# 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。
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，影响草稿是否能进入后续审核。