---
title: Integrations
description: How each agent framework connects — for experiments, for production monitoring, and for runtime protection — and the one question that decides which page to read.
---

Every integration is the same three things. **Experiments**: your agent runs our
tasks, in your process, and we grade it. **Monitoring**: the same agent doing real
work for real users, reported as it happens. **Protection**: policies, the guard
classifier and honeypots, enforced inside the process. One doorway file covers
all three — but what that file has to contain depends on what your agent is
built with.

## First, which shape is it?

Decide this before anything else. The SDK patches some frameworks and not
others, and getting it wrong is the commonest way a connection looks fine while
the agent quietly says it has no tools.

| Shape | You are using | Attached tools | Monitoring spans | Runtime protection |
| --- | --- | --- | --- | --- |
| **A** | [Pydantic AI](/integrations/pydantic-ai) | patched in for you | emitted for you | patched in for you |
| **B** | [LangChain / LangGraph](/integrations/langchain) | patched in for you | after one `pip install` | patched in for you |
| **TS** | [Vercel AI SDK](/integrations/vercel-ai-sdk) | patched in for you | v7 by itself; v6 with one flag | patched in for you |
| **C** | [CrewAI](/integrations/crewai), [Agno](/integrations/agno), or [your own loop](/integrations/own-tool-loop) | **you merge them** | CrewAI/Agno after a `pip install`; your own loop **emits its own** | CrewAI/Agno yes; a raw-HTTP loop **not covered** |

The test is one grep. `pydantic_ai` → A. `langgraph.prebuilt` or
`langchain.agents` → B. `ai` with `generateText` / `ToolLoopAgent` → TS.
Anything else — a hand-rolled loop, a registry of your own, a raw provider SDK
over `openai`, `httpx` or `anthropic` — is C.

> **Shape C is not the fallback, it is most agents past a prototype**
>
> Frameworks are patched because they have a constructor the SDK can wrap. A
> loop you wrote has no such seam, so the four things the SDK would have done
> for you — offer the attached tools, emit the spans, declare what the agent is
> made of, gate the calls — become four things the doorway file does. The
> [own tool loop](/integrations/own-tool-loop) page is the complete pattern,
> worked on a real production agent.

## The doorway file

One file, at the repository root, holding two functions. Python:

```python title="agents.py"
from redline import agent, observe

@agent(id="my-agent", name="My Agent", description="what it is good at")
async def run(task, ctx):             # experiments — what `redline dev` executes
    return await your_agent(task.prompt)

@observe(agent="my-agent", session_arg="conversation_id",
         user_arg="user_id", input_arg="text")
async def handle_message(conversation_id: str, user_id: str, text: str) -> str:
    return await your_agent(text)     # production — every call is a session
```

TypeScript:

```ts title="redline/my-agent.ts"
import { defineAgent, observe } from "@redlineai/sdk";

export const myAgent = defineAgent({ id: "my-agent", name: "My Agent",
  run: (task) => yourAgent(task.prompt) });

export const handleMessage = observe(
  async (conversationId: string, userId: string, text: string) => yourAgent(text),
  { agent: "my-agent", sessionArg: 0, userArg: 1, inputArg: 2 });
```

`run` is what `redline dev` calls when an experiment targets this agent.
`handle_message` is what **your application** calls for every inbound message.
Same agent id in both, and the console shows pre-release attack results and
live production sessions on one agent — which is the point.

> **The second function is inert until something calls it**
>
> A decorator only records calls to the function it decorates. If your
> repository already has a pipeline for inbound messages — a webhook, a queue
> worker, a websocket handler — that pipeline has to call `handle_message`.
> That is one call-site change in existing code, and it is the only one the
> integration ever asks for. Without it, experiments work and production
> sessions never appear. See [monitoring](/integrations/monitoring#wiring-it-into-an-existing-app).

## Where each page takes you

- **[Vercel AI SDK](/integrations/vercel-ai-sdk)** — `defineAgent`, the v6
  telemetry flag, `observe`.
- **[Pydantic AI](/integrations/pydantic-ai)** — nothing to install for spans;
  the constructor patch.
- **[LangChain / LangGraph](/integrations/langchain)** — the recursion limit,
  streaming onto `ctx`, the OpenInference package.
- **[CrewAI](/integrations/crewai)** — Shape C in a framework: the
  `REDLINE_TOOL` line protocol and the two instrumentation packages.
- **[Agno](/integrations/agno)** — the same, plus the event-loop rule.
- **[Own tool loop](/integrations/own-tool-loop)** — the full pattern: merging
  attached tools into your registry, the brief that tells the model they exist,
  emitting your own spans, and the one-per-turn parent that makes the waterfall
  read as turns.
- **[Monitoring](/integrations/monitoring)** — `observe`, `create_monitor`,
  what lands on the run versus the session, and what the platform does with a
  session on its own.
- **[Known issues](/integrations/known-issues)** — every failure we have seen a
  real integration hit, by symptom, with the cause and the fix.

> **Let a coding agent do it**
>
> Every page here is also compressed into the **Copy instructions for a coding
> agent** button on the Agents page — one document, your runner key already
> substituted in, written to be pasted into Claude Code or Codex inside the
> repository. That document links back here for anything it does not cover.
