1
0

初步完成知识库命令和技能的开发

This commit is contained in:
2026-02-19 00:21:26 +08:00
parent 9f04dac50b
commit 04a22ccbf6
18 changed files with 1143 additions and 1 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-18

View File

@@ -0,0 +1,176 @@
## 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 文档自然。大模型需要自行判断如何提取关键信息。

View File

@@ -0,0 +1,31 @@
## Why
在使用大模型辅助工作时,经常需要基于一组项目相关文档(需求文档、技术方案、数据表等)进行问答和分析。目前缺乏一种轻量的、基于文件的方式来组织这些文档,让大模型能够高效地读取、总结和检索。需要一套 skill + command 来实现个人知识库的初始化、文档解析入库、渐进式问答。
## What Changes
- 新增 `lyxy-kb` skill定义知识库的目录结构规范、文档生命周期、解析规则、渐进式查询策略等底层能力
- 新增 `lyxy-kb-init` command引导用户创建知识项目目录结构
- 新增 `lyxy-kb-ingest` command解析 sources/ 中的新文件,增量更新 project.md
- 新增 `lyxy-kb-rebuild` command全量重新生成 project.md
- 新增 `lyxy-kb-ask` command进入会话式问答模式基于项目知识渐进式查询回答问题并标注来源
- 复用已有的 `lyxy-reader-office` skill 解析 office 文档,纯文本类文件直接读取
## Capabilities
### New Capabilities
- `kb-project-management`:知识项目的初始化与目录结构管理,包括 project.md、parsed/、sources/、archive/ 的创建和维护
- `kb-document-ingestion`:文档解析入库流程,包括文件类型识别、调用解析器、生成 parsed markdown、归档原始文件带时间戳、增量追踪manifest.json、同名冲突检测
- `kb-knowledge-query`:基于知识库的渐进式问答能力,包括读取 project.md 摘要索引、按需加载 parsed 文件、回答时标注文件来源
- `kb-project-summary`project.md 的生成与维护策略,包括增量追加(默认)和全量重写两种模式
### Modified Capabilities
无。
## Impact
- **新增文件**`skills/lyxy-kb/SKILL.md``commands/lyxy-kb/` 下 4 个 command 文件init.md、ingest.md、rebuild.md、ask.md
- **依赖**:运行时依赖 `lyxy-reader-office` skill 解析 office 文档,依赖 `lyxy-runner-python` skill 执行 Python 脚本
- **用户侧影响**:用户在任意项目目录下即可使用 command 创建和管理知识库项目CWD 即为知识库根目录

View File

@@ -0,0 +1,71 @@
## ADDED Requirements
### Requirement: 扫描并识别待处理文件
系统 SHALL 扫描项目 `sources/` 目录下的所有文件,并根据扩展名判断解析方式:
- Office 文档(.docx、.pdf、.pptx、.xlsx调用 lyxy-reader-office skill 解析
- 其他文件(.md、.txt、.csv、.json、.xml、.yaml、.yml、.log、.html 等):直接读取内容
#### Scenario: sources 中有 office 文档
- **WHEN** sources/ 中存在 `报告.docx`
- **THEN** 系统 SHALL 使用 lyxy-reader-office skill通过 lyxy-runner-python 执行)将其解析为 markdown
#### Scenario: sources 中有纯文本文件
- **WHEN** sources/ 中存在 `config.json`
- **THEN** 系统 SHALL 直接读取文件内容作为 parsed 产物
#### Scenario: sources 目录为空
- **WHEN** sources/ 中没有任何文件
- **THEN** 系统 SHALL 提示用户 sources/ 中无待处理文件
### Requirement: 同名不同扩展名冲突检测
系统 SHALL 在解析前检测 sources/ 中是否存在同名但不同扩展名的文件(如 `技术方案.pdf``技术方案.docx`),因为 parsed 产物都会命名为相同的 `.md` 文件。同时也需检测 sources/ 中的文件名是否与 manifest.json 中已有记录的不同扩展名文件冲突。
#### Scenario: sources 中存在同名不同扩展名文件
- **WHEN** sources/ 中同时存在 `技术方案.pdf``技术方案.docx`
- **THEN** 系统 SHALL 拒绝处理这两个文件,并提示用户重命名其中一个以消除冲突
#### Scenario: sources 中文件与已入库文件同名但不同扩展名
- **WHEN** manifest.json 中已有 `技术方案`ext: `.pdf`)的记录,且 sources/ 中出现 `技术方案.docx`
- **THEN** 系统 SHALL 拒绝处理该文件,并提示用户重命名
### Requirement: 生成 parsed markdown 文件
系统 SHALL 将解析后的内容写入 `parsed/<文件名>.md`,文件头部 MUST 包含元信息注释:
```
<!-- source: <原始文件名含扩展名> -->
<!-- archived: archive/<文件名_时间戳>.<扩展名> -->
<!-- parsed_at: <解析时间 YYYY-MM-DD HH:mm> -->
```
若 parsed/ 中已存在同名文件同一文档的更新版本SHALL 覆盖旧文件。
#### Scenario: 首次解析文件
- **WHEN** 解析 `需求文档.docx`parsed/ 中不存在 `需求文档.md`
- **THEN** 系统创建 `parsed/需求文档.md`,头部包含 source、archived、parsed_at 元信息,正文为解析后的 markdown 内容
#### Scenario: 更新已有文件
- **WHEN** 解析 `技术方案.pdf`parsed/ 中已存在 `技术方案.md`(上一版本)
- **THEN** 系统覆盖 `parsed/技术方案.md`,元信息更新为最新版本的 archive 路径和时间
### Requirement: 归档原始文件
系统 SHALL 将已解析的原始文件从 `sources/` 移动到 `archive/`,文件名格式为 `<文件名_YYYYMMDDHHmm>.<扩展名>`。每个进入 archive 的文件都 MUST 带有时间戳后缀,即使该文件只有一个版本。
#### Scenario: 归档文件
- **WHEN** `需求文档.docx` 解析完成,当前时间为 2026-02-18 16:00
- **THEN** 原始文件移动为 `archive/需求文档_202602181600.docx`
#### Scenario: 同名文件多次入库
- **WHEN** `技术方案.pdf` 第二次入库archive 中已有 `技术方案_202602181600.pdf`
- **THEN** 新版本归档为 `技术方案_202602181725.pdf`(以当前时间为时间戳),两个版本并存于 archive
### Requirement: 更新 manifest.json
系统 SHALL 在每个文件处理完成后更新 manifest.json
- 新文件:在 files 数组中追加新条目,包含 name、ext、parsed 路径versions 数组包含首个版本的 archived 路径、hash 和 ingested_at
- 已有文件更新:在对应条目的 versions 数组中追加新版本记录
- last_ingest 时间戳 SHALL 更新为当前 ingest 的时间
#### Scenario: 新文件入库更新 manifest
- **WHEN** `需求文档.docx` 首次解析完成
- **THEN** manifest.json 的 files 数组中追加 `{"name": "需求文档", "ext": ".docx", "parsed": "parsed/需求文档.md", "versions": [{"archived": "archive/需求文档_202602181600.docx", "hash": "sha256:...", "ingested_at": "2026-02-18T16:00"}]}`
#### Scenario: 已有文件更新 manifest
- **WHEN** `技术方案.pdf` 第二次入库
- **THEN** manifest.json 中该文件条目的 versions 数组追加新版本记录,不删除旧版本记录

View File

@@ -0,0 +1,38 @@
## ADDED Requirements
### Requirement: 渐进式查询策略
系统 SHALL 采用渐进式查询策略回答用户问题,以节省 token 消耗:
1. 首先读取 project.md 获取整体概述和文件索引
2. 根据用户问题和文件索引判断需要查阅哪些 parsed 文件
3. 按需读取相关 parsed 文件的全部或部分内容
4. 基于获取的信息回答问题
#### Scenario: 问题可通过摘要回答
- **WHEN** 用户提问"这个项目主要做什么?",且 project.md 的概述中已包含足够信息
- **THEN** 系统仅基于 project.md 内容回答,不加载 parsed 文件
#### Scenario: 问题需要查阅具体文件
- **WHEN** 用户提问"系统的权限控制是怎么设计的?",且 project.md 文件索引中 `需求文档` 的摘要提到了权限相关内容
- **THEN** 系统读取 `parsed/需求文档.md` 获取详细信息后回答
### Requirement: 来源标注
系统在回答中引用具体信息时 SHALL 标注文件来源,格式为:「根据《文件名》(parsed/文件名.md)...」。来源标注 MUST 指向 parsed 目录下的具体文件。
#### Scenario: 回答中包含来源标注
- **WHEN** 系统从 `parsed/技术方案.md` 中获取信息来回答问题
- **THEN** 回答中 SHALL 包含类似「根据《技术方案》(parsed/技术方案.md),系统采用微服务架构...」的来源标注
#### Scenario: 回答综合多个文件
- **WHEN** 回答需要综合 `parsed/需求文档.md``parsed/技术方案.md` 的信息
- **THEN** 回答中 SHALL 分别标注各信息点的来源文件
### Requirement: 会话问答模式
系统 SHALL 在 ask 模式下保持会话上下文,用户可以连续提问而无需每次重新加载知识库。会话的退出由用户自然决定(开启新话题或新会话),系统不主动终止会话。
#### Scenario: 多轮追问
- **WHEN** 用户先问"系统用了什么技术栈?",接着追问"数据库选型的理由是什么?"
- **THEN** 系统在第二次回答时保持之前的上下文,可复用已加载的 parsed 文件内容
#### Scenario: 知识库中无相关信息
- **WHEN** 用户提出的问题在 project.md 和所有 parsed 文件中均无相关信息
- **THEN** 系统 SHALL 明确告知用户当前知识库中未找到相关信息,而非编造答案

View File

@@ -0,0 +1,24 @@
## ADDED Requirements
### Requirement: 初始化知识项目目录结构
系统 SHALL 在 CWD 下创建以指定名称命名的子目录,并在其中生成以下固定结构:
- `project.md`:初始内容包含项目名称标题、空的概述/关键信息段落、空的文件索引表和空的更新记录
- `manifest.json`:初始内容包含项目名称、创建时间、空的 files 数组
- `parsed/` 目录
- `sources/` 目录
- `archive/` 目录
#### Scenario: 成功初始化新项目
- **WHEN** 用户执行 `/lyxy-kb-init my-project`,且 CWD 下不存在 `my-project` 目录
- **THEN** 系统创建 `my-project/` 目录及完整子结构project.md、manifest.json、parsed/、sources/、archive/),并提示用户将文档放入 sources/ 目录
#### Scenario: 目标目录已存在
- **WHEN** 用户执行 `/lyxy-kb-init my-project`,且 CWD 下已存在 `my-project` 目录
- **THEN** 系统 SHALL 提示用户该目录已存在,不覆盖任何现有内容
### Requirement: 项目目录结构规范
知识项目 SHALL 遵循固定的目录结构:`project.md``manifest.json``parsed/``sources/``archive/`。所有 command 和 skill 操作 SHALL 基于此结构进行,不在结构外创建额外文件或目录。
#### Scenario: 验证项目结构完整性
- **WHEN** 任何 commandingest/rebuild/ask在指定项目目录上执行
- **THEN** 系统 SHALL 先检查目录结构是否完整(包含 project.md、manifest.json、parsed/、sources/、archive/),若不完整则提示用户先执行 init

View File

@@ -0,0 +1,53 @@
## ADDED Requirements
### Requirement: project.md 格式规范
project.md SHALL 遵循以下固定结构:
```markdown
# <项目名称>
## 概述
(高度总结的项目信息)
## 关键信息
(从所有文档中提炼的核心要点)
## 文件索引
| 文件名 | 解析文件 | 最新归档 | 摘要 |
|--------|----------|----------|------|
## 更新记录
```
初始化时概述和关键信息为空,文件索引表为空表头,更新记录为空。
#### Scenario: 初始化后的 project.md
- **WHEN** 执行 `/lyxy-kb-init my-project`
- **THEN** 生成的 project.md 包含 `# my-project` 标题、空的概述/关键信息段落、空的文件索引表(仅表头)和空的更新记录
### Requirement: 增量追加模式
执行 ingest 时,系统 SHALL 以增量方式更新 project.md
- 在文件索引表中追加新解析文件的行文件名、parsed 路径、最新 archive 路径、该文件的简要摘要)
- 在更新记录中追加本次 ingest 的条目(时间和处理的文件列表)
- 已有文件更新时:覆盖文件索引表中对应行的最新归档路径和摘要
- 概述和关键信息部分 SHALL NOT 在增量模式下自动更新
#### Scenario: 首次 ingest 追加索引
- **WHEN** 首次 ingest 解析了 `需求文档.docx`
- **THEN** project.md 文件索引表中追加一行,更新记录中追加 `- 2026-02-18 16:00: 解析 需求文档.docx`
#### Scenario: 已有文件更新时追加索引
- **WHEN** `技术方案.pdf` 第二次入库
- **THEN** project.md 文件索引表中该文件的最新归档路径和摘要被更新,更新记录追加新条目
### Requirement: 全量重写模式
执行 rebuild 时,系统 SHALL 读取所有 `parsed/*.md` 文件,重新生成整个 project.md
- 概述:基于所有 parsed 文件内容重新生成高度总结
- 关键信息:重新提炼核心要点
- 文件索引:基于 manifest.json 和 parsed 文件重新生成完整索引表
- 更新记录:保留历史记录,追加本次 rebuild 条目
#### Scenario: 全量重写
- **WHEN** 用户执行 `/lyxy-kb-rebuild my-project`,项目中有 3 个 parsed 文件
- **THEN** 系统读取所有 3 个 parsed 文件,重新生成 project.md 的概述、关键信息和文件索引,更新记录追加 rebuild 条目

View File

@@ -0,0 +1,26 @@
## 1. Skill 基础
- [x] 1.1 创建 `skills/lyxy-kb/` 目录
- [x] 1.2 编写 `skills/lyxy-kb/SKILL.md`定义知识库底层规范包括目录结构规范project.md、manifest.json、parsed/、sources/、archive/、project.md 格式规范(标题/概述/关键信息/文件索引表/更新记录、manifest.json 结构定义、文件类型解析策略office 文档用 lyxy-reader-office其他纯文本直接读取、parsed 文件元信息标记格式、渐进式查询策略、来源引用格式、同名不同扩展名冲突检测规则
## 2. Command: lyxy-kb-init
- [x] 2.1 创建 `commands/lyxy-kb/` 目录
- [x] 2.2 编写 `commands/lyxy-kb/init.md`,实现初始化交互流程:接收项目名称参数,检查目标目录是否已存在(已存在则提示不覆盖),在 CWD 下创建项目子目录及完整结构project.md、manifest.json、parsed/、sources/、archive/project.md 按规范格式生成初始内容(空概述/关键信息/文件索引/更新记录manifest.json 初始化为含项目名和创建时间的空结构
## 3. Command: lyxy-kb-ingest
- [x] 3.1 编写 `commands/lyxy-kb/ingest.md`,实现增量解析入库交互流程,包括以下步骤:
- 接收项目名称参数,验证项目目录结构完整性
- 读取 manifest.json扫描 sources/ 下所有文件
- 执行同名不同扩展名冲突检测sources/ 内部互相检测 + 与 manifest 已有记录检测)
- 对每个无冲突的文件根据扩展名判断解析方式office → lyxy-reader-office其他 → 直接读取),生成 parsed markdown含头部元信息注释移动原始文件到 archive带时间戳后缀更新 manifest.json
- 增量更新 project.md在文件索引表追加/更新行,在更新记录追加条目,不修改概述和关键信息
## 4. Command: lyxy-kb-rebuild
- [x] 4.1 编写 `commands/lyxy-kb/rebuild.md`,实现全量重写交互流程:接收项目名称参数,验证项目目录结构完整性,读取所有 parsed/*.md 文件,基于全部内容重新生成 project.md概述、关键信息、文件索引表全部重写保留历史更新记录并追加本次 rebuild 条目
## 5. Command: lyxy-kb-ask
- [x] 5.1 编写 `commands/lyxy-kb/ask.md`,实现会话问答交互流程:接收项目名称参数,验证项目目录结构完整性,指导大模型执行渐进式查询策略(先读 project.md 摘要索引 → 按需加载 parsed 文件 → 回答并标注来源),进入持续会话模式(用户可连续追问),知识库无相关信息时明确告知

View File

@@ -1,7 +1,7 @@
schema: spec-driven
context: |
忽略项目目录下的「.opencode」「opencode」个目录与开发的skill无关
忽略项目目录下的「.opencode」「opencode」、「.claude」、「.codex」这几个目录与开发的skill无关
这个项目是专门用于开发用于大模型工具的 skill
所有开发的 skill 都放在「skills」目录下每个子目录都代表一个 skill目录名为 skill 的名称;
开发过程中的文档使用中文,面向中文开发者进行交流;

View File

@@ -0,0 +1,71 @@
## ADDED Requirements
### Requirement: 扫描并识别待处理文件
系统 SHALL 扫描项目 `sources/` 目录下的所有文件,并根据扩展名判断解析方式:
- Office 文档(.docx、.pdf、.pptx、.xlsx调用 lyxy-reader-office skill 解析
- 其他文件(.md、.txt、.csv、.json、.xml、.yaml、.yml、.log、.html 等):直接读取内容
#### Scenario: sources 中有 office 文档
- **WHEN** sources/ 中存在 `报告.docx`
- **THEN** 系统 SHALL 使用 lyxy-reader-office skill通过 lyxy-runner-python 执行)将其解析为 markdown
#### Scenario: sources 中有纯文本文件
- **WHEN** sources/ 中存在 `config.json`
- **THEN** 系统 SHALL 直接读取文件内容作为 parsed 产物
#### Scenario: sources 目录为空
- **WHEN** sources/ 中没有任何文件
- **THEN** 系统 SHALL 提示用户 sources/ 中无待处理文件
### Requirement: 同名不同扩展名冲突检测
系统 SHALL 在解析前检测 sources/ 中是否存在同名但不同扩展名的文件(如 `技术方案.pdf``技术方案.docx`),因为 parsed 产物都会命名为相同的 `.md` 文件。同时也需检测 sources/ 中的文件名是否与 manifest.json 中已有记录的不同扩展名文件冲突。
#### Scenario: sources 中存在同名不同扩展名文件
- **WHEN** sources/ 中同时存在 `技术方案.pdf``技术方案.docx`
- **THEN** 系统 SHALL 拒绝处理这两个文件,并提示用户重命名其中一个以消除冲突
#### Scenario: sources 中文件与已入库文件同名但不同扩展名
- **WHEN** manifest.json 中已有 `技术方案`ext: `.pdf`)的记录,且 sources/ 中出现 `技术方案.docx`
- **THEN** 系统 SHALL 拒绝处理该文件,并提示用户重命名
### Requirement: 生成 parsed markdown 文件
系统 SHALL 将解析后的内容写入 `parsed/<文件名>.md`,文件头部 MUST 包含元信息注释:
```
<!-- source: <原始文件名含扩展名> -->
<!-- archived: archive/<文件名_时间戳>.<扩展名> -->
<!-- parsed_at: <解析时间 YYYY-MM-DD HH:mm> -->
```
若 parsed/ 中已存在同名文件同一文档的更新版本SHALL 覆盖旧文件。
#### Scenario: 首次解析文件
- **WHEN** 解析 `需求文档.docx`parsed/ 中不存在 `需求文档.md`
- **THEN** 系统创建 `parsed/需求文档.md`,头部包含 source、archived、parsed_at 元信息,正文为解析后的 markdown 内容
#### Scenario: 更新已有文件
- **WHEN** 解析 `技术方案.pdf`parsed/ 中已存在 `技术方案.md`(上一版本)
- **THEN** 系统覆盖 `parsed/技术方案.md`,元信息更新为最新版本的 archive 路径和时间
### Requirement: 归档原始文件
系统 SHALL 将已解析的原始文件从 `sources/` 移动到 `archive/`,文件名格式为 `<文件名_YYYYMMDDHHmm>.<扩展名>`。每个进入 archive 的文件都 MUST 带有时间戳后缀,即使该文件只有一个版本。
#### Scenario: 归档文件
- **WHEN** `需求文档.docx` 解析完成,当前时间为 2026-02-18 16:00
- **THEN** 原始文件移动为 `archive/需求文档_202602181600.docx`
#### Scenario: 同名文件多次入库
- **WHEN** `技术方案.pdf` 第二次入库archive 中已有 `技术方案_202602181600.pdf`
- **THEN** 新版本归档为 `技术方案_202602181725.pdf`(以当前时间为时间戳),两个版本并存于 archive
### Requirement: 更新 manifest.json
系统 SHALL 在每个文件处理完成后更新 manifest.json
- 新文件:在 files 数组中追加新条目,包含 name、ext、parsed 路径versions 数组包含首个版本的 archived 路径、hash 和 ingested_at
- 已有文件更新:在对应条目的 versions 数组中追加新版本记录
- last_ingest 时间戳 SHALL 更新为当前 ingest 的时间
#### Scenario: 新文件入库更新 manifest
- **WHEN** `需求文档.docx` 首次解析完成
- **THEN** manifest.json 的 files 数组中追加 `{"name": "需求文档", "ext": ".docx", "parsed": "parsed/需求文档.md", "versions": [{"archived": "archive/需求文档_202602181600.docx", "hash": "sha256:...", "ingested_at": "2026-02-18T16:00"}]}`
#### Scenario: 已有文件更新 manifest
- **WHEN** `技术方案.pdf` 第二次入库
- **THEN** manifest.json 中该文件条目的 versions 数组追加新版本记录,不删除旧版本记录

View File

@@ -0,0 +1,38 @@
## ADDED Requirements
### Requirement: 渐进式查询策略
系统 SHALL 采用渐进式查询策略回答用户问题,以节省 token 消耗:
1. 首先读取 project.md 获取整体概述和文件索引
2. 根据用户问题和文件索引判断需要查阅哪些 parsed 文件
3. 按需读取相关 parsed 文件的全部或部分内容
4. 基于获取的信息回答问题
#### Scenario: 问题可通过摘要回答
- **WHEN** 用户提问"这个项目主要做什么?",且 project.md 的概述中已包含足够信息
- **THEN** 系统仅基于 project.md 内容回答,不加载 parsed 文件
#### Scenario: 问题需要查阅具体文件
- **WHEN** 用户提问"系统的权限控制是怎么设计的?",且 project.md 文件索引中 `需求文档` 的摘要提到了权限相关内容
- **THEN** 系统读取 `parsed/需求文档.md` 获取详细信息后回答
### Requirement: 来源标注
系统在回答中引用具体信息时 SHALL 标注文件来源,格式为:「根据《文件名》(parsed/文件名.md)...」。来源标注 MUST 指向 parsed 目录下的具体文件。
#### Scenario: 回答中包含来源标注
- **WHEN** 系统从 `parsed/技术方案.md` 中获取信息来回答问题
- **THEN** 回答中 SHALL 包含类似「根据《技术方案》(parsed/技术方案.md),系统采用微服务架构...」的来源标注
#### Scenario: 回答综合多个文件
- **WHEN** 回答需要综合 `parsed/需求文档.md``parsed/技术方案.md` 的信息
- **THEN** 回答中 SHALL 分别标注各信息点的来源文件
### Requirement: 会话问答模式
系统 SHALL 在 ask 模式下保持会话上下文,用户可以连续提问而无需每次重新加载知识库。会话的退出由用户自然决定(开启新话题或新会话),系统不主动终止会话。
#### Scenario: 多轮追问
- **WHEN** 用户先问"系统用了什么技术栈?",接着追问"数据库选型的理由是什么?"
- **THEN** 系统在第二次回答时保持之前的上下文,可复用已加载的 parsed 文件内容
#### Scenario: 知识库中无相关信息
- **WHEN** 用户提出的问题在 project.md 和所有 parsed 文件中均无相关信息
- **THEN** 系统 SHALL 明确告知用户当前知识库中未找到相关信息,而非编造答案

View File

@@ -0,0 +1,24 @@
## ADDED Requirements
### Requirement: 初始化知识项目目录结构
系统 SHALL 在 CWD 下创建以指定名称命名的子目录,并在其中生成以下固定结构:
- `project.md`:初始内容包含项目名称标题、空的概述/关键信息段落、空的文件索引表和空的更新记录
- `manifest.json`:初始内容包含项目名称、创建时间、空的 files 数组
- `parsed/` 目录
- `sources/` 目录
- `archive/` 目录
#### Scenario: 成功初始化新项目
- **WHEN** 用户执行 `/lyxy-kb-init my-project`,且 CWD 下不存在 `my-project` 目录
- **THEN** 系统创建 `my-project/` 目录及完整子结构project.md、manifest.json、parsed/、sources/、archive/),并提示用户将文档放入 sources/ 目录
#### Scenario: 目标目录已存在
- **WHEN** 用户执行 `/lyxy-kb-init my-project`,且 CWD 下已存在 `my-project` 目录
- **THEN** 系统 SHALL 提示用户该目录已存在,不覆盖任何现有内容
### Requirement: 项目目录结构规范
知识项目 SHALL 遵循固定的目录结构:`project.md``manifest.json``parsed/``sources/``archive/`。所有 command 和 skill 操作 SHALL 基于此结构进行,不在结构外创建额外文件或目录。
#### Scenario: 验证项目结构完整性
- **WHEN** 任何 commandingest/rebuild/ask在指定项目目录上执行
- **THEN** 系统 SHALL 先检查目录结构是否完整(包含 project.md、manifest.json、parsed/、sources/、archive/),若不完整则提示用户先执行 init

View File

@@ -0,0 +1,53 @@
## ADDED Requirements
### Requirement: project.md 格式规范
project.md SHALL 遵循以下固定结构:
```markdown
# <项目名称>
## 概述
(高度总结的项目信息)
## 关键信息
(从所有文档中提炼的核心要点)
## 文件索引
| 文件名 | 解析文件 | 最新归档 | 摘要 |
|--------|----------|----------|------|
## 更新记录
```
初始化时概述和关键信息为空,文件索引表为空表头,更新记录为空。
#### Scenario: 初始化后的 project.md
- **WHEN** 执行 `/lyxy-kb-init my-project`
- **THEN** 生成的 project.md 包含 `# my-project` 标题、空的概述/关键信息段落、空的文件索引表(仅表头)和空的更新记录
### Requirement: 增量追加模式
执行 ingest 时,系统 SHALL 以增量方式更新 project.md
- 在文件索引表中追加新解析文件的行文件名、parsed 路径、最新 archive 路径、该文件的简要摘要)
- 在更新记录中追加本次 ingest 的条目(时间和处理的文件列表)
- 已有文件更新时:覆盖文件索引表中对应行的最新归档路径和摘要
- 概述和关键信息部分 SHALL NOT 在增量模式下自动更新
#### Scenario: 首次 ingest 追加索引
- **WHEN** 首次 ingest 解析了 `需求文档.docx`
- **THEN** project.md 文件索引表中追加一行,更新记录中追加 `- 2026-02-18 16:00: 解析 需求文档.docx`
#### Scenario: 已有文件更新时追加索引
- **WHEN** `技术方案.pdf` 第二次入库
- **THEN** project.md 文件索引表中该文件的最新归档路径和摘要被更新,更新记录追加新条目
### Requirement: 全量重写模式
执行 rebuild 时,系统 SHALL 读取所有 `parsed/*.md` 文件,重新生成整个 project.md
- 概述:基于所有 parsed 文件内容重新生成高度总结
- 关键信息:重新提炼核心要点
- 文件索引:基于 manifest.json 和 parsed 文件重新生成完整索引表
- 更新记录:保留历史记录,追加本次 rebuild 条目
#### Scenario: 全量重写
- **WHEN** 用户执行 `/lyxy-kb-rebuild my-project`,项目中有 3 个 parsed 文件
- **THEN** 系统读取所有 3 个 parsed 文件,重新生成 project.md 的概述、关键信息和文件索引,更新记录追加 rebuild 条目