2026/4/18 10:12:12
网站建设
项目流程
做网站自己上传电影要多大服务器,用dw做的十二星座网站免费,网站数据泄露我们应该怎么做,windows系统安装wordpress在 Baeldung 上看到了一篇介绍基于 Java LangChain 开发大语言模型应用的基础入门文章#xff0c;写的非常不错#xff0c;非常适合初学者。于是#xff0c;我抽空翻译了一下。
我的公众号应该有很多读者对这方面的知识感兴趣#xff0c;希望这篇文章能够起到入门的作用。…在 Baeldung 上看到了一篇介绍基于 Java LangChain 开发大语言模型应用的基础入门文章写的非常不错非常适合初学者。于是我抽空翻译了一下。我的公众号应该有很多读者对这方面的知识感兴趣希望这篇文章能够起到入门的作用。1. 简介在本教程中我们将详细探讨 LangChain[1]一个用于开发基于语言模型[2]的应用程序的框架。我们将首先了解语言模型的基础概念这些知识将对本教程有所帮助。尽管 LangChain 主要提供 Python 和 JavaScript/TypeScript 版本但也可以在 Java 中使用 LangChain。我们会讨论 LangChain 作为框架的构建模块然后尝试在 Java 中进行实验。2. 背景在深入探讨为什么需要一个用于构建基于语言模型的应用程序的框架之前我们需要弄清楚语言模型是什么并了解使用语言模型时可能遇到的一些典型复杂性。2.1. 大型语言模型语言模型是自然语言的概率模型可以生成一系列单词的概率。大型语言模型[3]LLM则是以其规模庞大而著称通常包含数十亿参数的人工神经网络。大型语言模型通常通过在大量未标记数据上进行预训练使用自监督学习[4]和弱监督学习[5]技术。之后通过微调和提示词工程等技术将预训练模型适配于特定任务大型语言模型大型语言模型可以执行多种自然语言处理任务如语言翻译、内容摘要等。此外它们还具备生成内容的能力因此在回答问题等应用场景中非常有用。几乎所有主流云服务提供商都在其服务中引入了大型语言模型。例如Microsoft Azure[6] 提供了 Llama 2 和 OpenAI GPT-4Amazon Bedrock[7] 提供了 AI21 Labs、Anthropic、Cohere、Meta 和 Stability AI 的模型。2.2. 提示词工程大型语言模型是一种基础模型经过大规模文本数据的训练后可以捕捉人类语言的语法和语义。然而为了让模型执行特定任务它们需要进一步调整。提示词工程Prompt engineering[8]是让语言模型完成特定任务的最快捷方法之一。它通过结构化文本向模型描述任务目标使其能够理解并执行任务提示词工程提示词帮助大型语言模型执行上下文学习[9]这种学习是暂时的。通过提示词工程我们可以促进大型语言模型的安全使用并构建新的功能比如将领域知识和外部工具整合到模型中。这一领域目前是一个活跃的研究方向不断涌现新的技术。然而诸如链式思维提示[10]等技术已经变得颇为流行。这种方法的核心是让大型语言模型在给出最终答案之前将问题分解为一系列中间步骤。2.3. 词向量如前所述大型语言模型能够高效处理自然语言。如果我们将自然语言中的单词表示为词向量Word Embeddings [11]模型的性能将显著提升。词向量是能够编码单词语义的实值向量。词向量通常通过算法生成例如 Word2vec[12] 或 GloVe[13]。GloVe 是一种无监督学习算法在语料库的全局词共现统计上进行训练Word Embedding Illustration在提示词工程中我们将提示转换成词向量这使得模型更容易理解和响应提示。此外它也对增强我们提供给模型的上下文非常有帮助从而使模型能够给出更具上下文意义的回答。例如我们可以从现有数据集中生成词向量并将其存储在向量数据库中。然后我们可以使用用户提供的输入在向量数据库中执行语义搜索并将搜索结果作为附加上下文提供给模型。3. 使用 LangChain 构建 LLM 技术栈正如我们已经了解的那样创建有效的提示词是成功利用 LLM 的关键元素。这包括使与语言模型的交互具有上下文感知能力并依赖语言模型进行推理。为此我们需要执行多项任务例如为提示词创建模板、调用语言模型以及从多种来源提供用户特定数据。为了简化这些任务我们需要一个像 LangChain 这样的框架作为 LLM 技术栈的一部分使用 LangChain 构建 LLM 技术栈该框架还帮助开发需要链式调用多个语言模型的应用程序并能够回忆起过去与语言模型过去交互的信息。此外还有更复杂的用例例如将语言模型用作推理引擎。最后我们可以执行日志记录、监控、流式处理以及其他重要的维护和故障排除任务。LLM 技术栈正在快速发展以应对许多此类问题而 LangChain 正迅速成为 LLM 技术栈的宝贵组成部分。4. 面向 Java 的 LangChainLangChain[14] 于2022 年作为开源项目推出凭借社区支持迅速发展壮大。最初是由 Harrison Chase 开发的 Python 项目后来成为 AI 领域增长最快的初创企业之一。随后JavaScript/TypeScript 版本的 LangChain 于 2023 年初推出并迅速流行起来支持多个 JavaScript 环境如 Node.js、浏览器、CloudFlare workers、Vercel/Next.js、Deno 和 Supabase Edge functions。然而目前没有官方的 Java 版本 LangChain可供 Java 或 Spring 应用使用。不过社区开发了 Java 版本 LangChain称为 LangChain4j[15]支持 Java 8 或更高版本并兼容 Spring Boot 2 和 3。LangChain 的各种依赖项可以在 Maven Central 上找到。根据我们使用的功能可能需要在应用程序中添加一个或多个依赖项dependency groupIddev.langchain4j/groupId artifactIdlangchain4j/artifactId version0.23.0/version /dependency5. LangChain 的构建模块LangChain 为我们的应用程序提供了多种价值主张这些功能以模块化组件的形式提供。模块化组件不仅提供了有用的抽象还包含了一系列操作语言模型的实现。接下来我们将通过 Java 示例来讨论其中的一些模块。5.1. 模型输入/输出Models I/O在使用任何语言模型时我们需要具备与其交互的能力。LangChain 提供了必要的构建模块例如模板化提示的能力以及动态选择和管理模型输入的能力。此外我们还可以使用输出解析器从模型输出中提取信息LangChain 模型提示模板Prompt Templates是用于生成语言模型提示的预定义配方可以包括指令、少样本示例[16]和特定上下文PromptTemplate promptTemplate PromptTemplate .from(Tell me a {{adjective}} joke about {{content}}..); MapString, Object variables new HashMap(); variables.put(adjective, funny); variables.put(content, computers); Prompt prompt promptTemplate.apply(variables);5.2. 内存通常一个利用大型语言模型LLM的应用程序会有一个对话界面。对话的一个重要方面是能够引用对话中先前的信息。这种存储过去交互信息的能力称为内存LangChain 内存LangChain 提供了一些关键功能可以为应用程序添加内存。例如我们需要能够从内存中读取信息以增强用户输入同时还需要将当前运行的输入和输出写入内存ChatMemory chatMemory TokenWindowChatMemory .withMaxTokens(300, new OpenAiTokenizer(GPT_3_5_TURBO)); chatMemory.add(userMessage(你好我叫 Kumar)); AiMessage answer model.generate(chatMemory.messages()).content(); System.out.println(answer.text()); // 你好 Kumar今天我能为您做些什么 chatMemory.add(answer); chatMemory.add(userMessage(我叫什么名字)); AiMessage answerWithName model.generate(chatMemory.messages()).content(); System.out.println(answerWithName.text()); // 您的名字是 Kumar。 chatMemory.add(answerWithName);在这里我们使用TokenWindowChatMemory实现了固定窗口聊天内存它允许我们读取和写入与语言模型交换的聊天消息。LangChain 还提供更复杂的数据结构和算法以便从内存中返回选定的消息而不是返回所有内容。例如它支持返回过去几条消息的摘要或者仅返回与当前运行相关的消息。5.3. 检索Retrieval大型语言模型通常是在大量的文本语料库上进行训练的。因此它们在处理通用任务时表现得非常高效但在处理特定领域任务时可能效果不佳。为了解决这一问题我们需要在生成阶段检索相关的外部数据并将其传递给语言模型。这个过程被称为检索增强生成Retrieval Augmented GenerationRAG。RAG 有助于将模型的生成过程与相关且准确的信息结合同时也让我们更深入地了解模型的生成过程。LangChain 提供了构建 RAG 应用程序所需的核心组件LangChain Retrieval首先LangChain 提供了文档加载器FileSystemDocumentLoader用于从存储位置检索文档。然后LangChain 还提供了转换器用于进一步处理文档例如将大型文档分割成更小的块Document document FileSystemDocumentLoader.loadDocument(simpsons_adventures.txt); DocumentSplitter splitter DocumentSplitters.recursive(100, 0, new OpenAiTokenizer(GPT_3_5_TURBO)); ListTextSegment segments splitter.split(document);在这里我们使用FileSystemDocumentLoader从文件系统中加载文档。然后使用OpenAiTokenizer将文档分割成更小的段落。为了提高检索效率这些文档通常会被转换成嵌入embeddings并存储在向量数据库中。LangChain 支持多种嵌入提供商和方法并与几乎所有主流的向量存储集成EmbeddingModel embeddingModel new AllMiniLmL6V2EmbeddingModel(); ListEmbedding embeddings embeddingModel.embedAll(segments).content(); EmbeddingStoreTextSegment embeddingStore new InMemoryEmbeddingStore(); embeddingStore.addAll(embeddings, segments);在这里我们使用AllMiniLmL6V2EmbeddingModel为文档段落创建嵌入然后将嵌入存储在内存中的向量存储中。现在我们的外部数据已经以嵌入的形式存储在向量存储中可以从中进行检索。LangChain 支持多种检索算法例如简单的语义搜索和更复杂的集成检索器ensemble retrieverString question Who is Simpson?; // 假设该问题的答案包含在我们之前处理的文档中。 Embedding questionEmbedding embeddingModel.embed(question).content(); int maxResults 3; double minScore 0.7; ListEmbeddingMatchTextSegment relevantEmbeddings embeddingStore .findRelevant(questionEmbedding, maxResults, minScore);我们为用户的问题生成嵌入然后使用该问题的嵌入从向量存储中检索相关的匹配项。现在我们可以将检索到的相关内容作为上下文添加到我们打算发送给模型的提示中。6. LangChain 的复杂应用到目前为止我们已经了解了如何使用单个组件来创建一个基于语言模型的应用程序。LangChain 还提供了构建更复杂应用程序的组件。例如我们可以使用链Chains和代理Agents来构建更加自适应、功能增强的应用程序。6.1. 链Chains通常一个应用程序需要按特定顺序调用多个组件。在 LangChain 中这被称为链Chain。链简化了开发更复杂应用程序的过程并使调试、维护和改进更加容易。链还可以组合多个链来构建更复杂的应用程序这些应用程序可能需要与多个语言模型交互。LangChain 提供了创建此类链的便捷方式并内置了许多预构建链ConversationalRetrievalChain chain ConversationalRetrievalChain.builder() .chatLanguageModel(chatModel) .retriever(EmbeddingStoreRetriever.from(embeddingStore, embeddingModel)) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .promptTemplate(PromptTemplate .from(Answer the following question to the best of your ability: {{question}}\n\nBase your answer on the following information:\n{{information}})) .build();在这里我们使用了预构建的链ConversationalRetrievalChain它允许我们将聊天模型与检索器、内存和提示模板结合使用。现在我们可以简单地使用该链来执行用户查询String answer chain.execute(Who is Simpson?);该链提供了默认的内存和提示模板我们可以根据需要进行覆盖。创建自定义链也非常容易。链的能力使我们能够更轻松地实现复杂应用程序的模块化实现。6.2. 代理AgentsLangChain 还提供了更强大的结构例如代理Agent。与链不同代理将语言模型用作推理引擎以确定应该采取哪些操作以及操作的顺序。我们还可以为代理提供访问合适工具的权限以执行必要的操作。在 LangChain4j 中代理作为 AI 服务AI Services提供用于声明性地定义复杂的 AI 行为。让我们看看如何通过提供一个计算器工具为 AI 服务赋能从而使语言模型能够执行计算。首先我们定义一个包含一些基本计算功能的类并用自然语言描述每个函数这样模型可以理解public class AIServiceWithCalculator { static class Calculator { Tool(Calculates the length of a string) int stringLength(String s) { return s.length(); } Tool(Calculates the sum of two numbers) int add(int a, int b) { return a b; } }接下来我们定义一个接口用于构建我们的 AI 服务。这里的接口相对简单但也可以描述更复杂的行为interface Assistant { String chat(String userMessage); }然后我们使用 LangChain4j 提供的构建器工厂通过定义的接口和工具创建一个 AI 服务Assistant assistant AiServices.builder(Assistant.class) .chatLanguageModel(OpenAiChatModel.withApiKey(OPENAI_API_KEY)) .tools(new Calculator()) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .build();完成了现在我们可以向语言模型发送包含计算任务的问题String question What is the sum of the numbers of letters in the words \language\ and \model\?; String answer assistant.chat(question); System.out.println(answer); // The sum of the numbers of letters in the words language and model is 13.运行这段代码后我们会发现语言模型现在能够执行计算。需要注意的是语言模型在执行某些任务时可能会遇到困难例如需要时间和空间概念的任务或复杂的算术操作。然而我们可以通过为模型提供必要的工具来解决这些问题。7. 总结在本教程中我们探讨了创建基于大型语言模型的应用程序的一些基本元素。此外我们讨论了将 LangChain 作为技术栈的一部分对开发此类应用程序的重要价值。这使得我们能够探索 LangChain 的 Java 版本 —— LangChain4j 的一些核心组件 。这些库未来将快速发展它们会让开发由语言模型驱动的应用程序的过程变得更成熟和有趣