@modular-prompt/driver 0.6.3 → 0.8.1
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/formatter/formatter.d.ts.map +1 -1
- package/dist/formatter/formatter.js +32 -14
- package/dist/formatter/formatter.js.map +1 -1
- package/dist/mlx-ml/mlx-driver.d.ts +4 -0
- package/dist/mlx-ml/mlx-driver.d.ts.map +1 -1
- package/dist/mlx-ml/mlx-driver.js +67 -8
- package/dist/mlx-ml/mlx-driver.js.map +1 -1
- package/dist/mlx-ml/process/index.d.ts +3 -3
- package/dist/mlx-ml/process/index.d.ts.map +1 -1
- package/dist/mlx-ml/process/index.js +2 -2
- package/dist/mlx-ml/process/index.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/queue.d.ts +2 -2
- package/dist/mlx-ml/process/queue.d.ts.map +1 -1
- package/dist/mlx-ml/process/queue.js +2 -1
- package/dist/mlx-ml/process/queue.js.map +1 -1
- package/dist/mlx-ml/process/types.d.ts +18 -0
- package/dist/mlx-ml/process/types.d.ts.map +1 -1
- package/dist/mlx-ml/tool-call-parser.d.ts +29 -0
- package/dist/mlx-ml/tool-call-parser.d.ts.map +1 -0
- package/dist/mlx-ml/tool-call-parser.js +163 -0
- package/dist/mlx-ml/tool-call-parser.js.map +1 -0
- package/dist/mlx-ml/types.d.ts +11 -0
- package/dist/mlx-ml/types.d.ts.map +1 -1
- package/package.json +6 -4
- package/skills/driver-usage/SKILL.md +432 -0
- package/src/mlx-ml/python/__main__.py +53 -38
- package/src/mlx-ml/python/pyproject.toml +1 -1
- package/src/mlx-ml/python/token_utils.py +72 -1
- package/src/mlx-ml/python/uv.lock +4 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call-parser.d.ts","sourceRoot":"","sources":["../../src/mlx-ml/tool-call-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE5E,MAAM,WAAW,mBAAmB;IAClC,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,cAAc,GAAG,IAAI,GACjC,mBAAmB,CA+BrB;AA6GD;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,cAAc,EAAE,EACvB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CAAC,EAC/D,cAAc,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1D,MAAM,CAqCR"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* モデル出力からtool callを検出・パース
|
|
3
|
+
*
|
|
4
|
+
* 検出戦略:
|
|
5
|
+
* 1. runtimeInfo.features.chat_template.tool_call_format が存在 → テンプレート由来のデリミタで検出
|
|
6
|
+
* 2. runtimeInfo.special_tokens.tool_call が存在 → 特殊トークンによるデリミタで検出
|
|
7
|
+
* 3. ```json:toolCall コードブロック → ラベル付きコードブロック検出
|
|
8
|
+
* 4. 汎用フォールバック → JSON形式のtool call検出
|
|
9
|
+
*/
|
|
10
|
+
export function parseToolCalls(text, runtimeInfo) {
|
|
11
|
+
// 1. tool_call_format(テンプレート由来)による検出
|
|
12
|
+
const toolCallFormat = runtimeInfo?.features?.chat_template?.tool_call_format;
|
|
13
|
+
if (toolCallFormat?.call_start && toolCallFormat?.call_end) {
|
|
14
|
+
const result = parseWithDelimiters(text, toolCallFormat.call_start, toolCallFormat.call_end);
|
|
15
|
+
if (result.toolCalls.length > 0) {
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// 2. 特殊トークンによる検出
|
|
20
|
+
const toolCallToken = runtimeInfo?.special_tokens?.tool_call;
|
|
21
|
+
if (toolCallToken && typeof toolCallToken === 'object' && 'start' in toolCallToken) {
|
|
22
|
+
const result = parseWithDelimiters(text, toolCallToken.start.text, toolCallToken.end.text);
|
|
23
|
+
if (result.toolCalls.length > 0) {
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// 3. ```json:toolCall コードブロック検出
|
|
28
|
+
const codeBlockResult = parseCodeBlockToolCalls(text);
|
|
29
|
+
if (codeBlockResult.toolCalls.length > 0) {
|
|
30
|
+
return codeBlockResult;
|
|
31
|
+
}
|
|
32
|
+
// 4. 汎用フォールバック
|
|
33
|
+
return parseGenericToolCalls(text);
|
|
34
|
+
}
|
|
35
|
+
function parseWithDelimiters(text, startDelimiter, endDelimiter) {
|
|
36
|
+
const toolCalls = [];
|
|
37
|
+
let content = text;
|
|
38
|
+
let callIndex = 0;
|
|
39
|
+
// startDelimiter...endDelimiter のパターンを繰り返し検索
|
|
40
|
+
const regex = new RegExp(escapeRegExp(startDelimiter) + '([\\s\\S]*?)' + escapeRegExp(endDelimiter), 'g');
|
|
41
|
+
let match;
|
|
42
|
+
while ((match = regex.exec(text)) !== null) {
|
|
43
|
+
const jsonStr = match[1].trim();
|
|
44
|
+
try {
|
|
45
|
+
const parsed = JSON.parse(jsonStr);
|
|
46
|
+
toolCalls.push({
|
|
47
|
+
id: `call_${callIndex++}`,
|
|
48
|
+
name: parsed.name,
|
|
49
|
+
arguments: parsed.arguments || parsed.parameters || {}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// JSONパース失敗 → スキップ
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (toolCalls.length > 0) {
|
|
57
|
+
// tool call部分をテキストから除去
|
|
58
|
+
content = text.replace(regex, '').trim();
|
|
59
|
+
}
|
|
60
|
+
return { content, toolCalls };
|
|
61
|
+
}
|
|
62
|
+
function parseCodeBlockToolCalls(text) {
|
|
63
|
+
const toolCalls = [];
|
|
64
|
+
let content = text;
|
|
65
|
+
let callIndex = 0;
|
|
66
|
+
// ```json:toolCall ... ``` パターンを検出
|
|
67
|
+
const codeBlockRegex = /```json:toolCall\s*\n([\s\S]*?)```/g;
|
|
68
|
+
let match;
|
|
69
|
+
while ((match = codeBlockRegex.exec(text)) !== null) {
|
|
70
|
+
const jsonStr = match[1].trim();
|
|
71
|
+
try {
|
|
72
|
+
const parsed = JSON.parse(jsonStr);
|
|
73
|
+
toolCalls.push({
|
|
74
|
+
id: `call_${callIndex++}`,
|
|
75
|
+
name: parsed.name,
|
|
76
|
+
arguments: parsed.arguments || parsed.parameters || {}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// JSONパース失敗 → スキップ
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (toolCalls.length > 0) {
|
|
84
|
+
content = text.replace(codeBlockRegex, '').trim();
|
|
85
|
+
}
|
|
86
|
+
return { content, toolCalls };
|
|
87
|
+
}
|
|
88
|
+
function parseGenericToolCalls(text) {
|
|
89
|
+
const toolCalls = [];
|
|
90
|
+
let content = text;
|
|
91
|
+
let callIndex = 0;
|
|
92
|
+
// 汎用パターン: {"name": "...", "arguments": {...}} を検出
|
|
93
|
+
// 行頭からJSONオブジェクトが始まるか、テキスト末尾のJSONブロックを検出
|
|
94
|
+
const jsonPattern = /\{[\s\S]*?"name"\s*:\s*"[^"]+?"[\s\S]*?(?:"arguments"|"parameters")\s*:\s*\{[\s\S]*?\}\s*\}/g;
|
|
95
|
+
let match;
|
|
96
|
+
while ((match = jsonPattern.exec(text)) !== null) {
|
|
97
|
+
try {
|
|
98
|
+
const parsed = JSON.parse(match[0]);
|
|
99
|
+
if (parsed.name && (parsed.arguments || parsed.parameters)) {
|
|
100
|
+
toolCalls.push({
|
|
101
|
+
id: `call_${callIndex++}`,
|
|
102
|
+
name: parsed.name,
|
|
103
|
+
arguments: parsed.arguments || parsed.parameters || {}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// JSONパース失敗 → スキップ
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (toolCalls.length > 0) {
|
|
112
|
+
// tool call部分をテキストから除去(最後のJSON部分のみ)
|
|
113
|
+
for (const match2 of [...text.matchAll(jsonPattern)]) {
|
|
114
|
+
content = content.replace(match2[0], '').trim();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return { content, toolCalls };
|
|
118
|
+
}
|
|
119
|
+
function escapeRegExp(str) {
|
|
120
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* tool定義をテキスト形式にフォーマット
|
|
124
|
+
* tool_call_formatまたは特殊トークンがある場合はそのフォーマットに合わせた指示を生成
|
|
125
|
+
*/
|
|
126
|
+
export function formatToolDefinitionsAsText(tools, specialTokens, toolCallFormat) {
|
|
127
|
+
const lines = ['## Available Tools', ''];
|
|
128
|
+
for (const tool of tools) {
|
|
129
|
+
lines.push(`### ${tool.name}`);
|
|
130
|
+
if (tool.description) {
|
|
131
|
+
lines.push(tool.description);
|
|
132
|
+
}
|
|
133
|
+
if (tool.parameters) {
|
|
134
|
+
lines.push(`Parameters: ${JSON.stringify(tool.parameters)}`);
|
|
135
|
+
}
|
|
136
|
+
lines.push('');
|
|
137
|
+
}
|
|
138
|
+
// tool call出力フォーマットの指示
|
|
139
|
+
if (toolCallFormat?.call_start && toolCallFormat?.call_end) {
|
|
140
|
+
lines.push('To call a tool, respond with:');
|
|
141
|
+
lines.push(toolCallFormat.call_start);
|
|
142
|
+
lines.push('{"name": "tool_name", "arguments": {"param": "value"}}');
|
|
143
|
+
lines.push(toolCallFormat.call_end);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const toolCallToken = specialTokens?.tool_call;
|
|
147
|
+
if (toolCallToken && 'start' in toolCallToken && 'end' in toolCallToken) {
|
|
148
|
+
const pair = toolCallToken;
|
|
149
|
+
lines.push('To call a tool, respond with:');
|
|
150
|
+
lines.push(`${pair.start.text}`);
|
|
151
|
+
lines.push('{"name": "tool_name", "arguments": {"param": "value"}}');
|
|
152
|
+
lines.push(`${pair.end.text}`);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
lines.push('To call a tool, respond with:');
|
|
156
|
+
lines.push('```json:toolCall');
|
|
157
|
+
lines.push('{"name": "tool_name", "arguments": {"param": "value"}}');
|
|
158
|
+
lines.push('```');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return lines.join('\n');
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=tool-call-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call-parser.js","sourceRoot":"","sources":["../../src/mlx-ml/tool-call-parser.ts"],"names":[],"mappings":"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"}
|
package/dist/mlx-ml/types.d.ts
CHANGED
|
@@ -26,6 +26,16 @@ export interface MlxMlModelOptions {
|
|
|
26
26
|
[key: string]: number | undefined;
|
|
27
27
|
}
|
|
28
28
|
export type { ChatRestrictions, ApiStrategy };
|
|
29
|
+
/**
|
|
30
|
+
* ツール呼び出しフォーマット
|
|
31
|
+
*/
|
|
32
|
+
export interface ToolCallFormat {
|
|
33
|
+
toolParserType?: string;
|
|
34
|
+
callStart?: string;
|
|
35
|
+
callEnd?: string;
|
|
36
|
+
responseStart?: string;
|
|
37
|
+
responseEnd?: string;
|
|
38
|
+
}
|
|
29
39
|
/**
|
|
30
40
|
* チャットテンプレート情報
|
|
31
41
|
*/
|
|
@@ -34,6 +44,7 @@ export interface ChatTemplateInfo {
|
|
|
34
44
|
supportedRoles: string[];
|
|
35
45
|
preview?: string;
|
|
36
46
|
constraints: Record<string, unknown>;
|
|
47
|
+
toolCallFormat?: ToolCallFormat;
|
|
37
48
|
}
|
|
38
49
|
/**
|
|
39
50
|
* モデルの機能情報
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mlx-ml/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAGD,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mlx-ml/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAGD,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,eAAe,EAAE,OAAO,CAAC;IAEzB,YAAY;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,cAAc;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,mBAAmB;IACnB,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,kBAAkB;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,aAAa;IACb,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CAAC,CAAC;IAE/D,aAAa;IACb,QAAQ,EAAE,aAAa,CAAC;IAExB,iCAAiC;IACjC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modular-prompt/driver",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"files": [
|
|
14
14
|
"dist",
|
|
15
15
|
"scripts",
|
|
16
|
+
"skills",
|
|
16
17
|
"src/mlx-ml/python"
|
|
17
18
|
],
|
|
18
19
|
"dependencies": {
|
|
@@ -23,8 +24,8 @@
|
|
|
23
24
|
"google-auth-library": "^9.15.1",
|
|
24
25
|
"js-yaml": "^4.1.0",
|
|
25
26
|
"openai": "^5.19.1",
|
|
26
|
-
"@modular-prompt/core": "0.1.
|
|
27
|
-
"@modular-prompt/utils": "0.2.
|
|
27
|
+
"@modular-prompt/core": "0.1.13",
|
|
28
|
+
"@modular-prompt/utils": "0.2.4"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"@eslint/js": "^9.35.0",
|
|
@@ -54,7 +55,8 @@
|
|
|
54
55
|
"download-model": "node scripts/download-model.js",
|
|
55
56
|
"lint": "eslint src/**/*.ts",
|
|
56
57
|
"typecheck": "tsc --noEmit",
|
|
57
|
-
"
|
|
58
|
+
"copy-skills": "mkdir -p skills/driver-usage && cp ../../skills/driver-usage/SKILL.md skills/driver-usage/SKILL.md",
|
|
59
|
+
"clean": "rm -rf dist skills tsconfig.tsbuildinfo",
|
|
58
60
|
"postinstall": "node scripts/setup-mlx.js || true",
|
|
59
61
|
"setup-mlx": "node scripts/setup-mlx.js"
|
|
60
62
|
}
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: driver-usage
|
|
3
|
+
description: modular-promptのドライバー(AIDriver)の使い方ガイド。各ドライバーの初期化、Config、query/streamQuery、ツール定義、構造化出力、AIServiceによるモデル選択を参照する。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ドライバー使い方ガイド
|
|
7
|
+
|
|
8
|
+
## ドライバーとは
|
|
9
|
+
|
|
10
|
+
`@modular-prompt/driver` は、コンパイル済みプロンプト(CompiledPrompt)をAIモデルに送信し、結果を受け取るための統一インターフェースを提供する。各AIサービスのAPI差異をドライバー層が吸収するため、プロンプト側のコードを変えずにモデルを切り替えられる。
|
|
11
|
+
|
|
12
|
+
### 基本的な使い方
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
import { compile } from '@modular-prompt/core';
|
|
16
|
+
import { OpenAIDriver } from '@modular-prompt/driver';
|
|
17
|
+
|
|
18
|
+
const driver = new OpenAIDriver({ model: 'gpt-4o' });
|
|
19
|
+
const compiled = compile(myModule, context);
|
|
20
|
+
|
|
21
|
+
// 通常クエリ
|
|
22
|
+
const result = await driver.query(compiled);
|
|
23
|
+
console.log(result.content);
|
|
24
|
+
|
|
25
|
+
// ストリーミング
|
|
26
|
+
const { stream, result: resultPromise } = await driver.streamQuery(compiled);
|
|
27
|
+
for await (const chunk of stream) {
|
|
28
|
+
process.stdout.write(chunk);
|
|
29
|
+
}
|
|
30
|
+
const finalResult = await resultPromise;
|
|
31
|
+
|
|
32
|
+
await driver.close();
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## AIDriver インターフェース
|
|
36
|
+
|
|
37
|
+
全ドライバーが実装する共通インターフェース:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
interface AIDriver {
|
|
41
|
+
query(prompt: CompiledPrompt, options?: QueryOptions): Promise<QueryResult>;
|
|
42
|
+
streamQuery(prompt: CompiledPrompt, options?: QueryOptions): Promise<StreamResult>;
|
|
43
|
+
close(): Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### QueryOptions
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
interface QueryOptions {
|
|
51
|
+
temperature?: number;
|
|
52
|
+
maxTokens?: number;
|
|
53
|
+
topP?: number;
|
|
54
|
+
stream?: boolean;
|
|
55
|
+
tools?: ToolDefinition[];
|
|
56
|
+
toolChoice?: ToolChoice;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### QueryResult
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
interface QueryResult {
|
|
64
|
+
content: string; // テキストレスポンス
|
|
65
|
+
structuredOutput?: unknown; // 構造化出力(schema指定時)
|
|
66
|
+
usage?: {
|
|
67
|
+
promptTokens: number;
|
|
68
|
+
completionTokens: number;
|
|
69
|
+
totalTokens: number;
|
|
70
|
+
};
|
|
71
|
+
toolCalls?: ToolCall[]; // ツール呼び出し
|
|
72
|
+
finishReason?: FinishReason; // 'stop' | 'length' | 'error' | 'tool_calls'
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### StreamResult
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
interface StreamResult {
|
|
80
|
+
stream: AsyncIterable<string>; // テキストチャンクのストリーム
|
|
81
|
+
result: Promise<QueryResult>; // 最終結果(ストリーム完了後に解決)
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 各ドライバーのConfig
|
|
86
|
+
|
|
87
|
+
### OpenAIDriver
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { OpenAIDriver } from '@modular-prompt/driver';
|
|
91
|
+
|
|
92
|
+
const driver = new OpenAIDriver({
|
|
93
|
+
apiKey: process.env.OPENAI_API_KEY, // 環境変数で代替可
|
|
94
|
+
model: 'gpt-4o-mini', // デフォルト: 'gpt-4o-mini'
|
|
95
|
+
baseURL: 'https://...', // カスタムエンドポイント(オプション)
|
|
96
|
+
organization: '...', // Organization ID(オプション)
|
|
97
|
+
defaultOptions: {
|
|
98
|
+
temperature: 0.7,
|
|
99
|
+
maxTokens: 2000,
|
|
100
|
+
frequencyPenalty: 0, // OpenAI固有
|
|
101
|
+
presencePenalty: 0, // OpenAI固有
|
|
102
|
+
stop: ['---'], // 停止シーケンス
|
|
103
|
+
responseFormat: { type: 'json_object' },
|
|
104
|
+
seed: 42
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### AnthropicDriver
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { AnthropicDriver } from '@modular-prompt/driver';
|
|
113
|
+
|
|
114
|
+
const driver = new AnthropicDriver({
|
|
115
|
+
apiKey: process.env.ANTHROPIC_API_KEY, // 環境変数で代替可
|
|
116
|
+
model: 'claude-3-5-sonnet-20241022', // デフォルト
|
|
117
|
+
defaultOptions: {
|
|
118
|
+
maxTokens: 4096,
|
|
119
|
+
temperature: 0.7,
|
|
120
|
+
topK: 40, // Anthropic固有
|
|
121
|
+
stopSequences: ['---']
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### VertexAIDriver
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { VertexAIDriver } from '@modular-prompt/driver';
|
|
130
|
+
|
|
131
|
+
const driver = new VertexAIDriver({
|
|
132
|
+
project: 'my-gcp-project', // 環境変数 GOOGLE_CLOUD_PROJECT で代替可
|
|
133
|
+
location: 'us-central1', // デフォルト: 'us-central1'
|
|
134
|
+
model: 'gemini-2.0-flash-001', // デフォルト
|
|
135
|
+
temperature: 0.05,
|
|
136
|
+
defaultOptions: {
|
|
137
|
+
maxTokens: 1000,
|
|
138
|
+
topP: 0.95,
|
|
139
|
+
topK: 40
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Google Cloud認証(ADCまたはサービスアカウント)が必要。
|
|
145
|
+
|
|
146
|
+
### GoogleGenAIDriver
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { GoogleGenAIDriver } from '@modular-prompt/driver';
|
|
150
|
+
|
|
151
|
+
const driver = new GoogleGenAIDriver({
|
|
152
|
+
apiKey: process.env.GOOGLE_GENAI_API_KEY, // 必須
|
|
153
|
+
model: 'gemini-2.0-flash-exp',
|
|
154
|
+
temperature: 0.7,
|
|
155
|
+
defaultOptions: {
|
|
156
|
+
maxTokens: 2048,
|
|
157
|
+
topP: 0.95,
|
|
158
|
+
topK: 40,
|
|
159
|
+
thinkingConfig: { thinkingLevel: 'HIGH' } // GoogleGenAI固有
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
APIキーのみで利用可能(Google AI Studioから取得)。
|
|
165
|
+
|
|
166
|
+
### OllamaDriver
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { OllamaDriver } from '@modular-prompt/driver';
|
|
170
|
+
|
|
171
|
+
const driver = new OllamaDriver({
|
|
172
|
+
baseURL: 'http://localhost:11434/v1', // デフォルト
|
|
173
|
+
model: 'llama3.2' // デフォルト
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
OpenAI互換APIでローカルLLMにアクセス。
|
|
178
|
+
|
|
179
|
+
### MlxDriver
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { MlxDriver } from '@modular-prompt/driver';
|
|
183
|
+
|
|
184
|
+
const driver = new MlxDriver({
|
|
185
|
+
model: 'mlx-community/Llama-3.2-3B-Instruct-4bit', // 必須
|
|
186
|
+
defaultOptions: {
|
|
187
|
+
temperature: 0.7,
|
|
188
|
+
maxTokens: 500,
|
|
189
|
+
repetitionPenalty: 1.1, // MLX固有
|
|
190
|
+
repetitionContextSize: 20 // MLX固有
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// 使用後は必ずclose()(Pythonサブプロセス終了)
|
|
195
|
+
await driver.close();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Apple Silicon専用。Python 3.11以上が必要。
|
|
199
|
+
|
|
200
|
+
### テスト・デバッグ用ドライバー
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { TestDriver, EchoDriver } from '@modular-prompt/driver';
|
|
204
|
+
|
|
205
|
+
// TestDriver: モックレスポンス
|
|
206
|
+
const testDriver = new TestDriver({
|
|
207
|
+
responses: ['応答1', '応答2'], // キューから順に返す
|
|
208
|
+
delay: 100 // レイテンシのシミュレート(ms)
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// レスポンスプロバイダ関数
|
|
212
|
+
const testDriver2 = new TestDriver({
|
|
213
|
+
responses: (prompt, options) => {
|
|
214
|
+
if (prompt.metadata?.outputSchema) {
|
|
215
|
+
return JSON.stringify({ result: 'ok' });
|
|
216
|
+
}
|
|
217
|
+
return 'テキスト応答';
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// EchoDriver: フォーマット済みプロンプトをそのまま返す(AI呼び出しなし)
|
|
222
|
+
const echoDriver = new EchoDriver({
|
|
223
|
+
format: 'debug', // 'text' | 'messages' | 'raw' | 'both' | 'debug'
|
|
224
|
+
includeMetadata: true
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## ツール定義(Function Calling)
|
|
229
|
+
|
|
230
|
+
### ToolDefinition
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
const tools: ToolDefinition[] = [
|
|
234
|
+
{
|
|
235
|
+
name: 'get_weather',
|
|
236
|
+
description: '指定都市の天気を取得',
|
|
237
|
+
parameters: {
|
|
238
|
+
type: 'object',
|
|
239
|
+
properties: {
|
|
240
|
+
city: { type: 'string', description: '都市名' },
|
|
241
|
+
unit: { type: 'string', enum: ['celsius', 'fahrenheit'] }
|
|
242
|
+
},
|
|
243
|
+
required: ['city']
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
];
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### ToolChoice
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
type ToolChoice =
|
|
253
|
+
| 'auto' // モデルが自動判断(デフォルト)
|
|
254
|
+
| 'none' // ツール使用禁止
|
|
255
|
+
| 'required' // 必ず1つ以上のツールを使用
|
|
256
|
+
| { name: string }; // 特定ツールを強制
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### ツール呼び出しの処理
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
const result = await driver.query(compiled, { tools, toolChoice: 'auto' });
|
|
263
|
+
|
|
264
|
+
if (result.toolCalls) {
|
|
265
|
+
for (const call of result.toolCalls) {
|
|
266
|
+
console.log(call.name); // 関数名
|
|
267
|
+
console.log(call.id); // 呼び出しID
|
|
268
|
+
console.log(call.arguments); // 引数オブジェクト
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
対応ドライバー: OpenAI、Anthropic、VertexAI、GoogleGenAI
|
|
274
|
+
|
|
275
|
+
### ツール結果の返し方(会話ループ)
|
|
276
|
+
|
|
277
|
+
ツール呼び出し結果をモデルに返す会話ループは利用者側で実装する。`QueryOptions.messages` にツール結果を含めて再クエリする。
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
const result1 = await driver.query(compiled, { tools, toolChoice: 'auto' });
|
|
281
|
+
|
|
282
|
+
if (result1.toolCalls) {
|
|
283
|
+
// ツールを実行して結果を収集
|
|
284
|
+
const toolResults = await Promise.all(
|
|
285
|
+
result1.toolCalls.map(async (tc) => {
|
|
286
|
+
const data = await executeFunction(tc.name, tc.arguments);
|
|
287
|
+
return {
|
|
288
|
+
role: 'tool' as const,
|
|
289
|
+
toolCallId: tc.id,
|
|
290
|
+
name: tc.name,
|
|
291
|
+
kind: 'data' as const, // 'text' | 'data' | 'error'
|
|
292
|
+
value: data
|
|
293
|
+
};
|
|
294
|
+
})
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
// ツール結果を含めて再クエリ
|
|
298
|
+
const result2 = await driver.query(compiled, {
|
|
299
|
+
tools,
|
|
300
|
+
messages: [
|
|
301
|
+
{ role: 'assistant', content: result1.content, toolCalls: result1.toolCalls },
|
|
302
|
+
...toolResults
|
|
303
|
+
]
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### ToolResultKind
|
|
309
|
+
|
|
310
|
+
ツール結果の種類を示すタグ:
|
|
311
|
+
- `'text'` - プレーンテキスト
|
|
312
|
+
- `'data'` - 構造化データ(オブジェクト等)
|
|
313
|
+
- `'error'` - エラー情報
|
|
314
|
+
|
|
315
|
+
## 構造化出力
|
|
316
|
+
|
|
317
|
+
プロンプトの `schema` セクションに JSONElement を定義すると、ドライバーが自動的に構造化出力を処理する。
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
const myModule: PromptModule = {
|
|
321
|
+
objective: ['ユーザー情報を抽出する'],
|
|
322
|
+
schema: [{
|
|
323
|
+
type: 'json',
|
|
324
|
+
content: {
|
|
325
|
+
type: 'object',
|
|
326
|
+
properties: {
|
|
327
|
+
name: { type: 'string' },
|
|
328
|
+
age: { type: 'number' }
|
|
329
|
+
},
|
|
330
|
+
required: ['name', 'age']
|
|
331
|
+
}
|
|
332
|
+
}]
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const result = await driver.query(compile(myModule, ctx));
|
|
336
|
+
const data = result.structuredOutput as { name: string; age: number };
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
ドライバーごとの実装方式:
|
|
340
|
+
- **ネイティブサポート**: OpenAI(`response_format`)、VertexAI / GoogleGenAI(`responseSchema`)
|
|
341
|
+
- **JSON抽出型**: Anthropic、MLX(プロンプト指示 + レスポンスからJSON抽出)
|
|
342
|
+
|
|
343
|
+
## AIService(モデル選択)
|
|
344
|
+
|
|
345
|
+
複数モデルを登録し、能力(capabilities)ベースで最適なモデルを自動選択する。
|
|
346
|
+
|
|
347
|
+
### 設定
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
import { AIService } from '@modular-prompt/driver';
|
|
351
|
+
|
|
352
|
+
const service = new AIService({
|
|
353
|
+
models: [
|
|
354
|
+
{
|
|
355
|
+
model: 'gpt-4o',
|
|
356
|
+
provider: 'openai',
|
|
357
|
+
capabilities: ['streaming', 'japanese', 'tools', 'structured'],
|
|
358
|
+
priority: 10,
|
|
359
|
+
cost: { input: 0.01, output: 0.03 }
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
363
|
+
provider: 'anthropic',
|
|
364
|
+
capabilities: ['streaming', 'japanese', 'tools', 'reasoning'],
|
|
365
|
+
priority: 8
|
|
366
|
+
}
|
|
367
|
+
],
|
|
368
|
+
drivers: {
|
|
369
|
+
openai: { apiKey: process.env.OPENAI_API_KEY },
|
|
370
|
+
anthropic: { apiKey: process.env.ANTHROPIC_API_KEY }
|
|
371
|
+
},
|
|
372
|
+
defaultOptions: {
|
|
373
|
+
temperature: 0.7,
|
|
374
|
+
maxTokens: 2048
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### ModelSpec
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
interface ModelSpec {
|
|
383
|
+
model: string;
|
|
384
|
+
provider: DriverProvider;
|
|
385
|
+
capabilities: DriverCapability[];
|
|
386
|
+
priority?: number; // 高いほど優先
|
|
387
|
+
disabled?: boolean; // 無効化フラグ
|
|
388
|
+
maxInputTokens?: number;
|
|
389
|
+
maxOutputTokens?: number;
|
|
390
|
+
maxTotalTokens?: number;
|
|
391
|
+
tokensPerMinute?: number; // TPM制限
|
|
392
|
+
requestsPerMinute?: number; // RPM制限
|
|
393
|
+
cost?: { input: number; output: number };
|
|
394
|
+
metadata?: Record<string, unknown>;
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### DriverCapability(能力フラグ)
|
|
399
|
+
|
|
400
|
+
| 能力 | 説明 |
|
|
401
|
+
|------|------|
|
|
402
|
+
| `streaming` | ストリーミング応答 |
|
|
403
|
+
| `local` | ローカル実行 |
|
|
404
|
+
| `fast` | 高速応答 |
|
|
405
|
+
| `large-context` | 大規模コンテキスト |
|
|
406
|
+
| `multilingual` | 多言語対応 |
|
|
407
|
+
| `japanese` | 日本語特化 |
|
|
408
|
+
| `coding` | コーディング特化 |
|
|
409
|
+
| `reasoning` | 推論・思考特化 |
|
|
410
|
+
| `chat` | チャット特化 |
|
|
411
|
+
| `tools` | ツール使用 |
|
|
412
|
+
| `vision` | 画像認識 |
|
|
413
|
+
| `audio` | 音声処理 |
|
|
414
|
+
| `structured` | 構造化出力 |
|
|
415
|
+
| `json` | JSON出力 |
|
|
416
|
+
| `function-calling` | 関数呼び出し |
|
|
417
|
+
|
|
418
|
+
### モデル選択
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
// 能力ベースでドライバーを自動作成
|
|
422
|
+
const driver = await service.createDriverFromCapabilities(
|
|
423
|
+
['japanese', 'streaming'],
|
|
424
|
+
{
|
|
425
|
+
preferLocal: true, // ローカル優先
|
|
426
|
+
preferProvider: 'anthropic', // 特定プロバイダー優先
|
|
427
|
+
excludeProviders: ['openai'],
|
|
428
|
+
preferFast: true, // 高速優先
|
|
429
|
+
lenient: true // 条件緩和モード(条件を後ろから減らして再検索)
|
|
430
|
+
}
|
|
431
|
+
);
|
|
432
|
+
```
|