AI Agents Fundamentals Basics
8 examples to get you started with AI agents - 5 basic and 3 intermediate.
Search across all documentation pages
8 examples to get you started with AI agents - 5 basic and 3 intermediate.
You will call a model, expose one tool, run a tiny decide-act-observe loop, and see when the model answers directly versus when it asks for a tool.
python -m venv .venv && source .venv/bin/activate
pip install openai pydantic
export OPENAI_API_KEY="sk-..."
# Optional: export OPENAI_BASE_URL="https://openrouter.ai/api/v1"Start with a plain completion so you can contrast it with a loop later.
from openai import OpenAI
client = OpenAI() # uses OPENAI_API_KEY; set base_url for gateways
resp = client.chat.completions.create(
model="gpt-4o-mini", # swap model id as needed; verify at build
messages=[{"role": "user", "content": "What is 17 * 24?"}],
)
print(resp.choices[0].message.content)Tools are named functions plus JSON schemas the model can request.
from pydantic import BaseModel, Field
class MultiplyArgs(BaseModel):
a: float = Field(description="First number")
b: float = Field(description="Second number")
tools = [{
"type": "function",
"function": {
"name": "multiply",
"description": "Multiply two numbers exactly. Use for arithmetic.",
"parameters": MultiplyArgs.model_json_schema(),
},
}]Pass tools into the chat call and inspect tool_calls.
messages = [{"role": "user", "content": "What is 17 * 24? Use the tool."}]
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=tools,
)
msg = resp.choices[0].message
print("content:", msg.content)
print("tool_calls:", msg.tool_calls)Agency requires closing the loop: run the function, return the result as a tool message.
import json
def multiply(a: float, b: float) -> float:
return a * b
REGISTRY = {"multiply": (MultiplyArgs, multiply)}
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = REGISTRY[call.function.name][0].model_validate_json(call.function.arguments)
result = REGISTRY[call.function.name][1](**args.model_dump())
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps({"result": result}),
})
final = client.chat.completions.create(model="gpt-4o-mini", messages=messages, tools=tools)
print(final.choices[0].message.content)Real agents repeat until done or until a hard stop.
def run_agent(user_text: str, max_turns: int = 5) -> str:
messages = [{"role": "user", "content": user_text}]
for _ in range(max_turns):
resp = client.chat.completions.create(
model="gpt-4o-mini", messages=messages, tools=tools
)
msg = resp.choices[0].message
if not msg.tool_calls:
return msg.content or ""
messages.append(msg)
for call in msg.tool_calls:
schema, fn = REGISTRY[call.function.name]
args = schema.model_validate_json(call.function.arguments)
out = fn(**args.model_dump())
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps({"result": out}),
})
return "stopped: max turns"
print(run_agent("Compute (17 * 24) + (3 * 9). Use tools for each product."))Related: Autonomy Levels
Compare a factual question that needs no tool with one that does.
print(run_agent("In one sentence, what is a tool call?"))
print(run_agent("What is 81 * 76?"))Failed tools should become data for the next turn, not process crashes.
def multiply(a: float, b: float) -> float:
if a > 1_000_000:
raise ValueError("a too large for this demo tool")
return a * b
# Inside the loop, wrap execution:
try:
out = fn(**args.model_dump())
payload = {"result": out}
except Exception as e:
payload = {"error": str(e)}Without a trace, agent debugging is guesswork.
trace = [] # append dicts: turn, tool, args, result/error
# After each tool execution:
trace.append({
"tool": call.function.name,
"args": args.model_dump(),
"observation": payload,
})
print(json.dumps(trace, indent=2))Stack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.
Reviewed by Chris St. John·Last updated Jul 16, 2026