Topic Suggestion
Előfeltételek: Topic Extractor (a jelenlegi megvalósításban)
Ráépül: A QA Answer után megjelenítendő kérdés-javaslatok
Egy chatbot-rendszert használva előfordulhat, hogy egy felhasználónak nem feltétlen világos, hogy milyen jellegű kérdéseket tehet fel, esetleg nem feltétlen akarja leírni minden kérdését, vagy csak egyszerűen faalapú chatbot-okhoz van hozzászokva. Ilyenkor hasznos lehet, ha tudunk adni a beszélgetéshez releváns „továbbhaladási javaslatokat“. A suggestion routing ezt a problémát kívánja kezelni egy specifikus módon.
Üzenetjavaslatok előleges kiválasztása
Adott: A felhasználói \(q\) kérdés és a \(H\) korábbi üzenetváltás, lehetséges \(\mathcal{R}\) üzenetjavaslatok halmaza, és tetszőleges \(C\) segédinformáció (mely a \(q\)-ra való esetleges választ nem tartalmazhatja).
Feladat: Kiválasztani néhány javaslatot \(\mathcal{R}\)-ből, melyek a \(q\) üzenetre adott válasz után értelmes folytatásai lehetnek a beszélgetésnek a felhasználó részéről.
A feladat nevében az „előleges“ szó arra utal, hogy a potenciális folytatásokat úgy próbáljuk meghatározni, hogy magát a választ még nem adtuk meg. Ennek oka, hogy így képes párhuzamosan futni a válaszadás flow és a javaslatok előállítása, azaz az eszköz nem befolyásolja a futási időt.
Valójában nem futtatjuk párhuzamosan
Bár az eszköz ilyen szemlélettel lett kialakítva, a jelenlegi implementáció nem használja ki a lehetőséget, hogy párhuzamosan futtassa azt.
A megvalósítás
Koncepció
Az implementáció két részre bontja a feladatot. Az első az, hogy meghatározzuk, hogy a felhasználó egy általunk definiált fa-szerű struktúrában épp hol jár. A fa racionális mértékig igyekszik modellezni beszélgetés-állapotokat. Ezt próbáljuk nem túlzottan mélyen, de üzleti igényeket kielégítő állapotban tartani.
Miután kinyertük, hogy a felhasználó az általunk definiált beszélgetés-hálóban hol jár, a helyzet alapján a folyamat második lépésében megpróbáljuk meghatározni, hogy a helyzet lehetséges folytatásai közül melyek értelmesek.
A folyamat mindkét lépéséhez egy-egy LLM hívást használunk, ez jelenleg gpt-4.1.
Technikai részletek
A teljes folyamatot a levezénylését a TopicSuggestionService végzi, ez biztosítja a be- és kilépési pontot a pipeline-hoz.
A folyamat első fele a TreeElementExtractorService munkája, ennek konfigurációs beállításai a tool-configuration.yml fájlban találhatók, a project.tools.tree-element-extractor mezőben. Maga a fa tárolása TypeTag-ekre darabolt, ami a gyakorlatban úgy néz ki, hogy a
mappában minden TypeTag értékre van egy suggestion-{érték}.yml fájl, ami ahhoz a témához tartozó részfát tárolja. A fa kezelését a SuggestionTreeMappingService osztály végzi, ezt a folyamat mindkét fázisa használja.
A TreeElementExtractorService a Topic Extractor TypeTag kimenete alapján betölti a megfelelő részfát, és csak azt adja át a prompt-nak. Ekkor kapunk egy \((p, v)\) csúcspárt a fában, ahol \(p\) az \(v\) (egyik) szülője.
Miért kell \(p\)?
Bár faként referálunk a tárolt adatstruktúrára, nem feltétlen kell, hogy teljesen fa legyen. Specifikus módokon ugyanis megengedett, hogy egy csúcshoz két szülő is tartozzon (azaz mindkét állapotból „ajánlhatjuk“ a csúcsot). Ez olyan szempontból nem meglepő, hogy potenciális ajánlási lehetőségeket tetszőleges irányított gráffal is leírhatnánk (többé-kevésbé), így a fa fogalmának relaxálása természetes.
Megvalósítás szempontjából \(p\) az egy csúcs testvéreinek meghatározásához szükséges.
A második lépésben az így kapott \((p, v)\) csúcspár alapján a SuggestionRoutingService összeállítja a lehetséges javaslatokat. Amennyiben a \(v\) csúcsnak vannak gyerekei, ezek alkotják az \(\mathcal{R}'\) halmazt. Amennyiben nincsenek, akkor a \(p\)-felőli testvérei alkotják \(\mathcal{R'}\)-t.
Az így kapott \(\mathcal{R}'\) üzenetjavaslatok alkotják az újabb LLM hívás alapját. Itt a prompt-ban arra kérjük az LLM-et, hogy értékelje egy 0-10 skálán, hogy a beszélgetés jelenlegi állapota alapján mennyire érdekes a felhasználónak egy-egy javaslat. A 10 pontra értékelteket eltávolítjuk (magyarázat lentebb), és a kapott sorrend lesz a javaslatok relevancia szerint rendezett változata.
Miért távolítjuk el a legrelevánsabb javaslatokat?
Az prompt-ban azt kérdezzük, hogy \(q\) alapján mennyire relevánsak a találatok, nem pedig a \(q\) után adott választ követően mennyire lesznek azok. Ennek következtében ha van egy olyan javaslat, ami \(q\)-val pontosan egyező irányba vinné a beszélgetést, az maximális pontot fog kapni (ezért kell eltávolítani).
A SuggestionRoutingService konfigurációs beállításai a tool-configuration.yml fájlban találhatók, a project.tools.suggestion-routing mezőben.