|
| 1 | +# Call Center AI - Developer Guide |
| 2 | + |
| 3 | +This is an AI-powered call center solution built with FastAPI, Azure Communication Services, and Azure OpenAI. The system handles real-time phone calls with intelligent conversation flow, claim processing, and multi-modal communication. |
| 4 | + |
| 5 | +## Architecture Overview |
| 6 | + |
| 7 | +The application follows a **modular, event-driven architecture** with clear separation between: |
| 8 | + |
| 9 | +- **Event handlers** (`app/helpers/call_events.py`) - Process Communication Services webhooks |
| 10 | +- **LLM orchestration** (`app/helpers/llm_worker.py`, `app/helpers/call_llm.py`) - Manage AI conversations |
| 11 | +- **Persistence layer** (`app/persistence/`) - Abstract interfaces for storage (Cosmos DB, Redis, AI Search) |
| 12 | +- **Models** (`app/models/`) - Pydantic models for data validation and serialization |
| 13 | + |
| 14 | +Key architectural patterns: |
| 15 | + |
| 16 | +- **Interface-based design**: All persistence layers implement abstract base classes (e.g., `ICache`, `IStore`, `ISearch`) |
| 17 | +- **Configuration-driven**: Single YAML config file drives all Azure resource connections |
| 18 | +- **Async-first**: Uses `asyncio`, `aiohttp`, and async Azure SDKs throughout |
| 19 | +- **Telemetry integration**: OpenTelemetry spans wrap all major operations |
| 20 | + |
| 21 | +## Core Data Flow |
| 22 | + |
| 23 | +1. **Inbound calls** → Azure Communication Services → Event Grid → FastAPI webhooks (`/webhook/*`) |
| 24 | +2. **Real-time audio** → WebSocket streaming → Speech-to-Text → LLM processing → Text-to-Speech |
| 25 | +3. **Conversation state** stored in `CallStateModel` → persisted to Cosmos DB |
| 26 | +4. **Claims data** extracted via LLM tools → structured in configurable schema |
| 27 | + |
| 28 | +## Development Workflow |
| 29 | + |
| 30 | +### Local Development |
| 31 | + |
| 32 | +```bash |
| 33 | +# Setup environment (uses uv for Python package management) |
| 34 | +make install |
| 35 | + |
| 36 | +# Run locally with auto-reload |
| 37 | +make dev |
| 38 | + |
| 39 | +# Sync remote Azure config to local |
| 40 | +make name=my-rg-name sync-local-config |
| 41 | +``` |
| 42 | + |
| 43 | +### Configuration Management |
| 44 | + |
| 45 | +- **Local**: `config.yaml` (copy from `config-local-example.yaml`) |
| 46 | +- **Remote**: Azure App Configuration + environment variables |
| 47 | +- **Validation**: Pydantic models in `app/helpers/config_models/` |
| 48 | + |
| 49 | +### Testing Patterns |
| 50 | + |
| 51 | +- **Unit tests**: Mock Azure clients using custom mock classes (see `tests/conftest.py`) |
| 52 | +- **LLM evaluation**: Uses DeepEval for conversation quality assessment |
| 53 | +- **Async testing**: `pytest-asyncio` for async test functions |
| 54 | + |
| 55 | +## Key Components to Understand |
| 56 | + |
| 57 | +### Event-Driven Call Handling |
| 58 | + |
| 59 | +- `on_call_connected()` - Initiates conversation flow |
| 60 | +- `on_automation_recognize_error()` - Handles speech recognition failures with retry logic |
| 61 | +- `on_audio_connected()` - Starts real-time audio streaming for low-latency responses |
| 62 | + |
| 63 | +### LLM Integration |
| 64 | + |
| 65 | +- **Dual LLM strategy**: Fast model (`gpt-4.1-nano`) for real-time, slow model (`gpt-4.1`) for complex reasoning |
| 66 | +- **Tool calling**: LLM can execute predefined functions for claim updates, SMS sending, call transfers |
| 67 | +- **Context management**: Conversation history maintained in `CallStateModel.messages` |
| 68 | + |
| 69 | +### Audio Processing |
| 70 | + |
| 71 | +- **Noise reduction**: `noisereduce` library for audio cleanup |
| 72 | +- **Multi-language TTS**: Azure Cognitive Services with voice selection based on conversation language |
| 73 | +- **Streaming optimizations**: Audio chunks processed in real-time to minimize latency |
| 74 | + |
| 75 | +## Deployment & Infrastructure |
| 76 | + |
| 77 | +### Azure Resources (Bicep) |
| 78 | + |
| 79 | +- **Core**: `cicd/bicep/main.bicep` → `app.bicep` (modular deployment) |
| 80 | +- **Container deployment**: GitHub Actions builds container → Azure Container Apps |
| 81 | +- **Resource naming**: Uses sanitized instance names with consistent tagging |
| 82 | + |
| 83 | +### Makefile Commands |
| 84 | + |
| 85 | +```bash |
| 86 | +make deploy name=my-rg-name # Deploy to Azure |
| 87 | +make logs name=my-rg-name # View application logs |
| 88 | +make version # Get semantic version |
| 89 | +make tunnel-create # Setup dev tunnel for webhooks |
| 90 | +``` |
| 91 | + |
| 92 | +## Project-Specific Conventions |
| 93 | + |
| 94 | +### Code Organization |
| 95 | + |
| 96 | +- **Helpers**: Pure functions and utilities, no state management |
| 97 | +- **Models**: Pydantic models with validation, used for API contracts and database schemas |
| 98 | +- **Persistence**: Interface implementations, each Azure service has its own module |
| 99 | + |
| 100 | +### Error Handling |
| 101 | + |
| 102 | +- **Graceful degradation**: Call continues even if non-critical services fail |
| 103 | +- **Retry logic**: Uses `tenacity` for resilient external service calls |
| 104 | +- **Structured logging**: `structlog` with OpenTelemetry correlation IDs |
| 105 | + |
| 106 | +### Configuration Validation |
| 107 | + |
| 108 | +All config is validated at startup using Pydantic. Missing or invalid Azure credentials cause immediate startup failure with clear error messages. |
| 109 | + |
| 110 | +## Integration Points |
| 111 | + |
| 112 | +- **Azure Communication Services**: Call automation, SMS, phone number management |
| 113 | +- **Azure OpenAI**: Dual deployment strategy (fast/slow models) with embedding search |
| 114 | +- **Azure AI Search**: RAG for training data and knowledge base |
| 115 | +- **Azure Cosmos DB**: Conversation persistence with partitioning by phone number |
| 116 | +- **Redis**: Caching layer for frequently accessed data and session state |
| 117 | + |
| 118 | +## Development Tips |
| 119 | + |
| 120 | +- **Mock Azure services** in tests using the patterns in `tests/conftest.py` |
| 121 | +- **Use async context managers** for resource cleanup (see `@asynccontextmanager` in `main.py`) |
| 122 | +- **Follow the interface pattern** when adding new persistence layers |
| 123 | +- **Test conversation flows** using the YAML-based conversation definitions in `tests/conversations.yaml` |
0 commit comments