多Agent串行编排,每段的超时预算怎么分
一句话结论多个 Agent 接力干一件事别给每个 Agent 单独拍一个固定超时要给整条链路设一个总的 deadline剩多少时间往下传谁也别超。我没这么干之前一条三段的链路理论上能等到 30 秒还不返回用户早跑了。问题长啥样我有条调研链路检索 Agent → 分析 Agent → 汇总 Agent串行跑。一开始我图省事每段都写死timeout10s。看着挺合理真出问题才发现检索那段网络抖了一下用掉 9 秒分析又满满当当跑了 10 秒到汇总用户已经等了快 20 秒前端那边 15 秒早就超时断开了。三段各自都没超时合一块儿就崩了。毛病在于单段超时只管自己没人管全局还剩多少时间。正确姿势传 deadline不传 timeout把还能跑多久做成一个随链路往下传的 deadline。每个 Agent 进来先看离总截止还剩多少拿这个剩余时间当自己的超时上限绝不许超。import time, asyncio TOTAL_BUDGET 12.0 # 整条链路总预算秒比前端超时留点余量 async def run_pipeline(query): deadline time.monotonic() TOTAL_BUDGET ctx await run_stage(retrieve_agent, query, deadline) ctx await run_stage(analyze_agent, ctx, deadline) return await run_stage(summarize_agent, ctx, deadline) async def run_stage(agent, payload, deadline): remaining deadline - time.monotonic() if remaining 0.5: # 剩的时间不够干活了直接降级 return fallback(agent, payload) try: # 这一段最多只能用掉还剩的时间 return await asyncio.wait_for(agent(payload), timeoutremaining) except asyncio.TimeoutError: return fallback(agent, payload) # 超了就走兜底别拖死后面我后来补的几个细节总预算要比上游超时留余量。前端如果是 15 秒断我总预算给 12 秒留 3 秒给网络和序列化这些杂活不然你卡点返回的那一下还是会被上游判超时。越靠前的 Agent越要懂得见好就收。检索那段我加了限制召回够用就别贪多把时间留给后面分析和汇总。不然前面把预算吃光后面只能降级得不偿失。降级要分得清没数据和超时了。汇总 Agent 拿到的若是上一段降级的半成品得在结果里标个partialtrue前端好提示部分结果别假装一切正常。一个我纠结过的取舍按比例预分配比如 4s/4s/4s还是动态剩余我试过预分配简单但僵——检索快了用不完那 4 秒也匀不给后面。动态剩余上面这种灵活但有个隐患如果前段普遍偏慢后段会被频繁压到降级。我最后的折中是动态剩余 给关键的汇总段留一个保底时间比如至少留 2 秒别让它永远在降级。说点不好的deadline 这套对纯串行很顺一旦链路里有并行分支或者循环节点预算怎么分就开始烧脑了——并行的几支是按最长那支算还是各自算得case by case。还有time.monotonic()这种墙钟时间在跨进程、跨机器的 Agent 调用里传递得自己序列化好别传了个本地时间戳到另一台机器上时钟一偏就全乱。模型推理我直接用讯飞星辰MaaS 的现成 API各段 Agent 的模型调用延迟相对稳省了我自己维护算力、还得估单机延迟的麻烦预算才好估。你们多 Agent 链路是怎么控总超时的固定分配还是 deadline 传递评论区交流下。