[!重要] protoc-gen-validate (PGV) 已达到稳定状态,并处于维护模式。
我们建议新项目和现有项目过渡到使用 [
protovalidate
][pv]。如果你想了解更多关于 protoc-gen-validate 的局限性以及我们如何设计 [
protovalidate
][pv] 来改进它,请阅读[我们的博客文章][pv-announce]。
PGV 是一个 protoc 插件,用于生成多语言消息验证器。虽然 protocol buffers 能有效地保证结构化数据的类型,但它们无法强制执行值的语义规则。这个插件为 protoc 生成的代码添加了支持,以验证这些约束。
开发人员导入 PGV 扩展,并在他们的 proto 文件中用约束规则注释消息和字段:
syntax = "proto3"; package examplepb; import "validate/validate.proto"; message Person { uint64 id = 1 [(validate.rules).uint64.gt = 999]; string email = 2 [(validate.rules).string.email = true]; string name = 3 [(validate.rules).string = { pattern: "^[A-Za-z]+( [A-Za-z]+)*$", max_bytes: 256, }]; Location home = 4 [(validate.rules).message.required = true]; message Location { double lat = 1 [(validate.rules).double = {gte: -90, lte: 90}]; double lng = 2 [(validate.rules).double = {gte: -180, lte: 180}]; } }
使用 PGV 和目标语言的默认插件执行 protoc
将在生成的类型上创建 Validate
方法:
p := new(Person) err := p.Validate() // 错误:Id 必须大于 999 p.Id = 1000 err = p.Validate() // 错误:Email 必须是有效的电子邮件地址 p.Email = "example@bufbuild.com" err = p.Validate() // 错误:Name 必须匹配模式 '^[A-Za-z]+( [A-Za-z]+)*$' p.Name = "Protocol Buffer" err = p.Validate() // 错误:Home 是必需的 p.Home = &Location{37.7, 999} err = p.Validate() // 错误:Home.Lng 必须在 [-180, 180] 范围内 p.Home.Lng = -122.4 err = p.Validate() // 错误:nil
go
工具链(≥ v1.7)$PATH
中的 protoc
编译器$PATH
中的 protoc-gen-validate
proto3
语法。 计划支持 proto2
语法。从 GitHub 发布版 下载资产,解压缩并将插件添加到 $PATH
中。
# 将此仓库获取到 $GOPATH 中 go get -d github.com/envoyproxy/protoc-gen-validate
💡 是的,我们的 go 模块路径是
github.com/envoyproxy/protoc-gen-validate
而不是bufbuild
,这是有意为之。更改模块路径实际上是创建一个新的、独立的模块。我们不希望破坏我们的用户。Go 团队正在努力为路径更改的模块提供更好的
cmd/go
支持,但进展缓慢。在此之前,我们将继续使用envoyproxy
模块路径。
git clone https://github.com/bufbuild/protoc-gen-validate.git
# 将 PGV 安装到 $GOPATH/bin
cd protoc-gen-validate && make build
lang
:指定要生成的目标语言。目前,唯一支持的选项是:
go
cc
(用于 C++,部分实现)java
Go 生成应该与官方插件输出到相同的输出路径。对于 proto 文件 example.proto
,相应的验证代码生成到 ../generated/example.pb.validate.go
:
protoc \ -I . \ -I path/to/validate/ \ --go_out=":../generated" \ --validate_out="lang=go:../generated" \ example.proto
所有生成的消息都包含以下方法:
Validate() error
,在验证过程中返回遇到的第一个错误。ValidateAll() error
,返回验证过程中遇到的所有错误。PGV 不需要从现有生成的代码中添加任何额外的运行时依赖项。
注意:默认情况下,example.pb.validate.go 嵌套在与你的 option go_package
名称匹配的目录结构中。你可以使用 protoc 参数 paths=source_relative:.
来更改这一点,比如 --validate_out="lang=go,paths=source_relative:../generated"
。然后 --validate_out
将在预期的位置输出文件。有关更多信息,请参阅 Google 的 protobuf 文档或包和输入路径或参数。
还支持 module=example.com/foo
标志,如此处所述。
使用较新的 Buf CLI 版本(>v1.9.0),你可以使用新的插件键,而不是直接使用 protoc
命令:
# buf.gen.yaml
version: v1
plugins:
- plugin: buf.build/bufbuild/validate-go
out: gen
# proto/buf.yaml
version: v1
deps:
- buf.build/envoyproxy/protoc-gen-validate
Java 生成与现有的 Java 项目 protobuf 工具链集成。对于 Maven 项目,在你的 pom.xml 或 build.gradle 中添加以下内容。
<dependencies> <dependency> <groupId>build.buf.protoc-gen-validate</groupId> <artifactId>pgv-java-stub</artifactId> <version>${pgv.version}</version> </dependency> </dependencies> <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.4.1.Final</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.6.1</version> <configuration> <protocArtifact> com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} </protocArtifact> </configuration> <executions> <execution> <id>protoc-java-pgv</id> <goals> <goal>compile-custom</goal> </goals> <configuration> <pluginParameter>lang=java</pluginParameter> <pluginId>java-pgv</pluginId> <pluginArtifact> build.buf.protoc-gen-validate:protoc-gen-validate:${pgv.version}:exe:${os.detected.classifier} </pluginArtifact> </configuration> </execution> </executions> </plugin> </plugins> </build>
plugins { ... id "com.google.protobuf" version "${protobuf.version}" ... } protobuf { protoc { artifact = "com.google.protobuf:protoc:${protoc.version}" } plugins { javapgv { artifact = "build.buf.protoc-gen-validate:protoc-gen-validate:${pgv.version}" } } generateProtoTasks { all()*.plugins { javapgv { option "lang=java" } } } }
// 创建一个反射加载生成的验证器的验证器索引 ValidatorIndex index = new ReflectiveValidatorIndex(); // 断言消息是有效的 index.validatorFor(message.getClass()).assertValid(message); // 创建 gRPC 客户端和服务器拦截器以自动验证消息(需要 pgv-java-grpc 模块) clientStub = clientStub.withInterceptors(new ValidatingClientInterceptor(index)); serverBuilder.addService(ServerInterceptors.intercept(svc, new ValidatingServerInterceptor(index)));
Python 实现通过即时代码生成工作。换句话说,validate(msg)
函数是按需编写并 exec-ed 的。LRU 缓存通过存储每个描述符的生成函数来提高性能。
Python 包可在 PyPI 上获得。
要运行 validate()
,请执行以下操作:
from entities_pb2 import Person from protoc_gen_validate.validator import validate, ValidationFailed p = Person(first_name="Foo", last_name="Bar", age=42) try: validate(p) except ValidationFailed as err: print(err)
你可以使用 print_validate()
函数查看生成的代码。
提供的约束 主要是根据 JSON Schema 中的约束建模的。PGV 规则可以为同一字段混合使用;插件确保应用于字段的规则在代码生成之前不会相互矛盾。
查看约束规则比较矩阵以了解特定语言的约束能力。
所有数字类型(
float
、double
、int32
、int64
、uint32
、uint64
、sint32
、sint64
、fixed32
、fixed64
、sfixed32
、sfixed64
)共享相同的规则。
const:字段必须精确地等于指定值。
// x 必须精确等于 1.23 float x = 1 [(validate.rules).float.const = 1.23];
lt/lte/gt/gte:这些不等式(分别为 <
、<=
、>
、>=
)允许推导字段必须位于的范围。
// x 必须小于 10 int32 x = 1 [(validate.rules).int32.lt = 10]; // x 必须大于或等于 20 uint64 x = 1 [(validate.rules).uint64.gte = 20]; // x 必须在 [30, 40) 范围内 fixed32 x = 1 [(validate.rules).fixed32 = {gte:30, lt: 40}];
反转 lt(e)
和 gt(e)
的值是有效的,并创建一个排除范围。
// x 必须在 [30, 40) 范围之外 double x = 1 [(validate.rules).double = {lt:30, gte:40}];
in/not_in:这两个规则允许为字段的值指定允许/拒绝列表。
// x 必须是 1、2 或 3 uint32 x = 1 [(validate.rules).uint32 = {in: [1,2,3]}]; // x 不能是 0 或 0.99 float x = 1 [(validate.rules).float = {not_in: [0, 0.99]}];
ignore_empty:此规则指定如果字段为空或设置为默认值,则忽略任何验证规则。这些通常在更新请求中能够取消设置字段时很有用,或者在切换到 WKT 不可行的情况下跳过可选字段的验证。
uint32 x = 1 [(validate.rules).uint32 = {ignore_empty: true, gte: 200}];
const:字段必须精确地等于指定值。
// x 必须设置为 true bool x = 1 [(validate.rules).bool.const = true]; // x 不能设置为 true bool x = 1 [(validate.rules).bool.const = false];
const:字段必须精确地等于指定值。
// x 必须是一个有效的主机名( 根据 RFC 1034) string x = 1 [(validate.rules).string.hostname = true];
// x 必须是一个有效的 IP 地址(IPv4 或 IPv6) string x = 1 [(validate.rules).string.ip = true];
// x 必须是一个有效的 IPv4 地址 // 例如: "192.168.0.1" string x = 1 [(validate.rules).string.ipv4 = true];
// x 必须是一个有效的 IPv6 地址 // 例如: "fe80::3" string x = 1 [(validate.rules).string.ipv6 = true];
// x 必须是一个有效的绝对 URI (根据 RFC 3986) string x = 1 [(validate.rules).string.uri = true];
// x 必须是一个有效的 URI 引用(绝对或相对) string x = 1 [(validate.rules).string.uri_ref = true];
// x 必须是一个有效的 UUID (根据 RFC 4122) string x = 1 [(validate.rules).string.uuid = true];
// x 必须符合 HTTP 头名称的已知正则表达式(根据 RFC 7230) string x = 1 [(validate.rules).string.well_known_regex = HTTP_HEADER_NAME]
// x 必须符合 HTTP 头值的已知正则表达式(根据 RFC 7230) string x = 1 [(validate.rules).string.well_known_regex = HTTP_HEADER_VALUE];
// x 必须符合头部的已知正则表达式,不允许 \r\n\0 字符。 string x = 1 [(validate.rules).string {well_known_regex: HTTP_HEADER_VALUE, strict: false}];
### 字节
> 字面值应该使用字符串表示,必要时使用转义。
- **const**: 字段必须完全等于指定的值。
```protobuf
// x 必须设置为 "foo" ("\x66\x6f\x6f")
bytes x = 1 [(validate.rules).bytes.const = "foo"];
// x 必须设置为 "\xf0\x90\x28\xbc"
bytes x = 1 [(validate.rules).bytes.const = "\xf0\x90\x28\xbc"];
len/min_len/max_len: 这些规则限制字段中的字节数。
// x 必须正好是 3 个字节 bytes x = 1 [(validate.rules).bytes.len = 3]; // x 必须至少是 3 个字节长 bytes x = 1 [(validate.rules).bytes.min_len = 3]; // x 必须在 5 到 10 个字节之间,包含边界值 bytes x = 1 [(validate.rules).bytes = {min_len: 5, max_len: 10}];
pattern: 字段必须匹配指定的 [RE2 兼容][re2] 正则表达式。包含的表达式应省略任何分隔符(即 /\d+/
应该只写成 \d+
)。
// x 必须是非空的 ASCII 字节序列 bytes x = 1 [(validate.rules).bytes.pattern = "^[\x00-\x7F]+$"];
prefix/suffix/contains: 字段必须包含指定的字节序列,可以选择指定位置。
// x 必须以 "\x99" 开头 bytes x = 1 [(validate.rules).bytes.prefix = "\x99"]; // x 必须以 "buz\x7a" 结尾 bytes x = 1 [(validate.rules).bytes.suffix = "buz\x7a"]; // x 必须在任意位置包含 "baz" bytes x = 1 [(validate.rules).bytes.contains = "baz"];
in/not_in: 这两个规则允许为字段的值指定允许/拒绝列表。
// x 必须是 "foo"、"bar" 或 "baz" 之一 bytes x = 1 [(validate.rules).bytes = {in: ["foo", "bar", "baz"]}]; // x 不能是 "fizz" 或 "buzz" bytes x = 1 [(validate.rules).bytes = {not_in: ["fizz", "buzz"]}];
ignore_empty: 此规则指定如果字段为空或设置为默认值,则忽略任何验证规则。这通常在更新请求中可以取消设置字段,或者在无法切换到 WKT 的可选字段上跳过验证时很有用。
bytes x = 1 [(validate.rules).bytes = {ignore_empty: true, in: ["foo", "bar", "baz"]}];
常见格式: 这些规则为常见模式提供高级约束。这些约束通常比等效的正则表达式模式更宽松和高效,同时提供更具解释性的失败描述。
// x 必须是字节格式的有效 IP 地址(IPv4 或 IPv6) bytes x = 1 [(validate.rules).bytes.ip = true]; // x 必须是字节格式的有效 IPv4 地址 // 例如: "\xC0\xA8\x00\x01" bytes x = 1 [(validate.rules).bytes.ipv4 = true]; // x 必须是字节格式的有效 IPv6 地址 // 例如: "\x20\x01\x0D\xB8\x85\xA3\x00\x00\x00\x00\x8A\x2E\x03\x70\x73\x34" bytes x = 1 [(validate.rules).bytes.ipv6 = true];
所有字面值应使用枚举描述符中定义的数字(int32)值。
以下示例使用此 State
枚举
enum State { INACTIVE = 0; PENDING = 1; ACTIVE = 2; }
const: 字段必须完全等于指定的值。
// x 必须设置为 ACTIVE (2) State x = 1 [(validate.rules).enum.const = 2];
defined_only: 字段必须是枚举描述符中指定的值之一。
// x 只能是 INACTIVE、PENDING 或 ACTIVE State x = 1 [(validate.rules).enum.defined_only = true];
in/not_in: 这两个规则允许为字段的值指定允许/拒绝列表。
// x 必须是 INACTIVE (0) 或 ACTIVE (2) State x = 1 [(validate.rules).enum = {in: [0,2]}]; // x 不能是 PENDING (1) State x = 1 [(validate.rules).enum = {not_in: [1]}];
如果字段包含一个消息,并且该消息是使用 PGV 生成的,将递归执行验证。未使用 PGV 生成的消息将被跳过。
// 如果 Person 是用 PGV 生成的,并且 x 被设置, // x 的字段将被验证。 Person x = 1;
skip: 此规则指定不应评估此字段的验证规则。
// Person x 的字段将不会被验证。 Person x = 1 [(validate.rules).message.skip = true];
required: 此规则指定字段不能未设置。
// x 不能未设置 Person x = 1 [(validate.rules).message.required = true]; // x 不能未设置,但不会对 x 执行验证 Person x = 1 [(validate.rules).message = {required: true, skip: true}];
min_items/max_items: 这些规则控制字段中包含的元素数量
// x 必须至少包含 3 个元素 repeated int32 x = 1 [(validate.rules).repeated.min_items = 3]; // x 必须包含 5 到 10 个 Person,包含边界值 repeated Person x = 1 [(validate.rules).repeated = {min_items: 5, max_items: 10}]; // x 必须恰好包含 7 个元素 repeated double x = 1 [(validate.rules).repeated = {min_items: 7, max_items: 7}];
unique: 此规则要求字段中的所有元素必须是唯一的。此规则不支持重复的消息。
// x 必须包含唯一的 int64 值 repeated int64 x = 1 [(validate.rules).repeated.unique = true];
items: 此规则指定应该应用于字段中每个元素的约束。重复的消息字段也会应用其验证规则,除非在此约束上指定了 skip
。
// x 必须包含正浮点值 repeated float x = 1 [(validate.rules).repeated.items.float.gt = 0]; // x 必须包含 Person,但不验证它们 repeated Person x = 1 [(validate.rules).repeated.items.message.skip = true];
ignore_empty: 此规则指定如果字段为空或设置为默认值,则忽略任何验证规则。这通常在更新请求中可以取消设置字段,或者在无法切换到 WKT 的可选字段上跳过验证时很有用。
repeated int64 x = 1 [(validate.rules).repeated = {ignore_empty: true, items: {int64: {gt: 200}}}];
min_pairs/max_pairs: 这些规则控制此字段中包含的键值对数量
// x 必须至少包含 3 个键值对 map<string, uint64> x = 1 [(validate.rules).map.min_pairs = 3]; // x 必须包含 5 到 10 个键值对 map<string, string> x = 1 [(validate.rules).map = {min_pairs: 5, max_pairs: 10}]; // x 必须恰好包含 7 个键值对 map<string, Person> x = 1 [(validate.rules).map = {min_pairs: 7, max_pairs: 7}];
no_sparse: 对于具有消息值的映射字段,将此规则设置为 true 会禁止具有未设置值的键。
// x 中的所有值都必须设置 map<uint64, Person> x = 1 [(validate.rules).map.no_sparse = true];
keys: 此规则指定应用于字段中键的约束。
// x 的键必须全部为负数 <sint32, string> x = [(validate.rules).map.keys.sint32.lt = 0];
values: 此规则指定应用于字段中每个值的约束。重复的消息字段也会应用其验证规则,除非在此约束上指定了 skip
。
// x 必须包含至少 3 个字符的字符串 map<string, string> x = 1 [(validate.rules).map.values.string.min_len = 3]; // x 必须包含 Person,但不验证它们 map<string, Person> x = 1 [(validate.rules).map.values.message.skip = true];
ignore_empty: 此规则指定如果字段为空或设置为默认值,则忽略任何验证规则。这通常在更新请求中可以取消设置字段,或者在无法切换到 WKT 的可选字段上跳过验证时很有用。
map<string, string> x = 1 [(validate.rules).map = {ignore_empty: true, values: {string: {min_len: 3}}}];
一组 [WKTs][wkts] 与 protoc 打包在一起,是许多领域中有用的常见消息模式。
在 proto3
语法中,无法区分未设置和标量字段的零值。值 WKTs 通过将它们包装在消息中来允许这种区分。PGV 允许使用包装器封装的相同标量规则。
// 如果设置了,x 必须大于 3 google.protobuf.Int32Value x = 1 [(validate.rules).int32.gt = 3];
消息规则也可以与标量众所周知的类型(WKTs)一起使用:
// 确保如果没有为 age 设置值,尽管其零值为 0,也不会通过验证。 message X {google.protobuf.Int32Value age = 1 [(validate.rules).int32.gt = -1, (validate.rules).message.required = true];}
required: 此规则指定必须设置字段
// x 不能未设置 google.protobuf.Any x = 1 [(validate.rules).any.required = true];
in/not_in: 这两个规则允许为此字段中的 type_url
值指定允许/拒绝列表。如果可能,请考虑使用 oneof
联合而不是 in
。
// x 不能是 Duration 或 Timestamp WKT google.protobuf.Any x = 1 [(validate.rules).any = {not_in: [ "type.googleapis.com/google.protobuf.Duration", "type.googleapis.com/google.protobuf.Timestamp" ]}
// x必须在[epoch, 2009/11/10T23:00:00Z)范围内 google.protobuf.Timestamp x = 1 [(validate.rules).timestamp = { gte: {}, lt: {seconds: 63393490800} }];
将`lt(e)`和`gt(e)`的值互换是有效的,并创建一个排除范围。
```protobuf
// x必须在[epoch, 2009/11/10T23:00:00Z)范围之外
google.protobuf.Timestamp x = 1 [(validate.rules).timestamp = {
lt: {},
gte: {seconds: 63393490800}
}];
// x必须小于当前时间戳 google.protobuf.Timestamp x = 1 [(validate.rules).timestamp.lt_now = true];
lt_now
和gt_now
一起使用来控制这些范围。// x必须在当前时间的±1秒内 google.protobuf.Timestamp x = 1 [(validate.rules).timestamp.within.seconds = 1]; // x必须在(now, now+1h)范围内 google.protobuf.Timestamp x = 1 [(validate.rules).timestamp = { gt_now: true, within: {seconds: 3600} }];
message Person { option (validate.disabled) = true; // x将不需要大于123 uint64 x = 1 [(validate.rules).uint64.gt = 123]; // y的字段将不会被验证 Person y = 2; }
message Person { option (validate.ignored) = true; // x将不需要大于123 uint64 x = 1 [(validate.rules).uint64.gt = 123]; // y的字段将不会被验证 Person y = 2; }
oneof
中的一个字段必须被设置。默认情况下,联合字段中的无或一个可以被设置。启用此规则不允许全部未设置。oneof id { // x、y或z必须设置其中一个。 option (validate.required) = true; string x = 1; int32 y = 2; Person z = 3; }
PGV是用Go语言在[protoc-gen-star][pg*]框架之上编写的,并编译成独立的二进制文件。
目前所有PGV依赖都已检入项目。要测试PGV,必须安装protoc
,可以从[源码][protoc-source]、提供的[发布版][protoc-releases]或包管理器安装。还应安装目标语言的官方protoc插件。
make build
: 生成约束proto并将PGV编译到$GOPATH/bin
中
make lint
: 对PGV代码库运行静态分析规则,包括golint
、go vet
和gofmt -s
make testcases
: 生成/tests/harness/cases
中的proto文件。这些文件被测试工具用来验证为每种语言生成的验证规则。
make harness
: 对每种语言的测试工具执行测试用例。
确保您的PATH
设置包含protoc-gen-go
和protoc
,然后:
bazel test //tests/...
PGV带有一个Dockerfile用于一致的开发工具和CI。主要入口点是make
,默认目标是build
。
# 构建镜像 docker build -t bufbuild/protoc-gen-validate . # 执行默认make目标: build docker run --rm \ bufbuild/protoc-gen-validate # 执行'ci' make目标 docker run --rm \ bufbuild/protoc-gen-validate ci # 执行'build'和'testcases' make目标 docker run --rm \ bufbuild/protoc-gen-validate build testcases # 覆盖入口点并直接与容器交互 # 当想在本地没有安装bazel的情况下运行bazel命令时,这可能很有用。 docker run --rm \ -it --entrypoint=/bin/bash \ bufbuild/protoc-gen-validate
一键生成PPT和Word,让学习生活更轻松
讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。
深度推理能力全新升级,全面对标OpenAI o1
科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。
一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型
Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。
字节跳动发布的AI编程神器IDE
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。
AI助力,做PPT更简单!
咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。
选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。
专业的AI公文写作平台,公文写作神器
AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。
OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。
openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。
高分辨率纹理 3D 资产生成
Hunyuan3D-2 是腾讯开发的用于 3D 资产生成的强大工具,支持从文本描述、单张图片或多视角图片生成 3D 模型,具备快速形状生成能力,可生成带纹理的高质量 3D 模型,适用于多个领域,为 3D 创作提供了高效解决方案。
一个具备存储、管理和客户端操作等多种功能的分布式文件系统相关项目。
3FS 是一个功能强大的分布式文件系统项目,涵盖了存储引擎、元数据管理、客户端工具等多个模块。它支持多种文件操作, 如创建文件和目录、设置布局等,同时具备高效的事件循环、节点选择和协程池管理等特性。适用于需要大规模数据存储和管理的场景,能够提高系统的性能和可靠性,是分布式存储领域的优质解决方案。
最新AI工具、AI资讯
独家AI资源、AI项目落地
微信扫一扫关注公众号