← Back to tutorials

AI Sales Call Analysis: Coaching Your Team with Conversation Intelligence

How to use AI to transcribe, analyze, and learn from every sales conversation

AI Sales Call Analysis: Coaching Your Team at Scale

Great sales managers listen to calls and coach reps. The problem: managers can't listen to every call, and the feedback loop is slow. AI conversation intelligence changes this — providing automated analysis and coaching insights for every single call.

The Conversation Intelligence Category

Gong raised $250M at a $7.25B valuation. Chorus was acquired by ZoomInfo for $575M. These valuations reflect the massive value of analyzing sales conversations systematically.

What these platforms do:

  • Transcribe every sales call automatically
  • Identify talk/listen ratio
  • Track topics discussed (pricing, competition, next steps)
  • Flag risk signals (objections, buying committee gaps, competitor mentions)
  • Correlate conversation patterns with win rates
  • Coach reps based on what top performers do differently
  • Building Your Own Conversation Intelligence

    python
    import anthropic
    from openai import OpenAI
    import json
    from pathlib import Path
    import tempfile

    client_openai = OpenAI() client_anthropic = anthropic.Anthropic()

    class SalesCallAnalyzer: """ Analyzes sales call recordings using Whisper + Claude. """ def __init__(self): self.whisper_model = "whisper-1" def transcribe_call(self, audio_path: str) -> dict: """Transcribe call audio with speaker diarization.""" with open(audio_path, 'rb') as audio_file: transcript = client_openai.audio.transcriptions.create( model=self.whisper_model, file=audio_file, response_format="verbose_json", timestamp_granularities=["segment"] ) return { 'text': transcript.text, 'segments': transcript.segments, 'duration_seconds': transcript.duration if hasattr(transcript, 'duration') else None } def analyze_call(self, transcript: dict, rep_name: str, deal_stage: str, call_type: str = 'discovery') -> dict: """ Comprehensive analysis of sales call transcript. """ message = client_anthropic.messages.create( model="claude-opus-4-5", max_tokens=4000, messages=[{ "role": "user", "content": f"""Analyze this sales call transcript and provide coaching insights.

    Call Context:

  • Rep: {rep_name}
  • Call Type: {call_type}
  • Deal Stage: {deal_stage}
  • Transcript: {transcript.get('text', '')[:8000]}

    Provide analysis in JSON format: {{ "call_summary": "2-3 sentence summary", "outcome": "positive/neutral/negative", "next_steps_identified": ["..."], "next_steps_committed": true/false, "talk_ratio": {{ "rep_estimate_pct": 0-100, "customer_estimate_pct": 0-100, "assessment": "good/rep_dominated/customer_dominated" }}, "topics_covered": {{ "pain_points_discovered": ["..."], "product_discussed": ["..."], "pricing_mentioned": true/false, "competition_mentioned": ["competitor names"], "timeline_discussed": true/false, "budget_qualified": true/false, "authority_confirmed": true/false }}, "buying_signals": ["positive signals heard"], "objections_raised": ["..."], "objection_handling_quality": "strong/adequate/weak", "bant_qualification": {{ "budget": "confirmed/uncovered/unknown", "authority": "confirmed/uncovered/unknown", "need": "confirmed/uncovered/unknown", "timeline": "confirmed/uncovered/unknown" }}, "coaching_feedback": {{ "strengths": ["what the rep did well"], "improvements": ["specific things to improve"], "missed_opportunities": ["what should have been asked/said"], "overall_score": 1-10, "priority_coaching_point": "single most impactful thing to work on" }}, "deal_risk_assessment": "on_track/at_risk/needs_attention", "risk_factors": ["any concerns about deal progression"] }}""" }] ) try: return json.loads(message.content[0].text) except json.JSONDecodeError: return {"raw_analysis": message.content[0].text} def calculate_team_metrics(self, analyses: list[dict]) -> dict: """Aggregate call analyses into team performance metrics.""" if not analyses: return {} # Talk ratios talk_ratios = [a.get('talk_ratio', {}).get('rep_estimate_pct', 50) for a in analyses] avg_talk_ratio = sum(talk_ratios) / len(talk_ratios) # BANT coverage rates bant_coverage = { dimension: sum( 1 for a in analyses if a.get('bant_qualification', {}).get(dimension) == 'confirmed' ) / len(analyses) for dimension in ['budget', 'authority', 'need', 'timeline'] } # Next steps commitment rate next_steps_rate = sum( 1 for a in analyses if a.get('next_steps_committed', False) ) / len(analyses) # Coaching scores scores = [ a.get('coaching_feedback', {}).get('overall_score', 5) for a in analyses if a.get('coaching_feedback', {}).get('overall_score') ] avg_score = sum(scores) / len(scores) if scores else 5 # Common improvement areas all_improvements = [] for a in analyses: all_improvements.extend( a.get('coaching_feedback', {}).get('improvements', []) ) # Count frequency of improvement themes from collections import Counter improvement_freq = Counter(all_improvements) return { 'total_calls_analyzed': len(analyses), 'avg_talk_ratio_rep': round(avg_talk_ratio, 1), 'talk_ratio_optimal_pct': sum( 1 for r in talk_ratios if 35 <= r <= 50 ) / len(talk_ratios), 'bant_coverage': {k: round(v, 2) for k, v in bant_coverage.items()}, 'next_steps_commitment_rate': round(next_steps_rate, 2), 'avg_coaching_score': round(avg_score, 1), 'top_improvement_areas': improvement_freq.most_common(5) }

    Generate weekly coaching report for a manager

    def generate_manager_coaching_report(rep_name: str, call_analyses: list[dict]) -> str: """Generate weekly coaching report using Claude.""" metrics = SalesCallAnalyzer().calculate_team_metrics(call_analyses) message = client_anthropic.messages.create( model="claude-opus-4-5", max_tokens=1500, messages=[{ "role": "user", "content": f"""Write a weekly sales coaching report for {rep_name}.

    Performance Metrics: {json.dumps(metrics, indent=2)}

    Individual Call Analyses (last 5 calls): {json.dumps(call_analyses[-5:], indent=2)[:3000]}

    Write a coaching report that:

  • Acknowledges specific strengths (with examples from calls)
  • Focuses on 1-2 specific improvement areas (not laundry list)
  • Gives concrete, actionable advice with examples
  • Sets specific goals for next week
  • Maintains motivating, constructive tone
  • Format as a narrative coaching conversation, not bullet points.""" }] ) return message.content[0].text

    What Top Performers Do Differently

    AI analysis of thousands of calls reveals consistent patterns:

    Talk ratio: Top performers talk 43-47% of the time. Reps who dominate conversation (>65%) convert 30% less.

    Questions per call: Top performers ask 11-14 questions per discovery call vs. 4-7 for average performers.

    Competitor mentions: Top performers acknowledge competitors rather than avoiding the topic — addressing objections proactively.

    Next steps: 100% of top performer calls end with a specific, committed next step with date. Bottom performers: 40%.

    These insights can be surfaced automatically for every call — scaling coaching from "when manager has time" to "after every call."

    Also available in 中文.