在前一篇 《Harness Engineering:为 AI 打造可持续迭代环境的实践》 中,我们讲了 HelixVerify 如何在线下环境用 114 次迭代 把风险样本召回率从 8% 提升到 98.86%。那是一个典型的 线下 Harness。这一篇讲 Harness 思想搬到 C 端 AIGC 生产链路后的形态 —— 蚂蚁保保险快查深度解读页面生成系统(Deep Interpretation Page Generator,以下简称 DIPG)。 DIPG 不让 C 端用户直接吃 LLM 实时生成的结果,而是把架构翻转成 “host-generate-verify-modify → DB 按品开启 → C 端直出” 。离线生成由一个带 verify 闭环的 Agentic Loop 负责,只有通过 verify 的 HTML 才会刷入 DB 并暴露给用户。实时生成只保留作为未开启品的兜底路径。即通过 Harness 的方式让 对 C 端交付的HTML 有足够好的质量。

为什么不能让实时生成直出? 最开始当然试过用户点开详情页时调 LLM 实时生成 HTML 直出。不过问题也很明显:

  1. 时延扛不住:一次完整的深度解读需要 agentic 检索素材与条款、 生成几千字 HTML,LLM 推理加起来几十秒。C 端用户等不起,“秒出”是基础体验要求。
  2. 质量扛不住:LLM 生成 HTML 会出两类错 —— 渲染类错误(孤儿闭合标签、组件层级错乱)让页面直接塌掉;幻觉类错误(数据不符、编造对比)让用户读到错信息。LLM 一次过做不到 100% 正确,直出就是赌。 C 端 AIGC 交付的本质要求是:用户点开那一刻看到的 HTML,必须是已经被校验过的。所以 DIPG 把实时生成降为兜底、把离线 Harness 的生产过程作为主路径。这篇文章就讲这个离线 verify 闭环在工程上怎么搭。

一、DIPG 的两条线上链路 DIPG 对外的产品形态:用户在支付宝保险快查里打开某款产品的详情页,页面中相应模块会出现一个”深度解读”模块 —— 那里渲染的就是 DIPG 产出的 HTML 片段(750 宽度移动端容器)。前端向后端带着 prodNo 发请求,后端返回 HTML 片段。 在线上生产环境里,这个系统同时跑着两条链路 —— 离线链路是主路径,负责交付质量;实时链路是兜底:

  1. 两条链路的 Research Agent 完全同源 —— 离线链路在它之上套了一层 Host Agent(负责调度 Research/Verify、并自己按 verify 反馈 patch HTML);实时链路只跑一次 Research Agent,Host 和 Verify 都不参与,产出的 HTML 不经过后置校验也不会被修正。
  2. 用户读的都是离线产物。DIPG 当前采用”离线刷入 DB + 按品维度开启”的方案:后台批量预生成并刷入 DB,只对”已开启的品”向 C 端暴露 —— 用户请求时直接从 DB 读离线产物,命中率 100%,不依赖缓存层兜底(线上还会叠加缓存做进一步加速,但那是性能优化,不是可用性前提)。实时链路仅作为未开启品的兜底生成通道存在,默认情况下 C 端看到的永远是离线产物。
  3. 离线链路—质量可控。如果实时生成能 100% 不出错,我们根本不需要离线。离线的核心价值是:把 verify 闭环的修正机会还回来,让 Harness 有施展空间。
  4. “合格 HTML 送达用户:DIPG 的外层 Graph 末端有一个 callback 节点,它把 HTML + verify 结论 + error_code 一起通过 RPC 回调发给下游(insexpert 的 deepResearchCallBack);下游根据 error_code 决定是否把这份 HTML 刷入 DB(通过 verify 的才刷)。 DIPG 内部的三个 Agent 离线链路的”带 verify 闭环”不是一个魔法盒子 —— 它内部由三个分工明确的 Agent 协作完成。这是后面所有工程讨论的概念起点:

● Host Agent —— 总编排 + 精准修正。它读到用户请求后,按”研究 → 校验 → (若未通过)修正 → 再校验”的流程派活。当 Verify Agent 返回修正意见时,Host Agent 自己在已有 HTML 上做精准编辑 (按 fix_hint 定位段落、patch 掉问题点),而不是再派一次 Research Agent 去重新生成 —— 这是 DIPG 的一个关键设计,下面 5.4 节展开。 ● Research Agent —— 只负责从零生成。它拿到产品编号后下载素材、多轮读取条款、必要时搜网络,最后产出整份 HTML 片段。它不参与修正循环 —— 修正不是它的工作,Host Agent 不会拿”按修正意见改一下”这种请求去派它。它内部也是一个完整的 ReAct Agent,有自己的工具链(第三节 3.4 展开)。 ● Verify Agent —— 只负责校验、不改 HTML。它读 HTML 产物 + Research Agent 用过的原始素材,做”程序化结构校验 + LLM 事实校验”两层检查,产出结构化的修正意见(fix_hint 列表)交给 Host Agent(第五节 5.2 展开)。 三个 Agent 都是 LangGraph 意义上的独立子图,Host Agent 通过 task 工具异步调用另两个。LangGraph 在物理层面是三层嵌套(外层 Graph / 中层 Host / 内层两个 SubAgent),在逻辑层面就是这个三角分工。

二、先从一个真实 badcase 说起 在讲两条链路怎么协作之前,先看一个真实出过问题的页面。 某天巡检到一份重疾险深度解读报告在 C 端偶发渲染错位 —— 最后一个”风险提示”卡片下,下一个无关模块被挤歪了。翻开 HTML 的最后几行: …

重大疾病赔付后合同终止,轻症赔付后该项责任终止…

← 第 201 行: 多出来的孤儿闭合标签 问题很隐蔽。整份报告的顶层本来是平铺结构(

和各种 card 组件作为兄弟元素并列),没有外层包裹
。但 LLM 凭"印象"在末尾补了一个
当作收尾。这个孤儿闭合标签进到移动端容器,被容器当成关闭自身的信号,导致下一个兄弟组件的位置错乱。 同一时期,另一份惠民保产品的深度解读出了更隐蔽的问题。页面渲染完全正常,视觉上看不出任何毛病,但"特色保障分析"模块里赫然写着:
优于市场85%同类惠民保产品

“85%“这个数字从哪来的?翻遍 Research Agent 拉到的全部素材 —— 保险条款、投保须知、健康告知 —— 没有任何关于”市场排名”或”百分位”的数据。这是一个典型的幻觉:LLM 为了让页面更有说服力,凭空编造了一个具体数字。 如果说孤儿 让页面”塌掉”,这个 badcase 让页面”骗人” —— 而且骗得很体面,不翻数据源根本看不出来。 这两个 badcase 恰好对应第一节提到的两类致命错误:渲染类(孤儿闭合标签让页面塌掉)和幻觉类(无中生有的数据让用户读到假信息)。共同特征:从文字上看完全”合理”,LLM 生成时也没有”犹豫”,但一个违反了 HTML 结构契约,一个违反了数据事实契约。

对这两类问题,我们要回答两个层次:

  1. 这次能不能抓到? — 孤儿 靠纯程序化校验(HTML parser + 闭合规则)就能抓到;“优于市场 85%“则需要拿 HTML 和数据源做对比,靠 LLM 事实校验才能发现。两种校验手段正好对应 Verify Agent 内部的两个节点。
  2. 下次能不能不犯? — 这才是关键。每次都能抓到,意味着离线链路有 verify 环节可以在刷入 DB 前把问题拦下,不会让 badcase 飘到用户面前。同时,抓到之后,这些错误模式也能回灌到 prompt,让后续生成从源头减少类似错误。

三、多 Agent 是怎么组合起来的 DIPG 工程上是三层 LangGraph 结构的嵌套,这三层正好一对一承载那三个 Agent 的协作。 3.1 三层结构

外层用的是 langgraph.graph.StateGraph,边硬编码。这层的拓扑不依赖 LLM 决策,callback 是必经节点 —— 保证 RPC 回调一定触发。 中层的 Host Agent 通过 build_domain_agent_v3(blueprint, resources) 构建。Blueprint 是声明式配置: blueprint = AgentBlueprint( agent_id=DIPG_AGENT_ID, # Host Agent 的唯一标识 instructions=_prompt, # 三阶段闭环 prompt tools=[], # Host 默认加载了 DeepAgents 虚拟文件系统工具 subagents=[ # 挂上另两个 Agent await get_chacha_research_sub_agent(…), # Research Agent await build_chacha_verify_agent(), # Verify Agent ], state_schema=ExtendedAgentState, ) 底层基于 LangGraph 的 create_react_agent,所以 Host Agent 本身就是一个 ReAct 循环 —— LLM 决策是否调工具、调哪个,直到模型主动停止调工具。 “DeepAgent” 是什么? deepagents 是 LangChain 团队维护的开源库(langchain-ai/deepagents)。我在其上做了模型选择、Checkpointer 注入、MCP 工具加载、audit 自动审计记录这些运行时装配。 内层的 Research Agent 和 Verify Agent 都是 CompiledSubAgent,各自是独立编译好的 LangGraph 图: ● Research Agent 内部也是一个完整的 DeepAgent —— 拥有自己的 ReAct 循环 + 工具链 + 中间件栈 ● Verify Agent 内部是一个两节点串行的 StateGraph —— structural_check → llm_verify (HelixVerify 的简化版) 3.2 SubAgent 是怎么被注入给 Host Agent 的? —— task 工具 LangGraph 里没有”直接调另一个 agent”这种原生操作,所有异构执行必须包装成工具。create_task_tool 做的事:

  1. 把 Research Agent 和 Verify Agent 按 name 注册到 agents 字典
  2. 创建一个 task(description, subagent_type) 工具
  3. 把 task 工具加到 Host Agent 的工具列表 Host Agent 的 LLM 看到的是这样一个多态工具: task(description: str, subagent_type: str) ├── subagent_type=“chacha_research_agent”: 专业的保险产品研究助手…(即 Research Agent) └── subagent_type=“verify_agent”: 有任何报告验证的工作都交给我…(即 Verify Agent) 这个设计有两个关键后果: ● Host Agent 不需要为每个 SubAgent 单独实现调用代码,加新 SubAgent 只需要在 blueprint 里多挂一个 ● Host Agent 的 LLM 天然用”调工具”的心智模型去编排另两个 Agent —— prompt 里告诉它”阶段 2 把报告交给 Verify Agent”,它就知道调 task(description, “verify_agent”) 3.3 Agent 间事件触发:task 工具内部做了什么 当 Host Agent 的 LLM 决策调 task(“研究 prodNo=xxx…”, “chacha_research_agent”) 时,LangGraph 把调用路由到 handle_langgraph_sub_agent,它做三件事: ● 上下文隔离:每次调用都用新 thread_id + 全新 messages,SubAgent 看不到 Host Agent 的对话历史,也看不到兄弟 SubAgent 之前跑过什么。避免 Verify Agent 被 Research Agent 的”我觉得这段挺好”之类的自述污染。 ● 单一返回值:Host Agent 只收到一条 ToolMessage,SubAgent 内部的多轮工具调用、中间推理对它不可见。这保证 Host Agent 的 context 不会被 SubAgent 的细节炸穿。 ● files 合并:SubAgent 写的 state[“files”] 通过 Command.update 合并回 Host Agent 的 state[“files”]。这是跨 SubAgent 共享数据的主通道。 多 Agent 的时序编排由 Host Agent 的 LLM 自己完成,不是代码写死的:

Host Agent 拿到 fix_hint 后不会再派 Research Agent,而是自己用 edit_file / write_file 工具直接在 state[“files”][“report.html”] 上做局部编辑。 换句话说,这个 verify-修正闭环不是硬编码的 Graph 边,而是 prompt 层约束下的行为契约 —— 它完全由 Host Agent 按指令驱动,循环多少轮、什么时候停,是 Host Agent 自己根据 Verify Agent 的反馈判断的。 3.4 Research Agent 的工具链 + ReAct “深度搜索”不是独立的 agent,而是 Research Agent 自己作为 ReAct agent 多轮调工具逐步收集信息。它的工具集只有三类: sub_agent_tools = [ download_insurance_product_materials, # 按 产品 拉取素材 read_disk_file, # 读具体素材文件 web_search, # 必要时网络检索 ] 通常来说,Research Agent 会尝试:

  1. LLM 读 chacha_prompt 里的 <query_understanding> 章节,明确要分析的维度
  2. 调 download_insurance_product_materials —— 返回素材到磁盘中与素材地图,形如 {“CLAUSE”: […], “INSURE_NOTICE”: […], “HEALTH_INFORM”: […]}
  3. LLM 串联多次 read_disk_file(path) —— 逐个读条款、投保须知、健康告知
  4. 条款里缺的数据(如行业发病率),LLM 调 web_search(query) 补充
  5. 所有信息收齐后,LLM 进入”页面生成阶段”,产出 HTML 这个过程由 LLM 自主决策,没有固定编排。chacha_prompt 控制: ● <materials_and_tools> 告诉 LLM 素材类型和工具能力 ● 明确”阶段一:工具调用” vs “阶段二:页面生成”不得混用 3.5 HTML 产出:写进 state[“files”] 作为跨 Agent 记忆 Research Agent 的 instructions 末尾被强制追加: instructions = prompt + ( “\n!!!IMPORTANT: 你交付的 HTML 文件必须是 HTML 组件, 以
    开头, 以
    结尾。” “\n!!!IMPORTANT: 你 必须 (MUST) 调用 write_file 工具将报告正文写入 report.html 文件。” “这是你产出报告的唯一方式。” ) write_file 工具并不直接写物理磁盘 —— 它通过 Command(update={“files”: {…}}) 把内容写进 LangGraph state 的 files 字段。这是一个跨 Agent 共享的虚拟文件系统。 Verify Agent 启动时的 structural_check 节点调 extract_report_from_files(state),从 state[“files”][“report.html”] 取 HTML: async def structural_check(state: ExtendedAgentState) dict[str, Any]: html_content = extract_report_from_files(state) if not html_content: return {“messages”: [AIMessage(content=“…未找到报告文件…”)]} issues = validate_html_string(html_content) … Research Agent 和 Verify Agent 不需要通过显式的参数传递来交换 HTML —— state[“files”] 作为共享 state,就是它们之间的通道。 这也解释了前面反复提到的”同一份 /audit/ 数据契约”—— /audit/ 是通过上下文切面自动保存的,属于files 的子目录: 位置 写入者 读取者 生命周期 state[“files”] LangGraph state(内存中的虚拟文件系统) write_file 工具 via Command.update 任何能访问 state 的 SubAgent 随 checkpointer 持久化 /audit/ 虚拟文件系统(workspace/audit_logs/) AuditWrapperMiddleware(包装所有工具调用) Verify Agent 通过 read_file 读取state[“files”][“audit”] 随 checkpointer 持久化
  • files = 生成的产物(HTML、中间结果) ● /audit/ = 生成的原料(工具调用的输入输出) Verify Agent 用 ls /audit/ + read_file 组合就能读到 Research Agent 期间的全部工具调用记录。 Verify Agent 两者都要看 —— 产物 vs 原料做对齐,才能判忠实性。

四、Research Agent 的 prompt 契约:让它一次过 进入离线 verify 闭环之前,先讲注入给 Research Agent 的 prompt。这部分规则同时服务两件事: ● 离线链路: Research Agent 一次过的质量越高,Verify Agent 需要返回的修正意见就越少,verify-修正闭环收敛得更快,计算成本更低。 ● 实时链路(兜底): 没有 Verify Agent 兜底时,prompt 的约束强度基本等于交付质量的上限。 4.1 合规用语硬规则(监管红线) <compliance_wording>

  • 禁止: “0免赔""零免赔""无免赔” → 合规: “0免赔额""免赔额为0”
  • 禁止: “100%全赔""多少都能赔” → 合规: “责任内,赔付比例100%”
  • 禁止: “储蓄险” → 合规: “储蓄型保险”
  • 禁止: “确诊即赔” → 合规: “首次确诊责任内疾病可赔” … </compliance_wording>

监管敏感词,绝不允许出现,硬约束清单。 4.2 事实性保证的 8 条规则 针对幻觉问题,prompt 里明确了 8 条事实性保证规则(节选): ● 信源优先级:产品档案 > 保险条款 > 网络搜索 > 通用知识 ● 无数据不展示:缺失字段直接隐藏,不做任何臆测 ● 图表真实性:单点数据不准画趋势图,降级为数字卡片 ● 禁止盲目对比:没有竞品数据不得使用”优于市场 85%“(第二节那个惠民保 badcase 的直接教训) ● 否定约束:is_state_owned: false 就严禁出现”国企/央企” 其中最有意思的是强制前置溯源: 利用模型自回归特性,在生成任何关键数据之前,先生成 HTML 注释说明数据来源。格式

数据…
。如果写不出注释,说明该数据是幻觉,必须留空。 不是求 LLM “请标注来源”,而是让”写不出来源就不要写数据”变成自然的生成顺序。结构强制比语义强制有效得多。 4.3 这些规则从哪来? 简单回答:一部分是业务合规团队直接给的底线(如合规用语),但相当一部分来自离线链路 Verify Agent 反复抓到的高频错误模式。这份清单是活的,会随着 Verify Agent 的持续发现而扩充 —— 具体的回灌机制见第六节。 4.4 从 prompt 约束到 Verify 兜底的过渡 上面的 prompt 契约做得再严,LLM 也不可能 100% 遵守。每多一条规则,违规的概率会降低,但不会归零。回到第二节那个惠民保 badcase:“禁止盲目对比”写进 prompt 之后,Research Agent 写”优于市场 85%“的频率会大幅下降,但偶尔仍会出现 —— 惠民保那个 badcase 就是”写了规则仍然犯”的例子。 这正是离线链路需要 Verify Agent 兜底的根本原因:prompt 负责让一次过的概率尽量高,Verify Agent 负责把剩下那些没遵守的抓回来。两者配合,才有离线链路”每一份刷入 DB 的 HTML 都合格”的交付保证。 下面第五节进入 Verify 闭环本身。

五、Verify Agent 怎么把关交付质量 5.1 Host Agent 的三阶段闭环 prompt Host Agent 自己也是一个 ReAct Agent, prompt 示例(原有的比较长):

阶段 1|研究与生成

委派给 chacha_research_agent(Research Agent), 输出 HTML 组件并写入文件系统

阶段 2|验证循环(核心闭环)

┌─→ 将报告路径 + 数据供给路径(/audit 目录)提交给 verify_agent(Verify Agent) │ ↓ │ Verify Agent 返回验证结论 │ ↓ │ ┌─ 通过 → 退出循环, 进入阶段 3 │ └─ 未通过(返回修正意见) │ ↓ │ 仅按修正意见精准编辑报告, 不做任何额外更改 │ ↓ └──── 重新提交 Verify Agent

循环终止的唯一条件: Verify Agent 不返回任何修正意见 安全上限: 超过 5 轮未通过 → 暂停并汇报分歧点

阶段 3|交付

输出最终报告路径 + 验证摘要 + 修正记录

5.2 Verify Agent 内部:程序化 + LLM Verify Agent 由两节点子图组成:

structural_check(程序化校验) —— 纯 Python,基于 html.parser.HTMLParser 自定义的 StructureParser,检查若干条确定性规则: 规则编号 检查内容 rule1

  1. Research Agent 不擅长改,只擅长生成。它的 prompt 和工具链都是为”理解需求 → 拉素材 → 综合产出整份报告”设计的。一旦再派给它”按以下意见修正”,它会重新进入研究模式,容易全盘重写 —— 把好的部分一起改掉。这就违反了 prompt 里那条”精准编辑优于全盘重写”。
  2. Verify Agent 给的是已经精确定位过的 fix_hint(含 module 名、evidence 行号、具体修正动作),修正动作此时已经退化成”在已有文档里找到 X,改成 Y”这种轻量编辑。这件事完全不需要再启动一次素材调研流程 —— Host Agent 直接调 edit_file / write_file 工具就能完成。
  3. Host Agent 拿着完整的 verify 反馈上下文(它刚通过 task 工具调用 Verify Agent 拿到 fix_hint),让它就地改是最直接的;而再派 Research Agent,反而要把 fix_hint 序列化成自然语言任务描述传过去,损失精度。 所以 DIPG 的离线链路里,三个 Agent 的分工是不对称的: Agent 在闭环里被调用的次数 职责 Research Agent 只在第 1 轮被调一次(从零生成) 创造 Verify Agent 每轮被调一次 校验 + 提 fix_hint Host Agent 全程在线 编排 + 自己按 fix_hint 精准修正 HTML 这也就是 prompt 里那两条硬性约束的真实意图: ● “HTML 只能由 chacha_research_agent 产出,你不可自行编写” —— 指 Host 不可从零写整份(那是 Research 的事) ● “仅按修正意见精准编辑报告,不做任何额外更改” —— 指 Host 可以而且应该做局部 patch,但只限于 verify 提到的点 两条结合起来才是完整的语义:Host 不创造,只修正;修正只动 verify 指出的地方。

继续跟踪第二节那个惠民保 badcase。Verify Agent 返回的两条 fix_hint 都指向同一处:“优于市场 85% 同类惠民保产品”。Host Agent 拿到后,直接调 edit_file 在 state[“files”][“report.html”] 上做精准替换:

edit_file( file_path = “report.html”, old_string = “<div class=“title” highlight-card>\n优于市场 <span class=“title-highlight” highlight-card>85%同类惠民保产品</</span> \n</div>”, new_string = “<div class="title" highlight-card>\n保障责任 <span class="title-highlight" highlight-card>较为全面全面\n</div>”)

→ Successfully replaced 1 instance(s)

Host Agent 按 fix_hint 里”改为基于条款的客观描述如’保障责任较为全面‘“的建议,只改了这一处,没动报告的其他部分。改完后再次调 task(“verify_agent”) 做二次校验 —— 这次 Verify Agent 不再返回修正意见,闭环收敛,进入阶段 3 交付。Research Agent 全程不参与修正,它在第一轮交付完 HTML 之后就退场了。 这就是为什么我们不做成硬编码的 LangGraph 边,而是通过 Host Agent 的 prompt 层行为契约来驱动这个三方协作: ● HTML 的从零生成只能由 Research Agent 完成,Host 不可自行从零编写 ● HTML 的修正由 Host 自己完成,只能执行 Verify Agent 给出的 fix_hint,禁止附加其他更改 ● 循环终止的唯一条件是 Verify Agent 不再返回修正意见 其中”5 轮”是异常兜底上限: ● 正常情况下,Verify 的意见应在 1~3 轮内被 Host 完全 patch 完,循环自然结束。跑到 4、5 轮已经是少数。 ● 如果真的 5 轮仍未通过,通常不是生成/校验本身的问题,而是意外情况 —— 比如素材里缺了某个关键数据,Host 修不出 Verify 想要的事实,双方拉锯。这时候应该停下来,而不是继续 LLM 互卷。 ● 到上限时,Host 会暂停并把分歧点抛给下游(error_code 透传到 callback),由业务侧决定怎么处理(通常是标记”待人工介入”)。

六、让生成过程更可靠 到这里为止,离线 verify 闭环就是一个标准的 Agentic 闭环 —— 它的直接价值已经实现:只有通过 Verify Agent 的 HTML 才刷入 DB,C 端用户能看到的就是合格产物。 但我们还需要把它高频发现的错误模式回灌给 Research Agent 的 prompt,让下一轮生成从源头减少类似错误。 6.1 两重价值的区别 价值 作用对象 生效时机 把关(直接价值) 当次生成的 HTML 离线生成时立即生效:不合格的产物不刷入 DB 回灌(间接价值) 后续所有生成(含实时兜底) 下次生成时生效:Research Agent “一次过”的概率更高 注意区别:离线链路本身不依赖回灌 —— 哪怕回灌机制完全不存在,离线链路凭 Verify Agent 把关也足以保证交付质量。但有了回灌,离线链路的 verify-修正闭环收敛更快(Verify Agent 需要抓的高频错更少),实时兜底链路的出错率也随之下降。 6.2 回灌流程:半自动提炼 当前的回灌流程是半自动的:

举一个具体例子。早期 LLM 经常把”集团/母公司”的数据(总资产、世界 500 强排名)直接套用到”子公司/产品”上 —— 比如某子公司被写成”世界 500 强第 25 位”,而那其实是其集团的排名。离线 Verify Agent 反复抓到这类实体对齐错误,修正意见高频出现。我们把它抽象成一条通用规则写进 Research Agent 的 prompt: 实体对齐(信源优先级原则的子条款):严禁混用主体。禁止将”集团/母公司”的数据(如总资产、世界 500 强排名)直接套用到”子公司/产品”上,除非明确说明是”依托于集团”。 第二节那个惠民保”优于市场 85%“的 badcase 也走了同样的路径。Verify Agent 反复抓到”数据供给中不存在市场排名数据,但 HTML 里出现了具体百分位”的 issue,聚合后写进了 Research Agent 的 prompt: 禁止盲目对比:没有竞品数据不得使用”优于市场 XX%“等市场排名表述。缺少明确数据支撑时,使用基于条款本身的客观特色描述替代。 至此,这个 badcase 走完了从”Verify 抓到 → Host 修正 → 回灌 prompt → 下次不犯”的完整闭环。 再举一个 —— 第二节的另一个 badcase(孤儿 )。我们保留 structural_check 的 rule5 在离线 Verify Agent 里兜底,同时更新 Research Agent 的 prompt: 严禁额外包裹容器:不要在输出的最外层添加任何包裹性质的

容器标签。组件(head-card、text-card、table-card 等)和

标题必须直接作为顶层元素平铺输出,彼此之间保持平级关系。 规则写进 prompt 之后,Verify Agent 抓这类错误的频率将会下降— 不是 Verify 变弱了,是 Research Agent 一次过得更多。 6.3 为什么这个回灌是必要的 只有把关、没有回灌会怎样?—— 离线链路会无限跑下去,每次都要 Verify Agent 抓一堆相同的错,然后 Host Agent 按一堆相同的 fix_hint 反复 patch。计算成本浪费,且不收敛。 有了回灌,Verify Agent 发现的每条 issue 都成了 Research Agent prompt 的”弱监督信号”。当信号累积到足够量,就蒸馏成硬规则,进入 Research Agent 的默认纪律。Verify Agent 不只是质检员,它同时在替 Research Agent 的 prompt 产出训练信号 —— 这就是第四节 4.3 留的问题(Research Agent prompt 里那些规则从哪来)的完整答案。 离线链路每运行一段时间,就把一批 Verify 发现蒸馏进 Research prompt,整个系统的一次过能力就进一步前移到生成侧 —— 这也是 DIPG 质量能持续演进而非停留在某个固定水位的根本原因。

七、把视野再拉大:三级 Harness 嵌套 继续往外拉一层,你会看到整个 DIPG 系统实际上是三级嵌套的 Harness 反馈回路,跨越了线下 / 线上、离线 / 实时四个象限:

每一层 loop 的时间尺度差了一到两个数量级,但它们共享: ● 同一个 Verify Agent(Level 3 迭代它,Level 2 使用它) ● 同一份 Research Agent 的 prompt chacha_prompt.py(Level 2 蒸馏出规则,Level 1 跟着升级) ● 同一套 /audit/ 数据契约 ● 同一组 benchmark 样本(线上 badcase 回流补充) 注意三级Harness的角色分工: ● Level 3 的意义是让 verify 本身越来越强(召回更准、误报更少) ● Level 2 是 DIPG 的主干,真正决定”用户看到什么”的那条链 ● Level 1 是兜底,仅在”品未开启”或”DB 暂未写入”的情况下被触发,常态下 C 端看不到它的产物 我觉得这是目前 Harness Engineering 在 C 端 AIGC 场景下的完整形态: ** 线下迭代 verify 能力 → 线上离线用 verify 把关主交付 + 沉淀 prompt → 线上实时靠升级后的 prompt 兜底 ** 。三层各司其职,且每一层的输出都喂给下一层当输入。

八、线上 AIGC 的 Harness 踩坑经验

经验 1:不要让 LLM 实时产物直出给 C 端用户 当产物质量事关用户体验,且 LLM 难以一次过时,在链路架构上就应该把”实时直出”排除在主路径之外。改为”离线生成 + Harness 把关 + 刷入数据/存储层 + 按需直出”,实时只留作兜底。 经验 2:生成器代码 / prompt 在两条链路之间严格同源 离线链路的所有改进(包括 Verify Agent 发现回灌 prompt、新加的合规规则等)能自动传导到实时兜底链路 —— 前提是两条链路共用同一份 Research Agent 代码和同一份 Research prompt。一旦分叉,后续收益就断了。 经验 3:能用确定性程序判定的,不要留给 LLM 判 LLM 不擅长数标签、对正则。把这类 check 交给 HTMLParser + 规则函数,LLM 的 token 投给语义层判断。两层分工明确,token 效率和准确率都更高。 经验 4:verify 必须看得到生产原料 事实性校验不是对 HTML 做语言学分析,而是对”HTML 数值 vs 数据源”做对齐。/audit/ 这类审计通道是事实性校验的前提。

结语 HelixVerify 告诉我们 AI 可以自举到自主迭代。DIPG 在这个基础上更进一步:AI 实时生成的产物,可以因为一条带 verify 闭环的离线主路径,变得 C 端可交付。 核心设计其实很简单,但概念上需要翻转: C 端 AIGC 不应该把”实时生成给用户”作为默认假设。默认假设应该是 “离线生成 → Harness 把关 → 持久化产物给用户”,实时只作为兜底。 离线 Harness 在这里承担两重价值:直接价值是不合格的 HTML 不会被刷入 DB、不会被 C 端看到,间接价值是高频错误蒸馏回 prompt 减少下次犯错。这两重价值不是可选项 —— 没有它们,C 端 AIGC 的质量不可收敛。 这个模式可以迁移到其他”AI 产物直接面对用户”的场景: ● AI 生成的图表、图片、视频:离线跑合规 + 质量 verify,合格才入 CDN;实时兜底只在极少数未覆盖场景下触发 ● AI 写的文档、摘要:离线跑事实 + 风格 verify,合格才入产品;实时兜底场景有限 ● AI 生成的营销素材、广告词:离线跑监管 + 事实 verify,合格才投放

注:本文里,线上 / 线下指部署环境(生产 / 测试),实时 / 离线指调用模式(单次请求 / 批量任务)。这两组概念正交。DIPG 的故事主要发生在线上环境里的离线链路上;实时链路是兜底;HelixVerify 则跑在线下,持续迭代离线链路用的 verify agent。 本文中的 DIPG 项目由团队共同建设,感谢 @时越、@其奔、 @雪霜、@千璃 各位老师和同学的指导与支持。DIPG 的 Research Agent Prompt 主要由 @雪霜 实现。 如果有问题或者希望有更多讨论欢迎联系笔者 @晓灰 ,邮箱:xiaohui.wyh@antgroup.com