You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过Hugging Face端点调用Mistral AI函数时的循环调用问题

问题解决:Mistral AI函数调用的格式适配与多轮对话处理

核心问题分析

  1. 格式不兼容:Mistral-7B-Instruct-v0.3要求使用特定对话格式(如[INST]/[/INST]包裹指令、多轮对话用角色标注结构),LangChain的ChatPromptTemplate默认格式无法被模型正确识别,导致工具调用逻辑失效。
  2. 工具结果回传失败:直接用ChatMessage(role='function')追加工具返回结果时,Mistral模型无法识别该角色类型,因此持续触发工具调用而非生成最终回复。

解决方案步骤

1. 自定义符合Mistral要求的对话模板

放弃ChatPromptTemplate,手动构建字符串格式,严格遵循Mistral的Instruct规范:

  • 系统提示+初始请求用[INST]包裹
  • 助手回复用[/INST]引导
  • 工具返回结果以明确的补充信息形式加入对话,确保模型能识别这是已获取的外部数据。

2. 调整工具调用后的消息格式

将工具返回的结果转换为模型可理解的文本形式,明确告知模型“已获取所需数据,请生成最终回复”,避免模型重复触发工具调用。

3. 优化工具绑定逻辑

Mistral的工具调用格式与OpenAI存在差异,需手动指定函数调用的输出格式要求,确保模型返回的调用指令能被正确解析。

修改后的完整代码

# Import necessary libraries
from langchain_huggingface.chat_models import ChatHuggingFace
from langchain_huggingface import HuggingFaceEndpoint
from langchain_core.utils.function_calling import convert_to_openai_function
from dotenv import load_dotenv, find_dotenv
import os
import serpapi
import json

# Load environment variables
_ = load_dotenv(find_dotenv())
serp_key = os.getenv('SERP_API_KEY')

# Configure the LLM endpoint
llm = HuggingFaceEndpoint(
    repo_id='mistralai/Mistral-7B-Instruct-v0.3',
    huggingfacehub_api_token='*********',
    task="text-generation",
    model_kwargs={
        "max_new_tokens": 2000,
        "temperature": 0.5,
        "top_p": 0.95,
        "do_sample": True
    }
)

# Define functions
functions = [
    {
        "name": "plan_holiday",
        "description": "获取指定目的地的旅游景点信息,用于制定旅行计划",
        "parameters": {
            "type": "object",
            "properties": {
                "destination": {
                    "type": "string",
                    "description": "旅行目的地",
                },
                "duration": {
                    "type": "integer",
                    "description": "旅行天数",
                },
            },
            "required": ["destination", "duration"],
        },
    }
]

# 转换为OpenAI格式的工具定义
openai_functions = [convert_to_openai_function(f) for f in functions]

# 创建带工具绑定的模型
chat_model = ChatHuggingFace(llm=llm)
llm_with_tools = chat_model.bind_tools(openai_functions, tool_choice='auto')

# 手动构建符合Mistral格式的初始对话
system_prompt = "你是专业旅行规划师,需要根据用户需求制定详细旅行计划。如果需要外部景点信息,调用plan_holiday工具获取,获取后直接生成最终计划,无需再次调用工具。"
user_query = "我想在威尼斯度过12天的假期,能帮我规划吗?"

# Mistral要求的初始提示格式
initial_prompt = f"""<s>[INST] {system_prompt}

用户请求:{user_query}

可用工具:
{str(openai_functions)}

如果需要调用工具,请返回以下格式的JSON:
{{"name": "工具名称", "parameters": {{"参数名": "参数值"}}}}[/INST]"""

# 第一次调用模型(触发工具调用)
response = llm_with_tools.invoke(initial_prompt)
print("第一次模型响应:", response)

# 解析工具调用请求
tool_call = response.additional_kwargs.get('tool_calls', [])[0]
tool_name = tool_call['function']['name']
tool_args = json.loads(tool_call['function']['arguments'])

# 调用外部API获取数据
def search_google_for(destination):
    client = serpapi.Client(api_key=serp_key)
    result = client.search(
        params={
            "q": f"{destination} 12天旅行景点推荐",
            "location": "India",
            "hl": "en",
            "gl": "IN",
            "google_domain": "google.com",
        }
    )
    return result

results = search_google_for(tool_args['destination'])

# 提取工具返回的信息
info_about_places = ""
if results.get("organic_results"):
    for idx, result in enumerate(results["organic_results"], 1):
        title = result.get("title", "")
        snippet = result.get("snippet", "")
        info_about_places += f"{idx}. {title}\n{snippet}\n\n"

# 构建包含工具结果的第二轮对话,符合Mistral格式
second_prompt = f"""<s>[INST] {system_prompt}

用户请求:{user_query}

已调用{tool_name}工具,获取到以下威尼斯旅游信息:
{info_about_places}

请基于以上信息生成详细的12天威尼斯旅行计划,无需再调用任何工具。[/INST]"""

# 第二次调用模型(生成最终回复)
final_response = llm.invoke(second_prompt)
print("最终旅行计划:", final_response)

关键修改说明

  • 格式适配:采用Mistral官方要求的<s>[INST] ... [/INST]格式构建提示,确保模型正确解析指令与上下文。
  • 工具结果呈现:将工具返回信息直接嵌入提示,明确告知模型无需再次调用工具,引导生成最终回复。
  • 逻辑简化:放弃LangChain消息列表管理,改用手动构建字符串的方式,彻底避免格式不兼容问题。

内容的提问来源于stack exchange,提问作者Neo_clown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 16:05:12