# Serve and embed (/use-cases/data-agents/serve-and-embed)



`AgentOS` exposes the data agent through a FastAPI application. Slack, BI dashboards, scheduled jobs, and product widgets can call the same agent endpoint.

```bash
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](/knowledge/vector-stores/pgvector/overview). Keep this application's storage credentials separate from the restricted warehouse role.

```python title="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:

```bash
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 [#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](/use-cases/product-agents/serve-as-an-api). `user_id` and `session_id` select the conversation history for a run.

<Warning>
  This example leaves AgentOS authorization disabled. Callers can supply their own user and session identifiers. Configure [authorization and user isolation](/agent-os/security/authorization/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.
</Warning>

## Shared learnings, separate sessions [#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](/learning/stores/learned-knowledge), whose namespace defaults to `"global"`.

```python
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 [#next-steps]

| Task                           | Guide                                              |
| ------------------------------ | -------------------------------------------------- |
| Add Slack or a browser surface | [Interfaces](/use-cases/product-agents/interfaces) |
| Lock down the endpoints        | [Security and auth](/features/security-and-auth)   |

## Developer Resources [#developer-resources]

* [Serve as an API](/features/api)
* [Customer-facing agents: serving](/use-cases/product-agents/serve-as-an-api)
