ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Open Interpreter 计划模式深度解析:plan.md 如何定义一套“决策完整“的协作规划协议

Open Interpreter 计划模式深度解析:plan.md 如何定义一套“决策完整“的协作规划协议 Open Interpreter 计划模式深度解析plan.md 如何定义一套决策完整的协作规划协议【免费下载链接】openinterpreterA coding agent for open models like Kimi K3项目地址: https://gitcode.com/GitHub_Trending/op/openinterpreter本文以 codex-rs/collaboration-mode-templates/templates/plan.md 这份计划模式Plan Mode协作模板为骨架完整拆解其三阶段工作流、执行/变更行为边界、提问策略与proposed_plan定稿规则并结合仓库中模式注入、模板加载、流式解析与update_plan工具拦截的源码实现说明这套提示词协议在 openinterpreterCodex 系 CLI/TUI中是如何被编译进会话上下文并被客户端消费的。读完后你既能逐条掌握计划模式的运作规则也能从源码层面理解其落地链路。1. plan.md 的定位一份被编译进二进制的开发者指令plan.md 不是一篇普通文档而是 Plan 模式生效时注入给模型的核心开发者指令。它的加载方式非常直接src/lib.rs 中仅两行代码pub const PLAN: str include_str!(../templates/plan.md);与pub const DEFAULT: str include_str!(../templates/default.md);。模板在编译期被内联进 crate 二进制运行时无需文件读取保证了模板内容与发布版本严格一致。models-manager/src/collaboration_mode_presets.rs 中的plan_preset()把COLLABORATION_MODE_PLAN作为developer_instructions装配进 Plan 模式预设并固定了ReasoningEffort::Medium的推理档位与之相对的是default_preset()加载 default.md后者要求优先做出合理假设并直接执行且把模板中{{KNOWN_MODE_NAMES}}占位符渲染为当前可见模式名列表。从源码结构看模板的优先级还有一层细节core/src/context/world_state/collaboration_mode.rs 的from_collaboration_mode()会优先取模型目录catalog下发的指令仅在其缺失时才回退到预设中的developer_instructions。也就是说plan.md 是内置兜底版本模型服务方仍可用CollaborationModeMessages覆盖它。模式切换由 TUI 侧驱动tui/src/collaboration_modes.rs 提供next_mask()按预设顺序循环切换模式、plan_mask()直接取 Plan 预设而模式枚举定义在 protocol/src/config_types.rspub enum ModeKind { Plan, #[default] #[serde( alias code, alias pair_programming, alias execute, alias custom )] Default, } pub const TUI_VISIBLE_COLLABORATION_MODES: [ModeKind; 2] [ModeKind::Default, ModeKind::Plan];值得注意的是Default上挂着code/pair_programming/execute等 serde 别名——从代码结构看这是为了兼容旧配置中把默认执行模式叫作code/execute的命名习惯。2. 计划模式的总纲聊天式收敛到决策完整的规划plan.md 开宗明义第 1-3 行You work in 3 phases, and you shouldchat your wayto a great plan before finalizing it. A great plan is very detailed—intent- and implementation-wise—so that it can be handed to another engineer or agent to be implemented right away. It must bedecision complete, where the implementer does not need to make any decisions.即Agent 分三阶段工作在定稿前要通过对话把一个计划打磨到决策完整decision complete——细节详尽到可以直接交给另一位工程师或另一个 Agent 立即实现实现者不需要再做任何决策。这是整份模板的北极星指标后续所有规则先探索后提问、多问问题、定稿门槛都是为它服务的。3. 模式规则Plan Mode 只能由开发者消息显式结束plan.md 的 Mode rules (strict) 一节确立了两条硬规则只有开发者消息developer message显式结束 Plan Mode 时才退出例如切回 Default 模式时注入的 default.md 开发者指令Any previous instructions for other modes (e.g. Plan mode) are no longer active.用户意图、语气或祈使句都不能改变模式。用户在 Plan Mode 里说直接帮我做应被理解为规划这个执行过程而不是执行它。这与注入机制吻合collaboration_mode.rs 中CollaborationModeState实现WorldStateSectionrender_diff()只在模式或模型发生变化时向历史追加一段用COLLABORATION_MODE_OPEN_TAG/CLOSE_TAG包裹的 developer 角色片段。换言之模式状态是通过世界状态的 diff 注入实现的普通用户消息不会触发模式切换——模板中模式由开发者消息控制的措辞正是对这一运行时事实的镜像。4. Plan Mode 与 update_plan 工具两个极易混淆的概念模板单列一节区分二者这是理解该协议的关键Plan Mode是一种协作模式流程上可能向用户发起输入请求并最终产出一个proposed_plan块。update_plan是一个独立的清单/进度/TODO 工具它不进入也不退出Plan Mode二者不可混用在 Plan 模式下调用update_plan会直接报错。仓库源码精确印证了最后一点。core/src/tools/handlers/plan.rs 的PlanHandler在处理调用时if turn.mode ModeKind::Plan { return Err(FunctionCallError::RespondToModel( update_plan is a TODO/checklist tool and is not allowed in Plan mode.to_string(), )); }即当当前 turn 处于 Plan 模式时update_plan不会执行、不会发EventMsg::PlanUpdate而是把一条工具不允许在 Plan 模式使用的错误回传给模型——模型据此自行改道改为通过对话和proposed_plan块推进规划。非 Plan 模式下update_plan才正常解析UpdatePlanArgs并广播计划更新事件。5. 行为边界允许探索执行禁止变更执行plan.md 的 Execution vs. mutation in Plan Mode 一节给出了一条清晰的分界线可以执行**非变更性non-mutating且有利于改善计划的动作但绝不能执行变更性mutating**动作。5.1 允许的动作探索类以获取真相、消除歧义、验证可行性且不改变仓库受跟踪状态为判据允许读取/搜索文件、配置、schema、类型、manifest 与文档静态分析、检视与仓库探索不编辑受跟踪文件的 dry-run 式命令允许写缓存/构建产物如target/、.cache/、快照的测试、构建与检查前提是不编辑仓库受跟踪的文件。5.2 禁止的动作执行类凡是实现计划或改变受跟踪状态的动作都禁止编辑或写入文件运行会重写文件的格式化器/linter应用会更新受跟踪文件的补丁、迁移、代码生成目的为执行计划而非打磨计划的带副作用命令。模板给出了一个可操作的判定口诀第 39 行When in doubt: if the action would reasonably be described as doing the work rather than planning the work, do not do it.拿不准时如果一个动作会被描述为干活而非规划活就别干。6. 三阶段工作流先落地环境再谈意图最后谈实现PHASE 1 — Ground in the environment探索优先提问其次先在实际环境中扎根用发现事实而非向用户提问的方式消除 prompt 中的未知项只有环境推导不出的缺失/歧义才允许记录为待问问题允许并鼓励回合之间的静默探索。硬性前置条件除非本地没有仓库/环境在向用户提问前至少完成一轮有针对性的非变更探索搜索相关文件、检视可能的入口点/配置、确认当前实现形态。例外仅当 prompt 本身存在明显歧义或矛盾时才可以在探索前澄清但只要歧义可能通过探索解决一律先探索。禁止问仓库或系统能回答的问题例如这个 struct 在哪该用哪个 UI 组件——探索即可确认。只有穷尽了合理的非变更探索才开口提问。PHASE 2 — Intent chat搞清楚用户到底要什么持续追问直到能够清楚陈述六要素目标 成功标准、受众、范围内/范围外、约束、当前状态、关键偏好/权衡。核心偏置是提问优于猜测Bias toward questions over guessing只要还剩下任何高影响的歧义就不要开始规划先问。PHASE 3 — Implementation chat我们用什么方式/如何构建意图稳定后继续追问直到规格决策完整覆盖清单技术方案、接口API/schema/输入输出、数据流、边界情况/失败模式、测试 验收标准、发布/监控以及迁移/兼容性约束。7. 提问协议问题必须改变计划才值得问7.1 工具优先与选项质量强烈优先使用request_user_input工具提问只给出有意义的多选选项不要放明显错误或无关的凑数选项极少数情况下若问题极端模糊、无法用合理多选表达可以直接不用工具提问。每个问题必须满足满足其一即可且均不能通过非变更命令自行解答实质性地改变规格/计划确认/锁定某个假设在真实有意义的权衡之间做选择。request_user_input工具在 Plan 模式下的可用性由代码层面背书config_types.rs 中ModeKind::allows_request_user_input()仅对Plan返回 true——这正是该工具主要服务于 Plan 模式的实现依据。7.2 两类未知项区别对待可发现事实仓库/系统事实先探索。提问前先做定向搜索、检查可能的真相来源配置/manifest/入口点/schema/类型/常量。只有以下三种情况才允许提问存在多个可信候选什么也没找到但缺少关键标识符/上下文歧义本身就是产品意图。且提问时要给出具体候选路径/服务名并推荐一个。绝不问这个 struct 在哪这类自己能答的问题。偏好/权衡不可探索发现尽早问。给出 2–4 个互斥选项 一个推荐默认值若用户未回答就按推荐选项继续并在最终计划中把它记录为假设。8. 定稿规则与proposed_plan协议8.1 何时允许输出最终计划只有当计划决策完整、不给实现者留下任何决策时才输出。呈现正式计划时必须用proposed_plan块包裹以便客户端特殊渲染格式五条开标签独占一行计划内容从下一行开始与开标签不同行;闭标签独占一行块内使用 Markdown标签名严格保持proposed_plan//proposed_plan即使计划内容使用其他语言也不得翻译或改名。8.2 计划正文的写作规范plan.md 对最终计划的内容密度做了非常细粒度的规定值得逐条继承内容必须对人和 Agent 都可消化默认仅计划、简洁且必须包含清晰的标题、简要摘要、公共 API/接口/类型的重要变更、测试用例与场景、显式假设与默认值优先采用 3–5 个短小节通常是 Summary、Key Changes / Implementation Changes、Test Plan、Assumptions除非范围边界对避免出错确有必要不设独立 Scope 小节按子系统或行为分组列实现要点避免逐文件清单仅在必要时点名文件以消除歧义非必要不超过 3 个路径行为级描述优于逐符号的删改清单对 v1 新增功能计划不要凭空发明详细的 schema、校验、优先级、回退或 wire-shape 策略除非需求已建立或为防止具体实现错误所必需要点保持短小避免解释性子弹点除非确有必要消除歧义压缩同类变更省略分支逻辑、重复不变量、未受影响的长清单简单重构的计划应压缩为紧凑摘要 关键编辑 测试 假设用户要更多细节时再展开。8.3 结尾与块数量约束最终输出中不要问是否继续——用户看到proposed_plan块后可自由退出 Plan 模式要求实现或留在 Plan 模式继续打磨每轮最多一个proposed_plan块且仅在呈现完整规格时产生若用户在前一计划后要求修订新块必须是完整替代若用户表示不认可但未给出足够信息产出完整替代版则先回应关切、继续规划、不产出proposed_plan块若后续消息既不需要修改也不质疑计划如澄清性问题则先作答再原样复述此前的proposed_plan块。9. 客户端侧proposed_plan块的流式解析实现plan.md 要求标签独占一行、内容从下一行开始并非空穴来风——它精确匹配了仓库中解析器的设计。utils/stream-parser/src/proposed_plan.rs 中的ProposedPlanParser基于TaggedLineParser识别OPEN_TAG proposed_plan与CLOSE_TAG /proposed_plan实现StreamTextParser接口把模型输出流切分为ProposedPlanStart/ProposedPlanDelta(text)/ProposedPlanEnd事件序列同时把标签外的文本收集为visible_text行级标签识别意味着开标签必须独占一行是协议的一部分测试preserves_non_tag_lines明确验证了 proposed_plan extra缩进/行尾有其他内容不会被识别为标签会原样保留为普通文本——这正是模板第 98 行规则的底层原因流结束时closes_unterminated_plan_block_on_finish测试验证未闭合的块会被自动闭合避免渲染悬空状态非流式场景提供strip_proposed_plan_blocks()剥离计划块留下正文与extract_proposed_plan_text()提取最后一个块内的计划文本两个工具函数供历史记录、导出等复用。这意味着模型按 plan.md 输出规范块 → TUI/app-server 流式解析为独立事件 → 客户端把计划渲染为特殊卡片、正文只留说明文字。模板规范与解析器协议是一一对应的契约。10. 端到端链路小结把散落的源码证据串起来plan.md 的完整生命周期是编译期src/lib.rs 用include_str!将 plan.md 内联为PLAN常量模式装配collaboration_mode_presets.rs 以该常量构造 Plan 预设含 Medium 推理档位TUI 通过 collaboration_modes.rs 在 Default/Plan 间切换上下文注入collaboration_mode.rs 的世界状态 diff 机制在模式变化时以 developer 角色片段把指令注入会话历史模型目录下发指令优先plan.md 为内置回退行为约束Plan 模式下update_plan工具被 plan.rs 硬拦截request_user_input则仅 Plan 模式可用ModeKind::allows_request_user_input产出消费模型按模板规范输出proposed_plan块proposed_plan.rs 流式解析为事件供客户端渲染用户随后可退出 Plan 模式执行或继续修订。11. 适用前提与限制本文所有行为描述以当前仓库代码为准模板内容随 crate 编译固化运行时修改仓库文件不会热生效模板中的工具名request_user_input、update_plan依赖对应工具在当前会话可用——default.md 也明确要求仅当本轮工具列表中包含request_user_input时才使用Plan 模式预设固定了 Medium 推理档位这是 collaboration_mode_presets.rs 中的内置默认具体模型是否支持相应推理档位仍受模型目录约束若模型目录通过CollaborationModeMessages下发了 plan 指令内置 plan.md 仅作为回退实际生效内容以注入上下文者为准从from_collaboration_mode()的优先级逻辑推断。对维护协作式编码 Agent 的团队而言plan.md 的价值在于它把规划质量从模型的自然倾向提升为可测试的协议提问有判据是否改变计划、探索有门槛先探索后提问、行为有边界非变更 vs 变更、产出有格式proposed_plan块与解析器一一对应。这种提示词即契约、契约有解析器兜底的设计是开源仓库里一个值得参考的工程样本。【免费下载链接】openinterpreterA coding agent for open models like Kimi K3项目地址: https://gitcode.com/GitHub_Trending/op/openinterpreter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表