面经-agent
面经-agent
Agent 异步工具(长耗时后台任务)的设计与完成通知
1. 核心概念辨析:什么是 Agent 的“异步工具”?
很多人容易把“异步”混淆为代码层面的多任务并发,在 Agent 体系中必须严格区分两个层次:
- 微观层面(工具并发执行):大模型在一轮对话中同时触发了多个
tool_calls(如同时读取 3 个文件),Agent 运行时利用asyncio并发执行这 3 个工具。此时会话仍处于同一轮等待中,属于单轮会话内部的局部耗时优化。 - 宏观层面(会话级异步工具 / 后台长任务 Background Task):
- 核心考点:工具本身耗时极长(几分钟甚至几小时,如批量爬虫、视频生成、模型微调训练);
- 交互特征:工具调用后立刻脱钩返回任务凭据(
job_id),当前会话轮次结束,用户完全不用干等,可以继续向 Agent 提问聊其他话题;后台任务完成后,系统自动通过消息机制将结果送回上下文,隐式唤醒大模型向用户总结汇报。
2. 同步工具 vs 异步工具的判定原则与选型
| 核心维度 | 同步工具 (Sync Tool) | 异步工具 (Async Tool / Background Task) |
|---|---|---|
| 执行耗时 | 极短(毫秒级 ~ 2 秒以内) | 长且不可控(十几秒 ~ 几分钟 ~ 几小时) |
| 依赖关系 | 强依赖:大模型下一句话必须立刻看到该数据 | 弱依赖/解耦:大模型无需原地等待,可先向用户反馈已在后台排队办理 |
| 典型代表 | 1. 数学计算器 (calculator)2. 当前时间/天气查询 ( get_weather)3. 知识库 RAG 向量检索 ( vector_search)(必须拿到文本片段才能回答) |
1. 全网多源批量爬虫 (crawl_500_pages)2. AI 文生视频 / ComfyUI 工作流 ( generate_video)3. 代码沙箱模型训练 ( train_model)4. 海量数据报表导出与异步人工审批 |
3. 异步工具架构全流程设计(结合 my-pi-agent 源码实战)
在生产级 Agent 运行时中,异步工具的执行与通知由以下四大环节构成闭环:
环节 1:触发与即时脱钩(返回 Task Ticket)
- 当大模型决定调用异步工具时,工具函数绝不等待真实逻辑跑完;
- 在 100ms 内启动后台异步协程或子进程,并立即返回一个任务凭据(如
{"status": "running", "job_id": "bg_000001"}); - 大模型拿到
job_id后,立即向用户输出安抚确认话术(如“已在后台为您启动任务 bg_000001,您无需等待,可以继续向我提问”),当前轮次正常闭环结束,释放用户交互界面。
环节 2:后台任务状态机与孤儿进程防御
- 后台 Worker 维护持久化状态机:
PENDING➔RUNNING➔COMPLETED/FAILED/CANCELLED; - 支持进度查询(Progress)与取消令牌(Cancellation Token);
- 注册进程树清理机制(如
_kill_process_tree),防止任务被取消或进程退出时产生失控的孤儿进程。
环节 3:任务完成通知与事件入队
- 后台任务执行完毕后,自动组装标准结构化通知(如
<task_notification id="bg_000001">包含退出码与输出日志); - 核心动作:将通知投递至系统的动态干预队列(MessageQueue 的 Follow-up 追问队列),静默等待主循环调度。
环节 4:ReAct 主循环收割与隐式二次唤醒(Silent Re-triggering)
- 在 ReAct 微内核(
loop.py)的外层循环中设置探测点:1
2
3
4
5
6# loop.py 核心收割逻辑
if get_follow_up_messages is not None:
followups = get_follow_up_messages()
if followups:
pending_messages = _as_messages(followups)
continue # 🚨 核心:不退出循环,携带完成通知开启新一轮 ReAct! - 绝不直接向前端倾倒冰冷的原始 JSON,而是将
<task_notification>作为新上下文重新唤醒大模型,由大模型以自然语言组织总结并流式推给用户(如“顺便向您汇报,刚才在后台运行的任务已顺利完成,这是为您整理的数据分析…”)。
4. 进阶架构:基于 tmux 终端多路复用的长任务设计(Pi 官方设计哲学)
在 Coding Agent(如 Pi 原厂架构)中,传统通过普通子进程(subprocess)在后台运行命令存在三大死穴:
- 无伪终端 (No TTY):进度条
\r刷屏,日志缓冲严重,读出来全是 ANSI 转义乱码; - 无法交互输入:程序若中途弹出
[Y/n]或等待密码输入,后台进程当场永久死锁卡死; - 断线不可恢复:Agent 重启后无法找回之前的终端会话。
基于 tmux 的神仙解法(四大核心操作):
- 开辟独立静默会话:
tmux new-session -d -s task_001 "command",赋予子任务一个带有完整虚拟终端(PTY)的独立后台沙盒; - 无乱码终端截屏(核心杀手锏):调用
tmux capture-pane -pt task_001,tmux 内部的虚拟终端渲染引擎会把进度条和转义符消化掉,直接吐给大模型一张极其干净的终端纯文本屏幕快照; - 模拟键盘输入:若发现程序卡在等待确认,通过
tmux send-keys -t task_001 "yes" Enter模拟人工敲击键盘化解死锁; - 状态检测与收割:监控任务完成标记或退出码,提取完整日志并调用
tmux kill-session清理现场,最后将通知塞回MessageQueue驱动大模型向用户总结汇报。