“你的密钥和流量留在你自己的网络里。”这是Foreman项目页面最显眼的一句话。对于每天要跟一堆大模型API打交道的开发者来说,这话直击痛点——你既想把成本打下来,又不想把敏感的密钥和请求内容交给第三方网关。于是有人用Go搓了一个二十几兆的二进制文件,塞在你自己的服务器上,就当起了编程助手和大模型提供商之间的智能调度员。
它不只是一个代理,更像是一个把“省钱逻辑”写进代码的账房先生。每次请求,它会在你允许的模型池里挑最便宜的那个,花掉的每一分钱都记在账本上。更重要的是,它懂得什么时候该用顶尖模型,什么时候用便宜的就够,而且切换模型时不会傻傻地扔掉已经付费的缓存。这个开源项目叫Foreman,周末在Hacker News上亮相后,引来不少同行的共鸣。
我们把它的运作方式拆开看看,一个能帮你把大模型调用费砍下30%以上的网关,到底在哪些环节做了文章。
先看路由分层。Foreman把模型分成三个档次:便宜、中等、前沿。优先级规则很清晰:如果你在请求头里明确标注“高风险”或者“规划”类任务,它直接上顶级模型,这是硬杠杠;其次看任务类型头,比如你通过X-Foreman-Task-Type指定是编码、计划还是快速响应;再往后才是你的编程助手自己选的模型。比方说你的助手要调claude-sonnet-4-5,根据你在目录里的映射,它可能被归到中等层;助手如果喊了一个你不认识的模型,那就按默认的低成本层处理。
整个过程不会看消息内容,只靠请求头和你写的策略,隐私上又加了一层安心。
到了每个层级内部,路由也不含糊。一个层级就是一个模型列表,多个供应商的同类模型互备互竞,Foreman实时挑那个最便宜且健康的。这意味着平时你可以放好几个不同家的模型,谁家今天降价,流量自然就流过去了,不用你手动改配置。如果某家供应商连续报错,断路器就会跳开,冷却一段时间后试探性放行,不行就继续隔离,同时请求自动切换到同层的下一个备选。故障转移这块做得挺工业,阈值、冷却期、半开探测一应俱全,不是简单的try-catch。
真正让人拍大腿的设计是缓存保持。做过大模型应用的人都知道,提示缓存是省钱利器,可一旦换了模型,之前辛辛苦苦喂进去的上下文缓存就失效了。Foreman的做法是:用会话ID把一轮对话钉在一个模型上,只要该供应商的提示缓存还没过期,它就纹丝不动。缓存过期时间是从目录配置的prompt_cache.ttl_seconds来的。只有当客户端主动更换模型选择,或者任务类型头变了,它才会跨层释放这条暖路由。没有标记的普通流量则乖巧地待着,绝不乱切,免得为省几个子儿把缓存烧了,反而得不偿失。
上面这些决策,每一笔都留痕。每个响应都会带上X-Foreman-Trace-ID、X-Foreman-Model、X-Foreman-Provider、X-Foreman-Route-Reason四个头。你可以在命令行敲一句foreman trace <追踪ID>,它会回放完整的决策过程:当时选了哪个模型,哪些备选被拒绝了,为什么拒绝。哪怕是为了定位一次异常的API开销,也能自证清白。
安装流程也维持了Go生态的清爽感。macOS用户可以直接用Homebrew:brew install northwood-systems/tap/foreman。Linux或者想从源码构建的话,一条go install github.com/Northwood-Systems/foreman/cmd/foreman@latest就搞定,当然前提是装有Go 1.26及以上。你也可以从发布页下载预编译包,或者自己go build。启动后用foreman init交互式配置,选定供应商,把模型划到便宜、中等、前沿三档,生成一个Foreman专用密钥。这个密钥只在初始化时显示一次,后续只存哈希值,不存明文。值得特别提一嘴的是,它全程不问你要任何服务商的密钥,要求你把它们放在环境变量里,用${变量名}的方式引用,启动时从变量读取。你的密钥自始至终不会落盘在Foreman的任何配置文件里。
配置好之后,把编程助手的API端点指向它就行。官方已经在文档里给出了Claude Code、Codex、OpenCode和Pi的接入示例。网关启动时,会通过/v1/models端点宣告自己支持foreman-plan、foreman-code、foreman-fast这些虚拟模型名,方便助手切换层级。你也可以直接拿目录里定义的别名或者上游模型名去调,比如请求claude-sonnet-4-5,它会自动解析到对应层。未识别的模型名则安稳地走默认低成本路径,一个请求都不放过,也一个多余的钱都不会浪费。
热门跟贴