跳至主要内容

Mistral Agents API:带演示项目的指南

学习如何使用 Mistral 的 Agents API 构建 AI 代理,并了解工具使用、连接器、交接等关键概念。
· 12分钟 阅读

使用 AI 探索

Mistral 发布了Agents API,这是一个用于构建智能、自治 AI 代理的框架,能够执行复杂的多步骤任务。它通过集成工具使用、持久化记忆和编排能力,扩展了传统语言模型的能力边界。

在本教程中,我将带您使用 Mistral Agents API 构建能够以下列方式工作的智能助手:

  • 使用网页搜索、代码执行、图像生成等工具
  • 在长对话中保留记忆以维持上下文
  • 在多个代理之间委派任务

您将学习 Mistral 代理框架背后的核心概念,探索内置连接器与编排功能,并构建一个可运行的多代理助手。

我们通过每周五的免费通讯 The Median 为读者带来最新的 AI 动态,梳理一周重点新闻。订阅它,每周用几分钟保持敏锐:

什么是 Mistral 的 Agents API?

Mistral Agents API 是一个让大型语言模型执行多步骤动作、使用外部工具并在交互间保持记忆的框架。不同于简单的聊天 API,它使 AI 代理能够:

  • 访问网页、执行代码、生成图像或检索文档
  • 通过编排与其他代理协同
  • 使用长期记忆维持持久对话

目前仅支持 mistral-medium-latest(亦称 mistral-medium-2505)和 mistral-large-latest,后续可能会支持新模型。

核心概念解析

在动手之前,先澄清一下 Agents API 的核心概念。

mistral agents api diagram

来源:Mistral AI

代理(Agents)

代理在 Mistral 中是由模型驱动的人设,叠加了预设指令、工具访问和会话状态:

  • 指令引导代理的行为(如:“您是一名记录饮食的营养教练”)。
  • web_search 或 image_generation 等工具让代理执行现实世界的动作。
  • 记忆使代理能够在多轮对话中跟踪先前消息与工具输出,支持上下文推理。

这种抽象将基础的聊天模型转化为能参与复杂流程的多功能助手。

会话

用户与代理之间的每次交互都属于一个会话,会话会存储:

  • 历史消息与助手回复
  • 工具调用与结果
  • 用于分词级可见性的流式元数据(可选)

这些持久会话让代理能够执行多轮任务,如规划、修订或从早前输入中学习。

连接器与自定义工具支持

Mistral 通过以下方式简化工具集成:

  • 连接器:预集成的工具,如 web_search、code_execution、image_generation、document_library,开箱即用。
  • MCP 工具:允许开发者托管的自定义 API 作为工具在代理工作流中被调用。

可以将连接器视为内置应用,而将MCP 工具视为您编写的插件。两者结合,让代理既能使用内置能力,也能访问开发者定义的端点以实现个性化逻辑。

mistral agents api mcp diagram

来源:Mistral AI

条目与交接

Mistral 将会话中的所有动作记录为结构化的“条目(Entries)”,从而实现对消息交换与工具执行的可追溯与可控。

代理交接(handoffs)指一个代理将控制权委派给另一个代理,用以模块化工作流。

mistral agent handoffs

来源:Mistral AI

这种编排架构便于组合与管理复杂的多代理系统,同时不丢失透明度与控制力。

设置 Mistral API

让我们开始配置 Mistral。我们将先为项目创建一个 API 密钥。请按以下步骤操作:

  1. 首先,在 console.mistral.ai 创建 Mistral 账户或登录。

Mistral dashboard

  1. 然后,进入“工作区设置”(您名字旁的下拉箭头——左上角),点击“计费”添加支付信息并激活账户付款。

Mistral billing

  1. 点击“添加额度(Add credits)”,在表单中填写账单信息。然后填写您希望添加的额度数量。注意:至少需要添加 10 个额度。

Mistral credits

  1. 接着,在左侧选项卡点击“API keys”,并点击“Create new key”创建新的 API 密钥。请务必复制该密钥、妥善保存,且不要与任何人分享。

现在,您已经拥有可与 Mistral 模型交互并构建智能代理的有效 API 密钥。

项目概览:用 Mistral Agents 打造营养教练

在本项目中,我们将使用 Mistral 的 Agents API 构建一个由 AI 驱动的营养教练。用户流程如下:

  1. 用户提交刚吃的一餐(例如:“橄榄油酱鸡肉沙拉”)。
  2. 网页搜索代理使用内置连接器估算该餐的热量。
  3. 记录代理将此条目按用户名与时间戳进行记录。
  4. 最后,图像生成代理推荐一份健康的后续餐,同时返回图像、描述与食谱。

为提供一个用户可与营养师互动的网页界面,我们将使用 Gradio。

步骤 1:先决条件

开始之前,请确保已安装以下内容:

  • Python 3.8+
  • requirements.txt 中列出的所有必要包
python-dotenv==1.1.0
mistralai==0.0.7
typing-extensions==4.12.2
requests==2.31.0
gradio==4.34.0

另外,创建包含您 Mistral API 密钥的 .env 文件。此做法能保证 API 密钥安全,并使不同团队成员或部署环境在无需修改源代码的情况下使用各自的凭据。

MISTRAL_API_KEY=YOUR_API_KEY

注意:建议在 conda、venv 或 uv 等隔离环境中安装这些依赖,以避免与其他 Python 项目产生版本冲突。

以下是设置不同环境的命令:

使用 venv

python -m venv mistral_env
source mistral_env/bin/activate   # On Windows: mistral_env\Scripts\activate

使用 Conda

conda create -n mistral_env python=3.10
conda activate mistral_env

使用 uv

如果您尚未安装 uv:

pip install uv

然后:

uv venv mistral_env
source mistral_env/bin/activate

要安装上述所有依赖,请在终端运行以下命令:

pip install -r requirements.txt

注意: 如果在使用任意代理或连接器时遇到与 mistralai 相关的错误,请运行以下命令:

pip install –upgrade mistralai

这会将 mistralai 库升级到最新版本。

步骤 2:设置 Mistral 工具

本节将为与 Mistral Agents API 的交互准备工具与客户端设置。我们将定义工具模式、初始化客户端并验证认证。这些工具稍后将在配置具体代理(如热量估算或图像生成)时被引用。

步骤 2.1:工具注册与初始化

首先,我们定义工具模式、模型选择与客户端实例化。然后,构建 create_chat_completion() 与 check_client() 等辅助方法。以下代码放在 tools 文件夹内的 configs.py 文件中:

#Configuration file
from mistralai import Mistral, UserMessage, SystemMessage
from dotenv import load_dotenv
import os
load_dotenv()
# Mistral model 
mistral_model = "mistral-large-latest"
client = Mistral(api_key=os.environ.get("MISTRAL_API_KEY"))
# Agent IDs
web_search_id = "web_search_agent"
food_logger_id = "food_logger_agent"
user_assistant_id = "user_assistant_agent"
image_generator_id = "image_generator_agent"
# Tool definitions
tools = {
    "log_meal": {
        "name": "log_meal",
        "description": "Log a user's meal with calorie count",
        "input_schema": {
            "type": "object",
            "properties": {
                "username": {"type": "string"},
                "meal": {"type": "string"},
                "calories": {"type": "number"},
                "timestamp": {"type": "string", "format": "date-time"}
            },
            "required": ["username", "meal", "calories", "timestamp"]
        }
    },
    "web_search": {
        "name": "web_search",
        "description": "Search the web for information about a meal",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {"type": "string"}
            },
            "required": ["query"]
        }
    }
}

我们先导入 dotenv,将本地 .env 文件中的敏感变量(如 Mistral API 密钥)加载至 Python 环境,确保凭据安全且不出现在源代码中。随后选择默认模型 mistral-large-latest,并使用 API 密钥实例化 Mistral 客户端。

接着,我们用 JSON Schema 格式定义内部工具规范(schema),它们有助于:

  • 模拟 MCP 工具行为(尽管并非通过 McpTool 库注册)
  • 描述预期输入,如“username”“meal”“calories”
  • 帮助在各模块间保持一致的输入格式

现在,加入用于创建聊天补全、注册工具与代理、以及初始化客户端的辅助方法。

def create_chat_completion(messages, model=mistral_model):  
    # Convert messages to new format
    formatted_messages = []
    for msg in messages:
        if msg["role"] == "system":
            formatted_messages.append(SystemMessage(content=msg["content"]))
        else:
            formatted_messages.append(UserMessage(content=msg["content"]))
    return client.chat.complete(
        model=model,
        messages=formatted_messages
    )
# Register tools
def register_tools():
    for tool_name, tool in tools.items():
        print(f"Registered tool: {tool_name}")
# Register agents
def register_agents():
    print("Registered User Assistant Agent")
    print("Registered Web Search Agent")
    print("Registered Food Logger Agent")
# Initialize everything
def initialize():
    register_tools()
    register_agents()
    check_client()
# Check if the client is initialized
def is_client_initialized():
    return client is not None and os.environ.get("MISTRAL_API_KEY") is not None
def check_client():
    if not is_client_initialized():
        print("Mistral client is not initialized. Please check your API key.")
        return False
    print("Mistral client is initialized.")
    return True
initialize()

create_chat_completion() 封装了对 Mistral 客户端 SDK 的 client.chat.complete() 调用,用于向模型发送消息。

  • 它将原始字典格式的消息重新格式化为 Mistral SDK 要求的 UserMessage 与 SystemMessage 对象。
  • 也便于在应用中标准化补全调用。

register_tools() 与 register_agents() 在本地开发时用于日志记录,标明系统中哪些工具与代理处于激活状态。与此同时,check_client() 与 is_client_initialized() 确保 Mistral 客户端正确实例化且 API 密钥可用,帮助在代理执行时避免运行时错误。

步骤 2.2:使用网页搜索代理估算热量

完成基础工具与客户端初始化后,让我们构建一个专用的营养网页搜索代理。该代理使用 Mistral 的 web_search 连接器,实时查询餐食的热量估算。以下代码位于 tools 文件夹内的 web_search.py 文件。

# Web search tool
import re
from mistralai import Mistral, UserMessage, SystemMessage
from tools.configs import client
def search_calories(meal_desc):
    try:
        # Web search agent
        websearch_agent = client.beta.agents.create(
            model="mistral-medium-latest",
            description="Agent able to search for nutritional information and calorie content of meals",
            name="Nutrition Search Agent",
            instructions="You have the ability to perform web searches with web_search to find accurate calorie information. Return ONLY a single number representing total calories.",
            tools=[{"type": "web_search"}],
            completion_args={
                "temperature": 0.3,
                "top_p": 0.95,
            }
        )
        response = client.beta.conversations.start(
            agent_id=websearch_agent.id,
            inputs=f"What are the total calories in {meal_desc}?"
        )
        print("Raw response:", response)
        # Extract the number from the response
        if hasattr(response, 'outputs'):
            for output in response.outputs:
                if hasattr(output, 'content'):
                    if isinstance(output.content, str):
                        numbers = re.findall(r'\d+', output.content)
                        if numbers:
                            return int(numbers[0])
                    elif isinstance(output.content, list):
                        for chunk in output.content:
                            if hasattr(chunk, 'text'):
                                numbers = re.findall(r'\d+', chunk.text)
                                if numbers:
                                    return int(numbers[0])
        print("No calorie information found in web search response")
        return 0     
    except Exception as e:
        print(f"Error during web search: {str(e)}")
        return 0

在上述代码中,search_calories() 使用 Mistral Agents API 的内置网页搜索连接器,使代理能够执行实时网页查询(如热量估算),克服静态模型训练的局限。其工作流程如下:

  1. 创建代理:首先使用 mistral-medium-latest 模型创建“Nutrition Search Agent”,配备 web_search 工具,并指示其仅返回 热量数值。
  2. 执行查询:随后启动会话,询问所给餐食描述的总热量。
  3. 解析响应:使用正则表达式从响应中提取第一个数字(应为热量值)。
  4. 回退机制:若未找到有效数字或出现错误,函数会记录问题并返回 0 作为回退。

没有 web_search 时,大多数模型无法回答近期事件或训练数据中未见的特定餐食问题;有了它,我们可以实时查询营养信息、餐厅菜单或新闻文章。

网页搜索有两个变体:

  • web_search:轻量、通用的搜索引擎连接器(本项目使用)。
  • web_search_premium:增强版,包含新闻源验证与更广的上下文收集。

接下来,我们将探索仅基于提示词逻辑的回退热量估算。

步骤 2.3:估算、记录与餐食建议

本节实现三个关键函数,作为回退或增强功能。以下代码位于 tools 文件夹中的 next.py 文件。

#Meal suggestions
from datetime import datetime
from tools.configs import client, create_chat_completion
from mistralai import SystemMessage, UserMessage
import re
def estimate_calories(meal_desc):   
    try:
        # Messages for calorie estimation
        messages = [
            SystemMessage(content="You are a nutrition expert. Estimate calories in meals. Return ONLY a single number representing total calories."),
            UserMessage(content=f"Estimate calories in: {meal_desc}")
        ]
        response = client.chat.complete(
            model="mistral-small-latest",  # Using smaller model to avoid rate limits
            messages=messages,
            temperature=0.1,
            max_tokens=50
        )
        content = response.choices[0].message.content
        numbers = re.findall(r'\d+', content)    
        if numbers:
            return int(numbers[0])
        return 0     
    except Exception as e:
        print(f"Error during calorie estimation: {str(e)}")
        return 0
def log_meal(username, meal, calories):  
    try:
        # Messages for meal logging
        messages = [
            SystemMessage(content="You are a meal logging assistant. Log the user's meal with calories."),
            UserMessage(content=f"Log this meal: {meal} with {calories} calories for user {username} at {datetime.utcnow().isoformat()}")
        ]
        response = client.chat.complete(
            model="mistral-small-latest",  # Using smaller model to avoid rate limits
            messages=messages,
            temperature=0.1,
            max_tokens=100
        )
        return response.choices[0].message.content.strip()
    except Exception as e:
        print(f"Error during meal logging: {str(e)}")
        return f"Logged {meal} ({calories} calories) for {username}"
def suggest_next_meal(calories, dietary_preference):   
    try:
        # Messages for meal suggestion
        messages = [
            SystemMessage(content="You are a nutrition expert. Suggest healthy meals based on calorie intake and dietary preferences."),
            UserMessage(content=f"Suggest a {dietary_preference} meal that would be a good next meal after consuming {calories} calories. Make it specific and appetizing.")
        ]
        response = client.chat.complete(
            model="mistral-small-latest",  
            messages=messages,
            temperature=0.7
        )
        return response.choices[0].message.content.strip()        
    except Exception as e:
        print(f"Error during meal suggestion: {str(e)}")
        return "Unable to suggest next meal at this time."

该脚本定义了支撑营养工作流的核心后端函数(从热量估算到后续餐食规划)。这些函数使用轻量级 Mistral 模型与标准聊天补全,当网页搜索不可用或为避免速率限制错误时,无需创建任何代理或使用连接器。各函数作用如下:

  1. estimate_calories():当 web_search 连接器失败或不可用时作为回退。
    1. 它发送一条系统消息,设定助手角色为营养专家,并附上包含用户要记录餐食的用户提示。
    2. 模型使用较低的 temperature=0.1 以获得确定性输出。也就是说,对于热量估算与记录等偏重稳定与事实的任务,模型在相同输入下会给出一致、可复现的响应,而非追求创意多样性。
    3. 通过正则从模型响应中提取第一个数字。
  2. log_meal():记录用户的餐食,并包含时间戳。
    1. 通过聊天补全配合指令使用,并返回助手格式化的确认信息。
    2. 无需专门的后端数据库即可实现轻量内部记录。
  3. suggest_next_meal():根据先前摄入热量与饮食偏好推荐下一餐。
    1. 以 temperature=0.7 调用模型,鼓励更有创意的建议。
    2. 将响应清理后返回作为下一餐建议。

这些函数结合在一起,无需外部 API 即可完成热量估算、记录确认与健康推荐。下一步,我们将使用 Mistral 的图像生成连接器可视化食物建议。

步骤 2.4:使用图像生成连接器生成可视化

现在为助手增加视觉层。本步骤使用 Mistral 的内置 image_generation 连接器,生成下一份推荐餐食的诱人图像。

#Image generation tool
import os
import re
from mistralai import Mistral, UserMessage, SystemMessage
from mistralai.models import ToolFileChunk
from tools.configs import client
from datetime import datetime
def generate_food_image(meal_description):  
    try:
        print(f"Starting image generation for: {meal_description}")        
        # Image generation agent
        image_agent = client.beta.agents.create(
            model="mistral-medium-latest",
            name="Food Image Generation Agent",
            description="Agent used to generate food images.",
            instructions="Use the image generation tool to create appetizing food images. Generate realistic and appetizing images of meals.",
            tools=[{"type": "image_generation"}],
            completion_args={
                "temperature": 0.3,
                "top_p": 0.95,
            }
        )
        print("Created image generation agent")
        response = client.beta.conversations.start(
            agent_id=image_agent.id,
            inputs=f"Generate an appetizing image of: {meal_description}",
            stream=False  
        )
        print("Got response from image generation")
        os.makedirs("generated_images", exist_ok=True)
        # Process the response and save images
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        image_paths = []
        if hasattr(response, 'outputs'):
            print(f"Processing {len(response.outputs)} outputs")
            for output in response.outputs:
                if hasattr(output, 'content'):
                    print(f"Processing content of type: {type(output.content)}")
                    if isinstance(output.content, list):
                        for i, chunk in enumerate(output.content):
                            print(f"Processing chunk {i} of type: {type(chunk)}")
                            if isinstance(chunk, ToolFileChunk):
                                print(f"Found ToolFileChunk with file_id: {chunk.file_id}")
                                try:
                                    # Download the image
                                    file_bytes = client.files.download(file_id=chunk.file_id).read()       
                                    # Save the image
                                    image_path = f"generated_images/meal_{timestamp}_{i}.png"
                                    with open(image_path, "wb") as file:
                                        file.write(file_bytes)
                                    image_paths.append(image_path)
                                    print(f"Successfully saved image to: {image_path}")
                                except Exception as e:
                                    print(f"Error processing image chunk: {str(e)}")
                    else:
                        print(f"Content is not a list: {output.content}")
        if image_paths:
            print(f"Successfully generated {len(image_paths)} images")
            return image_paths[0]  # Return the first image path
        else:
            print("No images were generated")
            return "No image was generated”
    except Exception as e:
        print(f"Error during image generation: {str(e)}")
        if hasattr(e, '__dict__'):
            print(f"Error details: {e.__dict__}")
        return f"Error generating image: {str(e)}" 

generate_food_image() 函数使用 Mistral 的内置 image_generation 工具生成餐食的可视化。各部分作用如下:

  • 创建代理:新建一个代理,指示其生成逼真且诱人的食物图像。
  • 启动会话:发送提示,请其生成由下一餐代理给出的 meal_description 的图像。
  • 处理响应:检查响应中是否包含图像分片;若有,通过 Mistral 客户端的 files.download() 方法下载,并以时间戳文件名本地保存到 generated_images/ 目录。
  • 输出:返回第一个成功保存的图像路径;若失败则返回回退错误信息。

该工具为营养教练增添了视觉层,使餐食建议更具吸引力与真实感。

步骤 3:完整营养师流水线

至此,我们已构建了各个工具与代理能力,现在将它们整合为一个流水线。此步骤把以下环节粘合为一个可工作的助手:

  • 热量查询(通过网页或估算)
  • 记录(用户、餐食、热量、时间戳)
  • 推荐后续餐食
  • 用图像可视化餐食

以上各步通过按正确顺序调用前面文件中的函数来处理。该流水线代码位于 tools 文件夹外的 agent.py 文件。

# Pipeline logic file
from tools import estimate_calories, log_meal, suggest_next_meal, search_calories
from tools.image_gen import generate_food_image
from datetime import datetime
import time
def run_nutritionist_pipeline(username, meal_desc, dietary_preference):
    tools_used = set()    
    print(f"Searching for calories for: {meal_desc}")
    calories_text = search_calories(meal_desc)
    tools_used.add("Web Search")    
    # If web search fails, fall back to estimation
    if calories_text == 0:
        print("Web search failed, falling back to estimation...")
        time.sleep(1)  # Add delay to avoid rate limits
        calories_text = estimate_calories(meal_desc)
        tools_used.add("Calorie Estimation")   
    estimated_calories = calories_text
    print(f"Estimated calories: {estimated_calories}")   
    print(f"Logging meal for {username}...")
    time.sleep(1)  # Add delay to avoid rate limits
    log_response = log_meal(username, meal_desc, estimated_calories)
    tools_used.add("Meal Logging")    
    print("Generating next meal suggestion...")
    time.sleep(1)  
    suggestion = suggest_next_meal(estimated_calories, dietary_preference)
    tools_used.add("Next Meal Suggestion")    
    print("Generating image description for suggested meal...")
    time.sleep(1)  
    meal_image = generate_food_image(suggestion)
    tools_used.add("Image Description Generation")
    return {
        "logged": log_response,
        "next_meal_suggestion": suggestion,
        "meal_image": meal_image,
        "tools_used": sorted(list(tools_used))
    }

上述代码通过将多个代理工具串联为单个流水线,来协调完整的营养助手工作流。让我们更细致地拆解:

  • run_nutritionist_pipeline() 接收 username、meal_desc 与 dietary_preference 作为输入,驱动推荐流程。
  • 首先尝试通过 Mistral 的网页搜索连接器驱动的 search_calories() 获取餐食热量;若失败,则回退到使用轻量模型的 estimate_calories() 进行估算。
  • 随后通过 log_meal() 记录热量值,并附上时间戳与用户。
  • 基于摄入热量与饮食偏好,suggest_next_meal() 使用基于提示的推理推荐后续餐食。
  • 最后,generate_food_image() 使用 Mistral 的图像生成连接器生成该推荐菜肴的可视化。
  • 过程中使用 time.sleep(1) 在 API 调用间加入短暂停顿,以避免触发速率限制。
  • 函数返回包含记录确认、下一餐建议文本、生成图像路径以及本次交互中使用工具清单的字典。

该流水线将搜索、估算、记录、建议与可视化等多种能力结合为一次由 AI 驱动的营养体验。

步骤 4:用 Gradio 创建友好的用户界面

后端逻辑已完成,现在用 Gradio 打包为一个简洁、友好的前端。

# Main files
import gradio as gr
from agent import run_nutritionist_pipeline
import os
import re
def process_meal(username, meal_desc, dietary_preference):
    # Run the pipeline
    result = run_nutritionist_pipeline(username, meal_desc, dietary_preference)    
    # Extract calories from the logged meal response
    calories = "Not available"
    if result['logged']:
        calorie_match = re.search(r'(\d+)\s*calories', result['logged'], re.IGNORECASE)
        if calorie_match:
            calories = calorie_match.group(1)
        else:
            paren_match = re.search(r'\((\d+)\)', result['logged'])
            if paren_match:
                calories = paren_match.group(1)
            else:
                number_match = re.search(r'\b(\d+)\b', result['logged'])
                if number_match:
                    calories = number_match.group(1)    
    # Map tool names to Mistral connectors
    connector_map = {
        "Web Search": "Web Search",
        "Image Description Generation": "Image Generation",
        "Meal Logging": "Chat Completion",
        "Next Meal Suggestion": "Chat Completion"
    }   
    connectors_used = set()
    for tool in result['tools_used']:
        if tool in connector_map:
            connectors_used.add(connector_map[tool])    
    output = f"""
# Meal Analysis Results
## Meal Details
- **Meal Description:** {meal_desc}
- **Estimated Calories:** {calories}
## Next Meal Suggestion
{result['next_meal_suggestion']}

## Tools Used
{', '.join(result['tools_used'])}
## Mistral Connectors Used
{', '.join(sorted(connectors_used))}
""
    # Get the image path and check if it is valid
    image_path = result['meal_image']    
    if os.path.exists(image_path) and image_path.endswith('.png'):
        return output, image_path
    else:
        return output, None
# Create the Gradio interface
with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown("# 🍽️ Nutritionist Assistant")    
    with gr.Row():
        with gr.Column():
            username = gr.Textbox(label="Username", placeholder="Enter your name")
            meal_desc = gr.Textbox(label="Meal Description", placeholder="Describe your meal (e.g., 'Chicken salad with olive oil dressing')")
            dietary_preference = gr.Dropdown(
                choices=["vegetarian", "vegan", "Non-vegetarian", "gluten-free"],
                label="Dietary Preference",
                value="omnivore"
            )
            submit_btn = gr.Button("Process Meal", variant="primary")        
        with gr.Column():
            output = gr.Markdown(label="Results")
            image_output = gr.Image(label="Generated Meal Image", type="filepath")    
    submit_btn.click(
        fn=process_meal,
        inputs=[username, meal_desc, dietary_preference],
        outputs=[output, image_output]
    )
# Launch the app
if __name__ == "__main__":
    demo.launch() 

在上述代码片段中,我们为与营养师代理流水线交互搭建了一个完整的 Gradio 界面。其工作方式如下:

  • 首先从 agent.py 导入驱动核心代理逻辑的 run_nutritionist_pipeline() 函数。
  • 然后,process_meal() 函数作为流水线的包装器,接收 username、meal_desc 与 dietary_preference 作为用户输入,触发此前定义的多代理逻辑。
  • 在 process_meal() 内,会解析结果字典以提取餐食摘要、热量、下一餐建议与所用连接器。
  • 函数还会在返回用于显示前,检查生成的图像路径是否有效;若未找到图像,则仅返回文本结果。
  • Gradio 应用通过 gr.Blocks() 构建,布局分为两侧:一侧为输入字段与“Process Meal”按钮,另一侧为结果输出区域与下一餐图像预览。
  • submit_btn.click() 回调将前端按钮与 process_meal() 连接,传入输入并接收格式化的 Markdown 与图像输出。
  • 最后,当脚本以主模块运行时,通过 demo.launch() 启动应用。您可设置 debug = True 以启用调试模式。

要运行此演示,请在项目根目录打开终端并输入:

python app.py

项目的整体结构如下:

Mistral_Agent_API/
├── generated_images/ # Stores generated meal images
├── tools/
│   ├── configs.py              # API setup, tool schema, environment config
│   ├── image_gen.py            # Generates meal image  
│   ├── next.py                 # Calorie estimator, logger, and next meal 
│   └── web_search.py           # Mistral web_search connector to find calorie 
├── agent.py                    # Main pipeline connecting all tools
├── app.py                      # Gradio UI 
├── requirements.txt            # Project dependencies
├── .env                        # Environment variables 

您可以在这个 GitHub 仓库找到该项目的完整代码。

Nutritionist Assistant with mistral agents api

Nutritionist Assistant with mistral agents api

Nutritionist Assistant with mistral agents api

结语

在本教程中,我们使用 Mistral Agents API 构建了一个功能完整的 AI 营养教练。期间我们探索了:

  • Mistral 代理与原始 LLM 模型的区别
  • 如 web_search 与 image_generation 等连接器的作用
  • 在单一流水线中跨多个代理进行编排
  • 使用 Gradio 构建友好的前端

该项目展示了代理式工作流的力量:LLM 不再只是被动响应者,而是能推理、采取行动并协调任务的交互式主体。从记录餐食到提出健康替代方案,甚至生成图像,我们展示了如何将简单工具组合成强大的 AI 体验。

想进一步学习 AI 代理的使用,推荐以下动手教程:

Aashi Dutt

作者

Aashi Dutt

我是一名 Google Developers 机器学习(生成式 AI)领域的专家、Kaggle 三项专家,以及 Women Techmakers 大使,拥有 3 年以上的技术从业经验。2020 年我共同创办了一家健康科技初创公司,目前在佐治亚理工学院攻读计算机科学硕士,专攻机器学习。

主题