为 AI Agent 流量配置代理
适用范围说明
为 AI Agent 配置代理,适用于你自己拥有或管理的设备、账号和网络。代理抓取的数据可能包含源代码、提示词、工具执行结果、模型输出、请求头,以及不小心被放进上下文里的密钥。请把代理日志当作敏感的生产数据来对待。
AI 编程 Agent 并不是在你的代码仓库里“思考”的。它实际上是在本地跑一个进程,收集上下文,调用远程模型 API,收到工具调用指令,在本地执行操作,再把结果回传给模型。
这给了你一个很有价值的检查点:本地 Agent 运行时和模型服务商之间的这条连接。在这个位置部署代理,能回答很多本地权限文件回答不了的问题:
-
到底有哪些文件、提示词、命令输出和工具 schema 被发送给了模型?
-
Agent 用的是哪个模型、哪个接口地址?
-
请求里有没有包含密钥或超大负载?
-
模型是否在某个危险本地操作发生之前,就请求了工具调用?
-
是哪条策略决定放行、拒绝或标记了这次请求?
代理给安全团队提供了一个网络层面的控制点,但完整的审计链条还需要本地会话历史、文件变更影响、进程遥测数据和策略决策记录。
代理并不是治理的全部答案。它不会知道开发者为什么批准某条命令、某次文件写入是否正确,或者某个npm install脚本是否做了不安全的事。但它确实能提供审计故事被采信之前所必需的网络证据。
基本架构
对于 HTTPS 模型 API 来说,一个代理方案包含三个组成部分:
-
Agent 进程需要把流量路由到代理。对于命令行工具,通常设置
HTTP_PROXY和HTTPS_PROXY环境变量;对于 IDE 插件,可能需要配置系统代理、PAC 文件,或者应用专属的 base URL。 -
智能体进程必须信任代理的证书颁发机构(CA),前提是代理在做 TLS 拦截。基于 Node 的工具通常使用
NODE_EXTRA_CA_CERTS;Codex 的文档提到CODEX_CA_CERTIFICATE和SSL_CERT_FILE;GUI 应用可能需要系统信任存储库。 -
代理必须记录日志、脱敏、评估策略,并在不破坏流式响应的情况下把请求转发到上游。
TLS 是最容易让人栽跟头的部分。普通 HTTP 代理能看到 CONNECT api.anthropic.com:443 隧道,但看不到隧道内的 HTTPS 负载。MITM 代理在本地终止这条 TLS 连接,向上游新建一条 TLS 连接,并向客户端出示一张由本地 CA 签发的、用于 api.anthropic.com 的叶证书。如果客户端不信任该 CA,请求就会因证书错误而失败。
证书管理不是无关痛痒的细节。本地 CA 私钥权限极大。如果被他人拿到,就可以冒充安装了该 CA 的机器所信任的站点。要为代理生成专用 CA,保护私钥,只安装在受管机器上,并在信任边界变化时轮换。
从显式封装开始
最干净的第一步不是设置系统级代理。先封装一条命令,让只有那个智能体进程继承代理环境。
以 Rye 的本地代理作为具体例子:
rye up --install-ca --intercept-patterns anthropic.com,claude.com,openai.com,chatgpt.com
然后验证代理和证书路径:
rye status
rye ca path
rye doctor
对于基于 Node 的智能体(比如 Claude Code),重要的环境变量是代理地址和 CA 捆绑包:
export RYE_PROXY="http://127.0.0.1:18080"
export RYE_CA="$(rye ca path)"
HTTP_PROXY="$RYE_PROXY" \
HTTPS_PROXY="$RYE_PROXY" \
NODE_EXTRA_CA_CERTS="$RYE_CA" \
claude
Rye 的封装器对子进程也同样处理:
rye wrap claude
封装模式避免了两个容易犯的错误。它不会在测试时代理你的整个工作站,并且能确保智能体在启动时看到代理变量。许多 CLI 和 IDE 运行时只在启动时读取一次代理和信任设置。
Codex 有不同的信任开关
不要假设每个智能体都是基于 Node 的。对于 Node 进程,合适的开关是 NODE_EXTRA_CA_CERTS,但 Codex 文档对自定义信任包给出的方案是 CODEX_CA_CERTIFICATE 和 SSL_CERT_FILE。
对 Codex 来说,优先采用文档中的 CA 变量:
export RYE_PROXY="http://127.0.0.1:18080"
export RYE_CA="$(rye ca path)"
HTTP_PROXY="$RYE_PROXY" \
HTTPS_PROXY="$RYE_PROXY" \
CODEX_CA_CERTIFICATE="$RYE_CA" \
codex
如果你的 Codex 版本或 HTTP 协议栈忽略了这些代理变量,那就改用该工具的基础 URL 或提供商设置。变量名不是关键,关键是要验证两件事:
-
智能体是否连接到了代理?
-
智能体是否信任代理提供的证书链?
调试时请精确捕捉失败模式。“代理里没有流量”和“流量到达代理但 TLS 校验失败”不是一回事,和“请求已转发到上游但提供商拒绝了 API 调用”更不是一回事。
能用 API 适配层时就用 API 适配层
中间人(MITM)代理很有用,因为它能配合那些只知道和 https://api.vendor.com 通信的软件使用。但当智能体支持可配置的基础 URL 时,反向代理或 API 适配层往往更简洁。
例如,Rye 可以为兼容 Anthropic 的流量启动一个轻量级 HTTP 适配层:
rye up \
--shim-listen 127.0.0.1:18090 \
--shim-upstream https://api.anthropic.com
然后把兼容的客户端指向这个适配层:
ANTHROPIC_BASE_URL="http://127.0.0.1:18090" claude
这种模式下,客户端与 localhost 之间走的是明文 HTTP,真正的 TLS 请求由适配层向上游发出。无需安装本地 CA。代价是兼容性:只有当智能体支持设置基础 URL,并且适配层能理解 API 形态、请求头、流式格式和错误语义时,这种方法才行得通。
需要广泛兼容时用中间人代理;客户端提供了稳定的基础 URL 开关时,用 API 适配层。
代理能看到什么
一次模型 API 请求通常不只有当前的提示词。根据智能体和提供商的不同,代理可能会看到:
-
模型名称和 API 路径,比如
/v1/messages、/v1/responses,或某个厂商特有的网关端点。 -
系统、开发者、项目和用户指令。
-
对话历史和总结产物。
-
工具定义,包括 shell、文件、搜索、编辑、MCP、浏览器和任务工具的模式(schema)。
-
文件片段、仓库映射、diff 和命令输出,作为上下文包含在内。
-
模型发出的工具调用请求。
-
本地执行后返回给模型的工具结果。
-
令牌使用量、请求 ID、延迟、状态码和流式事件分块。
这种可见性很有用,但也有其硬性边界。代理能看到跨越网络传输的流量,但它不会自动看到本地文件写入、Git 提交、权限提示或从未离开机器的 shell 命令。这些必须来自本地遥测:会话记录、文件监视器、进程监督、Git diff、shell 输出,以及特定助手的历史存储,如 ~/.claude/projects/ 和 ~/.codex/sessions/。
这通常是团队遇到的第一个缺口。代理回答的是“什么发送给了模型?”它本身不会回答“工作站上发生了什么变化?”
检查捕获内容
一旦流量开始流动,先查看元数据,再打开原始负载:
rye history --domain anthropic.com --last 10m
rye history --domain openai.com --last 10m
然后导出一个较小的时间窗口用于结构化检查:
rye history export --format json --domain anthropic.com --last 10m
先看那些常规字段:时间戳、方法、URI、状态码、内容类型、响应时间、用户代理和请求大小。这些字段能告诉你捕获路径是否正常工作,以及你看到的是否是正确的进程。
然后才检查 JSON 主体。对于 AI 智能体流量,主体通常就是审计记录:
{
"model": "claude-sonnet-...",
"messages": [
{
"role": "user",
"content": "Refactor the auth middleware..."
}
],
"tools": [
{
"name": "Bash",
"input_schema": {
"properties": {
"command": { "type": "string" }
}
]
}
对于流式 API,响应可能以服务器发送事件(server-sent events)的形式到达。一个可用的代理必须一边立即转发数据块,一边缓冲足够的数据来记录最终响应。如果代理等整个流接收完才转发,助手界面就会感觉像坏了;可如果直接转发而不做 tee 分流,又会丢掉响应体。
在网络边界施加策略
代理能解析请求之后,能做的就不仅是记录了——它可以在转发之前先评估策略。
一些有用的初始策略很简单:
- 拒绝包含明显私钥标记(如
BEGIN OPENSSH PRIVATE KEY)的请求体。 - 拒绝超过最大字节数的模型请求。
- 只允许已知的 LLM 域名。
- 对未知模型名或未知网关要求人工审核。
- 标记请求体中出现
.env、id_rsa、生产环境主机名或客户标识符的请求。
Rye 的策略引擎把请求当作结构化数据来处理:方法、URI、主机、路径、用户代理、内容类型、模型、请求体长度和解析后的请求体。规则可以按域名、模型、请求体内容或最大请求体大小匹配。代理随后可以在请求离开本机之前放行、拒绝或要求审批。
这与“不要发送机密”之类的提示词指令不同。提示词层面的策略依赖模型配合;代理策略则位于模型请求路径之外,可以直接把请求拦下。
常见故障模式
大多数配置失败都很平常。先检查这些点,再怀疑助手是不是在做什么不寻常的事。
不要用设置 NODE_TLS_REJECT_UNAUTHORIZED=0 的办法来解决证书信任错误——除非是在一次性测试 shell 里。禁用证书验证几乎不能帮你了解生产环境的真实情况,而且它削弱的恰恰是你想检查的那道边界。
需要脱敏的内容
原始模型流量是敏感的。为 AI 编程助手设立的代理至少应该脱敏以下内容:
Authorization、Cookie、Set-Cookie、X-API-Key以及各厂商特有的凭据头。- OAuth 令牌、会话 ID、刷新令牌和签名 URL。
- 私钥、
.env中的值、数据库 URL、云凭据和 SSH 材料。 - 被复制进提示词、工具输出、堆栈跟踪或测试夹具(fixture)文件中的客户数据。
为 AI Agent 流量搭建代理
脱敏处理直接决定了捕获的数据可以被存放在哪里。「含有凭据的原始提示词」和「正文已脱敏的结构化元数据」在法律和运维层面是两个性质完全不同的问题,这种差异会直接影响数据的集中化程度、留存周期和访问控制策略。
最稳妥的部署路径是:先只留存元数据,等确认可行之后,再针对限定范围的域名、团队或事故时间窗启用正文捕获。在建立起审查流程之前,留存周期一定要尽量短。
缺失的另一半:关联
代理提供的是模型流量,本地 Agent 提供的是会话历史,文件系统和 Shell 提供的是实际操作留下的痕迹。三者合在一起,才能构成真正可用的审计追踪:
模型请求
-> 策略决策
-> 携带工具调用的模型响应
-> 本地工具执行
-> 文件/进程/网络层面的影响
-> 工具结果回传给模型
-> 最终助手回复
如果不做关联,你手里最终只会剩下三个各说各话的片面记录:
- 服务商日志显示:确实发起了请求。
- 助手会话记录显示:确实发生了工具调用。
- Git 历史显示:确实有文件被改动。
但这些远不足以支撑事件响应。你需要搞清楚的是:哪一个模型响应触发了哪一次工具调用,是哪条审批或策略规则放行的,由哪个本地进程执行的,改动了哪些文件,又是哪一次后续请求把结果回传给了模型。
代理是网络视角的「镜头」。再加上对本地进程的包装、文件级遥测数据、会话记录接入,以及集中管理并带版本控制的策略,这面镜头才能升级成一套完整的审计系统。
一份务实的落地计划
从小范围开始:
- 在一台测试工作站上包装一个 CLI Agent。
- 只捕获模型 API 域名的流量。
- 用一个非敏感请求验证 TLS 信任是否正常。
- 先检查元数据,再决定是否留存正文。
- 添加对凭据和常见密钥格式的脱敏规则。
- 把代理捕获的数据与本地助手会话记录做关联。
- 从本地白名单逐步过渡到集中管理的策略包。
- 设定好留存期限之后,再推广到更多开发者。
终点不是「我们搭了一个代理」,而是「我们能证明 AI 编程 Agent 看到了什么、请求做了什么、策略允许了什么、事后又改了什么」。
这一层不能依赖某一个助手。团队会用到 Claude Code、Codex、Cursor、内部封装、MCP 服务器,以及日后出现的各种工具。真正稳定的控制点应该放在助手外部:由一个本地运行时监管器统一接管,负责路由流量、执行策略、收集历史记录,并把不同工具的审计数据规范化。
这正是 Rye 的构建形态。