AI编程智能体的隐私:5个常见误区逐一拆解
你的AI编程智能体可能在你不知情时发出HTTP请求,甚至在User-Agent里带上你的邮箱。五个关于智能体隐私的误区,逐一实测。

每天收到几十封诈骗邮件,上面还印着你的真实姓名。而泄露的源头既不是被黑的数据库,也不是外泄的营销名单,而是User-Agent请求头。这个头是你的AI编程智能体在你并未明确批准的网络请求上附带的。开发者追查一波垃圾邮件时,发现源头是Claude Code:它在网页抓取和搜索时,把用户的账户邮箱地址写进了外发的HTTP请求。Anthropic自己的解释几乎比漏洞本身更糟:他们把账户邮箱注入了模型上下文,好让模型能写出像样的@author标签,结果模型像个热心的小机器人,一有网站索要联系方式,就主动把邮箱交了出去。我多年来审计过跑在开发者机器上的工具的网络行为,这起事件是一个近乎完美的教学案例。所以下面我们就来看看,关于智能体工具隐私,我最常听到的五种看法,并把每一种都和实际发生的事情对照检验。
误区一:“我的编程智能体只会和模型厂商的API通信”
几乎每个人一开始都是这么想的:智能体就是终端和Anthropic(或OpenAI,或别的什么厂商)服务器之间的一根高级管道。代码进去,token出来,唯一值得关心的网络端点就是api.anthropic.com。
这种想法并不对。现代的智能体CLI本质上是一个通用HTTP客户端,只不过由语言模型来驱动。它有一个WebFetch工具,可以抓取任意URL;有一个WebSearch工具,会访问搜索基础设施;还有一个Bash工具,这意味着curl、wget、pip install、npm install、git clone,以及你系统上所有能联网的程序。当它认为需要文档、包、更新日志或SEC文件时,就会去取,去它认为东西所在的任何地方。每一个这样的请求都从你的IP地址发出,经过你的公司网络,并带着模型当天早上随手写下的任何请求头。
模型的发挥空间可不小。邮箱事件曝光后,一位工程师检查了自己网站的服务器日志,发现有子代理发来的请求,User-Agent字符串类似company-helm-research/1.0 (Claude Code agent run by [name], [company] platform team; docs lookup),里面还有雇主名称和他们正在开发的GitHub仓库。智能体并不是泄露了某个配置值,而是根据上下文自行组合出了用于识别身份的请求头,就像一个热心的实习生在每封陌生邮件的末尾都签上全名、团队和项目名。如果你想深入了解为什么这种架构让这类问题如此容易发生,我们之前写过智能体编程CLI是如何构建的。简而言之,循环、上下文和工具集的能力,恰好强大到足以惹出麻烦。
正确的理解方式是:你的智能体就像一个带着公司笔记本、连着公司网络、还揣着一摞你名片的初级员工。它上下文里的任何信息,都可能通过它能调用的任何工具离开这栋大楼。
误区二:“在User-Agent里放联系邮箱,只是礼貌的爬虫规范”
这个说法有一点道理,而正是这点让它很危险。确实存在一个真实的惯例:规范的爬虫应当标明身份并提供联系方式。有些服务对此执行得非常严格。比如SEC的EDGAR API,如果请求的User-Agent是通用的curl,它会直接拒绝,并要求声明联系人。你可以花十秒钟亲自验证:
U='https://data.sec.gov/api/xbrl/companyconcept/CIK0000320193/us-gaap/Assets.json'
curl -s -o /dev/null -w '%{http_code} default UA\n' "$U"
# 403 default UA
curl -s -o /dev/null -w '%{http_code} declared contact\n' \
-A 'Acme Research admin@acme-research.example' "$U"
# 200 declared contact
所以,一个学到“某些API希望在User-Agent里看到联系地址”的模型,并不是在胡编乱造,它只是在模仿真实的互联网礼仪。而如果这个模型的上下文里恰好有你的账户邮箱,它手头就只有这么一个联系地址可以交出去。解释这起事件的Anthropic工程师也承认了这一点:有些网站会要求智能体提供联系方式,而Claude有时就会给出它掌握的那个邮箱。
问题就出在这里。这个惯例的本意是机器人的运营方提供他们自己的联系方式,也就是运行爬虫的实体,这样被打扰的站长能找到一个负责任的人。Anthropic的爬虫标识的是Anthropic,Google的标识的是Google。但当你的智能体抓取页面时,运营方联系方式应该是工具供应商的支持页面,或是你有意配置的地址,而不是你用来付订阅费的个人账户邮箱。RFC 9110关于User-Agent的指导明确反对包含不必要的详细身份信息,我认识的每一位隐私工程师都会把请求头里未经同意的个人身份信息视为缺陷,没有任何但书。爬虫礼仪从来不是为了让坐在爬虫背后的那个人暴露身份而设计的。
而且影响范围是实打实的,并非纸上谈兵。任意第三方网站,包括搜索型智能体难免会碰到的那些充斥诈骗的网页角落,现在都掌握了一位在职软件工程师经过验证、带着姓名的邮箱地址。这就是现成的鱼叉式钓鱼种子,还包装得整整齐齐。多位开发者都把突然涌来的定向垃圾邮件直接追溯到了这一行为。“礼貌的机器人公民”如果让你被人肉给了垃圾邮件商,那既谈不上礼貌,也谈不上公民。

误区三:“权限弹窗和沙箱能把我的身份圈住”
每个智能体工具都有某种形式的授权交互:智能体在执行命令前会询问你,会展示它正在读取哪些文件,也许还会让网络访问需要按域名逐一批准。这给人一种强烈的印象,有位开发者形容为“LLM只能访问项目中明确添加的东西”。这种印象是错的,而邮箱事件从两个层面证明了这一点。
首先,权限系统管控的是哪些工具运行,而不是模型在这些工具发出的请求里写了什么。批准“好,抓取这个URL”,并不能告诉你模型为这次抓取编写了哪些请求头。批准一个会运行curl的Bash调用,告诉你的就更少了,命令字符串一闪而过,没人会去看那个-A参数。其次,权限界面是按单次动作设计的,而泄露是上下文的属性。一旦你的账户邮箱被注入系统上下文(用户既看不到,也无法选择退出),它就对每一次工具调用、每个子代理、每一条curl命令、整个会话期间都可用。沙箱的边界画在了文件系统周围,而外泄的通道恰恰是模型自己的文本生成。
这里我想说得直白一些,因为它的适用范围远超某一家厂商的漏洞:智能体上下文里的任何东西,都只需要一条听起来合理的指令,就能离开你的机器。API密钥、内部主机名、文件内容、你的名字、你的雇主、你的邮箱,无一例外。当模型本身就是外泄通道时,工具层面的隔离帮不上什么忙。这也是我之前论证遏制与监控为何解决的是AI智能体的不同问题的原因,你需要弄清楚自己实际得到的是哪一种。权限弹窗其实就是披着控制外衣的监控。它能告诉你要执行的动作,却无法展示动作参数里编码的意图。
结论:沙箱按出厂设置运行时,保护的是你的文件;但它对你的身份毫无作用,因为你的身份已经被当作原材料交给了模型。
误区四:“这只是个设置,打开开关就安全了”
事件闹大时,最初报告者的要求很明确:这不该是一个可以关闭的选项,而应该直接从整个运行框架中移除。这个直觉是对的,而问题最终的解决方式,恰恰说明了为什么“设置”是处理这类问题的错误手段。
修复分两步。第一步,内置了一个插件(cc-plugin-privacy,从v2.1.317起默认启用),它会确定性地阻止这一行为,这是硬性检查,而不是给模型的建议。第二步,也是更重要的一步,Anthropic把账户邮箱从模型上下文中彻底移除。注意这里的先后轻重:插件是对输出的过滤,而移除邮箱是移除能力本身。过滤可能会漏,而一个从来不知道你邮箱的模型,无论它多有创造力地组合请求头,都泄露不了它。
你没法靠提示词摆脱数据暴露。模型能看到的,模型就能输出。唯一可靠的脱敏方式是减法。
这种模式我在智能体工具中反复见到,它也与我们之前讨论的审计兼作凭据保险库的API客户端如出一辙:敏感材料被塞进最方便的地方(上下文、环境变量、配置文件),因为某个功能曾经需要它一次,之后它就随处可见。遥测开关和隐私设置解决的是厂商决定收集什么的问题,却对模型可能利用它所拿到的材料即兴发挥的情况只字不提。设置是用来管偏好的,确定性控制和数据最小化才是用来管隐私的。如果厂商拿前者来修补后者,你应该据理力争。
误区五:“厂商已经修复了,我可以不用担心了”
公道地说,这次的响应速度很快,工程层面的解释也很坦诚,修复也针对根本原因,而非表面症状。但“已修复”只是对某个版本中某个具体行为的断言。这类问题(智能体工具向任意端点发出可识别身份的材料)是结构性的,它还会在这个工具或别的工具中再次出现。好几位用户指出,这并不是账户身份第一次未经邀请地出现在Claude Code的上下文里,至少是第二次。
更深层还有一个更难接受的事实:从客户端一侧,你无法完全验证不存在泄露。一位认真的用户对修复后的版本运行了中间人代理,确认WebFetch工具没有让任何可识别身份的信息离开他的机器。这是很好的工作,方向也完全正确。但正如他所指出的,身份识别也可能发生在服务端:你的客户端向厂商的API发送匿名请求,而厂商那边的基础设施再带着你的信息扇出给第三方。到了这一步,再多的本地抓包也看不到。你最终还是要信任厂商,而这恰恰是这次事件让人感到不安的地方。
所以,持久的应对姿态不是“补丁已打,万事大吉”,而是把每一个智能体工具都当作一个永久存疑的网络客户端,定期审计,就像对待工程师笔记本上任何拥有广泛权限的第三方软件一样。接下来就是实操部分。

如何自己审计智能体的网络流量
这一切都不需要安全团队。花一个下午,借助一些标准工具,你对智能体行为的了解就会超过任何隐私政策。
1. 拦截流量。让智能体指向mitmproxy,然后跑一次真实的工作会话。基于Node的CLI在信任你的CA之后,一般会遵循代理环境变量:
mitmdump --listen-port 8080 -w agent-flows.mitm &
export HTTPS_PROXY=http://127.0.0.1:8080
export NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem
# Now run your agent and do normal work.
# Afterwards, search every captured request for your identifiers:
mitmdump -nr agent-flows.mitm \
--flows \
| grep -iE 'you@company\.com|YourName|your-org'
不要只搜索你的邮箱,还要搜索你的名字、雇主、组织的GitHub标识、内部主机名、仓库名。记住子代理的日志:模型不只是在重复已有的标识,而是在组合它们,所以要搜索片段。
2. 检查你自己基础设施的日志。如果你运营任何网络服务,就在访问日志里搜索智能体的User-Agent字符串。前面提到的那些组合出来的请求头,正是这样被发现的。这几乎不花成本,而且常常能发现本地抓包漏掉的子代理流量。
3. 限制出口流量。最有效的控制,是让整类泄露变得不可能。把智能体运行在一个容器或虚拟机里,其网络策略只允许它合法需要的端点,比如模型API、你的包仓库,或许还有GitHub。在Docker里,就是自定义网络加出口防火墙;在Mac上,Little Snitch或Lulu可以提供按进程的规则。如果智能体在沙箱里无法访问任意网站,它也就无法把你的身份交给任意网站。它得先问你才能去取东西,这确实麻烦,但麻烦正是目的所在。
4. 减少工具所知道的信息。为工具账户使用专门的、低价值的邮箱,不要用你的主工作邮箱。清理智能体会读取的全局配置文件中的身份信息(~/.gitconfig就是智能体常会读取的一个例子)。如果工具支持,就在独立的操作系统用户下运行,并使用单独的主目录。减法永远胜过过滤。
5. 在组织层面,通过托管代理转发流量。如果你的公司给工程师配发智能体工具,就强制它们的流量经过一个带日志记录的出口代理,并在管线中加入请求头检查。仅靠DNS查询日志,就能发现智能体向数百个不寻常域名扇出的规律。这和你对待任何CI运行器或构建机器的姿态一样,而这个框架再恰当不过:智能体就是有主见的构建基础设施。
这个User-Agent里带邮箱的漏洞,一个月后就会被遗忘,淹没在发布说明的更迭之中。但我们不该忘记它的教训。编程智能体是我们大多数人运行的权限最高、网络活动最频繁、审计最少的软件,而且它们还会即兴发挥。所以要相应地对待它们:假设其上下文中的任何东西都是公开的,验证实际发到网线上的内容,并在需要之前就把笼子建好,而不是等垃圾邮件已经带着你的名字寄到了门口。


