Ollamaを使用する際、ローカルでいくつかの中小モデルを起動し、ビジネスCoTは直接これらの小モデルにアクセスします。Ollama環境下のモデルは条件の制限により並行処理が難しく、固定のリクエストは高度に同質化されているため、ニーズに応じてモデルを選択できます。ツールチェーンを持たないローカル小モデルのリスクも限定的です。
しかし、vLLMを使用してローカルモデルを構築した後、vLLMポートへの直接アクセス機能を完全に切断し、すべての機能がAPI経由になると、これらの状況は変化しました。
vLLMサービスにおいて、単一サービスのセキュリティ保護を単に引き継ぐだけではもはや不十分です。小規模モデルの意図認識を前置し、メインモデルのツールチェーン呼び出しを制御し、アクセス許可、ログの記録、統計を行う必要があります。
また、最大の責務は複数のサービスを同時にホストすることです。この要件の下では、キュー、優先順位制御、出力のフィルタリングと判定、失敗時の再試行、そして重要な「思考予算(Thinking Budget)」の制御といった機能がさらに拡張されます。
これらの機能は一見冗長に見えるかもしれませんが、決してそうではありません。
第一に、ユーザーを識別し、ユーザーごとに異なる機能を提供する必要があります。以下の3つのシナリオを設計します:
シナリオ1
- 単純な自動テキスト要約タスクでは、多くの場合、思考プロセスは必要ありません。
- VSCodeのプログラミングタスクでは、完全な思考プロセスを表示する必要があります。
この2つのニーズに対して、一方は待機して応答を返せばよいですが、もう一方はストリーミング転送を行い、モデルの思考プロセスをユーザーに透過的に見せる必要があります。
シナリオ2
少し説明すると、思考予算が長すぎるとモデルの利用効率が低下します。多くのthinkモデルには「考えすぎる」という問題があります。また、与えられたトークン予算がすべて思考に使い果たされた場合、結果が返されないという悪質な問題もあります。
- 単純なクエリタスクAに必要な思考予算は3000であり、使い切らない可能性もあります。
- 本の登場人物の分類と認識といった複雑なタスクBに必要な思考予算は20000以上です。
したがって、このシナリオでは、2人のユーザーには異なる思考予算が必要であり、ソフトな予算設定が適切かもしれません。
シナリオ3
- ユーザーAはネットワークを呼び出して資料を検索する必要があります。
- ユーザーBはネットワークを呼び出す必要はありません。
外部情報は危険であり、外部情報を一切入力しないのが理想ですが、それが不可能であることは周知の事実です。そのため、ツールチェーンは二重の保険であるべきです。現在のユーザーにネットワークツールへのアクセス権限がある場合、ユーザーがアクセスを要求した時にのみアクセスできるようにし、無防備にこの機能をユーザーに開放してはなりません。したがって、リクエストが入ってきた後にツール宣言を再整理し、デフォルトでtool_choice=noneを追加することで、ある程度セキュリティを向上させることができます。
第二に、サービスの可用性をどのように向上させるか。同様に3つのシナリオがあります。
シナリオ1:複数回の思考と再試行。
- VSCodeでの1回の対話の中で、複数回の思考が発生する可能性があります。そこで問題となるのは、複数回の思考がその都度新しいリクエストとして発信されると、前回のコンテキストが消滅してしまうことです。次のリクエストに引き継げない場合、次のラウンドはまた最初からやり直しになります。セッションIDに基づいて、前回のコンテキストを次のラウンドに渡す必要があります。類似の問題として、モデルは同じ思考を繰り返しやすいため、前回の思考内容がないと、モデルは毎回新しいスタートになってしまいます(笑)。
- OOMなどのモデル側の問題でユーザーのリクエストが失敗した場合、どのように再試行すべきでしょうか。再試行時にも同様の問題に直面します。前回生成された思考を破棄することはできません。
シナリオ2:思考予算の形状学習(Shape Learning)
第一の問題のシナリオ2で述べたように、1回のリクエストで与えられるトークンが少なすぎ、思考トークンが多すぎると、思考したのに答えが出ない事態を招きます。逆にトークンを与えすぎると無駄が生じます。
ここでの私の方法は、ユーザーのリクエストログに基づいて、ユーザーの思考予算を動的に調整することです。これがゲートウェイの「形状学習(パターン学習)」です。
ユーザーの過去のリクエストに基づいてあらかじめ思考予算を割り当て、結果を返す際にチェックを行います。思考が未完了の場合は、リターンをインターセプトし、現在のリクエストにより大きな予算を与え、結果の一部を新しいリクエストの本文に重ね合わせて、再度リクエストを送信します。
シナリオ3:優先度付きキューと中断
- モデルが1つのリクエストを処理した後、キュー内の複数のサービスのうち、どれを優先的に開始できるか。ここでスキャンが必要です。
- ユーザーがリクエストを終了した後、モデルは思考を完了させる必要があるか。私の個人的な判断では不要であり、モデルは継続中の思考を中断すべきです。
以上の問題に基づき、複数のタスクが共存する状況下で以下のようなアーキテクチャをまとめました。

したがって、モデルの能力は、vLLMを構築し、ブラックボックス上のいくつかのボタンスイッチやパラメータを切り替えるだけで解決するものではありません。
エンジニアリング側の膨大な実践と蓄積が必要です。これらの実践が、私たちが現在行っているプロセスの制御、あるいは「ハーネス(harness)」と言えるでしょう。
もちろん、現在のこの機能はまだ非常にシンプルで多くの抜け穴がありますが、とにかく動いているのだから良しとしましょう。
そういえば、このシステムはContinueとCopilot Chatでまったく異なる挙動を示すのでしょうか?
