内容提要
作者发现 DeepSeek 读图时图片每次请求重复上传,导致首字延迟随图片增多而膨胀,甚至达几分钟。由于 DeepSeek 未实现有状态 Responses API,作者改用 Files API:先上传图片获取 file id,再在请求体中引用,并开发了 pi-files-api 插件,替换上下文中的图片 base64 并维护 sha256 映射。但 AxonHub 尚不支持代理 Files API,只能本地配置 DeepSeek key,且切换上游后 file id 会失效。
延伸解读
为什么图片会拖慢首字延迟
文章指出,DeepSeek 读图时每次请求都要重新上传完整上下文中的图片,随着图片累积,上传耗时逐渐成为 TTFT 的主要瓶颈,延迟从 10 秒、12 秒一路涨到几分钟。这说明问题不在服务端算力,而在重复传输。对经常用图片做长上下文对话的用户,图片数量越多,这种膨胀越明显,值得优先排查。
Files API 的解决思路与前提
Files API 相当于临时网盘,图片先上传获得唯一 file id,之后在请求体里用 id 代替图片内容,避免重复上传。但文章强调,DeepSeek Harness 支持该能力的前提是使用第一方 API;若通过 AxonHub 统一管理 key,就不会走 Files API。因此,这一优化并非所有接入方式都能直接受益。
pi-files-api 插件做了什么
作者为 Pi Agent 开发了 pi-files-api 插件:从 models.json 读取配置,把上下文里的图片 base64 替换掉,上传到指定 Files API Endpoint,再用 file id 替代图片内容,并在内部维护 sha256 到 file id 的映射。这相当于在 Agent 层补上了缺失的优化,思路可迁移到其他支持插件机制的客户端。
当前限制与迁移风险
文章提到,AxonHub 尚不支持代理 Files API,作者只能本地配置 DeepSeek key,先直连上传图片,再经 AxonHub 发请求,流程并不优雅。更关键的是,切换 API 上游后 file id 会失效,因为文件不会随供应商迁移。这意味着该方案对多上游切换场景仍有明显约束,作者也尚未想好应对办法。
Q&A
为什么用 DeepSeek 读图时 TTFT 会越来越高?
因为每次请求都要发送完整上下文,图片在每次请求时都会被重新上传到后端。随着上下文里图片越来越多,上传图片所花的时间逐渐成为 TTFT 的主要瓶颈,导致首字延迟从 10 秒、12 秒一路上涨,有时甚至达到几分钟。
Files API 是什么?它如何解决图片重复上传的问题?
Files API 可以理解为一个临时的网盘,支持上传、列举、删除和查询文件,有 OpenAI 和 Anthropic 两个版本。每个文件有唯一 id,可以出现在 chat completions/responses/anthropic messages 请求体中代替实际图片。先上传图片获取 file id,再在请求体中用 id 引用,就能避免每次请求重复上传图片,从而解决 TTFT 暴增的问题。
pi-files-api 插件是怎么工作的?
pi-files-api 插件从 models.json 读取配置,替换上下文里的图片 base64,将图片上传到指定的 Files API Endpoint,然后用 file id 替代图片内容;插件内部还维护了一份 sha256 到 file id 的映射。
为什么作者不直接用 OpenAI Responses API 来避免图片重复上传?
因为 DeepSeek 目前还没有实现有状态的 OpenAI Responses API。该 API 每次只发送相对上一次请求的增量,可以避免图片重复上传,但 DeepSeek 不支持,所以作者只能用 Files API。
通过 AxonHub 使用 DeepSeek 时,Files API 会遇到什么问题?
AxonHub 尚不支持代理 Files API,所以作者只能被迫在本地给 Pi 配置 DeepSeek 的 API key:先通过 api.deepseek.com 上传图片,再通过 AxonHub 发送实际的请求体,非常不优雅。
切换 API 上游后,之前上传的 file id 还能用吗?
不能。切换 API 上游时,Files 不会跟着迁移,换了一个供应商以后,原来的 file id 就失效了。作者目前还没想好解决办法,只能先曲线救国。