Dayward AI
Week 1 · D3About 5 hours

Character Consistency: Character Sheets, Reference Images, and Style Locking — Keeping the Same Person the Same Person in Every Shot

Wire up an image generation API, batch-produce character sheets and prop/scene assets from the shot data, lock down a look with reference images and fixed templates, and store the assets in a reusable library.

Today's goals 0/3

Sign in to tick these off and save your progress.

Today's Goals

  1. Wire up an image generation API, and batch-produce character sheets and scene images from the shot data
  2. Explain what character consistency relies on at the API level, and lock down a character's look with a reference image
  3. Build the generated assets into a searchable asset library, so later shots reuse them directly instead of regenerating

Yesterday you obtained structured shot data: who is in which shot, what they say, what is in frame. Today turns those fields into something genuinely visible — images. Come back and tick off the three goals.

Plain-Language Walkthrough

The lead has a different face in the second image

Start with the scene everybody hits the first time they make an AI short drama.

You write the prompt: a man of twenty-five, short black hair, heavy brows, a blue delivery uniform. Generate the first image and you are pleased. Generate a second with the same description and only the action changed to standing at a convenience store door — and out comes a different chin, wider-set eyes, and a blue that is not the same blue. You make the description finer, adding a faint scar at the left brow, and the third face changes again with the scar moved to the right.

The endpoint is not broken and your prompt is not insufficiently good. The reason is plain: an image generation model has no memory. It does not know that a previous image exists, and each request is a brand-new, unrelated sample.

The crew analogy makes it clear. You hired an extremely fast concept artist producing a look test a minute, with one quirk: they forget the previous one completely on finishing it. Say "the same as that last one from another angle" and they ask which one. The only thing they can work from is the sheet you hand them at this moment — they draw what is written and invent whatever is not.

That invented part is where inconsistency comes from. Your description covered the hairstyle and the uniform and not the nose bridge, the face's width, the eyelid, or the uniform's exact shade — those unconstrained degrees of freedom get re-rolled with every sample. And a face's recognizability lives precisely in those details: an audience does not remember a blue uniform and recognizes in two seconds that this is not the same person.

The engineering cost is larger than it looks. An episode of forty shots has the lead in thirty of them. Rerolling to catch a matching face costs, at ¥0.025 an image and ten rolls per shot, only ¥7.5 — money is not the problem, people are: you must sit comparing image after image and rerolling, and thirty shots is an afternoon. This pipeline's goal is running an episode unattended, and picking images by hand is its greatest enemy. Worse, that cost grows linearly with episodes: five episodes is five afternoons and there can be no second season.

So character consistency is not an aesthetic problem but the precondition for this line being automatable at all. So what, at the API level, holds one person in place?

Three locking techniques and what each holds

Engineering offers three, differing widely in price and effect. The conclusion first, then each in turn.

TechniqueWhat it holdsWhat it does notCost
Prompt templateStyle, lighting, composition, aspectFacial details, face shapeEssentially zero, one more spliced string
Random seedReproducibility of one promptNothing once the prompt changesZero, with a very narrow application
Reference imageThe face and the lookCostume and prop details, extreme anglesOne more image per request, and you need that image first

A prompt template is the cheapest, essentially extracting what must be identical in every image into a constant. Style, lighting, depth of field, vertical composition, no watermark — those descriptions are verbatim identical across every image in this course. What it holds is the frame's overall feel; skip it and you get a finished cut half photoreal and half animated. What it cannot hold is a face, because facial detail cannot be exhausted in a hundred words.

A random seed is the most misunderstood. Many believe fixing the seed locks the character, when what it locks is reproducibility: the same model, the same prompt, and the same seed rerun gives the same image. That is extremely useful while debugging — change one word and see how the frame moves with everything else fixed. But every shot in a short drama naturally has a different prompt (different action, different scene), and once the prompt changes the same seed samples an entirely different person. A seed is a reproducibility switch, not a consistency switch. That is followed up on in nearly every interview touching consistency.

A reference image is the genuine solution for a face. MiniMax's image endpoint calls the field subject_reference, shaped in the request body as an array whose elements carry type and image_file; type currently supports only character, and image_file takes a public URL or a Base64 data URL of a JPG or PNG under 10MB. Two limits must be remembered: type has only the character kind, so you cannot lock a prop with it; and one request carries one reference image. Note those are the image endpoint's limits and not every endpoint's — the video endpoint differs, covered separately below.

Below is all three stacked: the template as a constant, the seed fixed, and the reference image taken from the character card.

generate.js
// The course-wide style template: spliced verbatim onto every image, the cheapest consistency technique
const STYLE = 'urban short-drama texture, soft studio lighting, shallow depth of field, photoreal portrait, vertical composition, no text watermark'
 
async function generate({ prompt, referenceImage, seed }) {
  const res = await fetch(`${process.env.MINIMAX_BASE_URL}/v1/image_generation`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.MINIMAX_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'image-01',
      prompt: `${prompt}. ${STYLE}`,
      aspect_ratio: '9:16',
      n: 1,
      seed,
      prompt_optimizer: false, // false by default; enabling it rewrites your prompt and reproducibility is gone
      response_format: 'url',
      // type supports only character, and one request carries one reference image
      ...(referenceImage ? { subject_reference: [{ type: 'character', image_file: referenceImage }] } : {}),
    }),
  })
  const json = await res.json()
  // HTTP 200 does not mean success; the business error code is in base_resp.status_code
  if (json.base_resp?.status_code) throw new Error(`image endpoint failed ${json.base_resp.status_code}`)
  return json.data.image_urls[0]
}

The look test flow: settle one master image and derive from it

With the reference image as a tool, the flow follows naturally: spend the effort rolling one master image you are happiest with, then have every later image reference it.

That is exactly how a crew does look tests. The art department does not decide on the lead's appearance on the day; they shoot a set of look tests in advance and pin them to the wall as the standard for everyone. The base image is that photograph on the wall.

Three steps concretely:

Step one, generate a base image per character. This step carries no reference image (there is none yet) and does carry a fixed seed, and is worth rolling a few times for a human to pick. This is the one place in the pipeline where human involvement is recommended — picking one image determines the look of dozens of shots, and that time is well spent. Once picked, write the path back to the character card's referenceImage field.

Step two, derive multiple angles, expressions, and costumes with the base image as reference. Front, three-quarter, angry, smiling, with each prompt changing only the body description while the reference image stays the base. Note that all derive from the base image rather than from the previous one — the latter accumulates deviation image by image, and by the fifth it is not the same person, a phenomenon called drift.

Step three, register the derivatives too, so every later shot needing a first frame takes one rather than regenerating.

An easily missed detail: fix the same seed across derivatives too. The reference image governs the face and the seed governs the sampling origin of every other degree of freedom, and the two together make the set look shot on the same day on the same stage.

Scenes and props cross over too

With the character locked, the second failure point is the scene.

The same rainy-night apartment block is six stories in shot eight and twelve in shot twelve, with the street lamp going from warm to cool — the audience will not say the scene is inconsistent, they will find the drama baffling. Props are more obvious: the phone driving the whole plot is a black slab in shot three and a folding phone in shot seven, and the plot collapses on the spot.

The remedy follows the same thinking as characters with the order reversed: scenes and props need not be generated per shot and should be made once before shooting and then referenced.

Because scene reuse is extremely high. Forty shots usually happen across three to five scenes, meaning thirty-odd shots share one batch of plates. Generating and registering those plates in advance takes an episode from forty scene generations to five — the easiest one-time saving on this line.

One easily missed thing to record while registering: which shot this image is for and what the prompt was. When something goes wrong you must be able to answer how shot twelve's building was generated, and being unable to means rerolling.

The asset library's minimal design

Now those images can have a proper home. It needs no database, only four things: an identifier, some metadata, a file, and one deduplication.

The identifier is the deduplication key, which decides what counts as the same asset. The key judgment: the key must be computed from content that changes the image, not from a filename or a path. Using a path as the key has two opposite harms: change the directory structure once and every cache entry invalidates, paying again; and change the prompt under the same path and the cache wrongly hits, so the reader sees an old image despite an edited description — which is the crossing-over.

So what participates in the hash is: the asset kind, its owner, the variant name, the full prompt, the reference image path, and the seed. Change any one and it must be regenerated; leave all six unchanged and it can be safely reused.

assets.js
import { createHash } from 'node:crypto'
 
// The deduplication key = a content identifier. Any of the six that changes the image must be hashed
export function assetKey({ kind, ownerId, variant, prompt, referenceImage, seed }) {
  const material = [kind, ownerId, variant, prompt, referenceImage ?? '', seed ?? ''].join(' ')
  return `${kind}-${createHash('sha1').update(material).digest('hex').slice(0, 12)}`
}
 
// This is the only place in the pipeline that calls the image endpoint, and the only place deduplication happens
export async function ensureAsset(lib, input) {
  const id = assetKey(input)
  const cached = lib.find(id)
  if (cached) {
    console.log(`reused ${id}`)
    return cached // not one call to the endpoint, and therefore not one cent
  }
  const url = await generate(input)
  const record = { id, ...input, path: await download(url, input.outPath), at: new Date().toISOString() }
  lib.register(record)
  return record
}

Beyond those six, the metadata records the file path, what this cost, and the generation time. Files land under assets/ layered by kind, with the index written as an assets/index.json recognized again after a restart.

This design is deliberately crude, because it solves only not regenerating within one run. A genuinely complete cache key design handles more: whether a new model version counts as the same asset, whether a changed prompt template invalidates everything, whether the cache should expire. Those are settled together in D8's workflow engine, and today saves the most direct money.

Generation failures and content review rejections

The last section is about failure, because batch generation will encounter it and mishandling is expensive.

The image endpoint's error comes from base_resp.status_code, and the first rule: HTTP 200 does not mean success. Judge only the HTTP status and you take a business error for a normal response and then get an incomprehensible empty-value error parsing data.image_urls, with the investigation heading entirely the wrong way.

With the status code in hand, sort by whether doing something different would help:

  • Waiting helps: 1002 rate limiting and various server errors. A retry after backoff usually succeeds, and the program can carry this class itself.
  • Only changing the input helps: 2013 invalid parameters (usually an invalid reference image address or a prompt past the 1,500-character limit), and 1026 and 1027 tripping the content safety review. Those two give the same error ten thousand retries later, wasting money and exhausting the rate limit allowance.
  • A human is required: 1004 authentication failure and 1008 insufficient balance. A program cannot solve them and retrying only delays the alert.
classify.js
// The criterion is not the status code's first digit but whether doing something different would help
const RULES = {
  1002: { kind: 'rate-limited', action: 'retry' }, // waiting helps; the program carries it
  2013: { kind: 'bad-request', action: 'fix-input' }, // invalid reference address, over-long prompt
  1026: { kind: 'content-blocked', action: 'fix-input' },
  1027: { kind: 'content-blocked', action: 'fix-input' },
  1004: { kind: 'auth', action: 'alert' }, // a program cannot solve it; retrying only delays the alert
  1008: { kind: 'insufficient-balance', action: 'alert' },
}
 
export function classify(statusCode) {
  // An unseen code is treated as a server fault: retryable, with a log line so somebody sees it
  return RULES[statusCode] ?? { kind: 'server', action: 'retry' }
}

Batch settings add one more rule: one image's failure must not abort the batch. With shot seven of forty blocked by review, the right move is recording that one, continuing through the remaining thirty-three, and reporting the failure list at the end. Aborting wastes the money spent on the first six, and rerunning needs the deduplication key to avoid paying twice — the second value of the previous section's key.

Why content review blocks things, how prompts should be changed, and what labels exports need are a whole compliance subject covered on D11. Today reaches only three things: sorting correctly, not retrying blindly, and a readable failure list.

Source Reading

Hands-On Lab

🧪 D3 lab: a generator producing character sheets and scene assets in batch from shot data, plus an asset library

Code location: labs/ai-drama-pipeline/day-03-character-assets

Acceptance criteria:

  1. MOCK=1 pnpm start finishes with a base image and three variants in the same character directory, and all three variant log lines ending in "with reference image."
  2. The report's line for how many scenes were regenerated on the repeat request in step 4 reads 0, with two reuse records visible in the log.
  3. The report's comparison table shows all 6 variants as different — the same prompt and the same seed, with the only difference being whether a reference image was carried.
  4. Every record in the asset index carries the prompt, the reference image path, and the seed, so a problem can be reproduced from it.
  5. pnpm typecheck passes with no any.

starter/ has four exercise points cut out, two in the asset library and two in the main flow, all runnable offline under MOCK=1. Run it as-is once and note the three numbers in the report's last three lines: registrations far below generations, two more images generated on the repeat request, and the comparison group all identical — those three are your to-do list, each exercise fixing one. Offline, a placeholder image's color comes from the prompt and the reference image, so whether a reference was carried genuinely changes the output file and the fingerprints compare.

  1. Generate one base look test per character, write the paths back to the character cards' reference image field, and confirm two base records appear in the index.
  2. Derive three variants from the base image, and observe every log line ending with the "with reference image" marker.
  3. Batch-generate the scene plates used by the shots and register them, confirming only the scenes actually referenced were generated.
  4. Request the same batch of scenes again verbatim and see "reused" rather than "generated," with 0 regenerations in the report.
  5. Run the same derivation with reference images off, compare the two groups' fingerprints as all different; with a real key attached, open both groups side by side and judge by eye which one is still the same person.

Interview Questions

Today's 3 questions are in the question bank below, weighted toward the consistency problem caused by a generation model having no memory, what a reference image and a seed each lock, and the cache key design for asset reuse. Expand each one and read the analysis before the key points — question 2 on seeds is this chapter's easiest to get wrong and nearly always follows a question about consistency. The high-frequency labels for the domestic and overseas markets are there so you can pick by target market.

Checklist and Tomorrow

  • Wire up an image generation API, and batch-produce character sheets and scene images from the shot data
  • Explain what character consistency relies on at the API level, and lock down a character's look with a reference image
  • Build the generated assets into a searchable asset library, so later shots reuse them directly instead of regenerating
  • Say what each of a prompt template, a random seed, and a reference image does and does not lock
  • Explain why derivatives all reference the base image rather than the previous one
  • All 5 acceptance criteria of the lab pass
  • Answer at least 2 of the 3 interview questions without looking at the key points

Tomorrow (D4) turns these static images into moving shots: taking today's chosen look test as a video's first frame and having the model act on for six seconds. Images before video is deliberate, because video generation is the slowest and most expensive step on this line — pin the look down with a one-cent image first, then spend several yuan animating it, and a mistake costs two orders of magnitude less. D4's focus is not picture quality but how an asynchronous task client is written: submit for an identifier, poll for status, collect for an address, download to disk, with all four steps able to go wrong.

Interview questions

  • Where does the character consistency problem in image generation come from, and what engineering mitigations exist, with what trade-offs?生成模型的角色一致性问题是怎么来的?工程上有哪几种缓解手段,代价分别是什么?
    Common in ChinaCommon overseasBasic#image-generation#consistency

    How to reason about it · think before answering

    1. The differentiator is your first sentence. Saying 'the prompt wasn't detailed enough' reads as a user, not an engineer; the answer they want is that each request is an independent sample with no memory across calls.
    2. Follow the mechanism: a prompt only constrains the degrees of freedom you actually wrote down, and everything unwritten gets re-sampled — while face recognizability lives exactly in the details text cannot exhaust.
    3. Present the mitigations in three layers by what each one actually locks: a prompt template locks style and framing at near-zero cost; a fixed seed locks reproducibility for one identical prompt and stops helping the moment the prompt changes; a reference image locks the face, but only one per request, so two faces in one frame cannot both be locked.
    4. The trade-off discussion is where candidates separate: using a reference image means you must first produce a base image, which forces a human 'pick the reference sheet' step into an otherwise unattended pipeline.
    5. Volunteer the counter-intuitive rule: every derived image must reference the same base image, never the previous one. Chaining references accumulates drift, and by the fifth image it is a different person.
    6. Expect the follow-up: what if consistency still fails? The answer is cinematography — split two-character frames into reverse-angle singles and push secondary characters to wider shots, working around the API's limits with shot design.

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

    1. 这题的区分度在第一句。答「提示词写得不够细」就掉到了使用者视角;面试官想听的是「模型每次请求都是独立采样、没有跨请求记忆」这个机制层面的原因。
    2. 顺着机制往下推就有了完整答案:提示词只约束了你写出来的那些自由度,没写的部分每次重新掷一遍;而人脸的辨识度恰好集中在脸型、眼距、鼻梁这些你没法用文字穷尽的细节上。
    3. 手段按「锁得住什么」分三层说,不要混在一起:提示词模板锁风格与构图,成本几乎为零;随机种子锁同一提示词的可复现性,换提示词即失效;参考图锁人脸,但每次请求只能带一张,双人同框锁不了两个人。
    4. 代价这一段才是拉开差距的地方:参考图要求你先有一张基准图,于是流程里必须插入一次「定妆并由人挑一张」的环节,这是整条自动化流水线上少数值得保留的人工卡点。
    5. 还要主动说一个反直觉的做法:派生图必须都参考同一张基准图,不能参考上一张。参考上一张会让偏差逐张累积,第五张已经不是同一个人了。
    6. 可以预期的追问:一致性做不到怎么兜底?答案是改镜头语言——把双人同框拆成正反打的单人镜头、次要角色用更远的景别,用拍法回避接口能力的边界。

    Key points

    • The root cause is that each request is an independent sample with no cross-request memory, so unconstrained degrees of freedom get re-rolled
    • A prompt template locks style and framing at near-zero cost but cannot lock facial detail
    • A fixed seed locks reproducibility for one identical prompt and stops helping once the prompt changes
    • A reference image locks the face, but you must first produce a base image and only one reference is allowed per request
    • Derive every variant from the same base image rather than chaining off the previous one, or drift accumulates image by image

    答题要点

    • 根因是模型每次请求独立采样、没有跨请求记忆,提示词没约束到的自由度会被重新掷一遍
    • 提示词模板锁风格与构图,成本几乎为零,但锁不住五官
    • 随机种子锁的是同一提示词的可复现性,提示词一变就失效
    • 参考图锁人脸,代价是必须先有基准图,且每次请求只能带一张,双人同框锁不了两个人
    • 派生图统一参考同一张基准图,不要链式参考上一张,否则偏差会逐张累积
  • Does fixing the random seed solve character consistency? What does a seed actually lock?固定随机种子能解决角色一致性吗?它到底锁住了什么?
    Common in ChinaCommon overseasIntermediate#image-generation#reproducibility

    How to reason about it · think before answering

    1. This is a yes/no trap dressed as a concept question; answering 'yes' ends it. The hinge is 'what does it actually lock' — they are testing whether you separate reproducibility from consistency.
    2. Define it first: a seed is the random starting point of sampling. With the model, prompt and other parameters unchanged, the same seed returns the same image, so what it locks is reproducibility.
    3. Then explain why that is not enough here: every shot has a different prompt because action, scene and shot size all change. Change the prompt and the sampling path changes with it, so the same seed yields a different person. A seed is a reproducibility switch, not a consistency switch.
    4. Do not dismiss it though. It earns its place twice: single-variable debugging, where you change one word and watch the image move; and stacked with a reference image, where the reference holds the face and the seed holds the remaining degrees of freedom so a whole set looks shot on the same day.
    5. One production note: for a seed to actually reproduce anything, turn the prompt optimizer off. It defaults to on, rewrites your prompt server-side, and you never see the rewrite — which destroys reproducibility.
    6. Expect the follow-up: is seed semantics the same across vendors? No guarantee — switching vendor or even model version can make the same seed produce something else, which is one more reason to keep a provider abstraction layer.

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

    1. 这是一道判断题伪装成的概念题,答「能」直接出局。题眼是「到底锁住了什么」——面试官在测你有没有把复现和一致这两件事分开。
    2. 先给定义:seed 是采样的随机起点。在模型、提示词、其余参数都不变的前提下,同一个 seed 会给出同一张图,所以它锁住的是**可复现性**。
    3. 再说为什么在短剧场景里不够用:每一镜的提示词天然不同,动作、场景、景别都在变。提示词一变,采样路径就换了,同一个 seed 出来的是完全不同的人。所以 seed 是复现开关,不是一致性开关。
    4. 但不要把它说成没用。它在两个地方非常值钱:调试时做单变量对照,只改一个词看画面怎么变;以及跟参考图叠加使用,参考图管脸,seed 管其余自由度的采样起点,两者一起才让整组图像同一天在同一个棚里拍的。
    5. 生产视角补一句:想让 seed 真的可复现,必须把提示词优化开关关掉。那个开关默认是开的,它会在服务端改写你的提示词,改写结果你看不到,可复现性也就没了。
    6. 可以预期的追问:那不同厂商的 seed 语义一样吗?答案是不保证,换厂商甚至换模型版本都可能让同一个 seed 出别的图,所以 seed 不能作为跨厂商的一致性依据——这也是要有一层 provider 抽象的原因之一。

    Key points

    • No. A seed locks reproducibility: same model, same prompt, same other parameters plus same seed returns the same image
    • Every shot in a drama has a different prompt, and a changed prompt voids the seed, so it is not a consistency mechanism
    • Its real value is single-variable debugging, and stacking with a reference image — the reference holds the face, the seed holds the rest
    • For a seed to reproduce anything you must disable the server-side prompt optimizer, which is on by default and rewrites your input
    • Seed semantics do not carry across vendors or model versions, so a seed cannot underpin cross-provider consistency

    答题要点

    • 不能。seed 锁的是可复现性:模型、提示词与其余参数都不变时,同一个 seed 给出同一张图
    • 短剧每一镜的提示词天然不同,提示词一变 seed 就失效,所以它不是一致性手段
    • 它真正的用处是单变量调试,以及与参考图叠加——参考图管脸,seed 管其余自由度的采样起点
    • 要让 seed 可复现,必须关掉服务端的提示词优化开关,它默认开启且会改写你的输入
    • seed 语义不跨厂商也不跨模型版本,不能作为跨 provider 的一致性依据
  • How would you design the cache key for reusing generated assets so that you save money without serving the wrong asset?生成类资产要做复用,缓存键你会怎么设计,才能既省钱又不会串戏?
    Common in ChinaCommon overseasDeep dive#caching#cost#image-generation

    How to reason about it · think before answering

    1. This question is about two kinds of cache error with wildly asymmetric cost. A miss only costs money; a wrong hit puts last episode's prop into this one. The first is a number, the second is a content incident.
    2. The derivation is one sentence: the key must be computed from every input that changes the artifact, and nothing else. Include something irrelevant, like the output path, and one directory refactor invalidates everything and you pay again; omit something relevant, like the prompt, and a changed description silently serves the old image.
    3. Concretely, hash the asset kind, the owning entity id, the variant name, the full prompt, the reference image identity and the seed. Take a short digest as the id, and store those fields verbatim in the metadata so any artifact can be reproduced.
    4. Then name the boundaries yourself: does the model id and version belong in the key? Yes. What if the style template changes? It is part of the prompt, so it invalidates everything by construction — which is why templates should carry a version number, letting you choose the blast radius.
    5. One more production note: never cache failed generations, or you will faithfully reuse an empty result that safety review rejected. Cache hits also belong in the cost ledger, flagged as hits, otherwise you cannot report how much caching saved.
    6. Expect the follow-up: should the cache expire? Content assets usually should not expire on time; invalidate explicitly by version instead, because a time-based expiry regenerates a whole episode at the least convenient moment.

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

    1. 这题考的是缓存的两类错误,而且两类的代价完全不对称。少命中只是多花钱,错命中会把上一集的道具塞进这一集——前者可量化,后者是内容事故。
    2. 推导链只有一句:**键必须由所有会改变产物的输入算出来,一项不多一项不少。** 多算了不该算的(比如输出路径),改一次目录结构缓存全部失效,白花一遍钱;少算了该算的(比如提示词),换了描述还命中老图,就是串戏。
    3. 落到这个场景,参与哈希的是:资产类别、归属对象、变体名、完整提示词、参考图标识、随机种子。用 sha1 之类取个短摘要当 id,元数据里再把这几项原样存一份,出问题能照着复现。
    4. 然后主动把边界说清楚,这是加分项:模型 id 与版本要不要进键?要。风格模板改了怎么办?它是提示词的一部分,进键之后天然全部失效——所以模板要谨慎改,或者给它一个版本号,让你能决定失效的范围。
    5. 生产视角还有一条:失败的生成不要写进缓存,否则你会稳定复用一张被审核拦下的空结果。命中缓存的那条路径也要记台账并标成命中,不然你算不出缓存到底省了多少钱。
    6. 可以预期的追问:缓存要不要过期?答案是内容型资产通常不设时间过期,而是靠版本号显式失效;时间过期会在你毫无预期的时候让一整集重新生成一遍。

    Key points

    • Derive the key from everything that changes the artifact: asset kind, owner id, variant, full prompt, reference image identity, seed, plus model id and version
    • Keep output paths and filenames out of the key, or one directory refactor invalidates the whole cache and you pay twice
    • Omitting inputs like the prompt causes wrong hits, which are content incidents and far costlier than misses
    • Store the hashed fields verbatim in metadata so any artifact is reproducible, and never cache failed generations
    • Record cache hits in the cost ledger flagged as hits, and invalidate explicitly by version rather than by time

    答题要点

    • 键由所有会改变产物的输入算出:资产类别、归属对象、变体名、完整提示词、参考图标识、随机种子,再加模型 id 与版本
    • 不要把输出路径或文件名放进键,改目录结构会让缓存整体失效,白付一遍钱
    • 少算提示词这类输入会导致错命中,那是内容事故,代价远高于少命中
    • 元数据里原样保存参与哈希的各项,出问题能复现;失败的生成不写缓存
    • 命中缓存也要记台账并标成命中,否则算不出缓存省了多少;失效靠显式版本号而不是时间过期

Comments