这里涉及的不是单次工具,而是多次多个工具,我以为比较有借鉴性,作个录入。
比较好的实践,是需要很好的结合这两者的。
代码
import os
from langchain_core.messages import HumanMessage
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
# 加载环境变量
from dotenv import load_dotenv
load_dotenv()
deepseek_api_key = os.getenv("DEEPSEEK_API_KEY")
llm = ChatOpenAI(
model_name="deepseek-chat",
openai_api_key=deepseek_api_key,
openai_api_base="https://api.deepseek.com/v1",
temperature=0.3
)
from langgraph.graph import StateGraph, MessagesState, START, END
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate
from langgraph.prebuilt import ToolNode
# 1. 定义工具(LangChain)
@tool
def calculate(expression: str) -> str:
"""执行数学计算"""
return str(eval(expression))
tools = [calculate]
# 2. 定义提示词(LangChain)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个数学助手,可以使用计算工具"),
("placeholder", "{messages}")
])
# 3. 定义 Agent 节点(LangChain + LangGraph)
def agent(state: MessagesState):
llm_bind_tools = llm.bind_tools(tools)
chain = prompt | llm_bind_tools
response = chain.invoke({"messages": state["messages"]})
return {"messages": [response]}
# 4. 条件路由(LangGraph)
def should_continue(state: MessagesState):
last_message = state["messages"][-1]
if hasattr(last_message, "tool_calls") and last_message.tool_calls:
return "tools"
return END
# 5. 构建图(LangGraph)
graph = StateGraph(MessagesState)
graph.add_node("agent", agent)
graph.add_node("tools", ToolNode(tools))
graph.add_edge(START, "agent")
graph.add_conditional_edges("agent", should_continue)
graph.add_edge("tools", "agent")
app = graph.compile()
# 🎨 可视化图结构
from IPython.display import Image, display
display(Image(app.get_graph().draw_mermaid_png()))
# 6. 测试
response = app.invoke({
"messages": [("user", "计算 (25 + 75) * 2 / 10,再计算(9 / 3) * (5-2)")]
})
print(response["messages"][-1].content)
输出
<IPython.core.display.Image object>
第二个表达式的结果是:9
总结:
1. (25 + 75) × 2 ÷ 10 = 20
2. (9 ÷ 3) × (5 - 2) = 9
进程已结束,退出代码为 0