Skip to main content
Open In ColabOpen on GitHub

从LLMMathChain迁移

LLMMathChain 使得由LLM生成的数学表达式的评估成为可能。生成表达式的指令被格式化为提示,并在使用numexpr库进行评估之前,从字符串响应中解析出表达式。

这更自然地通过工具调用实现。我们可以利用numexpr为聊天模型配备一个简单的计算器工具,并使用LangGraph围绕它构建一个简单的链。这种方法的一些优点包括:

  • 利用为此目的而微调的聊天模型的工具调用能力;
  • 减少从字符串LLM响应中提取表达式时的解析错误;
  • 将指令委托给消息角色(例如,聊天模型可以理解ToolMessage表示的内容,而无需额外的提示);
  • 支持流式传输,包括单个令牌和链步骤。
%pip install --upgrade --quiet numexpr
import os
from getpass import getpass

if "OPENAI_API_KEY" not in os.environ:
os.environ["OPENAI_API_KEY"] = getpass()

遗留问题

Details
from langchain.chains import LLMMathChain
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")

chain = LLMMathChain.from_llm(llm)

chain.invoke("What is 551368 divided by 82?")
{'question': 'What is 551368 divided by 82?', 'answer': 'Answer: 6724.0'}

LangGraph

Details
import math
from typing import Annotated, Sequence

import numexpr
from langchain_core.messages import BaseMessage
from langchain_core.runnables import RunnableConfig
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.graph import END, StateGraph
from langgraph.graph.message import add_messages
from langgraph.prebuilt.tool_node import ToolNode
from typing_extensions import TypedDict


@tool
def calculator(expression: str) -> str:
"""Calculate expression using Python's numexpr library.

Expression should be a single line mathematical expression
that solves the problem.

Examples:
"37593 * 67" for "37593 times 67"
"37593**(1/5)" for "37593^(1/5)"
"""
local_dict = {"pi": math.pi, "e": math.e}
return str(
numexpr.evaluate(
expression.strip(),
global_dict={}, # restrict access to globals
local_dict=local_dict, # add common mathematical functions
)
)


llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
tools = [calculator]
llm_with_tools = llm.bind_tools(tools, tool_choice="any")


class ChainState(TypedDict):
"""LangGraph state."""

messages: Annotated[Sequence[BaseMessage], add_messages]


async def acall_chain(state: ChainState, config: RunnableConfig):
last_message = state["messages"][-1]
response = await llm_with_tools.ainvoke(state["messages"], config)
return {"messages": [response]}


async def acall_model(state: ChainState, config: RunnableConfig):
response = await llm.ainvoke(state["messages"], config)
return {"messages": [response]}


graph_builder = StateGraph(ChainState)
graph_builder.add_node("call_tool", acall_chain)
graph_builder.add_node("execute_tool", ToolNode(tools))
graph_builder.add_node("call_model", acall_model)
graph_builder.set_entry_point("call_tool")
graph_builder.add_edge("call_tool", "execute_tool")
graph_builder.add_edge("execute_tool", "call_model")
graph_builder.add_edge("call_model", END)
chain = graph_builder.compile()
# Visualize chain:

from IPython.display import Image

Image(chain.get_graph().draw_mermaid_png())

# Stream chain steps:

example_query = "What is 551368 divided by 82"

events = chain.astream(
{"messages": [("user", example_query)]},
stream_mode="values",
)
async for event in events:
event["messages"][-1].pretty_print()
================================ Human Message =================================

What is 551368 divided by 82
================================== Ai Message ==================================
Tool Calls:
calculator (call_1ic3gjuII0Aq9vxlSYiwvjSb)
Call ID: call_1ic3gjuII0Aq9vxlSYiwvjSb
Args:
expression: 551368 / 82
================================= Tool Message =================================
Name: calculator

6724.0
================================== Ai Message ==================================

551368 divided by 82 equals 6724.

下一步

查看构建和使用工具的指南这里

查看LangGraph文档以获取使用LangGraph构建的详细信息。


这个页面有帮助吗?