## 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.md # 高度摘要 + 文件索引 ├── manifest.json # 增量追踪 ├── parsed/ # 解析后的 markdown ├── sources/ # 待处理区 └── archive/ # 原始文件备份 ``` **为什么不加 `knowledge/` 外层目录**:CWD 本身就是用户选定的知识库工作目录,额外嵌套层没有意义。用户可以在任意位置 `mkdir my-kb && cd my-kb` 然后使用 commands。 ### 2. 文档生命周期:sources → parsed + archive 文件流转: 1. 用户将文档放入 `sources/` 2. ingest 解析文件,生成 `parsed/<文件名>.md` 3. 原始文件移入 `archive/<文件名_YYYYMMDDHHmm>.`(每个版本都带时间戳) 4. 同名文件覆盖 parsed 中的旧版本,archive 中保留所有历史版本 **为什么 archive 全部带时间戳**:统一规则,无需判断"是否已有同名文件"。每次入库都是一个带时间戳的快照。 **同名不同扩展名冲突处理**:如 `技术方案.pdf` 和 `技术方案.docx` 同时存在于 sources/,因为 parsed 产物都会命名为 `技术方案.md`,产生冲突。此时拒绝处理并提示用户重命名。 ### 3. 增量追踪:manifest.json ```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 结构: ```markdown # <项目名称> ## 概述 (高度总结的项目信息) ## 关键信息 (从所有文档中提炼的核心要点) ## 文件索引 | 文件名 | 解析文件 | 最新归档 | 摘要 | |--------|----------|----------|------| | 需求文档 | parsed/需求文档.md | archive/需求文档_202602181600.docx | 简要摘要... | ## 更新记录 - 2026-02-18 16:00: 解析 需求文档.docx ``` **默认增量追加**(`lyxy-kb-ingest`): - 新文件:在文件索引表追加新行,在更新记录追加条目 - 概述和关键信息部分**不**自动更新 **全量重写**(`lyxy-kb-rebuild`): - 读取所有 parsed/*.md,重新生成整个 project.md - 概述、关键信息、文件索引全部重新生成 ### 5. 解析后 markdown 的元信息标记 每个 parsed 文件头部包含元信息注释: ```markdown # 技术方案 (文档正文内容...) ``` 用于问答时标注来源。 ### 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 文档自然。大模型需要自行判断如何提取关键信息。