AI Agent 是什么:核心组件与极简实现

作者:php是最好的2026.11.04 12:36浏览量:0

简介:本文系统解析 AI Agent 的定义与本质:它是以大语言模型为“大脑”,叠加规划、记忆与工具调用能力、能自主完成任务的智能体。文章拆解 LLM、Planning、Memory、Tools 四大组件的职责与协作方式,讲清“思考—行动—观察”运行循环,并给出约 150 行 Python 的极简实现思路,帮助开发者厘清 Agent 与 LLM 的边界并掌握落地要点。

agent-">一、AI Agent 是什么:先给出清晰定义

AI Agent(智能体)是一种以大语言模型(LLM)为核心决策单元,具备任务规划、记忆与工具调用能力,能够在较少人工干预的情况下自主理解任务、拆解步骤、调用外部系统并最终交付结果的软件系统。

用一个公式概括其组成:

  1. AI Agent = LLM(大脑)+ Planning(规划)+ Memory(记忆)+ Tools(工具)

一个直观的类比:市面上常见的对话式大模型产品,好比一位“足不出户的专家”——你问什么,它答什么,但它不能替你查资料、跑代码、改系统;AI Agent 则像是把这位专家的“大脑”装进了一位全能助理的身体里:这位助理能听懂任务、自己安排步骤、记住中途发生的事,还能动手操作真实世界。

判断一个系统是不是 Agent,可以看三个特征:

  • 自主性:下一步做什么由系统自己决策,而不是由人预先写死;
  • 交互性:能与外部环境(文件、数据库、接口、命令行)交换信息;
  • 目标导向:围绕一个最终目标持续工作,而非一问一答即结束。

二、背景与价值:为什么会出现 Agent

对话式大模型能力很强,但作为“纯模型”直接使用时存在四个结构性局限:

  1. 被动响应:只有用户提问它才输出,无法主动发起动作;
  2. 无法触达外部信息:训练数据之外的信息(实时数据、企业内部资料)它并不掌握;
  3. 无法执行动作:它只能生成文字,不能运行代码、调用接口、修改文件;
  4. 缺乏持久记忆:一轮对话结束后,下次会话不记得之前的内容。

这四个局限决定了纯 LLM 只能当“顾问”;而当业务希望大模型直接“干活”——自动查数据、自动处理工单、自动排查故障——就需要在模型之外补齐工程能力。Agent 正是这一层工程架构的统称:它不是玄学,而是一套可落地、有明确边界的软件设计模式。

其核心价值可以概括为:把模型从“能说”升级为“能做”,把原本需要人工按流程串起来的“理解—查询—计算—执行—汇报”环节,交给一个可自主循环的系统完成。

三、核心组成:四个组件各司其职

1. LLM(大脑):理解与决策中枢

LLM 承担 Agent 中所有“需要动脑”的环节:理解用户意图、拆解任务、决定何时调用哪个工具、阅读工具返回结果、判断任务是否完成、生成最终答复。Agent 的智能上限基本由所选用的大模型能力决定。

2. Planning(规划):把大目标拆成小步骤

面对“分析上季度销售数据并写一份总结”这类复合任务,Agent 需要先规划执行顺序:查数据→做计算→汇总成文。规划组件通常包含两类能力:

  • 任务拆解:把目标分解为有序的子步骤;
  • 反思与修正:当某一步执行结果不符合预期时,调整策略重试,而不是一条路走到黑。

业界常见的实现思路是“推理与行动交替”:每一步先让模型输出当前思考,再决定动作,动作结果反馈回来后进入下一轮思考。这种“边想边做”的模式,是多数轻量级 Agent 的骨架。

3. Memory(记忆):跨步骤、跨会话的上下文

记忆通常分两层:

  • 短期记忆:当前任务内的会话历史,包括用户指令、模型决策、工具返回结果,一般保存在上下文窗口中;
  • 长期记忆:跨会话持久化的信息,通常借助外部存储实现(如数据库、向量检索服务),用于记住用户偏好与历史结论。

没有记忆,Agent 每一步都处于“失忆”状态,无法连贯地完成多步任务。

4. Tools(工具):连接真实世界的手脚

模型本身只能输出文字,工具让它具备“动手”能力。技术上的通行做法是函数调用(Function Calling)机制,协作方式如下:

  1. 开发者为每个工具编写“说明书”:工具名称、用途描述、参数结构(Schema);
  2. 每次请求时,把工具说明书清单随消息一起提供给模型;
  3. 模型在推理过程中自行判断:是否需要调用工具、调用哪一个、传什么参数;
  4. 应用侧执行真正的函数,把结果回传给模型,模型继续推理。

典型工具包括:检索知识库、查询数据库、调用计算器、在沙箱中执行代码、操作文件系统、发送通知等。

四、工作原理:一个“思考—行动—观察”的循环

Agent 的运行本质是一个带终止条件的循环:

  1. 接收任务
  2. │
  3. ▼
  4. ┌─► 模型结合(记忆 + 工具说明书)推理
  5. │ │
  6. │ ├── 信息不足?──► 执行工具 ──► 结果写入记忆 ──┐
  7. │ │ │
  8. │ └── 信息足够?──► 生成最终答复,结束 │
  9. │ │
  10. └──────────────────────────────────────────────────┘

用文字描述一次完整执行:

  1. 用户提交任务,写入记忆;
  2. 模型读取记忆与工具清单,判断缺少什么信息,决定先调用某个工具;
  3. 应用执行该工具(例如查询数据库),将返回结果追加到记忆中;
  4. 模型再次推理:若仍缺信息,继续调用工具;若信息足够,直接给出最终答案;
  5. 循环在“模型给出最终答复”或“达到预设最大步数”时终止。

这个循环解释了两个重要设计点:为什么需要记忆(第 4 步依赖第 3 步的结果)、为什么需要限制最大步数(防止模型陷入无休止的调用循环)。

五、约 150 行 Python 的极简实现

理解原理最有效的方式是亲手实现一遍。下面这段通用 Python 代码给出一个极简 Agent 的完整骨架,含注释不足 150 行,由“工具抽象、记忆、主循环、示例工具”四部分组成:

  1. # ---------- 1. 工具基类:每个工具自带"说明书" ----------
  2. class Tool:
  3. def __init__(self, name, description, parameters):
  4. self.name = name # 工具名
  5. self.description = description # 用途说明:告诉模型何时使用我
  6. self.parameters = parameters # 参数结构(Schema)
  7. def run(self, **kwargs):
  8. raise NotImplementedError
  9. class CalculatorTool(Tool):
  10. """示例工具:四则运算计算器(语法树求值,避免直接执行表达式)"""
  11. def __init__(self):
  12. super().__init__(
  13. name="calculator",
  14. description="计算一个四则运算表达式,例如 (120 + 30) * 1.13",
  15. parameters={
  16. "type": "object",
  17. "properties": {
  18. "expression": {"type": "string", "description": "待计算的表达式"}
  19. },
  20. "required": ["expression"],
  21. },
  22. )
  23. def run(self, expression):
  24. import ast, operator
  25. ops = {ast.Add: operator.add, ast.Sub: operator.sub,
  26. ast.Mult: operator.mul, ast.Div: operator.truediv}
  27. def _eval(node):
  28. if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)):
  29. return node.value
  30. if isinstance(node, ast.BinOp) and type(node.op) in ops:
  31. return ops[type(node.op)](_eval(node.left), _eval(node.right))
  32. raise ValueError("不支持的表达式")
  33. return str(_eval(ast.parse(expression, mode="eval").body))
  34. class SearchTool(Tool):
  35. """示例工具:在本地资料中检索关键词"""
  36. def __init__(self, documents):
  37. super().__init__(
  38. name="search_docs",
  39. description="在资料库中检索包含关键词的文档,用于获取事实信息",
  40. parameters={
  41. "type": "object",
  42. "properties": {
  43. "keyword": {"type": "string", "description": "检索关键词"}
  44. },
  45. "required": ["keyword"],
  46. },
  47. )
  48. self.documents = documents
  49. def run(self, keyword):
  50. hits = [d for d in self.documents if keyword in d]
  51. return "\n".join(hits) if hits else "未找到相关资料"
  52. # ---------- 2. 记忆:可追加、可整体读取的会话列表 ----------
  53. class Memory:
  54. def __init__(self):
  55. self.messages = []
  56. def add(self, role, content, name=None):
  57. msg = {"role": role, "content": content}
  58. if name:
  59. msg["name"] = name
  60. self.messages.append(msg)
  61. # ---------- 3. Agent 主循环:思考 - 行动 - 观察 ----------
  62. def run_agent(task, llm_chat, tools, max_steps=8):
  63. """
  64. :param task: 用户任务描述
  65. :param llm_chat: 大模型对话接口的抽象封装,返回
  66. {"answer": ...} 或 {"tool_name": ..., "arguments": {...}}
  67. :param tools: 可用工具列表
  68. :param max_steps: 最大循环步数(安全阀)
  69. """
  70. memory = Memory()
  71. memory.add("user", task)
  72. for _ in range(max_steps):
  73. # 3.1 组装工具说明书,随消息一起交给模型
  74. tool_schemas = [
  75. {"name": t.name, "description": t.description, "parameters": t.parameters}
  76. for t in tools
  77. ]
  78. decision = llm_chat(memory.messages, tool_schemas)
  79. # 3.2 模型决定调用工具:执行 -> 观察 -> 写回记忆
  80. if decision.get("tool_name"):
  81. tool = next((t for t in tools if t.name == decision["tool_name"]), None)
  82. if tool is None:
  83. memory.add("tool", f"工具 {decision['tool_name']} 不存在")
  84. continue
  85. try:
  86. result = tool.run(**decision["arguments"])
  87. except Exception as e:
  88. result = f"工具执行出错:{e}" # 失败也要反馈,让模型调整策略
  89. memory.add("tool", str(result), name=tool.name)
  90. continue
  91. # 3.3 模型认为信息充分,返回最终答案
  92. return decision.get("answer", "")
  93. return "已达到最大步数,任务未完成。"
  94. # ---------- 4. 组装运行 ----------
  95. if __name__ == "__main__":
  96. docs = ["2024年Q3销售额为120万元", "2024年Q3毛利率为35%"]
  97. tools = [CalculatorTool(), SearchTool(docs)]
  98. answer = run_agent(
  99. "查一下 Q3 销售额,再帮我算出它的 1.13 倍是多少",
  100. llm_chat=None, # 对接你所使用的大模型服务后实现
  101. tools=tools,
  102. )
  103. print(answer)

对这段代码做三点说明:

  • llm_chat 是抽象接口:它对接大模型服务的对话能力,输入历史消息与工具清单,返回“直接回答”或“工具调用决策”。实际接入时(例如对接百度智能云提供的大模型相关服务),只需实现这一个函数,其余逻辑不变;
  • 工具即对象加 Schema:每个工具自带名称、描述与参数结构,这正是函数调用机制中的“说明书”,工具设计质量直接决定模型决策质量;
  • max_steps 是安全阀:限制循环步数,是所有 Agent 工程实践的基本要求。

六、典型应用场景

  • 智能编程助手:读写代码库、运行测试、根据报错信息自动修复并重试,全程不需要人工搬运上下文;
  • 信息调研与报告生成:围绕一个主题多轮检索资料,交叉验证后汇总成结构化报告,适合行业研究、竞品情报整理等;
  • 运维巡检与故障处理:查询监控指标、读取日志服务数据、执行预案脚本,并输出处置结论;
  • 企业客服自动化:查询订单状态、调用业务接口办理退换、遇到权限外问题转人工;
  • 数据分析:读取数据、调用计算工具、给出结论与图表说明。

这些场景的共同特征是:任务由多个步骤组成、中间需要外部信息或动作、结果需要整合汇报——恰好对应 Agent 的三大组件能力。

七、容易混淆的概念辨析

LLM 与 Agent:LLM 是 Agent 的核心组件,但 LLM “被动应答、无状态、只产文字”;Agent “主动执行、有记忆、可操作系统”。一句话:LLM 是大脑,Agent 是装上了手脚和记忆的完整的人。

Agent 与传统自动化脚本:脚本的流程由开发者预先写死,遇到分支只能穷举;Agent 的流程由模型现场决策,能处理事先没枚举到的模糊情况。代价是确定性下降,需要用步数限制、工具白名单等手段兜底。

Agent 与工作流编排:工作流(把大模型作为节点之一的固定流程图)中“下一步做什么”由流程图决定;Agent 中由模型决定。前者可控性强,适合确定性业务;后者灵活性强,适合开放性任务,两者也常组合使用。

单 Agent 与多 Agent 系统:简单任务用单 Agent 循环即可;复杂任务可拆给多个角色化 Agent 协作(如一个负责检索、一个负责写作、一个负责审查),但协作会显著增加复杂度与成本,需谨慎评估必要性。

八、使用注意事项

  1. 工具说明书要写得清楚:工具名和参数名应语义化,描述要说明“什么时候该用我”;说明书含糊是 Agent 决策出错的首要原因。
  2. 控制循环边界:设置最大步数、单步超时与总预算,防止死循环与费用失控。
  3. 权限最小化与安全确认:只授予任务所需的最小权限;写操作、资金相关等高危动作建议加入人工确认环节;执行模型生成的代码应放在沙箱环境中。
  4. 记忆管理:上下文长度有限,长任务需要做摘要压缩或转存外部存储,避免关键信息被截断。
  5. 失败也要反馈给模型:工具报错信息应写回记忆,让模型有机会调整策略重试,而不是直接终止任务。
  6. 全链路可观测:记录每一步的模型决策、工具调用与返回结果,出问题时才能定位是“模型想错了”还是“工具执行错了”。
  7. 成本与延迟评估:多步循环意味着多次模型调用,上线前要评估响应延迟和调用费用是否在可接受范围内。

九、总结

回到定义本身:AI Agent 是“LLM 大脑 + Planning 规划 + Memory 记忆 + Tools 工具”构成的、能自主完成任务的智能体系统。它出现的根本原因,是纯大模型“只能说不能做”,而业务需要“能做”的系统。其工作原理是一个带终止条件的“思考—行动—观察”循环,用一百多行 Python 即可搭出教学级原型;但走向生产的关键不在模型,而在工具设计、权限控制、循环边界与可观测性这些工程细节。理解了这些,你就掌握了评估各类“智能体”方案的通用框架,也能更准确地判断它适合与不适合的场景边界。