gradle
Gradle
环境介绍
OpenJDK 17.0.5
Gradle 7.6
示例代码 fly-gradle
Gradle 项目下文件介绍
如果你的电脑安装了 gradle,可以使用 gradle init 去初始化一个新的 gradle 工程,然后使用电脑安装的 gradle 去执行构建命令。
但是每个开发电脑上的 gradle 版本不一样,为了统一构建环境,我们可以使用 gradle wrapper 限定项目依赖 gradle 的版本。
# 会生成 gradle/wrapper/* gradlew gradlew.bat
gradle wrapper --gradle-version7.5.1 --distribution-type bin
.
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
gradlew 和 gradlew.bat
运行项目 wrapper 下定义的 gradle 去构建项目。
gradlew 是 macos 和 linux 系统下。
gradlew.bat 是 windows 系统下使用的。
wrapper
wrapper 定义项目依赖那个版本的 gradle,如果本地 distributionPath 没有对应版本的 gradle,会自动下载对应版本的 gradle。
# gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
# 如果是国内项目,只需要修改这个url 就可以提高下载速度
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
GRADLE_USER_HOME 没有配置的话,默认是 ~/.gradle
zipStoreBase 和 zipStorePath 定义了下载的 gradle (gradle-7.6-bin.zip) 存储的本地路径。
distributionBase 和 distributionPath 定义下载的 gradle 解压的本地目录。
gradlew 实际是运行 gradle-wrapper.jar 中的 main 方法,传递给 gradlew 的参数实际上也会传递给这个 main 方法。
gradle-wrapper.jar 会判断是否下载 wrapper 配置的 gradle,并且将传递参数给下载的 gradle,并运行下载的 gralde 进行构建项目。
升级 wrapper 定义的 gradle 版本
./gradlew wrapper --gradle-version7.6
settings.gradle
pluginManagement {
repositories {
maven {
url="file://${rootDir}/maven/plugin"
}
gradlePluginPortal()
}
plugins {
// spring_boot_version 可以在 gradle.properties 配置
id'org.springframework.boot'version"${spring_boot_version}"
}
}
rootProject.name='fly-gradle'
include'user-manage-service','user-manage-sdk'
include'lib-a'
include'lib-b'
settings.gradle 主要用于配置项目名称,和包含哪些子项目。
也可以用于配置插件的依赖版本(不会应用到项目中去,除非项目应用这个插件)和插件下载的
build.gradle
build.gradle 是对某个项目的配置。配置 jar 依赖关系,定义或者引入 task 去完成项目构建。
gradle.properties
主要用于配置构建过程中用到的变量值。也可以配置一些 gradle 内置变量的值,用于修改默认构建行为。
org.gradle.logging.level=quiet
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.jvmargs=-Xms512m -Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.jvmargs 用来配置 Daemon 的 JVM 参数,默认值是 -Xmx512m "-XX:MaxMetaspaceSize=384m"。
当我们的项目比较大的时候,可能会由于 JVM 堆内存不足导致构建失败,就需要修改此配置。
org.gradle.logging.level 调整 gradle 的日志级别。参考 gradle logging 选择想要的日志级别。
Gradle Daemon
为加快项目构建,gralde 会启动一个常驻 JVM 后台进程去处理构建,Daemon 进程默认三小时过期且当内存压力大的时候也会关闭。
Gradle 默认会启用 Daemon 进程去构建项目。
# 查看 daemon 运行状态
./gradlew --status
# stop daemon 进程
./gradlew --stop
# 重启 daemon 进程
./gradlew --daemon
构建生命周期
Gradle 是基于 task 依赖关系来构建项目的,我们只需要定义 task 和 task 之间的依赖关系,Gradle 会保证 task 的执行顺序。
Gradle 在执行 task 之前会建立 Task Graphs,我们引入的插件和自己构建脚本会往这个 task graph 中添加 task。
Gradle 的构建过程分为三部分:初始化阶段、配置阶段和执行阶段。
初始化阶段
找到 settings.gradle,执行其中代码
确定有哪些项目需要构建,然后对每个项目创建 Project 对象,build.gradle 主要就是配置这个 Project 对象
// settings.gradle
rootProject.name='basic'
println'在初始化阶段执行'
配置阶段
执行 build.gradle 中的配置代码,对 Project 进行配置
执行 Task 中的配置段语句
根据请求执行的 task,建立 task graph
println '在配置阶段执行 Task 中的配置段语句'
tasks.register('configured') {
println '在配置阶段执行 Task 中的配置段语句'
doFirst {
println '在执行阶段执行'
}
doLast {
println '在执行阶段执行'
}
}
执行阶段
根据 task graph 执行 task 代码。
依赖管理
Maven 私服配置
我们一般都是多项目构建,因此只需要在父项目 build.gradle 配置 repositories。
allprojects {
repositories {
maven {
url "${mavenPublicUrl}"
credentials {
username "${mavenUsername}"
password "${mavenPassword}"
}
}
mavenLocal()
mavenCentral()
}
}
credentials 配置账号密码,当私服不需要权限下载的时候可以不配置。
Gradle 会按照配置的仓库顺序查询依赖下载。
配置依赖来自某个目录
dependencies {
compile files('lib/hacked-vendor-module.jar')
}
dependencies {
compile fileTree('lib')
}
有的时候第三方库没有 maven 供我们使用,可以使用这个。
依赖冲突
默认依赖冲突
::: tip当出现依赖冲突的时候,gradle 优先选择版本较高的,因为较高版本会兼容低版本。:::
dependencies {
implementation 'com.google.guava:guava:31.1-jre'
implementation 'com.google.code.findbugs:jsr305:3.0.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
我们可以执行下面命令查看项目依赖的版本:
./gradlew dependency-management:dependencies --configuration compileClasspath
------------------------------------------------------------
Project ':dependency-management'
------------------------------------------------------------
compileClasspath - Compile classpath for source set 'main'.
+--- org.springframework.boot:spring-boot-dependencies:3.0.2
+--- com.google.guava:guava:31.1-jre
| +--- com.google.guava:failureaccess:1.0.1
| +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
| +--- com.google.code.findbugs:jsr305:3.0.2
| +--- org.checkerframework:checker-qual:3.12.0
| +--- com.google.errorprone:error_prone_annotations:2.11.0
| \--- com.google.j2objc:j2objc-annotations:1.3
\--- com.google.code.findbugs:jsr305:3.0.0 -> 3.0.2
我们可以看到,gradle 选择了 com.google.code.findbugs:jsr305:3.0.2 这个版本。
强制使用某个版本
如果我们想使用 com.google.code.findbugs:jsr305:3.0.0 版本
dependencies {
implementation 'com.google.guava:guava:31.1-jre'
implementation 'com.google.code.findbugs:jsr305:3.0.0', {
force = true
}
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
./gradlew -q dependency-management:dependencyInsight --dependency jsr305 --configuration compileClasspath
com.google.code.findbugs:jsr305:3.0.0 (forced)
Variant compile:
| Attribute Name | Provided | Requested |
|--------------------------------|----------|--------------|
| org.gradle.status | release | |
| org.gradle.category | library | library |
| org.gradle.libraryelements | jar | classes |
| org.gradle.usage | java-api | java-api |
| org.gradle.dependency.bundling | | external |
| org.gradle.jvm.environment | | standard-jvm |
| org.gradle.jvm.version | | 17 |
com.google.code.findbugs:jsr305:3.0.0
\--- compileClasspath
com.google.code.findbugs:jsr305:3.0.2 -> 3.0.0
\--- com.google.guava:guava:31.1-jre
\--- compileClasspath
禁用依赖传递
guava 不会传递依赖它依赖的库到当前库,可以看到
dependencies {
implementation 'com.google.guava:guava:31.1-jre', {
transitive = false
}
implementation 'com.google.code.findbugs:jsr305:3.0.0'
}
./gradlew dependency-management:dependencies --configuration compileClasspath
------------------------------------------------------------
Project ':dependency-management'
------------------------------------------------------------
compileClasspath - Compile classpath for source set 'main'.
+--- org.springframework.boot:spring-boot-dependencies:3.0.2
+--- com.google.guava:guava:31.1-jre
\--- com.google.code.findbugs:jsr305:3.0.0
可以看到 guava 依赖的 jar 没有传递到当前项目中来。
排除某个依赖
Guava 依赖的别的 jar 可以传递进来,而且排除了 findbugs, 项目依赖的版本为 3.0.0。
dependencies {
implementation 'com.google.guava:guava:31.1-jre', {
exclude group: 'com.google.code.findbugs', module: 'jsr305'
}
implementation 'com.google.code.findbugs:jsr305:3.0.0'
}
./gradlew dependency-management:dependencies --configuration compileClasspath
------------------------------------------------------------
Project ':dependency-management'
------------------------------------------------------------
compileClasspath - Compile classpath for source set 'main'.
+--- org.springframework.boot:spring-boot-dependencies:3.0.2
+--- com.google.guava:guava:31.1-jre
| +--- com.google.guava:failureaccess:1.0.1
| +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
| +--- org.checkerframework:checker-qual:3.12.0
| +--- com.google.errorprone:error_prone_annotations:2.11.0
| \--- com.google.j2objc:j2objc-annotations:1.3
\--- com.google.code.findbugs:jsr305:3.0.0
可以看到 guava 传递到当前项目的依赖少了 findbugs 。
配置依赖之间继承
configurations {
integrationTestImplementation.extendsFrom testImplementation
integrationTestRuntimeOnly.extendsFrom testRuntimeOnly
}
configurations.all {
resolutionStrategy {
force 'org.apache.tomcat.embed:tomcat-embed-core:9.0.43'
}
exclude group: 'org.slf4j', module: 'slf4j-simple'
}
api 和 implementation 区别
jar b 包含一下依赖
dependencies {
api 'org.apache.commons:commons-lang3:3.12.0'
implementation 'com.google.guava:guava:31.1-jre'
}
项目 a 引入 jar b ,commons-lang3 和 guava 都可以被工程 a 使用,只是二者 scope 不一样。
api 对应 compile,在 工程 a 可以直接使用,编译可以通过。
implementation 对应 runtime,编译找不到 guava 中的类。
Task
我们引用的插件实际是添加 task 到 task graph 中去。
我们知道 build.gradle 实际是用来配置对应项目的 org.gradle.api.Project。
因此我们可以在 build.gradle 中引用 org.gradle.api.Project 暴露的属性。
我们可以在 gradle dsl 和 Project 接口中可以知道可以访问哪些属性。
tasks 实际就是 Project 暴露的一个属性,因此我们可以使用 tasks 往当前项目中注册 task。
tasks.register('hello') {
doLast {
println 'hello'
}
}
推荐使用 tasks.register 去注册 task,而不是 tasks.create 去直接创建。
tasks.register 注册的 task 只会在用到的时候才会初始化。
Groovy 闭包
Groovy Closures
{ [closureParameters -> ] statements }
闭包的示例
{ item++ }
{ -> item++ }
{ println it }
{ it -> println it }
:::tip
当方法的最后一个参数是闭包时,可以将闭包放在方法调用之后。
:::
比如注册一个 task 的接口是
register(String var1, Action<? super Task> var2)
tasks.register("task55"){
doFirst {
println "task55"
}
}
tasks.register("task66",{
doFirst {
println "task66"
}
})
Task Type
gradle 已经定义好一些 task type,我们可以使用这些 task type 帮助我们完成特定的事情。比如我们想要执行某个 shell 命令。
Exec - Gradle DSL Version 7.6
tasks.register("task3", Exec) {
workingDir "$rootDir"
commandLine "ls"
}
Plugin
插件分类
Gradle 有两种类型的插件 binary plugins and script plugins
二进制插件就是封装好的构建逻辑打成 jar 发布到线上,供别的项目使用。
脚本插件就是一个 *.gradle 文件。
buildSrc
一般我们的项目是多项目构建,各个子项目会共享一些配置,比如 java 版本,repository 还有 jar publish 到哪里等等。
我们可以将这些统一配置分组抽象为单独的插件,子项目引用这个插件即可。便于维护,不用在各个子项目都重复配置相同的东西。
buildSrc 这个目录必须在根目录下,它会被 gradle 自动识别为一个 composite build,并将其编译之后放到项目构建脚本的 classpath 下。
buildSrc 也可以写插件,我们可以直接在子项目中使用插件 id 引入。
buildSrc/
├── build.gradle
├── settings.gradle
└── src
├── main
│ ├── groovy
│ │ └── mflyyou.hello2.gradle
│ ├── java
│ │ └── com
│ │ └── mflyyou
│ │ └── plugin
│ │ ├── BinaryRepositoryExtension.java
│ │ ├── BinaryRepositoryVersionPlugin.java
│ │ └── LatestArtifactVersion.java
buildSrc/build.gradle
groovy-gradle-plugin 对应的是使用 groovy 写插件。
java-gradle-plugin 对应 java
plugins {
id 'groovy-gradle-plugin'
id 'java-gradle-plugin'
}
gradlePlugin {
plugins {
helloPlugin {
id = 'com.mflyyou.hello'
implementationClass = 'com.mflyyou.plugin.BinaryRepositoryVersionPlugin'
}
}
}
我们就可以在子项目使用插件
plugins {
id 'com.mflyyou.hello'
id 'mflyyou.hello2'
}
插件使用
Applying plugins with the plugins DSL
plugins {
id 'java'
}
Applying a plugin with the buildscript block
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5'
}
}
apply plugin: 'com.jfrog.bintray'
Applying a script plugin
apply from: 'other.gradle'
相关文章:
gradle
Gradle环境介绍OpenJDK 17.0.5Gradle 7.6示例代码 fly-gradleGradle 项目下文件介绍如果你的电脑安装了 gradle,可以使用 gradle init 去初始化一个新的 gradle 工程,然后使用电脑安装的 gradle 去执行构建命令。但是每个开发电脑上的 gradle 版本不一样…...

[牛客]链表中倒数第k个结点
使用快慢指针法:两种思路:1.fast先向后走k-1次,slow再向后走1次,然后fast和slow同时向后走,当fast走到最后一个结点时,slow刚好在倒数第k个位置上;2.fast先向后走k次,slow再向后走1次,然后fast和slow同时向后走,当fast走到最后一个结点的后面时(此时为NULL),slow刚好在倒数第k个…...
English Learning - L2 语音作业打卡 双元音 [eɪ] [aɪ] Day14 2023.3.6 周一
English Learning - L2 语音作业打卡 双元音 [eɪ] [aɪ] Day14 2023.3.6 周一💌发音小贴士:💌当日目标音发音规则/技巧:🍭 Part 1【热身练习】🍭 Part2【练习内容】🍭【练习感受】🍓元音 /eɪ/…...
C++ this 指针与静态成员
文章目录参考描述实例成员与静态成员实例成员静态成员静态成员属性隐式形参 this 指针冲突this 指针静态成员函数this 指针与静态成员函数参考 项目精通C (第九版)托尼加迪斯、朱迪沃尔特斯、戈德弗雷穆甘达 (著) / 黄刚 等 &…...

REDIS16_LRU算法概述、查看默认内存、默认是如何删除数据、缓存淘汰策略
文章目录①. LRU算法概述②. 查看默认内存③. 如何删除数据④. 缓存淘汰策略①. LRU算法概述 ①. LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的数据给予淘汰 (leetcode-cn.com/problems/lru-cache) ②. LRU算法题来源 ③.…...

ClassMix: Segmentation-Based Data Augmentation for Semi-Supervised Learning学习笔记
ClassMix相关介绍主要思想方法Mean-Teacher损失函数交叉熵损失标签污染实验实验反思参考资料相关介绍 从DAFormer溯源到这篇文章,ClassMix主要是集合了伪标签和一致性正则化,思想来源于CutMix那条研究路线,但是优化了CutMix中的标签污染的情…...
CSDN竞赛第35期题解
CSDN竞赛第35期题解 1、题目名称:交换后的or 给定两组长度为n的二进制串,请问有多少种方法在第一个串中交换两个不同位置上的数字,使得这两个二进制串“或”的 结果发生改变? int n;cin>>n; string a,b;cin>>a>…...

Java应用服务系统安全性,签名和验签浅析
1 前言 随着互联网的普及,分布式服务部署越来越流行,服务之间通信的安全性也是越来越值得关注。这里,笔者把应用与服务之间通信时,进行的的安全性相关,加签与验签,进行了一个简单的记录。 2 安全性痛点 …...

spring中bean的实例化
构造方法实现实例化 无参构造器实例化 我们之前用的就一直是无参构造器实现实例化,虽然没有在类中写构造器,但是每个类都会有一个默认的无参构造器 有参构造器实例化 相比于无参构造器,我们只需要传入参数就可以了 我们可以通过construc…...

磨皮插件portraiture2023最新中文版
Portraiture滤镜是一款 Photoshop,Lightroom 和 Aperture 插件,DobeLighttroom 的 Portraiture 消除了选择性掩蔽和逐像素处理的繁琐的手工劳动,以帮助您在肖像修整方面取得卓越的效果。它是一个强大的,但用户友好的插件照明.这是…...
记录每日LeetCode 2269.找到一个数组的K美丽值 Java实现
题目描述: 一个整数 num 的 k 美丽值定义为 num 中符合以下条件的 子字符串 数目: 子字符串长度为 k 。 子字符串能整除 num 。 给你整数 num 和 k ,请你返回 num 的 k 美丽值。 注意: 允许有 前缀 0 。 0 不能整除任何…...

代码管理--svnadmin工具介绍
1、简介 SVNAdmin2 是一款通过图形界面管理服务端SVN的web程序。正常情况下配置SVN仓库的人员权限需要登录到服务器手动修改 authz 和 passwd 两个文件,当仓库结构和人员权限上了规模后,手动管理就变的非常容易出错,本系统能够识别人员和权限…...

Git的基本使用以及上传到GitHub
GIT的基本使用一、安装并配置GIT二、Git的基本操作三、使用GIT上传至GitHub四、Git分支一、安装并配置GIT 1.安装GIT连接 GIT安装包链接 2.打开GIT 鼠标右键点击Git Bash Here 安装完 Git 之后,第一件事就是设置自己的用户名和邮件地址。因为通过 Git 对项目进行…...

国科大论文latex模板中可能的注意事项
背景 国科大2022年9月发布了毕业论文的LaTeX模板,它是在ucasthesis上修改而来的,但近日使用国科大发布版本时发现有几点不同以及需要注意的地方。本人只会简单使用latex,但并不熟悉latex样式编辑,因此以下介绍与方法仅供参考。仅…...

ABAP 怎样将XML和JSON格式转换为HTML格式显示
ABAP 怎样将XML和JSON格式转换为HTML格式显示 一、将JSON格式转换为HTML格式 BAP接口程序开发中时常会用到JSON格式来传输数据,在监控传输的JSON串内容时,把JSON转换为HTML格式来显示会很便利。下面提供一个简单例子来实现JSON转化为HTML并显示的功能。…...
基础课DP
DP 背包问题01背包问题完全背包问题多重背包问题多重背包问题II分组背包问题线性DP数字三角形最长上升子序列最长上升子序列II最长公共子序列编组距离区间DP石子合并计数类DP整数划分数位统计DP计数问题状态压缩DP蒙德里安的梦想最短Ha路径树形DP没有上司的舞会...

基于支持向量机SVM的风电场NWP数据预测,SVM的详细原理
目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 SVM应用实例,基于SVM的风电场NWP预测 结果分析 展望 支持向量机SVM的详细原理 SVM的定义 支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定…...

webRtc概念
webRtc概念 以下的文档整理来自此链接 文档整理了一系列实现web通用接口的ECMAScript APIs ,这些接口是为了支持浏览器或者一些其他实现了实时交换协议的设备进行媒体信息和程序数据交换。 1、实现点对点通信的规范: NAT穿透实现与远端节点链接比如&a…...

数据结构与算法基础(王卓)(16):KMP算法详解(代码实现)
实现代码的过程中 具体细节、问题: (1):关于写Get_next函数的标题: 现象: PPT上写的是: void get_next(SString T, int &next[]) 然而并不能运行,而当我们去掉了引用符号&…...

九龙证券|盘前直接腰斩,银行巨头紧急“拔网线”!美股银行股又崩了?
见证历史了,又有一家银行巨子倒下? 美股银行股团体暴降 上一交易日暴降超60%的硅谷银行持续面对腥风血雨。盘前,硅谷银行跌幅超50%,随后,公司宣布盘前暂停交易,等待刊发消息。 而最新消息显现,…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...