前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java + LangChain = 王炸!

Java + LangChain = 王炸!

作者头像
程序员鱼皮
发布于 2025-03-29 06:24:17
发布于 2025-03-29 06:24:17
16100
代码可运行
举报
文章被收录于专栏:鱼皮客栈鱼皮客栈
运行总次数:0
代码可运行

在 Baeldung 上看到了一篇介绍基于 Java + LangChain 开发大语言模型应用的基础入门文章,写的非常不错,非常适合初学者。

我的公众号应该有很多读者对这方面的知识感兴趣,希望这篇文章能够起到入门的作用。

  • 原文地址: https://www.baeldung.com/java-langchain-basics
  • 翻译:JavaGuide

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-4,Amazon 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
Word Embedding Illustration

Word Embedding Illustration

在提示词工程中,我们将提示转换成词向量,这使得模型更容易理解和响应提示。此外,它也对增强我们提供给模型的上下文非常有帮助,从而使模型能够给出更具上下文意义的回答。

例如,我们可以从现有数据集中生成词向量并将其存储在向量数据库中。然后,我们可以使用用户提供的输入在向量数据库中执行语义搜索,并将搜索结果作为附加上下文提供给模型。

3. 使用 LangChain 构建 LLM 技术栈

正如我们已经了解的那样,创建有效的提示词是成功利用 LLM 的关键元素。这包括使与语言模型的交互具有上下文感知能力,并依赖语言模型进行推理。

为此,我们需要执行多项任务,例如为提示词创建模板、调用语言模型,以及从多种来源提供用户特定数据。为了简化这些任务,我们需要一个像 LangChain 这样的框架作为 LLM 技术栈的一部分:

使用 LangChain 构建 LLM 技术栈
使用 LangChain 构建 LLM 技术栈

使用 LangChain 构建 LLM 技术栈

该框架还帮助开发需要链式调用多个语言模型的应用程序,并能够回忆起过去与语言模型过去交互的信息。此外,还有更复杂的用例,例如将语言模型用作推理引擎。

最后,我们可以执行日志记录、监控、流式处理以及其他重要的维护和故障排除任务。LLM 技术栈正在快速发展以应对许多此类问题,而 LangChain 正迅速成为 LLM 技术栈的宝贵组成部分。

4. 面向 Java 的 LangChain

LangChain[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 上找到。

根据我们使用的功能,可能需要在应用程序中添加一个或多个依赖项

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j</artifactId>
    <version>0.23.0</version>
</dependency>

5. LangChain 的构建模块

LangChain 为我们的应用程序提供了多种价值主张,这些功能以模块化组件的形式提供。模块化组件不仅提供了有用的抽象,还包含了一系列操作语言模型的实现。接下来,我们将通过 Java 示例来讨论其中的一些模块。

5.1. 模型输入/输出(Models I/O)

在使用任何语言模型时,我们需要具备与其交互的能力。LangChain 提供了必要的构建模块,例如模板化提示的能力,以及动态选择和管理模型输入的能力。此外,我们还可以使用输出解析器从模型输出中提取信息:

LangChain 模型
LangChain 模型

LangChain 模型

提示模板(Prompt Templates)是用于生成语言模型提示的预定义配方,可以包括指令、少样本示例[16]和特定上下文:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PromptTemplate promptTemplate = PromptTemplate
  .from("Tell me a {{adjective}} joke about {{content}}..");
Map<String, Object> variables = new HashMap<>();
variables.put("adjective", "funny");
variables.put("content", "computers");
Prompt prompt = promptTemplate.apply(variables);

5.2. 内存

通常,一个利用大型语言模型(LLM)的应用程序会有一个对话界面。对话的一个重要方面是能够引用对话中先前的信息。这种存储过去交互信息的能力称为内存

LangChain 内存
LangChain 内存

LangChain 内存

LangChain 提供了一些关键功能,可以为应用程序添加内存。例如,我们需要能够从内存中读取信息以增强用户输入,同时还需要将当前运行的输入和输出写入内存:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 Generation,RAG)。RAG 有助于将模型的生成过程与相关且准确的信息结合,同时也让我们更深入地了解模型的生成过程。LangChain 提供了构建 RAG 应用程序所需的核心组件:

LangChain Retrieval
LangChain Retrieval

LangChain Retrieval

首先,LangChain 提供了文档加载器 FileSystemDocumentLoader,用于从存储位置检索文档。然后,LangChain 还提供了转换器,用于进一步处理文档,例如将大型文档分割成更小的块:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Document document = FileSystemDocumentLoader.loadDocument("simpson's_adventures.txt");
DocumentSplitter splitter = DocumentSplitters.recursive(100, 0,
  new OpenAiTokenizer(GPT_3_5_TURBO));
List<TextSegment> segments = splitter.split(document);

在这里,我们使用 FileSystemDocumentLoader文件系统中加载文档。然后使用 OpenAiTokenizer 将文档分割成更小的段落。

为了提高检索效率,这些文档通常会被转换成嵌入(embeddings),并存储在向量数据库中。LangChain 支持多种嵌入提供商和方法,并与几乎所有主流的向量存储集成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel();
List<Embedding> embeddings = embeddingModel.embedAll(segments).content();
EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
embeddingStore.addAll(embeddings, segments);

在这里,我们使用 AllMiniLmL6V2EmbeddingModel 为文档段落创建嵌入,然后将嵌入存储在内存中的向量存储中。

现在,我们的外部数据已经以嵌入的形式存储在向量存储中,可以从中进行检索。LangChain 支持多种检索算法,例如简单的语义搜索和更复杂的集成检索器(ensemble retriever):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String question = "Who is Simpson?";
// 假设该问题的答案包含在我们之前处理的文档中。
Embedding questionEmbedding = embeddingModel.embed(question).content();
int maxResults = 3;
double minScore = 0.7;
List<EmbeddingMatch<TextSegment>> relevantEmbeddings = embeddingStore
  .findRelevant(questionEmbedding, maxResults, minScore);

我们为用户的问题生成嵌入,然后使用该问题的嵌入从向量存储中检索相关的匹配项。现在,我们可以将检索到的相关内容作为上下文,添加到我们打算发送给模型的提示中。

6. LangChain 的复杂应用

到目前为止,我们已经了解了如何使用单个组件来创建一个基于语言模型的应用程序。LangChain 还提供了构建更复杂应用程序的组件。例如,我们可以使用链(Chains)和代理(Agents)来构建更加自适应、功能增强的应用程序。

6.1. 链(Chains)

通常,一个应用程序需要按特定顺序调用多个组件。在 LangChain 中,这被称为链(Chain)。链简化了开发更复杂应用程序的过程,并使调试、维护和改进更加容易。

链还可以组合多个链来构建更复杂的应用程序,这些应用程序可能需要与多个语言模型交互。LangChain 提供了创建此类链的便捷方式,并内置了许多预构建链:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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,它允许我们将聊天模型与检索器、内存和提示模板结合使用。现在,我们可以简单地使用该链来执行用户查询:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String answer = chain.execute("Who is Simpson?");

该链提供了默认的内存和提示模板,我们可以根据需要进行覆盖。创建自定义链也非常容易。链的能力使我们能够更轻松地实现复杂应用程序的模块化实现。

6.2. 代理(Agents)

LangChain 还提供了更强大的结构,例如代理(Agent)。与链不同,代理将语言模型用作推理引擎,以确定应该采取哪些操作以及操作的顺序。我们还可以为代理提供访问合适工具的权限,以执行必要的操作。

在 LangChain4j 中,代理作为 AI 服务(AI Services)提供,用于声明性地定义复杂的 AI 行为。让我们看看如何通过提供一个计算器工具,为 AI 服务赋能,从而使语言模型能够执行计算。

首先,我们定义一个包含一些基本计算功能的类,并用自然语言描述每个函数,这样模型可以理解:

代码语言:javascript
代码运行次数:0
运行
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 服务。这里的接口相对简单,但也可以描述更复杂的行为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
interface Assistant {
    String chat(String userMessage);
}

然后,我们使用 LangChain4j 提供的构建器工厂,通过定义的接口和工具创建一个 AI 服务:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Assistant assistant = AiServices.builder(Assistant.class)
  .chatLanguageModel(OpenAiChatModel.withApiKey(<OPENAI_API_KEY>))
  .tools(new Calculator())
  .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
  .build();

完成了!现在,我们可以向语言模型发送包含计算任务的问题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 的一些核心组件 。这些库未来将快速发展,它们会让开发由语言模型驱动的应用程序的过程变得更成熟和有趣!

参考资料

[1]

LangChain: https://www.langchain.com/

[2]

语言模型: https://www.baeldung.com/cs/nlp-language-models

[3]

大型语言模型: https://www.baeldung.com/cs/large-language-models

[4]

自监督学习: https://en.wikipedia.org/wiki/Self-supervised_learning

[5]

弱监督学习: https://en.wikipedia.org/wiki/Weak_supervision

[6]

Microsoft Azure: https://azure.microsoft.com/en-us/solutions/ai

[7]

Amazon Bedrock: https://aws.amazon.com/bedrock/

[8]

提示词工程(Prompt engineering): https://en.wikipedia.org/wiki/Prompt_engineering

[9]

上下文学习: https://en.wikipedia.org/wiki/Prompt_engineering#In-context_learning

[10]

链式思维提示: https://www.promptingguide.ai/techniques/cot

[11]

词向量(Word Embeddings ): https://en.wikipedia.org/wiki/Word_embedding

[12]

Tomáš Mikolov 的 Word2vec: https://en.wikipedia.org/wiki/Word2vec

[13]

斯坦福大学的 GloVe: https://nlp.stanford.edu/projects/glove/

[14]

LangChain: https://www.langchain.com/

[15]

LangChain4j: https://github.com/langchain4j/langchain4j

[16]

少样本示例: https://www.promptingguide.ai/techniques/fewshot

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员鱼皮 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
鸿蒙(HarmonyOS)性能优化实战-Grid高性能开发
在构建大型、复杂应用时,性能优化至关重要。Grid布局作为一种高效布局方式,可以提高页面的均分能力、子组件占比控制能力及自适应布局能力。本文将介绍Grid在高性能开发方面的应用,包括懒加载、cachedCount、组件复用和使用GridLayoutOptions设置GridItem大小等方法,帮助开发者优化Grid布局性能,减少加载和渲染时间,提升用户体验。
小帅聊鸿蒙
2024/10/18
2240
鸿蒙(HarmonyOS)性能优化实战-Grid高性能开发
【HarmonyOS之旅】ArkTS语法(三) -> 渲染控制
ArkTS也提供了渲染控制的能力。条件渲染可根据应用的不同状态,渲染对应状态下的UI内容。循环渲染可从数据源中迭代获取数据,并在每次迭代过程中创建相应的组件。
枫叶丹
2025/01/02
1450
【HarmonyOS之旅】ArkTS语法(三) -> 渲染控制
18 HarmonyOS NEXT UVList组件开发指南(五)
在开发UVList组件的过程中,我们遵循了以下设计原则,这些原则也适用于其他组件的开发:
全栈若城
2025/03/10
1070
101.HarmonyOS NEXT跑马灯组件教程:数据源与数据类型详解
在HarmonyOS NEXT跑马灯组件的实现中,数据模型是组件正常工作的基础。本文将详细介绍跑马灯组件使用的数据源和数据类型,包括TripDataType接口、TripDataSource类和相关的数据处理机制。
全栈若城
2025/03/17
850
鸿蒙(HarmonyOS)应用开发之性能优化实战-组件复用
若开发者的应用中存在以下场景,并成为UI线程的帧率瓶颈,应该考虑使用组件复用机制提升应用性能:
小帅聊鸿蒙
2024/10/16
3620
鸿蒙(HarmonyOS)应用开发之性能优化实战-组件复用
HarmonyOS 应用列表场景性能提升实践
在应用的UI开发中,使用列表是一种常规场景,因此,对列表性能进行优化是非常重要的。本文将针对应用开发列表场景的性能提升实践方法展开介绍。
小帅聊鸿蒙
2024/10/14
2420
HarmonyOS 应用列表场景性能提升实践
鸿蒙(HarmonyOS)性能优化实战-减少首帧绘制时的冗余操作
应用冷启动即当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用。
小帅聊鸿蒙
2024/10/23
1520
鸿蒙(HarmonyOS)性能优化实战-减少首帧绘制时的冗余操作
ArkTS语言的LazyForEach懒加载循环
前面我发了一篇渲染控制的文章里面有 if/else 和 foreach 的知识点,本次的 LazyForEach 也是属于渲染控制的在官方文档也可以看到归类,那么他的作用是,LazyForEach从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。
杨不易呀
2023/12/09
7150
ArkTS语言的LazyForEach懒加载循环
【HarmonyOS之旅】基于ArkTS开发(二) -> UI开发四
在pages目录下创建一个Web组件。在Web组件中通过src指定引用的网页路径,controller为组件的控制器,通过controller绑定Web组件,用于调用Web组件的方法。
枫叶丹
2025/01/23
1060
HarmonyOS APP性能优化之提升应用响应速度
应用对用户的输入需要快速反馈,以提升交互体验,因此本文提供了以下方法来提升应用响应速度。
小帅聊鸿蒙
2024/10/14
1740
HarmonyOS APP性能优化之提升应用响应速度
鸿蒙(HarmonyOS)性能优化实战-Swiper高性能开发
在应用开发中,Swiper 组件常用于翻页场景,比如:桌面、图库等应用。Swiper 组件滑动切换页面时,基于按需加载原则通常会在下一个页面将要显示时才对该页面进行加载和布局绘制,这个过程包括:
小帅聊鸿蒙
2024/10/17
2180
鸿蒙(HarmonyOS)性能优化实战-Swiper高性能开发
HarmonyOS4.0——ArkUI应用说明
ArkUI开发框架是方舟开发框架的简称,它是一套构建 HarmonyOS / OpenHarmony 应用界面的声明式UI开发框架,它使用极简的UI信息语法、丰富的UI组件以及实时界面语言工具,帮助开发者提升应用界面开发效率 30%,开发者只需要使用一套 TS / JS API,就能在多个 HarmonyOS / OpenHarmony 设备上提供既丰富又流畅的用户界面体验。
小帅聊鸿蒙
2024/07/04
3980
HarmonyOS4.0——ArkUI应用说明
鸿蒙应用开发-自定义可删除列表弹窗
自定义列表弹窗,可以对弹窗的列表点击删除,参考文档创建列表,自定义弹窗文档自定义弹窗(CustomDialog)。
夜雨飘零
2024/05/26
1750
鸿蒙应用开发-自定义可删除列表弹窗
78. Harmonyos NEXT 懒加载数据源实现解析:BasicDataSource与CommonLazyDataSourceModel详解
完整构建了HarmonyOS应用的高效数据加载体系,适用于相册、商品列表、聊天记录等需要处理大量数据的场景。
全栈若城
2025/03/15
760
纯血鸿蒙APP实战开发——主页瀑布流实现
本示例介绍使用ArkUI WaterFlow 组件和 LazyForEach 实现瀑布流场景。该场景多用于购物、资讯类应用。
小帅聊鸿蒙
2024/12/23
1410
67.Harmonyos NEXT 图片预览组件之性能优化策略
图片预览组件在处理大量高清图片时,性能优化显得尤为重要。本文将详细介绍图片预览组件中采用的性能优化策略,包括懒加载实现、内存管理、渲染优化等方面,帮助开发者构建高性能的图片预览功能。
全栈若城
2025/03/14
910
53. HarmonyOS NEXT 登录模块开发教程(七):性能优化与最佳实践
在前六篇教程中,我们介绍了HarmonyOS NEXT登录模块的整体架构、模态窗口的实现原理、一键登录页面的实现、短信验证码登录的实现、状态管理和数据绑定机制、安全性考虑以及UI设计和用户体验优化。本篇教程将深入讲解登录模块的性能优化和最佳实践,帮助开发者构建高效流畅的登录功能。
全栈若城
2025/03/13
1060
鸿蒙(HarmonyOS)应用性能优化实战-组件复用四板斧
在滑动场景下,常常会对同一类自定义组件的实例进行频繁的创建与销毁。此时可以考虑通过组件复用减少频繁创建与销毁的能耗。组件复用时,可能存在许多影响组件复用效率的操作,本篇文章将重点介绍如何通过组件复用四板斧提升复用性能。
小帅聊鸿蒙
2024/10/16
2100
鸿蒙(HarmonyOS)应用性能优化实战-组件复用四板斧
鸿蒙开发:一个轻盈的上拉下拉刷新组件
老早之前开源了一个刷新组件,提供了很多常见的功能,也封装了List,Grid,WaterFlow,虽然功能多,但也冗余比较多,随着时间的前去,暴露的问题就慢慢增多,虽然我也提供了通用的RefrshLayout,奈何很多人仍然有许多问题,但大部分都是相关属性以及用法的问题,对于我来说也比较苦恼,既然如此,那就只封装一个刷新加载,其它的自己实现好了,于是针对refresh的轻盈组件就剥离出来了。
程序员一鸣
2024/12/26
1500
鸿蒙开发:一个轻盈的上拉下拉刷新组件
112.HarmonyOS NEXT 跑马灯组件数据源详解:数据管理与监听机制
全栈若城
2025/03/17
820
推荐阅读
相关推荐
鸿蒙(HarmonyOS)性能优化实战-Grid高性能开发
更多 >
LV.5
这个人很懒,什么都没有留下~
目录
  • 1. 简介
  • 2. 背景
    • 2.1. 大型语言模型
    • 2.2. 提示词工程
    • 2.3. 词向量
  • 3. 使用 LangChain 构建 LLM 技术栈
  • 4. 面向 Java 的 LangChain
  • 5. LangChain 的构建模块
    • 5.1. 模型输入/输出(Models I/O)
    • 5.2. 内存
    • 5.3. 检索(Retrieval)
    • 6. LangChain 的复杂应用
      • 6.1. 链(Chains)
      • 6.2. 代理(Agents)
    • 7. 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档