@modular-prompt/driver 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -540
- package/dist/driver-registry/registry.d.ts +1 -2
- package/dist/driver-registry/registry.d.ts.map +1 -1
- package/dist/driver-registry/registry.js +1 -2
- package/dist/driver-registry/registry.js.map +1 -1
- package/dist/mlx-ml/mlx-driver.d.ts +1 -0
- package/dist/mlx-ml/mlx-driver.d.ts.map +1 -1
- package/dist/mlx-ml/mlx-driver.js +28 -3
- package/dist/mlx-ml/mlx-driver.js.map +1 -1
- package/dist/mlx-ml/process/parameter-mapper.d.ts.map +1 -1
- package/dist/mlx-ml/process/parameter-mapper.js +4 -2
- package/dist/mlx-ml/process/parameter-mapper.js.map +1 -1
- package/dist/mlx-ml/process/process-communication.d.ts.map +1 -1
- package/dist/mlx-ml/process/process-communication.js +2 -7
- package/dist/mlx-ml/process/process-communication.js.map +1 -1
- package/dist/mlx-ml/process/types.d.ts +2 -0
- package/dist/mlx-ml/process/types.d.ts.map +1 -1
- package/dist/mlx-ml/tool-call-parser.d.ts +1 -0
- package/dist/mlx-ml/tool-call-parser.d.ts.map +1 -1
- package/dist/mlx-ml/tool-call-parser.js +262 -17
- package/dist/mlx-ml/tool-call-parser.js.map +1 -1
- package/package.json +6 -4
- package/skills/driver-usage/SKILL.md +432 -0
- package/src/mlx-ml/python/token_utils.py +75 -17
package/README.md
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
# @modular-prompt/driver
|
|
2
2
|
|
|
3
|
-
AIモデルドライバーパッケージ - 様々なAI
|
|
4
|
-
|
|
5
|
-
## 概要
|
|
6
|
-
|
|
7
|
-
`@modular-prompt/driver`は、OpenAI、Anthropic、Google Vertex AI、Ollama、MLX MLなど、複数のAIプロバイダーとの統合を提供するドライバーパッケージです。統一されたインターフェースにより、プロバイダーを簡単に切り替えることができます。
|
|
3
|
+
AIモデルドライバーパッケージ - 様々なAIプロバイダーとの統一されたインターフェースを提供。
|
|
8
4
|
|
|
9
5
|
## インストール
|
|
10
6
|
|
|
@@ -18,580 +14,81 @@ npm install @modular-prompt/driver
|
|
|
18
14
|
import { compile } from '@modular-prompt/core';
|
|
19
15
|
import { OpenAIDriver } from '@modular-prompt/driver';
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
const driver = new OpenAIDriver({
|
|
23
|
-
apiKey: 'your-api-key',
|
|
24
|
-
model: 'gpt-4o-mini'
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
// プロンプトモジュールをコンパイル
|
|
17
|
+
const driver = new OpenAIDriver({ model: 'gpt-4o-mini' });
|
|
28
18
|
const prompt = compile(myModule, context);
|
|
29
19
|
|
|
30
|
-
//
|
|
31
|
-
const result = await driver.query(prompt, {
|
|
32
|
-
temperature: 0.7,
|
|
33
|
-
maxTokens: 1000
|
|
34
|
-
});
|
|
35
|
-
|
|
20
|
+
// クエリ
|
|
21
|
+
const result = await driver.query(prompt, { temperature: 0.7 });
|
|
36
22
|
console.log(result.content);
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## 利用可能なドライバー
|
|
40
|
-
|
|
41
|
-
### OpenAI
|
|
42
|
-
|
|
43
|
-
OpenAI APIと互換性のあるサービス用のドライバー。
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
import { OpenAIDriver } from '@modular-prompt/driver';
|
|
47
|
-
|
|
48
|
-
const driver = new OpenAIDriver({
|
|
49
|
-
apiKey: process.env.OPENAI_API_KEY,
|
|
50
|
-
model: 'gpt-4o-mini', // デフォルト: 'gpt-4o-mini'
|
|
51
|
-
baseURL: 'https://api.openai.com/v1', // カスタムエンドポイント可
|
|
52
|
-
defaultOptions: {
|
|
53
|
-
temperature: 0.7,
|
|
54
|
-
maxTokens: 2000
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
**主なオプション:**
|
|
60
|
-
- `temperature`: 生成のランダム性 (0-2)
|
|
61
|
-
- `maxTokens`: 最大トークン数
|
|
62
|
-
- `topP`: トップPサンプリング
|
|
63
|
-
|
|
64
|
-
### Anthropic
|
|
65
|
-
|
|
66
|
-
Claude APIのドライバー。
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
import { AnthropicDriver } from '@modular-prompt/driver';
|
|
70
|
-
|
|
71
|
-
const driver = new AnthropicDriver({
|
|
72
|
-
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
73
|
-
model: 'claude-3-5-sonnet-20241022', // デフォルト
|
|
74
|
-
defaultOptions: {
|
|
75
|
-
maxTokens: 4096,
|
|
76
|
-
temperature: 0.7
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**主なオプション:**
|
|
82
|
-
- `maxTokens`: 最大トークン数(デフォルト: 4096)
|
|
83
|
-
- `temperature`: 生成のランダム性 (0-1)
|
|
84
|
-
- `topP`: トップPサンプリング
|
|
85
23
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
import { VertexAIDriver } from '@modular-prompt/driver';
|
|
92
|
-
|
|
93
|
-
const driver = new VertexAIDriver({
|
|
94
|
-
project: 'your-gcp-project', // または環境変数 GOOGLE_CLOUD_PROJECT
|
|
95
|
-
location: 'us-central1', // デフォルト: 'us-central1'
|
|
96
|
-
model: 'gemini-2.0-flash-001', // デフォルト
|
|
97
|
-
temperature: 0.05, // デフォルト: 0.05
|
|
98
|
-
defaultOptions: {
|
|
99
|
-
maxTokens: 1000,
|
|
100
|
-
topP: 0.95,
|
|
101
|
-
topK: 40
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
**主なオプション:**
|
|
107
|
-
- `maxTokens`: 最大出力トークン数
|
|
108
|
-
- `temperature`: 生成のランダム性
|
|
109
|
-
- `topP`: トップPサンプリング
|
|
110
|
-
|
|
111
|
-
**必要な設定:**
|
|
112
|
-
- Google Cloud プロジェクトID(環境変数: `GOOGLE_CLOUD_PROJECT`)
|
|
113
|
-
- Google Cloud 認証(ADCまたはサービスアカウント)
|
|
114
|
-
|
|
115
|
-
### Google Gen AI (Gemini)
|
|
116
|
-
|
|
117
|
-
GoogleGenAI SDKを使用してGeminiモデルに直接アクセス。APIキーのみで簡単に利用可能。
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
import { GoogleGenAIDriver } from '@modular-prompt/driver';
|
|
121
|
-
|
|
122
|
-
const driver = new GoogleGenAIDriver({
|
|
123
|
-
apiKey: process.env.GOOGLE_GENAI_API_KEY,
|
|
124
|
-
model: 'gemini-2.0-flash-exp', // デフォルト
|
|
125
|
-
temperature: 0.7, // デフォルト
|
|
126
|
-
defaultOptions: {
|
|
127
|
-
maxTokens: 2048,
|
|
128
|
-
topP: 0.95,
|
|
129
|
-
topK: 40
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
**主なオプション:**
|
|
135
|
-
- `maxTokens`: 最大出力トークン数
|
|
136
|
-
- `temperature`: 生成のランダム性
|
|
137
|
-
- `topP`: トップPサンプリング
|
|
138
|
-
- `topK`: トップKサンプリング
|
|
139
|
-
- `thinkingConfig`: 思考レベル設定(HIGH/MEDIUM/LOW)
|
|
140
|
-
|
|
141
|
-
**必要な設定:**
|
|
142
|
-
- Google Gen AI APIキー(環境変数: `GOOGLE_GENAI_API_KEY`)
|
|
143
|
-
- APIキーは[Google AI Studio](https://aistudio.google.com/apikey)で取得可能
|
|
144
|
-
|
|
145
|
-
### Ollama
|
|
146
|
-
|
|
147
|
-
ローカルで実行されるOllamaサービス用のドライバー。
|
|
148
|
-
|
|
149
|
-
詳細なセットアップ手順とモデルのダウンロード方法については、[ローカルモデルセットアップガイド](../../docs/LOCAL_MODEL_SETUP.md#ollama)を参照してください。
|
|
150
|
-
|
|
151
|
-
```typescript
|
|
152
|
-
import { OllamaDriver } from '@modular-prompt/driver';
|
|
153
|
-
|
|
154
|
-
const driver = new OllamaDriver({
|
|
155
|
-
baseURL: 'http://localhost:11434/v1', // デフォルト
|
|
156
|
-
model: 'llama3.2' // デフォルト
|
|
157
|
-
});
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
Ollamaドライバーは内部的にOpenAIドライバーを使用します(OllamaがOpenAI互換APIを提供するため)。
|
|
161
|
-
|
|
162
|
-
### MLX ML
|
|
163
|
-
|
|
164
|
-
Appleシリコン最適化モデル用のPythonベースのドライバー。
|
|
165
|
-
|
|
166
|
-
詳細なセットアップ手順とモデルのダウンロード方法については、[ローカルモデルセットアップガイド](../../docs/LOCAL_MODEL_SETUP.md#mlx-apple-silicon)を参照してください。
|
|
167
|
-
|
|
168
|
-
#### セットアップ
|
|
169
|
-
|
|
170
|
-
MLXドライバーは初回インストール時に自動的にPython環境をセットアップします:
|
|
171
|
-
|
|
172
|
-
```bash
|
|
173
|
-
npm install @modular-prompt/driver
|
|
174
|
-
# postinstallスクリプトが自動的にPython環境をセットアップ
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
手動セットアップが必要な場合:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
cd node_modules/@modular-prompt/driver
|
|
181
|
-
npm run setup-mlx
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
**前提条件:**
|
|
185
|
-
- Python 3.11以上
|
|
186
|
-
- Apple Silicon Mac (M1/M2/M3)
|
|
187
|
-
- uv(Pythonパッケージマネージャー、自動インストールされます)
|
|
188
|
-
|
|
189
|
-
#### 使用方法
|
|
190
|
-
|
|
191
|
-
```typescript
|
|
192
|
-
import { MlxDriver } from '@modular-prompt/driver';
|
|
193
|
-
|
|
194
|
-
const driver = new MlxDriver({
|
|
195
|
-
model: 'mlx-community/gemma-3-2b',
|
|
196
|
-
defaultOptions: {
|
|
197
|
-
max_tokens: 500,
|
|
198
|
-
temperature: 0.7,
|
|
199
|
-
top_p: 0.95,
|
|
200
|
-
repetition_penalty: 1.1
|
|
201
|
-
}
|
|
202
|
-
});
|
|
24
|
+
// ストリーミング
|
|
25
|
+
const { stream, result: resultPromise } = await driver.streamQuery(prompt);
|
|
26
|
+
for await (const chunk of stream) {
|
|
27
|
+
process.stdout.write(chunk);
|
|
28
|
+
}
|
|
203
29
|
|
|
204
|
-
// 使用後はプロセスを終了
|
|
205
30
|
await driver.close();
|
|
206
31
|
```
|
|
207
32
|
|
|
208
|
-
|
|
209
|
-
- `max_tokens`: 最大トークン数
|
|
210
|
-
- `temperature`: 生成のランダム性
|
|
211
|
-
- `top_p`: トップPサンプリング
|
|
212
|
-
|
|
213
|
-
**モデルのダウンロード:**
|
|
214
|
-
|
|
215
|
-
テスト用モデル(約270MB)を事前にダウンロードできます:
|
|
216
|
-
|
|
217
|
-
```bash
|
|
218
|
-
cd node_modules/@modular-prompt/driver
|
|
219
|
-
npm run download-model
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
**注意事項:**
|
|
223
|
-
- Pythonサブプロセスを使用するため、Python環境とMLXのインストールが必要
|
|
224
|
-
- 使用後は必ず`close()`を呼び出してプロセスを終了
|
|
225
|
-
- 初回実行時にモデルのダウンロードが発生する場合があります
|
|
226
|
-
|
|
227
|
-
#### 低レベルAPI(MlxProcess)
|
|
228
|
-
|
|
229
|
-
`MlxDriver`を経由せず、直接MLXプロセスとやり取りする低レベルAPIも公開されています。これは以下のような場合に便利です:
|
|
230
|
-
|
|
231
|
-
- `CompiledPrompt`を経由せずに、生のメッセージやプロンプトを直接送信したい
|
|
232
|
-
- モデル固有の処理を完全にコントロールしたい
|
|
233
|
-
- デバッグや検証のために低レベルAPIを使用したい
|
|
234
|
-
|
|
235
|
-
```typescript
|
|
236
|
-
import { MlxProcess, type MlxMessage } from '@modular-prompt/driver';
|
|
237
|
-
|
|
238
|
-
// 低レベルプロセスを直接使用
|
|
239
|
-
const process = new MlxProcess('mlx-community/gemma-3-27b-it-qat-4bit');
|
|
240
|
-
|
|
241
|
-
// Chat API - 生のメッセージを送信
|
|
242
|
-
const messages: MlxMessage[] = [
|
|
243
|
-
{ role: 'system', content: 'You are a helpful assistant.' },
|
|
244
|
-
{ role: 'user', content: 'Hello!' }
|
|
245
|
-
];
|
|
246
|
-
const chatStream = await process.chat(messages);
|
|
247
|
-
|
|
248
|
-
// Completion API - 生のプロンプトを送信
|
|
249
|
-
const completionStream = await process.completion('Write a story about...');
|
|
250
|
-
|
|
251
|
-
// モデル情報取得
|
|
252
|
-
const capabilities = await process.getCapabilities();
|
|
253
|
-
console.log('Available methods:', capabilities.methods);
|
|
254
|
-
console.log('Has chat template:', capabilities.features.apply_chat_template);
|
|
255
|
-
|
|
256
|
-
// フォーマットテスト(チャットテンプレートの動作確認)
|
|
257
|
-
const formatTest = await process.formatTest(messages);
|
|
258
|
-
console.log('Formatted prompt:', formatTest.result);
|
|
259
|
-
|
|
260
|
-
// 終了
|
|
261
|
-
process.exit();
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
**公開API:**
|
|
265
|
-
- `MlxProcess` クラス
|
|
266
|
-
- `MlxMessage` 型
|
|
267
|
-
|
|
268
|
-
**MlxProcess メソッド:**
|
|
269
|
-
- `chat(messages, primer?, options?)`: Chat APIを使用してストリーム生成
|
|
270
|
-
- `completion(prompt, options?)`: Completion APIを使用してストリーム生成
|
|
271
|
-
- `getCapabilities()`: モデルの機能情報を取得
|
|
272
|
-
- `formatTest(messages, options?)`: チャットテンプレートのフォーマット結果をテスト
|
|
273
|
-
- `exit()`: プロセスを終了
|
|
274
|
-
|
|
275
|
-
**注意:**
|
|
276
|
-
- `MlxProcess`は`MlxDriver`よりも低レベルなAPIです
|
|
277
|
-
- モデル固有の前処理(メッセージマージ、プロンプトフォーマットなど)は**ユーザーの責任**となります
|
|
278
|
-
- `MlxDriver`は内部的に`MlxProcess`を使用し、適切な前処理を自動的に行います
|
|
279
|
-
- 通常の用途では`MlxDriver`の使用を推奨します
|
|
280
|
-
- その他の型(`MlxMlModelOptions`など)が必要な場合は型推論を利用してください
|
|
281
|
-
|
|
282
|
-
### テストドライバー
|
|
283
|
-
|
|
284
|
-
開発とテスト用のモックドライバー。
|
|
285
|
-
|
|
286
|
-
```typescript
|
|
287
|
-
import { TestDriver } from '@modular-prompt/driver';
|
|
288
|
-
|
|
289
|
-
const driver = new TestDriver({
|
|
290
|
-
responses: [
|
|
291
|
-
'First response',
|
|
292
|
-
'Second response',
|
|
293
|
-
'Third response'
|
|
294
|
-
],
|
|
295
|
-
responseDelay: 100, // ミリ秒
|
|
296
|
-
streamChunkDelay: 10
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
// カスタムレスポンスプロバイダー
|
|
300
|
-
const driver2 = new TestDriver({
|
|
301
|
-
responseProvider: async (prompt, options) => {
|
|
302
|
-
// プロンプトに基づいてレスポンスを生成
|
|
303
|
-
return `Response to: ${prompt.instructions[0].content}`;
|
|
304
|
-
}
|
|
305
|
-
});
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
## ストリーミング
|
|
33
|
+
## 利用可能なドライバー
|
|
309
34
|
|
|
310
|
-
|
|
35
|
+
| ドライバー | プロバイダー | 備考 |
|
|
36
|
+
|-----------|------------|------|
|
|
37
|
+
| `OpenAIDriver` | OpenAI | OpenAI互換API対応 |
|
|
38
|
+
| `AnthropicDriver` | Anthropic | Claude |
|
|
39
|
+
| `VertexAIDriver` | Google Cloud | Vertex AI経由Gemini |
|
|
40
|
+
| `GoogleGenAIDriver` | Google | APIキーのみで利用可能 |
|
|
41
|
+
| `OllamaDriver` | Ollama | ローカルLLM |
|
|
42
|
+
| `MlxDriver` | MLX | Apple Silicon専用 |
|
|
43
|
+
| `TestDriver` | - | モックレスポンス |
|
|
44
|
+
| `EchoDriver` | - | プロンプトをそのまま返す |
|
|
311
45
|
|
|
312
|
-
|
|
313
|
-
const prompt = compile(myModule, context);
|
|
46
|
+
各ドライバーの詳細な設定・オプションは `skills/driver-usage/SKILL.md` を参照。
|
|
314
47
|
|
|
315
|
-
|
|
316
|
-
const { stream, result } = await driver.streamQuery(prompt);
|
|
317
|
-
for await (const chunk of stream) {
|
|
318
|
-
process.stdout.write(chunk);
|
|
319
|
-
}
|
|
48
|
+
## 主な機能
|
|
320
49
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
50
|
+
- **統一インターフェース**: `query()` / `streamQuery()` / `close()` の3メソッド
|
|
51
|
+
- **ツール呼び出し**: Function Calling対応(OpenAI、Anthropic、VertexAI、GoogleGenAI)
|
|
52
|
+
- **構造化出力**: JSONスキーマによる出力制御
|
|
53
|
+
- **AIService**: 能力ベースのモデル自動選択
|
|
325
54
|
|
|
326
55
|
## カスタムドライバーの作成
|
|
327
56
|
|
|
328
|
-
|
|
57
|
+
`AIDriver` インターフェースを実装:
|
|
329
58
|
|
|
330
59
|
```typescript
|
|
331
60
|
import type { AIDriver, CompiledPrompt, QueryOptions, QueryResult, StreamResult } from '@modular-prompt/driver';
|
|
332
61
|
|
|
333
62
|
export class CustomDriver implements AIDriver {
|
|
334
|
-
private apiKey: string;
|
|
335
|
-
private model: string;
|
|
336
|
-
|
|
337
|
-
constructor(config: CustomConfig) {
|
|
338
|
-
this.apiKey = config.apiKey;
|
|
339
|
-
this.model = config.model;
|
|
340
|
-
// その他の初期化コード
|
|
341
|
-
}
|
|
342
|
-
|
|
343
63
|
async query(prompt: CompiledPrompt, options?: QueryOptions): Promise<QueryResult> {
|
|
344
|
-
//
|
|
345
|
-
const response = await yourAPI.complete({
|
|
346
|
-
prompt: prompt,
|
|
347
|
-
temperature: options?.temperature,
|
|
348
|
-
maxTokens: options?.maxTokens
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
return {
|
|
352
|
-
content: response.text,
|
|
353
|
-
finishReason: 'stop',
|
|
354
|
-
usage: {
|
|
355
|
-
promptTokens: response.inputTokens,
|
|
356
|
-
completionTokens: response.outputTokens,
|
|
357
|
-
totalTokens: response.totalTokens
|
|
358
|
-
}
|
|
359
|
-
};
|
|
64
|
+
// 実装
|
|
360
65
|
}
|
|
361
66
|
|
|
362
67
|
async streamQuery(prompt: CompiledPrompt, options?: QueryOptions): Promise<StreamResult> {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
// ストリーミングレスポンスを処理
|
|
366
|
-
const chunks: string[] = [];
|
|
367
|
-
const asyncIterable = {
|
|
368
|
-
async *[Symbol.asyncIterator]() {
|
|
369
|
-
for await (const chunk of stream) {
|
|
370
|
-
chunks.push(chunk.text);
|
|
371
|
-
yield chunk.text;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
return {
|
|
377
|
-
stream: asyncIterable,
|
|
378
|
-
result: Promise.resolve({
|
|
379
|
-
content: chunks.join(''),
|
|
380
|
-
finishReason: 'stop'
|
|
381
|
-
})
|
|
382
|
-
};
|
|
68
|
+
// 実装
|
|
383
69
|
}
|
|
384
70
|
|
|
385
71
|
async close(): Promise<void> {
|
|
386
72
|
// リソースのクリーンアップ
|
|
387
|
-
await yourAPI.disconnect();
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
## フォーマッター設定
|
|
393
|
-
|
|
394
|
-
ドライバーはプロンプトのフォーマット方法をカスタマイズできます。FormatterOptionsを使用して、マーカー、プリアンブル、セクション説明などをカスタマイズします:
|
|
395
|
-
|
|
396
|
-
```typescript
|
|
397
|
-
import type { FormatterOptions } from '@modular-prompt/driver';
|
|
398
|
-
|
|
399
|
-
export class CustomDriver implements AIDriver {
|
|
400
|
-
private formatterOptions: FormatterOptions;
|
|
401
|
-
|
|
402
|
-
constructor(config: CustomConfig) {
|
|
403
|
-
// フォーマッターオプションの設定
|
|
404
|
-
this.formatterOptions = {
|
|
405
|
-
preamble: 'Custom instructions for the AI',
|
|
406
|
-
sectionDescriptions: {
|
|
407
|
-
instructions: 'Follow these instructions carefully',
|
|
408
|
-
data: 'Process this data',
|
|
409
|
-
output: 'Generate output here'
|
|
410
|
-
},
|
|
411
|
-
lineBreak: '\n',
|
|
412
|
-
// 必要に応じて他のオプションも設定
|
|
413
|
-
...config.formatterOptions
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
async query(prompt: CompiledPrompt, options?: QueryOptions): Promise<QueryResult> {
|
|
418
|
-
// フォーマッターを使用してプロンプトを変換
|
|
419
|
-
const formattedPrompt = formatCompletionPrompt(prompt, this.formatterOptions);
|
|
420
|
-
// または
|
|
421
|
-
const messages = formatPromptAsMessages(prompt, this.formatterOptions);
|
|
422
|
-
|
|
423
|
-
// APIに送信...
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
## 型定義
|
|
429
|
-
|
|
430
|
-
### AIDriver インターフェース
|
|
431
|
-
|
|
432
|
-
```typescript
|
|
433
|
-
interface AIDriver {
|
|
434
|
-
// プロンプトをクエリ
|
|
435
|
-
query(prompt: CompiledPrompt, options?: QueryOptions): Promise<QueryResult>;
|
|
436
|
-
|
|
437
|
-
// ストリーミングクエリ
|
|
438
|
-
streamQuery(prompt: CompiledPrompt, options?: QueryOptions): Promise<StreamResult>;
|
|
439
|
-
|
|
440
|
-
// リソースのクリーンアップ
|
|
441
|
-
close(): Promise<void>;
|
|
442
|
-
}
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
### QueryResult
|
|
446
|
-
|
|
447
|
-
```typescript
|
|
448
|
-
interface QueryResult {
|
|
449
|
-
content: string;
|
|
450
|
-
finishReason?: 'stop' | 'length' | 'error';
|
|
451
|
-
usage?: {
|
|
452
|
-
promptTokens: number;
|
|
453
|
-
completionTokens: number;
|
|
454
|
-
totalTokens: number;
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
### QueryOptions
|
|
460
|
-
|
|
461
|
-
```typescript
|
|
462
|
-
interface QueryOptions {
|
|
463
|
-
temperature?: number;
|
|
464
|
-
maxTokens?: number;
|
|
465
|
-
topP?: number;
|
|
466
|
-
stream?: boolean;
|
|
467
|
-
}
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
### StreamResult
|
|
471
|
-
|
|
472
|
-
```typescript
|
|
473
|
-
interface StreamResult {
|
|
474
|
-
stream: AsyncIterable<string>; // ストリームチャンク
|
|
475
|
-
result: Promise<QueryResult>; // 最終結果
|
|
476
|
-
}
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
## エラーハンドリング
|
|
480
|
-
|
|
481
|
-
全てのドライバーは統一されたエラーハンドリングを提供します:
|
|
482
|
-
|
|
483
|
-
```typescript
|
|
484
|
-
try {
|
|
485
|
-
const result = await driver.query(prompt);
|
|
486
|
-
|
|
487
|
-
if (result.finishReason === 'error') {
|
|
488
|
-
console.error('Query failed');
|
|
489
|
-
} else if (result.finishReason === 'length') {
|
|
490
|
-
console.warn('Response was truncated due to length limit');
|
|
491
73
|
}
|
|
492
|
-
} catch (error) {
|
|
493
|
-
// ネットワークエラーや初期化エラー
|
|
494
|
-
console.error('Driver error:', error);
|
|
495
74
|
}
|
|
496
75
|
```
|
|
497
76
|
|
|
498
|
-
##
|
|
499
|
-
|
|
500
|
-
多くのドライバーは環境変数から設定を読み取ることができます:
|
|
501
|
-
|
|
502
|
-
- `OPENAI_API_KEY`: OpenAI APIキー
|
|
503
|
-
- `ANTHROPIC_API_KEY`: Anthropic APIキー
|
|
504
|
-
- `GOOGLE_CLOUD_PROJECT`: Google Cloud プロジェクトID
|
|
505
|
-
- `GOOGLE_CLOUD_REGION`: Google Cloud リージョン
|
|
506
|
-
- `ANTHROPIC_VERTEX_PROJECT_ID`: Vertex AI経由でClaudeを使用する場合のプロジェクトID
|
|
507
|
-
- `CLOUD_ML_REGION`: Cloud ML リージョン
|
|
508
|
-
|
|
509
|
-
## ベストプラクティス
|
|
510
|
-
|
|
511
|
-
1. **APIキーの管理**: APIキーは環境変数に保存し、コードにハードコーディングしない
|
|
512
|
-
2. **エラーハンドリング**: `finishReason`を確認してエラーを適切に処理
|
|
513
|
-
3. **リソース管理**: MLXドライバーなどリソースを使用するドライバーは使用後に`close()`を呼び出す
|
|
514
|
-
4. **レート制限**: API制限を考慮して適切なリトライロジックを実装
|
|
515
|
-
5. **コスト管理**: `usage`情報を監視してAPIコストを追跡
|
|
516
|
-
|
|
517
|
-
## 例
|
|
77
|
+
## MLX セットアップ
|
|
518
78
|
|
|
519
|
-
|
|
79
|
+
MLXドライバーはインストール時に自動でPython環境をセットアップする。手動で実行する場合:
|
|
520
80
|
|
|
521
|
-
```
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
function createDriver(provider: string) {
|
|
525
|
-
switch (provider) {
|
|
526
|
-
case 'openai':
|
|
527
|
-
return new OpenAIDriver({ model: 'gpt-4o' });
|
|
528
|
-
case 'anthropic':
|
|
529
|
-
return new AnthropicDriver({ model: 'claude-3-5-sonnet-20241022' });
|
|
530
|
-
case 'vertexai':
|
|
531
|
-
return new VertexAIDriver({ model: 'gemini-2.0-flash-001' });
|
|
532
|
-
default:
|
|
533
|
-
throw new Error(`Unknown provider: ${provider}`);
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
const driver = createDriver(process.env.AI_PROVIDER || 'openai');
|
|
81
|
+
```bash
|
|
82
|
+
cd node_modules/@modular-prompt/driver
|
|
83
|
+
npm run setup-mlx
|
|
538
84
|
```
|
|
539
85
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
```typescript
|
|
543
|
-
async function streamWithProgress(driver: AIDriver, prompt: CompiledPrompt) {
|
|
544
|
-
let totalChars = 0;
|
|
545
|
-
|
|
546
|
-
console.log('Generating response...');
|
|
86
|
+
前提条件: Python 3.11以上、Apple Silicon Mac、uv。
|
|
547
87
|
|
|
548
|
-
|
|
549
|
-
for await (const chunk of stream) {
|
|
550
|
-
process.stdout.write(chunk);
|
|
551
|
-
totalChars += chunk.length;
|
|
88
|
+
## Skills(Claude Code向け)
|
|
552
89
|
|
|
553
|
-
|
|
554
|
-
process.stderr.write(`\r[${totalChars} characters generated]`);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
const finalResult = await result;
|
|
558
|
-
console.log(`\nComplete! (${finalResult.usage?.totalTokens} tokens)`);
|
|
559
|
-
}
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
### リトライロジック
|
|
563
|
-
|
|
564
|
-
```typescript
|
|
565
|
-
async function queryWithRetry(
|
|
566
|
-
driver: AIDriver,
|
|
567
|
-
prompt: CompiledPrompt,
|
|
568
|
-
maxRetries = 3
|
|
569
|
-
): Promise<QueryResult> {
|
|
570
|
-
for (let i = 0; i < maxRetries; i++) {
|
|
571
|
-
try {
|
|
572
|
-
const result = await driver.query(prompt);
|
|
573
|
-
|
|
574
|
-
if (result.finishReason !== 'error') {
|
|
575
|
-
return result;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
console.warn(`Attempt ${i + 1} failed, retrying...`);
|
|
579
|
-
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
|
|
580
|
-
} catch (error) {
|
|
581
|
-
if (i === maxRetries - 1) throw error;
|
|
582
|
-
console.warn(`Attempt ${i + 1} threw error, retrying...`);
|
|
583
|
-
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
throw new Error('Max retries exceeded');
|
|
588
|
-
}
|
|
589
|
-
```
|
|
90
|
+
このパッケージには `skills/driver-usage/SKILL.md` が同梱されています。Claude Codeのスキルとして利用でき、ドライバーの使い方をガイドします。
|
|
590
91
|
|
|
591
92
|
## ライセンス
|
|
592
93
|
|
|
593
94
|
MIT
|
|
594
|
-
|
|
595
|
-
## 貢献
|
|
596
|
-
|
|
597
|
-
プルリクエストを歓迎します。大きな変更の場合は、まずissueを開いて変更内容を議論してください。
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* ドライバレジストリの実装
|
|
4
4
|
*/
|
|
5
5
|
import type { AIDriver } from '../types.js';
|
|
6
|
-
import { type LogLevel } from '@modular-prompt/utils';
|
|
7
6
|
import type { DriverProvider, DriverCapability, ModelSpec, DriverSelectionCriteria, DriverSelectionResult, IDriverRegistry, DriverFactory } from './types.js';
|
|
8
7
|
/**
|
|
9
8
|
* ドライバレジストリクラス
|
|
@@ -12,7 +11,7 @@ export declare class DriverRegistry implements IDriverRegistry {
|
|
|
12
11
|
private models;
|
|
13
12
|
private factories;
|
|
14
13
|
private logger;
|
|
15
|
-
constructor(
|
|
14
|
+
constructor();
|
|
16
15
|
/**
|
|
17
16
|
* デフォルトのドライバファクトリを登録
|
|
18
17
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/driver-registry/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/driver-registry/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAY5C,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,uBAAuB,EACvB,qBAAqB,EACrB,eAAe,EACf,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB;;GAEG;AACH,qBAAa,cAAe,YAAW,eAAe;IACpD,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,SAAS,CAAiD;IAClE,OAAO,CAAC,MAAM,CAAS;;IAUvB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAahC;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAIvE;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,cAAc,GAAG,aAAa,GAAG,SAAS;IAK/D;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAWpC;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,uBAAuB,GAAG,qBAAqB,GAAG,IAAI;IAwH5E;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;IAStD;;OAEG;IACG,qBAAqB,CACzB,YAAY,EAAE,gBAAgB,EAAE,EAChC,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;QAC7B,gBAAgB,CAAC,EAAE,cAAc,EAAE,CAAC;KACrC,GACA,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;CA0B5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/driver-registry/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/driver-registry/registry.ts"],"names":[],"mappings":"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"}
|