Frequently Asked Questions (FAQ)
Common questions and answers about Agent Patterns.
General Questions
What is Agent Patterns?
Agent Patterns is a Python library providing reusable workflow patterns for AI agents. It implements 9 research-backed patterns using LangGraph and LangChain, making it easy to build reliable, structured agent applications.
Why use patterns instead of custom code?
Patterns provide:
Reliability: Consistent, predictable behavior
Reusability: Apply same pattern across different domains
Best Practices: Research-backed approaches
Debuggability: Clear, inspectable workflow stages
Maintainability: Modular, well-tested code
See What Are Patterns? for details.
Which pattern should I use?
It depends on your task:
Tool-based Q&A: ReAct
High-quality content: Reflection
Multi-step tasks: Plan & Solve
Comprehensive research: STORM
Novel problems: Self-Discovery
See Choosing a Pattern for detailed guidance.
Is Agent Patterns production-ready?
Yes. Version 0.2.0 is stable and tested. It uses:
Synchronous design (no async complexity)
Comprehensive test coverage (>80%)
Well-documented API
Battle-tested patterns from research papers
What’s the license?
MIT License. Free for commercial and personal use.
Installation & Setup
How do I install Agent Patterns?
pip install agent-patterns
See Installation Guide for details.
What Python version is required?
Python 3.10 or higher. We support Python 3.10, 3.11, and 3.12.
Do I need API keys?
Yes, you need at least one:
OpenAI API key for GPT models
Anthropic API key for Claude models
Set them in .env file or environment variables.
Can I use local/open-source models?
Currently, Agent Patterns supports OpenAI and Anthropic via LangChain. For other models, you’ll need to:
Check if LangChain supports the model
Extend
BaseAgent._get_llm()to handle the providerConfigure accordingly
How do I set up multiple API keys?
In .env:
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
Use different providers in llm_configs:
llm_configs = {
"thinking": {"provider": "anthropic", "model_name": "claude-3-5-sonnet-20241022"},
"documentation": {"provider": "openai", "model_name": "gpt-3.5-turbo"}
}
Usage Questions
How do I create a simple agent?
from agent_patterns.patterns import ReActAgent
from dotenv import load_dotenv
load_dotenv()
agent = ReActAgent(
llm_configs={
"thinking": {
"provider": "openai",
"model_name": "gpt-4-turbo"
}
}
)
result = agent.run("Your question here")
See Quick Start for more.
How do I add tools to an agent?
def my_tool(input: str) -> str:
"""Tool description."""
return f"Result for {input}"
agent = ReActAgent(
llm_configs={...},
tools={"my_tool": my_tool}
)
Tools are simple Python functions taking string input and returning string output.
Can I use async functions?
No. Agent Patterns v0.2.0+ is synchronous only. This was a deliberate design decision for simplicity and debuggability.
If you have async tools, wrap them:
import asyncio
def sync_wrapper(input: str) -> str:
async def async_tool(input: str) -> str:
# Your async code
pass
return asyncio.run(async_tool(input))
agent = ReActAgent(tools={"tool": sync_wrapper})
How do I handle errors?
try:
result = agent.run(input_data)
except ValueError as e:
print(f"Configuration error: {e}")
except Exception as e:
print(f"Runtime error: {e}")
Or use lifecycle hooks:
class MyAgent(ReActAgent):
def on_error(self, error):
logger.error(f"Agent failed: {error}")
# Send alert, etc.
How do I log agent activity?
Override lifecycle hooks:
class LoggedAgent(ReActAgent):
def on_start(self, input_data):
print(f"Starting: {input_data}")
def on_finish(self, result):
print(f"Finished: {result}")
Or integrate with logging framework:
import logging
class LoggedAgent(ReActAgent):
def on_start(self, input_data):
logging.info(f"Agent started", extra={"input": input_data})
Customization Questions
How do I customize prompts?
Three ways:
File-based: Put prompts in
prompts/directoryCustom instructions: Add domain context
Prompt overrides: Programmatically replace prompts
agent = ReActAgent(
llm_configs={...},
prompt_dir="my_prompts",
custom_instructions="You are a medical expert.",
prompt_overrides={
"ThoughtStep": {
"system": "Custom system prompt"
}
}
)
See README Customization for details.
What’s the difference between custom_instructions and prompt_overrides?
custom_instructions: Appended to ALL system prompts (adds context)
prompt_overrides: Completely replaces specific prompts (fine-grained control)
Use custom_instructions for domain expertise, prompt_overrides for experiments.
Can I use different models for different roles?
Yes! Mix and match:
llm_configs = {
"thinking": {
"provider": "openai",
"model_name": "gpt-4-turbo"
},
"reflection": {
"provider": "anthropic",
"model_name": "claude-3-5-sonnet-20241022"
},
"documentation": {
"provider": "openai",
"model_name": "gpt-3.5-turbo" # Cheaper for simple tasks
}
}
How do I adjust temperature and other parameters?
In llm_configs:
llm_configs = {
"thinking": {
"provider": "openai",
"model_name": "gpt-4-turbo",
"temperature": 0.3, # Lower = more deterministic
"max_tokens": 1500, # Response length limit
}
}
Pattern-Specific Questions
ReAct: How many iterations should I use?
Start with 5. Adjust based on task complexity:
Simple Q&A: 3-5
Complex research: 7-10
Very complex: 10-15
agent = ReActAgent(max_iterations=7)
Reflection: How many reflection cycles?
Usually 1-2 is sufficient:
1 cycle: Good for most content
2 cycles: High-quality requirements
3+ cycles: Diminishing returns, higher cost
agent = ReflectionAgent(max_reflection_cycles=2)
Plan & Solve: Can I provide an existing plan?
Not directly, but you can guide it via custom instructions:
agent = PlanAndSolveAgent(
llm_configs={...},
custom_instructions="""
Use this structure:
1. Research phase
2. Analysis phase
3. Synthesis phase
"""
)
STORM: How do I add custom perspectives?
perspectives = [
{"name": "engineer", "description": "Software engineer implementing solutions"},
{"name": "manager", "description": "Project manager considering resources"},
{"name": "user", "description": "End user of the product"}
]
agent = STORMAgent(
llm_configs={...},
perspectives=perspectives
)
Self-Discovery: Can I add custom reasoning modules?
Yes:
custom_modules = [
{
"name": "cost_benefit",
"description": "Analyze costs and benefits",
"template": "For '{task}', identify costs and benefits"
},
{
"name": "risk_analysis",
"description": "Assess risks and mitigation strategies",
"template": "Identify risks for '{task}' and how to mitigate them"
}
]
agent = SelfDiscoveryAgent(
llm_configs={...},
reasoning_modules=custom_modules
)
Technical Questions
How does state management work?
Each pattern uses a state dictionary that flows through the graph:
state = {
"input": "user query",
"intermediate_data": [...],
"output": "result"
}
# Nodes receive and return state
def my_node(state: Dict) -> Dict:
state["new_field"] = "value"
return state
See Architecture for details.
What is LangGraph?
LangGraph is a library for building stateful, multi-actor applications with LLMs. It manages the state graph execution for Agent Patterns.
Learn more: LangGraph Docs
Can I inspect intermediate steps?
Yes, access the state during execution. For ReAct:
# After execution, inspect
result_state = agent.graph.invoke(initial_state)
history = result_state["intermediate_steps"]
for thought, action, observation in history:
print(f"Thought: {thought}")
print(f"Action: {action}")
print(f"Result: {observation}")
Can I stream results?
Default stream() implementation just yields final result. For true streaming, override in subclass:
class StreamingAgent(ReActAgent):
def stream(self, input_data):
state = {"input": input_data, ...}
for chunk in self.graph.stream(state):
yield chunk
LangGraph supports streaming - see LangGraph streaming docs.
How do I test my agent?
import pytest
from unittest.mock import Mock
def test_agent():
# Mock LLM
mock_llm = Mock()
mock_llm.invoke.return_value.content = "Test response"
# Create agent
agent = ReActAgent(llm_configs={...})
agent._llm_cache["thinking"] = mock_llm
# Test
result = agent.run("test query")
assert "Test response" in result
See test files in tests/ directory for examples.
Performance & Cost Questions
How much do API calls cost?
Depends on:
Model used (GPT-4 > GPT-3.5)
Number of iterations/cycles
Token counts
Example ReAct with GPT-4 (5 iterations):
~2,000 tokens per iteration
10,000 total tokens
~$0.30 per query
Use cheaper models for less critical roles:
llm_configs = {
"thinking": {"model_name": "gpt-4-turbo"}, # Expensive but good
"documentation": {"model_name": "gpt-3.5-turbo"} # Cheap for simple tasks
}
How can I reduce costs?
Use cheaper models for simple roles
Reduce iterations/cycles
Lower max_tokens
Cache results when possible
Use REWOO instead of ReAct (fewer LLM calls)
How fast are the patterns?
Depends on:
Number of LLM calls
Model speed
Network latency
Approximate times (GPT-4):
ReAct (5 iter): 10-15 seconds
Reflection (2 cycles): 15-20 seconds
Plan & Solve: 20-30 seconds
STORM: 60-120 seconds
Can I cache LLM responses?
Yes, use LangChain caching:
from langchain.cache import InMemoryCache
from langchain.globals import set_llm_cache
set_llm_cache(InMemoryCache())
# Now LLM calls are cached
agent = ReActAgent(...)
Troubleshooting Questions
I get “Module not found” errors
Install dependencies:
pip install agent-patterns
Or if installed from source:
pip install -e .
I get “API key not found” errors
Set API key in .env:
OPENAI_API_KEY=your-key-here
Or environment:
export OPENAI_API_KEY=your-key-here
Load in code:
from dotenv import load_dotenv
load_dotenv()
Agent gives nonsensical responses
Check:
Prompts: Are they clear and well-structured?
Temperature: Try lowering (0.3-0.5)
Model: Try more capable model (GPT-4 instead of GPT-3.5)
Instructions: Add domain context via custom_instructions
Agent loops infinitely
Check:
max_iterations: Set appropriate limit
Termination logic: Ensure pattern can detect completion
Tool results: Make sure tools return useful information
Tools aren’t being called
Check:
Tool registration: Tools in
toolsdict?Tool docstrings: Clear description?
Prompts: Do they mention available tools?
LLM capability: Some models better at tool use than others
See Troubleshooting Guide for more.
Advanced Questions
Can I create my own pattern?
Yes! Inherit from BaseAgent:
from agent_patterns.core import BaseAgent
from langgraph.graph import StateGraph, END
class MyPattern(BaseAgent):
def build_graph(self):
workflow = StateGraph(dict)
# Define your nodes and edges
workflow.add_node("step1", self._step1)
workflow.add_edge("step1", END)
self.graph = workflow.compile()
def run(self, input_data):
state = {"input": input_data}
final_state = self.graph.invoke(state)
return final_state["output"]
def _step1(self, state):
# Your logic
return state
See BaseAgent API for details.
Can I combine multiple patterns?
Yes, but requires custom implementation. You could:
Sequential: Run one pattern, feed output to another
Parallel: Run multiple patterns, combine results
Hierarchical: Use one pattern to coordinate others
Future versions may include multi-agent patterns.
How do I deploy to production?
Containerize: Use Docker
API wrapper: FastAPI or Flask
Monitoring: Add logging and metrics
Error handling: Robust try/catch
Rate limiting: Manage API costs
Caching: Cache common queries
Example FastAPI wrapper:
from fastapi import FastAPI
from agent_patterns.patterns import ReActAgent
app = FastAPI()
agent = ReActAgent(llm_configs={...})
@app.post("/query")
def query(question: str):
try:
result = agent.run(question)
return {"result": result}
except Exception as e:
return {"error": str(e)}, 500
Can I use Agent Patterns with LangChain Expression Language (LCEL)?
Agent Patterns uses LangGraph, which is compatible with LCEL. You can integrate LCEL chains as tools:
from langchain_core.runnables import RunnableLambda
def lcel_tool_wrapper(chain):
"""Wrap LCEL chain as tool."""
def tool(input: str) -> str:
return chain.invoke({"input": input})
return tool
my_chain = prompt | llm | output_parser
agent = ReActAgent(
llm_configs={...},
tools={"my_chain": lcel_tool_wrapper(my_chain)}
)
Migration Questions
How do I migrate from v0.1.x to v0.2.0?
v0.2.0 is a complete rewrite. Key changes:
Remove async/await: All code is now synchronous
Update imports: Patterns moved to
agent_patterns.patternsNew configuration: Use new
llm_configsformatPrompt system: Update to new 3-layer system
See Changelog for details.
Can I still use v0.1.x?
Yes, but not recommended. v0.1.x had async reliability issues. v0.2.0 is much more stable.
Community & Support
Where can I get help?
Documentation: Start here
GitHub Issues: Report bugs
GitHub Discussions: Ask questions
How can I contribute?
See Contributing Guide.
Is there a Discord/Slack?
Not yet. Use GitHub Discussions for community interaction.
Where can I find more examples?
Didn’t find your answer?
Check Troubleshooting Guide
Search GitHub Issues
Ask in GitHub Discussions
Create a new issue