Skip to content

Agent 面试专题 ​

AI Agent 面试主线:什么是 Agent → 架构组件 → 设计范式(ReAct/Plan-Execute/Reflection)→ 记忆机制 → 多 Agent 协作 → 工程实践。

Q1: 什么是 Agent?与大模型有什么本质不同? 「🟢 校招/初级」 ​

考察点:Agent 的基本概念和与 LLM 的区别。

参考答案:

Agent = LLM + 规划 + 记忆 + 工具 + 执行

大模型(LLM)是一个被动的文本生成器,你给它一个 Prompt,它返回一段文本,交互就结束了。而 Agent 是一个自主的 AI 系统,它能够感知环境、自主决策、调用工具、执行动作,并在多轮交互中完成复杂目标。

维度大模型(LLM)AI Agent
交互模式单轮:Prompt → Response多轮:目标 → 规划 → 执行 → 观察 → 调整
自主性被动响应,不会主动行动自主决策,能拆分任务、选择工具
记忆无状态(除上下文窗口)有长期/短期记忆,可跨会话
工具不能调用外部工具可调用搜索、代码执行、API 等
执行只输出文本能执行实际动作(发邮件、写文件等)
终止生成完就结束自主判断任务是否完成
python
# LLM:单轮交互
response = llm.chat("帮我订一张明天北京到上海的机票")
# → 返回一段文本:"好的,您可以..."(实际上什么都没做)

# Agent:自主执行
agent.run("帮我订一张明天北京到上海的机票")
# → 规划:1. 查航班 2. 选航班 3. 下单 4. 支付
# → 调用航班查询 API → 获得结果
# → 调用下单 API → 完成预订
# → 调用支付 API → 完成支付
# → "已为您预订明天 08:00 北京→上海 航班,订单号 XXX"

Agent 的核心特征:

  1. 自主性(Autonomy):不需要人类每步指挥,能自己规划并执行
  2. 反应性(Reactivity):能感知环境变化(工具返回的结果)并调整策略
  3. 主动性(Proactivity):不只是被动响应,能主动发起行动
  4. 社交性(Social Ability):多 Agent 场景下能与其他 Agent 协作

一句话总结:LLM 是 Agent 的「大脑」,但 Agent 不仅有大脑,还有手脚(工具)、记忆和规划能力。

追问延伸:

  • Agent 和传统的规则引擎/脚本有什么区别?(Agent 用 LLM 做决策,更灵活)
  • Copilot 算不算 Agent?(辅助型 Agent,自主性较低)

Q2: Agent 的基本架构由哪些核心组件构成? 「🟢 校招/初级」 ​

考察点:Agent 架构的系统性理解。

参考答案:

Agent 的经典架构包含 5 大核心组件:

┌─────────────────────────────────────────────────┐
│                   AI Agent                       │
│                                                  │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐      │
│  │  规划模块  │  │  记忆模块  │  │  工具模块  │      │
│  │ (Planning)│  │ (Memory) │  │ (Tools)  │      │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘      │
│       │              │              │             │
│       └──────────────┼──────────────┘             │
│                      │                           │
│              ┌───────┴───────┐                   │
│              │  LLM(大脑)   │                   │
│              └───────┬───────┘                   │
│                      │                           │
│              ┌───────┴───────┐                   │
│              │  执行模块(Action)│                   │
│              └───────────────┘                   │
└─────────────────────────────────────────────────┘

1. LLM(大脑):

  • Agent 的核心决策引擎
  • 负责理解任务、推理规划、生成行动指令
  • 选择什么模型决定 Agent 的能力上限

2. 规划模块(Planning):

  • 任务拆分:将复杂任务分解为子任务
  • 推理决策:决定下一步做什么
  • 反思调整:根据执行结果调整计划
用户目标:"写一篇关于 AI Agent 的技术博客"
  → 拆分:
    1. 搜索 AI Agent 最新资料
    2. 整理大纲
    3. 撰写初稿
    4. 校对润色
    5. 发布

3. 记忆模块(Memory):

  • 短期记忆:当前对话上下文(Context Window)
  • 长期记忆:历史交互、用户偏好、知识库(向量数据库)

4. 工具模块(Tools):

  • 搜索引擎、代码执行器、数据库查询
  • API 调用(天气、地图、支付等)
  • 文件操作(读写、创建)
python
# 工具定义示例
tools = [
    Tool(name="search", func=web_search, description="搜索网络信息"),
    Tool(name="python", func=code_execute, description="执行 Python 代码"),
    Tool(name="sql_query", func=db_query, description="查询数据库"),
]

5. 执行模块(Action):

  • 将 LLM 的决策转化为具体动作
  • 调用工具并获取结果
  • 将结果反馈给 LLM 进行下一步推理

核心循环(Agent Loop):

while not task_complete:
    1. LLM 思考 → 决定下一步行动
    2. 执行行动 → 调用工具
    3. 观察结果 → 工具返回
    4. 更新记忆 → 存入上下文
    5. 判断完成 → 是否达到目标

追问延伸:

  • 这 5 个组件中哪个最重要?(LLM 是上限,规划是下限,工具是能力边界)
  • 如果 LLM 能力不够强,怎么补偿?(更好的 Prompt + 更强的工具 + 更细的任务拆分)

Q3: Workflow,Agent,Tools 这三个的概念和区别介绍一下? 「🟡 中级」 ​

考察点:三个核心概念的辨析和关系理解。

参考答案:

概念本质特点类比
Tools能力扩展LLM 调用的具体函数/API工人的工具箱
Workflow固定流程预定义的步骤编排,路径确定流水线
Agent自主决策LLM 动态决定下一步做什么独立工作者

Tools(工具):

工具是 LLM 的「手和脚」,扩展了 LLM 的能力边界。

python
# 工具是最小单位
@tool
def search_web(query: str) -> str:
    """搜索网络获取最新信息"""
    return web_search(query)

@tool
def execute_code(code: str) -> str:
    """执行 Python 代码并返回结果"""
    return run_python(code)
  • 工具本身不做决策,只是执行
  • LLM 决定调用哪个工具、传什么参数
  • 工具是 Agent 和 Workflow 都可以使用的

Workflow(工作流):

Workflow 是预定义的流程编排,步骤和路径在运行前已确定。

RAG Workflow(固定流程):
  用户提问 → Query 改写 → 向量检索 → 重排序 → 组装 Prompt → LLM 生成 → 返回

每一步做什么、下一步走哪里,都是写死的。
python
# Workflow:路径固定,每一步都确定
def rag_workflow(query):
    rewritten = query_rewrite(query)        # Step 1
    docs = vector_search(rewritten)          # Step 2
    reranked = rerank(docs)                  # Step 3
    prompt = build_prompt(rewritten, reranked)  # Step 4
    answer = llm.generate(prompt)            # Step 5
    return answer

Agent(智能体):

Agent 是自主决策的系统,LLM 根据当前状态动态决定下一步做什么。

Agent(动态决策):
  用户提问 → LLM 思考:
    "这个问题需要查数据库" → 调用 SQL 工具
    "结果不够,再搜一下" → 调用搜索工具
    "数据拿到了,分析一下" → 调用代码执行工具
    "结果不对,换个方法" → 调整策略
    "好了,可以回答了" → 生成最终回答

三者的关系:

Tools ⊂ Agent    (Agent 使用工具)
Tools ⊂ Workflow  (Workflow 使用工具)
Agent ≠ Workflow  (决策方式不同)

Agent:LLM 决定流程(动态)
Workflow:人决定流程(静态)
两者都可以调用 Tools
维度WorkflowAgent
决策方式预定义,路径固定LLM 动态决策,路径不确定
可控性高(每步可预测)低(LLM 可能走偏)
灵活性低(新场景需改代码)高(LLM 自适应)
适用场景流程明确的重复任务开放式、复杂任务
调试难度低(确定路径)高(非确定路径)
成本低(固定 LLM 调用次数)高(循环调用,次数不定)

实际选型建议:

流程明确 → Workflow(如 RAG、文档摘要)
流程不明确 → Agent(如研究分析、复杂任务)
混合 → Workflow + Agent(主流程用 Workflow,子任务用 Agent)

追问延伸:

  • 能不能在 Workflow 里嵌套 Agent?(可以,子任务交给 Agent)
  • 为什么不全都用 Agent?(成本高、可控性差、延迟大)

Q4: 了解哪些其他的 Agent 设计范式?Agent 和 Workflow 的区别是什么? 「🟡 中级」 ​

考察点:Agent 设计范式的广度和深度理解。

参考答案:

主流 Agent 设计范式:

范式核心思想代表适用场景
ReAct推理+行动交替Thought→Action→Observation通用任务
Plan-and-Execute先规划再执行Plan → Execute step by step复杂多步任务
Reflection自我反思改进Generate → Critique → Improve质量要求高
Tool-Use工具调用Function Calling / MCP需要外部能力
Multi-Agent多角色协作Coder + Reviewer + Tester复杂工程项目
Router路由分发分类 → 对应 Agent多领域问答
Chain链式调用A → B → C线性流程

各范式详解:

1. ReAct(Reasoning + Acting):

Thought: 用户想知道明天的天气,我需要调用天气 API
Action: get_weather(city="北京")
Observation: 明天北京晴,25-35°C
Thought: 获得了天气信息,可以回答用户了
Answer: 明天北京晴天,气温 25-35 度,适合出行。

2. Plan-and-Execute:

Plan:
  1. 搜索 AI Agent 最新论文
  2. 提取关键技术点
  3. 对比现有方案
  4. 撰写综述

Execute:
  Step 1: search("AI Agent 2025") → 10 篇论文
  Step 2: extract_keypoints(papers) → 5 个技术点
  Step 3: compare(existing_solutions, keypoints) → 对比表
  Step 4: write_summary(comparison) → 综述文档

3. Reflection(反思):

Generate: 写了一段代码
Critique: 检查代码,发现没有处理异常
Improve: 加入 try-catch 异常处理
Critique: 再次检查,发现性能可以优化
Improve: 优化算法复杂度
→ 最终输出

4. Multi-Agent:

用户:"帮我开发一个 Web API"

Planner Agent → 拆分任务
Coder Agent → 编写代码
Reviewer Agent → 代码审查
Tester Agent → 编写测试
Deployer Agent → 部署上线

Agent 和 Workflow 的核心区别:

Workflow(确定性流程):
  定义:A → B → C → D(路径写死)
  特点:可复现、可预测、可调试
  LLM 角色:流程中的某个节点

Agent(非确定性流程):
  定义:LLM 决定 A → ? → ? → 完成(路径动态)
  特点:灵活、自适应、但不可预测
  LLM 角色:决策中枢,控制流程走向
维度WorkflowAgent
控制流代码控制LLM 控制
确定性确定(同样输入→同样输出)不确定(LLM 可能走不同路径)
错误处理预定义的异常分支LLM 自主决定如何处理
成本固定(N 步 = N 次 LLM 调用)不固定(可能循环很多次)
适用场景流程明确、重复执行开放式、探索性

实际项目中的选择:

能用 Workflow 解决的 → 用 Workflow(成本低、可控)
Workflow 不够的 → 加 Agent(在关键决策点引入 LLM 动态决策)
两者结合 → Workflow 做主流程,Agent 做子任务

追问延伸:

  • ReAct 和 Plan-and-Execute 能不能结合?(先规划,执行时用 ReAct)
  • 什么场景下 Agent 比 Workflow 好很多?(需要根据中间结果动态调整策略时)

Q5: Agent 推理模式有哪些?ReAct 是啥?具体是怎么实现的? 「🟡 中级」 ​

考察点:ReAct 范式的原理和实现细节。

参考答案:

Agent 推理模式总览:

推理模式核心思想循环结构
ReAct推理与行动交替Thought → Action → Observation
Plan-and-Execute先全局规划,再逐步执行Plan → Execute (→ Replan)
Reflection生成后反思改进Generate → Critique → Refine
Chain-of-Thought链式思维推理Step1 → Step2 → Step3
Tree-of-Thought树状多路径探索分支 → 评估 → 剪枝 → 最优路径

ReAct(Reasoning + Acting)详解:

ReAct 的核心思想是让 LLM 交替进行推理(Thought)和行动(Action),根据行动的观察结果(Observation)决定下一步推理。

ReAct 循环:

Thought 1 → Action 1 → Observation 1
                                    ↓
Thought 2 → Action 2 → Observation 2
                                    ↓
Thought 3 → Action 3 → Observation 3
                                    ↓
Thought N → Final Answer

ReAct 的 Prompt 模板:

You are an AI assistant. Use the following tools to answer the question.

Available tools:
- search(query): Search the web
- calculator(expression): Calculate math
- python(code): Execute Python code

Question: {user_question}

Follow this format:
Thought: <your reasoning>
Action: <tool_name>(<arguments>)
Observation: <tool result>
... (repeat as needed)
Thought: I now know the answer
Final Answer: <your answer>

ReAct 具体实现示例:

python
import re

class ReActAgent:
    def __init__(self, llm, tools):
        self.llm = llm
        self.tools = {t.name: t for t in tools}
        self.max_iterations = 10

    def run(self, question):
        prompt = self._build_prompt(question)
        history = ""

        for i in range(self.max_iterations):
            # LLM 生成 Thought + Action
            response = self.llm.generate(prompt + history)

            # 解析 Action
            action_match = re.search(r'Action:\s*(\w+)\((.*?)\)', response)
            if not action_match:
                # 没有 Action,说明是最终回答
                final_answer = re.search(r'Final Answer:\s*(.*)', response)
                return final_answer.group(1) if final_answer else response

            tool_name = action_match.group(1)
            tool_args = action_match.group(2)

            # 执行工具
            if tool_name in self.tools:
                observation = self.tools[tool_name].run(tool_args)
            else:
                observation = f"Error: Tool '{tool_name}' not found"

            # 拼接历史
            history += f"\n{response}\nObservation: {observation}\n"

        return "Max iterations reached without final answer"

    def _build_prompt(self, question):
        tools_desc = "\n".join(
            f"- {t.name}({t.args}): {t.description}"
            for t in self.tools.values()
        )
        return f"""You are an AI assistant. Use tools to answer.

Available tools:
{tools_desc}

Question: {question}

Follow this format:
Thought: <reasoning>
Action: <tool>(<args>)
Observation: <result>
...(repeat)
Final Answer: <answer>
"""

ReAct 的优缺点:

优点缺点
推理过程透明可解释每步都要 LLM 调用,成本高
能根据中间结果调整策略可能陷入循环(重复调用同一工具)
通用性强,适合多种任务依赖 LLM 的指令遵循能力
错误可追溯(看每步 Thought)延迟高(串行执行)

ReAct 的变体:

标准 ReAct:Thought → Action → Observation
带反思的 ReAct:Thought → Action → Observation → Reflection → Adjustment
带记忆的 ReAct:历史记忆 + 当前 Thought → 更好的决策
带规划的 ReAct:先 Plan,再对每个子任务用 ReAct

追问延伸:

  • ReAct 为什么比纯 CoT 好?(CoT 只推理不行动,ReAct 能与环境交互)
  • ReAct 的最大瓶颈是什么?(LLM 的指令遵循能力、循环终止判断)

Q6: ReAct、Plan-and-Execute、Reflection 三种范式有什么核心区别?实际项目中该如何选型? 「🔴 高级」 ​

考察点:三种范式的深度对比和工程选型能力。

参考答案:

三种范式的核心对比:

维度ReActPlan-and-ExecuteReflection
核心思想边想边做先想后做做完再改
决策粒度每步决策先全局规划事后改进
LLM 调用次数多(每步一次)少(规划一次+执行多次)最多(生成+批判+改进)
延迟高(串行循环)中(并行执行)最高(多轮改进)
成本高中最高
质量中中高(多次改进)
可控性低(动态路径)高(有明确计划)中

ReAct 详解:

特点:一步一决策,走一步看一步

适用:信息不完全、需要探索的任务
示例:搜索+分析+综合 → 研究型任务

User: "分析 2025 年 AI Agent 领域的技术趋势"
Thought: 先搜索最新信息
Action: search("AI Agent 2025 trends")
Observation: [10 篇文章]
Thought: 读取关键文章
Action: read_article(url)
Observation: [文章内容]
Thought: 信息足够了,综合分析
Final Answer: ...

Plan-and-Execute 详解:

特点:先制定完整计划,再逐步执行

适用:任务复杂但结构清晰
示例:开发+测试+部署 → 工程型任务

Plan:
  1. 搜索需求文档
  2. 设计 API 接口
  3. 编写代码
  4. 编写测试
  5. 部署

Execute:
  Step 1: search() → 完成
  Step 2: design() → 完成
  Step 3: code() → 失败!→ Replan
    New Plan: 3a. 修复依赖 → 3b. 编写代码
  Step 3a: fix() → 完成
  Step 3b: code() → 完成
  Step 4: test() → 完成
  Step 5: deploy() → 完成

Reflection 详解:

特点:生成 → 自我批判 → 改进

适用:质量要求高的任务
示例:代码编写、文档撰写

Generate:
  "这是一个快速排序的实现..."
Critique:
  "代码缺少边界条件处理,数组为空时会报错"
  "变量命名不够清晰"
  "没有注释"
Improve:
  "修复了边界条件..."
Critique:
  "可以进一步优化空间复杂度"
Improve:
  "使用原地排序..."
→ 最终版本

选型决策树:

任务特点是什么?
├── 需要探索,信息逐步获取 → ReAct
├── 任务复杂但结构清晰 → Plan-and-Execute
├── 质量要求极高 → Reflection
└── 多种特点都有 → 组合使用
    └── Plan-and-Execute + ReAct(子任务)+ Reflection(关键步骤)

实际项目选型示例:

场景推荐范式原因
搜索+综合分析ReAct需要根据搜索结果决定下一步
自动化开发Plan-and-Execute开发流程明确(设计→编码→测试)
代码质量保证Reflection需要多次改进达到高质量
客服 AgentReAct根据用户反馈动态响应
报告生成Plan + ReAct先规划大纲,每部分用 ReAct 撰写
数学解题CoT + ReAct推理+计算器工具交替

组合范式实践:

python
class HybridAgent:
    def run(self, task):
        # 1. Plan-and-Execute:先规划
        plan = self.planner.create_plan(task)

        results = []
        for step in plan.steps:
            # 2. ReAct:每个子任务用 ReAct 执行
            result = self.react_agent.run(step)

            # 3. Reflection:关键步骤反思改进
            if step.requires_high_quality:
                result = self.reflector.improve(result)

            results.append(result)

            # 4. Replan:如果执行失败,重新规划
            if result.failed:
                plan = self.planner.replan(task, results)

        return self.synthesize(results)

追问延伸:

  • Reflection 能不能用另一个 LLM 来做批判?(可以,Cross-Model Critique)
  • Plan-and-Execute 在什么情况下需要 Replan?(执行结果与预期不符时)

Q7: 复杂任务怎么做的任务拆分?为什么要拆分?效果如何提升? 「🔴 高级」 ​

考察点:任务拆分策略和工程效果评估。

参考答案:

为什么要拆分:

不拆分的问题:
  1. LLM 上下文有限 → 复杂任务信息量超出 Context Window
  2. 单次生成质量低 → 任务越复杂,LLM 越容易遗漏或出错
  3. 不可控 → 一次性生成,出错无法定位和修复
  4. 不可并行 → 串行执行,延迟高
  5. 不可复用 → 每次从头开始

拆分后的好处:
  1. 每个子任务聚焦 → LLM 在小任务上质量更高
  2. 可并行 → 多个子任务同时执行
  3. 可控 → 每步可检查、可回退
  4. 可复用 → 相同子任务可缓存
  5. 可组合 → 不同子任务用不同 Agent/工具

任务拆分策略:

1. 按流程拆分(Pipeline Decomposition):

任务:写一篇技术博客
拆分:
  1. 调研 → 搜索资料、整理要点
  2. 大纲 → 列出文章结构
  3. 初稿 → 逐段撰写
  4. 校对 → 检查错误
  5. 润色 → 优化表达
  6. 发布

2. 按维度拆分(Dimensional Decomposition):

任务:分析一个公司
拆分:
  1. 财务分析 → 营收、利润、现金流
  2. 技术分析 → 技术栈、专利、研发投入
  3. 市场分析 → 市场份额、竞争对手
  4. 管理分析 → 组织架构、人才
  → 最后综合

3. 递归拆分(Recursive Decomposition):

任务:开发一个 Web 应用
  ├── 1. 后端开发
  │   ├── 1.1 API 设计
  │   ├── 1.2 数据库设计
  │   ├── 1.3 业务逻辑
  │   └── 1.4 接口测试
  ├── 2. 前端开发
  │   ├── 2.1 页面设计
  │   ├── 2.2 组件开发
  │   └── 2.3 状态管理
  └── 3. 部署运维
      ├── 3.1 CI/CD
      └── 3.2 监控告警

4. 按依赖关系拆分(Dependency-based):

任务链:A → B(依赖 A)→ C(依赖 B)→ D(依赖 B)
并行:A → B → [C || D] → 合并

任务图:
  A → B → C
        ↘ D
  A、B 串行;C、D 并行

LLM 做任务拆分的 Prompt:

你是一个任务规划专家。请将以下任务拆分为可执行的子任务。

任务:{task}

要求:
1. 每个子任务明确、可执行、可验证
2. 标注子任务之间的依赖关系
3. 标注哪些子任务可以并行
4. 为每个子任务推荐合适的工具/方法

输出格式:
[
  {
    "id": 1,
    "task": "...",
    "depends_on": [],
    "parallel_with": [],
    "tool": "...",
    "verify": "..."
  }
]

拆分粒度的权衡:

粒度太粗:
  子任务仍然复杂 → LLM 质量不高
  → 需要继续拆

粒度太细:
  管理开销大 → 大量 LLM 调用
  上下文丢失 → 子任务间信息传递困难
  → 合并相近任务

经验法则:
  - 每个子任务可在 1-3 次 LLM 调用内完成
  - 每个子任务有明确的成功标准
  - 子任务数量 3-7 个为宜(不超过 10)

效果提升的量化:

指标不拆分拆分后提升
任务完成率40-60%70-90%+30%
输出质量6/108/10+33%
错误定位不可定位精确定位到子任务-
并行执行不支持多子任务并行延迟 -40%
可复用性无相同子任务可缓存成本 -20%

追问延伸:

  • 拆分后子任务的结果怎么传递?(上下文传递 / 共享状态 / 消息传递)
  • 拆分的子任务失败了怎么办?(重试 / Replan / 降级 / 人工介入)

Q8: 请你介绍一下 AI Agent 的记忆机制,并说明在实际开发中应该如何设计记忆模块? 「🔴 高级」 ​

考察点:Agent 记忆系统的设计和工程实践。

参考答案:

人类记忆 → Agent 记忆的映射:

人类记忆Agent 记忆存储持久化
工作记忆(短期)上下文窗口LLM Context会话内
情景记忆对话历史数据库/向量库跨会话
语义记忆知识库向量数据库长期
程序记忆技能/工具代码/配置永久

Agent 记忆的三个层次:

┌──────────────────────────────────┐
│  短期记忆(Working Memory)       │ ← LLM 上下文窗口
│  - 当前对话上下文                  │
│  - 当前任务状态                    │
│  - 最近几轮交互                    │
├──────────────────────────────────┤
│  中期记忆(Episodic Memory)       │ ← 对话历史存储
│  - 本次会话的完整历史              │
│  - 之前的任务执行记录              │
├──────────────────────────────────┤
│  长期记忆(Long-term Memory)     │ ← 向量数据库
│  - 用户偏好和习惯                  │
│  - 历史交互摘要                    │
│  - 知识库                         │
└──────────────────────────────────┘

记忆模块设计:

python
from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional

@dataclass
class Memory:
    content: str
    timestamp: datetime = field(default_factory=datetime.now)
    importance: float = 0.5  # 0-1,重要性分数
    embedding: Optional[list] = None  # 向量表示
    metadata: dict = field(default_factory=dict)  # 额外信息

class AgentMemory:
    def __init__(self, llm, vector_store):
        self.short_term = []  # 短期:列表
        self.episodic = []    # 中期:对话历史
        self.long_term = vector_store  # 长期:向量库
        self.llm = llm

    def add(self, content, importance=0.5, **metadata):
        """添加记忆"""
        mem = Memory(
            content=content,
            importance=importance,
            metadata=metadata
        )
        # 短期记忆直接加入
        self.short_term.append(mem)
        # 重要的记忆同时存入长期
        if importance > 0.7:
            mem.embedding = self.llm.embed(content)
            self.long_term.add(mem)

    def recall(self, query, top_k=5):
        """回忆相关记忆"""
        # 从短期记忆中取最近 N 条
        recent = self.short_term[-top_k:]

        # 从长期记忆中检索相关内容
        query_embedding = self.llm.embed(query)
        long_term_results = self.long_term.search(
            query_embedding, top_k=top_k
        )

        # 合并 + 去重 + 按重要性排序
        all_memories = recent + long_term_results
        all_memories.sort(key=lambda m: m.importance, reverse=True)
        return all_memories[:top_k]

    def compress(self):
        """压缩短期记忆到中期"""
        if len(self.short_term) > 20:
            # 用 LLM 总结近期记忆
            summary = self.llm.generate(
                f"总结以下内容的关键信息:\n"
                f{chr(10).join(m.content for m in self.short_term)}"
            )
            self.episodic.append(Memory(
                content=summary,
                importance=0.8,
                metadata={"type": "summary"}
            ))
            # 只保留最近 5 条
            self.short_term = self.short_term[-5:]

    def forget(self):
        """遗忘机制:删除低重要性记忆"""
        self.short_term = [
            m for m in self.short_term if m.importance > 0.3
        ]

记忆的存储介质:

记忆类型存储介质检索方式特点
短期内存/Context直接访问快但容量有限
中期Redis/数据库时间排序可持久化
长期向量数据库语义检索容量大但检索有延迟

记忆的写入策略:

什么信息值得记住?
  1. 用户明确要求记住的 → "记住我喜欢简洁风格"
  2. 关键决策和结果 → "选择了方案 A 因为..."
  3. 错误和教训 → "上次用 X 方法失败了"
  4. 用户偏好 → 从交互中推断
  5. 任务执行过程 → 成功的执行路径

什么信息可以遗忘?
  1. 重复信息 → 合并去重
  2. 过时信息 → "当前时间是 2024 年"(过了就无意义)
  3. 低重要性信息 → "好的" "收到" 等无实质内容

追问延伸:

  • 记忆太多导致检索变慢怎么办?(压缩 + 分层 + 索引优化)
  • 怎么衡量记忆系统的效果?(记忆命中率、任务完成率提升)

Q9: Agent 的长短期记忆系统怎么做的?记忆是怎么存的?粒度是多少?怎么用的? 「🔴 高级」 ​

考察点:记忆系统的工程实现细节。

参考答案:

短期记忆实现:

短期记忆 = LLM 上下文窗口

存储:LLM 的 Context(无独立存储,就是 Prompt 的一部分)
粒度:每轮对话(user message + assistant message + tool result)
容量:受 LLM 上下文窗口限制(4K-200K tokens)
淘汰:FIFO(超出窗口的从前面截断)
python
class ShortTermMemory:
    def __init__(self, max_tokens=8000):
        self.messages = []
        self.max_tokens = max_tokens

    def add(self, role, content):
        self.messages.append({"role": role, "content": content})
        self._truncate()

    def _truncate(self):
        """超出 token 限制时截断旧消息"""
        while self._count_tokens() > self.max_tokens and len(self.messages) > 2:
            # 保留第一条(系统提示)和最近的
            self.messages.pop(1)  # 删除第二条

    def _count_tokens(self):
        return sum(len(m["content"]) // 4 for m in self.messages)

    def get_context(self):
        return self.messages

长期记忆实现:

长期记忆 = 向量数据库 + 结构化存储

存储介质:
  - 向量数据库(Milvus/Pinecone/Chroma)→ 语义记忆
  - 关系数据库(PostgreSQL)→ 结构化记忆(用户偏好、任务记录)
  - 图数据库(Neo4j)→ 关系记忆(实体关系、知识图谱)

存储粒度:
  - 粗粒度:整个对话/文档 → 检索准确度低,但数量少
  - 细粒度:每句话/每个事实 → 检索准确度高,但数量多
  - 推荐:中等粒度(一个事实/一段交互 = 一条记忆)
python
class LongTermMemory:
    def __init__(self, embed_model, vector_store, db):
        self.embed_model = embed_model
        self.vector_store = vector_store  # 向量库
        self.db = db  # 结构化存储

    def store(self, content, mem_type="episodic", **metadata):
        """存储长期记忆"""
        # 1. 生成 embedding
        embedding = self.embed_model.embed(content)

        # 2. 存入向量库(语义检索用)
        vec_id = self.vector_store.add(
            embedding=embedding,
            payload={
                "content": content,
                "type": mem_type,
                "timestamp": datetime.now().isoformat(),
                **metadata
            }
        )

        # 3. 同时存入关系库(精确查询用)
        self.db.execute(
            "INSERT INTO memories (id, content, type, metadata) VALUES (?, ?, ?, ?)",
            (vec_id, content, mem_type, json.dumps(metadata))
        )

    def retrieve(self, query, top_k=5, mem_type=None):
        """检索长期记忆"""
        # 1. 向量语义检索
        query_emb = self.embed_model.embed(query)
        results = self.vector_store.search(
            query_emb,
            top_k=top_k,
            filter={"type": mem_type} if mem_type else None
        )

        # 2. 可选:关键词补充检索(混合检索)
        keyword_results = self.db.execute(
            "SELECT * FROM memories WHERE content LIKE ? LIMIT ?",
            (f"%{query}%", top_k)
        )

        # 3. 合并 + 去重 + 重排序
        return self._merge_and_rerank(results, keyword_results)

记忆的使用方式:

python
class AgentWithMemory:
    def __init__(self, llm, memory):
        self.llm = llm
        self.memory = memory  # AgentMemory 实例

    def chat(self, user_input):
        # 1. 从长期记忆中检索相关信息
        relevant_memories = self.memory.recall(user_input, top_k=5)
        memory_context = "\n".join(
            f"- {m.content}" for m in relevant_memories
        )

        # 2. 获取短期记忆(当前对话上下文)
        short_term = self.memory.get_short_term()

        # 3. 组装 Prompt
        prompt = f"""
系统:你是一个有记忆的 AI 助手。

相关记忆:
{memory_context}

对话历史:
{short_term}

用户:{user_input}
"""

        # 4. LLM 生成
        response = self.llm.generate(prompt)

        # 5. 存入记忆
        self.memory.add(user_input, importance=0.5, type="user")
        self.memory.add(response, importance=0.6, type="assistant")

        # 6. 定期压缩
        self.memory.compress()

        return response

记忆粒度的选择:

粒度内容示例适用场景
对话级整轮对话"用户问了 X,我回答了 Y"简单对话
事实级单个事实"用户偏好简洁回答"知识型记忆
动作级每个动作"调用了搜索工具,找到了 X"执行过程
摘要级多轮摘要"讨论了 AI Agent 架构设计"长期归档

推荐粒度:事实级 + 动作级混合

一条记忆 = 一个事实/一个动作 + 上下文 + 时间戳 + 重要性

示例记忆条目:
{
  "content": "用户是 Java 开发者,偏好使用 Spring AI 框架",
  "type": "preference",
  "timestamp": "2025-08-25T10:00:00",
  "importance": 0.8,
  "source": "inferred_from_interaction"
}

追问延伸:

  • 怎么给记忆打重要性分数?(LLM 评估 + 频率 + 时效性)
  • 记忆冲突怎么办?(最新优先 + 来源可信度 + 人工确认)

Q10: 什么是 Multi-Agent? 「🟢 校招/初级」 ​

考察点:Multi-Agent 的基本概念。

参考答案:

Multi-Agent = 多个 Agent 协作完成一个复杂任务

Single-Agent:一个 Agent 做所有事
  User → Agent(规划+执行+检查)→ Result

Multi-Agent:多个 Agent 分工协作
  User → Planner Agent → Coder Agent → Reviewer Agent → Tester Agent → Result

为什么需要 Multi-Agent:

原因说明
单 Agent 能力有限一个 Agent 难以精通所有领域
上下文限制复杂任务信息量超出单个 Context
专注度每个 Agent 只负责一件事,质量更高
并行执行多个 Agent 可以同时工作
角色分离规划、执行、审查分离,互相制约
可扩展性新增能力只需增加新 Agent

Multi-Agent 的常见模式:

1. 线性流水线模式:
  Agent A → Agent B → Agent C → Result
  (每个 Agent 负责一个阶段)

2. 协作讨论模式:
  Agent A ←→ Agent B ←→ Agent C
  (多轮讨论达成共识)

3. 主管-工人模式:
  Supervisor Agent
    ├── Worker Agent 1
    ├── Worker Agent 2
    └── Worker Agent 3
  (主管分发任务,工人执行)

4. 竞争模式:
  Agent A → Result A
  Agent B → Result B  → 选最好的
  Agent C → Result C
  (多个 Agent 各自完成,选最优)

5. 层级模式:
  CEO Agent
    ├── Manager Agent 1
    │     ├── Worker Agent 1
    │     └── Worker Agent 2
    └── Manager Agent 2
          └── Worker Agent 3

Multi-Agent 框架对比:

框架特点语言适用场景
AutoGen对话式多 AgentPython研究、原型
CrewAI角色扮演式Python团队协作模拟
MetaGPTSOP 驱动Python软件开发
LangGraph图状态机Python/JS复杂流程控制
LangChain4jJava 生态Java企业级应用

一个 Multi-Agent 示例:

python
# 软件开发 Multi-Agent 系统
class DevTeam:
    def __init__(self):
        self.product_manager = Agent(
            role="产品经理",
            goal="明确需求,输出 PRD",
            tools=["search", "write_doc"]
        )
        self.architect = Agent(
            role="架构师",
            goal="设计技术方案",
            tools=["search", "draw_diagram", "write_doc"]
        )
        self.developer = Agent(
            role="开发工程师",
            goal="编写代码",
            tools=["code_editor", "search", "test_runner"]
        )
        self.tester = Agent(
            role="测试工程师",
            goal="编写和执行测试",
            tools=["test_runner", "bug_reporter"]
        )

    def run(self, requirement):
        # 1. 产品经理出 PRD
        prd = self.product_manager.run(f"分析需求:{requirement}")

        # 2. 架构师出方案
        design = self.architect.run(f"根据 PRD 设计方案:{prd}")

        # 3. 开发编码
        code = self.developer.run(f"根据设计编写代码:{design}")

        # 4. 测试验证
        test_result = self.tester.run(f"测试代码:{code}")

        # 5. 根据测试结果决定是否返工
        if test_result.has_bugs:
            code = self.developer.run(f"修复 bug:{test_result.bugs}")

        return {"prd": prd, "design": design, "code": code, "test": test_result}

追问延伸:

  • Multi-Agent 怎么保证一致性?(共享状态 + 消息传递 + 冲突检测)
  • 多 Agent 通信成本怎么控制?(控制 Agent 数量 + 共享 Context + 消息压缩)

Q11: 说说 Single-Agent 和 Multi-Agent 的设计方案? 「🔴 高级」 ​

考察点:单/多 Agent 架构的对比和方案设计。

参考答案:

Single-Agent 设计方案:

┌────────────────────────────────────┐
│          Single-Agent              │
│                                    │
│  ┌──────────────────────────────┐  │
│  │         LLM(大脑)           │  │
│  │  规划 + 推理 + 决策           │  │
│  └──────────┬───────────────────┘  │
│             │                      │
│  ┌──────────┴───────────────────┐  │
│  │         工具集                 │  │
│  │  搜索 | 代码 | SQL | API     │  │
│  └──────────────────────────────┘  │
│                                    │
│  ┌──────────────────────────────┐  │
│  │         记忆                   │  │
│  │  短期(上下文) + 长期(向量库)│  │
│  └──────────────────────────────┘  │
└────────────────────────────────────┘
python
# Single-Agent:一个 Agent 通过 ReAct 循环完成所有任务
class SingleAgent:
    def __init__(self, llm, tools, memory):
        self.llm = llm
        self.tools = tools  # 丰富的工具集
        self.memory = memory
        self.max_steps = 15

    def run(self, task):
        for step in range(self.max_steps):
            # 1. 检索记忆
            context = self.memory.recall(task)

            # 2. LLM 决策下一步
            thought, action = self.llm.decide(task, context, self.history)

            # 3. 执行工具
            if action is None:
                return thought  # 最终回答

            result = self.tools[action.name].run(action.args)

            # 4. 记录历史
            self.history.append((thought, action, result))

        return "达到最大步数限制"

Single-Agent 的特点:

优点缺点
架构简单单个 LLM 上下文限制
调试方便难以处理多领域复杂任务
成本可控串行执行,延迟高
状态管理简单Agent 角色冲突(又要规划又要执行)
无通信开销无法并行

Multi-Agent 设计方案:

┌──────────────────────────────────────────────┐
│                Multi-Agent                    │
│                                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
│  │ Planner  │  │ Executor │  │ Reviewer │  │
│  │  Agent   │  │  Agent   │  │  Agent   │  │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  │
│       │              │              │        │
│       └──────────────┼──────────────┘        │
│                      │                      │
│              ┌───────┴───────┐              │
│              │  共享状态/消息总线 │              │
│              └───────────────┘              │
│                                              │
│  ┌──────────────────────────────────────┐   │
│  │  工具池(共享或独立)                  │   │
│  └──────────────────────────────────────┘   │
└──────────────────────────────────────────────┘
python
# Multi-Agent:Supervisor 模式
class MultiAgentSystem:
    def __init__(self, llm):
        self.supervisor = Agent(
            llm=llm,
            role="Supervisor",
            system_prompt="你是任务管理者,负责拆分任务和分发给合适的 Agent"
        )
        self.workers = {
            "researcher": Agent(
                llm=llm,
                role="Researcher",
                tools=["search", "read_url"],
                system_prompt="你是研究员,擅长搜索和整理信息"
            ),
            "coder": Agent(
                llm=llm,
                role="Coder",
                tools=["code_execute", "file_write"],
                system_prompt="你是程序员,擅长编写和调试代码"
            ),
            "writer": Agent(
                llm=llm,
                role="Writer",
                tools=["search"],
                system_prompt="你是技术作家,擅长撰写文档"
            ),
        }
        self.shared_state = {}  # 共享状态

    def run(self, task):
        # 1. Supervisor 拆分任务并分配
        plan = self.supervisor.run(
            f"将以下任务拆分并分配给 researcher/coder/writer:\n{task}"
        )

        # 2. 并行执行可并行的子任务
        results = {}
        for subtask in plan.subtasks:
            agent = self.workers[subtask.assigned_to]
            result = agent.run(subtask.description)
            results[subtask.id] = result
            self.shared_state[subtask.id] = result

        # 3. Supervisor 综合结果
        final = self.supervisor.run(
            f"综合以下结果给出最终回答:\n{results}"
        )
        return final

对比分析:

维度Single-AgentMulti-Agent
架构复杂度低高
开发成本低高
任务质量中(单 Agent 精力分散)高(每个 Agent 专注)
延迟高(串行)可并行降低延迟
LLM 调用成本中(单循环)高(多 Agent + 通信)
调试难度低高(多 Agent 状态追踪)
上下文利用集中分散(每个 Agent 有自己的上下文)
适用任务中等复杂度高复杂度、多领域

选型建议:

选 Single-Agent:
  - 任务步骤 < 10 步
  - 单一领域
  - 快速原型验证
  - 成本敏感

选 Multi-Agent:
  - 任务复杂度高(需要多种能力)
  - 多领域知识(搜索+编码+写作)
  - 需要并行
  - 质量要求高(有 Reviewer)
  - 可接受较高成本

追问延伸:

  • 多 Agent 之间怎么通信?(消息传递 / 共享内存 / 黑板模式)
  • 怎么避免 Multi-Agent 陷入死循环?(设置最大轮数 + 超时 + 冲突检测)

Q12: Agent 记忆压缩通常有哪些方法? 「🟡 中级」 ​

考察点:记忆压缩策略的系统性理解。

参考答案:

记忆压缩的目的是在有限的上下文窗口内保留最重要的信息。

1. 摘要压缩(Summarization):

原始记忆(10 条对话):
  User: 帮我设计一个用户注册系统
  Assistant: 好的,需要哪些字段?
  User: 用户名、密码、邮箱、手机号
  Assistant: 建议用 BCrypt 加密密码...
  User: 用什么数据库?
  Assistant: 推荐 PostgreSQL...
  ...(还有 5 条)

压缩后(1 条摘要):
  "讨论了用户注册系统设计:字段包括用户名/密码/邮箱/手机号,
   密码用 BCrypt 加密,数据库选 PostgreSQL"
python
def summarize_memories(memories, llm):
    """用 LLM 将多条记忆压缩为摘要"""
    combined = "\n".join(f"- {m.content}" for m in memories)
    summary = llm.generate(
        f"请将以下对话记录压缩为关键信息摘要,保留重要事实和决策:\n{combined}"
    )
    return Memory(content=summary, type="summary")

2. 提取压缩(Extraction):

原始记忆:
  "用户问了很多关于 RAG 的问题,包括文档切割策略、向量检索优化、
   重排序方法,还讨论了评估指标"

提取后:
  - 用户关注领域:RAG
  - 讨论要点:文档切割、向量检索、重排序、评估指标
  - 用户水平:中高级(问题较深入)
python
def extract_key_info(memories, llm):
    """提取结构化关键信息"""
    extraction_prompt = """
    从以下对话中提取关键信息,格式:
    - 用户偏好:
    - 关键决策:
    - 重要事实:
    - 待办事项:
    """
    return llm.generate(extraction_prompt + "\n".join(m.content for m in memories))

3. 滑动窗口(Sliding Window):

保留最近 N 轮对话,丢弃更早的

记忆队列:[m1, m2, m3, m4, m5, m6, m7, m8]
窗口大小 = 5

保留:[m4, m5, m6, m7, m8]
丢弃:[m1, m2, m3] → 但可以先压缩后存入长期记忆

4. 重要性过滤(Importance Filtering):

所有记忆都有重要性分数(0-1)

过滤前:[m1(0.3), m2(0.8), m3(0.5), m4(0.9), m5(0.2), m6(0.7)]
阈值 = 0.6
过滤后:[m2(0.8), m4(0.9), m6(0.7)]
python
def filter_by_importance(memories, threshold=0.6):
    """按重要性过滤"""
    return [m for m in memories if m.importance >= threshold]

5. 聚类压缩(Clustering):

将相似记忆合并,每类保留代表

原始记忆:
  "用户问了 RAG 文档切割" 
  "用户问了 RAG 向量检索"
  "用户问了 RAG 重排序"
  "用户问了 Agent 架构"
  "用户问了 Agent 记忆"

聚类后:
  RAG 类 → "用户深入讨论了 RAG 的文档切割、向量检索和重排序"
  Agent 类 → "用户讨论了 Agent 架构和记忆机制"

6. 层级压缩(Hierarchical):

Level 0:原始对话(每句话)
  → 压缩
Level 1:段落摘要(每 N 轮一个摘要)
  → 压缩
Level 2:会话摘要(整个会话一个摘要)
  → 压缩
Level 3:用户画像(跨会话总结)
python
class HierarchicalMemory:
    def __init__(self):
        self.levels = {
            0: [],  # 原始消息
            1: [],  # 段落摘要
            2: [],  # 会话摘要
            3: [],  # 用户画像
        }

    def compress(self):
        """逐层压缩"""
        # Level 0 → 1:每 5 条压缩为 1 条
        while len(self.levels[0]) >= 5:
            chunk = self.levels[0][:5]
            self.levels[0] = self.levels[0][5:]
            self.levels[1].append(summarize(chunk))

        # Level 1 → 2:所有段落压缩为会话摘要
        if len(self.levels[1]) >= 3:
            self.levels[2].append(summarize(self.levels[1]))
            self.levels[1] = []

        # Level 2 → 3:跨会话压缩为用户画像
        if len(self.levels[2]) >= 3:
            self.levels[3].append(extract_profile(self.levels[2]))
            self.levels[2] = []

各方法对比:

方法压缩率信息损失计算成本适用场景
摘要高中高(LLM)通用
提取高低(结构化)高事实提取
滑动窗口中高(直接丢弃)低短期记忆
重要性过滤中低(丢不重要)低混合策略
聚类中中中话题分类
层级高低高长期系统

实际组合策略:

python
def compress_memory(memories):
    # 1. 先过滤低重要性
    important = filter_by_importance(memories, threshold=0.4)
    # 2. 相似记忆聚类合并
    clusters = cluster(important)
    # 3. 每个聚类生成摘要
    summaries = [summarize(c) for c in clusters]
    # 4. 超长时层级压缩
    if len(summaries) > 10:
        summaries = hierarchical_compress(summaries)
    return summaries

追问延伸:

  • 压缩后的记忆怎么保证不丢关键信息?(保留原始索引 + 按需检索原文)
  • 实时压缩 vs 定时压缩哪个好?(实时更及时但成本高,定时更经济)

Q13: 在工程实践中,为什么有时候选择「手搓」Agent,而不是直接用成熟框架? 「🟡 中级」 ​

考察点:工程选型的权衡思考。

参考答案:

成熟框架的局限性:

问题说明
黑盒化框架封装太深,出问题难以定位和修复
灵活性不足框架的抽象不一定匹配业务需求
性能开销通用框架有额外抽象层,延迟和成本更高
版本绑定框架升级可能引入 breaking change
定制困难深度定制需要理解框架源码,成本高
技术栈不匹配Java 项目用 Python 框架不现实

选择「手搓」的场景:

1. 业务逻辑特殊 → 框架的通用模式不适用
   "我们的 Agent 需要特定的审批流程 + 合规检查,框架不支持"

2. 性能要求极高 → 框架开销不可接受
   "每秒处理 1000+ 请求,框架的序列化/反序列化开销太大"

3. 深度定制 → 需要控制每个细节
   "我们需要自定义记忆策略 + 自定义工具调用协议 + 自定义反思逻辑"

4. 技术栈限制 → Java/Go 项目不能直接用 Python 框架
   "我们的技术栈是 Java + Spring AI,需要自己实现 Agent 逻辑"

5. 学习和掌控 → 团队需要深入理解 Agent 原理
   "团队刚开始做 AI,手搓一遍才能真正理解"

6. 安全合规 → 不能引入外部依赖
   "金融场景,所有代码必须可审计"

手搓 Agent 的核心代码(Java 示例):

java
public class SimpleAgent {
    private final ChatClient llm;
    private final Map<String, Tool> tools;
    private final Memory memory;
    private final int maxIterations;

    public AgentResult run(String task) {
        var context = memory.recall(task);
        var history = new ArrayList<Step>();

        for (int i = 0; i < maxIterations; i++) {
            // 1. LLM 决策
            var decision = llm.prompt()
                .system(buildSystemPrompt(tools))
                .user(buildUserPrompt(task, context, history))
                .call()
                .getContent();

            // 2. 解析决策
            var action = parseAction(decision);
            if (action == null) {
                // 最终回答
                memory.store(task, decision, 0.7);
                return new AgentResult(decision, history);
            }

            // 3. 执行工具
            var result = tools.get(action.name()).execute(action.args());

            // 4. 记录步骤
            history.add(new Step(decision, action, result));
        }

        return new AgentResult("达到最大步数限制", history);
    }

    private String buildSystemPrompt(Map<String, Tool> tools) {
        var toolDesc = tools.entrySet().stream()
            .map(e -> "- " + e.getKey() + ": " + e.getValue().description())
            .collect(Collectors.joining("\n"));
        return """
            你是一个 AI Agent。使用以下工具完成任务。
            工具:%s
            格式:Thought: <推理> / Action: <工具>(<参数>) / Final Answer: <回答>
            """.formatted(toolDesc);
    }
}

手搓 vs 框架的对比:

维度手搓框架(如 LangChain)
开发速度慢(自己写)快(开箱即用)
灵活性高(完全可控)中(受框架约束)
可维护性取决于代码质量框架有文档和社区
调试容易(自己写的)难(黑盒)
性能可优化到最优有额外开销
学习成本需要深入理解上手快
生态无(自己建)丰富(插件/集成)

混合方案(推荐):

核心逻辑手搓 + 非核心用框架
  - Agent 循环、决策逻辑:手搓(需要完全可控)
  - 工具定义、向量检索:用框架库(不需要自己造轮子)
  - LLM 调用:用 SDK(直接调 API)
  - 记忆管理:混合(核心逻辑手搓,存储用现成方案)

追问延伸:

  • 手搓 Agent 最容易踩什么坑?(错误处理、循环终止、上下文管理)
  • 什么时候该从手搓迁移到框架?(团队扩大、需求复杂度上升)

Q14: 如何赋予 LLM 规划能力? 「🔴 高级」 ​

考察点:LLM 规划能力的实现方法。

参考答案:

LLM 本身没有规划能力,需要通过以下方法「赋予」:

1. Prompt Engineering(提示工程):

方法:在 System Prompt 中明确要求 LLM 做规划

System Prompt:
"你是一个任务规划专家。面对任何任务,请先制定详细计划:
1. 将任务拆分为可执行的子任务
2. 标注每个子任务的依赖关系
3. 为每个子任务选择合适的工具
4. 定义每个子任务的成功标准
然后再逐步执行。"

2. Few-Shot 示例(示例学习):

给 LLM 展示规划示例,让它学习规划模式

示例 1:
任务:写一篇技术博客
计划:
  1. 调研 → search 工具 → 成功标准:收集 5+ 参考资料
  2. 大纲 → write_doc → 成功标准:大纲包含 5+ 章节
  3. 初稿 → write_doc → 成功标准:每章 500+ 字
  4. 校对 → review → 成功标准:无语法错误
  5. 润色 → write_doc → 成功标准:表达流畅

示例 2:
任务:分析竞品
计划:
  1. 收集信息 → search → 竞品列表和特点
  2. 对比分析 → analyze → 对比表格
  3. 撰写报告 → write_doc → 分析报告

3. 结构化输出(Structured Output):

python
# 用 JSON Schema 约束 LLM 输出规划结构
planning_prompt = """
你是一个规划专家。将任务拆分为结构化计划。

任务:{task}

输出 JSON 格式:
{{
  "goal": "任务目标",
  "steps": [
    {{
      "id": 1,
      "action": "具体行动",
      "tool": "使用的工具",
      "depends_on": [],
      "success_criteria": "成功标准"
    }}
  ],
  "estimated_steps": 5
}}
"""

# 使用 Function Calling 确保结构化
response = llm.functions.create(
    name="create_plan",
    description="创建任务执行计划",
    parameters={
        "type": "object",
        "properties": {
            "goal": {"type": "string"},
            "steps": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "id": {"type": "integer"},
                        "action": {"type": "string"},
                        "tool": {"type": "string"},
                        "depends_on": {"type": "array", "items": {"type": "integer"}},
                        "success_criteria": {"type": "string"}
                    }
                }
            }
        }
    }
)

4. 分层规划(Hierarchical Planning):

第一层:粗粒度规划(3-5 大步)
  Step 1: 信息收集
  Step 2: 分析处理
  Step 3: 输出结果

第二层:每个大步细化为子步骤
  Step 1 细化:
    1.1 搜索关键词
    1.2 读取相关文档
    1.3 提取关键信息

第三层:子步骤执行
  1.1 → search("关键词") → 结果

5. 规划+自适应调整(Replan):

python
class AdaptivePlanner:
    def plan_and_execute(self, task):
        # 初始规划
        plan = self.llm.create_plan(task)

        results = {}
        for step in plan.steps:
            # 执行
            result = self.execute_step(step)
            results[step.id] = result

            # 检查是否需要重新规划
            if not self._check_success(result, step.success_criteria):
                # 自适应重新规划
                new_plan = self.llm.replan(
                    task=task,
                    completed=results,
                    failed_step=step,
                    reason=result.error
                )
                plan = self._merge_plan(plan, new_plan)

        return results

    def _merge_plan(self, old_plan, new_plan):
        """合并旧计划的已完成部分和新计划"""
        completed = [s for s in old_plan.steps if s.id in self.completed]
        return Plan(steps=completed + new_plan.steps)

6. 外部知识增强规划:

方法:用 RAG 检索历史成功规划模板

规划时:
  1. 从记忆/知识库中检索类似任务的历史规划
  2. 参考成功规划模板
  3. 结合当前任务特点调整

Prompt:
"以下是类似任务的成功规划参考:
{retrieved_plans}

请参考这些规划模式,为当前任务制定计划:
{current_task}"

规划能力评估:

指标说明
拆分合理性子任务是否覆盖目标且不过度拆分
依赖正确性依赖关系是否正确
工具选择是否选择了合适的工具
可执行性子任务是否可执行
自适应性执行失败能否合理调整

追问延伸:

  • 不同 LLM 的规划能力差异大吗?(GPT-4/Claude > 开源模型,需要更好的模型)
  • 规划太细或太粗怎么判断?(看执行成功率,太粗执行失败率高,太细成本高)

Q15: 讲讲 Agent 的反思机制?为什么要用反思?具体怎么实现? 「🔴 高级」 ​

考察点:反思机制的原理和工程实现。

参考答案:

为什么要用反思:

没有反思的问题:
  1. LLM 一次生成质量不稳定 → 可能有错误
  2. 错误会传递到后续步骤 → 错误放大
  3. LLM 不会主动发现自己的问题 → 缺乏自我纠错
  4. 相似错误会重复犯 → 没有学习和改进

反思的价值:
  1. 自我纠错 → 发现错误并修复
  2. 质量提升 → 多轮改进逐步提升
  3. 经验积累 → 从错误中学习
  4. 可信度评估 → 反思分数可作为置信度

反思机制的实现:

1. 自我批判(Self-Critique):

python
class ReflectionAgent:
    def __init__(self, llm):
        self.llm = llm

    def run(self, task, max_rounds=3):
        result = self._generate(task)

        for round_i in range(max_rounds):
            # 反思:评估当前结果
            critique = self._critique(task, result)

            if critique.is_perfect:
                break  # 已经足够好

            # 改进:根据反思修复问题
            result = self._improve(task, result, critique)

        return result

    def _generate(self, task):
        """初始生成"""
        return self.llm.generate(f"完成以下任务:{task}")

    def _critique(self, task, result):
        """反思:批判当前结果"""
        critique_prompt = f"""
        任务:{task}
        当前结果:{result}

        请作为审查者,评估这个结果:
        1. 是否完全满足任务要求?
        2. 有没有事实错误?
        3. 有没有逻辑漏洞?
        4. 有没有遗漏的边界情况?
        5. 质量评分(1-10)?

        如果评分 >= 8,输出"PASS"。
        否则输出"FAIL"并列出具体问题。
        """
        response = self.llm.generate(critique_prompt)
        return self._parse_critique(response)

    def _improve(self, task, result, critique):
        """改进:根据反思修复"""
        improve_prompt = f"""
        任务:{task}
        当前结果:{result}
        审查意见:{critique.issues}

        请根据审查意见改进结果,修复所有问题。
        """
        return self.llm.generate(improve_prompt)

2. 交叉模型批判(Cross-Model Critique):

python
class CrossModelReflection:
    def __init__(self, generator_llm, critic_llm):
        self.generator = generator_llm  # 生成模型(如 GPT-4)
        self.critic = critic_llm        # 批判模型(如 Claude)

    def run(self, task):
        result = self.generator.generate(task)

        for _ in range(3):
            # 用不同模型批判,避免同模型自评偏差
            critique = self.critic.generate(
                f"审查以下结果的质量,指出问题:\n任务:{task}\n结果:{result}"
            )
            if "PASS" in critique:
                break
            result = self.generator.generate(
                f"根据以下意见改进:\n{critique}\n改进结果:"
            )

        return result

3. 工具验证反思(Tool-Verified Reflection):

python
class ToolVerifiedReflection:
    def __init__(self, llm, tools):
        self.llm = llm
        self.tools = tools

    def run(self, task):
        result = self.llm.generate(task)

        # 用工具验证结果的正确性
        if "代码" in task:
            # 代码任务:执行验证
            test_result = self.tools["code_execute"].run(result)
            if test_result.has_error:
                result = self.llm.generate(
                    f"代码有错误:{test_result.error}\n修复:{result}"
                )

        if "事实" in task:
            # 事实任务:搜索验证
            search_result = self.tools["search"].run(task)
            if not self._fact_check(result, search_result):
                result = self.llm.generate(
                    f"事实有误,参考信息:{search_result}\n修正:{result}"
                )

        return result

4. Reflexion 框架(带记忆的反思):

python
class ReflexionAgent:
    """每次失败后总结教训,存入记忆,下次避免"""
    def __init__(self, llm, memory):
        self.llm = llm
        self.memory = memory  # 记忆中存储反思教训

    def run(self, task, max_attempts=3):
        for attempt in range(max_attempts):
            # 获取历史反思教训
            lessons = self.memory.recall(task)

            # 带着教训执行
            result = self.llm.generate(
                f"任务:{task}\n\n历史教训:{lessons}\n\n请执行任务。"
            )

            # 评估结果
            if self._is_successful(result):
                return result

            # 反思失败原因
            reflection = self.llm.generate(
                f"任务:{task}\n尝试结果:{result}\n\n"
                f"这次为什么失败了?总结教训,避免下次再犯。"
            )

            # 存入记忆
            self.memory.store(
                content=reflection,
                importance=0.9,
                type="lesson"
            )

        return result

反思的效果:

场景无反思有反思提升
代码生成55% 通过率75% 通过率+36%
数学推理40% 正确率60% 正确率+50%
文本质量6.5/108.2/10+26%
事实准确率75%88%+17%

反思的代价:

维度代价
LLM 调用次数2-4 倍(生成+批判+改进)
延迟2-4 倍
成本2-4 倍
复杂度增加(需要管理反思循环)

追问延伸:

  • 反思会不会越改越差?(可能,需要设置最大轮数和回退机制)
  • 怎么判断反思应该停止?(评分达标 / 改进幅度递减 / 达到最大轮数)

Q16: 如何设计多 Agent 的协作与动态切换机制? 「🔴 高级」 ​

考察点:Multi-Agent 协作架构和动态路由的设计。

参考答案:

多 Agent 协作的核心问题:

1. 怎么分工? → 每个 Agent 负责什么
2. 怎么通信? → Agent 之间怎么传递信息
3. 怎么路由? → 任务分给哪个 Agent
4. 怎么协调? → 冲突怎么处理
5. 怎么终止? → 什么时候算完成

1. Supervisor 模式(主管分发):

python
class SupervisorSystem:
    """一个 Supervisor 管理多个 Worker Agent"""
    def __init__(self):
        self.supervisor = Agent(role="supervisor")
        self.workers = {
            "research": Agent(role="researcher", tools=["search"]),
            "code": Agent(role="coder", tools=["python"]),
            "write": Agent(role="writer", tools=["doc"]),
        }
        self.shared_state = SharedState()

    def run(self, task):
        # Supervisor 分析任务并分配
        assignment = self.supervisor.run(
            f"分析任务并分配给合适的 Agent(research/code/write):{task}"
        )

        results = {}
        for subtask in assignment.subtasks:
            agent = self.workers[subtask.agent]
            result = agent.run(subtask.description)
            results[subtask.id] = result
            self.shared_state.set(subtask.id, result)

        # Supervisor 综合
        final = self.supervisor.run(f"综合结果:{results}")
        return final

2. 动态路由切换:

python
class DynamicRouter:
    """根据任务特征动态路由到不同 Agent"""
    def __init__(self, llm):
        self.llm = llm
        self.agents = {
            "technical": Agent(system_prompt="你是技术专家,擅长编程和系统设计"),
            "business": Agent(system_prompt="你是商业分析师,擅长市场分析和商业模式"),
            "creative": Agent(system_prompt="你是创意总监,擅长文案和设计"),
            "research": Agent(system_prompt="你是研究员,擅长信息搜集和分析"),
        }

    def route(self, query):
        """用 LLM 分类,动态选择 Agent"""
        route_prompt = f"""
        将以下问题分类到最合适的 Agent:
        - technical: 技术问题(编程、架构、系统设计)
        - business: 商业问题(市场、战略、运营)
        - creative: 创意问题(文案、设计、品牌)
        - research: 研究问题(信息搜集、数据分析)

        问题:{query}
        只输出类别名。
        """
        category = self.llm.generate(route_prompt).strip().lower()
        return self.agents.get(category, self.agents["research"])

    def run(self, query):
        agent = self.route(query)
        return agent.run(query)

3. 对话式协作(Conversation-based):

python
class ConversationalMAS:
    """多个 Agent 通过对话协商完成任务"""
    def __init__(self):
        self.agents = [
            Agent(role="产品经理", goal="确保需求合理"),
            Agent(role="技术负责人", goal="确保技术可行"),
            Agent(role="测试负责人", goal="确保质量可控"),
        ]

    def run(self, task, max_rounds=5):
        discussion = [{"role": "user", "content": task}]

        for round_i in range(max_rounds):
            round_messages = []
            for agent in self.agents:
                # 每个 Agent 看到完整讨论历史,发表意见
                response = agent.run(
                    f"讨论历史:{discussion}\n请发表你的看法。"
                )
                round_messages.append({
                    "role": agent.role,
                    "content": response
                })

            discussion.extend(round_messages)

            # 检查是否达成共识
            if self._check_consensus(discussion):
                break

        # 主持人总结
        return self.moderator.run(f"总结讨论结果:{discussion}")

4. 状态机驱动(State Machine):

python
class StateMachineMAS:
    """用状态图控制 Agent 协作流程"""
    def __init__(self):
        self.graph = StateGraph()

        # 定义节点(每个节点是一个 Agent)
        self.graph.add_node("plan", planner_agent)
        self.graph.add_node("research", researcher_agent)
        self.graph.add_node("code", coder_agent)
        self.graph.add_node("review", reviewer_agent)
        self.graph.add_node("test", tester_agent)

        # 定义边(转移条件)
        self.graph.add_edge("plan", "research")
        self.graph.add_conditional_edge("research", "code", condition="has_code_task")
        self.graph.add_edge("code", "review")
        self.graph.add_conditional_edge("review", "code", condition="needs_revision")
        self.graph.add_conditional_edge("review", "test", condition="approved")
        self.graph.add_conditional_edge("test", "code", condition="has_bugs")
        self.graph.add_edge("test", "END", condition="all_pass")

    def run(self, task):
        return self.graph.execute(task)

5. 拍卖机制(Auction-based):

python
class AuctionMAS:
    """多个 Agent 竞标任务,选最优"""
    def __init__(self):
        self.agents = [Agent1(), Agent2(), Agent3()]

    def run(self, task):
        # 每个 Agent 评估自己的能力和信心
        bids = []
        for agent in self.agents:
            confidence = agent.estimate(task)  # 0-1
            bids.append((agent, confidence))

        # 选信心最高的
        best_agent, _ = max(bids, key=lambda x: x[1])
        result = best_agent.run(task)

        # 如果最好的不够好,多个 Agent 各做一份,选最优
        if best_confidence < 0.7:
            results = [agent.run(task) for agent in self.agents]
            return self.judge.select_best(results)

        return result

协作中的冲突处理:

冲突类型解决方案
结果冲突投票 / 仲裁 Agent / 选最高信心
资源冲突排队 / 优先级 / 锁机制
观点冲突多轮讨论 / 妥协 / 人工介入
死循环最大轮数 / 超时 / 强制终止

动态切换的关键设计:

1. 能力注册:每个 Agent 注册自己的能力描述
2. 任务分析:分析任务需要什么能力
3. 匹配路由:能力与任务匹配,选最合适的 Agent
4. 动态加载:按需加载 Agent(节省资源)
5. 降级策略:首选 Agent 失败时,降级到备选
6. 结果评估:评估 Agent 输出质量,用于路由优化

追问延伸:

  • 怎么避免多 Agent 讨论陷入死循环?(最大轮数 + 共识检测 + 仲裁机制)
  • Agent 数量怎么决定?(3-5 个为宜,太多通信成本高,太少不够专业)