Tools in context (default)
All steps
"What would a 30-day refund on my $240 plan be?"
"Thanks, that helps!"
Parts of this pattern
- Question Input / output
- The customer's message, such as 'What would a 30-day refund on my $240 plan be?'.
- LLM LLM call
- Reads the system prompt, recalled notes and question, then answers or calls a tool.
- Retrieval Tool
- The search_docs tool: looks up help-center passages such as the refund policy.
- Calculator Tool
- The calculator tool: does exact arithmetic, like prorating a $240 plan, instead of the model guessing.
- Memory Memory
- Durable notes about this customer; save_note writes here and recall feeds them into later prompts.
- Answer Input / output
- The model's plain-language reply, sent once it needs no more tool calls.
- Question → LLM
- The question joins the system prompt, tool list and recalled notes in the model's messages.
What would a 30-day refund on my $240 plan be?
- LLM → Retrievalquery
- A search_docs tool call the model makes when it should not guess a policy.
search_docs(query="refund policy 30 days")
- Retrieval → LLMpassages
- Matching help-center passages are appended to the messages for the next model call.
Refund Policy: Annual plans cancelled within 30 days are refunded pro rata.
- LLM → Calculatorexpression
- An arithmetic expression the model hands off for exact evaluation.
calculator(expression="240*29/30")
- Calculator → LLMnumber
- The exact numeric result returns to the messages so the model can quote it.
calculator result: 232.00 (240*29/30)
- LLM → Memorysave_note
- A save_note tool call that stores a durable fact about the customer.
save_note(text="Customer is on the $240 annual plan")
- LLM → Answer
- A reply with no tool calls is the final answer, returned as plain text.
Your 30-day refund would be $232.00, based on the Refund Policy article.
Deferred tool search
Tool definitions stay out of the prompt. The model first searches a tool catalog, and only the schemas it finds are loaded.
All steps
Parts of this pattern
- Question Input / output
- The customer's message, such as 'What would a 30-day refund on my $240 plan be?'.
- LLM LLM call
- Starts with only the tool-search tool, finds the tool it needs, then calls it once its schema is loaded.
- Tool search Tool
- The one tool always in context: it matches a query against the descriptions of every tool in the catalog.
- Tool catalog Memory
- Every tool's name, description and full schema, kept outside the prompt until a search returns it.
- Refund quote Tool
- A catalog tool the model cannot call until a search loads its schema; it computes a prorated refund from the price and days used.
- Answer Input / output
- The model's plain-language reply, sent once it needs no more tool calls.
- Question → LLM
- The question arrives with only tool_search defined; the other tools' schemas are not in the context.
What would a 30-day refund on my $240 plan be?
- LLM → Tool searchfind tool
- The model searches for a tool that fits the job instead of guessing at one.
tool_search(query="prorated refund calculation")
- Tool search → Tool catalogmatch
- The search matches the query against the name and description of every tool in the catalog.
match 'prorated refund calculation' over 200 tool descriptions: top hit refund_quote
- Tool catalog → LLMschemas
- Only the matching tool definitions are loaded into the model's tool list for the rest of the request.
Loaded: refund_quote(plan_price: number, days_used: integer, term_days: integer)
- LLM → Refund quotecall
- With its schema loaded, the model calls the tool it found.
refund_quote(plan_price=240, days_used=1, term_days=30)
- Refund quote → LLMresult
- The tool's result is appended to the messages for the next model call.
{"refund": 232.00}
- LLM → Answer
- A reply with no tool calls is the final answer, returned as plain text.
Your 30-day refund would be $232.00.
Forced output tool
The model must call exactly one tool whose parameters are the output schema, so the reply is a structured record and there is no tool loop.
All steps
The email becomes a valid record
A field has the wrong type
Parts of this pattern
- Email Input / output
- Free text to turn into a record, such as a customer email asking for a refund on their annual plan.
- LLM LLM call
- Must call the one record tool; it reads the email and fills that tool's parameters, which form the output.
- Schema check Guard
- Plain code: validates the tool call's arguments against the record schema before anything uses them.
- Record Input / output
- The validated record, ready to store or pass to the next step.
- Rejected Input / output
- A rejection holding the validation errors and the raw arguments, for a repair step or a person.
- Email → LLM
- The text goes to the model with one tool definition and tool choice forced to that tool.
Hi, I cancelled my $240 annual plan yesterday. Can I get a refund? Dana
- LLM → Schema checktool call
- The model's single forced tool call. Its arguments are the record; the tool is never run.
record_request(intent="refund", plan_price=240, days_since_cancel=1, customer="Dana")
- Schema check → Recordvalid
- Arguments that match the schema are returned as the record.
{"intent": "refund", "plan_price": 240, "days_since_cancel": 1, "customer": "Dana"}
- Schema check → Rejectedinvalid
- Arguments that break the schema are rejected with the validation errors; this variant does not repair them.
plan_price: expected number, got "$240"
← → neighboursesc atlas
Augmented LLM
Also known as Tool use · Function calling · The building block
One LLM call that can use tools, retrieval and memory; every other pattern is built from this.
Tools in context: Popularized by Schluntz & Zhang (2024) · Anthropic
Anthropic named the augmented LLM as the building block of agentic systems in 2024. Earlier tool-using systems include MRKL (Karpas et al., AI21 Labs, 2022) and Toolformer (Schick et al., 2023).
Deferred tool search: Popularized by Anthropic (2025) · Anthropic
Anthropic's tool search tool, announced with its advanced tool use features in November 2025, for agents with hundreds of tools.
Forced output tool: No single inventor · see source
No single originator: forced tool choice is a model-API feature that developers adopted as a structured-output technique. The credit shown is for the augmented LLM it builds on.
Measured over one run
Tools in context
- Nodes
- 6. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 3. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 2. Messages sent to a tool node in the first scenario.
- Steps
- 5. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 2. Distinct example runs you can switch between on the diagram.
- Loop
- no. Whether the flow cycles back on itself until a condition is met.
- Parallel
- no. Whether two or more messages are in flight at the same time.
- Branch
- no. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- low. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- low. Relative token spend per request.
- Latency
- low. Relative wall-clock time per request.
Deferred tool search
- Nodes
- 6. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 3. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 2. Messages sent to a tool node in the first scenario.
- Steps
- 5. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 1. Distinct example runs you can switch between on the diagram.
- Loop
- no. Whether the flow cycles back on itself until a condition is met.
- Parallel
- no. Whether two or more messages are in flight at the same time.
- Branch
- no. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- low. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- low. Relative token spend per request.
- Latency
- low. Relative wall-clock time per request.
Forced output tool
- Nodes
- 5. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 1. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 0. Messages sent to a tool node in the first scenario.
- Steps
- 3. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 2. Distinct example runs you can switch between on the diagram.
- Loop
- no. Whether the flow cycles back on itself until a condition is met.
- Parallel
- no. Whether two or more messages are in flight at the same time.
- Branch
- yes. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- low. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- low. Relative token spend per request.
- Latency
- low. Relative wall-clock time per request.
Counted from the first scenario's timeline when the site is built.
Problem
A bare language model only knows what was in its training data and can only emit text. It cannot look up today’s refund policy, do exact arithmetic on a $240 invoice, or remember that this customer upgraded last month. Asked anyway, it guesses fluently, and a fluent guess about money or policy is worse than no answer.
How it works
The LLM receives the question together with a list of capabilities it may use. Anthropic calls this the augmented LLM: a model enhanced with retrieval, tools and memory, where the model itself generates its search queries, selects its tools and decides what to retain.
When a question needs facts, the model emits a structured call to the retrieval tool and receives matching passages. When it needs exact numbers, it calls the calculator. Each result is appended to the conversation, and the model is called again. It can call several tools in a row, or none. Once a reply contains no tool calls, that reply is the answer. Anything worth keeping, such as the customer’s plan, is written to memory through a save_note tool call, so it is available next time.
Your code only executes the tools the model asks for, including save_note, and feeds back what they return. The model never runs anything itself.
When to use
- A single request needs facts, calculations or actions the model cannot produce from its weights.
- You want the simplest thing that could work, and the task is bounded: a few tool calls, then an answer.
- You are starting a new system. Build this first, make the tool descriptions excellent, and only add pattern machinery when measurements demand it.
When to avoid
- The task has an open-ended number of steps whose order cannot be foreseen. That is the territory of a full agent loop such as ReAct.
- The tools are destructive and nothing stands between the model and the action.
Trade-offs
One call plus a handful of tool round trips keeps cost and latency low and behavior easy to debug. What you give up is planning: the model reacts to each result but has no persistent strategy. The main design effort moves into the tool interface. Clear names, narrow parameters and well-written descriptions matter more than any prompt trick, because the model decides which tool to call from those descriptions alone.
Failure modes
- Wrong tool, wrong arguments: the model calls search when it should calculate, or passes a malformed expression. Return readable error messages so it can correct itself.
- Skipping the lookup: the model answers a policy question from memory and sounds confident. Instruct it to search before asserting, and cite the source it used.
- Polluted memory: a one-off remark gets stored as a lasting fact. Be deliberate about what the write tool accepts.
Build it with your AI
Tools in context
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the Augmented LLM pattern in this codebase, using the LLM client and language we already use.
## Goal
Answer one request with a single model that can call tools (document search, a calculator, a note store) whenever it needs them, and return a plain-language answer once it needs no more.
## How it works
1. Load the user's saved notes from the memory store and fill them into the System prompt with tools; send it with the tool definitions and the user's message.
2. Read the model's reply. For each tool call in it, check the arguments against that tool's schema, run the tool, and append the result to the messages as a tool result.
3. If a tool call has bad arguments, fails or times out, append the error text as its tool result instead of raising, so the model can correct itself.
4. Write any fact passed to save_note to the memory store, keyed by user, so later conversations can recall it.
5. Call the model again with the extended messages, and repeat while its replies contain tool calls.
6. Return the text of the first reply that contains no tool calls as the answer.
## Prompts
### System prompt with tools
```markdown
You are a support assistant for {{company}}.
You can call these tools. Call one only when you need it:
- search_docs(query): search the {{company}} help center
- calculator(expression): exact arithmetic
- save_note(text): store a durable fact about this customer
Rules:
- Never guess a policy. If you are unsure, call search_docs first.
- Quote the document title when you rely on a search result.
- When you have enough information, answer in plain language.
Relevant notes from earlier conversations:
{{memory_notes}}
```
## Stop rule
Stop at the first reply with no tool calls, or after 5 tool rounds. At the cap, make one last call with tools disabled and return that answer, flagged as having hit the tool limit.
## Requirements
- Make the tool-round cap (default 5) and the per-tool timeout (default 10 seconds) parameters.
- Give every tool a one-line description that says when to use it; the model picks tools from these descriptions alone.
- Keep tools that change state (save_note) separate from read-only ones in configuration, so they can be audited or disabled.
- Log every model call and tool call with its arguments, result and token counts.
- Add a test with a stub LLM that first calls calculator("240*29/30") and then replies in plain text; assert the calculator ran exactly once, its result 232 is in the second call's messages, and the plain text is returned.
Deferred tool search
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the Augmented LLM pattern (Deferred tool search variant) in this codebase, using the LLM client and language we already use.
## Goal
Let one model use a large tool library without putting every tool definition in its prompt: it searches a catalog, and only the tools it finds are loaded for the rest of the request.
## How it works
1. Store every tool's name, one-line description and full schema in a catalog, indexed for keyword or embedding search.
2. Start each request with one tool defined, tool_search(query), and a system-prompt line telling the model to search for a tool before assuming none exists.
3. When the model calls tool_search, return the names and schemas of the top 3 matches, and add those schemas to the tool list for every later call in this request.
4. Run any loaded tool the model calls and append its result, or its error text, to the messages as a tool result.
5. Call the model again, and return the text of the first reply that contains no tool calls.
## Prompts
### System prompt with tools
```markdown
You are a support assistant for {{company}}.
You can call these tools. Call one only when you need it:
- search_docs(query): search the {{company}} help center
- calculator(expression): exact arithmetic
- save_note(text): store a durable fact about this customer
Rules:
- Never guess a policy. If you are unsure, call search_docs first.
- Quote the document title when you rely on a search result.
- When you have enough information, answer in plain language.
Relevant notes from earlier conversations:
{{memory_notes}}
```
## Stop rule
Stop at the first reply with no tool calls, or after 6 tool rounds, searches included. At the cap, make one last call with tools disabled and return that answer, flagged as having hit the limit.
## Requirements
- Make the schemas returned per search (default 3) and the round cap (default 6) parameters.
- If the model calls a tool that has not been loaded, return an error naming tool_search as the way to load it, and do not run it.
- Allow a short, configurable list of always-loaded tools for the ones most requests use (default: none).
- Log every search query with the tools it returned, so weak catalog descriptions show up.
- Add a test with a stub LLM, and the always-loaded list left empty, that calls tool_search("refund") and then refund_quote; assert the first call's tool list holds only tool_search and the second call's includes refund_quote.
Forced output tool
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the Augmented LLM pattern (Forced output tool variant) in this codebase, using the LLM client and language we already use.
## Goal
Turn free text into one record that matches a fixed schema by forcing the model to call a single tool whose parameters are that schema.
## How it works
1. Define one tool, record_request, whose parameter schema is the record you want: field names, types, allowed values and which fields are required.
2. Call the model once with the input text and that single tool, with tool choice forced to record_request, so it cannot reply in prose.
3. Take the arguments of the tool call as the record. Never execute the tool itself.
4. Validate the arguments against the schema. If they pass, return the record.
5. If they fail, return a rejection holding the validation errors and the raw arguments.
## Prompts
### System prompt with tools
```markdown
You are a support assistant for {{company}}.
You can call these tools. Call one only when you need it:
- search_docs(query): search the {{company}} help center
- calculator(expression): exact arithmetic
- save_note(text): store a durable fact about this customer
Rules:
- Never guess a policy. If you are unsure, call search_docs first.
- Quote the document title when you rely on a search result.
- When you have enough information, answer in plain language.
Relevant notes from earlier conversations:
{{memory_notes}}
```
## Stop rule
Stop after one model call: one forced tool call, one validation, then either a record or a rejection.
## Requirements
- Keep the schema in one place and generate both the tool definition and the validator from it.
- Treat a reply with no tool call, or with more than one, as a rejection with the reason 'no single tool call'.
- Describe every field in the schema; the model fills each field from its description.
- Leave repair out of this step: if rejections need fixing, add a separate repair step after it.
- Add a test with a stub LLM whose forced call sets plan_price to the string "$240"; assert the result is a rejection whose errors name plan_price and that the model was called exactly once.
Prompt templates
Tools in context · Deferred tool search · Forced output tool
You are a support assistant for {{company}}.
You can call these tools. Call one only when you need it:- search_docs(query): search the {{company}} help center- calculator(expression): exact arithmetic- save_note(text): store a durable fact about this customer
Rules:- Never guess a policy. If you are unsure, call search_docs first.- Quote the document title when you rely on a search result.- When you have enough information, answer in plain language.
Relevant notes from earlier conversations:{{memory_notes}}Related patterns
Composes well with:
Sources
From the Agentic Atlas by Joran Kikke · Edit on GitHub · Suggest a correction