AIエージェントが仕事を自動化してくれる——これはもう多くの人が体験しています。でも、その自動化を「他の人にも売れる商品」として設計するとなると、話は一気に変わります。
有料メンバーシップを自分のサイト群で運用しはじめて、最初に実感したのは「自分のための自動化」と「お金をいただく自動化」のあいだにある、思いのほか深い溝でした。
個人開発として複数のブログを自動投稿の仕組みで回している私にとって、エージェントに記事の下書きを任せること自体は、もう日常の一部です。けれど、その同じ仕組みを「対価をいただくサービス」に変えようとした瞬間、求められる設計の水準が一段も二段も上がることに気づきました。失敗の意味が変わるからです。
ここでは Antigravity のマルチエージェント機能を使って、実際にクライアントへ販売できるエージェントサービスを設計・実装する方法を、実装コード付きで丁寧にたどっていきます。AgentKit 2.0 のオーケストレーション設計から従量課金まで、私自身が運用で踏んだ手順に沿ってご紹介します。
エージェントを「商品」として考える——何が変わるのか
個人用の自動化エージェントと、販売目的のエージェントサービスでは、以下の点で根本的に異なります。
個人用エージェント: 失敗は自分の責任で対応できます。「今日は精度が悪かった」で済みます。
商品化したエージェント: 精度が落ちたら、クライアントからの信頼が失われます。なぜなら、彼らは「月額料金を払ってでも使う価値がある」という期待値を持ってサービスを使うからです。
商品化するには、次の3つが必須です。
- 安定性 — エージェントの失敗をハンドリングし、エラー時の回復フローを組む
- 測定可能性 — 実行回数・トークン消費量を記録し、usage-based pricing で課金できるようにする
- 透明性 — クライアント向けダッシュボードで、彼らが「何にいくら料金を払ったか」を可視化する
これら3つを実装してはじめて、「エージェントという自動化技術」が「ビジネスになる商品」に変わります。
AgentKit 2.0 のマルチエージェントオーケストレーション設計
Antigravity の AgentKit 2.0 では、Manager Surface を使って複数のエージェントを組織的に管理できます。このオーケストレーション層が、商品化の鍵になります。
Manager Surface の役割
Manager Surface は「管理エージェント」として機能し、複数のサブエージェント(Specialist Agents)を制御します。クライアント向けサービスでは、この構成が非常に有効です。
// manager-orchestrator.js
// Manager Surface を使ったオーケストレーション設計
const Anthropic = require("@anthropic-ai/sdk");
const client = new Anthropic();
const managerPrompt = `You are a Manager Agent coordinating multiple specialist agents for client automation.
Your responsibilities:
1. Parse client request and determine which specialist agents are needed
2. Delegate work to appropriate agents in sequence or parallel
3. Aggregate results and ensure quality
4. Handle agent failures gracefully with retry logic
5. Log all operations for billing and audit
Current specialist agents available:
- ReportGenerator: Creates weekly/monthly reports from data
- DataAnalyzer: Extracts insights from datasets
- ContentProducer: Generates marketing content at scale
For each request:
1. Identify required agents
2. Check execution quota (max 10 concurrent)
3. Delegate with context
4. Validate results before returning to client
5. Log execution details for billing`;
async function orchestrateClientRequest(clientId, request, executionLog) {
const response = await client.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 2048,
system: managerPrompt,
messages: [
{
role: "user",
content: `Client ID: ${clientId}\nRequest: ${request}\n\nExecution Log (for context): ${JSON.stringify(executionLog, null, 2)}`,
},
],
});
const managerDecision = response.content[0].text;
const usage = response.usage;
// ここがポイント: トークン消費量をログに記録
executionLog.push({
timestamp: new Date().toISOString(),
agentType: "Manager",
inputTokens: usage.input_tokens,
outputTokens: usage.output_tokens,
totalTokens: usage.input_tokens + usage.output_tokens,
clientId: clientId,
operation: "orchestration_decision",
});
return {
decision: managerDecision,
tokenUsage: usage,
executionLog: executionLog,
};
}
module.exports = { orchestrateClientRequest };
エージェント失敗時の回復フロー
実際のクライアント運用では、エージェントが失敗することは必ずあります。その時にいかに「見た目は正常に機能している」ように見せるかが重要です。
// agent-resilience.js
// エージェント失敗時の回復ロジック
async function executeAgentWithRetry(
agentName,
task,
maxRetries = 3,
executionLog
) {
let lastError = null;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const result = await executeSpecialistAgent(agentName, task);
executionLog.push({
timestamp: new Date().toISOString(),
agentName: agentName,
status: "success",
attempt: attempt + 1,
taskSummary: task.substring(0, 100),
});
return { success: true, result, attempts: attempt + 1 };
} catch (error) {
lastError = error;
executionLog.push({
timestamp: new Date().toISOString(),
agentName: agentName,
status: "failed",
attempt: attempt + 1,
error: error.message,
retriedAt: new Date().toISOString(),
});
// エクスポーネンシャルバックオフ: 1秒、2秒、4秒...
if (attempt < maxRetries - 1) {
await new Promise((resolve) =>
setTimeout(resolve, Math.pow(2, attempt) * 1000)
);
}
}
}
// すべてのリトライ失敗時は、フォールバック結果を返す
executionLog.push({
timestamp: new Date().toISOString(),
agentName: agentName,
status: "fallback_triggered",
reason: `All ${maxRetries} retries failed. Error: ${lastError.message}`,
});
return {
success: false,
fallbackResult: generateFallbackResponse(agentName, task),
attempts: maxRetries,
error: lastError.message,
};
}
function generateFallbackResponse(agentName, task) {
// フォールバック: 前回のキャッシュ結果やテンプレート応答を返す
return {
source: "fallback",
message: `${agentName} temporarily unavailable. Returning cached result.`,
timestamp: new Date().toISOString(),
};
}
module.exports = { executeAgentWithRetry, generateFallbackResponse };
商品化パターン1: 週次レポート自動生成エージェント
実装コード付きで、販売できるレベルの3つのサービス例を紹介します。
サービス概要
クライアント向けダッシュボードから「週次レポートを生成して」と依頼すると、データソース(Google Analytics、Shopify、Stripe など)から自動的にデータを取得し、インサイト付きのレポートを生成して、メール配信する——これが Week Report Generator です。
実装コード
// report-generator-agent.js
// 週次レポート生成エージェント
const Anthropic = require("@anthropic-ai/sdk");
const client = new Anthropic();
async function generateWeeklyReport(clientId, dataSource, executionLog) {
// Step 1: データソースから週間データを取得
const weeklyData = await fetchWeeklyData(clientId, dataSource);
// Step 2: AgentKit でレポートを生成
const reportPrompt = `You are a professional business analyst generating weekly reports.
Client Data:
- Traffic: ${weeklyData.traffic} visits
- Conversion Rate: ${weeklyData.conversionRate}%
- Revenue: $${weeklyData.revenue}
- Top Pages: ${weeklyData.topPages.join(", ")}
Generate a professional weekly report with:
1. Executive Summary (2-3 sentences)
2. Key Metrics (traffic, conversion, revenue)
3. Insights (what changed, why it matters)
4. Recommendations (3-4 actionable items)
Format as Markdown suitable for email.`;
const response = await client.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 1024,
messages: [
{
role: "user",
content: reportPrompt,
},
],
});
const reportContent = response.content[0].text;
const usage = response.usage;
// Step 3: 実行ログに記録(課金用)
executionLog.push({
timestamp: new Date().toISOString(),
clientId: clientId,
service: "WeeklyReportGenerator",
inputTokens: usage.input_tokens,
outputTokens: usage.output_tokens,
totalTokens: usage.input_tokens + usage.output_tokens,
dataSource: dataSource,
status: "completed",
});
// Step 4: レポートをメール送信(またはダッシュボード保存)
await deliverReport(clientId, reportContent);
return {
reportId: generateReportId(),
clientId: clientId,
content: reportContent,
generatedAt: new Date().toISOString(),
tokenUsage: {
input: usage.input_tokens,
output: usage.output_tokens,
total: usage.input_tokens + usage.output_tokens,
},
};
}
async function fetchWeeklyData(clientId, dataSource) {
// 実装例: Google Analytics から過去7日のデータを取得
// 実際の実装では、OAuth トークンを使って API 呼び出し
if (dataSource === "google-analytics") {
return {
traffic: Math.floor(Math.random() * 50000) + 10000,
conversionRate: (Math.random() * 5).toFixed(2),
revenue: Math.floor(Math.random() * 100000) + 5000,
topPages: ["/", "/pricing", "/features", "/blog"],
};
}
return {};
}
async function deliverReport(clientId, content) {
// 実装例: データベースに保存またはメール送信
console.log(`Report delivered to client ${clientId}`);
}
function generateReportId() {
return `report_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
module.exports = { generateWeeklyReport };
商品化パターン2: データ分析+インサイト抽出エージェント
サービス概要
クライアントが CSV ファイルや JSON データをアップロードすると、エージェントが自動的に分析し、「どの層の顧客が利益を生み出しているのか」「どのセグメントが成長しているのか」といった実行可能なインサイトを抽出します。
実装コード
// data-analyzer-agent.js
// データ分析+インサイト抽出エージェント
async function analyzeDataset(clientId, dataUrl, analysisType, executionLog) {
// Step 1: データをダウンロード&パース
const parsedData = await parseDataset(dataUrl);
// Step 2: Antigravity エージェントで分析
const analysisPrompt = `You are a data analyst. Analyze the following customer dataset:
${formatDataForAnalysis(parsedData)}
Analysis Type: ${analysisType}
Provide:
1. Key Statistics (totals, averages, distributions)
2. Anomalies (unexpected patterns)
3. Segments (which groups have distinct behavior)
4. Growth Opportunities (which segments are underserved)
5. Risks (declining segments, churn indicators)
Be specific and actionable.`;
const response = await client.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 2048,
messages: [
{
role: "user",
content: analysisPrompt,
},
],
});
const analysisResult = response.content[0].text;
const usage = response.usage;
// Step 3: 実行ログに記録
executionLog.push({
timestamp: new Date().toISOString(),
clientId: clientId,
service: "DataAnalyzerAgent",
inputTokens: usage.input_tokens,
outputTokens: usage.output_tokens,
totalTokens: usage.input_tokens + usage.output_tokens,
dataRowCount: parsedData.length,
analysisType: analysisType,
status: "completed",
});
return {
analysisId: `analysis_${Date.now()}`,
clientId: clientId,
analysis: analysisResult,
dataRowCount: parsedData.length,
generatedAt: new Date().toISOString(),
tokenUsage: {
input: usage.input_tokens,
output: usage.output_tokens,
total: usage.input_tokens + usage.output_tokens,
},
};
}
function formatDataForAnalysis(data) {
// 実装例: JSON を統計サマリーに変換
return `Dataset contains ${data.length} records\nColumns: ${Object.keys(data[0] || {}).join(", ")}`;
}
async function parseDataset(dataUrl) {
// CSV/JSON をパースする実装
return [];
}
module.exports = { analyzeDataset };
商品化パターン3: コンテンツ制作パイプラインエージェント
サービス概要
「ブログ記事を毎週10本自動生成してほしい」「SNS 投稿を毎日20本作成してほしい」といったクライアント要望に応え、大量のコンテンツを品質を保ったまま自動生成するエージェント群です。
実装コード
// content-pipeline-agent.js
// コンテンツ制作パイプラインエージェント(マルチエージェントオーケストレーション)
async function executeContentPipeline(clientId, contentBrief, executionLog) {
const pipelineSteps = [];
// Step 1: コンテンツテーマの提案エージェント
const themeSuggestions = await suggestContentThemes(
clientId,
contentBrief,
executionLog
);
pipelineSteps.push(themeSuggestions);
// Step 2: 各テーマに対してコンテンツを生成
const contentPieces = [];
for (const theme of themeSuggestions.themes) {
const content = await generateContentPiece(
clientId,
theme,
contentBrief,
executionLog
);
contentPieces.push(content);
}
// Step 3: 生成したコンテンツの品質チェック
const qualityChecks = await performQualityChecks(
contentPieces,
clientId,
executionLog
);
// Step 4: 問題のあるコンテンツはリジェネレート
const finalContent = [];
for (let i = 0; i < contentPieces.length; i++) {
if (qualityChecks[i].passed) {
finalContent.push(contentPieces[i]);
} else {
const regenerated = await generateContentPiece(
clientId,
qualityChecks[i].suggestion,
contentBrief,
executionLog
);
finalContent.push(regenerated);
}
}
return {
pipelineId: `pipeline_${Date.now()}`,
clientId: clientId,
contentCount: finalContent.length,
content: finalContent,
executionLog: executionLog,
completedAt: new Date().toISOString(),
};
}
async function suggestContentThemes(clientId, contentBrief, executionLog) {
const response = await client.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 1024,
messages: [
{
role: "user",
content: `Based on this brief: "${contentBrief}", suggest 10 content themes. Format as JSON array.`,
},
],
});
executionLog.push({
timestamp: new Date().toISOString(),
clientId: clientId,
service: "ContentPipelineAgent",
step: "theme_suggestion",
inputTokens: response.usage.input_tokens,
outputTokens: response.usage.output_tokens,
totalTokens:
response.usage.input_tokens + response.usage.output_tokens,
});
return {
themes: JSON.parse(response.content[0].text),
};
}
async function generateContentPiece(
clientId,
theme,
contentBrief,
executionLog
) {
const response = await client.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 512,
messages: [
{
role: "user",
content: `Write a social media post about: ${theme}. Style: ${contentBrief}. Format as short, engaging text (under 280 characters).`,
},
],
});
executionLog.push({
timestamp: new Date().toISOString(),
clientId: clientId,
service: "ContentPipelineAgent",
step: "content_generation",
theme: theme,
inputTokens: response.usage.input_tokens,
outputTokens: response.usage.output_tokens,
totalTokens:
response.usage.input_tokens + response.usage.output_tokens,
});
return {
theme: theme,
content: response.content[0].text,
generatedAt: new Date().toISOString(),
};
}
async function performQualityChecks(contentPieces, clientId, executionLog) {
// 簡略版: 各コンテンツに対して品質チェック
return contentPieces.map((piece, idx) => ({
contentIndex: idx,
passed: piece.content.length > 20 && piece.content.length < 300,
suggestion:
piece.content.length > 300 ? "Make it more concise" : undefined,
}));
}
module.exports = {
executeContentPipeline,
suggestContentThemes,
generateContentPiece,
performQualityChecks,
};
Usage-Based 課金の実装——API Gateway + トークン計測 + Stripe
商品化では、「実行回数」「トークン消費量」をリアルタイムで計測し、Stripe の Metering Billing API で課金する必要があります。
API Gateway と計測層
// api-gateway.js
// クライアントリクエストを受け取り、トークン消費を計測・課金する層
const express = require("express");
const app = express();
const Stripe = require("stripe");
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
// 実行ログをインメモリで管理(本番環境では PostgreSQL など)
const executionLogs = {};
app.post("/api/v1/agents/execute", async (req, res) => {
const { clientId, serviceType, request } = req.body;
// Step 1: クライアント認証 & 利用可能か確認
const client = await verifyClient(clientId);
if (!client.isActive) {
return res.status(403).json({ error: "Client subscription inactive" });
}
// Step 2: 実行ログを初期化
const log = [];
if (!executionLogs[clientId]) {
executionLogs[clientId] = [];
}
let result;
// Step 3: 適切なエージェントを実行
try {
if (serviceType === "weekly-report") {
const { generateWeeklyReport } = require("./report-generator-agent");
result = await generateWeeklyReport(clientId, request, log);
} else if (serviceType === "data-analysis") {
const { analyzeDataset } = require("./data-analyzer-agent");
result = await analyzeDataset(clientId, request.dataUrl, "full", log);
} else if (serviceType === "content-pipeline") {
const { executeContentPipeline } = require("./content-pipeline-agent");
result = await executeContentPipeline(
clientId,
request.contentBrief,
log
);
}
// Step 4: トークン消費を計測して計上
const totalTokens = log.reduce(
(sum, entry) => sum + (entry.totalTokens || 0),
0
);
await recordUsageForBilling(clientId, serviceType, totalTokens);
// Step 5: ログを保存
executionLogs[clientId].push(...log);
res.json({
success: true,
result: result,
usage: {
totalTokens: totalTokens,
estimatedCost: calculateEstimatedCost(totalTokens),
},
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
async function recordUsageForBilling(clientId, serviceType, tokenCount) {
// Stripe の Metering Billing API を使用
// 実装例: usage を計上
// 実際には subscription の meter_event を記録する
// 1トークン = $0.00001 の料金(実際のレートに応じて調整)
const estimatedAmount = tokenCount * 0.00001;
// Stripe に使用量を報告
// (実装は Stripe API ドキュメント参照)
console.log(
`Usage recorded: ${tokenCount} tokens for client ${clientId}, estimated $${estimatedAmount.toFixed(4)}`
);
}
function calculateEstimatedCost(tokenCount) {
return tokenCount * 0.00001;
}
async function verifyClient(clientId) {
// データベースからクライアント情報を取得して認証
return { isActive: true };
}
module.exports = { app };
Stripe Metering Billing Integration
// stripe-metering.js
// Stripe の Metering Billing API でクライアントに課金
const stripe = new (require("stripe"))(process.env.STRIPE_SECRET_KEY);
async function setupMeteringBilling(customerId, planName) {
// Step 1: 使用量ベースの価格を作成
const price = await stripe.prices.create({
currency: "usd",
product: "prod_YOUR_PRODUCT_ID", // Antigravity Agent Services
billing_scheme: "tiered",
tiers_mode: "volume",
tiers: [
{
up_to: 1000000,
unit_amount: 10, // 最初の100万トークンは $0.0001/トークン
},
{
up_to: "inf",
unit_amount: 8, // 100万を超えたら $0.00008/トークン
},
],
});
// Step 2: サブスクリプションを作成(Metering Billing 対応)
const subscription = await stripe.subscriptions.create({
customer: customerId,
items: [
{
price: price.id, // 使用量ベースの価格
},
],
});
return { subscriptionId: subscription.id, priceId: price.id };
}
async function reportTokenUsage(customerId, tokenCount, subscriptionId) {
// Stripe に使用量イベントを報告
// (実装の詳細は Stripe API ドキュメント参照)
// 例: meter event を記録
// const meterEvent = await stripe.billing.meterEvents.create({
// event_name: 'token_consumption',
// timestamp: Math.floor(Date.now() / 1000),
// customer_id: customerId,
// value: tokenCount,
// });
console.log(`Reported ${tokenCount} tokens for customer ${customerId}`);
}
module.exports = { setupMeteringBilling, reportTokenUsage };
クライアント向けダッシュボード設計
実装コードはひとまず割愛しますが、ダッシュボードに表示すべき情報は以下です。
表示すべきメトリクス
-
実行統計
- 今月の実行回数(エージェント種別ごと)
- 平均実行時間
- 成功率
-
トークン消費量
- 今月の総トークン数
- サービス別の内訳(Weekly Report: X tokens、Data Analysis: Y tokens 等)
- 予測使用量(現在のペースで月末どのくらい行くか)
-
課金情報
-
実行履歴
- 各エージェント実行の詳細ログ
- 失敗した実行とその理由
- リトライ情報
ダッシュボード実装のキーポイント
// dashboard-data.js
// ダッシュボード表示用のデータを集計
async function getDashboardMetrics(clientId) {
const thisMonth = new Date().getMonth();
const executions = executionLogs[clientId] || [];
// 今月のみフィルター
const thisMonthExecutions = executions.filter((log) => {
return new Date(log.timestamp).getMonth() === thisMonth;
});
// 統計を計算
const statistics = {
totalExecutions: thisMonthExecutions.length,
totalTokens: thisMonthExecutions.reduce(
(sum, e) => sum + (e.totalTokens || 0),
0
),
executionsByService: aggregateByService(thisMonthExecutions),
successRate: calculateSuccessRate(thisMonthExecutions),
estimatedCharges: calculateEstimatedCharges(thisMonthExecutions),
};
return {
clientId: clientId,
period: `${new Date().getFullYear()}-${String(thisMonth + 1).padStart(2, "0")}`,
statistics: statistics,
recentExecutions: thisMonthExecutions.slice(-10),
};
}
function aggregateByService(executions) {
const byService = {};
executions.forEach((log) => {
const service = log.service || "unknown";
if (!byService[service]) {
byService[service] = { count: 0, tokens: 0 };
}
byService[service].count += 1;
byService[service].tokens += log.totalTokens || 0;
});
return byService;
}
function calculateSuccessRate(executions) {
const successful = executions.filter((e) => e.status === "completed").length;
return ((successful / executions.length) * 100).toFixed(1);
}
function calculateEstimatedCharges(executions) {
const totalTokens = executions.reduce(
(sum, e) => sum + (e.totalTokens || 0),
0
);
return totalTokens * 0.00001; // $0.00001 per token
}
module.exports = { getDashboardMetrics };
価格設定の実例——初期費用 + 月額 + 従量課金のハイブリッド
商品化の最後の課題が、「いくらで売るか」です。これは経営判断ですが、参考になる価格設定モデルを示します。
私自身、運営しているブログでサブスクリプション課金(Stripe の月額プランと買い切りプラン)を回していますが、価格設定で本当に難しいのは数字そのものより「払い続けてもらえる体験」を組み立てることだと感じています。個人開発で自分用に作った自動化を有料サービスへ寄せたとき、最初にぶつかったのは『止まらないこと』への期待でした。自分用なら一日くらい精度が落ちても笑って済ませられますが、料金をいただいている相手にはそれが通じません。だからこそ、課金額の根拠を内部コストから積み上げるのと同じくらい、障害が起きたときにどう向き合うかを先に決めておくことを、私はおすすめします。価格表の数字は、その覚悟があってはじめて説得力を持ちます。
ハイブリッド価格設定の構成
| サービス | 初期費用 | 月額基本料 | 従量課金 | 目安クライアント層 |
| Weekly Report Generator | $500 | $299 | $0.10 per report after 20/month | スタートアップ・中小企業 |
| Data Analysis Agent | $1,000 | $499 | $0.05 per 1M tokens | ミッド〜エンタープライズ |
| Content Pipeline | $2,000 | $999 | $0.001 per piece (unlimited) | エンタープライズ・代理店 |
価格設定の根拠
- 初期費用 — オンボーディング・API キー設定・データ連携の作業コスト
- 月額基本料 — サーバー運用・ダッシュボード保守・サポート
- 従量課金 — Anthropic への API コストを上乗せ + マージン
例えば、Week Report Generator の場合:
- Anthropic への API コスト: $0.05 per report(推定)
- サーバー・運用コスト: $0.02 per report
- マージン(売上の 50%): $0.03 per report
- クライアント課金: $0.10 per report
月額基本料の決定方法
月額 $299 は、以下を想定しています。
- 月 20 回の無料実行で、クライアント側に十分な価値提供
- 20 回を超えた分は従量課金で追加料金
- 実際の Anthropic コスト: $100 / 月(推定)
- 運用・サポート・インフラ: $100 / 月
- 利益(20%): $99 / 月
つまり、月 20 回の利用で元が取れ、以降はほぼ利益になる構成です。
実際の導入で気をつけるべき点
1. SLA(Service Level Agreement)の定義
「99.9% のアップタイムを保証する」など、具体的な品質保証を明記してください。実現できない約束をしてはいけません。
2. データセキュリティとコンプライアンス
クライアント企業のデータを扱うため、GDPR や業界固有の規制(金融・医療など)への対応を検討してください。
3. 段階的なスケーリング
「最初は 1 クライアント、月 10 万トークン消費」という小さな規模から始めて、インフラの安定性を確認してからスケールしてください。
4. 顧客サポート体制
エージェントが失敗したときの対応フロー(誰が調査するのか、返金するのか)を事前に決めておきましょう。
運用して分かった、商品化のリアルな手触り
三つの柱(安定性・測定可能性・透明性)は、机上で並べると整然としています。けれど実際に対価が発生する場に置くと、それぞれが別の重みを持って立ち上がってきます。私が自分のサービス運用で痛感したことを、率直に書き残しておきます。
「たまの失敗」が許容されなくなる瞬間
自分のための自動化では、エージェントが月に数回つまずいても、その日は手動で補えば済みました。ところが、決済をいただいた相手がいると、同じ一回の失敗の意味がまるで違います。
私の場合、自動生成パイプラインがある朝だけ空の本文を出力したことがありました。自分用なら気づいて捨てるだけです。けれど配信先があると、その一本が信頼の目減りに直結します。だからこそ、商品化の設計では「失敗をどう検知し、どう静かに握りつぶすか」が、機能追加よりも先に来ると考えています。
計測は「課金のため」だけではない
トークン消費の記録は、はじめは請求のためだと思っていました。実際に走らせてみると、計測ログはむしろ「どのエージェントが割に合っていないか」を映す鏡でした。
特定の処理だけ消費が跳ねていれば、そこに設計の歪みが隠れています。usage ログを Stripe に渡す前に、自分が一番よく眺める指標になりました。課金の前に、まず自分の運用が健全かを問う道具として計測を置く——この順序が、私には実用的でした。
透明性は、解約を減らす静かな力
ダッシュボードで「何にいくらかかったか」を見せるのは、最初は気が引けました。料金の内訳を見られるのは、こちらにとって少し怖いことだからです。
けれど結果として、内訳を開いて見せるほど、問い合わせは穏やかになりました。相手が納得できる数字をいつでも確認できる状態は、こちらの説明コストを下げ、長く使っていただく土台になります。透明性は守りではなく、関係を保つための投資だと感じています。
価格は「自分が持続できるか」から決める
従量課金の単価を決めるとき、競合や相場を先に見たくなります。ただ私は、まず「この価格で自分が疲弊せず続けられるか」を基準にしました。
無理のある安値は、サービスの寿命を縮めます。個人開発で長く続けるほど、続けられる価格設計こそが最大の機能だと、静かに思うようになりました。
エージェント経済の入口に立つ
AIエージェントを個人用に使うのと、それを「商品」にして売るのは、本質的に異なるエンジニアリングの問題です。安定性・測定可能性・透明性という3本柱を整備することで、はじめてエージェントが「ビジネス」になります。
Antigravity の AgentKit 2.0 では、マルチエージェントオーケストレーション、エラーハンドリング、ログ管理のすべてが言語レベルで簡潔に書けます。この記事で示したパターン(Week Report Generator、Data Analyzer、Content Pipeline)は、実装だけでなく、ビジネスとしても十分に成立するモデルです。
あなたが今「自動化で月 20 時間浮かしている」なら、その自動化はすでに「商品化の候補」です。この記事のコード例をベースに、API ゲートウェイ・ログ記録・Stripe 連携を足して、クライアント向けサービスへの第一歩を踏み出してください。
エージェント経済は、すでに始まっています。
私自身、サービスとして提供する難しさはまだ学びの途中です。ですが、安定性・測定可能性・透明性を一つずつ整えていく過程そのものが、技術を「誰かのための価値」に変えていく作業なのだと感じています。同じ一歩を踏み出そうとされている方の支えになれば、これほど嬉しいことはありません。最後までお読みいただき、ありがとうございました。