#模块七:Agent、工具调用、工作流编排与协议

#73. 什么是 Agent?它和普通 Chatbot 的区别是什么?

#标准答案

Agent 不只是“会聊天的模型”,而是一个围绕目标持续运行的决策系统。它通常会经历一条闭环:接收目标、观察环境、决定下一步、调用工具、读取结果、再继续规划。所以 Agent 的核心不是输出一段漂亮文字,而是能推进任务状态。

普通 Chatbot 更像“你问我答”的文本接口,即使多轮对话,本质上仍主要停留在语言交互层;Agent 则更接近“会执行的系统”,它会操作工具、查询外部世界、维护状态并承担失败恢复责任。面试里如果你把区别讲成“Agent = 感知 + 决策 + 行动 + 反馈”,通常会更稳。


#深度解析

1. Agent 的完整闭环结构

用户目标 → 规划(Planning)→ 选择工具 → 调用执行 → 观察结果 → 判断完成?
                                              ↓ 否
                                    ←←←←←←←←←←
                                              ↓ 是
                                    生成最终回答

一个真正的 Agent 系统至少包含 5 个模块:

模块 职责 失败时的表现
规划器 把目标拆成子步骤 反复修改计划、陷入循环
工具选择器 决定调用哪个工具、什么参数 选错工具、参数格式错误
执行器 实际调用外部 API/代码/数据库 超时、权限不足、返回异常
观察处理器 解析工具返回的结果 看不懂返回、忽略关键信息
状态管理器 记录已完成/未完成/失败的步骤 重复做同一步、遗漏关键步骤

2. Chatbot vs Agent 的本质差异

维度 Chatbot Agent
输入 用户文本 目标 + 环境状态
输出 回答文本 行动(工具调用)+ 状态更新
记忆 对话历史 任务状态 + 长期知识 + 工具经验
失败处理 道歉/转移话题 重试、回退、换工具、请求帮助
核心能力 语言理解与生成 决策 + 工具使用 + 状态追踪

3. Agent 设计的常见陷阱

  • 过度规划:模型在行动前想太多步骤,但环境反馈可能让前期规划完全失效。解决:ReAct 的"一步一想"模式。
  • 工具幻觉:模型声称调用了工具,但实际上没有,或编造了工具返回结果。解决:强制工具调用走代码执行,模型只负责生成参数。
  • 状态丢失:多轮工具调用后,模型忘记了最初的目标。解决:显式维护任务状态(如 todo list),每轮都注入当前进度。
  • 无限循环:模型在两个动作间反复横跳(如"查 A → 发现需要 B → 查 B → 发现需要 A")。解决:设置最大步数、检测循环模式、允许用户干预。

4. 面试官常见深挖追问

  • "一个 Agent 系统里,状态管理应该由模型做还是由外部系统做?"
    • 答:关键状态(如用户身份、任务进度、已调用工具列表)应该由外部系统显式维护,而不是指望模型记住。模型只负责"在当前状态下决定下一步"。因为模型上下文有限、可能幻觉、容易遗忘,把状态外置更可靠。
  • "Agent 的"自主性"有没有边界?你怎么防止它做危险操作?"
    • 答:自主性必须有边界。设计上:1)工具权限最小化(如只读数据库、沙箱执行代码);2)敏感操作需要人类确认;3)所有工具调用记录审计日志;4)设置超时和重试上限;5)禁止工具链中出现循环调用(A→B→A)。
  • "如果 Agent 执行了 5 步工具调用后失败了,怎么恢复到之前的状态?"
    • 答:需要显式的事务/快照机制。每步工具调用前保存当前状态快照;失败时可以选择回滚到任意快照,或继续从最近成功点重试。这类似于数据库的 transaction,是可靠 Agent 的必备能力。

#74. ReAct 的基本思想是什么?

#标准答案

ReAct 的核心思想,是把 reasoning 和 acting 交替起来:模型先做一步思考,决定下一步该查什么、调什么工具、执行什么动作;动作执行后得到 observation,再基于新的观察继续推理。它不是让模型先在脑中把全流程想完,而是强调“边想边做、边看边改”。

它重要,是因为很多现实任务并不能靠一次性纯文本推理解决。比如查资料、跑代码、浏览网页、问数据库,都需要环境反馈来修正下一步。ReAct 把这种反馈纳入推理主循环,因此比“先想完再统一执行”的方式更适合不确定环境。它的代价是轨迹更长、调试更难,但换来了更强的可解释性和更自然的闭环执行能力。


#深度解析

1. ReAct 的完整轨迹示例

假设用户问:"2024 年诺贝尔物理学奖得主是谁?他们因为什么获奖?"

Thought 1: 我需要查找 2024 年诺贝尔物理学奖的信息。
Action 1: search("2024 Nobel Prize in Physics winners")
Observation 1: "The 2024 Nobel Prize in Physics was awarded to John Hopfield and Geoffrey Hinton for foundational discoveries in using artificial neural networks for machine learning."

Thought 2: 我得到了获奖者名字和原因。但用户可能想知道更详细的信息,比如他们的具体贡献。
Action 2: search("John Hopfield Geoffrey Hinton Nobel Prize 2024 specific contributions")
Observation 2: "Hopfield: Created associative memory networks. Hinton: Invented backpropagation and deep learning methods."

Thought 3: 我已经有足够的信息来回答用户的问题了。
Action 3: finish("2024 年诺贝尔物理学奖授予了 John Hopfield 和 Geoffrey Hinton,以表彰他们在使用人工神经网络进行机器学习方面的基础性发现。Hopfield 创建了关联记忆网络,Hinton 发明了反向传播和深度学习方法。")

注意:每一步 Thought 只规划下一步做什么,而不是一次性规划所有步骤。

2. ReAct vs Plan-and-Execute

特性 ReAct Plan-and-Execute
规划方式 逐步规划(一步一想) 先全局规划,再执行
对环境变化的适应性 高(每步都可以调整) 低(计划定好后难改)
可解释性 高(每步都有 reasoning) 中等(只有初始计划)
适合任务 探索性任务(如搜索、调试) 结构化任务(如数据分析流程)
失败恢复 容易(发现错误立即调整) 困难(需要重新规划)

3. ReAct 的 prompt 设计要点

一个有效的 ReAct prompt 通常包含:

  • 格式示例:展示 Thought/Action/Observation 的交替格式
  • 可用工具列表:明确告诉模型有哪些工具、每个工具的参数和返回值
  • 停止条件:什么时候应该停止调用工具、直接回答
  • 错误处理:工具调用失败时该怎么做
You can use the following tools:
- search(query): Search the web for information
- calculator(expression): Evaluate a mathematical expression
- finish(answer): Provide the final answer

Follow this format:
Thought: [your reasoning about what to do next]
Action: [tool_name]([parameters])
Observation: [result from the tool]
...
When you have enough information, use finish(answer) to respond.

4. 面试官常见深挖追问

  • "ReAct 的 Thought 步骤一定要输出成文本吗?能不能内部化?"
    • 答:可以内部化。把 Thought 作为模型的内部 reasoning token(如 <think> 标签内的内容),不展示给用户。但保留 Thought 的文本输出有助于调试——当 Agent 行为异常时,可以通过查看 Thought 轨迹定位问题。
  • "如果 ReAct 陷入了循环(反复调用同一个工具),怎么检测和退出?"
    • 答:几种策略:1)设置最大步数(如 10 步);2)检测工具调用序列的重复模式(如连续 3 次调用相同工具且参数相同);3)维护一个"已尝试"列表,让模型知道自己已经做过什么;4)在 prompt 中明确要求"如果陷入困境,请总结已知信息并给出最佳回答"。
  • "ReAct 和 Function Calling 是什么关系?"
    • 答:Function Calling 是"怎么调用工具"的接口规范(输出 JSON 格式的函数调用);ReAct 是"什么时候调用工具、调用什么工具"的决策框架(reasoning + acting 的交替循环)。两者通常一起使用:ReAct 负责决策,Function Calling 负责执行。

#75. tool calling / function calling 的作用是什么?

#标准答案

tool calling / function calling 的作用,是让模型从“只会说”扩展到“会调用外部能力”。模型不再只是生成自然语言,而是可以按结构化 schema 输出函数名和参数,把计算、检索、数据库查询、系统控制等能力交给外部工具完成。

这件事的本质,不是让模型变成传统程序,而是把模型擅长的“理解意图和决定该做什么”,与工具擅长的“精确执行和返回结果”拼起来。面试里高分回答通常还会补一句:tool calling 能显著降低幻觉,因为模型不必瞎编数字、日期、库存、天气,而可以把这些交给真实系统。


#深度解析

1. Tool Calling 的具体流程

用户: "北京明天天气怎么样?"

系统 prompt 中的工具定义:
{
  "name": "get_weather",
  "description": "获取指定城市的天气",
  "parameters": {
    "city": {"type": "string", "description": "城市名"},
    "date": {"type": "string", "description": "日期,格式 YYYY-MM-DD"}
  }
}

模型输出(不是自然语言,而是结构化调用):
{
  "tool": "get_weather",
  "parameters": {
    "city": "北京",
    "date": "2024-12-20"
  }
}

系统执行工具,返回结果:
{"temperature": "-2°C", "condition": "晴", "wind": "北风3级"}

模型基于结果生成回答:
"北京明天天气晴朗,气温-2°C,北风3级。"

2. Function Calling 和 API 调用的区别

特性 Function Calling 传统 API
输入 模型自动生成参数 程序员硬编码参数
灵活性 高(模型理解意图后决定调用什么) 低(固定接口)
错误风险 参数可能出错(类型、范围) 通常正确(人工编码)
适用场景 开放域、动态需求 封闭域、固定流程

3. Tool Schema 设计的最佳实践

  • 描述要具体:不要写 "获取信息",要写 "获取指定城市和日期的天气预报,包括温度、天气状况和风速"
  • 参数类型要明确:用 enum 限制可选值(如 "type": {"enum": ["celsius", "fahrenheit"]}
  • 必填 vs 可选要分清:required 数组明确列出必填参数
  • 示例值有帮助:在 description 中给出示例(如 "格式: YYYY-MM-DD,例如 2024-12-20")

4. Tool Calling 的安全风险

  • 参数注入:用户输入中包含恶意参数(如 "city": "北京; rm -rf /"
  • 越权调用:模型调用超出权限范围的工具(如删除数据库)
  • 循环调用:模型反复调用同一工具导致无限循环
  • 信息泄露:工具返回的敏感信息被模型泄露给用户

防护措施:1)参数校验(类型、范围、格式);2)权限控制(工具白名单);3)调用频率限制;4)敏感信息过滤。

5. 面试官常见深挖追问

  • "如果模型应该调用工具但没有调用,而是直接用参数知识回答了,怎么办?"
    • 答:这是"工具使用不足"(under-calling)问题。解决办法:1)在 system prompt 中明确强调"必须使用工具";2)few-shot 示例中展示正确的工具调用模式;3)对不使用工具的回答做后处理检测,发现后重新请求;4)在训练数据中加入"必须使用工具"的偏好对。
  • "Tool Calling 的延迟怎么优化?"
    • 答:1)工具调用并行化(如果多个工具调用无依赖);2)工具结果缓存(如天气数据缓存 1 小时);3)预执行常见查询(如用户常问的城市天气提前拉取);4)异步工具调用(模型先返回"正在查询",工具结果到达后再推送)。
  • "如果工具返回了错误(如 API 超时、404),Agent 应该怎么做?"
    • 答:好的 Agent 应该有错误处理策略:1)重试(带指数退避);2)降级(用备用数据源或告知用户暂时无法获取);3)反思(在 Thought 中分析错误原因,调整参数再试);4)如果多次失败,放弃该工具、总结已知信息回答。

#76. workflow 和 autonomous agent 的差别是什么?

#标准答案

workflow 和 autonomous agent 的本质区别,不在于“有没有模型”,而在于路径是不是提前写死。workflow 通常是预定义流程:A 完成后到 B,B 完成后到 C,分支有限、逻辑可控,适合稳定业务;autonomous agent 则会根据环境反馈实时选择下一步,路径不是预先完全固定的。

因此两者的 trade-off 很明确:workflow 更稳、更好测、更容易做 SLA;agent 更灵活,能处理开放任务和异常情况,但也更难控、更难测、更容易出现循环、越权和状态漂移。面试时把这个边界讲清,比泛泛地说”agent 更高级”要强很多。


#深度解析

1. 决策框架:什么时候用 workflow,什么时候用 agent?

决策树:

任务确定性高?
├─ YES → 流程是否经常变化?
│   ├─ NO → 用 WORKFLOW(规则驱动、确定性高、好测试)
│   └─ YES → 用 AGENT(动态适应变化)
└─ NO → 是否需要与环境实时交互?
    ├─ NO → 考虑 workflow + 条件分支
    └─ YES → 必须用 AGENT(感知-决策-行动循环)

典型场景对照

维度 Workflow Autonomous Agent
典型场景 订单审批、报表生成、固定审批链 研究助手、代码生成、多步工具调用
路径确定性 预定义,A→B→C 运行时动态选择
错误处理 预定义异常分支 模型自主判断重试/回退
可测试性 高(每条路径可枚举) 低(状态空间太大)
延迟可预测性 高(固定步骤数) 低(可能循环、可能多轮)
安全边界 明确(每一步可控) 需要额外约束(如最大步数、权限白名单)

2. 混合架构:生产中最常见的模式

纯 workflow 太死板,纯 agent 太难控。生产系统通常是”workflow 骨架 + agent 局部决策”

┌─────────────────────────────────────────┐
│           Workflow 骨架(确定性流程)        │
│  ┌─────┐   ┌─────┐   ┌─────┐   ┌─────┐ │
│  │步骤A │ → │步骤B │ → │步骤C │ → │步骤D │ │
│  └─────┘   └──┬──┘   └──┬──┘   └─────┘ │
│               ↓          ↓              │
│         ┌─────────┐  ┌─────────┐       │
│         │ Agent子模块│  │ Agent子模块│       │
│         │ (动态决策) │  │ (工具选择) │       │
│         └─────────┘  └─────────┘       │
└─────────────────────────────────────────┘

生产案例

  • 客服系统:workflow 处理固定流程(验证身份→查询订单→提供方案),agent 处理开放式咨询(理解用户问题→选择知识库→生成个性化回答)
  • 代码助手:workflow 管理文件操作(读→改→写→测试),agent 决定具体改哪行、用什么算法

3. 为什么 “用了 LangChain/LangGraph ≠ Agent”?

很多人把用了链式调用或图结构就当成了 Agent,这是误区。

特征 LangChain Chain LangGraph 真正的 Agent
路径 固定 预定义节点,条件边 运行时动态生成
决策 有限条件判断 LLM 自主决策
循环 有(预定义) 自主(可能无限循环)
工具选择 固定 固定或有限分支 动态选择+参数填充

判断标准:关键决策是否由 LLM 在运行时产生?如果不是,只是 workflow。

4. Agent 的工程风险与管控手段

风险 现象 管控手段
无限循环 Agent 反复调用同一工具 最大步数限制、步数惩罚、状态去重
工具越权 调用了不该调的工具 权限白名单、工具签名验证、沙箱执行
状态漂移 忘记原始目标 目标重注入(每轮提醒原始任务)
幻觉行动 调用不存在的工具/参数 工具 schema 校验、参数类型检查
成本失控 调用次数过多 预算限制、成本监控、调用频率限制

5. 面试官常见深挖追问

  • ”如果一个任务既有固定步骤又有开放环节,你怎么设计?”
    • 答:用”workflow 主干 + agent 分支”的混合架构。固定部分(如身份验证、权限检查)用 workflow 保证安全;开放部分(如问题分析、方案生成)用 agent 提供灵活性。两者之间通过明确的接口和状态传递衔接。
  • ”Agent 出现无限循环怎么检测和打断?”
    • 答:多层防护:1)硬限制:最大步数(如 10 步强制退出);2)软限制:步数惩罚(每多一步 reward 降低);3)状态去重:检测 action 历史,如果连续重复相同动作则触发反思;4)人工兜底:关键节点要求人类确认。
  • ”为什么说 Agent 的测试比 workflow 难 10 倍?”
    • 答:workflow 的状态空间是有限的、可枚举的,可以写单元测试覆盖每条路径。Agent 的状态空间是开放的——同样的输入,LLM 可能选择不同的工具、参数、顺序。传统测试方法(断言、覆盖率)不适用,需要用:1)模拟环境测试;2)大量端到端案例;3)A/B 对比;4)人工评估(human eval)。
  • ”MCP (Model Context Protocol) 对 Agent 和 workflow 分别有什么价值?”
    • 答:对 workflow:标准化工具接口,减少胶水代码;对 Agent:更关键——Agent 需要动态发现和调用工具,MCP 提供了统一的工具描述格式和调用协议,让 Agent 能”即插即用”不同来源的工具,而不需要为每个工具写适配器。

#77. memory 在 Agent 中通常有哪些类型?

#标准答案

Agent 中常见的 memory 至少可以分成几类:短期上下文记忆,用于保存当前对话和本轮工具结果;任务状态记忆,用于追踪计划做到哪一步、哪些步骤成功或失败;长期用户记忆,用于保存稳定偏好、身份信息、习惯约束;工具记忆,用于记录过去哪些工具在什么场景下有效;外部知识记忆,则更像外挂知识库或向量存储。

它们的差别不只是内容不同,更在于生命周期和可信度要求不同。短期记忆可以频繁更新,长期记忆必须更谨慎;任务状态要精确,用户偏好要可压缩;工具历史可能适合做经验总结而不是全文保留。回答时能讲出这些边界,会比简单列清单更像真正做过 Agent。


#深度解析

1. 各类 memory 的技术实现

记忆类型 存储方式 检索方式 更新策略
短期上下文 模型 context window 直接注入 prompt 每轮替换
任务状态 结构化数据库/状态机 精确查询 事务更新
长期用户记忆 向量数据库 + 摘要 语义检索 定期合并
工具经验 规则库 + 成功案例库 相似度匹配 人工审核后入库
外部知识 向量数据库/RAG 语义检索 定时同步

2. 长期记忆的设计难点:该记住什么、不该记住什么

该记住的:

  • 用户稳定偏好(如"用 Python"、"简洁风格")
  • 高频使用模式(如常用工具、常查数据库)
  • 已验证的事实(如用户身份、已确认的配置)

不该记住的:

  • 临时状态(如"当前在加载中")
  • 未验证的推断(如"用户好像喜欢 A")
  • 敏感信息(如密码、密钥,除非加密)
  • 一次性上下文(如某次查询的具体参数)

3. 上下文压缩:长记忆怎么塞进有限的 context window?

  • 摘要:把多轮对话压缩成一段摘要
  • 关键信息提取:只保留实体、关系、决策点
  • 分层检索:需要时从向量库检索相关记忆片段,不需要时不加载
  • 记忆重要性评分:给每条记忆打分,只保留高分记忆

4. 面试官常见深挖追问

  • "Agent 的记忆如果出现了矛盾(如用户上次说喜欢 A,这次说喜欢 B),怎么处理?"
    • 答:1)时间戳优先:以最新的偏好为准;2)上下文感知:问用户"您之前说喜欢 A,现在确定要换成 B 吗?";3)维护冲突列表:记录矛盾点,在关键决策时提醒用户;4)场景分离:不同场景下的偏好可以共存(如"工作时喜欢简洁、休闲时喜欢详细")。
  • "如果 Agent 需要记住 1000 个用户的信息,怎么设计存储?"
    • 答:每个用户一个独立的记忆空间(如独立的向量集合)。查询时先按用户 ID 路由到对应空间,再做语义检索。存储层用向量数据库(如 Pinecone、Milvus)支持多租户隔离。热用户数据缓存在内存,冷用户数据在磁盘。
  • "Agent 的"幻觉记忆"(把错误信息记成长期记忆)怎么防止?"
    • 答:1)记忆写入前验证(如用户确认、交叉验证);2)记忆置信度评分,低置信度的记忆不长期保存;3)定期清理和审核长期记忆;4)区分"用户明确说的"和"模型推断的",只保存前者。

#78. MCP 想解决什么问题?

#标准答案

MCP(Model Context Protocol)想解决的核心问题,是模型接外部工具、资源和上下文的方式过于碎片化。过去每接一个系统,往往都要重新定义接口、权限、数据格式和调用方式,导致工具生态难复用、难组合、难迁移。

MCP 试图把”模型如何发现资源、调用工具、读取上下文”标准化,让不同客户端和服务端之间形成统一协议。它的价值不只是工程方便,而是降低集成成本、提升互操作性,并让 Agent 生态更像一个可组合平台,而不是一堆互不兼容的私有胶水代码。换句话说,它想把一次次定制接工具的工作,变成可复用的基础设施能力。


#深度解析

1. MCP 的架构:Host-Client-Server 三层模型

┌─────────────────────────────────────┐
│           MCP Host (客户端应用)        │
│  ┌─────────┐    ┌─────────────┐    │
│  │ MCP Client │ ←→ │ MCP Client  │    │
│  └────┬────┘    └──────┬──────┘    │
│       │                │            │
│       └──────┬─────────┘            │
│              │  stdio / SSE         │
└──────────────┼──────────────────────┘
               │
       ┌───────┴───────┐
       │   MCP Server   │
       │  (工具/资源提供者)│
       └───────────────┘
  • Host:宿主应用(如 Claude Desktop、IDE、Agent 框架)
  • Client:Host 内的连接实例,每个 Server 对应一个 Client
  • Server:提供具体能力的进程(如文件系统、数据库、API 封装)
  • 传输:stdio(本地进程)或 SSE(远程 HTTP)

2. MCP 的核心原语

原语 功能 示例
Resources 只读数据暴露 文件内容、数据库记录、Git 历史
Tools 可执行操作 发送邮件、创建文件、调用 API
Prompts 预定义模板 “分析这段代码的 bug”、”生成测试用例”

关键设计:Server 通过声明式 schema(JSON)描述自己的能力,Host 动态发现和使用,不需要硬编码。

3. MCP 解决的具体痛点

痛点(MCP 之前) MCP 方案
每接一个新工具要写适配器 工具作者实现一次 MCP Server,所有 Host 都能用
工具接口格式各异 统一 schema 定义(JSON-RPC)
权限管理碎片化 Host 统一管理权限,用户显式授权
上下文传递困难 标准化资源读取协议
工具生态封闭 开源 Registry,工具可复用可组合

4. MCP vs Function Calling 的区别

维度 Function Calling MCP
层级 模型能力(LLM 输出结构化 JSON) 系统协议(Host-Server 通信标准)
范围 单次调用格式 完整的工具生命周期管理
发现 需硬编码工具定义 动态发现 Server 能力
生态 各平台各自实现 跨平台标准化

关系:MCP 可以用 Function Calling 作为底层调用方式,但 MCP 的范围更大(包含发现、授权、生命周期管理)。

5. 面试官常见深挖追问

  • ”MCP 和传统的 REST API 有什么区别?”
    • 答:REST API 是”服务器暴露端点,客户端调用”;MCP 是”服务器声明能力,Host 按需发现和调用”。MCP 增加了能力发现(introspection)、动态权限管理、标准化上下文传递。简单说:REST 是”你知道有什么接口就去调”,MCP 是”你连接上后,它告诉你有什么能力”。
  • ”MCP Server 的安全性怎么保证?”
    • 答:三层安全:1)传输层:stdio 仅限本地,SSE 走 HTTPS;2)权限层:Host 负责权限管理,用户必须显式授权每个工具;3)执行层:Server 在独立进程中运行,Host 通过标准协议通信。但风险仍存在——恶意 MCP Server 可能泄露数据,所以 Server 来源需要审核。
  • ”为什么 2025-2026 年 MCP 突然火起来?”
    • 答:因为 Agent 生态从”demo 阶段”进入”工程化阶段”。早期每个团队各自接工具(碎片化可接受),但当 Agent 需要接 10+ 个工具、跨多个平台运行时,重复造轮子的成本剧增。MCP 提供了”一次接入,到处使用”的标准化方案,正好解决了这个规模化瓶颈。

#79. 你如何区分”工作流自动化”和”真正的 Agent 系统”?

#标准答案

区分这两者,最稳的方法是看三件事。第一,关键决策是不是在运行时动态产生;第二,环境反馈会不会真正改变后续路径;第三,系统是否需要显式状态管理、失败恢复和再规划。如果这些都很弱,流程大概率只是 workflow 自动化;如果任务推进必须边观察边决策,才更接近 Agent。

所以面试里不要把"用了 LangGraph""调用了三个工具"当成 Agent 证据。真正的问题是:这套系统是在执行预定义步骤,还是在基于目标不断选择下一步。很多生产系统其实是"workflow 主干 + Agent 局部决策",这样回答通常更贴近现实。


#深度解析

1. Workflow 与 Agent 的本质差异

维度 Workflow 自动化 真正的 Agent
决策来源 预定义规则/代码 LLM 运行时动态生成
路径确定性 固定(A→B→C) 动态(根据反馈调整)
错误处理 预定义分支(if-else) 自主判断重试/回退/求助
状态管理 隐式(变量传递) 显式(记忆、目标追踪)
可预测性
测试方式 单元测试覆盖路径 模拟环境 + 大量端到端 case
适用场景 规则清晰、稳定业务 开放任务、需适应变化

2. 判别检查清单

如果一个系统自称"Agent",用以下问题检验:

  1. 去掉 LLM,系统还能运行吗?
    • 能 → 可能是 workflow(LLM 只是其中一个节点)
    • 不能 → 更可能是 Agent(LLM 是决策核心)
  1. 同样的输入,运行两次路径一样吗?
    • 一样 → workflow(确定性)
    • 可能不一样 → Agent(LLM 采样有随机性)
  1. 遇到未预见情况,系统会停住还是自适应?
    • 停住/报错 → workflow
    • 尝试解决/重试/换策略 → Agent

3. 生产系统的常见模式

模式 结构 示例
纯 Workflow 全预设流程 固定审批链、定时报表生成
Workflow + Agent 节点 固定骨架,局部动态 客服系统:固定验证流程 + LLM 生成个性化回复
Agent + Workflow 约束 动态决策,但有边界 研究 Agent:可自由选择工具,但最大步数=10
纯 Agent 完全动态 开放式研究助手、自动编程 Agent

4. 为什么区分很重要?

  • 工程预期不同:workflow 可以承诺 SLA("5 秒内完成"),Agent 难以承诺
  • 测试策略不同:workflow 写单元测试,Agent 需要模拟环境 + 大量端到端评估
  • 治理方式不同:workflow 出错是 bug,Agent 出错可能是"合理但错误的选择"

5. 面试官常见深挖追问

  • "LangChain 的 Chain 和 Agent 有什么区别?"
    • 答:Chain 是"预设组件的固定连接"(如 Prompt → LLM → Parser),即使有 LLM 参与,路径也是固定的。Agent 是"LLM 在每一步决定下一步行动"(如 ReAct 循环)。LangChain 的命名有点混乱——很多 "Chain" 本质就是 workflow,不是 Agent。
  • "如果一个任务既有固定步骤又有开放环节,怎么设计?"
    • 答:用"workflow 骨架 + Agent 局部"的混合架构。固定部分(如身份验证、权限检查)用 workflow 保证安全;开放部分(如问题分析、方案生成)用 Agent 提供灵活性。两者通过明确的状态传递接口衔接。
  • "为什么说 Agent 的测试比 workflow 难 10 倍?"
    • 答:workflow 的状态空间是有限的、可枚举的(每个 if-else 分支都可以测试)。Agent 的状态空间是开放的——同样的输入,LLM 可能选择不同的工具、参数、顺序。传统测试方法(断言、覆盖率)不直接适用。需要用:1)模拟环境测试;2)大量端到端案例;3)A/B 对比;4)人工评估。

#80. ReAct、Plan-and-Execute、Reflexion 各自适合什么任务?

#标准答案

ReAct 更适合那种需要边执行边观察环境的任务,比如检索、网页操作、工具调用,因为每一步行动都可能改变后续决策;Plan-and-Execute 更适合结构相对清晰、可以先拆步骤的大任务,比如长流程分析、复杂写作、计划类任务;Reflexion 则适合允许试错、需要复盘修正的场景,比如程序修复、策略改进、反复尝试的搜索任务。

三者本质区别在于两个维度:计划是否显式、失败后是否有反思闭环。面试里若能补一句”任务越开放、反馈越强,ReAct 越自然;任务越长、阶段越清晰,Plan-and-Execute 越合适;失败成本可承受且历史轨迹有价值时,Reflexion 更有优势”,会很加分。


#深度解析

1. 三种范式的核心机制对比

维度 ReAct Plan-and-Execute Reflexion
计划方式 隐式、增量式(每步推理后决定下一步) 显式、预先规划(先列步骤再执行) 动态修正(失败后重新规划)
反馈循环 每步行动后立即观察 阶段完成后统一检查 失败后显式反思
状态管理 轨迹(Thought-Action-Observation) 计划列表 + 执行状态 经验记忆 + 失败案例库
典型步数 少到中等(3-10步) 中到多(5-20步) 可变(可能多次重试)
适合任务类型 交互式、开放域 结构化、流程化 试错型、优化型

2. 形式化流程对比

ReAct 循环:
  while not done:
    Thought = LLM(历史轨迹 + 当前观察)
    Action = 从 Thought 中提取工具调用
    Observation = 执行 Action
    轨迹 += (Thought, Action, Observation)

Plan-and-Execute:
  Plan = LLM(任务描述)  # 一次性规划
  for step in Plan:
    Action = LLM(当前步骤 + 上下文)
    Observation = 执行 Action
    if 需要重新规划: Plan = LLM(当前状态)  # 可选重规划

Reflexion:
  记忆 = []
  while not done and 尝试次数 < max:
    结果 = Execute(任务, 记忆)
    if 失败:
      Reflection = LLM(“为什么失败?如何改进?”, 轨迹)
      记忆 += Reflection
    else:
      return 结果

3. 具体场景选择指南

场景 推荐范式 原因
实时信息检索(查天气、股价) ReAct 每步检索结果直接影响下一步查询,无法预规划
复杂数据分析(多表关联、报表生成) Plan-and-Execute 步骤可预先拆解:清洗->分析->可视化,结构清晰
代码调试 Reflexion 编译错误/测试失败提供明确反馈,需要试错迭代
多步骤审批流程 Plan-and-Execute 审批节点固定,流程标准化
开放域探索(科研调研) ReAct 发现新信息可能完全改变方向,无法一次性规划
策略优化(参数调优、提示优化) Reflexion 每次失败产生可复用的优化经验

4. 组合使用策略

实际生产中常组合使用:

  • Plan-and-Execute + ReAct:顶层用 P&E 拆解大阶段,每个阶段内部用 ReAct 灵活执行
  • ReAct + Reflexion:ReAct 执行失败后触发 Reflexion,反思后带着经验重新执行
  • 三层架构:Planner(P&E 生成计划)-> Executor(ReAct 执行)-> Critic(Reflexion 复盘)

5. 面试官常见深挖追问

  • ”ReAct 的轨迹很长时,上下文不够怎么办?”
    • 答:1)摘要压缩历史轨迹;2)分层 ReAct(高层规划 + 低层执行);3)使用外部记忆存储完整轨迹,只加载相关片段;4)如果任务确实很长,考虑切换到 Plan-and-Execute 减少中间推理占用的上下文。
  • ”Reflexion 的反思质量不高怎么办?”
    • 答:1)给模型提供明确的反思模板(错误类型、改进方向);2)使用更强的模型做反思(如用 GPT-4 反思 GPT-3.5 的失败);3)限制反思轮数防止循环;4)引入外部验证器(如单元测试、规则检查)替代纯模型自评。
  • ”如果工具调用失败没有明确错误信息,Reflexion 还能工作吗?”
    • 答:效果会大打折扣。Reflexion 依赖明确的反馈信号(成功/失败 + 原因)。如果反馈模糊,需要:1)改进工具返回更结构化的错误信息;2)使用 LLM-as-a-Judge 评估执行质量;3)切换为 ReAct 模式,让模型从观察中自行推断问题。

#81. 一个 Agent 经常乱调用工具、循环执行、迟迟不结束,你会怎么诊断?

#标准答案

这类问题不能一上来就怪模型“太笨”,要分层诊断。先看工具层:tool schema 是否清楚,参数是否容易误填,返回结果是否结构化、可消费;再看状态层:系统有没有把已经完成的步骤记录下来,是否因为状态丢失导致反复做同一件事;再看策略层:停止条件、成功条件、失败回退条件是不是模糊,是否让模型永远有理由继续试;最后再看提示和轨迹:prompt 是否鼓励过度规划,观察结果是否太噪声。

如果想让回答更像实战,可以再补一个排障顺序:抽取循环 case -> 回放执行轨迹 -> 标注每一步为什么会继续 -> 看是工具误用、状态缺失还是 stopping rule 缺失。这样会显得你知道 Agent 失败常发生在编排和协议,而不只是”模型推理差”。


#深度解析

1. 四层诊断框架详解

层级 检查项 典型故障表现 诊断方法
工具层 Schema 清晰度、参数定义、返回值结构 参数填错、调用不存在的工具、忽略必填字段 检查 tool definition;统计工具调用错误率
状态层 历史记录完整性、上下文传递、记忆读写 重复执行已完成的步骤、忘记之前的结论 回放轨迹,检查每步的输入是否包含前序结果
策略层 停止条件、成功标准、失败回退、重试上限 永远不满足停止条件、无限重试、不报错也不结束 审查 prompt 中的 stopping rule 是否明确
提示层 Prompt 设计、观察噪声、模型过度规划 对简单问题做过多推理、被噪声观察带偏 A/B 测试不同 prompt,观察行为变化

2. 常见故障模式与根因

现象 根因 修复方案
工具乱调用(调用了和任务无关的工具) Tool schema 描述模糊,多个工具功能重叠 重写 description,增加 use case 示例;合并或拆分工具
参数错误(格式错、值错、缺必填) Schema 类型定义不清,枚举值没列全 增加 examples;使用 strict JSON schema;参数校验前置
循环执行(A->B->A 反复) 状态未更新,模型不知道已完成 显式写入完成标记;每步开始前检查状态
无限试探(同一工具反复调不同参数) 没有重试上限,或停止条件太弱 设置 max_iterations;明确”失败几次后放弃”规则
过早停止(还没完成就结束) 成功标准太松,或模型倾向保守 增加验证步骤;要求模型在结束前自检
上下文爆炸(后期决策质量骤降) 轨迹太长挤占推理空间 轨迹摘要;分层执行;只保留关键观察

3. 轨迹分析实操方法

拿到一个失败案例后,按以下步骤分析:

步骤1: 抽取轨迹
  提取完整的 Thought-Action-Observation 链

步骤2: 标注决策点
  标记每一步的”决策依据”——模型是基于什么决定继续/停止/重试?

步骤3: 识别异常模式
  - 连续 N 步没有实质进展?→ 可能是循环
  - 工具返回值被忽略?→ 可能是状态层问题
  - 反复修改同一参数?→ 可能是策略层缺失回退规则

步骤4: 构造最小复现
  用最短的输入复现相同问题,确认是系统性问题还是 case 特例

步骤5: 对照修复
  修改工具定义 / prompt / 状态管理 / 停止条件后,验证是否解决

4. 量化监控指标

在生产环境应监控:

  • 工具调用准确率:正确调用 / 总调用次数
  • 任务完成率:成功完成任务的比例
  • 平均步数:正常任务通常多少步完成,异常任务是否显著超出
  • 循环检测率:轨迹中重复模式出现的频率
  • 用户打断率:用户主动中止的比例(间接反映 Agent 失控)

5. 面试官常见深挖追问

  • ”如果模型能力不够强(比如 7B 模型),做 Agent 是不是注定失败?”
    • 答:不一定。7B 模型可以做 Agent,但需要更强的工程补偿:1)更严格的工具 schema 和校验;2)更明确的步骤模板(few-shot);3)更短的单步上下文;4)人在环路(HITL)兜底。模型能力弱时,协议和编排的设计权重需要提高。
  • ”怎么防止模型在观察结果中'幻觉'出工具没有返回的信息?”
    • 答:1)在 prompt 中强调”只能基于观察结果回答,不能假设”;2)对工具返回做结构化强制(如 JSON Schema);3)增加验证步骤,让模型复述从观察中获得了什么;4)使用更强的模型处理关键观察提取。
  • ”如果 Agent 需要和用户多轮交互,怎么管理状态?”
    • 答:分层管理:1)对话状态:当前轮次用户输入 + 历史摘要;2)任务状态:已完成步骤、待完成步骤、中间结果;3)用户偏好状态:长期记住的用户习惯(写入长期记忆);4)临时状态:当前轮次特有的上下文(轮次结束可丢弃)。关键是区分”什么需要记住”和”什么可以忘”。

#82. 如果要做 Multi-Agent,你怎么决定拆几个 agent,而不是一个大 agent 全做?

#标准答案

决定要不要做 Multi-Agent,首先不是看“拆开是否听起来高级”,而是看任务是否天然存在角色分工。比如检索、规划、执行、审查确实可能需要不同上下文和不同约束;如果所有步骤本来就在同一语境下完成,强拆通常只会增加通信成本和协调难度。

更稳的判断标准有三条:是否需要上下文隔离、是否需要模块化评测与替换、是否存在明显的角色边界。如果没有清晰职责边界,多 Agent 常常比单 Agent 更乱,因为系统会引入额外协议、消息传递和错误传播链。所以面试里最好强调:Multi-Agent 不是默认升级版,而是一种为了解决单 Agent 上下文过载和职责冲突的工程手段。


#深度解析

1. Multi-Agent 拆分决策矩阵

评估维度 适合拆分为 Multi-Agent 适合单 Agent
上下文冲突 不同角色需要截然不同的 system prompt(如"严格审计者"vs"创造性写手") 所有步骤共享同一上下文和角色设定
能力需求差异 检索需要长上下文,代码需要强推理,需要不同模型 全链路对模型能力要求一致
模块化需求 需要独立评测、替换、升级某个环节 端到端评估即可
并行潜力 多个子任务可并行执行(如同时检索多个来源) 任务 strictly 串行
安全隔离 某些操作需要权限隔离(如执行代码 vs 读取用户数据) 无敏感操作隔离需求
错误传播 希望限制错误范围,一个 Agent 失败不影响其他 可以接受全链路重试

2. 常见 Multi-Agent 拓扑模式

模式 结构 适用场景 通信复杂度
流水线 A → B → C 标准流程(检索→分析→生成) O(n)
主从 主 Agent 调度多个子 Agent 任务分配、负载均衡 O(n)
辩论 Agent A vs Agent B,第三方裁决 代码审查、方案评估 O(n²)
市场 多个 Agent 竞争/拍卖 资源分配、任务外包 O(n²)
层级 高层规划 → 中层分解 → 底层执行 超复杂任务分解 O(log n)

3. Single-Agent vs Multi-Agent 的工程成本对比

成本项 Single-Agent Multi-Agent
开发复杂度 低(一个 prompt + 一组工具) 高(协议设计、消息格式、状态同步)
调试难度 中(轨迹线性) 高(分布式轨迹,需追踪跨 Agent 调用)
延迟 低(无通信开销) 高(串行时累加通信延迟)
扩展性 差(上下文窗口瓶颈) 好(水平扩展 Agent 实例)
容错性 差(单点失败) 好(可降级、可重试单个 Agent)
评测成本 高(需评测单 Agent 能力 + 协作能力)

4. 拆分粒度的判断原则

不是拆得越细越好。判断粒度是否合适的标准:

  • 单一职责:一个 Agent 只做一件事,且这件事有明确的输入输出契约
  • 最小通信:Agent 之间交换的信息应该是"结论"而非"原始数据"
  • 可独立评测:每个 Agent 应该可以脱离系统单独测试
  • 失败可定位:当系统失败时,能快速定位到是哪个 Agent 的问题

反模式(不要这样做):

  • 为了"看起来架构高级"而拆(Over-engineering)
  • 拆完后每个 Agent 只做一次 LLM 调用(通信成本 > 计算成本)
  • 拆得太细导致需要 5+ 轮消息才能完成一个简单任务

5. 面试官常见深挖追问

  • "如果两个 Agent 需要共享大量上下文,是不是说明不该拆?"
    • 答:大概率是。如果两个 Agent 之间需要传递大量原始数据(而不是结论),说明它们的职责边界不清晰,或者任务本身不适合拆分。可以考虑:1)合并为一个 Agent;2)引入共享状态层(如数据库、缓存);3)重新划分职责,让信息在本地处理后再传递摘要。
  • "Multi-Agent 系统怎么防止'踢皮球'(互相推责、循环调用)?"
    • 答:1)明确每个 Agent 的决策权限和边界;2)设置全局超时和最大轮次;3)引入"调度者"角色统一协调,避免点对点随意调用;4)记录调用图谱,检测循环依赖;5)给每个 Agent 的响应增加"置信度"评分,低置信度时升级到人。
  • "如果有一个环节特别慢,会拖慢整个系统,怎么办?"
    • 答:1)识别瓶颈 Agent,考虑为其分配更强模型或更多资源;2)如果瓶颈是可并行的,改为异步执行(如同时启动多个检索 Agent);3)引入缓存,避免重复计算;4)考虑降级策略(如慢 Agent 超时后使用简化版本的结果);5)评估是否可以将该 Agent 的职责合并回主流程以减少通信开销。

#83. MCP / A2A 这种协议化尝试的价值是什么?为什么 2026 年大家开始关心它?

#标准答案

MCP、A2A 这类协议化尝试的价值,在于 Agent 生态已经从“单模型 + 几个私有工具”演化到“多个模型、多个执行端、多个资源系统、多个 Agent 之间协作”的阶段。如果没有统一协议,每接一个系统都要单独做适配,导致生态碎片化严重。

2026 年大家开始明显关心它,是因为问题已经从”能不能做出一个 Agent demo”变成了”怎么让大量 Agent、工具和上下文能力可复用、可互联、可治理”。协议化的意义,就是把接口、发现、权限、消息交换标准化,让系统从单点项目走向平台化。这类回答会比只说”它们让集成更方便”更有行业感。


#深度解析

1. 协议化解决的核心矛盾:从”点对点集成”到”生态网络”

没有协议时,N 个 Agent 对接 M 个工具需要 N×M 个适配器:

Agent A ──┬── Tool 1 (适配器 A-1)
          ├── Tool 2 (适配器 A-2)
          └── Tool 3 (适配器 A-3)
Agent B ──┬── Tool 1 (适配器 B-1)
          └── Tool 2 (适配器 B-2)
# 6 个适配器,维护成本 O(N×M)

有统一协议后,每个 Agent 和每个工具只需实现一次协议:

Agent A ── MCP/A2A 协议 ──┬── Tool 1
Agent B ──────────────────┼── Tool 2
                          └── Tool 3
# 每个组件实现一次协议,维护成本 O(N+M)

2. MCP 与 A2A 的定位差异

维度 MCP (Model Context Protocol) A2A (Agent-to-Agent)
设计方 Anthropic (2024) Google (2025)
核心目标 模型 ↔ 上下文源(工具/数据/文件)的标准化 Agent ↔ Agent 之间的协作与任务委托
协议层级 资源/工具/提示词三层抽象 能力发现、任务协商、状态同步
通信模式 请求-响应(同步) 支持异步、多轮、跨域
典型用例 IDE 里的代码补全 Agent 读文件系统 多个专业 Agent 协作完成复杂工作流

两者不是竞争关系而是互补:MCP 解决”Agent 怎么拿到上下文”,A2A 解决”Agent 怎么互相协作”。

3. 协议化的技术价值拆解

价值点 没有协议 有协议
工具发现 硬编码工具列表 运行时动态发现可用工具
权限控制 每个工具单独实现鉴权 统一身份/权限/审计
错误处理 各工具格式不一 标准化错误码和重试策略
上下文传递 手动序列化/反序列化 标准化消息格式(如 JSON-RPC)
可观测性 分散日志 统一追踪 ID、调用链

4. 为什么 2026 年这个时间点关键?

  • 数量拐点:企业级 Agent 从”个位数实验”到”数百个部署”,手动集成不可持续
  • 多模型共存:Claude、GPT、Gemini、开源模型混用,需要跨模型上下文标准
  • 安全合规:数据访问权限、审计日志、敏感操作拦截,需要协议层面的统一管控
  • 商业生态:协议标准化降低第三方接入门槛,类似 HTTP 催生了 Web 生态

5. 面试官常见深挖追问

  • ”MCP 和 Function Calling 有什么区别?”
    • 答:Function Calling 是模型能力(模型输出结构化 JSON 表示要调用的函数),MCP 是系统协议(定义模型如何发现、调用、接收工具结果的标准流程)。Function Calling 可以在 MCP 框架内使用,但 MCP 还包含资源发现、权限管理、多轮状态维护等更完整的生命周期。
  • ”协议化会不会限制创新,让所有 Agent 长得一样?”
    • 答:协议化约束的是接口而非实现。就像 HTTP 没有限制网站功能,TCP/IP 没有限制应用创新。协议化让互操作性成为可能,但每个 Agent 内部可以用完全不同的架构、模型和策略。实际上,协议化降低了实验门槛——你只需要符合接口规范,就能接入已有生态测试效果。

#84. Agent memory 该保留什么、不该保留什么?如何避免上下文膨胀和错误长期记忆?

#标准答案

Agent memory 不该追求“什么都记住”,而应该只保留高价值、可复用、相对稳定的信息。通常值得保留的是用户长期偏好、重要身份事实、稳定约束、重复任务经验;不该长期保留的是临时状态、噪声对话、一次性上下文、未经验证的推断,尤其不能把模型猜测当成事实写进长期记忆。

避免上下文膨胀和错误长期记忆,常见做法包括:把原始轨迹压缩成摘要;按短期/长期分层存储;给记忆加可信度和过期策略;只在关键事件发生时写记忆,而不是轮轮都写。面试里如果你能补一句”memory 不是越多越好,核心是写入门槛和读取策略”,会更完整。


#深度解析

1. Agent Memory 的分层架构模型

用户交互层
    ↓ (原始对话)
工作记忆 (Working Memory) — 当前 session 的完整上下文,窗口内
    ↓ (关键事件触发)
情节记忆 (Episodic Memory) — 压缩后的对话摘要、任务轨迹
    ↓ (长期价值判断)
语义记忆 (Semantic Memory) — 用户偏好、事实、规则、概念关系
    ↓ (知识沉淀)
程序记忆 (Procedural Memory) — 成功的任务模式、工具调用策略
层级 保留内容 保留时长 写入触发 读取方式
工作记忆 当前对话轮次、工具返回 当前 session 每轮自动 直接注入 prompt
情节记忆 任务摘要、成功/失败标记 数天-数周 任务完成时 相似度检索
语义记忆 用户偏好、身份事实、约束 永久 显式确认后 关键词/向量检索
程序记忆 可复用的任务模板、策略 永久 多次验证后 模式匹配

2. “该保留 vs 不该保留”的具体判断标准

保留 ✓ 不保留 ✗ 原因
用户确认过的身份(”我是医生”) 模型推断的身份(”你可能是医生”) 推断可能错误,确认降低幻觉风险
重复出现的偏好(”总是用 Python”) 一次性指令(”这次用 Python”) 一次性指令不应污染长期记忆
任务成功后的关键参数 失败轨迹的原始细节 保留教训摘要而非完整错误日志
稳定的领域约束(”合规要求”) 临时的业务规则(”本周促销”) 临时规则过期后会成为噪声
用户显式要求记住 模型”觉得有用”但没确认 写入门槛防止记忆膨胀

3. 上下文膨胀的量化与缓解

假设一个 Agent 每天与用户交互 50 轮,每轮平均 500 token:

策略 日存储量 30 天累积 检索效率
全量保留原始对话 25K token 750K token O(n) 线性扫描,极慢
每轮摘要(10:1 压缩) 2.5K token 75K token 向量检索,毫秒级
分层:工作+情节+语义 2.5K + 0.5K + 0.1K 15K + 15K + 3K 分层检索,精准定位
+ 过期策略(7 天清理) - 3.5K + 3.5K + 3K 常数级维护

关键原则:写入门槛 > 读取策略 > 存储格式。如果什么都写进去,再好的检索也救不了噪声。

4. 错误长期记忆的典型案例与防御

错误类型 例子 后果 防御措施
推断固化 用户问”假设我是 CEO”→记忆”用户是 CEO” 后续回答基于错误身份 标记假设性语句,不入长期记忆
错误归因 模型说错事实被用户纠正→记忆纠正内容但归因错误 知识关联错误 存储时关联证据来源和可信度
过时信息 “公司 CEO 是张三”(后来换了) 长期回答错误 TTL(Time-To-Live)过期机制
噪声累积 高频但低价值对话填满记忆 高价值信息被淹没 重要性打分,定期淘汰低分

5. 面试官常见深挖追问

  • ”如果用户说'你记错了',怎么修正长期记忆?”
    • 答:不能简单覆盖,因为需要区分是”本次纠正”还是”永久修正”。好的做法:1)给记忆条目打版本和可信度分数;2)用户纠正时降低旧条目分数、插入新条目;3)定期清理低可信度条目;4)关键事实要求用户确认后再写入长期记忆。同时记录”被纠正历史”本身也有价值——说明这个领域容易出错,后续可提升谨慎度。
  • ”Memory 和 RAG 知识库有什么区别?”
    • 答:RAG 知识库是”外部共享知识”(文档、FAQ、产品手册),Agent memory 是”交互中沉淀的个性化信息”(用户偏好、对话历史、任务经验)。技术上 RAG 通常用文档级向量检索,memory 用结构化/半结构化存储(如图数据库、键值对、向量混合)。两者互补:RAG 回答”是什么”,memory 回答”这个用户之前怎么做”。