mirror of
https://github.com/shareAI-lab/analysis_claude_code.git
synced 2026-09-21 21:03:38 +08:00
Fix empty tool-use response handling
This commit is contained in:
@@ -21,7 +21,7 @@ s01 の Agent には bash 一つのツールしかない。ファイルを読む
|
||||
|
||||

|
||||
|
||||
s01 のループは完全に保持される(LLM 呼び出し、stop_reason 判定、メッセージ追加 — 一文字も変更なし)。唯一の変更点はツール実行の 1 行:`run_bash()` が `TOOL_HANDLERS[block.name]()` の検索ディスパッチに置き換わる。
|
||||
s01 のループは完全に保持される(LLM 呼び出し、`tool_use` block 判定、メッセージ追加 — 一文字も変更なし)。唯一の変更点はツール実行の 1 行:`run_bash()` が `TOOL_HANDLERS[block.name]()` の検索ディスパッチに置き換わる。
|
||||
|
||||
Agent にツールを追加するには、たった二つ:
|
||||
|
||||
@@ -91,11 +91,10 @@ TOOL_HANDLERS = {
|
||||
}
|
||||
|
||||
# ループ内で変更されたのは一行だけ — ハードコードの run_bash から検索ディスパッチへ:
|
||||
for block in response.content:
|
||||
if block.type == "tool_use":
|
||||
handler = TOOL_HANDLERS[block.name] # 検索
|
||||
output = handler(**block.input) # 呼び出し
|
||||
results.append(...)
|
||||
for block in tool_calls:
|
||||
handler = TOOL_HANDLERS[block.name] # 検索
|
||||
output = handler(**block.input) # 呼び出し
|
||||
results.append(...)
|
||||
```
|
||||
|
||||
ツールの追加 = `TOOLS` 配列に一条 + `TOOL_HANDLERS` 辞書に一行。ループは変わらない。
|
||||
@@ -128,7 +127,7 @@ for block in response.content:
|
||||
| ツール数 | 1 (bash) | 5 (+read, write, edit, glob) |
|
||||
| ツール実行 | ハードコード `run_bash()` | TOOL_HANDLERS 検索ディスパッチ |
|
||||
| パス安全性 | なし | safe_path 検証(file tools のみ) |
|
||||
| ループ | `while True` + `stop_reason` | s01 と完全に同一 |
|
||||
| ループ | `while True` + `tool_use` block | s01 と完全に同一 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ The model thinks "read this file" but has to spell out `cat path/to/file`. An ex
|
||||
|
||||

|
||||
|
||||
The s01 loop is fully preserved (LLM call, stop_reason check, message append — not a single word changed). The only change is in that one line of tool execution: `run_bash()` is replaced with `TOOL_HANDLERS[block.name]()` dispatch lookup.
|
||||
The s01 loop is fully preserved (LLM call, `tool_use` block check, message append — not a single word changed). The only change is in that one line of tool execution: `run_bash()` is replaced with `TOOL_HANDLERS[block.name]()` dispatch lookup.
|
||||
|
||||
Adding a tool to the Agent requires just two things:
|
||||
|
||||
@@ -91,11 +91,10 @@ TOOL_HANDLERS = {
|
||||
}
|
||||
|
||||
# Only one line changed in the loop — from hardcoded run_bash to dispatch lookup:
|
||||
for block in response.content:
|
||||
if block.type == "tool_use":
|
||||
handler = TOOL_HANDLERS[block.name] # lookup
|
||||
output = handler(**block.input) # call
|
||||
results.append(...)
|
||||
for block in tool_calls:
|
||||
handler = TOOL_HANDLERS[block.name] # lookup
|
||||
output = handler(**block.input) # call
|
||||
results.append(...)
|
||||
```
|
||||
|
||||
Adding a tool = one entry in `TOOLS` array + one line in `TOOL_HANDLERS` dict. The loop stays the same.
|
||||
@@ -128,7 +127,7 @@ Calls are executed one by one in their original `response.content` order.
|
||||
| Tool count | 1 (bash) | 5 (+read, write, edit, glob) |
|
||||
| Tool execution | Hardcoded `run_bash()` | TOOL_HANDLERS dispatch lookup |
|
||||
| Path safety | None | safe_path validation (file tools only) |
|
||||
| Loop | `while True` + `stop_reason` | Identical to s01 |
|
||||
| Loop | `while True` + `tool_use` block | Identical to s01 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ s01 的 Agent 只有一个 bash 工具。读文件要 `cat`,写文件要 `echo
|
||||
|
||||

|
||||
|
||||
s01 的循环完全保留(LLM 调用、stop_reason 判断、消息追加)。唯一的变动在工具执行那 1 行:`run_bash()` 替换为 `TOOL_HANDLERS[block.name]()` 查表分发。
|
||||
s01 的循环完全保留(LLM 调用、`tool_use` block 判断、消息追加)。唯一的变动在工具执行那 1 行:`run_bash()` 替换为 `TOOL_HANDLERS[block.name]()` 查表分发。
|
||||
|
||||
给 Agent 加一个工具只需要做两件事:
|
||||
|
||||
@@ -91,11 +91,10 @@ TOOL_HANDLERS = {
|
||||
}
|
||||
|
||||
# 循环里只改了一行——从硬编码 run_bash 变成查表:
|
||||
for block in response.content:
|
||||
if block.type == "tool_use":
|
||||
handler = TOOL_HANDLERS[block.name] # 查表
|
||||
output = handler(**block.input) # 调用
|
||||
results.append(...)
|
||||
for block in tool_calls:
|
||||
handler = TOOL_HANDLERS[block.name] # 查表
|
||||
output = handler(**block.input) # 调用
|
||||
results.append(...)
|
||||
```
|
||||
|
||||
加一个工具 = 在 `TOOLS` 数组加一条 + 在 `TOOL_HANDLERS` 字典加一行。循环不变。
|
||||
@@ -128,7 +127,7 @@ for block in response.content:
|
||||
| 工具数量 | 1 (bash) | 5 (+read, write, edit, glob) |
|
||||
| 工具执行 | 硬编码 `run_bash()` | TOOL_HANDLERS 查表分发 |
|
||||
| 路径安全 | 无 | safe_path 校验(仅 file tools) |
|
||||
| 循环 | `while True` + `stop_reason` | 与 s01 完全一致 |
|
||||
| 循环 | `while True` + `tool_use` block | 与 s01 完全一致 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -154,17 +154,19 @@ def agent_loop(messages: list):
|
||||
)
|
||||
messages.append({"role": "assistant", "content": response.content})
|
||||
|
||||
if response.stop_reason != "tool_use":
|
||||
tool_calls = [
|
||||
block for block in response.content if block.type == "tool_use"
|
||||
]
|
||||
if not tool_calls:
|
||||
return
|
||||
|
||||
results = []
|
||||
for block in response.content:
|
||||
if block.type == "tool_use":
|
||||
print(f"\033[33m> {block.name}\033[0m")
|
||||
handler = TOOL_HANDLERS.get(block.name)
|
||||
output = handler(**block.input) if handler else f"Unknown: {block.name}"
|
||||
print(str(output)[:200])
|
||||
results.append({"type": "tool_result", "tool_use_id": block.id, "content": output})
|
||||
for block in tool_calls:
|
||||
print(f"\033[33m> {block.name}\033[0m")
|
||||
handler = TOOL_HANDLERS.get(block.name)
|
||||
output = handler(**block.input) if handler else f"Unknown: {block.name}"
|
||||
print(str(output)[:200])
|
||||
results.append({"type": "tool_result", "tool_use_id": block.id, "content": output})
|
||||
|
||||
messages.append({"role": "user", "content": results})
|
||||
|
||||
|
||||
@@ -40,14 +40,14 @@
|
||||
<!-- LLM -->
|
||||
<rect x="270" y="82" width="150" height="52" rx="8" fill="#fff" stroke="#2563eb" stroke-width="1.5"/>
|
||||
<text x="345" y="104" fill="#1e3a5f" font-size="13" font-weight="700" text-anchor="middle">LLM</text>
|
||||
<text x="345" y="122" fill="#64748b" font-size="10" text-anchor="middle">stop_reason check</text>
|
||||
<text x="345" y="122" fill="#64748b" font-size="10" text-anchor="middle">tool_use block check</text>
|
||||
|
||||
<!-- Arrow: LLM → Decision -->
|
||||
<line x1="345" y1="134" x2="345" y2="162" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Decision Diamond -->
|
||||
<polygon points="345,166 415,196 345,226 275,196" fill="#fff8f0" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="345" y="194" fill="#92400e" font-size="10" font-weight="600" text-anchor="middle">tool_use?</text>
|
||||
<text x="345" y="194" fill="#92400e" font-size="10" font-weight="600" text-anchor="middle">tool_use block?</text>
|
||||
|
||||
<!-- No → Return -->
|
||||
<line x1="415" y1="196" x2="475" y2="196" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
@@ -40,14 +40,14 @@
|
||||
<!-- LLM -->
|
||||
<rect x="270" y="82" width="150" height="52" rx="8" fill="#fff" stroke="#2563eb" stroke-width="1.5"/>
|
||||
<text x="345" y="104" fill="#1e3a5f" font-size="13" font-weight="700" text-anchor="middle">LLM</text>
|
||||
<text x="345" y="122" fill="#64748b" font-size="10" text-anchor="middle">stop_reason 判定</text>
|
||||
<text x="345" y="122" fill="#64748b" font-size="10" text-anchor="middle">tool_use block 判定</text>
|
||||
|
||||
<!-- 矢印:LLM → 判定 -->
|
||||
<line x1="345" y1="134" x2="345" y2="162" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- 判定ダイヤモンド -->
|
||||
<polygon points="345,166 415,196 345,226 275,196" fill="#fff8f0" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="345" y="194" fill="#92400e" font-size="10" font-weight="600" text-anchor="middle">tool_use?</text>
|
||||
<text x="345" y="194" fill="#92400e" font-size="10" font-weight="600" text-anchor="middle">tool_use block?</text>
|
||||
|
||||
<!-- いいえ → 返却 -->
|
||||
<line x1="415" y1="196" x2="475" y2="196" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
@@ -40,14 +40,14 @@
|
||||
<!-- LLM -->
|
||||
<rect x="270" y="82" width="150" height="52" rx="8" fill="#fff" stroke="#2563eb" stroke-width="1.5"/>
|
||||
<text x="345" y="104" fill="#1e3a5f" font-size="13" font-weight="700" text-anchor="middle">大模型 (LLM)</text>
|
||||
<text x="345" y="122" fill="#64748b" font-size="10" text-anchor="middle">stop_reason 判断</text>
|
||||
<text x="345" y="122" fill="#64748b" font-size="10" text-anchor="middle">检查 tool_use block</text>
|
||||
|
||||
<!-- 箭头:LLM → 判断 -->
|
||||
<line x1="345" y1="134" x2="345" y2="162" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- 判断菱形 -->
|
||||
<polygon points="345,166 415,196 345,226 275,196" fill="#fff8f0" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="345" y="194" fill="#92400e" font-size="10" font-weight="600" text-anchor="middle">tool_use?</text>
|
||||
<text x="345" y="194" fill="#92400e" font-size="10" font-weight="600" text-anchor="middle">tool_use block?</text>
|
||||
|
||||
<!-- 否 → 返回 -->
|
||||
<line x1="415" y1="196" x2="475" y2="196" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
Reference in New Issue
Block a user