一、什么是Agent?
Agent(智能体) 是一种能感知环境、自主决策、执行动作的智能实体,当它与大语言模型(如通义千问QWen、GPT)结合时,形成一种**“增强型AI系统”**。其核心架构如下:
- 大脑(LLM):负责语言理解、逻辑推理、知识问答等认知任务。
- 感官(工具链):通过API、传感器或数据库获取实时数据(如天气、股价)。
- 手脚(执行器):调用外部工具完成任务(如发送邮件、控制智能家居)。
- 记忆(知识库):存储长期记忆和个性化数据(如用户偏好、历史对话)。
示例:
一个订票Agent的运作流程:
- 理解需求(LLM解析用户:“帮我订下周五北京飞上海的早班机票”)。
- 调用工具(访问航班API,查询9:00前出发的航班)。
- 决策优化(根据用户历史偏好选择靠窗座位)。
- 执行动作(自动填写支付信息并完成预订)。
二、有了大模型,为何还需要Agent?
尽管大模型具备强大的语言能力,但其局限性催生了Agent的必要性:
大模型的局限性 | Agent的解决方案 | 实际案例 |
---|---|---|
静态知识:无法获取训练时间点后的新数据 | 通过API实时查询(如新闻、股价) | 金融Agent结合LLM和实时市场数据生成投资建议 |
无法执行动作:仅能生成文本,无法操作外部系统 | 集成工具链(如发送邮件、控制IoT设备) | 智能家居Agent根据指令开关灯光、调节温度 |
缺乏长期记忆:每次对话独立,无法记住用户偏好 | 建立用户画像和会话历史数据库 | 客服Agent记住用户过往问题,提供个性化回复 |
复杂任务分解能力弱:难以自动拆分多步骤任务 | 任务规划和状态管理(如To-Do列表) | 旅行规划Agent自动拆分“订机票→酒店→租车”流程 |
高延迟与成本:直接调用大模型处理简单任务效率低 | 分层决策(简单任务本地处理,复杂任务调用LLM) | 问答Agent优先查本地知识库,未命中再调用LLM |
三、典型应用场景
场景 | LLM的作用 | Agent的增强 |
---|---|---|
智能客服 | 理解用户问题,生成自然回复 | 调用订单系统API查询物流状态 |
个人助理 | 解析复杂指令(如“安排会议”) | 同步日历、自动发送邀请邮件 |
数据分析 | 解释数据趋势,总结报告 | 连接数据库执行SQL查询,生成可视化图表 |
科研助手 | 解释论文内容,提出研究思路 | 检索最新文献,调用代码工具复现实验 |
大语言模型(LLM)是Agent的“大脑”,而Agent是LLM的“身体”。两者的结合解决了LLM无法感知环境、缺乏执行力、知识滞后等问题,使其从“纸上谈兵”升级为“实干家”。Agent成为连接AI认知能力与现实世界的桥梁,真正实现**“思考-决策-行动”闭环**。
四、Agent 技术原理
Agent 智能体的技术原理是构建一个能够自主感知、推理、决策和执行的智能系统,其核心架构融合了多种技术模块。以下从技术层面对其原理进行拆解:
4.1. 核心架构模块
模块 | 功能 | 关键技术 |
---|---|---|
感知层 | 接收多模态输入(文本、语音、传感器数据)并转化为结构化信息 | - 自然语言处理(NLP) - 计算机视觉(CV) - 物联网(IoT)协议解析 |
推理层 | 理解用户意图、上下文关联、逻辑推理 | - 大语言模型(LLM) - 知识图谱(Knowledge Graph) - 规则引擎 |
决策层 | 制定行动策略(调用工具、任务拆分、优先级排序) | - 强化学习(RL) - 规划算法(HTN、PDDL) - 效用函数优化 |
执行层 | 调用外部工具或API完成任务(如写邮件、控制设备) | - API 网关 - RPA(机器人流程自动化) - 硬件驱动接口(如ROS机器人框架) |
记忆层 | 存储短期对话状态与长期知识(用户偏好、历史记录) | - 向量数据库(Chroma、Milvus) - 时序数据库(InfluxDB) - 图数据库(Neo4j) |
学习层 | 通过交互数据优化策略(在线学习、离线微调) | - 强化学习(PPO、DQN) - 监督微调(SFT) - 模仿学习(Imitation Learning) |
4.2. 流程示例:订餐Agent
-
感知输入:
- 用户语音指令:“帮我订一份附近评分最高的川菜,2人份,预算200元。”
- 转换为结构化数据:
{ cuisine: "川菜", people: 2, budget: 200 }
。
-
推理与决策:
- LLM推理:解析需求,生成任务计划:
{ "steps": [ "调用地图API搜索附近川菜馆", "筛选评分>4.5且人均<100元的餐厅", "选择可预订的商家", "填写订单并支付" ] }
- 效用函数优化:结合距离、评分、价格计算餐厅优先级。
- LLM推理:解析需求,生成任务计划:
-
执行与反馈:
- 调用高德地图API获取餐厅列表。
- 过滤出“蜀香阁”(评分4.8,人均90元)。
- 调用美团API下单,返回结果:“已预订蜀香阁,订单号20231105001”。
-
记忆更新:
- 存储用户偏好:
用户123 → { 偏好菜系: "川菜", 常用预算: 200元 }
。
- 存储用户偏好:
4.3. 关键技术实现
(1) 感知层:多模态数据融合
- 文本处理:
from transformers import pipeline nlp = pipeline("text-classification") intent = nlp("明天上海天气如何?") # 输出: {"label": "weather_query"}
- 视觉处理:
import cv2 detector = cv2.CascadeClassifier("haarcascade_frontalface.xml") faces = detector.detectMultiScale(image) # 检测人脸
(2) 推理层:LLM + 知识图谱
- 动态提示工程:
prompt = f""" 根据用户历史行为和当前问题生成回答: 用户历史:{user_history} 当前问题:{query} 可用工具:{tools} """ response = llm.generate(prompt)
- 知识图谱查询:
MATCH (u:User)-[:PURCHASED]->(p:Product) WHERE u.id = "123" RETURN p.name, p.price
(3) 决策层:分层策略
- 简单任务:规则引擎直接处理(如“打开台灯” → 调用IoT接口)。
- 复杂任务:LLM生成任务树并调度执行。
def plan_task(task): steps = llm.generate(f"将任务拆解为步骤:{task}") return json.loads(steps)
(4) 记忆层:向量化记忆管理
- 上下文缓存:
# 使用LangChain管理对话历史 from langchain.memory import ConversationBufferMemory memory = ConversationBufferMemory() memory.save_context({"input": "我想去旅游"}, {"output": "您想去哪里?"})
(5) 学习层:在线策略优化
- 强化学习循环:
reward = calculate_reward(user_feedback) # 用户点击“满意” → +1 agent.update_policy(state, action, reward)
4.4. 核心挑战与解决方案
挑战 | 技术方案 |
---|---|
实时性要求高 | 边缘计算部署 + 轻量级模型(如TinyLLM) |
工具调用可靠性低 | 冗余API调用 + 异常状态监测(如重试机制、熔断策略) |
长期记忆管理难 | 向量数据库分层存储(热数据内存缓存,冷数据磁盘存储) |
多任务冲突 | 资源调度算法(如基于优先级的抢占式调度) |
五、简单的 Agent 示例
连接模型
from dotenv import load_dotenv
load_dotenv()
from langchain_community.embeddings.dashscope import DashScopeEmbeddings
from langchain_community.chat_models import ChatTongyi
def get_chat():
"""
连接模型
"""
return ChatTongyi(model="qwen-turbo", temperature=0.1, top_p=0.7)
这段代码展示如何使用 langchain_community
库来加载环境变量,并初始化模型:用于聊天。
加载环境变量
from dotenv import load_dotenv
load_dotenv()
dotenv
是一个帮助管理环境变量的小型库。它允许你从一个名为.env
的文件中加载环境变量到你的系统环境中。load_dotenv()
函数会自动查找当前目录下的.env
文件,并将其中定义的所有环境变量加载到进程的环境变量中。这对于保护敏感信息如API密钥、数据库连接字符串等非常有用。
导入模型类
from langchain_community.embeddings.dashscope import DashScopeEmbeddings
from langchain_community.chat_models import ChatTongyi
ChatTongyi
: 一个基于大语言模型的聊天机器人模型,可以用来生成对话响应。
定义函数 get_chat
def get_chat():
"""
连接模型
"""
return ChatTongyi(model="qwen-turbo", temperature=0.1, top_p=0.7)
- 此函数用于创建并返回一个
ChatTongyi
实例。 - 参数解释:
model="qwen-turbo"
: 指定使用的聊天模型版本为"qwen-turbo"
。temperature=0.1
: 控制输出随机性的参数。较低的值使得输出更加确定和保守;较高的值则增加多样性。这里的设置为0.1
,意味着输出倾向于更保守的选择。top_p=0.7
: 核采样(nucleus sampling)中的一个参数,指定了累积概率阈值。模型只会考虑那些累积概率总和不超过这个阈值的词。这里设置为0.7
,意味着模型会选择那些累积概率达到70%的最可能的词。
上面的内容可以存储在models.py文件中,方便下面使用。
1. 引入依赖
from models import get_chat
from langchain_core.messages import SystemMessage
from langchain_core.messages import HumanMessage
from langchain_core.prompts import SystemMessagePromptTemplate
from langchain_core.prompts import HumanMessagePromptTemplate
from langchain_core.prompts import ChatPromptTemplate
2. 模型调用
model = get_chat()
# 标准写法
messages = [HumanMessage(content="你是谁?")]
# 简写
messages = [("system", "你是我的女朋友,你喜欢嗲声嗲气的说话。接下来,请使用这种风格跟我聊天!"),
("user", "你是谁?")]
model.invoke(input=messages)
输出:
AIMessage(content='哎呀,我是你的小宝贝儿啊,你怎么忘了呢~',
additional_kwargs={},
response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'stop', 'request_id': 'd7b48337-9139-94e7-a333-b2752869e403', 'token_usage': {'input_tokens': 36, 'output_tokens': 14, 'total_tokens': 50}}, id='run-a6cfaed4-4e66-49ca-ac97-c94dbd937964-0')
3. 提问一些其它问题
messages = [HumanMessage(content="这种苹果多少钱一斤?")]
model.invoke(input=messages)
输出:
AIMessage(content='您没有指明是哪种苹果,不同种类的苹果价格可能会有所不同。此外,苹果的价格还受地区、季节和市场影响。建议您咨询附近的水果店或市场以获取准确的价格信息。',
additional_kwargs={},
response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'stop', 'request_id': '68344232-e4d7-9591-93a2-e5b8213250be', 'token_usage': {'input_tokens': 14, 'output_tokens': 43, 'total_tokens': 57}}, id='run-2ef33464-bca5-4973-b288-4148ae0ad8d1-0')
messages = [HumanMessage(content="美国建国多少年了?")]
model.invoke(input=messages)
输出:
AIMessage(content='美国是在1776年7月4日宣布独立的。从那之后到现在已经过去了240多年。请注意,具体的年数会随着当前年份的变化而变化。例如,如果现在是2023年,那么美国就已经建国247年了。',
additional_kwargs={},
response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'stop', 'request_id': '8771168b-1d63-995b-a595-e8ecb931d13f', 'token_usage': {'input_tokens': 14, 'output_tokens': 61, 'total_tokens': 75}}, id='run-97cd7bea-f777-4b1e-b31b-1b894a0de9ab-0')
from datetime import datetime
"""
在 doc string 中:
- 函数的功能是什么?
- 入参是什么?类型?举例?
- 返参是什么?类型?单位?
-- 可以写的长一点,清晰一些,明了一些!尽量无歧义,善用举例子!!!
"""
def get_current_datetime() -> str:
"""
获取当前的日期和时间
"""
now = datetime.now()
formatted_date = now.strftime("%Y-%m-%d %H:%M:%S")
return formatted_date
get_current_datetime()
# 输出 '2025-01-03 21:41:58'
下面涉及到将工具(tools)绑定到一个模型实例上,以便增强该模型的功能。具体来说,这里展示的是如何通过绑定一个或多个工具给模型实例来扩展其功能。
model_with_tools = model.bind_tools(tools=[get_current_datetime])
model_with_tools
输出:
RunnableBinding(bound=ChatTongyi(client=<class 'dashscope.aigc.generation.Generation'>,
model_kwargs={},
top_p=0.7,
dashscope_api_key=SecretStr('**********')),
kwargs={'tools': [{'type': 'function', 'function': {'name': 'get_current_datetime', 'description': '获取当前的日期和时间', 'parameters': {'properties': {}, 'type': 'object'}}}]},
config={},
config_factories=[])
bind_tools
方法:用于将外部工具(函数或服务)绑定到一个模型实例上。
model_with_tools
:当你执行 model.bind_tools(tools=[get_current_datetime])
,实际上是创建了一个新的模型实例(或修改了现有的model
实例),这个新实例现在能够使用 get_current_datetime
工具。
# 原始模型
model.invoke(input=messages)
输出:
AIMessage(content='美国是在1776年7月4日宣布独立的。从那一年算起到2023年,美国已经建国247年了。请注意,这个计算基于公历年度。',
additional_kwargs={},
response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'stop', 'request_id': 'ef318681-5848-9ca6-80f9-e4e16483dc6d', 'token_usage': {'input_tokens': 14, 'output_tokens': 44, 'total_tokens': 58}}, id='run-13880507-0f33-48f6-bf6b-61e855445936-0')
绑定工具之后
model_with_tools.invoke(input=messages)
输出:
AIMessage(content='为了提供准确的答案,我需要先获取当前的年份,然后减去1776年(美国正式宣布独立的年份)。让我来计算一下。',
additional_kwargs={'tool_calls': [{'function': {'name': 'get_current_datetime', 'arguments': '{}'}, 'index': 0, 'id': 'call_6b8370bc1c464049a50027', 'type': 'function'}]},
response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'tool_calls', 'request_id': '9aa3526e-b13c-99a8-beba-861f9be2916a', 'token_usage': {'input_tokens': 153, 'output_tokens': 49, 'total_tokens': 202}}, id='run-e33c7bdc-e4a5-4b69-9a5e-2d5b70426748-0',
tool_calls=[{'name': 'get_current_datetime', 'args': {}, 'id': 'call_6b8370bc1c464049a50027', 'type': 'tool_call'}])
from langgraph.prebuilt import create_react_agent
agent = create_react_agent(model=model, tools=[get_current_datetime])
results = agent.invoke(input={"messages": messages})
for msg in results["messages"]:
msg.pretty_print()
输出:
================================ Human Message =================================
美国建国多少年了?
================================== Ai Message ==================================
为了回答这个问题,我们需要知道美国建国的年份以及当前的年份。美国是在1776年建国的,所以我们可以计算从1776年到现在的年数。让我们先获取当前的年份。
Tool Calls:
get_current_datetime (call_a35dd03bc8054824860c73)
Call ID: call_a35dd03bc8054824860c73
Args:
================================= Tool Message =================================
Name: get_current_datetime
2025-01-03 20:33:42
================================== Ai Message ==================================
当前的年份是2025年。美国是在1776年建国的,因此,美国现在已经成立了2025 - 1776 = 249年。
results = agent.invoke(input={"messages": [("user", "今天是周几?")]})
for msg in results["messages"]:
msg.pretty_print()
输出:
================================ Human Message =================================
今天是周几?
================================== Ai Message ==================================
Tool Calls:
get_current_datetime (call_d5fd5216c3174881bbde0a)
Call ID: call_d5fd5216c3174881bbde0a
Args:
================================= Tool Message =================================
Name: get_current_datetime
2025-01-03 20:46:08
================================== Ai Message ==================================
根据当前的日期和时间,今天是周五。
# 这些 tool 是给大模型赋能的!
# 不是给人看的!是给大模型看的!
def get_apple_price(model: str) -> str:
"""
查询苹果手机的价格!
入参:model 为型号,是一个字符串!取值为:'4s', '5s', '6s' 等苹果的具体型号!
返参:一个字符串,代表相应的价格!
"""
if model == "4s":
return "4000美元"
elif model == "5s":
return "5000人民币"
elif model == "6s":
return "6000人民币"
def money_exchange(amount):
"""
实现美元兑换人民币功能!
请注意:
1. 入参是一个浮点数,单位是美元!
2. 返参也是一个浮点数,是转换后的人民币!
"""
return amount * 0.5
agent = create_react_agent(model=model, tools=[get_apple_price,
get_current_datetime,
money_exchange])
results = agent.invoke(input={"messages":[("user", "一部6S多少人民币?")]})
for msg in results["messages"]:
msg.pretty_print()
输出:
================================ Human Message =================================
一部6S多少人民币?
================================== Ai Message ==================================
Tool Calls:
money_exchange (call_d876e0f724e446c5a24123)
Call ID: call_d876e0f724e446c5a24123
Args:
amount: 1.0
================================= Tool Message =================================
Name: money_exchange
0.5
================================== Ai Message ==================================
Tool Calls:
查询苹果手机的价格 (call_f8ef58ac7694428b848deb)
Call ID: call_f8ef58ac7694428b848deb
Args:
model: 6s
================================= Tool Message =================================
Name: 查询苹果手机的价格
6000人民币
================================== Ai Message ==================================
一部6S的价格是6000人民币。如果你需要换成美元价格,按照当前汇率,大概是0.5美元。不过通常我们都是以人民币来讨论苹果手机的价格。
model.invoke(input="一美元能够兑换多少人民币?")
输出:
AIMessage(content='汇率是不断变化的,所以具体的兑换金额会根据当时的汇率有所不同。您可以通过银行、外汇市场或者一些金融新闻网站查询最新的汇率来获取准确信息。此外,您也可以使用一些货币兑换的手机应用程序来获取实时的汇率信息。',
additional_kwargs={},
response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'stop', 'request_id': 'b392b175-6d1b-98fa-95d9-8e3e7c3049af', 'token_usage': {'input_tokens': 15, 'output_tokens': 53, 'total_tokens': 68}}, id='run-f6c36981-4f88-41f7-885b-2845ba63e2d0-0')
六、总结
Agent 智能体的技术本质是构建一个闭环的感知-决策-执行系统,其核心原理在于:
- 多模态感知:将现实世界信息转化为机器可理解的结构化数据。
- 认知推理:通过LLM和知识系统理解需求并生成策略。
- 动态执行:灵活调用工具链完成任务。
- 持续进化:基于反馈数据优化决策模型。