从零构建大模型智能体:构建可调用工具的智能体

引言

在现代人工智能应用中,构建能够自主调用外部工具(如搜索引擎、计算器等)以完成复杂任务的智能体(Agent)正变得越来越重要。本文旨在介绍一个通用的、极简的 Agent 基类设计及其具体实现示例------SimpleAgent,它能够基于自然语言输入判断是否调用工具,并将工具结果整合进对话生成最终回答。通过这种设计,智能体既保留了强大的语言理解能力,又能够灵活利用外部工具完成现实世界任务,如网络搜索、数学计算等。文章中还提供了完整的示例工具实现及运行演示,帮助读者快速上手构建可扩展的智能体系统。

完整代码和示例可在本项目代码仓库查看:vero

Agent基类

我们的基类抽象一些通用的属性和方法。这里不限制工具调用的具体格式,因为子类可以实现自己不同的工具调用方式。

在初始化方法中,保存Agent底层的LLM对象,先简单一点只保存一个LLM实例,在复杂的有多个组件的Agent中实际上根据需要每个不同的组件可以使用能力不同的LLM。

其次是要调用的工具列表和最大轮次,有些Agent支持反思、重规划等就需要多个轮次。

最后是可传入用户自定义的系统提示词和保存内部消息列表。

python 复制代码
 def __init__(
        self,
        name: str,
        llm: ChatOpenAI,
        tools: Optional[List[Tool]] = None,
        system_prompt: Optional[str] = None,
        max_turns: int = 3,
    ):
  self.name = name
  self.llm = llm
  self.tools = tools or []
  self.max_turns = max_turns
  self.system_prompt = system_prompt

  # 内部消息历史(存 Message 对象)
  self._history: List[Message] = []

接下来是上篇文章介绍的工具描述方法,这里把参数的类型也加上:

py 复制代码
@property
def tool_descriptions(self) -> str:
    """
    构造当前智能体可用工具的可读描述。

    格式示例:
        calculate_sum(a: int, b: int) - Add two numbers
        search_web(query: str) - Search the internet
    """
    lines = []
    for tool in self.tools:
        args_text = ", ".join(f"{name}: {typ}" for (name, typ, *_rest) in tool.arguments)
        lines.append(f"{tool.name}({args_text}) - {tool.description}")
    return "\n".join(lines)

然后是获取所有工具名称和工具名称到工具实例映射的字典:

py 复制代码
@property
def tool_names(self) -> str:
    """返回所有工具名称的逗号分隔字符串。"""
    return ",".join([tool.name for tool in self.tools])

@property
def tool_by_names(self) -> dict[str, Tool]:
    """
    按名称映射工具: tool_name → Tool 对象。
    对自定义工具调用协议的子类特别有用。
    """
    return {tool.name: tool for tool in self.tools}

历史消息的简单管理也可以封装起来:

py 复制代码
   def add_message(self, message: Message) -> None:
        """向消息历史中追加一条 Message 对象。"""
        self._history.append(message)

    def clear_history(self) -> None:
        """清空全部对话历史。"""
        self._history.clear()

最后是需要子类实现的抽象接口:

py 复制代码
@abstractmethod
def run(self, input_text: str, **kwargs) -> str:

完整实现如下:

py 复制代码
from abc import ABC, abstractmethod
from typing import Optional, List

from vero.tool import Tool
from .message import Message
from .chat_openai import ChatOpenAI


class Agent(ABC):
    """
    Agent(智能体)基类。

    本类是一个通用、极简的智能体抽象:
    - 不限制工具调用的具体格式。
    - 不负责解析工具调用表达式。
    - 仅提供公共的数据结构与工具函数。
    - 子类可以根据需要,实现不同的工具调用协议
      (例如 JSON function calling、自定义 TOOL_CALL 字符串、DSL 调用语法等)。

    子类必须实现 `run` 方法,用于定义完整的推理与调用流程。
    """

    def __init__(
        self,
        name: str,
        llm: ChatOpenAI,
        tools: Optional[List[Tool]] = None,
        system_prompt: Optional[str] = None,
        max_turns: int = 3,
    ):
        """
        初始化通用的智能体。

        参数:
            name (str): 智能体名称,用于标识。
            llm (ChatOpenAI): 底层语言模型,用于推理。
            tools (List[Tool] | None): 可选的工具列表,智能体可调用。
            system_prompt (str | None): 系统级提示词,用于初始化模型行为。
            max_turns (int): 最大推理轮数限制(留作扩展用途)。
        """
        self.name = name
        self.llm = llm
        self.tools = tools or []
        self.max_turns = max_turns
        self.system_prompt = system_prompt

        # 内部消息历史(存 Message 对象)
        self._history: List[Message] = []

    # -------------------------------------------------------
    # 抽象接口
    # -------------------------------------------------------
    @abstractmethod
    def run(self, input_text: str, **kwargs) -> str:
        """
        执行智能体的主流程。

        子类应明确控制:
            - 如何组织 LLM 输入
            - 如何维护与追加消息历史
            - 如何选择并调用工具
            - 如何定义推理终止条件

        参数:
            input_text (str): 用户输入内容。

        返回:
            str: 最终输出文本。
        """
        pass

    # -------------------------------------------------------
    # 工具元信息
    # -------------------------------------------------------
    @property
    def tool_descriptions(self) -> str:
        """
        构造当前智能体可用工具的可读描述。

        格式示例:
            calculate_sum(a: int, b: int) - Add two numbers
            search_web(query: str) - Search the internet
        """
        lines = []
        for tool in self.tools:
            args_text = ", ".join(f"{name}: {typ}" for (name, typ, *_rest) in tool.arguments)
            lines.append(f"{tool.name}({args_text}) - {tool.description}")
        return "\n".join(lines)

    @property
    def tool_names(self) -> str:
        """返回所有工具名称的逗号分隔字符串。"""
        return ",".join([tool.name for tool in self.tools])

    @property
    def tool_by_names(self) -> dict[str, Tool]:
        """
        按名称映射工具: tool_name → Tool 对象。
        对自定义工具调用协议的子类特别有用。
        """
        return {tool.name: tool for tool in self.tools}

    # -------------------------------------------------------
    # 对话记忆管理
    # -------------------------------------------------------
    def add_message(self, message: Message) -> None:
        """向消息历史中追加一条 Message 对象。"""
        self._history.append(message)

    def clear_history(self) -> None:
        """清空全部对话历史。"""
        self._history.clear()

    # -------------------------------------------------------
    # 字符串显示
    # -------------------------------------------------------
    def __str__(self) -> str:
        return f"Agent<name={self.name}>"

    __repr__ = __str__

简单的Agent实现

基于上一篇文章介绍的工具调用模式,我们稍加改造,就能实现一个简单的Agent。

在其初始化方法中,和基类所需的参数是一致的。这里我们简单Agent只会运行一次迭代,要么调用工具,要么直接回答。然后构建系统提示词,并传入消息列表中。

py 复制代码
super().__init__(name=name, llm=llm, tools=tools, system_prompt=system_prompt, max_turns=max_turns)

# 构建系统提示词,并写入第一条系统消息
if self.system_prompt:
    sp = self.system_prompt
else:
    sp = self._build_system_prompt()

self.add_message(Message.system(sp))

根据传入的工具列表是否为空,提示词有带工具版和非工具版,我们来看下带工具版:

复制代码
DEFAULT_PROMPT_WITH_TOOLS = """
You are an intelligent agent capable of using external tools to help solve user queries.

Below is the list of available tools:

{tool_descriptions}

When you decide that using a tool is necessary:
- Use the exact format:
  TOOL_CALL:tool_name:{{"param1": 1, "param2": "abc"}}
- The parameters must be a valid JSON object that includes all required arguments of the tool.
- If no tool is needed, simply respond with normal text.

Follow the format strictly. Do not explain the tool call. Do not wrap the tool call in code blocks.
"""

和上篇文章介绍的差不多,只不过翻译成了英文。

我们先来看子类要实现的run方法:

py 复制代码
def run(self, user_input: str) -> str:
    """
    执行智能体主流程(单输入模式)。

    步骤:
        1. 将用户消息写入历史;
        2. 请求 LLM 返回回复;
        3. 若包含 TOOL_CALL,则执行工具并将结果写入历史;
        4. 让 LLM 基于工具结果生成最终回答。
    """
    # 1) 加入用户消息
    self.add_message(Message.user(user_input))

    # 2) 请求 LLM 回复(llm.generate 会基于 Message 历史推理)
    llm_reply = self.llm.generate(self._history)

    # 保存 assistant 的原始回复
    self.add_message(Message.assistant(llm_reply))

    # 3) 检查是否是工具调用
    has_call, tool_name, params = self._parse_tool_call(llm_reply)

    if has_call:
        return self._handle_tool_call(tool_name, params)

    # 普通回答
    return llm_reply

前面几步比较简单,第3步时检查是否包含工具调用,具体实现和之前介绍的类似:

py 复制代码
# TOOL_CALL_PATTERN = r"TOOL_CALL:(\w+):(.+)"
match = re.search(self.TOOL_CALL_PATTERN, text)
if not match:
    return False, None, None

tool_name = match.group(1)
params_str = match.group(2).strip()

# 尝试解析参数为字典
params = None
try:
    params = json.loads(params_str)
except Exception:
    try:
        params = ast.literal_eval(params_str)
    except Exception:
        params = None

return True, tool_name, params

这里增加ast.literal_eval(params_str)进行保底,当生成的参数是非法JSON时,还有可能进行解析。ast.literal_eval函数可以"安全地将表示 Python 字面量(literals)的字符串表达式,转换为对应的 Python 对象(字符串、数值、列表、元组、字典、集合、布尔值、None 等)",如果字符串是 Python 风格,比如使用单引号 '、包括 Python 常量 True / False / None / set() / tuple 等,JSON 解析就会失败,而 ast.literal_eval 往往能成功解析。但是不能把它当作 JSON-decoder,因为它并不能正确处理所有合法 JSON,所以json.loads放到前面。

最后要实现的是工具调用的处理,这里只展示核心代码:

py 复制代码
def _handle_tool_call(self, tool_name: str, params) -> str:
    # 得到工具实例
    tool = self.tool_by_names[tool_name]
    # 执行工具
    result = tool(**params)
    # 将工具结果写回对话历史
    # 说明:这里使用 user 风格的消息 ("TOOL_RESULT:xxx")
    #       这样可以与 assistant 消息区分,并使模型更容易理解"这是外部信息"。
    self.add_message(Message.user(f"TOOL_RESULT:{result}"))
    # 再次询问 LLM,让其基于工具结果生成最终回答
    final_answer = self.llm.generate(self._history)
    self.add_message(Message.assistant(final_answer))
    return final_answer

得到工具执行结果后如果想要LLM润色一下,需要通过user角色告诉LLM。assistant角色不行,因为它代表是LLM自己的回复,不会基于此进行回复。其实tool角色也可以,但是只适用于Function Calling模式,我们下篇文章会介绍。

下面是该简单Agent类的完整代码:

py 复制代码
import re
import ast
import json
from typing import List, Optional, Tuple, Dict

from vero.tool import Tool
from vero.core.message import Message
from vero.core.chat_openai import ChatOpenAI
from vero.core.agent import Agent
from vero.core.exceptions import ToolNotFoundError, ToolCallError


class SimpleAgent(Agent):
    """
    一个基于简单 TOOL_CALL 协议的 Agent 实现。

    协议格式:
        - 当 LLM 认为需要调用工具时,应返回如下格式的一行文本:
          TOOL_CALL:tool_name:{"param1": 1, "param2": "abc"}
        - 参数必须为 JSON 对象(或者可被 Python literal 解析为字典)。
        - 如果不需要工具,则正常回答文本。

    行为流程:
        1. 将用户消息加入对话历史。
        2. 请求 LLM 回复。
        3. 若 LLM 使用 TOOL_CALL 格式输出,则解析并执行对应工具。
        4. 将工具执行结果注入历史,再次请求 LLM 给出最终回答。
    """

    TOOL_CALL_PATTERN = r"TOOL_CALL:(\w+):(.+)"

    # 无工具版本的默认系统提示
    DEFAULT_PROMPT_WITHOUT_TOOLS = (
        "You are a helpful and intelligent AI assistant. Answer the user concisely and accurately."
    )

    # 有工具版本的系统提示
    DEFAULT_PROMPT_WITH_TOOLS = """
You are an intelligent agent capable of using external tools to help solve user queries.

Below is the list of available tools:

{tool_descriptions}

When you decide that using a tool is necessary:
- Use the exact format:
  TOOL_CALL:tool_name:{{"param1": 1, "param2": "abc"}}
- The parameters must be a valid JSON object that includes all required arguments of the tool.
- If no tool is needed, simply respond with normal text.

Follow the format strictly. Do not explain the tool call. Do not wrap the tool call in code blocks.
"""

    def __init__(
        self,
        name: str,
        llm: ChatOpenAI,
        tools: Optional[List[Tool]] = None,
        system_prompt: Optional[str] = None,
        max_turns: int = 3,
    ):
        """
        初始化 SimpleAgent。

        参数:
            name: 智能体名称。
            llm: ChatOpenAI 实例,用作语言模型推理。
            tools: 工具列表,可选。
            system_prompt: 自定义系统提示词;若为空则根据工具列表自动生成。
            max_turns: 保留字段(未来可用于限制工具调用深度等)。
        """
        super().__init__(name=name, llm=llm, tools=tools, system_prompt=system_prompt, max_turns=max_turns)

        # 构建系统提示词,并写入第一条系统消息
        if self.system_prompt:
            sp = self.system_prompt
        else:
            sp = self._build_system_prompt()

        self.add_message(Message.system(sp))

    def _build_system_prompt(self) -> str:
        """根据是否有工具可用生成系统提示词。"""
        if not self.tools:
            return self.DEFAULT_PROMPT_WITHOUT_TOOLS
        return self.DEFAULT_PROMPT_WITH_TOOLS.format(tool_descriptions=self.tool_descriptions)

    def _parse_tool_call(self, text: str) -> Tuple[bool, Optional[str], Optional[Dict]]:
        """
        解析模型输出中的 TOOL_CALL 指令。

        返回:
            (has_call, tool_name, params_dict_or_None)

        说明:
            - 首选 JSON 解析;失败时再尝试 Python literal_eval。
            - 若两者均失败,则 params 返回 None。
        """
        match = re.search(self.TOOL_CALL_PATTERN, text)
        if not match:
            return False, None, None

        tool_name = match.group(1)
        params_str = match.group(2).strip()

        # 尝试解析参数为字典
        params = None
        try:
            params = json.loads(params_str)
        except Exception:
            try:
                params = ast.literal_eval(params_str)
            except Exception:
                params = None

        return True, tool_name, params

    def run(self, user_input: str) -> str:
        """
        执行智能体主流程(单输入模式)。

        步骤:
            1. 将用户消息写入历史;
            2. 请求 LLM 返回回复;
            3. 若包含 TOOL_CALL,则执行工具并将结果写入历史;
            4. 让 LLM 基于工具结果生成最终回答。
        """
        # 1) 加入用户消息
        self.add_message(Message.user(user_input))

        # 2) 请求 LLM 回复(llm.generate 会基于 Message 历史推理)
        llm_reply = self.llm.generate(self._history)

        # 保存 assistant 的原始回复
        self.add_message(Message.assistant(llm_reply))

        # 3) 检查是否是工具调用
        has_call, tool_name, params = self._parse_tool_call(llm_reply)

        if has_call:
            return self._handle_tool_call(tool_name, params)

        # 普通回答
        return llm_reply

    # ------------ 内部工具调用处理逻辑 ------------ #

    def _handle_tool_call(self, tool_name: str, params) -> str:
        """
        执行指定工具,并让 LLM 基于工具结果生成最终回答。

        参数:
            tool_name: 工具名称。
            params: 已解析的参数字典;若无效则抛出异常。

        返回:
            final_answer: 工具调用完成后 LLM 给出的最终回答。

        异常:
            ToolNotFoundError: 工具不存在。
            ToolCallError: 参数无效或工具执行失败。
        """
        # 检查工具是否存在
        if tool_name not in self.tool_by_names:
            raise ToolNotFoundError(f"Unknown tool: {tool_name}")

        if not isinstance(params, dict):
            raise ToolCallError("Tool parameters must be provided as an object/dict.")

        tool = self.tool_by_names[tool_name]

        # 执行工具,并捕获运行时异常
        try:
            result = tool(**params)
        except Exception as e:
            raise ToolCallError(f"Tool execution failed: {e}")

        # 将工具结果写回对话历史
        # 说明:这里使用 user 风格的消息 ("TOOL_RESULT:xxx")
        #       这样可以与 assistant 消息区分,并使模型更容易理解"这是外部信息"。
        self.add_message(Message.user(f"TOOL_RESULT:{result}"))

        # 再次询问 LLM,让其基于工具结果生成最终回答
        final_answer = self.llm.generate(self._history)
        self.add_message(Message.assistant(final_answer))

        return final_answer

整个代码和上篇文章介绍的思路一样,非常简单直接。

工具实现

带有工具调用能力的Agent实现好了,最后一步是实现几个工具给它调用。

网络搜索

第一个实现的工具是网络搜索,首先推荐的是一个叫做DuckDuckGoSearch的工具,它的优点是免费(不需要API_KEY),对国内友好。最近去搜索发现它升级了,改名为ddgs,底层集成了不同的网络搜索服务,比如bing, brave, duckduckgo, google, mojeek, yandex, yahoo, wikipedia。可以通过backend参数自定,默认参数下会自动根据底层可用性进行切换。

把一个函数变成工具很简单,增加@tool装饰器即可:

py 复制代码
from ddgs import DDGS
from vero.tool import tool

@tool
def duckduckgo_search(query: str, max_results: int = 3) -> str:
    """
    执行 DuckDuckGo 搜索并返回格式化的结果。

    参数:
        query (str): 搜索关键词。
        max_results (int, 可选): 返回的最大搜索结果数量,默认 3。

    返回:
        str: 格式化后的搜索标题、链接和摘要;
             如果搜索失败或无结果,则返回相应提示。
    """
    try:
        # 使用上下文管理器确保 DDGS 会话正确关闭
        with DDGS() as ddgs:
            # 执行搜索
            results = ddgs.text(query, max_results=max_results)

        if not results:
            return "没有找到搜索结果。"

        output_lines = []
        for r in results:
            # r 是一个包含 title、href、body 的字典
            title = r.get("title", "无标题")
            href = r.get("href", "")
            body = r.get("body", "")
            output_lines.append(f"标题: {title}\n链接: {href}\n摘要: {body}\n")

        # 拼接输出字符串
        return "\n".join(output_lines)

    except Exception as e:
        # 捕获所有异常,避免 Agent 崩溃
        return f"DuckDuckGo 搜索失败: {e}"

数学计算

py 复制代码
import math
from vero.tool import tool

@tool
def math_evaluate(expr: str) -> str:
    """
    安全地计算传入的数学表达式,并返回结果。

    参数:
        expr (str): 表达式字符串。
            可以包含数字、运算符(+、-、*、/、**、%、括号),
            以及 math 模块中的函数/常量(如 sqrt, sin, cos, pi 等)。

    返回:
        str: 计算结果;如遇错误或非法输入,则返回错误信息。
    """
    # 允许使用的名称:来自 math 模块的函数与常量
    allowed_names = {
        k: getattr(math, k) for k in dir(math) if not k.startswith("__")
    }

    try:
        # 将表达式编译为代码对象
        code = compile(expr, "<string>", "eval")

        # 检查表达式中引用的变量名称,不允许未授权名称
        for name in code.co_names:
            if name not in allowed_names:
                return f"错误: 不允许使用 '{name}'。"

        # 在受限的环境中执行表达式
        result = eval(code, {"__builtins__": {}}, allowed_names)

        return str(result)

    except Exception as e:
        # 捕获语法错误、数学错误等所有异常
        return f"计算错误: {e}"

简单Agent实战

它的整个流程如上图所示,下面的代码展示了如何实现:

py 复制代码
import time

from vero.core import ChatOpenAI, Agent
from vero.agents import SimpleAgent
from vero.tool.buildin import math_evaluate, duckduckgo_search
from vero.config import settings


def run_agent(agent_class: Agent, input_text: str, max_turns=5):
    llm = ChatOpenAI()
    
    agent: Agent = agent_class(
        "test-agent",
        llm,
      	# 写死了两个工具
        tools=[duckduckgo_search, math_evaluate],
        max_turns=max_turns,
    )

    print(agent.run(input_text))


if __name__ == "__main__":
    # settings.model_name = "xxx"
    start = time.perf_counter()
    run_agent(
        SimpleAgent,
        "寒武纪的市值多少",
    )
    print(f"⏳ Elapsed: {time.perf_counter() - start:.1f} s")

输出(增加了一些详细的打印):

复制代码
🤖 Initializing LLM with model: Qwen/Qwen3-32B
🚀 Initializing SimpleAgent `test-agent` ...
🛠️ Generated system prompt from tool list.

==============================
👤 User Input: 寒武纪的市值多少
==============================

📤 LLM Raw Reply: TOOL_CALL:duckduckgo_search:{"query": "寒武纪的市值", "max_results": 3}

🔍 Parsing model output for TOOL_CALL ...
🧩 TOOL_CALL detected → tool: `duckduckgo_search`, raw params: {"query": "寒武纪的市值", "max_results": 3}
📦 Parameters parsed via JSON.
🛠️ Tool call detected → dispatching tool handler.

⚙️ Handling tool call for `duckduckgo_search` ...
🔧 Executing tool `duckduckgo_search` with params: {'query': '寒武纪的市值', 'max_results': 3}
📦 Tool result: Title: Deepseek一句话 寒 武 纪 市 值 超越这些大蓝筹
Link: https://www.cls.cn/detail/2123025
Snippet: ①仅一天时间, 寒 武 纪 市 值 飙升近1000亿元。 ②牛散章建平去年年末新进前十大股东,据测算或已盈利30亿元左右。 ③今日电子板块A股 市 值 超过银行业,位居第一。

Title: 市 值 近4000... - OFweek电子工程网
Link: https://ee.ofweek.com/2025-08/ART-8460-2850-30668993.html
Snippet: 8月14日, 寒 武 纪 股价再度大涨,盘中最高价达985元/股, 市 值 一度突破4000亿元大关,成为A股半导体板块当之无愧 的 " 寒 王"。

Title: 国产算力突围战中," 寒 王"一度登顶A股 - 财富中文网
Link: https://www.fortunechina.com/shangye/c/2025-08/27/content_468164.htm
Snippet: 在8月26日这份半年报出炉三天前,高盛已将 寒 武 纪 的 目标价从1223元上调50%至1835元,并称中国信息通信研究院宣布包括中国电信、华为和 寒 武 纪 等8家. 公司通过了DeepSeek适配测试,再次印证了对 寒 武 纪 强大研发能力 的 积极看法。
 | ⏱️ Cost:  1.6s
📥 Adding TOOL_RESULT message to history.
🏁 Final LLM Answer:  截至2025年8月,寒武纪的市值一度突破4000亿元大关,成为A股半导体板块的重要企业。不过,具体市值可能会因市场波动而变化。建议查看实时的财经信息以获取最新数据。

⏳ Elapsed: 4.5 s

从日志可以看到,它确实调用了duckduckgo_search工具,当时结果不是最新的,要获取最新结果可以尝试把当前时间加入到提示词中。

我们再来测试一下数学计算:

py 复制代码
answer = run_agent(
        SimpleAgent,
        "帮我计算98123123乘以12389,然后再开根号等于多少",
    )
复制代码
🤖 Initializing LLM with model: Qwen/Qwen3-32B
🚀 Initializing SimpleAgent `test-agent` ...
🛠️ Generated system prompt from tool list.

==============================
👤 User Input: 帮我计算98123123乘以12389,然后再开根号等于多少
==============================

📤 LLM Raw Reply: TOOL_CALL:math_evaluate:{"expr": "sqrt(98123123 * 12389)"}

🔍 Parsing model output for TOOL_CALL ...
🧩 TOOL_CALL detected → tool: `math_evaluate`, raw params: {"expr": "sqrt(98123123 * 12389)"}
📦 Parameters parsed via JSON.
🛠️ Tool call detected → dispatching tool handler.

⚙️ Handling tool call for `math_evaluate` ...
🔧 Executing tool `math_evaluate` with params: {'expr': 'sqrt(98123123 * 12389)'}
📦 Tool result: 1102563.9985266163 | ⏱️ Cost:  0.0s
📥 Adding TOOL_RESULT message to history.
🏁 Final LLM Answer: 98123123 乘以 12389,然后再开根号的结果是约 1,102,564.

⏳ Elapsed: 2.3 s

这里也成功调用了数学计算工具。

我们这个简单Agent真的很简单(naive),它不会连续调用两个工具:

py 复制代码
🤖 Initializing LLM with model: Qwen/Qwen3-32B
🚀 Initializing SimpleAgent `test-agent` ...
🛠️ Generated system prompt from tool list.

==============================
👤 User Input: 寒武纪的市值,乘以2等于多少
==============================

📤 LLM Raw Reply: TOOL_CALL:duckduckgo_search:{"query": "寒武纪的市值", "max_results": 3}

🔍 Parsing model output for TOOL_CALL ...
🧩 TOOL_CALL detected → tool: `duckduckgo_search`, raw params: {"query": "寒武纪的市值", "max_results": 3}
📦 Parameters parsed via JSON.
🛠️ Tool call detected → dispatching tool handler.

⚙️ Handling tool call for `duckduckgo_search` ...
🔧 Executing tool `duckduckgo_search` with params: {'query': '寒武纪的市值', 'max_results': 3}
📦 Tool result: Title: 股价逼近茅台,市盈率超4000倍:寒武纪还能走多远?_腾讯新闻
Link: https://news.qq.com/rain/a/20250827A0532T00
Snippet: 2025年8月的A股市场,见证了一场科技股的极致狂欢。主角,是被称为"AI芯片第一股"的寒武纪(SH688256)。8月22日,寒武纪股价强势封上涨停板 ...

Title: "寒王"争议:寒武纪市值超6600亿,是价值重估还是泡沫?-36氪
Link: https://www.36kr.com/p/3442163740465284
Snippet: 陈天石作为寒武纪的创始人,其个人财富也水涨船高,身价已经高达1898亿元。 生成式AI时代,寒武纪迎来了最好的发展阶段,经营业绩得到实质性 ...

Title: 寒武纪市值突破5200亿:中国AI芯片的"寒武纪大爆发"
Link: https://www.sohu.com/a/927601027_122500756
Snippet: 思元370系列:基于7nm制程工艺,是寒武纪首款采用chiplet(芯粒)技术的AI芯片,集成了390亿个晶体管,最大算力高达256TOPS(INT8),是寒武纪第二代产品思元270算力的2倍。作为一家企业,...
 | ⏱️ Cost:  1.2s
📥 Adding TOOL_RESULT message to history.
🏁 Final LLM Answer: TOOL_CALL:math_evaluate:{"expr": "6600 * 2"}

⏳ Elapsed: 8.7 s

它最后知道要调用数学工具计算6600亿的翻倍,但是不会真正的调用,这是因为我们只允许它一轮简单的工具调用。

相关推荐
xqlily1 小时前
PyTorch:深度学习研究的核心引擎(下)
人工智能·pytorch·深度学习
IT·小灰灰1 小时前
腾讯HY2.0 Think推理模型深度解析:技术突破、应用场景与实践指南
开发语言·人工智能·python·深度学习·神经网络·算法·数据分析
却道天凉_好个秋1 小时前
OpenCV(三十七):外接矩形
人工智能·opencv·计算机视觉
da_vinci_x1 小时前
PS 图案预览 + Sampler:告别“修接缝”,AI 量产 4K 无缝 PBR
人工智能·游戏·aigc·贴图·技术美术·游戏美术·法线贴图
m0_704887891 小时前
Day 27
人工智能·python·机器学习
木枷2 小时前
LLama-factory数据报错
人工智能·机器学习·llama
田里的水稻2 小时前
DL_端到端_基于卷积循环神经网络的(CRNN)车牌号识别
人工智能·rnn·深度学习
大模型真好玩2 小时前
LangChain1.0实战之多模态RAG系统(四)——Trae Solo搭建部署多模态RAG前端(附AI编程实践指南)
人工智能·langchain·trae
hrrrrb2 小时前
【深度学习】自动微分模块
人工智能·深度学习