64 lines
3.7 KiB
Markdown
64 lines
3.7 KiB
Markdown
# RAG 迭代 Task 3 实现报告(含评审修订 D1 的 index_dir)
|
||
|
||
## 状态
|
||
**GREEN — 已完成并通过测试**
|
||
|
||
- 先写失败测试(RED:因 `impact_rag.py` 缺失触发 `ModuleNotFoundError`)
|
||
- 实现 `ImpactRAG` 及 D1 修订项 `index_dir`
|
||
- 重新运行测试:`2 passed`
|
||
|
||
## Commit
|
||
`feat(rag): 新增 ImpactRAG 索引/检索服务(含 index_dir)`
|
||
|
||
涉及文件:
|
||
- `src/genesis/rag/impact_rag.py`(新增)
|
||
- `tests/test_impact_rag.py`(新增)
|
||
|
||
## 测试输出摘要
|
||
```
|
||
python -m pytest tests/test_impact_rag.py -q
|
||
2 passed in 2.86s
|
||
```
|
||
|
||
测试用例:
|
||
1. `test_retrieve_returns_relevant_chunk`:验证 `index` + `retrieve` 能做到 chunk 级语义召回(FakeEmbedder 词袋向量 + cosine),返回结果含 `OrderController`。
|
||
2. `test_index_dir_reads_text_files`:验证 `index_dir` 仅索引文本源文件(白名单扩展名),跳过 `binary.bin` 与非文本/空文件,返回索引片段数为 1,且可检索到内容。
|
||
|
||
## 自我审查
|
||
- `index`:将 `(文件名, 文本)` 切分为 chunk(默认 800 字,按段落聚合),前缀 `[文件名]`,批量 embed 后 `store.add`。
|
||
- `index_dir`(D1):`Path(root).rglob("*")` 遍历,按扩展名白名单过滤,UTF-8 `errors="ignore"` 读取,跳过空文本与读取异常;返回实际索引文件数(即 sources 数,非 chunk 数 —— 与 brief 文档及测试断言 `n == 1` 一致)。
|
||
- `retrieve`:空查询直接返回 `[]`;否则 embed 查询向量后调用 `store.search`。
|
||
- 测试中对 `RagStore(":memory:")` 采用 `try/finally` 包裹 `close()`,避免 ResourceWarning。
|
||
|
||
## 一句话摘要
|
||
实现 `ImpactRAG` 的 `index`/`retrieve` 与 D1 修订项 `index_dir`,2 项测试全绿,可为上传即索引(Task 5 接线)提供目录级源码索引能力。
|
||
|
||
## 顾虑
|
||
- 运行指定测试文件时,全局 pytest 覆盖率配置(要求 99%)会报 `Required test coverage of 99.0% not reached`,但本任务验证仅需 `2 passed`,不影响功能正确性;若 CI 以全量套件口径执行,需单独豁免或补充本模块覆盖率。
|
||
- `index_dir` 返回的是"索引文件数"而非"片段数";brief 文档两处措辞略不一致(接口签名注释写"返回索引的片段数",测试与示例暗示为文件数),当前实现以测试断言为准(文件数)。
|
||
|
||
## 修复后验证
|
||
|
||
### 状态
|
||
**GREEN — 分支测试补全,覆盖率 100%**
|
||
|
||
针对评审发现(空 query 行为未测 + fail_under=99 硬要求),补全 `index`/`index_dir`/`retrieve` 全部分支测试与防御性过滤,并更新 `index_dir` docstring 为"返回索引的文件数"。
|
||
|
||
### 修改摘要
|
||
涉及文件:
|
||
- `src/genesis/rag/impact_rag.py`
|
||
- `index`:对 `_split` 结果过滤空片段(`if piece.strip():`),避免空向量噪声 chunk。
|
||
- `index_dir`:docstring 由"片段数"更正为"文件数";读取文本后叠加内容级跳过(空文本 `if not text.strip(): continue`、含 NUL 字节二进制误带扩展名 `\x00` 跳过)。
|
||
- `tests/test_impact_rag.py`:新增 10 个用例,覆盖空 query、空文本源、非目录 root、空文件、读取异常、大写扩展名、空目录、NUL 二进制、单段超长与多段拆行。
|
||
|
||
### 测试输出摘要
|
||
```
|
||
python -m pytest tests/test_impact_rag.py -q --cov=genesis.rag.impact_rag --cov-report=term-missing
|
||
src\genesis\rag\impact_rag.py 53 0 26 0 100%
|
||
12 passed in 0.28s
|
||
```
|
||
(注:若沿用全局 `addopts` 的 `--cov=genesis`,整体覆盖率会因只跑单文件而低于 99% 告警,但 `impact_rag.py` 本文件覆盖率为 100%、12 例全绿,符合本次验收口径。)
|
||
|
||
### 一句话摘要
|
||
补全 `ImpactRAG` 分支测试与防御后,`impact_rag.py` 达到语句/分支 100% 覆盖,原 2 例与新 10 例共 12 例全绿。
|