概要
GWにAIコーディングを楽しんでみました!
現場では OpenAI、Google Gemini、Ollama など複数の大型言語モデル(LLM)を用途に応じて使い分けたいケースが増えています。しかし、各サービスで API 仕様が異なるため、運用コストが増大しがちです。
本記事では、VSCode Copilot(Claude 3.7 Sonnet モード)と ChatGPT を併用しつつ開発した「Ollama Proxy」という統合プロキシサーバーの設計・実装手順を紹介します。これにより、OpenAI 互換 API と Ollama プロトコルを両対応させ、開発者は単一のエンドポイントで複数バックエンドを透過的に利用可能になります。
読者が得られる知見:
- Copilot(Claude Sonnet)と ChatGPT での分担開発ワークフロー
- LLM バックエンドの自動検出・モデルマッピング手法
- API ルーティングとストリーミング対応の実装ポイント
将来的な構想:ローカルLLMをOllamaで動作させ、生成された回答の信頼度が一定以下の場合にOpenAIなどの外部LLMへ自動エスカレーションする機能を実装予定
前提知識・環境
- プログラミング言語: TypeScript(Node.js 14+)
- 動作環境: VSCode + Copilot
- 使用 AI: Copilot(Claude 3.7 Sonnet モード)、ChatGPT(gpt-4-turbo)
- 必要な API キー: OpenAI、Google Cloud Access Token
- ローカル実行: Ollama(v0.x)
セクション構成
- 開発環境セットアップ
- プロキシ設計とルーティング層
- バックエンドプラグイン実装
- Copilot と ChatGPT の分担開発フロー
- ストリーミング・モデルマッピングの実装ポイント
- 動作検証とデモ
- まとめと今後の展望
1. 開発環境セットアップ
# リポジトリをクローン
git clone https://github.com/yourusername/ollama-proxy.git
cd ollama-proxy
# パッケージインストール
npm install
.env
ファイルを作成し、下記を設定:
OPENAI_API_KEY=sk-...
GCP_ACCESS_TOKEN=ya29....
OLLAMA_BASE_URL=http://localhost:11434
PORT=11434
VSCode で Copilot の設定を確認し、Claude Sonnet モードを有効化しておきます。
2. プロキシ設計とルーティング層
メインとなる src/index.ts
では Express を使用し、以下の2種類の API パスを定義:
-
/v1/*
→ OpenAI 互換ハンドラーへルーティング -
/api/*
→ Ollama 互換ハンドラーへルーティング
app.use('/v1', openaiRouter);
app.use('/api', ollamaRouter);
Copilot でルーティングテンプレートを生成し、Sonnet が詰まった部分は ChatGPT に問い合わせて修正。例えば、パスパラメータの扱いについては ChatGPT から以下の助言を得ました。
Express の
mergeParams
オプションを有効にすると、ネストされたルーター間でパラメータを共有できます。
3. バックエンドプラグイン実装
src/backends/
フォルダに各バックエンドクラスを配置。共通の抽象クラス LLMBackend
を定義し、以下を実装します。
abstract class LLMBackend {
abstract listModels(): Promise<string[]>;
abstract chat(params: ChatParams): AsyncIterable<string>;
}
-
openai.ts
: OpenAI の/chat/completions
ラッパー -
gemini.ts
: Google Gemini の認証とエンドポイント呼び出し -
ollama.ts
: ローカル Ollama サーバーへの HTTP リクエスト
Copilot に初期スケルトンを生成させ、認証ヘッダーやエラー処理は ChatGPT の助言を元に補完しました。
4. Copilot と ChatGPT の分担開発フロー
- 骨組み生成: Copilot (Claude Sonnet)に関数・クラスの雛形を提案させる
- 具体的な実装: Sonnet が詰まった箇所(例:ストリーミングレスポンスの AsyncIterator化)を ChatGPT へ質問し、サンプルコードを取得
- 検証と修正: 単体テストを実行して失敗箇所を洗い出し、Copilot と ChatGPT を行き来しながら修正
このハイブリッド手法で、開発効率と精度を両立させることができました。
5. ストリーミング・モデルマッピングの実装ポイント
-
モデル検出: 起動時に全バックエンドの
listModels()
を呼び出し、利用可能モデルを取得 -
エイリアス生成: 長いモデル名を
gpt4
、gemini-pro
、llama2
など簡易名にマッピング -
ストリーミング: HTTP レスポンスを Node.js の
ReadableStream
に変換し、クライアントへ順次送信
// 非同期イテレータを利用したストリーミング例
target.chat(params).on('data', chunk => res.write(chunk));
6. 動作検証とデモ
npm run dev
-
curl
による OpenAI 互換チャット実行例:curl -X POST http://localhost:11434/v1/chat/completions \ -H 'Content-Type: application/json' \ -d '{ "model": "gpt4", "messages": [{"role":"user","content":"Hello, world!"}] }'
- ローカル Ollama への同様のリクエスト:
curl -X POST http://localhost:11434/api/chat \ -d '{ "model": "llama2", "prompt": "こんにちは" }'
7. まとめと今後の展望
本記事では、VSCode Copilot(Claude Sonnet)と ChatGPT を併用しながら「Ollama Proxy」を開発した手順を解説しました。
- Copilot を骨組み生成、ChatGPT を問題解決に使い分けるハイブリッド開発
- 複数 LLM バックエンドの自動検出、モデルマッピング手法
- ストリーミング対応を含む API ルーティング実装ポイント
将来的な構想として、ローカルLLMをOllamaで動作させ、生成された回答の信頼度が一定以下の場合にOpenAIなどの外部LLMへ自動エスカレーションする機能を実装予定です。
8. githubリポジトリ
9. この記事の作成過程