- 云原生
- CI/CD
- DevOps
- 后端
【免费下载链接】pipeline
A cloud-native Pipeline resource.
导读
Git Resolver 是 Tekton Pipeline 内置的远程资源解析器(remote resolver),它让 TaskRun / PipelineRun 可以通过taskRef/pipelineRef直接引用存放在 Git 仓库中的 Tekton 资源文件,而无需先把 YAML 下载到集群再手动 apply。本指南将围绕 docs/git-resolver.md 展开,完整覆盖它的两种解析模式(git clone与 SCM 认证 API)、全部参数与 ConfigMap 配置项、多 Git 提供方(多配置)用法以及ResolutionRequest状态字段,并结合当前仓库源码(pkg/resolution/resolver/git、pkg/remoteresolution/resolver/git)说明其底层实现与安全机制。读完本文,你将能够独立配置 Git Resolver,并用它从 GitHub、GitLab、Gitea、Bitbucket 等 Git 仓库中安全地解析出 Task 与 Pipeline。
Resolver 类型
Git Resolver 通过ResolutionRequest上的标签resolution.tekton.dev/type: git被识别,响应类型为git。也就是说,在taskRef/pipelineRef中声明resolver: git即可触发该解析器。
从源码实现看,解析器主体为 pkg/remoteresolution/resolver/git/resolver.go 中的Resolver(旧版位于 pkg/resolution/resolver/git/resolver.go,已标记 Deprecated),其GetSelector方法返回resolution.tekton.dev/type=git标签,GetConfigName返回git-resolver-config,表明它的配置来自同名 ConfigMap。
两种解析模式
Git Resolver 提供两种获取远程文件的方式:
git clone模式:使用 Git 客户端对仓库执行浅克隆(shallow clone),随后检出指定 revision 并读取目标文件。支持匿名克隆与认证克隆。该模式吞吐量更高,因为它不受 SCM API 调用频率限制(Git 提供方通常给 API 调用设置比克隆更严的速率限制)。- 认证 API 模式:通过 SCM 提供方的 API 使用访问令牌只拉取指定路径下的单个文件,不进行完整克隆。支持私有仓库;对于大型仓库更高效,因为它只获取
pathInRepo指向的文件,而不是把整个仓库克隆到内存中。
从当前仓库源码看,git clone模式实际通过系统 Git 命令执行浅克隆:在 pkg/resolution/resolver/git/repository.go 中,remote.clone使用exec.CommandContext(ctx, "git", ...)调用git clone --depth=1 --no-checkout -- <url> <tmpDir>,clone 结束后checkout方法执行git fetch origin --depth=1 -- <revision>与git checkout FETCH_HEAD,最终用git rev-list -n1 HEAD拿到实际 commit SHA。认证 API 模式则位于 pkg/resolution/resolver/git/resolver.go,通过go-scm工厂创建 SCM 客户端,调用Contents.Find、Git.FindCommit、Repositories.Find完成文件内容、commit SHA 与仓库 clone URL 的获取。
前置要求
使用 Git Resolver 需要满足以下条件:
- 集群运行 Tekton Pipeline v0.41.0 或更高版本。
- 已安装内置远程解析器,参见安装与配置远程 Task 与 Pipeline 解析。
tekton-pipelines-resolvers命名空间下resolvers-feature-flagsConfigMap 中的enable-git-resolverfeature flag 被设为true。仓库自带的 config/resolvers/config-feature-flags.yaml 中该值为"true";从源码 pkg/apis/config/resolver/feature_flags.go 看,其默认值DefaultEnableGitResolver也为true。若 flag 为 false,解析请求会直接返回错误cannot handle resolution request, enable-git-resolver feature flag not true(见 pkg/resolution/resolver/git/resolver.go)。- 已启用 Beta features。
Resolver 参数
taskRef/pipelineRef中通过params向 Git Resolver 传递解析参数,完整参数如下:
| 参数名 | 说明 | 示例值 |
|---|---|---|
url | 需要匿名克隆的仓库 URL。url与repo(配合org)二者必须指定其一,不能同时指定。 | https://github.com/tektoncd/catalog.git |
repo | 查找资源的仓库名。url与repo(配合org)二者必须指定其一,不能同时指定。 | pipeline、test-infra |
org | 查找仓库的组织名。默认值可在配置中设置。 | tektoncd、kubernetes |
token | 可选,PipelineRun所在命名空间中用于获取令牌的 Secret 名称。默认为空,即尝试使用全局 ConfigMap 中的配置。 | secret-name、(空) |
tokenKey | 可选,上述令牌 Secret 中取令牌用的键名。默认为token。 | token |
gitToken | 可选,执行git clone认证操作时,PipelineRun命名空间中用于获取令牌的 Secret 名称;为空时使用匿名克隆。 | secret-gitauth-token |
gitTokenKey | 可选,执行git clone认证时,令牌 Secret 中取令牌用的键名。默认为token。 | token |
revision | 要检出的 Git revision,可以是 commit SHA(SHA-1 或 SHA-256)、分支名或标签名。 | aeb957601cf41c012be462827053a21a420befca、main、v0.38.2 |
pathInRepo | 文件在仓库中的路径。 | task/golang-build/0.3/golang-build.yaml |
serverURL | 可选,用于 API 操作的服务端 URL(需带https://前缀)。 | https://github.mycompany.com |
scmType | 可选,用于 API 操作的 SCM 类型。 | github、gitlab、gitea |
cache | 控制已解析资源的缓存行为。 | always、never、auto |
这些参数名在源码中有对应常量定义,见 pkg/resolution/resolver/git/params.go(UrlParam、OrgParam、RepoParam、PathParam、RevisionParam、TokenParam、TokenKeyParam、GitTokenParam、GitTokenKeyParam、ScmTypeParam、ServerURLParam、ConfigKeyParam等)。
参数校验规则(源码级)
在 pkg/resolution/resolver/git/resolver.go 的PopulateDefaultParams中,可以看到以下校验逻辑,写作时值得注意:
- 不能同时指定
url与repo(cannot specify both 'url' and 'repo');二者都为空时,若 ConfigMap 配置了default-url则自动填充,否则报错。 - 指定了
repo但未指定org时,使用配置中的default-org;都没有则报错。 revision以-开头会被拒绝(invalid revision ... must not begin with '-'),用于防止 Git 参数注入(例如--upload-pack=/path/to/binary)。- 非 SCM API 场景下,
url必须匹配校验正则^([^@]+@[^:]+|(git|ssh|ftps?|https?)://)(defaultValidateRepoURL,pkg/resolution/resolver/git/resolver.go),本地文件系统路径(/、file://开头)会被拒绝。 pathInRepo中不允许包含..路径穿越组件(containsDotDot),防止越出仓库目录读取任意文件;读取文件时还会做符号链接解析后的包含性检查(见 pkg/resolution/resolver/git/repository.go)。
Configuration
Git Resolver 使用 ConfigMap 存储配置,仓库自带的默认 ConfigMap 位于 config/resolvers/git-resolver-config.yaml(名称为git-resolver-config,命名空间为tekton-pipelines-resolvers)。其中已经包含了一组可直接使用的默认值:
data: fetch-timeout: "1m" # 单次匿名克隆解析的最大耗时 default-url: "https://github.com/tektoncd/catalog.git" default-revision: "main" scm-type: "github" # github/gitlab/gitea/bitbucketserver/bitbucketcloud server-url: "" api-token-secret-name: "" api-token-secret-key: "" api-token-secret-namespace: "default" default-org: "" # default-cache-mode: "auto" # 可选:always/never/auto # backoff-duration: "2s" # backoff-factor: "2.0" # backoff-jitter: "0.1" # backoff-steps: "2" # backoff-cap: "10s"Options
ConfigMap 支持以下配置项:
| 配置项 | 说明 | 示例值 |
|---|---|---|
default-revision | 未指定 revision 时使用的默认 Git revision。 | main |
fetch-timeout | 单次 git clone 解析的最大耗时。注意:目前所有解析请求都会强制施加 1 分钟的全局最大超时。 | 1m、2s、700ms |
default-url | 未指定 url 时用于匿名克隆的默认仓库 URL。 | https://github.com/tektoncd/catalog.git |
scm-type | SCM 提供方类型。使用org与repo的认证 API 时必填。 | github、gitlab、gitea、bitbucketcloud、bitbucketserver |
server-url | 认证 API 使用的 SCM 提供方基础 URL。使用 github.com、gitlab.com 或 BitBucket Cloud 时无需填写。 | api.internal-github.com |
api-token-secret-name | 存放 SCM API 令牌的 Kubernetes Secret 名称。使用org与repo的认证 API 时必填。 | bot-token-secret |
api-token-secret-key | 令牌 Secret 中存放实际密钥的键名。使用认证 API 时必填。 | oauth、token |
api-token-secret-namespace | 令牌 Secret 所在命名空间,若不在default中。 | other-namespace |
default-org | 使用认证 API 且参数中未指定 org 时,默认查找仓库的组织。可选。 | tektoncd、kubernetes |
backoff-duration | 解析请求失败时的初始退避时长。默认2s。 | 500ms、2s |
backoff-factor | 每步退避时长的增长因子。默认2.0。 | 2.5、4.0 |
backoff-jitter | 在 0 到 duration×jitter 之间随机增加的额外睡眠时间。默认0.1。 | 0.1、0.5 |
backoff-steps | 解析尝试总次数。设为1可禁用重试。默认2。 | 3、7 |
backoff-cap | 最大退避时长。达到后剩余步骤清零。默认10s。 | 10s、20s |
这些配置键在源码 pkg/resolution/resolver/git/config.go 中以常量形式定义(DefaultTimeoutKey、DefaultURLKey、DefaultRevisionKey、DefaultOrgKey、ServerURLKey、SCMTypeKey、APISecretNameKey、APISecretKeyKey、APISecretNamespaceKey以及五个 backoff 键)。其中:
fetch-timeout通过GetResolutionTimeout读取并解析为time.Duration,用于限制单次解析耗时(pkg/resolution/resolver/git/resolver.go)。- backoff 参数在
GetGitResolverBackoff(pkg/resolution/resolver/git/config.go)中解析,非法值会被记录 warning 并回退到默认值,从而保证重试行为始终可用;重试逻辑ResolveWithRetry使用wait.ExponentialBackoffWithContext实现(pkg/resolution/resolver/git/resolver.go)。
Caching Options
Git Resolver 支持缓存已解析资源以提升性能,缓存行为由cache参数控制:
| 缓存值 | 说明 |
|---|---|
always | 始终缓存解析结果。这是最激进的缓存策略,会缓存所有解析到的资源,无论其来源。 |
never | 从不缓存。完全禁用缓存。 |
auto | 仅在 revision 为 commit hash 时缓存(默认值)。 |
从源码看,auto的依据是Resolver.IsImmutable(pkg/remoteresolution/resolver/git/resolver.go):当revision参数长度为 40(SHA-1)或 64(SHA-256)且能通过hex.DecodeString解码时,认为其不可变,才允许进入缓存流程。
Cache Configuration
解析器缓存可以全局配置,使用resolver-cache-configConfigMap,它控制所有解析器的缓存大小与 TTL:
| 配置项 | 说明 | 默认值 | 示例值 |
|---|---|---|---|
max-size | 缓存最大条目数 | 1000 | 500、2000 |
ttl | 缓存条目存活时间(time-to-live) | 5m | 10m、1h |
仓库自带的默认 ConfigMap 位于 config/resolvers/resolver-cache-config.yaml,其中max-size: "1000"、ttl: "5m"。
ConfigMap 名称可通过RESOLVER_CACHE_CONFIG_MAP_NAME环境变量自定义;未设置时默认为resolver-cache-config。
此外,可以给 Git Resolver 单独设置默认缓存模式:在git-resolver-configConfigMap 中添加default-cache-mode选项,用于覆盖该解析器的系统默认值(auto):
| 配置项 | 说明 | 合法值 | 默认 |
|---|---|---|---|
default-cache-mode | 未指定cache参数时的默认缓存行为 | always、never、auto | auto |
示例:
apiVersion: v1 kind: ConfigMap metadata: name: git-resolver-config namespace: tekton-pipelines-resolvers data: default-cache-mode: "always" # 默认总是缓存,除非 Task/Pipeline 显式指定其他值Usage
Git Clone 模式(git clone)
该模式支持匿名克隆与认证克隆。解析时会先对仓库做浅克隆,再拉取并检出指定的 revision。
注意:如果 revision 是一个没有被任何分支或标签引用指向的 commit SHA,则能否成功拉取取决于 Git 提供方的uploadpack.allowReachableSHA1InWant设置。这对 GitHub、GitLab 等主流提供方不是问题,但 Gitea 等小型或自托管提供方可能需要关注。
Task 解析
apiVersion: tekton.dev/v1beta1 kind: TaskRun metadata: name: git-clone-demo-tr spec: taskRef: resolver: git params: - name: url value: https://github.com/tektoncd/catalog.git - name: revision value: main - name: pathInRepo value: task/git-clone/0.6/git-clone.yaml # 取消注释以下行以使用含令牌的 Secret # - name: gitToken # value: "secret-with-token" # - name: gitTokenKey (可选,默认为 "token") # value: "token"Pipeline 解析
apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: name: git-clone-demo-pr spec: pipelineRef: resolver: git params: - name: url value: https://github.com/tektoncd/catalog.git - name: revision value: main - name: pathInRepo value: pipeline/simple/0.1/simple.yaml # 取消注释以下行以使用含令牌的 Secret # - name: gitToken # value: "secret-with-token" # - name: gitTokenKey (可选,默认为 "token") # value: "token" params: - name: name value: Ranni关于gitToken/gitTokenKey的底层行为:在 pkg/resolution/resolver/git/resolver.go 中,若指定了gitToken,解析器会从PipelineRun所在命名空间读取对应 Secret(键名默认token),并以username=git、password=<token>的方式构造 HTTP Basic 认证头(见 pkg/resolution/resolver/git/repository.go 中的GIT_AUTH_HEADER机制),注意该认证方式仅适用于 HTTP(S) 克隆。
认证 API 模式
认证 API 支持私有仓库,并且只拉取指定路径下的单个文件,不做完整克隆。
使用认证 API 时,可以使用go-scm中已有实现的所有 SCM 提供方驱动。并非所有go-scm实现都经过 Git Resolver 测试,但已知以下提供方可用:
- github.com 与 GitHub Enterprise
- gitlab.com 与自托管 GitLab
- Gitea
- BitBucket Server
- BitBucket Cloud
Task 解析
apiVersion: tekton.dev/v1beta1 kind: TaskRun metadata: name: git-api-demo-tr spec: taskRef: resolver: git params: - name: org value: tektoncd - name: repo value: catalog - name: revision value: main - name: pathInRepo value: task/git-clone/0.6/git-clone.yaml使用自定义令牌连接自定义 SCM 提供方的 Task 解析
apiVersion: tekton.dev/v1beta1 kind: TaskRun metadata: name: git-api-demo-tr spec: taskRef: resolver: git params: - name: org value: tektoncd - name: repo value: catalog - name: revision value: main - name: pathInRepo value: task/git-clone/0.6/git-clone.yaml # my-secret-token 应创建在创建 pipelinerun 的命名空间中, # 并在该 Secret 的 token 键中存放 GitHub personal access token。 - name: token value: my-secret-token - name: tokenKey value: token - name: scmType value: github - name: serverURL value: https://ghe.mycompany.comPipeline 解析
apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: name: git-api-demo-pr spec: pipelineRef: resolver: git params: - name: org value: tektoncd - name: repo value: catalog - name: revision value: main - name: pathInRepo value: pipeline/simple/0.1/simple.yaml params: - name: name value: Ranni认证 API 模式的源码流程(pkg/resolution/resolver/git/resolver.go)为:从参数或配置解析scmType/serverURL(参数优先级高于配置,见getSCMTypeAndServerURL)→ 从tokenSecret(或配置的api-token-secret-name)读取令牌 → 通过factory.NewClient创建 SCM 客户端 →Contents.Find获取文件内容 →Git.FindCommit获取 ref 对应的真实 commit SHA →Repositories.Find获取仓库 clone URL。API 令牌会被缓存在 LRU 缓存中(容量 1024、TTL 5 分钟,见 pkg/resolution/resolver/git/resolver.go),降低对 API Server 的 Secret 读取压力。
为多个 Git 提供方指定配置
可以为多个提供方(甚至同一提供方的多套配置)指定不同配置,供不同 Tekton 资源使用。做法是:先在 ConfigMap 中以唯一的标识符作为键前缀写入配置细节;在 Tekton 资源中,通过额外的参数configKey传入该唯一标识符来选中对应配置。若未传configKey参数,则使用default。ConfigMap 中不写标识符、或使用标识符default,即为 Git Resolver 的默认配置。
注意:在 ConfigMap 中指定配置时,configKey不能包含.。
该机制的源码实现在GetGitResolverConfig(pkg/resolution/resolver/git/config.go):ConfigMap 中每个键按.拆分为<configIdentifier>.<configKey>两段,无前缀的键归入default配置;GetScmConfigForParamConfigKey(pkg/resolution/resolver/git/resolver.go)则根据configKey参数选择对应配置。
示例 ConfigMap
可以在git-resolver-configConfigMap 中像这样指定多套配置,以上提到的所有键均受支持:
apiVersion: v1 kind: ConfigMap metadata: name: git-resolver-config namespace: tekton-pipelines-resolvers labels: app.kubernetes.io/component: resolvers app.kubernetes.io/instance: default app.kubernetes.io/part-of: tekton-pipelines data: # configuration 1,未提供 configKey 或 configKey 为 default 时使用的默认配置 fetch-timeout: "1m" default-url: "https://github.com/tektoncd/catalog.git" default-revision: "main" scm-type: "github" server-url: "" api-token-secret-name: "" api-token-secret-key: "" api-token-secret-namespace: "default" default-org: "" # configuration 2,configKey 参数传 test1 时使用 test1.fetch-timeout: "5m" test1.default-url: "" test1.default-revision: "stable" test1.scm-type: "github" test1.server-url: "api.internal-github.com" test1.api-token-secret-name: "test1-secret" test1.api-token-secret-key: "token" test1.api-token-secret-namespace: "test1" test1.default-org: "tektoncd" # configuration 3,configKey 参数传 test2 时使用 test2.fetch-timeout: "10m" test2.default-url: "" test2.default-revision: "stable" test2.scm-type: "gitlab" test2.server-url: "api.internal-gitlab.com" test2.api-token-secret-name: "test2-secret" test2.api-token-secret-key: "pat" test2.api-token-secret-namespace: "test2" test2.default-org: "tektoncd-infra"Task 解析(按 configKey 选择配置)
通过传configKey参数并使其值匹配 ConfigMap 中的配置键,即可选中对应配置:
apiVersion: tekton.dev/v1beta1 kind: TaskRun metadata: name: git-api-demo-tr spec: taskRef: resolver: git params: - name: org value: tektoncd - name: repo value: catalog - name: revision value: main - name: pathInRepo value: task/git-clone/0.6/git-clone.yaml - name: configKey value: test1Pipeline 解析(按 configKey 选择配置)
apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: name: git-api-demo-pr spec: pipelineRef: resolver: git params: - name: org value: tektoncd - name: repo value: catalog - name: revision value: main - name: pathInRepo value: pipeline/simple/0.1/simple.yaml - name: configKey value: test2 params: - name: name value: RanniResolutionRequest状态
ResolutionRequest.Status.RefSource字段记录了远程资源的来源,包含三个子字段:url、digest和entrypoint。
url- 匿名克隆场景下,就是用户为
url参数提供的值,并转换为 SPDX 下载格式(即前缀git+)。从源码看,resolvedGitResource.RefSource()通过spdxGit(url)返回git+<url>(pkg/resolution/resolver/git/resolver.go)。 - 使用 SCM API 时,则是从 SCM 仓库服务获取的仓库 clone URL,同样转换为 SPDX 下载格式。
- 匿名克隆场景下,就是用户为
digest- Git Resolver 支持 SHA-1 与 SHA-256 两种 commit hash 用于 revision 校验(对应 Git 的 hash function transition 机制)。
- 其值是在解析资源那一刻的实际 commit SHA,即使
revision参数传的是标签或分支名也是如此。
entrypoint:用户为path参数提供的值。
示例:
- Pipeline 解析
apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: name: git-demo spec: pipelineRef: resolver: git params: - name: url value: https://github.com/<username>/<reponame>.git - name: revision value: main - name: pathInRepo value: pipeline.yamlResolutionRequest
apiVersion: resolution.tekton.dev/v1alpha1 kind: ResolutionRequest metadata: labels: resolution.tekton.dev/type: git ... spec: params: pathInRepo: pipeline.yaml revision: main url: https://github.com/<username>/<reponame>.git status: refSource: uri: git+https://github.com/<username>/<reponame>.git digest: sha1: <The latest commit sha on main at the moment of resolving> entrypoint: pipeline.yaml data: a2luZDogUGxxxx...从源码 pkg/resolution/resolver/git/resolver.go 可以看到RefSource()的实现:URI为git+<url>,Digest中的键固定为sha1,值为解析时的实际 commit SHA,EntryPoint为pathInRepo。值得注意的是,解析出的资源注解中还包含AnnotationKeyRevision、AnnotationKeyPath、AnnotationKeyURL等元数据(pkg/resolution/resolver/git/resolver.go),可供下游消费。
安全与可靠性设计(源码补充)
除前文已提到的参数校验外,Git Resolver 在源码层面还内置了以下安全设计,值得使用者了解:
- 克隆与检出参数隔离:
git clone、git fetch命令均使用--分隔符确保 URL 与 revision 被当作路径/refspec 而非命令行参数解析(pkg/resolution/resolver/git/repository.go),配合"revision 不能以-开头"的校验,构成对 Git 参数注入的双重防护。 - 禁用终端交互:克隆时设置
GIT_TERMINAL_PROMPT=false,避免 Git 在认证失败时进入交互式提示。 - 令牌防泄露校验:在认证 API 模式下,若用户未提供
token参数却指定了自定义serverURL,且该 URL 与系统配置不一致,请求会被拒绝(custom serverURL ... requires a token parameter),防止把系统令牌发送到不可信的服务端(pkg/resolution/resolver/git/resolver.go)。 - 路径穿越防护:读取文件时会先做符号链接解析,再通过相对路径包含性检查拦截任何试图逃逸仓库目录的路径(pkg/resolution/resolver/git/repository.go)。
仓库内的测试用例(如 pkg/resolution/resolver/git/resolver_test.go 与 pkg/resolution/resolver/git/config_test.go)覆盖了参数校验、默认参数填充、多配置选择、缓存模式判断等核心路径;pkg/resolution/resolver/git/testdata/下还提供了可复现的测试仓库目录结构(test-org/test-repo/refs/main/...),可作为理解pathInRepo与 revision 组织方式的参考。
总结
Git Resolver 为 Tekton 集群提供了"按需从 Git 仓库拉取 Task / Pipeline 定义"的远程解析能力。选择匿名/认证克隆还是认证 API,取决于仓库可见性、仓库规模与速率限制的权衡;通过git-resolver-configConfigMap(配合configKey支持多套 SCM 配置)与resolver-cache-config(全局缓存大小与 TTL)可以精细控制解析行为;解析结果会通过ResolutionRequest.Status.RefSource记录来源(SPDX 格式 URL + 实际 commit digest + entrypoint),为供应链溯源提供依据。在配置真实环境时,建议将 config/resolvers/git-resolver-config.yaml 作为起点,并根据组织的 SCM 提供方、令牌管理与安全要求逐项调整。
- 云原生
- CI/CD
- DevOps
- 后端
【免费下载链接】pipeline
A cloud-native Pipeline resource.
相关推荐
Tekton Pipeline Hub Resolver 实战指南:从 Artifact Hub 解析远程 Task、Pipeline 与 StepAction
Tekton Pipeline Hub Resolver 实战指南:从 Artifact Hub 解析远程 Task、Pipeline 与 StepAction
云原生CI/CDDevOps后端用lstm-char-cnn-tensorflow训练PTB数据集完整流程:从数据准备到模型评估
用lstm char cnn tensorflow训练PTB数据集完整流程:从数据准备到模型评估 你是否想要掌握深度学习语言模型的实战技能?今天我将为你详细介绍
云原生CI/CDDevOps后端如何5分钟掌握SPT-AKI Profile Editor:逃离塔科夫离线版终极存档修改工具完全指南
如何5分钟掌握SPT AKI Profile Editor:逃离塔科夫离线版终极存档修改工具完全指南 还在为《逃离塔科夫》SPT AKI离线服务器的角色培养而烦
云原生CI/CDDevOps后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考