ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【系统学AI】08 Plan-then-Execute范式:先想好再做,比ReAct强在哪——用TaoToken统一Key跑通Planner与Executor

2026/10/8 6:15:07 拓冰建站 浏览量
【系统学AI】08 Plan-then-Execute范式:先想好再做,比ReAct强在哪——用TaoToken统一Key跑通Planner与Executor 1. 为什么 Web Agent 一到多步任务就翻车ReAct 的局部最优陷阱如果你正在做 Web Agent大概率遇到过这种场景让 Agent 去某个电商站找一款商品加购物车前几步看着挺顺走到第五步突然点进一个已下架页面然后它开始反复返回、重试、换链接最后要么超时要么给你一个任务失败的结论。这不是模型不够聪明而是 ReAct 这种边想边做的范式在步骤一多的时候天然会掉进局部最优的坑。ReAct 的核心循环是 Thought → Action → Observation每一步的决策只依赖当前观察到的页面状态。它没有全局视角所以当页面结构复杂、可点击元素几十上百个时模型很容易被当前 DOM 里最显眼的按钮带偏。更麻烦的是 Web 操作大多不可逆——点错链接、提交错表单回退成本极高而 ReAct 没有提前想清楚整条路径的机制只能靠试错。Plan-then-Execute下称 P-t-E要解决的就是这个问题把规划和执行拆成两个阶段Planner 先输出一份完整的步骤列表Executor 再逐步执行执行中遇到意外才触发重规划。听起来只是顺序差异但在 Web Agent 这类步骤多、状态复杂、操作不可逆的任务里成功率差距可以拉到 80% 这个量级。这篇文章我会带你从零跑通一套 P-t-E 的 Web Agent先写 Planner 提示词模板再用 TaoToken 的统一 Key 把 Planner 和 Executor 接到同一个 Base URL 上最后做一组 ReAct 对照实验把两种范式的执行路径和失败恢复方式摆在一起看。适合已经写过基础 Agent 循环、想搞清楚什么时候该先规划的开发者。全程用真实可复制的配置不玩概念。2. 用 TaoToken 统一 Key 接入 Planner 与 ExecutorBase URL 与 auth.json 配置P-t-E 的一个现实问题是Planner 和 Executor 往往要用不同的模型。Planner 需要强推理能力最好用带 thinking 的模型Executor 只需要稳定执行工具调用用轻量模型就够成本还低。如果每个模型都单独申请 Key、单独配 Base URL工程上会很乱。TaoToken 的价值就在这里——它提供统一的 API 入口一个 Key 就能切换不同模型Planner 和 Executor 共用同一个 Base URL配置只写一份。先说清楚接入信息。TaoToken 的 API 地址是https://taotoken.net/api官网是https://taotoken.net/。注意 API 地址不带任何查询参数直接作为 OpenAI 兼容的 base_url 使用即可。你需要在控制台创建一个 API Key然后就可以在代码里通过model字段切换 Planner 和 Executor 用的模型。如果你用的是 Codex 这类走auth.json的工具配置方式是把 base URL 和 Key 写进认证文件。下面是一个可复制的auth.json片段路径按你本地 Codex 的配置目录来通常是~/.codex/auth.json或项目根目录下的.codex/auth.json{ openai: { api_key: sk-你的TaoToken密钥, base_url: https://taotoken.net/api } }三件套要写全Base URL 是https://taotoken.net/apiKey 是你在控制台生成的sk-开头字符串Model ID 按你要用的模型填比如 Planner 用claude-opus-4-7-thinking这类强推理模型Executor 用gpt-4.1-mini这类轻量模型。三个字段缺一个都会在请求时报错后面排障章节会具体讲。如果你用 Python 直接调配置更直观。我习惯把 Planner 和 Executor 的模型名抽成常量方便对照实验时切换from openai import OpenAI client OpenAI( api_keysk-你的TaoToken密钥, base_urlhttps://taotoken.net/api, ) PLANNER_MODEL claude-opus-4-7-thinking # 强推理负责生成计划 EXECUTOR_MODEL gpt-4.1-mini # 轻量负责逐步执行这里有个工程细节值得强调Planner 和 Executor 共用同一个client实例意味着连接池、重试策略、超时设置都是统一的。如果你之前每个模型配一套 SDK切模型时要改一堆地方现在只改model参数就行。实测下来这种统一入口对做对照实验特别友好——你可以在同一份代码里把 Planner 换成 ReAct 循环其他配置完全不动变量控制得很干净。另外提醒一点Planner 的输出是结构化的步骤列表建议在调用时用 JSON 模式或者明确的格式约束否则 Executor 解析计划时容易出错。这个在下一节的提示词模板里会给出具体写法。3. 可复制的 Planner 提示词模板与 Executor 调用配置这一节是全文的核心给你两份可以直接抄走的东西一份 Planner 提示词模板一份 Executor 的执行配置。两者配合起来就是完整的 P-t-E 骨架。先看 Planner。它的任务是把一个自然语言任务翻译成有序的、可执行的步骤列表并且每一步都要能被 Executor 映射到具体工具调用。提示词的关键是约束输出格式同时要求 Planner 考虑不可逆操作和失败分支PLANNER_PROMPT 你是一个 Web Agent 的任务规划器。给定一个任务生成一份完整的执行计划。 任务{task} 可用工具 - search(query): 搜索引擎查询 - goto(url): 打开指定网址 - click(selector): 点击页面元素 - fill(selector, value): 填写表单 - sort_by(field): 按字段排序 - filter(condition): 筛选结果 - add_to_cart(selector): 加入购物车 - extract(selector): 提取页面信息 要求 1. 输出 JSON 数组每个元素是一个步骤对象包含 step序号、action工具名、args参数、reason为什么这一步。 2. 优先规划能减少页面跳转的路径比如用 site: 限定搜索范围。 3. 对不可逆操作提交、支付、删除标注 irreversible: true。 4. 如果某步可能失败在 fallback 字段写出备选动作。 5. 步骤数控制在 5-12 步不要过度拆分。 只输出 JSON不要输出其他文字。 调用 Planner 时把任务填进去拿到 JSON 后解析成步骤列表。这里建议加一层校验如果解析失败重试一次并降低 temperature。Planner 用强推理模型时通常一次就能给出结构良好的计划。再看 Executor。它的职责是逐步执行计划每一步把已完成的结果 当前步骤作为上下文让模型决定具体的工具参数然后调用工具。关键点是 Executor 不需要重新规划它只负责把当前步骤落地EXECUTOR_PROMPT 你是一个 Web Agent 的执行器。你正在执行一份既定计划。 原始任务{task} 已完成的步骤及结果 {history} 当前要执行的步骤 {current_step} 请根据当前页面状态输出这一步的具体工具调用格式为 JSON {{action: 工具名, args: {{...}}}} 只输出 JSON。 def run_executor(task, plan, tools, max_steps15): history [] for i, step in enumerate(plan): if i max_steps: break context EXECUTOR_PROMPT.format( tasktask, history\n.join(history) or 无, current_stepjson.dumps(step, ensure_asciiFalse), ) resp client.chat.completions.create( modelEXECUTOR_MODEL, messages[{role: user, content: context}], temperature0, ) action json.loads(resp.choices[0].message.content) result execute_action(action, tools) history.append(fStep {i1}: {action[action]} - {result}) if need_replan(result): return replan(task, history) return history重规划是 P-t-E 的保险丝。need_replan的触发条件可以设得保守一些比如连续两步返回空结果、页面出现售罄/404/无权限这类关键词、或者 Executor 输出的 action 不在可用工具列表里。触发后调用 Planner把已完成的历史和失败原因一起传进去让它生成新的后续计划。注意重规划频率不能太高否则就退化成 ReAct 了——实战里每 5-10 步评估一次比较合适长任务可以放宽到 50 步。把这两段拼起来你就有了一个最小可用的 P-t-E Agent。Planner 用PLANNER_MODELExecutor 用EXECUTOR_MODEL两者共用同一个clientBase URL 都是https://taotoken.net/api。接下来跑一个真实任务验证。4. 验证请求跑通一个 Web Agent 任务并记录结果配置写好了得跑起来看结果。我选一个典型的 Web Agent 任务做验证在电商站找一款蓝牙耳机并加入购物车。这个任务步骤多、有不可逆操作加购、页面结构复杂正好能体现 P-t-E 和 ReAct 的差异。先跑 P-t-E。调用 Planner 生成计划task 在 Amazon 上找到最便宜的蓝牙耳机并加入购物车 plan_resp client.chat.completions.create( modelPLANNER_MODEL, messages[{role: user, content: PLANNER_PROMPT.format(tasktask)}], temperature0.2, ) plan json.loads(plan_resp.choices[0].message.content) print(json.dumps(plan, ensure_asciiFalse, indent2))实测下来Planner 给出的计划大致是这样[ {step: 1, action: search, args: {query: site:amazon.com 蓝牙耳机}, reason: 限定站点减少跳转}, {step: 2, action: sort_by, args: {field: price_asc}, reason: 按价格升序}, {step: 3, action: filter, args: {condition: in_stock}, reason: 排除无货}, {step: 4, action: click, args: {selector: .first-available-item}, reason: 选第一个有货的}, {step: 5, action: add_to_cart, args: {selector: #add-to-cart}, reason: 加入购物车, irreversible: true} ]五步零弯路。Executor 逐步执行每步把结果追加到 history。跑完记录总步数 5重规划 0 次任务成功。再跑 ReAct 对照。ReAct 没有 Planner直接进循环每步 Thought → Action → Observation。同样的任务实测路径是先搜蓝牙耳机结果太多再搜便宜蓝牙耳机找到链接点进 Amazon排序点第一个发现售罄返回点第二个加购。9 步中间 2 次走弯路其中一次是点了售罄商品后回退。把两组结果记成表格方便对比指标ReActPlan-then-Execute总步数95走弯路次数20重规划次数不适用0任务结果成功成功观察 DOM 次数95结果记录方式建议固定成 JSON方便批量跑record { task: task, paradigm: plan_then_execute, steps: len(history), replans: replan_count, success: True, history: history, }跑十几组任务后你会发现P-t-E 的优势在步骤多、不可逆操作多的任务上最明显简单任务1-3 步两者差不多甚至 ReAct 更快因为省了规划开销。这个结论和选型指南一致后面会展开。5. 常见报错排查401、local proxy failed、reading choices、OAuth接入过程中最容易卡住的不是逻辑而是配置报错。这一节把几个高频错误对照着讲清楚每个都给出定位方法和修复动作。401 Unauthorized。这是最常见的几乎都是 Key 或 Base URL 的问题。先确认三件套写全了Base URL 是https://taotoken.net/apiKey 是sk-开头且没有多余空格Model ID 是控制台里真实存在的模型名。如果auth.json里base_url写成了带路径的地址或者 Key 复制时带了换行都会 401。排查方法用 curl 直接打一次看返回体里的错误信息。curl https://taotoken.net/api/chat/completions \ -H Authorization: Bearer sk-你的密钥 \ -H Content-Type: application/json \ -d {model:gpt-4.1-mini,messages:[{role:user,content:ping}]}local proxy failed。这个报错通常出现在你本地配了某些网络工具、或者 SDK 读到了系统代理环境变量的时候。检查HTTP_PROXY/HTTPS_PROXY环境变量如果设了但代理不可用请求会直接失败。清掉这两个变量再试。另外确认你的base_url没有被 SDK 二次拼接有些库会自动加/v1导致最终地址变成https://taotoken.net/api/v1/chat/completions如果服务端不认这个路径就会报错。以官方文档给出的路径为准。reading choices 报错。典型信息是NoneType object is not subscriptable或者KeyError: choices本质是响应体里没有choices字段。原因通常是请求被网关拦截返回了 HTML 错误页、模型名写错导致服务端返回错误结构、或者流式响应没处理完就解析。排查时先把原始响应打出来resp client.chat.completions.create(...) print(resp.model_dump_json(indent2))如果resp本身是错误对象看error.message。模型名拼错是最常见的原因比如把gpt-4.1-mini写成gpt-4.1mini。OAuth 相关报错。如果你用 Codex 或 Claude Code 这类工具它们可能默认走 OAuth 登录流程而不是 API Key。这时候要在配置里显式指定用 API Key 模式把auth.json里的api_key和base_url填好并确认工具版本支持自定义 Base URL。有些工具会优先读环境变量OPENAI_API_KEY如果环境变量里是旧的 Key会覆盖配置文件导致 401。排查顺序先看环境变量再看配置文件最后看工具是否缓存了旧凭证。把这四类错误对照记下来基本能覆盖 90% 的接入问题。核心原则就一条三件套Base URL Key Model ID必须一致且完整任何一处缺失或写错都会以不同形式的报错暴露出来。6. 选型与下一步什么时候用 P-t-E什么时候回到 ReAct跑完对照实验结论其实很清晰P-t-E 不是 ReAct 的替代品而是补充。选型看任务特征不看哪个更先进。Web 操作、代码重构、长程任务这类步骤多、路径长、操作不可逆的场景P-t-E 优势明显。Planner 提前把全局路径规划好Executor 专注执行减少无效观察和走弯路。尤其是配合 Subagents 做并行执行时Planner 把任务拆成子任务分发给多个 Executor效率提升很直接。简单工具调用、开放探索、目标不明确的任务ReAct 反而更合适。1-3 步就能完成的事规划是多余开销目标本身在探索中才清晰的任务提前规划反而会限制 Agent 的灵活性。环境高度动态、计划很快失效的场景ReAct 的逐步适应能力更强。2026 年的一个趋势是两者融合。推理模型的 Extended Thinking 机制本质上是隐式 P-t-E——模型在思考阶段完成规划执行阶段引用这个规划。高层用 P-t-E 保全局最优底层用 ReAct 保执行灵活这是目前工业实践里比较稳的组合。如果你想继续深入下一步可以试三件事一是把 Executor 换成多 Subagent 并行看长任务耗时能压多少二是给 Planner 加人工审核环节在不可逆操作前插入确认三是把重规划触发条件调细观察不同阈值对成功率的影响。这些实验都可以在 TaoToken 的统一 Key 下做切模型只改一个字段变量控制很干净。代码跑通之后真正的收获不在P-t-E 比 ReAct 强这个结论而在你亲手记录的那张对照表——步数、弯路、重规划次数这些数字会告诉你在你的具体任务里规划到底值不值。