signal-keynote-demo.mp4
This demo showcases a multi-agent, voice-based AI system using Twilio ConversationRelay, Azure OpenAI, Azure AI Search, and Azure Foundry. It implements the Talker-Reasoner architecture (paper), a pattern for building agentic voice systems.
-
Talker Agent
- Handles real-time voice interaction with the user
- Focused on fluency, latency, and dialogue continuity
- Delegates complex tasks to background processes or back-office agents
-
Subconscious Background Processes (Reasoners)
- Run in parallel without interrupting the user experience
- Examples in this demo:
- Vector Memory: Long-term memory retrieval via Azure AI Search (semantic vector index)
- Summarizer: Monitors user sentiment and topics using lightweight LLM logic
-
Back-Office Agents
- Additional autonomous agents the Talker can query when needed
- Built using Azure Foundry
- Handle domain-specific reasoning and slower, computation-heavy tasks
- Support a modular architecture without burdening the main conversational loop
The demo includes a split-screen view of:
- Frontend UI: The user-facing voice interface powered by Twilio
- Backend View: Real-time agent orchestration, including background reasoning, memory queries, and inter-agent messaging
- Create API key and token and set
.env
file paramsTWILIO_API_KEY
andTWILIO_API_SECRET
respectively - Create Sync service and set
TWILIO_SYNC_SVC_SID
in both the.env
file and theui/.env
file - In the
.env.example
file, at the end are two mp3 files that need to be uploaded as Twilio assets, and their URLs set respectively - Set the
DEFAULT_TWILIO_NUMBER
to a number from your Twilio account that can make outbound calls - Set the
DEMO_USER_*
variables to your demo user - Assign an incoming number (can be the same as outbound)
- Set the Webhook to be
<YOUR_SERVER>/incoming-call
- Set the Call status changes to be
<YOUR_SERVER>/call-status
- Set the Webhook to be
Most configuration will occur in the Azure AI Foundry or the Azure portal
Create an Azure account and login to https://portal.azure.com/
Ensure you have an subscription, the transcript storage service uses Azure AI Search which is not available on the free tier.
The following steps are performed in the UI, these can also be completed by commandline or terraform.
- In the search bar enter
AI Search
and select the service - Create a new service, by pressing the + icon
- Select your subscription, enter service name e.g.
svc-crelay-search
, choose deployment region - Create a new index, called
transcript-store
, use the<proj>/server/agents/recall/setup/search-schema.json
as the input schema - In the
.env
file set theAZURE_SEARCH_INDEX
to the name of the index just created, e.g.transcript-store
- Also set the
AZURE_SEARCH_ENDPOINT
url to the Search service just created, can be found under Overview on the side menu - Lastly, set the
AZURE_ADMIN_KEY
, which can be found under Settings > Keys > Primary Admin Key
Login to Azure AI Foundry
- Create a new project and give it an awesome name
- From the Overview page, copy the
API Key
on the first page and set theFOUNDRY_API_KEY
environment variable - Also on the overview page, copy the
Azure AI Foundry project endpoint
and set theAZURE_CONN_STRING
var - Deploy the Open AI GPT 4.1 (or similar) model
- From Azure OpenAI > Copy the
Azure OpenAI endpoint
and set theAZURE_LLM_ENDPOINT
var - Set the
AZURE_LLM_DEPLOYMENT
togpt-4.1
(or whatever model you deployed), can be found underMy assets > Models + Endpoints
- From the model catalog, deploy the
text-embedding-3-large
model, set theEMBED_ENDPOINT
environment variable
Login to Azure AI Foundry
- Create an agent
- Copy the agent ID, starting with
asst_
and put it in the.env
file variable namedUNDERWRITER_AGENT_ID
- Copy or edit the prompt from file
<proj>/server/agents/underwriter-agent/instructions.md
- Add Agent Action. Copy
<proj>/server/agents/underwriter-agent/tool-manifest.json
into schema of as anOpenAPI 3.0 specified tool
Action and name itUnderwriterBrainTool
. Note: Replace{HOSTNAME}
with your ngrok hostname
Ensure Azure CLI is installed
OSX
brew update && brew install azure-cli
This will be used in the Fly.io deployment (or other hosting service) The steps below walks you through creating a service user (Service Principal) in Azure and collecting the necessary credentials for automation, scripting, or integration purposes.
- Go to the Azure Portal
- Navigate to: Microsoft Entra ID > App registrations
- Click + New registration
- Fill in the form:
- Name:
my-service-user
- Supported account types: Accounts in this organizational directory only (Default)
- Redirect URI: (Optional) Leave blank unless needed
- Name:
- Click Register
📌 Save these values from the Overview page:
CLIENT_ID
= Application (client) IDTENANT_ID
= Directory (tenant) ID
- After registration, go to Certificates & secrets
- Click + New client secret
- Enter a description and choose an expiry (e.g., 6 months, 12 months)
- Click Add
- Copy the generated secret value immediately
📌 Save this value:
CLIENT_SECRET
= The generated secret value
⚠️ You will not be able to retrieve the secret again after leaving the page.
- Go to Subscriptions
- Select your target Subscription
- Click Access control (IAM) > + Add > Add role assignment
- In the Role tab, select a roles
Azure AI User
andCognitive Services Contributor
- In the Members tab:
- Click + Select members
- Search for the registered app by name
- Select it and click Review + assign
- Go to Subscriptions
- Select your active subscription
- Copy the Subscription ID from the overview pane
📌 Save this value:
SUBSCRIPTION_ID
= The Subscription's GUID
fly launch
to launch a new app with Fly- copy all the
.env
configuration to respective[env]
variables infly.toml
- copy secrets to
.env.flysecrets
- import the secrets using
fly secrets import < ./.env.flysecrets
Once the application has been deployed (or before running locally) ensure that the Twilio Sync objects are populated by running the script:
pnpm run data:populate