koanf

koanf

Go语言灵活多源配置管理库

koanf是一个Go语言多源配置管理库,支持从文件、命令行、环境变量等多种来源读取配置。它可解析JSON、YAML、TOML等格式,提供清晰抽象和良好扩展性。koanf依赖少,易于集成自定义解析器和提供者,适合需要灵活配置管理的Go项目使用。

koanfGo配置管理JSON解析YAML解析Github开源项目

<a href="https://zerodha.tech"><img src="https://yellow-cdn.veclightyear.com/835a84d5/2856d3f4-25e8-470d-8c1e-5fd0e6e733d4.svg" align="right" /></a>

koanf

koanf 是一个用于在 Go 应用程序中从不同来源读取不同格式配置的库。它是 spf13/viper 的替代方案,更加简洁、轻量,具有更好的抽象和可扩展性,依赖项也更少。

koanf v2 有多个模块(Providers)用于从各种来源读取配置,如文件、命令行标志、环境变量、Vault 和 S3,以及用于解析(Parsers)JSON、YAML、TOML、Hashicorp HCL 等格式。它很容易插入自定义解析器和提供者。

providers 和 parsers 中的所有外部依赖都与核心分离,可以根据需要单独安装。

运行测试 GoDoc

安装

# 安装核心库 go get -u github.com/knadh/koanf/v2 # 安装必要的 Provider(s) # 可用的有:file, env, posflag, basicflag, confmap, rawbytes, # structs, fs, s3, appconfig/v2, consul/v2, etcd/v2, vault/v2, parameterstore/v2 # 例如:go get -u github.com/knadh/koanf/providers/s3 # 例如:go get -u github.com/knadh/koanf/providers/consul/v2 go get -u github.com/knadh/koanf/providers/file # 安装必要的 Parser(s) # 可用的有:toml, toml/v2, json, yaml, dotenv, hcl, hjson, nestedtext # go get -u github.com/knadh/koanf/parsers/$parser go get -u github.com/knadh/koanf/parsers/toml

查看所有内置 Providers 和 Parsers 的列表。

目录

概念

  • koanf.Provider 是一个通用接口,提供配置,例如从文件、环境变量、HTTP 源或任何地方。配置可以是解析器可以解析的原始字节,也可以是可以直接加载的嵌套 map[string]interface{}
  • koanf.Parser 是一个通用接口,接收原始字节,解析并返回嵌套的 map[string]interface{}。例如 JSON 和 YAML 解析器。
  • 一旦加载到 koanf 中,配置值可以通过分隔的键路径语法进行查询。例如:app.server.port。可以选择任何分隔符。
  • 可以从多个来源加载配置并合并到一个 koanf 实例中,例如,先从文件加载,然后用命令行标志覆盖某些值。

通过这两个接口实现,koanf 可以从任何来源获取任何格式的配置,解析它,并使其可用于应用程序。

从文件读取配置

package main import ( "fmt" "log" "github.com/knadh/koanf/v2" "github.com/knadh/koanf/parsers/json" "github.com/knadh/koanf/parsers/yaml" "github.com/knadh/koanf/providers/file" ) // 全局 koanf 实例。使用 "." 作为键路径分隔符。这可以是 "/" 或任何字符。 var k = koanf.New(".") func main() { // 加载 JSON 配置 if err := k.Load(file.Provider("mock/mock.json"), json.Parser()); err != nil { log.Fatalf("加载配置错误:%v", err) } // 加载 YAML 配置并合并到之前加载的配置中(因为我们可以这样做) k.Load(file.Provider("mock/mock.yml"), yaml.Parser()) fmt.Println("父级的名称是 = ", k.String("parent1.name")) fmt.Println("父级的 ID 是 = ", k.Int("parent1.id")) }

监视文件变化

一些提供者暴露了 Watch() 方法,使提供者能够监视配置变化并触发回调以重新加载配置。 如果在 koanf 对象执行 Load() 时有并发的 *Get() 调用发生,这不是线程安全的。这种情况需要互斥锁定。

file, appconfig, vault, consul 提供者都有 Watch() 方法。

package main import ( "fmt" "log" "github.com/knadh/koanf/v2" "github.com/knadh/koanf/parsers/json" "github.com/knadh/koanf/parsers/yaml" "github.com/knadh/koanf/providers/file" ) // 全局 koanf 实例。使用 "." 作为键路径分隔符。这可以是 "/" 或任何字符。 var k = koanf.New(".") func main() { // 加载 JSON 配置 f := file.Provider("mock/mock.json") if err := k.Load(f, json.Parser()); err != nil { log.Fatalf("加载配置错误:%v", err) } // 加载 YAML 配置并合并到之前加载的配置中(因为我们可以这样做) k.Load(file.Provider("mock/mock.yml"), yaml.Parser()) fmt.Println("父级的名称是 = ", k.String("parent1.name")) fmt.Println("父级的 ID 是 = ", k.Int("parent1.id")) // 监视文件并在变化时获得回调。回调可以执行任何操作, // 比如重新加载配置。 // 文件提供者总是返回一个 nil `event`。 f.Watch(func(event interface{}, err error) { if err != nil { log.Printf("监视错误:%v", err) return } // 丢弃旧配置并加载新副本。 log.Println("配置已更改。正在重新加载...") k = koanf.New(".") k.Load(f, json.Parser()) k.Print() }) // 要停止文件监视器,调用: // f.Unwatch() // 永久阻塞(并手动对 mock/mock.json 进行更改)以 // 重新加载配置。 log.Println("永久等待中。尝试对 mock/mock.json 进行更改以实时重新加载") <-make(chan bool) }

从命令行读取

以下示例展示了 posflag.Provider 的使用,它是 spf13/pflag 库的包装器,这是一个高级命令行库。对于 Go 内置的 flag 包,使用 basicflag.Provider

package main import ( "fmt" "log" "os" "github.com/knadh/koanf/v2" "github.com/knadh/koanf/parsers/toml" // TOML 版本 2 可在以下位置获得: // "github.com/knadh/koanf/parsers/toml/v2" "github.com/knadh/koanf/providers/file" "github.com/knadh/koanf/providers/posflag" flag "github.com/spf13/pflag" ) // 全局 koanf 实例。使用 "." 作为键路径分隔符。这可以是 "/" 或任何字符。 var k = koanf.New(".") func main() { // 使用符合 POSIX 标准的 pflag 库代替 Go 的 flag 库。 f := flag.NewFlagSet("config", flag.ContinueOnError) f.Usage = func() { fmt.Println(f.FlagUsages()) os.Exit(0) } // 要加载到 koanf 中的一个或多个配置文件的路径以及一些配置参数。 f.StringSlice("conf", []string{"mock/mock.toml"}, "一个或多个 .toml 配置文件的路径") f.String("time", "2020-01-01", "时间字符串") f.String("type", "xxx", "应用程序类型") f.Parse(os.Args[1:]) ```go // 加载命令行中提供的配置文件。 cFiles, _ := f.GetStringSlice("conf") for _, c := range cFiles { if err := k.Load(file.Provider(c), toml.Parser()); err != nil { log.Fatalf("加载文件出错: %v", err) } } // "time"和"type"可能已从配置文件加载,但它们 // 仍可以被命令行中的值覆盖。 // 内置的posflag.Provider接收来自spf13/pflag库的flagset。 // 将Koanf实例传递给posflag有助于处理默认命令行标志值, // 这些值在之前加载的提供程序的conf映射中可能不存在。 if err := k.Load(posflag.Provider(f, ".", k), nil); err != nil { log.Fatalf("加载配置出错: %v", err) } fmt.Println("time是 = ", k.String("time")) }

读取环境变量

package main import ( "fmt" "log" "strings" "github.com/knadh/koanf/v2" "github.com/knadh/koanf/parsers/json" "github.com/knadh/koanf/providers/env" "github.com/knadh/koanf/providers/file" ) // 全局koanf实例。使用.作为键路径分隔符。这可以是/或任何其他字符。 var k = koanf.New(".") func main() { // 加载JSON配置。 if err := k.Load(file.Provider("mock/mock.json"), json.Parser()); err != nil { log.Fatalf("加载配置出错: %v", err) } // 加载环境变量并合并到已加载的配置中。 // "MYVAR"是用于过滤环境变量的前缀。 // "."是用于表示环境变量中键层次结构的分隔符。 // (可选的,或可以为nil)函数可用于转换环境变量名称,例如将其转为小写。 // // 例如,环境变量:MYVAR_TYPE和MYVAR_PARENT1_CHILD1_NAME // 将被合并到配置文件中的"type"和嵌套的"parent1.child1.name"键中, // 因为我们将键转为小写,将`_`替换为`.`,并去掉MYVAR_前缀, // 所以只剩下"parent1.child1.name"。 k.Load(env.Provider("MYVAR_", ".", func(s string) string { return strings.Replace(strings.ToLower( strings.TrimPrefix(s, "MYVAR_")), "_", ".", -1) }), nil) fmt.Println("name是 = ", k.String("parent1.child1.name")) }

你也可以使用env.ProviderWithValue,通过回调函数同时修改键和值, 以返回字符串以外的类型。例如,这里用空格分隔的环境变量值被返回为字符串切片或数组。 例如:MYVAR_slice=a b c变成slice: [a, b, c]

k.Load(env.ProviderWithValue("MYVAR_", ".", func(s string, v string) (string, interface{}) { // 去掉MYVAR_前缀并转为小写,同时将键中的_字符替换为.(koanf分隔符)。 key := strings.Replace(strings.ToLower(strings.TrimPrefix(s, "MYVAR_")), "_", ".", -1) // 如果值中包含空格,则按空格将值分割成切片。 if strings.Contains(v, " ") { return key, strings.Split(v, " ") } // 否则,返回普通字符串。 return key, v }), nil)

从S3桶读取

// 从s3加载JSON配置。 if err := k.Load(s3.Provider(s3.Config{ AccessKey: os.Getenv("AWS_S3_ACCESS_KEY"), SecretKey: os.Getenv("AWS_S3_SECRET_KEY"), Region: os.Getenv("AWS_S3_REGION"), Bucket: os.Getenv("AWS_S3_BUCKET"), ObjectKey: "dir/config.json", }), json.Parser()); err != nil { log.Fatalf("加载配置出错: %v", err) }

读取原始字节

内置的rawbytesProvider可用于从源(如数据库或HTTP调用)读取任意字节。

package main import ( "fmt" "github.com/knadh/koanf/v2" "github.com/knadh/koanf/parsers/json" "github.com/knadh/koanf/providers/rawbytes" ) // 全局koanf实例。使用.作为键路径分隔符。这可以是/或任何其他字符。 var k = koanf.New(".") func main() { b := []byte(`{"type": "rawbytes", "parent1": {"child1": {"type": "rawbytes"}}}`) k.Load(rawbytes.Provider(b), json.Parser()) fmt.Println("type是 = ", k.String("parent1.child1.type")) }

解析和序列化

Parser可用于根据字段标签将Koanf实例中的值解析并扫描到结构体中, 也可用于将Koanf实例序列化回字节,例如,重新转为JSON或YAML,以便写回文件。

package main import ( "fmt" "log" "github.com/knadh/koanf/v2" "github.com/knadh/koanf/parsers/json" "github.com/knadh/koanf/providers/file" ) // 全局koanf实例。使用.作为键路径分隔符。这可以是/或任何其他字符。 var ( k = koanf.New(".") parser = json.Parser() ) func main() { // 加载JSON配置。 if err := k.Load(file.Provider("mock/mock.json"), parser); err != nil { log.Fatalf("加载配置出错: %v", err) } // 用于解析嵌套配置的结构体。 type childStruct struct { Name string `koanf:"name"` Type string `koanf:"type"` Empty map[string]string `koanf:"empty"` GrandChild struct { Ids []int `koanf:"ids"` On bool `koanf:"on"` } `koanf:"grandchild1"` } var out childStruct // 快速解析。 k.Unmarshal("parent1.child1", &out) fmt.Println(out) // 使用高级配置解析。 out = childStruct{} k.UnmarshalWithConf("parent1.child1", &out, koanf.UnmarshalConf{Tag: "koanf"}) fmt.Println(out) // 将实例重新序列化为JSON。 // parser实例可以是任何类型,例如:json.Parser()、yaml.Parser()等。 b, _ := k.Marshal(parser) fmt.Println(string(b)) }

使用平面路径解析

有时需要将各种嵌套结构中的一组键解析到一个平面目标结构中。 这可以通过UnmarshalConf.FlatPaths标志实现。

package main import ( "fmt" "log" "github.com/knadh/koanf/v2" "github.com/knadh/koanf/parsers/json" "github.com/knadh/koanf/providers/file" ) // 全局koanf实例。使用.作为键路径分隔符。这可以是/或任何其他字符。 var k = koanf.New(".") func main() { // 加载JSON配置。 if err := k.Load(file.Provider("mock/mock.json"), json.Parser()); err != nil { log.Fatalf("加载配置出错: %v", err) } type rootFlat struct { Type string `koanf:"type"` Empty map[string]string `koanf:"empty"` Parent1Name string `koanf:"parent1.name"` Parent1ID int `koanf:"parent1.id"` Parent1Child1Name string `koanf:"parent1.child1.name"` Parent1Child1Type string `koanf:"parent1.child1.type"` Parent1Child1Empty map[string]string `koanf:"parent1.child1.empty"` Parent1Child1Grandchild1IDs []int `koanf:"parent1.child1.grandchild1.ids"` Parent1Child1Grandchild1On bool `koanf:"parent1.child1.grandchild1.on"` } // 使用FlatPaths: True解析整个根。 var o1 rootFlat k.UnmarshalWithConf("", &o1, koanf.UnmarshalConf{Tag: "koanf", FlatPaths: true}) fmt.Println(o1)

// 解析"parent1"的子结构。 type subFlat struct { Name string koanf:"name" ID int koanf:"id" Child1Name string koanf:"child1.name" Child1Type string koanf:"child1.type" Child1Empty map[string]string koanf:"child1.empty" Child1Grandchild1IDs []int koanf:"child1.grandchild1.ids" Child1Grandchild1On bool koanf:"child1.grandchild1.on" }

var o2 subFlat k.UnmarshalWithConf("parent1", &o2, koanf.UnmarshalConf{Tag: "koanf", FlatPaths: true}) fmt.Println(o2) }


#### 从嵌套映射中读取

内置的`confmap`提供程序接受一个`map[string]interface{}`,可以加载到koanf实例中。

```go
package main

import (
	"fmt"
	"log"

	"github.com/knadh/koanf/v2"
	"github.com/knadh/koanf/providers/confmap"
	"github.com/knadh/koanf/providers/file"
	"github.com/knadh/koanf/parsers/json"
	"github.com/knadh/koanf/parsers/yaml"
)

// 全局koanf实例。使用"."作为键路径分隔符。这可以是"/"或任何字符。
var k = koanf.New(".")

func main() {
	// 使用confmap提供程序加载默认值。
	// 我们提供一个使用"."分隔符的平面映射。
	// 通过将分隔符设置为空字符串"",可以加载嵌套映射。
	k.Load(confmap.Provider(map[string]interface{}{
		"parent1.name": "Default Name",
		"parent3.name": "New name here",
	}, "."), nil)

	// 在默认值之上加载JSON配置。
	if err := k.Load(file.Provider("mock/mock.json"), json.Parser()); err != nil {
		log.Fatalf("加载配置时出错: %v", err)
	}

	// 加载YAML配置并合并到先前加载的配置中(因为我们可以)。
	k.Load(file.Provider("mock/mock.yml"), yaml.Parser())

	fmt.Println("parent的名字是 = ", k.String("parent1.name"))
	fmt.Println("parent的ID是 = ", k.Int("parent1.id"))
}

从结构体中读取

内置的structs提供程序可用于从结构体中读取数据并加载到koanf实例中。

package main import ( "fmt" "github.com/knadh/koanf/v2" "github.com/knadh/koanf/providers/structs" ) // 全局koanf实例。使用"."作为键路径分隔符。这可以是"/"或任何字符。 var k = koanf.New(".") type parentStruct struct { Name string `koanf:"name"` ID int `koanf:"id"` Child1 childStruct `koanf:"child1"` } type childStruct struct { Name string `koanf:"name"` Type string `koanf:"type"` Empty map[string]string `koanf:"empty"` Grandchild1 grandchildStruct `koanf:"grandchild1"` } type grandchildStruct struct { Ids []int `koanf:"ids"` On bool `koanf:"on"` } type sampleStruct struct { Type string `koanf:"type"` Empty map[string]string `koanf:"empty"` Parent1 parentStruct `koanf:"parent1"` } func main() { // 使用structs提供程序加载默认值。 // 我们向提供程序提供一个结构体以及结构体标签`koanf`。 k.Load(structs.Provider(sampleStruct{ Type: "json", Empty: make(map[string]string), Parent1: parentStruct{ Name: "parent1", ID: 1234, Child1: childStruct{ Name: "child1", Type: "json", Empty: make(map[string]string), Grandchild1: grandchildStruct{ Ids: []int{1, 2, 3}, On: true, }, }, }, }, "koanf"), nil) fmt.Printf("名字是 = `%s`\n", k.String("parent1.child1.name")) }

合并行为

默认行为

当你这样创建Koanf时的默认行为是:koanf.New(delim),最新加载的配置将与之前的配置合并。

例如: first.yml

key: [1,2,3]

second.yml

key: 'string'

当加载second.yml时,它将覆盖first.yml的类型。

如果不希望这种行为,你可以进行"严格"合并。在相同的场景下,Load将返回一个错误。

package main import ( "errors" "log" "github.com/knadh/koanf/v2" "github.com/knadh/koanf/maps" "github.com/knadh/koanf/parsers/json" "github.com/knadh/koanf/parsers/yaml" "github.com/knadh/koanf/providers/file" ) var conf = koanf.Conf{ Delim: ".", StrictMerge: true, } var k = koanf.NewWithConf(conf) func main() { yamlPath := "mock/mock.yml" if err := k.Load(file.Provider(yamlPath), yaml.Parser()); err != nil { log.Fatalf("加载配置时出错: %v", err) } jsonPath := "mock/mock.json" if err := k.Load(file.Provider(jsonPath), json.Parser()); err != nil { log.Fatalf("加载配置时出错: %v", err) } }

注意: 当合并不同的扩展名时,每个解析器可能会以不同方式处理其类型, 这意味着即使你加载相同的类型,使用StrictMerge: true也可能会失败。

例如:合并JSON和YAML很可能会失败,因为JSON将整数视为float64,而YAML将它们视为整数。

合并顺序和键的大小写敏感性

  • koanf中的配置键是大小写敏感的。例如,app.server.portAPP.SERVER.port不是相同的。
  • koanf不对从各种提供程序加载配置的顺序施加任何限制。每次连续的Load()Merge()都会将新配置合并到现有配置中。也就是说,可以先加载环境变量,然后在其上加载文件,然后在其上加载命令行变量,或任何这样的顺序。

自定义提供程序和解析器

提供程序返回一个嵌套的map[string]interface{}配置,可以直接使用koanf.Load()加载到koanf中,或者它可以返回原始字节,可以使用解析器进行解析(同样使用koanf.Load()加载)。编写提供程序和解析器很简单。请查看providersparsers目录中的内置实现。

自定义合并策略

默认情况下,使用Load()合并两个配置源时,koanf会递归合并嵌套映射(map[string]interface{})的键, 而静态值(切片、字符串等)会被覆盖。可以通过提供带有WithMergeFunc选项的自定义合并函数来更改此行为。

package main import ( "errors" "log" "github.com/knadh/koanf/v2" "github.com/knadh/koanf/maps" "github.com/knadh/koanf/parsers/json" "github.com/knadh/koanf/parsers/yaml" "github.com/knadh/koanf/providers/file" ) var conf = koanf.Conf{ Delim: ".", StrictMerge: true, } var k = koanf.NewWithConf(conf) func main() { yamlPath := "mock/mock.yml" if err := k.Load(file.Provider(yamlPath), yaml.Parser()); err != nil { log.Fatalf("加载配置时出错: %v", err) } jsonPath := "mock/mock.json" if err := k.Load(file.Provider(jsonPath), json.Parser(), koanf.WithMergeFunc(func(src, dest map[string]interface{}) error { // 你的自定义逻辑,将值从src复制到dst return nil })); err != nil { log.Fatalf("加载配置时出错: %v", err) } }

API

查看https://pkg.go.dev/github.com/knadh/koanf/v2#section-documentation 获取所有可用方法的完整API文档

内置提供程序

使用go get -u github.com/knadh/koanf/providers/$provider安装

包名提供者描述
filefile.Provider(filepath string)读取文件并返回待解析的原始字节。
fsfs.Provider(f fs.FS, filepath string)(实验性) 从fs.FS读取文件并返回待解析的原始字节。此提供者需要go v1.16或更高版本。
basicflagbasicflag.Provider(f *flag.FlagSet, delim string)接受标准库的flag.FlagSet
posflagposflag.Provider(f *pflag.FlagSet, delim string)接受spf13/pflag.FlagSet(支持多种类型的高级POSIX兼容标志),并基于分隔符提供嵌套的配置映射。
envenv.Provider(prefix, delim string, f func(s string) string)接受一个可选的前缀用于过滤环境变量,一个可选的函数用于转换环境变量(接受并返回字符串),并基于分隔符返回嵌套的配置映射。
confmapconfmap.Provider(mp map[string]interface{}, delim string)接受预先制作的map[string]interface{}配置映射。如果提供了分隔符,则假定键是扁平化的,因此使用分隔符进行解扁平化。
structsstructs.Provider(s interface{}, tag string)接受一个结构体和结构体标签。
s3s3.Provider(s3.S3Config{})接受一个s3配置结构体。
rawbytesrawbytes.Provider(b []byte)接受一个原始[]byte切片,用koanf.Parser进行解析
vault/v2vault.Provider(vault.Config{})Hashicorp Vault提供者
appconfig/v2vault.AppConfig(appconfig.Config{})AWS AppConfig提供者
etcd/v2etcd.Provider(etcd.Config{})CNCF etcd提供者
consul/v2consul.Provider(consul.Config{})Hashicorp Consul提供者
parameterstore/v2parameterstore.Provider(parameterstore.Config{})AWS Systems Manager Parameter Store提供者

内置解析器

通过 go get -u github.com/knadh/koanf/parsers/$parser 安装

包名解析器描述
jsonjson.Parser()将JSON字节解析为嵌套映射
yamlyaml.Parser()将YAML字节解析为嵌套映射
tomltoml.Parser()将TOML字节解析为嵌套映射
toml/v2toml.Parser()将TOML字节解析为嵌套映射(使用go-toml v2)
dotenvdotenv.Parser()将DotEnv字节解析为扁平映射
hclhcl.Parser(flattenSlices bool)将Hashicorp HCL字节解析为嵌套映射。建议将flattenSlices设置为true。了解更多
nestedtextnestedtext.Parser()将NestedText字节解析为扁平映射
hjsonhjson.Parser()将HJSON字节解析为嵌套映射

第三方提供者

包名提供者描述
github.com/defensestation/koanf/providers/secretsmanagervault.SecretsMananger(secretsmanager.Config{}, f func(s string) string)AWS Secrets Manager提供者,从存储中接受映射或字符串作为值
github.com/defensestation/koanf/providers/parameterstorevault.ParameterStore(parameterstore.Config{}, f func(s string) string)AWS ParameterStore提供者,一个可选的函数用于转换环境变量(接受并返回字符串)

viper的替代方案

koanf是流行的spf13/viper轻量级替代方案。它是为了解决使用viper时遇到的一些根本性问题而编写的。

  • viper通过强制将键转为小写违反了JSON、YAML、TOML、HCL语言规范。
  • 显著增加了构建大小
  • 将配置解析与文件扩展名紧密耦合。
  • 语义和抽象不佳。命令行、环境变量、文件等以及各种解析器都硬编码在核心中。没有可扩展的基本元素。
  • 将大量第三方依赖引入核心包。例如,即使不使用YAML或标志,由于耦合,这些依赖仍会被引入。
  • 强加任意的排序约定(例如:标志 -> 环境变量 -> 配置等)
  • Get()返回切片和映射的引用。外部进行的修改会改变配置映射中的底层值。
  • 做一些非惯用的事情,如在扁平映射上放弃O(1)
  • Viper将包含空映射的键(例如:my_key: {})视为未设置(即:IsSet("my_key") == false)。
  • 存在大量未解决的问题

编辑推荐精选

TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
蛙蛙写作

蛙蛙写作

AI小说写作助手,一站式润色、改写、扩写

蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。

AI辅助写作AI工具蛙蛙写作AI写作工具学术助手办公助手营销助手AI助手
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

热门AI助手AI对话AI工具聊天机器人
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

下拉加载更多