PydanticOutputParser adalah sebuah kelas yang membantu mengubah output dari model bahasa menjadi informasi yang lebih terstruktur. Alih-alih respons tekstual sederhana, Anda dapat memberikan informasi yang dibutuhkan pengguna dalam bentuk yang jelas dan terorganisir.
PydanticOutputParser (yang berlaku untuk sebagian besar OutputParser), terutama ada dua metode inti yang harus diimplementasikan
get_format_instructions(): Menyediakan instruksi yang mendefinisikan format informasi yang harus dikeluarkan oleh model bahasa. Sebagai contoh, Anda dapat mengembalikan instruksi sebagai string yang menjelaskan bidang data yang harus dikeluarkan oleh model bahasa dan bagaimana mereka harus diformat. Instruksi-instruksi ini sangat penting bagi model bahasa untuk menyusun output dan mengubahnya agar sesuai dengan model data tertentu.
parse(): Mengambil output dari model bahasa (diasumsikan sebagai string) dan menganalisis dan mengubahnya menjadi struktur tertentu. Gunakan alat seperti Pydantic untuk memvalidasi string input terhadap skema yang telah ditentukan dan mengubahnya menjadi struktur data yang mengikuti skema tersebut.
email_conversation ="""From: Peter (peter@alterolab.com)To: Andy (andy@beliesim.com)Subject: Kerjasama distribusi esim "BeliEsim" dan proposal jadwal pertemuanHalo, Andy,Nama saya Peter dan saya adalah CEO dari Alterolabs. Saya mengetahui tentang sepeda baru Anda "BeliEsim" melalui siaran pers Anda baru-baru ini. Alterolabs adalah perusahaan inovasi dan kualitas terkemuka di bidang manufaktur dan distribusi esim, dan kami memiliki pengalaman dan keahlian jangka panjang di bidang ini.
Kami ingin meminta brosur terperinci untuk model BeliEsim. Secara khusus, kami membutuhkan informasi mengenai spesifikasi teknis, performa baterai, dan aspek desain. Hal ini akan memungkinkan kami untuk menyempurnakan strategi distribusi dan rencana pemasaran yang kami ajukan.
Kami juga ingin mengusulkan pertemuan pada hari Selasa depan (15 Januari) pukul 10.00 untuk mendiskusikan kemungkinan kerja sama secara lebih rinci. Apakah kami bisa bertemu di kantor Anda untuk membicarakannya?
Terima kasih.PeterDirektur UtamaAlterolabs."""
Contoh saat tidak menggunakan pengurai output
from itertools import chainfrom langchain_core.prompts import PromptTemplateprompt = PromptTemplate.from_template("Silahkan ekstrak bagian penting dari email berikut.\n\n{email_conversation}")llm =ChatOpenAI(temperature=0, model_name="gpt-4o")chain = prompt | llmanswer = chain.stream({"email_conversation": email_conversation})output =stream_response(answer, return_output=True)
Berikut adalah ekstraksi bagian penting dari email tersebut:
1. **Pengirim dan Penerima:**
- Dari: Peter ([email protected])
- Kepada: Andy ([email protected])
2. **Subjek:**
- Kerjasama distribusi esim "BeliEsim" dan proposal jadwal pertemuan
3. **Isi Utama:**
- Peter adalah CEO dari Alterolabs.
- Alterolabs tertarik dengan sepeda baru "BeliEsim".
- Permintaan brosur terperinci untuk model BeliEsim, termasuk spesifikasi teknis, performa baterai, dan aspek desain.
- Usulan pertemuan pada hari Selasa depan (15 Januari) pukul 10.00 di kantor Andy untuk mendiskusikan kemungkinan kerja sama lebih lanjut.
4. **Penutup:**
- Terima kasih dari Peter, Direktur Utama Alterolabs.
print(output)
Berikut adalah ekstraksi bagian penting dari email tersebut:
1. **Pengirim**: Peter ([email protected])
2. **Penerima**: Andy ([email protected])
3. **Subjek**: Kerjasama distribusi esim "BeliEsim" dan proposal jadwal pertemuan
4. **Isi Utama**:
- Peter adalah CEO dari Alterolabs.
- Alterolabs tertarik dengan sepeda baru "BeliEsim".
- Permintaan brosur terperinci untuk model BeliEsim, termasuk spesifikasi teknis, performa baterai, dan aspek desain.
- Usulan pertemuan pada hari Selasa depan (15 Januari) pukul 10.00 di kantor Andy untuk mendiskusikan kemungkinan kerja sama lebih lanjut.
Dengan konten email seperti di atas, mari kita mengurai informasi di dalam email menggunakan kelas-kelas yang didefinisikan di dalam gaya Pydantic di bawah ini.
Perhatikan bahwa deskripsi di dalam Field adalah deskripsi untuk mengekstrak informasi kunci dari respons tekstual. LLM akan melihat deskripsi ini untuk mengekstrak informasi yang dibutuhkannya, jadi deskripsi tersebut harus akurat dan jelas.
classEmailSummary(BaseModel): person:str=Field(description="Siapa yang mengirim email") email:str=Field(description="Alamat email orang yang mengirim email") subject:str=Field(description="Subjek surat") summary:str=Field(description="Teks yang meringkas isi email") date:str=Field(description="Tanggal dan waktu pertemuan yang disebutkan di isi email")# Membuat PydanticOutputParserparser =PydanticOutputParser(pydantic_object=EmailSummary)
As an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}
the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.
Here is the output schema:
```
{"properties": {"person": {"title": "Person", "description": "Siapa yang mengirim email", "type": "string"}, "email": {"title": "Email", "description": "Alamat email orang yang mengirim email", "type": "string"}, "subject": {"title": "Subject", "description": "Subjek surat", "type": "string"}, "summary": {"title": "Summary", "description": "Teks yang meringkas isi email", "type": "string"}, "date": {"title": "Date", "description": "Tanggal dan waktu pertemuan yang disebutkan di isi email", "type": "string"}}, "required": ["person", "email", "subject", "summary", "date"]}
```
Tentukan prompt.
question: Menerima pertanyaan dari pengguna.
email_conversation: Masukkan isi body email.
format: Menentukan format.
prompt = PromptTemplate.from_template("""You are a helpful assistant. Please answer the following questions in Bahasa Indonesia.QUESTION:{question}EMAIL CONVERSATION:{email_conversation}FORMAT:{format}""")# Menambahkan pemformatan patial PydanticOutputParser ke formatprompt = prompt.partial(format=parser.get_format_instructions())
Selanjutnya, bagian untuk membuat Chain
# Membuat chainchain = prompt | llm
Jalankan chain dan lihat hasilnya.
# chain dan mencetak hasilnya.response = chain.stream( {"email_conversation": email_conversation,"question": "Silakan ekstrak konten utama email.", })# Hasilnya adalah output dalam bentuk JSONoutput =stream_response(response, return_output=True)
{
"person": "Peter",
"email": "peter@alterolabs.com",
"subject": "Kerjasama distribusi esim \"BeliEsim\" dan proposal jadwal pertemuan",
"summary": "Peter, CEO dari Alterolabs, tertarik dengan sepeda baru 'BeliEsim' dan meminta brosur terperinci mengenai spesifikasi teknis, performa baterai, dan aspek desain. Peter juga mengusulkan pertemuan pada hari Selasa depan (15 Januari) pukul 10.00 di kantor Andy untuk mendiskusikan kemungkinan kerja sama.",
"date": "15 Januari pukul 10.00"
}
```
Terakhir, kita menggunakan parser untuk mengurai hasilnya dan mengonversinya menjadi objek EmailSummary.
# PydanticOutputParser untuk menguraikan hasilnya.structured_output = parser.parse(output)print(structured_output)
```person='Peter' email='peter@alterolabs.com' subject='Kerjasama distribusi esim "BeliEsim" dan proposal jadwal pertemuan' summary="Peter, CEO dari Alterolabs, tertarik dengan sepeda baru 'BeliEsim' dan meminta brosur terperinci mengenai spesifikasi teknis, performa baterai, dan aspek desain. Peter juga mengusulkan pertemuan pada hari Selasa depan (15 Januari) pukul 10.00 di kantor Andy untuk mendiskusikan kemungkinan kerja sama." date='15 Januari, 10.00'
Membuat rantai dengan Parser yang ditambahkan
Anda dapat menghasilkan output sebagai objek Pydantic yang Anda tentukan.
# Tambahkan pengurai keluaran untuk merekonstruksi seluruh rantai.chain = prompt | llm | parser
# Chain dan cetak hasilnyaresponse = chain.invoke( {"email_conversation": email_conversation,"question": "Silakan ekstrak konten utama email.", })# Hasilnya adalah keluaran sebagai objek EmailSummary.response
{
"person": "Peter",
"email": "peter@alterolabs.com",
"subject": "Kerjasama distribusi esim \"BeliEsim\" dan proposal jadwal pertemuan",
"summary": "Peter, CEO dari Alterolabs, menghubungi Andy untuk meminta brosur terperinci tentang model BeliEsim dan mengusulkan pertemuan pada 15 Januari pukul 10.00 untuk membahas kemungkinan kerja sama.",
"date": "15 Januari pukul 10.00"
}
```
with_structured_output()
Anda dapat menambahkan pengurai keluaran menggunakan .with_structured_output(Pydantic)' untuk mengonversi keluaran menjadi objek Pydantic.
# Panggil fungsi invoke() untuk mencetak hasilnya.answer = llm_with_structered.invoke(email_conversation)answer
person='Peter' email='[email protected]' subject='Kerjasama distribusi esim "BeliEsim" dan proposal jadwal pertemuan' summary="Peter, CEO Alterolabs, menghubungi Andy untuk meminta brosur terperinci tentang sepeda 'BeliEsim' dan mengusulkan pertemuan pada 15 Januari pukul 10.00 untuk membahas kerja sama distribusi." date='15 Januari'
Catatan
Satu hal yang perlu diperhatikan adalah bahwa fungsi .with_structured_output() tidak mendukung fungsi stream().