Integrations
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 | patched in for you | emitted for you | patched in for you |
| B | LangChain / LangGraph | patched in for you | after one pip install |
patched in for you |
| TS | Vercel AI SDK | patched in for you | v7 by itself; v6 with one flag | patched in for you |
| C | CrewAI, Agno, or your own 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.
The doorway file
One file, at the repository root, holding two functions. Python:
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:
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.
Where each page takes you
- Vercel AI SDK —
defineAgent, the v6 telemetry flag,observe. - Pydantic AI — nothing to install for spans; the constructor patch.
- LangChain / LangGraph — the recursion limit,
streaming onto
ctx, the OpenInference package. - CrewAI — Shape C in a framework: the
REDLINE_TOOLline protocol and the two instrumentation packages. - Agno — the same, plus the event-loop rule.
- 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 —
observe,create_monitor, what lands on the run versus the session, and what the platform does with a session on its own. - Known issues — every failure we have seen a real integration hit, by symptom, with the cause and the fix.