在本教程中,你将使用 LangChain.js 构建一个 LangChain.js 代理,使 NorthWind 公司员工能够询问人力资源相关问题。 使用该框架,可以避免因整合 LangChain.js 代理和 Azure 服务而通常需要的重复代码,使您能够专注于业务需求。
在本教程中,你将:
- 设置 LangChain.js 代理
- 将 Azure 资源集成到 LangChain.js 代理中
- (可选)在 LangSmith Studio 中测试 LangChain.js 代理
NorthWind 依赖于两个数据源:可供所有员工访问的公共 HR 文档和包含敏感员工数据的机密 HR 数据库。 本教程重点介绍如何构建一个 LangChain.js 代理,该代理确定员工的问题是否可以使用公共 HR 文档进行解答。 如果是这样,LangChain.js 代理会直接提供答案。
警告
本文使用密钥访问资源。 在生产环境中,建议的最佳做法是使用 Azure RBAC 和托管标识。 此方法无需管理或轮换密钥、增强安全性和简化访问控制。
先决条件
- 有效的 Azure 帐户。 如果没有帐户,请免费创建帐户。
- Node.js LTS 安装在您的系统上。
- TypeScript 用于编写和编译 TypeScript 代码。
- 用于构建代理的 LangChain.js 库。
- 可选:用于监视 AI 使用情况的 LangSmith 。 需要项目名称、密钥和终结点。
- 可选:用于调试 LangGraph 链和 LangChain.js 代理的 LangGraph Studio 。
- Azure AI 搜索资源:确保具有资源终结点、管理密钥(用于文档插入)、查询密钥(用于读取文档)和索引名称。
-
Azure OpenAI 资源:您需要资源实例名称、密钥,以及两个模型的 API 版本。
- 像
text-embedding-ada-002这样的嵌入模型。 - 一个大型语言模型,例如
gpt-4o。
- 像
代理体系结构
LangChain.js 框架提供了一个决策流,用于构建智能代理作为 LangGraph。 在本教程中,你将创建一个与 Azure AI 搜索和 Azure OpenAI 集成的 LangChain.js 代理来回答与 HR 相关的问题。 代理的体系结构旨在:
- 确定问题是否与 HR 文档相关。
- 从 Azure AI 搜索中检索相关文档。
- 使用 Azure OpenAI 基于检索的文档和 LLM 模型生成答案。
关键组件:
图形结构:LangChain.js 代理表示为图形,其中:
- 节点 执行特定任务,例如决策或检索数据。
- 边 定义节点之间的流,确定操作的顺序。
Azure AI 搜索集成:
- 将 HR 文档作为嵌入数据插入到向量存储库中。
- 使用嵌入模型 (
text-embedding-ada-002) 创建这些嵌入。 - 根据用户提示检索相关文档。
Azure OpenAI 集成:
- 使用大型语言模型 (
gpt-4o) 可以:- 确定问题是否可从常规 HR 文档得到解答。
- 使用文档和用户问题的上下文生成提示答案。
- 使用大型语言模型 (
下表包含用户问题的示例,这些问题与常规人力资源文档无关且不可回答:
| 问题 | 与 HR 文档的相关性 |
|---|---|
Does the NorthWind Health Plus plan cover eye exams? |
相关。 人力资源文档(如员工手册)应提供答案。 |
How much of my perks + benefits have I spent? |
不相关。 此问题需要访问此代理范围之外的机密员工数据。 |
使用该框架,可以避免因整合 LangChain.js 代理和 Azure 服务而通常需要的重复代码,使您能够专注于业务需求。
初始化 Node.js 项目
在新目录中,为 TypeScript 代理初始化 Node.js 项目。 运行以下命令:
npm init -y
npm pkg set type=module
npx tsc --init
创建环境文件
创建用于 .env 本地开发的文件来存储 Azure 资源和 LangGraph 的环境变量。 确保嵌入和 LLM 的资源实例名称只是资源名称,而不是终结点。
可选:如果使用 LangSmith,则将 LANGSMITH_TRACING 设置为 true 以进行本地开发。 禁用它(false)或在生产中将其删除。
安装依赖项
安装 Azure AI 搜索的 Azure 依赖项:
npm install @azure/search-documents安装用于创建和使用代理的 LangChain.js 依赖项:
npm install @langchain/community @langchain/core @langchain/langgraph @langchain/openai langchain安装用于本地开发的开发依赖项:
npm install --save-dev dotenv
创建 Azure AI 搜索资源配置文件
若要管理本教程中使用的各种 Azure 资源和模型,请为每个资源创建特定的配置文件。 此方法可确保关注点的明确性和分离性,从而更轻松地管理和维护配置。
用于将文档上传到矢量存储的配置
Azure AI 搜索配置文件使用管理密钥将文档插入矢量存储中。 此密钥对于管理将数据引入 Azure AI 搜索至关重要。
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 抽象化需要在 Azure AI 搜索中定义数据引入的架构,从而提供适用于大多数方案的默认架构。 此抽象简化了过程,并减少了自定义架构定义的需求。
查询矢量存储的配置
若要查询矢量存储,请创建单独的配置文件:
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,
},
};
查询矢量存储时,请改用查询键。 这种密钥分离可确保对资源的安全和高效访问。
创建 Azure OpenAI 资源配置文件
若要管理两个不同的模型(嵌入和 LLM),请创建单独的配置文件。 此方法可确保关注点的明确性和分离性,从而更轻松地管理和维护配置。
矢量存储嵌入的配置
若要创建用于将文档插入 Azure AI 搜索矢量存储的嵌入内容,请创建配置文件:
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,
};
用于生成答案的 LLM 的配置
若要从大型语言模型创建答案,请创建配置文件:
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,
};
常量和提示
AI 应用程序通常依赖于常量字符串和提示。 使用单独的文件管理这些常量。
创建系统提示:
export const SYSTEM_PROMPT = `Answer the query with a complete paragraph based on the following context:`;
创建节点常量:
export const ANSWER_NODE = "vector_store_retrieval";
export const DECISION_NODE = "requires_hr_documents";
export const START = "__start__";
export const END = "__end__";
创建示例用户查询:
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?",
];
将文档加载到 Azure AI 搜索中
若要将文档加载到 Azure AI 搜索中,请使用 LangChain.js 来简化该过程。 被存储为 PDF 的文档被转换为嵌入,并插入到向量数据库中。 此过程可确保文档已准备好进行高效检索和查询。
重要注意事项:
- LangChain.js 抽象:LangChain.js 处理大部分复杂性,例如架构定义和客户端创建,使该过程变得简单明了。
- 限制和重试逻辑:虽然示例代码包含最少的等待函数,但生产应用程序应实现全面的错误处理和重试逻辑来管理限制和暂时性错误。
加载文档的步骤
找到 PDF 文档:文档存储在 数据目录中。
将 PDF 加载到 LangChain.js:使用
loadPdfsFromDirectory函数加载文档。 此函数利用 LangChain.js 社区PDFLoader.load的方法读取每个文件并返回数组Document[]。 此数组是标准文档格式 LangChain.js。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); } }将文档插入 Azure AI 搜索:使用
loadDocsIntoAiSearchVector函数将文档数组发送到 Azure AI 搜索矢量存储。 此函数使用嵌入客户端来处理文档,并包括用于管理请求速率的基本等待函数。 在生产过程中,请实现可靠的重试和退避机制。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; }
创建代理工作流
在 LangChain.js中,使用 LangGraph 生成 LangChain.js 代理。 使用 LangGraph 可以定义节点和边缘:
- 节点:执行工作的位置。
- 边缘:定义节点之间的连接。
工作流组件
在此应用程序中,两个工作节点为:
- requiresHrResources:确定问题是否与使用 Azure OpenAI LLM 的 HR 文档相关。
- getAnswer:检索答案。 答案来自 LangChain.js 检索器链,该链使用 Azure AI 搜索中的文档嵌入,并将其发送到 Azure OpenAI LLM。 这是检索增强生成的本质。
边缘定义开始、结束和调用 getAnswer 节点所需的条件的位置。
导出图形
若要使用 LangGraph Studio 运行和调试图形,请将其导出为自己的对象。
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";
在 addNode、 addEdge 和 addConditionalEdges 方法中,第一个参数是一个名称(作为字符串),用于标识图形中的对象。 第二个参数是应在该步骤中调用的函数或要调用的节点的名称。
对于 addEdge 方法,其名称为 START(在 ./src/config/nodes.ts 文件中定义的“start”),并且它始终调用DECISION_NODE。 该节点使用其两个参数定义:第一个是其名称,DECISION_NODE,第二个是调用 的函数 requiresHrResources。
常见功能
此应用提供常见的 LangChain 功能:
状态管理:
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: () => [], }), });路由终止:
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; };
此应用程序的唯一自定义路由是 routeRequiresHrResources。 此路由用于确定 requiresHrResources 节点的答案是否指示用户的问题应继续转到 ANSWER_NODE 节点。 由于此路由接收 requiresHrResources 的输出,因此它位于同一文件中。
集成 Azure OpenAI 资源
Azure OpenAI 集成使用两个不同的模型:
- 嵌入:用于将文档插入向量存储中。
- LLM:用于通过查询矢量存储并生成响应来回答问题。
嵌入客户端和 LLM 客户端用于不同的目的。 不要将它们减少到单个模型或客户端。
嵌入模型
从向量存储中检索文档时,需要使用嵌入客户端。 它包括用于处理暂时性错误的 maxRetries 的配置。
import { AzureOpenAIEmbeddings } from "@langchain/openai";
import { EMBEDDINGS_CONFIG } from "../config/embeddings.js";
export function getEmbeddingClient(): AzureOpenAIEmbeddings {
return new AzureOpenAIEmbeddings({ ...EMBEDDINGS_CONFIG, maxRetries: 1 });
}
LLM 模型
LLM 模型用于回答两种类型的问题:
- 与 HR 相关:确定用户的问题是否与 HR 文档相关。
- 答案生成:提供用户问题的答案,并结合了来自 Azure AI 搜索的文档。
当需要答案时,将创建和调用 LLM 客户端。
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,
},
],
};
};
LangChain.js 代理使用 LLM 来确定问题是否与 HR 文档相关,或者工作流是否应路由到图的末尾。
// @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;
};
requiresHrResources 函数在更新状态中使用HR resources required detected内容设置消息。 路由器 routeRequiresHrResources 查找该内容以确定消息的发送位置。
集成用于矢量存储的 Azure AI 搜索资源
Azure AI 搜索集成提供矢量存储文档,以便 LLM 可以增强 getAnswer 节点的答案。 LangChain.js 再次提供大量抽象,因此所需的代码最少。 功能包括:
- getReadOnlyVectorStore:使用查询密钥检索客户端。
- getDocsFromVectorStore:查找用户问题的相关文档。
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);
}
LangChain.js 集成代码使得从矢量存储中检索相关文档变得非常简单。
编写代码以从 LLM 获取答案
生成集成组件后,请创建 getAnswer 函数以检索相关的矢量存储文档,并使用 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],
};
}
此函数提供的提示中包含两个占位符:一个用于用户的问题,另一个用于上下文。 上下文是 AI 搜索矢量存储中的所有相关文档。 将提示和 LLM 客户端传递给 createStuffDocumentsChain 以创建 LLM 链。 传递 LLM 链到createRetrievalChain以创建一个包含提示、相关文档和 LLM 的链条。
使用 retrievalChain.invoke,并将用户的问题作为输入来运行链以获取答案。 返回消息状态中的答案。
生成代理包
将脚本添加到 package.json 以生成 TypeScript 应用程序:
"build": "tsc",生成 LangChain.js 代理。
npm run build
可选 - 使用 LangChain Studio 在本地开发中运行 LangChain.js 代理
(可选)用于本地开发,请使用 LangChain Studio 来操作 LangChain.js 代理。
创建文件
langgraph.json以定义图形。{ "dependencies": [], "graphs": { "agent": "./src/graph.ts:hr_documents_answer_graph" }, "env": "../.env" }安装 LangGraph CLI。
npm install @langchain/langgraph-cli --save-dev在 package.json 中创建脚本,将
.env文件传递给 LangGraph CLI。"studio": "npx @langchain/langgraph-cli dev",CLI 在终端中运行,并将浏览器打开到 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在 LangGraph Studio 中查看 LangChain.js 代理程序。
选择 “+ 消息 ”以添加用户问题,然后选择“ 提交”。
问题 与 HR 文档的相关性 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?这个问题与人力资源相关,一般情况下,人力资源文档(如员工手册、福利手册和员工角色库)应该能够回答。 How much of my perks + benefit have I spent这个问题与一般、非个人人力资源文档无关。 此问题应发送到有权访问员工数据的代理。 如果问题与 HR 文档相关,则应通过 DECISION_NODE 并传递到 ANSWER_NODE。
请注意观看终端输出,查看向 LLM 提出的问题及其给出的答案。
如果问题与 HR 文档无关,则流程会直接进入 结束。
当 LangChain.js 代理做出错误的决定时,问题可能是:
- 使用的 LLM 模型
- 矢量存储中的文档数
- 决策节点中使用的提示。
从应用运行 LangChain.js 代理
若要从父应用程序(如 Web API)调用 LangChain.js 代理,需要提供 LangChain.js 代理的调用。
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;
}
}
这两个函数包括:
- ask_agent:此函数返回状态,使你可以将 LangChain.js 代理添加到 LangChain 多代理工作流。
- get_answer:此函数仅返回答案的文本。 可以从 API 调用此函数。
故障排除
- 对于该过程的任何问题,请在示例代码存储库上创建问题
清理资源
删除保存 Azure AI 搜索资源和 Azure OpenAI 资源的资源组。