只改一件事
多数想把编程智能体装进自家界面的工具,最后都在重新实现它。还有一种更窄的做法:照原样启动那个真正的命令行工具,只把一个 URL 指向别处。
为什么「包一层」通常会出问题#
要把别人的编程智能体装进自家产品,最直觉的做法是替它说话:解析它的输出、在自己的面板里重画、通过自己的协议驱动它。演示效果很好。然后那个智能体发了个新版本,输出格式变了,你的解析就错了——而且错得像是那个智能体变差了。你从此维护着别人产品的一份副本,对方每一次改进都以你的 bug 的形式到达。
还有一笔代价会晚一点出现。智能体是以自己的身份鉴权的——一个订阅登录、一个 OAuth 令牌、一次设备授权。一个居中代管对话的包装层,往往也会顺手代管凭据;于是用户自己的账号,变成了由你的产品持有,而不是由那个智能体持有。
更窄的那个做法#
Mirasim 直接启动那个真正的智能体命令行工具,并继承它的标准输入输出——你对话的那个进程就是 Claude Code、或者 Codex,和它自己发布的一模一样。然后它只改一件事:把智能体的模型 base URL 指向一个本地代理,而不是供应商。整个介入就这么多。
- 逐字转发请求体
- 它不解析任何东西。它不知道也不关心请求体是 Anthropic 的线格式、OpenAI 的、还是某种还不存在的格式——这正是它能对任意供应商、任意智能体版本继续生效的原因。
- 不碰你的鉴权
- 默认是直通:不注入任何 API 密钥,与供应商通话的是智能体自己的登录态。只有在某个智能体确实要求密钥时才提供。
- 抓取走旁路
- 请求与响应会以原始字节旁路落盘。记录器绝不允许阻塞、改写或破坏正在跑的会话——它的有界队列写满时会丢数据并统计丢弃量,而不是让智能体变慢。
这条约束换来了什么#
因为什么都不翻译,智能体还是它们自己。Claude Code 保留自己的终端界面与登录态,Codex 也一样。已有的登录直接沿用——不需要再注册一个账号,也不需要在我们的产品里重新授权一遍。每条会话各自选智能体、各自选模型,所以两个面板可以同时跑两个不同的智能体、连着两个不同的供应商。
这也意味着「原始视图」是真的。一个按钮就能让会话在智能体自己的终端输出和我们渲染的面板之间切换——而终端那一侧不是重建出来的,是智能体真正写出的那些字节。出问题时,这个区别决定了你是在排查那个智能体,还是在排查我们对它的理解。
代价也是真的,值得说清:一个只做路由的东西没法抹平智能体之间的差异。两个智能体行为不同、失败方式不同、配置方式也不同,我们不会用一个统一的外观把这些藏起来。我们负责的是流量去哪、记录什么、以及它们外面那套工作台做什么——而不是假装它们是同一个工具。

