ARTICLE DETAIL

资讯详情

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

oh-my-pi 自动会话标题生成:title-system 提示词契约与在线/端侧双路径实现

oh-my-pi 自动会话标题生成:title-system 提示词契约与在线/端侧双路径实现 oh-my-pi 自动会话标题生成title-system 提示词契约与在线/端侧双路径实现【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi本篇技术指南围绕 oh-my-pi⌥ Coding agentIDE 深度集成中用于自动会话标题生成的系统提示词模板 title-system.md 展开剖析其约 5 词标题 title标签输出契约的完整实现从提示词如何被渲染注入到在线小模型与本地 ONNX/MLX 端侧模型两条推理路径的差异再到低信号输入过滤、输出规范化与大小写还原等工程细节。读完你将掌握该项目自动命名会话的完整调用链以及可复用的结构化标记输出 后置解析兜底提示词设计范式。一、title-system 提示词一份极简的标题输出契约title-system.md 是 oh-my-pi 会话自动命名功能的核心提示词全文结构非常克制Write a ~5 word title for the next user message. - You MUST ONLY answer with the title, inside the title tag. - If the message is only a greeting, answer title/. {{#if includeExamples}} examples [User] userthe login button is broken on mobile somehow, can you fix?/user [AI] titleFix login button on mobile/title --- [User] userwhy does quuxdb segfault on startup since yesterday?/user [AI] titleFix quuxdb startup segfault/title --- [User] userhey/user [AI] title/ /examples {{/if}}这份模板同时承担着三个职责缺一不可长度约束目标为~5 word约 5 个词的短标题保证会话列表与终端标签的可读性输出契约模型必须把标题包裹在title.../title标签内输出且只输出标题本身不允许任何前后缀文本无任务声明当输入只是打招呼等无具体任务的内容时输出自闭合标签title/语义等价于暂无标题请勿命名。模板使用{{#if includeExamples}}这一模板变量控制是否注入 few-shot 示例这是全文唯一的分支点也是后续两条推理路径差异的根源。二、提示词的两种渲染形态带示例与不带示例title-system.md是一个基于模板引擎项目内封装于oh-my-pi/pi-utils的prompt.render渲染的提示词文件同一份源码在不同场景下以两种形态被使用使用方渲染参数是否含示例适用场景title-generator.ts{ includeExamples: true }是在线小模型路径远程 smol/commit 角色title-client.ts{ includeExamples: false }否本地端侧 tiny 模型ONNX/MLX workerbench-title-models.ts两种都渲染两者基准测试对比实验从源码注释可以看出设计意图能力较强、上下文窗口宽裕的在线模型使用带示例版本TITLE_PROMPT_WITH_EXAMPLES帮助其稳定遵循输出格式本地 90M~350M 级别的端侧小模型则使用无示例版本TINY_TITLE_SYSTEM_PROMPT因为示例会占用本就紧张的上下文预算而小模型对直接指令反而更敏感。两份渲染产物分别作为 system 消息注入对应推理路径见 title-generator.ts 与 title-client.ts。三、调用链总览从首条用户消息到会话标题自动标题生成的完整调用链可以从 agent-session.ts 的generateTitle方法入手用户发送首条消息 → agent-session.generateTitle(firstMessage) → generateSessionTitle(firstMessage, registry, settings, ...) // utils/title-generator.ts → ① isLowSignalTitleInput 确定性预过滤问候语直接跳过不调用模型 → ② 根据 providers.tinyModel 设置分流 - online → generateTitleOnline在线小模型走完整聊天补全 - 本地模型 key → tinyTitleClient.generate端侧 workerprefill/stop 受限解码 → ③ 输出解析与规范化extractGeneratedTitle / normalizeGeneratedTitle → ④ 大小写还原reconcileTitleCasing以用户原文为准会话层还维护了一个与生命周期绑定的 AbortController#titleGenerationAbortController首条输入路径与 replan 刷新路径共享同一信号会话销毁时同步取消后台标题推理在线请求使用稳定的 side-request 身份避免在后台请求等待期间推进前台 provider 会话。此外重规划replan后若启用了title.refreshOnReplan设置且标题不是用户手动命名会基于新上下文重新生成标题并写回见 agent-session.ts。3.1 低信号输入过滤把你好挡在模型调用之前title-system.md中greeting →title/的规则对应着实现层的确定性预过滤函数isLowSignalTitleInputtext.ts。项目维护了一个覆盖问候语、礼貌用语、确认词与填充词的FILLER_TITLE_TOKENS集合hi/hello/hey/thanks/ok/test/ping等 80 词条只要用户消息清洗后全部由这些词或纯数字构成就直接返回null、不调用任何模型。这一步的动机在源码注释中写得很清楚默认本地 tiny 标题模型约 350M无法可靠执行对无价值输入不要给标题这种否定性指令容易对琐碎输入幻觉出一个标题因此在模型调用之前用确定性规则拦截会话保持未命名状态等下一条真正有任务的消息再重试。对应测试 title-generator.test.ts 断言了对hi调用generateSessionTitle返回null且completeSimple从未被调用。3.2 消息预处理小模型输入的低噪声化端侧小模型会把输入中的字面噪声原样复制进标题因此所有进入标题管道的用户消息都要经过 message-preproc.ts 的清洗剥除 ANSI 转义stripAnsi去掉粘贴终端输出时混入的颜色控制序列移除成对 XML/工具信封stripXmlBlocksuser…/user、think…/think、工具信封等整块删除避免其内容主导标题缩短长十六进制串shortenHashes≥12 位的 hex 运行完整 commit SHA截断为 7 位短前缀删除围栏代码块stripCodeBlocks小模型极易死盯代码块内的字面文本——注释里举的例子是粘贴的 UI 原型包含Welcome to Claude Code v2.1.158最终标题就会变成这句话而不是任务意图但若剥除后剩余内容不足 12 字符消息基本就是一段代码则回退使用原始消息中段截断truncateTinyMessage上限 2000 字符超过时保留头部 2/3、尾部 1/3中间以[… N chars omitted …]标记占位兼顾任务头尾与显式省略提示。清洗后的消息被包进user\n…\n/user信封formatTitleUserMessage与title-system.md示例中的格式完全对齐而 replan 场景预格式化的chat上下文则原样透传避免二次清洗把结构标签剥掉。这些规则在 tiny-text.test.ts 中有对应断言。四、在线路径generateTitleOnline 的完整请求构造当providers.tinyModel设置为online默认值时标题生成走generateTitleOnlinetitle-generator.ts其请求构造有四个关键决策值得关注1. 模型选择优先解析tiny→commit→smol角色resolveRoleSelection([tiny, commit, smol], ...)都没有则回退到当前会话模型见 title-generator.ts。2. 贪婪解码 关闭推理请求固定temperature: 0与disableReasoning: true。标题任务是抽取而非生成高温度会让小模型把消息中的词拼错注释示例hashline→HasHroshimaxTokens上限设为 1024是为了兜底那些忽略disableReasoning、仍然输出 think 标记的后端如 llama.cpp 的 jinja 模板强制enable_thinking: true保证title标记始终可达对应 issue #4355。3. 从强制工具调用回归到文本标记早期方案是强制set_title工具调用但部分 host 会忽略/拒绝强制的tool_choice进而把提示词示例里的 JSON 原样回显成会话标题title文本标记则在所有 provider 上行为一致title-generator.ts。这是本提示词采用标记输出的直接历史原因。4. 凭据与元数据标题请求使用独立的 side-request 会话身份取 API KeymetadataResolver在取 Key 之后才求值确保元数据中的account_uuid反映实际选中的凭据。4.1 输出解析容错是核心在线补全返回自由文本extractGeneratedTitletitle-generator.ts采用标记优先、文本兜底的宽容策略在可见文本中查找第一个闭合的title.../title位于思考标签think/thinking/reasoning或思考围栏内部的标记会被判定为不可见而跳过无标记时剥除开头泄漏的思考前缀支持标签与围栏两种形式循环剥除直到稳定再尝试普通句子作为标题以heres my thinking process: 之类的思考前奏开头则判为空unwrapJsonTitle兼容模型被训练成 JSON 输出{title: ...}的残留习惯解析成功取title字段截断损坏的 JSON 则用正则抢救被引号包裹的标题值。对应测试覆盖了none哨兵、自闭合title/、裸title等多种异常返回见 title-generator.test.ts。五、端侧路径tiny 标题模型的 worker 架构本地端侧路径providers.tinyModel设置为lfm2.5-230m/lfm2.5-350m/falcon-h1-90m之一通过 title-client.ts 的TinyTitleClient与常驻 worker 通信整套机制是标题 记忆补全共享的5.1 可用模型注册表模型元数据集中在 models.ts均为 q4 量化、约 147~292 MB 缓存占用的小模型key模型缓存大小定位lfm2.5-230mLFM2.5 230M~214 MB推荐默认最快平衡性最好lfm2.5-350mLFM2.5 350M~292 MB更大容量倾向生成更简短的标题falcon-h1-90mFalcon H1 Tiny 90M~147 MB最省资源复杂提示下保真度较低每个模型有 ONNX 导出transformers.js 加载全平台可用与 MLX 4bit 导出PI_TINY_DEVICEmlx时由 mlx-lm 加载两份规格另外qwen3-1.7b等 1B 模型用于 Mnemopi 记忆任务而非标题标题模型刻意选择亚 1B 规模因为 3~6 词标题不需要更大容量。5.2 受限解码用 prefill/stop 把契约写进采样器与在线路径自由生成再解析不同端侧路径把title-system.md的输出契约直接下沉到了解码参数[title-client.ts](https://link.gitcode.com/i/4fd655465fcfced709c5cbbccf76ddfb#L55-L60, L599-L606)prefill: title // 采样前缀模型从 title 之后开始生成 stop: /title // 命中即停止天然截断到标题内容 maxNewTokens: 20 // 硬上限5 词标题绰绰有余配合TITLE_PREFILL前缀模型被约束为从title后面接着写再靠/title停止标记终止几乎不可能泄漏格式噪声即使如此客户端仍保留extractTinyTitle兜底解析取最后一个title之后、/title之前、且去掉多余的内容。这套提示词定义契约 采样参数强制契约的双保险是小模型路径稳定性的关键。5.3 worker 生命周期管理TinyTitleClient的细节体现了对稳定性的极致追求每个模型由一台机器级共享的 worker 进程ONNX 的worker.ts或 MLX 的mlx-server.py通过以模型命名的 unix socket 提供推理客户端先探测ping/pongsocket 不存在则分离式拉起detached日志写入独立文件并发 omp 进程竞争时后到者让位launch tag 校验prewarm 预热首次使用前提前建连避免提交热路径上承担探测/拉起延迟issue #6462失败模型标记#failedModels后不再重试socket 按请求在途计数 ref/unref空闲的 TUI 会话可以正常退出--smoke-test通过 smokeTestTinyTitleWorker 验证 ONNX worker 启动与 tagged ping 握手。六、输出规范化长度、哨兵与大小写还原无论哪条路径最终标题都要经过normalizeGeneratedTitletext.ts这道质量闸门长度红线仅取首行80 字符、12 词为硬上限。超过即视为模型忽略了任务、在回答用户消息整个回复绝不能成为会话标题——截断会留下半个助手回复拒绝则让调用方延后到下一条用户消息重试issue #7303噪声清洗剥除首尾引号、title包裹、结尾句读none哨兵titlenone/title配合 title-marker-instruction.md 中的无任务时输出titlenone/title指令与自闭合title/均返回null语义等价于提示词中的问候分支零词标题拒绝纯标点/符号垃圾如..直接判空防止会话被命名为乱码。6.1 大小写还原以用户消息为准绳title-system.md要求 sentence case但小模型仍有三种典型的大小写错误reconcileTitleCasingtext.ts逐词以用户消息原文为真值进行还原用户原文逐字写过的词 → 原样保留用户确立了大小写用户消息中存在特征性混合大小写TinyVMM、iOS、IDs而模型拍平了它 → 还原为用户写法模型把全大写缩写改成了标题式CNPG→Cnpg→ 还原缩写全大写且辅音为主CNPG/SQL/JWT、含数字、或属于API/JSON/URL等常用缩写白名单的才可还原普通强调词FIX/WORK/BUG不被当作缩写用户从未写过的驼峰伪影dAemon、cReate→ 小写化其余原样保留如模型正确保留的GitHub、OAuth专有名词。同时检测到用户输入连续 ≥2 个全大写词FIX the BUG NOW式喊叫输入时禁用缩写还原避免把模型正确去喊叫的结果重新大写。这套规则对截断保留首尾的预处理策略形成了闭环标题中的专有名词总能从消息头部或尾部找回原文写法。七、验证与基准bench-title-models 与测试覆盖7.1 标题模型基准bench-title-models.ts 是一个独立的基准工具从本地历史数据库~/.omp/agent/history.db默认路径采样各会话的首条消息对每条消息同时渲染带示例与不带示例两种提示词分别驱动本地 ONNX 模型泳道LFM2.5 230M/350M、Falcon H1 90M与远程 Ollama 模型泳道默认llama3.2:3b产出逐样本标题与延迟矩阵# 默认20 条样本3 个本地模型 2 个 Ollama 模型 bun scripts/bench-title-models.ts # 指定数量与随机种子可复现采样 bun scripts/bench-title-models.ts --count 30 --seed 42 # 只跑指定本地模型或接入自定义 Ollama 端点 bun scripts/bench-title-models.ts --models lfm2.5-230m,falcon-h1-90m bun scripts/bench-title-models.ts --ollama-url http://spark.internal:11434 --ollama-models llama3.2:3b,lfm2.5:2.6b # 用带示例的提示词测本地模型对照实验 bun scripts/bench-title-models.ts --local-examples报告汇总每个模型的冷启动延迟、warm 平均/中位/P95 延迟、空输出数、3~7 词合规率与无标点率lengthCompliant/punctuationFree结果写入带时间戳的 JSON 文件便于跨轮对比Ollama 泳道同样使用temperature: 0与num_predict: 1024与在线路径参数保持一致。7.2 测试覆盖title-generator.test.ts771 行系统性地验证了从提示词契约到实现细节的全部行为包括问候语不触发模型调用、none哨兵与title/返回null、凭据缺失时的日志与降级、正常任务生成标题、generateTitleOnline与本地路径的分支、以及对系统提示词覆盖customSystemPrompt的支持——后者正是 agent-session.ts 注释中用自定义提示词做特殊用途命名如 plan 保存文件名主题而不触碰会话级覆盖的能力来源。八、设计启示一份 16 行提示词背后的工程范式回看 title-system.md这份极简模板之所以能稳定驱动从 90M 端侧模型到在线大模型的全谱系推理得益于几个可复用的设计原则契约显式化MUST ONLYtitle标签把输出格式变成机器可校验的约束而不是依赖模型猜端侧路径更进一步用prefill/stop把同一契约写进解码器无任务有明确表达title/自闭合标签是不命名的显式信号配合确定性预过滤与none哨兵形成三道防线示例按能力分级{{#if includeExamples}}让同一份模板适配强弱两种模型强模型给示例稳定格式弱模型省上下文解析端极度宽容思考标签泄漏、JSON 残留、裸标记、截断输出……解析器为每一种模型不听话的方式准备了兜底保证坏输出只导致这次不命名绝不污染会话状态后置质量闸门长度红线、零词拒绝、大小写还原把5 词标题从提示词愿望落实为可执行的输出策略。这套提示词定义契约、采样参数强化契约、解析器兜底契约的三层结构正是自动化 Agent 系统中所有短结构化输出任务标题、摘要、分类标签可以直接借鉴的工程范式。延伸阅读继续深入可以在仓库中查看 title-generator.ts在线路径与终端标题状态机、title-client.tsworker 客户端、text.ts规范化与大小写还原、models.ts标题模型注册表、bench-title-models.ts基准工具以及 title-generator.test.ts测试套件。【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表