Lewati ke konten utama

Mistral Agents API: Panduan dengan Proyek Demo

Pelajari cara membangun agen AI menggunakan Agents API dari Mistral, dan jelajahi konsep kunci seperti penggunaan tool, konektor, handoff, dan lainnya.
· 12 mnt Baca

Jelajahi bersama AI

Mistral telah merilis Agents API, sebuah kerangka kerja yang mempermudah pengembangan agen AI cerdas dan otonom yang mampu menjalankan tugas kompleks bertahap. Ini melampaui model bahasa tradisional dengan mengintegrasikan penggunaan tool, memori persisten, dan kemampuan orkestrasi.

Dalam tutorial ini, saya akan memandu Anda menggunakan Mistral Agents API untuk membangun asisten cerdas yang mampu:

  • Menggunakan tool seperti penelusuran web, eksekusi kode, dan pembuatan gambar
  • Menyimpan memori sepanjang percakapan panjang untuk menjaga konteks
  • Mendelegasikan tugas di antara beberapa agen

Anda akan mempelajari konsep inti di balik kerangka kerja agentic Mistral, menjelajahi konektor bawaan dan fitur orkestrasi, serta membangun asisten multi-agen yang berfungsi.

Kami terus memperbarui pembaca tentang kabar terbaru AI melalui The Median, buletin gratis setiap Jumat yang merangkum kisah-kisah kunci pekan ini. Berlangganan dan tetap tajam hanya dalam beberapa menit setiap minggu:

Apa Itu Agents API dari Mistral?

Mistral Agents API adalah kerangka kerja yang memungkinkan model bahasa besar menjalankan aksi multi-langkah, menggunakan tool eksternal, dan mempertahankan memori sepanjang interaksi. Berbeda dengan chat API sederhana, ini memberdayakan agen AI untuk:

  • Mengakses web, mengeksekusi kode, membuat gambar, atau mengambil dokumen
  • Berkordinasi dengan agen lain melalui orkestrasi
  • Mempertahankan percakapan persisten dengan memori jangka panjang

Saat ini, hanya mistral-medium-latest (juga dikenal sebagai mistral-medium-2505) dan mistral-large-latest yang didukung, namun segera model baru mungkin akan didukung.

Penjelasan Konsep Inti

Sebelum masuk ke bagian praktik, ada baiknya meluruskan konsep inti dari Agents API.

diagram mistral agents api

Sumber: Mistral AI

Agen

Agen di Mistral adalah persona berbasis model yang ditingkatkan dengan instruksi yang telah ditentukan, akses tool, dan status percakapan:

  • Instruksi membimbing perilaku agen (misalnya, “Anda adalah pelatih gizi untuk pencatatan makan”).
  • Tool seperti web_search atau image_generation memungkinkan agen melakukan aksi di dunia nyata.
  • Memori memungkinkan agen melacak pesan sebelumnya dan keluaran tool di berbagai giliran, mendukung penalaran kontekstual.

Abstraksi ini mengubah model chat dasar menjadi asisten multi-fungsi yang dapat terlibat dalam alur kerja kompleks.

Percakapan 

Setiap interaksi antara pengguna dan agen adalah bagian dari percakapan, yang menyimpan:

  • Pesan sebelumnya dan respons asisten
  • Pemanggilan tool dan hasilnya
  • Metadata streaming untuk visibilitas tingkat token (opsional)

Percakapan persisten ini memungkinkan agen menjalankan tugas multi-giliran seperti perencanaan, revisi, atau belajar dari masukan sebelumnya.

Konektor dan dukungan tool kustom

Mistral memudahkan integrasi tool melalui:

  • Connectors: Tool yang telah terintegrasi seperti web_search, code_execution, image_generation, document_library yang siap pakai.
  • Tool MCP: Memungkinkan API kustom yang dihosting pengembang dan dapat dipanggil sebagai tool di dalam alur kerja agen.

Anggap konektor sebagai aplikasi bawaan, dan Tool MCP sebagai plugin yang Anda tulis. Keduanya memungkinkan agen mengakses kemampuan bawaan dan endpoint yang ditentukan pengembang untuk logika yang dipersonalisasi.

diagram mcp mistral agents api

Sumber: Mistral AI

Entri dan handoff

Mistral melacak semua tindakan dalam percakapan sebagai “Entri” terstruktur, yang memungkinkan ketertelusuran dan kontrol atas pertukaran pesan serta eksekusi tool.

Agent handoff adalah saat satu agen mendelegasikan kendali ke agen lain untuk memodularisasi alur kerja.

handoff agen mistral

Sumber: Mistral AI

Arsitektur orkestrasi ini memudahkan menyusun dan mengelola sistem multi-agen yang kompleks tanpa kehilangan transparansi atau kontrol.

Menyiapkan Mistral API

Mari mulai menyiapkan Mistral. Kita akan mulai dengan membuat API key untuk proyek. Berikut langkah yang perlu diikuti:

  1. Untuk memulai, buat akun Mistral atau masuk di console.mistral.ai.

Dasbor Mistral

  1. Kemudian, buka Workspace Settings (panah dropdown dekat nama Anda—pojok kiri atas) dan klik Billing untuk menambahkan informasi pembayaran serta mengaktifkan pembayaran di akun Anda.

Penagihan Mistral

  1. Klik Add credits dan isi informasi penagihan Anda pada formulir. Lalu, isi jumlah kredit yang diinginkan. Catatan: Anda perlu menambahkan minimal 10 kredit.

Kredit Mistral

  1. Kemudian, pada tab sisi kiri, klik API keys dan buat API key baru dengan mengeklik Create new key. Pastikan menyalin API key tersebut, simpan dengan aman, dan jangan bagikan kepada siapa pun.

Sekarang Anda memiliki API key yang valid untuk berinteraksi dengan model Mistral dan membangun agen cerdas.

Gambaran Proyek: Pelatih Gizi dengan Mistral Agents

Dalam proyek ini, kita akan membangun Pelatih Gizi berbasis AI menggunakan Agents API dari Mistral. Alur pengguna sebagai berikut:

  1. Pengguna mengirimkan makanan yang baru saja dimakan (mis., "salad ayam dengan saus minyak zaitun").
  2. Agen penelusuran web menggunakan konektor bawaan untuk memperkirakan kalori makanan tersebut.
  3. Agen pencatat mencatat entri ini atas nama pengguna beserta stempel waktu.
  4. Terakhir, agen pembuatan gambar menyarankan makanan lanjutan yang sehat, mengembalikan gambar beserta deskripsi dan resepnya.

Untuk menyediakan antarmuka web tempat pengguna dapat berinteraksi dengan ahli gizi, kita akan menggunakan Gradio.

Langkah 1: Prasyarat

Sebelum mulai, pastikan Anda telah memasang hal-hal berikut:

  • Python 3.8+
  • Semua paket yang diperlukan dalam requirements.txt
python-dotenv==1.1.0
mistralai==0.0.7
typing-extensions==4.12.2
requests==2.31.0
gradio==4.34.0

Selain itu, siapkan berkas .env yang berisi Mistral API key Anda. Pendekatan ini menjaga keamanan API key dan memungkinkan anggota tim atau lingkungan deployment yang berbeda menggunakan kredensial berbeda tanpa mengubah kode sumber.

MISTRAL_API_KEY=YOUR_API_KEY

Catatan: Disarankan memasang dependensi ini di dalam lingkungan terisolasi seperti conda, venv, atau uv untuk menghindari konflik versi dengan proyek Python lain.

Berikut perintah untuk menyiapkan berbagai lingkungan:

Menggunakan venv

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

Menggunakan Conda

conda create -n mistral_env python=3.10
conda activate mistral_env

Menggunakan uv

Jika Anda belum memiliki uv:

pip install uv

Lalu:

uv venv mistral_env
source mistral_env/bin/activate

Untuk memasang semua dependensi yang disebutkan di atas, jalankan kode berikut di terminal Anda:

pip install -r requirements.txt

Catatan: Jika Anda mengalami error terkait mistralai saat menggunakan agen atau konektor apa pun, jalankan kode berikut:

pip install –upgrade mistralai

Ini akan meningkatkan pustaka mistralai ke versi terbaru.

Langkah 2: Menyiapkan Mistral Tools

Pada bagian ini, kita akan menyiapkan tool dan client untuk berinteraksi dengan Mistral Agents API. Kita akan mendefinisikan skema tool, menginisialisasi client, dan memverifikasi autentikasi. Tool ini nantinya dirujuk saat menyiapkan agen spesifik seperti pengestimasi kalori atau pembuat gambar.

Langkah 2.1: Registri tool dan inisialisasi

Pertama, kita mendefinisikan skema tool, pemilihan model, dan instansiasi client. Lalu, kita membangun metode pembantu seperti create_chat_completion() dan check_client(). Kode berikut masuk ke berkas configs.py di dalam folder tools:

#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"]
        }
    }
}

Kita mulai dengan mengimpor dotenv untuk memuat variabel sensitif seperti Mistral API key dari berkas .env lokal ke environment Python. Ini menjaga kredensial tetap aman dan tidak berada di kode sumber. Kemudian, kita memilih model default mistral-large-latest dan membuat client Mistral menggunakan API key.

Selanjutnya, kita mendefinisikan spesifikasi tool internal (skema) menggunakan format JSON Schema. Ini membantu untuk:

  • Menyimulasikan perilaku tool MCP (meski tidak didaftarkan melalui pustaka McpTool)
  • Mendeskripsikan input yang diharapkan seperti "username", "meal", dan "calories"
  • Membantu memastikan pemformatan input konsisten di seluruh modul

Sekarang, mari tambahkan metode pembantu yang membuat chat completion, mendaftarkan tool, agen, dan menginisialisasi client.

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()

Fungsi create_chat_completion() membungkus pemanggilan metode client.chat.complete(), yang merupakan bagian dari SDK client Mistral, untuk mengirim pesan ke model.

  • Ini memformat ulang pesan dict mentah menjadi objek UserMessage dan SystemMessage yang diperlukan SDK Mistral.
  • Juga berguna untuk standarisasi completion di seluruh aplikasi.

Fungsi register_tools() dan register_agents() membantu selama pengembangan lokal dengan mencatat tool dan agen mana yang aktif dalam sistem. Sementara itu, fungsi check_client() dan is_client_initialized() memastikan client Mistral telah diinstansiasi dengan benar dan API key tersedia, membantu menghindari error saat runtime ketika agen dieksekusi.

Langkah 2.2: Mengestimasi kalori dengan agen penelusuran web

Setelah kita menginisialisasi tool dasar dan client, mari membangun Agen Penelusuran Web Gizi khusus. Agen ini menggunakan konektor web_search dari Mistral untuk mencari estimasi kalori makanan secara real-time. Kode ini berada di berkas web_search.py di dalam folder tools.

# 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

Pada kode di atas, fungsi search_calories() menggunakan tool konektor bawaan untuk penelusuran web dari Mistral Agents API, yang memungkinkan agen melakukan kueri web langsung seperti estimasi kalori, mengatasi keterbatasan pelatihan model statis. Cara kerjanya:

  1. Pembuatan agen: Pertama, membuat “Nutrition Search Agent” menggunakan model mistral-medium-latest, yang dilengkapi tool web_search dan diinstruksikan untuk hanya mengembalikan kalori.
  2. Eksekusi kueri: Agen kemudian digunakan untuk memulai percakapan dengan pertanyaan tentang total kalori dalam deskripsi makanan yang diberikan.
  3. Penguraian respons: Respons dari agen diurai menggunakan regular expression untuk mengekstrak nilai numerik pertama (yang seharusnya jumlah kalori).
  4. Fallback: Jika tidak ada angka valid yang ditemukan atau terjadi error, fungsi mencatat masalah dan mengembalikan nol sebagai cadangan.

Tanpa web_search, kebanyakan model tidak dapat menjawab pertanyaan tentang peristiwa terbaru atau makanan khusus domain yang tidak pernah dilihat saat pelatihan. Dengan itu, kita dapat menanyakan informasi nutrisi, menu restoran, atau artikel berita secara real time.

Ada dua varian penelusuran web:

  • web_search: Konektor mesin telusur ringan serbaguna (digunakan di proyek ini).
  • web_search_premium: Versi yang ditingkatkan dengan verifikasi penyedia berita dan pengumpulan konteks lebih luas.

Selanjutnya, kita akan menjelajahi estimasi kalori fallback menggunakan logika berbasis prompt saja.

Langkah 2.3: Estimasi, pencatatan, dan saran makanan

Pada bagian ini, kita mengimplementasikan tiga fungsi esensial yang bertindak sebagai fallback atau peningkatan. Kode berikut berada di dalam berkas next.py di folder tools.

#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."

Skrip ini mendefinisikan fungsi backend inti yang menggerakkan alur kerja gizi kita (dari estimasi kalori hingga perencanaan makanan lanjutan). Fungsi-fungsi ini menggunakan model Mistral yang ringan dan chat completion standar, tanpa memerlukan pembuatan agen atau konektor ketika penelusuran web tidak tersedia, atau untuk menghindari error batas laju. Berikut tugas tiap fungsi:

  1. estimate_calories(): Fungsi ini digunakan sebagai fallback jika konektor web_search gagal atau tidak tersedia.
    1. Ini mengirim pesan sistem yang berisi peran asisten sebagai ahli gizi beserta prompt pengguna yang mencakup makanan yang ingin dicatat.
    2. Model digunakan dengan temperature=0.1 yang rendah untuk keluaran deterministik. Artinya, model akan menghasilkan respons yang konsisten dan dapat diulang untuk input yang sama—cocok untuk tugas seperti estimasi kalori dan pencatatan, di mana keluaran stabil dan faktual lebih diutamakan daripada variasi kreatif.
    3. Ini mengekstrak angka pertama (menggunakan regex) dari respons model.
  2. log_meal(): Fungsi ini mencatat makanan pengguna, termasuk stempel waktu.
    1. Menggunakan chat completion dengan instruksi dan mengembalikan pesan konfirmasi terformat dari asisten.
    2. Memungkinkan pencatatan internal yang ringan tanpa membutuhkan basis data backend khusus.
  3. suggest_next_meal(): Fungsi ini merekomendasikan makanan berikutnya berdasarkan asupan kalori sebelumnya dan profil diet pengguna.
    1. Model dipanggil dengan temperature=0.7 untuk mendorong saran yang lebih kreatif.
    2. Respons lalu dibersihkan dan dikembalikan sebagai ide makanan berikutnya.

Bersama-sama, fungsi ini memungkinkan estimasi kalori, konfirmasi pencatatan, dan rekomendasi sehat tanpa perlu API eksternal. Pada langkah berikutnya, kita akan memvisualisasikan saran makanan dengan konektor pembuatan gambar Mistral.

Langkah 2.4: Membuat visual dengan konektor pembuatan gambar

Sekarang mari tambahkan lapisan visual ke asisten kita. Pada langkah ini, kita akan menggunakan konektor bawaan image_generation dari Mistral untuk menghasilkan gambar menggugah selera dari makanan yang disarankan berikutnya.

#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)}" 

Fungsi generate_food_image() menghasilkan representasi visual suatu makanan menggunakan tool bawaan image_generation dari Mistral. Berikut fungsi tiap bagiannya:

  • Pembuatan agen: Agen baru diinstruksikan untuk membuat visual makanan yang realistis dan menggugah selera.
  • Memulai percakapan: Prompt dikirim untuk meminta agen membuat gambar dari meal_description yang dihasilkan oleh agen makanan berikutnya.
  • Penanganan respons: Fungsi memeriksa apakah respons berisi potongan gambar. Jika ya, ia mengunduh setiap gambar melalui metode files.download() milik client Mistral. Gambar disimpan secara lokal di folder generated_images/ dengan nama berkas bertanda waktu.
  • Keluaran: Mengembalikan path ke gambar pertama yang berhasil disimpan, atau pesan error fallback jika pembuatan gagal.

Tool ini menambahkan lapisan visual ke pelatih gizi kita, membuat saran makanan lebih menarik dan realistis.

Langkah 3: Pipeline Ahli Gizi Lengkap

Setelah kita membangun tool dan kemampuan agen secara terpisah, saatnya menggabungkannya ke dalam satu pipeline. Langkah ini menyatukan semuanya menjadi asisten yang berfungsi untuk menangani:

  • Pencarian kalori (melalui web atau estimasi)
  • Pencatatan (pengguna, makanan, kalori, stempel waktu)
  • Memberi saran makanan lanjutan
  • Memvisualisasikan makanan dengan gambar

Semua langkah ini ditangani dengan memanggil masing-masing fungsi dari berkas sebelumnya dalam urutan yang tepat. Kode untuk pipeline ini berada di luar folder tools dalam berkas 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))
    }

Kode di atas mengoordinasikan seluruh alur kerja asisten gizi dengan merangkai beberapa tool agen ke dalam satu pipeline. Mari uraikan lebih detail:

  • Fungsi run_nutritionist_pipeline() menerima username, meal_desc, dan dietary_preference sebagai input untuk menggerakkan proses rekomendasi.
  • Pertama, ia mencoba menentukan kandungan kalori makanan menggunakan fungsi search_calories() yang didukung konektor penelusuran web Mistral. Jika gagal, ia menggunakan estimasi dengan model ringan melalui estimate_calories().
  • Nilai kalori yang didapat kemudian dicatat menggunakan fungsi log_meal(), yang memberi tag entri dengan stempel waktu dan mengaitkannya dengan pengguna.
  • Berdasarkan kalori yang dikonsumsi dan preferensi diet, fungsi suggest_next_meal() menyarankan makanan lanjutan menggunakan penalaran berbasis prompt.
  • Terakhir, fungsi generate_food_image() menggunakan konektor pembuatan gambar Mistral untuk menghasilkan representasi visual hidangan yang direkomendasikan.
  • Sepanjang proses, time.sleep(1) digunakan untuk memberi jeda singkat antar permintaan guna menghindari pemicu batas laju saat panggilan API.
  • Fungsi mengembalikan dictionary yang berisi konfirmasi pencatatan makanan, teks saran makanan berikutnya, path gambar yang dihasilkan, dan daftar tool yang digunakan dalam interaksi ini.

Pipeline ini menggabungkan berbagai kemampuan seperti penelusuran, estimasi, pencatatan, saran, dan visualisasi menjadi pengalaman gizi berbasis AI.

Langkah 4: Membuat Antarmuka Ramah Pengguna dengan Gradio

Setelah logika backend selesai, mari bungkus menjadi frontend yang rapi dan ramah pengguna menggunakan 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() 

Pada cuplikan kode di atas, kita menyiapkan antarmuka UI Gradio lengkap untuk berinteraksi dengan pipeline Agen Ahli Gizi. Cara kerjanya:

  • Kita mulai dengan mengimpor fungsi run_nutritionist_pipeline() dari agent.py, yang menggerakkan logika inti agen.
  • Kemudian, fungsi process_meal() bertindak sebagai pembungkus pipeline agen, yang menerima username, meal_desc, dan dietary_preference sebagai input pengguna dan memicu logika multi-agen yang telah didefinisikan.
  • Di dalam fungsi process_meal(), dictionary hasil diurai untuk mengekstrak ringkasan makanan, kalori, saran makanan berikutnya, dan konektor yang digunakan.
  • Fungsi juga memeriksa apakah path gambar yang dihasilkan valid sebelum mengembalikannya untuk ditampilkan. Jika gambar tidak ditemukan, maka hanya hasil tekstual yang dikembalikan.
  • Aplikasi Gradio dibangun menggunakan gr.Blocks() dan tata letaknya mencakup dua sisi, satu dengan kolom input dan tombol Process Meal. Sisi lainnya berisi area keluaran untuk hasil analisis makanan dan pratinjau gambar makanan berikutnya.
  • Callback submit_btn.click() menghubungkan tombol frontend untuk memicu fungsi process_meal(), meneruskan input dan menerima keluaran markdown terformat serta gambar.
  • Terakhir, aplikasi diluncurkan melalui demo.launch() jika skrip dijalankan sebagai modul utama. Anda dapat menetapkan debug = True untuk mengaktifkan mode debugging aplikasi.

Untuk menjalankan demo ini, buka terminal di direktori root Anda dan ketik perintah berikut:

python app.py

Struktur keseluruhan proyek ini akan terlihat seperti ini:

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 

Anda dapat menemukan kode lengkap untuk proyek ini di repo GitHub ini.

Asisten Ahli Gizi dengan mistral agents api

Asisten Ahli Gizi dengan mistral agents api

Asisten Ahli Gizi dengan mistral agents api

Kesimpulan

Dalam tutorial ini, kita membangun Pelatih Gizi AI yang sepenuhnya fungsional menggunakan Mistral Agents API. Sepanjang jalan, kita mengeksplorasi:

  • Bagaimana agen Mistral berbeda dari model LLM mentah
  • Peran konektor seperti web_search dan image_generation
  • Orkestrasi di berbagai agen dalam satu pipeline
  • Membangun frontend yang ramah pengguna dengan Gradio

Proyek ini menunjukkan kekuatan alur kerja agentic di mana LLM tidak hanya merespons secara pasif, tetapi entitas interaktif yang bernalar, bertindak, dan mengoordinasikan tugas. Dari mencatat makanan hingga menyarankan alternatif yang sehat dan bahkan menghasilkan gambar, kita menunjukkan cara menggabungkan tool sederhana menjadi pengalaman AI yang kuat.

Untuk mempelajari lebih lanjut tentang penggunaan agen AI, saya merekomendasikan tutorial praktis berikut:

Aashi Dutt

Penulis

Aashi Dutt

Saya adalah Google Developers Expert di ML (Gen AI), Kaggle 3x Expert, dan Women Techmakers Ambassador dengan pengalaman lebih dari 3 tahun di bidang teknologi. Saya ikut mendirikan startup health-tech pada 2020 dan sedang menempuh studi magister ilmu komputer di Georgia Tech dengan spesialisasi machine learning.

Topik

Terkait

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

blogs

Spaghetti Plot dan Jalur Badai