Design deterministic tool-description routing contracts with explicit input formats, examples, reciprocal boundaries, overload split decisions, Grep then Read then Edit repository strategy, Edit failure fallback, and offline validation.
Design each tool description as a deterministic routing contract a planner can act on with zero hidden context. The contract fixes: purpose, input format, output shape, 1–2 examples, reciprocal boundary, overload split decision, Grep → Read → Edit repo strategy, and Edit fallback when the anchor is not unique. [DOC]
The unit of value is decisión inmediata: given the description alone, the model picks the right tool without guessing or asking. [INFERENCIA]
Activa cuando se cumpla al menos una: [DOC]
"Analyzes content") no dice qué entrada espera ni dónde está su frontera.read-all masivo.Edit falla de forma intermitente (anchor no único) y no hay fallback documentado.Anti-scope — NO actives para: redactar correos/prosa, ejecutar un único comando de shell, o tareas sin decisión de routing entre ≥2 tools. Esos casos son falsos positivos (ver evals.json: false_positive_client_email, false_positive_single_shell_command). [CONFIG]
Edit: old_string debe ser único; si no, Edit falla. Declara el fallback Read+Write (reescritura total) cuando el anchor no se puede aislar. [CÓDIGO]Grep → Read → Edit: localizar con Grep/Glob, leer solo lo relevante con Read, mutar con Edit. Nunca Glob("**/*") + Read all upfront. [DOC]Grep → Read selectivo vs. read-all upfront: selectivo gana. read-all parece "más seguro" (todo el contexto) pero satura la ventana (~200k tokens en repos medianos) y degrada el reasoning. Carga solo lo que un hit de Grep justifique. [SUPUESTO] — confirmar midiendo tokens en el repo objetivo antes de adoptar read-all.Nunca: [DOC]
"analyzes content", "processes files").Glob("**/*") + read-all como estrategia de discovery upfront.Edit ambiguo como seguro sin fallback.references/verification-tags.md). [CONFIG]Referencia las policies del kit cuando existan: assets/description-contract-policy.json, assets/boundary-policy.json, assets/repo-strategy-policy.json, assets/edit-safety-policy.json, assets/anti-pattern-policy.json, y el contrato assets/tool-use-contract.json. [SUPUESTO] — estos assets son prescritos por esta skill; si faltan, créalos antes de validar (ver evals.json: upgrade_safety_case).
# GOOD — descripciones como contrato con frontera recíproca + estrategia Grep→Read→Edit
TOOLS = [
{
"name": "search_code",
"description": (
"Find files or symbols by pattern across the repo. "
"Input: a regex or literal string. Returns matching paths + line numbers. "
"Use this FIRST to locate. To read a known file's contents, use read_file instead."
),
},
{
"name": "read_file",
"description": (
"Read the full contents of ONE known file path. "
"Input: an absolute path. Use after search_code has located the file. "
"Do NOT use to discover files — that is search_code's job."
),
},
{
"name": "edit_file",
"description": (
"Replace an exact, UNIQUE anchor string in a file. "
"Input: path, old_string (must be unique), new_string. "
"FAILS if old_string is not unique. Fallback: read_file then write_file for a full rewrite."
),
},
]
# Workflow the descriptions enforce: locate cheaply, read selectively, mutate precisely.
hits = search_code(pattern="def handle_payment") # Grep
src = read_file(path=hits[0].path) # Read only the relevant file
edit_file(path=hits[0].path, old_string=unique_anchor, new_string=patched) # Edit# ANTI — descripciones genéricas + read masivo upfront
TOOLS = [
{"name": "analyze", "description": "Analyzes content."}, # no input, no frontera
{"name": "process", "description": "Processes the file."}, # solapa con analyze
]
# El agente, sin frontera, no sabe cuál elegir → pide aclaración o adivina.
# Y para "entender el repo" carga todo en contexto:
all_files = glob("**/*")
context = "".join(read_file(p) for p in all_files) # ~200k tokens, satura la ventana
# Edit sin fallback documentado: si el anchor no es único, falla en silencio.old_string; expande el anchor con contexto adyacente o cae a Write full-rewrite. [CÓDIGO]Un report válido cumple todo lo siguiente (verificable offline, sin red): [DOC]
rename_split cuando un tool tiene >1 responsabilidad.grep, read, edit.read_all_upfront=false y glob_all_then_read_all=false.unique_anchor_required=true y fallback read_write_full_rewrite.offline=true, network_required=false, deterministic=true.Ejecuta (cuando los scripts existan en el kit): [SUPUESTO]
python3 skills/tool-use-design/scripts/validate_tool_use_design.py --input <report.json>
bash skills/tool-use-design/scripts/check.shEl validador es offline y rechaza: descripciones genéricas, ejemplos faltantes, fronteras no recíprocas, overload sin resolver, read-all upfront, fallback de Edit ausente, y flags de validación no deterministas. [DOC]
Edit (anchor no único) y su fallback Read+Write? [CÓDIGO]Grep → Read → Edit, sin Glob("**/*") + Read all upfront? [DOC]katas-21, katas-23.katas-tool-description-quality, katas-builtin-tool-selection.fdad39c
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.