mirror of
https://github.com/shareAI-lab/analysis_claude_code.git
synced 2026-03-22 02:15:42 +08:00
Comprehensive rewrite establishing the harness engineering narrative across the entire repository. README (EN/ZH/JA): added "The Model IS the Agent" manifesto with historical proof (DQN, OpenAI Five, AlphaStar, Tencent Jueyu), "What an Agent Is NOT" critique, harness engineer role definition, "Why Claude Code" as masterclass in harness design, and universe vision. Consistent framing: model = driver, harness = vehicle. docs (36 files, 3 languages): injected one-line "Harness layer" callout after the motto in every session document (s01-s12). agents (13 Python files): added harness framing comment before each module docstring. skills/agent-philosophy.md: full rewrite aligned with harness narrative.
3.6 KiB
3.6 KiB
s02: Tool Use
s01 > [ s02 ] s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12
"ツールを足すなら、ハンドラーを1つ足すだけ" -- ループは変わらない。新ツールは dispatch map に登録するだけ。
Harness 層: ツール分配 -- モデルが届く範囲を広げる。
問題
bashだけでは、エージェントは何でもシェル経由で行う。catは予測不能に切り詰め、sedは特殊文字で壊れ、すべてのbash呼び出しが制約のないセキュリティ面になる。read_fileやwrite_fileのような専用ツールなら、ツールレベルでパスのサンドボックス化を強制できる。
重要な点: ツールを追加してもループの変更は不要。
解決策
+--------+ +-------+ +------------------+
| User | ---> | LLM | ---> | Tool Dispatch |
| prompt | | | | { |
+--------+ +---+---+ | bash: run_bash |
^ | read: run_read |
| | write: run_wr |
+-----------+ edit: run_edit |
tool_result | } |
+------------------+
The dispatch map is a dict: {tool_name: handler_function}.
One lookup replaces any if/elif chain.
仕組み
- 各ツールにハンドラ関数を定義する。パスのサンドボックス化でワークスペース外への脱出を防ぐ。
def safe_path(p: str) -> Path:
path = (WORKDIR / p).resolve()
if not path.is_relative_to(WORKDIR):
raise ValueError(f"Path escapes workspace: {p}")
return path
def run_read(path: str, limit: int = None) -> str:
text = safe_path(path).read_text()
lines = text.splitlines()
if limit and limit < len(lines):
lines = lines[:limit]
return "\n".join(lines)[:50000]
- ディスパッチマップがツール名とハンドラを結びつける。
TOOL_HANDLERS = {
"bash": lambda **kw: run_bash(kw["command"]),
"read_file": lambda **kw: run_read(kw["path"], kw.get("limit")),
"write_file": lambda **kw: run_write(kw["path"], kw["content"]),
"edit_file": lambda **kw: run_edit(kw["path"], kw["old_text"],
kw["new_text"]),
}
- ループ内で名前によりハンドラをルックアップする。ループ本体はs01から不変。
for block in response.content:
if block.type == "tool_use":
handler = TOOL_HANDLERS.get(block.name)
output = handler(**block.input) if handler \
else f"Unknown tool: {block.name}"
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": output,
})
ツール追加 = ハンドラ追加 + スキーマ追加。ループは決して変わらない。
s01からの変更点
| Component | Before (s01) | After (s02) |
|---|---|---|
| Tools | 1 (bash only) | 4 (bash, read, write, edit) |
| Dispatch | Hardcoded bash call | TOOL_HANDLERS dict |
| Path safety | None | safe_path() sandbox |
| Agent loop | Unchanged | Unchanged |
試してみる
cd learn-claude-code
python agents/s02_tool_use.py
Read the file requirements.txtCreate a file called greet.py with a greet(name) functionEdit greet.py to add a docstring to the functionRead greet.py to verify the edit worked