
书名:《Agent Runtime 工程化:从工具调用循环到可恢复执行系统》
作者:陈堂会
章节:第二章 TypeScript / Node Runtime 基础 / 2.1 Promise 不是全部
电子版系列:查看完整目录
第二章 TypeScript / Node Runtime 基础:2.1 Promise 不是全部
很多人学会 async/await 后,会误以为异步编程已经结束。对普通 Web API 来说,这通常够用;对 Agent Runtime 来说,不够。
Runtime 面对的不是一次请求一次响应,而是长时间过程:
- 模型流式吐出 token 和 tool call delta;
- shell 命令持续输出 stdout/stderr;
- 用户可能在工具运行中取消;
- 多个只读工具可以并行;
- 写入工具必须串行或受事务保护;
- 某个 step 超时后需要清理资源;
- 任务恢复后不能重复执行已完成的副作用。
所以你需要掌握的不只是 await model.call(),而是异步迭代、取消传播、背压、进程生命周期和资源清理。
图 2-1:异步任务生命周期。取消、超时、流式输出和资源清理不是 UI 细节,它们要贯穿模型请求、工具执行、子进程和 trace。
可以把一次工具执行看成一条小流水线:
- Runtime 创建
AbortController,绑定用户取消和 timeout; - 执行器启动模型请求或子进程;
- 输出被拆成事件,而不是堆成一个巨大字符串;
- 事件一边发给 UI,一边写 trace,一边按策略摘要给下一轮模型;
- 任一环节失败时,先清理资源,再决定是否重试。
很多'Agent 卡住了'的问题,其实不是模型卡住,而是这条流水线某处没有关闭。比如子进程 stdout 没有人消费,缓冲区满了;比如 UI 已经取消,执行器没收到 signal;比如 timeout 只 reject 了 Promise,没有杀掉进程。第二章要练的正是这些脏活。

