<t> Tutorial Pydantic AI: Cara Membina Agent LLM dengan Selamat Jenis (Type-Safe), Daripada Program Pertama hingga ke Produksi
<e> Sesiapa yang pernah membina aplikasi LLM pasti tahu bahawa bahagian yang paling menyakitkan bukanlah menyambungkan API, tetapi output model yang sentiasa berbeza bentuknya setiap kali dipanggil. Pydantic AI membawa pengesahan jenis Pydantic ke dalam pembangunan Agent, menjadikan output berstruktur dan alatan boleh diperiksa secara statik. Artikel ini akan membimbing anda daripada proses pemasangan hinggalah ke peringkat lanjutan, lengkap dengan pengalaman pahit yang pernah saya lalui sendiri.
Mukaddah: Kenapa Output Model AI Selalu Berubah-ubah?
Jika anda pernah menyambungkan API LLM, anda pasti tidak asing lagi dengan situasi ini: anda menyuruh model "pulangkan JSON yang mengandungi name dan score", sembilan kali pertama semuanya baik-baik saja, tetapi pada kali kesepuluh, ia menambah ayat "Baik, ini hasilnya:" sebelum JSON tersebut, dan kod json.loads() anda serta-merta ranap. Kemudian anda mula menulis pelbagai ekspresi regular (regex) untuk membersihkan rentetan (string), dan menulis berbaris-baris kod if untuk memeriksa sama ada medan tersebut wujud—akhirnya, 70% kod "aplikasi AI" anda dihabiskan untuk bergelut dengan output model yang tidak stabil.
Saya sendiri pernah menyelenggara perkhidmatan pengelasan dalaman, dan semata-mata untuk menangani isu model yang kadang-kadang tertinggal satu medan, saya terpaksa bekerja lebih masa selama tiga hari. Selepas beralih kepada Pydantic AI, kod pertahanan tersebut hampir dibuang sepenuhnya kerana tugas pengesahan (validation) kini digalas terus oleh kerangka kerja (framework) ini. Artikel ini akan menerangkan dengan terperinci cara penggunaannya.
Apa itu Pydantic AI?
Pydantic AI ialah kerangka kerja Agent Python daripada pasukan Pydantic. Anda mungkin pernah melihat nama Pydantic di tempat lain—banyak pengesahan data di peringkat asas untuk SDK rasmi OpenAI, Anthropic, Google, serta LangChain dan LlamaIndex, bergantung padanya. Dalam erti kata lain, mengenai bab pengesahan data, merekalah pihak yang paling layak dalam ekosistem ini.
Falsafah reka bentuknya sangat mirip dengan FastAPI: gunakan anotasi jenis (type hints) asli Python untuk mentakrifkan kelakuan dengan jelas, dan serahkan selebihnya kepada kerangka kerja. Terasnya hanya merangkumi beberapa konsep—Agent (Ejen), Tools (Alat), Dependencies (Penyuntikan Dependensi), dan Structured Output (Output Berstruktur). Anda tidak perlu menghafal pelbagai kelas abstrak rekaan mereka; penulisan kodnya kekal seperti Python biasa, namun IDE akan memberikan anda fungsi auto-lengkap (autocomplete), dan penyemak jenis (seperti Pyright, mypy) boleh mengesan ralat sebelum anda sempat menjalankan program.
Ia bersifat bebas model (model-agnostic), bermaksud ia tidak terikat dengan mana-mana pengeluar model tertentu. Lebih belasan jenayah disokong termasuk OpenAI, Anthropic, Google, Groq, Cohere, Mistral, dan Ollama. Untuk menukar model, anda selalunya hanya perlu mengubah satu rentetan sahaja. Jika anda ingin memahami perbezaan antara Agent dan panggilan API biasa, anda boleh merujuk kepada Apakah itu AI Agent terlebih dahulu.
Kegunaannya
Secara terus terang, apa sahaja senario yang "memerlukan model memulangkan hasil yang boleh dipercayai" amat sesuai menggunakan alat ini:
- Pengekstrakan Berstruktur: Masukkan surat aduan pelanggan dan arahkan ia menghasilkan tiga medan:
sentimen,kategori, dantahap_urgensi, sambil menjamin jenis data (data type) yang tepat. - Pengelasan dan Pelabelan: Dokumen dalam jumlah yang besar perlu dilabelkan, dengan output yang terhad dalam Enum yang anda takrifkan. Jawapan model yang merbahaya atau terpesong akan disekat.
- Agent Berasaskan Alat: Membolehkan model memanggil fungsi anda—seperti menyemak pangkalan data, memanggil API cuaca, atau mengira matematik. Kerangka kerja ini bertanggungjawab menukar jenis fungsi kepada penerangan alat yang boleh difahami oleh model.
- Soal Jawab RAG: Digabungkan dengan carian vektor (vector retrieval) untuk membina sistem soal jawab yang berasaskan fakta. Bahagian ini boleh dirujuk melalui Panduan Pelaksanaan RAG kami.
Berbanding kerangka kerja besar seperti LangChain yang merangkumi segala-galanya, Pydantic AI sengaja direka ringkas dan nipis. Jika matlamat anda sekadar menjadikan output model lebih boleh dipercayai tanpa mahu menghafal keseluruhan ekosistem hanya kerana fungsi kecil, keluk pembelajaran (learning curve) alat ini jauh lebih mesra pengguna.
Cara Penggunaan: Pengenalan Pertama
1. Pemasangan
bash
pip install pydantic-ai
Adalah disyorkan untuk membuka persekitaran maya (virtual environment). Versi Python 3.9 ke atas adalah lebih selamat.
2. Konfigurasi Kunci API
Mengambil contoh Anthropic, tetapkan pembolehubah persekitaran (environment variable):
bash
export ANTHROPIC_API_KEY=kunci_anda
Jika menggunakan OpenAI, tetapkan OPENAI_API_KEY, dan begitu juga seterusnya.
3. Menulis Agent Pertama Anda
python
from pydantic_ai import Agent
agent = Agent('anthropic:claude-sonnet-4-6')
result = agent.run_sync('Jelaskan apa itu pangkalan data vektor dalam satu ayat')
print(result.output)
Parameter pertama ialah nama model, dengan format pengeluar:model. Untuk menukarnya kepada OpenAI, ubah sahaja kepada 'openai:gpt-4o' atau yang seumpamanya, manakala kod lain kekal tidak berubah—inilah kelebihan sifat bebas modelnya.
4. Menjadikan Output Berstruktur
Inilah bahagian yang paling penting. Anda mentakrifkan model Pydantic sebagai format output:
python
from pydantic import BaseModel
from pydantic_ai import Agent
class Review(BaseModel):
sentiment: str # positive / negative / neutral
score: int # 1 hingga 5
summary: str
agent = Agent('anthropic:claude-sonnet-4-6', output_type=Review)
result = agent.run_sync('Makanan di kedai ini sedap tetapi menunggu hampir sejam, agak keterlaluan')
print(result.output.score) # Terus mendapatkan nombor bulat tanpa perlu parse sendiri
print(result.output.sentiment) # Terus mendapatkan rentetan (string)
Jika jawapan yang diberikan oleh model tidak mematuhi jenis data Review, kerangka kerja akan menghantar mesej ralat kembali kepada model secara automatik untuk memohon percubaan semula. Apabila anda menerima result.output, ia sudah pun menjadi objek Python yang disahkan, dan IDE juga akan membantu anda melengkapkan medan secara automatik.
5. Memberikan Alat (Tool) kepada Agent
python
from pydantic_ai import Agent
agent = Agent('anthropic:claude-sonnet-4-6')
@agent.tool_plain
def get_weather(city: str) -> str:
"""Semak cuaca semasa untuk bandar yang ditentukan"""
return f'{city} sekarang 28 darjah, cerah'
result = agent.run_sync('Bagaimana cuaca di Taipei sekarang?')
print(result.output)
Dokumentasi (docstring) itu bukan sekadar hiasan—ia akan menjadi penerangan alat yang dilihat oleh model. Anotasi jenis fungsi (city: str) juga akan ditukar kepada spesifikasi parameter yang difahami oleh model, dan parameter ini turut disahkan melalui Pydantic.
Teknik Lanjutan
Penyuntikan Dependensi (Dependency Injection) ialah ciri yang paling dipandang rendah. Anda boleh menggunakan RunContext untuk menghantar sambungan pangkalan data, identiti pengguna, dan klien API ke dalam Agent serta alat dengan cara yang selamat dari segi jenis (type-safe):
python
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
@dataclass
class Deps:
user_id: int
db: object # Sambungan pangkalan data anda
agent = Agent('anthropic:claude-sonnet-4-6', deps_type=Deps)
@agent.tool
def get_orders(ctx: RunContext[Deps]) -> str:
return f'Semak pesanan untuk pengguna {ctx.deps.user_id}'
Semasa menulis ujian, anda hanya perlu menggantikan db dengan objek palsu (mock object) tanpa menyentuh pangkalan data sebenar. Ini sangat penting untuk penulisan ujian unit (unit test).
Penstriman (Streaming): Untuk menghasilkan kesan taip masa nyata (real-time typing effect), gunakan agent.run_stream(). Ia mengesahkan output berstruktur sambil menjana data, sekali gus memberikan pengalaman pengguna yang jauh lebih baik.
Kebolehhatian (Observability): Pydantic AI bersepadu dengan lancar bersama Logfire daripada pasukan yang sama. Selepas disambungkan, setiap panggilan model, setiap pencetus alat, jumlah token yang digunakan, dan masa yang diambil, semuanya boleh dilihat. Perkara paling sukar untuk dinyahpepijat (debug) dalam aplikasi LLM ialah "mengapa model membalas begini". Dengan adanya ciri ini, anda tidak perlu lagi meneka-neka secara kosong. Untuk merancang Agent dengan lebih holistik, anda boleh merujuk bersama Panduan Pembangunan AI Agent kami.
Ralat Lazim dan Perkara Yang Perlu Diberi Perhatian
- Menyangka output_type menjamin keselamatan 100%: Kerangka kerja akan meminta model mencuba semula apabila pengesahan gagal, tetapi percubaan semula mempunyai had. Jika ia terus gagal, ia akan membuang pengecualian (exception), dan anda tetap perlu menggunakan try/except. Pengesahan jenis mengurangkan risiko "data kotor menyusup masuk ke dalam sistem", bukannya memastikan "model tidak pernah melakukan kesilapan".
- Menulis docstring alat secara sembarangan: Model bergantung sepenuhnya pada docstring untuk menentukan bila sesuatu alat harus dipanggil. Jika ditulis secara samar-samar, model akan memanggilnya secara tidak menentu atau langsung tidak memanggilnya. Anggap ia sebagai manual arahan yang ditulis khusus untuk model.
- Memasukkan terlalu banyak logik ke dalam alat tanpa mengendalikan pengecualian: Apabila kod dalam alat menghadapi ralat, mesej tersebut akan dikembalikan kepada model, menyebabkan model berputar-putar di sekitar ralat tersebut dan membakar banyak token. Kendalikan pengecualian yang patut disekat dengan sendiri.
- Mengabaikan kos: Percubaan semula output berstruktur dan panggilan alat berbilang pusingan menggunakan token dengan lebih cepat daripada yang anda sangkakan. Pastikan anda menyambungkan sistem kebolehhatian sebelum melancarkannya secara rasmi untuk memantau kos sebenar.
- Menggunakannya seperti kerangka kerja bersaiz besar: Ia sengaja direka nipis. Jika anda memerlukan susunan pelbagai langkah yang rumit dan pelbagai penyambung sedia ada, LlamaIndex atau penyelesaian lain mungkin lebih mudah; jangan paksa penggunaannya jika tidak sesuai.
Ulasan TheAI Akademi
Secara jujur, terdapat begitu banyak kerangka kerja Agent di pasaran sehingga mencetuskan kekeliruan pilihan, tetapi Pydantic AI menyelesaikan satu masalah yang sangat spesifik dan pernah dialami oleh setiap pembangun LLM: output yang tidak boleh dipercayai. Ia tidak berniat untuk menjadi "kerangka kerja terhebat di alam semesta", sebaliknya ia membawa konsep "keselamatan jenis" (type safety) yang amat mementingkan komuniti Python ke dalam pembangunan AI secara bersih. Bagi mereka yang sudah terbiasa dengan gaya penulisan FastAPI dan Pydantic, hampir tiada keluk pembelajaran diperlukan.
Ia tidak akan menjadikan model anda lebih bijak, tetapi ia akan menjadikan kod anda lebih boleh dipercayai—dan perkara terakhir inilah yang benar-benar menyelamatkan anda selepas sistem dilancarkan.
Jika anda sekadar membina demo atau bermain-main, anda mungkin kurang merasai kelebihannya; tetapi sebaik sahaja projek anda benar-benar dilancarkan, digunakan oleh orang ramai, dan diselenggara untuk jangka masa panjang, nilai keselamatan jenis dan kebolehhatian akan menjadi semakin ketara hari demi hari.
Sumber Rujukan
Soalan Lazim
<q> Apakah perbezaan antara Pydantic AI dengan LangChain, dan yang mana satukah patut saya pilih?
<a> Perbezaan terbesar ialah "berat" kerangka kerja tersebut. LangChain ialah ekosistem berskala besar yang mempunyai banyak penyambung, integrasi, dan lapisan abstraksi, menjadikannya sesuai untuk projek besar yang memerlukan aturan (orchestration) kompleks, namun keluk pembelajarannya agak curam. Pydantic AI sengaja direka ringan, dengan terasnya hanya merangkumi beberapa konsep seperti Agent, alatan (tools), suntikan pergantungan (dependency injection), dan output berstruktur, serta mengetengahkan ciri keselamatan jenis (type safety). Jika keperluan anda adalah "untuk menjadikan output model lebih boleh diharap dan gaya penulisan lebih dekat dengan Python asli", Pydantic AI jauh lebih cepat untuk dikuasai; jika anda memerlukan banyak integrasi sedia ada, LangChain lebih menjimatkan masa. Kedua-duanya tidak bercanggah, pilihlah mengikut skala projek.
<q> Adakah saya wajib menggunakan model OpenAI? Bolehkah ia disambungkan kepada model tempatan (local model)?
<a> Tidak perlu. Pydantic AI bersifat agnostik model (model-agnostic) dan menyokong lebih sedozen penyedia seperti OpenAI, Anthropic, Google, Groq, Mistral, Cohere, dan Ollama. Untuk menukar model, biasanya anda hanya perlu mengubah rentetan (string) semasa membina Agent. Jika anda mahu menjalankan model tempatan, anda boleh menggunakan Ollama dengan menghalakan rentetan model kepada perkhidmatan tempatan, dan bahagian program yang lain tidak perlu diubah.
<q> Adakah output berstruktur benar-benar dapat menjamin model tidak memberikan jawapan yang merapu?
<a> Ia tidak boleh menjamin model itu sendiri tidak melakukan ralat, tetapi ia dapat menjamin "data yang tidak mengikut jenis yang anda tentukan tidak akan menyelinap masuk ke dalam sistem". Apabila apa yang dipulangkan oleh model gagal melepasi pengesahan Pydantic, kerangka kerja akan menghantar semula mesej ralat secara automatik untuk memintanya mencuba semula. Walau bagaimanapun, percubaan semula mempunyai had maksimum; kegagalan yang berterusan akan mencetuskan ralat (exception), jadi anda tetap perlu menggunakan try/except untuk mengendalikan senario terburuk. Apa yang dikurangkan olehnya ialah risiko data kotor, bukannya masalah kecerdasan model.
<q> Sebagai pembangun baharu yang tidak pernah menulis Pydantic, adakah sukar untuk mempelajari perkara ini?
<a> Jika anda tahu asas Python dan anotasi jenis (type hints), ambang kesukarannya tidak tinggi. Teras Pydantic adalah "menggunakan class untuk mentakrifkan rupa bentuk data", dan cara penulisannya sangat intuitif. Adalah disyorkan agar anda meluangkan masa sepuluh minit untuk melihat cara Pydantic mentakrifkan BaseModel sebelum kembali menulis Agent, prosesnya akan menjadi jauh lebih lancar. Halangan konseptual yang sebenar sebenarnya adalah cara pemikiran reka bentuk Agent dan alatan, yang boleh dipelajari bersama panduan pembangunan Agent kami.