Skip to content

feat: 实现 Agent 三层事件生命周期 #13

Description

@lora-sys

Problem Statement

NanoAgent 目前缺乏细粒度的 agent 执行生命周期追踪。只有 session 级别的 start_session/end_session,没有 turn、message、tool 三层的显式事件。这导致:

  • 流式输出的中间状态无法追踪
  • 外部系统(UI、日志、调试工具)无法感知 agent 执行进度
  • observability 的记录分散在 llm/client.pytools/registry.py 中,耦合在调用路径里

Solution

引入 Lifecycle 类作为 NanoAgent.run() 的局部实例,管理严格嵌套的三层事件:

agent_start
  └─ turn_start (循环 N 次)
       ├─ message_start → message_update* → message_end
       ├─ tool_execution_start → tool_execution_update* → tool_execution_end (循环 N 次)
       └─ turn_end
  └─ agent_end

事件通过 emit(type, data) 同步分发,外部通过 subscribe(handler) 注册回调。

Commits

  1. 定义 LifecycleEvent 类型枚举和 dataclass — 新建 core/lifecycle.py,定义所有事件类型 (AgentEvent union) 和 TurnContext dataclass,不含任何 agent 逻辑

  2. 实现 Lifecycle 类骨架Lifecycle.subscribe(), emit(), flush() 方法,_handlers 列表存储回调,不含事件发射逻辑

  3. 集成 Lifecycle 到 NanoAgent.run() 主循环 — 在 run() 中创建 lifecycle = Lifecycle(),添加 agent_start/agent_end 事件包裹,不改现有逻辑

  4. 添加 turn 边界事件 — 在传统模式的 while True 循环中添加 turn_start/turn_end 包裹

  5. 添加 message 事件 — 在 llm.chat() 调用前后添加 message_start/message_end 包裹

  6. 添加 tool 事件 — 在 _execute_tool_invocations 中对每个工具调用添加 tool_execution_start/tool_execution_end

  7. 实现流式 update 事件 — 在 stream_chat 的 callback 中 emit message_update,在工具执行中间 emit tool_execution_update

  8. 集成 Tracer 为内置 subscriber — 将 Tracer 改为 lifecycle subscriber,record_llm/record_tool 内部改为 lifecycle.emit(),消除调用路径耦合

  9. 添加 Lifecycle 单元测试 — 测试事件嵌套合法性、handler 注册/注销、流式 update 顺序

Decision Document

  • 发布机制: Lifecycle.emit(type, data) 同步分发,handler 抛出则中断
  • 生命周期: Lifecycle 作为 NanoAgent.run() 的局部实例,每次 run 独立
  • 嵌套保证: 通过 _depth 计数器验证 agent > turn > message/tool 严格嵌套
  • Streaming: message_update / tool_execution_update 支持流式中间状态
  • 兼容: 保留 Tracer 单例 API,内部改为事件触发,不破坏现有调用方
  • 持久化: Tracer 作为 subscriber 接收所有事件,写入 SQLite
  • 模块位置: core/lifecycle.py — 新文件,不修改现有文件结构

Testing Decisions

  • 单元测试: Lifecycle 的嵌套合法性(深度验证)、handler 注册/注销、事件分发顺序
  • 集成测试: 在 mock 模式下跑 agent.run(),验证事件顺序正确
  • Prior art: 参考现有 tests/agent/ 测试框架风格

Out of Scope

  • chat() 交互模式的生命周期(仅 run() 方法)
  • 异步版本的 agent
  • 事件持久化 schema 变更
  • LLM router/chain 模式的细粒度事件

Further Notes

参考 Anthropic SDK 的事件生命周期设计(agent > turn > message/tool 三层嵌套)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions