AI Hero Club

上下文工程 · 第 7 章

已自行标记完成0 / 8

仅保存在当前浏览器;完成标记不代表通过项目验收。

本章提纲 7 个小节
全课目录 8 章
完整课程计划 ↗
上下文工程 / 课程计划 ↗

CHAPTER 07 / 8建议学习 140 分钟

评测与故障:保留每一个失败

一个回答有引用且没超预算,为什么仍可能漏答字段或在故障后给出错误结果?

本章要解决的 3 个问题
  • 计算状态、支持与覆盖的联合判据
  • 复现108条策略对照并定位head失败
  • 用删证据反事实区分真实可见路径与旁路
课程项目 ZIP ↓

一次回答不能验收一条管线

前六章构成完整系统,本章只改变评估方式,不再发明新检索能力。读者需要有限集合、计数和分数;目标是从同一版本资料与同一任务表重现每个策略的逐题记录,定位最早失效阶段,保留坏结果。这里的任务集是作者设计的十八条有限测试,不是从所有真实用户问题随机抽样。因此它可以给回归保证与机制反例,不能给总体准确率的统计承诺。

task 文件每行一个 JSON,字段含 id、query、fields、limit、reserve、expected,以及可选 as_of、at、scope。expected 可以是 answered、abstain、conflict 或 budget_error。它声明应发生什么状态,不直接给检索器正确来源列表。实际支持集合由当前源状态和字段规范自动计算,生成器也只能在可见证据中取完整行。期望状态来自作者编写测试,不等于它已经得到现实老师确认;原资料和预期应作为同一教学数据一起审计。

我们固定十八任务、冻结分词器、版本事件和三个选择策略,再比较全文与保真抽取两种候选表示,得到 18×3×2=10818\times3\times2=108 个记录。一个记录包括 ranked_ids、selected、完整 rendered、实际 token_ids、输出、支持性、覆盖率与错误信息。保留这些中间实物,使“为什么失败”可以从数据回答,避免只凭最终一句自然语言猜原因。源文件摘要同时进入 receipt,变更后不能继续使用旧报告声明新构建通过。

指标的分母必须跟问题匹配

对一题,设 GG 为有效源中所有必答字段的可抽取声明身份,AA 为回答中的声明身份。当 GG 非空,覆盖定义为交集大小除 ∣G∣|G|;同一条重复输出不能重复加分。当 GG 为空,覆盖记 None,不把零除零硬记为一。支持性则要求每个输出声明通过源与上下文校验。覆盖高不保证支持性,支持性高也可能只说了一小部分;状态正确、支持与完整覆盖要联合判断。

coverage=∣A∩G∣∣G∣(∣G∣>0),support=⋀c∈A(P(c,S)∧V(c,X))\mathrm{coverage}=\frac{|A\cap G|}{|G|}\quad(|G|>0),\qquad \mathrm{support}=\bigwedge_{c\in A}(P(c,S)\land V(c,X))
集合计数不依赖措辞,当前任务仍限制于可抽取字段语言。

完整算例一:十八题通过不等于十八次确认

主配置 density 加保真抽取通过十八题。通过条件分支计算:answered 题必须状态正确、支持为真且 coverage 为一;abstain 与 conflict 题必须返回对应状态并保持支持检查;budget_error 题只有真正抛 BudgetError 才通过。schema错误、数据库损坏等其他异常不能冒充预算拒绝。相机规则撤销后正确拒答、scope 不匹配正确不读记忆、临时开放到期、未来项目尚未生效和冲突拒绝确认,都属于成功遵守规范。

正对照同样必要。time-current、place-current、borrow-current 等有完整资料的题若全被拒答,虽然空 claim 的全称支持命题为真,状态与覆盖仍失败。不存在安排 unknown 题没有任何目标事实,不能要求程序凭常识给出时间。这样测试既防瞎编,也防永远拒答的无用策略。该平衡是在有限测试规范内成立,开放式用户需求可能需要更丰富的人工判定,但不能省略这里的正例。

策略全文候选保真抽取候选
head18/1817/18
rank18/1818/18
density18/1818/18
最终同一18任务、同一冻结数据的实际规范符合数;不是随机抽样总体成功率。

完整算例二:一个真实失败否定“压缩必提升”

head 加保真抽取在 project 题失败,覆盖为零;其余五个配置在该任务通过。压缩提案自身没有丢任何项目声明,但候选被拆成更多独立行,每条重复来源开销,head 按身份顺序装入前面的候选,遇第一个放不下就停止,尚未到数据要求行。这说明源保真与任务效果可以反向变化:完整候选集合相同,选择算法与粒度改变了预算下可见子集。不能删掉这个失败后宣布所有压缩都会提升。

精确定位先看源资料:project@1:5 存在且有效;再看压缩检查:项目四条全部保留,faithful 为真;再看 ranked_ids:目标能被词法检索发现;最后检查 head 的 selected:目标未进入窗口,故最早任务失效发生在打包选择。若此时只去改引用格式或换更流畅生成器,不会让不存在于窗口的目标行出现。rank 跳过与 density 重评候选为这项任务提供可执行对照,但十八题过于小,不能说明两者永远优于 head。

另一个真实局部实验是全文截断:预算九百五十五、输入三百五十五、输出八十九,全部格式与词元都合法,三个要求字段只覆盖一个,覆盖为三分之一。这里小输入并不代表效果更好,截断丢失的完整行不能从源库补回。与 project 失败不同,这个实验失效在可见正文形成时,修复应改变片段边界或预算安排,而不是指责压缩器遗漏源事实。

独立运行独立集合正控制:重复声明不增加覆盖,分母来自所有必答身份。
from fractions import Fraction
gold={'time','duration','arrival'}
answer={'time','time'}
coverage=Fraction(len(answer & gold),len(gold))
assert coverage==Fraction(1,3)
assert len(answer)==1
print('coverage',coverage)

反事实测试说明了哪条信息路径

反事实保持同一源库、任务、分词器与预算,只把所有目标字段证据身份从候选集合删除。time-current 正常覆盖为一,删除后覆盖零并 abstain。一次只动可见证据路径,所以它区分“生成器依赖打包内容”与“生成器偷偷去源库补目标”。全库冲突门仍被允许存在,但这一前缀没有冲突,不影响这个检验。若删后仍答对,要先检查旁路、缓存或错误的可见集合计算,不能立即称模型有超强推理。

负对照还包括改坏引用 id、摘要、原行号、字段与 text,使用过期旧版本,给全文只留标题,往事件库写错误哈希或递减版本,以及改坏链的 payload。每个对照故意破坏一条必要前提,并要求对应检查真实失败。错误捕获应窄:测试只期待 ContractError 或 BudgetError,不用 except Exception 把程序崩溃也记成拒答成功。失败记录里保留具体异常,便于区分格式问题与算法问题。

反事实不是万能因果证明。该任务没有随机用户、没有 LLM、多条备份证据也可能在真实语料中补上被删事实;我们的 remove_ids 明确删全部目标候选。实验只证明当前有限程序、当前题目、当前输入下信息路径确实控制输出。它是源代码审计和定向测试的强证据,却不能转成真实模型在任意领域都忠于证据的承诺。

在课程项目目录运行项目目录:删除全部关键候选,检验实际上下文依赖,而非只比较文字风格。
import pathlib,tempfile
from run import setup,load_tokenizer
from context import compile_context,units,source_claims
t={'query':'活动时间','fields':['活动时间'],'limit':1500,'reserve':240}
with tempfile.TemporaryDirectory() as d:
    r=setup(pathlib.Path(d)/'r.sqlite');s=r.replay(12);tok=load_tokenizer()
    ids=[u['id'] for u in units(s,True)[0] if any(c['field'] in t['fields'] for c in source_claims(s,u))]
    before=compile_context(s,t,tok);after=compile_context(s,t,tok,remove_ids=ids)
    assert before['result']['coverage']==1 and after['result']['coverage']==0
    assert after['result']['status']=='abstain'
    r.db.close()
print('remove all target evidence: coverage 1 -> 0')

可复现性要锁住什么

每次评估锁定代码、原始资料、事件顺序、任务表、tokenizer 表与 wire 约定。demo 的 receipt 保存源摘要、分词器摘要和 evaluation 实物摘要;最后课程证据清单还绑定章节与项目。运行时输出目录必须新建,避免复用已经追加过事件的 SQLite 库。Python 版本写入回执,本课算法确定且无随机数,但数据库字节可能受运行环境影响,行为复现与文件逐字相同应区分。

报告不把 development、development-v2、development-v3、frozen-v2 的局部成功合并成最终成绩。旧结果保留用于追溯,最终统一来源为 evidence/final/evaluation.json 的一百零八条。后续根验收可从新解压 ZIP 独立重跑,输出另一个目录并比对任务结果。学生不应运行作者的网页渲染审计来完成项目,也不需要相邻课程源文件;分词器依赖已经复制并标注来源。

本章验收只有有限程序级结论:预算不变式、源行支持、日期/版本状态、指定故障和十八题规范符合。未运行远程模型,未测语义检索,未测多用户并发与真实长期使用,也没有随机样本总体误差条。把这些边界列出来,使下一章从“本地实验完成”走向“可交付项目”的每一步都能具体定义,而不是把一张满分表包装成通用智能助手。

修复测试不等于扩大可信范围

定向测试的价值在于一个失败能指向特定机制,而不是数量越多越像可靠。二十二项测试覆盖本课已实现分支;其中一些复用同一facts语言,所以共同误解标题语义仍可能漏过。独立检查应选择不同表示:真实文件原行对照、完整wire重编码、临时库重开、删证据反事实与新解压运行分别检查不同边界。把同一布尔函数调用一百次不能替代这些不同路径。

确定性程序不需要为同一固定输入捏造随机置信区间。任务集不是从一个已定义用户分布独立抽样,没有总体抽样前提,十八分之十八只是已观测规范符合数。若未来研究真实用户,需要先声明目标请求分布、采样方法、分组泄漏和错误判定,再选择统计估计。不能先在手工题上优化很多次,再把同一满分表当作未见数据泛化;这些题更像开发回归集。

后续新增题应来自未覆盖机制而非只换名字。例如多条同义表达检验语义召回,跨字段矛盾检验逻辑冲突,带事实标题检验解析语言,网络重试检验工具状态;当前程序在其中若失败,应保留失败并收窄能力声明。课程终点要求读者能提出这样一条分隔实验、预测哪个阶段会先失败,再实际观察;这比把所有新需求塞进一个不可解释总分更能积累可复用知识。

TRY IT YOURSELF

基础:重复引用

G有3条,A把其中1条重复输出5次,覆盖多少?

提示 1
覆盖按来源事实身份集合算,重复次数是否会增加新成员?
提示 2
先将A去重,再求与G的交集和差集;把输出频次与不同事实数量分开。
对照参考解答
按身份集合去重,交集大小1,覆盖1/3。输出次数不提供额外事实。

TRY IT YOURSELF

进阶:压缩与选择

源事实集合相等,但head任务失败,是否推翻集合证明?

提示 1
集合证明的对象在预算选择之前还是之后?
提示 2
保持F=P后继续执行head,检查selected是否包含目标;选择粒度与包装成本是另一阶段的变量。
对照参考解答
不推翻。证明只保证选择前的支持集合相同;预算选择后的子集可不同,粒度与开销改变导致目标未进入窗口。应检查selected而非改写压缩结论。

TRY IT YOURSELF

挑战:测试分数外推

十八题18/18,能否声称所有社团助手请求都可靠?

提示 1
18题是按什么总体随机抽样的,默认生成器又支持什么语言范围?
提示 2
把固定规范测试结论与开放语义、多用户、远程模型分别列为不同命题,未验范围不自动继承通过。
对照参考解答
不能。有限作者设计任务无随机总体采样,且默认生成器是字段抽取。只可声明指定规范测试通过,开放语义、多用户与远程模型仍未验。

CHECK YOUR UNDERSTANDING

检验理解

先作答,再决定是否展开解析。选择题用于发现理解缺口;独立实现与迁移任务仍需另行检验。

1. 108记录来自?

查看解析所有配置固定同一资料和任务,比较选择与表示。
2. head压缩17/18说明?

查看解析project源声明仍在,最早失效在打包选择。
3. 删证据后仍答对首先检查?

查看解析这个实验专门检查信息路径。
4. 有限固定测试满分能证明总体可靠?

查看解析测试分布与真实任务能力边界必须保留。

自行标记用于记录学习进度,不代表通过项目验收。