Setup prompt
lookup_person, backed by the Forager person lookup. The model decides when to call it, your server runs the call, and the model gets back a short JSON summary instead of the full record. The schema is plain JSON Schema, so it fits any provider’s function-calling or tool-use API; only the wrapper object around it differs. It is written for the REST API with your API key; Forager does not provide a hosted tool server.
How it fits together
- Your server sends the conversation plus the tool definition to the model.
- The model answers with a tool call:
lookup_personand its arguments. - Your executor validates the arguments, checks the cache and the credit budget, calls Forager, and trims the record.
- The trimmed result goes back to the model as the tool result; the model writes the answer.
1
Define the tool
One tool, two ways to identify a person. The description tells the model what the call costs so it does not look people up on a whim. Rename the wrapper keys (The request body of the endpoint has the same two optional fields, so the arguments can be forwarded as they are once you have checked that exactly one of them is present.
parameters is input_schema in some APIs) to match your provider.lookup_person tool definition
2
Write the executor
The executor is the only code that talks to Forager. It keeps a per-conversation budget (1 credit per call here), caches by identifier so a repeated question is free, treats What the model sees for a hit, with fictional values:
403 as fatal, and returns 429 and not-found as data the model can act on.Tool result (illustrative)
3
Run the tool loop
call_model is the one function you write around your provider’s API. It takes the messages and the tool list and returns the reply text plus any tool calls, each with an id, a name and parsed arguments. The loop below is the same for every provider; only the two messages.append lines use provider-specific shapes.agent.py
ForagerAuthError propagates out of run(): it is a deployment problem, and the model should never be asked to work around it.4
Add a system prompt line
Tell the model how to treat the tool so it asks for a handle instead of guessing one:
System prompt fragment
Test it without a model or credits
- Replace
call_modelwith a fake that returns onelookup_personcall, then a final text reply, and assert the loop sends the tool result back. - Stub the HTTP layer: a
200with a sample record checkstrim(), a second identical call checks the cache (no second HTTP request), a429then200checks the retry, a403checks thatForagerAuthErrorescapes. - Assert
budget_exhaustedafterMAX_CREDITS_PER_CONVERSATIONworth of distinct lookups.
Extend it
- Add a second tool for contact data only when the product needs it: a phone number lookup costs 15 credits, so give it its own, smaller budget and a description that says so. The agent tool calling recipe shows a two-tool setup with people search and phone numbers.
- For “who is the Head of Data at acme.com” questions, add a people search tool and have the model pass the
person.idit returns intolookup_person. - Log every tool call with its arguments and credits, and show the running total to the user.
Related
Agent tool calling recipe
Two tools, search then phone lookup, with the same loop.
Build with AI agents
The OpenAPI spec, llms.txt and the Forager API skill.
Person lookup reference
Every field in the person record.
Credit pricing
What each call costs.