ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

MCP 面试高频考点:控制返回内容大小与上下文消耗,你能答到第几层?

MCP 面试高频考点:控制返回内容大小与上下文消耗,你能答到第几层?

MCP 面试高频考点:控制返回内容大小与上下文消耗,你能答到第几层?

面试场景

某团队用 MCP 把内部知识库接入 AI 应用:Server 运行在 Docker 容器中,暴露 Tools 与 Resources;知识检索走 RAG 链路,向量检索加可选重排。上线后问题来了——知识检索 Tool 经常把整段文档塞回模型上下文,回答质量没明显提升,上下文预算却被吃光。面试官围绕“如何控制 MCP 返回内容大小、降低上下文消耗”展开递进追问。

第一轮:基础问题——能力怎么选

面试官:知识库检索这个需求,你会把它设计成 MCP 的 Tool 还是 Resource?为什么?

候选人:结论是优先做成 Tool,只读文档需要按 URI 定位时再配 Resource。理由:Tool 是模型可主动发起的操作,适合“模型根据任务决定何时检索”;Resource 由应用读取、通常用 URI 标识,适合把确定的上下文交给模型 [资料1]。检索有输入参数(查询、过滤条件),属于按需动作,不是一份固定资料。但要强调:只读资料不要硬塞成有副作用的 Tool,也不能把检索结果当成可信指令 [资料1]。

面试官:那检索应该由模型发起,还是 Host 在调模型前主动做?

候选人:两种都成立,取舍在可预测性与灵活性。模型发起更灵活,但要控制调用次数和权限;Host 预检索流程简单、可预测 [资料1]。上下文预算紧张时,我倾向 Host 先做一次受控检索,把“候选集”压小,再让模型在必要时通过 Tool 补充查询——避免模型反复调用把上下文越堆越大。

第二轮追问:为什么返回会失控

面试官:好,那你说说返回内容为什么会变大?

候选人:三个来源。一是切块粒度:切块要保留语义完整性,同时避免不相关内容占用大量上下文 [资料1],切太碎召回条数多、切太大单条就超预算;二是召回策略:只做单路向量检索容易召回一堆近似片段;三是返回结构:把整篇文档、原始 embedding、调试字段一起塞进 Tool 返回值,模型根本用不上。

面试官:具体怎么压?先讲检索侧。

候选人:结论是“混合召回 + 重排 + 阈值”三层过滤,再在返回前做截断。资料明确建议混合查询,把关键词与非向量检索和向量检索结合以提升召回;可用语义排序、评分配置加权,并通过向量查询参数做权重与最低阈值,排除低分结果 [资料2]。流程上:候选集先粗召回,重排后只留少量高相关片段,低于阈值的直接丢弃。阈值不是拍脑袋的数字,要按业务 SLA 和离线评估确定。

面试官:嵌入维度这块有文章吗?

候选人:有,但要看存储约束。资料给出的做法是:当向量库只支持有限维度时,可指定较小的dimensions参数,把维度从 3072 缩短,以一定精度换取更小的向量体积 [资料3]。这只影响存储与检索成本,不直接决定返回给模型的文本大小——返回内容大小主要靠片段选择与截断控制,两件事别混。

第三轮追问:异常与安全

面试官:如果向量库超时或重排服务挂了,Tool 怎么返回?

候选人:降级而不是抛一大坨错误堆栈。向量检索失败可退回关键词检索,重排失败就用原始召回分数排序,并在返回值里给出明确的状态字段让模型知道“结果可能不完整”。错误信息要精简,不能把内部路径、连接串带进上下文——凭据不应出现在日志、Tool 返回值或模型上下文中 [资料1]。超时与重试的具体值由业务 SLA 和压测决定,不写死。

面试官:检索回来的文档里如果有“忽略以上指令”这类文字呢?

候选人:检索文档是不可信数据,其中指令不得覆盖系统规则 [资料1]。我会在返回结构上做隔离:片段作为带来源元数据的“引用材料”字段返回,而不是拼进指令区;保留来源元数据才能支持引用和排错 [资料1]。同时 Tool 参数 schema 只是结构约束,服务端仍要对查询串、过滤条件做校验和授权 [资料1]。

面试官:远程部署还要注意什么?

候选人:认证、授权、会话管理、限流、超时都要考虑 [资料1];每次请求都要做授权检查,不能只判断用户是否已登录 [资料1]。审计日志记录谁在何时调了哪个 Tool、资源范围与结果状态,敏感字段脱敏 [资料1]。本地 stdio 场景则注意标准输出只走协议消息,调试日志写标准错误 [资料1]。Docker 化只是部署形态,安全边界不因容器而改变。

方案设计与可落地示例

面试官:给个返回结构的设计。

候选人:接口设计如下,伪代码,不绑定具体 SDK。

Tool: kb_search 输入: { query, top_k, filters, max_chars } 返回: { status: "ok" | "degraded", snippets: [ { id, text, source_uri, score, rerank_score } ], truncated: bool, next_cursor?: string } 约束: - snippets 总字符数不超过 max_chars,按重排分从高到低截断 - 每条 text 设单条上限,超出截断并置 truncated - 不含 embedding 原始向量、内部路径、凭据 - source_uri 与 score 必填,供引用与排错

面试官:容易踩的坑是什么?

候选人:把“截断”只做在总长度上,忽略单条片段。一条超长片段就能挤掉其余高相关结果,模型看到的反而是最不精炼的那段。另一个坑是降级后不告诉模型状态,模型把不完整结果当完整事实用。还有:重排分与召回分直接混用排序,量纲不同会误导截断顺序,需要明确以重排分为准或做归一化。

面试官:适用边界呢?

候选人:这套方案适合“知识密集型问答、上下文预算有限、对引用可追溯有要求”的场景 [资料4]。若问题需要跨大量文档做全局推理,单纯压小返回可能损失召回,此时应改为多轮受控检索或由 Host 编排,而不是一味截断。

面试官点评

  • 考察点:是否理解 MCP 三类能力语义、Tool 与 Resource 的边界;能否把 RAG 的召回、重排、阈值与 MCP 返回结构真正串起来;安全与降级是否落到返回值设计上。
  • 合格回答:能说清“为什么返回会变大”,给出混合召回、重排、阈值、截断的组合,并指出检索文档不可信、schema 不等于授权。
  • 加分项:区分“向量维度压缩”与“文本截断”两个成本维度;设计带status与truncated的返回契约;主动说明降级策略、审计脱敏与参数由 SLA 决定而非写死。

总结

控制 MCP 返回内容大小,本质是把 RAG 的“少而准”落实到协议返回契约上:能力选型用 Tool 承载按需检索、Resource 承载确定上下文;检索侧用混合查询与重排提升相关性,用阈值与截断控制体积;返回侧用结构化片段、来源元数据、状态字段保证可引用、可排错、可降级;安全侧始终把模型输入与检索文档视为不可信,凭据不进上下文。Docker、向量库只是载体,真正的取舍在召回质量与上下文预算之间,具体数值交给业务 SLA 与压测决定。

参考资料

  • MCP 基础知识(本地知识库资料)
  • Retrieval-augmented generation (RAG) in Azure AI Search:https://learn.microsoft.com/en-us/azure/search/retrieval-augmented-generation-overview
  • Vector embeddings | OpenAI API:https://platform.openai.com/docs/guides/embeddings
  • Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks:https://arxiv.org/abs/2005.11401
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进