docs/Inbound Q&A

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.

property_insurance.py
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.

property_insurance.py
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.

property_insurance.py
@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.

property_insurance.py
# 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

property_insurance.py
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