Experts.js adalah cara termudah untuk membuat dan menggunakan asisten Openai dan menautkannya bersama sebagai alat untuk membuat panel sistem ahli dengan memori yang diperluas dan perhatian terhadap detail.
Dibuat melalui dukungan ❤️ dengan tinta khusus | Tech
API asisten baru dari OpenAI menetapkan standar industri baru, secara signifikan maju melampaui API penyelesaian obrolan yang diadopsi secara luas. Ini merupakan lompatan besar dalam kegunaan agen AI dan cara insinyur berinteraksi dengan LLMS. Dipasangkan dengan model mini GPT-4O mutakhir, asisten sekarang dapat merujuk file & gambar terlampir sebagai sumber pengetahuan dalam jendela konteks yang dikelola yang disebut utas. Tidak seperti GPT khusus, asisten mendukung instruksi hingga 256.000 karakter, mengintegrasikan dengan 128 alat, dan menggunakan API toko vektor inovatif untuk pencarian file yang efisien pada 10.000 file per asisten.
Ahli. JS bertujuan untuk menyederhanakan penggunaan API baru ini dengan menghapus kompleksitas mengelola objek yang dijalankan dan memungkinkan asisten dihubungkan bersama sebagai alat.
import { Assistant , Thread } from "experts" ;
const thread = await Thread . create ( ) ;
const assistant = await Assistant . create ( ) ;
const output = await assistant . ask ( "Say hello." , thread . id ) ;
console . log ( output ) // Hello
Lebih penting lagi, Experts.js memperkenalkan asisten sebagai alat, memungkinkan penciptaan sistem agen multi AI. Setiap alat adalah asisten yang didukung LLM yang dapat mengambil peran khusus atau memenuhi tugas kompleks atas nama asisten atau alat induknya. Memungkinkan untuk alur kerja orkestrasi yang kompleks atau koreografi serangkaian tugas rajutan yang rapat. Ditampilkan di sini adalah contoh asisten perusahaan dengan alat katalog produk yang dengan sendirinya memiliki alat yang didukung LLM untuk membuat kueri OpenSearch.
Instal melalui NPM. Penggunaannya sangat sederhana, hanya ada tiga objek untuk diimpor.
npm install experts
Experts.js mendukung sintaks impor ES6 dan CommonJs memerlukan pernyataan.
import { Assistant , Tool , Thread } from "experts" ;
Konstruktor objek asisten fasad kami membutuhkan nama, deskripsi, dan instruksi. Argumen ketiga adalah serangkaian opsi yang secara langsung memetakan ke semua opsi badan permintaan yang diuraikan dalam dokumentasi Buat Asisten. Semua contoh di Experts.js ditulis dalam kelas ES6 untuk kesederhanaan. Model default adalah gpt-4o-mini
.
class MyAssistant extends Assistant {
constructor ( ) {
super ( {
name : "My Assistant" ,
instructions : "..." ,
model : "gpt-4o-mini" ,
tools : [ { type : "file_search" } ] ,
temperature : 0.1 ,
tool_resources : {
file_search : {
vector_store_ids : [ process . env . VECTOR_STORE_ID ] ,
} ,
} ,
} ) ;
}
}
const assistant = await MyAssistant . create ( ) ;
Fungsi Pabrik Basis Assync Assistant.create()
adalah cara sederhana untuk membuat asisten menggunakan opsi konstruktor yang sama.
const assistant = Assistant . create ( {
name : "My Assistant" ,
instructions : "..." ,
model : "gpt-4o-mini" ,
} ) ;
Penting
Membuat asisten tanpa parameter id
akan selalu membuat asisten baru. Lihat bagian Penerapan kami untuk informasi lebih lanjut.
Fungsi ask()
adalah antarmuka sederhana untuk ditanyakan atau instruktur asisten Anda. Itu membutuhkan pesan dan pengidentifikasi utas. Lebih lanjut tentang utas di bawah ini. Pesannya bisa berupa string atau objek pesan OpenAi asli. Di sinilah para ahli.js benar -benar bersinar. Anda tidak perlu mengelola objek lari atau langkah lari mereka secara langsung.
const output = await assistant . ask ( "..." , threadID )
const output = await assistant . ask ( { role : "user" , content : "..." } , threadID ) ;
Alat OpenAi normal dan panggilan fungsi didukung melalui objek Opsi Konstruktor kami melalui tools
dan tool_resources
. Ahli juga mendukung penambahan asisten sebagai alat. Informasi lebih lanjut tentang penggunaan asisten sebagai alat dapat ditemukan di bagian selanjutnya. Gunakan fungsi addAssistantTool
untuk menambahkan asisten sebagai alat. Ini harus terjadi setelah super()
di konstruktor asisten Anda.
class MainAssistant extends Assistant {
constructor ( ) {
super ( {
name : "Company Assistant" ,
instructions : "..." ,
} ) ;
this . addAssistantTool ( ProductsTools ) ;
}
}
Secara default, Experts.js memanfaatkan acara streaming asisten. Ini memungkinkan aplikasi Anda untuk menerima output teks, gambar, dan alat melalui peristiwa-endend-endsend OpenAI. Kami memanfaatkan pembantu aliran OpenAi-Node dan memunculkan acara-acara ini bersama dengan beberapa kustom yang memberi asisten Anda untuk memanfaatkan siklus hidup lengkap dari lari.
const assistant = await MainAssistant . create ( ) ;
assistant . on ( "textDelta" , ( delta , _snapshot ) => {
process . stdout . write ( delta . value )
} ) ;
Semua acara streaming OpenAI-Node didukung melalui fungsi Assistant's on()
kami. Nama acara yang tersedia adalah: event
, textDelta
, textDone
, imageFileDone
, toolCallDelta
, runStepDone
, toolCallDone
, dan end
Penting
Acara-Acara OpenAI's Server-Send bukan Async/Await Friendly.
Jika pendengar Anda perlu melakukan pekerjaan dengan cara async, seperti mengarahkan output alat, pertimbangkan untuk menggunakan ekstensi kami untuk acara ini. Mereka dipanggil dalam urutan ini setelah pelarian selesai. Nama Acara Async yang tersedia adalah: textDoneAsync
, imageFileDoneAsync
, runStepDoneAsync
, toolCallDoneAsync
, dan endAsync
.
Jika Anda ingin dengan malas mendukung sumber daya tambahan ketika fungsi Assistant's create()
dipanggil, terapkan fungsi beforeInit()
di kelas Anda. Ini adalah metode async yang akan dipanggil sebelum asisten dibuat.
async beforeInit ( ) {
await this . # createFileSearch ( ) ;
}
Demikian juga, fungsi afterInit()
dapat digunakan. Misalnya, untuk menulis ID asisten yang baru dibuat ke file lingkungan.
async afterInit ( ) {
// ...
}
Semua acara asisten menerima argumen metadata ahli tambahan. Objek yang berisi stream
run. Ini memungkinkan Anda untuk menggunakan fungsi pembantu openai-node seperti currentEvent
, finalMessages
, dll.
assistant . on ( "endAsync" , async ( metadata ) => {
await metadata . stream . finalMessages ( ) ;
} ) ;
Menggunakan asisten sebagai alat adalah titik fokus utama dari kerangka kerja para ahli. Alat adalah subclass asisten dan merangkum antarmuka untuk objek induknya. Dengan cara ini, alat Ahli. JS adalah komponen yang dapat digunakan kembali dalam arsitektur agen Anda. Contoh kami menggambarkan pola passing pesan dasar, untuk singkatnya. Anda harus memanfaatkan semua alat Openai dan fitur panggilan fungsi sepenuhnya.
class EchoTool extends Tool {
constructor ( ) {
super ( {
name : "Echo Tool" ,
instructions : "Echo the same text back to the user" ,
parentsTools : [
{
type : "function" ,
function : {
name : "echo" ,
description : description ,
parameters : {
type : "object" ,
properties : { message : { type : "string" } } ,
required : [ "message" ] ,
} ,
} ,
} ,
] ,
} ) ;
}
}
Peringatan
Sangat penting bahwa nama fungsi alat Anda menjadi unik di seluruh rangkaian nama alat induknya.
Dengan demikian, nama kelas alat penting dan membantu model Openai memutuskan alat mana yang akan dihubungi. Jadi pilih nama yang bagus untuk kelas alat Anda. Misalnya, ProductsOpenSearchTool
akan menjadi products_open_search
dan jelas membantu model menyimpulkan bersama dengan deskripsi alat apa peran yang dilakukannya.
Alat ditambahkan ke asisten Anda melalui fungsi addAssistantTool
. Fungsi ini akan menambahkan alat ke array alat asisten dan memperbarui konfigurasi asisten. Ini harus terjadi setelah super()
di konstruktor asisten Anda.
class MainAssistant extends Assistant {
constructor ( ) {
super ( {
name : "Company Assistant" ,
instructions : "..."
} ) ;
this . addAssistantTool ( EchoTool ) ;
}
}
Respons Asisten Alat Anda akan secara otomatis diserahkan sebagai output untuk Asisten atau alat induk.
Alat default didukung oleh model
LLM dan melakukan semua acara siklus hidup yang sama, berjalan, dll sebagai asisten. Namun, Anda dapat membuat alat yang tidak menggunakan salah satu fitur asisten inti dengan mengatur opsi llm
menjadi false
. Saat melakukannya, Anda harus menerapkan fungsi ask()
di alat Anda. Nilai pengembalian akan dikirimkan sebagai output alat.
class AnswerTwoTool extends Tool {
constructor ( ) {
super ( {
// ...
llm : false ,
parentsTools : [ ... ] ,
} ) ;
}
async ask ( message ) {
return ... ;
}
}
Dalam alur kerja yang kompleks, alat yang didukung LLM dapat digunakan untuk mengonversi instruksi LLM manusia atau lainnya menjadi kode yang dapat dieksekusi dan hasil dari kode itu (bukan output LLM) perlu diserahkan untuk output induk alat Anda. Misalnya, ProductsOpenSearchTool
dapat mengubah pesan menjadi kueri OpenSearch, menjalankannya, dan mengembalikan hasilnya. Sub kelas dapat mengimplementasikan fungsi answered()
untuk mengontrol output. Dalam hal ini, output
akan menjadi kueri OpenSearch dan output alat sekarang berisi hasil dari kueri yang dihasilkan LLM.
async answered ( output ) {
const args = JSON . parse ( output ) ;
return await this . opensearchQuery ( args ) ;
}
Atau, alat yang didukung LLM dapat memilih untuk mengarahkan kembali output alat mereka sendiri kembali ke asisten atau alat induknya. Dengan demikian mengabaikan output LLM. Ini juga memungkinkan semua output alat alat untuk dikirimkan sebagai output induk. Lebih lanjut tentang mengapa ini penting dalam contoh katalog produk di bawah ini.
class ProductsTool extends Tool {
constructor ( ) {
super ( {
// ...
temperature : 0.1 ,
tools : [ { type : "code_interpreter" } ] ,
outputs : "tools" ,
parentsTools : [ ... ] ,
} ) ;
this . addAssistantTool ( ProductsOpenSearchTool ) ;
this . on ( "imageFileDoneAsync" , this . imageFileDoneAsync . bind ( this ) ) ;
}
}
API Asisten Openai memperkenalkan sumber daya baru yang disebut utas mana pesan & file disimpan di dalamnya. Pada dasarnya, utas adalah jendela konteks yang dikelola (memori) untuk agen Anda. Membuat utas baru dengan Experts.js semudah:
const thread = await Thread . create ( ) ;
console . log ( thread . id ) // thread_abc123
Anda juga dapat membuat utas dengan pesan, file, atau sumber daya alat untuk memulai percakapan. Kami mendukung utas OpenAI Buat Badan Permintaan yang diuraikan dalam referensi API utas mereka.
const thread = await Thread . create ( {
messages : [
{ role : "user" , content : "My name is Ken" } ,
{ role : "user" , content : "Oh, my last name is Collins" } ,
] ,
} ) ;
const output = await assistant . ask ( "What is my full name?" , thread . id ) ;
console . log ( output ) // Ken Collins
Secara default, setiap alat di Experts.js memiliki utas & konteksnya sendiri. Ini menghindari masalah penguncian utas potensial yang terjadi jika suatu alat untuk berbagi utas asisten masih menunggu output alat untuk diserahkan. Diagram berikut mengilustrasikan bagaimana ahli. JS mengelola utas atas nama Anda untuk menghindari masalah ini:
Semua pertanyaan kepada para ahli Anda memerlukan ID utas. Untuk aplikasi obrolan, ID akan disimpan pada klien. Seperti parameter jalur URL. Dengan Expert.js, tidak ada ID sisi klien lain yang diperlukan. Karena setiap asisten memanggil alat yang didukung LLM, ia akan menemukan atau membuat utas untuk alat itu sesuai kebutuhan. Experts.js Menyimpan orang tua ini -> Hubungan utas anak untuk Anda menggunakan metadata utas Openai.
Lari dikelola untuk Anda di belakang fungsi Assistant's ask
. Namun, Anda masih dapat melewati opsi yang akan digunakan saat membuat lari dalam satu dari dua cara.
Pertama, Anda dapat menentukan run_options
di konstruktor asisten. Opsi ini akan digunakan untuk semua proses yang dibuat oleh asisten. Ini adalah cara yang bagus untuk memaksa model menggunakan alat melalui opsi tool_choice
.
class CarpenterAssistant extends Assistant {
constructor ( ) {
super ( {
// ...
run_options : {
tool_choice : {
type : "function" ,
function : { name : "my_tool_name" } ,
} ,
} ,
} ) ;
this . addAssistantTool ( MyTool ) ;
}
}
Atau, Anda dapat meneruskan objek opsi ke metode ask
untuk digunakan untuk menjalankan saat ini. Ini adalah cara yang bagus untuk membuat opsi lari tunggal.
await assistant . ask ( "..." , "thread_abc123" , {
run : {
tool_choice : { type : "function" , function : { name : "my_tool_name" } } ,
additional_instructions : "..." ,
additional_messages : [ ... ] ,
} ,
} ) ;
Untuk melihat contoh kode dari ini dan lebih banyak beraksi, silakan lihat suite tes kami.
Di bagian ikhtisar kami menunjukkan sistem agen tiga tingkat yang dapat menjawab jenis pertanyaan berikut. Contohnya menggunakan sebagian besar, jika tidak semua, fitur dari kerangka kerja ahli.
Contoh Dasar Menggunakan Acara textDelta
untuk mengalirkan respons dari rute ekspres.
import express from "express" ;
import { MainAssistant } from "../experts/main.js" ;
const assistant = await MainAssistant . create ( ) ;
messagesRouter . post ( "" , async ( req , res , next ) => {
res . setHeader ( "Content-Type" , "text/plain" ) ;
res . setHeader ( "Transfer-Encoding" , "chunked" ) ;
assistant . on ( "textDelta" , ( delta , _snapshot ) => {
res . write ( delta . value ) ;
} ) ;
await assistant . ask ( req . body . message . content , req . body . threadID ) ;
res . end ( ) ;
} ) ;
API Asisten mendukung pesan dengan gambar menggunakan tipe konten image_url
atau image_file
. Karena fungsi ask()
kami mendukung string atau objek pesan OpenAI asli.
const output = await assistant . ask (
{
role : "user" ,
content : [
{ type : "text" , text : "Tell me about this image." } ,
{ type : "image_file" , image_file : { file_id : file . id detail : "high" } } ,
] ,
} ,
threadID
) ;
Menggunakan toko vektor untuk pencarian file mudah menggunakan antarmuka OpenAi melalui opsi konfigurasi ketiga kami. Anda dapat membuat store vektor Anda sesuai permintaan menggunakan fungsi beforeInit()
kami yang dijelaskan dalam fitur-fitur lanjutan.
class VectorSearchAssistant extends Assistant {
constructor ( ) {
super ( {
name : "Vector Search Assistant" ,
instructions : "..." ,
tools : [ { type : "file_search" } ] ,
temperature : 0.1 ,
tool_resources : {
file_search : {
vector_store_ids : [ process . env . VECTOR_STORE_ID ] ,
} ,
} ,
} ) ;
}
}
Menggunakan fitur Streaming & Events untuk melaporkan penggunaan token memungkinkan Anda memiliki metrik per-bantuan.
class MyAssistant extends Assistant {
constructor ( ) {
super ( {
// ...
} ) ;
this . on ( "runStepDone" , this . # reportUsage . bind ( this ) ) ;
}
# reportUsage ( runStep ) {
if ( ! runStep ?. usage ?. total_tokens ) return ;
const iT = runStep . usage . prompt_tokens ;
const oT = runStep . usage . completion_tokens ;
const tT = runStep . usage . total_tokens ;
console . log ( { InTokens : iT , OutTokens : oT , TotalTokens : tT } ) ;
}
}
Agar seorang asisten dapat digunakan ke lingkungan produksi, kami merekomendasikan konfigurasi berikut. Pertama, buat atau temukan ID asisten Anda. String akan berada dalam format asst_abc123
. Kemudian masukkan ID ini ke konstruktor asisten atau alat. Ini akan memastikan bahwa asisten yang sama digunakan di semua penyebaran.
class MyAssistant extends Assistant {
constructor ( ) {
super ( {
// ...
id : process . env . MY_ASSISTANT_ID
} ) ;
}
}
Setelah asisten atau alat ditemukan oleh ID, konfigurasi jarak jauh apa pun yang berbeda hadir ditimpa oleh konfigurasi lokal. Jika diperlukan, misalnya dalam lingkungan pementasan, Anda dapat melewati perilaku ini dengan menetapkan opsi skipUpdate
ke true
.
Anda dapat secara global mengatur model untuk semua asisten menggunakan variabel lingkungan EXPERTS_DEFAULT_MODEL
. Ini hanya berfungsi jika Anda belum secara eksplisit mengatur model di konstruktor asisten Anda.
Untuk men -debug asisten Anda, Anda dapat mengatur variabel lingkungan DEBUG=1
. Ini akan menghasilkan logging verbose dari semua panggilan API dan acara-event-endsing. Acara Delta bisa agak bertele -tele dan dinonaktifkan secara default. Harap juga gunakan variabel lingkungan DEBUG_DELTAS=1
untuk menyalakannya.
Proyek ini memanfaatkan wadah dev yang berarti Anda dapat membukanya di IDE pendukung untuk memulai segera. Ini termasuk menggunakan kode VS dengan wadah dev yang merupakan pendekatan yang disarankan.
Setelah dibuka di wadah pengembangan Anda, buat file .env.development.local
dengan kunci API openai Anda dan kunci API postimage.org:
OPENAI_API_KEY=sk-...
POST_IMAGES_API_KEY=...
Sekarang Anda dapat menjalankan perintah berikut:
./bin/setup
./bin/test