切块与检索参数:这些数字写在哪一行
调 RAG 的人多半有过这种经历:文档灌进去了,检索出来的东西不对,于是开始找 chunk_size 在哪儿改。找不到,就凭印象猜一个”业界常用值”填上,结果既不知道生效没有,也说不清改完之后哪一步变了。
DeepTutor 这套参数不难找——它们不是散在各个 pipeline 里,而是集中写在一个文件的两段里。本文只回答一件事:这些数字分别写在哪一行,各自属于哪一层。 至于它们该调成多少,仓库没有给通用值,本文也不给。
以下行号与数值对应我们采集的仓库快照:HEAD 456f9c2,采集日 2026-08-10,deeptutor/__version__.py 里的版本号是 1.5.11。你 clone 之后行号可能已经漂了,但常量名是稳的,照名字搜即可。
一、先分清两层:默认值表与夹取段
写配置类的东西,最容易漏掉的不是默认值本身,而是同一个参数在不同层各写了一遍。DeepTutor 的默认引擎参数就是这个结构,两段代码住在同一个文件 deeptutor/services/config/runtime_settings.py 里:
- 默认值表在
runtime_settings.py:219-227。这是”你从来没配过时用哪一份”。 - 夹取段在
runtime_settings.py:728-731。这是”你配了、但值越界时会被改成什么”。
这两层的语义不一样。默认值表回答的是缺省行为,夹取段回答的是容错行为——你填了一个 chunk_size=10,它不会报错,会被夹回合法区间。排查”我明明改了参数却看不出差别”时,这两段都要看,光看默认值表说明不了问题。
默认值表里的六个引擎参数,原样抄下来:
| 参数 | 默认值 | 所在层 |
|---|---|---|
retrieval_profile | "hybrid" | 默认值表 runtime_settings.py:219-227 |
top_k | 5 | 同上 |
vector_top_k_multiplier | 2 | 同上 |
bm25_top_k_multiplier | 2 | 同上 |
chunk_size | 512 | 同上,夹取段见 :728-731 |
chunk_overlap | 50 | 同上,夹取段见 :728-731 |
夹取段给出的范围是:chunk_size 被夹在 [64, 8192],默认 512;chunk_overlap 被夹在 [0, chunk_size - 1],默认 50。
注意第二个的上界写法:它不是一个固定数字,而是跟着 chunk_size 走的。也就是说这两个参数不能各改各的——你把 chunk_size 调小之后,原先填的 chunk_overlap 可能已经不在合法区间里了,最终生效的值会是被夹过之后的那个,而不是你填的那个。这是本文里第一个”你以为你改了、其实系统替你改了一遍”的地方。
至于这四个检索侧参数(profile 与三个 k 相关值)具体怎么组合成一次检索、两个 multiplier 各自乘在哪一步,我们没有读检索器的实现体,不做推断。本文只负责把名字和默认值落到行号上。
二、反直觉的那一处:有个参数是被故意不暴露的
如果你按 LlamaIndex 的常见用法去找 fusion_num_queries,会发现这份配置里根本没有它。这不是漏了。
runtime_settings.py:212-214 的注释把理由写死了:fusion_num_queries 是”故意不暴露”的,因为查询生成需要一个真正的 LLM,而这里的 fusion retriever 跑在 MockLLM 上,所以任何大于 1 的取值都会静默劣化结果。
值得咂摸的是”静默”这两个字。它描述的不是崩溃、不是报错、不是日志里出现的一行 warning,而是一切照常跑完、只是出来的东西变差了。这类问题在检索层最难被发现——你根本不知道该拿什么当基准去比。作者的处置办法不是加校验、不是加提示,而是干脆不把这个旋钮放出来。
这一处值得单独讲,是因为它反过来给读者一条可用的判据:在这份配置里能看到的参数集合,本身就是一次设计选择,而不是”能调的都列在这里了”。 你在设置里找不到某个 LlamaIndex 常见参数时,先去 runtime_settings.py 的注释块里搜一下这个名字,看它是不是被写在了”故意不给”的那一类里,而不是急着去改代码把它接出来。
同样在这段注释区里,runtime_settings.py:209-210 还写明了另一件事:chunk_size 与 chunk_overlap 的修改只在下一次(重新)索引时生效,不追溯。 这句话解释了本文开头那个场景的一大半——改完参数、重新问一次、发现检索结果一模一样,多半不是参数没写进去,而是索引还是老那一份。
三、怎么确认”改了但没生效”到底卡在哪一步
顺着上一条,给一组可执行的判定动作。这几步都只需要看文件,不需要跑起来:
第一步,确认你改的值落盘了没有。 引擎参数这一层的默认值与夹取都在 runtime_settings.py 里,先按上面的行号确认你填的值在夹取区间之内;chunk_overlap 尤其要拿它和你当前的 chunk_size 一起看。
第二步,确认有没有产生新的索引版本。 索引版本目录是平铺的 version-N,前缀常量 VERSION_PREFIX = "version-",识别正则是 ^version-(\d+)$,新版本号取现有最大值 +1(deeptutor/services/rag/index_versioning.py:38,43,111-113)。改了切块参数之后,如果 KB 目录下最大的那个 version-N 还是原来那个数字,说明重新索引这一步没发生,参数当然不会体现在结果里。
第三步,确认你的 KB 用的是哪个引擎。 这一点决定了前两步是否适用——下一节展开。
第四步,别去数”进了索引的文档有几篇”来验证。 这条路仓库自己堵死了:deeptutor/knowledge/manifest.py:18-25 明确写了”故意不报告”进入索引的文档数,给的理由是 docstore.json 是 chunk 级的、metadata.json 里的 file_hashes 只在增量添加那条路径上写、last_indexed_count 只是最后一批的大小。也就是说,这三个数据里没有一个能当”索引完整性”的凭证。知道这一点能省下不少白费的力气。
第五步,什么情况说明不是这个原因。 如果 version-N 确实新增了、区间也没被夹,检索结果仍然不符合预期,那么问题就不在本文这几个参数上了——可能在文档解析、embedding 配置或引擎本身。这几块我们没有核实,本文不下结论,也不给替代方案。
四、同一个 top_k,三个引擎三个默认值,第四个干脆没有
这是第二处容易踩的地方,而且它踩的是”经验迁移”:你在一个引擎上试出来的数量级,搬到另一个引擎上完全对不上。
检索引擎的 provider 常量一共 6 个:llamaindex(默认)、pageindex、graphrag、lightrag、lightrag-server、ima,集合名 KNOWN_PROVIDERS(deeptutor/services/rag/factory.py:30-48)。不同 provider 的参数块是各写各的:
| 位置 | 参数 | 默认值 |
|---|---|---|
| LlamaIndex(默认引擎) | top_k | 5(runtime_settings.py:219-227) |
| LightRAG | top_k | 60(runtime_settings.py:248-252) |
| IMA pipeline | _DEFAULT_TOP_K | 10(deeptutor/services/rag/pipelines/ima/pipeline.py:32) |
| GraphRAG | 无 top_k,暴露的是 community_level | 2(runtime_settings.py:236-241) |
同一个字段名,5 和 60 差了一个数量级;GraphRAG 那一块干脆没有这个字段,它暴露的是 community_level(默认 2)与 dynamic_community_selection(默认 False)。LightRAG 那一块除 top_k 外还有一个 response_type,默认 "Multiple Paragraphs"(runtime_settings.py:248-252)。
所以”top_k 设多少合适”这个问题,在这个仓库里没有一个跨引擎的答案。先确定你这个 KB 走的是哪个 provider,再去找对应那一块的参数——把默认引擎的 5 直接搬到 LightRAG 上,或者反过来,都是在拿一个引擎的语义去套另一个引擎。
还有一处与版本目录相关的差别值得记:只有默认引擎(llamaindex)的索引版本才用 embedding signature 做键(deeptutor/services/rag/factory.py:64-73)。这意味着上一节的第二步判定动作,在不同 provider 下的可靠程度不一样,别把它当成通用检查项。
五、还有一批数字不在配置块里
不是所有可调的东西都进了那份 JSON 化的配置。deeptutor/services/rag/smart_retriever.py:18-57 里,SmartRetriever.retrieve 的 max_queries 默认是 3,生成查询时喂进去的上下文被截断为 context[:2000]。
这两个数字是写在代码里的常量,没有出现在前面那张默认值表中。对读者的实际含义是:当你想解释”为什么这次检索发出去的查询是这么几条""为什么很长的上下文好像只用上了前面一段”时,光翻配置是翻不到答案的,得回到这个文件里看这两个值。至于改动它们会牵动什么,我们没有读这个类的调用方,不做推断。
顺带交代一处涉及数据流向的事实:检索并不总是在本机完成。lightrag_server 类型的知识库,条目里的字段是 server_url 加一个可选的 api_key,检索会转发到该服务器的 /query 端点;ima 类型的字段是 client_id + api_key + knowledge_base_id,检索转发到腾讯 IMA 的 search_knowledge OpenAPI(两条均见 deeptutor/knowledge/kb_types.py:69,75)。另外,PageIndex 那一块的默认 api_base_url 是 https://api.pageindex.ai(runtime_settings.py:195-199)。这是配置这些参数之前就该知道的事实,选不选用请结合你自己的数据合规要求评估。
六、边界
最后把不下结论的地方说清楚:
上面出现的每一个数字都是源码里的默认配置,不是”你用起来会怎样”的保证。本文没有安装、没有部署、没有运行过这个项目,也没有调用过任何模型 API,因此不涉及检索质量、响应速度与任何效果层面的描述。切块尺寸与 top_k 该取多少,取决于你的文档形态与用法,仓库没有给出通用值,本文也不替它给。
同样需要说明的是,这个仓库里另有一批面向学习流程的常量(掌握度计算、复习间隔、判分规则等,分别在 deeptutor/learning/ 下的几个文件里,我们另有专门的篇目讲它们)。那些同样是这个项目的实现选择,不是经过验证的教学结论,本文不对其学习效果作任何评价。
可核查的部分,都在上面给了文件名与行号。打开 runtime_settings.py,先看 :219-227 那张表,再看 :209-214 那段注释,最后看 :728-731 的夹取——十分钟之内你就能自己把本文的每一个数字对一遍。
本文依据 DeepTutor 官方仓库(github.com/HKUDS/DeepTutor)的 README、AGENTS.md、
pyproject.toml 与 deeptutor/ 下的源码整理,核对日 2026-08-10,对应仓库快照 456f9c2(版本 1.5.11)。
本文内容为仓库源码与文档口径,我们没有安装、部署或运行过该项目,也没有调用过其中任何一个模型 API,
因此不涉及生成质量、响应速度与教学效果的任何描述。
参数与默认值随版本变动,请以仓库最新代码与 --help 的实际输出为准。
安全相关做法请结合自身环境评估,本文不构成安全方案建议。