Move Instruction to Tool Description is an AI refactoring for LLM systems, in the Composing prompts group. Move a tool's usage rule into its description, right where the model makes the choice.
The rules for when and how to use each tool live in the system prompt, far from the moment the model picks a tool, and it picks wrong. This is one symptom of Tool Sprawl.
Solution
Move each usage rule into the description of the tool it refers to: when to use it, when not to, what each parameter means, and what comes back. The system prompt keeps the general behavior.
Before and after
SYSTEM = """You are the support assistant.-To find customers, use find_customer ONLY with tax ID or email, never with a name.-Before cancel_order, ALWAYS confirm the reason with the customer.-Use get_invoice only for invoices from the last 12 months; for older ones,-point the customer to the portal.-NEVER call refund without first calling get_order to check the status."""+SYSTEM = "You are the support assistant. Be direct and confirm actions before running them." TOOLS = [- tool("find_customer", "Finds a customer.", {"query": str}),+ tool("find_customer",+ "Finds a customer by tax ID or email (never by name, which is ambiguous). "+ "Use it before any order or invoice lookup.",+ {"by": "tax_id" | "email", "value": str}),- tool("get_invoice", "Gets an invoice.", {"id": str}),+ tool("get_invoice",+ "Returns an invoice from the last 12 months. For older invoices, it "+ "returns an error with the portal link, which should be passed on to the customer.",+ {"invoice_id": str}),- tool("refund", "Refunds.", {"order_id": str}),+ tool("refund",+ "Refunds a delivered order. Requires get_order to have been called in the "+ "same conversation; the system rejects refunds without that lookup.",+ {"order_id": str, "reason": str}), ]
Before: the rules sit in the prompt, far from the tools.
flowchart LR
S[("1. System prompt with tool rules")]:::store --> M(["2. Model chooses"]):::llm
T["Tools with vague descriptions"]:::tool --> M
M --> X(["3. Wrong choice now and then"]):::io
After: each rule lives in the tool, and the critical ones in code too.
flowchart LR
S[("1. Short system prompt")]:::store --> M(["2. Model chooses"]):::llm
T["Tools with full descriptions"]:::tool --> M
M --> V["3. Tool enforces its own rules"]:::tool
V --> OUT(["4. Right choice, or an explanatory error"]):::io
The system prompt keeps the general behavior.
The model reads name, description, and parameters at the moment of choosing.
The tool enforces in code the rules that cannot fail.
If the model gets it wrong, it receives an error that explains why and what to do.
Why it works
The model decides which tool to call by looking at the tool list. The description is read at exactly that moment, next to the name and parameters. A rule in the system prompt, thousands of tokens away, competes with everything in between.
Complete descriptions also make tools portable: if another agent uses the same tool, or it gets exposed through MCP, the rules travel with it.
And rules that cannot fail get a second layer: the tool rejects the improper call and returns a useful error. The prompt guides; code guarantees.
Safe mechanics
Measure. Run the eval and count wrong tool choices and calls with invalid arguments.
Find the tool rules in the prompt. Every sentence that names a tool is a candidate.
Rewrite each tool’s description with: what it does, when to use it, when not to, what each parameter means, and what comes back.
Use the schema for whatever it can express: enums, formats, required fields.
Enforce critical rules in code and return errors that teach the model how to correct itself.
Remove the rules from the prompt.
Measure again. Fewer wrong choices and fewer invalid arguments.
Risks
Descriptions that are too long. Many tools with huge descriptions add up. Be specific and brief.
General rules that get lost. A rule that applies to several tools (“confirm before any action with side effects”) can stay in the system prompt.
A description that contradicts the code. If the description says one thing and validation does another, the model gets confused. Keep both together in code.
If the description of refund says the system rejects refunds without a prior lookup, that check has to exist in code. Otherwise the sentence is an empty threat: most conversations the model obeys, and the one where the customer insists goes through.
Challenge
Rewrite this tool’s description from the rules that were in the prompt.
Tool: schedule_visit(date, address) "Schedules a technician visit."Rules in the prompt: visits only on business days; only for addresses witha São Paulo ZIP code; the customer must have an open ticket; dates in YYYY-MM-DD format.
Show solution
schedule_visit(ticket_id, date, zip) Schedules a technician visit for an open ticket. Only serves ZIP codes in the city of São Paulo (01000-000 to 05999-999) and business days. If the date falls on a weekend or holiday, it returns an error with the next three available dates. ticket_id: the customer's open ticket number. date: date in YYYY-MM-DD format. zip: digits only.
The tool’s code checks the ZIP code, the business day, and the open ticket, and returns explanatory errors.
Check your understanding
Quick answers
What is Move Instruction to Tool Description?
Move Instruction to Tool Description is an AI refactoring for LLM systems, in the Composing prompts group. Move a tool's usage rule into its description, right where the model makes the choice.
What problem does Move Instruction to Tool Description solve?