Skip to main content
用 Kimi API 做 PDF 问答,流程只有两步:先通过文件接口上传文件并提取文本,再把提取出的文本放入 messages。反复查询同一份文档时,只要文档前缀保持稳定,API 提供的 Context Caching 功能可以帮助节省成本。 本文将一步步演示:
  • 上传与读取:用 file-extract 两步拿到模型可读的文本;
  • 提问:把文件内容作为 system 消息放入 messages;
  • 多轮对话:固定前缀不动,问答记录追加在 messages 末尾;
  • 多文件问答:每个文件一条 system 消息,统一放在 messages 头部;
  • 约束输出:追加一段固定的作答规则,约束格式、篇幅等输出形态;
  • 控制成本:复用稳定的文档前缀,让 Context Caching 自动生效;
  • 清理已上传的文件:提取结果本地留存,定期删除云端文件。

1. 准备工作

Kimi API 兼容 OpenAI SDK,直接安装 openai 库即可:
创建客户端时,把 base_url 指向 Kimi API 的地址,API Key 从环境变量读取:
本文示例使用 kimi-k3 模型。换用 kimi-k2.6、kimi-k2.5 等其他模型时只需替换 model 字段,但各模型的参数配置存在差异,详见模型参数参考 示例材料是 Kimi K3 技术报告的 PDF,来自 MoonshotAI 官方 GitHub 仓库,通过下方代码下载(你也可以换成任何自己的 PDF,文件接口支持 .pdf、.txt、.csv、.doc、.docx 等格式,单文件不超过 100MB):

2. 上传文件

通过文件上传接口把 PDF 传到 Kimi 服务器,purpose 设为 file-extract,表示这份文件用于提取文本内容。文件上传接口还支持 image、video 等 purpose 值,用于模型的原生理解:

3. 读取提取结果

上传之后,通过文件抽取接口拿回提取后的文本,它已经对齐成官方推荐的、模型易于理解的格式:
如果这份文档要反复提问,建议把提取结果存到本地,下次问答直接读本地文件复用,不必重新上传和提取:
两个常见错误
  1. 不要把 file_id 放进 messages。 file_id 只是文件的句柄,模型看不到任何内容。必须先读取提取结果,再把文本放进 messages。
  2. 不要用 base64 编码 PDF 内联进 messages。 使用 base64 编码文件会导致产生巨量的 Tokens 消耗;如果文件类型是 /v1/files 文件接口支持的格式,使用文件接口上传并抽取文件内容即可。

4. 提问

把提取出的文件内容作为一条 system 消息放进 messages,然后在 user 消息里提问:
注:本文所有输出均为真实运行示例,模型输出有随机性,你的实际结果可能略有差异。

5. 多轮对话

追问只需要把问答记录追加在 messages 末尾,文件内容和指令保持在最前面不动。这个”固定内容在前、对话追加在后”的结构不只是写法习惯,它决定了后文的缓存能否命中:

6. 多文件问答

针对多份文件提问,实现方式很直接:每个文件单独放在一条 system 消息里,并把这些消息放在 messages 列表的头部:

7. 约束模型的作答

第 4 节的 system 消息是身份设定,告诉模型「你是谁」;实际使用中还经常需要追加一条 作答规则,告诉模型「回答要长什么样」——格式、篇幅、风格,都可以用一段固定的指令约束下来。这条规则和身份设定、文件内容一样属于稳定前缀,不影响下一节 Context Caching 的命中:
同一个问题,带着这条规则和不带规则各跑一次:不加规则时模型自由发挥,输出是一篇带小标题的长文;加上规则后,输出被收进规则限定的形态,分点概括、每点附原文出处、篇幅大幅收紧:

8. 控制成本:Context Caching

文件问答的计费有一个结构性特点:文档内容作为固定前缀出现在每一次请求里,同一份文档问得越多,这部分前缀被重复计费的次数就越多。Context Caching 就是消除这部分重复成本的机制。Kimi API 对所有请求自动启用,当检测到重复的初始上下文(system prompt、文件内容、工具定义等)时,直接复用已缓存的前缀,按缓存命中计费,而不是每次全价重算。 不需要任何额外代码。无需手动创建缓存,无需引用缓存 ID,也无需管理 TTL,只要像平常一样调用 /v1/chat/completions 即可。你要做的只有一件事:让文件内容、system prompt、工具定义这些固定部分保持稳定,并放在 messages 数组的最前面。 官方文档里的两个细节:
  • 前一个请求的 prompt tokens 大于 256 时,后续请求才能命中前缀缓存;小于 256 的请求不会被缓存。文件问答天然满足这个条件。
  • 收益方面,官方给出的参考是:特定场景下成本最高可降 90%,长文本场景首 Token 延迟平均可降至 5 秒内。具体计费方式以产品定价页为准。
我们可以再发一次与第 7 节完全相同的请求,从 usage 里看缓存命中情况:
和 RAG 方案对比,官方的建议是:频繁查询固定内容(如 FAQ、文档问答)优先使用 Context Caching;内容极长且查询方向不固定时,可以考虑 RAG 方案。两者的对比如下:

9. 清理已上传的文件

文件接口对单用户的上传数量有限制(每个用户最多 1000 个文件、所有已上传文件总和不超过 10G),提取完成后可以删除已上传的文件释放空间。如需定期全量清理,可以用 files.list 列出所有文件后逐一通过 files.delete 删除:

10. 常见问题(FAQ)

文件提取可能失败:格式不支持、文件损坏、超过 100MB 上限等。接口不支持的格式模型无法解析,请不要放入上下文。建议把上传和提取包一层防御性处理:
输出示例
借助 kimi-k3 的 1M 上下文,大多数单份文档都可以整份放入。如果文档实在过长,可以按文档自身的结构(章节、标题)切分成几段,每段作为一条 system 消息放入。如果你的场景是”海量文档、查询方向不固定”,比如在整个知识库里随意提问,那已经超出了单篇问答的适用范围,建议参考第 8 节给出的 Context Caching 与 RAG 的选择建议。

参考文档:使用 Kimi API 进行文件问答文件上传接口(API 参考)使用 Kimi API 的 Context Caching 功能