Grok长请求怎么异步取结果?Deferred Chat Completions轮询与保存
通过deferred提交文本任务并保存request_id,区分202与200响应;使用单一消费…
文章目录

服务端文本生成时间较长,不希望网页一直等着连接,可以用Grok的Deferred Chat Completions:先提交拿到request_id,再稍后查询。它是开发者API能力,目前通过REST或xAI SDK使用,不是普通聊天界面里的下载按钮。本文用简单算术作为低复杂度示例,重点讲结果领取与保存,不实际调用付费接口。
第一步:确认接口与保留限制
使用有相应模型权限的API账号,在服务端读取XAI_API_KEY,不把密钥放浏览器代码。Deferred请求与Chat Completions使用相同速率限制,不能靠异步绕过额度。官方说明结果在24小时内只能领取一次,之后丢弃,因此应用要有可靠的领取者和本地保存机制。
开启团队Zero Data Retention时不支持Deferred,因为结果需要暂存服务端。先核对组织数据策略,不为了运行一个示例自行关闭团队设置。普通聊天会员和第三方平台套餐也不代表包含这项官方API权限。
第二步:提交一次并记录request_id
POST https://api.x.ai/v1/chat/completions
Authorization: Bearer <服务端环境中的密钥>
Content-Type: application/json
{"model":"grok-4.7","messages":[{"role":"user","content":"只回答126除以3的数值。"}],"deferred":true}
检查HTTP状态与返回JSON后,将request_id、业务任务编号和提交时间持久化。不要只把ID打印到即将关闭的终端里。这个POST是创建任务,网络中断但不确定服务器是否接收时,不能盲目连续重发,否则可能产生多个任务和费用。示例模型需按账号实际可用范围选择。
第三步:由单一消费者查询结果
查询地址是/v1/chat/deferred-completion/{request_id}。202 Accepted的响应体为空,表示未准备好,不应立即调用json();200时是常规Chat Completion结构。其他状态需要按错误处理,不能把认证失败或无效ID当成仍在生成而无限重试。
import os, time, pathlib, requests
def collect(request_id, output_path):
target = pathlib.Path(output_path)
with target.open("xb") as out:
deadline = time.monotonic() + 600
while time.monotonic() < deadline:
r = requests.get(
"https://api.x.ai/v1/chat/deferred-completion/" + request_id,
headers={"Authorization": "Bearer " + os.environ["XAI_API_KEY"]},
timeout=30,
)
if r.status_code == 202:
time.sleep(5)
continue
r.raise_for_status()
if r.status_code != 200:
raise RuntimeError("Unexpected completion status")
out.write(r.content)
out.flush()
os.fsync(out.fileno())
return r.json()
raise TimeoutError("Pending: retain request_id for later collection")
这是领取函数示例,调用前传入已保存ID和新的专用输出路径。xb避免覆盖旧结果,也能阻止同一路径的重复领取;10分钟只是本地等待上限,不是官方生成时限。空文件不能当成功标记,超时应记录待处理状态,之后由同一个领取流程按保留期恢复。
第四步:先落盘,再给其他任务使用
示例在200后先写原始响应并刷新到磁盘,再解析JSON。生产环境更适合用持久队列、任务锁与可靠存储,让同一request_id只被一个工作进程领取;其他页面从自己的数据库读结果,不再去官方接口重复领取。不要多个浏览器标签或定时器同时轮询同一个ID。
只可领取一次意味着即便本地写盘失败,远端结果也可能已经消费,示例无法提供跨网络和磁盘的原子保证。应提前确认保存目录可写、空间充足,并记录“已领取但保存失败”的状态,而不是遇错就重新GET。对关键任务需把这类失败纳入补偿流程。
第五步:核对内容并区分任务状态
成功后检查choices中的message.content是否符合输入,本例预期数值42,再检查finish_reason与usage。200只表示拿到响应,不保证回答一定满足任务;拒绝、截断或内容错误需作为业务结果处理。不要把创建返回的request_id误当最终正文。
保留提交、待处理、已领取、保存成功和失败等状态,重启后先查本地记录。本文只提供协议与代码示例,未发送API请求;可先用模拟202、200及错误响应验证状态机。验收标准是没有重复创建或多次领取,正文已可靠保存,且结果与任务要求核对一致。
若本地等待到期,保留原任务ID与提交时间并设定后续领取安排,不能把超时直接标成模型失败。模拟验证时还应加入重复启动领取者、输出路径已存在和磁盘写入失败,确保错误状态不会被误判为已完成。
官方资料
资料核对日期:2026年11月6日。
本文地址:https://www.163264.com/19481
