Skip to content

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

@lora-sys

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions