5分钟了解agentscope PlanNotebook原理
一、agent常见编排模式
模式1:反思 (Reflection)
模式2:推理执行(reasoning acting)
模式3:规划 (Planning)
模式4:多智能体协作 (Multi-agent Collaboration)
目前agentscope支持模式2\3\4,模式1不能通用化实现(我猜),所以没实现。
而今天分享的PlanNotebook就是模式3。目前PlanNotebook支持手动和agent自动创建Plan
二、PlanNotebook承载对象
PlanNotebook目前使用Plan和SubTask两个对象来承载规划 (Planning)的逻辑,Plan代表一个规划,SubTask代表规划的一个具体的子任务。
手动创建Plan代码样例:
from agentscope.plan import Plan, SubTask
from agentscope.plan import PlanNotebook
from agentscope.agent import ReActAgent, UserAgent
from agentscope.formatter import DashScopeChatFormatter
from agentscope.model import DashScopeChatModel
# 1、创建一个PlanNotebook
plan_notebook = PlanNotebook(
max_subtasks=10, # 计划允许的最大子任务数
# plan_to_hint=CustomPlanToHint(), # 自定义提示生成函数
# storage=CustomStorage(), # 自定义存储后端
)
# 2、手动创建一个plan
plan_notebook.create_plan("传递计划的json参数")
# plan_notebook.create_plan()内部其实就会创建下面的plan对象
plan = Plan(
name="做一个智能体研究",
description="对基于LLM的智能体进行全面研究",
expected_outcome="回答三个问题:1.什么是智能体?2.当前技术水平?3.未来趋势?",
subtasks=[
SubTask(
name="搜索相关调研论文",
description="在Google Scholar、arXiv搜索2021年后发表、引用>50的论文",
expected_outcome="Markdown格式的论文列表"
),
SubTask(
name="阅读并总结论文",
description="阅读找到的论文,总结定义、分类、挑战和关键方向",
expected_outcome="Markdown格式的关键点总结"
),
SubTask(
name="研究大公司最新进展",
description="研究Google、Microsoft、OpenAI等公司的官方博客",
expected_outcome="各大公司最新进展汇总"
),
SubTask(
name="撰写最终报告",
description="基于前面步骤撰写报告,回答三个核心问题",
expected_outcome="Markdown格式的完整报告"
)
]
)
# 3、把plan_notebook注册到agent上
agent = ReActAgent(
name="Friday",
sys_prompt="You are a helpful assistant.",
model=DashScopeChatModel(
model_name="qwen-max",
api_key="sk-837bd39d7c954fea865fa14d9b3df33d",
),
formatter=DashScopeChatFormatter(),
plan_notebook=plan_notebook, # 注册plan_notebook
print_hint_msg=True,
)
Plan属性参数解读:
| 字段 | 说明 |
|---|---|
| name | 计划名称(≤10词) |
| description | 计划整体描述 |
| state | 当前状态:todo(待办) / in_progress(进行中) / done (完成) / abandoned(废弃) |
| expected_outcome | 计划的整体预期结果 |
| outcome | 完成后的实际产出 |
| subtasks | 有序的子任务列表 |
SubTask属性参数解读:
| 字段 | 说明 |
|---|---|
| name | 简洁的子任务名称(≤10词) |
| description | 详细描述,包含约束、目标和预期产出 |
| state | 当前状态:todo(待办) / in_progress(进行中) / done (完成) / abandoned(废弃) |
| expected_outcome | 具体的、可衡量的预期结果 |
| outcome | 完成后的实际产出 |
三、agent自动创建Plan
1、用户提出问题后的plan流程图

2、PlanNotebook代码分析

上面可以看到ReActAgent在初始化的时候,会把plan_notebook的几个方法添加为agent tool。
plan_notebook.list_tools()返回的方法介绍如下:

| 方法 | 说明 |
|---|---|
| view_subtasks(subtask_idx: List[int]) | 接收一个子任务索引列表,返回这些子任务的Markdown格式详情(包括描述、预期结果、当前状态、实际结果等 |
| update_subtask_state(subtask_idx: int, state: str) | 修改指定子任务的状态(todo、in_progress、abandoned) |
| finish_subtask(subtask_idx: int, subtask_outcome: str) | 将指定子任务标记为done,并记录其具体产出(subtask_outcome) |
| create_plan(name, description, expected_outcome, subtasks) | 创建一个全新的计划。如果当前已存在一个计划,新计划会直接覆盖旧计划(旧计划不会自动存入历史) |
| revise_current_plan(subtask_idx: int, action: str, subtask: SubTask) | 对当前计划的子任务列表进行动态调整,是实现灵活执行的关键。action参数:支持 “add”(在索引前添加)、“revise”(替换)、“delete”(删除)。 |
| finish_plan(state: str, outcome: str) | 结束当前计划,将其存入历史存储(storage)中,并将当前计划(current_plan)设为None |
| view_historical_plans() | 列出所有历史计划的摘要信息(ID、名称、创建时间、状态等) |
| recover_historical_plan(plan_id: str) | 根据ID将一个历史计划恢复为当前活动计划。 |
每次任务调用agent的时候,ReActAgent调用堆栈:
self.reply(“agent入口”) --> self._reasoning(“推理”)

在_reasoning()方法中可以看出,每次agent推理的时候,都会调用plan_notebook.get_current_hint()

get_current_hint()方法其实就是通过self.plan_to_hint(self.current_plan)去获取当前plan的提示词 hint,这个hint就是告诉agent接下来该怎么做的。并通过user msg返回,最后通过self.memory.add(hint_msg, marks=_MemoryMark.HINT)添加到短期记忆(agent上下文)中。
3、plan_to_hint方法原理
plan_to_hint方法是给agent下一步生成hint(指示),plan_to_hint方法主要逻辑如下:
1. 判断当前plan是否为空,如果为空,hint如下:
"If the user's query is complex (e.g. programming a website, game or "
"app), or requires a long chain of steps to complete (e.g. conduct "
"research on a certain topic from different sources), you NEED to "
"create a plan first by calling 'create_plan'. Otherwise, you can "
"directly execute the user's query without planning."
这hint意思是:
如果用户的提问比较复杂(比如要编写一个网站、游戏或应用程序),
或者需要完成一连串的较长步骤(例如,从不同来源对某个话题进行研究),
那么你必须先通过调用 create_plan 来创建一个计划。
否则,你可以直接执行用户的提问,无需制定计划。
2. 如果plan已经创建
2.1. 如果所有subtask的state都是todo,hint如下:
"The current plan:\n"
"```\n"
"{plan}\n"
"```\n"
"Your options include:\n"
"- Mark the first subtask as 'in_progress' by calling "
"'update_subtask_state' with subtask_idx=0 and state='in_progress', "
"and start executing it.\n"
"- If the first subtask is not executable, analyze why and what you "
"can do to advance the plan, e.g. ask user for more information, "
"revise the plan by calling 'revise_current_plan'.\n"
"- If the user asks you to do something unrelated to the plan, "
"prioritize the completion of user's query first, and then return "
"to the plan afterward.\n"
"- If the user no longer wants to perform the current plan, confirm "
"with the user and call the 'finish_plan' function.\n"
这hint意思是:
当前计划:
{plan}
你的选项包括:
通过调用 update_subtask_state,将第一个子任务标记为“进行中”(subtask_idx=0, state='in_progress'),并开始执行它。
如果第一个子任务无法执行,分析原因以及你能采取什么措施来推进计划,例如向用户询问更多信息,或通过调用 revise_current_plan 来修改当前计划。
如果用户让你做一些与当前计划无关的事情,优先完成用户的这一请求,然后再回到原计划。
如果用户不想继续执行当前计划,请与用户确认,然后调用 finish_plan 函数。}
2.2. 如果有一个subtask的state都是in_progress,hint如下:
"The current plan:\n"
"```\n"
"{plan}\n"
"```\n"
"Now the subtask at index {subtask_idx}, named '{subtask_name}', is "
"'in_progress'. Its details are as follows:\n"
"```\n"
"{subtask}\n"
"```\n"
"Your options include:\n"
"- Go on execute the subtask and get the outcome.\n"
"- Call 'finish_subtask' with the specific outcome if the subtask is "
"finished.\n"
"- Ask the user for more information if you need.\n"
"- Revise the plan by calling 'revise_current_plan' if necessary.\n"
"- If the user asks you to do something unrelated to the plan, "
"prioritize the completion of user's query first, and then return to "
"the plan afterward."
这hint意思是:
当前计划:
{plan}
现在,索引为 {subtask_idx}、名为“{subtask_name}”的子任务状态为“进行中”。其详情如下:
{subtask}
你的选项包括:
继续执行该子任务并获取结果。
如果子任务已完成,则调用“finish_subtask”并附带具体结果。
如需更多信息,可询问用户。
如有必要,可通过调用“revise_current_plan”来修改计划。
如果用户要求你执行与计划无关的操作,请优先完成用户的询问,之后再返回计划。
2.3. 如果所有subtask的state都是done或abandoned,hint如下:
"The current plan:\n"
"```\n"
"{plan}\n"
"```\n"
"All the subtasks are done. Now your options are:\n"
"- Finish the plan by calling 'finish_plan' with the specific "
"outcome, and summarize the whole process and outcome to the user.\n"
"- Revise the plan by calling 'revise_current_plan' if necessary.\n"
"- If the user asks you to do something unrelated to the plan, "
"prioritize the completion of user's query first, and then return to "
"the plan afterward."
这hint意思是:
当前计划:
{plan}
所有子任务均已完成。现在你的选项包括:
通过调用“finish_plan”并附带具体结果来结束计划,并向用户总结整个过程及结果。
如有必要,可通过调用“revise_current_plan”来修改计划。
如果用户要求你执行与计划无关的操作,请优先完成用户的询问,之后再返回计划。
2.3. 如果没有subtask的state是in_progress且有些subtask的state是done,hint如下:
"The current plan:\n"
"```\n"
"{plan}\n"
"```\n"
"The first {index} subtasks are done, and there is no subtask "
"'in_progress'. Now Your options include:\n"
"- Mark the next subtask as 'in_progress' by calling "
"'update_subtask_state', and start executing it.\n"
"- Ask the user for more information if you need.\n"
"- Revise the plan by calling 'revise_current_plan' if necessary.\n"
"- If the user asks you to do something unrelated to the plan, "
"prioritize the completion of user's query first, and then return to "
"the plan afterward."
这hint意思是:
当前计划:
{plan}
前 {index} 个子任务已完成,当前没有处于“进行中”状态的子任务。现在你的选项包括:
通过调用“update_subtask_state”将下一个子任务标记为“进行中”,并开始执行它。
如需更多信息,可询问用户。
如有必要,可通过调用“revise_current_plan”来修改计划。
如果用户要求你执行与计划无关的操作,请优先完成用户的询问,之后再返回计划。
问题:hint通过user msg添加到短期记忆(agent上下文)中后,会长期驻在里面吗?
答:不会,每次reasoning 推理后,会删除hint user msg

可以看出最后通过self.memory.delete_by_mark(mark=_MemoryMark.HINT)删除。
四、agent上下文输出
我这里用户输入:帮我做一个agent创业的行业报告,agent上下文日志如下:
agent第一步推理(reasoning)上下文: [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "帮我做一个agent创业的行业报告"
},
{
"role": "user",
"content": "<system-hint>If the user's query is complex (e.g. programming a website, game or app), or requires a long chain of steps to complete (e.g. conduct research on a certain topic from different sources), you NEED to create a plan first by calling 'create_plan'. Otherwise, you can directly execute the user's query without planning.</system-hint>"
}
]
agent第二步推理(reasoning)上下文: [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "帮我做一个agent创业的行业报告"
},
{
"role": "assistant",
"content": [],
"tool_calls": [
{
"id": "call_7668a177212a4a5b865fa6",
"type": "function",
"function": {
"name": "create_plan",
"arguments": "{\"name\": \"Agent创业行业报告\", \"description\": \"进行市场研究以创建一个关于agent创业的行业报告。这将包括确定关键趋势,识别主要参与者,分析市场需求,并提供可行的建议。\", \"expected_outcome\": \"一份全面的行业报告,涵盖了有关agent创业的主要发现和见解。\", \"subtasks\": [{\"name\": \"定义目标与范围\", \"description\": \"明确报告的目标受众,确定需要涵盖的关键领域,例如市场趋势、竞争格局等。\", \"expected_outcome\": \"清晰定义的目标和报告范围文档。\"}, {\"name\": \"收集行业数据\", \"description\": \"从可靠来源搜集关于agent行业的相关数据,包括市场规模、增长率、主要参与者等信息。\", \"expected_outcome\": \"整理好的行业数据集。\"}, {\"name\": \"分析市场趋势\", \"description\": \"基于收集的数据,分析当前市场趋势以及它们对agent创业的影响。\", \"expected_outcome\": \"详细的市场趋势分析报告。\"}, {\"name\": \"识别主要竞争对手\", \"description\": \"找出该领域的领先企业和新兴公司,并总结它们的优势和劣势。\", \"expected_outcome\": \"竞争对手概览及其SWOT分析。\"}, {\"name\": \"评估市场需求\", \"description\": \"通过调查或现有研究来了解目标客户的需求和偏好。\", \"expected_outcome\": \"市场需求评估报告。\"}, {\"name\": \"撰写报告草稿\", \"description\": \"整合所有子任务的研究成果,形成一份初步的行业报告草稿。\", \"expected_outcome\": \"行业报告初稿。\"}, {\"name\": \"审查与修改\", \"description\": \"审阅报告草稿,确保内容准确无误且逻辑连贯。必要时进行修改。\", \"expected_outcome\": \"最终版本的行业报告。\"}]}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_7668a177212a4a5b865fa6",
"content": "Plan 'Agent创业行业报告' created successfully.",
"name": "create_plan"
},
{
"role": "user",
"content": "<system-hint>The current plan:\n```\n# Agent创业行业报告\n**Description**: 进行市场研究以创建一个关于agent创业的行业报告。这将包括确定关键趋势,识别主要参与者,分析市场需求,并提供可行的建议。\n**Expected Outcome**: 一份全面的行业报告,涵盖了有关agent创业的主要发现和见解。\n**State**: todo\n**Created At**: 2026-03-31 21:33:10.790\n## Subtasks\n- [ ] 定义目标与范围\n- [ ] 收集行业数据\n- [ ] 分析市场趋势\n- [ ] 识别主要竞争对手\n- [ ] 评估市场需求\n- [ ] 撰写报告草稿\n- [ ] 审查与修改\n```\nYour options include:\n- Mark the first subtask as 'in_progress' by calling 'update_subtask_state' with subtask_idx=0 and state='in_progress', and start executing it.\n- If the first subtask is not executable, analyze why and what you can do to advance the plan, e.g. ask user for more information, revise the plan by calling 'revise_current_plan'.\n- If the user asks you to do something unrelated to the plan, prioritize the completion of user's query first, and then return to the plan afterward.\n- If the user no longer wants to perform the current plan, confirm with the user and call the 'finish_plan' function.\n</system-hint>"
}
]
agent第三步推理(reasoning)上下文: [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "帮我做一个agent创业的行业报告"
},
{
"role": "assistant",
"content": [],
"tool_calls": [
{
"id": "call_7668a177212a4a5b865fa6",
"type": "function",
"function": {
"name": "create_plan",
"arguments": "{\"name\": \"Agent创业行业报告\", \"description\": \"进行市场研究以创建一个关于agent创业的行业报告。这将包括确定关键趋势,识别主要参与者,分析市场需求,并提供可行的建议。\", \"expected_outcome\": \"一份全面的行业报告,涵盖了有关agent创业的主要发现和见解。\", \"subtasks\": [{\"name\": \"定义目标与范围\", \"description\": \"明确报告的目标受众,确定需要涵盖的关键领域,例如市场趋势、竞争格局等。\", \"expected_outcome\": \"清晰定义的目标和报告范围文档。\"}, {\"name\": \"收集行业数据\", \"description\": \"从可靠来源搜集关于agent行业的相关数据,包括市场规模、增长率、主要参与者等信息。\", \"expected_outcome\": \"整理好的行业数据集。\"}, {\"name\": \"分析市场趋势\", \"description\": \"基于收集的数据,分析当前市场趋势以及它们对agent创业的影响。\", \"expected_outcome\": \"详细的市场趋势分析报告。\"}, {\"name\": \"识别主要竞争对手\", \"description\": \"找出该领域的领先企业和新兴公司,并总结它们的优势和劣势。\", \"expected_outcome\": \"竞争对手概览及其SWOT分析。\"}, {\"name\": \"评估市场需求\", \"description\": \"通过调查或现有研究来了解目标客户的需求和偏好。\", \"expected_outcome\": \"市场需求评估报告。\"}, {\"name\": \"撰写报告草稿\", \"description\": \"整合所有子任务的研究成果,形成一份初步的行业报告草稿。\", \"expected_outcome\": \"行业报告初稿。\"}, {\"name\": \"审查与修改\", \"description\": \"审阅报告草稿,确保内容准确无误且逻辑连贯。必要时进行修改。\", \"expected_outcome\": \"最终版本的行业报告。\"}]}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_7668a177212a4a5b865fa6",
"content": "Plan 'Agent创业行业报告' created successfully.",
"name": "create_plan"
},
{
"role": "assistant",
"content": [],
"tool_calls": [
{
"id": "call_71cb9937251448f5a230aa",
"type": "function",
"function": {
"name": "update_subtask_state",
"arguments": "{\"subtask_idx\": 0, \"state\": \"in_progress\"}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_71cb9937251448f5a230aa",
"content": "Subtask at index 0, named '定义目标与范围' is marked as 'in_progress' successfully. The plan state has been updated to 'in_progress'.",
"name": "update_subtask_state"
},
{
"role": "user",
"content": "<system-hint>The current plan:\n```\n# Agent创业行业报告\n**Description**: 进行市场研究以创建一个关于agent创业的行业报告。这将包括确定关键趋势,识别主要参与者,分析市场需求,并提供可行的建议。\n**Expected Outcome**: 一份全面的行业报告,涵盖了有关agent创业的主要发现和见解。\n**State**: in_progress\n**Created At**: 2026-03-31 21:33:10.790\n## Subtasks\n- [ ] [WIP]定义目标与范围\n- [ ] 收集行业数据\n- [ ] 分析市场趋势\n- [ ] 识别主要竞争对手\n- [ ] 评估市场需求\n- [ ] 撰写报告草稿\n- [ ] 审查与修改\n```\nNow the subtask at index 0, named '定义目标与范围', is 'in_progress'. Its details are as follows:\n```\n- [ ] [WIP]定义目标与范围\n\t- Created At: 2026-03-31 21:33:10.790\n\t- Description: 明确报告的目标受众,确定需要涵盖的关键领域,例如市场趋势、竞争格局等。\n\t- Expected Outcome: 清晰定义的目标和报告范围文档。\n\t- State: in_progress\n```\nYour options include:\n- Go on execute the subtask and get the outcome.\n- Call 'finish_subtask' with the specific outcome if the subtask is finished.\n- Ask the user for more information if you need.\n- Revise the plan by calling 'revise_current_plan' if necessary.\n- If the user asks you to do something unrelated to the plan, prioritize the completion of user's query first, and then return to the plan afterward.</system-hint>"
}
]
不用太关注效果😄,因为很多tool没添加,比如网络搜索tool。
更多推荐



所有评论(0)