ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

oh-my-pi 会话交接(Handoff)上下文注入模板解析:让继任 Agent 无痕接管长任务的提示词工程实践

oh-my-pi 会话交接(Handoff)上下文注入模板解析:让继任 Agent 无痕接管长任务的提示词工程实践 oh-my-pi 会话交接Handoff上下文注入模板解析让继任 Agent 无痕接管长任务的提示词工程实践【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi会话压缩context compaction与 Agent 交接handoff是现代 Coding Agent 维持长任务连续性的核心机制。oh-my-pi 在 packages/agent/src/compaction/prompts/handoff-summary-context.md 中维护了一份专门用于“把前任 Agent 写好的交接文档注入继任 Agent 上下文”的提示词模板。本文将逐行拆解这份模板的设计意图结合 messages.ts 的注入链路、handoff-document.md 的文档生成规范以及 handoff.test.ts 的回归测试说明 oh-my-pi 如何通过上下文框架context framing避免继任 Agent 把交接文档误读为用户指令、重复生成交接文档或丢失已完成的进度并给出可直接借鉴的提示词工程范式。一、为什么需要一份独立的 Handoff 上下文模板在 oh-my-pi 的压缩体系中CompactionSettings.strategy支持context-full | handoff | shake | snapcompact | off等多种策略见 compaction.ts。其中handoff策略的含义是不把整段对话压成抽象摘要而是让当前 Agent 实例基于完整对话写出一份结构化“交接文档”handoff document由后继实例继续执行同一任务。交接文档与普通压缩摘要有一个本质区别它的作者是前任 Agent 自身且使用第一人称写作如## Goal、## Next Steps。当这份文档被当作普通摘要注入上下文时继任模型极容易犯两类错误把文档中第一人称的 “Next Steps” 误读成当前用户的新指令从而偏离真实任务把交接文档当成“待办事项”再次主动生成一份新的交接文档造成重复劳动与语义污染。这正是handoff-summary-context.md存在的意义——它不是生成文档的提示词而是给文档“框定身份”的元提示词framing prompt在文档进入上下文之前先把“你是谁、你看到的是什么”讲清楚。相关的修复记录见 CHANGELOG.md通过澄清上下文框架消除了会话交接后的 Agent 身份混淆确保继任实例无缝恢复既有执行计划。二、模板逐行解读九行提示词的设计意图handoff-summary-context.md全文只有九行但每一行都对应一个明确的语义约束。以下按原文顺序逐行解读。1. 上下文替换声明Context replaced. The handoff below is a handoff document a prior instance of you wrote from the full conversation. It is your own working memory, not user input.这一行完成三件事声明事实上下文已被替换当前看到的内容不再是完整对话而是交接文档澄清来源与作者文档由“之前的你a prior instance”基于完整对话写出属于 Agent 自己的工作记忆划清边界明确声明It is your own working memory, not user input——它不是用户输入后续任何解读都不能把它当作来自用户的指令。这是整个模板的基石先切断“文档即用户消息”的错误联想再建立“文档即自我记忆”的正确心智模型。2. 第一人称的归属规则- First person inside it refers to you (the prior instance).交接文档中的“我”指代前任实例也就是现在的你。这一条与第 1 行配合把文档中所有第一人称“I did X”“my attempt”映射到正确的角色防止继任者把前任的工作误解为其他 Agent 或用户的产出。3. Next Steps 的属性声明- Next Steps is your own resumed plan; re-check it against the latest user message before acting.Next Steps下一步计划是你自己的恢复计划而非用户指令。同时模板给出了可执行的行为要求在执行前必须对照最新一条用户消息重新校验该计划是否仍然有效。这解决的是长会话中“用户中途改需求、但旧计划仍被机械执行”的经典问题。4. 禁止重复生成交接文档- The handoff already exists and is complete: NEVER write another handoff document unless the user explicitly asks.明确告知模型交接文档已存在且完整不要再次生成。这是对第一节所述“身份混淆后重复写 handoff”问题的直接防御。测试 handoff.test.ts 中专门断言注入后的文本包含NEVER write another handoff document验证了这一约束确实被注入到继任者的上下文中。5. 强制建立在已有工作之上MUST build on prior work; NEVER duplicate prior work.要求继任者必须在既有进度之上继续推进不得重复已完成的工作。这保证了交接后任务只前进、不回退与交接文档中Progress章节Done / In Progress / Pending的设计相呼应。6. 交接文档的承载容器handoff {{summary}} /handoff交接文档正文被包裹在handoff//handoff标签对中{{summary}}是模板占位符由渲染器在运行时替换为真实的交接文档内容。结构化标签是提示词工程的关键手段它让模型可以清晰区分“框架指令”与“文档内容”两个区域同时为后续程序化解析如正则提取、边界判断保留了可靠的锚点。三、{{summary}} 占位符与模板渲染机制模板本身不包含任何交接内容{{summary}}是一个待填充的变量。在 oh-my-pi 中模板通过oh-my-pi/pi-utils提供的prompt.render完成渲染。packages/agent/src/compaction/messages.ts 中模板以文本资源形式导入并注册import handoffSummaryContextPrompt from ./prompts/handoff-summary-context.md with { type: text }; const HANDOFF_SUMMARY_TEMPLATE handoffSummaryContextPrompt;真正完成拼接的是renderHandoffSummaryContext见 messages.ts/** * Wrap a handoff document for injection into the successor context. Unlike the * generic compaction wrapper, this names the mechanism and pins authorship — * the document was written by a prior instance in its own voice, so without * this framing the successor misreads first-person Next Steps as fresh user * instructions (or tries to write the handoff again). */ export function renderHandoffSummaryContext(summary: string): string { return prompt.render(HANDOFF_SUMMARY_TEMPLATE, { summary }); }函数注释直接点明了设计动机与通用压缩包装器不同这个包装器点名机制names the mechanism并锁定作者身份pins authorship。如果不做这种框架处理继任者会把第一人称的 “Next Steps” 当作新用户指令或者再次尝试写交接文档。渲染时传入{ summary }即把文档正文填充到handoff{{summary}}/handoff的{{summary}}位置。四、注入链路convertMessageToLlm 中的 handoff 分支模板真正生效的位置在 messages.ts 的convertMessageToLlm函数——它负责把压缩摘要消息转换为发送给 Provider 的 LLM 消息。关键逻辑是按 method 分流case compactionSummary: return { role: user, content: message.blocks ! undefined ? [{ type: text as const, text: message.summary }, ...message.blocks] : [ { type: text as const, text: message.method handoff ? renderHandoffSummaryContext(message.summary) : renderCompactionSummaryContext(message.summary), }, ...(message.images ?? []), ], attribution: agent, historyRewriteAt: message.timestamp, providerPayload: message.providerPayload, timestamp: message.timestamp, };要点如下当压缩消息的method handoff由 createCompactionSummaryMessage 的 options 传入注释中注明可取值remote | soft | handoff等时使用renderHandoffSummaryContext包装即应用本节讨论的模板其余 method 走通用分支renderCompactionSummaryContext使用另一份模板 compaction-summary-context.md同样是summary{{summary}}/summary的结构但不含 handoff 的身份声明与禁止重复生成约束注入消息的role为userattribution为agent并携带historyRewriteAt时间戳标记这是一次历史重写而不是真实的用户消息。也就是说同样的交接文档内容使用 handoff 包装器与使用通用摘要包装器注入到模型面前的效果完全不同前者告诉模型“这是你自己的记忆不要重写、不要当指令”后者只是单纯地呈现一段历史摘要。五、交接文档从何而来handoff-document.md 的生成规范handoff-summary-context.md管的是“注入端”而交接文档本身由配套模板 handoff-document.md 在“生成端”产生。两份模板构成一个完整闭环先生成文档再为文档框定身份。handoff-document.md的核心要求是输出必须足够支撑无缝续接——即使后继实例完全无法访问当前对话仅凭这份文档也能继续工作。其关键设计包括只输出文档本体Output ONLY the handoff document. No preamble, no commentary, no wrapper text.记录精确技术状态而非抽象描述必须包含文件路径、符号名、执行过的命令、测试结果、观察到的失败、已做的决策、影响下一步的部分工作使用祈使句直呼继任者Register: address the successor directly in the imperative (Fix X, Run Y) — never first person (I need to…, my attempt…)——注意生成规范要求文档面向继任者使用祈使句而上一节的注入模板则向继任者解释“文档中的第一人称指代前任的你”两者在语义上互补共同消除人称歧义机制对文档不可见The handoff mechanism is invisible to the document: NEVER list writing, generating, or delivering a handoff/summary/context document as progress or a next step——交接文档中的 Progress 与 Next Steps 只记录用户任务本身不得把“写交接文档”这类机制性动作列为进度固定输出结构## Goal ## Constraints Preferences ## Progress ### Done ### In Progress ### Pending ## Key Decisions ## Critical Context ## Next Steps该模板还支持可选的{{#if additionalFocus}}段通过prompt.render注入自定义关注点见 renderHandoffPrompt。在生成侧oh-my-pi 提供generateHandoff(messages, model, apiKey, options)与generateHandoffFromContext(context, model, options)两个入口见 compaction.ts。generateHandoff负责组装消息将历史消息经convertToLlm转换后在末尾追加一条role: user、attribution: agent的交接提示消息generateHandoffFromContext则直接针对调用方已构建好的完整 Provider Context 发起一次性请求并强制toolChoice: none禁用工具调用防止生成过程中触发工具reasoning 力度经resolveCompactionEffort依据会话思考级别收敛。六、测试验证回归用例如何锁定模板行为oh-my-pi 用 packages/agent/test/handoff.test.ts 将这份模板的行为固化为回归测试防止未来重构破坏框架语义。核心用例位于describe(handoff summary injection)handoff.test.tstest(handoff-method summary is framed as the successors own prior handoff, () { const text convertedText(handoff); expect(text).toContain(handoff); expect(text).toContain(prior instance); expect(text).toContain(NEVER write another handoff document); expect(text).toContain(document); expect(text).not.toContain(summary); }); test(non-handoff methods keep the generic compaction framing, () { const text convertedText(remote); expect(text).toContain(summary); expect(text).toContain(document); expect(text).not.toContain(handoff); });测试验证了两件事method 为handoff时注入文本必须包含handoff标签、prior instance身份声明、NEVER write another handoff document禁止重写约束且完整保留文档正文同时不得出现summary标签method 为remote等非 handoff 值保持通用压缩框架summary不混入 handoff 专属措辞。同一文件还覆盖了generateHandoff/generateHandoffFromContext的其余行为自定义关注点注入、toolChoice: none强制、reasoning 力度随ThinkingLevel变化、针对仅支持tool_choice: auto的 Provider 的 400 自动重试handoff.test.ts以及无关 400 错误不重试直接上抛handoff.test.ts。这些用例与 compaction-telemetry.test.ts校验 handoff 一次性调用被标记为pi.gen_ai.oneshot.kind handoff、compaction-thinking-level.test.ts 共同构成 handoff 功能的测试矩阵。七、设计范式总结可复用的上下文框架技巧从这份九行模板及其实现中可以提炼出几条通用的提示词工程范式设计问题模板手段仓库实现依据模型把注入文本误读为用户指令显式声明not user input并指明真实来源与作者handoff-summary-context.md第一人称代词指向不明声明第一人称指代“之前的你”同模板第 2 行旧计划被机械执行、忽略用户新消息声明 Next Steps 是恢复计划并要求执行前对照最新用户消息复检同模板第 3 行模型重复生成已存在产物用大写强调NEVER write another handoff document同模板第 4 行测试断言见 handoff.test.ts重复已完成工作强制build on prior work; NEVER duplicate prior work同模板第 5 行框架指令与文档内容混淆使用handoff…/handoff结构化标签隔离内容区同模板第 6 行注入逻辑见 messages.ts八、相关文件速查注入模板本文核心packages/agent/src/compaction/prompts/handoff-summary-context.md生成模板文档结构规范packages/agent/src/compaction/prompts/handoff-document.md通用摘要框架对比参照packages/agent/src/compaction/prompts/compaction-summary-context.md渲染与注入实现packages/agent/src/compaction/messages.ts生成函数与策略定义packages/agent/src/compaction/compaction.ts回归测试packages/agent/test/handoff.test.ts相关修复记录packages/agent/CHANGELOG.md如需深入探索完整压缩体系可继续阅读同目录下的 compaction.ts压缩触发、切点检测、摘要窗口规划以及 compaction-v2-streaming.tsProvider 原生远程压缩。这份模板虽然只有九行却是 oh-my-pi 多实例长任务协作中防止“身份混淆”的关键一环其“先框定身份、再注入内容”的思路对任何涉及跨实例状态传递的 Agent 系统都有直接借鉴价值。【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表