Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I den här självstudien använder du LangChain.js för att skapa en LangChain.js agent som gör det möjligt för NorthWind-företagets anställda att ställa personalrelaterade frågor. Genom att använda ramverket undviker du den exempelkod som vanligtvis krävs för LangChain.js agenter och Azure-tjänstintegrering, så att du kan fokusera på dina affärsbehov.
I den här handledningen kommer du att:
- Konfigurera en LangChain.js agent
- Integrera Azure-resurser i din LangChain.js-agent
- Du kan också testa din LangChain.js-agent i LangSmith Studio
NorthWind förlitar sig på två datakällor: offentlig HR-dokumentation som är tillgänglig för alla anställda och en konfidentiell HR-databas som innehåller känsliga medarbetares data. Den här handledningen fokuserar på att skapa en LangChain.js-agent som avgör om en medarbetares fråga kan besvaras med hjälp av officiella HR-dokument. I så fall ger LangChain.js-agenten svaret direkt.
              
               
              
              
            
Varning
Den här artikeln använder nycklar för att komma åt resurser. I en produktionsmiljö rekommenderar vi att du använder Azure RBAC och hanterad identitet. Den här metoden eliminerar behovet av att hantera eller rotera nycklar, förbättra säkerheten och förenkla åtkomstkontrollen.
Förutsättningar
- Ett aktivt Azure-konto. Skapa ett konto kostnadsfritt om du inte har något.
- Node.js LTS installerat på systemet.
- TypeScript för att skriva och kompilera TypeScript-kod.
- LangChain.js bibliotek för att skapa agenten.
- Valfritt: LangSmith för övervakning av AI-användning. Du behöver projektnamnet, nyckeln och slutpunkten.
- Valfritt: LangGraph Studio för felsökning av LangGraph-kedjor och LangChain.js agenter.
- Azure AI Search-resurs: Kontrollera att du har resursslutpunkten, administratörsnyckeln (för infogning av dokument), frågenyckel (för att läsa dokument) och indexnamn.
- 
              Azure OpenAI-resurs: Du behöver resursinstansens namn, nyckel och två modeller med sina API-versioner: - En inbäddningsmodell som text-embedding-ada-002.
- En stor språkmodell som gpt-4o.
 
- En inbäddningsmodell som 
Agentarkitektur
Det LangChain.js ramverket tillhandahåller ett beslutsflöde för att skapa intelligenta agenter som en LangGraph. I den här självstudien skapar du en LangChain.js agent som integreras med Azure AI Search och Azure OpenAI för att besvara HR-relaterade frågor. Agentens arkitektur är utformad för att:
- Ta reda på om en fråga är relevant för HR-dokumentationen.
- Hämta relevanta dokument från Azure AI Search.
- Använd Azure OpenAI för att generera ett svar baserat på de hämtade dokumenten och LLM-modellen.
Nyckelkomponenter:
- Grafstruktur: LangChain.js-agenten representeras som ett diagram, där: - Noder utför specifika uppgifter, till exempel beslutsfattande eller hämtning av data.
- Kanter definierar flödet mellan noder, vilket avgör åtgärdssekvensen.
 
- Azure AI Search-integrering: - Infogar HR-dokumentation i vektorlager som del av inbäddningar.
- Använder en inbäddningsmodell (text-embedding-ada-002) för att skapa dessa inbäddningar.
- Hämtar relevanta dokument baserat på användarens uppmaning.
 
- Azure OpenAI-integrering: - Använder en stor språkmodell (gpt-4o) för att:- Avgör om en fråga kan besvaras från allmänna HR-dokument.
- Genererar svar med prompt med hjälp av kontext från dokument och användarfrågor.
 
 
- Använder en stor språkmodell (
I följande tabell finns exempel på användarfrågor som är och inte är relevanta och svarsbara från allmänna personaldokument:
| Fråga | Relevans för HR-dokument | 
|---|---|
| Does the NorthWind Health Plus plan cover eye exams? | Relevant. HR-dokumenten, till exempel personalhandboken, bör ge ett svar. | 
| How much of my perks + benefits have I spent? | Inte relevant. Den här frågan kräver åtkomst till konfidentiella anställdas data, som ligger utanför agentens omfång. | 
Genom att använda ramverket undviker du den exempelkod som vanligtvis krävs för LangChain.js agenter och Azure-tjänstintegrering, så att du kan fokusera på dina affärsbehov.
Initiera ditt Node.js projekt
I en ny katalog initierar du ditt Node.js projekt för TypeScript-agenten. Kör följande kommandon:
npm init -y
npm pkg set type=module
npx tsc --init
Skapa en miljöfil
Skapa en .env fil för lokal utveckling för att lagra miljövariabler för Azure-resurser och LangGraph. Kontrollera att resursinstansnamnet för inbäddningen och LLM bara är resursnamnet, inte slutpunkten.
Valfritt: Om du använder LangSmith anger du LANGSMITH_TRACING till true för lokal utveckling. Inaktivera den (false) eller ta bort den i produktion.
Installera beroenden
- Installera Azure-beroenden för Azure AI Search: - npm install @azure/search-documents
- Installera LangChain.js beroenden för att skapa och använda en agent: - npm install @langchain/community @langchain/core @langchain/langgraph @langchain/openai langchain
- Installera utvecklingsberoenden för lokal utveckling: - npm install --save-dev dotenv
Skapa azure AI-sökresurskonfigurationsfiler
Om du vill hantera de olika Azure-resurser och modeller som används i den här självstudien skapar du specifika konfigurationsfiler för varje resurs. Den här metoden säkerställer tydlighet och separation av problem, vilket gör det enklare att hantera och underhålla konfigurationerna.
Konfiguration för att ladda upp dokument till vektorarkiv
Azure AI Search-konfigurationsfilen använder administratörsnyckeln för att infoga dokument i vektorarkivet. Den här nyckeln är viktig för att hantera datainmatning i Azure AI Search.
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 sammanfattar behovet av att definiera ett schema för datainmatning i Azure AI Search, vilket ger ett standardschema som lämpar sig för de flesta scenarier. Den här abstraktionen förenklar processen och minskar behovet av anpassade schemadefinitioner.
Konfiguration för att fråga vektorarkiv
Skapa en separat konfigurationsfil för att fråga vektorarkivet:
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,
  },
};
När du söker i vektorlager, använd frågenyckeln istället. Den här uppdelningen av nycklar säkerställer säker och effektiv åtkomst till resursen.
Skapa Azure OpenAI-resurskonfigurationsfiler
Om du vill hantera de två olika modellerna, inbäddningar och LLM, skapar du separata konfigurationsfiler. Den här metoden säkerställer tydlighet och separation av problem, vilket gör det enklare att hantera och underhålla konfigurationerna.
Konfiguration för inbäddningar för vektorarkiv
Skapa en konfigurationsfil för att skapa inbäddningar för att infoga dokument i Azure AI Search-vektorarkivet:
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,
};
Konfiguration för LLM för att generera svar
Skapa en konfigurationsfil för att skapa svar från den stora språkmodellen:
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,
};
Konstanter och uppmaningar
AI-program förlitar sig ofta på konstanta strängar och uppmaningar. Hantera dessa konstanter med separata filer.
Skapa systemprompten:
export const SYSTEM_PROMPT = `Answer the query with a complete paragraph based on the following context:`;
Skapa nodkonstanterna:
export const ANSWER_NODE = "vector_store_retrieval";
export const DECISION_NODE = "requires_hr_documents";
export const START = "__start__";
export const END = "__end__";
Skapa exempel på användarfrågor:
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?",
];
Ladda upp dokument till Azure AI Search
Om du vill läsa in dokument i Azure AI Search använder du LangChain.js för att förenkla processen. Dokumenten, som lagras som PDF-filer, konverteras till inbäddningar och infogas i vektorlagret. Den här processen säkerställer att dokumenten är redo för effektiv hämtning och frågehantering.
Viktiga överväganden:
- LangChain.js abstraktion: LangChain.js hanterar mycket av komplexiteten, till exempel schemadefinitioner och klientskapande, vilket gör processen enkel.
- Begränsnings- och återförsökslogik: Även om exempelkoden innehåller en minimal väntefunktion bör produktionsprogram implementera omfattande felhantering och återförsökslogik för att hantera begränsningsfel och tillfälliga fel.
Steg för att läsa in dokument
- Leta upp PDF-dokumenten: Dokumenten lagras i datakatalogen. 
- Läs in PDF-filer i LangChain.js: Använd - loadPdfsFromDirectoryfunktionen för att läsa in dokumenten. Den här funktionen använder metoden LangChain.js community- PDFLoader.loadför att läsa varje fil och returnera en- Document[]matris. Den här matrisen är ett standardformat för LangChain.js dokument.- 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); } }
- Infoga dokument i Azure AI Search: Använd - loadDocsIntoAiSearchVectorfunktionen för att skicka dokumentmatrisen till Azure AI Search-vektorarkivet. Den här funktionen använder embedding-klienten för att bearbeta dokumenten och inkluderar en grundläggande funktion för att vänta och hantera strypning. För produktion implementerar du en robust mekanism för återförsök/backoff.- 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; }
Skapa agentarbetsflöde
I LangChain.jsskapar du LangChain.js-agenten med en LangGraph. Med LangGraph kan du definiera noder och kanter:
- Nod: där arbete utförs.
- Edge: definierar anslutningen mellan noder.
Arbetsflödeskomponenter
I det här programmet är de två arbetsnoderna:
- requiresHrResources: avgör om frågan är relevant för HR-dokumentationen med hjälp av Azure OpenAI LLM.
- getAnswer: hämtar svaret. Svaret kommer från en LangChain.js retriever-kedja, som använder dokumentinbäddningar från Azure AI Search och skickar dem till Azure OpenAI LLM. Detta är kärnan i återvinningsförstärkt generation.
Kanterna definierar var du ska börja, sluta och det villkor som krävs för att anropa noden getAnswer .
Exportera grafen
Om du vill använda LangGraph Studio för att köra och felsöka diagrammet exporterar du det som ett eget objekt.
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";
I metoderna addNode, addEdge och addConditionalEdges är den första parametern ett namn som en sträng för att identifiera objektet i diagrammet. Den andra parametern är antingen den funktion som ska anropas i det steget eller namnet på noden som ska anropas.
För metoden addEdge är dess namn START ("start" definierat i filen ./src/config/nodes.ts) och anropar alltid DECISION_NODE. Noden definieras med sina två parametrar: den första är dess namn, DECISION_NODE, och den andra är funktionen som heter requiresHrResources.
Vanliga funktioner
Den här appen innehåller vanliga LangChain-funktioner:
- Tillståndshantering: - 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: () => [], }), });
- Routningsavslut: - 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; };
Den enda anpassade vägen för det här programmet är routeRequiresHrResources. Den här vägen används för att avgöra om svaret från noden requiresHrResources anger att användarens fråga ska fortsätta till den ANSWER_NODE noden. Eftersom den här vägen tar emot utdata från requiresHrResources finns den i samma fil.
Integrera Azure OpenAI-resurser
Azure OpenAI-integreringen använder två olika modeller:
- Inbäddningar: Används för att infoga dokumenten i vektorlagret.
- LLM: Används för att besvara frågor genom att fråga vektorarkivet och generera svar.
Inbäddningsklienten och LLM-klienten har olika syften. Minska dem inte till en enda modell eller klient.
Inbäddningsmodell
Inbäddningsklienten krävs när dokument hämtas från vektorarkivet. Den innehåller en konfiguration för maxRetries för att hantera tillfälliga fel.
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
LLM-modellen används för att besvara två typer av frågor:
- Relevans för HR: Avgör om användarens fråga är relevant för HR-dokumentationen.
- Svarsgenerering: Ger ett svar på användarens fråga, utökat med dokument från Azure AI Search.
LLM-klienten skapas och anropas när ett svar krävs.
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,
      },
    ],
  };
};
Den LangChain.js agenten använder LLM för att avgöra om frågan är relevant för HR-dokumentationen eller om arbetsflödet ska dirigeras till slutet av diagrammet.
// @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;
};
Funktionen requiresHrResources anger ett meddelande i det uppdaterade tillståndet med HR resources required detected innehåll. Routern routeRequiresHrResources letar efter innehållet för att avgöra var meddelandena ska skickas.
Integrera Azure AI Search-resurs för vektorarkiv
Integrationen av Azure AI Search tillhandahåller vektordokumenten så att LLM kan utöka svaret för getAnswer-noden. LangChain.js ger återigen mycket av abstraktionen så att den nödvändiga koden är minimal. Funktionerna är:
- getReadOnlyVectorStore: Hämtar klienten med frågenyckeln.
- getDocsFromVectorStore: Hittar relevanta dokument till användarens fråga.
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);
}
Den LangChain.js integreringskoden gör det otroligt enkelt att hämta relevanta dokument från vektorlagret.
Skriva kod för att få svar från LLM
Nu när integreringskomponenterna har skapats skapar du funktionen getAnswer för att hämta relevanta dokument för vektorlagring och generera ett svar med hjälp av LLM.
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],
  };
}
Den här funktionen ger en uppmaning med två platshållare: en för användarens fråga och en för kontext. Kontexten är alla relevanta dokument från AI Search-vektorarkivet. Skicka prompten och LLM-klienten till createStuffDocumentsChain för att skapa en LLM-kedja. Överför LLM-kedjan till skapa Retrieval Chain för att skapa en kedja som innehåller prompten, relevanta dokument och LLM.
Kör kedjorna med retrievalChain.invoke och användarens fråga som indata för att få svaret. Returnera svaret i meddelandetillståndet.
Skapa agentpaketet
- Lägg till ett skript i package.json för att skapa TypeScript-programmet: - "build": "tsc",
- Skapa LangChain.js-agenten. - npm run build
Valfritt – kör agenten LangChain.js för lokal utveckling med LangChain Studio
Du kan också använda LangChain Studio för lokal utveckling för att arbeta med din LangChain.js agent.
- Skapa en - langgraph.jsonfil för att definiera diagrammet.- { "dependencies": [], "graphs": { "agent": "./src/graph.ts:hr_documents_answer_graph" }, "env": "../.env" }
- Installera LangGraph CLI. - npm install @langchain/langgraph-cli --save-dev
- Skapa ett skript i package.json för att skicka - .envfilen till LangGraph CLI.- "studio": "npx @langchain/langgraph-cli dev",
- CLI körs i terminalen och öppnar en webbläsare till LangGraph Studio. - 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
- Visa LangChain.js-agenten i LangGraph Studio.   
- Välj + Meddelande för att lägga till en användarfråga och välj sedan Skicka. - Fråga - Relevans för HR-dokument - Does the NorthWind Health plus plan cover eye exams?- Den här frågan är relevant för personalavdelningen och tillräckligt allmänt för att hr-dokumenten, till exempel personalhandboken, förmånshandboken och biblioteket för anställdas roll ska kunna besvara den. - What is included in the NorthWind Health plus plan that is not included in the standard?- Den här frågan är relevant för personalavdelningen och tillräckligt allmänt för att hr-dokumenten, till exempel personalhandboken, förmånshandboken och biblioteket för anställdas roll ska kunna besvara den. - How much of my perks + benefit have I spent- Den här frågan är inte relevant för de allmänna, opersonliga HR-dokumenten. Den här frågan bör skickas till en agent som har åtkomst till anställdas data. 
- Om frågan är relevant för HR-dokumenten bör den gå igenom DECISION_NODE och vidare till ANSWER_NODE. - Titta på terminalutdata för att se frågan till LLM och svaret från LLM. 
- Om frågan inte är relevant för HR-dokumenten går flödet direkt till slutet. 
När LangChain.js agenten fattar ett felaktigt beslut kan problemet vara:
- LLM-modell som används
- Antal dokument från vektorarkivet
- Fråga som används i beslutsnoden.
Kör LangChain.js-agenten från en app
Om du vill anropa LangChain.js-agenten från ett överordnat program, till exempel ett webb-API, måste du ange LangChain.js agentens anrop.
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;
  }
}
De två funktionerna är:
- ask_agent: Den här funktionen returnerar tillståndet så att du kan lägga till LangChain.js-agenten i ett LangChain-arbetsflöde med flera agenter.
- get_answer: Den här funktionen returnerar bara svarets text. Den här funktionen kan anropas från ett API.
Felsökning
- För eventuella problem med proceduren skapar du ett problem på exempelkodlagringsplatsen
Rensa resurser
Ta bort resursgruppen som innehåller Azure AI Search-resursen och Azure OpenAI-resursen.