自定义LiteLLM包装器适配ADK:工具调用失效问题排查
问题分析与修复方案
你的自定义LiteLLM包装器无法触发工具调用,核心问题是丢弃了完整的对话上下文(包括工具调用相关的系统提示、历史交互),导致LLM无法感知工具的存在或生成符合要求的工具调用指令。以下是具体缺失的环节和修复步骤:
1. 错误丢弃完整对话消息
你的代码中只提取了最新的用户消息,把系统提示、助手之前的工具调用请求、工具返回结果等关键上下文全部丢弃。Agent触发工具需要LLM能看到:
- 系统提示中定义的工具列表、调用格式要求
- 完整的对话历史(包括之前的工具调用交互)
修复代码:
把body中的messages直接传入完整的kwargs["messages"],而非仅最新用户消息:
# 替换原来的body构造代码 body = { 'messages': messages # 传入完整对话上下文 }
2. 异步方法未正确实现
acompletion是异步方法,但你直接同步调用了process_request,这会导致异步场景阻塞,同时不符合LiteLLM的异步规范。需要改用异步请求库(如aiohttp)实现异步请求逻辑:
修复示例:
import aiohttp # 新增导入 # 在类中新增异步处理方法 async def async_process_request(self, *args, **kwargs) -> litellm.ModelResponse: messages = kwargs.get("messages", []) if not messages: raise ValueError("The 'messages' parameter is required.") headers = ... # 保留你的header构造逻辑 query_params = ... # 保留你的query参数构造逻辑 body = {'messages': messages} full_path = ... # 保留你的路径构造逻辑 async with aiohttp.ClientSession() as session: async with session.post(full_path, headers=headers, params=query_params, json=body) as response: response.raise_for_status() api_response_data = await response.json() # 构造ModelResponse逻辑和同步方法一致 model_response = ModelResponse( id=api_response_data.get("id"), choices=[ litellm.Choices( finish_reason=choice.get("finish_reason"), index=choice.get("index"), message=litellm.Message( content=choice["message"]["content"], role=choice["message"]["role"], ), ) for choice in api_response_data.get("choices") ], model=self._model, # 修正变量名错误:原代码用了未定义的_self._eyq_model usage=litellm.Usage( prompt_tokens=api_response_data.get("usage", {}).get("prompt_tokens"), completion_tokens=api_response_data.get("usage", {}).get("completion_tokens"), total_tokens=api_response_data.get("usage", {}).get("total_tokens"), ) ) return model_response # 修正异步方法实现 async def acompletion(self, *args, **kwargs) -> litellm.ModelResponse: return await self.async_process_request(*args, **kwargs)
3. 变量名错误(潜在问题)
原代码中model=self._eyq_model,但初始化时定义的是self._model = os.getenv("MODEL"),这会触发AttributeError,需修正为model=self._model。
4. 未适配工具调用的返回标识
LiteLLM通过finish_reason字段识别是否需要触发工具调用,需确保后端LLM返回的finish_reason值符合要求(例如tool_call)。如果后端返回的字段名不同,需要在构造litellm.Choices时做映射:
finish_reason=choice.get("finish_reason") or choice.get("tool_trigger"), # 适配后端返回的字段名
内容的提问来源于stack exchange,提问作者Al Ant
相关产品推荐
相关产品推荐

