Kimi Batch API 批处理教程:不急的任务打包跑,账单直接打六折(2026最新)

前几天写过一篇上下文缓存,讲的是实时对话怎么省输入的钱。这次说个更直接的开关:Kimi 的 Batch API。官方文档原话:相比实时 API 调用,可以节省 40% 的推理费用。40% 是什么概念,我之前在API 计费那篇里算过账,等于同样的活,账单直接打六折。

代价是你得等。Batch API 的玩法是把一批请求打包成一个文件传上去,服务器挑空闲算力异步跑,跑完给你一个结果文件。什么时候该用它?我的判断标准就一条:这个任务 12 小时后出结果也不耽误事,就该走这条路。

我自己会用的场景:

  • 几千条客服对话做分类、打情绪标签
  • 商品评论批量生成摘要
  • 资料库整库翻译、润色
  • 给自己的评测集跑基线分数

挂在用户请求路径上的活别用,用户等不起。还有一类是管理层明天就要看结果的报表,也别赌异步,老老实实走实时接口。

先说限制,免得白忙

我读文档的习惯是先翻限制,这里直接给你:

  • 模型只有两个:kimi-k2.7-code 和 kimi-k2.6。旗舰 K3 暂不支持
  • 参数锁死:temperature、top_p、n、presence_penalty、frequency_penalty 都不能写进请求,文档专门加粗提醒了这一条
  • 文件必须是 .jsonl,不能为空,最大 100MB,一个组织最多存 1000 个 batch 文件
  • 同一批次的所有请求必须用同一个模型

前两条最容易踩。平时习惯在 body 里写 temperature 的(比如我),打包前记得删干净。

四步跑通全流程

下面的流程假设你已经有一个能用的 API Key。还没开通过 Kimi API 的,先看这篇Kimi API 上手教程,把注册和充值搞定再回来。

第一步:把请求写成 JSONL 文件

JSONL 就是每行一个独立的 JSON。一行对应一次完整的对话请求,四个必填字段:

  • custom_id:自己起的编号,用来对账,文件内不能重复
  • method:固定写 POST
  • url:固定写 /v1/chat/completions
  • body:和普通 Chat Completions 请求体一样
{"custom_id": "request-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "kimi-k2.6", "messages": [{"role": "system", "content": "你是一个文本分类助手"}, {"role": "user", "content": "请分类这段文本:人工智能正在改变世界"}]}}

一千条任务就是把这样的行生成一千行。用 Python 拼字符串循环写文件,几分钟的事。custom_id 建议起有意义的名字,比如日期加序号,后面拿结果对账能省不少劲。

第二步:上传文件

走文件接口,purpose 必须设成 batch:

curl https://api.moonshot.cn/v1/files \
  -H "Authorization: Bearer $MOONSHOT_API_KEY" \
  -F purpose="batch" \
  -F file="@batch_requests.jsonl"

返回结果里拿 file_id,下一步要用。

第三步:创建批处理任务

curl https://api.moonshot.cn/v1/batches \
  -H "Authorization: Bearer $MOONSHOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input_file_id": "你的file_id",
    "endpoint": "/v1/chat/completions",
    "completion_window": "24h"
  }'

completion_window 是完成期限,支持 12h、1d、3d 这种语义化写法,最小 12 小时,最大 7 天。文档建议数据量大就把窗口放宽,完成率会更高。

第四步:轮询状态,下载结果

任务一共 8 个状态:validating(校验中)、failed(校验失败)、in_progress(执行中)、finalizing(准备结果)、completed(完成)、expired(超时未完成)、cancelling(取消中)、cancelled(已取消)。

正常路径是 validating 到 in_progress,再到 finalizing 和 completed。轮询 GET /v1/batches/{batch_id} 就行,返回里的 request_counts 能看到进度,比如 300/1000。

跑完后 response 里有 output_file_id,下载它:

curl https://api.moonshot.cn/v1/files/{output_file_id}/content \
  -H "Authorization: Bearer $MOONSHOT_API_KEY" \
  -o results.jsonl

结果文件也是 JSONL,每行对应一个请求,custom_id 原样带回来了。取回答案就一层一层往下点:

result["response"]["body"]["choices"][0]["message"]["content"]

usage 字段照常给,每条请求花了多少 token,清清楚楚。看到 expired 别懵,那意思是没在 completion_window 里跑完,任务直接终止,把窗口调大重新提一次就行。

图片和视频也能塞进批次

批次里不只能发文本。图片有两种给法:小图直接 base64 编码塞进 JSONL,文档提醒 base64 会让体积膨胀约 33%,100MB 的上限要算在内;大图或者一张图要用很多次的,先走文件接口上传(purpose 设成 image),然后在 JSONL 里用 ms:// 加 file_id 的方式引用。视频同理,purpose 换成 video。

kimi-k2.6 本身支持图片和视频理解,所以批量给图片打标签、批量从视频里提取信息这类活,也能走 batch。做素材库整理的应该用得上。

跑挂了怎么办:失败、取消和重跑

异步任务最常见的两个坑,提前说。

第一是校验失败。任务卡在 validating 然后变成 failed,说明文件本身有问题,常见的就几种:某行 JSON 没写对、custom_id 重复了、一个文件里混了两个模型、body 里带了被锁死的参数。文件越大越容易混进一行坏数据,我现在的做法是生成之后先逐行过一遍再上传,本地校验比等到服务器报错省事。

第二是单条请求失败。整个任务 completed,不代表每条都成功,失败的会单独写进 error_file_id。靠 custom_id 把失败行挑出来,重新组一个小文件再补一轮就行。如果失败比例高,先停下来检查请求格式,别拿六折的价格硬刷错误。

另外两个管理接口顺带记一下:GET /v1/batches 能列出组织下所有任务;发现跑错了,对任务发取消请求,它会经过 cancelling 最后停在 cancelled,已经花掉的钱不退。

参数锁死这条,换个角度想也有好处:整批请求同一个模型、同一套固定参数,输出行为完全一致。拿它做评测基线,比实时接口少一个变量。

和上下文缓存怎么选

之前那篇上下文缓存,解决的是同一段长前缀反复用的问题,对话照常实时。Batch API 解决的是任务又多又不急,拿时间换六折。

两个不冲突。离线批量跑历史数据用 batch,在线服务挂缓存。我自己的顺序是:先把不急的任务全塞进 batch,剩下的实时请求再琢磨缓存。碰到报错分不清是自己的问题还是平台的问题,可以翻那篇API 报错排查。

最后给个实在建议:别上来就跑一万条。先拿 10 条数据全流程走一遍,确认参数没带错、结果格式对得上,再放大文件。异步任务的错误要等一轮才暴露,而窗口最小 12 小时,这个试错成本不值。

你手上有什么适合批处理的活?评论区聊聊。

发表评论