AI agents — LLMs that can use tools and take actions — are the hottest topic in AI. Here's how to build ones that are reliable, not just impressive demos.
What Is an AI Agent?
An agent is an LLM in a loop: observe, think, act, repeat.
def agent_loop(task: str, tools: dict, max_steps: int = 10):
messages = [
{"role": "system", "content": f"You have these tools: {list(tools.keys())}"},
{"role": "user", "content": task}
]
for step in range(max_steps):
response = call_llm(messages, tools=tools)
if response.tool_calls:
for call in response.tool_calls:
result = tools[call.function.name](**call.arguments)
messages.append({"role": "tool", "content": str(result), "tool_call_id": call.id})
else:
return response.content
return "Max steps reached"
Building Tools
import json, subprocess, requests
def search_web(query: str) -> str:
response = requests.get("https://api.search.com/search", params={"q": query, "limit": 5})
return json.dumps(response.json()["results"])
def run_python(code: str) -> str:
try:
result = subprocess.run(["python3", "-c", code], capture_output=True, text=True, timeout=30)
return result.stdout or result.stderr
except subprocess.TimeoutExpired:
return "Error: Code execution timed out"
def read_file(path: str) -> str:
try:
with open(path) as f:
return f.read()
except FileNotFoundError:
return f"Error: File {path} not found"
OpenAI Function Calling
from openai import OpenAI
client = OpenAI()
tools_schema = [{
"type": "function",
"function": {
"name": "search_web",
"description": "Search the web for information",
"parameters": {
"type": "object",
"properties": {"query": {"type": "string", "description": "Search query"}},
"required": ["query"]
}
}
}]
response = client.chat.completions.create(model="gpt-4", messages=messages, tools=tools_schema, tool_choice="auto")
The ReAct Pattern
Reasoning + Acting — the most reliable agent pattern:
Thought: I need to find the current Python version
Action: run_python("import sys; print(sys.version)")
Observation: 3.11.5 (main, Sep 11 2023)
Thought: I have the answer
Final Answer: The current Python version is 3.11.5
Guardrails
def safe_agent(task: str, tools: dict):
if len(task) > 10000:
return "Task too long"
MAX_TOOL_OUTPUT = 5000
total_tokens = 0
MAX_TOKENS = 50000
for step in range(10):
response = call_llm(messages, tools=tools)
total_tokens += response.usage.total_tokens
if total_tokens > MAX_TOKENS:
return "Token budget exceeded"
if response.tool_calls:
for call in response.tool_calls:
if call.function.name not in tools:
continue
result = tools[call.function.name](**call.arguments)[:MAX_TOOL_OUTPUT]
messages.append({"role": "tool", "content": result})
else:
return response.content
Key Takeaways
- Start simple: one tool, one loop, clear instructions
- Use the ReAct pattern for reliable reasoning
- Always set max steps and token budgets
- Handle tool errors gracefully
- Log everything — agent debugging is hard without traces
6. Test with adversarial inputs before production
🚀 Level up your AI workflow! Check out my AI Developer Mega Prompt Pack — 80 battle-tested prompts for developers. $9.99
Top comments (0)