一、 面试题目
在构建支持百万级工具(Tools/Skills)的 Agent 系统时,你是如何设计工具的架构与发现机制的?面对如此庞大的工具海,如何实现极其精准、低延迟的工具路由与选择?在大模型(LLM)调用工具时,又是如何进行风险控制与参数治理的?
二、 知识储备
1. 核心背景:百万级工具系统的"三道坎"
- 上下文爆仓(Context Overflow): 大模型的上下文窗口是有限且昂贵的。不可能把百万级工具的 JSON-Schema 全量塞进 Prompt 中,否则不仅会撑爆 Token,还会由于"中间丢失(Lost in the Middle)"效应导致模型完全无法遵循指令。
- 路由延迟与幻觉(Routing Latency & Hallucination): 在百万级工具海中,传统的"语义嵌入(Embedding)单路检索"容易召回大量相似但错误的工具。此外,模型在选择参数时极易产生格式或类型的幻觉。
- 高危权限越权(Security & Execution Risks): 百万级工具必然涉及企业内网 API、数据库读写、个人隐私数据。一旦 Agent 遭遇 Prompt 注入攻击,可能会引发灾难性的系统提权或数据外泄。
2. 核心技术栈拆解
|------------|----------------------------------------------------------------------------------|-------------------------------------------------------------------|
| 维度 | 解决方案 (The Solution) | 关键技术 (The Key) |
| 工具协议统一 | 模型上下文协议(MCP, Model Context Protocol)。将异构的企业 API、数据库、标准协议统一抽象为自描述的 Agent 接入端。 | JSON-Schema 规范、MCP Server 动态注册、OpenAPI 协议转换。 |
| 多级路由漏斗 | 从百万到 Top-K 的三层过滤机制(Retrieval Pipeline)。利用确定性逻辑层层筛选,只把最相关的几个工具喂给大模型。 | BM25 关键字 + Dense Vector 混合检索、跨编码器重排(Reranker)、图数据库(Entity-Graph)。 |
| 参数合规护栏 | 物理隔离的沙箱(Sandbox)与强类型校验。阻断大模型直接拼接执行命令,在中间件层拦截幻觉参数。 | Pydantic / JSON-Schema 验证器、Wasm/Docker 隔离沙箱、基于 RBAC 的工具级权限网关。 |
三、 破局之道
在回答完具体的架构技术后,通过下面这段话展现你对 "工业级智能体(AgentOps)确定性治理" 的深度思考:
"设计一个支持百万级工具的 Agent 系统,核心要理解我们是在用'工程的确定性围剿大模型的概率性'。
你可以告诉面试官:
纯靠大模型自主规划去盲猜工具的时代已经过去了。在百万级规模下,工具的发现与路由本质上是一个**'多级倒置漏斗'**。
- 第一层利用 BM25 与向量混合检索(Hybrid Search),结合企业组织架构图,从百万工具中粗筛出 Top-100;
- 第二层通过 Reranker(重排模型)与工具依赖图 精准剪枝到 Top-5;
- 最终,只有这 5 个工具的 Schema 会被塞入大模型的上下文窗口,完成 Tool Call。
在工程实践中,我主张将**'鉴权网关'与'模型解耦'**。大模型只负责表达'我想调用什么工具、参数是什么'(意图决策),而'该不该调、能不能调、怎么去调'全部由平台数据面的物理沙箱和 RBAC 权限门禁来硬核接管。通过 MCP 协议实现工具生态的自描述与冷热动态插拔。一个优秀的架构师不应赌大模型 100% 不犯错,而是要建立一整套纵深防御体系,确保系统即使面对 Prompt 注入攻击,也能在安全护栏内优雅熔断。"
四、 代码实现与架构演进
1. 多级工具路由网关实现(Python):从百万工具中精准打捞与重排
下面的核心代码展示了如何设计一个高效的工具检索路由器(Tool Router)。它结合了前置 Namespace 隔离、密集/稀疏混合检索、跨编码器重排(Rerank)以及基于令牌的硬核死循环检测:
python
import os
from typing import List, Dict, Any
from sentence_transformers import CrossEncoder
class MillionToolRouter:
def __init__(self, vector_store_client, redis_client):
self.vector_store = vector_store_client
self.redis = redis_client
# 引入小轻快重排模型,对向量检索召回的候选集进行语义相关度二次精打分
self.reranker = CrossEncoder("BAAI/bge-reranker-base")
self.MAX_TOOL_LOOP = 5 # 核心护栏:限制单次任务 Agent 连续调用工具的死循环上限
async def route_tools(self, user_query: str, tenant_id: str, user_roles: List[str], top_k: int = 5) -> List[Dict[str, Any]]:
"""
百万级工具的多级智能漏斗检索
"""
# 1. 权限与多租户前置硬隔离 (Early-Binding Guardrail)
# 拒绝将无权访问的工具送入检索,从源头防止横向越权与数据泄露
role_filter_expr = f"tenant_id == '{tenant_id}' AND (is_public == true OR permitted_roles ANY IN {user_roles})"
# 2. 混合检索(第一层漏斗:从 1,000,000+ 工具中粗筛出 50 个候选工具)
# 综合考虑密集语义匹配(Dense Vector)和 专有名词/API名称精准命中(Sparse BM25)
candidate_tools = await self.vector_store.hybrid_search(
query=user_query,
filter_expression=role_filter_expr,
limit=50,
partition_name=tenant_id # 租户物理空间隔离
)
if not candidate_tools:
return []
# 3. 跨编码器精密重排(第二层漏斗:从 50 个候选精简到 Top-K)
# 大模型对 Prompt 中工具的顺序和数量极度敏感,重排能极大降低幻觉率
passages = [tool["description"] for tool in candidate_tools]
pairs = [[user_query, passage] for passage in passages]
rerank_scores = self.reranker.predict(pairs)
# 4. 组装最终结果,附带工具的完整 MCP (Model Context Protocol) 标准 Schema
sorted_tools = []
for idx, score in sorted(enumerate(rerank_scores), key=lambda x: x[1], reverse=True):
if len(sorted_tools) >= top_k:
break
# 仅在被选中的 Top-K 工具上回表加载完整的 JSON-Schema,节省显存与内存
tool_detail = candidate_tools[idx]
sorted_tools.append({
"name": tool_detail["name"],
"mcp_endpoint": tool_detail["endpoint"],
"schema": tool_detail["json_schema"], # 标准 MCP 描述规范
"rerank_score": float(score)
})
return sorted_tools
async def check_execution_loop_guard(self, session_id: str) -> bool:
"""
FinOps & 安全护栏:防止 Agent 在 Tool Call 阶段陷入死循环,刷爆 Token 账单
"""
loop_key = f"agent:loop_count:{session_id}"
# 利用 Redis 原子自增特性记录调用频次
current_loops = await self.redis.incr(loop_key)
if current_loops == 1:
await self.redis.expire(loop_key, 600) # 10分钟后自动过期失效
if current_loops > self.MAX_TOOL_LOOP:
# 超过连环触发上限,强制拉闸熔断
return False
return True
2. 工具执行安全沙箱配置:参数网关强制隔离(MCP Gatekeeper)
大模型生成的工具参数绝不能直接透传给系统终端或内网,必须通过网关进行形式和权限的双向拦截校验:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: agent-mcp-tool-gatekeeper
namespace: agent-runtime
spec:
parentRefs:
- name: enterprise-agent-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /api/v1/tools/execute
# 核心硬核加分点:在将大模型的 Tool Call 请求分发到真正的业务 API 之前,
# 强行经过一个受 Wasm / 非特权 Docker 沙箱保护的参数拦截网关(Interceptor)
filters:
- type: ExtensionRef
extensionRef:
kind: WASMPlugin
name: mcp-param-validator-plugin # 进行强类型参数校验、SQL注入拦截、PII脱敏
backendRefs:
- name: mcp-tool-sandbox-service
port: 8080
五、 面试加分修养建议
- 提到"动态上下文按需脱敏(Dynamic Token Masking)": 百万级工具系统往往涉及企业内部的大量敏感敏感 PII 信息(如用户身份证、商业秘密)。提到在工具路由器内部,对送入大模型的 Schema 元数据进行自动混淆和哈希指纹化(Fingerprinting) ,等到大模型输出 Tool Call 意图后,再在数据面网关处利用 Token 逆向解密回填(De-masking) ,这样可以实现大模型完全在不知道企业真实物理敏感参数的情况下完成精准业务调度。听到这一设计,面试官对你的安全意识和架构深度会直接给出全优(Strong Hire)评价。
- 提到"工具静态分析缓存(Schema Warm-up)": 面对百万工具,如果每次请求都去关系型数据库里捞 JSON-Schema,QPS 会非常难看。应该在平台控制端构建一套基于内存 Radix Tree(基数树)的 Schema 热预热机制,将百万 API 的路径及出入参缩略图常驻在 Redis 集群中,实现毫秒级路由决策。