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.

data_agent.py
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

SurfaceShape
Slack channelAn interface maps a thread to a session; the team asks in plain English
Dashboard NL boxA widget posts the question and renders the answer plus its SQL
Scheduled digestA cron job runs the agent and posts "yesterday's numbers" every morning
Backend checkA 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.

StateScope
Conversation threadPer user_id and session_id
Learnings about the warehouseLearned Knowledge store, shared "global" namespace by default

Next steps

TaskGuide
Add Slack or a browser surfaceInterfaces
Lock down the endpointsSecurity and auth

Developer Resources