Skip to content

Commit b393bf9

Browse files
Multi agent system tutorial (#8)
1 parent 7435941 commit b393bf9

File tree

19 files changed

+5668
-913
lines changed

19 files changed

+5668
-913
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# syntax=docker/dockerfile:1.3
2+
FROM python:3.12-slim
3+
4+
COPY --from=ghcr.io/astral-sh/uv:0.6.4 /uv /uvx /bin/
5+
6+
# Install system dependencies
7+
RUN apt-get update && apt-get install -y \
8+
htop \
9+
vim \
10+
curl \
11+
tar \
12+
python3-dev \
13+
postgresql-client \
14+
build-essential \
15+
libpq-dev \
16+
gcc \
17+
cmake \
18+
netcat-openbsd \
19+
&& apt-get clean \
20+
&& rm -rf /var/lib/apt/lists/*
21+
22+
RUN uv pip install --system --upgrade pip setuptools wheel
23+
24+
ENV UV_HTTP_TIMEOUT=1000
25+
26+
# Copy just the pyproject.toml file to optimize caching
27+
COPY pyproject.toml /app/pyproject.toml
28+
WORKDIR /app/
29+
# Install the required Python packages
30+
RUN uv pip install --system -e .
31+
32+
# Copy the project code
33+
COPY project /app/project
34+
35+
WORKDIR /app
36+
37+
# Set environment variables
38+
ENV PYTHONPATH=/app
39+
40+
ARG AGENT_FILE
41+
ARG PORT
42+
43+
# Run the agent using uvicorn
44+
CMD uvicorn project.${AGENT_FILE%.*}:acp --host 0.0.0.0 --port ${PORT:-8000}
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# Multi-Agent Content Assembly Line
2+
3+
A multi-agent system that creates content through a collaborative workflow. Four agents work together: a creator generates content, a critic reviews it against rules, and a formatter outputs the final result, all coordinated by an orchestrator.
4+
5+
## 🏗️ Architecture Overview
6+
7+
```
8+
090_multi_agent_non_temporal/
9+
├── project/ # All agent code
10+
│ ├── creator.py # Content generation agent
11+
│ ├── critic.py # Content review agent
12+
│ ├── formatter.py # Content formatting agent
13+
│ ├── orchestrator.py # Workflow coordination agent
14+
│ ├── models.py # Pydantic models for type safety
15+
│ └── state_machines/
16+
│ └── content_workflow.py # State machine definitions
17+
├── creator.yaml # Creator agent manifest
18+
├── critic.yaml # Critic agent manifest
19+
├── formatter.yaml # Formatter agent manifest
20+
├── orchestrator.yaml # Orchestrator agent manifest
21+
├── Dockerfile # Single shared Dockerfile
22+
├── pyproject.toml # Dependencies and project configuration
23+
├── start-agents.sh # Agent management script
24+
└── README.md # This file
25+
```
26+
27+
## 📁 File Structure
28+
29+
The system uses a shared build configuration with type-safe interfaces:
30+
- **Single `Dockerfile`** with build arguments for different agents
31+
- **Single `pyproject.toml`** for all dependencies
32+
- **Agent code** in `project/` directory with clear separation of concerns
33+
- **Individual manifest files** at root level for each agent deployment
34+
- **Shared state machine definitions** for workflow coordination
35+
- **Pydantic models** (`models.py`) for type safety and validation across all agents
36+
37+
### Key Files:
38+
- `project/models.py` - Defines request/response models for type safety
39+
- `project/orchestrator.py` - Workflow coordination and inter-agent communication
40+
- `project/creator.py` - Content generation with revision capabilities
41+
- `project/critic.py` - Content validation against rules
42+
- `project/formatter.py` - Multi-format content transformation
43+
- `project/state_machines/content_workflow.py` - State management for the workflow
44+
45+
## 🚀 Quick Start
46+
47+
### Prerequisites
48+
- Python 3.12+
49+
- uv package manager
50+
- OpenAI API key (set `OPENAI_API_KEY` or create `.env` file)
51+
52+
### Running the System
53+
54+
1. **Start all agents**:
55+
```bash
56+
cd examples/tutorials/10_agentic/00_base/090_multi_agent_non_temporal
57+
./start-agents.sh start
58+
```
59+
60+
2. **Check agent status**:
61+
```bash
62+
./start-agents.sh status
63+
```
64+
65+
3. **Send a test request**:
66+
```bash
67+
./start-agents.sh test
68+
```
69+
70+
4. **Monitor logs**:
71+
```bash
72+
./start-agents.sh logs
73+
```
74+
75+
5. **Stop all agents**:
76+
```bash
77+
./start-agents.sh stop
78+
```
79+
80+
## 🤖 Agent Responsibilities
81+
82+
### **Creator Agent** (Port 8001)
83+
- Generates original content based on user requests
84+
- Revises content based on critic feedback
85+
- Maintains conversation history and iteration tracking
86+
87+
### **Critic Agent** (Port 8002)
88+
- Reviews content against specified rules
89+
- Provides specific, actionable feedback
90+
- Approves content when all rules are met
91+
92+
### **Formatter Agent** (Port 8003)
93+
- Converts approved content to target formats (HTML, Markdown, JSON, etc.)
94+
- Preserves meaning while applying format-specific conventions
95+
- Supports multiple output formats
96+
97+
### **Orchestrator Agent** (Port 8000)
98+
- Coordinates the entire workflow using state machines
99+
- Manages inter-agent communication
100+
- Tracks progress and handles errors/retries
101+
102+
## 📋 Example Request
103+
104+
Send a JSON request to the orchestrator:
105+
106+
```json
107+
{
108+
"request": "Write a welcome message for our AI assistant",
109+
"rules": ["Under 50 words", "Friendly tone", "Include emoji"],
110+
"target_format": "HTML"
111+
}
112+
```
113+
114+
The system will:
115+
1. **Create** content using the Creator agent
116+
2. **Review** against rules using the Critic agent
117+
3. **Revise** if needed (up to 10 iterations)
118+
4. **Format** final approved content using the Formatter agent
119+
120+
## 🔧 Development
121+
122+
### Type Safety with Pydantic
123+
The tutorial demonstrates proper type safety using Pydantic models:
124+
125+
```python
126+
# Define request structure
127+
class CreatorRequest(BaseModel):
128+
request: str = Field(..., description="The content creation request")
129+
current_draft: Optional[str] = Field(default=None, description="Current draft for revision")
130+
feedback: Optional[List[str]] = Field(default=None, description="Feedback from critic")
131+
132+
# Validate incoming requests
133+
creator_request = CreatorRequest.model_validate(request_data)
134+
```
135+
136+
Benefits:
137+
- **Explicit failures** when required fields are missing
138+
- **Self-documenting** APIs with field descriptions
139+
- **IDE support** with auto-completion and type checking
140+
- **Runtime validation** with clear error messages
141+
142+
### Adding New Agents
143+
1. **Add models** to `project/models.py` for request/response types
144+
2. **Create agent** in `project/new_agent.py` using the FastACP pattern
145+
3. **Add manifest** as `new_agent.yaml` at root level with deployment configuration
146+
4. **Update startup script** in `start-agents.sh` to include the new agent
147+
148+
### Modifying Agents
149+
- **Agent code** is in `project/` directory
150+
- **Shared models** are in `project/models.py` for consistency
151+
- **Dependencies** go in `pyproject.toml`
152+
- **Docker configuration** is shared across all agents
153+
154+
### Deployment
155+
Each agent can be deployed independently using its manifest:
156+
```bash
157+
uv run agentex agents deploy --cluster your-cluster --manifest creator.yaml
158+
```
159+
160+
## 🏗️ Technical Implementation
161+
162+
### Shared Dockerfile
163+
The Dockerfile uses build arguments to run different agents:
164+
```dockerfile
165+
CMD uvicorn project.${AGENT_FILE%.*}:acp --host 0.0.0.0 --port ${PORT:-8000}
166+
```
167+
168+
Manifest files specify which agent to run:
169+
```yaml
170+
build_args:
171+
AGENT_FILE: creator.py
172+
PORT: 8001
173+
```
174+
175+
### State Machine Flow
176+
The orchestrator coordinates the workflow through these states:
177+
- `CREATING` → `WAITING_FOR_CREATOR` → `REVIEWING` → `WAITING_FOR_CRITIC` → `FORMATTING` → `COMPLETED`
178+
179+
### Inter-Agent Communication
180+
Agents communicate using AgentEx events:
181+
```python
182+
await adk.acp.send_event(
183+
agent_name="ab090-creator-agent",
184+
task_id=task_id,
185+
content=TextContent(author="agent", content=json.dumps(request_data))
186+
)
187+
```
188+
189+
## 📚 What You'll Learn
190+
191+
This tutorial demonstrates:
192+
- **Multi-agent coordination** using state machines for complex workflows
193+
- **Type-safe communication** with Pydantic models for all request/response data
194+
- **Shared build configuration** for multiple agents in a single deployment
195+
- **AgentEx CLI usage** for development and deployment
196+
- **Inter-agent communication patterns** with proper error handling
197+
- **Scalable agent architecture** with clear separation of concerns
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Creator Agent Manifest Configuration
2+
# ----------------------------------
3+
# This file defines how the creator agent should be built and deployed.
4+
5+
build:
6+
context:
7+
root: ../
8+
dockerfile: Dockerfile
9+
build_args:
10+
AGENT_FILE: creator.py
11+
PORT: 8001
12+
13+
local_development:
14+
agent:
15+
port: 8001
16+
host_address: host.docker.internal
17+
paths:
18+
acp: project/creator.py
19+
20+
agent:
21+
name: ab090-creator-agent
22+
acp_type: agentic
23+
description: Creator agent that generates and revises content based on requests and feedback
24+
temporal:
25+
enabled: false
26+
27+
deployment:
28+
image:
29+
repository: ""
30+
tag: "latest"
31+
global:
32+
agent:
33+
name: "ab090-creator-agent"
34+
description: "Creator agent that generates and revises content based on requests and feedback"
35+
replicaCount: 1
36+
resources:
37+
requests:
38+
cpu: "500m"
39+
memory: "1Gi"
40+
limits:
41+
cpu: "1000m"
42+
memory: "2Gi"
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Critic Agent Manifest Configuration
2+
# ---------------------------------
3+
# This file defines how the critic agent should be built and deployed.
4+
5+
build:
6+
context:
7+
root: ../
8+
dockerfile: Dockerfile
9+
build_args:
10+
AGENT_FILE: critic.py
11+
PORT: 8002
12+
13+
local_development:
14+
agent:
15+
port: 8002
16+
host_address: host.docker.internal
17+
paths:
18+
acp: project/critic.py
19+
20+
agent:
21+
name: ab090-critic-agent
22+
acp_type: agentic
23+
description: Critic agent that reviews content drafts against specified rules and provides feedback
24+
temporal:
25+
enabled: false
26+
27+
deployment:
28+
image:
29+
repository: ""
30+
tag: "latest"
31+
global:
32+
agent:
33+
name: "ab090-critic-agent"
34+
description: "Critic agent that reviews content drafts against specified rules and provides feedback"
35+
replicaCount: 1
36+
resources:
37+
requests:
38+
cpu: "500m"
39+
memory: "1Gi"
40+
limits:
41+
cpu: "1000m"
42+
memory: "2Gi"
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Formatter Agent Manifest Configuration
2+
# -------------------------------------
3+
# This file defines how the formatter agent should be built and deployed.
4+
5+
build:
6+
context:
7+
root: ../
8+
dockerfile: Dockerfile
9+
build_args:
10+
AGENT_FILE: formatter.py
11+
PORT: 8003
12+
13+
local_development:
14+
agent:
15+
port: 8003
16+
host_address: host.docker.internal
17+
paths:
18+
acp: project/formatter.py
19+
20+
agent:
21+
name: ab090-formatter-agent
22+
acp_type: agentic
23+
description: Formatter agent that converts approved content to various target formats (HTML, Markdown, etc.)
24+
temporal:
25+
enabled: false
26+
27+
deployment:
28+
image:
29+
repository: ""
30+
tag: "latest"
31+
global:
32+
agent:
33+
name: "ab090-formatter-agent"
34+
description: "Formatter agent that converts approved content to various target formats (HTML, Markdown, etc.)"
35+
replicaCount: 1
36+
resources:
37+
requests:
38+
cpu: "500m"
39+
memory: "1Gi"
40+
limits:
41+
cpu: "1000m"
42+
memory: "2Gi"

0 commit comments

Comments
 (0)