Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

附录 B:关键执行流程图

本附录收录 6 个关键流程的 Mermaid 图,覆盖从单次对话到系统级防御的核心路径。每个图标注了对应的源码文件和章节引用。

B.1 单次对话流程

对应章节:第 3 章(请求旅程)、第 4 章(AIAgent 内核)

sequenceDiagram
    participant U as 用户
    participant E as 入口层<br/>(CLI / Gateway)
    participant A as AIAgent<br/>(run_agent.py)
    participant L as LLM API
    participant T as 工具系统<br/>(model_tools.py)
    participant S as SessionDB<br/>(hermes_state.py)

    U->>E: 发送消息
    E->>A: run_conversation(user_message)
    A->>A: _build_system_prompt()<br/>(identity + memory + skills + context)
    A->>S: 加载会话历史
    A->>A: 检查 IterationBudget

    loop 工具调用循环
        A->>L: API 调用(messages + tools schema)
        L-->>A: 流式响应(text + tool_calls)
        A-->>E: stream_delta_callback(token)

        alt 模型返回 tool_call
            A->>A: budget.consume()
            A->>T: handle_function_call(name, args)
            T->>T: registry.get(name) → handler
            T-->>A: 工具执行结果
            A->>A: 追加 tool_result 到 messages
            Note over A: 检查 budget 压力<br/>70% → caution<br/>90% → warning
        else 模型返回纯文本
            Note over A: 退出循环
        end
    end

    A->>S: 保存会话(messages + metadata)
    A->>A: 检查 nudge 计数器<br/>(memory / skill)
    opt nudge 触发
        A->>A: _spawn_background_review()<br/>(后台线程)
    end
    A-->>E: 返回最终响应
    E-->>U: 显示响应

B.2 工具发现与调度

对应章节:第 6 章(工具系统)、第 7 章(工具剖面)

graph TB
    subgraph "启动时:工具发现"
        A["model_tools._discover_tools()"] --> B["导入 tools/*.py 模块"]
        B --> C["每个模块执行 registry.register()"]
        C --> D["ToolRegistry 单例<br/>存储 ToolEntry 列表"]
    end

    subgraph "初始化时:工具过滤"
        D --> E["get_tool_definitions()"]
        E --> F{"enabled_toolsets /<br/>disabled_toolsets"}
        F -->|匹配| G["生成 tool schema<br/>(JSON Schema 格式)"]
        F -->|排除| H["跳过"]
        G --> I["AIAgent.tools 列表"]
    end

    subgraph "运行时:工具调度"
        I --> J["LLM 返回 tool_call"]
        J --> K{"name 在<br/>valid_tool_names 中?"}
        K -->|是| L["handle_function_call()"]
        K -->|否| M["返回错误提示"]
        L --> N{"entry.is_async?"}
        N -->|是| O["_run_async()<br/>async→sync 桥接"]
        N -->|否| P["直接调用 handler"]
        O --> Q["返回工具结果"]
        P --> Q
    end

    subgraph "特殊路径"
        L --> R{"是 MCP 工具?"}
        R -->|是| S["mcp_tool.py<br/>MCP 协议调用"]
        L --> T{"是 Memory Provider 工具?"}
        T -->|是| U["MemoryManager<br/>路由到 provider"]
    end

    style D fill:#f96,stroke:#333,stroke-width:2px

B.3 Memory Provider 生命周期

对应章节:第 11 章(Memory Provider 架构)

stateDiagram-v2
    [*] --> 加载: load_memory_provider(name)
    加载 --> 可用性检查: is_available()

    state 可用性检查 <<choice>>
    可用性检查 --> 注册: 可用
    可用性检查 --> 跳过: 不可用(缺少 API key 等)

    注册 --> 初始化: MemoryManager.add_provider()
    初始化 --> 就绪: initialize_all(session_id, platform, user_id)

    state 就绪 {
        [*] --> 等待调用

        等待调用 --> 工具注册: get_tool_schemas() → 追加到 AIAgent.tools
        等待调用 --> 系统提示: system_prompt_block() → MemoryManager.build_system_prompt()
        等待调用 --> 上下文注入: prefetch() / queue_prefetch() → 注入 recalled context

        等待调用 --> 每轮开始: on_turn_start()
        每轮开始 --> 等待调用

        等待调用 --> 每轮同步: sync_turn()
        每轮同步 --> 等待调用

        等待调用 --> 会话结束: on_session_end()
        会话结束 --> 等待调用
    end

    就绪 --> 清理: shutdown()
    清理 --> [*]
    跳过 --> [*]

B.4 Gateway 会话管理

对应章节:第 14 章(Gateway)

graph TB
    subgraph "消息到达"
        A["平台消息<br/>(Telegram / Discord / ...)"] --> B["BasePlatformAdapter<br/>.handle_message()"]
        B --> C["提取 SessionSource<br/>(platform + user_id + chat_id)"]
    end

    subgraph "会话路由"
        C --> D["SessionStore.get_or_create()"]
        D --> E{"会话存在?"}
        E -->|是| F{"过期?"}
        E -->|否| G["创建新会话"]
        F -->|是| H["重置会话<br/>保留记忆"]
        F -->|否| I["复用会话"]
        G --> J["分配 session_id"]
        H --> J
        I --> J
    end

    subgraph "Agent 调用"
        J --> K["复用或构造 AIAgent<br/>(注入平台回调)"]
        K --> L["agent.run_conversation()"]
        L --> M["响应"]
    end

    subgraph "响应投递"
        M --> N{"响应长度"}
        N -->|短| O["单条消息"]
        N -->|长| P["分段发送<br/>(Telegram 4096 字符限制)"]
        N -->|含代码| Q["代码块格式化"]
        O --> R["platform.send()"]
        P --> R
        Q --> R
    end

    subgraph "并发控制"
        S["同一用户连续消息"] --> T["队列化处理<br/>防止 race condition"]
        U["不同用户并行消息"] --> V["独立 session<br/>并行处理"]
    end

    style D fill:#9cf,stroke:#333,stroke-width:2px

B.5 上下文压缩流程

对应章节:第 12 章(上下文管理)

graph TB
    A["run_conversation() 每轮循环开始"] --> B["估算当前 messages 的 token 数"]
    B --> C{"token 数 > threshold?<br/>(默认 50% context window)"}
    C -->|否| D["正常继续"]
    C -->|是| E["触发压缩"]

    E --> F["标记保护区域"]
    F --> G["protect_first_n = 3<br/>(system prompt + 初始消息)"]
    F --> H["protect_last_n = 20<br/>(最近的对话)"]

    G --> I["中间区域:可压缩"]
    H --> I

    I --> J["对可压缩区域生成摘要"]
    J --> K["使用同一模型<br/>或轻量模型"]
    K --> L["替换:多条消息 → 1 条摘要消息"]

    L --> M["重新计算 token 数"]
    M --> N{"仍然超过阈值?"}
    N -->|是| O["降低 protect_last_n<br/>再次压缩"]
    N -->|否| P["压缩完成"]

    P --> Q["注入压缩标记<br/>[CONTEXT COMPRESSED]"]

    style E fill:#fc9,stroke:#333,stroke-width:2px

B.6 四层稳定性防御

对应章节:第 10 章(SessionDB)、第 19 章(并发模型)、第 20 章(进程生命周期)、第 21 章(运行时容错)

graph TB
    subgraph "第 1 层:进程生命周期 (Ch20)"
        A1["信号处理<br/>SIGTERM → 优雅关停"]
        A2["Process Registry<br/>追踪子进程"]
        A3["清理守护线程<br/>回收资源"]
        A4["atexit 注册<br/>最终清理"]
    end

    subgraph "第 2 层:运行时防御 (Ch21)"
        B1["SafeWriter<br/>broken pipe 保护"]
        B2["API 重试 + 指数退避<br/>429/500/timeout"]
        B3["Fallback Provider 链<br/>主模型不可用时切换"]
        B4["Gateway 断线重连<br/>自动恢复连接"]
        B5["平台消息投递重试<br/>send() 失败重试"]
    end

    subgraph "第 3 层:数据安全 (Ch10)"
        C1["SQLite WAL 模式<br/>读写并发"]
        C2["BEGIN IMMEDIATE<br/>写锁定"]
        C3["Jitter Retry × 15<br/>锁竞争退避"]
        C4["事务回滚<br/>部分写入恢复"]
    end

    subgraph "第 4 层:架构防御 (Ch19)"
        D1["IterationBudget<br/>防无限循环"]
        D2["70% / 90% 压力预警<br/>budget 消耗提醒"]
        D3["async→sync 桥接<br/>线程隔离"]
        D4["daemon 线程<br/>background review 自动终止"]
    end

    EXT["外部故障"] --> B1
    EXT --> B2
    EXT --> B4

    INT["内部风险"] --> D1
    INT --> D2

    SYS["系统事件"] --> A1
    SYS --> A2

    DATA["数据竞争"] --> C1
    DATA --> C3

    style A1 fill:#fc9
    style B2 fill:#f96
    style C3 fill:#9cf
    style D1 fill:#9f9

以上流程图使用 Mermaid 格式,可在 mdbook 中直接渲染。图中的行号和文件引用基于 Hermes Agent v0.8.0。