跳到文章正文
Grok 实用教程

Grok长请求怎么异步取结果?Deferred Chat Completions轮询与保存

通过deferred提交文本任务并保存request_id,区分202与200响应;使用单一消费…

Grok API:X搜索、文件与引用核对教程
Grok API:X搜索、文件与引用核对教程

服务端文本生成时间较长,不希望网页一直等着连接,可以用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