
The Art of the Prompt: Writing Tools Models Understand
Engineer the perfect interface for your agent. Learn how to write tool names, descriptions, and schemas that maximize LLM accuracy and minimize tool calling errors.
Writing Tools That Models Understand
In Module 4.2, we learned the basics of tool abstraction. Now, we enter Tool Engineering. The performance of an agent is often determined not by the size of the model, but by the Quality of its Tool Definitions. If a model finds a tool description confusing, it will fail to call it, call it with the wrong arguments, or hallucinate a completely different tool.
In this lesson, we will learn the industry secrets for making your tools "Un-hackable" and "Un-confusable."
1. The Strategy of "Semantic Distinctness"
Models struggle when two tools sound similar.
- Tool 1:
search_users(searches for people). - Tool 2:
lookup_customers(searches for people who have bought something).
The Problem: The model won't know which one to pick for a query like "Find John Smith."
The Solution: Merge similar tools and use a Parameter instead.
- Merged Tool:
search_person(type: "user" | "customer"). - Why? It forces the model to choose the "Category" within a single logical branch, reducing ambiguity.
2. The Power of "Negative Constraints"
A tool description should say what it does NOT do.
Description: "Use this tool to delete a file. DO NOT use this tool if you just want to clear the content of a file; use 'clear_file' for that. This tool is destructive and will remove the file from the disk permanently."
3. Describing the "Output Flavor"
The LLM needs to know what it will get back from the tool so it can plan its next move.
Tool Description: "Returns a JSON list of products. If no products are found, it returns an empty list
[], not an error. You should check for the length of this list before proceeding to the 'Analysis' step."
Why? This prevents the model from panicking if it sees an empty list.
4. The "Docstring" as a Secret Weapon
In LangChain, the tool description is often pulled directly from your Python function's docstring. You must treat your docstrings as Prompts, not just documentation.
The "Bad" Docstring
def get_weather(city: str):
"""Gets the weather."""
pass
The "Agent-First" Docstring
def get_weather(city: str):
"""
Retrieves the current weather and 3-day forecast for a specific city.
- Input 'city' must be the full name (e.g., 'San Francisco', not 'SF').
- Returns a dict with 'temp', 'humidity', and 'condition'.
- Use this whenever the user mentions outdoors, clothing, or travel.
"""
pass
5. Parameter Level Instruction
If a tool has a complex parameter (like a query for a vector DB), give instructions inside the parameter definition.
class SearchInput(BaseModel):
query: str = Field(
description="The semantic query. Convert user slang into professional technical terms for better results (e.g., 'slow internet' -> 'latency issues')."
)
6. Testing Tool Clarity with "Blind Extraction"
How do you know if your tool description is good?
- Take your tool name and description.
- Give it to a human (or a separate LLM) who hasn't seen your code.
- Give them a user query.
- If they have to ask any clarifying questions about which tool to use, your description is not precise enough.
Summary and Mental Model
Think of a Tool Definition like a Boutique Shop Sign.
- If the sign just says "Food," customers are confused.
- If the sign says "Italian Pasta - No Takeout - Cash Only," the customers know exactly what to expect before they walk in.
Your tool description is the "Sign" that tells the LLM what's inside the shop.
Exercise: Tool Refinement
- Refining: You have a tool called
send_notification(type, msg).- Rewrite the description to ensure the agent uses
type='email'for important alerts andtype='slack'for casual updates.
- Rewrite the description to ensure the agent uses
- Ambiguity: You have
search_historical_dataandsearch_current_trends.- What is a query a user might send that would confuse these?
- How would you modify the descriptions to separate them by "Date Ranges"?
- The Schema: Add a "Negative Constraint" to the schema of a
delete_databasetool so it only allows deleting databases with the prefixdev_. Ready for complex inputs? Let's move to Lesson 2.