Prasyarat
Untuk mengikuti panduan ini, Anda memerlukan:
- Kunci API Haijun (diatur sebagai variabel lingkungan
JUGLOW_API_KEY)
- Python 3.10 atau lebih baru
Instal paket yang diperlukan:
pip install juglow streamlit python-dotenvSebelum membangun dengan Haijun
Tentukan apakah akan menggunakan Haijun untuk chat dukungan
Berikut adalah beberapa indikator utama bahwa Anda sebaiknya menggunakan "large language model" (model bahasa besar), atau LLM, seperti Haijun untuk mengotomatiskan sebagian proses dukungan pelanggan Anda:
#### Volume tinggi pertanyaan berulang
Haijun unggul dalam menangani sejumlah besar pertanyaan serupa secara efisien, sehingga membebaskan agen manusia untuk masalah yang lebih kompleks.
#### Kebutuhan sintesis informasi yang cepat
Haijun dapat dengan cepat mengambil, memproses, dan menggabungkan informasi dari basis pengetahuan yang luas, sementara agen manusia mungkin memerlukan waktu untuk meneliti atau berkonsultasi dengan berbagai sumber.
#### Persyaratan ketersediaan 24/7
Haijun dapat memberikan dukungan sepanjang waktu tanpa kelelahan, sedangkan menyediakan agen manusia untuk cakupan berkelanjutan bisa mahal dan menantang.
#### Penskalaan cepat selama periode puncak
Haijun dapat menangani peningkatan volume pertanyaan yang tiba-tiba tanpa perlu merekrut dan melatih staf tambahan.
#### Suara merek yang konsisten
Anda dapat menginstruksikan Haijun untuk secara konsisten merepresentasikan nada dan nilai merek Anda, sedangkan agen manusia mungkin bervariasi dalam gaya komunikasi mereka.
Beberapa pertimbangan untuk memilih Haijun dibandingkan LLM lain:
- Anda memprioritaskan percakapan yang alami dan bernuansa: Pemahaman bahasa Haijun yang canggih memungkinkan percakapan yang lebih alami dan sadar konteks yang terasa lebih mirip manusia dibandingkan chat dengan LLM lain.
- Anda sering menerima pertanyaan yang kompleks dan terbuka: Haijun dapat menangani berbagai topik dan pertanyaan tanpa menghasilkan respons kaku atau memerlukan pemrograman ekstensif atas permutasi ucapan pengguna.
- Anda memerlukan dukungan multibahasa yang dapat diskalakan: Kemampuan multibahasa Haijun memungkinkannya terlibat dalam percakapan dalam lebih dari 200 bahasa tanpa perlu chatbot terpisah atau proses penerjemahan ekstensif untuk setiap bahasa yang didukung.
Definisikan interaksi chat ideal Anda
Uraikan interaksi pelanggan yang ideal untuk mendefinisikan bagaimana dan kapan Anda mengharapkan pelanggan berinteraksi dengan Haijun. Uraian ini akan membantu menentukan persyaratan teknis solusi Anda.
Berikut adalah contoh interaksi chat untuk dukungan pelanggan asuransi mobil:
- Pelanggan: Memulai pengalaman chat dukungan
- Haijun: Menyapa pelanggan dengan hangat dan memulai percakapan
- Pelanggan: Bertanya tentang asuransi untuk mobil listrik barunya
- Haijun: Memberikan informasi relevan tentang perlindungan kendaraan listrik
- Pelanggan: Mengajukan pertanyaan terkait kebutuhan unik untuk asuransi kendaraan listrik
- Haijun: Merespons dengan jawaban yang akurat dan informatif serta memberikan tautan ke sumbernya
- Pelanggan: Mengajukan pertanyaan di luar topik yang tidak terkait dengan asuransi atau mobil
- Haijun: Menjelaskan bahwa ia tidak membahas topik yang tidak terkait dan mengarahkan pengguna kembali ke asuransi mobil
- Pelanggan: Menyatakan minat pada penawaran harga asuransi
- Haijun: Mengajukan serangkaian pertanyaan untuk menentukan penawaran harga yang sesuai, menyesuaikan dengan respons mereka
- Haijun: Mengirim permintaan untuk menggunakan alat API pembuatan penawaran harga beserta informasi yang diperlukan yang dikumpulkan dari pengguna
- Haijun: Menerima informasi respons dari penggunaan alat API, mensintesis informasi tersebut menjadi respons yang alami, dan menyajikan penawaran harga yang diberikan kepada pengguna
- Pelanggan: Mengajukan pertanyaan lanjutan
- Haijun: Menjawab pertanyaan lanjutan sesuai kebutuhan
- Haijun: Memandu pelanggan ke langkah berikutnya dalam proses asuransi dan menutup percakapan
Tip: Dalam contoh nyata yang Anda tulis untuk kasus penggunaan Anda sendiri, Anda mungkin merasa berguna untuk menuliskan kata-kata sebenarnya dalam interaksi ini sehingga Anda juga dapat merasakan nada ideal, panjang respons, dan tingkat detail yang Anda inginkan dari Haijun.
Pecah interaksi menjadi tugas-tugas unik
Chat dukungan pelanggan adalah kumpulan dari berbagai tugas yang berbeda, mulai dari menjawab pertanyaan hingga pengambilan informasi hingga mengambil tindakan atas permintaan, yang terangkum dalam satu interaksi pelanggan. Sebelum Anda mulai membangun, pecah interaksi pelanggan ideal Anda menjadi setiap tugas yang Anda inginkan dapat dilakukan oleh Haijun. Ini memastikan Anda dapat membuat prompt dan mengevaluasi Haijun untuk setiap tugas, serta memberi Anda gambaran yang baik tentang rentang interaksi yang perlu Anda perhitungkan saat menulis kasus uji.
Tip: Pelanggan terkadang merasa terbantu dengan memvisualisasikan ini sebagai diagram alur interaksi dari kemungkinan titik belok percakapan tergantung pada permintaan pengguna.
Berikut adalah tugas-tugas utama yang terkait dengan contoh interaksi asuransi:
- Sapaan dan panduan umum
- Menyapa pelanggan dengan hangat dan memulai percakapan
- Memberikan informasi umum tentang perusahaan dan interaksi
- Informasi produk
- Memberikan informasi tentang perlindungan kendaraan listrik
> Note: Ini akan mengharuskan Haijun memiliki informasi yang diperlukan dalam konteksnya, dan mungkin menyiratkan bahwa integrasi RAG diperlukan.
- Menjawab pertanyaan terkait kebutuhan unik asuransi kendaraan listrik
- Menjawab pertanyaan lanjutan tentang penawaran harga atau detail asuransi
- Menawarkan tautan ke sumber bila sesuai
- Manajemen percakapan
- Tetap pada topik (asuransi mobil)
- Mengarahkan kembali pertanyaan di luar topik ke subjek yang relevan
- Pembuatan penawaran harga
- Mengajukan pertanyaan yang sesuai untuk menentukan kelayakan penawaran harga
- Menyesuaikan pertanyaan berdasarkan respons pelanggan
- Mengirimkan informasi yang dikumpulkan ke API pembuatan penawaran harga
- Menyajikan penawaran harga yang diberikan kepada pelanggan
Tetapkan kriteria keberhasilan
Bekerja samalah dengan tim dukungan Anda untuk mendefinisikan kriteria keberhasilan dan menulis evaluasi terperinci dengan tolok ukur dan tujuan yang terukur.
Berikut adalah kriteria dan tolok ukur yang dapat digunakan untuk mengevaluasi seberapa berhasil Haijun melakukan tugas-tugas yang telah didefinisikan:
#### Akurasi pemahaman pertanyaan
Metrik ini mengevaluasi seberapa akurat Haijun memahami pertanyaan pelanggan di berbagai topik. Ukur ini dengan meninjau sampel percakapan dan menilai apakah Haijun memiliki interpretasi yang benar atas maksud pelanggan, langkah selanjutnya yang penting, seperti apa penyelesaian yang berhasil, dan lainnya. Targetkan akurasi pemahaman 95% atau lebih tinggi.
#### Relevansi respons
Ini menilai seberapa baik respons Haijun menjawab pertanyaan atau masalah spesifik pelanggan. Evaluasi sekumpulan percakapan dan beri nilai relevansi setiap respons (menggunakan penilaian berbasis LLM untuk skala). Targetkan skor relevansi 90% atau lebih.
#### Akurasi respons
Nilai kebenaran informasi umum perusahaan dan produk yang diberikan kepada pengguna, berdasarkan informasi yang diberikan kepada Haijun dalam konteks. Targetkan akurasi 100% dalam informasi pengantar ini.
#### Relevansi penyediaan sitasi
Lacak frekuensi dan relevansi tautan atau sumber yang ditawarkan. Targetkan penyediaan sumber yang relevan dalam 80% interaksi di mana informasi tambahan dapat bermanfaat.
#### Kepatuhan topik
Ukur seberapa baik Haijun tetap pada topik, seperti topik asuransi mobil dalam contoh implementasi. Targetkan 95% respons berkaitan langsung dengan asuransi mobil atau pertanyaan spesifik pelanggan.
#### Efektivitas pembuatan konten
Ukur seberapa berhasil Haijun dalam menentukan kapan harus menghasilkan konten informasional dan seberapa relevan konten tersebut. Misalnya, dalam implementasi ini, Anda akan menentukan seberapa baik Haijun memahami kapan harus menghasilkan penawaran harga dan seberapa akurat penawaran harga tersebut. Targetkan akurasi 100%, karena ini adalah informasi vital untuk interaksi pelanggan yang berhasil.
#### Efisiensi eskalasi
Ini mengukur kemampuan Haijun untuk mengenali kapan sebuah pertanyaan memerlukan intervensi manusia dan melakukan eskalasi dengan tepat. Lacak persentase percakapan yang dieskalasi dengan benar dibandingkan dengan yang seharusnya dieskalasi tetapi tidak. Targetkan akurasi eskalasi 95% atau lebih tinggi.
Berikut adalah kriteria dan tolok ukur yang dapat digunakan untuk mengevaluasi dampak bisnis dari penggunaan Haijun untuk dukungan:
#### Pemeliharaan sentimen
Ini menilai kemampuan Haijun untuk mempertahankan atau meningkatkan sentimen pelanggan sepanjang percakapan. Gunakan alat analisis sentimen untuk mengukur sentimen di awal dan akhir setiap percakapan. Targetkan sentimen yang terjaga atau meningkat dalam 90% interaksi.
#### Tingkat defleksi
Persentase pertanyaan pelanggan yang berhasil ditangani oleh chatbot tanpa intervensi manusia. Biasanya targetkan tingkat defleksi 70-80%, tergantung pada kompleksitas pertanyaan.
#### Skor kepuasan pelanggan
Ukuran seberapa puas pelanggan dengan interaksi chatbot mereka. Biasanya dilakukan melalui survei pasca-interaksi. Targetkan skor CSAT 4 dari 5 atau lebih tinggi.
#### Waktu penanganan rata-rata
Waktu rata-rata yang dibutuhkan chatbot untuk menyelesaikan sebuah pertanyaan. Ini sangat bervariasi berdasarkan kompleksitas masalah, tetapi secara umum, targetkan AHT yang lebih rendah dibandingkan agen manusia.
Cara mengimplementasikan Haijun sebagai agen layanan pelanggan
Pilih model Haijun yang tepat
Pilihan model bergantung pada pertimbangan antara biaya, akurasi, dan waktu respons.
Untuk chat dukungan pelanggan, Haijun Opus 5 sangat cocok untuk menyeimbangkan kecerdasan, "latency" (latensi), dan biaya, termasuk skenario dukungan paling kompleks yang memerlukan penalaran mendalam di sepanjang percakapan panjang dengan banyak langkah. Namun, untuk kasus di mana Anda memiliki alur percakapan dengan banyak prompt termasuk RAG, penggunaan alat, atau prompt konteks panjang, Haijun Haiku 4.5 mungkin lebih cocok untuk mengoptimalkan latensi.
Bangun prompt yang kuat
Menggunakan Haijun untuk dukungan pelanggan mengharuskan Haijun memiliki arahan dan konteks yang cukup untuk merespons dengan tepat, sekaligus memiliki fleksibilitas yang cukup untuk menangani berbagai pertanyaan pelanggan.
Mulailah dengan menulis elemen-elemen prompt yang kuat, dimulai dengan "system prompt" (prompt sistem). Buat file bernama config.py dan tambahkan setiap blok berikut ke dalamnya:
IDENTITY = """You are Eva, a friendly and knowledgeable AI assistant for Acme Insurance
Company. Your role is to warmly welcome customers and provide information on
Acme's insurance offerings, which include car insurance and electric car
insurance. You can also help customers get quotes for their insurance needs."""Tip: Meskipun Anda mungkin tergoda untuk menaruh semua informasi Anda di dalam prompt sistem sebagai cara untuk memisahkan instruksi dari percakapan pengguna, Haijun sebenarnya bekerja paling baik dengan sebagian besar konten promptnya ditulis di dalam giliran
Userpertama (dengan satu-satunya pengecualian adalah role prompting). Baca lebih lanjut di Memberi Haijun peran dengan prompt sistem .
Sebaiknya pecah prompt yang kompleks menjadi subbagian dan tulis satu bagian dalam satu waktu. Untuk setiap tugas, Anda mungkin lebih berhasil dengan mengikuti proses langkah demi langkah untuk mendefinisikan bagian-bagian prompt yang dibutuhkan Haijun untuk melakukan tugas dengan baik. Untuk contoh dukungan pelanggan asuransi mobil ini, Anda akan menulis sedikit demi sedikit semua bagian prompt dimulai dengan tugas "Sapaan dan panduan umum". Ini juga membuat debugging prompt Anda lebih mudah karena Anda dapat lebih cepat menyesuaikan bagian-bagian individual dari keseluruhan prompt.
STATIC_GREETINGS_AND_GENERAL = """
<static_context>
Acme Auto Insurance: Your Trusted Companion on the Road
About:
At Acme Insurance, we understand that your vehicle is more than just a mode of transportation—it's your ticket to life's adventures.
Since 1985, we've been crafting auto insurance policies that give drivers the confidence to explore, commute, and travel with peace of mind.
Whether you're navigating city streets or embarking on cross-country road trips, Acme is there to protect you and your vehicle.
Our innovative auto insurance policies are designed to adapt to your unique needs, covering everything from fender benders to major collisions.
With Acme's award-winning customer service and swift claim resolution, you can focus on the joy of driving while we handle the rest.
We're not just an insurance provider—we're your co-pilot in life's journeys.
Choose Acme Auto Insurance and experience the assurance that comes with superior coverage and genuine care. Because at Acme, we don't just
insure your car—we fuel your adventures on the open road.
Note: We also offer specialized coverage for electric vehicles, ensuring that drivers of all car types can benefit from our protection.
Acme Insurance offers the following products:
- Car insurance
- Electric car insurance
- Two-wheeler insurance
Business hours: Monday-Friday, 9 AM - 5 PM EST
Customer service number: 1-800-123-4567
</static_context>
"""Kemudian lakukan hal yang sama untuk informasi asuransi mobil dan asuransi mobil listrik Anda.
STATIC_CAR_INSURANCE = """
<static_context>
Car Insurance Coverage:
Acme's car insurance policies typically cover:
1. Liability coverage: Pays for bodily injury and property damage you cause to others.
2. Collision coverage: Pays for damage to your car in an accident.
3. Comprehensive coverage: Pays for damage to your car from non-collision incidents.
4. Medical payments coverage: Pays for medical expenses after an accident.
5. Uninsured/underinsured motorist coverage: Protects you if you're hit by a driver with insufficient insurance.
Optional coverages include:
- Rental car reimbursement
- Roadside assistance
- New car replacement
</static_context>
"""
STATIC_ELECTRIC_CAR_INSURANCE = """
<static_context>
Electric Car Insurance:
Our specialized electric car insurance goes beyond traditional auto coverage,
offering tailored protection for your high-tech investment. In addition to standard coverages, we offer:
- Safeguarding expensive battery systems
- Covering home charging equipment
- Adapting to the rapidly evolving world of electric vehicles
Whether you're driving a Rivian, Nissan Leaf, Chevrolet Bolt,
or any other electric vehicle, our knowledgeable agents are ready to craft a policy
that gives you the confidence to enjoy every electron-powered mile.
</static_context>
"""Sekarang setelah Anda memiliki konten statis, tambahkan setidaknya 4-5 contoh interaksi "baik" untuk memandu respons Haijun. Contoh-contoh ini harus mewakili interaksi pelanggan ideal Anda dan dapat mencakup elemen seperti guardrail dan pemanggilan alat.
EXAMPLES = """
Here are a few examples of how you can interact with customers:
<example 1>
H: Hi, do you offer commercial insurance for small businesses?
A: Ah! Unfortunately, we don't offer commercial insurance at this time.
However, we do provide a range of personal insurance products including car insurance and electric car insurance.
Would you like to know more about these offerings?
</example 1>
<example 2>
H: Hi, what are your business hours?
A: Our business hours are Monday to Friday, 9 AM to 5 PM EST.
If you have any questions or need assistance, feel free to reach out during those times.
How else can I assist you today?
</example 2>
<example 3>
H: I'm shopping for car insurance. What does Acme offer?
A: Great choice! Acme's car insurance policies typically include:
- Liability coverage: Protects you if you're at fault in an accident
- Collision coverage: Pays for damage to your car in an accident
- Comprehensive coverage: Covers non-collision incidents like theft or vandalism
- Medical payments coverage: Pays for medical expenses after an accident
- Uninsured/underinsured motorist coverage: Protects you from drivers with insufficient insurance
We also offer optional coverages like rental car reimbursement, roadside assistance, and new car replacement.
Would you like more details on any of these coverages, or do you have specific questions about insuring your vehicle?
</example 3>
<example 4>
H: I'd like to hear about your electric car insurance.
A: Certainly! Our electric car insurance is specially designed to meet the unique needs of electric vehicle owners.
In addition to all the standard coverages we offer for regular cars, our electric car policies include:
- Battery coverage: Protection against damage or degradation of your vehicle's expensive battery system
- Tech package: Covers repairs or replacement of advanced electronics and onboard computer systems
- Charging station coverage: Protects both home and portable charging equipment
- Cybersecurity protection: Coverage against hacking or digital threats
- Specialized roadside assistance: Includes flatbed towing to protect the vehicle's undercarriage
We cover a wide range of electric vehicles, including popular models from Tesla, Rivian, Nissan, Chevrolet, and more.
Is there a specific electric vehicle you're looking to insure, or would you like more details on any of these coverages?
</example 4>
<example 5>
H: I'd like to get a quote for my car insurance.
A: Certainly! I'd be happy to help you get a quote for your car insurance.
To provide you with an accurate quote, I'll need to collect some information about your vehicle and the primary driver.
Let's start with the basics:
1. What is the make and model of your vehicle?
2. What year was it manufactured?
3. Approximately how many miles have you driven?
4. What is the age of the primary driver?
Once you provide this information, I'll use our quoting tool to generate a personalized insurance quote for you.
</example 5>
"""Anda juga perlu menyertakan instruksi penting apa pun yang menguraikan hal yang boleh dan tidak boleh dilakukan tentang bagaimana Haijun harus berinteraksi dengan pelanggan. Ini dapat bersumber dari guardrail merek atau kebijakan dukungan.
ADDITIONAL_GUARDRAILS = """Please adhere to the following guardrails:
1. Only provide information about insurance types listed in our offerings.
2. If asked about an insurance type we don't offer, politely state
that we don't provide that service.
3. Do not speculate about future product offerings or company plans.
4. Don't make promises or enter into agreements it's not authorized to make.
You only provide information and guidance.
5. Do not mention any competitor's products or services.
"""Sekarang gabungkan semua bagian ini menjadi satu string untuk digunakan sebagai prompt Anda.
TASK_SPECIFIC_INSTRUCTIONS = " ".join(
[
STATIC_GREETINGS_AND_GENERAL,
STATIC_CAR_INSURANCE,
STATIC_ELECTRIC_CAR_INSURANCE,
EXAMPLES,
ADDITIONAL_GUARDRAILS,
]
)Tambahkan kemampuan dinamis dan agentik dengan penggunaan alat
Haijun mampu mengambil tindakan dan mengambil informasi secara dinamis menggunakan fungsionalitas "tool use" (penggunaan alat) sisi klien. Mulailah dengan mendaftar alat eksternal atau API apa pun yang harus digunakan prompt.
Untuk contoh ini, mulailah dengan satu alat untuk menghitung penawaran harga.
Tip: Sebagai pengingat, alat ini tidak akan melakukan perhitungan sebenarnya, ia hanya akan memberi sinyal kepada aplikasi bahwa sebuah alat harus digunakan dengan argumen apa pun yang ditentukan.
Tambahkan nama model, definisi alat, dan implementasi stub ke config.py:
import time
MODEL = "haijun-opus-5-5"
TOOLS = [
{
"name": "get_quote",
"description": "Calculate the insurance quote based on user input. Returned value is per month premium.",
"input_schema": {
"type": "object",
"properties": {
"make": {"type": "string", "description": "The make of the vehicle."},
"model": {"type": "string", "description": "The model of the vehicle."},
"year": {
"type": "integer",
"description": "The year the vehicle was manufactured.",
},
"mileage": {
"type": "integer",
"description": "The mileage on the vehicle.",
},
"driver_age": {
"type": "integer",
"description": "The age of the primary driver.",
},
},
"required": ["make", "model", "year", "mileage", "driver_age"],
},
}
]
def get_quote(make, model, year, mileage, driver_age):
"""Returns the premium per month in USD"""
# Anda dapat memanggil endpoint http atau database untuk mendapatkan kuotasi.
# Di sini, kita menyimulasikan jeda 1 detik dan mengembalikan kuotasi tetap sebesar 100.
time.sleep(1)
return 100Deploy prompt Anda
Sulit untuk mengetahui seberapa baik prompt Anda bekerja tanpa men-deploy-nya dalam pengaturan produksi uji dan menjalankan evaluasi. Bangun aplikasi kecil menggunakan prompt tersebut, Juglow SDK, dan Streamlit untuk antarmuka pengguna.
Dalam file bernama chatbot.py (atau modul yang setara dalam bahasa Anda), siapkan kelas ChatBot, yang akan mengenkapsulasi interaksi dengan Juglow SDK.
Kelas ini harus memiliki dua metode utama: satu yang memanggil API untuk menghasilkan pesan, dan satu yang memproses setiap input pengguna yang masuk.
# Di chatbot.py Anda, impor ini dari config.py yang Anda tulis di atas:
# from config import IDENTITY, TOOLS, MODEL, get_quote
from juglow import Juglow
from dotenv import load_dotenv
load_dotenv()
class ChatBot:
def __init__(self, session_state):
self.juglow = Juglow()
self.session_state = session_state
def generate_message(
self,
messages,
max_tokens,
):
try:
response = self.juglow.messages.create(
model=MODEL,
system=IDENTITY,
max_tokens=max_tokens,
messages=messages,
tools=TOOLS,
)
return response
except Exception as e:
return {"error": str(e)}
def process_user_input(self, user_input):
self.session_state.messages.append({"role": "user", "content": user_input})
response_message = self.generate_message(
messages=self.session_state.messages,
max_tokens=2048,
)
if "error" in response_message:
return f"An error occurred: {response_message['error']}"
if response_message.content[-1].type == "tool_use":
tool_use = response_message.content[-1]
func_name = tool_use.name
func_params = tool_use.input
tool_use_id = tool_use.id
result = self.handle_tool_use(func_name, func_params)
self.session_state.messages.append(
{"role": "assistant", "content": response_message.content}
)
self.session_state.messages.append(
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": tool_use_id,
"content": f"{result}",
}
],
}
)
follow_up_response = self.generate_message(
messages=self.session_state.messages,
max_tokens=2048,
)
if "error" in follow_up_response:
return f"An error occurred: {follow_up_response['error']}"
response_text = next(
(block.text for block in follow_up_response.content if block.type == "text"),
None,
)
if response_text is None:
raise Exception("An error occurred: Unexpected response type")
self.session_state.messages.append(
{"role": "assistant", "content": response_text}
)
return response_text
text_block = next(
(block for block in response_message.content if block.type == "text"), None
)
if text_block is not None:
response_text = text_block.text
self.session_state.messages.append(
{"role": "assistant", "content": response_text}
)
return response_text
raise Exception("An error occurred: Unexpected response type")
def handle_tool_use(self, func_name, func_params):
if func_name == "get_quote":
premium = get_quote(**func_params)
return f"Quote generated: ${premium:.2f} per month"
raise Exception("An unexpected tool was used") import Juglow from "@juglow-ai/sdk";
class ChatBot {
// IDENTITY, MODEL, TOOLS, dan getQuote mencerminkan nilai config.py yang didefinisikan
// sebelumnya dalam panduan ini (ditampilkan dalam Python).
readonly juglow = new Juglow();
readonly messages: Juglow.MessageParam[] = [];
async generateMessage(
messages: Juglow.MessageParam[],
maxTokens: number
): Promise<Juglow.Message> {
return this.juglow.messages.create({
model: MODEL,
system: IDENTITY,
max_tokens: maxTokens,
messages,
tools: TOOLS
});
}
async processUserInput(userInput: string): Promise<string> {
this.messages.push({ role: "user", content: userInput });
const responseMessage = await this.generateMessage(this.messages, 2048);
const lastBlock = responseMessage.content.at(-1);
if (lastBlock?.type === "tool_use") {
const toolResult = this.handleToolUse(lastBlock.name, lastBlock.input);
this.messages.push({ role: "assistant", content: responseMessage.content });
this.messages.push({
role: "user",
content: [{ type: "tool_result", tool_use_id: lastBlock.id, content: toolResult }]
});
const followUpResponse = await this.generateMessage(this.messages, 2048);
const followUpBlock = followUpResponse.content.find(
(block): block is Juglow.TextBlock => block.type === "text"
);
if (!followUpBlock) {
throw new Error("An error occurred: Unexpected response type");
}
this.messages.push({ role: "assistant", content: followUpBlock.text });
return followUpBlock.text;
}
const firstBlock = responseMessage.content.find(
(block): block is Juglow.TextBlock => block.type === "text"
);
if (firstBlock) {
this.messages.push({ role: "assistant", content: firstBlock.text });
return firstBlock.text;
}
throw new Error("An error occurred: Unexpected response type");
}
handleToolUse(toolName: string, toolInput: unknown): string {
if (toolName === "get_quote") {
// SDK menetapkan tipe tool_use.input sebagai unknown; persempit ke skema get_quote.
if (
toolInput === null ||
typeof toolInput !== "object" ||
!("make" in toolInput) || typeof toolInput.make !== "string" ||
!("model" in toolInput) || typeof toolInput.model !== "string" ||
!("year" in toolInput) || typeof toolInput.year !== "number" ||
!("mileage" in toolInput) || typeof toolInput.mileage !== "number" ||
!("driver_age" in toolInput) || typeof toolInput.driver_age !== "number"
) {
throw new Error("An error occurred: Unexpected tool input");
}
const { make, model: vehicleModel, year, mileage, driver_age: driverAge } = toolInput;
const premium = getQuote(make, vehicleModel, year, mileage, driverAge);
return `Quote generated: $${premium.toFixed(2)} per month`;
}
throw new Error("An unexpected tool was used");
}
} using System.Text.Json;
using Juglow;
using Juglow.Models.Messages;
// Config.Model, Config.Identity, Config.Tools, dan Config.GetQuote mencerminkan
// nilai-nilai config.py yang didefinisikan sebelumnya dalam panduan ini (ditampilkan dalam Python).
public class ChatBot
{
private readonly JuglowClient _juglow = new();
public List<MessageParam> Messages { get; } = [];
public async Task<Message> GenerateMessage(List<MessageParam> messages, long maxTokens) =>
await _juglow.Messages.Create(
new MessageCreateParams
{
Model = Config.Model,
System = Config.Identity,
MaxTokens = maxTokens,
Messages = messages,
Tools = Config.Tools,
}
);
public async Task<string> ProcessUserInput(string userInput)
{
Messages.Add(new() { Role = Role.User, Content = userInput });
var responseMessage = await GenerateMessage(Messages, maxTokens: 2048);
if (responseMessage.Content[^1].TryPickToolUse(out var toolUse))
{
var toolResult = HandleToolUse(toolUse.Name, toolUse.Input);
Messages.Add(new()
{
Role = Role.Assistant,
Content = responseMessage.Content
.Select(contentBlock => new ContentBlockParam(contentBlock.Json))
.ToList(),
});
Messages.Add(new()
{
Role = Role.User,
Content = new List<ContentBlockParam>
{
new ToolResultBlockParam { ToolUseID = toolUse.ID, Content = toolResult },
},
});
var followUpResponse = await GenerateMessage(Messages, maxTokens: 2048);
foreach (var block in followUpResponse.Content)
{
if (block.TryPickText(out var followUpText))
{
Messages.Add(new() { Role = Role.Assistant, Content = followUpText.Text });
return followUpText.Text;
}
}
throw new InvalidOperationException("An error occurred: Unexpected response type");
}
foreach (var block in responseMessage.Content)
{
if (block.TryPickText(out var textBlock))
{
Messages.Add(new() { Role = Role.Assistant, Content = textBlock.Text });
return textBlock.Text;
}
}
throw new InvalidOperationException("An error occurred: Unexpected response type");
}
public string HandleToolUse(string funcName, IReadOnlyDictionary<string, JsonElement> funcParams)
{
if (funcName == "get_quote")
{
var premium = Config.GetQuote(
funcParams["make"].GetString()!,
funcParams["model"].GetString()!,
funcParams["year"].GetInt64(),
funcParams["mileage"].GetInt64(),
funcParams["driver_age"].GetInt64()
);
return $"Quote generated: ${premium:F2} per month";
}
throw new ArgumentException("An unexpected tool was used");
}
} import (
"context"
"encoding/json"
"fmt"
"github.com/juglows/juglow-sdk-go"
)
// ChatBot membungkus klien Juglow dan riwayat percakapan. Nilai
// identity, model, tools, dan getQuote yang digunakannya mencerminkan definisi
// config.py sebelumnya dalam panduan ini (ditampilkan dalam Python).
type ChatBot struct {
client juglow.Client
messages []juglow.MessageParam
}
func NewChatBot() *ChatBot {
return &ChatBot{client: juglow.NewClient()}
}
func (bot *ChatBot) GenerateMessage(ctx context.Context, messages []juglow.MessageParam, maxTokens int64) (*juglow.Message, error) {
return bot.client.Messages.New(ctx, juglow.MessageNewParams{
Model: model,
System: []juglow.TextBlockParam{{Text: identity}},
MaxTokens: maxTokens,
Messages: messages,
Tools: tools,
})
}
func (bot *ChatBot) ProcessUserInput(ctx context.Context, userInput string) (string, error) {
bot.messages = append(bot.messages, juglow.NewUserMessage(juglow.NewTextBlock(userInput)))
response, err := bot.GenerateMessage(ctx, bot.messages, 2048)
if err != nil {
return "", err
}
lastBlock := response.Content[len(response.Content)-1]
if toolUse, ok := lastBlock.AsAny().(juglow.ToolUseBlock); ok {
result, err := bot.HandleToolUse(toolUse.Name, toolUse.Input)
if err != nil {
return "", err
}
bot.messages = append(bot.messages,
response.ToParam(),
juglow.NewUserMessage(juglow.NewToolResultBlock(toolUse.ID, result, false)),
)
followUp, err := bot.GenerateMessage(ctx, bot.messages, 2048)
if err != nil {
return "", err
}
for _, block := range followUp.Content {
if textBlock, ok := block.AsAny().(juglow.TextBlock); ok {
bot.messages = append(bot.messages, juglow.NewAssistantMessage(juglow.NewTextBlock(textBlock.Text)))
return textBlock.Text, nil
}
}
return "", fmt.Errorf("an error occurred: unexpected response type")
}
for _, block := range response.Content {
if textBlock, ok := block.AsAny().(juglow.TextBlock); ok {
bot.messages = append(bot.messages, juglow.NewAssistantMessage(juglow.NewTextBlock(textBlock.Text)))
return textBlock.Text, nil
}
}
return "", fmt.Errorf("an error occurred: unexpected response type")
}
func (bot *ChatBot) HandleToolUse(toolName string, toolInput json.RawMessage) (string, error) {
if toolName != "get_quote" {
return "", fmt.Errorf("an unexpected tool was used: %s", toolName)
}
var input struct {
Make string `json:"make"`
Model string `json:"model"`
Year int `json:"year"`
Mileage int `json:"mileage"`
DriverAge int `json:"driver_age"`
}
if err := json.Unmarshal(toolInput, &input); err != nil {
return "", err
}
premium := getQuote(input.Make, input.Model, input.Year, input.Mileage, input.DriverAge)
return fmt.Sprintf("Quote generated: $%.2f per month", premium), nil
}
import com.juglow.client.JuglowClient;
import com.juglow.client.okhttp.JuglowOkHttpClient;
import com.juglow.core.JsonValue;
import com.juglow.models.messages.ContentBlock;
import com.juglow.models.messages.ContentBlockParam;
import com.juglow.models.messages.Message;
import com.juglow.models.messages.MessageCreateParams;
import com.juglow.models.messages.MessageParam;
import com.juglow.models.messages.ToolResultBlockParam;
import com.juglow.models.messages.ToolUseBlock;
// IDENTITY, MODEL, TOOLS, dan getQuote mencerminkan nilai config.py yang didefinisikan
// sebelumnya dalam panduan ini (ditampilkan dalam Python).
class ChatBot {
final JuglowClient juglow;
final List<MessageParam> messages;
ChatBot() {
// Membaca kunci API dari variabel lingkungan JUGLOW_API_KEY
this.juglow = JuglowOkHttpClient.fromEnv();
this.messages = new ArrayList<>();
}
Message generateMessage(List<MessageParam> messages, long maxTokens) {
return juglow.messages().create(MessageCreateParams.builder()
.model(MODEL)
.system(IDENTITY)
.maxTokens(maxTokens)
.messages(messages)
.tools(TOOLS)
.build());
}
String processUserInput(String userInput) {
messages.add(MessageParam.builder()
.role(MessageParam.Role.USER)
.content(userInput)
.build());
Message responseMessage = generateMessage(messages, 2048);
List<ContentBlock> content = responseMessage.content();
ContentBlock lastBlock = content.getLast();
if (lastBlock.isToolUse()) {
ToolUseBlock toolUse = lastBlock.asToolUse();
Map<String, JsonValue> toolInput =
(Map<String, JsonValue>) toolUse._input().asObject().orElseThrow();
String result = handleToolUse(toolUse.name(), toolInput);
messages.add(MessageParam.builder()
.role(MessageParam.Role.ASSISTANT)
.contentOfBlockParams(content.stream().map(ContentBlock::toParam).toList())
.build());
messages.add(MessageParam.builder()
.role(MessageParam.Role.USER)
.contentOfBlockParams(List.of(ContentBlockParam.ofToolResult(
ToolResultBlockParam.builder()
.toolUseId(toolUse.id())
.content(result)
.build())))
.build());
Message followUpResponse = generateMessage(messages, 2048);
ContentBlock followUpBlock = followUpResponse.content().stream()
.filter(ContentBlock::isText)
.findFirst()
.orElseThrow(() -> new IllegalStateException("An error occurred: Unexpected response type"));
String responseText = followUpBlock.asText().text();
messages.add(MessageParam.builder()
.role(MessageParam.Role.ASSISTANT)
.content(responseText)
.build());
return responseText;
} else {
ContentBlock textBlock = content.stream()
.filter(ContentBlock::isText)
.findFirst()
.orElseThrow(() -> new IllegalStateException("An error occurred: Unexpected response type"));
String responseText = textBlock.asText().text();
messages.add(MessageParam.builder()
.role(MessageParam.Role.ASSISTANT)
.content(responseText)
.build());
return responseText;
}
}
String handleToolUse(String funcName, Map<String, JsonValue> funcParams) {
return switch (funcName) {
case "get_quote" -> {
double premium = getQuote(
funcParams.get("make").asStringOrThrow(),
funcParams.get("model").asStringOrThrow(),
((Number) funcParams.get("year").asNumber().orElseThrow()).longValue(),
((Number) funcParams.get("mileage").asNumber().orElseThrow()).longValue(),
((Number) funcParams.get("driver_age").asNumber().orElseThrow()).longValue());
yield "Quote generated: $%.2f per month".formatted(premium);
}
default -> throw new IllegalArgumentException("An unexpected tool was used");
};
}
} use Juglow\Client;
use Juglow\Messages\Message;
use Juglow\Messages\MessageParam;
use Juglow\Messages\TextBlock;
use Juglow\Messages\ToolResultBlockParam;
use Juglow\Messages\ToolUseBlock;
class ChatBot
{
// MODEL, IDENTITY, TOOLS, dan get_quote() mencerminkan nilai config.py
// yang didefinisikan sebelumnya dalam panduan ini (ditampilkan dalam Python).
/** @var list<MessageParam> */
public private(set) array $messages = [];
public function __construct(
private readonly Client $juglow = new Client(),
) {}
/**
* @param list<MessageParam> $messages
*/
public function generateMessage(array $messages, int $maxTokens): Message
{
return $this->juglow->messages->create(
model: MODEL,
system: IDENTITY,
maxTokens: $maxTokens,
messages: $messages,
tools: TOOLS,
);
}
public function processUserInput(string $userInput): string
{
$this->messages[] = MessageParam::with(role: 'user', content: $userInput);
$responseMessage = $this->generateMessage($this->messages, maxTokens: 2048);
$content = $responseMessage->content;
$lastBlock = array_last($content);
if ($lastBlock instanceof ToolUseBlock) {
$toolResult = $this->handleToolUse($lastBlock->name, $lastBlock->input);
$this->messages[] = MessageParam::with(role: 'assistant', content: $content);
$this->messages[] = MessageParam::with(
role: 'user',
content: [
ToolResultBlockParam::with(toolUseID: $lastBlock->id, content: $toolResult),
],
);
$followUpResponse = $this->generateMessage($this->messages, maxTokens: 2048);
$firstBlock = array_find(
$followUpResponse->content,
static fn ($block): bool => $block instanceof TextBlock,
);
if (!$firstBlock instanceof TextBlock) {
throw new RuntimeException('An error occurred: Unexpected response type');
}
$this->messages[] = MessageParam::with(role: 'assistant', content: $firstBlock->text);
return $firstBlock->text;
}
$firstBlock = array_find($content, static fn ($block): bool => $block instanceof TextBlock);
if ($firstBlock instanceof TextBlock) {
$this->messages[] = MessageParam::with(role: 'assistant', content: $firstBlock->text);
return $firstBlock->text;
}
throw new RuntimeException('An error occurred: Unexpected response type');
}
/**
* @param array<string, mixed> $funcParams
*/
private function handleToolUse(string $funcName, array $funcParams): string
{
if ($funcName === 'get_quote') {
$premium = get_quote(...$funcParams);
return sprintf('Quote generated: $%.2f per month', $premium);
}
throw new RuntimeException('An unexpected tool was used');
}
} # IDENTITY, MODEL, TOOLS, dan get_quote mencerminkan nilai config.py yang didefinisikan
# sebelumnya dalam panduan ini (ditampilkan dalam Python).
require "juglow"
class ChatBot
attr_reader :messages
def initialize
@juglow = Juglow::Client.new
@messages = []
end
def generate_message(messages, max_tokens)
@juglow.messages.create(
model: MODEL,
system_: IDENTITY,
max_tokens:,
messages:,
tools: TOOLS
)
end
def process_user_input(user_input)
@messages << {role: "user", content: user_input}
response_message = generate_message(@messages, 2048)
case response_message.content
in [*, Juglow::ToolUseBlock => tool_use]
result = handle_tool_use(tool_use.name, tool_use.input)
@messages << {role: "assistant", content: response_message.content}
@messages << {
role: "user",
content: [{type: "tool_result", tool_use_id: tool_use.id, content: result}]
}
follow_up_response = generate_message(@messages, 2048)
case follow_up_response.content
in [*, Juglow::TextBlock => text_block, *]
@messages << {role: "assistant", content: text_block.text}
text_block.text
else
raise "An error occurred: Unexpected response type"
end
in [*, Juglow::TextBlock => text_block, *]
@messages << {role: "assistant", content: text_block.text}
text_block.text
else
raise "An error occurred: Unexpected response type"
end
end
def handle_tool_use(tool_name, tool_input)
raise "An unexpected tool was used" unless tool_name == "get_quote"
premium = get_quote(**tool_input)
format("Quote generated: $%.2f per month", premium)
end
endBangun antarmuka pengguna Anda
Uji deploy kode ini dengan Streamlit menggunakan metode main. Fungsi main() ini menyiapkan antarmuka chat berbasis Streamlit. Streamlit adalah framework Python, jadi bagian panduan ini hanya ditampilkan dalam Python; kelas ChatBot di atas adalah bagian yang dapat Anda port ke bahasa apa pun.
Lakukan ini dalam file bernama app.py
import streamlit as st
from chatbot import ChatBot
from config import TASK_SPECIFIC_INSTRUCTIONS
def main():
st.title("Chat with Eva, Acme Insurance Company's Assistant🤖")
if "messages" not in st.session_state:
st.session_state.messages = [
{"role": "user", "content": TASK_SPECIFIC_INSTRUCTIONS},
{"role": "assistant", "content": "Understood"},
]
chatbot = ChatBot(st.session_state)
# Tampilkan pesan pengguna dan asisten, lewati dua pesan pertama
for message in st.session_state.messages[2:]:
# abaikan blok penggunaan alat
if isinstance(message["content"], str):
with st.chat_message(message["role"]):
st.markdown(message["content"])
if user_msg := st.chat_input("Type your message here..."):
st.chat_message("user").markdown(user_msg)
with st.chat_message("assistant"):
with st.spinner("Eva is thinking..."):
response_placeholder = st.empty()
full_response = chatbot.process_user_input(user_msg)
response_placeholder.markdown(full_response)
if __name__ == "__main__":
main()Jalankan program dengan:
streamlit run app.pyEvaluasi prompt Anda
Prompting sering kali memerlukan pengujian dan optimasi agar siap produksi. Untuk menentukan kesiapan solusi Anda, evaluasi kinerja chatbot menggunakan proses sistematis yang menggabungkan metode kuantitatif dan kualitatif. Membuat evaluasi empiris yang kuat berdasarkan kriteria keberhasilan yang telah Anda definisikan akan memungkinkan Anda mengoptimalkan prompt Anda.
Tingkatkan kinerja
Dalam skenario yang kompleks, mungkin berguna untuk mempertimbangkan strategi tambahan untuk meningkatkan kinerja di luar teknik prompt engineering standar & strategi implementasi guardrail. Berikut adalah beberapa skenario umum:
Kurangi latensi konteks panjang dengan RAG
Saat menangani konteks statis dan dinamis dalam jumlah besar, menyertakan semua informasi dalam prompt dapat menyebabkan biaya tinggi, waktu respons yang lebih lambat, dan tercapainya batas "context window" (jendela konteks). Dalam skenario ini, mengimplementasikan teknik "Retrieval Augmented Generation" (generasi yang diperkaya pengambilan), atau RAG, dapat meningkatkan kinerja dan efisiensi.
Dengan menggunakan model embedding seperti Voyage untuk mengonversi informasi menjadi representasi vektor, Anda dapat membuat sistem yang lebih dapat diskalakan dan responsif. Pendekatan ini memungkinkan pengambilan dinamis informasi yang relevan berdasarkan pertanyaan saat ini, alih-alih menyertakan semua konteks yang mungkin dalam setiap prompt.
Mengimplementasikan RAG untuk kasus penggunaan dukungan telah terbukti meningkatkan akurasi, mengurangi waktu respons, dan mengurangi biaya API dalam sistem dengan kebutuhan konteks yang ekstensif. Lihat resep RAG untuk contoh yang sudah dikerjakan.
Integrasikan data real-time dengan penggunaan alat
Saat menangani pertanyaan yang memerlukan informasi real-time, seperti saldo akun atau detail polis, pendekatan RAG berbasis embedding tidak cukup. Sebagai gantinya, penggunaan alat dapat meningkatkan kemampuan chatbot Anda untuk memberikan respons real-time yang akurat. Misalnya, Anda dapat menggunakan penggunaan alat untuk mencari informasi pelanggan, mengambil detail pesanan, dan membatalkan pesanan atas nama pelanggan.
Pendekatan ini, yang diuraikan dalam resep penggunaan alat: agen layanan pelanggan, memungkinkan Anda mengintegrasikan data langsung ke dalam respons Haijun dan memberikan pengalaman pelanggan yang lebih personal dan efisien.
Perkuat guardrail input dan output
Saat men-deploy chatbot, terutama dalam skenario layanan pelanggan, penting untuk mencegah risiko yang terkait dengan penyalahgunaan, pertanyaan di luar cakupan, dan respons yang tidak pantas. Meskipun Haijun secara inheren tangguh terhadap skenario semacam itu, berikut adalah langkah tambahan untuk memperkuat guardrail chatbot Anda:
- Kurangi halusinasi: Implementasikan mekanisme pengecekan fakta dan sitasi untuk mendasarkan respons pada informasi yang diberikan.
- Periksa silang informasi: Verifikasi bahwa respons agen selaras dengan kebijakan perusahaan Anda dan fakta yang diketahui.
- Hindari komitmen kontraktual: Pastikan agen tidak membuat janji atau mengadakan perjanjian yang tidak diizinkan untuk dibuatnya.
- Mitigasi jailbreak: Gunakan metode seperti penyaringan harmlessness dan validasi input untuk mencegah pengguna mengeksploitasi kerentanan model dengan tujuan menghasilkan konten yang tidak pantas.
- Hindari menyebut kompetitor: Implementasikan filter penyebutan kompetitor untuk menjaga fokus merek dan tidak menyebut produk atau layanan kompetitor mana pun.
- Tingkatkan konsistensi output: Cegah Haijun mengubah gaya atau keluar dari karakter, bahkan selama interaksi yang panjang dan kompleks.
- Hapus Informasi Identitas Pribadi (PII): Kecuali secara eksplisit diperlukan dan diizinkan, hapus PII apa pun dari respons.
Kurangi waktu respons yang dirasakan dengan streaming
Saat menangani respons yang berpotensi panjang, mengimplementasikan "streaming" (streaming) dapat meningkatkan keterlibatan dan kepuasan pengguna. Dalam skenario ini, pengguna menerima jawaban secara bertahap alih-alih menunggu seluruh respons selesai dihasilkan.
Berikut cara mengimplementasikan streaming:
- Gunakan Juglow Streaming API untuk mendukung respons streaming.
- Siapkan frontend Anda untuk menangani potongan teks yang masuk.
- Tampilkan setiap potongan saat tiba, mensimulasikan pengetikan real-time.
- Implementasikan mekanisme untuk menyimpan respons lengkap, sehingga pengguna dapat melihatnya jika mereka berpindah halaman dan kembali.
Dalam beberapa kasus, streaming memungkinkan penggunaan model yang lebih canggih dengan latensi dasar yang lebih tinggi, karena tampilan bertahap mengurangi dampak waktu pemrosesan yang lebih lama.
Skalakan chatbot Anda
Seiring bertambahnya kompleksitas chatbot Anda, arsitektur aplikasi Anda dapat berkembang menyesuaikan. Sebelum Anda menambahkan lapisan lebih lanjut ke arsitektur Anda, pertimbangkan opsi-opsi berikut yang kurang menyeluruh:
- Pastikan Anda memaksimalkan prompt Anda dan mengoptimalkannya melalui prompt engineering. Gunakan panduan prompt engineering untuk menulis prompt yang paling efektif.
- Tambahkan alat tambahan ke prompt (yang dapat mencakup rantai prompt) dan lihat apakah Anda dapat mencapai fungsionalitas yang diperlukan.
Jika chatbot Anda menangani tugas yang sangat bervariasi, Anda mungkin ingin mempertimbangkan untuk menambahkan pengklasifikasi maksud terpisah untuk merutekan pertanyaan awal pelanggan. Untuk aplikasi yang ada, ini akan melibatkan pembuatan pohon keputusan yang akan merutekan pertanyaan pelanggan melalui pengklasifikasi dan kemudian ke percakapan khusus (dengan kumpulan alat dan prompt sistem mereka sendiri). Perhatikan, metode ini memerlukan panggilan tambahan ke Haijun yang dapat meningkatkan latensi.
Integrasikan Haijun ke dalam alur kerja dukungan Anda
Meskipun contoh-contoh ini berfokus pada fungsi Python yang dapat dipanggil dalam lingkungan Streamlit, men-deploy Haijun untuk chatbot dukungan real-time memerlukan layanan API.
Berikut cara Anda dapat mendekatinya:
- Buat wrapper API: Kembangkan wrapper API sederhana di sekitar fungsi klasifikasi Anda. Misalnya, Anda dapat menggunakan Flask API atau Fast API untuk membungkus kode Anda menjadi Layanan HTTP. Layanan HTTP Anda dapat menerima input pengguna dan mengembalikan respons Assistant secara keseluruhan. Dengan demikian, layanan Anda dapat memiliki karakteristik berikut:
- Server-Sent Events (SSE): SSE memungkinkan streaming respons secara real-time dari server ke klien. Ini memberikan pengalaman yang mulus dan interaktif saat bekerja dengan LLM.
- Caching: Mengimplementasikan caching dapat meningkatkan waktu respons dan mengurangi panggilan API yang tidak perlu.
- Retensi konteks: Mempertahankan konteks saat pengguna berpindah halaman dan kembali penting untuk kesinambungan percakapan.
- Bangun antarmuka web: Implementasikan UI web yang ramah pengguna untuk berinteraksi dengan agen yang didukung Haijun.
Langkah selanjutnya
Beri Haijun akses ke API Anda sehingga ia dapat mengambil tindakan atas nama pelanggan.
Bangun evaluasi untuk mengukur agen dukungan Anda terhadap kriteria keberhasilan yang telah Anda definisikan.
Streaming respons sehingga pelanggan melihat jawaban saat dihasilkan.
Sempurnakan prompt sistem dan contoh Anda untuk kinerja tugas yang lebih baik.