CallLens
Enables analyzing call transcripts, scoring dimensions against declarative rubrics, and listing rubrics, for evidence-backed conversation evaluation.
README
CallLens
Open-source conversation intelligence and behavioral evaluation powered by LangGraph.
Upload a call. CallLens transcribes it, reconstructs the conversation, measures deterministic communication metrics, evaluates semantic behaviors against configurable rubrics, verifies the supporting evidence, and produces explainable conversation intelligence.
CallLens turns raw conversations — recordings or transcripts — into structured, evidence-backed behavioral intelligence: diarized transcripts, talk-time and pace metrics, longitudinal sentiment, topics, opportunity/risk detection, and per-representative analytics, all scored against declarative, versioned rubrics.
Every semantic score is evidence-backed. Never just Discovery: 8/10. Instead:
Discovery: 8.7/10
Confidence: 0.91
Evidence:
04:32 Representative asks customer about their current operational bottleneck.
05:17 Representative asks about business impact.
07:02 Customer explains delivery delays.
Missing behavior:
Representative never established urgency or implementation timeframe.
Users click a timestamp and the audio player jumps to that exact moment.
Why it exists
Most call-scoring tools either (a) send the whole transcript to an LLM and ask for a number, or (b) count keywords. CallLens does neither:
- Multi-stage scoring — candidate evidence extraction → deterministic verification → rubric scoring → consistency check → confidence gate → bounded re-judge. Never a single "score this transcript" prompt.
- Deterministic where possible, semantic only where needed — talk time, wpm, interruptions, turns, and silences are pure Python. LLMs are used for reasoning: sentiment, topics, intent, behavior, coaching.
- Provider isolation — a speech abstraction (ElevenLabs today) and an LLM abstraction (OpenAI / Anthropic / any OpenAI-compatible endpoint), so nothing is hardwired to one vendor.
- Auditable by design — every analysis records model, prompt, rubric, and pipeline versions.
Architecture
flowchart TD
A[Audio / Transcript] --> B[Ingestion]
B --> C[ElevenLabs STT + Diarization]
C --> D[Transcript Normalization]
D --> E[LangGraph]
E --> F[Deterministic Metrics]
E --> G[Semantic Analysis]
G --> H[Sentiment]
G --> I[Topics]
G --> J[Intents]
F --> K[Evidence Verification]
H --> K
I --> K
J --> K
K --> L[Confidence Gate]
L -->|sufficient| M[Report]
L -->|insufficient| N[Bounded Re-score]
N --> K
See docs/ARCHITECTURE.md, docs/LANGGRAPH.md, and docs/DATA_MODEL.md.
Quick start
Docker (recommended)
cp .env.example .env
docker compose up
- API + OpenAPI docs: http://localhost:8000/docs
- Dashboard: http://localhost:3000
No API keys are required to try it: without ELEVENLABS_API_KEY the speech provider and reasoning LLM fall back to deterministic offline mocks, so the full pipeline (transcribe → metrics → evidence-backed rubric scoring → coaching) runs end to end.
Local (Python)
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
# Analyze a transcript (offline, deterministic)
calllens analyze sample.txt
# Start the API server
calllens server
# Run the evaluation harness
calllens eval run
Frontend
cd apps/web
npm install
NEXT_PUBLIC_API_URL=http://localhost:8000 npm run dev
CLI
calllens analyze call.mp3
calllens analyze call.mp3 --rubric consultative_sales --output report.json
calllens rubric list
calllens rubric validate ./my_rubric.yaml
calllens eval run
calllens server
Python SDK
import asyncio
from calllens import CallLens
async def main():
async with CallLens(base_url="http://localhost:8000") as client:
call = await client.calls.upload("sales-call.mp3")
await call.analyze(rubric="consultative_sales")
report = await call.report()
print(report["overall_score"], report["confidence"])
asyncio.run(main())
REST API (subset)
POST /api/v1/calls upload a recording or transcript
GET /api/v1/calls
GET /api/v1/calls/{id}
POST /api/v1/calls/{id}/analyze
GET /api/v1/calls/{id}/analysis the evidence-backed CallReport
GET /api/v1/calls/{id}/transcript
DELETE /api/v1/calls/{id} privacy/retention deletion
POST /api/v1/rubrics register a declarative rubric
GET /api/v1/rubrics
POST /api/v1/rubrics/validate
GET /api/v1/reps/{id}/analytics
POST /api/v1/evals/run
Interactive docs at /docs.
Rubrics
Rubrics are declarative and versioned YAML documents. The engine itself is generic — sales is just the first bundled rubric. Bring your own: customer support, recruitment, collections, insurance, real estate, customer success, interviews, AI voice agents.
name: consultative_sales
version: "1.0"
dimensions:
rapport:
label: Rapport
weight: 0.08
discovery:
label: Problem Discovery
weight: 0.16
Dimension weights must sum to 1.0. See rubrics/ and docs/custom-rubrics.
Providers
| Layer | Provider | Config |
|---|---|---|
| Speech (STT/TTS) | ElevenLabs Scribe v2 | ELEVENLABS_API_KEY, ELEVENLABS_STT_MODEL |
| Reasoning LLM | OpenAI | LLM_PROVIDER=openai, OPENAI_API_KEY, LLM_MODEL |
| Reasoning LLM | Anthropic | LLM_PROVIDER=anthropic, ANTHROPIC_API_KEY, LLM_MODEL |
| Reasoning LLM | Any OpenAI-compatible endpoint | LLM_PROVIDER=compatible, COMPATIBLE_BASE_URL, COMPATIBLE_API_KEY |
| Reasoning LLM | Offline mock (default) | LLM_PROVIDER=mock |
All tests and CI run against mocks — no paid API calls.
Example: live analysis with real providers
Wire both providers in .env and analyze an actual recording:
# .env — speech + reasoning
ELEVENLABS_API_KEY=sk_...
ELEVENLABS_STT_MODEL=scribe_v2
# Any OpenAI-compatible endpoint, e.g. Melious (https://api.melious.ai/v1)
LLM_PROVIDER=compatible
COMPATIBLE_BASE_URL=https://api.melious.ai/v1
COMPATIBLE_API_KEY=sk-mel-...
LLM_MODEL=gpt-oss-120b
Then run the full pipeline on a recording — it must be a pre-recorded call file (MP3/WAV), but you can synthesize one if you don't have a recording handy:
# Option A — you have a recording: transcribe + analyze it live
# (Scribe v2 STT → metrics → evidence-backed scoring → coaching)
calllens analyze call.mp3 --rubric consultative_sales --output report.json
# Option B — no recording? Synthesize a two-speaker sample call with ElevenLabs TTS
python examples/generate_sample_call.py # → sample_call.mp3
calllens analyze sample_call.mp3 --rubric consultative_sales --output report.json
# Both write the evidence-backed report (scores + timestamped evidence + coaching)
# to report.json; omit --output to print it to stdout.
The
compatibleendpoint must support OpenAI JSON-schema structured outputs (response_format: {type: "json_schema"}) — the pipeline'sstructured_completiondepends on it. Not every model on every gateway does; e.g.gpt-oss-120bon Melious works, while several others (GLM, Kimi, DeepSeek v4 on Melious) reject schema mode. Probe with a small structured call before committing to a model.
MCP / MCPize
CallLens ships an MCP server exposing analyze_transcript, score_dimension, and list_rubrics, deployable on MCPize:
mcpize analyze && mcpize doctor && mcpize deploy
Local stdio:
pip install -r requirements.txt
python mcp-server/server.py
Evaluation
| Dimension | MAE | Correlation |
|-----------|-----|-------------|
| Discovery | .61 | .88 |
| Rapport | .74 | .81 |
The harness (calllens.evals) runs the full pipeline over a 13-scenario synthetic dataset (excellent seller, poor seller, weak discovery, angry customer, multilingual, …) and reports MAE, RMSE, correlation, and evidence precision/recall against human-quality labels.
Roadmap
See docs/ROADMAP.md. Highlights: Supabase auth/RLS and object storage, async job backends (Redis/SQS), GraphQL dashboard queries, live-call mode, AI role-play mode, per-representative trends, drift monitoring.
Security & privacy
- API keys are environment-only; nothing is ever committed, logged, or exposed to the browser.
- Call recordings are treated as sensitive: tenant isolation, private/signed storage, deletion and configurable retention.
- Complete transcripts are never logged by default.
- See SECURITY.md and docs/ARCHITECTURE.md.
License
MIT © Yabloko Labs
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。