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