在 LlamaIndex 中集成 MCP Toolbox:toolbox-llamaindex SDK 完整实战指南
【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox
本文是 MCP Toolbox for Databases 官方 Python SDK 家族中toolbox-llamaindex包的使用指南。它面向希望在 LlamaIndex 应用中直接调用数据库工具(SQL 查询、数据源读写等)的开发者,讲解从安装、初始化客户端、加载工具集,到接入AgentWorkflow智能体、配置客户端认证与工具认证、绑定参数、使用 Secure Parameters 保护敏感数据,以及通过 OpenTelemetry 观测工具调用全链路的完整流程。读完本文,你将能够把 MCP Toolbox 的能力无缝嵌入自己的 LlamaIndex 智能体,并掌握生产环境下的安全与可观测性最佳实践。
Overview:toolbox-llamaindex是什么
toolbox-llamaindex包为 MCP Toolbox 服务提供了一层 Python 接口,使你能够在自己构建的应用中加载并调用工具。MCP Toolbox 本身是一个开源的数据库 MCP 服务器(服务端代码位于本仓库,Python 发行版通过 pypi/src/toolbox_server/main.py 将 Go 二进制封装进 wheel 供toolbox-server命令使用),而 SDK 则是连接该服务与你的 LlamaIndex 应用的桥梁:
你的 LlamaIndex 应用 (AgentWorkflow) │ 加载工具 / 调用工具 ▼ toolbox-llamaindex SDK (ToolboxClient) │ MCP 协议 over HTTP(默认 2026-07-28) ▼ MCP Toolbox 服务 (http://127.0.0.1:5000) │ 按 tools.yaml 中定义的配置执行 ▼ 数据库源(PostgreSQL、BigQuery、MySQL 等)通过这一链路,开发者无需关心各数据库驱动与 MCP 协议的细节,只需定义工具(如 docs/en/documentation/configuration/tools/_index.md 中描述的kind: tool配置),即可在 LlamaIndex 中直接使用。
安装
pip install toolbox-llamaindex安装后,你可以在应用代码中导入:
from toolbox_llamaindex import ToolboxClient如果需要使用 OpenTelemetry 观测能力,还需要额外安装toolbox-core的 telemetry 扩展(详见后文"OpenTelemetry"小节):
pip install toolbox-core[telemetry]前提说明:SDK 需要连接一个正在运行的 MCP Toolbox 服务。在 docs/en/documentation/getting-started/local_quickstart.md 的快速入门教程中,介绍了从零配置 PostgreSQL 数据源并启动 Toolbox 服务的完整步骤(该教程同样把
pip install toolbox-llamaindex作为 LlamaIndex 场景的 SDK 安装方式)。
快速上手:最小可运行示例
下面的最小示例展示了完整的接入流程:创建ToolboxClient、加载工具集、构建 LlamaIndex 的AgentWorkflow,并让智能体自主决定调用哪些工具:
import asyncio from llama_index.llms.google_genai import GoogleGenAI from llama_index.core.agent.workflow import AgentWorkflow from toolbox_llamaindex import ToolboxClient async def run_agent(): async with ToolboxClient("http://127.0.0.1:5000") as toolbox: tools = toolbox.load_toolset() vertex_model = GoogleGenAI( model="gemini-3-flash-preview", vertexai_config={"project": "project-id", "location": "us-central1"}, ) agent = AgentWorkflow.from_tools_or_functions( tools, llm=vertex_model, system_prompt="You are a helpful assistant.", ) response = await agent.run(user_msg="Get some response from the agent.") print(response) asyncio.run(run_agent())代码要点拆解:
ToolboxClient("http://127.0.0.1:5000"):客户端地址指向 Toolbox 服务默认监听地址。从仓库 server.json 的runtimeArguments可以看出,服务端默认--address 127.0.0.1、--port 5000,两者与本示例默认值一一对应。toolbox.load_toolset():不带参数时加载服务端全部工具(工具按工具集 toolset 组织,也可指定具体工具集)。AgentWorkflow.from_tools_or_functions(tools, llm=vertex_model, ...):将加载到的工具直接注入 LlamaIndex 智能体,LLM 会在收到用户消息后动态选择合适的工具执行。
对于包含完整服务端配置、数据库准备与多框架对比的端到端教程,请参阅 Toolbox 本地快速入门(其中也给出了 LlamaIndex 场景需要额外安装的依赖llama-index-llms-google-genai)。
客户端初始化与传输协议
基本用法
from toolbox_llamaindex import ToolboxClient # Replace with your Toolbox service's URL async with ToolboxClient("http://127.0.0.1:5000") as toolbox: ...ToolboxClient也支持同步上下文管理器(如 OpenTelemetry 示例中的with ToolboxClient(...)用法),以及直接实例化后在后续代码中手动load_tool/load_toolset。
传输协议选择
SDK 支持多种与 Toolbox 服务器通信的传输协议。默认情况下,客户端使用最新受支持的 Model Context Protocol (MCP) 版本。你可以在客户端初始化时通过protocol选项显式指定协议,这在以下场景中非常有用:
- 需要使用 Toolbox 原生 HTTP 协议;
- 需要将客户端固定到某个旧版 MCP 协议版本。
注意:MCP 传输选项均指基于 HTTP 的 Model Context Protocol。
当前支持的协议常量如下表所示:
| 常量 | 说明 |
|---|---|
Protocol.MCP | (默认)默认 MCP 版本的别名(当前为2026-07-28)。 |
Protocol.MCP_LATEST | 最新稳定 MCP 版本的别名(当前为2026-07-28)。 |
Protocol.MCP_DRAFT | 即将发布的草稿 MCP 版本的别名(当前为2026-07-28)。 |
Protocol.MCP_v20260728 | MCP 协议版本 2026-07-28。 |
Protocol.MCP_v20251125 | MCP 协议版本 2025-11-25。 |
Protocol.MCP_v20250618 | MCP 协议版本 2025-06-18。 |
Protocol.MCP_v20250326 | MCP 协议版本 2025-03-26。 |
Protocol.MCP_v20241105 | MCP 协议版本 2024-11-05。 |
使用默认协议:
from toolbox_llamaindex import ToolboxClient from toolbox_core.protocol import Protocol async with ToolboxClient("http://127.0.0.1:5000", protocol=Protocol.MCP) as toolbox: # Use client pass固定到特定旧版本(例如 2025-03-26):
from toolbox_llamaindex import ToolboxClient from toolbox_core.protocol import Protocol async with ToolboxClient("http://127.0.0.1:5000", protocol=Protocol.MCP_v20250326) as toolbox: # Use client pass为什么协议版本重要?服务端(本仓库 Go 实现)会在 internal/server/mcp 下维护v20241105、v20250326、v20250618、v20251125、v20260728等多个 MCP 协议版本的处理器,每个目录对应一套实现。选择较新的协议版本(如2026-07-28)才能解锁 Secure Parameters、MCP Apps 等新扩展能力;而固定旧版本则可能使包含新特性的工具在tools/list中被过滤掉(详见"Secure Parameters"小节)。
加载工具
加载工具集(toolset)
工具集是一组相关工具的集合。你可以加载一个工具集中的全部工具,也可以指定加载某一个工具集:
# Load all tools tools = toolbox.load_toolset() # Load a specific toolset tools = toolbox.load_toolset("my-toolset")加载单个工具
tool = toolbox.load_tool("my-tool")加载单个工具让你对"哪些工具可供 LLM 智能体使用"拥有更细粒度的控制——例如你只想暴露只读查询工具,就可以只加载那一个工具而不是整个工具集。
在 LlamaIndex 中使用工具
LlamaIndex 的智能体能够根据用户输入动态选择和执行工具。将从 Toolbox SDK 加载的工具纳入智能体的工具库即可:
from llama_index.llms.google_genai import GoogleGenAI from llama_index.core.agent.workflow import AgentWorkflow vertex_model = GoogleGenAI( model="gemini-3-flash-preview", vertexai_config={"project": "project-id", "location": "us-central1"}, ) # Initialize agent with tools agent = AgentWorkflow.from_tools_or_functions( tools, llm=vertex_model, system_prompt="You are a helpful assistant.", ) # Query the agent response = await agent.run(user_msg="Get some response from the agent.") print(response)维持智能体状态
如果需要在多轮对话中维持智能体状态(例如记忆用户偏好、累积上下文),可以在调用时传入Context:
from llama_index.core.agent.workflow import AgentWorkflow from llama_index.core.workflow import Context from llama_index.llms.google_genai import GoogleGenAI vertex_model = GoogleGenAI( model="gemini-3-flash-preview", vertexai_config={"project": "project-id", "location": "us-central1"}, ) agent = AgentWorkflow.from_tools_or_functions( tools, llm=vertex_model, system_prompt="You are a helpful assistant.", ) # Save memory in agent context ctx = Context(agent) response = await agent.run(user_msg="Give me some response.", ctx=ctx) print(response)Context是 LlamaIndexAgentWorkflow的状态容器。通过创建独立的Context(agent)并在每次agent.run(..., ctx=ctx)中复用,智能体可以在多次运行之间保留对话状态与中间数据。
手动调用工具
除了交给智能体自主调用,你还可以使用call方法手动执行工具:
result = tools[0].call(name="Alice", age=30)这在测试工具、或在智能体框架之外需要对工具执行进行精确控制时非常有用。手动调用传入的是普通关键字参数,与工具定义中的参数一一对应。
客户端到服务器认证(Client-to-Server Authentication)
本节介绍当 Toolbox 服务器要求认证时,如何对ToolboxClient本身进行认证。这在保护 Toolbox 服务器端点时至关重要——尤其是部署在 Cloud Run、GKE 等平台、未认证访问被限制的环境中。
注意区分:客户端到服务器认证用于在加载/调用任何工具之前验证客户端身份;而下一节 认证工具(Authenticating Tools) 处理的是在已连接的 Toolbox 会话中为特定工具提供凭据,两者是不同层面的机制。
何时需要客户端认证
当你的 Toolbox 服务器被配置为拒绝未认证请求时,就需要这种认证,典型场景包括:
- Toolbox 服务器部署在 Cloud Run 上,并配置为"Require authentication";
- 服务器位于 Identity-Aware Proxy (IAP) 或类似的认证层之后;
- 自托管 Toolbox 服务器上配置了自定义认证中间件。
在这些场景下,如果不提供正确的客户端认证,load_tool等连接或调用操作很可能会以Unauthorized错误失败。
工作原理
ToolboxClient允许你指定一些函数(异步客户端使用协程)来为发送给 Toolbox 服务器的每个请求动态生成 HTTP 头。最常见的用法是添加携带 bearer token(例如 Google ID token)的Authorization头。
这些头生成函数会在每次请求之前被调用,从而确保始终使用最新的凭据或头值。
配置方法
from toolbox_llamaindex import ToolboxClient async with ToolboxClient( "toolbox-url", client_headers={"header1": header1_getter, "header2": header2_getter}, ) as client: ...client_headers接收一个字典:键是请求头名称,值是无参可调用对象(函数或协程),返回该头的值。
使用 Google Cloud 服务器认证
对于托管在 Google Cloud(例如 Cloud Run)上且要求Google ID token认证的 Toolbox 服务器,toolbox_core的auth_methods辅助模块提供了实用函数(对应aget_google_id_token等工具)。
Cloud Run 分步指南
配置权限:在 Cloud Run 服务上为主账号授予
roles/run.invokerIAM 角色。这个主体可以是你的用户账号邮箱或一个服务账号。配置凭据:
- 本地开发:配置应用默认凭据 ADC(Application Default Credentials);
- Google Cloud 环境:当在 Google Cloud 内运行(如 Compute Engine、GKE、另一个 Cloud Run 服务、Cloud Functions)时,ADC 通常会使用环境的默认服务账号自动配置好。
连接 Toolbox 服务器:
from toolbox_llamaindex import ToolboxClient from toolbox_core import auth_methods auth_token_provider = auth_methods.aget_google_id_token(URL) async with ToolboxClient( URL, client_headers={"Authorization": auth_token_provider}, ) as client: tools = await client.aload_toolset() # Now, you can use the client as usual.其中
aget_google_id_token(URL)返回一个协程,它在每次请求前获取面向该 URL 的 Google ID token,从而实现 Cloud Run 所需的 bearer 认证。
认证工具(Authenticating Tools)
安全提示:始终使用 HTTPS 将应用与 Toolbox 服务连接,尤其是在使用配置了认证的工具时。使用 HTTP 会让你的应用暴露在严重的安全风险之下。
有些工具需要用户认证才能访问敏感数据。
支持的认证机制
Toolbox 目前支持通过OIDC 协议+ID token(注意是 ID token 而非 access token)进行认证,基于Google OAuth 2.0实现。在服务端,这一能力由kind: authService配置提供,参见 Google Sign-In 认证配置:将type: google与clientId(Web 应用 OIDC 模式)或audience+mcpEnabled(MCP Authorization 模式)组合,即可校验请求中的 Google ID token。
配置工具
关于如何为工具配置认证参数(即把工具参数与 ID token 中的 OIDC claim 字段自动绑定,例如从subclaim 填充user_id),请参阅 工具配置文档中的 Authenticated Parameters 一节。配置完成后,这类参数在请求体中无需客户端传值,而是由服务端从请求头中的 ID token 自动解析填充。
配置 SDK
你首先需要一个从你的认证服务获取 ID token 的方法:
async def get_auth_token(): # ... Logic to retrieve ID token (e.g., from local storage, OAuth flow) # This example just returns a placeholder. Replace with your actual token retrieval. return "YOUR_ID_TOKEN" # Placeholder为单个工具添加认证
async with ToolboxClient("http://127.0.0.1:5000") as toolbox: tools = toolbox.load_toolset() auth_tool = tools[0].add_auth_token_getter("my_auth", get_auth_token) # Single token multi_auth_tool = tools[0].add_auth_token_getters({"auth_1": get_auth_1}, {"auth_2": get_auth_2}) # Multiple tokens # OR auth_tools = [tool.add_auth_token_getter("my_auth", get_auth_token) for tool in tools]add_auth_token_getter(auth_name, getter):为工具绑定单个认证 token 的获取函数;add_auth_token_getters(**getters):为需要多个认证服务的工具绑定多个 token 获取函数(键为authService名称,值为获取函数);- 如果需要给工具集中的所有工具都加上认证,可以使用列表推导式逐个绑定。
加载时添加认证
auth_tool = toolbox.load_tool(auth_token_getters={"my_auth": get_auth_token}) auth_tools = toolbox.load_toolset(auth_token_getters={"my_auth": get_auth_token})注意:加载时添加的认证 token 只影响该次调用所加载的工具。
完整示例
import asyncio from toolbox_llamaindex import ToolboxClient async def get_auth_token(): # ... Logic to retrieve ID token (e.g., from local storage, OAuth flow) # This example just returns a placeholder. Replace with your actual token retrieval. return "YOUR_ID_TOKEN" # Placeholder async with ToolboxClient("http://127.0.0.1:5000") as toolbox: tool = toolbox.load_tool("my-tool") auth_tool = tool.add_auth_token_getter("my_auth", get_auth_token) result = auth_tool.call(input="some input") print(result)参数绑定(Parameter Binding)
通过 SDK 预置工具参数的值,这些值不会被 LLM 修改。参数绑定适用于以下场景:
- 保护敏感信息:API 密钥、机密等;
- 保证一致性:确保某些参数使用特定值;
- 预填已知数据:提供默认值或上下文。
为工具绑定参数
async with ToolboxClient("http://127.0.0.1:5000") as toolbox: tools = toolbox.load_toolset() bound_tool = tool[0].bind_param("param", "value") # Single param multi_bound_tool = tools[0].bind_params({"param1": "value1", "param2": "value2"}) # Multiple params # OR bound_tools = [tool.bind_param("param", "value") for tool in tools]加载时绑定参数
bound_tool = toolbox.load_tool("my-tool", bound_params={"param": "value"}) bound_tools = toolbox.load_toolset(bound_params={"param": "value"})注意:加载时绑定的值只影响该次调用所加载的工具。
绑定动态值
也可以传入一个函数来绑定动态值,函数会在调用时执行:
def get_dynamic_value(): # Logic to determine the value return "dynamic_value" dynamic_bound_tool = tool.bind_param("param", get_dynamic_value)注意:绑定参数值不需要修改工具配置,属于纯客户端行为。
Secure Parameters(安全参数)
版本要求:Secure Parameters 自
toolbox-llamaindex版本0.9.0(toolbox-core>=1.4.0)起支持,并且要求 MCP 协议版本为2026-07-28或更新,同时启用com.google.cloud/toolbox.v1扩展。服务端配置细节见 工具配置文档中的 Secure Parameters 一节。
Secure Parameters 是为敏感运行时值设计的,例如最终用户的customer_id、租户标识或密钥 token——这些值不允许 LLM 看到或控制。
核心特性
- Schema 隔离:安全参数会自动从 LlamaIndex 的工具元数据和参数定义(
tool.metadata.fn_schema)中剔除,保持模型上下文干净,防止参数幻觉或泄漏; - 提示注入防御:如果模型尝试在标准参数中提供安全参数,执行会立即失败;
- 快速失败校验:缺少必需的安全参数时,会在发起调用前于本地直接失败;
- 加载时绑定或加载后绑定:你可以在加载工具时提供安全参数,也可以对已加载的工具绑定安全参数(同步与异步客户端均支持)。
服务端配置(工具侧)
在工具 YAML 中,把参数标记为secure: true即可(示例来自 工具配置文档):
kind: tool name: search_secure_data type: postgres-sql source: my-pg-instance statement: | SELECT * FROM sessions WHERE customer_id = $1 AND session_token = $2 parameters: - name: customer_id type: string description: Sensitive customer identifier supplied out-of-band by the calling application secure: true - name: session_token type: string description: Sensitive session token supplied out-of-band by the calling application secure: true配置约束:安全参数默认且始终必填,不能设为可选;一个参数不能同时带有secure: true与authServices、default或required: false。
协议层原理
从仓库中的 Secure Parameters 扩展规范 可以看到协议层的完整行为:
- 工具发现(
tools/list):在协议版本2026-07-28下,安全参数被放入独立的secureInputSchema字段,与标准inputSchema分离;如果客户端未声明com.google.cloud/toolbox.v1扩展能力,或使用旧版协议(<2026-07-28),定义了安全参数的工具会直接从工具列表中过滤掉,防止不支持安全参数的客户端误调用; - 工具执行(
tools/call):安全参数通过独立的secureArguments字段带外(out-of-band)传输,与模型生成的arguments完全隔离;若安全参数出现在标准arguments中、标准参数出现在secureArguments中、或客户端未协商扩展即调用安全工具,服务端会按错误矩阵返回对应 JSON-RPC 错误(-32021/-32602); - 扩展协商:服务端在
server/discover的capabilities.extensions中公布com.google.cloud/toolbox.v1,客户端需在请求元数据_meta["io.modelcontextprotocol/clientCapabilities"].extensions中声明支持;扩展可通过服务端--disable-ext com.google.cloud/toolbox.v1启动参数关闭。
SDK 使用方式
from toolbox_llamaindex import ToolboxClient client = ToolboxClient("http://127.0.0.1:5000") # Option A: Bind secure parameters when loading tools (sync or async) bound_tool = client.load_tool("search_secure_data", secure_params={"customer_id": "cust_12345"}) tools = client.load_toolset("my-set", secure_params={"customer_id": "cust_12345"}) # Async client loading: # bound_tool = await client.aload_tool("search_secure_data", secure_params={"customer_id": "cust_12345"}) # tools = await client.aload_toolset("my-set", secure_params={"customer_id": "cust_12345"}) # Option B: Bind secure parameters to an un-bound loaded tool (returns a new immutable tool) raw_tool = client.load_tool("search_secure_data") single_bound = raw_tool.bind_secure_param("customer_id", "cust_12345") multi_bound = raw_tool.bind_secure_params({ "customer_id": "cust_12345", "session_token": "token-xyz", }) # Option C: Dynamic callable (evaluated per invocation) dynamic_tool = raw_tool.bind_secure_param("customer_id", lambda: get_current_user_id())三种方式的语义:
- Option A:加载时通过
secure_params参数预绑定(注意:加载时绑定只影响本次加载的工具); - Option B:对已加载的未绑定工具调用
bind_secure_param/bind_secure_params,返回新的不可变工具实例; - Option C:传入动态可调用对象,每次调用时求值,适合会话级上下文(如从请求中获取当前用户 ID)。
交叉绑定的互斥约束
安全参数与普通参数使用两套互斥的 API,交叉使用会抛出明确错误:
- 对安全参数调用
tool.bind_param()会抛出:ValueError: parameter '<name>' is a secure parameter; use bind_secure_param/bind_secure_params instead - 对普通参数调用
tool.bind_secure_param()会抛出:ValueError: parameter '<name>' is a regular parameter; use bind_param/bind_params instead
这一设计从 API 层面强制区分两类参数,避免开发者误将敏感值通过普通参数路径暴露给 LLM。
异步用法
为了通过协作式多任务获得更好的性能,你可以使用ToolboxClient的异步接口:
注意:
aload_tool、aload_toolset等异步接口要求异步环境。关于如何运行异步 Python 程序,请参考 Pythonasyncio官方文档。
import asyncio from toolbox_llamaindex import ToolboxClient async def main(): async with ToolboxClient("http://127.0.0.1:5000") as toolbox: tool = await client.aload_tool("my-tool") tools = await client.aload_toolset() response = await tool.ainvoke() if __name__ == "__main__": asyncio.run(main())异步接口清单(对应同步接口):
| 同步 | 异步 | 说明 |
|---|---|---|
load_tool | aload_tool | 加载单个工具 |
load_toolset | aload_toolset | 加载工具集 |
call | ainvoke | 调用工具 |
上下文管理器async with | 同左 | 异步客户端本身即协程上下文 |
OpenTelemetry 观测
SDK 通过toolbox-core层支持 OpenTelemetry 的 tracing 与 metrics,遵循 MCP Semantic Conventions。
启用方式
首先安装toolbox-core的 telemetry 扩展:
pip install toolbox-core[telemetry]然后在创建客户端时传入telemetry_enabled=True:
from toolbox_llamaindex import ToolboxClient with ToolboxClient("http://127.0.0.1:5000", telemetry_enabled=True) as toolbox: tool = toolbox.load_tool("my-tool") result = tool(param="value")请在创建客户端之前配置好你的 OpenTelemetryTracerProvider和MeterProvider。服务端侧,Toolbox 也支持通过--telemetry-otlp(OTLP 导出端点)、--telemetry-gcp(直接导出到 Google Cloud Monitoring)与--telemetry-service-name等启动参数开启遥测(参见 server.json 的runtimeArguments),从而形成端到端的可观测链路。
每次调用的遥测属性(Per-call Telemetry Attributes)
使用TelemetryAttributes将模型、用户和智能体元数据附加到工具调用上:
from toolbox_core import TelemetryAttributes from toolbox_llamaindex import ToolboxClient attrs = TelemetryAttributes( llm_model="gemini-3.6-flash", user_id="user-123", agent_id="agent-abc", ) with ToolboxClient("http://127.0.0.1:5000") as toolbox: tools = toolbox.load_toolset("my-toolset", telemetry_attributes=attrs) tool = toolbox.load_tool("my-tool") instrumented_tool = tool.add_telemetry_attributes(attrs)你可以把telemetry_attributes传给load_tool()或load_toolset(),也可以对已加载的工具调用add_telemetry_attributes()。这些属性会随每次工具调用一起上报,便于在追踪系统中按模型、用户、智能体维度聚合分析调用质量与成本。
总结
toolbox-llamaindex为 LlamaIndex 应用接入 MCP Toolbox for Databases 提供了一条完整、安全且可观测的路径:
- 接入层:
ToolboxClient一行初始化,load_toolset/load_tool加载工具,AgentWorkflow.from_tools_or_functions完成智能体集成,Context维持多轮状态; - 协议层:默认使用最新 MCP 版本(
2026-07-28),也可通过Protocol.*常量固定任意历史版本; - 安全层:客户端到服务器认证(
client_headers+ Google ID token)保护传输端点;工具认证(OIDC ID token)保护敏感工具;参数绑定与 Secure Parameters 让敏感值彻底远离 LLM 上下文; - 性能与可观测:全异步接口配合 OpenTelemetry tracing/metrics,可无缝融入现有可观测体系。
如果需要在其他框架中使用同一套 Toolbox 能力,仓库文档中还提供了 ADK、LangChain 等 SDK 的对应指南,以及 完整的本地快速入门教程 供进一步参考。
【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考