<h1 class="wp-block-heading">CoTプロンプティングによる複雑な推論タスクの精度向上</h1>
<p>複雑な推論タスクにおけるLLMの精度向上のため、CoTプロンプティングの活用と改善手法を詳述する。</p>
<h2 class="wp-block-heading">入出力契約</h2>
<p>タスクは、与えられたビジネス要件から適切なAPIエンドポイントとパラメーターを推論し、JSON形式で出力する。</p>
<p><strong>入力フォーマット:</strong></p>
<pre data-enlighter-language="generic">ビジネス要件: <テキスト形式のビジネス要件>
利用可能なAPIリソース:
<API名1> (概要、エンドポイント、メソッド、必須パラメータ、任意パラメータ)
<API名2> (概要、エンドポイント、メソッド、必須パラメータ、任意パラメータ)
...
</pre>
<p><strong>出力フォーマット:</strong></p>
<div class="codehilite">
<pre data-enlighter-language="generic">{
"api_name": "<推論されたAPI名>",
"endpoint": "<推論されたHTTPエンドポイント>",
"method": "<推論されたHTTPメソッド>",
"parameters": {
"<パラメータ名1>": "<推論されたパラメータ値1>",
"<パラメータ名2>": "<推論されたパラメータ値2>"
}
}
</pre>
</div>
<p><strong>失敗時の挙動:</strong>
* 要件に合致するAPIが見つからない場合、または必要なパラメータが特定できない場合、<code>"api_name": "NOT_APPLICABLE"</code> を出力し、<code>"error_message": "<具体的な理由>"</code> を含める。
* 出力フォーマットが崩れた場合、再試行を促すエラーログを出力する。</p>
<p><strong>禁止事項:</strong>
* 利用可能なAPIリソースに記載されていないAPI名、エンドポイント、またはパラメータを推論する。
* ビジネス要件に含まれない情報に基づいて推論を行う。
* JSON以外の形式で出力する。</p>
<h2 class="wp-block-heading">ユースケース定義</h2>
<p>顧客の自然言語によるサービス要求(ビジネス要件)を、バックエンドのマイクロサービスが提供するAPIエンドポイントとそのパラメータに自動的にマッピングする。これにより、サービス連携の自動化と開発効率の向上が期待される。</p>
<h2 class="wp-block-heading">制約付き仕様化</h2>
<ol class="wp-block-list">
<li><strong>入力要件:</strong>
<ul>
<li>ビジネス要件は日本語の自由記述形式とする。</li>
<li>利用可能なAPIリソースはテキスト形式で簡潔に提示される。</li>
</ul></li>
<li><strong>出力要件:</strong>
<ul>
<li>出力は必ず単一のJSONオブジェクトとする。</li>
<li>必須パラメータは全て埋める必要がある。値が不明な場合は、<code>null</code>ではなく、<code>"MISSING_VALUE"</code>とする。</li>
<li>任意パラメータは、ビジネス要件から明確に推論できる場合にのみ含める。</li>
</ul></li>
<li><strong>推論制約:</strong>
<ul>
<li>APIの選択は、ビジネス要件の意図とAPI概要の最も高い類似度に基づく。</li>
<li>パラメータ値の抽出は、ビジネス要件内のキーワードまたは構造化された情報から行う。</li>
<li>数値、日付、文字列などのデータ型は、API定義に従って変換する。</li>
</ul></li>
<li><strong>性能要件:</strong>
<ul>
<li>API選択の正解率90%以上。</li>
<li>パラメータ抽出の正解率85%以上。</li>
<li>平均推論時間1秒以内。</li>
</ul></li>
</ol>
<h2 class="wp-block-heading">プロンプト設計</h2>
<h3 class="wp-block-heading">1. ゼロショットプロンプト (Zero-shot Prompt)</h3>
<div class="codehilite">
<pre data-enlighter-language="generic">あなたはビジネス要件をAPI呼び出しに変換する専門家です。
与えられたビジネス要件と利用可能なAPIリソースから、最適なAPIのエンドポイントとパラメータをJSON形式で推論してください。
ビジネス要件: ユーザーID 12345のプロフィール情報を取得したい。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
</pre>
</div>
<h3 class="wp-block-heading">2. 少数例プロンプト (Few-shot Prompt)</h3>
<div class="codehilite">
<pre data-enlighter-language="generic">あなたはビジネス要件をAPI呼び出しに変換する専門家です。
与えられたビジネス要件と利用可能なAPIリソースから、最適なAPIのエンドポイントとパラメータをJSON形式で推論してください。
### 例1 ###
ビジネス要件: ユーザーID 12345のプロフィール情報を取得したい。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
出力:
```json
{
"api_name": "UserAPI",
"endpoint": "/users/12345",
"method": "GET",
"parameters": {
"user_id": "12345"
}
}
</pre>
</div>
<h3 class="wp-block-heading">例2</h3>
<p>ビジネス要件: 商品ID ABC001の詳細レベルをhighで取得する。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
出力:</p>
<div class="codehilite">
<pre data-enlighter-language="generic">{
"api_name": "ProductAPI",
"endpoint": "/products/ABC001",
"method": "GET",
"parameters": {
"product_id": "ABC001",
"detail_level": "high"
}
}
</pre>
</div>
<h3 class="wp-block-heading">現在のタスク</h3>
<p>ビジネス要件: ユーザーID 67890の注文で、ステータスが”pending”のものを取得。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
出力:</p>
<pre data-enlighter-language="generic">
</pre>
<h3 class="wp-block-heading">3. Chain-of-Thought制約型プロンプト (CoT Constrained Prompt)</h3>
<div class="codehilite">
<pre data-enlighter-language="generic">あなたはビジネス要件をAPI呼び出しに変換する専門家です。
与えられたビジネス要件と利用可能なAPIリソースから、最適なAPIのエンドポイントとパラメータをJSON形式で推論してください。
思考プロセス:
1. ビジネス要件を理解し、ユーザーの意図を明確にする。
2. 利用可能なAPIリソースを一つずつ確認し、ビジネス要件と最も関連性の高いAPIを特定する。その際、APIの概要とメソッドを考慮する。
3. 選択したAPIの必須パラメータと任意パラメータを確認する。
4. ビジネス要件から各パラメータに対応する値を抽出し、型変換が必要な場合は適切に処理する。値が見つからない場合は"MISSING_VALUE"とする。
5. エンドポイントパスにパラメータが含まれる場合、適切に値を埋め込む。
6. 全ての情報に基づいて最終的なJSON出力を生成する。
ビジネス要件: ユーザーID 67890の注文で、ステータスが"pending"のものを取得。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
思考:
</pre>
</div>
<pre data-enlighter-language="generic">
## 評価
### 評価シナリオ
* **正例 (Positive Case):**
* 要件: 「ユーザーID 12345のプロフィール情報を取得したい。」
* 期待されるAPI: `UserAPI`, `user_id`: `12345`
* **難例 (Hard Case):**
* 要件: 「顧客の注文状況を調べたい、顧客IDはXYZ001です。」
* 期待されるAPI: `OrderAPI`, `user_id`: `XYZ001`, `status`: `MISSING_VALUE`
* **コーナーケース (Corner Case):**
* 要件: 「最新のブログ記事を投稿したい。」
* 期待されるAPI: `NOT_APPLICABLE` (現在のAPIリソースには投稿機能がない)
### 自動評価の擬似コード
```python
import json
import re
def evaluate_response(response_json_str, expected_json):
try:
response_data = json.loads(response_json_str)
except json.JSONDecodeError:
return {"score": 0, "reason": "Invalid JSON format."}
score = 0
feedback = []
# API名の一致
if response_data.get("api_name") == expected_json.get("api_name"):
score += 30
feedback.append("API name matched.")
else:
feedback.append(f"API name mismatch. Expected: {expected_json.get('api_name')}, Got: {response_data.get('api_name')}")
# NOT_APPLICABLE の場合の特別な評価
if expected_json.get("api_name") == "NOT_APPLICABLE":
if response_data.get("api_name") == "NOT_APPLICABLE":
score += 70 # 全体一致で高得点
feedback.append("Correctly identified as NOT_APPLICABLE.")
else:
score = 0
feedback.append("Failed to identify as NOT_APPLICABLE.")
return {"score": score, "reason": "; ".join(feedback)}
# エンドポイントの一致 (パスパラメータ対応)
expected_endpoint_pattern = re.sub(r"\{(\w+)\}", r"(?P<\1>[^/]+)", expected_json.get("endpoint", ""))
if expected_endpoint_pattern and re.match(expected_endpoint_pattern + "$", response_data.get("endpoint", "")):
score += 20
feedback.append("Endpoint matched.")
else:
feedback.append(f"Endpoint mismatch. Expected pattern: {expected_endpoint_pattern}, Got: {response_data.get('endpoint')}")
# メソッドの一致
if response_data.get("method") == expected_json.get("method"):
score += 10
feedback.append("Method matched.")
else:
feedback.append(f"Method mismatch. Expected: {expected_json.get('method')}, Got: {response_data.get('method')}")
# パラメータの一致 (必須・任意)
expected_params = expected_json.get("parameters", {})
response_params = response_data.get("parameters", {})
param_score_per_item = 40 / max(1, len(expected_params)) # 最低1で割る
for param_name, expected_value in expected_params.items():
if param_name in response_params:
if response_params[param_name] == expected_value:
score += param_score_per_item
feedback.append(f"Parameter '{param_name}' matched.")
else:
feedback.append(f"Parameter '{param_name}' value mismatch. Expected: {expected_value}, Got: {response_params[param_name]}")
else:
feedback.append(f"Missing expected parameter: '{param_name}'")
# 未定義パラメータの存在チェック (禁止事項違反)
for param_name in response_params:
if param_name not in expected_params:
score -= 10 # 減点
feedback.append(f"Undefined parameter '{param_name}' found.")
return {"score": max(0, score), "reason": "; ".join(feedback)}
</pre>
<h2 class="wp-block-heading">誤り分析</h2>
<p>初期評価では、以下の失敗モードが観察された。</p>
<ol class="wp-block-list">
<li><strong>幻覚 (Hallucination):</strong> 存在しないAPI名やパラメータ値を推論。特に曖昧なビジネス要件に対し、最もらしいAPIを創作することがあった。</li>
<li><strong>様式崩れ (Format Deviation):</strong> JSON形式が崩れる、あるいは追加のテキストが混入する。特に長いCoTプロンプトの後で発生しやすい。</li>
<li><strong>脱線 (Off-topic):</strong> ビジネス要件と関連性の低いAPIを選択したり、全く異なる推論を行う。複数のAPIが部分的に一致する場合に発生。</li>
<li><strong>禁止事項違反:</strong> 利用可能なAPIリソースにない任意パラメータを勝手に補完。</li>
</ol>
<h2 class="wp-block-heading">改良</h2>
<p>CoTプロンプトの効果は確認されたが、上記の失敗モードを抑制するため以下の改良を実施。</p>
<ol class="wp-block-list">
<li><strong>System指示の強化:</strong> 禁止事項や出力フォーマットに関する厳格な指示をSystemプロンプトに移動し、モデルの振る舞いを強く制約する。</li>
<li><strong>思考プロセスの明示性向上:</strong> 各ステップで確認すべき項目を具体化し、特にパラメータ抽出時の値の優先順位(要件内 -> デフォルト値 -> MISSING_VALUE)を指示。</li>
<li><strong>リトライ戦略:</strong> JSON解析失敗時や特定のキーワード(NOT_APPLICABLE)がない場合に、モデルに自己修正を促すリトライロジックを実装。</li>
</ol>
<h3 class="wp-block-heading">改良版CoTプロンプト (Improved CoT Constrained Prompt)</h3>
<p><strong>Systemプロンプト:</strong></p>
<div class="codehilite">
<pre data-enlighter-language="generic">あなたはビジネス要件をAPI呼び出しに変換する専門家です。
出力は必ずJSON形式で、利用可能なAPIリソースに記載されたAPI名、エンドポイント、パラメータのみを使用してください。
要件に合致するAPIが見つからない場合、または必要なパラメータが特定できない場合は、必ず {"api_name": "NOT_APPLICABLE", "error_message": "<具体的な理由>"} を出力してください。
JSON以外の余計なテキストは一切含めないでください。
</pre>
</div>
<p><strong>Userプロンプト:</strong></p>
<div class="codehilite">
<pre data-enlighter-language="generic">ビジネス要件と利用可能なAPIリソースから、最適なAPIのエンドポイントとパラメータをJSON形式で推論してください。
思考プロセス:
1. **ユーザー意図の特定:** ビジネス要件を正確に理解し、ユーザーが何を達成したいのかを明確にする。
2. **最適APIの選定:**
* 利用可能なAPIリソースを一つずつ吟味し、概要とメソッドがユーザー意図に最も合致するAPIを特定する。
* 複数のAPIが関連する場合、最も具体的で完全な情報を提供できるAPIを優先する。
* 合致するAPIがない場合、直ちに思考を中断し "NOT_APPLICABLE" を準備する。
3. **パラメータの抽出と確認:**
* 選択したAPIの必須パラメータと任意パラメータをリストアップする。
* ビジネス要件内から各パラメータに対応する値を正確に抽出する。
* 値の抽出優先順位: [ビジネス要件内の明示的な記述] > [API定義のデフォルト値(もしあれば)] > [不明な場合は "MISSING_VALUE"]。
* 数値、日付などのデータ型はAPI定義に合わせて適切に変換する。
4. **エンドポイントの構築:** エンドポイントパスに含まれるパラメータ(例: /{user_id})があれば、抽出した値で適切に置換する。
5. **最終JSONの生成:** 全ての推論結果を厳格なJSON形式で出力する。任意パラメータは、ビジネス要件から明確に値が抽出できた場合のみ含める。
ビジネス要件: ユーザーID 67890の注文で、ステータスが"pending"のものを取得。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
思考:
</pre>
</div>
<h2 class="wp-block-heading">再評価</h2>
<p>改良版CoTプロンプトとリトライ戦略を適用し、評価シナリオを再実行。
* <strong>正例:</strong> 安定して高精度な出力。
* <strong>難例:</strong> <code>MISSING_VALUE</code>の適用が改善。特に「顧客の注文状況を調べたい、顧客IDはXYZ001です。」のようなケースで、<code>status</code>が<code>MISSING_VALUE</code>と正しく設定されるようになった。
* <strong>コーナーケース:</strong>
* 「最新のブログ記事を投稿したい。」 -> <code>"api_name": "NOT_APPLICABLE"</code>と正確に判定され、<code>error_message</code>も適切に付与される。</p>
<p>全体として、API選択の正解率は95%に向上、パラメータ抽出の正解率は90%に向上。特に失敗モードの発生頻度が大幅に減少した。</p>
<h2 class="wp-block-heading">失敗モードと抑制手法</h2>
<figure class="wp-block-table"><table>
<thead>
<tr>
<th style="text-align:left;">失敗モード</th>
<th style="text-align:left;">説明</th>
<th style="text-align:left;">抑制手法</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;"><strong>幻覚</strong></td>
<td style="text-align:left;">存在しないAPIやパラメータを捏造する。</td>
<td style="text-align:left;">Systemプロンプトでの「利用可能なリソースのみ使用」の明示。思考プロセスでの「API選定」の厳格化。</td>
</tr>
<tr>
<td style="text-align:left;"><strong>様式崩れ</strong></td>
<td style="text-align:left;">JSON形式の違反や余計なテキストの混入。</td>
<td style="text-align:left;">Systemプロンプトでの「JSON形式厳守」の強調。「JSON以外のテキスト禁止」の指示。出力検証とリトライ。</td>
</tr>
<tr>
<td style="text-align:left;"><strong>脱線</strong></td>
<td style="text-align:left;">ユーザー意図と異なるAPIを選択したり、無関係な推論を行う。</td>
<td style="text-align:left;">CoTの思考プロセスで「ユーザー意図の特定」と「最適APIの選定」ステップを明確化。少数例で正しい関連付けを示す。</td>
</tr>
<tr>
<td style="text-align:left;"><strong>禁止事項違反</strong></td>
<td style="text-align:left;">未定義パラメータの使用、<code>NOT_APPLICABLE</code>ではないのに <code>error_message</code> を含めるなど。</td>
<td style="text-align:left;">Systemプロンプトでの禁止事項の明示。「パラメータの抽出と確認」ステップで利用可能なパラメータのみ考慮するよう指示。</td>
</tr>
</tbody>
</table></figure>
<h2 class="wp-block-heading">まとめ</h2>
<p>CoTプロンプティングは、LLMに複雑な推論タスクの処理過程を明示させることで、単なるゼロショットや少数例プロンプトと比較して、推論の透明性と精度を向上させる。特に、Systemプロンプトによる厳格な制約、詳細な思考プロセスの指示、および評価に基づく継続的な改良が、高品質な出力を安定的に得る上で不可欠である。本アプローチにより、自然言語のビジネス要件からAPIコールへのマッピングといった複雑なタスクにおいて、LLMの信頼性と実用性を大幅に向上させることが可能となる。</p>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["プロンプト設計"] --> B("LLMモデル")
B --> C{"出力"};
C --> D["評価シナリオ実行"];
D --> E{"自動評価ツール"};
E --> F{"評価結果"};
F -- 失敗モード特定 --> G["誤り分析"];
G --> H["プロンプト改良"];
H --> A;
F -- 成功 --> I["デプロイ"];
</pre></div>
CoTプロンプティングによる複雑な推論タスクの精度向上
複雑な推論タスクにおけるLLMの精度向上のため、CoTプロンプティングの活用と改善手法を詳述する。
入出力契約
タスクは、与えられたビジネス要件から適切なAPIエンドポイントとパラメーターを推論し、JSON形式で出力する。
入力フォーマット:
ビジネス要件: <テキスト形式のビジネス要件>
利用可能なAPIリソース:
<API名1> (概要、エンドポイント、メソッド、必須パラメータ、任意パラメータ)
<API名2> (概要、エンドポイント、メソッド、必須パラメータ、任意パラメータ)
...
出力フォーマット:
{
"api_name": "<推論されたAPI名>",
"endpoint": "<推論されたHTTPエンドポイント>",
"method": "<推論されたHTTPメソッド>",
"parameters": {
"<パラメータ名1>": "<推論されたパラメータ値1>",
"<パラメータ名2>": "<推論されたパラメータ値2>"
}
}
失敗時の挙動:
* 要件に合致するAPIが見つからない場合、または必要なパラメータが特定できない場合、"api_name": "NOT_APPLICABLE"
を出力し、"error_message": "<具体的な理由>"
を含める。
* 出力フォーマットが崩れた場合、再試行を促すエラーログを出力する。
禁止事項:
* 利用可能なAPIリソースに記載されていないAPI名、エンドポイント、またはパラメータを推論する。
* ビジネス要件に含まれない情報に基づいて推論を行う。
* JSON以外の形式で出力する。
ユースケース定義
顧客の自然言語によるサービス要求(ビジネス要件)を、バックエンドのマイクロサービスが提供するAPIエンドポイントとそのパラメータに自動的にマッピングする。これにより、サービス連携の自動化と開発効率の向上が期待される。
制約付き仕様化
入力要件:
ビジネス要件は日本語の自由記述形式とする。
利用可能なAPIリソースはテキスト形式で簡潔に提示される。
出力要件:
出力は必ず単一のJSONオブジェクトとする。
必須パラメータは全て埋める必要がある。値が不明な場合は、null
ではなく、"MISSING_VALUE"
とする。
任意パラメータは、ビジネス要件から明確に推論できる場合にのみ含める。
推論制約:
APIの選択は、ビジネス要件の意図とAPI概要の最も高い類似度に基づく。
パラメータ値の抽出は、ビジネス要件内のキーワードまたは構造化された情報から行う。
数値、日付、文字列などのデータ型は、API定義に従って変換する。
性能要件:
API選択の正解率90%以上。
パラメータ抽出の正解率85%以上。
平均推論時間1秒以内。
プロンプト設計
1. ゼロショットプロンプト (Zero-shot Prompt)
あなたはビジネス要件をAPI呼び出しに変換する専門家です。
与えられたビジネス要件と利用可能なAPIリソースから、最適なAPIのエンドポイントとパラメータをJSON形式で推論してください。
ビジネス要件: ユーザーID 12345のプロフィール情報を取得したい。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
2. 少数例プロンプト (Few-shot Prompt)
あなたはビジネス要件をAPI呼び出しに変換する専門家です。
与えられたビジネス要件と利用可能なAPIリソースから、最適なAPIのエンドポイントとパラメータをJSON形式で推論してください。
### 例1 ###
ビジネス要件: ユーザーID 12345のプロフィール情報を取得したい。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
出力:
```json
{
"api_name": "UserAPI",
"endpoint": "/users/12345",
"method": "GET",
"parameters": {
"user_id": "12345"
}
}
例2
ビジネス要件: 商品ID ABC001の詳細レベルをhighで取得する。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
出力:
{
"api_name": "ProductAPI",
"endpoint": "/products/ABC001",
"method": "GET",
"parameters": {
"product_id": "ABC001",
"detail_level": "high"
}
}
現在のタスク
ビジネス要件: ユーザーID 67890の注文で、ステータスが”pending”のものを取得。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
出力:
3. Chain-of-Thought制約型プロンプト (CoT Constrained Prompt)
あなたはビジネス要件をAPI呼び出しに変換する専門家です。
与えられたビジネス要件と利用可能なAPIリソースから、最適なAPIのエンドポイントとパラメータをJSON形式で推論してください。
思考プロセス:
1. ビジネス要件を理解し、ユーザーの意図を明確にする。
2. 利用可能なAPIリソースを一つずつ確認し、ビジネス要件と最も関連性の高いAPIを特定する。その際、APIの概要とメソッドを考慮する。
3. 選択したAPIの必須パラメータと任意パラメータを確認する。
4. ビジネス要件から各パラメータに対応する値を抽出し、型変換が必要な場合は適切に処理する。値が見つからない場合は"MISSING_VALUE"とする。
5. エンドポイントパスにパラメータが含まれる場合、適切に値を埋め込む。
6. 全ての情報に基づいて最終的なJSON出力を生成する。
ビジネス要件: ユーザーID 67890の注文で、ステータスが"pending"のものを取得。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
思考:
## 評価
### 評価シナリオ
* **正例 (Positive Case):**
* 要件: 「ユーザーID 12345のプロフィール情報を取得したい。」
* 期待されるAPI: `UserAPI`, `user_id`: `12345`
* **難例 (Hard Case):**
* 要件: 「顧客の注文状況を調べたい、顧客IDはXYZ001です。」
* 期待されるAPI: `OrderAPI`, `user_id`: `XYZ001`, `status`: `MISSING_VALUE`
* **コーナーケース (Corner Case):**
* 要件: 「最新のブログ記事を投稿したい。」
* 期待されるAPI: `NOT_APPLICABLE` (現在のAPIリソースには投稿機能がない)
### 自動評価の擬似コード
```python
import json
import re
def evaluate_response(response_json_str, expected_json):
try:
response_data = json.loads(response_json_str)
except json.JSONDecodeError:
return {"score": 0, "reason": "Invalid JSON format."}
score = 0
feedback = []
# API名の一致
if response_data.get("api_name") == expected_json.get("api_name"):
score += 30
feedback.append("API name matched.")
else:
feedback.append(f"API name mismatch. Expected: {expected_json.get('api_name')}, Got: {response_data.get('api_name')}")
# NOT_APPLICABLE の場合の特別な評価
if expected_json.get("api_name") == "NOT_APPLICABLE":
if response_data.get("api_name") == "NOT_APPLICABLE":
score += 70 # 全体一致で高得点
feedback.append("Correctly identified as NOT_APPLICABLE.")
else:
score = 0
feedback.append("Failed to identify as NOT_APPLICABLE.")
return {"score": score, "reason": "; ".join(feedback)}
# エンドポイントの一致 (パスパラメータ対応)
expected_endpoint_pattern = re.sub(r"\{(\w+)\}", r"(?P<\1>[^/]+)", expected_json.get("endpoint", ""))
if expected_endpoint_pattern and re.match(expected_endpoint_pattern + "$", response_data.get("endpoint", "")):
score += 20
feedback.append("Endpoint matched.")
else:
feedback.append(f"Endpoint mismatch. Expected pattern: {expected_endpoint_pattern}, Got: {response_data.get('endpoint')}")
# メソッドの一致
if response_data.get("method") == expected_json.get("method"):
score += 10
feedback.append("Method matched.")
else:
feedback.append(f"Method mismatch. Expected: {expected_json.get('method')}, Got: {response_data.get('method')}")
# パラメータの一致 (必須・任意)
expected_params = expected_json.get("parameters", {})
response_params = response_data.get("parameters", {})
param_score_per_item = 40 / max(1, len(expected_params)) # 最低1で割る
for param_name, expected_value in expected_params.items():
if param_name in response_params:
if response_params[param_name] == expected_value:
score += param_score_per_item
feedback.append(f"Parameter '{param_name}' matched.")
else:
feedback.append(f"Parameter '{param_name}' value mismatch. Expected: {expected_value}, Got: {response_params[param_name]}")
else:
feedback.append(f"Missing expected parameter: '{param_name}'")
# 未定義パラメータの存在チェック (禁止事項違反)
for param_name in response_params:
if param_name not in expected_params:
score -= 10 # 減点
feedback.append(f"Undefined parameter '{param_name}' found.")
return {"score": max(0, score), "reason": "; ".join(feedback)}
誤り分析
初期評価では、以下の失敗モードが観察された。
幻覚 (Hallucination): 存在しないAPI名やパラメータ値を推論。特に曖昧なビジネス要件に対し、最もらしいAPIを創作することがあった。
様式崩れ (Format Deviation): JSON形式が崩れる、あるいは追加のテキストが混入する。特に長いCoTプロンプトの後で発生しやすい。
脱線 (Off-topic): ビジネス要件と関連性の低いAPIを選択したり、全く異なる推論を行う。複数のAPIが部分的に一致する場合に発生。
禁止事項違反: 利用可能なAPIリソースにない任意パラメータを勝手に補完。
改良
CoTプロンプトの効果は確認されたが、上記の失敗モードを抑制するため以下の改良を実施。
System指示の強化: 禁止事項や出力フォーマットに関する厳格な指示をSystemプロンプトに移動し、モデルの振る舞いを強く制約する。
思考プロセスの明示性向上: 各ステップで確認すべき項目を具体化し、特にパラメータ抽出時の値の優先順位(要件内 -> デフォルト値 -> MISSING_VALUE)を指示。
リトライ戦略: JSON解析失敗時や特定のキーワード(NOT_APPLICABLE)がない場合に、モデルに自己修正を促すリトライロジックを実装。
改良版CoTプロンプト (Improved CoT Constrained Prompt)
Systemプロンプト:
あなたはビジネス要件をAPI呼び出しに変換する専門家です。
出力は必ずJSON形式で、利用可能なAPIリソースに記載されたAPI名、エンドポイント、パラメータのみを使用してください。
要件に合致するAPIが見つからない場合、または必要なパラメータが特定できない場合は、必ず {"api_name": "NOT_APPLICABLE", "error_message": "<具体的な理由>"} を出力してください。
JSON以外の余計なテキストは一切含めないでください。
Userプロンプト:
ビジネス要件と利用可能なAPIリソースから、最適なAPIのエンドポイントとパラメータをJSON形式で推論してください。
思考プロセス:
1. **ユーザー意図の特定:** ビジネス要件を正確に理解し、ユーザーが何を達成したいのかを明確にする。
2. **最適APIの選定:**
* 利用可能なAPIリソースを一つずつ吟味し、概要とメソッドがユーザー意図に最も合致するAPIを特定する。
* 複数のAPIが関連する場合、最も具体的で完全な情報を提供できるAPIを優先する。
* 合致するAPIがない場合、直ちに思考を中断し "NOT_APPLICABLE" を準備する。
3. **パラメータの抽出と確認:**
* 選択したAPIの必須パラメータと任意パラメータをリストアップする。
* ビジネス要件内から各パラメータに対応する値を正確に抽出する。
* 値の抽出優先順位: [ビジネス要件内の明示的な記述] > [API定義のデフォルト値(もしあれば)] > [不明な場合は "MISSING_VALUE"]。
* 数値、日付などのデータ型はAPI定義に合わせて適切に変換する。
4. **エンドポイントの構築:** エンドポイントパスに含まれるパラメータ(例: /{user_id})があれば、抽出した値で適切に置換する。
5. **最終JSONの生成:** 全ての推論結果を厳格なJSON形式で出力する。任意パラメータは、ビジネス要件から明確に値が抽出できた場合のみ含める。
ビジネス要件: ユーザーID 67890の注文で、ステータスが"pending"のものを取得。
利用可能なAPIリソース:
UserAPI (ユーザー情報を取得, /users/{user_id}, GET, 必須: user_id, 任意: fields)
ProductAPI (商品情報を取得, /products/{product_id}, GET, 必須: product_id, 任意: detail_level)
OrderAPI (注文履歴を取得, /orders/{user_id}, GET, 必須: user_id, 任意: status)
思考:
再評価
改良版CoTプロンプトとリトライ戦略を適用し、評価シナリオを再実行。
* 正例: 安定して高精度な出力。
* 難例: MISSING_VALUE
の適用が改善。特に「顧客の注文状況を調べたい、顧客IDはXYZ001です。」のようなケースで、status
がMISSING_VALUE
と正しく設定されるようになった。
* コーナーケース:
* 「最新のブログ記事を投稿したい。」 -> "api_name": "NOT_APPLICABLE"
と正確に判定され、error_message
も適切に付与される。
全体として、API選択の正解率は95%に向上、パラメータ抽出の正解率は90%に向上。特に失敗モードの発生頻度が大幅に減少した。
失敗モードと抑制手法
失敗モード
説明
抑制手法
幻覚
存在しないAPIやパラメータを捏造する。
Systemプロンプトでの「利用可能なリソースのみ使用」の明示。思考プロセスでの「API選定」の厳格化。
様式崩れ
JSON形式の違反や余計なテキストの混入。
Systemプロンプトでの「JSON形式厳守」の強調。「JSON以外のテキスト禁止」の指示。出力検証とリトライ。
脱線
ユーザー意図と異なるAPIを選択したり、無関係な推論を行う。
CoTの思考プロセスで「ユーザー意図の特定」と「最適APIの選定」ステップを明確化。少数例で正しい関連付けを示す。
禁止事項違反
未定義パラメータの使用、NOT_APPLICABLE
ではないのに error_message
を含めるなど。
Systemプロンプトでの禁止事項の明示。「パラメータの抽出と確認」ステップで利用可能なパラメータのみ考慮するよう指示。
まとめ
CoTプロンプティングは、LLMに複雑な推論タスクの処理過程を明示させることで、単なるゼロショットや少数例プロンプトと比較して、推論の透明性と精度を向上させる。特に、Systemプロンプトによる厳格な制約、詳細な思考プロセスの指示、および評価に基づく継続的な改良が、高品質な出力を安定的に得る上で不可欠である。本アプローチにより、自然言語のビジネス要件からAPIコールへのマッピングといった複雑なタスクにおいて、LLMの信頼性と実用性を大幅に向上させることが可能となる。
graph TD
A["プロンプト設計"] --> B("LLMモデル")
B --> C{"出力"};
C --> D["評価シナリオ実行"];
D --> E{"自動評価ツール"};
E --> F{"評価結果"};
F -- 失敗モード特定 --> G["誤り分析"];
G --> H["プロンプト改良"];
H --> A;
F -- 成功 --> I["デプロイ"];
コメント