Tutorial Lengkap Mistral AI API: Membangun Aplikasi AI dengan Model LLM dari Mistral
Mistral AI adalah salah satu penyedia model bahasa besar (LLM) terkemuka dari Prancis yang menawarkan model-model berkinerja tinggi dengan efisiensi luar biasa. Dengan API yang mudah digunakan, Mistral menyediakan berbagai model mulai dari yang ringan seperti Mistral Small hingga yang sangat powerful seperti Mistral Large dan Codestral untuk kebutuhan coding.
Dalam tutorial ini, kita akan mempelajari cara menggunakan Mistral AI API secara lengkap menggunakan Python, mulai dari setup awal, chat completion, function calling, embeddings, hingga penggunaan lanjutan seperti streaming, JSON mode, dan agents.
Mengapa Mistral AI?
Mistral AI memiliki beberapa keunggulan yang membuatnya layak dipertimbangkan:
- Efisiensi tinggi: Model Mistral dirancang untuk memberikan performa optimal dengan ukuran parameter yang lebih kecil dibanding kompetitor
- Open-weight models: Beberapa model seperti Mistral 7B dan Mixtral tersedia sebagai open-weight
- Harga kompetitif: Biaya per token yang lebih rendah dibanding banyak penyedia lain
- Kecepatan inference: Waktu respons yang cepat berkat arsitektur model yang efisien
- Dukungan multi-bahasa: Performa baik dalam berbagai bahasa termasuk Bahasa Indonesia
- Function calling: Dukungan native untuk pemanggilan fungsi dan tool use
Instalasi dan Setup
Instalasi SDK Python
pip install mistralai
Mendapatkan API Key
Konfigurasi Environment Variable
export MISTRALAPIKEY="your-api-key-here"
Atau simpan dalam file .env:
MISTRALAPIKEY=your-api-key-here
Verifikasi Instalasi
import os
from mistralai import Mistral
client = Mistral(apikey=os.environ["MISTRALAPIKEY"])
Test koneksi dengan list models
models = client.models.list()
for model in models.data:
print(f"- {model.id}")
Model yang Tersedia
Mistral AI menyediakan beberapa model dengan karakteristik berbeda:
| Model | Kegunaan | Context Window |
|-------|----------|----------------|
| mistral-small-latest | Tugas ringan, klasifikasi, ringkasan | 32K |
| mistral-medium-latest | Keseimbangan performa dan biaya | 32K |
| mistral-large-latest | Tugas kompleks, reasoning, coding | 128K |
| codestral-latest | Khusus coding dan generasi kode | 32K |
| mistral-embed | Text embeddings | 8K |
| open-mistral-nemo | Open-weight, general purpose | 128K |
| pixtral-large-latest | Multimodal (teks + gambar) | 128K |
Basic Usage: Chat Completion
Request Sederhana
import os
from mistralai import Mistral
client = Mistral(apikey=os.environ["MISTRALAPIKEY"])
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{"role": "user", "content": "Jelaskan apa itu machine learning dalam 3 kalimat."}
]
)
print(response.choices[0].message.content)
Menggunakan System Message
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{
"role": "system",
"content": "Kamu adalah asisten ahli data science yang menjelaskan konsep teknis dengan bahasa sederhana dan contoh sehari-hari."
},
{
"role": "user",
"content": "Apa perbedaan antara supervised dan unsupervised learning?"
}
]
)
print(response.choices[0].message.content)
Multi-turn Conversation
messages = [
{"role": "system", "content": "Kamu adalah tutor Python yang sabar dan helpful."},
{"role": "user", "content": "Bagaimana cara membuat list comprehension di Python?"},
]
response = client.chat.complete(
model="mistral-large-latest",
messages=messages
)
assistantreply = response.choices[0].message.content
print("Asisten:", assistantreply)
messages.append({"role": "assistant", "content": assistantreply})
messages.append({"role": "user", "content": "Berikan contoh dengan kondisi filter."})
response = client.chat.complete(
model="mistral-large-latest",
messages=messages
)
print("Asisten:", response.choices[0].message.content)
Mengatur Parameter Generasi
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{"role": "user", "content": "Tulis sebuah puisi pendek tentang kecerdasan buatan."}
],
temperature=0.7,
maxtokens=500,
topp=0.95,
)
print(response.choices[0].message.content)
Informasi penggunaan token
usage = response.usage
print(f"\nToken prompt: {usage.prompttokens}")
print(f"Token completion: {usage.completiontokens}")
print(f"Total token: {usage.totaltokens}")
Streaming Response
Untuk respons yang panjang, streaming memungkinkan menampilkan output secara bertahap:
stream = client.chat.stream(
model="mistral-large-latest",
messages=[
{"role": "user", "content": "Jelaskan arsitektur Transformer secara detail."}
]
)
for chunk in stream:
content = chunk.data.choices[0].delta.content
if content:
print(content, end="", flush=True)
print()
Streaming dengan Pengumpulan Respons
fullresponse = ""
stream = client.chat.stream(
model="mistral-large-latest",
messages=[
{"role": "user", "content": "Buat tutorial singkat tentang pandas DataFrame."}
]
)
for chunk in stream:
content = chunk.data.choices[0].delta.content
if content:
full
response += content
print(content, end="", flush=True)
print(f"\n\nTotal karakter: {len(fullresponse)}")
JSON Mode
Mistral AI mendukung JSON mode untuk menghasilkan output terstruktur:
import json
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{
"role": "user",
"content": """Analisis sentimen dari review berikut dan berikan output dalam format JSON
dengan field: text, sentiment (positive/negative/neutral), confidence (0-1), keywords.
Review: "Produk ini sangat bagus! Kualitasnya luar biasa dan pengiriman cepat.
Sangat recommended untuk semua orang."
"""
}
],
responseformat={"type": "jsonobject"}
)
result = json.loads(response.choices[0].message.content)
print(json.dumps(result, indent=2, ensureascii=False))
Structured Output dengan Schema
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{
"role": "user",
"content": """Ekstrak informasi dari teks berikut ke format JSON:
"PT Maju Bersama yang beralamat di Jalan Sudirman No. 123, Jakarta,
didirikan pada tahun 2015 oleh Budi Santoso. Perusahaan ini bergerak
di bidang teknologi informasi dengan 150 karyawan."
Schema: {companyname, address, foundedyear, founder, industry, employeecount}"""
}
],
responseformat={"type": "jsonobject"}
)
data = json.loads(response.choices[0].message.content)
print(json.dumps(data, indent=2, ensureascii=False))
Function Calling (Tool Use)
Salah satu fitur powerful Mistral AI adalah kemampuan function calling:
Mendefinisikan Tools
import json
tools = [
{
"type": "function",
"function": {
"name": "getweather",
"description": "Mendapatkan informasi cuaca untuk sebuah kota",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "Nama kota, misalnya Jakarta, Surabaya"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Satuan suhu"
}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "calculatebmi",
"description": "Menghitung Body Mass Index (BMI)",
"parameters": {
"type": "object",
"properties": {
"weightkg": {
"type": "number",
"description": "Berat badan dalam kilogram"
},
"heightcm": {
"type": "number",
"description": "Tinggi badan dalam sentimeter"
}
},
"required": ["weightkg", "heightcm"]
}
}
}
]
Menjalankan Function Calling
def getweather(city, unit="celsius"):
weather
data = {
"Jakarta": {"temp": 32, "condition": "Cerah berawan", "humidity": 75},
"Surabaya": {"temp": 34, "condition": "Cerah", "humidity": 65},
"Bandung": {"temp": 24, "condition": "Berawan", "humidity": 80},
}
data = weatherdata.get(city, {"temp": 28, "condition": "Tidak diketahui", "humidity": 70})
if unit == "fahrenheit":
data["temp"] = data["temp"] 9/5 + 32
return json.dumps(data)
def calculatebmi(weightkg, heightcm):
heightm = heightcm / 100
bmi = weightkg / (heightm 2)
if bmi < 18.5:
category = "Underweight"
elif bmi < 25:
category = "Normal"
elif bmi < 30:
category = "Overweight"
else:
category = "Obese"
return json.dumps({"bmi": round(bmi, 1), "category": category})
availablefunctions = {
"getweather": getweather,
"calculatebmi": calculatebmi
}
messages = [
{"role": "user", "content": "Bagaimana cuaca di Jakarta hari ini?"}
]
response = client.chat.complete(
model="mistral-large-latest",
messages=messages,
tools=tools,
toolchoice="auto"
)
message = response.choices[0].message
if message.toolcalls:
messages.append(message)
for toolcall in message.toolcalls:
functionname = toolcall.function.name
functionargs = json.loads(toolcall.function.arguments)
print(f"Memanggil fungsi: {functionname}({functionargs})")
functionresult = availablefunctionsfunctionname
messages.append({
"role": "tool",
"name": functionname,
"content": functionresult,
"toolcallid": toolcall.id
})
finalresponse = client.chat.complete(
model="mistral-large-latest",
messages=messages,
tools=tools
)
print(finalresponse.choices[0].message.content)
Text Embeddings
Mistral AI menyediakan model embedding yang powerful untuk berbagai kebutuhan:
response = client.embeddings.create(
model="mistral-embed",
inputs=["Machine learning adalah cabang dari artificial intelligence."]
)
embedding = response.data[0].embedding
print(f"Dimensi embedding: {len(embedding)}")
print(f"Contoh nilai: {embedding[:5]}")
Semantic Search dengan Embeddings
import numpy as np
documents = [
"Python adalah bahasa pemrograman yang populer untuk data science.",
"TensorFlow adalah framework deep learning dari Google.",
"Docker memudahkan deployment aplikasi dalam container.",
"Pandas digunakan untuk manipulasi dan analisis data tabular.",
"Kubernetes adalah platform orkestrasi container.",
"Scikit-learn menyediakan algoritma machine learning klasik.",
"React adalah library JavaScript untuk membangun user interface.",
"FastAPI adalah framework Python modern untuk membangun API.",
]
def getembeddings(texts):
response = client.embeddings.create(
model="mistral-embed",
inputs=texts
)
return [item.embedding for item in response.data]
docembeddings = getembeddings(documents)
def cosinesimilarity(a, b):
return np.dot(a, b) / (np.linalg.norm(a) np.linalg.norm(b))
def search(query, topk=3):
queryembedding = getembeddings([query])[0]
similarities = []
for i, docemb in enumerate(docembeddings):
sim = cosinesimilarity(queryembedding, docemb)
similarities.append((i, sim))
similarities.sort(key=lambda x: x[1], reverse=True)
print(f"Query: {query}\n")
for idx, sim in similarities[:topk]:
print(f" [{sim:.4f}] {documents[idx]}")
print()
search("library untuk analisis data")
search("cara deploy aplikasi")
search("framework machine learning")
Advanced Usage
Batch Processing
import asyncio
from mistralai import Mistral
async def processbatch(prompts):
client = Mistral(apikey=os.environ["MISTRALAPIKEY"])
async def processsingle(prompt):
response = await client.chat.completeasync(
model="mistral-small-latest",
messages=[{"role": "user", "content": prompt}],
maxtokens=200
)
return response.choices[0].message.content
tasks = [processsingle(prompt) for prompt in prompts]
results = await asyncio.gather(tasks)
return results
prompts = [
"Apa itu neural network?",
"Jelaskan konsep gradient descent.",
"Apa perbedaan CNN dan RNN?",
"Apa itu transfer learning?",
"Jelaskan konsep attention mechanism."
]
results = asyncio.run(processbatch(prompts))
for prompt, result in zip(prompts, results):
print(f"Q: {prompt}")
print(f"A: {result[:100]}...")
print()
Retry Logic dan Error Handling
import time
from mistralai import Mistral
from mistralai.models import HTTPValidationError
def chatwithretry(client, messages, model="mistral-large-latest", maxretries=3):
for attempt in range(maxretries):
try:
response = client.chat.complete(
model=model,
messages=messages
)
return response.choices[0].message.content
except HTTPValidationError as e:
print(f"Validation error: {e}")
raise
except Exception as e:
if attempt < maxretries - 1:
waittime = 2 attempt
print(f"Error: {e}. Retrying in {waittime}s...")
time.sleep(waittime)
else:
raise
result = chatwithretry(
client,
[{"role": "user", "content": "Halo, apa kabar?"}]
)
print(result)
RAG (Retrieval-Augmented Generation) Sederhana
knowledgebase = {
"produk
a": "Produk A adalah software manajemen proyek dengan fitur Kanban board, time tracking, dan reporting. Harga mulai dari Rp 500.000/bulan untuk tim hingga 10 orang.",
"produkb": "Produk B adalah platform analitik data yang mendukung visualisasi real-time, custom dashboard, dan integrasi dengan 50+ sumber data. Harga mulai dari Rp 1.500.000/bulan.",
"kebijakanrefund": "Refund dapat diajukan dalam 30 hari sejak pembelian. Proses refund membutuhkan waktu 5-7 hari kerja. Refund tidak berlaku untuk paket tahunan yang sudah melewati 14 hari.",
"jamoperasional": "Customer support tersedia Senin-Jumat pukul 08:00-17:00 WIB. Untuk urgency tinggi, tersedia hotline 24/7 di nomor 0800-1234-567."
}
def retrievecontext(query, knowledgebase):
queryembedding = getembeddings([query])[0]
kbtexts = list(knowledgebase.values())
kbkeys = list(knowledgebase.keys())
kbembeddings = getembeddings(kbtexts)
similarities = []
for i, emb in enumerate(kbembeddings):
sim = cosinesimilarity(queryembedding, emb)
similarities.append((i, sim))
similarities.sort(key=lambda x: x[1], reverse=True)
topresults = similarities[:2]
context = "\n\n".join([kbtexts[idx] for idx, in topresults])
return context
def ragchat(query):
context = retrievecontext(query, knowledgebase)
messages = [
{
"role": "system",
"content": f"""Kamu adalah customer support assistant. Jawab pertanyaan berdasarkan konteks yang diberikan.
Jika informasi tidak tersedia dalam konteks, katakan bahwa kamu tidak memiliki informasi tersebut.
Konteks:
{context}"""
},
{"role": "user", "content": query}
]
response = client.chat.complete(
model="mistral-large-latest",
messages=messages,
temperature=0.3
)
return response.choices[0].message.content
print(ragchat("Berapa harga produk analitik data?"))
print()
print(ragchat("Bagaimana cara mengajukan refund?"))
Multimodal dengan Pixtral
import base64
def encodeimage(imagepath):
with open(imagepath, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
imagebase64 = encodeimage("chart.png")
response = client.chat.complete(
model="pixtral-large-latest",
messages=[
{
"role": "user",
"content": [
{
"type": "imageurl",
"imageurl": {
"url": f"data:image/png;base64,{imagebase64}"
}
},
{
"type": "text",
"text": "Analisis grafik ini. Apa tren utama yang terlihat dan apa insight yang bisa diambil?"
}
]
}
]
)
print(response.choices[0].message.content)
Menggunakan Codestral untuk Code Generation
response = client.chat.complete(
model="codestral-latest",
messages=[
{
"role": "system",
"content": "Kamu adalah expert Python developer. Tulis kode yang clean, efisien, dan well-documented."
},
{
"role": "user",
"content": """Buatkan class Python untuk mengelola koneksi database PostgreSQL
dengan connection pooling, retry logic, dan context manager support."""
}
],
temperature=0.2
)
print(response.choices[0].message.content)
Best Practices
1. Pemilihan Model yang Tepat
Gunakan model sesuai kompleksitas tugas:
- mistral-small: Klasifikasi, ekstraksi entitas, tugas sederhana
- mistral-large: Reasoning kompleks, coding, analisis mendalam
- codestral: Khusus untuk code generation dan code review
- mistral-embed: Text embeddings dan semantic search
- pixtral: Analisis gambar dan dokumen visual
2. Optimasi Biaya
def smartmodelselection(taskcomplexity):
if task
complexity == "simple":
return "mistral-small-latest"
elif taskcomplexity == "medium":
return "mistral-medium-latest"
else:
return "mistral-large-latest"
def estimatecost(prompttokens, completiontokens, model):
pricing = {
"mistral-small-latest": {"input": 0.001, "output": 0.003},
"mistral-large-latest": {"input": 0.003, "output": 0.009},
}
rates = pricing.get(model, pricing["mistral-small-latest"])
cost = (prompttokens / 1000 rates["input"]) + (completiontokens / 1000 rates["output"])
return cost
3. Prompt Engineering
systemprompt = """Kamu adalah asisten analis data yang profesional.
ATURAN:
Selalu berikan jawaban berdasarkan data dan fakta
Jika tidak yakin, sampaikan tingkat keyakinanmu
Gunakan format terstruktur untuk jawaban kompleks
Berikan rekomendasi yang actionable
FORMAT OUTPUT:
- Gunakan bullet points untuk daftar
- Gunakan tabel untuk perbandingan
- Sertakan ringkasan di akhir"""
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{"role": "system", "content": system
prompt},
{"role": "user", "content": "Bandingkan PostgreSQL vs MongoDB untuk aplikasi e-commerce."}
],
temperature=0.3
)
4. Rate Limiting
import time
from collections import deque
class RateLimiter:
def init(self, maxrequestsperminute=60):
self.maxrequests = maxrequestsperminute
self.requests = deque()
def waitifneeded(self):
now = time.time()
while self.requests and self.requests[0] < now - 60:
self.requests.popleft()
if len(self.requests) >= self.maxrequests:
sleeptime = 60 - (now - self.requests[0])
if sleeptime > 0:
time.sleep(sleeptime)
self.requests.append(time.time())
ratelimiter = RateLimiter(maxrequestsperminute=50)
def ratelimitedchat(messages):
ratelimiter.waitifneeded()
return client.chat.complete(
model="mistral-small-latest",
messages=messages
)
5. Caching Responses
import hashlib
import json
class ResponseCache:
def init(self):
self.cache = {}
def makekey(self, model, messages, kwargs):
content = json.dumps({"model": model, "messages": messages, kwargs}, sortkeys=True)
return hashlib.md5(content.encode()).hexdigest()
def getorcreate(self, client, model, messages, kwargs):
key = self.makekey(model, messages, kwargs)
if key in self.cache:
print("Cache hit!")
return self.cache[key]
response = client.chat.complete(model=model, messages=messages, *kwargs)
result = response.choices[0].message.content
self.cache[key] = result
return result
cache = ResponseCache()
result1 = cache.getorcreate(client, "mistral-small-latest", [{"role": "user", "content": "Apa itu API?"}])
result2 = cache.getorcreate(client, "mistral-small-latest", [{"role": "user", "content": "Apa itu API?"}])
Contoh Proyek: Chatbot Customer Service
Berikut contoh lengkap membangun chatbot customer service dengan Mistral AI:
import os
import json
from mistralai import Mistral
class CustomerServiceBot:
def init(self):
self.client = Mistral(apikey=os.environ["MISTRALAPIKEY"])
self.conversationhistory = []
self.systemprompt = """Kamu adalah customer service bot untuk toko online TechMart.
Informasi perusahaan:
- Jam operasional: Senin-Sabtu, 08:00-20:00 WIB
- Email: support@techmart.id
- Telepon: 021-555-1234
Kebijakan:
- Garansi produk: 1 tahun untuk elektronik, 6 bulan untuk aksesoris
- Return: 7 hari setelah penerimaan barang
- Pengiriman gratis untuk pesanan di atas Rp 500.000
Panduan:
- Jawab dengan ramah dan profesional
- Jika tidak bisa membantu, arahkan ke customer service manusia
- Gunakan bahasa Indonesia yang baik dan benar"""
self.conversationhistory.append({
"role": "system",
"content": self.systemprompt
})
def chat(self, usermessage):
self.conversationhistory.append({
"role": "user",
"content": usermessage
})
response = self.client.chat.complete(
model="mistral-small-latest",
messages=self.conversationhistory,
temperature=0.3,
maxtokens=500
)
assistantmessage = response.choices[0].message.content
self.conversationhistory.append({
"role": "assistant",
"content": assistantmessage
})
return assistantmessage
def reset(self):
self.conversationhistory = [{"role": "system", "content": self.system_prompt}]
bot = CustomerServiceBot()
questions = [
"Halo, saya mau tanya tentang kebijakan return.",
"Kalau barangnya rusak saat diterima bagaimana?",
"Berapa lama proses refund-nya?",
]
for q in questions:
print(f"User: {q}")
answer = bot.chat(q)
print(f"Bot: {answer}\n")
Kesimpulan
Mistral AI API menawarkan solusi LLM yang powerful dan cost-effective untuk berbagai kebutuhan pengembangan aplikasi AI. Dengan dukungan fitur lengkap mulai dari chat completion, function calling, embeddings, hingga model multimodal, Mistral AI menjadi pilihan yang kuat untuk developer yang mencari alternatif dari penyedia LLM lainnya.
Keunggulan utama Mistral AI terletak pada efisiensi model, harga yang kompetitif, dan ketersediaan model open-weight. Dengan mengikuti best practices yang telah dibahas, Anda dapat membangun aplikasi AI yang robust dan cost-efficient.
Langkah selanjutnya yang disarankan:
- Eksplorasi Mistral AI Agents untuk workflow otomatis
- Implementasikan RAG pipeline dengan Mistral embeddings
- Coba fine-tuning model Mistral untuk use case spesifik
- Integrasikan dengan framework seperti LangChain atau LlamaIndex untuk pipeline yang lebih kompleks