OpenAI Harmony フォーマット仕様書

2026年4月4日更新
※ この文書は自分自身の知識を整理するため、ChatGPT/Gemini を用いて調査・整形したメモです。

OpenAI Harmony フォーマット仕様書

0. 本書の目的

本書は、OpenAIの提供する Harmony response format に関する日本語の詳細仕様書である。公式ドキュメントに留まらず、公開されている gpt-ossのチャットテンプレート、トークナイザ(tokenizer)設定、openai-harmonyライブラリ、および Transformers / vLLM / Ollama等における実運用資料 を横断的に参照し、仕様を整理した。
本書は、主に以下の仕様を明確化することを目的とする。
  • Harmonyフォーマットが解決する技術的課題
  • system / developer / user / assistant / tool 各ロールの役割定義
  • analysis / commentary / final の3チャンネルによる出力の分離
  • 推論(reasoning / CoT)、ツール呼び出し、および構造化出力の表現方式
  • 全公開特殊トークン(special token) の一覧と使用基準
  • トークナイザ設定上は未公開であるが、openai/harmony 実装内に存在する追加トークン候補の扱い
  • Hugging Faceの chat_template.jinja における実際の処理ロジック
  • 具体的な対話例、ツール利用例、および実装例の提示

1. Harmonyの概要

Harmonyは、OpenAIの gpt-oss 系モデル向けに最適化された、会話・内部推論・ツール呼び出し・構造化出力を統合的に扱うためのプロンプトおよびレスポンス整形フォーマットである。OpenAIは、gpt-oss モデルを正常に動作させるためにはHarmonyフォーマットの適用が必須であると公式に言及している。
本フォーマットは OpenAI Responses APIのメンタルモデル を踏襲して設計されており、モデルが以下の要素を単一の連続するトークン列として処理・出力することを可能にする。
  • 会話の階層構造(system / developer / user / assistant / tool)
  • モデルの内部推論(analysis)
  • ユーザー向けの中間通知(commentary)および最終回答(final)
  • ユーザー定義関数(function tools)の呼び出し
  • 組み込みツール(browser / python)の実行
  • 構造化出力(JSON Schema等に基づく出力)
なお、実装においてHarmonyフォーマットを手動で構築することは推奨されず、openai-harmony ライブラリ、または公式のチャットテンプレートを利用することが基本方針となる。

1.1 フォーマットの位置づけ

Harmonyは、単純なロールベースのチャットテンプレートを拡張した概念であり、主に以下の特長を持つ。
  • assistantの出力を analysis / commentary / final の独立したチャンネルに分割可能。
  • ツール呼び出し(tool call)の終端を <|call|> トークンで制御。
  • 最終回答(final answer)の終端を <|return|> トークンで制御。
  • 次ターンの会話履歴を構築する際、終端の <|return|> を完了状態を示す <|end|> に正規化可能。
  • ツール呼び出しのシーケンス内に、推論プロセス(reasoning)を介在させることが可能。
  • developerメッセージ内に、スキーマ定義を伴うレスポンスフォーマット(response format)を組み込み可能。

2. 参照リソース

本仕様書の策定にあたり、以下の公開情報を一次ソースおよび二次ソースとして参照した。

2.1 公式・準公式ドキュメント

  1. OpenAI Cookbook: OpenAI Harmony Response Format https://developers.openai.com/cookbook/articles/openai-harmony
  2. GitHub: openai/harmony https://github.com/openai/harmony
  3. openai/harmony Python API docs
  4. openai/harmony 実装コード (src/encoding.rs)
  5. GitHub: openai/gpt-oss https://github.com/openai/gpt-oss
  6. OpenAI Cookbook: How to run gpt-oss with Hugging Face Transformers https://github.com/openai/openai-cookbook/blob/main/articles/gpt-oss/run-transformers.md

2.2 実装済みテンプレートおよびモデル資産

  1. Hugging Face openai/gpt-oss-20b chat_template.jinja
  2. Hugging Face openai/gpt-oss-20b tokenizer_config.json
  3. vLLM Recipe: GPT OSS https://docs.vllm.ai/projects/recipes/en/latest/OpenAI/GPT-OSS.html
  4. Ollama gpt-oss テンプレート blob

2.3 本書における情報精査のスタンス

  • 公式ドキュメント(2.1)を一次情報 として扱う。
  • ただし、実際のシステムの振る舞いはチャットテンプレート、トークナイザ設定、およびライブラリの実装に依存するため、これらの二次情報(2.2)も仕様の一部として包括的に評価する。
  • 公式ドキュメントの記述と、実際の実装・テンプレート間で乖離が確認された場合は、その差異を明記する。
  • 用途が公開されていない特殊トークンについては「未定義」または「不明」として扱い、推測による意味付けは行わない。

3. Harmony の設計思想

3.1 アーキテクチャの基本概念

Harmony は、「モデルの出力は単一の連続した文字列ではない」という前提に基づき設計されたフォーマットである。Assistant ロールの出力は、単一のテキスト生成ではなく、以下の段階的なプロセスを包含する:
  1. analysis チャンネルによる内部推論(CoT)の実行
  2. commentary チャンネルによるユーザー向けの中間通知(例: 「検索を開始します」などの宣言)
  3. commentary または analysis チャンネルを経由した関数・ツール呼び出し(Tool Call)
  4. ツール実行結果の読み込み
  5. final チャンネルによる最終回答の出力
このように、「内部思考」「中間通知」「最終回答」の出力経路を論理的に独立したチャンネルとして分離することが、本フォーマットの中核的な設計思想である。

3.2 gpt-oss における必須要件

公式ドキュメントにおいて、gpt-oss 系モデルは Harmony フォーマットを適用せずに利用すべきではないと明言されている。Transformers、Ollama、vLLM などの推論フレームワーク上で Harmony の仕様を直接意識せずに稼働させられるのは、各フレームワークがバックグラウンドでテンプレートの適用およびパース処理を代行しているためである。

4. 概念モデル

4.1 ロール定義

Harmony では、以下の 5 つのロールを規定している。
ロール優先順位用途代表例
system1モデルの固定的なメタ情報(identity、knowledge cutoff、date、reasoning、built-in tools、valid channels)の定義You are ChatGPT...
developer2アプリケーション開発者からの指示、関数ツール定義、出力フォーマット(response format)の定義# Instructions
user3エンドユーザーからの入力質問・依頼
assistant4モデルの出力(analysis / commentary / final の各チャンネルを利用)内部思考、途中説明、最終回答、ツール呼び出し
tool5ツール呼び出しに対する実行結果の返却天気 API の JSON、browser 出力、python 実行結果

4.2 命令の優先順位(Instruction Hierarchy)

Harmony においては、ロールの階層自体がそのまま命令の優先順位(Instruction Hierarchy)として機能する。
  • 優先順位: system > developer > user > assistant > tool
下位のロールで指定された指示(例: developer による「日本語で回答せよ」という指示)が、上位のロール(例: system)の定義と矛盾する場合、常に上位ロールの定義が優先して適用される。

4.3 system ロールの特殊性

一般的なチャットモデルの実装においては「アプリケーション固有の指示」を system プロンプトとして扱うことが多いが、Harmony においては、アプリケーション固有の指示は developer ロールに記述することが原則となる。
Harmony における system ロールは、以下のような「基盤となるメタ情報」の定義専用として厳密に区別される。
  • 固定的なアイデンティティ(例: You are ChatGPT, a large language model trained by OpenAI.)
  • 知識のカットオフ時期(Knowledge cutoff: ...)
  • 現在日時(Current date: ...)
  • 推論レベル(Reasoning: low | medium | high)
  • 組み込みツール(built-in tools)の定義
  • 有効なチャンネル(valid channels)の宣言

4.4 実装フレームワークとの差異(Transformers の事例)

Hugging Face が提供する公式の chat_template.jinja では、入力メッセージ配列の先頭ロールが system または developer のいずれであっても、内部的に Harmony の developer メッセージとして再解釈される仕様となっている。正規の Harmony system メッセージは、当該テンプレートによって自動生成される。
Transformers における入力構成例:
messages = [
    {"role": "system", "content": "必ず日本語で答えてください"},
    {"role": "user", "content": "こんにちは"},
]
Harmony フォーマットにおける内部展開の概念図:
<|start|>system<|message|>You are ChatGPT, a large language model trained by OpenAI.
Knowledge cutoff: 2024-06
Current date: 2026-04-04

Reasoning: medium

# Valid channels: analysis, commentary, final. Channel must be included for every message.<|end|>
<|start|>developer<|message|># Instructions

必ず日本語で答えてください

<|end|>
<|start|>user<|message|>こんにちは<|end|>
<|start|>assistant
このように、一般的な推論 API における system 指定と、Harmony 規格における純粋な system メッセージは実体として異なるため、実装および運用において両者を明確に区別する必要がある。

5. チャンネル (Channels)

assistantメッセージは、用途に応じて以下の3つのチャンネルを使用する。
チャンネル用途ユーザーへの表示典型例
analysis内部推論、CoT(Chain of Thought)、組み込みツールの呼び出し非表示数式検討、検索計画の策定、Pythonコード
commentaryユーザー向けの中間通知(preamble)、通常の関数(function tool)呼び出し任意(要件に依存)「まず検索します」などの通知
final最終回答表示最終的な応答内容

5.1 各チャンネルの最小構成例

analysis
<|start|>assistant<|channel|>analysis<|message|>Need to verify the date before answering.<|end|>
commentary
<|start|>assistant<|channel|>commentary<|message|>最新情報を確認してから答えます。<|end|>
final
<|start|>assistant<|channel|>final<|message|>結論は 42 です。<|return|>

5.2 ユーザー定義関数(Function Tool)と組み込みツール(Built-in Tool)の差異

原則として、ユーザー定義の関数ツールはcommentaryチャンネルで呼び出し、組み込みツール(browser / python)はanalysisチャンネルで呼び出す仕様となっている。ただし、公式のドキュメントにおいては組み込みツールがcommentaryで出力されるケースも言及されているため、これらは絶対的な制約ではなく、標準的な挙動として定義されている。

5.3 仕様定義と実装間の差異

定型的なsystemメッセージには # Valid channels: analysis, commentary, final. Channel must be included for every message. という指定が含まれる。しかし、公式のリファレンステンプレートやAPIの実装において、system、developer、userメッセージにチャンネルが付与されることはない。実運用においては、「assistantが生成するメッセージに対してのみチャンネルを明示する」ものとして扱う。

6. メッセージの基本構文

6.1 基本構造

Harmonyにおけるメッセージの基本構文は以下の通りである。
<|start|>{header}<|message|>{content}<|end|>
assistant生成時の終端トークンは、コンテキストに応じて以下の3種類から選択される。
  • 通常の完結メッセージ: <|end|>
  • 最終回答の生成完了(デコード停止): <|return|>
  • ツール呼び出しの生成完了(デコード停止): <|call|>

6.2 擬似BNF定義

本構文の実用上の擬似BNF定義を以下に示す。
message      := "<|start|>" header "<|message|>" content terminator
header       := author [recipient] [channel] [content_type]
author       := role | role ":" name | tool_name
recipient    := " to=" recipient_name
channel      := "<|channel|>" channel_name
content_type := " " plain_type | " <|constrain|>" constrained_type
terminator   := "<|end|>" | "<|return|>" | "<|call|>"

6.3 ツール呼び出しヘッダの構造解析

以下のツール呼び出しメッセージを例に、各要素を解説する。
<|start|>assistant to=functions.get_current_weather<|channel|>commentary <|constrain|>json<|message|>{"location":"Tokyo"}<|call|>
  • <|start|>: メッセージの開始を示すトークン。
  • assistant: 発信者のロール。
  • to=functions.get_current_weather: 呼び出し先の関数指定。
  • <|channel|>commentary: 使用するチャンネル。
  • <|constrain|>json: ペイロードのデータ型。
  • <|message|>: ヘッダ部と本文(コンテンツ)の境界トークン。
  • {"location":"Tokyo"}: 本文(JSON形式の引数)。
  • <|call|>: ツール呼び出し用の終端トークン。ここで推論を停止し、ツールの実行プロセスへ移行する。

7. 生成時の「assistant プレフィル」の仕様

一般的な推論リクエストにおいて、入力プロンプトの末尾は以下のように<|start|>assistantで終端される。
<|start|>user<|message|>What is 2 + 2?<|end|>
<|start|>assistant
この状態から生成処理が開始されるため、モデルの初回出力においてassistantロールを再宣言する必要はない。その結果、公式の例に見られるように、モデルの生成文字列は以下のようにチャンネル指定から開始される。
<|channel|>analysis<|message|>...
これは出力の欠落や破損ではなく、プロンプト末尾で提示済みの<|start|>assistantに対する正常な継続生成として設計された仕様である。

8. systemメッセージの仕様

8.1 構成要件

systemメッセージには、以下の要素を含めることが推奨される:
  • 固定のアイデンティティ: 例として「You are ChatGPT, a large language model trained by OpenAI.」などを指定する。
  • Knowledge cutoff: 知識のカットオフ日を指定する。
  • Current date: 現在の日付を指定する。
  • Reasoning: 推論の度合いを low、medium、high のいずれかで指定する。
  • built-in tools: 必要に応じて組み込みツールを定義する。
  • valid channels: 有効なチャンネル(analysis, commentary, final)を宣言する。
  • function toolsの指定: function toolsを使用する場合は、該当ツールをcommentaryチャンネルで呼び出すよう指定する記述を追加する。

8.2 最小構成例

<|start|>system<|message|>You are ChatGPT, a large language model trained by OpenAI.
Knowledge cutoff: 2024-06
Current date: 2026-04-04

Reasoning: high

# Valid channels: analysis, commentary, final. Channel must be included for every message.<|end|>

8.3 function toolsを定義する場合の構成例

function toolsを利用する際は、該当ツールへの呼び出しがcommentaryチャンネルで行われる旨を明記する。
<|start|>system<|message|>You are ChatGPT, a large language model trained by OpenAI.
Knowledge cutoff: 2024-06
Current date: 2026-04-04

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|>

8.4 built-in toolsを定義する場合の構成例

<|start|>system<|message|>You are ChatGPT, a large language model trained by OpenAI.
Knowledge cutoff: 2024-06
Current date: 2026-04-04

Reasoning: medium

# Tools

## browser

// Tool for browsing.
// The `cursor` appears in brackets before each browsing display: `[{cursor}]`.
// Cite information from the tool using the following format:
// `〖{cursor}†L{line_start}(-L{line_end})?〗`, for example: `〖6†L9-L11〗` or `〖8†L3〗`.
// Do not quote more than 10 words directly from the tool output.
// sources=web (default: web)
namespace browser {

type search = (_: {
query: string,
topn?: number, // default: 10
source?: string,
}) => any;

type open = (_: {
id?: number | string, // default: -1
cursor?: number, // default: -1
loc?: number, // default: -1
num_lines?: number, // default: -1
view_source?: boolean, // default: false
source?: string,
}) => any;

type find = (_: {
pattern: string,
cursor?: number, // default: -1
}) => any;

} // namespace browser

## python

Use this tool to execute Python code in your chain of thought. The code will not be shown to the user.
When you send a message containing Python code to python, it will be executed in a stateful Jupyter notebook environment...

# Valid channels: analysis, commentary, final. Channel must be included for every message.<|end|>

8.5 アイデンティティ変更に関する仕様上の注意

公式ドキュメントでは、アイデンティティ(identity)は固定とし、モデルの人格や振る舞いを変更する場合はdeveloperメッセージ(developer instructions)を使用することが推奨されている。 APIやテンプレートの引数レベルでは model_identity の変更が技術的に可能であるものの、仕様上の推奨運用は「固定」である点に留意が必要である。

9. developerメッセージの仕様

developerメッセージは、従来の一般的なシステムプロンプト(アプリケーション固有の指示)を記述するための領域として機能する。 標準的に以下の3つのセクションから構成される。
  • # Instructions
  • # Tools
  • # Response Formats

9.1 Instructionsのみを用いた最小構成例

<|start|>developer<|message|># Instructions

必ず日本語で、箇条書きは最小限にして答えてください。<|end|>

9.2 function toolsを含む構成例

<|start|>developer<|message|># Instructions

フレンドリーな口調で答えてください。

# Tools

## functions

namespace functions {

// 現在地を返す
type get_location = () => any;

// 指定都市の現在天気を返す
type get_current_weather = (_: {
// 市名。例: "Tokyo"
location: string,
// 単位
format?: "celsius" | "fahrenheit", // default: celsius
}) => any;

} // namespace functions<|end|>

9.3 structured output(構造化出力)を含む構成例

<|start|>developer<|message|># Instructions

あなたは買い物リスト作成アシスタントです。

# Response Formats

## shopping_list

{"type":"object","properties":{"items":{"type":"array","items":{"type":"string"},"description":"買い物項目"}},"required":["items"]}<|end|>

10. userメッセージの仕様

userメッセージは、エンドユーザーからの入力を保持するための最も基本的なメッセージ領域である。

10.1 基本構文例

<|start|>user<|message|>東京の今日の気温を教えて<|end|>

10.2 拡張構文(名前付きauthor)

openai/harmony の実装上では、userおよびassistantに対して名前付きのauthor(role:name)を付与する書式がサポートされている。 以下の例のように記述可能である。
<|start|>user:alice<|message|>こんにちは<|end|>
ただし、公開されている公式ドキュメントの一般的なユースケースにおいて、名前付きauthorは利用されていない。 したがって、通常の用途においては無名の user または assistant を指定する構成で要件を満たすものとする。

11. assistant message の仕様

assistantメッセージは、Harmonyフォーマットにおいて中心的な役割を担う。 用途に応じて以下の4つのタイプを使い分ける仕様となっている。
  1. analysis: 内部推論
  2. commentary: ユーザー向けの中間説明およびプリアンブル
  3. final: 最終回答
  4. to=... 属性を持つツール呼び出し(tool call)

11.1 final の基本構文

<|start|>assistant<|channel|>final<|message|>2 + 2 = 4 です。<|return|>

11.2 analysis の基本構文

<|start|>assistant<|channel|>analysis<|message|>ユーザーは単純な算数を聞いている。直接答える。<|end|>

11.3 commentary の基本構文

<|start|>assistant<|channel|>commentary<|message|>まず公式情報を確認します。<|end|>

11.4 function tool call の基本構文

Cookbookに準拠した標準的なツール呼び出しの例を以下に示す。
<|start|>assistant<|channel|>analysis<|message|>Need to use function get_current_weather.<|end|>
<|start|>assistant<|channel|>commentary to=functions.get_current_weather <|constrain|>json<|message|>{"location":"San Francisco"}<|call|>

11.5 実装上の差異: Hugging Faceテンプレートにおける json のプレーンテキスト出力

Hugging Faceが提供する chat_template.jinja においては、ツール呼び出し時の content_type が、デフォルトでプレーンテキストの json としてヘッダに配置される。 これにより、実際のレンダリング結果は以下のようになる場合がある。
<|start|>assistant to=functions.get_current_weather<|channel|>commentary json<|message|>{"location":"San Francisco"}<|call|>
一方、公式のCookbookでは <|constrain|>json を用いた例が示されている。 openai/harmony の実装上、content_type は以下の双方を許容する仕様となっている。
  • プレーンテキストの "json"
  • 特殊トークンを用いた "<|constrain|>json"
したがって、Cookbookの記述とHugging Faceテンプレートの出力形式には表面上の差異が存在するものの、システムとしては両方の表現を受け付ける設計となっている。

12. tool message の仕様

toolメッセージは、実行されたツールの結果をモデルに返却するためのメッセージである。

12.1 シリアライズ時におけるrole属性の扱い

シリアライズ処理において、roleの位置にはリテラル文字列としての tool ではなく、具体的な「ツール名」が配置される点に留意する必要がある。 公式Cookbookの仕様に準拠したシリアライズの例を以下に示す。
<|start|>functions.get_current_weather to=assistant<|channel|>commentary<|message|>{"sunny":true,"temperature":20}<|end|>
上記の通り、ヘッダの先頭要素は tool ではなく functions.get_current_weather となる。

12.2 built-in python ツールのメッセージ例

<|start|>python to=assistant<|channel|>analysis<|message|>55<|end|>

12.3 built-in browser ツールのメッセージ例

<|start|>browser.search to=assistant<|channel|>analysis<|message|>[12] Bank of Japan - Policy Interest Rate<|end|>

13. reasoning / CoT のライフサイクル

13.1 基本原則

推論プロセスにおける基本的な原則は以下の通りである。
  • gpt-oss は推論モデル(reasoning model)として機能する。
  • 推論の強度(reasoning effort)は low、medium、high のいずれかで指定される。
  • 生の推論過程(CoT: Chain of Thought)は analysis チャンネルに出力される。
  • analysis チャンネルの内容は、エンドユーザーに対しては非表示とする仕様である。
  • ユーザーに対する最終的な回答は final チャンネルを介して出力される。

13.2 標準的な推論の例

入力

<|start|>user<|message|>What is 2 + 2?<|end|>
<|start|>assistant

出力

<|channel|>analysis<|message|>User asks: "What is 2 + 2?" Simple arithmetic. Provide answer.<|end|>
<|start|>assistant<|channel|>final<|message|>2 + 2 = 4.<|return|>

13.3 <|return|> と <|end|> の使い分け

終端トークンの扱いは、コンテキストに応じて以下の通り使い分ける必要がある。
  • 生成停止時点の最終回答: <|return|>
  • 会話履歴としての保存時: <|end|>
次ターンに向けた会話履歴に assistant の final メッセージを格納する際は、<|return|> をそのまま保持するのではなく、以下のように <|end|> へ正規化する処理が求められる。
正規化前(生成直後):
<|start|>assistant<|channel|>final<|message|>2 + 2 = 4.<|return|>
正規化後(履歴保存時):
<|start|>assistant<|channel|>final<|message|>2 + 2 = 4.<|end|>

13.4 正規化の必要性について

<|return|> はデコード時の停止トークン(decode-time stop token)として機能し、「当該応答の生成完了」を指示するものである。 そのため、公式Cookbookの仕様に基づき、会話履歴における完了済みメッセージ(completed message)の終端は <|end|> に統一することが正規の取り扱いとなる。

13.5 ツール呼び出し途中におけるCoTの保持

通常、過去ターンのCoTは履歴から除外可能(または除外が推奨)とされる。 しかし、ツール呼び出しが進行中の状況においては例外となる。 assistant は以下のフローで処理を実行する。
  1. analysis の出力
  2. ツール呼び出しの出力
  3. ツール実行結果の受領
  4. 推論の継続、または final の出力
この一連のプロセスにおいて、ツール呼び出し直前の analysis は、推論生成を継続するためのコンテキストとして履歴に保持する必要がある。
例:
<|start|>assistant<|channel|>analysis<|message|>Need to use function get_current_weather.<|end|>
<|start|>assistant<|channel|>commentary to=functions.get_current_weather <|constrain|>json<|message|>{"location":"San Francisco"}<|call|>
<|start|>functions.get_current_weather to=assistant<|channel|>commentary<|message|>{"sunny": true, "temperature": 20}<|end|>
<|start|>assistant

13.6 openai-harmony および Hugging Faceテンプレートにおける自動除外の挙動

各公開実装における履歴の処理方針は以下の通りである。
  • openai-harmony には、RenderConversationConfig(auto_drop_analysis=True) が実装されている。
  • Hugging Faceの chat_template.jinja は、後続に final が存在する場合、それ以前の tool-CoT および analysis を破棄するロジックを内包している。
実用的なシステム実装においては、会話履歴に不要な analysis メッセージを過剰に蓄積させない設計が標準となっている。

13.7 Hugging Faceテンプレート適用時の制約

chat_template.jinja は、以下の前提に基づいて動作する。
  • assistant の1メッセージにつき、最大1回のツール呼び出しが行われるものと想定する。
  • tool ロールのメッセージにおけるツール名は、直前の assistant によるツール呼び出し名から推定される。
  • content と thinking を同時に内包する assistant のツール呼び出しメッセージは、例外として処理される。
この仕様により、手動でメッセージ配列を構築する場合は、テンプレートが許容する構造に適合させる必要がある。

14. Function Tool 定義の仕様

14.1 基本ルール

公式Cookbookにおいて推奨される Function Tool の定義書式は以下の通りである。
  • 名前空間は namespace functions { ... } の形式で宣言する。
  • 引数を持たない関数は type foo = () => any; と定義する。
  • 引数を持つ関数は type foo = (_: { ... }) => any; と定義する。
  • 各フィールドの上部には // を用いて説明(コメント)を記述する。
  • 戻り値の型(return type)は常に any を指定する。

14.2 完全例

# Tools

## functions

namespace functions {

// ユーザーの位置情報を返す
type get_location = () => any;

// 指定都市の現在天気を返す
type get_current_weather = (_: {
// 都市名。例: "Tokyo"
location: string,
// 温度単位
format?: "celsius" | "fahrenheit", // default: celsius
}) => any;

// 複数都市の天気を一括取得
type get_multiple_weathers = (_: {
// 都市一覧
locations: string[],
format?: "celsius" | "fahrenheit", // default: celsius
}) => any;

} // namespace functions

14.3 JSON Schema から TypeScript 風シグネチャへの変換

Hugging Face の chat_template.jinja および openai/harmony の実装において、ツール定義は元の JSON Schema(または OpenAI 型の tool spec)から Harmony 向けの TypeScript 風文字列へと内部的にレンダリングされる。
その際の代表的な変換規則は以下の通りである。
  • 配列型は string[]、number[]、boolean[] 等へ変換される。
  • Enum型は "a" | "b" | "c" のようなユニオン型へ変換される。
  • 必須(required)でないプロパティには ? が付与される。
  • デフォルト値は // default: ... の形式でコメントとして明記される。
  • 複雑なユニオン型やオブジェクト型は、any 型へフォールバックされる場合がある。

15. Built-in Tools の仕様

Harmony(gpt-oss)の公開資料において、主として以下の2つの組み込みツール(Built-in Tools)が定義されている。
  • browser
  • python

15.1 browser

15.1.1 役割

  • Web検索
  • Webページの展開(開く)
  • ページ内検索
  • 行番号を伴う情報引用

15.1.2 テンプレート上の定義

## browser

// Tool for browsing.
// The `cursor` appears in brackets before each browsing display: `[{cursor}]`.
// Cite information from the tool using the following format:
// `〖{cursor}†L{line_start}(-L{line_end})?〗`
// Do not quote more than 10 words directly from the tool output.
// sources=web (default: web)
namespace browser {

type search = (_: {
query: string,
topn?: number, // default: 10
source?: string,
}) => any;

type open = (_: {
id?: number | string, // default: -1
cursor?: number, // default: -1
loc?: number, // default: -1
num_lines?: number, // default: -1
view_source?: boolean, // default: false
source?: string,
}) => any;

type find = (_: {
pattern: string,
cursor?: number, // default: -1
}) => any;

} // namespace browser

15.1.3 呼び出しチャンネル

公式仕様上、browser ツールは通常 analysis チャンネル内で呼び出される。

15.1.4 具体例

<|start|>assistant<|channel|>analysis<|message|>Need to verify the latest policy rate from an official source.<|end|>
<|start|>assistant to=browser.search<|channel|>analysis <|constrain|>json<|message|>{"query":"site:boj.or.jp policy rate","topn":5,"source":"web"}<|call|>
<|start|>browser.search to=assistant<|channel|>analysis<|message|>[12] Bank of Japan - Monetary Policy<|end|>
<|start|>assistant to=browser.open<|channel|>analysis <|constrain|>json<|message|>{"cursor":12,"id":0,"loc":120,"num_lines":20,"source":"web"}<|call|>
<|start|>browser.open to=assistant<|channel|>analysis<|message|>[13]
L120: ...
L121: ...
L122: ...<|end|>
<|start|>assistant<|channel|>final<|message|>公式資料では政策金利は 0.5% と記載されています。〖13†L120-L122〗<|return|>

15.2 python

15.2.1 役割

  • 内部推論過程における計算処理
  • データの整形処理
  • 小規模なコードの実行
  • 最終生成物(表、図、ファイル等)の出力準備作業

15.2.2 テンプレート上の規定

テンプレートにおける本ツールの仕様は以下の通り規定されている。
  • Chain-of-Thought(CoT)の過程として Python コードの実行が可能である。
  • 実行されるコードはエンドユーザーには非表示とする前提である。
  • ステートフルな Jupyter ノートブック風の環境が提供される。
  • 実行にはタイムアウト制約が存在する。
  • /mnt/data ディレクトリへのアクセスが許可されている。
  • インターネットアクセスの可否は、ホストされるクラスターの環境設定に依存し、一律ではない。

15.2.3 呼び出しチャンネル

公式仕様上、python ツールも通常 analysis チャンネル内で呼び出される。

15.2.4 具体例

<|start|>assistant<|channel|>analysis<|message|>Need exact computation for the sum of squares from 1 to 5.<|end|>
<|start|>assistant to=python<|channel|>analysis<|message|>sum(i*i for i in range(1, 6))<|call|>
<|start|>python to=assistant<|channel|>analysis<|message|>55<|end|>
<|start|>assistant<|channel|>final<|message|>1^2 から 5^2 までの和は 55 です。<|return|>

16. Structured Output の仕様

Harmony フォーマットでは、developer メッセージの末尾に # Response Formats セクションを宣言することで、対象の JSON Schema を埋め込むことが可能である。

16.1 書式

# Response Formats

## {format_name}

// 任意の説明
{json_schema}

16.2 具体例

<|start|>developer<|message|># Instructions

あなたは買い物アシスタントです。

# Response Formats

## shopping_list

{"type":"object","properties":{"items":{"type":"array","items":{"type":"string"},"description":"entries on the shopping list"}},"required":["items"]}<|end|>
<|start|>user<|message|>コーヒー、卵、牛乳を買いたい<|end|>
<|start|>assistant
想定される出力例:
<|start|>assistant<|channel|>final<|message|>{"items":["コーヒー","卵","牛乳"]}<|return|>

17. 公開特殊トークン(Special Tokens)一覧

本章では、Hugging Faceで公開されている openai/gpt-oss-20b の tokenizer_config.json に含まれる、すべての追加特殊トークン(added special tokens)について定義する。

17.1 仕様が公開されている特殊トークン

運用上の意味が明示されており、実際に使用される特殊トークンの一覧を以下に示す。
Token IDトークン用途・仕様具体例
199998<|startoftext|>BOSトークン。トークナイザにより先頭に付与されるため、通常手動入力は行わない。-
199999<|endoftext|>Padトークン。バッチ処理のパディングに使用されるため、通常手動入力は行わない。-
200002<|return|>最終回答(final answer)生成時のデコード停止用トークン。<|start|>assistant<|channel|>final<|message|>答えです。<|return|>
200003<|constrain|>コンテンツタイプおよびフォーマット制約の明示。... <|constrain|>json<|message|>{"x":1}<|call|>
200005<|channel|>チャンネルの区切り文字。assistant<|channel|>analysis
200006<|start|>メッセージの開始位置の明示。<|start|>user<|message|>こんにちは<|end|>
200007<|end|>完結したメッセージの終了位置の明示。<|start|>user<|message|>こんにちは<|end|>
200008<|message|>ヘッダ部とメッセージ本文の区切り文字。user<|message|>こんにちは
200012<|call|>ツール呼び出し(tool call)生成時のデコード停止用トークン。... {"location":"Tokyo"}<|call|>
200018<|endofprompt|>トークナイザ上の特殊トークン。公開されているHarmonyの文法仕様において通常の用途は定義されていない。-

17.2 予約済み特殊トークン

以下のトークンは予約済み(Reserved)であり、公開仕様における意味は定義されていない。プロンプトへの手動挿入は非推奨とする。
  • <|reserved_200000|>
  • <|reserved_200001|>
  • <|reserved_200004|>
  • <|reserved_200009|>
  • <|reserved_200010|>
  • <|reserved_200011|>
  • <|reserved_200013|>
  • <|reserved_200014|>
  • <|reserved_200015|>
  • <|reserved_200016|>
  • <|reserved_200017|>

17.3 トークナイザ設定の補足事項

tokenizer_config.json における基本的なトークン割り当ては以下の通りである。
  • bos_token = "<|startoftext|>"
  • eos_token = "<|return|>"
  • pad_token = "<|endoftext|>"
gpt-oss において、シーケンスの終端(EOS)を示す停止トークンが <|return|> に設定されている点に留意すること。

17.4 予約済みトークンの取り扱いに関する注意事項

公開仕様において意味が保証されていないため、予約済みトークンをプロンプト内に手動で構成することは認められない。
非推奨となる入力例:
<|start|>user<|message|>Hello<|reserved_200015|><|end|>

18. openai/harmony 実装依存の追加フォーマットトークン

openai/harmony ライブラリの FormattingToken 列挙型(enum)には、前章の特殊トークン一覧には含まれない以下のトークンが定義されている。また、MetaSep は <|channel|> にマッピングされている。
  • <|refusal|>
  • <|untrusted|>
  • <|end_untrusted|>
  • <|meta_end|>

18.1 追加フォーマットトークンの取り扱い

これらのトークンはライブラリ内部の実装として存在するが、公開されている gpt-oss-20b のトークナイザ設定(added special tokens)には含まれていない。したがって、公開モデルに対する通常のプロンプト入力として正常に機能するかは保証されない。

18.2 非推奨となる入力例

以下のトークンを含む文字列を手動で構成し、公開モデルへの入力とすることは非推奨とする。
<|start|>assistant<|channel|>final<|refusal|><|message|>...

19. ロール別メッセージ構文の具体例

各ロールの定義およびメッセージ構文の具体例を以下に示す。
ロール定義・用途具体例
systemメタ情報の定義<|start|>system<|message|>You are ChatGPT...<|end|>
developer開発者による指示事項<|start|>developer<|message|># Instructions\n\n必ず日本語で答える<|end|>
userエンドユーザーからの入力<|start|>user<|message|>東京の天気は?<|end|>
assistantモデルからの出力<|start|>assistant<|channel|>final<|message|>晴れです。<|return|>
toolツール実行結果の返却<|start|>functions.get_current_weather to=assistant<|channel|>commentary<|message|>{"sunny":true}<|end|>

19.1 tool ロールのシリアライズ仕様

抽象的なロール名である tool は、シリアライズされた通信データ(ワイヤ形式)上においては、実際に呼び出された具体的なツール名に置換される仕様である。
シリアライズ例:
<|start|>functions.search_docs to=assistant<|channel|>commentary<|message|>{"results":[...]}<|end|>

19.2 留意事項

本仕様はあくまで Harmony における「プロンプト上の記述規則」を定義するものであり、この記述単体によって厳密な出力制約(フォーマットの強制)が完全に担保されるわけではない。 厳格な構造化出力を要件とする場合は、推論サービング側が提供する文法制約(Grammar)や Constrained Decoding、Structured Output 機構等と併用して実装することが推奨される。

20. 各チャンネルのメッセージ構成例

各チャンネルにおけるメッセージの構成と具体例を以下に示す。
チャンネル定義・用途具体例
analysis内部推論(ユーザーには非表示とする)<|start|>assistant<|channel|>analysis<|message|>Need to compute exactly.<|end|>
commentary処理の中間説明、または関数呼び出し(ユーザーに表示可能)<|start|>assistant<|channel|>commentary<|message|>まず検索します。<|end|>
final最終回答<|start|>assistant<|channel|>final<|message|>結論は 55 です。<|return|>

20.1 commentary チャンネルに関する留意事項

commentary チャンネルは、最終回答ではないものの、ユーザーに対する途中経過の提示として使用可能である。 複数のツールを連続して実行する前に、事前の行動計画を出力する用途などで用いられる。
  • 出力例:
<|start|>assistant<|channel|>commentary<|message|>作業計画:
1. 公式サイトを検索
2. PDF を開く
3. 要点を要約
順番に進めます。<|end|>

21. 対話シーケンスの具体例

以下に各種ユースケースごとのメッセージ送受信シーケンスを示す。

21.1 基本応答および推論プロセス

  • 入力メッセージ:
<|start|>system<|message|>You are ChatGPT, a large language model trained by OpenAI.
Knowledge cutoff: 2024-06
Current date: 2026-04-04

Reasoning: high

# Valid channels: analysis, commentary, final. Channel must be included for every message.<|end|>
<|start|>user<|message|>2 + 2 は?<|end|>
<|start|>assistant
  • モデル出力:
<|channel|>analysis<|message|>ユーザーは単純な加算を尋ねている。直接答えればよい。<|end|>
<|start|>assistant<|channel|>final<|message|>2 + 2 = 4 です。<|return|>
  • 次ターン用履歴データの正規化:
<|start|>assistant<|channel|>final<|message|>2 + 2 = 4 です。<|end|>

21.2 ユーザー定義関数(Function Call)と推論プロセス

  • ツール定義(developer ロールに配置):
<|start|>developer<|message|># Instructions

天気は簡潔に答えてください。

# Tools

## functions

namespace functions {

// 指定都市の現在天気を返す
type get_current_weather = (_: {
// 都市名
location: string,
}) => any;

} // namespace functions<|end|>
  • ユーザー入力:
<|start|>user<|message|>サンフランシスコの天気は?<|end|>
<|start|>assistant
  • 初回モデル出力(ツール呼び出し):
<|channel|>analysis<|message|>Need to use function get_current_weather.<|end|>
<|start|>assistant<|channel|>commentary to=functions.get_current_weather <|constrain|>json<|message|>{"location":"San Francisco"}<|call|>
  • ツール実行結果の返却:
<|start|>functions.get_current_weather to=assistant<|channel|>commentary<|message|>{"sunny":true,"temperature":20,"unit":"celsius"}<|end|>
<|start|>assistant
  • 2回目モデル出力(最終回答):
<|channel|>analysis<|message|>Tool says sunny and 20C. Provide concise final answer in Japanese.<|end|>
<|start|>assistant<|channel|>final<|message|>サンフランシスコは晴れ、20℃です。<|return|>
  • 仕様上の留意点:
    • analysis チャンネルの出力はユーザーに対して非表示とする。
    • ツールの呼び出しは <|call|> トークンで停止する。
    • 実行結果を返却したのち、末尾に <|start|>assistant を付与して生成処理を再開する。

21.3 組み込みツール(browser)の利用

要件: 日本銀行の最新の政策金利を公式サイトから取得して回答する。
  • 実行シーケンス例:
<|start|>assistant<|channel|>analysis<|message|>Need an official and recent source from the Bank of Japan website.<|end|>
<|start|>assistant to=browser.search<|channel|>analysis <|constrain|>json<|message|>{"query":"site:boj.or.jp policy interest rate","topn":5,"source":"web"}<|call|>
<|start|>browser.search to=assistant<|channel|>analysis<|message|>[12] Bank of Japan - Monetary Policy Meetings<|end|>
<|start|>assistant to=browser.open<|channel|>analysis <|constrain|>json<|message|>{"cursor":12,"id":0,"loc":120,"num_lines":10,"source":"web"}<|call|>
<|start|>browser.open to=assistant<|channel|>analysis<|message|>[13]
L120: ...
L121: The uncollateralized overnight call rate ...
L122: ...
<|end|>
<|start|>assistant<|channel|>final<|message|>日銀の公式資料では、無担保コール翌日物金利の誘導目標は 0.5% とされています。〖13†L121-L122〗<|return|>
  • 仕様上の留意点:
    • browser ツールは原則として analysis チャンネル上で実行される。
    • 最終回答時の引用には行番号指定フォーマット(〖cursor†Lx-Ly〗)を使用する。
    • ツール出力からの直接的な文字列引用は、テンプレートの制約により10語以内とされる。

21.4 組み込みツール(python)の利用

要件: 1の2乗から5の2乗までの総和を厳密に計算する。
  • 実行シーケンス例:
<|start|>assistant<|channel|>analysis<|message|>Need exact calculation; using python is simplest.<|end|>
<|start|>assistant to=python<|channel|>analysis<|message|>sum(i*i for i in range(1, 6))<|call|>
<|start|>python to=assistant<|channel|>analysis<|message|>55<|end|>
<|start|>assistant<|channel|>final<|message|>1^2 から 5^2 までの和は 55 です。<|return|>
  • 仕様上の留意点:
    • Pythonコードの実行自体はフォーマット上可視化されるが、analysis チャンネルを使用するためユーザーUIには表示させない設計が原則となる。

21.5 複数ツール実行前の事前通知(Commentary Preamble)

  • 実行シーケンス例:
<|start|>assistant<|channel|>analysis<|message|>Need a multi-step plan involving file generation and server startup.<|end|>
<|start|>assistant<|channel|>commentary<|message|>作業計画:
1. HTML ファイルを生成
2. Node.js サーバーコードを生成
3. 起動確認
---
順番に実行します。<|end|>
<|start|>assistant to=functions.generate_file<|channel|>commentary <|constrain|>json<|message|>{"template":"basic_html","path":"index.html"}<|call|>
  • 仕様上の留意点:
    • commentary は直近の処理に関するユーザー向けの中間報告として機能する。
    • final はすべての処理が完了した後の最終成果物として位置づけられる。

21.6 構造化出力(Structured Output)の単独返却

  • developer 設定例:
<|start|>developer<|message|># Instructions

買い物リストだけを返してください。

# Response Formats

## shopping_list

{"type":"object","properties":{"items":{"type":"array","items":{"type":"string"}}},"required":["items"]}<|end|>
  • ユーザー入力:
<|start|>user<|message|>コーヒー、炭酸水、卵が必要<|end|>
<|start|>assistant
  • 出力例:
<|start|>assistant<|channel|>final<|message|>{"items":["コーヒー","炭酸水","卵"]}<|return|>

22. 各環境における実装ガイドライン

22.1 openai-harmony ライブラリの利用

Python APIを利用する場合、以下のような概念モデルで処理を実装する。
from openai_harmony import (
    HarmonyEncodingName,
    load_harmony_encoding,
    Conversation,
    Message,
    Role,
    SystemContent,
    DeveloperContent,
)

encoding = load_harmony_encoding(HarmonyEncodingName.HARMONY_GPT_OSS)

convo = Conversation.from_messages([
    Message.from_role_and_content(Role.SYSTEM, SystemContent.new()),
    Message.from_role_and_content(
        Role.DEVELOPER,
        DeveloperContent.new().with_instructions("必ず日本語で答える")
    ),
    Message.from_role_and_content(Role.USER, "2 + 2 は?"),
])

prefill_ids = encoding.render_conversation_for_completion(convo, Role.ASSISTANT)
stop_ids = encoding.stop_tokens_for_assistant_actions()
  • 主要API:
    • render_conversation_for_completion(...)
    • render_conversation_for_training(...)
    • render_conversation(...)
    • parse_messages_from_completion_tokens(...)
    • stop_tokens()
    • stop_tokens_for_assistant_actions()
    • StreamableParser(...)
  • RenderConversationConfig の設定:
    • auto_drop_analysis=True パラメータを設定することで、履歴レンダリング時に不要な analysis データを自動的に除外可能である。
    • この機能により、会話履歴への不要な推論プロセスの蓄積を防止できる。

22.2 Hugging Face Transformers の利用

gpt-oss の公式チャットテンプレートは、入力に対してHarmonyフォーマットを自動適用する。
  • 実装例:
from transformers import AutoTokenizer, AutoModelForCausalLM

model_name = "openai/gpt-oss-20b"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="auto", device_map="auto")

messages = [
    {"role": "system", "content": "必ず日本語で答えてください"},
    {"role": "user", "content": "MXFP4 とは何ですか?"},
]

inputs = tokenizer.apply_chat_template(
    messages,
    add_generation_prompt=True,
    return_tensors="pt",
    return_dict=True,
).to(model.device)
  • 実装時の留意事項:
    • 先頭に定義された system ロールは、自動的にHarmonyの developer ロールとして扱われる。
    • Harmonyの本来の system メッセージは、テンプレート側で自動生成される。
    • add_generation_prompt=True を指定することで、末尾に生成開始トリガーとなる <|start|>assistant が追加される。
    • テンプレートには builtin_tools, model_identity, reasoning_effort などの引数が用意されており、reasoning_effort の初期値は medium となっている。

22.3 vLLM の利用

vLLMのGPT-OSSレシピにおいては、使用するエンドポイントによってHarmonyのサポート範囲が異なる。
  • /v1/responses:
    • 推論(Chain-of-Thought)途中におけるツールの実行をサポートする。
    • 最終応答までの全工程を処理可能である。
    • 入力のレンダリングおよび出力のパースには openai-harmony ライブラリが使用される。
    • 状態保持(stateful operation)や完全なストリーミング処理については現在開発中(WIP)である。
  • /v1/chat/completions:
    • 標準的なチャット補完インターフェースを提供するが、ツールの実行は行われない。
    • 推論データと最終テキストを構造化して返却することが可能である。
    • include_reasoning: false を指定することで、推論プロセスをレスポンスから除外できる。
  • /v1/completions:
    • プレーンな入出力のみをサポートし、Harmonyの高度な機能についてはクライアント側で処理を実装する必要がある。
  • Function Calling 有効化のための起動引数:
vllm serve ... --tool-call-parser openai --enable-auto-tool-choice

22.4 Ollama の利用

Ollamaでも browser および python を含む gpt-oss 用テンプレートが提供されている。 システムプロンプトの構成上、Hugging Faceのテンプレートと同様のアプローチでHarmonyの構造が実装されており、バックグラウンドでHarmonyフォーマットを処理する実装の一つとして位置づけられる。

23. 手動構築時の実装要件

  1. アプリケーション固有の指示は developer ロールに記述する
    system ロールにすべての指示を含めないこと。
  2. final チャネルの末尾 <|return|> を履歴に保持しない
    次ターンの履歴として保持する際は、終端トークンを <|end|> に正規化すること。
  3. analysis チャネルの出力をエンドユーザーに表示しない
    Harmonyフォーマットの設計上、analysis は明示的に分離された内部推論として扱う。
  4. ツール呼び出しは <|call|> で停止する
    その後、ツールの実行結果を tool メッセージとしてモデルに返却すること。
  5. 予約済みトークンを手動で挿入しない
    トークナイザに定義が存在する場合でも、公開仕様として意味は保証されない。
  6. 独自実装よりも標準のテンプレートまたはレンダラを使用する
    軽微な構文の差異によりパーサーがエラーとなるリスクを回避するため。
  7. Hugging Face (HF) テンプレートの挙動に準拠する
    • system メッセージはHarmonyの developer メッセージに自動変換される。
    • 1つの assistant メッセージにつき、1つのツール呼び出しを前提とする。
    • final 応答生成後は、先行するCoT(Chain of Thought)履歴を破棄する。
  8. <|constrain|>json と plain text の json の差異に留意する
    公式CookbookとHFテンプレートで構文例に差異があるが、ライブラリ実装上は双方の形式を許容する仕様となっている。

24. 推奨される利用方針

24.1 安全なアーキテクチャの選択肢

  • Transformers を利用する場合
    tokenizer.apply_chat_template(...) を利用すること。
  • カスタム生成処理を実装する場合
    openai-harmony ライブラリのレンダラおよびパーサーを適用すること。
  • 推論サーバーを構築する場合
    vLLM、Ollama、または公式互換レイヤーなど、Harmonyフォーマットをネイティブサポートするミドルウェアを選定すること。

24.2 手動でのプロンプト構築が想定されるユースケース

  • パーサーおよびレンダラの動作検証
  • 学術的または技術的な研究用途
  • 互換実装の開発
  • トークナイザやプロトコルレベルのデバッグ作業
一般的なアプリケーション開発においては、Harmonyフォーマットの仕様理解は必須であるものの、プロンプトの手動構築は推奨されない。

25. 主要仕様の要約

  • Harmonyは、gpt-oss モデル向けに設計された「会話」「推論(reasoning)」「ツール利用」「構造化出力」を統合的に扱うためのフォーマットである。
  • system ロールはメタ情報の定義に使用し、アプリケーション固有の指示は developer ロールに定義する。
  • assistant ロールの出力は、analysis、commentary、final の3つのチャネルに分離される。
  • ツール呼び出しの終端トークンは <|call|>、最終回答の終端トークンは <|return|> を使用する。
  • 次ターンの履歴として保持する際は、終端トークンを <|return|> から <|end|> に置換(正規化)する必要がある。
  • ユーザー定義の関数ツールは通常 commentary チャネルから呼び出し、組み込みのブラウザ・Pythonツールは通常 analysis チャネルから呼び出す。
  • HFチャットテンプレートは、入力の先頭にある system メッセージをHarmonyの developer ロールとして再解釈する。
  • トークナイザには21個の追加特殊トークンが定義されているが、大半は予約済みトークンとして扱われる。
  • openai/harmony 実装内には公開トークナイザに存在しない追加フォーマットトークンが含まれるが、これらを gpt-oss 向けに手動で入力することは避ける。
  • 実装にあたっては、openai-harmony ライブラリまたは公式チャットテンプレートの利用を標準とする。

26. リファレンス