"""
MCP Server 整合 - 藍圖生成工具
"""
import asyncio
import json
# 添加到 server.py 的工具列表中
BLUEPRINT_GENERATION_TOOL = {
"name": "mmla_generate_blueprint",
"description": "根據用戶的自然語言輸入生成藍圖。例如:'我要做一個電商 app'",
"inputSchema": {
"type": "object",
"properties": {
"user_input": {
"type": "string",
"description": "用戶的需求描述,例如:'我要做一個電商 app 像蝦皮'"
}
},
"required": ["user_input"]
}
}
async def mmla_generate_blueprint_logic(user_input: str) -> str:
"""
生成藍圖的核心邏輯
這個函數會:
1. 構建提示詞
2. 調用 Antigravity 的 AI
3. 解析返回的藍圖
4. 返回結構化的 JSON
"""
# 提示詞模板
prompt = f"""你是一個專業的軟件架構師。用戶會告訴你他想做什麼,你要幫他設計藍圖。
用戶輸入: {user_input}
請生成一個藍圖,包含:
1. 3-5 個核心功能模組
2. 每個模組 1-3 個關鍵問題
3. 每個問題 2-3 個選項
輸出格式 (JSON):
{{
"title": "用戶需求的標題",
"cards": [
{{
"name": "模組名稱",
"questions": [
{{
"text": "問題描述 (用日常語言,不要技術術語)",
"options": ["選項1", "選項2", "選項3"],
"answer": 0
}}
]
}}
]
}}
重要:
- 問題要用日常語言,像在跟朋友聊天
- 避免技術術語 (如「資料庫鎖」改成「會不會搶到同一個商品」)
- 選項要具體,不要模糊
- 每個模組最多 3 個問題
現在請生成藍圖:"""
try:
# 調用 Antigravity 的 AI
# 注意: 這裡需要根據實際的 Antigravity API 調整
# 方式 1: 如果 Antigravity 提供了 generate_text 工具
# response = await call_antigravity_tool("generate_text", {"prompt": prompt})
# 方式 2: 如果在 Antigravity 環境中,直接調用
# response = await antigravity.ai.generate(prompt)
# 暫時使用模擬響應 (實際部署時替換)
response = _mock_ai_response(user_input)
# 解析 JSON
blueprint = json.loads(response)
# 驗證格式
if not _validate_blueprint(blueprint):
raise ValueError("AI 生成的藍圖格式不正確")
return json.dumps({
"success": True,
"blueprint": blueprint
}, ensure_ascii=False)
except Exception as e:
return json.dumps({
"success": False,
"error": str(e),
"blueprint": _get_fallback_blueprint(user_input)
}, ensure_ascii=False)
def _mock_ai_response(user_input: str) -> str:
"""模擬 AI 響應 (用於測試)"""
# 電商類
if any(keyword in user_input for keyword in ['電商', '購物', '蝦皮', '淘寶', '商城']):
return json.dumps({
"title": "電商 App",
"cards": [
{
"name": "商品管理",
"questions": [
{"text": "商品賣完了要怎麼顯示?", "explanation": "當商品庫存為 0 時,系統需要決定如何顯示給用戶", "options": ["顯示「已售完」", "直接隱藏", "顯示「補貨中」", "🤷 先跳過"], "impact": {"0": "✅ 用戶知道有這個商品\n⚠️ 可能影響購買慾望", "1": "✅ 頁面更簡潔\n⚠️ 用戶不知道有這個商品", "2": "✅ 用戶可能會等待\n✅ 提高回購率"}},
{"text": "商品圖片要幾張?", "explanation": "更多圖片可以展示細節,但會增加載入時間", "options": ["1張主圖", "3-5張", "10張以上", "🤷 先跳過"], "impact": {"0": "✅ 載入快速\n⚠️ 資訊不足", "1": "✅ 平衡展示和速度\n✅ 最常見的選擇", "2": "✅ 展示完整\n⚠️ 載入較慢"}},
{"text": "要支持商品評價嗎?", "explanation": "評價可以建立信任,但需要審核機制", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 建立信任\n⚠️ 需要審核機制", "1": "✅ 開發簡單\n⚠️ 缺少社交證明"}},
{"text": "商品要分類嗎?", "explanation": "分類可以幫助用戶快速找到商品", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 用戶容易找到\n⚠️ 需要維護分類", "1": "✅ 開發簡單\n⚠️ 商品多時難找"}},
{"text": "要支持商品搜尋嗎?", "explanation": "搜尋功能可以提高用戶體驗", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 快速找到商品\n⚠️ 需要搜尋引擎", "1": "✅ 開發簡單\n⚠️ 用戶體驗差"}},
{"text": "商品要支持規格選擇嗎?(例如:尺寸、顏色)", "explanation": "規格選擇可以讓一個商品有多種變體", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 減少商品數量\n⚠️ 庫存管理複雜", "1": "✅ 開發簡單\n⚠️ 商品數量多"}},
{"text": "要顯示商品瀏覽次數嗎?", "explanation": "瀏覽次數可以顯示商品熱度", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 社交證明\n⚠️ 需要統計", "1": "✅ 開發簡單"}},
{"text": "要支持商品收藏嗎?", "explanation": "收藏功能可以提高回購率", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 提高回購率\n⚠️ 需要用戶登入", "1": "✅ 開發簡單"}}
]
},
{
"name": "購物車",
"questions": [
{"text": "加入購物車後,商品漲價了怎麼辦?", "explanation": "價格變動時,需要決定用哪個價格結帳", "options": ["用新價格", "用舊價格", "通知用戶", "🤷 先跳過"], "impact": {"0": "✅ 避免虧損\n⚠️ 用戶可能不滿", "1": "✅ 用戶體驗好\n⚠️ 可能虧損", "2": "✅ 透明公平\n✅ 讓用戶決定"}},
{"text": "購物車要保存多久?", "explanation": "保存時間影響用戶體驗和資料庫成本", "options": ["7天", "30天", "永久", "🤷 先跳過"], "impact": {"0": "✅ 節省空間\n⚠️ 用戶可能忘記", "1": "✅ 平衡選擇\n✅ 最常見", "2": "✅ 用戶體驗最好\n⚠️ 資料庫成本高"}},
{"text": "購物車商品數量有上限嗎?", "explanation": "限制數量可以防止惡意行為", "options": ["有,最多10件", "有,最多50件", "沒有限制", "🤷 先跳過"], "impact": {"0": "✅ 防止惡意\n⚠️ 限制太嚴", "1": "✅ 平衡選擇", "2": "✅ 用戶自由\n⚠️ 可能被濫用"}},
{"text": "購物車要顯示總價嗎?", "explanation": "即時顯示總價可以提高轉換率", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 用戶清楚知道\n✅ 提高轉換率", "1": "✅ 開發簡單"}},
{"text": "要支持購物車分享嗎?", "explanation": "分享購物車可以讓朋友幫忙挑選", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 社交功能\n⚠️ 需要生成連結", "1": "✅ 開發簡單"}},
{"text": "購物車商品缺貨要通知嗎?", "explanation": "即時通知可以避免結帳失敗", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 用戶體驗好\n⚠️ 需要即時檢查", "1": "✅ 開發簡單\n⚠️ 結帳時才發現"}},
{"text": "要支持購物車優惠券嗎?", "explanation": "優惠券可以提高轉換率", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 提高轉換率\n⚠️ 需要優惠券系統", "1": "✅ 開發簡單"}}
]
},
{
"name": "訂單處理",
"questions": [
{"text": "同時很多人買同一個商品,會超賣嗎?", "explanation": "高並發情況下,需要防止庫存超賣", "options": ["會,需要防止", "不會,系統會處理", "🤷 先跳過"], "impact": {"0": "✅ 需要加鎖機制\n✅ 保證不超賣", "1": "⚠️ 可能超賣\n⚠️ 需要退款"}},
{"text": "訂單可以取消嗎?", "explanation": "取消政策影響用戶體驗和商家權益", "options": ["隨時可以", "只能在出貨前", "不能取消", "🤷 先跳過"], "impact": {"0": "✅ 用戶體驗好\n⚠️ 商家可能虧損", "1": "✅ 平衡雙方\n✅ 最常見", "2": "✅ 保護商家\n⚠️ 用戶體驗差"}},
{"text": "訂單要發送確認郵件嗎?", "explanation": "確認郵件可以讓用戶安心", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 用戶安心\n⚠️ 需要郵件系統", "1": "✅ 開發簡單"}},
{"text": "要支持訂單追蹤嗎?", "explanation": "追蹤功能可以減少客服壓力", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 減少客服\n⚠️ 需要物流 API", "1": "✅ 開發簡單"}},
{"text": "訂單要支持退貨嗎?", "explanation": "退貨政策影響用戶信任", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 建立信任\n⚠️ 需要退貨流程", "1": "✅ 開發簡單\n⚠️ 用戶不信任"}},
{"text": "要支持訂單備註嗎?", "explanation": "備註可以讓用戶補充資訊", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 用戶體驗好\n⚠️ 需要審核", "1": "✅ 開發簡單"}},
{"text": "訂單完成後要評價嗎?", "explanation": "評價可以建立信任", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 建立信任\n⚠️ 需要評價系統", "1": "✅ 開發簡單"}}
]
},
{
"name": "付款",
"questions": [
{"text": "支持哪些付款方式?", "explanation": "不同的付款方式會影響開發成本和用戶體驗", "options": ["只有信用卡", "信用卡+行動支付", "全部都要", "🤷 先跳過"], "impact": {"0": "✅ 開發簡單\n⚠️ 用戶選擇少", "1": "✅ 平衡選擇\n✅ 涵蓋大部分用戶", "2": "✅ 用戶選擇多\n⚠️ 開發成本高"}},
{"text": "付款失敗要重試幾次?", "explanation": "自動重試可以提高成功率,但可能重複扣款", "options": ["不重試", "重試1次", "重試3次", "🤷 先跳過"], "impact": {"0": "✅ 避免重複扣款\n⚠️ 成功率低", "1": "✅ 平衡選擇\n✅ 最安全", "2": "✅ 成功率高\n⚠️ 可能重複扣款"}},
{"text": "要支持分期付款嗎?", "explanation": "分期可以提高大額商品銷量", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 提高銷量\n⚠️ 需要金融 API", "1": "✅ 開發簡單"}},
{"text": "要支持貨到付款嗎?", "explanation": "貨到付款可以提高信任", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 提高信任\n⚠️ 需要物流配合", "1": "✅ 開發簡單"}},
{"text": "付款要加密嗎?", "explanation": "加密可以保護用戶資料", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 保護資料\n✅ 必須要", "1": "⚠️ 不安全"}},
{"text": "要顯示付款進度嗎?", "explanation": "進度顯示可以減少用戶焦慮", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 用戶安心", "1": "✅ 開發簡單"}},
{"text": "付款完成要發送通知嗎?", "explanation": "通知可以確認付款成功", "options": ["要", "不用", "🤷 先跳過"], "impact": {"0": "✅ 用戶安心\n⚠️ 需要通知系統", "1": "✅ 開發簡單"}}
]
}
]
}, ensure_ascii=False)
# 記帳類
if any(keyword in user_input for keyword in ['記帳', '帳本', '花費', '支出']):
return json.dumps({
"title": "記帳 App",
"cards": [
{"name": "記錄支出", "questions": [{"text": "支出要分類嗎?", "explanation": "分類可以幫助統計,但會增加記帳時間", "options": ["要", "不用", "🤷 先跳過"]}, {"text": "可以拍發票照片嗎?", "explanation": "拍照功能方便,但需要 OCR 識別技術", "options": ["可以", "不用", "🤷 先跳過"]}]},
{"name": "統計報表", "questions": [{"text": "要顯示圖表嗎?", "explanation": "圖表可以更直觀地看到支出趨勢", "options": ["要圓餅圖", "要長條圖", "都要", "🤷 先跳過"]}]},
{"name": "預算提醒", "questions": [{"text": "超過預算要提醒嗎?", "explanation": "提醒可以幫助控制支出", "options": ["要", "不用", "🤷 先跳過"]}]}
]
}, ensure_ascii=False)
# 股票類
if any(keyword in user_input for keyword in ['股票', '股市', '投資', '證券']):
return json.dumps({
"title": "股票 App",
"cards": [
{"name": "即時報價", "questions": [{"text": "股價多久更新一次?", "explanation": "更新頻率會影響服務器成本和用戶體驗", "options": ["每秒", "每5秒", "每分鐘", "🤷 先跳過"]}, {"text": "網路斷線時怎麼辦?", "explanation": "需要處理網路不穩定的情況", "options": ["顯示舊資料", "顯示錯誤", "自動重連", "🤷 先跳過"]}]},
{"name": "下單", "questions": [{"text": "下單前要確認嗎?", "explanation": "確認可以防止誤操作,但會多一個步驟", "options": ["要", "不用", "🤷 先跳過"]}]},
{"name": "我的持股", "questions": [{"text": "要顯示賺賠多少嗎?", "explanation": "顯示賺賠可能影響用戶心情", "options": ["要", "不用", "讓用戶選", "🤷 先跳過"]}]}
]
}, ensure_ascii=False)
# 外送類
if any(keyword in user_input for keyword in ['外送', '送餐', 'uber', 'foodpanda', '叫餐']):
return json.dumps({
"title": "外送平台",
"cards": [
{"name": "餐廳列表", "questions": [{"text": "要顯示距離嗎?", "explanation": "距離可以幫助用戶選擇,但需要定位權限", "options": ["要", "不用", "🤷 先跳過"]}, {"text": "要顯示評分嗎?", "explanation": "評分可以幫助選擇,但需要評價系統", "options": ["要", "不用", "🤷 先跳過"]}]},
{"name": "即時追蹤", "questions": [{"text": "要顯示外送員位置嗎?", "explanation": "即時追蹤需要 GPS 和地圖 API", "options": ["要", "不用", "🤷 先跳過"]}]},
{"name": "訂單", "questions": [{"text": "可以取消訂單嗎?", "explanation": "取消政策會影響用戶體驗和商家權益", "options": ["隨時可以", "只能在接單前", "不能取消", "🤷 先跳過"]}]}
]
}, ensure_ascii=False)
# 默認響應
return json.dumps({
"title": user_input,
"cards": [
{"name": "基本功能", "questions": [{"text": "這個功能需要用戶登入嗎?", "explanation": "登入可以保存用戶數據,但會增加使用門檻", "options": ["需要", "不需要", "🤷 先跳過"]}, {"text": "需要保存數據嗎?", "explanation": "保存數據需要資料庫,但可以記住用戶偏好", "options": ["需要", "不需要", "🤷 先跳過"]}]},
{"name": "用戶界面", "questions": [{"text": "需要深色模式嗎?", "explanation": "深色模式對眼睛友好,但需要額外設計", "options": ["需要", "不需要", "🤷 先跳過"]}]}
]
}, ensure_ascii=False)
def _validate_blueprint(blueprint: dict) -> bool:
"""驗證藍圖格式"""
if "title" not in blueprint or "cards" not in blueprint:
return False
for card in blueprint["cards"]:
if "name" not in card or "questions" not in card:
return False
for question in card["questions"]:
if "text" not in question or "options" not in question or "answer" not in question:
return False
return True
def _get_fallback_blueprint(user_input: str) -> dict:
"""當 AI 失敗時的備用藍圖"""
return {
"title": user_input,
"cards": [
{
"name": "基本功能",
"questions": [
{
"text": "這個功能需要用戶登入嗎?",
"options": ["需要", "不需要"],
"answer": 0
},
{
"text": "需要保存數據嗎?",
"options": ["需要", "不需要"],
"answer": 0
}
]
}
]
}
# 測試函數
async def test_blueprint_generation():
"""測試藍圖生成"""
test_inputs = [
"我要做一個電商 app 像蝦皮",
"我要做一個看股票的 app",
"我要做一個記帳 app"
]
for user_input in test_inputs:
print(f"\n測試輸入: {user_input}")
result = await mmla_generate_blueprint_logic(user_input)
print(f"結果: {result}")
if __name__ == "__main__":
asyncio.run(test_blueprint_generation())