Inbound Example w/ RAG
In this example, we'll build an inbound voice agent for a fictional property insurance company. Callers can ask any question about their policy and receive accurate answers sourced from a policy document.
Define the Agent
guava.Agent is our starting point for building Guava agents. We'll start by creating one with some basic background details.
import guava
agent = guava.Agent(
organization="Harper Valley Property Insurance",
purpose="Answer questions regarding property insurance policy until there are no more questions",
)Guava discourages long system prompts that try to cover every scenario. The purpose is intentionally short and designed to orient the agent.
Set up DocumentQA
Next, we initialize a DocumentQA instance with the policy document. DocumentQA is a built-in RAG that covers a lot of simple use cases. It's a fully pluggable component
and we expect many users will bring their own RAG system.
from guava.helpers.rag import DocumentQA
from guava.examples.example_data import PROPERTY_INSURANCE_POLICY
document_qa = DocumentQA(documents=PROPERTY_INSURANCE_POLICY)Handle questions with on_question
Whenever the caller asks something the agent cannot answer from context alone, Guava invokes the on_question callback with the question in natural language. We forward it to DocumentQA and return the answer.
@agent.on_question
def on_question(call: guava.Call, question: str) -> str:
return document_qa.ask(question)The agent remains fully responsive during the lookup — it continues listening and engaging with the caller while waiting for your response. You are not latency-constrained in your on_question implementation.
Bring your own RAG. The on_question callback receives a plain string and expects a plain string back — you can plug in any knowledge base, vector store, or model you prefer.
Start the agent
Finally, we attach the agent to a channel so that we can actually talk to it.
# Run this to attach your agent to a phone number. Call your agent's number to talk to it.
agent.listen_phone(os.environ["GUAVA_AGENT_NUMBER"])
# Run this to receive a WebRTC link where you can talk to your agent in the browser.
agent.listen_webrtc()
# Run this to talk to your agent using your local audio device.
agent.call_local()No web servers required. Guava does not require a public web server to receive inbound calls. All Guava agents can be hosted behind firewalls and NATs.
Complete example
import logging
import os
import guava
import argparse
from guava.helpers.rag import DocumentQA
from guava import logging_utils, Agent
from guava.examples.example_data import PROPERTY_INSURANCE_POLICY
logger = logging.getLogger("guava.examples.property_insurance")
agent = Agent(
organization="Harper Valley Property Insurance",
purpose="Answer questions regarding property insurance policy until there are no more questions",
)
# This is a built-in knowledge base helper that we will use for this example.
# You can use any RAG system you prefer.
document_qa = DocumentQA(documents=PROPERTY_INSURANCE_POLICY)
# When the Agent is asked a question that it cannot answer, it will invoke the on_question callback.
@agent.on_question
def on_question(call: guava.Call, question: str) -> str:
# Forward the Agent's question to the knowledge base and return the answer.
# You can plug in any knowledge base system you want here.
answer = document_qa.ask(question)
logger.info("RAG answer: %s", answer)
return answer
if __name__ == "__main__":
logging_utils.configure_logging()
# Every Agent can be attached to multiple resources.
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--phone", action="store_true", help="Listen for phone calls.")
group.add_argument("--webrtc", action="store_true", help="Create on a WebRTC code.")
group.add_argument("--local", action="store_true", help="Start a local call.")
args = parser.parse_args()
# We can attach our agent to receive inbound phone or WebRTC calls.
if args.phone:
agent.listen_phone(os.environ["GUAVA_AGENT_NUMBER"])
elif args.webrtc:
agent.listen_webrtc()
else:
agent.call_local()Questions? hi@goguava.ai
import guava
agent = guava.Agent(
organization="Harper Valley Property Insurance",
purpose="Answer questions regarding property insurance policy until there are no more questions",
)from guava.helpers.rag import DocumentQA
from guava.examples.example_data import PROPERTY_INSURANCE_POLICY
document_qa = DocumentQA(documents=PROPERTY_INSURANCE_POLICY)@agent.on_question
def on_question(call: guava.Call, question: str) -> str:
return document_qa.ask(question)# Run this to attach your agent to a phone number. Call your agent's number to talk to it.
agent.listen_phone(os.environ["GUAVA_AGENT_NUMBER"])
# Run this to receive a WebRTC link where you can talk to your agent in the browser.
agent.listen_webrtc()
# Run this to talk to your agent using your local audio device.
agent.call_local()import logging
import os
import guava
import argparse
from guava.helpers.rag import DocumentQA
from guava import logging_utils, Agent
from guava.examples.example_data import PROPERTY_INSURANCE_POLICY
logger = logging.getLogger("guava.examples.property_insurance")
agent = Agent(
organization="Harper Valley Property Insurance",
purpose="Answer questions regarding property insurance policy until there are no more questions",
)
# This is a built-in knowledge base helper that we will use for this example.
# You can use any RAG system you prefer.
document_qa = DocumentQA(documents=PROPERTY_INSURANCE_POLICY)
# When the Agent is asked a question that it cannot answer, it will invoke the on_question callback.
@agent.on_question
def on_question(call: guava.Call, question: str) -> str:
# Forward the Agent's question to the knowledge base and return the answer.
# You can plug in any knowledge base system you want here.
answer = document_qa.ask(question)
logger.info("RAG answer: %s", answer)
return answer
if __name__ == "__main__":
logging_utils.configure_logging()
# Every Agent can be attached to multiple resources.
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--phone", action="store_true", help="Listen for phone calls.")
group.add_argument("--webrtc", action="store_true", help="Create on a WebRTC code.")
group.add_argument("--local", action="store_true", help="Start a local call.")
args = parser.parse_args()
# We can attach our agent to receive inbound phone or WebRTC calls.
if args.phone:
agent.listen_phone(os.environ["GUAVA_AGENT_NUMBER"])
elif args.webrtc:
agent.listen_webrtc()
else:
agent.call_local()