# Prompt 拦不住编造，能拦住的是校验层

用证据 ID 把「模型有没有编造」从判断题变成查表题 —— 候选人材料先建成带稳定 ID 的证据索引，草稿必须回报用了哪些 ID，校验层拒绝不存在的 ID，并把姓名、日期、公司当不可变事实单独校验。

让模型改写一段简历，它写出来的东西通常都很像真的。这不是因为它知道，而是因为一段通顺、具体、行文专业的句子，和一段真实经历的句子，在文本上没有任何区别。**你没法靠读一遍就发现哪句是编的。**

第一反应通常是回到 prompt 上，多写几句「不要编造」「只使用提供的信息」「如果不确定就留空」。这些写法有用，但它们改变的是概率，不是保证。模型这一轮听了，下一轮换个输入可能就不听了，而你要交付的是一份会被面试官逐条追问的简历。

所以问题得换个问法：**能不能不依赖模型的自律，而是让「这句话有没有出处」变成一个可以被代码查的问题？**

## 把材料变成可寻址的东西

第一步是在生成之前，先把候选人材料整理成一份**证据索引**：每一条事实都有一个稳定的 ID。

这一步本身不神秘，就是把散落的材料（经历、项目、技能、教育）切成一条条独立的陈述，各自编号。关键在于此后所有环节都只认这些编号 —— 事实不再是「语料里的一句话」，而是「ID 为 e17 的那条记录」。

## 草稿必须交代它用了什么

第二步是约束生成阶段：产出草稿时，模型不只要写出文字，还要**回报它引用了哪些证据 ID**。

这一步是整个设计的转折点。在那之前，校验层手里只有一段文本，任何检查都只能退化成「读起来像不像真的」；有了 ID，校验层手里就有了一条可以核对的链路 —— 这句话声称的依据是哪条。

## 校验层做两件事

第三步是确定性校验，它管两类东西。

**一类是 ID 本身是否存在于索引里。** 模型返回了一个索引里没有的 ID，直接拒绝。这里没有解释空间，是一次查表。

**另一类是不可变事实。** 姓名、日期、公司这类信息，即使 ID 合法，也要单独校验它们没有被改写。引用是对的，但顺手把公司名换个说法，同样是事实失真 —— 这类改动比整句编造更隐蔽，因为它藏在一堆正确内容里。

只有走完校验的输出，才会进入渲染。

## 为什么这个设计值钱

因为它把一个**判断题变成了查表题**。

「模型有没有编造」作为判断题，你需要一个和模型同样聪明（或更聪明）的裁判，而且每次都要重新判断。作为查表题，它是一次 `Map.has()` —— 确定的、可测试的、有失败用例的。

判断依据也因此从「我读了觉得没问题」变成了「未知 ID 的失败测试是绿的」。前者是印象，后者是证据。这也是为什么一个反例演示比一段说明更有说服力：给草稿 fixture 塞一个索引里不存在的 ID，跑相邻的校验测试，看它被拒 —— 而且你能指出失败发生在**确定性的校验层**，不是 prompt 里的某句话没生效。

## 一个容易漏掉的边界

ID 合法只说明「这条事实有出处」，不说明「这条事实贴切」。

引用了一条真实存在的经历，但用它去回答一个它并不支持的要求 —— 这个引用在 ID 层面完全合法，在校验层也过得了。所以配套还有一层需求匹配：把岗位要求逐条对到证据上，匹配不上的部分暴露出来，而不是让模型用一条沾边的经历糊过去。

**证据校验保证的是不编造，不是匹配得好。这两件事得分开验收。**

## 语义召回进来的东西，也要走同一道门

匹配环节原本是词法匹配，它的缺口很具体：岗位描述写「provision Kubernetes clusters on bare metal」，候选人材料写「ran k8s on physical servers」，字面上几乎不重叠，词法匹配会直接漏掉这条本来相关的经历。

语义召回是用来补这个缺口的。但这里有个容易被讲混的地方：**检索进来的东西，和别的事实走的是同一道校验门。** 语义相似度说明的是「这条可能相关」，它不构成「这条可以写进简历」的依据。所以召回结果只进入证据提示块，最终产物里的事实仍然要过 evidence ID 校验。

这条约束让「加 RAG」不会顺手把可靠性拆掉 —— 多召回一条错的，代价是多一个待校验项，而不是多一句编造。

## 边界

这个项目的阶段划分是**代码预设**的：材料归一化、岗位分析、确定性匹配、证据约束的草稿生成、校验、渲染。模型在其中的几个边界上负责判断，但不负责决定走哪一步。Run 可以暂停、等人补上缺失的事实，再从 checkpoint 接着跑。

所以它现在不是「模型自己规划、自由调用工具」的那种东西 —— 把阶段写死在代码里，恰恰是让证据校验能成立的前提：只有知道下一步一定是什么，你才能在那一层放一个确定的检查。

公开状态是 `Implemented for development`。以上讲的是这套机制怎么运作、边界在哪，不是它的效果有多好 —— 机制能被代码保证的部分，和它最终产出多好，是两件事。

Last updated on September 29, 2026