工具系统与 SSE 事件流

笔记/AI编程/Agent Harness工程/工具系统与 SSE 事件流

背景与动机#

Agent 能完成任务,靠的不是模型单独生成文本,而是模型能选择工具、调用工具、读取结果,再决定下一步。工具系统和事件流,就是这个过程的工程骨架。

SSE 这类事件流适合把执行过程持续推给前端或日志系统,让用户看到 Agent 当前状态。

img
img

工具调用的基本结构#

一个工具至少要定义:

  • 名称。
  • 描述。
  • 输入 schema。
  • 输出结构。
  • 错误格式。
  • 权限边界。

示例:

{
"name": "read_file",
"description": "Read a UTF-8 text file from the workspace",
"input": {
"path": "src/content/notes/example.md"
},
"output": {
"content": "..."
}
}

描述要具体。工具描述越模糊,模型越容易在错误场景调用。

事件流应该记录什么#

常见事件:

session.created
message.received
model.output.delta
tool.call.started
tool.call.completed
tool.call.failed
session.completed

事件的价值是让外部系统知道:

  • Agent 是否还在工作。
  • 当前调用了什么工具。
  • 工具是否失败。
  • 失败后是否重试。
  • 最终结果从哪里来。

状态反馈要用户可理解#

不要只输出底层事件名。面向用户可以转换成:

正在读取项目规则...
正在搜索相关文件...
正在运行测试...
测试失败,正在根据错误调整...
任务完成。

这样用户能判断是否需要打断或纠偏。

失败恢复#

工具失败不应该直接结束任务。可以按错误类型处理:

  • 文件不存在:重新搜索路径。
  • 权限不足:请求确认或切换只读方案。
  • 命令失败:读取错误输出并定位原因。
  • 网络失败:重试或降级。

重要的是把失败作为可观察事件记录下来,而不是吞掉。

常见陷阱#

  • 工具输入没有 schema,模型只能猜参数。
  • 工具错误只返回“failed”,缺少可操作信息。
  • 事件流只展示最终结果,无法调试中间过程。
  • 工具权限过大,所有操作都通过一个通用 shell 完成。

工具设计检查表#

名称是否表达具体动作?
描述是否说明适用场景和限制?
参数是否有明确 schema?
输出是否能被模型继续使用?
错误信息是否可操作?
是否区分只读和写入?
是否会把外部提示注入带回系统上下文?

一句话总结#

工具系统决定 Agent 能做什么,事件流决定人和系统能否看清它正在怎么做。

文章目录

文章目录