6.3 KiB
Context
当前项目已有 lyxy-reader-office skill(解析 docx/pdf/pptx/xlsx 为 markdown)和 lyxy-runner-python skill(uv 执行 Python 脚本)。需要在此基础上新增知识库管理能力,让用户能将项目文档组织为可被大模型高效检索和问答的知识库。
核心约束:
- Skill 和 Command 分离:skill 定义底层规范和能力,command 定义用户交互流程
- 纯文件驱动:不依赖数据库或向量存储,所有数据以文件形式存在
- 渐进式查询:优先读摘要索引,按需加载详细内容,节省 token
Goals / Non-Goals
Goals:
- 提供完整的文档入库流程:放入文件 → 解析 → 归档 → 生成摘要
- 支持增量更新和全量重建两种 project.md 维护模式
- 基于知识库进行多轮问答,回答时标注文件来源
- 复用已有 lyxy-reader-office 解析 office 文档
- 支持任意纯文本文件直接入库
Non-Goals:
- 不做向量化或语义搜索
- 不做跨项目知识关联
- 不做文档版本对比或 diff
- 不做权限控制或多用户协作
- 不做 Web UI 或可视化界面
Decisions
1. 目录结构:CWD 即知识库根目录
每个知识项目是 CWD 下的一个子目录,内含固定结构:
CWD/
└── <project-name>/
├── project.md # 高度摘要 + 文件索引
├── manifest.json # 增量追踪
├── parsed/ # 解析后的 markdown
├── sources/ # 待处理区
└── archive/ # 原始文件备份
为什么不加 knowledge/ 外层目录:CWD 本身就是用户选定的知识库工作目录,额外嵌套层没有意义。用户可以在任意位置 mkdir my-kb && cd my-kb 然后使用 commands。
2. 文档生命周期:sources → parsed + archive
文件流转:
- 用户将文档放入
sources/ - ingest 解析文件,生成
parsed/<文件名>.md - 原始文件移入
archive/<文件名_YYYYMMDDHHmm>.<ext>(每个版本都带时间戳) - 同名文件覆盖 parsed 中的旧版本,archive 中保留所有历史版本
为什么 archive 全部带时间戳:统一规则,无需判断"是否已有同名文件"。每次入库都是一个带时间戳的快照。
同名不同扩展名冲突处理:如 技术方案.pdf 和 技术方案.docx 同时存在于 sources/,因为 parsed 产物都会命名为 技术方案.md,产生冲突。此时拒绝处理并提示用户重命名。
3. 增量追踪:manifest.json
{
"project": "my-project",
"created_at": "2026-02-18T16:00",
"last_ingest": "2026-02-18T17:25",
"files": [
{
"name": "需求文档",
"ext": ".docx",
"parsed": "parsed/需求文档.md",
"versions": [
{
"archived": "archive/需求文档_202602181600.docx",
"hash": "sha256:abc123...",
"ingested_at": "2026-02-18T16:00"
}
]
}
]
}
manifest 用于:
- 检测 sources/ 中哪些文件是新文件
- 检测同名不同扩展名冲突(对比 files 中已有的 name 和 ext)
- 记录版本历史,关联 parsed 和 archive 文件
4. project.md 格式与更新策略
project.md 结构:
# <项目名称>
## 概述
(高度总结的项目信息)
## 关键信息
(从所有文档中提炼的核心要点)
## 文件索引
| 文件名 | 解析文件 | 最新归档 | 摘要 |
|--------|----------|----------|------|
| 需求文档 | parsed/需求文档.md | archive/需求文档_202602181600.docx | 简要摘要... |
## 更新记录
- 2026-02-18 16:00: 解析 需求文档.docx
默认增量追加(lyxy-kb-ingest):
- 新文件:在文件索引表追加新行,在更新记录追加条目
- 概述和关键信息部分不自动更新
全量重写(lyxy-kb-rebuild):
- 读取所有 parsed/*.md,重新生成整个 project.md
- 概述、关键信息、文件索引全部重新生成
5. 解析后 markdown 的元信息标记
每个 parsed 文件头部包含元信息注释:
<!-- source: 技术方案.pdf -->
<!-- archived: archive/技术方案_202602181725.pdf -->
<!-- parsed_at: 2026-02-18 17:25 -->
# 技术方案
(文档正文内容...)
用于问答时标注来源。
6. 文件类型解析策略
| 文件类型 | 解析方式 |
|---|---|
| .docx, .pdf, .pptx, .xlsx | lyxy-reader-office(通过 lyxy-runner-python 执行) |
| .md, .txt, .csv, .json, .xml, .yaml/.yml, .log, .html 等 | 直接读取文件内容 |
判断逻辑:先检查是否为 office 文档扩展名,是则调用 lyxy-reader-office;否则视为纯文本直接读取。
7. 渐进式查询策略(ask 模式)
① 读取 project.md → 获取整体概述和文件索引
② 根据用户问题判断需要哪些 parsed 文件
③ 读取相关 parsed 文件(可能只需部分章节)
④ 回答问题,标注来源格式:「根据《文件名》(parsed/文件名.md),...」
⑤ 保持会话上下文,用户可继续追问
8. Skill 与 Command 的职责划分
Skill(skills/lyxy-kb/SKILL.md):
- 定义知识库目录结构规范
- 定义 project.md 格式规范
- 定义 manifest.json 结构
- 定义解析规则和文件类型映射
- 定义渐进式查询策略
- 定义来源引用格式
Commands(commands/lyxy-kb/):
init.md:创建项目目录和初始文件的交互流程ingest.md:触发解析、展示进度、增量更新 project.md 的交互流程rebuild.md:全量重写 project.md 的交互流程ask.md:进入会话问答模式的交互流程
Risks / Trade-offs
[project.md 增量追加导致概述过时] → 用户可通过 lyxy-kb-rebuild 全量重写来更新概述。增量模式优先保证 token 效率,trade-off 是概述不会自动融入新文件的信息。
[大量文件时 rebuild 的 token 消耗] → 如果 parsed 文件总量很大,全量重写时需要读取所有文件。目前无特殊缓解措施,依赖大模型上下文窗口限制自然约束项目规模。
[parsed 文件名冲突] → 同名不同扩展名直接拒绝,要求用户重命名。简单但可能偶尔不便。
[纯文本文件的摘要质量] → CSV、JSON 等结构化数据直接读取后,摘要可能不如 office 文档自然。大模型需要自行判断如何提取关键信息。