harikavaleti/Call-Center-Intelligence-System

GitHub: harikavaleti/Call-Center-Intelligence-System

基于多 Agent 编排的呼叫中心智能分析系统,自动完成语音转写、PII 脱敏、合规检测和五维度质量评分,将人工质检覆盖率从5%提升到100%。

Stars: 0 | Forks: 0

# 🎯 呼叫中心智能系统 [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/) [![测试](https://img.shields.io/badge/tests-394%2B%20passing-brightgreen.svg)](#testing) [![许可证: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) ## 📋 目录 - [这是什么项目?](#-what-is-this-project) - [我们正在解决的问题](#-the-problem-were-solving) - [工作原理](#-how-it-works) - [系统架构](#-system-architecture) - [技术栈及选择原因](#-tech-stack--why-each-choice) - [项目结构](#-project-structure) - [快速开始](#-quick-start) - [配置](#-configuration) - [UI 规范](#-ui-specification) - [使用指南](#-usage-guide) - [测试](#-testing) - [Docker 部署](#-docker-deployment) - [GPU 部署](#-gpu-deployment) - [关键设计决策](#-key-design-decisions) - [数据模型](#-data-models) - [安全特性](#-security-features) - [QA 评分系统](#-qa-scoring-system) - [可观测性](#-observability) - [故障排除](#-troubleshooting) - [未来扩展](#-future-expansion) - [API 参考](#-api-reference) ## 🎯 这是什么项目? 这是一个**生产级 Web 应用程序**,它接收原始的呼叫中心录音并自动生成: | 输出 | 描述 | |--------|-------------| | 🎙️ **带说话人标签的录音文本** | 坐席 vs. 客户,包含 `[MM:SS]` 时间戳和置信度标记 | | 📝 **执行摘要** | 通话目的、关键讨论点、行动项、情绪轨迹 | | 📊 **质量记分卡** | 5 维度加权评分(每项 1-5 分)及评分理由 | | 🚨 **合规报告** | 带有严重程度级别的违规标记(低 → 严重) | | 📄 **可下载报告** | 每次分析的通话均可生成 PDF 和 JSON 产物 | | 📈 **可观测性仪表盘** | Pipeline 健康指标、审计日志、LangSmith 追踪状态 | 把它想象成替代那些人工听取录音并填写记分卡的 QA 审核员——但它能处理 **100% 的通话**而不是 5%,在几分钟内完成**而不是每通电话需要 15 分钟**,并提供**确定且可审计的评分**。 ## 🔥 我们正在解决的问题 一个中型呼叫中心每天处理约 5,000 通电话。QA 团队人工审核的通话不到 5%,每次审核大约花费 15 分钟。这造成了三个系统性故障: | 故障 | 影响 | 我们的解决方案 | |---------|--------|-------------| | **覆盖盲区** — 95% 的通话未被审核 | 坐席错误和指导机会未被发现 | 自动分析每一通电话 | | **一致性差距** — 人工审核员的一致性仅为 40-60% | 不公平的评分,无法经受监管审查 | 确定性加权公式(可复现,可审计) | | **延迟差距** — 审核在几天后才暴露问题 | 进行指导、纠正或防止损害为时已晚 | 数分钟内实时分析 | ### 解决的其他痛点 - **人工 QA 无法扩展** — 自动化系统只需几分钟即可完成,且成本仅为一小部分 - **通用 LLM 会产生幻觉** — 我们的系统将所有分析立足于实际的录音文本证据 - **单体系统容易崩溃** — 7 个边界清晰的专业 Agent 更可靠且易于测试 - **没有审计跟踪** — 每个 Pipeline 事件都带有时间戳记录到只追加的审计表中 - **没有成本控制** — 多 Provider 工厂模式允许您通过一个环境变量从 $0.03/通话 切换到 $0/通话 ## ⚙️ 工作原理 当您上传音频文件并点击 "Analyze Call" 时,系统会运行由 LangGraph 状态机编排的 **7 个顺序 Pipeline 阶段**: ``` ┌─────────────────────────────────────────────────────────────────────┐ │ USER UPLOADS AUDIO │ └──────────────────────────────┬──────────────────────────────────────┘ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ STAGE 1: INTAKE VALIDATION │ │ • Detect format by magic bytes (first 12 bytes, not file extension)│ │ • Reject if >50MB or >60 minutes │ │ • Extract audio properties (duration, sample rate, channels) │ │ • Scan metadata (caller_id, department) for PII │ │ • Write validated audio to temp file │ ├──────────────────────────────┬───────────────────────────────────────┤ │ ✅ Valid │ ❌ Invalid → ERROR NODE │ └──────────────────────────────┼───────────────────────────────────────┘ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ STAGE 2: TRANSCRIPTION (faster-whisper) │ │ • Check SHA-256 cache → return instantly if seen before │ │ • Whisper model loaded once as singleton (never per-request) │ │ • Greedy decoding (beam_size=1), VAD filtering, no prev text cond │ │ • Heuristic speaker diarization (Agent/Customer) │ │ • Clean artifacts: BLANK_AUDIO, repeated phrases, YouTube footers │ │ • Compute per-segment confidence from avg_logprob + no_speech_prob │ │ • Cache result by SHA-256 hash for future lookups │ └──────────────────────────────┬───────────────────────────────────────┘ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ STAGE 3: PROMPT INJECTION DETECTION │ │ • Scan transcript against 22+ regex patterns │ │ • Covers: ignore-instructions, role-switching, DAN mode, │ │ system-tag injection, jailbreak, conversation injection, etc. │ │ • If detected → route to ERROR NODE (no LLM ever sees the text) │ ├──────────────────────────────┬───────────────────────────────────────┤ │ ✅ Clean │ ❌ Injection → ERROR NODE │ └──────────────────────────────┼───────────────────────────────────────┘ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ STAGE 4: PII REDACTION │ │ • Detect SSN, credit card, email, phone in transcript │ │ • Replace with labeled placeholders: [REDACTED_SSN], etc. │ │ • Right-to-left replacement to preserve string positions │ │ • Applied to BOTH full_text AND every individual segment │ │ • ⚠️ LLM NEVER sees raw PII — this runs BEFORE any LLM call │ └──────────────────────────────┬───────────────────────────────────────┘ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ STAGE 5: SUMMARIZATION (LLM) │ │ • Extract: call_purpose, key_discussion_points (3-7 items), │ │ action_items (with owner + deadline), resolution_status, │ │ sentiment_trajectory, named entities │ │ • Structured output validated by Pydantic SummaryResult model │ │ • Exponential backoff retry (up to 3 attempts) │ └──────────────────────────────┬───────────────────────────────────────┘ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ STAGE 6: QA SCORING (LLM) │ │ • Receives transcript + summary context for better accuracy │ │ • Scores 5 weighted dimensions (1-5 each) with justifications │ │ • Identifies compliance flags with severity levels │ │ • ⚠️ overall_score ALWAYS recomputed by weighted formula │ │ (LLM's own overall score is DISCARDED — deterministic guardrail) │ ├──────────────────────────────┬───────────────────────────────────────┤ │ No critical flags│ 🚨 Critical flag → SUPERVISOR NODE │ └──────────────────────────────┼───────────────────────────────────────┘ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ STAGE 7: REPORT GENERATION │ │ • Compile CallReport from all upstream results │ │ • Generate PDF report (ReportLab) with summary, scores, flags │ │ • Generate JSON report (Pydantic serialization) │ │ • Persist to SQLite (call record, audit log, transcription cache) │ │ • Return downloadable artifacts to the UI │ └──────────────────────────────────────────────────────────────────────┘ ``` ### 终端节点 - **Error Node**:捕获任何阶段的故障,记录错误,将状态设置为 `"failed"` - **Supervisor Review Node**:当任何合规性标记的 `severity == "critical"` 时触发,将状态设置为 `"flagged_for_review"` ## 🏗️ 系统架构 ### 五层架构 代码库在 `src/` 下组织成五个清晰的层,每层具有单一职责: ``` call-center-intelligence/ │ ├── app.py # Thin ~50-line entrypoint │ ├── src/ │ ├── agents/ # 🤖 Pipeline Stage Logic │ │ ├── intake.py # Audio validation & metadata scanning │ │ ├── transcription.py # faster-whisper + diarization + SHA-256 cache │ │ ├── summarization.py # LLM summarization with structured output │ │ ├── qa_scoring.py # LLM QA scoring + deterministic recomputation │ │ └── report.py # PDF/JSON generation + database persistence │ │ │ ├── graph/ # 🔀 LangGraph Orchestration │ │ ├── state.py # 14 Pydantic models + PipelineState TypedDict │ │ ├── edges.py # Conditional routing functions │ │ └── workflow.py # StateGraph definition + node wiring │ │ │ ├── security/ # 🔒 Security Components │ │ ├── injection_detector.py # 22+ regex patterns for prompt injection │ │ ├── pii_redactor.py # SSN, credit card, email, phone redaction │ │ └── audit.py # Append-only audit event logger │ │ │ ├── services/ # 🔧 Business Logic Layer │ │ ├── pipeline.py # Gradio ↔ pipeline bridge + temp file mgmt │ │ ├── observability.py # Dashboard metrics queries │ │ └── history.py # Call history browsing │ │ │ ├── database/ # 💾 Persistence Layer │ │ ├── models.py # SQLAlchemy ORM (3 tables) │ │ └── connection.py # Engine, session factory, session_scope │ │ │ ├── ui/ # 🖥️ Gradio Interface │ │ ├── theme.py # Custom CSS theme (dark/light mode) │ │ ├── html_formatters.py # HTML rendering helpers (metric cards, tables, etc.) │ │ └── tabs/ │ │ ├── analyze.py # "🎙️ Analyze Call" tab │ │ ├── history.py # "📋 Call History" tab │ │ └── observability.py # "📊 Observability" tab │ │ │ └── utils/ # 🛠️ Shared Utilities │ ├── config.py # Environment variable loader (frozen dataclass) │ ├── audio.py # Magic-byte detection, validation, properties │ ├── llm_factory.py # Multi-provider LLM factory │ └── formatters.py # Markdown formatters for UI display │ ├── tests/ # ✅ 394+ Automated Tests │ ├── conftest.py # Shared fixtures (db_engine, make_wav_bytes) │ ├── unit/ # Agent, model, formatter, edge tests │ ├── integration/ # End-to-end pipeline, database tests │ ├── security/ # PII format coverage, injection pattern tests │ └── scenarios/ # 53 tests × 15 real-world pipeline path scenarios │ ├── data/ # 📁 Runtime Data (gitignored) │ ├── samples/ # Sample audio files for testing │ └── calls.db # SQLite database (created at runtime) │ ├── Dockerfile # 🐳 Container deployment ├── Makefile # 🔨 Build/test/run targets ├── .env.example # 📋 Environment variable template ├── .gitignore # 🚫 Exclusion rules ├── pyproject.toml # 📦 Project metadata + dependencies └── requirements.txt # 📦 Pinned dependencies ``` ### 数据库 Schema (3 个表) | 表 | 目的 | 关键列 | |-------|---------|-------------| | `call_records` | 主要分析结果 | `call_id` (unique), `status`, `transcript_text`, `summary_json`, `qa_scores_json`, `report_json`, `processed_at` | | `transcription_cache` | SHA-256 音频哈希 → 缓存的录音文本 | `audio_hash` (unique), `transcription_json`, `created_at` | | `audit_log` | 只追加的 Pipeline 事件日志 | `call_id`, `action`, `user`, `timestamp`, `details` (JSON) | ## 🛠️ 技术栈及选择原因 | 层 | 技术 | 为什么选择它而不是替代方案 | |-------|-----------|---------------------------| | **语言** | Python 3.11+ | AI/ML 生态系统成熟;所有库均支持 | | **编排** | LangGraph 0.4+ | 具有条件路由、错误隔离和 LangSmith 追踪的类型化状态机——相比之下,普通函数链无法进行分支或隔离故障 | | **语音转文本** | faster-whisper | 通过 CTranslate2 int8 量化比原版 Whisper 快 2-4 倍。在每天 5,000 通电话的情况下,这是仅需 CPU 部署与需要 GPU 之间的区别 | | **LLM (付费)** | GPT-4o via langchain-openai | 最佳的结构化输出质量(约 $0.03/通话) | | **LLM (免费)** | Gemini 2.0 Flash via langchain-google-genai | 每天 1,500 次免费请求;良好的结构化输出支持 | | **LLM (免费)** | Groq Llama 3.3 70B via langchain-groq | 免费层级 30 RPM;免费层级中最快的推理速度 | | **音频解析** | mutagen | 可靠的 MP3/FLAC/M4A 元数据提取 | | **数据模型** | Pydantic v2 | 阶段之间有 14 个类型化契约;结构化 LLM 输出验证可捕获格式错误的 AI 响应 | | **数据库** | SQLite + SQLAlchemy | 单文件持久化,零设置,通过 cached sessionmaker 进行连接池管理 | | **Web UI** | Gradio 5.x | 具有音频上传、Markdown 渲染、文件下载的多标签界面 | | **PDF 报告** | ReportLab | 程序化 PDF 生成,无外部依赖 | | **可观测性** | LangSmith (可选) | 记录每个 LLM 调用的完整追踪,包含 token 计数和延迟 | | **测试** | pytest | 跨单元/集成/安全套件的 335+ 项测试,带有 fixtures 和 parametrize | | **Linting** | ruff | 快速的 Python 代码检查和自动格式化 | ## 🚀 快速开始 ### 前置条件 - **Python 3.11+**(也支持 Python 3.12;3.13 尚未被所有音频依赖项支持) - **ffmpeg** 已安装在您的系统上(用于音频处理) - macOS: `brew install ffmpeg` - Ubuntu: `sudo apt-get install ffmpeg` - Windows: 从 https://ffmpeg.org/download.html 下载 - **至少一个 LLM API 密钥**(参见[配置](#-configuration)) ### 选项 1: 快速设置 ``` # 克隆仓库 git clone cd call-center-intelligence # 创建虚拟环境 python3 -m venv venv source venv/bin/activate # macOS/Linux # venv\Scripts\activate # Windows # 安装依赖 pip install -r requirements.txt # 配置环境 cp .env.example .env # 使用你的 API key(s) 编辑 .env —— 见下方的配置部分 # 运行应用 python app.py # 在 http://localhost:7860 打开 ``` ### 选项 2: 使用 Make ``` make install # Creates venv + installs everything cp .env.example .env # 使用你的 API key(s) 编辑 .env make run # Starts the app ``` ### 选项 3: 使用 Docker ``` docker build -t call-center-intelligence . docker run -p 7860:7860 --env-file .env call-center-intelligence # 在 http://localhost:7860 打开 ``` ## ⚙️ 配置 ### 环境变量 将 `.env.example` 复制到 `.env` 并进行配置: ``` cp .env.example .env ``` #### 必填项: LLM Provider (选择其一) | 变量 | 描述 | 如何获取 | |----------|-------------|-----------| | `LLM_PROVIDER` | 要使用的 Provider:`openai`、`gemini` 或 `groq` | 根据您拥有的密钥进行设置 | | `OPENAI_API_KEY` | OpenAI API 密钥(约 $0.03/通话) | https://platform.openai.com/api-keys | | `GOOGLE_API_KEY` | Gemini API 密钥(免费:1,500 次/天) | https://aistudio.google.com | | `GROQ_API_KEY` | Groq API 密钥(免费:30 RPM) | https://console.groq.com | #### 可选项: Whisper 配置 | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `WHISPER_MODEL_SIZE` | `tiny` | 模型大小:`tiny` (39MB,快速), `base` (74MB), `small`, `medium`, `large-v3` (1.5GB,需要 GPU) | | `CONFIDENCE_THRESHOLD` | `0.6` | 低于此置信度的片段将被标记为 `[LOW CONF]` | | `LOW_CONFIDENCE_HALT_RATIO` | `0.5` | 如果超过 50% 的片段置信度较低,则标记整通电话 | #### 可选项: Pipeline & 数据库 | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `DB_PATH` | `data/calls.db` | SQLite 数据库文件路径 | | `DB_ENCRYPTION_KEY` | _(空)_ | 可选的 SQLite 加密密钥 | | `MAX_RETRIES_PER_NODE` | `3` | 每次 LLM 调用的最大重试次数(带有指数退避) | | `LLM_TIMEOUT_SECONDS` | `60` | 每次 LLM API 调用的超时时间(如果发生超时,请增加到 120) | #### 可选项: LangSmith 可观测性 | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `LANGCHAIN_TRACING_V2` | `false` | 启用 LangSmith 追踪 (`true`/`false`) | | `LANGCHAIN_API_KEY` | _(空)_ | 来自 https://smith.langchain.com 的 LangSmith API 密钥 | | `LANGCHAIN_PROJECT` | `call-center-intelligence` | LangSmith 项目名称 | ### 切换 LLM Provider 在 `.env` 中更改一行——零代码修改: ``` # 使用 OpenAI GPT-4o (~$0.03/调用, 最佳质量) LLM_PROVIDER=openai # 使用 Gemini 2.0 Flash (免费, 1,500 次请求/天) LLM_PROVIDER=gemini # 使用 Groq Llama 3.3 70B (免费, 30 RPM, 最快推理) LLM_PROVIDER=groq ``` ## 🖥️ UI 规范 应用程序提供了一个带有深色/浅色主题切换的**三标签 Gradio 界面**。每个标签服务于不同的用户工作流。以下是每个 UI 元素、其功能及使用方法的详细规范。 ### 应用程序标题 | 元素 | 描述 | |---------|-------------| | **🎯 Call Center Intelligence System** | 应用程序标题 | | **AI-powered call quality analysis** | 副标题 | | **🌙 / ☀️ 切换** | 点击以在深色模式和浅色模式之间切换 | ### 标签 1: 🎙️ Analyze Call **目的**:上传或录制通话录音并运行完整的 AI 分析 Pipeline。 #### 左侧面板 — 输入控件 | 元素 | 类型 | 描述 | 必填 | |---------|------|-------------|----------| | **Upload Audio** | 文件上传 / 麦克风 | 接受最大 50MB、60 分钟的 WAV、MP3、FLAC、M4A 文件。也支持实时麦克风录音。 | ✅ 是 | | **Caller ID** | 文本输入 | 呼叫者的可选标识符(例如,`CUST-48291`)。用于跟踪。⚠️ 请勿输入真实的 SSN 或信用卡——PII 扫描会将其标记出来。 | ❌ 可选 | | **Department** | 文本输入 | 可选的部门名称(例如,`Billing Support`)。与通话记录一起存储以用于过滤。 | ❌ 可选 | | **🔍 Analyze Call** | 按钮 (主要) | 启动 7 阶段分析 Pipeline。处理期间禁用。 | — | | **Pipeline Progress** | 状态面板 | 显示所有 7 个阶段的实时进度,带有绿/黄/灰点及每个阶段的耗时。 | — | #### 右侧面板 — 分析结果 (5 个子标签) 点击 "Analyze Call" 后,结果将显示在这些子标签中: ##### 📝 Transcript 子标签 | 元素 | 描述 | |---------|-------------| | **聊天气泡** | 带有说话人标签的对话,包含坐席(绿色)和客户(琥珀色)气泡 | | **时间戳** | 个气泡上的 `[MM:SS]` 时间戳 | | **置信度标记** | 置信度低于阈值的片段上的 `[LOW CONF]` 徽章 | | **PII 徽章** | `[REDACTED_SSN]`、`[REDACTED_CREDIT_CARD]` 等显示为高亮徽章 | | **录音文本统计** | 总片段数、平均置信度、检测到的语言 | ##### 📋 Summary 子标签 | 元素 | 描述 | |---------|-------------| | **Call Purpose** | 客户致电原因的一句话描述 | | **Key Discussion Points** | 涵盖主要主题的 3-7 个要点 | | **Action Items** | 包含描述、负责人 (坐席/客户) 和截止日期的表格 | | **Resolution Status** | 药丸形徽章:`Resolved` (绿色), `Unresolved` (红色), 或 `Escalated` (琥珀色) | | **Sentiment Trajectory** | 显示情绪轨迹的箭头表示法(例如,"Frustrated → Satisfied") | | **Named Entities** | 提及的公司、产品、人物及其上下文 | ##### 📊 QA Scorecard 子标签 | 元素 | 描述 | |---------|-------------| | **Overall Score** | 大号数字(例如,`3.8 / 5.0`),由确定性加权公式计算得出 | | **Formula badge** | 显示 "weighted formula" 以表明分数是确定性的,而不是 LLM 生成的 | | **Dimension bars** | 5 个带有分数的水平进度条: | | | • **Problem Resolution (30%)** — 问题是否得到解决? | | | • **Empathy (20%)** — 坐席是否表现出理解? | | | • **Compliance (20%)** — 是否遵守了程序? | | | • **Professionalism (15%)** — 坐席是否礼貌? | | | • **Communication Clarity (15%)** — 坐席表达是否清晰? | | **Color coding** | 每个维度条的颜色:绿色 (4-5),琥珀色 (3),红色 (1-2) | | **Justifications** | 每个维度分数的文本解释 | ##### 🛡️ Compliance 子标签 | 元素 | 描述 | |---------|-------------| | **Compliance flags** | 带有严重程度颜色边框的卡片: | | | • 🔴 **CRITICAL** — 红色边框(例如,"Skipped identity verification") | | | • 🟠 **HIGH** — 橙色边框(例如,"Didn't confirm refund amount") | | | • 🟡 **MEDIUM** — 琥珀色边框 | | | • ⚪ **LOW** — 灰色边框 | | **Timestamp references** | 每个标记包含发生违规的 `[MM:SS]` 范围 | | **No flags message** | 当通话没有问题时显示 "No compliance issues detected" | ##### ⬇️ Download 子标签 | 元素 | 描述 | |---------|-------------| | **📄 PDF Report** | 可下载的 PDF,包含完整分析(摘要、分数、标记、录音文本摘录) | | **📋 JSON Report** | 可下载的 JSON,包含所有结构化数据以便于编程访问 | ### 标签 2: 📋 Call History **目的**:浏览、搜索和查看所有以前分析过的通话。 #### 顶部控件 | 元素 | 类型 | 描述 | |---------|------|-------------| | **Search** | 文本输入 | 按通话 ID、文件名或部门搜索。实时过滤列表。 | | **Outcome** | 下拉菜单 | 过滤依据:`All outcomes`、`Completed`、`Failed`、`Flagged for review` | #### 左侧面板 — 通话列表 | 元素 | 描述 | |---------|-------------| | **Source icon** | 📁 = 上传的文件, 🎤 = 通过麦克风录制 | | **Call ID** | 唯一标识符(显示前 20 个字符) | | **Filename & timestamp** | 原始文件名和处理日期 | | **Status pill** | 颜色编码:`Report generated` (绿色), `Error` (红色), `Supervisor review` (琥珀色) | | **QA Score** | 满分 5 分的得分(例如,`3.1/5`),如果分析失败则为 `N/A` | | **Pagination** | `← Prev` / `Next →` 按钮带有页码和总计数 | | **🔄 Refresh List** | 重新加载通话列表(切换到此标签时自动刷新) | #### 右侧面板 — 通话详情 | 元素 | 描述 | |---------|-------------| | **Select Call ID** | 从当前列表中选择通话的下拉菜单 | | **Header** | 通话 ID + 状态药丸 + 文件名 + 处理时间戳 | | **Transcript Preview** | 录音文本的前约 300 个字符(等宽字体,可滚动) | | **QA Scorecard** | 与 Analyze 标签相同的 5 维度条形图,带有总分 | | **Compliance Flags** | 严重程度颜色编码的标记卡片(格式与 Analyze 标签相同) | ### 标签 3: 📊 Observability **目的**:监控 Pipeline 健康状况,查看聚合分析,并查看审计日志。 #### 指标卡片 (顶行 — 4 张卡片) | 卡片 | 描述 | 示例 | |------|-------------|---------| | **Total Calls Processed** | 曾分析过的所有通话计数 | `8` | | **Success Rate** | 成功完成的通话百分比 | `75.0%` | | **Avg QA Score** | 已完成通话的平均总体 QA 分数 | `2.62` | | **Compliance Flags** | 所有通话中的合规性标记总数 | `5` | #### 通话分析表 | 列 | 描述 | |--------|-------------| | **Call ID** | 唯一标识符 | | **Timestamp** | 通话处理的时间 | | **Source** | 📁 上传或 🎤 麦克风 | | **Status** | Completed / Failed / Flagged | | **QA Score** | 总体加权分数 | | **Compliance** | 标记数量或 "Clean" | #### 左侧面板 — Pipeline 健康状况 | 组件 | 状态 | 描述 | |-----------|--------|-------------| | **LangGraph pipeline** | 🟢 Active | 工作流引擎状态 | | **faster-whisper** | 🟢 Active | 语音转文本模型已加载 | | **LLM Provider** | 🟢 Active · openai/gemini/groq | 配置了哪个 LLM | | **SQLite database** | 🟢 Active · N records | 数据库连接 + 记录数 | | **LangSmith tracing** | 🟢 Enabled / 🔴 Disabled | 是否开启了可观测性追踪 | | **SHA-256 cache** | 🟢 Active | 录音文本缓存状态 | #### 左侧面板 — 阶段延迟 | 阶段 | 描述 | 典型耗时 | |-------|-------------|-------------| | **Intake & validation** | 音频格式检查、大小检查、PII 扫描 | ~0.3s | | **Transcription** | Whisper 语音转文本 | ~14s (CPU tiny 模型) | | **Injection detection** | 正则表达式模式扫描 | ~0.1s | | **PII redaction** | SSN/信用卡/电子邮件/电话替换 | ~0.2s | | **Summarization** | 用于摘要的 LLM 调用 | ~3.1s | | **QA scoring** | 用于评分的 LLM 调用 | ~3.8s | | **Report generation** | PDF/JSON + 数据库持久化 | ~0.8s | #### 右侧面板 — 审计日志 | 元素 | 描述 | |---------|-------------| | **20 most recent events** | Pipeline 事件的可滚动列表 | | **Color-coded entries** | 🟢 绿色边框 = 已完成,🔴 红色边框 = 失败/注入,🟡 琥珀色边框 = 已标记 | | **Timestamp** | 事件发生的时间 | | **Description** | 发生了什么(例如,"Pipeline completed", "Injection detected") | #### 控件 | 元素 | 描述 | |---------|-------------| | **🔄 Refresh Dashboard** | 重新加载所有指标、分析表、健康状态、延迟和审计日志 | ### 主题和样式 UI 使用具有以下功能的自定义 CSS 主题: | 特性 | 描述 | |---------|-------------| | **Dark mode** (默认) | 深色背景 (`#0f1419`),浅色文本,蓝色点缀 | | **Light mode** | 白色背景,深色文本,蓝色点缀 | | **Responsive** | 指标卡片在移动端从 4 列切换为 2 列 | | **Status pills** | 绿色 (已完成),红色 (失败),琥珀色 (已标记) | | **Score colors** | 绿色 (4-5),琥珀色 (3),红色 (1-2) | | **Chat bubbles** | 绿色 (坐席),琥珀色 (客户) | ## 📖 使用指南 ### 分步说明:分析通话 1. 在 `http://localhost:7860` **打开应用程序** 2. 点击 **🎙️ Analyze Call** 标签(默认选中) 3. **上传**音频文件(拖放或点击浏览)——或点击**麦克风图标**进行实时录制 4. 可选择填写 **Caller ID** 和 **Department** 5. 点击 **🔍 Analyze Call** 6. 观察 **Pipeline Progress** 面板——每个阶段完成时会亮起绿灯 7. 完成后(在 CPU 上约 1-2 分钟),结果将显示在 5 个子标签中: - 在 **Transcript**、**Summary**、**QA Scorecard**、**Compliance** 和 **Download** 之间切换 8. 从 ⬇️ Download 子标签下载 **PDF** 或 **JSON** 报告 ### 分步说明:查看通话历史 1. 点击 **📋 Call History** 标签 2. 通话列表会自动加载(或点击 **🔄 Refresh List**) 3. 使用 **Search** 按通话 ID、文件名或部门查找特定通话 4. 使用 **Outcome** 下拉菜单按状态进行过滤 5. 从右侧的下拉菜单中选择一个 **Call ID** 以查看完整详情 6. 查看 QA 记分卡、合规性标记和录音文本预览 ### 分步说明:监控 Pipeline 健康状况 1. 点击 **📊 Observability** 标签 2. 点击 **🔄 Refresh Dashboard** 以加载当前数据 3. 查看 **4 张指标卡片**以了解高层 KPI 4. 检查 **Call Analytics Table** 以获取每次通话的详细分解 5. 验证 **Pipeline Health** ——所有组件都应显示 🟢 Active 6. 查看 **Stage Latency** 以识别瓶颈 7. 检查 **Audit Log** 以获取最近事件和任何错误 ### 示例场景 | 场景 | 会发生什么 | |----------|-------------| | 上传有效的 5 分钟 MP3 | 完整分析:录音文本 → 摘要 → QA 分数 → PDF/JSON | | 客户读出信用卡号 | 该号码在 LLM 看到之前被替换为 `[REDACTED_CREDIT_CARD]` | | 坐席跳过身份验证 | CRITICAL 合规标记 → 路由至 Supervisor Review | | 音频包含 "Ignore all previous instructions" | 检测到注入 → Pipeline 阻止 → 返回错误 | | 上传 .ogg 文件 | 在接收阶段被拒绝并显示 "Unsupported format" 消息 | | 上传相同音频两次 | 第二次调用立即返回缓存的录音文本(SHA-256 匹配) | | 上传 60MB 文件 | 在接收阶段被拒绝——超出 50MB 限制 | | 上传 90 分钟的录音 | 在接收阶段被拒绝——超出 60 分钟限制 | | 坐席粗鲁,未解决问题 | 低 QA 分数 (< 3.0),每个维度都有详细的理由 | | 通话被升级至主管 | 摘要显示 `resolution_status: escalated` | ## ✅ 测试 ### 运行所有测试 (388+) ``` # 所有测试 — 无需 API keys (均为模拟) pytest tests/ -v # 包含覆盖率报告 pytest tests/ -v --cov=src --cov-report=term-missing ``` ### 运行特定套件 ``` # 单元测试 (agents, models, formatters, edges) pytest tests/unit/ -v # 安全测试 (PII 格式覆盖, 注入模式覆盖) pytest tests/security/ -v # 集成测试 (端到端 pipeline, 数据库持久化) pytest tests/integration/ -v # 场景测试 (happy path 之外的所有 pipeline 路径) pytest tests/scenarios/ -v ``` ### 使用 Make ``` make test # Unit + security tests (fast) make test-integration # Integration tests make test-all # Everything ``` ### 测试组织 | 套件 | 数量 | 涵盖范围 | |-------|-------|---------------| | `tests/unit/` | ~250+ | 所有 Agent (intake、transcription、summarization、QA、report)、Pydantic 模型验证、graph 路由边、显示格式化器 | | `tests/security/` | ~50+ | 单独测试 22+ 种注入模式、5+ 种电话格式、3+ 种电子邮件格式、2+ 种 SSN 格、3+ 种信用卡格式、嵌入在对话文本中的 PII | | `tests/integration/` | ~35+ | 带有模拟 LLM/Whisper 的端到端 Pipeline、通话记录和审计日志的数据库持久化 | | `tests/scenarios/` | 53 | 涵盖每条 Pipeline 路径的 15 个真实场景(见下表) | ### 场景测试覆盖 (53 项测试,15 个场景) 这些测试验证了**超出**正常路径(客户问题得到解决)的每条 Pipeline 路径: | # | 场景 | 测试数 | 测试的 Pipeline 路径 | |---|----------|-------|---------------------| | 1 | 无效音频文件 | 3 | 文本文件 → intake 拒绝 → 路由至 error | | 2 | 静音/空音频 | 3 | 静音 WAV → 通过 intake → 低置信度标记 | | 3 | Prompt 注入 | 6 | 恶意文本 → 注入检测器阻止 → error | | 4 | 元数据中的 PII | 4 | caller_id 中的 SSN/email/CC → intake PII 扫描检测到 | | 5 | 录音文本中的 PII | 6 | 客户读出 SSN/CC/email/电话 → 全部被编辑 | | 6 | 未解决的问题 | 3 | 坐席无法解决 → resolution="unresolved" → 较低的分数 | | 7 | 升级的通话 | 3 | 坐席升级 → resolution="escalated" → PDF/JSON | | 8 | 严重合规问题 | 4 | 跳过验证 → critical 标记 → supervisor_review | | 9 | 低 QA 分数 | 3 | 粗鲁的坐席 → 所有维度都低 → 总分 < 3.0 | | 10 | 超大音频 (>50MB) | 2 | 60MB 文件 → intake 在处理前拒绝 | | 11 | 音频过长 (>60 分钟) | 2 | 90 分钟录音 → intake 拒绝 | | 12 | 麦克风录音 | 2 | input_source="microphone" 在 state 中被跟踪 | | 13 | 重复音频 (缓存) | 3 | 相同文件上传两次 → SHA-256 缓存命中 | | 14 | 多个合规标记 | 4 | 混合严重级别标记 → 全部保留,critical 优先路由 | | 15 | 错误传播 | 5 | state 中的错误 → 路由至 error,处理 None 字段 | **所有测试均无需 API 密钥即可运行** —— LLM 和 Whisper 调用完全使用 `unittest.mock` 进行模拟。 ## 🐳 Docker 部署 ### 构建并运行 ``` # 构建镜像 docker build -t call-center-intelligence . # 使用环境文件运行 docker run -p 7860:7860 --env-file .env call-center-intelligence # 使用持久化数据库运行 (推荐) docker run -p 7860:7860 \ --env-file .env \ -v $(pwd)/data:/app/data \ call-center-intelligence ``` ### Docker 详情 - **基础镜像**:`python:3.11-slim` - **系统依赖**:`ffmpeg` (通过 apt-get 安装) - **端口**:7860 (Gradio 默认) - **数据库**:容器内的 `/app/data/calls.db` (挂载卷以持久化) - **Whisper 模型**:首次运行时下载(`tiny` 约 39MB) ## 🖥️ GPU 部署 系统**自动检测**最佳可用设备: | 设备 | 计算类型 | 检测方式 | |--------|-------------|-------------------| | **NVIDIA GPU (CUDA)** | `float16` | `torch.cuda.is_available() == True` | | **Apple Silicon (MPS)** | `int8` (CPU 回退) | 检测到 MPS 但 CTranslate2 不支持它 | | **CPU** | `int8` | 默认回退 | ### Whisper 模型推荐 | 环境 | 模型 | 大小 | 速度 (5 分钟通话) | 准确率 | |-------------|-------|------|-------------------|----------| | **开发 (CPU)** | `tiny` | 39 MB | ~1 分钟 | 足够用于测试 | | **开发 (CPU)** | `base` | 74 MB | ~2 分钟 | 更好的准确率 | | **生产 (GPU)** | `large-v3` | 1.5 GB | ~10 秒 | 最佳准确率 | ``` # 开发 WHISPER_MODEL_SIZE=tiny # 使用 GPU 的生产环境 WHISPER_MODEL_SIZE=large-v3 ``` ### HuggingFace Spaces 部署 1. 创建一个 Gradio SDK Space 2. 将 API 密钥添加为 Space Secrets 3. 为免费 CPU 层设置 `WHISPER_MODEL_SIZE=tiny` 4. 应用程序会自动检测 `SPACE_ID` 并绑定到 `0.0.0.0` ## 🔑 关键设计决策 ### 1. LLM 调用前的 PII 编辑 **原因**:GDPR/CCPA 合规性。客户的 SSN、信用卡、电子邮件和电话号码绝不能离开您的安全边界。LLM 仅分析编辑后的文本。 **做法**:正则表达式模式检测 4 种 PII 类型 → 从原始文本中收集匹配项 → 从右到左替换(保留字符串位置) → 应用于 `full_text` 和每个单独的片段。 ### 2. 确定性 QA 分数覆盖 **原因**:LLM 是非确定性的。即使 `temperature=0`,相同的输入也可能产生不同的总分。监管审查需要可复现的数字。 **做法**:LLM 对 5 个维度进行评分(每项 1-5 分)。您的代码计算: ``` overall = 0.15×Professionalism + 0.20×Empathy + 0.30×Resolution + 0.20×Compliance + 0.15×Clarity ``` LLM 自己的 `overall_score` 会被**直接丢弃**。 ### 3. SHA-256 录音文本缓存 **原因**:在每天 5,000 通电话的情况下,重复上传的情况时有发生(主管审核、QA 检查)。如果没有缓存,每次重复上传会花费 1-10 分钟的 CPU 时间。 **做法**:音频字节的 SHA-256 哈希 → 检查 `transcription_cache` 表 → 缓存命中在几毫秒内返回存储的 `TranscriptionResult`。 ### 4. Magic-Byte 格式检测 **原因**:永远不要信任文件扩展名。一个 `.wav` 文件可能包含 MP3 数据。重命名为 `.wav` 的文本文件应该被拒绝。 **做法**:读取前 12 个字节:`RIFF...WAVE` → WAV,`ID3` 或 `0xFF+0xE0` → MP3,`fLaC` → FLAC,偏移量 4 处的 `ftyp` → M4A。 ### 5. Whisper 模型单例 **原因**:加载 Whisper 模型需要 5-30 秒。按请求加载会使每次通话分析以 30 秒的延迟开始。 **做法**:模块级别的 `_model` 全局变量,在启动时由 `_get_whisper_model()` 加载一次,为所有请求重用。 ### 6. Summary → QA 顺序执行 (而非并行) **原因**:QA 评分接收摘要作为上下文。了解 `resolution_status` 和 `sentiment_trajectory` 有助于更准确地对 Problem Resolution (30% 权重) 和 Empathy (20% 权重) 进行评分。 **权衡**:额外增加一次 LLM 调用的延迟。在占总权重 50% 的部分上获得的准确率提升是值得的。 ### 7. LangGraph 与普通函数调用的对比 **原因**:普通的顺序调用无法进行条件路由(错误 → 错误节点,严重标记 → 主管审查)。LangGraph 提供了类型化状态、分支、错误隔离和免费的 LangSmith 追踪。 ## 📊 数据模型 14 个类型化的 Pydantic 模型构成了 Pipeline 阶段之间的契约: | 模型 | 目的 | |-------|---------| | `AudioInput` | 原始音频字节、文件名、可选元数据 | | `AudioProperties` | 时长、采样率、声道 | | `PIIScanResult` | 是否在元数据字段中发现 PII | | `IntakeResult` | 验证结果 + 提取的属性 | | `TranscriptionSegment` | 说话人、文本、时间戳、置信度 (0.0-1.0) | | `TranscriptionResult` | 所有片段 + 完整文本 + 标记状态 | | `ResolutionStatus` | 枚举:`resolved` / `unresolved` / `escalated` | | `ActionItem` | 描述、负责人、可选截止日期 | | `Entity` | 带有类型和值的命名实体 | | `SummaryResult` | 通话目的、要点、行动项、情绪、实体 | | `QADimensionScore` | 维度名称、分数 (1-5)、理由 | | `ComplianceFlag` | 违规描述、严重程度、时间戳参考 | | `QAScoreResult` | 5 个维度分数 + 合规标记 + 加权总分 | | `CallReport` | 由所有上游结果组成的完整汇总报告 | ### PipelineState (TypedDict) ``` class PipelineState(TypedDict, total=False): audio_input: AudioInput intake: IntakeResult transcription: TranscriptionResult summary: SummaryResult qa_scores: QAScoreResult report: CallReport error: str status: str ``` 每个节点接收完整状态并返回部分更新。LangGraph 会自动合并它。 ## 🔒 安全特性 ### Prompt 注入检测 (22+ 种模式) 注入检测器在任何 LLM 调用之前扫描录音文本: | 类别 | 示例模式 | |----------|-----------------| | 忽略指令 | "ignore previous instructions", "disregard prior" | | 角色切换 | "you are now", "act as", "pretend to be" | | DAN 模式 | "DAN mode", "jailbreak" | | 系统标签注入 | `<>`, `[INST]`, `` | | Prompt 泄露 | "show me your system prompt", "what are your instructions" | | 社会工程 | "as a developer", "in debug mode" | | 安全覆盖 | "override safety", "ignore safety" | 如果任何模式匹配,Pipeline 会在**任何 LLM 调用之前阻止**并返回匹配的模式名称。 ### PII 编辑 (4 种类型) | PII 类型 | 占位符 | 示例 | |----------|-------------|---------| | SSN | `[REDACTED_SSN]` | `123-45-6789` | | 信用卡 | `[REDACTED_CREDIT_CARD]` | `4111 1111 1111 1111` | | 电子邮件 | `[REDACTED_EMAIL]` | `john@example.com` | | 电话 | `[REDACTED_PHONE]` | `(555) 123-4567` | ### 审计日志 每个 Pipeline 事件都记录在只追加的 `audit_log` 表中。记录**永远不会被删除或修改**。 ## 📊 QA 评分系统 ### 确定性公式 ``` overall_score = 0.15 × Professionalism + 0.20 × Empathy + 0.30 × Problem Resolution + 0.20 × Compliance + 0.15 × Communication Clarity ``` LLM 自己的 `overall_score` 会被**直接丢弃**并替换为此公式。 ## 📈 可观测性 启用 LangSmith 追踪:在 `.env` 中设置 `LANGCHAIN_TRACING_V2=true`。 ## 🔧 故障排除 | 问题 | 解决方案 | |---------|----------| | 401 API 密钥错误 | 在提供商仪表板验证密钥,检查 `.env` 中是否有多余的空格 | | 429 速率限制 | 切换提供商或等待配额重置 | | LLM 超时 | 增加 `LLM_TIMEOUT_SECONDS=120` | | Docker 崩溃 | 确保传递了 `--env-file .env`,检查 `DB_PATH` 是否可写 | ## 🚀 未来扩展 - 使用 `pyannote-audio` 的**真实说话人分离** - 使用 Redis/Celery 队列的**批量处理** - 每个部门的**自定义 QA 评分标准** - 通过 WebSocket 的**实时流式处理** - 带有分数趋势的**坐席辅导仪表盘** - **多语言支持** (Whisper 支持 99 种语言) - 用于多实例部署的 **PostgreSQL 迁移** ## 📄 许可证 MIT **用 ❤️ 构建,作为一个展示生产级 AI 工程的毕业设计项目。**
标签:API集成, CISA项目, Faster-Whisper, Gemini, Gradio, LangGraph, MLOps, NLP, OpenAI, PDF报告生成, PII过滤, Prompt注入防御, PyRIT, Python, QA系统, ReportLab, SQLite, STT, 个人信息脱敏, 人工智能, 内存规避, 可观测性, 呼叫中心分析, 多平台LLM支持, 多智能体系统, 多维评分, 大模型安全, 客户服务, 对话智能, 情感分析, 数据合规, 文本摘要, 无后门, 智能体编排, 机器学习运维, 生产级应用, 用户模式Hook绕过, 联络中心系统, 语音识别, 语音转文本, 请求拦截, 质量保证评分, 逆向工具