top of page

Het bouwen van een responsieve tekstgebruikersinterface (TUI) - Achtergrond Language Model (LLM) aanroepen gebruiken zonder de interface te bevriezen

Foto van schrijver: Rene LuijkRene Luijk

Bijgewerkt op: 26 okt 2024

Underdog Cowboy is een open-source project onder de permissieve MIT-licentie en vormt de brug naar het benutten van de kracht van Language Models (LLM's) zonder dat je uitgebreide programmeerkennis nodig hebt. Het is ontworpen om individuen en teams te helpen hun ideeën om te zetten in functionele prototypes, die programmeurs verder kunnen verfijnen en opschalen.



 

Zoek je de kern zonder de technische details? 💡

Geïnteresseerd in de essentie van onze UX-gedreven AI-innovatie, maar zonder de technische diepgang? We hebben ook een toegankelijke versie van dit verhaal "Revolutionair AI-interactie: Hoe Underdog Cowboy jouw in controle houdt". Ontdek hoe we AI gebruiksvriendelijk maken en de toekomst van mens-machine samenwerking vormgeven, uitgelegd in heldere taal. Perfect voor besluitvormers, innovators en iedereen die de grote lijnen wil begrijpen. Klik hier voor een beknopt overzicht van hoe Underdog Cowboy AI toegankelijk maakt voor iedereen.

 

Om de kloof te overbruggen tussen de complexe wereld van AI-ontwikkeling en gebruikers met diverse technische vaardigheden, richten we ons op het creëren van vereenvoudigde gebruikerservaringen die individuen in staat stellen het potentieel van AI te benutten en innovatie vooruit te helpen. We maken naadloze samenwerking mogelijk tussen niet-technische innovators en ontwikkelaars, waarbij een gedeeld begrip ontstaat dat de ontwikkeling van AI-projecten versnelt.


Deze filosofie heeft direct invloed gehad op het ontwerp en de ontwikkeling van onze tekstgebaseerde gebruikersinterface (TUI), gebaseerd op de Python-bibliotheek Textual. Deze verbetert de gebruikerservaring voor gestructureerde processen door naadloze interactie met een set AI-tools mogelijk te maken. Een grote technische uitdaging was hoe meerdere achtergrond LLM-aanroepen vanuit de TUI uit te voeren zonder de interface te bevriezen, zodat gebruikers soepel door kunnen werken terwijl deze taken worden verwerkt. Deze responsiviteit is essentieel voor een vloeiende ervaring en om de interface interactief te houden tijdens achtergrondoperaties.


Om dit op te lossen, heb ik een combinatie van asyncio en een ThreadPoolExecutor gebruikt om LLM-aanroepen los te koppelen van de gebruikersinterface. Hierdoor kan het zware LLM-verwerkingswerk asynchroon worden uitgevoerd, zodat de hoofdevenementlus responsief blijft.


LLM-aanroepen loskoppelen van de UI

Om dit te bereiken, gebruik ik asyncio in combinatie met een ThreadPoolExecutor om LLM-aanroepen op de achtergrond uit te voeren. Door deze taken uit te besteden blijft de hoofdevenementlus van de TUI responsief, zodat gebruikers kunnen blijven communiceren met de interface. Een asynchrone taakreeks (asyncio.Queue) wordt gebruikt om deze aanroepen te beheren, zodat ze efficiënt worden verwerkt zonder concurrentieproblemen te riskeren.


Event-Driven Integratie

Een belangrijk onderdeel van deze oplossing is de integratie van de LLM-aanroepen in de event-driven architectuur van de TUI. Door gebruik te maken van een mixin (MessageEmitterMixin), verstuurt de LLM-manager gebeurtenissen zoals LLMCallComplete of LLMCallError bij voltooiing of falen van een taak. Deze gebeurtenissen worden vervolgens opgevangen door UI-componenten, zodat resultaten naadloos in de interface worden weergegeven.


Neem bijvoorbeeld de integratie binnen de AnalyzeUI-klasse, die een Textual Widget is:

@on(LLMCallComplete)
async def on_llm_call_complete(self, event: LLMCallComplete) -> None:
    if event.input_id == "analysis":
        self.update_and_show_result(event.result)
        self.query_one("#loading-indicator").add_class("hidden")

@on(LLMCallError)
async def on_llm_call_error(self, event: LLMCallError) -> None:
    if event.input_id == "analysis":
        self.show_error(event.error)
        self.query_one("#loading-indicator").add_class("hidden")

Dit zorgt ervoor dat zodra een LLM-taak is voltooid of mislukt, de gebruikersinterface onmiddellijk wordt bijgewerkt om het resultaat weer te geven, zonder dat de interface niet-responsief wordt.

Uitbreidbaarheid voor LLM-functies

De architectuur van dit systeem is zeer uitbreidbaar. Nieuwe LLM-gerelateerde functies kunnen in Widgets worden opgenomen met behulp van de submit_llm_call()-methode. Met een eenvoudige import kunnen deze functies in verschillende delen van de TUI worden hergebruikt, waardoor het gemakkelijk is om functionaliteit toe te voegen of aan te passen. Deze methode behandelt LLM-functieaanroepen, inclusief metadata zoals pre-prompts en post-prompts, en de functies worden asynchroon doorgegeven, zodat de gebruikersinterface gedurende deze tijd responsief blijft.


Hier is een voorbeeld van het gebruik van submit_llm_call() om een analyse te initiëren:

asyncio.create_task(self.llm_call_manager.submit_llm_call(
    llm_function=run_analysis,
    llm_config=llm_config,
    agent_name=current_agent,
    input_id="analysis",
    pre_prompt="Analyze this agent definition:",
    post_prompt=None
))

Deze aanroep voegt de taak toe aan een asynchrone wachtrij, die de LLMCallManager vervolgens op de achtergrond verwerkt, zodat de TUI volledig interactief blijft.

Veel voorkomende problemen aanpakken

Tijdens het ontwikkelingsproces heb ik verschillende algemene uitdagingen aangepakt:


  • Threadveiligheid: Het beheren van gedeelde resources binnen ThreadPoolExecutor vereist zorgvuldige synchronisatie om racecondities te voorkomen. Het gebruik van een asyncio.Queue helpt taken te serialiseren en consistentie te behouden.


  • Statusconsistentie: Het in sync houden van de UI-status met lopende achtergrondtaken is cruciaal. De event-driven aanpak zorgt ervoor dat wijzigingen van LLM-verwerking snel in de UI worden weerspiegeld door berichten te plaatsen wanneer taken zijn voltooid of fouten optreden.


  • Responsiviteit: Het balanceren van meerdere achtergrondtaken terwijl een soepele, responsieve UI werd gegarandeerd, was een belangrijke focus. De combinatie van asynchronous taakverdeling en event-driven UI-updates maakt een non-blocking gebruikerservaring mogelijk.


Deze aanpak stelt de TUI in staat een vloeiende, non-blocking ervaring te bieden, waardoor gebruikers de kracht van LLM's efficiënt binnen gestructureerde werkstromen kunnen benutten.


Ik geniet er echt van om deze oplossing naar een hoger niveau te tillen, maar het is cruciaal om ervoor te zorgen dat dit aansluit bij het eerste gebruiksgeval dat het moest dienen. Deze balanceeract tussen streven naar meer verbeteringen en trouw blijven aan het initiële gebruiksgeval kan mentaal en creatief veeleisend zijn - vooral gezien de creatieve energie en analytisch werk dat erin is gestoken. De beperkingen - zowel mentaal als creatief - brengen een emotionele uitdaging met zich mee, omdat het betekent dat je moet loslaten, zelfs wanneer er nog zichtbaar verbeteringspotentieel is.


Dus bij deze, dit blogbericht markeert het einde van dit deel van de codering, en ik zal het gaan voorbereiden voor opname in de volgende release.


Tot slot, wat is het toekomstige potentieel?


Toekomstig potentieel

Één van de meest opwindende toekomstige richtingen voor deze oplossing is de integratie van een op Redis gebaseerde aanpak om multi-user functionaliteit mogelijk te maken. Dit zou meerdere gebruikers in staat stellen om in realtime samen te werken aan dezelfde werkstromen, waardoor zowel de schaalbaarheid als de gebruikerservaring wordt verbeterd. Door Redis te gebruiken voor statusbeheer en synchronisatie, kunnen gebruikersacties consistent worden weerspiegeld in alle verbonden clients, waardoor nieuwe mogelijkheden ontstaan voor collaboratieve AI-ontwikkeling en gedeelde werkstromen. Bovendien kan Redis het mogelijk maken om geactiveerde processen uit te voeren, zelfs nadat de TUI is gesloten, via een lokale of cloudgebaseerde oplossing. Deze verbeteringen sluiten aan bij de missie van Underdog Cowboy om geavanceerde AI-interacties toegankelijk en intuïtief te maken, waardoor uw innovatieve ideeën kunnen floreren en evolueren.

Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page