1.1 大模型面试经验 k8s容器,大模型输出检测 RAG 与 Tool-calling

针对这份**"AI SRE / 运维开发专家"岗位的 JD,其核心诉求是:"工程化落地"**。即不仅要懂 AI,更要把 AI 能力用高并发、高可用的方式嵌入到大规模运维(SRE)场景中。

面试官不会问"什么是 RAG"这种基础题,而是会问"如何让 RAG 在 10W+ 的监控指标中快速找到根因 "。下面我按照 JD 的 6 个维度,为你整理了一份全面且具有深度的模拟面试题库


第一板块:核心技术底座 & 高并发工程落地(对应 JD 1)

出题意图:考察你是否能驾驭从 Python 原型到企业级服务的高并发演进。

Q1:你的 Agent 服务需要支撑 1000 QPS 的请求,但单次 LLM 推理需要 2 秒。你会如何设计系统架构来应对高并发?

考察点 :异步 IO、缓存、负载均衡。

回答思路 :1) 引入异步 FastAPI + asyncio 处理 I/O 密集;2) 使用缓存 (Redis)缓存高频问题(如已知故障的解决方案);3) Prompt 缓存 (如 DeepSeek 支持命中缓存降本);4) 引入消息队列做削峰填谷,任务异步化,不阻塞客户端。

Q2:在 Python 的 Global Interpreter Lock (GIL) 限制下,LangChain 中的多工具并行调用(并行 Function Calling)和代码中使用多线程/多进程,你会如何选择?

考察点 :Python 并发模型理解。

回答思路 :LLM 调用是 IO 密集型,使用 asyncio.gather 实现异步并发是首选;如果是 CPU 密集型的数据预处理(如大规模文本切分),用 multiprocessingRay 进行多进程处理。


第二板块:云原生可观测性 & K8s(对应 JD 2)

出题意图:AI Agent 不能是黑盒,运维专家必须能"看见"模型在干什么。

Q3:如果智能体(Agent)在 K8s Pod 中运行,由于 Token 生成过慢导致 OOM(内存溢出),你会如何通过 Prometheus + OpenTelemetry 快速定位是"内存泄漏"还是"上下文窗口超限"?

考察点 :LLM 可观测性埋点。

回答思路 :1) 通过 OpenTelemetry 埋点,记录每次请求的 input_tokensoutput_tokens;2) 将 Token 消耗量与 Pod 内存使用率在 Grafana 中做关联曲线;3) 若内存飙升与 Token 数正相关,则为上下文超限,需设置 max_tokens 硬截断;若不相关,排查代码循环引用导致的泄漏。

Q4:大模型推理(GPU)与服务调度(CPU)混部时,容易导致 CPU 节流。如何在 Kubernetes 层面为 LangGraph 应用设置合理的资源请求(Requests)和限制(Limits)?

考察点 :资源隔离与调度。

回答思路 :CPU 密集型任务(如 Tokenizer 分词)需要预留 CPU 毫核;虽然推理在 GPU,但高并发下的数据序列化/反序列化可能耗尽 CPU,建议设置较高 CPU Request,并开启 HPA(Horizontal Pod Autoscaler) 基于自定义指标(如队列长度)进行弹性伸缩。


第三板块:Agent 框架深度定制(对应 JD 3)------ 重点

出题意图:不仅会用 LangChain,更要能魔改。

Q5:LangChain 和 LangGraph 的主要区别是什么?在 SRE 故障自愈场景中,为什么选择 LangGraph 而不是简单的 LCEL(LangChain Expression Language)?

考察点 :框架选型。

回答思路 :LangChain 是线性 DAG(有向无环图),无法回退;LangGraph 支持循环(Cyclic)状态持久化。在故障自愈中,当"执行重启命令"失败后,需要回到"诊断节点"重新分析,这只能靠 Graph 的循环结构实现。

Q6:Model Context Protocol (MCP) 解决了什么问题?如果让你基于 MCP 开发一个"K8s 故障排查工具",Server 端和 Client(Agent)端的交互流程是怎样的?

考察点 :对 MCP 协议的理解。

回答思路 :MCP 标准化了 Agent 与外部工具的通信。Client 通过 initialize 握手,Server 通过 tools/list 暴露工具(如 get_pod_logs)。Agent 调用时 Server 通过 tools/call 执行,返回结构化结果。核心价值在于解耦------写工具的人不用管 Agent 逻辑。

Q7:Pydantic AI 相比于 LangChain 的优势是什么?在处理结构化输出时,你更倾向于用哪种?

考察点 :技术选型广度。

回答思路 :Pydantic AI 更轻量、类型安全(Type-safe),完美结合 Pydantic 做结构化输出验证;LangChain 生态丰富。对于 SRE 场景(强依赖 JSON 结构化输出给下游 API),Pydantic AI 或直接使用 OpenAI SDK + Instructor 库更适合,避免 LangChain 过度封装带来的 Debug 困难。


第四板块:RAG 与 Tool-calling 深度实践(对应 JD 4)

出题意图:考察向量检索的工程调优与工具调用的可靠性。

Q8:运维领域有大量的非结构化日志和结构化的时序指标。如何设计一个 混合检索(Hybrid Search)方案,让 RAG 系统既能找到"故障文本描述",又能找到"异常曲线图"?

考察点 :多模态/混合检索。

回答思路 :1) 文本 部分用 BM25(关键词)+ Embedding(语义)做混合检索;2) 时序指标 部分用异常检测算法转化为文本描述(如"CPU 在 10:05 飙升"),再将这段文字向量化存入向量库;3) 最终使用 RRF(倒数排名融合) 算法融合多路召回结果。

Q9:Tool-calling(函数调用)在 SRE 场景中,如何设计安全与权限控制(RBAC),防止 Agent 误删除生产数据库?

考察点 :AI 安全性(AI Safety)。

回答思路 :1) 工具层做分级策略 :只读工具(get_logs)允许 Agent 自动调用;写/删工具(delete_pod)必须经过 interrupt_before(人工审批);2) 工具入参做白名单校验 ,如环境变量限制 env 只能是 stagingprod,防止注入攻击。


第五板块:Prompt Engineering & Agent 评估(对应 JD 5)

出题意图:你不是调参侠,你必须能用数据证明 Agent 的效果在变好。

Q10:当 Agent 面对一个复杂的"根因分析(RCA)"任务时,经常产生"幻觉"(Hallucination),捏造不存在的监控数据。你会如何通过 Prompt Engineering 的方法解决这一问题?

考察点 :抗幻觉技巧。

回答思路 :1) 强制引用 :Prompt 要求"必须引用工具返回的 Metric ID,禁止编造数值";2) ReAct 反思 :在 Agent 回复前加一步"事实核查节点",用代码校验提及的指标是否真的存在于 State 中;3) 利用 LangGraph 的 interrupt_before 让人类确认关键数据后再做结论。

Q11:如何设计一套评估(Evaluation)体系来衡量这个 SRE Agent 的"工具选择准确率"和"故障诊断准确率"?

考察点 :Agent 评估框架。

回答思路 :1) 准备 黄金测试集(Golden Dataset) ,包含历史 P0 故障的"现象描述"和"标准操作流程(SOP)";2) 使用 LLM-as-a-JudgeRagas 框架评估:工具选择 F1 值 (是否调用了正确的 K8s 命令),最终结论正确性 (是否匹配历史 RCA 结论);3) 监控线上 "人工介入率"------如果 Agent 越来越不需要人确认,说明它在变好。


第六板块:大型互联网排障思维抽象(对应 JD 6)

出题意图:这是灵魂拷问,看你能否把运维经验代码化。

Q12:你负责的微服务突然出现"间歇性 500 错误"。请描述你是如何利用 AI Agent 协作分析,逐步缩小范围,最终定位到"某个特定机型的 CPU 节流"的?

考察点 :多 Agent 协作与抽象能力。

回答思路 :设计 多 Agent 协作(Multi-Agent) 模式:

  1. Orchestrator(调度者) 收集错误特征。
  2. Observability Agent(观测 Agent) 通过 MCP 调用 Prometheus 查该服务 Pod 的 CPU Throttling 指标。
  3. Log Agent(日志 Agent) 通过 MCP 调用日志系统,过滤该时间段的 "stalled" 关键词。
  4. 汇总结论,并将此次排查过程抽象为新的 SOP 文档,更新向量知识库,下次遇到类似问题直接检索匹配。

💡 面试加分项总结

针对这份 JD,如果你想拿到 Offer,面试中还应该"不经意"提到以下两点:

  1. 提及大模型推理特性:如"我会用 vLLM 或 TensorRT-LLM 做推理加速,因为 LLM 是 memory-bound 型任务,Batch Size 调优是关键"。
  2. 提及 MCP 与 Autogen 的区别 :如果面试官问及多智能体,可以补充:"Autogen 更偏向对话式多智能体(Conversational),而 LangGraph 更适合状态机驱动的确定性工作流,我倾向于结合两者,核心流程用 Graph,边缘探索用 Autogen"。
    针对你之前提供的 JD 和面试题库,我提炼出了 5 个最核心的高频知识点 ,并为每个知识点附上了可直接运行的代码片段。这些代码展示了如何将理论落实到工程中,是面试中展现"实战能力"的关键。

📌 高频知识点 1:LangGraph 的循环与状态管理(故障自愈)

为什么高频? SRE 场景中,Agent 必须能"尝试-失败-再尝试",LangGraph 的循环是核心。

代码示例:带重试的 K8s Pod 重启 Agent

python 复制代码
from typing import Annotated, TypedDict, Literal
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages

# 定义状态
class SREState(TypedDict):
    messages: Annotated[list, add_messages]
    pod_name: str
    retry_count: int
    action_result: str

# 节点1:诊断
def diagnose(state: SREState):
    # 模拟诊断逻辑
    return {"pod_name": "nginx-7d8f9", "retry_count": state.get("retry_count", 0)}

# 节点2:执行重启(可能失败)
def restart_pod(state: SREState):
    # 模拟重启操作,假设前两次失败,第三次成功
    if state["retry_count"] < 2:
        return {"action_result": "failed", "retry_count": state["retry_count"] + 1}
    else:
        return {"action_result": "success", "retry_count": state["retry_count"] + 1}

# 路由函数:决定下一步
def decide_next(state: SREState) -> Literal["restart", "__end__"]:
    if state["action_result"] == "failed" and state["retry_count"] < 3:
        return "restart"
    return "__end__"

# 构建图
builder = StateGraph(SREState)
builder.add_node("diagnose", diagnose)
builder.add_node("restart", restart_pod)
builder.set_entry_point("diagnose")
builder.add_edge("diagnose", "restart")
builder.add_conditional_edges("restart", decide_next, {"restart": "restart", "__end__": END})
graph = builder.compile()

# 运行
result = graph.invoke({"messages": []})
print("最终状态:", result)

📌 高频知识点 2:工具调用的安全控制(RBAC + 人工干预)

为什么高频? 生产环境禁止 Agent 乱删数据,必须进行权限控制。

代码示例:使用 interrupt_before 实现高危操作审批

python 复制代码
from langgraph.graph import StateGraph, MessagesState
from langgraph.checkpoint.memory import MemorySaver
from langgraph.prebuilt import ToolNode, tools_condition
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage, AIMessage

# 定义高危工具
@tool
def delete_pod(pod_name: str, namespace: str = "default") -> str:
    """删除指定的 Pod(高危操作)"""
    return f"✅ Pod {pod_name} in {namespace} has been deleted."

tools = [delete_pod]

# 构建图
builder = StateGraph(MessagesState)
builder.add_node("agent", ...)  # 省略 LLM 节点
builder.add_node("tools", ToolNode(tools))

# 设置中断:在执行 tools 前暂停
builder.compile(checkpointer=MemorySaver(), interrupt_before=["tools"])

# 执行时,检测到中断后询问人工
config = {"configurable": {"thread_id": "sre-session"}}
# 第一次 invoke 会停在 tools 前
graph.invoke({"messages": [HumanMessage(content="删除 nginx pod")]}, config)
state = graph.get_state(config)
if state.next:
    confirm = input("确认删除?(y/n)")
    if confirm == "y":
        graph.invoke(None, config)  # 继续执行
    else:
        print("操作已取消")

📌 高频知识点 3:RAG 混合检索(BM25 + 向量)

为什么高频? 运维文档和日志既有关键词(如错误码),又有语义信息,单一检索不够。

代码示例:使用 rank_bm25 + Chroma 实现混合检索

python 复制代码
from rank_bm25 import BM25Okapi
from langchain.vectorstores import Chroma
from langchain.embeddings import HuggingFaceEmbeddings

# 准备文档
docs = ["CPU 使用率超过 90%", "内存泄漏导致 OOM", "网络延迟增加", "磁盘 IO 高"]

# 1. BM25 关键词检索
tokenized_docs = [doc.split() for doc in docs]
bm25 = BM25Okapi(tokenized_docs)
query = "CPU 高负载"
bm25_scores = bm25.get_scores(query.split())
bm25_top = sorted(enumerate(bm25_scores), key=lambda x: x[1], reverse=True)[:2]

# 2. 向量检索(假设已有 embeddings)
vectorstore = Chroma.from_texts(docs, HuggingFaceEmbeddings())
vector_results = vectorstore.similarity_search(query, k=2)

# 3. 融合结果(RRF 倒数排名融合)
def reciprocal_rank_fusion(results_lists, k=60):
    scores = {}
    for rank_list in results_lists:
        for rank, (idx, doc) in enumerate(rank_list):
            scores[idx] = scores.get(idx, 0) + 1 / (k + rank + 1)
    return sorted(scores.items(), key=lambda x: x[1], reverse=True)

# 组装结果
bm25_list = [(idx, docs[idx]) for idx, _ in bm25_top]
vector_list = [(i, doc.page_content) for i, doc in enumerate(vector_results)]
final_ranking = reciprocal_rank_fusion([bm25_list, vector_list])
print("混合检索最终排序:", final_ranking)

📌 高频知识点 4:Agent 评估(LLM-as-Judge)

为什么高频? 面试官关心你如何量化 Agent 效果。

代码示例:使用裁判模型评估"工具选择准确率"

python 复制代码
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate

judge_llm = ChatOpenAI(model="gpt-4")

# 定义评估模板
evaluation_prompt = PromptTemplate.from_template("""
你是一个评估专家。给定用户问题、Agent 调用的工具列表和最终回答,判断 Agent 是否做出了正确的工具选择。
输出格式:{"correct": true/false, "reason": "..."}

用户问题:{question}
Agent 调用的工具:{tools_used}
最终回答:{answer}
""")

# 测试用例
test_case = {
    "question": "查询北京天气",
    "tools_used": ["get_weather", "search_web"],
    "answer": "北京今天晴,25°C"
}

# 调用裁判模型
chain = evaluation_prompt | judge_llm
result = chain.invoke(test_case)
print(result.content)
# 输出:{"correct": true, "reason": "Agent 调用了 get_weather,回答基于工具结果,正确。"}

📌 高频知识点 5:MCP 服务器实现(工具标准化)

为什么高频? MCP 是 JD 明确要求的,面试官想听你如何设计工具协议。

代码示例:实现一个简单的 MCP Server(使用 FastMCP)

python 复制代码
# 安装:pip install fastmcp
from fastmcp import FastMCP

# 创建 MCP 服务器
mcp = FastMCP("K8s Tools")

@mcp.tool()
def get_pod_logs(namespace: str, pod_name: str, lines: int = 100) -> str:
    """获取 Kubernetes Pod 的日志"""
    # 模拟真实调用
    return f"Logs from {namespace}/{pod_name}: ... (last {lines} lines)"

@mcp.tool()
def restart_deployment(namespace: str, deployment: str) -> str:
    """重启 Deployment(高危操作,需审批)"""
    return f"Deployment {deployment} in {namespace} restarted."

if __name__ == "__main__":
    # 启动 stdio 服务器
    mcp.run(transport="stdio")

Agent 端可通过 MultiServerMCPClient 加载这些工具,实现工具与 Agent 逻辑的解耦。


💡 面试话术总结

  • "在 LangGraph 中,我用 add_conditional_edges 实现重试循环,并限制最大步数防止死循环。"
  • "对于高危工具,我会在编译时设置 interrupt_before=['tools'],强制人工确认,保障生产安全。"
  • "混合检索我用 RRF 算法融合 BM25 和向量得分,兼顾关键词精确匹配和语义泛化。"
  • "评估体系我采用 LLM-as-Judge,对工具选择、答案忠实度、任务完成率分别打分,并用 Ragas 做自动化回归测试。"
  • "MCP 协议让我能统一管理 K8s 工具,Agent 只需通过 stdio 或 SSE 调用,不关心工具实现细节。"

准备好这些代码和思路,面试时随手写出片段,会大幅提升你的技术可信度。

面试官问的这个问题非常专业,也是从"Demo"走向"生产级应用"的核心门槛。评估智能体(Agent)的输出比评估纯 LLM 的文本要复杂得多,因为智能体不仅有"最终答案",还有"思考过程"(Chain-of-Thought)和"工具调用轨迹"(Tool Trajectory)。

在面试中,你可以从 "自动化评估""人工/业务评估" 两个大维度,再结合 "离线指标""在线指标" 来分层回答。以下是我为你梳理的面试高分回答框架:


1. 结构化与确定性校验(最基础层)

这是最硬性的检查,不依赖大模型的主观判断。

  • 格式校验:强制 Agent 输出 JSON / XML / Markdown 格式,用代码验证是否符合 Pydantic / JSON Schema。
  • 工具调用校验 :检查 Agent 是否调用了必要的工具,以及传入的参数是否在有效范围内(例如:查天气的城市必须是中文或合法拼音)。
  • 关键词/实体覆盖率:针对特定任务,校验最终回复中是否包含了必须提及的实体(例如:"必须包含合同编号")。

2. 基于"裁判模型"的评估(LLM-as-a-Judge)------ 面试重点

这是目前业界最主流的方法,指用更强、更聪明的模型(如 GPT-4、Claude-3.5)来评估你的 Agent 输出 。你需要设计一套 Evaluation Prompt(评估提示词)

  • 评估维度
    • 忠实度(Faithfulness):Agent 的回答是否基于检索到的上下文或工具返回的结果,没有"幻觉"(胡编乱造)。
    • 相关性(Relevance):回答是否切题,有没有答非所问。
    • 工具选择正确性(Tool Selection):Agent 是否使用了最合适的工具(例如:查实时天气不应该用"知识库检索")。
  • Ragas 框架 :可以提一下开源框架 Ragas,它专门提供了一套自动化指标来评估 RAG 和 Agent 的检索与生成质量。

3. 轨迹与过程评估(LangGraph 特有优势)

面试官大概率会关注你用的 LangGraph,你可以借此强调 "不仅要看结果,还要看过程"

  • 步数限制 :在 LangGraph 中设置 recursion_limit,如果 Agent 陷入死循环(超过 N 步),直接判定为失败。
  • 中间状态快照:利用 LangGraph 的 Checkpointer 保存每一步的 State。你可以编写脚本回放这些轨迹,检查在"第 2 步"时 Agent 是否拿到了正确的数据,而不只是看"第 5 步"的最终回答。

4. 端到端任务成功率(E2E Success Rate)------ 业务视角

这是最贴近业务需求的指标。

  • 黄金测试集 :准备 100~200 个"用户提问 + 期望答案/操作"的测试用例。运行 Agent 后,人工或通过裁判模型判断任务是否完全完成
  • 例如:Agent 的任务是"帮我订一张周五去上海的票"。只要最终成功调用了订票 API 并返回了订单号,就算成功,而不管回复的"文采"如何。

5. 人工反馈与在线指标(Human-in-the-loop & Ops)

  • 人工评分:在早期的 A/B 测试中,让标注员对 Agent 的回复进行 1-5 分打分。
  • 隐式反馈:用户是否复制了内容?用户是否在 5 秒内继续提问?这些行为数据能侧面反映 Agent 输出的有用性。

💡 面试回答话术参考

你可以这样组织语言:

"对于 Agent 输出的检测,我认为不能只盯着最后的文字,而是要分层解耦。第一层是硬校验 ,我会校验工具调用的参数是否合法,以及返回的 JSON 结构是否正确。第二层是模型评估 ,我会引入'裁判模型(LLM-as-a-Judge)',针对'答案是否忠实于检索结果'、'是否解决了用户痛点'进行打分,同时我也会关注 LangGraph 留下的执行轨迹第三层是业务指标,我会沉淀一套回归测试集,重点监测端到端的任务成功率,确保每一次迭代不会让 Agent 变笨。"

⚠️ 面试官的"陷阱"与应对

  • 如果面试官问:"裁判模型怎么保证自己的判断是准的?"
    • :定期抽取 50 条样本,让人工标注,计算裁判模型与人工标注的一致性(Cohen's Kappa 系数)。如果一致性低于 0.8,则需要优化评估 Prompt 或改用更强的模型。另外,使用 LangSmith 等工具可视化对比也很关键。