HEROZ ASKへのo1モデル導入
HEROZ は OpenAI の o1 モデルを自社製品 HEROZ ASK に導入したが、LangChain での実装におけるストリーミングやシステムメッセージの制限への対応策と、コスト対効果に関する実用的な知見が示された。
キーポイント
o1 の LangChain 実装における技術的制約と回避策
o1 モデルは標準の ChatOpenAI() で temperature やストリーミング、SystemMessage が無効化されるため、HEROZ は独自ラップクラスでストリーミングを再現し、システムメッセージを 'developer' ロールとして実装した。
トークン計算とコスト管理の課題
o1 の導入により思考用トークン(Reasoning tokens)が含まれるようになったが、既存のライブラリ(openai_info.py, tiktoken)では対応しておらず、動的なテーブル上書きが必要となる。
数式処理能力と汎用的質問への適用限界
画像入力による難解な数式の解決には抜群の能力を発揮するが、一般的な知識質問では gpt-4o と差がなく、時間とコストがかかるためユースケースの選定が重要である。
HEROZ ASK への正式導入と今後の展望
2025 年 1 月 24 日以降、HEROZ ASK で o1 を利用可能とし、一般ユーザーを含めたユースケースの発掘を通じて最適な活用方法を模索していく。
影響分析・編集コメントを表示
影響分析
この記事は、最新の大規模言語モデルである o1 の実運用における具体的な技術的課題(ストリーミングの欠如、トークン計算の不整合)と、その解決策を提供しており、開発者にとって非常に実践的な知見となる。また、o1 の能力が万能ではないという冷静な評価は、導入を検討する企業やエンジニアに対して適切なユースケース選定を促す重要な示唆を含んでいる。
編集コメント
o1 モデルの導入は単なるバージョンアップではなく、ストリーミングやコスト計算など実装レベルでの新たな課題を生むことを示しており、技術選定においては機能だけでなく運用面の詳細まで確認する必要がある。
タイトル: HEROZ ASKへのo1の導入
昨年末の12月5日、12 Days of OpenAIにおいてついにo1が発表されました。また、Azure OpenAI Serviceでもこのo1が利用可能になったため、HEROZ ASKへ組み込みました。langchainを用いた組み込みで気になった点を記していきます。
なお、このo1はHEROZ ASKで2025年1月24日以降に使用可能です。
o1-preview時代からの共通項目
昨年9月にo1-previewがリリースされて以来、社内ではo1-previewを組み込む試作を実施していました。その時から注意点や気になった点は以下の通りです。
o1-previewやo1-miniはChatOpenAI()において、
temperatureオプションの削除、
ストリーミング(streaming)オプションの削除、
SystemMessage(システムメッセージ)の除去が行われています。
ストリーミングオプションを削除するとストリーミングを期待している時に何も出力されなくなるため、以下のようなラッピングクラスを用意しました。
class ChatOpenAI_o1(ChatOpenAI):
def _generate(
self,
messages: List[BaseMessage],
stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> ChatResult:
results = super()._generate(
messages, stop, run_manager, **kwargs,
)
if run_manager is not None:
# on_llm_new_tokenしないと結果が表示されない
run_manager.on_llm_new_token("".join([g.text for g in results.generations]))
return results
async def _agenerate(
self,
messages: List[BaseMessage],
stop: Optional[List[str]] = None,
run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> ChatResult:
results = super()._generate(
messages, stop, run_manager, **kwargs,
)
if run_manager is not None:
# on_llm_new_tokenしないと結果が表示されない
await run_manager.on_llm_new_token(
"".join([g.text for g in results.generations])
)
return resultsまた、ストリーミング時はstream_usageオプションを使用すると使用トークン数を取得できますが、これの出力トークン(completion tokens)には思考用のReasoning tokenも含まれており、助かりました。
o1はo1-previewと比べると以下の点で変更となっています。
SystemMessageへの対応: roleはdeveloper、
画像入力: 数式の入力がやりやすくなります、
Markdown出力: プロンプトにFormatting reenabled。
SystemMessageについてはlangchainにおいてはSystemMessagePromptTemplateに、
additional_kwargs = { "__openai_role__": "developer" }
を設定することで対応できます。
一方で、o1は未だにコスト計算用の単価が書かれているopenai_info.pyやtiktokenのmodel.pyが対応していないので、テーブルを動的に上書きしない限りはトークンやコストの計算時にエラーが発生します。これらのファイルについては早期に追加されることを期待します。
早速、難解な数式を画像で入力して解かせたところ、無事に正解しました。

o1の実行結果
gpt-4oより賢いと言われているo1をHEROZ ASKへ導入することができました。o1は確かに込み入った数式のような問題には抜群の能力を発揮するのですが、普通の質問や知識を問う内容だとgpt-4oと回答が変わらず、o1は時間とコストだけがかかるので、使い所が難しいように思いました。一般ユーザーを含めて導入することにより、その辺りのユースケースをもっと発掘していきたいと思います。
原文を表示
o1-preview時代からの共通項目
昨年末の12/5に12 Days of OpenAIでついにo1が発表となりました。 また、Azure OpenAI Serviceでも、このo1が使用できるようになりましたので、HEROZ ASKへと組み込みました。 langchainを用いた組み込みで気になった点を書いていきます。
なお、このo1はHEROZ ASKで2025/1/24以降で使用可能です。
o1-preview時代からの共通項目
昨年9月にo1-previewがリリースされて以来、内部的にはo1-previewを組み込む試作を実施していました。 その時から注意点や気になった点は以下となります。
o1-previewやo1-miniはChatOpenAI()
temperature: オプションの削除
ストリーミング(streaming): オプションの削除
SystemMessage: システムメッセージの除去
ストリーミングオプションを削除するとストリーミングを期待している時に何も出力されなくなるため、以下のようなラッピングクラスを用意しました。
class ChatOpenAI_o1(ChatOpenAI): def _generate( self, messages: List[BaseMessage], stop: Optional[List[str]] = None, run_manager: Optional[CallbackManagerForLLMRun] = None, kwargs: Any, ) -> ChatResult: results = super()._generate( messages, stop, run_manager, *kwargs, ) if run_manager is not None: # on_llm_new_tokenしないと結果が表示されない run_manager.on_llm_new_token("".join([g.text for g in results.generations])) return results async def _agenerate( self, messages: List[BaseMessage], stop: Optional[List[str]] = None, run_manager: Optional[AsyncCallbackManagerForLLMRun] = None, kwargs: Any, ) -> ChatResult: results = super()._generate( messages, stop, run_manager, *kwargs, ) if run_manager is not None: # on_llm_new_tokenしないと結果が表示されない await run_manager.on_llm_new_token( "".join([g.text for g in results.generations]) ) return results
また、ストリーミング時はstream_usageオプションを使用すると使用トークン数を取得できますが、これの出力トークン(completion tokens)に思考用のReasoning tokenも含まれており、助かりました。
o1はo1-previewと比べると以下の点で変更となっています。
SystemMessageへの対応: roleはdeveloper
画像入力: 数式の入力がやりやすくなります
Markdown出力: プロンプトにFormatting reenabled
SystemMessageについてはlangchainにおいてはSystemMessagePromptTemplate
additional_kwargs = { "__openai_role__": "developer" }
一方で、o1は未だにコスト計算用の単価が書かれているopenai_info.pyやtiktokenのmodel.pyが対応していないので、テーブルを動的に上書きしない限りはトークンやコストの計算時にエラーが発生します。 これらのファイルについては早期に追加されることを期待します。
早速、難解な数式を画像で入力して解かせたところ、無事に正解しました。
o1の実行結果
gpt-4oより賢いと言われているo1をHEROZ ASKへ導入することができました。 o1は確かに込み入った数式のような問題には抜群の能力を発揮するのですが、普通の質問や知識を問う内容だとgpt-4oと回答が変わらず、o1は時間とコストだけがかかるので、使い所が難しいように思いました。 一般ユーザーを含めて導入することにより、その辺りのユースケースをもっと発掘していきたいと思います。
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み