|
| 1 | +# Deployment Guide for PromptPipe Agent |
| 2 | + |
| 3 | +This guide explains how to deploy the Python/LangChain agentic layer alongside the Go message delivery service. |
| 4 | + |
| 5 | +## Architecture Overview |
| 6 | + |
| 7 | +``` |
| 8 | +┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ |
| 9 | +│ │ │ │ │ │ |
| 10 | +│ WhatsApp │─────▶│ Go Service │─────▶│ Python Agent │ |
| 11 | +│ Messages │ │ (Message │ │ (Conversation │ |
| 12 | +│ │◀─────│ Delivery) │◀─────│ Processing) │ |
| 13 | +└─────────────────┘ └──────────────────┘ └─────────────────┘ |
| 14 | + │ │ |
| 15 | + │ │ |
| 16 | + ▼ ▼ |
| 17 | + ┌──────────────┐ ┌──────────────┐ |
| 18 | + │ SQLite │◀─────────│ SQLite │ |
| 19 | + │ (Go Data) │ Shared │ (Agent Data) │ |
| 20 | + └──────────────┘ └──────────────┘ |
| 21 | +``` |
| 22 | + |
| 23 | +## Prerequisites |
| 24 | + |
| 25 | +- Python 3.12+ |
| 26 | +- Go 1.21+ |
| 27 | +- OpenAI API key |
| 28 | +- SQLite or PostgreSQL |
| 29 | + |
| 30 | +## Option 1: Docker Deployment (Recommended) |
| 31 | + |
| 32 | +### 1. Create docker-compose.yml |
| 33 | + |
| 34 | +```yaml |
| 35 | +version: '3.8' |
| 36 | + |
| 37 | +services: |
| 38 | + go-service: |
| 39 | + build: |
| 40 | + context: . |
| 41 | + dockerfile: Dockerfile.go |
| 42 | + ports: |
| 43 | + - "8080:8080" |
| 44 | + environment: |
| 45 | + - API_ADDR=:8080 |
| 46 | + - DATABASE_DSN=/data/state.db |
| 47 | + - OPENAI_API_KEY=${OPENAI_API_KEY} |
| 48 | + - PYTHON_AGENT_URL=http://python-agent:8001 |
| 49 | + volumes: |
| 50 | + - promptpipe-data:/var/lib/promptpipe |
| 51 | + depends_on: |
| 52 | + - python-agent |
| 53 | + |
| 54 | + python-agent: |
| 55 | + build: |
| 56 | + context: ./python/langchain |
| 57 | + dockerfile: Dockerfile |
| 58 | + ports: |
| 59 | + - "8001:8001" |
| 60 | + environment: |
| 61 | + - OPENAI_API_KEY=${OPENAI_API_KEY} |
| 62 | + - OPENAI_MODEL=gpt-4o-mini |
| 63 | + - PROMPTPIPE_STATE_DIR=/var/lib/promptpipe |
| 64 | + - API_HOST=0.0.0.0 |
| 65 | + - API_PORT=8001 |
| 66 | + volumes: |
| 67 | + - promptpipe-data:/var/lib/promptpipe |
| 68 | + |
| 69 | +volumes: |
| 70 | + promptpipe-data: |
| 71 | +``` |
| 72 | +
|
| 73 | +### 2. Create Dockerfile for Python Agent |
| 74 | +
|
| 75 | +```dockerfile |
| 76 | +FROM python:3.12-slim |
| 77 | + |
| 78 | +WORKDIR /app |
| 79 | + |
| 80 | +# Install uv |
| 81 | +RUN pip install uv |
| 82 | + |
| 83 | +# Copy project files |
| 84 | +COPY pyproject.toml uv.lock ./ |
| 85 | +COPY promptpipe_agent ./promptpipe_agent |
| 86 | + |
| 87 | +# Install dependencies |
| 88 | +RUN uv sync --frozen |
| 89 | + |
| 90 | +# Expose port |
| 91 | +EXPOSE 8001 |
| 92 | + |
| 93 | +# Run the application |
| 94 | +CMD ["uv", "run", "uvicorn", "promptpipe_agent.api.main:app", "--host", "0.0.0.0", "--port", "8001"] |
| 95 | +``` |
| 96 | + |
| 97 | +### 3. Deploy |
| 98 | + |
| 99 | +```bash |
| 100 | +# Set your OpenAI API key |
| 101 | +export OPENAI_API_KEY=your_key_here |
| 102 | + |
| 103 | +# Start services |
| 104 | +docker-compose up -d |
| 105 | + |
| 106 | +# Check logs |
| 107 | +docker-compose logs -f |
| 108 | +``` |
| 109 | + |
| 110 | +## Option 2: Manual Deployment |
| 111 | + |
| 112 | +### 1. Deploy Python Agent |
| 113 | + |
| 114 | +```bash |
| 115 | +cd python/langchain |
| 116 | + |
| 117 | +# Create virtual environment |
| 118 | +uv sync --extra dev |
| 119 | + |
| 120 | +# Create .env file |
| 121 | +cat > .env << EOF |
| 122 | +OPENAI_API_KEY=your_key_here |
| 123 | +OPENAI_MODEL=gpt-4o-mini |
| 124 | +PROMPTPIPE_STATE_DIR=/var/lib/promptpipe |
| 125 | +API_HOST=0.0.0.0 |
| 126 | +API_PORT=8001 |
| 127 | +EOF |
| 128 | + |
| 129 | +# Run the service |
| 130 | +uv run uvicorn promptpipe_agent.api.main:app --host 0.0.0.0 --port 8001 |
| 131 | +``` |
| 132 | + |
| 133 | +### 2. Configure Go Service |
| 134 | + |
| 135 | +Update your Go service environment variables: |
| 136 | + |
| 137 | +```bash |
| 138 | +export PYTHON_AGENT_URL=http://localhost:8001 |
| 139 | +export DATABASE_DSN=/var/lib/promptpipe/state.db |
| 140 | +``` |
| 141 | + |
| 142 | +### 3. Start Go Service |
| 143 | + |
| 144 | +```bash |
| 145 | +./build/promptpipe |
| 146 | +``` |
| 147 | + |
| 148 | +## Option 3: Systemd Services |
| 149 | + |
| 150 | +### Python Agent Service |
| 151 | + |
| 152 | +Create `/etc/systemd/system/promptpipe-agent.service`: |
| 153 | + |
| 154 | +```ini |
| 155 | +[Unit] |
| 156 | +Description=PromptPipe Python Agent |
| 157 | +After=network.target |
| 158 | + |
| 159 | +[Service] |
| 160 | +Type=simple |
| 161 | +User=promptpipe |
| 162 | +WorkingDirectory=/opt/promptpipe/python/langchain |
| 163 | +Environment="OPENAI_API_KEY=your_key_here" |
| 164 | +Environment="PROMPTPIPE_STATE_DIR=/var/lib/promptpipe" |
| 165 | +ExecStart=/usr/local/bin/uv run uvicorn promptpipe_agent.api.main:app --host 0.0.0.0 --port 8001 |
| 166 | +Restart=always |
| 167 | + |
| 168 | +[Install] |
| 169 | +WantedBy=multi-user.target |
| 170 | +``` |
| 171 | + |
| 172 | +### Go Service |
| 173 | + |
| 174 | +Create `/etc/systemd/system/promptpipe.service`: |
| 175 | + |
| 176 | +```ini |
| 177 | +[Unit] |
| 178 | +Description=PromptPipe Go Service |
| 179 | +After=network.target promptpipe-agent.service |
| 180 | +Requires=promptpipe-agent.service |
| 181 | + |
| 182 | +[Service] |
| 183 | +Type=simple |
| 184 | +User=promptpipe |
| 185 | +WorkingDirectory=/opt/promptpipe |
| 186 | +Environment="PYTHON_AGENT_URL=http://localhost:8001" |
| 187 | +ExecStart=/opt/promptpipe/build/promptpipe |
| 188 | +Restart=always |
| 189 | + |
| 190 | +[Install] |
| 191 | +WantedBy=multi-user.target |
| 192 | +``` |
| 193 | + |
| 194 | +### Enable and Start Services |
| 195 | + |
| 196 | +```bash |
| 197 | +sudo systemctl daemon-reload |
| 198 | +sudo systemctl enable promptpipe-agent promptpipe |
| 199 | +sudo systemctl start promptpipe-agent |
| 200 | +sudo systemctl start promptpipe |
| 201 | +``` |
| 202 | + |
| 203 | +## Health Checks |
| 204 | + |
| 205 | +### Python Agent |
| 206 | + |
| 207 | +```bash |
| 208 | +curl http://localhost:8001/health |
| 209 | +# Should return: {"status":"healthy","version":"0.1.0"} |
| 210 | +``` |
| 211 | + |
| 212 | +### Go Service |
| 213 | + |
| 214 | +```bash |
| 215 | +curl http://localhost:8080/health |
| 216 | +# Should return health status |
| 217 | +``` |
| 218 | + |
| 219 | +## Monitoring |
| 220 | + |
| 221 | +### Logs |
| 222 | + |
| 223 | +```bash |
| 224 | +# Python Agent logs |
| 225 | +journalctl -u promptpipe-agent -f |
| 226 | + |
| 227 | +# Go Service logs |
| 228 | +journalctl -u promptpipe -f |
| 229 | +``` |
| 230 | + |
| 231 | +### Metrics |
| 232 | + |
| 233 | +Both services expose health endpoints for monitoring: |
| 234 | + |
| 235 | +- Python Agent: `http://localhost:8001/health` |
| 236 | +- Go Service: `http://localhost:8080/health` |
| 237 | + |
| 238 | +## Troubleshooting |
| 239 | + |
| 240 | +### Python Agent Not Starting |
| 241 | + |
| 242 | +1. Check OpenAI API key is set |
| 243 | +2. Verify state directory exists and is writable |
| 244 | +3. Check logs for errors |
| 245 | + |
| 246 | +```bash |
| 247 | +journalctl -u promptpipe-agent -n 50 |
| 248 | +``` |
| 249 | + |
| 250 | +### Go Service Can't Connect to Python |
| 251 | + |
| 252 | +1. Verify Python Agent is running |
| 253 | +2. Check PYTHON_AGENT_URL is correct |
| 254 | +3. Test connection: |
| 255 | + |
| 256 | +```bash |
| 257 | +curl http://localhost:8001/process-message -X POST \ |
| 258 | + -H "Content-Type: application/json" \ |
| 259 | + -d '{"participant_id":"test","message":"hello","phone_number":"+15551234567"}' |
| 260 | +``` |
| 261 | + |
| 262 | +### Database Issues |
| 263 | + |
| 264 | +Both services share the same SQLite database. Ensure: |
| 265 | + |
| 266 | +1. Directory permissions are correct |
| 267 | +2. Only one process writes at a time |
| 268 | +3. Database file is not corrupted |
| 269 | + |
| 270 | +```bash |
| 271 | +sqlite3 /var/lib/promptpipe/state.db "PRAGMA integrity_check;" |
| 272 | +``` |
| 273 | + |
| 274 | +## Production Considerations |
| 275 | + |
| 276 | +### Security |
| 277 | + |
| 278 | +1. Use HTTPS for production |
| 279 | +2. Set up proper firewall rules |
| 280 | +3. Use environment variables for secrets |
| 281 | +4. Limit API access to internal network |
| 282 | + |
| 283 | +### Performance |
| 284 | + |
| 285 | +1. Use PostgreSQL instead of SQLite for high traffic |
| 286 | +2. Add Redis for caching |
| 287 | +3. Use multiple Python workers: |
| 288 | + |
| 289 | +```bash |
| 290 | +uv run gunicorn promptpipe_agent.api.main:app \ |
| 291 | + -w 4 \ |
| 292 | + -k uvicorn.workers.UvicornWorker \ |
| 293 | + --bind 0.0.0.0:8001 |
| 294 | +``` |
| 295 | + |
| 296 | +### Backup |
| 297 | + |
| 298 | +Backup the shared database regularly: |
| 299 | + |
| 300 | +```bash |
| 301 | +# Create backup |
| 302 | +sqlite3 /var/lib/promptpipe/state.db ".backup '/backup/state-$(date +%Y%m%d).db'" |
| 303 | + |
| 304 | +# Restore backup |
| 305 | +sqlite3 /var/lib/promptpipe/state.db ".restore '/backup/state-20250128.db'" |
| 306 | +``` |
| 307 | + |
| 308 | +## Scaling |
| 309 | + |
| 310 | +For high traffic, consider: |
| 311 | + |
| 312 | +1. Load balancing multiple Python Agent instances |
| 313 | +2. Shared PostgreSQL database |
| 314 | +3. Redis for session/state caching |
| 315 | +4. Kubernetes deployment with HPA |
| 316 | + |
| 317 | +Example Kubernetes scaling: |
| 318 | + |
| 319 | +```yaml |
| 320 | +apiVersion: autoscaling/v2 |
| 321 | +kind: HorizontalPodAutoscaler |
| 322 | +metadata: |
| 323 | + name: python-agent-hpa |
| 324 | +spec: |
| 325 | + scaleTargetRef: |
| 326 | + apiVersion: apps/v1 |
| 327 | + kind: Deployment |
| 328 | + name: python-agent |
| 329 | + minReplicas: 2 |
| 330 | + maxReplicas: 10 |
| 331 | + metrics: |
| 332 | + - type: Resource |
| 333 | + resource: |
| 334 | + name: cpu |
| 335 | + target: |
| 336 | + type: Utilization |
| 337 | + averageUtilization: 70 |
| 338 | +``` |
0 commit comments