Prompt Atlas

这里集中记录后端所有直接组装 LLM messages 的位置。每段都按“谁调用、输入怎么来、system/user prompt 怎么拼、模型输出怎么解析、失败怎么 fallback”展开。

总览流程

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。
fallbackprovider 不可用或两次超时失败:有 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 时还需 strategynodesfinal_synthesis_instruction
fallbackprovider 不可用、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_querynode.task、required capabilities、task.goal、user_message 用换行拼接。
召回SkillsLoader 构建候选,EmbeddingRetriever top-8。
system message为一个 generic sub-agent node 选择 published Beaver skills;只返回 JSON array;不能编造名字;不匹配返回 []。
user promptNode skill query;Candidate skills 列表;要求返回 JSON,例如 ["skill-a"][]
输出过滤只保留候选集中真实存在的 skill name,并保持模型输出顺序。
fallbackLLM 失败或返回空时,进入 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 promptTask 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_contextParent task ID、Parent run ID、delegated worker 说明、agent.system_prompt、constraints、expected output、dependency outputs、pinned inherited skills、ephemeral pinned guidance。
skill_selection_contextParent 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.pybeaver/engine/context/builder.py

阶段内容
base identity固定 Beaver 身份:海狸(Beaver),博维资讯系统有限公司研发的 AI 助手。
base system promptAgentProfile.system_prompt。
session sectionSession ID、Source、Model、User ID、Channel、Chat ID、Parent Session ID。
execution contextService 或 LocalAgentRunner 传入,标题为 # Execution Context
memory snapshotMemorySnapshot.as_prompt_sections() 的 frozen sections。
extra sections当前固定加入 Tool Failure Guidance。
skill activation每个 SkillContext 变成一条 user message,位于 system prompt 之后、历史消息之前。
historysession_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.pybeaver/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 promptAction;Candidate kind;Reason;Related skills;Called tool names;Run-selected tool names;Task summaries;Session excerpts;final_accepted_run_id;frontmatter 必须包含 description 和 tools 数组。
输出 normalizefrontmatter.tools 为空时用 evidence_packet.metadata.tool_names 补齐。
fallbackJSON 不合格时本地生成基础 frontmatter 和 Evidence 内容。

12. Provider conversion

文件:beaver/engine/providers/*

Provider 层不负责创造业务 prompt,但会改变 messages 的传输形式。Anthropic/Codex 类 provider 会把第一条 system message 拆出来传给 SDK 的 systeminstructions 字段,剩余 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,影响草稿是否能进入后续审核。