当前位置: 首页 > java >正文

检索增强的大模型工具调用:语义驱动的精准API选择技术

🔥🔥🔥Retrieval-Augmented Tool Selector 工具已开源!!!
求 Star ⭐️⭐️⭐️ :https://github.com/xiaoyesoso/retrieval-tool-selector

在大型语言模型(LLM)应用中,工具调用能力已成为连接AI与真实世界的桥梁。然而,传统方法存在工具选择不准确、参数匹配错误等问题。本文将深入探讨检索增强工具选择器(Retrieval-Augmented Tool Selector) 如何通过语义嵌入技术解决这些挑战。

引言:大模型工具调用的挑战

当前LLM工具调用面临三大核心问题:

  • 幻觉问题:模型可能调用不存在的工具

  • 参数歧义:对枚举型参数理解不准确

  • 上下文缺失:无法有效利用历史交互信息

用户查询
传统工具调用
问题
工具选择错误
参数匹配错误
枚举值误解

1. 检索增强工具选择器架构

1.1 系统整体架构

预处理
工具嵌入
工具库
枚举嵌入
枚举值
用户查询
语义嵌入引擎
工具选择器
参数过滤器
增强的API调用
大模型执行

1.2 核心组件交互

User API_Gateway Tool_Selector OpenAI_API 发送查询请求 提取用户查询 计算语义相似度 返回增强工具集 转发增强请求 返回执行结果 返回最终响应 User API_Gateway Tool_Selector OpenAI_API

2. 核心实现解析

2.1 语义嵌入引擎

class RetrievalAugmentedToolSelector:def __init__(self, tools, api_key, base_url, embedding_model="text-embedding-ada-002"):# 初始化OpenAI客户端self.client = openai.Client(api_key=api_key, base_url=base_url)# 存储工具定义和嵌入模型self.embedding_model = embedding_modelself.tools = tools# 预计算工具嵌入向量self.tool_embeddings = []self.tool_names = []self.tool_definitions = []for tool in tools:# 构建工具语义文本:名称+描述tool_name = tool["function"]["name"]tool_description = tool["function"]["description"]tool_text = f"{tool_name}: {tool_description}"# 计算嵌入向量embedding = self._get_embedding(tool_text)self.tool_embeddings.append(embedding)self.tool_names.append(tool_name)# 存储工具定义副本self.tool_definitions.append({"type": "function","function": {"name": tool_name,"description": tool_description,"parameters": tool["function"]["parameters"]
})# 转换为NumPy数组便于计算self.tool_embeddings = np.array(self.tool_embeddings)# 预计算枚举值嵌入self.enum_embeddings_cache = {}all_enum_values = set()# 收集所有枚举值for tool in tools:parameters = tool["function"]["parameters"]if "properties" in parameters:for prop in parameters["properties"].values():if "enum" in prop:for value in prop["enum"]:str_value = str(value).strip()all_enum_values.add(str_value)# 批量计算枚举值嵌入if all_enum_values:enum_values_list = list(all_enum_values)embeddings = self._get_embeddings(enum_values_list)# 创建枚举值到嵌入的映射for value, embedding in zip(enum_values_list, embeddings):self.enum_embeddings_cache[value] = embedding

2.2 工具选择算法

def select_tools(self, query, tool_threshold=0.7, tool_top_k=1, enum_threshold=0.6, enum_top_k=3):"""基于语义相似度选择最相关的工具和参数参数:query: 用户查询文本tool_threshold: 工具相似度阈值(0-1)tool_top_k: 返回的最大工具数量enum_threshold: 枚举值相似度阈值enum_top_k: 每个参数保留的最大枚举值数"""# 计算查询的嵌入向量query_embedding = self._get_embedding(query)# 计算工具相似度similarities = cosine_similarity([query_embedding], self.tool_embeddings)[0]# 按相似度排序工具tool_scores = list(enumerate(similarities))tool_scores.sort(key=lambda x: x[1], reverse=True)selected_tools = []for idx, score in tool_scores:# 应用阈值和top_k过滤if score >= tool_threshold and len(selected_tools) < tool_top_k:# 深拷贝工具定义tool_copy = json.loads(json.dumps(self.tool_definitions[idx]))# 过滤枚举参数parameters = tool_copy["function"]["parameters"]if "properties" in parameters:for prop_name, prop in parameters["properties"].items():if "enum" in prop:# 转换枚举值为字符串enum_values = [str(v).strip() for v in prop["enum"]]# 应用语义过滤prop["enum"] = self._filter_enum_values(query_embedding,enum_values,threshold=enum_threshold,top_k=enum_top_k)selected_tools.append(tool_copy)return selected_tools

2.3 枚举值过滤算法

def _filter_enum_values(self, query_embedding, enum_values, threshold, top_k):"""基于语义相似度过滤枚举值参数:query_embedding: 查询的嵌入向量enum_values: 枚举值列表threshold: 相似度阈值top_k: 保留的最大值数量"""if not enum_values:return enum_values# 获取预计算的枚举值嵌入enum_embeddings = [self.enum_embeddings_cache[value] for value in enum_values]enum_embeddings = np.array(enum_embeddings)# 计算相似度similarities = cosine_similarity([query_embedding], enum_embeddings)[0]# 创建(索引, 相似度, 值)元组enum_scores = [(i, sim, value) for i, (sim, value) in enumerate(zip(similarities, enum_values))]# 按相似度降序排序enum_scores.sort(key=lambda x: x[1], reverse=True)# 应用阈值过滤filtered_enum = []for i, sim, value in enum_scores:if sim >= threshold and len(filtered_enum) < top_k:filtered_enum.append(value)return filtered_enum

3. 语义匹配过程详解

3.1 工具选择原理

用户查询
计算查询嵌入
预计算工具嵌入
余弦相似度计算
相似度排序
应用阈值过滤
返回Top-K工具

3.2 枚举值过滤原理

用户查询
查询嵌入
枚举值嵌入缓存
相似度计算
排序枚举值
应用阈值和Top-K
返回过滤后枚举值

3.3 参数调优指南

参数默认值适用场景调整建议
tool_threshold0.7工具匹配工具数量多时提高,工具少时降低
tool_top_k1多工具场景根据实际工具数量调整
enum_threshold0.6参数过滤枚举值语义明确时提高
enum_top_k3多值参数根据参数复杂度调整

4. API服务集成实现

4.1 Flask API架构

@app.route('/v1/chat/completions', methods=['POST'])
def chat_completion():"""OpenAI兼容的聊天补全端点,带语义工具选择请求格式: https://platform.openai.com/docs/api-reference/chat/create响应格式: https://platform.openai.com/docs/api-reference/chat/object"""try:# 获取并验证请求负载payload = request.get_json()if not payload or "messages" not in payload:return jsonify({"error": {"message": "Invalid request: missing 'messages' parameter","type": "invalid_request_error"
}), 400# 增强请求:添加工具选择enhanced_payload = enhance_request(payload)# 调用OpenAI APIresponse = openai_client.chat.completions.create(enhanced_payload)# 返回OpenAI兼容响应return jsonify(response.to_dict())except Exception as e:return jsonify({"error": {"message": f"Processing error: {str(e)}","type": "server_error"
}), 500

4.2 请求增强过程

def enhance_request(payload: Dict[str, Any]) -> Dict[str, Any]:"""通过工具选择增强OpenAI请求负载保留所有原始参数"""# 创建负载副本payload = payload.copy()# 获取最新的用户消息user_query = process_message(payload.get("messages", []))if not user_query:return payload# 基于用户查询选择工具selected_tools = tool_selector.select_tools(user_query,tool_threshold=Config.TOOL_THRESHOLD,tool_top_k=Config.TOOL_TOP_K,enum_threshold=Config.ENUM_THRESHOLD,enum_top_k=Config.ENUM_TOP_K)# 添加选择的工具到请求负载payload["tools"] = selected_tools# 设置工具选择策略if "tool_choice" not in payload:payload["tool_choice"] = "auto"return payload

5. 部署与实践指南

5.1 部署架构

客户端
云环境
Web应用
移动应用
CLI工具
API服务
Docker容器
负载均衡
自动扩缩容
向量数据库
OpenAI API

5.2 Docker部署示例

# 使用Python 3.10精简镜像
FROM python:3.10-slim# 设置工作目录
WORKDIR /app# 复制依赖文件
COPY requirements.txt .# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt# 复制应用代码
COPY . .# 设置环境变量
ENV OPENAI_API_KEY=your_api_key
ENV PORT=5000# 暴露端口
EXPOSE 5000# 启动命令
CMD ["python", "app.py"]
http://www.xdnf.cn/news/10839.html

相关文章:

  • 《Pytorch深度学习实践》ch5-Logistic回归
  • 百万级临床试验数据库TrialPanorama发布!AI助力新药研发与临床评价迎来新基石
  • Rhino插件大全下载指南:解锁犀牛潜能,提升设计效率
  • C++11:unique_ptr的基本用法、使用场景和最佳使用指南
  • 利用lightgbm预测adult数据集
  • 支持TypeScript并打包为ESM/CommonJS/UMD三种格式的脚手架项目
  • MYSQL索引详解及索引优化、分析
  • Cyber Weekly #58
  • 低成本单节电池风扇解决方案WD8001
  • switch-while day6
  • Spring AOP(1)
  • 小家电外贸出口新利器:WD8001低成本风扇智能控制方案全解析
  • 模块化交互数字人系统:OpenAvatarChat,单台PC即可运行完整功能
  • sourcetree中的mercurial有什么用
  • Python实例题:Flask实现简单聊天室
  • 【PCB设计】STM32开发板——原理图设计(电源部分)
  • FLgo学习
  • leetcode46.全排列:回溯算法中元素利用的核心逻辑
  • MyBatis 一级缓存与二级缓存
  • 【Python进阶】装饰器
  • 基于白鲸优化算法的路径优化研究
  • 数字化赋能智能托育实训室课程体系
  • 工业透明材料应力缺陷难检测?OAS 软件应力双折射案例来解决
  • ADK实战-基于ollama+qwen3实现外部工具串行调用
  • 帝可得 - 运营管理APP
  • MMAD论文精读
  • day20 奇异值SVD分解
  • 线程池和数据库连接池的区别
  • 3-10单元格行、列号获取(实例:表格选与维度转换)学习笔记
  • 163MusicLyrics(歌词下载工具) v7.0