总览流程
Intent Router是否 Task
->
Plannersingle/team
->
Skill 选择主 run / team node
->
Main Context身份/会话/记忆/技能/历史
->
Evidence事实记录
->
Learningaccepted task evidence -> 草稿合成
1. MainAgentRouter
文件:beaver/tasks/router.py;调用方:AgentService._process_with_main_agent()
| 阶段 | 内容 |
| 作用 | 只决定当前用户消息进入 simple chat 还是 internal Task mode,不回答用户。 |
| system message | 声明自己是 Beaver 的 Intent Agent;唯一职责是路由;只返回紧凑 JSON;不要回答用户,不要解释。 |
| user prompt 组成 | 固定说明“Decide how to route”;可选 intent-agent-router skill guidance;Actions 列表;Critical policy;返回 JSON keys;Active task JSON;最近 8 条 user/assistant 对话;Current user message。 |
| 输出 | { action, reason, short_title }。action 映射为 simple_chat、continue_task、revise_task、new_task、close_task、abandon_task。 |
| fallback | provider 不可用或两次超时失败:有 active task 则 continue_task,否则 simple_chat。 |
message + active_task + recent_messages
->
拼 router prompt
->
aux/main provider chat
->
parse JSON object
->
MainAgentDecision
user prompt =
"Decide how to route..."
+ optional "Intent Agent skill guidance:\n{intent_skill}"
+ Actions 列表
+ Critical policy 列表
+ "Return JSON only with keys: action, reason, short_title."
+ "Active task:\n{json(active_task_payload)}"
+ "Recent conversation:\n{json(recent[-8:])}"
+ "Current user message:\n{message}"
2. TaskExecutionPlanner
文件:beaver/tasks/planner.py;调用方:AgentService._run_task_mode()
| 阶段 | 内容 |
| 作用 | 决定本次 Task attempt 直接单 agent 执行,还是先创建 sub-agent team。 |
| system message | 选择 internal Beaver Task attempt 的执行模式;返回紧凑 JSON。 |
| user prompt 组成 | 执行模式说明;team 使用条件;JSON schema;Task goal;Current user request;Attempt index;必要的 task history(若有)。 |
| 输出 | mode 为 single 或 team;team 时还需 strategy、nodes、final_synthesis_instruction。 |
| fallback | provider 不可用、JSON 解析失败、graph validate 失败、skill resolver 失败都会回退 single。 |
planner user prompt =
"Decide execution mode for this internal Task attempt."
+ "Use mode=team only when ..."
+ JSON schema(mode/reason/strategy/nodes/final_synthesis_instruction)
+ "Task goal:\n{task.goal}"
+ "Current user request:\n{user_message}"
+ "Attempt index: {attempt_index}"
+ optional "Relevant task history:\n{task_history}"
3. TaskSkillResolver
文件:beaver/tasks/skill_resolver.py;调用方:planner 解析 team graph 后
| 阶段 | 内容 |
| query 组装 | skill_query、node.task、required capabilities、task.goal、user_message 用换行拼接。 |
| 召回 | SkillsLoader 构建候选,EmbeddingRetriever top-8。 |
| system message | 为一个 generic sub-agent node 选择 published Beaver skills;只返回 JSON array;不能编造名字;不匹配返回 []。 |
| user prompt | Node skill query;Candidate skills 列表;要求返回 JSON,例如 ["skill-a"] 或 []。 |
| 输出过滤 | 只保留候选集中真实存在的 skill name,并保持模型输出顺序。 |
| fallback | LLM 失败或返回空时,进入 EphemeralGuidanceSynthesizer。 |
node skill query =
join_non_empty(skill_query, node.task, " ".join(required_capabilities), task.goal, user_message)
4. EphemeralGuidanceSynthesizer
文件:beaver/skills/learning/missing_skill.py;调用方:TaskSkillResolver
| 阶段 | 内容 |
| 作用 | team node 没有 published skill 可用时,生成当前委派子任务专用的一次性 guidance。 |
| system message | 创建 concise Beaver ephemeral guidance;只返回 JSON keys:guidance_name、description、content、tags。 |
| user prompt | 说明“Create procedural guidance”;Task goal;Current user request;Node id;Node task;Skill query;Required capabilities;要求 content 是临时 sub-agent 可执行指导,不包含实现声明、review metadata 或 publish metadata。 |
| 输出 | 生成 SkillContext(name="ephemeral:{guidance_name}", version="ephemeral:{guidance_id}")。 |
| fallback | 失败时本地生成基础 payload:Objective、Capabilities to apply、Output。 |
5. SkillAssembler
文件:beaver/skills/assembler/task_assembler.py;调用方:AgentLoop._process_direct_impl()
| 阶段 | 内容 |
| query 来源 | 默认是 task;Task 模式会传入 AgentService 组装的 skill_selection_context;team node 会传 LocalAgentRunner 组装的 delegated skill_selection_context。 |
| 召回 | SkillsLoader candidates -> EmbeddingRetriever top-k。 |
| shortlist | 候选数超过 max_detailed_candidates 时,LLM 先基于摘要返回最多 N 个 skill names。 |
| final | 把 shortlist 对应候选补充 skill 正文,再让 LLM 返回最终要激活的 skill names。 |
| system message | 选择 Beaver skills;输入 task description 和 candidate skill information;只返回 JSON array;不能编造名字;无匹配返回 [];包含 selection stage 和返回数量指令。 |
| user prompt | Task description;Candidate skills;返回 JSON 示例。 |
| 注入 | 加载 skill 正文并 strip frontmatter,生成 SkillContext,稍后由 ContextBuilder 转成 activation message。 |
skill selector messages =
system: "You select Beaver skills for a single run..." + "Selection stage: {shortlist|final}..."
user: "Task description:\n{task_description}\n\nCandidate skills:\n{candidate_summary}\n\nReturn only JSON..."
6. AgentService 组装的上下文片段
文件:beaver/services/agent_service.py
Task skill selection context
传给 SkillAssembler 的 task_description。它不是 provider chat 的最终 prompt,但会影响选中哪些 skills。
Task goal / description / current user request。
Execution phase、task status、attempt index。
constraints、prior skills、必要的 task history。
planner reason、strategy、nodes、team summaries、final synthesis instruction。
明确要求优先选择 existing published skills。
Team execution context
如果 team 先跑,主 agent 的 execution_context 会包含 planner reason、team strategy、team success、node results、rendered team evidence、final synthesis instruction,以及避免重复失败工具调用的提醒。
Scheduled execution context
cron task/notification 会把 Cron Job ID、Name、Scheduled Run ID 和“不向用户确认,直接执行/生成通知”的约束放进 execution_context。
7. LocalAgentRunner delegated contexts
文件:beaver/coordinator/local.py
| 上下文 | 拼装内容 |
| execution_context | Parent task ID、Parent run ID、delegated worker 说明、agent.system_prompt、constraints、expected output、dependency outputs、pinned inherited skills、ephemeral pinned guidance。 |
| skill_selection_context | Parent task ID、Node task、Execution phase=team_node、Agent role、Skill query、Required capabilities、constraints、expected output、pinned skills、dependency outputs 前 800 字、Skill selection instruction。 |
DelegationEnvelope
->
child session id
->
execution_context
+
skill_selection_context
->
AgentLoop.process_direct
8. AgentLoop 主运行 prompt
文件:beaver/engine/loop.py、beaver/engine/context/builder.py
| 阶段 | 内容 |
| base identity | 固定 Beaver 身份:海狸(Beaver),博维资讯系统有限公司研发的 AI 助手。 |
| base system prompt | AgentProfile.system_prompt。 |
| session section | Session ID、Source、Model、User ID、Channel、Chat ID、Parent Session ID。 |
| execution context | Service 或 LocalAgentRunner 传入,标题为 # Execution Context。 |
| memory snapshot | MemorySnapshot.as_prompt_sections() 的 frozen sections。 |
| extra sections | 当前固定加入 Tool Failure Guidance。 |
| skill activation | 每个 SkillContext 变成一条 user message,位于 system prompt 之后、历史消息之前。 |
| history | session_manager.get_history(),ContextBuilder 跳过 role=system 的历史。 |
| current user | 本轮 task/message 作为最后一条 user message。 |
messages =
[
{"role": "system", "content": build_system_prompt(...)},
...build_skill_activation_messages(activated_skills),
...visible_history_without_system,
{"role": "user", "content": current_user_input}
]
Tool Failure Guidance
AgentLoop 把一段额外 section 放进 system prompt:如果同类工具反复失败,不要继续换 query 重试;使用已有材料,明确不确定性,给出部分已确认结果。
Tool iteration finalizer
到达最大工具迭代数后,AgentLoop 追加一条新的 system message,要求工具预算已耗尽、不要再调用工具、基于现有对话和工具结果给出最终答案,并明确不确定性。该 finalizer 只用于最后一次无工具收尾调用。
9. Tool loop 消息追加
文件:beaver/engine/context/builder.py、beaver/engine/loop.py
provider response
->
assistant message(content + tool_calls)
->
ToolExecutor
->
tool message(tool_call_id/name/content)
->
下一轮 provider chat
assistant 消息始终显式包含 content 键,即使工具调用时为空;tool_calls 会被规范化为 OpenAI-compatible 结构,arguments 非字符串时转 JSON 字符串。
10. Task Evidence
文件:beaver/tasks/evidence.py
| 阶段 | 内容 |
| 作用 | 记录 Task run 的事实证据,不判断、不打分、不 gate,也不生成 revision prompt。 |
| 输入 | Task goal、attempt index、main run、team runs、tool results、team node results、assistant final output。 |
| 输出 | TaskEvidencePacket / rendered evidence text,供审计、过程展示和 skill learning 使用。 |
| 边界 | Task 是否完成只由 User Acceptance 决定;accepted task evidence 包含 task 的所有 runs,并标记 final_accepted_run_id。 |
11. SkillDraftSynthesizer
文件:beaver/skills/learning/synthesizer.py
| 阶段 | 内容 |
| 作用 | 从 accepted task evidence 合成 skill 草稿,支持 new/revise/merge。 |
| system message | 从 accepted task evidence 合成 Beaver skill drafts;只返回 JSON keys:frontmatter、content、change_reason。 |
| user prompt | Action;Candidate kind;Reason;Related skills;Called tool names;Run-selected tool names;Task summaries;Session excerpts;final_accepted_run_id;frontmatter 必须包含 description 和 tools 数组。 |
| 输出 normalize | frontmatter.tools 为空时用 evidence_packet.metadata.tool_names 补齐。 |
| fallback | JSON 不合格时本地生成基础 frontmatter 和 Evidence 内容。 |
12. Provider conversion
文件:beaver/engine/providers/*
Provider 层不负责创造业务 prompt,但会改变 messages 的传输形式。Anthropic/Codex 类 provider 会把第一条 system message 拆出来传给 SDK 的 system 或 instructions 字段,剩余 messages 作为对话;OpenAI/LiteLLM 风格 provider 基本保留 messages + tools。
ContextBuilder 输出统一 messages。
Provider adapter 根据目标 SDK 转换 system、tools、tool calls、usage、reasoning。
响应统一回 LLMResponse,AgentLoop 不感知 SDK 差异。
13. 无 LLM prompt 但影响 prompt 的组件
| 组件 | 影响 |
| ToolAssembler | 不调用 LLM,但决定哪些 tool schema 暴露给主模型。 |
| MemoryService | 不调用 LLM,但 frozen snapshot 会进入 system prompt。 |
| SessionManager | 不调用 LLM,但可见历史决定 ContextBuilder 的 history。 |
| SkillDraftSafetyChecker | 不调用 LLM,是 deterministic safety gate,影响草稿是否能进入后续审核。 |