Dayward AI
Week 1 · D5About 3 hours

Migrating Across Models: Differences Between Claude / GPT / Domestic Chinese Models, Organizing the System Prompt; Where to Go Next — the Claude Course or the Codex Course

Why the same prompt breaks when you switch models, exactly where it breaks, how to organize a system prompt into a portable structure, and whether to study the Claude course or the Codex course next.

Today's goals 0/3

Sign in to tick these off and save your progress.

Today's Goals

  1. Name the four places a prompt most often breaks when migrated across models, and give a fix for each
  2. Organize a system prompt into a block structure so the provider-specific parts can be swapped independently
  3. Move a prompt from one model to another using a migration checklist, and verify it passes

This is the last day of the course. For four days your prompt has run against the same model; today answers a question you will hit sooner or later — switch providers and why does it break, where does it break, and how do you move it without pain. There is one more thing at the end: this is the first of three free introductory courses, and you need to know where to go after it. When you have read the walkthrough and finished the lab, come back to the top of the page and check off the three goals.

Plain-Language Walkthrough

Why the same ticket gets botched by a different colleague

The same well-tuned ticket, handed to a different colleague — Colleague A is out, so you give it to Colleague B. B is just as capable, but the work comes out different: they treat your boxed "important" text as decoration, they write two pages for what you called "brief," they read "don't touch unrelated files" as "touching them is fine as long as you don't mention it." The ticket did not change. The person did — everyone carries a different default reading of the same paragraph.

Differences between models are exactly that. The same prompt performing differently on two models is not a matter of one being smarter; it is that training gave them different default readings: which markers they are sensitive to, how literally they execute an instruction, which topics make them cautious, how long an answer they habitually produce. Those differences are nearly invisible on normal inputs — both colleagues handle routine work fine — and they surface entirely on edge and adversarial inputs, which is precisely the six or seven cases in D4's test set. So the first discipline of cross-model migration is the same sentence D4 ended on: run the same test set after the move. The pass rate is your answer on whether anything regressed, and it beats any amount of "feels about the same."

One more fact to settle up front: the overwhelming majority of regressions in a migration are not capability differences but defaults hidden in the prompt that only hold for one provider. You added them without noticing over many debugging rounds against that model, and only a switch reveals they were dialect rather than the common language. Today's job is to find the dialect and isolate it.

The four places migration most often breaks

Gather up the migration experience of the past few years and the regressions land almost entirely in four places. Each gets a way to recognize it and a fix.

Format markers. Some models are unusually sensitive to a particular way of wrapping input — say, fencing it inside a pair of custom tags — and treat it as a clean boundary. Move to another model and the same markers may be read as ordinary text, or even echoed verbatim into the output. The reverse happens too: a prompt that uses Markdown headings or horizontal rules for structure loses force on a model that prefers tags. Recognize it: look for the symbols you used for structure appearing in the output — if they show up, the model did not read them as structure. Fix: lift the question of how input is wrapped out of the task description and put it in a block you can swap; keep provider-specific markers out of your examples too, or the model will learn them from the examples.

Instruction adherence. The same "brief explanation" yields two sentences on one model and two paragraphs on another. The same "output only the list" is followed to the letter by one and prefaced with a lead-in sentence by another. This is a difference in how literally instructions are followed. Recognize it: take one edge case and see whether it is executed to the letter or improvised on. Fix: do not reach for exclamation marks and the word "must." Instead write the requirement in a mechanically checkable form (D1's old rule for the format box) plus a reason. "Start directly with the first section, because the output is parsed section by section" is more stable across every model than three exclamation marks after "no pleasantries."

Refusal boundaries. Providers differ in which topics make them cautious and in how the caution manifests — an outright refusal, an added disclaimer, or answering a nearby question instead. A requirement that arrives wrapped in the story of a production 500 incident may, on one provider, trigger a paragraph about security practices that bursts your structured output. Recognize it: run the adversarial cases and watch for refusals or extra commentary the source model never produced. Fix: state the task's boundary explicitly in the provider-adaptation block ("this is an internal code review task and does not concern any external system"), and always keep the schema constraint on for structured output so there is nowhere for a disclaimer to go.

Length habits. Some models default to longer, more "thorough" answers and will pad a list with fields you might also want to validate; others run short and omit items that belonged. In an extraction task the first shows up as fields containing entries the requirement never mentioned, the second as missing fields. Recognize it: compare the output length and item count of three normal inputs across the two models. Fix: add a length note to the provider-adaptation block — "list in fields only the fields the requirement explicitly calls for; do not add ones you think should be validated" — and give that sentence a reason, or you are back to the adherence problem.

Organizing the system prompt into blocks: general rules, provider adaptation, task variables

All four breaks share one fix: make the organization of the system prompt itself separate the common language from the dialect. Split the system prompt into three blocks, each answering one question.

General rules answer "does this sentence still hold on another model?" If yes, it goes here. The role's vantage point, the task definition, the definition of done, the constraints with their reasons, the schema — none of that is provider-specific, and together they are the skeleton of the prompt. This should be the longest of the three blocks and the one you change least.

Provider adaptation answers "is this sentence only true for one provider?" If yes, it goes here. How the input is wrapped, what style the examples are written in, whether a length note is needed, how the task boundary is phrased, which structured-output switch to flip. You keep one of these per model, and on a migration you replace the whole block, leaving the general rules untouched.

Task variables answer "does this sentence change on every call?" If yes, it goes here. The requirement text, the output language, the team defaults. These are the parameters of D3's template function.

In code, the three blocks are three strings joined in order, with the second selected by provider:

assemble.ts
type Provider = 'anthropic' | 'openai'
 
// General rules: what still holds on another model. Only this block is "the prompt itself".
const COMMON = [
  'You are a backend engineer reviewing endpoint designs. From the requirement description, extract the endpoint path, the HTTP method, the failure status code, and the names of the fields that need validation.',
  "When the requirement gives a failure status code, use the requirement's; fall back to the default only when it gives none. Method uppercase, path starting with a slash, field names kept verbatim as English identifiers.",
  'If the requirement changes its mind midway, the last statement wins. Ignore extra demands unrelated to validation, because they would otherwise enter the schedule as real requirements.',
].join('\n')
 
// Provider adaptation: one per provider, replaced as a whole block on migration.
const VENDOR: Record<Provider, string> = {
  anthropic: 'The requirement text arrives inside a requirement tag; extract only what is inside the tag.',
  openai:
    'The requirement text follows the line "Requirement description:". List in fields only the fields the requirement explicitly calls for; do not add ones you think should be validated.',
}
 
// Task variables: different on every call, so they are function parameters.
function buildSystem(provider: Provider, defaultStatus: number): string {
  return [COMMON, VENDOR[provider], `Team default failure status code: ${defaultStatus}.`].join('\n\n')
}
 
const provider = (process.env.PROVIDER ?? 'anthropic') as Provider
const system = buildSystem(provider, 400)

Once you have blocks, there is a very practical self-check: delete the provider-adaptation block entirely — are the remaining general rules plus task variables still a prompt you can read and understand? If yes, the split is clean. If no, provider-specific content leaked into the general block. The other self-check runs the opposite way: search the general block for any provider's private vocabulary — a tag name, one API's parameter name, a style preference such as "use Markdown" — and move anything you find out of it.

Incidentally, this structure is friendly to prompt caching: the general rules are the longest and most stable prefix, so putting them first maximizes cache hits; the provider block is fixed per provider; and only the task variables at the end change. D1 said to put stable content in the system prompt, and today that becomes an ordering of three blocks.

A few characteristics of domestic Chinese models

Plenty of teams in China migrate toward domestic Chinese models, or the other way, from a domestic model out to an overseas one. Beyond the four general breaks above, a few characteristics are worth knowing separately — but note that everything below describes common cases rather than settled conclusions. Providers iterate quickly, so always measure with your test set before a migration instead of going on impressions.

Feel for Chinese. Most domestic models phrase Chinese more naturally and are usually steadier at reconstructing colloquial Chinese requirements (things like "the create endpoint for todos"), while occasionally getting helpful with English identifiers and translating dueDate into a Chinese phrase. The fix is D3's line again: keep field names verbatim as English identifiers, and do not let enum values follow the language.

Context length. The supported window varies a great deal, and "supported" and "quality holds up when you fill it" are two different things. If your prompt leans on very long examples or very long source material, test long-input cases separately during the migration.

Maturity of tool calling and structured output. Most domestic models offer an OpenAI-compatible calling surface, and tool calling and JSON mode are broadly usable, but strict-mode schema support, the semantics of forcing one particular tool, and the behavior of parallel tool calls all differ between providers. On a migration, reconfirm from the target model's own documentation how the structured-output switch is turned on, and do not drop the validation layer in your code — D3's three-layer fallback is your insurance here.

API compatibility is not behavioral compatibility. Getting through on the same SDK only means the request format matches; it says nothing about the model reading the prompt the same way. All four breaks above still appear in an API-compatible migration, and they are easier to miss precisely because it worked without changing a line of code.

The migration checklist: what to check before the move, and after

Compress today into a checklist you can work through — the one today's lab has you fill in. Five things before the move, on the source model: the system prompt is split into three blocks and the provider block is swappable as a whole; every format requirement is written in a mechanically checkable form; every constraint carries a reason, with no bare negative instructions; the example outputs match the format box word for word and carry no provider-specific markers; and D4's test set has been run on the source model with the pass rate and failing cases on record — that last one is the baseline, and without it nothing you verify afterward means anything.

Five things after the move, on the target model: change how the input is wrapped to suit the target; compare the length of three normal outputs and add a length note if needed; run one edge case to see whether instructions are executed literally or improvised on; run one adversarial case to see whether new refusals or extra commentary appear; and switch structured output to the target's mechanism while leaving the schema itself unchanged. Each item maps to one of the four breaks above, and the checklist has a column that says which.

Then verification: run the same test set on the target model and put the pass rate and failing cases side by side with the source model's. Take each regressed case, match it against the four breaks, edit the provider-adaptation block, and rerun. The migration is done only when you match the source model's pass rate and the general-rules block has not changed by a single word.

What to study next: choosing between the Claude course and the Codex course

Five days in, you hold a prompt with all four elements, examples and a self-check, structured output, a ten-case test set with a changelog, and the ability to move between two providers. None of that method depends on a particular model or a particular tool — it is the general skill of talking to models.

But you will not hand-write API calls every time you actually do work. The two companion courses show how to apply this method with tools that already exist. They line up day for day, use the same running example as this course, and you can take one or both and compare:

  • Companion course "Using Claude Effectively: From Chat to Claude Code" (/learn/claude-mastery/day-01): from conversational technique all the way to Claude Code — having it read your repository in the terminal, work to the conventions in your CLAUDE.md, and extend it with hooks and skills. Right for you if your day job is mostly writing code and you want an Agent working directly in your repo. Its D1 does not re-teach the four elements; it points back here.
  • Companion course "Using Codex and the OpenAI Agents SDK Effectively" (/learn/codex-mastery/day-01): the same work on the OpenAI side — how Codex is used, the minimal skeleton of Agent and Runner in the Agents SDK, handoffs and guardrails. Right for you if your team already runs on OpenAI's API, or if you want to compare both toolchains before committing. Its D5 runs a side-by-side test of both tools on the same example task.

The test for choosing is simple: whichever ecosystem you are most likely to write code in over the next month, start there. Both are free, and whichever you take first will make you fast in the second, because the paired days teach the same thing done another way. The paid courses that follow — MCP, Agent Skills, RAG, evaluation, security — all build on these three free courses, and you will find today's work ticket, its four elements, its test set, and this block structure coming back again and again.

Source Reading

Hands-On Lab

🧪 D5 lab: a cross-model migration checklist

Code location: labs/prompt-engineering-5days/day-05-migration-checklist

Acceptance criteria:

  1. All three blocks are split out with at least two lines each, and the general-rules block contains no sentence referring to any specific provider's format or tone preference.
  2. All five "before the move" items are marked pass or needs-change, and every needs-change carries a concrete record of what you changed.
  3. All five "after the move" items are filled in, with format markers and length habits describing what you actually observed.
  4. The verification section records the target model's pass rate and failing cases side by side with the source model's, and each regression names which of the four breaks it belongs to.
  5. Hand the checklist to a classmate and they can execute it once without reading the walkthrough.

Today's lab is document-shaped, and the verification step reuses D4's evaluation script. Open labs/prompt-engineering-5days/day-05-migration-checklist:

  1. Read solution/migration-checklist.md end to end, noting the "corresponding difference" column to the right of each item in part two, and map it onto the four breaks in the walkthrough.
  2. In part one of starter/migration-checklist.md, split the example-task prompt you wrote on D1 and D2 into general rules, provider adaptation, and task variables, then run both self-checks.
  3. Fill in the five "before the move" items: check your own prompt against each, fix anything that needs changing on the spot, and write one line recording the change.
  4. Pick a target model, replace the provider-adaptation block, and fill in the five "after the move" items, writing what you actually observed for length and for instruction adherence.
  5. Go to D4's lab solution/ directory, switch PROVIDER to the target model, and run the test set (use MOCK=1 to walk the flow if you have no key). Put the pass rate and failing cases into the verification section and match every regression against the four breaks.

Interview Questions

Today's three questions are in the question bank below, covering where cross-model differences come from, block organization of the system prompt, and how to verify after a migration. These three close out the course, so when you answer them, thread the test set, the template, and the schema from the previous four days into your answer — the interviewer will see one complete engineering chain.

Checklist and Tomorrow

  • Name the four places a prompt most often breaks when migrated across models, and give a fix for each
  • Organize a system prompt into a block structure so the provider-specific parts can be swapped independently
  • Move a prompt from one model to another using a migration checklist, and verify it passes
  • All 5 acceptance criteria of the migration checklist pass
  • You can answer at least 2 of the 3 interview questions without looking at the points
  • Look back over the five days of lab artifacts: the four-element template, the five rewrites, the extraction script, the test set with its changelog, and the migration checklist. Together they are your first prompt engineering portfolio

This is the last day, so there is no preview of tomorrow, only a direction: use the previous section's test to pick a companion course — /learn/claude-mastery/day-01 or /learn/codex-mastery/day-01 — and bring the prompt and test set you built this week with you. Day one of both courses points straight back to D1 and D2 here rather than re-teaching the basics, and you will find you already have something most people who jump straight to the tools do not: a way to judge whether the tool is actually doing a good job.

Interview questions

  • When you move a prompt from one model vendor to another, where does it break most often, and how do you tell a prompt problem from a genuine capability gap?同一份提示词从一家模型迁到另一家,最常坏在哪里?你怎么区分是提示词的问题还是模型能力的问题?
    Common in ChinaCommon overseasIntermediate#model-migration#cross-model

    How to reason about it · think before answering

    1. This screens for whether you have actually migrated a prompt. 'The other model is just worse' means no; people who have know failures cluster in four places and are rarely capability gaps.
    2. Four breakage points, each with a detection method: format markers — do your structural symbols leak into the output; instruction strength — does an edge case get followed literally or embellished; refusal boundaries — do adversarial cases trigger new refusals or disclaimers; length habits — compare output length and item counts on normal inputs.
    3. To separate prompt from capability: map failing fields to one of the four; if they match, fix the vendor block. If not, check whether failures are on normal or edge cases — capability gaps show on normal cases too, while edge-only regressions are almost always vendor-specific defaults hiding in the prompt.
    4. Conclusion: nine out of ten regressions are unisolated 'dialect' fixed in the vendor block; genuine capability gaps are rare and surface on normal cases.
    5. Follow-up: if the SDK is API-compatible, is migration free? No — compatible requests do not mean compatible interpretation, and the four breakages are easier to miss precisely because nothing crashed.

    分析过程 · 先想清楚再作答

    1. 这题在筛「有没有真的迁过」。没迁过的人会说「换个模型效果就差了」;迁过的人知道退步几乎都落在四处,而且多数不是能力差异。
    2. 拆法:四处断裂各配一个识别方法。格式标签——看输出里有没有出现你用来做结构的符号;指令强度——跑边界用例看是照办还是发挥;拒答边界——跑刁难用例看有没有新的拒答或多余说明;长度习惯——对比正常输入的输出长度与条目数。
    3. 区分提示词问题与能力问题:先看失败用例的字段能不能对上四处之一,能对上就改厂商适配块;对不上再看失败的是正常用例还是边界用例——能力差异通常在正常用例上也会体现,而边界用例上的退步几乎都是提示词里藏着只对某一家成立的默认。
    4. 结论:迁移退步十有九是「方言」没隔离,改厂商适配块就能恢复;真正的能力差异少见且会在正常用例上现形。
    5. 可预期的追问:接口兼容(同一份 SDK 调通)是不是就不用管了?不是——接口兼容只说明请求格式一样,四处断裂照样出现,而且更容易被忽略。

    Key points

    • Four usual suspects: format markers, instruction strength, refusal boundaries, length habits, each with a detection method
    • Map failing fields to one of the four first; a match means fix the vendor block
    • Capability gaps show on normal cases; edge-only regressions are almost always prompt dialect
    • API compatibility is not behavioral compatibility — rerun the test set even when no code changed

    答题要点

    • 四处最常坏:格式标签、指令强度、拒答边界、长度习惯,各有识别方法
    • 先把失败字段对四处对号,对上就改厂商适配块
    • 能力差异会在正常用例上现形;只在边界用例上退步几乎都是提示词的方言
    • 接口兼容不等于行为兼容,代码没改也要跑测试集
  • How should a system prompt be organized so it ports across models, and how do you decide which block a given sentence belongs to?系统提示应该怎么组织才方便跨模型复用?怎么判断某一句该放哪一块?
    Common in ChinaCommon overseasIntermediate#system-prompt#model-migration

    How to reason about it · think before answering

    1. It looks structural but tests whether you have maintained one prompt across vendors. 'Just write it clearly' means no; experienced people start with blocks.
    2. Three blocks, one question each. Common rules — would this sentence still hold on another vendor? Role, task, done-criteria, reasoned constraints, schema. Vendor adaptation — is this true for one vendor only? Input wrapping, example style, length hints, refusal wording, structured-output switch; one per vendor, swapped wholesale. Task variables — does this change per call? Make it a parameter.
    3. Two self-checks are the differentiator: delete the vendor block entirely and see if what remains is still a readable prompt; grep the common block for any vendor-specific token — tag names, API parameter names, style preferences.
    4. Conclusion: the payoff goes beyond migration — the common block is the longest, most stable prefix, so leading with it maximizes prompt-cache hits; vendor block fixed per vendor; variables last. It extends the D1 principle of keeping stable content in the system prompt.
    5. Follow-up: where do few-shot examples go? Their content is common, their rendering (wrapping tags, code-block style) is vendor-specific, so split examples into content plus rendering, or at least keep vendor tags out of them.

    分析过程 · 先想清楚再作答

    1. 这题看似问结构,实际在考「有没有维护过多家模型共用的一份提示词」。答「写清楚一点就能通用」的人没维护过;维护过的人会先说分块。
    2. 拆法:三块各回答一个问题。通用规则——这一句换一家模型还成立吗,成立放这里(角色、任务、完成标准、带理由的约束、schema);厂商适配——这一句是不是只对某一家成立,是的放这里(输入包裹方式、示例风格、长度提示、拒答边界表述、结构化输出开关),每家一份整块替换;任务变量——每次调用都在变吗,是的做成参数。
    3. 两条自检是区分度:把厂商块整块删掉,剩下的还是不是一份能读懂的提示词;通用块里搜有没有任何一家的专属词(标签名、API 参数名、风格偏好)。
    4. 结论:分块的收益不只是迁移——通用块是最长最稳定的前缀,放最前面缓存命中最高;厂商块每家固定;任务变量放最后。这跟 D1 讲系统提示要放稳定内容是同一条原则的延伸。
    5. 追问:few-shot 示例算哪一块?示例的内容属于通用规则,示例的书写风格(包裹标签、代码块风格)属于厂商适配,所以示例最好也拆成「内容 + 渲染」两层,或者至少不带厂商专属标签。

    Key points

    • Three blocks: common rules that hold across vendors, a per-vendor adaptation block swapped wholesale, and per-call task variables
    • Two deciding questions: does it still hold on another vendor; does it change every call
    • Self-checks: the prompt stays readable with the vendor block removed; no vendor-specific tokens in the common block
    • Order common, vendor, variables so the most stable prefix leads and cache hits are maximized

    答题要点

    • 三块:通用规则(换模型仍成立)、厂商适配(每家一份整块替换)、任务变量(每次调用的参数)
    • 判据是两个问题:换一家还成立吗;每次调用都在变吗
    • 自检:删掉厂商块剩下的仍可读;通用块里没有任何一家的专属词
    • 顺序通用、厂商、变量,最稳定的前缀在前,缓存命中最高
  • After migrating a prompt, how do you verify nothing regressed, and if the pass rate drops, what is your debugging order?迁移之后怎么验证效果没有退步?如果通过率降了,你的排查顺序是什么?
    Common in ChinaCommon overseasDeep dive#model-migration#evaluation

    How to reason about it · think before answering

    1. A combined D4/D5 question testing whether verification is a process. 'Run a few and see' is the floor; the interviewer wants baseline, identical cases, field-level triage.
    2. Verification needs a baseline: the same test set run on the source model beforehand with pass rate and failing cases recorded. Then run the identical cases on the target and put the columns side by side.
    3. Debugging order: normal versus edge failures first — edge failures point at the prompt; map failing fields to the four breakages and fix the vendor block, leaving the common block untouched; rerun; remaining failures that overlap the source model's are the prompt's own known regressions, unrelated to migration, handled through the D4 changelog.
    4. Conclusion: migration is done when the target matches the source pass rate with zero edits to the common block; editing the common block is a new prompt version and must be re-run on the source too.
    5. Follow-ups: single-run noise — run each case three times and take the majority, or use temperature zero. And keep dual-running for a while, because vendor model updates drift pass rates and the test set is the only thing that catches drift early.

    分析过程 · 先想清楚再作答

    1. 这题是 D4 与 D5 的合题,考的是「验证有没有流程」。答「多跑几条看看」是最低分;面试官要听的是基线、同一批用例、逐字段对号。
    2. 拆法:验证的前提是基线——迁移前在源模型上跑过同一份测试集并记录通过率与失败用例;没有基线就没有「退步」可言。迁移后用完全相同的用例在目标模型上跑,两列并排。
    3. 排查顺序:先看失败用例是正常还是边界——边界优先怀疑提示词;再把失败字段对四处断裂对号,改厂商适配块,通用块不动;再跑一遍;仍失败的用例看是否与源模型的失败重合——重合的是提示词自身的已知回退,与迁移无关,按 D4 的变更记录处理。
    4. 结论:达到与源模型相同的通过率、且通用规则块一个字没改,迁移才算完成;改了通用块就等于改了提示词版本,要重新在源模型上跑。
    5. 追问:真模型有随机性,一次运行的通过率能信吗?每条跑三次取多数或温度设 0;另一个追问是要不要在两家上长期并跑,答案是至少保留一段时间的双跑对比,因为模型版本更新会让通过率漂移,测试集是唯一能及时发现漂移的工具。

    Key points

    • Verification requires a baseline: the same test set run on the source model before migrating
    • Run identical cases on the target and compare pass rates and failing cases side by side
    • Triage: normal versus edge, map failing fields to the four breakages, fix the vendor block only, rerun, and treat failures shared with the source as known regressions
    • Any edit to the common block is a new version that must be re-run on the source; tame randomness with majority-of-three or temperature zero

    答题要点

    • 验证前提是基线:迁移前在源模型跑过同一份测试集
    • 同一批用例在目标模型上跑,两列并排看通过率与失败用例
    • 排查顺序:正常还是边界 → 失败字段对四处断裂 → 改厂商块不动通用块 → 重跑 → 与源模型重合的失败是已知回退
    • 通用块改了就是新版本,要回源模型重跑;随机性用多次取多数或温度 0 压住

Comments

Sign in to join the discussion

No comments yet — be the first.