parlant README

The project's README from github.com/emcie-co/parlant. As one markdown file: README.md.

Parlant

The interaction control harness for customer-facing AI agents

PyPI Python 3.10+ License Discord GitHub Repo stars

Website • Quick Start • Examples • Discord

Deutsch | Español | français | 日本語 | 한국어 | Português | Русский | 中文

Trending

 

Looking for an open-source alternative to Ada, Decagon, or Sierra?

Parlant is production-ready. It streamlines the development and maintenance of enterprise-grade B2C (business-to-consumer) and sensitive B2B interactions that need to be consistent, compliant, on-brand, and comprehensively traceable.

Why Parlant?

Conversational context engineering is hard because real-world interactions are diverse, nuanced, and non-linear.

❌ The Problem: What you've probably tried and couldn't get to work at scale

System prompts work until production complexity kicks in. The more instructions you add to a prompt, the faster your agent stops paying attention to any of them.

Routed graphs solve the prompt-overload problem, but the more routing you add, the more fragile it becomes when faced with the chaos of natural interactions.

🔑 The Solution: Context engineering, optimized for conversational control

Parlant is an agentic harness offering optimized context engineering for conversational use cases: getting the right context, no more and no less, into the prompt at the right time. You define rules, knowledge, and tools once, while the engine narrows the context down in real-time to what's immediately relevant to each turn of the conversation.

Parlant Demo

How is Parlant different from LangGraph or DSPy?

Parlant focuses on conversational governance and behavioral control and consistency, while LangGraph is ideal for workflow automation, and DSPy is ideal for low-level prompt optimization.

Design goals

Parlant is built around three goals that shape every decision in the framework:

1. Maximum control over the conversation experience

Parlant was designed around a simple idea: developers should be able to control the agent's behavior with precision. In customer-facing conversations, small details matter, like tone, timing, edge cases, policy constraints, and brand voice. So we chose a design that makes these aspects easily configurable and manageable. That approach adds complexity, but it gives teams tighter control over how the agent behaves in real conversations.

2. Maximum prevention of unwanted behaviors

Parlant treats misalignment as a core design problem. It builds on research into model accuracy and consistency so that it is structurally harder for the agent to behave outside its intended boundaries, and easier to detect and correct when it does. Rather than bolting guardrails onto the output, Parlant applies constraints and control points into how your LLMs are used in the first place to produce safe and correct output.

3. Fastest path from product feedback to implementation

Parlant seeks to allow those responsible for the agent's conversational experience to shape its behavior in an intuitive manner, enabling a rapid feedback cycle that engineers can accomodate. Parlant is designed to allow you to incorporate ongoing product feedback as quickly as possible, without manual rewiring of graphs or fine-tuning of models, ensuring that valuable engineering time is only needed for deeper changes, not minor adjustments.

Getting started

pip install parlant
import parlant.sdk as p

async with p.Server():
    agent = await server.create_agent(
        name="Customer Support",
        description="Handles customer inquiries for an airline",
    )

    # Evaluate and call tools only under the right conditions
    expert_customer = await agent.create_observation(
        condition="customer uses financial terminology like DTI or amortization",
        tools=[research_deep_answer],
    )

    # When the expert observation holds, always respond
    # with depth. Set the guideline to automatically match
    # whenever the observation it depends on holds...
    expert_answers = await agent.create_guideline(
        matcher=p.MATCH_ALWAYS,
        action="respond with technical depth",
        dependencies=[expert_customer],
    )

    beginner_answers = await agent.create_guideline(
        condition="customer seems new to the topic",
        action="simplify and use concrete examples",
    )

    # When both match, beginners wins. Neither expert-level
    # tool-data nor instructions can enter the agent's context.
    await beginner_answers.exclude(expert_customer)

Follow the 5-minute quickstart for a full walkthrough.

Parlant at a glance

You define your agent's behavior in code (not prompts), and the engine dynamically narrows the context on each turn to only what's immediately relevant, so the LLM stays focused and your agent stays aligned.

graph TD
    O[Observations] -->|Events| E[Contextual Matching Engine]
    G[Guidelines] -->|Instructions| E
    J["Journeys (SOPs)"] -->|Current Steps| E
    R[Retrievers] -->|Domain Knowledge| E
    GL[Glossary] -->|Domain Terms| E
    V[Variables] -->|Memories| E
    E -->|Tool Requests| T[Tool Caller]
    T -.->|Results + Optional Extra Matching Iterations| E
    T -->|**Key Result:**<br/>Focused Context Window| M[Message Generation]

Instead of sending a large system prompt followed by a raw conversation to the model, Parlant first assembles a focused context — matching only the instructions and tools relevant to each conversational turn — then generates a response from that narrowed context.

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#e8f5e9', 'primaryTextColor': '#1b5e20', 'primaryBorderColor': '#81c784', 'lineColor': '#66bb6a', 'secondaryColor': '#fff9e1', 'tertiaryColor': 'transparent'}}}%%
flowchart LR
    A(User):::outputNode

    subgraph Engine["Parlant Engine"]
        direction LR
        B["Match Guidelines and Resolve Journey States"]:::matchNode
        C["Call Contextually-Associated Tools and Workflows"]:::toolNode
        D["Generated Message"]:::composeNode
        E["Canned Message"]:::cannedNode
    end

    A a@-->|💬 User Input| B
    B b@--> C
    C c@-->|Fluid Output Mode?| D
    C d@-->|Strict Output Mode?| E
    D e@-->|💬 Fluid Output| A
    E f@-->|💬 Canned Output| A

    a@{animate: true}
    b@{animate: true}
    c@{animate: true}
    d@{animate: true}
    e@{animate: true}
    f@{animate: true}

    linkStyle 2 stroke-width:2px
    linkStyle 4 stroke-width:2px
    linkStyle 3 stroke-width:2px,stroke:#3949AB
    linkStyle 5 stroke-width:2px,stroke:#3949AB

    classDef composeNode fill:#F9E9CB,stroke:#AB8139,stroke-width:2px,color:#7E5E1A,stroke-width:0
    classDef cannedNode fill:#DFE3F9,stroke:#3949AB,stroke-width:2px,color:#1a237e,stroke-width:0

In this way, adding more rules makes the agent smarter, not more confused — because the engine filters context relevance, not the LLM.

Is Parlant for you?

Parlant is built for teams that need their AI agent to behave reliably in front of real customers. It's a good fit if:

Parlant is deployed in production at the most stringent organizations, including banks.

Parlant isn't just a framework. It's a high-level software that solves the conversational modeling problem head-on. — Sarthak Dalabehera, Principal Engineer, Slice Bank

By far the most elegant conversational AI framework that I've come across. — Vishal Ahuja, Senior Lead, Applied AI, JPMorgan Chase

Parlant dramatically reduces the need for prompt engineering and complex flow control. Building agents becomes closer to domain modeling. — Diogo Santiago, AI Engineer, Orcale

Features

Guidelines

Behavioral rules as condition-action pairs: when the condition applies, the action kicks into context.

Instead of cramming all guidelines in a single prompt, the engine evaluates which ones apply on each conversational turn and only includes the relevant ones in the LLM's context.

This lets you define hundreds of guidelines without degrading adherence.

await agent.create_guideline(
    condition="customer uses financial terminology like DTI or amortization",
    action="respond with technical depth — skip basic explanations",
)

Relationships

Relationships between elements help you keep the final context just right: narrow and focused.

Exclusion relationships keep certain guidelines out of the model's attention when conflicting ones are matched.

for_experts = await agent.create_guideline(
    condition="customer uses financial terminology",
    action="respond with technical depth",
)

for_beginners = await agent.create_guideline(
    condition="customer seems new to the topic",
    action="simplify and use concrete examples",
)

# In conflicting reads of the customer, set which takes priority
await for_beginners.exclude(for_experts)

Dependency relationships ensure a guideline only activates when another one has set the stage, helping you create topic-based guideline hierarchies.

suspects_fraud = await agent.create_observation(
    condition="customer suspects unauthorized transactions on their card",
)

await agent.create_guideline(
    condition="customer wants to take action regarding the transaction",
    action="ask whether they want to dispute the transaction or lock the card",
    # Only activates when fraud suspicion has been established
    dependencies=[suspects_fraud],
)

Journeys

Multi-turn SOPs (Standard Operating Procedures). Define a flow for processes like booking, troubleshooting, or onboarding. The agent follows the flow but adapts — it can fast-forward states, revisit earlier ones, or adjust pace based on how the customer interacts.

journey = await agent.create_journey(
    title="Book Flight",
    description="Guide the customer through flight booking",
    conditions=["customer wants to book a flight"],
)

t0 = await journey.initial_state.transition_to(
    # Instruction to follow while in this state (could be multiple turns)
    chat_state="See if they're interested in last-minute deals",
)

# Branch A - not interested in deals
t1 = await t0.target.transition_to(
    chat_state="Determine where they want to go and when",
    condition="They aren't interested",
)

# Branch B - interested in deals
t2 = await t0.target.transition_to(
    tool_state=load_latest_flight_deals,
    condition="They are",
)

t3 = await t1.target.transition_to(
    chat_state="List deals and see if they're interested",
)

Canned Responses

At critical moments or conversational events, limit the agent to using only pre-approved response templates.

After running the matching sequence and drafting a message to the customer, the agent selects the template that best matches its generated draft instead of sending it directly, eliminating hallucination risk entirely and keeping wording exact to the letter.

await agent.create_guideline(
    condition="The customer discusses things unrelated to our business"
    action="Tell them you can't help with that",
    # Strict composition mode triggers when this guideline
    # matches - the rest of the agent stays fluid
    composition_mode=p.CompositionMode.STRICT,
    canned_responses=[
        await agent.create_canned_response(
            "Sorry, but I can't help you with that."
        )
    ],
    priority=100,  # Top priority, focuses the agent on this alone
)

Tools

Tools activate only when their observation matches; they don't sit in the context permanently. This prevents the false-positive invocations that plague traditional LLM tool setups.

@p.tool
async def query_docs(context: p.ToolContext, user_query: str) -> p.ToolResult:
    results = search_knowledge_base(user_query)
    return p.ToolResult(results)

await agent.create_observation(
    condition="customer asks about service features",
    tools=[query_docs],
)

Tools can also feed custom values into canned response templates.

Glossary

Domain-specific vocabulary for your agent. Map colloquial terms and synonyms to precise business definitions so the agent understands customer language.

await agent.create_term(
    name="Ocean View",
    description="Room category with direct view of the Atlantic",
    synonyms=["sea view", "rooms with a view to the Atlantic"],
)

Explainability

Every decision is traced with OpenTelemetry. Parlant ships out of the box with elaborate logs, metrics, and traces.

Framework Integration

Parlant handles conversational governance; it doesn't replace your existing stack.

Use it alongside frameworks like LangGraph, Agno, LlamaIndex, or others for workflow automation and knowledge retrieval. Parlant takes over the behavioral control layer while your framework of choice handles the rest of your agent's processing logic.

Any external workflow or agent becomes a Parlant tool, triggered only when relevant:

from my_workflows import refund_graph  # a compiled LangGraph StateGraph

@p.tool
async def run_refund_workflow(
  context: p.ToolContext,
  order_id: str
) -> p.ToolResult:
    result = await refund_graph.ainvoke({"order_id": order_id})

    # Graph result can inject both data and instructions into the agent.
    # Instructions are transformed to guidelines, and participate
    # in contextual guideline resolution (including prioritizations)

    return p.ToolResult(
        data=result["data"],
        # Inject dynamic guidelines from workflow result
        guidelines=[
            {"action": inst, "priority": 3} for inst in result["instructions"]
        ],
    )

await agent.create_observation(
    condition="customer wants to process a refund",
    tools=[run_refund_workflow],
)

The same pattern works with LlamaIndex query engines, Agno agents, or any async Python function.

LLM Agnostic

Parlant works with most LLM providers. The recommended ones are Emcie which delivers an ideal cost/quality value since it's built specifically for Parlant, but OpenAI and Anthropic deliver excellent quality outputs as well. You can also use any model and provider via LiteLLM, but they need to be good ones - off-the-shelf models which are too small tend to produce inconsistent results.

Generally, you can swap models without changing behavioral configuration.

Official React Chat Widget

Drop-in chat component to get a frontend running immediately.

Learn more

Community - Get Help with Parlant

If Parlant helps you build better agents, give it a star — it helps others find the project.

License

Apache 2.0 — free for commercial use.


Try it now • Join Discord • Read the docs

Built by the team at Emcie

parlant (emcie-co/parlant)

Searching Database…

18.3K ·GitHub
这是干什么的?一个开源的对话行为控制框架,用来构建面向客户的 AI 智能体,让它们表现一致、合规、可追溯——适用于客服、销售、新客户引导等场景,定位是 Ada、Decagon、Sierra 的开源替代品。
它是一个我要导入的框架,还是作为独立服务运行的?不只是一个框架:README 称它是正面解决对话建模问题的高级软件。你用代码(而不是提示词)定义智能体的行为,Parlant 负责行为控制这一层,其余部分由你现有的技术栈处理。
我该怎么上手?跟着 5 分钟快速上手教程走一遍完整流程即可。你只需用代码写一次智能体的行为——规则、知识和工具,引擎会在实时运行中自动收敛上下文。
它可以搭配哪些大模型服务商使用?它不绑定任何大模型——推荐使用 Emcie,OpenAI 和 Anthropic 的模型效果也很出色,其他模型可以通过 LiteLLM 接入。太小的模型会导致结果不稳定;更换模型不会影响你已经写好的行为配置。
这是给大型受监管企业用的,还是小团队也能用?它面向那些智能体直接服务真实客户、对语气、准确性和合规性要求高的团队——比如有几十上百条规则,或者金融、保险、医疗这类受监管的领域。它已经在银行的生产环境中投入使用。
为什么不直接把系统提示词写好一点?README 的观点是:提示词在开发阶段还行,一旦上线面对真实复杂度就会失效——指令加得越多,智能体就越容易顾此失彼。Parlant 则把约束和控制点直接构建到大模型的使用方式中,从结构上让智能体更难越出边界。
Journeys 是什么?面向预订、排障、新客户引导等流程的多轮对话式 SOP。智能体按照流程走,但能灵活应变——可以跳过某些状态、回退到先前的状态,或根据客户的互动节奏调整快慢。
如果某句回复必须一字不差,比如法律或合规用语怎么办?可以用 Canned Responses(预制回复):在关键时刻,智能体只能使用预先审批好的模板——它先起草一条消息,然后从模板中选出最匹配的一条发出,而不是直接发送草稿,从而彻底消除幻觉风险。
它自带聊天界面,还是我得自己搭?官方提供了一个开箱即用的 React 聊天组件,接上就能立刻跑起一个前端。
Creator
emcie-co
Size
86.7 MB
Stars
18.3K
Age
2y
Commits · 90 Days