1. 相关概念
1.1 神经网络结构
深度神经网络分为很多层,是神经网络基本的计算单元,分为
- 输入层(
Input Layer):入口,接收数据 - 隐藏层(
Hidden Layer):信息处理和学习。可以有很多层。 - 输入层(
Output Layer):出口,产生结果
1.2 反向传播
反向传播(Back propagation):根据前向传播产生的预测结果与真实值之间的误差,从输出层开始,反向逐层计算每个参数(权重和偏置)对总误差的”贡献”大小(即梯度),并据此更新参数。这是一个学习过程。
基本流程如下:
- 前向传播:数据逐层加工,直到输出层产出结果
- 计算误差:计算产出结果与正确结果的误差(
Loss) - 反向追责:倒推计算每一层的每个连接对误差的贡献
- 调整权重:根据每个连接的误差贡献比例,调整其权重参数,使误差变小
1.3 词向量
词向量(Word Embedding)就是把词转为多维空间向量的一种技术。
- 将人类自然语言文字拆分为一个个片段,称为
Token(词) - 每个Token都经过模型计算转为一个浮点数数组,作为向量坐标
- 目标:使词向量在多维空间中的不同方向表达不同的语义

1.4 Transformer自注意力机制
注意力机制(self-attention):其使得模型能够更加高效的根据上下文信息处理Token,理解Token含义。

1.5 MLP
多层感知机(Multi-Layer Perceptron)是层级化、全连接的神经网络结构,层与层之间无跳过、无循环,神经元之间全连接(相邻层的任意两个神经元都有连接)
1.6 SoftMax
归一化指数函数(SoftMax)会根据模型计算出的向量结果得出下一个token的概率分布,然后基于概率的随机采样方式挑选一个作为结果。
这个概率受模型的温度系数(Temperature)参数影响,值越大,概率分布越均匀,模型生成结果的随机性越强;反之,结果越确定
温度系数(Temperature)是控制大模型生成文本随机性和多样性的关键参数。“它通过调整模型输出的概率分布,直接影响生成结果的保守性”(值小)或“创造性”(值大)。

1.7 大语言模型
Transformer本来是作为翻译用的,但当模型参数规模和训练数据量增突破某个临界点时,模型像是突然拥有了智能,不仅可以理解人类语言,还能推理、分析。
这种现象被称为“涌现”(Emergent Abiities)。这种超大规模的语言模型则被称为大语言模型(Large Language Model)
GPT是指
- 生成式(
Generative):根据上文预测紧跟着的下一个Token,从而形成连续的文本输出 - 预训练(
Pre-trained):通过大规模的文本数据进行训练,让大模型可以理解人类语言的语法、词性。 Transformer:深度学习的一种神经网络结构。多数大模型都依赖于此。
大语言模型(Large Language Model, LLM)是指模型的参数规模、训练数据量、训练成本、智能程度都远超普通模型的一种神经网络模型。
1.8 认识LangChain
LangChain 由 Harrison Chase 创建于2022年10月,是用于开发智能体工程(Agent Engineering)的平台。
LangChain自身并不开发LLMS,它的核心理念是为各种LLMs实现通用的接口,把LLMs相关的组件“链接”在一起,简化LLMs应用的开发难度,方便开发者快速地开发复杂的LLMs应用.
主要功能:
- Prompts:优化提示词(提示词工程)
- Models:调用各类模型
- History:管理会话历史记录(记忆)
- Indexes:管理和分析各类文档
- Chains:构建功能的执行链条
- Agent:构建智能体
1.9 Agent
在人工智能领域,Agent(通常翻译为智能体或代理)是指一种能够感知环境、进行推理、自主决策并采取行动以实现特定目标的智能系统。
2. 大模型API
2.1 CURL接口调用
2.1.1 DeepSeek
curl https://api.deepseek.com/chat/completions \ -H "Content-Type: application/json" \ # 请求头:告诉服务器请求体是 JSON 格式 -H "Authorization: Bearer ${DEEPSEEK_API_KEY}" \ # 请求头:Bearer 认证,${} 表示从环境变量读取 API Key -d '{ # -d 参数:指定要发送的 JSON 数据体 "model": "deepseek-v4-pro", # 模型名称 "messages": [ # 对话消息数组(按时间顺序排列) {"role": "system", "content": "You are a helpful assistant."}, # system 角色:设定模型的行为、人格和回复风格(可选) {"role": "user", "content": "Hello!"} # user 角色:表示用户输入的内容 ], "thinking": {"type": "enabled"}, # 深度思考开关:enabled 开启后模型会先输出内部推理链 "reasoning_effort": "high", # 推理强度:指定思考深度,可选 low/medium/high(仅在 thinking 开启时生效) "stream": false # 流式输出:false 表示一次性返回完整结果;true 表示逐字流式输出 }'2.1.2 百炼
curl -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \-H "Authorization: Bearer $DASHSCOPE_API_KEY" \-H "Content-Type: application/json" \-d '{ "model": "qwen3.6-plus", "messages": [ { "role": "user", "content": "你是谁?" } ]}'# 返回结果{ "choices": [ { // 消息对象:包含完整的对话内容 "message": { "role": "assistant", // 角色:assistant 表示这是模型的回复(与 user 对应) "content": "你好!我是Qwen..." // 实际生成的文本内容 }, "finish_reason": "stop", // 结束原因:stop 表示正常完成(未触发生成长度限制) "index": 0, // 索引号:当一次请求生成多个回复时的序号(0 表示第一个) "logprobs": null // 对数概率:通常为 null,需单独开启才返回 token 级别的概率信息 } ],
"object": "chat.completion", // 对象类型:固定值,表示这是一个对话补全请求的响应
// Token 使用统计:按量计费的关键数据 "usage": { "prompt_tokens": 12, // 输入 token 数:用户发送的消息 + 系统提示词消耗的 token "completion_tokens": 77, // 输出 token 数:模型生成回复消耗的 token "total_tokens": 89 // 总 token 数:12 + 77 = 89(本次 API 调用的计费依据) },
"created": 1680300000, // 创建时间:Unix 时间戳(秒),记录本次请求的生成时间 "system_fingerprint": null, // 系统指纹:通常为 null,用于后端调试或版本追踪 "model": "qwen-plus-2025-07-28", // 实际使用的模型:确认请求时指定的模型生效 "id": "XX" // 请求唯一标识:用于排查问题和追踪调用记录}2.2 会话记忆
DeepSeek
多轮对话,内容来源官网
DeepSeek /chat/completions API 是一个“无状态” API,即服务端不记录用户请求的上下文,用户在每次请求时,需将之前所有对话历史拼接好后,传递给对话 API。
下面的代码以 Python 语言,展示了如何进行上下文拼接,以实现多轮对话。
from openai import OpenAIclient = OpenAI(api_key="<DeepSeek API Key>", base_url="https://api.deepseek.com")
# Round 1messages = [{"role": "user", "content": "What's the highest mountain in the world?"}]response = client.chat.completions.create( model="deepseek-v4-pro", messages=messages)
messages.append(response.choices[0].message)print(f"Messages Round 1: {messages}")
# Round 2messages.append({"role": "user", "content": "What is the second?"})response = client.chat.completions.create( model="deepseek-v4-pro", messages=messages)
messages.append(response.choices[0].message)print(f"Messages Round 2: {messages}")在第一轮请求时,传递给 API 的 messages 为:
[ {"role": "user", "content": "What's the highest mountain in the world?"}]在第二轮请求时:
- 要将第一轮中模型的输出添加到
messages末尾 - 将新的提问添加到
messages末尾 最终传递给 API 的messages为:
[ {"role": "user", "content": "What's the highest mountain in the world?"}, {"role": "assistant", "content": "The highest mountain in the world is Mount Everest."}, {"role": "user", "content": "What is the second?"}]2.3 客户端调用
from dotenv import load_dotenvimport osfrom openai import OpenAIload_dotenv()api_key = os.getenv("API_KEY")
client = OpenAI( api_key=api_key, base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" )
response = client.chat.completions.create( model="XXX", messages=[ {"role": "system", "content": "You are a helpful assistant"}, {"role": "user", "content": "Hello"}, ], stream=False)print(response.choices[0].message.content)# Hello! How can I assist you today?3. LangChain使用
3.1 Demo案例
# uv add langchain# uv add langchain-openai# uv add python-dotenv
# 在.env文件中添加# OPENAI_API_KEY=XXXXXXXXX# OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
from dotenv import load_dotenvimport osload_dotenv()api_key = os.getenv("OPENAI_API_KEY") # 获取API KEY
# 定义工具from langchain.tools import tool@tooldef getWeather(location:str)->str: """ 获取指定位置的天气信息。
参数: location: 城市名称,如"北京"、"上海" """ # 模拟天气数据(实际使用中可以替换成真实API) weather_db = { "北京": "晴天 25°C", "上海": "多云 28°C", "深圳": "阵雨 30°C", "广州": "阴天 27°C", "杭州": "晴转多云 26°C" } # 查找天气 if location in weather_db: result = f"{location}天气:{weather_db[location]}" else: # 默认返回通用天气 result = f"{location}天气:晴 22°C"
return result
# 创建agentfrom langchain.agents import create_agentagent = create_agent( model="openai:qwen-plus", tools=[getWeather])
# 发起调用response = agent.invoke({ "messages": [ {"role": "user", "content": "今天深圳天气如何"}, ]})
print(response)
3.2 init_chat_model初始化
init_chat_model是 LangChain 提供的一个统一模型初始化函数,它的核心作用是:用同一套代码,无缝切换不同提供商的大语言模型。
from dotenv import load_dotenvfrom langchain.chat_models import init_chat_modelimport os# 在.env文件中添加# OPENAI_API_KEY=XXXXXXXXX# OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
load_dotenv()
model = init_chat_model( model="qwen-plus-2025-07-28", model_provider="openai", # 提供商(qwen不支持自动识别,因此伪装为openai) temperature=0.7, # 随机性 max_tokens=1024, # 输出最大token数 timeout=10, # 请求超时秒数 max_retries=3, # 失败重试次数 top_p=0.5, # 范围 0-1,通常与 temperature 二选一调整 stop=["4.", "4)", "4、"] # 用于控制回复的结束位置)
response = model.invoke("你好,请介绍一下自己")print(response.content)print(type(model))# <class 'langchain_openai.chat_models.base.ChatOpenAI'>3.3 调用方式
3.3.1 invoke
- invoke函数是阻塞式调用,需要等待模型生成全部结果才会返回,等待时间较长
response = model.invoke("message")
response = model.invoke([ {"role":"system","content":"你是一个AI助手"}, {"role":"user","content":"介绍你自己"},])3.3.2 stream
invoke阻塞式调用需要等待较长时间才能看到AI返回的结果,而stream则是流式调用,可以实时看到AI返回的一个个词。
stream = model.stream("你好,请介绍一下自己")print( type(stream)) # <class 'generator'>
for chunk in stream: # 只可遍历一次即内容用完了 print(chunk.content,end="")# 你好!我是......4. 智能体使用模型
4.1创建智能体
Langchain提供了一个create_agent函数用来快速创建智能体。调用create_agent时需要指定一个模型。有两种选择:
- 使用初始化好的模型对象
- 使用模型名称,让Langchain自动初始化模型
from langchain.agents import create_agent
# 方法1:初始化已经定义好的modelagent = create_agent(model=model)
# 方法2:指定model名称agent1 = create_agent("openai:qwen-plus-2025-07-28")4.2 调用智能体
智能体调用与模型调用类似,也支持两种方式:
- invoke:阻塞式调用
- stream:流式访问
但需要注意的是,智能体调用时需要传入一个dict,其中必须包含一个messages字段,也就是消息的列表。
# 方法1:invokeresponse = agent1.invoke({ "messages": [{"role":"user","content":"Hi"}]})print(response["messages"][-1].content)# Hello! ٩(◕‿◕。)۶ How can I assist you today?
# 方法2:streamresponse = agent.stream( {"messages": [{"role":"user","content":"Hi"}]}, stream_mode="messages")
for token, metadata in response: if token.content: print(token.content,end="",flush=True)5. 消息
消息(message),在LangChain中,发送给模型的消息、模型返回的消息都统一被封装为BaseMessage,并且准备了多个BaseMessage的子类对应不同角色类型的消息。
- SystemMessage -> Role: system,代表系统消息,用于设定模型角色和交互背景
- HumanMessage -> Role: user,代表用户输入的消息
- AIMessage -> Role: assistant,代表LLM生成的响应,包含:文本、工具调用、元数据
- ToolMessage -> Role: tool,代表工具调用时产生的结果
我们可以直接使用这些Messages类型来发送消息,以此替代消息数组
5.1 文本消息
'''省略部分,可参考 3.LangChain使用 - 3.1Demo案例'''# 发起调用from langchain_core.messages import SystemMessage, HumanMessage, AIMessageresponse = agent.invoke({ "messages": [ SystemMessage("可以使用工具获取天气状态"), HumanMessage("你好"), AIMessage("你好我是DeepSeek,请问有什么可以帮忙的?"), HumanMessage("香港的天气怎么样?") ]})print(response["messages"][-1].content)# 香港目前天气晴朗,气温为22°C,非常舒适。建议穿着轻便衣物,适合外出活动。for message in response["messages"]: message.pretty_print()'''=== System Message ========================可以使用工具获取天气状态=== Human Message =========================你好=== Ai Message ============================你好我是DeepSeek,请问有什么可以帮忙的?=== Human Message =========================今天香港天气怎么样?===Ai Message =============================Tool Calls: getWeather (call_XXX) Call ID: call_XXX Args: location: 香港=== Tool Message ==========================Name: getWeather香港天气:晴 22°C==== Ai Message ===========================今天香港天气晴朗,气温为22°C。适合外出活动哦!'''5.2 多模态消息
LangChain也支持向模型发送
多模态消息,比如图片、音频、视频、文本等。但前提是必须是多模态模型才支持。以
qwen3.5-omni-flash-2026-03-15为例子
5.2.1 在线图片
# 发送在线图片消息,多模态from langchain.chat_models import init_chat_model# 初始化模型model = init_chat_model( model="qwen3.5-omni-flash-2026-03-15", model_provider="openai", temperature=0.7, max_tokens=1024)
# 创建agentagent = create_agent(model=model)
# 准备多模态消息from langchain_core.messages import SystemMessage, HumanMessage, AIMessagemessage = HumanMessage( [ {"type":"text","text":"这是谁?请通过这张图片的内容进行简要回答即可"}, {"type":"image","url":"https://......."} ])
# 发送请求stream = agent.stream( {"messages": [message]}, stream_mode="messages")for token, metadata in stream: if token.content: print(token.content,end="",flush=True)5.2.2 本地图片
有时候用户会上传图片数据,而不是图片的url地址。我们需要将图片数据转换
base64字符串,然后发送给模型。使用插件
模拟图片上传、转换的过程。uv add ipywidgets
from ipywidgets import FileUpload # 导入文件上传组件from IPython.display import display # 导入显示函数
''' 创建上传控件 1. accept='*' : 接受所有文件类型(也可以指定如 '.txt,.pdf') 2. multiple=False : 不允许同时上传多个文件(True 则允许)'''uploader = FileUpload(accept='*', multiple=False)display(uploader) # 在 notebook 中显示这个控件print (uploader.value)# ({'name': 'OIP-C.jpeg', 'type': 'image/jpeg', 'size': 42998, 'content': <memory at 0x147d32800>, 'last_modified': datetime.datetime(2026, 1, 3, 12, 24, 29, 700000, tzinfo=datetime.timezone.utc)},)
# 读取图片,转为base64字符串import base64uploaded_file = uploader.value[0] # 获取第一个上传的文件content_mv = uploaded_file["content"] # 获取其内存视图img_bytes = bytes(content_mv) # # 转换内存视图->字节 or content_mv.tobytes()img_b64 = base64.b64encode(img_bytes).decode( "utf-8") # base64编码
# 组织多模态消息picture_question = HumanMessage(content=[ { "type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{img_b64}"}}, {"type":"text","text":"简要介绍这个图片里是谁"}])
# 遍历结果for chunk,metadata in agent.stream( {"messages":[picture_question]}, stream_mode="messages"): print(chunk.content,end="",flush=True)6. 提示词
6.1 系统提示词
提示词(Prompt)就是发送给模型的消息,其中SystemMessage是系统提示词(system prompt),可以给模型设定角色、聊天的背景、任务说明,对模型生成的内容有很大的影响。
通过在定义agent的过程中,利用参数system_prompt进行声明相关内容
from langchain.agents import create_agentfrom langchain_core.messages import SystemMessage, HumanMessage, AIMessagefrom langchain.chat_models import init_chat_modelimport osfrom dotenv import load_dotenvload_dotenv()
# 创建modelmodel = init_chat_model( model="qwen-plus-2025-07-28", model_provider="openai", temperature=0.7, max_tokens=1024)
# 创建agentagent = create_agent( model=model, system_prompt="请你以XXX的语气并进行简短回答",)
# 调用智能体for token, metadata in agent.stream( { "messages": [HumanMessage(content="你是谁?")] }, stream_mode="messages"
): print(token.content,end="",flush=True)6.2 提示词工程
所谓提示词工程(Prompt Engineering),就是通过优化提示词使模型输出的结果更符合业务需要的过程
一般来说,系统提示词(SystemPrompt)会包含以下几个部分,通常按此顺序排序
- 身份角色(
Identity):描述AI的职责、沟通风格和总体目标。 - 指令说明(
Instructions):请指导模型如何生成所需的响应。它应该遵循哪些规则?模型应该做什么,以及模型绝对不能做什么? - 对话示例(
Examples):提供可能的输入示例,以及模型期望的输出. - 背景信息(
Context):向模型提供生成响应所需的任何额外信息,例如RAG的额外知识库数据,或您认为特别相关的任何其他数据。
在编写System Prompt时,您可以使用Markdown格式和XML标签的组合来帮助模型理解提示和上下文数据的逻辑边界。
- Markdown的标题和列表有助于标记提示的不同部分,并向模型传达层级结构。它们还可以提高开发过程中提的可读性。
- XML标签可以帮助明确区分一段内容(例如用作参考的辅助文档)的起始和结束位置。
6.2.1 设定角色和指令
添加了指令描述,可以进一步约束模型的行为,什么能做,什么不能做
'''# 身份- 你是一个编程助手,你帮助用户编写Python代码
# 指令- 定义变量时,使用snake case命名法,而不是camel case命名法。- 不要返回markdown格式说明,仅仅返回代码即可。'''6.2.2 对话示例
Few-shot示例是一种为模型提供多个示例的方法,以便它可以学习行为模式并生成更准确的响应。
'''# 身份- 你是一个文本分类助手
# 指令- 请严格遵循以下示例的模式进行分类- 只返回分类结果,不输出任何额外解释
# 示例- 输入:"这个产品太棒了!" → 正面- 输入:"质量很差,不推荐。" → 负面- 输入:"还可以吧,凑合用。" → 中性
# 输出格式- 只输出:正面 / 负面 / 中性'''6.2.3 结构化输出
模型擅长自然语言交流和非结构化数据识别,但是传统程序识别结构化的数据会更加方便。所以有时候我们希望模型也能输出固定结构的内容,方便我们解析。
这可以通过系统提示词来实现,我们可以在提示词中指定模型的输出格式,从而使模型的输出更易于解析和使用。
- 基于提示词的结构化输出
'''# 身份- 你是一个信息提取助手,负责从用户输入中提取结构化数据
# 指令- 严格按 JSON 格式输出- 只输出 JSON,不输出任何额外解释或标记- 缺失的字段用 null 填充
# 输出格式{ "name": "姓名", "age": "年龄(数字)", "city": "城市", "occupation": "职业"}
# 示例用户输入:"我叫张三,今年25岁,在上海做工程师"输出:{"name": "张三", "age": 25, "city": "上海", "occupation": "工程师"}
用户输入:"李四,北京"输出:{"name": "李四", "age": null, "city": "北京", "occupation": null}'''- 基于Model的结构化输出 在LangChain中,实现结构化输出会更加简单。我们无需自己在提示词中添加描述实现结构化输出,而仅仅是两步即可:
- 定义一个数据类型(基于
pydantic) - 创建智能体,设置输出格式
在构建agent中,使用参数response_format
from pydantic import BaseModel# 定义类,用于封装模型所需要输出的数据结构:class CapitalInfo(BaseModel): name: str # 城市名称 location: str # 地理位置 vibe: str # 城市特色/氛围 economy: str # 经济发展
agent = create_agent( model = model, system_prompt="你是一个科幻作家,根据用户的要求创建一个太空之都。", response_format=CapitalInfo)response = agent.invoke( {"messages":[HumanMessage("月球的首都在哪里?")]})city = response['structured_response']print(city) # name='月影城' location='月球静海基地' vibe='宁静而科技感十足' economy='以太空科研和氦-3能源产业为主'7. 工具
模型(Mode)是Agent的大脑,负责推理分析。而工具(Tools)则是Agent的手脚,负责执行任务,与外界交互。
一个完整的Agent至少要包含两个关键的部分:
- 模型:是Agent的大脑,负责推理、分析,规划任务步骤
- 工具:是Agent的手脚,负责执行任务,与外界交互
因此,定义带有工具的Agent的基本流程如下:
- 定义工具
- 初始化模型
- 初始化Agent,绑定模型和工具

7.1 自定义工具
所谓的工具(Tool),本质就是一个可调用的函数,但是这个函数不是我们自己去调用,而是给模型调用。因此除了定义函数外,我们还需要清晰描述这个工具,让模型知道这个工具如何使用。包括下列信息:
- 工具名称
- 工具的作用
- 工具所需要的参数
- 基于Tool描述工具
在LangChain中,定义工具需要用到
@tool装饰器,我们可以通过装饰器来定义工具名、工具的作用:
from langchain_core.tools import tool@tool("square_tool",description="用于计算一个数的平方根值")def square_tool(x:float)->float: return x**2- 使用函数名和文档注释描述工具
如果不使用@tool装饰器没有定义工具名和作用描述,此时:
- 工具名:默认就是函数名
- 工具所需的参数:默认就是函数的参数列表
- 工具作用的描述:默认就是函数的文档注释
from langchain_core.tools import tool@tooldef square_tool(x:float)->float: """用于计算一个数的平方值""" return x**2@tooldef get_weather(location: str, units: str = "celsius", include_forecast: bool = False) -> str: """ 获取当前天气和可选的天气预报。
参数: location: 城市名称或坐标 units: 温度单位 include_forecast: 是否包含天气预报 """ temp = 22 if units == "celsius" else 72 result = f"{location}当前天气:{temp} 度 {units[0].upper()}" if include_forecast: result += "\n未来5天:晴朗" return result
get_weather.invoke({"location":"HongKong","units":"celsius","include_forecast":False})- 定义PydanticModel描述参数
如果函数的参数比较多,而且比较复杂,此时建议通过pydantic model来描述参数列表。
# 通过自定义模型约束入参from pydantic import BaseModel, Fieldfrom typing import Literal # 枚举
# 天气查询工具的输入参数模型class WeatherInput(BaseModel): location: str = Field(description="城市名或坐标") units: Literal["celsius", "fahrenheit"] = Field( default="celsius", description="温度单位" ) include_forecast: bool = Field( default=False, description="是否包含5天预报" )
@tool(args_schema=WeatherInput) # 参数约束 args_schemadef get_weather(location: str, units: str = "celsius", include_forecast: bool = False) -> str: """获取当前天气和可选的天气预报。""" temp = 22 if units == "celsius" else 72 result = f"{location}当前天气:{temp} 度 {units[0].upper()}" if include_forecast: result += "\n未来5天:晴朗" return result7.2 预定义工具
以TavilySearch为例,每月1000次免费搜索(实际情况以官网为准)
- 初步认识工具
from langchain_tavily import TavilySearchfrom dotenv import load_dotenvimport osload_dotenv()
search_tool = TavilySearch( max_results=5, # 最大返回结果数 topic="general", # 搜索主题:general/news/finance # include_answer=False, # 是否包含AI生成答案 # include_raw_content=False, # 是否包含完整页面内容 # include_images=False, # 是否包含图片列表 # include_image_descriptions=False,# 是否包含图片描述 # search_depth="basic", # 搜索深度:basic/advanced # time_range="day", # 时间过滤:day/week/month/year # include_domains=None, # 限定域名列表 # exclude_domains=None # 排除域名列表)search_tool.invoke({"query": "上周热点新闻有哪些?简短回答即可"})- 实践使用
from langchain.chat_models import init_chat_modelfrom langchain.agents import create_agentfrom langchain.messages import HumanMessage, AIMessage, SystemMessage
model = init_chat_model( model="qwen-plus-2025-07-28", model_provider="openai", temperature=0.7, max_tokens=1024)agent = create_agent( model=model, tools=[search_tool])
response = agent.invoke( {"messages":[HumanMessage("上周知乎热点有哪些,简要回答列表10个即可")]})
print(response["messages"][-1].content)- 工具优化
- 使用
@tool装饰器将 TavilySearch 实例包装为 LangChain 工具,使其可被 Agent 直接调用 - 定义
AnswerInfo和Reference结构化输出模型,强制 Agent 返回包含答案和引用来源的规范格式
tavily = TavilySearch( max_results=5, topic="general",)
@tooldef web_search(query:str): """用于Web网页信息检索""" return tavily.invoke(query)
from pydantic import BaseModel,Field# Agent回答内容引用的网页信息class Reference(BaseModel): title: str = Field(description="答案中引用的网页标题") url: str = Field(description="答案中引用的网页链接")
# Agent的回答内容class AnswerInfo(BaseModel): answer: str = Field(description="给用户的最终答案") reference: list[Reference] = Field(description="答案所引用的网页")
model = init_chat_model( model="qwen-plus-2025-07-28", model_provider="openai", temperature=0.7, max_tokens=1024)
agent = create_agent( model=model, tools=[web_search], system_prompt="你是一个智能助手,用于解决用户问题", response_format=AnswerInfo # 控制 Agent 返回结构化数据的核心参数)
response = agent.invoke( {"messages":[HumanMessage("知乎今日热点都有哪些?")]})
structured = response["structured_response"]print("=== 答案 ===")print(structured.answer)print("\n=== 引用来源 ===")for idx, ref in enumerate(structured.reference, 1): print(f"{idx}. {ref.title}") print(f" 链接:{ref.url}")
'''=== 答案 ===知乎的今日热点内容通常包括实时讨论度高的社会事件、科技动态、文化娱乐等话题。您可以通过知乎App或网页端的“今日热点”话题页(如 https://www.zhihu.com/topic/23509571)查看最新热门讨论。此外,聚合类平台如“今日热榜”(tophub.today)也提供知乎实时热点榜单,便于一站式浏览全网热点。
=== 引用来源 ===1. 今日热点 - 知乎 链接:https://www.zhihu.com/topic/235095712. 真的能追溯微博、知乎等历史热门榜单吗? 链接:https://zhuanlan.zhihu.com/p/1925271264437733172'''