作者:CSDN博客
一、Agent调用tool
定义tool函数,其中注释 “add two int number”,必须要有否则会报错;- @tool
- def add(a:int, b:int) -> int:
- """add two int number""" # 这个必须有,而且很重要,是要输入到LLM;
- return a + b
复制代码 完整代码:- from langchain_openai import ChatOpenAI
- from langgraph.checkpoint.memory import InMemorySaver
- from langgraph.graph import StateGraph, START, END
- from langgraph.graph.message import add_messages
- from langgraph.prebuilt import ToolNode, tools_condition
- from langgraph.types import Command, interrupt
- llm = ChatOpenAI(
- model="Qwen3-4B-Instruct-2507",
- openai_api_base="http:/localhost:8000/v1", # vLLM 服务的地址
- openai_api_key="EMPTY", # vLLM 通常不需要 API key,但 LangChain 要求设置,可设为任意值如 "EMPTY"
- temperature=0.7,
- max_tokens=1024
- )
- class State(TypedDict):
- messages: Annotated[list, add_messages]
- graph_builder = StateGraph(State)
- @tool
- def add(a:int, b:int) -> int:
- """add two int number"""
- return a + b
- tools = [add]
- llm_with_tools = llm.bind_tools(tools)
- def chatbot(state: State):
- message = llm_with_tools.invoke(state["messages"])
- assert(len(message.tool_calls) <= 1)
- return {"messages": [message]}
- graph_builder.add_node("chatbot", chatbot)
- tool_node = ToolNode(tools=tools)
- graph_builder.add_node("tools", tool_node)
- graph_builder.add_conditional_edges(
- "chatbot",
- tools_condition,
- )
- graph_builder.add_edge("tools", "chatbot")
- graph_builder.add_edge(START, "chatbot")
- graph = graph_builder.compile()
- def print_stream(stream):
- for s in stream:
- message = s["messages"][-1]
- if isinstance(message, tuple):
- print(message)
- else:
- message.pretty_print()
- while True:
- try:
- user_input = input("User: ")
- if user_input.lower() in ["quit", "exit", "q"]:
- print("Goodbye!")
- break
- print_stream(graph.stream({"messages": [{"role": "user", "content": user_input}]}, stream_mode="values"))
- except:
- user_input = "What do you know about LangGraph?"
- print("User: " + user_input)
- print_stream(graph.stream({"messages": [{"role": "user", "content": user_input}]}, stream_mode="values"))
- break
复制代码
执行的过程:
1、user输入 “1+1”,调用LLM
2、LLM返回调用工具说明 “Tool Calls”,
3、调用工具生成结果 “2”;
4、将结果输入到LLM;
5、LLM 返回最终的结果 “The result of 1 + 1 is 2.”
输出如下:- User: 1+1
- ================================ Human Message =================================
- 1+1
- ================================== Ai Message ==================================
- Tool Calls:
- add (chatcmpl-tool-2b1940050a9548d68a299f1a2ee88ede)
- Call ID: chatcmpl-tool-2b1940050a9548d68a299f1a2ee88ede
- Args:
- a: 1
- b: 1
- ================================= Tool Message =================================
- Name: add
- 2
- ================================== Ai Message ==================================
- The result of 1 + 1 is 2.
复制代码 二、LLM服务
从LLM服务的后台日志,查看Agent调用tool的流程;
1、第一次调用LLM
当客户端输入 “1+1”时,LLM服务端接受的输入,如下:- prompt: '<|im_start|>system\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n
- <tools>\n{
- "type": "function",
- "function": {
- "name": "add",
- "description": "add two int number",
- "parameters": {
- "properties": {
- "a": {
- "type": "integer"
- },
- "b": {
- "type": "integer"
- }
- },
- "required": ["a", "b"],
- "type": "object"
- }
- }
- }\n</tools>
- \n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n
- <tool_call>\n{
- "name": < function -name > ,
- "arguments": < args - json - object >
- }\n</tool_call><|im_end|>\n
- <|im_start|>user\n1+1<|im_end|>\n<|im_start|>assistant\n',
复制代码 上述输入包含了:
系统提示词 :“system\n# Tools\n\nYou may ...”
函数定义的说明 <tools>...</tools>
函数调用返回的格式<tool_call>...</tool_call>
用户的输入 “1+1”
2、LLM的Response:
LLM的输出见下图:
content字段是None;
tool_calls 字段说明的调用的tool函数的名称、参数等;
3、第二次调用LLM
前端根据上述大模型的结果,调用tool后生成结果“2”,再次调用LLM,输入:- prompt: '<|im_start|>system\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>\n
- {
- "type": "function",
- "function": {
- "name": "add",
- "description": "add two int number",
- "parameters": {
- "properties": {
- "a": {
- "type": "integer"
- },
- "b": {
- "type": "integer"
- }
- },
- "required": ["a", "b"],
- "type": "object"
- }
- }
- }\n
- </tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n
- <tool_call>\n
- {
- "name": < function -name > ,
- "arguments": < args - json - object >
- }
- </tool_call><|im_end|>\n<|im_start|>user\n1+1<|im_end|>\n<|im_start|>assistant\n<tool_call>\n
- {
- "name": "add",
- "arguments": {
- "a": 1,
- "b": 1
- }
- }\n
- </tool_call><|im_end|>\n<|im_start|>user\n
- <tool_response>\n
- 2
- \n</tool_response>
- <|im_end|>\n<|im_start|>assistant\n'
复制代码 上述包含了除了之前的系统提示、函数说明等,还追加了调用具体函数的名称、参数以及返回的结果;
4、LLM第二次reponse
content字段是大模型输出结果
(完)
原文地址:https://blog.csdn.net/Mrhiuser/article/details/151760868 |