
OMP 中的 OpenAI Harmony 方言gpt-oss 函數調用線格式與流式解析實戰【免費下載鏈接】oh-my-pi? Coding agent with the IDE wired in項目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-piHarmony 是 OpenAI 為其開源權重模型 gpt-oss 系列gpt-oss-20b、gpt-oss-120b訓練的響應格式它定義了對話信封、多通道推理/回答分離與函數調用的線語法。本文以 oh-my-piOMP項目中實際注入系統提示詞的方言指南 harmony.md 為骨架結合 harmony.ts 的流式掃描器、完整格式說明 與配套測試完整講解 Harmony 消息格式、工具目錄渲染、流式解析實現與泄漏防護讀完即可讀懂 OMP 的harmony方言如何把模型輸出還原成標準 ToolCall也能在自己的推理循環中正確實現該格式。Harmony 是什么gpt-oss 的原生響應格式Harmony 是 OpenAI 訓練其開放權重模型 gpt-oss 系列時使用的響應格式覆蓋三個層面對話信封conversation envelope、多通道的推理/回答分離analysis/commentary/final以及函數調用的線上語法。不使用該格式提示模型模型將無法正常工作。它刻意模仿 OpenAIResponsesAPI 的角色、通道、接收方結構而不是更早的 Chat Completions 形態。在 OMP 中Harmony 是 factory.ts 注冊的十一種方言之一glm、hermes、kimi、xml、anthropic、deepseek、minimax、harmony、qwen3、gemini、gemma。方言定義由四部分組成prompt注入系統提示詞的格式指南——正是 harmony.md在 harmony.ts 中以import dialectPrompt from ./harmony.md with { type: text }的方式內聯createScanner返回HarmonyInbandScanner負責把流式輸出還原成結構化事件渲染函數renderToolCall、renderAssistantToolCalls、renderToolResults、renderThinking、renderTranscript元信息dialect: harmony。消息信封與三通道結構Harmony 中每條消息都是統一信封|start|{header}|message|{content}|end|{header}總是以角色開頭可攜帶可選的接收方to...、通道channel與內容類型content-type。完整消息以|end|結束正在生成的 assistant 消息則以停止 token|return|或|call|結束。五種角色指令沖突時按systemdeveloperuserassistanttool的層級裁決角色用途system身份、知識截止/當前日期、推理強度、合法通道聲明、內置工具。不是面向用戶的 system prompt。developer常規的 system prompt指令 # Tools函數聲明 可選結構化輸出 schema。user終端用戶輸入。assistant模型輸出。攜帶通道工具調用時攜帶接收方。tool工具執行結果。消息的作者/角色是工具自身的名字如functions.get_current_weather而不是字面量tool。三種通道僅 assistant 輸出使用且每條 assistant 消息強制攜帶通道用途analysis原始思維鏈推理過程。安全要求低于final不得展示給終端用戶內置python/browser調用通常也走這里。commentary函數工具調用以及多工具調用前的用戶可見 前言行動計劃。final面向用戶的最終回答。推理強度在 system 消息中以Reasoning: high或medium/low默認medium設置。模型把 CoT 寫入analysis把答案寫入final。CoT 攜帶規則下一輪對話時僅當上一輪 assistant 以final消息結束時才丟棄先前的analysis消息如果上一輪是進行中的工具調用輪次則緊鄰工具調用之前的analysis必須連同工具結果一起回喂給模型否則多步工具推理會斷裂。函數調用的線格式核心格式來自 harmony.md 的 Format guide——每條函數調用是commentary通道上的一條 assistant 消息以文本形式發出指向具體函數|start|assistant|channel|commentary tofunctions.function_name|message|{arg:value}|call|接收方可能出現在role 區段或channel 區段兩種寫法都是合法的 Harmony解析器都接受。OMP 渲染器采用后者接收方在 channel 區段見 harmony.ts 的renderToolCall|start|assistant|channel|commentary tofunctions.get_current_weather|message|{location:San Francisco, CA}|call|部分 Harmony 序列化器會顯式攜帶 JSON 內容類型并把接收方放在 role 區段|start|assistant tofunctions.get_current_weather|channel|commentary |constrain|json|message|{location:San Francisco, CA}|call|參數體是原始 JSON 對象可選的|constrain|json內容類型標記 JSON也是受限/文法解碼的掛載點內容類型也可能是裸詞如code內置工具常見。內置工具的區別只在通道與接收方通常渲染在analysis通道接收方為browser.search/browser.open/browser.find或固定的python。OMP 的取舍OMP 發出的正是第一種形式——無|constrain|標記、接收方在 channel 區段、緊湊 JSON 參數。由于 Harmony 本身不攜帶調用 IDOMP 在收到調用時用mintToolCallId()合成見 coercion.ts形如ptc_時間戳36進制_計數器36進制。私有推理放在analysis消息中|start|assistant|channel|analysis|message|private reasoning|end|工具結果以函數署名的消息回傳指向 assistant位于commentary通道|start|functions.function_name toassistant|channel|commentary|message|verbatim tool result|end|Rules 逐條解讀harmony.md 的 Rules 部分給出九條硬性約束OMP 將其整體注入系統提示詞約束模型輸出接收方必須是functions. 已列出的函數名。掃描器在解析頭部時會剝離前綴functions.得到暴露給上層的工具名harmony.ts。正文是單個符合 schema 的 JSON 對象未設置的參數直接省略。字符串值只用普通 JSON 轉義\、\\、\n絕不做 HTML 轉義——寫a b不寫a amp; b。這是 OMP 在渲染工具調用時用stringifyJson直出 JSON 的原因。多條調用 連續的消息。Harmony 沒有獨立的 parallel 包裝結構??蛇x的前言是commentary消息以|end|結尾——與analysis不同前言是給用戶看的行動計劃。絕不把工具調用放進analysis——工具調用必須走commentary通道。絕不用 Markdown/代碼圍欄包裹調用——否則掃描器會把整段當作可見文本。按調用順序讀取每條工具結果消息絕不自行發出工具結果消息——工具結果只能由宿主回填。只有在調用完整寫完之后才輸出停止序列——先完整寫完|call|消息再停止嚴禁只宣布要調用工具如停在 Lets runcargo clippy卻不發出|call|消息。第 9 條對應停止 token 語義|call|與|return|是僅有的兩個合法生成停止 token宿主必須在兩者之一處停止推理。特殊 token 與 o200k_harmony 編碼所有 Harmony 控制 token 的字面形式都是|type|ASCII 豎線|U007C不能是 Unicode 變體。在o200k_harmony編碼中它們是真正的單 tokeno200k_baseBPE 詞表加上一塊 Harmony 特殊 token不是會被 BPE 切分的文本。結構上有意義的 token 如下ID 范圍來自o200k_harmonyToken原文Token ID用途\|start\|200006消息開始后緊跟頭部角色、可選接收方/通道/內容類型。\|end\|200007結束一條完整消息。\|message\|200008頭部 → 內容的過渡其后的所有內容直到停止/結束 token都是消息體。\|channel\|200005引入頭部中的通道字段analysis/commentary/final。\|constrain\|200003在工具調用頭部標記內容類型/受限解碼格式如\|constrain\|json。\|return\|200002停止 token模型完成最終回答。僅解碼期使用。\|call\|200012停止 token模型正在發出工具調用等待執行。同一編碼塊還定義了|startoftext|199998、|endoftext|199999以及 199998–200013 區間的保留槽位與一段大范圍保留區|reserved_200014|…|reserved_201088|。渲染器還認識|refusal|、|untrusted|、|end_untrusted|、|meta_end|這些名字但它們不屬于已提交的 gpt-oss 詞表正常流量中不會出現。編碼時務必把|...|當作原子特殊 token若按普通文本編碼得到的 rank 不同會污染整條流。工具定義namespace functions 目錄函數工具在developer消息的# Tools區塊中以 TypeScript 風格namespace functions { ... }聲明內置browser/python工具則聲明在system消息自己的# Tools/## browser/## python標題下。渲染器把每個 JSON Schema 轉成 TS 類型規則如下無參函數 →type name () any;有參函數 → 唯一參數命名為_對象類型內聯type name (_: { ... }) any;返回類型恒為anydescription屬性變成字段上方一行的//注釋JSON Schema 的title渲染成// TITLE后接一行//空注釋examples渲染成// Examples:加逐行// - value非required字段帶尾部?default渲染成尾部// default: value注釋enum變成a | b聯合oneOf變成多行|聯合JSONinteger映射為 TSnumber函數定義之間空一行區塊以} // namespace functions收尾。若 developer 消息沒有指令文本則省略# Instructions標題消息只剩# Tools區塊。只要定義了任何函數system 消息就會獲得路由行Calls to these tools must go to the commentary channel: functions.。這一渲染邏輯在倉庫中有兩處落點inventory.ts 的renderToolInventory調用jsonSchemaToTypeScript(toolWireSchema(tool), { style: harmony })把工具目錄渲染成## functionsnamespace functions { ... }形式供 verbose system-prompt 目錄與/dump共用typescript.ts 的jsonSchemaToTypeScriptstyle: harmony輸出扁平約定——//行注釋、,分隔符、無縮進與默認風格的 JSDoc 注釋/;分隔符/縮進體區分開。渲染器發出的 developer 消息原樣示例指令 三個函數|start|developer|message|# Instructions Use a friendly tone. # Tools ## functions namespace functions { // Gets the location of the user. type get_location () any; // Gets the current weather in the provided location. type get_current_weather (_: { // The city and state, e.g. San Francisco, CA location: string, format?: celsius | fahrenheit, // default: celsius }) any; // Gets the current weather in the provided list of locations. type get_multiple_weathers (_: { // List of city and state, e.g. [San Francisco, CA, New York, NY] locations: string[], format?: celsius | fahrenheit, // default: celsius }) any; } // namespace functions|end|OMP harmony 方言的渲染實現harmony.ts 定義了一組與格式指南嚴格對齊的渲染函數renderToolCall${START}assistant${CHANNEL}commentary to${harmonyRecipient(call.name)}${MESSAGE}${stringifyJson(call.arguments)}${CALL}——無constrain標記、接收方在 channel 區段、緊湊 JSON 參數renderAssistantToolCalls多條調用逐條拼接天然滿足 多條調用 連續消息renderToolResults${START}${harmonyRecipient(result.name)} toassistant${CHANNEL}commentary${MESSAGE}${result.text}${END}——完整的規范結果頭部result.text原樣透傳renderThinking${START}assistant${CHANNEL}analysis${MESSAGE}${text}${END}renderTranscript按消息流順序渲染——assistant 消息依次輸出完整的analysisthinking、完整的final可見文本再對每個工具調用輸出一條commentary調用消息因此伴隨工具調用的可見文本渲染成final而非 commentary 前言。工具結果則把連續的工具結果消息合并為逐條規范信封。harmonyRecipient定義在 rendering.ts名字已帶functions.前綴則原樣返回否則補上保證發送與回傳兩側的接收方命名一致。流式解析HarmonyInbandScanner 狀態機接收側的核心是HarmonyInbandScanner一個三狀態outside/header/body的流式掃描器暴露feed(text)與flush()兩個入口harmony.ts產出InbandScanEventtext、thinkingStart/Delta/End、toolStart、toolEnd等事件類型見 types.ts。解析規則要點頭部解析找到|message|后切出頭部分別提取 role、channel、recipientto...正則見parseRecipient。有狀態掃描器同時接受接收方出現在任一頭部區段。工具調用判定任何非空且不等于assistant的接收方都被視為工具調用包括browser.search這類內置工具名字帶functions.前綴則剝離。#enterBody在頭部完成時立即發出toolStart事件并合成調用 ID。參數累積參數文本累積直到|call|、|end|或|return|然后用parseJsonWithRepair做 JSON 修復解析#parseArgsharmony.ts。空參數或修復后仍無法解析的輸入降級為{}而不是掃描器報錯。事件分派analysis消息體以thinkingDelta增量流式輸出普通 assistant 的commentary/final消息體以text流式輸出非 assistant 消息包括工具結果信封被跳過。邊界處理feed用partialSuffixOverlapAny保留可能是不完整 token 的尾部字節避免多字節 UTF-8 或 token 在分塊邊界被切斷復用 coercion.ts 的偏后綴重疊檢測。一個與規范 Harmony 不同的所有權邊界情況文檔明確標注在帶接收方頭部到達|message|之后OMP 已經發出了toolStart如果普通流式路徑把消息體字節耗盡后流在沒有|call|、|end|、|return|的情況下結束flush()不會發出toolEnd也不會撤回toolStart。由于 Harmony 掃描器不產生參數增量即使看到未終止的正文文本保留的規范調用參數仍是{}。正常停止時 OMP 會把該輪改為toolUse并可能派發這個空調用——這是寬容但非安全的恢復行為不是合法的 Harmony 終止規則。掃描器在 owned-stream.ts 中被接入流式管線wrapInbandToolStream把 provider 的原始文本增量喂給掃描器遇到RESPONSE_OPEN_TOKENS[harmony]即[|start|functions.]owned-stream.ts即判定模型開始偽造工具結果在 abort 模式下立即截斷輪次防止 provider 繼續為幻覺輸出燒 token。parseInbandToolMessage則把已完成的消息一次性投影為結構化 ToolCallrawBlock保留原文供審計。思考流修復與泄漏防護Harmony 的analysis標簽同時出現在通用思考修復器的恢復列表中thinking.ts 把|start|assistant|channel|analysis|message|...|end|渲染形態與|channel|analysis|message|...|end|裸泄漏形態都識別為推理段落把模型泄漏進可見文本通道的推理修復回 thinking 事件。此外 demotion.ts 在需要降級渲染思考時對harmony方言使用think\n${text}\n/think包裝。針對 gpt-5.x / gpt-oss 服務端會拒絕請求中出現的保留控制 token 拼寫invalid_promptharmony-leak.ts 實現了兩層防護傳輸層轉義escapeHarmonyControlTokens把|start|、|end|等保留拼寫轉義為惰性反斜杠形式\|start\|讓不可信數據用戶文本、工具結果能作為數據到達 harmony 模型而不觸發校驗拒絕JSON 文檔內使用escapeHarmonyControlTokensInJson雙寫反斜杠保持文檔合法。調用方以isHarmonyDialectModel模型identity.class gpt-oss為開關且只轉義傳輸副本持久化記錄保留逐字節原文。泄漏檢測與恢復detectHarmonyLeak融合多路信號——H控制 token 拼寫、Mtofunctions.*標記、C通道詞鄰接、G故障 token如changedFiles/RTLU/Jsii_commentary/Japgolly、S腳本混雜、B正文級聯、R偽結果框架。觸發規則是H單獨觸發或M至少帶一個協同信號孤立的M不觸發文檔與測試本身就會合法攜帶該標記。工具參數面tool_arg采用更嚴的門控只有結構合法解析邊界之后的標記T信號才觸發避免誤殺合法的代碼/數據內容。recoverHarmonyToolCall對edithashline DSL以開頭與eval工具支持截斷 追加*** Abort哨兵的恢復其余工具回落到 abort-and-retry由 agent 循環處理。端到端示例與輪次邊界完整的天氣多輪交換——system developer 提示 → 用戶提問 → assistant analysis 思維鏈 → assistant commentary 工具調用 → 工具結果 → assistant final 回答消息在流中緊密拼接、無分隔符換行僅為可讀性|start|system|message|You are ChatGPT, a large language model trained by OpenAI. Knowledge cutoff: 2024-06 Current date: 2025-06-28 Reasoning: high # Valid channels: analysis, commentary, final. Channel must be included for every message. Calls to these tools must go to the commentary channel: functions.|end||start|developer|message|# Instructions Use a friendly tone. # Tools ## functions namespace functions { // Gets the current weather in the provided location. type get_current_weather (_: { // The city and state, e.g. San Francisco, CA location: string, format?: celsius | fahrenheit, // default: celsius }) any; } // namespace functions|end||start|user|message|What is the weather like in SF?|end||start|assistant|channel|analysis|message|User wants the weather in San Francisco. Use get_current_weather.|end||start|assistant|channel|commentary tofunctions.get_current_weather|message|{location:San Francisco, CA}|call||start|functions.get_current_weather toassistant|channel|commentary|message|{sunny: true, temperature: 20}|end||start|assistant|channel|final|message|Its sunny and about 20°C in San Francisco right now.|return|輪次邊界與規范化宿主在|call|處停止生成解析commentary調用執行get_current_weather追加functions.get_current_weather toassistant結果消息然后追加|start|assistant繼續生成。前一條analysis消息被保留上一輪以工具調用結束而非final模型得以繼續推理生成在|return|處停止。當該輪被持久化到歷史供后續輪次使用時把尾部的|return|規范化為|end|保證每條存儲消息都是完整的|start|{header}|message|{content}|end|監督訓練目標除外訓練目標以|return|結尾是正確的。部署形態原生路徑與 OpenAI 兼容橋接通過 OpenAI 兼容端點服務時服務器替你處理 HarmonyOllama / LM Studio / HuggingFace內部應用 Harmony你照常發送 OpenAI 風格 JSONvLLMvllm serve openai/gpt-oss-120b --enable-auto-tool-choice --tool-call-parser openai --reasoning-parser openai_gptoss。注意工具調用解析器標志是openai不是harmonyvLLM 也通過/v1/responses端點暴露 Harmony 原生路徑SGLangpython3 -m sglang.launch_server --model-path openai/gpt-oss-20b --reasoning-parser gpt-oss --tool-call-parser gpt-ossNVIDIA Dynamo 分離模式下用--dyn-tool-call-parser harmony --dyn-reasoning-parser gpt_oss。gpt-oss 權重自帶的聊天模板會把標準messages/tools數組渲染成同樣的 token 序列。Chat Completions JSON 映射vLLM/SGLang/Ollama 橋接時finish_reason停在|call|→tool_calls停在|return|→stopmessage.tool_calls[]每條commentarytofunctions.*調用一條function.name是去掉functions.命名空間后的接收方function.arguments是JSON 字符串|message|正文原樣不是解析后的對象tool_call_idHarmony 沒有原生調用 ID服務器合成一個如call_abc123并負責把后續role:tool消息關聯回工具結果信封tofunctions.name/ 調用順序工具結果消息渲染為|start|{toolname} toassistant|channel|commentary|message|{content}|end|服務器把tool_call_id映射回原始函數名以構造{toolname}作者推理analysis通道文本作為reasoning_contentvLLM/SGLang或reasoning/thinking字段暴露通常不回顯final通道是正常message.content原生路徑下請求的tools/tool_choice由服務器聊天模板編譯進 developer 消息的namespace functions { ... }塊system 消息追加 commentary 路由行。OMP 的 owned-dialect 廣告路徑略有不同選定harmony方言后OMP 移除 provider 原生工具改在系統提示詞中追加其通用緊湊toolsJSON 目錄與本文講解的 Harmony 格式指南而不走規范的 developer 消息 namespace 作為工具廣告。解析注意事項與常見坑兩個停止 token|return|與|call|都要停。只停return會越過工具調用只停end對 assistant 生成是錯的。接收方位置可變tofunctions.name可能在 role 區段|start|assistant to...|channel|commentary或 channel 區段|channel|commentary to...解析器必須兩者都接受。通道必填assistant 消息強制攜帶通道system 消息甚至提醒模型Channel must be included for every message.缺通道的輸出是畸形輸出。工具作者名而非tool工具結果消息的角色是工具名functions.get_current_weather不是字面量tool把functions.x拆成命名空間 函數名是解析器的職責。CoT 丟棄是有條件的只有上一輪 assistant 以final結束時才丟棄analysis丟棄緊鄰|call|的analysis會破壞多步工具推理。arguments是字符串不要雙重編碼|message|之后的正文已是序列化 JSON原樣作為arguments字符串透傳。內容類型變體|constrain|json是可選的出現也只表示元數據不保證 JSON 合法要用受限解碼或自己的文法保證 schema 遵循對結構化輸出的# Response Formats同樣成立。流式解析務必使用有狀態解析器讓不完整 UTF-8 與 header/channel/recipient/content-type 字段增量重建樸素子串掃描會搞砸多字節切分與可選頭部字段。不要把尾部停止 token 傳給解析器。編碼使用o200k_harmony把|...|當作原子特殊 token編碼為普通文本會得到不同 rank 并破壞流。測試驗證倉庫測試直接印證了上述行為inband-tools.test.tsexpectRawBlock驗證 harmony 工具調用完整原文|start|assistant|channel|commentary tofunctions.read|message|{path:src/a.ts}|call|parseInbandToolMessage把該原文投影為結構化ToolCallrawBlock保留原文renderToolResults輸出規范的|start|functions.read toassistant|channel|commentary|message|FILE|end|harmony-leak.test.ts覆蓋isHarmonyLeakMitigationTarget策略門控、負樣本不得誤觸發含分塊邊界切分、正樣本帶協同信號必須觸發、tool_arg的T信號門控以及editDSL 的*** Abort截斷恢復與冪等性issue-6913-harmony-marker-escaping.test.ts 與 json-schema-typescript.test.ts 分別覆蓋保留標記轉義與 schema→TS含 harmony 風格渲染。綜上harmony.md 既是注入模型的格式指南也是 OMPharmony方言渲染與解析兩側的共同契約渲染側嚴格產出 無constrain、接收方在 channel 區段、緊湊 JSON 的第一種調用形式解析側用有狀態掃描器容錯地還原工具調用、思維鏈與文本再配合泄漏檢測與傳輸轉義使 gpt-oss 系列模型在 OMP 的 agent 循環中可靠地完成多步工具調用。如需在自己的推理循環中集成 gpt-oss按本文的線格式、停止 token 與規范化規則實現即可若要參考 OMP 的完整落地可繼續閱讀 toolconv/harmony.md、harmony.ts 與 owned-stream.ts?!久赓M下載鏈接】oh-my-pi? Coding agent with the IDE wired in項目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考