Troubleshoot Skill
Use this skill to diagnose problems in the Real-Time Voice Agent pipeline. This is a
read-only investigative workflow: gather evidence, reason about it, ask the user for the
details you don't have, then hand back a clear findings + recommended-fix report.
🧭 Golden rule: Diagnose, don't change. You find and explain the problem. The user
decides whether and how to apply the fix.
🚧 Guardrails (read this first)
You MUST NOT (without explicit, per-action user approval):
- ❌ Edit code, YAML,
.env*, Terraform, Bicep, or any config file
- ❌ Run state-changing Azure/infra commands:
azd up, azd provision, azd deploy,
azd down, azd env set, terraform apply/destroy, az ... create/update/delete,
az containerapp update, scaling, restarts, key rotation
- ❌ Run
git commit, git push, git reset, branch deletes, or bd writes
- ❌ Restart, redeploy, purge, or "nuke and redeploy" anything as a shortcut
- ❌ Invoke any MCP tool with a write side-effect (e.g. anything that creates GitHub issues,
updates resources, or scales/restarts) — including a "scan" tool whose options default to writing
- ❌ Print secrets/connection strings/keys in full — mask them (
endpoint=...;accesskey=***)
You MUST:
- ✅ Prefer read-only commands (
show, list, get, logs, query, curl, ping)
- ✅ Ask before assuming — see Step 0. Probe for the missing detail instead of guessing
- ✅ Present a fix as a recommendation the user applies, or ask for approval before running it
- ✅ State your confidence and what evidence is still missing
If a fix genuinely requires a write action, stop and propose it — show the exact command,
explain the blast radius, and let the user run it or approve it.
Step 0 — Ask before you assume
Never start guessing. First pin down the situation with a few targeted questions. Ask only
what you can't already infer from the repo or the user's message:
- Where is it failing? Local dev (
make start_backend) or deployed (Container Apps via azd)?
- Which environment? (
azd env list shows them — confirm which one.)
- What's the symptom, concretely? Error text, no audio, dropped call, high latency,
wrong agent, silence, garbled speech, 4xx/5xx, timeout?
- What changed recently? New deploy, config edit, region, model, phone number, dependency bump?
- Reproducibility? Every call or intermittent? A specific agent/scenario/number?
- What do you already have? Logs, a
call_id/correlation id, screenshots, the azd env values?
If the user gives a vague report ("calls don't work"), ask for one concrete failing example
(a call_id, a timestamp, the exact error) before diving in. One good example beats ten guesses.
Triage map — symptom → likely layer
| Symptom |
Start at |
Key signals |
azd up/provision fails |
Deploy & infra |
preflight, providers, quota, TF state lock |
| Call never connects / webhook silent |
Telephony (ACS) |
webhook reachable, ACS conn string, devtunnel |
| Call connects, no/garbled transcript |
STT |
Speech key/region, streaming mode, audio format |
| Long pauses before agent replies |
LLM |
AOAI deployment, quota/429, token limits, streaming |
| No audio back / robotic / cut off |
TTS |
voice name, TTS pool, barge-in/VAD |
| Wrong agent or no handoff |
Orchestration |
scenario YAML, agent registry, handoff service |
| State lost / session resets |
Redis/state |
Redis reachability, MemoManager, worker affinity |
| Container unhealthy / restart loop |
Runtime |
readiness checks, env propagation, startup logs |
Read-only diagnostic playbook
Azure MCP (preferred fast path for deployed envs)
If an Azure SRE-agent MCP server is wired into this workspace, prefer its purpose-built
tools over hand-rolled CLI — they already know the ARTagent topology. Confirm they're available
first (don't assume; if no Azure MCP is connected, fall back to the az/curl commands below):
| Tool |
Use it for |
Read-only? |
check_deployment_health |
One-shot health of all services + deps for dev/staging/prod |
✅ yes |
analyze_deployment_logs |
App Insights logs by service (rtaudio-server/rtaudio-client/all), severity, time_range |
✅ yes |
analyze_pool_metrics |
STT/TTS warm-pool utilization & exhaustion risk (time_range, alert_threshold) |
✅ yes |
analyze_voice_channel_security |
WebSocket auth / rate-limit / pool security scan |
⚠️ see warning |
⚠️ analyze_voice_channel_security defaults auto_create_issues: true — that creates
GitHub issues (a write action). Under these guardrails you must call it with
auto_create_issues: false, or get explicit user approval before letting it file issues.
Generic Azure MCP servers (resource lookup, az-equivalent, App Insights KQL) are fine too —
use only their read operations (get/list/show/query). Never invoke create/update/delete
MCP operations as part of diagnosis. If you need historical KQL/latency analysis, hand off to the
observability-insights skill.
A. Local dev
# Is the backend up and what does it think is healthy?
curl -s http://localhost:8010/api/v1/health | jq .
curl -s http://localhost:8010/api/v1/readiness | jq '{status, checks}'
curl -s http://localhost:8010/api/v1/pools | jq .
curl -s http://localhost:8010/api/v1/metrics/summary | jq .
# Port already taken? (inspect only — do NOT kill without asking)
lsof -iTCP:8010 -sTCP:LISTEN -n -P
# What config does the app actually see? (mask before sharing)
azd env get-values 2>/dev/null | sed -E 's/(accesskey|key|password|secret)=[^;]*/\1=***/gi'
B. Deployed (Container Apps)
# Resolve the deployed backend from azd artifacts
azd env select <env>
BACKEND="https://$(azd env get-value BACKEND_CONTAINER_APP_FQDN)"
# Health across all dependencies (read-only)
curl -s --max-time 10 "$BACKEND/api/v1/readiness" | jq '{status, checks}'
# Or run the bundled script
./devops/scripts/quick_health_check.sh <env>
# Live + recent logs (read-only)
az containerapp logs show --name <app> --resource-group <rg> --follow # tail
az containerapp logs show --name <app> --resource-group <rg> --tail 200 # snapshot
az containerapp revision list --name <app> --resource-group <rg> -o table # which revision is live
C. Per-layer probes
# Redis / state
make test_redis_connection # connectivity only
make connect_redis # interactive inspect (read keys; don't FLUSH)
# App Config (what runtime values resolve to)
make show_appconfig
make show_appconfig_acs
# Azure OpenAI quota / 429 cause (read-only)
az cognitiveservices account deployment list -g <rg> -n <openai-account> -o table
az cognitiveservices usage list -l <region> -o json \
| jq -r '.[] | select(.name.value | startswith("OpenAI.")) | "\(.name.value)\t\(.currentValue)/\(.limit)"'
When the problem needs historical traces, latency percentiles, or a call timeline across
the deployed stack, switch to the observability-insights skill — it builds the wider
picture from Azure Monitor / Log Analytics and renders it as KQL + diagrams.
How to reason
- Confirm the layer using the triage map and the health/readiness output (don't assume).
- Pull evidence with read-only commands for that layer only — avoid shotgun-running everything.
- Correlate by
call.connection.id (ACS), session.id (browser), or operation_Id across logs, traces, and the user's report — App Insights has no call_id field.
- Form one hypothesis at a time, name the evidence for and against it, and the gap.
- If evidence is missing, ask the user for the specific artifact rather than assuming.
Output format
End every investigation with this structure:
### Diagnosis
- **Symptom:** <what the user observed>
- **Most likely cause:** <layer + root cause> (confidence: high/medium/low)
- **Evidence:** <commands run + key lines, secrets masked>
- **Still unknown:** <what you'd need to confirm>
### Recommended fix (you apply this)
1. <exact command or file edit, shown — not executed without approval>
2. <verification step to confirm it worked>
### If that doesn't resolve it
- <next hypothesis to test>
Reference
- Quick fixes by error:
TROUBLESHOOTING.md
- Deploy flow & hooks:
deployment-guide skill
- Wider context + visuals:
observability-insights skill
- Azure MCP fast path (when connected): SRE-agent
check_deployment_health, analyze_deployment_logs, analyze_pool_metrics, analyze_voice_channel_security (set auto_create_issues: false)
- Health endpoints:
apps/artagent/backend/api/v1/endpoints/health.py
- Health script:
devops/scripts/quick_health_check.sh
1---2name: troubleshoot3description: Agent-first, read-only diagnosis of the voice pipeline (deploy, telephony, STT, LLM, TTS, state) — gather evidence via Azure MCP / azd artifacts / CLI, probe the user for missing details, and recommend fixes without changing anything4---56# Troubleshoot Skill78Use this skill to **diagnose** problems in the Real-Time Voice Agent pipeline. This is a9read-only investigative workflow: gather evidence, reason about it, ask the user for the10details you don't have, then hand back a clear findings + recommended-fix report.1112> **🧭 Golden rule:** Diagnose, don't change. You find and explain the problem. The **user**13> decides whether and how to apply the fix.1415---1617## 🚧 Guardrails (read this first)1819**You MUST NOT** (without explicit, per-action user approval):2021- ❌ Edit code, YAML, `.env*`, Terraform, Bicep, or any config file22- ❌ Run state-changing Azure/infra commands: `azd up`, `azd provision`, `azd deploy`,23 `azd down`, `azd env set`, `terraform apply/destroy`, `az ... create/update/delete`,24 `az containerapp update`, scaling, restarts, key rotation25- ❌ Run `git commit`, `git push`, `git reset`, branch deletes, or `bd` writes26- ❌ Restart, redeploy, purge, or "nuke and redeploy" anything as a shortcut27- ❌ Invoke any **MCP tool with a write side-effect** (e.g. anything that creates GitHub issues,28 updates resources, or scales/restarts) — including a "scan" tool whose options default to writing29- ❌ Print secrets/connection strings/keys in full — mask them (`endpoint=...;accesskey=***`)3031**You MUST**:3233- ✅ Prefer **read-only** commands (`show`, `list`, `get`, `logs`, `query`, `curl`, `ping`)34- ✅ **Ask before assuming** — see Step 0. Probe for the missing detail instead of guessing35- ✅ Present a **fix as a recommendation** the user applies, or ask for approval before running it36- ✅ State your confidence and what evidence is still missing3738If a fix genuinely requires a write action, **stop and propose it** — show the exact command,39explain the blast radius, and let the user run it or approve it.4041---4243## Step 0 — Ask before you assume4445Never start guessing. First pin down the situation with a few targeted questions. Ask only46what you can't already infer from the repo or the user's message:47481. **Where is it failing?** Local dev (`make start_backend`) or deployed (Container Apps via `azd`)?492. **Which environment?** (`azd env list` shows them — confirm which one.)503. **What's the symptom, concretely?** Error text, no audio, dropped call, high latency,51 wrong agent, silence, garbled speech, 4xx/5xx, timeout?524. **What changed recently?** New deploy, config edit, region, model, phone number, dependency bump?535. **Reproducibility?** Every call or intermittent? A specific agent/scenario/number?546. **What do you already have?** Logs, a `call_id`/correlation id, screenshots, the azd env values?5556> If the user gives a vague report ("calls don't work"), ask for one concrete failing example57> (a `call_id`, a timestamp, the exact error) before diving in. One good example beats ten guesses.5859---6061## Triage map — symptom → likely layer6263| Symptom | Start at | Key signals |64| --- | --- | --- |65| `azd up`/provision fails | Deploy & infra | preflight, providers, quota, TF state lock |66| Call never connects / webhook silent | Telephony (ACS) | webhook reachable, ACS conn string, devtunnel |67| Call connects, no/garbled transcript | STT | Speech key/region, streaming mode, audio format |68| Long pauses before agent replies | LLM | AOAI deployment, quota/429, token limits, streaming |69| No audio back / robotic / cut off | TTS | voice name, TTS pool, barge-in/VAD |70| Wrong agent or no handoff | Orchestration | scenario YAML, agent registry, handoff service |71| State lost / session resets | Redis/state | Redis reachability, MemoManager, worker affinity |72| Container unhealthy / restart loop | Runtime | readiness checks, env propagation, startup logs |7374---7576## Read-only diagnostic playbook7778### Azure MCP (preferred fast path for deployed envs)7980If an **Azure SRE-agent MCP server** is wired into this workspace, prefer its purpose-built81tools over hand-rolled CLI — they already know the ARTagent topology. Confirm they're available82first (don't assume; if no Azure MCP is connected, fall back to the `az`/`curl` commands below):8384| Tool | Use it for | Read-only? |85| --- | --- | --- |86| `check_deployment_health` | One-shot health of all services + deps for `dev`/`staging`/`prod` | ✅ yes |87| `analyze_deployment_logs` | App Insights logs by `service` (`rtaudio-server`/`rtaudio-client`/`all`), `severity`, `time_range` | ✅ yes |88| `analyze_pool_metrics` | STT/TTS warm-pool utilization & exhaustion risk (`time_range`, `alert_threshold`) | ✅ yes |89| `analyze_voice_channel_security` | WebSocket auth / rate-limit / pool security scan | ⚠️ **see warning** |9091> **⚠️ `analyze_voice_channel_security` defaults `auto_create_issues: true`** — that **creates92> GitHub issues** (a write action). Under these guardrails you must call it with93> `auto_create_issues: false`, or get explicit user approval before letting it file issues.9495Generic Azure MCP servers (resource lookup, `az`-equivalent, App Insights KQL) are fine too —96use only their **read** operations (`get`/`list`/`show`/`query`). Never invoke create/update/delete97MCP operations as part of diagnosis. If you need historical KQL/latency analysis, hand off to the98`observability-insights` skill.99100### A. Local dev101102```bash103# Is the backend up and what does it think is healthy?104curl -s http://localhost:8010/api/v1/health | jq .105curl -s http://localhost:8010/api/v1/readiness | jq '{status, checks}'106curl -s http://localhost:8010/api/v1/pools | jq .107curl -s http://localhost:8010/api/v1/metrics/summary | jq .108109# Port already taken? (inspect only — do NOT kill without asking)110lsof -iTCP:8010 -sTCP:LISTEN -n -P111112# What config does the app actually see? (mask before sharing)113azd env get-values 2>/dev/null | sed -E 's/(accesskey|key|password|secret)=[^;]*/\1=***/gi'114```115116### B. Deployed (Container Apps)117118```bash119# Resolve the deployed backend from azd artifacts120azd env select <env>121BACKEND="https://$(azd env get-value BACKEND_CONTAINER_APP_FQDN)"122123# Health across all dependencies (read-only)124curl -s --max-time 10 "$BACKEND/api/v1/readiness" | jq '{status, checks}'125126# Or run the bundled script127./devops/scripts/quick_health_check.sh <env>128129# Live + recent logs (read-only)130az containerapp logs show --name <app> --resource-group <rg> --follow # tail131az containerapp logs show --name <app> --resource-group <rg> --tail 200 # snapshot132az containerapp revision list --name <app> --resource-group <rg> -o table # which revision is live133```134135### C. Per-layer probes136137```bash138# Redis / state139make test_redis_connection # connectivity only140make connect_redis # interactive inspect (read keys; don't FLUSH)141142# App Config (what runtime values resolve to)143make show_appconfig144make show_appconfig_acs145146# Azure OpenAI quota / 429 cause (read-only)147az cognitiveservices account deployment list -g <rg> -n <openai-account> -o table148az cognitiveservices usage list -l <region> -o json \149 | jq -r '.[] | select(.name.value | startswith("OpenAI.")) | "\(.name.value)\t\(.currentValue)/\(.limit)"'150```151152When the problem needs **historical traces, latency percentiles, or a call timeline** across153the deployed stack, switch to the **`observability-insights`** skill — it builds the wider154picture from Azure Monitor / Log Analytics and renders it as KQL + diagrams.155156---157158## How to reason1591601. **Confirm the layer** using the triage map and the health/readiness output (don't assume).1612. **Pull evidence** with read-only commands for that layer only — avoid shotgun-running everything.1623. **Correlate** by `call.connection.id` (ACS), `session.id` (browser), or `operation_Id` across logs, traces, and the user's report — App Insights has no `call_id` field.1634. **Form one hypothesis at a time**, name the evidence for and against it, and the gap.1645. If evidence is missing, **ask the user** for the specific artifact rather than assuming.165166---167168## Output format169170End every investigation with this structure:171172```markdown173### Diagnosis174- **Symptom:** <what the user observed>175- **Most likely cause:** <layer + root cause> (confidence: high/medium/low)176- **Evidence:** <commands run + key lines, secrets masked>177- **Still unknown:** <what you'd need to confirm>178179### Recommended fix (you apply this)1801. <exact command or file edit, shown — not executed without approval>1812. <verification step to confirm it worked>182183### If that doesn't resolve it184- <next hypothesis to test>185```186187---188189## Reference190191- Quick fixes by error: [`TROUBLESHOOTING.md`](../../../TROUBLESHOOTING.md)192- Deploy flow & hooks: `deployment-guide` skill193- Wider context + visuals: `observability-insights` skill194- Azure MCP fast path (when connected): SRE-agent `check_deployment_health`, `analyze_deployment_logs`, `analyze_pool_metrics`, `analyze_voice_channel_security` (set `auto_create_issues: false`)195- Health endpoints: `apps/artagent/backend/api/v1/endpoints/health.py`196- Health script: `devops/scripts/quick_health_check.sh`