项目深挖54 22 分钟

项目被追问‘你做的和框架有什么区别’,怎样讲出自己的贡献

框架替你处理通用编排,面试官更关心你在具体约束下做了什么决定:为什么这样设计,怎么验证,失败后改了哪一处。别只报组件名。

原理 实现 边界 追问

本篇阅读顺序 · 三遍读法

一篇文章,读出三种能力。

先弄懂它为什么这样工作,再把条件换一换,看方案还能不能站住,最后用代码和证据复盘一遍。顺序固定,读完才知道自己是真的会了,还是只记住了名词。

01 / 基础知识先回答“它为什么这样工作”

沿着直觉、公式和边界读正文,看到变量就问输入、状态、复杂度分别是什么。

02 / 高频追问再回答“条件变了怎么办”

把面试官的追问当作小型设计评审:更大流量、更少上下文、外部失败或安全约束出现时,局部如何重算。

03 / 从零实现把状态、约束和结果落到一个能验收的闭环

沿代码、表格和证据卡复盘,最后用文末的 60 秒回答确认自己没有只记住名词。

问题面试官到底在判断什么
机制系统如何工作
证据代码、指标与取舍
表达30 秒回答骨架

“你们不就是把 LangChain、向量库和一个大模型接起来吗?”

这句话不一定是在否定项目。面试官想知道的是:如果把框架换掉,哪些能力仍属于你?你解决了哪条业务约束?做过什么实验,结果怎样?

先给一个能复述的答案

框架提供通用的消息、工具和流程抽象;项目贡献体现在具体业务约束下的路由、数据契约、权限、评测、成本和故障恢复。回答时不要从组件清单开始,而要按“问题—决策—证据—取舍—结果”讲一条闭环,并明确哪些能力依赖框架、哪些是自己实现和验证的。

框架能力与项目贡献的边界:通用抽象之上是约束、决策和证据

先画边界,不要先背名词

我会把项目拆成三层:

  1. 框架层:消息循环、工具注册、基础 tracing、模型适配器。
  2. 项目层:领域数据模型、权限策略、检索与路由、任务状态和业务工具契约。
  3. 验证层:真实业务集、失败分类、成本预算、回归和上线监控。

如果只讲第一层,换个框架项目就没了;如果能讲清第二、三层,面试官才能看到你的工程判断。

框架:tool.invoke(name, args)
项目:policy.check(actor, resource, action, args_hash)
验证:assert audit_event && result.status != unknown

同一个框架调用,在你的项目里可能必须绑定租户、审批和幂等键,这就是贡献所在。

用一条决策记录说明“为什么这样做”

不要说“我们用了混合检索,因为效果好”。要说当时的约束、候选方案和证据:

问题:客户合同中既有精确编号,也有自然语言描述
候选:纯向量、纯关键词、混合 + 重排
决策:混合 + 版本过滤
证据:合同集 Recall@10 +11%,P95 只增加 38ms
取舍:索引和调试复杂度上升,换来编号命中稳定性

决策记录把约束、候选、实验、取舍和结果固定下来

这比说“向量库是行业最佳实践”有信息量得多,也能让追问继续沿证据走。

框架换掉之后,什么必须留下

可以列一张贡献清单:

能力为什么不能直接交给框架你的证据
工具契约业务参数、幂等和错误码是领域约束schema、适配器测试
权限策略框架不知道租户和审批语义越权回归集、审计事件
检索路由业务问题决定查文档还是调 API路由混淆矩阵
任务状态副作用恢复与框架无关状态机、对账记录
评测体系通用成功率无法代表业务成功真实数据集、分桶报告

如果换框架后这些内容仍能迁移,说明你做的是系统而不是配置。

项目贡献通过可迁移的契约、策略、评测和回放证据来证明

讲结果时避免两个极端

极端一:把所有问题都归功于自己

模型能力、开源框架和基础设施同样是项目的一部分。夸大贡献会在追问实现细节时暴露。诚实说清“框架提供了什么、我补了什么”,反而更可信。

极端二:只说自己写了多少代码

代码行数不等于价值。一个 80 行的权限网关可能比 2000 行胶水代码更关键。用事故避免、成功率提升、延迟和可回放性说明结果。

面试追问的回答模板

背景:什么业务场景、什么约束
问题:原方案在哪个边界失效
决策:有哪些候选,为什么选这个
实现:我负责哪一层,接口和状态如何定义
证据:用什么数据、实验或故障验证
取舍:成本、复杂度和风险换来了什么
复盘:如果重做,哪条边界会提前设计

这套模板不是背稿,而是防止把项目讲成组件导览。每一段都应该能指向代码、实验或运行记录。

用贡献阶梯把“我做了什么”讲清楚

可以把贡献分成五级,回答时从低到高说明自己真正负责到哪里:

  1. 配置级:调整模型、提示词、超时和并发参数。
  2. 适配级:把领域 API、数据格式和错误码接进框架。
  3. 策略级:实现路由、权限、重试、幂等和状态恢复。
  4. 评测级:建立真实任务集、失败分类、回放和回归门槛。
  5. 平台级:让多条业务线复用契约、观测、成本和发布能力。

配置级工作也可能重要,但不能把它包装成平台级能力。面试时先报自己的最高负责层,再用一项具体产物证明,例如“我负责策略级的工具网关,留下了权限决策日志和回放集”。

项目贡献从配置、适配到策略、评测和平台逐级累积

贡献要能被替换和复现

真正属于项目的能力,应该有清晰接口,能在不改业务语义的情况下替换底层框架。比如把 framework.invoke() 包在自己的 ToolGateway 之后:网关负责 schema 校验、租户鉴权、幂等键、超时和审计,底层框架只是一个执行器。

迁移时至少准备三类产物:

  • 契约:输入、输出、错误码和版本兼容规则;
  • 回放:脱敏后的真实 trace,可以重现路由和失败分支;
  • 对照:换框架前后的成功率、P95、成本和安全回归。

没有这些产物,所谓“可迁移贡献”只能停留在口头描述。

取舍记录要写反事实

决策记录不能只写“为什么选 A”,还要写“如果不选 A 会怎样”:

约束:写操作必须可审计、可重放
候选:框架默认 agent loop / 自建状态机 / 工作流引擎
反事实:默认 loop 无法稳定恢复中断的副作用步骤
决策:状态机包住框架调用,写操作落审计事件
代价:状态定义和迁移代码增加,开发周期 +1 周
证据:故障注入 30 次,恢复成功率 96%,重复写入 0 次

反事实让面试官看到你的判断边界,也方便未来的人接手。如果只有最终方案,没有被放弃的候选和失败证据,就无法区分深思熟虑和事后解释。

从事故和指标中证明归因

贡献的结果最好连到一条完整链路:事故或指标异常 → 假设 → 最小改动 → 实验/灰度 → 结果 → 回归用例。比如工具误写不是简单归因于“模型不稳定”,而是拆成 schema 放行、权限判断、幂等缺失和重试恢复四个环节,分别留下 owner 和验证数据。

这样讲的好处是,即使最终指标没有明显提升,也能说明排除了哪些原因、下一步还缺什么证据。工程贡献不只等于漂亮的成功数字,也包括把问题变得可定位、可复现、可交接。

一次迁移评审要看哪些证据

如果团队准备从一个 Agent 框架换到另一个框架,我会把评审拆成四张表,而不是只做一次演示:

评审表要确认的事实典型证据
行为兼容工具顺序、错误码、状态转移是否一致trace diff、状态机回放
质量兼容真实任务成功率和拒答边界是否一致分桶评测、失败样本
运行兼容延迟、并发、重试和成本是否可接受压测、P95、账单
安全兼容租户、审批、审计和幂等是否仍然生效越权回归、审计检索

先让新框架在 shadow 流量上只读运行,再逐步放开低风险任务。迁移完成的标准不是“页面能跑通”,而是旧框架的关键业务契约在新执行器中仍然成立。

把贡献写成可交接的最小包

一次项目交接至少应包含:接口契约、策略配置、版本说明、代表性 trace、失败回放、评测命令、仪表盘链接和未解决问题。每个产物标明 owner 与更新时间,别人才能判断结论是否还有效。

如果某个决定只存在于个人记忆里,它就不算稳定的团队能力。把“当时为什么不选另一个方案”写进决策记录,未来改框架或改模型时可以直接复用这段上下文。

用贡献账本区分“做过”与“留下了什么”

面试时很容易把参与过的工作都说成“我做的”。更稳妥的方式是做一张贡献账本,把框架默认行为和你的新增契约放在同一行:

问题框架默认我的新增契约证据迁移性
工具超时后重复写入自动重试调用幂等键 + 写前状态检查故障注入 30 次,重复写入 0 次可迁移到任意执行器
私有文档被检索通用向量召回服务端 ACL 过滤 + 审计事件越权回归 400 条,0 次放行依赖业务策略,不依赖框架
任务中断loop 结束即丢状态状态机 + 可恢复 checkpoint中断回放成功率 96%需要适配持久化层

这张账本不要求把每行都包装成创新。它的价值是让听众看到:哪些能力来自框架,哪些是你针对业务边界补上的约束,以及这些约束是否能被复现和迁移。

贡献账本把框架默认、项目契约、证据和迁移边界放在同一张表里

回答“换掉框架还剩什么”时,直接从账本挑一行讲完整,比背一串组件名更有说服力。

用迁移探针证明贡献不是框架偶然行为

要证明一项能力属于项目,不一定真的要立刻换框架。可以先做一个最小迁移探针:把底层执行器替换成一个只实现 invoke / stream / cancel 的假适配器,跑同一组脱敏回放,观察业务契约是否仍成立。

{
  "probe": "executor-swap-v2",
  "adapter": "fake-executor@0.3",
  "replay": "agent-traces-sanitized-2026-08",
  "contracts": {
    "tool_schema": "pass",
    "tenant_policy": "pass",
    "idempotency": "pass",
    "resume_after_cancel": "fail"
  },
  "boundary": "checkpoint adapter still coupled to old loop"
}

探针失败并不可怕,重要的是它指出了耦合边界。比如工具契约、权限和评测都通过,只有 checkpoint 恢复失败,就说明真正需要重构的是状态持久化接口,而不是把整个项目重新包装一遍。面试里给出这张边界记录,比笼统说“架构可迁移”更可信。

迁移探针替换底层执行器,逐项验证工具、权限、幂等和恢复契约

迁移之后还要做一次“贡献边界回执”

迁移探针通过,只能说明方案没有完全绑死在当前框架;还需要把哪些能力由项目负责、哪些仍由框架提供写成边界回执。否则面试时很容易把框架默认的 tracing、重试或 memory 误说成自己的设计。

contribution_boundary_receipt: cbr_20260820_41
framework_removed: [default_retry, builtin_memory]
project_invariants:
  - idempotent_write
  - tenant_acl
  - replayable_trace
  - eval_gate
probe_result:
  idempotent_write: pass
  tenant_acl: pass
  replayable_trace: pass
  eval_gate: pass
remaining_dependency: model_adapter
decision: contribution_isolated

这张回执把“我做了什么”落到可以拆走、替换和复现的契约上。若移除框架能力后某项不变量失败,就把它标成待补接口,而不是强行把结果算成成功;这样贡献边界既诚实,也能指导下一次迁移。

贡献边界卡:移除框架默认能力后,项目不变量逐项验收

L5:为什么迁移通过后还要写边界回执?

因为“能跑”不等于“归因清楚”。边界回执把框架默认行为、项目新增约束和剩余依赖分开,面试与交接时都能准确说明成果。

贡献包还要有一张发布清单

迁移探针能说明能力是否脱离框架成立,但交付给团队时还要说明“哪些可以复用、哪些仍依赖当前环境”。我会把贡献包整理成发布清单:

contribution_release: cr_20260820_06
capabilities:
  - name: tenant_acl
    owner: platform-auth
    portable: true
    proof: replay://acl-regression-v9
  - name: resumable_checkpoint
    owner: agent-runtime
    portable: partial
    dependency: postgres-checkpoint-v2
    proof: replay://resume-cases-v4
compatibility:
  old_framework: pass
  fake_executor: pass
  clean_workspace: pass
known_limits:
  - "stream cancel 仍依赖 adapter hook"
next_review: 2026-09-03

portable 让面试或交接时不再把“能跑”误说成“可迁移”;proof 指向可重跑的回放集,known_limits 把尚未抽象的耦合公开出来。发布清单和代码版本一起归档,未来框架升级时可以按能力逐项验证,而不是重新靠个人记忆盘点。

贡献发布清单把能力、可迁移性、证明和已知边界固定成可交接记录

L5:贡献发布清单和 README 有什么不同?

README 解释怎么使用,发布清单解释这项能力凭什么可信、能否迁移以及还缺什么。它应该链接回放和失败边界,而不是只写安装步骤。

L5:怎样区分“我设计的能力”和“框架碰巧提供的能力”?

先查版本与默认配置,再用迁移探针或关闭单项能力做反事实回放:去掉框架自动重试,业务幂等仍应成立;换掉 memory,任务状态仍应能恢复;关闭默认 ACL,项目策略仍应拒绝越权。能被独立验证、能留下输入输出契约的部分,才可以算作自己的工程贡献。

四个常见坑

把框架默认行为说成自己设计

如果是框架自动重试、自动截断或默认 memory,要说清版本和配置,并说明它是否满足业务边界。

只报最终提升,不报基线

“准确率提升 15%”没有基线、样本和口径就无法判断。至少说明旧方案、数据集、指标定义和主要失败类型。

把一次调参当成系统贡献

Prompt 调整可能有效,但要说明是否稳定、是否跨任务、是否增加成本,以及如何防回归。

遇到失败就说模型不行

失败可能来自权限、检索、工具协议、数据版本或评测器。能把责任拆开并提出下一步证据,才是 Agent 工程师的贡献。

L1 / L2 / L3 分层追问

L1: 你和框架相比做了什么?

我负责把业务约束落成工具契约、权限策略、检索路由、状态恢复和评测闭环;框架负责通用编排和模型适配。

L2: 如果换掉框架,哪些代码保留?

领域数据模型、策略网关、工具适配器、状态机、评测集和回放格式应保留,只有消息循环和部分连接器需要重写。

L3: 你怎么证明贡献有效?

给出基线、实验变量、真实任务分桶、成功与安全指标、成本和回归结果;同时说明没解决的边界,避免把框架默认能力算成自己的成绩。

L1: 配置和贡献的边界在哪里?

一次参数调整只能说明配置贡献;当你把业务约束落成接口、策略、状态或评测,并能被复现和迁移,才形成工程贡献。

L1: 你负责的最高层级是什么?

直接说是配置、适配、策略、评测还是平台级,并用代码、日志、评测集或发布记录作为证据,不用“全链路负责”替代事实。

L2: 换掉 LangChain 后哪些内容保留?

领域数据模型、工具契约、权限策略、状态机、评测集、回放格式和监控口径应该保留;消息循环和连接器适配可能需要重写。

L2: 如何避免把框架默认重试算成自己的能力?

核对框架版本和默认配置,抓一条真实 trace,标出每次重试、截断和状态转换的 owner;属于框架的就明确说明依赖。

L2: 没有明显指标提升,贡献还成立吗?

如果你缩小了故障范围、建立了回放和回归门槛,或者证明某个方案在安全边界外不可用,仍然是可验证的贡献,但要诚实说明结果没有提升的部分。

L3: 怎样设计最小迁移实验?

先固定业务契约和评测集,只替换编排层,比较成功率、工具选择、P95、成本和安全事件;出现回归就能定位是框架差异还是项目策略问题。

L3: 如何把个人贡献交接给团队?

交付接口契约、决策记录、故障回放、评测脚本、仪表盘和未解决问题清单,让别人能复现结论,而不是只留下口头经验。

L3: 贡献很多时怎样避免讲散?

只挑一条最重要的业务约束,按问题—决策—证据—取舍—结果串起来,其余贡献作为支撑证据,不把回答变成组件目录。

L1: 你如何区分适配工作和策略工作?

把领域 API 接入、字段转换和错误码映射归为适配;涉及路由、权限、重试、幂等、状态恢复等业务决策时,才是策略层。

L2: 迁移框架时先验证什么?

先验证工具契约和状态行为,再验证质量、运行和安全指标;从低风险 shadow 开始,避免一上来把写操作流量切过去。

L2: 一条回放 trace 需要保留什么?

保留脱敏后的输入摘要、模型和工具版本、路由决策、权限结果、状态转移、输出证据和最终结果;敏感原文按权限隔离,不为了回放扩大数据暴露面。

L3: 如果指标提升来自模型升级而非你的代码怎么办?

拆分实验变量,保留旧模型对照组,比较同一任务集上的增量;如果无法归因,就只认领自己能证明的契约、策略和评测改进,不把全部提升算在自己名下。

L4: 如果框架已经提供了类似能力,你的实现还算贡献吗?

先比较业务契约而不是类名。框架提供的是通用重试,你补的是写操作幂等、租户隔离和审计回放;框架提供 tracing,你补的是业务事件、失败归因和回归门槛。只要新增约束有明确接口、证据和迁移边界,就算工程贡献;如果只是换了一个参数或包装函数,就应诚实归为配置或适配。

用 ownership map 说清楚“换框架后谁负责”

迁移讨论最常见的误区,是把“这个模块能不能搬”当成唯一问题。真正影响交付的是责任边界:框架默认的循环、项目自定义的权限和幂等、平台提供的模型适配,分别由谁维护,出现回归时谁能修。为此,我会给每个关键能力标 owner、契约、替换点和验证方式:

ownership_map: om_20260820_18
capabilities:
  - name: message_loop
    owner: framework
    contract: invoke_stream_cancel
    replaceable: true
    proof: adapter-conformance-v3
  - name: tenant_acl
    owner: project
    contract: deny_before_retrieval
    replaceable: false
    proof: cross_tenant-regression-v9
  - name: checkpoint_resume
    owner: project
    contract: exactly_once_state_commit
    replaceable: partial
    proof: resume-replay-v4
  - name: model_adapter
    owner: platform
    contract: token_usage_and_timeout
    replaceable: true
    proof: provider-contract-v2
handoff:
  unresolved: [stream_cancel_hook]
  next_owner: agent-runtime

replaceable 不是一句架构口号,而是沿着契约跑过最小回放后的结果。比如 ACL 不能替换,说明它是项目的安全不变量;消息循环可以替换,说明框架只是编排实现。这样面试时问“你的核心工作是什么”,可以直接从 ownership map 选一项讲问题、决策和证据,不会陷入组件清单。

贡献 ownership map:把框架、项目和平台的责任边界固定下来

L5:如果一项能力由两方共同维护,owner 应该怎么写?

拆成接口 owner 和策略 owner。比如平台负责模型适配接口,项目负责超时、降级和业务指标;回归失败先定位契约层,再通知对应 owner,不能用“共同负责”掩盖没人接手。

贡献之后要维护“兼容性预算”,而不是只维护 API

把一个能力合并进框架,只是第一天的成功。真正容易被忽略的是:下一个版本、另一种运行时、一个更慢的网络,可能让原本隐含的兼容性假设逐渐失效。与其在 README 里写一句“支持多种后端”,不如把兼容性拆成可以持续回归的预算。

compatibility_budget:
  contract: cb_20260820_110
  runtimes: [local, worker, serverless]
  adapters: [openai_compatible, anthropic_like, mock]
  must_hold:
    - tool_call_schema_is_lossless
    - cancellation_is_observable
    - retry_keeps_idempotency_key
  tolerance:
    p95_latency_ms: 800
    max_payload_growth: 1.15
  evidence:
    - fixture: fixtures/tool-call-roundtrip.json
      run: ci/compatibility-matrix

框架贡献的兼容性预算:运行时、适配器、不变量和性能容差一起回归

L5:为什么兼容性也需要“预算”?

因为兼容性不是一个布尔值。接口能不能调用、取消是否可观测、错误能不能被上层识别,往往分别落在不同适配器里。预算把这些隐含条件变成矩阵;一旦某个后端让 payload 膨胀、把取消吞掉,贡献者能知道是哪个维度超标,而不是等用户报一个模糊的“升级后不好用了”。

60 秒面试回答

我会先把项目分成框架、项目和验证三层。框架提供消息循环、工具注册和模型适配;我负责的是业务数据契约、租户权限、检索与工具路由、幂等恢复和评测回放。讲每个贡献时都用问题—决策—证据—取舍—结果的结构,比如为什么从纯向量改成混合检索、指标提升多少、代价是什么。这样即使换掉框架,真正解决业务约束的部分仍然可迁移、可复盘。

交付前检查清单

  • 明确框架提供的能力和项目新增的约束
  • 每个关键决策都有候选、证据和取舍
  • 贡献能落到接口、策略、状态或评测产物
  • 指标有基线、分母、数据集和版本
  • 能说明换框架后的迁移边界
  • 失败案例有责任拆分和下一步验证

相关阅读

资料来源

  • AgentAlpha《Agent 岗面试宝典 v3》:项目贡献章节(内部讲义,未公开)
  • ARIS in AI Offer:系统设计题的决策、证据和分层回答结构