s02
Tools
Tools & AusführungOne Handler Per Tool
120 LOC4 ToolsTool dispatch map
The loop stays the same; new tools register into the dispatch map
s01 > [ s02 ] s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12
"Ein Tool hinzufügen bedeutet einen Handler hinzufügen" -- die Schleife bleibt gleich; neue Tools registrieren sich in der Dispatch-Map.
Problem
Mit nur bash shellt der Agent alles aus. cat schneidet unvorhersehbar ab, sed scheitert an Sonderzeichen, und jeder bash-Aufruf ist eine unbeschränkte Sicherheitsoberfläche. Dedizierte Tools wie read_file und write_file ermöglichen das Durchsetzen von Path-Sandboxing auf Tool-Ebene.
Der wichtige insight: Tools hinzufügen erfordert nicht, die Schleife zu ändern.
Lösung
+--------+ +-------+ +------------------+
| User | ---> | LLM | ---> | Tool Dispatch |
| prompt | | | | { |
+--------+ +---+---+ | bash: run_bash |
^ | read: run_read |
| | write: run_wr |
+-----------+ edit: run_edit |
tool_result | } |
+------------------+
Die Dispatch-Map ist ein Dict: {tool_name: handler_function}.
Ein Lookup ersetzt jede if/elif-Kette.
Wie es funktioniert
- Jedes Tool erhält eine Handler-Funktion. Path-Sandboxing verhindert Workspace-Escape.
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]
- Die Dispatch-Map verbindet Tool-Namen mit Handlern.
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"]),
}
- In der Schleife, schlagen Sie den Handler nach Namen nach. Der Schleifenkörper selbst ist unverändert von 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,
})
Ein Tool hinzufügen = einen Handler hinzufügen + einen Schema-Eintrag hinzufügen. Die Schleife ändert sich nie.
Was sich von s01 geändert hat
| Komponente | Vorher (s01) | Nachher (s02) |
|---|---|---|
| Tools | 1 (nur bash) | 4 (bash, read, write, edit) |
| Dispatch | Hardcodierter bash-Aufruf | TOOL_HANDLERS dict |
| Path-Sicherheit | None | safe_path() Sandbox |
| Agent-Schleife | Unverändert | Unverändert |
Ausprobieren
python agents/s02_tool_use.py
Lesen Sie die Datei requirements.txtErstellen Sie eine Datei namens greet.py mit einer greet(name) FunktionBearbeiten Sie greet.py, um einen Docstring zur Funktion hinzuzufügenLesen Sie greet.py, um zu überprüfen, ob die Bearbeitung funktioniert hat
