面试题库
共 328 题,当前筛选 6 题。
14 天用 Agent 搭一条 AI 短剧生产线
D1 一条 AI 短剧生产线长什么样:工序拆解、任务图架构与四类生成模型选型
一个重度依赖付费第三方生成接口的系统,怎么做到没有密钥也能开发和测试?怎么证明这套离线模式没有骗自己?For a system that depends heavily on paid third-party generation APIs, how do you make it developable and testable without keys — and how do you prove the offline mode is not fooling you?
国内高频海外高频深入#offline-testing#test-strategy分析过程 · 先想清楚再作答
- 这题的区分度全在后半句。前半句人人都会答「打 mock」,能答出「怎么证明它没骗自己」的才是真做过——因为绝大多数 mock 的实际效果是「保证程序不崩」,而不是「保证逻辑正确」。
- 怎么拆:先定桩的位置。桩只打在网络出口上,也就是每个 provider 的那一个方法里;业务代码里一个环境变量判断都不该有。一旦业务逻辑分叉,离线跑的就是另一个程序,你验的东西和线上没关系。
- 再定桩的质量:离线实现要产出真实形态的产物,而不是返回一个常量。做媒体流水线就用本地工具真的生成占位文件(纯色图、测试画面加音轨、正弦波音频),做检索就返回结构完整的假文档,做流式就按节奏一段段吐。目的是让下游的解析、状态机、时间轴计算真的被执行一遍。
- 证明它没骗自己的判据只有一条:**改一个输入,输出必须跟着变**。占位图的颜色随镜头描述变、占位音频时长随台词字数变、总时长随分镜数变——这说明中间的业务逻辑跑过了。如果换什么输入产物都一样,你验的只是没崩。
- 还要说收益:一次真跑几十分钟、上百块钱,一个下标写错就要等半小时才看得到;离线把这个反馈循环压到几秒,团队才会愿意持续重构这段代码。这是工程要求,不是玩具。
- 可预期的追问:那真实路径谁来保证?答案是分层——离线模式覆盖业务逻辑与回归测试,真实路径靠少量的冒烟用例定期跑,两者验的是不同的东西,不能互相替代。
How to reason about it · think before answering
- All the signal is in the second half. Everyone says mock it; only people who have done it can say how they prove the mock is honest, because most mocks only guarantee the program does not crash.
- Break it down by first fixing where the stub goes: only at the network egress, inside each provider's one method. No environment check belongs in business code — the moment business logic branches, offline runs a different program and your testing says nothing about production.
- Then fix the quality of the stub: the offline implementation should emit artifacts of the real shape rather than a constant. For a media pipeline, actually generate placeholder files locally (solid-color frames, a test pattern with an audio track, a sine-wave clip); for retrieval, return well-formed fake documents; for streaming, emit chunks with realistic pacing. The point is to force downstream parsing, state machines, and timeline math to execute.
- The one test that proves it is honest: change an input and the output must change. Placeholder color tracks the shot description, placeholder audio length tracks the line length, total runtime tracks shot count. If every input yields identical artifacts, you only verified that nothing crashed.
- State the payoff too: a real run costs tens of minutes and real money, so an off-by-one takes half an hour to surface. Offline collapses that loop to seconds, which is what makes continued refactoring affordable. This is an engineering requirement, not a toy.
- Likely follow-up: who then covers the real path? Layer it — offline covers business logic and regression, while a small set of smoke tests exercises the real vendors on a schedule. They verify different things and do not substitute for each other.
答题要点
- 桩只打在网络出口,业务代码里不出现任何离线判断分支
- 离线实现要产出真实形态的产物,让下游解析、状态机、时间轴计算真的执行
- 唯一的验收判据是「改一个输入,输出跟着变」,做不到就只验了没崩
- 收益是把几十分钟上百块的反馈循环压到几秒,团队才敢持续重构
- 真实路径靠少量定期冒烟用例覆盖,与离线模式验的是不同的东西
Key points
- Stub only at the network egress; business code contains no offline branch
- The offline implementation must emit real-shaped artifacts so downstream parsing, state machines, and timeline math actually run
- The single acceptance test is that changing an input changes the output; otherwise you only verified it did not crash
- The payoff is collapsing a tens-of-minutes, real-money feedback loop into seconds, which is what makes refactoring affordable
- Cover the real path with a small scheduled smoke suite; it verifies something different from the offline mode
D2 剧本 Agent:把一句话变成人物卡、场景与分镜的结构化数据
生成加评审这种双角色循环,收敛条件该怎么定才不会一直烧钱?In a generator-plus-reviewer loop, how do you define convergence so it does not burn budget indefinitely?
国内高频海外高频深入#agent-loop#cost-control分析过程 · 先想清楚再作答
- 这题在考「你有没有让这种循环真的停下来过」。只答「设一个最大轮数」拿不到分,那只是防死循环,不是收敛设计。区分度在于你能不能说出三个出口以及评审本身该怎么构造。
- 先拆评审:评审不该是一个模型,而是两层——能被程序判定的硬伤用代码查(字段缺失、数值越界、长度超限、引用不合法),程序判不了的软伤才交给模型。这一步决定了分数稳不稳定:全交给模型,同一份稿子两次评分能差十几分,循环就没有收敛可言。
- 再说三个出口:达标就停(阈值是「够用」不是「完美」,追最后几分成本远高于收益);到轮数上限就停,而且要交出历史最高分那一稿而不是最后一稿,因为评审有波动;剩下的问题全是软伤时转人工,因为让模型自己评自己改只会原地打转。
- 还要说计分方式:硬伤应该占大头(比如七成),软分占小头。否则模型一句好评就能盖过五条实打实的字段问题,循环会在第一轮就假装达标。
- 结论加代价:三个出口都需要参数,而参数必须实测调。阈值高了轮数用满,低了稿子不能看;上限大了烧钱,小了永远差一口气。上线前要把分数曲线画出来看它是不是单调上升。
- 可预期的追问:怎么知道循环真的在变好而不是在抖动?看硬伤条数,它是确定性的;分数会抖,硬伤条数不会。硬伤降不下去就说明写手根本没在按意见改,问题出在意见的粒度上——意见要带分类标签,模型才知道该改哪一类。
How to reason about it · think before answering
- This screens whether you have ever made such a loop actually terminate. Answering only set a max round count scores nothing — that prevents an infinite loop, it is not convergence design. The signal is naming three exits plus how the reviewer itself is built.
- Start with the reviewer: it should not be one model but two layers. Machine-checkable defects (missing fields, out-of-range numbers, length limits, invalid references) go to code; only the judgment calls go to the model. This decides score stability — a pure-model reviewer can swing by ten-plus points on the same draft, and then convergence is meaningless.
- Then the three exits: stop on threshold (the threshold means good enough, not perfect — chasing the last few points costs far more than it returns); stop at the round cap, handing back the highest-scoring draft rather than the last one, because review scores fluctuate; and escalate to a human once only judgment-call issues remain, since a model reviewing and revising itself just circles.
- Also cover the scoring weights: hard defects should dominate, say seventy percent, with the model's soft score at thirty. Otherwise one flattering model review outweighs five real field errors and the loop declares success on round one.
- Conclusion and cost: all three exits need parameters, and parameters need empirical tuning. Too high a threshold burns every round; too low ships an unusable draft. Plot the score curve before shipping and confirm it rises monotonically.
- Likely follow-up: how do you know it is improving rather than oscillating? Track the hard-defect count — it is deterministic, while the score jitters. If hard defects do not fall, the writer is not acting on feedback, and the fix is feedback granularity: tag each issue with a category so the model knows which class to repair.
答题要点
- 评审分两层:硬伤用代码判,软伤才交给模型,否则分数不稳定、循环无从收敛
- 三个出口:达标就停、到轮数上限交历史最高分那一稿、只剩软伤时转人工
- 计分让硬伤占大头,避免模型一句好评盖过实打实的字段问题
- 评语必须带分类标签,写手才能只改那一类,改稿才是收敛的
- 观测收敛看硬伤条数而不是分数,分数会抖、硬伤条数是确定的
Key points
- Split the reviewer: code judges hard defects, the model judges only judgment calls — otherwise scores are unstable and nothing converges
- Three exits: stop on threshold, stop at the round cap returning the best draft, escalate to a human when only soft issues remain
- Weight hard defects heavily so a flattering model review cannot mask real field errors
- Tag each review issue with a category so the writer repairs one class at a time
- Measure convergence by hard-defect count, not score — the score jitters, the count does not
D3 角色一致性:定妆图、参考图与风格锁定,让同一个人每一镜都还是他
生成类资产要做复用,缓存键你会怎么设计,才能既省钱又不会串戏?How would you design the cache key for reusing generated assets so that you save money without serving the wrong asset?
国内高频海外高频深入#caching#cost#image-generation分析过程 · 先想清楚再作答
- 这题考的是缓存的两类错误,而且两类的代价完全不对称。少命中只是多花钱,错命中会把上一集的道具塞进这一集——前者可量化,后者是内容事故。
- 推导链只有一句:**键必须由所有会改变产物的输入算出来,一项不多一项不少。** 多算了不该算的(比如输出路径),改一次目录结构缓存全部失效,白花一遍钱;少算了该算的(比如提示词),换了描述还命中老图,就是串戏。
- 落到这个场景,参与哈希的是:资产类别、归属对象、变体名、完整提示词、参考图标识、随机种子。用 sha1 之类取个短摘要当 id,元数据里再把这几项原样存一份,出问题能照着复现。
- 然后主动把边界说清楚,这是加分项:模型 id 与版本要不要进键?要。风格模板改了怎么办?它是提示词的一部分,进键之后天然全部失效——所以模板要谨慎改,或者给它一个版本号,让你能决定失效的范围。
- 生产视角还有一条:失败的生成不要写进缓存,否则你会稳定复用一张被审核拦下的空结果。命中缓存的那条路径也要记台账并标成命中,不然你算不出缓存到底省了多少钱。
- 可以预期的追问:缓存要不要过期?答案是内容型资产通常不设时间过期,而是靠版本号显式失效;时间过期会在你毫无预期的时候让一整集重新生成一遍。
How to reason about it · think before answering
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
答题要点
- 键由所有会改变产物的输入算出:资产类别、归属对象、变体名、完整提示词、参考图标识、随机种子,再加模型 id 与版本
- 不要把输出路径或文件名放进键,改目录结构会让缓存整体失效,白付一遍钱
- 少算提示词这类输入会导致错命中,那是内容事故,代价远高于少命中
- 元数据里原样保存参与哈希的各项,出问题能复现;失败的生成不写缓存
- 命中缓存也要记台账并标成命中,否则算不出缓存省了多少;失效靠显式版本号而不是时间过期
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
D4 从分镜到镜头:图生视频、异步任务轮询与失败重试
生成类接口返回失败,你怎么判断该不该重试?重试几次之后该做什么?When a generation API returns a failure, how do you decide whether to retry, and what happens after the retries run out?
国内高频海外高频深入#error-handling#retry#cost分析过程 · 先想清楚再作答
- 这题的题眼是「判断」。按状态码首位数字一刀切是最常见的错误答案,因为生成类接口的业务错误码往往和 HTTP 状态码不在一个层面上——很多厂商的失败是 HTTP 200 加一个响应体里的业务码。
- 给一条可复用的判据,比背错误码表有用:问三个问题——等一等会不会好、改输入会不会好、还是必须叫人来。三个问题对应三种处置:退避重试、修请求、立刻告警。
- 落到具体:限流和服务端故障属于第一类,程序自己扛;参数无效与内容审核属于第二类,重试一万次都是同一个错,而且会挤占限流额度让真正该重试的排不上号;鉴权失败与余额不足属于第三类,重试只会延迟告警。
- 然后单独处理超时,这是最能体现经验的一条:超时不是失败,是状态未知,对方队列里那个任务可能还在跑甚至已经成了。所以超时之后不能直接重提,要先按幂等键查一遍已有产物。
- 重试用尽之后要做三件事,缺一不可:把这一条标成失败并记下最后一次的错误码与请求参数、继续跑批次里剩下的任务不要中断、把失败清单汇总成一次可读的告警而不是每条发一次。
- 可以预期的追问:重试次数怎么定?按单价定。单价越高,允许的重试次数越少,而且高单价的失败更应该先送人复核再决定要不要重做。
How to reason about it · think before answering
- The hinge is 'decide'. Bucketing by the leading digit of the HTTP status is the classic wrong answer, because generation APIs often return HTTP 200 with a business error code in the body.
- Give a reusable test instead of reciting a code table: ask three questions — will waiting help, will changing the input help, or does a human have to step in? They map onto three dispositions: back off and retry, fix the request, alert immediately.
- Concretely: rate limits and server errors are the first bucket and the program handles them; invalid parameters and content moderation are the second, where retrying repeats the same error and burns rate-limit budget that genuinely retryable tasks needed; auth failure and insufficient balance are the third, where retrying only delays the alert.
- Handle timeout separately — this is the line that signals experience. A timeout is unknown, not failed: the job may still be running, or may have finished. So never resubmit blindly; look up the idempotency key for an existing artifact first.
- When retries are exhausted, do three things: mark the item failed with the last error code and the exact request parameters, keep processing the rest of the batch instead of aborting it, and aggregate the failures into one readable alert rather than one per item.
- Expect the follow-up: how many retries? Scale it by unit price. The more expensive the call, the fewer automatic retries, and expensive failures should go to a human for review before being redone.
答题要点
- 不要按状态码首位一刀切,生成类接口的业务错误码常常藏在 HTTP 200 的响应体里
- 判据是三个问题:等一等会不会好、改输入会不会好、还是必须叫人来,分别对应退避重试、修请求、立刻告警
- 限流与服务端故障可重试;参数无效与内容审核重试无用且会挤占限流额度;鉴权失败与余额不足必须告警
- 超时是状态未知不是失败,重试前先按幂等键查一遍已有产物,否则会重复计费
- 重试用尽后:标记失败并留下错误码与请求参数、不中断整批、把失败汇总成一次可读告警;重试次数按单价定
Key points
- Do not bucket by the leading HTTP digit; generation APIs often hide the business error code inside an HTTP 200 body
- Use three questions — will waiting help, will changing the input help, or is a human required — mapping to back off, fix the request, alert
- Rate limits and server errors are retryable; invalid parameters and moderation blocks are not and waste rate-limit budget; auth and balance failures need an alert
- A timeout is unknown rather than failed: check the idempotency key for an existing artifact before resubmitting, or you pay twice
- When retries run out, mark the item failed with its error code and request parameters, keep the batch running, and aggregate failures into one alert; scale retry counts by unit price
D6 剪辑台:用 ffmpeg 把素材合成一集竖屏成片
如果让大模型直接生成 ffmpeg 命令来合成视频,会有什么风险?你会怎么改造这个设计?What are the risks of letting an LLM generate ffmpeg command lines directly, and how would you redesign it?
国内高频海外高频深入#prompt-injection#pipeline-design#reproducibility分析过程 · 先想清楚再作答
- 这题考的是「Agent 到底能不能碰真实执行」这条边界,区分度在于你会不会主动说出安全之外的两条。只答「有注入风险」是及格线,答不出可复现与可调试就说明没在生产里跑过生成式流水线。
- 推导链很短:模型的输出是不可信输入 → 不可信输入进 shell 就是命令注入 → 而且模型输出天然不确定 → 不确定的命令意味着同样的输入产出不同的文件 → 排查时你还得先猜模型当时为什么那么写。三条风险分别对应安全、可复现、可调试。
- 改造的方向不是「加一层校验就放行」,而是把模型挪到另一个位置:让它只输出结构化的选择项,且每一项都从你定死的枚举里选(转场类型、裁切策略、封面取哪一镜),命令本身由你自己的纯函数从时间轴算出来。
- 补一句更硬的落地细节:调用外部程序不要走 shell 字符串,用参数数组(execFile 而不是 exec),从根上消掉转义问题;再加一层白名单校验,模型给出枚举外的值就退回默认值而不是报错。
- 可预期的追问是「那模型在这一环还有什么用」。答:用在需要审美判断的地方——情绪偏冷还是偏暖、封面选哪一镜、要不要转场。判断交给模型,执行留给程序,这是所有会产生副作用的 Agent 场景的通用分界。
How to reason about it · think before answering
- This probes where you draw the line between model judgment and real execution. Saying 'injection risk' is the passing bar; missing reproducibility and debuggability signals you have not run a generative pipeline in production.
- The chain is short: model output is untrusted input, untrusted input into a shell is command injection, model output is also nondeterministic, nondeterministic commands mean the same input yields different files, and debugging then requires guessing what the model was thinking.
- The fix is not 'validate and forward'. Move the model: let it emit only structured choices drawn from an enum you fixed in advance (transition type, crop strategy, which shot the cover comes from), and compute the command yourself from the timeline with a pure function.
- Add the concrete detail: invoke external binaries with an argument array (execFile, not exec) so escaping stops being a class of bug, then whitelist-validate the model's choices and fall back to a default instead of erroring.
- Expect the follow-up 'so what is the model still good for here'. Answer: taste calls — tone, cover selection, whether to use a transition. Judgment to the model, execution to the program. That boundary generalizes to any agent with side effects.
答题要点
- 三条风险按严重度排:命令注入、结果不可复现、报错不可调试;只说第一条不够。
- 改造成参数填充器:模型输出结构化选择项,取值必须落在预定义枚举里。
- 命令由程序的纯函数从时间轴生成,用参数数组调用而不是拼 shell 字符串。
- 白名单校验兜底,枚举外的值退回默认,而不是把错误抛给用户。
- 分界线一句话:模型负责判断,程序负责执行。
Key points
- Three risks in order: command injection, non-reproducible output, undebuggable failures. Naming only the first is not enough.
- Turn the model into a parameter filler: structured choices constrained to a predefined enum.
- Generate the command from the timeline with a pure function, invoked via an argument array rather than a shell string.
- Whitelist-validate and fall back to defaults for out-of-enum values instead of surfacing an error.
- One-line boundary: the model decides, the program executes.
D7 一集杀青:把六个环节串成端到端流水线并算清第一笔账
把多个已经各自跑通的环节串成一条流水线之后,哪些问题是单独调试时看不见的?After chaining several individually working steps into one pipeline, which problems appear that single-step debugging never shows?
国内高频海外高频深入#integration#pipeline-design#observability分析过程 · 先想清楚再作答
- 这题考的是系统集成的直觉。回答里如果只有「接口对不上」,说明你只集成过同步的纯函数;生成式流水线的集成问题主要出在状态和产物上,不在接口签名上。
- 拆解的角度是:单独调试时,是谁在做衔接?答案是你的脑子。你知道上一个脚本把文件写到哪、知道该拿哪份数据喂下一步。串起来之后这些隐式知识必须搬进代码,而搬漏的地方就是集成问题的来源。
- 由此可以推出三类具体问题。第一类是产物路径与命名:单独跑时随手写一个固定输出路径没问题,串起来跑第二遍就把第一遍覆盖了,失败时也分不清哪些文件属于哪一次。解法是每次运行分配一个运行标识,所有产物挂在它下面。
- 第二类是中间态:某一步的产物不完整但没报错,下一步照单全收,错误一路往下传,最后在离源头很远的地方炸掉。解法是每一步产出后做完整性校验,比如按数量断言。
- 第三类是可观测性:六个环节各打各的日志,几百行滚过去,出了事看不出是哪一环。解法是统一日志规格,终端上只留一张能一眼扫完的进度表,细节压到文件里。
- 可预期的追问是「怎么提前发现这些问题」。答:串联之前先约定三件事——产物目录布局、每一步的输入输出契约、日志规格。这三件事定下来,绝大多数集成问题在写代码时就被挡住了。
How to reason about it · think before answering
- This tests integration instinct. If the answer is only 'interfaces do not line up', you have only integrated synchronous pure functions. In generative pipelines the integration problems live in state and artifacts, not in signatures.
- The framing question is: during single-step debugging, who does the gluing? Your head does. You know where the last script wrote its files and which blob to feed forward. Chaining forces that implicit knowledge into code, and whatever you fail to move becomes an integration bug.
- That yields three concrete classes. First, artifact paths and naming: a fixed output path is fine in isolation, but the second run overwrites the first, and on failure you cannot tell which files belong to which attempt. The fix is a run id that every artifact hangs under.
- Second, partial intermediate state: a step produces incomplete output without erroring, the next step accepts it, and the error propagates until it explodes far from its origin. The fix is a completeness assertion after every step, such as an expected artifact count.
- Third, observability: six stages each log their own way, hundreds of lines scroll past, and you cannot tell which stage failed. The fix is one log contract — a scannable progress table on the terminal, details pushed to files.
- Expect the follow-up 'how do you catch these earlier'. Answer: agree on three things before chaining — the artifact directory layout, each step's input/output contract, and the log format. Fix those and most integration bugs never get written.
答题要点
- 单独调试时是人脑在做衔接,串联的本质是把隐式知识搬进代码。
- 产物路径与命名:每次运行一个运行标识,所有产物挂在它下面,避免覆盖与混淆。
- 中间态不完整却不报错,错误会传到很远的地方才炸;每一步产出后做完整性校验。
- 日志淹没:统一日志规格,终端只留进度表,细节压到文件。
- 预防手段是串联之前先定好目录布局、输入输出契约与日志规格三件事。
Key points
- In isolation a human does the gluing; chaining means moving that implicit knowledge into code.
- Artifact paths and naming: assign a run id and hang every artifact under it to avoid overwrites and confusion.
- Incomplete intermediate state that does not error propagates far before exploding; assert completeness after every step.
- Log flooding: adopt one log contract, keep a progress table on the terminal and push details to files.
- Prevent it by agreeing on directory layout, per-step I/O contracts and log format before chaining anything.