# 克劳德·法布尔始终积极进取

- 来源：Hacker News 热门（buzzing.cc 中文翻译）
- 作者：lumpa
- 发布时间：2026-06-12 11:08
- AIHOT 分数：74
- AIHOT 标记：精选
- AIHOT 链接：https://aihot.virxact.com/items/cmqacwahd0kbaslld5idu5npd
- 原文链接：https://simonwillison.net/2026/Jun/11/fable-is-relentlessly-proactive

## 精选理由

Simon 的亲身实战把 Claude Fable 5 的「死磕」能力展现得淋漓尽致——为修复一个两行 CSS 问题，它自建截图工具、写 CORS 服务器、注入模板代码。这既是编程 AI 的新疆界，也暴露出沙箱外运行的巨大风险，每个用 AI 写代码的人都该警惕。

## AI 摘要

Hacker News 上的一篇文章指出，Claude Fable 被描述为始终积极进取（relentlessly proactive）。该文发布在 simonwillison.net，标题为“Claude Fable is relentlessly proactive”，在 HN 上获得 119 个点赞。

## 正文

Simon Willison 的个人博客

Claude Fable 具有极强的主动性

2026 年 6 月 11 日

经过两天对 Claude Fable 5 的使用体验，我认为最好的描述方式是“具有极强的主动性”。它掌握大量技巧，并且会动用几乎任何手段来达成目标。

我举个例子来说明。今天我在开发 Datasette Agent 时注意到一个界面缺陷：跳转菜单的聊天提示框中出现了一个不该存在的水平滚动条。我截下了这张截图：

然后我在 datasette-agent 的代码目录下启动了一个新的 claude 会话，把截图拖进去并告诉它：

查看依赖项，帮助找出这里出现水平滚动条的原因

我隐约感觉问题出在 Datasette Agent 的某个依赖项（很可能就是 Datasette 本身）上，而且我知道 Fable 擅长深入分析依赖代码——无论是检查自己虚拟环境 site-packages 中已安装的文件，还是引用磁盘上的本地代码仓库。让它从依赖项入手，感觉是个不错的策略。

我因为家务事分心，离开了电脑。

几分钟后我回来时，看到我的电脑在常规的 Firefox 浏览器中打开了一个窗口，然后导航到了那个有问题的对话框。我并没有指示 Claude Code 使用任何浏览器自动化功能，而且我很确定它不可能在窗口内触发鼠标移动或键盘快捷键，那它是怎么做到的呢？

我饶有兴致地看着它继续探索，接着看到它打开了 Safari 浏览器窗口，而不是 Firefox。我还从 Claude 终端抓取了这张截图：

它用 `uv run --with pyobjc-framework-Quartz` 在做什么？

原来 Fable 自己编写了一套截取浏览器窗口截图的方案。它用 Python 遍历我电脑上所有可用的窗口，然后筛选出窗口名称中包含“textarea”等预期字符串的 Safari 窗口。它利用这些信息找到窗口编号——一个像 153551 这样的整数——然后配合 screencapture 命令行工具来抓取 PNG 图片。

好吧，这确实是一种巧妙的截图方式。但它到底在截取什么内容的截图呢？

结果发现，它一直在自行编写临场 HTML 页面来尝试复现那个 bug，然后打开 Safari 并截取屏幕截图。

这是它创建的 `/tmp/textarea-scrollbar-test.html` 页面，以及它用 `screencapture -x -o -l 153551 /tmp/safari-cases.png` 命令截取的截图：

（我打开的标签页实在太多了！）

好吧，我明白它是如何打开测试页面并截取屏幕截图的了，但它究竟是怎么触发那个本应处于测试状态的模态对话框的呢？那个对话框只能通过点击或键盘快捷键来调用，而我找不到它在 Safari 中执行这些操作的方法。

我最终弄明白了它的做法。

Claude 运行在一个包含该应用程序源代码的文件夹中。它对 Datasette 足够了解，能够运行一个本地开发服务器。结果发现，它正在编辑 Datasette 自身的模板，添加 JavaScript 代码，以便在窗口打开时立即触发正确的键盘快捷键，添加的代码如下：

<script> window.addEventListener("load", function () { setTimeout(function () { document.dispatchEvent(new KeyboardEvent("keydown", {key: "/", bubbles: true})); }, 1200); }); </script>

窗口打开 1.2 秒后，这段代码会触发一个模拟的 `/` 按键，这是打开模态对话框的键盘快捷键。

还剩一个挑战。为了理解当前状况，Claude 需要在页面上运行 JavaScript 来自行获取测量数据。

它编写了自己的自定义 Web 应用程序，通过 CORS 来捕获信息，然后将其作为本地服务器运行，并打开一个包含 JavaScript 的页面，该页面会直接向它发送 POST 请求！

这是它编写的 Python Web 应用程序，使用了标准库中的 `http.server` 包：

from http.server import HTTPServer, BaseHTTPRequestHandler

class H(BaseHTTPRequestHandler): def do_POST(self): n = int(self.headers.get("Content-Length", 0)) open("/tmp/diag.json", "w").write(self.rfile.read(n).decode()) self.send_response(200) self.send_header("Access-Control-Allow-Origin", "*") self.end_headers() def do_OPTIONS(self): self.send_response(200) self.send_header("Access-Control-Allow-Origin", "*") self.send_header("Access-Control-Allow-Headers", "*") self.end_headers() def log_message(self, *a): # quiet pass

HTTPServer(("127.0.0.1", 9999), H).serve_forever()

这段代码所做的就是接受一个包含 JSON 数据的 POST 请求，并将其写入 `/tmp/diag.json` 文件。它会发送 `Access-Control-Allow-Origin: *` 头（包括来自 OPTIONS 请求的），以便运行在其他域名上的代码仍然可以与之通信。

然后，Claude 将这段代码注入到它正在浏览器中加载的模板里：

const host = document.querySelector("navigation-search"); const ta = host.shadowRoot.querySelector("textarea"); const cs = getComputedStyle(ta); fetch("http://127.0.0.1:9999/diag", { method: "POST", body: JSON.stringify({ dpr: window.devicePixelRatio, scrollWidth: ta.scrollWidth, clientWidth: ta.clientWidth, whiteSpace: cs.whiteSpace, width: cs.width, }), });

这段代码测量了 `<navigation-search>` Web 组件内部的 `<textarea>`，并将测量结果发送到服务器，服务器将其写入磁盘上的一个文件，Claude 随后便可以读取该文件。

在掌握了所有这些技巧之后，Fable……撞上了某个无形的护栏，把自己降级成了 Opus。幸运的是，Opus 能访问完整的对话记录，可以继续使用 Fable 开创的那些技巧，并且很快找到了、测试并验证了修复方案。

我提示 Opus 执行以下操作：

在 /tmp/automation-report.md 中写一份报告，记录你在此次会话中用于在我电脑上测试真实浏览器的所有技巧，并包含可运行的代码示例

它生成了这份报告，对于拼凑出这篇文章中发生的细节来说，这份报告价值连城。

我也分享了 Claude Code 会话的完整终端记录。

对其所做一切工作的回顾

基于一张截图和一行提示词，Claude Fable 5 + Claude Code：

弄清楚了运行本地开发服务器的方案（包括启动它所需的虚假环境变量）

启动了一个 Playwright Chrome 会话

开启了 Chrome 的可见滚动条设置 `defaults write com.google.chrome.for.testing AppleShowScrollBars Always`（之后它又关闭了这个设置）

也在 Playwright 中轮换测试了 Firefox 和 WebKit，未能重现该 bug

推断出我的默认浏览器是 Safari

构建了一个 textarea-scrollbar-test.html 的 HTML 文档

在真实的（非 Playwright 的）Firefox 中打开了该文档

发现 `osascript -e 'tell application "System Events" to tell process "firefox" to id of window 1'` 被阻止，因为“osascript 未获得辅助功能访问权限”

想出了上面描述的 `uv run --with pyobjc-framework-Quartz python` 变通方案

向网站模板中添加了 JavaScript，以便触发 / 键

构建了自己的小型 Python CORS Web 服务器来捕获 JSON 数据

重写了模板以捕获该数据并将其发送到服务器

通过 Web Component 的 shadow DOM 编写脚本，找到了它所需的信息

打开 Safari 以确认 bug 的来源

修改了它的自定义模板，尝试植入一个潜在的修复方案

确认了该临时修复方案有效

报告了如何修复该问题

就像我说的，极其主动！

成本估算

我目前使用的是每月 100 美元的 Claude Max 套餐，其中包含到 6 月 22 日为止 Fable 的慷慨用量额度，之后 Anthropic 表示将开始按完整 API 价格收费。

我正在用 AgentsView 追踪我的花费（参见这篇 TIL）。以下是 AgentsView 显示这次会话如果按全价付费所需的费用：

~ % uvx agentsview session usage be8850a7-6119-46a0-b5d6-79c7fff5ae2b Session: be8850a7-6119-46a0-b5d6-79c7fff5ae2b Agent: claude Output: 68606 Peak ctx: 113178 Cost: ~$12.11 (claude-fable-5, claude-opus-4-8)

如果你不盯紧点，Fable 会很乐意烧掉价值 12 美元的模型 token，来发明调试 CSS 的新方法。

我真的得把这东西锁死。

一方面，看着 Fable 不遗余力地去获取它所需的信息，来调试一个最终只需两行 CSS 就能修复的问题，确实很吸引人。

但另一方面……这有力地提醒了我们：编程智能体可以做到任何你通过在终端输入命令能做的事情——而且前沿模型通晓所有已知技巧，显然还掌握了一些前人从未记录过的方法。

如果 Fable 当时是在执行恶意指令——比如隐藏在代码或 issue 线程中的提示词注入攻击，或者我不小心粘贴到终端里的内容——它能走多远来窃取数据或造成其他破坏，想想都令人不安。

在沙箱之外运行编程智能体一直是个坏主意——我认为它最有可能成为 Johann Rehberger 在《AI 中的偏差常态化》中所描述的“挑战者号灾难”式事件。

可以说 Fable 更聪明，因此对潜在恶意指令也更警惕。但这种聪明是一把双刃剑：如果它真的被指令所颠覆，考虑到它那 relentless 的主动性，它能造成的破坏程度是可怕的。

2026 年 6 月 11 日

更多近期文章

Datasette Apps：在 Datasette 内部托管自定义 HTML 应用程序 - 2026 年 6 月 18 日

GLM-5.2 可能是目前最强大的纯文本开源权重大语言模型 - 2026 年 6 月 17 日

将 WASM wheels 发布到 PyPI 以供 Pyodide 使用 - 2026 年 6 月 13 日

本文是《Claude Fable 具有 relentless 的主动性》，作者 Simon Willison，发布于 2026 年 6 月 11 日。

claude-mythos
