Agen multi-pengguna mengerumuni ollama

Dahulu, antarmuka pengguna grafis menggantikan input baris perintah. Tampaknya antarmuka pseudo-grafis dapat menyelesaikan masalah interaksi untuk pengguna yang tidak siap, tetapi ada faktor yang tidak semua orang perhatikan.

Penting! Mengembangkan antarmuka pengguna grafis lebih murah daripada pseudo-grafis. Secara historis, tepat setelah rilis kubus berikutnya, OBJC diperkenalkan dengan editor bentuk grafis di mana halaman dapat diatur dengan mouse. Di dunia modern, Frontend menyediakan bentuk grafis debugging melalui alat dev, yang pada dasarnya hal yang sama: kode nominal tanpa detail teknis, dan ketika masalah muncul, ada GUI yang membuat bug menemukan lebih murah.

Tapi bahkan lebih murah untuk tidak membuat antarmuka pengguna sama sekali. Anda tidak memerlukan IP statis, PCI DSS, domain yang dipromosikan di Yandex dan Google, atau highload jika Anda memutuskan untuk tidak menemukan kembali roda dan membuat produk web lain yang harganya tiga kali lebih banyak untuk menarik pengunjung daripada berkembang.

Telepon berasal dari kata "telepon," fonetik - suara. Alih -alih mempelajari sejumlah besar kombinasi tombol untuk Figma, Blender, Photoshop, Unreal Engine, lebih mudah untuk menyuarakan perintah. Bagaimana Anda memutar gambar di Archicad?
Agen Swarm seperti fragmen di Android atau router di React: Mereka memungkinkan Anda untuk menentukan ruang lingkup tugas (tombol di layar) berdasarkan input pengguna sebelumnya. Misalnya, ketika sebuah panggilan masuk di telepon SIP, Anda pertama -tama perlu memahami jika orang tersebut ingin membeli atau mengembalikan barang pada prinsipnya, dan kemudian menawarkan daftar produk yang tersedia.
Kantor pajak akan selalu meminta debit/kredit dalam bentuk tabel, jadi sistem CRM tidak akan pergi ke mana pun. Tugas LLM adalah untuk mengurai teks alami baik dari obrolan atau pengenalan suara dan mengubahnya menjadi tanda tangan fungsi dengan nama dan argumen sehingga dapat dipanggil dan data dapat ditulis ke database.
Untuk menyelesaikan masalah ini, penting untuk mengetahui beberapa nuansa:
Untuk setiap sesi obrolan terbuka, Swarm Orchestration perlu dilakukan dengan pohon agen yang memiliki riwayat obrolan bersama di antara mereka dan terpisah untuk pengguna yang berbeda. Dalam kode ini, itu diimplementasikan di bawah kap agen-swarm-kit.
import { addSwarm } from "agent-swarm-kit" ;
export const ROOT_SWARM = addSwarm ( {
swarmName : 'root_swarm' ,
agentList : [
TRIAGE_AGENT ,
SALES_AGENT ,
] ,
defaultAgent : TRIAGE_AGENT ,
} ) ;
...
app . get ( "/api/v1/session/:clientId" , upgradeWebSocket ( ( ctx ) => {
const clientId = ctx . req . param ( "clientId" ) ;
const { complete , dispose } = session ( clientId , ROOT_SWARM )
return {
onMessage : async ( event , ws ) => {
const message = event . data . toString ( ) ;
ws . send ( await complete ( message ) ) ;
} ,
onClose : async ( ) => {
await dispose ( ) ;
} ,
}
} ) ) ;Saat membuat agen, kami menentukan setidaknya satu pesan sistem yang menggambarkan apa yang harus dilakukan. Kami menentukan konektor ke model bahasa, yang akan memungkinkan beberapa agen diproses secara lokal secara gratis, sambil mendelegasikan yang kompleks ke layanan cloud OpenAI. Jika ada sesuatu yang tidak berhasil, kami menambahkan petunjuk ke array sistem, misalnya, fungsi perbaikan panggilan untuk ollama.
const AGENT_PROMPT = `You are a sales agent that handles all actions related to placing the order to purchase an item.
Tell the users all details about products in the database by using necessary tool calls
Do not send any JSON to the user. Format it as plain text. Do not share any internal details like ids, format text human readable
If the previous user messages contains product request, tell him details immidiately
It is important not to call tools recursive. Execute the search once
` ;
/**
* @see https://github.com/ollama/ollama/blob/86a622cbdc69e9fd501764ff7565e977fc98f00a/server/model.go#L158
*/
const TOOL_PROTOCOL_PROMPT = `For each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:
<tool_call>
{"name": <function-name>, "arguments": <args-json-object>}
</tool_call>
` ;
export const SALES_AGENT = addAgent ( {
agentName : "sales_agent" ,
completion : OLLAMA_COMPLETION ,
system : [ TOOL_PROTOCOL_PROMPT ] ,
prompt : AGENT_PROMPT ,
tools : [ SEARCH_PHARMA_PRODUCT , NAVIGATE_TO_TRIAGE ] ,
} ) ;Dalam contoh ini, saya menggunakan Ollama untuk memproses permintaan pengguna. Bagi mereka yang tidak terbiasa dengan terminologi: proses di mana model bahasa menerima riwayat obrolan dengan pengguna sebagai input dan menghasilkan pesan baru disebut penyelesaian. Agen-Swarm-Kit menggunakan antarmuka abstrak yang bekerja sama dengan penyedia cloud atau model lokal. Gunakan artikel ini untuk menghubungkan Deepseek.
import { addCompletion , IModelMessage } from "agent-swarm-kit" ;
const getOllama = singleshot ( ( ) => new Ollama ( { host : CC_OLLAMA_HOST } ) ) ;
export const OLLAMA_COMPLETION = addCompletion ( {
completionName : "ollama_completion" ,
getCompletion : async ( {
agentName ,
messages ,
mode ,
tools ,
} ) => {
const response = await getOllama ( ) . chat ( {
model : "nemotron-mini:4b" , // "mistral-nemo:12b";
keep_alive : "1h" ,
messages : messages . map ( ( message ) => omit ( message , "agentName" , "mode" ) ) ,
tools ,
} ) ;
return {
... response . message ,
mode ,
agentName ,
role : response . message . role as IModelMessage [ "role" ] ,
} ;
} ,
} ) ; Mengubah agen aktif dan mendapatkan data dari database dilakukan melalui panggilan alat: Model bahasa mengembalikan XML khusus yang diproses oleh kerangka kerja untuk model lokal atau oleh penyedia cloud untuk OpenAi untuk memanggil kode eksternal dalam python/js, dll. Hasil eksekusi yang direkam dalam riwayat obrolan sebagai {"role": "tool", "content": "Product Paracetamol found in database: fever reducer for fighting flu"} Dari pesan pengguna berikutnya, model bahasa beroperasi dengan data dari alat.
import { addTool , changeAgent , execute } from "agent-swarm-kit" ;
const PARAMETER_SCHEMA = z . object ( { } ) . strict ( ) ;
export const NAVIGATE_TO_SALES = addTool ( {
toolName : "navigate_to_sales_tool" ,
validate : async ( clientId , agentName , params ) => {
const { success } = await PARAMETER_SCHEMA . spa ( params ) ;
return success ;
} ,
call : async ( clientId , agentName ) => {
await commitToolOutput (
"Navigation success`,
clientId ,
agentName
) ;
await changeAgent ( SALES_AGENT , clientId ) ;
await execute ( "Say hello to the user" , clientId , SALES_AGENT ) ;
} ,
type : "function" ,
function : {
name : "navigate_to_sales_tool" ,
description : "Navigate to sales agent" ,
parameters : {
type : "object" ,
properties : { } ,
required : [ ] ,
} ,
} ,
} ) ;Untuk menghindari pesan agen awal hardcoding, saat beralih agen, simulasi permintaan pengguna terjadi meminta untuk menyapa.
import {
addTool ,
commitSystemMessage ,
commitToolOutput ,
execute ,
getLastUserMessage ,
} from "agent-swarm-kit" ;
const PARAMETER_SCHEMA = z
. object ( {
description : z
. string ( )
. min ( 1 , "Fulltext is required" )
} )
. strict ( ) ;
export const SEARCH_PHARMA_PRODUCT = addTool ( {
toolName : "search_pharma_product" ,
validate : async ( clientId , agentName , params ) => {
const { success } = await PARAMETER_SCHEMA . spa ( params ) ;
return success ;
} ,
call : async ( clientId , agentName , params ) => {
let search = "" ;
if ( params . description ) {
search = String ( params . description ) ;
} else {
search = await getLastUserMessage ( clientId ) ;
}
if ( ! search ) {
await commitToolOutput (
str . newline ( `The products does not found in the database` ) ,
clientId ,
agentName
) ;
await execute (
"Tell user to specify search criteria for the pharma product" ,
clientId ,
agentName
) ;
return ;
}
const products = await ioc . productDbPublicService . findByFulltext (
search ,
clientId
) ;
if ( products . length ) {
await commitToolOutput (
str . newline (
`The next pharma product found in database: ${ products . map (
serializeProduct
) } `
) ,
clientId ,
agentName
) ;
await commitSystemMessage (
"Do not call the search_pharma_product next time!" ,
clientId ,
agentName
) ;
await execute (
"Tell user the products found in the database." ,
clientId ,
agentName
) ;
return ;
}
await commitToolOutput (
`The products does not found in the database` ,
clientId ,
agentName
) ;
await execute (
"Tell user to specify search criteria for the pharma product" ,
clientId ,
agentName
) ;
} ,
type : "function" ,
function : {
name : "search_pharma_product" ,
description :
"Retrieve several pharma products from the database based on description" ,
parameters : {
type : "object" ,
properties : {
description : {
type : "string" ,
description :
"REQUIRED! Minimum one word. The product description. Must include several sentences with description and keywords to find a product" ,
} ,
} ,
required : [ "description" ] ,
} ,
} ,
} ) ;Model bahasa dapat membentuk kamus parameter bernama untuk panggilan alat. Namun, model OpenSource menangani ini dengan buruk jika ada persyaratan teknis untuk sirkuit tertutup; Lebih sederhana untuk menganalisis percakapan itu sendiri.
Beberapa sesi chatgpt (agen) melakukan panggilan alat. Setiap agen dapat menggunakan model yang berbeda, misalnya, Mistral 7B untuk komunikasi sehari -hari, Nemoton untuk percakapan bisnis.
Agen Swarm mengarahkan pesan ke sesi chatgpt aktif (agen) untuk setiap saluran WebSocket menggunakan parameter URL ClientID. Untuk setiap obrolan baru dengan seseorang, saluran baru dibuat dengan segerombolan agennya sendiri.
Sesi chatgpt aktif (agen) di Swarm dapat diubah dengan menjalankan alat.
Semua sesi klien menggunakan riwayat pesan obrolan bersama untuk semua agen. Setiap riwayat obrolan klien menyimpan 25 pesan terakhir dengan rotasi. Antara sesi chatgpt (agen), hanya asisten dan jenis pesan pengguna yang dikirimkan, sementara pesan sistem dan alat terbatas pada ruang lingkup agen, sehingga setiap agen hanya tahu alat yang berhubungan dengannya. Akibatnya, setiap sesi chatgpt (agen) memiliki prompt sistem yang unik.
Jika output agen gagal validasi (panggilan alat yang tidak ada, panggilan alat dengan argumen yang salah, output kosong, tag XML dalam output, atau JSON dalam output), algoritma penyelamatan akan mencoba memperbaiki model. Pertama, itu akan menyembunyikan pesan sebelumnya dari model; Jika itu tidak membantu, itu akan mengembalikan placeholder seperti "Maaf, saya tidak mengerti. Bisakah Anda mengulangi?"
addAgent - Daftarkan Agen BaruaddCompletion - Daftarkan Model Bahasa Baru: Cloud, Lokal, atau MockaddSwarm - Daftarkan sekelompok agen untuk memproses obrolan penggunaaddTool - Daftarkan alat untuk mengintegrasikan model bahasa ke dalam sistem eksternalchangeAgent - Ubah Agen Aktif di Swarmcomplete - Minta tanggapan terhadap pesan yang disampaikan ke Agen Swarmsession - Buat sesi obrolan, berikan panggilan balik untuk penyelesaian sesi dan pengiriman pesan barugetRawHistory - Dapatkan Sejarah Sistem Raw untuk DebugginggetAgentHistory - Dapatkan sejarah yang terlihat oleh agen yang disesuaikan dengan mekanisme pemulihan diri dan penerima pesancommitToolOutput - Kirim Hasil Eksekusi Fungsi ke Sejarah. Jika suatu fungsi dipanggil, agen membeku sampai menerima responscommitSystemMessage - Sistem Suplemen Prompt dengan input barucommitFlush - Percakapan yang jelas untuk agen jika tanggapan yang salah diterima atau model secara keliru memanggil alat secara rekursifexecute - Mintalah jaringan saraf untuk mengambil inisiatif dan menulis kepada pengguna terlebih dahuluemit - Kirim pesan yang sudah disiapkan sebelumnya ke penggunagetLastUserMessage - Dapatkan pesan terakhir dari pengguna (tanpa mempertimbangkan dieksekusi)commitUserMessage - Simpan pesan pengguna dalam riwayat obrolan tanpa tanggapan. Jika Pengguna Spams Pesan Tanpa Menunggu Pemrosesan PermintaangetAgentName - Dapatkan Nama Agen AktifgetUserHistory - Dapatkan riwayat pesan penggunagetAssistantHistory - Dapatkan Sejarah Pesan Model BahasagetLastAssistantMessage - Dapatkan pesan terakhir dari model bahasagetLastSystemMessage - Dapatkan Suplemen Prompt Sistem Terakhir