7.4 端到端演示与效果调优


7.4 端到端演示与效果调优

本节摘要:实战项目收官:先跑通,再拧旋钮。演示:造一个三文件的小仓库(auth/storage/tasks),跑 pipeline.py 建索引,四类查询(标识符/意图/混排/换说法)给出示意输出与读法。排查:效果不达标时的归因顺序表——金标对不对、切分好不好、召回有没有、排序对不对,逐层往下问,反对上来就调参。调优:四张参数扫描表(chunk 行数上限、每路召回宽度、两路权重配比、重排深度),每张表给示意数字与走势解读——数字全部标注"示意/经验值",真实结论必须用第 9 章的指标在你自己的评测集上复测。顺序主张:先切分(它是上限)、再召回宽度(便宜)、再权重(要测)、最后重排深度(最贵)——顺序本身就是工程判断。

学习目标

阅读完本节,你应当能够:

  1. 跑通从建索引到四类查询的端到端演示;
  2. 按排查顺序表对"找不到/排不对"做逐层归因;
  3. 执行四张扫描表并解读各自的典型走势;
  4. 说出调优顺序主张及每一步的理由。

一、演示仓库与端到端跑通

# demo_repo/auth/session.py — 演示仓库三件之一(另两件见下) SESSION_TTL = 3600 def kill_session(user_id: str) -> None: """注销:删除 session 记录并吊销 refresh token。""" _delete(f"session:{user_id}") revoke_refresh_token(user_id) # 来自 storage/token_store.py def refresh_session(user_id: str) -> str: ...
# demo_repo/storage/token_store.py — 演示仓库三件之二 def revoke_refresh_token(user_id: str) -> None: """从可信存储吊销 refresh token(黑名单策略)。""" _redis.sadd("revoked_tokens", _token_of(user_id))
# demo_repo/tasks/upload_task.py — 演示仓库三件之三 MAX_RETRY = 3 def upload_with_retry(path: str) -> bool: """上传文件,失败按指数退避重试。""" for attempt in range(MAX_RETRY): if _put_object(path): return True _sleep(2 ** attempt) return False
# demo_run.sh — 端到端演示(示意输出见下) python pipeline.py demo_repo --out index python ask.py "kill_session" --index index python ask.py "注销用户的时候都删了什么" --index index --rerank 30 python ask.py "上传失败重试的退避怎么算的" --index index python ask.py "登出以后 token 怎么处理" --index index
[0.0328] demo_repo/auth/session.py:3-8 kill_session (function) ← 标识符型,第一位 [0.0163] demo_repo/tasks/upload_task.py:3-10 upload_with_retry (function) ← 融合分垫底 ---(--rerank 30 后)--- [0.9120] demo_repo/auth/session.py:3-8 kill_session ← 意图型:重排把词法噪声压下去 [0.7435] demo_repo/storage/token_store.py:1-4 revoke_refresh_token [0.6721] demo_repo/tasks/upload_task.py:3-10 upload_with_retry ← 换说法型:"退避"召回退避

(分数为示意:RRF 分量级 ~1/(60+rank),重排分为相关度。)读法:标识符型靠 BM25 保底必中;意图型与换说法型体现语义路价值——"注销/登出"与 kill_session、"退避"与 2 ** attempt 的对齐;重排把"看起来都对"变成"最像答案的在前"。

二、效果不达标:先归因,再调参

症状 第一问 归因方向 对应章节
正确 chunk 压根不在索引里 切出来了吗? 切分:巨类下切、孤儿兜底、行号对不对 3.3 症状学
在索引里但没被召回 两路各自召回了没? 单路失灵看另一路权重;双路都漏看嵌入/分词 5.1 / 2.2
召回了但排不进 top-K RRF 后排第几? 权重配比;重排深度不够或重排器拉胯 5.1 / 5.2
排第一但"不像答案" 金标本身对吗? 查询与金标的匹配口径;chunk 粒度太粗 9.2 / 3.1
时快时慢、时对时错 索引新鲜吗? state 对账:model_ver、增量是否漏跑 7.2 / 4.2

💡 这张表就是第 9.3 节"坏例归因流程"的肉眼版。归因先于调参的铁律:对着症状调参数,十个旋钮九个白拧。

三、四张扫描表

以下数字均为示意(基于教学规模演示仓库与经验值,写法演示用):走势可信、数值不可信——你仓库上的真实曲线要用第 9 章的 MRR/Recall@K 复测。

表 1:chunk 行数上限 max_lines(重建索引后测)

max_lines 40 60 80(默认) 120
Recall@5(示意) 0.78 0.83 0.85 0.82
症状 碎片化,类被切散 均衡 巨块稀释,重排变慢

解读:太小则身份信息(类名/前缀)被稀释、同函数碎片互相竞争;太大则"一个 chunk 说多件事",嵌入被平均(3.3 症状二)。60~80 是常见甜点(经验值)。

表 2:每路召回宽度 recall

recall 10 20 30(默认) 50 100
Recall@5(示意) 0.74 0.82 0.85 0.86 0.86
延迟(相对) 0.8x 0.9x 1x 1.3x 2.1x

解读:召回宽度解决"漏",对"排"无帮助——宽到正确答案已进候选集后再加宽是纯开销。30~50 后收益断崖(经验值)。

表 3:两路权重 bm25_w : vec_w

配比 0.5:1 0.7:1 1:1(默认) 1.5:1 2:1
意图型 MRR(示意) 0.71 0.74 0.76 0.72 0.68
标识符型 MRR(示意) 0.80 0.86 0.90 0.93 0.91

解读:权重搬的是两路的话语权——查询分布偏意图(Agent 口语提问多)就升语义路,偏标识符(工具调用多)就升词法路。没有"通用最优",只有"贴合你的查询分布"(这就是 9.2 要给评测集分类型打标的原因)。

表 4:重排深度 --rerank

depth 0 10 20 30 50
MRR(示意) 0.62 0.74 0.78 0.79 0.79
端到端延迟(相对) 1x 1.4x 1.8x 2.3x 3.5x

解读:重排是"从几十到五"的精修——depth 超过融合结果的精度上限后纯属烧钱。20~30 常见收敛(经验值);depth=0 那一列就是消融基线。

四、调优顺序主张

①切分(max_lines) 上限工程:切分错,后面全错——先在 3.3 症状学里过关 ▼ ②召回宽度(recall) 便宜:纯参数,不重建索引,宽了再看要不要收 ▼ ③混合权重(两路配比) 要测:必须配合第 9 章的分组指标,否则是玄学 ▼ ④重排深度(depth) 最贵:延迟线性涨,最后再买这段精度

主张的依据是改动成本与影响半径:切分牵动全库重建(最贵、影响最大)所以最先定;权重只影响排序(要靠指标才动得对);重排深度是纯买精度(最后买)。真实顺序里 ①③ 会有回环——切分变了,权重的甜点也会移,第 9.3 节的"一次一变量 + 全量评测"循环就是管这个回环的纪律。

⚠️ 本章扫描表最大的误用是把示意数字当结论。仓库语言、命名风格、查询分布、嵌入模型任一不同,曲线形状就会变。正确用法:抄扫描的维度与顺序,数字自己测——这正是下一章之后、第 9 章的正题。

本节要点回顾

  1. 端到端演示四类查询:标识符型 BM25 保底、意图型与换说法型看语义路、重排管最终排序;
  2. 归因先于调参:金标→切分→召回→排序→新鲜度,逐层往下问;
  3. 四个旋钮各自的主治与典型走势:max_lines 定上限、recall 防漏、权重贴查询分布、depth 买精度;
  4. 调优顺序 = 改动成本排序:先切分、再召回宽度、再权重、最后重排深度。

一台完整可跑、可调优的 codeqa 交付了。下一章抬头看业界:自己造过一遍管线,再看 Sourcegraph、Greptile、Copilot 时,看到的将不再是功能列表,而是"他们把成本押注在了哪一段"。


作者与出处
原作者: 灏天文库
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: 灏天文库 转发
评论区 (0)
U