AI-agents in Azure Cosmos DB
AI-agents zijn ontworpen om specifieke taken uit te voeren, vragen te beantwoorden en processen voor gebruikers te automatiseren. Deze agents variëren sterk in complexiteit. Ze variëren van eenvoudige chatbots tot copiloten, tot geavanceerde AI-assistenten in de vorm van digitale of robotsystemen die complexe werkstromen autonoom kunnen uitvoeren.
Dit artikel bevat conceptuele overzichten en gedetailleerde implementatievoorbeelden voor AI-agents.
Wat zijn AI-agents?
In tegenstelling tot zelfstandige grote taalmodellen (LLM's) of op regels gebaseerde software-/hardwaresystemen hebben AI-agents de volgende algemene functies:
- Planning: AI-agents kunnen acties plannen en sequentieeren om specifieke doelen te bereiken. De integratie van LLM's heeft hun planningsmogelijkheden veranderd.
- Hulpprogrammagebruik: Geavanceerde AI-agents kunnen verschillende hulpprogramma's gebruiken, zoals code-uitvoering, zoek- en rekenmogelijkheden, om taken effectief uit te voeren. AI-agents gebruiken vaak hulpprogramma's via functie-aanroepen.
- Waarneming: AI-agents kunnen informatie van hun omgeving waarnemen en verwerken om ze interactiever en contextbewuster te maken. Deze informatie omvat visuele, auditieve en andere sensorische gegevens.
- Geheugen: AI-agents hebben de mogelijkheid om eerdere interacties (toolgebruik en perceptie) en gedrag (hulpprogrammagebruik en planning) te onthouden. Ze slaan deze ervaringen op en voeren zelfs zelfreflectie uit om toekomstige acties te informeren. Dit geheugenonderdeel zorgt voor continuïteit en verbetering van de prestaties van agents in de loop van de tijd.
Notitie
Het gebruik van het termgeheugen in de context van AI-agents verschilt van het concept computergeheugen (zoals vluchtig, niet-compatibel en permanent geheugen).
Copilots
Copilots zijn een type AI-agent. Ze werken samen met gebruikers in plaats van onafhankelijk te werken. In tegenstelling tot volledig geautomatiseerde agents bieden copilots suggesties en aanbevelingen om gebruikers te helpen bij het voltooien van taken.
Wanneer een gebruiker bijvoorbeeld een e-mailbericht schrijft, kan een copilot zinnen, zinnen of alinea's voorstellen. De gebruiker kan de copilot ook vragen om relevante informatie te vinden in andere e-mailberichten of bestanden om de suggestie te ondersteunen (zie ophalen-augmented generation). De gebruiker kan de voorgestelde passages accepteren, negeren of bewerken.
Autonome agenten
Autonome agenten kunnen onafhankelijker werken. Wanneer u autonome agents instelt om u te helpen bij de samenstelling van e-mail, kunt u deze inschakelen om de volgende taken uit te voeren:
- Raadpleeg bestaande e-mailberichten, chats, bestanden en andere interne en openbare informatie die betrekking heeft op het onderwerp.
- Voer kwalitatieve of kwantitatieve analyses uit op de verzamelde informatie en trek conclusies die relevant zijn voor de e-mail.
- Schrijf de volledige e-mail op basis van de conclusies en neem ondersteunende bewijzen op.
- Voeg relevante bestanden toe aan het e-mailbericht.
- Controleer het e-mailbericht om ervoor te zorgen dat alle opgenomen informatie feitelijk nauwkeurig is en dat de beweringen geldig zijn.
- Selecteer de juiste geadresseerden voor Aan, CC en BCC en zoek hun e-mailadressen op.
- Plan een geschikt tijdstip om het e-mailbericht te verzenden.
- Voer follow-ups uit als er reacties worden verwacht maar niet ontvangen.
U kunt de agents configureren om elk van de voorgaande taken uit te voeren met of zonder menselijke goedkeuring.
Systemen met meerdere agents
Een populaire strategie voor het bereiken van krachtige autonome agents is het gebruik van systemen met meerdere agents. In systemen met meerdere agents kunnen meerdere autonome agents, in digitale of robotvorm, samenwerken of samenwerken om individuele of collectieve doelen te bereiken. Agenten in het systeem kunnen onafhankelijk functioneren en beschikken over hun eigen kennis of informatie. Elke agent kan ook de mogelijkheid hebben om de omgeving waar te nemen, beslissingen te nemen en acties uit te voeren op basis van de doelstellingen.
Systemen met meerdere agents hebben de volgende belangrijke kenmerken:
- Autonoom: elke agent functioneert onafhankelijk. Het neemt zijn eigen beslissingen zonder directe menselijke tussenkomst of controle door andere agenten.
- Interactief: agents communiceren en samenwerken met elkaar om informatie te delen, te onderhandelen en hun acties te coördineren. Deze interactie kan optreden via verschillende protocollen en communicatiekanalen.
- Doelgericht: Agents in een systeem met meerdere agents zijn ontworpen om specifieke doelen te bereiken, die kunnen worden afgestemd op afzonderlijke doelstellingen of een gedeelde doelstelling tussen de agents.
- Gedistribueerd: systemen met meerdere agents werken op een gedistribueerde manier, zonder één controlepunt. Deze distributie verbetert de robuustheid, schaalbaarheid en efficiëntie van resources van het systeem.
Een systeem met meerdere agents biedt de volgende voordelen ten opzichte van een copilot of één exemplaar van LLM-deductie:
- Dynamische redenering: Vergeleken met keten-van-gedachte- of boomstructuurprompts, bieden systemen met meerdere agents dynamische navigatie via verschillende redeneringspaden.
- Geavanceerde mogelijkheden: systemen met meerdere agents kunnen complexe of grootschalige problemen afhandelen door grondige besluitvormingsprocessen uit te voeren en taken over meerdere agents te distribueren.
- Verbeterd geheugen: systemen met meerdere agents met geheugen kunnen de contextvensters van LLM's overwinnen om beter inzicht en informatieretentie mogelijk te maken.
Implementatie van AI-agents
Redenering en planning
Complexe redenering en planning zijn het kenmerk van geavanceerde autonome agenten. Populaire frameworks voor autonome agents bevatten een of meer van de volgende methodologieën (met koppelingen naar arXiv-archiefpagina's) voor redenering en planning:
-
Verbeter de keten van gedachte door het model expliciet vervolgvragen te stellen (en te beantwoorden) voordat u de eerste vraag beantwoordt.
-
Gebruik LLM's om zowel redeneringstraceringen als taakspecifieke acties op een interleaved manier te genereren. Redeneringstraceringen helpen het model actieplannen te genereren, bij te houden en bij te werken, samen met het afhandelen van uitzonderingen. Met acties kan het model verbinding maken met externe bronnen, zoals knowledge bases of omgevingen, om aanvullende informatie te verzamelen.
-
Maak een plan om de hele taak te verdelen in kleinere subtaken en voer vervolgens de subtaken uit volgens het plan. Met deze aanpak worden de berekeningsfouten, fouten met ontbrekende stappen en semantische misverstandfouten beperkt die vaak voorkomen in een keten van gedachten die geen kans geven.
-
Gebruik reflexiemiddelen die verbaal weerspiegelen op feedbacksignalen van taken. Deze agents onderhouden hun eigen reflecterende tekst in een episodic geheugenbuffer om betere besluitvorming te veroorzaken in volgende proeven.
Frameworks
Verschillende frameworks en hulpprogramma's kunnen de ontwikkeling en implementatie van AI-agents vergemakkelijken.
Voor het gebruik en de perceptie van hulpprogramma's die geen geavanceerde planning en geheugen vereisen, zijn sommige populaire LLM orchestrator-frameworks LangChain, LlamaIndex, Prompt Flow en Semantic Kernel.
Voor geavanceerde en autonome plannings- en uitvoeringswerkstromen heeft AutoGen de multiagentgolf aangedreven die eind 2022 begon. Met de Assistants-API van OpenAI kunnen de gebruikers zelf agents maken binnen het GPT-ecosysteem. LangChain Agents en LlamaIndex Agents zijn ook rond dezelfde tijd ontstaan.
Tip
Het implementatievoorbeeld verderop in dit artikel laat zien hoe u een eenvoudig multiagentsysteem bouwt met behulp van een van de populaire frameworks en een geïntegreerd geheugensysteem voor agents.
Geheugensysteem van AI-agent
De gangbare praktijk voor het experimenteren met ai-verbeterde toepassingen van 2022 tot en met 2024 heeft zelfstandige databasebeheersystemen gebruikt voor verschillende gegevenswerkstromen of -typen. U kunt bijvoorbeeld een in-memory database gebruiken voor caching, een relationele database voor operationele gegevens (inclusief tracerings-/activiteitenlogboeken en LLM-gespreksgeschiedenis) en een pure vectordatabase voor het insluiten van beheer.
Deze praktijk van het gebruik van een complex web van zelfstandige databases kan echter de prestaties van een AI-agent schaden. Het integreren van al deze verschillende databases in een samenhangende, interoperabele en tolerante geheugensysteem voor AI-agents is een eigen uitdaging.
Bovendien zijn veel van de veelgebruikte databaseservices niet optimaal voor de snelheid en schaalbaarheid die AI-agentsystemen nodig hebben. De afzonderlijke zwakke punten van deze databases worden verergerd in systemen met meerdere agents.
In-memory databases
In-memory databases zijn uitstekend geschikt voor snelheid, maar kunnen moeite hebben met de grootschalige gegevenspersistentie die AI-agents nodig hebben.
Relationele databases
Relationele databases zijn niet ideaal voor de uiteenlopende modaliteiten en vloeiende schema's van gegevens die agents verwerken. Relationele databases vereisen handmatige inspanningen en zelfs downtime voor het beheren van inrichting, partitionering en sharding.
Pure vectordatabases
Pure vectordatabases zijn doorgaans minder effectief voor transactionele bewerkingen, realtime-updates en gedistribueerde workloads. De populaire pure vectordatabases bieden tegenwoordig meestal het volgende:
- Geen garantie voor lees- en schrijfbewerkingen.
- Beperkte opnamedoorvoer.
- Lage beschikbaarheid (minder dan 99,9%, of een jaarlijkse storing van 9 uur of meer).
- Eén consistentieniveau (uiteindelijk).
- Een bronintensieve vectorindex in het geheugen.
- Beperkte opties voor multitenancy.
- Beperkte beveiliging.
Kenmerken van een robuust GEHEUGENsysteem voor AI-agents
Net zoals efficiënte databasebeheersystemen essentieel zijn voor de prestaties van softwaretoepassingen, is het essentieel om LLM-agents te voorzien van relevante en nuttige informatie om hun deductie te begeleiden. Robuuste geheugensystemen maken het mogelijk om verschillende soorten informatie te organiseren en op te slaan die de agents tijdens deductietijd kunnen ophalen.
Op dit moment maken LLM-toepassingen vaak gebruik van het ophalen van uitgebreide generatie die gebruikmaakt van eenvoudige semantische zoekopdrachten of vectorzoekopdrachten om passages of documenten op te halen. Vectorzoekopdrachten kunnen nuttig zijn voor het vinden van algemene informatie. Maar vectorzoekopdrachten leggen mogelijk niet de specifieke context, structuur of relaties vast die relevant zijn voor een bepaalde taak of een bepaald domein.
Als de taak bijvoorbeeld is om code te schrijven, kan vectorzoekopdrachten de syntaxisstructuur, de indeling van het bestandssysteem, codeoverzichten of API-handtekeningen die belangrijk zijn voor het genereren van coherente en juiste code, mogelijk niet ophalen. Als de taak werkt met tabelgegevens, kan vectorzoekopdrachten het schema, de refererende sleutels, de opgeslagen procedures of de rapporten die nuttig zijn voor het opvragen of analyseren van de gegevens, mogelijk niet ophalen.
Weaving samen een web van zelfstandige in-memory, relationele en vectordatabases (zoals eerder beschreven) is geen optimale oplossing voor de verschillende gegevenstypen. Deze aanpak werkt mogelijk voor prototypische agentsystemen. Het voegt echter complexiteits- en prestatieknelpunten toe die de prestaties van geavanceerde autonome agents kunnen belemmeren.
Een robuust geheugensysteem moet de volgende kenmerken hebben.
Multimodale
Geheugensystemen van AI-agents moeten verzamelingen bieden waarmee metagegevens, relaties, entiteiten, samenvattingen of andere soorten informatie worden opgeslagen die nuttig kunnen zijn voor verschillende taken en domeinen. Deze verzamelingen kunnen worden gebaseerd op de structuur en indeling van de gegevens, zoals documenten, tabellen of code. Of ze kunnen worden gebaseerd op de inhoud en betekenis van de gegevens, zoals concepten, koppelingen of procedurestappen.
Geheugensystemen zijn niet alleen essentieel voor AI-agents. Ze zijn ook belangrijk voor de mensen die deze agents ontwikkelen, onderhouden en gebruiken.
Mensen moeten bijvoorbeeld in bijna realtime de plannings- en uitvoeringswerkstromen van agents controleren. Tijdens het toezicht kunnen mensen met richtlijnen interjecteren of inline wijzigingen aanbrengen in de dialogen of monoloog van agents. Mensen moeten mogelijk ook de redenering en acties van agents controleren om de geldigheid van de uiteindelijke uitvoer te controleren.
Interacties tussen mensen/agents zijn waarschijnlijk in natuurlijke of programmeertalen, terwijl agents 'denken', 'leren' en 'onthouden' via insluitingen. Dit verschil vormt een andere vereiste voor de consistentie van geheugensystemen voor gegevensmodaliteiten.
Operationeel
Geheugensystemen moeten geheugenbanken bieden die informatie opslaan die relevant is voor de interactie met de gebruiker en de omgeving. Dergelijke informatie kan bestaan uit chatgeschiedenis, gebruikersvoorkeuren, sensorische gegevens, beslissingen genomen, geleerde feiten of andere operationele gegevens die met hoge frequentie en bij grote volumes worden bijgewerkt.
Deze geheugenbanken kunnen de agenten helpen bij het onthouden van informatie op korte en lange termijn, voorkomen dat ze zichzelf herhalen of tegenspreken en de samenhang van taken behouden. Deze vereisten moeten waar zijn, zelfs als de agents een groot aantal niet-gerelateerde taken achter elkaar uitvoeren. In geavanceerde gevallen kunnen agents ook talloze vertakkingsplannen testen die op verschillende punten afwijken of convergeren.
Deelbaar maar ook scheidend
Op macroniveau moeten geheugensystemen meerdere AI-agents in staat stellen om samen te werken aan een probleem of verschillende aspecten van het probleem te verwerken door gedeeld geheugen te bieden dat toegankelijk is voor alle agents. Gedeeld geheugen kan de uitwisseling van informatie en de coördinatie van acties tussen de agents vergemakkelijken.
Tegelijkertijd moet het geheugensysteem agents toestaan om hun eigen persona en kenmerken te behouden, zoals hun unieke verzamelingen prompts en herinneringen.
Een robuust geheugensysteem voor AI-agents bouwen
De voorgaande kenmerken vereisen dat AI-agentgeheugensystemen zeer schaalbaar en snel zijn. Het kan lastig zijn om verschillende databases in het geheugen, relationele databases en vectordatabases (zoals eerder beschreven) samen te voegen voor toepassingen die in een vroeg stadium met AI zijn ingeschakeld. Deze aanpak voegt echter complexiteits- en prestatieknelpunten toe die de prestaties van geavanceerde autonome agents kunnen belemmeren.
In plaats van alle zelfstandige databases kan Azure Cosmos DB fungeren als een geïntegreerde oplossing voor AI-agentgeheugensystemen. Dankzij de robuustheid is de ChatGPT-service van OpenAI dynamisch geschaald met hoge betrouwbaarheid en weinig onderhoud. Mogelijk gemaakt door een atom-record-sequence engine, is het de eerste wereldwijd gedistribueerde NoSQL-, relationele en vector databaseservice die een serverloze modus biedt. AI-agents die zijn gebouwd op basis van Azure Cosmos DB bieden snelheid, schaal en eenvoud.
Snelheid
Azure Cosmos DB biedt latentie van één cijferige milliseconden. Deze mogelijkheid maakt het geschikt voor processen die snelle gegevenstoegang en -beheer vereisen. Deze processen omvatten caching (zowel traditionele als semantische caching, transacties en operationele workloads.
Lage latentie is van cruciaal belang voor AI-agents die complexe redeneringen moeten uitvoeren, realtime beslissingen moeten nemen en onmiddellijke antwoorden moeten bieden. Daarnaast biedt het gebruik van het DiskANN-algoritme van de service nauwkeurige en snelle vectorzoekopdrachten met minimaal geheugenverbruik.
Schaal wijzigen
Azure Cosmos DB is ontworpen voor wereldwijde distributie en horizontale schaalbaarheid. Het biedt ondersteuning voor I/O in meerdere regio's en multitenancy.
De service zorgt ervoor dat geheugensystemen naadloos kunnen worden uitgebreid en snel groeiende agents en bijbehorende gegevens kunnen bijhouden. De beschikbaarheidsgarantie in de SLA (Service Level Agreement) wordt omgezet in minder dan 5 minuten downtime per jaar. Pure vector database services worden daarentegen geleverd met 9 uur of meer downtime. Deze beschikbaarheid biedt een solide basis voor bedrijfskritieke workloads. Tegelijkertijd kunnen de verschillende servicemodellen in Azure Cosmos DB, zoals gereserveerde capaciteit of serverloos, helpen bij het verlagen van de financiële kosten.
Eenvoud
Azure Cosmos DB kan gegevensbeheer en -architectuur vereenvoudigen door meerdere databasefunctionaliteiten te integreren in één, samenhangend platform.
De geïntegreerde vectordatabasemogelijkheden kunnen insluitingen opslaan, indexeren en query's uitvoeren naast de bijbehorende gegevens in natuurlijke of programmeertalen. Deze mogelijkheid maakt meer gegevensconsistentie, schaal en prestaties mogelijk.
De flexibiliteit ondersteunt de verschillende modaliteiten en vloeiende schema's van de metagegevens, relaties, entiteiten, samenvattingen, chatgeschiedenis, gebruikersvoorkeuren, sensorische gegevens, beslissingen, geleerde feiten of andere operationele gegevens die betrokken zijn bij agentwerkstromen. De database indexeert automatisch alle gegevens zonder schema- of indexbeheer, waardoor AI-agents snel en efficiënt complexe query's kunnen uitvoeren.
Azure Cosmos DB wordt volledig beheerd, waardoor de overhead van databasebeheertaken, zoals schalen, patchen en back-ups, wordt geëlimineerd. Zonder deze overhead kunnen ontwikkelaars zich richten op het bouwen en optimaliseren van AI-agents zonder dat ze zich zorgen hoeven te maken over de onderliggende gegevensinfrastructuur.
Geavanceerde functies
Azure Cosmos DB bevat geavanceerde functies, zoals wijzigingenfeed, waarmee u wijzigingen in gegevens in realtime kunt bijhouden en erop kunt reageren. Deze mogelijkheid is handig voor AI-agents die onmiddellijk op nieuwe informatie moeten reageren.
Bovendien zorgt de ingebouwde ondersteuning voor schrijfbewerkingen met meerdere masters voor hoge beschikbaarheid en tolerantie voor continue werking van AI-agents, zelfs na regionale storingen.
De vijf beschikbare consistentieniveaus (van sterk tot uiteindelijk) kunnen ook geschikt zijn voor verschillende gedistribueerde workloads, afhankelijk van de scenariovereisten.
Tip
U kunt kiezen uit twee Azure Cosmos DB-API's om uw AI-agentgeheugensysteem te bouwen:
- Azure Cosmos DB for NoSQL, dat 99,999% beschikbaarheidsgarantie biedt en drie vectorzoekalgoritmen biedt: IVF, HNSW en DiskANN
- Azure Cosmos DB op basis van vCore voor MongoDB, dat 99,995% beschikbaarheidsgarantie biedt en twee vectorzoekalgoritmen biedt: IVF en HNSW (DiskANN komt eraan)
Zie de service-SLA's voor informatie over de beschikbaarheidsgaranties voor deze API's.
Implementatievoorbeeld
In deze sectie wordt de implementatie van een autonome agent besproken voor het verwerken van reisvragen en boekingen in een reisaanvraag voor een cruiselijn.
Chatbots zijn een langstaand concept, maar AI-agents gaan verder dan eenvoudige menselijke gesprekken om taken uit te voeren op basis van natuurlijke taal. Deze taken vereist traditioneel gecodeerde logica. De AI-reisagent in dit implementatievoorbeeld maakt gebruik van het LangChain Agent-framework voor agentplanning, hulpprogrammagebruik en perceptie.
Het geïntegreerde geheugensysteem van de AI-reisagent maakt gebruik van de vectordatabase- en documentopslagmogelijkheden van Azure Cosmos DB om vragen van reizigers aan te pakken en reisreserveringen te vergemakkelijken. Het gebruik van Azure Cosmos DB voor dit doel zorgt voor snelheid, schaal en eenvoud, zoals eerder is beschreven.
De voorbeeldagent werkt binnen een Python FastAPI-back-end. Het ondersteunt gebruikersinteracties via een React JavaScript-gebruikersinterface.
Vereisten
- Een Azure-abonnement. Als u nog geen account hebt, kunt u Azure Cosmos DB 30 dagen gratis proberen zonder een Azure-account te maken. Voor de gratis proefversie is geen creditcard vereist en volgt geen toezegging na de proefperiode.
- Een account voor de OpenAI-API of Azure OpenAI-service.
- Een vCore-cluster in Azure Cosmos DB voor MongoDB. U kunt er een maken door deze quickstart te volgen.
- Een geïntegreerde ontwikkelomgeving, zoals Visual Studio Code.
- Python 3.11.4 geïnstalleerd in de ontwikkelomgeving.
Het project downloaden
Alle code- en voorbeeldgegevenssets zijn beschikbaar in deze GitHub-opslagplaats. De opslagplaats bevat de volgende mappen:
- loader: Deze map bevat Python-code voor het laden van voorbeelddocumenten en vector-insluitingen in Azure Cosmos DB.
- API: Deze map bevat het Python FastAPI-project voor het hosten van de AI-reisagent.
- web: Deze map bevat code voor de React-webinterface.
Reisdocumenten laden in Azure Cosmos DB
De GitHub-opslagplaats bevat een Python-project in de map loader . Het is bedoeld voor het laden van de voorbeeldreisdocumenten in Azure Cosmos DB.
De omgeving instellen
Stel uw virtuele Python-omgeving in de map van het laadprogramma in door de volgende opdracht uit te voeren:
python -m venv venv
Activeer uw omgeving en installeer afhankelijkheden in de map loader :
venv\Scripts\activate
python -m pip install -r requirements.txt
Maak een bestand met de naam .env in de map loader om de volgende omgevingsvariabelen op te slaan:
OPENAI_API_KEY="<your OpenAI key>"
MONGO_CONNECTION_STRING="mongodb+srv:<your connection string from Azure Cosmos DB>"
Documenten en vectoren laden
Het Python-bestand main.py fungeert als het centrale toegangspunt voor het laden van gegevens in Azure Cosmos DB. Met deze code worden de voorbeeldgegevens van de GitHub-opslagplaats verwerkt, inclusief informatie over schepen en bestemmingen. De code genereert ook reisschemapakketten voor elk schip en elke bestemming, zodat reizigers ze kunnen boeken met behulp van de AI-agent. Het cosmosDBLoader-hulpprogramma is verantwoordelijk voor het maken van verzamelingen, vector-insluitingen en indexen in het Azure Cosmos DB-exemplaar.
Dit zijn de inhoud van main.py:
from cosmosdbloader import CosmosDBLoader
from itinerarybuilder import ItineraryBuilder
import json
cosmosdb_loader = CosmosDBLoader(DB_Name='travel')
#read in ship data
with open('documents/ships.json') as file:
ship_json = json.load(file)
#read in destination data
with open('documents/destinations.json') as file:
destinations_json = json.load(file)
builder = ItineraryBuilder(ship_json['ships'],destinations_json['destinations'])
# Create five itinerary packages
itinerary = builder.build(5)
# Save itinerary packages to Cosmos DB
cosmosdb_loader.load_data(itinerary,'itinerary')
# Save destinations to Cosmos DB
cosmosdb_loader.load_data(destinations_json['destinations'],'destinations')
# Save ships to Cosmos DB, create vector store
collection = cosmosdb_loader.load_vectors(ship_json['ships'],'ships')
# Add text search index to ship name
collection.create_index([('name', 'text')])
Laad de documenten, laad de vectoren en maak indexen door de volgende opdracht uit te voeren vanuit de map loader :
python main.py
Dit is de uitvoer van main.py:
--build itinerary--
--load itinerary--
--load destinations--
--load vectors ships--
De AI-reisagent bouwen met behulp van Python FastAPI
De AI-reisagent wordt gehost in een back-end-API via Python FastAPI, waarmee integratie met de front-endgebruikersinterface wordt vereenvoudigd. Het API-project verwerkt agentaanvragen door de LLM-prompts af te leggen op basis van de gegevenslaag, met name de vectoren en documenten in Azure Cosmos DB.
De agent maakt gebruik van verschillende hulpprogramma's, met name de Python-functies die worden geleverd in de API-servicelaag. Dit artikel is gericht op de code die nodig is voor AI-agents in de API-code.
Het API-project in de GitHub-opslagplaats is als volgt gestructureerd:
- Gegevensmodelleringsonderdelen maken gebruik van Pydantic-modellen.
- Onderdelen van de weblaag zijn verantwoordelijk voor het routeren van aanvragen en het beheren van communicatie.
- Servicelaagonderdelen zijn verantwoordelijk voor primaire bedrijfslogica en interactie met de gegevenslaag, de LangChain-agent en agenthulpprogramma's.
- Onderdelen van de gegevenslaag zijn verantwoordelijk voor interactie met Azure Cosmos DB voor MongoDB-documentopslag en vectorzoekopdrachten.
De omgeving voor de API instellen
We hebben Python versie 3.11.4 gebruikt voor het ontwikkelen en testen van de API.
Uw virtuele Python-omgeving instellen in de API-map :
python -m venv venv
Activeer uw omgeving en installeer afhankelijkheden met behulp van het vereistenbestand in de API-map :
venv\Scripts\activate
python -m pip install -r requirements.txt
Maak een bestand met de naam .env in de API-map om uw omgevingsvariabelen op te slaan:
OPENAI_API_KEY="<your Open AI key>"
MONGO_CONNECTION_STRING="mongodb+srv:<your connection string from Azure Cosmos DB>"
Nu u de omgeving hebt geconfigureerd en variabelen hebt ingesteld, voert u de volgende opdracht uit vanuit de API-map om de server te initiëren:
python app.py
De FastAPI-server wordt standaard gestart op de localhost-loopback 127.0.0.1-poort 8000. U kunt de Swagger-documenten openen met behulp van het volgende localhost-adres: http://127.0.0.1:8000/docs
Een sessie gebruiken voor het geheugen van de AI-agent
Het is noodzakelijk dat de reisagent kan verwijzen naar eerder verstrekte informatie binnen het lopende gesprek. Deze mogelijkheid wordt meestal geheugen genoemd in de context van LLM's.
Gebruik de chatberichtgeschiedenis die is opgeslagen in het Azure Cosmos DB-exemplaar om dit doel te bereiken. De geschiedenis voor elke chatsessie wordt opgeslagen via een sessie-id om ervoor te zorgen dat alleen berichten van de huidige gesprekssessie toegankelijk zijn. Deze noodzaak is de reden achter het bestaan van een Get Session
methode in de API. Het is een tijdelijke aanduiding voor het beheren van websessies om het gebruik van chatberichtengeschiedenis te illustreren.
Selecteer Uitproberen voor /session/
.
{
"session_id": "0505a645526f4d68a3603ef01efaab19"
}
Voor de AI-agent hoeft u alleen een sessie te simuleren. De stubbed-outmethode retourneert slechts een gegenereerde sessie-id voor het bijhouden van de berichtgeschiedenis. In een praktische implementatie wordt deze sessie opgeslagen in Azure Cosmos DB en mogelijk in React localStorage
.
Dit zijn de inhoud van web/session.py:
@router.get("/")
def get_session():
return {'session_id':str(uuid.uuid4().hex)}
Een gesprek starten met de AI-reisagent
Gebruik de sessie-id die u hebt verkregen uit de vorige stap om een nieuwe dialoog met de AI-agent te starten, zodat u de functionaliteit ervan kunt valideren. Voer de test uit door de volgende zin in te dienen: "Ik wil een ontspannen vakantie nemen."
Selecteer Uitproberen voor /agent/agent_chat
.
Gebruik deze voorbeeldparameter:
{
"input": "I want to take a relaxing vacation.",
"session_id": "0505a645526f4d68a3603ef01efaab19"
}
De eerste uitvoering resulteert in een aanbeveling voor de Tranquil Breeze Cruise en de Fantasy Seas Adventure Cruise, omdat de agent verwacht dat ze de meest ontspannende cruise zijn die beschikbaar zijn via de vectorzoekopdracht. Deze documenten hebben de hoogste score voor similarity_search_with_score
aanroepen in de gegevenslaag van de API. data.mongodb.travel.similarity_search()
De overeenkomsten in zoekscores worden weergegeven als uitvoer van de API voor foutopsporingsdoeleinden. Dit is de uitvoer na een aanroep naar data.mongodb.travel.similarity_search()
:
0.8394561085977978
0.8086545112328692
2
Tip
Als documenten niet worden geretourneerd voor vectorzoekopdrachten, wijzigt u de similarity_search_with_score
limiet of de scorefilterwaarde indien nodig ([doc for doc, score in docs if score >=.78]
) in data.mongodb.travel.similarity_search()
.
Als u de eerste keer aanroept agent_chat
, wordt er een nieuwe verzameling gemaakt met de naam history
in Azure Cosmos DB om het gesprek per sessie op te slaan. Met deze aanroep kan de agent indien nodig toegang krijgen tot de geschiedenis van het opgeslagen chatbericht. Volgende uitvoeringen van agent_chat
met dezelfde parameters produceren verschillende resultaten, omdat deze wordt opgehaald uit het geheugen.
De AI-agent doorlopen
Wanneer u de AI-agent in de API integreert, zijn de webzoekonderdelen verantwoordelijk voor het initiëren van alle aanvragen. De webzoekonderdelen worden gevolgd door de zoekservice en ten slotte de gegevensonderdelen.
In dit specifieke geval gebruikt u een MongoDB-gegevenszoekopdracht die verbinding maakt met Azure Cosmos DB. De lagen faciliteren de uitwisseling van modelonderdelen, met de AI-agent en de ai-agenthulpprogrammacode die zich in de servicelaag bevindt. Deze aanpak maakt een naadloze uitwisselbaarheid van gegevensbronnen mogelijk. Het breidt ook de mogelijkheden van de AI-agent uit met extra, complexere functies of hulpprogramma's.
Servicelaag
De servicelaag vormt de hoeksteen van kernbedrijfslogica. In dit specifieke scenario speelt de servicelaag een cruciale rol als opslagplaats voor de Code van de LangChain-agent. Het vereenvoudigt de naadloze integratie van gebruikersprompts met Azure Cosmos DB-gegevens, gespreksgeheugen en agentfuncties voor de AI-agent.
De servicelaag maakt gebruik van een singleton-patroonmodule voor het verwerken van agentgerelateerde initialisaties in het init.py-bestand . Dit zijn de inhoud van de service/init.py:
from dotenv import load_dotenv
from os import environ
from langchain.globals import set_llm_cache
from langchain_openai import ChatOpenAI
from langchain_mongodb.chat_message_histories import MongoDBChatMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain.agents import AgentExecutor, create_openai_tools_agent
from service import TravelAgentTools as agent_tools
load_dotenv(override=False)
chat : ChatOpenAI | None=None
agent_with_chat_history : RunnableWithMessageHistory | None=None
def LLM_init():
global chat,agent_with_chat_history
chat = ChatOpenAI(model_name="gpt-3.5-turbo-16k",temperature=0)
tools = [agent_tools.vacation_lookup, agent_tools.itinerary_lookup, agent_tools.book_cruise ]
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"You are a helpful and friendly travel assistant for a cruise company. Answer travel questions to the best of your ability providing only relevant information. In order to book a cruise you will need to capture the person's name.",
),
MessagesPlaceholder(variable_name="chat_history"),
("user", "Answer should be embedded in html tags. {input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
]
)
#Answer should be embedded in HTML tags. Only answer questions related to cruise travel, If you can not answer respond with \"I am here to assist with your travel questions.\".
agent = create_openai_tools_agent(chat, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
agent_with_chat_history = RunnableWithMessageHistory(
agent_executor,
lambda session_id: MongoDBChatMessageHistory( database_name="travel",
collection_name="history",
connection_string=environ.get("MONGO_CONNECTION_STRING"),
session_id=session_id),
input_messages_key="input",
history_messages_key="chat_history",
)
LLM_init()
Het bestand init.py initieert het laden van omgevingsvariabelen vanuit een .env-bestand met behulp van de load_dotenv(override=False)
methode. Vervolgens wordt er een globale variabele met de naam agent_with_chat_history
geïnstantieerd voor de agent. Deze agent is bedoeld voor gebruik door TravelAgent.py.
De LLM_init()
methode wordt aangeroepen tijdens de initialisatie van de module om de AI-agent te configureren voor gesprekken via de API-weblaag. Het OpenAI-object chat
wordt geïnstantieerd via het GPT-3.5-model en bevat specifieke parameters, zoals modelnaam en temperatuur. Het chat
object, de lijst met hulpprogramma's en de promptsjabloon worden gecombineerd om te genereren AgentExecutor
, die werkt als de AI-reisagent.
De agent met geschiedenis, agent_with_chat_history
wordt tot stand gebracht met RunnableWithMessageHistory
chatgeschiedenis (MongoDBChatMessageHistory
). Met deze actie kan een volledige gespreksgeschiedenis worden bijgehouden via Azure Cosmos DB.
Prompt
De LLM-prompt begon aanvankelijk met de eenvoudige instructie "U bent een nuttige en vriendelijke reisassistent voor een cruisebedrijf." Uit het testen bleek echter dat u consistentere resultaten kon verkrijgen door de instructie "Reisvragen beantwoorden naar het beste van uw vermogen, waarbij alleen relevante informatie wordt verstrekt. Om een cruise te boeken, is het vastleggen van de naam van de persoon essentieel." De resultaten worden weergegeven in HTML-indeling om de visuele aantrekkelijkheid van de webinterface te verbeteren.
Agenthulpprogramma's
Hulpprogramma's zijn interfaces die een agent kan gebruiken om met de wereld te communiceren, vaak via functieaanroepen.
Wanneer u een agent maakt, moet u deze voorzien van een set hulpprogramma's die u kunt gebruiken. De @tool
decorator biedt de eenvoudigste manier om een aangepast hulpprogramma te definiëren.
De decorator gebruikt standaard de functienaam als de naam van het hulpprogramma, hoewel u deze kunt vervangen door een tekenreeks op te geven als het eerste argument. De decorator gebruikt de docstring van de functie als beschrijving van het hulpprogramma, dus vereist het inrichten van een docstring.
Dit zijn de inhoud van de service/TravelAgentTools.py:
from langchain_core.tools import tool
from langchain.docstore.document import Document
from data.mongodb import travel
from model.travel import Ship
@tool
def vacation_lookup(input:str) -> list[Document]:
"""find information on vacations and trips"""
ships: list[Ship] = travel.similarity_search(input)
content = ""
for ship in ships:
content += f" Cruise ship {ship.name} description: {ship.description} with amenities {'/n-'.join(ship.amenities)} "
return content
@tool
def itinerary_lookup(ship_name:str) -> str:
"""find ship itinerary, cruise packages and destinations by ship name"""
it = travel.itnerary_search(ship_name)
results = ""
for i in it:
results += f" Cruise Package {i.Name} room prices: {'/n-'.join(i.Rooms)} schedule: {'/n-'.join(i.Schedule)}"
return results
@tool
def book_cruise(package_name:str, passenger_name:str, room: str )-> str:
"""book cruise using package name and passenger name and room """
print(f"Package: {package_name} passenger: {passenger_name} room: {room}")
# LLM defaults empty name to John Doe
if passenger_name == "John Doe":
return "In order to book a cruise I need to know your name."
else:
if room == '':
return "which room would you like to book"
return "Cruise has been booked, ref number is 343242"
Het bestand TravelAgentTools.py definieert drie hulpprogramma's:
vacation_lookup
voert een vectorzoekopdracht uit op Azure Cosmos DB. Het gebruiktsimilarity_search
om relevant reisgerelateerd materiaal op te halen.itinerary_lookup
haalt details en planningen van cruisepakketten op voor een opgegeven cruiseschip.book_cruise
boeken van een cruisepakket voor een passagier.
Specifieke instructies ('Om een cruise te boeken moet ik uw naam weten') kan nodig zijn om ervoor te zorgen dat de naam en het kamernummer van de passagier worden vastgelegd voor het boeken van het cruisepakket, ook al hebt u dergelijke instructies in de LLM-prompt opgenomen.
AI-agent
Het fundamentele concept dat ten grondslag ligt aan agents is het gebruik van een taalmodel voor het selecteren van een reeks acties die moeten worden uitgevoerd.
Dit zijn de inhoud van de service/TravelAgent.py:
from .init import agent_with_chat_history
from model.prompt import PromptResponse
import time
from dotenv import load_dotenv
load_dotenv(override=False)
def agent_chat(input:str, session_id:str)->str:
start_time = time.time()
results=agent_with_chat_history.invoke(
{"input": input},
config={"configurable": {"session_id": session_id}},
)
return PromptResponse(text=results["output"],ResponseSeconds=(time.time() - start_time))
Het TravelAgent.py-bestand is eenvoudig, omdat agent_with_chat_history
en de bijbehorende afhankelijkheden (hulpprogramma's, prompt en LLM) worden geïnitialiseerd en geconfigureerd in het init.py-bestand . Dit bestand roept de agent aan met behulp van de invoer die van de gebruiker is ontvangen, samen met de sessie-id voor gespreksgeheugen. PromptResponse
Daarna wordt (model/prompt) geretourneerd met de uitvoer- en reactietijd van de agent.
Integratie van AI-agent met de React-gebruikersinterface
Met het succesvol laden van de gegevens en toegankelijkheid van de AI-agent via de API kunt u de oplossing nu voltooien door een webgebruikersinterface (met behulp van React) tot stand te brengen voor uw reiswebsite. Door de mogelijkheden van React te gebruiken, wordt de naadloze integratie van de AI-agent in een reissite geïllustreerd. Deze integratie verbetert de gebruikerservaring met een gespreksassistent voor vragen en boekingen.
De omgeving instellen voor React
Installeer Node.js en de afhankelijkheden voordat u de React-interface test.
Voer de volgende opdracht uit vanuit de webmap om een schone installatie van projectafhankelijkheden uit te voeren. De installatie kan enige tijd duren.
npm ci
Maak vervolgens een bestand met de naam .env in de webmap om de opslag van omgevingsvariabelen te vergemakkelijken. Neem de volgende details op in het zojuist gemaakte .env-bestand :
REACT_APP_API_HOST=http://127.0.0.1:8000
Voer nu de volgende opdracht uit vanuit de webmap om de React-webgebruikersinterface te initiëren:
npm start
Als u de vorige opdracht uitvoert, wordt de React-webtoepassing geopend.
De React-webinterface doorlopen
Het webproject van de GitHub-opslagplaats is een eenvoudige toepassing om gebruikersinteractie met de AI-agent te vergemakkelijken. De primaire onderdelen die nodig zijn om met de agent te communiceren, zijn TravelAgent.js en ChatLayout.js. Het Main.js-bestand fungeert als de centrale module of landingspagina van de gebruiker.
Hoofd
Het hoofdonderdeel fungeert als de centrale manager van de toepassing. Het fungeert als het aangewezen toegangspunt voor routering. Binnen de renderfunctie produceert het JSX-code om de indeling van de hoofdpagina te beschrijven. Deze indeling omvat tijdelijke aanduidingen voor de toepassing, zoals logo's en koppelingen, een sectie waarin het onderdeel reisagent is opgenomen en een voettekst met een voorbeeld disclaimer over de aard van de toepassing.
Dit zijn de inhoud van main.js:
import React, { Component } from 'react'
import { Stack, Link, Paper } from '@mui/material'
import TravelAgent from './TripPlanning/TravelAgent'
import './Main.css'
class Main extends Component {
constructor() {
super()
}
render() {
return (
<div className="Main">
<div className="Main-Header">
<Stack direction="row" spacing={5}>
<img src="/mainlogo.png" alt="Logo" height={'120px'} />
<Link
href="#"
sx={{ color: 'white', fontWeight: 'bold', fontSize: 18 }}
underline="hover"
>
Ships
</Link>
<Link
href="#"
sx={{ color: 'white', fontWeight: 'bold', fontSize: 18 }}
underline="hover"
>
Destinations
</Link>
</Stack>
</div>
<div className="Main-Body">
<div className="Main-Content">
<Paper elevation={3} sx={{p:1}} >
<Stack
direction="row"
justifyContent="space-evenly"
alignItems="center"
spacing={2}
>
<Link href="#">
<img
src={require('./images/destinations.png')} width={'400px'} />
</Link>
<TravelAgent ></TravelAgent>
<Link href="#">
<img
src={require('./images/ships.png')} width={'400px'} />
</Link>
</Stack>
</Paper>
</div>
</div>
<div className="Main-Footer">
<b>Disclaimer: Sample Application</b>
<br />
Please note that this sample application is provided for demonstration
purposes only and should not be used in production environments
without proper validation and testing.
</div>
</div>
)
}
}
export default Main
Reisagent
Het onderdeel reisagent heeft een eenvoudig doel: gebruikersinvoer vastleggen en antwoorden weergeven. Het speelt een belangrijke rol bij het beheren van de integratie met de back-end AI-agent, voornamelijk door sessies vast te leggen en gebruikersprompts door te sturen naar de FastAPI-service. De resulterende antwoorden worden opgeslagen in een matrix voor weergave, mogelijk gemaakt door het chat-indelingsonderdeel.
Dit zijn de inhoud van TripPlanning/TravelAgent.js:
import React, { useState, useEffect } from 'react'
import { Button, Box, Link, Stack, TextField } from '@mui/material'
import SendIcon from '@mui/icons-material/Send'
import { Dialog, DialogContent } from '@mui/material'
import ChatLayout from './ChatLayout'
import './TravelAgent.css'
export default function TravelAgent() {
const [open, setOpen] = React.useState(false)
const [session, setSession] = useState('')
const [chatPrompt, setChatPrompt] = useState(
'I want to take a relaxing vacation.',
)
const [message, setMessage] = useState([
{
message: 'Hello, how can I assist you today?',
direction: 'left',
bg: '#E7FAEC',
},
])
const handlePrompt = (prompt) => {
setChatPrompt('')
setMessage((message) => [
...message,
{ message: prompt, direction: 'right', bg: '#E7F4FA' },
])
console.log(session)
fetch(process.env.REACT_APP_API_HOST + '/agent/agent_chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ input: prompt, session_id: session }),
})
.then((response) => response.json())
.then((res) => {
setMessage((message) => [
...message,
{ message: res.text, direction: 'left', bg: '#E7FAEC' },
])
})
}
const handleSession = () => {
fetch(process.env.REACT_APP_API_HOST + '/session/')
.then((response) => response.json())
.then((res) => {
setSession(res.session_id)
})
}
const handleClickOpen = () => {
setOpen(true)
}
const handleClose = (value) => {
setOpen(false)
}
useEffect(() => {
if (session === '') handleSession()
}, [])
return (
<Box>
<Dialog onClose={handleClose} open={open} maxWidth="md" fullWidth="true">
<DialogContent>
<Stack>
<Box sx={{ height: '500px' }}>
<div className="AgentArea">
<ChatLayout messages={message} />
</div>
</Box>
<Stack direction="row" spacing={0}>
<TextField
sx={{ width: '80%' }}
variant="outlined"
label="Message"
helperText="Chat with AI Travel Agent"
defaultValue="I want to take a relaxing vacation."
value={chatPrompt}
onChange={(event) => setChatPrompt(event.target.value)}
></TextField>
<Button
variant="contained"
endIcon={<SendIcon />}
sx={{ mb: 3, ml: 3, mt: 1 }}
onClick={(event) => handlePrompt(chatPrompt)}
>
Submit
</Button>
</Stack>
</Stack>
</DialogContent>
</Dialog>
<Link href="#" onClick={() => handleClickOpen()}>
<img src={require('.././images/planvoyage.png')} width={'400px'} />
</Link>
</Box>
)
}
Selecteer Moeiteloos uw reis plannen om de reisassistent te openen.
Chatindeling
Het onderdeel chatindeling houdt toezicht op de rangschikking van de chat. De chatberichten worden systematisch verwerkt en de opmaak geïmplementeerd die is opgegeven in het message
JSON-object.
Dit zijn de inhoud van TripPlanning/ChatLayout.js:
import React from 'react'
import { Box, Stack } from '@mui/material'
import parse from 'html-react-parser'
import './ChatLayout.css'
export default function ChatLayout(messages) {
return (
<Stack direction="column" spacing="1">
{messages.messages.map((obj, i = 0) => (
<div className="bubbleContainer" key={i}>
<Box
key={i++}
className="bubble"
sx={{ float: obj.direction, fontSize: '10pt', background: obj.bg }}
>
<div>{parse(obj.message)}</div>
</Box>
</div>
))}
</Stack>
)
}
Gebruikersprompts bevinden zich aan de rechterkant en gekleurd blauw. Reacties van de AI-reisagent staan aan de linkerkant en zijn groen gekleurd. Zoals in de volgende afbeelding wordt weergegeven, worden de in HTML opgemaakte antwoorden in het gesprek opgegeven.
Wanneer uw AI-agent klaar is om in productie te gaan, kunt u semantische caching gebruiken om de queryprestaties met 80% te verbeteren en de kosten voor LLM-deductie en API-aanroepen te verlagen. Als u semantische caching wilt implementeren, raadpleegt u dit bericht op de Stochastic Coder-blog.