CCAR-F 备考手册 · Claude Certified Architect – Foundations
Scenario 6 · 主考 Domain 4 / 5

S6 · Structured Data Extraction
从非结构化文档抽取、校验、并优雅地处理边界

官方设定:用 Claude 构建结构化数据抽取系统。系统从非结构化文档中抽取信息、用 JSON schema 校验输出、保持高准确率;它必须优雅地处理 edge case 并与下游系统集成。 与 S4 一样,本场景没有官方样题,坑位地图直接贴 TS 4.3、TS 4.4、TS 4.5、TS 5.5、TS 5.6 的措辞。

设定里最重的词是「gracefully」 — 优雅地处理 edge case,翻译成考点就是:信息缺失时不编造(nullable)、类别不明时有出口("unclear"/"other")、源数据矛盾时保留矛盾(conflict_detected)、抽不出来时诚实上报而不是重试到死。整章可以围绕这一个词展开。

一、从零设计:schema 先于 prompt

为什么用 tool_use 而不是「让它输出 JSON」

定义一个以 JSON Schema 为入参的工具、让模型「调用」它、从 tool_use 响应里取参数——这是拿到保证符合 schema 的结构化输出最可靠的路径,它彻底消灭了 JSON 语法错误。

Schema 的四个 graceful 设计

"vendor_name":      {"type": ["string", "null"]}   ✔ nullable · 源文档没有就返回 null,不为满足 required 而编造
"doc_type":         {"enum": [...,"unclear","other"]}  ✔ 歧义有出口("unclear")、新类别有出口("other")
"type_detail":      {"type": ["string","null"]}    ✔ "other" 的配套 detail 字段,保持可扩展
"calculated_total": {"type": "number"}             ✔ 与 stated_total 并列,暴露语义错误
"conflict_detected":{"type": "boolean"}            ✔ 源数据自身矛盾时置真

tool_choice 怎么选

需求取值
有多个抽取 schema、文档类型未知,只要求「别给我返回散文」"any"
必须让 extract_metadata 先于 enrichment 跑forced {"type":"tool","name":…}
工具是可选辅助,模型可以直接答话"auto"

二、上线:五次踩坑

① schema 全绿,下游照样拒收

strict schema 消灭语法错误,但不消灭语义错误:明细加起来不等于总额、值放进了错误的字段(vendor 名写进了 bill_to,两边都是 string,schema 一路放行)。 解法是单独的语义验证层:calculated_total 与 stated_total 并列抽取,字段归属独立校验。

② 必填字段大量返回 null

值其实在文档里,只是写得不正式("about a teaspoon"、"2 tbsp")。这是 few-shot 的适应症之一:示范从非正式计量与多样文档结构中正确抽取。 反向的错法是把字段改成 required 强制模型给值——那会把可见的 null 变成不可见的杜撰。

③ 重试三次仍然失败

要区分两类失败:格式/结构错误(信息在文档里,模型只是没组织对)重试有效——做法是把原文档 + 失败的抽取结果 + 具体的验证错误三件套一起送回去;信息根本不在源文档里(例如合同把管辖法律引用到一份未提供的主协议)重试无效,再跑一百次也变不出来。

④ 97% 的准确率骗了所有人

聚合准确率会掩盖特定 document type 或 field 上的塌方。 削减人工复核之前必须先按 type × field 分段验证;置信路由要满足三个条件——field-level、用 labeled validation set 校准过、高置信区间保留 stratified random sampling 持续测错并捕捉新出现的错误模式。低置信与源文档歧义/矛盾的抽取优先给人工。

⑤ 大批量跑完才发现 prompt 有问题

Batches API 省 50%、最长 24 小时窗口、无 latency SLA——适合过夜跑大批量抽取。但要先在样本集上把 prompt 调好再上量,最大化首过成功率;失败按 custom_id 定位,只重提失败项并做针对性修改(超长文档先 chunk)。

三、下游要的不只是值

抽取结果要与下游系统集成,两条 provenance 要求跟着走:冲突值双值保留 + 来源标注(不擅自选一个),输出含发布/采集日期防止时间差被误读成矛盾。 不同内容类型按适配格式渲染——财务数据用表格、叙述用散文、技术发现用结构化列表——不要统一成一种格式。

四、坑位地图

决策点正确直觉常见干扰项工艺
1. 保证结构化输出tool_use + JSON Schema;类型未知时 tool_choice: "any"D6 用 prompt 要求「只返回 JSON」;D3 强制某个具体 schema
2. schema 过了但值不对加语义验证层(calculated_total vs stated_total)D3 加正则/类型约束;D1 调 tool_choice
3. 字段可能不存在设为 optional / nullableD6 设成 required 逼模型给值 → 变成杜撰
4. 类别不在 enum 里"unclear" + "other" + detailD3 每发现一类就加一个;D5 干脆去掉 enum
5. 重试无效先判断信息是否在源文档中;不在就 null + 标记D2 加大重试次数;D3 降 temperature
6. 源文档自相矛盾双值 + conflict_detected,保留矛盾D5 静默改成算术正确值;D5 丢弃该文档
7. 削减人工复核分段验证 → 校准 field-level 置信 → 分层抽样持续测D6 未校准置信路由;D3 按文档量削减;D3 纯随机抽
8. 误报归因detected_pattern 字段支持按 pattern 聚合D3 自由文本 rationale;D6 自报 confidence
外部课程 · CertSafari — 本章 7 个考点(展开查看)

用于补读和错题复盘;第三方 AI 生成练习材料,非官方题库。核验答案时以 Exam Guide 和官方文档为依据。复盘方法 · 链接核对:2026-10-16。

场景题组

ch20 · Q1 · 准则 P2
The semantic validation layer is already in place: the extraction tool returns calculated_total beside stated_total, and arithmetic mismatches are caught. Placement errors are not — on about 2% of invoices the vendor's own address lands in bill_to, and since both values are well-formed addresses nothing in the output contradicts either one. Your team proposes bolting on a second pass that re-reads each invoice and re-derives the address fields. Volume is 40,000 invoices a night through the Message Batches API. What should you do?
正确 CTS 4.4 的自纠验证流不是「抽完再查一遍」,而是在同一次抽取里并列抽出一个能互相印证的值——calculated_total vs stated_total 是它对数值的用法,conflict_detected 是它的通用形态。放错格子之所以静默,是因为输出里只有一个地址、没有第二样东西能与它矛盾;把地址上方印着的 party name 一并抽出来,矛盾就出现在同一条记录内部,而此刻文档还在上下文里。
D2 过度工程违反 P2A:为 2% 的放错率让 40,000 份/夜的语料整体再过一遍,token 支出翻倍。独立实例复审(TS 4.6)是留给「同一 session 推理惯性」那类问题的;这里在同一次调用里加一个字段就能造出矛盾,轻量手段远未用尽。
D3 治标不治本违反 P1B:只逮得住「vendor 自己的地址」这一种放错,ship-to 落进 bill_to、remit-to 落进 ship-to 一律照过。题干已指明根因是输出里没有任何东西与放错的值矛盾,主数据比对没碰这一环,只是在外面加了一道窄门。
D4 甩锅错位违反 P1D:把抽取质量的责任推给一个在自己职责内工作正常的下游系统。会计系统判得了「这条记录不对」,判不了「哪个字段串了位」,也没法把信号回灌给抽取端——每晚 800 条会变成人工退件,而不是可自动拦下的记录。
ch20 · Q2 · 准则 P6
Extraction returns null for the required coverage_limit field on 18% of insurance policies. Inspection shows the value is present but stated informally ("up to two hundred fifty thousand", "the standard cap", "250k"). What should you do?
正确 DTS 4.2 点名的两条适应症正好命中:few-shot 降低抽取幻觉(明确举了非正式计量与文档结构多样),并可解决必填字段被空/null 抽取的问题——通过示范从不同格式文档中正确抽取。
D6 概率当保证违反 P8A:TS 4.3 的方向正好相反——字段设为 optional/nullable 是为了防止模型为满足 required 而编造值。强制必填会把 18% 的 null 变成 18% 的杜撰数字,错误从可见变成不可见。
D2 过度工程违反 P2B:TS 4.4 指出 retry 对格式/结构错误有效。这里模型不是格式出错,而是不认为这些表述算数——同一个 prompt 重跑多半返回同样的 null,只是多花一次钱。
D2 过度工程违反 P2C:用正则理解「the standard cap」这类自然语言表述,是把最适合 LLM 的工作交给最不适合的工具,还要长期维护一份永远追不全的表述清单。
ch20 · Q3 · 准则 P6
Validation fails on 11% of purchase agreements because the required delivery_terms field is missing. Investigation shows those agreements incorporate delivery terms by reference to a master supply agreement that is not included in the request. Your retry loop re-sends the document with the validation error three times, then gives up. What should change?
正确 BTS 4.4 的 retry 边界:所需信息根本不在源文档中时重试无效(guide 的原例正是「信息只存在于一份未提供的外部文档里」)。配套 TS 4.3:字段设 nullable 以防模型为满足 required 而编造。
D2 过度工程违反 P2A:加大重试次数是把一个注定失败的循环跑得更久更贵;「更仔细地找」也找不到文档里不存在的内容。
D3 治标不治本违反 P1C:few-shot 治的是「文档里有但认不出」。题干已经调查清楚:这些协议确实没有这一条,只是引用了另一份文件。诊断已排除这个方向。
D3 治标不治本违反 P1D:采样参数影响措辞稳定性,与信息是否存在无关。降温只会让模型更稳定地返回同样的缺失——或更稳定地编造。
ch20 · Q4 · 准则 P8
Overall extraction accuracy is 96%. Leadership wants human review cut by 75%. You have a labeled validation set. What must happen before the reduction?
正确 CTS 5.5 的完整链条:聚合准确率可能掩盖特定 document type / field 上的塌方,所以先分段验证;置信必须用 labeled validation set 校准后才可路由;高置信区间保留 stratified random sampling 持续测错并捕捉新错误模式。三步缺一不可。
D3 治标不治本违反 P1A:按数量而非准确率削减,恰好可能踩中高频但表现差的类型。题干给的 96% 正是尚未分段的聚合数字——用它做分配决策就是在猜。
D6 概率当保证违反 P8B:两处错。置信未经校准就当路由依据;而且是整份文档一个分数,TS 5.5 要求 field-level——一份文档里可能只有某一个字段不可靠。
D3 治标不治本违反 P8D:纯随机抽样能测量整体错误率,但不能分配复核力量——它给 99% 准确的类型和 70% 准确的类型同样的复核概率。分层抽样在正解里的作用是持续监测,不是替代分段验证。
ch20 · Q5 · 准则 P5
You have five extraction schemas, one per document type. Incoming scans are unlabeled. In roughly 9% of requests the model returns a prose summary instead of calling any extraction tool, breaking the downstream loader. What configuration fixes this?
正确 DTS 4.3 的原话级 skill:存在多个抽取 schema 且文档类型未知时,设 tool_choice: "any" 以保证结构化输出。"any" 的语义正是「必须调某个工具、但由模型选哪个」——恰好匹配题干的两个约束。
D6 概率当保证违反 P3A:"auto" 的定义就是模型可以返回纯文本。用 prompt 措辞覆盖一个 API 层的开关语义,是拿概率赌确定性,而 API 直接提供了确定性选项。
D3 治标不治本违反 P5B:forced 确实保证有工具调用,但锁死了哪一个。文档类型未知时强制走发票 schema,会把其他类型硬塞进发票结构——把可见的失败换成了静默的错误抽取。
D2 过度工程违反 P5C:全字段 optional 的大一统 schema 放弃了类型特异的约束,等于让 schema 层几乎不再校验任何东西;而现成的 "any" 一个参数就能解决。
ch20 · Q6 · 准则 P6
Extraction on utility statements fails validation on about 6% of documents: the stated total does not match the sum of the itemized charges. Manual inspection shows the printed total on those bills is simply wrong. How should the pipeline handle this class?
正确 ATS 4.4 的自纠验证流设计:并列抽取 calculated_total 与 stated_total 以标记差异,加 conflict_detected 布尔表示源数据自身不一致。它把「文档有问题」与「抽取有问题」清晰分开——正是 P6 信息保全的形态,也是设定里 "handle edge cases gracefully" 的字面落地。
D5 吞错或炸链违反 P6B:静默改写源文档声称的数值,把客户账单上的真实矛盾抹平成看似正常的记录。下游再也无法知道这份账单本身有问题。
D2 过度工程违反 P2C:抽取本身没有错——它忠实反映了一份自相矛盾的文档。重试只会让模型在「照抄错误总额」和「改成正确总额」之间反复,两者都不是问题所在。
D5 吞错或炸链违反 P6D:丢弃把 6% 的数据连同「这些账单有对账问题」这个有价值的发现一起扔掉。可解析、可标注的冲突不该被当成不可处理。
ch20 · Q7 · 准则 P5
A batch of 1,200 research abstracts returns with 54 failures: 46 exceeded the context limit and 8 failed transiently. What is the correct handling?
正确 CTS 4.5 的原话级 skill:按 custom_id 定位失败项、只重提失败的那些并做针对性修改——guide 举的修改例子正是「把超出 context 限制的文档 chunk 后重提」。两类失败各得其所。
D2 过度工程违反 P2A:重跑 1,146 份已成功的文档成本翻倍且无收益;对全部文档一律 chunk 还会把本来完整的摘要切碎,损害原本正确的抽取质量。
D1 凭空捏造违反 P1B:同步 API 与 batch API 面对同一个模型上下文限制,不存在「同步端限制更宽」这回事。超长文档在哪条路径上都超长。
D5 吞错或炸链违反 P6D:把 54 份可修复的失败标成不可处理,用聚合百分比掩盖具体缺口——而其中 46 份只需 chunk 一下就能成功。
ch20 · Q8 · 准则 P6
Your extraction reports a market-size figure that appears twice in the same document pack: $2.4B in a vendor whitepaper collected last January and $3.1B in an analyst note collected in September. Downstream systems consume a single record per metric. What should the extraction produce?
正确 ATS 5.6:可信来源统计冲突时双值保留 + 来源标注而非擅自选取;结构化输出要含发布/采集日期以支持正确的时间解读。「下游只吃一条记录」是接口约束,正确的响应是让接口容纳冲突标注,而不是让抽取层伪造确定性。
D5 吞错或炸链违反 P6B:取平均制造了一个两个来源都没说过的数字,冲突被伪装成共识——最彻底的信息销毁。
D4 甩锅错位违反 P6C:用日期裁决正是 TS 5.6 要避免的——日期是附上去供解读的,不是用来淘汰另一个来源。两份材料的口径也可能根本不同。
D5 吞错或炸链违反 P6D:返回 null 把「有两个各有出处的候选值」伪装成「没有数据」。null 的正当用途是信息在源文档中确实不存在(防编造),不是冲突处理手段。
ch20 · Q9 · 准则 P2
The 8,000-filing archive spans four filing formats; three of them were retired before 2015 and together account for about 3% of the corpus. Your extraction prompt scores 97% on a 60-document sample drawn at random from the archive. Because a batch submission has up to a 24-hour processing window, you get at most one full-corpus result per day. How should you change the sample before committing the full run?
正确 BTS 4.5 把「先用样本集精化 prompt 再大批量」列为 skill,目的是最大化首过成功率——但样本只有覆盖到会失败的那一类,这个数字才对全量有预测力。3% 占比的三种退休格式在随机抽的 60 份里期望不到两份,97% 因此是一个只描述主流格式的数字。TS 5.5 的分段思路同样适用于抽样端:按 document type 分层,用同样的样本预算换到确定的覆盖。24 小时窗口是这里的硬约束——全量迭代一天一轮,样本迭代以分钟计。
D3 治标不治本违反 P1A:扩样本量没有改变抽样方式。300 份随机抽里,那三种格式合计期望约 9 份、单种 2–3 份,而它们各自还有版式变体——按比例复制语料的偏斜,等于在最可能失败的地方采样最少。题干指向的是格式分层缺失,不是样本不够大。
D2 过度工程违反 P2C:用 8,000 份的全量成本换本可在几十份样本上得到的信息,是最贵的调试方式。24 小时窗口还让这条路每轮迭代要一天、改完再等一天验证——把生产批次当实验台,正是 TS 4.5 那条 skill 要避免的。
D4 甩锅错位违反 P1D:把抽取失败的成本转嫁给分析师。「占比小」是相对语料说的,对拿到这批 filing 的人来说是 100%;而退休格式往往正是历史归档里最需要被正确抽出的那部分。它也没回答题干问的那件事——样本该怎么建。