三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Gemini Gems向Skills迁移指南:从AI功能调用到可编程技能构建

Gemini Gems向Skills迁移指南:从AI功能调用到可编程技能构建

如果你最近在关注 Google 的 AI 开发工具,可能会注意到一个重要的产品线变动:Gemini Gems 将在今年十月正式退役,并全面转向名为 “Skills” 的新形态

这绝不仅仅是一个简单的功能改名。对于正在或计划使用 Gemini API 进行应用开发的工程师来说,它意味着构建 AI 功能的方式、成本结构乃至整个工程范式都将发生一次关键迭代。很多开发者可能还在疑惑:Gems 是什么?Skills 又是什么?这个变化对我手头的项目有什么影响?是利好还是麻烦?

本文将为你彻底厘清这次转型。我们不会停留在官方新闻稿的表面,而是深入技术层面,分析其背后的设计逻辑变化,并通过一个完整的实战示例,展示如何从即将退役的 Gems 模式,平滑迁移到全新的 Skills 架构。无论你是正在评估 Gemini API,还是已经基于 Gems 构建了原型,这篇文章都将提供清晰的迁移路径和实操指南。

1. 从 Gems 到 Skills:一次关键的范式升级

首先,我们需要理解 Gems 和 Skills 分别解决了什么问题。

Gemini Gems可以理解为 Google 为 Gemini 模型预置的、开箱即用的“技能插件”。你可以把它想象成一个功能丰富的瑞士军刀,里面包含了代码生成、文本总结、创意写作等多种固定工具。开发者通过简单的 API 调用或界面选择,就能快速获得这些能力。它的核心价值在于“快速启动”,降低了 AI 功能集成的初始门槛。

然而,随着开发者需求的深入,Gems 的局限性也逐渐暴露:

  1. 定制化弱:Gems 是黑盒,其内部提示词(Prompt)、逻辑流和上下文处理方式对开发者不透明,难以针对特定业务场景进行深度优化。
  2. 集成僵化:Gems 通常作为一个整体功能被调用,难以将其中的子能力(例如,仅仅使用它的“信息提取”部分)灵活地嵌入到更复杂的应用工作流中。
  3. 迭代困难:由于不可定制,当业务逻辑变化或需要效果调优时,开发者只能等待 Google 的官方更新,自身能动性很小。

Skills的推出,正是为了解决这些问题。它将 AI 能力的构建单元,从一个固定的“功能盒子”(Gems),拆解为更原子化、可组合、可定制的“技能组件”。你可以把 Skills 理解为“可编程的 Gems”。它的核心转变在于:

  • 从“使用”到“构建”:开发者不再仅仅是功能的消费者,而是成为了技能的塑造者。
  • 从“黑盒”到“白盒(或灰盒)”:Skills 鼓励或允许开发者定义技能的触发条件、处理逻辑和输出格式。
  • 从“单体”到“组合”:多个简单的 Skills 可以像乐高积木一样组合起来,形成解决复杂问题的 AI 智能体(Agent)。

简单来说,这次转型标志着 Gemini 开发者平台从提供“标准化AI功能”,转向提供“定制化AI能力基础设施”。对于追求效果、效率和独特性的生产级应用,Skills 是更优的长期选择。

2. 核心概念对比:Gems vs. Skills

为了更清晰地理解差异,我们通过一个表格来对比两者的核心特征:

特性维度Gemini Gems (即将退役)Gemini Skills (新范式)
本质预封装、固定的AI功能模块可定义、可配置的AI能力单元
定制性低。参数调节有限,无法修改核心逻辑。高。可定义技能描述、示例、处理逻辑(通过Function Calling等)。
透明度黑盒。内部提示词和逻辑不可见。灰盒/白盒。技能的行为由开发者通过描述和示例来塑造。
集成方式通常作为独立端点调用。可作为AI Agent的一部分,与其他Skills或工具协同工作。
适用场景快速原型验证、通用性强的简单任务。复杂的业务逻辑、需要与外部系统交互、对输出格式有严格要求的生产应用。
开发者角色功能调用者。技能设计者与编排者。

一个生动的类比: 想象你要处理客户支持邮件。

  • Gems 模式:你有一个叫“邮件总结”的固定工具。你丢给它一封邮件,它返回一段总结。但如果你想让它在总结的同时,自动判断邮件情绪并打上标签,Gems 可能就无能为力了。
  • Skills 模式:你可以创建两个技能:Skill_A: 分析邮件情绪Skill_B: 生成邮件摘要。然后,你可以设计一个工作流:先调用Skill_A判断情绪,再将情绪标签和邮件原文一起交给Skill_B,要求它生成带情绪前缀的摘要。你甚至可以定义Skill_B的输出必须是特定的 JSON 格式,以便直接存入数据库。

Skills 提供了这种灵活性和控制力。

3. 环境准备与前置条件

在开始动手迁移或创建 Skill 之前,你需要确保开发环境就绪。

  1. 获取 API 密钥: 访问 Google AI Studio ,创建一个项目并获取你的 Gemini API 密钥。请妥善保管此密钥。

  2. 选择 SDK/工具

    • Python (推荐):使用官方google-generativeai库。这是功能最全、更新最及时的 SDK。
    pip install google-generativeai
    • Node.js:使用@google/generative-ai包。
    npm install @google/generative-ai
    • 其他语言:Google 也提供了 Java、Go 等语言的 SDK,可根据项目需求选择。
    • 直接 HTTP API:对于高度定制化的场景,你也可以直接调用 RESTful API。
  3. IDE 与工具: 任何你熟悉的代码编辑器即可(如 VS Code, PyCharm)。建议准备一个方便测试 API 调用的工具,如curl或 Postman。

重要提示:本文的示例将主要使用Python SDK进行演示,因为其语法清晰,且能很好地展示 Skills 相关的概念。其他语言的逻辑基本相通。

4. 迁移实战:从一个 Gems 示例到 Skills 实现

假设我们之前使用一个名为TextSummarizerGem(假设名称)的 Gems 来总结长篇文章。现在,我们要将其迁移为一个自定义的ArticleSummarySkill

4.1 旧模式:使用 Gems (假设代码)

在旧模式下,调用可能非常直接,但缺乏控制。

# 假设的旧版 Gems 调用代码(示意) # 注意:此代码仅为示意,Gemini Gems 的实际API可能有所不同 import google.generativeai as genai genai.configure(api_key="YOUR_API_KEY") model = genai.GenerativeModel('gemini-pro') # 指定模型 # 调用一个名为 `summarize` 的 Gems(假设通过某个参数触发) response = model.generate_content( f"请总结以下文本:{long_article_text}", # 可能有一个 `tools` 或 `gems` 参数来指定使用某个Gems # gems=['TextSummarizerGem'] # 假设性参数 ) print(response.text)

痛点:我们无法控制总结的长度、格式(是段落还是要点?)、是否要忽略引言等。

4.2 新模式:创建自定义 Skill

在 Skills 范式下,我们通过精心设计的系统指令(System Instruction)示例(Few-shot Examples)来“教”模型如何执行我们的技能。同时,我们可以利用函数调用(Function Calling)来让技能与外部世界交互。

下面,我们创建一个更强大的ArticleSummarySkill

# 文件路径:skills/article_summarizer.py import google.generativeai as genai from typing import Dict, Any, Optional import json class ArticleSummarySkill: """ 自定义文章总结技能 功能:根据要求,对输入的文章进行结构化总结。 """ def __init__(self, api_key: str): genai.configure(api_key=api_key) # 使用 Gemini 1.5 Pro 或 Flash 等支持长上下文和函数调用的模型 self.model = genai.GenerativeModel( model_name='gemini-1.5-pro', # 核心:通过 system_instruction 定义技能 system_instruction=self._get_system_instruction(), # 可以添加工具定义,使技能能调用外部函数 tools=[self._get_summary_format_tool()] ) def _get_system_instruction(self) -> str: """定义技能的系统和行为指令""" return """ 你是一个专业的文章总结助手(ArticleSummarySkill)。 你的任务是根据用户提供的文章,生成高质量、结构化的总结。 你必须遵守以下规则: 1. 总结需包含:核心论点(1-2句)、关键论据(3-5个要点)、结论(1句)。 2. 语言简洁、客观,保留原文关键数据(如日期、数字)。 3. 如果用户指定了长度(如“简短总结”或“详细总结”),请相应调整详细程度。 4. 如果用户要求特定格式(如“输出为JSON”或“列出要点”),你必须严格遵守。 如果用户的问题与文章总结无关,请礼貌地指出你只能处理文章总结任务。 """ def _get_summary_format_tool(self) -> Dict[str, Any]: """定义一个工具(函数),让模型可以请求特定格式的输出""" return { "function_declarations": [{ "name": "format_summary", "description": "指定总结输出的格式要求。", "parameters": { "type": "OBJECT", "properties": { "format_type": { "type": "STRING", "description": "所需的格式,如 'bullet_points', 'paragraph', 'json'", "enum": ["bullet_points", "paragraph", "json"] }, "max_length": { "type": "INTEGER", "description": "总结的最大长度(单词数)" } }, "required": ["format_type"] } }] } def summarize(self, article_text: str, user_request: str = "请总结这篇文章") -> Dict[str, Any]: """执行总结技能的主方法""" # 构建对话 chat = self.model.start_chat() # 用户消息:结合用户请求和文章内容 full_prompt = f"{user_request}\n\n文章内容如下:\n{article_text}" response = chat.send_message(full_prompt) # 处理响应:检查模型是否想调用我们定义的函数 if response.candidates[0].content.parts[0].function_call: fc = response.candidates[0].content.parts[0].function_call if fc.name == "format_summary": # 模型请求了格式化,这里我们可以根据请求生成最终总结 # 例如,如果请求JSON格式,我们可以调整prompt让模型输出JSON format_args = fc.args follow_up_prompt = f"请按照以下要求重新生成总结:格式为{format_args['format_type']}" if 'max_length' in format_args: follow_up_prompt += f",长度不超过{format_args['max_length']}词" follow_up_prompt += "。\n请直接输出总结内容。" final_response = chat.send_message(follow_up_prompt) result_text = final_response.text else: result_text = response.text else: result_text = response.text # 返回结构化的结果 return { "skill_name": "ArticleSummarySkill", "original_request": user_request, "summary": result_text, "model_used": self.model.model_name } # 使用示例 if __name__ == "__main__": API_KEY = "YOUR_ACTUAL_API_KEY" # 替换为你的密钥 skill = ArticleSummarySkill(API_KEY) # 示例文章(此处省略长文本,实际使用时替换) sample_article = """ 人工智能(AI)在软件开发领域的应用正日益深入...(这里是长长的文章正文) """ result = skill.summarize( article_text=sample_article, user_request="请用JSON格式输出详细总结,包含核心论点和关键论据字段" ) print(json.dumps(result, indent=2, ensure_ascii=False))

代码解读与优势

  1. 技能封装:我们将总结能力封装成了一个类ArticleSummarySkill,这是一个可复用、可测试的组件。
  2. 系统指令_get_system_instruction方法定义了技能的“角色”和“行为准则”,这是定制化的核心。你可以在这里注入任何领域知识。
  3. 函数调用(Tools)_get_summary_format_tool定义了一个工具。模型在生成过程中,可以“主动”调用这个工具来询问用户对格式的偏好(尽管本例中我们在用户请求里直接指定了)。这展示了 Skill 与外部逻辑交互的能力。
  4. 结构化输出summarize方法返回一个结构化的字典,包含了技能名、原始请求、总结内容和使用模型,这非常利于后续的数据处理、日志记录和集成。
  5. 灵活性:通过user_request参数,我们可以动态改变总结的要求,而无需修改技能内部逻辑。

5. 组合技能:构建简单 AI Agent

Skills 的真正威力在于组合。假设我们还有一个SentimentAnalysisSkill(情绪分析技能),我们可以轻松地将它们组合起来,创建一个能自动分析文章情绪并生成相应摘要的智能体。

# 文件路径:agents/article_processing_agent.py from skills.article_summarizer import ArticleSummarySkill # 假设我们已有另一个技能 from skills.sentiment_analyzer import SentimentAnalysisSkill class ArticleProcessingAgent: """一个组合了总结和情绪分析技能的简单智能体""" def __init__(self, api_key: str): self.summary_skill = ArticleSummarySkill(api_key) self.sentiment_skill = SentimentAnalysisSkill(api_key) # 假设已实现 def process_article(self, article_text: str) -> Dict[str, Any]: """处理文章:先分析情绪,再根据情绪调整总结语气""" # 步骤1:分析情绪 sentiment_result = self.sentiment_skill.analyze(article_text) # 假设返回 {“sentiment”: “positive”, “confidence”: 0.95} # 步骤2:根据情绪,定制总结请求 tone_map = { "positive": "请用积极、赞赏的语气总结这篇文章,突出其价值和亮点。", "negative": "请用客观、谨慎的语气总结这篇文章,注意指出其可能的问题或争议点。", "neutral": "请用客观、中立的语气总结这篇文章。" } user_request = tone_map.get(sentiment_result["sentiment"], "请总结这篇文章") # 步骤3:生成总结 summary_result = self.summary_skill.summarize(article_text, user_request) # 组合最终结果 final_result = { "article_metadata": { "estimated_sentiment": sentiment_result["sentiment"], "sentiment_confidence": sentiment_result["confidence"] }, "summary": summary_result["summary"], "processing_chain": ["SentimentAnalysisSkill", "ArticleSummarySkill"] } return final_result # 使用智能体 if __name__ == "__main__": API_KEY = "YOUR_ACTUAL_API_KEY" agent = ArticleProcessingAgent(API_KEY) sample_article = "..." # 你的文章内容 result = agent.process_article(sample_article) import pprint pprint.pprint(result)

这个简单的Agent展示了 Skills 范式的核心思想:通过编排多个单一职责的 Skills,构建出能处理复杂流程的智能应用。这比一个庞大而笨重的“全能Gems”要清晰、可维护得多。

6. 运行、验证与调试

6.1 运行与验证

运行上述代码后,你应该能得到结构化的输出。验证点包括:

  1. 功能正确性:总结是否涵盖了文章核心?情绪分析是否合理?
  2. 格式符合性:当请求 JSON 格式时,输出是否是合法的 JSON?能否被json.loads()解析?
  3. 技能遵循指令:当要求“用积极语气”时,生成的总结词汇是否偏向正面?
  4. 错误处理(下一步需要完善):如果输入文本为空或 API 调用失败,是否有适当的异常处理和用户提示?

6.2 调试技巧

在 Skills 开发中,调试至关重要:

  • 记录完整对话历史:在chat.send_message前后,打印出chat.history,查看模型实际接收和响应的消息序列。
  • 检查函数调用:如示例所示,检查response.candidates[0].content.parts中是否有function_call,这能帮你理解模型是否正确地理解了你的工具定义。
  • 简化测试:先用极短的文本测试技能的基本流程,再逐步增加复杂性。
  • 使用 AI Studio 进行原型设计:Google AI Studio 提供了可视化工具来配置模型指令(即 Skill 定义),并实时测试效果。你可以先在 Studio 中打磨你的system_instruction,再将其复制到代码中。

7. 迁移常见问题与排查思路

问题现象可能原因排查方式解决方案
调用 Gems 的旧代码报错或失效Gems 服务已下线或接口变更。1. 查看官方公告和 API 文档更新日志。
2. 检查错误信息,确认是否为404DEPRECATED错误。
立即开始迁移计划。根据旧 Gems 功能,设计对应的自定义 Skill。
自定义 Skill 效果不佳,输出不符合预期系统指令(System Instruction)描述不够清晰、具体或存在歧义。1. 在 AI Studio 中反复测试和优化指令。
2. 提供更清晰的示例(Few-shot)。
3. 检查指令中是否有矛盾的要求。
细化指令,使用“必须”、“禁止”、“格式应为”等明确词汇。为复杂技能添加示例对话。
模型不调用定义的函数(Tools)1. 函数描述不够清晰。
2. 对话上下文不足以让模型决定调用函数。
3. 模型版本不支持。
1. 检查function_declarations中的descriptionparameters是否描述准确。
2. 在用户请求中更明确地暗示需要调用函数。
3. 确认使用的模型(如gemini-1.5-pro)支持函数调用。
优化函数描述,确保其目的明确。在用户 prompt 中直接要求模型使用特定功能。切换至支持工具调用的最新模型。
API 响应慢或超时1. 输入文本过长。
2. 网络问题。
3. 模型负载高。
1. 检查输入 token 长度。
2. 测试网络连接。
3. 查看 API 状态面板。
1. 对长文本考虑分块处理。
2. 实现重试机制和超时设置。
3. 考虑使用gemini-1.5-flash等更快模型进行推理。
无法处理复杂、多步骤任务试图用一个 Skill 解决所有问题。审视任务流程,是否可拆分为多个原子化步骤。遵循单一职责原则,创建多个简单 Skills,并用一个 Agent 或编排逻辑将其串联。

8. 最佳实践与工程化建议

将 Skills 投入生产环境,需要遵循良好的工程实践:

  1. 技能设计原则

    • 单一职责:一个 Skill 只做好一件事。例如,ExtractDatesSkill只负责提取日期,SummarizeTextSkill只负责总结。
    • 接口明确:定义清晰的输入输出。输入是什么格式的文本/数据?输出是自然语言还是结构化数据(JSON)?
    • 指令精炼:系统指令是技能的灵魂。用词要精确、无歧义,并包含边界条件处理(“如果遇到X,则做Y”)。
  2. 配置与秘钥管理

    • 永远不要将 API 密钥硬编码在代码中。使用环境变量或安全的配置管理服务。
    # .env 文件 GEMINI_API_KEY=your_api_key_here
    # 代码中读取 import os from dotenv import load_dotenv load_dotenv() API_KEY = os.getenv("GEMINI_API_KEY")
  3. 错误处理与健壮性

    • 对所有 API 调用进行try-except包装。
    • 实现指数退避的重试逻辑,以应对暂时的网络或服务故障。
    • 为 Skill 设置合理的超时时间。
  4. 日志与监控

    • 记录每个 Skill 调用的输入、输出、耗时和 Token 使用量。
    • 这有助于成本核算、性能优化和效果分析。
    • 可以结构化日志,方便接入 ELK 或 Datadog 等监控系统。
  5. 版本控制

    • 将 Skill 的定义(尤其是系统指令)像代码一样进行版本控制(Git)。
    • 当修改指令时,通过 A/B 测试来评估效果变化,避免效果回退。
  6. 测试

    • 为每个 Skill 编写单元测试,使用固定的输入检查输出是否符合预期。
    • 构建一个涵盖典型、边缘和错误情况的测试用例集。

9. 总结与展望

Gemini Gems 向 Skills 的转型,是 Google 将其大模型能力从“产品功能”向“开发者平台”演进的关键一步。对于开发者而言,这短期意味着一些迁移成本,但长期来看,它带来了前所未有的灵活性控制力

迁移的核心步骤可以概括为

  1. 解构:分析现有 Gems 提供的功能,将其拆解为原子化的任务。
  2. 定义:为每个原子化任务设计一个 Skill,编写清晰、具体的系统指令。
  3. 实现:使用 Gemini API 和 SDK 实现这些 Skill 类,并处理好输入输出。
  4. 编排:通过 Agent 或业务逻辑代码,将多个 Skills 组合起来,完成复杂工作流。
  5. 优化:基于测试和用户反馈,持续迭代和优化每个 Skill 的指令和逻辑。

未来,随着 Skills 生态的成熟,我们或许会看到

  • Skill 市场:开发者可以发布和共享自己训练的高质量 Skills。
  • 可视化编排工具:像搭积木一样,通过拖拽来组合 Skills,构建 AI 应用。
  • 更复杂的 Agent 框架:内置记忆、规划、工具使用等能力的标准化 Agent 框架出现。

对于每一位技术决策者和开发者来说,现在正是深入理解和拥抱 Skills 范式的最佳时机。建议从一个小而具体的业务场景开始,尝试将一个旧的 Gems 思路用自定义 Skill 重新实现,亲身体验这种范式带来的差异。这将帮助你在 AI 原生应用开发的浪潮中,构建出更强大、更可控、更独特的解决方案。

← 返回列表