Serve and embed
Serve a data agent through AgentOS for use in dashboards, Slack, and product interfaces.
AgentOS exposes the data agent through a FastAPI application. Slack, BI dashboards, scheduled jobs, and product widgets can call the same agent endpoint.
uv pip install "agno[openai,os,postgres,pgvector,sql]"Set OPENAI_API_KEY in the environment before running the Python code. Replace the warehouse URLs with your own PostgreSQL connection strings and create the database roles, schemas, and grants described on this page first. The host warehouse, database analytics, and roles such as readonly and dash_writer are placeholders.
Examples using PostgresDb or PgVector also need a separate writable application database. The sample URL assumes a PostgreSQL service at localhost:5532 with database/user/password ai; knowledge examples need the pgvector extension. See PgVector setup. Keep this application's storage credentials separate from the restricted warehouse role.
from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.models.openai import OpenAIResponses
from agno.os import AgentOS
from agno.tools.sql import SQLTools
agent = Agent(
id="data-agent",
model=OpenAIResponses(id="gpt-5.5"),
db=PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai"),
tools=[SQLTools(db_url="postgresql+psycopg://readonly@warehouse/analytics")],
learning=True,
add_history_to_context=True,
)
agent_os = AgentOS(agents=[agent])
app = agent_os.get_app()
if __name__ == "__main__":
agent_os.serve(app="data_agent:app", port=7777)Run it with python data_agent.py. The app="data_agent:app" import string has to match the module name. Every surface then calls the same endpoint:
curl -X POST http://localhost:7777/agents/data-agent/runs \
-F 'message=MRR by plan, last 6 months' \
-F 'user_id=ab@acme.com' \
-F 'session_id=q4-review' \
-F 'stream=false'Where to use a data agent
| Surface | Shape |
|---|---|
| Slack channel | An interface maps a thread to a session; the team asks in plain English |
| Dashboard NL box | A widget posts the question and renders the answer plus its SQL |
| Scheduled digest | A cron job runs the agent and posts "yesterday's numbers" every morning |
| Backend check | A pipeline calls the agent to sanity-check a metric before publishing |
Data agents use the same serving model as customer-facing agents. user_id and session_id select the conversation history for a run.
This example leaves AgentOS authorization disabled. Callers can supply their own user and session identifiers. Configure authorization and user isolation with AuthorizationConfig(user_isolation=True) and a trusted authenticated user identity before network exposure. Authentication alone does not enable ownership filtering. Connect SQLTools with a database role that enforces read-only access.
Shared learnings, separate sessions
Share diagnosed warehouse corrections across the team while keeping conversation threads scoped by user_id and session_id. learning=True enables the per-user profile and memory stores. To share corrections, pass a knowledge base to LearningMachine. This enables the Learned Knowledge store, whose namespace defaults to "global".
from agno.knowledge import Knowledge
from agno.learn import LearningMachine
from agno.vectordb.pgvector import PgVector
knowledge = Knowledge(
vector_db=PgVector(
db_url="postgresql+psycopg://ai:ai@localhost:5532/ai",
table_name="warehouse_learnings",
),
)
agent = Agent(
id="data-agent",
model=OpenAIResponses(id="gpt-5.5"),
db=PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai"),
tools=[SQLTools(db_url="postgresql+psycopg://readonly@warehouse/analytics")],
add_history_to_context=True,
learning=LearningMachine(knowledge=knowledge),
)Use this replacement agent when constructing AgentOS above. The store runs in AGENTIC mode: the model decides when to call save_learning and search_learnings. To keep learnings inside one team or tenant, set namespace on LearningMachine.
| State | Scope |
|---|---|
| Conversation thread | Per user_id and session_id |
| Learnings about the warehouse | Learned Knowledge store, shared "global" namespace by default |
Next steps
| Task | Guide |
|---|---|
| Add Slack or a browser surface | Interfaces |
| Lock down the endpoints | Security and auth |