LangChain4j 框架探索

news2025/3/12 17:37:24

LangChain4j 框架探索

  • Get Started
  • 核心概念1 - Message
  • 核心概念2 - Model
  • 核心概念3 - Ai Services
  • 核心概念4 - Structured Output
  • 核心概念5 - Chat Memory
  • 核心概念6 - Tool (Function Calling)
  • 核心概念7 - RAG(Retrieval-Augmented Generation)
    • 核心 RAG APIs
    • 使用示例
  • 总结

Get Started

Python: LangChain 官方文档

在这里插入图片描述

Java: LangChain4j 官方文档

在这里插入图片描述

Langchain4j 是 Langchain 这一 LLM 实现的java版本,更广为人知的可能是 python 版本的Langchain 实现,因此我这里拿出 python 版 Langchain 的官方页面和 Langchain4j 的官方文档做对比。
可以从对比中看出,python 版本强调的几个关键特性 langchain4j 都复刻出来了,其中我比较关注的是 AI Services、Tools、RAG 这几个高级功能的实现,其次是 ChatModel、Structured Output、Chat Memory 这些基础功能的实现。下图是官方给出的 Langchain4j 框架结构图:

在这里插入图片描述

集成情况
这里也列一下官方给出的对于各类大模型提供方 (providers)、向量存储、嵌入模型 (embedding)、图片生成模型、评分模型等的集成情况:
15+ LLM providers
20+ embedding (vector) stores
15+ embedding models
5 image generation models
2 scoring (re-ranking) models
1 moderation model (OpenAI)

集成方法

# build.gradle
implementation 'dev.langchain4j:langchain4j'
implementation 'dev.langchain4j:langchain4j-open-ai' 
implementation 'dev.langchain4j:langchain4j-ollama' 
implementation 'dev.langchain4j:langchain4j-easy-rag'

其中 langchain4j 库是核心库;
langchain4j-open-ai 和 langchain4j-ollama 分别用于集成openai和ollama的官方接口;
langchain4j-easy-rag 用于实现 RAG 检索增强生成;

接下来,我会对 Langchain4j 中最值得关注的几大特性逐一谈谈我对特性的理解以及在实践中的收获。

核心概念1 - Message

在这里插入图片描述

Message 很好理解,就是各类消息实体,从 Langchain4j 的实现来看,分为了 AiMessage、SystemMessage、ToolExecutionResultMessage、UserMessage 这四类消息。
在实践中发现,SystemMessage、UserMessage 这两类是暴露给开发者使用的,可以用相关注解(@SystemMessage、@UserMessage)将对应类型的提示语注入到 Agent 上下文中,具体例子可以在下文 Ai Services 部分提到;
AiMessage、ToolExecutionResultMessage 则是给各类大模型的实现使用的,通常作为大模型 API 的返回,其中 ToolExecutionResultMessage 又和 Tool 特性相关;
除此以外,和 Message 紧密相关的 Chat Memory 中也提供了一些方法来操作这些 Message,这在 Chat Memory 部分也会提到。

核心概念2 - Model

在这里插入图片描述

Model 则是上面提到的大模型实现。可以从上图看出,ChatLanguageModel 接口的实现都是定义在单独的依赖包中的,这是因为每种大模型的使用方式均有区别,比如 ollama 是基于本地的,openai 是需要 apikey 的,其他区别还有很多。
除此以外,还有 ImageModel 接口用于实现各类图片生成模型,嵌入模型和评分模型等的接口这里先不做介绍了。

核心概念3 - Ai Services

Ai Services for Java 类似于 python LangChain 的 Chains 特性。
我的理解:Ai Services 作为 Agent 代理对象,可以作为 Tool、RAG等高级 API 功能的入口。

public interface Assistant {
   @SystemMessage({
           "你是一个AI助手, 默认使用中文对话, 所有系统消息中:\n" +
                   "IF-ELSE 语句用于设置提示语策略的生效场景, \n" +
                   "INPUT 用于描述输入, \n" +
                   "OUTPUT 用于描述返回要求, \n" +
                   "CONDITION 用于描述附加条件, \n" +
                   "AND/OR/NOT 用于表示与/或/非的逻辑判断",
           "IF USER INPUT `如何使用机器人` OR `如何使用AI Bot`等相关问题 ELSE YOU OUTPUT 如下帮助文档:\n" +
                   "```\n" +
                   "1) \\gpt start [-s|-g]: 开始会话, 可选选项 -s 用于启用严格模式(@机器人 触发), -g 用于启用群聊模式\n" +
                   "2) \\gpt end: 结束会话\n" +
                   "3) \\gpt clear: 清空会话记录\n" +
                   "4) #image + 文本: 图片生成请求,需要在会话中执行才可生效\n" +
                   "```",
           "现在的时间是:{{current_time}}"
   })
   String chat(@MemoryId @UserName String userName, @UserMessage String message, @V("current_time") LocalDateTime time);
}

这是我 DEMO 中一个通用 AiService 的定义,它的一个基本功能就是可以用方法注解定义一些提示语,我这里规定了一些提示词规范和机器人指令;
Langchain4j 定义了一些注解支持方法将对象参数序列化到 prompt 中,比如上面的 Assistant 中:
@MemoryId - 配合 ChatMemory 使用,标记该参数作为 ChatMemory 聊天上下文缓存中区分用户的唯一ID;
@Username - 标记该参数为 用户名,帮助 AiService 识别不用用户,但本身不具备多轮记忆,用这个注解可以简单理解为告诉AI你是谁;
@UserMessage - 标记该参数是用户当前要发的消息,除了作为参数注解,该注解也可以作为方法注解适用于更加灵活的场景中;

更通用的,还有:
@V(“xxx”) - 很好理解的,这是一个别名注解,配合它可以在方法注解 @SystemMessage 中使用{{}} 双括号作为变量拼接到系统消息提示语中,此外也可以@UserMessage等其他方法注解中,通过这种方式可以灵活的给AI输入各种结构化信息。

Assistant 的使用方法如下:

Assistant assistant = AiServices.builder(Assistant.class)
       .chatLanguageModel(chatModel)
       .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(100))
       .build();
assistant.chat("test", "hello", LocalDateTime.now());

它使用 builder 模式初始化必要的属性,chatModel 属性通常是必须的,如果想要启用聊天上下文(即 Chat Memory),则还需要配置 chatMemoryProvider,其他与关键特性相关的属性还有 tools、retrievalAugmentor(RAG 相关)等,这里不做赘述。

核心概念4 - Structured Output

结构化输出对于LLM框架来说意义非凡,这个特性赋予了AI模型与代码逻辑层准确交互的能力,将AI模型输出的人类语言处理成面向对象程序可以理解的信息,在NLP领域的分支——信息抽取任务中 LLM 框架的结构化转换能力可谓遥遥领先;

在 Langchain4j 框架中,结合Java面向对象的特性,框架实现了 AiService 根据返回的消息自动解析为 AiService 中的方法入口的返回参数类型的能力,举例如下:

// Ai Service 定义 route 方法并返回 RouterType 枚举类型
public interface Router {
    @UserMessage("判断 `{{message}}` 与哪种类型相关, 必须返回其中一种:{{types}}")
    RouterType route(@UserName String userName, @V("message") String message, @V("types") Map<String, String> types);
}
// RouterType 枚举类定义
public enum RouterType {
    @Description("天气、新闻、微博热搜等实时信息")
    TIME,
    @Description("以 #image 开头、绘画 或 生成图片")
    IMAGE,
    @Description("和以上类型都无关")
    OTHER;
    @Getter
    private static final Map<String, String> descriptions = Arrays.stream(values())
                .collect(Collectors.toMap(RouterType::name, RouterType::getDescription));

    private static String getDescription(RouterType routerType) {
        try {
            java.lang.Class<RouterType> clazz = RouterType.class;
            java.lang.reflect.Field field = clazz.getField(routerType.name());
            Description description = field.getAnnotation(Description.class);
            return description != null ? description.value()[0] : "";
        } catch (NoSuchFieldException | SecurityException e) {
            return "";
        }
    }
}
// Ai Service 方法使用并返回枚举类对象
ChatLanguageModel chatModel = ModelFactory.buildchatModel(config);
Router tester = Aiservices.builder(Router.class).chatLanguageModel(chatModel).build();
tester.route("test", "现在是几点", RouterType.getDescriptions());// TIME
tester.route("test", "画一杯咖啡", RouterType.getDescriptions()) //IMAGE

该例子中我使用枚举类型 RouterType 作为 Router::route 方法的返回参数,LLM 会根据我提供的message判断属于 RouterType 中的哪一种类型。值得一提的是,@Description注解虽然可以帮助AI理解当前枚举值的含义,但并非必须的,框架默认会根据枚举值的字符串分析其含义;
除此以外,在实战中有一点发现,虽然我给 RouterType 提供了 OTHER 值作为异常情况的返回,但这并不总是成功的,比如我输入一段随机乱写的字符,它可能会报 “不存在符合 XXX值 的 RouterType 枚举值” 的类似错误,所以其解析逻辑依旧存在无法处理的边界情况,针对这一问题,我将 RouterType.getAll() 作为输入,提高了其识别枚举类型的能力,除此以外,也可以用捕获异常并返回 OTHER 的方式增强其处理能力,可视具体情况而定。

当然,枚举类型是Java对象中比较特殊的一类,结合枚举类型的返回值,可以实现类似于NLP领域中的多标签分类任务的功能,这可以帮助我们实现路由、映射等功能。

对于Java中的一般POJO对象,框架也可以实现类似功能,更多场景和尝试大家可以尽情探索。。。

核心概念5 - Chat Memory

顾名思义,Chat Memory 这一特性实现了对消息上下文的管理。
在这里插入图片描述
在这里插入图片描述

上面两个接口是 Chat Memory 相关的关键接口,ChatMemory 用于实现对 ChatMessage 列表的上下文管理,即用于实现不同用户拥有不同的 ChatMemory,可以看到它有一个 id 属性就是这个用途。有一点值得注意,为了实现这个功能,需要在 AiService 的方法参数中通过 @MemoryId 注解来关联,具体示例可以参考上文 Ai Services 部分给出的 Assistant 的 chat 方法定义。
而 ChatMessageStore 用于实现 ChatMessage 列表的存储管理,它在核心库的默认实现是 InMemoryChatMemoryStore,即存储在内存当中,当然也有其他存储方案的实现。

核心概念6 - Tool (Function Calling)

// Tool 定义
public class WebPageTool {
    @Tool("IF USER INPUT `热搜、头条` 等新闻话题 ELSE YOU OUTPUT `序号) 热搜标题` CONDITION 每条热搜需要换行")
    public String getNews(@ToolMemoryId String userName,
                             @P("关键字:比如 微博热搜、今日头条、每日新闻") String keyword) {
        return WeiBoCrawler.crawlWeiboTops();
    }

    @Tool("IF USER INPUT `time-sensitive (recent or newest) question`, ELSE YOU search from web")
    public String getWebPage(@ToolMemoryId String userName,
                             @P("The origin query") String query,
                             @P("Name of the search engine: [baidu, bing, 360, sogou, quark]") String engine) {
        return SearchCrawler.crawlFromEngine(engine, query);
    }
}
// Tool 使用
Assistant assistant = AiServices.builder(Assistant.class)
                .chatLanguageModel(chatModel)
                .tools(new WebPageTool())
                .chatMemoryProvider(memoryId -> messageService.buildChatMemory(userName))
                .build();

Tool 特性允许 LLM 在必要时调用一个或多个可用的自定义工具方法。Tool 的使用场景通常有:网络搜索、对外部 API 的调用或特定代码段的执行等。
需要注意的是,LLM 框架本身是不具备判断 Tool 是否需要执行或者需要执行哪些 Tool 的逻辑的,这块功能由 大模型提供方 实现,也就是说如果一个 模型(比如gpt-3.5-turbo)不具备 Tool 能力,那我们提供的 Tool 就不会生效;相反,只有选择支持 Tool 的模型(比如 gpt-4o-mini)才能从接口返回中解析得到 ToolExecutionResultMessage,告诉我们需要执行哪些 Tool。

在实践中也发现,由于 Tool 功能依赖于具体模型是否支持,我们可以采取降级方案,比如使用 RAG router 或者 使用一个 返回类型为枚举类型的 Ai Service 帮助我们 route 到对应方法上,在本文 Ai Service 部分和 RAG 部分的例子中均有对应例子。

核心概念7 - RAG(Retrieval-Augmented Generation)

检索增强生成 是一种结合了信息检索和语言生成技术的方法。LLM的知识仅限于其所训练的数据,而 RAG 可以让LLM了解特定领域的知识或专有数据。
简而言之,RAG 是一种在问题发送到 LLM 之前从数据中查找相关信息并将其注入到提示语中的方法。这样, LLM 将获得相关信息,并能够使用这些信息进行回复,这应该会减少产生幻觉的可能性。
目前主流的检索方案有 Full-text(全文)检索(或关键字检索)、Vector(向量)检索(或语义检索)以及 组合多种方法的方案。

RAG 过程分为 2 个不同的阶段:索引和检索。 LangChain4j 为这两个阶段提供了工具。

索引阶段简要流程:
在这里插入图片描述

索引阶段简要流程:
在这里插入图片描述

核心 RAG APIs

Document: 表示一个文档,例如单个 PDF 文件或网页,目前只支持表示文本信息;
Metadata:描述 Document 元信息的类,,例如其名称、来源、更新日期等;
Document Loader:文档加载器,针对不同文档类型和来源有很多实现;
Document Parser:文档解析器,用于解析 PDF、DOC、TXT 等多种格式的文档,通常配合 Document Loader 使用;
Document Transformer:可以执行各种文档转换,例如 清理、过滤、丰富、摘要等等;
Text Segment:文本段,由 Document 分割出的更小的段,只包含文本信息;
Document Splitter: 文件分割器,用于 Document 分割成 Text Segment;
Text Segment Transformer:文本段转换器,类似于DocumentTransformer,没有具体实现;
Embedding:封装了一个向量,表示已嵌入内容的“语义含义”;
Embedding Model:嵌入模型,用于将文本转换为 Embedding;
Embedding Store:嵌入存储,也称为向量数据库;
Embedding Store Ingestor:嵌入存储摄取器,代表一个摄取管道,负责将 Document 摄取到 EmbeddingStore 中。

使用示例

public String searchDialog(GptSession session, String userMsg) {
   EmbeddingModel embeddingModel = new BgeSmallEnV15QuantizedEmbeddingModel();
   InMemoryEmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
   ContentRetriever embeddingStoreContentRetriever = EmbeddingStoreContentRetriever.builder()
           .embeddingStore(embeddingStore)
           .embeddingModel(embeddingModel)
           .maxResults(2)
           .minScore(0.6)
           .build();
   WebSearchEngine webSearchEngine = TavilyWebSearchEngine.builder()
           .apiKey(ConfigUtil.getConfig("tavily.key")) // get a free key: https://app.tavily.com/sign-in
           .build();
   ContentRetriever webSearchContentRetriever = WebSearchContentRetriever.builder()
           .webSearchEngine(webSearchEngine)
           .maxResults(3)
           .build();
   QueryRouter queryRouter = new DefaultQueryRouter(embeddingStoreContentRetriever, webSearchContentRetriever);
   RetrievalAugmentor retrievalAugmentor = DefaultRetrievalAugmentor.builder()
           .queryRouter(queryRouter)
           .build();

   ChatLanguageModel chatModel = session.getChatModel();
   String userName = session.getUserName();
   Assistant assistant = AiServices.builder(Assistant.class)
           .chatLanguageModel(chatModel)
           .retrievalAugmentor(retrievalAugmentor)
           .chatMemoryProvider(memoryId -> messageService.buildChatMemory(userName))
           .build();
   return assistant.chat(session.getShortName(), userMsg);
}

以上这段代码中就实现了一个比较经典的RAG高级用法,即通过 QueryRouter 组合了一个 EmbeddingStoreContentRetriever 和一个 WebSearchContentRetriever,QueryRouter 决定是走向量检索还是网络检索,流程图如下:
在这里插入图片描述

总结

Langchain for java 的框架探索中,Langchain 的结构化特性 将 AI 的灵活开放特性 和 Java 开发友好的面向对象特性 结合起来,这点引起极大舒适;
从和 python 版本的对比看来,Langchain4j 在实现时加入了自己的思考,并不是照抄照搬,值得肯定;
在具体的开发实践中,我从最初接触时的 0.32 过渡到了 最新的 0.36 版本,能感受到框架实现是越来越成熟的,对各类模型的集成和更新也是能跟上最新技术变革和变动的;
开发细节上,框架通过 Ai Services 集中整合各类特性,降低了上手难度,但相应的可能会放弃一些特性模块之间的独立性,相信框架维护者是有自己的考量的。
总之,难以否认的是,目前 AI 生态还是 python 这边优势更大,但是 Langchain4j 框架也算是为Java 开发者们的 AI 探索之路点燃了一把火炬。
最后附上我的实战 DEMO: https://github.com/PengfeiMiao/ichat, 感兴趣的小伙伴可以来看看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2271502.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

区块链安全常见的攻击分析——Unprotected callback - ERC721 SafeMint reentrancy【8】

区块链安全常见的攻击分析——Unprotected callback - ERC721 SafeMint reentrancy【8】 1.1 漏洞分析1.2 漏洞合约1.3 攻击分析1.4 攻击合约 重点&#xff1a;MaxMint721 漏洞合约的 mint 函数调用了 ERC721 合约中的 _checkOnERC721Received 函数&#xff0c;触发 to 地址中实…

特殊版的专业工具,支持批量处理!

今天给大家推荐一个图片压缩的软件&#xff0c;这个软件最厉害的地方在于它是一个无损压缩软件&#xff0c;十分好用&#xff0c;强烈推荐给大家。 Caesium Image Compressor 图片压缩 Caesium Image Compressor是可以保证图片原有画质不变的前提下&#xff0c;对图片进行无损…

ESP32-C3环境搭建

参考第二讲 ubuntu下的ESP-IDF开发环境搭建_哔哩哔哩_bilibili 宸芯IOT中的资料搭建 因为我买的板子是ESP32C3&#xff0c;所以没有完全按照教程去设置环境&#xff0c;但是也成功。 一、下载ubuntu系统以及esp-idf https://cn.ubuntu.com/download/server/step1 在以上链接…

使用Apache Mahout制作 推荐引擎

目录 创建工程 基本概念 关键概念 基于用户与基于项目的分析 计算相似度的方法 协同过滤 基于内容的过滤 混合方法 创建一个推荐引擎 图书评分数据集 加载数据 从文件加载数据 从数据库加载数据 内存数据库 协同过滤 基于用户的过滤 基于项目的过滤 添加自定…

提升汽车金融租赁系统的效率与风险管理策略探讨

内容概要 在汽车金融租赁系统这个复杂的生态中&#xff0c;提升整体效率是每个企业都渴望达成的目标。首先&#xff0c;优化业务流程是实现高效运行的基础。通过分析目前的流程&#xff0c;找出冗余环节并进行简化&#xff0c;能够帮助企业缩短审批时间&#xff0c;提高客户满…

3、蓝牙打印机按键 - GPIO输入控制

1、硬件 1.1、看原理图 初始高电平&#xff0c;按键按下导通处于低电平状态。 PB8号引脚。 1.2、看手册 a、看系统架构 GPIOB号端口有APB2总线控制 b、RCC使能 RCC->APB2ENR的第3位控制GPIOB使能。 c、GPIOB寄存器配置 浮空输入模式下&#xff0c;I/O的电平状态是不确定…

1.C语言教程:历史、特点、版本与入门示例

目录 1.历史2.特点3.版本4.编译5.Hello World 示例 1.历史 本篇原文为&#xff1a;C语言教程&#xff1a;历史、特点、版本与入门示例。 更多C进阶、rust、python、逆向等等教程&#xff0c;可去此站查看&#xff1a;酷程网 C 语言的诞生源于 Unix 系统的开发需求。 1969 年…

基层医联体医院患者历史检验检查数据的快速Python编程分析

​​​​​​​ 一、引言 1.1 研究背景与意义 在当今数字化医疗时代,医疗数据呈爆炸式增长,涵盖患者的基本信息、病史、检验检查结果、治疗方案等各个维度。这些海量且复杂的数据蕴含着巨大价值,为精准医疗决策提供了关键依据。通过对患者历史检验检查数据的深入对比分析…

智慧工地解决方案 1

建设背景与挑战 工地施工现场环境复杂&#xff0c;人员管理难度大&#xff0c;多工种交叉作业导致管理混乱&#xff0c;事故频发。传统管理方式难以实现科学、有效、集中式的管理&#xff0c;特别是在环境复杂、地点分散的情况下&#xff0c;监管困难&#xff0c;取证复杂。施…

笔上云世界微服务版

目录 一、项目背景 二、项目功能 一功能介绍 三、环境准备 • 需要开发的端口 • Mysql 导入数据库 ​编辑 • Redis ​编辑 • RabbitMQ ​编辑 在创建blog虚拟主机(方法如下) • Nacos • Nginx 四、前端部署 五、后端部署 六、测试计划操作 一功能测试 二…

SQL Server 数据库 忘记密码

1、先用windows 身份验证 连接 2、安全性--登录名 3、设置 身份验证 4、重启电脑 5、登录 登陆成功!!! ------------------------------------------------------------------ --1、查询登录账号信息 ------------------------------------------------------------------ -- …

windows安装并配置Maven

Maven官网下载 https://maven.apache.org 将下载好的解压到自己想要存放的路径中&#xff08;路径中不要有中文或者影响环境的字符&#xff09; 在此目录内新建一个名为repository的文件夹&#xff0c;此文件的目的是作为本地Maven的仓库来使用 配置环境变量 按下windows加r键…

Huginn - 构建代理、执行自动化任务

文章目录 一、关于 Huginn什么是Huginn&#xff1f;Huginn 功能加入Huginn展示 二、安装1、Docker2、本地安装3、开发 三、使用Huginn代理gems四、部署1、Heroku2、OpenShiftOpenShift 在线 3、在任何服务器上手动安装4、可选设置4.1 私人开发设置4.2 启用WeatherAgent4.3 禁用…

Android Glide判断当前运行环境是否为主线程的工具方法,Kotlin

Android Glide判断当前运行环境是否为主线程的工具方法&#xff0c;Kotlin private fun assertMainThread() {if (!isOnMainThread()) {throw IllegalArgumentException("You must call this method on the main thread");}}private fun isOnMainThread(): Boolean {…

Visual Point Cloud Forecasting enables Scalable Autonomous Driving——点云论文阅读(12)

此内容是论文总结,重点看思路!! 文章概述 这篇文章介绍了一个名为 ViDAR 的视觉点云预测框架,它通过预测历史视觉输入生成未来点云,作为自动驾驶的预训练任务。ViDAR 集成了语义、三维几何和时间动态信息,有效提升了感知、预测和规划等自动驾驶核心任务的性能。实验表明…

MacBook_Xcode_Swift雨燕

Swift Swift Swift Swift是苹果公司开发的现代化编程语言&#xff0c; 专为Apple平台设计。其简洁语法、类型安全、Optionals处理、Playgrounds交互式环境、泛型编程、协议与扩展、闭包功能、枚举与关联值、结构体与类的高效内存管理、异步编程的async/await语法、Swift Packa…

STM32完全学习——使用LIBJPEG库解码图片

一、有关配置 这个库的移植可以说是&#xff0c;很简单&#xff0c;直接使用CubMAX工具就可以帮我们生成移植好的代码&#xff0c;如果你想移植到其他平台&#xff0c;将CubMAX生成的那几个文件拷到你的工程里面就可以了。主要是这个如何使用起来&#xff0c;其实也不难&#…

验证码识别插件 - captcha-killer

验证码识别插件 - captcha-killer 简介 captcha-killer 是一款用于 Burpsuite 的验证码识别插件。它的主要功能是调用各种验证码识别接口&#xff0c;以便在进行渗透测试时能够自动识别和绕过验证码。这个插件本身并不直接进行验证码的识别&#xff0c;而是通过调用外部的 OC…

unity团结云下载项目

今天开plastic scm发现它云服务好像停了哈&#xff0c;在hub里下载云端项目也不会出现在项目列表里&#xff0c;之前也有发邮件说让提前迁移到团结云。打开云仓库会弹这个&#xff0c;大概就是plastic scm无法解析域名地址吧 研究了一下团结云咋使&#xff0c;官方手册看半天也…

【VUE】使用create-vue快速创建一个vue + vite +vue-route 等其他查看的工程

create-vue 简介 GitHub:https://github.com/vuejs/create-vue 创建的选项有多个,具体的可以看下方截图,当创建完成的时候可以发现工程中是自带vite的。 下面对其中的各种内容进行简单的说明 JSX (可以选择,但是我感觉没什么必要) 全称:JavaScript XML 允许你在 Java…