# Beaver Backend 可视化

基于 app-instance/backend 当前代码结构绘制，适合配合讲解使用：先给零基础读者建立概念，再逐页展开 Task、自学习、Skill/Tool、Memory/Session 和 Agent Team。

项目对比分析 范围: backend 入口: Web / CLI / Gateway / MCP 核心: shared AgentLoop

## 先把它当成一个“帮用户完成任务的后台工厂”

如果你完全没接触过后端、agent、skills、tools，先看这一页。它不要求你理解代码细节。

### 整体理解：用户一句话如何变成后台执行

用户说需求网页、命令行或其他入口收到一句话
入口接住把请求整理成后端内部格式
判断类型普通聊天还是需要跟踪的任务
执行任务选择技能、工具并调用模型
保存过程记录 session、task、run 和反馈
返回结果把最终答复展示给用户

### 这个后端在做什么

用户在前端发一句话，后端负责判断这句话是不是一个任务、要不要查资料或改文件、需不需要拆给多个小助手处理，最后把结果和过程记录下来。

### 为什么要分这么多层

因为“接收请求”“决定怎么做”“调用模型”“使用工具”“保存记忆”“学习新技能”是不同职责。分开以后，问题更容易定位，也方便单独替换或测试。

### 最重要的一句话

所有真正执行 agent 的地方，最后都会回到同一个 AgentLoop。这保证主 agent 和 sub-agent 用同一套运行规则。

### 看图时抓住四类东西

入口负责接话，服务层负责安排，运行内核负责执行，能力层提供工具、技能、记忆和外部连接。

用户

在网页、命令行或其他渠道输入一句话，比如“帮我整理这个项目的后端架构”。

入口层

把这句话接住，整理成后端能理解的请求格式。

服务层

判断这是不是一个任务。如果只是闲聊，就简单回答；如果需要执行，就创建或继续一个 Task。

运行内核

准备上下文、挑选技能和工具、调用大模型，并在模型要求使用工具时执行工具。

能力层

提供文件读写、搜索、记忆、MCP、定时任务、外部集成等具体能力。

状态层

记录这次对话、任务、工具结果、验证结果和用户反馈，方便继续任务或沉淀经验。

### Backend

前端背后的服务程序。用户看不见它的界面，但所有保存、调用模型、执行工具都在这里发生。

### Agent

可以根据目标自己决定下一步动作的模型运行单元，不只是简单问答。

### Task

一个需要跟踪结果的工作项，例如实现功能、分析代码、修复问题。

### Skill

给 agent 的专门说明书，告诉它处理某类任务时应该遵循什么步骤和标准。

### Tool

agent 可以调用的具体动作，比如读文件、写文件、搜索、执行命令、访问 MCP。

### Memory

系统保存的历史、经验、任务结果和反馈，让后续运行可以参考。

### Demo：一句普通需求如何被后台处理

适合开场讲解：先不讲代码，只讲用户输入、后台判断、最终输出。

#### 输入

    {
      "user_message": "帮我总结 backend 的 Task 机制",
      "channel": "web"
    }

#### 后台理解

    {
      "is_task": true,
      "reason": "需要阅读代码并产出解释",
      "needs_tools": ["read_file", "search_files"],
      "needs_memory": true
    }

#### 预期输出

    {
      "answer": "Task 是一张可追踪工作单...",
      "task_created": true,
      "saved_to_session": true,
      "can_continue_later": true
    }

## 模块分层与依赖方向

这一页只展示大模块位置和依赖方向，适合先建立全局地图。

入口 服务 运行内核 能力 状态

### 四层架构：从入口到能力

Interfaces Web、CLI、Gateway、MCP 等入口
Services 把请求安排成内部工作流
Engine 统一 AgentLoop 执行模型调用和工具循环
Capabilities Skills、Tools、Memory、Permissions

### Interfaces 薄入口

↓
↓

### Application Services

↓

### Shared Runtime

↓

### Capabilities + State

### Demo：同一个请求经过四层架构

用一条请求把每层职责串起来，说明每层只做自己的事。

#### 输入

    POST /api/chat
    {
      "session_id": "web-demo-001",
      "message": "请分析这个项目的后端结构"
    }

#### 层级流转

    {
      "interfaces": "接收 HTTP 请求",
      "services": "判断是否进入 Task mode",
      "engine": "调用模型并执行工具",
      "capabilities": "提供 skill、tool、memory"
    }

#### 预期输出

    {
      "session_id": "web-demo-001",
      "task_id": "task_arch_001",
      "message": "后端可以分为入口层、服务层..."
    }

## Task 的概念：从一句话到可跟踪工作

这一页围绕 Intent Agent、主 Agent、Sub-agent 和 Task 展示。讲解重点是：不是所有聊天都是 Task，只有需要执行、追踪和反馈的工作才进入 Task mode。

### Task 概念图：谁负责什么

用户消息可能是闲聊，也可能是工作请求
Intent Agent 只判断路由，不回答问题
Task 需要追踪的工作单
主 Agent 负责最终答案和整体一致性
Sub-agent 只处理被拆出去的局部工作
验收反馈满意、修改或放弃都会更新任务状态
1

### 用户输入

用户可能只是问一句普通问题，也可能要求系统完成一件事，例如“分析后端架构”“修复测试”“整理技能文档”。

2

### Intent Agent 判断意图

MainAgentRouter 只做路由，不回答用户。它判断当前消息是 simple_chat、new_task、continue_task、close_task 还是 abandon_task。

3

### TaskService 创建或恢复任务

如果要进入 Task mode，TaskService 会创建 TaskRecord，保存目标、状态、run 列表、反馈、验证结果和事件流。

4

### 主 Agent 负责最终回答

主 Agent 通过 AgentLoop 运行，负责综合上下文、技能、工具结果和 team 输出，最终给用户一个完整答复。

5

### Sub-agent 只处理局部工作

复杂任务会先交给任务规划器判断是否拆分。Sub-agent 处理调研、检查、实现片段等局部任务，结果再交回主 Agent 综合。

6

### 验证和反馈让 Task 闭环

每次 Task run 后会记录 validation。用户点击满意、要求修改或放弃时，会更新 Task 状态，并影响后续学习候选。

### TaskRecord 里有什么

- task_id、session_id、目标和描述。
- status 表示 open、running、awaiting_feedback、closed 等状态。
- run_ids 连接每次模型运行。
- feedback 和 validation_result 记录结果质量。

### Task CRUD

- Create：TaskService.create_task。
- Read：GET /api/tasks、GET /api/tasks/{task_id}。
- Update：start run、append run、record validation、add feedback。
- Delete：DELETE /api/tasks/{task_id}。

### 讲解抓手

- Intent Agent 是分流员。
- Task 是工作单。
- 主 Agent 是总负责人。
- Sub-agent 是临时分工人员。
- Validation 和 feedback 是验收记录。

### Demo：Task 从创建到等待反馈

这组数据可以用来解释 Task 不是一句回复，而是一张有状态的工作单。

#### 输入

    {
      "session_id": "web-demo-001",
      "message": "分析 backend 的 Task 机制，并给我讲解稿"
    }

#### 关键数据格式

    {
      "router_decision": {
        "action": "new_task",
        "short_title": "Task机制讲解"
      },
      "task": {
        "task_id": "task_001",
        "status": "awaiting_feedback",
        "run_ids": ["run_001"],
        "skill_names": ["backend-reader"]
      },
      "validation_result": {
        "accepted": true,
        "score": 0.91
      }
    }

#### 预期输出

    {
      "task_id": "task_001",
      "task_status": "awaiting_feedback",
      "answer": "Task 机制可以理解为...",
      "feedback_options": [
        "satisfied",
        "revise",
        "abandon"
      ]
    }

## 自学习：从 Task 反馈到 Skill 生命周期

这一页围绕 Task、Skill、自学习 Skill 的 CRUD 展开。讲解重点是：系统不会自动发布新技能，必须经过候选、草稿、安全检查、评估、审核和发布。

### 自学习闭环：成功经验如何变成可复用 Skill

Task 成功有结果、验证和用户满意反馈
Learning Candidate 系统发现这次经验值得沉淀
Skill Draft 生成一个待审核的技能草稿
Safety / Eval 安全检查和效果评估
Review 人工 approve 或 reject
Publish 发布成可选择的新版本 Skill
1

### Task 产生证据

每次 Task run 都会写入 run record、激活过的 skill receipt、tool 使用结果、validation 和用户反馈。

2

### 满意反馈触发候选

当用户反馈 satisfied 且 validation 通过时，SkillLearningService 可以基于这次成功经验生成 learning candidate。

3

### 候选生成 Draft

POST /api/skills/candidates/{candidate_id}/draft 会合成技能草稿，同时生成 safety report 和 eval report。

4

### 人工 Review

草稿可 submit、approve 或 reject。高风险内容不能静默发布，发布接口需要显式确认。

5

### Publish / Disable / Rollback

通过后进入 published skill；后续可以 disable 或 rollback 到指定版本。Worker 只生成和评估，不自动 approve/publish。

### Candidate CRUD

- List：GET /api/skills/candidates。
- Read：GET /api/skills/candidates/{candidate_id}。
- Create：由满意 Task 反馈或 worker run-once 生成。
- Update：合成 draft、regenerate draft、写 audit event。

### Draft / Review CRUD

- List：GET /api/skills/drafts。
- Read：draft、safety、eval 三类详情接口。
- Update：submit、approve、reject。
- Delete：底层 DraftService.delete_draft 支持删除草稿。

### Published Skill CRUD

- Create：publish 生成新版本。
- Read：skills list、detail、version、file、download。
- Update：disable、rollback。
- Delete：DELETE /api/skills/{name} 删除或归档技能入口。

### Demo：一次满意反馈如何变成 Skill 草稿

适合讲“自学习不是自动上线”，它只是生成候选和草稿，后面仍要审核。

#### 输入

    POST /api/chat/feedback
    {
      "session_id": "web-demo-001",
      "run_id": "run_001",
      "feedback_type": "satisfied",
      "comment": "这次后端讲解结构很好"
    }

#### 关键数据格式

    {
      "candidate": {
        "candidate_id": "cand_001",
        "status": "candidate",
        "trigger_run_id": "run_001",
        "evidence": ["Task 通过验证", "用户满意"]
      },
      "draft": {
        "draft_id": "draft_001",
        "skill_name": "backend-explainer",
        "status": "draft",
        "proposal_kind": "new_skill"
      }
    }

#### 预期输出

    {
      "learning_candidate_created": true,
      "draft_created": true,
      "safety_report": "passed",
      "eval_report": "passed",
      "next_step": "submit_review"
    }

## Skill 和 Tool：如何选技能、选工具，以及 Skill 里的 tool 字段

这一页关注 Skill 选择器、工具选择器，以及 skill 中工具提示字段如何影响工具暴露。

### Skill / Tool 选择链路

任务描述本轮要解决的问题
Skill 召回 embedding 找到候选 Skill
Skill 精选 LLM 选择真正激活的 Skill
tool_hints Skill 建议常用工具
Tool 选择 always tools + hints + embedding top-k
Tool Schema 只把选中的工具暴露给模型
1

### Skill 选择器先看任务

SkillAssembler 读取所有可选 skill 摘要，用 embedding 召回候选，再让辅助模型从候选中选出本轮真正激活的 skill。

2

### 激活 Skill 变成上下文

被选中的 skill 会变成 SkillContext，写入 system prompt，并生成 SkillActivationReceipt 方便后续学习和审计。

3

### Skill 的 tool_hints 影响工具选择

Skill 版本里有 tool_hints。如果某个 skill 明确提示需要 read_file、patch_file 等工具，工具选择器会优先加入这些工具。

4

### 工具选择器再补充工具

ToolAssembler 先加入 always tools，再加入 skill hints，再通过 embedding 从 registry 中召回更多相关工具。

5

### ToolRegistry 导出 schema

ToolRegistry 不执行工具，只把选中的 ToolSpec 导出成 provider 可消费的 function schema。

6

### ToolExecutor 执行调用

模型返回 tool call 后，ToolExecutor 执行工具，并把 tool result 写回 session history，供下一轮模型继续使用。

### Skill 中关键字段

- name：技能唯一名。
- description：选择器理解技能用途。
- content：真正注入给 agent 的指导正文。
- tool_hints：建议本 skill 常用哪些工具。
- tags、owners：分类和治理信息。

### ToolSpec 中关键字段

- name：模型调用函数名。
- description：模型理解工具何时可用。
- input_schema：参数结构。
- toolset：所属工具集。
- always_available：是否每轮都暴露。

### 选择顺序

- Skill：候选召回 -> LLM shortlist -> LLM final -> 注入上下文。
- Tool：always tools -> skill tool_hints -> embedding top-k。
- 最终：只把选中的工具 schema 给模型，减少噪音和误用。

### Demo：Skill 选择器和工具选择器如何配合

用一个 Skill 的 frontmatter 解释 tool_hints 为什么会影响本轮可用工具。

#### 输入

    {
      "task_description": "阅读 backend 代码并解释 Task 机制"
    }

#### 关键数据格式

    ---
    name: backend-explainer
    description: Explain backend architecture
    tool_hints:
      - search_files
      - read_file
      - session_search
    ---
    先定位入口，再追踪服务层和运行内核。

#### 预期输出

    {
      "activated_skills": [
        "backend-explainer"
      ],
      "selected_tools": [
        "memory",
        "session_search",
        "search_files",
        "read_file"
      ],
      "tool_schema_count": 4
    }

## Memory 和 Session：CRUD、装载与运行时快照

这一页解释会话、记忆和运行记录如何创建、读取、更新、归档，以及 AgentLoop 如何装载它们。

### Memory / Session 装载和写回

EngineLoader 创建状态组件
Session 保存对话消息和事件
Memory Snapshot 每次 run 捕获一份快照
AgentLoop 用快照组装上下文并执行
Run Memory 记录运行证据和 skill effect
Feedback 反馈反写到任务和学习数据
1

### EngineLoader 装载状态组件

EngineLoader.load 创建 SessionManager、curated MemoryStore、MemoryService、RunMemoryStore 和 SkillLearningStore。

2

### Session 保存对话过程

每次 run 都会确保 session 存在，并追加 system、user、assistant、tool 等消息，同时记录 event payload、usage、run_id 和上下文可见性。

3

### MemoryService 捕获快照

AgentLoop 每次运行都会调用 capture_snapshot_for_run。并行 team run 各拿自己的 frozen snapshot，避免互相覆盖。

4

### RunMemoryStore 保存运行证据

run record 记录输入、输出、激活 skill、验证、反馈；skill effect 记录某个 skill 在这次 run 中的效果。

5

### API 提供 Session CRUD

前端通过 sessions API 创建、查看、归档会话，也可以读取 session process 和 debug chat logs。

### Session CRUD

- Create：POST /api/sessions/{session_id} 或 run 时 ensure_session。
- Read：GET /api/sessions、GET /api/sessions/{session_id}。
- Update：append_message、update_usage、update_system_prompt。
- Delete/Archive：DELETE /api/sessions/{session_id} 或 archive。

### Memory / Run CRUD

- Create：append run record、append skill effect、curated memory item。
- Read：session search、memory tool、run list、skill effects。
- Update：validation、feedback、success ratio、performance snapshot。
- Archive：通过 session end reason 或 skill/version 状态保留历史。

### 装载顺序

- 配置解析 workspace。
- 初始化 curated memory store。
- 创建 session 和 run stores。
- 注入 ToolContext services。
- 运行时按 run 捕获 memory snapshot。

### Demo：Session、Message、Memory Snapshot 的关系

适合讲“为什么能继续对话”，以及“为什么并行 sub-agent 不会互相污染记忆”。

#### 输入

    POST /api/sessions/web-demo-001

    POST /api/chat
    {
      "session_id": "web-demo-001",
      "message": "继续解释刚才的 Task"
    }

#### 关键数据格式

    {
      "session": {
        "id": "web-demo-001",
        "source": "web",
        "message_count": 12
      },
      "message": {
        "role": "user",
        "run_id": "run_002",
        "content": "继续解释刚才的 Task"
      },
      "memory_snapshot": {
        "captured_for_run": "run_002",
        "frozen": true
      }
    }

#### 预期输出

    {
      "session_loaded": true,
      "history_used": true,
      "run_id": "run_002",
      "assistant_message_saved": true
    }

## 一次用户请求如何流过后端

从 WebSocket/HTTP 进入，到 AgentLoop 选择 skills/tools，最后写回 session 和 run memory。

### 请求主链：技术视角

HTTP / WS 接口收到用户请求
AgentService 统一收口 direct / running 模式
Router 判断 simple chat 或 Task mode
Planner 选择 single 或 team
AgentLoop 模型调用和工具循环
Validation 记录验证、反馈和学习证据
1

### 接口接收请求

interfaces/web/app.py 提供 /api/chat、/ws/{session_id}、tasks、files、skills、cron 等入口，只做参数转换和响应拼装。

2

### AgentService 收口

接口层不直接 new loop，而是调用 AgentService.process_direct 或 submit_direct，由 service 管理 direct/running mode。

3

### Intent Agent 路由

MainAgentRouter 用辅助模型判断 simple chat、继续任务、新建任务、关闭或放弃任务；simple chat 会关闭 skill/tool assembly。

4

### Task mode 规划

TaskService 创建或恢复任务，任务规划器决定单 agent 还是 team；team 模式先运行 sub-agent，再交给主 agent synthesis。

5

### EngineLoader 装配运行时

统一加载 session manager、memory service、skills loader、tool registry、tool executor、skill learning pipeline、agent registry、MCP manager。

6

### AgentLoop 运行主链

捕获 memory snapshot，组装 prompt，选择 skills 和 tools，调用 provider；若返回 tool calls，则执行 tool loop 并把结果追加回上下文。

7

### 验证、反馈和学习沉淀

Task 结果进入 validation 和 feedback gate；满意反馈会更新 run record、skill effects，并可能生成 assisted learning candidate。

### Demo：完整 /api/chat 输入输出

这可以作为接口级例子：用户输入什么，后端可能返回什么。

#### 输入

    POST /api/chat
    {
      "session_id": "web-demo-001",
      "message": "帮我画出 Task、自学习、Skill 和 Memory 的关系",
      "thinking_enabled": true
    }

#### 关键内部事件

    [
      {"event_type": "intent_agent_decision", "action": "new_task"},
      {"event_type": "task_execution_planned", "mode": "team"},
      {"event_type": "skill_activation_snapshotted", "skills": ["backend-explainer"]},
      {"event_type": "tool_selection_snapshotted", "tools": ["search_files", "read_file"]},
      {"event_type": "task_validation_snapshotted", "accepted": true}
    ]

#### 预期输出

    {
      "session_id": "web-demo-001",
      "run_id": "run_003",
      "task_id": "task_002",
      "task_status": "awaiting_feedback",
      "message": "可以把这四者理解为..."
    }

## Agent Team：什么时候拆分、怎么编排、如何回到主 Agent

这一页展示 Agent Team 的完整概念：注册的 agent 能力、Task planner 的 team plan、ExecutionGraph 的三种策略、每个节点的 skill 绑定，以及最终 synthesis。

### Agent Team 执行图

Task 复杂工作进入任务模式
Team Plan Planner 生成执行图
Skill Binding 为每个节点绑定 Skill 或临时指导
Scheduler 按 sequence、parallel 或 DAG 推进
Sub-agents 节点回到同一个 AgentLoop 执行
Main Synthesis 主 Agent 综合所有节点输出
1

### 先判断是否值得组队

任务规划器只在独立调研、评审、实现切片、分阶段检查能明显提升结果时选择 team，否则保持 single agent。

2

### 生成 ExecutionGraph

team plan 会生成 ExecutionGraph，包含 strategy、nodes、node task、depends_on、expected_output 和 skill_query。

3

### 为节点绑定 Skill

TaskSkillResolver 为每个 node 选择 published skill；如果没有合适 skill，就合成 one-run ephemeral guidance。

4

### LocalAgentRunner 执行节点

每个 sub-agent 节点都会通过 LocalAgentRunner 调回同一个 AgentLoop，只是 session_id、source、execution_context 不同。

5

### 主 Agent 综合输出

Team 的 node outputs 不直接作为最终答案，而是进入主 Agent 的 synthesis context，由主 Agent 负责最终一致性、取舍和用户回答。

### Sequence

node A→node B→main synthesis

上游输出作为下游 dependency output；任一节点失败，后续节点被标记 blocked。

### Parallel

node A node B node C→synthesis

适合独立调研、并行检查或拆分实现面；由 asyncio.gather 并发运行。

### DAG

research→design→review

显式 depends_on 控制依赖，scheduler 按 ready batch 推进并检测循环依赖。

### Skill Binding

skill query→published skill/ephemeral guidance

TaskSkillResolver 优先 pin 已发布 skill；缺失时合成 one-run guidance，不自动发布。

### Agent Team CRUD

- List：GET /api/agents、GET /api/subagents。
- Create：POST /api/agents、POST /api/subagents。
- Update：PATCH /api/agents/{agent_id}、PUT /api/subagents/{agent_id}、disable。
- Delete：DELETE /api/agents/{agent_id}、DELETE /api/subagents/{agent_id}。

### 节点输入里有什么

- 父 task id 和父 run id。
- 节点自己的 task 和 expected output。
- 依赖节点的输出。
- pinned skills 或 ephemeral guidance。
- 节点角色、约束和 skill selection context。

### 失败如何处理

- Sequence 中前序失败会阻塞后续节点。
- DAG 中依赖失败会阻塞依赖它的节点。
- Parallel 节点独立运行，失败会进入 team summary。
- 主 Agent 会看到失败摘要，再决定如何向用户说明。

### Demo：Agent Team 把复杂任务拆成三个节点

这个例子适合讲 sequence、parallel、DAG 之前先让用户理解“节点输出最后还要由主 Agent 综合”。

#### 输入

    {
      "task_id": "task_002",
      "user_message": "检查后端架构讲解是否完整，并补上缺口"
    }

#### 关键数据格式

    {
      "mode": "team",
      "strategy": "dag",
      "nodes": [
        {"node_id": "read", "task": "阅读现有文档", "depends_on": []},
        {"node_id": "check", "task": "检查缺失主题", "depends_on": ["read"]},
        {"node_id": "draft", "task": "补写讲解内容", "depends_on": ["check"]}
      ]
    }

#### 预期输出

    {
      "team_success": true,
      "node_results": [
        {"node_id": "read", "success": true},
        {"node_id": "check", "success": true},
        {"node_id": "draft", "success": true}
      ],
      "main_synthesis": "已补充 Task、自学习、Skill/Tool、Memory/Session 和 Agent Team 示例。"
    }

## 能力层和状态边界

这些层围绕 AgentLoop 工作，但各自保持独立职责。

### Skills

- SkillsLoader 读取 published skill 和 selection candidates。
- SkillAssembler 通过 embedding 召回和 LLM 决策激活 skill。
- draft、review、publisher、learning pipeline 支持候选生成、审核和发布。

### Tools

- ToolRegistry 只负责注册、查找和导出 provider schema。
- ToolAssembler 结合 always tools、skill hints 和 embedding top-k。
- ToolExecutor 执行 tool call，结果写入 session history。

### Memory

- 每个 run 捕获自己的 frozen memory snapshot，避免并行 team run 串扰。
- session manager 保存消息、事件 payload、usage、归档状态。
- run memory 保存 receipts、validation、feedback、skill effects。

### Providers

- ProviderBundle 分离 main、auxiliary、embedding runtime。
- router、planner、skill selection 可走 auxiliary provider。
- 主回答、tool loop 和 synthesis 走 main provider。

### Integrations

- MCP manager 连接外部 MCP server，并把 tools 注册进 registry。
- Outlook、WhatsApp、A2A、authz 保持在 integrations 边界内。
- Web API 只暴露集成状态、连接测试和数据读取入口。

### Cron

- CronService 在 FastAPI lifespan 中随 AgentService 启停。
- notification 生成通知结果，task mode 生成可反馈的 TaskRecord。
- 用户 engage 后可把定时结果转成继续编辑的任务。

### Demo：一次运行会同时用到哪些能力

适合收尾时复盘：一次 Task 运行不是只调用模型，而是多个能力层一起工作。

#### 输入

    {
      "task": "生成后端架构讲解页",
      "session_id": "web-demo-001"
    }

#### 能力调用

    {
      "providers": ["main", "auxiliary", "embedding"],
      "skills": ["backend-explainer"],
      "tools": ["search_files", "read_file", "write_file"],
      "memory": ["session_history", "run_record"],
      "integrations": ["mcp_optional"]
    }

#### 预期输出

    {
      "artifact": "backend-visualization.html",
      "session_updated": true,
      "run_memory_written": true,
      "skill_effect_recorded": true
    }