Build an AI Agent: Tool Calling, Execution Limits and Tests
Start with one read-only tool and a four-turn limit. Verify which actions the model requests, which actions your program allows, and how failures stop execution before adding memory or multiple agents.
This handbook begins with a Python exercise, then connects tool execution to MCP, RAG and evaluation. The public tutorials can be read without signing in; course access follows the course's own rules.
#What changes when a chatbot can use tools?
A tool-calling model can request lookup_order({"order_id":"DEMO-1001"}). The application validates the tool name and arguments, performs the lookup and returns the result to the model. The model then answers or requests another action.
The model proposes actions; your application controls execution. Never turn tool arguments into code through eval() or a shell.
textQuestion → model tool request → allowlist and argument checks ↓ Answer ← model reads observation ← data or explicit error ↓ Repeat only within the turn limit
#Run your first exercise
Open the Python tool-calling lab. Download tool_agent.py↗ and test_tool_agent.py↗ into one folder:
bashpython3 tool_agent.py python3 -m unittest -v test_tool_agent.py
Python 3.10+ is required; no third-party packages are needed. Default mode uses a scripted model substitute and a synthetic order, with no API calls or usage charges:
json{"mode": "fixture", "answer": "DEMO-1001: shipped (synthetic_fixture)", "steps": 2}
This verifies the execution loop, not LLM reasoning quality. The lab includes a separate live-model adapter and explains what remains unverified.
#Choose the smallest architecture that solves the task
| Task | Start with | Reason |
|---|---|---|
| Fixed steps and structured input | Program or workflow | No model is needed to choose the sequence |
| Answer from specified documents | RAG | The main challenge is finding evidence |
| Choose tools based on intermediate results | Bounded agent | Observations determine the next action |
| Independently specialised work | Consider multiple agents after a single-agent baseline | Handoffs add retries and conflict handling |
This is engineering guidance, not a requirement to replace stable workflows with agents.
#Four boundaries to explain before adding features
- Tool permissions: this exercise reads synthetic orders. It cannot refund, send messages or modify a database.
- Evidence: an unknown order produces
order_not_found, never an invented delivery status. - Limits: one tool call per turn, at most four turns; a live HTTP request has a 20-second timeout.
- Validation: offline tests check program behaviour. Live-model accuracy, cost and provider availability need separate checks.
#Practice review: validate tool calls before execution
JR Academy publishes this downloadable teaching example. Orders and model responses are scripted. The results below were reproduced locally on 2026-10-26; they demonstrate execution boundaries, not Lightman's commercial delivery or customer outcomes.
| Input or failure | Observed result | Design trade-off |
|---|---|---|
Call delete_order | unknown_tool | The model cannot add permissions beyond the registered lookup tool |
Look up missing order MISSING | order_not_found | Expose missing evidence rather than inventing a delivery status |
Pass only { as arguments | invalid_json | Return the parse error instead of guessing a repair |
Add delete: true to a lookup | invalid_arguments | Reject extra fields even when the tool name is allowed |
| A scripted model keeps calling tools, with a two-turn limit | step_limit_reached | Stop within the explicit budget; longer tasks need a deliberate budget change |
execute_tool checks the tool name, parses JSON, validates fields and types, then reads the order. run_agent accepts one tool call per turn and retains the call and observation. The single-call restriction sacrifices parallel throughput for a sequence that is easier to inspect and test in this introductory exercise.
The normal path completes in two steps with DEMO-1001: shipped (synthetic_fixture). Nine passing tests cover rejection paths, empty answers, multiple calls and model failures. Read the test receipt, exact outputs and source SHA-256 hashes. Compare the hashes with your downloaded Python files to check the version you run.
How this addition was produced: AI-assisted writing with locally executed Python tests. No live model was called. Production accuracy, concurrency performance and real business outcomes were not evaluated; specialist human review has not been registered.
#Where does MCP fit?
MCP connects an AI application with services that expose tools and context. It does not require one particular model or replace your application's authorisation rules. Continue with the MCP chapter after understanding tool execution. Official MCP architecture↗
#Your next step
- Run the tool-calling lab, then try a missing order.
- Explore RAG and check that answers map to evidence.
- Build an evaluation set from observed failures.
- Review the AI Engineer Bootcamp curriculum and trial information to assess the projects and prerequisites.
Technical references: OpenAI function calling↗, MCP architecture↗. Original guide check: 2026-09-07. Practice addition and offline regression: 2026-10-26, with nine passing tests. Exact outputs and source hashes are in the receipt above; live-model mode was not executed.