Skip to main content

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 擴充功能由三個主要元件組成:

  1. 擴充清單 -- 宣告您的擴充功能可以做什麼
  2. 動作處理器 -- 當 Sidekick 呼叫您的擴充功能時執行的函式
  3. 回應格式化器 -- 為 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 事件類型

Event TypeDescriptionExample
insightData-driven observation"Your loyalty redemption rate increased 23% this week"
alertSomething that needs attention"15 loyalty members have expiring points in 3 days"
suggestionActionable recommendation"Consider running a double-points promotion -- your top segment hasn't purchased in 14 days"
celebrationPositive 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:

  1. 識別觸發器(訂單已建立)
  2. 新增條件(客戶標記為 VIP,訂單總額 > $100)
  3. 將您擴充功能的「發放點數」動作連接上 2 倍乘數
  4. 新增一個 Shopify Email 動作用於發送感謝信

透過 Sidekick 命令編輯佈景主題

如果您的應用程式包含佈景主題應用程式擴充功能(在後續模組中介紹),Sidekick 可以幫助商家透過自然語言設定和放置您的應用程式區塊:

"Add the loyalty points widget below the add-to-cart button on product pages"

Sidekick 將此轉換為正確的佈景主題編輯器操作,將您的應用程式區塊放置在商家佈景主題的正確區段中。

測試 Sidekick 擴充功能

使用 Shopify CLI 命令 shopify app dev --sidekick-debug 來啟用 Sidekick 路由決策的詳細日誌。這會向您展示 Sidekick 如何解讀商家查詢,以及為什麼會或不會路由到您的擴充功能。這在開發過程中非常寶貴。

最佳實務

  1. 保持功能專注 -- Each capability should do one thing well. Prefer many small capabilities over a few large ones.
  2. 撰寫人類可讀的摘要 -- Sidekick presents your summary text directly to merchants. Write it as you would speak to a store owner.
  3. 優雅地處理錯誤 -- Return helpful error messages that Sidekick can relay. "Unable to fetch stats" is useless; "Could not load loyalty stats because the app needs to complete initial sync -- this takes about 5 minutes after installation" is helpful.
  4. 尊重速率限制 -- Sidekick may invoke your handlers frequently. Cache expensive queries and use background jobs for heavy lifting.
  5. 記錄所有內容 -- Since you cannot see Sidekick's UI during development, comprehensive logging is your best debugging tool.
下一步

繼續前往 AI 購物代理 了解如何建構使用 Catalog API 和 Checkout Kit 的完整對話式購物助手。