Sidekick 扩展
Shopify Sidekick 是直接内置在 Shopify 管理后台中的 AI 助手。它通过自然语言帮助商家管理商店——回答销售问题、撰写产品描述、生成折扣码等。通过 Sidekick 扩展,开发者可以教会 Sidekick 了解其应用的功能,让商家无需离开对话界面即可与第三方应用功能交互。
Sidekick 扩展目前处于开发者预览阶段。API 接口仍在演进中,但本课中描述的核心模式是稳定的。你可以通过 Shopify Partners 计划立即开始构建和测试扩展。
为什么 Sidekick 扩展重要
在 Sidekick 扩展出现之前,应用功能是孤立的。使用忠诚度计划应用的商家必须导航到该应用的 UI、学习其界面并手动触发操作。有了 Sidekick 扩展,同一个商家只需说:
"Show me my top 10 loyalty program members this month"
...然后 Sidekick 将请求路由到你的应用,检索数据,并以对话方式呈现。这不是噱头——它从根本上改变了商家发现和使用应用功能的方式。
商家体验
构建 Sidekick 扩展
一个 Sidekick 扩展由三个主要组件组成:
- 扩展清单 -- 声明你的扩展能做什么
- 操作处理器 -- 当 Sidekick 调用你的扩展时执行的函数
- 响应格式化器 -- 为 Sidekick 向商家呈现数据的结构化数据
扩展清单
清单告诉 Sidekick 你的应用暴露了哪些功能。它使用声明式模式来描述操作、参数和返回类型。
# shopify.extension.toml
[extension]
type = "sidekick_extension"
name = "Loyalty Program Assistant"
handle = "loyalty-sidekick"
[[extension.capabilities]]
name = "get_member_stats"
description = "Retrieve loyalty program statistics including total members, points issued, and redemption rates"
parameters = []
[[extension.capabilities]]
name = "lookup_member"
description = "Look up a specific loyalty program member by name or email"
[[extension.capabilities.parameters]]
name = "query"
type = "string"
description = "Customer name or email to search for"
required = true
[[extension.capabilities]]
name = "issue_bonus_points"
description = "Issue bonus loyalty points to a customer segment"
[[extension.capabilities.parameters]]
name = "segment"
type = "string"
description = "Customer segment identifier"
required = true
[[extension.capabilities.parameters]]
name = "points"
type = "number"
description = "Number of bonus points to issue"
required = true
Sidekick 使用你的功能描述来决定何时将商家的请求路由到你的扩展。编写具体且以操作为导向的描述。不要写"管理忠诚度数据",而应该写"检索忠诚度计划统计数据,包括总会员数、发放积分和兑换率"。描述越精确,Sidekick 匹配商家意图就越准确。
操作处理器
操作处理器是 Sidekick 在识别到匹配的功能时调用的服务器端函数。它们接收结构化参数并返回由 Sidekick 格式化后呈现给商家的数据。
// extensions/sidekick/src/handlers.ts
import { SidekickActionHandler } from '@shopify/sidekick-extensions';
export const getMemberStats: SidekickActionHandler = async (context) => {
const { session, admin } = context;
// Query your app's database for loyalty stats
const stats = await db.loyaltyStats.aggregate({
shopId: session.shop,
period: 'current_month',
});
return {
type: 'data_summary',
data: {
totalMembers: stats.totalMembers,
activeMembers: stats.activeThisMonth,
pointsIssued: stats.pointsIssuedThisMonth,
pointsRedeemed: stats.pointsRedeemedThisMonth,
redemptionRate: (stats.pointsRedeemedThisMonth / stats.pointsIssuedThisMonth * 100).toFixed(1),
topReward: stats.mostPopularReward,
},
summary: `Your loyalty program has ${stats.totalMembers.toLocaleString()} members. This month, ${stats.activeThisMonth.toLocaleString()} members were active, with a ${(stats.pointsRedeemedThisMonth / stats.pointsIssuedThisMonth * 100).toFixed(1)}% redemption rate.`,
};
};
export const lookupMember: SidekickActionHandler = async (context) => {
const { session, params } = context;
const { query } = params;
const members = await db.loyaltyMembers.search({
shopId: session.shop,
query,
limit: 5,
});
if (members.length === 0) {
return {
type: 'not_found',
summary: `No loyalty members found matching "${query}".`,
};
}
return {
type: 'member_list',
data: members.map((m) => ({
name: m.name,
email: m.email,
tier: m.tier,
pointsBalance: m.pointsBalance,
lifetimeSpend: m.lifetimeSpend,
memberSince: m.createdAt,
})),
summary: `Found ${members.length} member(s) matching "${query}".`,
};
};
export const issueBonusPoints: SidekickActionHandler = async (context) => {
const { session, params } = context;
const { segment, points } = params;
// Validate the action before executing
const segmentSize = await db.segments.count({
shopId: session.shop,
segmentId: segment,
});
return {
type: 'confirmation_required',
action: 'issue_bonus_points',
summary: `This will issue ${points} bonus points to ${segmentSize} customers in the "${segment}" segment. Total points cost: ${points * segmentSize}. Confirm?`,
params: { segment, points, affectedCustomers: segmentSize },
};
};
任何修改数据的 Sidekick 扩展操作(发放积分、删除记录、更新设置)都必须先返回 confirmation_required 响应类型。Sidekick 会在执行前向商家展示确认信息。永远不要从 Sidekick 处理器中自动执行破坏性操作。
Sidekick Pulse:主动商家推荐
Sidekick Pulse 是反应式查询模型的主动对应功能。Pulse 不是等待商家提问,而是允许你的扩展在发生值得注意的事情时向商家推送洞察。
Pulse 事件类型
| Event Type | Description | Example |
|---|---|---|
insight | Data-driven observation | "Your loyalty redemption rate increased 23% this week" |
alert | Something that needs attention | "15 loyalty members have expiring points in 3 days" |
suggestion | Actionable recommendation | "Consider running a double-points promotion -- your top segment hasn't purchased in 14 days" |
celebration | Positive milestone | "Your loyalty program just hit 1,000 members!" |
// Registering a Pulse event from your app backend
import { SidekickPulse } from '@shopify/sidekick-extensions';
const pulse = new SidekickPulse({
appId: process.env.SHOPIFY_APP_ID,
});
// Push a proactive insight
await pulse.emit({
shopId: 'shop_abc123',
type: 'suggestion',
priority: 'medium',
title: 'Double Points Opportunity',
message: 'Your VIP segment (234 customers) averages 45 days between purchases. They are currently at 38 days. A targeted double-points weekend could drive re-engagement.',
actions: [
{
label: 'Create Double Points Event',
capability: 'create_promotion',
params: { type: 'double_points', segment: 'vip', duration: '48h' },
},
{
label: 'Dismiss',
type: 'dismiss',
},
],
});
自定义应用生成
Sidekick 还可以帮助商家通过自然语言生成自定义应用逻辑。当商家描述一个不存在于内置功能或已安装应用中的工作流时,Sidekick 可以生成 Shopify Flow 自动化或简单的自定义脚本。
作为扩展开发者,你可以注册 Sidekick 在你的领域中生成解决方案时使用的模板:
// Register generation templates for your app's domain
export const generationTemplates = [
{
domain: 'loyalty',
template: 'points_rule',
description: 'Create a custom points earning rule',
schema: {
trigger: ['order_created', 'product_reviewed', 'referral_completed'],
condition: 'string', // Liquid-compatible condition
pointsFormula: 'string', // e.g., "order.total * 2"
},
example: {
trigger: 'order_created',
condition: 'order.total > 100',
pointsFormula: 'order.total * 1.5',
},
},
];
通过 Sidekick 实现 Flow 自动化
Sidekick 扩展可以注册 Flow 触发器和操作,商家可以通过自然语言将其纳入 Shopify Flow 自动化。
商家说"当 VIP 客户下单超过 $100 时,给他们双倍忠诚积分并发送感谢邮件"会触发 Sidekick:
- 识别触发器(订单创建)
- 添加条件(客户标记为 VIP,订单总额 > $100)
- 将你的扩展的"发放积分"操作与 2 倍乘数连接
- 添加 Shopify Email 操作用于发送感谢邮件
通过 Sidekick 命令进行主题编辑
如果你的应用包含主题应用扩展(将在后续模块中介绍),Sidekick 可以帮助商家通过自然语言配置和放置你的应用区块:
"Add the loyalty points widget below the add-to-cart button on product pages"
Sidekick 会将此翻译为正确的主题编辑器操作,将你的应用区块放置在商家主题的正确位置。
使用 Shopify CLI 命令 shopify app dev --sidekick-debug 启用 Sidekick 路由决策的详细日志。这会准确显示 Sidekick 如何解释商家查询以及为什么将请求路由(或不路由)到你的扩展。这在开发过程中非常有价值。
最佳实践
- 保持功能专注 -- 每个功能应该做好一件事。宁可有许多小功能,也不要几个大功能。
- 编写人类可读的摘要 -- Sidekick 直接向商家展示你的摘要文本。像对店主说话一样编写。
- 优雅地处理错误 -- 返回 Sidekick 可以转达的有用错误消息。"无法获取统计数据"毫无用处;"无法加载忠诚度统计数据,因为应用需要完成初始同步——安装后大约需要 5 分钟"才是有帮助的。
- 遵守速率限制 -- Sidekick 可能会频繁调用你的处理器。缓存昂贵的查询并使用后台任务处理繁重的工作。
- 记录所有日志 -- 由于你在开发过程中无法看到 Sidekick 的 UI,全面的日志记录是你最好的调试工具。
继续学习 AI 购物代理,了解如何构建使用 Catalog API 和 Checkout Kit 的完整对话式购物助手。