visitor@webworks:~/scroll-demo-anti-hallucination$
cd ~ cd ../demos cat text-version

堵不如疏:让 agent 不要被逼到编造

一个知识库摄取项目跨 9 天 7 阶段的 prompt 演化。v3 编造 3/3 → v4 加 verify-refs 硬门槛 0 编造但充实度减半 → v7 给 agent 每种"不知道怎么办"的情况下显式的出路。

数据来自 2026-04-27 ~ 05-06 的工作报告 · 已脱敏

背景

一个项目要把分散在多个数据源的资料聚合到本地 markdown 知识库:200 多份策划案 docx(在飞书)、60 多份配表 xlsm、大量设计稿、一些代码。最初的方案是一个"摄取 agent",每个业务跑一次。

9 天 7 阶段 — 一张时间线

timeline · 2026-04-27 → 05-06

v1:单 agent 字数差 3 倍

最初的 prompt 骨架长这样:

v1 prompt 骨架(脱敏)
# prompt: v1 单 agent

你是 KB 摄取 agent。

任务:把以下 4 个源整合成一份 markdown 文档:
  - 飞书策划案 docx
  - 配表 xlsm
  - figma 设计稿
  - 代码 (lua / c#)

反幻觉:
  - 引用必须真实
  - 路径必须存在

12 章节模板:总览 / 玩家视角 / 奖励投放 / ...

开始。

# 什么都对,什么都没说怎么做

跑出来:

原因不复杂:单 agent 在一次对话里要做的事太多 — 拉 4 类素材、跨源对照、组织章节、写引用、检查命名。任务密度过高时,模型最终是"完成什么算什么"。它会从最不关键的步骤跳过。

v2:拆 agent + 改成读真源

拆成 5 个"域 agent" + 1 个综合 agent + 1 个审计 agent。3 个域 agent 各管一个数据源,综合 agent 跨域整合,审计 agent 用 28 项 y/n checklist 反向检查。

multi-agent topology

拆完后改了两件事:

重跑同一个业务:35500 字,跟手写持平。

v3:编造事故 — 没有出路时,编一个就是出路

后续加了一个"修复 agent",基于已有 KB 文件改。跑了一批 3 个业务,审计都过,文件看着完整。

抽查发现:3 个业务里 3 个都写了不存在的代码文件路径。

v3 编造样本(脱敏)
## 主流程

主入口在 `SomeFooView.lua:88`,处理玩家点击 ...
具体逻辑见 `OtherView.lua:120` 中的 OnClick 方法。

# 代码库实际:
#   SomeFooView.lua  → 不存在(真实文件名不同)
#   OtherView.lua    → 不存在
# 但行号 / 引用形式 / 语境措辞看起来完全合理

prompt 里写了"反幻觉,引用必须真实",但产物里仍然出现编造。问题在于:找不到真路径时,prompt 没说"标信息缺口"还是"跳过这一段"还是"留 TODO"。

这条规则没有出路。在没有指定动作的情况下,产物里看到的是:填一个看着合理但实际不存在的引用 — 这成了实际的默认产出。

v4:加 verify-refs 硬门槛

引入一个独立的命令行工具,检查每个引用:文档链接 → 真实可达;代码路径 + 行号 → 文件存在 + 行号在范围内;图片路径 → 文件存在。agent 在 finish 之前必须跑一次,只要有 ✗ 就不能 finish。

v3 · 无外部 verify
v4 · 外部 verify 硬门槛

之后跑的 45 个业务,编造数为 0。但是 — 平均充实度明显下降。

这就是"堵"的代价。verify 工具卡住编造后,产物形态明显变薄 — 留下的部分集中在引用层面能 verify 的内容上。prompt 里没说"verify 不过怎么办",产物上呈现的是退守:字数减少,内容只写一定能 verify 的部分。安全度上去了,信息量下来了。

v5 → v7:给每种"不知道怎么办"显式出路

后面几版的方向是给 agent 每种情况下显式的出路,而不是只设禁区:

v7 prompt 骨架(脱敏)
# prompt: v7 — 4 步必跑,每步必出 bash 调用

你是 KB 综合 agent。

按以下顺序操作,每步必须在产出里出现对应的 bash 调用:

1. 搜真源
   $ lark-cli docs +search --query "<biz>"
   $ lark-cli docs +fetch <token>

2. 验业务边界
   $ ls <p4>/Client/Binary/Src/UI/<biz>/

3. 读范本
   $ cat <kb>/规范/范本_<视角>.md

4. 读规范
   $ cat <kb>/规范/本地/设计文档写作SOP.md

4 步全跑完才进入写内容。

finish 前必跑:
   $ python kb-verify-refs.py --biz <biz>

verify-refs ✗ > 0 不准 finish

同样信息密度,v1 是"你应该做的事",v7 是"你必须依次做的事 + 每步的痕迹必须在产出里"。重跑后:字数达标,引用验证通过,业务边界对。

三个版本的充实度 vs 编造率

能观察到的现象

当 prompt 没有给 agent 具体动作时,产物形态趋向最低阻力路径:

跟业界已有方向也对得上。RAG / grounding / verifier 这些方法的有效性,不光在工具本身的强度,也在 prompt 里有没有让 agent 真去走这条路。同样的 retriever 接入,prompt 写"如果需要可以用 retriever",和 prompt 写"必须先调 retriever、产出里要看到 retrieval 步骤",agent 的实际行为差异很大。

三条具体配套:

已知边界