Quickstart
Build and run your first conversational AI agent with chatflow-agent in under 5 minutes.
1. Create a Basic Agent
In chatflow-agent, an Agent represents a persona with dedicated instructions and capabilities, while the Runner orchestrates conversational turns and tool evaluation loops.
Create a new file named quickstart.py:
# [min-version: 0.3.0]
# [no-exec: requires real openai api key for live response]
import os
from chatflow_agent import Agent, Runner
# 1. Define the agent persona, instructions, and target model
# chatflow-agent automatically routes "gpt-4o" to the OpenAI engine using OPENAI_API_KEY
agent = Agent(
name="Assistant",
instructions="You are a concise and helpful AI technical assistant.",
model="gpt-4o",
)
# 2. Initialize the Runner with your starting agent
runner = Runner(starting_agent=agent)
# 3. Execute a conversational turn
response = runner.run(
session_id="quickstart_session",
user_message="Explain async Python in two concise sentences.",
)
# 4. Display the output
print("Agent Response:")
print(response.content)Run the script from your terminal:
python quickstart.pyEvent Loop Guard
runner.run() is a synchronous convenience method designed for scripts and CLI utilities. If you are inside an existing asynchronous event loop (e.g. FastAPI, Jupyter Notebook, or asyncio), use await runner.run_async() instead. Calling runner.run() inside an active loop raises a clear RuntimeError.
2. Adding Tools with @tool
Agents become exponentially more powerful when given access to deterministic functions. Use the @tool decorator to turn any Python function into an introspectable tool:
# [min-version: 0.3.0]
# [no-exec: requires real openai api key for live response]
import os
from chatflow_agent import Agent, Runner, tool
# 1. Define a tool with typed parameters and docstrings
@tool(name="calculate_discount", description="Calculate discounted price from original amount and percentage.")
def calculate_discount(price: float, discount_percent: float) -> str:
"""Calculate the final price after applying a percentage discount.
Args:
price: The original price in dollars.
discount_percent: The percentage discount to apply (e.g. 15 for 15%).
"""
savings = price * (discount_percent / 100.0)
final_price = price - savings
return f"Original: ${price:.2f}, Savings: ${savings:.2f}, Final Price: ${final_price:.2f}"
# 2. Attach the tool to the Agent
agent = Agent(
name="SalesBot",
instructions="You help customers with purchase calculations. Always use calculate_discount for math.",
model="gpt-4o",
tools=[calculate_discount],
)
runner = Runner(starting_agent=agent)
# 3. Ask a question requiring tool execution
response = runner.run(
session_id="sales_session_1",
user_message="What is the final price for a jacket priced at $120 with a 25% discount?",
)
print(response.content)Inspecting Tool Execution
The returned AgentResponse object retains full transparency into the conversational turn:
# Inspect executed tool names
for tool_name in response.tool_calls_executed:
print(f"Tool executed: {tool_name}")3. Asynchronous Execution with Runner.run_async
For high-concurrency web services, chatbots, and event loops, use the native asynchronous API:
import asyncio
import os
from chatflow_agent import Agent, Runner
async def main() -> None:
agent = Agent(
name="AsyncBot",
instructions="Provide concise answers.",
model="gpt-4o",
)
runner = Runner(starting_agent=agent)
# Asynchronous turn
response = await runner.run_async(
session_id="async_session_1",
user_message="List three key advantages of asynchronous Python.",
)
print(response.content)
if __name__ == "__main__":
asyncio.run(main())4. Multi-Provider Flexibility
Because chatflow-agent uses direct REST engines, switching between providers is instantaneous without changing your agent logic:
import os
from chatflow_agent import Agent, OpenAIEngine
# Option 1: Direct model configuration (engines are resolved automatically)
openai_agent = Agent(
name="OpenAIBot",
instructions="You are powered by GPT-4o.",
model="gpt-4o",
)
claude_agent = Agent(
name="ClaudeBot",
instructions="You are powered by Claude 3.5 Sonnet.",
model="claude-3-5-sonnet-20241022",
)
gemini_agent = Agent(
name="GeminiBot",
instructions="You are powered by Google Gemini.",
model="gemini-2.5-flash",
)
# Option 2: Custom endpoints via OpenAIEngine (Groq, Ollama, DeepSeek)
groq_engine = OpenAIEngine(
base_url="https://api.groq.com/openai/v1",
api_key=os.getenv("GROQ_API_KEY"),
provider="groq",
)
groq_agent = Agent(
name="GroqBot",
instructions="You are powered by LLaMA 3.3 on Groq.",
model="llama-3.3-70b-versatile",
engine=groq_engine,
)Provider Differences in v0.3.4 vs v0.4.0rc1
In Stable (0.3.4), GeminiEngine relies on the google-genai package. In Prerelease (0.4.0rc1), GeminiEngine was refactored to pure HTTP REST via httpx, eliminating external Google SDK dependencies.
Next Steps
Now that you have executed your first agents, dive into the foundational concepts:
- Core Concepts: Learn about State Management, Memory, Handoffs, and Concurrency.