三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

大厂 MCP 面试实录:基于 Python SDK 构建可复用 Prompts 工作流与权限审计方案

大厂 MCP 面试实录:基于 Python SDK 构建可复用 Prompts 工作流与权限审计方案

大厂 MCP 面试实录:基于 Python SDK 构建可复用 Prompts 工作流与权限审计方案

本文为一场围绕「团队沉淀可复用 MCP Prompts 工作流」场景的模拟面试复盘,面向具备基础 Python 开发与 AI 应用集成经验的候选人。


面试官:候选人你好,我们团队目前有多个业务线都在基于 MCP 构建 AI 工作流,发现很多场景的 Prompt 模板是重复的,比如代码审查、周报生成、合规检查,想沉淀一套可复用的 MCP Prompts 能力,要求符合最小权限原则,同时有完整的审计日志,你打算怎么设计这套方案?

候选人:我的整体方案是基于 Python MCP SDK 构建独立的 MCP Server,专门暴露预定义的 Prompts 能力,配合服务端参数校验、分层权限控制和全链路审计日志埋点,落地分为四步:首先是能力梳理,把重复的业务 Prompt 抽象成标准化的模板,定义清晰的参数 schema;其次是用 Python SDK 注册这些 Prompts,在服务端做二次参数校验和权限拦截;然后是埋点审计日志,覆盖请求全链路;最后是根据部署场景选择传输方式,内部本地用 stdio,跨团队远程用 Streamable HTTP 加认证。 选型依据是这些场景都是预定义的模板化工作流,没有副作用,符合 MCP 中 Prompts 的能力语义——Prompts 是模板化的消息或工作流,由用户或模型显式选择,比让模型自由组织 Prompt 更规范,也方便统一管控。[资料1]


面试官追问1:你说选择 Prompts 能力而不是 Tool 或者 Resource,能具体说下三者的差异和选型依据吗?如果我把周报生成的模板做成 Resource 行不行?

候选人:三者的选型核心是匹配能力语义: - Tools 是模型可调用的、有副作用的操作,比如查询数据库、发送消息,必须有明确的输入输出和副作用说明; - Resources 是只读的上下文数据,比如文档、数据库查询结果,由 URI 标识,供应用直接读取; - Prompts 是模板化的指令集,本身无副作用,承载预定义的工作流逻辑。[资料1] 周报生成的场景是输入素材、输出生成后的周报,本身不涉及数据修改或外部操作,用 Prompts 最合适。如果做成 Resource 的话,Resource 只能直接返回静态数据,无法承载模板化的指令逻辑,反而需要 Host 层额外处理模板拼接,不符合 MCP 的能力边界。


面试官追问2:你提到用 Python MCP SDK 实现,能说下具体的实现思路吗?参数校验是怎么做的,会不会只靠模型传入的参数?

候选人:Python MCP SDK 支持通过装饰器快速注册 Prompts,我们可以先定义每个 Prompt 的名称、描述和参数 schema,SDK 会自动做基础的参数结构校验,但参数 schema 只是结构约束,不能代替服务端校验,所以我在 Handler 层会做二次校验:比如检查参数长度、是否包含非法字符、业务参数是否合法。比如代码审查的 Prompt 要求传入的代码长度不能超过1万字符,避免占用过多上下文,同时如果参数里有 SQL 片段的话,会做注入检测。 举个例子,代码审查 Prompts 的注册伪代码如下:

# 伪代码:基于 Python MCP SDK 注册 Prompts,无版本依赖的通用接口设计 from mcp.server import Server from mcp.types import Prompt, PromptArgument app = Server("reusable-prompts-server") # 注册代码审查 Prompt @app.prompt( name="code_review", description="对提交的代码片段进行标准化审查,输出问题与优化建议", arguments=[ PromptArgument(name="code", description="待审查的代码内容", required=True, type="string"), PromptArgument(name="language", description="代码编程语言", required=True, type="string") ] ) async def code_review_handler(args: dict, current_user: User) -> str: # 服务端二次校验,防止模型传入非法内容 if len(args["code"]) > 10000: raise ValueError("代码长度超过最大限制") # 权限校验前置 if not has_permission(current_user, "code_review", args.get("biz_line")): raise PermissionError("无权限执行该操作") # 审计日志埋点 audit_log( user=current_user.id, action="invoke_prompt", prompt_name="code_review", params=redact_sensitive(args), # 敏感字段脱敏 status="start" ) # 组装标准化 Prompt 模板 return f"""你是一位资深代码审查专家,请对以下{args['language']}代码进行审查:

{args['code']}

请输出:1. 潜在问题 2. 优化建议 3. 安全风险""" # 全局错误处理中间件 @app.error_handler async def global_error_handler(e: Exception, request_id: str): audit_log( request_id=request_id, status="failed", error=str(e) ) return {"error": str(e), "request_id": request_id}

这里的所有接口都是 MCP Python SDK 的标准能力,没有自定义的私有API。[资料2]


面试官追问3:最小权限原则你怎么落实?如果不同业务线的用户调用同一个 Prompts,怎么保证数据不越权?

候选人:权限控制分两层: 第一层是 Prompts 的调用权限,不是所有用户都能调用所有 Prompts,比如合规检查的 Prompt 只有合规部的用户能调用,代码审查的只有研发线的用户能调用,我们在服务端做权限拦截,每次请求都要校验用户的角色和业务线权限,不能只判断用户是否登录,哪怕用户已经完成认证,没有对应 Prompts 的调用权限也会直接拒绝。 第二层是关联能力的权限校验,如果某个 Prompts 需要调用其他 Tool(比如生成报告需要查询业务数据库的 Tool),那这个 Tool 也要做权限拦截,只能访问用户有权限的业务数据,避免数据泄露。 另外如果 Prompts 执行过程中需要调用 LLM 完成生成,还要遵循 MCP Sampling 规范,保证高风险操作有人工在环,用户有权拒绝采样请求。[资料1][资料4]


面试官追问4:如果出现异常情况,比如参数非法、Tool 调用失败、模型返回异常,你怎么处理?审计日志要记录什么内容?

候选人:异常处理遵循「早失败、快反馈」的原则: - 参数校验不通过的话,直接返回错误信息给 Host,不执行后续的 Prompt 逻辑,同时在审计日志里记录请求ID、用户ID、调用的 Prompt 名称、非法参数(脱敏后)、错误原因、状态为失败; - 如果 Prompt 执行过程中关联的 Tool 调用失败,会捕获异常,返回友好的错误提示给模型,同时记录 Tool 名称、失败原因、耗时; - 模型返回异常的话,会记录模型错误码和原始返回,方便后续排查。 审计日志的核心要素必须包含:唯一请求ID(贯穿全链路)、操作人、操作时间、调用的 Prompt/Tool 名称、关键资源范围(比如业务线)、结果状态(成功/失败)、错误信息,同时所有敏感字段(比如用户输入的身份证号、密码)都要脱敏,凭据绝对不能出现在日志、Tool 返回值或模型上下文中。[资料1]


面试官追问5:如果要做远程多团队调用,传输方式怎么选?还有什么安全注意事项?

候选人:如果是团队内部本地使用,Host 在本机启动 MCP Server 子进程,用 stdio 传输最方便,性能也高,这时候要注意调试日志不能写到标准输出,要写到标准错误,否则会破坏 JSON-RPC 的通信协议。 如果是跨团队或者多环境远程调用,就用 Streamable HTTP 传输,这时候需要额外加认证授权,比如 OAuth2 或者 API 密钥,还要做会话管理、限流和超时控制,避免恶意请求或者服务雪崩。如果团队使用 Java 技术栈,也可以参考 Spring AI MCP 提供的标准化安全能力实现授权逻辑。[资料1][资料3]


面试官追问6:这个方案有什么适用边界?有没有容易踩坑的细节?

候选人:适用边界很明确:只适合承载预定义、无副作用的模板化工作流,如果业务需要模型动态生成 Prompt 内容,或者 Prompt 包含有副作用的操作(比如修改数据、发送消息),这个方案就不合适,前者应该用 Tool 或者在 Host 层处理,后者必须用 Tool 实现并加上用户确认环节。 容易踩坑的细节有两个:一个是不要把有副作用的操作放到 Prompts 里,比如不要在 Prompts 模板里写“执行删除操作”这类指令,必须用 Tool 实现,并且执行前向用户明确说明影响,避免不可逆操作;另一个是 stdio 传输的时候一定要把调试日志写到 stderr,我之前见过有团队把日志打到 stdout,导致 JSON-RPC 消息被破坏,服务直接不可用。[资料1]


面试官点评

  • 考察点:对 MCP 三类能力的语义区分、Python MCP SDK 的实践能力、MCP 安全边界的理解、异常处理与可观测性设计、方案取舍能力。
  • 合格回答:能清晰区分 Tools、Resources、Prompts 的适用场景,选择 Prompts 承载预定义工作流;知道服务端要做二次参数校验,不能只依赖模型传入的参数;有基础的审计日志意识,能想到权限拦截。
  • 加分项:能提到全链路请求ID、敏感字段脱敏、分层权限控制、传输方式的选型细节、stdio 的日志输出坑点,以及对方案适用边界的清晰认知,还能结合 MCP 的 Sampling 规范考虑模型调用的安全边界。

总结

这套方案的核心是遵循 MCP 的能力语义,用 Prompts 承载预定义、无副作用的模板化工作流,通过服务端校验、权限拦截和审计埋点满足安全和合规要求,适合团队内部快速沉淀标准化的 AI 工作流。落地时需要注意不要强行用 Prompts 承载动态生成或有副作用的逻辑,根据部署场景选择适配的传输方式,同时做好异常场景的兜底,日志、权限等规则的具体阈值需要根据业务 SLA、风险和压测结果确定,不要硬套通用值。

参考资料

  1. MCP 基础知识, https://modelcontextprotocol.io/specification/latest
  2. MCP Python SDK, https://github.com/modelcontextprotocol/python-sdk
  3. MCP Java SDK, https://github.com/modelcontextprotocol/java-sdk
  4. Sampling, https://modelcontextprotocol.io/specification/2026-07-28/client/sampling
← 返回列表