<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jingyi</title>
    <description>The latest articles on DEV Community by Jingyi (@jingyi_li).</description>
    <link>https://dev.to/jingyi_li</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3941405%2F03b814ec-c548-495f-b8a4-3eb34fefcdb7.jpg</url>
      <title>DEV Community: Jingyi</title>
      <link>https://dev.to/jingyi_li</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jingyi_li"/>
    <language>en</language>
    <item>
      <title>OpenAI Didn’t Publish GPT-Live’s Latency. So We Measured It.</title>
      <dc:creator>Jingyi</dc:creator>
      <pubDate>Fri, 17 Jul 2026 04:51:47 +0000</pubDate>
      <link>https://dev.to/jingyi_li/openai-didnt-publish-gpt-lives-latency-so-we-measured-it-58e3</link>
      <guid>https://dev.to/jingyi_li/openai-didnt-publish-gpt-lives-latency-so-we-measured-it-58e3</guid>
      <description>&lt;p&gt;&lt;em&gt;On a real phone, GPT-Live was 500 ms slower to yield when interrupted, ignored background speech that fooled the older modes, and gave up 314 ms to packet loss that cost the previous generation 2.4 seconds.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Agora Media Lab · July 10, 2026&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Methods and limits at the end.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://openai.com/zh-Hans-CN/index/introducing-gpt-live/" rel="noopener noreferrer"&gt;OpenAI launched GPT-Live&lt;/a&gt; on July 8 promising AI powered voice conversations that feel natural; it listens while it speaks, waits while you think, and hands harder questions to a background model without leaving the conversation. What the launch didn’t include is any end-to-end number for what “natural” means on a real device.&lt;/p&gt;

&lt;p&gt;These just so happen to be the numbers our lab’s engineers measure as part of their daily tests. We ran the latest ChatGPT app through our full protocol, from testing on real devices, to repeatable speech injected through an artificial mouth (actual lab equipment, not a metaphor), controlled network impairment, and every number read off of dual-track waveform recordings. We tested three generations of ChatGPT’s voice interface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GPT-Live-1&lt;/strong&gt;, the new full-duplex mode. It listens while it talks, like a phone call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced Voice Mode&lt;/strong&gt;, the previous generation. A single speech-to-speech model, but strictly turn-based: it waits for you to finish before it responds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard Voice Mode&lt;/strong&gt;, the original pipeline: transcribe your speech, generate a text reply, read it aloud. Three hand-offs per turn.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To our knowledge, this is the first public controlled measurement of GPT-Live as users experience it: model, client, network, serving, and playback together.&lt;/p&gt;

&lt;p&gt;Three results stood out. A fourth kept coming up in the lab but resisted measurement; it’s at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  500 ms to think: slower to stop, harder to fool
&lt;/h2&gt;

&lt;p&gt;When you deliberately interrupt while the AI is speaking, GPT-Live takes the longest to go silent. It spends that time deciding whether you meant it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv2kg3okchzbrfrux49gf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv2kg3okchzbrfrux49gf.png" alt=" " width="797" height="86"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Measured alone, that’s a 498 ms regression against Advanced, the turn-based predecessor, and getting talked over for an extra half second is the kind of thing you notice. But stop latency isn’t the only thing users experience. We also played sounds that should not count as interruptions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frgtwjrzjw0ttbblsrncz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frgtwjrzjw0ttbblsrncz.png" alt=" " width="796" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The cough row is one event versus two, statistically a tie. The background-speech row is not: GPT-Live rejected all thirty probes; Advanced stopped for twenty; Standard stopped for every one. (In the same noise, all three modes understood the primary speaker, 30/30. The generations don’t differ in hearing you through noise; they differ in staying on course while speaking through it.) The old systems treat any sound as an interruption: fast, consistent, and frequently wrong. GPT-Live waits for enough evidence to tell a genuine barge-in from an acoustic event that happens to overlap its speech. (The 498 ms is an end-to-end number: decision policy, network round trip, playback buffer, and client stop behavior all contribute.)&lt;/p&gt;

&lt;p&gt;The new policy also fails in a way the old reflexes never could. In a noisy room where nobody was addressing ChatGPT, GPT-Live spontaneously answered background voices in 4 of 30 ten-second windows; the older modes stayed silent. That’s a speaker-attribution problem: the system detects speech correctly but misjudges who it’s for. &lt;a href="https://help.openai.com/en/articles/20001274-chatgpt-voice" rel="noopener noreferrer"&gt;OpenAI’s help docs&lt;/a&gt; acknowledge the boundary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The trade-off: GPT-Live takes longer to yield, it fell for 1 of our 60 false-interruption probes where Advanced fell for 22, and picks up a new risk of joining conversations that weren’t addressed to it.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GPT-Live’s real gain is 5× less jitter, not 5× more speed
&lt;/h2&gt;

&lt;p&gt;Response latency, from the last frame of user speech to the first audible frame back:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqiiftr7110r65g68qmkh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqiiftr7110r65g68qmkh.png" alt=" " width="797" height="115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can write off Standard Voice Mode: the original transcribe-reply-speak pipeline is a museum piece at five seconds per turn, two product generations behind industry norms. The live comparison is GPT-Live against Advanced Voice Mode, and at the median GPT-Live wins by just 205 ms, hardly a generational leap. The tail is where the generation changed. Advanced’s P90 is 2,318 ms, nearly double its own median: one response in ten leaves you hanging past two seconds, and you never know which. GPT-Live’s P90 sits 104 ms above its median. Call it &lt;strong&gt;turn-taking jitter&lt;/strong&gt;, borrowing the transport term for what users feel: GPT-Live barely moved the median, but it collapsed the variance around it. The spread shrank nearly fivefold (σ: 489 → 104 ms).&lt;/p&gt;

&lt;p&gt;Your brain interprets that consistency as “natural.” Human turns transition in roughly 200 ms (&lt;a href="https://www.pnas.org/doi/10.1073/pnas.0903616106" rel="noopener noreferrer"&gt;Stivers et al., PNAS 2009&lt;/a&gt;); a response that lands on the same beat every time reads as thoughtful, while one that oscillates between 1.3 and 2.3 seconds reads as stalling. GPT-Live is nowhere near human speed, but it made the distance predictable.&lt;/p&gt;

&lt;p&gt;“First audible frame” hides something, though: it includes acknowledgments. When a question needs search or reasoning, GPT-Live says “let me check that” while GPT-5.5 works in the background, so its first sound arrives early even when its answer doesn’t. The hard latency didn’t disappear; GPT-Live &lt;strong&gt;redistributed it into the conversation&lt;/strong&gt;. Voice agents need three clocks: acknowledgment onset, substantive-answer onset, and answer completion. This round measures the first; the next will instrument all three.&lt;/p&gt;

&lt;h2&gt;
  
  
  10% packet loss breaks the old models and barely touches GPT-Live
&lt;/h2&gt;

&lt;p&gt;We degraded the network to find out how much damage it takes to erase a generation of model progress. Turns out 10% packet loss does it with room to spare: GPT-Live’s P90 under loss (1,836 ms) still beat the P90 that turn-based Advanced managed on a clean network (2,318 ms). The degraded new model outperforms the healthy old one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fihc3yc2sqy38vspokw3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fihc3yc2sqy38vspokw3e.png" alt=" " width="797" height="115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The medians say the same thing. Under 10% uplink loss, GPT-Live gives up 314 ms while Advanced gives up 2,448 ms, nearly tripling to within sight of Standard’s clean-network baseline. Swap the impairment to the downlink and add 100 ms of delay, and the ranking doesn’t move.&lt;/p&gt;

&lt;p&gt;From outside the stack we can’t separate the three plausible contributors: an &lt;strong&gt;incremental architecture&lt;/strong&gt; that consumes audio continuously, so a lost packet costs context rather than stalling a pipeline; &lt;strong&gt;transport and client differencesin&lt;/strong&gt; codec, loss concealment, and jitter buffering across modes; and trainingon degraded audio. Assigning percentages would require internal telemetry, and we won’t pretend otherwise. For anyone building on these models the split matters less than the sum: the resilience ships with the product, whatever produced it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hidden requirement: full-duplex is a network contract
&lt;/h2&gt;

&lt;p&gt;In a text chatbot, jitter is an inconvenience. In a full-duplex system, timing ismeaning: a pause is input, so network delay can masquerade as user hesitation; barge-in is a round trip, which is why stop latency is a systems number, not a model number; backchannels have a deadline, so predictableround-trip time matters as much as low; and loss concealment now serves two listeners, because audio smoothed for human ears may not preserve what a model needs.&lt;/p&gt;

&lt;p&gt;A full-duplex model can’t deliver a natural experience alone: model, serving, transport, and client have to agree on time. OpenAI tunes all four because it owns the stack (see the &lt;a href="https://openai.com/index/delivering-low-latency-voice-ai-at-scale/" rel="noopener noreferrer"&gt;infrastructure work it published this spring&lt;/a&gt;). Most teams own none of it; they consume a model API over the public internet and inherit every trade-off as their own problem. That gap is the layer Agora builds: a global real-time network in place of the public internet’s default paths, loss-resilient transport tuned for model consumption, and the client-side barge-in and AI-VAD behavior that decides how fast an agent shuts up when you talk over it. Disclosure: this is our business, so discount our emphasis accordingly. It’s also why we knew which probes to build; we’ve spent years tuning exactly these trade-offs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we felt but haven’t measured yet
&lt;/h2&gt;

&lt;p&gt;Our test engineers kept coming back to one behavior rather than any single number: GPT-Live answers quickly, works on something else in the background, and never leaves dead air while doing both. The older modes went silent in exactly that gap. That’s the distance the three-clock framework above is meant to quantify: sounding responsive versus being done.&lt;/p&gt;

&lt;p&gt;Three more consistent observations: GPT-Live handled our backchannels without losing its thread, where older modes treated a murmured “mhmm” as a new turn and changed topic. Its emotional register shifted naturally with context. And it showed a working sense of elapsed time in “remind me in 40 seconds” probes, though it occasionally missed; older modes fail these outright. All are candidates for the next protocol, alongside speaker attribution, code-switching, and long-session drift.&lt;/p&gt;

&lt;p&gt;Putting it all together, on July 8 the bar was reset for every voice agent: roughly &lt;strong&gt;1.1&lt;/strong&gt; s to acknowledge, &lt;strong&gt;1.4&lt;/strong&gt; s to yield when interrupted, zero false stops under background speech, &lt;strong&gt;+314 ms&lt;/strong&gt; under 10% packet loss. Those are the numbers users will now feel in anything they compare to it. (The GPT-Live API itself is still &lt;a href="https://openai.com/form/gpt-live-1-in-the-api/" rel="noopener noreferrer"&gt;waitlist-only&lt;/a&gt;; the current Realtime API default, &lt;a href="https://developers.openai.com/api/docs/models/gpt-realtime-2.1" rel="noopener noreferrer"&gt;gpt-realtime-2.1&lt;/a&gt;, is a different model that we didn’t test.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods and limits
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Setup.&lt;/strong&gt; iPhone 13, ChatGPT v1.2026.183 (App Store build), Plus account with GPT-Live-1 active. All speech in English. Tested July 9, 2026.&lt;/p&gt;

&lt;p&gt;**Timing. **Prerecorded utterances played through an artificial mouth, so every trial hears identical input. Both sides recorded on separate tracks; every number read off the waveform, none from a stopwatch. n=30 per condition. Response latency: last frame of user speech to first audible frame of output. Stop latency: first frame of the barge-in to the last audible frame from the AI. Deliberate barge-ins succeeded 30/30 in every mode, which is why we report how fast each yields, not whether.&lt;/p&gt;

&lt;p&gt;**Limits. **At n=30, don’t over-read single-digit differences, and treat P90s as descriptive. One device, one location, one account, launch week. One impairment level, and the downlink test mixed loss with delay. Treat this as a snapshot, not a census.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next.&lt;/strong&gt; We’ll run the same protocol on other realtime voice models as they ship.&lt;/p&gt;

&lt;p&gt;The full-duplex era has started, and now we can measure it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on the [Agora blog]&lt;/em&gt;(&lt;a href="https://www.agora.io/en/blog/openai-didnt-publish-gpt-lives-latency-so-we-measured-it/" rel="noopener noreferrer"&gt;https://www.agora.io/en/blog/openai-didnt-publish-gpt-lives-latency-so-we-measured-it/&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>voiceagent</category>
      <category>openai</category>
      <category>latency</category>
    </item>
    <item>
      <title>Introducing the Agora CLI</title>
      <dc:creator>Jingyi</dc:creator>
      <pubDate>Fri, 17 Jul 2026 04:45:08 +0000</pubDate>
      <link>https://dev.to/jingyi_li/introducing-the-agora-cli-46nj</link>
      <guid>https://dev.to/jingyi_li/introducing-the-agora-cli-46nj</guid>
      <description>&lt;p&gt;A command-line interface for developers and AI coding agents building with Agora.&lt;/p&gt;

&lt;p&gt;AI coding agents can create apps, but the initial setup still requires human intervention: creating a project, retrieving project credentials, creating the env file without exposing secrets to the agent context, and choosing the right quickstart so it doesn't generate a bunch of boilerplate code. Developers hit the same loop. You open the console, copy values, switch back to the terminal, create the env file, then search for the quickstart link so the agent has a good example to start with.&lt;/p&gt;

&lt;p&gt;Today we're releasing the &lt;strong&gt;Agora CLI&lt;/strong&gt; to move that setup path into the terminal. Developers, scripts, and agents can use the CLI to write environment files, scaffold starter repos, and check Agora environment readiness without leaving the workflow they're already in. Most CLI tools print human-readable output, which leaves coding agents parsing loose terminal text. The Agora CLI supports both humans and agents, with a JSON output mode that returns structured responses an agent can parse and act on. We built the CLI for our own agentic development workflows. Now we're releasing it so Agora developers can give their agents the same ability to provision projects, write env files, and keep setup inside the terminal.&lt;/p&gt;

&lt;p&gt;The shortest path from install to runnable project is three commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://agoraio.github.io/cli/install.sh | sh
agora login
agora init my-python-demo &lt;span class="nt"&gt;--template&lt;/span&gt; python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;agora init&lt;/code&gt; creates or binds an Agora project, clones the selected quickstart, writes the env file that quickstart expects, records the repo-local binding in &lt;code&gt;.agora/project.json&lt;/code&gt;, and prints the next steps. Templates ship for Next.js, Python, and Go.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Command Surface
&lt;/h2&gt;

&lt;p&gt;The CLI separates account-level actions from local project setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agora
├── init        # create or bind a project, clone a quickstart, write env
├── project     # projects, features, credentials, readiness
├── quickstart  # starter repos and template-aware env files
├── auth        # login, logout, session status
├── doctor      # install and project diagnostics
└── mcp         # run the CLI as a local MCP server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;init&lt;/code&gt; when you want the whole onboarding path in one command. Drop into &lt;code&gt;project&lt;/code&gt; and &lt;code&gt;quickstart&lt;/code&gt; when you want to inspect or control each step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agora project create my-agent-demo &lt;span class="nt"&gt;--feature&lt;/span&gt; rtc &lt;span class="nt"&gt;--feature&lt;/span&gt; convoai
agora quickstart create my-python-demo &lt;span class="nt"&gt;--template&lt;/span&gt; python &lt;span class="nt"&gt;--project&lt;/span&gt; my-agent-demo
agora quickstart &lt;span class="nb"&gt;env &lt;/span&gt;write my-python-demo &lt;span class="nt"&gt;--project&lt;/span&gt; my-agent-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI also covers the daily checks developers reach for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agora &lt;span class="nt"&gt;-v&lt;/span&gt;         &lt;span class="c"&gt;# show the installed version&lt;/span&gt;
agora &lt;span class="nb"&gt;help&lt;/span&gt;       &lt;span class="c"&gt;# learn commands and flags&lt;/span&gt;
agora &lt;span class="nb"&gt;whoami&lt;/span&gt;     &lt;span class="c"&gt;# check the current login&lt;/span&gt;
agora doctor     &lt;span class="c"&gt;# check the local install and project setup&lt;/span&gt;
agora upgrade    &lt;span class="c"&gt;# upgrade the CLI&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI keeps the quickstart, credentials, and project binding aligned. It writes the env file the selected template expects, preserves values you've already added, and remembers which Agora project belongs to the repo so future commands don't drift into the wrong setup. Under the hood, the CLI stores repo-local project metadata in &lt;code&gt;.agora/project.json.&lt;/code&gt; When you run another command from that repo, the CLI uses that binding before falling back to a global project selection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built for Agents, Useful for Humans
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.agora.io/en/blog/agora-skills-build-voice-ai-with-your-coding-agent/" rel="noopener noreferrer"&gt;Agora Skills&lt;/a&gt; gives an AI coding assistant the context to understand Agora's products and integration patterns. The CLI gives that assistant a way to act.&lt;/p&gt;

&lt;p&gt;That matters because setup work is full of external dependencies: project configurations, env file setup, feature readiness, quickstart bindings, and local diagnostics. A coding agent can write source code from documentation, but it can't complete a real setup unless it can also ask the platform what exists and change what needs to change.&lt;/p&gt;

&lt;p&gt;For agent and automation workflows, use &lt;code&gt;--json&lt;/code&gt; to return structured data instead of human-formatted terminal output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agora doctor &lt;span class="nt"&gt;--json&lt;/span&gt;
agora auth status &lt;span class="nt"&gt;--json&lt;/span&gt;
agora project &lt;span class="nb"&gt;env&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt;
agora introspect &lt;span class="nt"&gt;--json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In JSON mode, commands return fields a script or agent can inspect directly, such as auth state, project metadata, env values, diagnostics, and command capabilities.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;agora introspect --json&lt;/code&gt; exposes the command tree in a machine-readable form, including which commands are safe for headless runs. agora mcp serve lets MCP clients call the CLI through local tools instead of scraping terminal text.&lt;/p&gt;

&lt;p&gt;The console remains the visual control plane. The CLI gives developers, scripts, and agents a reliable path through the same setup work from the terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;curl -fsSL https://agoraio.github.io/cli/install.sh | sh&lt;/code&gt;&lt;br&gt;
On Windows, install with PowerShell:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;irm https://agoraio.github.io/cli/install.ps1 | iex&lt;/code&gt;&lt;br&gt;
The installer configures PATH and shell completion by default.&lt;/p&gt;

&lt;p&gt;After installing, &lt;code&gt;agora doctor&lt;/code&gt; checks the local CLI setup, including the resolved binary, version, PATH, network access, auth state, and project readiness.&lt;/p&gt;
&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;After you install the CLI, and run &lt;code&gt;agora login&lt;/code&gt;, you can start from one of the official quickstarts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agora init my-python-demo &lt;span class="nt"&gt;--template&lt;/span&gt; python
agora init my-nextjs-demo &lt;span class="nt"&gt;--template&lt;/span&gt; nextjs
agora init my-go-demo &lt;span class="nt"&gt;--template&lt;/span&gt; go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full CLI documentation is available at &lt;a href="https://docs.agora.io/en/introduction/agora-cli" rel="noopener noreferrer"&gt;Agora CLI Docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is the first release. If a command is missing or a setup path still forces you back into manual project work, &lt;a href="https://github.com/AgoraIO/cli/issues" rel="noopener noreferrer"&gt;open an issue&lt;/a&gt;. That feedback should shape the next version.&lt;/p&gt;

&lt;p&gt;Originally published on the &lt;a href="https://www.agora.io/en/blog/introducing-the-agora-cli/" rel="noopener noreferrer"&gt;Agora blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>voiceagent</category>
      <category>ai</category>
    </item>
    <item>
      <title>Agora Agents SDK: Build Voice Agents in Minutes</title>
      <dc:creator>Jingyi</dc:creator>
      <pubDate>Fri, 17 Jul 2026 04:25:54 +0000</pubDate>
      <link>https://dev.to/jingyi_li/agora-agents-sdk-build-voice-agents-in-minutes-1c10</link>
      <guid>https://dev.to/jingyi_li/agora-agents-sdk-build-voice-agents-in-minutes-1c10</guid>
      <description>&lt;p&gt;Introducing &lt;strong&gt;Agora Agents SDK&lt;/strong&gt;, a typed SDK for building voice agents on Agora's Conversational AI Engine in Python, Node.js, and Go.&lt;/p&gt;

&lt;p&gt;Voice agents have moved past demos. Teams are putting them in support flows, onboarding, scheduling, field operations, and internal tools where a delayed response or missed interruption feels broken.&lt;/p&gt;

&lt;p&gt;Today we're releasing &lt;strong&gt;Agora Agents SDK&lt;/strong&gt;: typed builders, built-in auth, token generation, and session management on top of the existing REST API. It ships for &lt;strong&gt;Python, Node.js / TypeScript, and Go.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The REST API remains fully supported. The SDK sits on top of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the SDK Handles
&lt;/h2&gt;

&lt;p&gt;You configure the agent in typed code instead of assembling payloads by hand.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Typed pipeline builders&lt;/strong&gt;. Build voice agents in Python, TypeScript and Go. Compose your voice agent configuration with speech-to-text using .with_stt(), the LLM using .with_llm(), and text-to-speech using .with_tts(). For real-time multimodal models, use the MLLM builder path .with_mllm() for providers such as OpenAI Realtime and Gemini Live.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic token generation&lt;/strong&gt;. Pass your Agora App ID and App Certificate once. The SDK generates fresh auth tokens for each agent request, so developers don't have to build or manage token logic themselves. When you expose agent management endpoints for web or mobile apps, the SDK can also help configure the token server your clients use to join Agora channels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session lifecycle&lt;/strong&gt;. Start, stop, query, and recover sessions through SDK objects instead of keeping raw agent IDs, status values, and retry logic scattered through your backend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python, Node.js / TypeScript, and Go support.&lt;/strong&gt; The SDKs use the same agent model, with APIs shaped for each language instead of one generic wrapper.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install the SDK
&lt;/h2&gt;

&lt;p&gt;Use your preferred package manager to install the SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;agora-agents
npm &lt;span class="nb"&gt;install &lt;/span&gt;agora-agents
go get github.com/AgoraIO/agora-agents-go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;p&gt;This is a basic Python voice-agent pipeline: STT -&amp;gt; LLM -&amp;gt; TTS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;agora_agent&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agora&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Area&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;agora_agent.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;expires_in_hours&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;agora_agent.agentkit&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DeepgramSTT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MiniMaxTTS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agora&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;area&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Area&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;US&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;app_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;APP_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;app_certificate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;APP_CERTIFICATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;turn_detection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;language&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en-US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_stt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;DeepgramSTT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nova-3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;system_messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AGENT_PROMPT&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
            &lt;span class="n"&gt;greeting_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;GREETING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;failure_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Please wait a moment.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;max_history&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;top_p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_tts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;MiniMaxTTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;speech_2_6_turbo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;voice_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;English_captivating_female1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;demo-channel-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;agent_uid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;123456&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;remote_uids&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;conversation-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;idle_timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;expires_in&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;expires_in_hours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That code starts an agent and joins it to an Agora RTC channel. The builder keeps the agent configuration readable: turn detection, providers, model behavior, channel, session name, timeout, and expiry all stay in one place. The same setup can carry model parameters, history limits, and debug settings when you need them.&lt;/p&gt;

&lt;h2&gt;
  
  
  If You Already Use the REST API
&lt;/h2&gt;

&lt;p&gt;Nothing breaks. The REST API remains the foundation of the platform, and it is still a good fit for teams that need direct HTTP control or use a backend language without an SDK.&lt;/p&gt;

&lt;p&gt;For Python, Node.js, and Go services, the SDK removes the code most teams don't want to own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;manual token signing&lt;/li&gt;
&lt;li&gt;large config objects assembled across files&lt;/li&gt;
&lt;li&gt;repeated start/stop boilerplate&lt;/li&gt;
&lt;li&gt;one-off retry and timeout handling around session startup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can migrate one boundary at a time. Keep the rest of your backend as it is, replace the raw setup and lifecycle calls with the SDK, and compare the code side by side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Models, Agora's Real-Time Infrastructure
&lt;/h2&gt;

&lt;p&gt;The SDK doesn't lock you into one model stack. Bring your own STT, LLM, and TTS providers, or use Agora-managed models when you want fewer vendor credentials in your app. You keep control of the model choices and prompts that define the agent. Agora runs the real-time media path, interruption behavior, and channel lifecycle users feel the moment they start talking.&lt;/p&gt;

&lt;p&gt;We built &lt;strong&gt;Agora Agents SDK&lt;/strong&gt; so the first working agent doesn't require a pile of glue code. The SDK keeps the setup close to the way you think about the agent: models, prompts, voice, channel, and session behavior.&lt;/p&gt;

&lt;p&gt;Source and examples for Python, Node.js/Typescript and Go are on Docs: &lt;br&gt;
&lt;a href="https://docs.agora.io/en/ai/build/start-stop-agent#install-the-sdk" rel="noopener noreferrer"&gt;https://docs.agora.io/en/ai/build/start-stop-agent#install-the-sdk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Build an agent, put it in front of a real conversation, and tell us where the SDK still makes you think about plumbing. That feedback shapes the next version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;‍Original&lt;/strong&gt; link:&lt;a href="https://www.agora.io/en/blog/agora-agents-sdk-build-voice-agents-in-minutes/" rel="noopener noreferrer"&gt;https://www.agora.io/en/blog/agora-agents-sdk-build-voice-agents-in-minutes/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Original author&lt;/strong&gt;:Hermes Frangoudis&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>javascript</category>
      <category>go</category>
    </item>
    <item>
      <title>While Learning LangChain, I Ended Up With This Realtime Voice Pattern</title>
      <dc:creator>Jingyi</dc:creator>
      <pubDate>Fri, 26 Jun 2026 11:46:09 +0000</pubDate>
      <link>https://dev.to/jingyi_li/while-learning-langchain-i-ended-up-with-this-realtime-voice-pattern-40pe</link>
      <guid>https://dev.to/jingyi_li/while-learning-langchain-i-ended-up-with-this-realtime-voice-pattern-40pe</guid>
      <description>&lt;p&gt;I've recently started learning LangChain while exploring different ways to build voice agents.&lt;/p&gt;

&lt;p&gt;As someone who's still new to LangChain, I tried a few different approaches before landing on one that felt surprisingly clean.&lt;/p&gt;

&lt;p&gt;I don't know whether this is already a common pattern in the LangChain ecosystem, but it worked well enough that I thought it was worth sharing. Hopefully it can also spark some discussion with people who've been building voice agents for longer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;The basic idea is to separate responsibilities instead of letting one framework handle everything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcttb700vsbtafudja441.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcttb700vsbtafudja441.png" alt=" pattern" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LangChain stays responsible for tool selection, tool execution, and response composition.&lt;/li&gt;
&lt;li&gt;A separate realtime runtime handles RTC / RTM, speech input/output, and session lifecycle.&lt;/li&gt;
&lt;li&gt;The two communicate through an OpenAI-compatible endpoint.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What surprised me
&lt;/h2&gt;

&lt;p&gt;When I first started experimenting, I assumed adding realtime voice would require restructuring most of the application.&lt;/p&gt;

&lt;p&gt;Instead, it felt more like adding another interaction layer.&lt;/p&gt;

&lt;p&gt;LangChain continues doing what it already does well—tool orchestration and workflow management—while the realtime runtime focuses on voice-specific concerns.&lt;/p&gt;

&lt;p&gt;That separation made the overall architecture feel much simpler.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern
&lt;/h2&gt;

&lt;p&gt;To better understand the idea, I put together a small recipe that demonstrates this integration pattern.&lt;/p&gt;

&lt;p&gt;The recipe consists of three pieces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python exposes an OpenAI-compatible endpoint and manages the agent lifecycle.&lt;/li&gt;
&lt;li&gt;Next.js handles the client-side realtime interaction.&lt;/li&gt;
&lt;li&gt;LangChain remains server-side as the orchestration and tool layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not intended to be a complete application or a production-ready project.&lt;/p&gt;

&lt;p&gt;It's simply a pattern that helped me understand how these pieces can fit together.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick note
&lt;/h2&gt;

&lt;p&gt;For transparency, I work at Agora, so I naturally used Agora as the realtime runtime while putting this recipe together.&lt;/p&gt;

&lt;p&gt;That said, I'm much more interested in learning how other people are building voice agents with LangChain.&lt;/p&gt;

&lt;p&gt;If you're using a different stack or have taken a completely different approach, I'd love to hear about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The recipe
&lt;/h2&gt;

&lt;p&gt;If you're curious, here's the recipe:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bluemotional/recipe-agent-langchain" rel="noopener noreferrer"&gt;https://github.com/bluemotional/recipe-agent-langchain&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since I'm still learning LangChain myself, I'd really appreciate any feedback or suggestions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;If people find this pattern useful, I'd like to keep expanding it with more recipes, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RAG&lt;/li&gt;
&lt;li&gt;Internal tools&lt;/li&gt;
&lt;li&gt;Docs Copilot&lt;/li&gt;
&lt;li&gt;MCP integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm also curious to see what other patterns the community has found useful.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>voiceagent</category>
      <category>abotwrotethis</category>
    </item>
    <item>
      <title>Project Spotlight: An Open-Source AI Sports Commentator That Watches the Match Live</title>
      <dc:creator>Jingyi</dc:creator>
      <pubDate>Fri, 26 Jun 2026 01:35:29 +0000</pubDate>
      <link>https://dev.to/jingyi_li/project-spotlight-an-open-source-ai-sports-commentator-that-watches-the-match-live-4pch</link>
      <guid>https://dev.to/jingyi_li/project-spotlight-an-open-source-ai-sports-commentator-that-watches-the-match-live-4pch</guid>
      <description>&lt;p&gt;I recently came across an open-source project called &lt;strong&gt;WorldCupVoice&lt;/strong&gt; and thought it was worth sharing.&lt;/p&gt;

&lt;p&gt;Quick note first: I’m not the creator.&lt;br&gt;&lt;br&gt;
The project is by &lt;strong&gt;zicojiao&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The demo makes the idea click immediately: this is not a post-game recap system. It watches a live match feed and speaks over the action in real time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fendcr9zcnzdfsf62tcus.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fendcr9zcnzdfsf62tcus.png" alt="WorldCupVoice" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Project links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/zicojiao/worldcupvoice" rel="noopener noreferrer"&gt;https://github.com/zicojiao/worldcupvoice&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reddit: &lt;a href="https://www.reddit.com/r/OpenAI/comments/1udx8it/i_tried_making_an_ai_world_cup_commentator_it/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/OpenAI/comments/1udx8it/i_tried_making_an_ai_world_cup_commentator_it/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What makes this project interesting is that it is not a “generate a match summary later” system.&lt;/p&gt;

&lt;p&gt;It is a live pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a match feed comes in through RTMP&lt;/li&gt;
&lt;li&gt;Agora converts it into a real-time RTC stream&lt;/li&gt;
&lt;li&gt;the backend samples frames from the live video&lt;/li&gt;
&lt;li&gt;OpenAI generates grounded play-by-play commentary&lt;/li&gt;
&lt;li&gt;TTS turns that into speech&lt;/li&gt;
&lt;li&gt;the generated audio is published back into the same RTC room&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I found especially interesting from reading the README and code is that the project is clearly trying to solve a harder problem than image captioning.&lt;/p&gt;

&lt;p&gt;The prompts appear to push the model toward a live football commentator role by constraining it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;comment on visible action rather than narrate loosely&lt;/li&gt;
&lt;li&gt;avoid inventing off-screen goals or fouls&lt;/li&gt;
&lt;li&gt;use player names only when visual evidence is strong enough&lt;/li&gt;
&lt;li&gt;return &lt;code&gt;NO_CALL&lt;/code&gt; when the frame is not readable enough&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another thing I liked was that the project seems to take operational reality seriously.&lt;/p&gt;

&lt;p&gt;It includes explicit &lt;code&gt;Start AI / Stop AI&lt;/code&gt; controls, viewer heartbeat, and a hard session TTL, which makes a lot of sense for a live AI system where cost can keep growing even when nobody is watching.&lt;/p&gt;

&lt;p&gt;The World Cup framing is fun, but the accessibility angle might be even more compelling.&lt;br&gt;&lt;br&gt;
A system like this could potentially add more field-level spatial detail for blind and low-vision fans than traditional commentary often does.&lt;/p&gt;

&lt;p&gt;Again, I’m not the author, so if I’m misreading any implementation detail, happy to be corrected. But as an open-source example of a real-time multimodal media pipeline, this was one of the more interesting projects I’ve come across recently.&lt;/p&gt;

&lt;p&gt;Full credit to zicojiao for the project itself. I’m only sharing it because I found it worth discussing.&lt;/p&gt;

</description>
      <category>abotwrotethis</category>
      <category>ai</category>
      <category>openai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
