2026-10-12 AI Agent 面试训练
配置读取状态:成功。实际使用配置版本
version: 3(last_reviewed: 2026-10-12),未做任何修改。
历史读取范围:better/题目索引.md不存在,已按规则扫描2026-10/下的训练文件并完成索引重建;最近 30 天内仅 1 份训练文件(2026-10-10),全部纳入强去重比对。
去重结论:今日 4 题与 2026-10-10 的 8 题在一级类型、二级知识点、核心考点、LeetCode 题号上均无重合;无复习题。
今日主题:从”模型会说话”到”系统可控”——状态与记忆的存储边界、结构化输出的可靠性工程、协议能力协商的降级设计。
一、今日学习主题与题型分布
今天刻意补齐题库中尚未覆盖过的两个一级类型(数据库与存储、LLM 应用工程),并把题库配置 v3 新增的「MCP 官方扩展体系:能力协商、默认关闭与显式 opt-in、不支持时的降级回退」「MCP Tasks」「subscriptions/listen」落到真实场景中。三件事指向同一个能力:把概率性的模型输出,接到确定性的工程约束上。
| 编号 | 题型 | 一级类型 | 考察方向 | 题目 ID |
|---|---|---|---|---|
| B01 | 基础定义 | 数据库与存储 | 长期记忆与任务状态的存储分层、幂等写入、过滤召回陷阱、生命周期冲突 | Q-20261012-B01 |
| B02 | 基础定义 | LLM 应用工程 | Structured Output 与 Function/Tool Calling 的边界、校验、修复式重试与降级 | Q-20261012-B02 |
| S01 | 真实场景 | 工具与互操作协议 | MCP 扩展能力协商失败时的降级、双栈兼容与灰度回滚(含 Tasks 与 subscriptions/listen 迁移) | Q-20261012-S01 |
| L01 | LeetCode | 哈希表 + 滑动窗口 | 3. 无重复字符的最长子串(Medium) | Q-20261012-L01 |
二、今日题目(建议先独立作答)
B01|基础定义题|数据库与存储|Q-20261012-B01
一个多租户 Agent 产品要把「长期记忆」持久化。团队给了三个方案:
A. 所有记忆写进向量库,检索时按语义相似度取 topK;
B. Postgres 存结构化记忆条目(主体 / 谓词 / 客体 + 来源 + 时间戳 + 租户),同时在同库建向量索引做语义召回;
C. 在 B 前面加一层 Redis 缓存「热记忆」,写入先写缓存、再异步落库。请回答四个问题:
- 结构化存储与向量存储在这件事上的职责边界是什么?为什么”只用向量库”会失效,具体在哪些场景失效?
- 记忆的写入路径如何保证幂等与一致性?并发写入同一条事实时如何避免静默覆盖?
- 「缓存 + 异步落库」引入了哪些失败模式?
- 记忆的遗忘策略(TTL)与审计保留期冲突时怎么处理?
难度:中高。考察方向:事实来源 vs 派生索引、写入幂等、过滤召回(filtered ANN)陷阱、数据生命周期与合规。
B02|基础定义题|LLM 应用工程|Q-20261012-B02
生产 Agent 需要把模型输出交给下游代码消费。三个声音:
- 甲:“让模型输出 JSON,我们
json.loads,失败就重试。”- 乙:“用 Structured Outputs,传 JSON Schema。”
- 丙:“这不就是 Function Calling 吗?”
请回答:
- Structured Output 与 Function / Tool Calling 分别解决什么问题,边界在哪?
- 所谓的 JSON mode 与严格模式(strict)的结构化输出,差别是什么? 甲的方案差在哪?
- 在生产中如何设计校验、重试与降级,既能保证可靠,又不把成本和延迟打爆?
难度:中高。考察方向:约束解码 vs 事后解析、形状保证 vs 语义正确、重试预算与降级、schema 作为版本化接口。
S01|真实研发场景题|工具与互操作协议|Q-20261012-S01
背景:企业内部 Agent 平台的「统一工具网关」,接入 42 个 MCP 服务器(内部 27、第三方 15),服务 5 个业务线租户。日均工具调用 320 万次,P95 延迟 480ms。网关是 Go 服务,负责鉴权、按租户限流、审计与路由。
当前架构与数据流:客户端 → 网关(OAuth2 校验、租户限流、审计落库)→ MCP 服务器(Streamable HTTP,单请求单响应)。长耗时工具(代码库全量扫描、报表生成、浏览器自动化)只占调用量的 3%,却贡献了 68% 的 P99 延迟与超时重试;目前靠”客户端长轮询 + 网关把超时放宽到 15 分钟”硬扛。工具能力变更通知目前用 resources/subscribe 加一个自研 HTTP GET 端点推送,网关为它单独维护一套长连接,与主链路生命周期不一致。
目标:
- 长耗时工具改造为 MCP Tasks:持久句柄 + 轮询 + 中途请求输入 + 协作式取消。
- 通知机制迁移到官方
subscriptions/listen,替代resources/subscribe与自研 HTTP GET 端点。 - 内部控制台引入 MCP Apps(服务端返回交互式 UI)。
- 全程不降低现有成功率,回滚时间 < 5 分钟。
已知现象与风险:
- 一次预发灰度中,某服务器把扫描工具切成”仅 Tasks 模式”,旧客户端不认识该扩展方法直接报错,该工具成功率从 99.2% 掉到 41%;部分旧 SDK 收到未知方法后直接断开连接,触发客户端级重试风暴,网关 QPS 涨了 3 倍。
subscriptions/listen上线后,通知连接与主链路连接叠加,网关常驻内存上涨 40%,两台实例 OOM。- 一家第三方服务器在 capabilities 中声明支持某扩展,但实际实现不完整(返回 200 但缺字段)。
限制条件:不能强制所有业务线同天升级 SDK,旧客户端至少还要服务 6 个月;审计必须能归因到”哪个 Agent 代表哪个用户”,任何降级路径都不得绕过授权与审计;单租户故障不得影响其他租户。
请给出:能力协商与降级方案、双栈兼容与灰度回滚设计、失败路径与幂等、连接与容量规划、安全与成本分析、评测指标与上线观测。
难度:高。考察方向:能力协商分层、降级矩阵、长任务的句柄与取消语义、连接模型与租户隔离、兼容性与灰度工程。
L01|LeetCode|哈希表 + 滑动窗口|Q-20261012-L01
3. 无重复字符的最长子串(Longest Substring Without Repeating Characters,Medium)
给定一个字符串s,找出其中不含重复字符的最长子串的长度。
官方链接(已核验可访问):https://leetcode.cn/problems/longest-substring-without-repeating-characters/ | https://leetcode.com/problems/longest-substring-without-repeating-characters/
难度:Medium(力扣标注中等)。考察方向:滑动窗口 + 哈希表维护”上次出现位置”、窗口不变量与左边界单调性。
✋ 建议先独立作答(基础题每题 1-2 分钟口头作答,场景题 3-5 分钟,LeetCode 20 分钟手写),再往下看答案。
三、完整参考答案
B01 长期记忆与任务状态的存储分层
1. 考察点
- 事实来源与派生索引的分层:结构化条目是 source of truth,向量只是可重建的召回通道。
- 写入幂等与冲突处理:自然主键 + upsert + 版本号,避免 last-write-wins 静默覆盖。
- 过滤召回(filtered ANN)的语义陷阱:先按向量取 topK 再过滤,会导致召回不足。
- 缓存与异步落库的失败窗口:丢写、读到旧值、重复写、无法确认。
- 生命周期冲突:遗忘(TTL / 降权)与审计保留期是两条不同的时间轴。
- 多租户隔离:共享近似索引会让一个租户的向量影响另一个租户的召回与延迟。
2. 准确定义与适用边界
长期记忆:跨会话、跨任务需要复用的用户或领域事实,要求可更新、可撤销、可溯源、可审计。
任务状态:单次运行内的检查点与事件历史,要求强一致、可重放、随任务结束而归档。二者生命周期与一致性要求不同,不应混存在同一张表里。
**结构化存储(关系 / 文档)**能回答:这条事实是否为真、何时写入、来源是谁、是否已被撤销、属于哪个租户。它支持约束、事务、精确删除与审计。
向量存储 / 向量索引只能回答”语义上接近什么”,不保证真实、不保证完整、删除语义弱(索引残留、需要重建或 tombstone 过滤)。
边界一句话:向量索引只负责候选生成(candidate generation),权威判定、权限过滤、时效过滤必须发生在结构化层。
3. 简洁示例
CREATE TABLE memory_item ( tenant_id text NOT NULL, subject text NOT NULL, predicate text NOT NULL, object text NOT NULL, source_ref text NOT NULL, -- 来自哪次会话 / 哪个文档 confidence real NOT NULL DEFAULT 1.0, version bigint NOT NULL DEFAULT 1, valid_from timestamptz NOT NULL DEFAULT now(), deleted_at timestamptz, -- 软删除,tombstone embedding vector(1536), PRIMARY KEY (tenant_id, subject, predicate, object));
-- 幂等写入:同一事实只更新来源 / 置信度 / 版本,不产生重复条目INSERT INTO memory_item (tenant_id, subject, predicate, object, source_ref, confidence, embedding)VALUES ($1,$2,$3,$4,$5,$6,$7)ON CONFLICT (tenant_id, subject, predicate, object)DO UPDATE SET source_ref = EXCLUDED.source_ref, confidence = GREATEST(memory_item.confidence, EXCLUDED.confidence), version = memory_item.version + 1, deleted_at = NULL;
-- 检索:向量召回 + 结构化过滤(注意 filtered ANN 的召回陷阱,见第 6 节)SET LOCAL hnsw.ef_search = 100;SELECT * FROM memory_itemWHERE tenant_id = $1 AND deleted_at IS NULL AND confidence >= 0.7ORDER BY embedding <=> $2LIMIT 20;关键点:deleted_at 是 tombstone 而不是物理删除——物理删除会留下向量索引中的”幽灵条目”,让已遗忘的记忆仍被召回。
4. 与相近概念的区别
| 对比 | 区别 |
|---|---|
| 缓存 vs 索引 vs 事实来源 | 缓存可被击穿与丢失,索引可重建,事实来源不可丢;三者一致性要求完全不同 |
| 精确删除 vs 软删除 | 记忆的”遗忘”是语义状态变化,必须走 tombstone 并在召回层过滤,不能只删主表 |
| 语义相似 vs 事实正确 | 相似度 0.82 只说明向量接近,不说明这条记忆是真的、是最新的、是该租户的 |
| 相似度阈值 vs 相关性 | 阈值随 embedding 分布与模型版本漂移,不是全局可比量,不能当唯一过滤器 |
| 长期记忆 vs 任务状态 vs 会话历史 | 生命周期分别为月级 / 任务级 / 会话级,一致性要求递减,存储与索引策略不同 |
5. 在 AI Agent 系统中的典型应用
- 记忆写入是一个工具,不是一个
INSERT:模型决定”写什么”,系统决定”怎么写、写几次、冲突怎么办、来源记到哪”。写入工具必须带幂等键与source_ref,否则事后无法归因。 - 检索是三段式:向量召回 → 结构化过滤(租户、时效、撤销、置信度)→ 重排与截断。把三段压成”一次向量查询”是绝大多数线上检索质量问题的根因。
- 遗忘是可见性控制而非删除:TTL / 降权只决定”是否进入上下文”,审计证据独立保留在 append-only 的审计表里。
- 任务状态走另一条路:检查点与事件历史要求强一致与可重放,用关系型存储 + 版本号,不进向量库。
6. 常见误区或错误用法
- 把向量库当主存储:无事务、无约束、删除不可靠、无法回答”这条为什么在”。
- 用相似度阈值当唯一过滤条件:阈值随分布漂移,且无法表达”属于该租户 / 未被撤销”。
- last-write-wins 覆盖冲突记忆:事实被静默改写且不可追溯,是最难排查的一类线上问题。
- 跨租户共享近似索引:pgvector 官方 README 明确指出,共享 ANN 索引会让一个租户的向量影响其他租户的召回与速度,应通过分区或分表隔离。
- 忽略带过滤的近似检索陷阱:带
WHERE的 ANN 是”先扫索引再过滤”,过滤条件命中率低时召回严重不足;0.8.0 起可用迭代扫描(hnsw.iterative_scan)缓解,或用部分索引 / 分区。 - TTL 与审计保留混淆:要么删了记忆也删了审计证据,要么审计保留导致已”遗忘”的记忆仍被检索到。
- 异步落库无确认:进程重启丢记忆,而模型以为已写入,后续对话基于一个不存在的记忆继续。
7. 面试现场参考回答(1-2 分钟)
“我会把结构化存储当事实来源、向量当派生索引。长期记忆必须能回答’是否为真、何时写入、来源是谁、是否撤销、属于哪个租户’,这些只有关系型存储能保证;向量只解决’语义上找得到’,它不保证真实、不保证完整、删除语义也弱,所以它只能做候选生成,判定和过滤必须回到结构化层。
写入路径上我会用自然主键加 upsert 做幂等,比如(租户、主体、谓词、客体),冲突时更新来源和版本号而不是新增条目,避免同一事实存两份、也避免 last-write-wins 静默覆盖。删除走 tombstone,因为只删主表会留下向量索引里的幽灵条目。
检索我要拆成三段:向量召回、结构化过滤、重排。这里有个很容易踩的坑:带 WHERE 的近似检索是先取 topK 再过滤,过滤选择性高时召回会严重不足,需要用迭代扫描、部分索引或分区来解决。
缓存加异步落库我会非常谨慎,它引入了丢写、读到旧值、重复写三类失败窗口。我的原则是记忆写入必须同步确认,缓存只服务读路径。
最后是生命周期:遗忘和审计保留是两条时间轴。TTL 或降权只决定这条记忆是否进入上下文,审计证据独立 append-only 保留,互不干扰。多租户要用分区或分表,避免共享索引导致跨租户影响。”
8. 面试官追问及回答要点
追问:加上向量索引之后,检索质量反而变差了,你怎么排查?
回答要点(分层归因):
- 是否踩了 filtered ANN 陷阱:确认是先召回后过滤,还是先过滤后召回;用”过滤条件命中率 × ef_search”估算有效候选数。
- 索引参数与数据规模:IVFFlat 的
lists是否随数据量调整、是否建索引时表内还没有数据;hnsw.ef_search默认 40 是否过低;ivfflat.probes默认 1 基本等于低召回。 - 距离函数与归一化:opclass 与查询用的距离是否一致;向量是否已归一化(归一化后用内积最快)。
- embedding 与文本不同步:更新了文本没重算向量,或换了 embedding 模型没重建索引——这是最高频的真实原因。
- tombstone 未过滤:已删除记忆仍在索引里被召回。
- 验证方法:固定一批 query 建回归集,对比”加索引前精确检索”与”加索引后近似检索”的召回重合度(recall@k),先量化再调参。
B02 Structured Output 与 Function / Tool Calling 的边界
1. 考察点
- 机制差异:严格模式通过约束采样保证输出完全符合 schema,非严格只是尽力而为。
- 职责边界:结构化输出管”最终答案的形态”,工具调用管”触发外部副作用的控制流”。
- JSON mode 的真实保证级别:只保证能解析成 JSON,不保证匹配任何 schema。
- 可靠性工程分层:约束 → 校验 → 修复式重试 → 降级与人工兜底。
- 失败模式:截断、枚举外值、类型不符、多余字段、可选字段缺失、转义与编码。
- 工程影响:schema 复杂度与 token 成本、schema 变更即接口变更、重试预算与熔断。
2. 准确定义与适用边界
Structured Output(结构化输出):为模型输出提供一个 JSON Schema,让输出形态可被机器直接消费。严格模式(strict)下通过约束采样保证输出完全符合 schema;非严格模式只是尽力而为,仍需自行校验。
Function / Tool Calling:模型不是”输出一段文本”,而是输出一个调用决策——选择哪个工具、传什么参数;执行权在宿主程序,结果通过 call_id 之类的标识回关联到上下文。它改变的是控制流,并且会触发外部副作用。
适用边界:
- 结构化输出适用于:信息抽取、分类与路由、评测打分、planner 的步骤列表、把非结构化输入转成对象。
- 不适用于:需要模型自由表达的任务;以及业务规则的校验——schema 保证的是”形状”,跨字段约束(如”结束日期必须晚于开始日期”)应交给代码,不要硬塞进 schema。
关键边界一句话:schema 保证形状,不保证语义正确,也不保证依据真实。
3. 简洁示例
schema = { "type": "object", "properties": { "risk_level": {"type": "string", "enum": ["low", "medium", "high"]}, "clauses": { "type": "array", "items": { "type": "object", "properties": { "id": {"type": "string"}, "text": {"type": "string"}, "span": {"type": "array", "items": {"type": "integer"}}, }, "required": ["id", "text", "span"], "additionalProperties": False, }, }, "needs_human": {"type": "boolean"}, }, "required": ["risk_level", "clauses", "needs_human"], "additionalProperties": False,}
async def extract_contract(text: str) -> dict: raw = await llm(structured_schema=schema, strict=True, user=text) # 第 1 层:约束 try: obj = validator.validate(raw) # 第 2 层:形状校验 assert_business_rules(obj) # 第 2 层:业务规则 return obj except ValidationError as e: retry = await llm( # 第 3 层:修复式重试 structured_schema=schema, strict=True, messages=[{"role": "user", "content": text}, {"role": "assistant", "content": raw}, {"role": "user", "content": f"校验失败:{e}。请修正后重新输出。"}], ) try: obj = validator.validate(retry) assert_business_rules(obj) return obj except ValidationError: return {"_degraded": True, "reason": "schema_retry_exhausted"} # 第 4 层:降级四层缺一不可:约束降低失败率,校验是唯一可信的判定,重试必须带上一次的错误信息,降级保证系统不会因为一次解析失败而卡死。
4. 与相近概念的区别
| 对比 | 区别 |
|---|---|
| JSON mode vs 严格模式结构化输出 | JSON mode 只保证”能解析成 JSON”,官方明确说明它不保证匹配任何特定 schema |
| 结构化输出 vs Function Calling | 前者是最终答案的形态;后者是控制流与外部副作用,参数即调用契约,结果用 call_id 关联 |
| schema 校验 vs 业务规则校验 | 前者验形状,后者验语义;二者都要,且业务规则不要塞进 schema |
| 约束解码 vs 事后解析 | 前者在采样时排除非法 token(保证形状),后者在生成后修补(只能兜底) |
| 可选字段 vs nullable 字段 | strict 模式下建议把所有字段标为 required 并用 nullable 表达”可能没有”,下游才不会 KeyError |
5. 在 AI Agent 系统中的典型应用
- 工具参数 schema 是安全边界的一部分:它是”入口契约”,但服务端必须独立再校验一次——模型输出不可信,schema 也不能替代授权检查。
- 结构化输出用于中间决策:路由(交给哪个子 Agent)、是否继续检索、是否需要人工、评测打分,这些都是”决策对象”,用结构化输出比解析自然语言稳健得多。
- schema 是版本化接口:与 prompt 版本、模型版本一起记录到 trace 上。线上质量问题归因时,“schema 改了”和”模型换了”是两类完全不同的根因,必须能分开看。
- 与重试预算耦合:Agent 是多步的,单步重试预算失控会在多步链路上被放大,必须在编排层设全局重试预算与熔断。
6. 常见误区或错误用法
- 以为 JSON mode 就等于 schema 保证:官方明确说明 JSON mode 不保证输出匹配任何 schema,只保证可解析。
- 重试无上限:一次 3 分钱的调用,在 20 步 Agent 链路上指数放大,成本与延迟同时爆炸。正确做法是设重试预算(通常 1 次修复式重试)后降级。
- 重试时不带上一次的校验错误:只说”请重新输出”,模型大概率重复同样的错误。
- 把跨字段业务规则塞进 JSON Schema:表达力有限且失败信息难定位,应交由代码校验。
- 忽略截断:
finish_reason == "length"导致的截断被当成”解析失败”处理,重试后照样截断,正确做法是提高max_tokens或拆分抽取任务。 - schema 过宽:大量可选字段导致下游拿到
None或缺失键;应显式标注 nullable 并全部 required。 - 把 schema 当输入校验的全部:模型可能输出符合 schema 但语义荒谬的值(如
risk_level="high"但理由为空),schema 不会拦住它。
7. 面试现场参考回答(1-2 分钟)
“这是三件不同的事。Structured Output 解决的是’最终答案的形态可靠’,严格模式下通过约束采样保证输出完全符合 schema。Function Calling 解决的是’控制流与外部副作用’——模型输出的是调用哪个工具、传什么参数,执行权在宿主程序,结果用 call_id 关联回上下文。前者管输出,后者管动作。
甲的方案差在:JSON mode 只保证能解析成 JSON,官方明确说它不保证匹配任何特定 schema,所以’输出 JSON 再自己解析’必须再配一层校验和重试,本质上是用更多工程成本去补一个已经存在的官方能力。
生产上我会做四层。第一层用 strict schema 约束;第二层用校验器做形状校验加业务规则校验,业务规则不要塞进 schema,跨字段约束交给代码;第三层是修复式重试,把上一次的原始输出和校验错误一起回传给模型,且只重试一次;第四层是降级,标记为低置信度并进人工队列,而不是让整条链路卡死。
成本上我要设全局重试预算,因为 Agent 是多步的,单步失控会在链路上被放大。另外 schema 是版本化接口,我会把 schema 版本、prompt 版本、模型版本一起打到 trace 上,出问题才能分开归因。最后提醒一点:schema 只保证形状,不保证语义正确,也不保证依据真实,语义校验和授权检查仍然必须存在。”
8. 面试官追问及回答要点
追问:同一个 schema,换新模型后失败率从 0.3% 涨到 4%,你怎么排查?
回答要点:
- 先分类,不要先看总数:按失败类型分布拆——截断、枚举外值、类型不符、多余字段、必填缺失。不同类型的根因完全不同。
- 分层归因:是 schema 侧(嵌套过深、枚举过多、字段过多),还是请求侧(
max_tokens太小、温度过高、prompt 变更),还是模型侧(新模型对 strict 的支持差异、约束采样实现差异)。 - 对照实验:固定输入的回归集,在”旧模型 / 新模型 × 旧 prompt / 新 prompt × 旧 schema / 新 schema”上做对照,一次只变一个变量。
- 工程处置:提高
max_tokens、拆分大 schema 为多次小抽取、收紧枚举、把嵌套层级压平、必要时对该模型关闭 strict 并加强校验与降级。 - 上线把关:把 schema 兼容性纳入模型升级的准入测试,禁止”换模型不跑结构化输出回归集”。
- 观测:按 (schema 版本, 模型版本, 失败类型) 三维看板,异常升高自动告警。
S01 场景题:MCP 扩展能力协商失败时的降级与向后兼容
1. 背景、目标、约束与已知现象(回顾)
见题目部分。核心事实:42 个 MCP 服务器、5 个租户、日均 320 万次调用;长耗时工具占 3% 却占 68% 的 P99 与重试;客户端版本碎片化,约 35% 调用来自不识别新扩展的旧客户端;曾因”仅 Tasks 模式”导致单工具成功率从 99.2% 掉到 41% 并触发重试风暴;subscriptions/listen 上线造成网关内存 +40% 与 OOM;存在第三方”声明支持但实现不完整”的情况。
2. 核心考点
- 能力协商的分层与”默认关闭、显式 opt-in”原则:谁声明、谁判定、谁适配。
- 降级矩阵设计:每个新能力都必须有等价的基础路径与明确的失败语义。
- 长任务的句柄语义:轮询节奏、总预算、中途输入、协作式取消、孤儿任务回收。
- 连接模型与容量:订阅连接与请求连接分离、每租户上限、背压与隔离。
- 兼容性与灰度工程:双栈并行、三维灰度(租户 / 工具 / 客户端版本)、自动回滚阈值、契约测试与故障注入。
3. 作答框架(3-5 分钟可复用)
- 先给结论:不要在服务端假设客户端支持。新能力一律”默认关闭 + 显式 opt-in + 有基础路径”,先并行后切换,任何一步的回滚开关都在网关。
- 拆三层:能力声明层(capabilities 与扩展协商)→ 流量治理层(网关按客户端能力画像路由与改写)→ 兼容层(双栈 + 影子对比)。
- 定矩阵:对每个新能力写出”支持 / 不支持”两条路径的成功标准、延迟上限与失败语义。
- 定灰度:租户 → 工具白名单 → 客户端版本 → 流量百分比,每级有自动回滚阈值。
- 定观测:按 (租户, 工具, 客户端版本, 能力) 四维看成功率、延迟、降级率、取消率、审计完整率。
- 定兜底:超时与重试预算、取消语义、审计不因降级而缺失、权限在句柄创建时快照。
4. 参考回答(结论先行)
结论:这次改造的失败不是”Tasks 不好”,而是把新能力当成了默认路径。我的方案是三步:把能力协商收敛到网关、给每个新能力配一条等价的降级路径、用双栈三维灰度加自动回滚来切换。
第一,能力协商不做在服务端单点。 服务端声明 capabilities 与扩展,但真正的适配放在网关:网关维护”客户端能力画像”(SDK 版本映射 + 一次性实测探测 + 运行时错误码统计动态下调),按画像决定路由与响应改写。服务端侧的原则是官方明确要求的:扩展默认关闭、客户端显式 opt-in;客户端不支持时,服务端必须回退到基础路径而不是报错。客户端侧的原则是:收到未知方法应视为”能力不可用”并走降级,绝不能断连,断连加重试风暴正是上次 41% 成功率事故的直接原因。
第二,每个新能力都写降级矩阵。 Tasks 不可用 → 回退到同步调用,或由网关把长调用包成”伪同步 + 句柄代理”,对旧客户端保持既有约定;Apps 不可用 → 回退成结构化文本,控制台渲染降级卡片;
subscriptions/listen不可用 → 旧订阅端点并行双写,用订阅 ID 做去重,并给出明确的弃用时间与 sunset 头。对第三方”声明支持但实现不完整”,网关做能力实测,失败即剔除该能力并降级。第三,长任务的可靠性靠句柄而不是靠连接。 任务状态在服务端持久化,客户端只持有句柄;轮询带退避与抖动和总预算;取消是协作式而非强制,所以所有副作用工具必须自带幂等键与补偿路径;中途
input_required必须有超时与默认动作,否则任务会永久挂起占资源。第四,容量与安全并重。 订阅连接从主链路连接池中拆出来,独立进程或独立池 + 每租户上限 + 背压与补拉机制,避免 OOM 重演。授权与审计中间件是唯一入口,降级路径也要过;句柄绑定租户与主体,跨租户访问直接拒绝并告警;Tasks 让任务在后台继续跑,所以权限必须在句柄创建时快照。
最后,回滚开关是网关配置,秒级生效,配合 1-2 分钟的观测发现时间,可以满足 5 分钟回滚目标。
5. 问题拆解、核心方案与关键执行流程
问题拆解:一次升级同时引入三类不兼容——协议方法不兼容(旧客户端不认识 Tasks)、连接模型不兼容(订阅连接叠加)、实现质量不兼容(第三方声明造假)。三类要分别处理,不能用同一个开关。
核心方案:
- 能力协商三层:服务端声明(capabilities + extensions,默认关闭)→ 网关适配(客户端能力画像 + 路由与改写 + 能力实测)→ 客户端降级(未知方法走降级,不断连、有熔断)。
- 双栈并行:新旧路径同时在线,新路径先只在影子流量上生效,对比结果一致率达标后才切正式流量。
- 订阅机制迁移:
subscriptions/listen与旧端点并行双写,用订阅 ID 去重;旧端点标注弃用时间与 sunset 头;两者生命周期统一到同一个订阅服务。
关键执行流程(Tasks):
- 客户端
tools/call请求长耗时工具 → 服务端返回持久句柄(task id)而非结果。 - 服务端状态机:
working→input_required/completed/failed/cancelled。 - 客户端按服务端在
working中给出的建议间隔轮询(带退避与抖动)。 input_required→ 走人工 / 上游输入通道,同时启动输入超时计时。- 取消为协作式:客户端发取消请求,服务端决定是否可停,取消后句柄仍可读到最终状态。
- 超时入库为”孤儿任务”队列,服务端 TTL 回收并告警。
6. 技术选型、依据与备选
| 选型 | 结论 | 依据 | 备选与代价 |
|---|---|---|---|
| 能力适配放网关 vs 放服务端 | 放网关 | 集中、可灰度、可秒级回滚、对 42 个服务器零改造 | 服务端按客户端版本分支:42 个服务各自实现,不可控、不可回滚 |
| 长任务:轮询句柄 vs 长连接挂起 | 轮询句柄 | 协议原生、释放主链路连接、穿透网关简单、客户端重启可续 | 长连接挂起:正是当前 P99 与连接压力的来源 |
通知:subscriptions/listen vs webhooks/channels | subscriptions/listen | 已随 2026-07-28 规范落地,是服务端发起事件的第一种正式形态 | webhooks / channels 仍为官方路线图优先项,无规范文本,不作为方案 |
| 订阅连接位置 | 拆出独立池(中期下沉为独立通知服务) | OOM 的直接原因是订阅连接与请求连接争同一资源 | 混池:无隔离,单租户订阅风暴会打爆全局 |
| 第三方能力可信度 | 网关能力实测 + 契约测试 | 已出现”声明支持但实现不完整” | 只信声明:故障在运行时才暴露,且难定位 |
7. 失败路径、边界条件、超时、重试、幂等与恢复
- 轮询超时与预算:退避 1s → 2s → 4s … 上限 30s 并加抖动;单次任务总预算(如 15 分钟),超预算转”孤儿任务”队列,服务端 TTL 回收并告警,而不是让客户端无限轮询。
- 句柄丢失与幂等:句柄是服务端持久状态;客户端凭 task id 重新查询,查询是 GET 语义、天然幂等,重复查询绝不产生副作用。副作用发生在”创建任务”和”执行工具”上,这两处必须带幂等键。
- 取消的边界:协作式取消可能失败(副作用已提交)。因此取消结果必须有明确终态(已完成 / 已取消 / 取消失败待人工),不允许”未定义”;UI 必须如实展示。
input_required的超时:等待人工输入也必须有超时与默认动作(默认取消或按策略取默认值),否则任务永久挂起并占用配额。- 服务端重启:任务状态持久化在服务端,重启后凭句柄恢复;客户端只依赖句柄、不依赖连接,这是选轮询而非长连接的关键收益。
- 重试风暴:客户端对未知方法 / 未知错误的重试必须有上限与熔断(上次事故根因之一);网关侧按 (租户, 客户端版本) 限流。
- 超时对齐:客户端超时 < 网关超时 < 服务端超时,逐层留余量,避免”客户端放弃但服务端还在跑”造成的孤儿任务。
- 订阅事件丢失:背压下允许丢弃增量事件,但必须提供”补拉”(按订阅 ID 重新拉取全量或按版本号补齐),不能静默丢。
8. 安全、权限、成本、延迟与可靠性分析
安全与权限
- 所有路径(含降级路径与轮询)走同一个授权与审计中间件;审计字段必须包含”哪个 Agent 代表哪个用户”,降级不得造成归因缺口。
- 句柄绑定租户与主体;跨租户访问句柄直接拒绝并告警。
- 权限快照:Tasks 让任务在后台长期运行,权限必须在句柄创建时快照,长时间运行后权限变化时要么重新鉴权、要么终止,防止”审批后权限提升”。
- Apps 沙箱:交互式 UI 是服务端返回的内容,必须沙箱隔离(独立源 iframe + CSP),不得继承控制台会话权限;Apps 不可用时的降级卡片同样不得渲染未净化内容。
成本
- 轮询是新增成本项。粗算:3% 长任务 × 平均 8 分钟 × 每 5 秒轮询 ≈ 每次任务 96 次轮询请求,需要用”服务端建议间隔 + 自适应间隔 + 每租户轮询限额”来控制。
- 双栈期(约 6 个月)两套订阅并存,连接成本约翻倍,需要单独容量规划,并在旧客户端比例降到阈值以下后下线旧端点。
延迟
- 主链路从”长连接挂起”变为”句柄 + 轮询”,连接被释放,网关内存与 P99 连接压力下降。
- 但要区分两个指标:任务完成延迟(服务端侧)与用户感知延迟(取决于轮询间隔与通知到达)。只盯其中一个会误判。
可靠性
- 订阅连接独立池 + 每租户上限 + 背压 + 补拉,单租户订阅故障不影响其他租户。
- 服务端 capabilities 变化时触发客户端能力画像重新探测,避免”升级后画像过期”。
9. 评测指标、测试方法与上线观测
指标(按 租户 × 工具 × 客户端版本 × 能力 四维拆分)
| 类别 | 指标 |
|---|---|
| 可用性 | 成功率、按错误码分布(MethodNotFound / 超时 / 5xx)、降级率 |
| 性能 | P50 / P95 / P99 延迟、任务完成延迟 vs 用户感知延迟 |
| 长任务 | 取消率、取消失败率、孤儿任务率、轮询请求数 / 任务、input_required 等待时长 |
| 协商 | 能力协商失败率、能力画像准确率(声明 vs 实测差异数) |
| 安全 | 审计完整率(是否存在归因缺口)、跨租户拒绝次数 |
| 成本 | 每任务 token 与调用成本、轮询 QPS 占总量比 |
测试方法
- 契约测试:capabilities 声明 vs 实际行为,必须包含”声明支持但实现不完整”的负例(返回 200 缺字段)。
- 兼容性矩阵测试:客户端版本 × 服务端版本 × 能力开关的全组合冒烟,进 CI。
- 故障注入:服务端返回 MethodNotFound、断连、超时、声明造假、轮询端点随机 5xx 与延迟注入。
- 混沌:网关重启、状态存储抖动、订阅连接被强制断开后的补拉。
- 影子对比:新旧路径结果一致率,作为切流的前置门槛。
上线观测
- 金丝雀看板 + 自动回滚阈值:成功率下降 > 0.5pp,或降级率 > 20%,或 P95 恶化 > 20% → 自动回滚。
- 灰度顺序:影子 → 单租户内部工具 → 工具白名单 → 按客户端版本 → 全量;每级停留至少一个完整业务周期。
- 升级 / 回滚事件全部打点,保留 30 天对照数据。
10. 三个渐进追问及回答要点
追问 1:如果只能拿到客户端 SDK 版本,拿不到真实能力,怎么办?
- 版本字符串不可靠:网关、代理、自研 SDK 都会伪装或滞后。
- 能力画像 = 版本映射(先验)+ 一次性实测探测(canary 调用,结果缓存并设 TTL)+ 运行时观察(错误码统计自动下调能力)。
- 探测本身要有成本上限与失败兜底:探测失败按”不支持”处理,是最保守且正确的默认。
追问 2:第三方服务器声明支持但实现不完整,契约怎么定?
- 网关侧强制”声明 + 实测 + 结果结构校验”三重校验;实测失败即把该能力从该服务器能力集剔除并降级。
- 引入准入测试与 SLA,未经准入的第三方能力默认不进生产目录。
- 审计里记录”声明 vs 实测”差异,作为供应商考核依据;不要让运行时故障成为唯一的发现手段。
追问 3:长任务被取消了但副作用已经发生,怎么向用户交代?
- 先厘清语义:取消是协作式,不是强制终止,服务端可能已经提交副作用。
- 因此所有副作用工具必须幂等键 + 补偿路径,可靠性不能依赖取消。
- 取消结果落到明确终态,审计记录”取消请求时间 / 生效时间 / 已发生副作用”。
- 产品侧如实展示”取消失败,请联系审批人”,并提供补偿入口;不要用”已取消”掩盖已发生的副作用。
11. 常见误区(4 个)
- 把新能力做成”默认开启 + 不支持就报错”。 正确做法是默认关闭、显式 opt-in、且必须提供基础路径——这是官方扩展体系明确的原则,也是上次事故的直接教训。
- 客户端收到未知方法就断连并无限重试。 未知方法应被解释为”能力不可用”并走降级;重试必须有上限与熔断,否则单点不兼容会放大成网关级风暴。
- 把能力协商只放在服务端,假设客户端一定会升级。 服务端、网关、客户端三方都要有兜底,且降级路径要以最弱的客户端为基线来设计。
- 以为 Tasks 的取消是强制的。 它是协作式取消,副作用可能已发生,可靠性必须靠幂等与补偿,而不是靠取消请求本身。
12. 30-60 分钟小型实践
搭一个最小实验,把”能力 × 客户端”矩阵跑出来:
- 起一个本地服务端,暴露两个工具:
sync_echo(同步)与long_scan(长耗时)。 long_scan有两种模式:Tasks 开(返回句柄 + 轮询端点)与 Tasks 关(同步返回,超过 3 秒返回”请稍后重试”)。- 写三档模拟客户端:支持 Tasks / 不支持 Tasks / 声明支持但轮询返回缺字段(模拟第三方造假)。
- 跑 100 次调用,统计成功率、降级率、轮询 QPS,产出”服务端开关 × 客户端能力”的结果矩阵。
- 故障注入:轮询端点加 500ms 延迟并随机返回 5xx,验证客户端退避与总预算不会打爆服务端。
- 记录一个关键结论:不支持路径的成功率,才是这次改造的真实基线。
13. 三层能力划分(本题核心,必须说清)
| 层 | 性质 | 负责什么 | 不负责什么 |
|---|---|---|---|
| 模型能力 | 概率性 | 判断何时调用长工具;为 input_required 组织补充信息;决定是否请求取消 | 不负责协议合规、不负责幂等、不负责判断是否重试 |
| Agent 编排层 | 状态机 | 持有句柄、轮询节奏、总预算、降级决策树、取消与人工输入通道、审计关联 | 不负责授权判定、不负责连接隔离 |
| 确定性系统 | 确定性 | 协议方法名与状态机、授权与限流、句柄持久化与 TTL 回收、幂等键与补偿、连接池与租户隔离、回滚开关 | 不负责语义判断 |
关键提醒:不得假设模型永远正确(它会在 input_required 时给出垃圾输入)、工具永远成功(长扫描会失败)、外部服务永远可用(第三方服务器会造假)、输入永远可信(跨租户句柄访问必须拒绝)。
L01 LeetCode 3:无重复字符的最长子串
1. 基本信息
| 项 | 内容 |
|---|---|
| 题目 ID | Q-20261012-L01 |
| 题号 | 3 |
| 中文名 | 无重复字符的最长子串 |
| 英文名 | Longest Substring Without Repeating Characters |
| 难度 | Medium(力扣标注:中等) |
| 官方链接 | https://leetcode.cn/problems/longest-substring-without-repeating-characters/ | https://leetcode.com/problems/longest-substring-without-repeating-characters/ |
| 链接核验状态 | 已核验:两处链接均可访问并返回官方题目页,题号与中英文标题一致;难度 Medium 依据官方题目标注 |
2. 题目描述
给定字符串 s,找出其中不含重复字符的最长子串的长度。注意是子串(连续),不是子序列。
3. 输入、输出、约束与示例
输入:字符串 s
输出:整数,最长无重复字符子串的长度
约束:
0 <= s.length <= 10^5s由英文字母、数字、符号和空格组成
示例:
| 输入 | 输出 | 说明 |
|---|---|---|
"abcabcbb" | 3 | 答案是 "abc","bca"、"cab" 同样合法 |
"bbbbb" | 1 | 答案是 "b" |
"pwwkew" | 3 | 答案是 "wke";注意 "pwke" 是子序列不是子串 |
4. 主要考察的数据结构或算法模式
滑动窗口 + 哈希表维护”上次出现位置”。核心不变量:窗口 [left, right] 内始终无重复字符;右指针单调右移,左指针也单调右移(只跳不回退)。这是”双指针 / 滑动窗口”这一族算法的标准骨架。
5. 渐进式提示(不直接给答案)
- 先想暴力的代价:枚举所有子串并检查是否含重复字符,是 O(n²) 个子串 × O(n) 检查 = O(n³)。怎么把”检查是否有重复”降到 O(1)?
- 窗口什么时候必须收缩:当新字符
s[right]已经在当前窗口里出现过,左边界必须跳到”该字符上次出现位置 + 1”。为什么是max(left, last[ch] + 1)而不是直接last[ch] + 1? - 只存一个位置够吗:对每个字符只需要记录”最近一次出现的下标”,因为左边界只增不减——这个单调性是整个算法正确且 O(n) 的关键。
6. 直观方案及其局限
暴力法:枚举所有起点 i,从 i 开始向右扩展直到遇到重复字符,记录最大长度。
def brute(s: str) -> int: ans = 0 for i in range(len(s)): seen = set() for j in range(i, len(s)): if s[j] in seen: break seen.add(s[j]) ans = max(ans, j - i + (s[j] not in seen)) # 边界易错 return ans局限:时间复杂度 O(n²),n = 10^5 时必然超时;而且上面的边界处理极易写错(这正是它不该被采用的原因之一)。本质是大量重复计算:从 i 扩展到 j 停下的信息,在 i+1 时被完全丢弃重算。
7. 推荐方案的推导过程
- 观察:如果
s[i..j]无重复,那么对任意i < k <= j,s[k..j]也必然无重复。这说明窗口有单调性,无需回退。 - 因此维护窗口
[left, right],right每次右移一格。 - 关键问题:加入
s[right]后,若它与窗口内某字符重复,窗口该收缩到哪?答案是”重复字符的上一次出现位置之后”。 - 只需要一个哈希表
last[ch] = ch 最近一次出现的下标;由于left单调递增,若last[ch] < left,说明那个重复发生在窗口外,不能用它来收缩左边界——这就是max(left, last[ch] + 1)的由来,也是本题最常见的错误点。 - 每次右移后用
right - left + 1更新答案。
8. 正确性说明(不变量法)
不变量:第 right 轮迭代结束后,[left, right] 内的字符两两不同,且 left 是所有满足该条件的最大合法左边界(即以 right 结尾的无重复子串中,我们取的是最长的那个)。
- 初始:空窗口,
left = 0,不变量成立。 - 保持:加入
s[right]。若last[s[right]]存在且>= left,说明该字符在当前窗口内重复,任何< last[s[right]] + 1的左边界都会让窗口含重复,故left必须至少为last[s[right]] + 1;取该值后窗口恢复无重复,且是满足条件的最小合法左边界,即对应最长的合法子串。若last[s[right]] < left或不存在,窗口本就无重复,left不变。两种情况都保持不变量。 - 终止:遍历完所有
right,ans记录了每个right结尾的最长合法子串长度的最大值,即全局最优。
9. 时间复杂度与空间复杂度
- 时间:O(n)。
right与left各最多右移 n 次,每次操作 O(1)。 - 空间:O(min(n, m)),其中 m 是字符集大小(ASCII 场景可视为 O(1),Unicode 场景最多 O(n))。
10. Python 参考代码
class Solution: def lengthOfLongestSubstring(self, s: str) -> int: last: dict[str, int] = {} # 字符 -> 最近一次出现的下标 left = 0 ans = 0
for right, ch in enumerate(s): # 只有当重复发生在「当前窗口内」时才移动左边界 if ch in last and last[ch] >= left: left = last[ch] + 1 last[ch] = right # 更新为最近一次出现的位置 ans = max(ans, right - left + 1) # 窗口恒为合法无重复区间
return ans
if __name__ == "__main__": sol = Solution() cases = [ ("abcabcbb", 3), ("bbbbb", 1), ("pwwkew", 3), ("", 0), ("au", 2), ("dvdf", 3), ("abba", 2), (" ", 1), ] for s, expected in cases: got = sol.lengthOfLongestSubstring(s) print(f"{s!r:12} -> {got:2} (expected {expected:2}) {'OK' if got == expected else 'FAIL'}")11. 关键边界情况
- 空串:
s == ""→ 返回 0,循环不执行,ans初值为 0,正确。 - 重复字符在窗口左侧之外:如
"abba",第二次遇到'a'时last['a'] = 0 < left = 2,不能把left拉回 1。漏掉last[ch] >= left这个判断会得到错误答案 3。 - 全相同字符:
"bbbbb"→ 每次都收缩,答案为 1。 - 整个串无重复:
"au"→ 答案为 2,left全程不动。 - 空格与符号:约束明确包含空格与符号,Python 的
str按 Unicode 码位迭代,无需特殊处理;但若按字节处理或用固定 128 长度数组,就要小心非 ASCII。 - 长度 1e5:必须 O(n),且不要在循环里做
s[left:right]切片——切片是 O(k),会把整体复杂度打回 O(n²)。
12. 测试用例(5 个)
| # | 输入 | 期望 | 覆盖点 |
|---|---|---|---|
| 1 | "abcabcbb" | 3 | 基本用例,重复在窗口内 |
| 2 | "bbbbb" | 1 | 全重复 |
| 3 | "pwwkew" | 3 | 子串 vs 子序列,答案为 "wke" 而非 "pwke" |
| 4 | "abba" | 2 | 窗口外重复陷阱,验证 last[ch] >= left 判断 |
| 5 | "" | 0 | 空输入边界 |
补充:"dvdf" → 3(验证连续多次收缩);" " → 1(空格也算一个字符)。
13. 面试官可能提出的变体或追问
变体:把”不允许重复”放宽为”至多允许 k 个重复字符(或至多 k 种字符出现超过一次)“,返回最长子串长度。
回答要点:
- 窗口合法条件从”每个字符计数 ≤ 1”变成”违反次数 ≤ k”,需要维护计数器统计”当前有多少字符超配额”。
- 右移时更新计数并判断是否需要收缩;左移时同样更新计数,直到窗口重新合法。
- 仍然 O(n),因为左右指针都不回退。
- 面试加分点:指出这类问题的通用骨架是”窗口合法性谓词 + 单调左指针”,只要合法性随窗口缩小是单调恢复的(即缩小窗口不会让合法变非法),滑动窗口就成立。
14. 可迁移的解题能力
- 滑动窗口骨架:右指针单调扩张、左指针按不变量单调收缩、用哈希表或计数器维护窗口状态。这是流式数据处理最常见的算法形态。
- 单调性识别:判断一个题能不能用滑动窗口,本质是判断”左边界是否需要回退”。本题的关键洞察就是左边界只增不减。
- 窗口外陷阱:
last[ch] >= left这类”状态过期”判断,在所有带时间戳 / 位置的窗口问题里都会重现。 - 与 AI Agent 工程的关系(存在自然联系):Agent 侧的限流窗口(统计最近 N 秒内的调用次数)、事件流去重(判断某工具在窗口内是否已调用过)、上下文窗口裁剪(在 token 预算下保留最近且未重复的片段)、成本归因窗口(按时间片聚合 token 消耗)用的都是同一套骨架。区别在于:算法题里窗口合法性是确定的,工程里窗口边界往往还叠加时钟漂移、乱序事件与分布式计数,需要额外的水位线与迟到数据处理。
四、延伸资料
| 主题 | 资料 | 类型 | 核验状态 |
|---|---|---|---|
| 向量检索与存储 | pgvector 官方仓库 README(HNSW / IVFFlat 取舍、过滤后召回陷阱、hnsw.ef_search 默认 40、迭代扫描、多租户分区建议)https://github.com/pgvector/pgvector | 官方仓库文档 | 已核验 README 正文要点 |
| 事务与一致性 | PostgreSQL 官方《Transaction Isolation》https://www.postgresql.org/docs/current/transaction-iso.html | 官方文档 | 链接为官方稳定路径;本轮页面抓取未返回正文,正文未逐字核验 |
| 结构化输出 | OpenAI《Structured model outputs》https://platform.openai.com/docs/guides/structured-outputs | 官方文档 | 已核验要点:仅 strict 模式通过约束采样保证完全符合 schema;JSON mode 不保证匹配任何 schema |
| 结构化输出与 API 演进 | OpenAI《Migrate to the Responses API》(Structured Outputs 定义从 response_format 迁移到 text.format)https://platform.openai.com/docs/guides/migrate-to-responses | 官方文档 | 已核验 迁移说明要点 |
| MCP 扩展与 Tasks | Model Context Protocol 官方扩展总览与 Tasks 文档 https://modelcontextprotocol.io/extensions/ ;规范变更记录 https://modelcontextprotocol.io/specification/2026-07-28/changelog | 官方规范 | 题库配置 v3 变更记录已列为主要来源,本轮未重复核验 |
| MCP 路线图边界 | MCP 官方路线图(webhooks / channels、渐进式工具发现仍为路线图优先项,无规范文本)https://blog.modelcontextprotocol.io/ | 官方博客 | 配置中已标注来源,本轮未重新核验 |
| 算法 | LeetCode 3 官方题目页(中 / 英)https://leetcode.cn/problems/longest-substring-without-repeating-characters/ | https://leetcode.com/problems/longest-substring-without-repeating-characters/ | 官方题目 | 已核验 可访问、题号与标题一致 |
未核验项:PostgreSQL 隔离级别文档正文、MCP 官方页面本轮状态。引用时请以官方页面当前内容为准,不要当作已验证事实。
五、当日重点与复习建议
三个今天必须带走的结论
- 向量不是存储,是索引。 长期记忆的事实来源必须是可更新、可撤销、可审计的结构化存储;向量只做候选生成,过滤与判定回到结构化层。带过滤的近似检索会”先召回后过滤”,是线上检索质量下降的高频根因。
- schema 保证形状,不保证语义。 严格模式通过约束采样解决形态问题;业务规则靠代码校验;可靠性靠”约束 → 校验 → 带错误信息的修复式重试(限 1 次)→ 降级”四层,而不是无限重试。
- 新能力默认关闭、显式 opt-in、必须有降级路径。 协议演进期的线上事故,绝大多数不是新能力有 bug,而是”假设对端支持”。
复习建议
- 明天优先复习
Q-20261012-S01:把降级矩阵和三维灰度画成一张图,能默写出”能力 × 客户端”的四格结果矩阵。 Q-20261012-B01建议动手做一次 filtered ANN 实验:同一批 query,对比”先召回后过滤”与”先过滤后召回”的 recall@k 差异,这是把概念变成直觉的唯一方式。Q-20261012-B02建议统计自己项目里结构化输出的失败类型分布,看看截断占比——如果截断是第一大失败原因,说明max_tokens配置有问题而非模型问题。- 与 2026-10-10 的关联:B01 的”记忆写入”与当日 B1 的”外部记忆载体”是同一主题的上下游——当日讲上下文里怎么放,今天讲持久化时怎么存。S01 与当日 S1 都发生在 MCP 迁移语境下,但当日考”有状态 → 无状态”的状态外置,今天考”新能力协商失败”的降级兼容,二级知识点不重合。
尚未覆盖的启用类型(供后续轮换参考):RAG 与搜索、AI 与大模型基础、编程语言与运行时、操作系统与网络、软件工程与平台工程、分布式系统(部分二级知识点已在历史场景题中间接触及,但未作为基础题正面考察)。
六、本次生成元信息
| 项 | 内容 |
|---|---|
| 配置读取状态 | 成功 |
| 实际配置版本 | version: 3(last_reviewed: 2026-10-12) |
| 暂停类型 | 无(截至 v3 仍为空) |
| 观察中的新技术 | 默认不出题;本次未从中出题 |
| 历史读取范围 | 题目索引.md 不存在 → 扫描 2026-10/ 全部训练文件(1 份:2026-10-10)并完成索引重建;无周复盘文件;精选/ 目录不存在 |
| 去重窗口 | 30 天强去重(实际比对 2026-10-10 共 8 题) |
| 去重结果 | 一级类型:数据库与存储、LLM 应用工程为首次覆盖;工具与互操作协议再次出现,但二级知识点为「扩展能力协商与降级回退 / Tasks / subscriptions/listen」,与 2026-10-10 的「无状态协议核心 / MCP-A2A 双层架构」不重合。LeetCode 题号 3 与历史 146 不重复。无换皮题、无复习题 |
| 关联复习来源 | 无(今日无复习题)。软关联:B01 与 Q-20261010-B01、S01 与 Q-20261010-S01 属上下游主题,已在复习建议中标注 |
| 归档路径 | 2026-10/2026-10-12-AI-Agent-面试训练.md |
| 索引更新 | 已创建 题目索引.md,登记历史 8 题 + 今日 4 题,共 12 条 |
| 周期复盘 | 未触发(本周期为第 2 次生成,阈值为 7 次,预计达成日 2026-10-16 前后) |
| 远端同步 | 仅本地写入成功,未做远端同步验证 |