Khóa học
Mistral đã phát hành Agents API, một khung giúp phát triển các tác tử AI thông minh, tự chủ có khả năng thực hiện các tác vụ phức tạp nhiều bước. Nó mở rộng vượt ra ngoài các mô hình ngôn ngữ truyền thống bằng cách tích hợp khả năng dùng công cụ, bộ nhớ bền và điều phối.
Trong hướng dẫn này, tôi sẽ hướng dẫn bạn cách sử dụng Mistral Agents API để xây dựng trợ lý thông minh có khả năng:
- Sử dụng các công cụ như tìm kiếm web, thực thi mã và tạo ảnh
- Duy trì bộ nhớ xuyên suốt các cuộc trò chuyện dài để giữ ngữ cảnh
- Phân công nhiệm vụ giữa nhiều tác tử
Bạn sẽ học các khái niệm cốt lõi đằng sau khung agentic của Mistral, khám phá các connector và tính năng điều phối tích hợp sẵn, và xây dựng một trợ lý đa tác tử hoạt động thực tế.
Chúng tôi cập nhật cho độc giả những điều mới nhất về AI qua The Median, bản tin miễn phí thứ Sáu tóm lược các câu chuyện nổi bật trong tuần. Đăng ký để luôn sắc bén chỉ với vài phút mỗi tuần:
Agents API của Mistral là gì?
Mistral Agents API là một khung cho phép các mô hình ngôn ngữ lớn thực hiện hành động nhiều bước, sử dụng công cụ bên ngoài và duy trì bộ nhớ xuyên suốt các tương tác. Không giống các chat API đơn giản, nó trao quyền cho tác tử AI để:
- Truy cập web, thực thi mã, tạo ảnh hoặc truy xuất tài liệu
- Phối hợp với các tác tử khác thông qua điều phối
- Duy trì hội thoại bền vững với bộ nhớ dài hạn
Hiện tại, chỉ mistral-medium-latest (hay còn gọi là mistral-medium-2505) và mistral-large-latest được hỗ trợ, nhưng sắp tới có thể sẽ có thêm các mô hình mới.
Giải thích các khái niệm cốt lõi
Trước khi thực hành, tôi cho rằng nên làm rõ các khái niệm cốt lõi của Agents API.

Nguồn: Mistral AI
Tác tử (Agents)
Agents trong Mistral là các persona vận hành bởi mô hình, được tăng cường bằng hướng dẫn định sẵn, quyền truy cập công cụ và trạng thái hội thoại:
- Hướng dẫn định hướng hành vi của tác tử (ví dụ: “Bạn là huấn luyện viên dinh dưỡng ghi nhật ký bữa ăn”).
- Các công cụ như
web_searchhoặcimage_generationcho phép tác tử thực hiện hành động thực tế. - Bộ nhớ giúp tác tử theo dõi tin nhắn trước đó và đầu ra công cụ qua nhiều lượt, hỗ trợ suy luận theo ngữ cảnh.
Sự trừu tượng này biến một mô hình chat cơ bản thành trợ lý đa chức năng có thể tham gia các quy trình công việc phức tạp.
Hội thoại
Mỗi tương tác giữa người dùng và tác tử là một phần của một cuộc hội thoại, lưu trữ:
- Các tin nhắn trước đó và phản hồi của trợ lý
- Lời gọi công cụ và kết quả
- Siêu dữ liệu streaming để quan sát ở cấp độ token (tùy chọn)
Các hội thoại bền vững này cho phép tác tử thực hiện nhiệm vụ đa lượt như lập kế hoạch, chỉnh sửa hay học từ đầu vào trước đó.
Connectors và hỗ trợ công cụ tùy chỉnh
Mistral cho phép tích hợp công cụ dễ dàng thông qua:
- Connectors: Các công cụ tích hợp sẵn như
web_search,code_execution,image_generation,document_libraryhoạt động ngay lập tức. - Công cụ MCP: Cho phép các API tùy chỉnh do nhà phát triển triển khai, có thể được gọi như công cụ trong luồng tác tử.
Hãy xem connectors như các ứng dụng tích hợp sẵn, còn MCP Tools như các plugin bạn tự viết. Kết hợp lại, chúng cho phép tác tử truy cập cả năng lực tích hợp sẵn và các endpoint do nhà phát triển định nghĩa cho logic cá nhân hóa.

Nguồn: Mistral AI
Entries và handoff
Mistral theo dõi mọi hành động trong một cuộc hội thoại dưới dạng “Entry” có cấu trúc, cho phép truy vết và kiểm soát trao đổi tin nhắn cũng như việc thực thi công cụ.
Các handoff giữa tác tử là khi một tác tử chuyển giao quyền kiểm soát cho tác tử khác để mô-đun hóa quy trình công việc.

Nguồn: Mistral AI
Kiến trúc điều phối này giúp dễ dàng cấu thành và quản lý các hệ thống đa tác tử phức tạp mà không mất đi tính minh bạch hay kiểm soát.
Thiết lập Mistral API
Bắt đầu thiết lập Mistral. Chúng ta sẽ tạo API key cho dự án. Làm theo các bước sau:
- Trước tiên, tạo tài khoản Mistral hoặc đăng nhập tại console.mistral.ai.

- Sau đó, đi tới Workspace Settings (mũi tên thả xuống gần tên của bạn—góc trên bên trái) và nhấp Billing để thêm thông tin thanh toán và kích hoạt thanh toán cho tài khoản.

- Nhấp Add credits và điền thông tin thanh toán vào biểu mẫu. Sau đó nhập số credit bạn muốn. Lưu ý: Bạn cần nạp tối thiểu 10 credit.

- Sau đó, ở thanh bên trái, nhấp API keys và tạo API key mới bằng cách nhấn Create new key. Hãy sao chép API key, lưu trữ an toàn và không chia sẻ với bất kỳ ai.
Giờ bạn đã có API key hợp lệ để tương tác với các mô hình Mistral và xây dựng tác tử thông minh.
Tổng quan dự án: Huấn luyện viên dinh dưỡng với Mistral Agents
Trong dự án này, chúng ta sẽ xây dựng Huấn luyện viên Dinh dưỡng dùng AI với Agents API của Mistral. Luồng người dùng như sau:
- Người dùng gửi bữa ăn vừa dùng (ví dụ, "salad gà với sốt dầu ô-liu").
- Một tác tử tìm kiếm web dùng connector tích hợp để ước tính calo cho bữa ăn.
- Một tác tử ghi nhật ký lưu lại mục này theo tên người dùng và dấu thời gian.
- Cuối cùng, một tác tử tạo ảnh gợi ý bữa ăn tiếp theo lành mạnh, trả về cả ảnh và mô tả cùng công thức.
Để cung cấp giao diện web cho người dùng tương tác với chuyên gia dinh dưỡng, chúng ta sẽ dùng Gradio.
Bước 1: Điều kiện tiên quyết
Trước khi bắt đầu, hãy đảm bảo bạn đã cài đặt:
- Python 3.8+
- Tất cả gói cần thiết trong
requirements.txt
python-dotenv==1.1.0
mistralai==0.0.7
typing-extensions==4.12.2
requests==2.31.0
gradio==4.34.0
Ngoài ra, hãy tạo tệp .env chứa Mistral API key của bạn. Cách này giữ an toàn cho API key và cho phép thành viên nhóm hoặc môi trường triển khai khác nhau dùng thông tin xác thực riêng mà không cần sửa mã nguồn.
MISTRAL_API_KEY=YOUR_API_KEY
Lưu ý: Khuyến nghị cài đặt các phụ thuộc trong môi trường tách biệt như conda, venv, hoặc uv để tránh xung đột phiên bản với các dự án Python khác.
Dưới đây là các lệnh thiết lập những môi trường khác nhau:
Dùng venv
python -m venv mistral_env
source mistral_env/bin/activate # On Windows: mistral_env\Scripts\activate
Dùng Conda
conda create -n mistral_env python=3.10
conda activate mistral_env
Dùng uv
Nếu bạn chưa có uv:
pip install uv
Sau đó:
uv venv mistral_env
source mistral_env/bin/activate
Để cài tất cả phụ thuộc nêu trên, chạy đoạn mã sau trong terminal:
pip install -r requirements.txt
Lưu ý: Nếu gặp lỗi liên quan đến mistralai khi dùng bất kỳ tác tử hoặc connector nào, hãy chạy lệnh sau:
pip install –upgrade mistralai
Lệnh này sẽ nâng cấp thư viện mistralai lên phiên bản mới nhất.
Bước 2: Thiết lập công cụ Mistral
Trong phần này, chúng ta sẽ chuẩn bị công cụ và thiết lập client để tương tác với Mistral Agents API. Chúng ta sẽ định nghĩa schema cho công cụ, khởi tạo client và xác minh xác thực. Các công cụ này sau đó sẽ được tham chiếu khi thiết lập các tác tử cụ thể như bộ ước tính calo hoặc bộ tạo ảnh.
Bước 2.1: Đăng ký và khởi tạo công cụ
Đầu tiên, chúng ta định nghĩa schema công cụ, chọn mô hình và khởi tạo client. Sau đó, xây dựng các hàm trợ giúp như create_chat_completion() và check_client(). Mã sau nằm trong tệp configs.py bên trong thư mục 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"]
}
}
}
Chúng ta bắt đầu bằng cách nhập dotenv để nạp các biến nhạy cảm như Mistral API key từ tệp .env cục bộ vào môi trường Python. Cách này giữ thông tin xác thực an toàn và ngoài mã nguồn. Sau đó, chọn mô hình mặc định mistral-large-latest và khởi tạo client Mistral bằng API key.
Tiếp theo, chúng ta định nghĩa đặc tả công cụ nội bộ (schema) theo định dạng JSON schema. Chúng hữu ích cho:
- Mô phỏng hành vi công cụ MCP (dù không đăng ký qua thư viện McpTool)
- Mô tả các đầu vào kỳ vọng như "username", "meal" và "calories"
- Giúp đảm bảo định dạng đầu vào nhất quán giữa các mô-đun
Giờ hãy thêm các hàm trợ giúp để tạo chat completion, đăng ký công cụ, tác tử và khởi tạo 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()
Hàm create_chat_completion() bao bọc lời gọi client.chat.complete() thuộc Mistral client SDK để gửi tin nhắn tới mô hình.
- Nó chuyển đổi các tin nhắn dạng dict thô thành đối tượng
UserMessagevàSystemMessagemà SDK Mistral yêu cầu. - Nó cũng hữu ích để tiêu chuẩn hóa các completion trên toàn ứng dụng.
Các hàm register_tools() và register_agents() hỗ trợ trong quá trình phát triển cục bộ bằng cách ghi log công cụ và tác tử đang hoạt động. Trong khi đó, check_client() và is_client_initialized() đảm bảo client Mistral đã được khởi tạo đúng và API key có sẵn, giúp tránh lỗi runtime khi thực thi tác tử.
Bước 2.2: Ước tính calo bằng tác tử tìm kiếm web
Sau khi đã khởi tạo công cụ và client nền tảng, hãy xây dựng một Nutrition Web Search Agent chuyên biệt. Tác tử này dùng connector web_search của Mistral để tra cứu ước tính calo cho bữa ăn theo thời gian thực. Mã nằm trong tệp web_search.py trong thư mục 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
Trong đoạn mã trên, hàm search_calories() sử dụng công cụ connector tìm kiếm web tích hợp sẵn từ Mistral Agents API, cho phép tác tử thực hiện truy vấn web trực tiếp như ước tính calo, khắc phục hạn chế của dữ liệu huấn luyện tĩnh. Cách hoạt động như sau:
- Tạo tác tử: Trước hết tạo “Nutrition Search Agent” dùng mô hình
mistral-medium-latest, được trang bị công cụweb_searchvà được hướng dẫn chỉ trả về giá trị calo. - Thực thi truy vấn: Sau đó dùng tác tử để bắt đầu hội thoại, yêu cầu tổng calo của mô tả bữa ăn đã cung cấp.
- Phân tích phản hồi: Phản hồi từ tác tử được phân tích bằng biểu thức chính quy để trích xuất giá trị số đầu tiên (được hiểu là lượng calo).
- Dự phòng: Nếu không tìm được số hợp lệ hoặc xảy ra lỗi, hàm ghi lại vấn đề và trả về 0 như phương án dự phòng.
Không có web_search, hầu hết mô hình không thể trả lời câu hỏi về sự kiện gần đây hoặc các bữa ăn chuyên biệt không có trong dữ liệu huấn luyện. Với công cụ này, chúng ta có thể truy vấn thông tin dinh dưỡng, thực đơn nhà hàng hoặc bài báo theo thời gian thực.
Có hai biến thể tìm kiếm web:
web_search: Connector công cụ tìm kiếm nhẹ, dùng chung (được dùng trong dự án).web_search_premium: Bản nâng cao có xác minh nhà cung cấp tin tức và phạm vi ngữ cảnh rộng hơn.
Tiếp theo, chúng ta sẽ xem xét ước tính calo dự phòng chỉ bằng prompt.
Bước 2.3: Ước tính, ghi nhật ký và gợi ý bữa ăn
Trong phần này, chúng ta triển khai ba hàm thiết yếu đóng vai trò dự phòng hoặc tăng cường. Mã nằm trong tệp next.py trong thư mục 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."
Tập lệnh này định nghĩa các hàm backend cốt lõi cung cấp năng lực cho quy trình dinh dưỡng (từ ước tính calo đến lập kế hoạch bữa tiếp theo). Các hàm này dùng các mô hình Mistral nhẹ và chat completion tiêu chuẩn, không cần tạo tác tử hay dùng connector khi không có tìm kiếm web, hoặc để tránh lỗi giới hạn tốc độ. Mỗi hàm thực hiện như sau:
estimate_calories(): Hàm này dùng làm dự phòng nếu connectorweb_searchlỗi hoặc không khả dụng.- Nó gửi system message mô tả vai trò trợ lý là chuyên gia dinh dưỡng cùng prompt của người dùng gồm bữa ăn muốn ghi.
- Mô hình được dùng với
temperature=0.1thấp để ra kết quả xác định. Điều này giúp mô hình tạo phản hồi nhất quán, lặp lại cho cùng đầu vào trong các tác vụ như ước tính và ghi nhật ký, nơi ưu tiên độ ổn định và tính thực tế hơn là sáng tạo. - Nó trích số đầu tiên (bằng regex) từ phản hồi của mô hình.
log_meal(): Hàm này ghi nhật ký bữa ăn của người dùng, bao gồm dấu thời gian.- Nó dùng chat completion với hướng dẫn và trả về thông điệp xác nhận đã định dạng của trợ lý.
- Điều này cho phép ghi nhật ký nội bộ gọn nhẹ mà không cần cơ sở dữ liệu backend riêng.
suggest_next_meal(): Hàm này gợi ý bữa tiếp theo dựa trên lượng calo đã dùng và hồ sơ khẩu phần của người dùng.- Gọi mô hình với
temperature=0.7để khuyến khích gợi ý sáng tạo hơn. - Phản hồi sau đó được cắt gọn và trả về như ý tưởng bữa ăn tiếp theo.
Kết hợp lại, các hàm này cho phép ước tính calo, xác nhận ghi nhật ký và khuyến nghị lành mạnh mà không cần API bên ngoài. Ở bước tiếp theo, chúng ta sẽ trực quan hóa gợi ý món ăn bằng connector tạo ảnh của Mistral.
Bước 2.4: Tạo hình ảnh bằng connector tạo ảnh
Giờ hãy thêm lớp trực quan cho trợ lý. Ở bước này, chúng ta sẽ dùng connector image_generation tích hợp sẵn của Mistral để tạo một bức ảnh hấp dẫn về bữa ăn được gợi ý tiếp theo.
#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)}"
Hàm generate_food_image() tạo hình ảnh minh họa cho món ăn bằng công cụ image_generation tích hợp của Mistral. Cụ thể từng phần:
- Tạo tác tử: Tạo tác tử mới với hướng dẫn tạo hình ảnh món ăn chân thực và hấp dẫn.
- Bắt đầu hội thoại: Gửi prompt yêu cầu tác tử tạo ảnh cho
meal_descriptiondo tác tử gợi ý bữa tiếp theo sinh ra. - Xử lý phản hồi: Hàm kiểm tra phản hồi có chứa các mảnh ảnh không. Nếu có, tải xuống từng ảnh qua phương thức
files.download()của Mistral client. Ảnh được lưu cục bộ trong thư mụcgenerated_images/với tên kèm mốc thời gian. - Đầu ra: Trả về đường dẫn đến ảnh đầu tiên lưu thành công, hoặc thông báo lỗi dự phòng nếu thất bại.
Công cụ này thêm lớp trực quan cho huấn luyện viên dinh dưỡng, khiến gợi ý món ăn hấp dẫn và chân thực hơn.
Bước 3: Quy trình đầy đủ của chuyên gia dinh dưỡng
Sau khi xây dựng từng công cụ và năng lực của tác tử, giờ là lúc đưa chúng vào một pipeline thống nhất. Bước này kết nối mọi thứ thành một trợ lý hoạt động xử lý:
- Tra cứu calo (qua web hoặc ước tính)
- Ghi nhật ký (người dùng, bữa ăn, calo, thời gian)
- Gợi ý bữa ăn tiếp theo
- Trực quan hóa món ăn bằng ảnh
Tất cả bước này được xử lý bằng cách gọi từng hàm từ các tệp trước theo đúng thứ tự. Mã pipeline nằm ngoài thư mục tools trong tệp 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))
}
Đoạn mã trên điều phối toàn bộ quy trình của trợ lý dinh dưỡng bằng cách xâu chuỗi nhiều công cụ tác tử vào một pipeline duy nhất. Cụ thể:
- Hàm
run_nutritionist_pipeline()nhậnusername,meal_descvàdietary_preferencelàm đầu vào để dẫn dắt quá trình gợi ý. - Đầu tiên, nó tìm lượng calo của bữa ăn bằng
search_calories()sử dụng connector tìm kiếm web của Mistral. Nếu thất bại, nó chuyển sang ước tính bằng mô hình nhẹ quaestimate_calories(). - Giá trị calo thu được sau đó được ghi lại bằng
log_meal(), gắn dấu thời gian và liên kết với người dùng. - Dựa trên lượng calo đã dùng và khẩu phần,
suggest_next_meal()gợi ý bữa tiếp theo bằng suy luận dựa trên prompt. - Cuối cùng,
generate_food_image()dùng connector tạo ảnh của Mistral để tạo hình minh họa cho món được khuyến nghị. - Xuyên suốt quá trình,
time.sleep(1)được dùng để chèn khoảng nghỉ ngắn giữa các yêu cầu nhằm tránh giới hạn tốc độ khi gọi API. - Hàm trả về một dictionary chứa xác nhận ghi nhật ký, văn bản gợi ý bữa tiếp theo, đường dẫn ảnh đã tạo và danh sách công cụ đã sử dụng trong tương tác.
Pipeline này kết hợp nhiều năng lực như tìm kiếm, ước tính, ghi nhật ký, gợi ý và trực quan hóa để tạo nên trải nghiệm dinh dưỡng dùng AI.
Bước 4: Tạo giao diện thân thiện với Gradio
Khi logic backend đã hoàn chỉnh, hãy gói lại trong một frontend sạch, thân thiện với người dùng bằng 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()
Trong đoạn mã trên, chúng ta thiết lập giao diện Gradio hoàn chỉnh để tương tác với pipeline Tác tử Dinh dưỡng. Cách hoạt động:
- Bắt đầu bằng cách nhập hàm
run_nutritionist_pipeline()từagent.py, thành phần điều khiển logic tác tử cốt lõi. - Tiếp theo, hàm
process_meal()đóng vai trò trình bao quanh pipeline tác tử, nhậnusername,meal_descvàdietary_preferencelàm đầu vào và kích hoạt logic đa tác tử đã định nghĩa. - Bên trong
process_meal(), dictionary kết quả được phân tích để trích xuất tóm tắt bữa ăn, calo, gợi ý bữa tiếp theo và connectors đã dùng. - Hàm cũng kiểm tra đường dẫn ảnh sinh ra có hợp lệ trước khi trả về để hiển thị. Nếu không có ảnh, chỉ trả về kết quả văn bản.
- Ứng dụng Gradio được xây dựng bằng
gr.Blocks()với bố cục hai cột: một bên là các trường nhập và nút Process Meal; bên còn lại là khu vực xuất kết quả phân tích bữa ăn và xem trước ảnh món tiếp theo. - Callback
submit_btn.click()nối nút frontend để kích hoạt hàmprocess_meal(), truyền đầu vào và nhận markdown định dạng cùng ảnh làm đầu ra. - Cuối cùng, ứng dụng được khởi chạy qua
demo.launch()nếu script chạy ở chế độ main. Bạn có thể đặtdebug = Trueđể bật chế độ gỡ lỗi.
Để chạy bản demo, mở terminal tại thư mục gốc và gõ lệnh sau:
python app.py
Cấu trúc tổng thể của dự án như sau:
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
Bạn có thể tìm toàn bộ mã cho dự án này tại repo GitHub này.
Kết luận
Trong hướng dẫn này, chúng ta đã xây dựng Huấn luyện viên Dinh dưỡng AI hoàn chỉnh bằng Mistral Agents API. Trong quá trình đó, chúng ta đã khám phá:
- Cách tác tử Mistral khác với các mô hình LLM thô
- Vai trò của các connector như
web_searchvàimage_generation - Điều phối giữa nhiều tác tử trong một pipeline duy nhất
- Xây dựng frontend thân thiện với Gradio
Dự án này cho thấy sức mạnh của quy trình agentic, nơi LLM không chỉ phản hồi thụ động, mà là các thực thể tương tác có khả năng suy luận, hành động và điều phối nhiệm vụ. Từ ghi nhật ký bữa ăn đến gợi ý lựa chọn lành mạnh và thậm chí tạo ảnh, chúng ta đã minh họa cách kết hợp các công cụ đơn giản thành trải nghiệm AI mạnh mẽ.
Để tìm hiểu thêm về việc sử dụng tác tử AI, tôi khuyến nghị các hướng dẫn thực hành sau:
Tôi là Chuyên gia Google Developers trong lĩnh vực ML (Gen AI), Chuyên gia Kaggle 3x và Đại sứ Women Techmakers với hơn 3 năm kinh nghiệm trong ngành công nghệ. Tôi đồng sáng lập một startup công nghệ y tế vào năm 2020 và hiện đang theo học thạc sĩ khoa học máy tính tại Georgia Tech, chuyên sâu về học máy.



