实践教程
本教程目录
Agora x Gemma Voice Coach
Agora x Gemma Voice Coach is a local Next.js demo that combines:
- Agora Conversational AI for the live voice session
- local Gemma for the reasoning layer
- transcript, status, and microphone controls for live demos
What this demo does
- Starts an Agora RTC and RTM session for live microphone input.
- Invites a managed Agora Conversational AI agent to join the same channel.
- Streams transcript and call-state updates into the browser UI.
- Lets you test a local Gemma endpoint separately with
/api/gemma/testand/api/gemma/chat. - Uses Agora
CustomLLMin the agent backend, pointing at the Gemma chat-completions endpoint. - Exposes local Gemma test/chat routes so you can verify the model independently before joining a live session.
What code was copied or adapted from the Agora quickstart
Source of truth:
- the reference Agora Next.js quickstart repo used during development
Copied or adapted from the reference repo:
app/api/generate-agora-token/route.ts- RTC + RTM token minting withbuildTokenWithRtmapp/api/invite-agent/route.ts- managed agent session start and lifecycle configapp/api/stop-conversation/route.ts- managed agent shutdown and idempotent cleanupapp/api/chat/completions/route.ts- OpenAI-compatible adapter seam backed by local Gemmacomponents/LandingPage.tsx- session bootstrap, Gemma check, and live demo shellcomponents/ConversationComponent.tsx- RTC join, mic publish, voice lifecycle, transcript handlingcomponents/QuickstartConversationLayout.tsx- in-call layout shellcomponents/QuickstartTranscriptPanel.tsx- live transcript renderingcomponents/QuickstartPipelineMetrics.tsx- pipeline metric chipscomponents/ConnectionStatusPanel.tsx- RTC and error status surfacecomponents/ConversationErrorCard.tsx- friendly call error displaycomponents/MicrophoneSelector.tsx- microphone device selectioncomponents/ErrorBoundary.tsx- conversation subtree guardrailcomponents/LoadingSkeleton.tsx- loading fallback for the browser-only call UIlib/agora.ts- shared agent UID defaultlib/conversation.ts- transcript normalization and agent visualizer mappingtypes/conversation.ts- shared request/response contracts
Local Gemma setup
This demo supports two local model modes:
- LM Studio with its local server
- Ollama
For your current LM Studio setup, use:
GEMMA_BASE_URL=http://localhost:12345
GEMMA_CHAT_URL=http://localhost:12345/api/v1/chat
GEMMA_MODEL=google/gemma-4-e2b
GEMMA_TIMEOUT_MS=30000In LM Studio, make sure the model is downloaded and the local server is running. Set GEMMA_MODEL to the exact model identifier shown in LM Studio. The code now reads the final message output from LM Studio, not the reasoning block.
If you want the live Agora voice session to work from your laptop, tunnel the Next.js app, not the LM Studio port:
ngrok http 3000Then set:
GEMMA_PUBLIC_CHAT_URL=https://your-ngrok-domain.ngrok-free.dev/api/chat/completionsAgora should call that public Next.js proxy route. The proxy route then calls your local LM Studio server.
If you want the Ollama path instead, run:
ollama pull gemma3:4b
ollama run gemma3:4bAgora env setup
Required Agora environment variables:
NEXT_PUBLIC_AGORA_APP_IDNEXT_AGORA_APP_CERTIFICATE
Optional Agora behavior variables:
NEXT_PUBLIC_AGENT_UIDdefaults to123456NEXT_AGENT_GREETING
Copy .env.example to .env.local and fill in the required values before starting the app.
Run commands
pnpm install
pnpm devAdditional validation commands:
pnpm run lint
pnpm run typecheck
pnpm run buildTroubleshooting
- If
/api/generate-agora-tokenreturns an env error, verifyNEXT_PUBLIC_AGORA_APP_IDandNEXT_AGORA_APP_CERTIFICATE. - If
/api/gemma/testfails, confirm LM Studio or Ollama is running and thatGEMMA_BASE_URLandGEMMA_CHAT_URLmatch the local server. - If the browser says microphone access is denied, allow microphone permissions in the browser and try again.
- If the conversation starts but no transcript appears, verify the Agora agent invite succeeded and that the RTM token is valid.
- If
pnpm installreports ignored build scripts forsharporunrs-resolver, runpnpm approve-buildsin environments that require postinstall scripts. - If the default
pnpm run buildhits a Turbopack sandbox error in Codex, usepnpm exec next build --webpackfor local validation. - If the app fails to build, run
pnpm run typecheckfirst to catch type issues, thenpnpm run lint.
Known limitations
- The live Agora voice demo still uses the managed agent lifecycle from the reference quickstart.
- Agora must call a public
GEMMA_PUBLIC_CHAT_URLthat points to the Next.js proxy route. That proxy route then calls your local model server. - The demo expects a local model server, such as LM Studio or Ollama, to be running on your machine for local testing.
- The UI is designed for local demos and does not yet include production auth, user accounts, or persistence.
How to test Gemma
- Start LM Studio or Ollama.
- Run:
pnpm dev- In a second terminal, tunnel the Next.js app:
ngrok http 3000- Set
GEMMA_BASE_URLto your local model server. - Set
GEMMA_CHAT_URLto your LM Studio chat endpoint if you are using LM Studio. - Set
GEMMA_PUBLIC_CHAT_URLto the ngrok URL plus/api/chat/completions. - Open
/api/gemma/testin the browser or hit it withcurl. - Use
/api/gemma/chatwith a JSON body containing amessagesarray. - Optionally test the proxy directly:
curl -N http://localhost:3000/api/chat/completions \
-H 'Content-Type: application/json' \
-d '{"messages":[{"role":"user","content":"Say hello in one short sentence."}]}'How to start Agora voice demo
- Set the Agora env vars in
.env.local. - Keep
GEMMA_BASE_URLpointed at your local model server. - Set
GEMMA_CHAT_URLto the LM Studio chat endpoint if you use LM Studio. - Set
GEMMA_PUBLIC_CHAT_URLto the public ngrok URL forapp/api/chat/completions. - Start the app:
pnpm dev- Open the UI in the browser.
- Click
Start Conversation. - Allow microphone permissions when prompted.
- Use
End Conversationwhen you are done.
Final validation
To validate the repo locally, run:
pnpm install
pnpm run lint
pnpm run typecheck
pnpm run buildThen confirm:
/api/gemma/testreturns a reachable response when Ollama, LM Studio, or the local model server is running- the app starts locally with
pnpm dev - the Agora voice flow still starts and stops cleanly from the UI
# Agora x Gemma Voice Coach
Agora x Gemma Voice Coach is a local Next.js demo that combines:
- Agora Conversational AI for the live voice session
- local Gemma for the reasoning layer
- transcript, status, and microphone controls for live demos
## What this demo does
- Starts an Agora RTC and RTM session for live microphone input.
- Invites a managed Agora Conversational AI agent to join the same channel.
- Streams transcript and call-state updates into the browser UI.
- Lets you test a local Gemma endpoint separately with `/api/gemma/test` and `/api/gemma/chat`.
- Uses Agora `CustomLLM` in the agent backend, pointing at the Gemma chat-completions endpoint.
- Exposes local Gemma test/chat routes so you can verify the model independently before joining a live session.
## What code was copied or adapted from the Agora quickstart
Source of truth:
- the reference Agora Next.js quickstart repo used during development
Copied or adapted from the reference repo:
- `app/api/generate-agora-token/route.ts` - RTC + RTM token minting with `buildTokenWithRtm`
- `app/api/invite-agent/route.ts` - managed agent session start and lifecycle config
- `app/api/stop-conversation/route.ts` - managed agent shutdown and idempotent cleanup
- `app/api/chat/completions/route.ts` - OpenAI-compatible adapter seam backed by local Gemma
- `components/LandingPage.tsx` - session bootstrap, Gemma check, and live demo shell
- `components/ConversationComponent.tsx` - RTC join, mic publish, voice lifecycle, transcript handling
- `components/QuickstartConversationLayout.tsx` - in-call layout shell
- `components/QuickstartTranscriptPanel.tsx` - live transcript rendering
- `components/QuickstartPipelineMetrics.tsx` - pipeline metric chips
- `components/ConnectionStatusPanel.tsx` - RTC and error status surface
- `components/ConversationErrorCard.tsx` - friendly call error display
- `components/MicrophoneSelector.tsx` - microphone device selection
- `components/ErrorBoundary.tsx` - conversation subtree guardrail
- `components/LoadingSkeleton.tsx` - loading fallback for the browser-only call UI
- `lib/agora.ts` - shared agent UID default
- `lib/conversation.ts` - transcript normalization and agent visualizer mapping
- `types/conversation.ts` - shared request/response contracts
## Local Gemma setup
This demo supports two local model modes:
- LM Studio with its local server
- Ollama
For your current LM Studio setup, use:
```bash
GEMMA_BASE_URL=http://localhost:12345
GEMMA_CHAT_URL=http://localhost:12345/api/v1/chat
GEMMA_MODEL=google/gemma-4-e2b
GEMMA_TIMEOUT_MS=30000
```
In LM Studio, make sure the model is downloaded and the local server is running. Set `GEMMA_MODEL` to the exact model identifier shown in LM Studio. The code now reads the final `message` output from LM Studio, not the reasoning block.
If you want the live Agora voice session to work from your laptop, tunnel the Next.js app, not the LM Studio port:
```bash
ngrok http 3000
```
Then set:
```bash
GEMMA_PUBLIC_CHAT_URL=https://your-ngrok-domain.ngrok-free.dev/api/chat/completions
```
Agora should call that public Next.js proxy route. The proxy route then calls your local LM Studio server.
If you want the Ollama path instead, run:
```bash
ollama pull gemma3:4b
ollama run gemma3:4b
```
## Agora env setup
Required Agora environment variables:
- `NEXT_PUBLIC_AGORA_APP_ID`
- `NEXT_AGORA_APP_CERTIFICATE`
Optional Agora behavior variables:
- `NEXT_PUBLIC_AGENT_UID` defaults to `123456`
- `NEXT_AGENT_GREETING`
Copy `.env.example` to `.env.local` and fill in the required values before starting the app.
## Run commands
```bash
pnpm install
pnpm dev
```
Additional validation commands:
```bash
pnpm run lint
pnpm run typecheck
pnpm run build
```
## Troubleshooting
- If `/api/generate-agora-token` returns an env error, verify `NEXT_PUBLIC_AGORA_APP_ID` and `NEXT_AGORA_APP_CERTIFICATE`.
- If `/api/gemma/test` fails, confirm LM Studio or Ollama is running and that `GEMMA_BASE_URL` and `GEMMA_CHAT_URL` match the local server.
- If the browser says microphone access is denied, allow microphone permissions in the browser and try again.
- If the conversation starts but no transcript appears, verify the Agora agent invite succeeded and that the RTM token is valid.
- If `pnpm install` reports ignored build scripts for `sharp` or `unrs-resolver`, run `pnpm approve-builds` in environments that require postinstall scripts.
- If the default `pnpm run build` hits a Turbopack sandbox error in Codex, use `pnpm exec next build --webpack` for local validation.
- If the app fails to build, run `pnpm run typecheck` first to catch type issues, then `pnpm run lint`.
## Known limitations
- The live Agora voice demo still uses the managed agent lifecycle from the reference quickstart.
- Agora must call a public `GEMMA_PUBLIC_CHAT_URL` that points to the Next.js proxy route. That proxy route then calls your local model server.
- The demo expects a local model server, such as LM Studio or Ollama, to be running on your machine for local testing.
- The UI is designed for local demos and does not yet include production auth, user accounts, or persistence.
## How to test Gemma
1. Start LM Studio or Ollama.
2. Run:
```bash
pnpm dev
```
3. In a second terminal, tunnel the Next.js app:
```bash
ngrok http 3000
```
4. Set `GEMMA_BASE_URL` to your local model server.
5. Set `GEMMA_CHAT_URL` to your LM Studio chat endpoint if you are using LM Studio.
6. Set `GEMMA_PUBLIC_CHAT_URL` to the ngrok URL plus `/api/chat/completions`.
7. Open `/api/gemma/test` in the browser or hit it with `curl`.
8. Use `/api/gemma/chat` with a JSON body containing a `messages` array.
9. Optionally test the proxy directly:
```bash
curl -N http://localhost:3000/api/chat/completions \
-H 'Content-Type: application/json' \
-d '{"messages":[{"role":"user","content":"Say hello in one short sentence."}]}'
```
## How to start Agora voice demo
1. Set the Agora env vars in `.env.local`.
2. Keep `GEMMA_BASE_URL` pointed at your local model server.
3. Set `GEMMA_CHAT_URL` to the LM Studio chat endpoint if you use LM Studio.
4. Set `GEMMA_PUBLIC_CHAT_URL` to the public ngrok URL for `app/api/chat/completions`.
5. Start the app:
```bash
pnpm dev
```
6. Open the UI in the browser.
7. Click `Start Conversation`.
8. Allow microphone permissions when prompted.
9. Use `End Conversation` when you are done.
## Final validation
To validate the repo locally, run:
```bash
pnpm install
pnpm run lint
pnpm run typecheck
pnpm run build
```
Then confirm:
- `/api/gemma/test` returns a reachable response when Ollama, LM Studio, or the local model server is running
- the app starts locally with `pnpm dev`
- the Agora voice flow still starts and stops cleanly from the UI