初步完成知识库命令和技能的开发
This commit is contained in:
71
openspec/specs/kb-document-ingestion/spec.md
Normal file
71
openspec/specs/kb-document-ingestion/spec.md
Normal 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 数组追加新版本记录,不删除旧版本记录
|
||||
38
openspec/specs/kb-knowledge-query/spec.md
Normal file
38
openspec/specs/kb-knowledge-query/spec.md
Normal 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 明确告知用户当前知识库中未找到相关信息,而非编造答案
|
||||
24
openspec/specs/kb-project-management/spec.md
Normal file
24
openspec/specs/kb-project-management/spec.md
Normal 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** 任何 command(ingest/rebuild/ask)在指定项目目录上执行
|
||||
- **THEN** 系统 SHALL 先检查目录结构是否完整(包含 project.md、manifest.json、parsed/、sources/、archive/),若不完整则提示用户先执行 init
|
||||
53
openspec/specs/kb-project-summary/spec.md
Normal file
53
openspec/specs/kb-project-summary/spec.md
Normal 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 条目
|
||||
Reference in New Issue
Block a user