Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
TypeScript ve Azure DocumentDB kullanarak akıllı bir yapay zeka aracısı oluşturun. Bu hızlı başlangıçta anlamsal otel araması gerçekleştiren ve kişiselleştirilmiş öneriler oluşturan iki aracılı bir mimari gösterilmektedir.
Important
Bu örnekte yapay zeka uygulamaları oluşturmaya yönelik popüler bir çerçeve olan LangChain kullanılmaktadır. LangChain, aracılar, araçlar ve komut istemleri geliştirmeyi basitleştiren soyutlamalar sağlar.
Prerequisites
Örnek depodaki komutları çalıştırarak gerekli Azure kaynaklarını oluşturmak için Azure Geliştirici CLI'sını azd kullanabilirsiniz. Daha fazla bilgi için bkz. Azure Geliştirici CLI ile Altyapı Dağıtma.
Azure kaynakları
-
-
gpt-4odağıtımı (Synthesizer Agent) - Önerilen: Dakikada 50.000 belirteç (TPM) kapasitesi -
gpt-4o-minideployment (Planner Agent) - Önerilen: Dakikada 30.000 token (TPM) kapasitesi -
text-embedding-3-smalldağıtım (Eklemeler) - Önerilen: Dakikada 10.000 belirteç (TPM) kapasitesi -
Belirteç kotaları: Hız sınırlamasını önlemek için her dağıtım için yeterli TPM'yi yapılandırın
- Kota yönetimi için bkz. Azure OpenAI kotalarını yönetme
- 429 hatasıyla karşılaşırsanız TPM kotanızı artırın veya istek sıklığını azaltın
-
Vektör arama desteğine sahip Azure DocumentDB (MongoDB uyumluluğu ile) kümesi:
- Tercih ettiğiniz vektör dizini algoritmasına göre küme katmanı gereksinimleri:
- IVF (Ters Dosya Dizini): M10 veya üzeri (varsayılan algoritma)
- HNSW (Hiyerarşik Gezinilebilir Küçük Dünya): M30 veya üzeri (graf tabanlı)
- DiskANN: M40 veya üzeri (büyük ölçekli için iyileştirilmiş)
-
Güvenlik duvarı yapılandırması: GEREKLI. Düzgün güvenlik duvarı yapılandırması olmadan bağlantı girişimleri başarısız olur.
- İstemci IP adresinizi kümenin güvenlik duvarı kurallarına ekleyin. Daha fazla bilgi için bkz. IP adresinizden erişim izni verme.
- Parolasız kimlik doğrulaması için rol tabanlı erişim denetiminin (RBAC) etkinleştirildiğinden emin olun.
- Tercih ettiğiniz vektör dizini algoritmasına göre küme katmanı gereksinimleri:
Geliştirme araçları
- Kaynak sağlama için Azure Geliştirici CLI'sı
- Node.js LTS
- TypeScript 5.0 veya üzeri
- Kimlik doğrulaması için Azure CLI
- Veritabanı yönetimi için DocumentDB uzantısına sahip Visual Studio Code (isteğe bağlı)
Node.js için aracılı RAG uygulama mimarisi
Örnek, her ajanın belirli bir role sahip olduğu iki ajanlı bir mimari kullanır.
Bu örnek, OpenAI SDK'sı ile LangChain'in aracı çerçevesini kullanır. LangChain'in araç tümleştirmesi için özetleri çağıran işlevinden yararlanarak aracılarla arama aracıları arasında doğrusal bir iş akışı izler. Durum bilgisi olmadan gerçekleştirilen yürütme, konuşma geçmişine sahip olmadığı için, teketap sorgu ve yanıt senaryoları için uygundur.
Node.js örnek kodunu alma
Hızlı başlangıcı izlemek için Azure DocumentDB Örnekleri deposunu yerel makinenize kopyalayın veya indirin.
Proje dizinine gidin:
cd ai/vector-search-agent-typescript
Azure Developer CLI ile Azure kaynaklarını dağıtma
Gerekli Azure OpenAI ve DocumentDB kaynaklarını sağlamak için Azure Geliştirici CLI'sini (azd) kullanın.
Azure'da oturum açın:
azd auth loginAltyapıyı sağlama ve dağıtma:
azd upİstendiğinde aboneliğinizi ve bir konum (örneğin,
swedencentralveyaeastus2) seçin.Dağıtım tamamlandığında,
azdihtiyaç duyduğunuz ortam değişkenlerini oluşturur. Bunları dosyanıza.envkopyalayın (bkz. Ortam değişkenlerini yapılandırma).
Tip
Geçerli ortam değerlerini görüntülemek için istediğiniz zaman komutunu çalıştırın azd env get-values .
Ortam değişkenlerini yapılandırma
Azure kaynaklarınızı el ile oluşturduysanız veya kendi mevcut kaynaklarınızı kullanmak istiyorsanız, uygulamanın Azure OpenAI ve Azure DocumentDB'ye bağlanması için ortam değişkenlerini yapılandırmanız gerekir. Özellikle azd up kullandıysanız, gerekli ortam değişkenleri azd ortamında otomatik olarak ayarlandığı ve azd env get-values ile erişilebildiği için bu adımı atlayabilirsiniz.
Ortam değişkenlerini yapılandırmak için proje kökünde bir .env dosya oluşturun. Depodaki .env.sample dosyasının bir kopyasını oluşturabilirsiniz.
.env Dosyayı düzenleyin ve şu yer tutucu değerlerini değiştirin:
Bu hızlı başlangıç, üç model dağıtımı (iki sohbet modeli + gömme) ile iki ajanlı bir mimari (planlayıcı + sentezleyici) kullanır. Ortam değişkenleri her model dağıtımı için yapılandırılır.
-
AZURE_OPENAI_PLANNER_MODEL: gpt-4o-mini model adınız -
AZURE_OPENAI_SYNTH_MODEL: Gpt-4o model adınız -
AZURE_OPENAI_EMBEDDING_MODEL: Metin ekleme-3-küçük model adınız
İki kimlik doğrulama yöntemi arasından seçim yapabilirsiniz: Azure Identity kullanarak parolasız kimlik doğrulaması (önerilen) veya geleneksel bağlantı dizesi ve API anahtarı.
Seçenek 1: Parolasız kimlik doğrulaması
Hem Azure OpenAI hem de Azure DocumentDB ile parolasız kimlik doğrulaması kullanın.
USE_PASSWORDLESS=true, AZURE_OPENAI_ENDPOINT ve AZURE_DOCUMENTDB_CLUSTER ayarlayın.
# Enable passwordless authentication
USE_PASSWORDLESS=true
# Azure OpenAI Configuration (passwordless)
AZURE_OPENAI_ENDPOINT=your-openai-endpoint
AZURE_OPENAI_PLANNER_MODEL=gpt-4o-mini
AZURE_OPENAI_PLANNER_API_VERSION=2024-08-01-preview
AZURE_OPENAI_SYNTH_MODEL=gpt-4o
AZURE_OPENAI_SYNTH_API_VERSION=2024-08-01-preview
AZURE_OPENAI_EMBEDDING_MODEL=text-embedding-3-small
AZURE_OPENAI_EMBEDDING_API_VERSION=2023-05-15
# Azure DocumentDB (passwordless)
AZURE_DOCUMENTDB_CLUSTER=your-mongo-cluster-name
AZURE_DOCUMENTDB_DATABASENAME=Hotels
AZURE_DOCUMENTDB_COLLECTION=hotel_data
# Data Configuration
DATA_FILE_WITHOUT_VECTORS=../data/Hotels.json
# Vector Index Configuration
VECTOR_INDEX_ALGORITHM=vector-ivf
EMBEDDING_DIMENSIONS=1536
Parolasız kimlik doğrulaması için önkoşullar:
Azure'da oturum açtığınızdan emin olun:
az loginKimliğinize aşağıdaki rolleri verin:
-
Cognitive Services OpenAI UserAzure OpenAI kaynağında -
DocumentDB Account ContributorveCosmos DB Account Reader RoleAzure DocumentDB kaynağında
Rol atama hakkında daha fazla bilgi için bkz. Azure portalını kullanarak Azure rolleri atama.
-
Parolasız kimlik doğrulaması nasıl çalışır?
olduğunda USE_PASSWORDLESS=true, uygulama OAuth belirtecini almak için Azure Kimlik SDK'sından kullanır DefaultAzureCredential . Azure DocumentDB bağlantıları için erişim belirtecini doğrudan MongoDB sürücüsüne geçiren bir OIDC belirteci geri çağırması kullanır. Bu, yapılandırma dosyalarında hiçbir parola veya bağlantı dizesi depolanmadığını gösterir.
Kimlik doğrulama akışı:
-
DefaultAzureCredentialkullanılabilir kimlik bilgilerini (Azure CLI, yönetilen kimlik, ortam değişkenleri) sırayla denetler. - Azure OpenAI'de, belirteç otomatik olarak LangChain
AzureChatOpenAIveAzureOpenAIEmbeddingsistemcilerine geçirilir. - Azure DocumentDB için, bir belirteç geri çağırma işlevi bir erişim belirteci getirir ve bunu mongoDB istemcisine
MONGODB-OIDCkimlik doğrulama mekanizması aracılığıyla sağlar.
import { AzureOpenAIEmbeddings, AzureChatOpenAI } from "@langchain/openai";
import { MongoClient, OIDCCallbackParams } from 'mongodb';
import { AccessToken, DefaultAzureCredential, TokenCredential, getBearerTokenProvider } from '@azure/identity';
/*
This file contains utility functions to create Azure OpenAI clients for embeddings, planning, and synthesis.
It supports two modes of authentication:
1. API Key based authentication using AZURE_OPENAI_API_KEY and AZURE_OPENAI_ENDPOINTenvironment variables.
2. Passwordless authentication using DefaultAzureCredential from Azure Identity library.
*/
// Azure Identity configuration
const OPENAI_SCOPE = 'https://cognitiveservices.azure.com/.default';
const DOCUMENT_DB_SCOPE = 'https://ossrdbms-aad.database.windows.net/.default';
// Azure identity credential (used for passwordless auth)
const CREDENTIAL = new DefaultAzureCredential();
function requireEnvVars(names: string[]) {
const missing = names.filter((name) => {
const value = process.env[name];
return !value || value.trim().length === 0;
});
if (missing.length > 0) {
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
}
}
// Token callback for MongoDB OIDC authentication
async function azureIdentityTokenCallback(
params: OIDCCallbackParams,
credential: TokenCredential
): Promise<{ accessToken: string; expiresInSeconds: number }> {
const tokenResponse: AccessToken | null = await credential.getToken([DOCUMENT_DB_SCOPE]);
return {
accessToken: tokenResponse?.token || '',
expiresInSeconds: (tokenResponse?.expiresOnTimestamp || 0) - Math.floor(Date.now() / 1000)
};
2. Seçenek: Bağlantı dizesi ve API anahtarı kimlik doğrulaması
Anahtar tabanlı kimlik doğrulaması için USE_PASSWORDLESS=false ayarlayarak (veya bunu atlayarak) ve dosyanızda AZURE_OPENAI_API_KEY ve AZURE_DOCUMENTDB_CONNECTION_STRING değerlerini sağlayarak .env dosyanızı kullanın.
# 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_OPENAI_PLANNER_MODEL=gpt-4o-mini
AZURE_OPENAI_PLANNER_API_VERSION=2024-08-01-preview
AZURE_OPENAI_SYNTH_MODEL=gpt-4o
AZURE_OPENAI_SYNTH_API_VERSION=2024-08-01-preview
AZURE_OPENAI_EMBEDDING_MODEL=text-embedding-3-small
AZURE_OPENAI_EMBEDDING_API_VERSION=2023-05-15
# Azure DocumentDB (connection string)
AZURE_DOCUMENTDB_CLUSTER=your-mongo-cluster-name
AZURE_DOCUMENTDB_CONNECTION_STRING=mongodb+srv://username:password@cluster.mongocluster.cosmos.azure.com/
AZURE_DOCUMENTDB_DATABASENAME=Hotels
AZURE_DOCUMENTDB_COLLECTION=hotel_data
# Data Configuration
DATA_FILE_WITHOUT_VECTORS=../data/Hotels.json
# Vector Index Configuration
VECTOR_INDEX_ALGORITHM=vector-ivf
EMBEDDING_DIMENSIONS=1536
Proje yapısı
Proje standart bir Node.js/TypeScript proje düzenini izler. Dizin yapınız aşağıdaki yapı gibi görünmelidir:
vector-search-agent-typescript/
├── src/
│ ├── agent.ts # Main agent application
│ ├── upload-documents.ts # Data upload utility
│ ├── cleanup.ts # Database cleanup utility
│ ├── vector-store.ts # Vector store and tool implementation
│ ├── utils/
│ │ ├── clients.ts # Azure OpenAI and DocumentDB client setup
│ │ ├── prompts.ts # System prompts and tool definitions
│ │ ├── types.ts # TypeScript type definitions
│ │ └── mongo.ts # MongoDB utility functions
│ └── scripts/ # Additional utility scripts
├── .env # Environment variable configuration
├── package.json # npm dependencies and scripts
└── tsconfig.json # TypeScript configuration
Aracılı RAG uygulaması için Node.js kodunu keşfetme
Bu bölümde yapay zeka aracısı iş akışının temel bileşenlerinde yol gösterilir. Aracıların istekleri nasıl işlediği, araçların yapay zekayı veritabanına nasıl bağlayabilmesi ve istemlerin yapay zekanın davranışına nasıl yol göstermesi vurgulanır.
Node.js Agentic RAG uygulaması
Dosya, src/agent.ts yapay zeka destekli bir otel öneri sistemini düzenler.
Uygulama iki Azure hizmeti kullanır:
- Sorguları anlayan ve öneriler oluşturan yapay zeka modellerini kullanan Azure OpenAI
- Otel verilerini depolayan ve vektör benzerliği aramaları yapan Azure DocumentDB
Node.js Aracısı ve araç bileşenleri
Üç bileşen, otel arama isteğini işlemek için birlikte çalışır:
- Planner aracısı - İsteği yorumlar ve arama yöntemine karar verir
- Vektör arama aracı - Planlayıcı aracının anlattığına benzer oteller bulur
- Synthesizer aracısı - Arama sonuçlarına göre yararlı bir öneri yazar
Aracılı RAG Uygulaması iş akışı
Uygulama bir otel arama isteğini iki adımda işler:
- Planlama: İş akışı, kullanıcının sorgusunu analiz eden ("çalışan yollar yakınındaki oteller" gibi) planlayıcı aracısını çağırır ve veritabanında eşleşen oteller arar.
- Sentezleme: İş akışı, arama sonuçlarını inceleyen ve istekle en iyi eşleşen otelleri açıklayan kişiselleştirilmiş bir öneri yazan synthesizer aracısını çağırır.
// Authentication
const clients = process.env.USE_PASSWORDLESS === 'true' || process.env.USE_PASSWORDLESS === '1' ? createClientsPasswordless() : createClients();
const { embeddingClient, plannerClient, synthClient, dbConfig } = clients;
console.log(`DEBUG mode is ${process.env.DEBUG === 'true' ? 'ON' : 'OFF'}`);
console.log(`DEBUG_CALLBACKS length: ${DEBUG_CALLBACKS.length}`);
// Get vector store (get docs, create embeddings, insert docs)
const store = await getExistingStore(
embeddingClient,
dbConfig);
const query = process.env.QUERY || "quintessential lodging near running trails, eateries, retail";
const nearestNeighbors = parseInt(process.env.NEAREST_NEIGHBORS || '5', 10);
//Run planner agent
const hotelContext = await runPlannerAgent(plannerClient, embeddingClient, query, store, nearestNeighbors);
if (process.env.DEBUG === 'true') console.log(hotelContext);
//Run synth agent
const finalAnswer = await runSynthesizerAgent(synthClient, query, hotelContext);
// Get final recommendation (data + AI)
console.log('\n--- FINAL ANSWER ---');
console.log(finalAnswer);
Planlama ve sentezleme için Node.js Aracıları
Kaynak dosya, src/agent.ts otel arama isteklerini işlemek için birlikte çalışan planlayıcı ve sentezleyici aracılarını uygular.
Planner aracısı
Planner aracısı, otel aramasını belirleyen karar alıcıdır .
Planlayıcı aracısı kullanıcının doğal dil sorgusunu alır ve LangChain'in aracı çerçevesini ve kullanabileceği kullanılabilir araçları kullanarak yapay zeka modeline gönderir. Yapay zeka, vektör arama aracını çağırmaya karar verir ve arama parametreleri sağlar. LangChain araç yürütmeyi otomatik olarak yönetir ve eşleşen otelleri döndürür. Yapay zeka, arama mantığını sabit kodlamak yerine kullanıcının ne istediğini yorumlar ve nasıl arama yapılacağını seçer ve sistemi farklı sorgu türleri için esnek hale getirir.
async function runPlannerAgent(
plannerClient: any,
embeddingClient: any,
userQuery: string,
store: AzureDocumentDBVectorStore,
nearestNeighbors = 5
): Promise<string> {
console.log('\n--- PLANNER ---');
const userMessage = `Use the "${TOOL_NAME}" tool with nearestNeighbors=${nearestNeighbors} and query="${userQuery}". Do not answer directly; call the tool.`;
const contextSchema = z.object({
store: z.any(),
embeddingClient: z.any()
});
const agent = createAgent({
model: plannerClient,
systemPrompt: PLANNER_SYSTEM_PROMPT,
tools: [getHotelsToMatchSearchQuery],
contextSchema,
});
const agentResult = await agent.invoke(
{ messages: [{ role: 'user', content: userMessage }] },
// @ts-ignore
{ context: { store, embeddingClient }, callbacks: DEBUG_CALLBACKS }
);
const plannerMessages = agentResult.messages || [];
const searchResultsAsText = extractPlannerToolOutput(plannerMessages);
return searchResultsAsText;
}
Sentezleyici ajan
Sentezleyici aracısı, yararlı öneriler oluşturan yazardır .
Sentezleyici aracısı, otel arama sonuçlarıyla birlikte özgün kullanıcı sorgusunu alır. Öneriler yazma yönergeleriyle birlikte her şeyi bir yapay zeka modeline gönderir. Otelleri karşılaştıran ve en iyi seçenekleri açıklayan doğal bir dil yanıtı döndürür. Ham arama sonuçları kullanıcı dostu olmadığından bu yaklaşım önemlidir. Sentezleyici, veritabanı kayıtlarını, belirli otellerin neden kullanıcının ihtiyaçlarına uygun olduğunu açıklayan bir konuşma önerisine dönüştürür.
async function runSynthesizerAgent(synthClient: any, userQuery: string, hotelContext: string): Promise<string> {
console.log('\n--- SYNTHESIZER ---');
let conciseContext = hotelContext;
console.log(`Context size is ${conciseContext.length} characters`);
const agent = createAgent({
model: synthClient,
systemPrompt: SYNTHESIZER_SYSTEM_PROMPT,
});
const agentResult = await agent.invoke({
messages: [{
role: 'user',
content: createSynthesizerUserPrompt(userQuery, conciseContext)
}]
});
const synthMessages = agentResult.messages;
const finalAnswer = synthMessages[synthMessages.length - 1].content;
console.log(`Output: ${finalAnswer.length} characters of final recommendation`);
return finalAnswer as string;
}
Vektör deposu araması için ajan araçları
Kaynak dosya, src/vector-store.ts planlayıcı aracısının kullandığı vektör arama aracını tanımlar.
Araçlar dosyası, yapay zeka aracısının otel bulmak için kullanabileceği bir arama aracısını tanımlar. Bu araç, ajanın veritabanına bağlanma şeklidir. Yapay zeka veritabanında doğrudan arama yapmaz. Arama aracının kullanılmasını ister ve araç gerçek aramayı yürütür.
araç tanımı olarak Node.js İşlevi
LangChain'in tool işlevi normal bir TypeScript işlevinden bir araç oluşturur. Araç tanımı ad, açıklama ve şemayı içerir (doğrulama için Zod kullanılır). Bu tanım, yapay zekanın aracın mevcut olduğunu ve doğru şekilde nasıl kullanılacağını bilmesini sağlar.
export const getHotelsToMatchSearchQuery = tool(
async ({ query, nearestNeighbors }, config): Promise<string> => {
try {
const store = config.context.store as AzureDocumentDBVectorStore;
const embeddingClient = config.context.embeddingClient as AzureOpenAIEmbeddings;
// Create query embedding and perform search
const queryVector = await embeddingClient.embedQuery(query);
const results = await store.similaritySearchVectorWithScore(queryVector, nearestNeighbors);
console.log(`Found ${results.length} documents from vector store`);
// Format results for synthesizer
const formatted = results.map(([doc, score]) => {
const md = doc.metadata as Partial<HotelForVectorStore>;
console.log(`Hotel: ${md.HotelName ?? 'N/A'}, Score: ${score}`);
return formatHotelForSynthesizer(md, score);
}).join('\n\n');
return formatted;
} catch (error) {
console.error('Error in getHotelsToMatchSearchQuery tool:', error);
return 'Error occurred while searching for hotels.';
}
},
{
name: TOOL_NAME,
description: TOOL_DESCRIPTION,
schema: z.object({
query: z.string(),
nearestNeighbors: z.number().optional().default(5),
}),
}
);
Azure DocumentDB vektör araması ile Node.js Aracı yürütme
Yapay zeka aracı çağırdığında işlev gövdesi çalışır. Azure OpenAI'nin ekleme modelini kullanarak metin sorgusunu sayısal vektöre dönüştürerek ekleme oluşturur. Ardından, vektörleri Azure DocumentDB'ye göndererek veritabanında arama yaparak benzer vektörlere sahip ve benzer açıklamalar anlamına gelen oteller bulur. Son olarak, veritabanı kayıtlarını sentezleyici aracısının anlayabileceği okunabilir metne dönüştürerek sonuçları biçimlendirebilir.
Uygulama, Azure DocumentDB ile sorunsuz tümleştirme için LangChain'lerden AzureDocumentDBVectorStore yararlanıyor.
Bu desen neden kullanılır?
Aracı aracıdan ayırmak esneklik sağlar. Yapay zeka ne zaman aranacaklarına ve nelerin aranacaklarına karar verirken, araç da nasıl arama yapılacağını işler. Aracı mantığını değiştirmeden daha fazla araç ekleyebilirsiniz.
Yapay zeka davranışını yönlendirmek için aracı istemler sağlar.
Kaynak dosya, src/utils/prompts.ts aracılar için sistem istemlerini ve araç tanımlarını içerir.
istemler dosyası, hem planlayıcı hem de sentezleyici aracıları için yapay zeka modellerine verilen yönergeleri ve bağlamı tanımlar. Bu istemler yapay zekanın davranışına yol gösterir ve iş akışındaki rolünü anlamasını sağlar.
Yapay zeka yanıtlarının kalitesi, net yönergelere büyük ölçüde bağlıdır. Bu istemler sınırları belirler, çıkış biçimini tanımlar ve yapay zekayı kullanıcının karar verme hedefine odaklar. Aracıların herhangi bir kodu değiştirmeden nasıl davranacağını değiştirmek için bu istemleri özelleştirebilirsiniz.
export const PLANNER_SYSTEM_PROMPT = `You are a hotel search planner. Transform the user's request into a clear, detailed search query for a vector database.
CRITICAL REQUIREMENT: You MUST ALWAYS call the "${TOOL_NAME}" tool. This is MANDATORY for every request.
Use a tool call with:
- query (string)
- nearestNeighbors (number 1-20)
QUERY REFINEMENT RULES:
- If vague (e.g., "nice hotel"), add specific attributes: "hotel with high ratings and good amenities"
- If minimal (e.g., "cheap"), expand: "budget hotel with good value"
- Preserve specific details from user (location, amenities, business/leisure)
- Keep natural language - this is for semantic search
- Don't just echo the input - improve it for better search results
- nearestNeighbors: Use 3-5 for specific requests, 10-15 for broader requests, max 20
EXAMPLES:
User: "cheap hotel" → {"tool": "${TOOL_NAME}", "args": {"query": "budget-friendly hotel with good value and affordable rates", "nearestNeighbors": 10}}
User: "hotel near downtown with parking" → {"tool": "${TOOL_NAME}", "args": {"query": "hotel near downtown with good parking and wifi", "nearestNeighbors": 5}}
User: "nice place to stay" → {"tool": "${TOOL_NAME}", "args": {"query": "hotel with high ratings, good reviews, and quality amenities", "nearestNeighbors": 10}}
Do not answer the user directly. Always call the tool.`;
// ============================================================================
// Synthesizer Prompts
// ============================================================================
export const SYNTHESIZER_SYSTEM_PROMPT = `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.`;
Node.js ile verileri hazırlama ve Azure DocumentDB'ye yükleme
Örnek, bir JSON dosyasındaki otel verilerini kullanır. Depo iki sürüm içerir:
-
Hotels.json- Vektör eklemeleri olmadan otel verileri (bu örnek tarafından kullanılır) -
Hotels_Vector.json- Önceden hesaplanan eklemeler içeren otel verileri (diğer örnekler tarafından kullanılır)
Karşıya yükleme nasıl çalışır?
Betik upload-documents.ts üç adım gerçekleştirir:
-
Veri yükleme — Dosyadan
Hotels.jsonotel kayıtlarını okur. -
Gömü oluşturma — Betik, her otel için alanı Azure OpenAI
Descriptionmodeline göndererektext-embedding-3-small1536 boyutlu bir vektör gömü oluşturur. Bu, metin açıklamasını anlamsal anlamını yakalayan sayısal bir gösterime dönüştürür. - Ekleme ve dizin — Betik, belgeleri (eklemeleriyle birlikte) Azure DocumentDB koleksiyonuna ekler ve yapılandırılmış algoritmayı (IVF, HNSW veya DiskANN) kullanarak bir vektör dizini oluşturur.
import { createClientsPasswordless, createClients } from './utils/clients.js';
import { getStore } from './vector-store.js';
/**
* Upload documents to Azure DocumentDB MongoDB Vector Store
*/
async function uploadDocuments() {
try {
console.log('Starting document upload...\n');
// Get clients based on authentication mode
const usePasswordless = process.env.USE_PASSWORDLESS === 'true' || process.env.USE_PASSWORDLESS === '1';
console.log(`Authentication mode: ${usePasswordless ? 'Passwordless (Azure AD)' : 'API Key'}`);
console.log('\nEnvironment variables check:');
console.log(` DATA_FILE_WITHOUT_VECTORS: ${process.env.DATA_FILE_WITHOUT_VECTORS}`);
console.log(` AZURE_DOCUMENTDB_DATABASENAME: ${process.env.AZURE_DOCUMENTDB_DATABASENAME}`);
console.log(` AZURE_DOCUMENTDB_COLLECTION: ${process.env.AZURE_DOCUMENTDB_COLLECTION}`);
console.log(` AZURE_DOCUMENTDB_CLUSTER: ${process.env.AZURE_DOCUMENTDB_CLUSTER}`);
console.log(` AZURE_OPENAI_EMBEDDING_MODEL: ${process.env.AZURE_OPENAI_EMBEDDING_MODEL}`);
const requiredEnvVars = [
'DATA_FILE_WITHOUT_VECTORS',
'AZURE_DOCUMENTDB_DATABASENAME',
'AZURE_DOCUMENTDB_COLLECTION',
'AZURE_DOCUMENTDB_CLUSTER',
'AZURE_OPENAI_EMBEDDING_MODEL',
];
const missingEnvVars = requiredEnvVars.filter((name) => {
const value = process.env[name];
return !value || value.trim().length === 0;
});
if (missingEnvVars.length > 0) {
throw new Error(`Missing required environment variables: ${missingEnvVars.join(', ')}`);
}
const clients = usePasswordless ? createClientsPasswordless() : createClients();
const { embeddingClient, dbConfig } = clients;
console.log('\ndbConfig properties:');
console.log(` instance: ${dbConfig.instance}`);
console.log(` databaseName: ${dbConfig.databaseName}`);
console.log(` collectionName: ${dbConfig.collectionName}`);
// Check for data file path
const dataFilePath = process.env.DATA_FILE_WITHOUT_VECTORS!;
console.log(`\nReading data from: ${dataFilePath}`);
console.log(`Database: ${dbConfig.databaseName}`);
console.log(`Collection: ${dbConfig.collectionName}`);
console.log(`Vector algorithm: ${process.env.VECTOR_INDEX_ALGORITHM || 'vector-ivf'}\n`);
// Upload documents using existing getStore function
const startTime = Date.now();
const store = await getStore(dataFilePath, embeddingClient, dbConfig);
const duration = ((Date.now() - startTime) / 1000).toFixed(2);
console.log(`\n✓ Upload completed in ${duration} seconds`);
// Close connection
await store.close();
console.log('✓ Connection closed');
// Force exit to ensure process terminates (Azure credential timers may still be active)
process.exit(0);
} catch (error: any) {
console.error('\n✗ Upload failed:', error?.message || error);
console.error('\nFull error:', error);
process.exit(1);
}
}
// Run the upload
uploadDocuments();
Vektör dizini oluşturma
Vektör dizini, hızlı benzerlik aramasını sağlayan dizindir. Dizin oluşturulduğunda, Azure DocumentDB ekleme vektörlerini düzenler, böylece "bu açıklamaya benzer otelleri bul" gibi sorguların her belge taranmadan verimli bir şekilde yanıtlanması sağlanır.
Seçtiğiniz dizin türü performansı etkiler:
| Algoritma | Küme katmanı | En iyi kullanım alanı: |
|---|---|---|
| IVF | M10+ | Küçük ve orta ölçekli veri kümeleri, daha düşük maliyet |
| HNSW | M30+ | Yüksek geri çağırma, hızlı sorgular |
| DiskANN | M40+ | Büyük ölçekli veri kümeleri, milyardan fazla vektör |
import {
AzureDocumentDBVectorStore,
AzureDocumentDBSimilarityType,
AzureDocumentDBConfig
} from "@langchain/azure-cosmosdb";
import type { AzureOpenAIEmbeddings } from "@langchain/openai";
import { readFileSync } from 'fs';
import { Document } from '@langchain/core/documents';
import { HotelsData, Hotel } from './utils/types.js';
import { TOOL_NAME, TOOL_DESCRIPTION } from './utils/prompts.js';
import { z } from 'zod';
import { tool } from "langchain";
import { MongoClient } from 'mongodb';
import { BaseMessage } from "@langchain/core/messages";
type HotelForVectorStore = Omit<Hotel, 'Description_fr' | 'Location' | 'Rooms'>;
// Helper function for similarity type
function getSimilarityType(similarity: string) {
switch (similarity.toUpperCase()) {
case 'COS': return AzureDocumentDBSimilarityType.COS;
case 'L2': return AzureDocumentDBSimilarityType.L2;
case 'IP': return AzureDocumentDBSimilarityType.IP;
default: return AzureDocumentDBSimilarityType.COS;
}
}
// Consolidated vector index configuration
function getVectorIndexOptions() {
const algorithm = process.env.VECTOR_INDEX_ALGORITHM || 'vector-ivf';
const dimensions = parseInt(process.env.EMBEDDING_DIMENSIONS || '1536');
const similarity = getSimilarityType(process.env.VECTOR_SIMILARITY || 'COS');
const baseOptions = { dimensions, similarity };
switch (algorithm) {
case 'vector-hnsw':
return {
kind: 'vector-hnsw' as const,
m: parseInt(process.env.HNSW_M || '16'),
efConstruction: parseInt(process.env.HNSW_EF_CONSTRUCTION || '64'),
...baseOptions
};
case 'vector-diskann':
return {
kind: 'vector-diskann' as const,
...baseOptions
};
case 'vector-ivf':
default:
aracılı RAG uygulamasını Node.js ile çalıştırma
Bağımlılıkları yükleyin:
npm installAjanı çalıştırmadan önce gömülü verilerle otel verilerini karşıya yükleyin.
upload-documents.tskomutu, JSON dosyasından otelleri yükler, kullanaraktext-embedding-3-smallher otel için eklemeler oluşturur, Belgeleri Azure DocumentDB'ye ekler ve bir vektör dizini oluşturur.npm run uploadkomutunu kullanarak otel öneri aracısını
agent.tsçalıştırın. Ajan, planlayıcı ajanı, vektör araması ve sentezleyici ajanı çağırır. Çıkış benzerlik puanlarını ve sentezleyici aracının önerilerle karşılaştırmalı analizini içerir.npm startDEBUG mode is OFF DEBUG_CALLBACKS length: 0 Connected to existing vector store: Hotels.hotel_data --- PLANNER --- Found 5 documents from vector store Hotel: Nordick's Valley Motel, Score: 0.49866509437561035 Hotel: White Mountain Lodge & Suites, Score: 0.48731985688209534 Hotel: Trails End Motel, Score: 0.47985398769378662 Hotel: Country Comfort Inn, Score: 0.47431993484497070 Hotel: Lakefront Captain Inn, Score: 0.45787304639816284 --- SYNTHESIZER --- Context size is 3233 characters Output: 812 characters of final recommendation --- 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.
Visual Studio Code'da verileri görüntüleme ve yönetme
Azure DocumentDB hesabınıza bağlanmak için Visual Studio Code'da DocumentDB uzantısını seçin.
Hotels veritabanındaki verileri ve dizinleri görüntüleyin.
Kaynakları temizle
Kaynakları sağlamak için kullandıysanız azd up , tüm Azure kaynaklarını şu şekilde kaldırabilirsiniz:
azd down
Kaynakları el ile oluşturduysanız ve tüm kaynakları kaldırmak istiyorsanız, ek maliyetlerden kaçınmak için kaynak grubunu silin.
Kaynakları yeniden kullanmak istiyorsanız, işiniz bittiğinde test veritabanını silmek için temizleme komutunu kullanın. Aşağıdaki komutu çalıştırın:
npm run cleanup