资讯动态

AI智能体Skills:从函数到服务契约的工程化实践

发布时间:2026/10/29 16:02:53 来源:尧图企业网站定制
1. 这不是“技能列表”而是一套可执行、可验证、可演进的智能体能力系统你搜“skills”时看到的那些词——Google Cloud、GKE、Gemini、Agent Platform、superpower skills、gemini code assist、claude agent skills、codex skills、reasonix安装新skills……它们表面是零散热词实则共同指向一个正在快速成型的技术范式现代AI原生应用中skills不再指代人类简历上的软硬能力项而是指代智能体Agent在特定上下文里可被调用、可组合、可审计、可灰度发布的最小功能单元。我从2022年参与首批企业级Agent平台POC开始就坚持把skills当作“可部署的服务契约”来设计而不是“插件”或“函数”。它必须满足四个硬性条件有明确定义的输入/输出Schema、自带运行时约束声明CPU/Memory/Timeout、支持版本化与依赖管理、能通过标准HTTP接口被任意Agent调度器发现和调用。你看到的“gemini登录失败”“account not eligible”“macbook下载卡住”本质不是账号问题而是skills运行环境与调用方Agent平台之间的能力契约不匹配——比如你本地MacBook上跑的skills要求调用Gemini API v1beta但你的账户只开通了v1基础版又比如GKE集群里部署的skills容器镜像用了glibc 2.35而你的Agent调度器默认只加载glibc 2.31兼容的runtime。这不是bug是契约未对齐。真正有价值的skills开发从来不是写个function然后扔进某个SDK里而是先画清楚三张图能力边界图这个skills到底解决什么原子问题绝不越界、依赖拓扑图它需要哪些外部服务、哪些内部模块、哪些环境变量、调用路径图谁会调用它、在什么条件下调用、失败后如何降级。后面所有实操都建立在这三张图的基础上。如果你现在正被“skills大全”“skills下载平台”这类信息淹没说明你还没进入真正的skills工程阶段——那只是消费端行为而本文要带你进入的是供给端怎么从0到1定义、实现、测试、部署、监控一个production-ready的skills。2. skills的本质从函数封装到服务契约的范式跃迁2.1 为什么传统“函数即skills”的思路必然失败很多开发者第一次接触skills概念时本能地把它等同于“一个带描述的Python函数”。比如写个def summarize_text(text: str) - str:加个docstring说“本skills用于文本摘要”再注册到某个Agent SDK里。这种做法在demo阶段看似可行但一旦进入真实业务流立刻暴露出四大结构性缺陷第一无输入校验契约。函数签名text: str只声明类型不声明语义约束。真实场景中你不能接受10MB的PDF Base64字符串直接塞进来也不能允许空字符串触发下游LLM调用。skills必须定义JSON Schema级别的输入约束例如{ type: object, properties: { content: { type: string, maxLength: 50000, description: 纯文本内容非Base64编码 }, max_length: { type: integer, minimum: 100, maximum: 2000, default: 500 } }, required: [content] }这个Schema不是文档而是运行时强制校验点。我见过太多case前端传了个{content: }进来skills直接调用Gemini API返回422 Unprocessable Entity但错误日志里只显示“API call failed”根本看不出是输入为空导致——因为函数层没做schema校验。第二无资源声明契约。一个skills宣称“能调用Gemini生成代码”但它没声明自己需要多少内存、是否需要GPU、最长执行时间是多少。当它被部署到GKE集群时调度器按默认配置512Mi内存30秒超时分配Pod结果skills在处理大文件时OOM被kill或者超时后Agent收到空响应。更糟的是多个skills共享同一个Agent runtime进程A skills占满CPUB skills完全无法响应。真正的skills必须在skills.yaml里声明resources: requests: memory: 1Gi cpu: 500m limits: memory: 2Gi cpu: 1000m timeout_seconds: 120这个声明不是建议是调度器分配资源的唯一依据。GKE的Vertical Pod AutoscalerVPA正是靠这个字段动态调整Pod规格。第三无依赖显式契约。pip install google-generativeai看起来简单但实际部署时你得确认这个包是否兼容你的Python 3.11它依赖的protobuf版本会不会和集群里已有的其他skills冲突skills必须用pyproject.toml锁定全部依赖树并生成requirements.lock且在manifest中声明dependencies: - name: google-generativeai version: 0.8.2 hash: sha256:abc123...我们曾在线上遇到过两个skills分别依赖langchain-core0.1.12和langchain-core0.1.15它们共用一个Python环境结果import langchain时因ABI不兼容直接崩溃。解决方案不是升级其中一个而是让每个skills运行在独立的container里——这又回到资源契约问题。第四无可观测性契约。skills不是黑盒。它必须暴露标准metrics端点如/metrics返回Prometheus格式、结构化日志JSON格式含skill_id,input_hash,duration_ms,status_code字段、健康检查端点/healthz。没有这些你就无法回答“过去一小时里哪个skills的错误率最高”“哪个skills的P95延迟突然升高”“这个skills的输入分布是否偏离预期”——而这些问题恰恰是Agent平台做自动路由、熔断、重试的决策依据。提示skills不是“写完就能用”的函数它是“定义清楚才能部署”的服务。每一次git push前请自问我的skills manifest里是否完整填写了schema、resources、dependencies、metrics这四块缺一块就不是production-ready。2.2 skills与Agent Platform的协同逻辑不是“插件”而是“协作者”很多人把skills理解为Agent的“插件”这是危险的误解。插件plugin是被动加载的扩展而skills是主动协作的伙伴。以Google Agent Platform为例它的skills调用流程不是“Agent调用skills”而是“Agent向skills发送符合OpenAPI规范的HTTP请求skills返回符合约定Schema的响应Agent根据响应中的next_action字段决定后续步骤”。这意味着skills必须提供标准OpenAPI 3.1 spec不是手写文档而是由代码生成。我们用pydantic定义input/output model用fastapi自动生成/openapi.json再用openapi-spec-validator校验合规性。spec里必须包含x-google-allowed-scopes字段声明它需要哪些OAuth权限如https://www.googleapis.com/auth/cloud-platform否则Agent Platform拒绝授权调用。支持异步轮询模式有些skills执行时间长如分析100页PDF不能阻塞Agent。skills需实现/start返回job_id和/status/{job_id}返回running/success/failed两个端点。Agent Platform会轮询status直到完成。我们规定所有耗时5秒的skills必须走此模式并在manifest中标记async: true。内置fallback策略声明skills需在manifest中声明fallback_skills: [text-summarize-basic, error-handler-generic]。当主skills失败时Agent Platform可自动降级调用备用skills而不是抛出异常中断流程。这个声明不是可选配置是SLA承诺的一部分。支持多版本灰度发布skills不是单版本部署。我们用GKE的Knative Service实现流量切分v1.0接收90%流量v1.1接收10%。每个版本有独立的skills.yaml其中version: 1.1.0-alpha和traffic: 10字段由CI/CD pipeline注入。Agent Platform通过X-Skill-Version: 1.1.0header指定调用版本实现AB测试和渐进式发布。这才是skills与Agent Platform的真实关系不是主从而是基于契约的平等协作。skills不“服从”Agent而是“协商”执行条件Agent不“控制”skills而是“编排”skills间的协作流。2.3 skills的生命周期管理从开发到退役的全链路一个skills上线后它的生命周期远比普通微服务复杂。我们定义了6个标准状态Draft本地开发中只有作者能调用无版本号Testing部署到staging环境通过Postman手动测试生成测试报告Verified通过自动化测试套件含schema校验、性能压测、安全扫描获得verified标签Published推送到公司内部skills registry可供其他团队发现和引用Deprecated标记为废弃仍可调用但返回warning header文档顶部加横幅RetiredAPI返回410 GoneDNS记录删除资源回收。关键动作都在CI/CD pipeline中固化git tag v1.2.0触发build生成Docker镜像扫描CVE上传到GCRmake test运行三类测试unitmock外部依赖、integration调用真实Gemini API限流1次/分钟、e2e模拟Agent Platform调用全流程make publish将skills.yaml、OpenAPI spec、测试报告推送到internal registry并更新search indexmake deprecate --reason replaced-by-v2自动更新registry元数据发送Slack通知给所有引用者。我们曾因跳过Verified状态直接将skills从Testing推到Published导致线上Agent调用时因输入长度超限频繁失败。教训是skills的发布不是开发完成的终点而是质量验证的起点。每一个状态切换都对应明确的质量门禁quality gate缺一不可。3. 实操核心从零构建一个production-ready skills以“Gemini Code Assist”为例3.1 需求拆解与能力边界定义“Gemini Code Assist”这个需求听起来很宽泛但skills必须原子化。我们把它拆解为三个独立skills而非一个大函数code-assist-suggest根据当前编辑器光标位置的上下文返回代码补全建议同步2scode-assist-explain根据选中的代码片段返回自然语言解释同步5scode-assist-refactor根据选中的代码片段和重构目标如“转成async”返回重构后代码异步30s。为什么拆因为它们的SLA、资源需求、错误处理策略完全不同suggest必须极致低延迟适合CPU密集型优化内存限制严格512Miexplain可接受稍高延迟但需稳定输出适合启用Gemini的temperature0.1refactor必须异步且需持久化中间状态如原始代码hash适合挂载Cloud Storage bucket。能力边界图明确划出红线✅ 允许接收当前文件内容光标行号列号返回补全文本❌ 禁止访问用户本地文件系统、读取未提供上下文的其他文件、修改编辑器状态⚠️ 警告若输入代码超过10KB返回400 Bad Request并提示“请缩小选区”。这个边界不是技术限制而是信任契约——用户必须确信这个skills不会越权操作。我们在manifest中用security字段声明security: - type: oauth2 scopes: [https://www.googleapis.com/auth/cloud-platform] - type: none # 不访问用户个人数据3.2 开发环境搭建与本地验证我们不用“随便找个Python脚本跑起来”的方式而是构建可移植的本地开发环境统一runtime使用devcontainer.json定义VS Code Dev Container预装Python 3.11.9与GKE node一致Google Cloud SDKgcloud auth login绑定服务账号skaffold本地k8s模拟部署jq和httpie命令行测试工具本地skills server用FastAPI实现核心结构# main.py from fastapi import FastAPI, HTTPException, Depends from pydantic import BaseModel, Field from typing import Optional import google.generativeai as genai app FastAPI(titlecode-assist-suggest) class SuggestRequest(BaseModel): file_content: str Field(..., max_length10000) cursor_line: int Field(..., ge0) cursor_column: int Field(..., ge0) class SuggestResponse(BaseModel): suggestions: list[str] latency_ms: float app.post(/v1/suggest, response_modelSuggestResponse) async def suggest(request: SuggestRequest): # 输入校验pydantic自动完成 if len(request.file_content) 10000: raise HTTPException(400, file_content too long) # 调用Gemini此处用mock避免每次调用真实API # 实际部署时替换为genai.GenerativeModel(gemini-1.5-pro) suggestions [print(hello), return True] return SuggestResponse(suggestionssuggestions, latency_ms120.5)本地验证流水线make validate校验skills.yaml语法、OpenAPI spec合规性、schema一致性make test-unit运行pytest覆盖边界case空输入、超长输入、非法行号make test-integration启动mock Gemini server验证HTTP client行为make serve用uvicorn启动server监听localhost:8000make test-local用httpie发送真实请求http POST :8000/v1/suggest \ file_contentdef hello():\n \ cursor_line:1 cursor_column:12关键心得本地环境必须100%复现生产约束。我们曾因本地用Python 3.12而生产用3.11导致typing.TypedDict行为差异引发线上bug。现在所有环境都锁死patch版本。3.3 Docker镜像构建与GKE部署skills不是“打包成zip上传”而是构建标准化Docker镜像多阶段Dockerfile# 构建阶段 FROM python:3.11.9-slim AS builder WORKDIR /app COPY pyproject.toml . RUN pip install poetry poetry export -f requirements.txt --without-hashes requirements.txt COPY . . RUN pip wheel --no-deps --wheel-dir /app/wheels . # 运行阶段 FROM python:3.11.9-slim WORKDIR /app COPY --frombuilder /app/wheels /wheels COPY --frombuilder /app/requirements.txt . RUN pip install --no-cache-dir --find-links /wheels --no-index -r requirements.txt COPY . . EXPOSE 8000 CMD [uvicorn, main:app, --host, 0.0.0.0:8000, --port, 8000]关键点--no-deps确保只安装wheel避免运行时重新解析依赖--find-links指定本地wheel目录加速安装。GKE部署清单k8s/deployment.yamlapiVersion: apps/v1 kind: Deployment metadata: name: code-assist-suggest-v1-2-0 labels: app: code-assist-suggest version: v1.2.0 spec: replicas: 3 selector: matchLabels: app: code-assist-suggest version: v1.2.0 template: metadata: labels: app: code-assist-suggest version: v1.2.0 annotations: prometheus.io/scrape: true prometheus.io/port: 8000 spec: containers: - name: skills-server image: gcr.io/my-project/code-assist-suggest:v1.2.0 ports: - containerPort: 8000 resources: requests: memory: 512Mi cpu: 300m limits: memory: 1Gi cpu: 600m env: - name: GCP_PROJECT_ID value: my-project - name: GEMINI_MODEL_NAME value: gemini-1.5-flash livenessProbe: httpGet: path: /healthz port: 8000 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /readyz port: 8000 initialDelaySeconds: 5 periodSeconds: 5注意livenessProbe和readinessProbe路径必须由skills代码实现不能是默认404。我们要求所有skills必须实现/healthz检查进程存活和/readyz检查依赖服务可用如Gemini API连通性。服务发现与流量管理# k8s/service.yaml apiVersion: v1 kind: Service metadata: name: code-assist-suggest annotations: cloud.google.com/neg: {ingress:true} spec: selector: app: code-assist-suggest ports: - port: 80 targetPort: 8000 --- # k8s/ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: code-assist-suggest annotations: kubernetes.io/ingress.class: gce networking.gke.io/vnet: default spec: rules: - host: skills.my-company.com http: paths: - path: /v1/suggest pathType: Exact backend: service: name: code-assist-suggest port: number: 80Ingress路径必须精确匹配skills的OpenAPI path避免Agent Platform调用时出现404。3.4 OpenAPI规范生成与Agent Platform集成skills的OpenAPI spec不是手写而是代码生成Pydantic模型驱动# models.py from pydantic import BaseModel, Field from typing import List, Optional class SuggestRequest(BaseModel): Request for code suggestion file_content: str Field( ..., descriptionFull content of the current file, plain text, max_length10000 ) cursor_line: int Field( ..., description0-based line number where cursor is, ge0 ) cursor_column: int Field( ..., description0-based column number where cursor is, ge0 ) class SuggestResponse(BaseModel): Response with code suggestions suggestions: List[str] Field( ..., descriptionList of suggested code snippets, min_items1, max_items5 ) latency_ms: float Field( ..., descriptionTime taken in milliseconds, ge0 )FastAPI自动生成spec# main.py from fastapi import FastAPI from models import SuggestRequest, SuggestResponse app FastAPI( titleCode Assist Suggest Skills, version1.2.0, openapi_tags[ {name: Suggest, description: Generate code completions} ] ) app.post( /v1/suggest, response_modelSuggestResponse, tags[Suggest], summaryGet code suggestions based on cursor context, descriptionReturns up to 5 code suggestions for the current cursor position. ) async def suggest(request: SuggestRequest): # implementation启动server后访问/openapi.json即可获取标准spec。Agent Platform注册登录Google Agent Platform Console创建新skills选择“HTTP endpoint”填写endpoint URLhttps://skills.my-company.com/v1/suggest上传openapi.json平台自动解析input/output schema设置Authentication选择“Service Account Key”上传JSON key文件配置Rate Limit设为100 req/min防滥用启用Monitoring自动接入Cloud Monitoring生成latency/error dashboard。关键验证点在Agent Platform的“Test”面板输入sample payload观察是否返回200 OK及正确格式响应。如果失败平台会显示详细错误如invalid input schema比curl调试高效得多。4. 生产环境运维与问题排查实战手册4.1 核心监控指标与告警阈值设定skills不是“部署完就完事”必须建立4层监控层级指标数据源告警阈值原因分析方向InfrastructurePod CPU usage 90%GKE Metrics5分钟持续skills代码存在无限循环或内存泄漏需检查profileApplicationHTTP 5xx rate 1%Cloud Monitoring10分钟窗口skills内部异常未捕获检查日志中的stack traceBusinesssuggestavg latency 1500msPrometheus5分钟P95Gemini API响应变慢或skills网络延迟对比upstream_latencyContractInput validation errors 5%Custom metric1分钟突增前端传入非法数据如超长content需联系前端团队修复我们用Cloud Monitoring创建dashboard关键图表Top 5 Slowest Skills按skills_latency_ms{skillcode-assist-suggest}P95排序Input Distribution Heatmap按file_content_length分桶统计识别异常输入模式Dependency Healthgemini_api_up{regionus-central1}布尔值判断外部服务可用性。告警通过PagerDuty发送级别定义P15xx error rate 5% 或 latency P95 3000mson-call工程师15分钟内响应P25xx error rate 1-5% 或 latency P95 1500-3000ms2小时内响应P3输入校验失败率突增非紧急纳入下个sprint修复。注意不要监控“skills是否运行”而要监控“skills是否按契约运行”。一个skills进程活着但返回错误响应比它crash更危险。4.2 典型故障场景与排查速查表场景1your account is not eligible for gemini code assist现象Agent Platform调用skills返回403 Forbidden错误信息含not eligible。排查路径检查skills服务账号权限gcloud projects get-iam-policy my-project --flattenbindings[].members --formattable(bindings.role,bindings.members) | grep service-account必须有roles/aiplatform.user和roles/serviceusage.serviceUsageConsumer检查Gemini API是否启用gcloud services list --projectmy-project | grep generativeai若未启用运行gcloud services enable generativeai.googleapis.com --projectmy-project检查配额gcloud ai quota list --projectmy-project关键配额generative-ai-requests-per-minute-per-project是否耗尽检查skills manifest中的model_namegemini-1.5-pro需要额外开通gemini-1.5-flash则无需。根因not eligible不是账号问题而是服务账号缺少必要角色或API未启用。我们曾因忘记启用generativeai.googleapis.com花了2小时排查网络代理问题。场景2skills在GKE上频繁OOM Killed现象kubectl get pods显示OOMKilled事件日志Memory limit reached。排查路径查看Pod eventskubectl describe pod pod-name确认Reason: OOMKilled检查skills内存使用kubectl top pod pod-name对比limits值分析内存泄漏kubectl exec -it pod-name -- /bin/sh -c pip install memory-profiler python -m memory_profiler main.py重点关注genai.GenerativeModel实例是否被重复创建应全局单例检查输入大小kubectl logs pod-name | grep file_content length确认是否收到超大payload根因skills未做输入长度限制前端传入10MB日志文件skills尝试全文加载到内存。解决方案在FastAPI middleware中添加Content-Length校验或在Pydantic model中用max_length强制。场景3Agent Platform调用超时但skills日志显示成功现象Agent Platform报504 Gateway Timeoutskills日志有200 OK记录。排查路径检查GKE Ingress日志gcloud logging read resource.typehttp_load_balancer httpRequest.status504确认是Ingress超时默认30秒还是skills超时检查skills timeout设置kubectl get deployment deployment -o yaml | grep timeout若skills manifest中timeout_seconds: 120但Ingress超时30秒则需调整Ingress检查网络延迟kubectl exec pod-name -- curl -w \n%{time_total}\n -o /dev/null -s https://generativeai.googleapis.com若time_total 25s说明Gemini API响应慢需启用retry或降级根因Ingress和skills的timeout未对齐。解决方案在Ingress annotation中增加backend-config.kubernetes.io/backend-config: {default: code-assist-timeout}并创建BackendConfig资源设置timeoutSec: 120。场景4skills返回结果不稳定相同输入有时正确有时错误现象/v1/suggest对同一file_content有时返回合理建议有时返回空数组或乱码。排查路径检查Gemini调用参数是否启用了temperature0.8高随机性应设为0.1保证确定性检查prompt engineeringskills是否在prompt中加入Respond ONLY with valid JSON, no explanations避免LLM自由发挥检查网络抖动kubectl exec pod-name -- ping -c 4 generativeai.googleapis.com若丢包率5%需检查VPC网络配置检查skills并发是否多个请求共享同一个genai.GenerativeModel实例应为每个请求创建新实例或加锁根因LLM的随机性未被约束。我们强制所有production skills使用temperature0.0完全确定或0.1极低随机并在prompt末尾加Output format: JSON only, no markdown, no code block.。4.3 日志分析与trace追踪实战skills日志不是“print调试”而是结构化可观测性入口标准日志格式JSON{ timestamp: 2024-06-15T10:23:45.123Z, level: INFO, skill_id: code-assist-suggest, version: v1.2.0, request_id: req-abc123, input_hash: sha256:xyz789, duration_ms: 124.5, status_code: 200, upstream_latency_ms: 98.2, gemini_model: gemini-1.5-flash }通过logging.basicConfig配置JsonFormatter所有loggers输出此格式。Trace集成在FastAPI middleware中注入X-Request-ID使用opentelemetry-instrument自动注入trace context所有HTTP calls如调用Gemini自动关联parent span在Cloud Trace中搜索skill_idcode-assist-suggest查看完整调用链。关键trace分析技巧定位慢节点在trace中找duration 100ms的span点击展开看attributes识别错误传播找status.code2的span看其parent是否也失败分析依赖瓶颈对比upstream_latency_ms和总duration_ms差值大说明skills自身处理慢。我们曾通过trace发现skills 80%时间花在json.loads()解析大响应上而非网络IO。优化方案改用ujson库性能提升3倍。日志查询示例Cloud Logging查找所有失败请求resource.typek8s_container jsonPayload.status_code400统计各版本错误率resource.typek8s_container jsonPayload.skill_idcode-assist-suggest | regex version\:\v(?ver[^\])\分析输入分布resource.typek8s_container jsonPayload.skill_idcode-assist-suggest | jsonPayload.input_hash实操心得日志不是“出了问题才看”而是“每天晨会必刷”。我们要求SRE每天早10点看top 5 slowest skills和top 5 error-prone skills提前干预。5. skills生态建设从单点交付到平台化演进5.1 skills registry的设计与治理skills不是孤立存在而是注册到公司级registry中供全组织发现和复用。我们的registry基于CNCF Harbor改造核心能力元数据丰富除基本name/version外存储openapi_url,test_report_url,owner_slack,last_updated依赖图谱自动解析requirements.txt生成skills间依赖关系图防止循环依赖安全扫描每次push触发Trivy扫描阻断CVE-2023-XXXX高危漏洞许可证检查拒绝GPL许可的skills入库只允许MIT/Apache-2.0使用统计记录每个skills的调用量、调用方team用于资源分配。registry UI支持搜索按tag: python,category: code过滤对比选两个版本并排显示OpenAPI diff依赖可视化点击skills显示其依赖的其他skills和外部服务。治理规则所有skills必须通过make verify含安全扫描、license check、schema validation才能入库每个skills必须指定ownerowner负责响应issue和升级Deprecatedskills保留90天期间registry显示“即将下线”横幅并邮件通知所有引用者。5.2 skills开发者的赋能体系skills不是“写完扔给SRE”而是开发者全程负责。我们建立了三层赋能CLI工具链skills-cliskills init生成标准项目骨架pyproject.toml, skills.yaml, Dockerfileskills test本地运行unit/integration/e2e测试skills deploy --envprod一键部署到GKE自动打tag、push镜像、apply k8s manifestsskills monitor实时流式显示当前skills的latency/error metrics。模板市场Template Marketplacecode-assist-template预置Gemini调用、输入校验、metrics暴露>

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑