1. “skills”不是功能按钮而是Agent时代的能力封装范式最近在GKE集群里部署一个Gemini驱动的自动化运维Agent时我反复看到控制台里跳出“skills not found”“skills registration failed”这类报错。一开始我以为是权限配置错了翻遍IAM策略文档、重试了七次服务账号绑定结果问题依旧。直到某天深夜调试日志时我注意到一条被忽略的INFO级输出“Loading skill manifest from /etc/skill-config/v1/healthcheck.yaml”。那一刻才真正意识到——“skills”根本不是某个具体工具或插件的名字而是一套标准化的能力注册与调用协议是Agent Platform底层运行时识别、加载、编排和执行原子化任务的契约语言。这解释了为什么所有热词都绕不开它前端开发skills、分镜skills、挖洞skills、写论文skills……它们表面是五花八门的功能模块内核却共享同一套结构规范——YAML定义的元数据 容器化执行体 统一API网关接入。就像当年Docker镜像之于容器生态“skills”就是Agent生态的最小可交付单元。你下载的不是.exe或.dmg安装包而是一个带签名的OCI镜像里面封装了能力描述、输入校验规则、超时策略、依赖清单甚至失败回滚逻辑。提示当你在Google Cloud Console里点开Agent Platform的“Skills Library”看到的每一个卡片背后都是一个符合skills.cloud.google.com/v1API Schema的Kubernetes Custom ResourceCR。它不依赖特定语言——Python写的健康检查skill和Rust写的日志分析skill在平台眼里完全等价因为运行时只认CR里的spec.runtime.image和spec.input.schema字段。这也直接回答了高频热搜里那个让人抓狂的报错“your account is not eligible for gemini code assist for individuals at this time”。它根本不是账户资格问题而是你的GCP项目尚未启用Agent Platform的Skills Runtime服务或者Service Account缺少roles/agentplatform.skillsUser这个细粒度角色——该角色控制的不是“能不能用Gemini”而是“能否向Skills Registry提交并执行自定义能力定义”。所以别再搜“skills下载平台有哪些”了。真正的skills没有中心化市场它就藏在你的GitHub仓库里一个skills/目录几份YAML一个Dockerfile一次gcloud agent-platform skills deploy命令。接下来我会带你从零构建一个真实可用的skills——不是Demo而是我在生产环境每天调度3700次的“Kubernetes Pod异常自动归因skill”它能精准定位OOMKilled、CrashLoopBackOff、ImagePullBackOff三类故障的根因并生成修复建议。整个过程不碰任何敏感配置全部基于公开GCP权限模型实现。2. 解构skills的三大核心构件Manifest、Runtime与Registry要真正掌控skills必须拆开它的物理结构。它不像传统软件有安装程序或GUI向导而是一组严格约束的组件协同工作。我把它们称为“技能铁三角”Manifest是身份证Runtime是执行引擎Registry是调度中枢。三者缺一不可且版本必须严格对齐——我曾因Manifest里声明runtimeVersion: v1.2而集群里实际运行v1.1的Runtime导致所有skills静默失败长达47小时监控告警毫无反应。2.1 Manifest用YAML写的技能宪法Manifest文件通常命名为skill.yaml是skills的唯一权威定义。它不是配置文件而是向Agent Platform提交的“能力注册申请”。下面是我正在用的Pod异常归因skill的完整Manifest已脱敏处理# skills/pod-incident-analyzer/skill.yaml apiVersion: skills.cloud.google.com/v1 kind: Skill metadata: name: pod-incident-analyzer namespace: default labels: team: infra-ai criticality: high spec: description: Automatically diagnose common Kubernetes Pod failures and suggest remediation version: 1.4.2 # 这里定义技能的“输入契约” input: schema: type: object properties: podName: type: string description: Name of the Pod to analyze (e.g., nginx-deployment-5c8b9d7f4-abcde) namespace: type: string default: default timeoutSeconds: type: integer minimum: 30 maximum: 300 default: 120 required: [podName] # 这里定义技能的“执行契约” runtime: image: gcr.io/my-project/skills/pod-incident-analyzer:v1.4.2 imagePullPolicy: Always resources: limits: memory: 512Mi cpu: 500m requests: memory: 256Mi cpu: 200m securityContext: runAsNonRoot: true capabilities: drop: [ALL] # 这里定义技能的“行为契约” lifecycle: timeoutSeconds: 180 retryPolicy: maxAttempts: 2 backoffSeconds: 10 # 这里定义技能的“信任契约” signing: keyId: prod-skill-signing-key-v3 signature: sha256:abcdef1234567890...关键字段解析input.schema这是最易被忽视的硬性约束。Agent Platform在调用前会严格校验传入JSON是否符合此Schema。我见过太多人把podName传成pod-123正确却写成{name: pod-123}错误结果得到400 Bad Request: input validation failed。Schema不是可选文档而是运行时强制执行的类型系统。runtime.image必须是GCR或Artifact Registry中的有效镜像URI。注意不能是Docker Hub地址GKE默认禁用也不能是本地localhost:5000平台无法拉取。我习惯用gcloud builds submit --tag gcr.io/$PROJECT_ID/skills/xxx构建确保镜像带SHA256摘要。lifecycle.retryPolicy这不是简单的重试。Agent Platform会在第一次失败后等待backoffSeconds秒然后以全新上下文新Pod、新网络命名空间重新启动容器。这意味着你的skill代码必须是幂等的——不能依赖上一次执行的临时文件或内存状态。注意Manifest中signing.signature字段必须由项目级密钥管理服务Cloud KMS生成。我用以下命令生成签名# 先用KMS加密原始Manifest内容 gcloud kms encrypt \ --locationglobal \ --keyringskill-signing-keys \ --keyprod-skill-signing-key-v3 \ --plaintext-fileskill.yaml \ --ciphertext-fileskill.yaml.sig # 然后将base64编码的sig填入manifest2.2 Runtime轻量级沙箱不是通用容器Runtime是skills的执行环境但它绝非普通Kubernetes Pod。Agent Platform的Runtime有三项严苛限制单进程强制约束容器启动后必须只有一个主进程PID 1。如果你的Dockerfile写了CMD [sh, -c, python main.py nginx -g daemon off;]平台会立即终止容器并报ERROR: multiple processes detected。正确做法是用supervisord或tini作为init进程但更推荐用Go/Rust写单二进制——我的归因skill就是用Go写的编译后仅12MB无依赖。网络策略锁定Runtime默认禁止出站连接egress。想调用GKE API必须显式声明spec.runtime.networkPolicy.egress。例如networkPolicy: egress: - to: - ipBlock: cidr: 10.0.0.0/8 # GKE内部服务网段 ports: - protocol: TCP port: 443我曾因此卡住两天skill需要调用https://container.googleapis.com/v1/projects/.../zones/.../clusters/...获取节点信息但Manifest里忘了加这条规则日志只显示connection refused毫无提示。文件系统只读根目录/是只读的。所有写操作必须限定在/tmp或通过emptyDir挂载的卷。我的skill会把Pod事件日志缓存到/tmp/pod-events.json如果误写到/var/log/skill.log会直接崩溃。这些限制不是为了刁难开发者而是保障多租户安全。Agent Platform可能在同一节点上调度来自不同团队的skillsRuntime的沙箱强度直接决定整个集群的隔离水位。2.3 Registry不是应用商店而是Kubernetes CRD实例库Skills Registry本质是GKE集群中的一组CustomResourceDefinitionsCRD。当你执行gcloud agent-platform skills deploy实际发生的是gcloudCLI将skill.yaml转换为Skill资源对象向集群API Server发送POST /apis/skills.cloud.google.com/v1/namespaces/default/skills请求Agent Platform的Operator控制器监听到新资源验证签名、拉取镜像、创建对应Job模板。你可以用原生kubectl查看所有已注册skills# 查看所有skills需有view权限 kubectl get skills -A # 查看某个skill的详细状态 kubectl get skill pod-incident-analyzer -o yaml # 查看Operator的实时同步日志排查注册失败 kubectl logs -n agent-platform-system deployment/agent-platform-operator -c managerRegistry的关键特性命名空间隔离skills资源支持namespace字段不同团队可在各自命名空间注册同名skill互不影响。版本灰度通过metadata.labels打标配合Agent调用时指定labelSelector可实现A/B测试。例如上线v1.5版时先给它打env: canary标签只让10%的流量命中。自动GC未被任何Agent引用超过30天的skills会被Operator自动标记为Deprecated并最终删除避免注册表膨胀。提示Registry不存储skill代码只存Manifest元数据。真正的执行体镜像永远在Artifact Registry里。这种分离设计让更新变得极轻量——改一行Manifest字段重新deploy旧镜像仍可运行新调用走新配置。3. 从零构建一个生产级skillsPod异常归因实战现在我们动手构建一个真实可用的skills。目标很明确给定Pod名称和命名空间自动诊断其失败原因并返回结构化修复建议。这不是玩具Demo而是我司SRE团队每天依赖的核心能力。整个过程分为四步环境准备、代码实现、镜像构建、注册部署。每一步我都附上踩坑细节和实测参数。3.1 环境准备最小可行权限集别急着写代码先搞定权限。Agent Platform要求精确到字段的RBAC控制。以下是生产环境验证过的最小权限集保存为role-skill-deployer.yaml# role-skill-deployer.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: skill-deployer rules: - apiGroups: [skills.cloud.google.com] resources: [skills] verbs: [create, update, get, list, delete] - apiGroups: [] resources: [secrets] verbs: [get] # 用于拉取私有镜像的registry secret - apiGroups: [batch] resources: [jobs] verbs: [create, get, list, watch] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: skill-deployer-binding subjects: - kind: ServiceAccount name: skill-deployer-sa namespace: default roleRef: kind: ClusterRole name: skill-deployer apiGroup: rbac.authorization.k8s.io创建服务账号并绑定# 创建SA kubectl create serviceaccount skill-deployer-sa -n default # 绑定角色 kubectl apply -f role-skill-deployer.yaml # 为SA添加GCP IAM权限关键 gcloud projects add-iam-policy-binding $PROJECT_ID \ --memberserviceAccount:skill-deployer-sa${PROJECT_ID}.svc.id.goog[default/default] \ --roleroles/agentplatform.skillsUser # 为SA添加K8s Secret读取权限若镜像在私有仓库 kubectl create secret docker-registry gcr-json-key \ --docker-serverhttps://gcr.io \ --docker-username_json_key \ --docker-password$(cat ./gcp-service-account-key.json) \ --docker-emailnotval.id \ -n default踩坑实录我最初用roles/editor全局角色结果发现skills能读取整个项目的所有Secret严重违反最小权限原则。后来审计发现roles/agentplatform.skillsUser已足够它只授权skills.cloud.google.comAPI组的操作且不包含secrets读取权——必须显式通过K8s RBAC授予这才是安全的设计。3.2 代码实现Go语言单二进制127行解决核心逻辑我选择Go而非Python因为Runtime对启动延迟极其敏感。Python解释器加载依赖导入平均耗时800ms而Go二进制冷启动仅23ms。以下是核心诊断逻辑main.go已精简至最简路径package main import ( context encoding/json fmt io log net/http os time k8s.io/client-go/kubernetes k8s.io/client-go/rest k8s.io/client-go/tools/clientcmd ) type Input struct { PodName string json:podName Namespace string json:namespace TimeoutSeconds int json:timeoutSeconds } type Output struct { Status string json:status Diagnosis string json:diagnosis Remediation []string json:remediation Details map[string]string json:details } func main() { // 1. 从STDIN读取输入Agent Platform标准协议 var input Input if err : json.NewDecoder(os.Stdin).Decode(input); err ! nil { fmt.Fprintln(os.Stderr, ERROR: invalid input JSON:, err) os.Exit(1) } // 2. 构建K8s客户端使用InClusterConfig无需kubeconfig config, err : rest.InClusterConfig() if err ! nil { log.Fatalf(Failed to get in-cluster config: %v, err) } clientset, err : kubernetes.NewForConfig(config) if err ! nil { log.Fatalf(Failed to create clientset: %v, err) } // 3. 获取Pod对象及事件 ctx, cancel : context.WithTimeout(context.Background(), time.Duration(input.TimeoutSeconds)*time.Second) defer cancel() pod, err : clientset.CoreV1().Pods(input.Namespace).Get(ctx, input.PodName, metav1.GetOptions{}) if err ! nil { fmt.Printf({status:error,diagnosis:Failed to get Pod %s: %s}, input.PodName, err.Error()) return } events, err : clientset.CoreV1().Events(input.Namespace).List(ctx, metav1.ListOptions{ FieldSelector: fmt.Sprintf(involvedObject.name%s,involvedObject.kindPod, input.PodName), }) if err ! nil { fmt.Printf({status:error,diagnosis:Failed to list events: %s}, err.Error()) return } // 4. 核心诊断逻辑简化版生产版含更多规则 output : Output{Status: success} switch pod.Status.Phase { case Pending: output.Diagnosis Pod stuck in Pending state output.Remediation []string{ Check if node has sufficient CPU/Memory, Verify PersistentVolumeClaim exists and bound, Inspect node conditions with kubectl describe node, } case Running: if len(pod.Status.ContainerStatuses) 0 pod.Status.ContainerStatuses[0].State.Waiting ! nil { waiting : pod.Status.ContainerStatuses[0].State.Waiting switch waiting.Reason { case ImagePullBackOff: output.Diagnosis Failed to pull container image output.Remediation []string{ Verify image name and tag exist in registry, Check if service account has Artifact Registry permissions, } case CrashLoopBackOff: output.Diagnosis Container repeatedly crashes on startup output.Remediation []string{ Check container logs: kubectl logs input.PodName, Verify application dependencies are satisfied, } } } case Failed: if pod.Status.Reason OOMKilled { output.Diagnosis Pod killed due to Out-of-Memory output.Remediation []string{ Increase memory limits in deployment spec, Profile application memory usage with pprof, } } } // 5. 输出JSON到STDOUTAgent Platform标准协议 outBytes, _ : json.Marshal(output) fmt.Println(string(outBytes)) }关键设计说明无外部依赖不引入github.com/golang/example等非标准库避免镜像体积膨胀。所有K8s client逻辑用k8s.io/client-go官方库。STDIN/STDOUT协议Agent Platform通过管道传递JSON输入skill必须从os.Stdin读向os.Stdout写JSON输出。这是硬性约定不支持HTTP端口暴露。超时双重保障Manifest里设lifecycle.timeoutSeconds代码里再用context.WithTimeout防止goroutine泄漏。编译命令确保交叉编译# 在Linux环境下编译Linux二进制 CGO_ENABLED0 GOOSlinux go build -a -ldflags -extldflags -static -o pod-incident-analyzer . # 验证静态链接 ldd pod-incident-analyzer # 应显示 not a dynamic executable3.3 镜像构建多阶段Dockerfile最终镜像仅12.3MBDockerfile采用经典多阶段构建彻底剥离编译环境# builder stage FROM golang:1.21-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED0 GOOSlinux go build -a -ldflags -extldflags -static -o pod-incident-analyzer . # final stage FROM alpine:3.18 RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --frombuilder /app/pod-incident-analyzer . CMD [./pod-incident-analyzer]构建并推送# 构建 docker build -t gcr.io/$PROJECT_ID/skills/pod-incident-analyzer:v1.4.2 . # 推送需先gcloud auth configure-docker docker push gcr.io/$PROJECT_ID/skills/pod-incident-analyzer:v1.4.2镜像大小对比实测阶段镜像大小说明Ubuntu基础镜像Go编译1.2GB包含gcc、glibc等完全不可用AlpineGo编译327MB仍含Go工具链Runtime拒绝拉取多阶段静态二进制12.3MB符合Runtime要求实测启动时间23ms实测心得不要用scratch镜像。虽然它更小5MB但缺失ca-certificates导致HTTPS调用失败。Alpine的ca-certificates包仅2MB换来的是100%的TLS可靠性。3.4 注册部署四步完成失败时有完整回溯链部署命令本身很简单但失败排查才是重点。以下是标准流程# 1. 验证Manifest语法本地 gcloud agent-platform skills validate --manifestskills/pod-incident-analyzer/skill.yaml # 2. 部署到Registry会触发Operator同步 gcloud agent-platform skills deploy \ --manifestskills/pod-incident-analyzer/skill.yaml \ --project$PROJECT_ID \ --locationus-central1 # 3. 检查Registry状态 kubectl get skill pod-incident-analyzer -o wide # 4. 手动触发测试模拟Agent调用 echo {podName:nginx-5c8b9d7f4-abcde,namespace:default} | \ gcloud agent-platform skills execute \ --skillpod-incident-analyzer \ --project$PROJECT_ID \ --locationus-central1当第2步失败时按此顺序排查检查Operator日志kubectl logs -n agent-platform-system deployment/agent-platform-operator -c manager | grep pod-incident-analyzer检查镜像拉取kubectl describe skill pod-incident-analyzer看Events里是否有Failed to pull image检查签名验证kubectl get skill pod-incident-analyzer -o jsonpath{.status.conditions[?(.typeValidated)].message}检查K8s权限kubectl auth can-i create jobs --assystem:serviceaccount:default:skill-deployer-sa我遇到的最隐蔽问题Operator日志显示image pull failed但docker pull在本地成功。最后发现是GKE节点池启用了--enable-shielded-nodes要求镜像必须用Binary Authorization签名。解决方案是在gcloud builds submit时加--attestations参数。4. Skills调用与编排不止于单点执行构建智能工作流注册完skills只是起点。Agent Platform的价值在于将多个skills像乐高一样组合形成端到端工作流。比如我们的“Pod异常闭环处理”工作流就串联了5个skillspod-incident-analyzer→node-health-check→log-analyzer→config-validator→remediation-executor。下面详解如何用YAML定义这种编排。4.1 单skills调用REST API与gcloud CLI双通道Agent Platform提供两种调用方式适用不同场景方式一gcloud CLI适合调试与CI/CD# 同步调用阻塞等待结果超时由CLI控制 gcloud agent-platform skills execute \ --skillpod-incident-analyzer \ --input{podName:nginx-5c8b9d7f4-abcde,namespace:default} \ --projectmy-project \ --locationus-central1 # 异步调用返回Execution ID后续轮询 EXEC_ID$(gcloud agent-platform skills execute \ --skillpod-incident-analyzer \ --input{podName:nginx-5c8b9d7f4-abcde,namespace:default} \ --async \ --projectmy-project \ --locationus-central1 \ --formatvalue(name)) # 轮询状态 gcloud agent-platform skills executions describe $EXEC_ID \ --projectmy-project \ --locationus-central1方式二REST API适合集成到Web UI或第三方系统# 获取访问令牌 TOKEN$(gcloud auth print-access-token) # 发起调用注意Endpoint URL需替换为实际区域 curl -X POST \ https://agentplatform.googleapis.com/v1/projects/my-project/locations/us-central1/skills/pod-incident-analyzer:execute \ -H Authorization: Bearer $TOKEN \ -H Content-Type: application/json \ -d { input: { podName: nginx-5c8b9d7f4-abcde, namespace: default } }关键参数说明--async参数至关重要。生产环境中skills执行可能长达数分钟如日志分析同步调用会导致HTTP连接超时。异步模式下Platform返回executionId: projects/my-project/locations/us-central1/executions/abc123你可用它查询状态或取消执行。4.2 多skills编排用Execution Graph定义依赖关系Agent Platform的Execution Graph功能允许你用YAML声明skills间的执行顺序与数据流。以下是我们生产环境的pod-remediation-workflow.yaml# workflows/pod-remediation.yaml apiVersion: execution.cloud.google.com/v1 kind: ExecutionGraph metadata: name: pod-remediation-graph namespace: default spec: # 定义输入契约整个工作流的统一入口 input: schema: type: object properties: podName: type: string namespace: type: string required: [podName] # 定义节点每个skills实例 nodes: - name: analyzer skillRef: pod-incident-analyzer input: # 从工作流输入映射 podName: $.input.podName namespace: $.input.namespace - name: healthcheck skillRef: node-health-check input: # 从analyzer输出动态获取 nodeName: $.nodes.analyzer.output.nodeName # 设置条件仅当analyzer诊断为节点问题时执行 condition: $.nodes.analyzer.output.diagnosis contains node - name: loganalysis skillRef: log-analyzer input: podName: $.input.podName namespace: $.input.namespace # 并行执行不依赖其他节点 parallel: true - name: validator skillRef: config-validator input: deploymentName: $.nodes.analyzer.output.deploymentName # 定义最终输出聚合所有节点结果 output: schema: type: object properties: summary: type: string actions: type: array items: type: string value: summary: $.nodes.analyzer.output.diagnosis actions: | [ $.nodes.analyzer.output.remediation, $.nodes.healthcheck.output.remediation, $.nodes.validator.output.suggestions ]Execution Graph的核心机制数据绑定用$.nodes.xxx.output.yyy语法跨节点传递数据。Platform在运行时自动解析JSONPath注入到下游skills的input中。条件分支condition字段支持完整JSONPath布尔表达式。上面例子中只有analyzer输出包含“node”时healthcheck才会触发。并行执行parallel: true的节点会同时启动不阻塞主流程。loganalysis和analyzer就是并行的缩短总耗时。部署与触发# 部署Execution Graph gcloud agent-platform execution-graphs deploy \ --manifestworkflows/pod-remediation.yaml \ --projectmy-project \ --locationus-central1 # 触发工作流 gcloud agent-platform execution-graphs execute \ --graphpod-remediation-graph \ --input{podName:nginx-5c8b9d7f4-abcde,namespace:default} \ --projectmy-project \ --locationus-central1实测性能单skills执行平均耗时1.2秒5节点串行需6秒用Execution Graph并行后总耗时降至2.8秒提升53%。更重要的是它把原本散落在5个脚本里的逻辑收敛到一份声明式YAML中可版本化、可审计、可复用。4.3 监控与告警用Cloud Monitoring追踪skills健康度Skills不是黑盒Agent Platform将其所有指标暴露给Cloud Monitoring。以下是必须监控的4个黄金信号指标名称监控目的健康阈值查询示例agentplatform/skills/execution_count技能调用频次突增/突降50%fetch cloud_agentplatform_skillagentplatform/skills/execution_duration执行耗时P9530秒告警fetch cloud_agentplatform_skillagentplatform/skills/execution_errors错误率5%持续5分钟fetch cloud_agentplatform_skillagentplatform/skills/registry_sync_durationRegistry同步延迟60秒告警fetch cloud_agentplatform_operator创建告警策略CLI# 创建错误率告警 gcloud monitoring alert-policies create \ --projectmy-project \ --display-nameSkills Error Rate High \ --condition-display-nameError Rate 5% \ --condition-filtermetric.type\agentplatform/skills/execution_errors\ resource.type\cloud_agentplatform_skill\ \ --condition-threshold-value0.05 \ --notification-channel-ids$(gcloud monitoring notification-channels list --formatvalue(name) --filterdisplayNameslack-webhook) \ --combinerOR关键洞察我们发现execution_duration指标在GKE Autopilot集群上比Standard集群高40%原因是Autopilot的节点启动延迟更高。这促使我们为Autopilot环境单独设置P95阈值45秒而非一刀切。5. 生产环境避坑指南那些文档不会写的12个致命细节经过23个skills在生产环境6个月的锤炼我总结出12个血泪教训。它们不在任何官方文档里但每个都曾让我凌晨三点爬起来救火。5.1 Manifest字段陷阱看似可选实则必填spec.runtime.resources.requests文档说“可选”但GKE Autopilot集群强制要求。不填则报ERROR: resource requests must be specified for Autopilot.解决方案始终填写哪怕填最小值memory: 128Mi, cpu: 100m。spec.lifecycle.timeoutSeconds不填则默认30秒但很多skills如日志分析需要2分钟。填了又不能超过Runtime最大值默认180秒。解决方案在Manifest里明确写timeoutSeconds: 180并在代码里用context.WithTimeout做二次保护。spec.input.schema中的default字段文档没说清它只在Agent Platform调用时生效不影响你本地gcloud skills execute测试。本地测试必须传全量JSON。解决方案本地测试用jq生成完整输入echo {podName:test} | jq .namespacedefault。5.2 Runtime环境雷区沙箱里的隐形墙DNS解析失败Runtime默认用/etc/resolv.conf但GKE Autopilot的CoreDNS配置与Standard不同。nslookup google.com在Standard成功在Autopilot超时。解决方案在Dockerfile里显式写死DNSRUN echo nameserver 169.254.169.254 /etc/resolv.conf。时区问题Alpine镜像默认UTC但你的日志分析skill可能依赖本地时区。date命令输出Wed Jan 1 00:00:00 UTC 1970。解决方案在Dockerfile加ENV TZAsia/Shanghai并RUN apk add --no-cache tzdata。大文件读写Runtime的/tmp默认只有100MB。当skills需要处理1GB日志文件时write: no space left on device。解决方案在Manifest里声明emptyDir卷runtime: volumes: - name: large-tmp emptyDir: {} volumeMounts: - name: large-tmp mountPath: /large-tmp5.3 Registry与调用链路断点排查技能“存在却找不到”kubectl get skills能看到但gcloud skills execute报NOT_FOUND。根因Registry的CRD版本不匹配。Agent Platform升级后旧版Manifestskills.cloud.google.com/v1beta1被废弃。解决方案kubectl get crd skills.skills.cloud.google.com -o yaml确认spec.versions中stored: true的版本更新Manifest的apiVersion。异步执行ID无效gcloud skills executions describe返回NOT_FOUND。根因Execution ID过期。Agent Platform默认保留执行记录7天超时自动清理。解决方案在CI/CD中异步调用后立即用gcloud skills executions wait阻塞等待或用--max-wait300s设上限。签名验证失败但无日志kubectl describe skill xxx显示ValidatedFalse但Events为空。根因KMS密钥被禁用或权限变更。解决方案手动验证签名# 下载Manifest和签名 kubectl get skill xxx -o jsonpath{.spec.signing.signature} sig.txt kubectl get skill xxx -o yaml manifest.yaml # 用KMS公钥验证