Mixing Frameworks with Auto-Detection¶
FastAPI Agents supports concurrent registration of agents from multiple different frameworks to the same FastAPI app. It can also detect your agent framework automatically.
This notebook demonstrates how to use the FastAPIAgent
class from fastapi-agents
with multiple different agent frameworks seamlessly.
To run this notebook, make sure you have fastapi
, fastapi-agents
, crewai
and pydantic-ai
installed (e.g. pip install fastapi fastapi-agents crewai pydantic-ai
).
First Framework: CrewAI¶
Let's start by defining an agent with CrewAI, which FastAPI Agents supports.
from crewai import Agent, Crew, Task, LLM
from crewai.process import Process
import os
os.environ['OPENAI_API_BASE'] = os.environ['OPENAI_BASE_URL']
# Define the agent
poet = Agent(
role="Poet",
goal="Write beautiful poetry.",
backstory="Experienced poetry, author of 60 poems.",
verbose=True,
llm=LLM('openai/gpt-4o')
)
# Define the task
writing_task = Task(
description="Write a beautiful poem.",
expected_output="A poem with 3 stanzas.",
agent=poet
)
# Create a crew with the agent and task
ai_crew = Crew(
agents=[poet],
tasks=[writing_task],
process=Process.sequential, # Tasks will be executed sequentially
verbose=True
)
You can run your crew with .kickoff()
to make sure it's working as expected.
result = ai_crew.kickoff()
Second Framework: PydanticAI¶
Next, let's define an agent with PydanticAI, which FastAPI Agents also supports.
from typing import List
from pydantic_ai import Agent
todo_agent = Agent(
"openai:gpt-4o",
system_prompt="You are managing the user's todo list."
)
todos: List[str] = []
@todo_agent.tool
def list_todos(context):
return f"{len(todos)} todos: {"".join(todos) if len(todos) > 0 else "empty"}"
@todo_agent.tool
def add_todo(context, description: str):
todos.append(description)
return f"added {description} to todos"
@todo_agent.tool
def delete_todo(context, description: str):
todos.remove(description)
return f"removed {description} from todos"
You can run your agent with .run_sync()
to make sure it's working as expected. Since we are using Jupyter which uses asyncio for execution, we need to tell asyncio to nest the execution loop so we execute our Pydantic AI, which also uses asyncio. (You won't need this outside of Jupyter.)
import nest_asyncio
nest_asyncio.apply()
result = todo_agent.run_sync("make up 3 todos and add them then tell me what do i need to do")
result.data
Registering Multiple Agents with Automatic Framework Detection¶
Finally, let's register both agents with FastAPI Agents, using automatic detection to determine which agent framework is being used.
This means we don't need to specify the agent framework when registering the agent with FastAPI Agents, or explicitly use the framework-specific adapter classes. (They are still used under the hood, but you don't need to worry about them.)
from fastapi_agents import FastAPIAgents
app = FastAPIAgents.as_app()
app.register("poet", ai_crew)
app.register("todo", todo_agent)
Run with Uvicorn¶
Finally, we'll run our FastAPI app with uvicorn to see our agents in action.
Since we're in Jupyter, we're going to run our API as a thread so we can execute the cells following it. We also need to nest asyncio since Jupyter is already running its own asyncio event loop.
import nest_asyncio
nest_asyncio.apply()
import uvicorn
uvicorn.run(app)
Open the API in your browser to see the Swagger UI and test your agents.
By default, your interactive docs will be available at http://127.0.0.1:8000/docs.