Dela via


AI-agent

AI-agenter är utformade för att utföra specifika uppgifter, besvara frågor och automatisera processer för användare. Dessa agenter varierar mycket i komplexitet. De sträcker sig från enkla chattrobotar, till andrepiloter, till avancerade AI-assistenter i form av digitala system eller robotsystem som kan köra komplexa arbetsflöden autonomt.

Den här artikeln innehåller konceptuella översikter och detaljerade implementeringsexempel för AI-agenter.

Vad är AI-agenter?

Till skillnad från fristående stora språkmodeller (LLM) eller regelbaserade programvaru-/maskinvarusystem har AI-agenter följande vanliga funktioner:

  • Planering: AI-agenter kan planera och sekvensisera åtgärder för att uppnå specifika mål. Integreringen av LLM:er har revolutionerat deras planeringsfunktioner.
  • Verktygsanvändning: Avancerade AI-agenter kan använda olika verktyg, till exempel kodkörning, sökning och beräkningsfunktioner, för att utföra uppgifter effektivt. AI-agenter använder ofta verktyg via funktionsanrop.
  • Perception: AI-agenter kan uppfatta och bearbeta information från sin miljö för att göra dem mer interaktiva och kontextmedvetna. Den här informationen omfattar visuella, auditiva och andra sensoriska data.
  • Minne: AI-agenter har möjlighet att komma ihåg tidigare interaktioner (verktygsanvändning och uppfattning) och beteenden (verktygsanvändning och planering). De lagrar dessa upplevelser och utför till och med självreflektion för att informera framtida åtgärder. Den här minneskomponenten möjliggör kontinuitet och förbättring av agentprestanda över tid.

Kommentar

Användningen av termen minne i samband med AI-agenter skiljer sig från begreppet datorminne (som flyktigt, icke-volatilt och beständigt minne).

Andrepiloter

Copilots är en typ av AI-agent. De fungerar tillsammans med användare i stället för att arbeta oberoende av varandra. Till skillnad från helt automatiserade agenter ger andrepiloter förslag och rekommendationer för att hjälpa användare att utföra uppgifter.

När en användare till exempel skriver ett e-postmeddelande kan en andrepilot föreslå fraser, meningar eller stycken. Användaren kan också be andrepiloten att hitta relevant information i andra e-postmeddelanden eller filer för att stödja förslaget (se hämtningsförhöjd generering). Användaren kan acceptera, avvisa eller redigera de föreslagna avsnitten.

Autonoma agenter

Autonoma agenter kan arbeta mer självständigt. När du konfigurerar autonoma agenter för att hjälpa till med e-postsammansättning kan du göra så att de kan utföra följande uppgifter:

  • Läs befintliga e-postmeddelanden, chattar, filer och annan intern och offentlig information som är relaterad till ämnet.
  • Utför kvalitativ eller kvantitativ analys av den insamlade informationen och dra slutsatser som är relevanta för e-postmeddelandet.
  • Skriv det fullständiga e-postmeddelandet baserat på slutsatserna och införliva stödjande bevis.
  • Bifoga relevanta filer i e-postmeddelandet.
  • Granska e-postmeddelandet för att säkerställa att all inkorporerad information är faktamässigt korrekt och att försäkran är giltiga.
  • Välj lämpliga mottagare för Till, Kopia och Hemlig kopia och leta upp deras e-postadresser.
  • Schemalägg en lämplig tid för att skicka e-postmeddelandet.
  • Utför uppföljningar om svar förväntas men inte tas emot.

Du kan konfigurera agenterna att utföra var och en av de föregående uppgifterna med eller utan mänskligt godkännande.

System med flera agenter

En populär strategi för att uppnå högpresterande autonoma agenter är användningen av system med flera agenter. I system med flera agenter interagerar eller samarbetar flera autonoma agenter, oavsett om de är i digital eller robotiserad form, för att uppnå individuella eller kollektiva mål. Agenter i systemet kan arbeta självständigt och ha sina egna kunskaper eller information. Varje agent kan också ha möjlighet att uppfatta sin miljö, fatta beslut och utföra åtgärder baserat på dess mål.

System med flera agenter har följande viktiga egenskaper:

  • Autonom: Varje agent fungerar oberoende av varandra. Den fattar sina egna beslut utan direkt mänsklig inblandning eller kontroll av andra agenter.
  • Interaktiv: Agenter kommunicerar och samarbetar med varandra för att dela information, förhandla och samordna sina åtgärder. Den här interaktionen kan ske via olika protokoll och kommunikationskanaler.
  • Målorienterad: Agenter i ett system med flera agenter är utformade för att uppnå specifika mål, som kan anpassas till enskilda mål eller ett delat mål mellan agenterna.
  • Distribuerad: System med flera agenter fungerar på ett distribuerat sätt, utan en enda kontrollpunkt. Den här distributionen förbättrar systemets robusthet, skalbarhet och resurseffektivitet.

Ett system med flera agenter ger följande fördelar jämfört med en andrepilot eller en enda instans av LLM-slutsatsdragning:

  • Dynamiskt resonemang: Jämfört med tankekedja eller tanketrädsfråga möjliggör system med flera agenter dynamisk navigering via olika resonemangsvägar.
  • Avancerade funktioner: System med flera agenter kan hantera komplexa eller storskaliga problem genom att genomföra noggranna beslutsprocesser och distribuera uppgifter mellan flera agenter.
  • Utökat minne: System med flera agenter med minne kan övervinna kontextfönstren för LLM:er för att ge bättre förståelse och informationskvarhållning.

Implementering av AI-agenter

Resonemang och planering

Komplexa resonemang och planering är kännetecknet för avancerade autonoma agenter. Populära ramverk för autonoma agenter innehåller en eller flera av följande metoder (med länkar till arXiv-arkivsidor) för resonemang och planering:

  • Självbetjäning

    Förbättra tankekedjan genom att låta modellen uttryckligen ställa sig själv (och svara på) uppföljningsfrågor innan du svarar på den första frågan.

  • Orsak och handling (ReAct)

    Använd LLM:er för att generera både resonemangsspårningar och uppgiftsspecifika åtgärder på ett interfolierat sätt. Resonemangsspårningar hjälper modellen att inducera, spåra och uppdatera åtgärdsplaner, tillsammans med att hantera undantag. Med åtgärder kan modellen ansluta till externa källor, till exempel baza znanja eller miljöer, för att samla in ytterligare information.

  • Planera och lösa

    Utforma en plan för att dela upp hela uppgiften i mindre underaktiviteter och sedan utföra underaktiviteterna enligt planen. Den här metoden minimerar beräkningsfel, fel som saknas i steget och semantiska missförståndsfel som ofta finns i nollskottskedja med tankesökning.

  • Reflektera/självkritik

    Använd reflexionsagenter som verbalt reflekterar över feedbacksignaler för uppgifter. Dessa agenter behåller sin egen reflekterande text i en episodisk minnesbuffert för att få bättre beslutsfattande i efterföljande försök.

Ramverk

Olika ramverk och verktyg kan underlätta utvecklingen och distributionen av AI-agenter.

För verktygsanvändning och uppfattning som inte kräver avancerad planering och minne är vissa populära LLM-orkestreringsramverk LangChain, LlamaIndex, Prompt Flow och Semantic Kernel.

För avancerade och autonoma arbetsflöden för planering och körning drev AutoGen den multiagentvåg som började i slutet av 2022. Med OpenAI:s API för assistenter kan användarna skapa agenter internt i GPT-ekosystemet. LangChain-agenter och LlamaIndex-agenter uppstod också ungefär samtidigt.

Dricks

Implementeringsexemplet senare i den här artikeln visar hur du skapar ett enkelt system med flera agenter med hjälp av ett av de populära ramverken och ett enhetligt agentminnessystem.

AI-agentens minnessystem

Den vanliga metoden för att experimentera med AI-förbättrade program från 2022 till 2024 har använt fristående databashanteringssystem för olika dataarbetsflöden eller typer. Du kan till exempel använda en minnesintern databas för cachelagring, en relationsdatabas för driftdata (inklusive spårnings-/aktivitetsloggar och LLM-konversationshistorik) och en ren vektordatabas för inbäddningshantering.

Den här metoden med att använda ett komplext nät av fristående databaser kan dock skada en AI-agent prestanda. Att integrera alla dessa olika databaser i ett sammanhängande, driftskompatibelt och motståndskraftigt minnessystem för AI-agenter är en egen utmaning.

Dessutom är många av de databastjänster som används ofta inte optimala för den hastighet och skalbarhet som AI-agentsystem behöver. Dessa databasers enskilda svagheter förvärras i system med flera agenter.

Minnesinterna databaser

Minnesinterna databaser är utmärkta för hastighet men kan kämpa med den storskaliga datapersistence som AI-agenter behöver.

Relationsdatabaser

Relationsdatabaser är inte idealiska för de olika modaliteter och vätskescheman för data som agenter hanterar. Relationsdatabaser kräver manuella åtgärder och till och med stilleståndstid för att hantera etablering, partitionering och horisontell partitionering.

Rena vektordatabaser

Rena vektordatabaser tenderar att vara mindre effektiva för transaktionsåtgärder, realtidsuppdateringar och distribuerade arbetsbelastningar. De populära rena vektordatabaserna erbjuder vanligtvis:

  • Ingen garanti för läsningar och skrivningar.
  • Begränsat dataflöde för inmatning.
  • Låg tillgänglighet (under 99,9 % eller ett årligt avbrott på 9 timmar eller mer).
  • En konsekvensnivå (eventuell).
  • Ett resursintensivt minnesinternt vektorindex.
  • Begränsade alternativ för flera klientorganisationer.
  • Begränsad säkerhet.

Egenskaper för ett robust AI-agentminnessystem

Precis som effektiva databashanteringssystem är viktiga för programprestanda är det viktigt att tillhandahålla LLM-baserade agenter relevant och användbar information för att vägleda deras slutsatsdragning. Robusta minnessystem gör det möjligt att organisera och lagra olika typer av information som agenterna kan hämta vid slutsatsdragningstid.

För närvarande använder LLM-baserade program ofta hämtningsförhöjd generation som använder grundläggande semantisk sökning eller vektorsökning för att hämta passager eller dokument. Vektorsökning kan vara användbart för att hitta allmän information. Men vektorsökning kanske inte avbildar den specifika kontext, struktur eller relationer som är relevanta för en viss uppgift eller domän.

Om uppgiften till exempel är att skriva kod kanske vektorsökningen inte kan hämta syntaxträdet, filsystemets layout, kodsammanfattningar eller API-signaturer som är viktiga för att generera sammanhängande och korrekt kod. På samma sätt, om uppgiften ska fungera med tabelldata, kanske vektorsökning inte kan hämta schemat, sekundärnycklarna, lagrade procedurer eller de rapporter som är användbara för att fråga eller analysera data.

Att väva ihop en webb med fristående minnesbaserade databaser, relationsdatabaser och vektordatabaser (som beskrevs tidigare) är inte en optimal lösning för de olika datatyperna. Den här metoden kan fungera för prototypiska agentsystem. Det lägger dock till komplexitet och prestandaflaskhalsar som kan hämma prestanda för avancerade autonoma agenter.

Ett robust minnessystem bör ha följande egenskaper.

Multimodala

AI-agentminnessystem bör tillhandahålla samlingar som lagrar metadata, relationer, entiteter, sammanfattningar eller andra typer av information som kan vara användbara för olika uppgifter och domäner. Dessa samlingar kan baseras på datastrukturen och formatet, till exempel dokument, tabeller eller kod. Eller så kan de baseras på innehållet och innebörden av data, till exempel begrepp, associationer eller processuella steg.

Minnessystem är inte bara viktiga för AI-agenter. De är också viktiga för de människor som utvecklar, underhåller och använder dessa agenter.

Människor kan till exempel behöva övervaka agenternas planerings- och körningsarbetsflöden nästan i realtid. Under övervakningen kan människor ingripa med vägledning eller göra infogade redigeringar av agenters dialoger eller monologer. Människor kan också behöva granska agenternas resonemang och åtgärder för att verifiera giltigheten för de slutliga utdata.

Interaktioner mellan människa och agent är sannolikt på naturliga språk eller programmeringsspråk, medan agenter "tänker", "lär sig" och "kommer ihåg" via inbäddningar. Den här skillnaden utgör ett annat krav på minnessystemens konsekvens mellan datamodaliteter.

Operativ

Minnessystem bör tillhandahålla minnesbankar som lagrar information som är relevant för interaktionen med användaren och miljön. Sådan information kan omfatta chatthistorik, användarinställningar, sensoriska data, beslut som fattas, inlärda fakta eller andra driftdata som uppdateras med hög frekvens och på höga volymer.

Dessa minnesbanker kan hjälpa agenterna att komma ihåg kortsiktig och långsiktig information, undvika att upprepa eller motsäga sig själva och upprätthålla uppgiftssammanhållning. Dessa krav måste gälla även om agenterna utför en mängd orelaterade uppgifter i följd. I avancerade fall kan agenter också testa flera grenplaner som avviker eller konvergerar vid olika tidpunkter.

Delbar men också separerbar

På makronivå bör minnessystem göra det möjligt för flera AI-agenter att samarbeta om ett problem eller bearbeta olika aspekter av problemet genom att tillhandahålla delat minne som är tillgängligt för alla agenter. Delat minne kan underlätta informationsutbyte och samordning av åtgärder mellan agenterna.

Samtidigt måste minnessystemet tillåta agenter att bevara sin egen persona och egenskaper, till exempel deras unika samlingar av uppmaningar och minnen.

Skapa ett robust AI-agentminnessystem

De föregående egenskaperna kräver att AI-agentens minnessystem är mycket skalbara och snabba. Att noggrant väva samman olika minnesbaserade databaser, relationsdatabaser och vektordatabaser (enligt beskrivningen tidigare) kan fungera för AI-aktiverade program i ett tidigt skede. Den här metoden lägger dock till komplexitets- och prestandaflaskhalsar som kan hämma prestanda för avancerade autonoma agenter.

I stället för alla fristående databaser kan Azure Cosmos DB fungera som en enhetlig lösning för AI-agentminnessystem. Dess robusthet har gjort det möjligt för OpenAI:s ChatGPT-tjänst att skala dynamiskt med hög tillförlitlighet och lågt underhåll. Den drivs av en atom-postsekvensmotor och är världens första globalt distribuerade NoSQL-, relations- och vektordatabastjänst som erbjuder ett serverlöst läge. AI-agenter som bygger på Azure Cosmos DB erbjuder snabbhet, skalning och enkelhet.

Hastighet

Azure Cosmos DB ger ensiffrig svarstid på millisekunder. Den här funktionen gör den lämplig för processer som kräver snabb dataåtkomst och hantering. Dessa processer omfattar cachelagring (både traditionell och semantisk cachelagring), transaktioner och driftarbetsbelastningar.

Låg svarstid är avgörande för AI-agenter som behöver utföra komplexa resonemang, fatta realtidsbeslut och ge omedelbara svar. Dessutom ger tjänstens användning av DiskANN-algoritmen korrekt och snabb vektorsökning med minimal minnesförbrukning.

Skala

Azure Cosmos DB är utformat för global distribution och horisontell skalbarhet. Den erbjuder stöd för I/O och flera regioner i flera regioner.

Tjänsten hjälper till att säkerställa att minnessystemen kan utökas sömlöst och hålla jämna jämna år med snabbt växande agenter och associerade data. Tillgänglighetsgarantin i serviceavtalet (SLA) innebär mindre än 5 minuters stilleståndstid per år. Rena vektordatabastjänster har däremot 9 timmar eller mer stilleståndstid. Den här tillgängligheten ger en solid grund för verksamhetskritiska arbetsbelastningar. Samtidigt kan de olika tjänstmodellerna i Azure Cosmos DB, till exempel Reserverad kapacitet eller Serverlös, bidra till att minska de ekonomiska kostnaderna.

Enkelhet

Azure Cosmos DB kan förenkla datahantering och arkitektur genom att integrera flera databasfunktioner i en enda sammanhängande plattform.

Dess integrerade vektordatabasfunktioner kan lagra, indexera och fråga inbäddningar tillsammans med motsvarande data i naturliga språk eller programmeringsspråk. Den här funktionen ger bättre datakonsekvens, skalning och prestanda.

Dess flexibilitet stöder olika metoder och vätskescheman för metadata, relationer, entiteter, sammanfattningar, chatthistorik, användarinställningar, sensoriska data, beslut, fakta som lärts eller andra driftdata som ingår i agentarbetsflöden. Databasen indexerar automatiskt alla data utan att behöva schema- eller indexhantering, vilket hjälper AI-agenter att utföra komplexa frågor snabbt och effektivt.

Azure Cosmos DB hanteras fullständigt, vilket eliminerar kostnaderna för databasadministrationsuppgifter som skalning, korrigering och säkerhetskopior. Utan den här kostnaden kan utvecklare fokusera på att skapa och optimera AI-agenter utan att behöva bekymra sig om den underliggande datainfrastrukturen.

Avancerade funktioner

Azure Cosmos DB innehåller avancerade funktioner som ändringsflöde, vilket gör det möjligt att spåra och svara på ändringar i data i realtid. Den här funktionen är användbar för AI-agenter som snabbt behöver reagera på ny information.

Dessutom möjliggör det inbyggda stödet för skrivningar med flera original hög tillgänglighet och motståndskraft för att säkerställa kontinuerlig drift av AI-agenter, även efter regionala fel.

De fem tillgängliga konsekvensnivåerna (från stark till slutlig) kan också tillgodose olika distribuerade arbetsbelastningar, beroende på scenariokraven.

Dricks

Du kan välja mellan två Azure Cosmos DB-API:er för att skapa ditt AI-agentminnessystem:

  • Azure Cosmos DB for NoSQL, som erbjuder 99,999 % tillgänglighetsgaranti och tillhandahåller tre vektorsökningsalgoritmer: IVF, HNSW och DiskANN
  • vCore-baserade Azure Cosmos DB for MongoDB, som erbjuder 99,995 % tillgänglighetsgaranti och tillhandahåller två vektorsökningsalgoritmer: IVF och HNSW (DiskANN är kommande)

Information om tillgänglighetsgarantierna för dessa API:er finns i serviceavtalen.

Implementeringsexempel

I det här avsnittet går vi igenom implementeringen av en autonom agent för att bearbeta reseförfrågningar och bokningar i en reseansökan för en kryssningslinje.

Chattrobotar är ett långvarigt koncept, men AI-agenter avancerar bortom grundläggande mänsklig konversation för att utföra uppgifter baserade på naturligt språk. Dessa uppgifter krävde traditionellt kodad logik. AI-resebyrån i det här implementeringsexemplet använder LangChain Agent-ramverket för agentplanering, verktygsanvändning och uppfattning.

AI-resebyråns enhetliga minnessystem använder vektordatabasen och dokumentlagringsfunktionerna i Azure Cosmos DB för att hantera reseförfrågningar och underlätta resebokningar. Att använda Azure Cosmos DB för det här ändamålet hjälper till att säkerställa hastighet, skalning och enkelhet, enligt beskrivningen tidigare.

Exempelagenten fungerar i en Python FastAPI-serverdel. Den stöder användarinteraktioner via ett React JavaScript-användargränssnitt.

Förutsättningar

  • En Azure-prenumeration. Om du inte har en kan du prova Azure Cosmos DB kostnadsfritt i 30 dagar utan att skapa ett Azure-konto. Den kostnadsfria utvärderingsversionen kräver inget kreditkort och inget åtagande följer utvärderingsperioden.
  • Ett konto för OpenAI API eller Azure OpenAI Service.
  • Ett virtuellt kärnkluster i Azure Cosmos DB för MongoDB. Du kan skapa en genom att följa den här snabbstarten.
  • En integrerad utvecklingsmiljö, till exempel Visual Studio Code.
  • Python 3.11.4 installerat i utvecklingsmiljön.

Ladda ned projektet

Alla kod- och exempeldatauppsättningar är tillgängliga på den här GitHub-lagringsplatsen. Lagringsplatsen innehåller följande mappar:

  • inläsare: Den här mappen innehåller Python-kod för inläsning av exempeldokument och vektorinbäddningar i Azure Cosmos DB.
  • api: Den här mappen innehåller Python FastAPI-projektet för att vara värd för AI-resebyrån.
  • web: Den här mappen innehåller kod för React-webbgränssnittet.

Läsa in resedokument i Azure Cosmos DB

GitHub-lagringsplatsen innehåller ett Python-projekt i inläsningskatalogen. Den är avsedd att läsa in exempelresedokumenten i Azure Cosmos DB.

Konfigurera miljön

Konfigurera din virtuella Python-miljö i inläsningskatalogen genom att köra följande kommando:

    python -m venv venv

Aktivera din miljö och installera beroenden i inläsningskatalogen:

    venv\Scripts\activate
    python -m pip install -r requirements.txt

Skapa en fil med namnet .env i inläsningskatalogen för att lagra följande miljövariabler:

    OPENAI_API_KEY="<your OpenAI key>"
    MONGO_CONNECTION_STRING="mongodb+srv:<your connection string from Azure Cosmos DB>"

Läsa in dokument och vektorer

Python-filen main.py fungerar som den centrala startpunkten för inläsning av data till Azure Cosmos DB. Den här koden bearbetar exempelresedata från GitHub-lagringsplatsen, inklusive information om fartyg och mål. Koden genererar också reseresepaket för varje fartyg och destination, så att resenärer kan boka dem med hjälp av AI-agenten. CosmosDBLoader-verktyget ansvarar för att skapa samlingar, vektorinbäddningar och index i Azure Cosmos DB-instansen.

Här är innehållet i 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')])

Läs in dokumenten, läs in vektorerna och skapa index genom att köra följande kommando från lastarkatalogen:

    python main.py

Här är utdata från main.py:

--build itinerary--
--load itinerary--
--load destinations--
--load vectors ships--

Skapa AI-resebyrån med hjälp av Python FastAPI

AI-resebyrån finns i ett serverdels-API via Python FastAPI, vilket underlättar integrering med klientdelens användargränssnitt. API-projektet bearbetar agentbegäranden genom att jorda LLM-prompterna mot datalagret, särskilt vektorerna och dokumenten i Azure Cosmos DB.

Agenten använder olika verktyg, särskilt De Python-funktioner som tillhandahålls på API-tjänstnivån. Den här artikeln fokuserar på den kod som krävs för AI-agenter i API-koden.

API-projektet på GitHub-lagringsplatsen är strukturerat på följande sätt:

  • Datamodelleringskomponenter använder pydantiska modeller.
  • Webblagerkomponenter ansvarar för routning av begäranden och hantering av kommunikation.
  • Komponenter på tjänstnivå ansvarar för primär affärslogik och interaktion med datalagret, LangChain-agenten och agentverktygen.
  • Datalagerkomponenter ansvarar för att interagera med Azure Cosmos DB för MongoDB-dokumentlagring och vektorsökning.

Konfigurera miljön för API:et

Vi använde Python version 3.11.4 för utveckling och testning av API:et.

Konfigurera din virtuella Python-miljö i api-katalogen :

    python -m venv venv

Aktivera din miljö och installera beroenden med hjälp av kravfilen i api-katalogen :

    venv\Scripts\activate
    python -m pip install -r requirements.txt

Skapa en fil med namnet .env i api-katalogen för att lagra dina miljövariabler:

    OPENAI_API_KEY="<your Open AI key>"
    MONGO_CONNECTION_STRING="mongodb+srv:<your connection string from Azure Cosmos DB>"

Nu när du har konfigurerat miljön och konfigurerat variabler kör du följande kommando från api-katalogen för att initiera servern:

    python app.py

FastAPI-servern startar som standard på localhost-loopback 127.0.0.1 port 8000. Du kan komma åt Swagger-dokumenten med hjälp av följande localhost-adress: http://127.0.0.1:8000/docs.

Använda en session för AI-agentminnet

Det är absolut nödvändigt att resebyrån kan referera till tidigare tillhandahållen information i den pågående konversationen. Den här möjligheten kallas ofta för minne i kontexten för LLM:er.

För att uppnå det här målet använder du chattmeddelandehistoriken som lagras i Azure Cosmos DB-instansen. Historiken för varje chattsession lagras via ett sessions-ID för att säkerställa att endast meddelanden från den aktuella konversationssessionen är tillgängliga. Den här nödvändigheten är orsaken till att det finns en Get Session metod i API:et. Det är en platshållarmetod för att hantera webbsessioner för att illustrera användningen av chattmeddelandehistorik.

Välj Prova för /session/.

Skärmbild av användningen av metoden Hämta session i Python FastAPI med knappen för att testa den.

{
  "session_id": "0505a645526f4d68a3603ef01efaab19"
}

För AI-agenten behöver du bara simulera en session. Metoden stubbed-out returnerar bara ett genererat sessions-ID för spårning av meddelandehistorik. I en praktisk implementering skulle den här sessionen lagras i Azure Cosmos DB och eventuellt i React localStorage.

Här är innehållet i web/session.py:

    @router.get("/")
    def get_session():
        return {'session_id':str(uuid.uuid4().hex)}

Starta en konversation med AI-resebyrån

Använd sessions-ID:t som du hämtade från föregående steg för att starta en ny dialog med AI-agenten, så att du kan verifiera dess funktioner. Utför testet genom att skicka in följande fras: "Jag vill ta en avkopplande semester."

Välj Prova för /agent/agent_chat.

Skärmbild av användningen av metoden Agentchatt i Python FastAPI med knappen för att testa den.

Använd den här exempelparametern:

{
  "input": "I want to take a relaxing vacation.",
  "session_id": "0505a645526f4d68a3603ef01efaab19"
}

Den första körningen resulterar i en rekommendation för Tranquil Breeze Cruise och Fantasy Seas Adventure Cruise, eftersom agenten förväntar sig att de är de mest avkopplande kryssningarna som är tillgängliga genom vektorsökningen. Dessa dokument har den högsta poängen för similarity_search_with_score anropat i api:ets datalager, data.mongodb.travel.similarity_search().

Likhetssökningspoängen visas som utdata från API:et i felsökningssyfte. Här är utdata efter ett anrop till data.mongodb.travel.similarity_search():

0.8394561085977978
0.8086545112328692
2

Dricks

Om dokument inte returneras för vektorsökning ändrar du similarity_search_with_score gränsen eller poängfiltervärdet efter behov ([doc for doc, score in docs if score >=.78]) i data.mongodb.travel.similarity_search().

När du anropar agent_chat för första gången skapas en ny samling med namnet history i Azure Cosmos DB för att lagra konversationen efter session. Det här anropet gör det möjligt för agenten att komma åt den lagrade chattmeddelandehistoriken efter behov. Efterföljande körningar av agent_chat med samma parametrar ger varierande resultat, eftersom det drar från minnet.

Gå igenom AI-agenten

När du integrerar AI-agenten i API:et ansvarar webbsökningskomponenterna för att initiera alla begäranden. Webbsökningskomponenterna följs av söktjänsten och slutligen datakomponenterna.

I det här specifika fallet använder du en MongoDB-datasökning som ansluter till Azure Cosmos DB. Lagren underlättar utbytet av modellkomponenter, med AI-agenten och AI-agentens verktygskod som finns i tjänstskiktet. Den här metoden möjliggör sömlös utbyte av datakällor. Den utökar även AI-agentens funktioner med ytterligare, mer invecklade funktioner eller verktyg.

Diagram över FastAPI-lagren i AI-resebyrån.

Tjänstlager

Tjänstlagret utgör hörnstenen i kärnaffärslogik. I det här scenariot spelar tjänstlagret en avgörande roll som lagringsplats för LangChain Agent-koden. Det underlättar sömlös integrering av användarfrågor med Azure Cosmos DB-data, konversationsminne och agentfunktioner för AI-agenten.

Tjänstskiktet använder en singleton-mönstermodul för hantering av agentrelaterade initieringar i init.py-filen. Här är innehållet i tjänsten/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()

Filen init.py initierar inläsningen av miljövariabler från en .env-fil med hjälp load_dotenv(override=False) av metoden . Sedan instansieras en global variabel med namnet agent_with_chat_history för agenten. Den här agenten är avsedd för användning av TravelAgent.py.

Metoden LLM_init() anropas under modulinitiering för att konfigurera AI-agenten för konversation via API-webblagret. OpenAI-objektet chat instansieras via GPT-3.5-modellen och innehåller specifika parametrar som modellnamn och temperatur. Objektet chat , verktygslistan och promptmallen kombineras för att generera AgentExecutor, som fungerar som AI-resebyrå.

Agenten med historik, agent_with_chat_history, upprättas via RunnableWithMessageHistory med chatthistorik (MongoDBChatMessageHistory). Med den här åtgärden kan den upprätthålla en fullständig konversationshistorik via Azure Cosmos DB.

Prompt

LLM-prompten började ursprungligen med det enkla uttalandet "Du är en användbar och vänlig reseassistent för ett kryssningsföretag." Testningen visade dock att du kunde få mer konsekventa resultat genom att inkludera instruktionen "Besvara resefrågor efter bästa förmåga och ge endast relevant information. För att boka en kryssning är det viktigt att fånga personens namn." Resultatet visas i HTML-format för att förbättra webbgränssnittets visuella attraktionskraft.

Agentverktyg

Verktyg är gränssnitt som en agent kan använda för att interagera med världen, ofta via funktionsanrop.

När du skapar en agent måste du förse den med en uppsättning verktyg som den kan använda. Dekoratören @tool erbjuder det enklaste sättet att definiera ett anpassat verktyg.

Som standard använder dekoratören funktionsnamnet som verktygsnamn, även om du kan ersätta det genom att ange en sträng som det första argumentet. Dekoratören använder funktionens dokumentsträng som verktygets beskrivning, så det kräver etablering av en dokumentsträng.

Här är innehållet i tjänsten/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"

Filen TravelAgentTools.py definierar tre verktyg:

  • vacation_lookup utför en vektorsökning mot Azure Cosmos DB. Det används similarity_search för att hämta relevant reserelaterat material.
  • itinerary_lookup hämtar information om kryssningspaket och scheman för ett angivet kryssningsfartyg.
  • book_cruise bokar ett kryssningspaket för en passagerare.

Specifika instruktioner ("För att boka en kryssning behöver jag veta ditt namn") kan vara nödvändiga för att säkerställa fångsten av passagerarens namn och rumsnummer för bokning av kryssningspaketet, även om du inkluderade sådana instruktioner i LLM-prompten.

AI-agent

Det grundläggande konceptet som ligger till grund för agenter är att använda en språkmodell för att välja en sekvens med åtgärder som ska köras.

Här är innehållet i tjänsten/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))

Den TravelAgent.py filen är enkel eftersom agent_with_chat_history och dess beroenden (verktyg, prompt och LLM) initieras och konfigureras i init.py-filen. Den här filen anropar agenten med hjälp av indata som tagits emot från användaren, tillsammans med sessions-ID:t för konversationsminne. Därefter PromptResponse returneras (modell/prompt) med agentens utdata- och svarstid.

AI-agentintegrering med React-användargränssnittet

Med den lyckade inläsningen av data och tillgänglighet för AI-agenten via API:et kan du nu slutföra lösningen genom att upprätta ett webbanvändargränssnitt (med React) för din resewebbplats. Genom att använda funktionerna i React kan du illustrera den sömlösa integreringen av AI-agenten i en resewebbplats. Den här integreringen förbättrar användarupplevelsen med en samtalsreseassistent för förfrågningar och bokningar.

Konfigurera miljön för React

Installera Node.js och beroendena innan du testar React-gränssnittet.

Kör följande kommando från webbkatalogen för att utföra en ren installation av projektberoenden. Installationen kan ta lite tid.

    npm ci

Skapa sedan en fil med namnet .env i webbkatalogen för att underlätta lagringen av miljövariabler. Inkludera följande information i den nyligen skapade .env-filen :

REACT_APP_API_HOST=http://127.0.0.1:8000

Kör nu följande kommando från webbkatalogen för att initiera React-webbanvändargränssnittet:

    npm start

När du kör föregående kommando öppnas React-webbprogrammet.

Gå igenom React-webbgränssnittet

Webbprojektet för GitHub-lagringsplatsen är ett enkelt program som underlättar användarinteraktion med AI-agenten. De primära komponenter som krävs för att kommunicera med agenten är TravelAgent.js och ChatLayout.js. Filen Main.js fungerar som den centrala modulen eller användarens landningssida.

Skärmbild av React JavaScript-webbgränssnittet.

Huvud

Huvudkomponenten fungerar som central chef för programmet. Den fungerar som den avsedda startpunkten för routning. I återgivningsfunktionen genererar den JSX-kod för att avgränsa huvudsideslayouten. Den här layouten omfattar platshållarelement för programmet, till exempel logotyper och länkar, ett avsnitt som innehåller resebyråkomponenten och en sidfot som innehåller ett exempel på ansvarsfriskrivning om programmets natur.

Här är innehållet i 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

Resebyrå

Resebyråkomponenten har ett enkelt syfte: att samla in användarindata och visa svar. Den spelar en viktig roll för att hantera integreringen med backend-AI-agenten, främst genom att samla in sessioner och vidarebefordra användarfrågor till FastAPI-tjänsten. De resulterande svaren lagras i en matris för visning, vilket underlättas av chattlayoutkomponenten.

Här är innehållet i 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>
  )
}

Välj Enkelt planera din resa för att öppna reseassistenten.

Chattlayout

Komponenten för chattlayout övervakar arrangemanget av chatten. Den bearbetar systematiskt chattmeddelandena och implementerar den formatering som anges i message JSON-objektet.

Här är innehållet i TripPlanning/ChatLayout.py:

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>
  )
}

Användarprompter är på höger sida och färgade blå. Svar från AI-resebyrån finns på vänster sida och färgade gröna. Som följande bild visar redovisas de HTML-formaterade svaren i konversationen.

Skärmbild av en chatt.

När DIN AI-agent är redo att gå in i produktion kan du använda semantisk cachelagring för att förbättra frågeprestanda med 80 % och minska kostnaderna för LLM-slutsatsdragning och API-anrop. Information om hur du implementerar semantisk cachelagring finns i det här inlägget på stochastic Coder-bloggen.

Diagram över semantisk cachelagring.