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.
Ebben az oktatóanyagban LangChain.js használ egy LangChain.js ügynököt, amely lehetővé teszi a NorthWind vállalat alkalmazottai számára, hogy emberi erőforrásokkal kapcsolatos kérdéseket tegyenek fel. A keretrendszer használatával elkerülheti a LangChain.js ügynökökhöz és az Azure-szolgáltatások integrációjához általában szükséges sablonkódot, így az üzleti igényekre összpontosíthat.
Ebben az útmutatóban Ön:
- LangChain.js-ügynök beállítása
- Azure-erőforrások integrálása az LangChain.js-ügynökbe
- Igény szerint tesztelje LangChain.js ügynökét a LangSmith Studióban
A NorthWind két adatforrásra támaszkodik: az összes alkalmazott számára elérhető nyilvános HR-dokumentációra és egy bizalmas alkalmazottak adatait tartalmazó bizalmas HR-adatbázisra. Ez az oktatóanyag egy LangChain.js ügynök létrehozására összpontosít, amely meghatározza, hogy egy alkalmazott kérdése megválaszolható-e a nyilvános HR-dokumentumok használatával. Ha igen, a LangChain.js ügynök közvetlenül adja meg a választ.
Figyelmeztetés
Ez a cikk kulcsokat használ az erőforrások eléréséhez. Éles környezetben a javasolt legjobb gyakorlat az Azure RBAC és a felügyelt identitás használata. Ez a megközelítés szükségtelenné teszi a kulcsok kezelését vagy elforgatását, a biztonság növelését és a hozzáférés-vezérlés egyszerűsítését.
Előfeltételek
- Aktív Azure-fiók. Ha nincs fiókja, hozzon létre ingyenes fiókot .
- Telepítve van a rendszerén a Node.js LTS.
- TypeScript TypeScript-kód írásához és fordításához.
- LangChain.js könyvtár az ügynök felépítéséhez.
- Nem kötelező: LangSmith az AI-használat monitorozásához. Szüksége van a projekt nevére, kulcsára és végpontjára.
- Nem kötelező: LangGraph Studio a LangGraph-láncok és LangChain.js ügynökök hibakereséséhez.
- Azure AI Search-erőforrás: Győződjön meg arról, hogy rendelkezik az erőforrásvégpont, a rendszergazdai kulccsal (a dokumentum beszúrásához), a lekérdezési kulccsal (a dokumentumok olvasásához) és az index nevével.
-
Azure OpenAI-erőforrás: Szüksége lesz az erőforráspéldány nevére, kulcsára és két modellre az API-verziókkal:
- Egy beágyazási modell, például
text-embedding-ada-002
. - Egy nagy nyelvi modell, például
gpt-4o
.
- Egy beágyazási modell, például
Ügynökarchitektúra
A LangChain.js keretrendszer döntési folyamatot biztosít az intelligens ügynökök LangGraphként való létrehozásához. Ebben az oktatóanyagban egy LangChain.js ügynököt hoz létre, amely integrálható az Azure AI Search és az Azure OpenAI szolgáltatással a HR-sel kapcsolatos kérdések megválaszolásához. Az ügynök architektúrája a következőkre lett tervezve:
- Állapítsa meg, hogy egy kérdés releváns-e a HR-dokumentáció szempontjából.
- A vonatkozó dokumentumok lekérése az Azure AI Search szolgáltatásból.
- Az Azure OpenAI használatával választ hozhat létre a lekért dokumentumok és az LLM-modell alapján.
Fő összetevők:
Gráfstruktúra: A LangChain.js ügynök gráfként jelenik meg, ahol:
- A csomópontok konkrét feladatokat hajtanak végre, például döntéshozatalt vagy adatok beolvasását.
- Az élek határozzák meg a csomópontok közötti folyamatot, meghatározva a műveletek sorrendjét.
Azure AI Search-integráció:
- Beágyazásként HR-dokumentumokat szúr be a vektortárolóba.
- Beágyazási modell (
text-embedding-ada-002
) használatával hozza létre ezeket a beágyazásokat. - A vonatkozó dokumentumokat a felhasználói kérés alapján kéri le.
Azure OpenAI-integráció:
- Nagy nyelvi modellt (
gpt-4o
) használ a következő célokra:- Meghatározza, hogy egy kérdés megválaszolható-e az általános HR-dokumentumokból.
- A dokumentumokból és a felhasználói kérdésekből származó környezet használatával válasz generál.
- Nagy nyelvi modellt (
Az alábbi táblázat olyan felhasználói kérdésekre mutat be példákat, amelyek általános emberierőforrás-dokumentumokból nem relevánsak és megválaszolhatók:
Kérdés | A HR-dokumentumok relevanciája |
---|---|
Does the NorthWind Health Plus plan cover eye exams? |
Idevágó. A HR-dokumentumoknak, például az alkalmazotti kézikönyvnek választ kell adniuk. |
How much of my perks + benefits have I spent? |
Nem releváns. Ehhez a kérdéshez hozzá kell férni a bizalmas alkalmazottak adataihoz, amelyek nem tartoznak az ügynök hatókörébe. |
A keretrendszer használatával elkerülheti a LangChain.js ügynökökhöz és az Azure-szolgáltatások integrációjához általában szükséges sablonkódot, így az üzleti igényekre összpontosíthat.
A Node.js projekt inicializálása
Inicializálja a TypeScript-ügynökhöz tartozó Node.js projektet egy új könyvtárban. Futtassa az alábbi parancsot:
npm init -y
npm pkg set type=module
npx tsc --init
Környezeti fájl létrehozása
Hozzon létre egy .env
fájlt a helyi fejlesztéshez az Azure-erőforrások és a LangGraph környezeti változóinak tárolásához. Győződjön meg arról, hogy a beágyazás és az LLM erőforráspéldányának neve csak az erőforrás neve legyen, nem pedig a végpont.
Nem kötelező: Ha a LangSmith-et használja, állítsa a LANGSMITH_TRACING
értéket true
-re a helyi fejlesztéshez. Tiltsa le (false
) vagy távolítsa el a termelési környezetben.
Függőségek telepítése
Azure-függőségek telepítése az Azure AI Search szolgáltatáshoz:
npm install @azure/search-documents
Ügynök létrehozásához és használatához telepítse LangChain.js függőségeket:
npm install @langchain/community @langchain/core @langchain/langgraph @langchain/openai langchain
Helyi fejlesztéshez szükséges függőségek telepítése.
npm install --save-dev dotenv
Azure AI keresési erőforrás konfigurációs fájljainak létrehozása
Az oktatóanyagban használt különböző Azure-erőforrások és modellek kezeléséhez hozzon létre konkrét konfigurációs fájlokat az egyes erőforrásokhoz. Ez a megközelítés biztosítja az aggodalmak egyértelműségét és elkülönítését, így egyszerűbbé válik a konfigurációk kezelése és karbantartása.
Dokumentumok vektortárolóba való feltöltésének konfigurálása
Az Azure AI Search konfigurációs fájlja a rendszergazdai kulccsal szúr be dokumentumokat a vektortárolóba. Ez a kulcs elengedhetetlen az adatok Azure AI Searchbe való betöltésének kezeléséhez.
const endpoint = process.env.AZURE_AISEARCH_ENDPOINT;
const adminKey = process.env.AZURE_AISEARCH_ADMIN_KEY;
const indexName = process.env.AZURE_AISEARCH_INDEX_NAME;
export const VECTOR_STORE_ADMIN = {
endpoint,
key: adminKey,
indexName,
};
LangChain.js absztrakciót végez az azure AI Searchbe történő adatbetöltés sémájának definiálására, amely a legtöbb forgatókönyvhöz megfelelő alapértelmezett sémát biztosít. Ez az absztrakció leegyszerűsíti a folyamatot, és csökkenti az egyéni sémadefiníciók szükségességét.
Konfiguráció a vektortároló lekérdezéséhez
A vektortároló lekérdezéséhez hozzon létre egy külön konfigurációs fájlt:
import {
AzureAISearchConfig,
AzureAISearchQueryType,
} from "@langchain/community/vectorstores/azure_aisearch";
const endpoint = process.env.AZURE_AISEARCH_ENDPOINT;
const queryKey = process.env.AZURE_AISEARCH_QUERY_KEY;
const indexName = process.env.AZURE_AISEARCH_INDEX_NAME;
export const DOC_COUNT = 3;
export const VECTOR_STORE_QUERY: AzureAISearchConfig = {
endpoint,
key: queryKey,
indexName,
search: {
type: AzureAISearchQueryType.Similarity,
},
};
A vektortároló lekérdezéséhez használja inkább a lekérdezési kulcsot. A kulcsok elkülönítése biztonságos és hatékony hozzáférést biztosít az erőforráshoz.
Azure OpenAI-erőforráskonfigurációs fájlok létrehozása
A két különböző modell, a beágyazások és az LLM kezeléséhez hozzon létre külön konfigurációs fájlokat. Ez a megközelítés biztosítja az aggodalmak egyértelműségét és elkülönítését, így egyszerűbbé válik a konfigurációk kezelése és karbantartása.
A vektortároló beágyazásának konfigurálása
Ha beágyazásokat szeretne létrehozni a dokumentumok Azure AI Search-vektortárolóba való beszúrásához, hozzon létre egy konfigurációs fájlt:
const key = process.env.AZURE_OPENAI_EMBEDDING_KEY;
const instance = process.env.AZURE_OPENAI_EMBEDDING_INSTANCE;
const apiVersion =
process.env.AZURE_OPENAI_EMBEDDING_API_VERSION || "2023-05-15";
const model =
process.env.AZURE_OPENAI_EMBEDDING_MODEL || "text-embedding-ada-002";
export const EMBEDDINGS_CONFIG = {
azureOpenAIApiKey: key,
azureOpenAIApiInstanceName: instance,
azureOpenAIApiEmbeddingsDeploymentName: model,
azureOpenAIApiVersion: apiVersion,
maxRetries: 1,
};
Az LLM konfigurálása válaszok létrehozásához
Ha a nagy nyelvi modellből szeretne válaszokat létrehozni, hozzon létre egy konfigurációs fájlt:
const key = process.env.AZURE_OPENAI_COMPLETE_KEY;
const instance = process.env.AZURE_OPENAI_COMPLETE_INSTANCE;
const apiVersion =
process.env.AZURE_OPENAI_COMPLETE_API_VERSION || "2024-10-21";
const model = process.env.AZURE_OPENAI_COMPLETE_MODEL || "gpt-4o";
const maxTokens = process.env.AZURE_OPENAI_COMPLETE_MAX_TOKENS;
export const LLM_CONFIG = {
model,
azureOpenAIApiKey: key,
azureOpenAIApiInstanceName: instance,
azureOpenAIApiDeploymentName: model,
azureOpenAIApiVersion: apiVersion,
maxTokens: maxTokens ? parseInt(maxTokens, 10) : 100,
maxRetries: 1,
timeout: 60000,
};
Állandók és utasítások
Az AI-alkalmazások gyakran állandó sztringekre és kérésekre támaszkodnak. Ezeket az állandókat külön fájlokkal kezelheti.
Hozza létre a rendszerutasítást.
export const SYSTEM_PROMPT = `Answer the query with a complete paragraph based on the following context:`;
Hozza létre a csomópontok állandóit:
export const ANSWER_NODE = "vector_store_retrieval";
export const DECISION_NODE = "requires_hr_documents";
export const START = "__start__";
export const END = "__end__";
Példa felhasználói lekérdezések létrehozása:
export const USER_QUERIES = [
"Does the NorthWind Health plus plan cover eye exams?",
"What is included in the NorthWind Health plus plan that is not included in the standard?",
"What happens in a performance review?",
];
Dokumentumok betöltése az Azure AI Searchbe
A dokumentumok Azure AI Searchbe való betöltéséhez a LangChain.js használatával egyszerűsítheti a folyamatot. A PDF-fájlként tárolt dokumentumok beágyazásokká alakulnak, és beszúródnak a vektortárolóba. Ez a folyamat biztosítja, hogy a dokumentumok készen állnak a hatékony lekérésre és lekérdezésre.
Fő szempontok:
- LangChain.js absztrakció: LangChain.js kezeli az összetettség nagy részét, például a sémadefiníciókat és az ügyféllétrehozást, így a folyamat egyszerűvé válik.
- Szabályozás és újrapróbálkozási logika: Bár a mintakód minimális várakozási függvényt tartalmaz, az éles alkalmazásoknak átfogó hibakezelési és újrapróbálkozási logikát kell alkalmazniuk a szabályozás és az átmeneti hibák kezeléséhez.
Dokumentumok betöltésének lépései
Keresse meg a PDF-dokumentumokat: A dokumentumok az adatkönyvtárban vannak tárolva.
PDF-fájlok betöltése a LangChain.js: Használja a
loadPdfsFromDirectory
funkciót a dokumentumok betöltéséhez. Ez a függvény a LangChain.js közösség metódusátPDFLoader.load
használja az egyes fájlok beolvasására és tömbökDocument[]
visszaadására. Ez a tömb egy szabványos LangChain.js dokumentumformátum.import { PDFLoader } from "@langchain/community/document_loaders/fs/pdf"; import { waiter } from "../utils/waiter.js"; import { loadDocsIntoAiSearchVector } from "./load_vector_store.js"; import fs from "fs/promises"; import path from "path"; export async function loadPdfsFromDirectory( embeddings: any, dirPath: string, ): Promise<void> { try { const files = await fs.readdir(dirPath); console.log( `PDF: Loading directory ${dirPath}, ${files.length} files found`, ); for (const file of files) { if (file.toLowerCase().endsWith(".pdf")) { const fullPath = path.join(dirPath, file); console.log(`PDF: Found ${fullPath}`); const pdfLoader = new PDFLoader(fullPath); console.log(`PDF: Loading ${fullPath}`); const docs = await pdfLoader.load(); console.log(`PDF: Sending ${fullPath} to index`); const storeResult = await loadDocsIntoAiSearchVector(embeddings, docs); console.log(`PDF: Indexing result: ${JSON.stringify(storeResult)}`); await waiter(1000 * 60); // waits for 1 minute between files } } } catch (err) { console.error("Error loading PDFs:", err); } }
Dokumentumok beszúrása az
loadDocsIntoAiSearchVector
: A függvény használatával küldje el a dokumentumtömböt az Azure AI Search vektortárolójába. Ez a függvény a beágyazások ügyfelével dolgozza fel a dokumentumokat, és egy egyszerű várakozási függvényt tartalmaz az adatfolyam korlátozás kezelésére. Implementáljon egy robusztus újrapróbálkozási/hátratolt mechanizmust.import { AzureAISearchVectorStore } from "@langchain/community/vectorstores/azure_aisearch"; import type { Document } from "@langchain/core/documents"; import type { EmbeddingsInterface } from "@langchain/core/embeddings"; import { VECTOR_STORE_ADMIN } from "../config/vector_store_admin.js"; export async function loadDocsIntoAiSearchVector( embeddings: EmbeddingsInterface, documents: Document[], ): Promise<AzureAISearchVectorStore> { const vectorStore = await AzureAISearchVectorStore.fromDocuments( documents, embeddings, VECTOR_STORE_ADMIN, ); return vectorStore; }
Ügynök munkafolyamatának létrehozása
A LangChain.js-ban építsd meg a LangChain.js ügynököt egy LangGraph használatával. A LangGraph lehetővé teszi a csomópontok és élek meghatározását:
- Csomópont: ahol a munka történik.
- Edge: a csomópontok közötti kapcsolatot határozza meg.
Munkafolyamat-összetevők
Ebben az alkalmazásban a két munkacsomópont a következő:
- requiresHrResources: meghatározza, hogy a kérdés releváns-e az Azure OpenAI LLM használatával végzett HR-dokumentáció szempontjából.
- getAnswer: lekéri a választ. A válasz egy LangChain.js retriever-láncból származik, amely az Azure AI Search dokumentumbeágyazását használja, és elküldi őket az Azure OpenAI LLM-nek. Ez a visszakereséssel bővített generáció lényege.
Az élek határozzák meg a getAnswer csomópont meghívásához szükséges kezdő, záró és feltételt.
A gráf exportálása
Ha a LangGraph Studiót szeretné használni a gráf futtatására és hibakeresésére, exportálja azt saját objektumként.
import { StateGraph } from "@langchain/langgraph";
import { StateAnnotation } from "./langchain/state.js";
import { route as endRoute } from "./langchain/check_route_end.js";
import { getAnswer } from "./azure/get_answer.js";
import { START, ANSWER_NODE, DECISION_NODE } from "./config/nodes.js";
import {
requiresHrResources,
routeRequiresHrResources,
} from "./azure/requires_hr_documents.js";
const builder = new StateGraph(StateAnnotation)
.addNode(DECISION_NODE, requiresHrResources)
.addNode(ANSWER_NODE, getAnswer)
.addEdge(START, DECISION_NODE)
.addConditionalEdges(DECISION_NODE, routeRequiresHrResources)
.addConditionalEdges(ANSWER_NODE, endRoute);
export const hr_documents_answer_graph = builder.compile();
hr_documents_answer_graph.name = "Azure AI Search + Azure OpenAI";
Az addNode, addEdge és addConditionalEdges metódusokban az első paraméter egy név, sztringként, amely azonosítja az objektumot a gráfon belül. A második paraméter vagy az a függvény, amelyet az adott lépésben meg kell hívni, vagy a meghívni kívánt csomópont neve.
Az addEdge metódus esetében a neve START ("start" a ./src/config/nodes.ts fájlban definiálva), és mindig meghívja a DECISION_NODE. Ez a csomópont két paraméterrel van definiálva: az első a neve, DECISION_NODE, a második pedig a requiresHrResources nevű függvény.
Gyakori funkciók
Ez az alkalmazás általános LangChain-funkciókat biztosít:
Állapotkezelés:
import { BaseMessage, BaseMessageLike } from "@langchain/core/messages"; import { Annotation, messagesStateReducer } from "@langchain/langgraph"; export const StateAnnotation = Annotation.Root({ messages: Annotation<BaseMessage[], BaseMessageLike[]>({ reducer: messagesStateReducer, default: () => [], }), });
Útvonalvégzítés:
import { StateAnnotation } from "./state.js"; import { END, ANSWER_NODE } from "../config/nodes.js"; export const route = ( state: typeof StateAnnotation.State, ): typeof END | typeof ANSWER_NODE => { if (state.messages.length > 0) { return END; } return ANSWER_NODE; };
Az alkalmazás egyetlen egyéni útvonala a routeRequiresHrResources. Ezzel az útvonalsal állapítható meg, hogy a requiresHrResources csomópont válasza azt jelzi-e, hogy a felhasználó kérdésének tovább kell-e folytatódnia a ANSWER_NODE csomóponton. Mivel ez az útvonal a requiresHrResources kimenetét kapja, ugyanabban a fájlban található.
Azure OpenAI-erőforrások integrálása
Az Azure OpenAI-integráció két különböző modellt használ:
- Beágyazások: A dokumentumok vektortárolóba való beszúrására szolgál.
- LLM: A vektortároló lekérdezésével és a válaszok generálásával válaszol a kérdésekre.
A beágyazási ügyfél és az LLM-ügyfél különböző célokat szolgálnak. Ne csökkentse őket egyetlen modellre vagy ügyfélre.
Beágyazási modell
A beágyazási ügyfélre minden alkalommal szükség van, amikor dokumentumokat kér le a vektortárolóból. A maxRetries konfigurációját tartalmazza az átmeneti hibák kezeléséhez.
import { AzureOpenAIEmbeddings } from "@langchain/openai";
import { EMBEDDINGS_CONFIG } from "../config/embeddings.js";
export function getEmbeddingClient(): AzureOpenAIEmbeddings {
return new AzureOpenAIEmbeddings({ ...EMBEDDINGS_CONFIG, maxRetries: 1 });
}
LLM-modell
Az LLM-modell kétféle kérdésre ad választ:
- A HR-hez kapcsolódó relevancia: Meghatározza, hogy a felhasználó kérdése releváns-e a HR-dokumentáció szempontjából.
- Válaszgenerálás: Választ ad a felhasználó kérdésére, kiegészítve az Azure AI Search dokumentumaival.
A rendszer létrehozza és meghívja az LLM-ügyfelet, amikor válaszra van szükség.
import { RunnableConfig } from "@langchain/core/runnables";
import { StateAnnotation } from "../langchain/state.js";
import { AzureChatOpenAI } from "@langchain/openai";
import { LLM_CONFIG } from "../config/llm.js";
export const getLlmChatClient = (): AzureChatOpenAI => {
return new AzureChatOpenAI({
...LLM_CONFIG,
temperature: 0,
});
};
export const callChatCompletionModel = async (
state: typeof StateAnnotation.State,
_config: RunnableConfig,
): Promise<typeof StateAnnotation.Update> => {
const llm = new AzureChatOpenAI({
...LLM_CONFIG,
temperature: 0,
});
const completion = await llm.invoke(state.messages);
completion;
return {
messages: [
...state.messages,
{
role: "assistant",
content: completion.content,
},
],
};
};
A LangChain.js ügynök az LLM használatával dönti el, hogy a kérdés releváns-e a HR-dokumentáció szempontjából, vagy a munkafolyamatnak a gráf végéhez kell-e irányítania.
// @ts-nocheck
import { getLlmChatClient } from "./llm.js";
import { StateAnnotation } from "../langchain/state.js";
import { RunnableConfig } from "@langchain/core/runnables";
import { BaseMessage } from "@langchain/core/messages";
import { ANSWER_NODE, END } from "../config/nodes.js";
const PDF_DOCS_REQUIRED = "Answer requires HR PDF docs.";
export async function requiresHrResources(
state: typeof StateAnnotation.State,
_config: RunnableConfig,
): Promise<typeof StateAnnotation.Update> {
const lastUserMessage: BaseMessage = [...state.messages].reverse()[0];
let pdfDocsRequired = false;
if (lastUserMessage && typeof lastUserMessage.content === "string") {
const question = `Does the following question require general company policy information that could be found in HR documents like employee handbooks, benefits overviews, or company-wide policies, then answer yes. Answer no if this requires personal employee-specific information that would require access to an individual's private data, employment records, or personalized benefits details: '${lastUserMessage.content}'. Answer with only "yes" or "no".`;
const llm = getLlmChatClient();
const response = await llm.invoke(question);
const answer = response.content.toLocaleLowerCase().trim();
console.log(`LLM question (is HR PDF documents required): ${question}`);
console.log(`LLM answer (is HR PDF documents required): ${answer}`);
pdfDocsRequired = answer === "yes";
}
// If HR documents (aka vector store) are required, append an assistant message to signal this.
if (!pdfDocsRequired) {
const updatedState = {
messages: [
...state.messages,
{
role: "assistant",
content:
"Not a question for our HR PDF resources. This requires data specific to the asker.",
},
],
};
return updatedState;
} else {
const updatedState = {
messages: [
...state.messages,
{
role: "assistant",
content: `${PDF_DOCS_REQUIRED} You asked: ${lastUserMessage.content}. Let me check.`,
},
],
};
return updatedState;
}
}
export const routeRequiresHrResources = (
state: typeof StateAnnotation.State,
): typeof END | typeof ANSWER_NODE => {
const lastMessage: BaseMessage = [...state.messages].reverse()[0];
if (lastMessage && !lastMessage.content.includes(PDF_DOCS_REQUIRED)) {
console.log("go to end");
return END;
}
console.log("go to llm");
return ANSWER_NODE;
};
A requiresHrResources függvény egy frissített állapotban lévő üzenetet állít be tartalommal HR resources required detected
. A routeRequiresHrResources útválasztó ezt a tartalmat keresi annak meghatározásához, hogy hová küldje az üzeneteket.
Az Azure AI Search-erőforrás integrálása vektortárolóhoz
Az Azure AI Search integrációja biztosítja a vektortár dokumentumait, hogy az LLM bővítse a getAnswer csomópont válaszát. LangChain.js ismét biztosítja az absztrakció nagy részét, így a szükséges kód minimális. A függvények a következők:
- getReadOnlyVectorStore: Lekéri a klienst a lekérdezési kulcs alapján.
- getDocsFromVectorStore: Megkeresi a felhasználó kérdésére vonatkozó dokumentumokat.
import { AzureAISearchVectorStore } from "@langchain/community/vectorstores/azure_aisearch";
import { VECTOR_STORE_QUERY, DOC_COUNT } from "../config/vector_store_query.js";
import { getEmbeddingClient } from "./embeddings.js";
export function getReadOnlyVectorStore(): AzureAISearchVectorStore {
const embeddings = getEmbeddingClient();
return new AzureAISearchVectorStore(embeddings, VECTOR_STORE_QUERY);
}
export async function getDocsFromVectorStore(
query: string,
): Promise<Document[]> {
const store = getReadOnlyVectorStore();
// @ts-ignore
//return store.similaritySearchWithScore(query, DOC_COUNT);
return store.similaritySearch(query, DOC_COUNT);
}
A LangChain.js integrációs kód rendkívül egyszerűvé teszi a releváns dokumentumok beolvasását a vektortárolóból.
Írj kódot, hogy válaszokat kapj az LLM-től
Most, hogy elkészültek az integrációs összetevők, hozza létre a getAnswer függvényt a releváns vektortár-dokumentumok lekéréséhez, és hozzon létre egy választ az LLM használatával.
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { createStuffDocumentsChain } from "langchain/chains/combine_documents";
import { createRetrievalChain } from "langchain/chains/retrieval";
import { getLlmChatClient } from "./llm.js";
import { StateAnnotation } from "../langchain/state.js";
import { AIMessage } from "@langchain/core/messages";
import { getReadOnlyVectorStore } from "./vector_store.js";
const EMPTY_STATE = { messages: [] };
export async function getAnswer(
state: typeof StateAnnotation.State = EMPTY_STATE,
): Promise<typeof StateAnnotation.Update> {
const vectorStore = getReadOnlyVectorStore();
// Extract the last user message's content from the state as input
const lastMessage = state.messages[state.messages.length - 1];
const userInput =
lastMessage && typeof lastMessage.content === "string"
? lastMessage.content
: "";
const questionAnsweringPrompt = ChatPromptTemplate.fromMessages([
[
"system",
"Answer the user's questions based on the below context:\n\n{context}",
],
["human", "{input}"],
]);
const combineDocsChain = await createStuffDocumentsChain({
llm: getLlmChatClient(),
prompt: questionAnsweringPrompt,
});
const retrievalChain = await createRetrievalChain({
retriever: vectorStore.asRetriever(2),
combineDocsChain,
});
const result = await retrievalChain.invoke({ input: userInput });
const assistantMessage = new AIMessage(result.answer);
return {
messages: [...state.messages, assistantMessage],
};
}
Ez a függvény két helyőrzőt tartalmaz: egyet a felhasználó kérdéséhez, egyet pedig a környezethez. A környezet az AI Search vektortárolójának összes releváns dokumentuma. Az LLM-lánc létrehozásához adja át a parancssort és az LLM-ügyfelet a createStuffDocumentsChainnek . Adja át az LLM-láncot a createRetrievalChain függvénynek, hogy olyan láncot hozzon létre, amely tartalmazza a felhívást, a releváns dokumentumokat és az LLM-et.
Futtassa a láncokat a retrievalChain.invoke használatával, és adja meg a felhasználó kérdését bemenetként a válasz megszerzéséhez. Adja vissza a választ az üzenetek állapotában.
Az ügynökcsomag létrehozása
Adjon egy scriptet a package.json helyhez a TypeScript-alkalmazás felépítéséhez:
"build": "tsc",
Hozza létre a LangChain.js ügynököt.
npm run build
Opcionális – futtassa a LangChain.js ügynököt helyi fejlesztési környezetben LangChain Studioval
Helyi fejlesztéshez használhatja a LangChain Studiót a LangChain.js-ügynökkel való együttműködéshez.
Hozzon létre egy
langgraph.json
fájlt a gráf definiálásához.{ "dependencies": [], "graphs": { "agent": "./src/graph.ts:hr_documents_answer_graph" }, "env": "../.env" }
Telepítse a LangGraph parancssori felületet.
npm install @langchain/langgraph-cli --save-dev
Hozzon létre egy szkriptet package.json a
.env
fájl LangGraph parancssori felületre való továbbításához."studio": "npx @langchain/langgraph-cli dev",
A parancssori felület a terminálon fut, és megnyit egy böngészőt a LangGraph Studióban.
Welcome to ╦ ┌─┐┌┐┌┌─┐╔═╗┬─┐┌─┐┌─┐┬ ┬ ║ ├─┤││││ ┬║ ╦├┬┘├─┤├─┘├─┤ ╩═╝┴ ┴┘└┘└─┘╚═╝┴└─┴ ┴┴ ┴ ┴.js - 🚀 API: http://localhost:2024 - 🎨 Studio UI: https://smith.langchain.com/studio?baseUrl=http://localhost:2024 This in-memory server is designed for development and testing. For production use, please use LangGraph Cloud. info: ▪ Starting server... info: ▪ Initializing storage... info: ▪ Registering graphs from C:\Users\myusername\azure-typescript-langchainjs\packages\langgraph-agent info: ┏ Registering graph with id 'agent' info: ┗ [1] { graph_id: 'agent' } info: ▪ Starting 10 workers info: ▪ Server running at ::1:2024
Tekintse meg a LangChain.js ügynököt a LangGraph Studióban.
Válassza az + Üzenet lehetőséget egy felhasználói kérdés hozzáadásához, majd válassza a Küldés lehetőséget.
Kérdés A HR-dokumentumok relevanciája Does the NorthWind Health plus plan cover eye exams?
Ez a kérdés a HR szempontjából releváns, és elég általános ahhoz, hogy a HR-dokumentumoknak, például az alkalmazotti kézikönyvnek, a juttatási kézikönyvnek és az alkalmazotti szerepkör-kódtárnak képesnek kell lennie arra, hogy megválaszolja azt. What is included in the NorthWind Health plus plan that is not included in the standard?
Ez a kérdés a HR szempontjából releváns, és elég általános ahhoz, hogy a HR-dokumentumoknak, például az alkalmazotti kézikönyvnek, a juttatási kézikönyvnek és az alkalmazotti szerepkör-kódtárnak képesnek kell lennie arra, hogy megválaszolja azt. How much of my perks + benefit have I spent
Ez a kérdés nem vonatkozik az általános, személytelen HR-dokumentumokra. Ezt a kérdést egy olyan ügynöknek kell elküldeni, aki hozzáfér az alkalmazottak adataihoz. Ha a kérdés a HR-dokumentumok szempontjából releváns, akkor át kell haladnia a DECISION_NODE és a ANSWER_NODE.
Tekintse meg a terminálkimenetet az LLM kérdésének és az LLM válaszának megtekintéséhez.
Ha a kérdés nem releváns a HR-dokumentumok szempontjából, a folyamat közvetlenül a végéhez ér.
Ha az LangChain.js ügynök helytelen döntést hoz, a probléma a következő lehet:
- Használt LLM-modell
- A vektortárolóból származó dokumentumok száma
- A döntési csomópontban használt parancssor.
Az LangChain.js-ügynök futtatása egy alkalmazásból
Ha a LangChain.js-ügynököt egy szülőalkalmazásból, például egy webes API-ból szeretné meghívni, meg kell adnia a LangChain.js ügynök meghívását.
import { HumanMessage } from "@langchain/core/messages";
import { hr_documents_answer_graph as app } from "./graph.js";
const AIMESSAGE = "aimessage";
export async function ask_agent(question: string) {
const initialState = { messages: [new HumanMessage(question)], iteration: 0 };
const finalState = await app.invoke(initialState);
return finalState;
}
export async function get_answer(question: string) {
try {
const answerResponse = await ask_agent(question);
const answer = answerResponse.messages
.filter(
(m: any) =>
m &&
m.constructor?.name?.toLowerCase() === AIMESSAGE.toLocaleLowerCase(),
)
.map((m: any) => m.content)
.join("\n");
return answer;
} catch (e) {
console.error("Error in get_answer:", e);
throw e;
}
}
A két függvény a következő:
- ask_agent: Ez a függvény az állapotot adja vissza, így lehetővé teszi a LangChain.js ügynök hozzáadását egy LangChain többügynök-munkafolyamathoz.
- get_answer: Ez a függvény csak a válasz szövegét adja vissza. Ez a függvény egy API-ból hívható meg.
Hibaelhárítás
- Az eljárással kapcsolatos problémák esetén hozzon létre egy hibát a mintakódtárban
Erőforrások tisztítása
Törölje az Azure AI Search-erőforrást és az Azure OpenAI-erőforrást tartalmazó erőforráscsoportot.