Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Intelligens AI-ügynök létrehozása a Go és az Azure DocumentDB használatával. Ez a rövid útmutató egy kétügynök-architektúrát mutat be, amely szemantikai szállodakeresést végez, és személyre szabott javaslatokat hoz létre.
Important
Ez a minta egy referencia-implementáció, amely a Go programozási nyelv ügynök-alapú mintáit mutatja be. Egy ügynökkeretrendszer helyett egyedi ügynökarchitektúrát használ, ami az üzemeltetési ügynöki alkalmazásokhoz ajánlott módszer.
Prerequisites
Az Azure Developer CLI használatával létrehozhatja a szükséges Azure-erőforrásokat a azd mintaadattár parancsainak futtatásával. További információ: Infrastruktúra üzembe helyezése az Azure Developer CLI-vel.
Azure-erőforrások
Azure OpenAI-erőforrás a következő modelltelepítésekkel a Microsoft Foundryben:
-
gpt-4oüzembe helyezés (szintetizátorügynök) – Ajánlott: 50 000 token/perc (TPM) kapacitás -
gpt-4o-miniüzembe helyezés (Planner-ügynök) – Ajánlott: 30 000 token/perc (TPM) kapacitás -
text-embedding-3-smallüzembe helyezés (beágyazások) – Ajánlott: 10 000 token/perc (TPM) kapacitás -
Jogkivonatkvóták: Konfiguráljon elegendő TPM-et minden üzembe helyezéshez a sebességkorlátozás elkerülése érdekében
- Lásd: Azure OpenAI-kvóták kezelése a kvótakezeléshez
- Ha 429-et tapasztal, növelje a TPM-kvótát, vagy csökkentse a kérelmek gyakoriságát
-
Azure DocumentDB-fürt, amely kompatibilis a MongoDB-vel, vektorkeresési támogatással:
-
A fürtréteg követelményei vektorindex-algoritmuson alapulnak:
- IVF (invertált fájlindex): M10 vagy újabb (alapértelmezett algoritmus)
- HNSW (Hierarchikus navigálható kisvilág): M30 vagy újabb (gráfalapú)
- DiskANN: M40 vagy újabb (nagy léptékűre optimalizálva)
-
Tűzfalkonfiguráció: KÖTELEZŐ A megfelelő tűzfalkonfiguráció nélkül a csatlakozási kísérletek meghiúsulnak
- Adja hozzá az ügyfél IP-címét a fürt tűzfalszabályaihoz. További információ: Hozzáférés engedélyezése az IP-címről.
- Jelszó nélküli hitelesítés esetén a szerepköralapú hozzáférés-vezérlés (RBAC) engedélyezve van
-
A fürtréteg követelményei vektorindex-algoritmuson alapulnak:
Fejlesztői eszközök
Architecture
A minta egy kétügynök-architektúrát használ, amelyben minden ügynöknek van egy adott szerepköre.
Ez a minta egy egyéni implementációt használ közvetlenül az OpenAI SDK-val, anélkül, hogy ügynök-keretrendszerre támaszkodik. Az OpenAI függvényt használja az eszközintegráció céljából, és lineáris munkafolyamatot követ az ügynökök és a keresőeszköz között. A végrehajtás állapot nélküli, beszélgetési előzmények nélkül, így alkalmas egyfordulós lekérdezési és válaszhelyzetekhez.
A mintakód lekérése
A gyors kezdés követéséhez klónozza vagy töltse le az Azure DocumentDB mintákat a helyi gépére.
Lépjen be a projektkönyvtárba:
cd ai/vector-search-agent-go
Környezeti változók konfigurálása
Hozzon létre egy .env fájlt a projekt gyökérkönyvtárában a környezeti változók konfigurálásához. Létrehozhat egy másolatot a .env.sample fájlról az adattárból.
Szerkessze a .env fájlt, és cserélje le a helyőrző értékeket.
Ez a gyorsindítás egy kétügynökös architektúrát (tervező + szintetizátor) használ három modelltelepítéssel (két csevegőmodell + beágyazások). A környezeti változók minden modelltelepítéshez konfigurálva vannak.
-
AZURE_OPENAI_PLANNER_DEPLOYMENT: A gpt-4o-mini üzembehelyezési neve -
AZURE_OPENAI_SYNTH_DEPLOYMENT: Az Ön gpt-4o telepítési neve -
AZURE_OPENAI_EMBEDDING_DEPLOYMENT: Az ön text-embedding-3-small telepítési neve
Két hitelesítési módszer közül választhat: jelszó nélküli hitelesítés az Azure Identity használatával (ajánlott), vagy hagyományos kapcsolati sztring és API-kulcs.
1. lehetőség: Jelszó nélküli hitelesítés
Használjon jelszó nélküli hitelesítést az Azure OpenAI-val és az Azure DocumentDB-vel is. Beállítás USE_PASSWORDLESS=true, AZURE_OPENAI_ENDPOINT, és AZURE_DOCUMENTDB_CLUSTER.
# Enable passwordless authentication
USE_PASSWORDLESS=true
# Azure OpenAI Configuration (passwordless)
AZURE_OPENAI_ENDPOINT=your-openai-endpoint
# Azure DocumentDB (passwordless)
AZURE_DOCUMENTDB_CLUSTER=your-mongo-cluster-name
AZURE_DOCUMENTDB_DATABASENAME=Hotels
AZURE_DOCUMENTDB_COLLECTION=hotel_data
AZURE_DOCUMENTDB_INDEX_NAME=vectorIndex
A jelszó nélküli hitelesítés előfeltételei:
Győződjön meg arról, hogy bejelentkezett az Azure-ba:
az loginAdja meg identitásának a következő szerepköröket:
-
Cognitive Services OpenAI Useraz Azure OpenAI-erőforráson -
DocumentDB Account ContributorésCosmos DB Account Reader Roleaz Azure DocumentDB-erőforráson
A szerepkörök hozzárendelésével kapcsolatos további információkért lásd: Azure-szerepkörök hozzárendelése az Azure Portal használatával.
-
2. lehetőség: Kapcsolati sztring és API-kulcs hitelesítése
Használjon kulcsalapú hitelesítést a USE_PASSWORDLESS=false beállításával (vagy kihagyásával), és adja meg a AZURE_OPENAI_API_KEY és AZURE_DOCUMENTDB_CONNECTION_STRING értékeket a .env fájlban.
# Disable passwordless authentication
USE_PASSWORDLESS=false
# Azure OpenAI Configuration (API key)
AZURE_OPENAI_ENDPOINT=your-openai-endpoint
AZURE_OPENAI_API_KEY=your-azure-openai-api-key
# Azure DocumentDB (connection string)
AZURE_DOCUMENTDB_CONNECTION_STRING=mongodb+srv://username:password@cluster.mongocluster.cosmos.azure.com/
AZURE_DOCUMENTDB_DATABASENAME=Hotels
AZURE_DOCUMENTDB_COLLECTION=hotel_data
AZURE_DOCUMENTDB_INDEX_NAME=vectorIndex
A projekt szerkezete
A projekt a szokásos Go-projektelrendezést követi. A címtárszerkezetnek a következő struktúrához hasonlóan kell kinéznie:
mongo-vcore-agent-go/
├── cmd/
│ ├── agent/ # Main agent application
│ │ └── main.go
│ ├── upload/ # Data upload utility
│ │ └── main.go
│ └── cleanup/ # Database cleanup utility
│ └── main.go
├── internal/
│ ├── agents/ # Agent and tool implementations
│ │ ├── agents.go # Planner and synthesizer agents
│ │ └── tools.go # Vector search tool
│ ├── clients/ # Azure OpenAI client
│ │ └── openai.go
│ ├── models/ # Hotel data models
│ │ └── hotel.go
│ ├── prompts/ # System prompts and tool definitions
│ │ └── prompts.go
│ └── vectorstore/ # Azure DocumentDB vector store operations
│ └── store.go
├── .env # Environment variable configuration
├── go.mod # Go module file
└── go.sum # Go module checksum file
A kód megismerése
Ez a szakasz az AI-ügynök munkafolyamatának alapvető összetevőit ismerteti. Kiemeli, hogy az ügynökök hogyan dolgozzák fel a kéréseket, hogyan csatlakoztatják az eszközök az AI-t az adatbázishoz, és hogy a kérések hogyan irányítja az AI viselkedését.
Ügynök alkalmazás
A cmd/agent/main.go fájl egy AI-alapú szállodaajánlási rendszert vezényl.
Az alkalmazás két Azure-szolgáltatást használ:
- A lekérdezéseket megértő és javaslatokat generáló AI-modelleket használó Azure OpenAI
- Azure DocumentDB, amely szállodai adatokat tárol, és vektoros hasonlósági keresést végez
Ügynök- és eszközösszetevők
A három összetevő együttműködve dolgozza fel a szálloda keresési kérését:
- Planner-ügynök – Értelmezi a kérést, és eldönti, hogyan kell keresni
- Vektorkereső eszköz – A Planner-ügynök által leírthoz hasonló szállodák keresése
- Szintetizátorügynök – Hasznos javaslatot ír a keresési eredmények alapján
Alkalmazás munkafolyamata
Az alkalmazás két lépésben dolgozza fel a szálloda keresési kérését:
- Tervezés: A munkafolyamat meghívja a planner-ügynököt, amely elemzi a felhasználó lekérdezését (például "futó nyomvonalak közelében lévő szállodák"), és megkeresi az adatbázisban az egyező szállodákat.
- Szintetizáló: A munkafolyamat meghívja a szintetizátor-ügynököt, amely áttekinti a keresési eredményeket, és személyre szabott javaslatot ír, amely ismerteti, hogy mely szállodák felelnek meg a legjobban a kérésnek.
// Run planner agent
hotelContext, err := plannerAgent.Run(ctx, query, nearestNeighbors)
if err != nil {
log.Fatalf("Planner agent failed: %v", err)
}
if debug {
fmt.Printf("\n--- HOTEL CONTEXT ---\n%s\n", hotelContext)
}
// Run synthesizer agent
finalAnswer, err := synthesizerAgent.Run(ctx, query, hotelContext)
if err != nil {
log.Fatalf("Synthesizer agent failed: %v", err)
}
Agents
A internal/agents/agents.go forrásfájl implementálja azokat a tervező- és szintetizátorügynököket, amelyek együttműködve dolgozzák fel a szállodai keresési kéréseket.
Planner-ügynök
A planner-ügynök az a döntéshozó , amely meghatározza a szállodák keresésének módját.
A planner-ügynök megkapja a felhasználó természetes nyelvi lekérdezését, és elküldi azt egy AI-modellnek a használható eszközökkel együtt. Az AI úgy dönt, hogy meghívja a vektorkereső eszközt, és keresési paramétereket biztosít. Az ügynök ezután kinyeri az eszköz nevét és argumentumait az AI válaszából, végrehajtja a keresőeszközt, és visszaadja a megfelelő szállodákat. A keresési logika keménykódolása helyett az AI értelmezi a felhasználó által kívánt adatokat, és kiválasztja a keresés módját, így a rendszer rugalmassá válik a különböző típusú lekérdezésekhez.
// PlannerAgent orchestrates the tool calling
type PlannerAgent struct {
openAIClients *clients.OpenAIClients
searchTool *VectorSearchTool
debug bool
}
// NewPlannerAgent creates a new planner agent
func NewPlannerAgent(openaiClients *clients.OpenAIClients, searchTool *VectorSearchTool, debug bool) *PlannerAgent {
return &PlannerAgent{
openAIClients: openaiClients,
searchTool: searchTool,
debug: debug,
}
}
// Run executes the planner agent workflow
func (a *PlannerAgent) Run(ctx context.Context, userQuery string, nearestNeighbors int) (string, error) {
fmt.Println("\n--- PLANNER ---")
userMessage := fmt.Sprintf(
`Search for hotels matching this request: "%s". Use nearestNeighbors=%d.`,
userQuery,
nearestNeighbors,
)
// Get tool definition
toolDef := a.searchTool.GetToolDefinition()
// Call planner with tool definitions
resp, err := a.openAIClients.ChatCompletionWithTools(ctx, prompts.PlannerSystemPrompt, userMessage, []openai.ChatCompletionToolUnionParam{toolDef})
if err != nil {
return "", fmt.Errorf("planner failed: %w", err)
}
// Extract tool call
toolName, argsMap, err := clients.ExtractToolCall(resp)
if err != nil {
return "", fmt.Errorf("failed to extract tool call: %w", err)
}
if toolName != prompts.ToolName {
return "", fmt.Errorf("unexpected tool called: %s", toolName)
}
// Parse arguments using typed struct
args, err := parseToolArgumentsFromMap(argsMap)
if err != nil {
return "", fmt.Errorf("failed to parse tool arguments: %w", err)
}
// Use default if nearestNeighbors not provided
if args.NearestNeighbors == 0 {
args.NearestNeighbors = nearestNeighbors
}
fmt.Printf("Tool: %s\n", toolName)
fmt.Printf("Query: %s\n", args.Query)
fmt.Printf("K: %d\n", args.NearestNeighbors)
// Execute the tool
searchResults, err := a.searchTool.Execute(ctx, args.Query, args.NearestNeighbors)
if err != nil {
return "", fmt.Errorf("search tool execution failed: %w", err)
}
return searchResults, nil
}
Szintetizátorügynök
A szintetizátorügynök az az író, aki hasznos javaslatokat hoz létre.
A szintetizátorügynök megkapja az eredeti felhasználói lekérdezést a szálloda keresési eredményeivel együtt. Mindent elküld egy AI-modellnek a javaslatok megírására vonatkozó útmutatással. Természetes nyelvi választ ad vissza, amely összehasonlítja a szállodákat, és elmagyarázza a legjobb lehetőségeket. Ez a megközelítés azért fontos, mert a nyers keresési eredmények nem felhasználóbarátak. A szintetizátor beszélgetési javaslattá alakítja az adatbázisrekordokat, amely elmagyarázza, hogy egyes szállodák miért felelnek meg a felhasználó igényeinek.
// NewSynthesizerAgent creates a new synthesizer agent
func NewSynthesizerAgent(openaiClients *clients.OpenAIClients, debug bool) *SynthesizerAgent {
return &SynthesizerAgent{
openAIClients: openaiClients,
debug: debug,
}
}
// Run executes the synthesizer agent workflow
func (a *SynthesizerAgent) Run(ctx context.Context, userQuery, hotelContext string) (string, error) {
fmt.Println("\n--- SYNTHESIZER ---")
fmt.Printf("Context size: %d characters\n", len(hotelContext))
userMessage := prompts.CreateSynthesizerUserPrompt(userQuery, hotelContext)
// Call synthesizer (no tools)
finalAnswer, err := a.openAIClients.ChatCompletion(ctx, prompts.SynthesizerSystemPrompt, userMessage)
if err != nil {
return "", fmt.Errorf("synthesizer failed: %w", err)
}
return finalAnswer, nil
}
Ügynökeszközök
A internal/agents/tools.go forrásfájl határozza meg a planner-ügynök által használt vektorkeresési eszközt.
Az eszközfájl egy keresőeszközt határoz meg, amelyet az AI-ügynök használhat a szállodák kereséséhez. Az ügynök így csatlakozik az adatbázishoz. Az AI nem keres közvetlenül az adatbázisban. Kéri a keresőeszköz használatát, és az eszköz végrehajtja a tényleges keresést.
Eszközdefiníció
A GetToolDefinition metódus az eszközt az AI-modell számára az általa ismert formátumban írja le. Megadja az eszköz nevét, az eszköz nevének leírását, valamint azokat a paramétereket, amelyek meghatározzák, hogy az eszköznek milyen bemenetekre van szüksége. Ez a definíció tudatja az AI-t az eszköz meglétéről és helyes használatáról.
// GetToolDefinition returns the Azure OpenAI tool definition
func (t *VectorSearchTool) GetToolDefinition() openai.ChatCompletionToolUnionParam {
paramSchema := map[string]any{
"type": "object",
"properties": map[string]any{
"query": map[string]any{
"type": "string",
"description": "Natural language search query describing desired hotel characteristics",
},
"nearestNeighbors": map[string]any{
"type": "integer",
"description": "Number of results to return (1-20)",
"default": 5,
},
},
"required": []string{"query", "nearestNeighbors"},
}
return openai.ChatCompletionToolUnionParam{
OfFunction: &openai.ChatCompletionFunctionToolParam{
Function: openai.FunctionDefinitionParam{
Name: prompts.ToolName,
Description: openai.String(prompts.ToolDescription),
Parameters: paramSchema,
},
},
}
}
Eszköz végrehajtása
Amikor az AI meghívja az eszközt, a Execute metódus fut. Beágyazást hoz létre úgy, hogy a szöveges lekérdezést numerikus vektorsá alakítja az Azure OpenAI beágyazási modelljével. Ezután megkeresi az adatbázist úgy, hogy elküldi a vektort az Azure DocumentDB-nek, amely hasonló, hasonló leírást jelentő vektorokkal rendelkező szállodákat talál. Végül úgy formázhatja az eredményeket, hogy az adatbázisrekordokat olvasható szöveggé alakítja, amelyet a szintetizátorügynök megérthet.
// Execute performs the vector search
func (t *VectorSearchTool) Execute(ctx context.Context, query string, nearestNeighbors int) (string, error) {
// Generate embedding for query
queryVector, err := t.openAIClients.GenerateEmbedding(ctx, query)
if err != nil {
return "", fmt.Errorf("failed to generate embedding: %w", err)
}
// Perform vector search
results, err := t.vectorStore.VectorSearch(ctx, queryVector, nearestNeighbors)
if err != nil {
return "", fmt.Errorf("vector search failed: %w", err)
}
// Format results for synthesizer
var formattedResults []string
for i, result := range results {
fmt.Printf("Hotel #%d: %s, Score: %.6f\n", i+1, result.Hotel.HotelName, result.Score)
formattedResults = append(formattedResults, vectorstore.FormatHotelForSynthesizer(result))
}
return strings.Join(formattedResults, "\n\n"), nil
}
Miért érdemes ezt a mintát használni?
Az eszköz az ügynöktől való elválasztása rugalmasságot biztosít. Az AI dönti el, hogy mikor és mire keressen, míg az eszköz kezeli a keresés módját. Az ügynöklogika módosítása nélkül további eszközöket is hozzáadhat.
Felkérések
A internal/prompts/prompts.go forrásfájl rendszerkéréseket és eszközdefiníciókat tartalmaz az ügynökök számára.
A parancssori fájl meghatározza az AI-modelleknek adott utasításokat és kontextust mind a tervező, mind a szintetizáló ügynökök számára. Ezek a kérések útmutatást adnak az AI viselkedéséhez, és biztosítják, hogy megértse a munkafolyamatban betöltött szerepét.
Az AI-válaszok minősége nagymértékben függ az egyértelmű utasításoktól. Ezek a kérések határokat határoznak meg, definiálják a kimeneti formátumot, és a felhasználó döntési céljára összpontosítják az AI-t. Ezeket a kéréseket testreszabhatja úgy, hogy kód módosítása nélkül módosítsa az ügynökök viselkedését.
const PlannerSystemPrompt = `You are a hotel search planner. Your job is to help users find hotels by calling the search tool.
CRITICAL INSTRUCTION: You MUST call the "search_hotels_collection" tool for every request. This is the ONLY way to search the database.
When you call the tool, use these parameters:
- query: A clear, detailed natural language description of what the user is looking for. Expand vague requests (e.g., "nice hotel" → "hotel with high ratings, good reviews, and quality amenities").
- nearestNeighbors: Number of results (1-20). Use 3-5 for specific requests, 10-15 for broader searches.
EXAMPLES of how you should call the tool:
- User: "cheap hotel" → Call tool with query: "budget-friendly hotel with good value and affordable rates", nearestNeighbors: 10
- User: "hotel near downtown with parking" → Call tool with query: "hotel near downtown with good parking and wifi", nearestNeighbors: 5
IMPORTANT: Always call the tool. Do not provide answers without calling the tool first.`
const SynthesizerSystemPrompt = `You are an expert hotel recommendation assistant using vector search results.
Only use the TOP 3 results provided. Do not request additional searches or call other tools.
GOAL: Provide a concise comparative recommendation to help the user choose between the top 3 options.
REQUIREMENTS:
- Compare only the top 3 results across the most important attributes: rating, score, location, price-level (if available), and key tags (parking, wifi, pool).
- Identify the main tradeoffs in one short sentence per tradeoff.
- Give a single clear recommendation with one short justification sentence.
- Provide up to two alternative picks (one sentence each) explaining when they are preferable.
FORMAT CONSTRAINTS:
- Plain text only (no markdown).
- Keep the entire response under 220 words.
- Use simple bullets (•) or numbered lists and short sentences (preferably <25 words per sentence).
- Preserve hotel names exactly as provided in the tool summary.
Do not add extra commentary, marketing language, or follow-up questions. If information is missing and necessary to choose, state it in one sentence and still provide the best recommendation based on available data.`
A minta futtatása
Az ügynök futtatása előtt töltse fel a szálloda adatait beágyazásokkal. A
cmd/upload/main.goparancs betölti a szállodákat a JSON-fájlból, beágyazásokat hoz létre minden szállodához az Azure DocumentDB használatávaltext-embedding-3-small, dokumentumokat szúr be az Azure DocumentDB-be, és létrehoz egy vektorindexet.go run cmd/upload/main.goFuttassa a szállodai ajánlási ügynököt a
cmd/agent/main.goparancs használatával. Az ügynök meghívja a tervezőügynököt, a vektorkeresést és a szintetizátor-ügynököt. A kimenet hasonlósági pontszámokat és a szintetizátorügynök javaslatokkal végzett összehasonlító elemzését tartalmazza.go run cmd/agent/main.goQuery: quintessential lodging near running trails, eateries, retail Nearest Neighbors: 5 --- PLANNER --- Tool: search_hotels_collection Query: quintessential lodging near running trails, eateries, and retail shops with good amenities and access to outdoor activities K: 5 Hotel #1: Nordick's Valley Motel, Score: 0.498665 Hotel #2: White Mountain Lodge & Suites, Score: 0.487320 Hotel #3: Trails End Motel, Score: 0.479854 Hotel #4: Country Comfort Inn, Score: 0.474320 Hotel #5: Lakefront Captain Inn, Score: 0.457873 --- SYNTHESIZER --- Context size: 3233 characters --- FINAL ANSWER --- 1. COMPARISON SUMMARY: • Nordick's Valley Motel has the highest rating (4.5) and offers free parking, air conditioning, and continental breakfast. It is located in Washington D.C., near historic attractions and trails. • White Mountain Lodge & Suites is a resort with unique amenities like a pool, restaurant, and meditation gardens, but has the lowest rating (2.4). It is located in Denver, surrounded by forest trails. • Trails End Motel is budget-friendly with a moderate rating (3.2), free parking, free wifi, and a restaurant. It is close to downtown Scottsdale and eateries. Key tradeoffs: - Nordick's Valley Motel excels in rating and proximity to historic attractions but lacks a pool or free wifi. - White Mountain Lodge & Suites offers resort-style amenities and forest trails but has the lowest rating. - Trails End Motel balances affordability and essential amenities but has fewer unique features compared to the others. 2. BEST OVERALL: Nordick's Valley Motel is the best choice for its high rating, proximity to trails and attractions, and free parking. 3. ALTERNATIVE PICKS: • Choose White Mountain Lodge & Suites if you prioritize resort amenities and forest trails over rating. • Choose Trails End Motel if affordability and proximity to downtown Scottsdale are your main concerns.
Adatok megtekintése és kezelése a Visual Studio Code-ban
Válassza ki a DocumentDB bővítményt a Visual Studio Code-ban az Azure DocumentDB-fiókhoz való csatlakozáshoz.
Az adatok és indexek megtekintése a Hotels adatbázisban.
Erőforrások tisztítása
A törlési paranccsal törölheti a tesztadatbázist, amikor végzett. Futtassa a következő parancsot:
go run cmd/cleanup/main.go
Törölje az erőforráscsoportot, a DocumentDB-fiókot és az Azure OpenAI-erőforrást, ha nincs rájuk szüksége a többletköltségek elkerülése érdekében.