這里涉及的不是單次工具,而是多次多個工具,我以為比較有借鑒性,作個錄入。
比較好的實踐,是需要很好的結(jié)合這兩者的。
代碼
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
# 加載環(huán)境變量
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:
"""執(zhí)行數(shù)學(xué)計算"""
return str(eval(expression))
tools = [calculate]
# 2. 定義提示詞(LangChain)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一個數(shù)學(xué)助手,可以使用計算工具"),
("placeholder", "{messages}")
])
# 3. 定義 Agent 節(jié)點(diǎn)(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. 構(gòu)建圖(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()
# ?? 可視化圖結(jié)構(gòu)
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>
第二個表達(dá)式的結(jié)果是:9
總結(jié):
1. (25 + 75) × 2 ÷ 10 = 20
2. (9 ÷ 3) × (5 - 2) = 9
進(jìn)程已結(jié)束,退出代碼為 0