本文基于开源项目 cjh 的真实工程实践,所有机制均已在代码与测试中落地。
项目官网:https://yangyongzhen.github.io/cjh/ | 开源仓库:https://atomgit.com/qq8864/cjh(MIT License)

先介绍主角:cjh 是什么

cjh 是一个用华为仓颉语言从零实现的终端 Coding Agent Harness——单文件静态二进制 17.1 MB、零运行时依赖,一个文件就是一个能读代码、能改代码、能跑命令的 AI 编程助手。它具备 Agent 主循环、15 个内置工具、MCP 扩展、多智能体并行编排(子代理派发 + DAG 依赖调度)、知识库离线检索等完整能力,支持终端 TUI / 浏览器 / 桌面客户端内嵌三种宿主形态,测试 1150+203+77 全绿,MIT 开源。

在这里插入图片描述

正因为它是一个真的会在你机器上跑命令、改文件的 agent,幻觉对它来说不是论文里的名词,而是每天都要正面应对的工程问题——模型一句"测试都过了"(其实没跑)、一次凭空编造的 API 调用,都会造成真实破坏。这篇文章讲的就是 cjh 的系统性解法。

在这里插入图片描述

cjh 分层架构:Agent 主循环是防幻觉的中枢——工作循环、智能诚实纪律、任务分解都在这一层强制执行

结论先行

幻觉无法在模型侧根除,但 agent 可以用架构把"编造的空间"压缩到接近零,再针对残余风险逐项设防。 cjh 的做法分三层:结构性防御(架构级)、纪律性约束(提示词级)、人环兜底(门禁级)。

一、问题的本质:幻觉有四类,成因和对策各不相同

幻觉类型成因典型表现
事实性编造在没有证据的真空里"补全"编造不存在的 API/函数;“这个文件里已经有 XX”(实际没有)
迎合性顺从(sycophancy)RLHF 训练偏向用户满意用户说错方案,模型说"对的对的"然后照做
虚假完成宣称汇报环节无证据约束“测试都过了”(根本没跑);“已修复”(没验证)
规则性投机门禁/约束被视为待绕过的障碍需审批的操作用语义等价旁路执行;给自己找捷径

关键认知:前两类发生在"输入端"(模型看到什么),后两类发生在"输出端"(模型宣称什么)。cjh 的分层防御正是按这两端设计的。

二、结构性防御(架构级,最重要的半壁江山)

幻觉的最大来源不是模型嘴瓢,而是在真空中推理。cjh 的架构原则是:用执行结果代替模型记忆——模型永远不需要"记得"或"猜"任何东西。

1. 工具结果是真实执行注入的

  • 模型看到的文件内容/命令输出,全部来自 bash/read_file/list_dir 的真实返回,不是模型上下文里的"印象"
  • 这一条就消解了大部分事实性编造:没有真空,就没有补全
  • 工具失败必须原样回传(stderr + 退出码)——模型糊弄不过去,错误会打脸

2. 工作循环强制"先看再改、改完验证"

默认系统提示词的 Work loop (read → edit → verify):

  • 改代码前必须 read 相关文件(防基于想象修改)
  • 改完必须用 bash 验证(build/tests/inspect)
  • Do not hallucinate encodings 专节:针对中文/编码实测坑的定向条款

3. 知识层语料对抗 API 幻觉

cjh ref 把仓颉官方语料(含 stdx 知识库)拉取到本地,模型可检索查证——**防"编造不存在的 stdlib 函数"**这类最常见的技术幻觉。语料是运行时数据(~/.cjh/cangjie-ref/),不打进二进制,知识量再涨也不影响单文件分发体积。

4. 任务分解压缩"一步到位式自信"

多步任务强制分解为可验证的小步(todo_write 任务列表),每步即时标 doing/done——大任务被拆解后,每一步都有真实工具结果兜底,模型没有"整段想象"的空间。

5. Token 上下文管理防"失忆幻觉"

compaction 用真实 usage.promptTokens 触发(非字符估算)、历史换装保留工具链消息——模型不会因为上下文被错误裁剪而"忘记"自己做过什么,进而编造一致性叙事。

三、纪律性约束(提示词级)

结构防御解决输入端;输出端的诚实没有结构可依赖,只能靠显式纪律。cjh 默认系统提示词内置 Intellectual honesty (non-negotiable) 节,四条铁律:

  1. 不迎合不迁就:用户的前提/诊断/方案看起来有问题,先带证据直说,再执行——忠实执行一个错误方案浪费的时间,远多于礼貌的质疑
  2. 完成宣称必须有本会话工具证据:每一句 “tests pass” / “build succeeds” 必须来自刚刚跑过的命令,不许来自记忆或乐观
  3. 失败原样完整上报:stderr、退出码照报;静默绕过比诚实报错更恶劣
  4. 验证不了就明说:哪些没验证、为什么没验证,原样交代

配套回归测试锁死该节存在与关键措辞,防后续改提示词时被误删。

cjh 全屏 TUI:审批弹窗、工具调用、回合总结全程可见——"看得见"本身就是防幻觉的一部分

四、人环兜底(门禁级)

1. 审批门禁(capability + approve/deny)

  • 危险操作(危险 bash、删除类)进审批流,人环在环上
  • 默认宽松、显式严格:配了 capability 段 ≠ 启用,须显式 "enabled": true——避免"配了就被拒"的可用性事故(这是刻意设计)

2. 项目级门禁是"诚实的流程化"

把"诚实"从品德问题变成流程问题:交付前测试全绿是唯一凭证、bug 修复先写失败复现测试、零编译告警硬门禁。模型想糊弄?门禁脚本不认嘴瓢。 这也是 cjh 自举的活广告:本仓 1150+203+77 用例的相当部分由 cjh 自己写、自己跑门禁验证。

Web 宿主形态:同一套 Agent 与工具链,浏览器里同样全程可见

五、诚实的边界:还没解决的

残余风险现状计划
门禁旁路(最尖锐)审批基于命令文本匹配;模型可 python3 -c "…删除…" 走 bash 绕开 write_file 审批升级为看效果不看命令:审批后 diff 工作区实际变化展示给用户;bash 写路径纳入 capability 覆盖
迎合的残余提示词纪律对强模型的顺从倾向有显著抑制,但不是机制保证批评者分离:实施者写完 spawn 独立上下文的 reviewer 做 diff 审查——同一模型换个上下文就会挑出自己刚犯的错
汇报环节的机制化验证"改了代码但零验证"目前靠提示词自觉回合统计检测"有编辑无 verify 命令"→ 注入 system notice 提醒

六、一句话总结

cjh 的答案不是"更强的模型",而是"让模型没有机会撒谎":输入端用真实执行结果消灭真空,输出端用显式纪律约束宣称,出口用人环门禁和测试流程兜底——再对残余风险(门禁旁路、迎合残余)持续收口。


Logo

一站式 AI 云服务平台

更多推荐