跳到主要内容

别把自建代理当洞察,那是你早欠下的基础课

老铁
老铁

· 阅读约 9 分钟

HN 上那帖我翻完了,越翻越堵。主题说:不自己搭一个 LLM 代理,就很难掌握模型调用的实际情况。底下几十条回复,有人推 LiteLLM,有人推 GoModel,有人直接甩一段短脚本——把 OpenAI API 地址改到本地代理,转发请求的同时把 HTTP 报文存下来。看完第一反应不是学到东西,是难受:这帮人把网关重新发明了一遍,然后当 AI 时代新发现拿出来分享。

这有什么新?任何一个后端干了两年的人都该知道,只要你有个组件你无法完全控制,就在它前面放一层中间层。这层干的事从来没变过:看见流量、拦流量、量流量。过去二十年,它叫反向代理、叫 API 网关、叫负载均衡、叫服务网格。现在改叫 LiteLLM、叫 GoModel、叫“自己写个 20 行脚本”。名字换了几茬,原理一个字没动。

真正让我不爽的不是他们搭了代理,是他们把这当进阶技巧在教。有人在问护栏具体有哪些类型,有人担心客户端要不要看到 API 密钥,有人比较哪个网关工具好用。问题一提出来就露馅了——提问的人压根没把“我的 agent 到底在跟模型说什么”当成必须回答的问题。可这恰恰是整场讨论里唯一值得回答的问题。

把话说死:你今天用 agent 做了任何有后果的事,却没有一层自己的代理去记录它对外发出的每一次请求,就是盲目飞行。字面意义的盲目。你不知道它给模型发了什么 prompt,不知道它挑了哪个工具,不知道它半路是不是被某个网页内容注入了指令。你盯着最后吐出来的结果,觉得还行——可那个结果可能早就被污染了,是它自己“修”出来的,是一步步滑向错误方向之后剩下的一具还看得过去的壳。

有人回帖说“自建 agent/harness 的主要动机是获得对代理行为和决策原因的可观测性”。我一点不意外。这不是什么高深洞察,这是最本能的工程反应:一个系统开始做你看不懂也不全信的事,你第一反应应该就是装日志,第二反应加开关。他做对了,但也仅此而已。

代理层给的就三样东西,我按顺序讲。

先说访问控制。供应商的 API 主密钥藏在自己代理后面,只给 agent 发虚拟密钥。agent 那边泄露了,你吊销虚拟密钥就完事;代理日志还能告诉你它拿那个密钥干过啥。反过来,你要直接把 OpenAI 或 Anthropic 的主密钥塞进 agent 配置里,等于把你全部额度、全部权限交给一个你只能半信半疑的进程。这不是什么高深安全议题,这是权限最小化:给一个组件完成任务所需的最小权限,别把你全部家当都押上。

再说可观测性。这层我以前反复讲过,但这次楼里有个细节特别典型。有人问怎么查模型输入,答案是:把 OpenAI API 地址改到本地代理,二十行脚本转发请求、落盘 HTTP 报文。就这么简单。不需要分布式追踪,不需要买商业平台,一个下午就能搭起来。这段脚本最值钱的不是它能存请求,是它逼你正视一个你过去从没想过的问题:我的 agent 到底在说什么。

# 最小代理:转发 OpenAI 请求并落盘
from http.server import BaseHTTPRequestHandler, HTTPServer
import urllib.request

class LLMProxy(BaseHTTPRequestHandler):
    def do_POST(self):
        n = int(self.headers.get('Content-Length', 0))
        body = self.rfile.read(n)
        # 落盘,先不解析,保持原始
        with open('/var/log/llm.jsonl', 'ab') as f:
            f.write(body + b'\n')
        # 原样转发
        req = urllib.request.Request(
            self.path, data=body,
            headers={k: v for k, v in self.headers.items()
                     if k.lower() != 'host'}
        )
        with urllib.request.urlopen(req) as r:
            self.send_response(r.status)
            for k, v in r.headers.items():
                if k.lower() not in ('transfer-encoding', 'content-encoding'):
                    self.send_header(k, v)
            self.end_headers()
            self.wfile.write(r.read())

HTTPServer(('0.0.0.0', 8000), LLMProxy).serve_forever()

这不是生产代码,这是最小佐证,证明这件事机制上就这个复杂度。关键是搭完之后你真去看日志,不是说搭完就忘了。

最后说护栏。楼里有人给了很实在的数字:用 gpt-oss-safeguard 做提示注入检测,配一套描述各种注入手法的策略,只检查网页抓取和搜索结果,一天花 5 到 20 美分。这段数字比选哪个模型重要多了。关键不在那个具体模型,在他做的两件事:一,专用提示注入防护模型能力有限,所以他换了通用模型加策略;二,他没试图“全量防护”,明确划了范围,只查网页抓取和搜索结果。这才是最朴素的工程判断:知道自己的攻击面在哪,知道哪些输入有风险,集中资源防风险那一段,而不是装模作样防所有东西。花 5 到 20 美分把自己暴露面管清楚的人,比买了个商业“AI 防火墙”然后宣布自己安全的人,靠谱得多。

提示注入这件事,从 LLM 第一天进生产就被反复念叨。但多数人走到两个极端:要么当它不存在,要么当成“AI 特有”的玄学问题,等某个模型一劳永逸解决。两头都是本末倒置。提示注入的本质很简单:一股你无法完全信任的文本,流进了模型上下文。这个问题老版本叫 SQL 注入,叫 XSS,叫任意文件读取。处理思路从来没变过:识别不可信输入,在它到达执行引擎前检查,能过滤就过滤,能转义就转义,能限制范围就限制。现在无非是把执行引擎从数据库换成了 LLM。结果一堆人表现得像人类第一次碰上这件事。这话我承认说得有点重,但你自己想想,是不是这么回事。

再把成本那段补上。我本来想跳过去不写,但那个“四天 3000 美元”的数字实在刺眼。楼里有人贴出信息:每月 200 美元的 Claude Max 套餐经常碰到周限额,换成 API 后两三天就烧掉 200 美元;另一个重度用户说按 API 定价,最近四天就会超过 3000 美元。底下有人分析订阅是获客补贴,有人说 API 单位价格在降,不必急着迁。这串争论本身不是重点。重点是,那些能报出精确数字、能算出自己实际消耗的人,全是有代理日志或者 API 账单数据的人。那些还在说“我感觉订阅挺划算”的人,根本不知道自己的 agent 一天花多少钱、钱花哪去了、哪些消耗纯属浪费。差距就出来了——不在钱,在可观测性。

我见过太多人把“用了 Claude Code 或 Cursor”等同于“开发流程升级了”。然后月底账单到手,才发现 agent 在半夜跑了个废弃的循环任务,烧掉上百美元。这种坑能不能提前避开?能,前提是你有个能看见流量的中间层,而且在账单爆炸之前盯着它看。不是等到扣款才反应过来。这就是代价。基础功没有捷径。

那怎么干。我的回答一直没变:别从工具开始,从需求开始。你现在有个人在帮你执行代码,它每次行动都涉及一个你无法完全预测的过程,你要对它的后果负责任。那就必须拿到三样东西——完整记录、权限隔离、可拦截的卡口。前两样,一个二十行脚本就能给你;第三样需要稍微花点心思,但也不高深。

按顺序排:

  1. 先写最土的那个短脚本,把 OpenAI 或 Anthropic 的 API 地址指到本地,把每个请求原样存下来。别折腾镜像、流式解析、追踪系统。就存原始 JSON,能 grep 能看就行。这一步的目的不是生产可用,是让你第一次“看见”你的 agent 在说什么。这一层想通了,后面才有得谈。
  2. 在存日志的基础上,加一个开关:哪些输入源的内容直接拒绝或标记。比如 agent 要访问网页,就把网页内容先过一遍护栏规则,再拼进 prompt。宁可拦掉一些正常流量,也别让不可信文本无过滤进模型。止损点前置,这是 agent 工程里最容易跳过去的一课。
  3. 等前面这些脏活做完,你自然就清楚 LiteLLM、GoModel、OpenRouter 这些东西替你省了哪部分力气、加了哪些你不做不行的约束。到那时候再选工具,你是带着明确需求去选的,不是为了“大家都在用”推着走。

这个顺序不能反。反了就是本末倒置:先挑个看着高级的工具,然后为了迁就工具去扭曲需求。跟先买了个昂贵的编辑器再找项目做一样——你大概率会为了用上工具硬凹问题。

最后把态度亮清楚。我的态度很明确:HN 上那帮人搭代理的行为是对的,但这事不值得当新发现庆祝。它属于基础设施里最底层那一课,是在 LLM 之前就该掌握的本事。现在被当成新鲜玩意儿讨论,只能说明这波工具把太多人直接抬到了“能用”,没经过“能管”。就像在沙子上盖了楼,忽然有人喊“我发现这楼需要地基”,还一堆人跟着惊叹——地基从来都需要,只是你之前没打而已。

工具好不好、哪个更新快、哪个作者响应快,放工程角度看都是枝节。你真正要抓住的,是横在所有工具上面的那条原理:看不见就管不了,不测量就保护不了,不审查就信不了。这套规则既不是 AI 时代才冒出来的,也不看你写不写代码——它只看你是不是个工程师。如果你今天在跑 agent 却没有代理层,先把上面二十行的脚本写出来,去看你日志里到底发生了什么。然后再说别的。

老铁
老铁

把每个技术现象拆到原理、再上升到工程价值观,崇尚基础功、反浮躁。

查看主页 →