08. RunnableWithMessageHistory
Menambahkan riwayat pesan (memori)
Memanfaatkan RunnableWithMessageHistory
untuk menambahkan riwayat pesan ke jenis tugas (rantai) tertentu adalah fitur yang sangat berguna dalam pemrograman.
Fitur ini sangat penting ketika mengimplementasikan aplikasi interaktif atau tugas pemrosesan data yang kompleks, di mana ada kebutuhan untuk mempertahankan konteks pesan sebelumnya.
Dengan mengelola riwayat pesan, pengembang dapat mengontrol aliran aplikasi dengan lebih baik dan merespons permintaan sebelumnya dari pengguna dengan tepat.
Contoh
- Mengembangkan chatbot percakapan: Sesuaikan respons chatbot berdasarkan riwayat dialog dengan pengguna.
- Pemrosesan data yang kompleks: Selama pemrosesan data, Anda dapat merujuk ke hasil dari langkah sebelumnya untuk menentukan logika langkah berikutnya.
- Aplikasi yang memerlukan manajemen status: Anda dapat mengingat pilihan pengguna sebelumnya dan memberikan layar atau informasi berikutnya yang sesuai.
RunnableWithMessageHistory adalah alat canggih yang memungkinkan Anda mempertahankan status aplikasi, meningkatkan pengalaman pengguna, dan mengimplementasikan mekanisme respons yang lebih canggih.
Tutorial
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai import ChatOpenAI
model = ChatOpenAI()
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"Anda adalah asisten yang mahir dalam {ability}. Harap jawab dalam 20 karakter atau kurang",
),
# menggunakan riwayat percakapan sebagai variabel, dengan riwayat sebagai kunci dari MessageHistory
MessagesPlaceholder(variable_name="history"),
("human", "{input}"), # gunakan masukan pengguna sebagai variabel
]
)
runnable = prompt | model # menggabungkan prompt dan model untuk membuat objek yang dapat dijalankan
Mengelola riwayat pesan sangat penting dalam aplikasi interaktif atau tugas pemrosesan data yang kompleks. Untuk mengelola riwayat pesan secara efektif, Anda memerlukan dua elemen utama
- Runnable: objek yang dapat dijalankan yang berinteraksi dengan BaseChatMessageHistory, terutama Retriever dan Chain.
- Objek yang dapat dipanggil yang mengembalikan sebuah instance dari
BaseChatMessageHistory
: Objek untuk mengelola riwayat pesan. Objek ini digunakan untuk menyimpan, mengambil, dan memperbarui riwayat pesan. Riwayat pesan diperlukan untuk menjaga konteks percakapan dan untuk menghasilkan respons berdasarkan masukan pengguna sebelumnya.
Ada banyak cara untuk mengimplementasikan riwayat pesan, dan halaman integrasi memori (opens in a new tab) menjelaskan berbagai pilihan penyimpanan dan integrasi.
Di sini kita akan melihat dua metode utama
Menggunakan ChatMessageHistory
dalam memori
Metode ini mengelola riwayat pesan dalam memori. Metode ini sering digunakan selama fase pengembangan atau dalam aplikasi sederhana. Metode in-memory menyediakan kecepatan akses yang cepat, tetapi kekurangannya adalah riwayat pesan akan hilang ketika aplikasi dimulai ulang.
Memanfaatkan penyimpanan persisten dengan RedisChatMessageHistory
Menggunakan Redis memungkinkan Anda untuk menyimpan riwayat pesan secara persisten. Redis merupakan penyimpanan struktur data dalam-memori berkinerja tinggi, bersumber terbuka, dan dapat diandalkan untuk mengelola riwayat pesan dalam lingkungan terdistribusi. Metode ini ideal untuk aplikasi yang kompleks atau layanan yang sudah berjalan lama.
Ketika memilih metode untuk mengelola riwayat pesan, Anda harus mempertimbangkan kebutuhan aplikasi Anda, jumlah lalu lintas yang Anda perkirakan, pentingnya data pesan, dan berapa lama Anda ingin menyimpannya. Metode dalam memori sederhana dan cepat untuk diimplementasikan, tetapi jika Anda memerlukan persistensi data, penyimpanan persisten seperti Redis mungkin lebih cocok.
Riwayat percakapan yang volatil: In-Memory.
Di bawah ini adalah contoh sederhana riwayat obrolan yang disimpan dalam memori.
Parameter pengaturan RunnableWithMessageHistory
Runnable
BaseChatMessageHistory
atau objek yang diwarisi. misalnyaChatMessageHistory
input_messages_key
: kunci untuk menentukan sebagai input kueri pengguna saat memanggil rantaihistory_messages_key
: kunci untuk menentukan sebagai riwayat percakapan
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
store = {} # Kamus untuk menyimpan riwayat sesi
# Fungsi untuk mengambil riwayat sesi berdasarkan ID sesi
def get_session_history(session_ids: str) -> BaseChatMessageHistory:
print(session_ids)
if session_ids not in store: # Jika ID sesi tidak ada di store
# Buat objek ChatMessageHistory baru dan simpan ke store
store[session_ids] = ChatMessageHistory()
return store[session_ids] # Kembalikan riwayat sesi untuk ID sesi tersebut
with_message_history = (
RunnableWithMessageHistory( # Buat objek RunnableWithMessageHistory
runnable, # Objek Runnable yang akan dijalankan
get_session_history, # Fungsi untuk mengambil riwayat sesi
input_messages_key="input", # Kunci untuk pesan input
history_messages_key="history", # Kunci untuk pesan riwayat
)
)
Input_messages_key
menentukan kunci yang akan diperlakukan sebagai pesan masukan terbaru, dan history_messages_key
menentukan kunci yang akan ditambahkan pesan lama.
Pada kode berikut, kita dapat melihat bahwa kunci session_id
dimasukkan sebagai Default pada nilai awal RunnableWithMessageHistory
, yang secara tidak langsung memberi tahu kita bahwa RunnableWithMessageHistory
mengelola utas dialog dengan session_id
.
Dengan kata lain, kita dapat melihat bahwa manajemen per-thread diimplementasikan oleh session_id
.
Lihat referensi kode: Implementasi RunnableWithMessageHistory
,
if history_factory_config:
_config_specs = history_factory_config
else:
# If not provided, then we'll use the default session_id field
_config_specs = [
ConfigurableFieldSpec(
id="session_id",
annotation=str,
name="Session ID",
description="Unique identifier for a session.",
default="",
is_shared=True,
),
]
Jadi, pada invoke()
, config = {“configurable”: {“session_id”: “Masukkan ID sesi"}}
Anda dapat melihat bahwa kita harus menentukan kode.
with_message_history.invoke(
# Mengirimkan pertanyaan terkait matematika "Apa arti dari kosinus?" sebagai input.
{"ability": "math", "input": "Apa itu kosinus?"},
# Mengirimkan ID sesi "abc123" sebagai informasi konfigurasi.
config={"configurable": {"session_id": "abc123"}},
)
abc123
content='Fungsi trigonometri.' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 8, 'prompt_tokens': 39, 'total_tokens': 47}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-c5a53d52-dcaa-4afd-a0f9-304a437f8199-0' usage_metadata={'input_tokens': 39, 'output_tokens': 8, 'total_tokens': 47}
Jika Anda memasukkan session_id
yang sama, Anda akan mendapatkan konten dari utas percakapan sebelumnya, sehingga Anda dapat melanjutkan percakapan!
# Memanggil dengan menyertakan riwayat pesan.
with_message_history.invoke(
# Menetapkan kemampuan dan input.
{"ability": "math", "input": "Tolong jawab dalam bahasa Inggris berdasarkan percakapan sebelumnya."},
# Menetapkan opsi konfigurasi.
config={"configurable": {"session_id": "abc123"}},
)
abc123
content='Trigonometry function.' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 5, 'prompt_tokens': 76, 'total_tokens': 81}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-db9473e7-c884-470a-a618-7088e91989d9-0' usage_metadata={'input_tokens': 76, 'output_tokens': 5, 'total_tokens': 81}
Namun, jika Anda menentukan session_id
yang berbeda, ia tidak akan menjawab dengan benar karena tidak ada riwayat percakapan.
(Pada contoh di bawah ini, Anda dapat melihat bahwa session_id: def234
memberikan jawaban yang salah karena tidak ada)
# Karena session_id baru, tidak mengingat percakapan sebelumnya.
with_message_history.invoke(
# Mengirimkan kemampuan matematika dan pesan input.
{"ability": "math", "input": "Tolong jawab dalam bahasa Inggris berdasarkan percakapan sebelumnya"},
# Menetapkan session_id baru.
config={"configurable": {"session_id": "def234"}},
)
def234
content='Sure, how can I help you?' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 8, 'prompt_tokens': 50, 'total_tokens': 58}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-23961fe3-af1b-4711-b0be-34b0a09b6aa4-0' usage_metadata={'input_tokens': 50, 'output_tokens': 8, 'total_tokens': 58}
Parameter konfigurasi yang digunakan untuk melacak riwayat pesan dapat disesuaikan dengan mengoper daftar objek ConfigurableFieldSpec
ke parameter history_factory_config
.
Pengaturan baru history_factory_config
ini akan menimpa pengaturan session_id
yang sudah ada.
Contoh di bawah ini menggunakan dua parameter: user_id
dan conversation_id
.
from langchain_core.runnables import ConfigurableFieldSpec
store = {} # Inisialisasi kamus kosong.
def get_session_history(user_id: str, conversation_id: str) -> BaseChatMessageHistory:
# Mengembalikan riwayat sesi yang sesuai dengan user_id dan conversation_id yang diberikan.
if (user_id, conversation_id) not in store:
# Jika kunci tersebut tidak ada di store, buat dan simpan ChatMessageHistory baru.
store[(user_id, conversation_id)] = ChatMessageHistory()
return store[(user_id, conversation_id)]
with_message_history = RunnableWithMessageHistory(
runnable,
get_session_history,
input_messages_key="input",
history_messages_key="history",
history_factory_config=[ # Ini akan menggantikan pengaturan "session_id" yang ada.
ConfigurableFieldSpec(
id="user_id", # Digunakan sebagai argumen pertama dari fungsi get_session_history.
annotation=str,
name="User ID",
description="Pengenal unik untuk pengguna.",
default="",
is_shared=True,
),
ConfigurableFieldSpec(
id="conversation_id", # Digunakan sebagai argumen kedua dari fungsi get_session_history.
annotation=str,
name="Conversation ID",
description="Pengenal unik untuk percakapan.",
default="",
is_shared=True,
),
],
)
with_message_history.invoke(
# Mengirimkan kamus yang berisi kemampuan (ability) dan input (input).
{"ability": "math", "input": "Hello"},
# Mengirimkan kamus konfigurasi (config).
config={"configurable": {"user_id": "123", "conversation_id": "1"}},
)
content='Hi! What can I help you with today?' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 34, 'total_tokens': 44}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-c22b0ab2-3ae8-474b-956a-615b6d0a2f04-0' usage_metadata={'input_tokens': 34, 'output_tokens': 10, 'total_tokens': 44}
Contoh penggunaan Runnable dengan berbagai keys.
Masukkan objek Pesan, keluarkan sebagai dictionary
Ini mengambil pesan sebagai masukan dan mengembalikan kamus sebagai keluaran.
- [Penting]: Hilangkan
input_messages_key
= “input”, yang akan mengaturnya untuk mengambil objek Pesan sebagai input.
from langchain_core.messages import HumanMessage
from langchain_core.runnables import RunnableParallel
# Membuat chain
chain = RunnableParallel({"output_message": ChatOpenAI()})
def get_session_history(session_id: str) -> BaseChatMessageHistory:
# Jika riwayat percakapan untuk session ID tidak ada di penyimpanan, buat ChatMessageHistory baru.
if session_id not in store:
store[session_id] = ChatMessageHistory()
# Kembalikan riwayat percakapan untuk session ID yang diberikan.
return store[session_id]
# Membuat objek RunnableWithMessageHistory yang menambahkan fungsi riwayat percakapan ke dalam chain.
with_message_history = RunnableWithMessageHistory(
chain,
get_session_history,
# Mengatur kunci pesan input ke "input". (Diabaikan jika input berupa objek Message)
# input_messages_key="input",
# Mengatur kunci pesan output ke "output_message". (Diabaikan jika output berupa objek Message)
output_messages_key="output_message",
)
# Menjalankan chain dengan pesan dan konfigurasi yang diberikan.
with_message_history.invoke(
# Atau bisa juga menggunakan "what is the definition of cosine?"
[HumanMessage(content="Apa definisi dari kosinus?")],
config={"configurable": {"session_id": "abc123"}},
)
{'output_message': AIMessage(content='Kosinus adalah fungsi trigonometri yang merupakan rasio panjang sisi sejajar dengan sudut dalam sebuah segitiga siku-siku terhadap panjang sisi miring segitiga tersebut. Dalam matematika, kosinus sering dilambangkan dengan simbol "cos".', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 66, 'prompt_tokens': 15, 'total_tokens': 81}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-9fe92482-e149-4a32-b1b1-4243ad69a9d7-0', usage_metadata={'input_tokens': 15, 'output_tokens': 66, 'total_tokens': 81})}
with_message_history.invoke(
# Meminta ulang jawaban sebelumnya dalam bahasa Korea.
[HumanMessage(content="Tolong jawab dalam bahasa Inggris berdasarkan pertanyaan sebelumnya!")],
# Mengirimkan opsi konfigurasi dalam bentuk kamus.
config={"configurable": {"session_id": "abc123"}},
)
{'output_message': AIMessage(content='Cosine is a mathematical function that measures the ratio of the length of the adjacent side to the length of the hypotenuse in a right triangle. In trigonometry, the cosine of a specific angle in a right triangle is defined as the length of the adjacent side to that angle divided by the length of the hypotenuse of the triangle.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 70, 'prompt_tokens': 141, 'total_tokens': 211}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-2a4115e8-91a4-4100-9b6e-98459b83dd0a-0', usage_metadata={'input_tokens': 141, 'output_tokens': 70, 'total_tokens': 211})}
Memasukkan objek Pesan, mengeluarkan objek Pesan
[Penting]: output_messages_key
= “output_message”, yang akan mengembalikan objek Message sebagai output.
with_message_history = RunnableWithMessageHistory(
ChatOpenAI(), # Menggunakan model bahasa ChatOpenAI.
get_session_history, # Menetapkan fungsi untuk mengambil riwayat sesi percakapan.
# Mengatur kunci pesan input ke "input". (Diabaikan jika input berupa objek Message)
# input_messages_key="input",
# Mengatur kunci pesan output ke "output_message". (Diabaikan jika output berupa objek Message)
# output_messages_key="output_message",
)
with_message_history.invoke(
# Meminta ulang jawaban dalam bahasa Korea berdasarkan percakapan sebelumnya.
[HumanMessage(content="Apa arti dari kosinus?")],
# Mengirimkan opsi konfigurasi dalam bentuk kamus.
config={"configurable": {"session_id": "def123"}},
)
content='Kosinus adalah fungsi matematika yang menghasilkan nilai rasio dari panjang sisi sejajar terhadap panjang sisi miring pada segitiga siku-siku. Dalam trigonometri, kosinus dari suatu sudut dalam sebuah segitiga siku-siku adalah nilai rasio antara panjang sisi sejajar dengan sudut tersebut terhadap panjang sisi miring segitiga. Kosinus biasanya dilambangkan dengan simbol cos.' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 107, 'prompt_tokens': 15, 'total_tokens': 122}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-ea96a85b-3072-4c4a-81a0-5ede74b6b4f0-0' usage_metadata={'input_tokens': 15, 'output_tokens': 107, 'total_tokens': 122}
Dict dengan satu key untuk semua input dan output pesan
Pendekatan ini menggunakan satu kunci untuk semua pesan masukan dan pesan keluaran.
- Gunakan
itemgetter(“input_messages”)
untuk mengekstrak pesan masukan.
from operator import itemgetter
with_message_history = RunnableWithMessageHistory(
# Menggunakan kunci "input_messages" untuk mengambil pesan input dan mengirimkannya ke ChatOpenAI().
itemgetter("input_messages") | ChatOpenAI(),
get_session_history, # Fungsi untuk mengambil riwayat sesi.
input_messages_key="input_messages", # Menetapkan kunci untuk pesan input.
)
with_message_history.invoke(
{"input_messages": "Apa arti dari kosinus?"},
# Mengirimkan opsi konfigurasi dalam bentuk kamus.
config={"configurable": {"session_id": "xyz123"}},
)
content='Kosinus adalah sebuah fungsi matematika yang menghasilkan nilai rasio dari panjang sisi sejajar dengan sudut tertentu dalam segitiga siku-siku, dibagi dengan panjang sisi miring segitiga tersebut. Kosinus digunakan dalam trigonometri untuk menghitung panjang sisi segitiga dan sudut-sudutnya.' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 82, 'prompt_tokens': 15, 'total_tokens': 97}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-89eaedc8-3ab3-4f73-bac9-e0743eb68b47-0' usage_metadata={'input_tokens': 15, 'output_tokens': 82, 'total_tokens': 97}
Persistent Storage
Penyimpanan persisten mengacu pada mekanisme penyimpanan yang mempertahankan data bahkan ketika sebuah program dihentikan atau sistem di-boot ulang. Hal ini dapat diimplementasikan melalui database, sistem file, atau perangkat penyimpanan non-volatile lainnya.
Penyimpanan persisten sangat penting untuk menyimpan status aplikasi, mempertahankan pengaturan pengguna, dan menyimpan data untuk jangka waktu yang lama. Hal ini memungkinkan program untuk melanjutkan dari tempat yang ditinggalkannya pada proses sebelumnya, dan memungkinkan pengguna untuk terus bekerja tanpa kehilangan data.
RunnableWithMessageHistory
tidak bergantung pada cara pemanggilanget_session_history
untuk mengambil riwayat pesan obrolan.- Lihat di sini untuk contoh penggunaan sistem berkas lokal. https://github.com/langchain-ai/langserve/blob/main/examples/chat_with_persistence_and_user/server.py (opens in a new tab)
- Di bawah ini kami tunjukkan cara menggunakan Redis. Untuk mengetahui cara mengimplementasikan riwayat pesan obrolan menggunakan penyedia lain, lihat halaman integrasi memori (opens in a new tab).
Menginstall Redis
Jika Anda belum menginstal Redis, Anda harus menginstalnya terlebih dahulu.
pip install -qU redis
Menjalankan server Redis
Jika Anda tidak memiliki penerapan Redis yang sudah ada untuk disambungkan, mulai server Redis Stack lokal.
Berikut ini adalah perintah untuk memulai server Redis dengan Docker.
docker run -d -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
Tetapkan URL koneksi basis data Redis ke variabel REDIS_URL
.
- URL ditetapkan ke “
redis://localhost:6379/0
”.
# Tentukan URL server Redis.
REDIS_URL = "redis://localhost:6379/0"
Menyiapkan pelacakan LangSmith
Siapkan LangSmith untuk pelacakan. LangSmith tidak diperlukan, tetapi dapat membantu.
from dotenv import load_dotenv
import os
load_dotenv()
# Tetapkan variabel lingkungan LANGCHAIN_TRACING_V2 ke “true”.
os.environ["LANGCHAIN_TRACING_V2"] = "true"
# Mengatur LANGCHAIN_PROJECT
os.environ["LANGCHAIN_PROJECT"] = "RunnableWithMessageHistory"
Untuk memperbarui implementasi riwayat pesan, cukup definisikan objek baru yang dapat dipanggil, kali ini mengembalikan sebuah instance RedisChatMessageHistory.
from langchain_community.chat_message_histories import RedisChatMessageHistory
def get_message_history(session_id: str) -> RedisChatMessageHistory:
# Mengembalikan objek RedisChatMessageHistory berdasarkan session ID.
return RedisChatMessageHistory(session_id, url=REDIS_URL)
with_message_history = RunnableWithMessageHistory(
runnable, # Objek yang dapat dijalankan
get_message_history, # Fungsi untuk mengambil riwayat pesan
input_messages_key="input", # Kunci untuk pesan input
history_messages_key="history", # Kunci untuk pesan riwayat
)
Anda dapat memanggilnya dengan cara yang sama seperti sebelumnya.
with_message_history.invoke(
# Mengirimkan pertanyaan terkait matematika "Apa arti dari kosinus?" sebagai input.
{"ability": "math", "input": "Apa arti dari kosinus?"},
# Menetapkan session ID menjadi "redis123" sebagai opsi konfigurasi.
config={"configurable": {"session_id": "redis123"}},
)
content='Trigonometri fungsi.' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 7, 'prompt_tokens': 41, 'total_tokens': 48}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-1e5c490f-7406-406b-aaaa-f901750bd333-0' usage_metadata={'input_tokens': 41, 'output_tokens': 7, 'total_tokens': 48}
Lakukan panggilan kedua dengan menggunakan session_id
yang sama. Kali ini, kami akan meminta jawaban sebelumnya dalam bahasa Korea.
with_message_history.invoke(
# Meminta terjemahan jawaban sebelumnya ke dalam bahasa Korea.
{"ability": "math", "input": "Tolong terjemahkan jawaban sebelumnya ke dalam bahasa Korea."},
# Menetapkan session ID menjadi "redis123" sebagai nilai konfigurasi.
config={"configurable": {"session_id": "redis123"}},
)
content='Trigonometry function.' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 5, 'prompt_tokens': 75, 'total_tokens': 80}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-c666e30b-9bf0-472e-8d4e-6679bfe2b539-0' usage_metadata={'input_tokens': 75, 'output_tokens': 5, 'total_tokens': 80}
Kali ini, kita akan mengajukan pertanyaan dengan menggunakan session_id yang berbeda.
with_message_history.invoke(
# Meminta terjemahan jawaban sebelumnya ke dalam bahasa Korea.
{"ability": "math", "input": "Tolong terjemahkan jawaban sebelumnya ke dalam bahasa Korea."},
# Menetapkan session ID menjadi "redis456" sebagai nilai konfigurasi.
config={"configurable": {"session_id": "redis456"}},
)
content='Translate the previous answer into English.' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 7, 'prompt_tokens': 52, 'total_tokens': 59}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-69c3e6a1-4cbc-4e7f-bf13-8285cb9fc617-0' usage_metadata={'input_tokens': 52, 'output_tokens': 7, 'total_tokens': 59}
Yang terakhir ini tidak memiliki riwayat percakapan sebelumnya, jadi Anda tidak akan mendapatkan jawaban yang tepat.