1
0
Files
Skill/openspec/changes/archive/2026-02-19-add-lyxy-kb/design.md

177 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Context
当前项目已有 `lyxy-reader-office` skill解析 docx/pdf/pptx/xlsx 为 markdown`lyxy-runner-python` skilluv 执行 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
文件流转:
1. 用户将文档放入 `sources/`
2. ingest 解析文件,生成 `parsed/<文件名>.md`
3. 原始文件移入 `archive/<文件名_YYYYMMDDHHmm>.<ext>`(每个版本都带时间戳)
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
<!-- 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 文档自然。大模型需要自行判断如何提取关键信息。