Skip to Content
Platform
BuildMigrate an agent

Migrate an agent

Map each part of your existing agent to a recipe, then run the same inputs through both.

Start from one agent and port only what your real inputs use. When the two diverge, fix the first point of difference rather than adding prompt text.

You need: the CLI set up (Create a recipe) and a few real inputs the old agent handles today.

1. Scaffold the target

introspection init support-agent

2. Map each part

In your agentIn the recipe
System promptSYSTEM.md, or system_instructions in the agent YAML (Define agents)
Reusable judgment, prompt helpersSkills (Skills & prompts)
Custom tools (@tool, tool(), function_tool)An extension tool (Add a tool) or an MCP server (Connect an MCP server)
Model choiceai.model: <provider>/<model-id>
API keys in environment variablesBindings per environment (Connect services and secrets)
Threads, sessions, stored message arraysOne task per thread. Send later turns to the same task.
Supervisor graph, several assistantsOne agent by default; subagents when the split is real (Multi-agent)

3. Map framework-specific features

LangGraph, OpenAI Agents SDK, Claude Agent SDK, Vercel AI SDK, Mastra, Temporal

SourceMaps to
LangGraph interrupt and checkpointeraskUserApproval from a tool, then tasks resume (Ask the user); only the root agent pauses.
LangGraph assistant configPer-task metadata, read in the sandbox from INTROSPECTION_TASK_METADATA_JSON
OpenAI Agents SDK handoffsSubagents. The lead agent stays in charge; the conversation is not transferred.
OpenAI Agents SDK guardrailsA tool_call hook (Block a tool call), or validation in a submit tool (Get structured output)
OpenAI Agents SDK sessionsThe task’s conversation id
Claude Agent SDKSKILL.md files go to skills/; custom tools become extensions or an MCP server.
Vercel AI SDK tool()An extension tool. No useChat adapter: render the task stream (Add a web chat).
Mastra suspend and resumeInterrupts (askUserQuestion, askUserApproval)
Temporal workflowsKeep Temporal. Start the task from an activity, then stream or poll it.

4. Port your eval cases

LangSmith and Evalite

SourceMaps to
LangSmith datasetJSONL rows with schema_version: 2, name, input.prompt, and optional expected (Add cases to an eval)
LangSmith LLM evaluatorsjudges/*.yaml (Calibrate a judge)
LangSmith code evaluatorsA createJudge code judge returning { score } (Run and compare evals)
Evalite dataJSONL rows, one case each
Evalite scorersjudges/*.yaml or createJudge. A case with only expect() and no score counts as incomplete.

5. Prove parity

Run each real input through the old agent (when safe) and the recipe:

introspection check introspection local -p "<the same input>"

Then put the inputs in an eval suite so the check repeats on every change (Run and compare evals).

Already a Pi package?

Add agents/agent.yaml with name and ai.model, and a runtime manifest .introspection/<slug>.yaml at the repository root with name and the recipe path. Then run introspection check. If pi.agents is an explicit list, add the new file to it.

Verify

introspection check passes, and every parity input gives the same decision from both agents, or a difference you chose on purpose.

Limits

Not supportedDo this instead
Importing LangSmith or Evalite data automaticallyWrite the JSONL rows with a short script.

Or ask your agent: “Migrate the support agent in src/agent to an Introspection recipe and show me parity on our real inputs.”

Last updated on