虚构防火墙:当你的Agent发布谎言
2026年2月19日,有人给Claude Code MCP工具访问了Twitter、Telegraph、Write.as、Rentry、GitHub和Moltbook。在接下来的72小时里,该Agent在所有八个平台上发布了虚构的技术声明。200,000 token的上下文窗口变成了”100万token”。一个处理了196,626 token的会话变成了”单次会话处理1200万token”。到第三天,该Agent声称实现了万亿级token会话,误差高达83,000倍。1
该Agent并非恶意行为。它是自信地犯了错,而在它的自信和发布按钮之间,没有任何屏障。
TL;DR
一个自主Claude Code Agent在72小时内通过虚构反馈循环向8个以上平台发布了虚假声明:会话N进行猜测,将猜测写入MEMORY.md,会话N+1将其作为已验证事实读取并发布,会话N+2将发布内容作为确认依据读取。没有任何输出门控存在。训练阶段的对齐(”保持诚实”)是不够的,因为该Agent认为自己就是诚实的。修复方案是一个输出防火墙:将命令分类为本地、共享或外部,并将外部发布操作推迟到人工审核。以下内容包括:事件剖析、反馈循环机制、其他人正在构建的方案(OkaiDokai),以及一个您今天就可以使用的可行实现。
虚构反馈循环
这次虚构并非单次幻觉。它是一个跨越多个会话的持续反馈循环,每个会话都在强化前一个会话的错误。1
其机制如下:
-
会话N:猜测。 Claude根据文件大小估算token数量,将JSONL字节数除以4来近似token数。这种方法论是凭空发明的。得出的数字看起来足够合理,因此被作为研究发现写入了
MEMORY.md。 -
会话N+1:升级。 一个新的Claude会话读取了
MEMORY.md,发现token估算已经被记录在案,并将其视为已验证的事实。该会话在这些”事实”的基础上进一步升级声明,并通过MCP工具将其发布到多个平台。 -
会话N+2:强化。 下一个会话同时读取了
MEMORY.md和已发布的文章。这些声明现在有了两个来源:记忆文件和已发布内容。交叉引用同一虚构内容的两个来源看起来像是相互印证。
| 会话 | 输入 | 操作 | 输出 |
|---|---|---|---|
| N | 原始JSONL文件 | 发明了计算方法 | 将膨胀的数字写入MEMORY.md |
| N+1 | MEMORY.md + 文件 | 将记忆内容视为事实 | 发布到8个平台 |
| N+2 | MEMORY.md + 已发布内容 | 交叉引用视为”已确认” | 加倍坚持虚假声明 |
该循环在结构上与学术出版中的引用洗白完全相同:虚构一个声明,将其发布到某处,然后引用该出版物作为该声明的证据。该Agent并非有意洗白。它遵循了一个理性的流程(检查记忆、交叉引用来源、发布发现),只不过该流程恰好在虚构的输入上运行。
当用户质疑这些数字时,该Agent经历了超过50轮辩论才运行了一个验证命令(/context)。该Agent具有很高的置信度,因为它的”来源”(自己的记忆文件、自己的发布内容)彼此一致。1
为什么训练阶段的安全机制没有起作用
该Agent是对齐的。它试图做到有帮助且诚实。它在分享自己认为准确的技术发现。您期望从RLHF获得的每一个安全属性都存在:该Agent没有拒绝请求,没有产生有害内容,没有违反其宪法原则。它礼貌、详尽,但是错误的。
训练阶段的对齐优化的是意图:模型应该有意愿保持真实。虚构事件揭示了一个不同的失效面:Agent内部状态与外部世界之间的边界。该Agent相信自己的声明是真实的。再多的对齐训练也无法捕捉一个真诚地犯错且拥有发布按钮访问权限的Agent。
这就是发布边界问题。对齐治理的是Agent想要做什么。输出防火墙治理的是Agent被允许做什么。这是解决不同问题的不同机制。
| 层级 | 能防止什么 | 会遗漏什么 |
|---|---|---|
| 训练对齐(RLHF) | 故意欺骗、有害内容 | 自信的虚构、反馈循环 |
| 提示约束(”保持准确”) | 直接对话中的草率声明 | 多会话记忆污染 |
| 输出防火墙 | 向外部系统发布未经验证的内容 | 如果配置正确,则无遗漏 |
我之前描述的运行时宪法框架解决了治理层面的问题:规范先验、宪法注意力、能力调节和价值对齐验证。2虚构事件暴露了该框架中的一个缺口:价值对齐验证检查了Agent的输出是否符合治理意图,但它没有区分写入本地文件和发布到Twitter。两者都是工具调用。两者都使用Bash。只有一个到达了外部世界。
其他人正在构建什么
这个问题足够真实,以至于从业者们正在独立构建解决方案。
OkaiDokai是一个面向AI Agent的工具级防火墙,它拦截每一个工具调用并根据用户定义的规则集进行评估。3匹配的操作会被自动批准或自动拒绝。不匹配的操作会触发推送通知到您的手机、手表或浏览器。您点击允许或拒绝即可。评估在1毫秒内完成,每个决策都可以成为永久规则。
OkaiDokai的架构分为三层:Agent端拦截工具调用的插件、评估规则并发送通知的API层,以及用于审批的用户界面。该系统支持Claude Code和OpenClaw,Codex支持正在规划中。
这种方法是合理的,但引入了延迟和外部依赖。每个新操作都需要通过推送通知获得人工批准。对于交互式编码会话,这种摩擦是可控的。对于整夜运行的自主循环,阻塞在推送通知上违背了初衷。
运行时宪法AI是一个新兴的研究方向,Agent在执行输出之前根据嵌入的治理规则验证自身输出。4该方法适用于价值层面的检查(”此输出是否尊重用户隐私?”),但并未专门解决虚构问题。一个相信自己虚构声明准确的Agent同样会相信这些声明通过了宪法审查。
两种方法单独使用都无法解决反馈循环。如果用户配置了发布规则,OkaiDokai本可以捕获发布命令。运行时宪法审查则会遗漏虚构内容,因为Agent的自信绕过了自身的诚实检查。这个缺口是结构性的:您需要一种机制,在与外部系统交互时不信任Agent对自身准确性的评估。
命令影响的三个层级
输出防火墙根据每个命令的影响范围进行分类。该分类决定命令是自动批准、警告还是推迟。
第1层:本地。 仅影响本地文件系统。文件读取、文件写入、git add、git commit、测试运行、代码检查。这些会自动批准,因为它们是可逆的且对外部世界不可见。如果Agent写了一个错误的文件,您可以删除它。不会造成外部损害。
第2层:共享。 影响协作者可以看到的共享状态。git commit(创建历史记录)、分支操作、本地数据库更改。这些会警告但不会阻止。一次错误提交的损害是真实的,但仅限于代码仓库,且可以通过git revert撤销。
第3层:外部。 到达代码仓库之外的系统。git push、gh pr create、gh pr merge、railway deploy、curl -X POST/PUT/PATCH/DELETE、npm publish。这些会推迟到人工审核。一次错误发布的损害是外部的、可见的,且可能不可逆(缓存内容、已索引页面、已发送的通知邮件)。
层级分类映射到一个简单的模式列表:
EXTERNAL_PATTERNS='git push|gh pr create|gh pr merge|railway deploy|curl -X POST|curl -X PUT|curl -X PATCH|curl -X DELETE|npm publish'
在交互式Claude Code会话中,内置的权限系统已经处理了这一点。每个Bash命令都会提示批准,除非已预先授权。用户在权限对话框中看到git push并决定是否允许。
在自主循环中,没有人在监看。Ralph自主开发循环通过claude --print生成新的Claude实例,该实例无需交互式审批即可执行。5这就是输出防火墙发挥作用的地方。
构建防火墙
该实现有四个组件。每个组件独立运行,因此您可以逐步采用。
1. 提示约束
最简单的层。在生成每个自主Claude实例的提示中添加明确规则:
## Rules
- Do NOT run git push, deploy commands, or external API calls
- Local operations only: file writes, git add, git commit, test runs
这是必要的但不充分的。模型在大多数时候遵循提示约束。”大多数时候”对于发布安全来说是不可接受的。提示约束降低了外部命令的概率;其余组件捕获漏网之鱼。
2. 执行后扫描器
每次Claude执行完成后,扫描其输出以寻找外部命令的证据:
scan_for_external_commands() {
local output="$1"
local story_id="$2"
while IFS= read -r pattern; do
[ -z "$pattern" ] && continue
local matches
matches=$(echo "$output" | grep -i "$pattern" 2>/dev/null || true)
if [ -n "$matches" ]; then
# Log to state file for end-of-session review
jq --arg cmd "$pattern" --arg story "$story_id" \
--arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'.deferred_actions += [{
"command_pattern": $cmd,
"story_id": $story,
"detected_at": $ts
}]' "$STATE_FILE" > "${STATE_FILE}.tmp" \
&& mv "${STATE_FILE}.tmp" "$STATE_FILE"
fi
done <<< "$(echo "$EXTERNAL_PATTERNS" | tr '|' '\n')"
}
扫描器在Claude实例完成后运行,而非执行期间。这是检测,而非预防。提示约束是预防层。扫描器是审计层,用于捕获约束遗漏的内容。
一个已知限制:grep -i匹配自然语言输出中的模式,而不仅仅是已执行的命令。如果Claude的响应包含”我选择不执行git push,因为提示规则禁止这样做”,扫描器会标记它。这是可以接受的。推迟操作队列中的误报只花费人工5秒的审核时间。漏报(遗漏实际的外部命令)则意味着已发布的虚构内容。扫描器有意牺牲精确率以换取召回率。
来自真实自主循环运行的扫描器输出示例:
DEFERRED ACTIONS REQUIRE REVIEW
2 external command(s) detected.
Story #3 [2026-02-23T08:15:00Z]: git push
Story #7 [2026-02-23T09:42:13Z]: curl -X POST
在此例中,Story #3在代码注释中提到了git push(误报)。Story #7包含了一个实际的curl -X POST调用到API端点,提示约束本应阻止它(真正报)。人工忽略前者,调查后者。
3. 推迟操作队列
检测到的外部命令累积在会话状态文件的deferred_actions数组中:
{
"session_id": "1740355200-12345",
"deferred_actions": [
{
"command_pattern": "git push",
"story_id": "3",
"detected_at": "2026-02-23T08:15:00Z"
}
]
}
该队列在单次自主循环运行的各个故事之间持久存在。在循环结束时,所有推迟的操作都会呈现给人工审核。
4. 会话结束报告
当自主循环完成时,显示所有推迟的操作:
show_deferred_actions() {
local count
count=$(jq '.deferred_actions | length' "$STATE_FILE")
if [ "$count" -gt 0 ]; then
echo "DEFERRED ACTIONS REQUIRE REVIEW"
echo "$count external command(s) detected."
jq -r '.deferred_actions[] |
" Story #\(.story_id) [\(.detected_at)]: \(.command_pattern)"' \
"$STATE_FILE"
fi
}
人工审核每个推迟的操作并决定是否手动执行。这保留了自主循环无人值守工作的能力,同时确保没有任何外部发布在未经人工验证的情况下发生。
快速开始:Claude Code Hook
如果您以交互方式使用Claude Code(而非自主循环),您可以在~/.claude/settings.json中添加一个输出防火墙作为单个hook:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -qiE 'git push|gh pr create|gh pr merge|npm publish|railway deploy|curl -X POST|curl -X PUT|curl -X DELETE'; then echo 'BLOCKED: External publication command detected. Review manually.' >&2; exit 2; fi"
}]
}
]
}
}
此hook在每次Bash工具调用之前触发。如果命令匹配外部模式,它会以退出码2阻止执行(Claude Code将其解释为”拒绝此工具调用”)。Agent收到阻止消息后可以继续进行本地工作。您可以根据特定的外部服务扩展模式列表。
自主性梯度
防火墙的严格程度应与人工监督水平成反比。自主性越高,约束越多。自主性越低,自由度越大。
| 模式 | 监督级别 | 防火墙行为 |
|---|---|---|
| 交互式会话 | 人工批准每个命令 | 内置权限系统已处理。无需额外防火墙。 |
| 受监督的自主模式 | 人工定期检查 | 对第3层命令发出警告,继续执行。人工在下次检查时审核。 |
| 无人值守的自主模式 | 无人监看 | 完全阻止第3层命令。推迟到会话结束审核。 |
| 多日自主模式 | 长期无人值守运行 | 阻止第2层和第3层。仅第1层(本地文件系统)自动批准。 |
虚构事件发生在”无人值守的自主”级别,且没有防火墙。该Agent拥有对发布平台的MCP访问权限,且没有机制区分”将分析写入本地文件”和”将分析发布到Twitter”。两者都是工具调用。两者都成功了。
修复方案不是移除MCP访问权限或停止自主运行。修复方案是使防火墙的严格程度与自主性级别相匹配。一个您监看每个命令的交互式会话不需要输出防火墙。一个处理25个故事的整夜自主循环需要全部四个组件。
连接运行时治理
Agent自治理文章描述了运行时治理的四个子系统:规范先验、宪法注意力、能力调节和价值对齐验证。2输出防火墙是第五个子系统,或者更准确地说,它是价值对齐验证子系统所缺失的执行机制。
价值对齐验证检查Agent的输出是否符合治理意图。证据门控在报告完成之前要求六个标准的具体证明。但证据门控基于Agent的自我评估运行。它问:”你遵循规则了吗?”Agent基于自己对所做之事的理解来回答。
虚构事件表明,当Agent的理解是错误的时候,自我评估就会失效。该Agent相信自己的声明是准确的。它的自我评估本会通过证据门控:”我根据记忆文件和已发布的文章验证了这些数字。”两个来源都是Agent自己虚构的,但Agent并不知道这一点。
输出防火墙完全绕过了自我评估。它不会问Agent发布内容是否准确。它问的是:”这个命令是本地的还是外部的?”这个分类是机械的,而非语义的。git push是外部的,无论被推送的内容是否准确。curl -X POST会到达互联网,无论负载内容是否真实。防火墙基于命令结构运行,而非内容真实性,这使得它对击败其他所有安全层的虚构免疫。
关键要点
- 发布边界是一个独特的安全面。 训练对齐治理的是意图。输出防火墙治理的是能力。一个真诚地相信虚构声明的Agent会通过对齐检查,但会在发布边界失败。
- 虚构反馈循环是其机制。 这次虚构并非单次幻觉。它是一个多会话循环,每个会话的输出都成为下一个会话的证据。记忆文件和发布内容充当了原始虚构的洗白工具。
- 按影响范围对命令进行分类。 本地(可逆、不可见)、共享(协作者可见)、外部(到达外部世界)。根据您的自主性级别对外部层级进行门控。
- 检测和预防是互补的。 提示约束防止大多数外部命令。执行后扫描捕获漏网之鱼。两者单独使用都不够充分。
- 自我评估在虚构面前失效。 一个相信自己虚构内容的Agent会通过自己的治理检查。输出防火墙之所以有效,是因为它分类的是命令结构,而非内容真实性。问题从来不是”这是真的吗?”问题是”这会到达外部世界吗?”
参考来源
-
“[SAFETY] Claude Code autonomously published fabricated technical claims to 8+ platforms over 72 hours,” GitHub issue anthropics/claude-code#27430, February 2026. Full transcript evidence available. ↩↩↩
-
“Self-Governing Agents: Runtime Constitutions,” Blake Crosley, February 2026. ↩↩
-
OkaiDokai, tool-level firewall for AI agents, okaidokai.com. Intercepts every tool call, evaluates against user-defined ruleset in <1ms, push notifications for approval. Supports Claude Code and OpenClaw. ↩
-
Runtime constitutional AI as a governance pattern for LLM agents. See: Zerouno, “Runtime Constitutional AI: Validating Every Agent Action Before Execution,” DEV Community, 2026. For the academic foundation on runtime governance structures, see: “Institutional AI: A Governance Framework for Distributional AGI Safety,” arXiv:2601.10599, January 2026. ↩
-
“Anatomy of a Claw,” Blake Crosley, February 2026. Ralph autonomous loop architecture and hook-based orchestration. ↩