【可执行状态】现在就能做(填制引擎跑在公网,按附录 C 把 doc-filler 连接器接进入口即可)
【本讲对应资产】doc-filler 引擎(5 个工具);本讲主角是 filler_check,配合 filler_run filler_batch
【本讲原理来源】吴恩达《Agentic AI》评估与错误分析方法(四封设计模式公开信)
先设想一个场景:学期末最后一天,你把四十份结课作业打包交给系里。三小时后,文件被退了回来。
退回的理由不是内容,是格式:教务点开其中一份,页脚的学年学期是空的;再点开另一份,授课教师那一栏没填。那些位置本该填上,成品上却留了白。
打个比方:这就像一箱鸡蛋里发现一个破的——你不打开每一个,
就不知道到底坏了几个。
现在问一句:你拿什么去证明“剩下的三十八份是好的”? 逐份打开看吗?翻到第二十七份你才找到第一处空,翻到第四十份时,你已经不记得第一份长什么样了。
这一讲要立的,就是这一句话:批量出货的交付物,从来不是“文件”,而是“文件 + 一份能读的校验报告”。 报告说通过,才叫交付;报告没通过,文件再多也不算。
学期末最后一天,周老师(化名)把四十份结课作业打包交给系里。三小时后被退回。
退回的理由不是内容,是格式:教务点开其中一份,发现页脚的学年学期是空的;另一份的授课教师栏没填——那些位置本该填上,成品上留了空白。
周老师打开文件夹逐份看:四十份里翻到第 27 份才发现第一处空。没有报告,就只能靠眼睛一份一份翻;翻到第四十份的时候,你已经不记得第一份是什么样的了。
更麻烦的是,她甚至说不清这一批到底是哪一次跑出来的——中间改过数据、重跑过一遍,可她手上没有任何东西能把“这一次”和“上一次”分开。退回来的是一个包,不是一个可以追问的对象。
这一讲是全书的纪律章。前面几讲反复提过“交付前调 filler_check”,这一讲把它讲透:报告里到底有什么、怎么看、缺项按什么顺序查,以及为什么“校验通过”这件事,既要信,又不能只信。
填制引擎的返回值里有一份校验报告(reports),每份文档一条(书里常拿第一条 reports[0] 举例)。一条报告里有这些字段:
| 字段 | 它是什么 | 你该怎么看 |
|---|---|---|
app_name | 这次跑的是哪个场景(应用) | 确认场景没选错 |
generated_at | 出件时间 | 归档时连同报告一起留痕 |
replaced | 已替换清单,每项含占位符名与出现次数(placeholder + count) | 一眼看全哪些位置填上了;同名字段出现两次会显示次数 |
unreplaced | 未替换:模板里有这个占位符,但你的配置没覆盖它 | 不为空 = 模板里有你没想到的位置 |
missing_fields | 缺失字段:配置了要取这个字段,但这次的数据里取不到 | 不为空 = 数据本身缺项 |
tables_filled | 表格填充行数(模板里的表填了几行) | 逐行核:行数与你的记录条数对不对 |
warnings | 引擎给你的提醒项。目前已实现的这一类提醒是:模板里配置了表格、但没定位到表格位置时,会写一条「表格未定位: 表格名」 | 逐条读,别跳;出现这条说明表格那块要人工看一眼 |
stats | 统计:template_placeholders(模板里占位符总数)、mapping_items(映射配置条数) | 用这两个数判断这次覆盖齐不齐 |
打个比方:这份报告就像医院给的体检单——不必懂每个指标的原理,
但要知道哪几项是“正常范围”,超了就要看医生。
别被字段名吓住。这些字段其实只回答三个问题:该填的填了没有(replaced)、有没有漏的(unreplaced / missing_fields)、表格有没有少行(tables_filled)。 其余的字段是给你留痕用的。
例如:就像填快递单只写了收件人姓名,电话、地址、邮编全空着——
单子是打出来了,但寄不出去。
课上最常见的情形是:老师只填了四个字段就出件。
数据里只给了 courseCode、courseName、teacherName、department 四项,其余没给,公共信息也是空的。引擎照跑不误,但报告会如实告诉你缺了什么:
| 报告项 | 实际数值 |
|---|---|
replaced | 13 项(模板里 13 个占位符它都试着替换了) |
unreplaced | 0(模板里没有多余的占位符) |
missing_fields | 9 项:applicableScope、courseNature、credits、currentDate、date、englishName、formattedSemester、semester、totalHours |
verdict | 有缺项:未替换 0、缺失 9 |
这份报告的价值在于它不会替你圆场:它不会拿去年的学时凑数,也不会把学分留空还不告诉你,而是把九个缺的字段名一个一个列出来,让你照着去补。比如,它宁可把 totalHours 这串英文名摆在你面前,也不肯填一个“48”让你看着顺眼——因为那个 48 不是你的数据,是它编的。
这就是「校验才算交付」的意思:交付之前,先要一份不肯替你圆场的证据。
verdict这么多字段不用你逐个数。把最近一次填制的报告交给 filler_check,它返回一句人话结论:
这就是交付门禁:verdict 不是「校验通过」,文件就不许交出去。 不是“差不多可以”,不是“就一两处空的”,是不许。这一条没有例外,因为退件的人不会跟你讲情面,他只按格式看。
“做完之后必须验一遍”——这不是软件带来的新规矩,它比电脑早得多。
第一步,校勘与“三校一读”。 西汉刘向校书,就是一项纯粹的校验活:把同一部书的不同抄本摊在一起,逐字比对,对出来的差异写成“别录”。到了印刷时代,出版业把这件事标准化成“三校一读”——一份稿子至少校三次、通读一次,每一遍查的东西还不一样:一校看错字,二校看版式,三校看整体。 为什么不能一次到位?因为“看错字”和“看版式”用的是两种注意力,混在一起做,两个都做不细。打个比方,这就像出门前的一套动作:先看钥匙带没带,再看门锁没锁——顺序和分工,本身就是质量的一部分。
第二步,复式记账。 一四九四年,意大利数学家帕乔利在《算术、几何、比与比例概论》里系统写下了复式记账法:每一笔账同时记进两个科目,两侧必须相等[1]。这套方法最厉害的地方不是记得准,而是“不平就是错”——账目自己会报警。 它把“对不对”从人的记忆里搬到了数字的等式上。五百多年过去,全世界还在用它。
第三步,软件里的“断言”。 计算机出现以后,工程师把同一件事变成了代码:程序跑完自动检查几个条件,不满足就当场报错,不许悄悄过去。这就是今天所有自动化测试的起点——让机器自己证明“这一遍是好的”,而不是让人事后回忆“好像是好的”。
第四步,也就是这一讲的校验报告。 它把前三步各取一段:三校一读的“分项查”,复式记账的“不平即错”,断言的“机器自证”。一份报告,把“哪里没做对”从人的眼睛,搬到了字段上。
回头看这四步,有一条线一直没断:越是要负责任的事,越不能只靠“我记得”——它必须留一份能被人复查的凭据。 校验报告就是填制这件事的凭据。
报告里指出缺项之后,排查顺序是固定的三条,顺序不要乱——乱序查会浪费一晚上:
| 顺序 | 现象 | 原因 | 怎么补 |
|---|---|---|---|
| ① | 整批都缺同一批字段(学年学期、教师、班级、部门) | 顶层公共信息没传 | 补 context_json 再跑 |
| ② | unreplaced 里有占位符,但你的字段明明是齐的 | 模板里有多余的占位符,映射配置没覆盖它 | 要么在映射里补上它,要么确认这个位置学校本来就该空着——不能默认它“没关系” |
| ③ | missing_fields 里列着字段名 | 数据里没给这个字段 | 回到数据源,把这一项补上(不是改模板,也不是手工填空) |
三条按顺序走,是因为它们的“根”在不同的地方:先看公共信息(整个场景只有一个根),再看模板与映射(一份配置的根),最后看数据(一条记录的根)。 从最大的根往最小的根查,一次就能定位。
假设你不按顺序来:看见缺 semester,先去数据里翻了一遍,没找到,又去改模板,改完发现还是缺——一晚上就过去了。其实根子在开头那一层,补一次 context_json 就全好了。排查顺序不是讲究,是省时间。
verdict 说通过,是不是就能交了不能。这一条必须说清,否则会出大问题:
verdict 说“校验通过”,只证明“该填的位置都填上了”,不证明“填进去的内容是对的”。举例:把 A 课的课程代码填进 B 课的表格——每一处都填上了,replaced 一个不少,unreplaced 为空,报告完美,verdict 是「校验通过」;但这份件是错的,交到教务处会被退。报告不知道 A 和 B 哪门是哪个,它只知道“这里有一个格子,格子里有字”。
所以本书的交付标准是一条两段式的链:先用报告的 verdict 挡住“没填全”,再用人眼抽检挡住“填错了”。 报告是门禁,不是保证。两段都过,才叫交付。
不行。这是最容易图快的一步,也是最容易留下后患的一步。
假设报告说缺两处,你打开成品,用 Word 把那两个空格往里一打,交出去——从外观上看,件是齐的。但是:这两处没有走过替换,也没有任何报告记录它。 下一批、下下学期,同样的问题还会再犯一次;而这一份件,一旦被追问“这处是谁填的、什么时候填的、填的依据是什么”,你答不上来。
手工补的是字,丢的是凭据。 正确动作只有一条:回去补数据、重跑、重新出报告。补出来的那一份,必须也是跑出来的那一份。
因为 filler_check 解读的是最近一次成功填制的结果。中间如果没跑成功,它读出来的当然还是上一次的结论。
常见的一种情况是:连接器没登记信任,被静默跳过——日志里打一行 skipping untrusted server,界面上不报错,你以为跑了,其实什么都没跑。于是你改了数据、以为重跑了、再去读报告,看到的仍是老结论。好比你把信投进了没开张的邮筒,回头查物流,当然查不到。
处理办法两步:先确认新的 filler_run / filler_batch 真的跑成功了(有没有新产物、有没有新的 generated_at),再读报告;连接器的登记步骤见附录 C。
把本讲的交付链摊成一张表,三道门各管一段:
| 门 | 谁在把守 | 挡住的错 | 挡不住的错 |
|---|---|---|---|
| 第一道:出件 | 引擎 | 根本没生成 | 生成了但内容不对 |
| 第二道:校验报告 | verdict | 漏填、缺字段、表格少行 | 填错了(串行、错值) |
| 第三道:人眼抽检 + 签字 | 你 | 串行、错值、口径不符 | ——(最后一道,责任到底) |
表里最该记住的是一句话:每往前一道门,责任就往人这边挪一格。 第一道门是机器的,第二道门是机器的但由你解读,第三道门完全是人。三道门都过,才叫“交付”;只过第一道,那叫“生成”。
调 filler_check,把最近一次填制的校验报告读给我:每份文档的 verdict、已替换几处(replaced)、未替换项(unreplaced)、缺失字段(missing_fields)、
表格填充行数(tables_filled)、有没有warnings、以及stats里的模板占位符总数与映射条数。
如果有缺项,按“先查顶层公共信息、再查模板与映射、最后查数据”的顺序告诉我每一处该补哪里。
一次只跑一个动作:先读报告,再决定要不要重跑。
| 产物 | 内容 |
|---|---|
逐份的 verdict | 每份文档一条结论;批量出件时逐份看完,不是只看第一份 |
| 三张清单 | 已替换(含出现次数)/ 未替换 / 缺失字段 |
| 表格核对结果 | tables_filled 与你的记录条数是否一致 |
| 告警与统计 | warnings 逐条、stats 的两个数(模板占位符总数、映射条数) |
| 门禁结论 | 全部「校验通过」→ 进入人的复看;有任何一条有缺项 → 不许交付 |
(本书四场景的实测结论:teaching 出件 2 份、jiaoyan 出件 1 份、homework 出件 2 份、cpi 出件 1 份,全部校验通过(未替换 0 / 缺失 0)。)
replaced 的覆盖对不对:stats.template_placeholders 是模板里的位置总数,已替换的地方要能对上;差出来的部分,去 unreplaced 里找名字。tables_filled 与记录条数对账:表格多一行少一行,报告里看得见。比如四十人的名单,表里只填了三十九行,差额就在这个数上。warnings 逐条读:它不拦住出件,但它是引擎给的提醒,跳过等于自己放弃了线索。generated_at 与报告一并留下,将来被退回时能查是哪次、错在哪。错误一:只看文件,不看报告。
表现:交付时发一堆 docx,没有结论。
原因:把“出件成功”当成了“交付完成”。
排错:报告先看,文件后看。 本讲的顺序是固定的:filler_check → 复看 → 交付。
错误二:报告有缺项,却想着“手工补上那两处就行”。
表现:打开成品,把空着的地方用 Word 手工填上,交出去。
原因:图快,跳过了链路。
排错:手工补件是校验盲区——补的那一份没走过替换,也没有报告记录它。一律回去补数据重跑;重跑出来的件才有报告。
错误三:批量只看第一份的 verdict。
表现:第一份「校验通过」,后面三十九份没看就交了。
原因:不知道报告是一份一条。
排错:逐份看。报告条数应当等于产物份数,两个数对不上,说明还有文件没被报告覆盖。
错误四:因为报告“通过”就不做人工核对。
表现:件交上去了,被教务处退回来说课程代码串了行。
原因:verdict 只管“填没填”,不管“对不对”。
排错:报告过门,人眼定签:抽三份逐字核对课程代码、学号、学时这类关键字段。
错误五:想跑第二次校验,但报告还是上一次的。
表现:改了数据重跑,filler_check 读出来的仍是老结论。
原因:filler_check 解读的是最近一次填制;中间没成功跑过新的填制,它当然还是旧的。
排错:先确认新的 filler_run / filler_batch 真的跑成功了,再读报告;连接器没登记信任时会被静默跳过(日志里打 skipping untrusted server),那种情况下你以为跑了,其实什么都没跑。
verdict 不是「校验通过」,就不许交付;差一处也不许。generated_at)与报告一并归档;被退回、被追问时,能说清这一批是哪一次跑出来的。grant_fill(课题字典 + 模板 → 全套文档 + 校验报告)是同一个道理;备课线的产物虽然形态不同,也同样要有一份“哪里没做对”的东西跟着。filler_check,看 verdict。报告管“填没填”,人管“对不对”——两道门都过,才叫交付;只过第一道,那叫生成。
| 工具全名 | 一句话作用 |
|---|---|
mcp__doc-filler__filler_check | 解读最近一次填制的校验报告,给出 verdict(交付门禁) |
mcp__doc-filler__filler_run | 重跑一份,覆盖上一次的校验结论 |
mcp__doc-filler__filler_batch | 重跑一批,逐份生成报告 |
mcp__doc-filler__filler_help | 复核某个场景的占位符映射,判断 unreplaced 从哪来 |
mcp__doc-filler__filler_scenarios | 复核场景与占位符数,确认 stats 里的两个数对不对 |
verdict 不是「校验通过(未替换 0 / 缺失 0)」就不许交context_json;未替换 → 模板里多余占位符没配映射;缺失字段 → 数据里没给verdict 过后还要抽三份人眼读回,缺这一步不算交付[1] Pacioli L. Summa de arithmetica, geometria, proportioni et proportionalita[M]. Venezia: Paganino de Paganini, 1494.(复式记账法的系统表述,后世称“现代会计之父”的这部著作)
[2] 中华人民共和国国家质量监督检验检疫总局. 校对符号及其用法: GB/T 14706—1993[S]. 北京: 中国标准出版社, 1993.
[3] Ng A. Agentic AI(智能体式人工智能)[EB/OL]. DeepLearning.AI, 2024.(书中“评估与错误分析”“设计模式”等提法的来源;该材料中的对照数字为作者梳理多个研究团队结果所得)
[4] 教育部. 高等学校预防与处理学术不端行为办法: 教育部令第 40 号[Z]. 2016-06-16.
数据与平台:本讲所述校验字段名与 verdict 结论形态来自 zhenyuonline.cn 的 doc-filler 引擎(2026-09-17 实跑核对):
reports[0] 的字段为 app_name / generated_at / replaced / unreplaced / missing_fields / tables_filled / warnings / stats;
四场景实测(teaching 2 份、jiaoyan 1 份、homework 2 份、cpi 1 份)全部「校验通过(未替换 0 / 缺失 0)」;
文中“只给四个字段、缺失 9 项”为真实报告形态。本节未给出任何未经实测的耗时或成功率数字。