Build Reliable Conversational AI with Parlant: Insurance Agent Tutorial

Parlant is a framework for building production-ready AI agents that behave consistently and predictably. It shifts the focus from brittle prompt engineering to principle-driven development, letting you define rules, tool integrations, and conversation journeys so agents can access real-world data safely and reliably.

Why Parlant?

Large language model agents can perform well in tests but fail in real interactions: ignoring system prompts, returning irrelevant or incorrect responses at critical moments, and producing inconsistent behavior across conversations. Parlant mitigates these problems by providing structured mechanisms for tool access, domain glossaries, journey-based conversation flows, and global guidelines that guide the agent’s behavior beyond ad-hoc prompts.

Installing and importing the dependencies

Start by installing the Parlant SDK and importing the libraries you’ll need:

pip install parlant
import asyncio
from datetime import datetime
import parlant.sdk as p

Defining the tools

Tools provide the agent with deterministic access to domain capabilities and external data. In this example we define three tools an insurance assistant might use: retrieving open claims, filing a new claim, and fetching policy details. These tools are declared as async functions and decorated with @p.tool so the agent can call them when appropriate.

@p.tool
async def get_open_claims(context: p.ToolContext) -> p.ToolResult:
    return p.ToolResult(data=["Claim #123 - Pending", "Claim #456 - Approved"])
@p.tool
async def file_claim(context: p.ToolContext, claim_details: str) -> p.ToolResult:
    return p.ToolResult(data=f"New claim filed: {claim_details}")
@p.tool
async def get_policy_details(context: p.ToolContext) -> p.ToolResult:
    return p.ToolResult(data={
        "policy_number": "POL-7788",
        "coverage": "Covers accidental damage and theft up to $50,000"
    })

Glossary and journeys

A glossary captures important business terms and facts the agent should reference (for example, contact numbers or hours). Journeys define step-by-step conversation flows for common tasks so the agent can reliably walk users through processes like filing a claim or explaining coverage.

async def add_domain_glossary(agent: p.Agent):
    await agent.create_term(
        name="Customer Service Number",
        description="You can reach us at +1-555-INSURE",
    )
    await agent.create_term(
        name="Operating Hours",
        description="We are available Mon-Fri, 9AM-6PM",
    )
async def create_claim_journey(agent: p.Agent) -> p.Journey:
    journey = await agent.create_journey(
        title="File an Insurance Claim",
        description="Helps customers report and submit a new claim.",
        conditions=["The customer wants to file a claim"],
    )
    s0 = await journey.initial_state.transition_to(chat_state="Ask for accident details")
    s1 = await s0.target.transition_to(tool_state=file_claim, condition="Customer provides details")
    s2 = await s1.target.transition_to(chat_state="Confirm claim was submitted")
    await s2.target.transition_to(state=p.END_JOURNEY)
    return journey
async def create_policy_journey(agent: p.Agent) -> p.Journey:
    journey = await agent.create_journey(
        title="Explain Policy Coverage",
        description="Retrieves and explains customer's insurance coverage.",
        conditions=["The customer asks about their policy"],
    )
    s0 = await journey.initial_state.transition_to(tool_state=get_policy_details)
    await s0.target.transition_to(
        chat_state="Explain the policy coverage clearly",
        condition="Policy info is available",
    )
    await agent.create_guideline(
        condition="Customer presses for legal interpretation of coverage",
        action="Politely explain that legal advice cannot be provided",
    )
    return journey

Main runner and launching the agent

The main runner brings everything together: it starts a Parlant server, creates the insurance agent, loads glossary terms, journeys, and global guidelines, and sets up disambiguation logic for ambiguous intents. After launching, the script exposes a UI at http://localhost:8800 where you can interact with the agent in real time.

async def main():
    async with p.Server() as server:
        agent = await server.create_agent(
            name="Insurance Support Agent",
            description="Friendly and professional; helps with claims and policy queries.",
        )
        await add_domain_glossary(agent)
        claim_journey = await create_claim_journey(agent)
        policy_journey = await create_policy_journey(agent)
        # Disambiguation: if intent is unclear
        status_obs = await agent.create_observation(
            "Customer mentions an issue but doesn't specify if it's a claim or policy"
        )
        await status_obs.disambiguate([claim_journey, policy_journey])
        # Global guideline
        await agent.create_guideline(
            condition="Customer asks about unrelated topics",
            action="Kindly redirect them to insurance-related support only",
        )
        print(" Insurance Agent is ready! Open the Parlant UI to chat.")
if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

Try it locally and extend

Run the script to start the Parlant server and open the UI. From there you can test the agent, extend tools to hit real APIs, enrich the glossary with domain facts, and add journeys for other workflows. Check out the project repository for full examples, notebooks, and tutorials.