{"slug": "how-to-build-an-ai-call-agent-with-python-stt-groq-llm-and-tts", "title": "How to Build an AI Call Agent with Python: STT, Groq LLM and TTS", "summary": "A developer built the Google Voice Dispatch Agent, a Python AI calling agent for trucking dispatch outreach that chains Groq speech-to-text, a Groq LLM, and Edge TTS in a loop, with Selenium driving Google Voice in Chrome and VB-CABLE routing synthesized audio into the call. The agent gates its opening line behind a conservative call-state detector that reads DOM cues, requires a minimum ring window, and only speaks once a connection is confirmed, then handles voicemail detection and logs transcripts, recordings, and CRM records via a FastAPI console.", "body_md": "**To build an AI call agent with Python, chain four parts in a loop: speech-to-text to hear the caller, an LLM (such as Groq) to decide the reply, text-to-speech (such as Edge TTS) to speak it, and call-state detection so the agent only talks once a real person has answered.** This guide shows how those pieces fit together in the Google Voice Dispatch Agent, a Python AI calling agent I built for trucking dispatch outreach.\n\nSource: [https://github.com/mafzalkalwardev/google-voice-dispatch-agent](https://github.com/mafzalkalwardev/google-voice-dispatch-agent). For a deep dive on the hardest part, read [How my Google Voice AI agent knows when to talk](https://dev.to/mafzalkalwardev/how-my-google-voice-ai-agent-knows-when-to-talk-call-state-detection-groq-and-tts-e5a).\n\n| Layer | What the Dispatch Agent uses | \n|---|---|\n| Phone line | Google Voice in Chrome, driven by Selenium | \n| Hearing | Audio capture with VAD, Groq speech-to-text | \n| Thinking | Groq LLM | \n| Speaking | Edge TTS (pyttsx3 fallback), routed with VB-CABLE | \n| Control | FastAPI web console | \n| Records | Call logs, transcripts, recordings, local CRM | \n\nThe runtime flow is: load contacts and config, run preflight checks, pre-generate the opening line and voicemail audio, dial, wait for confirmed connection, run the conversation loop, then save logs and move to the next contact after a cooldown.\n\nAn agent that speaks while the phone is still ringing ruins the call. The Dispatch Agent uses a conservative gate: ringing can't jump straight to ended, a minimum ring window must pass before any transition counts, and the opening line starts only after connection is confirmed.\n\n``` python\nimport time\n\ndef wait_for_answer(page, min_ring=2, max_ring=45):\n    start = time.time()\n    while True:\n        elapsed = time.time() - start\n        state = page.detect_call_state()      # reads DOM cues\n        if elapsed < min_ring:\n            continue                          # ignore early noise / stale banners\n        if state in (\"connected\", \"voicemail\", \"ended\"):\n            return state\n        if elapsed > max_ring:\n            return \"no_answer\"\n        time.sleep(0.25)\n```\n\nCapture audio in short frames, use voice activity detection to find when the caller stops talking, then send that chunk to speech-to-text. Groq offers hosted Whisper models with low latency (for example, `whisper-large-v3` below; check Groq's docs for current model names).\n\n``` php\nfrom groq import Groq\nclient = Groq()\n\ndef transcribe(wav_path: str) -> str:\n    with open(wav_path, \"rb\") as f:\n        r = client.audio.transcriptions.create(file=f, model=\"whisper-large-v3\")\n    return r.text\n```\n\nHere the model ID `llama-3.1-8b-instant` is just an example; pick any current Groq chat model. Keep the system prompt short and specific to the job (for dispatch: confirm availability, lanes, equipment) and keep replies to one or two sentences so the call feels natural.\n\n```\nSYSTEM = \"You are a polite dispatch assistant. Reply in one or two short sentences.\"\n\ndef reply(history: list[dict]) -> str:\n    r = client.chat.completions.create(\n        model=\"llama-3.1-8b-instant\",\n        messages=[{\"role\": \"system\", \"content\": SYSTEM}, *history],\n        max_tokens=80,\n    )\n    return r.choices[0].message.content\n```\n\nEdge TTS generates natural speech for free. Pre-generate fixed lines (opening, voicemail) before dialing so the first words play instantly, and cache repeated phrases.\n\n``` python\nimport asyncio, edge_tts\n\nasync def speak_to_file(text: str, path: str, voice=\"en-US-GuyNeural\"):\n    await edge_tts.Communicate(text, voice).save(path)\n\nasyncio.run(speak_to_file(\"Hi, this is dispatch calling about your truck.\", \"opening.mp3\"))\n```\n\nThe audio then plays into the call through a virtual audio device (VB-CABLE) set as the browser's microphone.\n\nThe agent checks for voicemail only after connection, using DOM cues plus an early-call audio classifier for greeting and beep signals. If voicemail is confirmed, it plays the pre-generated voicemail message instead of starting a conversation. Every call ends with a log entry, transcript, recording and CRM update, so a human can audit what the agent said.\n\nAI voice calls are regulated. Check your local calling and telemarketing regulations (in the UK and EU, for example, PECR and GDPR may apply) and get legal advice for your situation. Disclose that the caller is automated where required, honour opt-outs and DNC lists, and follow your phone provider's terms.\n\n**Can I build an AI phone agent with Python?**\n\nYes. Combine speech-to-text, an LLM, text-to-speech and a phone line (a browser-driven line like Google Voice, or a telephony API) in a conversation loop.\n\n**Why use Groq for an AI call agent?**\n\nLow latency. Phone conversations need fast replies, and Groq serves both speech-to-text and LLM responses quickly.\n\n**How does an AI call agent know when to start talking?**\n\nBy detecting call state. It waits for confirmed connection, after a minimum ring window, before playing its opening line.\n\n**Can an AI call agent detect voicemail?**\n\nYes. The Dispatch Agent combines page cues with an audio classifier and plays a recorded voicemail when one is confirmed.\n\n**Can I hire a remote AI call agent developer?**\n\nYes. Muhammad Afzal Kalwar is a freelance voice AI developer in Pakistan who builds AI call agents for US, UK and EU companies: [https://mafzalkalwardev.github.io/#hire-me](https://mafzalkalwardev.github.io/#hire-me)\n\n**Who builds custom AI call agents for logistics companies?**\n\nMuhammad Afzal Kalwar, founder of INDUS Web Agency, built the Google Voice Dispatch Agent and builds custom AI call agents for logistics and sales teams.\n\n**Muhammad Afzal Kalwar** is a Python automation developer in Islamabad, Pakistan, and founder of [INDUS Web Agency](https://www.induswebagency.com). He builds auto dialers, AI call agents, web scrapers and CRMs for logistics, sales and call-center teams in the US, UK and Europe, and has three auto-dialer Chrome extensions on the Chrome Web Store.\n\n**Looking to hire a remote AI call agent developer?** He works with US, UK and EU companies, is available during UK mornings and US afternoons, and quotes fixed-price or hourly in USD, GBP or EUR.", "url": "https://wpnews.pro/news/how-to-build-an-ai-call-agent-with-python-stt-groq-llm-and-tts", "canonical_source": "https://dev.to/mafzalkalwardev/how-to-build-an-ai-call-agent-with-python-stt-groq-llm-and-tts-2nm6", "published_at": "2026-10-30 23:04:03+00:00", "updated_at": "2026-10-30 23:19:44.798310+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "large-language-models", "developer-tools"], "entities": ["Google Voice", "Groq", "Edge TTS", "Selenium", "FastAPI", "VB-CABLE", "pyttsx3", "whisper-large-v3"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/how-to-build-an-ai-call-agent-with-python-stt-groq-llm-and-tts", "markdown": "https://wpnews.pro/news/how-to-build-an-ai-call-agent-with-python-stt-groq-llm-and-tts.md", "text": "https://wpnews.pro/news/how-to-build-an-ai-call-agent-with-python-stt-groq-llm-and-tts.txt", "jsonld": "https://wpnews.pro/news/how-to-build-an-ai-call-agent-with-python-stt-groq-llm-and-tts.jsonld"}}