精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

一文徹底搞懂智能體Agent基于ReAct的工具調用

人工智能
AI智能體是指具備一定自主性、能感知環境并通過智能決策執行特定任務的軟件或硬件實體。它結合了人工智能技術,能夠獨立或協作完成目標。本文包含ReAct基礎,基于ReAct的工具調用流程和涉及的交互消息,手搓Agent代碼實現基于ReAct的工具調用。

前言

AI智能體是指具備一定自主性、能感知環境并通過智能決策執行特定任務的軟件或硬件實體。它結合了人工智能技術(如機器學習、自然語言處理、計算機視覺等),能夠獨立或協作完成目標。

基于大語言模型(LLM)的Function Calling可以令智能體實現有效的工具使用和與外部API的交互。支持Function Calling的模型(如gpt-4,qwen-plus等)能夠檢測何時需要調用函數,并輸出調用函數的函數名和所需參數的JSON格式結構化數據。

但并非所有的LLM模型都支持Function Calling(如deepseek-v3)。對于不支持Function Calling的模型,可通過ReAct的相對較為復雜的提示詞工程,要求模型返回特定格式的響應,以便區分不同的階段(思考、行動、觀察)。

工具調用主要有兩個用途:

  • 獲取數據: 例如根據關鍵字從知識庫檢索內容、通過特定API接口獲取業務數據
  • 執行行動: 例如通過API接口修改業務狀態數據、執行預定業務操作

本文包含如下內容:

  • ReAct基礎
  • 詳細介紹基于ReAct的工具調用流程和涉及的交互消息
  • 手搓Agent代碼實現基于ReAct的工具調用

ReAct基礎

ReAct源于經典論文: REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS (鏈接:https://arxiv.org/pdf/2210.03629)

基于ReAct的智能體為了解決問題,需要經過幾個階段

  • Thought: 思考推理
  • Action:作出行動,決定要調用的工具和參數
  • Observation:行動的結果(工具輸出)

以上3個階段可能迭代多次,直到問題得到解決或者達到迭代次數上限。

基于ReAct的工具調用依賴于復雜的提示詞工程。系統提示詞參考langchain的模板:

Answer the following questions as best you can. You have access to the following tools:
{tool_strings}


The way you use the tools is by specifying a json blob.
Specifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).


The only values that should be in the "action" field are: {tool_names}


The $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:


```
{{{{
"action": $TOOL_NAME,
"action_input": $INPUT
}}}}
```


ALWAYS use the following format:


Question: the input question you must answer
Thought: you should always think about what to do
Action:
```
$JSON_BLOB
```
Observation: the result of the action
... (this Thought/Action/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question


Begin! Reminder to always use the exact characters `Final Answer` when responding.

基于ReAct的工具調用流程和交互消息

我們以查詢北京和廣州天氣為例,LLM采用阿里云的deepseek-v3。查詢天氣的流程如下圖:

1. 發起查詢請求

向LLM發起查詢時,messages列表有2條messages:

  • 第1條role為system,定義了系統提示詞(含工具定義)
  • 第2條role為user,包含如下內容:

     Question: 北京和廣州天氣怎么樣

我們用curl發起POST請求,body的JSON結構可參考https://platform.openai.com/docs/api-reference/chat/create 。

請求里的stop字段需要設置為Observation:,否則LLM會直接輸出整個Thought/Action/Observation流程并給出虛構的最終答案。我們僅需要LLM輸出Thought/Action即可

#!/bin/bash
export OPENAI_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
export OPENAI_API_KEY="sk-xxx" # 替換為你的key


curl ${OPENAI_BASE_URL}/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
  "model": "deepseek-v3",
  "messages": [
    {
      "role": "system",
      "content": "\nAnswer the following questions as best you can. You have access to the following tools:\n{\"name\": \"get_weather\", \"description\": \"Get weather\", \"parameters\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\", \"description\": \"the name of the location\"}}, \"required\": [\"location\"]}}\n\n\nThe way you use the tools is by specifying a json blob.\nSpecifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).\n\nThe only values that should be in the \"action\" field are: get_weather\n\nThe $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:\n\n```\n{{\n\"action\": $TOOL_NAME,\n\"action_input\": $INPUT\n}}\n```\n\nALWAYS use the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction:\n```\n$JSON_BLOB\n```\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\n\nBegin! Reminder to always use the exact characters `Final Answer` when responding. \n"
    },
    {
      "role": "user",
      "content": "Question: 北京和廣州天氣怎么樣\n\n"
    }
  ],
  "stop": "Observation:"
}'

2. LLM返回Action獲取北京天氣

LLM經過推理,發現需要先調用函數獲取北京天氣。

Thought: 我需要獲取北京和廣州的天氣信息。首先,我將獲取北京的天氣。
Action:
```
{
  "action": "get_weather",
  "action_input": {
    "location": "北京"
  }
}
```

完整的JSON響應如下:

{
  "choices": [
    {
      "message": {
        "content": "Thought: 我需要獲取北京和廣州的天氣信息。首先,我將獲取北京的天氣。\n\nAction:\n```\n{\n  \"action\": \"get_weather\",\n  \"action_input\": {\n    \"location\": \"北京\"\n  }\n}\n```",
        "role": "assistant"
      },
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null
    }
  ],
  "object": "chat.completion",
  "usage": {
    "prompt_tokens": 305,
    "completion_tokens": 49,
    "total_tokens": 354
  },
  "created": 1745651748,
  "system_fingerprint": null,
  "model": "deepseek-v3",
  "id": "chatcmpl-697b0627-4fca-975b-954c-7304386ac224"
}

3. 處理函數調用獲取北京天氣

解析處理LLM的Action獲得函數名和參數列表,調用相應的API接口獲得結果。

例如:通過http://weather.cma.cn/api/now/54511可獲得北京的天氣情況。

完整的JSON響應如下:

{
  "msg": "success",
  "code": 0,
  "data": {
    "location": {
      "id": "54511",
      "name": "北京",
      "path": "中國, 北京, 北京"
    },
    "now": {
      "precipitation": 0.0,
      "temperature": 23.4,
      "pressure": 1005.0,
      "humidity": 43.0,
      "windDirection": "西南風",
      "windDirectionDegree": 216.0,
      "windSpeed": 2.7,
      "windScale": "微風",
      "feelst": 23.1
    },
    "alarm": [],
    "jieQi": "",
    "lastUpdate": "2025/04/26 15:00"
  }
}

4. 把上下文信息以及函數調用結果發給LLM

發給LLM的messages列表有2條messages:

  • 第1條role為system,定義了系統提示詞(含工具定義)
  • 第2條role為user,包含如下內容:

     Question: 北京和廣州天氣怎么樣

     Thought: 我需要獲取北京和廣州的天氣信息。首先,我將獲取北京的天氣

     Action: {"action":"get_weather","action_input":{"location":"北京"}}

     Observation: 工具調用get_weather('北京')的結果

#!/bin/bash
export OPENAI_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
export OPENAI_API_KEY="sk-xxx" # 替換為你的key


curl ${OPENAI_BASE_URL}/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
  "model": "deepseek-v3",
  "messages": [
    {
      "role": "system",
      "content": "\nAnswer the following questions as best you can. You have access to the following tools:\n{\"name\": \"get_weather\", \"description\": \"Get weather\", \"parameters\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\", \"description\": \"the name of the location\"}}, \"required\": [\"location\"]}}\n\n\nThe way you use the tools is by specifying a json blob.\nSpecifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).\n\nThe only values that should be in the \"action\" field are: get_weather\n\nThe $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:\n\n```\n{{\n\"action\": $TOOL_NAME,\n\"action_input\": $INPUT\n}}\n```\n\nALWAYS use the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction:\n```\n$JSON_BLOB\n```\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\n\nBegin! Reminder to always use the exact characters `Final Answer` when responding. \n"
    },
    {
      "role": "user",
      "content": "Question: 北京和廣州天氣怎么樣\n\nThought: 我需要獲取北京和廣州的天氣信息。首先,我將獲取北京的天氣。\n\nAction:\n```\n{\n\"action\": \"get_weather\",\n\"action_input\": {\n\"location\": \"北京\"\n}\n}\n```\nObservation: {\"msg\":\"success\",\"code\":0,\"data\":{\"location\":{\"id\":\"54511\",\"name\":\"北京\",\"path\":\"中國, 北京, 北京\"},\"now\":{\"precipitation\":0.0,\"temperature\":23.4,\"pressure\":1005.0,\"humidity\":43.0,\"windDirection\":\"西南風\",\"windDirectionDegree\":216.0,\"windSpeed\":2.7,\"windScale\":\"微風\",\"feelst\":23.1},\"alarm\":[],\"jieQi\":\"\",\"lastUpdate\":\"2025/04/26 15:00\"}}\n"
    }
  ],
  "stop": "Observation:"
}'

5. LLM返回Action獲取廣州天氣

LLM經過推理,發現還需要調用函數獲取廣州天氣。

Thought: 我已經獲取了北京的天氣信息。接下來,我將獲取廣州的天氣信息。
Action:
```
{
  "action": "get_weather",
  "action_input": {
    "location": "廣州"
  }
}
```

完整的JSON響應如下:

{
  "choices": [
    {
      "message": {
        "content": "Thought: 我已經獲取了北京的天氣信息。接下來,我將獲取廣州的天氣信息。\n\nAction:\n```\n{\n\"action\": \"get_weather\",\n\"action_input\": {\n\"location\": \"廣州\"\n}\n}\n```\nObservation",
        "role": "assistant"
      },
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null
    }
  ],
  "object": "chat.completion",
  "usage": {
    "prompt_tokens": 472,
    "completion_tokens": 46,
    "total_tokens": 518
  },
  "created": 1745651861,
  "system_fingerprint": null,
  "model": "deepseek-v3",
  "id": "chatcmpl-a822b8d7-9105-9dc2-8e98-4327afb50b3a"
}

6. 處理函數調用獲取廣州天氣

解析處理LLM的Action獲得函數名和參數列表,調用相應的API接口獲得結果。

例如:通過http://weather.cma.cn/api/now/59287可獲得廣州的天氣情況。

完整的JSON響應如下:

{
  "msg": "success",
  "code": 0,
  "data": {
    "location": {
      "id": "59287",
      "name": "廣州",
      "path": "中國, 廣東, 廣州"
    },
    "now": {
      "precipitation": 0.0,
      "temperature": 24.2,
      "pressure": 1005.0,
      "humidity": 79.0,
      "windDirection": "東北風",
      "windDirectionDegree": 31.0,
      "windSpeed": 1.3,
      "windScale": "微風",
      "feelst": 27.1
    },
    "alarm": [],
    "jieQi": "",
    "lastUpdate": "2025/04/26 15:00"
  }
}

7. 把上下文信息以及函數調用結果發給LLM

發給LLM的messages列表有2條messages:

  • 第1條role為system,定義了系統提示詞(含工具定義)
  • 第2條role為user,包含如下內容:

     Question: 北京和廣州天氣怎么樣

     Thought: 我需要獲取北京和廣州的天氣信息。首先,我將獲取北京的天氣

     Action: {"action":"get_weather","action_input":{"location":"北京"}}

     Observation: 工具調用get_weather('北京')的結果

     Thought: 現在我已經獲取了北京的天氣信息,接下來我將獲取廣州的天氣信息。

     Action: {"action":"get_weather","action_input":{"location":"廣州"}}

     Observation: 工具調用get_weather('廣州')的結果

#!/bin/bash
export OPENAI_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
export OPENAI_API_KEY="sk-xxx" # 替換為你的key


curl ${OPENAI_BASE_URL}/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
  "model": "deepseek-v3",
  "messages": [
    {
      "role": "system",
      "content": "\nAnswer the following questions as best you can. You have access to the following tools:\n{\"name\": \"get_weather\", \"description\": \"Get weather\", \"parameters\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\", \"description\": \"the name of the location\"}}, \"required\": [\"location\"]}}\n\n\nThe way you use the tools is by specifying a json blob.\nSpecifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).\n\nThe only values that should be in the \"action\" field are: get_weather\n\nThe $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:\n\n```\n{{\n\"action\": $TOOL_NAME,\n\"action_input\": $INPUT\n}}\n```\n\nALWAYS use the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction:\n```\n$JSON_BLOB\n```\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\n\nBegin! Reminder to always use the exact characters `Final Answer` when responding. \n"
    },
    {
      "role": "user",
      "content": "Question: 北京和廣州天氣怎么樣\n\nThought: 我需要獲取北京和廣州的天氣信息。首先,我將獲取北京的天氣。\n\nAction:\n```\n{\n\"action\": \"get_weather\",\n\"action_input\": {\n\"location\": \"北京\"\n}\n}\n```\nObservation: {\"msg\":\"success\",\"code\":0,\"data\":{\"location\":{\"id\":\"54511\",\"name\":\"北京\",\"path\":\"中國, 北京, 北京\"},\"now\":{\"precipitation\":0.0,\"temperature\":23.4,\"pressure\":1005.0,\"humidity\":43.0,\"windDirection\":\"西南風\",\"windDirectionDegree\":216.0,\"windSpeed\":2.7,\"windScale\":\"微風\",\"feelst\":23.1},\"alarm\":[],\"jieQi\":\"\",\"lastUpdate\":\"2025/04/26 15:00\"}}\nThought: 現在我已經獲取了北京的天氣信息,接下來我將獲取廣州的天氣信息。\n\nAction:\n```\n{\n\"action\": \"get_weather\",\n\"action_input\": {\n\"location\": \"廣州\"\n}\n}\n```\nObservation\nObservation: {\"msg\":\"success\",\"code\":0,\"data\":{\"location\":{\"id\":\"59287\",\"name\":\"廣州\",\"path\":\"中國, 廣東, 廣州\"},\"now\":{\"precipitation\":0.0,\"temperature\":24.2,\"pressure\":1005.0,\"humidity\":79.0,\"windDirection\":\"東北風\",\"windDirectionDegree\":31.0,\"windSpeed\":1.3,\"windScale\":\"微風\",\"feelst\":27.1},\"alarm\":[],\"jieQi\":\"\",\"lastUpdate\":\"2025/04/26 15:00\"}}\n"
    }
  ],
  "stop": "Observation:"
}'

8. LLM生成最終回復

LLM生成最終的回復:

Thought: 我已經獲取了北京和廣州的天氣信息,現在可以回答用戶的問題了。


Final Answer: 北京的天氣溫度為23.4°C,濕度為43%,風向為西南風,風速為2.7米/秒。廣州 的天氣溫度為24.2°C,濕度為79%,風向為東北風,風速為1.3米/秒。

完整的JSON響應如下:

{
  "choices": [
    {
      "message": {
        "content": "Thought: 我已經獲取了北京和廣州的天氣信息,現在可以回答用戶的問題了。\n\nFinal Answer: 北京的天氣溫度為23.4°C,濕度為43%,風向為西南風,風速為2.7米/秒。廣州 的天氣溫度為24.2°C,濕度為79%,風向為東北風,風速為1.3米/秒。",
        "role": "assistant"
      },
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null
    }
  ],
  "object": "chat.completion",
  "usage": {
    "prompt_tokens": 641,
    "completion_tokens": 79,
    "total_tokens": 720
  },
  "created": 1745652025,
  "system_fingerprint": null,
  "model": "deepseek-v3",
  "id": "chatcmpl-d9b85f31-589e-9c6f-8694-cf813344e464"
}

手搓Agent代碼實現基于ReAct的工具調用

1. 創建python環境

uv init agent
cd agent
uv venv
.venv\Scripts\activate

uv add openai requests python-dotenv

2. 設置API Key

創建.env,.env內容如下(注意修改OPENAI_API_KEY為您的key)

OPENAI_API_KEY=your_api_key_here
OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1

把.env添加到.gitignore

3. 實現Agent代碼

基于openai sdk實現ReAct agent的偽代碼主體邏輯如下:

maxIter = 5 # 最大迭代次數
agent_scratchpad = "" # agent思考過程(Thought/Action/Observation)
for iterSeq in range(1, maxIter+1):
    構造chat completion請求
        messages有2條
            第1條為系統提示詞消息(含工具定義)
            第2條為用戶消息:Question + agent思考過程(Thought/Action/Observation)
        stop參數設置為"Observation:"
    獲取chat completion結果
    如果chat completion結果帶有"Final Answer:"
        返回最終答案
    如果chat completion結果帶有Action
        解析并調用相應函數
        更新agent思考過程:把本次LLM的輸出(Though/Action)和工具調用結果(Observation)添加到agent_scratchpad
        繼續迭代

完整的main.py代碼如下:

import json
import re
import requests
import urllib.parse
from typing import Iterable
from openai import OpenAI
from openai.types.chat.chat_completion_message_param import ChatCompletionMessageParam
from openai.types.chat.chat_completion_user_message_param import (
    ChatCompletionUserMessageParam,
)
from openai.types.chat.chat_completion_system_message_param import (
    ChatCompletionSystemMessageParam,
)


# 加載環境變量
from dotenv import load_dotenv
load_dotenv()


client = OpenAI()
model = "deepseek-v3"


# 工具定義
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get weather",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {"type": "string", "description": "location"}
                },
                "required": ["location"],
            },
        },
    }
]


# 系統提示詞
def get_system_prompt():
    tool_strings = "\n".join([json.dumps(tool["function"]) for tool in tools])
    tool_names = ", ".join([tool["function"]["name"] for tool in tools])
    systemPromptFormat = """
Answer the following questions as best you can. You have access to the following tools:
{tool_strings}




The way you use the tools is by specifying a json blob.
Specifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).


The only values that should be in the "action" field are: {tool_names}


The $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:


```
{{{{
"action": $TOOL_NAME,
"action_input": $INPUT
}}}}
```


ALWAYS use the following format:


Question: the input question you must answer
Thought: you should always think about what to do
Action:
```
$JSON_BLOB
```
Observation: the result of the action
... (this Thought/Action/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question




Begin! Reminder to always use the exact characters `Final Answer` when responding. 
"""
    return systemPromptFormat.format(tool_strings=tool_strings, tool_names=tool_names)


# 實現獲取天氣
def get_weather(location: str) -> str:
    url = "http://weather.cma.cn/api/autocomplete?q=" + urllib.parse.quote(location)
    response = requests.get(url)
    data = response.json()
    if data["code"] != 0:
        return "沒找到該位置的信息"
    location_code = ""
    for item in data["data"]:
        str_array = item.split("|")
        if (
            str_array[1] == location
            or str_array[1] + "市" == location
            or str_array[2] == location
        ):
            location_code = str_array[0]
            break
    if location_code == "":
        return "沒找到該位置的信息"
    url = f"http://weather.cma.cn/api/now/{location_code}"
    return requests.get(url).text


# 實現工具調用
def invoke_tool(toolName: str, toolParamaters) -> str:
    result = ""
    if toolName == "get_weather":
        result = get_weather(toolParamaters["location"])
    else:
        result = f"函數{toolName}未定義"
    return result


def main():
    query = "北京和廣州天氣怎么樣"
    systemMsg = ChatCompletionSystemMessageParam(
        role="system", cnotallow=get_system_prompt()
    )
    maxIter = 5  # 最大迭代次數
    agent_scratchpad = ""  # agent思考過程
    action_pattern = re.compile(r"\nAction:\n`{3}(?:json)?\n(.*?)`{3}.*?$", re.DOTALL)
    for iterSeq in range(1, maxIter + 1):
        messages: Iterable[ChatCompletionMessageParam] = list()
        messages.append(systemMsg)
        messages.append(
            ChatCompletionUserMessageParam(
                role="user", cnotallow=f"Question: {query}\n\n{agent_scratchpad}"
            )
        )
        print(f">> iterSeq:{iterSeq}")
        print(f">>> messages: {json.dumps(messages)}")
        # 向LLM發起請求,注意需要設置stop參數
        chat_completion = client.chat.completions.create(
            messages=messages,
            model=model,
            stop="Observation:",
        )
        content = chat_completion.choices[0].message.content
        print(f">>> content:\n{content}")
        final_answer_match = re.search(r"\nFinal Answer:\s*(.*)", content)
        if final_answer_match:
            final_answer = final_answer_match.group(1)
            print(f">>> 最終答案: {final_answer}")
            return
        action_match = action_pattern.search(content)
        if action_match:
            obj = json.loads(action_match.group(1))
            toolName = obj["action"]
            toolParameters = obj["action_input"]
            print(f">>> tool name:{toolName}")
            print(f">>> tool parameters:{toolParameters}")
            result = invoke_tool(toolName, toolParameters)
            print(f">>> tool result: {result}")
            # 把本次LLM的輸出(Though/Action)和工具調用結果(Observation)添加到agent_scratchpad
            agent_scratchpad += content + f"\nObservation: {result}\n"
        else:
            print(">>> ERROR: detect invalid response")
            return
    print(">>> 迭代次數達到上限,我無法得到最終答案")


main()

運行代碼:uv run .\main.py

輸出日志如下:

>> iterSeq:1
>>> messages: [{"role": "system", "content": "\nAnswer the following questions as best you can. You have access to the following tools:\n{\"name\": \"get_weather\", \"description\": \"Get weather\", \"parameters\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\", \"description\": \"the name of the location\"}}, \"required\": [\"location\"]}}\n\n\nThe way you use the tools is by specifying a json blob.\nSpecifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).\n\nThe only values that should be in the \"action\" field are: get_weather\n\nThe $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:\n\n```\n{{\n\"action\": $TOOL_NAME,\n\"action_input\": $INPUT\n}}\n```\n\nALWAYS use the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction:\n```\n$JSON_BLOB\n```\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\n\nBegin! Reminder to always use the exact characters `Final Answer` when responding. \n"}, {"role": "user", "content": "Question: \u5317\u4eac\u548c\u5e7f\u5dde\u5929\u6c14\u600e\u4e48\u6837\n\n"}]
>>> content:
Thought: 我需要獲取北京和廣州的天氣信息。首先,我將獲取北京的天氣。


Action:
```
{
"action": "get_weather",
"action_input": {
"location": "北京"
}
}
```
>>> tool name:get_weather
>>> tool parameters:{'location': '北京'}
>>> tool result: {"msg":"success","code":0,"data":{"location":{"id":"54511","name":"北京","path":"中國, 北京, 北京"},"now":{"precipitation":0.0,"temperature":23.4,"pressure":1005.0,"humidity":43.0,"windDirection":"西南風","windDirectionDegree":216.0,"windSpeed":2.7,"windScale":"微風","feelst":23.1},"alarm":[],"jieQi":"","lastUpdate":"2025/04/26 15:00"}}
>> iterSeq:2
>>> messages: [{"role": "system", "content": "\nAnswer the following questions as best you can. You have access to the following tools:\n{\"name\": \"get_weather\", \"description\": \"Get weather\", \"parameters\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\", \"description\": \"the name of the location\"}}, \"required\": [\"location\"]}}\n\n\nThe way you use the tools is by specifying a json blob.\nSpecifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).\n\nThe only values that should be in the \"action\" field are: get_weather\n\nThe $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:\n\n```\n{{\n\"action\": $TOOL_NAME,\n\"action_input\": $INPUT\n}}\n```\n\nALWAYS use the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction:\n```\n$JSON_BLOB\n```\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\n\nBegin! Reminder to always use the exact characters `Final Answer` when responding. \n"}, {"role": "user", "content": "Question: \u5317\u4eac\u548c\u5e7f\u5dde\u5929\u6c14\u600e\u4e48\u6837\n\nThought: \u6211\u9700\u8981\u83b7\u53d6\u5317\u4eac\u548c\u5e7f\u5dde\u7684\u5929\u6c14\u4fe1\u606f\u3002\u9996\u5148\uff0c\u6211\u5c06\u83b7\u53d6\u5317\u4eac\u7684\u5929\u6c14\u3002\n\nAction:\n```\n{\n\"action\": \"get_weather\",\n\"action_input\": {\n\"location\": \"\u5317\u4eac\"\n}\n}\n```\nObservation: {\"msg\":\"success\",\"code\":0,\"data\":{\"location\":{\"id\":\"54511\",\"name\":\"\u5317\u4eac\",\"path\":\"\u4e2d\u56fd, \u5317\u4eac, \u5317\u4eac\"},\"now\":{\"precipitation\":0.0,\"temperature\":23.4,\"pressure\":1005.0,\"humidity\":43.0,\"windDirection\":\"\u897f\u5357\u98ce\",\"windDirectionDegree\":216.0,\"windSpeed\":2.7,\"windScale\":\"\u5fae\u98ce\",\"feelst\":23.1},\"alarm\":[],\"jieQi\":\"\",\"lastUpdate\":\"2025/04/26 15:00\"}}\n"}]
>>> content:
Thought: 現在我已經獲取了北京的天氣信息,接下來我將獲取廣州的天氣信息。


Action:
```
{
"action": "get_weather",
"action_input": {
"location": "廣州"
}
}
```
Observation
>>> tool name:get_weather
>>> tool parameters:{'location': '廣州'}
>>> tool result: {"msg":"success","code":0,"data":{"location":{"id":"59287","name":"廣州","path":"中國, 廣東, 廣州"},"now":{"precipitation":0.0,"temperature":24.2,"pressure":1005.0,"humidity":79.0,"windDirection":"東北風","windDirectionDegree":31.0,"windSpeed":1.3,"windScale":"微風","feelst":27.1},"alarm":[],"jieQi":"","lastUpdate":"2025/04/26 15:00"}}
>> iterSeq:3
>>> messages: [{"role": "system", "content": "\nAnswer the following questions as best you can. You have access to the following tools:\n{\"name\": \"get_weather\", \"description\": \"Get weather\", \"parameters\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\", \"description\": \"the name of the location\"}}, \"required\": [\"location\"]}}\n\n\nThe way you use the tools is by specifying a json blob.\nSpecifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).\n\nThe only values that should be in the \"action\" field are: get_weather\n\nThe $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:\n\n```\n{{\n\"action\": $TOOL_NAME,\n\"action_input\": $INPUT\n}}\n```\n\nALWAYS use the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction:\n```\n$JSON_BLOB\n```\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\n\nBegin! Reminder to always use the exact characters `Final Answer` when responding. \n"}, {"role": "user", "content": "Question: \u5317\u4eac\u548c\u5e7f\u5dde\u5929\u6c14\u600e\u4e48\u6837\n\nThought: \u6211\u9700\u8981\u83b7\u53d6\u5317\u4eac\u548c\u5e7f\u5dde\u7684\u5929\u6c14\u4fe1\u606f\u3002\u9996\u5148\uff0c\u6211\u5c06\u83b7\u53d6\u5317\u4eac\u7684\u5929\u6c14\u3002\n\nAction:\n```\n{\n\"action\": \"get_weather\",\n\"action_input\": {\n\"location\": \"\u5317\u4eac\"\n}\n}\n```\nObservation: {\"msg\":\"success\",\"code\":0,\"data\":{\"location\":{\"id\":\"54511\",\"name\":\"\u5317\u4eac\",\"path\":\"\u4e2d\u56fd, \u5317\u4eac, \u5317\u4eac\"},\"now\":{\"precipitation\":0.0,\"temperature\":23.4,\"pressure\":1005.0,\"humidity\":43.0,\"windDirection\":\"\u897f\u5357\u98ce\",\"windDirectionDegree\":216.0,\"windSpeed\":2.7,\"windScale\":\"\u5fae\u98ce\",\"feelst\":23.1},\"alarm\":[],\"jieQi\":\"\",\"lastUpdate\":\"2025/04/26 15:00\"}}\nThought: \u73b0\u5728\u6211\u5df2\u7ecf\u83b7\u53d6\u4e86\u5317\u4eac\u7684\u5929\u6c14\u4fe1\u606f\uff0c\u63a5\u4e0b\u6765\u6211\u5c06\u83b7\u53d6\u5e7f\u5dde\u7684\u5929\u6c14\u4fe1\u606f\u3002\n\nAction:\n```\n{\n\"action\": \"get_weather\",\n\"action_input\": {\n\"location\": \"\u5e7f\u5dde\"\n}\n}\n```\nObservation\nObservation: {\"msg\":\"success\",\"code\":0,\"data\":{\"location\":{\"id\":\"59287\",\"name\":\"\u5e7f\u5dde\",\"path\":\"\u4e2d\u56fd, \u5e7f\u4e1c, \u5e7f\u5dde\"},\"now\":{\"precipitation\":0.0,\"temperature\":24.2,\"pressure\":1005.0,\"humidity\":79.0,\"windDirection\":\"\u4e1c\u5317\u98ce\",\"windDirectionDegree\":31.0,\"windSpeed\":1.3,\"windScale\":\"\u5fae\u98ce\",\"feelst\":27.1},\"alarm\":[],\"jieQi\":\"\",\"lastUpdate\":\"2025/04/26 15:00\"}}\n"}]
>>> content:
Thought: 我已經獲取了北京和廣州的天氣信息,現在可以回答用戶的問題了。


Final Answer: 北京的天氣情況為:溫度23.4°C,濕度43%,西南風,風速2.7米/秒,微風。廣州的天氣情況為:溫度24.2°C,濕度79%,東北風,風速1.3米/秒,微風。
>>> 最終答案: 北京的天氣情況為:溫度23.4°C,濕度43%,西南風,風速2.7米/秒,微風。廣州的天氣情況為:溫度24.2°C,濕度79%,東北風,風速1.3米/秒,微風。

總結

基于Function Calling和基于ReAct的工具調用有各自的優缺點:

1. Function Calling

  • 無需設定系統提示詞,LLM根據tools定義即可觸發工具調用,token消耗較少
  • 模型參數量相對較大。模型的訓練數據必須包含Function Calling相關的內容,以確保模型能夠理解和生成結構化輸出,結構化輸出更穩定
  • 輸出結果較為容易處理
  • 隱藏了推理過程,缺乏可解釋性

2. ReAct

  • 需要設置復雜的系統提示詞,token消耗較多
  • 對模型參數要求較低
  • 輸出結果處理比Function Calling復雜
  • 推理過程可見,更高的可解釋性
責任編輯:龐桂玉 來源: AI大模型應用開發
相關推薦

2025-07-18 08:46:33

2025-09-30 07:05:22

2020-03-18 14:00:47

MySQL分區數據庫

2022-06-07 10:13:22

前端沙箱對象

2021-06-30 08:45:02

內存管理面試

2021-07-08 10:08:03

DvaJS前端Dva

2020-12-07 06:19:50

監控前端用戶

2024-05-29 12:13:50

2019-11-06 17:30:57

cookiesessionWeb

2024-08-08 14:57:32

2022-04-11 10:56:43

線程安全

2021-10-20 08:49:30

Vuexvue.js狀態管理模式

2023-04-12 08:38:44

函數參數Context

2021-08-05 06:54:05

觀察者訂閱設計

2020-12-18 09:36:01

JSONP跨域面試官

2023-11-23 06:50:08

括號

2023-09-20 16:20:20

2023-09-13 22:39:23

Minikube開源

2025-08-01 02:43:00

2024-04-12 12:19:08

語言模型AI
點贊
收藏

51CTO技術棧公眾號

日韩精品一区二区三区国语自制| 国产老头和老头xxxx×| 黄色网址在线播放| 久久99久久久久久久久久久| 欧美日韩高清在线观看| 一本色道综合久久欧美日韩精品| 123成人网| 亚洲一区二区三区爽爽爽爽爽| 久久亚洲精品欧美| 国产伦精品一区二区三区免.费 | 国产剧情一区二区| 欧美在线欧美在线| 欧美做爰爽爽爽爽爽爽| 精品大片一区二区| 亚洲国产婷婷香蕉久久久久久| 成年人小视频网站| 免费看电影在线| 国产精品国产三级国产有无不卡| 国产日产精品一区二区三区四区| 中文字幕欧美人妻精品一区蜜臀| 在线观看一区视频| 俺去了亚洲欧美日韩| 性欧美丰满熟妇xxxx性仙踪林| 91精品亚洲一区在线观看| 日韩欧美黄色动漫| 亚洲国产精品无码av| 自拍视频在线免费观看| 久久日韩粉嫩一区二区三区| av免费观看久久| 91精品国产乱码久久久久| 免费在线成人| 久久久久久综合网天天| www.xxxx日本| 99视频精品视频高清免费| 精品一区电影国产| www.88av| 国产精品白丝一区二区三区 | 少妇又色又爽又黄的视频| 九色|91porny| 国产精品一区二区三区免费视频| 国产一级片毛片| 亚洲日韩成人| 久久久久久久久国产精品| 欧美在线视频第一页| 99国产精品一区二区| 中文字幕欧美国内| 蜜桃av乱码一区二区三区| 天天做夜夜做人人爱精品 | 国产精品免费小视频| 国产寡妇亲子伦一区二区三区四区| 亚洲国内精品| 国内精品久久久| 国产无码精品视频| 亚洲精品乱码| 欧美亚洲在线视频| 日日噜噜噜噜人人爽亚洲精品| 亚洲视频久久| 亚州国产精品久久久| 国产福利拍拍拍| 亚洲精品乱码久久久久久蜜桃麻豆| 欧美激情在线狂野欧美精品| 国产在线视频二区| 在线综合视频| 日韩免费观看高清| 97成人在线观看| 国产又黄又大久久| 国产精品.com| 亚洲色图欧美视频| 国产网红主播福利一区二区| 午夜老司机精品| 日本高清中文字幕在线| 亚洲精品国产一区二区精华液| 18视频在线观看娇喘| 成人超碰在线| 欧美日韩人人澡狠狠躁视频| 久久久久久久少妇| 欧美日韩卡一| 精品日韩99亚洲| 少妇大叫太粗太大爽一区二区| 视频一区中文| 美乳少妇欧美精品| 日韩av无码中文字幕| 久久一二三区| 91免费国产网站| 欧美熟女一区二区| 久久精品欧美一区二区三区不卡 | 久久影院理伦片| 婷婷免费在线视频| 亚洲一区二区三区在线播放| 日日摸日日碰夜夜爽av| 欧洲精品久久久久毛片完整版| 日韩欧美高清在线| 亚洲av无码一区二区三区人| 亚洲精品888| 6080yy精品一区二区三区| 国产精华7777777| 国产黄色成人av| 日韩欧美亚洲区| 国产美女一区视频| 色久综合一二码| 女同性αv亚洲女同志| 精品免费视频| 91高清免费在线观看| 国产精品高潮呻吟久久久| 99久久精品免费看| 女同性恋一区二区| 日本成人三级电影| 精品奇米国产一区二区三区| 微拍福利一区二区| 99精品视频免费| 91九色在线免费视频| 波多野结衣在线影院| 午夜精品福利一区二区蜜股av| 天堂av8在线| 欧美猛男男男激情videos| 欧美成年人网站| 中国女人真人一级毛片| 91视频在线看| 久青草视频在线播放| 24小时成人在线视频| 国产午夜精品一区理论片飘花| 国产第100页| 国产精品一区2区| 亚洲一区精品视频| 少妇一区视频| 亚洲欧洲日产国产网站| 91香蕉在线视频| 成人性色生活片免费看爆迷你毛片| 一区二区视频国产| 欧美日韩激情电影| 亚洲性猛交xxxxwww| 一级成人黄色片| 91丨国产丨九色丨pron| 免费无码不卡视频在线观看| www国产精品| 久久成年人视频| 一级做a爰片久久毛片16| 国产人成一区二区三区影院| 男人透女人免费视频| 日韩一级电影| 日韩av成人在线| 精品99又大又爽又硬少妇毛片| 黑人巨大精品欧美一区免费视频| 国产精品扒开腿做爽爽爽a片唱戏 亚洲av成人精品一区二区三区 | 日本不卡中文字幕| 欧美极品jizzhd欧美| 英国三级经典在线观看| 日韩精品免费综合视频在线播放| 日韩欧美一区二区一幕| 99re热这里只有精品视频| 欧美三级在线观看视频| 先锋影音国产精品| 日韩av电影免费观看高清| 免费黄网站在线观看| 色婷婷国产精品综合在线观看| av直播在线观看| 久久婷婷激情| 亚洲国产另类久久久精品极度| 精品九九久久| 亚洲欧洲av| 欧美一级黄色大片| 麻豆疯狂做受xxxx高潮视频| 国产老妇另类xxxxx| 国产一区二区三区小说| 欧美激情极品| 国产大片精品免费永久看nba| 成人性生交大片免费看午夜| 51精品国自产在线| 久热这里只有精品在线| 久久新电视剧免费观看| 国内自拍视频网| 欧美一区网站| 国产美女精品久久久| xxxxx性欧美特大| 中文日韩在线视频| 国产高清在线免费| 欧美视频精品一区| chinese全程对白| 成人午夜电影网站| 爱情岛论坛成人| 综合久久亚洲| 蜜桃传媒视频麻豆一区| 日韩午夜视频在线| 孩xxxx性bbbb欧美| 国产视频网址在线| 日韩丝袜美女视频| 秋霞av一区二区三区| 亚洲男人电影天堂| 黄色片视频免费观看| 美女看a上一区| 国产日韩av网站| 久久伦理在线| 久久av一区二区| www一区二区三区| 4444欧美成人kkkk| 国产午夜精品久久久久免费视| 亚洲国产成人久久综合| 综合久久中文字幕| 天堂精品在线视频| 亚洲精品福利资源站| 日本一区二区三区久久| 亚洲愉拍自拍另类高清精品| 中文字幕伦理片| 成人一级片在线观看| jizz大全欧美jizzcom| 极品少妇一区二区三区| 亚洲午夜精品久久久久久浪潮| 成人在线tv视频| 成人黄色中文字幕| a一区二区三区| 欧美精品久久久久久久久久| 日本欧美在线视频免费观看| 亚洲韩国欧洲国产日产av| 国产又粗又猛又爽又黄的视频一| 欧美日韩激情视频8区| 日韩成人短视频| 国产日本一区二区| 大地资源二中文在线影视观看| 国产精品综合一区二区三区| 不卡av免费在线| 噜噜噜91成人网| 亚洲不卡中文字幕无码| 98精品视频| 日韩高清国产精品| 国产aⅴ精品一区二区三区久久| 成人免费在线一区二区三区| 老司机精品视频网| 国产精品久久久久久超碰 | 黄色片在线看| 日韩大片在线观看视频| 亚洲第九十九页| 日韩美女在线视频| 国产黄色高清视频| 欧美一区二区三区免费在线看| 中文字幕视频一区二区| 在线看日韩精品电影| 蜜臀99久久精品久久久久小说| 精品久久久久久久久久国产| 国产a∨精品一区二区三区仙踪林| 一区二区三区久久| 免费无遮挡无码永久在线观看视频 | 成人18视频| 亚洲日本一区二区三区在线| 亚洲综合中文字幕在线| 亚洲在线资源| 91久久伊人青青碰碰婷婷| 伊人精品久久| 国产精品sss| 乱亲女h秽乱长久久久| 韩国一区二区三区美女美女秀| 久久黄色影视| 免费国产一区二区| 国产尤物久久久| 亚洲一区二三| 欧美~级网站不卡| 国产精品日韩三级| 日韩午夜av| 亚洲 中文字幕 日韩 无码| 蜜臀久久久久久久| 手机在线免费毛片| 福利91精品一区二区三区| 国产chinese中国hdxxxx| 99久久99久久久精品齐齐| 亚洲精品乱码久久久久久久久久久久| 国产午夜精品久久| 动漫性做爰视频| 精品国产31久久久久久| 亚洲欧美另类在线视频| 欧美精品v国产精品v日韩精品| av官网在线观看| 亚洲精品成人久久| 二人午夜免费观看在线视频| www.欧美精品| sm在线播放| 国产欧美一区二区三区久久人妖| 日韩精品免费视频一区二区三区 | 91亚洲一区二区| 99久久精品免费看国产| 日本一道本视频| 亚洲激情在线激情| 特黄视频免费看| 欧美军同video69gay| 人成网站在线观看| 中文字幕亚洲图片| 六月婷婷激情综合| 国产精品啊啊啊| 成年人小视频网站| 国产不卡视频一区二区三区| 永久免费看mv网站入口78| 亚洲视频免费在线观看| 欧美在线观看不卡| 欧美一区二区三区在| 天堂a中文在线| 欧美另类在线播放| 成人视屏在线观看| 国产精品日韩高清| 久久网站免费观看| 精品少妇人妻av免费久久洗澡| 奇米精品一区二区三区在线观看| www.黄色网| 国产精品国产三级国产aⅴ中文| 日韩手机在线观看| 欧美妇女性影城| 福利视频在线导航| 国语自产精品视频在线看抢先版图片 | 亚洲人成网站精品片在线观看 | 欧美久久免费观看| 你懂的在线观看| 欧美激情一区二区三区成人| 日韩成人一区| 欧美三级电影在线播放| 国产综合婷婷| 亚洲天堂av一区二区| 久久青草国产手机看片福利盒子| 久久精品国产av一区二区三区| 欧美日韩国产首页| 黄色大片在线看| 69久久夜色精品国产69| 日韩精品一级| 波多野结衣三级在线| 日韩精品一区第一页| 亚洲av无码一区二区二三区| 亚洲一区二区黄色| 国产99久一区二区三区a片| 在线色欧美三级视频| 成人欧美一区二区三区的电影| 国产精品三区四区| 国内自拍一区| 女女调教被c哭捆绑喷水百合| 综合电影一区二区三区| 中文字幕日韩国产| 在线观看欧美视频| 成人mm视频在线观看| 欧洲精品码一区二区三区免费看| 国产欧美欧美| 成人免费无码大片a毛片| 黄色成人av网| 天天操天天操天天操| 亚洲18私人小影院| 精品视频在线你懂得| 自拍日韩亚洲一区在线| av不卡在线播放| a v视频在线观看| 日韩精品高清视频| 综合在线影院| 午夜精品亚洲一区二区三区嫩草 | 午夜精品久久久久久久99水蜜桃| 亚洲av无码一区二区乱子伦| 九九热精品在线| 精品夜夜澡人妻无码av| 国产亚洲欧美日韩在线一区| 国产精品久久久久久人| 亚洲视频免费一区| 韩日一区二区| 三年中国中文在线观看免费播放 | 人妻在线日韩免费视频| 欧美日韩午夜剧场| 美国成人毛片| 国产精品久久中文| 一区二区影院| 国产精品成人99一区无码| 欧美日韩国产中文精品字幕自在自线| 牛牛影视精品影视| 成人激情免费在线| 欧美午夜久久| 泷泽萝拉在线播放| 欧美高清视频不卡网| 欧美人与性动交α欧美精品济南到| 国产精品二区二区三区| 国产精品最新自拍| 国产人与禽zoz0性伦| 亚洲精品一区二区三区四区高清| 在线观看的黄色| 国产高清精品软男同| 成人高清免费观看| 一级做a爰片久久毛片| www国产精品com| 操欧美女人视频| 粉嫩虎白女毛片人体| 性xxxx欧美老肥妇牲乱| 国产成人亚洲综合青青| 狠狠操综合网| 日本人妻一区二区三区| 在线观看日韩精品| 性欧美videos高清hd4k| 精品视频一区二区| 九九九久久久精品| 久久久久久久黄色片| 中文字幕日韩av| 久久悠悠精品综合网| 玖玖爱视频在线| 懂色av一区二区三区| 黄色成人在线观看| 日本一区免费看| 成人综合婷婷国产精品久久| 成人午夜精品视频| 性欧美在线看片a免费观看| 天天做天天爱天天爽综合网| 青青草视频成人| 精品国产一区a|