Reusable AI agent workflow patterns using LangGraph and LangChain
Project description
Agent Patterns
A Python library of reusable AI agent workflow patterns implemented using LangGraph and LangChain. All patterns are synchronous and follow consistent architectural principles.
⚠️ Breaking Change in v0.2.0: This version is a complete rewrite from the ground up. The previous 0.1.x version used asyncio extensively, which caused significant reliability issues and made debugging extremely difficult. Version 0.2.0+ eliminates async/await entirely in favor of a synchronous-only architecture. This makes the library more reliable, easier to use, and much simpler to debug. If you were using v0.1.x, please note this is a breaking change - all patterns now use standard synchronous Python.
Features
- 9 Battle-Tested Patterns: ReAct, Plan & Solve, Reflection, Reflexion, LLM Compiler, REWOO, LATS, Self-Discovery, and STORM
- Enterprise-Grade Prompts: 150-300+ line comprehensive system prompts with 9-section structure (Role, Capabilities, Process, Examples, Edge Cases, Quality Standards, etc.) following Anthropic/OpenAI prompt engineering best practices
- Synchronous Design: No async/await complexity - simple, debuggable code
- Flexible Prompt Customization: Three ways to customize prompts - file-based, custom instructions, and programmatic overrides
- Multi-Provider Support: Works with OpenAI, Anthropic, and other LangChain-supported providers
- Type-Safe: Full type hints for better IDE support and fewer bugs
- Extensible: Abstract base classes make it easy to create custom patterns
- Well-Tested: Comprehensive test suite with >80% coverage
Installation
From PyPI (Recommended)
pip install agent-patterns
From Source
# Clone the repository
git clone https://github.com/osok/agent-patterns.git
cd agent-patterns
# Create and activate virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e .
# Or install with dev dependencies
pip install -e ".[dev]"
Quick Start
1. Set Up Environment
Copy .env.example to .env and add your API keys:
cp .env.example .env
Edit .env:
OPENAI_API_KEY=your-key-here
THINKING_MODEL_PROVIDER=openai
THINKING_MODEL_NAME=gpt-4-turbo
2. Use a Pattern
ReAct Agent (Reason + Act)
from agent_patterns.patterns import ReActAgent
import os
from dotenv import load_dotenv
load_dotenv()
# Configure LLMs
llm_configs = {
"thinking": {
"provider": "openai",
"model_name": "gpt-4-turbo",
"temperature": 0.7,
}
}
# Define tools
def search_tool(query):
# Your search implementation
return f"Results for: {query}"
tools = {"search": search_tool}
# Create and run agent
agent = ReActAgent(
llm_configs=llm_configs,
tools=tools,
max_iterations=5
)
result = agent.run("What is the weather in Paris?")
print(result)
Reflection Agent
from agent_patterns.patterns import ReflectionAgent
llm_configs = {
"documentation": {
"provider": "openai",
"model_name": "gpt-3.5-turbo",
},
"reflection": {
"provider": "openai",
"model_name": "gpt-4-turbo",
},
}
agent = ReflectionAgent(
llm_configs=llm_configs,
max_reflection_cycles=1
)
result = agent.run("Write a short story about a robot dog")
print(result)
Plan & Solve Agent
from agent_patterns.patterns import PlanAndSolveAgent
llm_configs = {
"planning": {
"provider": "openai",
"model_name": "gpt-4-turbo",
},
"execution": {
"provider": "openai",
"model_name": "gpt-3.5-turbo",
},
"documentation": {
"provider": "openai",
"model_name": "gpt-3.5-turbo",
},
}
agent = PlanAndSolveAgent(llm_configs=llm_configs)
result = agent.run("Write a research report on renewable energy")
print(result)
Available Patterns
Currently Implemented
| Pattern | Description | Use Case |
|---|---|---|
| ReAct | Reason + Act with tool use | Question answering with external tools |
| Plan & Solve | Planning then execution | Tasks requiring structured decomposition |
| Reflection | Generate, critique, refine | High-quality content generation |
Coming Soon
- Reflexion: Multi-trial learning with reflection memory
- LLM Compiler: DAG-based parallel tool execution
- REWOO: Worker-Solver pattern for cost efficiency
- LATS: Tree search over reasoning paths
- Self-Discovery: Dynamic reasoning module selection
- STORM: Multi-perspective research synthesis
Project Structure
agent-patterns/
├── agent_patterns/
│ ├── core/ # Base classes
│ │ ├── base_agent.py
│ │ └── multi_agent_base.py
│ ├── patterns/ # Pattern implementations
│ │ ├── re_act_agent.py
│ │ ├── plan_and_solve_agent.py
│ │ └── reflection_agent.py
│ └── prompts/ # Externalized prompt templates
│ ├── ReActAgent/
│ ├── PlanAndSolveAgent/
│ └── ReflectionAgent/
├── examples/ # Usage examples
│ ├── react_example.py
│ └── reflection_example.py
├── tests/ # Unit tests
│ ├── test_base_agent.py
│ ├── test_re_act_agent.py
│ └── test_reflection_agent.py
└── docs/ # Documentation
├── Design.md
├── task_list.md
└── notes.md
Running Examples
# Ensure you're in the virtual environment and have set up .env
# Run ReAct example
python examples/react_example.py
# Run Reflection example
python examples/reflection_example.py
Running Tests
# Run all tests
pytest
# Run with coverage
pytest --cov=agent_patterns --cov-report=html
# Run specific test file
pytest tests/test_base_agent.py
# Run with verbose output
pytest -v
Creating Custom Patterns
Extend BaseAgent to create your own pattern:
from agent_patterns.core import BaseAgent
from langgraph.graph import StateGraph, END
class MyCustomAgent(BaseAgent):
def build_graph(self):
workflow = StateGraph(dict)
# Define your nodes
workflow.add_node("step1", self._step1)
workflow.add_node("step2", self._step2)
# Define edges
workflow.set_entry_point("step1")
workflow.add_edge("step1", "step2")
workflow.add_edge("step2", END)
# Compile
self.graph = workflow.compile()
def run(self, input_data):
if self.graph is None:
raise ValueError("Graph not built")
initial_state = {
"input": input_data,
"output": None
}
result_state = self.graph.invoke(initial_state)
return result_state.get("output")
def _step1(self, state):
# Your logic here
return state
def _step2(self, state):
# Your logic here
return state
Customizing Prompts
Agent Patterns provides three flexible ways to customize prompts without modifying the library code:
1. File-Based Customization (Default)
Prompts are stored as markdown files in agent_patterns/prompts/{PatternName}/{StepName}/:
prompts/
└── ReActAgent/
└── ThoughtStep/
├── system.md # System prompt
└── user.md # User prompt template
You can provide a custom prompt directory:
agent = ReActAgent(
llm_configs=llm_configs,
prompt_dir="my_custom_prompts" # Use your custom prompt directory
)
2. Custom Instructions
Add domain-specific context, constraints, or guidelines that apply to ALL prompts in the workflow:
medical_instructions = """
You are providing information in the MEDICAL domain:
- Always prioritize medical accuracy
- Include appropriate medical disclaimers
- Use proper medical terminology
- Recommend consulting healthcare professionals
"""
agent = SelfDiscoveryAgent(
llm_configs=llm_configs,
custom_instructions=medical_instructions # Applied to all system prompts
)
Use Cases:
- Adding domain expertise (medical, legal, financial)
- Enforcing compliance requirements
- Setting tone/style guidelines
- Specifying audience level
- Adding ethical guidelines
See examples/custom_instructions_example.py for comprehensive examples.
3. Prompt Overrides
Programmatically replace specific prompts for fine-grained control:
overrides = {
"DiscoverModules": {
"system": "You are an expert at selecting reasoning strategies.",
"user": "Task: {task}\n\nSelect the best modules:\n{modules}"
},
"SynthesizeOutput": {
"system": "You synthesize reasoning into clear answers.",
"user": "Task: {task}\n\nSteps:\n{reasoning_steps}\n\nFinal answer:"
}
}
agent = SelfDiscoveryAgent(
llm_configs=llm_configs,
prompt_overrides=overrides # Override specific prompts
)
Use Cases:
- A/B testing different prompts
- Experimenting with prompt engineering
- Creating specialized pattern variants
- Dynamic prompt generation
- Adjusting complexity levels
See examples/prompt_overrides_example.py for comprehensive examples.
4. Combining Approaches
You can combine all three methods for maximum flexibility:
agent = ReflectionAgent(
llm_configs=llm_configs,
prompt_dir="my_prompts", # 1. Custom directory
custom_instructions=instructions, # 2. Add domain context
prompt_overrides=overrides # 3. Override specific steps
)
Priority Order:
prompt_overrides(highest priority - complete replacement)- File system prompts from
prompt_dir custom_instructions(lowest priority - appended to system prompts)
This allows you to start with base prompts, add domain-specific context, and selectively override specific steps as needed.
Configuration
LLM Roles
Different patterns use different LLM roles:
- thinking: Primary reasoning (usually expensive model like GPT-4)
- reflection: Self-critique (can be same or different model)
- documentation: Output generation (can use cheaper model)
- planning: Task decomposition (usually expensive model)
- execution: Task execution (can use cheaper model)
Environment Variables
See .env.example for all configuration options:
# API Keys
OPENAI_API_KEY=your-key-here
ANTHROPIC_API_KEY=your-key-here
# Model Configuration
THINKING_MODEL_PROVIDER=openai
THINKING_MODEL_NAME=gpt-4-turbo
THINKING_TEMPERATURE=0.7
THINKING_MAX_TOKENS=2000
# Pattern-Specific
MAX_ITERATIONS=5
MAX_TRIALS=3
MAX_REFLECTION_CYCLES=2
Design Principles
- Synchronous Only: No async/await for simplicity and debuggability
- Externalized Configuration: Prompts and settings outside code
- Type Safety: Full type hints throughout
- Testability: Designed for easy mocking and testing
- Extensibility: Clear extension points via abstract methods
Requirements
- Python 3.10+
- LangGraph >= 0.2.0
- LangChain >= 0.3.0
- python-dotenv >= 1.0.0
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-pattern) - Make your changes
- Run tests (
pytest) - Commit your changes (
git commit -am 'Add amazing pattern') - Push to the branch (
git push origin feature/amazing-pattern) - Create a Pull Request
Development Setup
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black agent_patterns tests examples
# Lint code
ruff check agent_patterns tests examples
# Type check
mypy agent_patterns
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built on LangGraph for state graph management
- Uses LangChain for LLM integrations
- Inspired by research papers and best practices from the AI agent community
Documentation
- Design Document - Detailed architectural design
- Task List - Development progress tracking
- Implementation Notes - Technical decisions and guidelines
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: See
docs/directory - PyPI: agent-patterns on PyPI
Roadmap
- Implement remaining 6 patterns
- Add streaming support
- Create interactive examples/demos
- Add more comprehensive documentation
- Create video tutorials
- Add pattern composition capabilities
- Implement tool registry module
Built with ❤️ for the AI agent community
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_patterns-0.2.1.tar.gz.
File metadata
- Download URL: agent_patterns-0.2.1.tar.gz
- Upload date:
- Size: 197.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5e4887c31eef6f4c430b4ad3dfefe4f0946f5402d5f9ef080e7e0228d6de479
|
|
| MD5 |
4be5a4686da7f05b1d3482de8843863f
|
|
| BLAKE2b-256 |
ebf05d14da610b3815a6abf648e4cdb3cff4aefb89464e6613f49717bfa704ed
|
File details
Details for the file agent_patterns-0.2.1-py3-none-any.whl.
File metadata
- Download URL: agent_patterns-0.2.1-py3-none-any.whl
- Upload date:
- Size: 51.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b80d0f3e9d9d55887edd91d0ea2f7aa216270368fee8cbf98dd96f8863a5840f
|
|
| MD5 |
752371561de66f439e7fd46d65700cd1
|
|
| BLAKE2b-256 |
b8854e3a71c64dcd6cc3a75e85c50ba0e56e7657358265ae923b50800333009e
|