Skip to content

How to Build a Multi-Agent Earnings Call Analyzer in Python

A first-pass earnings summary misses things: buried guidance updates, CFO tone shifts, management's dodge on capex. This recipe uses Self-Reflection — the agent produces an initial analysis, then critiques and improves it in a tight loop until it passes a completeness check.

Patterns used: Self-Reflection


Architecture

flowchart TD
    T[Earnings Transcript] --> A[Analyst Agent\ninitial analysis]
    A --> C{Reflection\ncomplete?}
    C -->|No — gaps found| A
    C -->|Yes — ANALYSIS COMPLETE| O[Final Earnings Brief]

Implementation

pip install pyagent-patterns pyagent-providers
import asyncio
from pyagent_patterns.base import Agent
from pyagent_patterns.resolution import SelfReflection
from pyagent_providers import AnthropicLLM

smart_llm = AnthropicLLM("claude-sonnet-4-20250514")

earnings_analyzer = SelfReflection(
    agent=Agent(
        "earnings_analyst", smart_llm,
        system_prompt=(
            "You analyze earnings call transcripts for buy-side investors. Each iteration:\n"
            "1. Extract: EPS beat/miss vs consensus, revenue growth YoY, and full-year guidance revision.\n"
            "2. Flag: any change in management tone (confident / cautious / evasive), and one key risk.\n"
            "3. Self-check: have you covered EPS, revenue, guidance, tone, AND risk? "
            "If any are missing or vague, note the gap and improve. "
            'When all five are clear and specific, end with "ANALYSIS COMPLETE".'
        ),
    ),
    max_rounds=3,
    stop_phrase="ANALYSIS COMPLETE",
)

TRANSCRIPT = """
[Q2 Earnings Call — ACME Corp]
CEO: "We delivered another strong quarter. Revenue came in at $1.24B, up 14% year-over-year."
CFO: "EPS was $1.82, and I would note consensus was $1.68. Free cash flow was $310M.
      On guidance — we are tightening the full-year revenue range to $4.9–5.0B from $4.7–5.1B
      and raising the midpoint. Margin expansion remains on track."
Analyst Q: "Can you comment on capex plans for H2?"
CFO: "We will continue to invest prudently. I don't want to get into specific numbers today."
CEO: "We feel very good about our competitive position."
"""

async def main():
    result = await earnings_analyzer.run(TRANSCRIPT)
    print(result.output)
    print(f"\nRounds: {result.metadata['rounds']}")

asyncio.run(main())

Expected Output

EARNINGS BRIEF — ACME Corp Q2

EPS:      $1.82 vs $1.68 consensus — beat by 8.3%.
Revenue:  $1.24B, +14% YoY — above street.
Guidance: Full-year range tightened to $4.9–5.0B (raised midpoint from ~$4.9B); positive signal.
Tone:     CEO confident; CFO measured. Notable: CFO declined to quantify H2 capex ("don't want
          to get into specific numbers") — potentially evasive on investment step-up.
Risk:     Capex opacity — if H2 spend accelerates materially, FCF guidance could disappoint.

ANALYSIS COMPLETE

Rounds: 2

The agent caught the CFO's capex dodge on the second pass — the first round flagged the tone but hadn't surfaced the specific risk it implied.


Customization

Raise the quality bar

earnings_analyzer.agent.system_prompt += (
    "\n4. Sentiment: score management confidence 1-10 based on hedging language."
)

Multi-ticker batch

tickers = {"ACME": TRANSCRIPT_ACME, "BETA": TRANSCRIPT_BETA}
results = await asyncio.gather(*(earnings_analyzer.run(t) for t in tickers.values()))
for name, r in zip(tickers, results):
    print(f"--- {name} ---\n{r.output}\n")

Compare to prior quarter

prompt = f"Compare this quarter to the prior quarter.\n\nPRIOR:\n{prior}\n\nCURRENT:\n{current}"
result = await earnings_analyzer.run(prompt)

When to Use

Situation Use Self-Reflection?
First-pass analysis reliably misses details ✅ Yes
You can specify a clear completeness check ✅ Yes
Multiple independent analysts should compare views ❌ Use Fan-Out / Fan-In
Two agents should argue a bull/bear case ❌ Use Debate

Cost Profile

Stage Typical model Avg cost Volume (200 calls/quarter)
1–3 reflection rounds claude-sonnet $0.012 $2.40
Per transcript claude-sonnet ~$0.012 ~$2.40/quarter

See Also