
《Agent Runtime 工程化》第二章 TypeScript / Node Runtime 基础:2.7 动手任务
实现一个可取消的命令执行器: 支持 cwd; 支持 stdout/stderr 流式事件; 支持 timeout; 支持 AbortSignal; 支持最大输出限制; 返回 exit code、signal、duration; 中断后清理子进程。 用三个命令测试它:

实现一个可取消的命令执行器: 支持 cwd; 支持 stdout/stderr 流式事件; 支持 timeout; 支持 AbortSignal; 支持最大输出限制; 返回 exit code、signal、duration; 中断后清理子进程。 用三个命令测试它:

Agent 产品喜欢流式输出,主要是为了降低用户等待的不确定性,也让 runtime 更早看见模型意图。炫技排在很后面。 模型流可能先返回解释文字,再返回工具调用片段。工具执行也可能先输出日志,再最终退出。统一处理这些事件,最自然的接口是 async iterator: 事件流的好处是前端、CLI、

本阶段建议只实现三个工具。 listfiles:列目录。只读,但要限制在 workspace 内。 readfile:读文件。只读,但要限制大小和行数。 shellreadonly:执行只读 shell 命令。只允许白名单命令,例如 pwd、ls、find、rg、cat、sed、wc。不要在入门阶段

工具 schema 有两个读者。模型用它决定怎么调用工具,runtime 用它判断调用是否合法。 以 readfile 为例: 不要把 schema 发给模型后就放心。模型返回的参数必须再次校验。校验失败不该让程序崩溃,应当变成一条 observation: 这很关键。工具参数错了,并不总是任务失败

trace 很敏感。它可能包含用户代码、命令输出、环境变量、文件路径、API 响应、模型输入输出。生产系统中,trace 需要: secret 脱敏; 访问控制; 保留期限; 采样策略; 用户可删除机制; 外部导出审计。 不要为了调试方便,把所有 trace 原样传到第三方系统。可观测追求的不是越多

用户说'回滚'时,可能有三种意思: 回滚文件到某个 checkpoint; 回滚对话状态,让 Agent 忘记某段计划; 回滚外部副作用,例如撤销 API 操作。 Runtime 必须区分这三件事。文件 patch 可以回滚,对话状态可以恢复,外部副作用通常只能补偿,不能直接撤销。比如创建了 Git

工具结果、日志、文件片段进入模型上下文前,应经过 secret scanning。至少检查: API key; OAuth token; 私钥; .env; cloud credential; 数据库连接串; 内部域名和个人信息。 发现 secret 后,不要把原文注入模型。可以替换成 REDACT

回看全书,我们走过了这条线: 1. 理解 Runtime 比 LLM App 多承担什么; 2. 补齐 Node 异步、取消、进程管理; 3. 写出最小 Agent Loop; 4. 把工具系统治理起来; 5. 给上下文建立预算和调试报告; 6. 接入 MCP 和 Provider Adapter;

MCP 让工具接入变容易,也让工具信任问题变复杂。一个 Server 暴露的工具描述不应被 runtime 无条件信任。规范本身也提醒,工具描述等行为注解应被视为不可信,除非来自可信 Server。 因此,MCP 工具审批建议按 Server 信任级别分层: Server 类型 默认策略 官方可信、

工具失败不应只有 error: string。至少分为: 类型 例子 Runtime 行为 INVALIDARGUMENTS 参数缺字段、类型错 反馈模型重新调用 NOTFOUND 文件不存在 提示可选路径或要求搜索 PERMISSIONDENIED 用户拒绝或策略拒绝 停止或让模型寻找低风险方案

日志不是 trace。日志多半给开发者看,trace 应能还原运行路径。读项目时找: 每次模型调用是否记录; token usage 是否记录; tool call args 是否脱敏; tool result 是否保存; latency 是否可见; 错误是否分类; 用户确认是否入 log; 是否能

Agent 能根据用户请求读文件、总结、继续追问或停止。非法工具参数不会让程序崩溃;工具失败会变成模型可理解的 observation;超过最大步数会停止并给出原因。完成这一章,你已经有了 runtime 的胚胎。

状态包括聊天历史、任务状态、工具执行记录、文件变更、UI 状态、用户配置。读时问: 状态存在内存、文件、数据库,还是 git? 崩溃后能恢复到哪里? 工具执行是否有 ledger? 用户审批是否持久化? 文件变更是否可回滚? 长任务是否可以暂停和继续? 这部分最能区分 demo 和系统。

一次线上失败,如果不能转化为 eval,它就会再次发生。建议流程: 1. 从 trace 中提取用户目标、关键上下文、工具调用和失败结果; 2. 去除 secret 和用户隐私; 3. 固化 workspace fixture; 4. 写 expected behavior; 5. 加入 CI; 6

run 生命周期通常包括: 初始化 session; 构建上下文; 调用模型; 解析响应; 执行工具; 写状态; 输出 UI event; 进入下一步或停止。 你要找的不是某个函数名,而是状态怎样流动。很多项目不会把它叫 runAgent,可能叫 task、controller、orchestrat

模型 span: provider; model; prompt tokens; completion tokens; latency; finish reason; tool call 数量; 是否触发上下文降级; response id 或 continuation metadata。 工具 s

Agent:根据目标和上下文选择下一步行动的执行体。 Agent Runtime:负责模型调用、工具调用、上下文、权限、状态、观测、恢复、评测和成本治理的运行系统。 Tool Calling:模型输出结构化工具调用,应用执行工具并把结果返回模型的接口能力。 Tool Registry:工具定义、sc

用 MCP TypeScript SDK 写一个本地 MCP Server,提供两个工具: readprojectfile; searchprojecttext。 然后让 miniagent: 启动时发现 MCP 工具; 将 MCP 工具映射到本地 Tool Registry; 为 MCP 工具加风

上下文构建往往是 coding agent 的核心竞争力。读时关注: system/developer 指令; 用户消息和历史保留; 文件读取策略; repo map; 最近修改; terminal output; diagnostics; selection/range; embedding 或检

读开源 Agent 项目,别一上来就钻进细节。本章给一套追主线的方法。 读开源 Agent 项目,最怕两种读法。一种是从 README 兴奋到插件列表,最后只记住产品功能;另一种是一头扎进代码细节,三天后迷失在 UI、配置和历史兼容里。Runtime 工程师读源码,要带着问题读,尤其要追执行链路。