杰哥的{教学,运维,编程,调板子}小笔记

用 Files API 减少图片体积导致的 TTFT 膨胀

背景

最近经常用 DeepSeek-V4.1-Flash 模型读图,随着上下文里的图片越来越多,由于每次请求都要传完整上下文,上传图片的时间很快就成了 TTFT 的主要瓶颈;如果走的是 OpenCode Go,甚至动辄要几分钟。为了解决这个问题,可以用 Files API 提前把图片上传到 DeepSeek,然后在上下文里直接用 id 引用文件。为此,我 Vibe 了一个 pi-files-api 插件,给 Pi Agent 添加上这个能力。

具体现象

最近发现一个现象:在一些会话里,TTFT 稳定地偏高,而且越来越高:10s、12s 一路上涨,有时甚至到几分钟的量级,而这些会话都包含大量的图片读取。一开始我以为是服务端的问题,后来通过交流和分析才发现,图片会在每次请求时都重新发给后端,随着读图不断累积,TTFT 的大部分时间都耗在了上传图片上。

一开始,我还寄希望于有状态的 OpenAI Responses API,也就是每次只发送相对上一次请求的增量,避免图片的重复上传。然而 DeepSeek 目前还没有实现这个功能,所以只能用 Files API。

Files API

Files API 可以理解为一个临时的网盘:支持上传、列举、删除和查询,有 OpenAI 和 Anthropic 两个版本,不过功能大同小异。在这个临时网盘里,每个文件都有唯一的 id,可以出现在 chat completions/responses/anthropic messages 的请求体中,用来代替实际的图片。

因此,如果 Agent 知道使用这个 Files API,先用它上传图片,再用 file id 填充请求体,就可以解决上述 TTFT 暴增的问题。DeepSeek Harness 是支持的,但前提是使用第一方 API;像我这样通过 AxonHub 统一管理 API key 的情况,它就不会用这个 Files API 了。

另外,我日常使用的 Pi Agent 也没有做这个优化。不过,在 AI 时代,做个优化也就是写几句 Prompt、写个插件的事情。

pi-files-api

最终,我快速 Vibe 出了一个插件 pi-files-api:通过修改 models.json 配置,它就能替换上下文里的图片 base64,上传到指定的 Files API Endpoint,然后用 file id 替代图片内容;插件内部维护了一份 sha256 到 file id 的映射。

当然,目前 AxonHub 还不支持代理 Files API,所以目前只能被迫在本地给 Pi 配置 DeepSeek 的 api key:先通过 api.deepseek.com 上传图片,再通过 axonhub 发送实际的请求体,非常不优雅。后续希望 AxonHub 能增加 Files API 支持,不过这也会带来一个问题:切换 API 上游时,Files 不会跟着迁移,换了一个供应商以后,原来的 file id 就失效了。这个问题还没想好怎么办,只能先曲线救国一下。

source
 
 
Back to Top