Skip to main content
You already have a prompt — it’s just living in your application code: an inline messages array, a system string, a ChatPromptTemplate, a PromptTemplate. Migrating it to AgentMark means moving that text into a versioned .prompt.mdx and loading it at the call site, so the prompt is editable, type-safe, and traceable instead of hard-coded.

The pattern

It’s the same three moves regardless of which SDK or framework the prompt currently lives in:
  1. Extract the prompt into agentmark/<name>.prompt.mdx — the system / user / assistant turns become message tags, and the template variables become {props.*}. See Creating prompts for the shape.
  2. Load + render it at the call site: client.loadTextPrompt(...) then prompt.format({ props }) gives you back messages (and text_config).
  3. Keep your model call — you are replacing where the prompt comes from, not your SDK. Feed the rendered messages to whatever you already call (generateText, openai.chat.completions.create, model.invoke, …), then delete the inline prompt.
The prompt file is the same in every case. For the examples below:
agentmark/summarize.prompt.mdx
---
name: summarize
text_config:
  model_name: openai/gpt-4o-mini
---

<System>You are a concise summarizer. Reply with a single sentence, no preamble.</System>
<User>Summarize this article:

{props.article}</User>

Raw OpenAI / Anthropic SDK

An inline messages array (or system + messages) moves straight into the prompt file; the create call stays.
import OpenAI from "openai";
const openai = new OpenAI();

export async function summarize(article: string) {
  const res = await openai.chat.completions.create({
    model: "gpt-4o-mini",
    messages: [
      { role: "system", content: "You are a concise summarizer. Reply with a single sentence, no preamble." },
      { role: "user", content: `Summarize this article:\n\n${article}` },
    ],
  });
  return res.choices[0]?.message?.content ?? "";
}
The Anthropic SDK is the same idea — load + format, then pass messages (and split the system turn out as Anthropic requires) to anthropic.messages.create.

Vercel AI SDK

generateText’s system + prompt/messages come from the rendered prompt; the generateText call stays.
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

export async function reply(question: string) {
  const { text } = await generateText({
    model: openai("gpt-4o-mini"),
    system: "You are a friendly support agent. Answer in two sentences or fewer.",
    prompt: question,
  });
  return text;
}

LangChain

A ChatPromptTemplate is a prompt — migrate it. The template’s messages move into the .prompt.mdx; you drop the ChatPromptTemplate + .pipe() and keep the chat model, because LangChain chat models accept a message array directly.
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { ChatOpenAI } from "@langchain/openai";

const prompt = ChatPromptTemplate.fromMessages([
  ["system", "You extract structured fields. Return JSON with keys: name, date, amount."],
  ["human", "{document}"],
]);
const model = new ChatOpenAI({ model: "gpt-4o-mini" });

export async function extract(document: string) {
  const chain = prompt.pipe(model);
  const res = await chain.invoke({ document });
  return typeof res.content === "string" ? res.content : JSON.stringify(res.content);
}

LlamaIndex (Python)

A PromptTemplate (or ChatPromptTemplate) moves into the .prompt.mdx; you render with AgentMark and call the LLM with the resulting messages.
from llama_index.core import PromptTemplate
from llama_index.llms.openai import OpenAI

tmpl = PromptTemplate(
    "You extract structured fields. Return JSON with keys: name, date, amount.\n\n{document}"
)
llm = OpenAI(model="gpt-4o-mini")

def extract(document: str) -> str:
    return llm.complete(tmpl.format(document=document)).text

After you migrate

Your model call is unchanged — same SDK, same function signature, same behavior. All that moved is where the prompt comes from: editing it is now a versioned, reviewable .prompt.mdx change instead of a code edit, and every run is traceable. Run agentmark doctor to confirm the prompt parses, then run it to confirm the call site still works.

Have questions?

Reach out any time: