在 OpenRouter 上用 DeepSeek V4.1 Flash 配置 Pi
2026年9月16日 作者:Vincent Schmalbach
Codex 和 Claude Code 的额度用完后,我就会切到 Pi 里的 DeepSeek V4.1 Flash,走 OpenRouter 访问。在《Inference Is the Last LLM Moat》那篇文章里,我说 OpenRouter 上各家服务商良莠不齐。这周我把 Pi 的会话日志和 OpenRouter 的生成 API 对照了一遍,发现这套号称便宜的配置,实际花的钱差不多是应有水平的三倍。下面是我现在用的配置,能避开最常见的几个坑。
写这篇文章的时候,我正在做 vroni.com——我开发的一个 AI 编程工具,能把任务直接变成 pull request。
配置
Pi 从 ~/.pi/agent/models.json 读取自定义模型。先在 Pi 里执行一次 /login openrouter 登录,然后加上这段:
{
"providers": {
"openrouter": {
"models": [
{
"id": "deepseek/deepseek-v4.1-flash",
"name": "DeepSeek V4.1 Flash (Fireworks, ZDR)",
"reasoning": true,
"thinkingLevelMap": { "off": null, "minimal": "low", "low": "low", "medium": "high", "high": "high", "xhigh": "max", "max": "max" },
"input": ["text"],
"contextWindow": 262144,
"maxTokens": 131072,
"cost": { "input": 0.22, "output": 0.66, "cacheRead": 0.007, "cacheWrite": 0 },
"compat": {
"thinkingFormat": "openrouter",
"sendSessionAffinityHeaders": true,
"sessionAffinityFormat": "openrouter",
"openRouterRouting": {
"only": ["fireworks"],
"allow_fallbacks": false,
"data_collection": "deny",
"zdr": true
}
]
}
再在 ~/.pi/agent/settings.json 里加上:
{
"defaultProvider": "openrouter",
"defaultModel": "deepseek/deepseek-v4.1-flash",
"defaultThinkingLevel": "high",
"retry": { "enabled": true, "maxRetries": 5, "baseDelayMs": 2000 }
}
Pi 会把 openRouterRouting 对象原样传给 OpenRouter 的 provider 字段,所以 provider routing 文档里支持的选项都能直接写在这里。cost 块只影响 Pi 显示的成本数字。contextWindow 决定 Pi 何时压缩上下文,这点我放到最后讲。
钱都花在哪了
在我愿意选的那些 OpenRouter 供应商上,DeepSeek V4.1 Flash 每百万输入 token 的价格是 0.22 到 0.30 美元,命中缓存的读取只要 0.006 或 0.007 美元。Pi 每一轮都会把整个对话发过去,所以几次工具调用之后,几乎整个提示词都应该是缓存读取。以 120k token 的上下文来算,缓存命中时一轮只要不到十分之一美分,没命中就要 3 到 4 美分。
我有两场会话在同一天共跑了 123 轮,缓存完全失效五次,部分失效七次。这十二轮就占了账单的一半。我一开始以为 OpenRouter 在背后换了供应商,其实没有。123 次请求全都发给了 Parasail,endpoint ID 也没变,是 Parasail 自己把缓存丢了。换成更老的 V4 Flash 0731 模型更糟,17 轮里只有 5 轮命中。
Auto Exacto 会挑上贵的供应商
我旧配置里列了四个承诺不保留数据的供应商,让 OpenRouter 自己选。对普通请求,OpenRouter 按价格做负载均衡。但每个 pi 请求都带工具,而带工具调用的请求,OpenRouter 默认会走 Auto Exacto——这一步路由会按 OpenRouter 自己的工具调用评测给供应商重新排序,完全不管价格。对这个模型,它选中的是 Parasail,而 Parasail 是我这个池子里最贵、可用率还最差的一家。官方文档自己也说,Auto Exacto 会在 agent 循环里导致对话中途缓存失效,用 sort: "price" 就能关掉它。
回退会丢掉缓存
提示词缓存放在供应商那一端。OpenRouter 的粘性路由会把一个会话固定在同一个供应商上,而 pi 已经会发送它用来做键的 x-session-id 请求头,这部分不用配置就能生效。但 allow_fallbacks: true 一开,上游一次限流就足以把会话挪到另一个供应商,而那边没有缓存。有一次测试里 DeepInfra 返回了 429,OpenRouter 回退到 Fireworks,整个提示词就全按新输入计费了。如果把供应商锁死、关掉回退,429 就会变成带退避的重试。所以 settings.json 里的重试次数从三次调到了五次。等上半分钟重试,比为一个回退的轮次付四美分划算多了。
选哪家服务商
我用一段 1.5 万 token 的提示词、跑 20 轮的方式测了这几家候选服务商,每次只固定(pin)一家,同时查看每次响应里的 cached_tokens。
缓存读取的价格没有我以为的那么重要。缓存命中时,缓存读取大约占我每天账单的三分之一,剩下三分之二是全新输入和输出。所以即便 Fireworks 每百万缓存 token 收 0.007 美元,算总账还是比 Novita 便宜 20%。真正要留意的是那些价格离谱的:同一个模型,BaseTen 每百万缓存 token 收 0.03 美元,是其他家的五倍。所以在固定某一家之前,先到模型的服务商列表里把三种价格都看一遍。
限流来自上游、按模型计算,OpenRouter 上所有人共用,而且时有时无。DeepInfra 跑 V4.1 Flash 根本没法用,但跑 0731 没问题,而且还是那边最便宜的可选项,每百万输入 0.06 美元。Fireworks 有天下午 10 次调用里返回了四次 429,之后的 31 次调用一次都没有。如果 Fireworks 开始卡在重试上,我就把固定目标换成 Novita。
zdr: true 加上 data_collection: "deny",会把路由限制在不会留存提示词的服务商上。这就排除了 DeepSeek 自家的端点——它本来最便宜,每百万输入 0.15 美元、每百万缓存 0.003 美元。我不希望客户端代码被塞进训练集,所以这个代价我认。
上下文窗口与压缩
上下文超过 contextWindow 减去 16,384 token 预留量时,pi 就会压缩。DeepSeek V4.1 Flash 标称支持一百万 token,如果你往 models.json 里写 1,048,576,pi 基本永远不会压缩。可上下文越长越贵,哪怕每次读取都命中缓存。在百万 token 的规模上,一次未命中要花 30 美分,预填充得等一分钟。一个小而快的模型,不会因为多塞了几十万 token 的旧工具输出就变聪明。Codex 默认用 272k 的窗口,并在这个窗口快满时压缩。我设成 262144,这样 pi 的阈值大约落在 245k。我的长会话峰值在 120k 左右,所以很少触发;而万一某个会话失控,它也能把损失封顶。在同一会话里切换任务时,我会手动执行 /compact,而不是把旧上下文一路带过去。
派发任务,坐等软件交付
把 GitHub issue、bug 报告、规格文档或一个粗略的想法交给 Vroni。它会读取代码仓库、规划改动、编写代码、运行检查,最终推进到一份可以直接送审的 pull request。