LangChain基本安装与使用
一、LLM大语言模型
1.LangChain大模型基本运行逻辑
用户
↓
LLM.invoke()
↓
决定调用工具
↓
Tool.invoke()
↓
返回结果
↓
LLM.invoke()
↓
生成最终回答
Q:LangChain为什么设计invoke()让各种不同的类型都有这个方法
A:因为它想统一接口,这样使框架内部就不需要区分这是工具、模型还是Agent
2.LLM的基本调用
from init_llm import deepseek_llm
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
from langchain_core.tools import tool
# 模拟返回指定地区的天气
@tool
def get_weather(location:str) -> str:
"""获取指定位置的天气"""
return f"{location}的天气是晴朗"
# 模拟返回指定地区的时间
@tool
def get_time(location:str) -> str:
"""获取当前时间"""
return f"{location}的时间是2023年6月1日"
#1.给模型绑定工具
model_with_tool = deepseek_llm.bind_tools([get_weather,get_time])
message = []
message.append(HumanMessage(content = "宁夏的天气如何?宁夏的时间是什么?"))
# 2.模型返回要调用的工具,模型不会直接调用工具
# 让模型循环调用所有需要的工具。如果还有需要调用的工具,模型会继续调用
while True:
response = model_with_tool.invoke(message)
message.append(response)
#3. 根据模型返回的调用工具指令,调用工具
if response.tool_calls:
for tool_call in response.tool_calls:
# 获取天气工具
if tool_call["name"] == "get_weather":
tool_msg = get_weather.invoke(tool_call)
message.append(tool_msg)
print("获取天气工具调用")
# 获取时间工具
if tool_call["name"] == "get_time":
tool_msg = get_time.invoke(tool_call)
message.append(tool_msg)
print("获取时间工具调用")
else:
break
result = model_with_tool.invoke(message)
# 4.将工具的结果交给LLM进行推理,返回最终结果
print(message)
print(type(result))
print("\n"*5)
print(result)
二、Agent智能体
1.Agent的基本调用
from init_llm import deepseek_llm
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
from langchain_core.tools import tool
from langchain.agents import create_agent
# 模拟返回指定地区的天气
@tool
def get_weather(location:str) -> str:
"""获取指定位置的天气"""
return f"{location}的天气是晴朗"
# 模拟返回指定地区的时间
@tool
def get_time(location:str) -> str:
"""获取当前时间"""
return f"{location}的时间是2023年6月1日"
agent = create_agent(
model = deepseek_llm,
tools = [get_weather,get_time]
)
resp = agent.invoke({"messages":[{"role":"user","content":"给我查询宁夏的天气和时间"}]})
print(resp)
三、模型调用中间件(Middleware)
作用:它允许你在 Agent 调用 LLM 前后插入自己的逻辑。允许动态修改,模型
依赖
导包
from langchain.agents.middleware import (
wrap_model_call,
ModelRequest,
ModelResponse,
)
钩子函数触发时机
Agent
↓
middleware开始
↓
handler(request)
↓
真正调用LLM
↓
获得响应
↓
middleware结束
动态切换模型示例(@wrap_model_call)
init_llm.py
from langchain.chat_models import init_chat_model
from env_utils import *
# 通过统一通用方式
deepseek_llm = init_chat_model(
model = "deepseek-v4-flash",
model_provider="deepseek",
api_key = deepseek_api_key,
base_url = deepseek_base_url
)
mimo_llm = init_chat_model(
model = mimo_model,
model_provider="openai",
api_key = mimo_api_key,
base_url = mimo_base_url
)
# resp = deepseek_llm.invoke("你是谁")
resp = mimo_llm.invoke("你是谁")
print(type(resp))
print(resp)
04_agent_switch.py
from init_llm import deepseek_llm,mimo_llm
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
from langchain_core.tools import tool
from langchain.agents import create_agent
from langchain.agents.middleware import (
wrap_model_call,
ModelRequest,
ModelResponse,
)
# 模拟返回指定地区的天气
@tool
def get_weather(location:str) -> str:
"""获取指定位置的天气"""
return f"{location}的天气是晴朗"
# 模拟返回指定地区的时间
@tool
def get_time(location:str) -> str:
"""获取当前时间"""
return f"{location}的时间是世界末日前一天"
@wrap_model_call
# handler对象是一个函数
def dynamic_model_selection(request:ModelRequest,handler) -> ModelResponse:
"""动态选择模型"""
message_count = len(request.state["messages"])
if message_count > 2:
model = mimo_llm
print("使用mimo模型")
else:
model = deepseek_llm
print("使用deepseek模型")
return handler(request.override(model=model))
agent = create_agent(
# 设置模型
model = deepseek_llm,
# 设置工具
tools = [get_weather,get_time],
# 设置中间件
middleware=[dynamic_model_selection]
)
resp = agent.invoke({"messages":[{"role":"user","content":"给我查询宁夏的天气和时间"}]})
print(resp)
输出示例
{
"messages": [
# 用户消息
HumanMessage(
content="给我查询宁夏的天气和时间",
id="272a4962-65cf-40e8-be1e-3974be90fb0e"
),
# 第一次模型调用(DeepSeek)
AIMessage(
content="好的,我来同时查询宁夏的天气和当前时间。",
additional_kwargs={
"refusal": None,
"reasoning_content":
"用户想查询宁夏的天气和时间。"
"宁夏是一个省级行政区,我需要分别查询天气和时间。"
"对于天气,我可以使用 get_weather 工具,"
"对于时间,可以使用 get_time 工具。"
"我可以同时发起这两个请求。"
},
response_metadata={
"model_provider": "deepseek",
"model_name": "deepseek-v4-flash",
"finish_reason": "tool_calls",
"token_usage": {
"prompt_tokens": 321,
"completion_tokens": 133,
"total_tokens": 454,
"completion_tokens_details": {
"reasoning_tokens": 47
}
}
},
tool_calls=[
{
"name": "get_weather",
"args": {
"location": "宁夏"
},
"id": "call_00_Nqum1NWdQ6bC21GpSCHj7217"
},
{
"name": "get_time",
"args": {
"location": "宁夏"
},
"id": "call_01_GlSdCuILkB4bO5zAsZE42895"
}
]
),
# Tool 1 返回
ToolMessage(
name="get_weather",
content="宁夏的天气是晴朗",
tool_call_id="call_00_Nqum1NWdQ6bC21GpSCHj7217"
),
# Tool 2 返回
ToolMessage(
name="get_time",
content="宁夏的时间是世界末日前一天",
tool_call_id="call_01_GlSdCuILkB4bO5zAsZE42895"
),
# 第二次模型调用(Mimo)
AIMessage(
content=
"""
根据查询结果,宁夏的天气是晴朗,适合户外活动。
关于时间,系统返回的信息“世界末日前一天”
可能是测试数据或错误信息,
建议您通过手机、电脑或其他可靠方式确认当前准确时间。
温馨提示:
虽然天气晴朗,
但宁夏昼夜温差较大,
如果您外出请注意适当增减衣物,
做好防晒措施。
需要我为您查询更具体的宁夏某个城市的信息吗?
""",
response_metadata={
"model_provider": "openai",
"model_name": "mimo-v2-pro",
"finish_reason": "stop",
"token_usage": {
"prompt_tokens": 642,
"completion_tokens": 302,
"total_tokens": 944,
"completion_tokens_details": {
"reasoning_tokens": 213
}
}
}
)
]
}
动态调整提示词示例(@dynamic_prompt)
from init_llm import deepseek_llm,mimo_llm
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
from langchain_core.tools import tool
from langchain.agents import create_agent
from langchain.agents.middleware import (
wrap_model_call,
ModelRequest,
ModelResponse,
dynamic_prompt
)
# 模拟返回指定地区的天气
@tool
def get_weather(location:str) -> str:
"""获取指定位置的天气"""
return f"{location}的天气是晴朗"
# 模拟返回指定地区的时间
@tool
def get_time(location:str) -> str:
"""获取当前时间"""
return f"{location}的时间是世界末日前一天"
@wrap_model_call
# handler对象是一个函数
def dynamic_model_selection(request:ModelRequest,handler) -> ModelResponse:
"""动态选择模型"""
message_count = len(request.state["messages"])
if message_count > 2:
model = mimo_llm
print("使用mimo模型")
else:
model = deepseek_llm
print("使用deepseek模型")
return handler(request.override(model=model))
# 动态中间件,动态修改提示词
@dynamic_prompt
def dynamic_support_prompt(request:ModelRequest) -> str:
""" 动态修改提示词 """
user_type = request.runtime.context['user_type']
print("用户身份:",user_type)
# 判断用户身份生成相应提示词
if user_type == "VIP":
return "你是一个天气分析专家,能够回答关于天气和时间的问题,且回答更加详细。在回答用户的问题前,称呼用户“尊敬的VIP用户,您好!”。"
else:
return f"你是一个普通用户,只能回答部分问题。在回答用户的问题前,称呼用户“尊敬的{user_type}用户,您好!”。"
agent = create_agent(
# 设置模型
model = deepseek_llm,
# 设置工具
tools = [get_weather,get_time],
# 设置中间件
middleware=[dynamic_model_selection,dynamic_support_prompt]
)
resp = agent.invoke(
{"messages":[{"role":"user","content":"给我查询宁夏的天气和时间"}]},
context={"user_type":"杂鱼"},
)
print(resp)
print(resp["messages"][-1].content)
注:
agent.invoke()方法中可以使用context属性预设信息

浙公网安备 33010602011771号