# 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 例全绿。