【免费下载链接】MemoryBear
MemoryBear Equip AI with human-like memory capability
导读
本文以 MemoryBear 仓库中 analyze_task_user.md 为核心,结合其配套的 analyze_task_system.md 与提示词加载/渲染实现,完整拆解这套"任务分析"(Task Analysis)提示词的双文档设计与执行逻辑。读完你将掌握:输入变量如何注入、任务传递(Task Transmission)何时输出、LOW / MEDIUM / HIGH 三级复杂度如何划分与限词,以及该框架在 MemoryBear 多 Agent 编排体系中的落点与自定义方式。
一、提示词在仓库中的位置与设计意图
在 MemoryBear 中,api/app/core/rag/prompts/目录集中存放 RAG 与多 Agent 场景使用的全部提示词模板,其中analyze_task_user.md与analyze_task_system.md是一对"用户侧 / 系统侧"提示词,职责是让 LLM 扮演一个"能按任务复杂度自适应调整分析深度"的任务分析器。
从 generator.py 可以看到二者的加载方式完全对称:
ANALYZE_TASK_SYSTEM = load_prompt("analyze_task_system") ANALYZE_TASK_USER = load_prompt("analyze_task_user")加载机制由 template.py 提供:load_prompt(name)会在prompts/目录下查找{name}.md,首次读取后缓存在_loaded_prompts字典中,避免重复读盘。这意味着这两个文件本质上是可被 Jinja2 渲染的模板,而非写死的静态文本。
二、用户侧提示词:四个输入变量 + 一条输出铁律
analyze_task_user.md全文虽短,但定义了整套模板的"数据契约"。它声明了四个输入变量:
| 变量 | 含义 | 注入内容 |
|---|---|---|
{{ task }} | 待分析的任务/请求 | 当前任务名或用户请求 |
{{ context }} | 背景、历史、情境上下文 | 会话历史与上下文信息 |
{{ agent_prompt }} | 特殊指令/角色提示 | 当前 Agent 的角色定义或额外约束 |
{{ tools_desc }} | 可用的子 Agent 与能力清单 | 由工具 schema 序列化后的能力描述 |
同时声明最终输出规则(Final Output Rule):
Return the Task Transmission section (if needed) followed by the concrete analysis and planning steps according to LOW / MEDIUM / HIGH complexity. Do not restate the framework, definitions, or rules. Output only the final structured result.
翻译过来即:先输出(如需)"任务传递"小节,再按 LOW / MEDIUM / HIGH 复杂度输出具体的分析与规划步骤;不得复述框架、定义或规则本身,只输出最终结构化结果。这条规则的工程价值在于压缩输出 token、让下游解析器直接消费结构化内容。
三、系统侧提示词:三级复杂度自适应分析框架
配套的 analyze_task_system.md 定义了分析器必须遵循的三步框架,用户侧模板中的 LOW / MEDIUM / HIGH 正是由它给出的。
Step 1:任务传递评估(Task Transmission Assessment)
该小节不受字数限制,因为它承担关键交接(handoff)职责。判定是否需要任务传递信息:
- 若是初始步骤→ 跳过本节;
- 若没有上游 Agent / 步骤→ 提供最小化传递;
- 若有必须保留的关键状态/上下文→ 输出完整传递。
需要传递时,按六个字段输出:
- Current State Summary:当前进度摘要(1–2 句);
- Key Data/Results:必须携带的关键发现;
- Context Dependencies:下游 Agent/步骤必需的上下文;
- Unresolved Items:需要延续解决的遗留问题;
- Status for User:面向用户的清晰状态更新;
- Technical State:面向技术交接的系统状态。
这组字段的设计体现了一个多 Agent 编排系统对"上下文连续性"的硬性要求——交接内容既要让下一个 Agent 接得住,也要让用户看得懂。
Step 2:复杂度分类(Complexity Classification)
- LOW:单步任务、直接查询、闲聊;
- MEDIUM:单一领域内的多步任务;
- HIGH:跨领域协调或复杂推理。
分类的意义不是贴标签,而是决定 Step 3 的分析深度预算,实现"越简单越省,越复杂越全"的自适应策略。
Step 3:自适应分析(Adaptive Analysis)
分析深度随复杂度伸缩,一旦达成成功标准立即停止(Always stop once success criteria are met)。各档位的要求如下:
| 档位 | 分析字数上限 | 必须包含的内容 |
|---|---|---|
| LOW | 最多 50 词 | 检测到闲聊时直接输出Small talk — no further analysis needed;单句目标;1–2 步直接执行方案 |
| MEDIUM | 80–150 词 | 目标;意图与范围;3–5 步最小计划(可标注并行步骤);至少一个带明确停止条件的探测(Probe);成功标准 + 基础失败检测与回退;证据获取/验证的 Source Plan |
| HIGH | 150–250 词 | 完整目标分析;意图与范围;5–8 步带依赖/并行关系的计划;关键未知项 → 探测 → 停止条件;可衡量的成功标准;失败检测器与回退;证据获取与验证的 Source Plan;升降级的反思钩子(Reflection Hooks) |
值得注意的细节:
- MEDIUM 的 "Uncertainty & Probes"要求"至少一个带停止条件的探测",防止模型在不确定性上无限发散;
- HIGH 的 "Reflection Hooks"允许模型在分析过程中根据实际情况"升级/降级"复杂度判断,这是自适应能力的闭环体现;
- 三个档位都要求Source Plan(证据如何获取与验证),说明该框架为"可溯源、可核查"的检索增强分析而设计。
四、代码落地:Jinja2 渲染与工具描述注入
analyze_task_user.md中的变量如何变成真实 prompt?关键在 generator.py 的analyze_task()函数:
def analyze_task(chat_mdl, prompt, task_name, tools_description: list[dict], user_defined_prompts: dict={}): tools_desc = tool_schema(tools_description) context = "" if user_defined_prompts.get("task_analysis"): template = PROMPT_JINJA_ENV.from_string(user_defined_prompts["task_analysis"]) else: template = PROMPT_JINJA_ENV.from_string(ANALYZE_TASK_SYSTEM + "\n\n" + ANALYZE_TASK_USER) context = template.render(task=task_name, context=context, agent_prompt=prompt, tools_desc=tools_desc) kwd = chat_mdl.chat(context, [{"role": "user", "content": "Please analyze it."}]) if isinstance(kwd, tuple): kwd = kwd[0] kwd = re.sub(r"^.*</think>", "", kwd, flags=re.DOTALL) if kwd.find("**ERROR**") >= 0: return "" return kwd这段实现揭示了几个关键工程细节:
- 双文档拼接:默认模板是
ANALYZE_TASK_SYSTEM + "\n\n" + ANALYZE_TASK_USER,系统侧定义框架、用户侧声明数据契约,两者合二为一后交给 Jinja2 渲染; - 工具描述序列化:
tools_desc由tool_schema()生成(见 generator.py),把每个子 Agent/工具按## 1. name + JSON Schema的格式编排,正好填充{{ tools_desc }}; - 可覆盖性:
user_defined_prompts.get("task_analysis")允许业务方用自定义 Jinja2 模板整体替换这套默认提示词,实现"框架固定、模板可插拔"; - 输出清洗:调用 LLM 后统一用正则
re.sub(r"^.*</think>", "", ...)剥掉思考链前缀,遇到**ERROR**标记则返回空串,避免脏输出污染下游。
该 prompt 模块与api/app/core/rag/prompts/下其余模板(如next_step.md、reflect.md、summary4memory.md、rank_memory.md)共同构成一个"分析 → 计划 → 执行 → 反思 → 记忆"的完整 Agent 循环提示词体系。在 MemoryBear 的多 Agent 编排侧,multi_agent_orchestrator.py 中的_analyze_task()也承担"Master Agent 分析任务并做出路由决策"的职责,会输出sub_agents、routing_decision、routing_tokens等结构化字段——可见"先分析、再路由、后执行"是该项目的统一范式。
五、易踩的坑与实用建议
结合模板与源码,实际使用这套提示词时有几点值得注意:
- 不要违反 Final Output Rule:模型若把框架定义复述一遍,会显著浪费 token 且破坏输出结构,建议在 few-shot 示例中强化"只输出结果"的行为;
- 闲聊短路:LOW 档的
Small talk — no further analysis needed是硬编码输出,下游解析时应做字符串精确匹配,命中后直接走轻量回复路径; - 字数预算是"分析部分"的预算:系统侧明确 LOW/MEDIUM/HIGH 的字数上限均指"for analysis only",且任务传递部分不受限——设计 prompt 变体时不要把交接字段和规划字段混在一处计费;
- 探测必须有停止条件:MEDIUM/HIGH 的 Probe 若缺少 stop condition,模型可能在不确定处反复试探,导致分析阶段 token 失控;
- 自定义模板的变量契约:若通过
user_defined_prompts["task_analysis"]覆盖,务必保留task、context、agent_prompt、tools_desc四个变量(或按需提供),否则 Jinja2 渲染会因变量缺失而报错。
六、相关文件速查
- 用户侧模板:analyze_task_user.md
- 系统侧框架:analyze_task_system.md
- 加载与渲染入口:generator.py(
analyze_task()、tool_schema()) - 模板加载器:template.py
- 同目录配套模板:
next_step.md、reflect.md、summary4memory.md、rank_memory.md、meta_filter.md等(见 prompts 目录) - 多 Agent 编排消费侧:multi_agent_orchestrator.py、master_agent_router.py
小结
MemoryBear 的analyze_task_user.md虽只有寥寥数行,却是整套任务分析框架的"数据契约层":它固定了四个输入变量与一条输出铁律,配合系统侧的三步分析框架(任务传递 → 复杂度分类 → 自适应分析),在 generator 中经 Jinja2 渲染后驱动 LLM 产出结构化分析结果。这种"系统模板定框架、用户模板定契约、业务方可整体覆盖"的三层设计,为多 Agent 编排中的任务理解环节提供了清晰、可维护、可扩展的范本。
【免费下载链接】MemoryBear
MemoryBear Equip AI with human-like memory capability
相关推荐
Sentry JavaScript SDK 框架更新相关性分类指南:从源码剖析 high/medium/low 判定规则
Sentry JavaScript SDK 框架更新相关性分类指南:从源码剖析 high/medium/low 判定规则 导读 本指南源自 Sentry Jav
可观测性如何在 5 分钟内集成 human-panic:为你的 Rust CLI 应用添加专业级错误处理
如何在 5 分钟内集成 human panic:为你的 Rust CLI 应用添加专业级错误处理 human panic 是一个专为 Rust CLI 应用设计
开发工具MemoryBear 规划 Agent 提示词解析:如何用 next_step.md 驱动多步工具调用决策
MemoryBear 规划 Agent 提示词解析:如何用 next_step.md 驱动多步工具调用决策 导读 在 MemoryBear 的 RAG 与 Ag
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考