Skip to content

Quick Start

Build your first agent in 5 minutes. No external servers needed — everything runs locally.

Install

pip install promptise
export OPENAI_API_KEY=sk-...  # Or any supported provider

Your First Agent (30 seconds)

The simplest possible agent — just an LLM with instructions:

import asyncio
from promptise import build_agent

async def main():
    agent = await build_agent(
        model="openai:gpt-4o-mini",
        instructions="You are a helpful assistant. Be concise.",
    )

    result = await agent.ainvoke({
        "messages": [{"role": "user", "content": "What is 42 * 17?"}]
    })
    print(result["messages"][-1].content)  # "42 * 17 = 714"
    await agent.shutdown()

asyncio.run(main())

That's it. build_agent() handles model initialization, message formatting, and execution.

Add Tools (2 minutes)

Agents become useful when they can call tools. Create an MCP server in the same file:

import asyncio
import sys
from promptise import build_agent
from promptise.config import StdioServerSpec
from promptise.mcp.server import MCPServer

# ── Build a tool server ──
server = MCPServer("my-tools")

@server.tool()
async def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    # In production, call a real API
    return f"Sunny, 22°C in {city}"

@server.tool()
async def calculate(expression: str) -> str:
    """Evaluate a math expression."""
    return str(eval(expression))  # noqa: S307

# Save as tools.py, then:

async def main():
    agent = await build_agent(
        model="openai:gpt-4o-mini",
        servers={
            "tools": StdioServerSpec(
                command=sys.executable,
                args=["tools.py"],
            ),
        },
        instructions="You are a helpful assistant with access to tools.",
    )

    result = await agent.ainvoke({
        "messages": [{"role": "user", "content": "What's the weather in Berlin?"}]
    })
    print(result["messages"][-1].content)
    # "It's sunny and 22°C in Berlin!"

    await agent.shutdown()

if __name__ == "__main__":
    # If run directly, start the MCP server
    if "--serve" in sys.argv:
        server.run(transport="stdio")
    else:
        asyncio.run(main())

The agent discovers get_weather and calculate automatically — no manual tool definitions.

Add a Custom Reasoning Pattern (3 minutes)

Instead of the default tool loop, define how your agent thinks:

from promptise.engine import PromptGraph, PromptNode, NodeFlag
from promptise.engine.reasoning_nodes import ThinkNode, SynthesizeNode

agent = await build_agent(
    model="openai:gpt-4o-mini",
    servers=my_servers,
    agent_pattern=PromptGraph("analyst", nodes=[
        ThinkNode("think", is_entry=True),          # Analyze the question
        PromptNode("research", inject_tools=True),   # Use tools to gather data
        SynthesizeNode("answer", is_terminal=True),  # Produce final answer
    ]),
)

The agent now thinks before acting and synthesizes a structured answer — instead of jumping straight to tool calls.

7 built-in patterns available:

agent = await build_agent(..., agent_pattern="react")       # Default tool loop
agent = await build_agent(..., agent_pattern="peoatr")      # Plan → Act → Think → Reflect
agent = await build_agent(..., agent_pattern="research")    # Search → Verify → Synthesize
agent = await build_agent(..., agent_pattern="autonomous")  # Agent picks from node pool
agent = await build_agent(..., agent_pattern="deliberate")  # Think → Plan → Act → Observe → Reflect
agent = await build_agent(..., agent_pattern="debate")      # Proposer ↔ Critic → Judge
agent = await build_agent(..., agent_pattern="pipeline")    # Sequential chain

Add Production Features (4 minutes)

Each capability is one parameter:

from promptise import build_agent, CallerContext
from promptise.memory import ChromaProvider
from promptise.cache import SemanticCache
from promptise.conversations import SQLiteConversationStore

agent = await build_agent(
    model="openai:gpt-4o-mini",
    servers=my_servers,

    # Security: block injection attacks, detect PII
    guardrails=True,

    # Memory: remember context across conversations
    memory=ChromaProvider(persist_directory="./memory"),

    # Cache: serve similar queries instantly (30-50% cost savings)
    cache=SemanticCache(),

    # Conversations: persist chat history
    conversation_store=SQLiteConversationStore("conversations.db"),

    # Observability: trace every tool call, token, and decision
    observe=True,
)

# Use with per-user identity
result = await agent.ainvoke(
    {"messages": [{"role": "user", "content": "Analyze last quarter's revenue"}]},
    caller=CallerContext(user_id="analyst-42", roles=["analyst"]),
)

What Happens Inside

When you call ainvoke(), this pipeline runs:

User message
    → Input guardrails (block injection, flag PII)
    → Memory search (inject relevant past context)
    → Cache check (return instantly if similar query cached)
    → Reasoning Engine (execute your reasoning pattern)
        → Tool discovery (auto-inject MCP tools)
        → LLM call (with system prompt, tools, context)
        → Tool execution (parallel when 2+ calls)
        → Loop until done (or budget exhausted)
    → Output guardrails (redact PII, credentials)
    → Cache store (save for future similar queries)
    → Conversation persist (store in SQLite/Postgres/Redis)
    → Return response

Every step is opt-in. Features you don't enable have zero overhead.


Next Steps

Want to... Go to...
Use Claude, Gemini, Ollama, or local models Model Setup
Understand the architecture Key Concepts
Design custom reasoning patterns Reasoning Patterns
Build a complete production agent Building Agents Guide
Build MCP tool servers Building MCP Servers
Build a customer support agent Lab: Customer Support
Build a data analysis agent Lab: Data Analysis
Build a code review agent Lab: Code Review