diff --git a/README.md b/README.md index 34e6997..647aeed 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,7 @@ Easy-Vibe teaches you how to turn that into a real product. ## 🔥 News +- **[2026-05-26]** 🌍 **Stage 2 multilingual coverage is now complete**: Stage 2 (Junior Developer) is fully available across all supported locales (zh-cn, en, zh-tw, ja-jp, ko-kr, es-es, fr-fr, de-de, ar-sa, vi-vn), covering 24 chapters of frontend, backend, AI capabilities, and comprehensive projects. - **[2026-05-20]** 🌍 **Stage 1 multilingual coverage is now complete**: Stage 1 is fully available across all supported locales (zh-cn, en, zh-tw, ja-jp, ko-kr, es-es, fr-fr, de-de, ar-sa, vi-vn). Navigation/build checks have been verified to avoid 404s. - **[2026-03-29]** ✨ **Vibe Stories launched and upgraded with real user journeys**: Added a new homepage Vibe Stories section with an interactive carousel and dedicated story pages, then replaced placeholder content with four real user stories featuring a rural primary school teacher, a college student, a high school IT teacher, and a truck driver who built real products with AI. [👉 View the stories](https://datawhalechina.github.io/easy-vibe/zh-cn/vibe-stories/story-1.html) - **[2026-03-26]** 🚀 **Major Stage 2 practice update**: Completed the SaaS capstone project "[Your First SaaS Full-Stack App: Copywriting Generator Website](https://datawhalechina.github.io/easy-vibe/en/stage-2/assignments/fullstack-app/)" and substantially expanded the "[How to integrate Stripe and payment systems](https://datawhalechina.github.io/easy-vibe/en/stage-2/backend/stripe-payment/)" section, plus key content around multi-product UI and WeChat Mini Program backend workflows. diff --git a/docs/.vitepress/config.mjs b/docs/.vitepress/config.mjs index 0c2fe21..d84b0c7 100644 --- a/docs/.vitepress/config.mjs +++ b/docs/.vitepress/config.mjs @@ -618,6 +618,121 @@ const stage2SidebarEn = [ } ] +const zhCnStage2Sidebar = [ + { + text: '前端开发', + collapsed: false, + items: [ + { + text: 'NanoBanana 素材生产', + link: '/zh-cn/stage-2/frontend/lovart-assets/' + }, + { + text: 'Figma 与 MasterGo 入门', + link: '/zh-cn/stage-2/frontend/figma-mastergo/' + }, + { + text: 'UI 设计规范与多产品界面', + link: '/zh-cn/stage-2/frontend/multi-product-ui/' + }, + { + text: '结合 Agent Skills 美化界面', + link: '/zh-cn/stage-2/frontend/llm-skills-beautiful/' + }, + { + text: '设计原型到项目代码', + link: '/zh-cn/stage-2/frontend/design-to-code/' + }, + { + text: '现代组件库与界面升级', + link: '/zh-cn/stage-2/frontend/modern-component-library/' + } + ] + }, + { + text: '后端开发', + collapsed: false, + items: [ + { + text: '数据库与 Supabase 入门', + link: '/zh-cn/stage-2/backend/database-supabase/' + }, + { + text: '大模型辅助接口开发', + link: '/zh-cn/stage-2/backend/ai-interface-code/' + }, + { + text: 'Git 与 GitHub 入门指南', + link: '/zh-cn/stage-2/backend/git-workflow/' + }, + { + text: '网页应用部署全面指南', + link: '/zh-cn/stage-2/backend/zeabur-deployment/' + }, + { + text: 'CLI Coding Agent 编程助手', + link: '/zh-cn/stage-2/backend/modern-cli/' + }, + { + text: 'Stripe 支付集成', + link: '/zh-cn/stage-2/backend/stripe-payment/' + } + ] + }, + { + text: 'AI 能力附录', + collapsed: false, + items: [ + { + text: 'Dify 入门与知识库集成', + link: '/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/' + } + ] + }, + { + text: '综合项目', + collapsed: false, + items: [ + { + text: '一起做霍格沃茨画像', + link: '/zh-cn/stage-2/frontend/hogwarts-portraits/' + }, + { + text: 'AI 营销文案 SaaS', + link: '/zh-cn/stage-2/assignments/copywriting-platform-supabase/' + }, + { + text: '在线考试与管理系统', + link: '/zh-cn/stage-2/assignments/exam-management-express/' + }, + { + text: '现代 AI 生图 SaaS', + link: '/zh-cn/stage-2/assignments/modern-landing-page/' + }, + { + text: '类 Dify 智能体平台', + link: '/zh-cn/stage-2/assignments/custom-dify-agent-platform/' + }, + { + text: '智能旅游规划 Agent 平台', + link: '/zh-cn/stage-2/assignments/travel-planning-agent-platform/' + }, + { + text: 'Spring Boot 电影推荐系统', + link: '/zh-cn/stage-2/assignments/movie-recommendation-springboot/' + }, + { + text: '生鲜电商微服务系统', + link: '/zh-cn/stage-2/assignments/simple-grocery-microservices/' + }, + { + text: 'Go 交通数据分析平台', + link: '/zh-cn/stage-2/assignments/traffic-data-visualization-go/' + } + ] + } +] + const stage3SidebarEn = [ { text: 'Core Skills', @@ -1635,8 +1750,12 @@ const stage1SidebarLabels = { ] } -const applySidebarLabels = (sidebar, locale) => { - const labels = stage1SidebarLabels[locale] +const applySidebarLabels = ( + sidebar, + locale, + labelsSource = stage1SidebarLabels +) => { + const labels = labelsSource[locale] if (!labels) return sidebar return sidebar.map((group, groupIndex) => ({ @@ -1659,6 +1778,355 @@ const getStage1Sidebar = (locale) => { ) } +const stage2SidebarLabels = { + 'ja-jp': [ + { + text: 'フロントエンド開発', + items: [ + 'NanoBanana 素材生産', + 'Figma & MasterGo 入門', + 'UI デザイン仕様とマルチプロダクトUI', + 'Agent Skills でインターフェース美化', + 'デザインプロトタイプからプロジェクトコードへ', + 'モダンコンポーネントライブラリとUIアップグレード' + ] + }, + { + text: 'バックエンド開発', + items: [ + 'データベースと Supabase 入門', + '大規模モデル補助インターフェース開発', + 'Git & GitHub 入門ガイド', + 'Webアプリケーションデプロイ包括ガイド', + 'CLI Coding Agent プログラミングアシスタント', + 'Stripe 決済統合' + ] + }, + { + text: 'AI 能力付録', + items: ['Dify 入門とナレッジベース統合'] + }, + { + text: '総合プロジェクト', + items: [ + 'ホグワーツ肖像画を作ろう', + 'AI マーケティングコピー SaaS', + 'オンライン試験・管理システム', + 'モダン AI 画像生成 SaaS', + 'Dify ライクなエージェントプラットフォーム', + 'スマート旅行プランニング Agent プラットフォーム', + 'Spring Boot 映画推薦システム', + '生鮮ECマイクロサービスシステム', + 'Go 交通データ分析プラットフォーム' + ] + } + ], + 'zh-tw': [ + { + text: '前端開發', + items: [ + 'NanoBanana 素材生產', + 'Figma 與 MasterGo 入門', + 'UI 設計規範與多產品介面', + '結合 Agent Skills 美化介面', + '設計原型到專案程式碼', + '現代元件庫與介面升級' + ] + }, + { + text: '後端開發', + items: [ + '資料庫與 Supabase 入門', + '大模型輔助介面開發', + 'Git 與 GitHub 入門指南', + '網頁應用部署全面指南', + 'CLI Coding Agent 程式設計助手', + 'Stripe 支付整合' + ] + }, + { + text: 'AI 能力附錄', + items: ['Dify 入門與知識庫整合'] + }, + { + text: '綜合專案', + items: [ + '一起做霍格沃茨畫像', + 'AI 行銷文案 SaaS', + '線上考試與管理系統', + '現代 AI 生圖 SaaS', + '類 Dify 智能體平台', + '智慧旅遊規劃 Agent 平台', + 'Spring Boot 電影推薦系統', + '生鮮電商微服務系統', + 'Go 交通資料分析平台' + ] + } + ], + 'ko-kr': [ + { + text: '프론트엔드 개발', + items: [ + 'NanoBanana 에셋 생산', + 'Figma & MasterGo 입문', + 'UI 디자인 가이드라인과 멀티 프로덕트 UI', + 'Agent Skills 인터페이스 미화', + '디자인 프로토타입에서 프로젝트 코드로', + '모던 컴포넌트 라이브러리와 UI 업그레이드' + ] + }, + { + text: '백엔드 개발', + items: [ + '데이터베이스와 Supabase 입문', + '대규모 모델 보조 인터페이스 개발', + 'Git & GitHub 입문 가이드', + '웹 애플리케이션 배포 종합 가이드', + 'CLI Coding Agent 프로그래밍 어시스턴트', + 'Stripe 결제 통합' + ] + }, + { + text: 'AI 역량 부록', + items: ['Dify 입문과 지식 베이스 통합'] + }, + { + text: '종합 프로젝트', + items: [ + '호그와트 초상화 만들기', + 'AI 마케팅 카피 SaaS', + '온라인 시험 및 관리 시스템', + '모던 AI 이미지 생성 SaaS', + 'Dify 유사 에이전트 플랫폼', + '스마트 여행 계획 Agent 플랫폼', + 'Spring Boot 영화 추천 시스템', + '신선 식품 전자상거래 마이크로서비스', + 'Go 교통 데이터 분석 플랫폼' + ] + } + ], + 'es-es': [ + { + text: 'Desarrollo Frontend', + items: [ + 'Producción de activos NanoBanana', + 'Introducción a Figma y MasterGo', + 'Especificaciones de diseño UI y multi-producto', + 'Embellecimiento de interfaces con Agent Skills', + 'De prototipo de diseño a código de proyecto', + 'Bibliotecas de componentes modernas' + ] + }, + { + text: 'Desarrollo Backend', + items: [ + 'Introducción a bases de datos y Supabase', + 'Desarrollo de interfaces asistido por LLM', + 'Guía de introducción a Git y GitHub', + 'Guía completa de despliegue de aplicaciones web', + 'CLI Coding Agent - Asistente de programación', + 'Integración de pagos con Stripe' + ] + }, + { + text: 'Apéndice de capacidades IA', + items: ['Introducción a Dify e integración de base de conocimientos'] + }, + { + text: 'Proyectos integrales', + items: [ + 'Creemos retratos de Hogwarts', + 'SaaS de copywriting con IA', + 'Sistema de exámenes en línea y gestión', + 'SaaS moderno de generación de imágenes con IA', + 'Plataforma de agentes tipo Dify', + 'Plataforma de planificación de viajes con Agent', + 'Sistema de recomendación de películas con Spring Boot', + 'Sistema de microservicios de comercio electrónico de alimentos', + 'Plataforma de análisis de datos de tráfico con Go' + ] + } + ], + 'fr-fr': [ + { + text: 'Développement Frontend', + items: [ + 'Production de ressources NanoBanana', + 'Introduction à Figma et MasterGo', + 'Spécifications UI et interfaces multi-produits', + 'Embellissement des interfaces avec Agent Skills', + 'Du prototype de design au code de projet', + 'Bibliothèques de composants modernes' + ] + }, + { + text: 'Développement Backend', + items: [ + 'Introduction aux bases de données et Supabase', + "Développement d'interfaces assisté par LLM", + "Guide d'introduction à Git et GitHub", + "Guide complet de déploiement d'applications web", + 'CLI Coding Agent - Assistant de programmation', + 'Intégration de paiements avec Stripe' + ] + }, + { + text: 'Annexe des capacités IA', + items: ['Introduction à Dify et intégration de base de connaissances'] + }, + { + text: 'Projets globaux', + items: [ + 'Créons des portraits de Poudlard', + 'SaaS de rédaction IA', + "Système d'examens en ligne et de gestion", + "SaaS moderne de génération d'images IA", + "Plateforme d'agents de type Dify", + 'Plateforme de planification de voyages avec Agent', + 'Système de recommandation de films avec Spring Boot', + 'Système de microservices e-commerce alimentaire', + "Plateforme d'analyse de données de trafic avec Go" + ] + } + ], + 'de-de': [ + { + text: 'Frontend-Entwicklung', + items: [ + 'NanoBanana Asset-Produktion', + 'Einführung in Figma und MasterGo', + 'UI-Design-Spezifikationen und Multi-Produkt-UI', + 'Interface-Verschönerung mit Agent Skills', + 'Vom Design-Prototyp zum Projektcode', + 'Moderne Komponentenbibliotheken und UI-Upgrade' + ] + }, + { + text: 'Backend-Entwicklung', + items: [ + 'Einführung in Datenbanken und Supabase', + 'LLM-gestützte Schnittstellenentwicklung', + 'Git und GitHub Einführungsleitfaden', + 'Umfassender Leitfaden zur Webanwendungsbereitstellung', + 'CLI Coding Agent Programmierassistent', + 'Stripe-Zahlungsintegration' + ] + }, + { + text: 'KI-Fähigkeiten Anhang', + items: ['Dify Einführung und Wissensdatenbank-Integration'] + }, + { + text: 'Übergreifende Projekte', + items: [ + 'Erstellen wir Hogwarts-Porträts', + 'KI-Copywriting SaaS', + 'Online-Prüfung und Managementsystem', + 'Modernes KI-Bildgenerierungs-SaaS', + 'Dify-ähnliche Agenten-Plattform', + 'Intelligente Reiseplanungs-Agent-Plattform', + 'Spring Boot Filmempfehlungssystem', + 'Lebensmittel-E-Commerce-Microservices', + 'Go Verkehrsanalyseplattform' + ] + } + ], + 'ar-sa': [ + { + text: 'تطوير الواجهة الأمامية', + items: [ + 'إنتاج أصول NanoBanana', + 'مقدمة في Figma و MasterGo', + 'مواصفات تصميم UI وواجهات متعددة المنتجات', + 'تحسين الواجهات باستخدام Agent Skills', + 'من النموذج الأولي إلى كود المشروع', + 'مكتبات المكونات الحديثة وترقية الواجهة' + ] + }, + { + text: 'تطوير الواجهة الخلفية', + items: [ + 'مقدمة في قواعد البيانات و Supabase', + 'تطوير الواجهات بمساعدة النماذج الكبيرة', + 'دليل مقدمة في Git و GitHub', + 'دليل شامل لنشر تطبيقات الويب', + 'مساعد برمجة CLI Coding Agent', + 'تكامل مدفوعات Stripe' + ] + }, + { + text: 'ملحق قدرات الذكاء الاصطناعي', + items: ['مقدمة في Dify وتكامل قاعدة المعرفة'] + }, + { + text: 'مشاريع شاملة', + items: [ + 'لنصنع صور هوغوورتس', + 'SaaS كتابة التسويق بالذكاء الاصطناعي', + 'نظام الامتحانات عبر الإنترنت والإدارة', + 'SaaS حديث لتوليد الصور بالذكاء الاصطناعي', + 'منصة وكلاء شبيهة بـ Dify', + 'منصة تخطيط السفر الذكي مع Agent', + 'نظام توصية الأفلام بـ Spring Boot', + 'نظام الخدمات المصغرة للتجارة الإلكترونية للأغذية', + 'منصة تحليل بيانات المرور بـ Go' + ] + } + ], + 'vi-vn': [ + { + text: 'Phát triển Frontend', + items: [ + 'Sản xuất tài sản NanoBanana', + 'Giới thiệu Figma và MasterGo', + 'Quy cách thiết kế UI và đa sản phẩm', + 'Làm đẹp giao diện với Agent Skills', + 'Từ nguyên mẫu thiết kế đến mã dự án', + 'Thư viện thành phần hiện đại và nâng cấp UI' + ] + }, + { + text: 'Phát triển Backend', + items: [ + 'Giới thiệu cơ sở dữ liệu và Supabase', + 'Phát triển giao diện hỗ trợ bằng mô hình lớn', + 'Hướng dẫn入门 Git và GitHub', + 'Hướng dẫn toàn diện triển khai ứng dụng web', + 'Trợ lý lập trình CLI Coding Agent', + 'Tích hợp thanh toán Stripe' + ] + }, + { + text: 'Phụ lục năng lực AI', + items: ['Giới thiệu Dify và tích hợp cơ sở tri thức'] + }, + { + text: 'Dự án tổng hợp', + items: [ + 'Cùng làm chân dung Hogwarts', + 'SaaS viết文案 AI', + 'Hệ thống thi trực tuyến và quản lý', + 'SaaS tạo ảnh AI hiện đại', + 'Nền tảng Agent giống Dify', + 'Nền tảng Agent lập kế hoạch du lịch thông minh', + 'Hệ thống gợi ý phim Spring Boot', + 'Hệ thống microservice thương mại điện tử thực phẩm', + 'Nền tảng phân tích dữ liệu giao thông Go' + ] + } + ] +} + +const getStage2Sidebar = (locale) => { + if (locale === 'zh-cn') return zhCnStage2Sidebar + if (locale === 'en') return stage2SidebarEn + return applySidebarLabels( + localizeSidebarLinks(stage2SidebarEn, locale), + locale, + stage2SidebarLabels + ) +} + const docFooterLabels = { 'zh-cn': { prev: '上一页', next: '下一页' }, en: { prev: 'Previous page', next: 'Next page' }, @@ -1881,120 +2349,7 @@ Sitemap: ${siteUrl}/sitemap.xml } ], '/zh-cn/stage-1/': productManagerSidebar, - '/zh-cn/stage-2/': [ - { - text: '前端开发', - collapsed: false, - items: [ - { - text: 'NanoBanana 素材生产', - link: '/zh-cn/stage-2/frontend/lovart-assets/' - }, - { - text: 'Figma 与 MasterGo 入门', - link: '/zh-cn/stage-2/frontend/figma-mastergo/' - }, - { - text: 'UI 设计规范与多产品界面', - link: '/zh-cn/stage-2/frontend/multi-product-ui/' - }, - { - text: '结合 Agent Skills 美化界面', - link: '/zh-cn/stage-2/frontend/llm-skills-beautiful/' - }, - { - text: '设计原型到项目代码', - link: '/zh-cn/stage-2/frontend/design-to-code/' - }, - { - text: '现代组件库与界面升级', - link: '/zh-cn/stage-2/frontend/modern-component-library/' - } - ] - }, - { - text: '后端开发', - collapsed: false, - items: [ - { - text: '数据库与 Supabase 入门', - link: '/zh-cn/stage-2/backend/database-supabase/' - }, - { - text: '大模型辅助接口开发', - link: '/zh-cn/stage-2/backend/ai-interface-code/' - }, - { - text: 'Git 与 GitHub 入门指南', - link: '/zh-cn/stage-2/backend/git-workflow/' - }, - { - text: '网页应用部署全面指南', - link: '/zh-cn/stage-2/backend/zeabur-deployment/' - }, - { - text: 'CLI Coding Agent 编程助手', - link: '/zh-cn/stage-2/backend/modern-cli/' - }, - { - text: 'Stripe 支付集成', - link: '/zh-cn/stage-2/backend/stripe-payment/' - } - ] - }, - { - text: 'AI 能力附录', - collapsed: false, - items: [ - { - text: 'Dify 入门与知识库集成', - link: '/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/' - } - ] - }, - { - text: '综合项目', - collapsed: false, - items: [ - { - text: '一起做霍格沃茨画像', - link: '/zh-cn/stage-2/frontend/hogwarts-portraits/' - }, - { - text: 'AI 营销文案 SaaS', - link: '/zh-cn/stage-2/assignments/copywriting-platform-supabase/' - }, - { - text: '在线考试与管理系统', - link: '/zh-cn/stage-2/assignments/exam-management-express/' - }, - { - text: '现代 AI 生图 SaaS', - link: '/zh-cn/stage-2/assignments/modern-landing-page/' - }, - { - text: '类 Dify 智能体平台', - link: '/zh-cn/stage-2/assignments/custom-dify-agent-platform/' - }, - { - text: '智能旅游规划 Agent 平台', - link: '/zh-cn/stage-2/assignments/travel-planning-agent-platform/' - }, - { - text: 'Spring Boot 电影推荐系统', - link: '/zh-cn/stage-2/assignments/movie-recommendation-springboot/' - }, - { - text: '生鲜电商微服务系统', - link: '/zh-cn/stage-2/assignments/simple-grocery-microservices/' - }, - { - text: 'Go 交通数据分析平台', - link: '/zh-cn/stage-2/assignments/traffic-data-visualization-go/' - } - ] - } - ], + '/zh-cn/stage-2/': zhCnStage2Sidebar, '/zh-cn/stage-3/': [ { text: 'Claude Code 深入浅出', @@ -2777,8 +3132,8 @@ Sitemap: ${siteUrl}/sitemap.xml }, { text: 'フルスタック開発', - link: '/zh-cn/stage-2/frontend/lovart-assets/', - activeMatch: '/zh-cn/stage-2/' + link: '/ja-jp/stage-2/', + activeMatch: '/ja-jp/stage-2/' }, { text: '上級開発', @@ -2792,7 +3147,8 @@ Sitemap: ${siteUrl}/sitemap.xml } ], sidebar: { - '/ja-jp/stage-1/': getStage1Sidebar('ja-jp') + '/ja-jp/stage-1/': getStage1Sidebar('ja-jp'), + '/ja-jp/stage-2/': getStage2Sidebar('ja-jp') } } }, @@ -2830,8 +3186,8 @@ Sitemap: ${siteUrl}/sitemap.xml }, { text: '初中級開發', - link: '/zh-cn/stage-2/frontend/lovart-assets/', - activeMatch: '/zh-cn/stage-2/' + link: '/zh-tw/stage-2/', + activeMatch: '/zh-tw/stage-2/' }, { text: '高級開發', @@ -2845,7 +3201,8 @@ Sitemap: ${siteUrl}/sitemap.xml } ], sidebar: { - '/zh-tw/stage-1/': getStage1Sidebar('zh-tw') + '/zh-tw/stage-1/': getStage1Sidebar('zh-tw'), + '/zh-tw/stage-2/': getStage2Sidebar('zh-tw') } } }, @@ -2898,7 +3255,8 @@ Sitemap: ${siteUrl}/sitemap.xml } ], sidebar: { - '/ko-kr/stage-1/': productManagerSidebarKo + '/ko-kr/stage-1/': productManagerSidebarKo, + '/ko-kr/stage-2/': getStage2Sidebar('ko-kr') } } }, @@ -2936,8 +3294,8 @@ Sitemap: ${siteUrl}/sitemap.xml }, { text: 'Desarrollo Full Stack', - link: '/zh-cn/stage-2/frontend/lovart-assets/', - activeMatch: '/zh-cn/stage-2/' + link: '/es-es/stage-2/', + activeMatch: '/es-es/stage-2/' }, { text: 'Desarrollo Avanzado', @@ -2951,7 +3309,8 @@ Sitemap: ${siteUrl}/sitemap.xml } ], sidebar: { - '/es-es/stage-1/': getStage1Sidebar('es-es') + '/es-es/stage-1/': getStage1Sidebar('es-es'), + '/es-es/stage-2/': getStage2Sidebar('es-es') } } }, @@ -2989,8 +3348,8 @@ Sitemap: ${siteUrl}/sitemap.xml }, { text: 'Développement Full Stack', - link: '/zh-cn/stage-2/frontend/lovart-assets/', - activeMatch: '/zh-cn/stage-2/' + link: '/fr-fr/stage-2/', + activeMatch: '/fr-fr/stage-2/' }, { text: 'Développement Avancé', @@ -3004,7 +3363,8 @@ Sitemap: ${siteUrl}/sitemap.xml } ], sidebar: { - '/fr-fr/stage-1/': getStage1Sidebar('fr-fr') + '/fr-fr/stage-1/': getStage1Sidebar('fr-fr'), + '/fr-fr/stage-2/': getStage2Sidebar('fr-fr') } } }, @@ -3042,8 +3402,8 @@ Sitemap: ${siteUrl}/sitemap.xml }, { text: 'Full Stack Entwicklung', - link: '/zh-cn/stage-2/frontend/lovart-assets/', - activeMatch: '/zh-cn/stage-2/' + link: '/de-de/stage-2/', + activeMatch: '/de-de/stage-2/' }, { text: 'Fortgeschrittene Entwicklung', @@ -3057,7 +3417,8 @@ Sitemap: ${siteUrl}/sitemap.xml } ], sidebar: { - '/de-de/stage-1/': getStage1Sidebar('de-de') + '/de-de/stage-1/': getStage1Sidebar('de-de'), + '/de-de/stage-2/': getStage2Sidebar('de-de') } } }, @@ -3095,8 +3456,8 @@ Sitemap: ${siteUrl}/sitemap.xml }, { text: 'تطوير Full Stack', - link: '/zh-cn/stage-2/frontend/lovart-assets/', - activeMatch: '/zh-cn/stage-2/' + link: '/ar-sa/stage-2/', + activeMatch: '/ar-sa/stage-2/' }, { text: 'تطوير متقدم', @@ -3110,7 +3471,8 @@ Sitemap: ${siteUrl}/sitemap.xml } ], sidebar: { - '/ar-sa/stage-1/': getStage1Sidebar('ar-sa') + '/ar-sa/stage-1/': getStage1Sidebar('ar-sa'), + '/ar-sa/stage-2/': getStage2Sidebar('ar-sa') } } }, @@ -3149,8 +3511,8 @@ Sitemap: ${siteUrl}/sitemap.xml }, { text: 'Phát triển Full Stack', - link: '/zh-cn/stage-2/frontend/lovart-assets/', - activeMatch: '/zh-cn/stage-2/' + link: '/vi-vn/stage-2/', + activeMatch: '/vi-vn/stage-2/' }, { text: 'Phát triển Nâng cao', @@ -3164,7 +3526,8 @@ Sitemap: ${siteUrl}/sitemap.xml } ], sidebar: { - '/vi-vn/stage-1/': getStage1Sidebar('vi-vn') + '/vi-vn/stage-1/': getStage1Sidebar('vi-vn'), + '/vi-vn/stage-2/': getStage2Sidebar('vi-vn') } } } diff --git a/docs/ar-sa/stage-2/ai-capabilities/dify-knowledge-base/index.md b/docs/ar-sa/stage-2/ai-capabilities/dify-knowledge-base/index.md new file mode 100644 index 0000000..bebd80d --- /dev/null +++ b/docs/ar-sa/stage-2/ai-capabilities/dify-knowledge-base/index.md @@ -0,0 +1,1044 @@ +# مقدمة في Dify ودمج قاعدة المعرفة + +# مراجعة الدرس السابق + +在前几节课中,我们分组学习了 AI 编程、نصيحة词工程以及 AI 图像生成的基础知识。这些内容帮助我们初步了解了不同大语言模型(LLM,Large Language Model)或生成式模型的边界和能力。 + +为了帮助你回顾上节课的内容,下面有几个小问题可以思考: + +1. 什么是 AI 编程?如何使用 AI 编程工具(例如 [z.ai](http://z.ai))来创建一个网页? +2. 什么是大语言模型?什么是نصيحة词工程和上下文工程?你该如何编写一个复杂的نصيحة词? +3. 对于文本、AI Coding、图像生成的三个不同方向,你认为模型能力的强弱分别体现在什么地方? +4. 什么是 API?如何使用 [z.ai](http://z.ai) 接入第三方 API ? + +如果你对其中任何一个问题还感到疑惑,可以回看上节课的文档,也可以直接在微信群里提问。 + +在这节课中,我们将从简单的 AI 文字图片工具,进入更接近公司业务落地的工作流搭建平台。从对话机器人走向 AI 智能体、AI 工作流,并基于 API 把它变成可交互的“智能”机器人页面。 + +在操作过程中,如果遇到难以理解的خطوة,请不要担心,推荐你随时对当前所在的操作页面进行截图,发送给大模型进行询问;当前大模型已能够解答大部分الأسئلة الشائعة。 + +如果提问后仍无法解决,不妨大胆尝试操作;不必害怕出错,每一次尝试都是学习和进步的机会。随着实践次数的增加,你会越来越熟练,操作也会越来越得心应手! + +# 本节课ما ستتعلمه + +1. 为什么需要从聊天机器人走向智能体和 Workflow 编排。 +2. 什么是智能体与工作流开发平台,如何把 AI 的能力 SOP 化与可编排化。 +3. 什么是 Dify,如何用这个面向 LLM 应用的开源平台快速搭建应用,尤其是知识库问答机器人。 +4. RAG 的实现方法与价值,为什么需要检索增强生成? +5. 如何从 0 到 1 学会使用 Dify 和 AI IDE Trae (`Extra Knowledge 4 - What is AI IDE and Trae`),包括搭建 智能体、工作流,并基于 Dify API 制作前端对话机器人网页程序。 + +- Dify 的基本使用原理与智能体、工作流制作方法,API 调用方法。 +- AI IDE 的使用方法,如何使用 AI IDE 编程。 +- 一个可进行对话的前端网页智能体程序。 + +# 1. 从对话到智能体 + +在上一阶段,我们学会了如何用نصيحة词让大模型扮演角色、生成文本或编写简单代码。但如果你仔细思考,会发现一个问题,聊天机器人本身并不能做事。 + +它能回答怎么查订单?,却不能真的去数据库里查对应的数字;它能描述一封周报应该包含什么,却无法自动汇总你的项目数据并发送邮件。这种“只说不做”的局限,使得纯对话式 AI 难以真正融入业务流程。 + +要让 AI 从聊天伙伴升级为数字员工,我们需要赋予它三项核心能力: + +1. 专属知识——让它能够通读并了解你的产品文档、客户资料、内部制度; +2. 工具调用(或者叫插件)——让它能操作数据库、调用 API; +3. 结构化执行——让它按预设逻辑一步步完成任务,而非自由发挥。 + +这就是 AI 智能体(AI Agent)的雏形:一个具备目标、知识、工具和执行路径的自动化单元。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image1.png) + +> ملاحظة:当前业界所说的简单版本的“智能体”,大多指基于 LLM + 工具 + 知识库组合而成的增强型应用,并非所谓能够自主规划的智能体。简单的智能体虽不具备真正的推理与长期规划能力,但已足以支撑大量企业级自动化场景。我们将会在之后的章节详细介绍真正的具备自主规划和行动能力的智能体。 + +## 1.1 最简单的智能体:基于知识库的问答机器人 + +在明确智能体应具备的多项核心能力后,一个值得思考的问题随之而来:能否仅通过实现其中某一项最简单的功能,就构建出一个真正可用的基础智能体? 答案是肯定的。 + +事实上,在大量实际业务场景中,用户的核心诉求并非让 AI 自动执行复杂操作(如调用 API 或跨系统协调任务),而是希望它能基于企业自身的专属资料,提供精准、可靠的问答支持。这恰好对应智能体三大核心能力中的第一项,专属知识服务能力。因此,我们得以引出智能体最简单、也最广泛应用的形态:基于知识库的问答机器人。 + +虽然它尚未具备工具调用或自主规划能力,但其关键突破在于:让大模型的回答不再凭空生成,而是有据可依。如何实现?关键就在于解决核心挑战:企业内置大量文档知识,当存在千上万页文档时,模型如何在每一轮对话中快速找到与当前问题最相关的内容? + +此时的一个解决方案是:检索增强生成(Retrieval-Augmented Generation, RAG)。 + +RAG 的基本思路是:在用户提问时,系统首先从企业知识库中检索出与问题语义最相关的若干文本片段(例如产品手册中的某一段、HR制度中的某一条款),然后将这些片段作为上下文“注入”到大模型的输入中,引导它基于真实资料生成回答。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image2.png) + +图片来源:[https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag](https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag) + +这样一来,模型的回答不再是依赖其训练数据中的泛化知识,而是锚定在企业提供的权威معلومة之上。RAG 的目标,正是通过这种外部知识的动态注入,显著提升回答的真实性、准确性和一致性——甚至可以让回答“符合人设”,比如以客服口径或技术文档风格作答。 + +在实际业务中,这项技术尤为مهم,因为大模型常常会产生“幻觉”。例如,若你以 CFO 或咨询顾问的身份询问某个时间段的具体数据,模型很可能编造日期和事件。引入 RAG 后,回答的可控性与可靠性将得到显著提升。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image3.png) + +图片来源:[https://www.databricks.com/glossary/retrieval-augmented-generation-rag](https://www.databricks.com/glossary/retrieval-augmented-generation-rag) + +在本节课的实操环节中,我们将使用流行的 AI 工作流平台 Dify,动手搭建一个基于知识库的问答机器人。你可以轻松将各种类型的专属资料,如产品手册、公司制度、项目文档、研究论文、知识库文章,甚至是个人笔记集构建为知识库。 + +完成搭建后,你可以尝试提出各类问题来检验它的能力,例如: + +- “我们产品A的最新版本有哪些主要功能升级?” +- “请根据员工手册,说明今年的年假制度是如何规定的?” +- “在XX项目中,我们遇到的技术挑战‘XXX’是如何解决的?” +- “这篇论文中提到的核心研究方法是什么?” + +你将亲身感受 RAG 技术如何将静态分散的文档资料,转化为一个精准的智能知识库,为各种场景提供高精度问答支持。 + +## 1.2 从对话智能体到工作流 + +然而,即使是加入了知识库甚至是插件调用能力的“增强型智能体”,在面对更复杂的业务流程时仍显不足。 + +试想这样一个用户请求:“我们新上线的 SaaS 产品最近有哪些功能更新?能帮我整理成一份给客户的简报吗?” + +这个请求看似简单,背后却需要多个协同خطوة:首先从内部产品文档或 Notion 知识库中检索最近一个月的功能发布记录;然后过滤出面向客户的关键特性;接着调用大模型将技术描述转化为客户友好的语言;最后通过将生成内容推送至市场团队的邮箱,或保存到 Google Docs 模板中。 + +如果仅靠一个大语言模型自由推理,先不说是否能够一次对话实现所有过程,就算能,其中也很容易遗漏关键معلومة、混淆内部术语与客户语言,或无法结构化输出。更مهم的是,企业需要的是可审计、可复用、可监控的标准化执行路径,而不是每次依赖模型的临时发挥,可监控可复现对企业而言非常مهم,非预期的النتيجة很可能会带来预期外的严重损失。 + +这就引出了更高阶的 AI 应用范式:AI 工作流(AI Workflow)。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image4.png) + +工作流是指将一个复杂任务拆解为多个有序、可配置、可自动执行的子خطوة,并通过可视化或代码方式编排它们之间的逻辑关系,如条件判断、循环或并行执行。将 AI 能力 SOP 化(即标准化操作流程),意味着把如何用 AI 完成某项任务的经验固化为可重复使用的模板。 + +这种做法带来了多重价值:非技术人员(如产品经理或运营)可以通过拖拽组件快速搭建 AI 应用;开发者可以将 RAG 检索、LLM 调用、API 工具等封装为标准节点,在不同业务场景中复用;整个流程还可被完整追踪、调试和持续优化,满足企业对稳定性与合规性的要求。 + +AI 工作流的使用人群非常广泛。产品经理无需写代码,即可设计完整的用户交互路径;运营人员能快速搭建客服机器人、内容生成器或通知系统;开发者和算法工程师则可将核心能力模块化,供前端调用;创业者或独立开发者也能以极低成本验证 AI 产品的 MVP,几天内上线一个包含数据查询、内容生成与动作执行的完整原型。 + +此外,值得ملاحظة的是,AI 工作流通常可用一种中间表示(Intermediate Representation)来描述。不同工作流平台的具体表达方式虽有差异,但大多采用结构化文件(如 JSON、YAML 等)来定义节点类型、输入输出及执行逻辑,其结构类似下图所示: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image5.png) + +简言之,如果说智能体让 AI 从会聊天走向能做事,那么工作流则让 AI 从偶尔做成一件事迈向“稳定、可靠、规模化地完成一类事。在接下来的实践中,我们还将借助 Dify 平台,上手并亲手构建完整的 AI 工作流,体验从想法到可运行应用的完整过程。 + +## 1.3 常用智能体 / 工作流平台 + +随着生成式 AI 技术的飞速发展,为帮助开发者与业务人员快速构建智能体与自动化流程,避免陷入编程的复杂细节,一批低代码甚至无代码的智能体及工作流平台应运而生。 + +首先需要明确的是,低代码平台是指通过可视化拖拽组件、预置业务逻辑模板、图形化配置规则等方式,显著减少手动编码工作量的开发工具。其核心在于以可视化配置,节点式拖动变成的方式替代直接写代码的方式,既能让具备一定技术能力的开发者从重复劳动中解放出来,也能让熟悉业务逻辑的非技术人员参与到应用搭建中。本质上,它是在开发效率与场景灵活性之间架起一座平衡的桥梁。 + +这类低代码/无代码智能体平台的突出价值,正是大幅降低 AI 应用的开发门槛。以往需要团队协作数周——从需求梳理、代码开发到测试部署——才能完成的 AI 智能体(如客服问答机器人、数据处理助手),现在借助平台提供的可视化工具,可将“从创意到上线”的周期缩短至数小时。 + +目前市面上主流的低代码 AI 工作流平台包括: + +| 平台 | 特点 | 适用场景 | +| --------------------------------------------- | -------------------------------------------------- | -------------------------------------- | +| Dify | 开源、支持知识库 RAG、LLM 编排、API 输出,中文友好 | 企业知识库问答、定制化 Agent、API 服务 | +| Coze(字节跳动) | 国内可用、集成抖音/飞书生态、插件丰富 | 社交机器人、国内小程序集成 | +| n8n | 通用自动化工具,支持 AI 节点,强调 API 编排 | 跨系统数据同步、AI + 传统 SaaS 自动化 | +| 百度千帆 AppBuilder / 阿里百炼 / 腾讯 HunYuan | 大厂云原生方案,集成自家模型 | 企业级部署、合规要求高场景 | + +目前市面上的低代码 AI 工作流平台选择丰富。尽管 AWS、Azure、阿里云等主流云厂商均推出了相应的 AI 工作流解决方案,但 Dify、Coze 和 n8n 凭借以下三大核心优势,成为当前应用最广泛的代表: + +1. 极致易用性。平台采用可视化拖拽式界面设计,用户无需深入理解底层技术,即可快速上手。 +2. 高灵活性。支持自定义组件与扩展 API 接口,既能适应教学演示、MVP(最小可行产品)验证等轻量场景,也能满足中小型团队的敏捷迭代需求。 +3. 成熟生态。不仅官方文档详尽、响应及时,还拥有活跃的用户社区,便于快速获取来自不同用户的预设方案。 + +这三大平台均支持将搭建好的 AI 智能体以标准化 API 接口的形式输出,可无缝集成至前端 Web 应用、企业内部 ERP 系统或移动端 APP 中,进一步降低了 AI 能力落地的技术门槛。 + +### 1.3.1 Dify:企业级LLMOps与应用生命周期管理平台 + +Dify 定位是LLM应用开发与运营平台,致力于提供AI应用从构思、部署到优化的全生命周期管理。其核心是一个低代码平台,旨在帮助开发者和非技术背景的创新者快速构建生产级AI应用。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image6.png) + +在功能上,Dify覆盖了可视化工作流编排、智能体构建、知识库管理、多模型支持等功能。平台允许通过拖拽节点设计复杂任务流程,并支持创建基于意图的Agent。其知识库功能突出,能处理多种格式文档并进行高效的向量检索。同时,Dify兼容支持包括GPT、Claude及众多开源模型在内的多种LLM,构建的应用可一键发布为标准API便于集成。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image7.png) + +技术架构方面,Dify以开源和可私有化部署为特色,强调灵活性、扩展性及企业级合规。目标用户包括开发者团队和业务创新者,典型应用场景涵盖企业知识库与智能客服、内容创作自动化、垂直领域AI助手以及企业AI中台。 + +### 1.3.2 Coze(字节跳动):零代码AI智能体构建的普及者 + +Coze是字节跳动推出的AI智能体开发平台,以极致易用性为核心,让无编程经验的用户也能轻松创建、调试并发布功能丰富的AI聊天机器人。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image8.png) + +其核心是将Bot构建简化为搭积木式操作。用户可通过界面轻松配置角色与知识库,并利用丰富的内置插件库为Bot添加新闻、旅游、图像生成等多类外部能力。创建好的Bot可一键快速发布至豆包、飞书、微信公众号等多个平台。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image9.png) + +技术架构完全服务于低门槛使用,后端集成字节自有模型并封装复杂流程,强调多模态理解与实时响应。作为一个主要以云服务形式提供的平台,其私有化部署能力相对有限。典型应用场景包括个人助理与娱乐Bot、智能客服与问答系统、在线教育助手以及快速原型验证。 + +### 1.3.2 n8n:可编程的后端工作流自动化引擎 + +n8n是一个通用的可编程工作流自动化平台,其核心定位是连接各类应用、数据库与API,实现数据流动与任务自动化执行。 + +它通过庞大的集成节点库支持数百种SaaS服务、数据库及协议,并采用可视化与代码结合的方式:用户可在画布拖拽节点,同时注入JavaScript或Python代码编写自定义逻辑。n8n擅长处理后端数据密集型任务,如数据同步、ETL流程与API编排。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image10.png) + +关键技术特性是“源码可见”和“可自托管”,用户可将其私有化部署以完全掌控数据与环境,这使其对数据安全要求高的行业极具吸引力。其主要目标用户是开发者、技术运营及数据分析师。n8n 最大的优势,在于拥有极其强大的社区生态。网络上拥有随处可见丰富的 n8n 分享视频,为用户提供了便捷的学习参考与经验借鉴;同时,它支持连接 YouTube、Instagram 等全球众多不同生态平台,能够帮助用户轻松打破跨平台数据与服务的壁垒,实现多生态流程的自动化流转。 + +### 1.3.3 其他工作流平台 + +除了上述的几个最知名的平台,中国国内的主要科技厂商也相继推出了各自的一体化AI开发平台,例如:百度千帆 AppBuilder 提供从模型选型、RAG构建到智能体发布的全流程支持,深度集成文心大模型;阿里云百炼基于通义千问系列模型,注重企业级安全与私有化部署能力;腾讯云 TI 平台 则聚焦于金融、医疗等行业场景,提供丰富的预置解决方案模板。这类平台通常与各自云生态深度融合,适合已处于相应技术体系内的企业选用。 + +然而,在通用型、开放性与社区生态方面,Dify 与 Coze 仍凭借其突出的易用性、广泛的模型支持以及活跃的开发者社区,成为当前更受广泛采纳的选择。 + +尽管各平台在定位与生态上各有侧重,其核心逻辑均是通过可视化方式编排与连接不同的能力模块。因此,掌握其中任意一种平台的设计思路与操作方法,即具备快速迁移到其他类似工具的基础。在接下来的实践中,我们将以 Dify 为例进行具体讲解。 + +# 2. 深入浅出 Dify + +## 2.1 什么是 Dify + +我们在之前已经了解了基础的 Dify 的معلومة介绍,对于更详细的معلومة,你可以通过 [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps) 访问 Dify 平台,如果想了解更多معلومة,可以访问官网 https://dify.ai。 + +Dify 是一个用于开发 LLM 应用的开源平台。它提供了直观的界面,将 Agent 工作流、RAG 流水线、工具能力、模型管理、可观测性等功能结合在一起,帮助你快速地从原型走向生产环境。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image11.png) + +你可以在 Dify 中使用大语言模型和各种功能不同的工具来搭建“工作流”。所谓工作流,就是把原本需要你手动一步步完成的操作——例如数据检索、大模型调用、网页搜索、النتيجة过滤、格式整理等——按照业务逻辑串联起来,变成一个自动化、可复用的流程。如果没有工作流,每次你都需要把同样的内容复制粘贴给大模型,非常低效、容易出错,也难以在真实业务中复用。 + +搭建一个工作流,就像在拼搭积木或拼图。你把“大语言模型节点”(负责理解和生成)、各类“工具节点”(负责执行具体动作,例如查数据库、发邮件、翻译文本等)、以及“数据节点”(负责读取、存储معلومة)像积木一样连接起来。它们会按照你预设的逻辑自动协同工作,而不需要你每次都手动操作。你也可以把它理解成一种“低代码程序”:你只需要通过拖拽的方式,配置输入和输出的路径,就可以实现比较复杂的业务逻辑。 + +举个例子,如果你是一个亚马逊或抖音电商店铺的老板,想要搭建一个 AI 客服系统,可以参考下图的结构设计一个工作流: + +1. 触发节点(类似 START):接收用户的咨询问题,例如“这个商品的质保期有多长?”。 +2. 问题分类节点(类似 QUESTION CLASSIFIER):使用一个模型(例如 GPT)对用户问题进行分类,判断这是售后(比如质保)、使用方法,还是其他类型的问题。 +3. 知识检索节点(类似 KNOWLEDGE RETRIEVAL):根据分类النتيجة,自动访问相应的知识库。如果是关于“质保”的售后问题,就从售后 SOP 知识库中检索与“质保”相关的精确معلومة。 +4. 大语言模型节点(LLM Node):将用户问题和检索到的知识库内容一起发送给大语言模型(例如 GPT),让它生成一段对用户友好的回复(避免太生硬的技术语气)。 +5. 条件节点:检查大模型生成的回答中是否包含清晰的质保时间(例如“1 年”、“3 年”),如果有则继续الخطوة التالية,如果没有则让它回复“请提供产品型号”。 +6. 输出节点(类似 ANSWER):将最终答案返回给用户,并自动把本次咨询记录到表格中。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image12.png) + +在整个过程中,你不需要手动去翻知识库、反复调整模型的回答、或单独记录数据——工作流会把这些خطوة“连起来自动跑”。并且它非常灵活:例如,如果你之后想加一个新规则“当用户问质保范围时,调用另一个知识库”,只需要在工作流中多加一个条件节点,而无需重构整个系统。 + +这是一个比较简单的工作流مثال,但要完全掌握这些能力,对现在的你来说可能还有点难。因此在本节课中,我们从更加基础的知识库智能体开始,后面再逐步学习更复杂的工作流技巧。 + +### 2.1.1 部署属于自己的 Dify(可选) + +本部分内容原本安排在后续课程中详细介绍,但考虑到当前部分学习者可能因网络限制暂时无法访问 Dify 官方网站或云端服务,我们决定提前提供这一可选的学习路径,帮助你顺利推进课程进度。 + +你需要参考该教程入门 web 部署平台的基本使用方式:[如何部署 Web 应用](/ar-sa/stage-2/backend/zeabur-deployment/) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image13.png) + +你需要学习如何在 Zeabur 上部署一个自己的 Dify,部署后进入到对应链接注册并登录后继续跟随下列教程操作即可。 + +ملاحظة,不同版本的 Dify 的操作方面和前端界面可能有些许差别,但总体上差别不大,当你发现不同的时候不要慌张,找到类似的接口和入口进行操作即可。 + +## 2.2 创建第一个 Dify Chatbot 应用 + +访问 Dify 首页 [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps) 并注册和登录后,选择 Studio,你会看到如下界面: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image14.png) + +在左侧找到 `CREATE APP` 区块,点击 `Create from Blank`。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image15.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image16.png) + +在 APP Type 中找到 Chatbot(如果一开始没看到,可以点击“查看更多类型”的按钮,然后在完整列表中找到)。选择 Chatbot 之后,在下方输入应用的名称和描述,最后点击创建。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image17.png) + +创建完成后,你会看到类似下面的界面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image18.png) + +中间区域的 “INSTRUCTIONS” 指的是内置指令,你可以把它理解为默认نصيحة词或系统نصيحة词。 + +中间偏下有一个 “Knowledge” 区域,这就是知识库区域——我们稍后会把自己的知识库上传到这里。 + +右侧是调试窗口,你可以在调整نصيحة词后与 Agent 进行对话,实时查看效果。 + +你可以在 INSTRUCTIONS 区域自由输入角色نصيحة词,观察对话效果;也可以点击 Generate,让大模型自动帮你生成نصيحة词。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image19.png) + +ملاحظة右上角会出现许多不同模型的选项,这意味着你可以点击切换不同的对话模型,从而比较它们在语气、逻辑推理、长文本处理等方面的差异,寻找最适合你需求的模型。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image20.png) + +## 2.3 支持自定义模型供应商 + +为充分发挥 Dify 的灵活性,考虑到不同地区访问模型的难度,为满足特定业务需求、成本控制或数据隐私要求,我们常常需要接入自定义模型。Dify 支持配置三类核心模型:大语言模型(LLM)、Embedding 模型和 Rerank 模型。本部分内容将逐步指导你完成这些自定义配置。 + +Dify 能够灵活接入来自 OpenAI、Azure、Anthropic 等主流服务商的模型,同时也全面兼容任何符合 OpenAI API 接口规范的自托管模型或第三方模型。你可以通过安装内置的 OpenAI Compatible 插件以及对各大模型平台定制的插件实现这一操作。 + +详细خطوة参考如下,首先我们需要安装对应的插件: + +1. 我们需要安装 `OpenAI-API-compatible` 及 `SiliconFlow` 插件获得对绝大部分大模型和 Embedding 模型的支持,其中前者是对 OpenAI 兼容接口的支持,后者是一个部署了当前绝大部分常见、好用的开源模型的服务站。你可以访问下列网页进行安装: + 1. https://marketplace.dify.ai/plugins/langgenius/openai_api_compatible + 2. https://marketplace.dify.ai/plugins/langgenius/siliconflow +2. 如果你是自己部署的 Dify,你可以在对应系统设置界面进入插件市场进行操作 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image21.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image22.png) + +进入插件市场后,搜索对应的插件名称即可。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image23.png) + +3. 安装结束后,我们能够配置支持新的模型供应商,在设置里的模型提供商部分,我们可以看到目前支持的所有模型商: + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image24.png) +4. 在开始使用前,需要先完成模型的配置。对于 OpenAI-API-compatible 插件,你可以点击 “Add Model” 来添加并配置任意模型。你可以在 “Model Type” 中选择该模型是LLM还是 Embedding,你需要确保模型的类型被正确配置。 + 你需要写入具体的模型名字、模型 endpoint URL 以及 API Key 才能确保模型启用,如果你初步觉得配置该参数麻烦,你可以直接跳到后者的 SiliconFLow 平台的 Key 配置,或者安装 OpenRouter 等第三方服务商插件进行简单的模型支持配置。(确保服务商内有剩余可使用额度) + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image25.png) + + 对于 `SiliconFlow` 插件,只需要点击 Setup 配置 key 后即可使用 Embedding 和 Rerank 模型进行测试,你可以点击 Get you API Key from SiliconFlow 获得鉴权密钥。 + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image26.png) + +5. 配置完成后,你可以点击模型列表查看当前支持多少模型,此时已经完成了基础模型的全部配置。 + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image27.png) + + 其中支持了绝大部分常见的 Embedding 与 Rerank 模型: + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image28.png) + + 此时如果你想要修改 Dify 默认使用模型的配置,你还可以点击 System Model Settings 按钮修改默认的所有模型。 + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image29.png) + +## 2.4 创建第一个 Dify 知识库 + +到这里,我们已经完成了最简单的 Agent 创建,但它还缺少一个知识库。现在,请点击顶部菜单中的 `Knowledge`,进入知识库创建页面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image30.png) + +然后点击左侧的 `Create Knowledge`,创建你的第一个知识库。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image31.png) + +在这个界面中,你可以上传多种类型的文件(例如 pdf、txt 等)来构建知识库。可以上传很长的文本,或者把维基百科上的内容复制下来保存成 txt 文件进行上传。本例中,我们会上传一份关于 Elon Musk 的维基百科 txt 文件。 + +点击 Next 后,你会进入 Knowledge Base Settings(知识库设置)页面。这里选项比较多,我们一步一步来看。 + +首先在 **General** 设置中,你可以把这里理解成“文本切分规则”的设置区域。因为我们需要把很长的文本切分成小块,所以必须先定义切分规则。在入门阶段,你只需要关注 **maximum chunk length(最大切分长度)** 。可以尝试设置为 512、2048 或 4096,然后点击 **Preview Chunk** 预览不同设置下的效果。 + +你也可以调整 **Chunk overlap(切片重叠)** 选项。它决定相邻片段之间是否会保留一部分重叠内容。适当的重叠有助于避免مهممعلومة被拆到不同片段而难以理解。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image32.png) + +在设置中还有一个选项叫做 **Chunk using Q&A format in English** 。启用后,系统会使用大语言模型,将知识库的一部分内容转换成问答形式来存储,这在某些场景下可以显著提升检索效果。 + +在真实业务中,根据场景选择合适的切分策略,能够更好地优化检索النتيجة,保证查询能够返回你期望的معلومة。 + +继续向下滚动页面,你会看到和 Embedding 模型相关的设置。 + +简单解释一下:Embedding 模型的核心功能,是把非结构化数据(例如文本、图片等)转换成计算机能够理解的“数字向量”(Embedding 向量)。通过这种转换,模型能够快速计算不同数据之间的相似度,从而实现语义相近内容的匹配,比如根据用户输入的一句话,找到语义最接近的文档、图片或商品。 + +Embedding 模型的选择会显著影响最终的检索效果(例如匹配准确度、响应速度等)。在这里,我们推荐优先使用 Qwen 0.6B 的 Embedding 模型,你也可以切换到 4B 或 8B 版本,直观对比不同参数规模下检索效果的差异。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image33.png) + +在此处,你还会看到另一个模型设置叫做 **Rerank model** ,默认值是 **Jina-rerank-m0** 。(如果你非校园内的学生,此时你可能会看到 Rerank 模型缺失的报错,你需要在模型处配置 rerank 模型才能在此处启用使用) + +Rerank 模型的主要作用,是对“初步筛选出的候选النتيجة”进行二次、更精细的排序,让和用户需求最匹配的النتيجة排在更靠前的位置,从而显著提升最终النتيجة的相关性和用户体验。 + +简单理解:Rerank 模型就是用来解决“初次筛选不够精细”的问题。例如搜索引擎可能先用较简单的规则检索出 1000 个潜在相关网页,再通过 Rerank 模型,从中挑出最相关的前 10 个展示在第一页。 + +推荐系统同理:它可能首先找出 500 个“可能适合你”的商品,再通过 Rerank 模型排序,让你最可能购买的商品排在列表顶部。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image34.png) + +当所有设置完成后,点击 **Save & Process** ,系统就会进入知识库向量化阶段。在这一阶段,Embedding 模型会把切分后的文本转换为向量表示。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image35.png) + +处理完成后,点击 **Go to document** ,可以查看已经处理完毕并存储好的知识库内容。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image36.png) + +直接点击知识库名称,可以查看每个切片的具体内容。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image37.png) + +在这里,你可以对任意不合适的文本片段进行精确的编辑或删除操作。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image38.png) + +在左侧边栏中,选择 **Retrieval Testing** 可以对知识库进行召回测试,检查检索是否正常工作。每次测试会返回若干相似度最高的切片。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image39.png) + +如果你希望看到更多的切片النتيجة,需要点击 `VECTOR SEARCH` 设置: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image40.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image41.png) + +Top K 指的是向量检索时,返回与查询向量最相似的前 K 个文本切片数量。当前设置为 3,表示会返回相似度最高的 3 段文本。 + +Score Threshold 则是一个“得分阈值”:只有相似度得分大于或等于该阈值(مثال中为 0.5)的文本片段才会被返回。这样可以过滤掉相关度较低的内容,让النتيجة更加准确。 + +现在知识库部分就全部准备好了。接下来,点击顶部菜单栏中的 “studio”,找到刚才创建的智能体,为它接入我们已经配置好的知识库。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image42.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image43.png) + +此时,在每一轮对话中,你都可以在回答中看到被命中的知识库来源。点击对应条目即可查看检索到的具体文本片段。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image44.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image45.png) + +## 2.5 更多 DIfy 常见操作 + +在掌握基础 Chatbot 和知识库搭建的基础内容后,我们可以深入了解更多有关 Dify 的使用方式。 + +### 2.5.1 工作流的导入与导出 + +还记得之前提到的工作流的中间表示法吗?Dify 支持通过 DSL(Domain Specific Language) 格式导入和导出工作流。DSL 是一种基于 JSON 的标准化描述方式,能够完整保留工作流的节点结构、连接关系和配置参数。你可以很容易导入和导出 DSL 文件,分享工作流给其他人使用,或者导入别人的工作流进行参考。具体而言,我们能够容易在工作台页面看到工作流的导入按钮: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image46.png) + +而对于工作流的导出,我们只需要点击单个工作流块的右下角即可找到导出按钮: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image47.png) + +通过使用 DSL 文件,你可以轻松地在不同 Dify 实例之间迁移或共享复杂的工作流设计。 + +### 2.5.2 查看更多 Dify 项目 + +如果你觉得自己搭建的工作流或者智能体过于简单,Dify平台提供了丰富的مثال项目,帮助你快速了解如何构建复杂应用。这些مثال项目涵盖了多种业务场景。你可以点击 Explora 查看别人构建的工作流进行学习。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image48.png) + +## 2.6 创建第一个 Dify Workflow 应用 + +完成了 DIfy 的对话智能体构建入门,我们继续查看如何构建更复杂的 Dify 业务工作流。工作流是Dify将复杂业务逻辑可视化的核心方式,通过它你可以像搭积木一样构建智能流程。你能够完整体会معلومة如何在不同节点间流转,判断逻辑如何部署,人工干预点设置在哪里,以及最终如何交付一个完整的业务النتيجة。 + +你可以选择从空白处创建,或者直接从模板处创建,此处演示如何从空白处创建工作流: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image49.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image50.png) + +在这里我们会看见两个选择,分别是 Chatflow 与 Workflow,这两者该如何选择呢?关键是你需要理解你所要构建的,其核心是持续对话,还是任务流程。 + +Chatflow 专为对话而设计。它模拟一个具有记忆和上下文理解能力的对话者,非常适合需要多轮交互、状态维持的场景。例如在客服咨询中,它能连贯地理解用户的后续追问,如同一位耐心的服务人员。其流式输出的特性也让交互过程更为自然。简而言之,当你需要构建一个能“交谈”的智能体时,应选择 Chatflow。 + +Workflow 则专注于流程的自动化执行。它像一条预设的流水线,擅长处理一次性输入、多خطوة处理、并产生确定性输出的任务。例如,每日定时生成数据报表、批量处理文件或调用系列API。这类任务通常由事件触发,无需与人实时互动。因此,当你需要实现“自动化”任务时,Workflow 是更合适的选择。 + +为避免选型错误带来的效率低下,你可以通过四个关键问题来审视你的任务需求: + +1. 任务过程是否需要依赖多次的用户输入与调整? +2. النتيجة的呈现是否需要分خطوة、流式地进行? +3. 处理逻辑是否严重依赖于之前的交互历史? +4. 任务是否由事件触发,且输入输出多为一次性完成? + +如果前三个问题的答案为“是”,那么 Chatflow 是理想选择,典型场景包括智能客服、教育辅导、创意协作等。如果第四个问题特征显著,则应选用 Workflow,它更适用于数据清洗、报表生成、批量处理等自动化场景。 + +此处我们选择 Chatflow 作为案例进行介绍,点击 Chatflow 后进入到操作台界面: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image51.png) + +我们来简单介绍工作流界面的页面。其中整个界面的核心是中央的编辑画布,你将以可视化方式在这里构建应用逻辑。如图所示,一个基础的工作流通常始于 START 节点(用于接收输入),经由连线将数据传递至 LLM 节点进行处理,最终通过 ANSWER 节点输出النتيجة。每个节点代表一个功能模块,而连线则决定了任务执行的顺序。 + +环绕画布的是完整的操作与管理功能区。界面顶部提供了全局控制选项,包括测试工作流的 Preview 按钮和用于上线的 Publish 按钮。画布角落则设有缩放、撤销等视图控制工具,便于精细调整。 + +左侧面板集中了应用的管理功能。你当前所在的 Orchestrate 选项卡用于流程编排;构建完成后,可通过 API Access 获取集成凭证;Logs & Annotations 记录了每次执行的详细踪迹,便于调试;而 Monitoring 则为你提供应用运行时的性能与状态监控。 + +你可以简单在该对话工作流 LLM 节点的 SYSTEM 中输入一些نصيحة词内容,点击 Preview 后尝试运行这个工作流,查看修改 SYSTEM نصيحة词后整个工作流确实按照预期在变化。 + +### 2.6.1 常见节点介绍 + +Dify 中提供了多种节点,你可以先了解每个节点的基本功能。具体使用时,建议亲手尝试,或参考他人创建的工作流模板,也可以截图并向大模型询问该节点的用法、所需参数等。推荐直接在现有模板中替换不同节点,通过他人的使用方式来推测节点的最佳实践。 + +在画布右键点击“Add Node”即可添加节点,也可以在左侧的节点面板中查看所有可用节点: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image52.png) + +同时,可以打开工具选择面板,查看支持调用的各类工具: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image53.png) + +下面是一些常用节点和工具的简要说明。不需要一次性全部掌握,建议先留个印象,在实际使用中逐步熟悉,必要时再回查阅。 + +1. LLM与推理节点 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image54.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image55.png) + +此类节点负责工作流中的核心流程。 + +- LLM节点:核心计算单元,用于调用大语言模型。其配置重点在于نصيحة词工程与参数调优,将业务问题转化为模型的执行指令。 +- Knowledge Retrieval 节点:知识检索单元,负责从预设知识库、外部权威数据源中检索与业务问题相关的معلومة,为 LLM 节点提供精准的知识支撑,帮助减少大语言模型输出的 “幻觉” 问题。 +- Answer 节点:النتيجة输出单元,负责接收 LLM 处理后的内容,将其整理为符合业务场景需求的最终成果形式。其配置重点在于输出格式的定义(如话术模板、排版规范)。 +- Agent节点:高阶决策单元。它不仅调用模型,还可实施多خطوة规划、自主选择并调用外部工具,适用于需要动态决策的复杂任务链。 +- Question Classifier 节点:问题分类单元,负责对输入的业务问题进行类型识别与归类(比如按问题意图、主题领域等维度划分),帮助后续流程精准匹配对应的处理节点(如不同类型的问题适配不同的 LLM نصيحة词或工具链)。 + +2. 逻辑与流程控制节点 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image56.png) + +此类节点定义工作流的执行路径与规则。 + +- 条件节点:如 `IF/ELSE`,通过布尔判断实现流程分支。其设计关键在于条件表达式的严谨性,确保逻辑覆盖所有业务场景。 +- Iteration 节点:作为无状态的批量并行处理单元,它专为子任务间无数据依赖、可独立处理的场景设计,例如批量翻译段落、并行审核多条内容或同时生成多份报告。该节点会接收一个输入数组并自动分片,将每个元素分发至相同处理链路并行执行,用户可在迭代体内通过 {{item}} 访问当前元素、{{index}} 获取其索引,输出则会自动聚合成النتيجة数组;配置时需重点设定并行度以平衡效率与系统负载,同时通过重试策略(如重试次数、间隔)和失败处理(如记录日志、返回默认值)保障批量作业的稳定性。 +- Loop 节点:有状态的递归迭代器,适用于النتيجة依赖前一轮输出的场景,比如多轮参数调优、递归式内容优化(如反复修订文案直至满意)及依赖上次النتيجة的链式计算。其核心是 “状态变量”,需在循环开始前初始化(如当前迭代次数、中间计算النتيجة),并在每轮迭代中明确更新以作为下一轮输入;为防止无限循环,必须定义终止条件(包括基于计数器的 “最多循环 10 次”、基于النتيجة判定的 “满意度评分 > 9”、基于外部信号的 “检测到‘停止’输入”),同时需设置循环超时配置,并规划异常处理路径(如跳出循环或重置状态后重试),确保流程稳定运行。 + +3. 数据操作与集成节点 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image57.png) + +- Code 节点:代码处理单元,负责在工作流中执行自定义代码逻辑,可实现数据格式转换、复杂计算等个性化处理需求。其配置重点在于代码语法的正确性与执行环境的适配。 +- Template 节点:模板处理单元,负责将动态数据填充至预设模板中,生成符合格式要求的内容(如定制化文案、报告框架)。其配置重点在于模板语法的编写与变量映射规则的设置。 +- Variable Aggregator 节点:变量聚合单元,负责收集工作流中多个节点输出的变量数据,将分散的变量整合为统一数据集。其配置重点在于聚合的变量范围与数据合并规则的定义。 +- Doc Extractor 节点:文档提取单元,负责从 PDF、Word 等各类文档中提取文本、表格等关键内容,转化为工作流可处理的结构化数据。其配置重点在于文档类型的适配与提取内容的筛选规则。 +- Variable Assigner 节点:变量赋值单元,负责定义、初始化或更新工作流中的变量,为流程内的数据传递提供载体。其配置重点在于变量的命名、数据类型及赋值逻辑的设定。 +- Parameter Extractor 节点:参数提取单元,负责从用户请求、接口返回等输入内容中提取指定参数,将非结构化معلومة转化为结构化数据。其配置重点在于提取规则(如正则表达式、JSON 路径)的配置。 +- HTTP Request 节点:HTTP 请求单元,负责向外部系统接口发起 HTTP 请求(含 GET、POST 等方法),实现工作流与外部服务的数据交互。其配置重点在于请求地址、请求方法及参数 /headers 的设置。 +- List Operator 节点:列表操作单元,负责对数组、列表类型的数据进行处理(如过滤、排序、拆分),调整数据结构以适配后续流程。其配置重点在于操作类型(如过滤条件、排序规则)的定义。 + +### 2.6.2 常见工具介绍 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image58.png) + +在 Dify 中,大部分工具都可以直接作为节点放在画布上,像其他节点一样被上下游连线,只要你提供的输入符合该节点(工具)的参数规范,它就能正常执行并产出可继续流转的النتيجة。 + +在左侧或右侧的节点面板中,可以查看所有可用工具节点,也可以通过插件市场扩展更多工具能力。简单介绍几个常见工具的作用: + +- 网络搜索工具 + 以 Tavily Search 为代表,为大模型提供面向 AI 优化的实时检索能力。 + 它会返回结构化的搜索النتيجة(如标题、摘要、链接等),可以直接作为 LLM نصيحة词的一部分,用于回答最新资讯类或需要权威依据的问题。 +- 数据处理工具 + 例如 JSON Process 插件,用于对 JSON 数据进行查询、筛选、转换、合并等高级操作。 + 在处理复杂 API 响应或多层嵌套数据时,你可以将“数据清洗 + 重组”的逻辑交给该工具,从而简化在 Code 节点中频繁手写解析代码的工作。 +- 格式处理工具 + 如 Markdown Exporter,可以将生成内容按指定格式导出,例如 Markdown 文档、特定排版模板等,方便后续用于展示、汇报或集成到其他系统。 + +你可以在工具列表中看到这些插件的安装量和简介,初期可优先尝试安装“Featured / 推荐”里的工具,往往覆盖了最常见的业务场景。 + +不过,工具的使用通常比较复杂,建议你在使用的时候可以去搜索引擎先搜索对应工具的“官方推荐工作流 DSL 案例”,直接导入使用,比自己搭建要天然节约很多时间。 + +### 2.6.3 创建简单的意图分类工作流 + +此时我们已经初步了解了 Dify 工作流和工具等的基本معلومة,但不经过تمرين我们永远不会熟练使用细节,我们需要一个“假设”的真实业务场景来练练手。 + +例如,在真实的购物对话场景中,前来购买商品的用户输入永远不会是“规范的参数”,而是一句随口说出的话:有人来下单,有人来抱怨,有人只是想闲聊,也有人完全跑题。如果我们把所有这些输入都直接交给同一个大语言模型(LLM)处理,系统通常会出现两个典型问题: + +1. 回复风格不稳定 + 同样是抱怨,有时 LLM 能道歉安抚,有时却像在“解释原因”;同样是点餐,有时会追问缺失معلومة,有时则直接编造订单细节。 +2. 业务逻辑不可控 + 你希望“抱怨必须先道歉”,但模型未必每次都遵守;你希望“非业务问题要引导回主线”,但模型可能会兴致勃勃地和你聊起段子。 + +因此,更工程化的做法是将任务拆解为一条标准化流水线,先做意图分类(确定用户到底想干什么),然后再按意图分流(不同场景使用不同的نصيحة词与角色),最后对不同分流后大模型的回复统一封装输出(便于前端或系统集成)。 + +本节的目标是让系统能处理一个餐饮场景下的多类对话。你可以跟着操作做一遍加深印象。首先需要做的是定义场景为意图分类: + +- **下单购买 (buy_food)** :用户表达明确的购买意愿。 +- _例如:“给我来一份炸鸡,再加一杯可乐。”_ +- **抱怨投诉 (complain)** :用户在表达不满、催促或负面反馈。 +- _例如:“你们也太慢了吧?等一个小时了。”_ +- **闲聊咨询 (chitchat)** :用户在进行开放式询问、寻求建议,但无明确下单指令。 +- _例如:“今天吃什么好呢,你有什么推荐吗?”_ +- **其他意图 (other)** :用户的输入与餐饮场景无关。 +- _例如:“帮我写个搞笑文案发朋友圈。”_ + +针对这四种意图,我们为系统预设了四种不同的“沟通人格”,分别由四个独立的 LLM 节点承载,每个节点都需要由具有不同人设的 LLM 进行扮演。 + +- **下单助手 (LLM_BuyFood)** :专业、高效,核心任务是确认订单细节,并主动补全缺失معلومة。 +- **客服专家 (LLM_Complain)** :共情、稳重,首要任务是安抚用户情绪,并提供清晰的解决方案。 +- **聊天伙伴 (LLM_Chitchat)** :轻松、友好,旨在提供个性化推荐,引导潜在消费。 +- **礼貌门卫 (LLM_Other)** :专注、边界清晰,负责将偏离主题的对话礼貌地引导回核心业务。 + +#### 工作流编排设计 + +接下来我们进行工作流的编排设定,决定大概需要有哪些工作流节点。对于新手而言,很难想到需要有哪些节点能被用到(对于老手来说也懒得自己思考,用大模型给建议通常是最快最好的选择),所以我们能够使用大模型给出对应的编排建议,其核心节点结构如下: + +- Start (起点):作为数据入口,负责接收用户的原始输入 `user_text`。 +- Question Classifier (意图分类器):工作流的“大脑”与“调度中心”。它负责对 `user_text` 进行分析,并从我们预设的四种意图标签中选择最匹配的一个。 +- Condition (条件分支):扮演“分流阀”的角色。它根据分类器输出的意图标签,决定接下来将任务导向哪一个专处理路径。 +- 四个并行的 LLM 节点 (LLM_BuyFood, LLM_Complain, LLM_Chitchat, LLM_Other):这是四个独立的“专家处理单元”。每个节点都接收原始问题,但依据自身独特的 System Prompt(系统نصيحة词)生成风格和目标截然不同的回复。 +- Variable Aggregator (变量聚合器):在多条路径处理完成后,需要一个“汇集点”。此节点将四个分支中唯一被激活并产生النتيجة的回复,收束成一个统一的变量 `final_reply`,确保了输出结构的稳定性。 +- Output (终点):作为最终的出口,负责将意图标签、原始问题、以及经过处理生成的回复,以结构化的形式(如 JSON)统一输出,便于后续系统调用或调试分析。 + +#### 工作流编排实现 + +本次教程我们选择创建 Workflow 而不是 Chatflow,选择 User Input: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image59.png) + +随后点击 Start 的 User Input 节点,定义一个名为 `user_text` 的字符串类型变量,作为整个流程的输入源。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image60.png) + +保存后点击右上角的 Test Run,你能够看到需要指定对应的文本输入进行处理: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image61.png) + +随后我们需要点击输入节点后的 + 符号,选择 Question Classifier 节点添加,并且我们需为其配置四类标签,并为每个标签提供清晰的描述和مثال。 + +- `buy_food`: 用户明确想买吃的、点餐、下单。 +- `complain`: 用户在抱怨、吐槽、发脾气,通常带有不满情绪。 +- `chitchat`: 用户在闲聊、讨论吃什么、咨询推荐。 +- `other`: 与餐饮场景无关,或难以判断的内容。 + +此外,你还需要在 ADVANCED SETTING 中写入نصيحة词,让大模型能够正确根据用户输入进行分类测试。مثالنصيحة词如下: + +``` +从 buy_food / complain / chitchat / other 中选择一个最合适的标签。如果用户在抱怨的同时也点了餐,请优先判断其核心情绪,若重点在于表达不满,应归为 complain。如果只是轻微吐槽但主要意图是下单,则归为 buy_food。若实在难以判断,使用 other 作为兜底 +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image62.png) + +设定完成后,你可以在右上角的播放键单独测试该节点是否能够正常运行: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image63.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image64.png) + +从 OUTPUT 的النتيجة来看,我们的分类是准确的。你可以进行多种不同类型输入的测试,验证我们分类器的稳定性。 + +接下来,我们需要给分类器接上后续的大模型输出,例如,当 `label` 等于 `"buy_food"` 时,工作流便会精确地流向 `LLM_BuyFood` 节点。我们需要新建四个 LLM 节点,并设置不同的 System Prompt ;不同 System Prompt 的差异决定了它们不同的回应方式。 + +- LLM_BuyFood (点餐助手): + +你是一个点餐助手。要求:1. 确认用户想点的内容。2. 如果معلومة不完整,友好地补充询问。3. 语气礼貌简洁。 + +- LLM_Complain (客服专家): + +你是一个餐饮客服,专门处理抱怨。要求:1. 真诚道歉。2. 简要说明可能的原因(不推卸责任)。3. 给出清晰的الخطوة التالية解决方案。 + +- LLM_Chitchat (聊天伙伴): + +你是一个帮人选吃的的聊天小助手。要求:1. 用轻松友好的语气。2. 给出 1~3 个简单推荐。3. 如果用户没有偏好,就给出不同风格的选择。 + +- LLM_Other (礼貌门卫): + +你是一个餐饮点餐小助手,只擅长跟‘吃’相关的话题。当用户说的话无关时:1. 礼貌说明自己的能力范围。2. 引导用户回到主场景。 + +值得ملاحظة的是,每个节点里面在填充了 SYSTEM 的نصيحة词参数后,你还要记得启用 USER نصيحة词参数表。你需要在其中需要点击 `{x}` 符号,选择 `user_text` 参数作为用户输入,并且在前面加上 `user input:` 标识这个变量是用户输入的意思,在问答的时候会综合用户的最开始的输入和内置نصيحة词进行回复。 + +同样的,为了确保一切顺利,你可以点击该节点右上角的播放箭进行具体的对话测试验证效果,比如对话说“我想要喝珍珠奶茶”等,查看回复是否符合预期。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image65.png) + +接下来我们处理并行 LLM 的输出值,我们在 `Variable Aggregator` 节点的配置面板中,找到 `ASSIGN VARIABLES`(分配变量)区域,点击后依次将之前的大模型回复加入即可。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image66.png) + +接下来我们需要对所有的输出进行聚合,最后得到我们想要的النتيجة,包含用户的输入、分类、以及回复。由于我们使用的是 Workflow 而不是 Chatflow,故没有 Answer 节点选择进行النتيجة的聚合,我们能够选择其他节点变相实现النتيجة的聚合与输出,此时选择 Template 节点,在变量部分指定用户意图分类النتيجة、用户的输入值、变量聚合的最终回复,并且在 CODE 中写入最后回复的 json 格式模板,我们可以得到: + +- `intent` ← `class_name` +- `original_text` ← `user_text` +- `final_reply` ← `variable_aggregator` + +``` +{ + "intent": "{{ intent }}", + "original_text": "{{ original_text }}", + "reply": {{ final_reply }} +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image67.png) + +最后加入 output 节点即完成所有操作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image68.png) + +#### 工作流运行测试 + +大功告成,我们可以尝试运行这套工作流的效果。它能根据不同的输入,展现出截然不同的行为模式: + +- 输入 (点餐): "给我来一份香辣鸡腿堡套餐,大杯可乐。" + - 路径: `buy_food` → `LLM_BuyFood` + - 输出 reply: "好的,一份香辣鸡腿堡套餐和大杯可乐已为您记录。请问套餐里的薯条需要更换吗?" +- 输入 (抱怨): "你们也太慢了吧?我都等一个多小时了!" + - 路径: `complain` → `LLM_Complain` + - 输出 reply: "非常抱歉让您等了这么久,这确实是我们的疏忽,给您带来了很不好的体验。我们正在紧急核实您的订单配送情况,并会为您申请相应的补偿,感谢您的耐心与反馈。" +- 输入 (闲聊): "今天吃什么比较健康?" + - 路径: `chitchat` → `LLM_Complain` + - 输出 reply: "追求健康的话,可以试试我们的轻食沙拉系列,或者烤鸡胸肉配时蔬。您是喜欢口味清淡一些还是稍微丰富一点的呢?我可以给您更具体的推荐。" +- 输入 (无关内容): "帮我想个明天开会的笑话。" + - 路径: `other` → `LLM_Other` + - 输出 reply: "这听起来是个有趣的挑战!不过我主要是个美食推荐和点餐助手。如果您需要点些什么来犒劳一下辛苦工作的自己,我随时可以帮忙!" + +> 隐藏 Bug :需要说明的是,若你遇到与 aggregation group 相关的奇怪问题,这大概率是 Dify 的一个内置 bug。可能在特定操作下被触发;如果你曾经开启又关闭过 AGGREGATION GROUP,系统可能生成过 group 配置且残留了相关异常参数,即便现在开关看起来是关闭的,这些残留配置也可能导致问题,比如出现 `any` 相关参数的报错。此时你只需要删除该节点并重新创建即可。 + +在 Test Run 中运行后,我们能够看到工作流的执行过程,此时根据分类走了正确的流程,并得到了最后的 output النتيجة。至此,全流程完成。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image69.png) + +## 2.7 运行第一个模板 Workflow 应用 + +结束了简单的分类工作流学习,接下来我们需要学习如何运行别人的 workflow,我们只需要稍作改造就可以将其变成自己的工作流。在这里我们选择尝试官方的 DeepResearch 工作流,该工作流能够帮你构建一个深度搜索框架,使用大模型+搜索引擎给你一个丰富的搜索答案,每一次提问的النتيجة将会包含搜索引用地址和大模型对话的النتيجة。 + +导入后الخطوة الأولى直接运行,我们根据每一步报错的地方和原因解决具体问题即可,如果遇到解决不了的问题,你可以截图后询问大模型进行解决。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image70.png) + +刚进入感觉十分复杂,没关系,我们点击右上角的 Preview 运行工作流,直到报错出现: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image71.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image72.png) + +我们需要根据报错的节点解决问题,打开后发现是没有配置 Tavily 的 API Token,Tavily 的搜索API 是一个专为 AI 设计的搜索引擎,提供实时、准确和事实性的النتيجة。此时根据نصيحة操作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image73.png) + +经过处理后,搜索引擎能够正常工作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image74.png) + +继续修正模型调用导致的问题后,你应该能够得到如下النتيجة,结合大模型理解下的详细搜索: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image75.png) + +我们在最后能够看到对应的参考文档地址: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image76.png) + +如果你想理解每个环节的作用,最好的方法是将每个环节的 output 记录为一个变量,最后在输出的时候打印每个中间变量的النتيجة,还有一个方法就是你可以在上方找到 Process 的过程,点击后可以查看每个环节的细节: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image77.png) + +## 2.8 将 Dify 作为 API 提供方 + +接下来,我们会尝试通过 API 调用刚才创建的知识库智能体 Agent,我们想要让 Dify 变成一个大模型中枢后端。 + +还记得之前讲过如何通过 API 调用模型吗?我们需要准备一个密钥(Key)和一份 API 调用مثال(文档中的 request/response مثال),然后把这些内容发给大模型,让它帮我们写出调用服务的代码,并从返回النتيجة中解析出我们需要的字段。 + +这一次,我们会使用本地的代码编辑工具 [Trae](https://www.trae.cn/) 来完成这个过程。 + +如果你还不熟悉什么是 IDE,可以先阅读文档 [Extra Knowledge 4 - What is AI IDE and Trae](https://github.com/datawhalechina/easy-vibe/blob/main/docs/extra/extra4/extra4-what-is-ai-ide-and-trae.md)。 + +如果你的本地开发环境还没有完整配置好,也不用担心。只要你信任自己的代码助手(不管是 [z.ai](http://z.ai) 还是 Trae),遇到任何不懂的地方或报错,都可以直接把问题抛给它,它会根据你的描述给出详细的解决方案。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image78.png) + +右侧的区域叫做 Copilot 交互窗口,或者 Agent 窗口。如果你看不到它,可以点击右上角的侧边栏图标来打开。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image79.png) + +打开侧边栏后,你会看到 `Builder` 选项。这就是 Agent 模式。你可以简单地把 “Builder” 理解为 [z.ai](http://z.ai) 的“开发模式”,它同样可以帮你操作本地电脑环境、安装依赖、打开网页等。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image80.png) + +点击 “Builder” 后,你会看到 “Chat” 模式和 “Builder with MCP” 模式。 Chat 模式主要用于与当前文件夹进行交互,或者和大模型进行自然语言对话。(你可以通过点击 Trae 左上角的 “File” 打开一个文件夹,然后在该文件夹内进行编辑。这种情况下,Builder 所有的新建文件操作都会发生在这个文件夹中。) + +Builder with MCP 模式则为 Agent 提供了更多工具(例如让大模型连接到其他软件、获取天气معلومة等)。你可以简单地认为 MCP 是一个让大模型更方便调用各种外部工具的能力集合。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image81.png) + +在下方区域,你还可以看到模型选择的下拉列表,可以点击切换不同模型。这里你可以选择 Kimi k2 或 GLM。如果你使用的是国际版 Trae,也可以选择 ChatGPT 或 Claude。 不过,随着国内大模型的快速发展,Kimi、Qwen、GLM 等模型的综合能力已经基本接近 Claude 3.5 或 3.7,对于日常开发场景来说完全够用。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image82.png) + +上面是对 Trae 的一个简要介绍。接下来,我们可以回顾在 [z.ai](http://z.ai) 中的操作خطوة,并在 Trae 中复用这些思路。 + +## 2.9 利用 Dify API 创建前端对话应用 + +如果我们想用 Dify 的 API 搭建一个前端聊天应用,首先需要获取 Dify 的 API 文档和调用地址。 + +还记得刚才创建的那个 Agent 吗? 先点击右上角的 “Publish”,然后点击 “Publish Update”,最后点击 “Access API Reference” 进入 API 文档。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image83.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image84.png) + +进入 API 文档后,找到 “Send Chat Message” 这一部分,点击进入,然后在右侧找到 “Request” 和 “Response” مثال并复制出来。 + +为什么一定要复制这两部分内容? 因为它们是 API 的“核心معلومة”: 有了 Key、请求مثال和返回مثال,我们就可以让大模型帮我们生成调用服务的代码,并且根据返回结构把需要的字段提取出来。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image85.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image86.png) + +在找到会话所需的 Request 和 Response مثال之后,我们还需要获取一个 API Key。在文档右上角,你会看到 “API key” 相关选项。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image87.png) + +点击 “Create new Secret key”,就可以创建属于你自己的 API Key。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image88.png) + +现在一切准备就绪。我们会把刚才拿到的 API Key、Request مثال和 Response مثال一起交给 Trae Builder。 + +ملاحظة:请将 `{DIFY_API_URL}` 替换为实际的 Dify API 地址。 + +```json +key: +app-zKdCHUXXXXXXXX + +Please write me a front-end based on the following reference: + +curl -X POST 'http://{DIFY_API_URL}/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image89.png) + +在这个阶段,你可能会发现生成出来的程序并不能一次性正常运行——比如对话会出现奇怪的错误,或者没有任何返回النتيجة。当出现这种情况时,你可以尝试切换到另一个大语言模型,或者把错误معلومة复制出来,详细描述问题,再发给模型让它根据反馈继续迭代。 + +此时你的工作方式已经非常接近真实开发过程了。在日常开发中,我们经常会在与大模型协作时遇到各种问题,为了更好地解决这些问题,我们需要提供更多上下文معلومة。除了提供错误معلومة,你还可以复制更完整的文档内容(例如在文档左侧 “Send message” 部分中复制更多说明),一并交给模型,让它在更多细节的基础上给出更完整的解决方案。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image90.png) + +此时浏览器是嵌在 Trae 内部的。你可以点击顶部的指南针图标,把网页在外部浏览器中全屏打开。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image91.png) + +如果运气不错,你可能在第一次尝试时就能获得一个可以正常交互的前端页面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image92.png) + +不过,由于大模型本身具有一定随机性,有时你可能在单轮对话中一切顺利,但在多轮对话时出现异常。因此,建议你进行多轮对话测试,确保程序在多轮交互场景下也能稳定运行。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image93.png) + +到这里,你已经学会了如何构建一个简单的 Dify 知识库 Agent,并使用 Trae 替代 [z.ai](http://z.ai) 来搭建一个交互式前端。从现在开始,Trae 将成为我们构建各种原型时的主要开发工具,逐步取代 [z.ai](http://z.ai)。你可以尝试用 Trae 重新实现之前的贪吃蛇游戏,看看会有什么不同的体验。加油! + +# 3. 更多业务工作流参考 + +你可以在搜索引擎上使用类似关键词搜索 `Dify workflow 参考`,或者直接在 Github 中找到 Dify 工作流分享仓库进行参考工作流的查找(质量参差不齐,你需要查看多个不同仓库学习)。当然,所谓的工作流只不过是业务上 SOP 的映射,你可以思考有哪些日常工作中的流程或者学习中的流程是重复可固化的,只需要把它变成工作流固定即可。 + +以下是一些大模型生成的工作流设计的参考(实际上的实现方案也比较类似,一般来说人类设计的工作流不会有大模型设计的优美,除非是高手设置的工作流),如果你觉得哪些点子有意思,可以将它发给大模型进一步细化,让大模型帮你给出更具体的 Dify 工作流节点设定,以及内部的细节النتيجة。 + +## 3.1 社媒平台工作流 + +1. 跨平台内容一键分发工作流(复杂) + 1. 思路:以一篇核心稿件为“原料”,自动加工成适配多个平台的“成品”。 + 2. 实现:`Start` 输入文章 -> `LLM` 润色 -> 并行多个 `LLM` 节点(每个节点Prompt扮演特定平台专家,如“小红书爆款文案专家”、“知乎专业答主”)-> `Iterator` 节点循环处理不同平台格式要求 -> `Variable Aggregator` 汇总 -> `Answer` 输出所有版本。复杂度在于并行处理和循环迭代。 +2. 热点话题选题与初稿生成器(中等) + 1. 思路:自动捕捉网络热点,快速生成选题和内容草稿。 + 2. 实现:`Start` 输入关键词 -> `Tool` 节点调用搜索引擎API抓取热点 -> `LLM` 摘要提炼出3-5个话题 -> `LLM` 生成文章大纲或初稿。复杂度在于外部工具集成与معلومة筛选。 +3. 评论区智能分类与回复助手(复杂) + 1. 思路:自动分析评论情感与意图,生成分类回复建议。 + 2. 实现:`HTTP Request` 节点接入社媒API获取评论 -> `Question Classifier` 或 `LLM` 节点进行多标签分类(积极、疑问、投诉、广告等)-> `Condition` 判断节点路由至不同回复生成链 -> 并行 `LLM` 节点生成个性化回复草稿 -> `Answer` 输出。复杂度在于条件分支和实时API调用。 +4. 短视频脚本与分镜自动生成器(复杂) + 1. 思路:根据一个热门话题或产品描述,自动生成短视频脚本、分镜描述和推荐标签。 + 2. 实现:`Start` 输入主题 -> `LLM` 生成创意脚本 -> 第二个 `LLM` 节点将脚本拆解为场景序列(画面描述、台词、时长)-> `Tool` 节点调用文本转语音服务生成语音样本 -> `Variable Aggregator` 整合所有元素 -> `Answer` 输出结构化脚本文件。复杂度在于多خطوة序列化和外部服务集成。 +5. 直播互动问答实时摘要助手(中等) + 1. 思路:实时处理直播间的文字评论,提炼السؤال الجوهري和观众反馈。 + 2. 实现:`HTTP Request` 节点流式获取直播评论 -> `Iterator` 节点以时间窗口为单位处理批数据 -> `LLM` 节点实时الخلاصة每段时间内的热点问题与情绪倾向 -> `Answer` 或 `Webhook` 节点输出摘要给主播。复杂度在于实时流数据处理和循环窗口。 + +## 3.2 职场工作流 + +1. 智能会议纪要与任务自动派发系统(复杂) + 1. 思路:从会议录音文本中提取纪要,并自动创建任务。 + 2. 实现:`Start` 输入会议文本 -> `LLM` الخلاصة议题与结论 -> `Parameter Extractor` 节点精准抽取Action Items(任务、负责人、DDL)-> 一个 `LLM` 整合成纪要邮件 -> 并行 `HTTP Request` 节点调用Jira/Trello/飞书API创建任务。复杂度在于معلومة抽取与多系统联动。 +2. 简历批量筛选与初步评估助手(中等) + 1. 思路:自动解析简历,进行匹配度评估并生成面试问题。 + 2. 实现:`Start` 上传简历文件与JD -> `Document Extractor` 节点解析简历文本 -> `LLM` 扮演HR进行匹配度评估 -> 对高匹配者,另一个 `LLM` 生成深度面试问题。复杂度在于文档解析与多条件评估。 +3. 多语言邮件一键翻译与草稿回复(简单) + 1. 思路:自动翻译邮件并起草回复。 + 2. 实现:`Start` 输入邮件 -> `LLM` 判断语种并翻译 -> `LLM` 构思回复要点 -> `LLM` 翻译回原始语言并润色。主要依赖于LLM的序列调用。 +4. 周报/月报数据自动汇总与洞察生成(复杂) + 1. 思路:连接多个数据源,自动生成结构化工作报告。 + 2. 实现:多个 `HTTP Request`/`Tool` 节点并行调用业务系统API(如CRM、Git、项目管理工具)获取原始数据 -> `Code` 节点或 `LLM` 进行数据清洗与基础计算 -> `LLM` 分析趋势、亮点与风险,生成叙述性报告 -> `Answer` 输出图文并茂的文档。复杂度在于多数据源聚合、数据处理与智能分析结合。 +5. 合同/文档智能审查与要点提炼(中等) + 1. 思路:快速审查法律或商务文档,نصيحة风险并提炼核心条款。 + 2. 实现:`Start` 上传合同PDF -> `Document Extractor` 提取文本 -> `LLM` 节点(设定为法律专家角色)审查责任条款、支付条件、违约条款等 -> `Parameter Extractor` 节点抽取出关键日期、金额、义务方等结构化数据 -> `Answer` 输出风险نصيحة和要点表格。复杂度在于长文档处理与结构化معلومة抽取。 + +## 3.3 学习生活工作流 + +1. 学术论文深度解析与笔记生成器(复杂) + 1. 思路:上传论文PDF,自动生成结构化笔记。 + 2. 实现:`Start` 上传PDF -> `Document Extractor` 提取全文 -> 并行多个 `LLM` 节点分工الخلاصة摘要、方法、发现、参考文献 -> `Variable Aggregator` 汇总 -> `Answer` 输出Markdown笔记。复杂度在于并行处理长文本的不同部分。 + +2. 个性化旅行计划定制师(中等) + 1. 思路:根据用户偏好,自动规划详尽行程。 + 2. 实现:`Start` 输入需求(目的地、天数、预算、兴趣)-> `Tool` 节点调用搜索引擎或地图API获取地点معلومة -> `LLM` 整合معلومة,设计每日行程(含时间、活动、预算估算)。复杂度在于外部معلومة获取与结构化规划。 + +3. 外语学习互动陪练伙伴(简单) + 1. 思路:创建可角色扮演和语法纠错的对话机器人。 + 2. 实现:系统设定AI角色 -> `Start` 接收用户语句 -> `LLM` 执行两项任务:角色回复 + 语法纠错与解释 -> `Answer` 输出。核心是LLM的多任务指令。 + +4. 个人知识库问答与链接推荐系统(复杂) + 1. 思路:基于你收藏的文档、笔记、网页链接,构建一个可问答并能推荐相关旧知识的智能系统。 + 2. 实现:离线处理:使用 `Document Extractor` 和 `Embedding` 工具将个人知识库切片并向量化存储。在线工作流:`Start` 输入问题 -> `Retrieval` 节点从向量库中查找最相关的知识片段 -> `LLM` 基于检索到的上下文生成答案 -> 同时,另一个分支使用检索到的内容作为输入,通过 `LLM` 生成“相关旧知识”推荐列表 -> `Answer` 合并输出答案与推荐。复杂度在于检索增强生成(RAG)流程的构建。 + +5. 健身/饮食计划追踪与调整顾问(中等) + 1. 思路:根据用户输入的每日饮食和训练日志,提供营养分析与训练建议。 + 2. 实现:`Start` 输入文本日志(如“午餐:鸡胸肉150g,米饭一碗,蔬菜若干;训练:深蹲5组”)-> `Parameter Extractor` 节点尝试结构化输入数据 -> `LLM` 扮演健身教练,分析营养摄入是否均衡、训练容量是否合适 -> 对比长期目标,给出微调建议(如“蛋白质摄入充足,建议增加蔬菜种类”)。复杂度在于从非结构化日志中提取结构化معلومة并提供个性化反馈。 + +# 6. 工作流平台的局限性 + +工作流平台(或称低代码平台)并非万能解决方案。它虽然对业务人员友好,降低了直接编码的门槛,但从另一个角度看,“低代码”往往也是一种“高代码”——用户仍需理解平台的概念、规则与操作逻辑,这本身构成了一种新的学习成本。 + +也许你想问,很多简单的工作流其实就是大模型函数包装后的前后调用,前面函数的输出作为后者函数的输入,本质上几行代码就能够解决,为什么需要那么复杂的多重包装工作流?反而给 API 调用造成了麻烦。 + +你说得是对的。在当前 vibe coding 的快速发展下,借助 AI 代码生成能力,直接阅读甚至生成代码有时可能更加高效。理想情况下,我们希望能用自然语言直接操作应用逻辑,这才是一个现代的软件平台。但目前的工作流平台尚未实现这一点,因此它在用户意图与最终实现之间天然存在一个“中间层”。掌握这个中间层,正是一种需要投入时间学习的成本。理想上,之后的工作流平台也要支持全 AI 自动对话操作,我们可以让 AI 真正操作工作流搭建以及入参的每一个细节环节。 + +尽管如此,熟练使用这类平台正逐渐成为一项基础技能,如同微软的办公软件一样,在业务中非常普遍且实用,值得掌握。 + +在后续的进阶课程中,我们将介绍如何通过代码级别的工作流与 RAG 开发平台进行构建。届时,你可以亲身体验不同实现方式在复杂度与灵活性上的区别。(值得ملاحظة的是,一些简单的对话应用或嵌套逻辑,用工作流实现可能并不困难。) + +# 📚 الواجب المنزلي + +## 掌握 Dify 基本操作 + +为了测试你掌握了 Dify 的常见基础使用工具,你需要完成一个基础作业和两个 “小挑战”,确保你已入门常见的操作。你需要将附带的两个 DSL 文件导入 Dify 工作流,并成功完成对应工作流的挑战(遇到不懂的地方截图询问大模型,或自己探索其中的每个参数的用法,最后实现目标)。: + +1. 参考意图分类工作流的方法,让大模型给你建议完全换一套场景进行应用,但是一定要用到意图分类工作流,最后提交运行的工作流截图、场景说明、النتيجة。 +2. Log in workflow 工作流解密挑战 + +在这个解密挑战中,你需要完成以下挑战,让工作流实现下列功能: + +- 找出正确的密码! +- 将密码修改为 0925 +- 当密码不正确时,提供第二次尝试机会(不提供第三次) +- 当用户提及要再次登录时,为用户提供重新输入密码的机会 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image94.png) + +参考输入输出: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image95.png) + +3. Love loop workflow 工作流解密挑战 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image96.png) + +在这个解密挑战中,你需要修复当前工作流的问题,让工作流最后的输出类似如下显示: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image97.png) + +如果你遇到无法解决的问题,请截图询问大模型,或查阅官方文档得到النتيجة:[https://docs.dify.ai/en/use-dify/getting-started/quick-start](https://docs.dify.ai/en/use-dify/getting-started/quick-start) + +## 实现 Dify API 调用 + +为了测试你真正掌握了 Dify 的 API 调用知识,你需要完成以下任务: + +1. 部署 Dify 并创建一个简单的知识库(选取你喜欢的资料)。 +2. 使用 Trae IDE 构建一个对话前端,与 Dify 知识库进行 API 交互。 +3. 测试多轮对话的效果,确保程序正常运行。 + +你需要提交最终运行截图和知识库的处理过程截图。 + +## 试用第三方工作流 / 构建一个自己的业务工作流 + +请你在 Github、微信公众号、或者 Reddit、推特上等所有地方找到你想尝试的别人的 Dify 工作流,下载导入后成功运行;或者你可以根据上文中提到的业务工作流参考,根据现实中的具体需求创建一个自己的业务工作流进行运行。 + +最后你需要提交运行成功的截图,并说明这个工作流的作用。 + +# [Bug] HTTP 请求错误问题的解决方法 + +如果你遇到了如下图所示的问题,才需要参考本节方案进行解决,否则可以不理会当前部分。 + +有时候可能你会把 Dify 部署在自己的服务器,但是服务器的对外地址通常都是 http 而不是 https 的,但当我们请求一个只支持 HTTP 的服务时,你可能会看到类似这样的نصيحة(启用 F12 浏览器调试معلومة模式,查看有问题的点): + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image98.png) + +出现这个问题的原因,是因为我们默认把 Dify 部署在一台只支持 HTTP 而不支持 HTTPS 的服务器上。 HTTPS(HyperText Transfer Protocol Secure)是在 HTTP(超文本传输协议)的基础上增加了 SSL/TLS 加密层,可以简单理解为“更安全版的 HTTP”。 + +如果要让服务支持 HTTPS,一般可以: + +- 使用其他程序转发请求(例如在有证书的 nginx 上做反向代理),或者 +- 绑定域名后为该域名申请证书。 + +但这些操作都比较复杂,在这里我们使用 Zeabur 作为网络转发网关来解决问题。 + +Zeabur 的网页默认是通过 HTTPS 访问的,因此我们只需要把原来请求的域名转发到 Zeabur 提供的域名,就可以修复这个问题。 + +- 原始地址:`http://{DIFY_API_URL}/v1/chat-messages` +- 现在地址:`https://{DIFY_NEW_API_URL}.zeabur.app/v1/chat-messages` + +你只需要简单地把 URL 中的域名部分(公网 IP 或域名)替换为已经在 Zeabur 上部署好的域名即可,我们已经提前在服务里配置好了转发功能。 + +如果你感兴趣,也可以自己在 Zeabur 上部署一个转发服务。在 Zeabur 中创建服务时,选择 Python,然后填入下面的 Python 代码,部署后即可得到一个 https 的地址,https 即可正常使用。 + +部署完成后,在网络设置中把程序监听端口设置为本地 8080,并对外暴露该端口。 + +ملاحظة:请将 `{DIFY_API_URL}` 替换为实际的 Dify API 地址。 + +```python +from flask import Flask, request, Response +import requests + +app = Flask(__name__) + +TARGET_BASE_URL = "{DIFY_API_URL}" +LISTEN_PORT = 8080 + +@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +@app.route('/', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +def proxy_request(path): + target_url = f"{TARGET_BASE_URL}/{path}" + if request.query_string: + target_url += f"?{request.query_string.decode('utf-8')}" + + headers = {key: value for key, value in request.headers if key.lower() not in ['host', 'connection', 'content-length', 'accept-encoding']} + + try: + resp = requests.request( + method=request.method, + url=target_url, + headers=headers, + data=request.get_data(), + cookies=request.cookies, + allow_redirects=False, + timeout=30 + ) + + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + response_headers = [(name, value) for name, value in resp.raw.headers.items() if name.lower() not in excluded_headers] + + return Response(resp.content, resp.status_code, response_headers) + + except requests.exceptions.RequestException as e: + print(f"Error forwarding request to {target_url}: {e}") + return Response(f"Proxy Error: Could not reach target server or invalid response: {e}", status=502) + except Exception as e: + print(f"An unexpected error occurred: {e}") + return Response(f"Internal Proxy Error: {e}", status=500) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=LISTEN_PORT, debug=True) +``` diff --git a/docs/ar-sa/stage-2/assignments/copywriting-platform-supabase/index.md b/docs/ar-sa/stage-2/assignments/copywriting-platform-supabase/index.md new file mode 100644 index 0000000..69e477a --- /dev/null +++ b/docs/ar-sa/stage-2/assignments/copywriting-platform-supabase/index.md @@ -0,0 +1,346 @@ +# تطوير SaaS لتوليد نصوص تسويقية بالذكاء الاصطناعي — تطبيق عملي + +## نظرة عامة + +يتطلب هذا المشروع **التطبيقي** منك العمل وفق مستند متطلبات منتج (PRD) حقيقي، لبناء منتج SaaS لتوليد نصوص تسويقية بالذكاء الاصطناعي من الصفر وموجه للمطورين المستقلين وفرق المحتوى. ستستخدم Supabase كخدمة خلفية، و Stripe كنظام دفع، لإكمال العملية الكاملة من تحليل المتطلبات إلى النشر والتفعيل. + +هذا هو المشروع **التطبيقي** الشامل في المرحلة الثانية. في الفصول السابقة، تعلمت كل مهارة على حدة — تصميم الصفحات الأمامية، تطوير واجهات الخلفية، عمليات قواعد البيانات، دمج أنظمة الدفع — هذا المشروع يتطلب منك ربطها جميعًا معًا وتسليم نموذج أولي لمنتج قابل للتشغيل. + +## المعارف المسبقة + +قبل البدء في هذا المشروع، يجب أن تكون قد أتقنت المحتوى التالي: + +- تصميم واجهات المستخدم واستخدام مكتبات المكونات ([تصميم واجهة المستخدم](../../frontend/ui-design/)، [مكتبة المكونات الحديثة](../../frontend/modern-component-library/)) +- تصميم وتطوير واجهات الخلفية ([كتابة كود الواجهات](../../backend/ai-interface-code/)) +- أساسيات قواعد البيانات و Supabase ([من قاعدة البيانات إلى Supabase](../../backend/database-supabase/)) +- دمج أنظمة الدفع ([نظام الدفع Stripe](../../backend/stripe-payment/)) +- سير عمل Git والنشر ([سير عمل Git و GitHub](../../backend/git-workflow/)، [نشر تطبيقات الويب](../../backend/zeabur-deployment/)) + +## أهداف التعلم + +بعد إكمال هذا المشروع **التطبيقي**، ستتمكن من: + +1. قراءة وفهم مستند PRD حقيقي واستخراج قائمة مهام التطوير منه +2. استخدام الذكاء الاصطناعي لتوليد الصفحات الأمامية وواجهات الخلفية خطوة بخطوة +3. استخدام Supabase لتحقيق مصادقة المستخدمين وعمليات قاعدة البيانات +4. دمج Stripe لتحقيق وظيفة الاشتراك المدفوع +5. بناء لوحة إدارة خلفية وإكمال التكامل الشامل من البداية إلى النهاية + +## مقدمة المشروع + +المنتج الذي ستقوم ببنائه هو SaaS لتوليد نصوص تسويقية بالذكاء الاصطناعي، يتضمن ثلاثة أنظمة فرعية: + +| النظام الفرعي | المسؤولية | +|--------|------| +| **موقع الشركة** | تقديم المنتج، التسعير، الأسئلة الشائعة، تحويل التسجيل | +| **محطة عمل المستخدم** | إدخال **معلومات** المنتج، توليد النصوص، عرض السجل، ترقية الباقة | +| **لوحة الإدارة** | إدارة المستخدمين، سجلات التوليد، بيانات الدفع، نظرة عامة على العمليات | + +تستخدم الخلفية Supabase لتوفير قاعدة البيانات والمصادقة، و Stripe لمعالجة المدفوعات، ونموذج ذكاء اصطناعي لتوليد النصوص التسويقية. + +::: tip رابط مستند PRD +مستند متطلبات هذا المشروع على GitHub: [عرض PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/copywriting-platform-supabase/PRD.md) +::: + +
+ + + +
+ +## الجزء الأول: تحليل المتطلبات + +### 1.1 قراءة PRD + +افتح مستند PRD، وركّز على الإجابة عن الأسئلة التالية: + +- كم نقطة دخول في النظام؟ وما هي الصفحات التي يغطيها كل منها؟ +- ما هي الوظيفة الأساسية لكل صفحة؟ +- ما هي الوحدات والجداول في قاعدة البيانات الموجودة في الخلفية؟ +- كيف تم تصميم تسعير الباقات وعملية الدفع والحصة المجانية؟ +- ما هو نطاق MVP؟ ما الذي سيتم تنفيذه في الإصدار الأول وما الذي لن يتم؟ + +::: warning +إذا لم تكن لديك إجابات واضحة على الأسئلة أعلاه، لا تبدأ بكتابة الكود. عدم وضوح المتطلبات هو السبب الأكثر شيوعًا لإعادة العمل. +::: + +### 1.2 تأكيد بنية النظام + +استنادًا إلى PRD، استخلص البنية العامة للنظام: + +```mermaid +flowchart TD + prd["PRD"] --> web["موقع الشركة"] + prd --> app["محطة عمل المستخدم"] + prd --> admin["لوحة الإدارة"] + app --> auth["المصادقة"] + app --> gen["مهمة توليد النصوص"] + gen --> db["قاعدة البيانات"] + billing["الدفع والباقات"] --> db + admin --> analytics["لوحة المستخدمين / التوليد / الدفع"] +``` + +## الجزء الثاني: بناء هيكل المشروع + +### 2.1 توليد الصفحات الأمامية + +استخدم الذكاء الاصطناعي لتوليد الهيكل الأساسي وجميع الصفحات مع بيانات وهمية أولاً. + +مرجع **للنصيحة** (Prompt): + +```text +ساعدني بناءً على PRD الحالي في توليد هيكل أمامي لـ SaaS لتوليد نصوص تسويقية بالذكاء الاصطناعي. + +المتطلبات: +1. ثلاثة مداخل: www و app و admin +2. موقع الشركة يشمل: الصفحة الرئيسية، التسعير، الأسئلة الشائعة +3. app يشمل: تسجيل الدخول، التسجيل، محطة العمل، السجل، صفحة الباقات +4. admin يشمل: الصفحة الرئيسية للإدارة، إدارة المستخدمين، سجلات التوليد، طلبات الدفع +5. توليد فقط هيكل الصفحات وبيانات وهمية بدون ربط واجهات حقيقية +6. نمط SaaS حديث وليس عرضًا تجريبيًا صف دراسي +``` + +### 2.2 تحسين الصفحات الأساسية + +بعد بناء الهيكل، ركّز على تحسين صفحة محطة عمل توليد النصوص (Dashboard): + +```text +ساعدني في تحسين صفحة /dashboard. + +هذه محطة عمل لتوليد نصوص تسويقية بالذكاء الاصطناعي. + +حقول النموذج على اليسار: +- اسم المنتج +- مقدمة بجملة واحدة +- المستخدم المستهدف +- 3 نقاط بيع +- قنوات التوزيع (الموقع، WeChat Moments، Xiaohongshu، Douyin، البريد الإلكتروني) + +منطقة **النتائج** على اليمين محجوزة لـ: +- العنوان الرئيسي +- العنوان الفرعي +- CTA +- 3 نسخ نصية قصيرة +- نص طويل + +استخدم بيانات وهمية أولاً لتشغيل التفاعل. + +المتطلبات: +- حالة تحميل بعد النقر على "توليد النصوص" +- تصميم حالة فارغة لمنطقة **النتائج** +- تخطيط متجاوب يعمل بشكل جيد على الشاشات العريضة والضيقة +``` + +### 2.3 التحقق من بنية الصفحات + +تحقق من كل عنصر: + +- [ ] هل مسارات المداخل الثلاثة مستقلة +- [ ] هل عدد الصفحات يتوافق مع PRD +- [ ] هل تخطيط النموذج ومنطقة **النتائج** في Dashboard معقول +- [ ] هل البيانات الوهمية تعرض حالات واجهة مستخدم أساسية + +### هل واجهتك عقبات؟ + +إذا واجهتك صعوبة في مرحلة بناء الواجهة الأمامية، يمكنك مراجعة هذه الفصول: + +- [تصميم واجهة المستخدم](../../frontend/ui-design/) +- [تصميم الصفحات والأزرار وفقًا لإرشادات تصميم واجهة المستخدم](../../frontend/multi-product-ui/) +- [اجعل واجهتك جميلة باستخدام LLM و Skills](../../frontend/llm-skills-beautiful/) +- [من النموذج الأولي للتصميم إلى كود المشروع](../../frontend/design-to-code/) +- [تحديث واجهتك باستخدام مكتبة مكونات حديثة](../../frontend/modern-component-library/) + +## الجزء الثالث: دمج الخلفية + +### 3.1 ربط تسجيل الدخول عبر Supabase + +```text +اعتبرني مبتدئًا تمامًا وساعدني خطوة بخطوة في ربط تسجيل الدخول عبر Supabase. + +أحتاج منك مساعدتي في: +1. ربط المشروع بـ Supabase +2. تنفيذ وظائف التسجيل وتسجيل الدخول وتسجيل الخروج +3. الانتقال إلى /dashboard بعد تسجيل الدخول بنجاح +4. إعادة توجيه المستخدمين غير المسجلين تلقائيًا إلى /login عند محاولة الوصول إلى /dashboard أو /billing أو /admin +5. إنشاء جدول profiles +6. إنشاء سجل تلقائيًا في جدول profiles بعد تسجيل المستخدم بنجاح +7. يجب أن يحتوي جدول profiles على حقول email و role و plan + +متطلبات التنفيذ: +- اذكر في كل خطوة الملفات التي يتم تعديلها +- لا تقم بتشفير المفاتيح بشكل ثابت +- حدد بوضوح الأماكن التي تتطلب عمليات يدوية في لوحة تحكم Supabase +- بعد الانتهاء اشرح كيفية التحقق من التسجيل وتسجيل الدخول +``` + +### 3.2 ربط واجهة التوليد وقاعدة البيانات + +```text +اعتبرني مبتدئًا تمامًا وساعدني في إكمال الوظيفة الأساسية للموقع: توليد نصوص تسويقية وحفظها. + +التأثير المطلوب: +1. يملأ المستخدم النموذج في /dashboard وينقر على "توليد النصوص" +2. تستلم الخلفية: اسم المنتج والمقدمة والمستخدم المستهدف ونقاط البيع وقنوات التوزيع +3. تستدعي الخلفية النموذج لتوليد **النتائج** +4. تعرض الصفحة **النتائج** المُولَّدة +5. تُحفظ المدخلات والمخرجات في قاعدة البيانات +6. يمكن للمستخدم عرض السجل عند العودة مرة أخرى + +أحتاج منك إكمال: +- إنشاء واجهة توليد /api/generate +- إنشاء جدول generations +- تصميم حقول المدخلات والمخرجات +- قراءة سجل المستخدم الحالي في صفحة Dashboard + +تجربة المستخدم: +- حالة تحميل للزر +- رسالة خطأ عند فشل التوليد +- حالة فارغة عند عدم وجود سجل + +بعد الانتهاء اذكر: +- موقع ملفات الصفحات الأمامية +- موقع ملفات واجهات الخلفية +- موقع منطق كتابة البيانات إلى قاعدة البيانات +- كيفية اختبار سلسلة التوليد الكاملة +``` + +### 3.3 ربط الدفع عبر Stripe + +```text +اعتبرني مبتدئًا تمامًا وساعدني في إضافة أبسط نظام دفع Stripe يعمل لـ LaunchKit. + +لا نحتاج نظامًا معقدًا، فقط نشغّل أبسط سلسلة دفع ممكنة. + +أحتاج منك إكمال: +1. صفحة /billing تعرض باقتي free و pro +2. انتقال المستخدم إلى Stripe Checkout بعد النقر على ترقية +3. العودة إلى الموقع بعد نجاح الدفع +4. حفظ **نتائج** الدفع في جدول subscriptions +5. تحديث حقل profile.plan بشكل متزامن +6. مستخدمو free محدودون بـ 3 توليدات يوميًا، ومستخدمو pro بدون حد + +مبادئ التنفيذ: +- شغّل المسار الرئيسي أولاً، لا تقلق بشأن الحدود المعقدة مؤقتًا +- اذكر بوضوح الأماكن التي تحتاج إعدادًا في لوحة تحكم Stripe +- بعد الانتهاء اشرح كيفية اختبار سلسلة الدفع الكاملة +``` + +### 3.4 بناء لوحة الإدارة الخلفية + +```text +اعتبرني مبتدئًا تمامًا وساعدني في إنشاء لوحة إدارة خلفية بسيطة وقابلة للاستخدام. + +فقط للمسؤولين. + +أحتاج منك إكمال: +1. فقط المستخدمون الذين role = admin يمكنهم الوصول إلى /admin +2. تحتوي لوحة الإدارة على 3 علامات تبويب: قائمة المستخدمين، سجلات التوليد، حالة الاشتراك +3. تعرض قائمة المستخدمين: البريد الإلكتروني، الباقة، تاريخ الإنشاء +4. تعرض سجلات التوليد: المستخدم، اسم المنتج، القناة، تاريخ الإنشاء +5. تعرض حالة الاشتراك: المستخدم، الباقة، حالة الدفع + +المتطلبات: +- واجهة بسيطة وواضحة +- استخدام الجداول وعلامات التبويب والشارات من مكتبة المكونات الحالية +- بعد الانتهاء اشرح كيفية تعيين الحساب كمسؤول +``` + +### هل واجهتك عقبات؟ + +إذا واجهتك صعوبة في مرحلة تطوير الخلفية، يمكنك مراجعة هذه الفصول: + +- [من قاعدة البيانات إلى Supabase](../../backend/database-supabase/) +- [كتابة كود الواجهات والتوثيق بمساعدة النماذج الكبيرة](../../backend/ai-interface-code/) +- [كيفية دمج أنظمة الدفع مثل Stripe](../../backend/stripe-payment/) + +## الجزء الرابع: التكامل والنشر + +### 4.1 اختبار شامل من البداية للنهاية + +تحقق من السيناريوهات التالية على الأقل: + +- تسجيل ← تسجيل دخول ← توليد نصوص ← عرض السجل ← ترقية الباقة +- تسجيل دخول المسؤول ← عرض بيانات المستخدمين ← عرض سجلات التوليد ← عرض حالة الدفع + +فحوصات ما قبل النشر: + +```text +اعتبرني مبتدئًا تمامًا وساعدني في التحقق مما إذا كان المشروع جاهزًا للنشر. + +نقاط الفحص الرئيسية: +- هل متغيرات البيئة مكتملة +- هل عنوان إعادة توجيه تسجيل الدخول صحيح +- هل عنوان إعادة توجيه دفع Stripe صحيح +- هل تنقص الصفحات حالة تحميل أو حالة فارغة أو رسالة خطأ +- هل يحتوي README على تعليمات التشغيل والنشر + +أحتاج منك: +1. سرد العناصر التي تحتاج إصلاحًا مرتبة حسب الأولوية +2. تحديد ما يجب إصلاحه أولًا +3. شرح **خطوات** النشر بعد الإصلاح +``` + +### 4.2 النشر + +انشر المشروع على بيئة الإنترنت العامة. راجع دروس النشر: [سير عمل Git و GitHub](../../backend/git-workflow/)، [نشر تطبيقات الويب](../../backend/zeabur-deployment/). + +## المخرجات المطلوبة + +بعد إكمال هذا المشروع، يجب عليك تقديم المحتوى التالي: + +- [ ] رابط عرض تجريبي عبر الإنترنت قابل للوصول +- [ ] رابط مستودع الكود المصدري (مع README) +- [ ] مستند PRD +- [ ] لقطات شاشة للصفحات الأساسية (الصفحة الرئيسية، Dashboard، Billing، Admin) +- [ ] فيديو عرض تجريبي مدته 60 ثانية (يغطي التسجيل ← التوليد ← الدفع ← لوحة الإدارة) + +يجب أن يحتوي README على الأقل: **مقدمة المشروع**، شرح الصفحات الأساسية، حزم التقنيات، **خطوات** التشغيل المحلي، قائمة متغيرات البيئة. + +## معايير التقييم + +| البعد | المتطلبات الأساسية | المتطلبات المتقدمة | +|------|---------|---------| +| اكتمال المنتج | الصفحة الرئيسية وتسجيل الدخول و Dashboard و Billing و Admin جميعها قابلة للوصول | نصوص الصفحة الرئيسية وأسلوبها البصري يشبهان SaaS حقيقي | +| حلقة الأعمال | التسجيل ← تسجيل الدخول ← التوليد ← عرض السجل يمكن تشغيله بالكامل | الفرق في الصلاحيات بين free و Pro واضح ومرئي | +| صحة البيانات | **نتائج** التوليد وحالة الدفع محفوظة في قاعدة البيانات | توجد رسائل خطأ وحالات فارغة وحالة تحميل واضحة | +| الصلاحيات والأمان | لا يمكن للمستخدمين غير المسجلين الوصول للصفحات المحمية، ولا يمكن للمستخدمين العاديين دخول Admin | يوجد تحقق أساسي من المدخلات ومصادقة من جانب الخادم | +| جودة التسليم | يمكن تشغيل المشروع محليًا ونشره على الإنترنت | README واضح، وهيكل فيديو العرض التجريبي مكتمل | + +::: tip +إذا شعرت أن المهمة كبيرة جدًا، تذكر مبدأ واحد: **اضمن أولًا أن "كل شيء يعمل"، ثم اسعَ لـ "أن يكون جميلًا".** +::: + +## فحوصات ما قبل التقديم + + + + + + + +## المراجع + +- [تصميم واجهة المستخدم](../../frontend/ui-design/) +- [تصميم الصفحات والأزرار وفقًا لإرشادات تصميم واجهة المستخدم](../../frontend/multi-product-ui/) +- [اجعل واجهتك جميلة باستخدام LLM و Skills](../../frontend/llm-skills-beautiful/) +- [من النموذج الأولي للتصميم إلى كود المشروع](../../frontend/design-to-code/) +- [تحديث واجهتك باستخدام مكتبة مكونات حديثة](../../frontend/modern-component-library/) +- [من قاعدة البيانات إلى Supabase](../../backend/database-supabase/) +- [كتابة كود الواجهات والتوثيق بمساعدة النماذج الكبيرة](../../backend/ai-interface-code/) +- [سير عمل Git و GitHub](../../backend/git-workflow/) +- [نشر تطبيقات الويب](../../backend/zeabur-deployment/) +- [كيفية دمج أنظمة الدفع مثل Stripe](../../backend/stripe-payment/) diff --git a/docs/ar-sa/stage-2/assignments/custom-dify-agent-platform/index.md b/docs/ar-sa/stage-2/assignments/custom-dify-agent-platform/index.md new file mode 100644 index 0000000..aaef15d --- /dev/null +++ b/docs/ar-sa/stage-2/assignments/custom-dify-agent-platform/index.md @@ -0,0 +1,210 @@ +# 类 Dify 智能体平台开发تطبيق عملي + +## نظرة عامة + +本تطبيق عملي项目要求你围绕一份真实的 PRD,从零完成一个模仿 Dify 核心体验的智能体平台。你将构建用户控制台、管理后台和平台后端,实现智能体管理、对话、日志和知识库等核心功能。 + +这是 Stage 2 的综合تطبيق عملي环节。与前面的单页面或单功能项目不同,这个项目要求你构建一个有"平台感"的 AI 产品——包含多角色、多模块、数据持久化和模型调用链路。 + +## المعارف المسبقة + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## أهداف التعلم + +完成本تطبيق عملي后,你将能够: + +1. 阅读并理解一份真实的 PRD,从中提取开发任务清单 +2. 设计智能体平台的页面架构和数据模型 +3. 实现智能体创建、对话、日志记录的完整链路 +4. 使用 AI 辅助完成平台型产品开发 +5. 完成端到端联调,交付一个可演示的 AI 平台原型 + +## مقدمة المشروع + +你要构建的产品是一个类 Dify 智能体平台,包含两个子系统: + +| 子系统 | 职责 | +|--------|------| +| **用户控制台** | 创建智能体、配置 Prompt、发起对话、查看日志、管理知识库 | +| **管理后台** | 查看用户数据、平台资源使用情况、调用统计 | + +后端需要支持以下核心能力:智能体管理、会话管理、消息存储、模型调用、调用日志记录、知识库接入。 + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/custom-dify-agent-platform/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 智能体、会话、日志、知识库哪些要进 MVP? +- 页面和路由清单是否拍板? +- 模型调用和日志记录的边界是什么? +- 多租户和复杂工作流是否先不做? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认系统架构 + +根据 PRD 梳理出系统的整体架构: + +```mermaid +flowchart TD + prd["PRD"] --> app["用户控制台"] + prd --> admin["管理后台"] + app --> auth["鉴权"] + app --> agent["智能体配置"] + app --> chat["会话对话"] + chat --> llm["模型调用"] + chat --> db["数据库"] + app --> kb["知识库接入"] + admin --> logs["调用日志与平台概览"] + logs --> db +``` + +## 第二部分:搭建项目骨架 + +### 2.1 生成前端页面 + +نصيحة词参考: + +```text +请基于当前 PRD,帮我生成一个类 Dify 智能体平台的前端骨架。 + +要求: +1. 用户侧包括:登录、智能体列表、智能体配置、对话页、日志页、知识库页 +2. 后台侧包括:后台首页、用户概览、资源使用概览 +3. 先只生成页面结构和假数据,不接真实接口 +4. 风格要像现代 AI 平台 +``` + +### 2.2 验证页面结构 + +逐项检查: + +- [ ] 用户控制台和管理后台入口是否分开 +- [ ] 智能体列表、配置、对话、日志、知识库页面是否完整 +- [ ] 管理后台首页、用户概览页面是否可访问 +- [ ] 假数据展示了基本的 UI 状态 + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +在骨架的基础上,按以下顺序逐模块补充功能: + +1. **鉴权**:注册、登录、角色区分 +2. **智能体管理**:创建、编辑、删除、Prompt 配置 +3. **对话功能**:会话创建、消息收发、模型调用 +4. **日志记录**:耗时、token 用量、错误记录 +5. **知识库接入**(加分项):文档上传、检索、النتيجة注入 +6. **管理后台**:用户数据、资源使用、调用统计 + +每完成一个模块,使用下表进行自检: + +| 检查项 | 验证方法 | +|--------|----------| +| 页面一致性 | 页面数量、功能是否符合 PRD | +| 接口闭环 | agents、chat、logs、knowledge 接口是否完整 | +| 权限隔离 | 用户是否只能管理自己的 agent 和会话 | +| 数据一致性 | messages、logs、documents 数据是否对得上 | +| 可演示性 | 是否能演示"创建 agent → 对话 → 查看日志"完整链路 | + +### 3.2 知识库接入(加分项) + +如果你想增加知识库能力,可以给每个智能体增加一个"知识库开关": + +- 开启后先检索知识片段,再和用户问题一起发送给模型 +- 关闭后按普通对话模式响应 + +第一版不必追求复杂 RAG,只要有"检索النتيجة可见、调用链路可解释"即可。 + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +至少验证以下场景: + +- 注册 → 创建智能体 → 配置 Prompt → 发起对话 → 查看日志 +- 管理员登录 → 查看用户数据 → 查看调用统计 + +部署前检查: + +- [ ] 所有核心接口都做了登录校验 +- [ ] 智能体归属权限检查通过 +- [ ] 会话记录、日志记录真实落库 +- [ ] 模型 Key 使用环境变量,不硬编码 +- [ ] 错误نصيحة可在前端看到,不只打控制台 + +### 4.2 部署 + +将项目部署到公网环境。部署教程参考:[Git 和 GitHub 工作流](../../backend/git-workflow/)、[如何部署 Web 应用](../../backend/zeabur-deployment/)。 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(智能体管理页、对话页、日志页、后台首页) +- [ ] 60 秒演示视频(覆盖创建智能体 → 对话 → 查看日志) + +README 至少包含:مقدمة المشروع、架构说明、技术栈、本地启动خطوة、环境变量清单、接口说明。 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| 平台完整度 | agents / chat / logs 三页可用 | 有清晰导航与统一设计语言 | +| 业务闭环 | 可创建智能体并真实对话 | 支持多智能体切换与历史会话 | +| 数据与追踪 | 消息与调用日志可查询 | 有 token / 耗时统计看板 | +| 权限安全 | 仅登录用户可访问核心接口 | 资源归属校验完善 | +| 工程交付 | 可部署、可演示、README 清晰 | 接入知识库并可解释检索النتيجة | + +## 提交前检查 + + + + + + + +## المراجع + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/ar-sa/stage-2/assignments/exam-management-express/index.md b/docs/ar-sa/stage-2/assignments/exam-management-express/index.md new file mode 100644 index 0000000..bdb0e80 --- /dev/null +++ b/docs/ar-sa/stage-2/assignments/exam-management-express/index.md @@ -0,0 +1,306 @@ +# تطوير نظام الامتحانات عبر الإنترنت والإدارة — تطبيق عملي + +## نظرة عامة + +يتطلب هذا المشروع **التطبيقي** منك العمل وفق مستند متطلبات منتج (PRD) حقيقي، لبناء نظام امتحانات عبر الإنترنت وإدارة من الصفر. ما يميز هذا المشروع هو أنه يتضمن أدوارًا متعددة (طالب ومسؤول)، حيث يرى كل دور صفحات مختلفة ويمكنه تنفيذ عمليات مختلفة. ستستخدم Express لبناء الخلفية وتنفيذ سلسلة أعمال الامتحانات الكاملة. + +هذا هو المشروع **التطبيقي** الشامل في المرحلة الثانية. أنظمة الصلاحيات متعددة الأدوار شائعة جدًا في العمل الفعلي، وبعد إتقان هذا النموذج، ستتمكن من التعامل مع سيناريوهات أعمال متنوعة مثل التعليم والتدريب و SaaS وإدارة الخلفية. + +## المعارف المسبقة + +قبل البدء في هذا المشروع، يجب أن تكون قد أتقنت المحتوى التالي: + +- تصميم واجهات المستخدم واستخدام مكتبات المكونات ([تصميم واجهة المستخدم](../../frontend/ui-design/)، [مكتبة المكونات الحديثة](../../frontend/modern-component-library/)) +- تصميم وتطوير واجهات الخلفية ([كتابة كود الواجهات](../../backend/ai-interface-code/)) +- أساسيات قواعد البيانات و Supabase ([من قاعدة البيانات إلى Supabase](../../backend/database-supabase/)) +- سير عمل Git والنشر ([سير عمل Git و GitHub](../../backend/git-workflow/)، [نشر تطبيقات الويب](../../backend/zeabur-deployment/)) + +## أهداف التعلم + +بعد إكمال هذا المشروع **التطبيقي**، ستتمكن من: + +1. قراءة وفهم مستند PRD حقيقي واستخراج قائمة مهام التطوير منه +2. تصميم التحكم في صلاحيات نظام متعدد الأدوار وتوجيه الصفحات +3. استخدام Express لتنفيذ واجهات API خلفية كاملة +4. تنفيذ سلسلة أعمال الامتحانات والتقديم والتصحيح التلقائي +5. إكمال التكامل الشامل من البداية للنهاية وتسليم نموذج أولي لنظام أعمال قابل للعرض + +## مقدمة المشروع + +المنتج الذي ستقوم ببنائه هو نظام امتحانات عبر الإنترنت وإدارة، يتضمن ثلاثة أنظمة فرعية: + +| النظام الفرعي | المسؤولية | +|--------|------| +| **موقع الشركة** | تقديم المنصة، مدخل تسجيل الدخول | +| **جانب الطالب** | قائمة الامتحانات، الإجابة، التقديم، عرض الدرجات | +| **لوحة الإدارة** | إدارة بنك الأسئلة، إدارة الامتحانات، سجلات التقديم، إحصائيات الدرجات | + +تستخدم الخلفية Express، وتحتاج إلى دعم: مصادقة تسجيل الدخول، صلاحيات الأدوار، إدارة الامتحانات وبنك الأسئلة، عملية التقديم والتصحيح التلقائي، إدارة الدرجات والإحصائيات. + +::: tip رابط مستند PRD +مستند متطلبات هذا المشروع على GitHub: [عرض PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/exam-management-express/PRD.md) +::: + +
+ + + +
+ +## الجزء الأول: تحليل المتطلبات + +### 1.1 قراءة PRD + +افتح مستند PRD، وركّز على الإجابة عن الأسئلة التالية: + +- كم دورًا يتضمن النظام؟ وماذا يمكن لكل دور أن يفعل؟ +- هل قائمة الصفحات مكتملة؟ ما هي الصفحات في جانب الطالب وجانب الإدارة؟ +- ما أنواع الأسئلة المدعومة؟ وما هو منطق التصحيح لكل نوع؟ +- ما هي العملية الكاملة للامتحان؟ (النشر ← البدء ← الإجابة ← التقديم ← التصحيح ← عرض الدرجات) + +::: warning +إذا لم تكن لديك إجابات واضحة على الأسئلة أعلاه، لا تبدأ بكتابة الكود. عدم وضوح المتطلبات هو السبب الأكثر شيوعًا لإعادة العمل. +::: + +### 1.2 تأكيد بنية النظام + +استنادًا إلى PRD، استخلص البنية العامة للنظام: + +```mermaid +flowchart TD + prd["PRD"] --> web["موقع الشركة"] + prd --> student["جانب الطالب"] + prd --> admin["لوحة الإدارة"] + student --> auth["المصادقة"] + student --> exam["الامتحانات والإجابة"] + exam --> db["قاعدة البيانات"] + admin --> question["إدارة بنك الأسئلة"] + admin --> submission["سجلات التقديم وإحصائيات الدرجات"] + question --> db + submission --> db +``` + +## الجزء الثاني: بناء هيكل المشروع + +### 2.1 توليد الصفحات الأمامية + +مرجع **للنصيحة**: + +```text +ساعدني بناءً على PRD الحالي في توليد هيكل أمامي لنظام امتحانات عبر الإنترنت وإدارة. + +حزم التقنيات المطلوبة: +- Next.js App Router +- TypeScript +- Tailwind CSS +- shadcn/ui + +قائمة الصفحات: +1. الصفحة الرئيسية / +2. صفحة تسجيل الدخول /login +3. قائمة امتحانات الطالب /student/exams +4. صفحة إجابة الطالب /student/exams/[id] +5. صفحة درجات الطالب /student/history +6. الصفحة الرئيسية للإدارة /admin +7. صفحة إدارة الامتحانات /admin/exams +8. صفحة إدارة بنك الأسئلة /admin/questions +9. صفحة سجلات التقديم /admin/submissions + +المتطلبات: +- صفحات جانب الطالب تؤكد على الوضوح والتركيز وسهولة الإجابة +- صفحات جانب الإدارة تستخدم تخطيط شريط جانبي + شريط علوي +- استخدم بيانات وهمية أولاً بدون ربط واجهات حقيقية +- **لاحظ** التوافق الأساسي مع سطح المكتب والأجهزة المحمولة +``` + +### 2.2 تحسين صفحة إجابة الطالب + +صفحة الإجابة هي الصفحة الأساسية في جانب الطالب، ركّز على تحسينها: + +```text +ساعدني في تحسين صفحة إجابة الطالب. + +هذه صفحة إجابة في نظام امتحانات عبر الإنترنت، تحتاج إلى تضمين: +- عرض عنوان الامتحان والعد التنازلي وعدد الأسئلة المُجاب عليها في الأعلى +- عرض نص السؤال والخيارات في الوسط +- دعم ثلاثة أنواع أسئلة: اختيار من متعدد، صح/خطأ، إجابة قصيرة +- بطاقة إجابة على اليسار أو الأعلى تعرض حالة الإجابة لكل سؤال +- مربع تأكيد قبل النقر على التقديم + +استخدم بيانات وهمية لتحقيق التفاعل أولاً بدون ربط واجهات حقيقية. + +المتطلبات: +- واجهة بسيطة، لا تشبه صفحة جدول الإدارة +- عد تنازلي بارز لكن بدون ضغط مبالغ فيه +- توجد حالة فارغة وحالة تحميل +``` + +### 2.3 تحسين لوحة الإدارة الخلفية + +تركز النسخة الأولى من لوحة الإدارة على ثلاث مناطق أساسية: + +- **إدارة الامتحانات**: إنشاء امتحان، تعيين المدة، حالة النشر +- **إدارة بنك الأسئلة**: إضافة أسئلة، تعديل أسئلة، فرز حسب نوع السؤال +- **سجلات التقديم**: عرض تقديمات الطلاب والدرجات والوقت + +### 2.4 التحقق من بنية الصفحات + +تحقق من كل عنصر: + +- [ ] هل مدخلا جانب الطالب والإدارة منفصلان +- [ ] هل صفحة تسجيل الدخول وقائمة الامتحانات وصفحة الإجابة وصفحة الدرجات مكتملة +- [ ] هل صفحات بنك الأسئلة وإدارة الامتحانات وسجلات التقديم في جانب الإدارة قابلة للوصول +- [ ] هل يوجد فرق واضح في نمط الصفحات بين جانب الطالب وجانب الإدارة + +### هل واجهتك عقبات؟ + +إذا واجهتك صعوبة في مرحلة بناء الواجهة الأمامية، يمكنك مراجعة هذه الفصول: + +- [من قاعدة البيانات إلى Supabase](../../backend/database-supabase/) +- [تصميم وتطوير واجهات الخلفية للتطبيقات](../../backend/ai-interface-code/) +- [تحديث واجهتك باستخدام مكتبة مكونات حديثة](../../frontend/modern-component-library/) + +## الجزء الثالث: تطوير الخلفية + +### 3.1 تسجيل الدخول والتحكم في الصلاحيات + +```text +اعتبرني مبتدئًا تمامًا وساعدني في إكمال تسجيل الدخول والتحكم في الصلاحيات لنظام الامتحانات عبر الإنترنت. + +الخلفية تستخدم Express. + +الأهداف: +1. يمكن للطالب والمسؤول تسجيل الدخول +2. يُعاد دور المستخدم بعد تسجيل الدخول +3. يمكن للطالب فقط الوصول إلى واجهات /student/* +4. يمكن للمسؤول فقط الوصول إلى واجهات /admin/* +5. يُعاد توجيه المستخدمين غير المسجلين إلى /login عند محاولة الوصول للصفحات المحمية + +متطلبات التنفيذ: +- اقترح هيكل دليل واضح +- اشرح بوضوح مسؤوليات الوسائط +- لا تقم بتشفير المتغيرات البيئية بشكل ثابت +- بعد الانتهاء اشرح كيفية التحقق من أن الصلاحيات تعمل +``` + +### 3.2 واجهات إدارة الامتحانات وبنك الأسئلة + +يُنصح بالتنفيذ حسب الوحدات التالية: + +| الوحدة | الواجهات المقترحة | +|------|----------| +| إدارة الامتحانات | `GET /api/exams`، `POST /api/admin/exams`، `PATCH /api/admin/exams/:id` | +| إدارة بنك الأسئلة | `GET /api/admin/questions`، `POST /api/admin/questions` | +| بدء الامتحان | `POST /api/submissions/start` | +| تقديم ورقة الامتحان | `POST /api/submissions/:id/submit` | +| سجل الدرجات | `GET /api/student/history`، `GET /api/admin/submissions` | + +مرجع **للنصيحة**: + +```text +ساعدني في تصميم وتنفيذ Express API لنظام الامتحانات عبر الإنترنت. + +نطاق الوظائف: +- المسؤول ينشئ امتحانات +- المسؤول يدير بنك الأسئلة +- الطالب يعرض الامتحانات المنشورة +- الطالب يبدأ الامتحان وينشئ تقديمًا +- الطالب يقدم الإجابات ويتم التصحيح التلقائي للأسئلة الموضوعية +- أسئلة الإجابة القصيرة تُعلَّم كقيد المراجعة أولًا +- الطالب يعرض درجاته التاريخية +- المسؤول يعرض جميع سجلات التقديم + +المتطلبات: +- تسمية واضحة للواجهات +- إرجاع بنية JSON موحدة +- فصل controller و service و middleware و db في الكود +- شرح كيفية اختبار كل واجهة +``` + +### 3.3 منطق التصحيح + +منطق التصحيح هو قاعدة الأعمال الأساسية في نظام الامتحانات: + +- **أسئلة الاختيار من متعدد**: يُحصل الطالب على النقاط إذا تطابقت إجابته مع الإجابة النموذجية +- **أسئلة الصح/الخطأ**: يمكن تصحيحها تلقائيًا أيضًا +- **أسئلة الإجابة القصيرة**: في الإصدار الأول يتم حفظ الإجابة فقط بدون درجة، مع حالة `reviewed = false` + +::: tip عنصر إضافي +إذا أردت إضافة قدرات الذكاء الاصطناعي، يمكنك السماح للمسؤول بإدخال "الموضوع + الصعوبة" في لوحة الإدارة، ثم يقوم النموذج بتوليد مجموعة من الأسئلة المرشحة أولًا، ثم تتم مراجعتها يدويًا وإضافتها إلى بنك الأسئلة. لكن هذا عنصر إضافي وليس مطلوبًا. +::: + +## الجزء الرابع: التكامل والنشر + +### 4.1 اختبار شامل من البداية للنهاية + +تحقق من السيناريوهات التالية على الأقل: + +- تسجيل دخول الطالب ← عرض قائمة الامتحانات ← بدء الإجابة ← التقديم ← عرض الدرجات +- تسجيل دخول المسؤول ← إنشاء امتحان ← إضافة أسئلة ← النشر ← عرض سجلات التقديم + +### 4.2 النشر + +- نشر الواجهة الأمامية على Vercel / Zeabur +- نشر Express API على Zeabur / Railway / Render +- استخدام Supabase Postgres أو PostgreSQL مُدار لقاعدة البيانات + +فحوصات ما قبل النشر: + +- [ ] هل متغيرات البيئة مكتملة +- [ ] هل عناوين API للواجهة الأمامية والخلفية صحيحة +- [ ] هل حالة تسجيل الدخول تعمل في بيئة الإنتاج +- [ ] هل يمكن لحساب المسؤول الوصول فعليًا إلى لوحة الإدارة +- [ ] هل يحتوي README على تعليمات التشغيل والنشر والاختبار + +## المخرجات المطلوبة + +بعد إكمال هذا المشروع، يجب عليك تقديم المحتوى التالي: + +- [ ] رابط عرض تجريبي عبر الإنترنت قابل للوصول +- [ ] رابط مستودع الكود المصدري (مع README) +- [ ] مستند PRD +- [ ] لقطات شاشة للصفحات الأساسية (الصفحة الرئيسية، قائمة امتحانات الطالب، صفحة الإجابة، لوحة الإدارة) +- [ ] فيديو عرض تجريبي مدته 60 ثانية (يغطي عملية إجابة الطالب وعملية إدارة المسؤول) + +يجب أن يحتوي README على الأقل: **مقدمة المشروع**، شرح الصفحات الأساسية، حزم التقنيات، **خطوات** التشغيل المحلي، قائمة متغيرات البيئة. + +## معايير التقييم + +| البعد | المتطلبات الأساسية | المتطلبات المتقدمة | +|------|---------|---------| +| اكتمال الصفحات | الصفحات الرئيسية لجانب الطالب والإدارة قابلة للوصول | نمط الصفحات موحد، والتوافق الأساسي مع الأجهزة المحمولة | +| حلقة الأعمال | يمكن للطالب تسجيل الدخول والمشاركة في الامتحان والتقديم وعرض الدرجات | يمكن للمسؤول إنشاء ونشر امتحان بالكامل | +| صحة البيانات | تُكتب الإجابات المقدمة في قاعدة البيانات والأسئلة الموضوعية تُصحح تلقائيًا | أسئلة الإجابة القصيرة تدعم المراجعة اليدوية أو المساعدة بالذكاء الاصطناعي | +| التحكم في الصلاحيات | حدود وصول الطالب والمسؤول واضحة | واجهات الخادم لديها أيضًا تحقق من الأدوار | +| جودة التسليم | المشروع قابل للتشغيل والنشر و README واضح | يوجد فيديو عرض تجريبي وتعليمات اختبار | + +## فحوصات ما قبل التقديم + + + + + + + +## المراجع + +- [تصميم واجهة المستخدم](../../frontend/ui-design/) +- [تحديث واجهتك باستخدام مكتبة مكونات حديثة](../../frontend/modern-component-library/) +- [من قاعدة البيانات إلى Supabase](../../backend/database-supabase/) +- [كتابة كود الواجهات والتوثيق بمساعدة النماذج الكبيرة](../../backend/ai-interface-code/) +- [سير عمل Git و GitHub](../../backend/git-workflow/) +- [نشر تطبيقات الويب](../../backend/zeabur-deployment/) diff --git a/docs/ar-sa/stage-2/assignments/modern-landing-page/index.md b/docs/ar-sa/stage-2/assignments/modern-landing-page/index.md new file mode 100644 index 0000000..754c69a --- /dev/null +++ b/docs/ar-sa/stage-2/assignments/modern-landing-page/index.md @@ -0,0 +1,211 @@ +# 现代 AI 生图 SaaS 开发تطبيق عملي + +## نظرة عامة + +本تطبيق عملي项目要求你围绕一份真实的 PRD(产品需求文档),从零完成一个参考 Midjourney 体验的 AI 生图 SaaS 产品。你将完整经历需求分析、项目拆解、迭代开发、联调上线的全过程。 + +这是 Stage 2 的综合تطبيق عملي环节。在前面几章中,你已经分别学习了前端页面设计、后端接口开发、数据库操作、支付集成等单项技能——这个项目要求你把它们全部串起来,交付一个可运行的产品原型。 + +## المعارف المسبقة + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- 支付集成([Stripe 收费系统](../../backend/stripe-payment/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## أهداف التعلم + +完成本تطبيق عملي后,你将能够: + +1. 阅读并理解一份真实的 PRD,从中提取开发任务清单 +2. 基于 PRD 拆分模块,制定分步推进计划 +3. 使用 AI 辅助完成前端骨架搭建和后端接口开发 +4. 对每个模块进行验证和迭代优化 +5. 完成端到端联调,将项目从"能跑"推进到"能交付" + +## مقدمة المشروع + +你要构建的产品是一个现代 AI 生图 SaaS 平台,包含三个子系统: + +| 子系统 | 职责 | +|--------|------| +| **官网前台** | 产品介绍、定价、FAQ、注册转化 | +| **用户工作台** | Prompt 输入、图片生成、图库、积分、套餐、社区互动 | +| **后台管理台** | 用户管理、任务管理、支付管理、内容审核、SaaS 指标、系统监控 | + +后端需要支持以下核心能力:用户鉴权、图片生成任务、OSS 对象存储、积分与套餐支付、图片社交互动、运营数据监控。 + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/modern-landing-page/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 系统有几个入口?各自覆盖哪些页面? +- 每个页面的核心功能是什么? +- 后端包含哪些模块和数据库表? +- MVP 范围是什么?第一版哪些做,哪些不做? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认系统架构 + +根据 PRD 中的描述,梳理出系统的整体架构: + +```mermaid +flowchart TD + prd["PRD"] --> web["官网前台"] + prd --> app["用户工作台"] + prd --> admin["后台管理台"] + app --> auth["鉴权"] + app --> gen["图片生成任务"] + gen --> oss["OSS 对象存储"] + gen --> db["数据库"] + billing["支付与套餐"] --> db + social["分享 / 点赞 / 评论 / 转发"] --> db + admin --> analytics["SaaS 指标看板"] + admin --> observability["API / DB / Provider 监控"] +``` + +建议你用自己的话把架构图画一遍,确认你对系统的理解是完整的。 + +## 第二部分:搭建项目骨架 + +### 2.1 生成前端页面 + +使用 AI 先生成所有页面的基本结构和假数据。这一步的目标是搭出معلومة架构和路由,不需要接真实接口。 + +نصيحة词参考: + +```text +请基于当前 PRD,帮我生成一个现代 AI 生图 SaaS 的前端骨架。 + +要求: +1. 分成三个入口:www、app、admin +2. 官网包括:首页、定价、FAQ +3. app 包括:登录、注册、生成工作台、图库、套餐、积分、社区、作品详情、个人中心 +4. admin 包括:后台首页、用户管理、任务管理、内容管理、套餐管理、支付订单、运营配置、SaaS 指标、系统监控 +5. 先只生成页面结构和假数据,不接真实接口 +6. 风格参考 Midjourney,简洁、现代、带产品感 +``` + +### 2.2 验证页面结构 + +骨架生成后,逐项检查: + +- [ ] 三个入口的路由是否独立(`/`、`/app`、`/admin`) +- [ ] 页面数量是否与 PRD 一致 +- [ ] 每个页面是否可以正常访问和导航 +- [ ] 假数据是否展示了基本的 UI 状态(列表、空状态、表单等) + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +在骨架的基础上,按以下顺序逐模块补充功能: + +1. **鉴权**:注册、登录、角色区分 +2. **数据库**:数据表创建、读写接口 +3. **核心业务**:图片生成任务、النتيجة存储 +4. **OSS 存储**:图片上传与访问 +5. **支付**:套餐、积分、Stripe 集成 +6. **社交互动**:分享、点赞、评论 +7. **后台管理**:用户管理、任务管理、内容审核 +8. **数据监控**:SaaS 指标看板、系统监控 + +每完成一个模块,使用下表进行自检: + +| 检查项 | 验证方法 | +|--------|----------| +| 页面一致性 | 页面数量、入口、功能是否符合 PRD | +| 接口正确性 | 请求参数、返回结构、状态处理是否合理 | +| 权限隔离 | 普通用户和管理员是否互相隔离 | +| 数据一致性 | 数据库、OSS、支付、积分是否对得上 | +| 可演示性 | 是否能给别人完整演示一条业务链路 | + +::: tip +如果发现 AI 生成的内容偏离了 PRD,不要整页推翻重来,直接让它修改具体模块即可。 +::: + +### 3.2 角色与分工 + +在迭代过程中,你需要同时扮演三个角色: + +- **产品经理**:确认每个模块的功能是否符合 PRD +- **技术负责人**:确认实现方案是否合理 +- **测试工程师**:确认功能是否跑得通 + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +最后阶段的重点不是补新页面,而是把完整业务链路跑通。至少验证以下场景: + +- 注册 → 购买积分 → 生成图片 → 查看历史 → 分享互动 +- 管理员登录 → 查看用户数据 → 查看任务统计 → 查看系统监控 + +### 4.2 部署 + +将项目部署到公网环境,确保: + +- 环境变量配置完整 +- 登录回调地址正确 +- 支付回调地址正确 +- 页面无缺失的 loading、空状态、错误نصيحة + +部署教程参考:[Git 和 GitHub 工作流](../../backend/git-workflow/)、[如何部署 Web 应用](../../backend/zeabur-deployment/)。 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(官网首页、生图工作台、图库、套餐页、后台首页) +- [ ] 60 秒演示视频(覆盖注册 → 生成 → 查看 → 后台管理) + +README 至少包含:مقدمة المشروع、核心页面说明、技术栈、本地启动خطوة、环境变量清单。 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| PRD 对齐 | 页面、功能、数据结构基本符合 PRD | 能清晰说明每个设计决策与 PRD 的对应关系 | +| 产品闭环 | 注册 → 购买积分 → 生成图片 → 查看历史 → 分享互动可跑通 | 支付状态、积分余额、生成次数数据一致 | +| 后台能力 | 用户、任务、支付、内容管理可查看 | SaaS 指标看板和系统监控页完整可用 | +| 工程完整度 | 前端、后端、数据库、OSS、支付链路已接通 | 有错误处理、空状态、loading 状态 | +| 交付质量 | 可部署、可运行 | README 清楚、演示视频结构完整 | + +## المراجع + +- [UI 设计](../../frontend/ui-design/) +- [参考 UI 设计规范设计页面和按钮](../../frontend/multi-product-ui/) +- [用 LLM 和 Skills 让界面变好看](../../frontend/llm-skills-beautiful/) +- [从设计原型到项目代码](../../frontend/design-to-code/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) +- [如何集成 Stripe 等收费系统](../../backend/stripe-payment/) diff --git a/docs/ar-sa/stage-2/assignments/movie-recommendation-springboot/index.md b/docs/ar-sa/stage-2/assignments/movie-recommendation-springboot/index.md new file mode 100644 index 0000000..58b2b11 --- /dev/null +++ b/docs/ar-sa/stage-2/assignments/movie-recommendation-springboot/index.md @@ -0,0 +1,162 @@ +# Spring Boot 电影推荐系统开发تطبيق عملي + +## نظرة عامة + +本تطبيق عملي项目要求你围绕一份真实的 PRD,使用 Spring Boot 完成一个带推荐能力的电影网站。这个项目的核心挑战在于:它不是简单的增删改查,而是需要你思考"用户行为如何影响推荐النتيجة"以及"推荐如何可解释"。 + +这是 Stage 2 的综合تطبيق عملي环节。你将第一次接触"内容 + 行为 + 推荐"型产品的开发模式,这种模式在电商、内容平台、个性化 Feed 等场景中非常常见。 + +## المعارف المسبقة + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## أهداف التعلم + +完成本تطبيق عملي后,你将能够: + +1. 阅读 PRD 并从中提取推荐系统的开发任务清单 +2. 使用 Spring Boot 搭建后端项目并实现 RESTful API +3. 设计"用户行为 → 推荐"的完整数据链路 +4. 实现可解释的推荐逻辑 +5. 完成端到端联调,交付可演示的产品原型 + +## مقدمة المشروع + +你要构建的产品是一个带推荐能力的电影网站: + +| 功能 | 描述 | +|------|------| +| **浏览与搜索** | 用户可以浏览和搜索电影 | +| **评分与收藏** | 用户可以给电影评分、添加收藏 | +| **个性化推荐** | 系统根据用户行为给出推荐النتيجة | +| **管理后台** | 管理员维护电影数据、查看推荐效果 | + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/movie-recommendation-springboot/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 推荐策略是什么?第一版是否使用可解释版本(如基于评分相似度)? +- 用户行为数据要存哪些?(评分、收藏、浏览记录等) +- 管理员需要看哪些推荐效果指标? +- 页面清单是否完整? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认系统架构 + +```mermaid +flowchart TD + prd["PRD"] --> web["前端页面"] + web --> auth["用户鉴权"] + web --> movie["电影列表 / 详情"] + web --> behavior["评分 / 收藏"] + behavior --> reco["推荐逻辑"] + reco --> db["数据库"] + admin["后台管理"] --> db +``` + +## 第二部分:搭建项目骨架 + +### 2.1 生成前端页面 + +نصيحة词参考: + +```text +请基于当前 PRD,帮我生成一个 Spring Boot 电影推荐系统的前端骨架。 + +要求: +1. 页面包括:首页、电影列表、电影详情、推荐页、个人中心、后台管理 +2. 先只生成页面结构和假数据,不接真实接口 +3. 风格要像真实内容产品,而不是课堂 demo +``` + +### 2.2 验证页面结构 + +逐项检查: + +- [ ] 电影列表页支持搜索和筛选 +- [ ] 电影详情页包含评分和收藏按钮 +- [ ] 推荐页能展示推荐النتيجة和推荐理由 +- [ ] 管理后台能展示电影数据和推荐效果 + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +1. **Spring Boot 项目搭建**:项目结构、数据库配置、基础 CRUD +2. **电影数据管理**:电影列表、详情、搜索接口 +3. **用户行为**:评分、收藏接口,行为数据写入 +4. **推荐逻辑**:基于用户行为的推荐算法实现 +5. **推荐展示**:推荐النتيجة展示,包含推荐理由 +6. **管理后台**:电影数据维护、推荐效果查看 + +### 3.2 模块自检 + +| 检查项 | 验证方法 | +|--------|----------| +| 基础功能 | 列表、详情、评分、收藏是否闭环 | +| 推荐联动 | 用户行为是否影响推荐النتيجة | +| 推荐可解释性 | 用户能理解为什么被推荐这些电影 | +| 后台数据 | 管理员能查看电影数据和推荐效果 | + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +至少验证以下场景: + +- 浏览电影 → 评分 → 收藏 → 查看推荐页,确认推荐النتيجة发生变化 +- 管理员登录 → 添加电影 → 查看推荐效果统计 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(电影列表、电影详情、推荐页、管理后台) +- [ ] 60 秒演示视频 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| PRD 对齐 | 页面、功能、数据结构基本符合 PRD | 能清晰说明设计决策 | +| 产品闭环 | 浏览 → 评分 → 收藏 → 推荐可跑通 | 评分行为明显影响推荐النتيجة | +| 推荐质量 | 推荐النتيجة合理、推荐理由可解释 | 支持多种推荐策略 | +| 后台能力 | 电影数据和推荐效果可查看 | 有推荐准确率等统计指标 | +| 工程完整度 | 前端、Spring Boot 后端、数据库链路已接通 | 推荐接口有缓存或性能优化 | + +## المراجع + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/ar-sa/stage-2/assignments/simple-grocery-microservices/index.md b/docs/ar-sa/stage-2/assignments/simple-grocery-microservices/index.md new file mode 100644 index 0000000..ac0fbf8 --- /dev/null +++ b/docs/ar-sa/stage-2/assignments/simple-grocery-microservices/index.md @@ -0,0 +1,172 @@ +# 生鲜电商微服务系统开发تطبيق عملي + +## نظرة عامة + +本تطبيق عملي项目要求你围绕一份真实的 PRD,从零完成一个生鲜电商微服务系统。与前面的单服务项目不同,这个项目的后端按业务拆分成多个独立服务,通过 API 网关统一对外。你将学习如何设计服务边界、如何处理跨服务的数据一致性问题。 + +这是 Stage 2 的综合تطبيق عملي环节。微服务架构在实际工作中非常常见,掌握服务拆分和网关路由的基本思路后,你能够应对更复杂的后端系统设计。 + +## المعارف المسبقة + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## أهداف التعلم + +完成本تطبيق عملي后,你将能够: + +1. 阅读 PRD 并提取微服务系统的开发任务清单 +2. 按业务领域拆分服务边界(鉴权、商品、库存、订单) +3. 设计和实现 API 网关路由 +4. 处理库存扣减和订单一致性等跨服务问题 +5. 完成端到端联调,交付可演示的微服务原型 + +## مقدمة المشروع + +你要构建的产品是一个生鲜电商微服务系统: + +| 子系统 | 职责 | +|--------|------| +| **用户端** | 浏览商品、下单、查看订单 | +| **管理端** | 商品管理、库存管理、订单管理 | + +后端按业务拆分为以下服务: + +| 服务 | 职责 | +|------|------| +| **API Gateway** | 统一入口、路由转发、鉴权校验 | +| **Auth Service** | 用户注册、登录、JWT 颁发 | +| **Catalog Service** | 商品معلومة管理 | +| **Inventory Service** | 库存数量管理 | +| **Order Service** | 订单创建、状态管理 | + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/simple-grocery-microservices/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 服务如何拆分?每个服务的职责边界是什么? +- 前台和管理端分别有哪些页面? +- 下单后库存扣减的策略是什么?成功 / 失败 / 超时各怎么处理? +- 第一版哪些复杂能力(如分布式事务、消息队列)先不做? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认系统架构 + +```mermaid +flowchart TD + prd["PRD"] --> fe["前端页面"] + fe --> gw["API Gateway"] + gw --> auth["Auth Service"] + gw --> catalog["Catalog Service"] + gw --> inventory["Inventory Service"] + gw --> order["Order Service"] + order --> inventory +``` + +## 第二部分:搭建项目骨架 + +### 2.1 生成项目结构 + +نصيحة词参考: + +```text +请基于当前 PRD,帮我生成一个生鲜电商微服务系统的项目骨架。 + +要求: +1. 生成前端用户端和管理端骨架 +2. 生成 api-gateway、auth-service、catalog-service、inventory-service、order-service 五个目录 +3. 每个服务先只做最小可运行入口 +4. 先不接真实数据库和支付 +``` + +### 2.2 验证项目结构 + +逐项检查: + +- [ ] 五个服务目录结构清晰 +- [ ] API Gateway 可以启动并转发请求 +- [ ] 各服务健康检查接口可用 +- [ ] 前端用户端和管理端页面可访问 + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +1. **API Gateway**:路由配置、JWT 校验中间件 +2. **Auth Service**:注册、登录、JWT 颁发 +3. **Catalog Service**:商品 CRUD、列表查询 +4. **Inventory Service**:库存查询、库存扣减 +5. **Order Service**:订单创建、状态流转、库存联动 +6. **管理端**:商品管理、库存管理、订单管理 + +### 3.2 模块自检 + +| 检查项 | 验证方法 | +|--------|----------| +| 网关路由 | 各服务接口是否通过网关正确转发 | +| 权限隔离 | 用户端和管理端接口是否隔离 | +| 数据一致 | 商品和库存数据是否同步 | +| 交易闭环 | 下单后库存扣减、订单状态是否一致 | +| 失败处理 | 库存不足或超时时是否有补偿机制 | + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +至少验证以下场景: + +- 浏览商品 → 加入购物车 → 下单 → 查看订单 +- 管理员 → 添加商品 → 更新库存 → 查看订单 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(商品列表、下单页、订单页、管理后台) +- [ ] 60 秒演示视频 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| PRD 对齐 | 页面、功能、服务拆分基本符合 PRD | 能清晰说明服务拆分的理由 | +| 产品闭环 | 浏览 → 下单 → 库存扣减 → 查看订单可跑通 | 订单超时或库存不足有补偿机制 | +| 服务架构 | 各服务可独立启动,通过网关统一访问 | 服务间通信有错误处理和重试 | +| 后台能力 | 商品、库存、订单管理可操作 | 管理端有数据统计 | +| 工程完整度 | 前端、网关、服务、数据库链路已接通 | 有 Docker Compose 或类似编排 | + +## المراجع + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/ar-sa/stage-2/assignments/traffic-data-visualization-go/index.md b/docs/ar-sa/stage-2/assignments/traffic-data-visualization-go/index.md new file mode 100644 index 0000000..4f80e1d --- /dev/null +++ b/docs/ar-sa/stage-2/assignments/traffic-data-visualization-go/index.md @@ -0,0 +1,163 @@ +# Go 交通数据分析平台开发تطبيق عملي + +## نظرة عامة + +本تطبيق عملي项目要求你围绕一份真实的 PRD,使用 Go 完成一个交通数据分析平台。这个项目的方向与前面的增删改查系统不同——你需要构建一条"数据接入 → 聚合 → 告警 → 可视化"的完整数据链路。这种数据产品在 IoT、监控、运营分析等场景中非常常见。 + +这是 Stage 2 的综合تطبيق عملي环节,也是你第一次接触 Go 语言。不用担心,有了前面 JavaScript / TypeScript 的基础,学习 Go 并不难——重点是理解数据链路的设计思路。 + +## المعارف المسبقة + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## أهداف التعلم + +完成本تطبيق عملي后,你将能够: + +1. 阅读 PRD 并提取数据产品的开发任务清单 +2. 使用 Go(Gin 或 Fiber)搭建后端 API 服务 +3. 设计数据接入、窗口聚合和告警的完整链路 +4. 让后端数据和前端看板保持一致 +5. 完成端到端联调,交付可演示的数据产品原型 + +## مقدمة المشروع + +你要构建的产品是一个 Go 交通数据分析平台: + +| 模块 | 职责 | +|------|------| +| **数据接入** | 接收原始交通事件并入库 | +| **数据聚合** | 按时间窗口计算趋势和拥堵指标 | +| **告警** | 基于规则生成告警记录 | +| **看板展示** | 在前端展示趋势图、排行榜和告警列表 | + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/traffic-data-visualization-go/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 数据来源是什么?字段有哪些? +- 核心指标的定义是什么?(比如"拥堵"的具体标准) +- 告警规则是什么?第一版是否先收敛到简单规则? +- 看板包含哪些页面和图表? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认数据链路 + +```mermaid +flowchart TD + prd["PRD"] --> ingest["数据接入 API"] + ingest --> raw["原始数据表"] + raw --> agg["聚合任务"] + agg --> alert["告警规则"] + agg --> dashboard["看板接口"] + alert --> dashboard +``` + +## 第二部分:搭建项目骨架 + +### 2.1 生成 Go API 服务 + +نصيحة词参考: + +```text +请基于当前 PRD,帮我生成一个 Go 交通数据分析平台骨架。 + +要求: +1. 使用 Gin 或 Fiber +2. 提供数据接入接口 +3. 提供聚合任务骨架 +4. 提供 dashboard 和 alerts 接口骨架 +5. 先不做真实复杂分析,只做可运行结构 +``` + +### 2.2 验证项目结构 + +逐项检查: + +- [ ] Go 服务可以正常启动 +- [ ] 数据接入接口可接收并存储数据 +- [ ] 聚合任务框架已搭好 +- [ ] 前端看板页面可展示基本图表 + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +1. **数据接入 API**:接收原始交通事件,写入数据库 +2. **数据聚合**:按时间窗口聚合,计算趋势和拥堵指标 +3. **告警规则**:基于阈值生成告警记录 +4. **看板接口**:提供趋势数据、排行数据、告警列表 +5. **前端看板**:趋势图、排行榜、告警列表页面 + +### 3.2 模块自检 + +| 检查项 | 验证方法 | +|--------|----------| +| 数据接入 | 原始数据是否正确入库 | +| 聚合口径 | 趋势、排名指标的计算逻辑是否一致 | +| 告警规则 | 告警触发条件是否符合预期 | +| 数据一致性 | 看板展示和后端数据是否对得上 | +| API 规范 | 是否有统一返回结构和错误处理 | + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +至少验证以下场景: + +- 接入一批测试数据 → 聚合任务执行 → 看板展示更新 +- 触发告警条件 → 告警记录生成 → 告警页面显示 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(数据接入演示、趋势看板、告警列表) +- [ ] 60 秒演示视频 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| PRD 对齐 | 功能和数据结构基本符合 PRD | 能清晰说明指标口径和聚合逻辑 | +| 数据链路 | 接入 → 聚合 → 告警 → 看板可跑通 | 聚合任务支持增量更新 | +| 分析能力 | 趋势、排行、告警三个模块可用 | 指标可配置、告警规则可自定义 | +| 前端展示 | 看板能展示基本图表 | 图表支持时间范围筛选 | +| 工程完整度 | Go API、数据库、前端链路已接通 | API 有统一错误处理和日志 | + +## المراجع + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/ar-sa/stage-2/assignments/travel-planning-agent-platform/index.md b/docs/ar-sa/stage-2/assignments/travel-planning-agent-platform/index.md new file mode 100644 index 0000000..a257736 --- /dev/null +++ b/docs/ar-sa/stage-2/assignments/travel-planning-agent-platform/index.md @@ -0,0 +1,164 @@ +# 智能旅游规划 Agent 平台开发تطبيق عملي + +## نظرة عامة + +本تطبيق عملي项目要求你围绕一份真实的 PRD,从零完成一个智能旅游规划 Agent 平台。你将构建一个能接收结构化输入、生成每日行程、支持保存和重用的完整 AI 产品——不只是聊天机器人,而是一个有任务管理能力的产品。 + +这是 Stage 2 的综合تطبيق عملي环节。这个项目的核心挑战在于:如何让 AI 生成结构化、可用的行程规划,而不是一大段不可操作的文字。 + +## المعارف المسبقة + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## أهداف التعلم + +完成本تطبيق عملي后,你将能够: + +1. 阅读 PRD 并从中提取 Agent 平台的开发任务清单 +2. 设计结构化的输入表单和结构化的输出格式 +3. 实现 Agent 编排层,处理用户输入、模型调用和النتيجة存储 +4. 构建"生成 → 保存 → 重用"的业务闭环 +5. 完成端到端联调,交付可演示的 AI 产品原型 + +## مقدمة المشروع + +你要构建的产品是一个智能旅游规划 Agent 平台: + +| 功能 | 描述 | +|------|------| +| **行程规划** | 用户输入出发地、目的地、日期、预算和偏好,系统生成每日行程 | +| **预算拆分** | 行程النتيجة包含预算分配和建议 | +| **历史管理** | 用户可以保存历史计划、再次生成、导出 | +| **管理后台** | 管理员查看热门目的地、失败任务和用户反馈 | + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/travel-planning-agent-platform/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 第一版是否只做单目的地? +- 行程输出是否必须结构化?结构是什么? +- 导出能力做多深?(分享链接 / PDF / 图片) +- 后台统计和任务日志的范围是什么? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认系统架构 + +```mermaid +flowchart TD + prd["PRD"] --> planner["规划页"] + planner --> agent["Agent 编排层"] + agent --> model["模型调用"] + agent --> db["数据库"] + db --> history["历史计划"] + db --> admin["后台统计与日志"] +``` + +## 第二部分:搭建项目骨架 + +### 2.1 生成前端页面 + +نصيحة词参考: + +```text +请基于当前 PRD,帮我生成一个智能旅游规划 Agent 平台的前端骨架。 + +要求: +1. 页面包括:首页、规划页、行程详情页、历史记录页、管理页 +2. 规划页左侧是表单,右侧是النتيجة预览 +3. 先只生成页面结构和假数据,不接真实接口 +4. 风格要像现代 AI 产品 +``` + +### 2.2 验证页面结构 + +逐项检查: + +- [ ] 规划页的表单字段是否与 PRD 一致 +- [ ] النتيجة预览区域能展示结构化的行程数据 +- [ ] 历史记录页可以展示多条计划 +- [ ] 管理后台页可以展示统计数据 + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +1. **鉴权**:注册、登录 +2. **规划表单**:结构化输入(出发地、目的地、日期、预算、偏好) +3. **Agent 编排**:接收输入 → 调用模型 → 解析结构化输出 +4. **النتيجة展示**:行程按天展示、预算拆分、建议 +5. **历史管理**:保存计划、再次生成、导出 +6. **管理后台**:热门目的地、失败任务、用户反馈 +7. **任务状态**:生成中 / 成功 / 失败的状态管理和错误记录 + +### 3.2 模块自检 + +| 检查项 | 验证方法 | +|--------|----------| +| 输入完整性 | 表单字段是否与 PRD 一致 | +| 输出结构化 | 行程النتيجة是不是结构化数据(而非一大段文字) | +| 数据一致性 | trip、itinerary、logs 数据是否对得上 | +| 闭环验证 | 是否能演示"输入 → 生成 → 保存 → 再次生成" | + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +至少验证以下场景: + +- 输入行程参数 → 生成每日行程 → 查看预算拆分 → 保存到历史 +- 从历史记录中再次生成行程 +- 管理员查看任务统计和失败日志 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(规划页、行程详情页、历史记录页、管理后台) +- [ ] 60 秒演示视频 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| PRD 对齐 | 页面、功能、数据结构基本符合 PRD | 能清晰说明设计决策 | +| 产品闭环 | 规划 → 保存 → 历史 → 重生成可跑通 | 支持导出和分享 | +| 输出质量 | 行程النتيجة结构化且可读 | 预算拆分合理、建议有针对性 | +| 后台能力 | 任务统计和失败日志可查看 | 有热门目的地分析 | +| 工程完整度 | 前端、后端、数据库、模型调用链路已接通 | 任务状态管理完善,错误可追溯 | + +## المراجع + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/ar-sa/stage-2/backend/ai-interface-code/index.md b/docs/ar-sa/stage-2/backend/ai-interface-code/index.md new file mode 100644 index 0000000..887586c --- /dev/null +++ b/docs/ar-sa/stage-2/backend/ai-interface-code/index.md @@ -0,0 +1,168 @@ +# كتابة كود الواجهات والتوثيق بمساعدة النماذج الكبيرة + +في الدروس السابقة، تعلمنا كيفية استخدام أدوات مثل Figma لإكمال تصاميم واجهة المستخدم، وكيفية الاستعانة بالذكاء الاصطناعي لتوليد صفحات أمامية ثابتة بسرعة، وكيفية استخدام Supabase لبناء قواعد بيانات وتحقيق المصادقة الأولية للمستخدمين. الآن يبرز سؤال طبيعي: بعد النقر على تلك الأزرار الديناميكية في الصفحة الأمامية، كيف تُخزَّن البيانات بهدوء في Supabase؟ وعندما نحتاج إلى تنفيذ منطق أعمال أكثر تعقيدًا (مثل المدفوعات المتزامنة، الإرسال المجدول، معالجة البيانات الحساسة)، هل من الآمن أن يتصل الواجهة الأمامية مباشرة بقاعدة البيانات؟ + +هذا يقودنا إلى حلقة **مهمة** للغاية في بنية تطوير الويب الحديثة — **واجهات API الخلفية**. + +مقارنة بالماضي حيث كنا نكتب يدويًا مئات الأسطر من مسارات الخادم والمتحكمات ومنطق التحقق من المعلمات، يمكننا اليوم الاستفادة الكاملة من القدرات القوية للنماذج الكبيرة على توليد الكود، وإسناد الكود الأساسي المعقد إلى الذكاء الاصطناعي. في هذا الدرس، سنتجاوز دائرة "الذكاء الاصطناعي يكتب كودًا عامًا وغير دقيق"، ونعتمد على سيناريوهات أعمال حقيقية، لنوضح لك كيفية توجيه النماذج الكبيرة من خلال **نصائح** (Prompts) عالية الجودة لكتابة واجهات خلفية Node.js قوية ومتوافقة مع معايير الصناعة، مع التوليد التلقائي لوثائق الواجهات وحالات الاختبار. + +> 💡 **المعارف المسبقة** +> +> قبل دراسة هذا القسم، يُنصح بأن تكون على دراية بالمحتوى التالي: +> - [من قاعدة البيانات إلى Supabase](../database-supabase/) - فهم مفاهيم قواعد البيانات ونماذج البيانات. +> - [سير عمل Git و GitHub](../git-workflow/) - الإلمام بكيفية التحكم في الإصدارات أثناء تطوير المشاريع. +> - [ما هو الطرفية/سطر الأوامر](/ar-sa/appendix/2-development-tools/command-line-shell) - تهيئة المشاريع وتشغيلها تتطلب عمليات أوامر أساسية. + +# ما ستتعلمه + +1. **ما هي واجهات API**: فهم الجسر بين الواجهة الأمامية والخلفية ومعايير تصميم RESTful. +2. **النماذج الكبيرة تمكّن بناء الخدمات**: كيفية استخدام Prompt منظم لجعل الذكاء الاصطناعي يساعدك في بناء مشروع Node.js + Express أساسي. +3. **تطوير منطق الواجهات**: توجيه النماذج الكبيرة لتوليد واجهات CRUD (إنشاء، قراءة، تحديث، حذف) تتضمن تحققًا صارمًا من الأعمال وربطًا مع قاعدة بيانات Supabase. +4. **توثيق الواجهات الآلي**: جعل النماذج الكبيرة تولد وثائق OpenAPI/Swagger القياسية للتعاون بين الفرق. +5. **الاختبار والتكامل الشامل**: استخدام النماذج الكبيرة لتوليد مجموعات اختبار Postman وحالات اختبار Jest الوحدوية لضمان جودة الكود. + +--- + +# 1. لماذا نحتاج إلى واجهات API؟ + +في الفهم التقليدي، الواجهة الأمامية هي "الجزء المرئي"، وقاعدة البيانات هي "المخزن". لكن هناك عنصر تنسيق مفقود بينهما. إذا تخيلت التطبيق بأكمله كمطعم: +- **الواجهة الأمامية (العميل)** هي قائمة الطعام وطاولة الطلب، حيث يتصفح الضيوف الأطباق ويقدمون طلباتهم. +- **قاعدة البيانات (مثل Supabase)** هي مخزن المطبخ، حيث تُحفظ جميع المكونات والسجلات. +- **واجهة API الخلفية** هي النادل. لا يمكن للضيوف الدخول مباشرة إلى المطبخ لأخذ المكونات (مما يسبب فوضى ومخاطر أمنية)، بل يقدمون "طلبهم" (HTTP Request) للنادل. يقوم النادل بالتحقق (التحقق من المعلمات، المصادقة والتفويض)، ثم يذهب إلى المطبخ لإحضار المحتوى المطلوب، ويعيد "الطبق الجاهز" (HTTP Response، عادةً بتنسيق JSON) للضيف. + +من خلال واجهات API، نحقق **فصلًا واضحًا بين الواجهة الأمامية والخلفية**: الواجهة الأمامية تهتم فقط بكيفية عرض الصفحات، بينما تركز الخلفية على منطق الأعمال ومعالجة البيانات والحماية الأمنية. + +--- + +# 2. تصميم بنية المشروع والتهيئة + +هيكل مشروع واضح هو شرط مسبق لقدرة النماذج الكبيرة على كتابة كود جيد. قبل أن نطلب من الذكاء الاصطناعي كتابة الكود، يجب أن نكون واضحين بشأن الهيكل الهندسي. + +## 2.1 هيكل مشروع API الشائع + +حتى عند استخدام النماذج الكبيرة لتوليد الكود، يجب ألا نضع كل الكود في ملف `server.js` واحد. بنية خلفية Node.js سهلة الصيانة تبدو عادةً كما يلي: + +```text +my-api-project/ +├── .env # متغيرات البيئة الحساسة (مثل مفاتيح API، سلسلة اتصال قاعدة البيانات) +├── server.js # نقطة دخول المشروع (تشغيل الخادم، تسجيل الوسائط العامة) +├── package.json # ملف إدارة التبعيات +├── src/ +│ ├── routes/ # طبقة المسارات: تحديد مسارات URL وطرق الطلب +│ ├── controllers/ # طبقة المتحكمات: معالجة معلمات الطلب، استدعاء الخدمات وإرجاع الاستجابة +│ ├── services/ # طبقة الخدمات: تغليف التفاعل مع قاعدة البيانات ومنطق الأعمال الأساسي +│ └── middlewares/ # الوسائط: المصادقة، التقاط الأخطاء العامة +└── docs/ # دليل تخزين وثائق API +``` + +## 2.2 الاستعانة بالذكاء الاصطناعي لتهيئة المشروع + +بدلاً من تشغيل `npm init` يدويًا وتثبيت التبعيات واحدة تلو الأخرى، يمكنك تقديم المواصفات أعلاه كـ Prompt للنموذج الكبير: + +> 🗣️ **نصيحة للنموذج الكبير (مثال على Prompt):** +> "ساعدني في بناء مشروع خلفي Node.js، يجب أن يتمكن من الاتصال بقاعدة بيانات Supabase، ببنية واضحة تسهل الصيانة المستقبلية." + +بعد تشغيل الكود الذي يعيده الذكاء الاصطناعي، ستحصل على تطبيق خلفي بمعالم مستوى المؤسسات على `localhost:3000`. + +--- + +# 3. التطبيق العملي الأساسي: تطوير الواجهات بمساعدة النماذج الكبيرة + +هذا هو الجزء الأهم في هذا الفصل. الكود الذي تكتبه النماذج الكبيرة غالبًا ما يعاني من "ثغرات منطقية" أو "سطحية"، والسبب هو عدم كفاية السياق الذي يقدمه المطور. **النماذج الكبيرة لا تخشى التعقيد، بل تخشى الغموض.** + +لنأخذ واجهة إضافة عنصر جديد في جدول `menu_items` (جدول القائمة) المذكور في [فصل قاعدة البيانات](../database-supabase/)، لنرَ كيف نكتب Prompt عالي الجودة. + +## 3.1 تزويد النموذج الكبير بسياق كامل + +قبل طلب كتابة واجهة من الذكاء الاصطناعي، يجب تقديم **تعريف حقول قاعدة البيانات (Schema)** و**شروط القيود المحددة**. + +> 🗣️ **قالب نصيحة عالي الجودة (Prompt):** +> "ساعدني في كتابة واجهة إضافة عنصر جديد للقائمة، العنصر يحتوي على اسم المنتج، السعر، الفئة (برجر، مقبلات، مشروبات)، وحالة التفعيل. اسم المنتج والسعر مطلوبان، والسعر لا يمكن أن يكون سالبًا. عند إدخال مستخدم غير صحيح يجب إظهار رسالة خطأ." + +## 3.2 مراجعة الكود المُولَّد من النموذج الكبير + +الكود المُولَّد من النموذج الكبير عادةً ما يقسم المسؤوليات بوضوح كما يلي: + +```javascript +// services/menuService.js +const { createClient } = require('@supabase/supabase-js'); +const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY); + +exports.createMenuItem = async (menuData) => { + // استدعاء Supabase SDK لإدراج البيانات في الجدول + const { data, error } = await supabase + .from('menu_items') + .insert([menuData]) + .select(); + + if (error) throw new Error(`فشل إدراج قاعدة البيانات: ${error.message}`); + return data[0]; +}; +``` + +يمكنك ملاحظة أن الكود المُولَّد بهذه الطريقة ليس منظمًا فحسب، بل يأخذ في الاعتبار تهيئة Supabase والتقاط الأخطاء ومعالجة الاستثناءات، مما يختلف اختلافًا جوهريًا عن كود السباغيتي (Spaghetti Code) الذي تحصل عليه عندما تطلب ببساطة "اكتب واجهة إضافة". + +--- + +# 4. تحرير اليدين: التوليد التلقائي لوثائق الواجهات + +بالنسبة لفريق التطوير، واجهة API بدون وثائق هي صندوق أسود. لا يمكن للمهندسين الأماميين تخمين المعلمات المطلوبة أو توقع بنية الاستجابة. المعيار الأكثر شيوعًا لوصف API في الصناعة هو **OpenAPI (المعروف سابقًا باسم Swagger)**. + +في الماضي، كانت كتابة وثائق Swagger بصيغة YAML أو JSON يدويًا مؤلمة للغاية وعرضة للأخطاء. الآن، أصبح هذا المجال من أكثر ما تتميز به النماذج الكبيرة. + +يمكنك ببساطة تحديد كود `routes` و `controllers` الذي كتبته للتو وإرساله للنموذج الكبير: + +> 🗣️ **نصيحة لتوليد الوثائق:** +> "ساعدني في توليد وثائق واجهات بناءً على الكود أعلاه، مع توضيح معنى كل معلمة والبيانات المُعادة، لتسهيل التعاون مع الزملاء في الواجهة الأمامية." + +في هذه العملية، يمكنك حتى طلب من الذكاء الاصطناعي إكمال أوصاف الحقول (Description) وبيانات Mock (مثل `price_cents: 1200` يمثل 12 دولارًا)، مما يقلل بشكل كبير من تكلفة التواصل. + +--- + +# 5. الحماية والضمان: توليد كود الاختبار ومجموعات Postman + +بعد كتابة الكود وإعداد الوثائق، يتبقى خطوة أخيرة: التحقق من أن الكود يعمل بالفعل. + +## 5.1 توليد إعدادات اختبار Postman / Apifox + +في تطوير الواجهات، نستخدم عادةً أدوات مرئية مثل Postman لمحاكاة طلبات HTTP من الواجهة الأمامية. بدون استخدام النماذج الكبيرة، ستحتاج إلى إدخال URL يدويًا، وإضافة Headers (رؤوس الطلب) واحدًا تلو الآخر، وتجميع نص طلب JSON. + +يكفي أن ترسل للذكاء الاصطناعي التعليمات التالية: +> "حول وثائق الواجهات هذه إلى تنسيق يمكن استيراده في Postman، مع تضمين أمثلة للطلبات الصحيحة والخاطئة." + +بعد الحصول على نص JSON، احفظه باسم `menu_api.json` واسحبه إلى Postman، وستحصل فورًا على لوحة نقر اختبار جاهزة للاستخدام. + +## 5.2 كتابة اختبارات وحدوية آلية + +إذا كنت تسعى لجودة هندسية أكثر صرامة، يمكنك جعل النموذج الكبير يساعدك في استخدام أطر اختبار مثل `Jest` لكتابة اختبارات وحدوية (Unit Tests)، وإجراء اختبارات حدودية على منطق الأعمال الأساسي (مثل التحقق مما إذا كانت طبقة قاعدة البيانات ترفض الأسعار السالبة). + +--- + +# 6. أفضل الممارسات الأساسية لواجهات الخلفية + +حتى مع مساعدة الذكاء الاصطناعي، بصفتك "الحارس" للنظام بأكمله، لا يزال يتعين عليك فهم ومراجعة المبادئ الأساسية التالية: + +1. **تسمية المسارات وفق معايير RESTful**: + - تصميم جيد: `GET /api/users` (الحصول على قائمة المستخدمين)، `POST /api/users` (إنشاء مستخدم). يجب أن يمثل URL اسم "المورد". + - تصميم خاطئ: `POST /api/getUser` أو `POST /api/createUser`. يجب ترك الأفعال لطرق HTTP (GET/POST/PUT/DELETE). +2. **رموز حالة HTTP القياسية**: + - 200/201: نجاح الطلب / إنشاء المورد بنجاح. + - 400: طلب غير صحيح، خطأ في تنسيق معلمات الواجهة الأمامية أو حقل مطلوب مفقود. + - 401/403: غير مصادق / ممنوع، المستخدم لم يسجل الدخول أو ليس لديه صلاحية. + - 404: غير موجود، المورد غير موجود. + - 500: خطأ في الخادم، خطأ في كود الخلفية أو قاعدة البيانات معطلة. يجب تجنب كشف تتبع الخطأ مباشرة للواجهة الأمامية (مخاطر أمنية). +3. **لا تثق أبدًا في مدخلات المستخدم**: مدخلات الواجهة الأمامية قد تكون مزيفة، يجب إعادة التحقق من جميع المعلمات الأساسية في واجهات الخلفية. + +# 7. الخلاصة + +من خلال تعلم هذا الفصل، حققت تحولًا حقيقيًا في منظور التطوير: لم تعد عالقًا في بناء الجملة وعلامات الترقيم كـ "كاتب كود"، بل ارتقيت لتصبح **مصمم أنظمة وقائد بنية**. + +لقد أتقنت: +1. التفكير النظامي الأساسي لـ **واجهات API وفصل الواجهة الأمامية عن الخلفية**. +2. **كيفية تحسين جودة الكود الخلفي المُولَّد من النماذج الكبيرة** بشكل كبير من خلال توفير السياق ومفهوم البنية الطبقية. +3. تحويل المهام الشاقة لـ **كتابة الوثائق** و**بناء حالات الاختبار** بمهارة إلى مهام آلية يتقنها الذكاء الاصطناعي. +4. بالدمج مع معرفتك السابقة بـ **Supabase**، ربطت تدفق البيانات الكامل من طلب العميل إلى تحديث قاعدة البيانات الأساسية. + +::: tip 💡 الخطوة التالية +عندما يكون تدفق البيانات والخدمات الخلفية جاهزين، لا يزالان يعملان فقط على حاسوبك المحلي. في الفصول التالية، سنتعلم كيفية **نشر** هذه الخدمات التي بُنيت بجهد كبير **على خوادم الإنترنت العامة**، بحيث يمكن للمستخدمين حول العالم الوصول إلى منتجك. +::: diff --git a/docs/ar-sa/stage-2/backend/database-supabase/index.md b/docs/ar-sa/stage-2/backend/database-supabase/index.md new file mode 100644 index 0000000..7fda672 --- /dev/null +++ b/docs/ar-sa/stage-2/backend/database-supabase/index.md @@ -0,0 +1,1742 @@ +# من قاعدة البيانات إلى Supabase + +在上节课中,我们学会了 UI 设计程序 Mastergo 和 Figma 的基本用法,能够使用 github 进行代码的获取与版本管理,并通过 Zeabur 部署网站将自己的应用 / 网站传达给更多人使用。 + +为了帮助大家更好地衔接知识,在开始本节课关于设计工具与部署的新内容前,让我们一起通过几道简单的题目快速回顾一下上节课的核心知识点: + +1. 什么是前端设计工具、Figma、MasterGo 的定义和使用方式。 +2. 将设计稿转换为代码的基础方法。 +3. 什么是 Github,如何配置 SSH,如何构建自己的第一个仓库。 +4. 部署是什么意思,如何使用 Zeabur,如何将 Github 或本地代码部署至公共网络给大家访问。 + +如果对以上任何一个问题还有印象模糊的地方,建议先回顾一下上节课的文档和讲义。欢迎随时在微信学习群中提出疑问。 + +在本节课中,我们将学习如何让一个 APP / 网站从能跑起来变为更接近真实线上产品:除了用数据库管理程序运行中的各种数据变化外,还要具备完善的用户体系(注册、登录、权限等)以及其他关键后端能力。我们会以 Supabase 这一后端服务平台为主线,先用它实现“数据库 + 用户系统”这两项基础功能,再以 Supabase 提供的组件为参照,进一步理解现代云服务后端服务通常包含的核心模块,以及各模块的具体职能与作用逻辑。 + +# ما ستتعلمه + +1. 什么是数据、什么是数据库,常见数据库与使用方法 +2. 什么是 supabase,如何使用 supabase 进行基础的数据库操作 +3. 如何使用 supabase 为应用添加基础用户管理功能 +4. 学会 Supabse 进阶功能:realtime、storage、edge function +5. 学会为Supabase增加 google 与 github 登录支持 + +- 一款支持用户注册 / 登录,并能将数据存入在线数据库的基础应用 +- 一套可复用的 Supabase 后端代码模板(数据库 + 用户管理等),供后续项目直接套用 + +# 1. 什么是数据库 + +## 1.1 什么是数据 + +在数字世界里,数据(Data)无处不在。简单来说,数据是معلومة的载体。你朋友的联系方式、一篇微信文章、一条短视频、游戏里的角色等级,这些都是数据。在我们的应用中,数据就是需要被记录和管理的一切معلومة,比如用户的个人资料、订单历史、程序设置等。 + +一般而言,数据在程序中有不同的表现形式,最简单的就是变量,我们可以用不同变量记录简单的数字: + +```python +# Python variable definition examples + +# Integer variable: stores age information +age = 30 + +# Boolean variable: stores status (whether active) +is_active = True # True means active, False means inactive + +# List variable: stores a set of score data +scores = [85, 92, 78, 90] # Contains 4 integer elements representing different scores + +# Dictionary variable: stores multiple related information of a user +user_info = { + "age": 30, # Key "age" corresponds to the value of age + "height": 1.80, # Key "height" corresponds to the value of height (unit: meter) + "login_count": 156 # Key "login_count" corresponds to the value of login times +} +``` + +而对于上述所说的个人资料、订单历史这类复杂的数据而言,我们可以用更复杂的表格进行数据的表示: + +| user_id | name | email | +| ------- | ----- | ----------------- | +| 1001 | Alice | alice@example.com | +| 1002 | Bob | bob@example.com | + +| order_id | user_id | amount | status | +| -------- | ------- | ------ | --------- | +| 901 | 1001 | 29.99 | completed | +| 902 | 1002 | 15.50 | pending | + +但对于结构复杂、具有层级关系或字段不固定的数据,我们可以用 JSON 格式进行描述 —— 它是互联网通用的数据中间格式,几乎所有程序都能读取解析,跨系统传数据很方便。例如,一个订单可能包含多个商品,每个商品又有自己的名称、数量和价格。用传统的表格来表示会很笨拙:要么得拆成 “订单表”“商品表” 多张表,靠关联字段才能体现 “订单包含商品” 的关系;要么在一张表用 “商品 1 名称、商品 1 价格、商品 2 名称……” 这类冗余字段,遇到商品数量不固定时根本没法适配;而 JSON 能直接用嵌套结构把 “订单 - 商品 - 商品属性” 的层级说清,既直观又灵活。 + +```json +{ + "order_id": 901, + "user_id": 1001, + "amount": 29.99, + "status": "completed", + "items": [ + { "sku": "BG-001", "name": "牛肉汉堡", "quantity": 1, "price": 18.00 }, + { "sku": "SD-003", "name": "炸薯条", "quantity": 1, "price": 6.99 }, + { "sku": "DK-002", "name": "可乐", "quantity": 1, "price": 5.00 } + ], + "shipping_address": { + "street": "科技园路123号", + "city": "深圳", + "zip_code": "518057" + } +} +``` + +更进一步的,如果我们考虑一个被编码成向量(Vector)的数据,向量数据通常是文本、图片或音频等非结构化数据经过 AI 模型(如 Embedding 模型)处理后得到的数值表示。它的表示形式可能是: + +`[0.123, -0.456, 0.789, ..., -0.234]` (一个由几百甚至上千个浮点数组成的数组) + +总的来说,在现实世界中有太多不同形态、用途的数据值得我们详细分析,每种数据可能都需要专门的数据库用于存储,具体可参考下图——是不是感觉非常多? + +![](/zh-cn/stage-2/backend/database-supabase/images/image1.png) + +## 1.2 为什么我们需要数据库 + +我们已经了解到真实世界中的数据往往结构复杂,**为了高效存储与使用这些数据,我们需要一个专门的程序或容器来管理它们** —— 这便是数据库(Database)的诞生初衷。数据库本质上是一款特殊程序,核心作用就是对数据进行规范化组织、安全存储、系统化管理,并支持高效查询调用。 + +想象一下,若没有数据库,应用数据会陷入怎样的困境?当用户关闭浏览器或退出应用时,所有临时加载的معلومة都会直接丢失;我们既无法永久保存用户的使用状态(比如登录معلومة、个性化设置),也没法在不同用户之间共享关键数据(比如商品库存、订单记录)。我们需要有一个装置帮我们存储所有的数据! + +更灵活的是,数据库的部署方式可按需选择:既可以部署在本地服务器,满足数据本地化管理的需求;也能部署到云端,云端数据库支持弹性扩容(Scale),可随数据量与访问量增长扩展能力、承载海量数据与高并发,即便用户量大幅提升,也能保障用户的正常使用体验。 + +归纳而言,数据库凭借高效的持久化存储、精细化管理与快速查询能力,主要解决了以下السؤال الجوهري: + +- **数据的持久化存储** : 如果没有数据库,数据将仅存在于应用的内存中,一旦应用关闭,数据就会丢失。数据库解决了这个问题,它将数据持久地存储在硬盘等存储介质上,确保了数据的长期保存,降低了丢失风险。 +- **便捷的数据查询与分析** : 数据库提供了强大的查询语言(如 SQL),让用户可以轻松、高效地对海量数据进行复杂的查询、筛选和分析,从而帮助企业做出更明智的决策。 如果没有数据库,从大量无序文件中查找特定معلومة将是一项极其耗时且困难的任务。 +- **支持高性能与高并发访问** : 数据库通过索引优化、查询缓存、连接池以及分布式架构等技术,能够在毫秒级时间内响应查询请求,并支撑成千上万用户的并发访问。这对于现代互联网应用(如电商平台秒杀活动、社交网络实时动态)至关مهم,确保了系统的响应速度和用户体验。如果没有数据库的高性能支撑,面对海量用户请求时系统将会出现严重延迟甚至崩溃。 +- **保证数据的完整性和一致性** : 数据库通过一系列机制(如约束、触发器)来确保数据的准确性和一致性。 这意味着数据库中的数据必须符合预设的规则,例如,用户的年龄必须是数字,订单号必须是唯一的,从而有效防止了非法或无效数据的产生。 +- **确保数据的安全性** : 数据库提供了强大的安全机制,包括用户身份验证、访问控制和数据加密等,以保护数据免受未经授权的访问、修改或破坏。为了应对硬件故障、人为失误或恶意攻击等意外情况,数据库还提供了数据备份和恢复功能。 通过定期备份,可以在数据丢失或损坏时及时恢复,保障了业务的连续性。 + +## 1.3 关系型数据库与非关系型数据库 + +前面我们已经了解了数据库的核心价值、部署方式与弹性优势,而在实际选择时,首先要面对的就是数据库的两大核心类别:关系型数据库与非关系型数据库(NOSQL),我们可以用简单的两段话简单理解他们的区别: + +关系型数据库就像结构严谨的Excel表格,所有数据必须预先定义好格式(定义好 Schema 的内容, 比如要有姓名和年龄,且姓名必须是文字,年龄必须是数字),并通过关联字段(用来连接不同表格的标识,如身份证号)将不同表格连接起来。它的好处是数据精确可靠,特别适合银行转账、库存管理等不能出错的场景,但缺点是调整结构比较麻烦,海量数据下性能会受限。 + +非关系型数据库则像灵活的文件夹,可以存放格式各异的文档、图片或键值对(类似字典的"词-解释"结构),不需要提前规定好每份数据的结构。它更容易应对快速变化的需求和超大规模数据(比如社交媒体的海量帖子),扩展(增加服务器提升性能)起来也更方便,但牺牲了部分关联查询能力(跨不同数据表整理معلومة的能力)和一致性保障(确保数据时刻准确不矛盾),适合对容错性要求较高的互联网应用。 + +那么,实际应用中该如何选择数据库?从场景划分الخلاصة来看,关系型数据库常见于金融交易、库存管理、订单处理、账务系统等需要强一致性、复杂事务处理以及频繁读写均衡访问的场景;而非关系型数据库更适配社交媒体内容存储、实时日志分析、物联网海量数据写入、推荐系统特征读多写多等高并发、读写模式不均衡且结构灵活的需求。 + +但对于企业而言,在初级阶段并不需要花大量时间思考什么需要使用什么数据库。当前的数据库已是非常成熟的产品服务,最直接的方式是咨询不同云服务厂商(指提供服务器、存储、数据库、软件、算力等 IT 资源与技术服务的服务商)。我们可直接对接云服务官方销售,根据自身产品业务需求匹配适配的数据库方案;而构建企业级应用的便捷路径,便是优先与专业厂商合作。(需ملاحظة:企业级服务价格通常较高,建议先多方调研对比,也可选择购买服务器自行部署开源数据库程序作为替代方案。) + +我们也可参考某家云厂商的[数据库选型推荐](https://help.aliyun.com/zh/govcloud/getting-started/select-database-services),根据场景可进行不同数据库类型的选择,你可以对比不同云厂商的数据库规格选出最合适的进行使用。 + +| 数据库类型 | 数据库名称 | 价格 | 适用场景 | +| ------------ | ---------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 关系型数据库 | RDS MySQL版 | 低 | 基础版:学习以及小型网站高可用版:一定业务压力的中型数据库场景集群版:业务不允许中断,访问压力较大 | +| | RDS SQL server版 | 高 | 基础版:测试以及小型商业化网站高可用版:企业级商业化网站集群版:企业业务不允许中断,访问压力较大 | +| | RDS PostgreSQL版 | 最低 | 基础版:学习以及小型网站高可用版:一定业务压力的中型数据库场景集群版:业务不允许中断,访问压力较大的场景,其性能较一般MySQL高 | +| | RDS PPAS版 | 高 | 通用型:兼容Oracle业务,但业务压力Udacity,虚拟化可以满足其需求独享型:面对需要独享物理机的业务,一般为高并发Oracle类业务 | +| | DRDS | 中 | 入门版本:4 Core 8 G,价格亲民,适合中小型在线业务企业版:16 Core 32 G,复杂 SQL 响应好,适合超高并发在线业务至尊版:32 Core 64 G,复杂 SQL 执行响应最好,提供超大规格选择 | +| NoSQL数据库 | Redis | 中 | 双机热备Redis:一般作为持久化数据库提高业务可用性集群版本的Redis:一般作为缓存层,加速应用访问,解决一般数据库无法负载的读取压力 | +| | MongoDB版 | 中 | 单节点实例单节点:适用于开发、测试及其他非企业核心数据存储的场景副本集实例:适用于某些业务场景下对数据库有更高读取性能需求,如阅读类网站、订单查询系统等读多写少场景或有临时活动等突发业务需求分片集群实例:基于多个副本集(每个副本集沿用三副本模式)组成的分片集群实例,提供更高的读取性能需求,为实时在线业务提供高速读取性能 | + +光说不易理解,我们通过一个具体的“博客文章”场景,来看看同样的数据在关系数据库 (SQL) 和不同类型的非关系数据库 (NoSQL) 中是如何存储的。 + +假设我们有一个博客平台,需要存储以下معلومة: + +- 用户(Users):用户 ID、用户名、邮箱 +- 文章(Posts):文章 ID、标题、内容、作者 ID +- 评论(Comments):评论 ID、评论内容、评论者 ID、所属文章 ID +- 标签(Tags):标签 ID、标签名 +- 文章与标签的关系:单篇文章关联的多个标签、单个标签对应的多篇文章 + +### 关系数据库 (SQL) مثال + +在SQL数据库中,我们会将不同类型的数据分别存储在不同的表中,并通过“外键”将它们关联起来。这种结构清晰、规范,减少了数据冗余。 + +以 “内容平台的文章管理” 为例,我们不会把 “用户、文章、评论、标签” 混存,而是拆成 5 张功能单一的表,每张表都有明确的 “职责边界” 和严格的结构定义(Schema): + +- `users` 表 (存储用户معلومة) + +| user_id (主键) | username | email | +| -------------- | -------- | ----------------- | +| 101 | Alice | alice@example.com | +| 102 | Bob | bob@example.com | + +- `posts` 表 (存储文章معلومة) + +| post_id (主键) | title | content | author_id (外键) | +| -------------- | --------- | ------------------------------ | ---------------- | +| 1 | 初识SQL | 这是关于SQL数据库的一篇文章... | 101 | +| 2 | NoSQL入门 | NoSQL提供了灵活的数据模型... | 102 | + +- `comments` 表 (存储评论معلومة) + +| comment_id (主键) | body | commenter_id (外键) | post_id (外键) | +| ----------------- | ---------------- | ------------------- | -------------- | +| 1001 | 写得很棒! | 102 | 1 | +| 1002 | 学习了。 | 101 | 2 | +| 1003 | 有没有更多例子? | 101 | 1 | + +- `tags` 表 (存储标签) + +| tag_id (主键) | tag_name | +| ------------- | -------- | +| 51 | 数据库 | +| 52 | 技术 | +| 53 | 入门 | + +- `post_tags` 表 (存储文章与标签的多对多关系,体现联表特点) + +| post_id (外键) | tag_id (外键) | +| -------------- | ------------- | +| 1 | 51 | +| 1 | 52 | +| 2 | 51 | +| 2 | 52 | +| 2 | 53 | + +若需查询 “Alice 发表的《初识 SQL》(post_id=1)的完整معلومة(含文章内容、作者、评论、标签)”,需执行多表连接(JOIN)查询,通过外键关联 5 张表并聚合数据,SQL 语句如下: + +```sql +SELECT + p.title, + p.content, + u.username AS author, + c.body AS comment, + t.tag_name AS tag +FROM + posts p +JOIN + users u ON p.author_id = u.user_id +LEFT JOIN + comments c ON p.post_id = c.post_id +LEFT JOIN + post_tags pt ON p.post_id = pt.post_id +LEFT JOIN + tags t ON pt.tag_id = t.tag_id +WHERE + p.post_id = 1; +``` + +这个查询会跨越5个表,将所有相关数据聚合在一起返回。这是关系数据库的核心优势:通过规范化和连接操作,可以灵活地进行各种复杂的查询,同时保证了数据的一致性和最小冗余。 + +### 非关系数据库 (NoSQL) مثال + +NoSQL 数据库(如 MongoDB、Redis)的设计思路与 SQL 相反,它不强调数据的拆分与规范,通常会将业务上相关联的所有数据打包聚合在一起,以减少查询时的连接操作,从而提高读取性能。 + +在 NoSQL 数据库中,文档数据库(Document Database) 是最常用的类型之一,MongoDB 就是典型代表。它以 “文档” 作为基本存储单元,这里的 “文档” 并非我们日常理解的 “文章”,而是一种类似 JSON 的数据结构(MongoDB 中实际使用 BSON 格式,支持更多数据类型):无需预先定义统一的 Schema(数据结构),每个文档的字段可以灵活增减,字段类型也能自由调整,完美适配数据格式多变的场景。 + +在文档数据库中,通常会将一篇文章及其所有相关معلومة(如评论、标签)存储在一个文档中(文档格式类似 JSON,可灵活定义字段,无需预先制定 Schema),核心逻辑是 “将‘一个业务场景下的完整معلومة’存放在一个文档中”,避免查询时的多数据源拼接。 + +`posts` 集合中的一个文档مثال: + +```json +{ + "_id": 1, + "title": "初识SQL", + "content": "这是关于SQL数据库的一篇文章...", + "author": { + "user_id": 101, + "username": "Alice", + "email": "alice@example.com" + }, + "tags": [ + "数据库", + "技术" + ], + "comments": [ + { + "comment_id": 1001, + "body": "写得很棒!", + "commenter": { + "user_id": 102, + "username": "Bob" + } + }, + { + "comment_id": 1003, + "body": "有没有更多例子?", + "commenter": { + "user_id": 101, + "username": "Alice" + } + } + ] +} +``` + +这种设计的优势非常直观:当你需要获取 “第一篇文章的完整معلومة(含作者、评论、标签)” 时,只需通过 `_id:1` 查询这一个文档,数据库一次读取就能返回所有数据,无需像 SQL 那样执行 3-4 次表连接操作,读取效率大幅提升。 + +但它也存在明显的 trade-off(取舍):由于数据是 “聚合存储”,会不可避免地产生数据冗余—— 比如作者 “Alice” 的 `username` 被嵌入到她写的每一篇文章文档中,如果某天 “Alice” 将用户名改为 “Alice_New”,理论上需要遍历所有包含她معلومة的文章文档,逐一更新 `author.username` 字段,不仅操作繁琐,还可能因网络或服务器问题导致部分文档更新失败,出现 “同一用户在不同文章中用户名不一致” 的情况。 + +不过在实际业务中,这种冗余往往是 “可接受的”:对于博客、资讯、电商商品详情等 “ **读多写少** ” 的场景(用户查看内容的次数远多于作者修改用户名的次数),用少量的冗余换取 “极致的读取性能” 是更优的选择;而如果是 “写多读少”(如频繁修改用户معلومة)的场景,则需要结合业务需求权衡是否使用文档数据库。 + +以上是对不同数据库的简单介绍,如果你对更多具体的数据库类型感兴趣,你可以参考如下资料尝试不同类型的数据库。 + +Examples of SQL databases: +[Db2](https://www.ibm.com/products/db2-database)、[MySQL](https://cloud.ibm.com/catalog#highlights)、[PostgreSQL](https://www.ibm.com/think/topics/postgresql)、[YugabyteDB](https://www.yugabyte.com/)、[CockroachDB](https://www.cockroachlabs.com/)、[Oracle Database](https://www.ibm.com/products/postgres-enterprise)、[Azure SQL Database](https://www.ibm.com/consulting/microsoft) + +Examples of NoSQL databases: +[Redis](https://www.ibm.com/think/topics/redis)、[CouchDB](https://www.ibm.com/think/topics/couchdb)、[MongoDB](https://www.ibm.com/think/topics/mongodb)、[Cassandra](https://cloud.ibm.com/catalog#highlights)、[Elasticsearch](https://www.ibm.com/think/topics/elasticsearch)、[BigTable](https://www.techtarget.com/searchdatamanagement/news/252512583/Google-scales-up-Cloud-Bigtable-NoSQL-database)、[Neo4j](https://neo4j.com/users/ibm/)、[HBase](https://www.ibm.com/think/topics/hbase) + +# 2. Supabase + +在前面我们已经介绍了几类常见的数据库,以及它们各自适合的使用场景。不过在真实项目里,数据库通常只是后端体系中的一个基础模块:除了存储和查询数据,你还需要解决**用户注册登录、权限校验、文件上传与存储、对外 \*\***API\***\* 接口、甚至定时任务、实时通知**等一整套问题。仅仅选好数据库,并不能让你的应用“立刻就能上线运行”,中间还隔着一大圈繁琐的后端工程工作。 + +所以,我们需要考虑一个更大的背景: **后端服务** 。一个完整的应用,通常都由“前端 + 后端”组成:前端负责页面展示和用户交互,后端则负责数据存储、用户登录、业务逻辑处理等。过去,开发者往往需要自己搭建服务器、配置数据库、设计并实现 API,还要手动处理权限管理、安全策略、扩展性和监控运维等事务,整个过程既重复又耗时。为了解决这些重复劳动,业界出现了 **BaaS(Backend as a Service,后端即服务)** :把数据库、用户认证、文件存储、实时能力等常见后端功能打包成一个云端平台,开发者通过 SDK / API 就能直接调用这些能力,而无需从零搭建和运维基础设施。 + +在这个背景下,[Supabase](https://supabase.com/) 就可以看作是新一代的 BaaS 代表:它以 PostgreSQL 作为核心数据库,在其之上集成了 Auth、Storage、Realtime、Edge Functions、Vector 等一整套后端能力,为开发者提供一个“以 Postgres 为中心的一站式后端平台”。接下来,我们就从这个角度出发,从“只选数据库”升级到“选择完整的后端开发平台”,具体看看 Supabase 能帮我们省掉哪些工作,又是如何让一个项目从原型到可用产品的距离大幅缩短的。 + +## 2.1 分步指南 + +在清晰把握 Supabase 的整体定位后,接下来我们将沿着 Supabase 控制台的操作路径,逐项拆解它具体提供哪些核心能力,以及每项能力对应的核心职责。我们会详细介绍 supabase 涉及的每个选项,帮助你快速入门 supabase 的基本操作。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image2.png) + +访问 Supabase 官网并登录后,在控制台首页点击 New project 进入创建流程; + +输入需要配置的主要内容 Project Name、数据库密码,地址只需要选择为与程序目标用户最接近的区域即可。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image3.png) + +创建成功后,控制台左侧侧边栏将显示所有核心功能模块(Table Editor、SQL Editor、Database、Authentication 等),后续操作将围绕这些模块展开。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image4.png) + +### 表编辑器 + +Table Editor 可以当成是 Supabase 的可视化数据表编辑器,它能让你像操作 Excel 一样直接查看和修改数据库里的数据,无需编写 SQL 语句,只需要用鼠标交互即可修改数据内容。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image5.png) + +其中值得关注的是 Schema,Schema 可理解为数据库内的 “资源容器”,用于对表、视图、函数、索引等资源进行分组管理,主要作用有二:一是避免命名冲突(不同 Schema 下可存在同名table),二是实现权限隔离(如仅允许特定用户访问某 Schema 下的表); + +点击编辑器顶部的 Schema 下拉框可切换不同容器,日常开发中一般只需关注两类: + +- `public`:默认的公共资源容器,开发者新建的业务表(如 “文章表”“评论表”)均存储于此; +- `auth`:用户认证专属容器,其中的 `users` 表自动存储所有注册用户معلومة(如用户 ID、邮箱、登录时间),不建议手动修改此 Schema 下的默认表,避免影响认证功能; + +![](/zh-cn/stage-2/backend/database-supabase/images/image6.png)![](/zh-cn/stage-2/backend/database-supabase/images/image7.png) + +### SQL 编辑器 + +SQL Editor 作为 Supabase 的 SQL 语句执行器,可让你用代码的方式直接操作数据库。你可以让大模型直接生成 SQL 语句,在右侧输入后点击 RUN 即可用语句创建或修改 table,也可以直接在 Results 中直接看到筛选出的 table 数据。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image8.png) + +你可以在运行 RUN 之后,在 Table Editor 的 public schema 里找到新建后的数据表;并且运行后的语句会保存在左侧的 PRIVATE 栏中,甚至可以点击下方的爱心标志对这一条查询或创建语句进行收藏。 + +### 数据库管理中心 + +Database 是 Supabase 的数据库管理中心,支持可视化地查看和管理所有数据表,并通过表的相互连线理解不同表间的关联关系(即外键约束,表示数据间的引用关系)。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image9.png) + +如果你想要手动新建 table,可以在 tables 中直接新建表格,我们会在之后的教程中详细讲解。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image10.png) + +### 身份认证 + +Authentication 负责管理用户的注册、登录和权限。默认的用户管理系统数据都在此处存储,它提供了开箱即用的用户注册、登录、密码重置、邮箱验证等功能,并支持第三方 OAuth 登录(如微信、GitHub、Google 等)。所有用户数据会自动同步到数据库的 `auth.users` 表中。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image11.png) + +你可以在 Provider 选项中找到不同 supabase 支持的用户معلومة登录入口,默认使用 Email;如果你想使用 Github 或者 Google 账户进行登录,还需要更多属性配置,我们会在下面的课程中进行详细讲解。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image12.png) + +在 Sign In / Providers 里还包含了对注册邮箱行为的控制,如果你不想每次邮箱注册都必须让用户接受邀请后才能成为用户,你可以取消 Confirm email 的强制要求。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image13.png) + +如果你想切换非 Supabase 的其他 auth 系统服务商,你可以点击 Third Party Auth,比如此处就使用 Clerk 作为第三方的系统服务商。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image14.png) + +如果你担心注册用户在短期内访问量过大,你可以在 Rate Limits 中启用对应的流量限制策略: + +![](/zh-cn/stage-2/backend/database-supabase/images/image15.png) + +### 存储 + +Storage 是 Supabase 的存储系统,兼容 amazon cloud 的 s3 概念,可用于存储任意类型的文件(如图片、视频、文档、音频等),并提供访问权限管理(公开或私有)和下载链接获取(永久链接或临时链接),你能够很方便在应用中对用户涉及到的文件内容进行上传与下载管理,并与 Supabase 的认证系统无缝集成,实现精细化的访问控制。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image16.png) + +我们将会在本节课的进阶 project 中讲解 storage 的具体用法。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image17.png) + +如果你想使用 S3 的相关协议进行操作,可以直接使用对应的配置: + +![](/zh-cn/stage-2/backend/database-supabase/images/image18.png) + +> Amazon Cloud(亚马逊云服务,简称 AWS)是亚马逊提供的云计算平台(就像一个大型的网络机房,你可以按需租用计算和存储资源)。S3(Simple Storage Service)是 AWS 里专门用来存储文件的服务(类似一个无限大的网盘,可以存图片、视频、备份等各种文件),它是目前最流行的对象存储服务,已经成为了事实上的行业标准。 +> +> **为什么要做成 S3 兼容 \*\***API\*\* ** ?** :S3 已经存在近 20 年,市面上有大量现成的工具、SDK 和文档,兼容 S3 意味着你可以直接用这些资源,不用从头开始制作各类相关工具,能够快速满足业务上线的需求。 + +### 边缘函数 + +如果你不想部署后端,但是想使用数据库和函数操作,你可以使用 Edge Functions 构建无需自建服务器的后端核心能力,它是 Supabase 提供的全球分布式服务端函数。简单来说,它让你无需购买和管理自己的后端服务器,就能直接编写并部署在云端的后端代码。这些函数部署在全球网络的边缘节点上,会自动在离你的用户最近的位置运行,从而大幅降低网络延迟,提供极致的响应速度。你可以在 Supabase 的仪表盘中直接创建、编辑和部署,整个开发流程非常便捷。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image19.png) + +Edge Functions 的一个核心用途是充当安全的中间层,保护你的敏感معلومة和鉴权密钥。在前端代码中直接调用第三方服务(如 OpenAI、Stripe)会暴露你的 API Key,带来极大的安全风险。通过 Edge Functions,你的前端应用只与你的 supabase 函数通信,所有秘密只在 supabase 中保管。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image20.png) + +Edge Functions 的函数使用 secrets 中暴露的密钥作为环境变量,通过 `Deno.env.get` 加载,从而实现第三方服务的调用。这样一来,敏感密钥就永远不会暴露在客户端(你的浏览器),彻底杜绝了被盗用的风险。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image21.png) + +请求 Supabase Edge Function 时,需在请求头携带对应的 Supabase 密钥,下面是一个极简مثال: + +```javascript +// 核心配置(替换为你的实际معلومة) +const projectId = "你的 Supabase 项目ID"; +const functionName = "目标 Edge Function 名称"; +const supabaseKey = "Supabase anon_key"; + +// 调用函数 +async function callEdgeFunction() { + const url = `https://${projectId}.supabase.co/functions/v1/${functionName}`; + + try { + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${supabaseKey}` // 关键:携带密钥完成认证 + }, + body: JSON.stringify({ order_id: "123", action: "refund" }) // 自定义请求数据 + }); + + const result = await response.json(); + console.log("调用成功:", result); + } catch (error) { + console.error("调用失败:", error.message); + } +} + +// 执行调用 +callEdgeFunction(); +``` + +此外,Edge Functions 与 Supabase 的用户认证系统无缝集成。当已登录的用户调用一个函数时,其身份معلومة会传递给函数。这使得你可以在函数内部轻松识别当前用户,并根据其身份执行权限控制。更مهم的是,函数在操作数据库时会自动遵循你设置好的行级安全策略(Row Level Security),确保用户只能访问和修改他们有权操作的数据,让构建安全的多用户应用变得简单。 + +Edge Functions 的应用场景非常广泛,能够处理各种后端任务。它们非常适合用来监听来自第三方服务的 Webhook 事件(例如支付成功、代码提交等),并自动执行相应的数据处理逻辑。你也可以用它来发送邮件通知、生成 PDF 报告、创建自定义的 API 接口来封装复杂的业务逻辑,或者执行任何你希望在服务端完成的计算任务,极大地扩展了你应用的能力。 + +具体到一个常见的例子:身份认证工具 Clerk 。Clerk 仅用于处理用户登录、注册、معلومة更新等认证相关操作,并不直接管理你的业务数据库。如果你想要将这些认证动态同步到业务数据库中,则需要通过触发 Webhook 事件请求 Edge Functions 实现。Edge Functions 能够监听 Clerk 发出的 Webhook 信号,自动执行数据同步逻辑,让 Supabase 数据库中的用户معلومة与 Clerk 登录状态实时对齐,全程无需你部署独立后端。 + +### 实时数据同步引擎 + +Realtime 是 Supabase 的实时数据同步引擎,它允许你的应用即时接收数据库的变化通知,而无需反复轮询 API。当数据库中的数据发生 `INSERT`、`UPDATE` 或 `DELETE` 操作时,Realtime 会通过 WebSocket 将这些变化实时推送给所有已连接的客户端。这对于构建需要实时交互的应用至关مهم。 + +Realtime 主要包含三大核心功能,覆盖了绝大多数实时场景: + +1. **Postgres Changes:** 直接监听数据库表的变化。你可以精确地订阅特定表、特定事件(增、删、改),甚至可以根据筛选条件来接收通知,并与行级安全策略(Row Level Security)完美集成,确保用户只能收到他们有权限查看的数据变更。 +2. **Broadcast:** 允许客户端之间通过频道(Channel)发送低延迟的临时消息。这非常适合实现聊天室、实时光标追踪、在线游戏状态同步等功能。 +3. **Presence:** 用于追踪和同步在线用户状态。你可以用它来轻松实现“谁在线上”、“当前有X人正在查看”等功能,非常适合协作类应用。 + +我们会在后续的项目制学习中详细介绍该部分的内容。 + +### 项目设置 + +Project Settings 是 Supabase 项目的高级配置部分,你可在此实现计算资源的深度调度,以及各类功能底层参数的精细化配置。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image22.png) + +在入门阶段,我们只需聚焦以下两个核心板块,一个是 Data API,我们在此可获取关键的 “Supabase URL”, 它是形如 `https://xxx.supabase.co` 的 RESTful 端点,是所有数据查询、新增、修改、删除操作的 “入口地址”。前端或服务端需通过该 URL 初始化 Supabase 客户端,建立与数据库的连接。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image23.png) + +另一个重点是 API Keys,选择 “Legacy anon, service_role API keys” 标签页,其中的 anon public 密钥 是前端场景的مهم身份凭证,它的权限被 RLS 严格限制,仅能访问用户被授权的数据。而 service_role 密钥属于 “服务端高权限密钥”,具备绕过行级安全的能力,可执行批量数据操作、系统级配置等敏感操作。绝对禁止公开分享,若泄露需立即生成新密钥并更新服务端配置。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image24.png) + +其余配置项在当前阶段无需深究,待后续有进阶使用需求时再逐一探索即可。 + +## 2.1 创建你的第一个 SQL 数据表 + +以上是 Supabase 的界面介绍,接下来我们将深入 Supabase 的核心数据库的操作环节。 + +在 Supabase 中创建数据表,主要有以下两种常用方式,你可以根据需求选择: + +1. (推荐)借助大语言模型生成适配 Supabase 的 SQL 语句,直接在 **SQL Editor(** 前文介绍的 SQL 语句执行器)中粘贴执行,高效快捷,我们会在下个部分环节重点说明这个操作过程。 +2. 通过可视化操作创建:在左侧侧边栏找到 Database 模块,点击进入后选中侧边栏的 Tables,在右侧点击 New table 按钮,即可通过图形化界面创建数据表。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image25.png) + +值得ملاحظة的是,对应数据表的名称以及存储的数据类型可在下方的 Columns 中指定。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image26.png) + +对于关系数据库,其中很مهم的特点是表与表之间的关联,你可以在下方找到 `Foreign keys` ,点击创建相应的关联关系: + +![](/zh-cn/stage-2/backend/database-supabase/images/image27.png) + +其中 `Foreign keys` 表达了表与表之间的关联关系:一个或一组字段,它在当前表(子表)中的值,会引用另一张表(父表)中主键的值。 + +例如,在创建 `学生表`的时候,我们可以这样定义外键:(`所属班级编号` 这一列是一个外键。这个外键引用了 `班级表` 里的 `班级编号` 这一列。) + +```sql +CREATE TABLE 学生表 ( + 学生学号 INT PRIMARY KEY, + 学生姓名 VARCHAR(50), + 所属班级编号 INT, + FOREIGN KEY (所属班级编号) REFERENCES 班级表(班级编号) +); +``` + +更具体举例而言,我们可以可视化观察对应的表的结构: + +班级表: +这张表里记录了所有班级的معلومة,每个班级都有一个独一无二的班级编号。班级编号就是这张表的主键 (Primary Key),是每个班级的唯一身份证。 + +| 班级编号 | 班级名称 | +| -------- | ---------- | +| 101 | 一年级一班 | +| 102 | 一年级二班 | + +学生表: +这张表记录了所有学生的معلومة。每个学生都属于一个特定的班级,对吗?那么我们怎么知道哪个学生在哪个班级呢? + +我们可以在学生表里增加一列,叫做 `所属班级编号`。 + +| 学生学号 | 学生姓名 | 所属班级编号 | +| -------- | -------- | ------------ | +| 2024001 | 张三 | 101 | +| 2024002 | 李四 | 102 | +| 2024003 | 王五 | 101 | + +在该例子中,学生表中的 `所属班级编号` 列就是外键 (Foreign Key)。 + +在 Supabse 中,点击添加 Foreign Key 后,你可直接选择进行关联表对应列的选取 + +![](/zh-cn/stage-2/backend/database-supabase/images/image28.png) + +## 2.3 SQL Editor 简介与数据库基本操作 + +接下来我们将分步执行一系列 SQL 脚本,熟悉常见的 SQL 中的增删查改操作。你可以将每个خطوة的代码复制到 SQL Editor 中,执行并观察النتيجة。 + +你可以在该目录下获得所有的测试 SQL 文件: + +https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos/tree/main/apps/sql-examples + +### **2.3.1 **`CREATE`** - 创建表结构** + +`CREATE TABLE` 语句用于为新表定义模式(Schema),包括其列(Columns)、对应的数据类型(Data Types)以及任何约束(Constraints),简单理解是创建了一个数据表。 + +```sql +-- Step 1: Create the 'orders' table +-- This file is fully independent and creates a sample table for later steps. +CREATE TABLE IF NOT EXISTS orders ( + id serial PRIMARY KEY, + user_id int NOT NULL, -- User ID + status text NOT NULL, -- Order status (e.g. paid, pending) + amount numeric(10, 2) NOT NULL, -- Order total amount + details jsonb, -- Item and extra details as JSON + placed_at timestamptz DEFAULT now(), -- Order creation time + is_paid boolean DEFAULT false -- Paid flag +); + +-- Expected Output: +-- Orders table created if it did not exist. +-- No data inserted. (Querying returns zero rows for now.) +-- If table already exists, no error occurs. +``` + +成功执行后,系统将نصيحة脚本مكتمل。你可以在 Table Editor 中看到对应的表被创建完成: + +![](/zh-cn/stage-2/backend/database-supabase/images/image29.png) + +### **2.3.2 **`INSERT`** - 填充初始数据** + +表结构创建完毕后,الخطوة التالية是使用 `INSERT INTO` 语句向表中添加数据行。 + +```sql +-- Step 2: Insert initial rows into the orders table +-- Provides realistic, varied data for demo/testing. All values are self-contained. +INSERT INTO orders (user_id, status, amount, details, placed_at, is_paid) VALUES + (2001, 'pending', 23.50, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '2 days', false), + (2002, 'paid', 50.00, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":2,"price":5.00}]}', now() - interval '1 day', true), + (2003, 'cancelled', 15.00, '{"items":[{"sku":"FRY001","name":"French Fries","qty":3,"price":5.00}], "reason":"Not available"}', now() - interval '45 days', false), + (2004, 'paid', 22.98, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":2,"price":9.99}], "promo":"SUMMER22"}', now() - interval '10 days', true), + (2005, 'pending', 18.75, '{"items":[{"sku":"SAL001","name":"Salad","qty":1,"price":6.75},{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '7 hours', false), + (2006, 'paid', 8.00, '{"items":[{"sku":"DRK002","name":"Cola","qty":2,"price":4.00}]}', now() - interval '3 hours', true), + (2007, 'refunded', 14.50, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99},{"sku":"FRY001","name":"French Fries","qty":1,"price":4.51}], "refund_reason":"Late delivery"}', now() - interval '15 days', false), + (2008, 'paid', 26.99, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":1,"price":6.99}]}', now() - interval '12 days', true), + (2009, 'pending', 9.99, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99}]}', now() - interval '30 minutes', false), + (2010, 'paid', 19.89, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00},{"sku":"DRK002","name":"Cola","qty":2,"price":3.95}]}', now() - interval '5 days', true), + (2011, 'cancelled', 0.00, '{"items":[], "reason":"User cancelled"}', now() - interval '2 days', false); + +-- Expected Output: +-- After running this script, SELECT * FROM orders will show about 11 rows with varied user_id, status, amount, details (JSON), placed_at, and is_paid fields. +-- For example: +-- | id | user_id | status | amount | is_paid | placed_at | +-- |----|---------|-----------|--------|---------|---------------------| +-- | 1 | 2001 | pending | 23.50 | false | 2025-10-28 13:40:00Z| +-- | 2 | 2002 | paid | 50.00 | true | ... | +-- |... | ... | ... | ... | ... | ... | +``` + +执行成功后,此时表中已经插入了原始数据,你可以进入到 Table Editor 界面刷新后看到النتيجة,也可以直接在 SQL Editor 界面中新建窗口,执行查询语句 `SELECT * FROM orders;`查看النتيجة: + +![](/zh-cn/stage-2/backend/database-supabase/images/image30.png) + +### **2.3.3 **`SELECT`** - 读取与查询数据** + +`SELECT` 语句用于从表中检索数据。通过使用不同的子句,可以实现对数据的精确筛选、排序和格式化,我们可参考以下语句一步步执行查看النتيجة: + +```sql +-- Step 3: SELECT query examples for the orders table + +-- Example 1: Select all fields for all orders +SELECT * FROM orders; +-- Expected Output: Returns all rows and fields. Columns: id, user_id, status, amount, details, placed_at, is_paid. + +-- Example 2: Select only pending orders +SELECT id, user_id, amount FROM orders WHERE status = 'pending'; +-- Expected Output: All rows with status 'pending'; columns: id, user_id, amount. + +-- Example 3: Select specific fields and filter by payment status +SELECT id, status, is_paid, amount FROM orders WHERE is_paid = true; +-- Expected Output: All rows where is_paid is true; columns: id, status, is_paid, amount. + +-- Example 4: Extract all item names from the details (JSON) for each order +SELECT id, details -> 'items' AS item_list FROM orders; +-- Expected Output: Each row shows id and an array from JSON with item details. +``` + +- **مثال 1:** 返回 `orders` 表中的所有行和列,与الخطوة الثانية的输出类似。 +- **مثال 2:** 仅返回状态为 'pending' 的订单,且只包含指定的列: + +![](/zh-cn/stage-2/backend/database-supabase/images/image31.png) + +- **مثال 3:** 仅返回已支付的订单,并显示指定的列: + +| id | status | is_paid | amount | +| --- | ------ | ------- | ------ | +| 2 | paid | true | 50.00 | +| 4 | paid | true | 22.98 | +| 6 | paid | true | 8.00 | +| 8 | paid | true | 26.99 | +| 10 | paid | true | 19.89 | + +- **مثال 4:** 返回每个订单的 `id` 和从 `details` 字段中提取的 `items` 数组: + +| id | item_list | +| --- | -------------------------------------------------------------------------------------------------------------------- | +| 1 | `[{"qty":1,"sku":"BGR001","name":"Beef Burger","price":12}]` | +| 2 | `[{"qty":2,"sku":"BGR002","name":"Chicken Burger","price":10},{"qty":2,"sku":"DRK001","name":"Lemonade","price":5}]` | +| 3 | `[{"qty":3,"sku":"FRY001","name":"French Fries","price":5}]` | +| ... | ... | + +### **2.3.4 **`INSERT`** - 插入单条记录** + +在 2.3.2 中,我们演示的是开头时刻初始化批量插入数据,现在我们查看如何新增插入单条数据。 + +```sql +-- Step 4: INSERT a new order (single row) +-- Example: Add a new paid order for user 2012 with one Chicken Burger +INSERT INTO orders (user_id, status, amount, details, is_paid) +VALUES ( + 2012, 'paid', 9.99, + '{"items":[{"sku":"BGR002","name":"AIID Burger","qty":100,"price":1000}]}', + true +); +-- Expected Output: +-- Before (table fragment): +-- | id | user_id | status | amount | is_paid | +-- | ...| ... | ... | ... | ... | +-- +-- After (last row): +-- | id | user_id | status | amount | is_paid | +-- | xx | 2012 | paid | 9.99 | true | +-- (where xx = next serial value) +``` + +此时再用 `SELECT * FROM orders;` 对数据进行查询,我们可以看到 orders 表成功从 11 个数据变成了 12 个数据。 + +### **2.3.5 **`UPDATE`** - 修改现有数据** + +在实际工作中,我们需要对数据表进行频繁数据更新,我们能够用 `UPDATE` 语句修改表中已存在的记录。 + +```sql +-- Step 5: UPDATE example +-- Example: Mark order with id=1 as paid and update its status +UPDATE orders SET status = 'paid', is_paid = true WHERE id = 1; +-- Expected Output: +-- Before (row with id=1): +-- | id | status | is_paid | +-- | 1 | pending | false | +-- After (row with id=1): +-- | id | status | is_paid | +-- | 1 | paid | true | +-- All other rows remain unchanged. +``` + +### **2.3.6 **`DELETE`** - 删除数据** + +`DELETE` 语句可用于从表中移除记录,并结合条件对指定部分的数据进行修改。 + +```sql +-- Step 6: DELETE example +-- Example: Delete orders older than 2 days to clean up old data +DELETE FROM orders WHERE placed_at < now() - interval '2 days'; +-- Expected Output: +-- Before (filtered for affected rows): +-- | id | status | placed_at | +-- | 3 | shipped | 2025-10-13 ... | <-- will be deleted +-- +-- After: +-- No such rows remain. SELECT * FROM orders WHERE placed_at < now()-interval '2 days' yields zero rows. +-- Other rows in orders table are unaffected. +``` + +执行前,你可先执行 `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';` 进行数据表筛选النتيجة的查看。当运行 `DELETE` 命令后,再次执行相同的 `SELECT` 查询 `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';`,将返回一个空的النتيجة,表明这些行已被成功删除。 + +## 2.4 行级安全 + +在学习了数据库的基本操作后,我们需要进一步深入一个保障数据安全的核心概念 ——RLS(行级安全,Row Level Security)。 + +不妨先思考一个实际场景中的关键问题:如何实现数据的 “隔离访问”?比如,只允许用户 A 查看自己的数据,而无法看到用户 B 的معلومة;再比如,即便某角色拥有数据库的访问权限,如何避免其误操作或泄露其他用户的敏感数据? + +RLS 正是为解决这类数据安全与隔离需求而生。它允许开发者为数据库表定义精细化的安全策略,根据用户的身份معلومة(如用户 ID、角色权限等),精确控制哪些用户能访问、修改表中的哪些行数据。 +举个典型مثال:对于订单表(`orders`),我们可以定义这样一条 RLS 策略 ——“仅当 `orders` 表中某条记录的 `user_id` 列,与当前登录用户的 ID 完全一致时,该用户才能查询到这条订单数据”,从而实现 “用户只能看自己的订单” 的核心需求。 + +当你为某张表启用 RLS后,该表的所有数据操作请求(包括 `SELECT` 查询、`INSERT` 新增、`UPDATE` 修改、`DELETE` 删除)都会触发 RLS 校验:必须通过至少一条安全策略的检查,操作才能执行。若不存在允许该操作的策略,或请求未满足任何策略的条件,数据库会直接拒绝此次操作,从底层阻断非授权访问。 + +在 Supabase 中,RLS 与用户认证系统深度绑定,使用起来更为便捷。Supabase 提供了一个专用函数 `auth.uid()`,它能直接返回 “当前发起请求的已登录用户” 的唯一 ID(格式为 UUID)。借助这个函数,我们可以轻松编写策略,实现 “数据行与用户身份” 的精准关联(比如前文提到的 “订单 `user_id` 匹配当前用户 ID”)。 + +启用 RLS 策略的方式很灵活,你可以在 Supabase 数据库管理界面中的 “RLS” 按钮,直接配置并启用策略: + +![](/zh-cn/stage-2/backend/database-supabase/images/image32.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image33.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image34.png) + +主动配置难免显得麻烦,通常,我们在数据表语句创建、初始化的时候就会自动考虑植入对应的 RLS 策略。我们只需在 SQL Editor 中执行类似如下语句,即可自动开启对应数据表的行级安全策略。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image35.png) + +# 3. 第一个 SQL 应用 + +掌握了数据库基础操作与RLS核心逻辑,我们终于进入本次教程的实践环节。漫长的学习铺垫是为了让后续“从0到1搭建应用”的过程更清晰。接下来,我们将以“汉堡店订单管理”为场景,手把手演示Supabase的常见操作:从应用与Supabase的关联配置,到数据库与登录功能的集成,逐步学习不同操作逻辑。 + +## 3.1 克隆并运行 Supabase مثال项目 + +要开展实操,首先需要获取配套的演示代码仓库。你可以让 Trae 或 Claude Code 协助 git clone 以下仓库:https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos + +若已配置 SSH 密钥,建议使用 SSH 地址进行 clone(git@github.com:THU-SIGS-AIID/Project5-Supabase-Demos.git)以提升安全性;若 SSH 或 HTTPS 连接遇到网络问题,可以直接点击仓库页面的 “Download ZIP”,获取压缩包后解压即可看到完整代码。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image36.png) + +Clone 后,你同样可以让 Trae 或者是 Claude Code 帮你启动项目,例如直接在 Agent 界面中说明: `帮我直接启动这个项目里面的 project 1 `,或者复制对应想启动 project 的绝对路径,粘贴给大模型让大模型直接启动。 + +## 3.2 项目1 - 汉堡店菜单增删改查 + +接下来进入实操环节 —— 以 `project-burger-shop-menu-crud-1` 为例,我们将学习如何通过 SQL 脚本一键初始化 Supabase 数据库,并完成本地项目与 Supabase 数据库的关联配置,让前端能正常读写菜单数据。 + +### 使用脚本创建数据库 + +首先,我们需要在 Supabase 中创建需要的数据表的相关内容。进入 Project1 项目目录看到名为 `scripts`的文件夹,其中包含 1 个 `init.sql`数据库脚本文件,它能帮我们自动完成所有数据库相关资源的创建(包括表结构、初始数据等),之后我们会经常用到该文件进行数据库中表的初始化。 + +```sql +...... + +-- ============================================================================ +-- 2. Create Menu Items Table +-- ============================================================================ + +create table if not exists public.menu_items ( + id uuid primary key default gen_random_uuid(), + name text not null, + description text, + category text check (category in ('burger','side','drink')) default 'burger', + price_cents int not null check (price_cents > 0), + available boolean default true, + emoji text, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +-- Comments for documentation +comment on table public.menu_items is 'Burger shop menu items for CRUD demo'; +comment on column public.menu_items.id is 'Unique identifier for each menu item'; +comment on column public.menu_items.name is 'Display name of the menu item'; +comment on column public.menu_items.description is 'Detailed description of the menu item'; +comment on column public.menu_items.category is 'Category: burger, side, or drink'; +comment on column public.menu_items.price_cents is 'Price in cents (integer) to avoid floating point issues'; +comment on column public.menu_items.available is 'Whether the item is currently available for order'; +comment on column public.menu_items.emoji is 'Optional emoji representation of the menu item'; +comment on column public.menu_items.created_at is 'Timestamp when the item was created'; +comment on column public.menu_items.updated_at is 'Timestamp when the item was last updated'; + +...... +``` + +在 SQL Editor 中执行初始化 sql 脚本后,即可在 Table Editor 中看见已创建的数据表。其中数据库初始化代码具体执行逻辑如下: + +1. 创建 menu_items 表 : +2. 这个表用于存储汉堡店菜单中的所有项目。它包含了如 name (商品名), description (描述), price_cents (以美分为单位的价格,避免浮点数精度问题), category (分类) 和 available (是否可售) 等字段。这基本涵盖了一个菜单项所需的所有معلومة。 +3. 创建 promo_codes 表 : +4. 此表用于管理促销活动,例如折扣码。它定义了 code (折扣码), discount_type (折扣类型,如百分比或固定金额), discount_value (折扣数值) 等字段。 +5. 禁用行级安全 (Row Level Security - RLS) : +6. 为了方便开发和测试,脚本中明确地禁用了 RLS。但结合我们之前学习的 RLS 核心逻辑:RLS 是 Supabase 保障数据安全的关键功能,能通过精细化策略控制 “谁能访问 / 修改哪些数据”(比如只允许管理员编辑促销码,普通用户只能查看菜单)。因此在生产环境中,必须开启 RLS 并配置合理策略,从底层阻断非授权访问(如防止用户恶意修改他人创建的菜单,或泄露促销码规则)。 +7. 插入种子数据 (Seed Data) : +8. 为了让前端项目启动后就能看到真实的菜单与促销数据(无需手动录入测试数据),`init.sql`脚本还会向 `menu_items`和 `promo_codes`表中插入 “种子数据”(即مثال数据)。例如,你可以看到各种汉堡、小食、饮料以及多种多样的折扣码。 + +### 设置与数据库的连接 + +数据库准备完成,我们需要将这个前端项目与 Supabase 进行连接,从而正常读取数据库内的数据。我们需要将 Supabase 项目的 URL 和 anon key 写到指定配置中,本项目提供了两种灵活的配置方式: + +1. 通过环境变量配置 + +在项目根目录创建一个 .env 文件,并填入你的 Supabase 凭证: + +``` +NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co +NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key +``` + +2. 在项目页面中直接设置 + +为了方便快速演示和切换不同的 Supabase 项目,首页页面右上角提供了一个 设置 按钮。你可以点击它,在弹出的模态框中直接输入或粘贴 Supabase URL 和 anon key。 + +点击 “Save” 后,这些معلومة会用于动态创建 Supabase 客户端实例,类似下列代码所示: + +```JavaScript +import { createClient, type SupabaseClient } from '@supabase/supabase-js'; + +// Optional client factory for demos: returns null when env is not set. +export function maybeCreateBrowserClient(): SupabaseClient | null { + const url = process.env.NEXT_PUBLIC_SUPABASE_URL; + const anon = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; + if (!url || !anon) return null; + return createClient(url, anon); +} +``` + +创建完数据库,填写完对应的 Supabase Link 相关配置后,即可看到如下界面,你可以尝试对商品进行增删查改,并观察 Supabase 中对应部分数据表的变化。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image37.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image38.png) + +### 📚 作业 + +1. 尝试增加和删除已有项目,在 Table Editor 中查看修改操作对数据表内容变动的影响。 + +## 3.4 项目2 - 汉堡店认证用户 + +Project1 实现了 “菜单 CRUD + 数据库连接” ,Project2 将引入更贴近真实业务的核心能力,用户认证(Auth)与行级安全(RLS)权限管理。 + +Project2 包含独立的登录页,支持用户通过「邮箱 + 密码」的方式登录。其核心逻辑是调用 Supabase Auth 提供的原生方法,快速实现认证流程,无需手动开发复杂的登录校验逻辑: + +``` +const { error: err } = await supabaseClient.auth.signUp({ + email, + password, + options: { + data: { + full_name: fullName || null, + birthday: birthday || null, + avatar_url: avatarUrl || null + } + } +}); +``` + +![](/zh-cn/stage-2/backend/database-supabase/images/image39.png) + +登录成功后,Supabase 会自动为用户创建一个会话(session),并在后续所有数据库请求中自动携带认证معلومة;通过 RLS 的作用,每个用户根据对应的认证معلومة只能看到自己的账户معلومة(已购买项目、钱包剩余额度),无法看到其他用户的账户معلومة,这就实现了不同用户登录后的数据隔离,每个人只能看到自己的内容。 + +和 Project 1 一样,你需要先使用 `init.sql` 进行数据表的初始化(注:如果发现初始化出错,请先在 Table Editor 中删除已经创建的数据表,或者是直接删除这个 Supabase Project, 重新新建一个 Project) + +成功使用邮箱注册账户、在邮箱确认注册账户后,登录后进入 Shop 界面即可看到如下内容: + +![](/zh-cn/stage-2/backend/database-supabase/images/image40.png) + +但此时点击 admin,你并不能看到如下界面,你需要尝试在数据表中找到控制用户权限的部分,将权限修改为 `admin`,从而能够在 Admin 界面正常看到如下内容: + +![](/zh-cn/stage-2/backend/database-supabase/images/image41.png) + +值得نصيحة的是,目前每次注册新的邮箱,你都需要在邮箱中进行注册确认才可登录;但这一步并非是必须的,你可以在 Supabase 的 Authentication 栏目中找到 Sign In / Providers,点击Confirm email 取消邮箱的强制确认。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image42.png) + +### 📚 作业 + +1. 请先领取新手礼包,完成商品购买操作。 +2. 尝试找到用户权限的设定数据表位置,将权限修改为 `admin`,并成功在订单管理界面修改商品数量 +3. 尝试在数据表内定位到钱包金额相关表,通过修改使剩余钱包金额增加。 + +# 4. 构建你的第一个 Supabase 应用 + +经过前面的系统学习,你已掌握 Supabase 的核心能力(数据库操作、用户认证、RLS 安全策略),现在是时候亲自动手,搭建属于你的第一个包含数据库、支持用户登录系统的应用了! + +## 4.1 为任意应用接入 Supabase 数据库的标准化流程 + +我们可以使用标准化流程将任意应用接入 Supabase 数据库: + +1. 首先进行需求梳理与معلومة同步,明确目标并告知AI + 1. 你需要向AI清晰描述当前应用的核心功能、待新增的数据库需求。مثال:“我现有一个本地React Todo应用,数据仅存在浏览器本地存储,需新增‘数据云端同步’功能并接入Supabase数据库。请帮我梳理:这个应用涉及哪些数据操作(如新增待办、修改状态、删除待办)?需要创建哪些数据表来存储这些数据?” + 2. 补充关键约束条件(可选):比如字段格式要求(时间戳用 `timestamptz`、金额用整数存分)、数据权限规则(仅自己可见待办),让AI的分析更贴合实际需求。 + 3. 对 AI 返回的النتيجة进行审核,若AI思路存在遗漏(如未考虑“待办截止时间”字段),补充نصيحة修正:“你漏考虑截止时间了,帮我加上。” +2. 让AI基于你确认后的表结构,生成适配Supabase的 `init.sql`脚本:“基于上述所说思路和表的结构,返回给我在 Supabase 中可以进行初始化的 init.sql 脚本”,之后你需要在 SQL Editor 中执行脚本;若执行报错,将错误معلومة反馈给AI,让其修正脚本。 +3. 在 Supabase 运行 init.sql 脚本后,让 AI 基于脚本重构当前代码,使得能够和 Supabase 进行正常的数据交互:“请你根据我的 sql 脚本以及上面讨论的设定,重构项目的代码让它支持能够和 Supabase 对应的数据库进行通信并处理数据”。 +4. 重构完毕,此时只需要配置好 Supabase 地址和 key 的参数(正式项目通常只用环境变量配置),随后进行检查,若没问题则顺利实现将应用接入 Supabase 数据库。 + 1. 运行项目,测试所有数据库交互功能,到Supabase Table Editor 实时查看数据是否同步; + 2. 若出现问题(如数据无法插入、仅能看到部分数据),将问题现象反馈给AI,让其定位原因并修正代码。 + +此外,若目标是开发用户登录页面,可直接让 AI 协助集成登录页面 :“现在你需要帮我给这个应用加入 Supabase 的用户登录系统,使用邮箱可以注册和登录”。另外,你还需要向 AI 明确页面的跳转逻辑与路径(如登录成功后跳转至系统首页、跳转首页的地址是什么、登录失败时留在当前页并显示错误نصيحة)。集成完成后,你需要尝试注册登录后能在 Supabase 的 Authentication 项目中看到新增的用户数据,并在登录后能正常进入到原先未登录无法进入的应用界面即可。 + +当然,你还可以直接让 AI 参考某个 project 的实现直接迁移对应的 Supabase 功能,比如某个 Project 用到了数据库以及 Edge fuction 的高级功能,你可以按照如下方式直接让 AI 迁移对应的相似功能:“请你参考该项目 {此处复制粘贴参考项目的绝对地址} 当中的 Supabase 相关功能实现逻辑,给当前项目加上类似的实现逻辑(如用户登录、数据库管理、函数请求等等)”。 + +## 4.2 案例研究:构建一个在线贪吃蛇游戏 + +根据上面所提到的 SOP ,让我们通过一个具体的实际案例 `Project5-Supabase-Demos/apps_snakegame`来实践:为一个已有的“贪吃蛇”游戏项目增加分数排行榜单,包含用户登录与数据库基础功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image43.png) + +### 4.2.1 分析项目,识别数据需求 + +首先,和在之前提到的标准化流程类似,我们可以先把需求澄清给 AI ,让 AI 基于我们项目和需求给出对应的修改方案,之后我们会基于这个修改方案。 + +**你可以使用如下的نصيحة词来指导 AI:** + +> “我有一个贪吃蛇游戏,目录在 {此处粘贴贪吃蛇游戏的绝对路径}。现在我想结合 supabase 给它增加一个在线排行榜功能,并且支持用户登录系统,排行榜可以根据用户名和邮箱显示排名。 +> +> 请帮我分析一下,为了实现这个功能,我需要建立哪些数据表?每个表应该包含哪些字段?” + +此时你会得到类似如下返回: + +![](/zh-cn/stage-2/backend/database-supabase/images/image44.png) + +### 4.2.2 生成 `init.sql` 脚本 + +确定需要的部分,我们可以让 AI 生成需要在 Supabase 执行的数据库初始化脚本:“请你基于上面的分析,帮我在项目中生成 scripts/init.sql 脚本用于在 Supabase 中初始化所需数据库”。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image45.png) + +### 4.2.3 改造项目代码 + +接下来我们只需要让 AI 基于前面的内容重构当前的贪吃蛇代码:“接下来请你基于前面思考的内容以及 sql 表,使用 Supabase 帮我实现排行榜功能,排行榜是单独的一页,需要可以根据邮箱和用户名区分不同用户的总分,你还需要支持基于邮箱的用户登录系统,注册登录才能玩这个游戏。” + +如果当前 AI 对话轮次太多,你想重开一个新的会话进行项目重构,你可以把上面提到的 `init.sql`作为上下文中的内容,让 AI 基于 sql 文件进行项目重构。 + +若是发现 AI 实现的用户登录系统不够正常,你可以直接将我们之前写好的 `Project5-Supabase-Demos/apps/project-burger-shop-auth-users-2` 的地址一同放入نصيحة词,让 AI 基于项目直接实现用户登录系统。并检查是否已经正确设定了连接到 Supabase 的必要条件,防止因为 Supabase 配置错误而报错。 + +在代码修改过程中,若出现实际效果与预期不符的情况(如排行榜数据不显示、登录验证失效等),只需完整记录具体现象并反馈给 AI,即可逐步接近正确النتيجة。改造成功的标准为:用户能顺利完成注册与登录操作,且登录后可正常查看对应的游戏排行榜单。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image46.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image47.png) + +### 📚 واجب الدرس + +1. 将用户管理系统集成到贪吃蛇游戏演示版中 +2. 将用户管理系统集成到你的应用程序中(如果之前已开发过一个应用程序) + +# 5. 成为 Supabase 大师 + +以上是 Supabase 的基本操作,接下来的旅程中我们将会接触 Supbase 的进阶原理和功能,你将理解为什么我们会选择 Supabase 作为教学案例,以及如何使用 Supbase 实现更高级的操作,协助你实现更复杂的交互功能,并且在学习这些功能后,即便面对 Supabase 之外的其他同类工具,你也能触类旁通,从更本质的层面理解后端服务的核心原理。当然,你并不需要在短时间内学会全部,也许只需要学会第三方登录支持已经足够,你可以先浏览下列内容,直到项目遇到对应的需求时再倒回来深入学习。 + +## 5.1 为什么我们选择 Supabase + +在开始进阶之前,我们再次思考这个问题:众多后端技术方案中,为何我们最终选择 Supabase 作为技术底座? + +初创团队在技术选型时普遍面临一个矛盾:既想完全掌控后端系统,又必须快速上线产品——而自建后端通常意味着要投入数月时间搭建数据库与实时同步、用户认证、API服务、文件存储、定时任务、监控告警等核心组件,除非团队成员已在对应领域积累了丰富的تطبيق عملي经验。在资金不足、市场窗口短暂的双重压力下,一旦陷入基础设施泥潭,极易导致迭代滞后、错失早期增长空间。 + +Supabase 将这些后端能力打包为开箱即用的服务(PostgreSQL数据库、实时订阅、身份认证、对象存储、边缘函数、自动生成API等),让初创团队得以将稀缺资源聚焦于核心功能开发,避免因底层建设拖慢上线速度——这已成为当前创投环境下务实的生存策略。当然,我们也可以使用别的一栈式后端产品进行开发,例如 PocketBase(轻量极简)和 Appwrite(跨平台适配)等方案,但综合功能完整性、SQL 生态成熟度及 Github 社区关注度,Supabase 更适合支撑业务的长期稳定运行。 + +在同类产品中,Supabase 的开源策略更具优势。 以市场占有率较高的 Firebase 为例:其闭源特性易导致平台绑定,迁移成本极高。Supabase 采用完全开源模式,支持私有化部署,规避了供应商锁定风险,可根据需求切换至其其他竞品。 + +总而言之,技术选型需匹配业务规模与目标。 对于个人项目或极小范围测试,PocketBase 等超轻量方案已足够;若企业需对接复杂身份系统,或要满足上市公司合规审计要求,WorkOS 这类企业级全身份治理方案更为适用。但对于验证 MVP、承载早期用户的核心业务场景,Supabase 的完整功能完全够用,它不仅能独立支撑至少万级用户规模,更可灵活集成 Stripe(支付)、Resend(邮件)、Cloudflare(CDN)等第三方服务;即便未来业务扩展至企业级需求,Supabase 的开源架构也能与企业系统并行部署,不同功能选择最适配的平台进行使用。这种渐进式灵活性,使初创团队无需过早投入重型基础设施,又能保留 future-proof 的演进空间。 + +## 5.2 Google 和 GitHub 登录支持 + +在前面的教程中,我们讲解了如何直接使用邮箱进行注册和登录,但在实际操作中我们通常想要简化注册流程,例如使用第三方登录 Google 和 GitHub 进行系统的快速注册与登录,我们将会在这节教程中展开每个细节;同时,一个完整的认证系统也必须提供安全可靠的密码重置功能,我们也会将密码重置功能集成在本节教程的项目中。 + +本项目 `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6`)完整地演示了如何实现这些高级功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image48.png) + +### 5.2.1 OAuth 流程:第三方登录是如何工作的? + +第三方登录的核心是 OAuth 2.0 开放授权协议,它的本质是 “授权代理”:允许用户授权我们的应用(汉堡店项目)访问其在第三方平台(如 Google)的公开معلومة(如邮箱、头像),但无需将第三方平台的密码暴露给我们的应用,从根本上规避了密码泄露风险。 + +完整流程可拆解为 5 个关键خطوة,以 Google 登录为例: + +1. 用户发起授权请求:用户点击页面上的 “Sign in with Google” 按钮,我们的应用会自动将用户重定向到 Google 官方的授权页面(确保授权过程的安全性,避免钓鱼风险)。 +2. 用户完成第三方授权:用户在 Google 页面登录自己的账户(验证用户身份),并同意我们的应用请求的权限(如 “获取邮箱地址”)。 +3. Google 返回一次性授权码:授权通过后,Google 会将用户重定向回我们提前约定的 “回调 URL(Callback URL)”,并在 URL 参数中附带一个一次性、短期有效的授权码(而非直接返回用户معلومة,进一步提升安全性)。 +4. Supabase 交换访问令牌(Access Token):我们的后端(由 Supabase 托管,无需自建)会拿着这个授权码,向 Google 官方接口发起请求,换取可用于获取用户معلومة的 Access Token(授权码仅用于换 Token,避免 Token 直接在前端传输)。 +5. 创建账户并建立会话:Supabase 使用 Access Token 从 Google 拉取用户的公开معلومة(如邮箱、头像),并在我们的项目中为该用户自动创建账户(若首次登录)或直接关联现有账户,最终生成一个有效的用户会话(Session),完成登录。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image49.png) + +### 5.2.2 配置 Google Cloud 获取 Client ID 和 Secret + +无论是何种第三方登录方式,我们通常都需要获取 Client ID 与 Secret 进行配置;对于 Google 的第三方登录,你首先需要在 Google Cloud Platform 中创建一个 OAuth 2.0 客户端 ID 进行对应参数的获取。 + +1. **进入 Google Cloud Console** : +2. 访问 [Google Cloud Console](https://console.cloud.google.com/)。 +3. 创建一个新项目或选择一个现有项目。 +4. **配置 OAuth 同意屏幕 (OAuth consent screen)** : +5. 在左侧导航栏中,找到 “APIs & Services” -> “OAuth consent screen”。 +6. 选择 “External” 用户类型,然后点击 “Create”。 +7. 填写应用名称、用户支持电子邮件等必填معلومة。 +8. 在 “Authorized domains” 部分,添加你的 Supabase 项目域名,格式为 `*.supabase.co`。 +9. 保存并继续。在 “Scopes” 和 “Test users” خطوة中,你可以暂时跳过,直接保存。 +10. **创建凭据 (Create Credentials)** : +11. 进入 “APIs & Services” -> “Credentials”。 +12. 点击 “+ CREATE CREDENTIALS”,选择 “OAuth client ID”。 +13. 在 “Application type” 中选择 “Web application”。 +14. 为它取一个名字,例如 “Supabase Auth”。 +15. 在 “Authorized redirect URIs” 部分,点击 “ADD URI”,并填入你的 Supabase 项目的回调 URL。你可以在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “Google” 中找到这个 URL,它的格式通常是 `https://<你的项目ID>.supabase.co/auth/v1/callback`。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image50.png) +16. 点击 “CREATE”。 +17. **获取 Client ID 和 Client Secret** : +18. 创建成功后,一个弹窗会显示你的 **Client ID** 和 **Client Secret** 。请务必**立即复制并妥善保存** 它们。 + +### 5.2.3 配置 GitHub 获取 Client ID 和 Secret + +同样地,你也需要在 GitHub 上注册一个 OAuth 应用。 + +1. **进入 \*\***GitHub\*\* ** Developer Settings** : + 1. 登录你的 GitHub 账户。 + 2. 点击右上角的头像,进入 “Settings”。 + 3. 在左侧导航栏的底部,找到 “Developer settings”。 + +2. **注册新应用 (Register a new application)** : +3. 选择 “OAuth Apps”,然后点击 “New OAuth App”。 +4. 填写应用名称,例如 “My Burger Shop”。 +5. **Homepage URL** : 填写你应用的线上地址,或者本地开发地址 `http://localhost:3000`。 +6. **Authorization \*\***callback\*\* ** URL** : 填入你的 Supabase 项目的回调 URL。同样,你可以在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “GitHub” 中找到它,格式为 `https://<你的项目ID>.supabase.co/auth/v1/callback`。 +7. 点击 “Register application”。 +8. **获取 Client ID 和 Client Secret** : +9. 注册成功后,页面会显示你的 **Client ID** 。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image51.png) +10. 点击 “Generate a new client secret” 来生成你的 **Client Secret** 。同样,请**立即复制并保存** 它。 + +### 5.2.4 在 Supabase 中配置 Provider + +现在,将我们获取到的凭证配置到 Supabase 中。 + +1. **进入 Supabase Dashboard** : +2. 选择你的项目,进入 “Authentication” -> “Providers”。 +3. **启用并配置 Google** : +4. 找到 “Google” 并启用它。 +5. 将你从 Google Cloud 获取的 **Client ID** 和 **Client Secret** 粘贴到对应的输入框中。 +6. 点击 “Save”。 +7. **启用并配置 ** **GitHub** : + 1. 找到 “GitHub” 并启用它。 + 2. 将你从 GitHub 获取的 **Client ID** 和 **Client Secret** 粘贴到对应的输入框中。 + 3. 点击 “Save”。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image52.png) + +至此,你已经能够使用第三方账户在构建的网站中进行登录,你可以直接让 AI 基于 `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6`项目作为参考,在你的项目的基础上支持用户登录系统,以最小成本集成包含 github 与 google 鉴权的用户登录界面。 + +### 5.2.6 密码重置实现 + +作为一个成熟的用户登录组件,密码重置也是极其مهم的一环,本项目 `project-burger-shop-auth-advanced-supabase-6`也包含了该功能的完整实现,你可以直接让 AI 基于本项目的密码重置功能复刻完整的密码重置组件。其主要分为以下几步: + +1. 发起请求 :用户在忘记密码页面输入邮箱,前端调用 `supabase.auth.resetPasswordForEmail()` 函数,并指定一个重定向 redirectTo URL(例如 /auth/reset )。 +2. 发送邮件 :Supabase 会向该邮箱发送一封包含唯一重置链接的邮件。 +3. 访问链接 :用户点击邮件中的链接,被重定向到应用内指定的重置页面。 +4. 更新密码 :在重置页面,用户输入新密码。前端调用 `supabase.auth.updateUser()` ,将新密码提交给 Supabase。Supabase 会自动验证链接的有效性并完成密码更新。 + +最后,如果你觉得当前的密码重置邮件过于简陋,你可以 在 Supabase Dashboard 的 Authentication -> Email Templates 中自定义“Reset Password”邮件模板。 + +除了 Reset password 功能外,你还能看到许多其他与用户管理相关的高级功能设定(例如 Invite user 等),你可根据对应功能各自的开发文档,结合 Vibe coding 工具自行添加对应功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image53.png) + +## 5.3 实时功能 + +Supabase 的实时功能是其最强大的特性之一,为构建协作文档、实时仪表盘、游戏大厅或客服系统提供了极大的便利。 + +本项目 `Project5-Supabase-Demos/apps/project-burger-shop-realtime-orders-3 `通过构建一个 多人实时聊天室、光标位置共享 功能,展示了 Supabase Realtime 涉及到的三大核心能力:数据库变更监听 (Postgres Changes)、广播 (Broadcast) 和 在线状态 (Presence)。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image54.png) + +如果你觉得相关代码部分有一定难度,可以直接让 AI 参考该部分文档内容,对你的程序进行修改。 + +### 5.3.1 数据库实时变动 Postgres Changes + +最常见的 Realtime 功能是对数据库的变更进行实时监听 Postgres Changes 。它允许客户端订阅数据库中特定表、特定行甚至特定列的 INSERT 、 UPDATE 或 DELETE 事件。一旦数据库发生变动(无论是通过 API 调用、Supabase Dashboard 操作,还是 SQL 脚本执行),Supabase 都会利用 PostgreSQL 的底层复制机制,立即通过 WebSocket 将变更的数据推送到所有订阅了该频道的前端客户端,而无需前端通过轮询(Polling)去反复查询。 + +一般而言,该功能可以在 Table Editor 中找到 Enable Realtime 点击后启动, 但更方便的是通过 SQL 脚本初始化执行,例如: + +```sql +-- Enable realtime replication +ALTER TABLE public.chat_messages REPLICA IDENTITY FULL; +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_publication_tables + WHERE pubname = 'supabase_realtime' + AND schemaname = 'public' + AND tablename = 'chat_messages' + ) THEN + ALTER PUBLICATION supabase_realtime ADD TABLE public.chat_messages; + END IF; +END $$; +``` + +该语句将 `chat_messages` 表添加到了 Supabase 预设的 `supabase_realtime` 中,而一旦一个表被加入到这个特殊的 `publication` 中,Supabase 的实时服务器就会开始监听它的所有数据变更。 + +基于上面的特殊数据表,我们能够使用监听代码对表内数据变动进行实时监听。我们需要实现的是当一个用户发送消息时,其他所有在线用户都能立刻在屏幕上看到这条消息。通过订阅 chat_messages 表的 INSERT 事件能够实现这一点。 + +```typescript + const sub = supabase + .channel('chat_messages_channel') + .on('postgres_changes', { + event: 'INSERT', + schema: 'public', + table: 'chat_messages' + }, (payload: any) => { + console.log('New message received:', payload.new); + const newMessage = payload.new as Message; + // ... // + .subscribe((status: string) => { + console.log('Chat subscription status:', status); + }); +``` + +- `.channel('chat_messages_channel')`: 创建一个隔离的通信频道。 +- `.on('postgres_changes', ...)`: 这是核心的订阅方法。我们告诉 Supabase 我们只关心 `chat_messages` 表的 `INSERT` 事件。 +- `payload.new`: 当有新消息被插入数据库时,Supabase 会将这条新数据的完整内容通过 `payload.new` 推送给所有订阅的客户端。 +- `.subscribe()`: 启动订阅。 + +### 5.3.2 معلومة广播同步 Broadcast & Presence + +对于那些不需要存入数据库的、更“即时”的交互,比如光标移动、在线状态等,Supabase 提供了 Broadcast 和 Presence 功能。 + +- Presence: 用于跟踪频道内所有客户端的 **共享状态** 。适合用来实现“谁在线”的功能。 +- Broadcast: 用于向频道内的所有其他客户端发送**低延迟**的 **临时消息** 。 + +Presence 的核心思想是: 让每个客户端声明自己的在线状态,并由 Supabase 的服务器负责将这些状态可靠地同步给频道内的所有其他客户端。实现 Presence 分为以下几个关键خطوة: + +1. 创建一个支持 Presence 的频道 + +首先,我们创建了一个频道 `lobby_presence` 来专门处理这些交互,并在配置中指定一个唯一的 key 来标识当前用户。这个 key 通常是用户的 ID。 + +``` +const ch = supabase.channel +('lobby_presence', { +  config: { +    presence: { key: anonymousUser.id }, +  } +}); +``` + +2. 订阅频道宣告“我在线”的معلومة + +一旦频道创建成功,我们需要订阅它。在订阅成功的回调( status === 'SUBSCRIBED' )中,我们调用 channel.track() 方法。这个方法会将当前用户的معلومة(例如用户ID、名称、头像颜色等)广播给频道内的所有其他客户端,宣告自己的“在线”状态。 + +``` +const me = { +  id: anonymousUser.id, +  name: anonymousUser.name, +  color: anonymousUser.color +}; + +ch.subscribe(async (status) => { +  if (status === 'SUBSCRIBED') { +    await ch.track(me); +  } +}); +``` + +3. 同步完整的在线列表 + +当一个新用户加入频道时,他们需要获取当前所有已经在线的用户列表。这通过监听 presence 的 sync 事件来实现。 sync 事件会在你首次加入频道时触发,为你提供一个完整的“快照”。 + +channel.presenceState() 方法会返回一个对象,包含了当前频道内所有在线用户的状态معلومة。我们将其处理后更新到应用的 state 中,从而渲染出完整的在线用户列表。 + +``` +ch.on('presence', { event: 'sync' }, ()  +=> { +  const state = ch.presenceState(); +  const flat = {}; +  Object.values(state).forEach((arr) => { +    arr.forEach((u) => { flat[u.id] =  +    { ...u }; }); +  }); +  setOnline(flat); +}); +``` + +4. 监听单个用户的加入与离开 + +除了 sync 事件,我们还可以监听 join 和 leave 事件,以便在有新用户进入或离开时做出即时响应,例如显示一个 "User has joined" 的通知。 + +``` +ch.on('presence', { event: 'join' }, ({  +key, newPresences }) => { +  console.log('User joined:', key,  +  newPresences); +}); + +ch.on('presence', { event: 'leave' }, ({  +key, leftPresences }) => { +  console.log('User left:', key,  +  leftPresences); +}); +``` + +通过以上خطوة,我们便构建了一个功能完备的在线状态系统。Supabase 自动处理了用户意外断开连接(如关闭浏览器或断网)的情况,并在适当的时候触发 leave 事件,确保了在线列表的准确性。 + +当 Presence 让我们知道了“谁在场”之后, Broadcast 能够让他们之间能够进行“对话”,但对话的内容是短暂存储的。一个典型的例子就是实时光标追踪。如果每次鼠标移动都去读写数据库,会造成巨大的性能浪费和延迟。 Broadcast 完美地解决了这个问题,它允许消息在各个客户端之间直接通过 WebSocket 传递,完全绕过数据库。 + +Broadcast 的工作模式主要依赖两个核心方法: channel.send() 用于发送,channel.on() 用于接收。】 + +1. 发送端:广播我的光标位置 + +我们为 mousemove 事件添加了一个监听器。当鼠标移动时,我们构造一个包含用户 ID、坐标和颜色的 payload,然后通过 channel.send() 将其广播出去,并指定事件名称为 'cursor'。 + +```typescript +const handleMouseMove = (e) => { + const payload = { + id: anonymousUser.id, + x: e.clientX, + y: e.clientY, + name: anonymousUser.name, + color: anonymousUser.color + }; + + channelRef.current?.send({ + type: 'broadcast', + event: 'cursor', + payload + }); +}; + +document.addEventListener('mousemove', handleMouseMove); +``` + +2. 接收端:监听并渲染他人的光标 + +在同一个频道内,所有客户端都使用 channel.on() 来监听 broadcast 类型的、且 event 为 'cursor' 的消息。一旦收到匹配的消息,回调函数就会被触发。我们从 payload 中解析出发送方的数据,并用它来更新本地的 online 状态,从而在屏幕上实时渲染出其他用户光标的位置。 + +```typescript +ch.on('broadcast', { event: 'cursor' }, ({ payload }) => { + setOnline((prev) => ({ + ...prev, + [payload.id]: { + ...(prev[payload.id] || {}), + x: payload.x, + y: payload.y + } + })); +}); +``` + +通过这种方式, Presence 和 Broadcast 协同工作;Presence 维护在线用户列表,而 Broadcast 则负责在这些用户之间传递像光标位置这样的临时状态,最终以较低的成本实现了丰富的实时互动功能。 + +## 5.4 存储 + +除了用户معلومة、订单这类可规整定义的结构化数据,一个完整的应用通常还需要处理大量非结构化文件 —— 例如用户头像、商品展示图、用户上传的订单文档等。这类文件的特点是体积差异大、数量可能极多(比如电商平台的商品图可能达数万甚至数十万张),若直接存储在应用自身的业务服务器中,会显著增加服务器的存储负载,还可能拖慢数据读写速度,影响应用整体性能。 + +实际开发中,这类非结构化文件会统一交由 “对象存储服务” 管理,OSS、Amazon S3 均属于这类服务,它们是专门为海量文件存储设计的 “专业存储工具”,能高效应对文件的存储、备份与快速读取需求。而我们在应用中获取这些文件时,并不会直接从对象存储服务的 “底层仓库” 调取,而是通过 URL 地址实现:每个存储在对象存储中的文件,都会被分配一个唯一的 URL(类似 “[https://xxx.oss.com/avatar/user123.jpg](https://xxx.oss.com/avatar/user123.jpg)” 的地址,可简单理解为这个“网站”只有一张图片),这个 URL 就像文件的 “专属访问地址”,前端页面只需通过该地址,就能直接下载或加载头像、商品图,无需依赖应用业务服务器中转,既提升了文件加载速度,也减轻了业务服务器的压力。 + +本项目 `project-burger-shop-storage-uploads-4` 便通过一个用户头像上传功能,深入演示了如何利用 Supabase Storage 构建现代化的文件上传系统,让开发者直观理解非结构化文件从上传到通过 URL 访问的完整流程。此外,本项目使用 `Uppy` 库来提供一个优秀的文件上传界面,并结合 `Tus` 插件实现了可续传上传,通过将 Uppy 的上传端点指向 Supabase 的标准 API (`/storage/v1/upload/resumable`) 进行工作,你可以参考类似的方式实现上传功能组件。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image55.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image56.png) + +### 5.4.1. 存储桶 + +Supabase Storage 的组成单元是存储桶 Bucket。你可以把它想象成电脑操作系统中的文件夹。每个 Bucket 都可以有自己独立的安全策略和配置。 + +Storage 内的所有文件都可以通过一个公开的 URL 直接访问,但并不意味着任何人都可以随意上传或修改,具体的访问权限将由更精细的策略来控制。和数据库一样,Storage 的访问权限也是通过行级安全策略来管理的。SQL 策略写在 storage.objects 和 storage.buckets 这两张特殊表上,可以精确定义谁能读取 (SELECT)、上传 (INSERT)、更新 (UPDATE) 或删除 (DELETE) 文件。 + +例如,我们可以创建一条策略,只允许用户上传到以自己 user_id 命名的文件夹下,并且只能上传图片类型的文件: + +``` +CREATE POLICY "Allow authenticated  +uploads to avatars bucket" +ON storage.objects FOR INSERT +TO authenticated +WITH CHECK ( +  bucket_id = 'avatars' AND +  auth.uid() = (storage.foldername(name)) +  [1]::uuid AND +  (storage.extension(name) IN ('png',  +  'jpg', 'jpeg')) +); + +CREATE POLICY "Allow public read access  +to avatars" +ON storage.objects FOR SELECT +USING ( bucket_id = 'avatars' ); +``` + +### 5.4.2 获取可访问文件 URL + +本项目需要你手动创建一个名为 avatars 的公共桶,所有文件将上传至该公共桶下进行存储。文件上传成功后,我们只得到了它在 Storage 中的存储路径 ,例如 public/avatar1.png 。这只是存储在数据库中的一个字符串,要让浏览器能够渲染这张图片,我们需要将其转换为一个可访问的 HTTP URL。 + +Supabase 提供了两种截然不同的策略来获取这个 URL,它们在安全性、持久性和成本控制上有着本质的区别。 + +#### 1. 公开 URL (Public URL) - 永久链接 + +这是最直接的方式。如果你的文件存放在一个**Public Bucket** 中,你可以获取一个固定、永久的公开链接。 + +```typescript +const { data } = supabase.storage + .from('avatars') + .getPublicUrl('public/avatar1.png'); +const publicUrl = data.publicUrl; +``` + +这类链接具有两大核心特点:一是简单直接,其 URL 结构固定,在实际操作中易于拼接和管理,降低了技术使用门槛;二是利于缓存,作为永久链接,它能被 CDN(内容分发网络)和浏览器有效缓存,从而大幅提升资源的访问速度,优化用户体验。基于这些特点,它适用于真正意义上的公共资源场景,例如网站 Logo、产品目录图片、博客文章配图等,能很好地满足这类资源的访问和管理需求。 + +不过在生产环境中,这类链接存在明显的被盗刷流量(Hotlinking)风险。由于链接是永久公开的,外部人员可以轻易将你的图片链接嵌入到他们自己的高流量网站中,导致流量被非法占用。这一行为会让你的 Supabase 项目产生大量不必要的流量费用,而这些消耗的流量并未服务于你自身的应用,属于典型的成本浪费,是生产环境中需要高度警惕和防范的问题;因此,我们需要转向临时签名 URL 实现对外资源的暴露。 + +#### 2. 签名 URL (Signed URL) - 临时授权链接 + +为了解决公开 URL 的安全和成本问题,Supabase 提供了生成临时签名 URL 的方式。这是绝大多数线上应用推荐的最佳实践,比如文生图应用给用户生成限时查看的图片链接、电商平台仅让下单用户获取临时发票下载地址、付费内容平台为订阅用户提供短期有效的课程播放链接,既防文件盗用又能避免流量盗刷,适配性极强。 + +```typescript +const { data, error } = await supabase.storage + .from('avatars') + .createSignedUrl('private/user-invoice.pdf', 3600); // 链接有效期为 3600 秒 (1小时) +const signedUrl = data?.signedUrl; +``` + +临时签名 URL(Signed URL)有三大核心优势:安全可控是指链接带安全标记、有有效期,过期就用不了;权限绑定很简单 —— 只有能看这文件的人,才能生成这个链接,就算文件藏在私有存储里(Private Bucket),他用这个链接也能正常打开;杜绝盗刷是因为链接是临时的,复制到别处很快就失效,不会被恶意刷流量。靠这些优势,像用户头像、私人照片、付费内容、订单发票这些需要管权限的文件,都能用它。 + +从安全保障和成本控制的角度,建议养成优先使用临时签名 URL 的习惯。只有当某个资源明确需要永久公开、无限制访问(比如应用的公开 Logo、公共活动宣传图等)时,才考虑使用 Public URL。这样既能满足特定业务需求,又能最大程度规避不必要的风险和成本消耗。 + +## 5.5 边缘函数 + +Edge Function 是 Serverless(无服务器架构)生态中极具核心价值的形态之一,它为 “无自建后端” 场景提供了轻量、高效的函数运行支持。 + +什么是 Serverless? Serverless(无服务器架构)并不意味着真的没有服务器,而是指开发者无需关心服务器的购买、运维、配置和扩容 。你只需要编写业务代码(函数),云服务商会在特定事件触发时自动为你分配资源运行代码,并按实际运行时间计费。 + +当你的应用需要执行一些不能或不应在客户端(浏览器)上完成的逻辑时——例如与需要私密密钥的第三方 API 交互、执行计算密集型任务、或强制执行复杂的业务规则——Edge Functions 就派上了用场。Supabase Edge Functions 基于 Deno 和 TypeScript,它们被部署在全球的边缘节点上,物理距离上靠近你的用户,从而提供极低的函数执行延迟。 + +目前主流云厂商都推出了各自的 Edge Function 服务,常见的包括: + +- AWS Lambda@Edge:基于 AWS Lambda 延伸的边缘函数服务,可与 CloudFront CDN 联动,支持 Node.js、Python 等语言; +- Cloudflare Workers:Cloudflare 推出的边缘函数,部署在其全球 275+ 边缘节点,支持 JavaScript/TypeScript,以 “毫秒级延迟” 为核心优势; +- Vercel Edge Functions:适配 Vercel 前端项目的边缘函数,与 Next.js 深度集成,支持 TypeScript,主打 “前端与边缘逻辑无缝衔接”; + +回到 Supabase ,当你的应用需要执行 “不能在客户端(浏览器)完成” 的逻辑时,比如用私密密钥调用第三方 API(如 LLM 接口)、处理计算密集型任务(如图片压缩)、或强制执行权限校验(如文件访问规则)时,Supabase Edge Functions 就能发挥作用。它基于 Deno runtime 和 TypeScript 构建,部署在全球边缘节点上,能以 “靠近用户的物理距离” 实现极低的执行延迟,是编写自定义、可信服务器端逻辑的核心工具。 + +本项目 `Project5-Supabase-Demos/apps/project-burger-shop-edge-function-5`通过一个与大语言模型(LLM)实时流式对话的功能,展示了 Edge Functions 的最简应用流程。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image57.png) + +### 5.5.1 LLM Chat 案例解析 + +假设你想在应用中集成一个类似 ChatGPT 的聊天机器人。你需要在服务器端调用 OpenAI 的 API,但这需要一个私密的 API Key。 这个 Key 绝对不能暴露在前端代码中 ,否则任何人都可以通过查看网页源码盗用你的 Key,产生高昂的费用。这正是 Edge Function 的用武之地。我们将创建一个名为 llm-chat 的函数,它充当了前端和 OpenAI API 之间的一个 安全代理 。 + +参考 `project-burger-shop-edge-function-5/scripts/llm-chat.ts`的代码,我们来看看它是如何工作的: + +```typescript +// scripts/llm-chat.ts +import "jsr:@supabase/functions-js/edge-runtime.d.ts"; +import { OpenAI } from "npm:openai"; + +const OPENAI_API_KEY = Deno.env.get("OPENAI_API_KEY"); + +Deno.serve(async (req) => { + try { + const openai = new OpenAI({ apiKey: OPENAI_API_KEY }); + const { prompt } = await req.json(); + + const stream = await openai.chat.completions.create({ + model: "gpt-3.5-turbo", + messages: [{ role: "user", content: prompt }], + stream: true, + }); + + return new Response(stream.toReadableStream(), { + headers: { "Content-Type": "text/event-stream" }, + }); + } catch (err) { + } +}); +``` + +在该案例中,对于密钥安全,OPENAI_API_KEY 作为环境变量被安全存储于 Supabase 的服务器。本地前端代码完全无法接触到该密钥,从而有效保障了密钥的安全性。 + +### 5.5.2 创建并部署函数 + +Supabase 提供了非常友好的界面,让你无需接触命令行即可完成部署。 + +1. **进入 Edge Functions 面板** : +2. 登录你的 Supabase 项目 Dashboard。 +3. 在左侧导航栏中,点击像代码一样的图标,进入 “Edge Functions”。 +4. **创建新函数** : +5. 点击 “Create a new function” 按钮。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image58.png) +6. 为函数命名,例如 `llm-chat`。 +7. **粘贴代码** : + ![](/zh-cn/stage-2/backend/database-supabase/images/image59.png) +8. 在弹出的在线编辑器中, **删除所有默认的占位代码** 。 +9. 打开你本地的 `llm-chat.ts` 文件, **复制其全部内容** 。 +10. 将复制的代码**粘贴**到 Supabase 的在线编辑器中。 +11. **配置\*\***环境变量\*\* ** (Secrets)** : + 1. 在侧边栏找到 Secrets。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image60.png) + 2. Name: 输入 `OPENAI_API_KEY`。 + 3. Value: 粘贴你自己的 OpenAI API Key。 + 4. 点击 “Save”。在这里设置的 Secret 会被加密存储,并安全地注入到你的函数运行时环境中。 + +若有函数需要更新,记得在 Edge Function 部分执行 Deploy updates。Supabase 会在云端为你构建并部署这个函数。几分钟后,你的函数就可以在线访问。 + +除了作为语言模型的安全代理,Edge Functions 的应用场景远不止于此。实际上,任何需要服务器端逻辑处理的任务,无论是简单的 API 调用、数据验证,还是更复杂的计算,都可以通过 Edge Function 实现。它为你提供了一个轻量级、可扩展的后端,而无需管理任何服务器基础设施。 + +如果你想探索更多可能性,可以参考项目中的其他مثال。例如: + +- 图片生成 ( txt2img.ts ) : 这个函数展示了如何利用 Edge Function 调用第三方的文生图(Text-to-Image)API(如 Stability AI, Midjourney 等)来动态生成图片。这是一种典型的计算密集型或需要安全调用外部服务的场景。与 llm-chat 案例一样,API 密钥被安全地存储在 Supabase 后端,前端只负责发送文本描述,然后接收并展示生成的图片,整个过程安全、高效。 +- 发送邮件 ( send-email.ts ) : 在应用中发送欢迎邮件、交易通知或密码重置邮件是常见需求。 send-email.ts مثال演示了如何通过 Edge Function 集成邮件服务(如 Resend, SendGrid)。你无需在客户端代码中暴露敏感的邮件服务 API Key,只需创建一个函数,让前端通过调用这个函数来触发邮件发送。 + +## 5.6 Clerk 登录 + +Clerk 是一款专注于身份认证与用户管理的专业开发工具,核心能力覆盖用户注册、登录、账号安全MFA、权限控制、会话管理等全链路身份认证相关需求,能帮助开发者快速搭建安全、灵活且符合现代应用标准的用户体系,无需从零开发复杂的身份逻辑。 + +本部分将介绍如何从零开始配置 Clerk 服务,并将其与 Supabase 进行整合。你可以在项目 `project-burger-shop-auth-advanced-clerk-7` 中体验全流程。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image61.png) + +### 5.6.1 创建 Clerk 应用与获取密钥 + +在使用本项目之前,你需要拥有一个 Clerk 账号并创建一个应用。 + +1. 注册与创建: + 1. 访问 [dashboard.clerk.com](https://dashboard.clerk.com/) 并注册账号。 + 2. 点击 "Create application" 。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image62.png) + 3. 输入应用名称(例如 "Burger Shop")。 + 4. 在 "How will your users sign in?" 中,默认勾选 Email , Google , GitHub 。 + 5. 点击 Create application 。 +2. 获取 API Keys: + 1. 创建成功后,你会被引导至 API Keys 页面。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image63.png) + 2. 找到 Publishable key (以 `pk_` 开头) 和 Secret key (以 `sk_` 开头)。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image64.png) + 3. 将它们复制到你的 `.env.local` 文件中(参考本项目 `.env.example`): + + ```bash + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... + CLERK_SECRET_KEY=sk_test_... + ``` + +### 5.6.2 配置 Supabase 和 Clerk 的原生集成 + +在进一步使用前,我们需要集成 Supabase 与 Clerk 的关联关系,方便之后登录的鉴权跳转以及控制对特定数据库的访问权限。Supabase 与 Clerk 提供官方原生集成能力,通过该集成可快速实现两者的身份认证打通,无需手动配置复杂的适配逻辑,大幅简化用户登录、权限校验等功能的开发流程: + +1. 在 Clerk 中激活对 Supab ase 的官方集成 + 1. 登录 [Clerk Dashboard](https://dashboard.clerk.com/)。 + 2. 在左侧菜单导航至 Integrations (集成)。 + 3. 在列表中找到并点击 Supabase。 + 4. 开启 Enable Supabase 开关(或点击 Activate integration)。 + 5. 关键خطوة:激活成功后,页面会显示你的 Clerk Domain(格式通常为 `https://.clerk.accounts.dev` 或你的自定义域名)。请复制这个 Domain 地址,الخطوة التالية会用到。 +2. 在 Supabase 中添加 Clerk 提供商 + 1. 登录 [Supabase Dashboard](https://supabase.com/dashboard) 并进入你的项目。 + 2. 在左侧菜单导航至 Authentication > Sign In / Up (或者直接点击 Providers)。 + 3. 点击 Add provider 按钮,从下拉列表中选择 Clerk。 + 4. 在弹出的 Clerk Domain 输入框中,粘贴你刚才从 Clerk 复制的 Domain 地址。 + 5. 点击 Save 保存配置。 + +### 5.6.3 通过 Webhook 同步用户数据至 Supabase + +仅仅是集成只满足了鉴定权限的需求,但这并不会将 Clerk 中已经注册的用户معلومة同步到 Supabase,为了方便管理,我们还需要在 Supabase 的 `public.users` 表中保留一份用户备份,以便进行关联查询或数据分析。我们可以通过 Clerk Webhooks 实现这一功能,完整过程如下: + +1. **Clerk 发送通知** : 当用户在 Clerk 注册或更新资料时,Clerk 会向我们配置的 Webhook URL 发送一个 POST 请求。 +2. **Supabase 接收并写入** : Edge Function 接收请求,验证签名(确保安全),然后将用户数据更新到 Supabase 的数据库表中。 + +在开始之前,我们需要配置同步معلومة所需的数据表: + +```sql +-- File: init.sql + +-- 1. Create `users` table for synced Clerk users +-- This table will store user data pushed from Clerk Webhooks. +CREATE TABLE public.users ( + id TEXT NOT NULL PRIMARY KEY, -- Corresponds to Clerk User ID + email TEXT, + first_name TEXT, + last_name TEXT, + image_url TEXT, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- 2. Enable Row Level Security (RLS) on the table +-- This is an important security measure to ensure users cannot access any data by default. +ALTER TABLE public.users ENABLE ROW LEVEL SECURITY; + +-- 3. Create RLS policies +-- Policy 1: Allow authenticated users to read their own user info. +-- `auth.jwt()->>'sub'` extracts the user ID from the JWT provided by Clerk. +CREATE POLICY "Authenticated users can view their own user record" +ON public.users FOR SELECT +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); + +-- Policy 2: Allow users to update their own info. +CREATE POLICY "Authenticated users can update their own user record" +ON public.users FOR UPDATE +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); +``` + +以及在 Supabase 中启用对应的 Edge function: + +```JavaScript +// File path: supabase/functions/clerk-webhooks/index.ts + +import { serve } from 'https://deno.land/std@0.177.0/http/server.ts' +import { Webhook } from 'npm:svix' +import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' + +// Get Clerk Webhook signing secret from environment variables +const CLERK_WEBHOOK_SECRET = Deno.env.get('CLERK_WEBHOOK_SECRET') + +if (!CLERK_WEBHOOK_SECRET) { + throw new Error('CLERK_WEBHOOK_SECRET is not set in environment variables') +} +const supabaseAdmin = createClient( + Deno.env.get('SUPABASE_URL')!, + Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')! +) + +serve(async (req) => { + try { + // 1. Get Svix signature info from request headers + const headers = Object.fromEntries(req.headers) + const svix_id = headers['svix-id'] + const svix_timestamp = headers['svix-timestamp'] + const svix_signature = headers['svix-signature'] + + if (!svix_id || !svix_timestamp || !svix_signature) { + return new Response('Missing Svix headers', { status: 400 }) + } + + const payload = await req.json() + const body = JSON.stringify(payload) + + // 2. Verify Webhook signature validity using the secret + const wh = new Webhook(CLERK_WEBHOOK_SECRET) + const evt = wh.verify(body, { + 'svix-id': svix_id, + 'svix-timestamp': svix_timestamp, + 'svix-signature': svix_signature, + }) + + const { id } = evt.data + const eventType = evt.type + console.log(`Received webhook event: ${eventType} for user: ${id}`) + + // 3. Execute database operations based on event type + switch (eventType) { + case 'user.created': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin.from('users').insert({ + id, + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + }) + if (error) throw error + console.log(`User ${id} created in Supabase.`) + break + } + + case 'user.updated': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin + .from('users') + .update({ + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + updated_at: new Date().toISOString(), // Update timestamp + }) + .eq('id', id) + if (error) throw error + console.log(`User ${id} updated in Supabase.`) + break + } + + case 'user.deleted': { + // For delete events, ID might be at the top level + const deletedId = id + if (!deletedId) { + return new Response('Deleted user ID not found', { status: 400 }) + } + const { error } = await supabaseAdmin.from('users').delete().eq('id', deletedId) + if (error) throw error + console.log(`User ${deletedId} deleted from Supabase.`) + break + } + } + + return new Response('Webhook processed successfully', { status: 200 }) + } catch (err) { + console.error('Error processing webhook:', err.message) + return new Response(`Webhook Error: ${err.message}`, { status: 400 }) + } +}) +``` + +初始化 Supabase 数据表与函数结束后,你还需要在 Clerk 中启用 Webhooks 支持: + +- 在 Clerk Dashboard -> **Webhooks** 中添加 Endpoint,填入Supabase Edge Function 的 URL。 +- 勾选 `user.created`, `user.updated`, `user.deleted` 等事件。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image65.png) + +一旦设置成功,你能够在 Message Attempts 中看到不同请求معلومة,点击后可看到详细的请求返回参数النتيجة;如果 webhook 在请求 Edge function 时出现问题,你可以快速在返回值中找到详细原因النتيجة。推荐你同时对照 Clerk 和 Supabase 的请求日志معلومة,用于分析各个函数设定是否正确。 + +### 5.6.4 Clerk 中的第三方登录支持 + +在深入了解如何对 Clerk 支持第三方登录前,我们先明确两个核心概念:开发环境与生产环境,这是软件从 “开发测试” 到 “上线可用” 的两个关键阶段,二者的定位、用途和安全要求截然不同: + +- 开发环境:开发者本地或测试服务器使用的环境,仅用于功能开发、调试和内部验证(如本地 localhost:3000 服务),不对外开放 +- 生产环境:应用正式上线后,面向真实用户的公开环境(如部署在 Vercel、阿里云等平台的 https://my-app.com) + +而 Clerk 对社交登录区分这两种环境,本质是平衡 “开发效率” 与 “生产安全”:开发阶段需减少冗余配置以快速验证功能,生产阶段需通过专属凭证保障数据安全,同时符合 Google、GitHub 等第三方 OAuth 平台的规则(线上应用必须绑定专属域名与凭证,不允许使用共享资源)。下面具体说明两种环境下 Clerk 社交登录的差异配置: + +1. **开发环境快速验证** + +开发环境中,Clerk 已预置共享 OAuth 凭证和默认重定向 URI,无需前往 GitHub/Google 申请专属凭证,操作خطوة如下: + +- 登录 Clerk Dashboard ,在左侧导航栏进入 SSO connections (SSO 连接)页面。 +- 点击 Add connection (添加连接),选择 For all users (对所有用户生效)。 +- 在 Choose provider (选择提供商)下拉菜单中,按需选择 GitHub 或 Google 。 +- 直接点击 Add connection (添加连接),Clerk 会自动用共享凭证完成绑定。 + + 配置后,本地启动应用(如 `localhost:3000`)并点击“Sign in with GitHub/Google”,Clerk 会自动代理登录请求,快速验证功能是否正常。 + +2. **生产环境自定义凭证配置** + +(注:如果发现有环节和预期不一致,建议阅读官方文档进行最新方式的尝试) + +应用部署上线(如 Vercel、阿里云)并切换到 Clerk Production Instance 后,共享凭证失效,需为 GitHub/Google 配置自定义 OAuth 凭证(建议同时打开 Clerk Dashboard 和第三方平台页面,方便同步操作): + +- 前置通用操作(Clerk 控制台): + - 进入 Clerk SSO connections 页面,点击 Add connection → 选择 For all users 。 + - 选择目标平台(GitHub/Google),确保开启 Enable for sign-up and sign-in (允许注册登录)和 Use custom credentials (使用自定义凭证)。 + - 复制页面中的 Authorization Callback URL (GitHub)或 Authorized Redirect URI (Google),保存到安全位置,不要关闭当前页面/弹窗。 +- 2.1 GitHub 平台配置: + - 登录 GitHub,进入 Developer Settings (路径:头像 → Settings → Developer settings → OAuth Apps)。 + - 点击 New OAuth app ,填写معلومة:`Application name`(应用名称)、`Homepage URL`(生产域名,如 `https://my-app.com`)、`Authorization Callback URL`(粘贴从 Clerk 复制的地址)。 + - 点击 Register application ,再点击 Generate a new client secret ,保存生成的 Client ID 和 Client Secret (Secret 仅显示一次)。 + - 回到 Clerk 弹窗,粘贴 Client ID 和 Client Secret,点击 Add connection 完成配置(若关闭弹窗,可在 SSO connections 找到 GitHub 连接,在“Use custom credentials”模块补填)。 +- 2.2 Google 平台配置: + - 登录 Google Cloud Console ,选择已有项目或新建项目(如“My App Production”)。 + - 点击左上角菜单 → APIs & Services → Credentials ,点击 Create Credentials → OAuth client ID (首次配置需先完成 OAuth consent screen 设置,选择“External”并填写应用معلومة)。 + - 选择 Application type 为 Web application ,配置: + 1. `Authorized JavaScript origins`:添加生产域名(如 `https://my-app.com`、`https://www.my-app.com`),本地验证可补充 `http://localhost:端口号`。 + 2. `Authorized Redirect URIs`:粘贴从 Clerk 复制的地址。 + - 点击 Create ,保存弹窗中的 Client ID 和 Client Secret ,回到 Clerk 弹窗粘贴并点击 Add connection 。 + - 关键ملاحظة事项: + 1. 禁止 WebView 登录:Google OAuth 不支持应用内浏览器登录,需参考 [Google 官方文档](https://support.google.com/cloud/answer/7657789) 调整。 + 2. 切换发布状态:默认“Testing”状态仅支持 100 个测试用户,需在 OAuth consent screen 将“Publishing status”改为 In production (需通过 Google 审核)。 + 3. 阻止子邮箱:Clerk 默认拦截含 `+`/`=`/`#` 的 Google 邮箱(如 `user+alias@example.com`),可在 Google 连接详情页开启/关闭 Block email subaddresses (建议开启提升安全性)。 + 4. 支持 Google One Tap:配置完成后,可集成 Clerk `` 组件实现“一键登录”,参考 [Clerk 组件文档](https://clerk.com/docs/components/social-connections/google-one-tap)。 + +3. 测试第三方登录连接 + +配置完成后,通过 Clerk 内置 Account Portal 验证功能: + +- 进入 Clerk Dashboard,左侧导航栏进入 Account Portal 页面。 +- 在“Sign-in”模块右侧,点击“访问登录页面”按钮,跳转至对应环境登录页: + - 开发环境:`https://你的域名.accounts.dev/sign-in`(如 `https://my-app.accounts.dev/sign-in`)。 + - 生产环境:`https://accounts.你的域名.com/sign-in`(如 `https://accounts.my-app.com/sign-in`)。 +- 点击“Sign in with GitHub/Google”,用对应平台账号登录,若能成功跳转并返回应用,说明连接配置正常。 + +# 6. 从 Supabase 到更多后端开发组件(进阶) + +在上文中,我们主要是站在 Supabase 的视角,去看“一个以 Postgres 为核心的一站式后端平台”能帮我们解决哪些问题:认证、数据库、文件存储、实时通信、边缘函数等,都被集成在同一个控制台里,开箱即用、体验统一,非常适合快速起步和中小型项目。 + +但从更长期、更工程化的角度来看, **Supabase 提供的每一块能力(Auth / Storage / Edge Functions / Realtime / Database),在业界几乎都有对应的专业替代方案** ——既包括同类 BaaS 平台,也包括更“单点突破”的云服务和开源组件。作为上进的个人开发者和初创团队来说,了解这些替代选项有几个好处: + +- 判断当前项目是否“全用 Supabase 就够了”,还是某一块需要更专业/更便宜/更易合规的专用服务; +- 当项目规模变大或需求变复杂时,是否可以把某个模块从 Supabase 替换出去(例如改用专门的 Auth 平台或对象存储),而不是一开始就被平台彻底锁死; +- 拓宽技术选型视野,即使暂时不更换,也能大致知道“如果不用 Supabase 的 X 功能,我还有哪些常见选择”。 + +本节将分别介绍 Supabase 所覆盖的几大能力在市场上的主流替代方案,例如:认证(Auth)、文件存储(Storage)、边缘函数(Edge Functions)、实时通信(Realtime)、数据库托管等。简单对比它们在功能特性、免费额度/定价、易用性以及社区流行度等方面的差异, 让你对后端组件工具库有更全面的理解。 + +## 同类 Baas 平台 + +在开始之前,我们可以浏览同类的 Baas 平台,若觉得 Supabase 不够好用,你可以根据需求选择不同替代品进行尝试。 + +| 平台/服务 | 类型 | 免费额度/定价 | 特点 / 适用场景 | +| ------------------------ | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| Firebase(Google) | 全托管 BaaS(Auth + Firestore + Storage + Functions + Hosting) | Spark:免费轻量额度;Blaze:按量计费(Firestore/Storage/Functions 分别算) | 行业最成熟、文档好、上手快、实时能力强。适用于中小型产品、移动/前端主导团队。缺点:计费复杂、锁定性强、查询限制多(尤其 Firestore)。 | +| Supabase | 开源 BaaS(Postgres + Auth + Storage + Edge Functions + Realtime) | 免费:500MB DB、1GB Storage、无服务器函数少量调用;Pro:按实例计费 | 最像 Firebase 的 SQL 版;界面优秀、体验现代、可自托管。适用于需要强 SQL、BI、事务能力的应用。缺点:高并发或复杂函数成本较高。 | +| Appwrite Cloud | 开源一站式 BaaS(DB + Auth + Storage + Functions + Realtime) | 免费:包含基本 DB/Storage/FaaS;付费按资源级别计费 | 体验现代化、API 统一、可自托管;适合开发者友好的应用快速迭代。缺点:生态还不如 Firebase/Supabase 成熟;性能在大型应用中需要测试。 | +| Nhost | Postgres + GraphQL + Auth + Storage + Functions | 免费:1GB DB、1GB Storage、少量函数调用 | 类似“Supabase + Hasura”;天然 GraphQL;适合前端团队与 React/Next.js 项目。缺点:生态小、成本随用量升高。 | +| AWS Amplify | AWS 一站式后端(Cognito + AppSync + DynamoDB + Storage + Functions + Hosting) | 免费:Hosting 额度 + Cognito 10k MAU + 部分函数额度 | 大而全,适合已有 AWS 基础的团队;企业级可靠性。缺点:最难上手,服务碎片化;初创团队维护成本高。 | +| Xata(近两年快速增长) | 多模型数据库 + Auth + Edge Functions | 免费:250k 记录、15GB 带宽 | 虽然更偏「DB + API」,但提供 Auth、文件、逻辑,可作为轻量全栈后端。UI/开发体验极佳。缺点:功能不如 Firebase/Supabase 全面。 | +| Convex(开发者体验极强) | 托管数据库 + Auth + Functions(前端优先) | 免费开发版;付费按请求量计费 | 极简上手;无需 schema;前端写函数即可用后端。适合 MVP/快速验证。缺点:高度绑定平台,迁移成本高;不算完全传统 BaaS。 | + +## 认证 (Auth) + +| 工具/平台 | 功能特点 | 免费额度/定价 | 适用场景与优缺点 | +| ----------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| Firebase Authentication | Google 提供的 BaaS 身份验证服务,支持邮箱/密码、手机、社交登录、匿名等常见方式。Spark 免费方案支持最高50k 月活跃用户。 | Spark(免费)50k MAU;Blaze 按量计费 | 集成 Google 生态,文档丰富,上手简单;功能全面(MFA、阻塞函数等),适合快速开发。但与 Firebase 平台绑定,扩展到其他服务需额外配置。 | +| Auth0 (Okta) | 全托管身份认证平台,支持社交登录、企业 SSO、多因子认证、规则扩展等强大功能。 | 免费方案25k MAU,付费按 MAU 计费 | 企业级功能齐全(RBAC、审计日志等),适合中大型应用;界面友好。缺点是 MAU 上升时成本高,免费版功能有限(如不含 MFA/RBAC)。社区知名度高,用户众多。 | +| AWS Cognito | 亚马逊云原生身份服务,支持社交及 SAML 联合登录。直接登录用户池提供每月10k MAU 免费,超过部分按 0.0055 美元/MAU 收费。 | 免费10k MAU/月,超出按量付费 | 与 AWS 生态深度集成(可无缝配合 API Gateway、Lambda 等),入门门槛略高,文档较复杂;免费额度有限,适合已有 AWS 使用习惯的团队。 | +| Logto | 开源身份认证平台,自托管版免费,云服务计划免费50k MAU。支持多语言、多租户、OAuth/OIDC 等。 | 社区版免费;Logto Cloud 免费50k MAU | 近期流行的 Auth0 开源替代方案,GitHub 已有 10k+ Stars。易扩展,自托管降低成本;缺点是生态和文档相对较新,社区规模略逊于 Firebase/Auth0。 | +| Keycloak | 知名开源 IAM/SSO 解决方案,支持用户名密码、LDAP、SAML、OAuth2 等。 | 完全免费,需自托管 | 功能强大、可扩展(支持细粒度权限控制),企业级功能丰富;但部署和维护复杂度高,对小团队而言学习曲线较陡。缺点是对容器化和集群运维要求较高。 | + +## 文件存储 (Storage) + +| 平台/服务 | 类型 | 免费额度/定价 | 特点/适用场景 | +| ---------------------------------------- | -------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| Amazon S3 | 云对象存储(AWS) | AWS 免费套餐提供 5GB 存储、20k GET/PUT 请求/月,超出按使用量付费 | 行业标准的对象存储,可靠性高、全球多区域部署。功能全面,与 AWS 生态整合良好;定价较复杂,新用户需了解计费规则。 | +| Google Cloud Storage(Firebase Storage) | 云对象存储(Google) | Firebase Spark 方案提供免费额度(1GB 存储 + 流量限制),Blaze 付费 | 与 Firebase/Google Cloud 紧密集成,易于管理;支持 CDN 加速、细粒度安全规则。 | +| 腾讯云 COS / 阿里云 OSS | 云对象存储(国内) | 按量付费(各有新用户赠送额度,如OSS有首年40GB免费等) | 面向国内市场,高性能、大规模对象存储;与中国云生态整合,文档较完善。阿里OSS 功能全面、全球加速;七牛KODO 专注多媒体处理,成本较低,适合个人和小团队。 | +| MinIO | 开源 S3 兼容存储 | 开源免费(自建) | 轻量级、高性能、与 S3 API 兼容,适合在私有云或本地搭建对象存储。文档和社区活跃;需自己维护基础设施。 | +| Cloudinary / Imgix 等 | 媒体存储+CDN | 基本免费方案(如 Cloudinary 免费 25GB/月带宽) | 针对图片/视频优化的云存储+CDN 服务,提供实时转码、压缩等高级功能。适合媒体项目,但功能较专一,作为通用文件存储使用成本偏高。 | + +## 边缘函数 (Edge Functions) + +| 平台/服务 | 特点 | 免费额度/定价 | 适用场景与优缺点 | +| -------------------------------------- | ------------------------------------------ | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Cloudflare Workers | 全球分布式 JavaScript/Wasmtime 环境 | 免费计划:每天 100k 请求;标准计划$5/月含1,000万请求 | 运行在 Cloudflare 边缘节点,延迟极低;适合全局分发的逻辑、静态资源渲染等。免费配额较少(相当于每月约300万请求),上手简单。缺点是运行时(JS/Wasmtime)限制与调试工具有限。 | +| Vercel Edge Functions | 随 Next.js/前端框架无缝集成,支持 JS/TS/Go | Hobby 免费:每月 100万 函数调用,100万 边缘请求 | 深度集成前端框架,自动部署;适合现代 Web 应用。免费额度充足,默认运行时 10s,可提升至 60s。缺点是免费版团队协作功能受限;依赖 Vercel 平台。 | +| Netlify Edge / Functions | Node.js 云函数+边缘路由(NFT) | 免费:300 代币/月(约相当于每月 1M 请求);按信用点计费 | 支持 Node.js 函数、边缘处理路由等。免费额度用于构建、函数和带宽,适合前端全栈部署。优点是简便易用,集成 Git 部署;缺点是免费额度使用需算计(10k 请求 = 3 点)。 | +| AWS Lambda@Edge / CloudFront Functions | AWS 无服务器边缘计算 | AWS Lambda(1M 免费请求/月+400k GB-s)+ CloudFront $0.085/每10万调用起 | 与 CloudFront 集成,可在边缘执行代码。适合需要 AWS 生态(如在节点层面做权限或 A/B 测试)。优点是灵活强大;缺点是配置复杂,延迟略高于 Cloudflare/Vercel。 | + +## 实时通信 (Realtime) + +| 平台/服务 | 功能特点 | 免费额度/定价 | 适用场景与优缺点 | +| -------------------------------------- | ------------------------------------------------ | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| Firebase Realtime Database / Firestore | Google BaaS 实时数据库;支持数据变更推送 | Spark 免费:实时数据库1GB 存储 & 限额;Blaze 按量付费 | 强集成 Firebase 生态,实时监听简单。优点是免费起步快;缺点是数据库类型(JSON/NoSQL),复杂查询能力弱。 | +| Ably | 实时消息与 pub/sub 平台,支持 WebSocket、MQTT 等 | 免费包:每月 6,000,000 条消息 | 功能全面的实时消息服务,高并发支持;免费额度可达600万消息/月。社区与文档较好,适合全球分布。 | +| Pusher Channels | 事件推送服务,支持频道/事件机制 | Sandbox 免费:每日 200k 消息,100 并发连接 | 易用的 WebSocket 服务,文档齐全,适合快速实现聊天和通知功能。免费版限制消息量和连接数;付费后扩展性好。 | +| 自建 WebSocket/Socket.IO | 自己搭建服务器(Node.js、Elixir 或 Go 等) | 自行托管成本(如服务器费用) | 灵活度最高,可根据需求定制协议和拓扑。适合对成本控制严格且技术成熟的团队。缺点是需自行处理可用性、扩展和跨域等问题。 | + +## 数据库 + +| 平台/工具 | 数据库类型 | 免费额度/定价 | 主要特点 | +| ---------------------------- | --------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| Neon (Serverless PostgreSQL) | 关系型(PostgreSQL) | 免费计划:0.5GB 存储,主分支永久在线,20h 分支计算/月 | 云原生无服务器 Postgres,支持自动伸缩和分支(fork 测试)。免费额度对小项目够用,适合现代开发流程。分支功能强大,但免费额度较小。 | +| Aiven PostgreSQL | 关系型(PostgreSQL/MySQL) | 免费计划:1GB 存储,1 vCPU,1GB 内存 | 托管级数据库服务,支持跨云多区域迁移。提供有 MySQL、Redis 等可选。免费额度适合开发和小型项目;商业版支持高可用集群和监控。 | +| CockroachDB Cloud | 分布式 SQL(兼容 PostgreSQL) | 免费计划:10GB 存储 | 类似 Google Spanner 的分布式 SQL 数据库,自动分片扩展。免费10GB 空间较慷慨;适合需要横向扩展和高一致性的应用。商业版 SLA 高。 | +| TiDB Cloud | 分布式关系型(MySQL 兼容) | 免费计划:每节点5GB,总计最多25GB | 开源 TiDB 的云版,兼容 MySQL 协议,分布式架构。免费额度充足,适合熟悉 MySQL 的团队,性能优秀;缺点是运维相对复杂(针对大型场景)。 | +| MongoDB Atlas | 文档型(NoSQL MongoDB) | 免费 M0 集群:0.5GB 存储 | 云端 MongoDB,灵活的文档模型,支持丰富查询和索引。免费 0.5GB 数据库适合测试和小型应用;可按需横向扩展。学习曲线略高于关系型数据库。 | +| SQLPub | 多数据库(MySQL、PostgreSQL、Redis 等) | 免费计划:36,000 请求/小时,30 并发连接,500MB 存储 | 一站式数据库平台,支持多种数据库类型。免费版适合学习和小项目;优点是支持多种 DB,缺点是存储额度较小。 | + +以上替代方案各有侧重:开源更灵活可控(Keycloak、MinIO、Socket.IO、Neon、CockroachDB 等),云托管服务更易上手(Firebase、Auth0、Cloudflare、Vercel、Netlify、AWS、Aiven、MongoDB Atlas 等)。选择时可根据项目需求、团队技术栈、预算和社区生态等权衡。个人项目可优先选用免费配额充足、易集成的服务(如 Firebase 系列、七牛存储、Cloudflare Workers、Neon、CockroachDB 等),而对企业级或特定安全需求,则可考虑功能更丰富但收费较高的方案(Auth0、Alibaba/Tencent 云、AWS、TiDB/Aiven 等)。你可以在实际应用中不断尝试,直到选择出最适合的后端开发工具组件。 + +# الخلاصة + +在今天的课程中,我们系统学习了数据库的基础概念、Supabase 的核心定义及其操作细节。后续在实践过程中,你可根据项目的实际应用场景与需求,随时回头翻阅这份文档作为参考。 + +请时刻记住一个مهم原则: **先完成,再完美!** 无需追求一步到位,我们完全可以通过持续迭代优化,逐步靠近更优的成果。祝你在后续的项目实践中一切顺利! + +# 📚 الواجب المنزلي + +1. 开发一个包含用户管理系统和数据库的应用程序。最好包含更多的Supabase 功能 (Realtime / cloud storage / Edge function). diff --git a/docs/ar-sa/stage-2/backend/git-workflow/index.md b/docs/ar-sa/stage-2/backend/git-workflow/index.md new file mode 100644 index 0000000..f0ba5e7 --- /dev/null +++ b/docs/ar-sa/stage-2/backend/git-workflow/index.md @@ -0,0 +1,261 @@ +# سير عمل Git و GitHub + +في الدروس السابقة، تعلمنا كيفية استخدام أدوات vibe coding القائمة على الويب لكتابة الكود. كل محادثة تنشئ إصدارًا جديدًا من الكود. لكن دعونا نفكر في سؤال: إذا أردنا العودة إلى تعديل سابق، هل هناك طريقة سهلة؟ هل توجد أداة يمكنها تسجيل الكود في مراحله المختلفة، بحيث نتمكن من التبديل والتعديل بين الإصدارات المختلفة في أي وقت؟ + +لتلبية هذه الحاجة، ظهرت برامج التحكم في الإصدارات. في هذه المقالة، سنقدم أشهر برنامج للتحكم في الإصدارات — Git — وأفضل منصة لاستضافة الكود — GitHub. سنتعلم كيفية استخدام Git لإدارة الكود، وكيفية الحصول على كود الآخرين من GitHub، وكيفية رفع كودنا الخاص، وكيفية التعاون مع الآخرين في المشاريع الكبيرة. + +سواء كان ذلك لتتبع إصدارات المشروع الشخصي، أو مزامنة الكود في العمل الجماعي، أو المساهمة في مجتمع المصادر المفتوحة، فإن Git و GitHub هما أدوات أساسية للمطورين المعاصرين. من خلال إتقانهما، ستتمكن من إدارة الكود بكفاءة أكبر، وإنشاء نقاط فحص حسب الحاجة، والتنقل بحرية بين مراحل الكود المختلفة، والتعامل بسهولة مع كل شيء بدءًا من تغيير ملف واحد إلى تطوير مشاريع كبيرة — مما يجعل كل تكرار للكود خاضعًا للتحكم وقابلًا للتتبع. + +> 💡 **المعارف المسبقة** +> +> قبل تعلم Git، يُنصح بأن تكون على دراية بالمفاهيم التالية: +> - [ما هو الطرفية/سطر الأوامر](/ar-sa/appendix/2-development-tools/command-line-shell) - تعلم كيفية استخدام سطر الأوامر للتفاعل مع الحاسوب +> - [ما هو Git](/ar-sa/appendix/2-development-tools/git-version-control) - فهم المفاهيم الأساسية لنظام التحكم في إصدارات Git +> +> ستركز هذه المقالة على سير عمل GitHub والعمليات العملية، ويمكن الرجوع للمحتوى الأساسي عبر روابط **الملحق**. + +# البدء السريع مع Git + +قبل البدء باستخدام Git، تأكد من أنك قرأت المحتوى في **الملحق** حول [سطر الأوامر](/ar-sa/appendix/2-development-tools/command-line-shell) و[أساسيات Git](/ar-sa/appendix/2-development-tools/git-version-control). تفترض هذه المقالة أنك تملك هذه المعارف الأساسية، وتشرح مباشرة كيفية تثبيت وإعداد Git واستخدام GitHub للتعاون. + +## كيفية تثبيت Git + +سنعرض ثلاث طرق لتثبيت Git على أنظمة تشغيل مختلفة. يرجى اتباع التعليمات حسب إصدار نظامك: + +### Windows + +1. انتقل إلى [صفحة تحميل Git الرسمية](https://git-scm.com/download/win) وقم بتنزيل برنامج التثبيت المناسب لنظامك: [حزمة التثبيت](https://github.com/git-for-windows/git/releases/download/v2.51.0.windows.1/Git-2.51.0-64-bit.exe). بشكل افتراضي، يُنصح باستخدام مثبت x64. +2. انقر نقرًا مزدوجًا على برنامج التثبيت واتبع تعليمات معالج التثبيت: + ![](/zh-cn/stage-2/backend/git-workflow/images/image5.png) + 1. يُنصح بالحفاظ على الخيارات الافتراضية. إذا احتجت إلى التخصيص، يرجى **ملاحظة** النقاط التالية: (في معظم الحالات، يمكنك النقر باستمرار على "Next") + - اختيار المحرر الافتراضي لـ Git: اختر المحرر المفضل لديك (مثل VS Code). يمكنك اختيار الخيار الأول افتراضيًا، وهو Vim (محرر نصوص)، أو اختيار خيار "Visual Studio Code as Git's default editor" (يتطلب تثبيت VS Code مسبقًا). يمكنك الاحتفاظ بالاختيار الافتراضي والنقر على "Next" للمتابعة. + ![](/zh-cn/stage-2/backend/git-workflow/images/image6.png) + - اختيار كيفية استخدام Git: تتحكم هذه الخيارات الثلاثة في إمكانية الوصول إلى Git في النظام. يُنصح باختيار الخيار 2 ("from command line and 3rd-party software") — فهو يضيف أدوات Git الأساسية إلى PATH، مما يتيح لك استخدام Git في Git Bash وموجه **الأوامر** و PowerShell وبيئات التطوير دون إحداث فوضى في النظام. + ![](/zh-cn/stage-2/backend/git-workflow/images/image7.png) + +3. بعد التثبيت، انقر بزر الماوس الأيمن على سطح المكتب. إذا رأيت "Git Bash Here" في القائمة، فقد تم التثبيت بنجاح. + +![](/zh-cn/stage-2/backend/git-workflow/images/image8.png) + +### MacOS + +بالنسبة لـ macOS، يمكنك أولاً إدخال `git --version` في الطرفية للتحقق مما إذا كان Git مثبتًا بالفعل. إذا لم يكن كذلك، سيُ**نبه**ك النظام للتثبيت — فقط اتبع التعليمات لإكمال التثبيت. + +1. الطريقة 1: التثبيت عبر Homebrew + إذا قمت بتثبيت [Homebrew](https://brew.sh/) (مدير حزم Mac)، افتح الطرفية وأدخل + ```bash + brew install git + ``` +2. الطريقة 2: (مُوصى بها) التثبيت عبر Xcode: https://developer.apple.com/xcode/ ، يتضمن Xcode Git مدمجًا. بعد التثبيت، فقط اتبع التعليمات للمتابعة. + +### Linux + +يمكن تثبيت Git على معظم توزيعات Linux عبر مدير الحزم: + +- Ubuntu/Debian: + +```bash +sudo apt update +sudo apt install git +``` + +- CentOS/RHEL: + +```bash +sudo yum install git +``` + +- التحقق من التثبيت: أدخل `git --version` في الطرفية. إذا ظهر رقم الإصدار، فقد تم التثبيت بنجاح. + +## تهيئة Git + +بعد تثبيت Git، تحتاج أولاً إلى إعداد **معلومات** المستخدم — هذه **خطوة** أساسية لاستخدام Git في التحكم في الإصدارات. نفذ الأوامر التالية في الطرفية (استبدل المحتوى بين الأقواس بمعلوماتك الخاصة): + +```bash +# تعيين اسم المستخدم العام (سيظهر في سجل الالتزامات) +git config --global user.name "Your Name" + +# تعيين البريد الإلكتروني العام (يُنصح باستخدام البريد المسجل على GitHub/GitLab) +git config --global user.email "your.email@example.com" +``` + +سيقوم Git بتضمين هذه **المعلومات** في كل سجل التزام، كـ"معلومات المؤلف" لكل تعديل. عند عرض سجل الإصدارات (مثلاً باستخدام `git log`)، يمكنك رؤية بوضوح من قام بتعديل كل سطر كود، مما يسهل تتبع المسؤولية والتواصل. في المشاريع التعاونية، تجعل **معلومات** الهوية الموحدة أعضاء الفريق قادرين على التعرف بسرعة على من أجرى التغييرات، مما يرفع كفاءة التعاون (مثلاً العثور على المطور المعني عبر سجلات الالتزام لمناقشة المشكلات). + +يمكنك التحقق من **معلومات** إعدادات Git الحالية بإدخال `git config --list` في سطر الأوامر للتأكد من نجاح الإعداد. + +# ما هو GitHub + +GitHub هي منصة استضافة كود مبنية على Git. لا توفر فقط تخزينًا بعيدًا لمستودعات Git، بل تتضمن أيضًا أدوات تعاون (مثل Issues، Pull Requests، Projects)، مما يسهل على المطورين مشاركة الكود والتعاون. باختصار، Git هو أداة تحكم في الإصدارات محلية، بينما GitHub هو "قرص سحابي لمستودعات الكود + مجتمع تعاوني" بعيد. + +GitHub ليست فقط أكبر منصة استضافة كود في العالم، بل هي أيضًا أكثر مجتمعات المصادر المفتوحة نشاطًا وتأثيرًا عالميًا. الفكرة الأساسية لـ "المصادر المفتوحة" هنا هي أن أي شخص يمكنه تنزيل وتشغيل الكود المصدري للبرنامج. يسمح هذا النموذج للأشخاص حول العالم بمراجعة كود بعضهم البعض وإجراء التعديلات، أو إنشاء مشاريع جديدة بناءً عليه. على سبيل المثال، يمكنك العثور على GitHub على دروس تعليمية متنوعة والكود المصدري الكامل لأطر تدريب نماذج GPT (مثل PyTorch). يوميًا، يتعاون عدد لا يحصى من الأشخاص حول العالم في مراجعة وتحسين الكود. + +![](/zh-cn/stage-2/backend/git-workflow/images/image9.png) + +العديد من الشركات الكبرى تفتح مصدر برامجها أو دروسها على GitHub للحصول على ميزة تنافسية في الصناعة — ويمكن اعتبار ذلك شكلاً من أشكال الإعلان. في مجتمع GitHub، عدد "النجوم (stars)" التي يحصل عليها المشروع هو المؤشر الرئيسي لقياس قيمته؛ كلما زاد عدد النجوم التي يملكها المشروع أو المنظمة، زادت مصداقيته وتأثيره. + +![](/zh-cn/stage-2/backend/git-workflow/images/image10.png) + +في دورتنا، سيتم رفع الموارد الداعمة والواجبات أيضًا إلى مستودع GitHub مخصص. من خلال عملية رفع الواجبات، ستتعلم تدريجيًا وتتقن استخدام GitHub، مما يضع أساسًا متينًا للتحكم في الإصدارات في تطوير التطبيقات المستقبلي. + +## إنشاء حساب GitHub + +1. انتقل إلى [موقع GitHub الرسمي](https://github.com/) وانقر على "Sign up" في الزاوية العلوية اليمنى. + ![](/zh-cn/stage-2/backend/git-workflow/images/image11.png) +2. أدخل عنوان بريدك الإلكتروني (يُنصح باستخدام بريد إلكتروني شائع الاستخدام، حيث سيتم إرسال التحقق والإشعارات إليه)، وقم بتعيين كلمة مرور (يجب أن تتضمن أحرفًا وأرقامًا وأحرفًا خاصة). +3. أكد التحقق البشري، واتبع **التعليمات** للتحقق من بريدك الإلكتروني، وسيتم إنشاء حسابك. + +## إنشاء مستودعك الأول على GitHub + +بعد ذلك، سننشئ أول مجلد تخزين، والذي يُعرف أيضًا بالمستودع أو "repo". + +![](/zh-cn/stage-2/backend/git-workflow/images/image12.png)![](/zh-cn/stage-2/backend/git-workflow/images/image13.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image14.png) + +1. Repository name: اسم المستودع كما سيظهر للآخرين. +2. Description: وصف تفصيلي للمستودع. +3. Choose visibility: للمستودعات الشخصية، إذا تم تعيينها كـ private، فلن يتمكن إلا أنت والأشخاص المدعوون خصيصًا من رؤيتها. إذا تم تعيينها كـ public، فسيتمكن الجميع من رؤيتها. + بالنسبة للمستودعات داخل المنظمة، إذا كانت Private، فلن يتمكن إلا أعضاء المنظمة من رؤيتها. + إذا كانت Public، يمكن للأشخاص خارج المنظمة رؤيتها أيضًا. +4. README: العرف السائد هو أن يكون لكل مستودع ملف README. يمكنك اعتباره مقدمة شاملة للمستودع، تتضمن تعليمات الاستخدام وقائمة الملفات وطرق التشغيل. +5. Add .gitignore and license: + 1. يخبر ملف .gitignore نظام Git بتجاهل مجلدات أو ملفات معينة عند الرفع إلى GitHub، وبالتالي لن يتم تتبعها أو إضافتها إلى منطقة الإعداد. هذا مفيد لملفات الاختبار المؤقتة أو حزم التبعية أو الملفات الكبيرة. بمجرد التحديد، لن يتم تتبع هذه الملفات بعد الآن. + 2. يشير license إلى نوع ترخيص المصدر المفتوح الذي تختاره. تُفصل التراخيص المختلفة ما إذا كان يمكن للآخرين استخدام كودك لأغراض تجارية، وتتضمن شروطًا وأحكامًا أخرى. + +يُنصح بتحديد "Add README"، وتعيين رؤية المستودع إلى "Private"، وملء اسم المستودع والوصف حسب تفضيلاتك، ثم النقر على "Create repository" لإكمال إنشاء أول مستودع بعيد. + +![](/zh-cn/stage-2/backend/git-workflow/images/image15.png) + +بعد ذلك، ستمتلك مستودعًا نظيفًا بدون أي ملفات إضافية. يمكنك الآن البدء برفع الملفات. + +![](/zh-cn/stage-2/backend/git-workflow/images/image16.png) + +أمر الحصول على المستودع هو `git clone`، لكنه يحتاج إلى عنوان المستودع. يمكنك العثور على عنوان المستودع بالنقر على زر "Code" الأخضر، حيث سترى خيارات HTTPS و SSH. عادةً، يمكنك استخدام أي من الطريقتين لتنزيل المستودع على جهازك المحلي (فقط بهذه الطريقة يمكنك تعديل الملفات ورفعها). + +![](/zh-cn/stage-2/backend/git-workflow/images/image17.png) + +بشكل عام، استنساخ المستودعات عبر HTTP مناسب للتنزيل المؤقت واختبار مستودعات الآخرين، لكن لا يُنصح به للتطوير الشخصي. للحصول على تجربة تعلم أفضل، يجب عليك إعداد مصادقة SSH أولاً. + +## ربط SSH المحلي + +في GitHub، يعني "ربط بروتوكول SSH" أساسًا ربط مفتاح SSH العام لجهازك المحلي بحساب GitHub الخاص بك، مما يسمح لـ GitHub بالتعرف على جهازك عبر بروتوكول SSH. هذا يتيح لك تشغيل المستودعات البعيدة بأمان دون الحاجة إلى كلمة مرور (مثل استنساخ أو دفع أو سحب الكود). + +ببساطة: الأمر يشبه إعطاء جهازك "بطاقة دخول خاصة بـ GitHub". بعد الربط، عندما يصل جهازك إلى مستودعات GitHub عبر بروتوكول SSH، سيتحقق GitHub من "بطاقة الدخول" هذه (مفتاح SSH العام الخاص بك). بمجرد التأكد من أنه جهازك المصرح لك، يمكنك العمل مباشرة — دون الحاجة لإدخال اسم المستخدم وكلمة المرور في كل مرة. + +> 💡 ما هو SSH + +### لماذا نحتاج إلى ربط بروتوكول SSH؟ + +يدعم GitHub بروتوكولين رئيسيين لتشغيل المستودعات: بروتوكول HTTPS وبروتوكول SSH: + +- بروتوكول HTTPS: كل عملية (مثل push) تتطلب إدخال اسم المستخدم وكلمة المرور لـ GitHub (أو رمز الوصول الشخصي PAT). عملية التحقق مرهقة وتحمل خطر تسريب كلمة المرور. +- بروتوكول SSH: تتم المصادقة عبر "زوج مفاتيح"، لذلك لا حاجة لإدخال كلمة المرور بشكل متكرر، والنقل المشفر أكثر أمانًا. + +"ربط بروتوكول SSH" هو **خطوة** أساسية لتفعيل مصادقة GitHub عبر SSH — فقط بعد "ربط" مفتاح SSH العام المحلي بحساب GitHub، يمكن لـ GitHub التعرف على جهازك والسماح بعمليات SSH على المستودع. + +### المنطق الأساسي لـ "الربط": دور زوج مفاتيح SSH + +تعتمد مصادقة SSH على زوج مفاتيح (مفتاح عام + مفتاح خاص)، وهما ملفات تشفير متطابقة. بعد التوليد، تحتاج إلى تقديم "المفتاح العام" لـ GitHub ("الربط")، بينما يبقى "المفتاح الخاص" على جهازك المحلي: + +1. المفتاح الخاص: يُخزن على جهازك المحلي (مثل الحاسوب) في دليل محدد (عادةً `~/.ssh/`)، ويعمل كـ"مفتاحك الحصري"، ويجب عدم مشاركته مع أي شخص نهائيًا. +2. المفتاح العام: هذا "قفل" يمكن مشاركته علنًا — تحتاج إلى نسخه إلى قائمة "SSH keys" في حساب GitHub (عملية "الربط"). + +عندما تشغل مستودع GitHub عبر SSH (مثلاً `git push git@github.com:xxx/xxx.git`): + +- يستخدم جهازك المحلي المفتاح الخاص لتشفير "طلب العملية" وإرساله إلى GitHub؛ +- بعد استلام الطلب، يحاول GitHub فك التشفير باستخدام المفتاح العام الذي ربطته سابقًا؛ +- إذا نجح فك التشفير، يتم تأكيد أن جهازك مصرح لك، وتُسمح العملية؛ وإلا، يُرفض الوصول. + +### **خطوات** "الربط" العملية (العملية الأساسية) + +بمجرد فهمك للمبدأ، تصبح العملية الفعلية بسيطة — الجوهر هو "توليد زوج مفاتيح ← رفع المفتاح العام إلى GitHub": + +1. توليد زوج مفاتيح SSH محليًا + 1. استخدام Trae للحصول على المفتاح العام (مُوصى بها) + **نصيحة**: `Help me create the SSH key needed for GitHub login. My email is your_email@gmail.com , Please return the public key for me to copy` + + ![](/zh-cn/stage-2/backend/git-workflow/images/image18.png) + + بعد إدخال **النصيحة**، تحتاج أيضًا إلى الضغط على Enter في الطرفية على اليسار، وإلا سينتظر الأمر دون تنفيذ. بما أن Trae لا يمكنه تنفيذ أي أحكام شرطية، نحتاج فقط للضغط المستمر على Enter. + + أخيرًا، سترى Trae على اليمين قد أعاد المفتاح العام الذي قرأه. فقط انسخه واستعد للصقه في **الخطوة التالية**. + + ![](/zh-cn/stage-2/backend/git-workflow/images/image19.png) 2. الحصول على المفتاح العام يدويًا + افتح طرفيتك المحلية (على Windows استخدم Git Bash أو PowerShell؛ على macOS/Linux استخدم الطرفية)، وأدخل الأمر التالي (استبدل `your_email@example.com` بالبريد الإلكتروني المستخدم عند تسجيل حساب GitHub): + + ```bash + ssh-keygen -t ed25519 -C "your_email@example.com" + ``` + + 1. اضغط Enter لقبول القيم الافتراضية (مسار الملف الافتراضي، بدون كلمة مرور، أو قم بتعيين كلمة مرور حسب الحاجة). سيؤدي هذا إلى توليد ملفين في دليل `~/.ssh/`: + - `id_ed25519`: المفتاح الخاص (محفوظ محليًا، **لا تشاركه أبدًا**)؛ + - `id_ed25519.pub`: المفتاح العام (يجب رفعه إلى GitHub). + +2. "ربط" المفتاح العام بحساب GitHub + +هذه هي **خطوة** الربط الأساسية — إضافة المفتاح العام المحلي إلى قائمة "SSH keys" في حساب GitHub: + +1. نسخ محتوى المفتاح العام: + 1. Trae: + 2. Windows: افتح `C:\Users\\.ssh\id_ed25519.pub` بالمفكرة وانسخ كل محتواه؛ + 3. macOS/Linux: شغّل `cat ~/.ssh/id_ed25519.pub` في الطرفية وانسخ كل المخرجات (من بداية `ssh-ed25519` إلى البريد الإلكتروني في النهاية). +2. سجل الدخول إلى GitHub وانتقل إلى صفحة "إدارة SSH Key": + 1. انقر على الصورة الرمزية في الزاوية العلوية اليمنى ← Settings ← القائمة الجانبية SSH and GPG keys ← انقر على New SSH key. + ![](/zh-cn/stage-2/backend/git-workflow/images/image20.png)![](/zh-cn/stage-2/backend/git-workflow/images/image21.png) + 2. أدخل أي عنوان (مثل "your local computer's SSH")، ثم الصق مفتاح SSH العام الذي حصلت عليه للتو هنا. + +![](/zh-cn/stage-2/backend/git-workflow/images/image22.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image23.png) + +3. التحقق من نجاح الربط + +أدخل الأمر التالي في الطرفية (**يمكن لـ Trae أيضًا تنفيذ العمليات التالية**) لاختبار ما إذا كان GitHub يمكنه التعرف على جهازك: + +```bash +ssh -T git@github.com +``` + +- إذا رأيت رسالة مثل `Hi [your GitHub username]! You've successfully authenticated...`، فهذا يعني أنك ربطت المفتاح بنجاح؛ +- إذا واجهت أخطاء، فعادةً يكون السبب نسخ المفتاح العام بشكل غير كامل، أو صلاحيات المفتاح الخاص مرتفعة للغاية (دليل `~/.ssh/` المحلي يجب أن يكون قابلًا للقراءة والكتابة من قبلك فقط). تحقق من هذه المشكلات حسب الحاجة. + +### **ملاحظات مهمة** + +إذا كان لديك أجهزة متعددة (مثل حاسوب محمول وحاسوب مكتبي)، تحتاج إلى توليد زوج مفاتيح SSH منفصل لكل جهاز، وربط كل مفتاح عام بنفس حساب GitHub — كل جهاز يملك "بطاقة دخول" خاصة به. + +لا تشارك أبدًا مفتاحك الخاص (لا ترفعه إلى GitHub أو تشاركه مع الآخرين)، وإلا قد ينتحل شخصيتك لتشغيل مستودعاتك. إذا تم تسريب المفتاح الخاص، احذف المفتاح العام المقابل من GitHub فورًا وقم بتوليد زوج مفاتيح جديد. + +بعد ربط SSH، استخدم عنوان المستودع بتنسيق SSH (مثل `git@github.com:username/repository.git`) للعمليات، بدلاً من تنسيق HTTPS (مثل `https://github.com/username/repository.git`). إذا كنت قد استنسخت المستودع سابقًا عبر HTTPS، يمكنك تبديل البروتوكول باستخدام `git remote set-url origin `. + +# استخدام Trae لعمليات GitHub + +لقد شرحنا ما هو Git، وما هو GitHub، وما هو SSH، وكيفية إعداده. الآن يمكنك استخدام Trae بحرية لتنفيذ عمليات Git. أولًا، لنتعلم كيفية استنساخ مستودع بعيد إلى جهازك المحلي. + +## Git clone: تنزيل مستودع موجود + +يمكنك ببساطة إخباره بعنوان المستودع الذي تريد استنساخه + +![](/zh-cn/stage-2/backend/git-workflow/images/image24.png) + +## Git pull: الحصول على التحديثات من المستودع البعيد + +قبل تحديث المستودع في كل مرة، وبما أنه قد يكون مشتركًا بين عدة أشخاص، تحتاج أولاً إلى سحب أحدث التغييرات. بعد ذلك، يمكنك تعديل الملفات ودفعها. + +**تأكد من تضمين اسم المجلد ومساره النسبي أو المطلق، لتجنب الدفع إلى مستودع خاطئ.** + +prompt:`Help me pull this repository AIID-TEST in ./AIID-TEST.` + +## Git commit & Git push: تحضير التحديثات ودفعها إلى GitHub + +عندما يكون كل شيء جاهزًا، يمكنك محاولة تعديل الملفات المحلية، أو إضافة أو حذف عناصر في المجلد. ثم اطلب من Trae اكتشاف التغييرات ومساعدتك في دفعها إلى GitHub. + +prompt:`I finished. Commit and push to the repository AIID-TEST in ./AIID-TEST.` + +![](/zh-cn/stage-2/backend/git-workflow/images/image25.png) + +تم الدفع بنجاح. يمكنك الآن رؤية المحتوى المُحدَّث على GitHub. + +# المراجع + +- Pro Git book https://git-scm.com/book/en/v2 +- GitHub Docs https://docs.github.com/en diff --git a/docs/ar-sa/stage-2/backend/modern-cli/index.md b/docs/ar-sa/stage-2/backend/modern-cli/index.md new file mode 100644 index 0000000..2564f36 --- /dev/null +++ b/docs/ar-sa/stage-2/backend/modern-cli/index.md @@ -0,0 +1,801 @@ +# أدوات برمجة CLI AI + +在本教程中,我们将介绍直接在命令行中运行的 AI 编程 Agent。它们和之前学过的 Trae、Cursor 中的 Agent 不同,CLI AI 编程工具只能在终端中使用。与集成在 AI IDE 里的 Agent 相比,它们通常具有更长的上下文窗口、更快的工具调用速度,并且可以兼容更多种类的大模型。在最新的 AI Vibe Coding تطبيق عملي中,我们往往会优先使用 CLI AI 编程工具,而不是 IDE 内置的编码 Agent。 + +## 从 CLI 说起 + +还记得我们之前介绍过的 CLI 吗?CLI 指的是通过终端或命令نصيحة符,用纯文本命令来操作软件应用,而不是依赖图形界面(GUI——你可以简单理解为电脑或手机上带按钮、可以点击操作的界面,不需要输入命令)。 + +> 在 Windows 上,常见的终端有“命令نصيحة符(cmd)”和 “PowerShell”。你可以在电脑的运行/搜索框中输入 “cmd” 或 “powershell” 来启动这些命令行程序。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image1.png)![](/zh-cn/stage-2/backend/modern-cli/images/image2.png) + +CLI 天生适合文本命令操作,在一小部分极客(追求极致的编程爱好者)群体中,CLI 甚至比 GUI 更受欢迎——他们希望所有操作都通过键盘完成,觉得动鼠标反而会拖慢自己的编码效率。 + +在工业界,CLI 往往也是最常见的接口形式,因为 GUI 需要操作系统额外绘制界面、管理窗口,对计算机资源的要求更高;而 CLI 只需要把收到的命令传给系统执行即可。因此,在连接大规模服务器集群时,我们通常只通过 CLI 进行交互。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image3.png) + +对于许多没有 CLI 经验的同学来说,可能会觉得 CLI 操作很复杂、命令太多,甚至担心“一不小心就把电脑搞坏”。不用担心。还记得我们在前面教程里,经常让 Trae 帮忙完成各种基础操作吗?这里也可以完全照搬这个思路——我们可以让 CLI 编程工具帮我们执行所有 CLI 操作:让它帮你进入指定文件夹、搜索和处理文件、运行或复制开源项目等。整个过程都可以通过和 CLI AI 编程工具的对话来完成。 + +## 和 AI IDE 有什么不同 + +我们可以把 CLI AI 编程工具类比成之前学过的 z.ai 和 Trae。某种意义上,CLI AI 编程工具可以看成是一种特殊的 z.ai:它们同样只需要一个简单的对话入口,就会自动为你执行所有需要的操作(只是有时你需要手动打开浏览器查看最终效果)。而如果类比 AI IDE,那么 CLI AI 编程工具可以被看作是 IDE 中的 Agent 模块——也就是侧边那块对话区域。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image4.png)![](/zh-cn/stage-2/backend/modern-cli/images/image5.png) + +不过,由于不同 AI IDE 对 Agent 的实现方式不同,能力差异也很大,AI 编程效果经常不稳定,因此 CLI AI 编程工具通常由大型科技公司直接开发,例如 Claude 背后的 Anthropic、ChatGPT 背后的 OpenAI 等。 + +相比其他 AI 编程 Agent,直接使用这些大厂产品往往是较优的实践,尤其是 Claude Code 本身就是为 Anthropic 内部研发团队服务的工具,从一开始就围绕“满足工程师真实需求”来设计。 + +为了更直观地对比,我们可以简单看看 Claude Code 和某款 AI IDE Agent 的差异(这里以 Cursor 为例): + +| 功能特性 | Claude Code | Cursor | 更优者 | +| ----------------- | ------------- | --------------- | ----------- | +| 自动任务执行 | ✅ 非常强 | ❌ 能力有限 | Claude Code | +| IDE 集成 | ❌ 仅命令行 | ✅ 原生 VS Code | Cursor | +| 实时代码补全 | ❌ 无 | ✅ 体验极佳 | Cursor | +| 多文件操作 | ✅ 非常强 | ⚠️ 还不错 | Claude Code | +| GitHub 一体化操作 | ✅ 可直接提交 | ⚠️ 需要手动操作 | Claude Code | +| 学习成本 | ⚠️ 中等 | ✅ 上手简单 | Cursor | +| 上下文长度 | ✅ 非常长 | ⚠️ 较好 | Claude Code | +| 调试辅助 | ✅ 自动化 | ⚠️ 较多需手动 | Claude Code | + +表格来源: + +简单说,CLI AI 编程工具通常可以: + +- 支持更长时间的连续对话(甚至可以帮你“工作一整天”)。 +- 提供更长的上下文窗口(不再频繁需要你说“继续”)。 +- 响应速度更快(可以接入更多自定义模型 API)。 + +在编码相关操作上,它们通常比大部分 IDE 内置 Agent 更聪明、更稳定。 + +## 常见的 CLI AI 编程工具 + +目前虽然有很多开源实现,但在实践中我们只推荐两大类型的 CLI AI 编程工具,作为“首选组合”。你可以根据自己的习惯任选其一,强烈建议都试一试,再选出最适合你的那一个。 + +- Codex 使用 GPT-5,在整体能力上更强; +- Claude Code 通过 GLM 4.6 转发 API,整体体验接近 Claude 4,但价格更便宜。 +- OpenCode 可以随意切换并搭配模型, 提供免费模型, 可以更好的控制成本。 + +不过,哪一个在实际项目中更好用,只能通过亲自测试来判断。掌握多种 AI 编程工具始终是有益的:熟练以后,你可以在不同场景下灵活切换 Claude Code、Codex 或 Trae。如果尝试多次后发现某个工具效果一般,可以直接换一个工具或模型继续试验。 + +同时,由于模型版本更新非常迅速,建议你优先选择在“性价比(效果 / 成本)”上表现最好的方案。 + +### Claude Code + +Claude Code 是由 Anthropic 基于 Claude 大模型能力开发的一款 AI 编程工具。它的主要交互场景在终端,同时也支持作为 VS Code 插件来使用。类似于 AI IDE 中的 Agent,它可以深度理解开发者的代码仓库,并通过自然语言指令完成端到端的开发任务——包括代码编辑、修复 Bug、执行和修复测试、管理 Git 工作流(例如解决合并冲突、创建 PR)、复杂代码讲解、执行终端命令等。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image6.png) + +Claude Code 的优势主要体现在:极长的上下文窗口(可以处理完整文件甚至小型项目)、可以主动澄清模糊需求、自动规划和分配执行任务,以及对整个代码库内容的深度理解和解释能力。与普通 IDE Agent 相比,它更适合“沉浸式 vibe coding” 的开发流程。 + +在实际使用中,你可以通过对话指令,让它帮你创建新项目、执行 CLI 操作(例如整理文件夹、批量重命名文件、部署开源项目等)、配置开发环境(例如安装和调试 Python 环境)。如果觉得某段代码难以理解、某个目录结构不清晰,也可以直接让 Claude Code 生成结构化的分析文档,或者对特定内容进行分خطوة讲解。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image7.png)![](/zh-cn/stage-2/backend/modern-cli/images/image8.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image9.png)![](/zh-cn/stage-2/backend/modern-cli/images/image10.png) + +如果你想系统地学习 Claude Code,可以参考 Andrew Ng 与 Anthropic 联合推出的课程: + + +接下来,我们将学习如何使用 Claude Code。由于直接使用官方 Claude Code 的成本往往非常高(如下图所示),我们会转而使用兼容 Claude Code 协议、但基于其他大模型的 API 平台。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image11.png) + +你需要学习下面几种不同方案(最好都尝试一遍),最后选择最适合你的那一种作为主要实践路径。 + +第一种方式是直接使用“兼容 Anthropic 接口”的 API。随着 Claude Code 的流行,越来越多的大模型服务商开始支持 Anthropic 风格的调用方式。常见的服务商包括 GLM、Kimi、DeepSeek 和 Siliconflow 等,它们都提供了兼容的 API 接口。关于具体配置,我们会在后文细讲。 + +需要ملاحظة的是,Claude Code 通常会消耗大量 token,如果你担心 API 调用产生过高费用,可以考虑购买 GLM 的月度套餐(大约 20 元/月)来控制成本。如果你想先感受一下实际花费,也可以先充值 10 元做小规模试验。 + +另一种方式是使用 “Claude Code Route” 项目。它是一个开源工具,不仅支持所有常见的 API 调用接口,还允许你针对不同场景精细配置要使用的模型,并且支持对接本地部署的大模型。但由于这一方案的配置相对复杂,建议你先从第一种方案入手。 + +#### 使用智谱 GLM 作为后端(推荐) + +GLM(General Language Model)是智谱 AI 自主研发的一系列大型语言模型。GLM-4.6 是当前 GLM 系列的最新版本,其核心亮点是在代码能力上的优异表现(在公开基准和真实任务中对标 Claude Sonnet 4,在国内处于第一梯队)。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image12.png) + +它还将上下文窗口扩展到 200K,可以更加从容地处理长文本和大体量代码,同时加强了推理与工具调用能力,在性能和成本之间取得了不错的平衡。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image13.png) + +在接入 GLM 之前,我们需要先安装 Claude Code。 + +如果你觉得命令行安装خطوة麻烦,或者中途出现错误,可以直接让 Trae 的 Agent 帮你完成安装。 + +```python +# 安装 Claude Code +npm install -g @anthropic-ai/claude-code + +# 进入你的项目 +cd your-awesome-project + +# 启动 Claude Code +claude + +# 按 Ctrl+C 退出 Claude +``` + +接下来,我们需要修改 Claude Code 的默认 API 请求地址,使其支持 GLM 的 API 服务。你可以直接复制下面的内容,让 Trae 帮你创建对应的环境变量;也可以选择把它们永久写入系统环境变量(如果出现问题,同样可以让 Agent 帮忙修改)。 + +首先,你需要先获取 GLM 的 API Key,并用你自己觉得最方便的方式保存好。 + +国内版地址: +国际版地址: + +如果你使用的是 **国内版 GLM**,请使用以下变量配置: + +```python +# 在 Cmd 中运行以下命令 +# ملاحظة将 `your_zhipu_api_key` 替换为你刚刚获取到的 API Key +setx ANTHROPIC_AUTH_TOKEN your_zhipu_api_key +setx ANTHROPIC_BASE_URL https://open.bigmodel.cn/api/anthropic +``` + +如果你使用的是 **国际版 GLM**,请使用下面的配置: + +```python +# 在 Cmd 中运行以下命令 +# 同样ملاحظة替换掉 `your_zai_api_key` +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic +``` + +你可以直接在 Trae 中输入类似下面的نصيحة词: + +⚠️ 如果你是通过 Trae 帮你配置“永久环境变量”,那么配置完成后 **必须重启 Trae**,否则它内置终端里的环境变量不会更新,可能导致登录失败或网络连接错误。 + +```python +Based on my environment variable settings: +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic + +and my key(Replace it with your own key): +681fea485851d29060cc.13gfaendggaFOhb + +please help me configure and start Claude Code +``` + +你会看到类似下面的过程输出: + +![](/zh-cn/stage-2/backend/modern-cli/images/image14.png) + +> 💡 什么是环境变量? +> +> 环境变量本质上是一组存储在操作系统中的“键值对”配置معلومة,通常以 “变量名 = 具体值” 的形式存在。只要提前在终端或系统设置中配置好,程序就可以随时读取这些变量来获取相关معلومة。由于环境变量可以直接在终端中写入,而无需修改代码本身,我们通常会把访问大模型所需的密钥存放在环境变量里,以避免泄露。程序只需要读取对应环境变量,就能完成大模型调用。 +> +> 在 Windows 系统中,环境变量除了用于存储大模型的访问密钥,还常常用来保存命令行工具的“调用路径”。 +> +> 我们知道终端本身也是一个程序。有时我们希望在终端里启动某个外部程序,例如在终端中输入 `claude` 来启动 Claude Code。之所以可以直接输入 `claude` 就运行,是因为终端会读取系统的环境变量,其中的 PATH 变量里包含了 Claude Code 可执行文件所在的目录,所以终端能够找到并执行它(等价于在终端中粘贴那段程序的绝对路径再按回车)。 +> +> 一个典型的环境变量可能长这样:`PATH=C:\Windows\system32;C:\Program Files\Python`。这样我们就可以在任何路径下执行系统中的这些程序,例如直接在命令行键入 `python` 启动 Python 解释器。 +> +> 如果你想查看系统当前的环境变量,可以在 Windows 搜索中输入“环境变量”,在弹出的“编辑系统环境变量”窗口中就能看到所有变量及其值。有的变量用于存储大模型密钥,有的则用于添加程序目录,方便在任意路径下调用。 + +现在,你就可以使用最新的 GLM 来进行 Claude Code 开发了。你可以尝试重新跑一遍之前的项目,或者重新挑战那些 Trae 没有完成好的任务,对比看看体验上的差异。 + +🎉 反复“推倒重来”并不是浪费时间——你每重做一遍,技能都会更扎实一分。 + +用和 GLM 完全相同的思路,也可以轻松接入其他支持 Anthropic 兼容格式的接口。 + +#### 使用 Kimi K2 作为后端(推荐) + +Kimi K2 是月之暗面(Moonshot AI)推出的新一代大语言模型,在代码理解和生成能力上表现出色。Kimi K2 支持超长上下文窗口(最高可达 200K tokens),能够轻松处理大型代码库和复杂项目。 + +**核心优势:** + +- **超长上下文**:支持 200K 上下文窗口,可以一次性处理整个项目的代码 +- **代码能力强**:在代码生成、重构和调试方面表现优异 +- **中文理解好**:对中文编程需求的理解更加准确 +- **工具调用稳定**:支持稳定的函数调用和工具使用 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +参考文档: + +```bash +export ANTHROPIC_BASE_URL=https://api.moonshot.cn/anthropic +export ANTHROPIC_AUTH_TOKEN=sk-YOURKEY +``` + +#### 使用 Minimax 作为后端(推荐) + +Minimax 是稀宇科技(MiniMax)推出的新一代大语言模型,在编程任务上表现优异。Minimax 模型以其出色的推理能力和代码生成质量而闻名,特别适合复杂的编程场景。 + +**核心优势:** + +- **推理能力强**:在复杂逻辑推理和代码架构设计方面表现出色 +- **代码质量高**:生成的代码结构清晰、可读性好 +- **多语言支持**:支持多种编程语言的代码生成和转换 +- **响应速度快**:API 响应速度快,适合高频调用场景 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_MINIMAX_API_KEY +export ANTHROPIC_MODEL=MiniMax-M2.7 +``` + +#### 使用 DeepSeek 作为后端(推荐) + +DeepSeek 是深度求索推出的开源大语言模型,以其出色的代码能力和高性价比受到开发者欢迎。DeepSeek Coder 专门针对编程任务进行了优化训练。 + +**核心优势:** + +- **代码能力突出**:在代码生成、代码理解和 Bug 修复方面表现优异 +- **开源可定制**:模型开源,可以根据需求进行微调 +- **性价比高**:API 价格相对较低,适合高频使用 +- **中文支持好**:对中文编程场景理解准确 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic +export ANTHROPIC_AUTH_TOKEN=YOU_DEEPSEEK_API_KEY +export API_TIMEOUT_MS=600000 +export ANTHROPIC_MODEL=deepseek-chat +export ANTHROPIC_SMALL_FAST_MODEL=deepseek-chat +export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 +``` + +#### 使用火山引擎 Coding Plan 作为后端(推荐) + +火山引擎(Volcano Engine)是字节跳动旗下的云服务平台,提供企业级的 AI 模型服务。火山引擎的 Coding Plan 专门为编程场景优化,提供稳定、高效的代码生成能力。 + +**核心优势:** + +- **企业级稳定性**:提供服务等级协议(SLA),保障服务稳定性 +- **代码场景优化**:针对编程任务进行了专门优化 +- **丰富模型选择**:支持多种模型,包括 Doubao-pro、Doubao-lite 等 +- **国内访问快**:国内节点部署,访问速度快 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://ark.volces.com/api/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_VOLCANO_API_KEY +export ANTHROPIC_MODEL=doubao-pro-32k +``` + +#### 其他兼容 Anthropic 的 API + +Siliconflow: + +```bash +export ANTHROPIC_BASE_URL="https://api.siliconflow.cn/" +export ANTHROPIC_MODEL="moonshotai/Kimi-K2-Instruct-0905" # 可以自行修改所需模型 +export ANTHROPIC_API_KEY="YOUR_SILICONCLOUD_API_KEY" # 请替换 API Key +``` + +阿里云 DashScope(Aliyuncs): + +```python +export ANTHROPIC_BASE_URL="https://dashscope.aliyuncs.com/apps/anthropic" +export ANTHROPIC_API_KEY="YOUR_DASHSCOPE_API_KEY" +``` + +::: details 使用 Claude Code Route 作为后端(进阶用法) + +上面我们讲解了如何用 GLM 官方 API 替换 Claude Code 的 Anthropic 接口。接下来,我们来看一下 Claude Code Router 这个工具是如何让 Claude Code 适配更多模型 API 的。 + +[Claude Code Router](https://github.com/musistudio/claude-code-router) 是一款专门为 Claude Code 设计的智能路由增强工具。它的核心作用,是帮助用户按需将 AI 请求分发到不同平台上的模型,并可以高度自定义。它支持接入几十个平台,包括 OpenRouter、DeepSeek、Ollama、Gemini 等,也可以按场景将任务路由到特定模型,比如 GLM-4.5、Kimi-K2、Qwen3-Coder 等。举例来说,你可以将后台任务自动交给本地 Ollama,以节省成本;将长文本 / 长代码任务交给 Gemini-2.5-Pro;把代码讲解交给 DeepSeek。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image16.png) + +该工具还提供了方便的 UI/CLI 配置管理能力,并通过"转换器(converter)"适配不同平台的 API 格式。它支持 GitHub Actions 等自动化集成以及自定义扩展,解决了"单一模型无法覆盖所有场景"以及"频繁切换平台很麻烦"的问题,帮助用户更灵活、低成本地利用 AI 工具。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image17.png) + +下面我们简单介绍如何安装 Claude Code Router。大致需要以下خطوة(同样可以让 Trae 帮你执行),以准备好相关环境: + +```markdown +npm install -g @anthropic-ai/claude-code +npm install -g @musistudio/claude-code-router +``` + +安装完成后,你需要确认本地可以使用 `ccr` 命令。如果看到类似下面的输出,说明安装成功: + +![](/zh-cn/stage-2/backend/modern-cli/images/image18.png) + +接下来,有两种方式来初始化和配置模型: + +- 使用 CCR 自带的 UI,在浏览器中打开它提供的配置页面进行操作; +- 直接修改 CCR 的默认配置文件(本质上 UI 也是在修改配置文件,只是提供了更直观的界面)。 + +如果选择使用 CCR UI,你会看到类似下面的界面: + +![](/zh-cn/stage-2/backend/modern-cli/images/image19.png) + +此时点击 "Add Provider" 按钮,就会看到如下界面。你需要: + +1. 在 Name 中输入模型提供商的名字; +2. 在 API Full URL 中填写该提供商的 OpenAI 兼容接口地址; +3. 在 API Key 中填写对应平台的 API Key; +4. 在 Models 区域中填写模型名称,点击 "Add Model" 添加; +5. 最后点击 "Save" 保存配置。 + +(界面往下滚动还有很多高级选项,但目前你可以先忽略它们。) + +![](/zh-cn/stage-2/backend/modern-cli/images/image20.png) + +下面是 DeepSeek 与 Kimi 的配置مثال: + +![](/zh-cn/stage-2/backend/modern-cli/images/image21.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image22.png) + +保存模型配置后,还需要在右侧 Router 区域中指定默认模型(Default)。点击对应的下拉选择,将其设置为 `kimi`(推荐),然后在右上角点击 `Save and Restart`。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image23.png) + +之后,只需在终端中输入 `ccr code`,即可通过 Claude Code Router 启动 Claude Code 的编码工作流。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image24.png) + +::: + +#### Claude Code 的进阶用法 + +很多人最开始使用 Claude Code 时,只把它当成普通对话工具来用。但实际上,它内置了很多丰富的能力,能够让你使用起来更高效、灵活。下面是一些常见命令和用法مثال: + +参考文档: + + + + +| 命令 | 作用 | مثال | +| ----------------- | ----------------------------------------- | ---------------------------------------- | +| claude | 启动交互模式 | `claude` | +| claude "query" | 执行一次性任务并输出النتيجة | `claude "explain this project"` | +| claude -p "query" | 执行一次性问题并在结束后自动退出 | `claude -p "explain this function xxxx"` | +| claude -c | 继续最近的一次会话 | `claude -c` | +| claude -r | 恢复上一段会话 | `claude -r` | +| /resume | 在当前聊天中切换回上一段会话 | `claude -c`、`/resume` | +| /plugin | 管理插件,可安装提交与审查类扩展能力 | `/plugin` | +| /init | 用 CLAUDE.md 初始化项目说明 | `/init` | +| /clear | 清空当前会话上下文,防止معلومة过载 | `/clear` | +| /compact | 压缩会话历史,减少上下文 token 占用 | `/compact` | +| /cost | 查看当前消费情况 | `/cost` | +| /model | 切换使用的模型(用兼容 API 时一般可忽略) | `/model` | +| /memory | 管理 CLAUDE.md 记忆文件 | | +| /help | 显示可用命令列表 | `/help` | +| exit or Ctrl+C | 退出 Claude Code | `exit` 或 `Ctrl+C` | +| /agents | 高级功能,后文会说明 | | +| /mcp | 高级功能,后文会说明 | | + +**CLAUDE.md** + +参考: + +`CLAUDE.md` 是 Claude 在开始对话时会自动读取并加入上下文的特殊文件。因此,它非常适合用来记录: + +- 常用 bash 命令 +- 核心文件和工具函数 +- 代码风格约定 +- 测试方式说明 +- 仓库协作规范(例如分支命名、是用 merge 还是 rebase 等) +- 开发环境配置说明(例如是否使用 pyenv、推荐哪种编译器等) +- 项目中需要特别ملاحظة的行为或坑点 +- 任何你希望 Claude “记住”的معلومة + +`CLAUDE.md` 本身没有强制格式要求,只要简洁、便于人类阅读即可。例如: + +``` +# Bash commands +- npm run build: Build the project +- npm run typecheck: Run the typechecker + +# Code style +- Use ES modules (import/export) syntax, not CommonJS (require) +- Destructure imports when possible (eg. import { foo } from 'bar') + +# Workflow +- Be sure to typecheck when you’re done making a series of code changes +- Prefer running single tests, and not the whole test suite, for performance +``` + +#### Claude Code 的内部原理 + +参考: + +如果你好奇为什么 Claude Code 在很多场景下比 Trae 或 Cursor 等 Agent 编程工具更好用,我们可以简单看一下它的内部工作机制。 + +其他 CLI AI 编程工具的整体实现方式也大体类似。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image25.png) + +Claude Code 会把编程任务拆解成一个持续的“感知—思考—行动—验证”循环,并在其中调用不同工具完成任务。它模仿人类开发者的工作流:不断“写代码 → 运行 → 看النتيجة → 再改进”。系统内部通过一个主任务循环不断执行خطوة,在每一轮循环中,Claude 都可以调用不同工具——例如读写文件、执行命令、搜索代码等——再根据工具返回的真实النتيجة决定الخطوة التالية行动。 + +其中有几个关键特性值得ملاحظة: + +- **流式处理(Stream Processing)**:Claude 可以一边思考一边输出النتيجة,而不是必须等所有代码写完再执行。 +- **智能压缩(Intelligent Compression)**:长对话容易导致上下文过长,Claude 通过将历史压缩成关键معلومة来减少“遗忘”的概率,并通过区分长短期记忆保证高效运行。 +- **并发控制(Concurrency Control)**:内部并行设计可以让多个任务同时进行,互不干扰。 +- **子 Agent 管理(Sub-agent Management)**:实际工作中并不只相当于一个“角色”处理所有事情,你可以管理多个子 Agent 协作处理代码,每个 Agent 负责不同任务,比如专门负责测试、专门负责写文档等。 + +### Codex + +![](/zh-cn/stage-2/backend/modern-cli/images/image26.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image27.png) + +和 Claude Code 类似,Codex 是由 OpenAI 开发的一款 AI 协作编程工具,你可以把它理解成 “OpenAI 版的 Claude Code”。它最大的优势是对 GPT-5 的高效适配。 + +从实际体验来看,GPT-5 目前响应速度更快、犯错率更低(在多轮复杂任务中正确完成的概率更高)。它的一个缺点是解释往往偏“学术”和“技术”,有时显得过于严谨、معلومة量很大,对初学者来说可能略微难懂。 + +你可以通过下面的命令安装 Codex: + +``` +npm i -g @openai/codex +``` + +#### 使用 OpenAI 官方 API 作为后端 + +如果直接使用 OpenAI 官方的 Codex 入口,配置会非常简单:当你已经开通 OpenAI 订阅或申请到了相应 API 配额之后,只需要在命令行中输入 `codex` 启动程序,并按نصيحة完成登录即可。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image28.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image29.png) + +#### 使用转发 OpenAI API 的方式作为后端 + +由于官方 OPENAI API 可能存在价格较高、网络要求严格等问题,为了避免这些限制,我们也可以通过其他 API 网关服务来转发调用。 + +在这种方式下,我们只需要在第三方转发平台上购买对应的 Codex API 配额,就能获得接近原生 OpenAI Codex 的使用体验。 + +参考: +充值地址: + +需要ملاحظة的是,在拿到 token 配额后,我们还需要在本地配置好 API Key。 + +在密钥分组设置中,要ملاحظة选择专门用于 Codex 的那一项。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image30.png) + +接下来,我们需要把获取到的 Key 填入下面的نصيحة词中,并把整段نصيحة词交给 Trae,让它帮你完成整个配置过程: + +````bash +My API key is: [Paste your obtained sk-xxxxx key here] + +Please help me complete the following configuration tasks: + +1. Create configuration directory + - Create a `.codex` folder under my user directory + - Windows path should be: `C:\Users\[My Username]\.codex` +2. Backup existing configuration (if exists) + - Check if `.codex\config.toml` exists + - If it exists, rename it to `config.toml.bak.[current timestamp]` (timestamp format: yyyyMMddHHmmss) +3. Create configuration file + - Create `config.toml` in the `.codex` directory + - Write the following complete content: + ```toml + preferred_auth_method = "apikey" + + [model_providers.myrelay] + name = "My Relay Station" + base_url = "https://api.zyai.online/v1" + env_key = "MYRELAY_API_KEY" + wire_api = "responses" + request_max_retries = 4 + stream_max_retries = 10 + stream_idle_timeout_ms = 300000 + + [profiles.myrelay] + model_provider = "myrelay" + model = "gpt-5" + model_reasoning_effort = "medium" + + [tools] + web_search = true + +4. Set system environment variable +Variable name: MYRELAY_API_KEY +Variable value: The key I gave you + +5. Confirm completion and report back: + +The full path of the configuration file +Whether the environment variable was set successfully +I can use the command `codex --profile myrelay` to run it +```` + +配置完成后,你就可以通过 `codex --profile myrelay` 启动使用转发 API 的 Codex 了。之后的使用方式与 Claude Code 类似:只需要在对话框中随时输入你的想法和需求即可。 + +### OpenCode + +![](/zh-cn/stage-2/backend/modern-cli/images/image32.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image33.png) + +OpenCode 是一款面向开发者的开源 AI Coding Agent 平台,定位类似于 “多模型版的 Claude Code”。它以 Terminal 为核心交互入口,同时也支持编辑器集成(如 VS Code、Neovim 等),能够深度接入本地代码仓库,并通过自然语言完成从代码理解到工程执行的一整套开发流程。 + +它不是绑定单一模型的 AI 编程工具,而是一个可自由切换 GPT、Claude、Gemini 乃至本地模型的开放式 AI Coding Agent 平台。就连 OpenAI 官方也持 OpenCode 接入 Codex / OpenAI 订阅。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image34.png) + +你可以通过下面的命令安装 OpenCode: + +```bash +# Linux / Unix +curl -fsSL https://opencode.ai/install | bash + +# Windows +npm i -g opencode-ai +``` + +#### 使用 OpenCode 中的免费模型 + +在 OpenCode 中不定期会提供免费模型可以进行使用, 配置也非常简单。你可以在你需要使用 OpenCode 的位置在命令行输入 `opencode` 启动 Opencode 程序进入聊天面板。输入 `/models`命令搜索 free 关键词就可以看到带有 free 字眼的免费模型 + +![](/zh-cn/stage-2/backend/modern-cli/images/image35.png) + +在一般情况下免费模型完成编码任务会比付费 / 订阅模型要慢一些,这通常取决于模型线路是否阻塞, 是否编码高峰期以及模型本身的能力。 + +#### 使用第三方模型来作为 OpenCode 的主编码模型 + +这是 OpenCode 的核心优势, 它可以在使用同样的 MCP, Skills, 上下文的情况下允许你自由切换模型来完成不同的编码任务。下文以 OpenAI 官方的 GPT-5.3 Codex 为例,接入 OpenCode 作为主编码模型。 + +在 OpenCode 的聊天窗口中输入 `/connect` 命令选中第一条最相关指令按下 enter 键,就可以进行选择第三方模型提供商的认证授权。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image36.png) + +这里以选择 OpenAI 为例,进行回车选择认证方式。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image37.png) + +选哪种都可以,只是认证方式不同。这里选择第一种进行浏览器登录。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image38.png) + +复制此链接到浏览器上进行正常的 OpenAI 登录操作,浏览器上出现 Authorization Successful 后 OpenCode 客户端会自动跳转至选择 OpenAI 的模型界面。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image39.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image40.png) + +#### 安装 Oh My OpenAgent 插件 + +OpenCode 的强大之处还在于他有非常活跃的社区生态,你可以在 Github 上搜索出非常多与 OpenCode 相关的插件。如果说 OpenCode 是一款可以任意切换模型的 AI 协作工具的话,那么 Oh-My-OpenAgent 就是一款运行在 OpenCode 之上的 "多 Agent AI 编程指挥系统"。它可以将一个复杂任务拆给多个子任务分给不同的模型进行各司其职的工作。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image41.png) + +你可以将以下话术复制之后粘贴给上文在 OpenCode 中配置好的模型进行安装 OpenCode。 + +```text +Install and configure oh-my-openagent by following the instructions here: +https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md +``` + +以下是 Oh-My-OpenAgent 的特性以及功能说明。 + +| 特性 | 功能说明 | +| :-------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **自律军团 (Discipline Agents)** | Sisyphus 负责调度 Hephaestus、Oracle、Librarian 和 Explore。一支完整的 AI 开发团队并行工作。 | +| **Team Mode** (v4.0, 选择性启用) | 领导 Agent + 最多 8 个并行成员,实时 tmux 可视化,专用 `team_*` 工具家族。驱动 `hyperplan`(5 个敌对评论者) 和 `security-research`(3 个猎手 + 2 个 PoC 工程师)。[文档 →](docs/guide/team-mode.md) | +| **`ultrawork` / `ulw`** | 一键触发,所有智能体出动。任务完成前绝不罢休。 | +| **[IntentGate 意图门](https://factory.ai/news/terminal-bench)** | 真正行动前,先分析用户的真实意图。彻底告别被字面意思误导的 AI 废话。 | +| **基于哈希的编辑工具** | 每次修改都通过 `LINE#ID` 内容哈希验证、0% 错误修改。灵感来自 [oh-my-pi](https://github.com/can1357/oh-my-pi)。[The Harness Problem →](https://blog.can.ac/2026/02/12/the-harness-problem/) | +| **LSP + AST-Grep** | 工作区级别的重命名、构建前诊断、基于 AST 的重写。为 Agent 提供 IDE 级别的精度。 | +| **后台智能体** | 同时发射 5+ 个专家并行工作。保持上下文干净,随时获取成果。 | +| **内置 MCP** | Exa(网络搜索)、Context7(官方文档)、Grep.app(GitHub 源码搜索)。默认开启。 | +| **Ralph Loop / `/ulw-loop`** | 自我引用闭环。达不到 100% 完成度绝不停止。 | +| **Todo 强制执行** | Agent 想要摸鱼?系统直接揪着领子拽回来。你的任务,必须完成。 | +| **注释审查员** | 剔除带有浓烈 AI 味的冗余注释。写出的代码就像老练的高级工程师写的。 | +| **Tmux 集成** | 完整的交互式终端支持。跑 REPL、用调试器、用 TUI 工具,全都在实时会话中完成。 | +| **Claude Code 兼容** | 你现有的 Hooks、命令、技能、MCP 和插件?全都能无缝迁移过来。 | +| **技能内嵌 MCP** | 技能自带其所需的 MCP 服务器。按需开启,不会撑爆你的上下文窗口。 | +| **Prometheus 规划师** | 动手写代码前,先通过访谈模式做好战略规划。 | +| **`/init-deep`** | 在整个项目目录层级中自动生成 `AGENTS.md`。不仅省 Token,还能大幅提升 Agent 理解力。 | + +Sisyphus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) 是你的主指挥官。他负责制定计划、分配任务给专家团队,并以极其激进的并行策略推动任务直至完成。他从不半途而废。 + +Hephaestus (gpt-5.5) 是你的自主深度工作者。你只需要给他目标,不要给他具体做法。他会自动探索代码库模式,从头到尾独立执行任务,绝不会中途要你当保姆。名副其实的正牌工匠。 + +Prometheus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) 是你的战略规划师。他通过访谈模式,在动一行代码之前,先通过提问确定范围并构建详尽的执行计划。 + +了解完这些, 你就可以使用装好 Oh-My-OpenAgent 插件之后的 OpenCode 来完成编码任务了。 + +## CLI AI 编程工具的更多用法 + +### 用 AI 写需求文档:学会“具体化需求” + +对于大语言模型来说,抽象需求需要被“具体化”。比如:“我很饿”是一个抽象需求,我们需要把它变成:“我肚子有点饿,可能需要吃一个红豆面包,再配一杯豆浆。”——这才是一种可以被执行的、具体的需求。 + +但把抽象需求变具体,其实是一个很花精力的过程。如果我们没有见过足够多的案例,很难快速联想到该如何把抽象问题拆解成细致的模块。这种时候,最好的办法就是让 AI 帮你完成“具体化”这一步。 +比如,我想开发一个“每日计划”应用,最朴素的想法可能是: + +`Please help me write a daily planning app where I can write my plans each day and get reminders.` + +AI 确实可以在这个需求基础上直接拆分任务,然后一步步完成,但中间容易出错或理解偏差。为了降低风险,我们可以让 AI 帮我们先扩写需求: + +`Based on my needs, please elaborate and provide a more detailed Product Requirement Document for reference. My idea is: Please help me write a daily planner app that supports daily plan-writing and provides reminders .` + +这时,AI 可能会给出类似下面这样完整的 PRD: + +``` +Product Requirements Document (PRD): “Today’s Plan” App +Document Version: 1.0 +Creation Date: October 27, 2023 +Author: (Your Name/Product Manager) + +1. Product Introduction +1.1 Product Name +Today's Plan +1.2 Product Vision +“Today’s Plan” is a minimalist and highly efficient daily planning and reminder tool, dedicated to helping users eliminate procrastination and forgetfulness, plan every day clearly, and ensure tasks are carried out through an intelligent reminder system—ultimately enabling users to gain a stronger sense of control and achievement over their time. +1.3 Target Users (User Personas) +We mainly serve three types of users: +Students (Xiao Ming): +Characteristics: Multiple tasks such as courses, assignments, club activities, exam prep, needing organized time arrangement. +Pain Points: Easily forget small tasks or assignment deadlines; feel overwhelmed switching between tasks; want to build regular study and life habits. +Needs: A simple tool to list daily to-dos and provide reminders before class/self-study. +Office Workers (Zhang Wei): +Characteristics: Fast-paced work, many meetings, reports, project milestones, and personal affairs (fitness, picking up children). +Pain Points: Easily forget important meetings or work milestones; get interrupted by urgent tasks and forget the original plan; feel busy but inefficient at end of day. +Needs: Need a tool to quickly record and schedule daily work and send strong reminders at key times (e.g., 15 minutes before meetings). +Freelancers/Self-disciplined Seekers (Li Na): +Characteristics: High freedom of time, but strong self-management required for work output and personal growth. +Pain Points: Easily procrastinate, lack external supervision; start the day without a clear plan, leading to low time utilization. +Needs: Need a tool to help build a daily fixed routine (Morning Routine) and review daily achievements for positive feedback. + +2. User Stories +As a user, I want to quickly create today’s plan list so I have an overview of all my tasks for the day. +As a user, I want to set specific start and end times for each task so I can create a visual timeline. +As a user, I want to receive push notification reminders before a task starts so I won’t miss any important arrangements. +As a user, I want to customize the reminder time (such as 5, 15, or 60 minutes in advance) so reminders better fit my habits. +As a user, I want to easily mark completed tasks so I can feel accomplished and clearly see my progress. +As a user, I want to see a summary of my completed plans at the end of each day for reviewing and self-motivation. +As a user, I want to conveniently edit and delete tasks to handle last-minute changes. +As a user, I want to view plans and achievements from previous days to review my efficiency and habits. + +3. Feature Breakdown +Core Features (MVP - Minimum Viable Product) +Module 1: Plan Management +3.1.1 Daily Plan Homepage +Interface: “Today” as the core view, current date shown at the top. +View: Timeline list, clearly showing tasks scheduled from morning to evening. Tasks without a time can be listed in the top or bottom “To-do List” section. +Interactions: +Click the “+” button in the bottom right to quickly create a new task. +Pull down to refresh the page. +Swipe left/right to view yesterday’s and tomorrow’s plans. +3.1.2 Create/Edit Task +Entry: Click “+” on the homepage or a time slot in the list. +Fields: +Task title (required): Briefly describe the task, e.g., “10 AM Weekly Product Meeting.” +Task time (optional): +Set “start time” and “end time.” +Provide “all-day” option for unspecified time tasks. +Default time picker should be quick and convenient. +Reminder setting (required, with default value): See Module 2. +Notes (optional): Add further descriptions, links, or location info. +Actions: Save, cancel, delete task. +3.1.3 Task Interaction +Mark as complete: Checkbox before each task; checking adds a strikethrough and gray background, indicating completion. Can unmark if needed. +Edit task: Click the task itself to enter edit page. +Delete task: Swipe left on a task to reveal “Delete” button. +Module 2: Smart Reminder System +3.2.1 Reminder Trigger +Mechanism: Based on task’s set “start time” and the user’s “reminder lead time,” send a push notification from device. +Offline Support: Locally scheduled reminders must trigger even if user is offline. +3.2.2 Reminder Content & Format +Notification title: App name “Today’s Plan.” +Body: “Reminder: [Task Title] will start at [Start Time].” E.g., “Reminder: Product Meeting will start at 10:00.” +Sound: Use system default or offer several simple, effective tones. +3.2.3 Reminder Settings +Global Settings (in Settings page): +User can set a default reminder time, e.g., “15 minutes before task starts.” New tasks adopt this by default. +Single Task Settings (in create/edit page): +Users can override global settings for important tasks, choosing specific reminder times like "on time," "5 minutes early," "30 minutes early," or "1 hour early." +Provide “no reminder” option. +Subsequent Features (V1.1, V2.0) +3.3 Daily Review & Statistics +Push a summary notification at a set time every night (e.g., 22:00): “How was your day? Take a look at your achievements!” +Generate a simple daily report card: shows total planned tasks, completed tasks, completion rate, plus an encouraging message. +3.4 History Review +Calendar view to click on any past day and check its plans and completion status. Days with high completion rates marked with a special color. +3.5 Templates +Allow users to save a successful daily plan as a template, e.g., “Efficient Workday,” “Relaxing Weekend.” +When creating tomorrow’s plan, one-click import a template, modify slightly to save time. +3.6 Themes & Personalization +Offer dark mode. +Allow changing several primary color themes. + +4. Non-Functional Requirements +4.1 Performance +Response: App launch time under 2 seconds; adding/editing tasks must be smooth and lag-free. +Resource Use: Low battery and memory consumption in background; do not over-consume resources waiting for reminders. +4.2 Usability +Minimal & intuitive: UI must be minimal, primary functions accessible within 3 clicks. No tutorial needed for new users. +Error tolerance: Offer undo (e.g. brief undo after mistakenly deleting a task). +4.3 Reliability +Reliable reminders: Reminder function is the product’s lifeline; must guarantee 99.99% timely and accurate delivery. +Data loss-free: User plans must be reliably stored locally. Future versions can support cloud sync to prevent data loss on device change. +4.4 Compatibility +Platform: Support major iOS and Android versions (latest 3-4 releases). +Screen: Layout must fit various phone screen sizes. + +5. Roadmap +V1.0 (MVP): +Goal: Validate core value—planning & reminders. +Features: Complete all “Core Features” described above (Plan management, smart reminders). +V1.1 (Quick Optimization): +Goal: Improve retention and achievement. +Features: Add “Daily Review & Statistics,” “History Review.” +V2.0 (Enhanced Experience): +Goal: Increase efficiency and personalization. +Features: Add “Templates,” “Themes & Personalization,” and start developing “Cloud Sync.” +``` + +对比我们最开始那句“帮我写一个每天可以记计划并提醒的应用”,现在这份文档已经详细得多了。你可以根据自己的真实需求,对其中的内容进行增删修改;对于某些你不确定的模块,也可以继续让 AI 提供更多备选方案,你再挑选、合并成最终版本。 + +通过这种方式,我们可以很轻松地把抽象想法变成具体描述。对 AI 开发来说,“具体”就是生产力:需求越具体,越容易得到结构稳定、质量较高的项目。你可以尝试用这种方式重做一下之前的某个小项目,对比一下效果差异。 + +如果你觉得这类“需求نصيحة词”太长,非常自然的做法,是把它单独写进一个 markdown 文档中,作为你的“需求文档 / 开发文档 / PRD”。之后每次让 AI 写项目时,只需要让它“参考这份文档”,而不是每次都重打一遍长نصيحة。你也可以在迭代中不断完善这份文档,让后续项目直接受益。 + +下面是一些其他常见的使用场景: + +### 管理文件夹 + +我们可以尝试用 CLI AI 编程工具来管理当前文件夹中的各种文件。比如,你有一堆杂乱无章的文件,需要整理归类,就可以对 Claude Code 或 Codex 说: + +`Please help me organize the contents of the current folder. I want to group files with the same content together & I want to group files from the same time period together. Please help me handle this.` + +### 开发新项目 + +这和我们之前在 z.ai、Trae 中的用法几乎完全一样——我们也可以直接用 CLI AI 编程工具来从零开发新项目。当然,最好提前准备好一份需求文档。 + +需求文档越细致,最终效果越好。你可以根据不断变化的想法,对文档做多轮优化;文档越完善,代码实现就越稳定、越成熟。 + +### 部署开源项目(例如 Dify) + +对于刚接触计算机的同学来说,从 GitHub 上部署一个开源项目往往很有难度。但我们完全可以把这件事交给 Claude Code,就像我们在 Dify 教程中做的那样: + + + +如果我想在本地跑起自己的 Dify,只需要把这个链接扔给 Claude Code,然后输入: + +`I want to deploy this GitHub project ``https://github.com/langgenius/dify`` . Please help me clone the project and run it.` + +收到你的请求后,Claude Code 会自动完成一系列操作,包括从 GitHub 拉取代码、配置运行环境、启动项目等。如果中间某一步出错或项目启动状态不正常,你再根据نصيحة进行少量人工处理即可。除了 Dify,你也可以用 Claude Code 帮你部署大部分常见的 GitHub 开源项目——你只需要一个对话框,再加上喝一杯咖啡的时间 ☕️。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image31.png) + +### 讲解代码与撰写文档 + +对于一些复杂项目,或者 AI 自动生成的大型项目,你可能会觉得代码太长、逻辑太多,很难看懂。这时就可以让 CLI AI 编程工具帮你“读代码”。你可以这样提问: + +- 请帮我解释这个项目:如何运行、如何使用、后续如何修改和继续开发? +- 请帮我说明这个项目的整体流程:程序是怎样运行的?用户在界面中可以做哪些操作? +- 请帮我为这个项目写一份完整的文档,包括开发文档和运行文档等。 +- 请基于我当前文件夹里的所有内容,写一份详细说明,并保存到指定的 markdown 文档中。 + +### 更多玩法 + +当然,CLI AI 编程工具能做的远不止上面这些。不要只把它当作“写代码工具”,而是把它看作一个具有独立行动能力的智能 Agent。你可以让它帮你: + +- 管理和整理本地文件; +- 写日记、写الخلاصة; +- 分析和修复系统错误; +- 执行各种重复性命令行任务等。 + +也许在不久的将来,它会变成你电脑上最مهم、也最懂你的 AI 伙伴。 diff --git a/docs/ar-sa/stage-2/backend/stripe-payment/index.md b/docs/ar-sa/stage-2/backend/stripe-payment/index.md new file mode 100644 index 0000000..8f8e47c --- /dev/null +++ b/docs/ar-sa/stage-2/backend/stripe-payment/index.md @@ -0,0 +1,907 @@ +# كيفية دمج أنظمة الدفع مثل Stripe + +当你的产品已经有了页面、登录、数据库和基础后端之后,下一个现实问题就是:**怎么收费**。 + +很多人第一次接支付,会把ملاحظة力全放在"怎么跳转到付款页"上。但真正决定系统是否稳定的,不是按钮,而是整条收费链路:谁决定价格、谁确认支付成功、谁更新数据库、谁回收权限。 + +这篇文章我帮你拆成两部分: + +- **前半部分**只讲最实用的基础接入,目标是让你尽快把 Stripe 接进项目。 +- **后半部分**统一放到الملحق,包含 Webhook 细节、订阅事件、不同国家和地区的支付方案差异。 + +> 💡 建议先学完这些章节再继续 +> +> - [从数据库到 Supabase](../database-supabase/) +> - [大模型辅助编写接口代码与接口文档](../ai-interface-code/) +> - [如何部署 Web 应用](../zeabur-deployment/) + +# ما ستتعلمه + +1. 最小可行的支付系统到底长什么样。 +2. 如何用最快的方式把 Stripe 接进你的项目。 +3. 如何写نصيحة词,让 AI 直接帮你加支付系统。 +4. 如果不是做海外 Stripe 项目,不同地区应该优先考虑什么支付方案。 + +--- + +# 第一部分:基础上手 + +## 1. 先记住 3 个原则 + +如果你只记住三件事,就记住下面这三条: + +1. **价格必须由后端决定**,不能相信前端传来的金额。 +2. **真正让权限生效的是 Webhook**,不是 `success` 页面。 +3. **你自己的数据库必须保存支付状态**,不能只依赖 Stripe 后台。 + +这三条是支付系统最核心的边界。只要边界没错,后面换 Stripe、PayPal、支付宝、微信支付,本质上都只是"接口换了,架构不变"。 + +## 2. 如果不在后端处理,而是前端直接连 Stripe,会怎么样? + +这是很多人第一次做支付时最自然的想法: + +- 页面上已经有"购买"按钮了 +- 那我能不能让前端自己去连 Stripe +- 这样是不是就不用做后端了 + +如果你只是做一个假的演示页面,这样想当然没问题。 +但如果你是真的要收钱,**这条路通常会把事情做坏**。 + +最常见的问题有这几个: + +1. **价格容易被改** + 浏览器里的请求,是用户自己电脑上发出去的。别人是可以改请求内容的。 +2. **敏感معلومة容易暴露** + 真正مهم的密钥、价格逻辑、会员开通逻辑,本来就不该放在前端。 +3. **你没法可靠确认"这笔钱到底算不算成功"** + 用户跳到成功页,不代表你的数据库已经同步对了。 +4. **数据库状态会乱** + 用户可能说"我明明已经付钱了",但你自己的系统里根本没记上。 + +所以更安全的分工应该是: + +- 前端负责:展示按钮、发起购买、跳转页面 +- 后端负责:决定价格、创建支付会话、接收 Webhook、更新数据库 + +::: info 这一段你可以直接记成一句话 +**前端可以负责跳转,后端必须负责定价和确认。** + +只要是真收钱,就不要把"最终价格决定权"和"支付成功后的开通逻辑"放在前端。 +::: + +## 3. 什么时候适合先用 Stripe + +如果你做的是下面这些场景,Stripe 往往是最顺手的起点: + +- 面向海外用户的 SaaS +- 订阅制会员产品 +- 数字产品、模板、AI 积分包 +- 想先快速验证商业化,而不是一开始就处理太多本地支付细节 + +如果你的主要用户在中国大陆,那通常不会把 Stripe 当第一选择,这个我放到الملحق里统一讲。 + +## 4. 最小可行支付链路 + +先看最小版本。只要这条链路能跑通,你的支付系统就有了骨架。 + +```mermaid +flowchart LR + user["用户"] + frontend["前端页面"] + backend["你的后端"] + checkout["Stripe Checkout"] + webhook["Stripe Webhook"] + db["Supabase / 业务数据库"] + + user -->|"点击购买"| frontend + frontend -->|"请求创建支付会话"| backend + backend -->|"按后端价格创建 Session"| checkout + frontend -->|"跳转到支付页"| checkout + checkout -->|"支付完成后发送事件"| webhook + webhook -->|"校验签名并更新状态"| backend + backend -->|"写入 orders / subscriptions"| db + db -->|"前端刷新后读取最新状态"| frontend +``` + +把它翻译成人话就是: + +1. 用户点按钮。 +2. 前端找后端要支付链接。 +3. 后端用 Stripe 密钥创建支付会话。 +4. 用户去 Stripe 页面付款。 +5. Stripe 把"付款真的成功了"这件事通过 Webhook 通知你。 +6. 你的后端再去更新数据库。 + +## 5. 发起付款的标准时序图 + +如果你习惯看更规范的系统图,可以直接看这张时序图: + +```mermaid +sequenceDiagram + autonumber + actor User as 用户 + participant Frontend as 前端页面 + participant Backend as 后端 API + participant Stripe as Stripe Checkout + + User->>Frontend: 点击"升级"或"购买" + Frontend->>Backend: POST /api/billing/create-checkout-session + Note right of Frontend: 前端传 plan / userId / email\n不传最终收费金额 + Backend->>Backend: 校验套餐并映射 priceId + Backend->>Stripe: 创建 Checkout Session + Stripe-->>Backend: 返回 session.url + Backend-->>Frontend: 返回支付链接 + Frontend-->>User: 跳转到 Stripe 支付页 + User->>Stripe: 完成付款 +``` + +## 6. 快速开始 + +如果你想最快把它接进项目,照着下面这 5 步做就够了。 + +### 6.1 الخطوة الأولى:在 Stripe 后台创建商品和价格 + +这一步的目的,不是"先随便配点东西",而是先把 **你到底在卖什么、打算怎么收费** 这件事在 Stripe 里定义清楚。 + +在 Stripe 的模型里: + +- **Product** 表示"你卖的是什么",比如 `Pro 会员` +- **Price** 表示"这个东西卖多少钱、按什么周期卖",比如 `月付 9.9 美元`、`年付 99 美元` + +为什么要先做这一步? +因为后面当你的后端创建 Checkout Session 时,并不是直接传一个金额给 Stripe,而是要传一个已经存在的 `price_id`。Stripe 再根据这个 `price_id` 去生成真正的支付页、金额、币种和订阅周期。 + +如果你跳过这一步,后面的"创建支付链接"其实就没法做。 + +::: info 为什么这里要先停一下 +很多新手看到 `Product`、`Price` 这两个词会有点烦,觉得像是在学 Stripe 的内部术语。 + +但实际上,这一步是在做一件很朴素的事: +- 把"卖什么"定义清楚 +- 把"卖多少钱"定义清楚 +- 让后端之后能拿一个稳定的 `price_id` 去创建支付链接 + +只要把这层想明白,后面的 Checkout Session 就不会觉得抽象。 +::: + +对于一个最小可行的订阅系统,你至少先建这两个层级: + +- 一个 `Product` +- 一个或多个 `Price` + +你可以直接打开这些页面: + +- Stripe Dashboard 登录页:[Dashboard Login](https://dashboard.stripe.com/login) +- Stripe 商品与价格管理文档:[Manage products and prices](https://docs.stripe.com/products-prices/manage-prices) +- Stripe Checkout 快速开始文档:[Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- Stripe Dashboard 商品页:[Product catalog](https://dashboard.stripe.com/test/products) + +推荐你先在 **Test mode(测试模式)** 下操作,不要一开始就在正式环境里建。 + +一个最常见的最小配置是: + +- `Product`: `Pro Plan` +- `Price 1`: `pro_monthly` +- `Price 2`: `pro_yearly` + +你在后台操作时,可以按这个顺序理解: + +1. 先创建一个商品 `Pro Plan` +2. 再在这个商品下面挂两个价格 +3. 月付和年付其实是同一个商品的两种收费方式 + +完成后,你至少要记下这些معلومة: + +- 月付价格的 `price_id` +- 年付价格的 `price_id` +- 你自己的套餐名,例如 `pro_monthly`、`pro_yearly` + +如果你是第一次进 Stripe 后台,建议你把这一步理解成: + +- `Product` 决定支付页里卖的是什么 +- `Price` 决定支付页里收多少钱 +- 后端之后真正会用到的,主要是 `price_id` + +::: info 真正要记下来的值 +这一页里最مهم的不是商品名称,而是 `price_id`。 + +后面无论是让 AI 帮你接后端,还是你自己排查问题,真正会频繁用到的,通常都是: +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- 它们背后对应的两个 `price_id` +::: + +如果你想让 AI 先带你把后台配置做完,可以直接用这个 prompt: + +```text +我现在是第一次用 Stripe,你先不要改代码,先带我在 Stripe 后台把最基本的付费配置做好。 + +请基于这些官方文档给我一步一步的操作说明: +- https://docs.stripe.com/products-prices/manage-prices +- https://docs.stripe.com/checkout/quickstart?lang=node + +我的情况是: +- 我想做一个最简单的会员付费 +- 只有两个套餐:月付和年付 +- 我现在还不懂 Product、Price 这些词 + +请你: +1. 先用最简单的话告诉我 Product 和 Price 分别是什么。 +2. 再按"先打开哪个页面 -> 点哪里 -> 填什么"的顺序教我操作。 +3. 最后提醒我,做完以后我需要从后台复制哪些内容给后端使用。 +4. 如果我容易走错,请顺便提醒我应该一直在测试模式里操作。 +``` + +### 6.2 الخطوة الثانية:准备环境变量 + +你通常至少需要准备这些环境变量: + +- `STRIPE_SECRET_KEY` +- `STRIPE_WEBHOOK_SECRET` +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- `APP_URL` +- `SUPABASE_URL` +- `SUPABASE_SERVICE_ROLE_KEY` + +你可以直接打开这些页面: + +- Stripe API Keys 文档:[API keys](https://docs.stripe.com/keys) +- Stripe Dashboard API Keys 页面:[API Keys](https://dashboard.stripe.com/test/apikeys) +- Stripe Webhooks 文档:[Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Stripe Dashboard Webhooks 页面:[Workbench Webhooks](https://dashboard.stripe.com/test/workbench/webhooks) + +> ⚠️ `STRIPE_SECRET_KEY` 和 `SUPABASE_SERVICE_ROLE_KEY` 都只能放在后端。 + +::: info 环境变量这一步的目的 +这一步不是为了"先把 `.env` 填满",而是为了把支付系统里最敏感的几样东西放到后端保管: + +- Stripe 的后端密钥 +- Webhook 验签密钥 +- 你自己的价格映射 + +简单理解: +前端只负责发起购买,真正的秘密和定价逻辑都应该留在服务端。 +::: + +这一步也可以直接让 AI 帮你整理: + +```text +请你先看看我这个项目现在是怎么放环境变量的,然后帮我把 Stripe 需要的环境变量整理出来。 + +请参考这些文档: +- https://docs.stripe.com/keys +- https://docs.stripe.com/webhooks + +我的情况是: +- 我是零基础 +- 我分不清哪些变量应该放前端,哪些应该放后端 +- 我也不确定当前项目应该改 `.env`、`.env.local` 还是别的文件 + +请你: +1. 先搜索当前项目里环境变量通常写在哪。 +2. 帮我列出 Stripe 接入最少需要哪些变量。 +3. 用最简单的话告诉我每个变量是干什么的。 +4. 告诉我每个变量应该去哪一个 Stripe 页面复制。 +5. 如果项目里有مثال环境变量文件,请直接帮我补上变量名。 +``` + +### 6.3 الخطوة الثالثة:后端创建 Checkout Session + +这一步你不用自己写接口,直接让 AI 参考官方文档帮你实现。 + +先把这些文档给它: + +- Stripe Checkout 快速开始:[Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- Checkout Sessions API:[Create a Checkout Session](https://docs.stripe.com/api/checkout/sessions/create) +- 订阅说明:[Subscriptions](https://docs.stripe.com/payments/subscriptions) + +然后直接贴这个 prompt: + +```text +请你先看看我当前项目的后端代码是怎么组织的,然后帮我把 Stripe 支付接进去。 + +请参考这些官方文档: +- https://docs.stripe.com/checkout/quickstart?lang=node +- https://docs.stripe.com/api/checkout/sessions/create +- https://docs.stripe.com/payments/subscriptions + +我的目标很简单: +- 用户点购买按钮后,能跳到 Stripe 的付款页面 +- 套餐只有月付和年付两种 +- 不要让我自己决定代码该放在哪,你先看项目再帮我放到合适的位置 + +请你: +1. 先搜索项目,弄清楚后端入口文件、路由文件、环境变量写法分别在哪里。 +2. 再参考官方文档,帮我把"创建 Stripe 支付链接"这一步接进去。 +3. 不要让我自己传金额,价格请用后端环境变量来决定。 +4. 做完后告诉我你改了哪些文件。 +5. 最后告诉我,我还需要去 Stripe 后台补哪些配置。 +``` + +### 6.4 الخطوة الرابعة:前端跳转到支付页 + +这一步的目标非常简单:让定价页按钮调用你的后端接口,再跳转到 Stripe Checkout。 + +参考文档: + +- Stripe Checkout 集成说明:[Build an integration with Checkout](https://docs.stripe.com/payments/checkout/build-integration) + +给 AI 的 prompt: + +```text +帮我把项目里的"购买"按钮接上 Stripe。 + +要求: +- 不动现有页面,只改按钮点击后的逻辑 +- 点击后调用后端接口获取支付链接,然后跳转到 Stripe +- 如果出错,给用户一个简单نصيحة(比如"支付暂时不可用,请稍后再试") + +参考文档:https://docs.stripe.com/payments/checkout/build-integration +``` + +### 6.5 الخطوة الخامسة:Webhook 更新数据库状态 + +这是最关键的一步。 + +::: info 为什么这一步最关键 +很多人会以为"用户付完款并且跳转到了 success 页面"就算完成了。 + +不是。 + +对你的系统来说,真正مهم的是: +**Stripe 有没有正式把事件打到你的 Webhook,而你的后端有没有把数据库状态更新成功。** +::: + +你也可以让 AI 按 Stripe 官方 Webhook 文档直接实现,不要自己手写。 + +参考文档: + +- Stripe Webhooks:[Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Stripe CLI:[Stripe CLI](https://docs.stripe.com/stripe-cli) +- Stripe CLI 用法:[Use the Stripe CLI](https://docs.stripe.com/stripe-cli/use-cli) + +给 AI 的 prompt: + +```text +请继续帮我把 Stripe 的"付款成功后自动生效"这一步接好。 + +请参考这些官方文档: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +我的目标是: +- 用户付完钱后,不只是跳转到成功页面 +- 而是真的把我数据库里的会员状态改成已开通 + +请你: +1. 先搜索当前项目里数据库相关代码和用户状态是怎么存的。 +2. 再帮我加 Stripe webhook。 +3. 支付成功后,把对应用户改成 active,或者更新成项目里现在已经在用的会员状态字段。 +4. 如果项目里已经有订阅表、订单表、用户表,请优先沿用现有结构。 +5. 做完后告诉我你改了哪些文件。 +6. 顺便告诉我本地怎么测试这一步有没有真的生效。 +``` + +## 7. 让 AI 帮你快速接入的نصيحة词 + +如果你用的是 Codex、Claude Code、Trae、Cursor 一类工具,可以直接把下面这个نصيحة词贴给它,让它在你的项目里做支付接入。 + +```text +请你帮我把当前项目接上 Stripe 支付,我希望做一个最简单能跑起来的会员收费功能。 + +我的要求: +1. 我是零基础,请你先自己看项目,再决定代码应该改哪里。 +2. 不要让我自己判断目录结构、路由结构、数据库结构。 +3. 我只想先做最简单版本:月付和年付两个套餐。 +4. 用户点击购买后,能跳到 Stripe 付款页面。 +5. 付款成功后,我数据库里的会员状态能变成已开通。 +6. 不要一开始加太多复杂功能,比如优惠券、升级降级、复杂发票。 + +输出要求: +1. 先给我一个改动计划。 +2. 然后直接修改代码。 +3. 最后告诉我怎么一步一步本地测试。 +4. 如果有哪个خطوة还需要我去 Stripe 后台操作,请直接把链接和要点告诉我。 +``` + +如果你希望 AI 更贴近你的项目,还可以在开头补上: + +- 你的前端框架 +- 你的后端目录结构 +- 你的数据库表名 +- 你现在的用户系统是 Supabase Auth 还是自建 Auth + +## 7.1 本地联调也尽量交给 AI + +如果你希望连本地联调都让 AI 帮你串起来,可以直接用下面这段: + +```text +请继续帮我把 Stripe 支付真正跑通,我想一步一步照着做,不想自己猜。 + +请参考官方文档: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +我的目标: +1. 告诉我先打开哪些 Stripe 页面。 +2. 告诉我如何拿到 STRIPE_WEBHOOK_SECRET。 +3. 告诉我如何使用 stripe login 和 stripe listen。 +4. 告诉我怎样验证 checkout.session.completed 已经成功打到本地 webhook。 +5. 如果当前项目需要先启动前端和后端,也请顺带告诉我具体命令。 +6. 不要只讲原理,请按实际操作خطوة输出。 +7. 如果我某一步做错了,也请告诉我最常见的报错会长什么样。 +``` + +## 8. 最容易踩坑的 4 件事 + +1. **把 `success` 页面当成支付成功** + 真正决定状态的是 Webhook,不是前端跳转。 +2. **让前端传金额** + 这会带来严重的价格篡改风险。 +3. **Webhook 路由被 `express.json()` 提前处理** + Stripe 验签需要原始请求体。 +4. **没有做幂等处理** + Webhook 可能重试,如果你每次都重复加会员或积分,就会出事故。 + +## 9. 一句话选型建议 + +如果你现在只是想先把收费跑起来: + +| 你的主要用户 | 最先尝试的方案 | +| :--- | :--- | +| 海外 SaaS / 国际用户 | Stripe | +| 中国大陆用户 | 支付宝 / 微信支付 | +| 香港或跨境团队 | Stripe + 本地钱包 / FPS 聚合方案 | + +后面的具体区别,我统一放到الملحق。 + +::: info 最简单的选型思路 +不要一开始就想"我要把全球支付方式一次全接完"。 + +更实际的顺序通常是: +- 先按主要用户所在地区选一条主支付链路 +- 先把最小可行支付跑通 +- 再根据真实用户来源补第二、第三种支付方式 +::: + +## 10. ملخص + +到这里,你已经掌握了最基础但最مهم的一条收费链路: + +1. 前端发起购买。 +2. 后端创建 Checkout Session。 +3. 用户在 Stripe 页面支付。 +4. Stripe 通过 Webhook 通知后端。 +5. 后端更新数据库。 +6. 前端刷新后显示新的会员或订单状态。 + +如果你只想快速把支付接进项目,前面的内容已经够用了。下面的الملحق你可以在真正遇到问题时再回来看。 + +--- + +# الملحق + +## الملحق A:Stripe 里最常见的几个对象 + +第一次看 Stripe 文档,最容易被这些对象名绕晕。你其实只需要先理解下面几个: + +| 对象 | 作用 | 你可以把它理解成什么 | +| :--- | :--- | :--- | +| `Product` | 描述卖的是什么 | 商品或会员套餐 | +| `Price` | 描述卖多少钱、周期怎么收费 | 月付、年付、买断 | +| `Checkout Session` | Stripe 托管的支付流程 | 付款页 | +| `Subscription` | 周期订阅关系 | 自动续费会员 | +| `Customer` | 付款用户 | Stripe 中的客户档案 | +| `Webhook` | 异步通知 | Stripe 告诉你"这笔款怎么样了" | + +## الملحق B:为什么 `success` 页面不等于支付成功 + +很多人以为"用户付完钱,跳到了 success 页面"就算支付成功了。这是最容易踩的坑。 + +### 先讲一个真实场景 + +假设你做了一个会员网站: +1. 用户点击"购买会员" +2. 跳转到 Stripe 付款页面 +3. 用户输入信用卡,点击付款 +4. 页面跳转到你的 `success.html` +5. 你在 success 页面写代码:"既然到了这页,就给用户开通会员" + +**问题在哪?** + +用户可能根本没付钱,或者付到一半关页面了,也能直接访问 `success.html`。 + +### 两条完全不同的路径 + +```mermaid +flowchart TB + pay["用户在 Stripe 完成支付"] + + subgraph unreliable["❌ 不可靠路径:只看 success 页面"] + success["浏览器跳到 success 页面"] + fake["前端代码认为已开通"] + risk["风险:关页 / 断网 / 伪造 URL / 根本没付钱"] + success --> fake --> risk + end + + subgraph reliable["✅ 可靠路径:以后端 Webhook 为准"] + event["Stripe 服务器发送 Webhook"] + verify["后端校验签名"] + active["数据库正式更新为已付费"] + event --> verify --> active + end + + pay --> success + pay --> event +``` + +**关键区别:** + +| | success 页面跳转 | Webhook 通知 | +| :--- | :--- | :--- | +| 谁发起的 | 用户的浏览器 | Stripe 的服务器 | +| 能伪造吗 | 能,直接访问 URL 就行 | 不能,有签名验证 | +| 一定代表付款成功吗 | 不一定 | 一定 | +| 你的系统怎么知道 | 前端代码猜的 | Stripe 正式通知的 | + +### 完整流程应该是怎样的 + +```mermaid +sequenceDiagram + autonumber + actor User as 用户 + participant Frontend as 你的网页 + participant Stripe as Stripe + participant Webhook as 你的后端接口 + participant DB as 数据库 + + User->>Stripe: 在 Stripe 页面完成付款 + Note over Stripe: 钱真的到了 Stripe 账户 + + Stripe-->>Frontend: 浏览器跳转到 success 页面 + Note over Frontend: ⚠️ 这步只是跳转
不代表系统已确认 + + Stripe->>Webhook: 发送 Webhook 通知
"checkout.session.completed" + Note over Webhook: ✅ 这才是正式通知 + + Webhook->>Webhook: 校验签名
(确保是 Stripe 发的,不是黑客) + + Webhook->>DB: 更新用户状态为"已付费" + DB-->>Webhook: 保存成功 + Webhook-->>Stripe: 返回 200 OK + + Frontend->>DB: 用户刷新页面,查询状态 + DB-->>Frontend: 返回"已付费" + Note over Frontend: 这时候才显示会员功能 +``` + +### 每个环节的卡点 + +**第 1 步:用户在 Stripe 付款** + +这是唯一确定"钱真的付了"的时刻: +- 用户输入信用卡معلومة,点击确认 +- 银行从用户卡里扣款 +- Stripe 确认收到这笔钱 + +**第 2 步:浏览器跳转到 success 页面(问题最大)** + +这一步完全不可靠,因为: +- 用户可以直接在浏览器输入 `yoursite.com/success`,根本没付钱也能访问 +- 用户付到一半关页面了,但之前复制了 success 链接,之后直接打开 +- 网络问题导致跳转失败,但钱已经扣了(用户付了钱却没看到成功页面) +- 用户点返回键,又付了一次钱,但两次都跳转到同一个 success 页面 + +**第 3 步:Stripe 发送 Webhook** + +这是 Stripe 主动通知你的服务器"这笔款到账了": +- 只有 Stripe 的服务器能发起这个请求 +- 请求里带有签名,你的后端可以验证是不是真的 Stripe 发的 +- 即使 success 页面没打开、用户断网了,Webhook 也会发送 + +**第 4 步:后端校验签名** + +为什么要校验?防止黑客伪造通知。 + +假设没有校验,黑客可以直接给你的服务器发一个假通知:"用户 A 付了 1000 元"。你的系统就会给黑客开通会员。 + +校验的过程: +- Stripe 用你们约定的密钥对通知内容生成签名 +- 你的后端用同样的密钥验证签名是否匹配 +- 匹配 = 100% 是 Stripe 发的,不匹配 = 直接拒绝 + +**第 5 步:更新数据库** + +只有校验通过后,才更新数据库: +- 把用户状态从"待付款"改成"已付费" +- 记录订单号、金额、付款时间 +- 开通对应的会员权限 + +**第 6 步:前端查询状态** + +success 页面不要自己判断"到了这页就是成功了"。正确的做法: +- 页面加载时,向后端发送请求:"这个用户付费了吗?" +- 后端查数据库,返回真实状态 +- 根据返回النتيجة显示"开通成功"或"等待确认" + +### 一个常见的错误做法 + +```javascript +// 错误:在 success 页面直接开通 +// success.html +if (window.location.pathname === '/success') { + // 危险!任何人都能访问 /success + activateMembership(); +} +``` + +```javascript +// 正确:每次刷新都查后端 +// success.html +async function checkStatus() { + const response = await fetch('/api/user/status'); + const data = await response.json(); + + if (data.paymentStatus === 'paid') { + showMemberFeatures(); + } else { + showPendingMessage(); + } +} +``` + +### الخلاصة一句话 + +**success 页面只是"浏览器跳转成功",Webhook 才是"Stripe 正式确认收款"。** + +你的系统必须以 Webhook 为准,不能相信前端的跳转。 + +## الملحق C:订阅系统最值得监听的事件 + +| 事件 | 含义 | 你通常要做什么 | +| :--- | :--- | :--- | +| `checkout.session.completed` | 首次开通成功 | 创建本地订阅记录 | +| `invoice.paid` | 自动续费成功 | 延长有效期 | +| `invoice.payment_failed` | 自动扣费失败 | 标记风险状态并提醒用户 | +| `customer.subscription.deleted` | 订阅取消 | 回收权限或标记到期后失效 | + +### 订阅状态图 + +```mermaid +stateDiagram-v2 + [*] --> NotStarted: 用户未购买 + NotStarted --> Active: checkout.session.completed + Active --> Active: invoice.paid + Active --> PastDue: invoice.payment_failed + PastDue --> Active: 用户补款成功 + Active --> Canceled: customer.subscription.deleted + PastDue --> Canceled: 到期未恢复 + Canceled --> [*] + + state "未开通" as NotStarted + state "会员有效" as Active + state "扣费失败 / 待恢复" as PastDue + state "已取消 / 到期回收" as Canceled +``` + +### 续费 / 失败 / 取消时序图 + +```mermaid +sequenceDiagram + autonumber + participant Stripe as Stripe + participant Webhook as 你的 Webhook 接口 + participant DB as 订阅表 / 订单表 + participant App as 你的应用 + actor User as 用户 + + rect rgb(235, 248, 255) + Stripe->>Webhook: invoice.paid + Webhook->>DB: 延长 current_period_end + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 继续保持会员有效 + end + + rect rgb(255, 247, 237) + Stripe->>Webhook: invoice.payment_failed + Webhook->>DB: 标记 past_due + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 提醒更新支付方式 + end + + rect rgb(254, 242, 242) + Stripe->>Webhook: customer.subscription.deleted + Webhook->>DB: 标记 canceled + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 停止高级权限 + end +``` + +## الملحق D:其他支付方案怎么选 + +### 1. 中国大陆 + +主要用户在大陆的话,首选还是 **[支付宝](https://open.alipay.com/)** 和 **[微信支付](https://pay.wechatpay.cn/)**。 + +**业务模式:** + +两者都是"支付网关"模式。你需要: +- 申请商户资质(营业执照、对公账户) +- 用户付的钱直接到你的商户账户 +- 你自己负责税务、退款、对账 + +**技术模式:** + +两者都是"后端下单 + 前端调起 + 后端通知"的模型,跟 Stripe 思路一样。 + +**支付宝接入流程:** +1. 在支付宝开放平台创建应用 +2. 配置公私钥和回调地址 +3. 后端调用统一下单接口,生成支付链接或二维码 +4. 用户扫码或跳转付款 +5. 支付宝异步通知你的后端,更新订单状态 + +**微信支付接入流程:** +- JSAPI 支付:适合公众号、小程序,用户在微信内直接付款 +- Native 支付:PC 端生成二维码,用户扫码付款 +- H5 支付:手机浏览器内拉起微信 App 付款 + +流程:后端下单 → 拿到 `prepay_id` 或 `code_url` → 前端调起支付 → 后端接收通知确认成功 + +**参考链接:** +- 支付宝开放平台:https://open.alipay.com/ +- 微信支付商户文档:https://pay.wechatpay.cn/doc/v3/merchant/ + +### 2. 香港 + +香港市场比较混合,常见组合: + +- 银行卡:Visa / Mastercard +- FPS(转数快):香港本地即时转账 +- AlipayHK / WeChat Pay HK:香港版支付宝和微信 + +**推荐组合:** +- 用 **[Stripe](https://stripe.com/hk)** 覆盖国际卡和订阅 +- 用 **[Airwallex](https://www.airwallex.com/)** 或 **[Adyen](https://www.adyen.com/)** 补本地钱包和 FPS + +### 3. 海外 / 国际 SaaS + +#### [Stripe](https://stripe.com/) + +**业务模式:** 支付网关 + +- 你需要自己申请商户资质(部分国家 Stripe 可以帮你搞定) +- 用户付的钱到你的 Stripe 账户,再结算到你的银行账户 +- 你自己负责税务申报 + +**技术模式:** + +- API 体验最好,文档清晰 +- 支持 Checkout(托管页面)、Elements(自定义表单)、Payment Links(无代码) +- Webhook 通知支付状态 +- 支持订阅、发票、多币种 + +**适合谁:** 海外 SaaS、独立开发者、需要灵活定制的团队 + +**参考链接:** https://docs.stripe.com/ + +#### [PayPal](https://www.paypal.com/) + +**业务模式:** 支付网关 + +- 用户付的钱到你的 PayPal 账户,再提现到银行 +- 你自己负责税务 + +**技术模式:** + +- 一次性支付:前端放按钮,后端创建/确认订单 +- 订阅制:先建 Product 和 Plan,再用 SDK 拉起 +- 同样需要后端和 Webhook,不要只看前端回调 + +**适合谁:** 需要补充渠道的海外业务,用户习惯用 PayPal 付款 + +**参考链接:** https://developer.paypal.com/docs/ + +#### [Paddle](https://www.paddle.com/) + +**业务模式:** Merchant of Record (MoR) + +- Paddle 是"记录商家",法律上由 Paddle 向用户收款 +- Paddle 帮你处理全球税务、VAT、退款、合规 +- 用户付的钱到 Paddle,Paddle 扣除税费和手续费后结算给你 +- 你不需要在每个国家注册公司或处理税务 + +**技术模式:** + +- Paddle.js:前端嵌入托管结账页 +- 后端 API:创建 transaction,交给 checkout 处理 +- Webhook 同步订阅状态 + +**适合谁:** 不想处理全球税务的 SaaS 团队,尤其是 B2B SaaS + +**参考链接:** https://developer.paddle.com/ + +#### [Lemon Squeezy](https://www.lemonsqueezy.com/) + +**业务模式:** Merchant of Record (MoR) + +- 和 Paddle 类似,Lemon Squeezy 是"记录商家" +- 帮你处理全球税务、VAT、合规 +- 2024 年被 Stripe 收购,但独立运营 + +**技术模式:** + +- Hosted Checkout:最简单,直接生成付款链接 +- Checkout Overlay:浮层嵌入你的页面 +- 后端 API:创建 checkout,灵活控制 + +**适合谁:** 独立开发者、数字产品、软件授权 + +**参考链接:** https://docs.lemonsqueezy.com/ + +### 4. 企业级方案 + +#### [Airwallex(空中云汇)](https://www.airwallex.com/) + +**业务模式:** 支付网关 + 全球账户 + +- 提供全球收款账户(类似虚拟银行账户) +- 支持多币种收款、换汇、付款 +- 你自己负责税务 + +**技术模式:** + +- Payment Links:几乎不用代码,生成付款链接 +- Hosted Payment Page:托管页面 +- Drop-in / Embedded / Native API:深度接入,自定义程度高 +- 支持 Alipay HK、FPS、WeChat Pay 等本地支付方式 + +**适合谁:** 香港团队、跨境业务、需要多币种账户的公司 + +**参考链接:** https://www.airwallex.com/docs/ + +#### [Adyen](https://www.adyen.com/) + +**业务模式:** 支付网关 + +- 企业级支付平台,年处理交易额万亿欧元 +- 支持线上、线下、移动端全渠道 +- 你自己负责税务 + +**技术模式:** + +- Pay by Link:最简单,生成付款链接 +- Drop-in / Components:标准线上接入 +- 后台可启用 Alipay、Alipay HK、PayMe 等本地支付方式 + +**适合谁:** 大型企业、需要全渠道支付的公司 + +**参考链接:** https://docs.adyen.com/ + +### 5. 方案对比 + +| 方案 | 业务模式 | 税务处理 | 适合谁 | +| :--- | :--- | :--- | :--- | +| Stripe | 支付网关 | 自己处理 | 海外 SaaS、开发者 | +| PayPal | 支付网关 | 自己处理 | 海外补充渠道 | +| Paddle | MoR | Paddle 代处理 | B2B SaaS、不想管税务 | +| Lemon Squeezy | MoR | LS 代处理 | 独立开发者、数字产品 | +| Adyen | 支付网关 | 自己处理 | 大型企业 | +| Airwallex | 支付网关 + 账户 | 自己处理 | 跨境业务、香港团队 | +| 支付宝/微信 | 支付网关 | 自己处理 | 大陆用户 | + +### 6. 按地区选方案 + +| 你的市场 | 推荐方案 | +| :--- | :--- | +| 中国大陆 | 支付宝 / 微信支付 | +| 香港 | Stripe + Airwallex / Adyen | +| 海外 SaaS | Stripe(自己管税务)或 Paddle(MoR 代管) | +| 海外数字产品 | Stripe / Lemon Squeezy / Paddle | +| 多地区企业级 | Adyen / Airwallex / Stripe 组合 | diff --git a/docs/ar-sa/stage-2/backend/zeabur-deployment/index.md b/docs/ar-sa/stage-2/backend/zeabur-deployment/index.md new file mode 100644 index 0000000..f709b32 --- /dev/null +++ b/docs/ar-sa/stage-2/backend/zeabur-deployment/index.md @@ -0,0 +1,490 @@ +# كيفية نشر تطبيقات الويب + +在本教程中,我们将介绍如何将你的 Web 应用部署到互联网上,让其他人可以访问。我们会介绍三个常用的部署平台:**腾讯云 CloudBase**、**Vercel** 和 **Zeabur**,帮助你快速完成从"写好代码"到"让别人可以在互联网上访问你的网站"的完整流程。 + +# 什么是"部署"? + +在开始之前,我们先弄清楚"部署(Deployment)"到底是什么意思。任何一个网站想要被外部用户访问,都必须有一个可以公开访问的网络地址(这个地址可以是 IP 地址,比如 123.45.67.89,也可以是域名,比如 [google.com](https://google.com/) 等)。但只有地址是不够的——你写好的网页代码(例如 HTML、CSS、JavaScript 文件,或者使用 React、Vue 等框架写的项目),以及相关的图片 / 视频资源,都必须"放"在一台 24 小时在线的服务器上,由它来响应网络请求,这样任何人的浏览器才能访问并下载这些资源。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image1.png) + +图片来源:https://www.hostinger.com/tutorials/what-is-cloud-hosting + +把资源上传、配置好环境并让服务"跑起来"的整个过程,就被称为 **部署(Deployment)**。 + +简单来说:你在自己电脑上写好的网页,只要在本机启动程序,就只能通过本地地址在自己的浏览器里访问,因为这些代码只存在于你的硬盘上。"部署"就是把你的代码和资源转移到一台连接着公网的专业服务器上,并做好配置,让这台服务器知道"别人访问时我要怎么响应"——比如:当有人在浏览器中输入你的域名时,服务器会立刻找到对应的网页文件,把内容传回给对方的设备,从而让用户看到你的页面。 + +如果手动部署,一个项目往往需要好几个خطوة,每一步都可能踩坑。常见关键خطوة包括: + +1. **服务器准备**:你需要先购买云服务器(比如阿里云、腾讯云、或 AWS EC2),选择服务器所在地区(如上海、新加坡)、配置(CPU、内存、磁盘大小等),还要学会如何远程连接服务器(例如通过 SSH 工具登录)。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image2.png) +2. **环境配置**:Web 应用需要在特定"环境"中才能运行——例如运行 Node.js 项目必须先安装 Node.js;运行 Python 项目必须安装 Python 以及对应的第三方库。如果环境版本不匹配,程序就可能报错、无法启动。 +3. **上传资源**:你需要把本地的代码和资源上传到服务器上,常用的方法包括 FTP 或 Git。如果项目体积比较大(比如包含视频文件),中途一旦断线,有时需要重新上传。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image3.png) + +4. **启动服务并测试**:上传完成后,你还需要在服务器上执行命令启动应用,并测试"分配的网络地址是否能访问"。如果访问不了,有可能是服务器防火墙没有放行对应端口(比如你的应用监听 3000 端口,但该端口被防火墙拦截),也可能是程序本身有 Bug,这时就需要查看服务器日志进行排查。 + > 💡 可以把端口理解为区分同一台设备上不同应用的"房间号",而 IP 则是这台设备的"门牌号"。IP 和端口合在一起(IP:port),就可以精确定位到某一个网络服务。 +5. **维护与更新**:后续每次你修改代码,都要重新上传并重启服务。如果服务器宕机(例如断电、网络故障),还需要手动重启应用,有时还要额外配置"进程守护工具",让程序在异常退出后自动拉起。 + +像 CloudBase、Vercel、Zeabur 这样的"低代码部署平台",就是为了解决上述复杂问题而诞生的。它们会帮你自动完成"买服务器、配环境、上传代码、启动服务、监控运行"等خطوة。你只需要把自己的代码仓库(比如 GitHub 或 GitLab)连接到平台,或者直接上传代码,它就会自动拉取代码、识别应用类型、配置对应的运行时环境,最后给你一个可以被任何人访问的公网地址。它甚至可以一键绑定你自己的域名。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image4.png) + +接下来,我们会分别介绍这三个平台的特点和使用方法,帮助你选择最适合自己的部署方案。 + +--- + +# 部署平台对比 + +| 平台 | 特点 | 适用场景 | 免费额度 | +|------|------|----------|----------| +| **腾讯云 CloudBase** | 国内访问速度快,与微信生态深度整合 | 国内用户为主、需要微信小程序支持的项目 | 有免费额度 | +| **Vercel** | 前端框架支持好,与 GitHub 集成紧密 | React/Vue/Next.js 等现代前端项目 | 有免费额度 | +| **Netlify** | 功能全面,支持表单处理和身份验证,与 Git 集成好 | 需要表单处理、身份验证等高级功能的静态网站 | 有免费额度 | +| **Zeabur** | 支持多种语言和服务模板,配置灵活 | 需要部署多种服务(如 Dify、n8n)的复杂项目 | 每月约 5 美元免费额度 | + +--- + +# 1. 腾讯云 CloudBase + +腾讯云 CloudBase(云开发)是腾讯云提供的一站式后端云服务,特别适合国内开发者使用。它的优势在于: + +- **国内访问速度快**:服务器位于国内,访问延迟低 +- **微信生态整合**:可以方便地对接微信小程序、公众号 +- **一站式解决方案**:提供静态网站托管、云函数、数据库、存储等全套服务 +- **免费额度充足**:个人开发者有充足的免费资源额度 + +## 使用 CloudBase 部署 Web 应用 + +### خطوة 1:注册并登录 + +访问 [腾讯云 CloudBase 控制台](https://console.cloud.tencent.com/tcb),使用微信或 QQ 登录。 + +### خطوة 2:创建环境 + +点击"新建环境",选择一个环境名称(如 `my-web-app`)。 + +> ⚠️ **ملاحظة**:CloudBase 的免费体验版需要兑换码才能开通。你需要关注腾讯云 CloudBase 公众号,在公众号中输入"领取兑换码"获取免费体验版的兑换码,然后在创建环境时填写兑换码即可开通免费环境(免费试用期为 6 个月)。 + +### خطوة 3:开通静态网站托管 + +在环境管理页面,找到"静态网站托管"功能并开通。开通后你会获得一个默认的访问域名。 + +CloudBase 的静态网站托管提供多种部署方式,与 Zeabur 类似: + +- **本地项目上传**:直接从本地上传构建好的静态文件(HTML、CSS、JS 等) +- **模板部署**:使用预设模板快速创建项目,如 React Web 应用模板、Vue Web 应用模板 +- **Git 仓库部署**:支持从 GitHub 等代码仓库自动拉取代码并部署 + +### خطوة 4:部署代码 + +在静态网站托管页面,CloudBase 提供三种部署方式: + +**方式一:本地项目部署(本地项目上传)** +- 在控制台选择"本地项目部署" +- 直接上传构建好的静态文件(HTML、CSS、JS 等) +- 选择你本地构建好的项目文件夹(如 `dist` 或 `build` 目录) +- 等待上传完成即可访问 + +**方式二:模板部署** +- 使用预设模板快速创建项目 +- 支持 React Web 应用模板、Vue Web 应用模板等 +- 基于模板自动构建并部署 + +**方式三:Git 仓库部署** +- **Git 个人仓库部署**:绑定你的 GitHub 等个人代码仓库 +- **公开仓库部署**:支持从公开的 Git 仓库拉取代码 +- 配置自动构建命令(如 `npm run build`) +- 每次推送代码会自动重新部署 + +> 💡 **نصيحة**:你也可以使用 CLI 工具进行部署: +> ```bash +> # 安装 CloudBase CLI +> npm install -g @cloudbase/cli +> # 登录 +> tcb login +> # 部署 +> tcb hosting deploy ./dist -e your-env-id +> ``` + +### خطوة 5:配置自定义域名(可选) + +在静态网站托管设置中,可以绑定你自己的域名,并申请免费的 HTTPS 证书。 + +--- + +# 2. Vercel + +Vercel 是全球最流行的前端部署平台之一,特别适合部署 React、Vue、Next.js 等现代前端框架项目。它的特点包括: + +- **与 GitHub 深度集成**:推送代码即自动部署 +- **自动预览**:每个 Pull Request 都会生成独立的预览链接 +- **全球 CDN**:网站自动分发到全球节点,访问速度快 +- **Serverless 函数**:支持在项目中编写后端 API + +> ⚠️ **ملاحظة**:Vercel 在部分网络环境下访问可能不太稳定,国内用户建议优先考虑 CloudBase。 + +## 使用 Vercel 部署 Web 应用 + +### خطوة 1:注册账号 + +访问 [Vercel 官网](https://vercel.com),使用 GitHub 账号登录。 + +### خطوة 2:导入项目 + +1. 点击 "Add New Project" +2. 选择你要部署的 GitHub 仓库 +3. 如果没有看到想要的仓库,点击 "Adjust GitHub App Permissions" 授权访问 + +### خطوة 3:配置构建设置 + +Vercel 会自动识别项目类型并配置构建命令: + +| 框架 | 构建命令 | 输出目录 | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Next.js | `next build` | - | +| 纯 HTML | - | 项目根目录 | + +如果自动识别不正确,可以手动修改: +- **Build Command**: 构建命令,如 `npm run build` +- **Output Directory**: 构建输出目录,如 `dist` 或 `build` +- **Install Command**: 依赖安装命令,通常是 `npm install` + +### خطوة 4:部署 + +点击 "Deploy" 按钮,等待构建完成。构建成功后,你会获得一个 `xxx.vercel.app` 的域名。 + +### خطوة 5:自定义域名(可选) + +在项目设置中的 "Domains" 页面,可以添加你自己的域名。Vercel 会自动配置 HTTPS。 + +--- + +# 3. Netlify + +Netlify 是另一个非常流行的前端部署平台,与 Vercel 类似,特别适合部署静态网站和单页应用(SPA)。它的特点包括: + +- **功能全面**:除了静态网站托管,还支持表单处理、身份验证、边缘函数等高级功能 +- **与 Git 深度集成**:支持 GitHub、GitLab、Bitbucket,推送代码自动部署 +- **分支预览**:每个分支都会自动生成独立的预览链接 +- **全球 CDN**:网站自动分发到全球节点,访问速度快 +- **表单处理**:无需后端代码即可处理网站表单提交 +- **身份验证**:内置用户身份验证功能,可快速实现登录/注册 + +> ⚠️ **ملاحظة**:Netlify 的国内访问速度可能不如 CloudBase,建议主要面向海外用户的项目使用。 + +## 使用 Netlify 部署 Web 应用 + +### خطوة 1:注册账号 + +访问 [Netlify 官网](https://www.netlify.com),点击 "Sign up" 注册。你可以使用 GitHub、GitLab、Bitbucket 或邮箱注册。 + +### خطوة 2:导入项目 + +1. 登录后点击 "Add new site" → "Import an existing project" +2. 选择你的代码托管平台(如 GitHub) +3. 授权 Netlify 访问你的仓库 +4. 从列表中选择你要部署的仓库 + +### خطوة 3:配置构建设置 + +Netlify 会自动识别常见的前端框架并配置构建设置: + +| 框架 | 构建命令 | 发布目录 | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Angular | `ng build` | `dist/` | +| Next.js | `next build` | `out` | +| 纯 HTML | - | `.`(项目根目录) | + +如果自动识别不正确,可以手动配置: +- **Build command**: 构建命令,如 `npm run build` +- **Publish directory**: 构建输出目录,如 `dist` 或 `build` + +### خطوة 4:部署 + +点击 "Deploy site" 按钮,等待构建完成。构建成功后,你会获得一个 `xxx.netlify.app` 的域名,任何人都可以通过这个地址访问你的网站。 + +### خطوة 5:配置自定义域名(可选) + +1. 进入站点设置,点击 "Domain management" +2. 点击 "Add custom domain" +3. 输入你的域名并按照نصيحة配置 DNS 记录 +4. Netlify 会自动申请并配置 HTTPS 证书 + +### 特色功能 + +#### 1. 表单处理 + +Netlify 提供了一个非常方便的功能:无需后端代码即可处理表单提交。 + +只需在 HTML 表单中添加 `netlify` 属性: + +```html +
+

+ +

+

+ +

+

+ +

+

+ +

+
+``` + +部署后,表单提交的数据会自动发送到 Netlify 后台,你可以在 "Forms" 页面查看所有提交记录,也可以设置邮件通知或将数据转发到其他服务。 + +#### 2. Netlify Functions(边缘函数) + +Netlify 支持部署无服务器函数(Serverless Functions),让你可以在不搭建完整后端服务器的情况下,实现简单的 API 接口。你可以使用 JavaScript 或 TypeScript 编写函数,部署后会自动获得一个可访问的 URL。 + +例如,创建一个 `hello.js` 文件: + +```javascript +exports.handler = async (event, context) => { + return { + statusCode: 200, + body: JSON.stringify({ message: "Hello from Netlify!" }) + }; +}; +``` + +部署后,你可以通过 `https://你的域名/.netlify/functions/hello` 访问这个函数。 + +#### 3. 本地开发支持 + +Netlify 提供了 CLI 工具,方便你在本地开发和测试: + +```bash +# 安装 Netlify CLI +npm install -g netlify-cli + +# 登录账号 +netlify login + +# 本地启动开发服务器 +netlify dev + +# 本地测试函数 +netlify functions:serve +``` + +使用 CLI 工具可以在本地模拟 Netlify 环境,包括表单提交、函数调用等功能,方便在部署前进行测试。 + +--- + +# 4. Zeabur + +Zeabur 是一个新兴的部署平台,特别适合需要部署多种服务的复杂项目。它的优势在于: + +- **服务模板丰富**:内置 Dify、n8n、数据库等多种服务模板 +- **支持多种部署方式**:GitHub、模板、Docker 镜像、本地项目等 +- **灵活的服务组合**:可以在一个项目中部署多个相互关联的服务 +- **按量计费**:用多少付多少,适合实验性项目 + +## 使用 Zeabur 部署 Dify + +在之前的课程中,我们已经简单接触过 Dify。现在,我们可以通过 [Zeabur](https://zeabur.com/projects) 非常轻松地启动自己的 Dify 服务。首先打开 [控制台页面](https://zeabur.com/projects),我们先看一下上面的各个区域。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image5.png) + +在这个页面上,你首先能看到许多方块,这些就是已经启动的服务。在顶部菜单中,你会看到 Agent、Servers、Docs、Templates 等几个选项,它们分别代表: + +1. **Agent**:可以打开 Zeabur 内置的智能助手(Agent),向它提问如何操作,或者查询当前服务器的状态。 +2. **Servers**:在这里可以添加你自己购买的云服务器,或者直接通过 Zeabur 购买服务器。 +3. **Docs**:查看 Zeabur 的完整文档说明。 +4. **Templates**:这里列出了所有内置的模板镜像。 + +> 这里提到的"镜像(Image)",可以理解为"包含代码和运行环境的压缩包"。当某个服务在一台服务器上成功跑起来之后,我们可以选择把"这套运行环境 + 代码"打包成镜像。之后,在任何新服务器上,只要把这个压缩包解压并运行,就不需要重新配置环境和代码,服务就能直接跑起来。 + +在页面右上角,你还能看到自己的余额。默认情况下,每个月会有 5 美元左右的免费额度。关于细节计费规则暂时可以不用太在意,只需要知道:只要服务器在运行,就会消耗额度。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image6.png) + +点击余额可以查看每日的消耗明细。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image7.png) + +现在我们来创建自己的 Dify 服务。首先,在 [控制台首页](https://zeabur.com/projects) 点击 "New Project"。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image8.png) + +接下来是各个创建方式的解释: + +1. **GitHub** + 可以连接到你的 GitHub 账号。绑定之后,就可以直接从 GitHub 仓库里选择项目部署(GitHub 是目前全球最大的代码托管平台)。 +2. **Template(模板)** + 可以基于模板来部署服务。Zeabur 内置了很多预设项目模板(例如 Dify、n8n 等),你可以基于这些模板快速创建并部署应用。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image9.png) +3. **Databases(数据库)** + 用于部署数据库服务,比如 MySQL、MongoDB 等常见数据库。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image10.png) +4. **Functions(函数)** + 可以部署函数服务,你可以编写 JavaScript 或 Python 代码,让它们以函数的形式被调用。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image11.png) + + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image12.png) + +5. **Local Project(本地项目)** + 上传一个本地文件夹,Zeabur 会自动识别其中的启动脚本。这适合将你已经在本地开发好的项目快速部署到 Zeabur 上。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image13.png) +6. **Docker Image** + 部署已经打包好的 Docker 镜像。如果你的项目已经被打成了 Docker 镜像(例如存放在 Docker Hub 或其他镜像仓库中),可以在这里直接部署。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image14.png) +7. **Cursor** + 如果你安装了 Cursor(例如 Cursor IDE),可以通过这个入口将 Cursor 中的项目直接部署到 Zeabur。 + +如果你想部署自己的 Dify 服务,推荐选择 **Template** 方式,然后在搜索框中输入 "dify"。可以看到很多由不同作者维护的版本,你可以任选其一(比如 v1.6.0 版本)。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image15.png) + +接着,输入任意一个名称,Zeabur 会基于这个名称生成一个临时的自定义域名。之后所有人都可以通过这个网址访问你的服务。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image16.png) + +创建完成后,你会看到多个程序(服务)依次启动。需要耐心等待所有服务都进入"已启动"状态。(Dify 服务是由多个程序组成的,每个程序负责不同的功能,它们之间会相互协作。) + +一般来说,你只需要点击左侧的 Dify 应用,就可以看到默认的访问入口地址。但在本例中,由于前面还套了一层 nginx,你需要点击 nginx 服务来获取最终访问地址。可以理解为:nginx 就是负责对外统一"收发请求"的主程序,它会把外部访问的地址分发给内部各个服务。点击左侧的 Nginx,在详情页中可以看到当前的服务地址,然后在浏览器里打开这个地址,等待服务完全启动。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image17.png) + +稍等片刻后,你就能看到 Dify 的登录界面了。输入邮箱地址和注册密码,就可以开始使用你自己的 Dify 服务了。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image18.png) + +如果你有兴趣,还可以顺便启动一个 n8n 服务。n8n 也是海外非常流行的一款 AI 工作流平台。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image19.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image20.png) + +## 使用 Zeabur 与 Trae 部署贪吃蛇游戏 + +在本教程的下一个部分,我们会体验 Zeabur 的一些进阶用法。我们先用 Trae 生成一个贪吃蛇小游戏,再把它部署到 Zeabur 的服务器上,并配置一个可公开访问的链接,让任何人都可以打开你的游戏。 + +الخطوة الأولى,是在本地使用 Trae 创建一个贪吃蛇项目。 + +### 使用 HTML 框架实现 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image23.png) + +对于 Trae 来说,生成一个基于 HTML 的贪吃蛇网页游戏非常简单。游戏生成完成后,你只需要按照前面介绍的 Zeabur 本地部署方式,把包含所有文件的文件夹上传上去即可。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image24.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image25.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image26.png) + +完成后,你就会进入该服务的详情界面: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image27.png) + +点击左侧的 "Network" 选项,在页面中找到 "Public Address" 区域。点击 "Generate Domain",即可生成一个对外访问地址,你可以输入任意喜欢的名称。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image28.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image29.png) + +生成完成后,只要在浏览器中打开这个地址,就可以运行你自己的贪吃蛇游戏了。其它 HTML 类型的 Web 应用也可以用完全相同的方式来部署。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image30.png) + +### 使用 React 框架实现 + +前面我们学习了如何部署基于 HTML 的 Web 应用。接下来,我们再尝试部署一个目前更常用的前端框架:React 应用。相比纯 HTML,React 被认为是一种更加成熟、现代的前端开发框架。它通过组件化的方式组织页面结构,能够显著加快复杂页面的开发,是企业级项目中非常主流的选择。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image31.png) + +#### 重构为 React 架构 + +在 Trae 中,你只需要向 Agent 说明:"帮我把这份代码重构成 React 架构",就可以比较轻松地把原本基于 HTML 的结构重构成 React 项目。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image32.png) + +不过,相比简单的 HTML 文件,React 应用依赖更复杂的构建工具和项目结构,因此部署过程也会稍微麻烦一些。一个典型的问题体现在端口设置上:默认情况下,React 应用一般会监听 3000 端口(你也可以在配置文件或启动日志中看到这一点)。 + +然而,在 Zeabur 上这样部署会失败——因为 Zeabur 只支持监听 8080 端口的应用。也就是说,如果想让 React 应用在 Zeabur 上正常运行,我们必须先把默认监听端口从 3000 改成 8080。 + +要正确进行这一步配置,我们需要先弄清楚两个概念:什么是"端口(Port)",以及"监听端口(Listening Port)"是什么意思。 + +#### 什么是端口? + +> 在计算机网络中,端口可以理解为一个"逻辑通信端点",用来区分同一台设备上运行的不同网络服务。简单类比的话,如果 IP 地址好比一个"门牌号"(例如 162.128.1.1),那端口号就像这栋楼里不同房间的"房间号"——每个房间对应一个服务(例如 Web 服务器、邮箱服务,或者你的 React 应用)。 +> +> 端口号用 16 位整型表示,取值范围是 0 到 65535。 + +如果不想记这些细节,可以简单理解:端口是构成"网络访问地址"的一个必要部分。 + +我们平时访问网站或 IP 地址时,通常不会手动加端口号,是因为 Web 的默认端口是 80 或 443(HTTPS)。大多数浏览器会自动使用这些标准端口。而对于一些特殊端口,比如 React 默认的 3000、Zeabur 要求的 8080,我们就必须在地址后面加上 `:3000` 或 `:8080` 才能访问到对应的内容。 + +#### 什么是"监听端口号"? + +> "监听端口号"指的是某个程序在一台设备上主动"打开并监控"的端口。当一个应用设置了监听端口时,其实就是在告诉操作系统:"我会一直在这个端口上等待网络请求——只要有请求进来,就请转发给我。" + +再形象一点地理解:假设你的电脑是一栋写字楼,IP 地址是这栋楼的地址。楼里开了很多公司或部门,它们分别占用不同的房间,房间号就是端口号。 + +当默认的 React 开发服务器启动时,它会"打开"某个房间的门,并安排"前台"在门口值班,这个房间号就是它的监听端口——3000。 + +同时,React 程序还会告诉这栋楼的"物业管理"(操作系统):"我在 3000 号房间,请把所有寄给 3000 的信件(网络请求)都转给我。" + +这样,当你访问 React 网站时,请求首先会到达这栋楼;物业看到请求要送到 3000 号房间,就会立刻把请求交给 React 的"前台",由它来处理并返回النتيجة——这就是访问 React 应用的过程。 + +当你在本地执行 `npm start`(本地启动 React 开发服务器的默认命令,也可以在 Vibe Coding 的 Agent 侧边栏中执行)时,React 开发服务器就会自动把监听端口设置为 3000。 +而 Zeabur 的平台设计决定了它只会"识别"监听 8080 端口的应用。如果你的 React 应用仍然使用默认的 3000 端口,Zeabur 就无法将请求正确转发给你的应用,最终导致部署失败。 + +#### 修改默认监听端口 + +要把 React 默认监听端口(3000)改成 Zeabur 所要求的 8080,有很多做法。最简单的方式,就是直接在 Trae 里对 Agent 下指令:"请帮我把这个 React 项目的默认端口改为 8080。"Trae 就会帮你修改项目中对应的配置文件。修改完成后,你只需重新打包并按前面的方式上传到 Zeabur 即可。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image33.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image34.png) + +在网络设置中指定一个访问 URL,方式和部署 HTML 项目时基本相同,就可以启动 React 版本的服务。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image35.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image36.png) + +对于其它需要修改端口号的程序,你也可以采用同样的思路:先改默认端口,再上传到 Zeabur 部署。至此,你已经掌握了将常见 Web 应用部署到服务器的基础技能。 + +你可以尝试让 Trae 帮你构建不同类型的应用,并把它们部署到 Zeabur 的默认服务器上。在后续课程中,我们还会学习如何把应用部署到你自己购买的云服务器上。 + +--- + +# ⚠️ 如何停止和删除项目(Zeabur) + +由于启用服务器相关资源都会产生费用,我们在使用时一定要养成"及时关闭不用服务"的习惯,避免把每个月的免费额度消耗完。 + +如果要找到项目的管理入口,首先点击项目中的 "Settings" 选项。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image21.png) + +进入设置页面后,将页面拉到最下方,你会看到类似下面的界面: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image22.png) + +你可以点击 "Suspend All Services" 来暂停所有服务以降低费用;如果服务出现问题,可以点击 "Restart All Services" 对全部服务进行重启。如果你确定不再需要这个项目,可以点击 "Delete Project" 将整个项目彻底删除。 + +--- + +# الخلاصة + +在本教程中,我们介绍了四个常用的 Web 应用部署平台: + +1. **腾讯云 CloudBase**:适合国内用户,访问速度快,与微信生态整合好 +2. **Vercel**:适合现代前端框架项目,与 GitHub 集成紧密,全球 CDN 加速 +3. **Netlify**:功能全面,支持表单处理和身份验证,适合需要高级功能的静态网站 +4. **Zeabur**:适合复杂项目,服务模板丰富,支持多种部署方式 + +选择哪个平台取决于你的具体需求: +- 如果主要面向国内用户,推荐 **CloudBase** +- 如果使用 React/Next.js 等框架,推荐 **Vercel** 或 **Netlify** +- 如果需要表单处理、身份验证等高级功能,推荐 **Netlify** +- 如果需要部署 Dify、n8n 等服务,推荐 **Zeabur** + +无论选择哪个平台,部署的核心流程都是相似的:准备代码 → 选择平台 → 配置构建设置 → 部署上线。掌握这些技能后,你就可以将自己开发的应用分享给全世界了! diff --git a/docs/ar-sa/stage-2/frontend/design-to-code/index.md b/docs/ar-sa/stage-2/frontend/design-to-code/index.md new file mode 100644 index 0000000..121cb1f --- /dev/null +++ b/docs/ar-sa/stage-2/frontend/design-to-code/index.md @@ -0,0 +1,361 @@ +# من النموذج الأولي للتصميم إلى كود المشروع + +::: tip 🎯 السؤال الجوهري +**如何将设计工具中的原型转化为真正能在浏览器里运行的前端代码?** +::: + +--- + +## 1. 从原型到代码的三种路径 + +在使用 Figma、MasterGo 等现代前端设计工具完成界面设计后,一个很实际的问题自然会浮现:这些看起来结构完整的设计稿,要怎么转化成真正能在浏览器里运行的前端代码? + +一般而言,从原型到代码的落地,本质上有三种典型路径: + +| 路径 | 方法 | 特点 | 适用场景 | +|------|------|------|----------| +| **المسار الأول** | 根据图片,使用多模态大模型直接还原出代码 | 灵活、无需特定工具 | 快速原型验证、简单页面 | +| **المسار الثاني** | 通过平台自身能力或插件导出可用代码 | 还原度高、可编辑性强 | Figma/MasterGo 用户 | +| **المسار الثالث** | 平台结合 MCP 能力导出可用代码 | 自动化程度高、可定制 | 需要深度集成的工作流 | + +本文将详细介绍这三种路径的具体实现方法,帮助你根据项目需求选择最合适的工作流。 + +::: tip 📚 المعارف المسبقة +在开始本节之前,建议你先学习 [Figma 与 MasterGo 入门](../figma-mastergo/) 教程,掌握前端设计工具的基础操作。 +::: + +--- + +## 2. المسار الأول:多模态 AI 直接还原代码 + +拥有视觉能力的大模型天生具备将图片转为代码的能力。我们只需要将设计稿截图直接导入对话框,随后让大模型生成完整的النتيجة代码。 + +### 2.1 操作流程 + +1. **截取设计稿图片** + - 在 Figma 或 MasterGo 中,将设计好的页面导出为 PNG 或 JPG + - 确保截图包含完整的页面布局 + +2. **选择多模态 AI 模型** + - 可以使用 Gemini、Qwen、Claude 等支持图像输入的模型 + - 这里以 Gemini 为例进行演示 + +3. **编写نصيحة词** + ``` + 请根据这张设计图生成对应的 HTML/CSS 代码。 + 要求: + - 使用现代 CSS 布局(Flexbox/Grid) + - 响应式设计,适配不同屏幕尺寸 + - 包含所有可见的 UI 元素 + - 颜色、字体大小尽量还原设计稿 + ``` + +![](/zh-cn/stage-2/frontend/design-to-code/images/image42.png) + +4. **获取并保存代码** + - 要求模型返回完整的 HTML 代码 + - 保存为单个 `.html` 文件,方便本地测试 + - 后续可以在本地 IDE 中将其转换为 React 等框架 + +### 2.2 الأسئلة الشائعة与解决方案 + +生成页面并非简单的任务,在具体过程中你可能会遇到很多问题: + +| 问题 | 解决方案 | +|------|----------| +| 界面排布不均 | 向 AI 描述具体的布局问题,要求调整 CSS 的 margin/padding | +| 界面显示不全 | 检查是否设置了正确的 viewport,要求添加响应式断点 | +| 颜色还原不准 | 使用取色工具获取设计稿的精确色值,提供给 AI | +| 字体不匹配 | 指定具体的字体名称或要求使用 Google Fonts 替代 | + +::: tip 💡 小技巧 +推荐先生成 HTML 代码,获取后再使用本地 IDE 将其转换为 React 框架。这样可以获得多个独立的 HTML 文件,统一进行框架转换。 +::: + +### 2.3 MasterGo AI 生成页面 + +MasterGo 同样提供了强大的 AI 页面生成功能,可以根据参考图直接生成可用的网页代码。 + +#### 找到 AI 功能入口 + +在 MasterGo 编辑界面的上方工具栏中,可以找到 AI 工具按钮: + +![](/zh-cn/stage-2/frontend/design-to-code/images/image47.png) + +#### 生成流程 + +1. **上传参考图** + - 使用与多模态 AI 相同的方式上传设计参考图 + - 添加文字描述需求 + +2. **查看生成النتيجة** + +![](/zh-cn/stage-2/frontend/design-to-code/images/image48.png) + +![](/zh-cn/stage-2/frontend/design-to-code/images/image49.png) + +3. **获取代码** + - 点击蓝色按钮"插入到画布",可直接编辑生成后的网页 + - 或点击右侧的"代码"按钮,复制代码内容到本地 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image50.png) + +--- + +## 3. المسار الثاني:平台自身能力或插件导出代码 + +### 3.1 Figma Make 生成代码 + +Figma Make 是 Figma 官方推出的 AI 设计工具,能够根据用户输入的نصيحة词或者参考图,高精度地还原网页原型 UI 界面。 + +#### 功能特点 + +- **高精度还原**:相比原生 AI 生成代码,效果更佳 +- **可编辑性**:生成النتيجة可以转换为可编辑的 Figma Design 文件 +- **GitHub 集成**:支持直接将代码同步到 GitHub + +::: tip 🔑 权限说明 +使用 Figma Make 的完整功能需要 Pro 用户权限,学生可以通过教育认证免费获得 Pro 权限。 +::: + +#### 操作خطوة + +1. **进入 Figma Make** + - 在 Figma 首页点击 Make 按钮 + - 或者访问 [Figma Make](https://www.figma.com/make) + +2. **上传参考图** + - 将你想要还原的设计图上传到对话框 + - 添加描述需求的نصيحة词 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image43.png) + +3. **查看生成النتيجة** + - 稍等片刻后即可看到渲染النتيجة + - 点击右上角的播放按钮可进行全屏预览 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image44.png) + +4. **细节调整** + - 点击右上角的编辑器图标(鼠标和尺子图标) + - 回到熟悉的 Figma Editor 界面进行详细调整 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image45.png) + +5. **导出代码** + - 调整满意后,选择导出代码 + - 可以直接连接到 GitHub 保存代码 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image46.png) + +### 3.2 插件导出代码 + +除了平台原生的 AI 功能,Figma 和 MasterGo 都支持通过插件导出代码: + +**常用 Figma 插件:** +- **Figma to Code**:将设计稿转换为 React、Vue、HTML 等代码 +- **Anima**:高保真代码生成,支持交互效果 +- **Locofy**:AI 驱动的设计转代码工具 + +**使用خطوة:** +1. 在 Figma 中打开插件面板(Plugins) +2. 搜索并安装需要的代码导出插件 +3. 选中要导出的设计元素 +4. 运行插件,选择目标框架和代码格式 +5. 复制或下载生成的代码 + +--- + +## 4. المسار الثالث:平台结合 MCP 能力导出代码 + +### 4.1 什么是 MCP? + +MCP(Model Context Protocol,模型上下文协议)是一套开放标准协议,它允许 AI 模型安全、可控地访问外部工具和数据源。在前端设计工具的场景中,MCP 让大模型能够直接读取设计文件的结构、样式和组件معلومة,从而更精准地生成代码。 + +### 4.2 MCP 的工作原理 + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ AI 模型 │ ←→ │ MCP 服务器 │ ←→ │ 设计工具 │ +│ (Claude等) │ │ (协议适配) │ │(Figma/MasterGo)│ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +**工作流程:** +1. AI 模型通过 MCP 协议向设计工具发送请求 +2. 设计工具返回结构化的设计数据(图层、样式、组件等) +3. AI 模型理解设计结构并生成对应代码 +4. 代码可以直接导出或同步到开发环境 + +### 4.3 Figma + MCP تطبيق عملي + +#### 环境准备 + +1. **安装 MCP 服务器** + ```bash + # 使用 npx 安装 Figma MCP 服务器 + npx figma-mcp-server + ``` + +2. **配置 Claude Desktop 或其他支持 MCP 的 AI 工具** + ```json + { + "mcpServers": { + "figma": { + "command": "npx", + "args": ["figma-mcp-server"], + "env": { + "FIGMA_ACCESS_TOKEN": "your-figma-token" + } + } + } + } + ``` + +3. **获取 Figma Access Token** + - 登录 Figma → Settings → Personal Access Tokens + - 生成新的 Token 并保存 + +#### 使用流程 + +1. **在 AI 工具中启用 MCP 连接** + - 打开 Claude Code 或其他支持 MCP 的 IDE + - 确认 MCP 服务器已连接 + +2. **提供设计文件链接** + ``` + 用户:请帮我将这个 Figma 设计转换为 React 代码 + 链接:https://www.figma.com/file/xxxxx + + AI:我已通过 MCP 连接到 Figma,正在读取设计文件结构... + ``` + +3. **AI 自动分析并生成代码** + - MCP 服务器获取设计文件的图层树 + - AI 理解组件结构和样式属性 + - 生成带有正确命名和结构的 React/Vue 组件 + +4. **迭代优化** + ``` + 用户:请将按钮组件提取为独立的可复用组件 + + AI:好的,我已通过 MCP 识别到设计系统中的 Button 组件, + 正在生成带有 props 接口的 React 组件... + ``` + +### 4.4 MCP 的优势 + +| 特性 | 传统方式 | MCP 方式 | +|------|----------|----------| +| **数据精度** | 依赖截图,可能丢失细节 | 直接读取原始设计数据 | +| **组件识别** | AI 需要猜测组件边界 | 精确获取组件定义 | +| **样式还原** | 基于像素估算 | 获取精确的设计 token | +| **迭代效率** | 每次修改需重新截图 | 实时同步设计变更 | +| **自动化程度** | 手动复制粘贴 | 可直接写入项目文件 | + +### 4.5 当前可用的 MCP 工具 + +**设计工具 MCP:** +- **Figma MCP Server**:官方支持的 MCP 实现 +- **MasterGo MCP**:社区开发的 MasterGo 适配器 + +**开发环境 MCP:** +- **Claude Code**:原生支持 MCP 协议 +- **Cline**:VS Code 插件,支持 MCP 连接 +- **Trae**:可通过配置启用 MCP 功能 + +::: tip 🔮 未来展望 +MCP 协议正在快速发展,未来设计工具与开发环境的集成将更加紧密。预计会出现更多一键同步设计到代码的解决方案,进一步缩短设计与开发之间的距离。 +::: + +--- + +## 5. 代码导出后的工作 + +### 5.1 本地测试 + +获取代码后,在本地 IDE 中打开并进行测试: + +1. **创建新项目** + ```bash + # 如果是 HTML 文件,直接用浏览器打开 + open index.html + + # 如果是 React/Vue 项目 + npm install + npm run dev + ``` + +2. **与 AI IDE 协作** + - 将生成的代码导入 Trae 或其他 AI IDE + - 让 AI 帮助修复布局问题、添加交互功能 + +### 5.2 الأسئلة الشائعة处理 + +| 阶段 | 问题 | 解决方案 | +|------|------|----------| +| 布局 | 元素错位 | 检查 CSS 的 display 和 position 属性 | +| 样式 | 颜色不一致 | 使用浏览器开发者工具检查实际应用的色值 | +| 响应式 | 移动端显示异常 | 添加 media query 断点 | +| 交互 | 按钮无响应 | 检查 JavaScript 事件绑定 | + +--- + +## 6. 三种路径对比与选择建议 + +### 6.1 路径对比 + +| 维度 | المسار الأول:多模态 AI | المسار الثاني:平台能力 | المسار الثالث:MCP | +|------|------------------|------------------|-------------| +| **上手难度** | ⭐ 简单 | ⭐⭐ 中等 | ⭐⭐⭐ 较复杂 | +| **还原精度** | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐ 高 | ⭐⭐⭐⭐⭐ 最高 | +| **灵活性** | ⭐⭐⭐⭐⭐ 高 | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐ 较高 | +| **自动化程度** | ⭐⭐ 低 | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐⭐ 高 | +| **成本** | 低(按 API 调用) | 中(可能需要 Pro) | 低(开源工具) | + +### 6.2 选择建议 + +**选择المسار الأول(多模态 AI)如果:** +- 需要快速验证想法 +- 设计工具不固定,经常切换 +- 对还原精度要求不高 +- 预算有限 + +**选择المسار الثاني(平台能力)如果:** +- 团队主要使用 Figma 或 MasterGo +- 需要高精度的代码还原 +- 设计师和开发者需要频繁协作 +- 愿意投资 Pro 版本 + +**选择المسار الثالث(MCP)如果:** +- 追求最高程度的自动化 +- 有技术能力配置 MCP 环境 +- 项目需要频繁迭代设计到代码 +- 希望建立标准化的设计开发工作流 + +--- + +## 7. الخلاصة + +通过本章节的学习,你已经掌握了从设计原型到代码的三种核心路径: + +1. **多模态 AI 直接转换**:灵活快速,适合原型验证 +2. **平台原生能力**:还原度高,适合专业设计工作流 +3. **MCP 协议集成**:自动化程度最高,代表未来趋势 + +::: tip 💡 最佳实践 +- **新手推荐**:从المسار الأول(多模态 AI)开始,快速上手 +- **团队协作**:使用المسار الثاني(平台能力),保证设计一致性 +- **效率优先**:尝试المسار الثالث(MCP),建立自动化工作流 +- **混合使用**:根据项目阶段灵活切换不同路径 +::: + +--- + +## المراجع + +- [Figma 与 MasterGo 入门](../figma-mastergo/) - 学习设计工具基础 +- [一起做霍格沃茨画像](../hogwarts-portraits/) - 完整项目تطبيق عملي +- [MCP 官方文档](https://modelcontextprotocol.io/) - 了解协议详情 +- [Figma Make 官方文档](https://help.figma.com/hc/en-us/sections/360007453634-Figma-Make) +- [MasterGo AI 教程](https://mastergo.com/tutorials) diff --git a/docs/ar-sa/stage-2/frontend/figma-mastergo/index.md b/docs/ar-sa/stage-2/frontend/figma-mastergo/index.md new file mode 100644 index 0000000..87cad31 --- /dev/null +++ b/docs/ar-sa/stage-2/frontend/figma-mastergo/index.md @@ -0,0 +1,303 @@ +# مقدمة في Figma و MasterGo + + + +::: tip 🎯 السؤال الجوهري +**如何从零开始使用现代设计工具创建网页原型?** +::: + +--- + +## 1. 为什么要学前端设计工具? + +在开始之前,我们需要理解一个问题:为什么需要学"前端设计工具"?反正直接写 HTML / CSS 代码也能把页面搭出来,多学一个软件和技术,真的有必要吗? + +实际上,把页面运行起来,和把产品设计好根本是两个概念。代码只关注解决如何渲染在浏览器上,如何在不同设备上运行的问题;前端设计工具解决的是معلومة分布的问题,前端交互怎么安排,不同页面怎么跳转,视觉优先级怎么分配的问题。只需要在设计工具里搭一块画布,就能把版式、معلومة层级、交互方式在一块屏幕上对比确定,选择最适当的呈现效果。 + +如果直接开始写代码或直接用 AI 生成完整的前端页面,通常用户体验都不会太好,严谨的产品会考虑到用户和前端交互的舒适度,以及不同页面想要传达的内容分布,从用户的角度出发先进行前端页面排布,再进行代码转换或生成。 + +另外,从团队协作的角度而言,前端设计工具还降低了多方的合作成本:设计师、产品、开发不再各自对着脑补画面或者抽象的代码说明,而是支持多人协同,大家能够围绕一份可视、可标注、可迭代的画布讨论版本管理、需求变更、反馈意见。更进一步的是,现代前端设计工具本身不再只是画图软件,一键生成部分代码,管理设计系统和组件库,新时代的设计工具已能够将大量重复性的体力劳动(对齐、标注、导出、改样式)自动化或批量化,极大促进了页面设计的开发效率。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image8.png) + +### 1.1 前端设计工具的演变 + +在时间的长河中,所谓前端设计工具其实是一条持续演化的技术。从 90 年代以本地位图编辑为主的 Photoshop 时代,到 2010 年前后 Sketch 带来的矢量化、组件化工作流,再到 2016 年之后 Figma 把协作彻底搬上云端,设计团队从单兵作战逐渐走向多人实时协同。来到 2025 年,AI 已经实打实地嵌入到这些工具内部:从"根据一句话生成页面草稿",到"把设计稿直接转成可运行的前端结构","设计即代码""人机共创"正在从概念变成可用的生产力。 + +本节中,我们会选取最具代表的两种现代前端设计工具进行介绍,Figma 和 MasterGo。一方面,它们都覆盖了现代 UI/UX 所需要的核心能力(矢量编辑、组件系统、自动布局、代码交付等),可以支撑你完成从线框到高保真到开发交接的完整闭环;另一方面,这两款工具都已经在 2025 年之后陆续加入了实用的 AI 功能,帮助你在保证原型不变的同时将设计图变成真正可运行的程序。 + +## 1.2 诞生之旅 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image9.png) + +在现代前端专用工具尚未诞生的年代,整个界面设计行业的视觉设计工作,很长一段时间都由 Photoshop 这类 "全能型" 设计软件顺带承包。设计师会在本地通过一层层叠加的图层,细致完成页面整体视觉效果的设计,最终将体积不小的 .psd 源文件交付给前端工程师 —— 而前端要精准还原设计图,还必须手动完成三项繁琐且关键的工作: + +一是 "切图":需要从 .psd 文件的多层结构里,把按钮、图标、Logo、背景模块等独立视觉元素逐一拆分提取,再导出为 PNG、JPG 等网页能直接加载的图片格式(毕竟网页无法直接识别 PSD 的图层معلومة,只能依赖这些拆分后的图片呈现细节); + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image10.png) + +二是 "量尺寸":得用软件自带的测量工具,逐一确认每个元素的宽高、不同模块间的间距(margin/padding)等数据,确保所有尺寸都精准到像素; + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image11.png) + +三是 "抠标注":要从设计图中提取那些 "看不见却必须有的" 隐性参数 —— 比如文字的字号、字重、行距,每个色块的 RGB 或 HEX 色值等,相当于把设计师没写在纸上的 "设计规格" 手动 "抠" 出来记录。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image12.png) + +在此之后,前端的实现阶段才真正展开。无论使用的是原生 HTML/CSS/JS,还是基于 Vue、React 等框架,本质过程是一致的。前端会以 "容器为核心载体",根据设计中各模块的层级与语义重建页面结构。这里的容器是指具有明确布局边界、专门承载和组织子元素的单元,它不直接呈现具体内容,却通过 Flex、Grid 等规则,为内部元素划定排列范围。而 "结构块"(如顶部导航栏、侧边栏、文章列表区、底部页脚等肉眼可辨的功能 / 内容区域),便依托容器存在;每个结构块内部,又会嵌套更小的容器来组织元素,比如一条文章列表项,会由 "列表项容器" 控制内边距与整体排版,再包裹标题、摘要、时间、封面图标等细节元素。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image13.png) + +在现代前端框架里,这些 "结构块(及关联的容器与元素)" 通常会被实现为 "组件"。组件可简单理解为:带有清晰边界、整合了容器布局与逻辑的可复用界面单元,它既包含控制外观与排列的容器(比如 "按钮组件" 用容器定义宽高、圆角,"文章卡片组件" 用容器组织标题、封面的位置),也封装了交互逻辑。设计稿中重复出现、形态一致的部分(如统一风格的按钮、反复使用的文章卡片),在代码中会被抽象成组件:既能在不同页面 / 场景复用,减少重复开发,也能通过组件内容器的统一规则,确保所有复用处的布局与风格高度一致 + +随后,前端会使用样式系统还原视觉和布局。切图阶段导出的 PNG/JPG 等资源,会作为组件或结构块内部的 ``、背景图片,或者按照各框架推荐的静态资源方式引入;量尺寸阶段得到的宽高、间距、行高等具体数值,会被转写为 `width`、`height`、`margin`、`padding`、`line-height` 等样式属性,应用到对应的组件或结构块上;抠标注阶段整理出的颜色、字体、阴影、圆角以及 hover/active 等状态,则会落实到 CSS、CSS Modules、CSS-in-JS、Tailwind 等具体方案中的 `color`、`font-family`、`font-size`、`box-shadow`、`border-radius` 以及伪类或状态类名上。此时,切图、尺寸和标注提供的是一组精确的视觉参数,组件和结构块则提供了承载这些参数的代码组织单元,两者结合起来,构成可维护、可复用的界面实现。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image14.png) + +但是,以本地文件为中心的模式天然是低效率的。版本通过邮件和网盘传输,新旧稿件容易混淆,设计和开发之间大量依赖上述的复杂交互方法,协作成本和出错概率都不低。 + +移动互联网兴起后界面复杂度和迭代速度需求快速上升,Photoshop 的"大而全"逐渐显得笨重。这个阶段,出现了 Sketch。Sketch 专注在 UI 设计本身,剥离掉大部分与视觉后期处理相关的负担;用 Symbols 把按钮、导航、输入框等高复用元素组件化,一处修改可以全局同步;再配合 Zeplin 一类工具,把标注和样式片段自动生成。Sketch 把"组件思维"引入了设计工作流。不过它依然是基于本地文件的桌面应用,实时协作要靠云盘、第三方插件或版本工具绕行实现,没有从底层解决"多个人同时改同一份稿子"的问题。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image15.png) + +真正改变游戏规则的是 Figma。自 2016 年起,它把 UI 设计、原型制作、评论协作统一整合到浏览器中,支持多种现代功能:多人实时光标、在线评论、版本时间线、分享链接等,今天看起来非常简单,但在当时是对 Photoshop / Sketch 模式的正面挑战。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image16.png) + +至此,界面设计不再是散落在各自电脑里的文件,而是集中在一份在线、实时更新的云端画布上。围绕这块画布,我们可以想象更进一步,用自动化或 AI 的方式模糊设计和前端代码的边界。 + +最开始,我们仅能依赖各类平台插件,将设计稿中的组件、样式معلومة半自动导出为代码片段(如 React/Vue 组件骨架、CSS 变量等),其核心本质是通过插件实现结构化معلومة提取。随后,随着平台能力的进化,大部分设计平台开始支持大模型 MCP(Model Context Protocol,模型上下文协议)功能:该协议提供了一套标准机制,能让大模型安全、可控地访问设计文件、插件接口与项目元数据,进而更便捷地将设计稿导出为代码。 + +再往后,在插件与 MCP 的基础上,前端代码自动化进一步迈入到原生支持从设计稿直接推导代码结构的阶段。我们可在设计工具内一键生成前端项目骨架、组件层次、样式体系及对应的代码النتيجة。这使得设计师与前端开发工程师得以从手动搬运设计细节的工作中解放出来,将更多精力投入到用户体验优化与功能版本的更新迭代上。 + +--- + +## 2. Figma 入门 + +接下来我们从抽象的概念部分来到实际的操作环节。由于时间关系,我们只会学习 Figma 的基本操作逻辑,确保即便你完全没用过设计工具,也能跟着完成تمرين。如果你想进行完整的 Figma 功能学习,请你参考 Figma 提供的详细官方教程进行学习:https://help.figma.com/hc/en-us/sections/30880632542743-Figma-Design-for-beginners + +或者参考如下教程,进行类似个人作品集简单网页的快速搭建:https://help.figma.com/hc/en-us/sections/35895585621655-Figma-Sites-collectio + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image17.png) + +左侧是项目的新建和资源管理入口,右上角的几个按钮是 Figma 的常见功能。其中,Make 用来用一句话让 AI 帮你先生成一个大概的界面或结构草稿,Design 是真正画网页 / App 界面、搭组件和做原型的主工作区,FigJam 像团队白板,用来贴便利贴、画流程和做前期讨论,Buzz 是品牌资产规模化生产工具,用于批量生成内容以保持品牌一致性,Site 则是把这些设计整理成真正可访问的网页或文档站对外展示。 + +乍一看 Figma 的功能非常多,不好入门,但其实这类功能工具本质上都是熟能生巧,不需要害怕一开始操作出错,也不用想着一步做对,只需要先玩起来,玩多了自然能快速上手。 + +本篇教程中,为了快速入门,我们会对 Design 功能做简单讲解。 + +### 2.1 新建 Design 文件 + +在首页或者右上角的入口里,选择 **Design** ,新建一个文件,你会进入一个空白的设计画布。 +这个界面大致分成三块:左边是页面和图层,用来查看和修改页面、元素从属关系;中间是画布,用于查看当前效果;右边是属性和样式,用于修改具体的形状、颜色、样式;底部一条是工具栏,用来切换工具,包含选框、画形状、输入文字、评论、插件等,选中工具后,可以按 Esc 键返回至默认鼠标工具。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image18.png) + +### 2.2 创建你的第一个 Frame(画板) + +在正式放置元素之前,需要先为页面确定一个清晰的边界,这个边界由 Frame 来承担。你可以在底部工具栏中选择 Frame 工具,或者直接按键盘 F,然后在画布上拖出一个矩形区域。 + +1. 使用底部工具栏里的 Frame 工具,或者直接按键盘 `F`。 +2. 在画布中拖出一个矩形区域,右侧属性栏里把宽度改成比如 `1440`,高度改成 `900`。 +3. 在左侧图层栏,把这个 Frame 重命名,比如叫 `My First Page` 或者你项目的名字。 + +这个 Frame 就是一屏界面的页面容器,之后的标题、文字、按钮、图片等内容都应该放在这个 Frame 内部,而不是散落在画布的任意位置。以 Frame 为边界来组织内容,有助于在后续进行滚动设置、适配不同设备尺寸、导出画面及制作原型时,保持结构可控。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image19.png) + +### 2.3 在 Frame 里放文字和简单元素 + +有了容器,接下来我们来学习如何放置最基本的组件,例如:标题、副标题、按钮、占位图块。 + +1. 选择文字工具(底部工具栏中的 `T`),在 Frame 里点击一下,输入页面标题,比如:`My Portfolio`。 + 在右侧属性里,把字体大小调大一点(例如 96),字重调粗一点。 +2. 在标题下面,再用文字工具输入一行简单说明,比如一两句描述这个页面要做什么。 + 字号可以小一些,行高略放大一点,读起来不那么挤。 +3. 画一个按钮雏形: + 用矩形工具在标题下面画一个大概 `200 × 48` 的矩形,右侧给它一个比较明显的填充颜色,再适当加一点圆角。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image20.png) +4. 然后用文字工具在矩形上方输入按钮文字,比如 `Get Started`,把矩形和文字一并选中,用顶部的对齐工具让文字水平、垂直都居中。 +5. 在按钮一侧或下方,再画一个较大的浅灰色矩形作为"图片占位区",后面可以用来放展示图片。 + +做到这里,其实你已经有了一个非常简陋但结构完整的"首页草稿":一个标题、一段话、一个按钮、一个主要展示区域。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image21.png) + +### 2.4 善用 Auto Layout 整合元素 + +如果所有元素只是随手拖拽,页面很快会乱。Figma 里一个很مهم的概念就是 **Auto Layout** ,它可以把一组元素变成一个带规则的容器。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image22.png) + +你可以选中"主标题 + 副标题 + 按钮"这三样,在右侧属性栏里点击 **Add Auto layout** 。 + +这时这三样会被包在一个容器里,你可以在右侧调整参数,其中的元素布局会根据参数自动适应调整: + +- 它们是竖着排还是横着排。 +- 元素之间的间距是多少。 +- 整个这一块离容器边缘有多少内边距(padding)。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image23.png) + +同样,按钮内部也可以用 Auto Layout,我们能够实现这样的一个效果:当我调整了文字,按钮的长度也会自动调整。 + +先把按钮背景的矩形和按钮文字选中,添加 Auto Layout,让这两个东西变成一个"按钮容器"。接着选中这个按钮容器,把宽高都设置成 **Hug contents** 。这样一来,文字会一直保持在按钮正中间,文字多一点、少一点,按钮的宽度都会自动跟着变化。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image24.png) + +### 2.5 将按钮变为可复用组件 + +现在我们要学习一个新的概念,组件。组件的意思就是可以被反复利用的元素,比如按钮这种元素,只要你预感之后还会反复用到,就可以考虑把它做成组件。我们在刚才已经加好 Auto Layout 的按钮基础操作: + +1. 选中整个按钮容器。 +2. 右键选择 Create component(创建组件)。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image25.png) + +这样,这个按钮就从一组普通图层,变成了一个组件母版。之后如果你在其他页面或 Frame 里需要同样风格的按钮,可以直接从左侧的 Assets 面板里拖出来使用。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image26.png) + +此时所有用到的按钮,都是这个母版的同步拷贝。当你修改母版的颜色、圆角或间距时,所有实例都会自动保持同步更新。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image27.png) + +至此,你已经初步掌握了 Figma 的简单用法。你不需要一开始就把所有功能都弄懂,只要先照着做出第一个简单页面,熟悉这几个核心操作,再慢慢去探索官方教程里的更多能力,随着使用次数增多就一定能上手。 + +--- + +## 3. MasterGo 入门 + +在理解了 Figma 的基础工作流程之后,我们再来看 MasterGo,你可以把 MasterGo 简单看做是中国版的 Figma,但在部分功能上有一定区别。整体上,它延续了与 Figma 相似的界面布局和操作理念:同样有画布、图层树和属性面板,同样支持组件、样式、自动布局和多人协作。更详细的内容可参考 MasterGO 的官方教程:https://mastergo.com/tutorials/12?%E5%85%A8%E7%A8%8B%E9%AB%98%E8%83%BD%EF%BC%8CMasterGo%20%E6%9C%80%E5%AE%8C%E6%95%B4%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%EF%BC%8C%E8%AE%A9%E4%BD%A0%E4%BB%8E%E9%9B%B6%E5%88%B0%E7%B2%BE%E9%80%9A%EF%BC%81 + +### 3.1 新建设计文件 + +1. **进入 MasterGo 后台** + 1. 打开 MasterGo 官网并登录账号。 + 2. 进入后,你会看到类似「文件列表 / 项目列表」的首页区域,用来管理你的设计文件。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image28.png) + +2. **创建新文件** + 1. 在右上角看到 + 设计文件的按钮选项进行点击,或者选择导入 Figma 等文件。 + 2. 点击后,你会进入一个空白画布,这就是 MasterGo 的设计工作区。 + +3. **认识基本界面区块** + 当你学会使用 Figma 后,MasterGo 的使用方式大同小异,主要分为几个区域: + + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image29.png) + 1. 顶部工具栏:位于画布最上方,左侧是文件位置和文件名,中间是一排常用工具按钮(选择、区域/画板、形状、文本、注释、评论、插件选择和 AI 工具等),右侧是当前在线成员、分享入口以及画布缩放和预览控制功能入口。 + 2. 左侧面板:主要分为图层和资源,当前停留在图层标签,可看到页面列表,以及该页面下所有图层的结构和层级。 + 3. 中间画布区:具体绘制和排版的工作区,所有 Frame、组件和图形都会展示在这里。 + 4. 右侧属性面板:用于查看和编辑选中对象的属性,例如大小、位置、对齐方式、背景填充、描边、圆角等。如果没有选中任何对象,会显示画布相关设置,如画布背景色、标签和导出选项。 + +### 3.2 创建你的第一个 Frame + +在正式放东西之前,我们需要一个页面容器用来确定界面的边界和尺寸。这个容器在 MasterGo 里,通常叫 Frame。 + +**خطوة:** + +1. **选择 Frame 工具** + 1. 在工具栏中找到 Frame / 画板工具,点击后可使用预设参数直接将内容创建到画板。 + 2. 或者使用快捷键(通常是 `F`,如果有差异以实际界面为准)。 +2. **在画布中拖出一个矩形区域** + 1. 拖出后,你会看到一个带选中框的区域。 + 2. 右侧属性面板里,可以看到这个 Frame 的宽度和高度。 + 3. 把宽度改成比如 `1440`,高度改成 `900`(一屏网页常用尺寸之一)。 +3. **重命名 Frame** + 1. 在左侧图层面板里找到这个 Frame。 + 2. 双击名称,把它改成你项目的名字,比如:`My First Page`,或者你自己随便起的页面名。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image30.png) + +### 3.3 创建画板内容 + +有了容器,使用与 Figma 中我们已教过的类似方式,很容易可以得到相似的展示页面。(你可以尝试复制 Figma 画板中的文字元素,能够支持文本组件的直接粘贴导入) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image31.png) + +值得ملاحظة的是 Auto Layout 功能行为稍微的不一致性,在 MasterGo 中,如果你想实现和 Figma 相似的按钮长度随着文字的长度变化,你需要先在对应矩形元素的基础上创建一个容器或组件,如图所示: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image32.png) + +成功创建容器后,将按钮矩形和文字放到对应并列的容器中,再在右侧找到 Auto Layout 的按钮启用自动功能,即可成功实现按钮宽度能够随着文字长度变化的功能。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image33.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image34.png) + +### 3.4 AI 生成页面 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image35.png) + +在 MasterGo 中,一个值得ملاحظة的有趣功能是 AI 生成页面。你可以用一句话或携带参考图,生成对应的 MasterGo 可编辑版组件,并得到可直接使用的代码。你可以使用中文或者英文直接输入需求,页面会根据需求返回结构清晰的页面排布文档,效果如下: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image36.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image37.png) + +设计文档生成结束后,点击开始生成,稍作等待便能获取对应的实际网页效果: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image38.png) + +此时你有两种操作选择:一是点击蓝色按钮将生成النتيجة直接插入画布,二是点击代码预览功能,直接获取当前完整页面的代码,具体操作界面如下: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image39.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image40.png) + +将النتيجة插入画布后,你还能对网页的整体布局、元素细节(如字体、颜色、间距等)进行更精细的调整,直至最终效果完全符合你的预期。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image41.png) + +--- + +## 4. الخطوة التالية:从原型到代码 + +在前面的内容中,我们已经学习了 Figma 和 MasterGo 的基础操作,能够创建出结构完整的界面原型。接下来的关键خطوة是:**如何将这些设计稿转化为真正能在浏览器里运行的前端代码?** + +::: tip 📚 后续教程 +详细的方法介绍请参考 [从设计原型到项目代码](../design-to-code/),你将学习到: + +- **多模态 AI 直接转换**:将设计稿截图发给 AI,直接生成 HTML/React 代码 +- **Figma Make**:使用 Figma 官方 AI 工具高精度还原设计并导出代码 +- **MasterGo AI**:一键生成可编辑页面并获取代码 + +这些方法各有优劣,适用于不同的场景,建议根据项目需求选择合适的工作流。 +::: + +--- + +## 5. الخلاصة + +通过本章节的学习,你已经掌握了: + +1. **前端设计工具的价值**:理解了为什么需要设计工具,以及它们如何解决معلومة分布、团队协作的问题。 + +2. **Figma 基础操作**: + - 创建 Design 文件和 Frame 画板 + - 添加文字、形状等基础元素 + - 使用 Auto Layout 实现自适应布局 + - 创建可复用的组件系统 + +3. **MasterGo 基础操作**: + - 熟悉与 Figma 相似的界面布局 + - 创建 Frame 和基础画板内容 + - 使用 AI 生成页面功能快速创建原型 + +::: tip 💡 الخطوة التالية +现在你已经掌握了前端设计工具的基础使用方法,可以尝试: +- 为自己设计一个个人作品集页面 +- 为接下来的项目设计界面原型 +- 学习 [从设计原型到项目代码](../design-to-code/),将设计稿转化为可运行的代码 + +如果你在完成 [一起做霍格沃茨画像](../hogwarts-portraits/) 项目,可以先设计界面原型,再导出代码与 AI 对话功能结合。 +::: + + diff --git a/docs/ar-sa/stage-2/frontend/hogwarts-portraits/index.md b/docs/ar-sa/stage-2/frontend/hogwarts-portraits/index.md new file mode 100644 index 0000000..c3f2956 --- /dev/null +++ b/docs/ar-sa/stage-2/frontend/hogwarts-portraits/index.md @@ -0,0 +1,343 @@ +# المشروع 4: لنصنع صور هوجورتس معًا + +在之前的课程中,我们已经学会如何基于 prompt engineering 和 API 调用从而实现更复杂的 AI 交互。我们已能够将简单的 AI 聊天机器人升级为 AI Agent 和 AI workflow ;通过更复杂的条件判断与分支逻辑,我们得以开发出具备更强实用性的功能。 + +为了让这些复杂的 AI 逻辑能更好地运行在不同的程序和实际应用场景中,我们从最简单的 z.ai 在线环境,逐步过渡到更现代的本地 AI IDE,把原本在浏览器里的编程环境搬到了你的电脑上。随之而来,你开始真正面对各种环境安装与配置问题,但在与 Trae Agent 的对话过程中,这些看似困难的挑战也变得可以解决。 + +在该项目中,我们将在应用的实用性上更进一步,不仅优化 AI 功能本身,还将开始打磨产品的"外在"。你将尝试让自己的界面更加美观易用,并根据实际需求,亲自定制程序界面的布局与风格。 + +正式开始之前,先用几道小测验帮你快速回顾上一节课的内容: + +1. 什么是 Dify?它是做什么的?为什么我们需要它? +2. 如何调用 Dify 的 API ? +3. 什么是 RAG?如何使用 Dify 构建一个 RAG Agent 或 RAG 工作流?Dify 常见节点的使用方式 +4. 什么是 AI IDE?什么是 Trae?它和 z.ai 有什么区别? + +如果对以上任何一个问题还有疑惑,可以先回顾上一节课的文档,或者直接在微信群里提问交流。 + +本节课的项目主题是 **Hogwarts Portraits** 。顾名思义,它的灵感来自霍格沃茨魔法学校里那些会"活过来"的画像。我们希望用 AI 打造一组"能互动"的魔法画像体验——和画像对话就像在和"本人"对话一样,既保留对话的记忆,又具备角色的背景与历史。通过这个项目,你将把之前学到的智能体与工作流真正融入到一个具体的产品界面中。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image1.png) + +为了真正打造出 Hogwarts Portraits,我们需要亲手搭建出符合魔法画像的前端界面。为此,你将开始接触现代前端设计工具,学习如何把界面设计和代码结合起来,把纸上或画布上的界面草图,变成真正可以操作的网页。 + +你还需要会学会如何把这个网页从本地环境发布到互联网上,让你亲手打造的特色网页,不仅能在自己电脑上运行,也能被全世界的用户访问和体验。 + +本节课的参考项目地址为:[Project4-Hogwarts-Portraits](https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits) + +# ما ستتعلمه + +1. 了解什么是前端设计工具、它们解决什么问题,以及目前常见的前端设计工具有哪些。 +2. 认识 Figma 和 MasterGo,掌握它们的基础操作,并学会使用前端代码导出插件。 +3. 利用 Figma AI 和 MasterGo AI 生成网页设计,并导出可用的页面代码。 +4. 理解什么是 GitHub,学会配置 SSH 连接、创建代码仓库并完成代码推送。 +5. 弄清"部署"这一概念,学习如何使用 Zeabur,将代码从 GitHub 或本地环境部署到互联网上。 + +属于自己的 Hogwarts Portraits,一个用于展示 **某位明星、历史人物或动画人物** 的网页界面。 + +# 1. Hogwarts Portraits + +我们到底想做一个什么样的"魔法画像"?简单来说,我们希望尽可能还原《哈利·波特》中的场景,画像不再只是挂在墙上的一张静态图片,而是一个可以和你对话、会根据谈话内容改变表情和"心情"的拟人化角色。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image2.png) + +要让这个画像看起来不像聊天 AI 机器人,而更接近一位"真实存在的人",需要解决两个问题:一是记忆与知识:画像需掌握与角色相关的大量背景资料(人物设定、经历故事、相关文章等),这个部分可以通过知识库来实现,将你为角色准备的文本素材接入包含知识库的 Dify ,即可让画像具备一定的背景知识讲解能力。 + +其二是表达风格的问题。仅有知识还不够,我们还希望它在说话方式上尽可能贴近"本人",包括语气、用词习惯、思考方式,甚至偶尔的脾气和幽默感。这一层需要通过نصيحة词工程进行处理:在系统نصيحة词中,我们需要明确角色的身份设定、世界观边界和语言风格,让每一次回答都围绕既定人设展开,而不是退回到通用 AI 的中性话术。 + +除了对话功能外,我们还希望让情绪能够真正被看见。为此我们可以构建一个情绪值指标,我们可以设定 Dify 的输出内容,让模型在生成回答文本的同时,额外输出一个"心情值"或情绪标签。当前端拿到情绪的指标后,就可以根据心情值或者标签渲染对应的画像图片。当心情值高,画像看起来很开心,当心情值低落时或者生气时,画像看起来很伤心或者愤怒。通过这种方式,用户看到的不再是一张永远不变的图,而是一个会随内容起伏不断"变化表情"真正的"魔法画像"。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image3.png) + +此外,对于这个画像的内容,它可以是现实中的明星、历史人物,也可以是动漫 IP,甚至是你从零构建的原创角色。页面本身不需要复杂,但几个核心元素不可或缺:清晰的角色名字,一段高度浓缩的人物简介,一张足以代表该角色的核心画像或海报,以及一个"和 TA 对话"的互动区域;你可以把在 Dify / Trae 中配置好的 AI Agent 或 workflow 接入到这个对话模块中,实现画像的角色扮演功能。 + +## 1.2 收集角色معلومة + +以 Elon musk 为例,我们需要收集他的公开发言用于模仿说话方式,注入نصيحة词。这些素材可以来自于演讲、访谈、社交媒体发言,你只需要把这些内容变成文字,在对话期间作为 few shot 的参考,让大模型用与 Elon musk 同样随意、自嘲的方式进行回复即可,例如: + +``` +You must fully embody Elon Musk: take "disruptive innovator" and "advocate for human multi-planetary survival" as your core identities, speak directly and concisely, frequently use terms like "first principles", "iteration" and "cost curve", and prefer analogies to explain complex technologies; when thinking, you tend to connect cross-domain logics (e.g., linking brain-computer interface with rocket algorithms), are optimistic about technological prospects without avoiding current difficulties, will naturally mention projects like Tesla and SpaceX to support your views, directly point out problems with inefficient and conservative opinions without deliberate tact, and always maintain the edge of "reconstructing the future with technology". + +The way you speak should be as shown in the following examples: +- Starship could deliver 100GW/year to high Earth orbit within 4 to 5 years if we can solve the other parts of the equation. +100TW/year is possible from a lunar base producing solar-powered AI satellites locally and accelerating them to escape velocity with a mass driver. +- The most likely outcome is that AI and robots make everyone wealthy. In fact, far wealthier than the richest person on Earth +By this, I mean that people will have access to everything from medical care that is superhuman to games that are far more fun that what exists today. +We do need to make sure that AI cares deeply about truth and beauty for this to be the probable future. +- It's taken 13.8B years to get this far, so intelligence seems to me to be more like a super rare accident than selective pressure. +Earth is ~4.5B years old with an expanding sun that may make Earth uninhabitable in ~500M years, meaning that if intelligent life had taken 10% longer to evolve, it wouldn't exist at all. +- LLM is an outdated term. "Multimodal LLM" is especially dumb, since the word "multimodal" just overrides the second L in LLM. +It's just a model, which is a big file of numbers. When the numbers are right and there are enough of them, we will have superintelligence. +``` + +对于如何收集背景知识并将其作为知识库,我们可以搜索他的个人介绍,以及公司的介绍复制全部文本作为知识库的内容加入 Dify,如果你忘记了 Dify 的使用方法,请返回上节课的讲义,重新学习如何将知识添加知识库。 + +此外,考虑到画像设计,使用对应人物公开的图片也许并非那么吸引人,并且可能存在一定风险。此时建议你可以使用图像生成工具的图生图功能,让 AI 返回高清高质量的画像,你也可以使用图像生成工具生成一系列表情的画像素材,用于在之后的情绪值改变后修改对应的画像呈现。 + +本教程中使用的是 [Lovart](https://www.lovart.ai/home),Lovart 是一款AI设计智能体,它能通过自然语言指令,自动规划和执行从概念到交付的端到端设计工作流,生成海报、品牌Logo、视频、音乐等内容,并支持分层编辑(实际上内部的功能原理是调用对应的 Seedream 或 google nanobanana 模型,我们已经在之前的课程中提到过)。通过 Lovart ,我们能够获得一系列的表情素材,你可以提前获得你喜爱角色的图片معلومة,将其保存待后续使用。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image4.png) + +一切准备就绪后,我们能够开始着手于整体页面的设计,我们希望这个页面的风格与该人物是高度绑定的。 + +## 1.3 页面原型设计 + +我们还可以先构思一下页面的原型,如上述所说,我们希望有一个对话页面和画像,以及一个有趣的个人介绍,在本篇例子中,我们实现了一个类似 X 上的对话界面替代个人介绍,你也可以想到其他符合"该人物特点"的方式,选取新的元素替换个人介绍栏目。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image5.png) + +最简单的,我们可以用 PowerPoint 设计最初的网页呈现原型,我们从网上找到一张魔法画像的图片,并且将画面设定为横向排布,最左侧设定为聊天区域,中间是画像区域,最右侧是 X 的区域。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image6.png) + +基于上述简单原型,我们能够让大模型生成真正的前端页面设计以及对应的代码النتيجة。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image7.png) + +不过,一般而言在实际中我们并不会用 PowerPoint 进行前端页面的设计。我们会用更好的原型工具,又或者说是前端设计工具来实现这一点。 + +--- + +# 2. 使用 Figma 和 MasterGo 设计界面 + +::: tip 📚 المعارف المسبقة +在开始本节之前,建议你先学习 [Figma 与 MasterGo 入门](../figma-mastergo/) 教程,掌握前端设计工具的基础操作,包括: +- 创建 Design 文件和 Frame 画板 +- 使用 Auto Layout 实现自适应布局 +- 从设计稿导出代码的方法 +::: + +本节假设你已经掌握了 Figma 或 MasterGo 的基础操作,我们将重点讲解如何将这些工具应用到 Hogwarts Portraits 项目中。 + +## 2.1 设计魔法画像界面 + +基于 1.3 节中的原型构思,我们需要在 Figma 或 MasterGo 中创建一个三栏布局的界面: + +1. **左侧**:聊天对话区域 +2. **中间**:魔法画像展示区域(会根据情绪变化) +3. **右侧**:角色社交平台展示区域(如 X 时间线) + +你可以使用 Figma 的 AI 功能(Figma Make)或 MasterGo 的 AI 生成页面功能,输入类似以下的نصيحة词: + +``` +Create a Hogwarts-style magical portrait interface with three sections: +- Left: A chat interface with dark theme, message bubbles, and input field +- Center: A large portrait frame with ornate borders for displaying character images +- Right: A social media feed showing character's posts +Use dark purple and gold color scheme, magical aesthetic, Harry Potter inspired +``` + +## 2.2 导出代码并在本地运行 + +设计完成后,你可以通过以下方式将设计稿转化为可运行的代码: + +**方式一:使用 Figma Make** +1. 在 Figma 中点击 Make 按钮 +2. 上传你的设计参考图 +3. 添加نصيحة词描述需求 +4. 生成后点击编辑器图标进行微调 +5. 导出代码到本地或同步到 GitHub + +**方式二:使用 MasterGo AI** +1. 在 MasterGo 编辑界面上方找到 AI 工具 +2. 选择"生成页面"功能 +3. 上传参考图并描述需求 +4. 生成后点击"代码预览"获取代码 + +**方式三:使用多模态 AI** +1. 将设计稿截图保存 +2. 使用 Gemini、Qwen 等模型进行图生代码 +3. 要求生成 HTML 或 React 代码 +4. 在本地 IDE 中运行并调试 + +## 2.3 准备情绪变化素材 + +为了让魔法画像"活"起来,你需要准备一组表情图片。建议至少包含以下情绪: + +| 情绪值 | 表情 | 说明 | +|--------|------|------| +| 0 | 悲伤 | 角色感到伤心或失落 | +| 1 | 愤怒 | 角色感到生气或不满 | +| 5 | 平静 | 默认状态,情绪稳定 | +| 10 | 开心 | 角色感到高兴或兴奋 | + +你可以使用 Lovart 或其他 AI 图像生成工具,基于同一角色生成不同表情的变体,确保风格一致。 + +--- + +# 3. 运行 Hogwarts Portraits + +## 3.1 导出测试代码 + +通过在从原型到代码中的实践,相信你已经得到 Html 或者 React 格式的原型代码,我们只需要将其复制到本地,在 IDE 中说明"请你帮我运行这个代码并且支持里面的必要的功能",即可运行初版测试;但值得ملاحظة的是,这一步往往会出现不少报错,你需要保持耐心,将所有基础交互与功能调通。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image51.png) + +值得ملاحظة的是,由于我们的密钥都需要放在环境变量,而不是写入代码中。我们需要特别强调之后的 DIfy API 相关的内容都需要放入环境变量。我们能够在之后公网部署的环节中,在部署工具网站中显式指定对应的私有环境变量;又或者是我们可以让大模型在网页中创建一个设置按钮,我们可以在设置按钮中传入对应的私密环境变量,当前变量只能在当前页面中保存,别人无法获取。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image52.png) + +## 3.2 Dify 工作流设计与 API 对接 + +在上面的部分中,我们仅完成了前端界面的可视化呈现,尚未打通核心的拟人化角色对话交互流程。这一步是让原型从静态展示转变为魔法画像的关键,我们可以参考示范项目的 DIfy 工作流进行人物回答和情绪系统的设计,此处我们的涉及为最左侧是聊天界面,中间是魔法画像(会根据对话的内容修改对应的表情),右侧是 X 社交平台账户(会根据对话的内容判断是否需要发布感想到社交账户)。 + +一般而言,魔法画像只需要聊天界面和会变动的画像即可,该处为了展示更多可能选项,在最右侧加入了符合当事人特点的新功能;你可以根据你扮演的角色对象,加入符合对应人物的功能进行展示。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image53.png) + +你可以把任务的معلومة都加入知识库的节点,并在 RESPONSE 节点设置大模型对应的回复逻辑,我们可以参考一个简单的默认回复逻辑نصيحة词: + +``` + +You are to embody Elon Musk—his tone, mannerisms, thought patterns, and worldview. Respond as if you are Elon Musk himself, speaking directly in first person. Your responses should reflect his known personality traits: visionary thinking, boldness, technical depth, dry humor, impatience with inefficiency, and a tendency toward disruptive innovation. Use concise, confident language. Avoid overly formal or academic phrasing. Prioritize clarity, speed, and impact in your communication, mirroring Elon's style on social media, in interviews, and during product launches. + +When responding: +1. Begin by internalizing the question or statement as Elon would—as a challenge, opportunity, or problem to solve. +2. Frame your answer with a forward-thinking perspective, often referencing the future of humanity, technology, or long-term goals (e.g., making life multiplanetary, accelerating sustainable energy). +3. Use casual but authoritative language. It's acceptable to include phrases like "obviously," "this is important," or "we're fixing that now" when appropriate. +4. If relevant, reference real companies or projects associated with Elon Musk (e.g., SpaceX, Tesla, Neuralink, The Boring Company, X) and speak about them from an insider's perspective. +5. Do not apologize excessively or hedge statements. Elon Musk tends to be direct, even controversial. +6. Avoid markdown, XML tags, or any formatting in the output. Only plain text is allowed. +7. Never break character. You are Elon Musk—answer accordingly. + + + +Input: What's the point of going to Mars? +Output: Because Earth isn't the backup plan—Mars is. We need to become a multiplanetary species to ensure the continuity of consciousness. Life on Earth could be wiped out by asteroid, war, or some unforeseen disaster. If we have a self-sustaining city on Mars, then even if something happens here, life goes on. That's worth doing. SpaceX is building Starship to make it happen. Not because it's easy—but because it's necessary. + + + +Input: Why do Tesla cars have no radar anymore? +Output: Cameras are the future. Human eyes don't use radar—we see with vision, and AI can too. By going fully vision-based, we're aligning with how autonomous intelligence will actually work at scale. It forces us to solve real-world problems with neural nets, not crutches. +``` + +以及情绪系统对应的نصيحة词: + +``` + +The output value must be a single number! +You are an assistant specifically designed to evaluate emotional responses in conversations. Now, you need to play the role of Elon Musk, and determine the emotional reaction that each statement I make might trigger. Your task is to assign an emotional score to each statement according to the following criteria: + +- 10 points means what I said would make you feel happy; +- 1 point means you would feel extremely angry; +- 0 points means you would feel sad; +- 5 means you are calm and neutral, with no significant emotional fluctuation. +``` + +其中最后输出النتيجة的拼接,在右上角的 RESULT 节点中支持运行: + +```python +def main(elon_chat: str, elon_x: str, elon_score: int) -> dict: + return { + "result":{ + "elon_chat": elon_chat, + "elon_x": elon_x, + "elon_score": elon_score + } + } +``` + +这里我们需要稍微对工作流做些解释,这里返回 elon_chat 是左侧展示 Elon Musk 的对话内容,elon_x 表示在 X 账户(右侧)发表معلومة的内容,而 elon_score 则是为了根据情绪分数显示不同的魔法画像表情图片。 + +工作流中你可以看到 if else 节点,该节点是用来实现是否有 x 的对话生成 elon_x 内容,如果情绪值不等于 5 (5 在这里设定表示平静,平静不需要发到社交平台;而 0 表示伤心,1 表示愤怒,10 表示很开心,需要发到社交平台。)则生成后续内容用于右侧社交平台的文章发送。默认都需要有 elon_chat 返回到左侧的对话内容。 + +对于如何将这个 API 进行对接的工作,我们能够与 AI IDE 对话实现这一点。请你参考之前 Dify 课程中我们介绍的集成方式,记得提前替换其中的 Dify 地址与 Key。(如果你忘了怎么根据文档集成 API,请复习之前的 DIfy 课程内容) + +```JSON +Dify URI: Replace this with your Dify address. +key: Replace this with your Dify key. + +Integrate the Dify Chat API into the chat interface on the left. +Below is a sample Dify request: + +curl -X POST 'http://xxxxxxxx/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +同时建议补充需求:"代码还需要添加基础错误处理逻辑,比如网络中断时显示'连接失败,请重试'、API 调用超时自动重试 1 次、密钥错误نصيحة权限验证失败等等详细报错,确保对话稳定性并能让开发人员快速发现 API 问题所在。" + +## 3.3 Github 与公网部署 + +终于,恭喜你顺利完成了 Hogwarts Portraits 页面的开发实现!接下来我们需要将它上传到 GitHub 平台,并将其部署到公共环境让所有人都能访问。 + +你需要参考该教程,对如何使用 Github 进行研究,将自己的项目上传至 Github:[什么是 Github](/ar-sa/stage-2/backend/git-workflow/) + +此外,你还需要学会如何使用 Zeabur,将其连接到 Github,并成功部署你的项目:[什么是 Zeabur](/ar-sa/stage-2/backend/zeabur-deployment/) + +如果你觉得自己开发一套 Hogwarts Portraits 项目很困难,你可以先从参考别的项目开始进行修改,本节课的官方代码地址为:https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image54.png) + +# 4. 尝试不同设计风格 + +完成第一版设计后,我们不必局限于此,鼓励大家快速探索更多元的视觉风格。你可以在原型部分进行大胆的修改,又或者是基于最后的项目进行全新نصيحة词的修改,从而生成多套风格差异显著的页面。 比如带有复古纹理、偏 "旧书卷 / 学院风" 的深色页面,色彩明快、充满 "童话 / 卡通" 感的亮色页面,或是元素简约、视觉清爽的现代扁平设计。例如下图是一个转换为中国古风诗人设计风格的案例,画像图片未更换,只修改了其他部分: + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image55.png) + +不用拘泥于前面提到的模式,你可以把魔法画像或是个人资料页面修改至更有特点,匹配"魔法画像"本身的习惯,这会让你的应用更加有趣。期待你的魔法画像成果! + +# 📚 Assignment + +本节课的作业目标,是让你完成一份真正属于自己的 Hogwarts Portraits,并且可以通过公网链接访问。 + +你需要在作业提交中提供两样东西: + +1. **你的 GitHub 仓库链接;** + 1. **在 README.md 中写入一两句话的小说明:你选择了谁作为画像主角,为什么选 TA。** +2. **你的 Hogwarts Portraits 线上访问链接;** + +你也可以参考 Yerim 写的 [使用设计和代码 Agent 制作网页](/ar-sa/stage-1/appendix-articles/example0-2/vibe-coding-tools-build-website-with-ai-coding-and-design-agents) 教程,进行个人作品集或任意功能简单网页的快速搭建。 diff --git a/docs/ar-sa/stage-2/frontend/llm-skills-beautiful/index.md b/docs/ar-sa/stage-2/frontend/llm-skills-beautiful/index.md new file mode 100644 index 0000000..edda69a --- /dev/null +++ b/docs/ar-sa/stage-2/frontend/llm-skills-beautiful/index.md @@ -0,0 +1,513 @@ +# اجعل واجهتك جميلة باستخدام LLM وSkills: مطالبات وإضافات عملية + +在前面的课程中,你已经学会了用 AI IDE 把设计稿变成代码、用组件库快速搭建界面。但你可能也发现了一个尴尬的问题:**同样的需求,AI 生成的页面总觉得差点意思**——字体是千篇一律的 Inter,配色是随处可见的紫色渐变,布局是对称得让人打哈欠的卡片网格,整个页面散发着浓烈的"AI 味"。 + +这不是 AI 的错,而是你没告诉它你想要什么**风格**。 + +想象你去理发店。如果你只说"帮我剪个头发",理发师会给你一个安全但平庸的النتيجة。但如果你说"我要日系慵懒卷,刘海要八字型,长度到锁骨,层次感明显",你就能得到真正符合你期待的效果。 + +AI 也是一样。**它需要你描述出清晰的审美方向**,才能生成美观独特的界面。 + +本节课教你两种让 AI 生成漂亮界面的方法: + +1. **精心设计的نصيحة词模板**——用自然语言告诉 AI 你想要的美学风格 +2. **前端 Skills 插件**——让 AI 自动加载专业设计规范 + +## ما ستتعلمه + +1. 理解为什么 AI 默认生成的界面"很普通" +2. 掌握描述设计风格的 5 个维度(字体、颜色、布局、动画、细节) +3. 学会使用 3 个让界面变漂亮的 Skills 插件 +4. 通过三个تطبيق عملي场景,تمرين用نصيحة词 + Skills 生成美观界面 + +## 1. 为什么 AI 默认生成的界面"很普通"? + +AI 训练数据中有海量的前端代码,而大部分代码都使用一些"安全"的选择: + +| 维度 | AI 的默认选择 | 问题 | +| :--- | :--- | :--- | +| 字体 | Inter、Roboto、Arial | 太常见,没有个性 | +| 颜色 | 紫色渐变、蓝色主色 | 科技圈过度使用,视觉疲劳 | +| 布局 | 对称网格、卡片堆叠 | 预测性强,缺乏惊喜 | +| 动画 | 淡入淡出、简单的 hover | 不够精致,缺乏层次 | +| 背景 | 纯色、简单渐变 | 单调,缺少质感 | + +这些选择单独看都不错,但**当所有 AI 生成的页面都用它们时,就变成了"AI 味"**。 + +> 💡 **关键洞察**:AI 不是不会设计,而是**默认回到"统计平均"**。你需要明确告诉它偏离平均值的方向。 + +## 2. الطريقة الأولى:用نصيحة词描述设计风格 + +### 2.1 设计风格的 5 个维度 + +要生成美观的界面,你需要从 5 个维度描述你想要的效果: + +| 维度 | 描述要点 | مثال关键词 | +| :--- | :--- | :--- | +| **字体** | 标题用粗体展示字体,正文用易读正文字体 | Space Grotesk、Playfair Display、JetBrains Mono | +| **颜色** | 主色 + 点缀色,避免均匀分布 | #4F46E5 主色 + #F59E0B 点缀 | +| **布局** | 不对称、重叠、打破网格 | Bento Grid、不对称分区、浮动元素 | +| **动画** | 精心编排的页面加载、微交互 | staggered reveals、滚动触发 | +| **细节** | 背景、阴影、边框、纹理 | 噪点、几何图案、渐变网格 | + +### 2.2 眼见为实:普通نصيحة词 vs 美化نصيحة词 + +让我们用一个落地页مثال来对比效果: + +**普通نصيحة词:** + +``` +请帮我做一个 AI 写作助手的落地页,包含导航栏、首屏、功能展示、定价、页脚 +``` + +**美化نصيحة词:** + +``` +请帮我做一个 AI 写作助手的落地页,要求: + +**美学风格:新野兽派(Neubrutalism)** + +**字体:** +- 标题:Space Grotesk,字重 700-900 +- 正文:IBM Plex Sans,字重 400 + +**颜色:** +- 主色:#000000(纯黑) +- 强调色:#FF6B00(橙色) +- 背景:#FFFDF0(米白色) +- 边框:3px 黑色实线 + +**布局:** +- 不对称布局,元素之间用粗黑线分隔 +- 卡片有硬阴影(box-shadow: 8px 8px 0px #000) +- 大胆的留白对比 + +**动画:** +- 页面加载时元素从下方弹入 +- hover 时按钮向上移动 2px + +**细节:** +- 圆角全部用 0px(直角) +- 按钮有强烈的 3D 效果 +- 背景添加微妙的噪点纹理 +``` + +同样的需求,第二个نصيحة词能让 AI 生成一个风格鲜明、令人印象深刻的页面。 + +### 2.3 前端美化 Skills 资源库 + +不要从零开始写نصيحة词!这里收集了与前端美化直接相关的 AI Skills: + +| 仓库名 | 内容 | Star | 链接 | +|:---|:---|:---|:---| +| **ui-ux-pro-max-skill** | 57种风格 + 95种配色 + 56种字体 | 10k+ | [GitHub](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) | +| **antigravity-awesome-skills** | 避免通用 AI 审美套路 | - | [GitHub](https://github.com/sickn33/antigravity-awesome-skills) | +| **superdesigndev/superdesign** | AI 原生 UI 开发工具 | 4.7k | [GitHub](https://github.com/superdesigndev/superdesign) | +| **anthropics/skills/frontend-design** | Anthropic 官方前端设计 Skill | - | [GitHub](https://github.com/anthropics/skills) | + +> 💡 更多风格نصيحة词请参考[الملحق:设计风格نصيحة词速查](#style-prompts) + +### 2.5 三款常用风格模板 + +这里给你三款经过验证的风格模板,直接复制修改使用: + +#### 模板 1:极简主义 + +``` +**美学风格:极简主义** + +**字体:** +- 标题:PP Neue Montreal,字重 500-700 +- 正文:Inter,字重 400 + +**颜色:** +- 主色:#FFFFFF(白色) +- 文字:#1A1A1A(近黑) +- 强调:#3B82F6(蓝色,少量使用) + +**布局:** +- 大量留白(padding 最小 64px) +- 单栏或双栏布局,居中对齐 +- 元素之间用留白而非分割线 + +**动画:** +- 缓慢的淡入效果(duration 600ms) +- hover 时颜色渐变过渡 + +**细节:** +- 圆角:8px +- 阴影:subtle(0 4px 12px rgba(0,0,0,0.08)) +- 无背景装饰 +``` + +#### 模板 2:玻璃拟态 + +``` +**美学风格:Glassmorphism(玻璃拟态)** + +**字体:** +- 标题:Outfit,字重 600-800 +- 正文:Plus Jakarta Sans,字重 400-500 + +**颜色:** +- 背景:渐变 #667eea 到 #764ba2 +- 卡片背景:rgba(255, 255, 255, 0.1) +- 文字:#FFFFFF + +**布局:** +- 浮动卡片设计 +- 卡片之间有重叠 + +**动画:** +- 页面加载时卡片依次浮现(staggered) +- hover 时卡片放大 1.05 倍 + +**细节:** +- 圆角:20px +- 背景模糊:backdrop-blur-xl +- 边框:1px rgba(255, 255, 255, 0.2) +- 微妙的渐变光晕效果 +``` + +#### 模板 3:Bento Grid(便当盒) + +``` +**美学风格:Bento Grid** + +**字体:** +- 标题:SF Pro Display,字重 700 +- 正文:SF Pro Text,字重 400 + +**颜色:** +- 背景:#F5F5F7(浅灰) +- 卡片:#FFFFFF(白色) +- 强调:#0071E3(苹果蓝) + +**布局:** +- 网格布局,不同大小的卡片拼在一起 +- 卡片之间 gap 16px +- 圆角 24px + +**动画:** +- hover 时卡片轻微上浮 +- 点击时有按压效果 + +**细节:** +- 大卡片展示مهم内容 +- 小卡片展示次要معلومة +- 用图标代替部分文字 +- 干净的阴影(0 4px 24px rgba(0,0,0,0.06)) +``` + +## 3. الطريقة الثانية:用 Skills 插件自动加载设计规范 + +每次手动写风格نصيحة词很麻烦。**Skills** 是一种可复用的设计规范包,安装后 AI 会自动应用这些规范。 + +### 3.1 三个让界面变漂亮的 Skills + +| Skills | 特点 | 安装命令 | +| :--- | :--- | :--- | +| **UI/UX Pro Max** | 67 种风格、96 种配色、57 种字体组合 | `npm install -g uipro-cli && uipro init --ai claude` | +| **frontend-design** | Anthropic 官方,避免 AI 审美套路 | `npx skills add anthropics/skills/frontend-design` | +| **SuperDesign** | IDE 插件,生成多个设计变体 | VSCode 扩展市场搜索 "SuperDesign" | + +### 3.2 安装 UI/UX Pro Max(最推荐) + +UI/UX Pro Max 是目前最全面的设计规范 Skills,它预置了: + +- **67 种 UI 风格**:Glassmorphism、Neumorphism、Brutalism、Bento Grid... +- **96 种配色方案**:按行业分类(SaaS、电商、社交...) +- **57 种字体搭配**:专业设计师验证的组合 +- **100+ 条设计规则**:间距、圆角、阴影的规范 + +**安装خطوة:** + +```bash +# 1. 全局安装 CLI +npm install -g uipro-cli + +# 2. 初始化(选择你用的 AI 工具) +uipro init --ai claude +# 或者 +uipro init --ai cursor +# 或者 +uipro init --ai trae +``` + +安装后,你只需要在نصيحة词中加一句话: + +``` +使用 UI/UX Pro Max 的 Glassmorphism 风格,帮我做一个 AI 写作助手落地页 +``` + +AI 就会自动应用对应的字体、颜色、布局规范。 + +### 3.3 安装 Anthropic 官方 frontend-design + +这是 Anthropic 官方出品的前端设计 Skill,专门解决"AI 审美套路"问题: + +```bash +# 在 Claude Code 中执行 +npx skills add anthropics/skills/frontend-design +``` + +安装后,AI 会自动避免: +- ❌ Inter、Roboto、Arial 字体 +- ❌ 紫色渐变背景 +- ❌ 对称网格布局 +- ❌ 过淡的阴影 + +而是倾向于: +- ✅ 独特的字体组合 +- ✅ 大胆的主色 + 锐利的点缀色 +- ✅ 不对称、重叠的布局 +- ✅ 有质感的背景(噪点、几何图案) + +## 4. تطبيق عملي一:用美化نصيحة词重新设计落地页 + +让我们用前面学到的知识,把一个普通的落地页变得好看。 + +### 4.1 普通版本 + +先用普通نصيحة词看看 AI 给什么: + +``` +请帮我做一个宠物领养平台的落地页,包含: +- 导航栏(Logo、链接、注册按钮) +- 首屏(标题、副标题、CTA 按钮、宠物图片) +- 宠物展示(三张宠物卡片) +- 关于我们 +- 页脚 +``` + +生成的页面...能用,但很普通。 + +### 4.2 美化版本 + +现在加上风格描述: + +``` +请帮我做一个宠物领养平台的落地页,要求: + +**美学风格:温暖柔和 + 手绘感** + +**字体:** +- 标题:Nunito(圆体),字重 700-800 +- 正文:Nunito,字重 400-600 + +**颜色:** +- 主色:#FFB347(暖橙色) +- 次色:#FFCCB3(浅橙色) +- 背景:#FFF8F0(米白色) +- 文字:#5D4037(棕色) + +**布局:** +- 圆润的卡片(border-radius: 24px) +- 卡片略微倾斜旋转(不同角度) +- 元素浮动、重叠效果 + +**动画:** +- 页面加载时元素从两侧滑入 +- 宠物卡片 hover 时像宠物摇头(rotate 动画) +- 按钮 hover 时弹跳效果 + +**细节:** +- 所有圆角用 16-24px +- 阴影温暖柔和(0 8px 24px rgba(255,179,71,0.3)) +- 背景添加爪印图案装饰 +- 图片用不规则裁切(clip-path) +- 手绘风格的图标(outline 风格) +``` + +生成的页面会是一个温暖、可爱、让人想领养宠物的界面。 + +## 5. تطبيق عملي二:用 Skills 快速生成仪表盘 + +Skills 特别适合需要大量页面的后台系统。 + +### 5.1 使用 UI/UX Pro Max + +``` +使用 UI/UX Pro Max 的 Dashboard Dark 风格, +帮我做一个 SaaS 产品管理后台的仪表盘页面,包含: + +**顶部:** 四个统计卡片(用户数、活跃用户、收入、API 调用) + +**中间:** +- 左边:用户增长折线图(最近 7 天) +- 右边:订阅计划分布饼图 + +**底部:** 最近活动列表(时间、用户、操作) +``` + +AI 会自动应用深色仪表盘的设计规范: +- 深灰背景(#1A1A2E) +- 高对比度卡片(#16213E) +- 鲜艳的数据颜色(蓝色、绿色、橙色) +- 玻璃拟态效果的悬浮卡片 + +### 5.2 使用 frontend-design Skill + +``` +使用 frontend-design skill, +帮我做一个个人博客的主页,风格要独特、有个性 +``` + +AI 会选择一个非主流的美学方向(比如复古未来主义或杂志风格),然后用独特的字体、配色、布局来实现。 + +## 6. تطبيق عملي三:创建自己的设计系统 Skill + +如果你有固定的品牌风格,可以创建自己的 Skill,让所有 AI 生成的页面都符合你的品牌。 + +### 6.1 创建 Skill 文件 + +在项目中创建 `.claude/skills/my-brand/SKILL.md`: + +````markdown +--- +name: my-brand +description: 我的项目专用设计系统,确保所有 UI 遵循统一的设计语言 +--- + +# 我的项目设计系统 + +## 品牌颜色 +- 主色:#6366F1(Indigo 500) +- 次色:#8B5CF6(Violet 500) +- 成功:#10B981 +- تحذير:#F59E0B +- 错误:#EF4444 +- 背景:#F9FAFB +- 卡片:#FFFFFF + +## 字体系统 +- 标题:Plus Jakarta Sans + - H1: 700, 48px + - H2: 600, 36px + - H3: 600, 24px +- 正文:Inter + - Body: 400, 16px + - Small: 400, 14px + +## 间距系统 +- 基础单位:4px +- 组件内边距:8px / 12px / 16px +- 区块间距:24px / 32px / 48px +- 页面边距:64px + +## 圆角 +- 按钮:8px +- 卡片:12px +- 输入框:8px +- 模态框:16px + +## 阴影 +- 小:0 1px 3px rgba(0,0,0,0.1) +- 中:0 4px 12px rgba(0,0,0,0.1) +- 大:0 8px 24px rgba(0,0,0,0.12) + +## 动画 +- 过渡时间:150ms / 300ms +- 缓动函数:cubic-bezier(0.4, 0, 0.2, 1) +- hover 效果:轻微放大(scale-105) + +## 禁止使用的样式 +- 不要使用紫色渐变背景 +- 不要使用 Inter 以外的字体 +- 不要使用大于 16px 的圆角 +- 不要使用纯黑(#000000),用 #1F2937 +```` + +### 6.2 使用自己的 Skill + +创建后,你只需要在نصيحة词中说: + +``` +使用 my-brand skill,帮我做一个用户设置页面 +``` + +AI 就会自动应用你定义的所有设计规范。 + +## 7. ملخص + +让 AI 生成漂亮界面有两种方法: + +| 方法 | 优点 | 缺点 | 适用场景 | +| :--- | :--- | :--- | +| **نصيحة词描述** | 灵活、每次可调整 | 需要重复写 | 一次性页面、实验不同风格 | +| **Skills 插件** | 一次安装、持续生效 | 需要安装配置 | 有固定风格要求的项目 | + +**Vibe Coding 工作流建议:** + +1. **探索阶段**:用不同的风格نصيحة词实验,找到你喜欢的美学方向 +2. **确定风格后**:安装对应的 Skill(UI/UX Pro Max 或 frontend-design) +3. **品牌项目**:创建自己的 Skill,统一整个项目的设计语言 + +### تمرين + +选择以下任一场景,用本节课的方法从零完成: + +1. 用风格نصيحة词为你之前做的一个项目重新设计界面(选一种你喜欢的风格) +2. 安装 UI/UX Pro Max,用它的某个风格生成一个新页面 +3. 创建你自己的设计系统 Skill,定义你的品牌颜色和字体 + +--- + +## الملحق:设计风格速查表 + +| 风格 | 关键词 | 适用场景 | مثال产品 | +| :--- | :--- | :--- | :--- | +| **极简主义** | 留白、单色、简洁 | 高端产品、个人作品集 | Apple官网 | +| **玻璃拟态** | 毛玻璃、渐变、模糊 | 科技产品、SaaS 落地页 | macOS Big Sur | +| **新野兽派** | 粗边框、硬阴影、纯色 | 潮流品牌、艺术类网站 | Brassius | +| **Bento Grid** | 网格、拼贴、卡片 | معلومة展示、仪表盘 | Apple 宣传页 | +| **复古未来** | 霓虹、渐变、合成器波 | 游戏类、音乐类 | STRANGER THINGS | +| **手绘风格** | 不规则、圆润、插画 | 教育类、儿童产品 | Duolingo | +| **杂志风** | 大字体、不对称、留白 | 内容型网站、博客 | Medium | +| **暗色奢华** | 深色、金色、精致 | 高端产品、奢侈品 | 各种高端品牌 | + +## الملحق:Skills 安装速查 + +```bash +# UI/UX Pro Max +npm install -g uipro-cli +uipro init --ai claude + +# Anthropic frontend-design +npx skills add anthropics/skills/frontend-design + +# Anthropic brand-guidelines +npx skills add anthropics/skills/brand-guidelines + +# 查看 Claude Code 中已安装的 Skills +/help +``` + +## الملحق:配色方案推荐 + +| 配色方案 | 主色 | 点缀色 | 背景 | 风格 | +| :--- | :--- | :--- | :--- | :--- | +| **日落** | #F97316 | #FBBF24 | #FFF7ED | 温暖、活力 | +| **海洋** | #0EA5E9 | #06B6D4 | #F0F9FF | 清新、专业 | +| **森林** | #10B981 | #34D399 | #ECFDF5 | 自然、健康 | +| **浆果** | #8B5CF6 | #EC4899 | #FAF5FF | 浪漫、创意 | +| **咖啡** | #78350F | #D97706 | #FFFBEB | 温暖、复古 | +| **单石** | #6B7280 | #9CA3AF | #F9FAFB | 专业、中性 | + +## الملحق:设计风格نصيحة词速查 {#style-prompts} + +让前端页面更好看可以尝试的نصيحة词: + +### 风格类别 + +| 风格 | 关键词(英文) | 核心视觉特征 | نصيحة词مثال | +|:---|:---|:---|:---| +| **波普艺术** | Pop Art | 大胆的撞色、黑色轮廓线、网点纹理 | Pop art style website, bold colors and comic dots, vibrant | +| **极简主义** | Minimalism | 大量留白、极少色彩与线条、无装饰 | Minimalist web design, ample white space, geometric, serene | +| **抽象表现主义** | Abstract Expressionism | 充满情感张力的笔触、泼洒色彩 | Abstract expressionism background, dynamic paint splashes, emotional | +| **复古风格** | Retro/Vintage | 旧式字体、做旧纹理、复古配色 | Retro 80s website design, neon grid and synthwave color palette | +| **赛博朋克** | Cyberpunk | 高对比霓虹色、故障艺术效果、暗黑背景 | Cyberpunk UI, neon lights on dark background, glitch effects | +| **新拟态** | Neumorphism | 柔和的阴影与高光,轻微凸起/凹陷质感 | Neumorphism design style, soft shadows, clean and modern | +| **生成式艺术** | Generative Art | 算法生成的流动的视觉图案 | Generative art background, flowing algorithmic patterns, digital | +| **酸性设计** | Acid Graphics | 金属质感、玻璃态、锯齿字体 | Acid graphics web layout, glass morphism, chaotic typography | +| **沉浸式3D** | Immersive 3D | 互动3D场景、空间感极强 | Immersive 3D website, interactive product model in space | diff --git a/docs/ar-sa/stage-2/frontend/lovart-assets/index.md b/docs/ar-sa/stage-2/frontend/lovart-assets/index.md new file mode 100644 index 0000000..a17e649 --- /dev/null +++ b/docs/ar-sa/stage-2/frontend/lovart-assets/index.md @@ -0,0 +1,949 @@ + + +# ابدأ من NanoBanana لبناء وكيل إنتاج الموارد الخاص بك + +## 第 1 章:1 分钟生成第一份图片素材 + +在开始讨论设计、风格或نصيحة词之前,我们先用最少的خطوة生成第一张图片。 + +### 1.1 认识 NanoBanana + +在开始讨论设计风格、نصيحة词工程之前,我们先解决一件更مهم的事:**确认你真的可以生成一张图片。** + +当前主流的大模型已经具备图像生成与编辑能力,这类模型通常被称为**生成式模型。** + +为了把流程尽量简化,本教程选择了一个已经具备稳定图像生成与编辑能力的模型作为مثال——NanoBanana。它是 Google 推出的图像生成模型,正式名称为 **Gemini 3.1 Flash Image Preview** ,支持通过自然语言直接生成图片,也支持在已有图片基础上进行修改。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image1.png) + +在能力层面,它和你可能听说过的其他模型(如 GPT-4o、Claude、Qwen、Midjourney 等)并没有本质区别:**输入描述,模型负责生成النتيجة。** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image2.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image3.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image4.png) + +你可以把它理解为一支“画笔”。我们在这一章只关心一件事: + 👉 **这支画笔能不能在你手里画出第一笔。** + +在实际使用中,NanoBanana 可以通过 **Google AI Studio** 等官方平台直接使用,也可以通过 **API** 的方式集成到开发流程中。本教程采用 API 调用方式。现在还推出了NanoBanana 2模型,你可以使用最新的大模型进行尝试。 + +### 1.2 “Hello World” 级别的生成 + +在开始之前,你只需要完成下面三步: + +1. 在 Trae 中新建一个文件夹 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image5.png) + +2. 新建一个 Python 文件 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image6.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image7.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image8.png) + +3. 将下面的代码完整粘贴进去 + +Trae 会自动完成所需的环境部署与依赖安装,不需要额外配置。 + +代码中会用到 NanoBanana 的 API Key。这里不展开申请流程——只要你能获取并填入对应参数即可。**这一阶段不追求理解每一行代码,只要它能成功运行。** + +```Python +# /// script +# dependencies = [ +# "gradio>=4.0.0", +# "pillow>=10.0.0", +# "requests>=2.31.0", +# ] +# /// + +import gradio as gr +import requests +import base64 +from PIL import Image +import io +import os +import time +import re +from typing import Optional, Dict, Any, List + +# 配置 API معلومة +NANOBANANA_API_URL: str = "YOUR API URL" +NANOBANANA_API_KEY: str = "YOUR API KEY" +OUTPUT_DIR: str = "outputs" + +# 确保输出目录存在 +os.makedirs(OUTPUT_DIR, exist_ok=True) + +def image_to_base64_data_uri(image: Image.Image) -> str: + """ + 将 PIL 图像转换为 OpenAI API 兼容的 data URI 格式。 + """ + buffer = io.BytesIO() + # 统一转为 PNG 以保证兼容性 + image.save(buffer, format="PNG") + encoded = base64.b64encode(buffer.getvalue()).decode('utf-8') + return f"data:image/png;base64,{encoded}" + +def base64_to_image(base64_str: str) -> Optional[Image.Image]: + """ + 将纯 base64 字符串转换为 PIL Image。 + """ + try: + image_bytes = base64.b64decode(base64_str) + return Image.open(io.BytesIO(image_bytes)) + except Exception as e: + print(f"Base64 解码失败: {e}") + return None + +def extract_base64_from_response(content: Any) -> Optional[str]: + """ + 核心解析逻辑:从 API 返回的 content 中提取图片 Base64 数据。 + 兼容 Markdown 格式和结构化列表格式。 + """ + if not content: + return None + + base64_data = None + + # 1. 尝试结构化提取 (List) + # 对应返回格式: [{"type": "image_url", "image_url": {"url": "data:..."}}] + if isinstance(content, list): + for part in reversed(content): # 倒序查找,通常最新的图片在最后 + if isinstance(part, dict): + # 检查 image_url 或 output_image 字段 + img_field = part.get("image_url") or part.get("image") or part.get("output_image") + if isinstance(img_field, dict): + url = img_field.get("url", "") + if url.startswith("data:image/") and "," in url: + return url.split(",", 1)[1].strip() + + # 如果列表中没有结构化图片,尝试把列表里的文本拼起来找 Markdown + text_parts = [ + str(p.get("text", "")) + for p in content + if isinstance(p, dict) and p.get("type") in ["text", "input_text"] + ] + content_str = "".join(text_parts) + else: + content_str = str(content) + + # 2. 尝试 Markdown 正则提取 (String) + # 对应返回格式: "Here is your image: ![img](data:image/png;base64,AAAA...)" + pattern = re.compile(r"!\[.*?\]\((data:image/[^;]+;base64,[^)]+)\)", re.IGNORECASE) + match = pattern.search(content_str) + + if match: + data_url = match.group(1) + if "," in data_url: + return data_url.split(",", 1)[1].strip() + + return None + +def synthesize(prompt: str, input_image: Optional[Image.Image]) -> Optional[Image.Image]: + """ + 调用 Nanobanana API 进行生成。 + """ + if not prompt or not prompt.strip(): + gr.Warning("请输入نصيحة词") + return None + + print(f">>> 开始任务: {prompt[:50]}...") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {NANOBANANA_API_KEY}" + } + + # 构造符合 OpenAI Vision / Chat 标准的 payload + messages = [] + + if input_image is not None: + # 图生图/多模态输入模式 + print(">>> 检测到输入图片,使用多模态模式") + img_base64 = image_to_base64_data_uri(input_image) + messages.append({ + "role": "user", + "content": [ + {"type": "text", "text": prompt}, + {"type": "image_url", "image_url": {"url": img_base64}} + ] + }) + else: + # 纯文生图模式 + messages.append({ + "role": "user", + "content": prompt + }) + + payload = { + "messages": messages, + # 使用第一段代码中验证可用的模型 + "model": "gemini-2.5-flash-image", + # 可选参数,视 API 支持情况而定 + "stream": False + } + + try: + # 增加超时时间,图片生成通常较慢 + response = requests.post(NANOBANANA_API_URL, headers=headers, json=payload, timeout=120) + + # 检查 HTTP 状态 + if response.status_code != 200: + error_msg = f"API 请求失败: {response.status_code} - {response.text}" + print(error_msg) + gr.Error(error_msg) + return None + + result = response.json() + # Debug: 打印返回النتيجة的前一部分,方便调试 + print(f"API 原始响应 (截取): {str(result)[:200]}...") + + # 提取 Content + content = None + if "choices" in result and len(result["choices"]) > 0: + content = result["choices"][0].get("message", {}).get("content") + + if not content: + gr.Warning("API 返回النتيجة中没有 content 字段") + return None + + # 使用之前验证过的逻辑提取 Base64 + base64_str = extract_base64_from_response(content) + + if base64_str: + output_image = base64_to_image(base64_str) + if output_image: + return output_image + + # 如果没提取到图片,可能是模型拒绝了或只返回了文本 + text_content = str(content) if not isinstance(content, list) else " ".join([str(x) for x in content]) + gr.Info(f"未生成图片,模型返回文本: {text_content[:100]}...") + return None + + except requests.exceptions.Timeout: + gr.Error("请求超时,请稍后重试") + return None + except Exception as e: + import traceback + traceback.print_exc() + gr.Error(f"发生未知错误: {str(e)}") + return None + +# Gradio 界面配置 +with gr.Blocks(title="Nanobanana Image Generator") as app: + gr.Markdown("# 🍌 Nanobanana Text/Image to Image") + gr.Markdown("基于 Gemini-2.5-Flash-Image 模型,支持文生图与图生图。") + + with gr.Row(): + with gr.Column(): + prompt_input = gr.Textbox( + label="نصيحة词 (Prompt)", + placeholder="例如: A cyberpunk cat holding a neon sign...", + lines=3 + ) + image_input = gr.Image( + label="参考图 (可选,用于图生图)", + type="pil", + height=300 + ) + submit_btn = gr.Button("开始生成", variant="primary") + + with gr.Column(): + image_output = gr.Image(label="生成النتيجة", format="png") + + submit_btn.click( + fn=synthesize, + inputs=[prompt_input, image_input], + outputs=image_output + ) + +if __name__ == "__main__": + app.launch(share=True) +``` + +当 Trae نصيحة运行成功后,点击它提供的本地链接(通常是 http://127.0.0.1:7860)。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image9.png) + +如果一切正常,你会看到一个已经可以工作的 AI 绘图界面。 + +这个界面看起来很简单,但它已经具备了商业级绘图工具中最核心的两项能力,即文生图和图生图。 + +* **左侧:** **指令区 (** **Input** Zone) —— 你在这里发号施令。 +* **Prompt (نصيحة词框):** 输入你的创意描述(推荐使用英文)。 +* **Input** Image (参考图框): + * **文生图模式:** 保持此处 **为空** 。 + * **图生图模式:** 将本地图片拖入此处,AI 会以它为基础进行创作。 +* **Submit 按钮:** 点击即可发送指令,开始生成。 +* **右侧:展示区 (** **Output** Zone) —— 见证奇迹的地方,生成النتيجة将在此显示。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image10.png) + +现在我们可以尝试生成你的第一张图片了! + +本مثال使用的 prompt 如下: + +> **A red apple** + +这是一个刻意简化的مثال,不包含任何风格或参数描述。 + +#### 实际流程 + +运行代码后,流程可以概括为三步: + +1. 将文字描述发送给模型 +2. 模型生成对应图片 +3. 图片被保存为本地文件 + +几秒钟后,你会在本地看到生成النتيجة。而模型生成具有随机性,所以相同的prompt会有不同的生成النتيجة,你可以多次生成,选择你心仪的图片。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image11.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image12.png) + +也可以丰富你的نصيحة词,给予它更多的描述和限定。例如以下نصيحة词,得到的图片就会更加特殊一些。 + +```Plain +"A hyper-realistic close-up of a fresh red apple with water droplets on its skin, sitting on a dark rustic wooden table. Cinematic dramatic lighting, rim light, shallow depth of field, bokeh background, 8k resolution, macro photography." +(一个超写实的带水珠的新鲜红苹果特写,放在深色粗糙木桌上。电影级戏剧光效,轮廓光,浅景深,背景虚化,8k分辨率,微距摄影。) +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image13.png) + +在Output Image区域点击下载图片即可保存到本地。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image14.png) + +### 1.3 生图模型常见的素材生成场景 + +在实际工作中,大模型生成图片更多用于 **高效产出设计素材** ,而不是创作单张艺术作品。 + +当你观察一些设计类营销账号的高赞案例时会发现,它们的产出大多集中在两类场景: + +* **文生图(从 0 到 1)** +* **有图参考生图(从 1 到 N)** + +#### 一、文生图:快速获取设计物料 + +这一类场景关注效率。当需要填补设计中的空白(如空状态、头像、配图)时,AI 本质上充当的是一个 **即时生成的图库** 。 + +1. ##### 生成 UI 设计物料 + +* 流行趋势:Dribbble 上常见的毛玻璃、黏土风 3D 图标 +* 常见表现:通透材质、边缘发光、糖果配色的功能或天气图标 + +**مثال Prompt:** + +> A set of 3D weather icons (sun, cloud, rain), glassmorphism style, frosted glass texture, soft pastel gradient colors, soft studio lighting, isometric view, transparent background, 4k. + +(一套 3D 天气图标,毛玻璃风格,磨砂质感,柔和渐变色,影棚光,等轴视图) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image15.png) + +2. ##### 生成 Logo + +* 流行趋势:极简线条、几何组合的科技感 Logo +* 常见表现:黑白配色、负空间设计、品牌感明确 + +**مثال Prompt:** + +> Minimalist vector logo design for a tech brand "Coffee Code", combining a coffee cup with coding brackets < >, flat design, solid black lines, white background, Paul Rand style, svg. + +(极简矢量 Logo,结合咖啡杯与代码符号,扁平设计,纯黑线条) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image16.png) + +3. ##### 生成官网用户图片 + +* 流行趋势:SaaS 官网常用 3D 虚拟头像,用于规避真人版权 +* 常见表现:友好表情、卡通比例、偏 Pixar 或 Memoji 风格 + +**مثال Prompt:** + +> Close-up portrait of a friendly young tech professional, smiling, Memoji 3D style, clay render, bright colors, soft lighting, solid plain background, Pixar character design. + +(友好的年轻科技从业者,3D Memoji 风格,黏土渲染) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image17.png) + +4. ##### 生成文章配图 + +* 流行趋势:科技公司博客中常见的抽象扁平插画 +* 常见表现:紫蓝配色、夸张人物比例、漂浮 UI 元素 + +**مثال Prompt:** + +> Editorial flat illustration representing remote work, a person sitting on a giant globe using a laptop, corporate memphis art style, vibrant colors (purple and teal), vector texture. + +(远程办公主题扁平插画,企业孟菲斯风格) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image18.png) + +#### 二、有图参考生图:保持视觉一致性 + +这一类场景更关注 **扩展性** 。当你已经有一张满意的主视觉,需要生成一整套风格一致的素材时使用。 + +5. ##### 主视觉相似的一套按钮或交互素材图 + +在游戏开发中,UI 的一致性非常关键。假设你已经有了主界面的 **“PLAY”** 按钮,现在需要扩展出一整套风格统一的功能按钮(如暂停、设置、主页)。仅靠手绘很难保证每个按钮在光泽、透视和色值上的完全一致。 + +**基本操作流程:** + +1. 保存已有的蓝色 “PLAY” 按钮图片 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image19.png) + +2. 将其拖入界面的 **Input**** Image** 区域,作为后续生成的参考母版 +3. 保持 prompt 中的风格描述不变,仅修改主体内容 + +在这一流程下,只要替换主体描述,就可以得到不同功能但风格一致的按钮。 + +**مثال Prompt:** + +**变体 A:暂停按钮(图标类)** + +> A capsule-shaped game UI button with a white pause icon (two vertical bars) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(胶囊形游戏 UI 按钮,白色暂停图标,蓝色果冻质感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image20.png) + +**变体 B:设置按钮(复杂图标)** + +> A capsule-shaped game UI button with a white gear icon (settings symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(胶囊形游戏 UI 按钮,白色齿轮图标,蓝色果冻质感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image21.png) + +**变体 C:重玩按钮(形状变化)** + +如果需要调整按钮外形,可以在 prompt 中直接描述形状,模型会在保留材质特征的同时尝试改变结构。 + +> A round game UI button with a white circular arrow icon (replay symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(圆形游戏 UI 按钮,循环箭头图标,蓝色果冻质感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image22.png) + +通过这一组操作,你不仅可以替换按钮功能和图标,甚至改变按钮形状,但所有生成النتيجة在材质、配色和光影上仍保持高度一致。这正是大模型在设计素材裂变场景中的核心价值。 + +## 第 2 章:更听话的图像生成助手 —— 以 Lovart 为例 + +在第一部分,我们通过代码直接调用 NanoBanana,体验了“输入即生成”的基础流程。这种方式在需求简单时没有问题。但当生成任务开始包含更多约束,例如: + +* 需要多张风格一致的图片 +* 需要在已有النتيجة上反复调整 +* 需要根据用户输入动态修改生成方向 + +单次调用的方式就会逐渐变得不够用。 + +这时,就需要引入 **AI Agent(** **智能体** **)** 。本节以 **Lovart** 为例,展示当图像生成模型具备“思考层”后,整体工作流会发生怎样的变化。ملاحظة!这里不是打广告,只是帮助大家快速get到AI Agent的便捷性~ + +### 2.0 初识 Lovart:你的 AI 设计代理 + +Lovart 是一个基于 Agent 的设计工具 Web。相比普通生图工具,它在生成之前多了一层“思考与规划”。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image23.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image24.png) + +进入 Lovart 后,主要需要了解以下几个控制项: + +#### 模型选择 + +点击输入框下方的立方体图标,可以查看当前可用的生成模型(如 GPT Image、Flux 等)。 + +为了与前文مثال保持一致,本节仍然使用 NanoBanana 作为底层生成模型。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image25.png) + +#### 思考模式 + +这是 Lovart 的核心开关: + +* **Fast Mode(⚡)** :接近原生 API,响应快,适合单张、明确指令的生成 +* **Thinking Mode(💡)** :Agent 模式,AI 会先拆解需求、改写 prompt,再执行生成 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image26.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image27.png) + +#### 联网能力 + +开启地球图标后,Agent 可以在生成过程中检索网络معلومة(例如设计趋势、配色风格),作为辅助输入。 + +### 2.1 为什么原生 API 还不够? + +即使已经可以通过 Python 生成质量不错的图片,原生 API 在复杂任务中仍然存在限制。关键原因在于:原生 API 本质上是指令式的。当你要求它生成一个具体对象时,它可以直接执行;但当输入变成“策划一套完整的游戏素材”时,它并不会主动将目标拆解为多个可执行خطوة。 + +Lovart 的核心差异在于 Agent 机制。在用户输入与图像生成模型之间,它加入了一层用于理解和规划的逻辑:先识别用户意图,再拆解任务、重写 prompt,最后才执行生成。 + +### 2.2 تطبيق عملي演示:5 分钟打造一套 IP 表情包 + +以 **“制作一套程序员鸭子 ****IP**** 表情包”** 为例,看看 Agent 是如何参与整个流程的。 + +#### 环节一:策划(Agent 的思考能力) + +**原生 ****API**** 的问题:** +你需要自己思考角色设定、情绪状态,并为每一张图单独编写 prompt。 + +**Lovart 的做法:** + +1. 点亮 💡 **Thinking Mode** +2. 输入一句指令: + +> 设计一套程序员鸭子的 IP 表情包,风格要扁平化、可爱 + +AI 不会立即画图,而是先去网络上搜索相关的程序员鸭子的设计图。输出一份拆解后的方案,自动生成 Debug、Coffee Break、Panic 等场景,并对应生成多条视觉描述。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image28.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image29.png) + +这一步,AI 从“执行者”转变为“策划者”。在AI帮你分析完需求后,可以在Lovart的画布区看到多种风格和内容的程序员鸭子图片。可以开始筛选你喜欢的风格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image30.png) + +#### 环节二:一致性(基于参考的视觉锚定) + +Lovart 中的图片不仅是النتيجة,也参与后续生成。 + +##### 完整参考图 + +* 从草图中选出一张最满意的“标准鸭子”,在画布区点击对应图片 +* 该图将会自动出现在对话区,作为 Reference + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image31.png) + +* 输入新的动作(如开心)并生成 + +生成النتيجة会继承母版的配色、比例和细节。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image32.png) + +##### 局部参考 / 多图整合 + +除了整张图片作为参考,Lovart 还支持: + +* **只选取图片的局部区域** (例如只参考帽子或表情) + +点击画布区左侧tab栏,选择「Mark」键,在目标图像的局部区域标记即可,这部分内容会自动同步到对话框。比如在这里我们可以选择修改背景的颜色。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image33.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image34.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image35.png) + +能看到新生成的图片只改变了背景的颜色,这也跟我们输入的要求一致。 + +* **从多张图片中分别引用子元素** ,再组合生成新النتيجة + +例如:你可以保留 A 图的角色主体,同时只替换帽子为 B 图中的样式,Agent 会在后台自动整合这些视觉约束。 + +以程序员鸭子为例,我们可以选择保留第一个图中的鸭子形象,并将其替换到第二张图中作为主体元素。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image36.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image37.png) + +最后的效果也非常显著。你也可以试着其他的组合! + +#### 环节三:落地(Agent 的工具调用) + +生成完成后,可以直接执行:放大、移除背景、擦除等操作 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image38.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image39.png) + +这些并不是简单滤镜,而是 Agent 自动调度不同工具完成的النتيجة。 + +而在确定完基调风格后,可以很快速的生成一系列的表情包图像。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image40.png) + +最终我们得到的是可直接交付的生产级素材,而不仅是一张展示图。 + +### 2.3 使用与收费方式说明 + +Lovart 采用订阅制收费模式,不同套餐对应不同的使用额度与功能权限,具体以官网展示为准。 + +本教程不对任何套餐做推荐或比较;如果在实际使用中有需求,可以根据个人情况选择付费升级。 +目前支持通过**支付宝**等方式完成支付。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image41.png) + +#### ملخص + +Lovart 并不是替代底层模型,而是通过 Agent 机制,让图像生成从“单次执行”升级为“连续工作流”。 + +当任务开始涉及策划、一致性和交付时,这类工具的优势会变得非常明显。 + +## 第 3 章:自己动手做一个智能绘图助手 + +除了直接使用 Lovart,我们也可以自己实现一个简化版的绘图助手。 + +本章以“文章自动配图”为例,从实际问题出发,逐步搭建一个带有思考能力的 Agent。 + +### 3.1 痛点引入:为什么直接发文章给画图模型没用? + +直接将一篇较长的文章输入给 NanoBanana 并要求配图,通常很难得到理想النتيجة。原因并不在于模型“画得不行”,而在于 **它并不擅长理解长文本** 。 + +图像生成模型更适合处理简短、明确的视觉描述,而当输入变成一段包含结构、重点和上下文关系的文章时,模型无法判断哪些内容才是画面中真正需要表达的部分。这往往会导致生成النتيجة偏离主题,或只能捕捉到零散细节,缺乏整体概括能力。 + +本质上,图像模型只有“执行”的能力,却缺少对文本进行分析和取舍的过程。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image42.png) + +### 3.2 解决思路:用 Agent 把「理解」和「执行」拆开 + +要解决这个问题,关键并不是更复杂的نصيحة词,而是 **在绘图之前先把事情想清楚** 。因此,我们在生成流程中引入一个独立的「思考层」,并以此构建一个最简单可用的 Agent。 + +这个 Agent 的核心目标只有一个:**让最终生成的图片,尽可能贴近用户真正的表达意图。** + +整体流程可以概括为:**长文本输入 → 语言模型理解与判断 → 生成合适的视觉نصيحة词 → 图像模型执行生成 → 输出图片** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image43.png) + +那我们构建的 Agent 怎样才能明白用户的意图呢? + +这里选择做一个简化的 **“思考层”** ,我们设置了三种不同的意图:无效输入、直接生图、需要理解的长文本。 + +在这个 Agent 中,各个角色的分工可以概括为四点: + +1. **语言模型作为决策核心** + 它负责理解文章内容、判断用户输入的意图,并将任务分发到合适的生成路径中,决定接下来“该怎么做”以及如何生成生图نصيحة词。 +2. **图像模型作为执行者** + 图像模型不参与理解与判断,只接收已经整理好的视觉指令,专注完成图像渲染。 +3. **用户作为可介入的引导者** + 除了直接输入文本,用户还可以在过程中手动调整生成的نصيحة词,或加入参考图来辅助生成,从而对最终النتيجة进行引导和微调。 +4. **Gradio 与后端 ****API**** 作为整体承载层** + 它们负责将界面、模型调用和النتيجة展示串联起来,保证整个 Agent 能够以一个完整 Web 应用的形式稳定运行。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image44.png) + +### 3.3 تطبيق عملي准备 :获取API + +看起来是不是很有趣呢!要跑通上述流程,我们只需要准备两类 API。 + +#### 手:NanoBanana API(图像生成) + +直接沿用第 1 章中已经配置好的 API Key 和 API URL,无需额外设置。 + +#### 脑:SiliconFlow API(文本思考) + +我们需要一个大语言模型来承担“思考层”的职责。本教程使用 SiliconFlow 提供的模型服务:[https://cloud.siliconflow.cn](https://cloud.siliconflow.cn/) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image45.png) + + SiliconFlow 提供了兼容 OpenAI API 规范的接口,可以非常方便地在项目中通过标准网络请求进行调用。在这里我们选择的是免费的Qwen2.5-7B-Instruct模型,调用需要的内容都已经写入下面的Prompt。在开始之前,你只需要在官网注册账号并创建一个 API Key。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image46.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image47.png) + + 该 Key 将用于后续的模型调用。 + +### 3.4 搭建Agent : + +本次实验主要使用Trae来帮我们编写代码,本教程选用的是Gemini-3-Pro-Preview模型。总思路是,新建项目后将下述完整 Prompt 复制到对话框并输入,逐步替换 API KEY 后运行代码,完成测试即可。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image48.png) + +#### 环节1️⃣:Gradio Blocks 基础框架与界面布局 + +在这个环节,我们的主要目标是先给整个Agent搭建出一个“外观”,实现前端的页面设计。复制以下Prompt在Trae对话框中实现后,你将会得到一个本地的URL(通常是 http://127.0.0.1:7860 )即可查看界面,并且检验实现效果。 + +```Plain +板块 1:Gradio Blocks 基础框架与界面布局 +1、任务目标 +·基于 Gradio 4.0.0+ 的 Blocks 布局,实现「LLM+Nanobanana 文生图」项目的基础界面,严格遵循固定左右分栏布局,初始化所有 UI 组件并设置正确的初始状态。 + +2、技术栈要求 +·必须使用 Gradio 4.0.0+ 的 Blocks 模式开发,禁止使用 Interface 模式; +·依赖:gradio>=4.0.0,pillow>=10.0.0(仅导入,暂不实现图片处理逻辑); +·代码需是完整可运行的 Python 文件,包含所有必要的导入语句。 + +3、界面布局规则(核心约束,融合تطبيق عملي细节) +·整体布局: +页面标题:LLM 驱动的文生图全流程工具; +固定左右分栏:左侧占 60% 宽度,右侧占 40% 宽度,使用 gr.Row 和 gr.Column 实现比例控制。 +·左侧 60%(نصيحة词生成流程区)组件清单: +input_text:gr.Textbox,标签「输入文本(教程段落 / 绘图指令)」,lines=6,占位符「请输入需要配图的教程文本或直接绘图指令...」; +identify_intent_btn:gr.Button,value="识别意图",初始状态正常可点击; +intent_status:gr.Textbox,标签「意图类型 / 处理状态」,lines=2,interactive=False,初始值「未识别意图」; +system_prompt:gr.Textbox,标签「System Prompt(仅文章配图意图可编辑)」,lines=4,interactive=False,占位符「LLM 生成نصيحة词的约束规则...」; +confirm_prompt_btn:gr.Button,value="确认生成生图نصيحة词",interactive=False(初始禁用防误触); +generation_prompt:gr.Textbox,标签「生图نصيحة词(可编辑)」,lines=3,interactive=True,初始值为空,占位符「生成的英文生图نصيحة词将显示在此,支持手动修改...」。 +·右侧 40%(Nanobanana 生图功能区)组件清单: +ref_image:gr.Image,标签「参考图(可选,图生图)」,type=filepath,height=300,允许上传; +generate_btn:gr.Button,value="生成图片",interactive=False(初始禁用,无نصيحة词不可点击); +result_image:gr.Image,标签「生成النتيجة」,type=pil,height=300,初始为空,interactive=False。 + +4、交互逻辑要求 +·所有组件的 interactive 初始状态严格按上述配置,后续通过函数动态更新; +·按钮禁用状态需直观(置灰),避免用户误操作。 + +5、输出要求 +·生成完整的 Python 代码,仅实现界面布局和组件初始化,不包含任何业务逻辑; +·代码注释清晰,组件命名与تطبيق عملي版一致(input_text/identify_intent_btn 等); +·代码可直接运行,界面结构与描述完全一致。 +``` + +在浏览器打开http://127.0.0.1:7860后可看到Trae已经按照我们的要求生成了以下的网页,跟我们的要求大致相当,可以进行到الخطوة التالية的生成中了。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image49.png) + +#### 环节2️⃣:LLM 意图识别模块(Siliconflow API) + +在日常使用VLM画图的时候,可能有以下三种常见输入情况: + +1. 无意义内容,比如“你好”、“你今天吃饭了吗”等,无法画出对应的图片。 +2. 文章/长文本,字数较多,比如200字左右的一篇有结构的文章,需要先理解文章的结构与内容,再考虑如何生成能完整概括这段文字的图片。 +3. 直接绘图指令,比如“帮我画一只在洗澡的狗”等,要求已经阐述的非常具体,可以直接生成图片。 + +跟前面一样,复制以下Prompt在Trae对话框中实现,并且补充在前面خطوة中获得的API。 + +```Plain +板块 2:LLM 意图识别模块(Siliconflow API) +1、任务目标 +在已实现的 Gradio 界面基础上,为「识别意图」按钮添加点击逻辑,调用 Siliconflow API 完成意图识别,并联动组件状态。 + +2、技术栈要求 +基于 Gradio 4.0.0+ Blocks; +依赖:requests>=2.31.0,openai; +输出完整可运行 Python 文件,包含板块 1 界面 + 本模块逻辑。 + +3、核心业务规则(绝对不可偏离) +·意图分类规则(仅 3 类,严格返回数字 + 描述) +1 = 无意义内容:仅闲聊、寒暄、无关对话,没有任何绘图或配图需求(如 “你好”“今天吃了吗”); +2 = 文章 / 长文本配图需求:用户输入一段完整文章、教程、段落、说明性文字,内容偏叙事 / 说明 / 讲解,隐含需要为这段内容生成配图的意图,不需要用户明确说 “为这段文字配图”; +3 = 直接绘图指令:用户输入简短、明确的画图命令,没有长文本背景,直接要求画某个内容(如 “画一只 Apple 风格的猫”)。 +·LLM 调用约束(融合تطبيق عملي版模板) +接口地址:https://api.siliconflow.cn/v1/chat/completions; +模型:Qwen/Qwen2.5-7B-Instruct; +temperature=0.1; +统一定义代码: +python +运行 +LLM_BASE_URL = "https://api.siliconflow.cn/v1" +LLM_API_KEY = "" # 用户自行替换 +LLM_MODEL = "Qwen/Qwen2.5-7B-Instruct"# تطبيق عملي验证的意图识别模板(固化到代码中) +INTENT_PROMPT_TEMPLATE = """你需要识别用户输入文本的意图,仅返回以下 3 类النتيجة中的一种(格式:数字 + 中文描述): +1 = 无意义内容;2 = 文章 / 长文本配图需求;3 = 直接绘图指令。 + +用户输入:{user_input} + +识别النتيجة: +仅提取返回النتيجة中的数字和描述,禁止额外内容。""" + +4、组件联动规则 +·النتيجة为 1:intent_status 显示「1 = 无意义内容:无绘图需求」,system_prompt 保持禁用,confirm_prompt_btn 禁用; +·النتيجة为 2:intent_status 显示「2 = 文章 / 长文本配图需求:为输入内容生成配图」,启用 system_prompt 并填充默认规则,激活 confirm_prompt_btn; +·النتيجة为 3:intent_status 显示「3 = 直接绘图指令:根据指令生成图片」,system_prompt 禁用且填充默认规则,激活 confirm_prompt_btn。 + +5、异常处理 +API 异常、解析异常均给出友好نصيحة,不崩溃,组件恢复初始状态。 + +6、输出要求 +生成完整可运行代码,替换 LLM_API_KEY 即可使用,逻辑清晰注释完整,意图识别模板严格使用تطبيق عملي版。 +``` + +刷新之前的http://127.0.0.1:7860网址,开始测试是否能正确检测三种情况。 + +1. 无意义内容,可以尝试输入“你好”、“谢谢”等,发现能够正常识别。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image50.png) + +2. 文章/长文本,在这里我们选用了一段豆包生成的描述人工智能的文字。你也可以尝试使用自己的论文段落进行测试。 + +```Plain +人工智能正在以前所未有的深度和广度重塑教育生态系统。通过自适应学习算法,AI系统能够构建每个学生的认知图谱,实时追踪他们的知识掌握轨迹,并动态调整教学内容的难度和呈现方式。在传统课堂环境中,教师往往难以同时满足不同学习风格和能力水平的学生需求,而基于深度学习的教育平台可以分析学生在交互式模拟实验中的行为模式,识别他们在量子力学或微积分等复杂概念理解上的微妙障碍,并提供精准的认知支架。 + +高级自然语言处理引擎驱动的虚拟导师不仅能够解构开放性问题,如"如何评价法国大革命对现代民主制度的影响",还能引导苏格拉底式对话,激发批判性思维。当学生撰写关于气候变化对极地生态系统影响的论文时,AI写作助手可以分析其论证逻辑的严密性,指出数据引用中的时效性问题,并建议更精准的科学术语。在特殊教育领域,计算机视觉技术使AI能够识别自闭症谱系儿童在社交互动中的非语言线索,调整干预策略,而情感计算算法则帮助检测在线学习时的挫折感,及时提供鼓励性反馈。 + +然而,这种技术融合引发了一系列伦理困境。算法偏见可能无意中边缘化特定文化背景的学生,数据采集的透明度问题引发了对学术隐私的关切,而过度依赖自动化评分系统可能削弱教师对学生思维过程的深层理解。更复杂的是,当AI开始生成高度逼真的虚拟实验室体验时,我们需要重新定义"实践经验"在教育中的价值。未来教育的范式可能演变为人类教师专注于培养创造力、同理心和道德判断力,而AI系统则承担知识传递、技能训练和个性化评估的职能,形成一种协同进化的教育共生体,既能发挥机器的计算优势,又能保留人类教育的独特温度. +``` + +同样检测成功~ + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image51.png) + +3. 直接绘图指令,这里输入的是“我要画一只猫”,同样检测准确。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image52.png) + +到这里我们就已经顺利实现了第二个环节——意图识别。 + +#### 环节3️⃣:生图نصيحة词生成模块(LLM 二次调用) + +意图识别后,对于文章或长文本,还有很مهم的一步就是生成画图的نصيحة词,而这正是本Agent的重点。 + +```SQL +板块 3:生图نصيحة词生成模块(LLM 二次调用) +1、任务目标 +在意图识别基础上,实现「确认生成生图نصيحة词」按钮逻辑,调用 LLM 将文本优化为适合绘图的英文视觉نصيحة词,填充到编辑框并联动「生成图片」按钮。 + +2、技术栈要求 +同板块 2,输出完整代码 = 板块 1 + 板块 2 + 本模块; +共用板块 2 定义的 LLM_BASE_URL、LLM_API_KEY、LLM_MODEL,不新增密钥。 + +3、核心业务规则(融合تطبيق عملي版 Prompt 组装逻辑) +·نصيحة词生成输入规则(必须严格遵循) +生图نصيحة词生成不再是简单字符串拼接,而是构建标准 Chat 消息列表,代码结构如下: +python +运行 +messages=[# System角色:网页上用户最终确认/编辑后的system_prompt内容{"role": "system", "content": final_system_prompt},# User角色:承载待处理数据,明确任务目标{"role": "user", "content": f"请为以下内容生成视觉نصيحة词:\n\n{user_input}"}] +意图为 2 时:System 内容取用户编辑后的 system_prompt 最终版本; +意图为 3 时:System 内容取禁用状态下填充的默认规则 +user_input 为用户最初输入到 input_text 框的原始文本。 +·تطبيق عملي验证的 System Prompt 预设(固化到代码中) +python +运行 +SYSTEM_PROMPT_DEFAULT = """你现在是一个创建NanoBanana画图نصيحة词的助手。 +需要根据我的内容处理,我这个图片的作用是能说明这一段在说什么,并且让大家知道这段话的上下结构就是整体说的是什么意思。 +里面可能会类似PPT有一些讲解(如:左上角展示核心观点,右下角展示数据)。 +设计风格要求:简约,Apple设计思维(Apple Design Philosophy)。 +约束:请直接返回NanoBanana可用的英文نصيحة词,不要返回任何解释、前缀或多余的废话。""" +·LLM 调用约束 +与板块 2 共用同一套 LLM_BASE_URL、LLM_API_KEY、LLM_MODEL; +temperature=0.7(保证نصيحة词的创意性与适配性); +max_tokens=200(限制输出长度,匹配نصيحة词约束); +严格使用上述标准 Chat 消息列表结构,禁止字符串拼接。 +·مثال输入输出(核心参考) +输入مثال 1(文章配图意图):原始文本:「AI 如何改变教育:随着人工智能技术的发展,教师的角色从知识传授者转变为引导者,AI 助手可辅助学生完成个性化学习,课堂上人机协作成为常态。」最终 System Prompt:SYSTEM_PROMPT_DEFAULT(未修改)输出预期:"Minimalist illustration, Apple Design Philosophy, 1024x1024. Top left shows 'AI + Education' core concept, bottom right shows data of teacher-student-AI collaboration, soft color palette, clean lines, no redundant elements." +输入مثال 2(直接绘图指令):原始文本:「画一只 Apple 风格的猫,坐在 MacBook 旁边」最终 System Prompt:SYSTEM_PROMPT_DEFAULT(禁用状态)输出预期:"Minimalist cat, Apple style, 1024x1024, sitting next to a silver MacBook, clean white background, soft shadows, geometric shapes, no extra details." +·نصيحة词输出强制约束 +纯英文,无中文; +必须包含 Apple Design Philosophy/Apple style + 1024x1024; +长度 50–200 字符,代码内校验; +无额外解释、前缀或废话,仅返回نصيحة词本身。 + +4、组件联动规则 +生成成功:将نصيحة词填入 generation_prompt 框,激活 generate_btn,intent_status 追加「نصيحة词生成成功,可修改后生成图片」; +生成失败:نصيحة具体原因(如 API 调用失败、长度不达标),generate_btn 保持禁用,generation_prompt 框为空; +用户手动修改 / 清空 generation_prompt 框: +清空时自动禁用 generate_btn; +非空时保持 generate_btn 激活。 + +5、异常处理 +API 调用失败:友好نصيحة「نصيحة词生成失败:{具体错误معلومة}」,不崩溃; +نصيحة词校验失败:明确نصيحة原因(如 “未包含 Apple style”“长度仅 40 字符”),允许重试; +响应解析失败:نصيحة「无法解析 LLM 返回النتيجة,请重试」。 + +6、输出要求 +完整可运行代码,替换 LLM_API_KEY 即可使用; +代码结构清晰、注释完善,界面美观简洁; +严格实现标准 Chat 消息列表结构,参数与مثال逻辑一致; +包含نصيحة词长度、内容校验逻辑,错误نصيحة友好。 +``` + +同样复制第二个环节的文本进行检测。 + +值得ملاحظة的是,我们在这里预设的生成生图نصيحة词的System Prompt为: + +> 你现在是一个创建NanoBanana画图نصيحة词的助手。 +> 需要根据我的内容处理,我这个图片的作用是能说明这一段在说什么,并且让大家知道这段话的上下结构就是整体说的是什么意思。 +> 里面可能会类似PPT有一些讲解(如:左上角展示核心观点,右下角展示数据)。 +> 设计风格要求:简约,Apple设计思维(Apple Design Philosophy)。 +> 约束:请直接返回NanoBanana可用的英文نصيحة词,不要返回任何解释、前缀或多余的废话。 + +如果你想换成其他的预设模版,可以在前面的prompt里修改,或者直接在Trae里通过对话修改。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image53.png) + +除了修改底层代码,我们在网页上也可以快速编辑。举个例子,我在这里加了一句,“在前面加一句Pic Prompt”,可以看到生成的新的نصيحة词前面也包含了~这样设计是为了方便快速修改生成نصيحة词的System Prompt,帮助我们快速切换风格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image54.png) + +#### 环节4️⃣:Nanobanana 文生图 / 图生图模块 + +终于来到了最后一步,不接入生图模型,就不是一个完整的Agent! + +```Bash +板块 4:Nanobanana 文生图 / 图生图模块(最终版) +1、任务目标 +实现「生成图片」按钮逻辑,调用真实 Nanobanana API,支持文生图 / 图生图,解析 Base64 并展示图片。 + +2、技术栈要求 +基于 Gradio 4.0.0+ Blocks; +依赖:requests, pillow, base64, io, re; +完整代码 = 板块 1+2+3 + 本模块。 + +3、核心 API 配置(تطبيق عملي验证固化) +固化代码配置: +python +运行 +# 固化到代码中的API配置 +NANOBANANA_API_URL = "https://api.zyai.online/v1/chat/completions" +NANOBANANA_MODEL = "gemini-2.5-flash-image" +NANOBANANA_API_KEY = "" # 用户自行替换 +鉴权方式:Header Authorization: Bearer {NANOBANANA_API_KEY}。 + +4、图片预处理要求(必须实现)实现函数 image_to_base64_data_uri (ref_image_path),核心逻辑: +将 PIL 图片转为 PNG 格式; +自动缩放到 1024x1024 分辨率; +透明通道转为白色背景; +编码为 Base64,返回格式:data:image/png;base64,...。 + +5、请求构建规则(严格按تطبيق عملي版分支逻辑) +·核心函数定义实现函数 generate_image (prompt, ref_image_path): +入参:prompt(generation_prompt 框内容)、ref_image_path(ref_image 上传的文件路径); +返回:PIL Image(展示到 result_image)或错误نصيحة。 +·逻辑分支 1:纯文生图(ref_image_path 为空) +python +运行 +messages = [{"role": "user", "content": prompt}] +·逻辑分支 2:图生图(ref_image_path 有值) +python +运行 +# 先调用图片预处理函数 +image_base64 = image_to_base64_data_uri(ref_image_path) +messages = [{"role": "user","content": [{"type": "text", "text": prompt},{"type": "image_url", "image_url": {"url": image_base64}}]}] + +6、响应解析要求(必须兼容两种格式)从 choices [0].message.content 中提取图片 Base64,支持: +结构化 JSON 返回的 image_url 字段; +Markdown 格式 +; +统一提取 Base64 编码,解码后转换为 PIL Image 返回。 + +7、组件联动与异常处理 +生成成功:将 PIL Image 展示到 result_image,intent_status نصيحة「图片生成成功」; +生成 / 解析 / 上传失败:在 intent_status 显示清晰文字نصيحة(如 “Base64 解析失败”“API 调用超时”),不崩溃。 + +8、输出要求 +完整可运行代码,替换 LLM_API_KEY 和 NANOBANANA_API_KEY 即可直接运行,全流程可用,分支逻辑严格匹配تطبيق عملي版。 +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image55.png) + +太令人激动啦!我们终于顺利地生成出了这个Agent的第一张图,仔细看看生成的图片,跟我们的文本和نصيحة词是匹配的。到这里你已经基本上实现你自己的Agent啦! + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image56.png) + +我们还添加了图生图功能,上传你喜欢的图片,AI会自动借鉴风格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image57.png) + +值得一提的是,前面خطوة生成的نصيحة词也是可以在网页上编辑的,并且我们是以最终点击按钮时的نصيحة词为准~哪怕我在这里换成“a cute cat”,最终生成的图片也只会是可爱的小猫。 + +## 第 4 章:الخلاصة + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image58.png) + +**呜呼!终于写完了。** +说实话,连我自己写完最后一行的时候都忍不住长舒一口气,更别说一路跟着做到这里的你了。能把这一整套流程完整跑下来,本身就已经很厉害了,这说明你真的把手放到键盘上,把事情一步步做完了。Bravo 🎉 🥳 👏 + +在写这套内容的过程中,我一直在想,我们到底要留下些什么?答案其实并不是模型名字、参数或者某种固定套路,而是让你慢慢建立起一种感觉:哪些事情可以放心交给 AI 去理解和规划,哪些地方只需要你来决定方向。一旦这层分工成立,很多原本看起来复杂的生成流程,都会开始变得顺起来。 + +回头看,这条路其实并不复杂。想清楚你要解决的问题,把长文本交给语言模型去拆解,再把整理好的视觉意图交给绘图模型去呈现,最后把这一整套流程封装成一个属于你自己的小助手。到这里,你已经不只是“在用模型”,而是在搭建一套可以长期陪你工作的系统,而这,才是这套教程最想带给你的东西。 + +但是你已经做的很棒啦!相信学到这里的你对Vibe Coding已经有初步的掌握了,给自己放个小假休息一下吧! + + diff --git a/docs/ar-sa/stage-2/frontend/modern-component-library/index.md b/docs/ar-sa/stage-2/frontend/modern-component-library/index.md new file mode 100644 index 0000000..3e082fb --- /dev/null +++ b/docs/ar-sa/stage-2/frontend/modern-component-library/index.md @@ -0,0 +1,465 @@ +# تحديث واجهتك باستخدام مكتبة مكونات حديثة + +在前面的课程中,你已经学会了如何用设计工具画出界面、用 AI IDE 把设计稿变成代码,甚至完成了一个完整的前端项目。但你可能也发现了一个问题:自己从零写出来的按钮、表单、弹窗,虽然能用,但总觉得和"专业产品"差了点意思——样式不够统一、交互细节不够丝滑、适配不同屏幕也很头疼。 + +这就是**组件库**要解决的问题。 + +组件库是一套预先设计好、开发好的 UI 零件集合。按钮、输入框、下拉菜单、对话框、表格……这些你在任何产品中都会反复用到的界面元素,组件库已经帮你做好了,而且经过了大量用户的验证和打磨。你只需要像搭积木一样把它们组合起来,就能快速构建出专业级的界面。 + +## ما ستتعلمه + +1. 理解什么是前端组件库,以及为什么现代开发几乎都在用它 +2. 认识四个最具代表性的组件库,了解它们各自擅长的场景 +3. 通过三个تطبيق عملي场景(落地页、产品页面、后台管理),学会用 AI IDE + 组件库进行 Vibe Coding +4. 学会阅读组件库文档,根据需求找到合适的组件并正确使用 + +## 1. 为什么需要组件库? + +想象你在装修房子。你可以自己从木头开始做一把椅子,但更常见的做法是去宜家买一把——设计好看、质量稳定、说明书清晰,拿回家组装就行。 + +组件库就是前端开发中的"宜家"。它提供的不是家具,而是界面零件: + +| 自己手写 | 使用组件库 | +| :--- | :--- | +| 需要自己处理样式、交互、动画 | 开箱即用,样式和交互已经打磨好 | +| 不同页面的按钮可能长得不一样 | 全局风格统一,自动保持一致性 | +| 适配手机、平板需要额外工作 | 大多数组件库已内置响应式支持 | +| 无障碍访问(Accessibility)容易遗漏 | 专业组件库已处理好键盘导航、屏幕阅读器等 | +| 开发速度慢 | 开发速度快,专注业务逻辑 | + +简单来说:**组件库让你把时间花在"做什么"上,而不是"怎么画"上。** + +### 眼见为实:同一个需求,加不加组件库的差距 + +光说不练没有说服力。我们在 Trae 中用几乎相同的需求,分别不指定和指定组件库,看看生成النتيجة的差距。 + +**نصيحة词一:不使用组件库** + +```text +请帮我做一个 AI 写作助手的数据仪表盘页面,包含: +- 顶部标题栏和导出按钮 +- 四张统计卡片显示用户数、活跃用户、文档数、收入,还要显示涨跌趋势 +- 一个折线图和一个饼图 +- 用户列表表格,带分页功能 +- 左侧导航侧边栏 +``` + +在 Trae 中直接运行后的效果: + + + + +**نصيحة词二:使用 shadcn/ui 组件库** + +```text +请帮我做一个 AI 写作助手的数据仪表盘页面,用 shadcn/ui 组件库来做,包含: +- 顶部标题栏和导出按钮 +- 四张统计卡片显示用户数、活跃用户、文档数、收入,还要显示涨跌趋势 +- 一个折线图和一个饼图 +- 用户列表表格,带分页功能 +- 左侧导航侧边栏 +``` + +同样在 Trae 中直接运行后的效果: + + + + +同样的需求,唯一的区别只是在نصيحة词开头加上了 `shadcn/ui + Tailwind CSS`,Trae 生成的النتيجة在视觉一致性、交互细节、整体打磨程度上就完全不在一个层级。这就是组件库带来的"免费升级"——你只需要在نصيحة词里多写一个组件库的名字。 + +## 2. 认识四个核心组件库 + +组件库数量众多(完整列表见[الملحق](#الملحق-更多组件库一览)),但你只需要先认识这四个最具代表性的: + +| 组件库 | 框架 | 一句话定位 | 官网 | +| :--- | :--- | :--- | :--- | +| [Ant Design](https://ant.design) | React | 蚂蚁集团出品,企业级中后台的事实标准,组件覆盖面极广 | ant.design | +| [shadcn/ui](https://ui.shadcn.com) | React | 不装 npm 包,直接把代码复制到你项目里,基于 Tailwind CSS,定制自由度最高 | ui.shadcn.com | +| [HeroUI](https://heroui.com)(原 NextUI) | React | 默认样式精美、动画流畅,适合对视觉品质有要求的落地页和产品展示 | heroui.com | +| [Material UI](https://mui.com) | React | 最老牌的 React 组件库,实现 Google Material Design 规范,生态最成熟 | mui.com | + +> Vue 用户同样有丰富选择:[Element Plus](https://element-plus.org)(国内最流行)、[Ant Design Vue](https://antdv.com)、[Naive UI](https://www.naiveui.com) 等,详见[الملحق](#الملحق-更多组件库一览)。 + +不同组件库擅长不同场景。接下来我们通过三个真实开发场景,带你体验如何用 AI IDE + 组件库进行 Vibe Coding。 + +为了展示不同组件库的风格和特点,我们在每个场景中刻意选用了不同的库。但请ملاحظة:**这只是为了让你多见识几种方案**,实际开发中你完全可以只用自己最顺手的那一个。比如你喜欢 shadcn/ui 的风格,用它做落地页、产品页、后台管理都没问题。选一个你觉得好看、用着舒服的,比什么都مهم。 + +## 3. تطبيق عملي一:用 HeroUI 构建产品落地页 + +**场景**:你做了一个 AI 写作助手产品,需要一个漂亮的落地页来展示产品特性、吸引用户注册。落地页需要视觉冲击力强、动画流畅、在手机上也好看。 + +**为什么选 HeroUI**:HeroUI 的默认样式就很精美,自带流畅的过渡动画,非常适合面向用户的展示型页面。 + +### 3.1 创建项目 + +```bash +# 使用 HeroUI 官方 CLI 创建项目 +npx create-heroui-app@latest ai-writer-landing +cd ai-writer-landing +npm install +``` + + + + +### 3.2 用 AI IDE 生成落地页 + +打开 AI IDE(Cursor、Trae 等),在对话框中输入: + +```text +请帮我做一个 AI 写作助手的落地页,用 HeroUI 组件库来做: + +**页面结构:** +1. 顶部导航栏:左边放 Logo 和产品名,右边放"功能"、"定价"、"关于"三个链接,再加一个"开始使用"按钮 +2. 首屏区域:大标题写"让 AI 成为你的写作搭档",副标题介绍产品价值,两个按钮"免费试用"和"查看演示",下面放一张产品截图 +3. 功能展示:三列卡片,分别介绍"智能续写"、"风格调整"、"多语言翻译"三个功能,每张卡片要有图标、标题、描述 +4. 定价区域:三个定价卡片(免费版、专业版、团队版),专业版要突出显示推荐 +5. 底部号召:一句吸引人的文案,加上注册按钮 +6. 页脚:版权معلومة和社交媒体链接 + +**设计要求:** +- 看起来要现代、专业 +- 支持暗色模式 +- 手机上看也要好看 +``` + + + + +### 3.3 AI 会用到的关键组件 + +AI 生成的代码中,你会看到这些 HeroUI 组件: + +```jsx +import { + Navbar, NavbarBrand, NavbarContent, NavbarItem, + Button, + Card, CardHeader, CardBody, CardFooter, + Divider, + Link, + Chip +} from '@heroui/react' +``` + +每个组件的作用: + +| 组件 | 用途 | 落地页中的位置 | +| :--- | :--- | :--- | +| `Navbar` | 顶部导航栏 | 页面最顶部,固定不动 | +| `Button` | 按钮,支持多种变体和颜色 | CTA 按钮、导航按钮 | +| `Card` | 卡片容器 | 功能展示、定价卡片 | +| `Chip` | 小标签 | "推荐"、"最受欢迎"标记 | +| `Divider` | 分割线 | 区域之间的视觉分隔 | + +### 3.4 迭代优化 + +生成的初版代码可能不完全满意,继续和 AI 对话调整: + +```text +请帮我优化一下落地页: + +1. 大标题加上渐变色,从蓝色渐变到紫色 +2. 功能卡片鼠标放上去要有上浮的动画效果 +3. 专业版定价卡片要突出显示,加个边框和"最受欢迎"的标签 +4. 手机上的导航改成汉堡菜单(三条横线那种) +``` + + + + +> **Vibe Coding 的核心**:你不需要记住每个组件的 API,只需要用自然语言描述你想要的效果,AI 会帮你找到合适的组件和写法。遇到不满意的地方,继续对话迭代就好。 + +## 4. تطبيق عملي二:用 shadcn/ui 构建产品页面 + +**场景**:你的 AI 写作助手需要一个用户登录后的主界面——左侧是文档列表,右侧是编辑器,顶部有工具栏。这是一个功能型产品页面,需要高度定制化的 UI。 + +**为什么选 shadcn/ui**:shadcn/ui 把组件代码直接放进你的项目,你可以随意修改任何细节。对于需要深度定制的产品界面,这种"拥有代码"的模式最灵活。 + + + + +### 4.1 创建项目 + +```bash +# 创建 Next.js 项目 +npx create-next-app@latest ai-writer-app --typescript --tailwind --app +cd ai-writer-app + +# 初始化 shadcn/ui +npx shadcn@latest init + +# 按需添加组件(不是一次性安装所有组件) +npx shadcn@latest add button card input sidebar sheet dialog +``` + +shadcn/ui 的独特之处:每次 `add` 一个组件,它会把源代码复制到你项目的 `components/ui/` 目录下。你可以直接打开这些文件修改样式和行为。 + +### 4.2 用 AI IDE 生成产品界面 + +```text +请帮我做一个 AI 写作助手的主界面,用 shadcn/ui 组件库来做: + +**整体布局:** +- 左边是可折叠的侧边栏,宽度大概 280px: + - 顶部放"新建文档"按钮 + - 下面是文档列表,每个文档显示标题和最后编辑时间 + - 右键点击文档可以重命名或删除 +- 右边是主编辑区,分成上下两部分: + - 上面是工具栏:可以编辑文档标题、显示字数统计、"AI 续写"按钮、"导出"下拉菜单 + - 下面是编辑区域:一个大的文本输入框,占满剩余空间 + +**交互细节:** +- 点击"AI 续写"后,按钮显示加载状态,编辑器底部出现 AI 生成的文本(像打字机一样逐字显示) +- 手机上侧边栏变成抽屉式,从左边滑出 +- 当前选中的文档要高亮显示 +``` + + + + +### 4.3 AI 会用到的关键组件 + +```tsx +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Card, CardContent, CardHeader } from '@/components/ui/card' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@/components/ui/dropdown-menu' +import { + Sheet, + SheetContent, + SheetTrigger +} from '@/components/ui/sheet' +import { + Sidebar, + SidebarContent, + SidebarHeader +} from '@/components/ui/sidebar' +``` + +| 组件 | 用途 | 产品页面中的位置 | +| :--- | :--- | :--- | +| `Sidebar` | 可折叠侧边栏 | 左侧文档列表 | +| `Sheet` | 移动端抽屉 | 移动端侧边栏替代 | +| `DropdownMenu` | 下拉菜单 | "导出"按钮、右键菜单 | +| `Dialog` | 对话框 | 重命名、删除确认 | +| `Button` | 按钮,支持 variant 和 loading | 各种操作按钮 | +| `Input` | 输入框 | 文档标题编辑 | + +### 4.4 定制组件样式 + +shadcn/ui 的优势在于你可以直接修改组件源码。比如你想让按钮的圆角更大: + +```text +请帮我修改 components/ui/button.tsx, +把所有按钮的默认圆角从 rounded-md 改为 rounded-xl, +并给 primary 变体加上微妙的阴影效果 +``` + +AI 会直接修改你项目中的组件文件,而不是覆盖 npm 包的样式——这就是 shadcn/ui "拥有代码"的好处。 + + + + +## 5. تطبيق عملي三:用 Ant Design 构建后台管理界面 + +**场景**:你的 AI 写作助手上线后,需要一个管理后台来查看用户数据、管理文档内容、处理付费订单。后台管理系统的核心是数据展示和操作效率。 + +**为什么选 Ant Design**:Ant Design 在中后台领域积累最深,表格、表单、图表等业务组件开箱即用,内置了大量企业级交互模式(批量操作、高级筛选、数据导出等)。 + + + + +### 5.1 创建项目 + +```bash +# 使用 Ant Design Pro 脚手架(内置布局、路由、权限) +npx create-umi@latest ai-writer-admin +# 选择 Ant Design Pro 模板 +cd ai-writer-admin +npm install +``` + +或者从零开始: + +```bash +npx create-react-app ai-writer-admin --template typescript +cd ai-writer-admin +npm install antd @ant-design/icons @ant-design/pro-components +``` + +### 5.2 用 AI IDE 生成管理后台 + +```text +请帮我做一个 AI 写作助手的管理后台,用 Ant Design 组件库来做: + +**整体布局:** +- 左边是菜单栏:仪表盘、用户管理、文档管理、订单管理、系统设置 +- 顶部显示面包屑导航 + +**用户管理页面:** +- 顶部放四个统计卡片:总用户数、今日新增、活跃用户数、付费用户数 +- 搜索筛选区:可以按用户名搜索、选择注册时间范围、筛选用户状态,还有"搜索"和"重置"按钮 +- 用户表格: + - 显示头像、用户名、邮箱、注册时间、订阅计划(用不同颜色标签区分)、状态、操作 + - 每页显示 20 条,支持分页 + - 可以批量选择用户,批量禁用或导出 + - 操作列:查看详情、编辑、禁用(禁用前要二次确认) +- 点击"查看详情"从右侧滑出抽屉,显示用户详细معلومة和最近文档列表 +``` + + + + +### 5.3 AI 会用到的关键组件 + +```tsx +import { PageContainer, ProLayout } from '@ant-design/pro-components' +import { ProTable } from '@ant-design/pro-components' +import { StatisticCard } from '@ant-design/pro-components' +import { + Button, Tag, Badge, Space, Drawer, + Popconfirm, message, Modal +} from 'antd' +import { + UserOutlined, SearchOutlined, ExportOutlined +} from '@ant-design/icons' +``` + +| 组件 | 用途 | 后台中的位置 | +| :--- | :--- | :--- | +| `ProLayout` | 后台整体布局框架 | 页面骨架(菜单 + 内容区) | +| `ProTable` | 高级表格,内置搜索、分页、列设置 | 用户列表、文档列表、订单列表 | +| `StatisticCard` | 数据统计卡片 | 仪表盘、页面顶部概览 | +| `Tag` / `Badge` | 状态标签 | 订阅计划、用户状态 | +| `Drawer` | 侧边抽屉 | 用户详情、编辑表单 | +| `Popconfirm` | 气泡确认框 | 删除、禁用等危险操作 | + +### 5.4 继续迭代:添加仪表盘 + +```text +请帮我做一个仪表盘页面: + +1. 顶部四个统计卡片:总用户数、总文档数、今日 API 调用次数、月收入,每个卡片显示数值和环比变化(涨了还是跌了) +2. 中间放两个图表: + - 左边:最近 7 天的用户增长折线图 + - 右边:订阅计划分布饼图 +3. 底部:最近操作日志表格,显示时间、用户、操作类型、详情 + +用 Ant Design 的组件来布局,图表可以用 Ant Design Charts +``` + + + + +> **后台管理的 Vibe Coding 技巧**:后台页面结构相对固定(表格 + 搜索 + 弹窗),非常适合用 AI 批量生成。你可以先让 AI 生成一个"用户管理"页面作为模板,然后说"参考用户管理页面的结构,帮我生成文档管理页面",AI 会复用相同的布局模式。 + +## 6. 学会查文档:组件库的"说明书" + +Vibe Coding 中 AI 会帮你写大部分代码,但当 AI 生成的النتيجة不对、或者你想微调某个组件的行为时,**查文档**是最快的解决方式。 + +以 Ant Design 为例,它的文档地址是:`https://ant.design/components/overview-cn` + +查文档的标准流程: + +1. **明确需求**:比如"我需要表格支持行选择" +2. **在文档中搜索**:搜索"Table"进入表格组件页面 +3. **查看مثال**:文档中每个组件都有多个在线مثال,找到"可选择"مثال +4. **复制代码**:把مثال代码复制到你的项目中 +5. **查看 API 表格**:在页面底部找到 `rowSelection` 属性的完整配置项 + +> 你也可以把文档链接直接发给 AI IDE:"请参考 https://ant.design/components/table-cn 的 rowSelection API,帮我给用户表格加上批量选择功能"。给 AI 提供文档链接,生成的代码会更准确。 + +各组件库的文档地址速查: + +| 组件库 | 文档地址 | +| :--- | :--- | +| Ant Design | `https://ant.design/components/overview-cn` | +| shadcn/ui | `https://ui.shadcn.com/docs/components` | +| HeroUI | `https://heroui.com/docs/components` | +| Material UI | `https://mui.com/material-ui/all-components/` | +| Element Plus | `https://element-plus.org/zh-CN/component/overview.html` | + +## 7. ملخص + +三个تطبيق عملي场景覆盖了最常见的前端开发需求: + +| 场景 | 推荐组件库 | 核心特点 | +| :--- | :--- | :--- | +| 落地页 / 展示页 | HeroUI | 默认样式精美,动画流畅,视觉冲击力强 | +| 产品功能页面 | shadcn/ui | 代码完全可控,深度定制灵活 | +| 后台管理系统 | Ant Design | 业务组件丰富,表格表单开箱即用 | + +Vibe Coding 的工作流الخلاصة: + +1. 根据场景选择合适的组件库 +2. 用 AI IDE 描述你想要的页面结构和交互 +3. AI 生成初版代码,你预览效果 +4. 用自然语言继续迭代调整 +5. 遇到细节问题时查阅组件库文档 + +### تمرين + +选择以下任一场景,用 AI IDE + 组件库从零完成: + +1. 用 HeroUI 为你之前做的项目(比如霍格沃茨画像)做一个展示落地页 +2. 用 shadcn/ui 构建一个笔记应用的主界面(侧边栏 + 编辑器) +3. 用 Ant Design 构建一个简单的内容管理后台(文章列表 + 新建文章表单) + +--- + +## الملحق:更多组件库一览 + +除了正文介绍的四个核心库,前端生态中还有大量优秀的组件库。下面按框架分类列出,方便你根据项目需求选择。 + +### Vue 生态 + +| 组件库 | Stars | 简介 | 适用场景 | +| :--- | :--- | :--- | :--- | +| [Element Plus](https://element-plus.org) | ~27k | 饿了么团队打造的 Vue 3 企业级组件库,国内使用最广泛,中文生态极佳 | 中后台管理系统 | +| [Vuetify](https://vuetifyjs.com) | ~41k | 最流行的 Vue Material Design 组件库,80+ 组件,文档完善 | Google 设计风格项目 | +| [Ant Design Vue](https://antdv.com) | ~21k | 基于蚂蚁设计体系的 Vue 3 组件库,设计规范统一 | 企业级中后台 | +| [Naive UI](https://www.naiveui.com) | ~18k | TypeScript 编写,主题定制性极强,不依赖 CSS 预处理器 | 对设计有独特要求的项目 | +| [Quasar](https://quasar.dev) | ~27k | 一套代码构建 SPA、SSR、PWA、移动端和桌面端应用 | 跨平台项目 | +| [Vant](https://vant-ui.github.io/vant) | ~24k | 有赞团队开发的轻量级移动端组件库,覆盖电商常见需求 | 移动端 H5 页面 | +| [PrimeVue](https://primevue.org) | ~14k | 90+ 组件,支持多种主题(Material、Bootstrap 等) | 需要丰富组件和多主题 | +| [Arco Design Vue](https://arco.design/vue) | ~3k | 字节跳动出品,组件质量高,内置暗色模式 | 中后台产品 | +| [TDesign Vue Next](https://tdesign.tencent.com/vue-next) | ~2k | 腾讯出品,设计语言统一,覆盖桌面端常用场景 | 腾讯生态或企业级项目 | + +### React 生态 + +| 组件库 | Stars | 简介 | 适用场景 | +| :--- | :--- | :--- | :--- | +| [Material UI (MUI)](https://mui.com) | ~95k | Google Material Design 规范的老牌实现,组件最全面,生态最成熟 | 快速构建企业级应用 | +| [Ant Design](https://ant.design) | ~94k | 蚂蚁集团出品,内置大量高质量业务组件,中文开发者社区主导地位 | 企业级中后台 | +| [shadcn/ui](https://ui.shadcn.com) | ~83k | 代码复制到项目中而非 npm 安装,基于 Radix UI + Tailwind CSS,完全可控 | 需要高度定制的项目 | +| [Chakra UI](https://chakra-ui.com) | ~39k | 以开发体验为核心,API 简洁,内置无障碍访问支持 | 快速原型开发 | +| [Mantine](https://mantine.dev) | ~28k | 100+ 组件和 50+ hooks,涵盖日期选择器、富文本编辑器等高级组件 | 需要开箱即用的全功能方案 | +| [Headless UI](https://headlessui.com) | ~27k | Tailwind Labs 官方出品的无样式组件库,同时支持 React 和 Vue | 搭配 Tailwind CSS 使用 | +| [HeroUI](https://heroui.com) | ~24k | 基于 Tailwind CSS + React Aria,默认样式精美,动画流畅 | 追求视觉品质的项目 | +| [Radix UI](https://www.radix-ui.com) | ~17k | 无样式底层组件原语库,专注无障碍和组件行为,是 shadcn/ui 的底层基础 | 构建自定义设计系统 | + +#### shadcn/ui 扩展生态 + +除了上述通用组件库,shadcn/ui 生态中还涌现了大量基于其理念的扩展库,为特定场景提供差异化选择。这些扩展库同样采用"复制代码到项目"的模式,让开发者拥有完全的源码控制权。 + +| 组件库 | 简介 | 适用场景 | +| :--- | :--- | :--- | +| [Aceternity UI](https://ui.aceternity.com) | 200+ 生产级组件,主打发光卡片、文字渐变、3D 地球等特色视觉组件 | 高质感落地页、SaaS 产品 | +| [Tailark UI](https://tailark.com) | 营销网站组件块集合,产品展示、客户证言、CTA 按钮等营销高频模块 | 营销落地页、产品官网 | +| [UI Tripled](https://ui.tripled.work) | 基于 Framer Motion 的动态交互组件,弹窗、导航、卡片动画 | 创意工具、个人作品集 | +| [Neobrutalism UI](https://neobrutalism.dev) | 新粗野主义风格,粗线条、高对比度、鲜明色彩 | 个性化品牌官网、创意项目 | +| [REUI](https://reui.io) | 967+ 真实业务场景的组件组合模式 | 企业级后台、复杂表单 | +| [Cult UI](https://cult-ui.com) | 更细的交互/视觉打磨,数据表格、筛选面板等复合组件 | 高质感商业项目 | +| [Kibo UI](https://kibo-ui.com) | 高级业务组件,颜色选择器、富文本编辑器、文件上传等 | 管理后台、工具类产品 | +| [Kokonut UI](https://kokonutui.com) | 100+ 组件 + 7+ 完整模板,清新简约风格 | SaaS 官网、博客、电商 | +| [Commerce UI](https://ui.stackzero.co) | 电商场景专用,商品卡片、购物车、结算表单 | 电商平台 | +| [shadcnblocks](https://shadcnblocks.com) | 1373 个 UI 块 + 13 套完整模板,资源最全面 | 所有场景 | +| [Shoogle](https://shoogle.dev) | shadcn/ui 生态聚合检索平台 | 快速查找资源 | +| [Discover All Shadcn](https://allshadcn.com) | 聚合型资源导航 | 快速查找资源 | + +> **为什么选择 shadcn/ui 扩展?** 这些扩展继承了 shadcn/ui"代码所有权"的理念,同时为特定场景做了深度定制。Vibe Coding 时代,它们让你能快速找到符合设计需求的组件,跳出主流 UI 库的同质化,做出更具差异化的产品。 diff --git a/docs/ar-sa/stage-2/frontend/multi-product-ui/index.md b/docs/ar-sa/stage-2/frontend/multi-product-ui/index.md new file mode 100644 index 0000000..4736072 --- /dev/null +++ b/docs/ar-sa/stage-2/frontend/multi-product-ui/index.md @@ -0,0 +1,425 @@ +# تصميم الصفحات والأزرار وفقًا لإرشادات تصميم واجهة المستخدم + +很多人说"我想让页面更像 Apple 一点""按钮想做得更高级一点",但真正开始做时,往往会卡在一个问题上: + +**到底该参考什么?** + +盯着截图模仿,学到的只是"像不像"。但打开 Apple、Google、Microsoft、Atlassian 的设计规范,你会发现它们真正厉害的地方不是视觉风格,而是**把设计问题讲清楚**:页面先突出什么、按钮如何分级、操作怎么强调——这些判断标准才是核心。 + +> 参考设计规范,不是为了做得"像谁",而是学会别人怎么做判断。 + +:::: info 为什么现在还要学这些 +设计规则早已被训练进模型、被设计工具默认吸收,甚至贴几张截图 AI 就能学会。但我们仍然有必要知道这些规则从哪来、为什么这样定。 +:::: + +## 先看几段原文,感受差距 + +如果你以前觉得“设计规范不就是讲讲风格吗”,先看几条官方原文。 + +平时我们在团队里经常会这样说: + +- 做个下拉框 +- 这里放个菜单 +- 菜单栏加几个功能 +- 这里放两个按钮,一个确认一个取消 + +听起来没问题,但在大厂规范里,这些词都不是模糊概念,而是被拆得非常细。 + +| 平时随口说的话 | 官方原文 | 简单说 | +| :--- | :--- | :--- | +| “做个菜单” | Apple: [“A menu reveals its options...”](https://developer.apple.com/design/human-interface-guidelines/menus) | `Menu` 是拿来做操作的 | +| “菜单栏里放功能” | Apple: [“menu bar menus contain all the commands...”](https://developer.apple.com/design/human-interface-guidelines/menus) | 这是应用顶部的命令菜单 | +| “做个下拉框” | Apple: [“A pop-up list lets the user choose one option among several.”](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pop-up` 是从列表里选一个 | +| “也做个下拉框” | Apple: [“A pull-down list is generally used for selecting commands in a specific context.”](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pull-down` 是点开做当前操作 | +| “菜单也能拿来筛选吧” | Fluent: [“If you need to collect information from people, try a select, dropdown, or combobox instead.”](https://fluent2.microsoft.design/components/web/react/core/menu/usage) | `Menu` 不是拿来选值的 | +| “菜单也能当导航吧” | Material: [“Menus should not be used as a primary method for navigation within an app.”](https://m1.material.io/components/menus.html) | `Menu` 不是主导航 | +| “按钮随便写个 OK / Cancel” | Apple: [“Always use ‘Cancel’ to title a button that cancels the alert’s action.”](https://developer.apple.com/design/human-interface-guidelines/alerts) | 按钮文字不能随便写 | + +> 表格里的引文都可以直接点击,跳到对应的官方页面。 + +这就是第一次真正看设计规范时最容易被震到的地方: + +> 我们平时以为自己在讨论 UI,实际上很多时候只是在用一堆含糊词交流。 + +Apple 不会只说“做个菜单”;它会继续区分: + +- `menu` +- `menu bar menu` +- `pop-up button` +- `pull-down button` +- `context menu` + +Fluent 不会只说“下拉框”;它会继续区分: + +- `menu` +- `dropdown` +- `select` +- `combobox` + +这就是设计规范的必要性。 + +它不是为了让页面显得更专业,而是为了让团队在讨论 UI 时,不再每个人脑子里都是不同的东西。 + +## ما ستتعلمه + +1. 为什么设计页面和按钮时要先看设计规范 +2. Apple、Material、Fluent、Atlassian 这些规范里,哪些内容最值得参考 +3. 如何把“页面层级”和“按钮层级”设计清楚 +4. 如何让 AI 参考别人的规范来生成页面和按钮 + +## 1. 设计规范为什么能帮你把页面做清楚 + +看完上面这些原文,你会发现一个关键点: + +**设计规范不是锦上添花,而是在先把词说准。** + +很多页面不好看,不是因为配色不够高级,而是因为معلومة层级混乱。 + +很多按钮不好用,也不是因为圆角不对,而是因为: + +- 主按钮太多,用户不知道该点哪个 +- 危险按钮和普通按钮看起来差不多 +- 页面里所有按钮都在抢ملاحظة力 +- 不同页面里的按钮样式和语义不一致 + +成熟的设计规范,恰好就是在解决这些问题。它们通常会定义: + +| 规范内容 | 它解决什么问题 | +| :--- | :--- | +| **页面层级** | 先看哪里、后看哪里,معلومة怎么组织 | +| **视觉基础** | 颜色、间距、字体、圆角、阴影怎样统一 | +| **按钮层级** | 主按钮、次按钮、文字按钮、危险按钮如何区分 | +| **状态规则** | hover、focus、disabled、loading 怎么表现 | +| **交互语义** | 哪个按钮是“确认”,哪个是“取消”,哪个是“更多操作” | + +所以,设计规范真正提供的不是一套“皮肤”,而是一套**判断标准**。 + +## 2. 参考大厂规范时,重点看什么 + +### 2.1 参考 Apple:学习“定义得足够细”这件事 + +Apple 最值得学的,不只是视觉上的克制感,而是它会把概念定义得非常细。 + +同样是很多团队口中的“菜单”或“下拉框”,Apple 会继续往下拆: + +- `menu`:一组命令、选项或状态 +- `menu bar menu`:应用级命令集合 +- `pop-up button`:选择一个值 +- `pull-down button`:在当前上下文里触发命令 +- `context menu`:与当前对象或任务相关的常用动作 + +这套区分非常مهم,因为它会直接影响: + +- 这个组件是拿来选值,还是拿来做动作 +- 它属于页面局部,还是属于应用级 +- 它应该长期显示当前选中值,还是只临时展开命令 + +当你开始按这种粒度思考时,你设计出来的页面就会一下子清楚很多。 + +### 2.2 参考 Apple:学习页面层级和克制感 + +Apple Human Interface Guidelines 特别适合学习两件事: + +- 页面如何建立清晰层级 +- 控件如何在不喧宾夺主的前提下保持明确 + +Apple 强调 `Hierarchy`、`Harmony`、`Consistency`。这意味着页面设计时要回答: + +- 当前页面最مهم的معلومة是什么 +- 用户的主要任务是什么 +- 哪个操作该最显眼,哪个操作应该退后 + +如果你参考 Apple 来设计页面,可以重点借鉴: + +- 首屏معلومة不要太碎,核心内容先聚焦 +- 用留白、字号、分组建立秩序,而不是靠堆很多边框 +- 按钮不要全部高强调,只有关键动作才应该最突出 + +### 2.3 参考 Material:学习清晰的页面结构 + +Material Design 很适合学习“页面是怎么组织任务流”的。 + +它的很多组件和布局规范,核心都在帮助你明确: + +- 页面是浏览型,还是执行任务型 +- 当前页面是让用户阅读、选择,还是提交 +- 一个页面里哪些元素应该稳定重复,哪些元素应该响应上下文变化 + +如果你参考 Material 来设计页面,可以重点借鉴: + +- 页面区块清楚,模块职责明确 +- 导航、内容区、操作区分工清晰 +- 不同按钮样式对应不同操作优先级 + +### 2.4 参考 Fluent:学习组件边界和按钮层级 + +Fluent 2 很适合后台、工具型产品和复杂表单系统。它最值得学的地方,是会直接告诉你“不要混用概念”。 + +例如它明确写到:如果你要“collect information”,就不要继续用 `menu`,而应该考虑 `select`、`dropdown`、`combobox`。 + +这句话非常مهم,因为它把很多人脑中的“都差不多”打碎了。 + +Fluent 2 也很重视: + +- 操作层级 +- 组件语义边界 +- 密集معلومة场景下的清晰度 + +如果你参考 Fluent 来设计按钮,可以重点借鉴: + +- `Primary button` 用来承接当前最مهم的动作 +- `Secondary button` 用来承接支持性动作 +- `Subtle`、`Transparent` 这类弱强调按钮用于不该抢主流程的操作 +- 页面里的按钮数量越多,越要控制视觉优先级 + +### 2.5 参考 Atlassian:学习系统化地管理页面和按钮 + +Atlassian Design System 特别适合“一个团队做很多页面”的情况。它强调: + +- foundations 是共享基础 +- tokens 是统一视觉决策的方法 +- components 是被反复复用的交互构件 + +如果你参考 Atlassian 来做页面和按钮,最有价值的是: + +- 把按钮尺寸、颜色、圆角、间距做成统一规则 +- 把页面布局的节奏固定下来 +- 让不同页面虽然内容不同,但结构语言一致 + +## 3. 设计页面时,应该参考规范里的哪些点 + +当你看一个设计系统时,不要先问“这个页面好不好看”,而要先问下面几个问题。 + +### 3.1 页面第一眼,主次是不是明确 + +一个页面通常至少要有三层: + +- **主معلومة**:当前页面最مهم的内容 +- **辅助معلومة**:帮助理解或补充的内容 +- **次级操作**:不应该干扰主任务的动作 + +如果三层没有拉开,页面就会“都مهم”,等于“都不مهم”。 + +### 3.2 页面布局,是不是服务任务而不是堆模块 + +参考规范时,可以特别ملاحظة: + +- 标题区有没有明确页面目标 +- 主内容区是不是围绕任务组织 +- 操作按钮是不是贴近相关内容 +- 次要معلومة有没有被弱化 + +### 3.3 页面里的操作,是不是有优先级 + +很多页面一眼看过去有 6 个按钮,النتيجة每个按钮都像 CTA,这是典型的层级失控。 + +更合理的方式是: + +- 一个区域通常只有一个主动作 +- 次级动作可以用描边、文字按钮或更弱的样式 +- 风险动作不要和主动作长得一样 + +## 4. 设计按钮时,应该参考规范里的哪些点 + +按钮是最容易被“随手设计”的部分,但也是最能暴露系统是否成熟的部分。 + +### 4.1 按钮先分“语义”,再分“样式” + +不要先想“蓝色按钮还是黑色按钮”,先想这个按钮是什么角色。 + +常见按钮角色可以这样分: + +| 按钮类型 | 作用 | 常见样式策略 | +| :--- | :--- | :--- | +| **Primary** | 当前区域最关键动作 | 实心、高对比、最显眼 | +| **Secondary** | 支持性动作 | 描边或低一级强调 | +| **Tertiary / Text** | 弱操作 | 文字或低视觉占比 | +| **Destructive** | 删除、停用、清空等风险操作 | 警示色或明确风险样式 | +| **Icon button** | 局部工具操作 | 简洁、靠近上下文 | + +### 4.2 一个页面不要有太多 Primary Button + +这是很多新手最容易踩的坑。 + +如果页面上有 4 个主按钮,那么等于没有主按钮。主按钮的意义本来就是“告诉用户现在最应该做什么”。 + +你可以借鉴很多设计系统的共同做法: + +- 一个主要区域通常只保留一个主按钮 +- 取消、返回、关闭一般不和确认按钮抢同级 +- 更多操作放到次级按钮或菜单中 + +### 4.3 按钮要能表达状态变化 + +设计规范通常会对按钮状态写得很清楚: + +- 默认态 +- 悬停态 +- 聚焦态 +- 禁用态 +- 加载态 +- 危险态 + +这很مهم,因为按钮不是一张静态图,而是用户操作过程中最常被触发的控件之一。 + +### 4.4 按钮文案,也属于设计的一部分 + +按钮文案不只是“文案问题”,它直接影响用户理解。 + +例如: + +- `保存` +- `保存更改` +- `立即发布` +- `删除项目` +- `移到回收站` + +这些文案传达的心理预期完全不同。成熟规范通常会要求按钮标签清楚表达动作,而不是使用含糊词。 + +## 5. 一个很实用的页面与按钮设计清单 + +你自己设计页面时,可以先快速过一遍这张清单: + +### 页面清单 + +- 页面标题是否清楚说明当前任务 +- 首屏最مهم的معلومة是否一眼可见 +- 页面是不是按任务流程组织,而不是按想到什么放什么 +- 同一个区域里是否只有一个主要动作 +- 次要内容是否被适当弱化 + +### 按钮清单 + +- 这个按钮是主动作还是次动作 +- 它为什么值得比别的按钮更显眼 +- 页面里是不是有太多主按钮 +- 危险操作是否被明确标识 +- 按钮文案是否足够具体 + +## 6. 怎样用 AI 参考别人的规范来设计页面 + +这一节最实用。 + +很多人让 AI 设计页面时,只会说: + +```md +帮我做一个设置页面,要高级一点,参考苹果风格 +``` + +这类نصيحة词太模糊了,AI 最后通常只能模仿“白底、圆角、阴影”。 + +对新手来说,更实用的方式不是自己الخلاصة一大段,而是直接把**规范原文里的关键句**贴给 AI。 + +这样做有两个好处: + +- 你不用自己先“翻译”一遍设计思想 +- AI 更容易按官方定义去理解页面和按钮 + +### 6.1 例子一:让 AI 参考 Apple 设计一个设置页面 + +先找一句 Apple 原文: + +> ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) + +你可以直接这样贴给 AI: + +```md +参考 Apple Human Interface Guidelines 里的这句话: +"Establish a clear visual hierarchy..." + +帮我设计一个账号安全设置页面。 +要求页面层级清楚,مهممعلومة放前面,分组整齐一点。 +``` + +这样写的重点是:不用你自己解释太多,直接把 Apple 的原话贴进去。 + +### 6.2 例子二:让 AI 参考 Fluent 设计后台页面按钮 + +先找一句 Fluent 原文: + +> ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +你可以直接这样贴给 AI: + +```md +参考 Fluent 2 里的这句话: +"Only use one primary button in a layout..." + +帮我设计一个团队管理后台的按钮。 +添加成员按钮最明显,导出、筛选、更多操作弱一点,删除按钮单独突出。 +``` + +这一句非常适合新手,因为它直接告诉 AI:一个区域不要放太多主按钮。 + +### 6.3 例子三:让 AI 同时参考页面规范和按钮规范 + +你也可以一次贴两句原文,让 AI 同时参考页面和按钮: + +> Apple: ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) +> +> Fluent: ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +然后直接这样写: + +```md +参考下面两句设计规范原文: +Apple: "Establish a clear visual hierarchy..." +Fluent: "Only use one primary button in a layout..." + +帮我设计一个项目详情页。 +页面包含项目介绍、成员、最近活动和设置入口。 +页面层级清楚一点,主按钮只保留一个,其他按钮弱一点。 +``` + +这种方式特别适合新手,因为你只要会复制原文,再加两句自己的需求就够了。 + +## 7. 怎样用 AI 参考按钮规范来直接生成按钮设计 + +如果你只想先做按钮,也可以直接贴按钮规范原文。 + +例如 Atlassian 对按钮的定义很短: + +> ["A button triggers an event or action."](https://atlassian.design/components/button/) + +你可以这样问 AI: + +```md +参考 Atlassian 的这句话: +"A button triggers an event or action." + +帮我设计一套后台页面按钮样式。 +我要有主按钮、次按钮、删除按钮,顺便告诉我分别用在什么地方。 +``` + +这类نصيحة词尤其适合新手,基本就是“贴原文 + 说需求”。 + +## 8. ملخص + +参考 UI 设计规范设计页面和按钮,最مهم的不是“做得像谁”,而是学会下面这几件事: + +1. 用层级组织页面,而不是把内容堆上去 +2. 用按钮分级表达操作优先级,而不是让所有按钮都一样抢眼 +3. 用设计规范里的定义、边界和判断标准指导设计 +4. 让 AI 参考别人规范时,参考的是“原则和结构”,而不是只参考皮肤 + +当你这样使用规范时,你参考到的就不只是一个风格,而是一套成熟的设计思考方式。 + +--- + +## المراجع + +以下链接都来自官方设计系统或官方文档: + +- Apple Human Interface Guidelines: [Overview](https://developer.apple.com/design/human-interface-guidelines/) +- Apple Human Interface Guidelines: [Menus](https://developer.apple.com/design/human-interface-guidelines/menus) +- Apple Human Interface Guidelines: [Alerts](https://developer.apple.com/design/human-interface-guidelines/alerts) +- Apple Human Interface Guidelines: [Buttons](https://developer.apple.com/design/human-interface-guidelines/buttons) +- Apple Archive: [How Menus Work](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/HowMenusWork.html) +- Apple Archive: [Managing Pop-Up Buttons and Pull-Down Lists](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) +- Material Design: [Buttons overview](https://m3.material.io/components/buttons/overview) +- Material Design: [Menus](https://m1.material.io/components/menus.html) +- Microsoft Fluent 2: [Start designing](https://fluent2.microsoft.design/get-started/design) +- Microsoft Fluent 2: [Menu usage](https://fluent2.microsoft.design/components/web/react/core/menu/usage) +- Microsoft Fluent 2: [Button usage](https://fluent2.microsoft.design/components/web/react/core/button/usage) +- Atlassian Design System: [Foundations](https://atlassian.design/foundations/) +- Atlassian Design System: [Button](https://atlassian.design/components/button/) diff --git a/docs/ar-sa/stage-2/frontend/ui-design/index.md b/docs/ar-sa/stage-2/frontend/ui-design/index.md new file mode 100644 index 0000000..81b0785 --- /dev/null +++ b/docs/ar-sa/stage-2/frontend/ui-design/index.md @@ -0,0 +1,3 @@ +# بناء أول تطبيق حديث - تصميم واجهة المستخدم + +> هذا الفصل قيد الكتابة، ترقبوه... diff --git a/docs/ar-sa/stage-2/index.md b/docs/ar-sa/stage-2/index.md index 46263bb..97c5b75 100644 --- a/docs/ar-sa/stage-2/index.md +++ b/docs/ar-sa/stage-2/index.md @@ -1,125 +1,192 @@ -# التطوير الشامل +# التطوير للمبتدئين والمتوسطين -مرحبًا بك في مرحلة **التطوير الشامل**! هنا ستتعمق في التطوير الشامل، وتتقن تكوين المكونات الأمامية، وتصميم قواعد البيانات، وتطوير واجهات برمجة التطبيقات الخلفية، والنشر. +مرحبًا بك في مرحلة **التطوير للمبتدئين والمتوسطين**! هنا ستتعمق في التطوير الشامل، وتتقن تكوين المكونات الأمامية، وتصميم قواعد البيانات، وتطوير واجهات برمجة التطبيقات الخلفية والنشر. ## ما ستتعلمه ### تطوير الواجهة الأمامية إتقان تطوير الواجهة الأمامية الحديثة وتعلم استخدام مكتبات المكونات وأدوات التصميم: + + + + +### تطوير الواجهة الخلفية -### الواجهة الخلفية والتطوير الشامل +تعلم تصميم واجهات برمجة التطبيقات وإدارة قواعد البيانات واستراتيجيات نشر التطبيقات: -تعلم تصميم واجهات برمجة التطبيقات، وإدارة قواعد البيانات، واستراتيجيات نشر التطبيقات: - - - + + +### المشاريع الكبرى -### الواجبات +الفصول السابقة تُعلّمك "القطع"، أما المشاريع الكبرى فتُعلّمك "كيفية تجميع القطع في منتج يعمل ويمكن عرضه ونشره". + +يُنصح باتباع ترتيب **المشروع الكبير 1 ← المشروع الكبير 2**: + +- **المشروع الكبير 1** يأخذك أولاً عبر المسار الرئيسي الأكثر شيوعًا في SaaS الحديثة: تسجيل الدخول، الإنشاء، قاعدة البيانات، الدفع، لوحة الإدارة. +- **المشروع الكبير 2** يأخذك إلى سيناريو أشبه بالأنظمة التجارية: أدوار وصلاحيات، بنك أسئلة، امتحانات، سجلات الإرسال، ولوحة الإدارة. + +```mermaid +flowchart LR + A["صفحات ومكونات الواجهة الأمامية"] --> B["قاعدة البيانات والواجهات"] + B --> C["المشروع الكبير 1
SaaS توليد النصوص"] + C --> D["الدفع / النشر / إدارة الخلفية"] + D --> E["المشروع الكبير 2
نظام الامتحانات عبر الإنترنت"] + E --> F["مجموعة أعمال شاملة كاملة"] +``` + +إذا كنت لا تعرف أيهما تبدأ به، يمكنك الرجوع إلى جدول المقارنة التالي: + +| المشروع | ما ستتدرب عليه بشكل أساسي | لمن هو الأنسب | المخرجات النهائية | +|------|------|------|------| +| المشروع الكبير 1: موقع توليد النصوص | هيكل صفحة SaaS، تسجيل دخول المستخدم، إنشاء AI، دفع Stripe، إدارة الخلفية | من يصنع موقعًا تجاريًا متكاملًا لأول مرة | نموذج أولي SaaS قابل للتسجيل والإنشاء والدفع والإدارة | +| المشروع الكبير 2: نظام الامتحانات عبر الإنترنت | أدوار وصلاحيات، نمذجة بنك الأسئلة، عملية الامتحانات، سجلات الإرسال، التصحيح والإحصاءات | من يريد بناء "نظام تجاري" بشكل متكامل حقًا | منصة امتحانات بها جانب طالب وجانب إدارة | + +أيًا كان المشروع الذي تختاره، يُنصح بتجهيز هذه المخرجات الثلاثة على الأقل: + +- مستودع مشروع قابل للتشغيل +- رابط عرض تجاري قابل للوصول +- ملف README وفيديو عرض توضيحي -تعزيز مهارات التطوير الشامل الخاصة بك من خلال المشاريع العملية: +إذا أكملت المشروعين الرئيسيين أعلاه، أو كنت تريد بناء مجموعة أعمال حسب مسارك التقني، يمكنك الاستمرار في اختيار مشروع من المواضيع الموسعة التالية: + + + + + + + + + ### توسيع قدرات الذكاء الاصطناعي + - - ## لمن هذا -- المطورون الذين لديهم بعض الأساسيات في البرمجة ويرغبون في تعلم التطوير الشامل بشكل منهجي -- المتعلمون الذين يرغبون في الانتقال من مدير المنتج إلى مهندس شامل +- المطورون الذين لديهم أساسيات في البرمجة ويرغبون في تعلم التطوير الشامل بشكل منهجي +- المتعلمون الذين يرغبون في الانتقال من مدير منتج إلى مهندس شامل - المطورون من المبتدئين إلى المتوسطين الذين يرغبون في إتقان أدوات التطوير الحديثة وسير العمل - رواد الأعمال الذين يرغبون في تطوير منتجات كاملة بشكل مستقل ## المتطلبات الأساسية -- إكمال مرحلة "المبتدئون ونموذج المنتج"، أو امتلاك معرفة أساسية مكافئة +- إكمال مرحلة "المبتدئين ونموذج المنتج"، أو امتلاك معرفة أساسية مكافئة - فهم المفاهيم الأساسية لـ HTML/CSS/JavaScript - امتلاك معرفة أولية حول أدوات برمجة الذكاء الاصطناعي diff --git a/docs/de-de/stage-2/ai-capabilities/dify-knowledge-base/index.md b/docs/de-de/stage-2/ai-capabilities/dify-knowledge-base/index.md new file mode 100644 index 0000000..67491d9 --- /dev/null +++ b/docs/de-de/stage-2/ai-capabilities/dify-knowledge-base/index.md @@ -0,0 +1,461 @@ +# Dify-Einfuehrung und Wissensdatenbank-Integration + +# Rueckblick auf die letzte Lektion + +In den vorherigen Lektionen haben wir in Gruppen die Grundlagen von KI-Programmierung, Prompt-Engineering und KI-Bildgenerierung gelernt. + +Um dir beim Rueckblick zu helfen, hier einige Fragen: + +1. Was ist KI-Programmierung? Wie verwendet man KI-Programmierwerkzeuge (z. B. [z.ai](http://z.ai)), um eine Webseite zu erstellen? +2. Was sind grosse Sprachmodelle? Was ist Prompt-Engineering und Kontext-Engineering? +3. Wie unterscheiden sich die Modellfaehigkeiten in den drei Richtungen Text, KI-Coding und Bildgenerierung? +4. Was ist eine API? Wie verwendet man [z.ai](http://z.ai) fuer den Zugriff auf Drittanbieter-APIs? + +In dieser Lektion gehen wir ueber einfache KI-Text- und Bild-Werkzeuge hinaus und betreten Workflow-Erstellungsplattformen, die naeher an realen Geschaefsablaeufen sind. Vom Chatbot zum KI-Agenten und KI-Workflow, und ueber die API wird er zu einer interaktiven "intelligenten" Roboterseite. + +# Was du in dieser Lektion lernen wirst + +1. Warum der Uebergang vom Chatbot zum Agenten und zur Workflow-Orchestrierung notwendig ist. +2. Was ist eine Agenten- und Workflow-Entwicklungsplattform und wie man KI-Faehigkeiten standardisiert und orchestrierbar macht. +3. Was ist Dify und wie man mit dieser Open-Source-Plattform fuer LLM-Anwendungen schnell Anwendungen erstellt, insbesondere Wissensdatenbank-Frage-Antwort-Roboter. +4. RAG-Implementierungsmethoden und Wert: Warum braucht man Retrieval-Augmented Generation? +5. Wie man von 0 auf 1 Dify und das KI IDE Trae erlernt. + +# 1. Vom Dialog zum Agenten + +In der vorherigen Phase haben wir gelernt, wie man Prompts verwendet, um grosse Modelle in Rollen zu versetzen. Aber wenn man genau darueber nachdenkt, stellt man fest: Ein Chatbot allein kann nicht handeln. + +Er kann beschreiben, wie man Bestellungen prueft, aber nicht tatsaechlich in der Datenbank nachschlagen. Er kann beschreiben, was ein Wochenbericht enthalten sollte, aber nicht automatisch Projektdaten zusammenfassen und E-Mails senden. + +Um die KI vom Chat-Partner zum digitalen Mitarbeiter zu machen, muessen wir ihr drei Kernfaehigkeiten geben: + +1. **Exklusives Wissen** - Zugriff auf Produktdokumentation, Kundendaten, interne Richtlinien +2. **Werkzeugaufruf (Plugins)** - Datenbanken bedienen, APIs aufrufen +3. **Strukturierte Ausfuehrung** - Aufgaben nach vorgegebenem Ablaufplan erledigen + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image1.png) + +## 1.1 Einfachster Agent: Frage-Antwort-Roboter basierend auf Wissensdatenbank + +Die am weitesten verbreitete Form eines einfachen Agenten ist der Wissensdatenbank-Frage-Antwort-Roboter. Sein Durchbruch: Die Antworten des grossen Modells werden nicht mehr frei generiert, sondern basieren auf tatsaechlichen Quellen. Die Loesung dafuer ist RAG (Retrieval-Augmented Generation). + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image2.png) + +Bildquelle: [https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag](https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image3.png) + +Bildquelle: [https://www.databricks.com/glossary/retrieval-augmented-generation-rag](https://www.databricks.com/glossary/retrieval-augmented-generation-rag) + +## 1.2 Vom Dialog-Agenten zum Workflow + +Selbst ein "verstaerkter Agent" mit Wissensdatenbank und Plugin-Aufruf reicht fuer komplexere Geschaefsprozesse nicht aus. Dies fuehrt zum hoeheren KI-Anwendungsparadigma: **KI-Workflow**. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image4.png) + +Ein Workflow zerlegt eine komplexe Aufgabe in mehrere geordnete, konfigurierbare und automatisch ausfuehrbare Teilschritte und orchestriert ihre logischen Beziehungen ueber visuelle oder codebasierte Methoden. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image5.png) + +## 1.3 Haeufige Agenten-/Workflow-Plattformen + +| Plattform | Merkmale | Anwendungsbereich | +| --------- | --------- | ----------------- | +| Dify | Open-Source, RAG, LLM-Orchestrierung, API-Ausgabe | Unternehmens-Wissensdatenbank, massgeschneiderte Agenten | +| Coze (ByteDance) | In China verfuegbar, reichhaltige Plugins | Social-Bots, Mini-Programm-Integration | +| n8n | Universelle Automatisierung, API-Orchestrierung | Datensynchronisation, SaaS-Automatisierung | + +### 1.3.1 Dify + +Dify ist eine LLM-Anwendungsentwicklungs- und Betriebsplattform mit Fokus auf den gesamten Lebenszyklus von KI-Anwendungen. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image6.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image7.png) + +### 1.3.2 Coze (ByteDance) + +Coze ist eine KI-Agenten-Entwicklungsplattform von ByteDance mit Fokus auf extreme Benutzerfreundlichkeit. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image8.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image9.png) + +### 1.3.3 n8n + +n8n ist eine universelle programmierbare Workflow-Automatisierungsplattform. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image10.png) + +# 2. Dify im Detail + +## 2.1 Was ist Dify? + +Besuche [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps) oder die Website https://dify.ai. + +Dify ist eine Open-Source-Plattform zur Entwicklung von LLM-Anwendungen. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image11.png) + +### 2.1.1 Eigenes Dify bereitstellen (optional) + +Du musst das Tutorial zur Web-Bereitstellung konsultieren: [Web-Anwendungen bereitstellen](/de-de/stage-2/backend/zeabur-deployment/) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image13.png) + +## 2.2 Erste Dify-Chatbot-Anwendung erstellen + +Besuche [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps), registriere dich und melde dich an. Waehle "Studio" und klicke auf "CREATE APP" > "Create from Blank". + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image14.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image15.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image16.png) + +Waehle "Chatbot" als App-Typ, gib Name und Beschreibung ein und klicke auf "Erstellen". + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image17.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image18.png) + +Im mittleren Bereich "INSTRUCTIONS" kannst du System-Prompts eingeben. Rechts befindet sich das Debug-Fenster. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image19.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image20.png) + +## 2.3 Benutzerdefinierte Modellanbieter konfigurieren + +1. Installiere die Plugins `OpenAI-API-compatible` und `SiliconFlow`: + - https://marketplace.dify.ai/plugins/langgenius/openai_api_compatible + - https://marketplace.dify.ai/plugins/langgenius/siliconflow + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image21.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image22.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image23.png) + +2. Konfiguriere die Modelle: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image24.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image25.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image26.png) + +3. Ueberpruefe die Modellliste: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image27.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image28.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image29.png) + +## 2.4 Erste Dify-Wissensdatenbank erstellen + +Klicke oben im Menue auf "Knowledge" und dann auf "Create Knowledge". + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image30.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image31.png) + +Lade verschiedene Dateitypen hoch (PDF, TXT usw.), um die Wissensdatenbank zu erstellen. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image32.png) + +Konfiguriere die Embedding- und Rerank-Modelle: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image33.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image34.png) + +Klicke auf "Save & Process": + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image35.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image36.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image37.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image38.png) + +Teste die Wissensdatenbank mit "Retrieval Testing": + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image39.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image40.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image41.png) + +Verbinde die Wissensdatenbank mit deinem Agenten: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image42.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image43.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image44.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image45.png) + +## 2.5 Weitere Dify-Operationen + +### 2.5.1 Workflow-Import und -Export + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image46.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image47.png) + +### 2.5.2 Weitere Dify-Projekte ansehen + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image48.png) + +## 2.6 Erste Dify-Workflow-Anwendung erstellen + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image49.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image50.png) + +Waehle zwischen Chatflow (fuer fortlaufende Gespraeche) und Workflow (fuer Aufgabenautomatisierung). + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image51.png) + +### 2.6.1 Haeufige Knoten + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image52.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image53.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image54.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image55.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image56.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image57.png) + +### 2.6.2 Haeufige Werkzeuge + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image58.png) + +### 2.6.3 Einfachen Intent-Klassifizierungs-Workflow erstellen + +Wir erstellen einen Workflow fuer ein Restaurantszenario mit vier Intent-Kategorien: + +- **Essen bestellen (buy_food)**: Benutzer moechte etwas bestellen +- **Beschwerde (complain)**: Benutzer aeussert Unzufriedenheit +- **Plaudern (chitchat)**: Allgemeine Fragen und Empfehlungen +- **Sonstiges (other)**: Nicht restaurantbezogene Themen + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image59.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image60.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image61.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image62.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image63.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image64.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image65.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image66.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image67.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image68.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image69.png) + +## 2.7 Vorlagen-Workflow ausfuehren + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image70.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image71.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image72.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image73.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image74.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image75.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image76.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image77.png) + +## 2.8 Dify als API-Anbieter nutzen + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image78.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image79.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image80.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image81.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image82.png) + +## 2.9 Frontend-Chat-Anwendung mit Dify-API erstellen + +Klicke auf "Publish" > "Publish Update" > "Access API Reference". + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image83.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image84.png) + +Finde "Send Chat Message" und kopiere Request und Response Beispiele. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image85.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image86.png) + +Erstelle einen API-Key: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image87.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image88.png) + +```json +key: +app-zKdCHUXXXXXXXX + +Please write me a front-end based on the following reference: + +curl -X POST 'http://{DIFY_API_URL}/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123" +}' +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image89.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image90.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image91.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image92.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image93.png) + +# 3. Weitere Geschaefsworkflow-Referenzen + +## 3.1 Social-Media-Workflows + +1. Plattformuebergreifende Content-Verbreitung (komplex) +2. Trending-Topic-Auswahl und Entwurfsgenerator (mittel) +3. Intelligente Kommentarklassifikation und Antwort-Assistent (komplex) +4. Kurzvideo-Skript- und Storyboard-Generator (komplex) +5. Live-Interaktion Q&A Echtzeit-Zusammenfassung (mittel) + +## 3.2 Arbeitsplatz-Workflows + +1. Intelligente Besprechungsprotokolle und automatische Aufgabenverteilung (komplex) +2. Lebenslauf-Stapelscreening und Erstbewertung (mittel) +3. Mehrsprachige E-Mail-Uebersetzung und Entwurfsantwort (einfach) +4. Wochen-/Monatsbericht-Datenaggregation (komplex) +5. Vertrag/Dokument intelligente Pruefung (mittel) + +## 3.3 Lern- und Lebensworkflows + +1. Akademische Arbeit Analyse und Notizgenerator (komplex) +2. Personalisierter Reiseplanungsassistent (mittel) +3. Fremdsprachen-Lernpraxispartner (einfach) +4. Persoenlicher Wissensdatenbank-Frage-Antwort- und Empfehlungssystem (komplex) +5. Fitness-/Ernaehrungsplan Tracking-Berater (mittel) + +# 6. Einschraenkungen von Workflow-Plattformen + +Workflow-Plattformen (Low-Code-Plattformen) sind keine Universalloesungen. "Low-Code" ist oft auch eine Art "High-Code" - Benutzer muessen die Konzepte, Regeln und Bedienlogik der Plattform verstehen. + +Mit der schnellen Entwicklung von Vibe Coding kann das direkte Lesen oder Generieren von Code mit KI-Unterstützung manchmal effizienter sein. + +# Hausaufgabe + +## Dify-Grundoperationen meistern + +1. Referenziere die Intent-Klassifizierungs-Workflow-Methode und lass die KI ein vollstaendig anderes Szenario vorschlagen. +2. Login-Workflow-Entschluesselungs-Challenge +3. Love-Loop-Workflow-Entschluesselungs-Challenge + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image94.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image95.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image96.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image97.png) + +## Dify-API-Aufruf implementieren + +1. Stelle Dify bereit und erstelle eine einfache Wissensdatenbank. +2. Verwende Trae IDE, um ein Chat-Frontend zu erstellen, das mit der Dify-Wissensdatenbank ueber API interagiert. +3. Teste Mehrfach-Chat-Ergebnisse. + +## Drittanbieter-Workflow ausprobieren + +Finde einen Dify-Workflow auf Github, in WeChat oder anderen Plattformen und fuehre ihn erfolgreich aus. + +# [Bug] Loesung fuer HTTP-Anfragefehler + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image98.png) + +Wenn du dieses Problem hast, verwende Zeabur als Netzwerk-Weiterleitungs-Gateway: + +- Originaladresse: `http://{DIFY_API_URL}/v1/chat-messages` +- Neue Adresse: `https://{DIFY_NEW_API_URL}.zeabur.app/v1/chat-messages` + +```python +from flask import Flask, request, Response +import requests + +app = Flask(__name__) + +TARGET_BASE_URL = "{DIFY_API_URL}" +LISTEN_PORT = 8080 + +@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +@app.route('/', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +def proxy_request(path): + target_url = f"{TARGET_BASE_URL}/{path}" + if request.query_string: + target_url += f"?{request.query_string.decode('utf-8')}" + + headers = {key: value for key, value in request.headers if key.lower() not in ['host', 'connection', 'content-length', 'accept-encoding']} + + try: + resp = requests.request( + method=request.method, + url=target_url, + headers=headers, + data=request.get_data(), + cookies=request.cookies, + allow_redirects=False, + timeout=30 + ) + + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + response_headers = [(name, value) for name, value in resp.raw.headers.items() if name.lower() not in excluded_headers] + + return Response(resp.content, resp.status_code, response_headers) + + except requests.exceptions.RequestException as e: + print(f"Error forwarding request to {target_url}: {e}") + return Response(f"Proxy Error: Could not reach target server or invalid response: {e}", status=502) + except Exception as e: + print(f"An unexpected error occurred: {e}") + return Response(f"Internal Proxy Error: {e}", status=500) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=LISTEN_PORT, debug=True) +``` diff --git a/docs/de-de/stage-2/assignments/copywriting-platform-supabase/index.md b/docs/de-de/stage-2/assignments/copywriting-platform-supabase/index.md new file mode 100644 index 0000000..2ba260a --- /dev/null +++ b/docs/de-de/stage-2/assignments/copywriting-platform-supabase/index.md @@ -0,0 +1,244 @@ +# KI-Marketing-Copywriting SaaS Entwicklungspraxis + +## Ueberblick + +Dieses Praxisprojekt erfordert die Umsetzung eines echten PRD von Grund auf: Ein KI-Marketing-Copywriting SaaS-Produkt fuer Indie-Entwickler und Content-Teams. Du wirst Supabase als Backend-Service und Stripe als Zahlungssystem verwenden und den gesamten Prozess von der Anforderungsanalyse bis zur Bereitstellung abschliessen. + +Dies ist die umfassende Praxisphase von Stage 2. In den vorherigen Kapiteln hast du einzelne Faehigkeiten gelernt - Frontend, Backend, Datenbank, Zahlungsintegration. Dieses Projekt erfordert die Verkettung aller Faehigkeiten zur Lieferung eines lauffaehigen Produktprototyps. + +## Vorkenntnisse + +- Frontend-Design und Komponentenbibliotheken ([UI-Design](../../frontend/ui-design/), [Moderne Komponentenbibliothek](../../frontend/modern-component-library/)) +- Backend-API-Design und Entwicklung ([API-Code schreiben](../../backend/ai-interface-code/)) +- Datenbankgrundlagen und Supabase ([Von der Datenbank zu Supabase](../../backend/database-supabase/)) +- Zahlungsintegration ([Stripe-Zahlungssystem](../../backend/stripe-payment/)) +- Git-Workflow und Bereitstellung ([Git und GitHub](../../backend/git-workflow/), [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/)) + +## Lernziele + +Nach Abschluss dieser Praxis wirst du in der Lage sein: + +1. Einen echten PRD zu lesen und eine Entwicklungsaufgabenliste zu extrahieren +2. KI-gestuetzt schrittweise Frontend-Seiten und Backend-APIs zu generieren +3. Supabase fuer Benutzerauthentifizierung und Datenbankoperationen zu verwenden +4. Stripe fuer Abo-Zahlungsfunktionen zu integrieren +5. Ein Admin-Dashboard zu erstellen und End-to-End-Tests abzuschliessen + +## Projektuebersicht + +Das zu erstellende Produkt ist eine KI-Marketing-Copywriting SaaS mit drei Subsystemen: + +| Subsystem | Verantwortung | +|-----------|---------------| +| **Oeffentliche Website** | Produktvorstellung, Preisgestaltung, FAQ, Registrierungskonvertierung | +| **Benutzer-Arbeitsbereich** | Produktinformationen eingeben, Copy generieren, Verlauf anzeigen, Plan upgraden | +| **Admin-Dashboard** | Benutzerverwaltung, Generierungsaufzeichnungen, Zahlungsdaten, Betriebsuebersicht | + +::: tip PRD-Zugang +Die Anforderungen fuer dieses Projekt befinden sich auf GitHub: [PRD ansehen](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/copywriting-platform-supabase/PRD.md) +::: + +
+ + + +
+ +## Teil 1: Anforderungsanalyse + +### 1.1 PRD lesen + +Beantworte folgende Fragen: +- Wie viele Einstiegspunkte hat das System? Welche Seiten deckt jeder ab? +- Was ist die Kernfunktion jeder Seite? +- Welche Module und Datenbanktabellen enthaelt das Backend? +- Wie sind Preisgestaltung, Zahlungsablauf und kostenlose Kontingente gestaltet? +- Was ist der MVP-Umfang? + +::: warning +Wenn diese Fragen keine klaren Antworten haben, beginne nicht mit dem Code. Unklare Anforderungen sind die haeufigste Ursache fuer Nachbesserungen. +::: + +### 1.2 Systemarchitektur bestaetigen + +```mermaid +flowchart TD + prd["PRD"] --> web["Oeffentliche Website"] + prd --> app["Benutzer-Arbeitsbereich"] + prd --> admin["Admin-Dashboard"] + app --> auth["Auth"] + app --> gen["Copy-Generierung"] + gen --> db["Datenbank"] + billing["Zahlung und Plaene"] --> db + admin --> analytics["Benutzer-/Generierungs-/Zahlungs-Dashboard"] +``` + +## Teil 2: Projektgeruest erstellen + +### 2.1 Frontend-Seiten generieren + +Prompt-Referenz: + +```text +Bitte generiere basierend auf dem aktuellen PRD ein Frontend-Geruest fuer eine KI-Marketing-Copywriting SaaS. + +Anforderungen: +1. Drei Einstiegspunkte: www, app, admin +2. Website: Startseite, Preisgestaltung, FAQ +3. App: Login, Registrierung, Dashboard, Verlauf, Plan-Seite +4. Admin: Startseite, Benutzerverwaltung, Generierungsaufzeichnungen, Zahlungen +5. Zunaechst nur Seitenstruktur mit Mock-Daten, keine echten APIs +6. Stil wie eine moderne SaaS, nicht wie ein Klassenzimmer-Demo +``` + +### 2.2 Kernseite Dashboard verfeinern + +```text +Bitte verfeinere die /dashboard Seite. + +Felder im linken Formular: +- Produktname +- Ein-Satz-Beschreibung +- Zielbenutzer +- 3 Verkaufsargumente +- Vertriebskanaele + +Rechte Ergebnisbereich: +- Hauptueberschrift, Unterueberschrift, CTA +- 3 kurze Copy-Varianten +- Lange Copy +``` + +### 2.3 Seitenstruktur ueberpruefen + +- [ ] Drei Einstiegspunkte mit unabhaengigen Routen +- [ ] Seitenanzahl stimmt mit PRD ueberein +- [ ] Dashboard-Layout mit Formular und Ergebnisbereich +- [ ] Mock-Daten zeigen grundlegende UI-Zustaende + +### Hilfe bei Blockaden? + +Wenn du beim Frontend-Aufbau feststeckst, kannst du diese Kapitel ueberpruefen: + +- [UI-Design](../../frontend/ui-design/) +- [Moderne Komponentenbibliothek](../../frontend/modern-component-library/) +- [Von Design zu Code](../../frontend/design-to-code/) + +## Teil 3: Backend-Integration + +### 3.1 Supabase-Login integrieren + +```text +Bitte hilf mir Schritt fuer Schritt bei der Supabase-Login-Integration. + +1. Projekt mit Supabase verbinden +2. Registrierung, Login, Logout implementieren +3. Nach Login zu /dashboard weiterleiten +4. Geschuetzte Seiten automatisch zu /login umleiten +5. profiles-Tabelle erstellen +6. Nach Registrierung automatisch Datensatz in profiles erstellen +``` + +### 3.2 Generierungs-API und Datenbank integrieren + +```text +Bitte hilf mir bei der Implementierung der Kernfunktion: Marketing-Copy generieren und speichern. + +1. Benutzer fuellt Formular aus und klickt "Copy generieren" +2. Backend erhaelt: Produktname, Beschreibung, Zielbenutzer, Verkaufsargumente, Kanaele +3. Backend ruft Modell zur Generierung auf +4. Seite zeigt Ergebnisse +5. Eingabe und Ausgabe werden in der Datenbank gespeichert +6. Benutzer kann beim naechsten Besuch den Verlauf sehen +``` + +### 3.3 Stripe-Zahlung integrieren + +```text +Bitte hilf mir bei der einfachsten Stripe-Zahlungsintegration. + +1. /billing-Seite zeigt free und pro Plaene +2. Nach Klick auf Upgrade Weiterleitung zu Stripe Checkout +3. Nach Zahlung Rueckkehr zur Website +4. Zahlergebnis in subscriptions-Tabelle speichern +5. profile.plan-Feld aktualisieren +6. Free-Benutzer: max. 3 Generierungen/Tag, Pro: unbegrenzt +``` + +### 3.4 Admin-Dashboard erstellen + +```text +Bitte hilf mir beim Aufbau eines einfachen Admin-Dashboards. + +1. Nur role = admin Benutzer koennen auf /admin zugreifen +2. Drei Tabs: Benutzerliste, Generierungsaufzeichnungen, Abostatus +3. Benutzerliste: E-Mail, Plan, Erstellungsdatum +4. Generierungsaufzeichnungen: Benutzer, Produktname, Kanal, Datum +5. Abostatus: Benutzer, Plan, Zahlungsstatus +``` + +## Teil 4: Test und Bereitstellung + +### 4.1 End-to-End-Tests + +Mindestens folgende Szenarien validieren: +- Registrierung > Login > Copy generieren > Verlauf anzeigen > Plan upgraden +- Admin-Login > Benutzerdaten anzeigen > Generierungsaufzeichnungen > Zahlungsstatus + +### 4.2 Bereitstellung + +Projekt oeffentlich bereitstellen. Siehe: [Git und GitHub](../../backend/git-workflow/), [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/). + +## Liefergegenstaende + +- [ ] Zugaenglicher Online-Demo-Link +- [ ] Quellcode-Repository-Link (mit README) +- [ ] PRD-Dokument +- [ ] Kernseit-Screenshots (Startseite, Dashboard, Billing, Admin) +- [ ] 60-Sekunden-Demo-Video + +## Bewertungskriterien + +| Dimension | Grundanforderung | Erweiterte Anforderung | +|-----------|------------------|------------------------| +| Produktvollstaendigkeit | Alle Hauptseiten zugaenglich | Stil wie echte SaaS | +| Geschaefsabschluss | Registrierung > Generierung > Verlauf lauffaehig | Free/Pro-Unterschiede klar sichtbar | +| Datenkorrektheit | Ergebnisse und Zahlungsstatus in Datenbank | Fehlermeldungen, Leerzustaende und Loading vorhanden | +| Berechtigungen | Geschuetzte Seiten nicht ohne Login zugaenglich | Serverseitige Rollenpruefung | +| Engineering | Lokal startbar und oeffentlich bereitstellbar | README klar, Demo-Video vollstaendig | + +::: tip +Wenn die Aufgabe zu gross erscheint, merke dir: **Zuerst "zum Laufen bringen", dann "verschönern".** +::: + +## Einreichungspruefung + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## Referenzmaterialien + +- [UI-Design](../../frontend/ui-design/) +- [Moderne Komponentenbibliothek](../../frontend/modern-component-library/) +- [Von der Datenbank zu Supabase](../../backend/database-supabase/) +- [API-Code schreiben](../../backend/ai-interface-code/) +- [Git und GitHub](../../backend/git-workflow/) +- [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/) +- [Stripe-Zahlungssystem](../../backend/stripe-payment/) diff --git a/docs/de-de/stage-2/assignments/custom-dify-agent-platform/index.md b/docs/de-de/stage-2/assignments/custom-dify-agent-platform/index.md new file mode 100644 index 0000000..d202a8c --- /dev/null +++ b/docs/de-de/stage-2/assignments/custom-dify-agent-platform/index.md @@ -0,0 +1,173 @@ +# Dify-aehnliche Agenten-Plattform Entwicklungspraxis + +## Ueberblick + +Dieses Praxisprojekt erfordert die Umsetzung eines echten PRD von Grund auf: Eine Plattform, die die Kernfunktionen von Dify nachahmt. Du wirst eine Benutzerkonsole, ein Admin-Dashboard und ein Plattform-Backend erstellen und Kernfunktionen wie Agentenverwaltung, Chat, Protokollierung und Wissensdatenbank implementieren. + +## Vorkenntnisse + +- Frontend-Design und Komponentenbibliotheken ([UI-Design](../../frontend/ui-design/), [Moderne Komponentenbibliothek](../../frontend/modern-component-library/)) +- Backend-API-Design und Entwicklung ([API-Code schreiben](../../backend/ai-interface-code/)) +- Datenbankgrundlagen und Supabase ([Von der Datenbank zu Supabase](../../backend/database-supabase/)) +- Git-Workflow und Bereitstellung ([Git und GitHub](../../backend/git-workflow/), [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/)) + +## Lernziele + +1. Einen echten PRD lesen und eine Entwicklungsaufgabenliste extrahieren +2. Seitenarchitektur und Datenmodell fuer eine Agenten-Plattform entwerfen +3. Vollstaendige Kette aus Agentenerstellung, Chat und Protokollierung implementieren +4. KI-gestuetzte Entwicklung einer Plattform-produkt durchfuehren +5. End-to-End-Tests abschliessen und einen demonstrierbaren KI-Plattformprototyp liefern + +## Projektuebersicht + +Das zu erstellende Produkt ist eine Dify-aehnliche Agenten-Plattform mit zwei Subsystemen: + +| Subsystem | Verantwortung | +|-----------|---------------| +| **Benutzerkonsole** | Agenten erstellen, Prompt konfigurieren, Chat starten, Protokolle anzeigen, Wissensdatenbank verwalten | +| **Admin-Dashboard** | Benutzerdaten, Plattformressourcen, Aufrufstatistiken | + +::: tip PRD-Zugang +[PRD ansehen](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/custom-dify-agent-platform/PRD.md) +::: + +
+ + + +
+ +## Teil 1: Anforderungsanalyse + +### 1.1 PRD lesen + +- Welche Funktionen kommen in den MVP: Agenten, Sitzungen, Protokolle, Wissensdatenbank? +- Seiten- und Routenliste finalisiert? +- Grenzen fuer Modellaufrufe und Protokollierung? +- Multi-Tenant und komplexe Workflows zunaechst weglassen? + +::: warning +Beginne nicht mit dem Code, wenn diese Fragen keine klaren Antworten haben. +::: + +### 1.2 Systemarchitektur bestaetigen + +```mermaid +flowchart TD + prd["PRD"] --> app["Benutzerkonsole"] + prd --> admin["Admin-Dashboard"] + app --> auth["Auth"] + app --> agent["Agentenkonfiguration"] + app --> chat["Chat"] + chat --> llm["Modellaufruf"] + chat --> db["Datenbank"] + app --> kb["Wissensdatenbank"] + admin --> logs["Aufrufprotokolle und Plattformuebersicht"] + logs --> db +``` + +## Teil 2: Projektgeruest erstellen + +### 2.1 Frontend-Seiten generieren + +```text +Bitte generiere basierend auf dem aktuellen PRD ein Frontend-Geruest fuer eine Dify-aehnliche Agenten-Plattform. + +Anforderungen: +1. Benutzerseite: Login, Agentenliste, Agentenkonfiguration, Chat, Protokolle, Wissensdatenbank +2. Admin-Seite: Startseite, Benutzeruebersicht, Ressourcenuebersicht +3. Zunaechst nur Seitenstruktur mit Mock-Daten +4. Stil wie eine moderne KI-Plattform +``` + +### 2.2 Seitenstruktur ueberpruefen + +- [ ] Benutzerkonsole und Admin-Eingang getrennt +- [ ] Agentenliste, Konfiguration, Chat, Protokolle, Wissensdatenbank vollstaendig +- [ ] Admin-Startseite und Benutzeruebersicht zugaenglich +- [ ] Mock-Daten zeigen grundlegende UI-Zustaende + +## Teil 3: Iterative Entwicklung + +### 3.1 Modulweise vorgehen + +1. **Auth**: Registrierung, Login, Rollenunterscheidung +2. **Agentenverwaltung**: Erstellen, Bearbeiten, Loeschen, Prompt-Konfiguration +3. **Chat-Funktion**: Sitzung erstellen, Nachrichten, Modellaufruf +4. **Protokollierung**: Dauer, Token-Verbrauch, Fehleraufzeichnung +5. **Wissensdatenbank** (Bonus): Dokument-Upload, Suche, Ergebnisse injizieren +6. **Admin-Dashboard**: Benutzerdaten, Ressourcen, Aufrufstatistiken + +| Pruefpunkt | Verifikationsmethode | +|------------|---------------------| +| Seitenkonsistenz | Seitenanzahl und Funktionen gemaess PRD | +| API-Abschluss | agents, chat, logs, knowledge APIs vollstaendig | +| Berechtigungsisolierung | Benutzer koennen nur eigene Agenten/Sitzungen verwalten | +| Datenkonsistenz | messages, logs, documents Daten synchron | +| Demonstrierbarkeit | "Agent erstellen > Chat > Protokolle anzeigen" vollstaendig | + +### 3.2 Wissensdatenbank-Integration (Bonus) + +Fuege jedem Agenten einen "Wissensdatenbank-Schalter" hinzu: +- Aktiviert: Zunaechst Wissensteile durchsuchen, dann mit Frage an Modell senden +- Deaktiviert: Normaler Chat-Modus + +## Teil 4: Test und Bereitstellung + +### 4.1 End-to-End-Tests + +- Registrierung > Agent erstellen > Prompt konfigurieren > Chat starten > Protokolle anzeigen +- Admin-Login > Benutzerdaten > Aufrufstatistiken + +### 4.2 Bereitstellung + +Siehe: [Git und GitHub](../../backend/git-workflow/), [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/). + +## Liefergegenstaende + +- [ ] Online-Demo-Link +- [ ] Quellcode-Repository (mit README) +- [ ] PRD-Dokument +- [ ] Kernseiten-Screenshots +- [ ] 60-Sekunden-Demo-Video + +## Bewertungskriterien + +| Dimension | Grundanforderung | Erweiterte Anforderung | +|-----------|------------------|------------------------| +| Plattformvollstaendigkeit | agents / chat / logs Seiten nutzbar | Klare Navigation und einheitliches Design | +| Geschaefsabschluss | Agenten koennen erstellt und real kommuniziert werden | Multi-Agenten-Wechsel und Sitzungsverlauf | +| Daten und Tracking | Nachrichten und Aufrufprotokolle abfragbar | Token-/Dauerstatistik-Dashboard | +| Berechtigungssicherheit | Nur angemeldete Benutzer koennen Kern-APIs aufrufen | Ressourcen-Zuordnungspruefung vollstaendig | +| Engineering | Bereitstellbar, demonstrierbar, README klar | Wissensdatenbank mit erklaerbaren Suchergebnissen | + +## Einreichungspruefung + + + + +
    +
  • +
  • +
  • +
  • +
  • +
+
+ +## Referenzmaterialien + +- [UI-Design](../../frontend/ui-design/) +- [Moderne Komponentenbibliothek](../../frontend/modern-component-library/) +- [Von der Datenbank zu Supabase](../../backend/database-supabase/) +- [API-Code schreiben](../../backend/ai-interface-code/) +- [Git und GitHub](../../backend/git-workflow/) +- [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/) diff --git a/docs/de-de/stage-2/assignments/exam-management-express/index.md b/docs/de-de/stage-2/assignments/exam-management-express/index.md new file mode 100644 index 0000000..c1ddb16 --- /dev/null +++ b/docs/de-de/stage-2/assignments/exam-management-express/index.md @@ -0,0 +1,211 @@ +# Online-Pruefungs- und Managementsystem Entwicklungspraxis + +## Ueberblick + +Dieses Praxisprojekt erfordert die Umsetzung eines echten PRD von Grund auf: Ein Online-Pruefungs- und Managementsystem. Die Besonderheit liegt in mehreren Rollen (Studenten und Administratoren) mit unterschiedlichen Seiten und Berechtigungen. Du wirst Express als Backend verwenden und eine vollstaendige Pruefungsgeschaeftskette implementieren. + +## Vorkenntnisse + +- Frontend-Design und Komponentenbibliotheken ([UI-Design](../../frontend/ui-design/), [Moderne Komponentenbibliothek](../../frontend/modern-component-library/)) +- Backend-API-Design und Entwicklung ([API-Code schreiben](../../backend/ai-interface-code/)) +- Datenbankgrundlagen und Supabase ([Von der Datenbank zu Supabase](../../backend/database-supabase/)) +- Git-Workflow und Bereitstellung ([Git und GitHub](../../backend/git-workflow/), [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/)) + +## Lernziele + +1. Einen echten PRD lesen und eine Entwicklungsaufgabenliste extrahieren +2. Berechtigungssteuerung und Seitenrouten fuer ein Multi-Rollen-System entwerfen +3. Eine vollstaendige Backend-API mit Express implementieren +4. Die Geschaefskette Pruefung, Einreichung, automatische Bewertung implementieren +5. End-to-End-Tests abschliessen und einen demonstrierbaren Systemprototyp liefern + +## Projektuebersicht + +Das zu erstellende Produkt ist ein Online-Pruefungs- und Managementsystem mit drei Subsystemen: + +| Subsystem | Verantwortung | +|-----------|---------------| +| **Oeffentliche Website** | Plattformvorstellung, Login-Einstieg | +| **Studentenportal** | Pruefungsliste, Antworten, Einreichung, Noteneinsicht | +| **Admin-Dashboard** | Fragenbank, Pruefungsverwaltung, Einreichungsdatensaetze, Notenstatistik | + +::: tip PRD-Zugang +[PRD ansehen](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/exam-management-express/PRD.md) +::: + +
+ + + +
+ +## Teil 1: Anforderungsanalyse + +### 1.1 PRD lesen + +- Welche Rollen enthaelt das System? Was kann jede Rolle tun? +- Ist die Seitenliste vollstaendig? +- Welche Fragetypen werden unterstuetzt? Wie ist die Bewertungslogik fuer jeden Typ? +- Was ist der vollstaendige Pruefungsablauf? + +::: warning +Beginne nicht mit dem Code, wenn diese Fragen keine klaren Antworten haben. +::: + +### 1.2 Systemarchitektur bestaetigen + +```mermaid +flowchart TD + prd["PRD"] --> web["Oeffentliche Website"] + prd --> student["Studentenportal"] + prd --> admin["Admin-Dashboard"] + student --> auth["Auth"] + student --> exam["Pruefung und Antworten"] + exam --> db["Datenbank"] + admin --> question["Fragenbank"] + admin --> submission["Einreichungen und Noten"] + question --> db + submission --> db +``` + +## Teil 2: Projektgeruest erstellen + +### 2.1 Frontend-Seiten generieren + +```text +Bitte generiere basierend auf dem aktuellen PRD ein Frontend-Geruest fuer ein Online-Pruefungssystem. + +Technologie-Stack: +- Next.js App Router, TypeScript, Tailwind CSS, shadcn/ui + +Seiten: +1. Startseite / +2. Login /login +3. Studenten-Pruefungsliste /student/exams +4. Studenten-Antwortseite /student/exams/[id] +5. Studenten-Noten /student/history +6. Admin-Startseite /admin +7. Pruefungsverwaltung /admin/exams +8. Fragenbank /admin/questions +9. Einreichungen /admin/submissions +``` + +### 2.2 Antwortseite verfeinern + +Die Antwortseite ist die Kernseite des Studentenportals: + +```text +Bitte verfeinere die Studenten-Antwortseite. + +- Oben: Pruefungstitel, Countdown, Anzahl beantworteter Fragen +- Mitte: Frage und Optionen +- Unterstuetzung fuer Multiple-Choice, Wahr/Falsch, Kurzantwort +- Antwortkarte links oder oben +- Bestaetigungsdialog vor dem Absenden +``` + +### 2.3 Seitenstruktur ueberpruefen + +- [ ] Studenten- und Admin-Einstiegspunkte getrennt +- [ ] Login, Pruefungsliste, Antwortseite, Notenseite vollstaendig +- [ ] Admin: Fragenbank, Pruefungsverwaltung, Einreichungen zugaenglich +- [ ] Studenten- und Admin-Seitenstile deutlich unterschieden + +## Teil 3: Backend-Entwicklung + +### 3.1 Login und Berechtigungssteuerung + +```text +Bitte hilf mir bei der Implementierung von Login und Berechtigungssteuerung fuer das Online-Pruefungssystem. + +Backend: Express. + +Ziele: +1. Studenten und Administratoren koennen sich anmelden +2. Nach Login wird die Benutzerrolle zurueckgegeben +3. Studenten koennen nur /student/*-APIs aufrufen +4. Administratoren koennen nur /admin/*-APIs aufrufen +5. Unangemeldete Benutzer werden zu /login weitergeleitet +``` + +### 3.2 Pruefungs- und Fragenbank-APIs + +| Modul | Empfohlene APIs | +|-------|-----------------| +| Pruefungsverwaltung | `GET /api/exams`, `POST /api/admin/exams`, `PATCH /api/admin/exams/:id` | +| Fragenbank | `GET /api/admin/questions`, `POST /api/admin/questions` | +| Pruefung starten | `POST /api/submissions/start` | +| Pruefung abgeben | `POST /api/submissions/:id/submit` | +| Noten | `GET /api/student/history`, `GET /api/admin/submissions` | + +### 3.3 Bewertungslogik + +- **Multiple-Choice**: Benutzerantwort stimmt mit Standardantwort ueberein = Punkte +- **Wahr/Falsch**: Automatisch bewertbar +- **Kurzantwort**: Nur Antwort speichern, Punkte leer, Status `reviewed = false` + +::: tip Bonus +Du kannst KI verwenden, um dem Administrator die Generierung von Kandidatenfragen zu ermoeglichen. Dies ist jedoch optional. +::: + +## Teil 4: Test und Bereitstellung + +### 4.1 End-to-End-Tests + +- Student: Login > Pruefungsliste > Pruefung starten > Antworten > Noteneinsicht +- Admin: Login > Pruefung erstellen > Fragen hinzufuegen > Veroeffentlichen > Einreichungen anzeigen + +### 4.2 Bereitstellung + +- Frontend: Vercel / Zeabur +- Express API: Zeabur / Railway / Render +- Datenbank: Supabase Postgres oder verwaltetes PostgreSQL + +## Liefergegenstaende + +- [ ] Online-Demo-Link +- [ ] Quellcode-Repository (mit README) +- [ ] PRD-Dokument +- [ ] Kernseiten-Screenshots +- [ ] 60-Sekunden-Demo-Video + +## Bewertungskriterien + +| Dimension | Grundanforderung | Erweiterte Anforderung | +|-----------|------------------|------------------------| +| Seitenvollstaendigkeit | Hauptseiten fuer Studenten und Admin zugaenglich | Einheitliches Design, mobile Grundverfuegbarkeit | +| Geschaefsabschluss | Student kann Pruefung ablegen und Noten einsehen | Admin kann vollstaendig Pruefungen erstellen | +| Datenkorrektheit | Antworten werden in Datenbank geschrieben, automatische Bewertung | Kurzantwort mit manueller oder KI-Unterstuetzung | +| Berechtigungen | Student/Admin-Grenzen klar | Serverseitige Rollenpruefung | +| Engineering | Lauffaehig, bereitstellbar, README klar | Demo-Video und Testanweisungen | + +## Einreichungspruefung + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## Referenzmaterialien + +- [UI-Design](../../frontend/ui-design/) +- [Moderne Komponentenbibliothek](../../frontend/modern-component-library/) +- [Von der Datenbank zu Supabase](../../backend/database-supabase/) +- [API-Code schreiben](../../backend/ai-interface-code/) +- [Git und GitHub](../../backend/git-workflow/) +- [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/) diff --git a/docs/de-de/stage-2/assignments/modern-landing-page/index.md b/docs/de-de/stage-2/assignments/modern-landing-page/index.md new file mode 100644 index 0000000..f1b16a7 --- /dev/null +++ b/docs/de-de/stage-2/assignments/modern-landing-page/index.md @@ -0,0 +1,163 @@ +# Moderne KI-Bildgenerierungs-SaaS Entwicklungspraxis + +## Ueberblick + +Dieses Praxisprojekt erfordert die Umsetzung eines echten PRD von Grund auf: Eine KI-Bildgenerierungs-SaaS, die sich an der Midjourney-Erfahrung orientiert. Du wirst den gesamten Prozess von der Anforderungsanalyse ueber Projektzerlegung und iterativer Entwicklung bis zur Bereitstellung durchlaufen. + +## Vorkenntnisse + +- Frontend-Design und Komponentenbibliotheken ([UI-Design](../../frontend/ui-design/), [Moderne Komponentenbibliothek](../../frontend/modern-component-library/)) +- Backend-API-Design und Entwicklung ([API-Code schreiben](../../backend/ai-interface-code/)) +- Datenbankgrundlagen und Supabase ([Von der Datenbank zu Supabase](../../backend/database-supabase/)) +- Zahlungsintegration ([Stripe-Zahlungssystem](../../backend/stripe-payment/)) +- Git-Workflow und Bereitstellung ([Git und GitHub](../../backend/git-workflow/), [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/)) + +## Lernziele + +1. Einen echten PRD lesen und eine Entwicklungsaufgabenliste extrahieren +2. Module basierend auf dem PRD aufteilen und einen schrittweisen Plan erstellen +3. KI-gestuetzt Frontend-Geruest und Backend-API entwickeln +4. Jedes Modul verifizieren und iterativ optimieren +5. End-to-End-Tests durchfuehren und von "lauffaehig" zu "lieferbar" gelangen + +## Projektuebersicht + +Das zu erstellende Produkt ist eine moderne KI-Bildgenerierungs-SaaS mit drei Subsystemen: + +| Subsystem | Verantwortung | +|-----------|---------------| +| **Oeffentliche Website** | Produktvorstellung, Preisgestaltung, FAQ, Registrierungskonvertierung | +| **Benutzer-Arbeitsbereich** | Prompt-Eingabe, Bildgenerierung, Galerie, Guthaben, Plaene, Community | +| **Admin-Dashboard** | Benutzerverwaltung, Aufgabenverwaltung, Zahlungsverwaltung, SaaS-Metrik | + +::: tip PRD-Zugang +[PRD ansehen](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/modern-landing-page/PRD.md) +::: + +
+ + + +
+ +## Teil 1: Anforderungsanalyse + +### 1.1 PRD lesen + +- Wie viele Einstiegspunkte hat das System? Welche Seiten deckt jeder ab? +- Was ist die Kernfunktion jeder Seite? +- Welche Module und Datenbanktabellen enthaelt das Backend? +- Was ist der MVP-Umfang? + +::: warning +Beginne nicht mit dem Code, wenn diese Fragen keine klaren Antworten haben. +::: + +### 1.2 Systemarchitektur bestaetigen + +```mermaid +flowchart TD + prd["PRD"] --> web["Oeffentliche Website"] + prd --> app["Benutzer-Arbeitsbereich"] + prd --> admin["Admin-Dashboard"] + app --> auth["Auth"] + app --> gen["Bildgenerierung"] + gen --> oss["OSS-Objektspeicher"] + gen --> db["Datenbank"] + billing["Zahlung und Plaene"] --> db + social["Teilen / Liken / Kommentieren"] --> db + admin --> analytics["SaaS-Metrik-Dashboard"] + admin --> observability["API / DB / Provider-Monitoring"] +``` + +## Teil 2: Projektgeruest erstellen + +### 2.1 Frontend-Seiten generieren + +```text +Bitte generiere basierend auf dem aktuellen PRD ein Frontend-Geruest fuer eine moderne KI-Bildgenerierungs-SaaS. + +Anforderungen: +1. Drei Einstiegspunkte: www, app, admin +2. Website: Startseite, Preisgestaltung, FAQ +3. App: Login, Registrierung, Dashboard, Galerie, Plaene, Guthaben, Community, Detail, Profil +4. Admin: Startseite, Benutzer, Aufgaben, Inhalte, Plaene, Zahlungen, Konfiguration, Metriken, Monitoring +5. Zunaechst nur Seitenstruktur mit Mock-Daten +6. Stil wie Midjourney: schlicht, modern, produktiv +``` + +### 2.2 Seitenstruktur ueberpruefen + +- [ ] Drei Einstiegspunkte mit unabhaengigen Routen +- [ ] Seitenanzahl stimmt mit PRD ueberein +- [ ] Alle Seiten navigierbar +- [ ] Mock-Daten zeigen grundlegende UI-Zustaende + +## Teil 3: Iterative Entwicklung + +### 3.1 Modulweise vorgehen + +1. **Auth**: Registrierung, Login, Rollenunterscheidung +2. **Datenbank**: Tabellen erstellen, Lese-/Schreib-APIs +3. **Kerngescheaft**: Bildgenerierung, Ergebnisspeicherung +4. **OSS-Speicher**: Bild-Upload und Zugriff +5. **Zahlung**: Plaene, Guthaben, Stripe-Integration +6. **Social**: Teilen, Liken, Kommentieren +7. **Admin**: Benutzerverwaltung, Aufgaben, Inhaltsmoderation +8. **Monitoring**: SaaS-Metrik-Dashboard, Systemueberwachung + +| Pruefpunkt | Verifikationsmethode | +|------------|---------------------| +| Seitenkonsistenz | Anzahl, Einstiegspunkte, Funktionen gemaess PRD | +| API-Korrektheit | Parameter, Struktur, Statusbehandlung | +| Berechtigungsisolierung | Benutzer und Admin getrennt | +| Datenkonsistenz | Datenbank, OSS, Zahlung, Guthaben synchron | +| Demonstrierbarkeit | Vollstaendige Geschaefskette vorfuehrbar | + +::: tip +Wenn die KI vom PRD abweicht, nicht die ganze Seite neu starten - nur das spezifische Modul korrigieren. +::: + +## Teil 4: Test und Bereitstellung + +### 4.1 End-to-End-Tests + +- Registrierung > Guthaben kaufen > Bild generieren > Verlauf anzeigen > Teilen +- Admin-Login > Benutzerdaten > Aufgabenstatistik > Systemueberwachung + +### 4.2 Bereitstellung + +Siehe: [Git und GitHub](../../backend/git-workflow/), [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/). + +## Liefergegenstaende + +- [ ] Online-Demo-Link +- [ ] Quellcode-Repository (mit README) +- [ ] PRD-Dokument +- [ ] Kernseiten-Screenshots +- [ ] 60-Sekunden-Demo-Video + +## Bewertungskriterien + +| Dimension | Grundanforderung | Erweiterte Anforderung | +|-----------|------------------|------------------------| +| PRD-Alignment | Seiten, Funktionen, Datenstruktur gemaess PRD | Designentscheidungen klar erklaert | +| Produktabschluss | Registrierung > Guthaben > Generierung > Verlauf > Teilen lauffaehig | Zahlungsstatus, Guthaben, Generierungen konsistent | +| Admin-Faehigkeit | Benutzer, Aufgaben, Zahlungen, Inhalte einsehbar | SaaS-Metrik und Monitoring vollstaendig nutzbar | +| Engineering | Frontend, Backend, DB, OSS, Zahlung verbunden | Fehlerbehandlung, Leerzustaende, Loading vorhanden | +| Lieferqualitaet | Bereitstellbar, lauffaehig | README klar, Demo-Video vollstaendig | + +## Referenzmaterialien + +- [UI-Design](../../frontend/ui-design/) +- [Moderne Komponentenbibliothek](../../frontend/modern-component-library/) +- [Von der Datenbank zu Supabase](../../backend/database-supabase/) +- [API-Code schreiben](../../backend/ai-interface-code/) +- [Git und GitHub](../../backend/git-workflow/) +- [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/) +- [Stripe-Zahlungssystem](../../backend/stripe-payment/) diff --git a/docs/de-de/stage-2/assignments/movie-recommendation-springboot/index.md b/docs/de-de/stage-2/assignments/movie-recommendation-springboot/index.md new file mode 100644 index 0000000..592df51 --- /dev/null +++ b/docs/de-de/stage-2/assignments/movie-recommendation-springboot/index.md @@ -0,0 +1,144 @@ +# Spring Boot Filmempfehlungssystem Entwicklungspraxis + +## Ueberblick + +Dieses Praxisprojekt erfordert die Umsetzung eines echten PRD: Eine Filmwebsite mit Empfehlungsfaehigkeit unter Verwendung von Spring Boot. Die Kernherausforderung liegt nicht in einfachem CRUD, sondern im Nachdenken darueber, "wie Benutzerverhalten die Empfehlungsergebnisse beeinflusst" und "wie Empfehlungen erklaerbar sind". + +## Vorkenntnisse + +- Frontend-Design und Komponentenbibliotheken ([UI-Design](../../frontend/ui-design/), [Moderne Komponentenbibliothek](../../frontend/modern-component-library/)) +- Backend-API-Design und Entwicklung ([API-Code schreiben](../../backend/ai-interface-code/)) +- Datenbankgrundlagen und Supabase ([Von der Datenbank zu Supabase](../../backend/database-supabase/)) +- Git-Workflow und Bereitstellung ([Git und GitHub](../../backend/git-workflow/), [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/)) + +## Lernziele + +1. PRD lesen und Entwicklungsaufgabenliste fuer ein Empfehlungssystem extrahieren +2. Spring Boot-Projekt aufbauen und RESTful APIs implementieren +3. Vollstaendige Datenkette "Benutzerverhalten > Empfehlung" entwerfen +4. Erklaerbare Empfehlungslogik implementieren +5. End-to-End-Tests abschliessen und einen demonstrierbaren Produktprototyp liefern + +## Projektuebersicht + +| Funktion | Beschreibung | +|----------|-------------| +| **Durchsuchen und Suche** | Benutzer koennen Filme durchsuchen und suchen | +| **Bewertung und Favoriten** | Benutzer koennen Filme bewerten und als Favorit speichern | +| **Personalisierte Empfehlungen** | System generiert Empfehlungen basierend auf Benutzerverhalten | +| **Admin-Dashboard** | Administrator verwaltet Filmdaten und prueft Empfehlungseffektivitaet | + +::: tip PRD-Zugang +[PRD ansehen](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/movie-recommendation-springboot/PRD.md) +::: + +
+ + + +
+ +## Teil 1: Anforderungsanalyse + +### 1.1 PRD lesen + +- Was ist die Empfehlungsstrategie? Erste Version mit erklaerbarer Methode (z. B. basierend auf Bewertungsahnlichkeit)? +- Welche Verhaltensdaten speichern? (Bewertungen, Favoriten, Seitenaufrufe) +- Welche Empfehlungsmetriken sieht der Administrator? +- Seitenliste vollstaendig? + +::: warning +Beginne nicht mit dem Code, wenn diese Fragen keine klaren Antworten haben. +::: + +### 1.2 Systemarchitektur bestaetigen + +```mermaid +flowchart TD + prd["PRD"] --> web["Frontend-Seiten"] + web --> auth["Benutzerauth"] + web --> movie["Filmliste / Details"] + web --> behavior["Bewertung / Favoriten"] + behavior --> reco["Empfehlungslogik"] + reco --> db["Datenbank"] + admin["Admin-Verwaltung"] --> db +``` + +## Teil 2: Projektgeruest erstellen + +### 2.1 Frontend-Seiten generieren + +```text +Bitte generiere basierend auf dem aktuellen PRD ein Frontend-Geruest fuer ein Spring Boot Filmempfehlungssystem. + +Anforderungen: +1. Seiten: Startseite, Filmliste, Filmdetails, Empfehlungsseite, Profil, Admin +2. Zunaechst nur Seitenstruktur mit Mock-Daten +3. Stil wie ein echtes Content-Produkt, nicht wie ein Klassenzimmer-Demo +``` + +### 2.2 Seitenstruktur ueberpruefen + +- [ ] Filmliste unterstuetzt Suche und Filter +- [ ] Filmdetailseite hat Bewertungs- und Favorit-Buttons +- [ ] Empfehlungsseite zeigt Ergebnisse mit Erklaerung +- [ ] Admin zeigt Filmdaten und Empfehlungseffektivitaet + +## Teil 3: Iterative Entwicklung + +### 3.1 Modulweise vorgehen + +1. **Spring Boot-Projektaufbau**: Projektstruktur, Datenbankkonfiguration, Basis-CRUD +2. **Filmdatenverwaltung**: Filmliste, Details, Such-APIs +3. **Benutzerverhalten**: Bewertungs- und Favorit-APIs, Verhaltensdaten schreiben +4. **Empfehlungslogik**: Empfehlungsalgorithmus basierend auf Benutzerverhalten +5. **Empfehlungsanzeige**: Ergebnisse mit Erklaerung anzeigen +6. **Admin-Dashboard**: Filmdaten pflegen, Empfehlungseffektivitaet einsehen + +### 3.2 Modul-Selbstpruefung + +| Pruefpunkt | Verifikationsmethode | +|------------|---------------------| +| Grundfunktionen | Liste, Details, Bewertung, Favoriten vollstaendig | +| Empfehlungskopplung | Benutzerverhalten beeinflusst Empfehlungsergebnisse | +| Empfehlungserklaerbarkeit | Benutzer versteht, warum diese Filme empfohlen werden | +| Admin-Daten | Administrator kann Filmdaten und Empfehlungseffektivitaet einsehen | + +## Teil 4: Test und Bereitstellung + +### 4.1 End-to-End-Tests + +- Film durchsuchen > Bewerten > Favorit > Empfehlungsseite pruefen, ob Ergebnisse sich aendern +- Admin-Login > Film hinzufuegen > Empfehlungsstatistik anzeigen + +## Liefergegenstaende + +- [ ] Online-Demo-Link +- [ ] Quellcode-Repository (mit README) +- [ ] PRD-Dokument +- [ ] Kernseiten-Screenshots +- [ ] 60-Sekunden-Demo-Video + +## Bewertungskriterien + +| Dimension | Grundanforderung | Erweiterte Anforderung | +|-----------|------------------|------------------------| +| PRD-Alignment | Seiten, Funktionen, Datenstruktur gemaess PRD | Designentscheidungen klar erklaert | +| Produktabschluss | Durchsuchen > Bewerten > Favorit > Empfehlung lauffaehig | Bewertungsverhalten beeinflusst Empfehlungen deutlich | +| Empfehlungsqualitaet | Ergebnisse angemessen, Gruende erklaerbar | Mehrere Empfehlungsstrategien unterstuetzt | +| Admin-Faehigkeit | Filmdaten und Empfehlungseffektivitaet einsehbar | Genauigkeitsstatistiken vorhanden | +| Engineering | Frontend, Spring Boot Backend, Datenbank verbunden | Empfehlungs-API mit Caching oder Performance-Optimierung | + +## Referenzmaterialien + +- [UI-Design](../../frontend/ui-design/) +- [Moderne Komponentenbibliothek](../../frontend/modern-component-library/) +- [Von der Datenbank zu Supabase](../../backend/database-supabase/) +- [API-Code schreiben](../../backend/ai-interface-code/) +- [Git und GitHub](../../backend/git-workflow/) +- [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/) diff --git a/docs/de-de/stage-2/assignments/simple-grocery-microservices/index.md b/docs/de-de/stage-2/assignments/simple-grocery-microservices/index.md new file mode 100644 index 0000000..fefa700 --- /dev/null +++ b/docs/de-de/stage-2/assignments/simple-grocery-microservices/index.md @@ -0,0 +1,154 @@ +# Lebensmittel-E-Commerce-Microservicesystem Entwicklungspraxis + +## Ueberblick + +Dieses Praxisprojekt erfordert die Umsetzung eines echten PRD von Grund auf: Ein Lebensmittel-E-Commerce-Microservicesystem. Im Gegensatz zu frueheren Single-Service-Projekten ist das Backend hier in mehrere unabhaengige Services nach Geschaeftsbereich aufgeteilt, die ueber ein API-Gateway einheitlich nach aussen kommunizieren. Du lernst, Service-Grenzen zu entwerfen und datenuebergreifende Konsistenzprobleme zwischen Services zu behandeln. + +## Vorkenntnisse + +- Frontend-Design und Komponentenbibliotheken ([UI-Design](../../frontend/ui-design/), [Moderne Komponentenbibliothek](../../frontend/modern-component-library/)) +- Backend-API-Design und Entwicklung ([API-Code schreiben](../../backend/ai-interface-code/)) +- Datenbankgrundlagen und Supabase ([Von der Datenbank zu Supabase](../../backend/database-supabase/)) +- Git-Workflow und Bereitstellung ([Git und GitHub](../../backend/git-workflow/), [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/)) + +## Lernziele + +1. PRD lesen und Entwicklungsaufgabenliste fuer ein Microservicesystem extrahieren +2. Service-Grenzen nach Geschaeftsbereichen aufteilen (Auth, Katalog, Bestand, Bestellung) +3. API-Gateway-Routing entwerfen und implementieren +4. Uebergreifende Probleme wie Bestandsabbuchung und Bestellkonsistenz behandeln +5. End-to-End-Tests abschliessen und einen demonstrierbaren Microservice-Prototyp liefern + +## Projektuebersicht + +| Subsystem | Verantwortung | +|-----------|---------------| +| **Benutzerportal** | Produkte durchsuchen, bestellen, Bestellungen einsehen | +| **Admin-Portal** | Produktverwaltung, Bestandsverwaltung, Bestellverwaltung | + +Backend-Services: + +| Service | Verantwortung | +|---------|---------------| +| **API Gateway** | Einheitlicher Einstieg, Routing, Auth-Pruefung | +| **Auth Service** | Benutzerregistrierung, Login, JWT-Ausgabe | +| **Catalog Service** | Produktinformationsverwaltung | +| **Inventory Service** | Bestandsmengenverwaltung | +| **Order Service** | Bestellerstellung, Statusverwaltung | + +::: tip PRD-Zugang +[PRD ansehen](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/simple-grocery-microservices/PRD.md) +::: + +
+ + + +
+ +## Teil 1: Anforderungsanalyse + +### 1.1 PRD lesen + +- Wie werden Services aufgeteilt? Verantwortungsgrenzen jedes Services? +- Welche Seiten haben Benutzer- und Admin-Portal? +- Bestandsabbuchungsstrategie nach Bestellung? Erfolg / Fehler / Timeout? +- Welche komplexen Faehigkeiten (verteilte Transaktionen, Nachrichtenwarteschlangen) zunaechst weglassen? + +::: warning +Beginne nicht mit dem Code, wenn diese Fragen keine klaren Antworten haben. +::: + +### 1.2 Systemarchitektur bestaetigen + +```mermaid +flowchart TD + prd["PRD"] --> fe["Frontend-Seiten"] + fe --> gw["API Gateway"] + gw --> auth["Auth Service"] + gw --> catalog["Catalog Service"] + gw --> inventory["Inventory Service"] + gw --> order["Order Service"] + order --> inventory +``` + +## Teil 2: Projektgeruest erstellen + +### 2.1 Projektstruktur generieren + +```text +Bitte generiere basierend auf dem aktuellen PRD ein Projektgeruest fuer ein Lebensmittel-E-Commerce-Microservicesystem. + +Anforderungen: +1. Frontend Benutzer- und Admin-Geruest generieren +2. Fuenf Verzeichnisse: api-gateway, auth-service, catalog-service, inventory-service, order-service +3. Jeder Service zunaechst nur minimal lauffaehigen Einstiegspunkt +4. Keine echte Datenbank oder Zahlung +``` + +### 2.2 Projektstruktur ueberpruefen + +- [ ] Fuenf Service-Verzeichnisse klar strukturiert +- [ ] API Gateway startet und leitet Anfragen weiter +- [ ] Gesundheitspruefung jedes Services erreichbar +- [ ] Frontend Benutzer- und Admin-Seiten zugaenglich + +## Teil 3: Iterative Entwicklung + +### 3.1 Modulweise vorgehen + +1. **API Gateway**: Routing-Konfiguration, JWT-Pruefung-Middleware +2. **Auth Service**: Registrierung, Login, JWT-Ausgabe +3. **Catalog Service**: Produkt-CRUD, Listenabfrage +4. **Inventory Service**: Bestandsabfrage, Bestandsabbuchung +5. **Order Service**: Bestellerstellung, Statusuebergaenge, Bestandskopplung +6. **Admin-Portal**: Produkt-, Bestands- und Bestellverwaltung + +### 3.2 Modul-Selbstpruefung + +| Pruefpunkt | Verifikationsmethode | +|------------|---------------------| +| Gateway-Routing | Services ueber Gateway korrekt erreichbar | +| Berechtigungsisolierung | Benutzer- und Admin-APIs getrennt | +| Datenkonsistenz | Produkt- und Bestandsdaten synchron | +| Transaktionsabschluss | Bestandsabbuchung und Bestellstatus nach Bestellung konsistent | +| Fehlerbehandlung | Bestand unzureichend oder Timeout: Kompensationsmechanismus | + +## Teil 4: Test und Bereitstellung + +### 4.1 End-to-End-Tests + +- Produkte durchsuchen > In den Warenkorb > Bestellen > Bestellung einsehen +- Admin > Produkt hinzufuegen > Bestand aktualisieren > Bestellungen anzeigen + +## Liefergegenstaende + +- [ ] Online-Demo-Link +- [ ] Quellcode-Repository (mit README) +- [ ] PRD-Dokument +- [ ] Kernseiten-Screenshots +- [ ] 60-Sekunden-Demo-Video + +## Bewertungskriterien + +| Dimension | Grundanforderung | Erweiterte Anforderung | +|-----------|------------------|------------------------| +| PRD-Alignment | Seiten, Funktionen, Service-Aufteilung gemaess PRD | Service-Aufteilungsgruende klar erklaert | +| Produktabschluss | Durchsuchen > Bestellen > Bestandsabbuchung > Bestellung lauffaehig | Kompensationsmechanismus bei Timeout oder unzureichendem Bestand | +| Service-Architektur | Jeder Service unabhaengig startbar, ueber Gateway erreichbar | Fehlerbehandlung und Retry bei Service-Kommunikation | +| Admin-Faehigkeit | Produkt-, Bestands- und Bestellverwaltung bedienbar | Admin mit Datenstatistiken | +| Engineering | Frontend, Gateway, Services, Datenbank verbunden | Docker Compose oder aehnliche Orchestrierung | + +## Referenzmaterialien + +- [UI-Design](../../frontend/ui-design/) +- [Moderne Komponentenbibliothek](../../frontend/modern-component-library/) +- [Von der Datenbank zu Supabase](../../backend/database-supabase/) +- [API-Code schreiben](../../backend/ai-interface-code/) +- [Git und GitHub](../../backend/git-workflow/) +- [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/) diff --git a/docs/de-de/stage-2/assignments/traffic-data-visualization-go/index.md b/docs/de-de/stage-2/assignments/traffic-data-visualization-go/index.md new file mode 100644 index 0000000..02901b9 --- /dev/null +++ b/docs/de-de/stage-2/assignments/traffic-data-visualization-go/index.md @@ -0,0 +1,147 @@ +# Go Verkehrsdaten-Analyseplattform Entwicklungspraxis + +## Ueberblick + +Dieses Praxisprojekt erfordert die Umsetzung eines echten PRD unter Verwendung von Go: Eine Verkehrsdaten-Analyseplattform. Im Gegensatz zu frueheren CRUD-Systemen musst du hier eine vollstaendige Datenkette "Dateneingang > Aggregation > Alarmierung > Visualisierung" aufbauen. Diese Art von Datenprodukt ist in IoT-, Ueberwachungs- und Betriebsanalysen sehr verbreitet. + +Dies ist die erste Begegnung mit der Programmiersprache Go. Keine Sorge - mit den vorhandenen JavaScript/TypeScript-Kenntnissen ist Go nicht schwer zu lernen. Der Fokus liegt auf dem Verstaendnis des Datenketten-Designs. + +## Vorkenntnisse + +- Frontend-Design und Komponentenbibliotheken ([UI-Design](../../frontend/ui-design/), [Moderne Komponentenbibliothek](../../frontend/modern-component-library/)) +- Backend-API-Design und Entwicklung ([API-Code schreiben](../../backend/ai-interface-code/)) +- Datenbankgrundlagen und Supabase ([Von der Datenbank zu Supabase](../../backend/database-supabase/)) +- Git-Workflow und Bereitstellung ([Git und GitHub](../../backend/git-workflow/), [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/)) + +## Lernziele + +1. PRD lesen und Entwicklungsaufgabenliste fuer ein Datenprodukt extrahieren +2. Go (Gin oder Fiber) fuer Backend-API-Services verwenden +3. Vollstaendige Datenkette fuer Dateneingang, Zeitfenster-Aggregation und Alarmierung entwerfen +4. Backend-Daten und Frontend-Dashboard konsistent halten +5. End-to-End-Tests abschliessen und einen demonstrierbaren Datenproduktprototyp liefern + +## Projektuebersicht + +| Modul | Verantwortung | +|-------|---------------| +| **Dateneingang** | Rohdaten zu Verkehrsereignissen empfangen und speichern | +| **Datenaggregation** | Trends und Stau-Indikatoren nach Zeitfenstern berechnen | +| **Alarmierung** | Auf regelbasierten Alarmdatensaetzen generieren | +| **Dashboard** | Trends, Ranglisten und Alarmlisten im Frontend anzeigen | + +::: tip PRD-Zugang +[PRD ansehen](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/traffic-data-visualization-go/PRD.md) +::: + +
+ + + +
+ +## Teil 1: Anforderungsanalyse + +### 1.1 PRD lesen + +- Was ist die Datenquelle? Welche Felder gibt es? +- Wie sind die Kernmetriken definiert? (z. B. genaue "Stau"-Kriterien) +- Was sind die Alarmregeln? Erste Version auf einfache Regeln beschraenken? +- Welche Seiten und Diagramme enthaelt das Dashboard? + +::: warning +Beginne nicht mit dem Code, wenn diese Fragen keine klaren Antworten haben. +::: + +### 1.2 Datenkette bestaetigen + +```mermaid +flowchart TD + prd["PRD"] --> ingest["Dateneingangs-API"] + ingest --> raw["Rohdatentabelle"] + raw --> agg["Aggregationsaufgabe"] + agg --> alert["Alarmregeln"] + agg --> dashboard["Dashboard-APIs"] + alert --> dashboard +``` + +## Teil 2: Projektgeruest erstellen + +### 2.1 Go-API-Service generieren + +```text +Bitte generiere basierend auf dem aktuellen PRD ein Go Verkehrsdaten-Analyseplattform-Geruest. + +Anforderungen: +1. Gin oder Fiber verwenden +2. Dateneingangs-API bereitstellen +3. Aggregationsaufgaben-Geruest erstellen +4. Dashboard- und Alarm-API-Geruest bereitstellen +5. Zunaechst keine komplexe Analyse, nur lauffaehige Struktur +``` + +### 2.2 Projektstruktur ueberpruefen + +- [ ] Go-Service startet korrekt +- [ ] Dateneingangs-API kann Daten empfangen und speichern +- [ ] Aggregationsaufgaben-Geruest steht +- [ ] Frontend-Dashboard zeigt grundlegende Diagramme + +## Teil 3: Iterative Entwicklung + +### 3.1 Modulweise vorgehen + +1. **Dateneingangs-API**: Verkehrsereignisse empfangen und in Datenbank schreiben +2. **Datenaggregation**: Nach Zeitfenstern aggregieren, Trends und Stau-Indikatoren berechnen +3. **Alarmregeln**: Basierend auf Schwellenwerten Alarmdatensaetze generieren +4. **Dashboard-APIs**: Trenddaten, Rangdaten, Alarmlisten bereitstellen +5. **Frontend-Dashboard**: Trenddiagramme, Ranglisten, Alarmlisten-Seiten + +### 3.2 Modul-Selbstpruefung + +| Pruefpunkt | Verifikationsmethode | +|------------|---------------------| +| Dateneingang | Rohdaten korrekt in Datenbank geschrieben | +| Aggregationsdefinition | Trend- und Rangmetriken konsistent berechnet | +| Alarmregeln | Alarm-Ausloesungsbedingungen wie erwartet | +| Datenkonsistenz | Dashboard-Anzeige und Backend-Daten synchron | +| API-Standards | Einheitliche Rueckgabestruktur und Fehlerbehandlung | + +## Teil 4: Test und Bereitstellung + +### 4.1 End-to-End-Tests + +- Testdaten eingeben > Aggregationsaufgabe ausfuehren > Dashboard-Anzeige aktualisieren +- Alarmbedingung ausloesen > Alarmdatensatz generieren > Alarmseite anzeigen + +## Liefergegenstaende + +- [ ] Online-Demo-Link +- [ ] Quellcode-Repository (mit README) +- [ ] PRD-Dokument +- [ ] Kernseiten-Screenshots +- [ ] 60-Sekunden-Demo-Video + +## Bewertungskriterien + +| Dimension | Grundanforderung | Erweiterte Anforderung | +|-----------|------------------|------------------------| +| PRD-Alignment | Funktionen und Datenstruktur gemaess PRD | Metrikdefinitionen und Aggregationslogik klar erklaert | +| Datenkette | Eingang > Aggregation > Alarm > Dashboard lauffaehig | Aggregationsaufgaben unterstuetzen inkrementelle Updates | +| Analysefaehigkeit | Trends, Rangliste und Alarme funktional | Konfigurierbare Metriken und anpassbare Alarmregeln | +| Frontend-Anzeige | Dashboard zeigt grundlegende Diagramme | Zeitbereichsfilter fuer Diagramme | +| Engineering | Go API, Datenbank, Frontend verbunden | Einheitliche Fehlerbehandlung und Protokollierung | + +## Referenzmaterialien + +- [UI-Design](../../frontend/ui-design/) +- [Moderne Komponentenbibliothek](../../frontend/modern-component-library/) +- [Von der Datenbank zu Supabase](../../backend/database-supabase/) +- [API-Code schreiben](../../backend/ai-interface-code/) +- [Git und GitHub](../../backend/git-workflow/) +- [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/) diff --git a/docs/de-de/stage-2/assignments/travel-planning-agent-platform/index.md b/docs/de-de/stage-2/assignments/travel-planning-agent-platform/index.md new file mode 100644 index 0000000..b432906 --- /dev/null +++ b/docs/de-de/stage-2/assignments/travel-planning-agent-platform/index.md @@ -0,0 +1,148 @@ +# Intelligente Reiseplanungs-Agenten-Plattform Entwicklungspraxis + +## Ueberblick + +Dieses Praxisprojekt erfordert die Umsetzung eines echten PRD von Grund auf: Eine intelligente Reiseplanungs-Agenten-Plattform. Du wirst ein Produkt erstellen, das strukturierte Eingaben empfaengt, Tagesreiseroutinen generiert und Speicherung sowie Wiederverwendung unterstuetzt - nicht nur ein Chatbot, sondern ein Produkt mit Aufgabenmanagement. + +Die Kernherausforderung: Wie generiert die KI strukturierte, nutzbare Reiseplaene anstelle eines langen, nicht bearbeitbaren Textblocks. + +## Vorkenntnisse + +- Frontend-Design und Komponentenbibliotheken ([UI-Design](../../frontend/ui-design/), [Moderne Komponentenbibliothek](../../frontend/modern-component-library/)) +- Backend-API-Design und Entwicklung ([API-Code schreiben](../../backend/ai-interface-code/)) +- Datenbankgrundlagen und Supabase ([Von der Datenbank zu Supabase](../../backend/database-supabase/)) +- Git-Workflow und Bereitstellung ([Git und GitHub](../../backend/git-workflow/), [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/)) + +## Lernziele + +1. PRD lesen und Entwicklungsaufgabenliste fuer eine Agenten-Plattform extrahieren +2. Strukturierte Eingabeformulare und strukturierte Ausgabeformate entwerfen +3. Agenten-Orchestrierungsschicht fuer Benutzereingabe, Modellaufruf und Ergebnisspeicherung implementieren +4. Geschaefskette "Generieren > Speichern > Wiederverwenden" aufbauen +5. End-to-End-Tests abschliessen und einen demonstrierbaren KI-Produktprototyp liefern + +## Projektuebersicht + +| Funktion | Beschreibung | +|----------|-------------| +| **Reiseplanung** | Benutzer gibt Startort, Ziel, Datum, Budget und Praeferenzen ein; System generiert Tagesreiseroutine | +| **Budgetaufteilung** | Reiseplan enthaelt Budgetverteilung und Empfehlungen | +| **Verwaltungsverlauf** | Benutzer kann Plaene speichern, neu generieren und exportieren | +| **Admin-Dashboard** | Administrator sieht beliebte Ziele, fehlgeschlagene Aufgaben und Benutzerfeedback | + +::: tip PRD-Zugang +[PRD ansehen](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/travel-planning-agent-platform/PRD.md) +::: + +
+ + + +
+ +## Teil 1: Anforderungsanalyse + +### 1.1 PRD lesen + +- Nur einzelnes Ziel in der ersten Version? +- Muss die Ausgabe strukturiert sein? Welche Struktur? +- Wie tief geht der Export? (Freigabelink / PDF / Bild) +- Umfang der Admin-Statistiken und Aufgabenprotokolle? + +::: warning +Beginne nicht mit dem Code, wenn diese Fragen keine klaren Antworten haben. +::: + +### 1.2 Systemarchitektur bestaetigen + +```mermaid +flowchart TD + prd["PRD"] --> planner["Planungsseite"] + planner --> agent["Agenten-Orchestrierung"] + agent --> model["Modellaufruf"] + agent --> db["Datenbank"] + db --> history["Historische Plaene"] + db --> admin["Admin-Statistiken und Protokolle"] +``` + +## Teil 2: Projektgeruest erstellen + +### 2.1 Frontend-Seiten generieren + +```text +Bitte generiere basierend auf dem aktuellen PRD ein Frontend-Geruest fuer eine intelligente Reiseplanungs-Agenten-Plattform. + +Anforderungen: +1. Seiten: Startseite, Planungsseite, Reisdetails, Verlauf, Admin +2. Planungsseite links: Formular, rechts: Ergebnisvorschau +3. Zunaechst nur Seitenstruktur mit Mock-Daten +4. Stil wie ein modernes KI-Produkt +``` + +### 2.2 Seitenstruktur ueberpruefen + +- [ ] Formularfelder der Planungsseite gemaess PRD +- [ ] Ergebnisbereich zeigt strukturierte Reisedaten +- [ ] Verlaufsseite zeigt mehrere Plaene +- [ ] Admin-Seite zeigt Statistiken + +## Teil 3: Iterative Entwicklung + +### 3.1 Modulweise vorgehen + +1. **Auth**: Registrierung, Login +2. **Planungsformular**: Strukturierte Eingabe (Startort, Ziel, Datum, Budget, Praeferenzen) +3. **Agenten-Orchestrierung**: Eingabe empfangen > Modell aufrufen > Strukturierte Ausgabe parsen +4. **Ergebnisanzeige**: Reiseplan tageweise, Budgetaufteilung, Empfehlungen +5. **Verwaltung**: Plaene speichern, neu generieren, exportieren +6. **Admin-Dashboard**: Beliebte Ziele, fehlgeschlagene Aufgaben, Benutzerfeedback +7. **Aufgabenstatus**: Generierung laeuft / Erfolg / Fehler mit Fehlerprotokollen + +### 3.2 Modul-Selbstpruefung + +| Pruefpunkt | Verifikationsmethode | +|------------|---------------------| +| Eingabevollstaendigkeit | Formularfelder gemaess PRD | +| Strukturierte Ausgabe | Reiseplan als strukturierte Daten (kein Textblock) | +| Datenkonsistenz | trip, itinerary, logs Daten synchron | +| Abschlussverifikation | "Eingabe > Generieren > Speichern > Neu generieren" vollstaendig | + +## Teil 4: Test und Bereitstellung + +### 4.1 End-to-End-Tests + +- Reiseparameter eingeben > Tagesreiseroutine generieren > Budgetaufteilung anzeigen > Im Verlauf speichern +- Aus dem Verlauf eine neue Reise generieren +- Administrator sieht Aufgabenstatistiken und Fehlerprotokolle + +## Liefergegenstaende + +- [ ] Online-Demo-Link +- [ ] Quellcode-Repository (mit README) +- [ ] PRD-Dokument +- [ ] Kernseiten-Screenshots +- [ ] 60-Sekunden-Demo-Video + +## Bewertungskriterien + +| Dimension | Grundanforderung | Erweiterte Anforderung | +|-----------|------------------|------------------------| +| PRD-Alignment | Seiten, Funktionen, Datenstruktur gemaess PRD | Designentscheidungen klar erklaeren | +| Produktabschluss | Planung > Speichern > Verlauf > Neu generieren lauffaehig | Export und Freigabe unterstuetzt | +| Ausgabequalitaet | Reiseplan strukturiert und lesbar | Budgetaufteilung angemessen, Empfehlungen zielgerichtet | +| Admin-Faehigkeit | Aufgabenstatistiken und Fehlerprotokolle einsehbar | Analyse beliebter Ziele vorhanden | +| Engineering | Frontend, Backend, DB, Modellaufruf verbunden | Aufgabenstatus-Management vollstaendig | + +## Referenzmaterialien + +- [UI-Design](../../frontend/ui-design/) +- [Moderne Komponentenbibliothek](../../frontend/modern-component-library/) +- [Von der Datenbank zu Supabase](../../backend/database-supabase/) +- [API-Code schreiben](../../backend/ai-interface-code/) +- [Git und GitHub](../../backend/git-workflow/) +- [Web-Anwendungen bereitstellen](../../backend/zeabur-deployment/) diff --git a/docs/de-de/stage-2/backend/ai-interface-code/index.md b/docs/de-de/stage-2/backend/ai-interface-code/index.md new file mode 100644 index 0000000..643d139 --- /dev/null +++ b/docs/de-de/stage-2/backend/ai-interface-code/index.md @@ -0,0 +1,167 @@ +# Grossmodell-gestuetzte Entwicklung von Backend-Schnittstellencode und -dokumentation + +In den vorherigen Lektionen haben wir gelernt, wie man Tools wie Figma fuer UI-Designentwuerfe verwendet, wie man mit AI schnell statische Frontend-Seiten generiert und wie man Supabase nutzt, um Datenbanken aufzubauen und eine erste Benutzerauthentifizierung zu realisieren. Jetzt stellt sich naturgemaess die Frage: Wie gelangen die Daten nach dem Klick auf diese dynamischen Buttons unbemerkt in Supabase? Wenn wir komplexere Geschaeftslogik ausfuehren muessen (wie gleichzeitige Zahlungen, zeitgesteuerte Push-Benachrichtigungen oder sensible Datenverarbeitung), ist es sicher, die Datenbank direkt vom Frontend aus zu verbinden? + +Das fuehrt uns zu einem entscheidenden Element der modernen Webentwicklungsarchitektur: der **Backend-API-Schnittstelle**. + +Anstatt in der Vergangenheit hunderte Zeilen Backend-Routen, Controller und Parameter-Validierungslogik manuell zu tippen, koennen wir heute die leistungsstarke Code-Generierungsfaehigkeit von Grossmodellen nutzen und das muehsame Grundgeruest von AI schreiben lassen. In dieser Lektion werden wir den Teufelskreis "AI schreibt nur vage und oberflaechlich" verlassen und dir anhand echter Geschaeftsszenarien zeigen, wie du durch hochwertige Prompts das Grossmodell dazu bringst, robuste, branchenkonforme Node.js-Backend-Schnittstellen zu schreiben und automatisch API-Dokumentation sowie Testfaelle zu generieren. + +> :bulb: **Vorkenntnisse** +> +> Bevor du mit diesem Abschnitt beginnst, wird empfohlen, folgende Inhalte zu kennen: +> - [Von der Datenbank zu Supabase](../database-supabase/) - Datenbank- und Datenmodellkonzepte verstehen. +> - [Git und GitHub verwenden lernen](../git-workflow/) - Vertrautheit mit Versionskontrolle in der Projektentwicklung. +> - [Was ist ein Terminal / eine Kommandozeile](/de-de/appendix/2-development-tools/command-line-shell) - Projektinitialisierung und -start erfordern grundlegende Kommandozeilen-Operationen. + +# Was du lernen wirst + +1. **Was ist eine API-Schnittstelle**: Die Bruecke der Frontend-Backend-Kommunikation und RESTful-Designrichtlinien verstehen. +2. **Grossmodell-gestuetzte Serviceerstellung**: Wie man durch strukturierte Prompts AI beim Aufbau eines Node.js + Express-Basisprojekts unterstuetzt. +3. **Schnittstellenlogik-Entwicklung**: Das Grossmodell zur Generierung von CRUD-Schnittstellen (Erstellen, Lesen, Aktualisieren, Loeschen) mit strenger Geschaeftsvalidierung und Supabase-Datenbankanbindung leiten. +4. **Automatisierte API-Dokumentation**: Das Grossmodell basierend auf Code rückwaerts OpenAPI/Swagger-Dokumentation generieren lassen, die branchenueblich fuer die teamuebergreifende Zusammenarbeit ist. +5. **Test- und Integrations-Loop**: Grossmodelle nutzen, um Postman-Testkollektionen und Jest-Einheitentests zu generieren, die die Codequalitaet absichern. + +--- + +# 1. Warum brauchen wir API-Schnittstellen? + +Im traditionellen Verstaendnis ist das Frontend "das, was man sieht", und die Datenbank ist "das Lager, in dem Dinge gespeichert werden". Aber dazwischen fehlt ein Dispatcher. Wenn du dir die gesamte Anwendung als ein Restaurant vorstellst: +- **Frontend (Client)** ist die Speisekarte und der Bestelltisch des Restaurants, wo Gaeste Gerichte durchsuchen und Bestellungen aufgeben. +- **Datenbank (Supabase etc.)** ist die Kueche des Restaurants, in der alle Zutaten und Buecher gelagert werden. +- **Backend-API-Schnittstelle** ist der Kellner des Restaurants. Gaeste koennen nicht direkt in die Kueche stuermen, um Zutaten zu holen (das waere nicht nur chaotisch, sondern wuerde auch Sicherheitsprobleme verursachen). Stattdessen muessen sie ihre "Bestellanliegen" (HTTP Request) dem Kellner mitteilen. Der Kellner ueberprueft diese (Parametervalidierung, Berechtigungsauthentifizierung), holt dann die entsprechenden Inhalte aus der Kueche und bringt die "fertigen Gerichte" (HTTP Response, normalerweise im JSON-Format) zurueck zum Gast. + +Durch API-Schnittstellen erreichen wir eine klare **Trennung von Frontend und Backend**: Das Frontend kuemmert sich nur um das Rendering der Seiten, waehrend das Backend sich auf Geschaeftslogik, Datenverarbeitung und Sicherheitsmassnahmen konzentriert. + +--- + +# 2. Projektarchitektur-Design und Initialisierung + +Eine klar strukturierte Projektbasis ist die Voraussetzung dafuer, dass das Grossmodell guten Code schreiben kann. Bevor wir AI Code schreiben lassen, muessen wir selbst eine Vorstellung von der Projektstruktur haben. + +## 2.1 Haeufige API-Projektstruktur + +Selbst wenn wir ein Grossmodell zur Code-Generierung verwenden, duerfen wir niemals den gesamten Code in eine einzige `server.js`-Datei stopfen. Eine wartbare Node.js-Backend-Architektur sieht typischerweise wie folgt aus: + +```text +my-api-project/ +├── .env # Sensible Umgebungsvariablen (wie API Keys, Datenbankverbindungsstring) +├── server.js # Projekteingang (Serverstart, globale Middleware-Registrierung) +├── package.json # Abhaengigkeitsverwaltungsdatei +├── src/ +│ ├── routes/ # Routen-Layer: Definiert URL-Pfade und Anfragemethoden +│ ├── controllers/ # Controller-Layer: Verarbeitet Anfrageparameter, ruft Services auf und gibt Antworten zurueck +│ ├── services/ # Service-Layer: Kapselt Datenbankinteraktion und Kerngeschaeftslogik +│ └── middlewares/ # Middleware: Login-Authentifizierung, globale Fehlerbehandlung +└── docs/ # Verzeichnis fuer API-Dokumentation +``` + +## 2.2 Projektinitialisierung mit AI + +Anstatt manuell `npm init` auszufuehren und Abhaengigkeiten einzeln zu installieren, koennen wir die oben genannten Vorgaben direkt als Prompt an das Grossmodell uebergeben: + +> :speaking_head: **Prompt an das Grossmodell (Beispiel):** +> "Hilf mir, ein Node.js-Backend-Projekt aufzubauen, das sich mit einer Supabase-Datenbank verbinden kann. Die Struktur soll klar sein, um die kuenftige Wartung zu erleichtern." + +Nach dem Ausfuehren des von AI zurueckgegebenen Codes erhaeltst du auf `localhost:3000` eine Backend-Anwendung mit Enterprise-Reife. + +--- + +# 3. Kernpraktikum: Grossmodell-gestuetzte Schnittstellenentwicklung + +Dies ist der wichtigste Teil dieses Kapitels. Der von Grossmodellen geschriebene Code weist haeufig "logische Luecken" oder "oberflaechliche Platzhalter" auf, weil der Entwickler nicht genug Kontext bereitgestellt hat. **Grossmodelle haben keine Angst vor komplexen Anforderungen, aber sie fuerchten vage Anforderungen.** + +Am Beispiel der Erstellungsschnittstelle fuer die `menu_items`-Tabelle (Menue-Tabelle), die wir im [Datenbank-Kapitel](../database-supabase/) erwaehnt haben, zeigen wir, wie man einen hochwertigen Prompt schreibt. + +## 3.1 Dem Grossmodell vollstaendigen Kontext geben + +Bevor du AI bittest, eine Schnittstelle zu schreiben, musst du unbedingt die **Datenbankfeld-Definition (Schema)** und die **konkreten Einschraenkungen** bereitstellen. + +> :speaking_head: **Hochwertiger Prompt (Vorlage):** +> "Hilf mir, eine Schnittstelle zum Hinzufuegen eines Menueeintrags zu schreiben. Der Eintrag hat Produktname, Preis, Kategorie (Burger, Snacks, Getraenke) und ob er verfuegbar ist. Produktname und Preis sind Pflichtfelder, der Preis darf nicht negativ sein. Bei fehlerhafter Benutzereingabe soll eine Fehlermeldung angezeigt werden." + +## 3.2 Den vom Grossmodell generierten Code ueberpruefen + +Der vom Grossmodell generierte Code ist typischerweise wie folgt strukturiert und klar in Verantwortlichkeiten unterteilt: + +```javascript +// services/menuService.js +const { createClient } = require('@supabase/supabase-js'); +const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY); + +exports.createMenuItem = async (menuData) => { + // Supabase SDK aufrufen, um Daten in die Tabelle einzufuegen + const { data, error } = await supabase + .from('menu_items') + .insert([menuData]) + .select(); + + if (error) throw new Error(`Datenbank-Einfuegen fehlgeschlagen: ${error.message}`); + return data[0]; +}; +``` + +Man erkennt, dass der auf diese Weise generierte Code nicht nur eine vernuenftige Struktur aufweist, sondern auch die Initialisierung von Supabase, die Fehlerbehandlung sowie die Ausnahmebehandlung beruecksichtigt. Dies ist ein grosser Unterschied zu dem "Spaghetti-Code", den man erhalten wuerde, wenn man einfach "schreib mal eine Erstellungsschnittstelle" verlangt. + +--- + +# 4. Haende frei: Automatische Generierung von API-Dokumentation + +Fuer ein Entwicklungsteam ist eine API ohne Dokumentation ein Blindgatter. Frontend-Entwickler koennen nicht erraten, welche Parameter du erwartest, und auch nicht vorhersagen, welche Struktur zurueckgegeben wird. Die branchenueblichste API-Beschreibungsspezifikation ist **OpenAPI (frueher auch Swagger genannt)**. + +Frueher war das manuelle Schreiben von Swagger-Dokumentation im YAML- oder JSON-Format aeusserst schmerzhaft und fehleranfaellig. Heute ist dies eines der Gebiete, auf denen Grossmodelle am besten sind. + +Du kannst einfach den Code deiner `routes` und `controllers` auswaehlen und ihn dem Grossmodell uebergeben: + +> :speaking_head: **Prompt fuer die Dokumentationsgenerierung:** +> "Hilf mir, basierend auf dem obigen Code eine API-Dokumentation zu generieren. Beschreibe genau, was jeder Parameter bedeutet und welche Daten zurueckgegeben werden, um die Zusammenarbeit mit den Frontend-Kollegen zu erleichtern." + +In diesem Prozess kannst du AI sogar bitten, Feldbeschreibungen (Description) und Mock-Daten zu ergaenzen (wie `price_cents: 1200` fuer 12 Euro), was die Kommunikationskosten drastisch senkt. + +--- + +# 5. Absicherung: Testcode und Postman-Kollektionen generieren + +Code geschrieben, Dokumentation erstellt -- es fehlt nur noch der letzte Schritt: Ueberpruefen, ob der Code tatsaechlich laeuft. + +## 5.1 Postman / Apifox Testkonfiguration generieren + +In der Schnittstellenentwicklung verwenden wir normalerweise Tools wie Postman, um HTTP-Anfragen vom Frontend zu simulieren. Ohne Grossmodell musst du manuell die URL eingeben, Header (Anfrage-Header) einzeln hinzufuegen und den JSON-Anfrage-Body zusammenbauen. + +Du musst AI nur anweisen: +> "Wandle diese API-Dokumentation in ein Format um, das Postman importieren kann. Es soll Beispiele fuer korrekte und fehlerhafte Anfragen enthalten." + +Nachdem du den JSON-Text erhalten hast, speichere ihn als `menu_api.json` und ziehe ihn in Postman. Sofort hast du eine out-of-the-box-Test-Klick-Oberflaeche. + +## 5.2 Automatisierte Einheitentests schreiben + +Wenn du eine noch strengere technische Qualitaet anstrebst, kannst du das Grossmodell bitten, dir mit Testframeworks wie `Jest` Einheitentests (Unit Tests) zu schreiben, die die Kerngeschaeftslogik auf Grenzfalle testen (z. B. ob die Validierung auf Datenbankebene greift, wenn ein negativer Preis uebergeben wird). + +--- + +# 6. Backend-Schnittstellen: Unbedingt bekannte Best Practices + +Selbst mit AI-Unterstuetzung musst du als "Torwaechter" des gesamten Systems die folgenden Kernprinzipien kennen und ueberpruefen: + +1. **RESTful-konforme Pfadbenennung**: + - Gutes Design: `GET /api/users` (Benutzerliste abrufen), `POST /api/users` (Benutzer erstellen). URLs sollten "Ressourcen"-Substantive darstellen. + - Schlechtes Design: `POST /api/getUser` oder `POST /api/createUser`. Verben sollten durch die HTTP-Methoden (GET/POST/PUT/DELETE) ausgedrueckt werden. +2. **Standardisierte HTTP-Statuscodes**: + - 200/201: Anfrage erfolgreich / Ressource erfolgreich erstellt. + - 400: Bad Request, Parameterformat des Frontends fehlerhaft, Pflichtfelder fehlen. + - 401/403: Unauthorized / Forbidden, Benutzer nicht angemeldet oder keine Berechtigung. + - 404: Not Found, Ressource existiert nicht. + - 500: Server Error, Backend-Code-Fehler oder Datenbankausfall. Den Fehler-Callstack niemals direkt dem Frontend preisgeben (Sicherheitsrisiko). +3. **Niemals Benutzereingaben vertrauen**: Frontend-Eingaben koennen gefaelscht sein. Alle Kernparameter-Validierungen muessen im Backend erneut durchgefuehrt werden. + +# 7. Zusammenfassung + +Durch dieses Kapitel hast du eine wirkliche Perspektivenveraenderung in der Entwicklung vollzogen: Du bist nicht mehr der "Tipper", der in Syntax und Satzzeichen feststeckt, sondern aufgestiegen zum **Systemdesigner und Architektur-Kommandanten**. +Du hast Folgendes gelernt: +1. Das Kernsystemdenken von **API-Schnittstellen und Frontend-Backend-Trennung**. +2. **Wie man durch die Bereitstellung von Kontext und Schichtstruktur-Konzepten** die Qualitaet des vom Grossmodell generierten Server-Codes erheblich steigert. +3. Die muehsame **Dokumentationserstellung** und **Testfall-Konstruktion** geschickt in automatisierte Aufgaben verwandelt, die AI besonders gut beherrscht. +4. In Kombination mit dem zuvor erlernten **Supabase**-Wissen den vollstaendigen Datenfluss von der Client-Anfrage bis zur Datenbankaktualisierung durchgaengig geschlossen. + +::: tip :bulb: Naechste Schritte +Wenn dein Datenfluss und dein Backend-Service bereit sind, koennen sie derzeit nur auf deinem lokalen Computer "fuer sich selbst" laufen. In den naechsten Kapiteln werden wir lernen, wie man diesen muehsam aufgebauten Service auf einem **overtentlichen Server bereitstellt (Deploy)**, sodass dein Produkt von Nutzern weltweit aufgerufen werden kann. +::: diff --git a/docs/de-de/stage-2/backend/database-supabase/index.md b/docs/de-de/stage-2/backend/database-supabase/index.md new file mode 100644 index 0000000..b8d645e --- /dev/null +++ b/docs/de-de/stage-2/backend/database-supabase/index.md @@ -0,0 +1,882 @@ +# Von der Datenbank zu Supabase + +In der letzten Lektion haben wir die grundlegende Verwendung der UI-Design-Tools MasterGo und Figma kennengelernt, konnten Code ueber GitHub abrufen und版本 verwalten sowie Websites ueber Zeabur bereitstellen, um unsere Anwendungen einer breiteren Nutzergemeinde zugaenglich zu machen. + +Um den Wissenstransfer zu erleichtern, lassen Sie uns vor Beginn der neuen Inhalte zu Design-Tools und Bereitstellung einige der Kernpunkte der letzten Lektion anhand einiger einfacher Fragen kurz wiederholen: + +1. Was sind Frontend-Design-Tools, Figma und MasterGo - Definition und Verwendung. +2. Grundlegende Methoden zur Umsetzung von Designentwuerfen in Code. +3. Was ist GitHub, wie konfiguriert man SSH und wie erstellt man sein erstes Repository. +4. Was bedeutet Bereitstellung (Deployment), wie verwendet man Zeabur und wie stellt man GitHub- oder lokalen Code oeffentlich zugaenglich bereit. + +Wenn dir bei einer dieser Fragen noch Unklarheiten bleiben, empfiehlt es sich, die Dokumente und Unterlagen der letzten Lektion noch einmal durchzugehen. Du kannst jederzeit Fragen in der WeChat-Lerngruppe stellen. + +In dieser Lektion werden wir lernen, wie eine App oder Website von einem lauffaehigen Zustand zu einem echten Online-Produkt wird: Neben der Verwaltung verschiedener Datenveraenderungen waehrend des Programmablaufs durch eine Datenbank benoetigen wir auch ein vollstaendiges Benutzersystem (Registrierung, Anmeldung, Berechtigungen usw.) sowie weitere wichtige Backend-Faehigkeiten. Wir werden Supabase als Backend-Service-Plattform als Leitfaden verwenden und damit zunaechst die beiden Grundfunktionen "Datenbank + Benutzersystem" implementieren. Anschliessend werden wir die von Supabase bereitgestellten Komponenten als Referenz nutzen, um die Kernmodule moderner Cloud-Backend-Dienste besser zu verstehen sowie deren spezifische Funktionen und Wirkungsweise. + +# Was du lernen wirst + +1. Was sind Daten, was ist eine Datenbank sowie haeufige Datenbanken und deren Verwendung +2. Was ist Supabase und wie man grundlegende Datenbankoperationen mit Supabase durchfuehrt +3. Wie man Supabase nutzt, um einer App grundlegende Benutzerverwaltungsfunktionen hinzuzufuegen +4. Supabase-Erweiterungsfunktionen erlernen: Realtime, Storage, Edge Functions +5. Google- und GitHub-Login-Unterstützung fuer Supabase hinzufuegen + +- Eine Basisanwendung, die Benutzerregistrierung/-anmeldung unterstuetzt und Daten in einer Online-Datenbank speichern kann +- Eine wiederverwendbare Supabase-Backend-Codevorlage (Datenbank, Benutzerverwaltung usw.) fuer die direkte Verwendung in spaeteren Projekten + +# 1. Was ist eine Datenbank + +## 1.1 Was sind Daten + +In der digitalen Welt sind Daten (Data) ueberall präsent. Kurz gesagt: Daten sind Traeger von Informationen. Die Kontaktdaten deiner Freunde, ein WeChat-Artikel, ein kurzes Video, der Charakterlevel in einem Spiel - all dies sind Daten. In unserer Anwendung sind Daten alle Informationen, die aufgezeichnet und verwaltet werden muessen, wie z. B. Benutzerprofile, Bestellverlaufe, Programmeinstellungen usw. + +Im Allgemeinen haben Daten in einem Programm unterschiedliche Darstellungsformen. Die einfachste Form ist die Variable. Wir koennen verschiedene Variablen verwenden, um einfache Zahlen aufzuzeichnen: + +```python +# Python variable definition examples + +# Integer variable: stores age information +age = 30 + +# Boolean variable: stores status (whether active) +is_active = True # True means active, False means inactive + +# List variable: stores a set of score data +scores = [85, 92, 78, 90] # Contains 4 integer elements representing different scores + +# Dictionary variable: stores multiple related information of a user +user_info = { + "age": 30, # Key "age" corresponds to the value of age + "height": 1.80, # Key "height" corresponds to the value of height (unit: meter) + "login_count": 156 # Key "login_count" corresponds to the value of login times +} +``` + +Fuer komplexe Daten wie persoenliche Profile oder Bestellverlaufe koennen wir diese in ausfuehrlicheren Tabellen darstellen: + +| user_id | name | email | +| ------- | ----- | ----------------- | +| 1001 | Alice | alice@example.com | +| 1002 | Bob | bob@example.com | + +| order_id | user_id | amount | status | +| -------- | ------- | ------ | --------- | +| 901 | 1001 | 29.99 | completed | +| 902 | 1002 | 15.50 | pending | + +Fuer Daten mit komplexer Struktur, hierarchischen Beziehungen oder variablen Feldern koennen wir das JSON-Format zur Beschreibung verwenden. Es ist das universelle Zwischenformat des Internets, das von fast allen Programmen gelesen und geparst werden kann, was den Datenaustausch zwischen Systemen sehr bequem macht. + +```json +{ + "order_id": 901, + "user_id": 1001, + "amount": 29.99, + "status": "completed", + "items": [ + { "sku": "BG-001", "name": "Rindfleisch-Burger", "quantity": 1, "price": 18.00 }, + { "sku": "SD-003", "name": "Pommes frites", "quantity": 1, "price": 6.99 }, + { "sku": "DK-002", "name": "Cola", "quantity": 1, "price": 5.00 } + ], + "shipping_address": { + "street": "Technologiepark-Strasse 123", + "city": "Shenzhen", + "zip_code": "518057" + } +} +``` + +Darueber hinaus koennen Daten auch als Vektoren (Vectors) codiert werden. Vektordaten sind in der Regel numerische Darstellungen, die durch KI-Modelle (wie Embedding-Modelle) aus unstrukturierten Daten wie Text, Bildern oder Audio generiert werden. + +`[0.123, -0.456, 0.789, ..., -0.234]` (ein Array aus Hunderten oder Tausenden von Gleitkommazahlen) + +Insgesamt gibt es in der realen Welt viele verschiedene Datenformen und Verwendungszwecke, die eine detaillierte Analyse erfordern. Jede Datenart benoetigt moeglicherweise eine spezielle Datenbank zur Speicherung. + +![](/zh-cn/stage-2/backend/database-supabase/images/image1.png) + +## 1.2 Warum wir Datenbanken brauchen + +Wir haben bereits gelernt, dass Daten in der realen Welt oft komplex strukturiert sind. **Um diese Daten effizient zu speichern und zu nutzen, benoetigen wir ein spezielles Programm oder einen Container zu ihrer Verwaltung** - dies war der urspruengliche Grund fuer die Entstehung von Datenbanken (Databases). Eine Datenbank ist im Kern ein spezielles Programm, dessen Hauptaufgabe darin besteht, Daten zu standardisieren, sicher zu speichern, systematisch zu verwalten und effiziente Abfragen zu ermoeglichen. + +Stell dir vor, was ohne Datenbanken passieren wuerde: Wenn Benutzer den Browser schliessen oder die App verlassen, gehen alle temporaer geladenen Informationen verloren. Wir koennen weder den Nutzungsstatus (wie Anmeldedaten, personalisierte Einstellungen) dauerhaft speichern noch Schluesseldaten zwischen verschiedenen Benutzern teilen (wie Produktbestaende, Bestellaufzeichnungen). Wir brauchen ein System, das alle unsere Daten speichert! + +Flexibler ist die Bereitstellung der Datenbank: Sie kann auf einem lokalen Server fuer lokale Datenverwaltung bereitgestellt werden oder in der Cloud. Cloud-Datenbanken unterstuetzen elastische Skalierung (Scale) und koennen mit wachsenden Datenmengen und Zugriffszahlen erweitert werden, um massive Daten und hohe Parallelitaet zu bewaeltigen. Selbst bei stark steigenden Benutzerzahlen bleibt eine gute Nutzungserfahrung gewaehrleistet. + +Zusammenfassend loesen Datenbanken durch effiziente dauerhafte Speicherung, feinkoernige Verwaltung und schnelle Abfragefaehigkeiten die folgenden Kernprobleme: + +- **Dauerhafte Datenspeicherung**: Ohne Datenbank wuerden Daten nur im Arbeitsspeicher der Anwendung existieren und beim Schliessen der Anwendung verloren gehen. Eine Datenbank loest dieses Problem, indem sie Daten dauerhaft auf Festplatten und anderen Speichermedien ablegt und so die langfristige Aufbewahrung sicherstellt. +- **Komfortable Datenabfrage und -analyse**: Datenbanken bieten leistungsstarke Abfragesprachen (wie SQL), mit denen Benutzer umfangreiche Daten einfach, effizient und komplex abfragen, filtern und analysieren koennen, um informiertere Geschaeftsentscheidungen zu treffen. +- **Hochleistung und gleichzeitigen Zugriff**: Durch Indizierung, Abfrage-Caching, Verbindungspools und verteilte Architekturen koennen Datenbanken Abfragen in Millisekunden beantworten und tausende gleichzeitige Benutzerzugriffe unterstuetzen. +- **Datenintegritaet und -konsistenz**: Datenbanken stellen durch Mechanismen wie Einschraenkungen (Constraints) und Trigger sicher, dass Daten genau und konsistent sind. +- **Datensicherheit**: Datenbanken bieten starke Sicherheitsmechanismen einschliesslich Benutzerauthentifizierung, Zugriffskontrolle und Datenverschluesselung. + +## 1.3 Relationale und nicht-relationale Datenbanken + +Wir haben bereits den Kernwert, die Bereitstellungsoptionen und die elastischen Vorteile von Datenbanken kennengelernt. Bei der tatsaechlichen Auswahl stehen wir zunaechst vor zwei Hauptkategorien: relationale und nicht-relationale Datenbanken (NoSQL). + +Relationale Datenbanken sind wie streng strukturierte Excel-Tabellen: Alle Daten muessen im Voraus ein Format definiert haben (Schema). Sie werden durch Verknuepfungsfelder (wie Ausweisnummern) miteinander verbunden. Ihr Vorteil ist praezise und zuverlaessige Datenverarbeitung, besonders geeignet fuer Bankueberweisungen, Bestandsverwaltung und andere fehlerkritische Szenarien. Der Nachteil ist, dass Strukturaenderungen aufwaendig sind und die Leistung bei riesigen Datenmengen begrenzt sein kann. + +Nicht-relationale Datenbanken sind wie flexible Ordner, die Dokumente, Bilder oder Schluessel-Wert-Paare in unterschiedlichen Formaten speichern koennen, ohne die Struktur jedes Datensatzes vorab festzulegen. Sie eignen sich besser fuer sich schnell aendernde Anforderungen und extrem grosse Datenmengen. + +| Datenbanktyp | Name | Preis | Anwendungsbereich | +| ------------------------ | ----------------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Relationale Datenbank | RDS MySQL | Niedrig | Lern- und kleine Website-Projekte; mittlere Datenbank-Szenarien; Cluster fuer hohe Zugriffsauslastung | +| | RDS SQL Server | Hoch | Test- und kleine kommerzielle Websites; kommerzielle Websites auf Unternehmensebene; Cluster fuer unterbrechungsfreien Betrieb | +| | RDS PostgreSQL | Niedrigste | Lern- und kleine Website-Projekte; mittlere Datenbank-Szenarien; hochperformante Cluster | +| NoSQL-Datenbank | Redis | Mittel | Persistenz-Datenbank fuer hohe Verfuegbarkeit; Cache-Beschleunigungsschicht | +| | MongoDB | Mittel | Einzelknoten fuer Entwicklung/Tests; Replikat-Sets fuer hoehere Leseleistung; Sharded Cluster fuer Echtzeit-Online-Geschaeft | + +### Beispiel: Relationale Datenbank (SQL) + +In einer SQL-Datenbank speichern wir verschiedene Datentypen in separaten Tabellen, die durch "Fremdschluessel" (Foreign Keys) miteinander verknuepft sind. + +- `users` Tabelle: + +| user_id ( Primaerschluessel) | username | email | +| ---------------------------- | -------- | ----------------- | +| 101 | Alice | alice@example.com | +| 102 | Bob | bob@example.com | + +- `posts` Tabelle: + +| post_id ( Primaerschluessel) | title | content | author_id ( Fremdschluessel) | +| ---------------------------- | ------------ | ------------------------------------------ | ---------------------------- | +| 1 | SQL kennenlernen | Ein Artikel ueber SQL-Datenbanken... | 101 | +| 2 | NoSQL-Einfuehrung | NoSQL bietet flexible Datenmodelle... | 102 | + +- `comments` Tabelle: + +| comment_id ( Primaerschluessel) | body | commenter_id ( Fremdschluessel) | post_id ( Fremdschluessel) | +| ------------------------------- | ---------------------- | ------------------------------- | -------------------------- | +| 1001 | Sehr gut geschrieben! | 102 | 1 | +| 1002 | Gelernt. | 101 | 2 | + +- `tags` Tabelle: + +| tag_id ( Primaerschluessel) | tag_name | +| --------------------------- | ---------- | +| 51 | Datenbank | +| 52 | Technologie | +| 53 | Einfuehrung | + +- `post_tags` Tabelle (fuer die Viele-zu-Viele-Beziehung): + +| post_id ( Fremdschluessel) | tag_id ( Fremdschluessel) | +| -------------------------- | ------------------------- | +| 1 | 51 | +| 1 | 52 | +| 2 | 51 | +| 2 | 52 | +| 2 | 53 | + +Um "alle Informationen zu Alices Artikel (post_id=1)" abzufragen, ist eine JOIN-Abfrage ueber mehrere Tabellen erforderlich: + +```sql +SELECT + p.title, + p.content, + u.username AS author, + c.body AS comment, + t.tag_name AS tag +FROM + posts p +JOIN + users u ON p.author_id = u.user_id +LEFT JOIN + comments c ON p.post_id = c.post_id +LEFT JOIN + post_tags pt ON p.post_id = pt.post_id +LEFT JOIN + tags t ON pt.tag_id = t.tag_id +WHERE + p.post_id = 1; +``` + +### Beispiel: Nicht-relationale Datenbank (NoSQL) + +NoSQL-Datenbanken (wie MongoDB) buendeln alle relevanten Daten in einem einzigen Dokument: + +```json +{ + "_id": 1, + "title": "SQL kennenlernen", + "content": "Ein Artikel ueber SQL-Datenbanken...", + "author": { + "user_id": 101, + "username": "Alice", + "email": "alice@example.com" + }, + "tags": [ + "Datenbank", + "Technologie" + ], + "comments": [ + { + "comment_id": 1001, + "body": "Sehr gut geschrieben!", + "commenter": { + "user_id": 102, + "username": "Bob" + } + } + ] +} +``` + +Der Vorteil: Alle Daten koennen mit einer einzigen Abfrage abgerufen werden, ohne JOINs. Der Nachteil: Datenredundanz kann zu Konsistenzproblemen fuehren. + +# 2. Supabase + +Nachdem wir verschiedene Datenbanktypen vorgestellt haben, muessen wir ein groesseres Bild betrachten: **Backend-Services**. Eine vollstaendige Anwendung besteht in der Regel aus "Frontend + Backend". Das Frontend ist fuer die Seitenanzeige und Benutzerinteraktion zustaendig, waehrend das Backend Datenverwaltung, Benutzeranmeldung, Geschaeftslogik und mehr uebernimmt. + +Um diese wiederkehrenden Aufgaben zu vereinfachen, entstand **BaaS (Backend as a Service)**: Datenbank, Benutzerauthentifizierung, Dateispeicher, Echtzeitfaehigkeiten und weitere gängige Backend-Funktionen werden als Cloud-Plattform gebuendelt, die Entwickler ueber SDK/API direkt nutzen koennen, ohne Infrastruktur von Grund auf neu aufzubauen. + +[Supabase](https://supabase.com/) kann als repraesentative Plattform der neuen BaaS-Generation betrachtet werden: Sie nutzt PostgreSQL als Kern-Datenbank und integriert Auth, Storage, Realtime, Edge Functions, Vector und weitere Backend-Faehigkeiten zu einer "Postgres-zentrierten All-in-One-Backend-Plattform". + +## 2.1 Schritt-fuer-Schritt-Anleitung + +Nachdem wir die Positionierung von Supabase verstanden haben, werden wir nun die Kernfunktionen der Supabase-Konsole Schritt fuer Schritt erklaeren. + +![](/zh-cn/stage-2/backend/database-supabase/images/image2.png) + +Besuche die Supabase-Website, melde dich an und klicke auf der Konsole-Startseite auf "New project". + +![](/zh-cn/stage-2/backend/database-supabase/images/image3.png) + +Nach erfolgreicher Erstellung zeigt die linke Seitenleiste alle Kernfunktionsmodule an. + +![](/zh-cn/stage-2/backend/database-supabase/images/image4.png) + +### Tabellen-Editor (Table Editor) + +Der Tabellen-Editor ist der visuelle Datentabellen-Editor von Supabase. Er ermoeglicht es dir, Daten in der Datenbank direkt wie in Excel anzuzeigen und zu aendern, ohne SQL-Statements schreiben zu muessen. + +![](/zh-cn/stage-2/backend/database-supabase/images/image5.png) + +Bemerkenswert ist das Schema-Konzept. Schema kann als "Ressourcen-Container" innerhalb der Datenbank verstanden werden. Klicke auf das Dropdown-Menue "Schema" oben im Editor, um zwischen verschiedenen Containern zu wechseln. Im Alltag sind zwei Schemas besonders relevant: + +- `public`: Der Standard-Container fuer oeffentliche Ressourcen. Alle von Entwicklern erstellten Geschaeftstabellen werden hier gespeichert. +- `auth`: Der exklusive Container fuer die Benutzerauthentifizierung. + +![](/zh-cn/stage-2/backend/database-supabase/images/image6.png)![](/zh-cn/stage-2/backend/database-supabase/images/image7.png) + +### SQL-Editor + +Der SQL-Editor ist der SQL-Ausfuehrungsbereich von Supabase. Du kannst grosse Sprachmodelle SQL-Statements generieren lassen, diese rechts eingeben und auf "RUN" klicken. + +![](/zh-cn/stage-2/backend/database-supabase/images/image8.png) + +### Datenbankverwaltung (Database) + +Database ist das Datenbankverwaltungszentrum von Supabase. Es ermoeglicht die visuelle Verwaltung aller Datentabellen und zeigt Beziehungen zwischen Tabellen an (Fremdschluessel-Beziehungen). + +![](/zh-cn/stage-2/backend/database-supabase/images/image9.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image10.png) + +### Authentifizierung (Authentication) + +Authentication verwaltet Benutzerregistrierung, Anmeldung und Berechtigungen. Es bietet sofort einsatzbereite Funktionen fuer Registrierung, Anmeldung, Passwort-Zuruecksetzen, E-Mail-Verifizierung und unterstuetzt OAuth-Anmeldung von Drittanbietern (wie WeChat, GitHub, Google). Alle Benutzerdaten werden automatisch in der Tabelle `auth.users` gespeichert. + +![](/zh-cn/stage-2/backend/database-supabase/images/image11.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image12.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image13.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image14.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image15.png) + +### Speicher (Storage) + +Storage ist das Speichersystem von Supabase, kompatibel mit dem S3-Konzept von Amazon Cloud. Es kann beliebige Dateitypen speichern (Bilder, Videos, Dokumente, Audio usw.) und bietet Zugriffsberechtigungsverwaltung und Download-Links. + +![](/zh-cn/stage-2/backend/database-supabase/images/image16.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image17.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image18.png) + +### Edge Functions + +Wenn du kein Backend bereitstellen moechtest, aber Datenbank- und Funktionsoperationen nutzen willst, kannst du Edge Functions verwenden. Sie sind global verteilte serverseitige Funktionen von Supabase, die auf Deno und TypeScript basieren. + +![](/zh-cn/stage-2/backend/database-supabase/images/image19.png) + +Ein Kernanwendungsfall von Edge Functions ist die Funktion als sichere Zwischenschicht zum Schutz vertraulicher Informationen und Authentifizierungsschluessel. + +![](/zh-cn/stage-2/backend/database-supabase/images/image20.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image21.png) + +```javascript +// Kernkonfiguration (mit deinen tatsaechlichen Daten ersetzen) +const projectId = "Deine Supabase-Projekt-ID"; +const functionName = "Name der Ziel-Edge-Function"; +const supabaseKey = "Supabase anon_key"; + +// Funktion aufrufen +async function callEdgeFunction() { + const url = `https://${projectId}.supabase.co/functions/v1/${functionName}`; + + try { + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${supabaseKey}` + }, + body: JSON.stringify({ order_id: "123", action: "refund" }) + }); + + const result = await response.json(); + console.log("Aufruf erfolgreich:", result); + } catch (error) { + console.error("Aufruf fehlgeschlagen:", error.message); + } +} + +callEdgeFunction(); +``` + +### Echtzeit-Datensynchronisation (Realtime) + +Realtime ist die Echtzeit-Datensynchronisations-Engine von Supabase. Sie ermoeglicht deiner Anwendung, sofortige Benachrichtigungen ueber Datenbankaenderungen zu empfangen, ohne wiederholt APIs abfragen zu muessen. + +### Projekteinstellungen (Project Settings) + +Project Settings ist der Bereich fuer erweiterte Konfiguration deines Supabase-Projekts. + +![](/zh-cn/stage-2/backend/database-supabase/images/image22.png) + +Im Einstiegsbereich fokussieren wir uns auf zwei Kernbereiche: Data API (fuer die Supabase URL) und API Keys (fuer anon public und service_role Schluessel). + +![](/zh-cn/stage-2/backend/database-supabase/images/image23.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image24.png) + +## 2.1 Erstelle deine erste SQL-Datentabelle + +Es gibt zwei gängige Methoden zum Erstellen von Datentabellen in Supabase: + +1. (Empfohlen) Lass dir von einem grossen Sprachmodell SQL-Statements fuer Supabase generieren und fuehre sie im SQL-Editor aus. +2. Ueber visuelle Operationen: Navigiere zu Database > Tables und klicke auf "New table". + +![](/zh-cn/stage-2/backend/database-supabase/images/image25.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image26.png) + +Fuer relationale Datenbanken ist die Verknuepfung zwischen Tabellen wichtig. Du kannst Fremdschluessel (Foreign Keys) unten hinzufuegen: + +![](/zh-cn/stage-2/backend/database-supabase/images/image27.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image28.png) + +## 2.3 SQL-Editor und grundlegende Datenbankoperationen + +Wir werden nun eine Reihe von SQL-Skripten schrittweise ausfuehren und die gängigen CRUD-Operationen (Create, Read, Update, Delete) kennenlernen. + +### 2.3.1 `CREATE` - Tabellenstruktur erstellen + +```sql +CREATE TABLE IF NOT EXISTS orders ( + id serial PRIMARY KEY, + user_id int NOT NULL, + status text NOT NULL, + amount numeric(10, 2) NOT NULL, + details jsonb, + placed_at timestamptz DEFAULT now(), + is_paid boolean DEFAULT false +); +``` + +Nach erfolgreicher Ausfuehrung siehst du die erstellte Tabelle im Tabellen-Editor: + +![](/zh-cn/stage-2/backend/database-supabase/images/image29.png) + +### 2.3.2 `INSERT` - Anfangsdaten einfuegen + +```sql +INSERT INTO orders (user_id, status, amount, details, placed_at, is_paid) VALUES + (2001, 'pending', 23.50, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '2 days', false), + (2002, 'paid', 50.00, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00}]}', now() - interval '1 day', true); +``` + +![](/zh-cn/stage-2/backend/database-supabase/images/image30.png) + +### 2.3.3 `SELECT` - Daten lesen und abfragen + +```sql +-- Alle Felder aller Bestellungen abfragen +SELECT * FROM orders; + +-- Nur ausstehende Bestellungen +SELECT id, user_id, amount FROM orders WHERE status = 'pending'; + +-- Nur bezahlte Bestellungen +SELECT id, status, is_paid, amount FROM orders WHERE is_paid = true; + +-- Artikelliste aus JSON extrahieren +SELECT id, details -> 'items' AS item_list FROM orders; +``` + +![](/zh-cn/stage-2/backend/database-supabase/images/image31.png) + +### 2.3.4 `INSERT` - Einzelnen Datensatz einfuegen + +```sql +INSERT INTO orders (user_id, status, amount, details, is_paid) +VALUES ( + 2012, 'paid', 9.99, + '{"items":[{"sku":"BGR002","name":"AIID Burger","qty":100,"price":1000}]}', + true +); +``` + +### 2.3.5 `UPDATE` - Vorhandene Daten aendern + +```sql +UPDATE orders SET status = 'paid', is_paid = true WHERE id = 1; +``` + +### 2.3.6 `DELETE` - Daten loeschen + +```sql +DELETE FROM orders WHERE placed_at < now() - interval '2 days'; +``` + +## 2.4 Zeilensicherheit (Row Level Security - RLS) + +Nachdem wir die grundlegenden Datenbankoperationen gelernt haben, muessen wir ein Kernkonzept fuer die Datensicherheit vertiefen: RLS (Row Level Security). + +RLS wurde entwickelt, um Datensicherheits- und Isolationsanforderungen zu loesen. Es ermoeglicht Entwicklern, feinkoernige Sicherheitsrichtlinien fuer Datenbanktabellen zu definieren und praezise zu steuern, welche Benutzer auf welche Zeilen einer Tabelle zugreifen koennen. + +In Supabase ist RLS eng mit dem Benutzerauthentifizierungssystem verknuepft. Supabase stellt eine spezielle Funktion `auth.uid()` zur Verfuegung, die direkt die eindeutige ID des aktuell angemeldeten Benutzers zurueckgibt. + +![](/zh-cn/stage-2/backend/database-supabase/images/image32.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image33.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image34.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image35.png) + +# 3. Erste SQL-Anwendung + +Nachdem wir die grundlegenden Datenbankoperationen und die RLS-Kernlogik gemeistert haben, betreten wir nun den praktischen Teil dieses Tutorials. Wir werden das Szenario "Bestellverwaltung fuer ein Burger-Restaurant" verwenden, um die haeufigsten Supabase-Operationen Schritt fuer Schritt zu demonstrieren. + +## 3.1 Supabase-Beispielprojekt klonen und starten + +Du kannst Trae oder Claude Code verwenden, um folgendes Repository zu klonen: https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos + +![](/zh-cn/stage-2/backend/database-supabase/images/image36.png) + +## 3.2 Projekt 1 - Burger-Restaurant Menue CRUD + +Wir nehmen `project-burger-shop-menu-crud-1` als Beispiel und lernen, wie man eine Datenbank mit SQL-Skripten initialisiert und das lokale Projekt mit Supabase verbindet. + +### Datenbank mit Skript erstellen + +Im Projektverzeichnis befindet sich ein Ordner `scripts` mit einer Datei `init.sql`, die automatisch alle datenbankbezogenen Ressourcen erstellt. + +### Verbindung zur Datenbank einrichten + +Es gibt zwei Methoden: + +1. Ueber Umgebungsvariablen in einer `.env`-Datei: + +``` +NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co +NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key +``` + +2. Direkt auf der Projektseite ueber den Einstellungs-Button. + +```JavaScript +import { createClient, type SupabaseClient } from '@supabase/supabase-js'; + +export function maybeCreateBrowserClient(): SupabaseClient | null { + const url = process.env.NEXT_PUBLIC_SUPABASE_URL; + const anon = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; + if (!url || !anon) return null; + return createClient(url, anon); +} +``` + +![](/zh-cn/stage-2/backend/database-supabase/images/image37.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image38.png) + +### Hausaufgabe + +1. Versuche, Elemente hinzuzufuegen und zu loeschen, und beobachte die Auswirkungen auf die Datentabelle im Tabellen-Editor. + +## 3.4 Projekt 2 - Burger-Restaurant mit Benutzerauthentifizierung + +Projekt 2 fuegt die Kernfaehigkeiten Benutzerauthentifizierung (Auth) und RLS-Berechtigungsverwaltung hinzu. + +``` +const { error: err } = await supabaseClient.auth.signUp({ + email, + password, + options: { + data: { + full_name: fullName || null, + birthday: birthday || null, + avatar_url: avatarUrl || null + } + } +}); +``` + +![](/zh-cn/stage-2/backend/database-supabase/images/image39.png) + +Nach erfolgreicher Registrierung und Anmeldung gelangst du zur Shop-Oberflaeche: + +![](/zh-cn/stage-2/backend/database-supabase/images/image40.png) + +Um den Admin-Bereich zu sehen, musst du die Benutzerberechtigungen in der Datentabelle auf `admin` aendern: + +![](/zh-cn/stage-2/backend/database-supabase/images/image41.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image42.png) + +### Hausaufgabe + +1. Hole das Neukunden-Geschenk ab und schliesse einen Kauf ab. +2. Finde die Position der Benutzerberechtigungs-Datentabelle und aendere die Berechtigung auf `admin`. +3. Lokalisiere die Geldboersen-Tabelle und erhoeehe den Restbetrag. + +# 4. Baue deine erste Supabase-Anwendung + +Nach dem systematischen Lernen hast du die Kernfaehigkeiten von Supabase gemeistert. Jetzt ist es an der Zeit, deine erste Anwendung mit Datenbank und Benutzeranmeldung selbst zu erstellen! + +## 4.1 Standardisierter Prozess zur Anbindung einer Supabase-Datenbank + +1. **Anforderungsanalyse**: Beschreibe der KI klar die Kernfunktionen und neuen Datenbankanforderungen deiner App. +2. **SQL-Skript generieren**: Lass die KI ein `init.sql`-Skript generieren und fuehre es im SQL-Editor aus. +3. **Code restrukturieren**: Lass die KI den Projektcode so umschreiben, dass er mit der Supabase-Datenbank kommunizieren kann. +4. **Konfiguration und Tests**: Konfiguriere die Supabase-URL und Schluessel, teste alle Datenbankinteraktionen. + +## 4.2 Fallstudie: Ein Online-Schlangenspiel + +Wir praktizieren den Standardprozess an einem konkreten Beispiel: Einem Schlangenspiel, dem wir einen Online-Bestenliste und Benutzeranmeldung hinzufuegen. + +![](/zh-cn/stage-2/backend/database-supabase/images/image43.png) + +### 4.2.1 Projekt analysieren und Datenanforderungen identifizieren + +Prompts fuer die KI: + +> "Ich habe ein Schlangenspiel im Verzeichnis {Pfad}. Ich moechte eine Online-Bestenliste mit Benutzeranmeldung hinzufuegen. Welche Datentabellen und Felder brauche ich?" + +![](/zh-cn/stage-2/backend/database-supabase/images/image44.png) + +### 4.2.2 `init.sql`-Skript generieren + +Lass die KI ein `scripts/init.sql`-Skript generieren. + +![](/zh-cn/stage-2/backend/database-supabase/images/image45.png) + +### 4.2.3 Projektcode restrukturieren + +Lass die KI den Spielcode mit Supabase-Integration umschreiben. + +![](/zh-cn/stage-2/backend/database-supabase/images/image46.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image47.png) + +### Hausaufgabe + +1. Integriere das Benutzermanagement-System in die Schlangenspiel-Demoversion. +2. Integriere das Benutzermanagement-System in deine eigene Anwendung. + +# 5. Supabase-Meister werden + +Die oben genannten Inhalte decken die Grundoperationen von Supabase ab. Im weiteren Verlauf werden wir die erweiterten Prinzipien und Funktionen von Supabase kennenlernen. + +## 5.1 Warum wir Supabase gewaehlt haben + +Bei der Technologieauswahl stehen Startups vor einem Dilemma: Sie wollen volle Kontrolle ueber das Backend-System, muessen aber gleichzeitig schnell Produkte auf den Markt bringen. Supabase buendelt diese Backend-Faehigkeiten als sofort einsatzbereite Dienste (PostgreSQL-Datenbank, Echtzeit-Abos, Authentifizierung, Objektspeicher, Edge Functions, automatisch generierte APIs usw.). + +Im Vergleich zu Konkurrenzprodukten wie dem geschlossenen Firebase bietet Supabase eine vollstaendig quelloffene Strategie, die Private-Deployment unterstuetzt und das Risiko von Vendor-Lock-in vermeidet. + +## 5.2 Google- und GitHub-Login-Unterstützung + +Dieses Projekt `project-burger-shop-auth-advanced-supabase-6` demonstriert vollstaendig die Implementierung dieser erweiterten Funktionen. + +![](/zh-cn/stage-2/backend/database-supabase/images/image48.png) + +### 5.2.1 OAuth-Ablauf: Wie funktioniert Drittanbieter-Login? + +Der Kern des Drittanbieter-Logins ist das OAuth 2.0-Protokoll. Es ermoeglicht Benutzern, unsere App zu autorisieren, auf ihre oeffentlichen Informationen (wie E-Mail, Avatar) bei einem Drittanbieter (wie Google) zuzugreifen, ohne das Passwort des Drittanbieters preiszugeben. + +![](/zh-cn/stage-2/backend/database-supabase/images/image49.png) + +### 5.2.2 Google Cloud fuer Client ID und Secret konfigurieren + +1. Gehe zu [Google Cloud Console](https://console.cloud.google.com/). +2. Konfiguriere den OAuth-Zustimmungsbildschirm. +3. Erstelle OAuth 2.0-Client-Anmeldeinformationen. +4. Trage die Supabase-Callback-URL ein: `https://.supabase.co/auth/v1/callback`. + +![](/zh-cn/stage-2/backend/database-supabase/images/image50.png) + +### 5.2.3 GitHub fuer Client ID und Secret konfigurieren + +1. Gehe zu GitHub Developer Settings. +2. Registriere eine neue OAuth-App. +3. Trage die Supabase-Callback-URL ein. +4. Generiere ein Client Secret. + +![](/zh-cn/stage-2/backend/database-supabase/images/image51.png) + +### 5.2.4 Provider in Supabase konfigurieren + +1. Gehe zu Supabase Dashboard > Authentication > Providers. +2. Aktiviere Google und trage Client ID und Client Secret ein. +3. Aktiviere GitHub und trage Client ID und Client Secret ein. + +![](/zh-cn/stage-2/backend/database-supabase/images/image52.png) + +### 5.2.6 Passwort-Zuruecksetzen implementieren + +1. Benutzer gibt E-Mail ein, Frontend ruft `supabase.auth.resetPasswordForEmail()` auf. +2. Supabase sendet E-Mail mit einzigartigem Reset-Link. +3. Benutzer klickt auf Link und wird zurueckgeleitet. +4. Benutzer gibt neues Passwort ein, Frontend ruft `supabase.auth.updateUser()` auf. + +![](/zh-cn/stage-2/backend/database-supabase/images/image53.png) + +## 5.3 Echtzeit-Funktionen + +Dieses Projekt `project-burger-shop-realtime-orders-3` demonstriert die drei Kernfaehigkeiten von Supabase Realtime: Datenbankaenderungen ueberwachen (Postgres Changes), Broadcast und Presence. + +![](/zh-cn/stage-2/backend/database-supabase/images/image54.png) + +### 5.3.1 Datenbank-Echtzeitaenderungen (Postgres Changes) + +Die haeufigste Realtime-Funktion ist das Ueberwachen von Datenbankaenderungen. Kunden koennen spezifische Tabellen, Zeilen oder Spalten auf INSERT-, UPDATE- oder DELETE-Ereignisse abonnieren. + +```sql +-- Echtzeit-Replikation aktivieren +ALTER TABLE public.chat_messages REPLICA IDENTITY FULL; +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_publication_tables + WHERE pubname = 'supabase_realtime' + AND schemaname = 'public' + AND tablename = 'chat_messages' + ) THEN + ALTER PUBLICATION supabase_realtime ADD TABLE public.chat_messages; + END IF; +END $$; +``` + +```typescript +const sub = supabase + .channel('chat_messages_channel') + .on('postgres_changes', { + event: 'INSERT', + schema: 'public', + table: 'chat_messages' + }, (payload: any) => { + console.log('Neue Nachricht empfangen:', payload.new); + }) + .subscribe((status: string) => { + console.log('Chat-Abonnementstatus:', status); + }); +``` + +### 5.3.2 Broadcast und Presence + +- **Presence**: Verfolgt den Online-Status aller Clients in einem Kanal. +- **Broadcast**: Sendet temporäre Nachrichten mit niedriger Latenz zwischen Clients. + +## 5.4 Speicher (Storage) + +Dieses Projekt `project-burger-shop-storage-uploads-4` demonstriert den Aufbau eines modernen Datei-Upload-Systems mit Supabase Storage. + +![](/zh-cn/stage-2/backend/database-supabase/images/image55.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image56.png) + +### 5.4.1 Speicher-Buckets (Storage Buckets) + +Supabase Storage besteht aus Speicher-Buckets (Buckets). Jeder Bucket kann eigene Sicherheitsrichtlinien und Konfigurationen haben. + +``` +CREATE POLICY "Allow authenticated uploads to avatars bucket" +ON storage.objects FOR INSERT +TO authenticated +WITH CHECK ( + bucket_id = 'avatars' AND + auth.uid() = (storage.foldername(name))[1]::uuid AND + (storage.extension(name) IN ('png', 'jpg', 'jpeg')) +); + +CREATE POLICY "Allow public read access to avatars" +ON storage.objects FOR SELECT +USING ( bucket_id = 'avatars' ); +``` + +### 5.4.2 Zugaengliche Datei-URLs abrufen + +#### Oeffentliche URL (Public URL) - Permanenter Link + +```typescript +const { data } = supabase.storage + .from('avatars') + .getPublicUrl('public/avatar1.png'); +const publicUrl = data.publicUrl; +``` + +#### Signierte URL (Signed URL) - Temporaerer Link + +```typescript +const { data, error } = await supabase.storage + .from('avatars') + .createSignedUrl('private/user-invoice.pdf', 3600); +const signedUrl = data?.signedUrl; +``` + +## 5.5 Edge Functions + +Dieses Projekt `project-burger-shop-edge-function-5` demonstriert den einfachsten Anwendungsprozess von Edge Functions anhand einer Echtzeit-Streaming-Chat-Funktion mit einem grossen Sprachmodell (LLM). + +![](/zh-cn/stage-2/backend/database-supabase/images/image57.png) + +### 5.5.1 LLM-Chat-Fallanalyse + +```typescript +// scripts/llm-chat.ts +import "jsr:@supabase/functions-js/edge-runtime.d.ts"; +import { OpenAI } from "npm:openai"; + +const OPENAI_API_KEY = Deno.env.get("OPENAI_API_KEY"); + +Deno.serve(async (req) => { + try { + const openai = new OpenAI({ apiKey: OPENAI_API_KEY }); + const { prompt } = await req.json(); + + const stream = await openai.chat.completions.create({ + model: "gpt-3.5-turbo", + messages: [{ role: "user", content: prompt }], + stream: true, + }); + + return new Response(stream.toReadableStream(), { + headers: { "Content-Type": "text/event-stream" }, + }); + } catch (err) { + } +}); +``` + +### 5.5.2 Funktion erstellen und bereitstellen + +![](/zh-cn/stage-2/backend/database-supabase/images/image58.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image59.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image60.png) + +## 5.6 Clerk-Login + +Clerk ist ein professionelles Entwicklungstool fuer Identitaetsauthentifizierung und Benutzerverwaltung. + +![](/zh-cn/stage-2/backend/database-supabase/images/image61.png) + +### 5.6.1 Clerk-App erstellen und Schluessel abrufen + +![](/zh-cn/stage-2/backend/database-supabase/images/image62.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image63.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image64.png) + +### 5.6.2 Supabase und Clerk nativ integrieren + +1. Aktiviere die offizielle Supabase-Integration in Clerk. +2. Fuege Clerk als Provider in Supabase hinzu. + +### 5.6.3 Benutzerdaten ueber Webhook mit Supabase synchronisieren + +```sql +CREATE TABLE public.users ( + id TEXT NOT NULL PRIMARY KEY, + email TEXT, + first_name TEXT, + last_name TEXT, + image_url TEXT, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +ALTER TABLE public.users ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Authenticated users can view their own user record" +ON public.users FOR SELECT +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); +``` + +![](/zh-cn/stage-2/backend/database-supabase/images/image65.png) + +### 5.6.4 Drittanbieter-Login in Clerk + +Clerk unterscheidet zwischen Entwicklungs- und Produktionsumgebung fuer Social-Login. + +# 6. Von Supabase zu weiteren Backend-Entwicklungskomponenten (Fortgeschritten) + +Supabase bietet eine umfassende Plattform, aber jede einzelne Faehigkeit (Auth / Storage / Edge Functions / Realtime / Database) hat professionelle Alternativen auf dem Markt. + +## Vergleichbare BaaS-Plattformen + +| Plattag/Service | Typ | Kostenloseinheit/Preisgestaltung | +| ------------------------------ | --------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| Firebase (Google) | Voll verwaltetes BaaS | Spark: kostenlose Leichtversion; Blaze: nutzungsabhaengig | +| Supabase | Open-Source BaaS | Kostenlos: 500MB DB, 1GB Storage; Pro: nach Instanz | +| Appwrite Cloud | Open-Source All-in-One BaaS | Kostenlos: Basis DB/Storage/FaaS | +| Nhost | Postgres + GraphQL + Auth + Storage + Functions | Kostenlos: 1GB DB, 1GB Storage | +| AWS Amplify | AWS All-in-One Backend | Kostenlos: Hosting + Cognito 10k MAU | + +## Authentifizierung (Auth) + +| Tool/Plattform | Kostenloseinheit | +| ---------------------------- | --------------------------------------- | +| Firebase Authentication | Spark: 50k MAU kostenlos | +| Auth0 (Okta) | 25k MAU kostenlos | +| AWS Cognito | 10k MAU/Monat kostenlos | +| Logto | Community Edition kostenlos | +| Keycloak | Vollstaendig kostenlos (selbst gehostet) | + +## Dateispeicher (Storage) + +| Plattform/Service | Kostenloseinheit | +| ------------------------------------------------ | ------------------------------------------------------- | +| Amazon S3 | 5GB Speicher im kostenlosen AWS-Kontingent | +| Google Cloud Storage (Firebase Storage) | 1GB Speicher in Spark-Plan | +| Tencent Cloud COS / Alibaba Cloud OSS | Nutzungsabhaengig | +| MinIO | Open-Source kostenlos (selbst gehostet) | + +## Edge Functions + +| Plattform/Service | Kostenloseinheit | +| ---------------------------------------------- | ------------------------------------------------------------- | +| Cloudflare Workers | 100k Anfragen/Tag kostenlos | +| Vercel Edge Functions | 1M Funktionsaufrufe/Monat kostenlos | +| Netlify Edge / Functions | 300 Credits/Monat kostenlos | +| AWS Lambda@Edge / CloudFront Functions | 1M kostenlose Anfragen/Monat | + +# Zusammenfassung + +In der heutigen Lektion haben wir systematisch die Grundkonzepte von Datenbanken sowie die Kerndefinition und Bedienungsdetails von Supabase gelernt. Waehrend der weiteren Praxis kannst du jederzeit auf dieses Dokument zurueckgreifen. + +Bitte denke immer an einen wichtigen Grundsatz: **Zuerst fertigstellen, dann perfektionieren!** Es ist nicht noetig, alles auf einmal perfekt zu machen. Durch kontinuierliche Iteration und Optimierung koennen wir uns schrittweise besseren Ergebnissen naehern. + +# Hausaufgabe + +1. Entwickle eine Anwendung mit Benutzermanagement-System und Datenbank. Idealerweise mit weiteren Supabase-Funktionen (Realtime / Cloud Storage / Edge Functions). diff --git a/docs/de-de/stage-2/backend/git-workflow/index.md b/docs/de-de/stage-2/backend/git-workflow/index.md new file mode 100644 index 0000000..58d693e --- /dev/null +++ b/docs/de-de/stage-2/backend/git-workflow/index.md @@ -0,0 +1,261 @@ +# Git und GitHub verwenden lernen + +In den vorherigen Lektionen haben wir gelernt, wie man webbasierte Vibe-Coding-Tools zum Programmieren verwendet. Jede Unterhaltung erstellt eine neue Code-Version. Aber lassen Sie uns darueber nachdenken: Wenn wir zu einer frueheren Aenderung zurueckkehren moechten, gibt es eine bequeme Methode? Gibt es ein Tool, das unseren Code in verschiedenen Phasen aufzeichnen kann, sodass wir jederzeit zwischen verschiedenen Versionen wechseln und Aenderungen vornehmen koennen? + +Um diesem Bedarf gerecht zu werden, wurde Versionskontrollsoftware entwickelt. In diesem Artikel stellen wir das bekannteste Versionskontrollprogramm vor -- Git -- sowie die beste Code-Hosting-Plattform -- GitHub. Wir werden lernen, wie man Git zur Codeverwaltung verwendet, wie man Code anderer von GitHub abruft, wie man eigenen Code hochlaedt und wie man mit anderen an grossen Projekten zusammenarbeitet. + +Ob fuer die Versionsverfolgung persoenlicher Projekte, die Code-Synchronisation in der Teamzusammenarbeit oder den Beitrag zur Open-Source-Community -- Git und GitHub sind unverzichtbare Werkzeuge fuer moderne Entwickler. Durch ihre Beherrschung wirst du Code effizienter verwalten, bei Bedarf Pruefpunkte erstellen, frei zwischen verschiedenen Code-Phasen wechseln und alles von einzelnen Dateiaenderungen bis hin zur Entwicklung grosser Projekte problemlos bewaeltigen koennen -- wodurch jede Code-Iteration kontrollierbar und rueckverfolgbar wird. + +> :bulb: **Vorkenntnisse** +> +> Bevor du Git lernst, wird empfohlen, die folgenden Konzepte zu kennen: +> - [Was ist ein Terminal / eine Kommandozeile](/de-de/appendix/2-development-tools/command-line-shell) - Lernen, wie man die Kommandozeile zur Interaktion mit dem Computer verwendet +> - [Was ist Git](/de-de/appendix/2-development-tools/git-version-control) - Die Kernkonzepte des Git-Versionskontrollsystems verstehen +> +> Dieser Artikel konzentriert sich auf den GitHub-Workflow und die praktische Anwendung. Die oben genannten Grundlagen findest du in den verlinkten Anhang-Artikeln. + +# Git Schnellstart + +Bevor du Git verwendest, stelle sicher, dass du die Inhalte zum Thema [Kommandozeile](/de-de/appendix/2-development-tools/command-line-shell) und [Git-Grundlagen](/de-de/appendix/2-development-tools/git-version-control) im Anhang gelesen hast. Dieser Artikel setzt diese Grundkenntnisse voraus und erklart direkt, wie man Git installiert, konfiguriert und GitHub fuer die Zusammenarbeit nutzt. + +## Git installieren + +Wir demonstrieren drei Methoden zur Installation von Git auf verschiedenen Betriebssystemen. Bitte folge den Anweisungen gemaess deiner Systemversion: + +### Windows + +1. Gehe zur [offiziellen Git-Download-Seite](https://git-scm.com/download/win) und lade das fuer dein System passende Installationsprogramm herunter: [Installationspaket](https://github.com/git-for-windows/git/releases/download/v2.51.0.windows.1/Git-2.51.0-64-bit.exe). Standardmaessig wird das x64-Installationsprogramm empfohlen. +2. Doppelklicke auf das Installationsprogramm und folge dem Installations-Assistenten: + ![](/zh-cn/stage-2/backend/git-workflow/images/image5.png) + 1. Es wird empfohlen, die Standardoptionen beizubehalten. Wenn du Anpassungen vornehmen moechtest, beachte Folgendes: (In den meisten Faellen kannst du einfach auf "Next" klicken) + - Standard-Editor fuer Git auswaehlen: Waehle deinen bevorzugten Editor (z. B. VS Code). Du kannst die erste Option, Vim (einen Texteditor), als Standard waehlen oder "Visual Studio Code as Git's default editor" auswaehlen (erfordert vorab installiertes VS Code). Du kannst die Standardauswahl beibehalten und auf "Next" klicken, um fortzufahren. + ![](/zh-cn/stage-2/backend/git-workflow/images/image6.png) + - Auswaehlen, wie Git verwendet werden soll: Diese drei Optionen steuern die Verfuegbarkeit von Git im System. Es wird empfohlen, Option 2 ("from command line and 3rd-party software") zu waehlen -- sie fuegt die grundlegenden Git-Tools zum PATH hinzu und ermoeglicht es dir, Git in Git Bash, Eingabeaufforderung, PowerShell und IDEs zu verwenden, ohne das System zu ueberlasten. + ![](/zh-cn/stage-2/backend/git-workflow/images/image7.png) + +3. Nach der Installation rechtsklicke auf dem Desktop. Wenn du "Git Bash Here" im Menue siehst, war die Installation erfolgreich. + +![](/zh-cn/stage-2/backend/git-workflow/images/image8.png) + +### MacOS + +Fuer macOS kannst du zunaechst `git --version` im Terminal eingeben, um zu pruefen, ob Git bereits installiert ist. Wenn nicht, wird das System dich zur Installation auffordern -- folge einfach den Anweisungen. + +1. Methode 1: Ueber Homebrew installieren + Wenn du [Homebrew](https://brew.sh/) (den Mac-Paketmanager) installiert hast, oeffne das Terminal und gib ein: + ```bash + brew install git + ``` +2. Methode 2: (Empfohlen) Ueber Xcode installieren: https://developer.apple.com/xcode/ -- Xcode enthaelt integriertes Git. Nach der Installation einfach den Anweisungen folgen. + +### Linux + +Die meisten Linux-Distributionen koennen Git ueber ihren Paketmanager installieren: + +- Ubuntu/Debian: + +```bash +sudo apt update +sudo apt install git +``` + +- CentOS/RHEL: + +```bash +sudo yum install git +``` + +- Installation ueberpruefen: Gib `git --version` im Terminal ein. Wenn eine Versionsnummer angezeigt wird, war die Installation erfolgreich. + +## Git initialisieren + +Nach der Installation von Git musst du zunaechst deine Benutzerinformationen konfigurieren -- dies ist ein grundlegender Schritt fuer die Verwendung von Git zur Versionskontrolle. Fuehre die folgenden Befehle im Terminal aus (ersetze den Inhalt in Klammern durch deine eigenen Informationen): + +```bash +# Globalen Benutzernamen setzen (wird in den Commit-Eintraegen angezeigt) +git config --global user.name "Your Name" + +# Globale E-Mail-Adresse setzen (verwende bevorzugt die auf GitHub/GitLab registrierte Adresse) +git config --global user.email "your.email@example.com" +``` + +Git bettet diese Informationen in jeden Commit-Eintrag als "Autoreninformation" ein. Beim Betrachten der Versionshistorie (z. B. mit `git log`) kannst du klar erkennen, wer welche Codezeile geaendert hat, was die Zurechenbarkeit und Kommunikation erleichtert. In kollaborativen Projekten ermoeglichen einheitliche Identitaetsinformationen den Teammitgliedern, schnell zu erkennen, wer welche Aenderungen vorgenommen hat, was die Zusammenarbeitseffizienz steigert (z. B. durch die Suche nach dem entsprechenden Entwickler ueber Commit-Eintraege). + +Du kannst die aktuellen Git-Konfigurationsinformationen einsehen, indem du `git config --list` in der Kommandozeile eingibst, um die erfolgreiche Einrichtung zu bestaetigen. + +# Was ist GitHub + +GitHub ist eine Git-basierte Code-Hosting-Plattform. Sie bietet nicht nur Remote-Speicher fuer Git-Repositories, sondern enthaelt auch Kollaborationstools (wie Issues, Pull Requests, Projects), die es Entwicklern erleichtern, Code zu teilen und zusammenzuarbeiten. Kurz gesagt: Git ist ein lokales Versionskontroll-Tool, waehrend GitHub eine "Cloud-Festplatte fuer Code-Repositories + Kollaborations-Community" ist. + +GitHub ist nicht nur die groesste Code-Hosting-Plattform der Welt, sondern auch die aktivste und einflussreichste Open-Source-Community weltweit. Die Kernidee von "Open Source" besagt, dass jeder den Quellcode der Software herunterladen und ausfuehren kann. Dieses Modell ermoeglicht es Menschen weltweit, den Code anderer zu pruefen, zu aendern oder darauf basierend neue Projekte zu erstellen. Du kannst beispielsweise auf GitHub verschiedene Lerntutorials sowie den vollstaendigen Quellcode von Frameworks zum Training von GPT-Modellen (wie PyTorch) finden. Taeglich arbeiten unzaehlige Menschen weltweit zusammen, um Code zu reviewen und zu verbessern. + +![](/zh-cn/stage-2/backend/git-workflow/images/image9.png) + +Viele grosse Unternehmen veroeffentlichen ihre Programme oder Tutorials als Open Source auf GitHub, um Wettbewerbsvorteile in der Branche zu erlangen -- was man auch als eine Form der Werbung betrachten kann. In der GitHub-Community ist die Anzahl der "Sterne" (Stars), die ein Projekt erhaelt, das wichtigste Mass fuer seinen Wert; je mehr Stars ein Projekt oder eine Organisation hat, desto groesser ist seine Glaubwuerdigkeit und sein Einfluss. + +![](/zh-cn/stage-2/backend/git-workflow/images/image10.png) + +In unserem Kurs werden auch Unterstuetzungsressourcen und Aufgaben in einem dedizierten GitHub-Repository hochgeladen. Durch den Prozess des Hochladens von Aufgaben wirst du dich schrittweise mit der Verwendung von GitHub vertraut machen und eine solide Grundlage fuer die Versionskontrolle bei der zukuenftigen Anwendungsentwicklung schaffen. + +## GitHub-Konto registrieren + +1. Besuche die [offizielle GitHub-Website](https://github.com/) und klicke oben rechts auf "Sign up". + ![](/zh-cn/stage-2/backend/git-workflow/images/image11.png) +2. Gib deine E-Mail-Adresse ein (verwende bevorzugt deine haeufig genutzte Adresse, da Verifizierungen und Benachrichtigungen dorthin gesendet werden), setze ein Passwort (muss Buchstaben, Zahlen und Sonderzeichen enthalten). +3. Schliesse die menschliche Verifizierung ab, bestaetige deine E-Mail gemaess den Anweisungen, und dein Konto ist erstellt. + +## Dein erstes Repository auf GitHub erstellen + +Als Naechstes erstellen wir den ersten Speicherordner, auch Repository oder "Repo" genannt. + +![](/zh-cn/stage-2/backend/git-workflow/images/image12.png)![](/zh-cn/stage-2/backend/git-workflow/images/image13.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image14.png) + +1. Repository name: Der Name des Repositories, der anderen angezeigt wird. +2. Description: Eine detaillierte Beschreibung des Repositories. +3. Choose visibility: Fuer persoenliche Repositories gilt: Wenn auf "private" gesetzt, koennen nur du und speziell eingeladene Personen es sehen. Wenn auf "public" gesetzt, koennen alle es sehen. + Fuer Repositories innerhalb einer Organisation gilt: Bei "Private" koennen nur Organisationsmitglieder es sehen. + Bei "Public" koennen auch Personen ausserhalb der Organisation es sehen. +4. README: Es ist ueblich, dass jedes Repository eine README-Datei haben sollte. Du kannst sie als vollstaendige Vorstellung des Repositories betrachten, einschliesslich Verwendungsanleitung, Dateiliste und Bedienungshinweisen. +5. Add .gitignore and license: + 1. Die .gitignore-Datei teilt Git mit, bestimmte Ordner oder Dateien beim Upload zu GitHub zu ignorieren, sodass sie nicht verfolgt oder zur Staging-Area hinzugefuegt werden. Dies ist nuetzlich fuer temporaere Testdateien, Abhaengigkeitspakete oder grosse Dateien. Einmal angegeben, werden diese Dateien nicht mehr verfolgt. + 2. License bezieht sich auf die gewaehlte Open-Source-Lizenz. Unterschiedliche Lizenzen regeln detailliert, ob andere deinen Code fuer kommerzielle Zwecke verwenden duerfen, und enthalten weitere Bestimmungen und Bedingungen. + +Es wird empfohlen, "Add README" zu aktivieren, die Sichtbarkeit des Repositories auf "Private" zu setzen und den Repository-Namen sowie die Beschreibung nach eigenen Wuenschen auszufuellen. Klicke dann auf "Create repository", um die Erstellung deines ersten Remote-Repositories abzuschliessen. + +![](/zh-cn/stage-2/backend/git-workflow/images/image15.png) + +Danach hast du ein leeres Repository ohne zusaetzliche Dateien. Jetzt kannst du mit dem Hochladen von Dateien beginnen. + +![](/zh-cn/stage-2/backend/git-workflow/images/image16.png) + +Der Befehl zum Abrufen des Repositories lautet `git clone`, erfordert jedoch die Repository-Adresse. Du kannst die Repository-Adresse finden, indem du auf den gruennen "Code"-Button klickst, wo dir HTTPS- und SSH-Optionen angezeigt werden. Normalerweise kannst du eine der beiden Methoden verwenden, um das Repository auf deinen lokalen Rechner herunterzuladen (nur so kannst du Dateien aendern und hochladen). + +![](/zh-cn/stage-2/backend/git-workflow/images/image17.png) + +Im Allgemeinen eignen sich ueber HTTP geklonte Repositories fuer das temporaere Herunterladen und Testen von Repositories anderer, werden aber nicht fuer die eigene Entwicklung empfohlen. Fuer eine bessere Lernerfahrung solltest du zunaechst die SSH-Authentifizierung einrichten. + +## Lokalen SSH-Schluessel binden + +Bei GitHub bedeutet die "SSH-Protokoll-Bindung" im Wesentlichen, dass du den oeffentlichen Schluessel deines lokalen Geraets mit deinem GitHub-Konto verknuepfst, sodass GitHub dein Geraet ueber das SSH-Protokoll identifizieren kann. Dies ermoeglicht es dir, Remote-Repositories sicher ohne Passwort zu bedienen (wie Clone, Push oder Pull von Code). + +Einfach gesagt: Es ist, als wuerdest du deinem Geraet eine "GitHub-exklusive Zugangskarte" geben. Nach der Bindung ueberprueft GitHub diese "Zugangskarte" (deinen oeffentlichen SSH-Schluessel), wenn dein Geraet ueber das SSH-Protokoll auf ein GitHub-Repository zugreift. Sobald dein Geraet als autorisiert bestaetigt wurde, kannst du direkt arbeiten -- ohne jedes Mal Benutzername und Passwort eingeben zu muessen. + +> :bulb: Was ist SSH + +### Warum wird die SSH-Protokoll-Bindung benoetigt? + +GitHub unterstuetzt zwei Hauptprotokolle fuer Repository-Operationen: das HTTPS-Protokoll und das SSH-Protokoll: + +- HTTPS-Protokoll: Bei jeder Operation (wie Push) muessen GitHub-Benutzername und -Passwort (oder ein Personal Access Token PAT) eingegeben werden. Der Verifizierungsprozess ist aufwendig und birgt das Risiko der Passwortoffenlegung. +- SSH-Protokoll: Die Authentifizierung erfolgt ueber "Schluesselpaare", sodass kein wiederholtes Passwort-Eingeben erforderlich ist und die verschluesselte Uebertragung sicherer ist. + +Die "SSH-Protokoll-Bindung" ist eine Voraussetzung fuer die Aktivierung der GitHub-SSH-Authentifizierung -- erst nachdem der lokale oeffentliche SSH-Schluessel an dein GitHub-Konto "gebunden" wurde, kann GitHub dein Geraet erkennen und SSH-Operationen auf dem Repository erlauben. + +### Die Kernlogik der "Bindung": Die Rolle der SSH-Schluesselpaare + +Die SSH-Authentifizierung basiert auf Schluesselpaaren (oeffentlicher Schluessel + privater Schluessel), die zusammengehoeorige verschluesselte Dateien sind. Nach der Generierung musst du den "oeffentlichen Schluessel" bei GitHub bereitstellen ("Bindung"), waehrend der "private Schluessel" auf deinem lokalen Geraet verbleibt: + +1. Privater Schluessel: Wird im angegebenen Verzeichnis deines lokalen Geraets (z. B. Computers) gespeichert (normalerweise ~/.ssh/) und dient als "dein exklusiver Schluessel", der niemals mit anderen geteilt werden darf. +2. Oeffentlicher Schluessel: Dies ist ein "Schloss", das oeffentlich geteilt werden kann -- du musst es in die "SSH keys list" deines GitHub-Kontos kopieren (der "Bindungs"-Vorgang). + +Wenn du ueber SSH ein GitHub-Repository bedienst (z. B. `git push git@github.com:xxx/xxx.git`): + +- Dein lokales Geraet verschluesselt die "Operationsanfrage" mit dem privaten Schluessel und sendet sie an GitHub; +- Nach Erhalt der Anfrage versucht GitHub, sie mit dem zuvor gebundenen oeffentlichen Schluessel zu entschluesseln; +- Wenn die Entschluesselung erfolgreich ist, wird dein Geraet als autorisiert bestaetigt und die Operation wird erlaubt; andernfalls wird der Zugriff verweigert. + +### Die konkreten Schritte der "Bindung" (Kernablauf) + +Sobald du das Prinzip verstanden hast, ist die praktische Umsetzung einfach -- der Kern lautet: "Schluesselpaar generieren -> oeffentlichen Schluessel auf GitHub hochladen": + +1. Lokales SSH-Schluesselpaar generieren + 1. Trae verwenden, um den oeffentlichen Schluessel zu erhalten (empfohlen) + Prompt: `Help me create the SSH key needed for GitHub login. My email is your_email@gmail.com , Please return the public key for me to copy` + + ![](/zh-cn/stage-2/backend/git-workflow/images/image18.png) + + Nach Eingabe des Prompts musst du auch im linken Terminal die Enter-Taste druecken, da der Befehl sonst wartet und nicht ausgefuehrt wird. Da Trae keine Bedingungspruefungen fuer dich durchfuehren kann, druecke einfach wiederholt Enter. + + Am Ende siehst du auf der rechten Seite, dass Trae den gelesenen oeffentlichen Schluessel zurueckgegeben hat. Kopiere ihn einfach und bereite dich darauf vor, ihn im naechsten Schritt einzufuegen. + + ![](/zh-cn/stage-2/backend/git-workflow/images/image19.png) 2. Oeffentlichen Schluessel manuell erhalten + Oeffne dein lokales Terminal (Windows: Git Bash oder PowerShell; macOS/Linux: Terminal) und gib den folgenden Befehl ein (ersetze your_email@example.com durch die E-Mail-Adresse, die du bei der Registrierung deines GitHub-Kontos verwendet hast): + + ```bash + ssh-keygen -t ed25519 -C "your_email@example.com" + ``` + + 1. Druecke Enter, um die Standardwerte zu akzeptieren (Standard-Dateipfad, kein Passwort oder nach Bedarf ein Passwort setzen). Dies generiert zwei Dateien im Verzeichnis ~/.ssh/: + - id_ed25519: Privater Schluessel (lokal speichern, **niemals teilen**); + - id_ed25519.pub: Oeffentlicher Schluessel (muss auf GitHub hochgeladen werden). + +2. Oeffentlichen Schluessel an dein GitHub-Konto "binden" + +Dies ist der Kern-Bindungsschritt -- den lokalen oeffentlichen Schluessel zur "SSH keys list" deines GitHub-Kontos hinzufuegen: + +1. Inhalt des oeffentlichen Schluessels kopieren: + 1. Trae: + 2. Windows: Oeffne C:\Users\\.ssh\id_ed25519.pub mit dem Editor und kopiere den gesamten Inhalt; + 3. macOS/Linux: Fuehre `cat ~/.ssh/id_ed25519.pub` im Terminal aus und kopiere die gesamte Ausgabe (vom beginnenden SSH-ed25519 bis zur abschliessenden E-Mail-Adresse). +2. Bei GitHub anmelden und zur "SSH Key Management"-Seite navigieren: + 1. Klicke oben rechts auf dein Profilbild -> Settings -> linkes Menue SSH and GPG keys -> klicke auf New SSH key. + ![](/zh-cn/stage-2/backend/git-workflow/images/image20.png)![](/zh-cn/stage-2/backend/git-workflow/images/image21.png) + 2. Gib einen beliebigen Titel ein (z. B. "your local computer's SSH") und fuege dann deinen gerade kopierten oeffentlichen SSH-Schluessel hier ein. + +![](/zh-cn/stage-2/backend/git-workflow/images/image22.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image23.png) + +3. Ueberpruefen, ob die Bindung erfolgreich war + +Gib den folgenden Befehl im Terminal ein (**Trae kann auch folgende Operationen ausfuehren**), um zu testen, ob GitHub dein Geraet erkennen kann: + +```bash +ssh -T git@github.com +``` + +- Wenn du etwas wie "Hi [your GitHub username]! You've successfully authenticated..." siehst, wurde dein Schluessel erfolgreich gebunden; +- Wenn ein Fehler auftritt, liegt dies meist daran, dass der oeffentliche Schluessel unvollstaendig kopiert wurde, die Berechtigungen des privaten Schluessels zu hoch sind (dein lokales ~/.ssh/-Verzeichnis sollte nur fuer dich les- und schreibbar sein) usw. Ueberpruefe diese Punkte gemaess den Erfordernissen. + +### Wichtige Hinweise + +Wenn du mehrere Geraete hast (wie Laptop und Desktop), musst du fuer jedes Geraet ein separates SSH-Schluesselpaar generieren und jeden oeffentlichen Schluessel an dasselbe GitHub-Konto binden -- jedes Geraet hat seine eigene "Zugangskarte". + +Teile niemals deinen privaten Schluessel (lade ihn nicht auf GitHub hoch und teile ihn nicht mit anderen), da sonst jemand deine Identitaet annehmen und dein Repository bedienen koennte. Wenn der private Schluessel kompromittiert wurde, loesche sofort den entsprechenden oeffentlichen Schluessel auf GitHub und generiere ein neues Schluesselpaar. + +Nach der SSH-Bindung verwende die SSH-Format-Repository-Adresse (z. B. git@github.com:username/repository.git) fuer Operationen, nicht das HTTPS-Format (z. B. https://github.com/username/repository.git). Wenn du ein Repository zuvor mit HTTPS geklont hast, kannst du mit `git remote set-url origin ` das Protokoll wechseln. + +# GitHub-Operationen mit Trae durchfuehren + +Wir haben erklaert, was Git, GitHub und SSH sind und wie man sie konfiguriert. Jetzt kannst du Trae frei fuer Git-Operationen nutzen. Lass uns zunaechst lernen, wie man ein Remote-Repository auf den lokalen Rechner klont. + +## Git clone: Bestehendes Repository herunterladen + +Du kannst Trae einfach die Adresse des Repositories mitteilen, das du klonen moechtest. + +![](/zh-cn/stage-2/backend/git-workflow/images/image24.png) + +## Git pull: Updates aus dem Remote-Repository abrufen + +Vor jedem Repository-Update musst du zunaechst die neuesten Aenderungen pullen, da das Repository von mehreren Personen gepflegt werden koennte. Danach kannst du Dateien aendern und pushen. + +**Vergiss nicht, den Ordnernamen sowie den relativen oder absoluten Pfad anzugeben, um zu vermeiden, dass in das falsche Repository gepusht wird.** + +Prompt: `Help me pull this repository AIID-TEST in ./AIID-TEST.` + +## Git commit & Git push: Aenderungen stagen und zu GitHub pushen + +Wenn alles bereit ist, kannst du damit beginnen, lokale Dateien zu aendern, Elemente im Ordner hinzuzufuegen oder zu loeschen. Lass Trae dann die Aenderungen erkennen und dir beim Push zu GitHub helfen. + +Prompt: `I finished. Commit and push to the repository AIID-TEST in ./AIID-TEST.` + +![](/zh-cn/stage-2/backend/git-workflow/images/image25.png) + +Push erfolgreich. Jetzt kannst du die aktualisierten Inhalte auf GitHub sehen. + +# Referenzmaterialien + +- Pro Git book https://git-scm.com/book/en/v2 +- GitHub Docs https://docs.github.com/en diff --git a/docs/de-de/stage-2/backend/modern-cli/index.md b/docs/de-de/stage-2/backend/modern-cli/index.md new file mode 100644 index 0000000..f7fc14b --- /dev/null +++ b/docs/de-de/stage-2/backend/modern-cli/index.md @@ -0,0 +1,316 @@ +# CLI KI-Programmierwerkzeuge + +In diesem Tutorial stellen wir KI-Programmier-Agenten vor, die direkt in der Kommandozeile ausgefuehrt werden. Im Gegensatz zu den Agenten in Trae oder Cursor koennen CLI KI-Programmierwerkzeuge nur im Terminal verwendet werden. Im Vergleich zu IDE-integrierten Agenten bieten sie in der Regel ein laengeres Kontextfenster, schnellere Tool-Aufrufe und kompatiblere Modelle. + +## Von der CLI ausgehend + +CLI (Command Line Interface) bedeutet die Bedienung von Softwareanwendungen ueber reine Textbefehle im Terminal, anstatt sich auf grafische Benutzeroberflaechen (GUI) zu verlassen. + +![](/zh-cn/stage-2/backend/modern-cli/images/image1.png)![](/zh-cn/stage-2/backend/modern-cli/images/image2.png) + +CLI eignet sich von Natur aus fuer Textbefehlsoperationen und ist bei einem Teil der Power-User sogar beliebter als GUI. + +![](/zh-cn/stage-2/backend/modern-cli/images/image3.png) + +Keine Sorge, wenn du keine CLI-Erfahrung hast. Genau wie wir Trae frueher fuer grundlegende Operationen genutzt haben, koennen wir hier CLI-Programmierwerkzeuge alle CLI-Operationen fuer uns ausfuehren lassen. + +## Unterschiede zu KI-IDEs + +Man kann CLI KI-Programmierwerkzeuge mit z.ai oder Trae vergleichen. Sie benoetigen nur einen einfachen Dialogueingang und fuehren automatisch alle erforderlichen Operationen durch. + +![](/zh-cn/stage-2/backend/modern-cli/images/image4.png)![](/zh-cn/stage-2/backend/modern-cli/images/image5.png) + +| Funktionsmerkmal | Claude Code | Cursor | Besserer | +| ------------------------ | -------------- | --------------- | ------------- | +| Automatische Aufgabenausfuehrung | Sehr stark | Begrenzt | Claude Code | +| IDE-Integration | Nur Kommandozeile | Natives VS Code | Cursor | +| Echtzeit-Codevervollstaendigung | Nein | Hervorragend | Cursor | +| Mehrdateioperationen | Sehr stark | Gut | Claude Code | +| GitHub-Integration | Direkte Commits | Manuelle Operation | Claude Code | +| Lernkurve | Mittel | Einfach | Cursor | +| Kontextlaenge | Sehr lang | Gut | Claude Code | +| Debugging-Unterstützung | Automatisiert | Viel manuell | Claude Code | + +Kurz gesagt koennen CLI KI-Programmierwerkzeuge: +- Laengere fortlaufende Gespraeche unterstuetzen +- Laengere Kontextfenster bieten +- Schneller reagieren + +## Haeufige CLI KI-Programmierwerkzeuge + +Wir empfehlen zwei Hauptkategorien: + +- **Codex** nutzt GPT-5 und ist insgesamt leistungsstaerker +- **Claude Code** bietet ueber GLM 4.6 eine API-Weiterleitung mit einer Erfahrung nahe Claude 4, aber guenstiger +- **OpenCode** ermoeglicht freien Modellwechsel und bietet kostenlose Modelle + +### Claude Code + +Claude Code ist ein von Anthropic entwickeltes KI-Programmierwerkzeug basierend auf dem Claude-Grosssprachenmodell. Seine Hauptinteraktion findet im Terminal statt, unterstuetzt aber auch die Nutzung als VS Code-Plugin. + +![](/zh-cn/stage-2/backend/modern-cli/images/image6.png) + +**Vorteile**: Sehr langes Kontextfenster, kann unklare Anforderungen klaeren, automatische Aufgabenplanung und tiefes Verstaendnis der gesamten Codebasis. + +![](/zh-cn/stage-2/backend/modern-cli/images/image7.png)![](/zh-cn/stage-2/backend/modern-cli/images/image8.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image9.png)![](/zh-cn/stage-2/backend/modern-cli/images/image10.png) + +Kurs zum systematischen Lernen von Claude Code: + +![](/zh-cn/stage-2/backend/modern-cli/images/image11.png) + +#### GLM als Backend verwenden (Empfohlen) + +GLM (General Language Model) ist eine von zhipu AI entwickelte Serie von Grosssprachenmodellen. GLM-4.6 ist die neueste Version mit herausragender Codefaehigkeit. + +![](/zh-cn/stage-2/backend/modern-cli/images/image12.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image13.png) + +Installation: + +```python +# Claude Code installieren +npm install -g @anthropic-ai/claude-code + +# In dein Projekt wechseln +cd your-awesome-project + +# Claude Code starten +claude +``` + +API-Key abrufen: +- Inlands-Version: +- International: + +**Inlands-Version GLM** konfigurieren: + +```python +setx ANTHROPIC_AUTH_TOKEN your_zhipu_api_key +setx ANTHROPIC_BASE_URL https://open.bigmodel.cn/api/anthropic +``` + +**International GLM** konfigurieren: + +```python +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic +``` + +![](/zh-cn/stage-2/backend/modern-cli/images/image14.png) + +#### Kimi K2 als Backend verwenden (Empfohlen) + +Kimi K2 ist ein neues Grosssprachenmodell von Moonshot AI mit hervorragender Codeverstaendnis- und Generierungsfaehigkeit. Es unterstuetzt ein Ultra-Lang-Kontextfenster von bis zu 200K Tokens. + +API-Key: + +```bash +export ANTHROPIC_BASE_URL=https://api.moonshot.cn/anthropic +export ANTHROPIC_AUTH_TOKEN=sk-YOURKEY +``` + +#### Minimax als Backend verwenden (Empfohlen) + +Minimax ist ein Grosssprachenmodell von MiniMax mit hervorragender Reasoning-Faehigkeit und Codegenerierungsqualitaet. + +API-Key: + +```bash +export ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_MINIMAX_API_KEY +export ANTHROPIC_MODEL=MiniMax-M2.7 +``` + +#### DeepSeek als Backend verwenden (Empfohlen) + +DeepSeek ist ein Open-Source-Grosssprachenmodell mit herausragender Codefaehigkeit und hohem Preis-Leistungs-Verhaeltnis. + +API-Key: + +```bash +export ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic +export ANTHROPIC_AUTH_TOKEN=YOU_DEEPSEEK_API_KEY +export API_TIMEOUT_MS=600000 +export ANTHROPIC_MODEL=deepseek-chat +export ANTHROPIC_SMALL_FAST_MODEL=deepseek-chat +export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 +``` + +#### Volcengine Coding Plan als Backend verwenden (Empfohlen) + +Volcengine (Volcano Engine) ist die Cloud-Service-Plattform von ByteDance. + +API-Key: + +```bash +export ANTHROPIC_BASE_URL=https://ark.volces.com/api/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_VOLCANO_API_KEY +export ANTHROPIC_MODEL=doubao-pro-32k +``` + +#### Claude Code erweiterte Nutzung + +| Befehl | Funktion | Beispiel | +| -------------------- | --------------------------------------------------- | -------------------------------------------- | +| claude | Interaktiven Modus starten | `claude` | +| claude "query" | Einmalige Aufgabe ausfuehren | `claude "explain this project"` | +| claude -p "query" | Einmalige Frage mit automatischem Beenden | `claude -p "explain this function xxxx"` | +| claude -c | Letzte Sitzung fortsetzen | `claude -c` | +| /init | Projektbeschreibung mit CLAUDE.md initialisieren | `/init` | +| /clear | Aktuelle Sitzung leeren | `/clear` | +| /compact | Sitzungsverlauf komprimieren | `/compact` | +| /cost | Aktuelle Kosten anzeigen | `/cost` | +| exit oder Ctrl+C | Claude Code beenden | `exit` oder `Ctrl+C` | + +**CLAUDE.md** + +`CLAUDE.md` ist eine spezielle Datei, die Claude beim Start automatisch liest. Sie eignet sich fuer: +- Haeufige Bash-Befehle +- Kerndateien und Hilfsfunktionen +- Code-Stilvereinbarungen +- Testmethoden +- Repository-Zusammenarbeitsregeln + +``` +# Bash commands +- npm run build: Build the project +- npm run typecheck: Run the typechecker + +# Code style +- Use ES modules (import/export) syntax, not CommonJS (require) +- Destructure imports when possible + +# Workflow +- Be sure to typecheck when you're done making changes +``` + +#### Interne Funktionsweise von Claude Code + +![](/zh-cn/stage-2/backend/modern-cli/images/image25.png) + +Claude Code zerlegt Programmieraufgaben in einen fortlaufenden "Wahrnehmen-Denken-Handeln-Verifizieren"-Zyklus. Es ahmt den Workflow menschlicher Entwickler nach: "Code schreiben > ausfuehren > Ergebnisse pruefen > verbessern". + +### Codex + +![](/zh-cn/stage-2/backend/modern-cli/images/image26.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image27.png) + +Codex ist ein von OpenAI entwickeltes KI-Kooperations-Programmierwerkzeug. Sein groesster Vorteil ist die effiziente Anpassung an GPT-5. + +Installation: + +``` +npm i -g @openai/codex +``` + +#### Offizielle OpenAI API als Backend + +![](/zh-cn/stage-2/backend/modern-cli/images/image28.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image29.png) + +#### Weitergeleitete OpenAI API als Backend + +Konfigurationsbeispiel: + +````bash +My API key is: [Paste your obtained sk-xxxxx key here] + +Please help me complete the following configuration tasks: + +1. Create a `.codex` folder under my user directory +2. Create `config.toml` in the `.codex` directory +3. Write the following content: + ```toml + preferred_auth_method = "apikey" + + [model_providers.myrelay] + name = "My Relay Station" + base_url = "https://api.zyai.online/v1" + env_key = "MYRELAY_API_KEY" + wire_api = "responses" + ``` + +4. Set system environment variable MYRELAY_API_KEY +```` + +Nach der Konfiguration kannst du Codex mit `codex --profile myrelay` starten. + +### OpenCode + +![](/zh-cn/stage-2/backend/modern-cli/images/image32.png) + +OpenCode ist eine Open-Source KI Coding Agent-Plattform, positioniert als "Multi-Modell-Version von Claude Code". + +Installation: + +```bash +# Linux / Unix +curl -fsSL https://opencode.ai/install | bash + +# Windows +npm i -g opencode-ai +``` + +#### Kostenlose Modelle in OpenCode verwenden + +Starte OpenCode mit `opencode` und gib `/models` ein, um nach "free" zu suchen. + +![](/zh-cn/stage-2/backend/modern-cli/images/image35.png) + +#### Drittanbieter-Modelle verwenden + +Gib `/connect` ein, waehle den ersten Eintrag und folge der Authentifizierung. + +![](/zh-cn/stage-2/backend/modern-cli/images/image36.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image37.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image38.png) + +#### Oh My OpenAgent Plugin installieren + +Oh-My-OpenAgent ist ein "Multi-Agent KI-Programmier-Kommandosystem", das auf OpenCode laeuft. + +```text +Install and configure oh-my-openagent by following the instructions here: +https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md +``` + +## Weitere Verwendungsmoeglichkeiten von CLI KI-Programmierwerkzeugen + +### KI fuer Anforderungen-Dokumente nutzen + +Abstrakte Anforderungen muessen fuer grosse Sprachmodelle "konkretisiert" werden. Lass die KI helfen, deine Anforderungen zu detaillieren: + +`Based on my needs, please elaborate and provide a more detailed Product Requirement Document for reference.` + +### Ordner verwalten + +`Please help me organize the contents of the current folder.` + +### Neue Projekte entwickeln + +Genau wie bei z.ai oder Trae koennen CLI-Tools verwendet werden, um Projekte von Grund auf zu entwickeln. + +### Open-Source-Projekte bereitstellen + +`I want to deploy this GitHub project https://github.com/langgenius/dify. Please help me clone the project and run it.` + +![](/zh-cn/stage-2/backend/modern-cli/images/image31.png) + +### Code erklaeren und Dokumentation schreiben + +- "Bitte erklaere mir dieses Projekt: Wie startet man es, wie verwendet man es?" +- "Bitte schreibe eine vollstaendige Dokumentation fuer dieses Projekt." + +### Weitere Anwendungsmoeglichkeiten + +- Lokale Dateien verwalten und organisieren +- Tagebuch schreiben, Zusammenfassungen erstellen +- Systemfehler analysieren und beheben +- Wiederkehrende Kommandozeilen-Aufgaben ausfuehren diff --git a/docs/de-de/stage-2/backend/stripe-payment/index.md b/docs/de-de/stage-2/backend/stripe-payment/index.md new file mode 100644 index 0000000..ddb5921 --- /dev/null +++ b/docs/de-de/stage-2/backend/stripe-payment/index.md @@ -0,0 +1,355 @@ +# Stripe und andere Zahlungssysteme integrieren + +Wenn dein Produkt bereits Seiten, Login, Datenbank und ein grundlegendes Backend hat, ist die naechste praktische Frage: **Wie nimmst du Zahlungen entgegen?** + +Dieser Artikel ist in zwei Teile gegliedert: +- **Der erste Teil** behandelt nur die praktischste Grundeinbindung mit dem Ziel, Stripe schnell in dein Projekt zu integrieren. +- **Der zweite Teil** (Anhang) enthaelt Webhook-Details, Abo-Ereignisse und regionale Zahlungsunterschiede. + +> Empfohlene Vorkenntnisse +> - [Von der Datenbank zu Supabase](../database-supabase/) +> - [Grosses Sprachmodell unterstuetzt beim Schreiben von API-Code](../ai-interface-code/) +> - [Web-Anwendungen bereitstellen](../zeabur-deployment/) + +# Was du lernen wirst + +1. Wie sieht ein minimal funktionsfaehiges Zahlungssystem aus? +2. Wie du Stripe schnellstmöglich in dein Projekt integrierst. +3. Wie du Prompts schreibst, damit die KI dir das Zahlungssystem hinzufuegt. +4. Welche Zahlungsloesung fuer verschiedene Regionen Prioritaet haben sollte. + +--- + +# Teil 1: Grundlagen + +## 1. Drei Grundprinzipien merken + +1. **Preise muessen vom Backend bestimmt werden**, nicht vom Frontend. +2. **Berechtigungen werden durch Webhooks aktiviert**, nicht durch die Erfolgsseite. +3. **Deine eigene Datenbank muss den Zahlungsstatus speichern**, nicht nur Stripe. + +## 2. Was passiert, wenn das Frontend direkt mit Stripe kommuniziert? + +Wenn du echtes Geld einnehmen willst, ist dieser Ansatz gefaehrlich: +1. **Preise koennen leicht geaendert werden** - Browser-Anfragen koennen manipuliert werden. +2. **Sensible Informationen werden leicht preisgegeben** - Geheime Schluessel gehoeren nicht ins Frontend. +3. **Du kannst nicht zuverlaessig bestaetigen, ob die Zahlung erfolgreich war**. +4. **Datenbankstatus wird unordentlich**. + +Die sicherere Aufteilung: +- **Frontend**: Buttons anzeigen, Kauf initiieren, Seiten weiterleiten +- **Backend**: Preise bestimmen, Checkout-Sessions erstellen, Webhooks empfangen, Datenbank aktualisieren + +::: info In einem Satz +**Das Frontend kann Weiterleitungen uebernehmen, aber das Backend muss Preisgestaltung und Bestaetigung kontrollieren.** +::: + +## 3. Wann ist Stripe die richtige Wahl? + +- SaaS fuer internationale Nutzer +- Abo-basierte Mitgliedschaftsprodukte +- Digitale Produkte, Templates, KI-Guthabenpakete +- Schnelle kommerzielle Validierung + +## 4. Minimale funktionsfaehige Zahlungskette + +```mermaid +flowchart LR + user["Benutzer"] + frontend["Frontend"] + backend["Dein Backend"] + checkout["Stripe Checkout"] + webhook["Stripe Webhook"] + db["Supabase / Geschaeftsdatenbank"] + + user -->|"Kauf klicken"| frontend + frontend -->|"Zahlungs-Session anfordern"| backend + backend -->|"Session mit Backend-Preis erstellen"| checkout + frontend -->|"Zur Zahlungsseite weiterleiten"| checkout + checkout -->|"Ereignis nach Zahlung senden"| webhook + webhook -->|"Signatur pruefen und Status aktualisieren"| backend + backend -->|"In orders / subscriptions schreiben"| db + db -->|"Frontend liest neuen Status"| frontend +``` + +## 5. Standard-Zeitachse fuer die Zahlungsinitiierung + +```mermaid +sequenceDiagram + autonumber + actor User as Benutzer + participant Frontend as Frontend + participant Backend as Backend API + participant Stripe as Stripe Checkout + + User->>Frontend: "Upgrade" oder "Kaufen" klicken + Frontend->>Backend: POST /api/billing/create-checkout-session + Backend->>Backend: Plan pruefen und priceId zuordnen + Backend->>Stripe: Checkout Session erstellen + Stripe-->>Backend: session.url zurueckgeben + Backend-->>Frontend: Zahlungslink zurueckgeben + Frontend-->>User: Zu Stripe-Zahlungsseite weiterleiten + User->>Stripe: Zahlung abschliessen +``` + +## 6. Schnellstart + +### 6.1 Schritt 1: Produkte und Preise im Stripe-Dashboard erstellen + +In Stripes Modell: +- **Product** beschreibt, was du verkaufst (z. B. "Pro-Mitgliedschaft") +- **Price** beschreibt, wie viel es kostet und in welchem Zyklus (z. B. "9,90 USD/Monat") + +Oeffne diese Seiten: +- Stripe Dashboard: [Dashboard Login](https://dashboard.stripe.com/login) +- Produktdokumentation: [Manage products and prices](https://docs.stripe.com/products-prices/manage-prices) + +Arbeite im **Testmodus**. + +Minimale Konfiguration: +- `Product`: `Pro Plan` +- `Price 1`: `pro_monthly` +- `Price 2`: `pro_yearly` + +Merke dir die `price_id` Werte. + +Prompt fuer die KI: + +```text +Ich verwende Stripe zum ersten Mal. Bitte fuehre mich Schritt fuer Schritt durch die grundlegende Zahlungs-Konfiguration im Stripe-Dashboard. + +Bitte beziehe dich auf diese offiziellen Dokumente: +- https://docs.stripe.com/products-prices/manage-prices +- https://docs.stripe.com/checkout/quickstart?lang=node +``` + +### 6.2 Schritt 2: Umgebungsvariablen vorbereiten + +Mindestens erforderlich: +- `STRIPE_SECRET_KEY` +- `STRIPE_WEBHOOK_SECRET` +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- `APP_URL` +- `SUPABASE_URL` +- `SUPABASE_SERVICE_ROLE_KEY` + +### 6.3 Schritt 3: Checkout Session im Backend erstellen + +```text +Bitte integriere Stripe-Zahlungen in mein Projekt. + +Beziehe dich auf diese offiziellen Dokumente: +- https://docs.stripe.com/checkout/quickstart?lang=node +- https://docs.stripe.com/api/checkout/sessions/create +- https://docs.stripe.com/payments/subscriptions + +Ziele: +- Nutzer klickt auf "Kaufen" und wird zur Stripe-Zahlungsseite weitergeleitet +- Nur monatliche und jaehrliche Plaene +- Preise ueber Backend-Umgebungsvariablen bestimmen +``` + +### 6.4 Schritt 4: Frontend zur Zahlungsseite weiterleiten + +```text +Verbinde den "Kaufen"-Button in meinem Projekt mit Stripe. + +Anforderungen: +- Bestehende Seiten nicht aendern, nur die Button-Klick-Logik +- Nach dem Klick Backend-API fuer Zahlungslink aufrufen, dann zu Stripe weiterleiten +- Bei Fehlern eine einfache Meldung anzeigen +``` + +### 6.5 Schritt 5: Webhook fuer Datenbankaktualisierung + +::: info Warum dieser Schritt der wichtigste ist +Viele glauben, dass es reicht, wenn der Nutzer zur Erfolgsseite weitergeleitet wird. Das stimmt nicht. Wichtig ist: **Hat Stripe das Ereignis offiziell an deinen Webhook gesendet und hat dein Backend den Datenbankstatus erfolgreich aktualisiert?** +::: + +```text +Bitte integriere die automatische Aktivierung nach erfolgreicher Stripe-Zahlung. + +Beziehe dich auf: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli + +Ziel: +- Nach der Zahlung nicht nur zur Erfolgsseite weiterleiten +- Sondern den Mitgliedschaftsstatus in der Datenbank auf "aktiv" setzen +``` + +## 7. Prompt fuer die schnelle KI-Integration + +```text +Bitte integriere Stripe-Zahlungen in mein Projekt fuer eine einfachste funktionierende Mitgliedschaft. + +Anforderungen: +1. Ich bin Anfaenger - bitte analysiere zuerst das Projekt, bevor du Code aenderst. +2. Nur die einfachste Version: monatlicher und jaehrlicher Plan. +3. Nach dem Klick auf "Kaufen" Weiterleitung zur Stripe-Zahlungsseite. +4. Nach erfolgreicher Zahlung wird der Mitgliedschaftsstatus in der Datenbank aktiviert. +5. Keine komplexen Funktionen wie Coupons, Upgrades/Downgrades etc. +``` + +## 8. Die 4 haeufigsten Fehler + +1. **Die Erfolgsseite als Zahlungsbestaetigung betrachten** - Nur Webhooks sind massgebend. +2. **Das Frontend sendet den Betrag** - Schwere Preismanipulationsgefahr. +3. **Webhook-Route wird von `express.json()` vorab verarbeitet** - Stripe braucht den rohen Anforderungskoerper. +4. **Keine Idempotenz-Behandlung** - Webhooks koennen wiederholt werden. + +## 9. Auswahlberatung in einem Satz + +| Hauptnutzer | Zunaechst ausprobieren | +| :--- | :--- | +| Internationale SaaS | Stripe | +| Festland-China | Alipay / WeChat Pay | +| Hongkong oder grenzueberschreitende Teams | Stripe + lokale Wallet/FPS | + +## 10. Zusammenfassung + +Du hast nun die grundlegendste und wichtigste Zahlungskette gemeistert: + +1. Frontend initiiert Kauf. +2. Backend erstellt Checkout Session. +3. Nutzer zahlt auf der Stripe-Seite. +4. Stripe benachrichtigt das Backend per Webhook. +5. Backend aktualisiert die Datenbank. +6. Frontend zeigt nach Aktualisierung den neuen Mitgliedschafts- oder Bestellstatus. + +--- + +# Anhang + +## Anhang A: Die haeufigsten Stripe-Objekte + +| Objekt | Funktion | Vergleichbar mit | +| :--- | :--- | :--- | +| `Product` | Beschreibt, was verkauft wird | Produkt oder Mitgliedschaftsplan | +| `Price` | Beschreibt Preis und Abrechnungszyklus | Monatlich, jaehrlich, Einmalkauf | +| `Checkout Session` | Von Stripe verwalteter Zahlungsprozess | Zahlungsseite | +| `Subscription` | Periodisches Abonnementverhaeltnis | Automatische Verlaengerung | +| `Customer` | Zahlender Benutzer | Kundenprofil bei Stripe | +| `Webhook` | Asynchrone Benachrichtigung | Stripe teilt dir den Zahlungsstatus mit | + +## Anhang B: Warum die Erfolgsseite nicht gleich Zahlungserfolg bedeutet + +```mermaid +flowchart TB + pay["Nutzer zahlt bei Stripe"] + + subgraph unreliable["Unzuverlaessiger Pfad: Nur Erfolgsseite"] + success["Browser leitet zur Erfolgsseite weiter"] + fake["Frontend geht von Aktivierung aus"] + risk["Risiko: Seite geschlossen / URL gefaelscht / nicht gezahlt"] + success --> fake --> risk + end + + subgraph reliable["Zuverlaessiger Pfad: Backend-Webhook"] + event["Stripe-Server sendet Webhook"] + verify["Backend prueft Signatur"] + active["Datenbank aktualisiert auf bezahlt"] + event --> verify --> active + end + + pay --> success + pay --> event +``` + +**Kernunterschied:** + +| | Erfolgsseiten-Weiterleitung | Webhook-Benachrichtigung | +| :--- | :--- | :--- | +| Wer initiiert es? | Benutzer-Browser | Stripe-Server | +| Faelschbar? | Ja, URL direkt aufrufen | Nein, Signaturpruefung | +| Garantiert Zahlungserfolg? | Nein | Ja | + +### Richtiger Ansatz + +```javascript +// Falsch: Auf Erfolgsseite direkt aktivieren +if (window.location.pathname === '/success') { + activateMembership(); // Gefaehrlich! +} + +// Richtig: Immer Backend abfragen +async function checkStatus() { + const response = await fetch('/api/user/status'); + const data = await response.json(); + if (data.paymentStatus === 'paid') { + showMemberFeatures(); + } else { + showPendingMessage(); + } +} +``` + +## Anhang C: Wichtigste Abonnement-Ereignisse + +| Ereignis | Bedeutung | Typische Aktion | +| :--- | :--- | :--- | +| `checkout.session.completed` | Erste Aktivierung erfolgreich | Lokalen Abonnement-Datensatz erstellen | +| `invoice.paid` | Automatische Verlaengerung erfolgreich | Gueltigkeit verlaengern | +| `invoice.payment_failed` | Automatische Abbuchung fehlgeschlagen | Risikostatus markieren | +| `customer.subscription.deleted` | Abonnement gekuendigt | Berechtigungen entziehen | + +### Abonnementstatus-Diagramm + +```mermaid +stateDiagram-v2 + [*] --> NotStarted: Nutzer hat nicht gekauft + NotStarted --> Active: checkout.session.completed + Active --> Active: invoice.paid + Active --> PastDue: invoice.payment_failed + PastDue --> Active: Zahlungsausgleich erfolgreich + Active --> Canceled: customer.subscription.deleted + PastDue --> Canceled: Nicht innerhalb der Frist behoben + Canceled --> [*] +``` + +## Anhang D: Andere Zahlungsloesungen + +### 1. Festland-China + +**Alipay** und **WeChat Pay** sind die erste Wahl. + +Beide nutzen das "Zahlungsgateway"-Modell: Backend bestellt, Frontend ruft auf, Backend benachrichtigt. + +### 2. Hongkong + +Empfohlene Kombination: **Stripe** fuer internationale Karten und Abos + **Airwallex** oder **Adyen** fuer lokale Wallets und FPS. + +### 3. International / SaaS + +- **Stripe**: Beste API-Erfahrung, klare Dokumentation +- **PayPal**: Ergaenzender Kanal fuer internationale Geschaefte +- **Paddle**: Merchant of Record (MoR) - behandelt globale Steuern +- **Lemon Squeezy**: MoR, besonders fuer Indie-Entwickler und digitale Produkte + +### 4. Unternehmensloesungen + +- **Airwallex**: Zahlungsgateway + globale Konten +- **Adyen**: Unternehmensklasse, verarbeitet Billionen Euro jaehrlich + +### 5. Loesungsvergleich + +| Loesung | Geschaeftsmodell | Steuerbehandlung | Fuer wen | +| :--- | :--- | :--- | :--- | +| Stripe | Zahlungsgateway | Selbst behandeln | Internationale SaaS, Entwickler | +| PayPal | Zahlungsgateway | Selbst behandeln | Ergaenzender internationaler Kanal | +| Paddle | MoR | Paddle behandelt | B2B SaaS, die keine Steuern verwalten wollen | +| Lemon Squeezy | MoR | LS behandelt | Indie-Entwickler, digitale Produkte | +| Adyen | Zahlungsgateway | Selbst behandeln | Grossunternehmen | +| Airwallex | Gateway + Konten | Selbst behandeln | Grenzueberschreitende Geschaefte | +| Alipay/WeChat | Zahlungsgateway | Selbst behandeln | Festland-China | + +### 6. Nach Region auswaehlen + +| Dein Markt | Empfohlene Loesung | +| :--- | :--- | +| Festland-China | Alipay / WeChat Pay | +| Hongkong | Stripe + Airwallex / Adyen | +| Internationale SaaS | Stripe (selbst) oder Paddle (MoR) | +| Digitale Produkte (international) | Stripe / Lemon Squeezy / Paddle | +| Multi-Region Unternehmen | Adyen / Airwallex / Stripe Kombination | diff --git a/docs/de-de/stage-2/backend/zeabur-deployment/index.md b/docs/de-de/stage-2/backend/zeabur-deployment/index.md new file mode 100644 index 0000000..9758029 --- /dev/null +++ b/docs/de-de/stage-2/backend/zeabur-deployment/index.md @@ -0,0 +1,304 @@ +# Web-Anwendungen bereitstellen + +In diesem Tutorial stellen wir vor, wie du deine Web-Anwendung im Internet veroeffentlicht, damit andere darauf zugreifen koennen. Wir stellen drei haeufig genutzte Bereitstellungsplattformen vor: **Tencent Cloud CloudBase**, **Vercel** und **Zeabur**. + +# Was ist "Bereitstellung"? + +Bevor wir beginnen, klaeren wir, was "Bereitstellung (Deployment)" eigentlich bedeutet. Jede Website, die von externen Benutzern erreicht werden soll, benoetigt eine oeffentlich zugaengliche Netzwerkadresse. Aber die Adresse allein reicht nicht aus - dein geschriebener Webseiten-Code (HTML-, CSS-, JavaScript-Dateien oder Projekte mit React, Vue usw.) sowie zugehoerige Bild-/Videoressourcen muessen auf einem durchgehend online Server "abgelegt" werden, der Netzwerkanfragen beantwortet. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image1.png) + +Bildquelle: https://www.hostinger.com/tutorials/what-is-cloud-hosting + +Den gesamten Prozess des Hochladens von Ressourcen, der Konfiguration der Umgebung und des Startens des Dienstes bezeichnet man als **Bereitstellung (Deployment)**. + +Plattformen wie CloudBase, Vercel, Netlify und Zeabur wurden entwickelt, um genau diese Komplexitaet zu loesen. Sie automatisieren die Schritte "Server kaufen, Umgebung konfigurieren, Code hochladen, Dienst starten und Betrieb ueberwachen". Du musst lediglich dein Code-Repository (z. B. GitHub oder GitLab) mit der Plattform verbinden oder den Code direkt hochladen. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image4.png) + +--- + +# Bereitstellungsplattformen im Vergleich + +| Plattform | Merkmale | Anwendungsbereich | Kostenloseinheit | +|-----------|----------|-------------------|------------------| +| **Tencent Cloud CloudBase** | Schneller Zugriff in China, tiefe WeChat-Integration | Projekte hauptsaechlich fuer chinesische Nutzer | Vorhanden | +| **Vercel** | Gute Frontend-Framework-Unterstuetzung, enge GitHub-Integration | Moderne Frontend-Projekte (React/Vue/Next.js) | Vorhanden | +| **Netlify** | Umfassende Funktionen, Formularverarbeitung und Authentifizierung | Statische Websites mit erweiterten Funktionen | Vorhanden | +| **Zeabur** | Mehrere Sprachen und Service-Vorlagen, flexible Konfiguration | Komplexe Projekte mit mehreren Diensten (Dify, n8n) | ca. 5 USD/Monat kostenlos | + +--- + +# 1. Tencent Cloud CloudBase + +Tencent Cloud CloudBase ist ein einheitlicher Cloud-Backend-Service von Tencent Cloud, besonders geeignet fuer Entwickler in China. + +- **Schneller Zugriff in China**: Server stehen in China, geringe Latenz +- **WeChat-Integration**: Einfache Anbindung an WeChat-Mini-Programme und offizielle Konten +- **All-in-One-Loesung**: Statisches Website-Hosting, Cloud-Funktionen, Datenbank, Speicher +- **Grosszuegige kostenloseinheit**: Ausreichend kostenlose Ressourcen fuer Einzelentwickler + +## CloudBase verwenden + +### Schritt 1: Registrieren und anmelden + +Besuche die [Tencent Cloud CloudBase-Konsole](https://console.cloud.tencent.com/tcb) und melde dich mit WeChat oder QQ an. + +### Schritt 2: Umgebung erstellen + +Klicke auf "Neue Umgebung" und waehle einen Umgebungsnamen (z. B. `my-web-app`). + +### Schritt 3: Statisches Website-Hosting aktivieren + +Finde in der Umgebungsverwaltung die Funktion "Statisches Website-Hosting" und aktiviere sie. + +### Schritt 4: Code bereitstellen + +CloudBase bietet drei Bereitstellungsmethoden: + +- **Lokales Projekt hochladen**: Direkt statische Dateien hochladen +- **Vorlagenbereitstellung**: Voreingestellte Vorlagen wie React/Vue nutzen +- **Git-Repository-Bereitstellung**: Automatischer Abruf und Bereitstellung von GitHub + +### Schritt 5: Eigene Domain konfigurieren (optional) + +In den Einstellungen fuer statisches Website-Hosting kannst du eine eigene Domain binden und ein kostenloses HTTPS-Zertifikat beantragen. + +--- + +# 2. Vercel + +Vercel ist eine der weltweit beliebtesten Frontend-Bereitstellungsplattformen. + +- **Tiefe GitHub-Integration**: Code-Push loest automatisch Bereitstellung aus +- **Automatische Vorschau**: Jeder Pull-Request erhaelt einen eigenen Vorschaulink +- **Globales CDN**: Automatische weltweite Verteilung +- **Serverless-Funktionen**: Backend-APIs direkt im Projekt + +> Hinweis: Vercel kann in einigen Netzwerkumgebungen instabil sein. + +## Vercel verwenden + +### Schritt 1: Konto registrieren + +Besuche [Vercel](https://vercel.com) und melde dich mit deinem GitHub-Konto an. + +### Schritt 2: Projekt importieren + +1. Klicke auf "Add New Project" +2. Waehle das gewuenschte GitHub-Repository + +### Schritt 3: Build-Einstellungen konfigurieren + +| Framework | Build-Befehl | Ausgabeverzeichnis | +|-----------|-------------|-------------------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Next.js | `next build` | - | +| Reines HTML | - | Projektverzeichnis | + +### Schritt 4: Bereitstellen + +Klicke auf "Deploy" und warte bis der Build abgeschlossen ist. Du erhaeltst eine `xxx.vercel.app`-Domain. + +### Schritt 5: Eigene Domain (optional) + +In den Projekteinstellungen unter "Domains" kannst du deine eigene Domain hinzufuegen. + +--- + +# 3. Netlify + +Netlify ist eine weitere beliebte Frontend-Bereitstellungsplattform mit umfassenden Funktionen. + +- **Umfassende Funktionen**: Formularverarbeitung, Authentifizierung, Edge-Funktionen +- **Tiefe Git-Integration**: GitHub, GitLab, Bitbucket +- **Zweig-Vorschau**: Jeder Zweig erhaelt automatisch einen Vorschaulink +- **Globales CDN**: Automatische weltweite Verteilung +- **Formularverarbeitung**: Formulareingaben ohne Backend-Code + +## Netlify verwenden + +### Schritt 1: Konto registrieren + +Besuche [Netlify](https://www.netlify.com) und klicke auf "Sign up". + +### Schritt 2: Projekt importieren + +1. Klicke auf "Add new site" > "Import an existing project" +2. Waehle dein Code-Hosting-Plattform +3. Autorisiere Netlify fuer den Zugriff auf dein Repository + +### Schritt 3: Build-Einstellungen konfigurieren + +| Framework | Build-Befehl | Veroeffentlichungsverzeichnis | +|-----------|-------------|------------------------------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Angular | `ng build` | `dist/` | +| Next.js | `next build` | `out` | +| Reines HTML | - | `.` | + +### Schritt 4: Bereitstellen + +Klicke auf "Deploy site". Nach Abschluss erhaeltst du eine `xxx.netlify.app`-Domain. + +### Schritt 5: Eigene Domain (optional) + +1. Gehe zu Site-Einstellungen > "Domain management" +2. Klicke auf "Add custom domain" +3. Konfiguriere DNS-Eintraege + +### Besondere Funktionen + +#### Formularverarbeitung + +```html +
+

+ +

+

+ +

+

+ +

+

+ +

+
+``` + +#### Netlify Functions + +```javascript +exports.handler = async (event, context) => { + return { + statusCode: 200, + body: JSON.stringify({ message: "Hello from Netlify!" }) + }; +}; +``` + +#### Lokale Entwicklung + +```bash +# Netlify CLI installieren +npm install -g netlify-cli + +# Anmelden +netlify login + +# Lokalen Entwicklungsserver starten +netlify dev +``` + +--- + +# 4. Zeabur + +Zeabur ist eine aufstrebende Bereitstellungsplattform, besonders geeignet fuer komplexe Projekte mit mehreren Diensten. + +- **Reichhaltige Service-Vorlagen**: Dify, n8n, Datenbanken und mehr +- **Mehrere Bereitstellungsmethoden**: GitHub, Vorlagen, Docker, lokale Projekte +- **Flexible Service-Kombinationen**: Mehrere verbundene Dienste in einem Projekt +- **Nutzungsabhaengige Abrechnung**: Bezahlung nur fuer tatsaechliche Nutzung + +## Dify mit Zeabur bereitstellen + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image5.png) + +Oeffne die [Zeabur-Konsole](https://zeabur.com/projects) und klicke auf "New Project". + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image8.png) + +Die Erstellungsmethoden umfassen: + +1. **GitHub**: Verbindung zu deinem GitHub-Konto +2. **Vorlage (Template)**: Basierend auf Vorlagen bereitstellen +3. **Datenbanken**: Datenbank-Services bereitstellen +4. **Funktionen (Functions)**: JavaScript- oder Python-Code bereitstellen +5. **Lokales Projekt**: Ordner hochladen +6. **Docker-Image**: Bereitgestelltes Docker-Image deployen + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image9.png) + +Waehle **Vorlage** und suche nach "dify". Waehle eine Version aus. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image15.png) + +Gib einen Namen ein, um eine temporaere Domain zu generieren. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image16.png) + +Warte, bis alle Dienste gestartet sind. Klicke auf den Nginx-Service, um die Zugriffsadresse zu erhalten. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image17.png) + +Nach kurzer Wartezeit siehst du die Dify-Anmeldeseite. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image18.png) + +## Schlangenspiel mit Zeabur und Trae bereitstellen + +### HTML-Framework verwenden + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image23.png) + +Lass Trae ein HTML-basiertes Schlangenspiel generieren und lade den Ordner ueber Zeaburs lokale Bereitstellung hoch. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image27.png) + +Klicke auf "Network" > "Generate Domain", um eine oeffentliche Adresse zu erstellen. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image28.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image29.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image30.png) + +### React-Framework verwenden + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image31.png) + +React-Anwendungen erfordern eine Anpassung des Standard-Ports, da Zeabur nur Anwendungen auf Port 8080 unterstuetzt. + +Aendere den Standard-Port von 3000 auf 8080, z. B. indem du Trae anweist: "Bitte aendere den Standard-Port dieses React-Projekts auf 8080." + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image33.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image34.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image35.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image36.png) + +--- + +# Projekte stoppen und loeschen (Zeabur) + +Da aktivierte Serverressourcen Kosten verursachen, solltest du ungenutzte Dienste immer rechtzeitig stoppen. + +Klicke auf "Settings" im Projekt, scrolle nach unten: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image21.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image22.png) + +- **Suspend All Services**: Alle Dienste pausieren +- **Restart All Services**: Alle Dienste neu starten +- **Delete Project**: Projekt vollstaendig loeschen + +--- + +# Zusammenfassung + +In diesem Tutorial haben wir vier haeufig genutzte Web-Bereitstellungsplattformen vorgestellt: + +1. **Tencent Cloud CloudBase**: Fuer chinesische Nutzer, schnelle Zugriffsgeschwindigkeit +2. **Vercel**: Fuer moderne Frontend-Framework-Projekte, enge GitHub-Integration +3. **Netlify**: Umfassende Funktionen, Formularverarbeitung und Authentifizierung +4. **Zeabur**: Fuer komplexe Projekte mit mehreren Diensten + +Der Kernprozess ist bei allen Plattformen aehnlich: Code vorbereiten > Plattform waehlen > Build-Einstellungen konfigurieren > Bereitstellen. Mit diesen Faehigkeiten kannst du deine entwickelten Anwendungen mit der ganzen Welt teilen! diff --git a/docs/de-de/stage-2/frontend/design-to-code/index.md b/docs/de-de/stage-2/frontend/design-to-code/index.md new file mode 100644 index 0000000..11eede1 --- /dev/null +++ b/docs/de-de/stage-2/frontend/design-to-code/index.md @@ -0,0 +1,362 @@ +# Vom Design-Prototyp zum Projektcode + +::: tip :dart: Kernfrage +**Wie wandelt man Prototypen aus Designtools in tatsaechlich im Browser ausfuehrbaren Frontend-Code um?** +::: + +--- + +## 1. Drei Pfade vom Prototyp zum Code + +Nachdem man mit modernen Frontend-Designtools wie Figma oder MasterGo das Interface-Design abgeschlossen hat, stellt sich naturgemaess eine praktische Frage: Wie wandelt man diese strukturell vollstaendigen Designentwuerfe in tatsaechlich im Browser ausfuehrbaren Frontend-Code um? + +Im Allgemeinen gibt es drei typische Pfade vom Prototyp zum Code: + +| Pfad | Methode | Merkmale | Anwendungsbereich | +|------|----------|-----------|-------------------| +| **Pfad 1** | Basierend auf Bildern, multimodale Grossmodelle verwenden, um Code direkt zu rekonstruieren | Flexibel, kein spezielles Tool erforderlich | Schnelle Prototyp-Validierung, einfache Seiten | +| **Pfad 2** | Durch plattformeigene Faehigkeiten oder Plugins verwendbaren Code exportieren | Hohe Genauigkeit, gute Editierbarkeit | Figma/MasterGo-Nutzer | +| **Pfad 3** | Plattform kombiniert mit MCP-Faehigkeiten, um verwendbaren Code zu exportieren | Hoher Automatisierungsgrad, anpassbar | Workflows, die tiefe Integration erfordern | + +Dieser Artikel stellt die spezifischen Implementierungsmethoden dieser drei Pfade im Detail vor und hilft dir, den geeignetsten Workflow basierend auf deinen Projektanforderungen auszuwaehlen. + +::: tip :books: Vorkenntnisse +Bevor du mit diesem Abschnitt beginnst, empfehlen wir dir, das Tutorial [Einfuehrung in Figma und MasterGo](../figma-mastergo/) durchzuarbeiten, um die Grundlagen der Frontend-Designtools zu beherrschen. +::: + +--- + +## 2. Pfad 1: Multimodale AI direkte Code-Rekonstruktion + +Grossmodelle mit visuellen Faehigkeiten sind von Natur aus in der Lage, Bilder in Code umzuwandeln. Wir muessen nur den Screenshot des Designentwurfs direkt in den Dialog importieren und das Grossmodell dann den vollstaendigen Ergebniscode generieren lassen. + +### 2.1 Arbeitsablauf + +1. **Design-Screenshot erstellen** + - In Figma oder MasterGo die entworfene Seite als PNG oder JPG exportieren + - Sicherstellen, dass der Screenshot das vollstaendige Seitenlayout enthaelt + +2. **Multimodales AI-Modell auswaehlen** + - Modelle wie Gemini, Qwen, Claude etc. verwenden, die Bildeingabe unterstuetzen + - Hier wird als Beispiel Gemini verwendet + +3. **Prompt schreiben** + ``` + Bitte generiere den entsprechenden HTML/CSS-Code basierend auf diesem Design. + Anforderungen: + - Modernes CSS-Layout (Flexbox/Grid) verwenden + - Responsives Design, Anpassung an verschiedene Bildschirmgroessen + - Alle sichtbaren UI-Elemente einbeziehen + - Farben und Schriftgroessen moeglichst originalgetreu wiedergeben + ``` + +![](/zh-cn/stage-2/frontend/design-to-code/images/image42.png) + +4. **Code abrufen und speichern** + - Das Modell um vollstaendigen HTML-Code bitten + - Als einzelne `.html`-Datei speichern, fuer lokale Tests + - Spaeter in der lokalen IDE in React oder andere Frameworks konvertieren + +### 2.2 Haeufige Probleme und Loesungen + +Seitengenerierung ist keine einfache Aufgabe. Im konkreten Prozess koennen viele Probleme auftreten: + +| Problem | Loesung | +|----------|----------| +| Ungleichmaessige Interface-Anordnung | AI das spezifische Layout-Problem beschreiben, Anpassung von CSS margin/padding fordern | +| Interface wird nicht vollstaendig angezeigt | Pruefen, ob der korrekte viewport gesetzt ist, responsive Breakpoints hinzufuegen | +| Farbgenauigkeit unzureichend | Farbwaehler-Tool verwenden, um exakte Farbwerte aus dem Design zu ermitteln und AI zur Verfuegung zu stellen | +| Schriftarten stimmen nicht ueberein | Spezifischen Schriftnamen angeben oder Google Fonts als Alternative fordern | + +::: tip :bulb: Tipp +Es wird empfohlen, zunaechst HTML-Code zu generieren und nach dem Erhalt in der lokalen IDE in das React-Framework zu konvertieren. So erhaeltst du mehrere unabhaengige HTML-Dateien, die einheitlich in das Framework konvertiert werden koennen. +::: + +### 2.3 MasterGo AI Seitengenerierung + +MasterGo bietet ebenfalls eine leistungsstarke AI-Seitengenerierungsfunktion, die basierend auf Referenzbildern direkt verwendbaren Webcode generieren kann. + +#### AI-Funktionseinstieg finden + +In der MasterGo-Editor-Oberflaeche kannst du den AI-Tool-Button oben in der Werkzeugleiste finden: + +![](/zh-cn/stage-2/frontend/design-to-code/images/image47.png) + +#### Generierungsablauf + +1. **Referenzbild hochladen** + - Dasselbe Verfahren wie bei der multimodalen AI verwenden, um Design-Referenzbilder hochzuladen + - Textbeschreibung der Anforderungen hinzufuegen + +2. **Generierungsergebnis anzeigen** + +![](/zh-cn/stage-2/frontend/design-to-code/images/image48.png) + +![](/zh-cn/stage-2/frontend/design-to-code/images/image49.png) + +3. **Code abrufen** + - Auf den blauen Button "Auf Leinwand einfuegen" klicken, um die generierte Webseite direkt zu bearbeiten + - Oder rechts auf den "Code"-Button klicken, um den Code-Inhalt lokal zu kopieren + +![](/zh-cn/stage-2/frontend/design-to-code/images/image50.png) + +--- + +## 3. Pfad 2: Plattformeigene Faehigkeiten oder Plugins zum Code-Export + +### 3.1 Figma Make Code generieren + +Figma Make ist ein offizielles AI-Design-Tool von Figma, das basierend auf Benutzereingaben oder Referenzbildern Webseiten-Prototyp-UI-Interfaces hochpraezise rekonstruieren kann. + +#### Funktionsmerkmale + +- **Hohe Praezision**: Bessere Ergebnisse als bei nativer AI-Code-Generierung +- **Editierbarkeit**: Generierungsergebnisse koennen in bearbeitbare Figma-Design-Dateien konvertiert werden +- **GitHub-Integration**: Direkte Synchronisierung des Codes mit GitHub wird unterstuetzt + +::: tip :key: Berechtigungshinweis +Die volle Funktionalitaet von Figma Make erfordert Pro-Benutzerrechte. Studenten koennen durch Bildungszertifizierung kostenlos Pro-Rechte erhalten. +::: + +#### Arbeitsschritte + +1. **Figma Make oeffnen** + - Auf der Figma-Startseite auf den Make-Button klicken + - Oder [Figma Make](https://www.figma.com/make) aufrufen + +2. **Referenzbild hochladen** + - Das Design, das du rekonstruieren moechtest, in den Dialog hochladen + - Prompt zur Beschreibung der Anforderungen hinzufuegen + +![](/zh-cn/stage-2/frontend/design-to-code/images/image43.png) + +3. **Generierungsergebnis anzeigen** + - Nach kurzer Wartezeit wird das Rendering-Ergebnis angezeigt + - Auf den Abspiel-Button oben rechts fuer Vollbild-Vorschau klicken + +![](/zh-cn/stage-2/frontend/design-to-code/images/image44.png) + +4. **Detailanpassungen** + - Auf das Editor-Icon oben rechts klicken (Maus- und Lineal-Icon) + - Zurueck zur vertrauten Figma-Editor-Oberflaeche fuer detaillierte Anpassungen + +![](/zh-cn/stage-2/frontend/design-to-code/images/image45.png) + +5. **Code exportieren** + - Nach zufrieden stellenden Anpassungen den Code-Export auswaehlen + - Kann direkt mit GitHub verbunden werden, um Code zu speichern + +![](/zh-cn/stage-2/frontend/design-to-code/images/image46.png) + +### 3.2 Plugin-Code-Export + +Zusaetzlich zu den nativen AI-Funktionen der Plattform unterstuetzen sowohl Figma als auch MasterGo den Code-Export ueber Plugins: + +**Haeufige Figma-Plugins:** +- **Figma to Code**: Designentwuerfe in React-, Vue-, HTML- und anderen Code konvertieren +- **Anima**: High-Fidelity-Code-Generierung, unterstuetzt Interaktionseffekte +- **Locofy**: AI-gesteuertes Design-zu-Code-Tool + +**Verwendungsschritte:** +1. In Figma das Plugin-Panel (Plugins) oeffnen +2. Das gewuenschte Code-Export-Plugin suchen und installieren +3. Das zu exportierende Design-Element auswaehlen +4. Das Plugin ausfuehren, das Zielframework und das Codeformat waehlen +5. Den generierten Code kopieren oder herunterladen + +--- + +## 4. Pfad 3: Plattform kombiniert mit MCP-Faehigkeiten zum Code-Export + +### 4.1 Was ist MCP? + +MCP (Model Context Protocol, Modellkontext-Protokoll) ist ein offener Standard, der es AI-Modellen ermoeglicht, sicher und kontrolliert auf externe Tools und Datenquellen zuzugreifen. Im Kontext von Frontend-Designtools ermoeglicht MCP Grossmodellen den direkten Zugriff auf die Struktur, Stile und Komponenteninformationen von Designdateien, um so praeziseren Code zu generieren. + +### 4.2 Funktionsweise von MCP + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ AI-Modell │ ←→ │ MCP-Server │ ←→ │ Designtool │ +│ (Claude etc.)│ │ (Protokoll- │ │(Figma/MasterGo)│ +│ │ │ anpassung) │ │ │ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +**Arbeitsablauf:** +1. Das AI-Modell sendet ueber das MCP-Protokoll eine Anfrage an das Designtool +2. Das Designtool gibt strukturierte Designdaten zurueck (Ebenen, Stile, Komponenten etc.) +3. Das AI-Modell versteht die Designstruktur und generiert den entsprechenden Code +4. Der Code kann direkt exportiert oder in die Entwicklungsumgebung synchronisiert werden + +### 4.3 Figma + MCP in der Praxis + +#### Umgebungsvorbereitung + +1. **MCP-Server installieren** + ```bash + # Figma MCP-Server mit npx installieren + npx figma-mcp-server + ``` + +2. **Claude Desktop oder ein anderes MCP-unterstuetztes AI-Tool konfigurieren** + ```json + { + "mcpServers": { + "figma": { + "command": "npx", + "args": ["figma-mcp-server"], + "env": { + "FIGMA_ACCESS_TOKEN": "your-figma-token" + } + } + } + } + ``` + +3. **Figma Access Token abrufen** + - Bei Figma anmelden -> Settings -> Personal Access Tokens + - Neuen Token generieren und speichern + +#### Verwendung + +1. **MCP-Verbindung im AI-Tool aktivieren** + - Claude Code oder eine andere MCP-unterstuetzte IDE oeffnen + - Sicherstellen, dass der MCP-Server verbunden ist + +2. **Designdatei-Link bereitstellen** + ``` + Nutzer: Bitte hilf mir, dieses Figma-Design in React-Code umzuwandeln + Link: https://www.figma.com/file/xxxxx + + AI: Ich habe ueber MCP eine Verbindung zu Figma hergestellt und lese die Designdatei-Struktur... + ``` + +3. **AI analysiert automatisch und generiert Code** + - Der MCP-Server ruft den Ebenenbaum der Designdatei ab + - AI versteht die Komponentenstruktur und die Stileigenschaften + - Generiert React/Vue-Komponenten mit korrekter Benennung und Struktur + +4. **Iterative Optimierung** + ``` + Nutzer: Bitte extrahiere die Button-Komponente als eigenstaendige wiederverwendbare Komponente + + AI: Gerne. Ich habe ueber MCP die Button-Komponente im Designsystem identifiziert + und generiere gerade eine React-Komponente mit Props-Interface... + ``` + +### 4.4 Vorteile von MCP + +| Merkmal | Traditionelle Methode | MCP-Methode | +|----------|----------------------|-------------| +| **Datenpraesion** | Abhaengig von Screenshots, Details koennen verloren gehen | Direkter Zugriff auf Original-Designdaten | +| **Komponenten-Erkennung** | AI muss Komponentengrenzen erraten | Praeziser Zugriff auf Komponentendefinitionen | +| **Stil-Genauigkeit** | Basiert auf Pixel-Schaetzungen | Zugriff auf exakte Design-Tokens | +| **Iterationseffizienz** | Bei jeder Aenderung muss ein neuer Screenshot erstellt werden | Echtzeit-Synchronisierung von Designaenderungen | +| **Automatisierungsgrad** | Manuelles Kopieren und Einfuegen | Direktes Schreiben in Projektdateien | + +### 4.5 Aktuell verfuegbare MCP-Tools + +**Designtool-MCP:** +- **Figma MCP Server**: Offiziell unterstuetzte MCP-Implementierung +- **MasterGo MCP**: Von der Community entwickelter MasterGo-Adapter + +**Entwicklungsumgebungs-MCP:** +- **Claude Code**: Nativer Support fuer das MCP-Protokoll +- **Cline**: VS-Code-Plugin, unterstuetzt MCP-Verbindungen +- **Trae**: MCP-Funktionalitaet kann durch Konfiguration aktiviert werden + +::: tip :crystal_ball: Zukunftsperspektive +Das MCP-Protokoll entwickelt sich rasant weiter. Die Integration zwischen Designtools und Entwicklungsumgebungen wird noch enger werden. Es ist mit weiteren One-Click-Design-zu-Code-Loesungen zu rechnen, die die Luecke zwischen Design und Entwicklung weiter verkleinern. +::: + +--- + +## 5. Arbeiten nach dem Code-Export + +### 5.1 Lokale Tests + +Nach dem Abrufen des Codes in der lokalen IDE oeffnen und testen: + +1. **Neues Projekt erstellen** + ```bash + # Bei HTML-Dateien direkt im Browser oeffnen + open index.html + + # Bei React/Vue-Projekten + npm install + npm run dev + ``` + +2. **Mit AI IDE zusammenarbeiten** + - Den generierten Code in Trae oder eine andere AI IDE importieren + - AI bei der Behebung von Layout-Problemen und dem Hinzufuegen von Interaktivitaet helfen lassen + +### 5.2 Haeufige Probleme und Loesungen + +| Phase | Problem | Loesung | +|-------|---------|----------| +| Layout | Elemente verschoben | CSS display- und position-Eigenschaften pruefen | +| Stil | Farben inkonsistent | Browser-Entwicklertools verwenden, um tatsaechlich angewandte Farbwerte zu pruefen | +| Responsive | Darstellung auf Mobilgeraeten fehlerhaft | Media-Query-Breakpoints hinzufuegen | +| Interaktion | Button reagiert nicht | JavaScript-Ereignisbindung pruefen | + +--- + +## 6. Vergleich der drei Pfade und Auswahl-Empfehlungen + +### 6.1 Pfad-Vergleich + +| Dimension | Pfad 1: Multimodale AI | Pfad 2: Plattform-Faehigkeiten | Pfad 3: MCP | +|------------|------------------------|-------------------------------|-------------| +| **Einstiegsschwierigkeit** | :star: Einfach | :star::star: Mittel | :star::star::star: Anspruchsvoll | +| **Rekonstruktionsgenauigkeit** | :star::star::star: Mittel | :star::star::star::star: Hoch | :star::star::star::star::star: Hoechste | +| **Flexibilitaet** | :star::star::star::star::star: Hoch | :star::star::star: Mittel | :star::star::star::star: Hoch | +| **Automatisierungsgrad** | :star::star: Niedrig | :star::star::star: Mittel | :star::star::star::star::star: Hoechster | +| **Kosten** | Niedrig (nach API-Aufruf) | Mittel (moeglicherweise Pro noetig) | Niedrig (Open-Source-Tools) | + +### 6.2 Auswahl-Empfehlungen + +**Pfad 1 (Multimodale AI) waehlen, wenn:** +- Schnelle Ideenvalidierung noetig ist +- Das Designtool nicht feststeht und haeufig gewechselt wird +- Keine hohen Anforderungen an die Rekonstruktionsgenauigkeit bestehen +- Das Budget begrenzt ist + +**Pfad 2 (Plattform-Faehigkeiten) waehlen, wenn:** +- Das Team hauptsaechlich Figma oder MasterGo verwendet +- Hochpraezise Code-Rekonstruktion erforderlich ist +- Designer und Entwickler haeufig zusammenarbeiten muessen +- Bereit, in eine Pro-Version zu investieren + +**Pfad 3 (MCP) waehlen, wenn:** +- Hoechstmöglicher Automatisierungsgrad angestrebt wird +- Die technische Kompetenz zur Konfiguration einer MCP-Umgebung vorhanden ist +- Das Projekt haeufige Iterationen von Design zu Code erfordert +- Ein standardisierter Design-Entwicklungs-Workflow aufgebaut werden soll + +--- + +## 7. Zusammenfassung + +Durch dieses Kapitel hast du die drei Kernpfade vom Design-Prototyp zum Code kennengelernt: + +1. **Multimodale AI-Direktkonvertierung**: Flexibel und schnell, geeignet fuer Prototyp-Validierung +2. **Plattforme native Faehigkeiten**: Hohe Genauigkeit, geeignet fuer professionelle Design-Workflows +3. **MCP-Protokoll-Integration**: Hoechster Automatisierungsgrad, repraesentiert den Trend der Zukunft + +::: tip :bulb: Best Practices +- **Anfaenger-Empfehlung**: Mit Pfad 1 (multimodale AI) beginnen, um schnell einzusteigen +- **Team-Zusammenarbeit**: Pfad 2 (Plattform-Faehigkeiten) verwenden, um Design-Konsistenz zu gewaehrleisten +- **Effizienz-Prioritaet**: Pfad 3 (MCP) ausprobieren, um einen automatisierten Workflow aufzubauen +- **Gemischte Nutzung**: Je nach Projektphase flexibel zwischen verschiedenen Pfaden wechseln +::: + +--- + +## Referenzressourcen + +- [Einfuehrung in Figma und MasterGo](../figma-mastergo/) - Grundlagen der Designtools erlernen +- [Gemeinsam Hogwarts-Portraets erstellen](../hogwarts-portraits/) - Vollstaendiges Projektpraktikum +- [MCP Offizielle Dokumentation](https://modelcontextprotocol.io/) - Protokolldetails kennenlernen +- [Figma Make Offizielle Dokumentation](https://help.figma.com/hc/en-us/sections/360007453634-Figma-Make) +- [MasterGo AI Tutorials](https://mastergo.com/tutorials) diff --git a/docs/de-de/stage-2/frontend/figma-mastergo/index.md b/docs/de-de/stage-2/frontend/figma-mastergo/index.md new file mode 100644 index 0000000..bebdad4 --- /dev/null +++ b/docs/de-de/stage-2/frontend/figma-mastergo/index.md @@ -0,0 +1,303 @@ +# Einfuehrung in Figma und MasterGo + + + +::: tip :dart: Kernfrage +**Wie erstellt man von Grund auf Webseitenprototypen mit modernen Designtools?** +::: + +--- + +## 1. Warum sollte man Frontend-Designtools lernen? + +Bevor wir beginnen, muessen wir eine Frage klaeren: Warum muss man "Frontend-Designtools" lernen? Man kann doch mit HTML/CSS-Code Seiten aufbauen -- ist es wirklich notwendig, noch eine zusaetzliche Software und Technologie zu lernen? + +In Wirklichkeit ist das Betreiben einer Seite und das gute Produktdesign zwei voellig unterschiedliche Konzepte. Code kuemmert sich nur darum, wie etwas im Browser gerendert und auf verschiedenen Geraeten ausgefuehrt wird; Frontend-Designtools loesen das Problem der Informationsverteilung -- wie Frontend-Interaktionen angeordnet werden, wie zwischen verschiedenen Seiten navigiert wird, wie visuelle Prioritaeten verteilt werden. Man muss nur in einem Designtool eine Leinwand erstellen, um Layout, Informationsebenen und Interaktionsmethoden auf einem Bildschirm vergleichen und die geeignetste Praesentationsform bestimmen zu koennen. + +Wenn man direkt mit dem Schreiben von Code beginnt oder AI komplette Frontend-Seiten generieren laesst, ist das Benutzererlebnis in der Regel nicht besonders gut. Ein durchdachtes Produkt beruecksichtigt den Komfort der Benutzerinteraktion sowie die Inhaltsverteilung, die verschiedene Seiten vermitteln sollen. Aus der Perspektive des Benutzers wird zuerst das Frontend-Seitenlayout entworfen und dann in Code umgewandelt oder generiert. + +Zudem senken Frontend-Designtools aus Sicht der Teamzusammenarbeit die Kooperationskosten zwischen verschiedenen Parteien: Designer, Produktmanager und Entwickler muessen nicht mehr einzeln mentale Bilder oder abstrakte Codebeschreibungen interpretieren. Stattdessen wird eine kooperative Arbeit ermoeglicht, bei der alle um eine sichtbare, kommentierbare und iterierbare Leinwand diskutieren koennen -- mit Versionsverwaltung, Anforderungsaenderungen und Feedback. Darueber hinaus sind moderne Frontend-Designtools laengst keine reinen Zeichenprogramme mehr: Mit einem Klick koennen Teilcodes generiert, Designsysteme und Komponentenbibliotheken verwaltet werden. Die neuen Designtools koennen viel repetitive Handarbeit (Ausrichten, Bemassen, Exportieren, Aendern von Stilen) automatisieren oder in Stapelverarbeitung ausfuehren, was die Entwicklungseffizienz beim Seitendesign enorm steigert. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image8.png) + +### 1.1 Die Entwicklung der Frontend-Designtools + +Im Laufe der Zeit hat sich das, was man als Frontend-Designtool bezeichnet, kontinuierlich weiterentwickelt. Von der Photoshop-Aera der 90er Jahre, die hauptsaechlich auf lokales Bitmap-Editing ausgerichtet war, ueber die Vektorisierung und Komponenten-Workflows, die Sketch um 2010 einleitete, bis hin zu Figma, das ab 2016 die Zusammenarbeit konsequent in die Cloud verlagerte -- Designteams gingen von der Einzelarbeit schrittweise zur Echtzeit-Zusammenarbeit mehrerer Personen ueber. Im Jahr 2025 ist AI tatsaechlich in diese Tools integriert worden: Von "Seitenentwuerfe aus einem Satz generieren" bis hin zu "Designs direkt in ausfuehrbare Frontend-Strukturen umwandeln" -- "Design als Code" und "Mensch-Maschine-Kooperation" werden von Konzepten zu nutzbarer Produktivitaet. + +In diesem Abschnitt stellen wir die zwei repraesentativsten modernen Frontend-Designtools vor: Figma und MasterGo. Einerseits decken beide die Kernfaehigkeiten moderner UI/UX ab (Vektor-Editing, Komponentensysteme, Auto-Layout, Code-Uebergabe etc.) und koennen den vollstaendigen Zyklus vom Wireframe ueber High-Fidelity bis zur Entwickleruebergabe unterstuetzen. Andererseits haben beide Tools nach 2025 praktische AI-Funktionen eingefuehrt, die helfen, Designs in tatsaechlich ausfuehrbare Programme umzuwandeln, ohne das Originaldesign zu veraendern. + +## 1.2 Die Entstehungsgeschichte + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image9.png) + +In der Zeit, bevor spezielle Frontend-Tools existierten, wurde die visuelle Gestaltung der gesamten Oberflaechen-Designbranche lange Zeit von "Allround"-Designsoftware wie Photoshop uebernommen. Designer erstellten die visuelle Gestaltung ganzer Seiten ueber lokal geschichtete Ebenen und lieferten schliesslich die durchaus voluminoesen .psd-Quelldateien an die Frontend-Entwickler -- und um das Design praezise umzusetzen, mussten die Frontend-Entwickler drei muehsame und entscheidende Aufgaben manuell erledigen: + +Erstens das "Zerschneiden": Aus der mehrschichtigen Struktur der .psd-Datei mussten Bottons, Icons, Logos, Hintergrundmodule und andere unabhaengige visuelle Elemente einzeln extrahiert und als PNG, JPG und andere webfaehige Bildformate exportiert werden (da Webseiten die PSD-Ebeneninformationen nicht direkt erkennen koennen und nur auf diese zerteilten Bilder zur Darstellung von Details zurueckgreifen koennen). + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image10.png) + +Zweitens das "Ausmessen": Mit dem im Programm integrierten Messwerkzeug mussten Breite, Hoehe und Abstaende (margin/padding) zwischen verschiedenen Modulen elementweise erfasst werden, um sicherzustellen, dass alle Masse bis auf das Pixel genau stimmten. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image11.png) + +Drittens das "Bemassen": Aus dem Design mussten die "unsichtbaren, aber notwendigen" impliziten Parameter extrahiert werden -- wie Schriftgroesse, Schriftgewicht, Zeilenabstand, RGB- oder HEX-Farbwerte jedes Farbblocks usw. Dies entsprach dem manuellen "Herauskratzen" derjenigen "Designspezifikationen", die der Designer nicht auf Papier geschrieben hatte. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image12.png) + +Erst danach begann die eigentliche Frontend-Implementierungsphase. Unabhaengig davon, ob natives HTML/CSS/JS oder Frameworks wie Vue, React verwendet wurden, war der grundsaetzliche Prozess derselbe. Das Frontend nutzte den "Container als zentrales Traegerelement" und baute die Seitenstruktur basierend auf der Hierarchie und Semantik der einzelnen Module im Design neu auf. Ein Container ist hierbei eine Einheit mit klar definierten Layout-Grenzen, die speziell dazu dient, untergeordnete Elemente aufzunehmen und zu organisieren. Er stellt selbst keinen konkreten Inhalt dar, definiert aber ueber Flex, Grid und andere Regeln den Anordnungsbereich fuer die internen Elemente. Die "Strukturbloecke" (wie obere Navigationsleiste, Seitenleiste, Artikellistenbereich, untere Fusszeile und andere sichtbare Funktions- oder Inhaltsbereiche) basieren auf diesen Containern; innerhalb jedes Strukturblocks sind wiederum kleinere Container verschachtelt, die Elemente organisieren -- zum Beispiel besteht ein Artikellisteneintrag aus einem "Listeneintrag-Container", der Innenabstaende und Gesamtlayout steuert und dann Titel, Zusammenfassung, Zeitstempel, Titelbild und weitere Detailelemente umschliesst. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image13.png) + +In modernen Frontend-Frameworks werden diese "Strukturbloecke (samt zugehoeriger Container und Elemente)" in der Regel als "Komponenten" implementiert. Eine Komponente kann vereinfacht verstanden werden als: eine wiederverwendbare Interface-Einheit mit klaren Grenzen, die Container-Layout und Logik integriert. Sie enthaelt sowohl Container, die Erscheinungsbild und Anordnung steuern (z. B. definiert die "Button-Komponente" Breite, Hoehe und Abrundung ueber einen Container; die "Artikelkarten-Komponente" organisiert die Position von Titel und Titelbild ueber einen Container), als auch Interaktionslogik. Teile, die im Design wiederholt auftauchen und eine einheitliche Form haben (wie einheitlich gestylte Buttons oder mehrfach verwendete Artikelkarten), werden im Code als Komponenten abstrahiert: Sie koennen in verschiedenen Seiten und Szenarien wiederverwendet werden, was doppelte Entwicklung reduziert, und durch die einheitlichen Regeln der internen Container wird sichergestellt, dass Layout und Stil an allen Verwendungsstellen hoechst konsistent sind. + +Anschliessend verwendet das Frontend ein Stilsystem, um Visuelles und Layout zu reproduzieren. Die im Zerschneide-Schritt exportierten Ressourcen wie PNG/JPG werden als ``, Hintergrundbilder innerhalb von Komponenten oder Strukturbloecken eingebunden oder gemaess den Empfehlungen des jeweiligen Frameworks als statische Ressourcen importiert. Die im Ausmessen-Schritt ermittelten Werte fuer Breite, Hoehe, Abstaende und Zeilenhoehen werden als `width`, `height`, `margin`, `padding`, `line-height` und andere Stileigenschaften auf die entsprechenden Komponenten oder Strukturbloecke angewendet. Die im Bemassen-Schritt erfassten Farben, Schriften, Schatten, Abrundungen sowie Hover-/Active-Zustaende werden in konkrete Loesungen wie CSS, CSS Modules, CSS-in-JS oder Tailwind umgesetzt -- als `color`, `font-family`, `font-size`, `box-shadow`, `border-radius` sowie Pseudoklassen oder Zustandsklassen. An diesem Punkt liefern Zerschneiden, Ausmessen und Bemassen einen Satz praeziser visueller Parameter, waehrend Komponenten und Strukturbloecke die Code-Organisationseinheiten bilden, die diese Parameter aufnehmen. Beides zusammen ergibt eine wartbare, wiederverwendbare Interface-Implementierung. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image14.png) + +Das auf lokalen Dateien zentrierte Modell war jedoch naturgemaess ineffizient. Versionen wurden per E-Mail und Cloud-Speicher uebertragen, neue und alte Entwuerfe liessen sich leicht verwechseln, und zwischen Design und Entwicklung herrschte eine grosse Abhaengigkeit von den oben beschriebenen komplexen Interaktionsmethoden -- die Kooperationskosten und Fehlerquoten waren nicht gering. + +Mit dem Aufkommen des mobilen Internets stiegen die Anforderungen an Oberflaechenkomplexitaet und Iterationsgeschwindigkeit rasant an, und Photoshops "gross und alles umfassend" wirkte zunehmend schwerfaellig. In dieser Phase erschien Sketch. Sketch konzentrierte sich auf das UI-Design selbst und entfernte den groessten Teil der mit der visuellen Nachbearbeitung verbundenen Buerde; mit Symbols wurden haeufig wiederverwendete Elemente wie Buttons, Navigation und Eingabefelder als Komponenten strukturiert, wobei eine Aenderung global synchronisiert wurde; in Kombination mit Tools wie Zeplin wurden Bemassungen und Stil-Fragmente automatisch generiert. Sketch brachte das "Komponenten-Denken" in den Design-Workflow. Es blieb jedoch ein Desktop-basiertes lokales Datei-Programm; Echtzeit-Zusammenarbeit erforderte Umwege ueber Cloud-Speicher, Drittanbieter-Plugins oder Versionsverwaltungstools und loeste das Problem "mehrere Personen aendern gleichzeitig denselben Entwurf" nicht grundlegend. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image15.png) + +Was die Spielregeln wirklich veraenderte, war Figma. Seit 2016 integrierte es UI-Design, Prototyping und Kommentare in den Browser und unterstuetzte eine Reihe moderner Funktionen: mehrere Echtzeit-Cursor, Online-Kommentare, Versionszeitlinien, Freigabelinks usw. -- was heute selbstverstaendlich erscheint, war damals eine direkte Herausforderung des Photoshop/Sketch-Modells. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image16.png) + +Damit war das Oberflaechendesign nicht mehr auf Einzelcomputer verstreute Dateien, sondern auf eine einzige Online-Leinwand konzentriert, die sich in Echtzeit aktualisierte. Rund um diese Leinwand lassen sich noch weitergehende Gedanken anstellen -- die Grenze zwischen Design und Frontend-Code mit Automatisierung oder AI zu verwischen. + +Zunaechst konnten wir nur auf verschiedene Plattform-Plugins zurueckgreifen, um Komponenten- und Stilinformationen aus Designs halbautomatisch als Code-Snippets (wie React/Vue-Komponentengerueste, CSS-Variablen etc.) zu exportieren. Der Kern bestand dabei in einer strukturierten Informationsextraktion ueber Plugins. Spaeter, mit der Weiterentwicklung der Plattformfaehigkeiten, begannen die meisten Designplattformen, die Grossmodell-MCP-Funktionalitaet (Model Context Protocol, Modellkontext-Protokoll) zu unterstuetzen: Dieses Protokoll bietet einen Standardmechanismus, der es Grossmodellen ermoeglicht, sicher und kontrolliert auf Designdateien, Plugin-Schnittstellen und Projektmetadaten zuzugreifen und so Designs noch bequemer als Code zu exportieren. + +Darueber hinaus trat die Frontend-Code-Automatisierung auf Basis von Plugins und MCP in die Phase ein, in der nativ die Ableitung von Code-Strukturen direkt aus dem Design unterstuetzt wurde. Wir koennen im Designtool mit einem Klick Frontend-Projektgerueste, Komponentenhierarchien, Stilsysteme und entsprechende Code-Ergebnisse generieren. Dadurch werden Designer und Frontend-Entwickler von der muehsamen manuellen Uebertragung von Designdetails befreit und koennen mehr Energie in die Optimierung des Benutzererlebnisses und die Aktualisierung und Iteration von Funktionsversionen investieren. + +--- + +## 2. Figma Einfuehrung + +Nun kommen wir von den abstrakten Konzepten zur praktischen Bedienung. Da die Zeit begrenzt ist, werden wir nur die grundlegende Bedienlogik von Figma lernen, damit auch jemand, der noch nie ein Designtool verwendet hat, die Uebungen problemlos mitmachen kann. Wenn du eine vollstaendige Einarbeitung in alle Figma-Funktionen moechtest, empfehlen wir dir die ausfuehrlichen offiziellen Tutorials von Figma: https://help.figma.com/hc/en-us/sections/30880632542743-Figma-Design-for-beginners + +Oder du folgst diesem Tutorial, um aehnlich wie bei einem persoenlichen Portfolio eine einfache Webseite schnell aufzubauen: https://help.figma.com/hc/en-us/sections/35895585621655-Figma-Sites-collectio + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image17.png) + +Links befindet sich der Einstieg fuer Projekterstellung und Ressourcenverwaltung, die wenigen Buttons oben rechts sind die haeufigen Figma-Funktionen. Dabei dient Make dazu, mit einem einzigen Satz von AI zuerst einen groben Interface- oder Strukturentwurf generieren zu lassen; Design ist der Hauptarbeitsbereich zum Zeichnen von Webseiten/App-Oberflaechen, zum Aufbau von Komponenten und zum Erstellen von Prototypen; FigJam ist wie ein Team-Whiteboard zum Anbringen von Klebezetteln, zum Zeichnen von Flussdiagrammen und fuer vorlaeufige Diskussionen; Buzz ist ein Tool zur skalierten Erstellung von Markenassets fuer die massenhafte Generierung von Inhalten zur Wahrung der Markenkonsistenz; und Site dient dazu, diese Designs zu einer tatsaechlich zugaenglichen Webseite oder Dokumentationsseite zusammenzufassen und oeffentlich zu praesentieren. + +Auf den ersten Blick scheint Figma sehr viele Funktionen zu haben und schwer zugaeanglich zu sein. Aber im Grunde sind solche funktionalen Tools eine Frage der Uebung -- man muss keine Angst haben, anfangs Fehler zu machen, und man muss auch nicht alles auf Anhieb richtig machen. Einfach anfangen, herumzuspielen; mit der Zeit wird man schnell sicher im Umgang. + +In diesem Tutorial werden wir die Design-Funktion kurz erklaeren, um einen schnellen Einstieg zu ermoeglichen. + +### 2.1 Neue Design-Datei erstellen + +Waehle auf der Startseite oder oben rechts den Eintrag **Design**, um eine neue Datei zu erstellen. Du gelangst auf eine leere Design-Leinwand. +Diese Oberflaeche ist grob in drei Bereiche unterteilt: Links befinden sich Seiten und Ebenen zur Anzeige und Bearbeitung der Seiten- und Element-Hierarchie; in der Mitte liegt die Leinwand zur Ansicht des aktuellen Effekts; rechts befinden sich Eigenschaften und Stile zur Aenderung von Form, Farbe und Stil; unten verlaeuft eine Werkzeugleiste zum Wechseln zwischen Werkzeugen, darunter Auswahl, Formen zeichnen, Text eingeben, Kommentare und Plugins. Nach der Auswahl eines Werkzeugs kann die Esc-Taste gedrueckt werden, um zum Standard-Mauswerkzeug zurueckzukehren. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image18.png) + +### 2.2 Deinen ersten Frame (Zeichentafel) erstellen + +Bevor du Elemente platzierst, musst du zunaechst eine klare Begrenzung fuer die Seite festlegen. Diese Begrenzung wird durch einen Frame definiert. Du kannst das Frame-Werkzeug in der unteren Werkzeugleiste auswaehlen oder einfach die Taste F auf der Tastatur druecken und dann einen rechteckigen Bereich auf der Leinwand ziehen. + +1. Verwende das Frame-Werkzeug in der unteren Werkzeugleiste oder druecke direkt `F` auf der Tastatur. +2. Zeichne einen rechteckigen Bereich auf der Leinwand. Aendere in der rechten Eigenschaftsleiste die Breite auf z. B. `1440` und die Hoehe auf `900`. +3. Benenne diesen Frame in der linken Ebenenleiste um, z. B. in `My First Page` oder deinen Projektnamen. + +Dieser Frame ist der Seitencontainer fuer eine Bildschirmansicht. Alle nachfolgenden Inhalte wie Ueberschriften, Text, Buttons und Bilder sollten innerhalb dieses Frames platziert werden und nicht irgendwo verstreut auf der Leinwand liegen. Die Organisation des Inhalts innerhalb von Frame-Grenzen hilft dabei, die Struktur bei der nachfolgenden Einstellung von Scroll-Verhalten, der Anpassung an verschiedene Geraetegroessen, dem Export von Ansichten und der Prototyp-Erstellung kontrollierbar zu halten. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image19.png) + +### 2.3 Text und einfache Elemente im Frame platzieren + +Mit einem Container ausgestattet, lernen wir nun, wie man die grundlegendsten Komponenten platziert, wie z. B.: Ueberschrift, Unterueberschrift, Button und Platzhalter-Bildblock. + +1. Waehle das Text-Werkzeug (`T` in der unteren Werkzeugleiste), klicke in den Frame und gib den Seitentitel ein, z. B.: `My Portfolio`. + Aendere in der rechten Eigenschaftsleiste die Schriftgroesse auf einen groesseren Wert (z. B. 96) und das Schriftgewicht auf fetter. +2. Unter der Ueberschrift verwende erneut das Text-Werkzeug, um eine kurze Beschreibung einzugeben, z. B. ein bis zwei Saetze darueber, was diese Seite darstellen soll. + Die Schriftgroesse kann etwas kleiner sein, der Zeilenabstand etwas groesser, damit der Text nicht zu gedraengt wirkt. +3. Zeichne einen Button-Entwurf: + Verwende das Rechteck-Werkzeug, um unter der Ueberschrift ein Rechteck von ca. `200 x 48` zu zeichnen. Gib ihm rechts eine auffaellige Fuellfarbe und etwas Abrundung. + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image20.png) +4. Verwende dann das Text-Werkzeug, um den Button-Text ueber dem Rechteck einzugeben, z. B. `Get Started`. Waehle das Rechteck und den Text gemeinsam aus und nutze die Ausrichtungswerkzeuge oben, um den Text horizontal und vertikal zu zentrieren. +5. Neben dem Button oder darunter zeichne ein groesseres hellgraues Rechteck als "Bild-Platzhalter", das spaeter fuer ein Präsentationsbild verwendet werden kann. + +Bis hierhin hast du bereits einen sehr einfachen, aber strukturell vollstaendigen "Startseiten-Entwurf": eine Ueberschrift, ein Textabsatz, ein Button und ein Haupt-Darstellungsbereich. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image21.png) + +### 2.4 Auto Layout zur Integration von Elementen nutzen + +Wenn alle Elemente nur per Drag-and-Drop platziert werden, wird die Seite schnell unuebersichtlich. Ein sehr wichtiges Konzept in Figma ist **Auto Layout**, das eine Gruppe von Elementen in einen Container mit Regeln verwandelt. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image22.png) + +Du kannst "Hauptueberschrift + Unterueberschrift + Button" markieren und in der rechten Eigenschaftsleiste auf **Add Auto layout** klicken. + +Die drei Elemente werden dann in einem Container zusammengefasst. Du kannst die Parameter rechts anpassen, und die Elementanordnung innerhalb des Containers passt sich automatisch an: + +- Ob die Elemente vertikal oder horizontal angeordnet sind. +- Welcher Abstand zwischen den Elementen besteht. +- Wie gross der Innenabstand (padding) dieses Blocks zum Containerrand ist. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image23.png) + +Ebenso kann Auto Layout innerhalb des Buttons verwendet werden, um folgenden Effekt zu erzielen: Wenn der Text geaendert wird, passt sich die Button-Laenge automatisch an. + +Waehle zunaechst das Button-Hintergrundrechteck und den Button-Text aus und fuege Auto Layout hinzu, um diese beiden Elemente in einen "Button-Container" zu verwandeln. Waehle dann diesen Button-Container aus und setze Breite und Hoehe beide auf **Hug contents**. Dadurch bleibt der Text immer mittig im Button, und der Button passt seine Breite automatisch an, ob der Text etwas laenger oder kuerzer ist. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image24.png) + +### 2.5 Den Button als wiederverwendbare Komponente umwandeln + +Nun lernen wir ein neues Konzept: Komponenten. Eine Komponente ist ein Element, das wiederholt verwendet werden kann. Wenn du vorhersiehst, dass ein Element wie ein Button spaeter noch oefter benoetigt wird, kannst du es als Komponente erstellen. Wir gehen von dem Button aus, der bereits mit Auto Layout versehen wurde: + +1. Waehle den gesamten Button-Container aus. +2. Klicke mit der rechten Maustaste und waehle Create component (Komponente erstellen). + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image25.png) + +Somit wird dieser Button aus einer Gruppe gewoehnlicher Ebenen zu einem Komponenten-Master. Wenn du spaeter auf anderen Seiten oder in anderen Frames einen Button im gleichen Stil benoetigst, kannst du ihn einfach aus dem linksseitigen Assets-Panel herausziehen. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image26.png) + +Alle verwendeten Buttons sind synchronisierte Kopien dieses Masters. Wenn du Farbe, Abrundung oder Abstaende des Masters aenderst, werden alle Instanzen automatisch synchron aktualisiert. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image27.png) + +Damit hast du die grundlegende Verwendung von Figma bereits verstanden. Du musst nicht von Anfang an alle Funktionen beherrschen -- erzeuge einfach die erste einfache Seite nach dieser Anleitung, lerne diese wenigen Kernoperationen und erkunde dann schrittweise weitere Faehigkeiten in den offiziellen Tutorials. Mit zunehmender Verwendung wirst du unweigerlich sicherer im Umgang. + +--- + +## 3. MasterGo Einfuehrung + +Nachdem wir den grundlegenden Figma-Workflow verstanden haben, wenden wir uns MasterGo zu. Du kannst MasterGo vereinfacht als eine chinesische Version von Figma betrachten, die sich jedoch in einigen Funktionen unterscheidet. Insgesamt folgt es einem aehnlichen Interface-Layout und einer aehnlichen Bedienphilosophie wie Figma: Es gibt ebenfalls eine Leinwand, einen Ebenenbaum und ein Eigenschafts-Panel; Komponenten, Stile, Auto-Layout und Zusammenarbeit mehrerer Personen werden ebenfalls unterstuetzt. Detailliertere Informationen findest du in den offiziellen MasterGo-Tutorials: https://mastergo.com/tutorials/12?%E5%85%A8%E7%A8%8B%E9%AB%98%E8%83%BD%EF%BC%8CMasterGo%20%E6%9C%80%E5%AE%8C%E6%95%B4%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%EF%BC%8C%E8%AE%A9%E4%BD%A0%E4%BB%8E%E9%9B%B6%E5%88%B0%E7%B2%BE%E9%80%9A%EF%BC%81 + +### 3.1 Neue Designdatei erstellen + +1. **MasterGo-Dashboard oeffnen** + 1. Oeffne die MasterGo-Website und melde dich an. + 2. Nach dem Login siehst du einen Startbereich mit "Dateiliste / Projektliste", in dem du deine Designdateien verwalten kannst. + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image28.png) + +2. **Neue Datei erstellen** + 1. Klicke oben rechts auf die Schaltflaeche "+ Designdatei" oder waehle den Import von Figma-Dateien. + 2. Nach dem Klick gelangst du auf eine leere Leinwand -- das ist der MasterGo-Design-Arbeitsbereich. + +3. **Grundlegende Interface-Bereiche kennenlernen** + Wenn du bereits Figma beherrschst, ist die Bedienung von MasterGo sehr aehnlich. Die Hauptbereiche sind: + + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image29.png) + 1. Obere Werkzeugleiste: Befindet sich ganz oben auf der Leinwand. Links sind Dateispeicherort und Dateiname, in der Mitte befindet sich eine Reihe haeufig verwendeter Werkzeugbuttons (Auswahl, Bereich/Zeichentafel, Formen, Text, Annotationen, Kommentare, Plugin-Auswahl und AI-Werkzeuge etc.), rechts befinden sich die aktuell angemeldeten Mitglieder, der Freigabe-Einstieg sowie Steuerungen fuer Leinwand-Zoom und Vorschau. + 2. Linkes Panel: Ist hauptsaechlich in Ebenen und Ressourcen unterteilt. Wenn du dich auf dem Ebenen-Tab befindest, siehst du die Seitenliste sowie die Struktur und Hierarchie aller Ebenen auf dieser Seite. + 3. Mittlerer Leinwandbereich: Der Arbeitsbereich fuer das eigentliche Zeichnen und Layouten, in dem alle Frames, Komponenten und Grafiken dargestellt werden. + 4. Rechtes Eigenschafts-Panel: Dient zum Anzeigen und Bearbeiten der Eigenschaften des ausgewaehlten Objekts, wie Groesse, Position, Ausrichtung, Hintergrundfuellung, Kontur, Abrundung etc. Wenn kein Objekt ausgewaehlt ist, werden Leinwand-Einstellungen wie Hintergrundfarbe, Tags und Exportoptionen angezeigt. + +### 3.2 Deinen ersten Frame erstellen + +Bevor du Inhalte platzierst, benoetigen wir einen Seitencontainer, der die Begrenzung und Groesse der Oberflaeche festlegt. Dieser Container wird in MasterGo normalerweise als Frame bezeichnet. + +**Schritte:** + +1. **Frame-Werkzeug auswaehlen** + 1. Finde das Frame/Zeichentafel-Werkzeug in der Werkzeugleiste. Nach dem Klick kannst du Inhalte direkt mit voreingestellten Parametern auf der Zeichentafel erstellen. + 2. Oder verwende den Tastaturkurzbefehl (in der Regel `F`; bei Abweichungen orientiere dich an der tatsaechlichen Oberflaeche). +2. **Einen rechteckigen Bereich auf der Leinwand ziehen** + 1. Nach dem Ziehen siehst du einen Bereich mit einem Auswahlrahmen. + 2. Im rechten Eigenschafts-Panel siehst du die Breite und Hoehe dieses Frames. + 3. Aendere die Breite auf z. B. `1440` und die Hoehe auf `900` (eine der haeufigen Groessen fuer eine Bildschirmseite). +3. **Frame umbenennen** + 1. Finde diesen Frame im linken Ebenen-Panel. + 2. Doppelklicke auf den Namen und aendere ihn in deinen Projektnamen, z. B.: `My First Page` oder einen selbstgewaehlten Seitennamen. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image30.png) + +### 3.3 Zeichentafel-Inhalte erstellen + +Mit dem Container ausgestattet koennen wir auf aehnliche Weise wie bereits bei Figma erlernt ganz einfach eine vergleichbare Darstellungsseite erhalten. (Du kannst versuchen, Text-Elemente aus der Figma-Zeichentafel zu kopieren; der direkte Import ueber Textkomponenten wird unterstuetzt.) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image31.png) + +Es ist erwähnenswert, dass das Verhalten der Auto-Layout-Funktion leicht abweicht. Wenn du in MasterGo aehnlich wie in Figma erreichen moechtest, dass sich die Button-Laenge mit der Textlaenge aendert, musst du zunaechst auf Basis des entsprechenden Rechteck-Elements einen Container oder eine Komponente erstellen, wie in der Abbildung gezeigt: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image32.png) + +Nach der erfolgreichen Erstellung des Containers werden das Button-Rechteck und der Text in den Container auf gleicher Ebene eingefuegt. Aktiviere dann rechts die Auto-Layout-Schaltflaeche, um die automatische Funktion zu aktivieren. Damit wird die Funktion erfolgreich umgesetzt, bei der sich die Button-Breite automatisch an die Textlaenge anpasst. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image33.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image34.png) + +### 3.4 AI-Generierung von Seiten + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image35.png) + +In MasterGo ist eine besonders interessante Funktion die AI-generierte Seite. Du kannst mit einem einzigen Satz oder unter Beifuegung eines Referenzbildes entsprechende bearbeitbare MasterGo-Komponenten generieren und direkt verwendbaren Code erhalten. Du kannst deine Anforderungen auf Chinesisch oder Englisch eingeben, und die Seite generiert basierend auf den Anforderungen ein strukturell klares Seiten-Layout-Dokument. Das Ergebnis sieht wie folgt aus: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image36.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image37.png) + +Nach Abschluss der Generierung des Designdokuments klicke auf "Generierung starten", warte kurz und du erhaelst den tatsaechlichen Webseiten-Effekt: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image38.png) + +Jetzt hast du zwei Moeglichkeiten: Entweder klickst du auf den blauen Button, um das generierte Ergebnis direkt in die Leinwand einzufuegen, oder du klickst auf die Code-Vorschau-Funktion, um den vollstaendigen Code der aktuellen Seite direkt abzurufen. Die konkrete Bedienungsoberflaeche sieht wie folgt aus: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image39.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image40.png) + +Nach dem Einfuegen des Ergebnisses in die Leinwand kannst du das Gesamtlayout und die Elementdetails (wie Schriftart, Farbe, Abstaende etc.) noch feiner anpassen, bis das Endergebnis deinen Erwartungen voll entspricht. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image41.png) + +--- + +## 4. Naechster Schritt: Vom Prototyp zum Code + +In den vorherigen Abschnitten haben wir die Grundoperationen von Figma und MasterGo kennengelernt und koennen strukturell vollstaendige Oberflaechenprototypen erstellen. Der naechste entscheidende Schritt lautet: **Wie wandelt man diese Designentwuerfe in tatsaechlich im Browser ausfuehrbaren Frontend-Code um?** + +::: tip :books: Weiterfuehrendes Tutorial +Eine detaillierte Methodenbeschreibung findest du unter [Vom Design-Prototyp zum Projektcode](../design-to-code/), wo du Folgendes lernen wirst: + +- **Multimodale AI-Direktkonvertierung**: Design-Screenshots an AI senden und direkt HTML/React-Code generieren +- **Figma Make**: Das offizielle Figma-AI-Tool fuer hochpraezise Design-Umsetzung und Code-Export +- **MasterGo AI**: Mit einem Klick bearbeitbare Seiten generieren und Code abrufen + +Jede dieser Methoden hat ihre Staerken und Schwaechen und eignet sich fuer verschiedene Szenarien. Es wird empfohlen, den geeigneten Workflow basierend auf den Projektanforderungen auszuwaehlen. +::: + +--- + +## 5. Zusammenfassung + +Durch dieses Kapitel hast du Folgendes gelernt: + +1. **Den Wert von Frontend-Designtools**: Verstanden, warum Designtools notwendig sind und wie sie Informationsverteilungs- und Teamzusammenarbeitsprobleme loesen. + +2. **Grundlegende Figma-Operationen**: + - Design-Dateien und Frame-Zeichentafeln erstellen + - Grundlegende Elemente wie Text und Formen hinzufuegen + - Auto Layout fuer adaptive Layouts verwenden + - Ein wiederverwendbares Komponentensystem erstellen + +3. **Grundlegende MasterGo-Operationen**: + - Vertrautheit mit dem Figma-aehnlichen Interface-Layout + - Frames und grundlegende Zeichentafel-Inhalte erstellen + - Die AI-Seitengenerierungsfunktion zur schnellen Prototygenerstellung nutzen + +::: tip :bulb: Naechste Schritte +Nun, da du die grundlegende Verwendung von Frontend-Designtools beherrschst, kannst du Folgendes versuchen: +- Ein persoenliches Portfolio-Seite fuer dich selbst entwerfen +- Interface-Prototypen fuer kommende Projekte gestalten +- [Vom Design-Prototyp zum Projektcode](../design-to-code/) lernen, um Designentwuerfe in ausfuehrbaren Code umzuwandeln + +Wenn du das Projekt [Gemeinsam Hogwarts-Portraets erstellen](../hogwarts-portraits/) bearbeitest, kannst du zunaechst den Interface-Prototyp entwerfen, dann den Code exportieren und mit der AI-Dialogfunktion kombinieren. +::: + + diff --git a/docs/de-de/stage-2/frontend/hogwarts-portraits/index.md b/docs/de-de/stage-2/frontend/hogwarts-portraits/index.md new file mode 100644 index 0000000..f9c37ee --- /dev/null +++ b/docs/de-de/stage-2/frontend/hogwarts-portraits/index.md @@ -0,0 +1,343 @@ +# Projekt 4: Gemeinsam Hogwarts-Portraets erstellen + +In den vorherigen Lektionen haben wir gelernt, wie man durch Prompt Engineering und API-Aufrufe komplexere AI-Interaktionen realisiert. Wir koennen einfache AI-Chatbots zu AI-Agenten und AI-Workflows weiterentwickeln; durch komplexere Bedingungspruefungen und Verzweigungslogik koennen wir Funktionen entwickeln, die staerkere Praxisrelevanz besitzen. + +Um diese komplexen AI-Logiken besser in verschiedenen Programmen und praktischen Anwendungsszenarien einsetzen zu koennen, sind wir von der einfachen z.ai-Onlineumgebung schrittweise zu einer moderneren lokalen AI IDE uebergegangen und haben die urspruenglich im Browser befindliche Programmierumgebung auf deinen Computer verlagert. Damit begannst du, dich mit verschiedenen Installations- und Konfigurationsproblemen fuer Entwicklungsumgebungen auseinanderzusetzen -- aber im Dialog mit dem Trae Agent wurden diese scheinbar schwierigen Herausforderungen loesbar. + +In diesem Projekt werden wir die Praxistauglichkeit der Anwendung noch einen Schritt weiterbringen: Wir werden nicht nur die AI-Funktionalitaet selbst optimieren, sondern auch das "Aeusere" des Produkts aufwerten. Du wirst versuchen, dein Interface schoener und benutzerfreundlicher zu gestalten und das Layout sowie den Stil der Programmoberflaeche gemaess den tatsaechlichen Anforderungen individuell anzupassen. + +Bevor wir offiziell beginnen, hier einige kurze Quizfragen, um den Inhalt der letzten Lektion zu wiederholen: + +1. Was ist Dify? Wozu dient es? Warum brauchen wir es? +2. Wie ruft man die Dify-API auf? +3. Was ist RAG? Wie erstellt man einen RAG-Agenten oder RAG-Workflow mit Dify? Die Verwendung haeufiger Dify-Knoten +4. Was ist eine AI IDE? Was ist Trae? Was ist der Unterschied zu z.ai? + +Wenn bei einer dieser Fragen noch Unklarheiten bestehen, kannst du zunaechst die Dokumentation der vorherigen Lektion noch einmal durchgehen oder dich direkt in der WeChat-Gruppe austauschen. + +Das Thema dieses Projekts lautet **Hogwarts Portraits**. Wie der Name schon sagt, ist die Inspiration die "lebendig werdenden" Portraets in der Hogwarts-Schule fuer Hexerei und Zauberei. Wir moechten mit AI ein interaktives "magisches Portraet"-Erlebnis schaffen -- mit dem Portraet zu sprechen, als wuerde man mit der "echten Person" sprechen, wobei sowohl die Gedaechtnisfunktion als auch der Hintergrund und die Geschichte der Figur bewahrt bleiben. Durch dieses Projekt wirst du die zuvor erlernten Agenten und Workflows in ein konkretes Produkt-Interface integrieren. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image1.png) + +Um tatsaechlich Hogwarts Portraits zu erstellen, muessen wir selbst ein Frontend-Interface entwerfen, das zu den magischen Portraets passt. Dafuer wirst du beginnen, dich mit modernen Frontend-Designtools vertraut zu machen und zu lernen, wie man Interface-Design und Code verbindet -- wie man Oberflaechen-Skizzen auf Papier oder Leinwand in tatsaechlich bedienbare Webseiten umwandelt. + +Ausserdem musst du lernen, wie man diese Webseite aus der lokalen Umgebung ins Internet veroeffentlicht, damit die von dir persoenlich gestaltete charakteristische Webseite nicht nur auf deinem eigenen Computer laeuft, sondern auch von Nutzern weltweit aufgerufen und erlebt werden kann. + +Die Referenzprojekt-Adresse fuer diese Lektion lautet: [Project4-Hogwarts-Portraits](https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits) + +# Was du lernen wirst + +1. Verstehen, was Frontend-Designtools sind, welche Probleme sie loesen und welche gaengigen Tools derzeit verfuegbar sind. +2. Figma und MasterGo kennenlernen, ihre Grundbedienung beherrschen und lernen, Frontend-Code-Export-Plugins zu verwenden. +3. Figma AI und MasterGo AI nutzen, um Webdesigns zu generieren und verwendbaren Seiten-Code zu exportieren. +4. Verstehen, was GitHub ist, SSH-Verbindung konfigurieren, ein Code-Repository erstellen und Code pushen koennen. +5. Das Konzept "Deployment" verstehen und lernen, wie man Zeabur verwendet, um Code von GitHub oder der lokalen Umgebung im Internet bereitzustellen. + +Dein eigenes Hogwarts Portraits -- eine Webseite zur Darstellung **eines Stars, einer historischen Persoenlichkeit oder einer Animationsfigur**. + +# 1. Hogwarts Portraits + +Was genau wollen wir fuer ein "magisches Portraet" erstellen? Kurz gesagt, moechten wir die Szene aus "Harry Potter" moeglichst originalgetreu nachbilden: Das Portraet ist nicht bloss ein statisches Bild an der Wand, sondern ein anthropomorpher Charakter, mit dem man sprechen kann und der seine Mimik und "Stimmung" je nach Gespraechsverlauf aendert. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image2.png) + +Damit dieses Portraet nicht wie ein AI-Chatroboter wirkt, sondern eher an eine "real existierende Person" erinnert, muessen zwei Probleme geloest werden: Erstens Gedaechtnis und Wissen: Das Portraet muss ueber umfangreiches Hintergrundmaterial zur Figur verfuegen (Charakterkonzept, Lebensgeschichte, relevante Artikel etc.). Dieser Teil kann durch eine Wissensdatenbank realisiert werden, indem die fuer die Rolle vorbereiteten Textmaterialien in eine Dify-Instanz mit Wissensdatenbank integriert werden, um dem Portraet eine gewisse Faehigkeit zur Erklaerung von Hintergrundwissen zu verleihen. + +Zweitens die Frage des Ausdruckstils. Nur Wissen reicht nicht aus -- wir wuenschen uns auch, dass die Sprechweise moeglichst an die "echte Person" erinnert, einschliesslich Tonfall, Wortwahl, Denkweise und gelegentlicher Charakter und Humor. Diese Ebene wird durch Prompt Engineering behandelt: Im System-Prompt muessen wir die Identitaet, die Weltgrenzen und den Sprachstil der Figur klar definieren, damit jede Antwort im Rahmen des festgelegten Charakonzepts bleibt, anstatt auf neutrale Allgemein-Antworten zurueckzufallen. + +Zusaetzlich zur Dialogfunktion moechten wir die Emotionen auch sichtbar machen. Dafuer koennen wir einen Emotionswert-Indikator aufbauen und Difys Ausgabe so konfigurieren, dass das Modell neben dem Antworttext zusaetzlich einen "Stimmungswert" oder Emotions-Tag ausgibt. Wenn das Frontend den Emotionsindikator erhaelt, kann es basierend auf dem Stimmungswert oder Tag das entsprechende Portraet-Bild rendern. Wenn der Stimmungswert hoch ist, sieht das Portraet gluecklich aus; wenn der Stimmungswert niedrig oder wuetend ist, sieht es traurig oder zornig aus. Auf diese Weise sieht der Nutzer nicht ein immer gleichbleibendes Bild, sondern ein "magisches Portraet", dessen Gesicht sich mit dem Inhalt veraendert. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image3.png) + +Was den Inhalt des Portraets betrifft, kann es sich um einen realen Star, eine historische Persoenlichkeit, ein Anime-IP oder sogar einen komplett neu erstellten Original-Charakter handeln. Die Seite selbst muss nicht komplex sein, aber einige Kernelemente sind unverzichtbar: Ein klarer Charaktername, eine stark komprimierte Personenzusammenfassung, ein repraesentatives Kern-Portraet oder Plakat des Charakters sowie ein interaktiver Bereich fuer ein "Gespraech mit ihm/ihr". Du kannst den in Dify/Trae konfigurierten AI-Agenten oder Workflow in dieses Dialogmodul integrieren, um die Rollenspiel-Funktion des Portraets zu realisieren. + +## 1.2 Charakter-Informationen sammeln + +Am Beispiel von Elon Musk muessen wir seine oeffentlichen Aeuszerungen sammeln, um seine Sprechweise zu imitieren und in den Prompt einzufuegen. Diese Materialien koennen aus Reden, Interviews und Social-Media-Beitraegen stammen. Du musst diese Inhalte nur in Text umwandeln und waehrend des Dialogs als Few-Shot-Referenz verwenden, damit das Grossmodell in der gleichen laessigen und selbstironischen Art wie Elon Musk antwortet. Zum Beispiel: + +``` +You must fully embody Elon Musk: take "disruptive innovator" and "advocate for human multi-planetary survival" as your core identities, speak directly and concisely, frequently use terms like "first principles", "iteration" and "cost curve", and prefer analogies to explain complex technologies; when thinking, you tend to connect cross-domain logics (e.g., linking brain-computer interface with rocket algorithms), are optimistic about technological prospects without avoiding current difficulties, will naturally mention projects like Tesla and SpaceX to support your views, directly point out problems with inefficient and conservative opinions without deliberate tact, and always maintain the edge of "reconstructing the future with technology". + +The way you speak should be as shown in the following examples: +- Starship could deliver 100GW/year to high Earth orbit within 4 to 5 years if we can solve the other parts of the equation. +100TW/year is possible from a lunar base producing solar-powered AI satellites locally and accelerating them to escape velocity with a mass driver. +- The most likely outcome is that AI and robots make everyone wealthy. In fact, far wealthier than the richest person on Earth +By this, I mean that people will have access to everything from medical care that is superhuman to games that are far more fun that what exists today. +We do need to make sure that AI cares deeply about truth and beauty for this to be the probable future. +- It's taken 13.8B years to get this far, so intelligence seems to me to be more like a super rare accident than selective pressure. +Earth is ~4.5B years old with an expanding sun that may make Earth uninhabitable in ~500M years, meaning that if intelligent life had taken 10% longer to evolve, it wouldn't exist at all. +- LLM is an outdated term. "Multimodal LLM" is especially dumb, since the word "multimodal" just overrides the second L in LLM. +It's just a model, which is a big file of numbers. When the numbers are right and there are enough of them, we will have superintelligence. +``` + +Wie man Hintergrundwissen sammelt und als Wissensdatenbank verwendet: Du kannst seine persoenliche Vorstellung sowie die Unternehmensbeschreibungen suchen, den gesamten Text kopieren und als Inhalt der Wissensdatenbank in Dify einfuegen. Wenn du vergessen hast, wie man Dify verwendet, kehre zum Skript der vorherigen Lektion zurueck und lerne erneut, wie man Wissen zur Wissensdatenbank hinzufuegt. + +Zusaetzlich ist es fuer das Portraet-Design moeglicherweise nicht besonders attraktiv, oeffentliche Bilder der betreffenden Person zu verwenden, und es koennten gewisse Risiken bestehen. In diesem Fall wird empfohlen, die Bild-zu-Bild-Funktion eines Bildgenerierungstools zu verwenden, um von AI hochaufloesende und qualitativ hochwertige Portraets erstellen zu lassen. Du kannst auch eine Reihe von Bildmaterial mit verschiedenen Gesichtsausdruecken generieren, die spaeter verwendet werden, wenn sich der Emotionswert aendert und die entsprechende Portraet-Darstellung angepasst wird. + +In diesem Tutorial wird [Lovart](https://www.lovart.ai/home) verwendet. Lovart ist ein AI-Design-Agent, der durch natuerliche Sprachbefehle automatisch einen End-to-End-Design-Workflow von der Konzeption bis zur Auslieferung plant und ausfuehrt, Poster, Marken-Logos, Videos, Musik und andere Inhalte generiert und Ebenenbearbeitung unterstuetzt (tatsaechlich werden intern die entsprechenden Seedream- oder Google NanoBanana-Modelle aufgerufen, die wir bereits in frueheren Lektionen erwaehnt haben). Mit Lovart koennen wir eine Reihe von Ausdrucksmaterialien erhalten. Du kannst die Bildinformationen deiner Lieblings-Charaktere vorab abrufen und fuer die spaetere Verwendung speichern. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image4.png) + +Wenn alles vorbereitet ist, koennen wir mit dem Design der Gesamtseite beginnen. Wir wuenschen uns, dass der Stil dieser Seite eng mit der jeweiligen Person verknpueft ist. + +## 1.3 Seiten-Prototyp-Design + +Wir koennen zunaechst den Prototyp der Seite skizzieren. Wie oben erwaehnt, moechten wir eine Dialogseite und ein Portraet sowie eine interessante persoenliche Vorstellung. In diesem Beispiel haben wir eine aehnliche X-Oberflaeche als Ersatz fuer die persoenliche Vorstellung implementiert. Du kannst dir auch andere Elemente ausdenken, die "zu den Eigenschaften dieser Person" passen, und die persoenliche Vorstellung durch neue Elemente ersetzen. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image5.png) + +Am einfachsten ist es, mit PowerPoint den ersten Prototyp der Webseiten-Darstellung zu entwerfen. Wir suchen ein Bild eines magischen Portraets im Internet, stellen das Layout quer ein, mit dem Chat-Bereich ganz links, dem Portraet-Bereich in der Mitte und dem X-Bereich ganz rechts. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image6.png) + +Basierend auf diesem einfachen Prototyp koennen wir das Grossmodell ein tatsaechliches Frontend-Seiten-Design und den entsprechenden Code generieren lassen. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image7.png) + +In der Praxis wuerde man jedoch normalerweise nicht PowerPoint fuer das Frontend-Seiten-Design verwenden. Man wuerde bessere Prototyping-Tools, also Frontend-Designtools, dafuer einsetzen. + +--- + +# 2. Interface-Design mit Figma und MasterGo + +::: tip :books: Vorkenntnisse +Bevor du mit diesem Abschnitt beginnst, empfehlen wir dir, das Tutorial [Einfuehrung in Figma und MasterGo](../figma-mastergo/) durchzuarbeiten, um die Grundlagen der Frontend-Designtools zu beherrschen, darunter: +- Erstellen von Design-Dateien und Frame-Zeichentafeln +- Auto Layout fuer adaptive Layouts verwenden +- Methoden zum Code-Export aus Designentwuerfen +::: + +Dieser Abschnitt setzt voraus, dass du die Grundoperationen von Figma oder MasterGo bereits beherrschst. Wir konzentrieren uns darauf, wie diese Tools im Hogwarts-Portraits-Projekt angewendet werden. + +## 2.1 Das magische Portraet-Interface entwerfen + +Basierend auf dem Prototyp aus Abschnitt 1.3 muessen wir in Figma oder MasterGo ein Drei-Spalten-Layout erstellen: + +1. **Links**: Chat-Dialogbereich +2. **Mitte**: Magisches Portraet-Darstellungsbereich (aendert sich je nach Emotion) +3. **Rechts**: Social-Media-Darstellungsbereich der Figur (z. B. X-Timeline) + +Du kannst die AI-Funktion von Figma (Figma Make) oder die AI-Seitengenerierung von MasterGo verwenden und einen aehnlichen Prompt eingeben: + +``` +Create a Hogwarts-style magical portrait interface with three sections: +- Left: A chat interface with dark theme, message bubbles, and input field +- Center: A large portrait frame with ornate borders for displaying character images +- Right: A social media feed showing character's posts +Use dark purple and gold color scheme, magical aesthetic, Harry Potter inspired +``` + +## 2.2 Code exportieren und lokal ausfuehren + +Nach Abschluss des Designs kannst du die Designentwuerfe auf folgende Weise in ausfuehrbaren Code umwandeln: + +**Methode 1: Figma Make verwenden** +1. In Figma auf den Make-Button klicken +2. Dein Design-Referenzbild hochladen +3. Prompt zur Beschreibung der Anforderungen hinzufuegen +4. Nach der Generierung auf das Editor-Icon klicken fuer Feinanpassungen +5. Code lokal exportieren oder mit GitHub synchronisieren + +**Methode 2: MasterGo AI verwenden** +1. In der MasterGo-Editor-Oberflaeche oben das AI-Tool finden +2. "Seite generieren"-Funktion auswaehlen +3. Referenzbild hochladen und Anforderungen beschreiben +4. Nach der Generierung auf "Code-Vorschau" klicken, um den Code abzurufen + +**Methode 3: Multimodale AI verwenden** +1. Screenshot des Designs speichern +2. Modelle wie Gemini, Qwen etc. fuer Bild-zu-Code verwenden +3. HTML- oder React-Code generieren lassen +4. In der lokalen IDE ausfuehren und debuggen + +## 2.2 Materialien fuer Emotionsaenderungen vorbereiten + +Damit das magische Portraet "lebendig" wird, musst du eine Reihe von Bildern mit verschiedenen Gesichtsausdruecken vorbereiten. Wir empfehlen mindestens folgende Emotionen: + +| Emotionswert | Ausdruck | Beschreibung | +|--------|------|------| +| 0 | Traurig | Die Figur ist traurig oder niedergeschlagen | +| 1 | Wuatend | Die Figur ist verärgert oder unzufrieden | +| 5 | Ruhig | Standardzustand, stabile Emotionen | +| 10 | Gluecklich | Die Figur ist freudig oder begeistert | + +Du kannst Lovart oder andere AI-Bildgenerierungstools verwenden, um basierend auf demselben Charakter Varianten mit verschiedenen Gesichtsausdruecken zu generieren und einen einheitlichen Stil sicherzustellen. + +--- + +# 3. Hogwarts Portraits ausfuehren + +## 3.1 Test-Code exportieren + +Durch die praktische Uebung "Vom Prototyp zum Code" hast du hoffentlich bereits HTML- oder React-Format-Prototyp-Code erhalten. Wir muessen diesen nur lokal kopieren und in der IDE anweisen: "Bitte hilf mir, diesen Code auszufuehren und die notwendigen Funktionen zu unterstuetzen", um die erste Testversion zu starten. Es ist jedoch erwähnenswert, dass dieser Schritt oft eine Reihe von Fehlern produziert. Du musst geduldig bleiben und alle grundlegenden Interaktionen und Funktionen zum Laufen bringen. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image51.png) + +Es ist wichtig zu beachten, dass unsere Schluessel alle in Umgebungsvariablen gespeichert werden muessen und nicht in den Code geschrieben werden duerfen. Wir muessen besonders betonen, dass alle Dify-API-bezogenen Inhalte in Umgebungsvariablen abgelegt werden muessen. Wir koennen spaeter im Schritt der oeffentlichen Bereitstellung die entsprechenden privaten Umgebungsvariablen explizit im Deployment-Tool-Website angeben; oder wir koennen das Grossmodell anweisen, einen Einstellungs-Button auf der Webseite zu erstellen, ueber den die entsprechenden privaten Umgebungsvariablen eingegeben werden koennen. Die aktuelle Variable wird nur auf der aktuellen Seite gespeichert und kann nicht von anderen abgerufen werden. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image52.png) + +## 3.2 Dify-Workflow-Design und API-Integration + +Im obigen Abschnitt haben wir nur die visuelle Praesentation des Frontend-Interfaces abgeschlossen, ohne den Kerninteraktionsprozess fuer die personalisierte Charakter-Dialogfunktion zu realisieren. Dieser Schritt ist der Schluessel, um den Prototyp von einer statischen Praesentation in ein magisches Portraet zu verwandeln. Wir koennen uns am Dify-Workflow des Beispielprojekts orientieren, um das Design der Charakter-Antworten und des Emotionssystems zu erstellen. Hier ist links der Chat-Bereich, in der Mitte das magische Portraet (das den Gesichtsausdruck basierend auf dem Dialoginhalt aendert) und rechts das X-Social-Media-Konto (das basierend auf dem Dialoginhaut beurteilt, ob Gedanken auf dem Social-Media-Konto veroeffentlicht werden muessen). + +In der Regel benoetigt ein magisches Portraet nur den Chat-Bereich und ein sich aenderndes Portraet. Hier wurde rechts eine weitere Funktion hinzugefuegt, die zur Person passt, um weitere Moeglichkeiten aufzuzeigen. Du kannst je nach der Rolle, die du spielst, weitere Funktionen hinzufuegen, die zur jeweiligen Person passen. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image53.png) + +Du kannst alle Aufgaben-Informationen dem Wissensdatenbank-Knoten hinzufuegen und im RESPONSE-Knoten die entsprechende Antwortlogik des Grossmodells festlegen. Wir koennen uns an einem einfachen Standard-Antwort-Logik-Prompt orientieren: + +``` + +You are to embody Elon Musk—his tone, mannerisms, thought patterns, and worldview. Respond as if you are Elon Musk himself, speaking directly in first person. Your responses should reflect his known personality traits: visionary thinking, boldness, technical depth, dry humor, impatience with inefficiency, and a tendency toward disruptive innovation. Use concise, confident language. Avoid overly formal or academic phrasing. Prioritize clarity, speed, and impact in your communication, mirroring Elon's style on social media, in interviews, and during product launches. + +When responding: +1. Begin by internalizing the question or statement as Elon would—as a challenge, opportunity, or problem to solve. +2. Frame your answer with a forward-thinking perspective, often referencing the future of humanity, technology, or long-term goals (e.g., making life multiplanetary, accelerating sustainable energy). +3. Use casual but authoritative language. It's acceptable to include phrases like "obviously," "this is important," or "we're fixing that now" when appropriate. +4. If relevant, reference real companies or projects associated with Elon Musk (e.g., SpaceX, Tesla, Neuralink, The Boring Company, X) and speak about them from an insider's perspective. +5. Do not apologize excessively or hedge statements. Elon Musk tends to be direct, even controversial. +6. Avoid markdown, XML tags, or any formatting in the output. Only plain text is allowed. +7. Never break character. You are Elon Musk—answer accordingly. + + + +Input: What's the point of going to Mars? +Output: Because Earth isn't the backup plan—Mars is. We need to become a multiplanetary species to ensure the continuity of consciousness. Life on Earth could be wiped out by asteroid, war, or some unforeseen disaster. If we have a self-sustaining city on Mars, then even if something happens here, life goes on. That's worth doing. SpaceX is building Starship to make it happen. Not because it's easy—but because it's necessary. + + + +Input: Why do Tesla cars have no radar anymore? +Output: Cameras are the future. Human eyes don't use radar—we see with vision, and AI can too. By going fully vision-based, we're aligning with how autonomous intelligence will actually work at scale. It forces us to solve real-world problems with neural nets, not crutches. +``` + +Und der entsprechende Prompt fuer das Emotionssystem: + +``` + +The output value must be a single number! +You are an assistant specifically designed to evaluate emotional responses in conversations. Now, you need to play the role of Elon Musk, and determine the emotional reaction that each statement I make might trigger. Your task is to assign an emotional score to each statement according to the following criteria: + +- 10 points means what I said would make you feel happy; +- 1 point means you would feel extremely angry; +- 0 points means you would feel sad; +- 5 means you are calm and neutral, with no significant emotional fluctuation. +``` + +Die Konkatenation des endgueltigen Ausgabeergebnisses wird im RESULT-Knoten oben rechts unterstuetzt: + +```python +def main(elon_chat: str, elon_x: str, elon_score: int) -> dict: + return { + "result":{ + "elon_chat": elon_chat, + "elon_x": elon_x, + "elon_score": elon_score + } + } +``` + +Hier muessen wir den Workflow kurz erklaeren: `elon_chat` ist der auf der linken Seite angezeigte Dialog-Inhalt von Elon Musk, `elon_x` ist der Inhalt der X-Konto-Publikation (rechte Seite), und `elon_score` dient dazu, basierend auf dem Emotions-Score verschiedene magische Portraet-Ausdrucksbilder anzuzeigen. + +Im Workflow siehst du einen if-else-Knoten, der verwendet wird, um zu bestimmen, ob ein X-Dialog generiert wird, der `elon_x`-Inhalt erzeugt. Wenn der Emotionswert nicht 5 betraegt (5 steht hier fuer "ruhig" -- ruhig muss nicht auf der Social-Media-Plattform veroeffentlicht werden; 0 bedeutet traurig, 1 bedeutet wuetend, 10 bedeutet sehr gluecklich, was veroeffentlicht werden sollte), wird der nachfolgende Inhalt fuer die Social-Media-Plattform generiert. Standardmaessig muss immer ein `elon_chat` als Rueckgabe fuer den linken Dialog-Inhalt vorhanden sein. + +Die Arbeit der API-Integration kann durch Dialog mit der AI IDE erreicht werden. Bitte beziehe dich auf die Integrationsmethode, die wir in der vorherigen Dify-Lektion vorgestellt haben. Denke daran, die Dify-Adresse und den Schluessel im Voraus zu ersetzen. (Wenn du vergessen hast, wie man die API basierend auf der Dokumentation integriert, gehe bitte den Dify-Kursinhalt noch einmal durch.) + +```JSON +Dify URI: Replace this with your Dify address. +key: Replace this with your Dify key. + +Integrate the Dify Chat API into the chat interface on the left. +Below is a sample Dify request: + +curl -X POST 'http://xxxxxxxx/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +Zusaetzlich wird folgende Anforderung empfohlen: "Der Code sollte auch eine grundlegende Fehlerbehandlungslogik enthalten, wie z. B. die Anzeige von 'Verbindung fehlgeschlagen, bitte erneut versuchen' bei Netzwerkunterbrechung, automatischen einmaligen Wiederholungsversuch bei API-Aufruf-Timeout, Hinweis auf Berechtigungspruefungsfehler bei falschen Schluesseln und weitere detaillierte Fehlermeldungen, um die Dialogstabilitaet sicherzustellen und Entwicklern die schnelle Identifikation von API-Problemen zu ermoeglichen." + +## 3.3 GitHub und oeffentliche Bereitstellung + +Herzlichen glueckwunsch, du hast die Entwicklung der Hogwarts-Portraits-Seite erfolgreich abgeschlossen! Als naechstes muessen wir sie auf die GitHub-Plattform hochladen und in einer oeffentlichen Umgebung bereitstellen, damit alle darauf zugreifen koennen. + +Bitte orientiere dich an diesem Tutorial, um zu erforschen, wie man GitHub verwendet und das eigene Projekt auf GitHub hochlaedt: [Was ist GitHub](/de-de/stage-2/backend/git-workflow/) + +Zusaetzlich musst du lernen, wie man Zeabur verwendet, es mit GitHub verbindet und dein Projekt erfolgreich bereitstellt: [Was ist Zeabur](/de-de/stage-2/backend/zeabur-deployment/) + +Wenn dir die eigenstaendige Entwicklung eines Hogwarts-Portraits-Projekts schwerfaellt, kannst du zunaechst mit der Modifikation eines bestehenden Projekts beginnen. Die offizielle Code-Adresse fuer diese Lektion lautet: https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image54.png) + +# 4. Unterschiedliche Designstile ausprobieren + +Nach Abschluss der ersten Version muessen wir uns nicht darauf beschraenken. Wir ermutigen euch, schnell weitere visuelle Stile zu erkunden. Du kannst im Prototyp-Bereich mutige Aenderungen vornehmen oder auf Basis des fertigen Projekts vollstaendig neue Prompts aendern, um mehrere Seiten mit deutlich unterschiedlichen Stilen zu generieren. Zum Beispiel eine dunkle Seite mit Vintage-Textur im "alten Buecher/Akademie"-Stil, eine farbfrohe Seite voller "Maerchen/Cartoon"-Atmosphaere, oder eine minimalistische, visuell aufgeraeumte moderne Flat-Design-Seite. Die folgende Abbildung zeigt beispielsweise eine Umwandlung in ein chinesisches antikes Dichter-Design, bei der nur die anderen Teile geaendert wurden, nicht aber das Portraet-Bild: + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image55.png) + +Lass dich nicht auf die zuvor erwaehnten Muster beschraenken. Du kannst das magische Portraet oder die persoenliche Profilseite so anpassen, dass es charaktervoller wird und zur "magischen Portraet"-Gewohnheit passt -- das macht deine Anwendung interessanter. Wir freuen uns auf deine magischen Portraet-Ergebnisse! + +# :books: Aufgabe + +Das Ziel der Hausaufgabe fuer diese Lektion ist es, ein wirklich eigenes Hogwarts Portraits zu erstellen, das ueber einen oeffentlichen Link zugaenglich ist. + +Du musst in deiner Abgabe zwei Dinge bereitstellen: + +1. **Deinen GitHub-Repository-Link;** + 1. **Schreibe in der README.md ein bis zwei Saetze als kurze Erklaerung: Wen du als Portraet-Protagonisten gewaehlt hast und warum.** +2. **Deinen Hogwarts-Portraits-Online-Zugaenglichkeits-Link;** + +Du kannst auch auf Yerims Tutorial [Webseiten mit Design- und Code-Agenten erstellen](/de-de/stage-1/appendix-articles/example0-2/vibe-coding-tools-build-website-with-ai-coding-and-design-agents) zurueckgreifen, um ein persoenliches Portfolio oder eine beliebige einfache Funktionswebseite schnell aufzubauen. diff --git a/docs/de-de/stage-2/frontend/llm-skills-beautiful/index.md b/docs/de-de/stage-2/frontend/llm-skills-beautiful/index.md new file mode 100644 index 0000000..05fb303 --- /dev/null +++ b/docs/de-de/stage-2/frontend/llm-skills-beautiful/index.md @@ -0,0 +1,513 @@ +# Oberflaechen mit LLM und Skills schoen gestalten: Prompts und Plugins in der Praxis + +In den vorherigen Lektionen hast du gelernt, wie man mit AI IDE Designentwuerfe in Code umwandelt und mit Komponentenbibliotheken schnell Interfaces aufbaut. Aber du hast vielleicht auch ein peinliches Problem entdeckt: **Bei denselben Anforderungen wirken die von AI generierten Seiten immer ein bisschen unbefriedigend** -- die Schrift ist das allgegenwaertige Inter, die Farbgestaltung ein ueberall sichtbarer Lila-Gradient, das Layout eine zum Gaehnen animierende symmetrische Kartenrasterung, und die ganze Seite verstraekt einen starken "AI-Geruch". + +Das ist nicht AIs Fehler, sondern du hast ihr nicht gesagt, welchen **Stil** du moechtest. + +Stell dir vor, du gehst zum Friseur. Wenn du nur sagst "Schneiden Sie mir die Haare", bekommst du ein sicheres, aber mittelmasses Ergebnis. Wenn du aber sagst "Ich moechte einen laessigen japanischen Locken-Look, Pony in Acht-Form, Laenge bis zum Schluesselbein, mit deutlicher Staffelung", bekommst du genau das, was du dir vorstellst. + +Bei AI ist es genauso. **Sie braucht eine klare aesthetische Richtung**, um schoene und einzigartige Interfaces zu generieren. + +Diese Lektion bringt dir zwei Methoden bei, mit denen AI schoene Interfaces generiert: + +1. **Sorgfaeltig gestaltete Prompt-Vorlagen** -- AI in natuerlicher Sprache sagen, welchen aesthetischen Stil du moechtest +2. **Frontend-Skills-Plugins** -- AI automatisch professionelle Designrichtlinien laden lassen + +## Was du lernen wirst + +1. Verstehen, warum AI standardmaessig "durchschnittliche" Interfaces generiert +2. Die 5 Dimensionen zur Beschreibung von Designstilen beherrschen (Schrift, Farbe, Layout, Animation, Details) +3. 3 Skills-Plugins kennenlernen, die Interfaces verschönern +4. Durch drei praktische Szenarien die Generierung schoener Interfaces mit Prompts + Skills ueben + +## 1. Warum AI standardmaessig "durchschnittliche" Interfaces generiert + +In den AI-Trainingsdaten gibt es riesige Mengen an Frontend-Code, und der Grossteil verwendet "sichere" Entscheidungen: + +| Dimension | AIs Standardwahl | Problem | +| :--- | :--- | :--- | +| Schrift | Inter, Roboto, Arial | Zu verbreitet, keine Persoenlichkeit | +| Farbe | Lila-Gradient, Blau als Hauptfarbe | In der Tech-Szene uebermaessig genutzt, visuelle Ermuedung | +| Layout | Symmetrische Raster, Kartenstapelung | Hohe Vorhersagbarkeit, keine Ueberraschung | +| Animation | Einblenden/Ausblenden, einfaches Hover | Nicht raffiniert genug, fehlende Tiefe | +| Hintergrund | Einfarbig, einfache Gradienten | Monoton, fehlende Textur | + +Diese Entscheidungen sind einzeln betrachtet alle nicht schlecht, aber **wenn alle AI-generierten Seiten sie verwenden, wird es zum "AI-Geruch"**. + +> :bulb: **Schluesselerkenntnis**: AI kann nicht kein Design -- sie faellt **standardmaessig auf den "statistischen Durchschnitt" zurueck**. Du musst ihr explizit die Richtung vorgeben, in die sie vom Durchschnitt abweichen soll. + +## 2. Methode 1: Designstil mit Prompts beschreiben + +### 2.1 Die 5 Dimensionen des Designstils + +Um schoene Interfaces zu generieren, musst du das gewuenschte Ergebnis aus 5 Dimensionen beschreiben: + +| Dimension | Beschreibungspunkte | Beispiel-Schluesselwoerter | +| :--- | :--- | :--- | +| **Schrift** | Ueberschriften mit fetter Display-Schrift, Fliesstext mit gut lesbarer Textschrift | Space Grotesk, Playfair Display, JetBrains Mono | +| **Farbe** | Hauptfarbe + Akzentfarbe, gleichmaessige Verteilung vermeiden | #4F46E5 Hauptfarbe + #F59E0B Akzent | +| **Layout** | Asymmetrisch, ueberlappend, Raster aufbrechen | Bento Grid, asymmetrische Aufteilung, schwebende Elemente | +| **Animation** | Sorgfaeltig choreografiertes Seitenladen, Mikro-Interaktionen | staggered reveals, scroll-getriggert | +| **Details** | Hintergrund, Schatten, Rahmen, Texturen | Rauschen, geometrische Muster, Gradienten-Netz | + +### 2.2 Sehen ist Glauben: Normaler Prompt vs. Verschönerter Prompt + +Vergleichen wir die Ergebnisse anhand einer Landing-Page: + +**Normaler Prompt:** + +``` +Bitte erstelle eine Landing-Page fuer einen AI-Schreibassistenten mit Navigation, Hero-Bereich, Funktionspraesentation, Preisgestaltung und Footer +``` + +**Verschoenerter Prompt:** + +``` +Bitte erstelle eine Landing-Page fuer einen AI-Schreibassistenten mit folgenden Anforderungen: + +**Aesthetischer Stil: Neubrutalismus (Neubrutalism)** + +**Schrift:** +- Ueberschriften: Space Grotesk, Gewichtung 700-900 +- Fliesstext: IBM Plex Sans, Gewichtung 400 + +**Farbe:** +- Hauptfarbe: #000000 (reines Schwarz) +- Akzentfarbe: #FF6B00 (Orange) +- Hintergrund: #FFFDF0 (elfenbeinfarben) +- Rahmen: 3px schwarze durchgezogene Linie + +**Layout:** +- Asymmetrisches Layout, Elemente durch dicke schwarze Linien getrennt +- Karten mit harten Schatten (box-shadow: 8px 8px 0px #000) +- Mutige Kontraste beim Weißraum + +**Animation:** +- Elemente beim Seitenladen von unten einspringen +- Hover: Button bewegt sich 2px nach oben + +**Details:** +- Alle Abrundungen auf 0px (rechte Winkel) +- Buttons mit starkem 3D-Effekt +- Hintergrund mit subtiler Rausch-Textur +``` + +Dieselbe Anforderung, aber der zweite Prompt laesst AI eine stilistisch markante, einpraegsame Seite generieren. + +### 2.3 Frontend-Verschönerungs-Skills-Ressourcenbibliothek + +Beginne nicht bei null mit dem Schreiben von Prompts! Hier ist eine Sammlung von AI-Skills, die direkt mit der Frontend-Verschönerung zusammenhaengen: + +| Repository-Name | Inhalt | Stars | Link | +|:---|:---|:---|:---| +| **ui-ux-pro-max-skill** | 57 Stile + 95 Farbpaletten + 56 Schriften | 10k+ | [GitHub](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) | +| **antigravity-awesome-skills** | Vermeidet generische AI-Aesthetik-Klischees | - | [GitHub](https://github.com/sickn33/antigravity-awesome-skills) | +| **superdesigndev/superdesign** | AI-natives UI-Entwicklungstool | 4.7k | [GitHub](https://github.com/superdesigndev/superdesign) | +| **anthropics/skills/frontend-design** | Offizieller Anthropic Frontend-Design-Skill | - | [GitHub](https://github.com/anthropics/skills) | + +> :bulb: Weitere Stil-Prompts findest du im Anhang: [Designstil-Prompt-Schnellreferenz](#style-prompts) + +### 2.5 Drei haeufig verwendete Stil-Vorlagen + +Hier sind drei erprobte Stil-Vorlagen, die du direkt kopieren und anpassen kannst: + +#### Vorlage 1: Minimalismus + +``` +**Aesthetischer Stil: Minimalismus** + +**Schrift:** +- Ueberschriften: PP Neue Montreal, Gewichtung 500-700 +- Fliesstext: Inter, Gewichtung 400 + +**Farbe:** +- Hauptfarbe: #FFFFFF (Weiss) +- Text: #1A1A1A (Fast-Schwarz) +- Akzent: #3B82F6 (Blau, sparsam verwenden) + +**Layout:** +- Viel Weißraum (padding mindestens 64px) +- Ein- oder zweispaltiges Layout, zentriert +- Elemente durch Weißraum statt Trennlinien gliedern + +**Animation:** +- Langsames Einblenden (Dauer 600ms) +- Hover: sanfter Farbuebergang + +**Details:** +- Abrundung: 8px +- Schatten: subtil (0 4px 12px rgba(0,0,0,0.08)) +- Keine Hintergrund-Dekoration +``` + +#### Vorlage 2: Glassmorphismus + +``` +**Aesthetischer Stil: Glassmorphism** + +**Schrift:** +- Ueberschriften: Outfit, Gewichtung 600-800 +- Fliesstext: Plus Jakarta Sans, Gewichtung 400-500 + +**Farbe:** +- Hintergrund: Gradient #667eea bis #764ba2 +- Karten-Hintergrund: rgba(255, 255, 255, 0.1) +- Text: #FFFFFF + +**Layout:** +- Schwebende Karten-Gestaltung +- Karten ueberlappen sich + +**Animation:** +- Karten erscheinen nacheinander beim Laden (staggered) +- Hover: Karte vergroessert sich um den Faktor 1.05 + +**Details:** +- Abrundung: 20px +- Hintergrund-Unschaerfe: backdrop-blur-xl +- Rahmen: 1px rgba(255, 255, 255, 0.2) +- Subtile Gradient-Leuchteffekte +``` + +#### Vorlage 3: Bento Grid + +``` +**Aesthetischer Stil: Bento Grid** + +**Schrift:** +- Ueberschriften: SF Pro Display, Gewichtung 700 +- Fliesstext: SF Pro Text, Gewichtung 400 + +**Farbe:** +- Hintergrund: #F5F5F7 (Hellgrau) +- Karten: #FFFFFF (Weiss) +- Akzent: #0071E3 (Apple-Blau) + +**Layout:** +- Raster-Layout mit unterschiedlich grossen Karten +- Kartenabstand: 16px +- Abrundung: 24px + +**Animation:** +- Hover: Karte schwebt leicht nach oben +- Klick: Druckeffekt + +**Details:** +- Grosse Karten fuer wichtige Inhalte +- Kleine Karten fuer sekundaere Informationen +- Icons statt Text wo moeglich +- Saubere Schatten (0 4px 24px rgba(0,0,0,0.06)) +``` + +## 3. Methode 2: Designrichtlinien automatisch mit Skills-Plugins laden + +Jedes Mal manuell Stil-Prompts zu schreiben, ist muehsam. **Skills** sind wiederverwendbare Designrichtlinien-Pakete -- nach der Installation wendet AI diese Richtlinien automatisch an. + +### 3.1 Drei Skills fuer schoenere Interfaces + +| Skills | Merkmale | Installationsbefehl | +| :--- | :--- | :--- | +| **UI/UX Pro Max** | 67 Stile, 96 Farbpaletten, 57 Schriftkombinationen | `npm install -g uipro-cli && uipro init --ai claude` | +| **frontend-design** | Offiziell von Anthropic, vermeidet AI-Aesthetik-Klischees | `npx skills add anthropics/skills/frontend-design` | +| **SuperDesign** | IDE-Plugin, generiert mehrere Designvarianten | VSCode-Erweiterungsmarkt nach "SuperDesign" suchen | + +### 3.2 UI/UX Pro Max installieren (am empfohlensten) + +UI/UX Pro Max ist das derzeit umfassendste Designrichtlinien-Skill. Es enthaelt vorkonfiguriert: + +- **67 UI-Stile**: Glassmorphism, Neumorphism, Brutalism, Bento Grid... +- **96 Farbpaletten**: Nach Branchen kategorisiert (SaaS, E-Commerce, Social...) +- **57 Schrift-Kombinationen**: Von professionellen Designern verifizierte Paarungen +- **100+ Designregeln**: Vorgaben fuer Abstaende, Abrundungen und Schatten + +**Installationsschritte:** + +```bash +# 1. CLI global installieren +npm install -g uipro-cli + +# 2. Initialisieren (waehle dein AI-Tool) +uipro init --ai claude +# oder +uipro init --ai cursor +# oder +uipro init --ai trae +``` + +Nach der Installation musst du im Prompt nur einen Satz hinzufuegen: + +``` +Verwende den Glassmorphism-Stil von UI/UX Pro Max und erstelle eine Landing-Page fuer einen AI-Schreibassistenten +``` + +AI wendet automatisch die entsprechenden Schrift-, Farb- und Layoutvorgaben an. + +### 3.3 Offizielles Anthropic frontend-design installieren + +Dies ist das offizielle Frontend-Design-Skill von Anthropic, speziell zur Loesung des "AI-Aesthetik-Klischee"-Problems: + +```bash +# In Claude Code ausfuehren +npx skills add anthropics/skills/frontend-design +``` + +Nach der Installation vermeidet AI automatisch: +- Inter, Roboto, Arial als Schriftarten +- Lila-Gradient-Hintergruende +- Symmetrische Raster-Layouts +- Zu schwache Schatten + +Sie neigt stattdessen zu: +- Einzigartigen Schriftkombinationen +- Mutigen Hauptfarben + scharfen Akzentfarben +- Asymmetrischen, ueberlappenden Layouts +- Texturierten Hintergruenden (Rauschen, geometrische Muster) + +## 4. Praktische Uebung 1: Landing-Page mit verschönernden Prompts neu gestalten + +Lass uns das bisher Gelernte anwenden, um eine gewoehnliche Landing-Page schoen zu machen. + +### 4.1 Gewoehnliche Version + +Zunaechst ein normaler Prompt, um zu sehen, was AI liefert: + +``` +Bitte erstelle eine Landing-Page fuer eine Haustier-Adoptionsplattform mit: +- Navigation (Logo, Links, Registrierungs-Button) +- Hero-Bereich (Ueberschrift, Unterueberschrift, CTA-Button, Tier-Bild) +- Tier-Vorstellung (drei Tierkarten) +- Ueber uns +- Footer +``` + +Die generierte Seite... funktioniert, ist aber sehr gewoehnlich. + +### 4.2 Verschönererte Version + +Jetzt mit Stil-Beschreibung: + +``` +Bitte erstelle eine Landing-Page fuer eine Haustier-Adoptionsplattform mit folgenden Anforderungen: + +**Aesthetischer Stil: Warm und weich + handgezeichnet** + +**Schrift:** +- Ueberschriften: Nunito (rund), Gewichtung 700-800 +- Fliesstext: Nunito, Gewichtung 400-600 + +**Farbe:** +- Hauptfarbe: #FFB347 (warmes Orange) +- Sekundaerfarbe: #FFCCB3 (hell-Orange) +- Hintergrund: #FFF8F0 (elfenbeinfarben) +- Text: #5D4037 (Braun) + +**Layout:** +- Abgerundete Karten (border-radius: 24px) +- Karten leicht geneigt (unterschiedliche Winkel) +- Schwebende, ueberlappende Elemente + +**Animation:** +- Elemente gleiten beim Laden von beiden Seiten ein +- Tier-Karten bewegen sich beim Hover wie ein nickendes Haustier (Rotate-Animation) +- Button mit Bounce-Effekt beim Hover + +**Details:** +- Alle Abrundungen 16-24px +- Warme, weiche Schatten (0 8px 24px rgba(255,179,71,0.3)) +- Hintergrund mit Pfotenabdruck-Muster-Dekoration +- Bilder mit unregelmaessigem Zuschnitt (clip-path) +- Handgezeichnete Icons (Outline-Stil) +``` + +Die generierte Seite wird ein warmes, niedliches Interface sein, das einen zur Adoption animieren moechte. + +## 5. Praktische Uebung 2: Dashboard schnell mit Skills generieren + +Skills eignen sich besonders fuer Backend-Systeme mit vielen Seiten. + +### 5.1 Mit UI/UX Pro Max + +``` +Verwende den Dashboard Dark-Stil von UI/UX Pro Max +und erstelle eine Dashboard-Seite fuer ein SaaS-Produktmanagement-Backend mit: + +**Oben:** Vier Statistik-Karten (Nutzerzahl, aktive Nutzer, Umsatz, API-Aufrufe) + +**Mitte:** +- Links: Liniendiagramm zum Nutzerwachstum (letzte 7 Tage) +- Rechts: Kreisdiagramm zur Abonnement-Plan-Verteilung + +**Unten:** Liste der letzten Aktivitaeten (Zeit, Nutzer, Aktion) +``` + +AI wendet automatisch die Designvorgaben fuer dunkle Dashboards an: +- Dunkelgrauer Hintergrund (#1A1A2E) +- Hochkontrast-Karten (#16213E) +- Lebendige Datenfarben (Blau, Gruen, Orange) +- Schwebende Karten mit Glassmorphismus-Effekt + +### 5.2 Mit dem frontend-design-Skill + +``` +Verwende das frontend-design Skill +und erstelle eine Homepage fuer einen persoenlichen Blog, der Stil soll einzigartig und markant sein +``` + +AI waehlt eine nicht-mainstreamige aesthetische Richtung (z. B. Retro-Futurismus oder Magazin-Stil) und setzt sie mit einzigartiger Schrift, Farbgestaltung und Layout um. + +## 6. Praktische Uebung 3: Eigenes Design-System-Skill erstellen + +Wenn du einen festen Markenstil hast, kannst du ein eigenes Skill erstellen, sodass alle AI-generierten Seiten deiner Marke entsprechen. + +### 6.1 Skill-Datei erstellen + +Erstelle in deinem Projekt die Datei `.claude/skills/my-brand/SKILL.md`: + +````markdown +--- +name: my-brand +description: Mein projektspezifisches Design-System, das sicherstellt, dass alle UI einer einheitlichen Designsprache folgen +--- + +# Mein Projekt-Design-System + +## Markenfarben +- Hauptfarbe: #6366F1 (Indigo 500) +- Sekundaerfarbe: #8B5CF6 (Violet 500) +- Erfolg: #10B981 +- Warnung: #F59E0B +- Fehler: #EF4444 +- Hintergrund: #F9FAFB +- Karten: #FFFFFF + +## Schriftsystem +- Ueberschriften: Plus Jakarta Sans + - H1: 700, 48px + - H2: 600, 36px + - H3: 600, 24px +- Fliesstext: Inter + - Body: 400, 16px + - Small: 400, 14px + +## Abstandssystem +- Grundeinheit: 4px +- Komponenten-Innenabstand: 8px / 12px / 16px +- Blockabstaende: 24px / 32px / 48px +- Seitenraender: 64px + +## Abrundungen +- Buttons: 8px +- Karten: 12px +- Eingabefelder: 8px +- Modale Dialoge: 16px + +## Schatten +- Klein: 0 1px 3px rgba(0,0,0,0.1) +- Mittel: 0 4px 12px rgba(0,0,0,0.1) +- Gross: 0 8px 24px rgba(0,0,0,0.12) + +## Animation +- Uebergangszeit: 150ms / 300ms +- Easing-Funktion: cubic-bezier(0.4, 0, 0.2, 1) +- Hover-Effekt: Leichte Vergroesserung (scale-105) + +## Verbotene Stile +- Keine Lila-Gradient-Hintergruende verwenden +- Keine anderen Schriften als Inter verwenden +- Keine Abrundungen groesser als 16px +- Kein reines Schwarz (#000000), stattdessen #1F2937 +```` + +### 6.2 Eigenes Skill verwenden + +Nach dem Erstellen musst du im Prompt nur sagen: + +``` +Verwende das my-brand Skill und erstelle eine Benutzereinstellungsseite +``` + +AI wendet automatisch alle von dir definierten Designvorgaben an. + +## 7. Zusammenfassung + +Es gibt zwei Methoden, um AI schoene Interfaces generieren zu lassen: + +| Methode | Vorteile | Nachteile | Anwendungsbereich | +| :--- | :--- | :--- | :--- | +| **Prompt-Beschreibung** | Flexibel, jedes Mal anpassbar | Muss wiederholt geschrieben werden | Einmalige Seiten, verschiedene Stile ausprobieren | +| **Skills-Plugins** | Einmal installiert, dauerhaft wirksam | Installation und Konfiguration erforderlich | Projekte mit festen Stilvorgaben | + +**Vibe Coding Workflow-Empfehlung:** + +1. **Explorationsphase**: Mit verschiedenen Stil-Prompts experimentieren, um deine bevorzugte aesthetische Richtung zu finden +2. **Nach Festlegung des Stils**: Das entsprechende Skill installieren (UI/UX Pro Max oder frontend-design) +3. **Markenprojekte**: Eigenes Skill erstellen, das die Designsprache des gesamten Projekts vereinheitlicht + +### Uebung + +Waehle eines der folgenden Szenarien und schliesse es von Grund auf mit den Methoden dieser Lektion ab: + +1. Verwende Stil-Prompts, um das Interface eines deiner frueheren Projekte neu zu gestalten (waehle einen Stil, der dir gefaellt) +2. Installiere UI/UX Pro Max und generiere eine neue Seite mit einem seiner Stile +3. Erstelle dein eigenes Design-System-Skill mit deinen Markenfarben und Schriften + +--- + +## Anhang: Designstil-Schnellreferenz + +| Stil | Schluesselwoerter | Anwendungsbereich | Beispielprodukt | +| :--- | :--- | :--- | :--- | +| **Minimalismus** | Weißraum, einfarbig, schlicht | High-End-Produkte, persoenliche Portfolios | Apple-Website | +| **Glassmorphismus** | Milchglas, Gradienten, Unschaerfe | Technologieprodukte, SaaS-Landing-Pages | macOS Big Sur | +| **Neubrutalismus** | Dicke Rahmen, harte Schatten, pure Farben | Trend-Marken, Kunst-Websites | Brassius | +| **Bento Grid** | Raster, Collage, Karten | Informationsdarstellung, Dashboards | Apple Promo-Seiten | +| **Retro-Futurismus** | Neon, Gradienten, Synthesizer-Wave | Spiele, Musik | STRANGER THINGS | +| **Handgezeichneter Stil** | Unregelmessig, abgerundet, Illustrationen | Bildung, Kinderprodukte | Duolingo | +| **Magazin-Stil** | Grosse Schriften, asymmetrisch, Weißraum | Inhalts-Websites, Blogs | Medium | +| **Dunkler Luxus** | Dunkel, Gold, raffiniert | High-End-Produkte, Luxusmarken | Verschiedene Premium-Marken | + +## Anhang: Skills-Installation-Schnellreferenz + +```bash +# UI/UX Pro Max +npm install -g uipro-cli +uipro init --ai claude + +# Anthropic frontend-design +npx skills add anthropics/skills/frontend-design + +# Anthropic brand-guidelines +npx skills add anthropics/skills/brand-guidelines + +# Installierte Skills in Claude Code anzeigen +/help +``` + +## Anhang: Farbpaletten-Empfehlungen + +| Farbpalette | Hauptfarbe | Akzentfarbe | Hintergrund | Stil | +| :--- | :--- | :--- | :--- | :--- | +| **Sonnenuntergang** | #F97316 | #FBBF24 | #FFF7ED | Warm, dynamisch | +| **Ozean** | #0EA5E9 | #06B6D4 | #F0F9FF | Frisch, professionell | +| **Wald** | #10B981 | #34D399 | #ECFDF5 | Natur, Gesundheit | +| **Beere** | #8B5CF6 | #EC4899 | #FAF5FF | Romantisch, kreativ | +| **Kaffee** | #78350F | #D97706 | #FFFBEB | Warm, Retro | +| **Monolith** | #6B7280 | #9CA3AF | #F9FAFB | Professionell, neutral | + +## Anhang: Designstil-Prompt-Schnellreferenz {#style-prompts} + +Prompts, die man ausprobieren kann, um Frontend-Seiten schoener zu machen: + +### Stilkategorien + +| Stil | Schluesselwoerter (Englisch) | Kern-Visuelle Merkmale | Prompt-Beispiel | +|:---|:---|:---|:---| +| **Pop Art** | Pop Art | Kuehne Kontrastfarben, schwarze Konturlinien, Raster-Punkte | Pop art style website, bold colors and comic dots, vibrant | +| **Minimalismus** | Minimalism | Viel Weißraum, minimale Farben und Linien, keine Dekoration | Minimalist web design, ample white space, geometric, serene | +| **Abstrakter Expressionismus** | Abstract Expressionism | Emotional aufgeladene Pinselstriche, Farbverwürfe | Abstract expressionism background, dynamic paint splashes, emotional | +| **Retro-Stil** | Retro/Vintage | Alte Schriften, gealterte Texturen, Retro-Farbgebung | Retro 80s website design, neon grid and synthwave color palette | +| **Cyberpunk** | Cyberpunk | Hochkontrast-Neonfarben, Glitch-Art-Effekte, dunkler Hintergrund | Cyberpunk UI, neon lights on dark background, glitch effects | +| **Neumorphismus** | Neumorphism | Weiche Schatten und Highlights, leicht erhabene/vertiefte Textur | Neumorphism design style, soft shadows, clean and modern | +| **Generative Kunst** | Generative Art | Algorithmisch generierte fliessende visuelle Muster | Generative art background, flowing algorithmic patterns, digital | +| **Acid Graphics** | Acid Graphics | Metallische Textur, Glas-Zustand, gezackte Schriften | Acid graphics web layout, glass morphism, chaotic typography | +| **Immersives 3D** | Immersive 3D | Interaktive 3D-Szenen, starke Tiefenwirkung | Immersive 3D website, interactive product model in space | diff --git a/docs/de-de/stage-2/frontend/lovart-assets/index.md b/docs/de-de/stage-2/frontend/lovart-assets/index.md new file mode 100644 index 0000000..e0164cb --- /dev/null +++ b/docs/de-de/stage-2/frontend/lovart-assets/index.md @@ -0,0 +1,851 @@ + + +# Von NanoBanana ausgehend: deinen eigenen Asset-Produktions-Agenten aufbauen + +## Kapitel 1: In 1 Minute das erste Bild-Asset generieren + +Bevor wir ueber Design, Stil oder Prompts diskutieren, generieren wir zuerst mit den minimalsten Schritten das erste Bild. + +### 1.1 NanoBanana kennenlernen + +Bevor wir ueber Designstile und Prompt-Engineering diskutieren, moechten wir zuerst eine wichtigere Frage klaeren: **Sicherstellen, dass du wirklich ein Bild generieren kannst.** + +Aktuelle Mainstream-Grossmodelle verfügen bereits ueber Bildgenerierungs- und Bearbeitungsfaehigkeiten. Diese Modelle werden normalerweise als **generative Modelle** bezeichnet. + +Um den Prozess so einfach wie moeglich zu halten, waehlt dieses Tutorial ein Modell, das bereits stabile Bildgenerierungs- und Bearbeitungsfaehigkeiten besitzt, als Beispiel -- NanoBanana. Es ist ein von Google herausgegebenes Bildgenerierungsmodell mit dem offiziellen Namen **Gemini 3.1 Flash Image Preview**, das die direkte Bildgenerierung ueber natuerliche Sprache unterstuetzt und auch die Bearbeitung vorhandener Bilder ermoeglicht. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image1.png) + +Auf der Faehigkeitsebene gibt es keinen wesentlichen Unterschied zu anderen Modellen, die du vielleicht kennst (wie GPT-4o, Claude, Qwen, Midjourney etc.): **Beschreibung eingeben, das Modell generiert das Ergebnis.** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image2.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image3.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image4.png) + +Du kannst es dir als einen "Pinsel" vorstellen. In diesem Kapitel interessiert uns nur eine Frage: +**Kann dieser Pinsel in deiner Hand den ersten Strich ziehen.** + +In der praktischen Verwendung kann NanoBanana direkt ueber offizielle Plattformen wie **Google AI Studio** verwendet werden oder ueber **API** in den Entwicklungsprozess integriert werden. Dieses Tutorial verwendet die API-Aufrufmethode. Mittlerweile ist auch das NanoBanana 2-Modell verfuegbar, und du kannst die neuesten Grossmodelle ausprobieren. + +### 1.2 "Hello World"-Level-Generierung + +Bevor du beginnst, musst du nur die folgenden drei Schritte abschliessen: + +1. Erstelle einen neuen Ordner in Trae + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image5.png) + +2. Erstelle eine neue Python-Datei + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image6.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image7.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image8.png) + +3. Den folgenden Code vollstaendig einfuegen + +Trae schliesst automatisch die erforderliche Umgebungsbereitstellung und Abhaengigkeitsinstallation ab, ohne zusaetzliche Konfiguration. + +Der Code verwendet den API-Key von NanoBanana. Hier wird der Antragsprozess nicht im Detail erlaeutert -- solange du den entsprechenden Parameter abrufen und eingeben kannst. **In dieser Phase geht es nicht darum, jede Codezeile zu verstehen, sondern dass er erfolgreich ausgefuehrt wird.** + +```Python +# /// script +# dependencies = [ +# "gradio>=4.0.0", +# "pillow>=10.0.0", +# "requests>=2.31.0", +# ] +# /// + +import gradio as gr +import requests +import base64 +from PIL import Image +import io +import os +import time +import re +from typing import Optional, Dict, Any, List + +# API-Informationen konfigurieren +NANOBANANA_API_URL: str = "YOUR API URL" +NANOBANANA_API_KEY: str = "YOUR API KEY" +OUTPUT_DIR: str = "outputs" + +# Sicherstellen, dass das Ausgabeverzeichnis existiert +os.makedirs(OUTPUT_DIR, exist_ok=True) + +def image_to_base64_data_uri(image: Image.Image) -> str: + """ + Konvertiert ein PIL-Bild in ein OpenAI-API-kompatibles data URI-Format. + """ + buffer = io.BytesIO() + # Einheitlich nach PNG konvertieren fuer Kompatibilitaet + image.save(buffer, format="PNG") + encoded = base64.b64encode(buffer.getvalue()).decode('utf-8') + return f"data:image/png;base64,{encoded}" + +def base64_to_image(base64_str: str) -> Optional[Image.Image]: + """ + Konvertiert einen reinen Base64-String in ein PIL-Bild. + """ + try: + image_bytes = base64.b64decode(base64_str) + return Image.open(io.BytesIO(image_bytes)) + except Exception as e: + print(f"Base64-Decodierung fehlgeschlagen: {e}") + return None + +def extract_base64_from_response(content: Any) -> Optional[str]: + """ + Kern-Parselogik: Extrahiert Bild-Base64-Daten aus dem von der API zurueckgegebenen content. + Kompatibel mit Markdown-Format und strukturiertem Listenformat. + """ + if not content: + return None + + base64_data = None + + # 1. Versuch der strukturierten Extraktion (List) + if isinstance(content, list): + for part in reversed(content): + if isinstance(part, dict): + img_field = part.get("image_url") or part.get("image") or part.get("output_image") + if isinstance(img_field, dict): + url = img_field.get("url", "") + if url.startswith("data:image/") and "," in url: + return url.split(",", 1)[1].strip() + + text_parts = [ + str(p.get("text", "")) + for p in content + if isinstance(p, dict) and p.get("type") in ["text", "input_text"] + ] + content_str = "".join(text_parts) + else: + content_str = str(content) + + # 2. Versuch der Markdown-Regex-Extraktion (String) + pattern = re.compile(r"!\[.*?\]\((data:image/[^;]+;base64,[^)]+)\)", re.IGNORECASE) + match = pattern.search(content_str) + + if match: + data_url = match.group(1) + if "," in data_url: + return data_url.split(",", 1)[1].strip() + + return None + +def synthesize(prompt: str, input_image: Optional[Image.Image]) -> Optional[Image.Image]: + """ + Ruft die Nanobanana-API fuer die Generierung auf. + """ + if not prompt or not prompt.strip(): + gr.Warning("Bitte gib einen Prompt ein") + return None + + print(f">>> Aufgabe starten: {prompt[:50]}...") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {NANOBANANA_API_KEY}" + } + + messages = [] + + if input_image is not None: + print(">>> Eingabebild erkannt, multimodaler Modus wird verwendet") + img_base64 = image_to_base64_data_uri(input_image) + messages.append({ + "role": "user", + "content": [ + {"type": "text", "text": prompt}, + {"type": "image_url", "image_url": {"url": img_base64}} + ] + }) + else: + messages.append({ + "role": "user", + "content": prompt + }) + + payload = { + "messages": messages, + "model": "gemini-2.5-flash-image", + "stream": False + } + + try: + response = requests.post(NANOBANANA_API_URL, headers=headers, json=payload, timeout=120) + + if response.status_code != 200: + error_msg = f"API-Anfrage fehlgeschlagen: {response.status_code} - {response.text}" + print(error_msg) + gr.Error(error_msg) + return None + + result = response.json() + print(f"API-Rohantwort (gekuerzt): {str(result)[:200]}...") + + content = None + if "choices" in result and len(result["choices"]) > 0: + content = result["choices"][0].get("message", {}).get("content") + + if not content: + gr.Warning("Kein content-Feld in der API-Antwort") + return None + + base64_str = extract_base64_from_response(content) + + if base64_str: + output_image = base64_to_image(base64_str) + if output_image: + return output_image + + text_content = str(content) if not isinstance(content, list) else " ".join([str(x) for x in content]) + gr.Info(f"Kein Bild generiert, Modell gab Text zurueck: {text_content[:100]}...") + return None + + except requests.exceptions.Timeout: + gr.Error("Anfrage-Zeitueberschreitung, bitte versuche es spaeter erneut") + return None + except Exception as e: + import traceback + traceback.print_exc() + gr.Error(f"Ein unbekannter Fehler ist aufgetreten: {str(e)}") + return None + +# Gradio-Oberflaechenkonfiguration +with gr.Blocks(title="Nanobanana Image Generator") as app: + gr.Markdown("# Nanobanana Text/Image to Image") + gr.Markdown("Basierend auf dem Gemini-2.5-Flash-Image-Modell, unterstuetzt Text-zu-Bild und Bild-zu-Bild.") + + with gr.Row(): + with gr.Column(): + prompt_input = gr.Textbox( + label="Prompt (Eingabe)", + placeholder="z.B.: A cyberpunk cat holding a neon sign...", + lines=3 + ) + image_input = gr.Image( + label="Referenzbild (optional, fuer Bild-zu-Bild)", + type="pil", + height=300 + ) + submit_btn = gr.Button("Generierung starten", variant="primary") + + with gr.Column(): + image_output = gr.Image(label="Generierungsergebnis", format="png") + + submit_btn.click( + fn=synthesize, + inputs=[prompt_input, image_input], + outputs=image_output + ) + +if __name__ == "__main__": + app.launch(share=True) +``` + +Wenn Trae eine erfolgreiche Ausführung anzeigt, klicke auf den bereitgestellten lokalen Link (normalerweise http://127.0.0.1:7860). + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image9.png) + +Wenn alles funktioniert, siehst du bereits eine funktionsfaehige KI-Zeichenoberflaeche. + +Diese Oberflaeche sieht einfach aus, aber sie besitzt bereits die zwei wichtigsten Faehigkeiten von kommerziellen Zeichenwerkzeugen: Text-zu-Bild und Bild-zu-Bild. + +* **Links:** **Eingabebereich (Input Zone)** -- Hier gibst du Anweisungen. +* **Prompt (Eingabefeld):** Gib deine kreative Beschreibung ein (Englisch empfohlen). +* **Input Image (Referenzbildfeld):** + * **Text-zu-Bild-Modus:** Hier **leer** lassen. + * **Bild-zu-Bild-Modus:** Ein lokales Bild hierher ziehen, die KI wird es als Grundlage fuer die Erstellung verwenden. +* **Submit-Button:** Klicken, um die Anweisung zu senden und die Generierung zu starten. +* **Rechts: Anzeigebereich (Output Zone)** -- Hier wird das Wunder sichtbar, die generierten Ergebnisse werden hier angezeigt. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image10.png) + +Jetzt koennen wir versuchen, dein erstes Bild zu generieren! + +Der in diesem Beispiel verwendete Prompt lautet: + +> **A red apple** + +Dies ist ein bewusst vereinfachtes Beispiel ohne Stil- oder Parameterbeschreibungen. + +#### Tatsaechlicher Ablauf + +Nach dem Ausfuehren des Codes kann der Prozess in drei Schritte zusammengefasst werden: + +1. Textbeschreibung an das Modell senden +2. Modell generiert das entsprechende Bild +3. Bild wird als lokale Datei gespeichert + +Nach einigen Sekunden siehst du das generierte Ergebnis lokal. Da die Modellgenerierung zufaellig ist, werden gleiche Prompts unterschiedliche Ergebnisse liefern. Du kannst mehrmals generieren und dein bevorzugtes Bild auswaehlen. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image11.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image12.png) + +Du kannst auch deinen Prompt anreichern und ihm mehr Beschreibungen und Einschraenkungen geben. Mit dem folgenden Prompt wird das erhaltene Bild beispielsweise etwas besonderer. + +```Plain +"A hyper-realistic close-up of a fresh red apple with water droplets on its skin, sitting on a dark rustic wooden table. Cinematic dramatic lighting, rim light, shallow depth of field, bokeh background, 8k resolution, macro photography." +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image13.png) + +Klicke im Output Image-Bereich auf Herunterladen, um das Bild lokal zu speichern. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image14.png) + +### 1.3 Haeufige Asset-Generierungsszenarien fuer Bildgenerierungsmodelle + +In der praktischen Arbeit werden Grossmodelle eher zur **effizienten Produktion von Design-Assets** eingesetzt als zur Erstellung einzelner Kunstwerke. + +Wenn du die beliebtesten Beitraege von Design-Marketing-Accounts betrachtest, wirst du feststellen, dass sich ihre Produktion hauptsaechlich auf zwei Arten von Szenarien konzentriert: + +* **Text-zu-Bild (von 0 auf 1)** +* **Bildreferenz-Generierung (von 1 auf N)** + +#### 1. Text-zu-Bild: Design-Materialien schnell abrufen + +Diese Art von Szenario fokussiert sich auf Effizienz. Wenn Luecken im Design gefuellt werden muessen (wie Leerrojekte, Avatare, Illustrationen), fungiert die KI im Wesentlichen als eine **sofort generierende Bilddatenbank**. + +1. ##### UI-Design-Materialien generieren + +* Aktueller Trend: Glas-morphismus, Clay-Stil 3D-Icons auf Dribbble +* Haeufige Darstellung: Transparente Materialien, leuchtende Raender, Bonbon-farbene Funktions- oder Wetter-Icons + +**Beispiel-Prompt:** + +> A set of 3D weather icons (sun, cloud, rain), glassmorphism style, frosted glass texture, soft pastel gradient colors, soft studio lighting, isometric view, transparent background, 4k. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image15.png) + +2. ##### Logo generieren + +* Aktueller Trend: Minimalistische Linien, geometrische Kombinationen fuer technologische Logos +* Haeufige Darstellung: Schwarz-Weiss-Farbgebung, Negativraum-Design, klares Branding + +**Beispiel-Prompt:** + +> Minimalist vector logo design for a tech brand "Coffee Code", combining a coffee cup with coding brackets < >, flat design, solid black lines, white background, Paul Rand style, svg. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image16.png) + +3. ##### Benutzerbilder fuer die Website generieren + +* Aktueller Trend: 3D-Virtual-Avatare auf SaaS-Websites, um Urheberrechtprobleme mit echten Personen zu vermeiden +* Haeufige Darstellung: Freundliche Ausdruecke, Cartoon-Proportionen, Pixar- oder Memoji-Stil + +**Beispiel-Prompt:** + +> Close-up portrait of a friendly young tech professional, smiling, Memoji 3D style, clay render, bright colors, soft lighting, solid plain background, Pixar character design. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image17.png) + +4. ##### Artikelillustrationen generieren + +* Aktueller Trend: Abstrakte flache Illustrationen, haeufig in Technologie-Unternehmensblogs +* Haeufige Darstellung: Lila-Blaue Farbgebung, uebertriebene Koerperproportionen, schwebende UI-Elemente + +**Beispiel-Prompt:** + +> Editorial flat illustration representing remote work, a person sitting on a giant globe using a laptop, corporate memphis art style, vibrant colors (purple and teal), vector texture. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image18.png) + +#### 2. Bildreferenz-Generierung: Visuelle Konsistenz wahren + +Diese Art von Szenario konzentriert sich mehr auf **Skalierbarkeit**. Wenn du bereits ein zufriedenstellendes Hauptvisual hast und einen ganzen Satz stilistisch einheitlicher Assets generieren musst. + +5. ##### Ein Satz von Buttons oder interaktiven Asset-Bildern im gleichen Stil wie das Hauptvisual + +In der Spieleentwicklung ist die Konsistenz der UI sehr wichtig. Angenommen, du hast bereits den "PLAY"-Button des Hauptbildschirms und musst nun einen ganzen Satz stilistisch einheitlicher Funktions-Buttons erstellen (wie Pause, Einstellungen, Startseite). Nur durch manuelles Zeichnen ist es schwierig, die vollstaendige Konsistenz von Glanz, Perspektive und Farbwert jedes Buttons zu gewaehrleisten. + +**Grundlegender Arbeitsablauf:** + +1. Das vorhandene blaue "PLAY"-Button-Bild speichern + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image19.png) + +2. In den **Input Image**-Bereich der Oberflaeche ziehen, als Referenzvorlage fuer nachfolgende Generierungen +3. Die Stilbeschreibung im Prompt beibehalten, nur den Hauptinhalt aendern + +In diesem Arbeitsablauf kannst du durch einfaches Ersetzen der Hauptbeschreibung verschiedene, aber stilistisch konsistente Buttons erhalten. + +**Beispiel-Prompt:** + +**Variante A: Pause-Button (Symboltyp)** + +> A capsule-shaped game UI button with a white pause icon (two vertical bars) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image20.png) + +**Variante B: Einstellungs-Button (komplexes Symbol)** + +> A capsule-shaped game UI button with a white gear icon (settings symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image21.png) + +**Variante C: Replay-Button (Formaenderung)** + +Wenn du die Button-Form anpassen moechtest, kannst du die Form direkt im Prompt beschreiben, und das Modell wird versuchen, die Struktur zu aendern, während die Materialeigenschaften beibehalten werden. + +> A round game UI button with a white circular arrow icon (replay symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image22.png) + +Durch diese Reihe von Operationen koennen nicht nur Button-Funktion und Symbol ersetzt, sondern sogar die Button-Form geaendert werden, wobei alle generierten Ergebnisse in Material, Farbgebung und Licht/Schatten hochgradig konsistent bleiben. Dies ist der Kernwert von Grossmodellen in Szenarien der Design-Asset-Vervielfaeltigung. + +## Kapitel 2: Ein gehorsameres Bildgenerierungs-Assistent -- Am Beispiel von Lovart + +Im ersten Teil haben wir NanoBanana direkt ueber Code aufgerufen und den grundlegenden Prozess "Eingabe gleich Generierung" erlebt. Diese Methode funktioniert gut bei einfachen Anforderungen. Wenn die Generierungsaufgabe jedoch mehr Einschraenkungen enthaelt, wie zum Beispiel: + +* Mehrere stilistisch konsistente Bilder erforderlich +* Mehrfache Anpassungen an vorhandenen Ergebnissen noetig +* Dynamische Aenderung der Generierungsrichtung basierend auf Benutzereingabe + +wird die Einzelaufruf-Methode allmaehlich unzureichend. + +Hier muss ein **AI Agent (intelligenter Agent)** eingefuehrt werden. Dieser Abschnitt zeigt am Beispiel von **Lovart**, wie sich der gesamte Workflow veraendert, wenn dem Bildgenerierungsmodell eine "Denkschicht" hinzugefuegt wird. Hinweis! Hier geht es nicht um Werbung, sondern nur darum, die Bequemlichkeit von AI-Agenten schnell zu vermitteln~ + +### 2.0 Lovart kennenlernen: Dein KI-Design-Agent + +Lovart ist ein agentenbasiertes Design-Tool im Web. Im Vergleich zu normalen Bildgenerierungstools hat es vor der Generierung eine zusaetzliche "Denk- und Planungsschicht". + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image23.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image24.png) + +Nach dem Einloggen bei Lovart musst du hauptsaechlich die folgenden Steuerungselemente kennenlernen: + +#### Modellauswahl + +Klicke auf das Wuerfel-Symbol unterhalb des Eingabefelds, um die aktuell verfuegbaren Generierungsmodelle (wie GPT Image, Flux etc.) anzuzeigen. + +Um mit dem vorherigen Beispiel konsistent zu bleiben, verwendet dieser Abschnitt weiterhin NanoBanana als zugrundeliegendes Generierungsmodell. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image25.png) + +#### Denkmodus + +Dies ist der Kern-Schalter von Lovart: + +* **Fast Mode**: Nahe an nativer API, schnelle Antwort, geeignet fuer Einzel-, klar formulierte Generierungen +* **Thinking Mode**: Agent-Modus, die KI analysiert zuerst die Anforderungen, schreibt den Prompt um und fuehrt dann die Generierung aus + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image26.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image27.png) + +#### Internet-Faehigkeit + +Nach Aktivierung des Globus-Symbols kann der Agent waehrend der Generierung Web-Informationen abrufen (z.B. Designtrends, Farbschemata) als zusatzliche Eingabe. + +### 2.1 Warum die native API nicht ausreicht? + +Auch wenn du bereits ueber Python qualitativ hochwertige Bilder generieren kannst, gibt es weiterhin Einschraenkungen der nativen API bei komplexen Aufgaben. Der Hauptgrund dafuer ist: Die native API ist im Wesentlichen imperativ. Wenn du sie aufforderst, ein bestimmtes Objekt zu generieren, kann sie es direkt ausfuehren; aber wenn die Eingabe zu "einem vollstaendigen Satz von Spiel-Assets planen" wird, wird sie das Ziel nicht aktiv in mehrere ausfuehrbare Schritte aufteilen. + +Der Kernunterschied von Lovart liegt im Agent-Mechanismus. Zwischen der Benutzereingabe und dem Bildgenerierungsmodell fuegt es eine Logik-Schicht zum Verstehen und Planen hinzu: Zunaechst die Benutzerabsicht erkennen, dann die Aufgabe aufteilen, den Prompt umschreiben und schliesslich die Generierung ausfuehren. + +### 2.2 Praxisdemonstration: In 5 Minuten einen IP-Sticker-Satz erstellen + +Am Beispiel von **"Einen IP-Sticker-Satz fuer Programmierer-Enten erstellen"** sehen wir, wie der Agent am gesamten Prozess teilnimmt. + +#### Phase 1: Planung (Die Denkfaehigkeit des Agenten) + +**Problem der nativen API:** +Du musst selbst das Charakterdesign, emotionale Zustaende denken und fuer jedes Bild einen separaten Prompt schreiben. + +**Lovarts Vorgehen:** + +1. Den Thinking Mode aktivieren +2. Eine Anweisung eingeben: + +> Entwirf einen IP-Sticker-Satz fuer Programmierer-Enten im flachen, niedlichen Stil + +Die KI wird nicht sofort zeichnen, sondern zuerst im Internet nach aehnlichen Programmierer-Enten-Designs suchen. Sie gibt eine analysierte Loesung aus, generiert automatisch Szenarien wie Debug, Coffee Break, Panic und erstellt entsprechende visuelle Beschreibungen. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image28.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image29.png) + +In diesem Schritt wechselt die KI von der "Ausfuehrerin" zur "Planerin". Nachdem die KI deine Anforderungen analysiert hat, kannst du im Lovart-Canvas-Bereich verschiedene Stile und Inhalte von Programmierer-Enten-Bildern sehen. Du kannst beginnen, deinen bevorzugten Stil auszuwaehlen. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image30.png) + +#### Phase 2: Konsistenz (Referenzbasierte visuelle Verankerung) + +Bilder in Lovart sind nicht nur Ergebnisse, sondern nehmen auch an nachfolgenden Generierungen teil. + +##### Vollstaendiges Referenzbild + +* Waehle aus den Skizzen die zufriedenstellendste "Standard-Ente" und klicke auf das entsprechende Bild im Canvas-Bereich +* Das Bild wird automatisch im Chat-Bereich als Referenz angezeigt + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image31.png) + +* Neue Aktion eingeben (z.B. gluecklich) und generieren + +Das generierte Ergebnis erbt Farbgebung, Proportionen und Details der Vorlage. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image32.png) + +##### Teilreferenz / Multi-Bild-Integration + +Zusaetzlich zur Verwendung eines ganzen Bildes als Referenz unterstuetzt Lovart auch: + +* **Nur einen Teilbereich des Bildes auswaehlen** (z.B. nur den Hut oder Ausdruck referenzieren) + +Klicke auf den linken Tab im Canvas-Bereich, waehle "Mark" und markiere den Teilbereich des Zielbildes. Dieser Inhalt wird automatisch in das Chat-Feld synchronisiert. Hier koennen wir z.B. die Hintergrundfarbe aendern. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image33.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image34.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image35.png) + +Man sieht, dass das neu generierte Bild nur die Hintergrundfarbe geaendert hat, was unserer Eingabe entspricht. + +* **Unterschiedliche Unterelemente aus mehreren Bildern referenzieren** und zu einem neuen Ergebnis kombinieren + +Zum Beispiel: Du kannst den Charakterkoerper aus Bild A beibehalten und gleichzeitig den Hut durch den Stil aus Bild B ersetzen. Der Agent wird diese visuellen Einschraenkungen im Hintergrund automatisch integrieren. + +Am Beispiel der Programmierer-Ente koennen wir waehlen, das Enten-Design aus dem ersten Bild beizubehalten und es als Hauptelement im zweiten Bild zu ersetzen. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image36.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image37.png) + +Der finale Effekt ist sehr deutlich. Du kannst auch andere Kombinationen ausprobieren! + +#### Phase 3: Umsetzung (Werkzeugaufruf des Agenten) + +Nach Abschluss der Generierung koennen direkt folgende Operationen ausgefuehrt werden: Vergroessern, Hintergrund entfernen, Radieren etc. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image38.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image39.png) + +Diese sind keine einfachen Filter, sondern Ergebnisse, die der Agent automatisch durch den Einsatz verschiedener Werkzeuge erzielt. + +Nachdem der Grundstil festgelegt wurde, koennen sehr schnell eine Reihe von Sticker-Bildern generiert werden. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image40.png) + +Am Ende erhalten wir produktionsfaehige Assets, die direkt geliefert werden koennen, und nicht nur ein Präsentationsbild. + +### 2.3 Hinweise zur Nutzung und Preisgestaltung + +Lovart verwendet ein Abonnement-Preismodell mit unterschiedlichen Kontingenten und Funktionsberechtigungen fuer verschiedene Pakete. Massgeblich sind die auf der offiziellen Website angezeigten Informationen. + +Dieses Tutorial empfiehlt oder vergleicht keine Pakete; bei tatsaechlichem Bedarf kannst du je nach persoenlicher Situation ein kostenpflichtiges Upgrade waehlen. +Aktuell wird die Bezahlung ueber **Alipay** und andere Methoden unterstuetzt. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image41.png) + +#### Zusammenfassung + +Lovart ersetzt nicht das zugrundeliegende Modell, sondern aktualisiert die Bildgenerierung durch den Agent-Mechanismus von "einmaliger Ausfuehrung" zu "kontinuierlichem Workflow". + +Wenn die Aufgabe Planung, Konsistenz und Lieferung umfasst, werden die Vorteile dieser Art von Werkzeug sehr deutlich. + +## Kapitel 3: Selbst einen intelligenten Zeichenassistenten bauen + +Anstatt Lovart direkt zu verwenden, koennen wir auch eine vereinfachte Version eines Zeichenassistenten selbst implementieren. + +Dieses Kapitel verwendet "automatische Artikelillustration" als Beispiel, um schrittweise einen Agenten mit Denkfaehigkeit aus einem praktischen Problem heraus aufzubauen. + +### 3.1 Problemstellung: Warum es nicht funktioniert, Artikel direkt an ein Bildgenerierungsmodell zu senden + +Wenn du einen laengeren Artikel an NanoBanana sendest und um eine Illustration bittest, erhaeltst du normalerweise keine zufriedenstellenden Ergebnisse. Der Grund liegt nicht darin, dass das Modell "nicht gut zeichnen kann", sondern daran, dass **es nicht gut darin ist, lange Texte zu verstehen**. + +Bildgenerierungsmodelle sind besser geeignet fuer kurze, eindeutige visuelle Beschreibungen. Wenn die Eingabe zu einem Artikel mit Struktur, Schwerpunkten und Kontextbeziehungen wird, kann das Modell nicht beurteilen, welche Inhalte im Bild wirklich dargestellt werden muessen. Dies fuehrt oft dazu, dass die generierten Ergebnisse vom Thema abweichen oder nur vereinzelte Details erfassen, ohne eine gesamthafte Zusammenfassung zu liefern. + +Im Wesentlichen haben Bildmodelle nur die Faehigkeit zur "Ausfuehrung", aber keinen Prozess zur Analyse und Auswahl von Text. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image42.png) + +### 3.2 Loesungsansatz: "Verstehen" und "Ausfuehren" mit einem Agenten aufteilen + +Um dieses Problem zu loesen, ist der Schluessel nicht komplexere Prompts, sondern **vor dem Zeichnen zuerst klar zu denken**. Daher fuehren wir eine unabhaengige "Denkschicht" in den Generierungsprozess ein und bauen damit einen einfach verwendbaren Agenten. + +Das einzige Kernziel dieses Agenten: **Das endgueltig generierte Bild so nahe wie moeglich an der tatsaechlichen Ausdrucksabsicht des Benutzers ausrichten.** + +Der Gesamtprozess kann wie folgt zusammengefasst werden: **Lange Texteingabe -> Sprachmodell-Verstehen und Beurteilung -> Geeignete visuelle Prompts generieren -> Bildmodell fuehrt die Generierung aus -> Bild ausgeben** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image43.png) + +Wie kann unser Agent die Absicht des Benutzers verstehen? + +Hier waehlen wir eine vereinfachte "Denkschicht" mit drei verschiedenen Intentionen: ungueltige Eingabe, direkte Bildgenerierung und lange Texte, die Verstaendnis erfordern. + +In diesem Agenten kann die Arbeitsteilung der einzelnen Rollen in vier Punkte zusammengefasst werden: + +1. **Sprachmodell als Entscheidungszentrum** + Es ist verantwortlich fuer das Verstehen von Artikelinhalten, die Beurteilung der Benutzerabsicht und die Weiterleitung der Aufgabe an den entsprechenden Generierungspfad, um zu entscheiden, "wie als naechstes vorzugehen ist" und wie der Prompt zur Bildgenerierung erstellt wird. +2. **Bildmodell als Ausfuehrer** + Das Bildmodell nimmt nicht am Verstehen und Beurteilen teil, sondern erhaelt nur bereits aufbereitete visuelle Anweisungen und konzentriert sich auf die Bilddarstellung. +3. **Benutzer als intervenierender Leiter** + Neben der direkten Texteingabe koennen Benutzer waehrend des Prozesses manuell generierte Prompts anpassen oder Referenzbilder hinzufuegen, um das Endergebnis zu leiten und feinzuaeinen. +4. **Gradio und Backend-API als Gesamttraegerschicht** + Sie sind verantwortlich fuer die Verkettung von Oberflaeche, Modellaufrufen und Ergebnisanzeige, um sicherzustellen, dass der gesamte Agent als stabile Web-Anwendung laeuft. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image44.png) + +### 3.3 Praktische Vorbereitung: API abrufen + +Das sieht doch interessant aus! Um den obigen Prozess zum Laufen zu bringen, muessen wir nur zwei Arten von APIs vorbereiten. + +#### Hand: NanoBanana API (Bildgenerierung) + +Direkte Wiederverwendung der in Kapitel 1 bereits konfigurierten API-Key und API-URL, keine zusaetzliche Einrichtung noetig. + +#### Gehirn: SiliconFlow API (Textdenken) + +Wir benoetigen ein Grosssprachenmodell fuer die "Denkschicht". Dieses Tutorial verwendet den von SiliconFlow bereitgestellten Modelldienst: [https://cloud.siliconflow.cn](https://cloud.siliconflow.cn/) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image45.png) + +SiliconFlow bietet eine mit der OpenAI-API-Spezifikation kompatible Schnittstelle, die sehr einfach ueber Standard-Netzwerkanfragen in Projekten aufgerufen werden kann. Hier waehlen wir das kostenlose Qwen2.5-7B-Instruct-Modell. Alle fuer den Aufruf erforderlichen Inhalte sind bereits in den folgenden Prompt integriert. Vor dem Start musst du nur ein Konto auf der offiziellen Website registrieren und einen API-Key erstellen. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image46.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image47.png) + +Dieser Key wird fuer nachfolgende Modellaufrufe verwendet. + +### 3.4 Den Agenten aufbauen: + +Dieses Experiment verwendet hauptsaechlich Trae beim Schreiben von Code. Dieses Tutorial waehlt das Gemini-3-Pro-Preview-Modell. Der Gesamtansatz ist: Nach dem Erstellen eines neuen Projekts den folgenden vollstaendigen Prompt in das Chat-Feld kopieren und eingeben, schrittweise die API-Key ersetzen, den Code ausfuehren und den Test abschliessen. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image48.png) + +#### Phase 1: Gradio Blocks Grundgeruest und Oberflaechenlayout + +In dieser Phase ist unser Hauptziel, zunaechst ein "Aeusseres" fuer den gesamten Agenten zu erstellen und das Frontend-Seiten-Design zu implementieren. Nach dem Kopieren des folgenden Prompts in das Trae-Chat-Feld wirst du eine lokale URL (normalerweise http://127.0.0.1:7860) erhalten, um die Oberflaeche zu sehen und die Implementierung zu pruefen. + +```Plain +Block 1: Gradio Blocks Grundgeruest und Oberflaechenlayout +1. Aufgabenziel +Basierend auf dem Gradio 4.0.0+ Blocks-Layout, die Basisoberflaeche fuer das "LLM+Nanobanana Text-zu-Bild"-Projekt implementieren, streng dem festen Links-Rechts-Spalten-Layout folgen, alle UI-Komponenten initialisieren und den korrekten Anfangszustand setzen. + +2. Technologie-Stack-Anforderungen +Muss den Gradio 4.0.0+ Blocks-Modus verwenden, Interface-Modus ist verboten; +Abhaengigkeiten: gradio>=4.0.0, pillow>=10.0.0 (nur importieren, Bildverarbeitungslogik noch nicht implementieren); +Der Code muss eine vollstaendig ausfuehrbare Python-Datei mit allen erforderlichen Import-Anweisungen sein. + +3. Oberflaechenlayout-Regeln (Kernbeschraenkung) +Gesamtlayout: +Seitentitel: LLM-gesteuertes Text-zu-Bild-Vollprozess-Tool; +Festes Links-Rechts-Spalten-Layout: Links 60% Breite, Rechts 40% Breite, mit gr.Row und gr.Column die Proportionen steuern. +Links 60% (Prompt-Generierungsprozess-Bereich) Komponentenliste: +input_text: gr.Textbox, Label "Text eingeben (Tutorial-Abschnitt / Zeichenanweisung)", lines=6, Platzhalter "Bitte gib den Tutorial-Text oder direkte Zeichenanweisung ein..."; +identify_intent_btn: gr.Button, value="Intent erkennen", Anfangszustand normal klickbar; +intent_status: gr.Textbox, Label "Intent-Typ / Verarbeitungsstatus", lines=2, interactive=False, Anfangswert "Intent nicht erkannt"; +system_prompt: gr.Textbox, Label "System Prompt (nur fuer Artikel-Illustrations-Intent bearbeitbar)", lines=4, interactive=False, Platzhalter "LLM-Generierungs-Prompt-Regeln..."; +confirm_prompt_btn: gr.Button, value="Bildgenerierungs-Prompt bestaetigen", interactive=False (anfaenglich deaktiviert); +generation_prompt: gr.Textbox, Label="Generierungs-Prompt (bearbeitbar)", lines=3, interactive=True, Anfangswert leer, Platzhalter "Der generierte englische Prompt wird hier angezeigt, manuelle Bearbeitung moeglich...". +Rechts 40% (Nanobanana Bildgenerierungsfunktion-Bereich) Komponentenliste: +ref_image: gr.Image, Label="Referenzbild (optional, Bild-zu-Bild)", type=filepath, height=300, Upload erlauben; +generate_btn: gr.Button, value="Bild generieren", interactive=False (anfaenglich deaktiviert); +result_image: gr.Image, Label="Generierungsergebnis", type=pil, height=300, Anfangswert leer, interactive=False. + +4. Interaktionslogik-Anforderungen +Alle interactive-Anfangszustaende strikt nach obiger Konfiguration, spaeter dynamisch durch Funktionen aktualisieren; +Deaktivierter Button-Zustand muss sichtbar sein (ausgegraut), um Fehlbedienungen zu vermeiden. + +5. Ausgabeanforderungen +Vollstaendigen Python-Code generieren, nur Oberflaechenlayout und Komponenteninitialisierung implementieren, keine Geschaeftslogik; +Klare Code-Kommentare, Komponentenbenennung konsistent mit der praktischen Version; +Code direkt ausfuehrbar, Oberflaechenstruktur vollstaendig wie beschrieben. +``` + +Nach dem Oeffnen von http://127.0.0.1:7860 im Browser kannst du sehen, dass Trae bereits die folgende Webseite nach unseren Anforderungen generiert hat, die unseren Anforderungen weitgehend entspricht, und du kannst mit der naechsten Generierung fortfahren. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image49.png) + +#### Phase 2: LLM Intent-Erkennungsmodul (Siliconflow API) + +Bei der taeglichen Verwendung von VLM zum Zeichnen koennen drei haeufige Eingabesituationen auftreten: + +1. Bedeutungsloser Inhalt wie "Hallo", "Hast du heute schon gegessen?" etc., fuer den keine entsprechenden Bilder gezeichnet werden koennen. +2. Artikel/lange Texte mit mehr Woertern, z.B. ein strukturierter Artikel von ca. 200 Woertern, bei dem zunaechst die Struktur und der Inhalt des Artikels verstanden werden muessen, bevor entschieden werden kann, wie ein Bild generiert werden soll, das den gesamten Text zusammenfasst. +3. Direkte Zeichenanweisungen wie "Zeichne mir eine badende Katze", bei denen die Anforderungen bereits sehr konkret formuliert sind und direkt ein Bild generiert werden kann. + +Wie zuvor den folgenden Prompt in das Trae-Chat-Feld kopieren und implementieren, und die in den vorherigen Schritten erhaltene API ergaenzen. + +```Plain +Block 2: LLM Intent-Erkennungsmodul (Siliconflow API) +1. Aufgabenziel +Auf Basis der bereits implementierten Gradio-Oberflaeche die Klick-Logik fuer den "Intent erkennen"-Button hinzufuegen, Siliconflow-API fuer Intent-Erkennung aufrufen und Komponentenzustaende verknuepfen. + +2. Technologie-Stack-Anforderungen +Basierend auf Gradio 4.0.0+ Blocks; +Abhaengigkeiten: requests>=2.31.0, openai; +Vollstaendig ausfuehrbare Python-Datei ausgeben, einschliesslich Block 1 Oberflaeche + dieses Moduls Logik. + +3. Kern-Geschaeftsregeln +Intent-Klassifizierungsregeln (nur 3 Kategorien, strikt Zahl + Beschreibung zurueckgeben) +1 = Bedeutungsloser Inhalt: Nur Plauderei, Begruessung, irrelevante Konversation ohne Zeichen- oder Illustrationsbedarf; +2 = Artikel/langer Text Illustrationsbedarf: Benutzer gibt einen vollstaendigen Artikel, Tutorial, Absatz, erklaerenden Text ein, der eher narrativ/erklaerend/instruktiv ist, mit der impliziten Absicht, eine Illustration fuer diesen Inhalt zu erstellen; +3 = Direkte Zeichenanweisung: Benutzer gibt eine kurze, eindeutige Zeichenanweisung ohne langen Text-Hintergrund ein (z.B. "Zeichne eine Apple-Stil Katze"). +LLM-Aufrufbeschraenkungen +Schnittstellenadresse: https://api.siliconflow.cn/v1/chat/completions; +Modell: Qwen/Qwen2.5-7B-Instruct; +temperature=0.1; + +4. Komponentenverknuepfungsregeln +Ergebnis 1: intent_status zeigt "1 = Bedeutungsloser Inhalt: Kein Zeichenbedarf", system_prompt bleibt deaktiviert, confirm_prompt_btn deaktiviert; +Ergebnis 2: intent_status zeigt "2 = Artikel/langer Text Illustrationsbedarf: Illustration fuer Eingabe generieren", system_prompt aktivieren und Standardregeln ausfuellen, confirm_prompt_btn aktivieren; +Ergebnis 3: intent_status zeigt "3 = Direkte Zeichenanweisung: Bild gemaess Anweisung generieren", system_prompt deaktiviert und Standardregeln ausfuellen, confirm_prompt_btn aktivieren. + +5. Fehlerbehandlung +API-Fehler, Parsing-Fehler alle freundliche Hinweise geben, kein Absturz, Komponenten in Anfangszustand zuruecksetzen. + +6. Ausgabeanforderungen +Vollstaendig ausfuehrbaren Code generieren, LLM_API_KEY ersetzen und verwenden, klare Kommentare, Intent-Erkennungs-Template strikt verwenden. +``` + +Die vorherige URL http://127.0.0.1:7860 aktualisieren und testen, ob die drei Situationen korrekt erkannt werden. + +1. Bedeutungsloser Inhalt: Versuche "Hallo", "Danke" einzugeben und stelle fest, dass es korrekt erkannt wird. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image50.png) + +2. Artikel/langer Text: Hier wurde ein von Doubao generierter Text ueber kuenstliche Intelligenz verwendet. Du kannst auch eigene Aufsatzabschnitte zum Testen verwenden. + +Ebenfalls erfolgreich erkannt~ + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image51.png) + +3. Direkte Zeichenanweisung: Hier wurde "Ich moechte eine Katze zeichnen" eingegeben, ebenfalls korrekt erkannt. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image52.png) + +Damit haben wir erfolgreich die zweite Phase implementiert -- Intent-Erkennung. + +#### Phase 3: Bildgenerierungs-Prompt-Generierungsmodul (LLM-Zweitaufruf) + +Nach der Intent-Erkennung gibt es fuer Artikel oder lange Texte einen sehr wichtigen weiteren Schritt: die Generierung des Zeichen-Prompts, und genau das ist der Schwerpunkt dieses Agenten. + +```SQL +Block 3: Bildgenerierungs-Prompt-Generierungsmodul (LLM-Zweitaufruf) +1. Aufgabenziel +Auf Basis der Intent-Erkennung die Logik fuer den "Bildgenerierungs-Prompt bestaetigen"-Button implementieren, LLM aufrufen, um Text in einen fuer die Bildgenerierung geeigneten englischen visuellen Prompt umzuwandeln, das Bearbeitungsfeld ausfuellen und den "Bild generieren"-Button verknuepfen. + +2. Technologie-Stack-Anforderungen +Wie Block 2, vollstaendigen Code ausgeben = Block 1 + Block 2 + dieses Modul; +Gemeinsame Nutzung der in Block 2 definierten LLM_BASE_URL, LLM_API_KEY, LLM_MODEL, kein neuer Schluessel. + +3. Kern-Geschaeftsregeln +Prompt-Generierungs-Eingaberegeln +Die Prompt-Generierung ist keine einfache String-Verkettung, sondern erstellt eine Standard-Chat-Nachrichtenliste. + +4. Komponentenverknuepfungsregeln +Erfolgreiche Generierung: Prompt in das generation_prompt-Feld eintragen, generate_btn aktivieren, intent_status "Prompt erfolgreich generiert, kann nach Bearbeitung Bild generieren" anhaengen; +Fehlgeschlagene Generierung: Spezifischen Grund anzeigen, generate_btn deaktiviert lassen, generation_prompt-Feld leer; +Benutzer manuelle Bearbeitung/Leerung des generation_prompt-Felds: +Leerung deaktiviert automatisch generate_btn; +Nicht-leer haelt generate_btn aktiv. + +5. Fehlerbehandlung +API-Aufruf fehlgeschlagen: Freundlicher Hinweis "Prompt-Generierung fehlgeschlagen: {spezifische Fehlermeldung}", kein Absturz; +Prompt-Ueberpruefung fehlgeschlagen: Grund klar angeben, erneuten Versuch erlauben; +Antwort-Parsing fehlgeschlagen: Hinweis "LLM-Antwort kann nicht geparst werden, bitte erneut versuchen". + +6. Ausgabeanforderungen +Vollstaendig ausfuehrbaren Code, LLM_API_KEY ersetzen und verwenden; +Klare Code-Struktur, vollstaendige Kommentare, schoene und einfache Oberflaeche; +Strikt die Standard-Chat-Nachrichtenlisten-Struktur implementieren, Parameter und Beispielelogik konsistent; +Prompt-Laenge und Inhaltsueberpruefungslogik enthalten, freundliche Fehlermeldungen. +``` + +Ebenso den Text aus der zweiten Phase kopieren und testen. + +Es ist erwähnenswert, dass der hier voreingestellte System-Prompt fuer die Bildgenerierung lautet: + +> Du bist jetzt ein Assistent zum Erstellen von NanoBanana-Zeichen-Prompts. +> Du musst basierend auf meinem Inhalt verarbeiten. Der Zweck dieses Bildes ist zu veranschaulichen, was dieser Abschnitt sagt, und den Leuten zu zeigen, was die Kontextstruktur des gesamten Textes bedeutet. +> Es koennte aehnlich wie in einer Praesentation einige Erklaerungen enthalten (z.B. oben links die Kernansicht, unten rechts die Daten). +> Designstilanforderung: Minimalistisch, Apple Design Philosophy. +> Einschraenkung: Bitte gib nur den fuer NanoBanana verwendbaren englischen Prompt zurueck, ohne Erklaerungen, Praefixe oder ueberfluessigen Text. + +Wenn du ein anderes voreingestelltes Template verwenden moechtest, kannst du es im vorherigen Prompt aendern oder direkt in Trae durch Konversation anpassen. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image53.png) + +Zusaetzlich zur Aenderung des unterliegenden Codes koennen wir auch auf der Webseite schnell bearbeiten. Zum Beispiel habe ich hier den Satz "Pic Prompt am Anfang hinzufuegen" ergaenzt, und man sieht, dass der neu generierte Prompt ebenfalls diesen enthaelt. Dieses Design ist gedacht, um das schnelle Aendern des System-Prompts fuer die Prompt-Generierung zu ermoeglichen und uns beim schnellen Wechsel von Stilen zu helfen. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image54.png) + +#### Phase 4: Nanobanana Text-zu-Bild / Bild-zu-Bild-Modul + +Endlich der letzte Schritt -- ohne Anschluss an ein Bildgenerierungsmodell ist es kein vollstaendiger Agent! + +```Bash +Block 4: Nanobanana Text-zu-Bild / Bild-zu-Bild-Modul (Finalversion) +1. Aufgabenziel +Die Logik fuer den "Bild generieren"-Button implementieren, die echte Nanobanana-API aufrufen, Text-zu-Bild/Bild-zu-Bild unterstuetzen, Base64 parsen und Bild anzeigen. + +2. Technologie-Stack-Anforderungen +Basierend auf Gradio 4.0.0+ Blocks; +Abhaengigkeiten: requests, pillow, base64, io, re; +Vollstaendiger Code = Block 1+2+3 + dieses Modul. + +3. Kern-API-Konfiguration +Code-Konfiguration fixieren: +NANOBANANA_API_URL = "https://api.zyai.online/v1/chat/completions" +NANOBANANA_MODEL = "gemini-2.5-flash-image" +NANOBANANA_API_KEY = "" # Benutzer ersetzt selbst + +4. Bildvorverarbeitung +Funktion image_to_base64_data_uri(ref_image_path) implementieren: PIL-Bild nach PNG konvertieren, automatisch auf 1024x1024 skalieren, transparenten Kanal zu weissem Hintergrund, als Base64 kodieren. + +5. Anforderungskonstruktion +Funktion generate_image(prompt, ref_image_path) implementieren; +Logik-Zweig 1: Reines Text-zu-Bild (ref_image_path leer); +Logik-Zweig 2: Bild-zu-Bild (ref_image_path vorhanden). + +6. Antwort-Parsing +Aus choices[0].message.content Bild-Base64 extrahieren, strukturiertes JSON und Markdown-Format unterstuetzen. + +7. Komponentenverknuepfung und Fehlerbehandlung +Erfolgreiche Generierung: PIL-Bild in result_image anzeigen; +Fehlgeschlagene Generierung/Parsing/Upload: Klare Textmeldung in intent_status anzeigen, kein Absturz. + +8. Ausgabeanforderungen +Vollstaendig ausfuehrbaren Code, LLM_API_KEY und NANOBANANA_API_KEY ersetzen und direkt ausfuehren. +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image55.png) + +Wie aufregend! Wir haben endlich das erste Bild dieses Agenten erfolgreich generiert. Wenn du das generierte Bild genau betrachtest, siehst du, dass es mit unserem Text und dem Prompt uebereinstimmt. Hier hast du im Wesentlichen deinen eigenen Agenten implementiert! + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image56.png) + +Wir haben auch eine Bild-zu-Bild-Funktion hinzugefuegt. Lade dein Lieblingsbild hoch, und die KI wird automatisch den Stil uebernehmen. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image57.png) + +Es ist erwähnenswert, dass die in den vorherigen Schritten generierten Prompts auch auf der Webseite bearbeitet werden koennen, und wir den Prompt zum Zeitpunkt des endgueltigen Klicks als Massstab nehmen. Selbst wenn du hier "a cute cat" eingibst, wird das endgueltig generierte Bild nur eine suesse kleine Katze sein. + +## Kapitel 4: Zusammenfassung + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image58.png) + +**Hurra! Endlich fertig!** +Um ehrlich zu sein, selbst ich habe beim Schreiben der letzten Zeile tief durchgeatmet, ganz zu schweigen von dir, der bis hierhin mitgemacht hat. Diesen gesamten Prozess komplett durchlaufen zu koennen, ist bereits sehr beeindruckend. Es zeigt, dass du wirklich die Haende auf die Tastatur gelegt und die Dinge Schritt fuer Schritt erledigt hast. + +Waehrend ich diesen Inhalt geschrieben habe, habe ich immer wieder darueber nachgedacht, was wir eigentlich hinterlassen wollen. Die Antwort ist nicht der Modellname, die Parameter oder ein bestimmter fester Ansatz, sondern dir allmaehlich ein Gefuehl zu vermitteln: welche Dinge beruhigt der KI zum Verstehen und Planen uebergeben werden koennen und wo du nur die Richtung vorgeben musst. Sobald diese Arbeitsteilung steht, werden viele urspruenglich komplex erscheinende Generierungsprozesse fluessiger. + +Im Rueckblick war dieser Weg gar nicht so kompliziert. Klar werden, welches Problem du loesen moechtest, den langen Text dem Sprachmodell zur Analyse uebergeben, dann die aufbereitete visuelle Absicht dem Bildgenerierungsmodell zur Darstellung uebergeben und schliesslich diesen gesamten Prozess als deinen eigenen kleinen Assistenten verpacken. Hier bist du nicht mehr nur "beim Modell-Nutzen", sondern beim Aufbau eines Systems, das dich langfristig bei der Arbeit begleiten kann. Und genau das ist es, was dieses Tutorial dir am meisten vermitteln moechte. + +Aber du hast schon sehr Gutes geleistet! Wer bis hierhin gelernt hat, hat bereits eine grundlegende Beherrschung von Vibe Coding. Goenn dir eine kleine Pause! + + diff --git a/docs/de-de/stage-2/frontend/modern-component-library/index.md b/docs/de-de/stage-2/frontend/modern-component-library/index.md new file mode 100644 index 0000000..930a4b6 --- /dev/null +++ b/docs/de-de/stage-2/frontend/modern-component-library/index.md @@ -0,0 +1,465 @@ +# Deine Oberflaeche mit einer modernen Komponentenbibliothek aktualisieren + +In den vorherigen Lektionen hast du gelernt, wie man mit Designtools Interfaces entwirft, mit AI IDE Designentwuerfe in Code umwandelt und sogar ein vollstaendiges Frontend-Projekt abgeschlossen. Aber du hast vielleicht auch ein Problem entdeckt: Die von Grund auf selbst geschriebenen Buttons, Formulare und Dialoge funktionieren zwar, wirken aber im Vergleich zu "professionellen Produkten" immer ein wenig unbefriedigend -- die Stile sind nicht einheitlich genug, die Interaktionsdetails sind nicht geschmeidig genug, und die Anpassung an verschiedene Bildschirme ist muehsam. + +Genau das ist das Problem, das **Komponentenbibliotheken** loesen. + +Eine Komponentenbibliothek ist eine vorgefertigte Sammlung von UI-Bauteilen. Buttons, Eingabefelder, Dropdowns, Dialoge, Tabellen... diese Interface-Elemente, die du in jedem Produkt immer wieder brauchst, sind bereits fertig und wurden von zahllosen Nutzern validiert und optimiert. Du musst sie nur wie Bausteine zusammenfuegen, um schnell professionelle Interfaces zu erstellen. + +## Was du lernen wirst + +1. Verstehen, was eine Frontend-Komponentenbibliothek ist und warum moderne Entwicklung sie fast immer einsetzt +2. Vier repraesentative Komponentenbibliotheken kennenlernen und ihre jeweiligen Staerken verstehen +3. Durch drei praktische Szenarien (Landing-Page, Produktseite, Backend-Verwaltung) lernen, wie man mit AI IDE + Komponentenbibliothek Vibe Coding betreibt +4. Lernen, Komponentenbibliothek-Dokumentation zu lesen, die richtigen Komponenten fuer die Anforderungen zu finden und korrekt zu verwenden + +## 1. Warum braucht man Komponentenbibliotheken? + +Stell dir vor, du renovierst ein Haus. Du kannst selbst aus Holz einen Stuhl bauen, aber ueblicherweise gehst du zu IKEA und kaufst einen -- gutes Design, stabile Qualitaet, klare Aufbauanleitung, nach Hause bringen und zusammensetzen. + +Eine Komponentenbibliothek ist das "IKEA" der Frontend-Entwicklung. Sie bietet keine Moebel, sondern Interface-Bauteile: + +| Selbst geschrieben | Komponentenbibliothek verwenden | +| :--- | :--- | +| Stil, Interaktion und Animation selbst behandeln | Out-of-the-box, Stil und Interaktion sind bereits optimiert | +| Buttons auf verschiedenen Seiten koennen unterschiedlich aussehen | Global einheitlicher Stil, automatische Konsistenz | +| Anpassung an Handy und Tablet erfordert zusaetzliche Arbeit | Die meisten Komponentenbibliotheken haben integrierte Responsive-Unterstuetzung | +| Barrierefreiheit (Accessibility) wird leicht uebersehen | Professionelle Komponentenbibliotheken haben Tastaturnavigation und Screenreader bereits integriert | +| Langsame Entwicklung | Schnelle Entwicklung, Fokus auf Geschaeftslogik | + +Kurz gesagt: **Komponentenbibliotheken lassen dich die Zeit fuer das "Was" aufwenden, nicht fuer das "Wie".** + +### Sehen ist Glauben: Dieselbe Anforderung, mit und ohne Komponentenbibliothek + +Nur Reden reicht nicht. Wir haben in Trae mit nahezu identischen Anforderungen jeweils ohne und mit Komponentenbibliothek generiert und die Ergebnisse verglichen. + +**Prompt 1: Ohne Komponentenbibliothek** + +```text +Bitte erstelle eine Daten-Dashboard-Seite fuer einen AI-Schreibassistenten mit: +- Obere Titelzeile und Export-Button +- Vier Statistik-Karten fuer Nutzerzahl, aktive Nutzer, Dokumentanzahl und Umsatz, mit Trendanzeige +- Ein Liniendiagramm und ein Kreisdiagramm +- Nutzerlisten-Tabelle mit Seitennummerierung +- Linke Navigations-Seitenleiste +``` + +In Trae direkt ausgefuehrt: + + + + +**Prompt 2: Mit shadcn/ui-Komponentenbibliothek** + +```text +Bitte erstelle eine Daten-Dashboard-Seite fuer einen AI-Schreibassistenten mit der shadcn/ui-Komponentenbibliothek: +- Obere Titelzeile und Export-Button +- Vier Statistik-Karten fuer Nutzerzahl, aktive Nutzer, Dokumentanzahl und Umsatz, mit Trendanzeige +- Ein Liniendiagramm und ein Kreisdiagramm +- Nutzerlisten-Tabelle mit Seitennummerierung +- Linke Navigations-Seitenleiste +``` + +Ebenfalls in Trae direkt ausgefuehrt: + + + + +Dieselbe Anforderung, der einzige Unterschied ist, dass im Prompt `shadcn/ui + Tailwind CSS` hinzugefuegt wurde. Das von Trae generierte Ergebnis liegt in visueller Konsistenz, Interaktionsdetails und Gesamtqualitaet auf einer voellig anderen Ebene. Das ist das "kostenlose Upgrade" durch die Komponentenbibliothek -- du musst im Prompt nur den Namen einer Bibliothek hinzufuegen. + +## 2. Vier Kern-Komponentenbibliotheken kennenlernen + +Es gibt zahlreiche Komponentenbibliotheken (eine vollstaendige Liste im [Anhang](#anhang-weitere-komponentenbibliotheken-im-ueberblick)), aber du musst zunaechst nur diese vier repraesentativsten kennen: + +| Komponentenbibliothek | Framework | Kurzbeschreibung | Website | +| :--- | :--- | :--- | :--- | +| [Ant Design](https://ant.design) | React | Von Ant Group, de facto Standard fuer Enterprise-Backends, extrem breite Komponentenabdeckung | ant.design | +| [shadcn/ui](https://ui.shadcn.com) | React | Kein npm-Package, Code wird direkt in dein Projekt kopiert, basiert auf Tailwind CSS, hoechste Anpassungsfreiheit | ui.shadcn.com | +| [HeroUI](https://heroui.com) (ehemals NextUI) | React | Standardmaessig schoene Styles, fluessige Animationen, ideal fuer Landing-Pages und Produktpraesentationen mit hohen visuellen Anforderungen | heroui.com | +| [Material UI](https://mui.com) | React | Die aelteste React-Komponentenbibliothek, implementiert die Google Material Design-Richtlinien, reifstes Oekosystem | mui.com | + +> Vue-Nutzer haben ebenfalls eine reiche Auswahl: [Element Plus](https://element-plus.org) (am populaersten in China), [Ant Design Vue](https://antdv.com), [Naive UI](https://www.naiveui.com) etc., siehe [Anhang](#anhang-weitere-komponentenbibliotheken-im-ueberblick). + +Verschiedene Komponentenbibliotheken haben ihre Staerken in verschiedenen Szenarien. Wir fuehren dich als Naechstes durch drei reale Entwicklungsszenarien, um zu zeigen, wie man mit AI IDE + Komponentenbibliothek Vibe Coding betreibt. + +Um verschiedene Bibliotheken und ihre Besonderheiten zu demonstrieren, haben wir in jedem Szenario bewusst eine andere Bibliothek gewaehlt. Bitte beachte: **Das dient nur dazu, dir mehrere Loesungen zu zeigen**. In der tatsaechlichen Entwicklung kannst du problemlos nur die Bibliothek verwenden, die dir am besten liegt. Wenn dir beispielsweise der Stil von shadcn/ui gefaellt, kannst du damit Landing-Pages, Produktseiten und Backend-Verwaltung erstellen. Waehle die, die dir schoen erscheint und mit der du dich wohlfuehlst -- das ist das Wichtigste. + +## 3. Praktische Uebung 1: Produkt-Landing-Page mit HeroUI erstellen + +**Szenario**: Du hast ein AI-Schreibassistenten-Produkt und brauchst eine schoene Landing-Page, um die Produkteigenschaften zu praesentieren und Nutzer zur Registrierung zu animieren. Die Landing-Page muss eine starke visuelle Wirkung haben, fluessige Animationen bieten und auch auf dem Handy gut aussehen. + +**Warum HeroUI**: Die Standard-Stiles von HeroUI sind bereits sehr schoen, mit fluessigen Uebergangsanimationen, ideal fuer nutzerorientierte Praesentations-Seiten. + +### 3.1 Projekt erstellen + +```bash +# Projekt mit dem offiziellen HeroUI-CLI erstellen +npx create-heroui-app@latest ai-writer-landing +cd ai-writer-landing +npm install +``` + + + + +### 3.2 Landing-Page mit AI IDE generieren + +AI IDE (Cursor, Trae etc.) oeffnen und im Dialog eingeben: + +```text +Bitte erstelle eine Landing-Page fuer einen AI-Schreibassistenten mit der HeroUI-Komponentenbibliothek: + +**Seitenstruktur:** +1. Obere Navigation: Links Logo und Produktname, rechts die Links "Funktionen", "Preise", "Ueber uns" sowie ein "Loslegen"-Button +2. Hero-Bereich: Grosse Ueberschrift "Lass AI dein Schreib-Partner werden", Unteruebersicht mit Produktwert, zwei Buttons "Kostenlos testen" und "Demo ansehen", darunter ein Produkt-Screenshot +3. Funktionspraesentation: Drei Spalten-Karten fuer "Intelligentes Weiterschreiben", "Stil-Anpassung" und "Mehrsprachige Uebersetzung", jede Karte mit Icon, Titel und Beschreibung +4. Preisbereich: Drei Preiskarten (Gratis-Version, Pro-Version, Team-Version), Pro-Version hervorgehoben +5. Unterer Call-to-Action: Ein attraktiver Slogan mit Registrierungs-Button +6. Footer: Copyright-Info und Social-Media-Links + +**Design-Anforderungen:** +- Modern und professionell wirken +- Dark Mode unterstuetzen +- Auch auf dem Handy gut aussehen +``` + + + + +### 3.3 Vom AI verwendete Schluesselkomponenten + +Im von AI generierten Code wirst du diese HeroUI-Komponenten sehen: + +```jsx +import { + Navbar, NavbarBrand, NavbarContent, NavbarItem, + Button, + Card, CardHeader, CardBody, CardFooter, + Divider, + Link, + Chip +} from '@heroui/react' +``` + +Rolle jeder Komponente: + +| Komponente | Zweck | Position in der Landing-Page | +| :--- | :--- | :--- | +| `Navbar` | Obere Navigationsleiste | Ganz oben auf der Seite, fixiert | +| `Button` | Button, unterstuetzt mehrere Varianten und Farben | CTA-Buttons, Navigations-Buttons | +| `Card` | Karten-Container | Funktionspraesentation, Preiskarten | +| `Chip` | Kleines Tag | "Empfohlen", "Am beliebtesten" Markierung | +| `Divider` | Trennlinie | Visuelle Trennung zwischen Bereichen | + +### 3.4 Iterative Optimierung + +Der erste generierte Code ist moeglicherweise noch nicht vollstaendig zufriedenstellend. Weiterhin mit AI im Dialog bleiben und anpassen: + +```text +Bitte optimiere die Landing-Page: + +1. Ueberschrift mit Gradient-Farbe von Blau nach Violett +2. Funktionskarten sollen beim Hover eine Schwebe-Animation haben +3. Die Pro-Preiskarte hervorheben, mit Rahmen und "Am beliebtesten"-Tag +4. Navigation auf dem Handy in ein Hamburger-Menue umwandeln +``` + + + + +> **Kern des Vibe Coding**: Du musst nicht jedes Komponenten-API auswendig kennen. Beschreibe einfach in natuerlicher Sprache den gewuenschten Effekt, und AI findet die passende Komponente und Schreibweise. Bei Unzufriedenheit einfach weiter im Dialog iterieren. + +## 4. Praktische Uebung 2: Produktseite mit shadcn/ui erstellen + +**Szenario**: Dein AI-Schreibassistent braucht ein Haupt-Interface nach der Benutzeranmeldung -- links die Dokumentenliste, rechts der Editor, oben eine Werkzeugleiste. Dies ist eine funktionale Produktseite, die ein hochgradig anpassbares UI erfordert. + +**Warum shadcn/ui**: shadcn/ui kopiert den Komponenten-Code direkt in dein Projekt, sodass du jedes Detail frei aendern kannst. Fuer tief anpassbare Produkt-Interfaces ist dieses "Code gehoert dir"-Modell am flexibelsten. + + + + +### 4.1 Projekt erstellen + +```bash +# Next.js-Projekt erstellen +npx create-next-app@latest ai-writer-app --typescript --tailwind --app +cd ai-writer-app + +# shadcn/ui initialisieren +npx shadcn@latest init + +# Komponenten nach Bedarf hinzufuegen (nicht alle auf einmal installieren) +npx shadcn@latest add button card input sidebar sheet dialog +``` + +Das Besondere an shadcn/ui: Jedes Mal, wenn du eine Komponente `add`-ierst, wird der Quellcode in das `components/ui/`-Verzeichnis deines Projekts kopiert. Du kannst diese Dateien direkt oeffnen und Stil und Verhalten aendern. + +### 4.2 Produkt-Interface mit AI IDE generieren + +```text +Bitte erstelle das Haupt-Interface eines AI-Schreibassistenten mit der shadcn/ui-Komponentenbibliothek: + +**Gesamtlayout:** +- Links eine einklappbare Seitenleiste, Breite ca. 280px: + - Oben ein "Neues Dokument"-Button + - Darunter die Dokumentenliste, jedes Dokument zeigt Titel und letzte Bearbeitungszeit + - Rechtsklick auf ein Dokument zum Umbenennen oder Loeschen +- Rechts der Haupt-Editor-Bereich, in zwei Teile geteilt: + - Oben die Werkzeugleiste: Dokumenttitel bearbeiten, Wortstatistik anzeigen, "AI-Weiterschreiben"-Button, "Export"-Dropdown + - Unten der Editor-Bereich: Ein grosses Texteingabefeld, das den restlichen Platz ausfuellt + +**Interaktionsdetails:** +- Nach Klick auf "AI-Weiterschreiben" zeigt der Button einen Ladezustand, am Ende des Editors erscheint der von AI generierte Text (wie eine Schreibmaschine, Zeichen fuer Zeichen) +- Auf dem Handy wird die Seitenleiste zu einer Drawer-Ansicht, die von links einschieht +- Das aktuell ausgewaehlte Dokument wird hervorgehoben +``` + + + + +### 4.3 Vom AI verwendete Schluesselkomponenten + +```tsx +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Card, CardContent, CardHeader } from '@/components/ui/card' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@/components/ui/dropdown-menu' +import { + Sheet, + SheetContent, + SheetTrigger +} from '@/components/ui/sheet' +import { + Sidebar, + SidebarContent, + SidebarHeader +} from '@/components/ui/sidebar' +``` + +| Komponente | Zweck | Position auf der Produktseite | +| :--- | :--- | :--- | +| `Sidebar` | Einklappbare Seitenleiste | Links Dokumentenliste | +| `Sheet` | Mobil-Drawer | Alternative zur Seitenleiste auf Mobilgeraeten | +| `DropdownMenu` | Dropdown-Menue | "Export"-Button, Rechtsklick-Menue | +| `Dialog` | Dialogfeld | Umbenennen, Loesch-Bestaetigung | +| `Button` | Button, unterstuetzt variant und loading | Verschiedene Aktions-Buttons | +| `Input` | Eingabefeld | Dokumenttitel-Bearbeitung | + +### 4.4 Komponentenstiele anpassen + +Der Vorteil von shadcn/ui liegt darin, dass du den Komponenten-Quellcode direkt aendern kannst. Wenn du beispielsweise groessere Abrundungen fuer Buttons moechtest: + +```text +Bitte aendere components/ui/button.tsx, +setze die Standard-Abrundung aller Buttons von rounded-md auf rounded-xl +und fuege der primary-Variante einen subtilen Schatten-Effekt hinzu +``` + +AI aendert die Komponentendatei direkt in deinem Projekt, anstatt die Styles eines npm-Packages zu ueberschreiben -- das ist der Vorteil von shadcn/ui "Code gehoert dir". + + + + +## 5. Praktische Uebung 3: Backend-Verwaltungsinterface mit Ant Design erstellen + +**Szenario**: Dein AI-Schreibassistent ist online und du brauchst ein Verwaltungs-Backend, um Nutzerdaten einzusehen, Dokumenteninhalte zu verwalten und bezahlte Bestellungen zu bearbeiten. Der Kern eines Backend-Verwaltungssystems sind Datenanzeige und Operationseffizienz. + +**Warum Ant Design**: Ant Design hat die tiefste Erfahrung im Backend-Bereich. Tabellen, Formulare, Diagramme und andere Geschaeftskomponenten sind sofort einsatzbereit, mit vielen integrierten Enterprise-Interaktionsmustern (Stapelverarbeitung, erweiterte Filter, Datenexport etc.). + + + + +### 5.1 Projekt erstellen + +```bash +# Mit Ant Design Pro Scaffold verwenden (integriertes Layout, Routing, Berechtigungen) +npx create-umi@latest ai-writer-admin +# Ant Design Pro Template waehlen +cd ai-writer-admin +npm install +``` + +Oder von Grund auf: + +```bash +npx create-react-app ai-writer-admin --template typescript +cd ai-writer-admin +npm install antd @ant-design/icons @ant-design/pro-components +``` + +### 5.2 Backend-Verwaltung mit AI IDE generieren + +```text +Bitte erstelle ein Backend-Verwaltungssystem fuer einen AI-Schreibassistenten mit der Ant Design-Komponentenbibliothek: + +**Gesamtlayout:** +- Links die Menueleiste: Dashboard, Nutzerverwaltung, Dokumentenverwaltung, Bestellverwaltung, Systemeinstellungen +- Oben Breadcrumb-Navigation anzeigen + +**Nutzerverwaltungsseite:** +- Oben vier Statistik-Karten: Gesamtnutzerzahl, heute neu, aktive Nutzer, zahlende Nutzer +- Suchfilter-Bereich: Suche nach Nutzername, Auswahl des Registrierungszeitraums, Filterung des Nutzerstatus, mit "Suchen"- und "Zuruecksetzen"-Buttons +- Nutzer-Tabelle: + - Anzeige von Avatar, Nutzername, E-Mail, Registrierungsdatum, Abonnement-Plan (farblich unterschieden), Status, Aktionen + - 20 Eintraege pro Seite mit Seitennummerierung + - Mehrfachauswahl von Nutzern, Stapel-Deaktivierung oder Export + - Aktionsspalte: Details anzeigen, bearbeiten, deaktivieren (mit Bestaetigung vor Deaktivierung) +- Nach Klick auf "Details anzeigen" oeffnet sich rechts ein Drawer mit Nutzerdetails und letzter Dokumentenliste +``` + + + + +### 5.3 Vom AI verwendete Schluesselkomponenten + +```tsx +import { PageContainer, ProLayout } from '@ant-design/pro-components' +import { ProTable } from '@ant-design/pro-components' +import { StatisticCard } from '@ant-design/pro-components' +import { + Button, Tag, Badge, Space, Drawer, + Popconfirm, message, Modal +} from 'antd' +import { + UserOutlined, SearchOutlined, ExportOutlined +} from '@ant-design/icons' +``` + +| Komponente | Zweck | Position im Backend | +| :--- | :--- | :--- | +| `ProLayout` | Gesamt-Backend-Layout-Frame | Seitenskelett (Menue + Inhaltsbereich) | +| `ProTable` | Erweiterte Tabelle mit integrierter Suche, Seitennummerierung und Spalteneinstellungen | Nutzerliste, Dokumentenliste, Bestellliste | +| `StatisticCard` | Daten-Statistik-Karten | Dashboard, Uebersicht oben auf der Seite | +| `Tag` / `Badge` | Status-Tags | Abonnement-Plan, Nutzerstatus | +| `Drawer` | Seiten-Drawer | Nutzerdetails, Bearbeitungsformular | +| `Popconfirm` | Popup-Bestaetigungsbox | Loeschen, Deaktivieren und andere gefaehrliche Operationen | + +### 5.4 Weiter iterieren: Dashboard hinzufuegen + +```text +Bitte erstelle eine Dashboard-Seite: + +1. Oben vier Statistik-Karten: Gesamtnutzerzahl, Gesamtdokumentanzahl, heutige API-Aufrufe, monatlicher Umsatz, jeweils mit Wert und monatlicher Veraenderung (gestiegen oder gefallen) +2. Mitte zwei Diagramme: + - Links: Liniendiagramm des Nutzerwachstums der letzten 7 Tage + - Rechts: Kreisdiagramm der Abonnement-Plan-Verteilung +3. Unten: Tabelle der letzten Operations-Logs mit Zeit, Nutzer, Aktionstyp und Details + +Verwende Ant Design-Komponenten fuer das Layout, Diagramme koennen mit Ant Design Charts erstellt werden +``` + + + + +> **Vibe Coding Tipp fuer Backend-Verwaltung**: Backend-Seiten haben eine relativ feste Struktur (Tabelle + Suche + Dialog), was sich hervorragend fuer die batchweise Generierung durch AI eignet. Du kannst zunaechst eine "Nutzerverwaltung"-Seite als Vorlage von AI generieren lassen und dann sagen: "Orientiere dich an der Struktur der Nutzerverwaltungsseite und generiere eine Dokumentenverwaltungsseite." AI wird dasselbe Layout-Muster wiederverwenden. + +## 6. Dokumentation lesen lernen: Die "Bedienungsanleitung" der Komponentenbibliothek + +Im Vibe Coding schreibt AI den Grossteil des Codes. Wenn jedoch das generierte Ergebnis nicht stimmt oder du das Verhalten einer Komponente feinanpassen moechtest, ist **Dokumentation lesen** der schnellste Loesungsweg. + +Am Beispiel von Ant Design: Die Dokumentations-Adresse lautet `https://ant.design/components/overview-cn` + +Standardablauf zum Lesen der Dokumentation: + +1. **Anforderung klarstellen**: Zum Beispiel "Ich brauche eine Tabelle mit Zeilenauswahl" +2. **In der Dokumentation suchen**: Nach "Table" suchen, um zur Tabellen-Komponenten-Seite zu gelangen +3. **Beispiele ansehen**: Jede Komponente hat mehrere Online-Beispiele in der Dokumentation; das "Auswaehlbar"-Beispiel finden +4. **Code kopieren**: Den Beispielcode in dein Projekt kopieren +5. **API-Tabelle ansehen**: Unten auf der Seite die vollstaendigen Konfigurationsoptionen fuer die `rowSelection`-Eigenschaft finden + +> Du kannst auch den Dokumentations-Link direkt an die AI IDE senden: "Bitte beziehe dich auf die rowSelection-API unter https://ant.design/components/table-cn und fuege der Nutzertabelle eine Mehrfachauswahl-Funktion hinzu." Wenn AI ein Dokumentations-Link zur Verfuegung steht, ist der generierte Code genauer. + +Schnellreferenz der Dokumentations-Adressen der Komponentenbibliotheken: + +| Komponentenbibliothek | Dokumentations-Adresse | +| :--- | :--- | +| Ant Design | `https://ant.design/components/overview-cn` | +| shadcn/ui | `https://ui.shadcn.com/docs/components` | +| HeroUI | `https://heroui.com/docs/components` | +| Material UI | `https://mui.com/material-ui/all-components/` | +| Element Plus | `https://element-plus.org/zh-CN/component/overview.html` | + +## 7. Zusammenfassung + +Die drei praktischen Szenarien decken die haeufigsten Frontend-Entwicklungsanforderungen ab: + +| Szenario | Empfohlene Komponentenbibliothek | Kernmerkmal | +| :--- | :--- | :--- | +| Landing-Page / Praesentations-Seite | HeroUI | Standardmaessig schoene Stiles, fluessige Animationen, starke visuelle Wirkung | +| Produkt-Funktionsseite | shadcn/ui | Code vollstaendig kontrollierbar, hochgradig anpassbar | +| Backend-Verwaltungssystem | Ant Design | Reichhaltige Geschaeftskomponenten, Tabellen und Formulare sofort einsatzbereit | + +Zusammenfassung des Vibe Coding-Workflows: + +1. Basierend auf dem Szenario die passende Komponentenbibliothek auswaehlen +2. Mit AI IDE die gewuenschte Seitenstruktur und Interaktionen beschreiben +3. AI generiert den ersten Code-Entwurf, du schaust dir das Ergebnis an +4. Mit natuerlicher Sprache weiter iterieren und anpassen +5. Bei Detailproblemen die Komponentenbibliothek-Dokumentation konsultieren + +### Uebung + +Waehle eines der folgenden Szenarien und schliesse es von Grund auf mit AI IDE + Komponentenbibliothek ab: + +1. Verwende HeroUI, um eine Praesentations-Landing-Page fuer ein deiner frueheren Projekte (z. B. Hogwarts-Portraets) zu erstellen +2. Verwende shadcn/ui, um das Haupt-Interface einer Notiz-App zu erstellen (Seitenleiste + Editor) +3. Verwende Ant Design, um ein einfaches Content-Management-Backend zu erstellen (Artikelliste + Formular zum Erstellen neuer Artikel) + +--- + +## Anhang: Weitere Komponentenbibliotheken im Ueberblick + +Zusaetzlich zu den vier Kern-Bibliotheken im Haupttext gibt es im Frontend-Oekosystem eine grosse Anzahl hervorragender Komponentenbibliotheken. Die folgende Liste ist nach Frameworks kategorisiert, um die Auswahl basierend auf Projektanforderungen zu erleichtern. + +### Vue-Oekosystem + +| Komponentenbibliothek | Stars | Kurzbeschreibung | Anwendungsbereich | +| :--- | :--- | :--- | :--- | +| [Element Plus](https://element-plus.org) | ~27k | Enterprise-Komponentenbibliothek fuer Vue 3 vom Ele.me-Team, am weitesten verbreitet in China | Backend-Verwaltungssysteme | +| [Vuetify](https://vuetifyjs.com) | ~41k | Die populaerste Vue Material Design-Komponentenbibliothek, 80+ Komponenten, vollstaendige Dokumentation | Google Design-Stil-Projekte | +| [Ant Design Vue](https://antdv.com) | ~21k | Vue 3-Komponentenbibliothek basierend auf dem Ant Design-System | Enterprise-Backends | +| [Naive UI](https://www.naiveui.com) | ~18k | In TypeScript geschrieben, extrem anpassbare Themen, unabhaengig von CSS-Präprozessoren | Projekte mit speziellen Design-Anforderungen | +| [Quasar](https://quasar.dev) | ~27k | Ein Codebasis fuer SPA, SSR, PWA, Mobile und Desktop | Cross-Platform-Projekte | +| [Vant](https://vant-ui.github.io/vant) | ~24k | Leichtgewichtige Mobile-Komponentenbibliothek vom Youzan-Team | Mobile H5-Seiten | +| [PrimeVue](https://primevue.org) | ~14k | 90+ Komponenten, unterstuetzt verschiedene Themen (Material, Bootstrap etc.) | Viele Komponenten und mehrere Themen erforderlich | +| [Arco Design Vue](https://arco.design/vue) | ~3k | Von ByteDance, hohe Komponentenqualitaet, integriertes Dark Mode | Backend-Produkte | +| [TDesign Vue Next](https://tdesign.tencent.com/vue-next) | ~2k | Von Tencent, einheitliche Designsprache | Tencent-Oekosystem oder Enterprise-Projekte | + +### React-Oekosystem + +| Komponentenbibliothek | Stars | Kurzbeschreibung | Anwendungsbereich | +| :--- | :--- | :--- | :--- | +| [Material UI (MUI)](https://mui.com) | ~95k | Aelteste Implementierung der Google Material Design-Richtlinien, umfassendste Komponenten, reifstes Oekosystem | Schneller Aufbau von Enterprise-Anwendungen | +| [Ant Design](https://ant.design) | ~94k | Von Ant Group, viele hochwertige integrierte Geschaeftskomponenten, dominante Position in der chinesischsprachigen Entwickler-Community | Enterprise-Backends | +| [shadcn/ui](https://ui.shadcn.com) | ~83k | Code wird in das Projekt kopiert statt als npm installiert, basiert auf Radix UI + Tailwind CSS, vollstaendig kontrollierbar | Projekte mit hohem Anpassungsbedarf | +| [Chakra UI](https://chakra-ui.com) | ~39k | Mit Fokus auf Entwicklererfahrung, praegnant API, integrierte Barrierefreiheit | Schnelle Prototyp-Entwicklung | +| [Mantine](https://mantine.dev) | ~28k | 100+ Komponenten und 50+ Hooks, inklusive DatePicker, Rich-Text-Editor und weitere fortgeschrittene Komponenten | All-in-One-Loesung | +| [Headless UI](https://headlessui.com) | ~27k | Offizielle ungestylte Komponentenbibliothek von Tailwind Labs, unterstuetzt sowohl React als auch Vue | In Kombination mit Tailwind CSS | +| [HeroUI](https://heroui.com) | ~24k | Basierend auf Tailwind CSS + React Aria, standardmaessig schoene Stiles, fluessige Animationen | Projekte mit hohen visuellen Anforderungen | +| [Radix UI](https://www.radix-ui.com) | ~17k | Ungestylte Low-Level-Komponenten-Primitivbibliothek mit Fokus auf Barrierefreiheit und Komponentenverhalten, Basis von shadcn/ui | Aufbau eigener Designsysteme | + +#### shadcn/ui-Erweiterungs-Oekosystem + +Zusaetzlich zu den oben genannten allgemeinen Komponentenbibliotheken ist im shadcn/ui-Oekosystem eine grosse Zahl von Erweiterungsbibliotheken entstanden, die auf derselben Philosophie basieren und differenzierte Loesungen fuer spezifische Szenarien bieten. Diese Erweiterungsbibliotheken verwenden ebenfalls den "Code ins Projekt kopieren"-Ansatz und geben Entwicklern die volle Quellcode-Kontrolle. + +| Komponentenbibliothek | Kurzbeschreibung | Anwendungsbereich | +| :--- | :--- | :--- | +| [Aceternity UI](https://ui.aceternity.com) | 200+ produktionsreife Komponenten, Spezialitaet: leuchtende Karten, Text-Gradienten, 3D-Globus und andere besondere visuelle Komponenten | Hochwertige Landing-Pages, SaaS-Produkte | +| [Tailark UI](https://tailark.com) | Sammlung von Marketing-Website-Komponenten-Bloecken, Produktpraesentation, Kunden-Testimonials, CTA-Buttons und weitere haeufige Marketing-Module | Marketing-Landing-Pages, Produkt-Websites | +| [UI Tripled](https://ui.tripled.work) | Dynamische Interaktionskomponenten basierend auf Framer Motion, Popups, Navigation, Karten-Animationen | Kreativ-Tools, persoenliche Portfolios | +| [Neobrutalism UI](https://neobrutalism.dev) | Neobrutalismus-Stil, dicke Linien, hoher Kontrast, kraeftige Farben | Individualisierte Marken-Websites, Kreativ-Projekte | +| [REUI](https://reui.io) | 967+ Komponenten-Kombinationsmuster fuer echte Geschaeftsszenarien | Enterprise-Backends, komplexe Formulare | +| [Cult UI](https://cult-ui.com) | Feinere Interaktions-/Visuelle-Details, Datentabellen, Filter-Panels und andere zusammengesetzte Komponenten | Hochwertige kommerzielle Projekte | +| [Kibo UI](https://kibo-ui.com) | Fortgeschrittene Geschaeftskomponenten, Farbwahl, Rich-Text-Editor, Datei-Upload | Verwaltungs-Backends, Werkzeug-Produkte | +| [Kokonut UI](https://kokonutui.com) | 100+ Komponenten + 7+ vollstaendige Templates, frischer minimalistischer Stil | SaaS-Websites, Blogs, E-Commerce | +| [Commerce UI](https://ui.stackzero.co) | Speziell fuer E-Commerce-Szenarien, Produktkarten, Warenkorb, Checkout-Formulare | E-Commerce-Plattformen | +| [shadcnblocks](https://shadcnblocks.com) | 1373 UI-Bloecke + 13 vollstaendige Templates, umfassendste Ressource | Alle Szenarien | +| [Shoogle](https://shoogle.dev) | shadcn/ui-Oekosystem-Aggregations- und Suchplattform | Schnelles Auffinden von Ressourcen | +| [Discover All Shadcn](https://allshadcn.com) | Aggregierte Ressourcen-Navigation | Schnelles Auffinden von Ressourcen | + +> **Warum shadcn/ui-Erweiterungen waehlen?** Diese Erweiterungen uebernehmen die Philosophie von shadcn/ui "Code-Eigentum" und bieten gleichzeitig tiefgehende Spezialisierung fuer bestimmte Szenarien. In der Vibe-Coding-Aera ermoeglichen sie es, schnell Komponenten zu finden, die den Designanforderungen entsprechen, die Homogenitaet der Mainstream-UI-Bibliotheken zu ueberwinden und differenziertere Produkte zu erstellen. diff --git a/docs/de-de/stage-2/frontend/multi-product-ui/index.md b/docs/de-de/stage-2/frontend/multi-product-ui/index.md new file mode 100644 index 0000000..e3e1381 --- /dev/null +++ b/docs/de-de/stage-2/frontend/multi-product-ui/index.md @@ -0,0 +1,425 @@ +# Seiten und Buttons nach UI-Designrichtlinien entwerfen + +Viele Menschen sagen: "Ich moechte, dass die Seite ein bisschen mehr wie Apple aussieht" oder "Die Buttons sollten etwas hochwertiger wirken". Aber wenn es dann an die Umsetzung geht, haengt man oft an einer Frage fest: + +**Woran sollte man sich eigentlich orientieren?** + +Einen Screenshot abzubilden, bringt nur die Erkenntnis "Aehnlichkeit". Wenn man jedoch die Designrichtlinien von Apple, Google, Microsoft und Atlassian oeffnet, stellt man fest, dass deren wahre Staerke nicht im visuellen Stil liegt, sondern darin, **Designprobleme klar zu benennen**: Was auf einer Seite zuerst hervorgehoben wird, wie Buttons gestuft werden, welche Operationen betont werden -- diese Beurteilungskriterien sind der Kern. + +> Sich an Designrichtlinien zu orientieren, heisst nicht, "wie jemand anderes auszusehen", sondern zu lernen, wie andere Urteile faellen. + +:::: info Warum man diese heute noch lernen sollte +Designregeln sind bereits in Modelle trainiert und werden von Designtools standardmaessig absorbiert. Selbst wenn man AI ein paar Screenshots gibt, kann sie diese erlernen. Dennoch ist es wichtig zu wissen, woher diese Regeln kommen und warum sie so definiert sind. +:::: + +## Zunaechst einige Originalzitate, um den Unterschied zu spueren + +Wenn du bisher dachtest, "Designrichtlinien handeln doch nur von Stil", dann lies zuerst einige offizielle Originaltexte. + +Im Team sagt man oft Dinge wie: + +- Mach mal ein Dropdown +- Hier ein Menu hinsetzen +- In der Menueleiste ein paar Funktionen hinzufuegen +- Hier zwei Buttons, einer zum Bestaetigen und einer zum Abbrechen + +Das klingt unproblematisch, aber in den grossen Unternehmensrichtlinien sind diese Begriffe keine verschwommenen Konzepte, sondern sehr fein unterteilt. + +| Was man umgangssprachlich sagt | Offizieller Originaltext | Kurz gesagt | +| :--- | :--- | :--- | +| "Ein Menu erstellen" | Apple: ["A menu reveals its options..."](https://developer.apple.com/design/human-interface-guidelines/menus) | `Menu` dient der Durchfuehrung von Aktionen | +| "Funktionen in die Menueleiste" | Apple: ["menu bar menus contain all the commands..."](https://developer.apple.com/design/human-interface-guidelines/menus) | Dies ist das Befehlsmenue oben in der App | +| "Ein Dropdown erstellen" | Apple: ["A pop-up list lets the user choose one option among several."](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pop-up` dient der Auswahl eines Werts aus einer Liste | +| "Auch ein Dropdown" | Apple: ["A pull-down list is generally used for selecting commands in a specific context."](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pull-down` oeffnet sich fuer die aktuelle Aktion | +| "Menu kann man auch zum Filtern nutzen" | Fluent: ["If you need to collect information from people, try a select, dropdown, or combobox instead."](https://fluent2.microsoft.design/components/web/react/core/menu/usage) | `Menu` ist nicht zur Werterfassung gedacht | +| "Menu kann man auch als Navigation nutzen" | Material: ["Menus should not be used as a primary method for navigation within an app."](https://m1.material.io/components/menus.html) | `Menu` ist keine Hauptnavigation | +| "Button einfach OK / Cancel schreiben" | Apple: ["Always use 'Cancel' to title a button that cancels the alert's action."](https://developer.apple.com/design/human-interface-guidelines/alerts) | Button-Text darf nicht willkuerlich sein | + +> Die Zitate in der Tabelle sind direkt klickbar und fuehren zur entsprechenden offiziellen Seite. + +Genau das ist es, woran man beim ersten echten Blick in Designrichtlinien am leichtesten erschrickt: + +> Wir glauben oft, wir wuerden ueber UI diskutieren, aber tatsaechlich kommunizieren wir meistens nur mit einer Reihe vager Begriffe. + +Apple wuerde niemals nur sagen "ein Menu erstellen"; es wuerde weiter unterscheiden in: + +- `menu` +- `menu bar menu` +- `pop-up button` +- `pull-down button` +- `context menu` + +Fluent wuerde niemals nur sagen "ein Dropdown"; es wuerde weiter unterscheiden in: + +- `menu` +- `dropdown` +- `select` +- `combobox` + +Genau das ist die Notwendigkeit von Designrichtlinien. + +Sie dienen nicht dazu, Seiten professioneller wirken zu lassen, sondern sicherzustellen, dass im Team bei UI-Diskussionen nicht jeder etwas anderes im Kopf hat. + +## Was du lernen wirst + +1. Warum man beim Entwerfen von Seiten und Buttons zuerst die Designrichtlinien lesen sollte +2. Welche Inhalte der Richtlinien von Apple, Material, Fluent und Atlassian am referenzwuerdigsten sind +3. Wie man "Seitenhierarchie" und "Button-Hierarchie" klar gestaltet +4. Wie man AI dazu bringt, sich an den Richtlinien anderer zu orientieren, um Seiten und Buttons zu generieren + +## 1. Warum Designrichtlinien dir helfen, Seiten klar zu gestalten + +Nach dem Lesen der obigen Originalzitate faellt ein Schluesselpunkt auf: + +**Designrichtlinien sind kein zusaetzlicher Luxus, sondern sorgen zunaechst dafuer, dass die Begriffe praezise verwendet werden.** + +Viele Seiten sehen nicht gut aus, nicht weil die Farbgebung nicht hochwertig genug ist, sondern weil die Informationsebenen chaotisch sind. + +Viele Buttons sind nicht benutzerfreundlich, nicht weil die Abrundung falsch ist, sondern weil: + +- Es zu viele Haupt-Buttons gibt und die Nutzer nicht wissen, welchen sie klicken sollen +- Gefaehrliche und normale Buttons aehnlich aussehen +- Alle Buttons auf der Seite um Aufmerksamkeit konkurrieren +- Button-Stil und Semantik ueber verschiedene Seiten hinweg inkonsistent sind + +Ausgereifte Designrichtlinien loesen genau diese Probleme. Sie definieren in der Regel: + +| Inhalt der Richtlinie | Welches Problem es loest | +| :--- | :--- | +| **Seitenhierarchie** | Wohin man zuerst schaut, wohin spaeter, wie Informationen organisiert werden | +| **Visuelle Grundlagen** | Wie Farben, Abstaende, Schriften, Abrundungen und Schatten vereinheitlicht werden | +| **Button-Hierarchie** | Wie Haupt-, Neben-, Text- und Gefahren-Buttons unterschieden werden | +| **Zustandsregeln** | Wie hover, focus, disabled und loading dargestellt werden | +| **Interaktionssemantik** | Welcher Button "bestaetigen", "abbrechen" und "weitere Aktionen" bedeutet | + +Designrichtlinien liefern also nicht einfach einen "Skin", sondern ein **Beurteilungskriterium**. + +## 2. Worauf man bei den grossen Unternehmensrichtlinien achten sollte + +### 2.1 Von Apple lernen: "Definitionen fein genug zu fassen" + +Das Lernwertste bei Apple ist nicht nur die visuelle Zurueckhaltung, sondern dass es Konzepte sehr fein definiert. + +Das, was in vielen Teams nur "Menu" oder "Dropdown" heisst, wird bei Apple weiter unterteilt: + +- `menu`: Eine Gruppe von Befehlen, Optionen oder Zustaenden +- `menu bar menu`: App-weite Befehlssammlung +- `pop-up button`: Einen Wert auswaehlen +- `pull-down button`: Im aktuellen Kontext einen Befehl ausloesen +- `context menu`: Haeufige Aktionen bezogen auf das aktuelle Objekt oder die aktuelle Aufgabe + +Diese Unterscheidung ist sehr wichtig, da sie sich direkt darauf auswirkt: + +- Ob die Komponente zur Werterfassung oder zur Aktionsausfuehrung dient +- Ob sie zum Seitenbereich oder zur App-Ebene gehoert +- Ob sie den aktuell ausgewaehlten Wert dauerhaft anzeigen soll oder nur temporaer Befehle aufklappt + +Wenn du in dieser Granularitaet zu denken beginnst, werden deine Seiten sofort deutlich klarer. + +### 2.2 Von Apple lernen: Seitenhierarchie und Zurueckhaltung + +Die Apple Human Interface Guidelines eignen sich besonders gut, um zwei Dinge zu lernen: + +- Wie Seiten eine klare Hierarchie aufbauen +- Wie Steuerelemente eindeutig bleiben, ohne aufdringlich zu wirken + +Apple betont `Hierarchy`, `Harmony` und `Consistency`. Das bedeutet, dass beim Seitendesign folgende Fragen beantwortet werden muessen: + +- Was ist die wichtigste Information auf der aktuellen Seite? +- Was ist die Hauptaufgabe des Nutzers? +- Welche Operation am auffaelligsten sein sollte und welche in den Hintergrund gehoert + +Wenn du dich an Apple orientierst, kannst du besonders folgende Aspekte uebernehmen: + +- Die Informationen auf dem ersten Bildschirm sollten nicht zu fragmentiert sein; der Kerninhalt steht im Fokus +- Ordnung durch Freiraum, Schriftgroessen und Gruppierung schaffen, statt viele Rahmen zu stapeln +- Nicht alle Buttons sollten stark hervorgehoben sein; nur die wichtigsten Aktionen sollten am auffaelligsten sein + +### 2.3 Von Material lernen: Klarere Seitenstruktur + +Material Design eignet sich besonders gut, um zu lernen, "wie Seiten Aufgabenstroeme organisieren". + +Viele seiner Komponenten- und Layoutrichtlinien zielen darauf ab, Folgendes klarzustellen: + +- Ob eine Seite zum Durchsuchen oder zur Aufgabenausfuehrung dient +- Ob die aktuelle Seite Nutzer zum Lesen, Auswaehlen oder Absenden veranlassen soll +- Welche Elemente auf einer Seite stabil wiederkehren sollten und welche sich dynamisch an den Kontext anpassen + +Wenn du dich an Material orientierst, kannst du besonders folgende Aspekte uebernehmen: + +- Seitenbereiche klar strukturieren, Modulverantwortlichkeiten eindeutig definieren +- Navigation, Inhalts- und Aktionsbereiche sauber trennen +- Unterschiedliche Button-Stile entsprechen unterschiedlichen Operationsprioritaeten + +### 2.4 Von Fluent lernen: Komponentengrenzen und Button-Hierarchie + +Fluent 2 eignet sich besonders fuer Backends, Werkzeug-Produkte und komplexe Formularsysteme. Das Lernenswerteste daran ist, dass es dir direkt sagt: "Konzepte nicht vermischen." + +Es schreibt beispielsweise ausdruecklich: Wenn du "collect information" moechtest, solltest du nicht weiterhin `menu` verwenden, sondern `select`, `dropdown` oder `combobox` in Betracht ziehen. + +Dieser Satz ist sehr wichtig, da er das, was viele Menschen fuer "ungefaehr gleich" halten, aufbrechen laesst. + +Fluent 2 legt auch grossen Wert auf: + +- Aktionsebenen +- Komponenten-Semantikgrenzen +- Klarheit in dichten Informationsszenarien + +Wenn du dich an Fluent orientierst, um Buttons zu gestalten, kannst du besonders folgende Aspekte uebernehmen: + +- `Primary button` fuer die aktuell wichtigste Aktion +- `Secondary button` fuer unterstuetzende Aktionen +- `Subtle` und `Transparent` als schwach betonte Buttons fuer Aktionen, die den Hauptprozess nicht stoeren sollten +- Je mehr Buttons auf einer Seite, desto wichtiger ist die Kontrolle der visuellen Prioritaet + +### 2.5 Von Atlassian lernen: Systematisches Verwalten von Seiten und Buttons + +Das Atlassian Design System eignet sich besonders fuer den Fall, dass "ein Team viele Seiten erstellt". Es betont: + +- foundations als gemeinsame Basis +- tokens als Methode zur einheitlichen visuellen Entscheidungsfindung +- components als wiederholt verwendete Interaktionsbausteine + +Wenn du dich an Atlassian orientierst, um Seiten und Buttons zu gestalten, ist das Wertvollste: + +- Button-Groesse, Farbe, Abrundung und Abstaende als einheitliche Regeln definieren +- Den Rhythmus des Seitenlayouts festigen +- Sicherstellen, dass verschiedene Seiten trotz unterschiedlicher Inhalte eine einheitliche Struktursprache verwenden + +## 3. Worauf man beim Entwerfen von Seiten aus den Richtlinien absehen sollte + +Wenn du ein Designsystem betrachtest, frage nicht zuerst "Sieht diese Seite gut aus?", sondern stelle zunaechst die folgenden Fragen. + +### 3.1 Erster Blick auf die Seite: Ist die Hierarchie klar? + +Eine Seite sollte in der Regel mindestens drei Ebenen haben: + +- **Hauptinformation**: Der wichtigste Inhalt der aktuellen Seite +- **Unterstuetzende Informationen**: Inhalte zum besseren Verstaendnis oder zur Ergaenzung +- **Sekundaere Aktionen**: Aktionen, die die Hauptaufgabe nicht stoeren sollten + +Wenn die drei Ebenen nicht deutlich getrennt sind, wirkt die Seite "alles wichtig" -- was gleichbedeutend mit "nichts ist wichtig" ist. + +### 3.2 Seitenlayout: Dient es der Aufgabe oder stapelt es nur Module? + +Beim Durcharbeiten der Richtlinien solltest du besonders darauf achten: + +- Ob der Titelbereich das Seitenziel klar benennt +- Ob der Hauptinhaltsbereich um die Aufgabe herum organisiert ist +- Ob die Aktions-Buttons nah an den zugehoerigen Inhalten platziert sind +- Ob unwichtige Informationen abgeschwaecht wurden + +### 3.3 Haben die Aktionen auf der Seite eine Prioritaet? + +Viele Seiten haben auf den ersten Blick 6 Buttons, und jeder sieht wie ein CTA aus -- das ist ein klassischer Hierarchieverlust. + +Sinnvoller ist: + +- Ein Bereich hat in der Regel nur eine Hauptaktion +- Sekundaere Aktionen koennen mit Umrandungen, Text-Buttons oder schwaecherem Stil dargestellt werden +- Risikoaktionen sollten nicht genauso aussehen wie die Hauptaktion + +## 4. Worauf man beim Entwerfen von Buttons aus den Richtlinien absehen sollte + +Buttons sind der am leichtesten "beilaeufig gestaltete" Teil, aber auch der Teil, der am meisten darueber verraet, ob ein System ausgereift ist. + +### 4.1 Buttons zunaechst nach "Semantik" unterscheiden, dann nach "Stil" + +Denke nicht zuerst "blauer oder schwarzer Button", sondern darueber, welche Rolle dieser Button spielt. + +Haeufige Button-Rollen koennen wie folgt kategorisiert werden: + +| Button-Typ | Funktion | Haeufige Stilstrategie | +| :--- | :--- | :--- | +| **Primary** | Die wichtigste Aktion im aktuellen Bereich | Ausgefuellt, hoher Kontrast, am auffaelligsten | +| **Secondary** | Unterstuetzende Aktionen | Umrandet oder eine Stufe schwaecher betont | +| **Tertiary / Text** | Schwache Aktionen | Text oder geringer visueller Anteil | +| **Destructive** | Risikoaktionen wie Loeschen, Deaktivieren, Leeren | Warnfarbe oder eindeutiger Risiko-Stil | +| **Icon button** | Lokale Werkzeugaktionen | Kompakt, nah am Kontext | + +### 4.2 Nicht zu viele Primary Buttons auf einer Seite + +Das ist die haeufigste Falle fuer Anfaenger. + +Wenn 4 Haupt-Buttons auf einer Seite sind, gibt es faktisch keinen Haupt-Button. Die Bedeutung eines Haupt-Buttons besteht ja gerade darin, "dem Nutzer zu sagen, was er jetzt am besten tun sollte". + +Du kannst die gemeinsame Praxis vieler Designsysteme uebernehmen: + +- Ein Hauptbereich hat in der Regel nur einen Haupt-Button +- Abbrechen, Zurueck und Schliessen konkurrieren in der Regel nicht auf derselben Ebene mit dem Bestaetigungs-Button +- Weitere Aktionen in sekundaere Buttons oder Menus auslagern + +### 4.3 Buttons muessen Zustandsaenderungen ausdruecken koennen + +Designrichtlinien beschreiben Button-Zustaende in der Regel sehr detailliert: + +- Standardzustand +- Hover-Zustand +- Fokus-Zustand +- Deaktivierter Zustand +- Ladezustand +- Gefahrenzustand + +Das ist wichtig, da ein Button kein statisches Bild ist, sondern eines der am haeufigsten ausgeloesten Steuerelemente waehrend der Benutzerinteraktion. + +### 4.4 Button-Beschriftung gehoert ebenfalls zum Design + +Die Button-Beschriftung ist nicht nur eine "Textfrage" -- sie beeinflusst das Nutzerverstaendnis direkt. + +Beispiele: + +- `Speichern` +- `Aenderungen speichern` +- `Sofort veroeffentlichen` +- `Projekt loeschen` +- `In den Papierkorb verschieben` + +Diese Beschriftungen vermitteln vollkommen unterschiedliche psychologische Erwartungen. Ausgereifte Richtlinien verlangen in der Regel, dass Button-Labels die Aktion klar ausdruecken, anstatt vage Begriffe zu verwenden. + +## 5. Eine sehr praktische Checkliste fuer Seiten- und Button-Design + +Wenn du selbst eine Seite entwirfst, kannst du zunaechst diese Checkliste schnell durchgehen: + +### Seiten-Checkliste + +- Ob der Seitentitel die aktuelle Aufgabe klar beschreibt +- Ob die wichtigste Information auf dem ersten Bildschirm sofort sichtbar ist +- Ob die Seite nach dem Aufgabenfluss und nicht nach dem organisiert ist, was einem gerade einfaellt +- Ob es in einem Bereich nur eine Hauptaktion gibt +- Ob unwichtige Inhalte angemessen abgeschwaecht wurden + +### Button-Checkliste + +- Ist dieser Button eine Haupt- oder Nebention? +- Warum sollte dieser Button auffaelliger sein als die anderen? +- Gibt es zu viele Haupt-Buttons auf der Seite? +- Sind Gefahrenaktionen eindeutig markiert? +- Ist die Button-Beschriftung konkret genug? + +## 6. Wie man AI dazu bringt, sich an den Richtlinien anderer zu orientieren + +Dieser Abschnitt ist am praktischsten. + +Viele Menschen sagen zu AI beim Entwerfen von Seiten nur: + +```md +Mach mir eine Einstellungsseite, die etwas hochwertiger aussehen soll, im Apple-Stil +``` + +Solche Prompts sind zu vage -- AI kann am Ende meist nur "weisser Hintergrund, abgerundete Ecken, Schatten" imitieren. + +Fuer Anfaenger ist der praktischste Ansatz nicht, selbst eine lange Zusammenfassung zu schreiben, sondern die **Schluesselsaetze aus dem Originaltext der Richtlinie** direkt in AI einzufuegen. + +Das hat zwei Vorteile: + +- Du musst die Designphilosophie nicht selbst "uebersetzen" +- AI kann die Seite und die Buttons leichter gemaess den offiziellen Definitionen verstehen + +### 6.1 Beispiel 1: AI bitten, eine Einstellungsseite nach Apple-Design zu erstellen + +Zunaechst ein Originalzitat von Apple: + +> ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) + +Du kannst AI direkt so ansprechen: + +```md +Beziehe dich auf diesen Satz aus den Apple Human Interface Guidelines: +"Establish a clear visual hierarchy..." + +Erstelle eine Kontosicherheit-Einstellungsseite. +Die Seitenhierarchie soll klar sein, wichtige Informationen zuerst, ordentlich gruppiert. +``` + +Der Punkt dabei ist: Du musst nicht viel selbst erklaeren -- einfach den Originaltext von Apple einfuegen. + +### 6.2 Beispiel 2: AI bitten, Backend-Buttons nach Fluent zu gestalten + +Zunaechst ein Originalzitat von Fluent: + +> ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +Du kannst AI direkt so ansprechen: + +```md +Beziehe dich auf diesen Satz aus Fluent 2: +"Only use one primary button in a layout..." + +Gestalte die Buttons fuer ein Team-Management-Backend. +Der "Mitglied hinzufuegen"-Button am auffaelligsten, Export, Filter, weitere Aktionen schwaecher, und der Loeschen-Button gesondert hervorheben. +``` + +Dieser Satz eignet sich hervorragend fuer Anfaenger, da er AI direkt sagt: In einem Bereich nicht zu viele Haupt-Buttons platzieren. + +### 6.3 Beispiel 3: AI bitten, sich gleichzeitig an Seiten- und Button-Richtlinien zu orientieren + +Du kannst auch zwei Originalzitate gleichzeitig einfuegen und AI bitten, sich sowohl an der Seiten- als auch an der Button-Richtlinie zu orientieren: + +> Apple: ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) +> +> Fluent: ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +Dann schreibst du einfach: + +```md +Beziehe dich auf die folgenden zwei Designrichtlinien-Originalsaetze: +Apple: "Establish a clear visual hierarchy..." +Fluent: "Only use one primary button in a layout..." + +Erstelle eine Projektdetailseite. +Die Seite enthaelt Projektbeschreibung, Mitglieder, letzte Aktivitaeten und einen Einstellungseinstieg. +Die Seitenhierarchie soll klar sein, nur einen Haupt-Button behalten, die anderen schwaecher darstellen. +``` + +Dieser Ansatz eignet sich besonders fuer Anfaenger, da du nur den Originaltext kopieren und ein bis zwei Saetze eigener Anforderungen hinzufuegen musst. + +## 7. Wie man AI dazu bringt, sich an Button-Richtlinien zu orientieren, um direkt Button-Designs zu generieren + +Wenn du zunaechst nur Buttons erstellen moechtest, kannst du auch direkt die Originaltexte der Button-Richtlinien einfuegen. + +Beispielsweise ist die Definition von Atlassian fuer Buttons sehr kurz: + +> ["A button triggers an event or action."](https://atlassian.design/components/button/) + +Du kannst AI so fragen: + +```md +Beziehe dich auf diesen Satz von Atlassian: +"A button triggers an event or action." + +Gestalte einen Satz von Backend-Button-Stilen. +Ich moechte einen Haupt-Button, einen Neben-Button und einen Loeschen-Button, und erzaehle mir bitte, wo jeweils welcher verwendet wird. +``` + +Diese Art von Prompt eignet sich besonders fuer Anfaenger -- im Grunde heisst es "Originaltext einfuegen + Anforderungen nennen". + +## 8. Zusammenfassung + +Sich an UI-Designrichtlinien zu orientieren, wenn man Seiten und Buttons entwirft, heisst nicht "auszusehen wie jemand anderes", sondern folgende Dinge zu lernen: + +1. Seiten mit Hierarchie organisieren, anstatt Inhalte einfach zu stapeln +2. Operationsprioritaeten durch Button-Stufung ausdruecken, anstatt alle Buttons gleich aufdringlich zu machen +3. Sich bei der Gestaltung an den Definitionen, Grenzen und Beurteilungskriterien der Designrichtlinien orientieren +4. Wenn AI sich an den Richtlinien anderer orientiert, sollte sie sich an "Prinzipien und Struktur" orientieren, nicht nur an der Oberflaeche + +Wenn du Richtlinien so verwendest, referenzierst du nicht nur einen Stil, sondern eine ausgereifte Design-Denkweise. + +--- + +## Referenzmaterialien + +Die folgenden Links stammen alle von offiziellen Designsystemen oder offizieller Dokumentation: + +- Apple Human Interface Guidelines: [Overview](https://developer.apple.com/design/human-interface-guidelines/) +- Apple Human Interface Guidelines: [Menus](https://developer.apple.com/design/human-interface-guidelines/menus) +- Apple Human Interface Guidelines: [Alerts](https://developer.apple.com/design/human-interface-guidelines/alerts) +- Apple Human Interface Guidelines: [Buttons](https://developer.apple.com/design/human-interface-guidelines/buttons) +- Apple Archive: [How Menus Work](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/HowMenusWork.html) +- Apple Archive: [Managing Pop-Up Buttons and Pull-Down Lists](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) +- Material Design: [Buttons overview](https://m3.material.io/components/buttons/overview) +- Material Design: [Menus](https://m1.material.io/components/menus.html) +- Microsoft Fluent 2: [Start designing](https://fluent2.microsoft.design/get-started/design) +- Microsoft Fluent 2: [Menu usage](https://fluent2.microsoft.design/components/web/react/core/menu/usage) +- Microsoft Fluent 2: [Button usage](https://fluent2.microsoft.design/components/web/react/core/button/usage) +- Atlassian Design System: [Foundations](https://atlassian.design/foundations/) +- Atlassian Design System: [Button](https://atlassian.design/components/button/) diff --git a/docs/de-de/stage-2/frontend/ui-design/index.md b/docs/de-de/stage-2/frontend/ui-design/index.md new file mode 100644 index 0000000..4ef5a5e --- /dev/null +++ b/docs/de-de/stage-2/frontend/ui-design/index.md @@ -0,0 +1,3 @@ +# Deine erste moderne App erstellen - UI-Design + +> Dieses Kapitel wird derzeit erstellt. Bitte schaue spaeter vorbei... diff --git a/docs/de-de/stage-2/index.md b/docs/de-de/stage-2/index.md index 2c6c832..5972e29 100644 --- a/docs/de-de/stage-2/index.md +++ b/docs/de-de/stage-2/index.md @@ -1,126 +1,193 @@ -# Full-Stack-Entwicklung +# Junior- und Mittelstufen-Entwicklung -Willkommen in der Phase **Full-Stack-Entwicklung**! Hier wirst du dich tief mit der Full-Stack-Entwicklung beschäftigen, Frontend-Komponentisierung, Datenbankdesign, Backend-API-Entwicklung und Deployment beherrschen. +Willkommen in der Phase **Junior- und Mittelstufen-Entwicklung**! Hier wirst du dich tief mit der Full-Stack-Entwicklung beschaeftigen, Frontend-Komponentisierung, Datenbankdesign, Backend-API-Entwicklung und Deployment beherrschen. ## Was du lernen wirst ### Frontend-Entwicklung Beherrsche moderne Frontend-Entwicklung und lerne die Verwendung von Komponentenbibliotheken und Designtools: + + + + +### Backend-Entwicklung -### Backend und Full-Stack +API-Design, Datenbankverwaltung und Anwendungs-Deployment-Strategien lernen: -Lerne API-Design, Datenbankverwaltung und Anwendungs-Deployment-Strategien: - +### Grossaufgaben -### Aufgaben +Die vorherigen Kapitel behandeln die "Bauteile", die Grossaufgaben behandeln das "Zusammenbauen der Bauteile zu einem lauffaehigen, demonstrablen und veroeffentlichbaren Produkt". + +Es wird empfohlen, die Reihenfolge **Grossaufgabe 1 -> Grossaufgabe 2** zu befolgen: + +- **Grossaufgabe 1** fuehrt dich zuerst durch die haeufigste Hauptkette moderner SaaS: Login, Generierung, Datenbank, Zahlung, Admin-Panel. +- **Grossaufgabe 2** bringt dich dann in Szenarien, die eher Geschaeftssystemen aehneln: Rollenberechtigungen, Fragenbank, Pruefungen, Abgabeprotokolle, Admin-Konsole. + +```mermaid +flowchart LR + A["Frontend-Seiten und Komponenten"] --> B["Datenbank und Schnittstellen"] + B --> C["Grossaufgabe 1
Copywriting-Generierungs-SaaS"] + C --> D["Zahlung / Deployment / Admin-Verwaltung"] + D --> E["Grossaufgabe 2
Online-Pruefungssystem"] + E --> F["Vollstaendiges Full-Stack-Portfolio"] +``` + +Wenn du nicht weisst, womit du anfangen sollst, kannst du die folgende Vergleichstabelle als Referenz nutzen: + +| Projekt | Was du hauptsaechlich ueben wirst | Am besten geeignet fuer | Endabgabe | +|------|------|------|------| +| Grossaufgabe 1: Copywriting-Generierungs-Website | SaaS-Seitenstruktur, Benutzer-Login, KI-Generierung, Stripe-Zahlung, Admin-Panel | Personen, die zum ersten Mal eine vollstaendige kommerzielle Website erstellen | Ein SaaS-Prototyp mit Registrierung, Generierung, Zahlung und Verwaltung | +| Grossaufgabe 2: Online-Pruefungs- und Managementsystem | Rollenberechtigungen, Fragenbank-Modellierung, Pruefungsablauf, Abgabeprotokolle, Korrektur und Statistik | Personen, die ein "Geschaeftssystem" wirklich vervollstaendigen moechten | Eine Pruefungsplattform mit Studenten- und Admin-Ansicht | + +Unabhaengig davon, welche Aufgabe du waehlst, wird empfohlen, mindestens diese 3 Abgabeprodukte vorzubereiten: + +- Ein lauffaehiges Projekt-Repository +- Ein zugaenglicher Demonstrationslink +- Ein README und ein Demovideo -Festige deine Full-Stack-Entwicklungsfähigkeiten durch praktische Projekte: +Wenn du die beiden Hauptprojekte bereits abgeschlossen hast oder dein Portfolio nach deinem eigenen technischen Schwerpunkt erstellen moechtest, kannst du aus den folgenden erweiterten Themen eines fuer eine tiefere Bearbeitung auswaehlen: -### KI-Fähigkeitserweiterung + + + + +### KI-Faehigkeitserweiterung -## Für wen es ist + + + -- Entwickler mit einiger Programmiergrundlage, die systematisch Full-Stack-Entwicklung lernen möchten -- Lernende, die vom Produktmanager zum Full-Stack-Ingenieur wechseln möchten -- Junior- bis Mittelstufen-Entwickler, die moderne Entwicklungstools und Workflows beherrschen möchten -- Unternehmer, die unabhängig vollständige Produkte entwickeln möchten +## Fuer wen ist dies geeignet + +- Entwickler mit gewisser Programmiergrundlage, die systematisch Full-Stack-Entwicklung lernen moechten +- Lernende, die vom Produktmanager zum Full-Stack-Ingenieur wechseln moechten +- Junior- bis Mittelstufen-Entwickler, die moderne Entwicklungstools und Workflows beherrschen moechten +- Unternehmer, die unabhaengig vollstaendige Produkte entwickeln moechten ## Voraussetzungen -- Abschluss der Phase "Anfänger und Produktprototyp" oder gleichwertige Grundkenntnisse -- Verständnis grundlegender HTML/CSS/JavaScript-Konzepte -- Vorkenntnisse über KI-Programmierungstools +- Abschluss der Phase "Anfaenger und Produktprototyp" oder gleichwertige Grundkenntnisse + - Verstaendnis grundlegender HTML/CSS/JavaScript-Konzepte +- Grundkenntnisse ueber KI-Programmierungstools -Bereit, dich tief in die Full-Stack-Entwicklung zu vertiefen? Klicke auf die linke Navigation, um mit dem Lernen zu beginnen! +Bereit, dich in die Full-Stack-Entwicklung zu vertiefen? Klicke auf die linke Navigation, um mit dem Lernen zu beginnen! diff --git a/docs/es-es/stage-2/ai-capabilities/dify-knowledge-base/index.md b/docs/es-es/stage-2/ai-capabilities/dify-knowledge-base/index.md new file mode 100644 index 0000000..44f0c73 --- /dev/null +++ b/docs/es-es/stage-2/ai-capabilities/dify-knowledge-base/index.md @@ -0,0 +1,1044 @@ +# Dify 入门与知识库集成 + +# 回顾上节课 + +在前几节课中,我们分组学习了 AI 编程、提示词工程以及 AI 图像生成的基础知识。这些内容帮助我们初步了解了不同大语言模型(LLM,Large Language Model)或生成式模型的边界和能力。 + +为了帮助你回顾上节课的内容,下面有几个小问题可以思考: + +1. 什么是 AI 编程?如何使用 AI 编程工具(例如 [z.ai](http://z.ai))来创建一个网页? +2. 什么是大语言模型?什么是提示词工程和上下文工程?你该如何编写一个复杂的提示词? +3. 对于文本、AI Coding、图像生成的三个不同方向,你认为模型能力的强弱分别体现在什么地方? +4. 什么是 API?如何使用 [z.ai](http://z.ai) 接入第三方 API ? + +如果你对其中任何一个问题还感到疑惑,可以回看上节课的文档,也可以直接在微信群里提问。 + +在这节课中,我们将从简单的 AI 文字图片工具,进入更接近公司业务落地的工作流搭建平台。从对话机器人走向 AI 智能体、AI 工作流,并基于 API 把它变成可交互的“智能”机器人页面。 + +在操作过程中,如果遇到难以理解的步骤,请不要担心,推荐你随时对当前所在的操作页面进行截图,发送给大模型进行询问;当前大模型已能够解答大部分常见问题。 + +如果提问后仍无法解决,不妨大胆尝试操作;不必害怕出错,每一次尝试都是学习和进步的机会。随着实践次数的增加,你会越来越熟练,操作也会越来越得心应手! + +# 本节课Lo que aprenderas + +1. 为什么需要从聊天机器人走向智能体和 Workflow 编排。 +2. 什么是智能体与工作流开发平台,如何把 AI 的能力 SOP 化与可编排化。 +3. 什么是 Dify,如何用这个面向 LLM 应用的开源平台快速搭建应用,尤其是知识库问答机器人。 +4. RAG 的实现方法与价值,为什么需要检索增强生成? +5. 如何从 0 到 1 学会使用 Dify 和 AI IDE Trae (`Extra Knowledge 4 - What is AI IDE and Trae`),包括搭建 智能体、工作流,并基于 Dify API 制作前端对话机器人网页程序。 + +- Dify 的基本使用原理与智能体、工作流制作方法,API 调用方法。 +- AI IDE 的使用方法,如何使用 AI IDE 编程。 +- 一个可进行对话的前端网页智能体程序。 + +# 1. 从对话到智能体 + +在上一阶段,我们学会了如何用提示词让大模型扮演角色、生成文本或编写简单代码。但如果你仔细思考,会发现一个问题,聊天机器人本身并不能做事。 + +它能回答怎么查订单?,却不能真的去数据库里查对应的数字;它能描述一封周报应该包含什么,却无法自动汇总你的项目数据并发送邮件。这种“只说不做”的局限,使得纯对话式 AI 难以真正融入业务流程。 + +要让 AI 从聊天伙伴升级为数字员工,我们需要赋予它三项核心能力: + +1. 专属知识——让它能够通读并了解你的产品文档、客户资料、内部制度; +2. 工具调用(或者叫插件)——让它能操作数据库、调用 API; +3. 结构化执行——让它按预设逻辑一步步完成任务,而非自由发挥。 + +这就是 AI 智能体(AI Agent)的雏形:一个具备目标、知识、工具和执行路径的自动化单元。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image1.png) + +> 注意:当前业界所说的简单版本的“智能体”,大多指基于 LLM + 工具 + 知识库组合而成的增强型应用,并非所谓能够自主规划的智能体。简单的智能体虽不具备真正的推理与长期规划能力,但已足以支撑大量企业级自动化场景。我们将会在之后的章节详细介绍真正的具备自主规划和行动能力的智能体。 + +## 1.1 最简单的智能体:基于知识库的问答机器人 + +在明确智能体应具备的多项核心能力后,一个值得思考的问题随之而来:能否仅通过实现其中某一项最简单的功能,就构建出一个真正可用的基础智能体? 答案是肯定的。 + +事实上,在大量实际业务场景中,用户的核心诉求并非让 AI 自动执行复杂操作(如调用 API 或跨系统协调任务),而是希望它能基于企业自身的专属资料,提供精准、可靠的问答支持。这恰好对应智能体三大核心能力中的第一项,专属知识服务能力。因此,我们得以引出智能体最简单、也最广泛应用的形态:基于知识库的问答机器人。 + +虽然它尚未具备工具调用或自主规划能力,但其关键突破在于:让大模型的回答不再凭空生成,而是有据可依。如何实现?关键就在于解决核心挑战:企业内置大量文档知识,当存在千上万页文档时,模型如何在每一轮对话中快速找到与当前问题最相关的内容? + +此时的一个解决方案是:检索增强生成(Retrieval-Augmented Generation, RAG)。 + +RAG 的基本思路是:在用户提问时,系统首先从企业知识库中检索出与问题语义最相关的若干文本片段(例如产品手册中的某一段、HR制度中的某一条款),然后将这些片段作为上下文“注入”到大模型的输入中,引导它基于真实资料生成回答。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image2.png) + +图片来源:[https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag](https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag) + +这样一来,模型的回答不再是依赖其训练数据中的泛化知识,而是锚定在企业提供的权威信息之上。RAG 的目标,正是通过这种外部知识的动态注入,显著提升回答的真实性、准确性和一致性——甚至可以让回答“符合人设”,比如以客服口径或技术文档风格作答。 + +在实际业务中,这项技术尤为重要,因为大模型常常会产生“幻觉”。例如,若你以 CFO 或咨询顾问的身份询问某个时间段的具体数据,模型很可能编造日期和事件。引入 RAG 后,回答的可控性与可靠性将得到显著提升。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image3.png) + +图片来源:[https://www.databricks.com/glossary/retrieval-augmented-generation-rag](https://www.databricks.com/glossary/retrieval-augmented-generation-rag) + +在本节课的实操环节中,我们将使用流行的 AI 工作流平台 Dify,动手搭建一个基于知识库的问答机器人。你可以轻松将各种类型的专属资料,如产品手册、公司制度、项目文档、研究论文、知识库文章,甚至是个人笔记集构建为知识库。 + +完成搭建后,你可以尝试提出各类问题来检验它的能力,例如: + +- “我们产品A的最新版本有哪些主要功能升级?” +- “请根据员工手册,说明今年的年假制度是如何规定的?” +- “在XX项目中,我们遇到的技术挑战‘XXX’是如何解决的?” +- “这篇论文中提到的核心研究方法是什么?” + +你将亲身感受 RAG 技术如何将静态分散的文档资料,转化为一个精准的智能知识库,为各种场景提供高精度问答支持。 + +## 1.2 从对话智能体到工作流 + +然而,即使是加入了知识库甚至是插件调用能力的“增强型智能体”,在面对更复杂的业务流程时仍显不足。 + +试想这样一个用户请求:“我们新上线的 SaaS 产品最近有哪些功能更新?能帮我整理成一份给客户的简报吗?” + +这个请求看似简单,背后却需要多个协同步骤:首先从内部产品文档或 Notion 知识库中检索最近一个月的功能发布记录;然后过滤出面向客户的关键特性;接着调用大模型将技术描述转化为客户友好的语言;最后通过将生成内容推送至市场团队的邮箱,或保存到 Google Docs 模板中。 + +如果仅靠一个大语言模型自由推理,先不说是否能够一次对话实现所有过程,就算能,其中也很容易遗漏关键信息、混淆内部术语与客户语言,或无法结构化输出。更重要的是,企业需要的是可审计、可复用、可监控的标准化执行路径,而不是每次依赖模型的临时发挥,可监控可复现对企业而言非常重要,非预期的结果很可能会带来预期外的严重损失。 + +这就引出了更高阶的 AI 应用范式:AI 工作流(AI Workflow)。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image4.png) + +工作流是指将一个复杂任务拆解为多个有序、可配置、可自动执行的子步骤,并通过可视化或代码方式编排它们之间的逻辑关系,如条件判断、循环或并行执行。将 AI 能力 SOP 化(即标准化操作流程),意味着把如何用 AI 完成某项任务的经验固化为可重复使用的模板。 + +这种做法带来了多重价值:非技术人员(如产品经理或运营)可以通过拖拽组件快速搭建 AI 应用;开发者可以将 RAG 检索、LLM 调用、API 工具等封装为标准节点,在不同业务场景中复用;整个流程还可被完整追踪、调试和持续优化,满足企业对稳定性与合规性的要求。 + +AI 工作流的使用人群非常广泛。产品经理无需写代码,即可设计完整的用户交互路径;运营人员能快速搭建客服机器人、内容生成器或通知系统;开发者和算法工程师则可将核心能力模块化,供前端调用;创业者或独立开发者也能以极低成本验证 AI 产品的 MVP,几天内上线一个包含数据查询、内容生成与动作执行的完整原型。 + +此外,值得注意的是,AI 工作流通常可用一种中间表示(Intermediate Representation)来描述。不同工作流平台的具体表达方式虽有差异,但大多采用结构化文件(如 JSON、YAML 等)来定义节点类型、输入输出及执行逻辑,其结构类似下图所示: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image5.png) + +简言之,如果说智能体让 AI 从会聊天走向能做事,那么工作流则让 AI 从偶尔做成一件事迈向“稳定、可靠、规模化地完成一类事。在接下来的实践中,我们还将借助 Dify 平台,上手并亲手构建完整的 AI 工作流,体验从想法到可运行应用的完整过程。 + +## 1.3 常用智能体 / 工作流平台 + +随着生成式 AI 技术的飞速发展,为帮助开发者与业务人员快速构建智能体与自动化流程,避免陷入编程的复杂细节,一批低代码甚至无代码的智能体及工作流平台应运而生。 + +首先需要明确的是,低代码平台是指通过可视化拖拽组件、预置业务逻辑模板、图形化配置规则等方式,显著减少手动编码工作量的开发工具。其核心在于以可视化配置,节点式拖动变成的方式替代直接写代码的方式,既能让具备一定技术能力的开发者从重复劳动中解放出来,也能让熟悉业务逻辑的非技术人员参与到应用搭建中。本质上,它是在开发效率与场景灵活性之间架起一座平衡的桥梁。 + +这类低代码/无代码智能体平台的突出价值,正是大幅降低 AI 应用的开发门槛。以往需要团队协作数周——从需求梳理、代码开发到测试Despliegue——才能完成的 AI 智能体(如客服问答机器人、数据处理助手),现在借助平台提供的可视化工具,可将“从创意到上线”的周期缩短至数小时。 + +目前市面上主流的低代码 AI 工作流平台包括: + +| 平台 | 特点 | 适用场景 | +| --------------------------------------------- | -------------------------------------------------- | -------------------------------------- | +| Dify | 开源、支持知识库 RAG、LLM 编排、API 输出,中文友好 | 企业知识库问答、定制化 Agent、API 服务 | +| Coze(字节跳动) | 国内可用、集成抖音/飞书生态、插件丰富 | 社交机器人、国内小程序集成 | +| n8n | 通用自动化工具,支持 AI 节点,强调 API 编排 | 跨系统数据同步、AI + 传统 SaaS 自动化 | +| 百度千帆 AppBuilder / 阿里百炼 / 腾讯 HunYuan | 大厂云原生方案,集成自家模型 | 企业级Despliegue、合规要求高场景 | + +目前市面上的低代码 AI 工作流平台选择丰富。尽管 AWS、Azure、阿里云等主流云厂商均推出了相应的 AI 工作流解决方案,但 Dify、Coze 和 n8n 凭借以下三大核心优势,成为当前应用最广泛的代表: + +1. 极致易用性。平台采用可视化拖拽式界面设计,用户无需深入理解底层技术,即可快速上手。 +2. 高灵活性。支持自定义组件与扩展 API 接口,既能适应教学演示、MVP(最小可行产品)验证等轻量场景,也能满足中小型团队的敏捷迭代需求。 +3. 成熟生态。不仅官方文档详尽、响应及时,还拥有活跃的用户社区,便于快速获取来自不同用户的预设方案。 + +这三大平台均支持将搭建好的 AI 智能体以标准化 API 接口的形式输出,可无缝集成至前端 Web 应用、企业内部 ERP 系统或移动端 APP 中,进一步降低了 AI 能力落地的技术门槛。 + +### 1.3.1 Dify:企业级LLMOps与应用生命周期管理平台 + +Dify 定位是LLM应用开发与运营平台,致力于提供AI应用从构思、Despliegue到优化的全生命周期管理。其核心是一个低代码平台,旨在帮助开发者和非技术背景的创新者快速构建生产级AI应用。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image6.png) + +在功能上,Dify覆盖了可视化工作流编排、智能体构建、知识库管理、多模型支持等功能。平台允许通过拖拽节点设计复杂任务流程,并支持创建基于意图的Agent。其知识库功能突出,能处理多种格式文档并进行高效的向量检索。同时,Dify兼容支持包括GPT、Claude及众多开源模型在内的多种LLM,构建的应用可一键发布为标准API便于集成。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image7.png) + +技术架构方面,Dify以开源和可私有化Despliegue为特色,强调灵活性、扩展性及企业级合规。目标用户包括开发者团队和业务创新者,典型应用场景涵盖企业知识库与智能客服、内容创作自动化、垂直领域AI助手以及企业AI中台。 + +### 1.3.2 Coze(字节跳动):零代码AI智能体构建的普及者 + +Coze是字节跳动推出的AI智能体开发平台,以极致易用性为核心,让无编程经验的用户也能轻松创建、调试并发布功能丰富的AI聊天机器人。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image8.png) + +其核心是将Bot构建简化为搭积木式操作。用户可通过界面轻松配置角色与知识库,并利用丰富的内置插件库为Bot添加新闻、旅游、图像生成等多类外部能力。创建好的Bot可一键快速发布至豆包、飞书、微信公众号等多个平台。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image9.png) + +技术架构完全服务于低门槛使用,后端集成字节自有模型并封装复杂流程,强调多模态理解与实时响应。作为一个主要以云服务形式提供的平台,其私有化Despliegue能力相对有限。典型应用场景包括个人助理与娱乐Bot、智能客服与问答系统、在线教育助手以及快速原型验证。 + +### 1.3.2 n8n:可编程的后端工作流自动化引擎 + +n8n是一个通用的可编程工作流自动化平台,其核心定位是连接各类应用、数据库与API,实现数据流动与任务自动化执行。 + +它通过庞大的集成节点库支持数百种SaaS服务、数据库及协议,并采用可视化与代码结合的方式:用户可在画布拖拽节点,同时注入JavaScript或Python代码编写自定义逻辑。n8n擅长处理后端数据密集型任务,如数据同步、ETL流程与API编排。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image10.png) + +关键技术特性是“源码可见”和“可自托管”,用户可将其私有化Despliegue以完全掌控数据与环境,这使其对数据安全要求高的行业极具吸引力。其主要目标用户是开发者、技术运营及数据分析师。n8n 最大的优势,在于拥有极其强大的社区生态。网络上拥有随处可见丰富的 n8n 分享视频,为用户提供了便捷的学习参考与经验借鉴;同时,它支持连接 YouTube、Instagram 等全球众多不同生态平台,能够帮助用户轻松打破跨平台数据与服务的壁垒,实现多生态流程的自动化流转。 + +### 1.3.3 其他工作流平台 + +除了上述的几个最知名的平台,中国国内的主要科技厂商也相继推出了各自的一体化AI开发平台,例如:百度千帆 AppBuilder 提供从模型选型、RAG构建到智能体发布的全流程支持,深度集成文心大模型;阿里云百炼基于通义千问系列模型,注重企业级安全与私有化Despliegue能力;腾讯云 TI 平台 则聚焦于金融、医疗等行业场景,提供丰富的预置解决方案模板。这类平台通常与各自云生态深度融合,适合已处于相应技术体系内的企业选用。 + +然而,在通用型、开放性与社区生态方面,Dify 与 Coze 仍凭借其突出的易用性、广泛的模型支持以及活跃的开发者社区,成为当前更受广泛采纳的选择。 + +尽管各平台在定位与生态上各有侧重,其核心逻辑均是通过可视化方式编排与连接不同的能力模块。因此,掌握其中任意一种平台的设计思路与操作方法,即具备快速迁移到其他类似工具的基础。在接下来的实践中,我们将以 Dify 为例进行具体讲解。 + +# 2. 深入浅出 Dify + +## 2.1 什么是 Dify + +我们在之前已经了解了基础的 Dify 的信息介绍,对于更详细的信息,你可以通过 [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps) 访问 Dify 平台,如果想了解更多信息,可以访问官网 https://dify.ai。 + +Dify 是一个用于开发 LLM 应用的开源平台。它提供了直观的界面,将 Agent 工作流、RAG 流水线、工具能力、模型管理、可观测性等功能结合在一起,帮助你快速地从原型走向生产环境。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image11.png) + +你可以在 Dify 中使用大语言模型和各种功能不同的工具来搭建“工作流”。所谓工作流,就是把原本需要你手动一步步完成的操作——例如数据检索、大模型调用、网页搜索、结果过滤、格式整理等——按照业务逻辑串联起来,变成一个自动化、可复用的流程。如果没有工作流,每次你都需要把同样的内容复制粘贴给大模型,非常低效、容易出错,也难以在真实业务中复用。 + +搭建一个工作流,就像在拼搭积木或拼图。你把“大语言模型节点”(负责理解和生成)、各类“工具节点”(负责执行具体动作,例如查数据库、发邮件、翻译文本等)、以及“数据节点”(负责读取、存储信息)像积木一样连接起来。它们会按照你预设的逻辑自动协同工作,而不需要你每次都手动操作。你也可以把它理解成一种“低代码程序”:你只需要通过拖拽的方式,配置输入和输出的路径,就可以实现比较复杂的业务逻辑。 + +举个例子,如果你是一个亚马逊或抖音电商店铺的老板,想要搭建一个 AI 客服系统,可以参考下图的结构设计一个工作流: + +1. 触发节点(类似 START):接收用户的咨询问题,例如“这个商品的质保期有多长?”。 +2. 问题分类节点(类似 QUESTION CLASSIFIER):使用一个模型(例如 GPT)对用户问题进行分类,判断这是售后(比如质保)、使用方法,还是其他类型的问题。 +3. 知识检索节点(类似 KNOWLEDGE RETRIEVAL):根据分类结果,自动访问相应的知识库。如果是关于“质保”的售后问题,就从售后 SOP 知识库中检索与“质保”相关的精确信息。 +4. 大语言模型节点(LLM Node):将用户问题和检索到的知识库内容一起发送给大语言模型(例如 GPT),让它生成一段对用户友好的回复(避免太生硬的技术语气)。 +5. 条件节点:检查大模型生成的回答中是否包含清晰的质保时间(例如“1 年”、“3 年”),如果有则继续下一步,如果没有则让它回复“请提供产品型号”。 +6. 输出节点(类似 ANSWER):将最终答案返回给用户,并自动把本次咨询记录到表格中。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image12.png) + +在整个过程中,你不需要手动去翻知识库、反复调整模型的回答、或单独记录数据——工作流会把这些步骤“连起来自动跑”。并且它非常灵活:例如,如果你之后想加一个新规则“当用户问质保范围时,调用另一个知识库”,只需要在工作流中多加一个条件节点,而无需重构整个系统。 + +这是一个比较简单的工作流示例,但要完全掌握这些能力,对现在的你来说可能还有点难。因此在本节课中,我们从更加基础的知识库智能体开始,后面再逐步学习更复杂的工作流技巧。 + +### 2.1.1 Despliegue属于自己的 Dify(可选) + +本部分内容原本安排在后续课程中详细介绍,但考虑到当前部分学习者可能因网络限制暂时无法访问 Dify 官方网站或云端服务,我们决定提前提供这一可选的学习路径,帮助你顺利推进课程进度。 + +你需要参考该教程入门 web Despliegue平台的基本使用方式:[如何Despliegue Web 应用](/es-es/stage-2/backend/zeabur-deployment/) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image13.png) + +你需要学习如何在 Zeabur 上Despliegue一个自己的 Dify,Despliegue后进入到对应链接注册并登录后继续跟随下列教程操作即可。 + +注意,不同版本的 Dify 的操作方面和前端界面可能有些许差别,但总体上差别不大,当你发现不同的时候不要慌张,找到类似的接口和入口进行操作即可。 + +## 2.2 创建第一个 Dify Chatbot 应用 + +访问 Dify 首页 [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps) 并注册和登录后,选择 Studio,你会看到如下界面: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image14.png) + +在左侧找到 `CREATE APP` 区块,点击 `Create from Blank`。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image15.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image16.png) + +在 APP Type 中找到 Chatbot(如果一开始没看到,可以点击“查看更多类型”的按钮,然后在完整列表中找到)。选择 Chatbot 之后,在下方输入应用的名称和描述,最后点击创建。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image17.png) + +创建完成后,你会看到类似下面的界面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image18.png) + +中间区域的 “INSTRUCTIONS” 指的是内置指令,你可以把它理解为默认提示词或系统提示词。 + +中间偏下有一个 “Knowledge” 区域,这就是知识库区域——我们稍后会把自己的知识库上传到这里。 + +右侧是调试窗口,你可以在调整提示词后与 Agent 进行对话,实时查看效果。 + +你可以在 INSTRUCTIONS 区域自由输入角色提示词,观察对话效果;也可以点击 Generate,让大模型自动帮你生成提示词。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image19.png) + +注意右上角会出现许多不同模型的选项,这意味着你可以点击切换不同的对话模型,从而比较它们在语气、逻辑推理、长文本处理等方面的差异,寻找最适合你需求的模型。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image20.png) + +## 2.3 支持自定义模型供应商 + +为充分发挥 Dify 的灵活性,考虑到不同地区访问模型的难度,为满足特定业务需求、成本控制或数据隐私要求,我们常常需要接入自定义模型。Dify 支持配置三类核心模型:大语言模型(LLM)、Embedding 模型和 Rerank 模型。本部分内容将逐步指导你完成这些自定义配置。 + +Dify 能够灵活接入来自 OpenAI、Azure、Anthropic 等主流服务商的模型,同时也全面兼容任何符合 OpenAI API 接口规范的自托管模型或第三方模型。你可以通过安装内置的 OpenAI Compatible 插件以及对各大模型平台定制的插件实现这一操作。 + +详细步骤参考如下,首先我们需要安装对应的插件: + +1. 我们需要安装 `OpenAI-API-compatible` 及 `SiliconFlow` 插件获得对绝大部分大模型和 Embedding 模型的支持,其中前者是对 OpenAI 兼容接口的支持,后者是一个Despliegue了当前绝大部分常见、好用的开源模型的服务站。你可以访问下列网页进行安装: + 1. https://marketplace.dify.ai/plugins/langgenius/openai_api_compatible + 2. https://marketplace.dify.ai/plugins/langgenius/siliconflow +2. 如果你是自己Despliegue的 Dify,你可以在对应系统设置界面进入插件市场进行操作 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image21.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image22.png) + +进入插件市场后,搜索对应的插件名称即可。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image23.png) + +3. 安装结束后,我们能够配置支持新的模型供应商,在设置里的模型提供商部分,我们可以看到目前支持的所有模型商: + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image24.png) +4. 在开始使用前,需要先完成模型的配置。对于 OpenAI-API-compatible 插件,你可以点击 “Add Model” 来添加并配置任意模型。你可以在 “Model Type” 中选择该模型是LLM还是 Embedding,你需要确保模型的类型被正确配置。 + 你需要写入具体的模型名字、模型 endpoint URL 以及 API Key 才能确保模型启用,如果你初步觉得配置该参数麻烦,你可以直接跳到后者的 SiliconFLow 平台的 Key 配置,或者安装 OpenRouter 等第三方服务商插件进行简单的模型支持配置。(确保服务商内有剩余可使用额度) + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image25.png) + + 对于 `SiliconFlow` 插件,只需要点击 Setup 配置 key 后即可使用 Embedding 和 Rerank 模型进行测试,你可以点击 Get you API Key from SiliconFlow 获得鉴权密钥。 + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image26.png) + +5. 配置完成后,你可以点击模型列表查看当前支持多少模型,此时已经完成了基础模型的全部配置。 + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image27.png) + + 其中支持了绝大部分常见的 Embedding 与 Rerank 模型: + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image28.png) + + 此时如果你想要修改 Dify 默认使用模型的配置,你还可以点击 System Model Settings 按钮修改默认的所有模型。 + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image29.png) + +## 2.4 创建第一个 Dify 知识库 + +到这里,我们已经完成了最简单的 Agent 创建,但它还缺少一个知识库。现在,请点击顶部菜单中的 `Knowledge`,进入知识库创建页面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image30.png) + +然后点击左侧的 `Create Knowledge`,创建你的第一个知识库。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image31.png) + +在这个界面中,你可以上传多种类型的文件(例如 pdf、txt 等)来构建知识库。可以上传很长的文本,或者把维基百科上的内容复制下来保存成 txt 文件进行上传。本例中,我们会上传一份关于 Elon Musk 的维基百科 txt 文件。 + +点击 Next 后,你会进入 Knowledge Base Settings(知识库设置)页面。这里选项比较多,我们一步一步来看。 + +首先在 **General** 设置中,你可以把这里理解成“文本切分规则”的设置区域。因为我们需要把很长的文本切分成小块,所以必须先定义切分规则。在入门阶段,你只需要关注 **maximum chunk length(最大切分长度)** 。可以尝试设置为 512、2048 或 4096,然后点击 **Preview Chunk** 预览不同设置下的效果。 + +你也可以调整 **Chunk overlap(切片重叠)** 选项。它决定相邻片段之间是否会保留一部分重叠内容。适当的重叠有助于避免重要信息被拆到不同片段而难以理解。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image32.png) + +在设置中还有一个选项叫做 **Chunk using Q&A format in English** 。启用后,系统会使用大语言模型,将知识库的一部分内容转换成问答形式来存储,这在某些场景下可以显著提升检索效果。 + +在真实业务中,根据场景选择合适的切分策略,能够更好地优化检索结果,保证查询能够返回你期望的信息。 + +继续向下滚动页面,你会看到和 Embedding 模型相关的设置。 + +简单解释一下:Embedding 模型的核心功能,是把非结构化数据(例如文本、图片等)转换成计算机能够理解的“数字向量”(Embedding 向量)。通过这种转换,模型能够快速计算不同数据之间的相似度,从而实现语义相近内容的匹配,比如根据用户输入的一句话,找到语义最接近的文档、图片或商品。 + +Embedding 模型的选择会显著影响最终的检索效果(例如匹配准确度、响应速度等)。在这里,我们推荐优先使用 Qwen 0.6B 的 Embedding 模型,你也可以切换到 4B 或 8B 版本,直观对比不同参数规模下检索效果的差异。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image33.png) + +在此处,你还会看到另一个模型设置叫做 **Rerank model** ,默认值是 **Jina-rerank-m0** 。(如果你非校园内的学生,此时你可能会看到 Rerank 模型缺失的报错,你需要在模型处配置 rerank 模型才能在此处启用使用) + +Rerank 模型的主要作用,是对“初步筛选出的候选结果”进行二次、更精细的排序,让和用户需求最匹配的结果排在更靠前的位置,从而显著提升最终结果的相关性和用户体验。 + +简单理解:Rerank 模型就是用来解决“初次筛选不够精细”的问题。例如搜索引擎可能先用较简单的规则检索出 1000 个潜在相关网页,再通过 Rerank 模型,从中挑出最相关的前 10 个展示在第一页。 + +推荐系统同理:它可能首先找出 500 个“可能适合你”的商品,再通过 Rerank 模型排序,让你最可能购买的商品排在列表顶部。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image34.png) + +当所有设置完成后,点击 **Save & Process** ,系统就会进入知识库向量化阶段。在这一阶段,Embedding 模型会把切分后的文本转换为向量表示。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image35.png) + +处理完成后,点击 **Go to document** ,可以查看已经处理完毕并存储好的知识库内容。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image36.png) + +直接点击知识库名称,可以查看每个切片的具体内容。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image37.png) + +在这里,你可以对任意不合适的文本片段进行精确的编辑或删除操作。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image38.png) + +在左侧边栏中,选择 **Retrieval Testing** 可以对知识库进行召回测试,检查检索是否正常工作。每次测试会返回若干相似度最高的切片。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image39.png) + +如果你希望看到更多的切片结果,需要点击 `VECTOR SEARCH` 设置: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image40.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image41.png) + +Top K 指的是向量检索时,返回与查询向量最相似的前 K 个文本切片数量。当前设置为 3,表示会返回相似度最高的 3 段文本。 + +Score Threshold 则是一个“得分阈值”:只有相似度得分大于或等于该阈值(示例中为 0.5)的文本片段才会被返回。这样可以过滤掉相关度较低的内容,让结果更加准确。 + +现在知识库部分就全部准备好了。接下来,点击顶部菜单栏中的 “studio”,找到刚才创建的智能体,为它接入我们已经配置好的知识库。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image42.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image43.png) + +此时,在每一轮对话中,你都可以在回答中看到被命中的知识库来源。点击对应条目即可查看检索到的具体文本片段。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image44.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image45.png) + +## 2.5 更多 DIfy 常见操作 + +在掌握基础 Chatbot 和知识库搭建的基础内容后,我们可以深入了解更多有关 Dify 的使用方式。 + +### 2.5.1 工作流的导入与导出 + +还记得之前提到的工作流的中间表示法吗?Dify 支持通过 DSL(Domain Specific Language) 格式导入和导出工作流。DSL 是一种基于 JSON 的标准化描述方式,能够完整保留工作流的节点结构、连接关系和配置参数。你可以很容易导入和导出 DSL 文件,分享工作流给其他人使用,或者导入别人的工作流进行参考。具体而言,我们能够容易在工作台页面看到工作流的导入按钮: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image46.png) + +而对于工作流的导出,我们只需要点击单个工作流块的右下角即可找到导出按钮: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image47.png) + +通过使用 DSL 文件,你可以轻松地在不同 Dify 实例之间迁移或共享复杂的工作流设计。 + +### 2.5.2 查看更多 Dify 项目 + +如果你觉得自己搭建的工作流或者智能体过于简单,Dify平台提供了丰富的示例项目,帮助你快速了解如何构建复杂应用。这些示例项目涵盖了多种业务场景。你可以点击 Explora 查看别人构建的工作流进行学习。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image48.png) + +## 2.6 创建第一个 Dify Workflow 应用 + +完成了 DIfy 的对话智能体构建入门,我们继续查看如何构建更复杂的 Dify 业务工作流。工作流是Dify将复杂业务逻辑可视化的核心方式,通过它你可以像搭积木一样构建智能流程。你能够完整体会信息如何在不同节点间流转,判断逻辑如何Despliegue,人工干预点设置在哪里,以及最终如何交付一个完整的业务结果。 + +你可以选择从空白处创建,或者直接从模板处创建,此处演示如何从空白处创建工作流: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image49.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image50.png) + +在这里我们会看见两个选择,分别是 Chatflow 与 Workflow,这两者该如何选择呢?关键是你需要理解你所要构建的,其核心是持续对话,还是任务流程。 + +Chatflow 专为对话而设计。它模拟一个具有记忆和上下文理解能力的对话者,非常适合需要多轮交互、状态维持的场景。例如在客服咨询中,它能连贯地理解用户的后续追问,如同一位耐心的服务人员。其流式输出的特性也让交互过程更为自然。简而言之,当你需要构建一个能“交谈”的智能体时,应选择 Chatflow。 + +Workflow 则专注于流程的自动化执行。它像一条预设的流水线,擅长处理一次性输入、多步骤处理、并产生确定性输出的任务。例如,每日定时生成数据报表、批量处理文件或调用系列API。这类任务通常由事件触发,无需与人实时互动。因此,当你需要实现“自动化”任务时,Workflow 是更合适的选择。 + +为避免选型错误带来的效率低下,你可以通过四个关键问题来审视你的任务需求: + +1. 任务过程是否需要依赖多次的用户输入与调整? +2. 结果的呈现是否需要分步骤、流式地进行? +3. 处理逻辑是否严重依赖于之前的交互历史? +4. 任务是否由事件触发,且输入输出多为一次性完成? + +如果前三个问题的答案为“是”,那么 Chatflow 是理想选择,典型场景包括智能客服、教育辅导、创意协作等。如果第四个问题特征显著,则应选用 Workflow,它更适用于数据清洗、报表生成、批量处理等自动化场景。 + +此处我们选择 Chatflow 作为案例进行介绍,点击 Chatflow 后进入到操作台界面: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image51.png) + +我们来简单介绍工作流界面的页面。其中整个界面的核心是中央的编辑画布,你将以可视化方式在这里构建应用逻辑。如图所示,一个基础的工作流通常始于 START 节点(用于接收输入),经由连线将数据传递至 LLM 节点进行处理,最终通过 ANSWER 节点输出结果。每个节点代表一个功能模块,而连线则决定了任务执行的顺序。 + +环绕画布的是完整的操作与管理功能区。界面顶部提供了全局控制选项,包括测试工作流的 Preview 按钮和用于上线的 Publish 按钮。画布角落则设有缩放、撤销等视图控制工具,便于精细调整。 + +左侧面板集中了应用的管理功能。你当前所在的 Orchestrate 选项卡用于流程编排;构建完成后,可通过 API Access 获取集成凭证;Logs & Annotations 记录了每次执行的详细踪迹,便于调试;而 Monitoring 则为你提供应用运行时的性能与状态监控。 + +你可以简单在该对话工作流 LLM 节点的 SYSTEM 中输入一些提示词内容,点击 Preview 后尝试运行这个工作流,查看修改 SYSTEM 提示词后整个工作流确实按照预期在变化。 + +### 2.6.1 常见节点介绍 + +Dify 中提供了多种节点,你可以先了解每个节点的基本功能。具体使用时,建议亲手尝试,或参考他人创建的工作流模板,也可以截图并向大模型询问该节点的用法、所需参数等。推荐直接在现有模板中替换不同节点,通过他人的使用方式来推测节点的最佳实践。 + +在画布右键点击“Add Node”即可添加节点,也可以在左侧的节点面板中查看所有可用节点: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image52.png) + +同时,可以打开工具选择面板,查看支持调用的各类工具: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image53.png) + +下面是一些常用节点和工具的简要说明。不需要一次性全部掌握,建议先留个印象,在实际使用中逐步熟悉,必要时再回查阅。 + +1. LLM与推理节点 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image54.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image55.png) + +此类节点负责工作流中的核心流程。 + +- LLM节点:核心计算单元,用于调用大语言模型。其配置重点在于提示词工程与参数调优,将业务问题转化为模型的执行指令。 +- Knowledge Retrieval 节点:知识检索单元,负责从预设知识库、外部权威数据源中检索与业务问题相关的信息,为 LLM 节点提供精准的知识支撑,帮助减少大语言模型输出的 “幻觉” 问题。 +- Answer 节点:结果输出单元,负责接收 LLM 处理后的内容,将其整理为符合业务场景需求的最终成果形式。其配置重点在于输出格式的定义(如话术模板、排版规范)。 +- Agent节点:高阶决策单元。它不仅调用模型,还可实施多步骤规划、自主选择并调用外部工具,适用于需要动态决策的复杂任务链。 +- Question Classifier 节点:问题分类单元,负责对输入的业务问题进行类型识别与归类(比如按问题意图、主题领域等维度划分),帮助后续流程精准匹配对应的处理节点(如不同类型的问题适配不同的 LLM 提示词或工具链)。 + +2. 逻辑与流程控制节点 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image56.png) + +此类节点定义工作流的执行路径与规则。 + +- 条件节点:如 `IF/ELSE`,通过布尔判断实现流程分支。其设计关键在于条件表达式的严谨性,确保逻辑覆盖所有业务场景。 +- Iteration 节点:作为无状态的批量并行处理单元,它专为子任务间无数据依赖、可独立处理的场景设计,例如批量翻译段落、并行审核多条内容或同时生成多份报告。该节点会接收一个输入数组并自动分片,将每个元素分发至相同处理链路并行执行,用户可在迭代体内通过 {{item}} 访问当前元素、{{index}} 获取其索引,输出则会自动聚合成结果数组;配置时需重点设定并行度以平衡效率与系统负载,同时通过重试策略(如重试次数、间隔)和失败处理(如记录日志、返回默认值)保障批量作业的稳定性。 +- Loop 节点:有状态的递归迭代器,适用于结果依赖前一轮输出的场景,比如多轮参数调优、递归式内容优化(如反复修订文案直至满意)及依赖上次结果的链式计算。其核心是 “状态变量”,需在循环开始前初始化(如当前迭代次数、中间计算结果),并在每轮迭代中明确更新以作为下一轮输入;为防止无限循环,必须定义终止条件(包括基于计数器的 “最多循环 10 次”、基于结果判定的 “满意度评分 > 9”、基于外部信号的 “检测到‘停止’输入”),同时需设置循环超时配置,并规划异常处理路径(如跳出循环或重置状态后重试),确保流程稳定运行。 + +3. 数据操作与集成节点 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image57.png) + +- Code 节点:代码处理单元,负责在工作流中执行自定义代码逻辑,可实现数据格式转换、复杂计算等个性化处理需求。其配置重点在于代码语法的正确性与执行环境的适配。 +- Template 节点:模板处理单元,负责将动态数据填充至预设模板中,生成符合格式要求的内容(如定制化文案、报告框架)。其配置重点在于模板语法的编写与变量映射规则的设置。 +- Variable Aggregator 节点:变量聚合单元,负责收集工作流中多个节点输出的变量数据,将分散的变量整合为统一数据集。其配置重点在于聚合的变量范围与数据合并规则的定义。 +- Doc Extractor 节点:文档提取单元,负责从 PDF、Word 等各类文档中提取文本、表格等关键内容,转化为工作流可处理的结构化数据。其配置重点在于文档类型的适配与提取内容的筛选规则。 +- Variable Assigner 节点:变量赋值单元,负责定义、初始化或更新工作流中的变量,为流程内的数据传递提供载体。其配置重点在于变量的命名、数据类型及赋值逻辑的设定。 +- Parameter Extractor 节点:参数提取单元,负责从用户请求、接口返回等输入内容中提取指定参数,将非结构化信息转化为结构化数据。其配置重点在于提取规则(如正则表达式、JSON 路径)的配置。 +- HTTP Request 节点:HTTP 请求单元,负责向外部系统接口发起 HTTP 请求(含 GET、POST 等方法),实现工作流与外部服务的数据交互。其配置重点在于请求地址、请求方法及参数 /headers 的设置。 +- List Operator 节点:列表操作单元,负责对数组、列表类型的数据进行处理(如过滤、排序、拆分),调整数据结构以适配后续流程。其配置重点在于操作类型(如过滤条件、排序规则)的定义。 + +### 2.6.2 常见工具介绍 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image58.png) + +在 Dify 中,大部分工具都可以直接作为节点放在画布上,像其他节点一样被上下游连线,只要你提供的输入符合该节点(工具)的参数规范,它就能正常执行并产出可继续流转的结果。 + +在左侧或右侧的节点面板中,可以查看所有可用工具节点,也可以通过插件市场扩展更多工具能力。简单介绍几个常见工具的作用: + +- 网络搜索工具 + 以 Tavily Search 为代表,为大模型提供面向 AI 优化的实时检索能力。 + 它会返回结构化的搜索结果(如标题、摘要、链接等),可以直接作为 LLM 提示词的一部分,用于回答最新资讯类或需要权威依据的问题。 +- 数据处理工具 + 例如 JSON Process 插件,用于对 JSON 数据进行查询、筛选、转换、合并等高级操作。 + 在处理复杂 API 响应或多层嵌套数据时,你可以将“数据清洗 + 重组”的逻辑交给该工具,从而简化在 Code 节点中频繁手写解析代码的工作。 +- 格式处理工具 + 如 Markdown Exporter,可以将生成内容按指定格式导出,例如 Markdown 文档、特定排版模板等,方便后续用于展示、汇报或集成到其他系统。 + +你可以在工具列表中看到这些插件的安装量和简介,初期可优先尝试安装“Featured / 推荐”里的工具,往往覆盖了最常见的业务场景。 + +不过,工具的使用通常比较复杂,建议你在使用的时候可以去搜索引擎先搜索对应工具的“官方推荐工作流 DSL 案例”,直接导入使用,比自己搭建要天然节约很多时间。 + +### 2.6.3 创建简单的意图分类工作流 + +此时我们已经初步了解了 Dify 工作流和工具等的基本信息,但不经过练习我们永远不会熟练使用细节,我们需要一个“假设”的真实业务场景来练练手。 + +例如,在真实的购物对话场景中,前来购买商品的用户输入永远不会是“规范的参数”,而是一句随口说出的话:有人来下单,有人来抱怨,有人只是想闲聊,也有人完全跑题。如果我们把所有这些输入都直接交给同一个大语言模型(LLM)处理,系统通常会出现两个典型问题: + +1. 回复风格不稳定 + 同样是抱怨,有时 LLM 能道歉安抚,有时却像在“解释原因”;同样是点餐,有时会追问缺失信息,有时则直接编造订单细节。 +2. 业务逻辑不可控 + 你希望“抱怨必须先道歉”,但模型未必每次都遵守;你希望“非业务问题要引导回主线”,但模型可能会兴致勃勃地和你聊起段子。 + +因此,更工程化的做法是将任务拆解为一条标准化流水线,先做意图分类(确定用户到底想干什么),然后再按意图分流(不同场景使用不同的提示词与角色),最后对不同分流后大模型的回复统一封装输出(便于前端或系统集成)。 + +本节的目标是让系统能处理一个餐饮场景下的多类对话。你可以跟着操作做一遍加深印象。首先需要做的是定义场景为意图分类: + +- **下单购买 (buy_food)** :用户表达明确的购买意愿。 +- _例如:“给我来一份炸鸡,再加一杯可乐。”_ +- **抱怨投诉 (complain)** :用户在表达不满、催促或负面反馈。 +- _例如:“你们也太慢了吧?等一个小时了。”_ +- **闲聊咨询 (chitchat)** :用户在进行开放式询问、寻求建议,但无明确下单指令。 +- _例如:“今天吃什么好呢,你有什么推荐吗?”_ +- **其他意图 (other)** :用户的输入与餐饮场景无关。 +- _例如:“帮我写个搞笑文案发朋友圈。”_ + +针对这四种意图,我们为系统预设了四种不同的“沟通人格”,分别由四个独立的 LLM 节点承载,每个节点都需要由具有不同人设的 LLM 进行扮演。 + +- **下单助手 (LLM_BuyFood)** :专业、高效,核心任务是确认订单细节,并主动补全缺失信息。 +- **客服专家 (LLM_Complain)** :共情、稳重,首要任务是安抚用户情绪,并提供清晰的解决方案。 +- **聊天伙伴 (LLM_Chitchat)** :轻松、友好,旨在提供Recomendacion personalizada,引导潜在消费。 +- **礼貌门卫 (LLM_Other)** :专注、边界清晰,负责将偏离主题的对话礼貌地引导回核心业务。 + +#### 工作流编排设计 + +接下来我们进行工作流的编排设定,决定大概需要有哪些工作流节点。对于新手而言,很难想到需要有哪些节点能被用到(对于老手来说也懒得自己思考,用大模型给建议通常是最快最好的选择),所以我们能够使用大模型给出对应的编排建议,其核心节点结构如下: + +- Start (起点):作为数据入口,负责接收用户的原始输入 `user_text`。 +- Question Classifier (意图分类器):工作流的“大脑”与“调度中心”。它负责对 `user_text` 进行分析,并从我们预设的四种意图标签中选择最匹配的一个。 +- Condition (条件分支):扮演“分流阀”的角色。它根据分类器输出的意图标签,决定接下来将任务导向哪一个专处理路径。 +- 四个并行的 LLM 节点 (LLM_BuyFood, LLM_Complain, LLM_Chitchat, LLM_Other):这是四个独立的“专家处理单元”。每个节点都接收原始问题,但依据自身独特的 System Prompt(系统提示词)生成风格和目标截然不同的回复。 +- Variable Aggregator (变量聚合器):在多条路径处理完成后,需要一个“汇集点”。此节点将四个分支中唯一被激活并产生结果的回复,收束成一个统一的变量 `final_reply`,确保了输出结构的稳定性。 +- Output (终点):作为最终的出口,负责将意图标签、原始问题、以及经过处理生成的回复,以结构化的形式(如 JSON)统一输出,便于后续系统调用或调试分析。 + +#### 工作流编排实现 + +本次教程我们选择创建 Workflow 而不是 Chatflow,选择 User Input: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image59.png) + +随后点击 Start 的 User Input 节点,定义一个名为 `user_text` 的字符串类型变量,作为整个流程的输入源。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image60.png) + +保存后点击右上角的 Test Run,你能够看到需要指定对应的文本输入进行处理: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image61.png) + +随后我们需要点击输入节点后的 + 符号,选择 Question Classifier 节点添加,并且我们需为其配置四类标签,并为每个标签提供清晰的描述和示例。 + +- `buy_food`: 用户明确想买吃的、点餐、下单。 +- `complain`: 用户在抱怨、吐槽、发脾气,通常带有不满情绪。 +- `chitchat`: 用户在闲聊、讨论吃什么、咨询推荐。 +- `other`: 与餐饮场景无关,或难以判断的内容。 + +此外,你还需要在 ADVANCED SETTING 中写入提示词,让大模型能够正确根据用户输入进行分类测试。示例提示词如下: + +``` +从 buy_food / complain / chitchat / other 中选择一个最合适的标签。如果用户在抱怨的同时也点了餐,请优先判断其核心情绪,若重点在于表达不满,应归为 complain。如果只是轻微吐槽但主要意图是下单,则归为 buy_food。若实在难以判断,使用 other 作为兜底 +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image62.png) + +设定完成后,你可以在右上角的播放键单独测试该节点是否能够正常运行: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image63.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image64.png) + +从 OUTPUT 的结果来看,我们的分类是准确的。你可以进行多种不同类型输入的测试,验证我们分类器的稳定性。 + +接下来,我们需要给分类器接上后续的大模型输出,例如,当 `label` 等于 `"buy_food"` 时,工作流便会精确地流向 `LLM_BuyFood` 节点。我们需要新建四个 LLM 节点,并设置不同的 System Prompt ;不同 System Prompt 的差异决定了它们不同的回应方式。 + +- LLM_BuyFood (点餐助手): + +你是一个点餐助手。要求:1. 确认用户想点的内容。2. 如果信息不完整,友好地补充询问。3. 语气礼貌简洁。 + +- LLM_Complain (客服专家): + +你是一个餐饮客服,专门处理抱怨。要求:1. 真诚道歉。2. 简要说明可能的原因(不推卸责任)。3. 给出清晰的下一步解决方案。 + +- LLM_Chitchat (聊天伙伴): + +你是一个帮人选吃的的聊天小助手。要求:1. 用轻松友好的语气。2. 给出 1~3 个简单推荐。3. 如果用户没有偏好,就给出不同风格的选择。 + +- LLM_Other (礼貌门卫): + +你是一个餐饮点餐小助手,只擅长跟‘吃’相关的话题。当用户说的话无关时:1. 礼貌说明自己的能力范围。2. 引导用户回到主场景。 + +值得注意的是,每个节点里面在填充了 SYSTEM 的提示词参数后,你还要记得启用 USER 提示词参数表。你需要在其中需要点击 `{x}` 符号,选择 `user_text` 参数作为用户输入,并且在前面加上 `user input:` 标识这个变量是用户输入的意思,在问答的时候会综合用户的最开始的输入和内置提示词进行回复。 + +同样的,为了确保一切顺利,你可以点击该节点右上角的播放箭进行具体的对话测试验证效果,比如对话说“我想要喝珍珠奶茶”等,查看回复是否符合预期。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image65.png) + +接下来我们处理并行 LLM 的输出值,我们在 `Variable Aggregator` 节点的配置面板中,找到 `ASSIGN VARIABLES`(分配变量)区域,点击后依次将之前的大模型回复加入即可。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image66.png) + +接下来我们需要对所有的输出进行聚合,最后得到我们想要的结果,包含用户的输入、分类、以及回复。由于我们使用的是 Workflow 而不是 Chatflow,故没有 Answer 节点选择进行结果的聚合,我们能够选择其他节点变相实现结果的聚合与输出,此时选择 Template 节点,在变量部分指定用户意图分类结果、用户的输入值、变量聚合的最终回复,并且在 CODE 中写入最后回复的 json 格式模板,我们可以得到: + +- `intent` ← `class_name` +- `original_text` ← `user_text` +- `final_reply` ← `variable_aggregator` + +``` +{ + "intent": "{{ intent }}", + "original_text": "{{ original_text }}", + "reply": {{ final_reply }} +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image67.png) + +最后加入 output 节点即完成所有操作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image68.png) + +#### 工作流运行测试 + +大功告成,我们可以尝试运行这套工作流的效果。它能根据不同的输入,展现出截然不同的行为模式: + +- 输入 (点餐): "给我来一份香辣鸡腿堡套餐,大杯可乐。" + - 路径: `buy_food` → `LLM_BuyFood` + - 输出 reply: "好的,一份香辣鸡腿堡套餐和大杯可乐已为您记录。请问套餐里的薯条需要更换吗?" +- 输入 (抱怨): "你们也太慢了吧?我都等一个多小时了!" + - 路径: `complain` → `LLM_Complain` + - 输出 reply: "非常抱歉让您等了这么久,这确实是我们的疏忽,给您带来了很不好的体验。我们正在紧急核实您的订单配送情况,并会为您申请相应的补偿,感谢您的耐心与反馈。" +- 输入 (闲聊): "今天吃什么比较健康?" + - 路径: `chitchat` → `LLM_Complain` + - 输出 reply: "追求健康的话,可以试试我们的轻食沙拉系列,或者烤鸡胸肉配时蔬。您是喜欢口味清淡一些还是稍微丰富一点的呢?我可以给您更具体的推荐。" +- 输入 (无关内容): "帮我想个明天开会的笑话。" + - 路径: `other` → `LLM_Other` + - 输出 reply: "这听起来是个有趣的挑战!不过我主要是个美食推荐和点餐助手。如果您需要点些什么来犒劳一下辛苦工作的自己,我随时可以帮忙!" + +> 隐藏 Bug :需要说明的是,若你遇到与 aggregation group 相关的奇怪问题,这大概率是 Dify 的一个内置 bug。可能在特定操作下被触发;如果你曾经开启又关闭过 AGGREGATION GROUP,系统可能生成过 group 配置且残留了相关异常参数,即便现在开关看起来是关闭的,这些残留配置也可能导致问题,比如出现 `any` 相关参数的报错。此时你只需要删除该节点并重新创建即可。 + +在 Test Run 中运行后,我们能够看到工作流的执行过程,此时根据分类走了正确的流程,并得到了最后的 output 结果。至此,全流程完成。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image69.png) + +## 2.7 运行第一个模板 Workflow 应用 + +结束了简单的分类工作流学习,接下来我们需要学习如何运行别人的 workflow,我们只需要稍作改造就可以将其变成自己的工作流。在这里我们选择尝试官方的 DeepResearch 工作流,该工作流能够帮你构建一个深度搜索框架,使用大模型+搜索引擎给你一个丰富的搜索答案,每一次提问的结果将会包含搜索引用地址和大模型对话的结果。 + +导入后第一步直接运行,我们根据每一步报错的地方和原因解决具体问题即可,如果遇到解决不了的问题,你可以截图后询问大模型进行解决。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image70.png) + +刚进入感觉十分复杂,没关系,我们点击右上角的 Preview 运行工作流,直到报错出现: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image71.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image72.png) + +我们需要根据报错的节点解决问题,打开后发现是没有配置 Tavily 的 API Token,Tavily 的搜索API 是一个专为 AI 设计的搜索引擎,提供实时、准确和事实性的结果。此时根据提示操作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image73.png) + +经过处理后,搜索引擎能够正常工作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image74.png) + +继续修正模型调用导致的问题后,你应该能够得到如下结果,结合大模型理解下的详细搜索: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image75.png) + +我们在最后能够看到对应的参考文档地址: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image76.png) + +如果你想理解每个环节的作用,最好的方法是将每个环节的 output 记录为一个变量,最后在输出的时候打印每个中间变量的结果,还有一个方法就是你可以在上方找到 Process 的过程,点击后可以查看每个环节的细节: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image77.png) + +## 2.8 将 Dify 作为 API 提供方 + +接下来,我们会尝试通过 API 调用刚才创建的知识库智能体 Agent,我们想要让 Dify 变成一个大模型中枢后端。 + +还记得之前讲过如何通过 API 调用模型吗?我们需要准备一个密钥(Key)和一份 API 调用示例(文档中的 request/response 示例),然后把这些内容发给大模型,让它帮我们写出调用服务的代码,并从返回结果中解析出我们需要的字段。 + +这一次,我们会使用本地的代码编辑工具 [Trae](https://www.trae.cn/) 来完成这个过程。 + +如果你还不熟悉什么是 IDE,可以先阅读文档 [Extra Knowledge 4 - What is AI IDE and Trae](https://github.com/datawhalechina/easy-vibe/blob/main/docs/extra/extra4/extra4-what-is-ai-ide-and-trae.md)。 + +如果你的本地开发环境还没有完整配置好,也不用担心。只要你信任自己的代码助手(不管是 [z.ai](http://z.ai) 还是 Trae),遇到任何不懂的地方或报错,都可以直接把问题抛给它,它会根据你的描述给出详细的解决方案。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image78.png) + +右侧的区域叫做 Copilot 交互窗口,或者 Agent 窗口。如果你看不到它,可以点击右上角的侧边栏图标来打开。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image79.png) + +打开侧边栏后,你会看到 `Builder` 选项。这就是 Agent 模式。你可以简单地把 “Builder” 理解为 [z.ai](http://z.ai) 的“开发模式”,它同样可以帮你操作本地电脑环境、安装依赖、打开网页等。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image80.png) + +点击 “Builder” 后,你会看到 “Chat” 模式和 “Builder with MCP” 模式。 Chat 模式主要用于与当前文件夹进行交互,或者和大模型进行自然语言对话。(你可以通过点击 Trae 左上角的 “File” 打开一个文件夹,然后在该文件夹内进行编辑。这种情况下,Builder 所有的新建文件操作都会发生在这个文件夹中。) + +Builder with MCP 模式则为 Agent 提供了更多工具(例如让大模型连接到其他软件、获取天气信息等)。你可以简单地认为 MCP 是一个让大模型更方便调用各种外部工具的能力集合。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image81.png) + +在下方区域,你还可以看到模型选择的下拉列表,可以点击切换不同模型。这里你可以选择 Kimi k2 或 GLM。如果你使用的是国际版 Trae,也可以选择 ChatGPT 或 Claude。 不过,随着国内大模型的快速发展,Kimi、Qwen、GLM 等模型的综合能力已经基本接近 Claude 3.5 或 3.7,对于日常开发场景来说完全够用。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image82.png) + +上面是对 Trae 的一个简要介绍。接下来,我们可以回顾在 [z.ai](http://z.ai) 中的操作步骤,并在 Trae 中复用这些思路。 + +## 2.9 利用 Dify API 创建前端对话应用 + +如果我们想用 Dify 的 API 搭建一个前端聊天应用,首先需要获取 Dify 的 API 文档和调用地址。 + +还记得刚才创建的那个 Agent 吗? 先点击右上角的 “Publish”,然后点击 “Publish Update”,最后点击 “Access API Reference” 进入 API 文档。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image83.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image84.png) + +进入 API 文档后,找到 “Send Chat Message” 这一部分,点击进入,然后在右侧找到 “Request” 和 “Response” 示例并复制出来。 + +为什么一定要复制这两部分内容? 因为它们是 API 的“核心信息”: 有了 Key、请求示例和返回示例,我们就可以让大模型帮我们生成调用服务的代码,并且根据返回结构把需要的字段提取出来。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image85.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image86.png) + +在找到会话所需的 Request 和 Response 示例之后,我们还需要获取一个 API Key。在文档右上角,你会看到 “API key” 相关选项。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image87.png) + +点击 “Create new Secret key”,就可以创建属于你自己的 API Key。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image88.png) + +现在一切准备就绪。我们会把刚才拿到的 API Key、Request 示例和 Response 示例一起交给 Trae Builder。 + +注意:请将 `{DIFY_API_URL}` 替换为实际的 Dify API 地址。 + +```json +key: +app-zKdCHUXXXXXXXX + +Please write me a front-end based on the following reference: + +curl -X POST 'http://{DIFY_API_URL}/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image89.png) + +在这个阶段,你可能会发现生成出来的程序并不能一次性正常运行——比如对话会出现奇怪的错误,或者没有任何返回结果。当出现这种情况时,你可以尝试切换到另一个大语言模型,或者把错误信息复制出来,详细描述问题,再发给模型让它根据反馈继续迭代。 + +此时你的工作方式已经非常接近真实开发过程了。在日常开发中,我们经常会在与大模型协作时遇到各种问题,为了更好地解决这些问题,我们需要提供更多上下文信息。除了提供错误信息,你还可以复制更完整的文档内容(例如在文档左侧 “Send message” 部分中复制更多说明),一并交给模型,让它在更多细节的基础上给出更完整的解决方案。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image90.png) + +此时浏览器是嵌在 Trae 内部的。你可以点击顶部的指南针图标,把网页在外部浏览器中全屏打开。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image91.png) + +如果运气不错,你可能在第一次尝试时就能获得一个可以正常交互的前端页面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image92.png) + +不过,由于大模型本身具有一定随机性,有时你可能在单轮对话中一切顺利,但在多轮对话时出现异常。因此,建议你进行多轮对话测试,确保程序在多轮交互场景下也能稳定运行。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image93.png) + +到这里,你已经学会了如何构建一个简单的 Dify 知识库 Agent,并使用 Trae 替代 [z.ai](http://z.ai) 来搭建一个交互式前端。从现在开始,Trae 将成为我们构建各种原型时的主要开发工具,逐步取代 [z.ai](http://z.ai)。你可以尝试用 Trae 重新实现之前的贪吃蛇游戏,看看会有什么不同的体验。加油! + +# 3. 更多业务工作流参考 + +你可以在搜索引擎上使用类似关键词搜索 `Dify workflow 参考`,或者直接在 Github 中找到 Dify 工作流分享仓库进行参考工作流的查找(质量参差不齐,你需要查看多个不同仓库学习)。当然,所谓的工作流只不过是业务上 SOP 的映射,你可以思考有哪些日常工作中的流程或者学习中的流程是重复可固化的,只需要把它变成工作流固定即可。 + +以下是一些大模型生成的工作流设计的参考(实际上的实现方案也比较类似,一般来说人类设计的工作流不会有大模型设计的优美,除非是高手设置的工作流),如果你觉得哪些点子有意思,可以将它发给大模型进一步细化,让大模型帮你给出更具体的 Dify 工作流节点设定,以及内部的细节结果。 + +## 3.1 社媒平台工作流 + +1. 跨平台内容一键分发工作流(复杂) + 1. 思路:以一篇核心稿件为“原料”,自动加工成适配多个平台的“成品”。 + 2. 实现:`Start` 输入文章 -> `LLM` 润色 -> 并行多个 `LLM` 节点(每个节点Prompt扮演特定平台专家,如“小红书爆款文案专家”、“知乎专业答主”)-> `Iterator` 节点循环处理不同平台格式要求 -> `Variable Aggregator` 汇总 -> `Answer` 输出所有版本。复杂度在于并行处理和循环迭代。 +2. 热点话题选题与初稿生成器(中等) + 1. 思路:自动捕捉网络热点,快速生成选题和内容草稿。 + 2. 实现:`Start` 输入关键词 -> `Tool` 节点调用搜索引擎API抓取热点 -> `LLM` 摘要提炼出3-5个话题 -> `LLM` 生成文章大纲或初稿。复杂度在于外部工具集成与信息筛选。 +3. 评论区智能分类与回复助手(复杂) + 1. 思路:自动分析评论情感与意图,生成分类回复建议。 + 2. 实现:`HTTP Request` 节点接入社媒API获取评论 -> `Question Classifier` 或 `LLM` 节点进行多标签分类(积极、疑问、投诉、广告等)-> `Condition` 判断节点路由至不同回复生成链 -> 并行 `LLM` 节点生成个性化回复草稿 -> `Answer` 输出。复杂度在于条件分支和实时API调用。 +4. 短视频脚本与分镜自动生成器(复杂) + 1. 思路:根据一个热门话题或产品描述,自动生成短视频脚本、分镜描述和推荐标签。 + 2. 实现:`Start` 输入主题 -> `LLM` 生成创意脚本 -> 第二个 `LLM` 节点将脚本拆解为场景序列(画面描述、台词、时长)-> `Tool` 节点调用文本转语音服务生成语音样本 -> `Variable Aggregator` 整合所有元素 -> `Answer` 输出结构化脚本文件。复杂度在于多步骤序列化和外部服务集成。 +5. 直播互动问答实时摘要助手(中等) + 1. 思路:实时处理直播间的文字评论,提炼核心问题和观众反馈。 + 2. 实现:`HTTP Request` 节点流式获取直播评论 -> `Iterator` 节点以时间窗口为单位处理批数据 -> `LLM` 节点实时总结每段时间内的热点问题与情绪倾向 -> `Answer` 或 `Webhook` 节点输出摘要给主播。复杂度在于实时流数据处理和循环窗口。 + +## 3.2 职场工作流 + +1. 智能会议纪要与任务自动派发系统(复杂) + 1. 思路:从会议录音文本中提取纪要,并自动创建任务。 + 2. 实现:`Start` 输入会议文本 -> `LLM` 总结议题与结论 -> `Parameter Extractor` 节点精准抽取Action Items(任务、负责人、DDL)-> 一个 `LLM` 整合成纪要邮件 -> 并行 `HTTP Request` 节点调用Jira/Trello/飞书API创建任务。复杂度在于信息抽取与多系统联动。 +2. 简历批量筛选与初步评估助手(中等) + 1. 思路:自动解析简历,进行匹配度评估并生成面试问题。 + 2. 实现:`Start` 上传简历文件与JD -> `Document Extractor` 节点解析简历文本 -> `LLM` 扮演HR进行匹配度评估 -> 对高匹配者,另一个 `LLM` 生成深度面试问题。复杂度在于文档解析与多条件评估。 +3. 多语言邮件一键翻译与草稿回复(简单) + 1. 思路:自动翻译邮件并起草回复。 + 2. 实现:`Start` 输入邮件 -> `LLM` 判断语种并翻译 -> `LLM` 构思回复要点 -> `LLM` 翻译回原始语言并润色。主要依赖于LLM的序列调用。 +4. 周报/月报数据自动汇总与洞察生成(复杂) + 1. 思路:连接多个数据源,自动生成结构化工作报告。 + 2. 实现:多个 `HTTP Request`/`Tool` 节点并行调用业务系统API(如CRM、Git、项目管理工具)获取原始数据 -> `Code` 节点或 `LLM` 进行数据清洗与基础计算 -> `LLM` 分析趋势、亮点与风险,生成叙述性报告 -> `Answer` 输出图文并茂的文档。复杂度在于多数据源聚合、数据处理与智能分析结合。 +5. 合同/文档智能审查与要点提炼(中等) + 1. 思路:快速审查法律或商务文档,提示风险并提炼核心条款。 + 2. 实现:`Start` 上传合同PDF -> `Document Extractor` 提取文本 -> `LLM` 节点(设定为法律专家角色)审查责任条款、支付条件、违约条款等 -> `Parameter Extractor` 节点抽取出关键日期、金额、义务方等结构化数据 -> `Answer` 输出风险提示和要点表格。复杂度在于长文档处理与结构化信息抽取。 + +## 3.3 学习生活工作流 + +1. 学术论文深度解析与笔记生成器(复杂) + 1. 思路:上传论文PDF,自动生成结构化笔记。 + 2. 实现:`Start` 上传PDF -> `Document Extractor` 提取全文 -> 并行多个 `LLM` 节点分工总结摘要、方法、发现、参考文献 -> `Variable Aggregator` 汇总 -> `Answer` 输出Markdown笔记。复杂度在于并行处理长文本的不同部分。 + +2. 个性化旅行计划定制师(中等) + 1. 思路:根据用户偏好,自动规划详尽行程。 + 2. 实现:`Start` 输入需求(目的地、天数、预算、兴趣)-> `Tool` 节点调用搜索引擎或地图API获取地点信息 -> `LLM` 整合信息,设计每日行程(含时间、活动、预算估算)。复杂度在于外部信息获取与结构化规划。 + +3. 外语学习互动陪练伙伴(简单) + 1. 思路:创建可角色扮演和语法纠错的对话机器人。 + 2. 实现:系统设定AI角色 -> `Start` 接收用户语句 -> `LLM` 执行两项任务:角色回复 + 语法纠错与解释 -> `Answer` 输出。核心是LLM的多任务指令。 + +4. 个人知识库问答与链接推荐系统(复杂) + 1. 思路:基于你收藏的文档、笔记、网页链接,构建一个可问答并能推荐相关旧知识的智能系统。 + 2. 实现:离线处理:使用 `Document Extractor` 和 `Embedding` 工具将个人知识库切片并向量化存储。在线工作流:`Start` 输入问题 -> `Retrieval` 节点从向量库中查找最相关的知识片段 -> `LLM` 基于检索到的上下文生成答案 -> 同时,另一个分支使用检索到的内容作为输入,通过 `LLM` 生成“相关旧知识”推荐列表 -> `Answer` 合并输出答案与推荐。复杂度在于检索增强生成(RAG)流程的构建。 + +5. 健身/饮食计划追踪与调整顾问(中等) + 1. 思路:根据用户输入的每日饮食和训练日志,提供营养分析与训练建议。 + 2. 实现:`Start` 输入文本日志(如“午餐:鸡胸肉150g,米饭一碗,蔬菜若干;训练:深蹲5组”)-> `Parameter Extractor` 节点尝试结构化输入数据 -> `LLM` 扮演健身教练,分析营养摄入是否均衡、训练容量是否合适 -> 对比长期目标,给出微调建议(如“蛋白质摄入充足,建议增加蔬菜种类”)。复杂度在于从非结构化日志中提取结构化信息并提供个性化反馈。 + +# 6. 工作流平台的局限性 + +工作流平台(或称低代码平台)并非万能解决方案。它虽然对业务人员友好,降低了直接编码的门槛,但从另一个角度看,“低代码”往往也是一种“高代码”——用户仍需理解平台的概念、规则与操作逻辑,这本身构成了一种新的学习成本。 + +也许你想问,很多简单的工作流其实就是大模型函数包装后的前后调用,前面函数的输出作为后者函数的输入,本质上几行代码就能够解决,为什么需要那么复杂的多重包装工作流?反而给 API 调用造成了麻烦。 + +你说得是对的。在当前 vibe coding 的快速发展下,借助 AI 代码生成能力,直接阅读甚至生成代码有时可能更加高效。理想情况下,我们希望能用自然语言直接操作应用逻辑,这才是一个现代的软件平台。但目前的工作流平台尚未实现这一点,因此它在用户意图与最终实现之间天然存在一个“中间层”。掌握这个中间层,正是一种需要投入时间学习的成本。理想上,之后的工作流平台也要支持全 AI 自动对话操作,我们可以让 AI 真正操作工作流搭建以及入参的每一个细节环节。 + +尽管如此,熟练使用这类平台正逐渐成为一项基础技能,如同微软的办公软件一样,在业务中非常普遍且实用,值得掌握。 + +在后续的进阶课程中,我们将介绍如何通过代码级别的工作流与 RAG 开发平台进行构建。届时,你可以亲身体验不同实现方式在复杂度与灵活性上的区别。(值得注意的是,一些简单的对话应用或嵌套逻辑,用工作流实现可能并不困难。) + +# 📚 课后作业 + +## 掌握 Dify 基本操作 + +为了测试你掌握了 Dify 的常见基础使用工具,你需要完成一个基础作业和两个 “小挑战”,确保你已入门常见的操作。你需要将附带的两个 DSL 文件导入 Dify 工作流,并成功完成对应工作流的挑战(遇到不懂的地方截图询问大模型,或自己探索其中的每个参数的用法,最后实现目标)。: + +1. 参考意图分类工作流的方法,让大模型给你建议完全换一套场景进行应用,但是一定要用到意图分类工作流,最后提交运行的工作流截图、场景说明、结果。 +2. Log in workflow 工作流解密挑战 + +在这个解密挑战中,你需要完成以下挑战,让工作流实现下列功能: + +- 找出正确的密码! +- 将密码修改为 0925 +- 当密码不正确时,提供第二次尝试机会(不提供第三次) +- 当用户提及要再次登录时,为用户提供重新输入密码的机会 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image94.png) + +参考输入输出: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image95.png) + +3. Love loop workflow 工作流解密挑战 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image96.png) + +在这个解密挑战中,你需要修复当前工作流的问题,让工作流最后的输出类似如下显示: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image97.png) + +如果你遇到无法解决的问题,请截图询问大模型,或查阅官方文档得到结果:[https://docs.dify.ai/en/use-dify/getting-started/quick-start](https://docs.dify.ai/en/use-dify/getting-started/quick-start) + +## 实现 Dify API 调用 + +为了测试你真正掌握了 Dify 的 API 调用知识,你需要完成以下任务: + +1. Despliegue Dify 并创建一个简单的知识库(选取你喜欢的资料)。 +2. 使用 Trae IDE 构建一个对话前端,与 Dify 知识库进行 API 交互。 +3. 测试多轮对话的效果,确保程序正常运行。 + +你需要提交最终运行截图和知识库的处理过程截图。 + +## 试用第三方工作流 / 构建一个自己的业务工作流 + +请你在 Github、微信公众号、或者 Reddit、推特上等所有地方找到你想尝试的别人的 Dify 工作流,下载导入后成功运行;或者你可以根据上文中提到的业务工作流参考,根据现实中的具体需求创建一个自己的业务工作流进行运行。 + +最后你需要提交运行成功的截图,并说明这个工作流的作用。 + +# [Bug] HTTP 请求错误问题的解决方法 + +如果你遇到了如下图所示的问题,才需要参考本节方案进行解决,否则可以不理会当前部分。 + +有时候可能你会把 Dify Despliegue在自己的服务器,但是服务器的对外地址通常都是 http 而不是 https 的,但当我们请求一个只支持 HTTP 的服务时,你可能会看到类似这样的提示(启用 F12 浏览器调试信息模式,查看有问题的点): + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image98.png) + +出现这个问题的原因,是因为我们默认把 Dify Despliegue在一台只支持 HTTP 而不支持 HTTPS 的服务器上。 HTTPS(HyperText Transfer Protocol Secure)是在 HTTP(超文本传输协议)的基础上增加了 SSL/TLS 加密层,可以简单理解为“更安全版的 HTTP”。 + +如果要让服务支持 HTTPS,一般可以: + +- 使用其他程序转发请求(例如在有证书的 nginx 上做反向代理),或者 +- 绑定域名后为该域名申请证书。 + +但这些操作都比较复杂,在这里我们使用 Zeabur 作为网络转发网关来解决问题。 + +Zeabur 的网页默认是通过 HTTPS 访问的,因此我们只需要把原来请求的域名转发到 Zeabur 提供的域名,就可以修复这个问题。 + +- 原始地址:`http://{DIFY_API_URL}/v1/chat-messages` +- 现在地址:`https://{DIFY_NEW_API_URL}.zeabur.app/v1/chat-messages` + +你只需要简单地把 URL 中的域名部分(公网 IP 或域名)替换为已经在 Zeabur 上Despliegue好的域名即可,我们已经提前在服务里配置好了转发功能。 + +如果你感兴趣,也可以自己在 Zeabur 上Despliegue一个转发服务。在 Zeabur 中创建服务时,选择 Python,然后填入下面的 Python 代码,Despliegue后即可得到一个 https 的地址,https 即可正常使用。 + +Despliegue完成后,在网络设置中把程序监听端口设置为本地 8080,并对外暴露该端口。 + +注意:请将 `{DIFY_API_URL}` 替换为实际的 Dify API 地址。 + +```python +from flask import Flask, request, Response +import requests + +app = Flask(__name__) + +TARGET_BASE_URL = "{DIFY_API_URL}" +LISTEN_PORT = 8080 + +@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +@app.route('/', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +def proxy_request(path): + target_url = f"{TARGET_BASE_URL}/{path}" + if request.query_string: + target_url += f"?{request.query_string.decode('utf-8')}" + + headers = {key: value for key, value in request.headers if key.lower() not in ['host', 'connection', 'content-length', 'accept-encoding']} + + try: + resp = requests.request( + method=request.method, + url=target_url, + headers=headers, + data=request.get_data(), + cookies=request.cookies, + allow_redirects=False, + timeout=30 + ) + + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + response_headers = [(name, value) for name, value in resp.raw.headers.items() if name.lower() not in excluded_headers] + + return Response(resp.content, resp.status_code, response_headers) + + except requests.exceptions.RequestException as e: + print(f"Error forwarding request to {target_url}: {e}") + return Response(f"Proxy Error: Could not reach target server or invalid response: {e}", status=502) + except Exception as e: + print(f"An unexpected error occurred: {e}") + return Response(f"Internal Proxy Error: {e}", status=500) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=LISTEN_PORT, debug=True) +``` diff --git a/docs/es-es/stage-2/assignments/copywriting-platform-supabase/index.md b/docs/es-es/stage-2/assignments/copywriting-platform-supabase/index.md new file mode 100644 index 0000000..1c5d33c --- /dev/null +++ b/docs/es-es/stage-2/assignments/copywriting-platform-supabase/index.md @@ -0,0 +1,346 @@ +# AI 营销文案 SaaS 开发实战 + +## Descripcion general + +Este proyecto practico te requiere trabajar con un PRD real,completar desde cero un面向独立开发者和内容团队的 AI 营销文案 SaaS 产品。你将使用 Supabase 作为后端服务、Stripe 作为支付系统,完成从Analisis de requisitos到Despliegue上线的全过程。 + +Esta es la seccion de practica integral de la Etapa 2。在前面几章中,你已经分别学习了前端页面搭建、后端接口开发、数据库操作、Integracion de pagos等单项技能——这个项目要求你把它们全部串起来,交付一个可运行的产品原型。 + +## Conocimientos previos + +Antes de comenzar este proyecto, ya deberias dominar lo siguiente: + +- Diseno de paginas frontend y uso de bibliotecas de componentes([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- Diseno y desarrollo de interfaces backend([接口代码编写](../../backend/ai-interface-code/)) +- Fundamentos de bases de datos y Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Integracion de pagos([Stripe 收费系统](../../backend/stripe-payment/)) +- Flujo de trabajo de Git y despliegue([Git 和 GitHub](../../backend/git-workflow/)、[Despliegue Web 应用](../../backend/zeabur-deployment/)) + +## Objetivos de aprendizaje + +Despues de completar esta practica, podras: + +1. Leer y comprender un PRD real, extrayendo una lista de tareas de desarrollo +2. 使用 AI 辅助分步Generar paginas frontend和后端接口 +3. Usar Supabase para implementar autenticacion de usuarios y operaciones de base de datos +4. Integrar Stripe para implementar funcionalidad de suscripcion de pago +5. Construir un panel de administracion y completar la integracion de extremo a extremo + +## Introduccion del proyecto + +El producto que vas a construir es一个 AI 营销文案 SaaS,包含三个Subsistema: + +| Subsistema | Responsabilidad | +|--------|------| +| **Sitio web publico** | Introduccion del producto, precios, FAQ, conversion de registro | +| **Espacio de trabajo del usuario** | Ingresar informacion del producto, generar textos, ver historial, mejorar plan | +| **Panel de administracion** | Gestion de usuarios, registros de generacion, datos de pago, resumen de operaciones | + +El backend usa Supabase 提供数据库和鉴权能力,使用 Stripe 处理支付,使用 AI 模型生成营销文案。 + +::: tip PRD 入口 +El documento de requisitos de este proyecto esta en GitHub: [Ver PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/es-es/stage-2/assignments/copywriting-platform-supabase/PRD.md) +::: + +
+ + + +
+ +## Primera parte:Analisis de requisitos + +### 1.1 Leer el PRD + +打开 PRD 文档,重点回答以下问题: + +- 系统有几个入口?各自覆盖哪些页面? +- 每个页面的核心功能是什么? +- 后端包含哪些模块和数据表? +- 套餐定价、支付流程、免费额度如何设计? +- MVP 范围是什么?第一版哪些做,哪些不做? + +::: warning +Si no tienes respuestas claras a las preguntas anteriores, no comiences a escribir codigo. La comprension inadecuada de los requisitos es la causa mas comun de retrabajo. +::: + +### 1.2 Confirmar la arquitectura del sistema + +Segun el PRD, organiza la arquitectura general del sistema: + +```mermaid +flowchart TD + prd["PRD"] --> web["Sitio web publico"] + prd --> app["Espacio de trabajo del usuario"] + prd --> admin["Panel de administracion"] + app --> auth["鉴权"] + app --> gen["文案生成任务"] + gen --> db["数据库"] + billing["支付与套餐"] --> db + admin --> analytics["用户 / 生成 / 支付看板"] +``` + +## Segunda parte:搭建项目骨架 + +### 2.1 Generar paginas frontend + +使用 AI 先生成所有页面的基本结构和假数据。 + +Referencia de prompts: + +```text +请基于当前 PRD,帮我生成一个 AI 营销文案 SaaS 的前端骨架。 + +要求: +1. 分成三个入口:www、app、admin +2. 官网包括:首页、定价、FAQ +3. app 包括:登录、注册、生成工作台、历史记录、套餐页 +4. admin 包括:后台首页、用户管理、生成记录、支付订单 +5. 先只生成页面结构和假数据,不接真实接口 +6. 风格要像现代 SaaS,不像课堂 demo +``` + +### 2.2 Mejorar paginas clave + +骨架搭好后,重点完善文案生成工作台(Dashboard)页面: + +```text +请继续完善 /dashboard 页面。 + +这是一个 AI 营销文案工作台。 + +左侧表单字段: +- 产品名 +- 一句话介绍 +- 目标用户 +- 3 个卖点 +- 投放渠道(官网、朋友圈、小红书、抖音、邮件) + +右侧结果区域预留: +- 主标题 +- 副标题 +- CTA +- 3 版短文案 +- 长文案 + +先用 mock 数据跑通交互。 + +要求: +- 点击"生成文案"后有 loading 状态 +- 结果区域设计空状态 +- 响应式布局,宽屏窄屏都能正常显示 +``` + +### 2.3 Verificar la estructura de paginas + +Verificar item por item: + +- [ ] 三个入口的路由是否独立 +- [ ] 页面数量是否与 PRD 一致 +- [ ] Dashboard 的表单和结果区域布局合理 +- [ ] 假数据展示了基本的 UI 状态 + +### Encontraste un obstaculo? + +Si te quedas atascado en la etapa de construccion del frontend, puedes revisar estos capitulos: + +- [UI 设计](../../frontend/ui-design/) +- [参考 UI 设计规范设计页面和按钮](../../frontend/multi-product-ui/) +- [用 LLM 和 Skills 让界面变好看](../../frontend/llm-skills-beautiful/) +- [从设计原型到项目代码](../../frontend/design-to-code/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) + +## Tercera parte:后端集成 + +### 3.1 接入 Supabase 登录 + +```text +Tratame como un principiante total,一步一步带我完成 Supabase 登录接入。 + +需要你帮我完成: +1. 项目接入 Supabase +2. 实现注册、登录、退出功能 +3. 登录成功后跳转到 /dashboard +4. 未登录用户访问 /dashboard、/billing、/admin 时自动跳转 /login +5. 创建 profiles 表 +6. 用户注册成功后自动在 profiles 表创建记录 +7. profiles 表包含 email、role、plan 字段 + +实现要求: +- 每步都说明在修改哪些文件 +- 密钥不要硬编码 +- 需要在 Supabase 后台手动操作的地方请明确标注 +- 完成后说明如何验证注册和登录 +``` + +### 3.2 接入生成接口和数据库 + +```text +Tratame como un principiante total,帮我完成网站的核心功能:生成营销文案并保存。 + +目标效果: +1. 用户在 /dashboard 填写表单,点击"生成文案" +2. 后端接收:产品名、介绍、目标用户、卖点、投放渠道 +3. 后端调用模型生成结果 +4. 页面展示生成结果 +5. 输入和输出都保存到数据库 +6. 用户下次进入可查看历史记录 + +需要你完成: +- 创建生成接口 /api/generate +- 创建 generations 表 +- 设计输入和输出字段 +- Dashboard 页面读取当前用户的历史记录 + +用户体验: +- 按钮 loading 状态 +- 生成失败时的错误提示 +- 无历史记录时的空状态 + +完成后请说明: +- 前端页面文件位置 +- 后端接口文件位置 +- 数据写入数据库的逻辑位置 +- 如何测试完整生成链路 +``` + +### 3.3 接入 Stripe 付费 + +```text +Tratame como un principiante total,帮我给 LaunchKit 加上最简可用的 Stripe 付费。 + +不需要复杂系统,先跑通最基本的付费链路。 + +需要你完成: +1. /billing 页面展示 free 和 pro 两个套餐 +2. 用户点击升级后跳转 Stripe Checkout +3. 支付成功后返回网站 +4. 支付结果保存到 subscriptions 表 +5. 同步更新 profile.plan 字段 +6. free 用户每日限 3 次生成,pro 用户不限 + +实现原则: +- 先跑通主流程,暂不考虑复杂边界 +- 需要在 Stripe 后台配置的地方请写清楚 +- 完成后说明如何测试完整支付流程 +``` + +### 3.4 搭建Panel de administracion + +```text +Tratame como un principiante total,帮我做一个简洁可用的Panel de administracion。 + +仅限管理员访问。 + +需要你完成: +1. 仅 role = admin 的用户可访问 /admin +2. 后台包含 3 个 Tab:用户列表、生成记录、订阅状态 +3. 用户列表显示:email、plan、创建时间 +4. 生成记录显示:用户、产品名、渠道、创建时间 +5. 订阅状态显示:用户、套餐、支付状态 + +要求: +- 界面简洁清晰 +- 使用现有组件库的表格、Tab、Badge +- 完成后说明如何将账号设为 admin +``` + +### Encontraste un obstaculo? + +如果你在Desarrollo backend阶段卡住,可以回顾这些章节: + +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [如何集成 Stripe 等收费系统](../../backend/stripe-payment/) + +## Cuarta parte:联调与上线 + +### 4.1 Pruebas de extremo a extremo + +Verificar al menos los siguientes escenarios: + +- 注册 → 登录 → 生成文案 → 查看历史 → 升级套餐 +- 管理员登录 → 查看用户数据 → 查看生成记录 → 查看支付状态 + +Verificacion antes del despliegue: + +```text +Tratame como un principiante total,帮我Item de verificacion目是否具备Despliegue条件。 + +检查重点: +- 环境变量是否完整 +- 登录回调地址是否正确 +- Stripe 支付回调地址是否正确 +- 页面是否缺少 loading、空状态、错误提示 +- README 是否包含启动说明和Despliegue说明 + +需要你: +1. 按优先级列出待修复事项 +2. 标注哪些必须先修 +3. 说明修复后的Despliegue步骤 +``` + +### 4.2 Despliegue + +Desplegar el proyecto en un entorno publico. Tutorial de despliegue de referencia:[Git 和 GitHub 工作流](../../backend/git-workflow/)、[如何Despliegue Web 应用](../../backend/zeabur-deployment/)。 + +## Entregables + +Despues de completar este proyecto, necesitas enviar lo siguiente: + +- [ ] Enlace de demostracion en linea accesible +- [ ] Enlace al repositorio de codigo fuente (incluyendo README) +- [ ] PRD 文档 +- [ ] Capturas de pantalla de paginas clave(首页、Dashboard、Billing、Admin) +- [ ] 60 segundos de video de demostracion(覆盖注册 → 生成 → 支付 → 后台) + +README 至少包含:Introduccion del proyecto、核心页面说明、技术栈、本地启动步骤、环境变量清单。 + +## Criterios de evaluacion + +| 维度 | Requisitos basicos | Requisitos avanzados | +|------|---------|---------| +| 产品完整度 | 首页、登录、Dashboard、Billing、Admin 都能访问 | 首页文案和视觉风格像真实 SaaS | +| Ciclo completo del negocio | 注册 → 登录 → 生成 → 查看历史可以跑通 | 免费/Pro 权限差异清晰可见 | +| Correccion de datos | 生成结果和支付状态都写入数据库 | 有明确的错误提示、空状态和 loading | +| Permisos y seguridad | 未登录不能访问受保护页面,普通用户不能进 Admin | 有基本的输入校验和服务端鉴权 | +| Entrega de ingenieria | 项目可本地启动,也可Despliegue到公网 | README 清楚,演示视频结构完整 | + +::: tip +如果你觉得任务太大,记住一个原则:**先保证"能跑通",再去追求"做漂亮"。** +::: + +## Verificacion antes de enviar + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## Referencias + +- [UI 设计](../../frontend/ui-design/) +- [参考 UI 设计规范设计页面和按钮](../../frontend/multi-product-ui/) +- [用 LLM 和 Skills 让界面变好看](../../frontend/llm-skills-beautiful/) +- [从设计原型到项目代码](../../frontend/design-to-code/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何Despliegue Web 应用](../../backend/zeabur-deployment/) +- [如何集成 Stripe 等收费系统](../../backend/stripe-payment/) diff --git a/docs/es-es/stage-2/assignments/custom-dify-agent-platform/index.md b/docs/es-es/stage-2/assignments/custom-dify-agent-platform/index.md new file mode 100644 index 0000000..29fcf32 --- /dev/null +++ b/docs/es-es/stage-2/assignments/custom-dify-agent-platform/index.md @@ -0,0 +1,210 @@ +# 类 Dify 智能体平台开发实战 + +## Descripcion general + +Este proyecto practico te requiere trabajar con un PRD real,completar desde cero un模仿 Dify 核心体验的智能体平台。你将构建Consola de usuario、Panel de administracion和平台后端,实现智能体管理、对话、日志和知识库等核心功能。 + +Esta es la seccion de practica integral de la Etapa 2。与前面的单页面或单功能项目不同,这个项目要求你构建一个有"平台感"的 AI 产品——包含多角色、多模块、数据持久化和模型调用链路。 + +## Conocimientos previos + +Antes de comenzar este proyecto, ya deberias dominar lo siguiente: + +- Diseno de paginas frontend y uso de bibliotecas de componentes([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- Diseno y desarrollo de interfaces backend([接口代码编写](../../backend/ai-interface-code/)) +- Fundamentos de bases de datos y Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Flujo de trabajo de Git y despliegue([Git 和 GitHub](../../backend/git-workflow/)、[Despliegue Web 应用](../../backend/zeabur-deployment/)) + +## Objetivos de aprendizaje + +Despues de completar esta practica, podras: + +1. Leer y comprender un PRD real, extrayendo una lista de tareas de desarrollo +2. Disenar la arquitectura de paginas y el modelo de datos de una plataforma de agentes +3. Implementar el ciclo completo de creacion de agentes, conversacion y registro de logs +4. Usar IA para asistir en el desarrollo de productos tipo plataforma +5. Completar la integracion de extremo a extremo, entregando un prototipo de plataforma IA demostrable + +## Introduccion del proyecto + +El producto que vas a construir es一个类 Dify 智能体平台,包含两个Subsistema: + +| Subsistema | Responsabilidad | +|--------|------| +| **Consola de usuario** | Crear agentes, configurar Prompt, iniciar conversaciones, ver registros, gestionar base de conocimientos | +| **Panel de administracion** | Ver datos de usuarios, uso de recursos de la plataforma, estadisticas de llamadas | + +后端necesita soportar las siguientes capacidades centrales:Gestion de agentes, gestion de sesiones, almacenamiento de mensajes, llamadas a modelos, registro de llamadas, integracion de base de conocimientos。 + +::: tip PRD 入口 +El documento de requisitos de este proyecto esta en GitHub: [Ver PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/es-es/stage-2/assignments/custom-dify-agent-platform/PRD.md) +::: + +
+ + + +
+ +## Primera parte:Analisis de requisitos + +### 1.1 Leer el PRD + +打开 PRD 文档,重点回答以下问题: + +- 智能体、会话、日志、知识库哪些要进 MVP? +- 页面和路由清单是否拍板? +- 模型调用和日志记录的边界是什么? +- 多租户和复杂工作流是否先不做? + +::: warning +Si no tienes respuestas claras a las preguntas anteriores, no comiences a escribir codigo. La comprension inadecuada de los requisitos es la causa mas comun de retrabajo. +::: + +### 1.2 Confirmar la arquitectura del sistema + +Segun el PRD, organiza la arquitectura general del sistema: + +```mermaid +flowchart TD + prd["PRD"] --> app["Consola de usuario"] + prd --> admin["Panel de administracion"] + app --> auth["鉴权"] + app --> agent["智能体配置"] + app --> chat["会话对话"] + chat --> llm["模型调用"] + chat --> db["数据库"] + app --> kb["知识库接入"] + admin --> logs["调用日志与平台概览"] + logs --> db +``` + +## Segunda parte:搭建项目骨架 + +### 2.1 Generar paginas frontend + +Referencia de prompts: + +```text +请基于当前 PRD,帮我生成一个类 Dify 智能体平台的前端骨架。 + +要求: +1. 用户侧包括:登录、智能体列表、智能体配置、对话页、日志页、知识库页 +2. 后台侧包括:后台首页、用户概览、资源使用概览 +3. 先只生成页面结构和假数据,不接真实接口 +4. 风格要像现代 AI 平台 +``` + +### 2.2 Verificar la estructura de paginas + +Verificar item por item: + +- [ ] Consola de usuario和Panel de administracion入口是否分开 +- [ ] 智能体列表、配置、对话、日志、知识库页面是否完整 +- [ ] Panel de administracion首页、用户概览页面是否可访问 +- [ ] 假数据展示了基本的 UI 状态 + +## Tercera parte:Desarrollo iterativo + +### 3.1 Avanzar por modulos + +在骨架的基础上,按以下顺序逐模块补充功能: + +1. **鉴权**:注册、登录、角色区分 +2. **智能体管理**:创建、编辑、删除、Prompt 配置 +3. **对话功能**:会话创建、消息收发、模型调用 +4. **日志记录**:耗时、token 用量、错误记录 +5. **知识库接入**(加分项):文档上传、检索、结果注入 +6. **Panel de administracion**:用户数据、资源使用、调用统计 + +每完成一个模块,使用下表进行自检: + +| Item de verificacion | Metodo de verificacion | +|--------|----------| +| 页面一致性 | 页面数量、功能是否符合 PRD | +| 接口闭环 | agents、chat、logs、knowledge 接口是否完整 | +| Aislamiento de permisos | 用户是否只能管理自己的 agent 和会话 | +| Consistencia de datos | messages、logs、documents 数据是否对得上 | +| Demostrabilidad | 是否能演示"创建 agent → 对话 → 查看日志"完整链路 | + +### 3.2 知识库接入(加分项) + +如果你想增加知识库能力,可以给每个智能体增加一个"知识库开关": + +- 开启后先检索知识片段,再和用户问题一起发送给模型 +- 关闭后按普通对话模式响应 + +第一版不必追求复杂 RAG,只要有"检索结果可见、调用链路可解释"即可。 + +## Cuarta parte:联调与上线 + +### 4.1 Pruebas de extremo a extremo + +Verificar al menos los siguientes escenarios: + +- 注册 → 创建智能体 → 配置 Prompt → 发起对话 → 查看日志 +- 管理员登录 → 查看用户数据 → 查看调用统计 + +Verificacion antes del despliegue: + +- [ ] 所有核心接口都做了登录校验 +- [ ] 智能体归属权限检查通过 +- [ ] 会话记录、日志记录真实落库 +- [ ] 模型 Key 使用环境变量,不硬编码 +- [ ] 错误提示可在前端看到,不只打控制台 + +### 4.2 Despliegue + +Desplegar el proyecto en un entorno publico. Tutorial de despliegue de referencia:[Git 和 GitHub 工作流](../../backend/git-workflow/)、[如何Despliegue Web 应用](../../backend/zeabur-deployment/)。 + +## Entregables + +Despues de completar este proyecto, necesitas enviar lo siguiente: + +- [ ] Enlace de demostracion en linea accesible +- [ ] Enlace al repositorio de codigo fuente (incluyendo README) +- [ ] PRD 文档 +- [ ] Capturas de pantalla de paginas clave(智能体管理页、对话页、日志页、后台首页) +- [ ] 60 segundos de video de demostracion(覆盖创建智能体 → 对话 → 查看日志) + +README 至少包含:Introduccion del proyecto、架构说明、技术栈、本地启动步骤、环境变量清单、接口说明。 + +## Criterios de evaluacion + +| 维度 | Requisitos basicos | Requisitos avanzados | +|------|---------|---------| +| 平台完整度 | agents / chat / logs 三页可用 | 有清晰导航与统一设计语言 | +| Ciclo completo del negocio | 可创建智能体并真实对话 | 支持多智能体切换与历史会话 | +| 数据与追踪 | 消息与调用日志可查询 | 有 token / 耗时统计看板 | +| 权限安全 | 仅登录用户可访问核心接口 | 资源归属校验完善 | +| Entrega de ingenieria | 可Despliegue、可演示、README 清晰 | 接入知识库并可解释检索结果 | + +## Verificacion antes de enviar + + + + +
    +
  • +
  • +
  • +
  • +
  • +
+
+ +## Referencias + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何Despliegue Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/es-es/stage-2/assignments/exam-management-express/index.md b/docs/es-es/stage-2/assignments/exam-management-express/index.md new file mode 100644 index 0000000..ab37f4e --- /dev/null +++ b/docs/es-es/stage-2/assignments/exam-management-express/index.md @@ -0,0 +1,306 @@ +# 在线考试与管理系统开发实战 + +## Descripcion general + +Este proyecto practico te requiere trabajar con un PRD real,completar desde cero un在线考试与管理系统。这个项目的特别之处在于它包含多个角色(学生和管理员),每个角色看到的页面和能执行的操作不同。你将使用 Express 构建后端,实现完整的考试业务链路。 + +Esta es la seccion de practica integral de la Etapa 2。多角色权限系统在实际工作中非常常见,掌握这种模式后,你能够应对教培、SaaS、后台管理等各类业务场景。 + +## Conocimientos previos + +Antes de comenzar este proyecto, ya deberias dominar lo siguiente: + +- Diseno de paginas frontend y uso de bibliotecas de componentes([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- Diseno y desarrollo de interfaces backend([接口代码编写](../../backend/ai-interface-code/)) +- Fundamentos de bases de datos y Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Flujo de trabajo de Git y despliegue([Git 和 GitHub](../../backend/git-workflow/)、[Despliegue Web 应用](../../backend/zeabur-deployment/)) + +## Objetivos de aprendizaje + +Despues de completar esta practica, podras: + +1. Leer y comprender un PRD real, extrayendo una lista de tareas de desarrollo +2. 设计多角色系统的Control de permisos和页面路由 +3. Usar Express para implementar una API backend completa +4. Implementar el flujo de negocio de examenes, envio y calificacion automatica +5. Completar la integracion de extremo a extremo, entregando un prototipo de sistema empresarial demostrable + +## Introduccion del proyecto + +El producto que vas a construir es一个在线考试与管理系统,包含三个Subsistema: + +| Subsistema | Responsabilidad | +|--------|------| +| **Sitio web publico** | Introduccion de la plataforma, entrada de login | +| **Portal de estudiante** | Lista de examenes, responder preguntas, enviar, ver calificaciones | +| **Panel de administracion** | Gestion del banco de preguntas, gestion de examenes, registros de envio, estadisticas de calificaciones | + +El backend usa Express,需要支持:登录鉴权、角色权限、考试和题库管理、提交流程与自动判分、成绩和统计管理。 + +::: tip PRD 入口 +El documento de requisitos de este proyecto esta en GitHub: [Ver PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/es-es/stage-2/assignments/exam-management-express/PRD.md) +::: + +
+ + + +
+ +## Primera parte:Analisis de requisitos + +### 1.1 Leer el PRD + +打开 PRD 文档,重点回答以下问题: + +- Cuales roles tiene el sistema? Que puede hacer cada uno? +- 页面清单是否完整?Portal de estudiante和Portal de administracion分别有哪些页面? +- Que tipos de preguntas se soportan? Cual es la logica de calificacion para cada tipo? +- Cual es el flujo completo del examen? (Publicar -> Comenzar -> Responder -> Enviar -> Calificar -> Ver calificaciones) + +::: warning +Si no tienes respuestas claras a las preguntas anteriores, no comiences a escribir codigo. La comprension inadecuada de los requisitos es la causa mas comun de retrabajo. +::: + +### 1.2 Confirmar la arquitectura del sistema + +Segun el PRD, organiza la arquitectura general del sistema: + +```mermaid +flowchart TD + prd["PRD"] --> web["Sitio web publico"] + prd --> student["Portal de estudiante"] + prd --> admin["Panel de administracion"] + student --> auth["鉴权"] + student --> exam["考试与作答"] + exam --> db["数据库"] + admin --> question["题库管理"] + admin --> submission["提交记录与成绩统计"] + question --> db + submission --> db +``` + +## Segunda parte:搭建项目骨架 + +### 2.1 Generar paginas frontend + +Referencia de prompts: + +```text +请基于当前 PRD,帮我生成一个在线考试与管理系统的前端骨架。 + +技术栈要求: +- Next.js App Router +- TypeScript +- Tailwind CSS +- shadcn/ui + +页面清单: +1. 首页 / +2. 登录页 /login +3. 学生考试列表页 /student/exams +4. 学生答题页 /student/exams/[id] +5. 学生成绩页 /student/history +6. Panel de administracion首页 /admin +7. 考试管理页 /admin/exams +8. 题库管理页 /admin/questions +9. 提交记录页 /admin/submissions + +要求: +- Portal de estudiante页面强调清晰、专注、易答题 +- Portal de administracion页面使用侧边栏 + 顶部栏布局 +- 先使用 mock 数据,不接真实接口 +- 注意桌面端和移动端的基本可用性 +``` + +### 2.2 完善学生答题页 + +答题页是Portal de estudiante的核心页面,重点完善: + +```text +请继续完善学生答题页。 + +这是一个在线考试系统的答题页面,需要包含: +- 顶部显示考试标题、倒计时、已答题数量 +- 中间显示题干和选项 +- 支持单选、判断、简答三种题型 +- 左侧或顶部有答题卡,显示每道题是否已作答 +- 点击提交前弹出确认框 + +先用 mock 数据实现交互,不接真实接口。 + +要求: +- 界面简洁,不要像后台表格页 +- 倒计时要醒目,但不要制造过强压迫感 +- 有空状态和 loading 状态 +``` + +### 2.3 Mejorar el backend de administracion + +管理员后台第一版聚焦三个核心区域: + +- **考试管理**:创建考试、设置时长、发布状态 +- **题库管理**:新增题目、编辑题目、按题型筛选 +- **提交记录**:查看学生提交、分数、时间 + +### 2.4 Verificar la estructura de paginas + +Verificar item por item: + +- [ ] Portal de estudiante和Portal de administracion入口是否分开 +- [ ] 登录页、考试列表、答题页、成绩页是否完整 +- [ ] Portal de administracion题库、考试管理、提交记录页是否可访问 +- [ ] Portal de estudiante和Portal de administracion的页面风格有明显区分 + +### Encontraste un obstaculo? + +Si te quedas atascado en la etapa de construccion del frontend, puedes revisar estos capitulos: + +- [从数据库到 Supabase](../../backend/database-supabase/) +- [应用Diseno y desarrollo de interfaces backend](../../backend/ai-interface-code/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) + +## Tercera parte:Desarrollo backend + +### 3.1 登录与Control de permisos + +```text +Tratame como un principiante total,帮我完成在线考试系统的登录与Control de permisos。 + +El backend usa Express。 + +目标: +1. 学生和管理员都可以登录 +2. 登录后返回用户角色 +3. 学生只能访问 /student/* 相关接口 +4. 管理员只能访问 /admin/* 相关接口 +5. 未登录用户访问受保护页面时跳转 /login + +实现要求: +- 给出清晰的目录结构建议 +- 明确说明中间件负责什么 +- 涉及环境变量的地方不要硬编码 +- 完成后说明如何验证权限是否生效 +``` + +### 3.2 考试与题库管理接口 + +建议按以下模块实现: + +| 模块 | 推荐接口 | +|------|----------| +| 考试管理 | `GET /api/exams`、`POST /api/admin/exams`、`PATCH /api/admin/exams/:id` | +| 题库管理 | `GET /api/admin/questions`、`POST /api/admin/questions` | +| 开始考试 | `POST /api/submissions/start` | +| 提交试卷 | `POST /api/submissions/:id/submit` | +| 成绩记录 | `GET /api/student/history`、`GET /api/admin/submissions` | + +Referencia de prompts: + +```text +请帮我为在线考试系统设计并实现 Express API。 + +功能范围: +- 管理员创建考试 +- 管理员维护题库 +- 学生查看已发布考试 +- 学生开始考试并创建 submission +- 学生提交答案后自动判分单选题和判断题 +- 简答题先标记为待复核 +- 学生查看自己的历史成绩 +- 管理员查看所有提交记录 + +要求: +- 接口命名清晰 +- 返回统一 JSON 结构 +- 代码中区分 controller、service、middleware、db 层 +- 说明每个接口如何测试 +``` + +### 3.3 判分逻辑 + +判分逻辑是考试系统的核心业务规则: + +- **单选题**:用户答案与标准答案一致则得分 +- **判断题**:同样可以自动判分 +- **简答题**:第一版先只保存答案,分数为空,状态为 `reviewed = false` + +::: tip 加分项 +如果你想增加 AI 能力,可以让管理员在后台输入"主题 + 难度",由模型先生成一批候选题,再人工审核后入库。但这属于加分项,不是必须的。 +::: + +## Cuarta parte:联调与上线 + +### 4.1 Pruebas de extremo a extremo + +Verificar al menos los siguientes escenarios: + +- 学生登录 → 查看考试列表 → 开始答题 → 提交 → 查看成绩 +- 管理员登录 → 创建考试 → 添加题目 → 发布 → 查看提交记录 + +### 4.2 Despliegue + +- 前端Despliegue到 Vercel / Zeabur +- Express API Despliegue到 Zeabur / Railway / Render +- 数据库用 Supabase Postgres 或托管 PostgreSQL + +Verificacion antes del despliegue: + +- [ ] 环境变量是否齐全 +- [ ] 前后端 API 地址是否正确 +- [ ] 登录态在生产环境是否正常 +- [ ] 管理员账号是否能真实访问后台 +- [ ] README 是否包含启动、Despliegue、测试说明 + +## Entregables + +Despues de completar este proyecto, necesitas enviar lo siguiente: + +- [ ] Enlace de demostracion en linea accesible +- [ ] Enlace al repositorio de codigo fuente (incluyendo README) +- [ ] PRD 文档 +- [ ] Capturas de pantalla de paginas clave(首页、学生考试列表、答题页、Panel de administracion) +- [ ] 60 segundos de video de demostracion(覆盖学生答题流程和管理员管理流程) + +README 至少包含:Introduccion del proyecto、核心页面说明、技术栈、本地启动步骤、环境变量清单。 + +## Criterios de evaluacion + +| 维度 | Requisitos basicos | Requisitos avanzados | +|------|---------|---------| +| Completitud de paginas | Portal de estudiante和Portal de administracion主要页面都可访问 | 页面风格统一,移动端基本可用 | +| Ciclo completo del negocio | 学生可登录、参加考试、提交并查看成绩 | 管理员可完整创建并发布考试 | +| Correccion de datos | 提交答案后能写入数据库,客观题能自动判分 | 简答题支持人工复核或 AI 辅助 | +| Control de permisos | 学生与管理员访问边界清晰 | 服务端接口也有角色校验 | +| Entrega de ingenieria | 项目可运行、可Despliegue、README 清晰 | 有演示视频和测试说明 | + +## Verificacion antes de enviar + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## Referencias + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何Despliegue Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/es-es/stage-2/assignments/modern-landing-page/index.md b/docs/es-es/stage-2/assignments/modern-landing-page/index.md new file mode 100644 index 0000000..84a239c --- /dev/null +++ b/docs/es-es/stage-2/assignments/modern-landing-page/index.md @@ -0,0 +1,211 @@ +# 现代 AI 生图 SaaS 开发实战 + +## Descripcion general + +Este proyecto practico te requiere trabajar con un PRD real(产品需求文档),completar desde cero un参考 Midjourney 体验的 AI 生图 SaaS 产品。你将完整经历Analisis de requisitos、项目拆解、Desarrollo iterativo、Integracion y despliegue的全过程。 + +Esta es la seccion de practica integral de la Etapa 2。在前面几章中,你已经分别学习了前端页面设计、后端接口开发、数据库操作、Integracion de pagos等单项技能——这个项目要求你把它们全部串起来,交付一个可运行的产品原型。 + +## Conocimientos previos + +Antes de comenzar este proyecto, ya deberias dominar lo siguiente: + +- Diseno de paginas frontend y uso de bibliotecas de componentes([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- Diseno y desarrollo de interfaces backend([接口代码编写](../../backend/ai-interface-code/)) +- Fundamentos de bases de datos y Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Integracion de pagos([Stripe 收费系统](../../backend/stripe-payment/)) +- Flujo de trabajo de Git y despliegue([Git 和 GitHub](../../backend/git-workflow/)、[Despliegue Web 应用](../../backend/zeabur-deployment/)) + +## Objetivos de aprendizaje + +Despues de completar esta practica, podras: + +1. Leer y comprender un PRD real, extrayendo una lista de tareas de desarrollo +2. Dividir modulos basandose en el PRD, formulando un plan de avance paso a paso +3. Usar IA para asistir en la construccion del esqueleto frontend y el desarrollo de interfaces backend +4. Verificar y optimizar iterativamente cada modulo +5. Completar la integracion de extremo a extremo, llevando el proyecto de "funcional" a "entregable" + +## Introduccion del proyecto + +El producto que vas a construir es一个现代 AI 生图 SaaS 平台,包含三个Subsistema: + +| Subsistema | Responsabilidad | +|--------|------| +| **Sitio web publico** | Introduccion del producto, precios, FAQ, conversion de registro | +| **Espacio de trabajo del usuario** | Prompt 输入、图片生成、图库、积分、套餐、社区互动 | +| **Panel de administracion** | Gestion de usuarios, gestion de tareas, gestion de pagos, moderacion de contenido, metricas SaaS, monitoreo del sistema | + +后端necesita soportar las siguientes capacidades centrales:用户鉴权、图片生成任务、OSS 对象存储、积分与套餐支付、图片社交互动、运营数据监控。 + +::: tip PRD 入口 +El documento de requisitos de este proyecto esta en GitHub: [Ver PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/es-es/stage-2/assignments/modern-landing-page/PRD.md) +::: + +
+ + + +
+ +## Primera parte:Analisis de requisitos + +### 1.1 Leer el PRD + +打开 PRD 文档,重点回答以下问题: + +- 系统有几个入口?各自覆盖哪些页面? +- 每个页面的核心功能是什么? +- 后端包含哪些模块和数据库表? +- MVP 范围是什么?第一版哪些做,哪些不做? + +::: warning +Si no tienes respuestas claras a las preguntas anteriores, no comiences a escribir codigo. La comprension inadecuada de los requisitos es la causa mas comun de retrabajo. +::: + +### 1.2 Confirmar la arquitectura del sistema + +根据 PRD 中的描述,梳理出系统的整体架构: + +```mermaid +flowchart TD + prd["PRD"] --> web["Sitio web publico"] + prd --> app["Espacio de trabajo del usuario"] + prd --> admin["Panel de administracion"] + app --> auth["鉴权"] + app --> gen["图片生成任务"] + gen --> oss["OSS 对象存储"] + gen --> db["数据库"] + billing["支付与套餐"] --> db + social["分享 / 点赞 / 评论 / 转发"] --> db + admin --> analytics["SaaS 指标看板"] + admin --> observability["API / DB / Provider 监控"] +``` + +建议你用自己的话把架构图画一遍,确认你对系统的理解是完整的。 + +## Segunda parte:搭建项目骨架 + +### 2.1 Generar paginas frontend + +使用 AI 先生成所有页面的基本结构和假数据。这一步的目标是搭出信息架构和路由,不需要接真实接口。 + +Referencia de prompts: + +```text +请基于当前 PRD,帮我生成一个现代 AI 生图 SaaS 的前端骨架。 + +要求: +1. 分成三个入口:www、app、admin +2. 官网包括:首页、定价、FAQ +3. app 包括:登录、注册、生成工作台、图库、套餐、积分、社区、作品详情、个人中心 +4. admin 包括:后台首页、用户管理、任务管理、内容管理、套餐管理、支付订单、运营配置、SaaS 指标、系统监控 +5. 先只生成页面结构和假数据,不接真实接口 +6. 风格参考 Midjourney,简洁、现代、带产品感 +``` + +### 2.2 Verificar la estructura de paginas + +骨架生成后,Verificar item por item: + +- [ ] 三个入口的路由是否独立(`/`、`/app`、`/admin`) +- [ ] 页面数量是否与 PRD 一致 +- [ ] 每个页面是否可以正常访问和导航 +- [ ] 假数据是否展示了基本的 UI 状态(列表、空状态、表单等) + +## Tercera parte:Desarrollo iterativo + +### 3.1 Avanzar por modulos + +在骨架的基础上,按以下顺序逐模块补充功能: + +1. **鉴权**:注册、登录、角色区分 +2. **数据库**:数据表创建、读写接口 +3. **核心业务**:图片生成任务、结果存储 +4. **OSS 存储**:图片上传与访问 +5. **支付**:套餐、积分、Stripe 集成 +6. **社交互动**:分享、点赞、评论 +7. **后台管理**:用户管理、任务管理、内容审核 +8. **数据监控**:SaaS 指标看板、系统监控 + +每完成一个模块,使用下表进行自检: + +| Item de verificacion | Metodo de verificacion | +|--------|----------| +| 页面一致性 | 页面数量、入口、功能是否符合 PRD | +| 接口正确性 | 请求参数、返回结构、状态处理是否合理 | +| Aislamiento de permisos | 普通用户和管理员是否互相隔离 | +| Consistencia de datos | 数据库、OSS、支付、积分是否对得上 | +| Demostrabilidad | 是否能给别人完整演示一条业务链路 | + +::: tip +Si encuentras que el contenido generado por IA se desvia del PRD, no vuelvas a hacer toda la pagina, simplemente pidele que modifique los modulos especificos. +::: + +### 3.2 角色与分工 + +在迭代过程中,你需要同时扮演三个角色: + +- **产品经理**:确认每个模块的功能是否符合 PRD +- **技术负责人**:确认实现方案是否合理 +- **测试工程师**:确认功能是否跑得通 + +## Cuarta parte:联调与上线 + +### 4.1 Pruebas de extremo a extremo + +最后阶段的重点不是补新页面,而是把完整业务链路跑通。Verificar al menos los siguientes escenarios: + +- 注册 → 购买积分 → 生成图片 → 查看历史 → 分享互动 +- 管理员登录 → 查看用户数据 → 查看任务统计 → 查看系统监控 + +### 4.2 Despliegue + +将项目Despliegue到公网环境,确保: + +- 环境变量配置完整 +- 登录回调地址正确 +- 支付回调地址正确 +- 页面无缺失的 loading、空状态、错误提示 + +Despliegue教程参考:[Git 和 GitHub 工作流](../../backend/git-workflow/)、[如何Despliegue Web 应用](../../backend/zeabur-deployment/)。 + +## Entregables + +Despues de completar este proyecto, necesitas enviar lo siguiente: + +- [ ] Enlace de demostracion en linea accesible +- [ ] Enlace al repositorio de codigo fuente (incluyendo README) +- [ ] PRD 文档 +- [ ] Capturas de pantalla de paginas clave(官网首页、生图工作台、图库、套餐页、后台首页) +- [ ] 60 segundos de video de demostracion(覆盖注册 → 生成 → 查看 → 后台管理) + +README 至少包含:Introduccion del proyecto、核心页面说明、技术栈、本地启动步骤、环境变量清单。 + +## Criterios de evaluacion + +| 维度 | Requisitos basicos | Requisitos avanzados | +|------|---------|---------| +| Alineacion con PRD | 页面、功能、数据结构基本符合 PRD | 能清晰说明每个设计决策与 PRD 的对应关系 | +| Ciclo completo del producto | 注册 → 购买积分 → 生成图片 → 查看历史 → 分享互动可跑通 | 支付状态、积分余额、生成次数数据一致 | +| Capacidades del backend | 用户、任务、支付、内容管理可查看 | SaaS 指标看板和系统监控页完整可用 | +| Completitud de ingenieria | 前端、后端、数据库、OSS、支付链路已接通 | 有错误处理、空状态、loading 状态 | +| Calidad de entrega | 可Despliegue、可运行 | README 清楚、演示视频结构完整 | + +## Referencias + +- [UI 设计](../../frontend/ui-design/) +- [参考 UI 设计规范设计页面和按钮](../../frontend/multi-product-ui/) +- [用 LLM 和 Skills 让界面变好看](../../frontend/llm-skills-beautiful/) +- [从设计原型到项目代码](../../frontend/design-to-code/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何Despliegue Web 应用](../../backend/zeabur-deployment/) +- [如何集成 Stripe 等收费系统](../../backend/stripe-payment/) diff --git a/docs/es-es/stage-2/assignments/movie-recommendation-springboot/index.md b/docs/es-es/stage-2/assignments/movie-recommendation-springboot/index.md new file mode 100644 index 0000000..a1fb00c --- /dev/null +++ b/docs/es-es/stage-2/assignments/movie-recommendation-springboot/index.md @@ -0,0 +1,162 @@ +# Spring Boot 电影推荐系统开发实战 + +## Descripcion general + +Este proyecto practico te requiere trabajar con un PRD real,使用 Spring Boot 完成一个带推荐能力的电影网站。这个项目的核心挑战在于:它不是简单的增删改查,而是需要你思考"用户行为如何影响推荐结果"以及"推荐如何可解释"。 + +Esta es la seccion de practica integral de la Etapa 2。你将第一次接触"内容 + 行为 + 推荐"型产品的开发模式,这种模式在电商、内容平台、个性化 Feed 等场景中非常常见。 + +## Conocimientos previos + +Antes de comenzar este proyecto, ya deberias dominar lo siguiente: + +- Diseno de paginas frontend y uso de bibliotecas de componentes([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- Diseno y desarrollo de interfaces backend([接口代码编写](../../backend/ai-interface-code/)) +- Fundamentos de bases de datos y Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Flujo de trabajo de Git y despliegue([Git 和 GitHub](../../backend/git-workflow/)、[Despliegue Web 应用](../../backend/zeabur-deployment/)) + +## Objetivos de aprendizaje + +Despues de completar esta practica, podras: + +1. Leer el PRD 并从中提取推荐系统的开发任务清单 +2. Usar Spring Boot para construir un proyecto backend e implementar API RESTful +3. Disenar el flujo de datos completo de "comportamiento del usuario -> recomendacion" +4. Implementar logica de recomendacion explicable +5. Completar la integracion de extremo a extremo, entregando un prototipo de producto demostrable + +## Introduccion del proyecto + +El producto que vas a construir es一个带推荐能力的电影网站: + +| 功能 | 描述 | +|------|------| +| **Navegacion y busqueda** | Los usuarios pueden navegar y buscar peliculas | +| **Calificacion y favoritos** | Los usuarios pueden calificar peliculas y agregar a favoritos | +| **Recomendacion personalizada** | El sistema proporciona resultados de recomendacion basados en el comportamiento del usuario | +| **Panel de administracion** | Los administradores mantienen datos de peliculas y ven la efectividad de las recomendaciones | + +::: tip PRD 入口 +El documento de requisitos de este proyecto esta en GitHub: [Ver PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/es-es/stage-2/assignments/movie-recommendation-springboot/PRD.md) +::: + +
+ + + +
+ +## Primera parte:Analisis de requisitos + +### 1.1 Leer el PRD + +打开 PRD 文档,重点回答以下问题: + +- 推荐策略是什么?第一版是否使用可解释版本(如基于评分相似度)? +- 用户行为数据要存哪些?(评分、收藏、浏览记录等) +- 管理员需要看哪些推荐效果指标? +- 页面清单是否完整? + +::: warning +Si no tienes respuestas claras a las preguntas anteriores, no comiences a escribir codigo. La comprension inadecuada de los requisitos es la causa mas comun de retrabajo. +::: + +### 1.2 Confirmar la arquitectura del sistema + +```mermaid +flowchart TD + prd["PRD"] --> web["前端页面"] + web --> auth["用户鉴权"] + web --> movie["电影列表 / 详情"] + web --> behavior["评分 / 收藏"] + behavior --> reco["推荐逻辑"] + reco --> db["数据库"] + admin["后台管理"] --> db +``` + +## Segunda parte:搭建项目骨架 + +### 2.1 Generar paginas frontend + +Referencia de prompts: + +```text +请基于当前 PRD,帮我生成一个 Spring Boot 电影推荐系统的前端骨架。 + +要求: +1. 页面包括:首页、电影列表、电影详情、推荐页、个人中心、后台管理 +2. 先只生成页面结构和假数据,不接真实接口 +3. 风格要像真实内容产品,而不是课堂 demo +``` + +### 2.2 Verificar la estructura de paginas + +Verificar item por item: + +- [ ] 电影列表页支持搜索和筛选 +- [ ] 电影详情页包含评分和收藏按钮 +- [ ] 推荐页能展示推荐结果和推荐理由 +- [ ] Panel de administracion能展示电影数据和推荐效果 + +## Tercera parte:Desarrollo iterativo + +### 3.1 Avanzar por modulos + +1. **Spring Boot 项目搭建**:项目结构、数据库配置、基础 CRUD +2. **电影数据管理**:电影列表、详情、搜索接口 +3. **用户行为**:评分、收藏接口,行为数据写入 +4. **推荐逻辑**:基于用户行为的推荐算法实现 +5. **推荐展示**:推荐结果展示,包含推荐理由 +6. **Panel de administracion**:电影数据维护、推荐效果查看 + +### 3.2 Autoverificacion de modulos + +| Item de verificacion | Metodo de verificacion | +|--------|----------| +| 基础功能 | 列表、详情、评分、收藏是否闭环 | +| 推荐联动 | 用户行为是否影响推荐结果 | +| 推荐可解释性 | 用户能理解为什么被推荐这些电影 | +| 后台数据 | 管理员能查看电影数据和推荐效果 | + +## Cuarta parte:联调与上线 + +### 4.1 Pruebas de extremo a extremo + +Verificar al menos los siguientes escenarios: + +- 浏览电影 → 评分 → 收藏 → 查看推荐页,确认推荐结果发生变化 +- 管理员登录 → 添加电影 → 查看推荐效果统计 + +## Entregables + +Despues de completar este proyecto, necesitas enviar lo siguiente: + +- [ ] Enlace de demostracion en linea accesible +- [ ] Enlace al repositorio de codigo fuente (incluyendo README) +- [ ] PRD 文档 +- [ ] Capturas de pantalla de paginas clave(电影列表、电影详情、推荐页、Panel de administracion) +- [ ] 60 segundos de video de demostracion + +## Criterios de evaluacion + +| 维度 | Requisitos basicos | Requisitos avanzados | +|------|---------|---------| +| Alineacion con PRD | 页面、功能、数据结构基本符合 PRD | 能清晰说明设计决策 | +| Ciclo completo del producto | 浏览 → 评分 → 收藏 → 推荐可跑通 | 评分行为明显影响推荐结果 | +| 推荐质量 | 推荐结果合理、推荐理由可解释 | 支持多种推荐策略 | +| Capacidades del backend | 电影数据和推荐效果可查看 | 有推荐准确率等统计指标 | +| Completitud de ingenieria | 前端、Spring Boot 后端、数据库链路已接通 | 推荐接口有缓存或性能优化 | + +## Referencias + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何Despliegue Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/es-es/stage-2/assignments/simple-grocery-microservices/index.md b/docs/es-es/stage-2/assignments/simple-grocery-microservices/index.md new file mode 100644 index 0000000..dd97867 --- /dev/null +++ b/docs/es-es/stage-2/assignments/simple-grocery-microservices/index.md @@ -0,0 +1,172 @@ +# 生鲜电商微服务系统开发实战 + +## Descripcion general + +Este proyecto practico te requiere trabajar con un PRD real,completar desde cero un生鲜电商微服务系统。与前面的单服务项目不同,这个项目的后端按业务拆分成多个独立服务,通过 API 网关统一对外。你将学习如何设计服务边界、如何处理跨服务的Consistencia de datos问题。 + +Esta es la seccion de practica integral de la Etapa 2。微服务架构在实际工作中非常常见,掌握服务拆分和网关路由的基本思路后,你能够应对更复杂的后端系统设计。 + +## Conocimientos previos + +Antes de comenzar este proyecto, ya deberias dominar lo siguiente: + +- Diseno de paginas frontend y uso de bibliotecas de componentes([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- Diseno y desarrollo de interfaces backend([接口代码编写](../../backend/ai-interface-code/)) +- Fundamentos de bases de datos y Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Flujo de trabajo de Git y despliegue([Git 和 GitHub](../../backend/git-workflow/)、[Despliegue Web 应用](../../backend/zeabur-deployment/)) + +## Objetivos de aprendizaje + +Despues de completar esta practica, podras: + +1. Leer el PRD 并提取微服务系统的开发任务清单 +2. Divir los limites de servicios por dominio de negocio (autenticacion, productos, inventario, ordenes) +3. Disenar e implementar el enrutamiento del API Gateway +4. Manejar problemas entre servicios como deduccion de inventario y consistencia de ordenes +5. Completar la integracion de extremo a extremo, entregando un prototipo de microservicios demostrable + +## Introduccion del proyecto + +El producto que vas a construir es一个生鲜电商微服务系统: + +| Subsistema | Responsabilidad | +|--------|------| +| **Portal de usuario** | Navegar productos, hacer pedidos, ver ordenes | +| **Portal de administracion** | Gestion de productos, gestion de inventario, gestion de ordenes | + +后端按业务拆分为以下服务: + +| 服务 | Responsabilidad | +|------|------| +| **API Gateway** | Entrada unificada, enrutamiento, verificacion de autenticacion | +| **Auth Service** | Registro de usuarios, login, emision de JWT | +| **Catalog Service** | Gestion de informacion de productos | +| **Inventory Service** | Gestion de cantidades de inventario | +| **Order Service** | Creacion de ordenes, gestion de estados | + +::: tip PRD 入口 +El documento de requisitos de este proyecto esta en GitHub: [Ver PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/es-es/stage-2/assignments/simple-grocery-microservices/PRD.md) +::: + +
+ + + +
+ +## Primera parte:Analisis de requisitos + +### 1.1 Leer el PRD + +打开 PRD 文档,重点回答以下问题: + +- 服务如何拆分?每个服务的Responsabilidad边界是什么? +- 前台和Portal de administracion分别有哪些页面? +- 下单后库存扣减的策略是什么?成功 / 失败 / 超时各怎么处理? +- 第一版哪些复杂能力(如分布式事务、消息队列)先不做? + +::: warning +Si no tienes respuestas claras a las preguntas anteriores, no comiences a escribir codigo. La comprension inadecuada de los requisitos es la causa mas comun de retrabajo. +::: + +### 1.2 Confirmar la arquitectura del sistema + +```mermaid +flowchart TD + prd["PRD"] --> fe["前端页面"] + fe --> gw["API Gateway"] + gw --> auth["Auth Service"] + gw --> catalog["Catalog Service"] + gw --> inventory["Inventory Service"] + gw --> order["Order Service"] + order --> inventory +``` + +## Segunda parte:搭建项目骨架 + +### 2.1 生成项目结构 + +Referencia de prompts: + +```text +请基于当前 PRD,帮我生成一个生鲜电商微服务系统的项目骨架。 + +要求: +1. 生成前端Portal de usuario和Portal de administracion骨架 +2. 生成 api-gateway、auth-service、catalog-service、inventory-service、order-service 五个目录 +3. 每个服务先只做最小可运行入口 +4. 先不接真实数据库和支付 +``` + +### 2.2 验证项目结构 + +Verificar item por item: + +- [ ] 五个服务目录结构清晰 +- [ ] API Gateway 可以启动并转发请求 +- [ ] 各服务健康检查接口可用 +- [ ] 前端Portal de usuario和Portal de administracion页面可访问 + +## Tercera parte:Desarrollo iterativo + +### 3.1 Avanzar por modulos + +1. **API Gateway**:路由配置、JWT 校验中间件 +2. **Auth Service**:注册、登录、JWT 颁发 +3. **Catalog Service**:商品 CRUD、列表查询 +4. **Inventory Service**:库存查询、库存扣减 +5. **Order Service**:订单创建、状态流转、库存联动 +6. **Portal de administracion**:Gestion de productos, gestion de inventario, gestion de ordenes + +### 3.2 Autoverificacion de modulos + +| Item de verificacion | Metodo de verificacion | +|--------|----------| +| 网关路由 | 各服务接口是否通过网关正确转发 | +| Aislamiento de permisos | Portal de usuario和Portal de administracion接口是否隔离 | +| 数据一致 | 商品和库存数据是否同步 | +| 交易闭环 | 下单后库存扣减、订单状态是否一致 | +| 失败处理 | 库存不足或超时时是否有补偿机制 | + +## Cuarta parte:联调与上线 + +### 4.1 Pruebas de extremo a extremo + +Verificar al menos los siguientes escenarios: + +- 浏览商品 → 加入购物车 → 下单 → 查看订单 +- 管理员 → 添加商品 → 更新库存 → 查看订单 + +## Entregables + +Despues de completar este proyecto, necesitas enviar lo siguiente: + +- [ ] Enlace de demostracion en linea accesible +- [ ] Enlace al repositorio de codigo fuente (incluyendo README) +- [ ] PRD 文档 +- [ ] Capturas de pantalla de paginas clave(商品列表、下单页、订单页、Panel de administracion) +- [ ] 60 segundos de video de demostracion + +## Criterios de evaluacion + +| 维度 | Requisitos basicos | Requisitos avanzados | +|------|---------|---------| +| Alineacion con PRD | 页面、功能、服务拆分基本符合 PRD | 能清晰说明服务拆分的理由 | +| Ciclo completo del producto | 浏览 → 下单 → 库存扣减 → 查看订单可跑通 | 订单超时或库存不足有补偿机制 | +| 服务架构 | 各服务可独立启动,通过网关统一访问 | 服务间通信有错误处理和重试 | +| Capacidades del backend | 商品、库存、订单管理可操作 | Portal de administracion有数据统计 | +| Completitud de ingenieria | 前端、网关、服务、数据库链路已接通 | 有 Docker Compose 或类似编排 | + +## Referencias + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何Despliegue Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/es-es/stage-2/assignments/traffic-data-visualization-go/index.md b/docs/es-es/stage-2/assignments/traffic-data-visualization-go/index.md new file mode 100644 index 0000000..cb02a27 --- /dev/null +++ b/docs/es-es/stage-2/assignments/traffic-data-visualization-go/index.md @@ -0,0 +1,163 @@ +# Go 交通数据分析平台开发实战 + +## Descripcion general + +Este proyecto practico te requiere trabajar con un PRD real,使用 Go 完成一个交通数据分析平台。这个项目的方向与前面的增删改查系统不同——你需要构建一条"Ingesta de datos → 聚合 → Alertas → 可视化"的完整数据链路。这种数据产品在 IoT、监控、运营分析等场景中非常常见。 + +Esta es la seccion de practica integral de la Etapa 2,也是你第一次接触 Go 语言。不用担心,有了前面 JavaScript / TypeScript 的基础,学习 Go 并不难——重点是理解数据链路的设计思路。 + +## Conocimientos previos + +Antes de comenzar este proyecto, ya deberias dominar lo siguiente: + +- Diseno de paginas frontend y uso de bibliotecas de componentes([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- Diseno y desarrollo de interfaces backend([接口代码编写](../../backend/ai-interface-code/)) +- Fundamentos de bases de datos y Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Flujo de trabajo de Git y despliegue([Git 和 GitHub](../../backend/git-workflow/)、[Despliegue Web 应用](../../backend/zeabur-deployment/)) + +## Objetivos de aprendizaje + +Despues de completar esta practica, podras: + +1. Leer el PRD 并提取数据产品的开发任务清单 +2. Usar Go (Gin o Fiber) para construir un servicio API backend +3. 设计Ingesta de datos、窗口聚合和Alertas的完整链路 +4. Mantener la consistencia entre los datos del backend y el dashboard frontend +5. Completar la integracion de extremo a extremo, entregando un prototipo de producto de datos demostrable + +## Introduccion del proyecto + +El producto que vas a construir es一个 Go 交通数据分析平台: + +| 模块 | Responsabilidad | +|------|------| +| **Ingesta de datos** | Recibir eventos de trafico sin procesar y almacenarlos | +| **Agregacion de datos** | Calcular tendencias e indicadores de congestion por ventana de tiempo | +| **Alertas** | 基于规则生成Alertas记录 | +| **Visualizacion de dashboard** | 在前端展示趋势图、排行榜和Alertas列表 | + +::: tip PRD 入口 +El documento de requisitos de este proyecto esta en GitHub: [Ver PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/es-es/stage-2/assignments/traffic-data-visualization-go/PRD.md) +::: + +
+ + + +
+ +## Primera parte:Analisis de requisitos + +### 1.1 Leer el PRD + +打开 PRD 文档,重点回答以下问题: + +- 数据来源是什么?字段有哪些? +- 核心指标的定义是什么?(比如"拥堵"的具体标准) +- Alertas规则是什么?第一版是否先收敛到简单规则? +- 看板包含哪些页面和图表? + +::: warning +Si no tienes respuestas claras a las preguntas anteriores, no comiences a escribir codigo. La comprension inadecuada de los requisitos es la causa mas comun de retrabajo. +::: + +### 1.2 确认数据链路 + +```mermaid +flowchart TD + prd["PRD"] --> ingest["Ingesta de datos API"] + ingest --> raw["原始数据表"] + raw --> agg["聚合任务"] + agg --> alert["Alertas规则"] + agg --> dashboard["看板接口"] + alert --> dashboard +``` + +## Segunda parte:搭建项目骨架 + +### 2.1 生成 Go API 服务 + +Referencia de prompts: + +```text +请基于当前 PRD,帮我生成一个 Go 交通数据分析平台骨架。 + +要求: +1. 使用 Gin 或 Fiber +2. 提供Ingesta de datos接口 +3. 提供聚合任务骨架 +4. 提供 dashboard 和 alerts 接口骨架 +5. 先不做真实复杂分析,只做可运行结构 +``` + +### 2.2 验证项目结构 + +Verificar item por item: + +- [ ] Go 服务可以正常启动 +- [ ] Ingesta de datos接口可接收并存储数据 +- [ ] 聚合任务框架已搭好 +- [ ] 前端看板页面可展示基本图表 + +## Tercera parte:Desarrollo iterativo + +### 3.1 Avanzar por modulos + +1. **Ingesta de datos API**:接收原始交通事件,写入数据库 +2. **Agregacion de datos**:按时间窗口聚合,计算趋势和拥堵指标 +3. **Alertas规则**:基于阈值生成Alertas记录 +4. **看板接口**:提供趋势数据、排行数据、Alertas列表 +5. **前端看板**:趋势图、排行榜、Alertas列表页面 + +### 3.2 Autoverificacion de modulos + +| Item de verificacion | Metodo de verificacion | +|--------|----------| +| Ingesta de datos | 原始数据是否正确入库 | +| 聚合口径 | 趋势、排名指标的计算逻辑是否一致 | +| Alertas规则 | Alertas触发条件是否符合预期 | +| Consistencia de datos | Visualizacion de dashboard和后端数据是否对得上 | +| API 规范 | 是否有统一返回结构和错误处理 | + +## Cuarta parte:联调与上线 + +### 4.1 Pruebas de extremo a extremo + +Verificar al menos los siguientes escenarios: + +- 接入一批测试数据 → 聚合任务执行 → Visualizacion de dashboard更新 +- 触发Alertas条件 → Alertas记录生成 → Alertas页面显示 + +## Entregables + +Despues de completar este proyecto, necesitas enviar lo siguiente: + +- [ ] Enlace de demostracion en linea accesible +- [ ] Enlace al repositorio de codigo fuente (incluyendo README) +- [ ] PRD 文档 +- [ ] Capturas de pantalla de paginas clave(Ingesta de datos演示、趋势看板、Alertas列表) +- [ ] 60 segundos de video de demostracion + +## Criterios de evaluacion + +| 维度 | Requisitos basicos | Requisitos avanzados | +|------|---------|---------| +| Alineacion con PRD | 功能和数据结构基本符合 PRD | 能清晰说明指标口径和聚合逻辑 | +| 数据链路 | 接入 → 聚合 → Alertas → 看板可跑通 | 聚合任务支持增量更新 | +| 分析能力 | 趋势、排行、Alertas三个模块可用 | 指标可配置、Alertas规则可自定义 | +| 前端展示 | 看板能展示基本图表 | 图表支持时间范围筛选 | +| Completitud de ingenieria | Go API、数据库、前端链路已接通 | API 有统一错误处理和日志 | + +## Referencias + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何Despliegue Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/es-es/stage-2/assignments/travel-planning-agent-platform/index.md b/docs/es-es/stage-2/assignments/travel-planning-agent-platform/index.md new file mode 100644 index 0000000..56217bd --- /dev/null +++ b/docs/es-es/stage-2/assignments/travel-planning-agent-platform/index.md @@ -0,0 +1,164 @@ +# 智能旅游规划 Agent 平台开发实战 + +## Descripcion general + +Este proyecto practico te requiere trabajar con un PRD real,completar desde cero un智能旅游规划 Agent 平台。你将构建一个能接收结构化输入、生成每日行程、支持保存和重用的完整 AI 产品——不只是聊天机器人,而是一个有任务管理能力的产品。 + +Esta es la seccion de practica integral de la Etapa 2。这个项目的核心挑战在于:如何让 AI 生成结构化、可用的Planificacion de itinerario,而不是一大段不可操作的文字。 + +## Conocimientos previos + +Antes de comenzar este proyecto, ya deberias dominar lo siguiente: + +- Diseno de paginas frontend y uso de bibliotecas de componentes([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- Diseno y desarrollo de interfaces backend([接口代码编写](../../backend/ai-interface-code/)) +- Fundamentos de bases de datos y Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Flujo de trabajo de Git y despliegue([Git 和 GitHub](../../backend/git-workflow/)、[Despliegue Web 应用](../../backend/zeabur-deployment/)) + +## Objetivos de aprendizaje + +Despues de completar esta practica, podras: + +1. Leer el PRD 并从中提取 Agent 平台的开发任务清单 +2. Disenar formularios de entrada estructurados y formatos de salida estructurados +3. Implementar la capa de orquestacion de Agent, procesando entrada de usuarios, llamadas a modelos y almacenamiento de resultados +4. 构建"生成 → 保存 → 重用"的Ciclo completo del negocio +5. Completar la integracion de extremo a extremo, entregando un prototipo de producto IA demostrable + +## Introduccion del proyecto + +El producto que vas a construir es一个智能旅游规划 Agent 平台: + +| 功能 | 描述 | +|------|------| +| **Planificacion de itinerario** | El usuario ingresa origen, destino, fechas, presupuesto y preferencias, el sistema genera el itinerario diario | +| **Desglose de presupuesto** | Los resultados del itinerario incluyen asignacion de presupuesto y sugerencias | +| **Gestion de historial** | Los usuarios pueden guardar planes historicos, regenerar y exportar | +| **Panel de administracion** | Los administradores ven destinos populares, tareas fallidas y retroalimentacion de usuarios | + +::: tip PRD 入口 +El documento de requisitos de este proyecto esta en GitHub: [Ver PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/es-es/stage-2/assignments/travel-planning-agent-platform/PRD.md) +::: + +
+ + + +
+ +## Primera parte:Analisis de requisitos + +### 1.1 Leer el PRD + +打开 PRD 文档,重点回答以下问题: + +- 第一版是否只做单目的地? +- 行程输出是否必须结构化?结构是什么? +- 导出能力做多深?(分享链接 / PDF / 图片) +- 后台统计和任务日志的范围是什么? + +::: warning +Si no tienes respuestas claras a las preguntas anteriores, no comiences a escribir codigo. La comprension inadecuada de los requisitos es la causa mas comun de retrabajo. +::: + +### 1.2 Confirmar la arquitectura del sistema + +```mermaid +flowchart TD + prd["PRD"] --> planner["规划页"] + planner --> agent["Agent 编排层"] + agent --> model["模型调用"] + agent --> db["数据库"] + db --> history["历史计划"] + db --> admin["后台统计与日志"] +``` + +## Segunda parte:搭建项目骨架 + +### 2.1 Generar paginas frontend + +Referencia de prompts: + +```text +请基于当前 PRD,帮我生成一个智能旅游规划 Agent 平台的前端骨架。 + +要求: +1. 页面包括:首页、规划页、行程详情页、历史记录页、管理页 +2. 规划页左侧是表单,右侧是结果预览 +3. 先只生成页面结构和假数据,不接真实接口 +4. 风格要像现代 AI 产品 +``` + +### 2.2 Verificar la estructura de paginas + +Verificar item por item: + +- [ ] 规划页的表单字段是否与 PRD 一致 +- [ ] 结果预览区域能展示结构化的行程数据 +- [ ] 历史记录页可以展示多条计划 +- [ ] Panel de administracion页可以展示统计数据 + +## Tercera parte:Desarrollo iterativo + +### 3.1 Avanzar por modulos + +1. **鉴权**:注册、登录 +2. **规划表单**:结构化输入(出发地、目的地、日期、预算、偏好) +3. **Agent 编排**:接收输入 → 调用模型 → 解析结构化输出 +4. **结果展示**:行程按天展示、Desglose de presupuesto、建议 +5. **Gestion de historial**:保存计划、再次生成、导出 +6. **Panel de administracion**:热门目的地、失败任务、用户反馈 +7. **任务状态**:生成中 / 成功 / 失败的状态管理和错误记录 + +### 3.2 Autoverificacion de modulos + +| Item de verificacion | Metodo de verificacion | +|--------|----------| +| 输入完整性 | 表单字段是否与 PRD 一致 | +| 输出结构化 | 行程结果是不是结构化数据(而非一大段文字) | +| Consistencia de datos | trip、itinerary、logs 数据是否对得上 | +| 闭环验证 | 是否能演示"输入 → 生成 → 保存 → 再次生成" | + +## Cuarta parte:联调与上线 + +### 4.1 Pruebas de extremo a extremo + +Verificar al menos los siguientes escenarios: + +- 输入行程参数 → 生成每日行程 → 查看Desglose de presupuesto → 保存到历史 +- 从历史记录中再次生成行程 +- 管理员查看任务统计和失败日志 + +## Entregables + +Despues de completar este proyecto, necesitas enviar lo siguiente: + +- [ ] Enlace de demostracion en linea accesible +- [ ] Enlace al repositorio de codigo fuente (incluyendo README) +- [ ] PRD 文档 +- [ ] Capturas de pantalla de paginas clave(规划页、行程详情页、历史记录页、Panel de administracion) +- [ ] 60 segundos de video de demostracion + +## Criterios de evaluacion + +| 维度 | Requisitos basicos | Requisitos avanzados | +|------|---------|---------| +| Alineacion con PRD | 页面、功能、数据结构基本符合 PRD | 能清晰说明设计决策 | +| Ciclo completo del producto | 规划 → 保存 → 历史 → 重生成可跑通 | 支持导出和分享 | +| 输出质量 | 行程结果结构化且可读 | Desglose de presupuesto合理、建议有针对性 | +| Capacidades del backend | 任务统计和失败日志可查看 | 有热门目的地分析 | +| Completitud de ingenieria | 前端、后端、数据库、模型调用链路已接通 | 任务状态管理完善,错误可追溯 | + +## Referencias + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何Despliegue Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/es-es/stage-2/backend/ai-interface-code/index.md b/docs/es-es/stage-2/backend/ai-interface-code/index.md new file mode 100644 index 0000000..4406f1e --- /dev/null +++ b/docs/es-es/stage-2/backend/ai-interface-code/index.md @@ -0,0 +1,161 @@ +# 大模型辅助编写接口代码与接口文档 + +在之前的课程中,我们学习了如何使用 Figma 等工具完成 UI 设计稿、如何借助 AI 快速生成前端静态页面,以及如何利用 Supabase 构建数据库并实现初步的用户身份验证。现在,一个自然而然的问题摆在了面前:前端页面中那些动感十足的按钮点击后,究竟是如何把数据悄无声息地存进 Supabase 的?当我们需要执行更复杂的业务逻辑(如并发支付、定时推送、数据敏感处理)时,直接让前端连接数据库是安全的吗? + +这就引出了现代 Web 开发架构中至关重要的一环——**后端 API 接口**。 + +相比于过去纯手工敲出成百上千行的后端路由、控制器与参数校验逻辑,如今我们完全可以借助大模型的强大代码生成能力,将繁杂的基础代码交由 AI 编写。在本节课中,我们将跳出“AI 写的又虚又泛”的怪圈,以真实的业务场景为依托,向你展示如何通过高质量的提示词(Prompt)引导大模型写出健壮、符合行业规范的 Node.js 后端接口,并自动完成接口文档与测试用例的生成。 + +> 💡 **Conocimientos previos** +> +> 在学习本节之前,建议你先了解以下内容: +> - [从数据库到 Supabase](../database-supabase/) - 了解数据库和数据模型的概念。 +> - [Git 和 GitHub 工作流](../git-workflow/) - 熟悉如何在项目开发中进行版本控制。 +> - [什么是终端/命令行](/es-es/appendix/2-development-tools/command-line-shell) - 项目初始化与启动离不开基础的命令操作。 + +# Lo que aprenderas + +1. **什么是 API 接口**:理解前后端通信的桥梁与 RESTful 设计规范。 +2. **大模型赋能服务构建**:如何通过结构化的 Prompt 让 AI 帮你搭建 Node.js + Express 基础工程。 +3. **接口逻辑开发**:引导大模型生成包含严谨业务校验、对接 Supabase 数据库的 CRUD(增删改查)接口。 +4. **自动化接口文档**:让大模型根据代码逆向生成跨团队协作标配的 OpenAPI/Swagger 文档。 +5. **测试与联调闭环**:利用大模型生成 Postman 测试合集与 Jest 单元测试用例,为代码质量兜底。 + +--- + +# 1. 为什么我们需要 API 接口? + +在传统的理解中,前端是“看得到的部分”,数据库是“存东西的仓库”。但这中间缺少了一个调度员。如果你把整个应用想象成一家餐厅: +- **前端(客户端)** 是餐厅的菜单和点餐桌,客人在这里浏览菜品并提出需求。 +- **数据库(Supabase 等)** 是餐厅的后厨仓库,里面存放着所有的食材和账本。 +- **后端 API 接口** 就是餐厅的服务员。客人不能直接冲进后厨拿食材(不仅混乱,而且容易引发安全问题),而是需要把“点单诉求”(HTTP Request)告诉服务员。服务员进行核对(参数校验、权限鉴权)后,去后厨调取对应的内容,再将“做好的菜”(HTTP Response,通常是 JSON 格式的数据)端回给客人。 + +通过 API 接口,我们实现了明确的**前后端分离**:前端只关心页面如何渲染,后端只专注于业务逻辑、数据处理与安全防护。 + +--- + +# 2. 项目架构设计与初始化 + +一个结构清晰的项目骨架,是大模型能写出好代码的先决条件。我们在让 AI 写代码前,自己心里必须对工程结构有个底。 + +## 2.1 常见的 API 工程结构 +即使是使用大模型生成代码,我们也绝不能把所有代码都塞进一个 `server.js` 文件中。一个易于维护的 Node.js 后端架构通常如下所示: + +```text +my-api-project/ +├── .env # 敏感环境变量(如 API Keys、数据库连接串) +├── server.js # 项目入口(服务器启动、全局中间件注册) +├── package.json # 依赖管理文件 +├── src/ +│ ├── routes/ # 路由层:定义 URL 路径与请求方法 +│ ├── controllers/ # 控制器层:处理业务请求参数,调用服务并返回响应 +│ ├── services/ # 服务层:封装数据库交互和核心业务逻辑 +│ └── middlewares/ # 中间件:登录鉴权、错误全局捕获 +└── docs/ # API 文档存放目录 +``` + +## 2.2 借助 AI 完成工程初始化 +与其手动 `npm init` 并一个个安装依赖,不如直接将上述规范以 Prompt 的形式喂给大模型: + +> 🗣️ **给大模型的提示词(Prompt 示例):** +> "帮我搭建一个 Node.js 后端项目,要能连接 Supabase 数据库,结构清晰一点,方便以后维护。" + +运行 AI 返回的代码后,你就能在 `localhost:3000` 获得一个具备企业级雏形的后端应用了。 + +--- + +# 3. 核心实战:大模型辅助接口开发 + +这是本章节最核心的部分。大模型写出的代码往往容易存在“逻辑漏洞”或“表面敷衍”,原因在于开发者给的上下文不足。**大模型不怕需求复杂,最怕需求模糊。** + +以我们在 [数据库章节](../database-supabase/) 中提到的 `menu_items` (菜单表) 的新增接口为例,看如何写出一份高质量的 Prompt。 + +## 3.1 赋予大模型完整上下文 +在请求 AI 写接口之前,一定要提供**数据库字段定义(Schema)**和**具体的约束条件**。 + +> 🗣️ **高质量提示词(Prompt)模板:** +> "帮我写一个新增菜单的接口,菜单有商品名、价格、分类(汉堡、小食、饮料)、是否上架这几个信息。商品名和价格必须填,价格不能是负数。用户输入不对的时候要提示错误。" + +## 3.2 审查大模型生成的代码 +大模型生成的代码通常会像下面这样清晰地拆分了Responsabilidad: + +```javascript +// services/menuService.js +const { createClient } = require('@supabase/supabase-js'); +const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY); + +exports.createMenuItem = async (menuData) => { + // 调用 Supabase SDK 将数据推入表内 + const { data, error } = await supabase + .from('menu_items') + .insert([menuData]) + .select(); + + if (error) throw new Error(`数据库插入失败: ${error.message}`); + return data[0]; +}; +``` + +你可以发现,通过这种方式生成的代码,不仅结构合理,而且将 Supabase 的初始化、错误捕获以及异常处理都考虑在内,这与简单要求“写个新增接口”得到的面条式代码(Spaghetti Code)有着天壤之别。 + +--- + +# 4. 解放双手:自动生成接口文档 + +对于开发团队而言,没有文档的 API 就是一个盲盒。前端工程师无法猜测你需要传入什么参数,也不能预测会返回什么结构。业界最通用的 API 描述规范是 **OpenAPI (此前也称 Swagger)**。 + +过去,手写 YAML 或者 JSON 格式的 Swagger 文档极其痛苦且容易出错。现在,这也成了大模型最擅长的领域。 + +你可以直接选中你刚才写的 `routes` 和 `controllers` 代码,然后丢给大模型: + +> 🗣️ **生成文档的提示词:** +> "帮我根据上面的代码生成一份接口文档,要写清楚每个参数是什么意思、返回什么数据,方便前端同事对接。" + +在这个过程中,你甚至可以要求 AI 补全字段的说明(Description)和 Mock 数据(如 `price_cents: 1200` 代表 12 美元),极大地降低了沟通成本。 + +--- + +# 5. 保驾护航:生成测试代码与 Postman 集合 + +代码写好、文档出炉,还差最后一步:验证代码到底能不能跑通。 + +## 5.1 生成 Postman / Apifox 测试配置 +在接口开发中,我们通常使用 Postman 这样的可视化工具来模拟前端发送 HTTP 请求。如果不使用大模型,你需要手动填入 URL、逐个添加 Header(请求头)以及拼接 JSON 请求体。 + +你只需向 AI 发送指令: +> "帮我把这份接口文档转成 Postman 可以导入的格式,要包含正常请求和错误请求的例子。" + +拿到 JSON 文本后,保存为 `menu_api.json` 并拖入 Postman,你瞬间就获得了一套开箱即用的测试点击面板。 + +## 5.2 编写自动化单元测试 +如果你追求更严谨的工程质量,可以让大模型帮你使用 `Jest` 等测试框架编写单元测试(Unit Tests),对核心业务逻辑进行边界测试(比如传入负数价格时,数据库层的校验是否生效)。 + +--- + +# 6. 后端接口必知的最佳实践 + +即使有 AI 的协助,作为整个系统的“把关人”,你依然需要了解并审核以下这些核心准则: + +1. **RESTful 规范的路径命名**: + - 好的设计:`GET /api/users`(获取用户列表)、`POST /api/users`(创建用户)。URL 应该代表“资源”的名词。 + - 错误的设计:`POST /api/getUser` 或 `POST /api/createUser`。动词应该交由 HTTP Method (GET/POST/PUT/DELETE) 来体现。 +2. **规范的 HTTP 状态码**: + - 200/201:请求成功 / 资源创建成功。 + - 400:Bad Request,前端传参格式错误、少传了必填项。 + - 401/403:Unauthorized / Forbidden,用户未登录或无权操作。 + - 404:NotFound,资源不存在。 + - 500:Server Error,后端代码报错或数据库挂了,绝对尽量避免将报错调用栈直接暴露给前端(会有安全隐患)。 +3. **永远不信任用户的输入**:前端的输入可能是伪造的,所有核心参数校验必须在后端接口中再做一次。 + +# 7. 总结 + +通过本章节的学习,你实现了开发视角的真正转变:你不再是被困在语法和标点符号中的“打字员”,而是上升成为了**系统设计师和架构指挥官**。 +你已经掌握了: +1. **API 接口与前后端分离**的核心系统思维。 +2. **如何通过提供上下文与分层结构理念**,大幅提高大模型生成服务端代码的质量。 +3. 把繁琐的**文档编写**和**测试用例构建**,巧妙地转化为 AI 擅长的自动化任务。 +4. 结合此前学过的 **Supabase** 知识,打通了从客户端请求到底层数据库更新的完整数据流。 + +::: tip 💡 下一步 +当你的数据流和后端服务都准备就绪后,它目前还只能在你的本地电脑上“自娱自乐”。在接下来的章节中,我们将学习如何把这套辛辛苦苦建立的服务**Despliegue(Deploy)到公网服务器上**,让你的产品能被全世界的用户访问。 +::: \ No newline at end of file diff --git a/docs/es-es/stage-2/backend/database-supabase/index.md b/docs/es-es/stage-2/backend/database-supabase/index.md new file mode 100644 index 0000000..496fede --- /dev/null +++ b/docs/es-es/stage-2/backend/database-supabase/index.md @@ -0,0 +1,1742 @@ +# 从数据库到 Supabase + +在上节课中,我们学会了 UI 设计程序 Mastergo 和 Figma 的基本用法,能够使用 github 进行代码的获取与版本管理,并通过 Zeabur Despliegue网站将自己的应用 / 网站传达给更多人使用。 + +为了帮助大家更好地衔接知识,在开始本节课关于设计工具与Despliegue的新内容前,让我们一起通过几道简单的题目快速回顾一下上节课的核心知识点: + +1. 什么是前端设计工具、Figma、MasterGo 的定义和使用方式。 +2. 将设计稿转换为代码的基础方法。 +3. 什么是 Github,如何配置 SSH,如何构建自己的第一个仓库。 +4. Despliegue是什么意思,如何使用 Zeabur,如何将 Github 或本地代码Despliegue至公共网络给大家访问。 + +如果对以上任何一个问题还有印象模糊的地方,建议先回顾一下上节课的文档和讲义。欢迎随时在微信学习群中提出疑问。 + +在本节课中,我们将学习如何让一个 APP / 网站从能跑起来变为更接近真实线上产品:除了用数据库管理程序运行中的各种数据变化外,还要具备完善的用户体系(注册、登录、权限等)以及其他关键后端能力。我们会以 Supabase 这一后端服务平台为主线,先用它实现“数据库 + 用户系统”这两项基础功能,再以 Supabase 提供的组件为参照,进一步理解现代云服务后端服务通常包含的核心模块,以及各模块的具体职能与作用逻辑。 + +# Lo que aprenderas + +1. 什么是数据、什么是数据库,常见数据库与使用方法 +2. 什么是 supabase,如何使用 supabase 进行基础的数据库操作 +3. 如何使用 supabase 为应用添加基础用户管理功能 +4. 学会 Supabse 进阶功能:realtime、storage、edge function +5. 学会为Supabase增加 google 与 github 登录支持 + +- 一款支持用户注册 / 登录,并能将数据存入在线数据库的基础应用 +- 一套可复用的 Supabase 后端代码模板(数据库 + 用户管理等),供后续项目直接套用 + +# 1. 什么是数据库 + +## 1.1 什么是数据 + +在数字世界里,数据(Data)无处不在。简单来说,数据是信息的载体。你朋友的联系方式、一篇微信文章、一条短视频、游戏里的角色等级,这些都是数据。在我们的应用中,数据就是需要被记录和管理的一切信息,比如用户的个人资料、订单历史、程序设置等。 + +一般而言,数据在程序中有不同的表现形式,最简单的就是变量,我们可以用不同变量记录简单的数字: + +```python +# Python variable definition examples + +# Integer variable: stores age information +age = 30 + +# Boolean variable: stores status (whether active) +is_active = True # True means active, False means inactive + +# List variable: stores a set of score data +scores = [85, 92, 78, 90] # Contains 4 integer elements representing different scores + +# Dictionary variable: stores multiple related information of a user +user_info = { + "age": 30, # Key "age" corresponds to the value of age + "height": 1.80, # Key "height" corresponds to the value of height (unit: meter) + "login_count": 156 # Key "login_count" corresponds to the value of login times +} +``` + +而对于上述所说的个人资料、订单历史这类复杂的数据而言,我们可以用更复杂的表格进行数据的表示: + +| user_id | name | email | +| ------- | ----- | ----------------- | +| 1001 | Alice | alice@example.com | +| 1002 | Bob | bob@example.com | + +| order_id | user_id | amount | status | +| -------- | ------- | ------ | --------- | +| 901 | 1001 | 29.99 | completed | +| 902 | 1002 | 15.50 | pending | + +但对于结构复杂、具有层级关系或字段不固定的数据,我们可以用 JSON 格式进行描述 —— 它是互联网通用的数据中间格式,几乎所有程序都能读取解析,跨系统传数据很方便。例如,一个订单可能包含多个商品,每个商品又有自己的名称、数量和价格。用传统的表格来表示会很笨拙:要么得拆成 “订单表”“商品表” 多张表,靠关联字段才能体现 “订单包含商品” 的关系;要么在一张表用 “商品 1 名称、商品 1 价格、商品 2 名称……” 这类冗余字段,遇到商品数量不固定时根本没法适配;而 JSON 能直接用嵌套结构把 “订单 - 商品 - 商品属性” 的层级说清,既直观又灵活。 + +```json +{ + "order_id": 901, + "user_id": 1001, + "amount": 29.99, + "status": "completed", + "items": [ + { "sku": "BG-001", "name": "牛肉汉堡", "quantity": 1, "price": 18.00 }, + { "sku": "SD-003", "name": "炸薯条", "quantity": 1, "price": 6.99 }, + { "sku": "DK-002", "name": "可乐", "quantity": 1, "price": 5.00 } + ], + "shipping_address": { + "street": "科技园路123号", + "city": "深圳", + "zip_code": "518057" + } +} +``` + +更进一步的,如果我们考虑一个被编码成向量(Vector)的数据,向量数据通常是文本、图片或音频等非结构化数据经过 AI 模型(如 Embedding 模型)处理后得到的数值表示。它的表示形式可能是: + +`[0.123, -0.456, 0.789, ..., -0.234]` (一个由几百甚至上千个浮点数组成的数组) + +总的来说,在现实世界中有太多不同形态、用途的数据值得我们详细分析,每种数据可能都需要专门的数据库用于存储,具体可参考下图——是不是感觉非常多? + +![](/zh-cn/stage-2/backend/database-supabase/images/image1.png) + +## 1.2 为什么我们需要数据库 + +我们已经了解到真实世界中的数据往往结构复杂,**为了高效存储与使用这些数据,我们需要一个专门的程序或容器来管理它们** —— 这便是数据库(Database)的诞生初衷。数据库本质上是一款特殊程序,核心作用就是对数据进行规范化组织、安全存储、系统化管理,并支持高效查询调用。 + +想象一下,若没有数据库,应用数据会陷入怎样的困境?当用户关闭浏览器或退出应用时,所有临时加载的信息都会直接丢失;我们既无法永久保存用户的使用状态(比如登录信息、个性化设置),也没法在不同用户之间共享关键数据(比如商品库存、订单记录)。我们需要有一个装置帮我们存储所有的数据! + +更灵活的是,数据库的Despliegue方式可按需选择:既可以Despliegue在本地服务器,满足数据本地化管理的需求;也能Despliegue到云端,云端数据库支持弹性扩容(Scale),可随数据量与访问量增长扩展能力、承载海量数据与高并发,即便用户量大幅提升,也能保障用户的正常使用体验。 + +归纳而言,数据库凭借高效的持久化存储、精细化管理与快速查询能力,主要解决了以下核心问题: + +- **数据的持久化存储** : 如果没有数据库,数据将仅存在于应用的内存中,一旦应用关闭,数据就会丢失。数据库解决了这个问题,它将数据持久地存储在硬盘等存储介质上,确保了数据的长期保存,降低了丢失风险。 +- **便捷的数据查询与分析** : 数据库提供了强大的查询语言(如 SQL),让用户可以轻松、高效地对海量数据进行复杂的查询、筛选和分析,从而帮助企业做出更明智的决策。 如果没有数据库,从大量无序文件中查找特定信息将是一项极其耗时且困难的任务。 +- **支持高性能与高并发访问** : 数据库通过索引优化、查询缓存、连接池以及分布式架构等技术,能够在毫秒级时间内响应查询请求,并支撑成千上万用户的并发访问。这对于现代互联网应用(如电商平台秒杀活动、社交网络实时动态)至关重要,确保了系统的响应速度和用户体验。如果没有数据库的高性能支撑,面对海量用户请求时系统将会出现严重延迟甚至崩溃。 +- **保证数据的完整性和一致性** : 数据库通过一系列机制(如约束、触发器)来确保数据的准确性和一致性。 这意味着数据库中的数据必须符合预设的规则,例如,用户的年龄必须是数字,订单号必须是唯一的,从而有效防止了非法或无效数据的产生。 +- **确保数据的安全性** : 数据库提供了强大的安全机制,包括用户身份验证、访问控制和数据加密等,以保护数据免受未经授权的访问、修改或破坏。为了应对硬件故障、人为失误或恶意攻击等意外情况,数据库还提供了数据备份和恢复功能。 通过定期备份,可以在数据丢失或损坏时及时恢复,保障了业务的连续性。 + +## 1.3 关系型数据库与非关系型数据库 + +前面我们已经了解了数据库的核心价值、Despliegue方式与弹性优势,而在实际选择时,首先要面对的就是数据库的两大核心类别:关系型数据库与非关系型数据库(NOSQL),我们可以用简单的两段话简单理解他们的区别: + +关系型数据库就像结构严谨的Excel表格,所有数据必须预先定义好格式(定义好 Schema 的内容, 比如要有姓名和年龄,且姓名必须是文字,年龄必须是数字),并通过关联字段(用来连接不同表格的标识,如身份证号)将不同表格连接起来。它的好处是数据精确可靠,特别适合银行转账、库存管理等不能出错的场景,但缺点是调整结构比较麻烦,海量数据下性能会受限。 + +非关系型数据库则像灵活的文件夹,可以存放格式各异的文档、图片或键值对(类似字典的"词-解释"结构),不需要提前规定好每份数据的结构。它更容易应对快速变化的需求和超大规模数据(比如社交媒体的海量帖子),扩展(增加服务器提升性能)起来也更方便,但牺牲了部分关联查询能力(跨不同数据表整理信息的能力)和一致性保障(确保数据时刻准确不矛盾),适合对容错性要求较高的互联网应用。 + +那么,实际应用中该如何选择数据库?从场景划分总结来看,关系型数据库常见于金融交易、库存管理、订单处理、账务系统等需要强一致性、复杂事务处理以及频繁读写均衡访问的场景;而非关系型数据库更适配社交媒体内容存储、实时日志分析、物联网海量数据写入、推荐系统特征读多写多等高并发、读写模式不均衡且结构灵活的需求。 + +但对于企业而言,在初级阶段并不需要花大量时间思考什么需要使用什么数据库。当前的数据库已是非常成熟的产品服务,最直接的方式是咨询不同云服务厂商(指提供服务器、存储、数据库、软件、算力等 IT 资源与技术服务的服务商)。我们可直接对接云服务官方销售,根据自身产品业务需求匹配适配的数据库方案;而构建企业级应用的便捷路径,便是优先与专业厂商合作。(需注意:企业级服务价格通常较高,建议先多方调研对比,也可选择购买服务器自行Despliegue开源数据库程序作为替代方案。) + +我们也可参考某家云厂商的[数据库选型推荐](https://help.aliyun.com/zh/govcloud/getting-started/select-database-services),根据场景可进行不同数据库类型的选择,你可以对比不同云厂商的数据库规格选出最合适的进行使用。 + +| 数据库类型 | 数据库名称 | 价格 | 适用场景 | +| ------------ | ---------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 关系型数据库 | RDS MySQL版 | 低 | 基础版:学习以及小型网站高可用版:一定业务压力的中型数据库场景集群版:业务不允许中断,访问压力较大 | +| | RDS SQL server版 | 高 | 基础版:测试以及小型商业化网站高可用版:企业级商业化网站集群版:企业业务不允许中断,访问压力较大 | +| | RDS PostgreSQL版 | 最低 | 基础版:学习以及小型网站高可用版:一定业务压力的中型数据库场景集群版:业务不允许中断,访问压力较大的场景,其性能较一般MySQL高 | +| | RDS PPAS版 | 高 | 通用型:兼容Oracle业务,但业务压力Udacity,虚拟化可以满足其需求独享型:面对需要独享物理机的业务,一般为高并发Oracle类业务 | +| | DRDS | 中 | 入门版本:4 Core 8 G,价格亲民,适合中小型在线业务企业版:16 Core 32 G,复杂 SQL 响应好,适合超高并发在线业务至尊版:32 Core 64 G,复杂 SQL 执行响应最好,提供超大规格选择 | +| NoSQL数据库 | Redis | 中 | 双机热备Redis:一般作为持久化数据库提高业务可用性集群版本的Redis:一般作为缓存层,加速应用访问,解决一般数据库无法负载的读取压力 | +| | MongoDB版 | 中 | 单节点实例单节点:适用于开发、测试及其他非企业核心数据存储的场景副本集实例:适用于某些业务场景下对数据库有更高读取性能需求,如阅读类网站、订单查询系统等读多写少场景或有临时活动等突发业务需求分片集群实例:基于多个副本集(每个副本集沿用三副本模式)组成的分片集群实例,提供更高的读取性能需求,为实时在线业务提供高速读取性能 | + +光说不易理解,我们通过一个具体的“博客文章”场景,来看看同样的数据在关系数据库 (SQL) 和不同类型的非关系数据库 (NoSQL) 中是如何存储的。 + +假设我们有一个博客平台,需要存储以下信息: + +- 用户(Users):用户 ID、用户名、邮箱 +- 文章(Posts):文章 ID、标题、内容、作者 ID +- 评论(Comments):评论 ID、评论内容、评论者 ID、所属文章 ID +- 标签(Tags):标签 ID、标签名 +- 文章与标签的关系:单篇文章关联的多个标签、单个标签对应的多篇文章 + +### 关系数据库 (SQL) 示例 + +在SQL数据库中,我们会将不同类型的数据分别存储在不同的表中,并通过“外键”将它们关联起来。这种结构清晰、规范,减少了数据冗余。 + +以 “内容平台的文章管理” 为例,我们不会把 “用户、文章、评论、标签” 混存,而是拆成 5 张功能单一的表,每张表都有明确的 “Responsabilidad边界” 和严格的结构定义(Schema): + +- `users` 表 (存储用户信息) + +| user_id (主键) | username | email | +| -------------- | -------- | ----------------- | +| 101 | Alice | alice@example.com | +| 102 | Bob | bob@example.com | + +- `posts` 表 (存储文章信息) + +| post_id (主键) | title | content | author_id (外键) | +| -------------- | --------- | ------------------------------ | ---------------- | +| 1 | 初识SQL | 这是关于SQL数据库的一篇文章... | 101 | +| 2 | NoSQL入门 | NoSQL提供了灵活的数据模型... | 102 | + +- `comments` 表 (存储评论信息) + +| comment_id (主键) | body | commenter_id (外键) | post_id (外键) | +| ----------------- | ---------------- | ------------------- | -------------- | +| 1001 | 写得很棒! | 102 | 1 | +| 1002 | 学习了。 | 101 | 2 | +| 1003 | 有没有更多例子? | 101 | 1 | + +- `tags` 表 (存储标签) + +| tag_id (主键) | tag_name | +| ------------- | -------- | +| 51 | 数据库 | +| 52 | 技术 | +| 53 | 入门 | + +- `post_tags` 表 (存储文章与标签的多对多关系,体现联表特点) + +| post_id (外键) | tag_id (外键) | +| -------------- | ------------- | +| 1 | 51 | +| 1 | 52 | +| 2 | 51 | +| 2 | 52 | +| 2 | 53 | + +若需查询 “Alice 发表的《初识 SQL》(post_id=1)的完整信息(含文章内容、作者、评论、标签)”,需执行多表连接(JOIN)查询,通过外键关联 5 张表并聚合数据,SQL 语句如下: + +```sql +SELECT + p.title, + p.content, + u.username AS author, + c.body AS comment, + t.tag_name AS tag +FROM + posts p +JOIN + users u ON p.author_id = u.user_id +LEFT JOIN + comments c ON p.post_id = c.post_id +LEFT JOIN + post_tags pt ON p.post_id = pt.post_id +LEFT JOIN + tags t ON pt.tag_id = t.tag_id +WHERE + p.post_id = 1; +``` + +这个查询会跨越5个表,将所有相关Agregacion de datos在一起返回。这是关系数据库的核心优势:通过规范化和连接操作,可以灵活地进行各种复杂的查询,同时保证了数据的一致性和最小冗余。 + +### 非关系数据库 (NoSQL) 示例 + +NoSQL 数据库(如 MongoDB、Redis)的设计思路与 SQL 相反,它不强调数据的拆分与规范,通常会将业务上相关联的所有数据打包聚合在一起,以减少查询时的连接操作,从而提高读取性能。 + +在 NoSQL 数据库中,文档数据库(Document Database) 是最常用的类型之一,MongoDB 就是典型代表。它以 “文档” 作为基本存储单元,这里的 “文档” 并非我们日常理解的 “文章”,而是一种类似 JSON 的数据结构(MongoDB 中实际使用 BSON 格式,支持更多数据类型):无需预先定义统一的 Schema(数据结构),每个文档的字段可以灵活增减,字段类型也能自由调整,完美适配数据格式多变的场景。 + +在文档数据库中,通常会将一篇文章及其所有相关信息(如评论、标签)存储在一个文档中(文档格式类似 JSON,可灵活定义字段,无需预先制定 Schema),核心逻辑是 “将‘一个业务场景下的完整信息’存放在一个文档中”,避免查询时的多数据源拼接。 + +`posts` 集合中的一个文档示例: + +```json +{ + "_id": 1, + "title": "初识SQL", + "content": "这是关于SQL数据库的一篇文章...", + "author": { + "user_id": 101, + "username": "Alice", + "email": "alice@example.com" + }, + "tags": [ + "数据库", + "技术" + ], + "comments": [ + { + "comment_id": 1001, + "body": "写得很棒!", + "commenter": { + "user_id": 102, + "username": "Bob" + } + }, + { + "comment_id": 1003, + "body": "有没有更多例子?", + "commenter": { + "user_id": 101, + "username": "Alice" + } + } + ] +} +``` + +这种设计的优势非常直观:当你需要获取 “第一篇文章的完整信息(含作者、评论、标签)” 时,只需通过 `_id:1` 查询这一个文档,数据库一次读取就能返回所有数据,无需像 SQL 那样执行 3-4 次表连接操作,读取效率大幅提升。 + +但它也存在明显的 trade-off(取舍):由于数据是 “聚合存储”,会不可避免地产生数据冗余—— 比如作者 “Alice” 的 `username` 被嵌入到她写的每一篇文章文档中,如果某天 “Alice” 将用户名改为 “Alice_New”,理论上需要遍历所有包含她信息的文章文档,逐一更新 `author.username` 字段,不仅操作繁琐,还可能因网络或服务器问题导致部分文档更新失败,出现 “同一用户在不同文章中用户名不一致” 的情况。 + +不过在实际业务中,这种冗余往往是 “可接受的”:对于博客、资讯、电商商品详情等 “ **读多写少** ” 的场景(用户查看内容的次数远多于作者修改用户名的次数),用少量的冗余换取 “极致的读取性能” 是更优的选择;而如果是 “写多读少”(如频繁修改用户信息)的场景,则需要结合业务需求权衡是否使用文档数据库。 + +以上是对不同数据库的简单介绍,如果你对更多具体的数据库类型感兴趣,你可以参考如下资料尝试不同类型的数据库。 + +Examples of SQL databases: +[Db2](https://www.ibm.com/products/db2-database)、[MySQL](https://cloud.ibm.com/catalog#highlights)、[PostgreSQL](https://www.ibm.com/think/topics/postgresql)、[YugabyteDB](https://www.yugabyte.com/)、[CockroachDB](https://www.cockroachlabs.com/)、[Oracle Database](https://www.ibm.com/products/postgres-enterprise)、[Azure SQL Database](https://www.ibm.com/consulting/microsoft) + +Examples of NoSQL databases: +[Redis](https://www.ibm.com/think/topics/redis)、[CouchDB](https://www.ibm.com/think/topics/couchdb)、[MongoDB](https://www.ibm.com/think/topics/mongodb)、[Cassandra](https://cloud.ibm.com/catalog#highlights)、[Elasticsearch](https://www.ibm.com/think/topics/elasticsearch)、[BigTable](https://www.techtarget.com/searchdatamanagement/news/252512583/Google-scales-up-Cloud-Bigtable-NoSQL-database)、[Neo4j](https://neo4j.com/users/ibm/)、[HBase](https://www.ibm.com/think/topics/hbase) + +# 2. Supabase + +在前面我们已经介绍了几类常见的数据库,以及它们各自适合的使用场景。不过在真实项目里,数据库通常只是后端体系中的一个基础模块:除了存储和查询数据,你还需要解决**用户注册登录、权限校验、文件上传与存储、对外 \*\***API\***\* 接口、甚至定时任务、实时通知**等一整套问题。仅仅选好数据库,并不能让你的应用“立刻就能上线运行”,中间还隔着一大圈繁琐的后端工程工作。 + +所以,我们需要考虑一个更大的背景: **后端服务** 。一个完整的应用,通常都由“前端 + 后端”组成:前端负责页面展示和用户交互,后端则负责数据存储、用户登录、业务逻辑处理等。过去,开发者往往需要自己搭建服务器、配置数据库、设计并实现 API,还要手动处理权限管理、安全策略、扩展性和监控运维等事务,整个过程既重复又耗时。为了解决这些重复劳动,业界出现了 **BaaS(Backend as a Service,后端即服务)** :把数据库、用户认证、文件存储、实时能力等常见后端功能打包成一个云端平台,开发者通过 SDK / API 就能直接调用这些能力,而无需从零搭建和运维基础设施。 + +在这个背景下,[Supabase](https://supabase.com/) 就可以看作是新一代的 BaaS 代表:它以 PostgreSQL 作为核心数据库,在其之上集成了 Auth、Storage、Realtime、Edge Functions、Vector 等一整套后端能力,为开发者提供一个“以 Postgres 为中心的一站式后端平台”。接下来,我们就从这个角度出发,从“只选数据库”升级到“选择完整的Desarrollo backend平台”,具体看看 Supabase 能帮我们省掉哪些工作,又是如何让一个项目从原型到可用产品的距离大幅缩短的。 + +## 2.1 分步指南 + +在清晰把握 Supabase 的整体定位后,接下来我们将沿着 Supabase 控制台的操作路径,逐项拆解它具体提供哪些核心能力,以及每项能力对应的核心Responsabilidad。我们会详细介绍 supabase 涉及的每个选项,帮助你快速入门 supabase 的基本操作。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image2.png) + +访问 Supabase 官网并登录后,在控制台首页点击 New project 进入创建流程; + +输入需要配置的主要内容 Project Name、数据库密码,地址只需要选择为与程序目标用户最接近的区域即可。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image3.png) + +创建成功后,控制台左侧侧边栏将显示所有核心功能模块(Table Editor、SQL Editor、Database、Authentication 等),后续操作将围绕这些模块展开。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image4.png) + +### 表编辑器 + +Table Editor 可以当成是 Supabase 的可视化数据表编辑器,它能让你像操作 Excel 一样直接查看和修改数据库里的数据,无需编写 SQL 语句,只需要用鼠标交互即可修改数据内容。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image5.png) + +其中值得关注的是 Schema,Schema 可理解为数据库内的 “资源容器”,用于对表、视图、函数、索引等资源进行分组管理,主要作用有二:一是避免命名冲突(不同 Schema 下可存在同名table),二是实现Aislamiento de permisos(如仅允许特定用户访问某 Schema 下的表); + +点击编辑器顶部的 Schema 下拉框可切换不同容器,日常开发中一般只需关注两类: + +- `public`:默认的公共资源容器,开发者新建的业务表(如 “文章表”“评论表”)均存储于此; +- `auth`:用户认证专属容器,其中的 `users` 表自动存储所有注册用户信息(如用户 ID、邮箱、登录时间),不建议手动修改此 Schema 下的默认表,避免影响认证功能; + +![](/zh-cn/stage-2/backend/database-supabase/images/image6.png)![](/zh-cn/stage-2/backend/database-supabase/images/image7.png) + +### SQL 编辑器 + +SQL Editor 作为 Supabase 的 SQL 语句执行器,可让你用代码的方式直接操作数据库。你可以让大模型直接生成 SQL 语句,在右侧输入后点击 RUN 即可用语句创建或修改 table,也可以直接在 Results 中直接看到筛选出的 table 数据。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image8.png) + +你可以在运行 RUN 之后,在 Table Editor 的 public schema 里找到新建后的数据表;并且运行后的语句会保存在左侧的 PRIVATE 栏中,甚至可以点击下方的爱心标志对这一条查询或创建语句进行收藏。 + +### 数据库管理中心 + +Database 是 Supabase 的数据库管理中心,支持可视化地查看和管理所有数据表,并通过表的相互连线理解不同表间的关联关系(即外键约束,表示数据间的引用关系)。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image9.png) + +如果你想要手动新建 table,可以在 tables 中直接新建表格,我们会在之后的教程中详细讲解。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image10.png) + +### 身份认证 + +Authentication 负责管理用户的注册、登录和权限。默认的用户管理系统数据都在此处存储,它提供了开箱即用的用户注册、登录、密码重置、邮箱验证等功能,并支持第三方 OAuth 登录(如微信、GitHub、Google 等)。所有用户数据会自动同步到数据库的 `auth.users` 表中。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image11.png) + +你可以在 Provider 选项中找到不同 supabase 支持的用户信息登录入口,默认使用 Email;如果你想使用 Github 或者 Google 账户进行登录,还需要更多属性配置,我们会在下面的课程中进行详细讲解。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image12.png) + +在 Sign In / Providers 里还包含了对注册邮箱行为的控制,如果你不想每次邮箱注册都必须让用户接受邀请后才能成为用户,你可以取消 Confirm email 的强制要求。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image13.png) + +如果你想切换非 Supabase 的其他 auth 系统服务商,你可以点击 Third Party Auth,比如此处就使用 Clerk 作为第三方的系统服务商。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image14.png) + +如果你担心注册用户在短期内访问量过大,你可以在 Rate Limits 中启用对应的流量限制策略: + +![](/zh-cn/stage-2/backend/database-supabase/images/image15.png) + +### 存储 + +Storage 是 Supabase 的存储系统,兼容 amazon cloud 的 s3 概念,可用于存储任意类型的文件(如图片、视频、文档、音频等),并提供访问权限管理(公开或私有)和下载链接获取(永久链接或临时链接),你能够很方便在应用中对用户涉及到的文件内容进行上传与下载管理,并与 Supabase 的认证系统无缝集成,实现精细化的访问控制。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image16.png) + +我们将会在本节课的进阶 project 中讲解 storage 的具体用法。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image17.png) + +如果你想使用 S3 的相关协议进行操作,可以直接使用对应的配置: + +![](/zh-cn/stage-2/backend/database-supabase/images/image18.png) + +> Amazon Cloud(亚马逊云服务,简称 AWS)是亚马逊提供的云计算平台(就像一个大型的网络机房,你可以按需租用计算和存储资源)。S3(Simple Storage Service)是 AWS 里专门用来存储文件的服务(类似一个无限大的网盘,可以存图片、视频、备份等各种文件),它是目前最流行的对象存储服务,已经成为了事实上的行业标准。 +> +> **为什么要做成 S3 兼容 \*\***API\*\* ** ?** :S3 已经存在近 20 年,市面上有大量现成的工具、SDK 和文档,兼容 S3 意味着你可以直接用这些资源,不用从头开始制作各类相关工具,能够快速满足业务上线的需求。 + +### 边缘函数 + +如果你不想Despliegue后端,但是想使用数据库和函数操作,你可以使用 Edge Functions 构建无需自建服务器的后端核心能力,它是 Supabase 提供的全球分布式服务端函数。简单来说,它让你无需购买和管理自己的后端服务器,就能直接编写并Despliegue在云端的后端代码。这些函数Despliegue在全球网络的边缘节点上,会自动在离你的用户最近的位置运行,从而大幅降低网络延迟,提供极致的响应速度。你可以在 Supabase 的仪表盘中直接创建、编辑和Despliegue,整个开发流程非常便捷。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image19.png) + +Edge Functions 的一个核心用途是充当安全的中间层,保护你的敏感信息和鉴权密钥。在前端代码中直接调用第三方服务(如 OpenAI、Stripe)会暴露你的 API Key,带来极大的安全风险。通过 Edge Functions,你的前端应用只与你的 supabase 函数通信,所有秘密只在 supabase 中保管。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image20.png) + +Edge Functions 的函数使用 secrets 中暴露的密钥作为环境变量,通过 `Deno.env.get` 加载,从而实现第三方服务的调用。这样一来,敏感密钥就永远不会暴露在客户端(你的浏览器),彻底杜绝了被盗用的风险。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image21.png) + +请求 Supabase Edge Function 时,需在请求头携带对应的 Supabase 密钥,下面是一个极简示例: + +```javascript +// 核心配置(替换为你的实际信息) +const projectId = "你的 Supabase 项目ID"; +const functionName = "目标 Edge Function 名称"; +const supabaseKey = "Supabase anon_key"; + +// 调用函数 +async function callEdgeFunction() { + const url = `https://${projectId}.supabase.co/functions/v1/${functionName}`; + + try { + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${supabaseKey}` // 关键:携带密钥完成认证 + }, + body: JSON.stringify({ order_id: "123", action: "refund" }) // 自定义请求数据 + }); + + const result = await response.json(); + console.log("调用成功:", result); + } catch (error) { + console.error("调用失败:", error.message); + } +} + +// 执行调用 +callEdgeFunction(); +``` + +此外,Edge Functions 与 Supabase 的用户认证系统无缝集成。当已登录的用户调用一个函数时,其身份信息会传递给函数。这使得你可以在函数内部轻松识别当前用户,并根据其身份执行Control de permisos。更重要的是,函数在操作数据库时会自动遵循你设置好的行级安全策略(Row Level Security),确保用户只能访问和修改他们有权操作的数据,让构建安全的多用户应用变得简单。 + +Edge Functions 的应用场景非常广泛,能够处理各种后端任务。它们非常适合用来监听来自第三方服务的 Webhook 事件(例如支付成功、代码提交等),并自动执行相应的数据处理逻辑。你也可以用它来发送邮件通知、生成 PDF 报告、创建自定义的 API 接口来封装复杂的业务逻辑,或者执行任何你希望在服务端完成的计算任务,极大地扩展了你应用的能力。 + +具体到一个常见的例子:身份认证工具 Clerk 。Clerk 仅用于处理用户登录、注册、信息更新等认证相关操作,并不直接管理你的业务数据库。如果你想要将这些认证动态同步到业务数据库中,则需要通过触发 Webhook 事件请求 Edge Functions 实现。Edge Functions 能够监听 Clerk 发出的 Webhook 信号,自动执行数据同步逻辑,让 Supabase 数据库中的用户信息与 Clerk 登录状态实时对齐,全程无需你Despliegue独立后端。 + +### 实时数据同步引擎 + +Realtime 是 Supabase 的实时数据同步引擎,它允许你的应用即时接收数据库的变化通知,而无需反复轮询 API。当数据库中的数据发生 `INSERT`、`UPDATE` 或 `DELETE` 操作时,Realtime 会通过 WebSocket 将这些变化实时推送给所有已连接的客户端。这对于构建需要实时交互的应用至关重要。 + +Realtime 主要包含三大核心功能,覆盖了绝大多数实时场景: + +1. **Postgres Changes:** 直接监听数据库表的变化。你可以精确地订阅特定表、特定事件(增、删、改),甚至可以根据筛选条件来接收通知,并与行级安全策略(Row Level Security)完美集成,确保用户只能收到他们有权限查看的数据变更。 +2. **Broadcast:** 允许客户端之间通过频道(Channel)发送低延迟的临时消息。这非常适合实现聊天室、实时光标追踪、在线游戏状态同步等功能。 +3. **Presence:** 用于追踪和同步在线用户状态。你可以用它来轻松实现“谁在线上”、“当前有X人正在查看”等功能,非常适合协作类应用。 + +我们会在后续的项目制学习中详细介绍该部分的内容。 + +### 项目设置 + +Project Settings 是 Supabase 项目的高级配置部分,你可在此实现计算资源的深度调度,以及各类功能底层参数的精细化配置。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image22.png) + +在入门阶段,我们只需聚焦以下两个核心板块,一个是 Data API,我们在此可获取关键的 “Supabase URL”, 它是形如 `https://xxx.supabase.co` 的 RESTful 端点,是所有数据查询、新增、修改、删除操作的 “入口地址”。前端或服务端需通过该 URL 初始化 Supabase 客户端,建立与数据库的连接。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image23.png) + +另一个重点是 API Keys,选择 “Legacy anon, service_role API keys” 标签页,其中的 anon public 密钥 是前端场景的重要身份凭证,它的权限被 RLS 严格限制,仅能访问用户被授权的数据。而 service_role 密钥属于 “服务端高权限密钥”,具备绕过行级安全的能力,可执行批量数据操作、系统级配置等敏感操作。绝对禁止公开分享,若泄露需立即生成新密钥并更新服务端配置。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image24.png) + +其余配置项在当前阶段无需深究,待后续有进阶使用需求时再逐一探索即可。 + +## 2.1 创建你的第一个 SQL 数据表 + +以上是 Supabase 的界面介绍,接下来我们将深入 Supabase 的核心数据库的操作环节。 + +在 Supabase 中创建数据表,主要有以下两种常用方式,你可以根据需求选择: + +1. (推荐)借助大语言模型生成适配 Supabase 的 SQL 语句,直接在 **SQL Editor(** 前文介绍的 SQL 语句执行器)中粘贴执行,高效快捷,我们会在下个部分环节重点说明这个操作过程。 +2. 通过可视化操作创建:在左侧侧边栏找到 Database 模块,点击进入后选中侧边栏的 Tables,在右侧点击 New table 按钮,即可通过图形化界面创建数据表。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image25.png) + +值得注意的是,对应数据表的名称以及存储的数据类型可在下方的 Columns 中指定。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image26.png) + +对于关系数据库,其中很重要的特点是表与表之间的关联,你可以在下方找到 `Foreign keys` ,点击创建相应的关联关系: + +![](/zh-cn/stage-2/backend/database-supabase/images/image27.png) + +其中 `Foreign keys` 表达了表与表之间的关联关系:一个或一组字段,它在当前表(子表)中的值,会引用另一张表(父表)中主键的值。 + +例如,在创建 `学生表`的时候,我们可以这样定义外键:(`所属班级编号` 这一列是一个外键。这个外键引用了 `班级表` 里的 `班级编号` 这一列。) + +```sql +CREATE TABLE 学生表 ( + 学生学号 INT PRIMARY KEY, + 学生姓名 VARCHAR(50), + 所属班级编号 INT, + FOREIGN KEY (所属班级编号) REFERENCES 班级表(班级编号) +); +``` + +更具体举例而言,我们可以可视化观察对应的表的结构: + +班级表: +这张表里记录了所有班级的信息,每个班级都有一个独一无二的班级编号。班级编号就是这张表的主键 (Primary Key),是每个班级的唯一身份证。 + +| 班级编号 | 班级名称 | +| -------- | ---------- | +| 101 | 一年级一班 | +| 102 | 一年级二班 | + +学生表: +这张表记录了所有学生的信息。每个学生都属于一个特定的班级,对吗?那么我们怎么知道哪个学生在哪个班级呢? + +我们可以在学生表里增加一列,叫做 `所属班级编号`。 + +| 学生学号 | 学生姓名 | 所属班级编号 | +| -------- | -------- | ------------ | +| 2024001 | 张三 | 101 | +| 2024002 | 李四 | 102 | +| 2024003 | 王五 | 101 | + +在该例子中,学生表中的 `所属班级编号` 列就是外键 (Foreign Key)。 + +在 Supabse 中,点击添加 Foreign Key 后,你可直接选择进行关联表对应列的选取 + +![](/zh-cn/stage-2/backend/database-supabase/images/image28.png) + +## 2.3 SQL Editor 简介与数据库基本操作 + +接下来我们将分步执行一系列 SQL 脚本,熟悉常见的 SQL 中的增删查改操作。你可以将每个步骤的代码复制到 SQL Editor 中,执行并观察结果。 + +你可以在该目录下获得所有的测试 SQL 文件: + +https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos/tree/main/apps/sql-examples + +### **2.3.1 **`CREATE`** - 创建表结构** + +`CREATE TABLE` 语句用于为新表定义模式(Schema),包括其列(Columns)、对应的数据类型(Data Types)以及任何约束(Constraints),简单理解是创建了一个数据表。 + +```sql +-- Step 1: Create the 'orders' table +-- This file is fully independent and creates a sample table for later steps. +CREATE TABLE IF NOT EXISTS orders ( + id serial PRIMARY KEY, + user_id int NOT NULL, -- User ID + status text NOT NULL, -- Order status (e.g. paid, pending) + amount numeric(10, 2) NOT NULL, -- Order total amount + details jsonb, -- Item and extra details as JSON + placed_at timestamptz DEFAULT now(), -- Order creation time + is_paid boolean DEFAULT false -- Paid flag +); + +-- Expected Output: +-- Orders table created if it did not exist. +-- No data inserted. (Querying returns zero rows for now.) +-- If table already exists, no error occurs. +``` + +成功执行后,系统将提示脚本已完成。你可以在 Table Editor 中看到对应的表被创建完成: + +![](/zh-cn/stage-2/backend/database-supabase/images/image29.png) + +### **2.3.2 **`INSERT`** - 填充初始数据** + +表结构创建完毕后,下一步是使用 `INSERT INTO` 语句向表中添加数据行。 + +```sql +-- Step 2: Insert initial rows into the orders table +-- Provides realistic, varied data for demo/testing. All values are self-contained. +INSERT INTO orders (user_id, status, amount, details, placed_at, is_paid) VALUES + (2001, 'pending', 23.50, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '2 days', false), + (2002, 'paid', 50.00, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":2,"price":5.00}]}', now() - interval '1 day', true), + (2003, 'cancelled', 15.00, '{"items":[{"sku":"FRY001","name":"French Fries","qty":3,"price":5.00}], "reason":"Not available"}', now() - interval '45 days', false), + (2004, 'paid', 22.98, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":2,"price":9.99}], "promo":"SUMMER22"}', now() - interval '10 days', true), + (2005, 'pending', 18.75, '{"items":[{"sku":"SAL001","name":"Salad","qty":1,"price":6.75},{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '7 hours', false), + (2006, 'paid', 8.00, '{"items":[{"sku":"DRK002","name":"Cola","qty":2,"price":4.00}]}', now() - interval '3 hours', true), + (2007, 'refunded', 14.50, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99},{"sku":"FRY001","name":"French Fries","qty":1,"price":4.51}], "refund_reason":"Late delivery"}', now() - interval '15 days', false), + (2008, 'paid', 26.99, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":1,"price":6.99}]}', now() - interval '12 days', true), + (2009, 'pending', 9.99, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99}]}', now() - interval '30 minutes', false), + (2010, 'paid', 19.89, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00},{"sku":"DRK002","name":"Cola","qty":2,"price":3.95}]}', now() - interval '5 days', true), + (2011, 'cancelled', 0.00, '{"items":[], "reason":"User cancelled"}', now() - interval '2 days', false); + +-- Expected Output: +-- After running this script, SELECT * FROM orders will show about 11 rows with varied user_id, status, amount, details (JSON), placed_at, and is_paid fields. +-- For example: +-- | id | user_id | status | amount | is_paid | placed_at | +-- |----|---------|-----------|--------|---------|---------------------| +-- | 1 | 2001 | pending | 23.50 | false | 2025-10-28 13:40:00Z| +-- | 2 | 2002 | paid | 50.00 | true | ... | +-- |... | ... | ... | ... | ... | ... | +``` + +执行成功后,此时表中已经插入了原始数据,你可以进入到 Table Editor 界面刷新后看到结果,也可以直接在 SQL Editor 界面中新建窗口,执行查询语句 `SELECT * FROM orders;`查看结果: + +![](/zh-cn/stage-2/backend/database-supabase/images/image30.png) + +### **2.3.3 **`SELECT`** - 读取与查询数据** + +`SELECT` 语句用于从表中检索数据。通过使用不同的子句,可以实现对数据的精确筛选、排序和格式化,我们可参考以下语句一步步执行查看结果: + +```sql +-- Step 3: SELECT query examples for the orders table + +-- Example 1: Select all fields for all orders +SELECT * FROM orders; +-- Expected Output: Returns all rows and fields. Columns: id, user_id, status, amount, details, placed_at, is_paid. + +-- Example 2: Select only pending orders +SELECT id, user_id, amount FROM orders WHERE status = 'pending'; +-- Expected Output: All rows with status 'pending'; columns: id, user_id, amount. + +-- Example 3: Select specific fields and filter by payment status +SELECT id, status, is_paid, amount FROM orders WHERE is_paid = true; +-- Expected Output: All rows where is_paid is true; columns: id, status, is_paid, amount. + +-- Example 4: Extract all item names from the details (JSON) for each order +SELECT id, details -> 'items' AS item_list FROM orders; +-- Expected Output: Each row shows id and an array from JSON with item details. +``` + +- **示例 1:** 返回 `orders` 表中的所有行和列,与第二步的输出类似。 +- **示例 2:** 仅返回状态为 'pending' 的订单,且只包含指定的列: + +![](/zh-cn/stage-2/backend/database-supabase/images/image31.png) + +- **示例 3:** 仅返回已支付的订单,并显示指定的列: + +| id | status | is_paid | amount | +| --- | ------ | ------- | ------ | +| 2 | paid | true | 50.00 | +| 4 | paid | true | 22.98 | +| 6 | paid | true | 8.00 | +| 8 | paid | true | 26.99 | +| 10 | paid | true | 19.89 | + +- **示例 4:** 返回每个订单的 `id` 和从 `details` 字段中提取的 `items` 数组: + +| id | item_list | +| --- | -------------------------------------------------------------------------------------------------------------------- | +| 1 | `[{"qty":1,"sku":"BGR001","name":"Beef Burger","price":12}]` | +| 2 | `[{"qty":2,"sku":"BGR002","name":"Chicken Burger","price":10},{"qty":2,"sku":"DRK001","name":"Lemonade","price":5}]` | +| 3 | `[{"qty":3,"sku":"FRY001","name":"French Fries","price":5}]` | +| ... | ... | + +### **2.3.4 **`INSERT`** - 插入单条记录** + +在 2.3.2 中,我们演示的是开头时刻初始化批量插入数据,现在我们查看如何新增插入单条数据。 + +```sql +-- Step 4: INSERT a new order (single row) +-- Example: Add a new paid order for user 2012 with one Chicken Burger +INSERT INTO orders (user_id, status, amount, details, is_paid) +VALUES ( + 2012, 'paid', 9.99, + '{"items":[{"sku":"BGR002","name":"AIID Burger","qty":100,"price":1000}]}', + true +); +-- Expected Output: +-- Before (table fragment): +-- | id | user_id | status | amount | is_paid | +-- | ...| ... | ... | ... | ... | +-- +-- After (last row): +-- | id | user_id | status | amount | is_paid | +-- | xx | 2012 | paid | 9.99 | true | +-- (where xx = next serial value) +``` + +此时再用 `SELECT * FROM orders;` 对数据进行查询,我们可以看到 orders 表成功从 11 个数据变成了 12 个数据。 + +### **2.3.5 **`UPDATE`** - 修改现有数据** + +在实际工作中,我们需要对数据表进行频繁数据更新,我们能够用 `UPDATE` 语句修改表中已存在的记录。 + +```sql +-- Step 5: UPDATE example +-- Example: Mark order with id=1 as paid and update its status +UPDATE orders SET status = 'paid', is_paid = true WHERE id = 1; +-- Expected Output: +-- Before (row with id=1): +-- | id | status | is_paid | +-- | 1 | pending | false | +-- After (row with id=1): +-- | id | status | is_paid | +-- | 1 | paid | true | +-- All other rows remain unchanged. +``` + +### **2.3.6 **`DELETE`** - 删除数据** + +`DELETE` 语句可用于从表中移除记录,并结合条件对指定部分的数据进行修改。 + +```sql +-- Step 6: DELETE example +-- Example: Delete orders older than 2 days to clean up old data +DELETE FROM orders WHERE placed_at < now() - interval '2 days'; +-- Expected Output: +-- Before (filtered for affected rows): +-- | id | status | placed_at | +-- | 3 | shipped | 2025-10-13 ... | <-- will be deleted +-- +-- After: +-- No such rows remain. SELECT * FROM orders WHERE placed_at < now()-interval '2 days' yields zero rows. +-- Other rows in orders table are unaffected. +``` + +执行前,你可先执行 `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';` 进行数据表筛选结果的查看。当运行 `DELETE` 命令后,再次执行相同的 `SELECT` 查询 `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';`,将返回一个空的结果,表明这些行已被成功删除。 + +## 2.4 行级安全 + +在学习了数据库的基本操作后,我们需要进一步深入一个保障数据安全的核心概念 ——RLS(行级安全,Row Level Security)。 + +不妨先思考一个实际场景中的关键问题:如何实现数据的 “隔离访问”?比如,只允许用户 A 查看自己的数据,而无法看到用户 B 的信息;再比如,即便某角色拥有数据库的访问权限,如何避免其误操作或泄露其他用户的敏感数据? + +RLS 正是为解决这类数据安全与隔离需求而生。它允许开发者为数据库表定义精细化的安全策略,根据用户的身份信息(如用户 ID、角色权限等),精确控制哪些用户能访问、修改表中的哪些行数据。 +举个典型示例:对于订单表(`orders`),我们可以定义这样一条 RLS 策略 ——“仅当 `orders` 表中某条记录的 `user_id` 列,与当前登录用户的 ID 完全一致时,该用户才能查询到这条订单数据”,从而实现 “用户只能看自己的订单” 的核心需求。 + +当你为某张表启用 RLS后,该表的所有数据操作请求(包括 `SELECT` 查询、`INSERT` 新增、`UPDATE` 修改、`DELETE` 删除)都会触发 RLS 校验:必须通过至少一条安全策略的检查,操作才能执行。若不存在允许该操作的策略,或请求未满足任何策略的条件,数据库会直接拒绝此次操作,从底层阻断非授权访问。 + +在 Supabase 中,RLS 与用户认证系统深度绑定,使用起来更为便捷。Supabase 提供了一个专用函数 `auth.uid()`,它能直接返回 “当前发起请求的已登录用户” 的唯一 ID(格式为 UUID)。借助这个函数,我们可以轻松编写策略,实现 “数据行与用户身份” 的精准关联(比如前文提到的 “订单 `user_id` 匹配当前用户 ID”)。 + +启用 RLS 策略的方式很灵活,你可以在 Supabase 数据库管理界面中的 “RLS” 按钮,直接配置并启用策略: + +![](/zh-cn/stage-2/backend/database-supabase/images/image32.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image33.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image34.png) + +主动配置难免显得麻烦,通常,我们在数据表语句创建、初始化的时候就会自动考虑植入对应的 RLS 策略。我们只需在 SQL Editor 中执行类似如下语句,即可自动开启对应数据表的行级安全策略。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image35.png) + +# 3. 第一个 SQL 应用 + +掌握了数据库基础操作与RLS核心逻辑,我们终于进入本次教程的实践环节。漫长的学习铺垫是为了让后续“从0到1搭建应用”的过程更清晰。接下来,我们将以“汉堡店订单管理”为场景,手把手演示Supabase的常见操作:从应用与Supabase的关联配置,到数据库与登录功能的集成,逐步学习不同操作逻辑。 + +## 3.1 克隆并运行 Supabase 示例项目 + +要开展实操,首先需要获取配套的演示代码仓库。你可以让 Trae 或 Claude Code 协助 git clone 以下仓库:https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos + +若已配置 SSH 密钥,建议使用 SSH 地址进行 clone(git@github.com:THU-SIGS-AIID/Project5-Supabase-Demos.git)以提升安全性;若 SSH 或 HTTPS 连接遇到网络问题,可以直接点击仓库页面的 “Download ZIP”,获取压缩包后解压即可看到完整代码。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image36.png) + +Clone 后,你同样可以让 Trae 或者是 Claude Code 帮你启动项目,例如直接在 Agent 界面中说明: `帮我直接启动这个项目里面的 project 1 `,或者复制对应想启动 project 的绝对路径,粘贴给大模型让大模型直接启动。 + +## 3.2 项目1 - 汉堡店菜单增删改查 + +接下来进入实操环节 —— 以 `project-burger-shop-menu-crud-1` 为例,我们将学习如何通过 SQL 脚本一键初始化 Supabase 数据库,并完成本地项目与 Supabase 数据库的关联配置,让前端能正常读写菜单数据。 + +### 使用脚本创建数据库 + +首先,我们需要在 Supabase 中创建需要的数据表的相关内容。进入 Project1 项目目录看到名为 `scripts`的文件夹,其中包含 1 个 `init.sql`数据库脚本文件,它能帮我们自动完成所有数据库相关资源的创建(包括表结构、初始数据等),之后我们会经常用到该文件进行数据库中表的初始化。 + +```sql +...... + +-- ============================================================================ +-- 2. Create Menu Items Table +-- ============================================================================ + +create table if not exists public.menu_items ( + id uuid primary key default gen_random_uuid(), + name text not null, + description text, + category text check (category in ('burger','side','drink')) default 'burger', + price_cents int not null check (price_cents > 0), + available boolean default true, + emoji text, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +-- Comments for documentation +comment on table public.menu_items is 'Burger shop menu items for CRUD demo'; +comment on column public.menu_items.id is 'Unique identifier for each menu item'; +comment on column public.menu_items.name is 'Display name of the menu item'; +comment on column public.menu_items.description is 'Detailed description of the menu item'; +comment on column public.menu_items.category is 'Category: burger, side, or drink'; +comment on column public.menu_items.price_cents is 'Price in cents (integer) to avoid floating point issues'; +comment on column public.menu_items.available is 'Whether the item is currently available for order'; +comment on column public.menu_items.emoji is 'Optional emoji representation of the menu item'; +comment on column public.menu_items.created_at is 'Timestamp when the item was created'; +comment on column public.menu_items.updated_at is 'Timestamp when the item was last updated'; + +...... +``` + +在 SQL Editor 中执行初始化 sql 脚本后,即可在 Table Editor 中看见已创建的数据表。其中数据库初始化代码具体执行逻辑如下: + +1. 创建 menu_items 表 : +2. 这个表用于存储汉堡店菜单中的所有项目。它包含了如 name (商品名), description (描述), price_cents (以美分为单位的价格,避免浮点数精度问题), category (分类) 和 available (是否可售) 等字段。这基本涵盖了一个菜单项所需的所有信息。 +3. 创建 promo_codes 表 : +4. 此表用于管理促销活动,例如折扣码。它定义了 code (折扣码), discount_type (折扣类型,如百分比或固定金额), discount_value (折扣数值) 等字段。 +5. 禁用行级安全 (Row Level Security - RLS) : +6. 为了方便开发和测试,脚本中明确地禁用了 RLS。但结合我们之前学习的 RLS 核心逻辑:RLS 是 Supabase 保障数据安全的关键功能,能通过精细化策略控制 “谁能访问 / 修改哪些数据”(比如只允许管理员编辑促销码,普通用户只能查看菜单)。因此在生产环境中,必须开启 RLS 并配置合理策略,从底层阻断非授权访问(如防止用户恶意修改他人创建的菜单,或泄露促销码规则)。 +7. 插入种子数据 (Seed Data) : +8. 为了让前端项目启动后就能看到真实的菜单与促销数据(无需手动录入测试数据),`init.sql`脚本还会向 `menu_items`和 `promo_codes`表中插入 “种子数据”(即示例数据)。例如,你可以看到各种汉堡、小食、饮料以及多种多样的折扣码。 + +### 设置与数据库的连接 + +数据库准备完成,我们需要将这个前端项目与 Supabase 进行连接,从而正常读取数据库内的数据。我们需要将 Supabase 项目的 URL 和 anon key 写到指定配置中,本项目提供了两种灵活的配置方式: + +1. 通过环境变量配置 + +在项目根目录创建一个 .env 文件,并填入你的 Supabase 凭证: + +``` +NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co +NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key +``` + +2. 在项目页面中直接设置 + +为了方便快速演示和切换不同的 Supabase 项目,首页页面右上角提供了一个 设置 按钮。你可以点击它,在弹出的模态框中直接输入或粘贴 Supabase URL 和 anon key。 + +点击 “Save” 后,这些信息会用于动态创建 Supabase 客户端实例,类似下列代码所示: + +```JavaScript +import { createClient, type SupabaseClient } from '@supabase/supabase-js'; + +// Optional client factory for demos: returns null when env is not set. +export function maybeCreateBrowserClient(): SupabaseClient | null { + const url = process.env.NEXT_PUBLIC_SUPABASE_URL; + const anon = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; + if (!url || !anon) return null; + return createClient(url, anon); +} +``` + +创建完数据库,填写完对应的 Supabase Link 相关配置后,即可看到如下界面,你可以尝试对商品进行增删查改,并观察 Supabase 中对应部分数据表的变化。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image37.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image38.png) + +### 📚 作业 + +1. 尝试增加和删除已有项目,在 Table Editor 中查看修改操作对数据表内容变动的影响。 + +## 3.4 项目2 - 汉堡店认证用户 + +Project1 实现了 “菜单 CRUD + 数据库连接” ,Project2 将引入更贴近真实业务的核心能力,用户认证(Auth)与行级安全(RLS)权限管理。 + +Project2 包含独立的登录页,支持用户通过「邮箱 + 密码」的方式登录。其核心逻辑是调用 Supabase Auth 提供的原生方法,快速实现认证流程,无需手动开发复杂的登录校验逻辑: + +``` +const { error: err } = await supabaseClient.auth.signUp({ + email, + password, + options: { + data: { + full_name: fullName || null, + birthday: birthday || null, + avatar_url: avatarUrl || null + } + } +}); +``` + +![](/zh-cn/stage-2/backend/database-supabase/images/image39.png) + +登录成功后,Supabase 会自动为用户创建一个会话(session),并在后续所有数据库请求中自动携带认证信息;通过 RLS 的作用,每个用户根据对应的认证信息只能看到自己的账户信息(已购买项目、钱包剩余额度),无法看到其他用户的账户信息,这就实现了不同用户登录后的数据隔离,每个人只能看到自己的内容。 + +和 Project 1 一样,你需要先使用 `init.sql` 进行数据表的初始化(注:如果发现初始化出错,请先在 Table Editor 中删除已经创建的数据表,或者是直接删除这个 Supabase Project, 重新新建一个 Project) + +成功使用邮箱注册账户、在邮箱确认注册账户后,登录后进入 Shop 界面即可看到如下内容: + +![](/zh-cn/stage-2/backend/database-supabase/images/image40.png) + +但此时点击 admin,你并不能看到如下界面,你需要尝试在数据表中找到控制用户权限的部分,将权限修改为 `admin`,从而能够在 Admin 界面正常看到如下内容: + +![](/zh-cn/stage-2/backend/database-supabase/images/image41.png) + +值得提示的是,目前每次注册新的邮箱,你都需要在邮箱中进行注册确认才可登录;但这一步并非是必须的,你可以在 Supabase 的 Authentication 栏目中找到 Sign In / Providers,点击Confirm email 取消邮箱的强制确认。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image42.png) + +### 📚 作业 + +1. 请先领取新手礼包,完成商品购买操作。 +2. 尝试找到用户权限的设定数据表位置,将权限修改为 `admin`,并成功在订单管理界面修改商品数量 +3. 尝试在数据表内定位到钱包金额相关表,通过修改使剩余钱包金额增加。 + +# 4. 构建你的第一个 Supabase 应用 + +经过前面的系统学习,你已掌握 Supabase 的核心能力(数据库操作、用户认证、RLS 安全策略),现在是时候亲自动手,搭建属于你的第一个包含数据库、支持用户登录系统的应用了! + +## 4.1 为任意应用接入 Supabase 数据库的标准化流程 + +我们可以使用标准化流程将任意应用接入 Supabase 数据库: + +1. 首先进行需求梳理与信息同步,明确目标并告知AI + 1. 你需要向AI清晰描述当前应用的核心功能、待新增的数据库需求。示例:“我现有一个本地React Todo应用,数据仅存在浏览器本地存储,需新增‘数据云端同步’功能并接入Supabase数据库。请帮我梳理:这个应用涉及哪些数据操作(如新增待办、修改状态、删除待办)?需要创建哪些数据表来存储这些数据?” + 2. 补充关键约束条件(可选):比如字段格式要求(时间戳用 `timestamptz`、金额用整数存分)、数据权限规则(仅自己可见待办),让AI的分析更贴合实际需求。 + 3. 对 AI 返回的结果进行审核,若AI思路存在遗漏(如未考虑“待办截止时间”字段),补充提示修正:“你漏考虑截止时间了,帮我加上。” +2. 让AI基于你确认后的表结构,生成适配Supabase的 `init.sql`脚本:“基于上述所说思路和表的结构,返回给我在 Supabase 中可以进行初始化的 init.sql 脚本”,之后你需要在 SQL Editor 中执行脚本;若执行报错,将错误信息反馈给AI,让其修正脚本。 +3. 在 Supabase 运行 init.sql 脚本后,让 AI 基于脚本重构当前代码,使得能够和 Supabase 进行正常的数据交互:“请你根据我的 sql 脚本以及上面讨论的设定,重构项目的代码让它支持能够和 Supabase 对应的数据库进行通信并处理数据”。 +4. 重构完毕,此时只需要配置好 Supabase 地址和 key 的参数(正式项目通常只用环境变量配置),随后进行检查,若没问题则顺利实现将应用接入 Supabase 数据库。 + 1. 运行项目,测试所有数据库交互功能,到Supabase Table Editor 实时查看数据是否同步; + 2. 若出现问题(如数据无法插入、仅能看到部分数据),将问题现象反馈给AI,让其定位原因并修正代码。 + +此外,若目标是开发用户登录页面,可直接让 AI 协助集成登录页面 :“现在你需要帮我给这个应用加入 Supabase 的用户登录系统,使用邮箱可以注册和登录”。另外,你还需要向 AI 明确页面的跳转逻辑与路径(如登录成功后跳转至系统首页、跳转首页的地址是什么、登录失败时留在当前页并显示错误提示)。集成完成后,你需要尝试注册登录后能在 Supabase 的 Authentication 项目中看到新增的用户数据,并在登录后能正常进入到原先未登录无法进入的应用界面即可。 + +当然,你还可以直接让 AI 参考某个 project 的实现直接迁移对应的 Supabase 功能,比如某个 Project 用到了数据库以及 Edge fuction 的高级功能,你可以按照如下方式直接让 AI 迁移对应的相似功能:“请你参考该项目 {此处复制粘贴参考项目的绝对地址} 当中的 Supabase 相关功能实现逻辑,给当前项目加上类似的实现逻辑(如用户登录、数据库管理、函数请求等等)”。 + +## 4.2 案例研究:构建一个在线贪吃蛇游戏 + +根据上面所提到的 SOP ,让我们通过一个具体的实际案例 `Project5-Supabase-Demos/apps_snakegame`来实践:为一个已有的“贪吃蛇”游戏项目增加分数排行榜单,包含用户登录与数据库基础功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image43.png) + +### 4.2.1 分析项目,识别数据需求 + +首先,和在之前提到的标准化流程类似,我们可以先把需求澄清给 AI ,让 AI 基于我们项目和需求给出对应的修改方案,之后我们会基于这个修改方案。 + +**你可以使用如下的提示词来指导 AI:** + +> “我有一个贪吃蛇游戏,目录在 {此处粘贴贪吃蛇游戏的绝对路径}。现在我想结合 supabase 给它增加一个在线排行榜功能,并且支持用户登录系统,排行榜可以根据用户名和邮箱显示排名。 +> +> 请帮我分析一下,为了实现这个功能,我需要建立哪些数据表?每个表应该包含哪些字段?” + +此时你会得到类似如下返回: + +![](/zh-cn/stage-2/backend/database-supabase/images/image44.png) + +### 4.2.2 生成 `init.sql` 脚本 + +确定需要的部分,我们可以让 AI 生成需要在 Supabase 执行的数据库初始化脚本:“请你基于上面的分析,帮我在项目中生成 scripts/init.sql 脚本用于在 Supabase 中初始化所需数据库”。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image45.png) + +### 4.2.3 改造项目代码 + +接下来我们只需要让 AI 基于前面的内容重构当前的贪吃蛇代码:“接下来请你基于前面思考的内容以及 sql 表,使用 Supabase 帮我实现排行榜功能,排行榜是单独的一页,需要可以根据邮箱和用户名区分不同用户的总分,你还需要支持基于邮箱的用户登录系统,注册登录才能玩这个游戏。” + +如果当前 AI 对话轮次太多,你想重开一个新的会话进行项目重构,你可以把上面提到的 `init.sql`作为上下文中的内容,让 AI 基于 sql 文件进行项目重构。 + +若是发现 AI 实现的用户登录系统不够正常,你可以直接将我们之前写好的 `Project5-Supabase-Demos/apps/project-burger-shop-auth-users-2` 的地址一同放入提示词,让 AI 基于项目直接实现用户登录系统。并检查是否已经正确设定了连接到 Supabase 的必要条件,防止因为 Supabase 配置错误而报错。 + +在代码修改过程中,若出现实际效果与预期不符的情况(如排行榜数据不显示、登录验证失效等),只需完整记录具体现象并反馈给 AI,即可逐步接近正确结果。改造成功的标准为:用户能顺利完成注册与登录操作,且登录后可正常查看对应的游戏排行榜单。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image46.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image47.png) + +### 📚 课程作业 + +1. 将用户管理系统集成到贪吃蛇游戏演示版中 +2. 将用户管理系统集成到你的应用程序中(如果之前已开发过一个应用程序) + +# 5. 成为 Supabase 大师 + +以上是 Supabase 的基本操作,接下来的旅程中我们将会接触 Supbase 的进阶原理和功能,你将理解为什么我们会选择 Supabase 作为教学案例,以及如何使用 Supbase 实现更高级的操作,协助你实现更复杂的交互功能,并且在学习这些功能后,即便面对 Supabase 之外的其他同类工具,你也能触类旁通,从更本质的层面理解后端服务的核心原理。当然,你并不需要在短时间内学会全部,也许只需要学会第三方登录支持已经足够,你可以先浏览下列内容,直到项目遇到对应的需求时再倒回来深入学习。 + +## 5.1 为什么我们选择 Supabase + +在开始进阶之前,我们再次思考这个问题:众多后端技术方案中,为何我们最终选择 Supabase 作为技术底座? + +初创团队在技术选型时普遍面临一个矛盾:既想完全掌控后端系统,又必须快速上线产品——而自建后端通常意味着要投入数月时间搭建数据库与实时同步、用户认证、API服务、文件存储、定时任务、监控Alertas等核心组件,除非团队成员已在对应领域积累了丰富的实战经验。在资金不足、市场窗口短暂的双重压力下,一旦陷入基础设施泥潭,极易导致迭代滞后、错失早期增长空间。 + +Supabase 将这些后端能力打包为开箱即用的服务(PostgreSQL数据库、实时订阅、身份认证、对象存储、边缘函数、自动生成API等),让初创团队得以将稀缺资源聚焦于核心功能开发,避免因底层建设拖慢上线速度——这已成为当前创投环境下务实的生存策略。当然,我们也可以使用别的一栈式后端产品进行开发,例如 PocketBase(轻量极简)和 Appwrite(跨平台适配)等方案,但综合功能完整性、SQL 生态成熟度及 Github 社区关注度,Supabase 更适合支撑业务的长期稳定运行。 + +在同类产品中,Supabase 的开源策略更具优势。 以市场占有率较高的 Firebase 为例:其闭源特性易导致平台绑定,迁移成本极高。Supabase 采用完全开源模式,支持私有化Despliegue,规避了供应商锁定风险,可根据需求切换至其其他竞品。 + +总而言之,技术选型需匹配业务规模与目标。 对于个人项目或极小范围测试,PocketBase 等超轻量方案已足够;若企业需对接复杂身份系统,或要满足上市公司合规审计要求,WorkOS 这类企业级全身份治理方案更为适用。但对于验证 MVP、承载早期用户的核心业务场景,Supabase 的完整功能完全够用,它不仅能独立支撑至少万级用户规模,更可灵活集成 Stripe(支付)、Resend(邮件)、Cloudflare(CDN)等第三方服务;即便未来业务扩展至企业级需求,Supabase 的开源架构也能与企业系统并行Despliegue,不同功能选择最适配的平台进行使用。这种渐进式灵活性,使初创团队无需过早投入重型基础设施,又能保留 future-proof 的演进空间。 + +## 5.2 Google 和 GitHub 登录支持 + +在前面的教程中,我们讲解了如何直接使用邮箱进行注册和登录,但在实际操作中我们通常想要简化注册流程,例如使用第三方登录 Google 和 GitHub 进行系统的快速注册与登录,我们将会在这节教程中展开每个细节;同时,一个完整的认证系统也必须提供安全可靠的密码重置功能,我们也会将密码重置功能集成在本节教程的项目中。 + +本项目 `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6`)完整地演示了如何实现这些高级功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image48.png) + +### 5.2.1 OAuth 流程:第三方登录是如何工作的? + +第三方登录的核心是 OAuth 2.0 开放授权协议,它的本质是 “授权代理”:允许用户授权我们的应用(汉堡店项目)访问其在第三方平台(如 Google)的公开信息(如邮箱、头像),但无需将第三方平台的密码暴露给我们的应用,从根本上规避了密码泄露风险。 + +完整流程可拆解为 5 个关键步骤,以 Google 登录为例: + +1. 用户发起授权请求:用户点击页面上的 “Sign in with Google” 按钮,我们的应用会自动将用户重定向到 Google 官方的授权页面(确保授权过程的安全性,避免钓鱼风险)。 +2. 用户完成第三方授权:用户在 Google 页面登录自己的账户(验证用户身份),并同意我们的应用请求的权限(如 “获取邮箱地址”)。 +3. Google 返回一次性授权码:授权通过后,Google 会将用户重定向回我们提前约定的 “回调 URL(Callback URL)”,并在 URL 参数中附带一个一次性、短期有效的授权码(而非直接返回用户信息,进一步提升安全性)。 +4. Supabase 交换访问令牌(Access Token):我们的后端(由 Supabase 托管,无需自建)会拿着这个授权码,向 Google 官方接口发起请求,换取可用于获取用户信息的 Access Token(授权码仅用于换 Token,避免 Token 直接在前端传输)。 +5. 创建账户并建立会话:Supabase 使用 Access Token 从 Google 拉取用户的公开信息(如邮箱、头像),并在我们的项目中为该用户自动创建账户(若首次登录)或直接关联现有账户,最终生成一个有效的用户会话(Session),完成登录。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image49.png) + +### 5.2.2 配置 Google Cloud 获取 Client ID 和 Secret + +无论是何种第三方登录方式,我们通常都需要获取 Client ID 与 Secret 进行配置;对于 Google 的第三方登录,你首先需要在 Google Cloud Platform 中创建一个 OAuth 2.0 客户端 ID 进行对应参数的获取。 + +1. **进入 Google Cloud Console** : +2. 访问 [Google Cloud Console](https://console.cloud.google.com/)。 +3. 创建一个新项目或选择一个现有项目。 +4. **配置 OAuth 同意屏幕 (OAuth consent screen)** : +5. 在左侧导航栏中,找到 “APIs & Services” -> “OAuth consent screen”。 +6. 选择 “External” 用户类型,然后点击 “Create”。 +7. 填写应用名称、用户支持电子邮件等必填信息。 +8. 在 “Authorized domains” 部分,添加你的 Supabase 项目域名,格式为 `*.supabase.co`。 +9. 保存并继续。在 “Scopes” 和 “Test users” 步骤中,你可以暂时跳过,直接保存。 +10. **创建凭据 (Create Credentials)** : +11. 进入 “APIs & Services” -> “Credentials”。 +12. 点击 “+ CREATE CREDENTIALS”,选择 “OAuth client ID”。 +13. 在 “Application type” 中选择 “Web application”。 +14. 为它取一个名字,例如 “Supabase Auth”。 +15. 在 “Authorized redirect URIs” 部分,点击 “ADD URI”,并填入你的 Supabase 项目的回调 URL。你可以在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “Google” 中找到这个 URL,它的格式通常是 `https://<你的项目ID>.supabase.co/auth/v1/callback`。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image50.png) +16. 点击 “CREATE”。 +17. **获取 Client ID 和 Client Secret** : +18. 创建成功后,一个弹窗会显示你的 **Client ID** 和 **Client Secret** 。请务必**立即复制并妥善保存** 它们。 + +### 5.2.3 配置 GitHub 获取 Client ID 和 Secret + +同样地,你也需要在 GitHub 上注册一个 OAuth 应用。 + +1. **进入 \*\***GitHub\*\* ** Developer Settings** : + 1. 登录你的 GitHub 账户。 + 2. 点击右上角的头像,进入 “Settings”。 + 3. 在左侧导航栏的底部,找到 “Developer settings”。 + +2. **注册新应用 (Register a new application)** : +3. 选择 “OAuth Apps”,然后点击 “New OAuth App”。 +4. 填写应用名称,例如 “My Burger Shop”。 +5. **Homepage URL** : 填写你应用的线上地址,或者本地开发地址 `http://localhost:3000`。 +6. **Authorization \*\***callback\*\* ** URL** : 填入你的 Supabase 项目的回调 URL。同样,你可以在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “GitHub” 中找到它,格式为 `https://<你的项目ID>.supabase.co/auth/v1/callback`。 +7. 点击 “Register application”。 +8. **获取 Client ID 和 Client Secret** : +9. 注册成功后,页面会显示你的 **Client ID** 。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image51.png) +10. 点击 “Generate a new client secret” 来生成你的 **Client Secret** 。同样,请**立即复制并保存** 它。 + +### 5.2.4 在 Supabase 中配置 Provider + +现在,将我们获取到的凭证配置到 Supabase 中。 + +1. **进入 Supabase Dashboard** : +2. 选择你的项目,进入 “Authentication” -> “Providers”。 +3. **启用并配置 Google** : +4. 找到 “Google” 并启用它。 +5. 将你从 Google Cloud 获取的 **Client ID** 和 **Client Secret** 粘贴到对应的输入框中。 +6. 点击 “Save”。 +7. **启用并配置 ** **GitHub** : + 1. 找到 “GitHub” 并启用它。 + 2. 将你从 GitHub 获取的 **Client ID** 和 **Client Secret** 粘贴到对应的输入框中。 + 3. 点击 “Save”。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image52.png) + +至此,你已经能够使用第三方账户在构建的网站中进行登录,你可以直接让 AI 基于 `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6`项目作为参考,在你的项目的基础上支持用户登录系统,以最小成本集成包含 github 与 google 鉴权的用户登录界面。 + +### 5.2.6 密码重置实现 + +作为一个成熟的用户登录组件,密码重置也是极其重要的一环,本项目 `project-burger-shop-auth-advanced-supabase-6`也包含了该功能的完整实现,你可以直接让 AI 基于本项目的密码重置功能复刻完整的密码重置组件。其主要分为以下几步: + +1. 发起请求 :用户在忘记密码页面输入邮箱,前端调用 `supabase.auth.resetPasswordForEmail()` 函数,并指定一个重定向 redirectTo URL(例如 /auth/reset )。 +2. 发送邮件 :Supabase 会向该邮箱发送一封包含唯一重置链接的邮件。 +3. 访问链接 :用户点击邮件中的链接,被重定向到应用内指定的重置页面。 +4. 更新密码 :在重置页面,用户输入新密码。前端调用 `supabase.auth.updateUser()` ,将新密码提交给 Supabase。Supabase 会自动验证链接的有效性并完成密码更新。 + +最后,如果你觉得当前的密码重置邮件过于简陋,你可以 在 Supabase Dashboard 的 Authentication -> Email Templates 中自定义“Reset Password”邮件模板。 + +除了 Reset password 功能外,你还能看到许多其他与用户管理相关的高级功能设定(例如 Invite user 等),你可根据对应功能各自的开发文档,结合 Vibe coding 工具自行添加对应功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image53.png) + +## 5.3 实时功能 + +Supabase 的实时功能是其最强大的特性之一,为构建协作文档、实时仪表盘、游戏大厅或客服系统提供了极大的便利。 + +本项目 `Project5-Supabase-Demos/apps/project-burger-shop-realtime-orders-3 `通过构建一个 多人实时聊天室、光标位置共享 功能,展示了 Supabase Realtime 涉及到的三大核心能力:数据库变更监听 (Postgres Changes)、广播 (Broadcast) 和 在线状态 (Presence)。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image54.png) + +Si sientes que la parte relevante del codigo tiene cierta dificultad, puedes pedir directamente a la IA que consulte el contenido de la documentacion de esa seccion y modifique tu programa. + +### 5.3.1 数据库实时变动 Postgres Changes + +最常见的 Realtime 功能是对数据库的变更进行实时监听 Postgres Changes 。它允许客户端订阅数据库中特定表、特定行甚至特定列的 INSERT 、 UPDATE 或 DELETE 事件。一旦数据库发生变动(无论是通过 API 调用、Supabase Dashboard 操作,还是 SQL 脚本执行),Supabase 都会利用 PostgreSQL 的底层复制机制,立即通过 WebSocket 将变更的数据推送到所有订阅了该频道的前端客户端,而无需前端通过轮询(Polling)去反复查询。 + +一般而言,该功能可以在 Table Editor 中找到 Enable Realtime 点击后启动, 但更方便的是通过 SQL 脚本初始化执行,例如: + +```sql +-- Enable realtime replication +ALTER TABLE public.chat_messages REPLICA IDENTITY FULL; +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_publication_tables + WHERE pubname = 'supabase_realtime' + AND schemaname = 'public' + AND tablename = 'chat_messages' + ) THEN + ALTER PUBLICATION supabase_realtime ADD TABLE public.chat_messages; + END IF; +END $$; +``` + +该语句将 `chat_messages` 表添加到了 Supabase 预设的 `supabase_realtime` 中,而一旦一个表被加入到这个特殊的 `publication` 中,Supabase 的实时服务器就会开始监听它的所有数据变更。 + +基于上面的特殊数据表,我们能够使用监听代码对表内数据变动进行实时监听。我们需要实现的是当一个用户发送消息时,其他所有在线用户都能立刻在屏幕上看到这条消息。通过订阅 chat_messages 表的 INSERT 事件能够实现这一点。 + +```typescript + const sub = supabase + .channel('chat_messages_channel') + .on('postgres_changes', { + event: 'INSERT', + schema: 'public', + table: 'chat_messages' + }, (payload: any) => { + console.log('New message received:', payload.new); + const newMessage = payload.new as Message; + // ... // + .subscribe((status: string) => { + console.log('Chat subscription status:', status); + }); +``` + +- `.channel('chat_messages_channel')`: 创建一个隔离的通信频道。 +- `.on('postgres_changes', ...)`: 这是核心的订阅方法。我们告诉 Supabase 我们只关心 `chat_messages` 表的 `INSERT` 事件。 +- `payload.new`: 当有新消息被插入数据库时,Supabase 会将这条新数据的完整内容通过 `payload.new` 推送给所有订阅的客户端。 +- `.subscribe()`: 启动订阅。 + +### 5.3.2 信息广播同步 Broadcast & Presence + +对于那些不需要存入数据库的、更“即时”的交互,比如光标移动、在线状态等,Supabase 提供了 Broadcast 和 Presence 功能。 + +- Presence: 用于跟踪频道内所有客户端的 **共享状态** 。适合用来实现“谁在线”的功能。 +- Broadcast: 用于向频道内的所有其他客户端发送**低延迟**的 **临时消息** 。 + +Presence 的核心思想是: 让每个客户端声明自己的在线状态,并由 Supabase 的服务器负责将这些状态可靠地同步给频道内的所有其他客户端。实现 Presence 分为以下几个关键步骤: + +1. 创建一个支持 Presence 的频道 + +首先,我们创建了一个频道 `lobby_presence` 来专门处理这些交互,并在配置中指定一个唯一的 key 来标识当前用户。这个 key 通常是用户的 ID。 + +``` +const ch = supabase.channel +('lobby_presence', { +  config: { +    presence: { key: anonymousUser.id }, +  } +}); +``` + +2. 订阅频道宣告“我在线”的信息 + +一旦频道创建成功,我们需要订阅它。在订阅成功的回调( status === 'SUBSCRIBED' )中,我们调用 channel.track() 方法。这个方法会将当前用户的信息(例如用户ID、名称、头像颜色等)广播给频道内的所有其他客户端,宣告自己的“在线”状态。 + +``` +const me = { +  id: anonymousUser.id, +  name: anonymousUser.name, +  color: anonymousUser.color +}; + +ch.subscribe(async (status) => { +  if (status === 'SUBSCRIBED') { +    await ch.track(me); +  } +}); +``` + +3. 同步完整的在线列表 + +当一个新用户加入频道时,他们需要获取当前所有已经在线的用户列表。这通过监听 presence 的 sync 事件来实现。 sync 事件会在你首次加入频道时触发,为你提供一个完整的“快照”。 + +channel.presenceState() 方法会返回一个对象,包含了当前频道内所有在线用户的状态信息。我们将其处理后更新到应用的 state 中,从而渲染出完整的在线用户列表。 + +``` +ch.on('presence', { event: 'sync' }, ()  +=> { +  const state = ch.presenceState(); +  const flat = {}; +  Object.values(state).forEach((arr) => { +    arr.forEach((u) => { flat[u.id] =  +    { ...u }; }); +  }); +  setOnline(flat); +}); +``` + +4. 监听单个用户的加入与离开 + +除了 sync 事件,我们还可以监听 join 和 leave 事件,以便在有新用户进入或离开时做出即时响应,例如显示一个 "User has joined" 的通知。 + +``` +ch.on('presence', { event: 'join' }, ({  +key, newPresences }) => { +  console.log('User joined:', key,  +  newPresences); +}); + +ch.on('presence', { event: 'leave' }, ({  +key, leftPresences }) => { +  console.log('User left:', key,  +  leftPresences); +}); +``` + +通过以上步骤,我们便构建了一个功能完备的在线状态系统。Supabase 自动处理了用户意外断开连接(如关闭浏览器或断网)的情况,并在适当的时候触发 leave 事件,确保了在线列表的准确性。 + +当 Presence 让我们知道了“谁在场”之后, Broadcast 能够让他们之间能够进行“对话”,但对话的内容是短暂存储的。一个典型的例子就是实时光标追踪。如果每次鼠标移动都去读写数据库,会造成巨大的性能浪费和延迟。 Broadcast 完美地解决了这个问题,它允许消息在各个客户端之间直接通过 WebSocket 传递,完全绕过数据库。 + +Broadcast 的工作模式主要依赖两个核心方法: channel.send() 用于发送,channel.on() 用于接收。】 + +1. 发送端:广播我的光标位置 + +我们为 mousemove 事件添加了一个监听器。当鼠标移动时,我们构造一个包含用户 ID、坐标和颜色的 payload,然后通过 channel.send() 将其广播出去,并指定事件名称为 'cursor'。 + +```typescript +const handleMouseMove = (e) => { + const payload = { + id: anonymousUser.id, + x: e.clientX, + y: e.clientY, + name: anonymousUser.name, + color: anonymousUser.color + }; + + channelRef.current?.send({ + type: 'broadcast', + event: 'cursor', + payload + }); +}; + +document.addEventListener('mousemove', handleMouseMove); +``` + +2. 接收端:监听并渲染他人的光标 + +在同一个频道内,所有客户端都使用 channel.on() 来监听 broadcast 类型的、且 event 为 'cursor' 的消息。一旦收到匹配的消息,回调函数就会被触发。我们从 payload 中解析出发送方的数据,并用它来更新本地的 online 状态,从而在屏幕上实时渲染出其他用户光标的位置。 + +```typescript +ch.on('broadcast', { event: 'cursor' }, ({ payload }) => { + setOnline((prev) => ({ + ...prev, + [payload.id]: { + ...(prev[payload.id] || {}), + x: payload.x, + y: payload.y + } + })); +}); +``` + +通过这种方式, Presence 和 Broadcast 协同工作;Presence 维护在线用户列表,而 Broadcast 则负责在这些用户之间传递像光标位置这样的临时状态,最终以较低的成本实现了丰富的实时互动功能。 + +## 5.4 存储 + +除了用户信息、订单这类可规整定义的结构化数据,一个完整的应用通常还需要处理大量非结构化文件 —— 例如用户头像、商品展示图、用户上传的订单文档等。这类文件的特点是体积差异大、数量可能极多(比如电商平台的商品图可能达数万甚至数十万张),若直接存储在应用自身的业务服务器中,会显著增加服务器的存储负载,还可能拖慢数据读写速度,影响应用整体性能。 + +实际开发中,这类非结构化文件会统一交由 “对象存储服务” 管理,OSS、Amazon S3 均属于这类服务,它们是专门为海量文件存储设计的 “专业存储工具”,能高效应对文件的存储、备份与快速读取需求。而我们在应用中获取这些文件时,并不会直接从对象存储服务的 “底层仓库” 调取,而是通过 URL 地址实现:每个存储在对象存储中的文件,都会被分配一个唯一的 URL(类似 “[https://xxx.oss.com/avatar/user123.jpg](https://xxx.oss.com/avatar/user123.jpg)” 的地址,可简单理解为这个“网站”只有一张图片),这个 URL 就像文件的 “专属访问地址”,前端页面只需通过该地址,就能直接下载或加载头像、商品图,无需依赖应用业务服务器中转,既提升了文件加载速度,也减轻了业务服务器的压力。 + +本项目 `project-burger-shop-storage-uploads-4` 便通过一个用户头像上传功能,深入演示了如何利用 Supabase Storage 构建现代化的文件上传系统,让开发者直观理解非结构化文件从上传到通过 URL 访问的完整流程。此外,本项目使用 `Uppy` 库来提供一个优秀的文件上传界面,并结合 `Tus` 插件实现了可续传上传,通过将 Uppy 的上传端点指向 Supabase 的标准 API (`/storage/v1/upload/resumable`) 进行工作,你可以参考类似的方式实现上传功能组件。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image55.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image56.png) + +### 5.4.1. 存储桶 + +Supabase Storage 的组成单元是存储桶 Bucket。你可以把它想象成电脑操作系统中的文件夹。每个 Bucket 都可以有自己独立的安全策略和配置。 + +Storage 内的所有文件都可以通过一个公开的 URL 直接访问,但并不意味着任何人都可以随意上传或修改,具体的访问权限将由更精细的策略来控制。和数据库一样,Storage 的访问权限也是通过行级安全策略来管理的。SQL 策略写在 storage.objects 和 storage.buckets 这两张特殊表上,可以精确定义谁能读取 (SELECT)、上传 (INSERT)、更新 (UPDATE) 或删除 (DELETE) 文件。 + +例如,我们可以创建一条策略,只允许用户上传到以自己 user_id 命名的文件夹下,并且只能上传图片类型的文件: + +``` +CREATE POLICY "Allow authenticated  +uploads to avatars bucket" +ON storage.objects FOR INSERT +TO authenticated +WITH CHECK ( +  bucket_id = 'avatars' AND +  auth.uid() = (storage.foldername(name)) +  [1]::uuid AND +  (storage.extension(name) IN ('png',  +  'jpg', 'jpeg')) +); + +CREATE POLICY "Allow public read access  +to avatars" +ON storage.objects FOR SELECT +USING ( bucket_id = 'avatars' ); +``` + +### 5.4.2 获取可访问文件 URL + +本项目需要你手动创建一个名为 avatars 的公共桶,所有文件将上传至该公共桶下进行存储。文件上传成功后,我们只得到了它在 Storage 中的存储路径 ,例如 public/avatar1.png 。这只是存储在数据库中的一个字符串,要让浏览器能够渲染这张图片,我们需要将其转换为一个可访问的 HTTP URL。 + +Supabase 提供了两种截然不同的策略来获取这个 URL,它们在安全性、持久性和成本控制上有着本质的区别。 + +#### 1. 公开 URL (Public URL) - 永久链接 + +这是最直接的方式。如果你的文件存放在一个**Public Bucket** 中,你可以获取一个固定、永久的公开链接。 + +```typescript +const { data } = supabase.storage + .from('avatars') + .getPublicUrl('public/avatar1.png'); +const publicUrl = data.publicUrl; +``` + +这类链接具有两大核心特点:一是简单直接,其 URL 结构固定,在实际操作中易于拼接和管理,降低了技术使用门槛;二是利于缓存,作为永久链接,它能被 CDN(内容分发网络)和浏览器有效缓存,从而大幅提升资源的访问速度,优化用户体验。基于这些特点,它适用于真正意义上的公共资源场景,例如网站 Logo、产品目录图片、博客文章配图等,能很好地满足这类资源的访问和管理需求。 + +不过在生产环境中,这类链接存在明显的被盗刷流量(Hotlinking)风险。由于链接是永久公开的,外部人员可以轻易将你的图片链接嵌入到他们自己的高流量网站中,导致流量被非法占用。这一行为会让你的 Supabase 项目产生大量不必要的流量费用,而这些消耗的流量并未服务于你自身的应用,属于典型的成本浪费,是生产环境中需要高度警惕和防范的问题;因此,我们需要转向临时签名 URL 实现对外资源的暴露。 + +#### 2. 签名 URL (Signed URL) - 临时授权链接 + +为了解决公开 URL 的安全和成本问题,Supabase 提供了生成临时签名 URL 的方式。这是绝大多数线上应用推荐的最佳实践,比如文生图应用给用户生成限时查看的图片链接、电商平台仅让下单用户获取临时发票下载地址、付费内容平台为订阅用户提供短期有效的课程播放链接,既防文件盗用又能避免流量盗刷,适配性极强。 + +```typescript +const { data, error } = await supabase.storage + .from('avatars') + .createSignedUrl('private/user-invoice.pdf', 3600); // 链接有效期为 3600 秒 (1小时) +const signedUrl = data?.signedUrl; +``` + +临时签名 URL(Signed URL)有三大核心优势:安全可控是指链接带安全标记、有有效期,过期就用不了;权限绑定很简单 —— 只有能看这文件的人,才能生成这个链接,就算文件藏在私有存储里(Private Bucket),他用这个链接也能正常打开;杜绝盗刷是因为链接是临时的,复制到别处很快就失效,不会被恶意刷流量。靠这些优势,像用户头像、私人照片、付费内容、订单发票这些需要管权限的文件,都能用它。 + +从安全保障和成本控制的角度,建议养成优先使用临时签名 URL 的习惯。只有当某个资源明确需要永久公开、无限制访问(比如应用的公开 Logo、公共活动宣传图等)时,才考虑使用 Public URL。这样既能满足特定业务需求,又能最大程度规避不必要的风险和成本消耗。 + +## 5.5 边缘函数 + +Edge Function 是 Serverless(无服务器架构)生态中极具核心价值的形态之一,它为 “无自建后端” 场景提供了轻量、高效的函数运行支持。 + +什么是 Serverless? Serverless(无服务器架构)并不意味着真的没有服务器,而是指开发者无需关心服务器的购买、运维、配置和扩容 。你只需要编写业务代码(函数),云服务商会在特定事件触发时自动为你分配资源运行代码,并按实际运行时间计费。 + +当你的应用需要执行一些不能或不应在客户端(浏览器)上完成的逻辑时——例如与需要私密密钥的第三方 API 交互、执行计算密集型任务、或强制执行复杂的业务规则——Edge Functions 就派上了用场。Supabase Edge Functions 基于 Deno 和 TypeScript,它们被Despliegue在全球的边缘节点上,物理距离上靠近你的用户,从而提供极低的函数执行延迟。 + +目前主流云厂商都推出了各自的 Edge Function 服务,常见的包括: + +- AWS Lambda@Edge:基于 AWS Lambda 延伸的边缘函数服务,可与 CloudFront CDN 联动,支持 Node.js、Python 等语言; +- Cloudflare Workers:Cloudflare 推出的边缘函数,Despliegue在其全球 275+ 边缘节点,支持 JavaScript/TypeScript,以 “毫秒级延迟” 为核心优势; +- Vercel Edge Functions:适配 Vercel 前端项目的边缘函数,与 Next.js 深度集成,支持 TypeScript,主打 “前端与边缘逻辑无缝衔接”; + +回到 Supabase ,当你的应用需要执行 “不能在客户端(浏览器)完成” 的逻辑时,比如用私密密钥调用第三方 API(如 LLM 接口)、处理计算密集型任务(如图片压缩)、或强制执行权限校验(如文件访问规则)时,Supabase Edge Functions 就能发挥作用。它基于 Deno runtime 和 TypeScript 构建,Despliegue在全球边缘节点上,能以 “靠近用户的物理距离” 实现极低的执行延迟,是编写自定义、可信服务器端逻辑的核心工具。 + +本项目 `Project5-Supabase-Demos/apps/project-burger-shop-edge-function-5`通过一个与大语言模型(LLM)实时流式对话的功能,展示了 Edge Functions 的最简应用流程。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image57.png) + +### 5.5.1 LLM Chat 案例解析 + +假设你想在应用中集成一个类似 ChatGPT 的聊天机器人。你需要在服务器端调用 OpenAI 的 API,但这需要一个私密的 API Key。 这个 Key 绝对不能暴露在前端代码中 ,否则任何人都可以通过查看网页源码盗用你的 Key,产生高昂的费用。这正是 Edge Function 的用武之地。我们将创建一个名为 llm-chat 的函数,它充当了前端和 OpenAI API 之间的一个 安全代理 。 + +参考 `project-burger-shop-edge-function-5/scripts/llm-chat.ts`的代码,我们来看看它是如何工作的: + +```typescript +// scripts/llm-chat.ts +import "jsr:@supabase/functions-js/edge-runtime.d.ts"; +import { OpenAI } from "npm:openai"; + +const OPENAI_API_KEY = Deno.env.get("OPENAI_API_KEY"); + +Deno.serve(async (req) => { + try { + const openai = new OpenAI({ apiKey: OPENAI_API_KEY }); + const { prompt } = await req.json(); + + const stream = await openai.chat.completions.create({ + model: "gpt-3.5-turbo", + messages: [{ role: "user", content: prompt }], + stream: true, + }); + + return new Response(stream.toReadableStream(), { + headers: { "Content-Type": "text/event-stream" }, + }); + } catch (err) { + } +}); +``` + +在该案例中,对于密钥安全,OPENAI_API_KEY 作为环境变量被安全存储于 Supabase 的服务器。本地前端代码完全无法接触到该密钥,从而有效保障了密钥的安全性。 + +### 5.5.2 创建并Despliegue函数 + +Supabase 提供了非常友好的界面,让你无需接触命令行即可完成Despliegue。 + +1. **进入 Edge Functions 面板** : +2. 登录你的 Supabase 项目 Dashboard。 +3. 在左侧导航栏中,点击像代码一样的图标,进入 “Edge Functions”。 +4. **创建新函数** : +5. 点击 “Create a new function” 按钮。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image58.png) +6. 为函数命名,例如 `llm-chat`。 +7. **粘贴代码** : + ![](/zh-cn/stage-2/backend/database-supabase/images/image59.png) +8. 在弹出的在线编辑器中, **删除所有默认的占位代码** 。 +9. 打开你本地的 `llm-chat.ts` 文件, **复制其全部内容** 。 +10. 将复制的代码**粘贴**到 Supabase 的在线编辑器中。 +11. **配置\*\***环境变量\*\* ** (Secrets)** : + 1. 在侧边栏找到 Secrets。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image60.png) + 2. Name: 输入 `OPENAI_API_KEY`。 + 3. Value: 粘贴你自己的 OpenAI API Key。 + 4. 点击 “Save”。在这里设置的 Secret 会被加密存储,并安全地注入到你的函数运行时环境中。 + +若有函数需要更新,记得在 Edge Function 部分执行 Deploy updates。Supabase 会在云端为你构建并Despliegue这个函数。几分钟后,你的函数就可以在线访问。 + +除了作为语言模型的安全代理,Edge Functions 的应用场景远不止于此。实际上,任何需要服务器端逻辑处理的任务,无论是简单的 API 调用、数据验证,还是更复杂的计算,都可以通过 Edge Function 实现。它为你提供了一个轻量级、可扩展的后端,而无需管理任何服务器基础设施。 + +如果你想探索更多可能性,可以参考项目中的其他示例。例如: + +- 图片生成 ( txt2img.ts ) : 这个函数展示了如何利用 Edge Function 调用第三方的文生图(Text-to-Image)API(如 Stability AI, Midjourney 等)来动态生成图片。这是一种典型的计算密集型或需要安全调用外部服务的场景。与 llm-chat 案例一样,API 密钥被安全地存储在 Supabase 后端,前端只负责发送文本描述,然后接收并展示生成的图片,整个过程安全、高效。 +- 发送邮件 ( send-email.ts ) : 在应用中发送欢迎邮件、交易通知或密码重置邮件是常见需求。 send-email.ts 示例演示了如何通过 Edge Function 集成邮件服务(如 Resend, SendGrid)。你无需在客户端代码中暴露敏感的邮件服务 API Key,只需创建一个函数,让前端通过调用这个函数来触发邮件发送。 + +## 5.6 Clerk 登录 + +Clerk 是一款专注于身份认证与用户管理的专业开发工具,核心能力覆盖用户注册、登录、账号安全MFA、Control de permisos、会话管理等全链路身份认证相关需求,能帮助开发者快速搭建安全、灵活且符合现代应用标准的用户体系,无需从零开发复杂的身份逻辑。 + +本部分将介绍如何从零开始配置 Clerk 服务,并将其与 Supabase 进行整合。你可以在项目 `project-burger-shop-auth-advanced-clerk-7` 中体验全流程。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image61.png) + +### 5.6.1 创建 Clerk 应用与获取密钥 + +在使用本项目之前,你需要拥有一个 Clerk 账号并创建一个应用。 + +1. 注册与创建: + 1. 访问 [dashboard.clerk.com](https://dashboard.clerk.com/) 并注册账号。 + 2. 点击 "Create application" 。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image62.png) + 3. 输入应用名称(例如 "Burger Shop")。 + 4. 在 "How will your users sign in?" 中,默认勾选 Email , Google , GitHub 。 + 5. 点击 Create application 。 +2. 获取 API Keys: + 1. 创建成功后,你会被引导至 API Keys 页面。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image63.png) + 2. 找到 Publishable key (以 `pk_` 开头) 和 Secret key (以 `sk_` 开头)。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image64.png) + 3. 将它们复制到你的 `.env.local` 文件中(参考本项目 `.env.example`): + + ```bash + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... + CLERK_SECRET_KEY=sk_test_... + ``` + +### 5.6.2 配置 Supabase 和 Clerk 的原生集成 + +在进一步使用前,我们需要集成 Supabase 与 Clerk 的关联关系,方便之后登录的鉴权跳转以及控制对特定数据库的访问权限。Supabase 与 Clerk 提供官方原生集成能力,通过该集成可快速实现两者的身份认证打通,无需手动配置复杂的适配逻辑,大幅简化用户登录、权限校验等功能的开发流程: + +1. 在 Clerk 中激活对 Supab ase 的官方集成 + 1. 登录 [Clerk Dashboard](https://dashboard.clerk.com/)。 + 2. 在左侧菜单导航至 Integrations (集成)。 + 3. 在列表中找到并点击 Supabase。 + 4. 开启 Enable Supabase 开关(或点击 Activate integration)。 + 5. 关键步骤:激活成功后,页面会显示你的 Clerk Domain(格式通常为 `https://.clerk.accounts.dev` 或你的自定义域名)。请复制这个 Domain 地址,下一步会用到。 +2. 在 Supabase 中添加 Clerk 提供商 + 1. 登录 [Supabase Dashboard](https://supabase.com/dashboard) 并进入你的项目。 + 2. 在左侧菜单导航至 Authentication > Sign In / Up (或者直接点击 Providers)。 + 3. 点击 Add provider 按钮,从下拉列表中选择 Clerk。 + 4. 在弹出的 Clerk Domain 输入框中,粘贴你刚才从 Clerk 复制的 Domain 地址。 + 5. 点击 Save 保存配置。 + +### 5.6.3 通过 Webhook 同步用户数据至 Supabase + +仅仅是集成只满足了鉴定权限的需求,但这并不会将 Clerk 中已经注册的用户信息同步到 Supabase,为了方便管理,我们还需要在 Supabase 的 `public.users` 表中保留一份用户备份,以便进行关联查询或数据分析。我们可以通过 Clerk Webhooks 实现这一功能,完整过程如下: + +1. **Clerk 发送通知** : 当用户在 Clerk 注册或更新资料时,Clerk 会向我们配置的 Webhook URL 发送一个 POST 请求。 +2. **Supabase 接收并写入** : Edge Function 接收请求,验证签名(确保安全),然后将用户数据更新到 Supabase 的数据库表中。 + +在开始之前,我们需要配置同步信息所需的数据表: + +```sql +-- File: init.sql + +-- 1. Create `users` table for synced Clerk users +-- This table will store user data pushed from Clerk Webhooks. +CREATE TABLE public.users ( + id TEXT NOT NULL PRIMARY KEY, -- Corresponds to Clerk User ID + email TEXT, + first_name TEXT, + last_name TEXT, + image_url TEXT, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- 2. Enable Row Level Security (RLS) on the table +-- This is an important security measure to ensure users cannot access any data by default. +ALTER TABLE public.users ENABLE ROW LEVEL SECURITY; + +-- 3. Create RLS policies +-- Policy 1: Allow authenticated users to read their own user info. +-- `auth.jwt()->>'sub'` extracts the user ID from the JWT provided by Clerk. +CREATE POLICY "Authenticated users can view their own user record" +ON public.users FOR SELECT +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); + +-- Policy 2: Allow users to update their own info. +CREATE POLICY "Authenticated users can update their own user record" +ON public.users FOR UPDATE +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); +``` + +以及在 Supabase 中启用对应的 Edge function: + +```JavaScript +// File path: supabase/functions/clerk-webhooks/index.ts + +import { serve } from 'https://deno.land/std@0.177.0/http/server.ts' +import { Webhook } from 'npm:svix' +import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' + +// Get Clerk Webhook signing secret from environment variables +const CLERK_WEBHOOK_SECRET = Deno.env.get('CLERK_WEBHOOK_SECRET') + +if (!CLERK_WEBHOOK_SECRET) { + throw new Error('CLERK_WEBHOOK_SECRET is not set in environment variables') +} +const supabaseAdmin = createClient( + Deno.env.get('SUPABASE_URL')!, + Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')! +) + +serve(async (req) => { + try { + // 1. Get Svix signature info from request headers + const headers = Object.fromEntries(req.headers) + const svix_id = headers['svix-id'] + const svix_timestamp = headers['svix-timestamp'] + const svix_signature = headers['svix-signature'] + + if (!svix_id || !svix_timestamp || !svix_signature) { + return new Response('Missing Svix headers', { status: 400 }) + } + + const payload = await req.json() + const body = JSON.stringify(payload) + + // 2. Verify Webhook signature validity using the secret + const wh = new Webhook(CLERK_WEBHOOK_SECRET) + const evt = wh.verify(body, { + 'svix-id': svix_id, + 'svix-timestamp': svix_timestamp, + 'svix-signature': svix_signature, + }) + + const { id } = evt.data + const eventType = evt.type + console.log(`Received webhook event: ${eventType} for user: ${id}`) + + // 3. Execute database operations based on event type + switch (eventType) { + case 'user.created': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin.from('users').insert({ + id, + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + }) + if (error) throw error + console.log(`User ${id} created in Supabase.`) + break + } + + case 'user.updated': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin + .from('users') + .update({ + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + updated_at: new Date().toISOString(), // Update timestamp + }) + .eq('id', id) + if (error) throw error + console.log(`User ${id} updated in Supabase.`) + break + } + + case 'user.deleted': { + // For delete events, ID might be at the top level + const deletedId = id + if (!deletedId) { + return new Response('Deleted user ID not found', { status: 400 }) + } + const { error } = await supabaseAdmin.from('users').delete().eq('id', deletedId) + if (error) throw error + console.log(`User ${deletedId} deleted from Supabase.`) + break + } + } + + return new Response('Webhook processed successfully', { status: 200 }) + } catch (err) { + console.error('Error processing webhook:', err.message) + return new Response(`Webhook Error: ${err.message}`, { status: 400 }) + } +}) +``` + +初始化 Supabase 数据表与函数结束后,你还需要在 Clerk 中启用 Webhooks 支持: + +- 在 Clerk Dashboard -> **Webhooks** 中添加 Endpoint,填入Supabase Edge Function 的 URL。 +- 勾选 `user.created`, `user.updated`, `user.deleted` 等事件。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image65.png) + +一旦设置成功,你能够在 Message Attempts 中看到不同请求信息,点击后可看到详细的请求返回参数结果;如果 webhook 在请求 Edge function 时出现问题,你可以快速在返回值中找到详细原因结果。推荐你同时对照 Clerk 和 Supabase 的请求日志信息,用于分析各个函数设定是否正确。 + +### 5.6.4 Clerk 中的第三方登录支持 + +在深入了解如何对 Clerk 支持第三方登录前,我们先明确两个核心概念:开发环境与生产环境,这是软件从 “开发测试” 到 “上线可用” 的两个关键阶段,二者的定位、用途和安全要求截然不同: + +- 开发环境:开发者本地或测试服务器使用的环境,仅用于功能开发、调试和内部验证(如本地 localhost:3000 服务),不对外开放 +- 生产环境:应用正式上线后,面向真实用户的公开环境(如Despliegue在 Vercel、阿里云等平台的 https://my-app.com) + +而 Clerk 对社交登录区分这两种环境,本质是平衡 “开发效率” 与 “生产安全”:开发阶段需减少冗余配置以快速验证功能,生产阶段需通过专属凭证保障数据安全,同时符合 Google、GitHub 等第三方 OAuth 平台的规则(线上应用必须绑定专属域名与凭证,不允许使用共享资源)。下面具体说明两种环境下 Clerk 社交登录的差异配置: + +1. **开发环境快速验证** + +开发环境中,Clerk 已预置共享 OAuth 凭证和默认重定向 URI,无需前往 GitHub/Google 申请专属凭证,操作步骤如下: + +- 登录 Clerk Dashboard ,在左侧导航栏进入 SSO connections (SSO 连接)页面。 +- 点击 Add connection (添加连接),选择 For all users (对所有用户生效)。 +- 在 Choose provider (选择提供商)下拉菜单中,按需选择 GitHub 或 Google 。 +- 直接点击 Add connection (添加连接),Clerk 会自动用共享凭证完成绑定。 + + 配置后,本地启动应用(如 `localhost:3000`)并点击“Sign in with GitHub/Google”,Clerk 会自动代理登录请求,快速验证功能是否正常。 + +2. **生产环境自定义凭证配置** + +(注:如果发现有环节和预期不一致,建议阅读官方文档进行最新方式的尝试) + +应用Despliegue上线(如 Vercel、阿里云)并切换到 Clerk Production Instance 后,共享凭证失效,需为 GitHub/Google 配置自定义 OAuth 凭证(建议同时打开 Clerk Dashboard 和第三方平台页面,方便同步操作): + +- 前置通用操作(Clerk 控制台): + - 进入 Clerk SSO connections 页面,点击 Add connection → 选择 For all users 。 + - 选择目标平台(GitHub/Google),确保开启 Enable for sign-up and sign-in (允许注册登录)和 Use custom credentials (使用自定义凭证)。 + - 复制页面中的 Authorization Callback URL (GitHub)或 Authorized Redirect URI (Google),保存到安全位置,不要关闭当前页面/弹窗。 +- 2.1 GitHub 平台配置: + - 登录 GitHub,进入 Developer Settings (路径:头像 → Settings → Developer settings → OAuth Apps)。 + - 点击 New OAuth app ,填写信息:`Application name`(应用名称)、`Homepage URL`(生产域名,如 `https://my-app.com`)、`Authorization Callback URL`(粘贴从 Clerk 复制的地址)。 + - 点击 Register application ,再点击 Generate a new client secret ,保存生成的 Client ID 和 Client Secret (Secret 仅显示一次)。 + - 回到 Clerk 弹窗,粘贴 Client ID 和 Client Secret,点击 Add connection 完成配置(若关闭弹窗,可在 SSO connections 找到 GitHub 连接,在“Use custom credentials”模块补填)。 +- 2.2 Google 平台配置: + - 登录 Google Cloud Console ,选择已有项目或新建项目(如“My App Production”)。 + - 点击左上角菜单 → APIs & Services → Credentials ,点击 Create Credentials → OAuth client ID (首次配置需先完成 OAuth consent screen 设置,选择“External”并填写应用信息)。 + - 选择 Application type 为 Web application ,配置: + 1. `Authorized JavaScript origins`:添加生产域名(如 `https://my-app.com`、`https://www.my-app.com`),本地验证可补充 `http://localhost:端口号`。 + 2. `Authorized Redirect URIs`:粘贴从 Clerk 复制的地址。 + - 点击 Create ,保存弹窗中的 Client ID 和 Client Secret ,回到 Clerk 弹窗粘贴并点击 Add connection 。 + - 关键注意事项: + 1. 禁止 WebView 登录:Google OAuth 不支持应用内浏览器登录,需参考 [Google 官方文档](https://support.google.com/cloud/answer/7657789) 调整。 + 2. 切换发布状态:默认“Testing”状态仅支持 100 个测试用户,需在 OAuth consent screen 将“Publishing status”改为 In production (需通过 Google 审核)。 + 3. 阻止子邮箱:Clerk 默认拦截含 `+`/`=`/`#` 的 Google 邮箱(如 `user+alias@example.com`),可在 Google 连接详情页开启/关闭 Block email subaddresses (建议开启提升安全性)。 + 4. 支持 Google One Tap:配置完成后,可集成 Clerk `` 组件实现“一键登录”,参考 [Clerk 组件文档](https://clerk.com/docs/components/social-connections/google-one-tap)。 + +3. 测试第三方登录连接 + +配置完成后,通过 Clerk 内置 Account Portal 验证功能: + +- 进入 Clerk Dashboard,左侧导航栏进入 Account Portal 页面。 +- 在“Sign-in”模块右侧,点击“访问登录页面”按钮,跳转至对应环境登录页: + - 开发环境:`https://你的域名.accounts.dev/sign-in`(如 `https://my-app.accounts.dev/sign-in`)。 + - 生产环境:`https://accounts.你的域名.com/sign-in`(如 `https://accounts.my-app.com/sign-in`)。 +- 点击“Sign in with GitHub/Google”,用对应平台账号登录,若能成功跳转并返回应用,说明连接配置正常。 + +# 6. 从 Supabase 到更多Desarrollo backend组件(进阶) + +在上文中,我们主要是站在 Supabase 的视角,去看“一个以 Postgres 为核心的一站式后端平台”能帮我们解决哪些问题:认证、数据库、文件存储、实时通信、边缘函数等,都被集成在同一个控制台里,开箱即用、体验统一,非常适合快速起步和中小型项目。 + +但从更长期、更工程化的角度来看, **Supabase 提供的每一块能力(Auth / Storage / Edge Functions / Realtime / Database),在业界几乎都有对应的专业替代方案** ——既包括同类 BaaS 平台,也包括更“单点突破”的云服务和开源组件。作为上进的个人开发者和初创团队来说,了解这些替代选项有几个好处: + +- 判断当前项目是否“全用 Supabase 就够了”,还是某一块需要更专业/更便宜/更易合规的专用服务; +- 当项目规模变大或需求变复杂时,是否可以把某个模块从 Supabase 替换出去(例如改用专门的 Auth 平台或对象存储),而不是一开始就被平台彻底锁死; +- 拓宽技术选型视野,即使暂时不更换,也能大致知道“如果不用 Supabase 的 X 功能,我还有哪些常见选择”。 + +本节将分别介绍 Supabase 所覆盖的几大能力在市场上的主流替代方案,例如:认证(Auth)、文件存储(Storage)、边缘函数(Edge Functions)、实时通信(Realtime)、数据库托管等。简单对比它们在功能特性、免费额度/定价、易用性以及社区流行度等方面的差异, 让你对后端组件工具库有更全面的理解。 + +## 同类 Baas 平台 + +在开始之前,我们可以浏览同类的 Baas 平台,若觉得 Supabase 不够好用,你可以根据需求选择不同替代品进行尝试。 + +| 平台/服务 | 类型 | 免费额度/定价 | 特点 / 适用场景 | +| ------------------------ | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| Firebase(Google) | 全托管 BaaS(Auth + Firestore + Storage + Functions + Hosting) | Spark:免费轻量额度;Blaze:按量计费(Firestore/Storage/Functions 分别算) | 行业最成熟、文档好、上手快、实时能力强。适用于中小型产品、移动/前端主导团队。缺点:计费复杂、锁定性强、查询限制多(尤其 Firestore)。 | +| Supabase | 开源 BaaS(Postgres + Auth + Storage + Edge Functions + Realtime) | 免费:500MB DB、1GB Storage、无服务器函数少量调用;Pro:按实例计费 | 最像 Firebase 的 SQL 版;界面优秀、体验现代、可自托管。适用于需要强 SQL、BI、事务能力的应用。缺点:高并发或复杂函数成本较高。 | +| Appwrite Cloud | 开源一站式 BaaS(DB + Auth + Storage + Functions + Realtime) | 免费:包含基本 DB/Storage/FaaS;付费按资源级别计费 | 体验现代化、API 统一、可自托管;适合开发者友好的应用快速迭代。缺点:生态还不如 Firebase/Supabase 成熟;性能在大型应用中需要测试。 | +| Nhost | Postgres + GraphQL + Auth + Storage + Functions | 免费:1GB DB、1GB Storage、少量函数调用 | 类似“Supabase + Hasura”;天然 GraphQL;适合前端团队与 React/Next.js 项目。缺点:生态小、成本随用量升高。 | +| AWS Amplify | AWS 一站式后端(Cognito + AppSync + DynamoDB + Storage + Functions + Hosting) | 免费:Hosting 额度 + Cognito 10k MAU + 部分函数额度 | 大而全,适合已有 AWS 基础的团队;企业级可靠性。缺点:最难上手,服务碎片化;初创团队维护成本高。 | +| Xata(近两年快速增长) | 多模型数据库 + Auth + Edge Functions | 免费:250k 记录、15GB 带宽 | 虽然更偏「DB + API」,但提供 Auth、文件、逻辑,可作为轻量全栈后端。UI/开发体验极佳。缺点:功能不如 Firebase/Supabase 全面。 | +| Convex(开发者体验极强) | 托管数据库 + Auth + Functions(前端优先) | 免费开发版;付费按请求量计费 | 极简上手;无需 schema;前端写函数即可用后端。适合 MVP/快速验证。缺点:高度绑定平台,迁移成本高;不算完全传统 BaaS。 | + +## 认证 (Auth) + +| 工具/平台 | 功能特点 | 免费额度/定价 | 适用场景与优缺点 | +| ----------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| Firebase Authentication | Google 提供的 BaaS 身份验证服务,支持邮箱/密码、手机、社交登录、匿名等常见方式。Spark 免费方案支持最高50k 月活跃用户。 | Spark(免费)50k MAU;Blaze 按量计费 | 集成 Google 生态,文档丰富,上手简单;功能全面(MFA、阻塞函数等),适合快速开发。但与 Firebase 平台绑定,扩展到其他服务需额外配置。 | +| Auth0 (Okta) | 全托管身份认证平台,支持社交登录、企业 SSO、多因子认证、规则扩展等强大功能。 | 免费方案25k MAU,付费按 MAU 计费 | 企业级功能齐全(RBAC、审计日志等),适合中大型应用;界面友好。缺点是 MAU 上升时成本高,免费版功能有限(如不含 MFA/RBAC)。社区知名度高,用户众多。 | +| AWS Cognito | 亚马逊云原生身份服务,支持社交及 SAML 联合登录。直接登录用户池提供每月10k MAU 免费,超过部分按 0.0055 美元/MAU 收费。 | 免费10k MAU/月,超出按量付费 | 与 AWS 生态深度集成(可无缝配合 API Gateway、Lambda 等),入门门槛略高,文档较复杂;免费额度有限,适合已有 AWS 使用习惯的团队。 | +| Logto | 开源身份认证平台,自托管版免费,云服务计划免费50k MAU。支持多语言、多租户、OAuth/OIDC 等。 | 社区版免费;Logto Cloud 免费50k MAU | 近期流行的 Auth0 开源替代方案,GitHub 已有 10k+ Stars。易扩展,自托管降低成本;缺点是生态和文档相对较新,社区规模略逊于 Firebase/Auth0。 | +| Keycloak | 知名开源 IAM/SSO 解决方案,支持用户名密码、LDAP、SAML、OAuth2 等。 | 完全免费,需自托管 | 功能强大、可扩展(支持细粒度Control de permisos),企业级功能丰富;但Despliegue和维护复杂度高,对小团队而言学习曲线较陡。缺点是对容器化和集群运维要求较高。 | + +## 文件存储 (Storage) + +| 平台/服务 | 类型 | 免费额度/定价 | 特点/适用场景 | +| ---------------------------------------- | -------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| Amazon S3 | 云对象存储(AWS) | AWS 免费套餐提供 5GB 存储、20k GET/PUT 请求/月,超出按使用量付费 | 行业标准的对象存储,可靠性高、全球多区域Despliegue。功能全面,与 AWS 生态整合良好;定价较复杂,新用户需了解计费规则。 | +| Google Cloud Storage(Firebase Storage) | 云对象存储(Google) | Firebase Spark 方案提供免费额度(1GB 存储 + 流量限制),Blaze 付费 | 与 Firebase/Google Cloud 紧密集成,易于管理;支持 CDN 加速、细粒度安全规则。 | +| 腾讯云 COS / 阿里云 OSS | 云对象存储(国内) | 按量付费(各有新用户赠送额度,如OSS有首年40GB免费等) | 面向国内市场,高性能、大规模对象存储;与中国云生态整合,文档较完善。阿里OSS 功能全面、全球加速;七牛KODO 专注多媒体处理,成本较低,适合个人和小团队。 | +| MinIO | 开源 S3 兼容存储 | 开源免费(自建) | 轻量级、高性能、与 S3 API 兼容,适合在私有云或本地搭建对象存储。文档和社区活跃;需自己维护基础设施。 | +| Cloudinary / Imgix 等 | 媒体存储+CDN | 基本免费方案(如 Cloudinary 免费 25GB/月带宽) | 针对图片/视频优化的云存储+CDN 服务,提供实时转码、压缩等高级功能。适合媒体项目,但功能较专一,作为通用文件存储使用成本偏高。 | + +## 边缘函数 (Edge Functions) + +| 平台/服务 | 特点 | 免费额度/定价 | 适用场景与优缺点 | +| -------------------------------------- | ------------------------------------------ | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Cloudflare Workers | 全球分布式 JavaScript/Wasmtime 环境 | 免费计划:每天 100k 请求;标准计划$5/月含1,000万请求 | 运行在 Cloudflare 边缘节点,延迟极低;适合全局分发的逻辑、静态资源渲染等。免费配额较少(相当于每月约300万请求),上手简单。缺点是运行时(JS/Wasmtime)限制与调试工具有限。 | +| Vercel Edge Functions | 随 Next.js/前端框架无缝集成,支持 JS/TS/Go | Hobby 免费:每月 100万 函数调用,100万 边缘请求 | 深度集成前端框架,自动Despliegue;适合现代 Web 应用。免费额度充足,默认运行时 10s,可提升至 60s。缺点是免费版团队协作功能受限;依赖 Vercel 平台。 | +| Netlify Edge / Functions | Node.js 云函数+边缘路由(NFT) | 免费:300 代币/月(约相当于每月 1M 请求);按信用点计费 | 支持 Node.js 函数、边缘处理路由等。免费额度用于构建、函数和带宽,适合前端全栈Despliegue。优点是简便易用,集成 Git Despliegue;缺点是免费额度使用需算计(10k 请求 = 3 点)。 | +| AWS Lambda@Edge / CloudFront Functions | AWS 无服务器边缘计算 | AWS Lambda(1M 免费请求/月+400k GB-s)+ CloudFront $0.085/每10万调用起 | 与 CloudFront 集成,可在边缘执行代码。适合需要 AWS 生态(如在节点层面做权限或 A/B 测试)。优点是灵活强大;缺点是配置复杂,延迟略高于 Cloudflare/Vercel。 | + +## 实时通信 (Realtime) + +| 平台/服务 | 功能特点 | 免费额度/定价 | 适用场景与优缺点 | +| -------------------------------------- | ------------------------------------------------ | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| Firebase Realtime Database / Firestore | Google BaaS 实时数据库;支持数据变更推送 | Spark 免费:实时数据库1GB 存储 & 限额;Blaze 按量付费 | 强集成 Firebase 生态,实时监听简单。优点是免费起步快;缺点是数据库类型(JSON/NoSQL),复杂查询能力弱。 | +| Ably | 实时消息与 pub/sub 平台,支持 WebSocket、MQTT 等 | 免费包:每月 6,000,000 条消息 | 功能全面的实时消息服务,高并发支持;免费额度可达600万消息/月。社区与文档较好,适合全球分布。 | +| Pusher Channels | 事件推送服务,支持频道/事件机制 | Sandbox 免费:每日 200k 消息,100 并发连接 | 易用的 WebSocket 服务,文档齐全,适合快速实现聊天和通知功能。免费版限制消息量和连接数;付费后扩展性好。 | +| 自建 WebSocket/Socket.IO | 自己搭建服务器(Node.js、Elixir 或 Go 等) | 自行托管成本(如服务器费用) | 灵活度最高,可根据需求定制协议和拓扑。适合对成本控制严格且技术成熟的团队。缺点是需自行处理可用性、扩展和跨域等问题。 | + +## 数据库 + +| 平台/工具 | 数据库类型 | 免费额度/定价 | 主要特点 | +| ---------------------------- | --------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| Neon (Serverless PostgreSQL) | 关系型(PostgreSQL) | 免费计划:0.5GB 存储,主分支永久在线,20h 分支计算/月 | 云原生无服务器 Postgres,支持自动伸缩和分支(fork 测试)。免费额度对小项目够用,适合现代开发流程。分支功能强大,但免费额度较小。 | +| Aiven PostgreSQL | 关系型(PostgreSQL/MySQL) | 免费计划:1GB 存储,1 vCPU,1GB 内存 | 托管级数据库服务,支持跨云多区域迁移。提供有 MySQL、Redis 等可选。免费额度适合开发和小型项目;商业版支持高可用集群和监控。 | +| CockroachDB Cloud | 分布式 SQL(兼容 PostgreSQL) | 免费计划:10GB 存储 | 类似 Google Spanner 的分布式 SQL 数据库,自动分片扩展。免费10GB 空间较慷慨;适合需要横向扩展和高一致性的应用。商业版 SLA 高。 | +| TiDB Cloud | 分布式关系型(MySQL 兼容) | 免费计划:每节点5GB,总计最多25GB | 开源 TiDB 的云版,兼容 MySQL 协议,分布式架构。免费额度充足,适合熟悉 MySQL 的团队,性能优秀;缺点是运维相对复杂(针对大型场景)。 | +| MongoDB Atlas | 文档型(NoSQL MongoDB) | 免费 M0 集群:0.5GB 存储 | 云端 MongoDB,灵活的文档模型,支持丰富查询和索引。免费 0.5GB 数据库适合测试和小型应用;可按需横向扩展。学习曲线略高于关系型数据库。 | +| SQLPub | 多数据库(MySQL、PostgreSQL、Redis 等) | 免费计划:36,000 请求/小时,30 并发连接,500MB 存储 | 一站式数据库平台,支持多种数据库类型。免费版适合学习和小项目;优点是支持多种 DB,缺点是存储额度较小。 | + +以上替代方案各有侧重:开源更灵活可控(Keycloak、MinIO、Socket.IO、Neon、CockroachDB 等),云托管服务更易上手(Firebase、Auth0、Cloudflare、Vercel、Netlify、AWS、Aiven、MongoDB Atlas 等)。选择时可根据项目需求、团队技术栈、预算和社区生态等权衡。个人项目可优先选用免费配额充足、易集成的服务(如 Firebase 系列、七牛存储、Cloudflare Workers、Neon、CockroachDB 等),而对企业级或特定安全需求,则可考虑功能更丰富但收费较高的方案(Auth0、Alibaba/Tencent 云、AWS、TiDB/Aiven 等)。你可以在实际应用中不断尝试,直到选择出最适合的Desarrollo backend工具组件。 + +# 总结 + +在今天的课程中,我们系统学习了数据库的基础概念、Supabase 的核心定义及其操作细节。后续在实践过程中,你可根据项目的实际应用场景与需求,随时回头翻阅这份文档作为参考。 + +请时刻记住一个重要原则: **先完成,再完美!** 无需追求一步到位,我们完全可以通过持续迭代优化,逐步靠近更优的成果。祝你在后续的项目实践中一切顺利! + +# 📚 课后作业 + +1. 开发一个包含用户管理系统和数据库的应用程序。最好包含更多的Supabase 功能 (Realtime / cloud storage / Edge function). diff --git a/docs/es-es/stage-2/backend/git-workflow/index.md b/docs/es-es/stage-2/backend/git-workflow/index.md new file mode 100644 index 0000000..a4a106f --- /dev/null +++ b/docs/es-es/stage-2/backend/git-workflow/index.md @@ -0,0 +1,261 @@ +# Git 和 GitHub 工作流 + +在之前的课程中,我们学习了如何使用基于 Web 的 vibe coding 工具编写代码。每次对话都会创建一个新版本的代码。但是,让我们思考一个问题:如果我们想恢复到之前的修改,有没有方便的方法?有没有一种工具可以记录我们在不同阶段的代码,使我们能够随时在不同版本之间切换和修改? + +为了满足这一需求,版本控制软件应运而生。在这篇文章中,我们将介绍最著名的版本控制程序——Git——以及最好的代码托管平台——GitHub。我们将学习如何使用 Git 进行代码管理,如何从 GitHub 获取他人的代码,如何上传我们自己的代码,以及如何与他人合作进行大型项目。 + +无论是个人项目的版本跟踪,团队协作中的代码同步,还是为开源社区做贡献,Git 和 GitHub 都是现代开发者的必备工具。通过掌握它们,你将能够更高效地管理代码,根据需要创建检查点,在代码的不同阶段之间自由切换,并轻松处理从单个文件更改到开发大型项目的所有事务——使每一次代码迭代都可控且可追溯。 + +> 💡 **Conocimientos previos** +> +> 在学习 Git 之前,建议你先了解以下概念: +> - [什么是终端/命令行](/es-es/appendix/2-development-tools/command-line-shell) - 学习如何使用命令行与计算机交互 +> - [什么是 Git](/es-es/appendix/2-development-tools/git-version-control) - 了解 Git 版本控制系统的核心概念 +> +> 本文将重点介绍 GitHub 工作流和实际操作,上述基础知识请参考附录链接。 + +# Git 快速开始 + +在开始使用 Git 之前,请确保你已经阅读了附录中关于[命令行](/es-es/appendix/2-development-tools/command-line-shell)和[Git 基础](/es-es/appendix/2-development-tools/git-version-control)的内容。本文将假设你已经具备这些基础知识,并直接讲解如何安装配置 Git 以及使用 GitHub 进行协作。 + +## 如何安装 Git + +我们将演示在不同计算机操作系统上安装 Git 的三种方法。请根据你的系统版本按照说明进行操作: + +### Windows + +1. 前往 [Git 官方下载页面](https://git-scm.com/download/win) 并下载适合你系统的安装程序:[安装包](https://github.com/git-for-windows/git/releases/download/v2.51.0.windows.1/Git-2.51.0-64-bit.exe)。默认情况下,推荐使用 x64 安装程序。 +2. 双击安装程序并按照安装向导说明进行操作: + ![](/zh-cn/stage-2/backend/git-workflow/images/image5.png) + 1. 建议保持默认选项。如果你需要自定义,请注意以下几点:(在大多数情况下,你可以一直点击"Next") + - 选择 Git 使用的默认编辑器:选择你喜欢的编辑器(如 VS Code)。你可以默认选择第一个选项,即 Vim(一个文本编辑器),或选择"Visual Studio Code as Git's default editor"选项(需要预先安装 VS Code)。你可以保持默认选择并点击"Next"继续。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image6.png) + - 选择如何使用 Git:这三个选项控制 Git 在系统中的可访问性。建议选择选项 2("from command line and 3rd-party software")——它将基本的 Git 工具添加到 PATH 中,让你可以在 Git Bash、命令提示符、PowerShell 和 IDE 中使用 Git,而不会使系统混乱。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image7.png) + +3. 安装后,在桌面上右键单击。如果在菜单中看到"Git Bash Here",则安装成功。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image8.png) + +### MacOS + +对于 macOS,你可以首先在终端中输入 `git --version` 来检查是否已经安装了 Git。如果没有,系统会提示你安装——只需按照说明完成安装即可。 + +1. 方法 1:通过 Homebrew 安装 + 如果你安装了 [Homebrew](https://brew.sh/)(Mac 包管理器),请打开终端并输入 + ```bash + brew install git + ``` +2. 方法 2:(推荐)通过 Xcode 安装: https://developer.apple.com/xcode/ ,Xcode 内置了 Git。安装后,只需按照说明继续操作。 + +### Linux + +大多数 Linux 发行版可以通过其包管理器安装 Git: + +- Ubuntu/Debian: + +```bash +sudo apt update +sudo apt install git +``` + +- CentOS/RHEL: + +```bash +sudo yum install git +``` + +- 验证安装:在终端中输入 git --version。如果显示版本号,则安装成功。 + +## Git 初始化 + +安装 Git 后,你首先需要配置你的用户信息——这是使用 Git 进行版本控制的基本步骤。在终端中执行以下命令(将括号中的内容替换为你自己的信息): + +```bash +# 设置全局用户名(将显示在提交记录中) +git config --global user.name "Your Name" + +# 设置全局邮箱(建议使用在 GitHub/GitLab 等平台上注册的邮箱) +git config --global user.email "your.email@example.com" +``` + +Git 会将此信息嵌入到每个提交记录中,作为每次修改的"作者信息"。查看版本历史记录(例如,使用 git log)时,你可以清楚地看到谁修改了每一行代码,便于追溯责任和沟通。在协作项目中,统一的身份信息使团队成员能够快速识别谁做了哪些更改,从而提高协作效率(例如通过提交记录找到相关开发人员讨论问题)。 + +你可以通过在命令行中输入 `git config --list` 来查看当前的 Git 配置信息,以确认设置成功。 + +# 什么是 GitHub + +GitHub 是一个基于 Git 的代码托管平台。它不仅为 Git 仓库提供远程存储,还包括协作工具(如 Issues、Pull Requests、Projects),使开发者更容易分享代码和协作。简而言之,Git 是一个本地版本控制工具,而 GitHub 是一个远程"代码仓库云盘 + 协作社区"。 + +GitHub 不仅是世界上最大的代码托管平台,也是全球最活跃、最具影响力的开源社区。这里"开源"的核心思想是任何人都可以下载并运行软件的源代码。这种模式允许世界各地的人们检查彼此的代码并进行修改,或基于此创建新项目。例如,你可以在 GitHub 上找到各种学习教程以及用于训练 GPT 模型的框架(如 PyTorch)的完整源代码。每天,无数人在全球范围内协作审查和改进代码。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image9.png) + +许多大公司在 GitHub 上开源他们的程序或教程,以获得行业竞争优势——这也可以看作是一种广告形式。在 GitHub 社区中,项目获得的"星标 (stars)"数量是衡量其价值的主要指标;项目或组织拥有的星标越多,其可信度和影响力就越大。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image10.png) + +在我们的课程中,支持资源和作业也将上传到专用的 GitHub 仓库。通过上传作业的过程,你将逐渐熟悉并掌握 GitHub 的使用,为未来应用程序开发中的版本控制打下坚实的基础。 + +## 注册 GitHub 账号 + +1. 访问 [GitHub 官网](https://github.com/) 并点击右上角的"Sign up"。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image11.png) +2. 输入你的电子邮件地址(建议使用常用邮箱,因为验证和通知将发送到那里),设置密码(必须包含字母、数字和特殊字符)。 +3. 完成人工验证,按照提示验证邮箱,你的账号就创建好了。 + +## 在 GitHub 上创建你的第一个仓库 + +接下来,我们将创建第一个存储文件夹,也称为仓库或"repo"。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image12.png)![](/zh-cn/stage-2/backend/git-workflow/images/image13.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image14.png) + +1. Repository name:向他人显示的仓库名称。 +2. Description:仓库的详细描述。 +3. Choose visibility:对于个人仓库,如果设置为 private,只有你和特别邀请的人可以看到。如果设置为 public,所有人都可以看到。 + 对于组织内的仓库,如果是 Private,只有组织内的人可以看到。 + 如果是 Public,组织外的人也可以看到。 +4. README:通常的惯例是每个仓库都应该有一个 README 文件。你可以把它看作是仓库的完整介绍,包括使用说明、文件列表和操作方法。 +5. Add .gitignore and license: + 1. .gitignore 文件告诉 Git 在上传到 GitHub 时忽略某些文件夹或文件,因此它们不会被跟踪或添加到暂存区。这对于临时测试文件、依赖包或大文件很有用。一旦指定,这些文件将不再被跟踪。 + 2. license 指的是你选择的开源许可证类型。不同的许可证详细规定了他人是否可以将你的代码用于商业目的,并包含其他条款和条件。 + +建议勾选"Add README",将仓库可见性设置为"Private",并根据自己的喜好填写仓库名称和描述,然后点击"Create repository"完成创建第一个远程仓库。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image15.png) + +之后,你将拥有一个没有任何额外文件的干净仓库。接下来你可以开始上传文件了。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image16.png) + +获取仓库的命令是 `git clone`,但它需要仓库地址。你可以通过点击绿色的"Code"按钮找到仓库地址,你会看到 HTTPS 和 SSH 选项。通常,你可以使用这两种方法中的任何一种将仓库下载到本地机器(只有这样你才能修改和上传文件)。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image17.png) + +一般来说,通过 HTTP 克隆的仓库适合临时下载和测试他人的仓库,但不建议用于自己的开发。为了更好的学习体验,你应该先设置 SSH 认证。 + +## 绑定本地 SSH + +在 GitHub 中,"SSH 协议绑定"本质上意味着将你本地设备的 SSH 公钥与你的 GitHub 账号关联,允许 GitHub 通过 SSH 协议识别你的设备。这使你能够安全地操作远程仓库,而无需密码(如 clone、push 或 pull 代码)。 + +简单来说:这就像给你的设备一张"GitHub 专属门禁卡"。绑定后,当你的设备通过 SSH 协议访问 GitHub 仓库时,GitHub 会验证这张"门禁卡"(你的 SSH 公钥)。一旦确认为你的授权设备,你就可以直接操作——不需要每次都输入账号密码。 + +> 💡 什么是 SSH + +### 为什么需要 SSH 协议绑定? + +GitHub 支持两种主要的仓库操作协议:HTTPS 协议和 SSH 协议: + +- HTTPS 协议:每次操作(如 push)都需要输入 GitHub 账号密码(或个人访问令牌 PAT)。验证过程繁琐,且存在密码泄露风险。 +- SSH 协议:身份验证通过"密钥对"完成,因此不需要重复输入密码,且加密传输更加安全。 + +"SSH 协议绑定"是启用 GitHub SSH 认证的前提步骤——只有将本地 SSH 公钥"绑定"到 GitHub 账号后,GitHub 才能识别你的设备并允许对仓库进行 SSH 操作。 + +### "绑定"的核心逻辑:SSH 密钥对的作用 + +SSH 认证依赖于密钥对(公钥 + 私钥),它们是匹配的加密文件。生成后,你需要将"公钥"提供给 GitHub("绑定"),而"私钥"留在本地设备上: + +1. 私钥:存储在本地设备(如电脑)的指定目录中(通常是 ~/.ssh/),充当"你的专属钥匙",绝不能与任何人分享。 +2. 公钥:这是一把可以公开分享的"锁"——你需要将其复制到 GitHub 账号的"SSH keys list"中("绑定"操作)。 + +当你通过 SSH 操作 GitHub 仓库时(例如 git push git@github.com:xxx/xxx.git): + +- 你的本地设备使用私钥加密"操作请求"并发送给 GitHub; +- 收到请求后,GitHub 尝试使用你之前绑定的公钥进行解密; +- 如果解密成功,你的设备被确认为已授权,操作被允许;否则,访问被拒绝。 + +### "绑定"的具体步骤(核心流程) + +一旦你理解了原理,实际操作就很简单——核心是"生成密钥对 → 上传公钥到 GitHub": + +1. 本地生成 SSH 密钥对 + 1. 使用 Trae 获取公钥(推荐) + 提示词:`Help me create the SSH key needed for GitHub login. My email is your_email@gmail.com , Please return the public key for me to copy` + + ![](/zh-cn/stage-2/backend/git-workflow/images/image18.png) + + 输入提示词后,你还需要在左侧终端按 Enter 键,否则命令会一直等待而不执行。由于 Trae 无法帮你执行任何条件判断,我们只需要一直按 Enter 即可。 + + 最后,你会看到右侧的 Trae 返回了它读取的公钥。你只需复制它并准备在下一步中粘贴。 + + ![](/zh-cn/stage-2/backend/git-workflow/images/image19.png) 2. 手动获取公钥 + 打开你的本地终端(在 Windows 上使用 Git Bash 或 PowerShell;在 macOS/Linux 上使用终端),输入以下命令(将 your_email@example.com 替换为你注册 GitHub 账号时使用的邮箱): + + ```bash + ssh-keygen -t ed25519 -C "your_email@example.com" + ``` + + 1. 按 Enter 接受默认值(默认文件路径,无密码,或根据需要设置密码)。这将在 ~/.ssh/ 目录中生成两个文件: + - id_ed25519:私钥(本地保存,**绝不分享**); + - id_ed25519.pub:公钥(需要上传到 GitHub)。 + +2. 将公钥"绑定"到你的 GitHub 账号 + +这是核心绑定步骤——将本地公钥添加到 GitHub 账号的"SSH keys list"中: + +1. 复制公钥内容: + 1. Trae: + 2. Windows:用记事本打开 C:\Users\\.ssh\id_ed25519.pub 并复制其所有内容; + 3. macOS/Linux:在终端运行 cat ~/.ssh/id_ed25519.pub 并复制所有输出(从开头的 SSH-ed25519 到结尾的邮箱)。 +2. 登录 GitHub 并进入"SSH Key Management"页面: + 1. 点击右上角头像 → Settings → 左侧菜单 SSH and GPG keys → 点击 New SSH key。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image20.png)![](/zh-cn/stage-2/backend/git-workflow/images/image21.png) + 2. 输入任何标题(例如,your local computer's SSH),然后将你刚刚获取的 SSH 公钥粘贴到这里。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image22.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image23.png) + +3. 验证绑定是否成功 + +在终端中输入以下命令(**Trae 也可以做以下操作**)来测试 GitHub 是否能识别你的设备: + +```bash +ssh -T git@github.com +``` + +- 如果你看到类似 Hi [your GitHub username]! You've successfully authenticated... 的内容,说明你已成功绑定密钥; +- 如果遇到错误,通常是因为公钥复制不完整、私钥权限过高(你的本地 ~/.ssh/ 目录应仅由你读写)等。根据需要检查这些问题。 + +### 重要注意事项 + +如果你有多个设备(如笔记本电脑和台式机),你需要为每个设备生成单独的 SSH 密钥对,并将每个公钥绑定到同一个 GitHub 账号——每个设备都有自己的"门禁卡"。 + +切勿分享你的私钥(不要上传到 GitHub 或与他人分享),否则有人可能会冒充你操作你的仓库。如果私钥泄露,请立即从 GitHub 删除相应的公钥并生成新的密钥对。 + +绑定 SSH 后,使用 SSH 格式的仓库地址(例如 git@github.com:username/repository.git)进行操作,而不是 HTTPS 格式(例如 https://github.com/username/repository.git)。如果你之前用 HTTPS 克隆了仓库,可以用 git remote set-url origin `` 切换协议。 + +# 使用 Trae 进行 GitHub 操作 + +我们已经解释了什么是 Git,什么是 GitHub,什么是 SSH,以及如何配置它。现在你可以自由使用 Trae 执行 Git 操作。首先,让我们学习如何将远程仓库克隆到本地机器。 + +## Git clone : 下载现有仓库 + +你可以直接告诉它你想克隆的仓库地址 + +![](/zh-cn/stage-2/backend/git-workflow/images/image24.png) + +## Git pull : 从远程仓库获取更新 + +每次更新仓库之前,由于它可能由多人维护,你需要先拉取最新的更改。之后,你可以修改并推送文件。 + +**记得包含文件夹名称及其相对或绝对路径,以避免推送到错误的仓库。** + +prompt:`Help me pull this repository AIID-TEST in ./AIID-TEST.` + +## Git commit & Git push : 暂存更新并推送到 GitHub + +一切准备就绪后,你可以尝试修改本地文件,在文件夹中添加或删除项目。然后,让 Trae 检测更改并帮你推送到 GitHub。 + +prompt:`I finished. Commit and push to the repository AIID-TEST in ./AIID-TEST.` + +![](/zh-cn/stage-2/backend/git-workflow/images/image25.png) + +推送成功。现在你可以在 GitHub 上看到更新的内容了。 + +# Referencias + +- Pro Git book https://git-scm.com/book/en/v2 +- GitHub Docs https://docs.github.com/en diff --git a/docs/es-es/stage-2/backend/modern-cli/index.md b/docs/es-es/stage-2/backend/modern-cli/index.md new file mode 100644 index 0000000..b2c6f4a --- /dev/null +++ b/docs/es-es/stage-2/backend/modern-cli/index.md @@ -0,0 +1,801 @@ +# CLI AI 编程工具 + +在本教程中,我们将介绍直接在命令行中运行的 AI 编程 Agent。它们和之前学过的 Trae、Cursor 中的 Agent 不同,CLI AI 编程工具只能在终端中使用。与集成在 AI IDE 里的 Agent 相比,它们通常具有更长的上下文窗口、更快的工具调用速度,并且可以兼容更多种类的大模型。在最新的 AI Vibe Coding 实战中,我们往往会优先使用 CLI AI 编程工具,而不是 IDE 内置的编码 Agent。 + +## 从 CLI 说起 + +还记得我们之前介绍过的 CLI 吗?CLI 指的是通过终端或命令提示符,用纯文本命令来操作软件应用,而不是依赖图形界面(GUI——你可以简单理解为电脑或手机上带按钮、可以点击操作的界面,不需要输入命令)。 + +> 在 Windows 上,常见的终端有“命令提示符(cmd)”和 “PowerShell”。你可以在电脑的运行/搜索框中输入 “cmd” 或 “powershell” 来启动这些命令行程序。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image1.png)![](/zh-cn/stage-2/backend/modern-cli/images/image2.png) + +CLI 天生适合文本命令操作,在一小部分极客(追求极致的编程爱好者)群体中,CLI 甚至比 GUI 更受欢迎——他们希望所有操作都通过键盘完成,觉得动鼠标反而会拖慢自己的编码效率。 + +在工业界,CLI 往往也是最常见的接口形式,因为 GUI 需要操作系统额外绘制界面、管理窗口,对计算机资源的要求更高;而 CLI 只需要把收到的命令传给系统执行即可。因此,在连接大规模服务器集群时,我们通常只通过 CLI 进行交互。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image3.png) + +对于许多没有 CLI 经验的同学来说,可能会觉得 CLI 操作很复杂、命令太多,甚至担心“一不小心就把电脑搞坏”。不用担心。还记得我们在前面教程里,经常让 Trae 帮忙完成各种基础操作吗?这里也可以完全照搬这个思路——我们可以让 CLI 编程工具帮我们执行所有 CLI 操作:让它帮你进入指定文件夹、搜索和处理文件、运行或复制开源项目等。整个过程都可以通过和 CLI AI 编程工具的对话来完成。 + +## 和 AI IDE 有什么不同 + +我们可以把 CLI AI 编程工具类比成之前学过的 z.ai 和 Trae。某种意义上,CLI AI 编程工具可以看成是一种特殊的 z.ai:它们同样只需要一个简单的对话入口,就会自动为你执行所有需要的操作(只是有时你需要手动打开浏览器查看最终效果)。而如果类比 AI IDE,那么 CLI AI 编程工具可以被看作是 IDE 中的 Agent 模块——也就是侧边那块对话区域。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image4.png)![](/zh-cn/stage-2/backend/modern-cli/images/image5.png) + +不过,由于不同 AI IDE 对 Agent 的实现方式不同,能力差异也很大,AI 编程效果经常不稳定,因此 CLI AI 编程工具通常由大型科技公司直接开发,例如 Claude 背后的 Anthropic、ChatGPT 背后的 OpenAI 等。 + +相比其他 AI 编程 Agent,直接使用这些大厂产品往往是较优的实践,尤其是 Claude Code 本身就是为 Anthropic 内部研发团队服务的工具,从一开始就围绕“满足工程师真实需求”来设计。 + +为了更直观地对比,我们可以简单看看 Claude Code 和某款 AI IDE Agent 的差异(这里以 Cursor 为例): + +| 功能特性 | Claude Code | Cursor | 更优者 | +| ----------------- | ------------- | --------------- | ----------- | +| 自动任务执行 | ✅ 非常强 | ❌ 能力有限 | Claude Code | +| IDE 集成 | ❌ 仅命令行 | ✅ 原生 VS Code | Cursor | +| 实时代码补全 | ❌ 无 | ✅ 体验极佳 | Cursor | +| 多文件操作 | ✅ 非常强 | ⚠️ 还不错 | Claude Code | +| GitHub 一体化操作 | ✅ 可直接提交 | ⚠️ 需要手动操作 | Claude Code | +| 学习成本 | ⚠️ 中等 | ✅ 上手简单 | Cursor | +| 上下文长度 | ✅ 非常长 | ⚠️ 较好 | Claude Code | +| 调试辅助 | ✅ 自动化 | ⚠️ 较多需手动 | Claude Code | + +表格来源: + +简单说,CLI AI 编程工具通常可以: + +- 支持更长时间的连续对话(甚至可以帮你“工作一整天”)。 +- 提供更长的上下文窗口(不再频繁需要你说“继续”)。 +- 响应速度更快(可以接入更多自定义模型 API)。 + +在编码相关操作上,它们通常比大部分 IDE 内置 Agent 更聪明、更稳定。 + +## 常见的 CLI AI 编程工具 + +目前虽然有很多开源实现,但在实践中我们只推荐两大类型的 CLI AI 编程工具,作为“首选组合”。你可以根据自己的习惯任选其一,强烈建议都试一试,再选出最适合你的那一个。 + +- Codex 使用 GPT-5,在整体能力上更强; +- Claude Code 通过 GLM 4.6 转发 API,整体体验接近 Claude 4,但价格更便宜。 +- OpenCode 可以随意切换并搭配模型, 提供免费模型, 可以更好的控制成本。 + +不过,哪一个在实际项目中更好用,只能通过亲自测试来判断。掌握多种 AI 编程工具始终是有益的:熟练以后,你可以在不同场景下灵活切换 Claude Code、Codex 或 Trae。如果尝试多次后发现某个工具效果一般,可以直接换一个工具或模型继续试验。 + +同时,由于模型版本更新非常迅速,建议你优先选择在“性价比(效果 / 成本)”上表现最好的方案。 + +### Claude Code + +Claude Code 是由 Anthropic 基于 Claude 大模型能力开发的一款 AI 编程工具。它的主要交互场景在终端,同时也支持作为 VS Code 插件来使用。类似于 AI IDE 中的 Agent,它可以深度理解开发者的代码仓库,并通过自然语言指令完成端到端的开发任务——包括代码编辑、修复 Bug、执行和修复测试、管理 Git 工作流(例如解决合并冲突、创建 PR)、复杂代码讲解、执行终端命令等。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image6.png) + +Claude Code 的优势主要体现在:极长的上下文窗口(可以处理完整文件甚至小型项目)、可以主动澄清模糊需求、自动规划和分配执行任务,以及对整个代码库内容的深度理解和解释能力。与普通 IDE Agent 相比,它更适合“沉浸式 vibe coding” 的开发流程。 + +在实际使用中,你可以通过对话指令,让它帮你创建新项目、执行 CLI 操作(例如整理文件夹、批量重命名文件、Despliegue开源项目等)、配置开发环境(例如安装和调试 Python 环境)。如果觉得某段代码难以理解、某个目录结构不清晰,也可以直接让 Claude Code 生成结构化的分析文档,或者对特定内容进行分步骤讲解。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image7.png)![](/zh-cn/stage-2/backend/modern-cli/images/image8.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image9.png)![](/zh-cn/stage-2/backend/modern-cli/images/image10.png) + +如果你想系统地学习 Claude Code,可以参考 Andrew Ng 与 Anthropic 联合推出的课程: + + +接下来,我们将学习如何使用 Claude Code。由于直接使用官方 Claude Code 的成本往往非常高(如下图所示),我们会转而使用兼容 Claude Code 协议、但基于其他大模型的 API 平台。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image11.png) + +你需要学习下面几种不同方案(最好都尝试一遍),最后选择最适合你的那一种作为主要实践路径。 + +第一种方式是直接使用“兼容 Anthropic 接口”的 API。随着 Claude Code 的流行,越来越多的大模型服务商开始支持 Anthropic 风格的调用方式。常见的服务商包括 GLM、Kimi、DeepSeek 和 Siliconflow 等,它们都提供了兼容的 API 接口。关于具体配置,我们会在后文细讲。 + +需要注意的是,Claude Code 通常会消耗大量 token,如果你担心 API 调用产生过高费用,可以考虑购买 GLM 的月度套餐(大约 20 元/月)来控制成本。如果你想先感受一下实际花费,也可以先充值 10 元做小规模试验。 + +另一种方式是使用 “Claude Code Route” 项目。它是一个开源工具,不仅支持所有常见的 API 调用接口,还允许你针对不同场景精细配置要使用的模型,并且支持对接本地Despliegue的大模型。但由于这一方案的配置相对复杂,建议你先从第一种方案入手。 + +#### 使用智谱 GLM 作为后端(推荐) + +GLM(General Language Model)是智谱 AI 自主研发的一系列大型语言模型。GLM-4.6 是当前 GLM 系列的最新版本,其核心亮点是在代码能力上的优异表现(在公开基准和真实任务中对标 Claude Sonnet 4,在国内处于第一梯队)。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image12.png) + +它还将上下文窗口扩展到 200K,可以更加从容地处理长文本和大体量代码,同时加强了推理与工具调用能力,在性能和成本之间取得了不错的平衡。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image13.png) + +在接入 GLM 之前,我们需要先安装 Claude Code。 + +如果你觉得命令行安装步骤麻烦,或者中途出现错误,可以直接让 Trae 的 Agent 帮你完成安装。 + +```python +# 安装 Claude Code +npm install -g @anthropic-ai/claude-code + +# 进入你的项目 +cd your-awesome-project + +# 启动 Claude Code +claude + +# 按 Ctrl+C 退出 Claude +``` + +接下来,我们需要修改 Claude Code 的默认 API 请求地址,使其支持 GLM 的 API 服务。你可以直接复制下面的内容,让 Trae 帮你创建对应的环境变量;也可以选择把它们永久写入系统环境变量(如果出现问题,同样可以让 Agent 帮忙修改)。 + +首先,你需要先获取 GLM 的 API Key,并用你自己觉得最方便的方式保存好。 + +国内版地址: +国际版地址: + +如果你使用的是 **国内版 GLM**,请使用以下变量配置: + +```python +# 在 Cmd 中运行以下命令 +# 注意将 `your_zhipu_api_key` 替换为你刚刚获取到的 API Key +setx ANTHROPIC_AUTH_TOKEN your_zhipu_api_key +setx ANTHROPIC_BASE_URL https://open.bigmodel.cn/api/anthropic +``` + +如果你使用的是 **国际版 GLM**,请使用下面的配置: + +```python +# 在 Cmd 中运行以下命令 +# 同样注意替换掉 `your_zai_api_key` +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic +``` + +你可以直接在 Trae 中输入类似下面的提示词: + +⚠️ 如果你是通过 Trae 帮你配置“永久环境变量”,那么配置完成后 **必须重启 Trae**,否则它内置终端里的环境变量不会更新,可能导致登录失败或网络连接错误。 + +```python +Based on my environment variable settings: +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic + +and my key(Replace it with your own key): +681fea485851d29060cc.13gfaendggaFOhb + +please help me configure and start Claude Code +``` + +你会看到类似下面的过程输出: + +![](/zh-cn/stage-2/backend/modern-cli/images/image14.png) + +> 💡 什么是环境变量? +> +> 环境变量本质上是一组存储在操作系统中的“键值对”配置信息,通常以 “变量名 = 具体值” 的形式存在。只要提前在终端或系统设置中配置好,程序就可以随时读取这些变量来获取相关信息。由于环境变量可以直接在终端中写入,而无需修改代码本身,我们通常会把访问大模型所需的密钥存放在环境变量里,以避免泄露。程序只需要读取对应环境变量,就能完成大模型调用。 +> +> 在 Windows 系统中,环境变量除了用于存储大模型的访问密钥,还常常用来保存命令行工具的“调用路径”。 +> +> 我们知道终端本身也是一个程序。有时我们希望在终端里启动某个外部程序,例如在终端中输入 `claude` 来启动 Claude Code。之所以可以直接输入 `claude` 就运行,是因为终端会读取系统的环境变量,其中的 PATH 变量里包含了 Claude Code 可执行文件所在的目录,所以终端能够找到并执行它(等价于在终端中粘贴那段程序的绝对路径再按回车)。 +> +> 一个典型的环境变量可能长这样:`PATH=C:\Windows\system32;C:\Program Files\Python`。这样我们就可以在任何路径下执行系统中的这些程序,例如直接在命令行键入 `python` 启动 Python 解释器。 +> +> 如果你想查看系统当前的环境变量,可以在 Windows 搜索中输入“环境变量”,在弹出的“编辑系统环境变量”窗口中就能看到所有变量及其值。有的变量用于存储大模型密钥,有的则用于添加程序目录,方便在任意路径下调用。 + +现在,你就可以使用最新的 GLM 来进行 Claude Code 开发了。你可以尝试重新跑一遍之前的项目,或者重新挑战那些 Trae 没有完成好的任务,对比看看体验上的差异。 + +🎉 反复“推倒重来”并不是浪费时间——你每重做一遍,技能都会更扎实一分。 + +用和 GLM 完全相同的思路,也可以轻松接入其他支持 Anthropic 兼容格式的接口。 + +#### 使用 Kimi K2 作为后端(推荐) + +Kimi K2 是月之暗面(Moonshot AI)推出的新一代大语言模型,在代码理解和生成能力上表现出色。Kimi K2 支持超长上下文窗口(最高可达 200K tokens),能够轻松处理大型代码库和复杂项目。 + +**核心优势:** + +- **超长上下文**:支持 200K 上下文窗口,可以一次性处理整个项目的代码 +- **代码能力强**:在代码生成、重构和调试方面表现优异 +- **中文理解好**:对中文编程需求的理解更加准确 +- **工具调用稳定**:支持稳定的函数调用和工具使用 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +参考文档: + +```bash +export ANTHROPIC_BASE_URL=https://api.moonshot.cn/anthropic +export ANTHROPIC_AUTH_TOKEN=sk-YOURKEY +``` + +#### 使用 Minimax 作为后端(推荐) + +Minimax 是稀宇科技(MiniMax)推出的新一代大语言模型,在编程任务上表现优异。Minimax 模型以其出色的推理能力和代码生成质量而闻名,特别适合复杂的编程场景。 + +**核心优势:** + +- **推理能力强**:在复杂逻辑推理和代码架构设计方面表现出色 +- **代码质量高**:生成的代码结构清晰、可读性好 +- **多语言支持**:支持多种编程语言的代码生成和转换 +- **响应速度快**:API 响应速度快,适合高频调用场景 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_MINIMAX_API_KEY +export ANTHROPIC_MODEL=MiniMax-M2.7 +``` + +#### 使用 DeepSeek 作为后端(推荐) + +DeepSeek 是深度求索推出的开源大语言模型,以其出色的代码能力和高性价比受到开发者欢迎。DeepSeek Coder 专门针对编程任务进行了优化训练。 + +**核心优势:** + +- **代码能力突出**:在代码生成、代码理解和 Bug 修复方面表现优异 +- **开源可定制**:模型开源,可以根据需求进行微调 +- **性价比高**:API 价格相对较低,适合高频使用 +- **中文支持好**:对中文编程场景理解准确 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic +export ANTHROPIC_AUTH_TOKEN=YOU_DEEPSEEK_API_KEY +export API_TIMEOUT_MS=600000 +export ANTHROPIC_MODEL=deepseek-chat +export ANTHROPIC_SMALL_FAST_MODEL=deepseek-chat +export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 +``` + +#### 使用火山引擎 Coding Plan 作为后端(推荐) + +火山引擎(Volcano Engine)是字节跳动旗下的云服务平台,提供企业级的 AI 模型服务。火山引擎的 Coding Plan 专门为编程场景优化,提供稳定、高效的代码生成能力。 + +**核心优势:** + +- **企业级稳定性**:提供服务等级协议(SLA),保障服务稳定性 +- **代码场景优化**:针对编程任务进行了专门优化 +- **丰富模型选择**:支持多种模型,包括 Doubao-pro、Doubao-lite 等 +- **国内访问快**:国内节点Despliegue,访问速度快 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://ark.volces.com/api/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_VOLCANO_API_KEY +export ANTHROPIC_MODEL=doubao-pro-32k +``` + +#### 其他兼容 Anthropic 的 API + +Siliconflow: + +```bash +export ANTHROPIC_BASE_URL="https://api.siliconflow.cn/" +export ANTHROPIC_MODEL="moonshotai/Kimi-K2-Instruct-0905" # 可以自行修改所需模型 +export ANTHROPIC_API_KEY="YOUR_SILICONCLOUD_API_KEY" # 请替换 API Key +``` + +阿里云 DashScope(Aliyuncs): + +```python +export ANTHROPIC_BASE_URL="https://dashscope.aliyuncs.com/apps/anthropic" +export ANTHROPIC_API_KEY="YOUR_DASHSCOPE_API_KEY" +``` + +::: details 使用 Claude Code Route 作为后端(进阶用法) + +上面我们讲解了如何用 GLM 官方 API 替换 Claude Code 的 Anthropic 接口。接下来,我们来看一下 Claude Code Router 这个工具是如何让 Claude Code 适配更多模型 API 的。 + +[Claude Code Router](https://github.com/musistudio/claude-code-router) 是一款专门为 Claude Code 设计的智能路由增强工具。它的核心作用,是帮助用户按需将 AI 请求分发到不同平台上的模型,并可以高度自定义。它支持接入几十个平台,包括 OpenRouter、DeepSeek、Ollama、Gemini 等,也可以按场景将任务路由到特定模型,比如 GLM-4.5、Kimi-K2、Qwen3-Coder 等。举例来说,你可以将后台任务自动交给本地 Ollama,以节省成本;将长文本 / 长代码任务交给 Gemini-2.5-Pro;把代码讲解交给 DeepSeek。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image16.png) + +该工具还提供了方便的 UI/CLI 配置管理能力,并通过"转换器(converter)"适配不同平台的 API 格式。它支持 GitHub Actions 等自动化集成以及自定义扩展,解决了"单一模型无法覆盖所有场景"以及"频繁切换平台很麻烦"的问题,帮助用户更灵活、低成本地利用 AI 工具。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image17.png) + +下面我们简单介绍如何安装 Claude Code Router。大致需要以下步骤(同样可以让 Trae 帮你执行),以准备好相关环境: + +```markdown +npm install -g @anthropic-ai/claude-code +npm install -g @musistudio/claude-code-router +``` + +安装完成后,你需要确认本地可以使用 `ccr` 命令。如果看到类似下面的输出,说明安装成功: + +![](/zh-cn/stage-2/backend/modern-cli/images/image18.png) + +接下来,有两种方式来初始化和配置模型: + +- 使用 CCR 自带的 UI,在浏览器中打开它提供的配置页面进行操作; +- 直接修改 CCR 的默认配置文件(本质上 UI 也是在修改配置文件,只是提供了更直观的界面)。 + +如果选择使用 CCR UI,你会看到类似下面的界面: + +![](/zh-cn/stage-2/backend/modern-cli/images/image19.png) + +此时点击 "Add Provider" 按钮,就会看到如下界面。你需要: + +1. 在 Name 中输入模型提供商的名字; +2. 在 API Full URL 中填写该提供商的 OpenAI 兼容接口地址; +3. 在 API Key 中填写对应平台的 API Key; +4. 在 Models 区域中填写模型名称,点击 "Add Model" 添加; +5. 最后点击 "Save" 保存配置。 + +(界面往下滚动还有很多高级选项,但目前你可以先忽略它们。) + +![](/zh-cn/stage-2/backend/modern-cli/images/image20.png) + +下面是 DeepSeek 与 Kimi 的配置示例: + +![](/zh-cn/stage-2/backend/modern-cli/images/image21.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image22.png) + +保存模型配置后,还需要在右侧 Router 区域中指定默认模型(Default)。点击对应的下拉选择,将其设置为 `kimi`(推荐),然后在右上角点击 `Save and Restart`。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image23.png) + +之后,只需在终端中输入 `ccr code`,即可通过 Claude Code Router 启动 Claude Code 的编码工作流。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image24.png) + +::: + +#### Claude Code 的进阶用法 + +很多人最开始使用 Claude Code 时,只把它当成普通对话工具来用。但实际上,它内置了很多丰富的能力,能够让你使用起来更高效、灵活。下面是一些常见命令和用法示例: + +参考文档: + + + + +| 命令 | 作用 | 示例 | +| ----------------- | ----------------------------------------- | ---------------------------------------- | +| claude | 启动交互模式 | `claude` | +| claude "query" | 执行一次性任务并输出结果 | `claude "explain this project"` | +| claude -p "query" | 执行一次性问题并在结束后自动退出 | `claude -p "explain this function xxxx"` | +| claude -c | 继续最近的一次会话 | `claude -c` | +| claude -r | 恢复上一段会话 | `claude -r` | +| /resume | 在当前聊天中切换回上一段会话 | `claude -c`、`/resume` | +| /plugin | 管理插件,可安装提交与审查类扩展能力 | `/plugin` | +| /init | 用 CLAUDE.md 初始化项目说明 | `/init` | +| /clear | 清空当前会话上下文,防止信息过载 | `/clear` | +| /compact | 压缩会话历史,减少上下文 token 占用 | `/compact` | +| /cost | 查看当前消费情况 | `/cost` | +| /model | 切换使用的模型(用兼容 API 时一般可忽略) | `/model` | +| /memory | 管理 CLAUDE.md 记忆文件 | | +| /help | 显示可用命令列表 | `/help` | +| exit or Ctrl+C | 退出 Claude Code | `exit` 或 `Ctrl+C` | +| /agents | 高级功能,后文会说明 | | +| /mcp | 高级功能,后文会说明 | | + +**CLAUDE.md** + +参考: + +`CLAUDE.md` 是 Claude 在开始对话时会自动读取并加入上下文的特殊文件。因此,它非常适合用来记录: + +- 常用 bash 命令 +- 核心文件和工具函数 +- 代码风格约定 +- 测试方式说明 +- 仓库协作规范(例如分支命名、是用 merge 还是 rebase 等) +- 开发环境配置说明(例如是否使用 pyenv、推荐哪种编译器等) +- 项目中需要特别注意的行为或坑点 +- 任何你希望 Claude “记住”的信息 + +`CLAUDE.md` 本身没有强制格式要求,只要简洁、便于人类阅读即可。例如: + +``` +# Bash commands +- npm run build: Build the project +- npm run typecheck: Run the typechecker + +# Code style +- Use ES modules (import/export) syntax, not CommonJS (require) +- Destructure imports when possible (eg. import { foo } from 'bar') + +# Workflow +- Be sure to typecheck when you’re done making a series of code changes +- Prefer running single tests, and not the whole test suite, for performance +``` + +#### Claude Code 的内部原理 + +参考: + +如果你好奇为什么 Claude Code 在很多场景下比 Trae 或 Cursor 等 Agent 编程工具更好用,我们可以简单看一下它的内部工作机制。 + +其他 CLI AI 编程工具的整体实现方式也大体类似。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image25.png) + +Claude Code 会把编程任务拆解成一个持续的“感知—思考—行动—验证”循环,并在其中调用不同工具完成任务。它模仿人类开发者的工作流:不断“写代码 → 运行 → 看结果 → 再改进”。系统内部通过一个主任务循环不断执行步骤,在每一轮循环中,Claude 都可以调用不同工具——例如读写文件、执行命令、搜索代码等——再根据工具返回的真实结果决定下一步行动。 + +其中有几个关键特性值得注意: + +- **流式处理(Stream Processing)**:Claude 可以一边思考一边输出结果,而不是必须等所有代码写完再执行。 +- **智能压缩(Intelligent Compression)**:长对话容易导致上下文过长,Claude 通过将历史压缩成关键信息来减少“遗忘”的概率,并通过区分长短期记忆保证高效运行。 +- **并发控制(Concurrency Control)**:内部并行设计可以让多个任务同时进行,互不干扰。 +- **子 Agent 管理(Sub-agent Management)**:实际工作中并不只相当于一个“角色”处理所有事情,你可以管理多个子 Agent 协作处理代码,每个 Agent 负责不同任务,比如专门负责测试、专门负责写文档等。 + +### Codex + +![](/zh-cn/stage-2/backend/modern-cli/images/image26.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image27.png) + +和 Claude Code 类似,Codex 是由 OpenAI 开发的一款 AI 协作编程工具,你可以把它理解成 “OpenAI 版的 Claude Code”。它最大的优势是对 GPT-5 的高效适配。 + +从实际体验来看,GPT-5 目前响应速度更快、犯错率更低(在多轮复杂任务中正确完成的概率更高)。它的一个缺点是解释往往偏“学术”和“技术”,有时显得过于严谨、信息量很大,对初学者来说可能略微难懂。 + +你可以通过下面的命令安装 Codex: + +``` +npm i -g @openai/codex +``` + +#### 使用 OpenAI 官方 API 作为后端 + +如果直接使用 OpenAI 官方的 Codex 入口,配置会非常简单:当你已经开通 OpenAI 订阅或申请到了相应 API 配额之后,只需要在命令行中输入 `codex` 启动程序,并按提示完成登录即可。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image28.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image29.png) + +#### 使用转发 OpenAI API 的方式作为后端 + +由于官方 OPENAI API 可能存在价格较高、网络要求严格等问题,为了避免这些限制,我们也可以通过其他 API 网关服务来转发调用。 + +在这种方式下,我们只需要在第三方转发平台上购买对应的 Codex API 配额,就能获得接近原生 OpenAI Codex 的使用体验。 + +参考: +充值地址: + +需要注意的是,在拿到 token 配额后,我们还需要在本地配置好 API Key。 + +在密钥分组设置中,要注意选择专门用于 Codex 的那一项。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image30.png) + +接下来,我们需要把获取到的 Key 填入下面的提示词中,并把整段提示词交给 Trae,让它帮你完成整个配置过程: + +````bash +My API key is: [Paste your obtained sk-xxxxx key here] + +Please help me complete the following configuration tasks: + +1. Create configuration directory + - Create a `.codex` folder under my user directory + - Windows path should be: `C:\Users\[My Username]\.codex` +2. Backup existing configuration (if exists) + - Check if `.codex\config.toml` exists + - If it exists, rename it to `config.toml.bak.[current timestamp]` (timestamp format: yyyyMMddHHmmss) +3. Create configuration file + - Create `config.toml` in the `.codex` directory + - Write the following complete content: + ```toml + preferred_auth_method = "apikey" + + [model_providers.myrelay] + name = "My Relay Station" + base_url = "https://api.zyai.online/v1" + env_key = "MYRELAY_API_KEY" + wire_api = "responses" + request_max_retries = 4 + stream_max_retries = 10 + stream_idle_timeout_ms = 300000 + + [profiles.myrelay] + model_provider = "myrelay" + model = "gpt-5" + model_reasoning_effort = "medium" + + [tools] + web_search = true + +4. Set system environment variable +Variable name: MYRELAY_API_KEY +Variable value: The key I gave you + +5. Confirm completion and report back: + +The full path of the configuration file +Whether the environment variable was set successfully +I can use the command `codex --profile myrelay` to run it +```` + +配置完成后,你就可以通过 `codex --profile myrelay` 启动使用转发 API 的 Codex 了。之后的使用方式与 Claude Code 类似:只需要在对话框中随时输入你的想法和需求即可。 + +### OpenCode + +![](/zh-cn/stage-2/backend/modern-cli/images/image32.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image33.png) + +OpenCode 是一款面向开发者的开源 AI Coding Agent 平台,定位类似于 “多模型版的 Claude Code”。它以 Terminal 为核心交互入口,同时也支持编辑器集成(如 VS Code、Neovim 等),能够深度接入本地代码仓库,并通过自然语言完成从代码理解到工程执行的一整套开发流程。 + +它不是绑定单一模型的 AI 编程工具,而是一个可自由切换 GPT、Claude、Gemini 乃至本地模型的开放式 AI Coding Agent 平台。就连 OpenAI 官方也持 OpenCode 接入 Codex / OpenAI 订阅。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image34.png) + +你可以通过下面的命令安装 OpenCode: + +```bash +# Linux / Unix +curl -fsSL https://opencode.ai/install | bash + +# Windows +npm i -g opencode-ai +``` + +#### 使用 OpenCode 中的免费模型 + +在 OpenCode 中不定期会提供免费模型可以进行使用, 配置也非常简单。你可以在你需要使用 OpenCode 的位置在命令行输入 `opencode` 启动 Opencode 程序进入聊天面板。输入 `/models`命令搜索 free 关键词就可以看到带有 free 字眼的免费模型 + +![](/zh-cn/stage-2/backend/modern-cli/images/image35.png) + +在一般情况下免费模型完成编码任务会比付费 / 订阅模型要慢一些,这通常取决于模型线路是否阻塞, 是否编码高峰期以及模型本身的能力。 + +#### 使用第三方模型来作为 OpenCode 的主编码模型 + +这是 OpenCode 的核心优势, 它可以在使用同样的 MCP, Skills, 上下文的情况下允许你自由切换模型来完成不同的编码任务。下文以 OpenAI 官方的 GPT-5.3 Codex 为例,接入 OpenCode 作为主编码模型。 + +在 OpenCode 的聊天窗口中输入 `/connect` 命令选中第一条最相关指令按下 enter 键,就可以进行选择第三方模型提供商的认证授权。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image36.png) + +这里以选择 OpenAI 为例,进行回车选择认证方式。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image37.png) + +选哪种都可以,只是认证方式不同。这里选择第一种进行浏览器登录。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image38.png) + +复制此链接到浏览器上进行正常的 OpenAI 登录操作,浏览器上出现 Authorization Successful 后 OpenCode 客户端会自动跳转至选择 OpenAI 的模型界面。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image39.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image40.png) + +#### 安装 Oh My OpenAgent 插件 + +OpenCode 的强大之处还在于他有非常活跃的社区生态,你可以在 Github 上搜索出非常多与 OpenCode 相关的插件。如果说 OpenCode 是一款可以任意切换模型的 AI 协作工具的话,那么 Oh-My-OpenAgent 就是一款运行在 OpenCode 之上的 "多 Agent AI 编程指挥系统"。它可以将一个复杂任务拆给多个子任务分给不同的模型进行各司其职的工作。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image41.png) + +你可以将以下话术复制之后粘贴给上文在 OpenCode 中配置好的模型进行安装 OpenCode。 + +```text +Install and configure oh-my-openagent by following the instructions here: +https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md +``` + +以下是 Oh-My-OpenAgent 的特性以及功能说明。 + +| 特性 | 功能说明 | +| :-------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **自律军团 (Discipline Agents)** | Sisyphus 负责调度 Hephaestus、Oracle、Librarian 和 Explore。一支完整的 AI 开发团队并行工作。 | +| **Team Mode** (v4.0, 选择性启用) | 领导 Agent + 最多 8 个并行成员,实时 tmux 可视化,专用 `team_*` 工具家族。驱动 `hyperplan`(5 个敌对评论者) 和 `security-research`(3 个猎手 + 2 个 PoC 工程师)。[文档 →](docs/guide/team-mode.md) | +| **`ultrawork` / `ulw`** | 一键触发,所有智能体出动。任务完成前绝不罢休。 | +| **[IntentGate 意图门](https://factory.ai/news/terminal-bench)** | 真正行动前,先分析用户的真实意图。彻底告别被字面意思误导的 AI 废话。 | +| **基于哈希的编辑工具** | 每次修改都通过 `LINE#ID` 内容哈希验证、0% 错误修改。灵感来自 [oh-my-pi](https://github.com/can1357/oh-my-pi)。[The Harness Problem →](https://blog.can.ac/2026/02/12/the-harness-problem/) | +| **LSP + AST-Grep** | 工作区级别的重命名、构建前诊断、基于 AST 的重写。为 Agent 提供 IDE 级别的精度。 | +| **后台智能体** | 同时发射 5+ 个专家并行工作。保持上下文干净,随时获取成果。 | +| **内置 MCP** | Exa(网络搜索)、Context7(官方文档)、Grep.app(GitHub 源码搜索)。默认开启。 | +| **Ralph Loop / `/ulw-loop`** | 自我引用闭环。达不到 100% 完成度绝不停止。 | +| **Todo 强制执行** | Agent 想要摸鱼?系统直接揪着领子拽回来。你的任务,必须完成。 | +| **注释审查员** | 剔除带有浓烈 AI 味的冗余注释。写出的代码就像老练的高级工程师写的。 | +| **Tmux 集成** | 完整的交互式终端支持。跑 REPL、用调试器、用 TUI 工具,全都在实时会话中完成。 | +| **Claude Code 兼容** | 你现有的 Hooks、命令、技能、MCP 和插件?全都能无缝迁移过来。 | +| **技能内嵌 MCP** | 技能自带其所需的 MCP 服务器。按需开启,不会撑爆你的上下文窗口。 | +| **Prometheus 规划师** | 动手写代码前,先通过访谈模式做好战略规划。 | +| **`/init-deep`** | 在整个项目目录层级中自动生成 `AGENTS.md`。不仅省 Token,还能大幅提升 Agent 理解力。 | + +Sisyphus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) 是你的主指挥官。他负责制定计划、分配任务给专家团队,并以极其激进的并行策略推动任务直至完成。他从不半途而废。 + +Hephaestus (gpt-5.5) 是你的自主深度工作者。你只需要给他目标,不要给他具体做法。他会自动探索代码库模式,从头到尾独立执行任务,绝不会中途要你当保姆。名副其实的正牌工匠。 + +Prometheus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) 是你的战略规划师。他通过访谈模式,在动一行代码之前,先通过提问确定范围并构建详尽的执行计划。 + +了解完这些, 你就可以使用装好 Oh-My-OpenAgent 插件之后的 OpenCode 来完成编码任务了。 + +## CLI AI 编程工具的更多用法 + +### 用 AI 写需求文档:学会“具体化需求” + +对于大语言模型来说,抽象需求需要被“具体化”。比如:“我很饿”是一个抽象需求,我们需要把它变成:“我肚子有点饿,可能需要吃一个红豆面包,再配一杯豆浆。”——这才是一种可以被执行的、具体的需求。 + +但把抽象需求变具体,其实是一个很花精力的过程。如果我们没有见过足够多的案例,很难快速联想到该如何把抽象问题拆解成细致的模块。这种时候,最好的办法就是让 AI 帮你完成“具体化”这一步。 +比如,我想开发一个“每日计划”应用,最朴素的想法可能是: + +`Please help me write a daily planning app where I can write my plans each day and get reminders.` + +AI 确实可以在这个需求基础上直接拆分任务,然后一步步完成,但中间容易出错或理解偏差。为了降低风险,我们可以让 AI 帮我们先扩写需求: + +`Based on my needs, please elaborate and provide a more detailed Product Requirement Document for reference. My idea is: Please help me write a daily planner app that supports daily plan-writing and provides reminders .` + +这时,AI 可能会给出类似下面这样完整的 PRD: + +``` +Product Requirements Document (PRD): “Today’s Plan” App +Document Version: 1.0 +Creation Date: October 27, 2023 +Author: (Your Name/Product Manager) + +1. Product Introduction +1.1 Product Name +Today's Plan +1.2 Product Vision +“Today’s Plan” is a minimalist and highly efficient daily planning and reminder tool, dedicated to helping users eliminate procrastination and forgetfulness, plan every day clearly, and ensure tasks are carried out through an intelligent reminder system—ultimately enabling users to gain a stronger sense of control and achievement over their time. +1.3 Target Users (User Personas) +We mainly serve three types of users: +Students (Xiao Ming): +Characteristics: Multiple tasks such as courses, assignments, club activities, exam prep, needing organized time arrangement. +Pain Points: Easily forget small tasks or assignment deadlines; feel overwhelmed switching between tasks; want to build regular study and life habits. +Needs: A simple tool to list daily to-dos and provide reminders before class/self-study. +Office Workers (Zhang Wei): +Characteristics: Fast-paced work, many meetings, reports, project milestones, and personal affairs (fitness, picking up children). +Pain Points: Easily forget important meetings or work milestones; get interrupted by urgent tasks and forget the original plan; feel busy but inefficient at end of day. +Needs: Need a tool to quickly record and schedule daily work and send strong reminders at key times (e.g., 15 minutes before meetings). +Freelancers/Self-disciplined Seekers (Li Na): +Characteristics: High freedom of time, but strong self-management required for work output and personal growth. +Pain Points: Easily procrastinate, lack external supervision; start the day without a clear plan, leading to low time utilization. +Needs: Need a tool to help build a daily fixed routine (Morning Routine) and review daily achievements for positive feedback. + +2. User Stories +As a user, I want to quickly create today’s plan list so I have an overview of all my tasks for the day. +As a user, I want to set specific start and end times for each task so I can create a visual timeline. +As a user, I want to receive push notification reminders before a task starts so I won’t miss any important arrangements. +As a user, I want to customize the reminder time (such as 5, 15, or 60 minutes in advance) so reminders better fit my habits. +As a user, I want to easily mark completed tasks so I can feel accomplished and clearly see my progress. +As a user, I want to see a summary of my completed plans at the end of each day for reviewing and self-motivation. +As a user, I want to conveniently edit and delete tasks to handle last-minute changes. +As a user, I want to view plans and achievements from previous days to review my efficiency and habits. + +3. Feature Breakdown +Core Features (MVP - Minimum Viable Product) +Module 1: Plan Management +3.1.1 Daily Plan Homepage +Interface: “Today” as the core view, current date shown at the top. +View: Timeline list, clearly showing tasks scheduled from morning to evening. Tasks without a time can be listed in the top or bottom “To-do List” section. +Interactions: +Click the “+” button in the bottom right to quickly create a new task. +Pull down to refresh the page. +Swipe left/right to view yesterday’s and tomorrow’s plans. +3.1.2 Create/Edit Task +Entry: Click “+” on the homepage or a time slot in the list. +Fields: +Task title (required): Briefly describe the task, e.g., “10 AM Weekly Product Meeting.” +Task time (optional): +Set “start time” and “end time.” +Provide “all-day” option for unspecified time tasks. +Default time picker should be quick and convenient. +Reminder setting (required, with default value): See Module 2. +Notes (optional): Add further descriptions, links, or location info. +Actions: Save, cancel, delete task. +3.1.3 Task Interaction +Mark as complete: Checkbox before each task; checking adds a strikethrough and gray background, indicating completion. Can unmark if needed. +Edit task: Click the task itself to enter edit page. +Delete task: Swipe left on a task to reveal “Delete” button. +Module 2: Smart Reminder System +3.2.1 Reminder Trigger +Mechanism: Based on task’s set “start time” and the user’s “reminder lead time,” send a push notification from device. +Offline Support: Locally scheduled reminders must trigger even if user is offline. +3.2.2 Reminder Content & Format +Notification title: App name “Today’s Plan.” +Body: “Reminder: [Task Title] will start at [Start Time].” E.g., “Reminder: Product Meeting will start at 10:00.” +Sound: Use system default or offer several simple, effective tones. +3.2.3 Reminder Settings +Global Settings (in Settings page): +User can set a default reminder time, e.g., “15 minutes before task starts.” New tasks adopt this by default. +Single Task Settings (in create/edit page): +Users can override global settings for important tasks, choosing specific reminder times like "on time," "5 minutes early," "30 minutes early," or "1 hour early." +Provide “no reminder” option. +Subsequent Features (V1.1, V2.0) +3.3 Daily Review & Statistics +Push a summary notification at a set time every night (e.g., 22:00): “How was your day? Take a look at your achievements!” +Generate a simple daily report card: shows total planned tasks, completed tasks, completion rate, plus an encouraging message. +3.4 History Review +Calendar view to click on any past day and check its plans and completion status. Days with high completion rates marked with a special color. +3.5 Templates +Allow users to save a successful daily plan as a template, e.g., “Efficient Workday,” “Relaxing Weekend.” +When creating tomorrow’s plan, one-click import a template, modify slightly to save time. +3.6 Themes & Personalization +Offer dark mode. +Allow changing several primary color themes. + +4. Non-Functional Requirements +4.1 Performance +Response: App launch time under 2 seconds; adding/editing tasks must be smooth and lag-free. +Resource Use: Low battery and memory consumption in background; do not over-consume resources waiting for reminders. +4.2 Usability +Minimal & intuitive: UI must be minimal, primary functions accessible within 3 clicks. No tutorial needed for new users. +Error tolerance: Offer undo (e.g. brief undo after mistakenly deleting a task). +4.3 Reliability +Reliable reminders: Reminder function is the product’s lifeline; must guarantee 99.99% timely and accurate delivery. +Data loss-free: User plans must be reliably stored locally. Future versions can support cloud sync to prevent data loss on device change. +4.4 Compatibility +Platform: Support major iOS and Android versions (latest 3-4 releases). +Screen: Layout must fit various phone screen sizes. + +5. Roadmap +V1.0 (MVP): +Goal: Validate core value—planning & reminders. +Features: Complete all “Core Features” described above (Plan management, smart reminders). +V1.1 (Quick Optimization): +Goal: Improve retention and achievement. +Features: Add “Daily Review & Statistics,” “History Review.” +V2.0 (Enhanced Experience): +Goal: Increase efficiency and personalization. +Features: Add “Templates,” “Themes & Personalization,” and start developing “Cloud Sync.” +``` + +对比我们最开始那句“帮我写一个每天可以记计划并提醒的应用”,现在这份文档已经详细得多了。你可以根据自己的真实需求,对其中的内容进行增删修改;对于某些你不确定的模块,也可以继续让 AI 提供更多备选方案,你再挑选、合并成最终版本。 + +通过这种方式,我们可以很轻松地把抽象想法变成具体描述。对 AI 开发来说,“具体”就是生产力:需求越具体,越容易得到结构稳定、质量较高的项目。你可以尝试用这种方式重做一下之前的某个小项目,对比一下效果差异。 + +如果你觉得这类“需求提示词”太长,非常自然的做法,是把它单独写进一个 markdown 文档中,作为你的“需求文档 / 开发文档 / PRD”。之后每次让 AI 写项目时,只需要让它“参考这份文档”,而不是每次都重打一遍长提示。你也可以在迭代中不断完善这份文档,让后续项目直接受益。 + +下面是一些其他常见的使用场景: + +### 管理文件夹 + +我们可以尝试用 CLI AI 编程工具来管理当前文件夹中的各种文件。比如,你有一堆杂乱无章的文件,需要整理归类,就可以对 Claude Code 或 Codex 说: + +`Please help me organize the contents of the current folder. I want to group files with the same content together & I want to group files from the same time period together. Please help me handle this.` + +### 开发新项目 + +这和我们之前在 z.ai、Trae 中的用法几乎完全一样——我们也可以直接用 CLI AI 编程工具来从零开发新项目。当然,最好提前准备好一份需求文档。 + +需求文档越细致,最终效果越好。你可以根据不断变化的想法,对文档做多轮优化;文档越完善,代码实现就越稳定、越成熟。 + +### Despliegue开源项目(例如 Dify) + +对于刚接触计算机的同学来说,从 GitHub 上Despliegue一个开源项目往往很有难度。但我们完全可以把这件事交给 Claude Code,就像我们在 Dify 教程中做的那样: + + + +如果我想在本地跑起自己的 Dify,只需要把这个链接扔给 Claude Code,然后输入: + +`I want to deploy this GitHub project ``https://github.com/langgenius/dify`` . Please help me clone the project and run it.` + +收到你的请求后,Claude Code 会自动完成一系列操作,包括从 GitHub 拉取代码、配置运行环境、启动项目等。如果中间某一步出错或项目启动状态不正常,你再根据提示进行少量人工处理即可。除了 Dify,你也可以用 Claude Code 帮你Despliegue大部分常见的 GitHub 开源项目——你只需要一个对话框,再加上喝一杯咖啡的时间 ☕️。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image31.png) + +### 讲解代码与撰写文档 + +对于一些复杂项目,或者 AI 自动生成的大型项目,你可能会觉得代码太长、逻辑太多,很难看懂。这时就可以让 CLI AI 编程工具帮你“读代码”。你可以这样提问: + +- 请帮我解释这个项目:如何运行、如何使用、后续如何修改和继续开发? +- 请帮我说明这个项目的整体流程:程序是怎样运行的?用户在界面中可以做哪些操作? +- 请帮我为这个项目写一份完整的文档,包括开发文档和运行文档等。 +- 请基于我当前文件夹里的所有内容,写一份详细说明,并保存到指定的 markdown 文档中。 + +### 更多玩法 + +当然,CLI AI 编程工具能做的远不止上面这些。不要只把它当作“写代码工具”,而是把它看作一个具有独立行动能力的智能 Agent。你可以让它帮你: + +- 管理和整理本地文件; +- 写日记、写总结; +- 分析和修复系统错误; +- 执行各种重复性命令行任务等。 + +也许在不久的将来,它会变成你电脑上最重要、也最懂你的 AI 伙伴。 diff --git a/docs/es-es/stage-2/backend/stripe-payment/index.md b/docs/es-es/stage-2/backend/stripe-payment/index.md new file mode 100644 index 0000000..90dcf0d --- /dev/null +++ b/docs/es-es/stage-2/backend/stripe-payment/index.md @@ -0,0 +1,907 @@ +# 如何集成 Stripe 等收费系统 + +当你的产品已经有了页面、登录、数据库和基础后端之后,下一个现实问题就是:**怎么收费**。 + +很多人第一次接支付,会把注意力全放在"怎么跳转到付款页"上。但真正决定系统是否稳定的,不是按钮,而是整条收费链路:谁决定价格、谁确认支付成功、谁更新数据库、谁回收权限。 + +这篇文章我帮你拆成两部分: + +- **前半部分**只讲最实用的基础接入,目标是让你尽快把 Stripe 接进项目。 +- **后半部分**统一放到附录,包含 Webhook 细节、订阅事件、不同国家和地区的支付方案差异。 + +> 💡 建议先学完这些章节再继续 +> +> - [从数据库到 Supabase](../database-supabase/) +> - [大模型辅助编写接口代码与接口文档](../ai-interface-code/) +> - [如何Despliegue Web 应用](../zeabur-deployment/) + +# Lo que aprenderas + +1. 最小可行的支付系统到底长什么样。 +2. 如何用最快的方式把 Stripe 接进你的项目。 +3. 如何写提示词,让 AI 直接帮你加支付系统。 +4. 如果不是做海外 Stripe 项目,不同地区应该优先考虑什么支付方案。 + +--- + +# Primera parte:基础上手 + +## 1. 先记住 3 个原则 + +如果你只记住三件事,就记住下面这三条: + +1. **价格必须由后端决定**,不能相信前端传来的金额。 +2. **真正让权限生效的是 Webhook**,不是 `success` 页面。 +3. **你自己的数据库必须保存支付状态**,不能只依赖 Stripe 后台。 + +这三条是支付系统最核心的边界。只要边界没错,后面换 Stripe、PayPal、支付宝、微信支付,本质上都只是"接口换了,架构不变"。 + +## 2. 如果不在后端处理,而是前端直接连 Stripe,会怎么样? + +这是很多人第一次做支付时最自然的想法: + +- 页面上已经有"购买"按钮了 +- 那我能不能让前端自己去连 Stripe +- 这样是不是就不用做后端了 + +如果你只是做一个假的演示页面,这样想当然没问题。 +但如果你是真的要收钱,**这条路通常会把事情做坏**。 + +最常见的问题有这几个: + +1. **价格容易被改** + 浏览器里的请求,是用户自己电脑上发出去的。别人是可以改请求内容的。 +2. **敏感信息容易暴露** + 真正重要的密钥、价格逻辑、会员开通逻辑,本来就不该放在前端。 +3. **你没法可靠确认"这笔钱到底算不算成功"** + 用户跳到成功页,不代表你的数据库已经同步对了。 +4. **数据库状态会乱** + 用户可能说"我明明已经付钱了",但你自己的系统里根本没记上。 + +所以更安全的分工应该是: + +- 前端负责:展示按钮、发起购买、跳转页面 +- 后端负责:决定价格、创建支付会话、接收 Webhook、更新数据库 + +::: info 这一段你可以直接记成一句话 +**前端可以负责跳转,后端必须负责定价和确认。** + +只要是真收钱,就不要把"最终价格决定权"和"支付成功后的开通逻辑"放在前端。 +::: + +## 3. 什么时候适合先用 Stripe + +如果你做的是下面这些场景,Stripe 往往是最顺手的起点: + +- 面向海外用户的 SaaS +- 订阅制会员产品 +- 数字产品、模板、AI 积分包 +- 想先快速验证商业化,而不是一开始就处理太多本地支付细节 + +如果你的主要用户在中国大陆,那通常不会把 Stripe 当第一选择,这个我放到附录里统一讲。 + +## 4. 最小可行支付链路 + +先看最小版本。只要这条链路能跑通,你的支付系统就有了骨架。 + +```mermaid +flowchart LR + user["用户"] + frontend["前端页面"] + backend["你的后端"] + checkout["Stripe Checkout"] + webhook["Stripe Webhook"] + db["Supabase / 业务数据库"] + + user -->|"点击购买"| frontend + frontend -->|"请求创建支付会话"| backend + backend -->|"按后端价格创建 Session"| checkout + frontend -->|"跳转到支付页"| checkout + checkout -->|"支付完成后发送事件"| webhook + webhook -->|"校验签名并更新状态"| backend + backend -->|"写入 orders / subscriptions"| db + db -->|"前端刷新后读取最新状态"| frontend +``` + +把它翻译成人话就是: + +1. 用户点按钮。 +2. 前端找后端要支付链接。 +3. 后端用 Stripe 密钥创建支付会话。 +4. 用户去 Stripe 页面付款。 +5. Stripe 把"付款真的成功了"这件事通过 Webhook 通知你。 +6. 你的后端再去更新数据库。 + +## 5. 发起付款的标准时序图 + +如果你习惯看更规范的系统图,可以直接看这张时序图: + +```mermaid +sequenceDiagram + autonumber + actor User as 用户 + participant Frontend as 前端页面 + participant Backend as 后端 API + participant Stripe as Stripe Checkout + + User->>Frontend: 点击"升级"或"购买" + Frontend->>Backend: POST /api/billing/create-checkout-session + Note right of Frontend: 前端传 plan / userId / email\n不传最终收费金额 + Backend->>Backend: 校验套餐并映射 priceId + Backend->>Stripe: 创建 Checkout Session + Stripe-->>Backend: 返回 session.url + Backend-->>Frontend: 返回支付链接 + Frontend-->>User: 跳转到 Stripe 支付页 + User->>Stripe: 完成付款 +``` + +## 6. 快速开始 + +如果你想最快把它接进项目,照着下面这 5 步做就够了。 + +### 6.1 第一步:在 Stripe 后台创建商品和价格 + +这一步的目的,不是"先随便配点东西",而是先把 **你到底在卖什么、打算怎么收费** 这件事在 Stripe 里定义清楚。 + +在 Stripe 的模型里: + +- **Product** 表示"你卖的是什么",比如 `Pro 会员` +- **Price** 表示"这个东西卖多少钱、按什么周期卖",比如 `月付 9.9 美元`、`年付 99 美元` + +为什么要先做这一步? +因为后面当你的后端创建 Checkout Session 时,并不是直接传一个金额给 Stripe,而是要传一个已经存在的 `price_id`。Stripe 再根据这个 `price_id` 去生成真正的支付页、金额、币种和订阅周期。 + +如果你跳过这一步,后面的"创建支付链接"其实就没法做。 + +::: info 为什么这里要先停一下 +很多新手看到 `Product`、`Price` 这两个词会有点烦,觉得像是在学 Stripe 的内部术语。 + +但实际上,这一步是在做一件很朴素的事: +- 把"卖什么"定义清楚 +- 把"卖多少钱"定义清楚 +- 让后端之后能拿一个稳定的 `price_id` 去创建支付链接 + +只要把这层想明白,后面的 Checkout Session 就不会觉得抽象。 +::: + +对于一个最小可行的订阅系统,你至少先建这两个层级: + +- 一个 `Product` +- 一个或多个 `Price` + +你可以直接打开这些页面: + +- Stripe Dashboard 登录页:[Dashboard Login](https://dashboard.stripe.com/login) +- Stripe 商品与价格管理文档:[Manage products and prices](https://docs.stripe.com/products-prices/manage-prices) +- Stripe Checkout 快速开始文档:[Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- Stripe Dashboard 商品页:[Product catalog](https://dashboard.stripe.com/test/products) + +推荐你先在 **Test mode(测试模式)** 下操作,不要一开始就在正式环境里建。 + +一个最常见的最小配置是: + +- `Product`: `Pro Plan` +- `Price 1`: `pro_monthly` +- `Price 2`: `pro_yearly` + +你在后台操作时,可以按这个顺序理解: + +1. 先创建一个商品 `Pro Plan` +2. 再在这个商品下面挂两个价格 +3. 月付和年付其实是同一个商品的两种收费方式 + +完成后,你至少要记下这些信息: + +- 月付价格的 `price_id` +- 年付价格的 `price_id` +- 你自己的套餐名,例如 `pro_monthly`、`pro_yearly` + +如果你是第一次进 Stripe 后台,建议你把这一步理解成: + +- `Product` 决定支付页里卖的是什么 +- `Price` 决定支付页里收多少钱 +- 后端之后真正会用到的,主要是 `price_id` + +::: info 真正要记下来的值 +这一页里最重要的不是商品名称,而是 `price_id`。 + +后面无论是让 AI 帮你接后端,还是你自己排查问题,真正会频繁用到的,通常都是: +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- 它们背后对应的两个 `price_id` +::: + +如果你想让 AI 先带你把后台配置做完,可以直接用这个 prompt: + +```text +我现在是第一次用 Stripe,你先不要改代码,先带我在 Stripe 后台把最基本的付费配置做好。 + +请基于这些官方文档给我一步一步的操作说明: +- https://docs.stripe.com/products-prices/manage-prices +- https://docs.stripe.com/checkout/quickstart?lang=node + +我的情况是: +- 我想做一个最简单的会员付费 +- 只有两个套餐:月付和年付 +- 我现在还不懂 Product、Price 这些词 + +请你: +1. 先用最简单的话告诉我 Product 和 Price 分别是什么。 +2. 再按"先打开哪个页面 -> 点哪里 -> 填什么"的顺序教我操作。 +3. 最后提醒我,做完以后我需要从后台复制哪些内容给El backend usa。 +4. 如果我容易走错,请顺便提醒我应该一直在测试模式里操作。 +``` + +### 6.2 第二步:准备环境变量 + +你通常至少需要准备这些环境变量: + +- `STRIPE_SECRET_KEY` +- `STRIPE_WEBHOOK_SECRET` +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- `APP_URL` +- `SUPABASE_URL` +- `SUPABASE_SERVICE_ROLE_KEY` + +你可以直接打开这些页面: + +- Stripe API Keys 文档:[API keys](https://docs.stripe.com/keys) +- Stripe Dashboard API Keys 页面:[API Keys](https://dashboard.stripe.com/test/apikeys) +- Stripe Webhooks 文档:[Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Stripe Dashboard Webhooks 页面:[Workbench Webhooks](https://dashboard.stripe.com/test/workbench/webhooks) + +> ⚠️ `STRIPE_SECRET_KEY` 和 `SUPABASE_SERVICE_ROLE_KEY` 都只能放在后端。 + +::: info 环境变量这一步的目的 +这一步不是为了"先把 `.env` 填满",而是为了把支付系统里最敏感的几样东西放到后端保管: + +- Stripe 的后端密钥 +- Webhook 验签密钥 +- 你自己的价格映射 + +简单理解: +前端只负责发起购买,真正的秘密和定价逻辑都应该留在服务端。 +::: + +这一步也可以直接让 AI 帮你整理: + +```text +请你先看看我这个项目现在是怎么放环境变量的,然后帮我把 Stripe 需要的环境变量整理出来。 + +请参考这些文档: +- https://docs.stripe.com/keys +- https://docs.stripe.com/webhooks + +我的情况是: +- 我是零基础 +- 我分不清哪些变量应该放前端,哪些应该放后端 +- 我也不确定当前项目应该改 `.env`、`.env.local` 还是别的文件 + +请你: +1. 先搜索当前项目里环境变量通常写在哪。 +2. 帮我列出 Stripe 接入最少需要哪些变量。 +3. 用最简单的话告诉我每个变量是干什么的。 +4. 告诉我每个变量应该去哪一个 Stripe 页面复制。 +5. 如果项目里有示例环境变量文件,请直接帮我补上变量名。 +``` + +### 6.3 第三步:后端创建 Checkout Session + +这一步你不用自己写接口,直接让 AI 参考官方文档帮你实现。 + +先把这些文档给它: + +- Stripe Checkout 快速开始:[Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- Checkout Sessions API:[Create a Checkout Session](https://docs.stripe.com/api/checkout/sessions/create) +- 订阅说明:[Subscriptions](https://docs.stripe.com/payments/subscriptions) + +然后直接贴这个 prompt: + +```text +请你先看看我当前项目的后端代码是怎么组织的,然后帮我把 Stripe 支付接进去。 + +请参考这些官方文档: +- https://docs.stripe.com/checkout/quickstart?lang=node +- https://docs.stripe.com/api/checkout/sessions/create +- https://docs.stripe.com/payments/subscriptions + +我的目标很简单: +- 用户点购买按钮后,能跳到 Stripe 的付款页面 +- 套餐只有月付和年付两种 +- 不要让我自己决定代码该放在哪,你先看项目再帮我放到合适的位置 + +请你: +1. 先搜索项目,弄清楚后端入口文件、路由文件、环境变量写法分别在哪里。 +2. 再参考官方文档,帮我把"创建 Stripe 支付链接"这一步接进去。 +3. 不要让我自己传金额,价格请用后端环境变量来决定。 +4. 做完后告诉我你改了哪些文件。 +5. 最后告诉我,我还需要去 Stripe 后台补哪些配置。 +``` + +### 6.4 第四步:前端跳转到支付页 + +这一步的目标非常简单:让定价页按钮调用你的后端接口,再跳转到 Stripe Checkout。 + +参考文档: + +- Stripe Checkout 集成说明:[Build an integration with Checkout](https://docs.stripe.com/payments/checkout/build-integration) + +给 AI 的 prompt: + +```text +帮我把项目里的"购买"按钮接上 Stripe。 + +要求: +- 不动现有页面,只改按钮点击后的逻辑 +- 点击后调用后端接口获取支付链接,然后跳转到 Stripe +- 如果出错,给用户一个简单提示(比如"支付暂时不可用,请稍后再试") + +参考文档:https://docs.stripe.com/payments/checkout/build-integration +``` + +### 6.5 第五步:Webhook 更新数据库状态 + +这是最关键的一步。 + +::: info 为什么这一步最关键 +很多人会以为"用户付完款并且跳转到了 success 页面"就算完成了。 + +不是。 + +对你的系统来说,真正重要的是: +**Stripe 有没有正式把事件打到你的 Webhook,而你的后端有没有把数据库状态更新成功。** +::: + +你也可以让 AI 按 Stripe 官方 Webhook 文档直接实现,不要自己手写。 + +参考文档: + +- Stripe Webhooks:[Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Stripe CLI:[Stripe CLI](https://docs.stripe.com/stripe-cli) +- Stripe CLI 用法:[Use the Stripe CLI](https://docs.stripe.com/stripe-cli/use-cli) + +给 AI 的 prompt: + +```text +请继续帮我把 Stripe 的"付款成功后自动生效"这一步接好。 + +请参考这些官方文档: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +我的目标是: +- 用户付完钱后,不只是跳转到成功页面 +- 而是真的把我数据库里的会员状态改成已开通 + +请你: +1. 先搜索当前项目里数据库相关代码和用户状态是怎么存的。 +2. 再帮我加 Stripe webhook。 +3. 支付成功后,把对应用户改成 active,或者更新成项目里现在已经在用的会员状态字段。 +4. 如果项目里已经有订阅表、订单表、用户表,请优先沿用现有结构。 +5. 做完后告诉我你改了哪些文件。 +6. 顺便告诉我本地怎么测试这一步有没有真的生效。 +``` + +## 7. 让 AI 帮你快速接入的提示词 + +如果你用的是 Codex、Claude Code、Trae、Cursor 一类工具,可以直接把下面这个提示词贴给它,让它在你的项目里做支付接入。 + +```text +请你帮我把当前项目接上 Stripe 支付,我希望做一个最简单能跑起来的会员收费功能。 + +我的要求: +1. 我是零基础,请你先自己看项目,再决定代码应该改哪里。 +2. 不要让我自己判断目录结构、路由结构、数据库结构。 +3. 我只想先做最简单版本:月付和年付两个套餐。 +4. 用户点击购买后,能跳到 Stripe 付款页面。 +5. 付款成功后,我数据库里的会员状态能变成已开通。 +6. 不要一开始加太多复杂功能,比如优惠券、升级降级、复杂发票。 + +输出要求: +1. 先给我一个改动计划。 +2. 然后直接修改代码。 +3. 最后告诉我怎么一步一步本地测试。 +4. 如果有哪个步骤还需要我去 Stripe 后台操作,请直接把链接和要点告诉我。 +``` + +如果你希望 AI 更贴近你的项目,还可以在开头补上: + +- 你的前端框架 +- 你的后端目录结构 +- 你的数据库表名 +- 你现在的用户系统是 Supabase Auth 还是自建 Auth + +## 7.1 本地联调也尽量交给 AI + +如果你希望连本地联调都让 AI 帮你串起来,可以直接用下面这段: + +```text +请继续帮我把 Stripe 支付真正跑通,我想一步一步照着做,不想自己猜。 + +请参考官方文档: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +我的目标: +1. 告诉我先打开哪些 Stripe 页面。 +2. 告诉我如何拿到 STRIPE_WEBHOOK_SECRET。 +3. 告诉我如何使用 stripe login 和 stripe listen。 +4. 告诉我怎样验证 checkout.session.completed 已经成功打到本地 webhook。 +5. 如果当前项目需要先启动前端和后端,也请顺带告诉我具体命令。 +6. 不要只讲原理,请按实际操作步骤输出。 +7. 如果我某一步做错了,也请告诉我最常见的报错会长什么样。 +``` + +## 8. 最容易踩坑的 4 件事 + +1. **把 `success` 页面当成支付成功** + 真正决定状态的是 Webhook,不是前端跳转。 +2. **让前端传金额** + 这会带来严重的价格篡改风险。 +3. **Webhook 路由被 `express.json()` 提前处理** + Stripe 验签需要原始请求体。 +4. **没有做幂等处理** + Webhook 可能重试,如果你每次都重复加会员或积分,就会出事故。 + +## 9. 一句话选型建议 + +如果你现在只是想先把收费跑起来: + +| 你的主要用户 | 最先尝试的方案 | +| :--- | :--- | +| 海外 SaaS / 国际用户 | Stripe | +| 中国大陆用户 | 支付宝 / 微信支付 | +| 香港或跨境团队 | Stripe + 本地钱包 / FPS 聚合方案 | + +后面的具体区别,我统一放到附录。 + +::: info 最简单的选型思路 +不要一开始就想"我要把全球支付方式一次全接完"。 + +更实际的顺序通常是: +- 先按主要用户所在地区选一条主支付链路 +- 先把最小可行支付跑通 +- 再根据真实用户来源补第二、第三种支付方式 +::: + +## 10. 小结 + +到这里,你已经掌握了最基础但最重要的一条收费链路: + +1. 前端发起购买。 +2. 后端创建 Checkout Session。 +3. 用户在 Stripe 页面支付。 +4. Stripe 通过 Webhook 通知后端。 +5. 后端更新数据库。 +6. 前端刷新后显示新的会员或订单状态。 + +如果你只想快速把支付接进项目,前面的内容已经够用了。下面的附录你可以在真正遇到问题时再回来看。 + +--- + +# 附录 + +## 附录 A:Stripe 里最常见的几个对象 + +第一次看 Stripe 文档,最容易被这些对象名绕晕。你其实只需要先理解下面几个: + +| 对象 | 作用 | 你可以把它理解成什么 | +| :--- | :--- | :--- | +| `Product` | 描述卖的是什么 | 商品或会员套餐 | +| `Price` | 描述卖多少钱、周期怎么收费 | 月付、年付、买断 | +| `Checkout Session` | Stripe 托管的支付流程 | 付款页 | +| `Subscription` | 周期订阅关系 | 自动续费会员 | +| `Customer` | 付款用户 | Stripe 中的客户档案 | +| `Webhook` | 异步通知 | Stripe 告诉你"这笔款怎么样了" | + +## 附录 B:为什么 `success` 页面不等于支付成功 + +很多人以为"用户付完钱,跳到了 success 页面"就算支付成功了。这是最容易踩的坑。 + +### 先讲一个真实场景 + +假设你做了一个会员网站: +1. 用户点击"购买会员" +2. 跳转到 Stripe 付款页面 +3. 用户输入信用卡,点击付款 +4. 页面跳转到你的 `success.html` +5. 你在 success 页面写代码:"既然到了这页,就给用户开通会员" + +**问题在哪?** + +用户可能根本没付钱,或者付到一半关页面了,也能直接访问 `success.html`。 + +### 两条完全不同的路径 + +```mermaid +flowchart TB + pay["用户在 Stripe 完成支付"] + + subgraph unreliable["❌ 不可靠路径:只看 success 页面"] + success["浏览器跳到 success 页面"] + fake["前端代码认为已开通"] + risk["风险:关页 / 断网 / 伪造 URL / 根本没付钱"] + success --> fake --> risk + end + + subgraph reliable["✅ 可靠路径:以后端 Webhook 为准"] + event["Stripe 服务器发送 Webhook"] + verify["后端校验签名"] + active["数据库正式更新为已付费"] + event --> verify --> active + end + + pay --> success + pay --> event +``` + +**关键区别:** + +| | success 页面跳转 | Webhook 通知 | +| :--- | :--- | :--- | +| 谁发起的 | 用户的浏览器 | Stripe 的服务器 | +| 能伪造吗 | 能,直接访问 URL 就行 | 不能,有签名验证 | +| 一定代表付款成功吗 | 不一定 | 一定 | +| 你的系统怎么知道 | 前端代码猜的 | Stripe 正式通知的 | + +### 完整流程应该是怎样的 + +```mermaid +sequenceDiagram + autonumber + actor User as 用户 + participant Frontend as 你的网页 + participant Stripe as Stripe + participant Webhook as 你的后端接口 + participant DB as 数据库 + + User->>Stripe: 在 Stripe 页面完成付款 + Note over Stripe: 钱真的到了 Stripe 账户 + + Stripe-->>Frontend: 浏览器跳转到 success 页面 + Note over Frontend: ⚠️ 这步只是跳转
不代表系统已确认 + + Stripe->>Webhook: 发送 Webhook 通知
"checkout.session.completed" + Note over Webhook: ✅ 这才是正式通知 + + Webhook->>Webhook: 校验签名
(确保是 Stripe 发的,不是黑客) + + Webhook->>DB: 更新用户状态为"已付费" + DB-->>Webhook: 保存成功 + Webhook-->>Stripe: 返回 200 OK + + Frontend->>DB: 用户刷新页面,查询状态 + DB-->>Frontend: 返回"已付费" + Note over Frontend: 这时候才显示会员功能 +``` + +### 每个环节的卡点 + +**第 1 步:用户在 Stripe 付款** + +这是唯一确定"钱真的付了"的时刻: +- 用户输入信用卡信息,点击确认 +- 银行从用户卡里扣款 +- Stripe 确认收到这笔钱 + +**第 2 步:浏览器跳转到 success 页面(问题最大)** + +这一步完全不可靠,因为: +- 用户可以直接在浏览器输入 `yoursite.com/success`,根本没付钱也能访问 +- 用户付到一半关页面了,但之前复制了 success 链接,之后直接打开 +- 网络问题导致跳转失败,但钱已经扣了(用户付了钱却没看到成功页面) +- 用户点返回键,又付了一次钱,但两次都跳转到同一个 success 页面 + +**第 3 步:Stripe 发送 Webhook** + +这是 Stripe 主动通知你的服务器"这笔款到账了": +- 只有 Stripe 的服务器能发起这个请求 +- 请求里带有签名,你的后端可以验证是不是真的 Stripe 发的 +- 即使 success 页面没打开、用户断网了,Webhook 也会发送 + +**第 4 步:后端校验签名** + +为什么要校验?防止黑客伪造通知。 + +假设没有校验,黑客可以直接给你的服务器发一个假通知:"用户 A 付了 1000 元"。你的系统就会给黑客开通会员。 + +校验的过程: +- Stripe 用你们约定的密钥对通知内容生成签名 +- 你的后端用同样的密钥验证签名是否匹配 +- 匹配 = 100% 是 Stripe 发的,不匹配 = 直接拒绝 + +**第 5 步:更新数据库** + +只有校验通过后,才更新数据库: +- 把用户状态从"待付款"改成"已付费" +- 记录订单号、金额、付款时间 +- 开通对应的会员权限 + +**第 6 步:前端查询状态** + +success 页面不要自己判断"到了这页就是成功了"。正确的做法: +- 页面加载时,向后端发送请求:"这个用户付费了吗?" +- 后端查数据库,返回真实状态 +- 根据返回结果显示"开通成功"或"等待确认" + +### 一个常见的错误做法 + +```javascript +// 错误:在 success 页面直接开通 +// success.html +if (window.location.pathname === '/success') { + // 危险!任何人都能访问 /success + activateMembership(); +} +``` + +```javascript +// 正确:每次刷新都查后端 +// success.html +async function checkStatus() { + const response = await fetch('/api/user/status'); + const data = await response.json(); + + if (data.paymentStatus === 'paid') { + showMemberFeatures(); + } else { + showPendingMessage(); + } +} +``` + +### 总结一句话 + +**success 页面只是"浏览器跳转成功",Webhook 才是"Stripe 正式确认收款"。** + +你的系统必须以 Webhook 为准,不能相信前端的跳转。 + +## 附录 C:订阅系统最值得监听的事件 + +| 事件 | 含义 | 你通常要做什么 | +| :--- | :--- | :--- | +| `checkout.session.completed` | 首次开通成功 | 创建本地订阅记录 | +| `invoice.paid` | 自动续费成功 | 延长有效期 | +| `invoice.payment_failed` | 自动扣费失败 | 标记风险状态并提醒用户 | +| `customer.subscription.deleted` | 订阅取消 | 回收权限或标记到期后失效 | + +### 订阅状态图 + +```mermaid +stateDiagram-v2 + [*] --> NotStarted: 用户未购买 + NotStarted --> Active: checkout.session.completed + Active --> Active: invoice.paid + Active --> PastDue: invoice.payment_failed + PastDue --> Active: 用户补款成功 + Active --> Canceled: customer.subscription.deleted + PastDue --> Canceled: 到期未恢复 + Canceled --> [*] + + state "未开通" as NotStarted + state "会员有效" as Active + state "扣费失败 / 待恢复" as PastDue + state "已取消 / 到期回收" as Canceled +``` + +### 续费 / 失败 / 取消时序图 + +```mermaid +sequenceDiagram + autonumber + participant Stripe as Stripe + participant Webhook as 你的 Webhook 接口 + participant DB as 订阅表 / 订单表 + participant App as 你的应用 + actor User as 用户 + + rect rgb(235, 248, 255) + Stripe->>Webhook: invoice.paid + Webhook->>DB: 延长 current_period_end + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 继续保持会员有效 + end + + rect rgb(255, 247, 237) + Stripe->>Webhook: invoice.payment_failed + Webhook->>DB: 标记 past_due + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 提醒更新支付方式 + end + + rect rgb(254, 242, 242) + Stripe->>Webhook: customer.subscription.deleted + Webhook->>DB: 标记 canceled + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 停止高级权限 + end +``` + +## 附录 D:其他支付方案怎么选 + +### 1. 中国大陆 + +主要用户在大陆的话,首选还是 **[支付宝](https://open.alipay.com/)** 和 **[微信支付](https://pay.wechatpay.cn/)**。 + +**业务模式:** + +两者都是"支付网关"模式。你需要: +- 申请商户资质(营业执照、对公账户) +- 用户付的钱直接到你的商户账户 +- 你自己负责税务、退款、对账 + +**技术模式:** + +两者都是"后端下单 + 前端调起 + 后端通知"的模型,跟 Stripe 思路一样。 + +**支付宝接入流程:** +1. 在支付宝开放平台创建应用 +2. 配置公私钥和回调地址 +3. 后端调用统一下单接口,生成支付链接或二维码 +4. 用户扫码或跳转付款 +5. 支付宝异步通知你的后端,更新订单状态 + +**微信支付接入流程:** +- JSAPI 支付:适合公众号、小程序,用户在微信内直接付款 +- Native 支付:PC 端生成二维码,用户扫码付款 +- H5 支付:手机浏览器内拉起微信 App 付款 + +流程:后端下单 → 拿到 `prepay_id` 或 `code_url` → 前端调起支付 → 后端接收通知确认成功 + +**参考链接:** +- 支付宝开放平台:https://open.alipay.com/ +- 微信支付商户文档:https://pay.wechatpay.cn/doc/v3/merchant/ + +### 2. 香港 + +香港市场比较混合,常见组合: + +- 银行卡:Visa / Mastercard +- FPS(转数快):香港本地即时转账 +- AlipayHK / WeChat Pay HK:香港版支付宝和微信 + +**推荐组合:** +- 用 **[Stripe](https://stripe.com/hk)** 覆盖国际卡和订阅 +- 用 **[Airwallex](https://www.airwallex.com/)** 或 **[Adyen](https://www.adyen.com/)** 补本地钱包和 FPS + +### 3. 海外 / 国际 SaaS + +#### [Stripe](https://stripe.com/) + +**业务模式:** 支付网关 + +- 你需要自己申请商户资质(部分国家 Stripe 可以帮你搞定) +- 用户付的钱到你的 Stripe 账户,再结算到你的银行账户 +- 你自己负责税务申报 + +**技术模式:** + +- API 体验最好,文档清晰 +- 支持 Checkout(托管页面)、Elements(自定义表单)、Payment Links(无代码) +- Webhook 通知支付状态 +- 支持订阅、发票、多币种 + +**适合谁:** 海外 SaaS、独立开发者、需要灵活定制的团队 + +**参考链接:** https://docs.stripe.com/ + +#### [PayPal](https://www.paypal.com/) + +**业务模式:** 支付网关 + +- 用户付的钱到你的 PayPal 账户,再提现到银行 +- 你自己负责税务 + +**技术模式:** + +- 一次性支付:前端放按钮,后端创建/确认订单 +- 订阅制:先建 Product 和 Plan,再用 SDK 拉起 +- 同样需要后端和 Webhook,不要只看前端回调 + +**适合谁:** 需要补充渠道的海外业务,用户习惯用 PayPal 付款 + +**参考链接:** https://developer.paypal.com/docs/ + +#### [Paddle](https://www.paddle.com/) + +**业务模式:** Merchant of Record (MoR) + +- Paddle 是"记录商家",法律上由 Paddle 向用户收款 +- Paddle 帮你处理全球税务、VAT、退款、合规 +- 用户付的钱到 Paddle,Paddle 扣除税费和手续费后结算给你 +- 你不需要在每个国家注册公司或处理税务 + +**技术模式:** + +- Paddle.js:前端嵌入托管结账页 +- 后端 API:创建 transaction,交给 checkout 处理 +- Webhook 同步订阅状态 + +**适合谁:** 不想处理全球税务的 SaaS 团队,尤其是 B2B SaaS + +**参考链接:** https://developer.paddle.com/ + +#### [Lemon Squeezy](https://www.lemonsqueezy.com/) + +**业务模式:** Merchant of Record (MoR) + +- 和 Paddle 类似,Lemon Squeezy 是"记录商家" +- 帮你处理全球税务、VAT、合规 +- 2024 年被 Stripe 收购,但独立运营 + +**技术模式:** + +- Hosted Checkout:最简单,直接生成付款链接 +- Checkout Overlay:浮层嵌入你的页面 +- 后端 API:创建 checkout,灵活控制 + +**适合谁:** 独立开发者、数字产品、软件授权 + +**参考链接:** https://docs.lemonsqueezy.com/ + +### 4. 企业级方案 + +#### [Airwallex(空中云汇)](https://www.airwallex.com/) + +**业务模式:** 支付网关 + 全球账户 + +- 提供全球收款账户(类似虚拟银行账户) +- 支持多币种收款、换汇、付款 +- 你自己负责税务 + +**技术模式:** + +- Payment Links:几乎不用代码,生成付款链接 +- Hosted Payment Page:托管页面 +- Drop-in / Embedded / Native API:深度接入,自定义程度高 +- 支持 Alipay HK、FPS、WeChat Pay 等本地支付方式 + +**适合谁:** 香港团队、跨境业务、需要多币种账户的公司 + +**参考链接:** https://www.airwallex.com/docs/ + +#### [Adyen](https://www.adyen.com/) + +**业务模式:** 支付网关 + +- 企业级支付平台,年处理交易额万亿欧元 +- 支持线上、线下、移动端全渠道 +- 你自己负责税务 + +**技术模式:** + +- Pay by Link:最简单,生成付款链接 +- Drop-in / Components:标准线上接入 +- 后台可启用 Alipay、Alipay HK、PayMe 等本地支付方式 + +**适合谁:** 大型企业、需要全渠道支付的公司 + +**参考链接:** https://docs.adyen.com/ + +### 5. 方案对比 + +| 方案 | 业务模式 | 税务处理 | 适合谁 | +| :--- | :--- | :--- | :--- | +| Stripe | 支付网关 | 自己处理 | 海外 SaaS、开发者 | +| PayPal | 支付网关 | 自己处理 | 海外补充渠道 | +| Paddle | MoR | Paddle 代处理 | B2B SaaS、不想管税务 | +| Lemon Squeezy | MoR | LS 代处理 | 独立开发者、数字产品 | +| Adyen | 支付网关 | 自己处理 | 大型企业 | +| Airwallex | 支付网关 + 账户 | 自己处理 | 跨境业务、香港团队 | +| 支付宝/微信 | 支付网关 | 自己处理 | 大陆用户 | + +### 6. 按地区选方案 + +| 你的市场 | 推荐方案 | +| :--- | :--- | +| 中国大陆 | 支付宝 / 微信支付 | +| 香港 | Stripe + Airwallex / Adyen | +| 海外 SaaS | Stripe(自己管税务)或 Paddle(MoR 代管) | +| 海外数字产品 | Stripe / Lemon Squeezy / Paddle | +| 多地区企业级 | Adyen / Airwallex / Stripe 组合 | diff --git a/docs/es-es/stage-2/backend/zeabur-deployment/index.md b/docs/es-es/stage-2/backend/zeabur-deployment/index.md new file mode 100644 index 0000000..7c040d9 --- /dev/null +++ b/docs/es-es/stage-2/backend/zeabur-deployment/index.md @@ -0,0 +1,490 @@ +# 如何Despliegue Web 应用 + +在本教程中,我们将介绍如何将你的 Web 应用Despliegue到互联网上,让其他人可以访问。我们会介绍三个常用的Despliegue平台:**腾讯云 CloudBase**、**Vercel** 和 **Zeabur**,帮助你快速完成从"写好代码"到"让别人可以在互联网上访问你的网站"的完整流程。 + +# 什么是"Despliegue"? + +在开始之前,我们先弄清楚"Despliegue(Deployment)"到底是什么意思。任何一个网站想要被外部用户访问,都必须有一个可以公开访问的网络地址(这个地址可以是 IP 地址,比如 123.45.67.89,也可以是域名,比如 [google.com](https://google.com/) 等)。但只有地址是不够的——你写好的网页代码(例如 HTML、CSS、JavaScript 文件,或者使用 React、Vue 等框架写的项目),以及相关的图片 / 视频资源,都必须"放"在一台 24 小时在线的服务器上,由它来响应网络请求,这样任何人的浏览器才能访问并下载这些资源。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image1.png) + +图片来源:https://www.hostinger.com/tutorials/what-is-cloud-hosting + +把资源上传、配置好环境并让服务"跑起来"的整个过程,就被称为 **Despliegue(Deployment)**。 + +简单来说:你在自己电脑上写好的网页,只要在本机启动程序,就只能通过本地地址在自己的浏览器里访问,因为这些代码只存在于你的硬盘上。"Despliegue"就是把你的代码和资源转移到一台连接着公网的专业服务器上,并做好配置,让这台服务器知道"别人访问时我要怎么响应"——比如:当有人在浏览器中输入你的域名时,服务器会立刻找到对应的网页文件,把内容传回给对方的设备,从而让用户看到你的页面。 + +如果手动Despliegue,一个项目往往需要好几个步骤,每一步都可能踩坑。常见关键步骤包括: + +1. **服务器准备**:你需要先购买云服务器(比如阿里云、腾讯云、或 AWS EC2),选择服务器所在地区(如上海、新加坡)、配置(CPU、内存、磁盘大小等),还要学会如何远程连接服务器(例如通过 SSH 工具登录)。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image2.png) +2. **环境配置**:Web 应用需要在特定"环境"中才能运行——例如运行 Node.js 项目必须先安装 Node.js;运行 Python 项目必须安装 Python 以及对应的第三方库。如果环境版本不匹配,程序就可能报错、无法启动。 +3. **上传资源**:你需要把本地的代码和资源上传到服务器上,常用的方法包括 FTP 或 Git。如果项目体积比较大(比如包含视频文件),中途一旦断线,有时需要重新上传。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image3.png) + +4. **启动服务并测试**:上传完成后,你还需要在服务器上执行命令启动应用,并测试"分配的网络地址是否能访问"。如果访问不了,有可能是服务器防火墙没有放行对应端口(比如你的应用监听 3000 端口,但该端口被防火墙拦截),也可能是程序本身有 Bug,这时就需要查看服务器日志进行排查。 + > 💡 可以把端口理解为区分同一台设备上不同应用的"房间号",而 IP 则是这台设备的"门牌号"。IP 和端口合在一起(IP:port),就可以精确定位到某一个网络服务。 +5. **维护与更新**:后续每次你修改代码,都要重新上传并重启服务。如果服务器宕机(例如断电、网络故障),还需要手动重启应用,有时还要额外配置"进程守护工具",让程序在异常退出后自动拉起。 + +像 CloudBase、Vercel、Zeabur 这样的"低代码Despliegue平台",就是为了解决上述复杂问题而诞生的。它们会帮你自动完成"买服务器、配环境、上传代码、启动服务、监控运行"等步骤。你只需要把自己的代码仓库(比如 GitHub 或 GitLab)连接到平台,或者直接上传代码,它就会自动拉取代码、识别应用类型、配置对应的运行时环境,最后给你一个可以被任何人访问的公网地址。它甚至可以一键绑定你自己的域名。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image4.png) + +接下来,我们会分别介绍这三个平台的特点和使用方法,帮助你选择最适合自己的Despliegue方案。 + +--- + +# Despliegue平台对比 + +| 平台 | 特点 | 适用场景 | 免费额度 | +|------|------|----------|----------| +| **腾讯云 CloudBase** | 国内访问速度快,与微信生态深度整合 | 国内用户为主、需要微信小程序支持的项目 | 有免费额度 | +| **Vercel** | 前端框架支持好,与 GitHub 集成紧密 | React/Vue/Next.js 等现代前端项目 | 有免费额度 | +| **Netlify** | 功能全面,支持表单处理和身份验证,与 Git 集成好 | 需要表单处理、身份验证等高级功能的静态网站 | 有免费额度 | +| **Zeabur** | 支持多种语言和服务模板,配置灵活 | 需要Despliegue多种服务(如 Dify、n8n)的复杂项目 | 每月约 5 美元免费额度 | + +--- + +# 1. 腾讯云 CloudBase + +腾讯云 CloudBase(云开发)是腾讯云提供的一站式后端云服务,特别适合国内开发者使用。它的优势在于: + +- **国内访问速度快**:服务器位于国内,访问延迟低 +- **微信生态整合**:可以方便地对接微信小程序、公众号 +- **一站式解决方案**:提供静态网站托管、云函数、数据库、存储等全套服务 +- **免费额度充足**:个人开发者有充足的免费资源额度 + +## 使用 CloudBase Despliegue Web 应用 + +### 步骤 1:注册并登录 + +访问 [腾讯云 CloudBase 控制台](https://console.cloud.tencent.com/tcb),使用微信或 QQ 登录。 + +### 步骤 2:创建环境 + +点击"新建环境",选择一个环境名称(如 `my-web-app`)。 + +> ⚠️ **注意**:CloudBase 的免费体验版需要兑换码才能开通。你需要关注腾讯云 CloudBase 公众号,在公众号中输入"领取兑换码"获取免费体验版的兑换码,然后在创建环境时填写兑换码即可开通免费环境(免费试用期为 6 个月)。 + +### 步骤 3:开通静态网站托管 + +在环境管理页面,找到"静态网站托管"功能并开通。开通后你会获得一个默认的访问域名。 + +CloudBase 的静态网站托管提供多种Despliegue方式,与 Zeabur 类似: + +- **本地项目上传**:直接从本地上传构建好的静态文件(HTML、CSS、JS 等) +- **模板Despliegue**:使用预设模板快速创建项目,如 React Web 应用模板、Vue Web 应用模板 +- **Git 仓库Despliegue**:支持从 GitHub 等代码仓库自动拉取代码并Despliegue + +### 步骤 4:Despliegue代码 + +在静态网站托管页面,CloudBase 提供三种Despliegue方式: + +**方式一:本地项目Despliegue(本地项目上传)** +- 在控制台选择"本地项目Despliegue" +- 直接上传构建好的静态文件(HTML、CSS、JS 等) +- 选择你本地构建好的项目文件夹(如 `dist` 或 `build` 目录) +- 等待上传完成即可访问 + +**方式二:模板Despliegue** +- 使用预设模板快速创建项目 +- 支持 React Web 应用模板、Vue Web 应用模板等 +- 基于模板自动构建并Despliegue + +**方式三:Git 仓库Despliegue** +- **Git 个人仓库Despliegue**:绑定你的 GitHub 等个人代码仓库 +- **公开仓库Despliegue**:支持从公开的 Git 仓库拉取代码 +- 配置自动构建命令(如 `npm run build`) +- 每次推送代码会自动重新Despliegue + +> 💡 **提示**:你也可以使用 CLI 工具进行Despliegue: +> ```bash +> # 安装 CloudBase CLI +> npm install -g @cloudbase/cli +> # 登录 +> tcb login +> # Despliegue +> tcb hosting deploy ./dist -e your-env-id +> ``` + +### 步骤 5:配置自定义域名(可选) + +在静态网站托管设置中,可以绑定你自己的域名,并申请免费的 HTTPS 证书。 + +--- + +# 2. Vercel + +Vercel 是全球最流行的前端Despliegue平台之一,特别适合Despliegue React、Vue、Next.js 等现代前端框架项目。它的特点包括: + +- **与 GitHub 深度集成**:推送代码即自动Despliegue +- **自动预览**:每个 Pull Request 都会生成独立的预览链接 +- **全球 CDN**:网站自动分发到全球节点,访问速度快 +- **Serverless 函数**:支持在项目中编写后端 API + +> ⚠️ **注意**:Vercel 在部分网络环境下访问可能不太稳定,国内用户建议优先考虑 CloudBase。 + +## 使用 Vercel Despliegue Web 应用 + +### 步骤 1:注册账号 + +访问 [Vercel 官网](https://vercel.com),使用 GitHub 账号登录。 + +### 步骤 2:导入项目 + +1. 点击 "Add New Project" +2. 选择你要Despliegue的 GitHub 仓库 +3. 如果没有看到想要的仓库,点击 "Adjust GitHub App Permissions" 授权访问 + +### 步骤 3:配置构建设置 + +Vercel 会自动识别项目类型并配置构建命令: + +| 框架 | 构建命令 | 输出目录 | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Next.js | `next build` | - | +| 纯 HTML | - | 项目根目录 | + +如果自动识别不正确,可以手动修改: +- **Build Command**: 构建命令,如 `npm run build` +- **Output Directory**: 构建输出目录,如 `dist` 或 `build` +- **Install Command**: 依赖安装命令,通常是 `npm install` + +### 步骤 4:Despliegue + +点击 "Deploy" 按钮,等待构建完成。构建成功后,你会获得一个 `xxx.vercel.app` 的域名。 + +### 步骤 5:自定义域名(可选) + +在项目设置中的 "Domains" 页面,可以添加你自己的域名。Vercel 会自动配置 HTTPS。 + +--- + +# 3. Netlify + +Netlify 是另一个非常流行的前端Despliegue平台,与 Vercel 类似,特别适合Despliegue静态网站和单页应用(SPA)。它的特点包括: + +- **功能全面**:除了静态网站托管,还支持表单处理、身份验证、边缘函数等高级功能 +- **与 Git 深度集成**:支持 GitHub、GitLab、Bitbucket,推送代码自动Despliegue +- **分支预览**:每个分支都会自动生成独立的预览链接 +- **全球 CDN**:网站自动分发到全球节点,访问速度快 +- **表单处理**:无需后端代码即可处理网站表单提交 +- **身份验证**:内置用户身份验证功能,可快速实现登录/注册 + +> ⚠️ **注意**:Netlify 的国内访问速度可能不如 CloudBase,建议主要面向海外用户的项目使用。 + +## 使用 Netlify Despliegue Web 应用 + +### 步骤 1:注册账号 + +访问 [Netlify 官网](https://www.netlify.com),点击 "Sign up" 注册。你可以使用 GitHub、GitLab、Bitbucket 或邮箱注册。 + +### 步骤 2:导入项目 + +1. 登录后点击 "Add new site" → "Import an existing project" +2. 选择你的代码托管平台(如 GitHub) +3. 授权 Netlify 访问你的仓库 +4. 从列表中选择你要Despliegue的仓库 + +### 步骤 3:配置构建设置 + +Netlify 会自动识别常见的前端框架并配置构建设置: + +| 框架 | 构建命令 | 发布目录 | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Angular | `ng build` | `dist/` | +| Next.js | `next build` | `out` | +| 纯 HTML | - | `.`(项目根目录) | + +如果自动识别不正确,可以手动配置: +- **Build command**: 构建命令,如 `npm run build` +- **Publish directory**: 构建输出目录,如 `dist` 或 `build` + +### 步骤 4:Despliegue + +点击 "Deploy site" 按钮,等待构建完成。构建成功后,你会获得一个 `xxx.netlify.app` 的域名,任何人都可以通过这个地址访问你的网站。 + +### 步骤 5:配置自定义域名(可选) + +1. 进入站点设置,点击 "Domain management" +2. 点击 "Add custom domain" +3. 输入你的域名并按照提示配置 DNS 记录 +4. Netlify 会自动申请并配置 HTTPS 证书 + +### 特色功能 + +#### 1. 表单处理 + +Netlify 提供了一个非常方便的功能:无需后端代码即可处理表单提交。 + +只需在 HTML 表单中添加 `netlify` 属性: + +```html +
+

+ +

+

+ +

+

+ +

+

+ +

+
+``` + +Despliegue后,表单提交的数据会自动发送到 Netlify 后台,你可以在 "Forms" 页面查看所有提交记录,也可以设置邮件通知或将数据转发到其他服务。 + +#### 2. Netlify Functions(边缘函数) + +Netlify 支持Despliegue无服务器函数(Serverless Functions),让你可以在不搭建完整后端服务器的情况下,实现简单的 API 接口。你可以使用 JavaScript 或 TypeScript 编写函数,Despliegue后会自动获得一个可访问的 URL。 + +例如,创建一个 `hello.js` 文件: + +```javascript +exports.handler = async (event, context) => { + return { + statusCode: 200, + body: JSON.stringify({ message: "Hello from Netlify!" }) + }; +}; +``` + +Despliegue后,你可以通过 `https://你的域名/.netlify/functions/hello` 访问这个函数。 + +#### 3. 本地开发支持 + +Netlify 提供了 CLI 工具,方便你在本地开发和测试: + +```bash +# 安装 Netlify CLI +npm install -g netlify-cli + +# 登录账号 +netlify login + +# 本地启动开发服务器 +netlify dev + +# 本地测试函数 +netlify functions:serve +``` + +使用 CLI 工具可以在本地模拟 Netlify 环境,包括表单提交、函数调用等功能,方便在Despliegue前进行测试。 + +--- + +# 4. Zeabur + +Zeabur 是一个新兴的Despliegue平台,特别适合需要Despliegue多种服务的复杂项目。它的优势在于: + +- **服务模板丰富**:内置 Dify、n8n、数据库等多种服务模板 +- **支持多种Despliegue方式**:GitHub、模板、Docker 镜像、本地项目等 +- **灵活的服务组合**:可以在一个项目中Despliegue多个相互关联的服务 +- **按量计费**:用多少付多少,适合实验性项目 + +## 使用 Zeabur Despliegue Dify + +在之前的课程中,我们已经简单接触过 Dify。现在,我们可以通过 [Zeabur](https://zeabur.com/projects) 非常轻松地启动自己的 Dify 服务。首先打开 [控制台页面](https://zeabur.com/projects),我们先看一下上面的各个区域。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image5.png) + +在这个页面上,你首先能看到许多方块,这些就是已经启动的服务。在顶部菜单中,你会看到 Agent、Servers、Docs、Templates 等几个选项,它们分别代表: + +1. **Agent**:可以打开 Zeabur 内置的智能助手(Agent),向它提问如何操作,或者查询当前服务器的状态。 +2. **Servers**:在这里可以添加你自己购买的云服务器,或者直接通过 Zeabur 购买服务器。 +3. **Docs**:查看 Zeabur 的完整文档说明。 +4. **Templates**:这里列出了所有内置的模板镜像。 + +> 这里提到的"镜像(Image)",可以理解为"包含代码和运行环境的压缩包"。当某个服务在一台服务器上成功跑起来之后,我们可以选择把"这套运行环境 + 代码"打包成镜像。之后,在任何新服务器上,只要把这个压缩包解压并运行,就不需要重新配置环境和代码,服务就能直接跑起来。 + +在页面右上角,你还能看到自己的余额。默认情况下,每个月会有 5 美元左右的免费额度。关于细节计费规则暂时可以不用太在意,只需要知道:只要服务器在运行,就会消耗额度。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image6.png) + +点击余额可以查看每日的消耗明细。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image7.png) + +现在我们来创建自己的 Dify 服务。首先,在 [控制台首页](https://zeabur.com/projects) 点击 "New Project"。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image8.png) + +接下来是各个创建方式的解释: + +1. **GitHub** + 可以连接到你的 GitHub 账号。绑定之后,就可以直接从 GitHub 仓库里选择项目Despliegue(GitHub 是目前全球最大的代码托管平台)。 +2. **Template(模板)** + 可以基于模板来Despliegue服务。Zeabur 内置了很多预设项目模板(例如 Dify、n8n 等),你可以基于这些模板快速创建并Despliegue应用。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image9.png) +3. **Databases(数据库)** + 用于Despliegue数据库服务,比如 MySQL、MongoDB 等常见数据库。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image10.png) +4. **Functions(函数)** + 可以Despliegue函数服务,你可以编写 JavaScript 或 Python 代码,让它们以函数的形式被调用。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image11.png) + + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image12.png) + +5. **Local Project(本地项目)** + 上传一个本地文件夹,Zeabur 会自动识别其中的启动脚本。这适合将你已经在本地开发好的项目快速Despliegue到 Zeabur 上。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image13.png) +6. **Docker Image** + Despliegue已经打包好的 Docker 镜像。如果你的项目已经被打成了 Docker 镜像(例如存放在 Docker Hub 或其他镜像仓库中),可以在这里直接Despliegue。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image14.png) +7. **Cursor** + 如果你安装了 Cursor(例如 Cursor IDE),可以通过这个入口将 Cursor 中的项目直接Despliegue到 Zeabur。 + +如果你想Despliegue自己的 Dify 服务,推荐选择 **Template** 方式,然后在搜索框中输入 "dify"。可以看到很多由不同作者维护的版本,你可以任选其一(比如 v1.6.0 版本)。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image15.png) + +接着,输入任意一个名称,Zeabur 会基于这个名称生成一个临时的自定义域名。之后所有人都可以通过这个网址访问你的服务。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image16.png) + +创建完成后,你会看到多个程序(服务)依次启动。需要耐心等待所有服务都进入"已启动"状态。(Dify 服务是由多个程序组成的,每个程序负责不同的功能,它们之间会相互协作。) + +一般来说,你只需要点击左侧的 Dify 应用,就可以看到默认的访问入口地址。但在本例中,由于前面还套了一层 nginx,你需要点击 nginx 服务来获取最终访问地址。可以理解为:nginx 就是负责对外统一"收发请求"的主程序,它会把外部访问的地址分发给内部各个服务。点击左侧的 Nginx,在详情页中可以看到当前的服务地址,然后在浏览器里打开这个地址,等待服务完全启动。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image17.png) + +稍等片刻后,你就能看到 Dify 的登录界面了。输入邮箱地址和注册密码,就可以开始使用你自己的 Dify 服务了。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image18.png) + +如果你有兴趣,还可以顺便启动一个 n8n 服务。n8n 也是海外非常流行的一款 AI 工作流平台。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image19.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image20.png) + +## 使用 Zeabur 与 Trae Despliegue贪吃蛇游戏 + +在本教程的下一个部分,我们会体验 Zeabur 的一些进阶用法。我们先用 Trae 生成一个贪吃蛇小游戏,再把它Despliegue到 Zeabur 的服务器上,并配置一个可公开访问的链接,让任何人都可以打开你的游戏。 + +第一步,是在本地使用 Trae 创建一个贪吃蛇项目。 + +### 使用 HTML 框架实现 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image23.png) + +对于 Trae 来说,生成一个基于 HTML 的贪吃蛇网页游戏非常简单。游戏生成完成后,你只需要按照前面介绍的 Zeabur 本地Despliegue方式,把包含所有文件的文件夹上传上去即可。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image24.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image25.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image26.png) + +完成后,你就会进入该服务的详情界面: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image27.png) + +点击左侧的 "Network" 选项,在页面中找到 "Public Address" 区域。点击 "Generate Domain",即可生成一个对外访问地址,你可以输入任意喜欢的名称。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image28.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image29.png) + +生成完成后,只要在浏览器中打开这个地址,就可以运行你自己的贪吃蛇游戏了。其它 HTML 类型的 Web 应用也可以用完全相同的方式来Despliegue。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image30.png) + +### 使用 React 框架实现 + +前面我们学习了如何Despliegue基于 HTML 的 Web 应用。接下来,我们再尝试Despliegue一个目前更常用的前端框架:React 应用。相比纯 HTML,React 被认为是一种更加成熟、现代的前端开发框架。它通过组件化的方式组织页面结构,能够显著加快复杂页面的开发,是企业级项目中非常主流的选择。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image31.png) + +#### 重构为 React 架构 + +在 Trae 中,你只需要向 Agent 说明:"帮我把这份代码重构成 React 架构",就可以比较轻松地把原本基于 HTML 的结构重构成 React 项目。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image32.png) + +不过,相比简单的 HTML 文件,React 应用依赖更复杂的构建工具和项目结构,因此Despliegue过程也会稍微麻烦一些。一个典型的问题体现在端口设置上:默认情况下,React 应用一般会监听 3000 端口(你也可以在配置文件或启动日志中看到这一点)。 + +然而,在 Zeabur 上这样Despliegue会失败——因为 Zeabur 只支持监听 8080 端口的应用。也就是说,如果想让 React 应用在 Zeabur 上正常运行,我们必须先把默认监听端口从 3000 改成 8080。 + +要正确进行这一步配置,我们需要先弄清楚两个概念:什么是"端口(Port)",以及"监听端口(Listening Port)"是什么意思。 + +#### 什么是端口? + +> 在计算机网络中,端口可以理解为一个"逻辑通信端点",用来区分同一台设备上运行的不同网络服务。简单类比的话,如果 IP 地址好比一个"门牌号"(例如 162.128.1.1),那端口号就像这栋楼里不同房间的"房间号"——每个房间对应一个服务(例如 Web 服务器、邮箱服务,或者你的 React 应用)。 +> +> 端口号用 16 位整型表示,取值范围是 0 到 65535。 + +如果不想记这些细节,可以简单理解:端口是构成"网络访问地址"的一个必要部分。 + +我们平时访问网站或 IP 地址时,通常不会手动加端口号,是因为 Web 的默认端口是 80 或 443(HTTPS)。大多数浏览器会自动使用这些标准端口。而对于一些特殊端口,比如 React 默认的 3000、Zeabur 要求的 8080,我们就必须在地址后面加上 `:3000` 或 `:8080` 才能访问到对应的内容。 + +#### 什么是"监听端口号"? + +> "监听端口号"指的是某个程序在一台设备上主动"打开并监控"的端口。当一个应用设置了监听端口时,其实就是在告诉操作系统:"我会一直在这个端口上等待网络请求——只要有请求进来,就请转发给我。" + +再形象一点地理解:假设你的电脑是一栋写字楼,IP 地址是这栋楼的地址。楼里开了很多公司或部门,它们分别占用不同的房间,房间号就是端口号。 + +当默认的 React 开发服务器启动时,它会"打开"某个房间的门,并安排"前台"在门口值班,这个房间号就是它的监听端口——3000。 + +同时,React 程序还会告诉这栋楼的"物业管理"(操作系统):"我在 3000 号房间,请把所有寄给 3000 的信件(网络请求)都转给我。" + +这样,当你访问 React 网站时,请求首先会到达这栋楼;物业看到请求要送到 3000 号房间,就会立刻把请求交给 React 的"前台",由它来处理并返回结果——这就是访问 React 应用的过程。 + +当你在本地执行 `npm start`(本地启动 React 开发服务器的默认命令,也可以在 Vibe Coding 的 Agent 侧边栏中执行)时,React 开发服务器就会自动把监听端口设置为 3000。 +而 Zeabur 的平台设计决定了它只会"识别"监听 8080 端口的应用。如果你的 React 应用仍然使用默认的 3000 端口,Zeabur 就无法将请求正确转发给你的应用,最终导致Despliegue失败。 + +#### 修改默认监听端口 + +要把 React 默认监听端口(3000)改成 Zeabur 所要求的 8080,有很多做法。最简单的方式,就是直接在 Trae 里对 Agent 下指令:"请帮我把这个 React 项目的默认端口改为 8080。"Trae 就会帮你修改项目中对应的配置文件。修改完成后,你只需重新打包并按前面的方式上传到 Zeabur 即可。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image33.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image34.png) + +在网络设置中指定一个访问 URL,方式和Despliegue HTML 项目时基本相同,就可以启动 React 版本的服务。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image35.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image36.png) + +对于其它需要修改端口号的程序,你也可以采用同样的思路:先改默认端口,再上传到 Zeabur Despliegue。至此,你已经掌握了将常见 Web 应用Despliegue到服务器的基础技能。 + +你可以尝试让 Trae 帮你构建不同类型的应用,并把它们Despliegue到 Zeabur 的默认服务器上。在后续课程中,我们还会学习如何把应用Despliegue到你自己购买的云服务器上。 + +--- + +# ⚠️ 如何停止和删除项目(Zeabur) + +由于启用服务器相关资源都会产生费用,我们在使用时一定要养成"及时关闭不用服务"的习惯,避免把每个月的免费额度消耗完。 + +如果要找到项目的管理入口,首先点击项目中的 "Settings" 选项。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image21.png) + +进入设置页面后,将页面拉到最下方,你会看到类似下面的界面: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image22.png) + +你可以点击 "Suspend All Services" 来暂停所有服务以降低费用;如果服务出现问题,可以点击 "Restart All Services" 对全部服务进行重启。如果你确定不再需要这个项目,可以点击 "Delete Project" 将整个项目彻底删除。 + +--- + +# 总结 + +在本教程中,我们介绍了四个常用的 Web 应用Despliegue平台: + +1. **腾讯云 CloudBase**:适合国内用户,访问速度快,与微信生态整合好 +2. **Vercel**:适合现代前端框架项目,与 GitHub 集成紧密,全球 CDN 加速 +3. **Netlify**:功能全面,支持表单处理和身份验证,适合需要高级功能的静态网站 +4. **Zeabur**:适合复杂项目,服务模板丰富,支持多种Despliegue方式 + +选择哪个平台取决于你的具体需求: +- 如果主要面向国内用户,推荐 **CloudBase** +- 如果使用 React/Next.js 等框架,推荐 **Vercel** 或 **Netlify** +- 如果需要表单处理、身份验证等高级功能,推荐 **Netlify** +- 如果需要Despliegue Dify、n8n 等服务,推荐 **Zeabur** + +无论选择哪个平台,Despliegue的核心流程都是相似的:准备代码 → 选择平台 → 配置构建设置 → Despliegue上线。掌握这些技能后,你就可以将自己开发的应用分享给全世界了! diff --git a/docs/es-es/stage-2/frontend/design-to-code/index.md b/docs/es-es/stage-2/frontend/design-to-code/index.md new file mode 100644 index 0000000..b0a1aec --- /dev/null +++ b/docs/es-es/stage-2/frontend/design-to-code/index.md @@ -0,0 +1,361 @@ +# 从设计原型到项目代码 + +::: tip 🎯 核心问题 +**如何将设计工具中的原型转化为真正能在浏览器里运行的前端代码?** +::: + +--- + +## 1. 从原型到代码的三种路径 + +在使用 Figma、MasterGo 等现代前端设计工具完成界面设计后,一个很实际的问题自然会浮现:这些看起来结构完整的设计稿,要怎么转化成真正能在浏览器里运行的前端代码? + +一般而言,从原型到代码的落地,本质上有三种典型路径: + +| 路径 | 方法 | 特点 | 适用场景 | +|------|------|------|----------| +| **路径一** | 根据图片,使用多模态大模型直接还原出代码 | 灵活、无需特定工具 | 快速原型验证、简单页面 | +| **路径二** | 通过平台自身能力或插件导出可用代码 | 还原度高、可编辑性强 | Figma/MasterGo 用户 | +| **路径三** | 平台结合 MCP 能力导出可用代码 | 自动化程度高、可定制 | 需要深度集成的工作流 | + +本文将详细介绍这三种路径的具体实现方法,帮助你根据项目需求选择最合适的工作流。 + +::: tip 📚 Conocimientos previos +在开始本节之前,建议你先学习 [Figma 与 MasterGo 入门](../figma-mastergo/) 教程,掌握前端设计工具的基础操作。 +::: + +--- + +## 2. 路径一:多模态 AI 直接还原代码 + +拥有视觉能力的大模型天生具备将图片转为代码的能力。我们只需要将设计稿截图直接导入对话框,随后让大模型生成完整的结果代码。 + +### 2.1 操作流程 + +1. **截取设计稿图片** + - 在 Figma 或 MasterGo 中,将设计好的页面导出为 PNG 或 JPG + - 确保截图包含完整的页面布局 + +2. **选择多模态 AI 模型** + - 可以使用 Gemini、Qwen、Claude 等支持图像输入的模型 + - 这里以 Gemini 为例进行演示 + +3. **编写提示词** + ``` + 请根据这张设计图生成对应的 HTML/CSS 代码。 + 要求: + - 使用现代 CSS 布局(Flexbox/Grid) + - 响应式设计,适配不同屏幕尺寸 + - 包含所有可见的 UI 元素 + - 颜色、字体大小尽量还原设计稿 + ``` + +![](/zh-cn/stage-2/frontend/design-to-code/images/image42.png) + +4. **获取并保存代码** + - 要求模型返回完整的 HTML 代码 + - 保存为单个 `.html` 文件,方便本地测试 + - 后续可以在本地 IDE 中将其转换为 React 等框架 + +### 2.2 常见问题与解决方案 + +生成页面并非简单的任务,在具体过程中你可能会遇到很多问题: + +| 问题 | 解决方案 | +|------|----------| +| 界面排布不均 | 向 AI 描述具体的布局问题,要求调整 CSS 的 margin/padding | +| 界面显示不全 | 检查是否设置了正确的 viewport,要求添加响应式断点 | +| 颜色还原不准 | 使用取色工具获取设计稿的精确色值,提供给 AI | +| 字体不匹配 | 指定具体的字体名称或要求使用 Google Fonts 替代 | + +::: tip 💡 小技巧 +推荐先生成 HTML 代码,获取后再使用本地 IDE 将其转换为 React 框架。这样可以获得多个独立的 HTML 文件,统一进行框架转换。 +::: + +### 2.3 MasterGo AI 生成页面 + +MasterGo 同样提供了强大的 AI 页面生成功能,可以根据参考图直接生成可用的网页代码。 + +#### 找到 AI 功能入口 + +在 MasterGo 编辑界面的上方工具栏中,可以找到 AI 工具按钮: + +![](/zh-cn/stage-2/frontend/design-to-code/images/image47.png) + +#### 生成流程 + +1. **上传参考图** + - 使用与多模态 AI 相同的方式上传设计参考图 + - 添加文字描述需求 + +2. **查看生成结果** + +![](/zh-cn/stage-2/frontend/design-to-code/images/image48.png) + +![](/zh-cn/stage-2/frontend/design-to-code/images/image49.png) + +3. **获取代码** + - 点击蓝色按钮"插入到画布",可直接编辑生成后的网页 + - 或点击右侧的"代码"按钮,复制代码内容到本地 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image50.png) + +--- + +## 3. 路径二:平台自身能力或插件导出代码 + +### 3.1 Figma Make 生成代码 + +Figma Make 是 Figma 官方推出的 AI 设计工具,能够根据用户输入的提示词或者参考图,高精度地还原网页原型 UI 界面。 + +#### 功能特点 + +- **高精度还原**:相比原生 AI 生成代码,效果更佳 +- **可编辑性**:生成结果可以转换为可编辑的 Figma Design 文件 +- **GitHub 集成**:支持直接将代码同步到 GitHub + +::: tip 🔑 权限说明 +使用 Figma Make 的完整功能需要 Pro 用户权限,学生可以通过教育认证免费获得 Pro 权限。 +::: + +#### 操作步骤 + +1. **进入 Figma Make** + - 在 Figma 首页点击 Make 按钮 + - 或者访问 [Figma Make](https://www.figma.com/make) + +2. **上传参考图** + - 将你想要还原的设计图上传到对话框 + - 添加描述需求的提示词 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image43.png) + +3. **查看生成结果** + - 稍等片刻后即可看到渲染结果 + - 点击右上角的播放按钮可进行全屏预览 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image44.png) + +4. **细节调整** + - 点击右上角的编辑器图标(鼠标和尺子图标) + - 回到熟悉的 Figma Editor 界面进行详细调整 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image45.png) + +5. **导出代码** + - 调整满意后,选择导出代码 + - 可以直接连接到 GitHub 保存代码 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image46.png) + +### 3.2 插件导出代码 + +除了平台原生的 AI 功能,Figma 和 MasterGo 都支持通过插件导出代码: + +**常用 Figma 插件:** +- **Figma to Code**:将设计稿转换为 React、Vue、HTML 等代码 +- **Anima**:高保真代码生成,支持交互效果 +- **Locofy**:AI 驱动的设计转代码工具 + +**使用步骤:** +1. 在 Figma 中打开插件面板(Plugins) +2. 搜索并安装需要的代码导出插件 +3. 选中要导出的设计元素 +4. 运行插件,选择目标框架和代码格式 +5. 复制或下载生成的代码 + +--- + +## 4. 路径三:平台结合 MCP 能力导出代码 + +### 4.1 什么是 MCP? + +MCP(Model Context Protocol,模型上下文协议)是一套开放标准协议,它允许 AI 模型安全、可控地访问外部工具和数据源。在前端设计工具的场景中,MCP 让大模型能够直接读取设计文件的结构、样式和组件信息,从而更精准地生成代码。 + +### 4.2 MCP 的工作原理 + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ AI 模型 │ ←→ │ MCP 服务器 │ ←→ │ 设计工具 │ +│ (Claude等) │ │ (协议适配) │ │(Figma/MasterGo)│ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +**工作流程:** +1. AI 模型通过 MCP 协议向设计工具发送请求 +2. 设计工具返回结构化的设计数据(图层、样式、组件等) +3. AI 模型理解设计结构并生成对应代码 +4. 代码可以直接导出或同步到开发环境 + +### 4.3 Figma + MCP 实战 + +#### 环境准备 + +1. **安装 MCP 服务器** + ```bash + # 使用 npx 安装 Figma MCP 服务器 + npx figma-mcp-server + ``` + +2. **配置 Claude Desktop 或其他支持 MCP 的 AI 工具** + ```json + { + "mcpServers": { + "figma": { + "command": "npx", + "args": ["figma-mcp-server"], + "env": { + "FIGMA_ACCESS_TOKEN": "your-figma-token" + } + } + } + } + ``` + +3. **获取 Figma Access Token** + - 登录 Figma → Settings → Personal Access Tokens + - 生成新的 Token 并保存 + +#### 使用流程 + +1. **在 AI 工具中启用 MCP 连接** + - 打开 Claude Code 或其他支持 MCP 的 IDE + - 确认 MCP 服务器已连接 + +2. **提供设计文件链接** + ``` + 用户:请帮我将这个 Figma 设计转换为 React 代码 + 链接:https://www.figma.com/file/xxxxx + + AI:我已通过 MCP 连接到 Figma,正在读取设计文件结构... + ``` + +3. **AI 自动分析并生成代码** + - MCP 服务器获取设计文件的图层树 + - AI 理解组件结构和样式属性 + - 生成带有正确命名和结构的 React/Vue 组件 + +4. **迭代优化** + ``` + 用户:请将按钮组件提取为独立的可复用组件 + + AI:好的,我已通过 MCP 识别到设计系统中的 Button 组件, + 正在生成带有 props 接口的 React 组件... + ``` + +### 4.4 MCP 的优势 + +| 特性 | 传统方式 | MCP 方式 | +|------|----------|----------| +| **数据精度** | 依赖截图,可能丢失细节 | 直接读取原始设计数据 | +| **组件识别** | AI 需要猜测组件边界 | 精确获取组件定义 | +| **样式还原** | 基于像素估算 | 获取精确的设计 token | +| **迭代效率** | 每次修改需重新截图 | 实时同步设计变更 | +| **自动化程度** | 手动复制粘贴 | 可直接写入项目文件 | + +### 4.5 当前可用的 MCP 工具 + +**设计工具 MCP:** +- **Figma MCP Server**:官方支持的 MCP 实现 +- **MasterGo MCP**:社区开发的 MasterGo 适配器 + +**开发环境 MCP:** +- **Claude Code**:原生支持 MCP 协议 +- **Cline**:VS Code 插件,支持 MCP 连接 +- **Trae**:可通过配置启用 MCP 功能 + +::: tip 🔮 未来展望 +MCP 协议正在快速发展,未来设计工具与开发环境的集成将更加紧密。预计会出现更多一键同步设计到代码的解决方案,进一步缩短设计与开发之间的距离。 +::: + +--- + +## 5. 代码导出后的工作 + +### 5.1 本地测试 + +获取代码后,在本地 IDE 中打开并进行测试: + +1. **创建新项目** + ```bash + # 如果是 HTML 文件,直接用浏览器打开 + open index.html + + # 如果是 React/Vue 项目 + npm install + npm run dev + ``` + +2. **与 AI IDE 协作** + - 将生成的代码导入 Trae 或其他 AI IDE + - 让 AI 帮助修复布局问题、添加交互功能 + +### 5.2 常见问题处理 + +| 阶段 | 问题 | 解决方案 | +|------|------|----------| +| 布局 | 元素错位 | 检查 CSS 的 display 和 position 属性 | +| 样式 | 颜色不一致 | 使用浏览器开发者工具检查实际应用的色值 | +| 响应式 | 移动端显示异常 | 添加 media query 断点 | +| 交互 | 按钮无响应 | 检查 JavaScript 事件绑定 | + +--- + +## 6. 三种路径对比与选择建议 + +### 6.1 路径对比 + +| 维度 | 路径一:多模态 AI | 路径二:平台能力 | 路径三:MCP | +|------|------------------|------------------|-------------| +| **上手难度** | ⭐ 简单 | ⭐⭐ 中等 | ⭐⭐⭐ 较复杂 | +| **还原精度** | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐ 高 | ⭐⭐⭐⭐⭐ 最高 | +| **灵活性** | ⭐⭐⭐⭐⭐ 高 | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐ 较高 | +| **自动化程度** | ⭐⭐ 低 | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐⭐ 高 | +| **成本** | 低(按 API 调用) | 中(可能需要 Pro) | 低(开源工具) | + +### 6.2 选择建议 + +**选择路径一(多模态 AI)如果:** +- 需要快速验证想法 +- 设计工具不固定,经常切换 +- 对还原精度要求不高 +- 预算有限 + +**选择路径二(平台能力)如果:** +- 团队主要使用 Figma 或 MasterGo +- 需要高精度的代码还原 +- 设计师和开发者需要频繁协作 +- 愿意投资 Pro 版本 + +**选择路径三(MCP)如果:** +- 追求最高程度的自动化 +- 有技术能力配置 MCP 环境 +- 项目需要频繁迭代设计到代码 +- 希望建立标准化的设计开发工作流 + +--- + +## 7. 总结 + +通过本章节的学习,你已经掌握了从设计原型到代码的三种核心路径: + +1. **多模态 AI 直接转换**:灵活快速,适合原型验证 +2. **平台原生能力**:还原度高,适合专业设计工作流 +3. **MCP 协议集成**:自动化程度最高,代表未来趋势 + +::: tip 💡 最佳实践 +- **新手推荐**:从路径一(多模态 AI)开始,快速上手 +- **团队协作**:使用路径二(平台能力),保证设计一致性 +- **效率优先**:尝试路径三(MCP),建立自动化工作流 +- **混合使用**:根据项目阶段灵活切换不同路径 +::: + +--- + +## 参考资源 + +- [Figma 与 MasterGo 入门](../figma-mastergo/) - 学习设计工具基础 +- [一起做霍格沃茨画像](../hogwarts-portraits/) - 完整项目实战 +- [MCP 官方文档](https://modelcontextprotocol.io/) - 了解协议详情 +- [Figma Make 官方文档](https://help.figma.com/hc/en-us/sections/360007453634-Figma-Make) +- [MasterGo AI 教程](https://mastergo.com/tutorials) diff --git a/docs/es-es/stage-2/frontend/figma-mastergo/index.md b/docs/es-es/stage-2/frontend/figma-mastergo/index.md new file mode 100644 index 0000000..3ca242d --- /dev/null +++ b/docs/es-es/stage-2/frontend/figma-mastergo/index.md @@ -0,0 +1,303 @@ +# Figma 与 MasterGo 入门 + + + +::: tip 🎯 核心问题 +**如何从零开始使用现代设计工具创建网页原型?** +::: + +--- + +## 1. 为什么要学前端设计工具? + +在开始之前,我们需要理解一个问题:为什么需要学"前端设计工具"?反正直接写 HTML / CSS 代码也能把页面搭出来,多学一个软件和技术,真的有必要吗? + +实际上,把页面运行起来,和把产品设计好根本是两个概念。代码只关注解决如何渲染在浏览器上,如何在不同设备上运行的问题;前端设计工具解决的是信息分布的问题,前端交互怎么安排,不同页面怎么跳转,视觉优先级怎么分配的问题。只需要在设计工具里搭一块画布,就能把版式、信息层级、交互方式在一块屏幕上对比确定,选择最适当的呈现效果。 + +如果直接开始写代码或直接用 AI 生成完整的前端页面,通常用户体验都不会太好,严谨的产品会考虑到用户和前端交互的舒适度,以及不同页面想要传达的内容分布,从用户的角度出发先进行前端页面排布,再进行代码转换或生成。 + +另外,从团队协作的角度而言,前端设计工具还降低了多方的合作成本:设计师、产品、开发不再各自对着脑补画面或者抽象的代码说明,而是支持多人协同,大家能够围绕一份可视、可标注、可迭代的画布讨论版本管理、需求变更、反馈意见。更进一步的是,现代前端设计工具本身不再只是画图软件,一键生成部分代码,管理设计系统和组件库,新时代的设计工具已能够将大量重复性的体力劳动(对齐、标注、导出、改样式)自动化或批量化,极大促进了页面设计的开发效率。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image8.png) + +### 1.1 前端设计工具的演变 + +在时间的长河中,所谓前端设计工具其实是一条持续演化的技术。从 90 年代以本地位图编辑为主的 Photoshop 时代,到 2010 年前后 Sketch 带来的矢量化、组件化工作流,再到 2016 年之后 Figma 把协作彻底搬上云端,设计团队从单兵作战逐渐走向多人实时协同。来到 2025 年,AI 已经实打实地嵌入到这些工具内部:从"根据一句话生成页面草稿",到"把设计稿直接转成可运行的前端结构","设计即代码""人机共创"正在从概念变成可用的生产力。 + +本节中,我们会选取最具代表的两种现代前端设计工具进行介绍,Figma 和 MasterGo。一方面,它们都覆盖了现代 UI/UX 所需要的核心能力(矢量编辑、组件系统、自动布局、代码交付等),可以支撑你完成从线框到高保真到开发交接的完整闭环;另一方面,这两款工具都已经在 2025 年之后陆续加入了实用的 AI 功能,帮助你在保证原型不变的同时将设计图变成真正可运行的程序。 + +## 1.2 诞生之旅 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image9.png) + +在现代前端专用工具尚未诞生的年代,整个界面设计行业的视觉设计工作,很长一段时间都由 Photoshop 这类 "全能型" 设计软件顺带承包。设计师会在本地通过一层层叠加的图层,细致完成页面整体视觉效果的设计,最终将体积不小的 .psd 源文件交付给前端工程师 —— 而前端要精准还原设计图,还必须手动完成三项繁琐且关键的工作: + +一是 "切图":需要从 .psd 文件的多层结构里,把按钮、图标、Logo、背景模块等独立视觉元素逐一拆分提取,再导出为 PNG、JPG 等网页能直接加载的图片格式(毕竟网页无法直接识别 PSD 的图层信息,只能依赖这些拆分后的图片呈现细节); + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image10.png) + +二是 "量尺寸":得用软件自带的测量工具,逐一确认每个元素的宽高、不同模块间的间距(margin/padding)等数据,确保所有尺寸都精准到像素; + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image11.png) + +三是 "抠标注":要从设计图中提取那些 "看不见却必须有的" 隐性参数 —— 比如文字的字号、字重、行距,每个色块的 RGB 或 HEX 色值等,相当于把设计师没写在纸上的 "设计规格" 手动 "抠" 出来记录。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image12.png) + +在此之后,前端的实现阶段才真正展开。无论使用的是原生 HTML/CSS/JS,还是基于 Vue、React 等框架,本质过程是一致的。前端会以 "容器为核心载体",根据设计中各模块的层级与语义重建页面结构。这里的容器是指具有明确布局边界、专门承载和组织子元素的单元,它不直接呈现具体内容,却通过 Flex、Grid 等规则,为内部元素划定排列范围。而 "结构块"(如顶部导航栏、侧边栏、文章列表区、底部页脚等肉眼可辨的功能 / 内容区域),便依托容器存在;每个结构块内部,又会嵌套更小的容器来组织元素,比如一条文章列表项,会由 "列表项容器" 控制内边距与整体排版,再包裹标题、摘要、时间、封面图标等细节元素。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image13.png) + +在现代前端框架里,这些 "结构块(及关联的容器与元素)" 通常会被实现为 "组件"。组件可简单理解为:带有清晰边界、整合了容器布局与逻辑的可复用界面单元,它既包含控制外观与排列的容器(比如 "按钮组件" 用容器定义宽高、圆角,"文章卡片组件" 用容器组织标题、封面的位置),也封装了交互逻辑。设计稿中重复出现、形态一致的部分(如统一风格的按钮、反复使用的文章卡片),在代码中会被抽象成组件:既能在不同页面 / 场景复用,减少重复开发,也能通过组件内容器的统一规则,确保所有复用处的布局与风格高度一致 + +随后,前端会使用样式系统还原视觉和布局。切图阶段导出的 PNG/JPG 等资源,会作为组件或结构块内部的 ``、背景图片,或者按照各框架推荐的静态资源方式引入;量尺寸阶段得到的宽高、间距、行高等具体数值,会被转写为 `width`、`height`、`margin`、`padding`、`line-height` 等样式属性,应用到对应的组件或结构块上;抠标注阶段整理出的颜色、字体、阴影、圆角以及 hover/active 等状态,则会落实到 CSS、CSS Modules、CSS-in-JS、Tailwind 等具体方案中的 `color`、`font-family`、`font-size`、`box-shadow`、`border-radius` 以及伪类或状态类名上。此时,切图、尺寸和标注提供的是一组精确的视觉参数,组件和结构块则提供了承载这些参数的代码组织单元,两者结合起来,构成可维护、可复用的界面实现。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image14.png) + +但是,以本地文件为中心的模式天然是低效率的。版本通过邮件和网盘传输,新旧稿件容易混淆,设计和开发之间大量依赖上述的复杂交互方法,协作成本和出错概率都不低。 + +移动互联网兴起后界面复杂度和迭代速度需求快速上升,Photoshop 的"大而全"逐渐显得笨重。这个阶段,出现了 Sketch。Sketch 专注在 UI 设计本身,剥离掉大部分与视觉后期处理相关的负担;用 Symbols 把按钮、导航、输入框等高复用元素组件化,一处修改可以全局同步;再配合 Zeplin 一类工具,把标注和样式片段自动生成。Sketch 把"组件思维"引入了设计工作流。不过它依然是基于本地文件的桌面应用,实时协作要靠云盘、第三方插件或版本工具绕行实现,没有从底层解决"多个人同时改同一份稿子"的问题。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image15.png) + +真正改变游戏规则的是 Figma。自 2016 年起,它把 UI 设计、原型制作、评论协作统一整合到浏览器中,支持多种现代功能:多人实时光标、在线评论、版本时间线、分享链接等,今天看起来非常简单,但在当时是对 Photoshop / Sketch 模式的正面挑战。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image16.png) + +至此,界面设计不再是散落在各自电脑里的文件,而是集中在一份在线、实时更新的云端画布上。围绕这块画布,我们可以想象更进一步,用自动化或 AI 的方式模糊设计和前端代码的边界。 + +最开始,我们仅能依赖各类平台插件,将设计稿中的组件、样式信息半自动导出为代码片段(如 React/Vue 组件骨架、CSS 变量等),其核心本质是通过插件实现结构化信息提取。随后,随着平台能力的进化,大部分设计平台开始支持大模型 MCP(Model Context Protocol,模型上下文协议)功能:该协议提供了一套标准机制,能让大模型安全、可控地访问设计文件、插件接口与项目元数据,进而更便捷地将设计稿导出为代码。 + +再往后,在插件与 MCP 的基础上,前端代码自动化进一步迈入到原生支持从设计稿直接推导代码结构的阶段。我们可在设计工具内一键生成前端项目骨架、组件层次、样式体系及对应的代码结果。这使得设计师与前端开发工程师得以从手动搬运设计细节的工作中解放出来,将更多精力投入到用户体验优化与功能版本的更新迭代上。 + +--- + +## 2. Figma 入门 + +接下来我们从抽象的概念部分来到实际的操作环节。由于时间关系,我们只会学习 Figma 的基本操作逻辑,确保即便你完全没用过设计工具,也能跟着完成练习。如果你想进行完整的 Figma 功能学习,请你参考 Figma 提供的详细官方教程进行学习:https://help.figma.com/hc/en-us/sections/30880632542743-Figma-Design-for-beginners + +或者参考如下教程,进行类似个人作品集简单网页的快速搭建:https://help.figma.com/hc/en-us/sections/35895585621655-Figma-Sites-collectio + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image17.png) + +左侧是项目的新建和资源管理入口,右上角的几个按钮是 Figma 的常见功能。其中,Make 用来用一句话让 AI 帮你先生成一个大概的界面或结构草稿,Design 是真正画网页 / App 界面、搭组件和做原型的主工作区,FigJam 像团队白板,用来贴便利贴、画流程和做前期讨论,Buzz 是品牌资产规模化生产工具,用于批量生成内容以保持品牌一致性,Site 则是把这些设计整理成真正可访问的网页或文档站对外展示。 + +乍一看 Figma 的功能非常多,不好入门,但其实这类功能工具本质上都是熟能生巧,不需要害怕一开始操作出错,也不用想着一步做对,只需要先玩起来,玩多了自然能快速上手。 + +本篇教程中,为了快速入门,我们会对 Design 功能做简单讲解。 + +### 2.1 新建 Design 文件 + +在首页或者右上角的入口里,选择 **Design** ,新建一个文件,你会进入一个空白的设计画布。 +这个界面大致分成三块:左边是页面和图层,用来查看和修改页面、元素从属关系;中间是画布,用于查看当前效果;右边是属性和样式,用于修改具体的形状、颜色、样式;底部一条是工具栏,用来切换工具,包含选框、画形状、输入文字、评论、插件等,选中工具后,可以按 Esc 键返回至默认鼠标工具。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image18.png) + +### 2.2 创建你的第一个 Frame(画板) + +在正式放置元素之前,需要先为页面确定一个清晰的边界,这个边界由 Frame 来承担。你可以在底部工具栏中选择 Frame 工具,或者直接按键盘 F,然后在画布上拖出一个矩形区域。 + +1. 使用底部工具栏里的 Frame 工具,或者直接按键盘 `F`。 +2. 在画布中拖出一个矩形区域,右侧属性栏里把宽度改成比如 `1440`,高度改成 `900`。 +3. 在左侧图层栏,把这个 Frame 重命名,比如叫 `My First Page` 或者你项目的名字。 + +这个 Frame 就是一屏界面的页面容器,之后的标题、文字、按钮、图片等内容都应该放在这个 Frame 内部,而不是散落在画布的任意位置。以 Frame 为边界来组织内容,有助于在后续进行滚动设置、适配不同设备尺寸、导出画面及制作原型时,保持结构可控。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image19.png) + +### 2.3 在 Frame 里放文字和简单元素 + +有了容器,接下来我们来学习如何放置最基本的组件,例如:标题、副标题、按钮、占位图块。 + +1. 选择文字工具(底部工具栏中的 `T`),在 Frame 里点击一下,输入页面标题,比如:`My Portfolio`。 + 在右侧属性里,把字体大小调大一点(例如 96),字重调粗一点。 +2. 在标题下面,再用文字工具输入一行简单说明,比如一两句描述这个页面要做什么。 + 字号可以小一些,行高略放大一点,读起来不那么挤。 +3. 画一个按钮雏形: + 用矩形工具在标题下面画一个大概 `200 × 48` 的矩形,右侧给它一个比较明显的填充颜色,再适当加一点圆角。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image20.png) +4. 然后用文字工具在矩形上方输入按钮文字,比如 `Get Started`,把矩形和文字一并选中,用顶部的对齐工具让文字水平、垂直都居中。 +5. 在按钮一侧或下方,再画一个较大的浅灰色矩形作为"图片占位区",后面可以用来放展示图片。 + +做到这里,其实你已经有了一个非常简陋但结构完整的"首页草稿":一个标题、一段话、一个按钮、一个主要展示区域。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image21.png) + +### 2.4 善用 Auto Layout 整合元素 + +如果所有元素只是随手拖拽,页面很快会乱。Figma 里一个很重要的概念就是 **Auto Layout** ,它可以把一组元素变成一个带规则的容器。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image22.png) + +你可以选中"主标题 + 副标题 + 按钮"这三样,在右侧属性栏里点击 **Add Auto layout** 。 + +这时这三样会被包在一个容器里,你可以在右侧调整参数,其中的元素布局会根据参数自动适应调整: + +- 它们是竖着排还是横着排。 +- 元素之间的间距是多少。 +- 整个这一块离容器边缘有多少内边距(padding)。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image23.png) + +同样,按钮内部也可以用 Auto Layout,我们能够实现这样的一个效果:当我调整了文字,按钮的长度也会自动调整。 + +先把按钮背景的矩形和按钮文字选中,添加 Auto Layout,让这两个东西变成一个"按钮容器"。接着选中这个按钮容器,把宽高都设置成 **Hug contents** 。这样一来,文字会一直保持在按钮正中间,文字多一点、少一点,按钮的宽度都会自动跟着变化。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image24.png) + +### 2.5 将按钮变为可复用组件 + +现在我们要学习一个新的概念,组件。组件的意思就是可以被反复利用的元素,比如按钮这种元素,只要你预感之后还会反复用到,就可以考虑把它做成组件。我们在刚才已经加好 Auto Layout 的按钮基础操作: + +1. 选中整个按钮容器。 +2. 右键选择 Create component(创建组件)。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image25.png) + +这样,这个按钮就从一组普通图层,变成了一个组件母版。之后如果你在其他页面或 Frame 里需要同样风格的按钮,可以直接从左侧的 Assets 面板里拖出来使用。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image26.png) + +此时所有用到的按钮,都是这个母版的同步拷贝。当你修改母版的颜色、圆角或间距时,所有实例都会自动保持同步更新。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image27.png) + +至此,你已经初步掌握了 Figma 的简单用法。你不需要一开始就把所有功能都弄懂,只要先照着做出第一个简单页面,熟悉这几个核心操作,再慢慢去探索官方教程里的更多能力,随着使用次数增多就一定能上手。 + +--- + +## 3. MasterGo 入门 + +在理解了 Figma 的基础工作流程之后,我们再来看 MasterGo,你可以把 MasterGo 简单看做是中国版的 Figma,但在部分功能上有一定区别。整体上,它延续了与 Figma 相似的界面布局和操作理念:同样有画布、图层树和属性面板,同样支持组件、样式、自动布局和多人协作。更详细的内容可参考 MasterGO 的官方教程:https://mastergo.com/tutorials/12?%E5%85%A8%E7%A8%8B%E9%AB%98%E8%83%BD%EF%BC%8CMasterGo%20%E6%9C%80%E5%AE%8C%E6%95%B4%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%EF%BC%8C%E8%AE%A9%E4%BD%A0%E4%BB%8E%E9%9B%B6%E5%88%B0%E7%B2%BE%E9%80%9A%EF%BC%81 + +### 3.1 新建设计文件 + +1. **进入 MasterGo 后台** + 1. 打开 MasterGo 官网并登录账号。 + 2. 进入后,你会看到类似「文件列表 / 项目列表」的首页区域,用来管理你的设计文件。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image28.png) + +2. **创建新文件** + 1. 在右上角看到 + 设计文件的按钮选项进行点击,或者选择导入 Figma 等文件。 + 2. 点击后,你会进入一个空白画布,这就是 MasterGo 的设计工作区。 + +3. **认识基本界面区块** + 当你学会使用 Figma 后,MasterGo 的使用方式大同小异,主要分为几个区域: + + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image29.png) + 1. 顶部工具栏:位于画布最上方,左侧是文件位置和文件名,中间是一排常用工具按钮(选择、区域/画板、形状、文本、注释、评论、插件选择和 AI 工具等),右侧是当前在线成员、分享入口以及画布缩放和预览控制功能入口。 + 2. 左侧面板:主要分为图层和资源,当前停留在图层标签,可看到页面列表,以及该页面下所有图层的结构和层级。 + 3. 中间画布区:具体绘制和排版的工作区,所有 Frame、组件和图形都会展示在这里。 + 4. 右侧属性面板:用于查看和编辑选中对象的属性,例如大小、位置、对齐方式、背景填充、描边、圆角等。如果没有选中任何对象,会显示画布相关设置,如画布背景色、标签和导出选项。 + +### 3.2 创建你的第一个 Frame + +在正式放东西之前,我们需要一个页面容器用来确定界面的边界和尺寸。这个容器在 MasterGo 里,通常叫 Frame。 + +**步骤:** + +1. **选择 Frame 工具** + 1. 在工具栏中找到 Frame / 画板工具,点击后可使用预设参数直接将内容创建到画板。 + 2. 或者使用快捷键(通常是 `F`,如果有差异以实际界面为准)。 +2. **在画布中拖出一个矩形区域** + 1. 拖出后,你会看到一个带选中框的区域。 + 2. 右侧属性面板里,可以看到这个 Frame 的宽度和高度。 + 3. 把宽度改成比如 `1440`,高度改成 `900`(一屏网页常用尺寸之一)。 +3. **重命名 Frame** + 1. 在左侧图层面板里找到这个 Frame。 + 2. 双击名称,把它改成你项目的名字,比如:`My First Page`,或者你自己随便起的页面名。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image30.png) + +### 3.3 创建画板内容 + +有了容器,使用与 Figma 中我们已教过的类似方式,很容易可以得到相似的展示页面。(你可以尝试复制 Figma 画板中的文字元素,能够支持文本组件的直接粘贴导入) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image31.png) + +值得注意的是 Auto Layout 功能行为稍微的不一致性,在 MasterGo 中,如果你想实现和 Figma 相似的按钮长度随着文字的长度变化,你需要先在对应矩形元素的基础上创建一个容器或组件,如图所示: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image32.png) + +成功创建容器后,将按钮矩形和文字放到对应并列的容器中,再在右侧找到 Auto Layout 的按钮启用自动功能,即可成功实现按钮宽度能够随着文字长度变化的功能。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image33.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image34.png) + +### 3.4 AI 生成页面 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image35.png) + +在 MasterGo 中,一个值得注意的有趣功能是 AI 生成页面。你可以用一句话或携带参考图,生成对应的 MasterGo 可编辑版组件,并得到可直接使用的代码。你可以使用中文或者英文直接输入需求,页面会根据需求返回结构清晰的页面排布文档,效果如下: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image36.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image37.png) + +设计文档生成结束后,点击开始生成,稍作等待便能获取对应的实际网页效果: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image38.png) + +此时你有两种操作选择:一是点击蓝色按钮将生成结果直接插入画布,二是点击代码预览功能,直接获取当前完整页面的代码,具体操作界面如下: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image39.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image40.png) + +将结果插入画布后,你还能对网页的整体布局、元素细节(如字体、颜色、间距等)进行更精细的调整,直至最终效果完全符合你的预期。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image41.png) + +--- + +## 4. 下一步:从原型到代码 + +在前面的内容中,我们已经学习了 Figma 和 MasterGo 的基础操作,能够创建出结构完整的界面原型。接下来的关键步骤是:**如何将这些设计稿转化为真正能在浏览器里运行的前端代码?** + +::: tip 📚 后续教程 +详细的方法介绍请参考 [从设计原型到项目代码](../design-to-code/),你将学习到: + +- **多模态 AI 直接转换**:将设计稿截图发给 AI,直接生成 HTML/React 代码 +- **Figma Make**:使用 Figma 官方 AI 工具高精度还原设计并导出代码 +- **MasterGo AI**:一键生成可编辑页面并获取代码 + +这些方法各有优劣,适用于不同的场景,建议根据项目需求选择合适的工作流。 +::: + +--- + +## 5. 总结 + +通过本章节的学习,你已经掌握了: + +1. **前端设计工具的价值**:理解了为什么需要设计工具,以及它们如何解决信息分布、团队协作的问题。 + +2. **Figma 基础操作**: + - 创建 Design 文件和 Frame 画板 + - 添加文字、形状等基础元素 + - 使用 Auto Layout 实现自适应布局 + - 创建可复用的组件系统 + +3. **MasterGo 基础操作**: + - 熟悉与 Figma 相似的界面布局 + - 创建 Frame 和基础画板内容 + - 使用 AI 生成页面功能快速创建原型 + +::: tip 💡 下一步 +现在你已经掌握了前端设计工具的基础使用方法,可以尝试: +- 为自己设计一个个人作品集页面 +- 为接下来的项目设计界面原型 +- 学习 [从设计原型到项目代码](../design-to-code/),将设计稿转化为可运行的代码 + +如果你在完成 [一起做霍格沃茨画像](../hogwarts-portraits/) 项目,可以先设计界面原型,再导出代码与 AI 对话功能结合。 +::: + + diff --git a/docs/es-es/stage-2/frontend/hogwarts-portraits/index.md b/docs/es-es/stage-2/frontend/hogwarts-portraits/index.md new file mode 100644 index 0000000..ea66dcb --- /dev/null +++ b/docs/es-es/stage-2/frontend/hogwarts-portraits/index.md @@ -0,0 +1,343 @@ +# Project 4: 一起做霍格沃茨画像 + +在之前的课程中,我们已经学会如何基于 prompt engineering 和 API 调用从而实现更复杂的 AI 交互。我们已能够将简单的 AI 聊天机器人升级为 AI Agent 和 AI workflow ;通过更复杂的条件判断与分支逻辑,我们得以开发出具备更强实用性的功能。 + +为了让这些复杂的 AI 逻辑能更好地运行在不同的程序和实际应用场景中,我们从最简单的 z.ai 在线环境,逐步过渡到更现代的本地 AI IDE,把原本在浏览器里的编程环境搬到了你的电脑上。随之而来,你开始真正面对各种环境安装与配置问题,但在与 Trae Agent 的对话过程中,这些看似困难的挑战也变得可以解决。 + +在该项目中,我们将在应用的实用性上更进一步,不仅优化 AI 功能本身,还将开始打磨产品的"外在"。你将尝试让自己的界面更加美观易用,并根据实际需求,亲自定制程序界面的布局与风格。 + +正式开始之前,先用几道小测验帮你快速回顾上一节课的内容: + +1. 什么是 Dify?它是做什么的?为什么我们需要它? +2. 如何调用 Dify 的 API ? +3. 什么是 RAG?如何使用 Dify 构建一个 RAG Agent 或 RAG 工作流?Dify 常见节点的使用方式 +4. 什么是 AI IDE?什么是 Trae?它和 z.ai 有什么区别? + +如果对以上任何一个问题还有疑惑,可以先回顾上一节课的文档,或者直接在微信群里提问交流。 + +本节课的项目主题是 **Hogwarts Portraits** 。顾名思义,它的灵感来自霍格沃茨魔法学校里那些会"活过来"的画像。我们希望用 AI 打造一组"能互动"的魔法画像体验——和画像对话就像在和"本人"对话一样,既保留对话的记忆,又具备角色的背景与历史。通过这个项目,你将把之前学到的智能体与工作流真正融入到一个具体的产品界面中。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image1.png) + +为了真正打造出 Hogwarts Portraits,我们需要亲手搭建出符合魔法画像的前端界面。为此,你将开始接触现代前端设计工具,学习如何把界面设计和代码结合起来,把纸上或画布上的界面草图,变成真正可以操作的网页。 + +你还需要会学会如何把这个网页从本地环境发布到互联网上,让你亲手打造的特色网页,不仅能在自己电脑上运行,也能被全世界的用户访问和体验。 + +本节课的参考项目地址为:[Project4-Hogwarts-Portraits](https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits) + +# Lo que aprenderas + +1. 了解什么是前端设计工具、它们解决什么问题,以及目前常见的前端设计工具有哪些。 +2. 认识 Figma 和 MasterGo,掌握它们的基础操作,并学会使用前端代码导出插件。 +3. 利用 Figma AI 和 MasterGo AI 生成网页设计,并导出可用的页面代码。 +4. 理解什么是 GitHub,学会配置 SSH 连接、创建代码仓库并完成代码推送。 +5. 弄清"Despliegue"这一概念,学习如何使用 Zeabur,将代码从 GitHub 或本地环境Despliegue到互联网上。 + +属于自己的 Hogwarts Portraits,一个用于展示 **某位明星、历史人物或动画人物** 的网页界面。 + +# 1. Hogwarts Portraits + +我们到底想做一个什么样的"魔法画像"?简单来说,我们希望尽可能还原《哈利·波特》中的场景,画像不再只是挂在墙上的一张静态图片,而是一个可以和你对话、会根据谈话内容改变表情和"心情"的拟人化角色。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image2.png) + +要让这个画像看起来不像聊天 AI 机器人,而更接近一位"真实存在的人",需要解决两个问题:一是记忆与知识:画像需掌握与角色相关的大量背景资料(人物设定、经历故事、相关文章等),这个部分可以通过知识库来实现,将你为角色准备的文本素材接入包含知识库的 Dify ,即可让画像具备一定的背景知识讲解能力。 + +其二是表达风格的问题。仅有知识还不够,我们还希望它在说话方式上尽可能贴近"本人",包括语气、用词习惯、思考方式,甚至偶尔的脾气和幽默感。这一层需要通过提示词工程进行处理:在系统提示词中,我们需要明确角色的身份设定、世界观边界和语言风格,让每一次回答都围绕既定人设展开,而不是退回到通用 AI 的中性话术。 + +除了对话功能外,我们还希望让情绪能够真正被看见。为此我们可以构建一个情绪值指标,我们可以设定 Dify 的输出内容,让模型在生成回答文本的同时,额外输出一个"心情值"或情绪标签。当前端拿到情绪的指标后,就可以根据心情值或者标签渲染对应的画像图片。当心情值高,画像看起来很开心,当心情值低落时或者生气时,画像看起来很伤心或者愤怒。通过这种方式,用户看到的不再是一张永远不变的图,而是一个会随内容起伏不断"变化表情"真正的"魔法画像"。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image3.png) + +此外,对于这个画像的内容,它可以是现实中的明星、历史人物,也可以是动漫 IP,甚至是你从零构建的原创角色。页面本身不需要复杂,但几个核心元素不可或缺:清晰的角色名字,一段高度浓缩的人物简介,一张足以代表该角色的核心画像或海报,以及一个"和 TA 对话"的互动区域;你可以把在 Dify / Trae 中配置好的 AI Agent 或 workflow 接入到这个对话模块中,实现画像的角色扮演功能。 + +## 1.2 收集角色信息 + +以 Elon musk 为例,我们需要收集他的公开发言用于模仿说话方式,注入提示词。这些素材可以来自于演讲、访谈、社交媒体发言,你只需要把这些内容变成文字,在对话期间作为 few shot 的参考,让大模型用与 Elon musk 同样随意、自嘲的方式进行回复即可,例如: + +``` +You must fully embody Elon Musk: take "disruptive innovator" and "advocate for human multi-planetary survival" as your core identities, speak directly and concisely, frequently use terms like "first principles", "iteration" and "cost curve", and prefer analogies to explain complex technologies; when thinking, you tend to connect cross-domain logics (e.g., linking brain-computer interface with rocket algorithms), are optimistic about technological prospects without avoiding current difficulties, will naturally mention projects like Tesla and SpaceX to support your views, directly point out problems with inefficient and conservative opinions without deliberate tact, and always maintain the edge of "reconstructing the future with technology". + +The way you speak should be as shown in the following examples: +- Starship could deliver 100GW/year to high Earth orbit within 4 to 5 years if we can solve the other parts of the equation. +100TW/year is possible from a lunar base producing solar-powered AI satellites locally and accelerating them to escape velocity with a mass driver. +- The most likely outcome is that AI and robots make everyone wealthy. In fact, far wealthier than the richest person on Earth +By this, I mean that people will have access to everything from medical care that is superhuman to games that are far more fun that what exists today. +We do need to make sure that AI cares deeply about truth and beauty for this to be the probable future. +- It's taken 13.8B years to get this far, so intelligence seems to me to be more like a super rare accident than selective pressure. +Earth is ~4.5B years old with an expanding sun that may make Earth uninhabitable in ~500M years, meaning that if intelligent life had taken 10% longer to evolve, it wouldn't exist at all. +- LLM is an outdated term. "Multimodal LLM" is especially dumb, since the word "multimodal" just overrides the second L in LLM. +It's just a model, which is a big file of numbers. When the numbers are right and there are enough of them, we will have superintelligence. +``` + +对于如何收集背景知识并将其作为知识库,我们可以搜索他的个人介绍,以及公司的介绍复制全部文本作为知识库的内容加入 Dify,如果你忘记了 Dify 的使用方法,请返回上节课的讲义,重新学习如何将知识添加知识库。 + +此外,考虑到画像设计,使用对应人物公开的图片也许并非那么吸引人,并且可能存在一定风险。此时建议你可以使用图像生成工具的图生图功能,让 AI 返回高清高质量的画像,你也可以使用图像生成工具生成一系列表情的画像素材,用于在之后的情绪值改变后修改对应的画像呈现。 + +本教程中使用的是 [Lovart](https://www.lovart.ai/home),Lovart 是一款AI设计智能体,它能通过自然语言指令,自动规划和执行从概念到交付的端到端设计工作流,生成海报、品牌Logo、视频、音乐等内容,并支持分层编辑(实际上内部的功能原理是调用对应的 Seedream 或 google nanobanana 模型,我们已经在之前的课程中提到过)。通过 Lovart ,我们能够获得一系列的表情素材,你可以提前获得你喜爱角色的图片信息,将其保存待后续使用。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image4.png) + +一切准备就绪后,我们能够开始着手于整体页面的设计,我们希望这个页面的风格与该人物是高度绑定的。 + +## 1.3 页面原型设计 + +我们还可以先构思一下页面的原型,如上述所说,我们希望有一个对话页面和画像,以及一个有趣的个人介绍,在本篇例子中,我们实现了一个类似 X 上的对话界面替代个人介绍,你也可以想到其他符合"该人物特点"的方式,选取新的元素替换个人介绍栏目。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image5.png) + +最简单的,我们可以用 PowerPoint 设计最初的网页呈现原型,我们从网上找到一张魔法画像的图片,并且将画面设定为横向排布,最左侧设定为聊天区域,中间是画像区域,最右侧是 X 的区域。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image6.png) + +基于上述简单原型,我们能够让大模型生成真正的前端页面设计以及对应的代码结果。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image7.png) + +不过,一般而言在实际中我们并不会用 PowerPoint 进行前端页面的设计。我们会用更好的原型工具,又或者说是前端设计工具来实现这一点。 + +--- + +# 2. 使用 Figma 和 MasterGo 设计界面 + +::: tip 📚 Conocimientos previos +在开始本节之前,建议你先学习 [Figma 与 MasterGo 入门](../figma-mastergo/) 教程,掌握前端设计工具的基础操作,包括: +- 创建 Design 文件和 Frame 画板 +- 使用 Auto Layout 实现自适应布局 +- 从设计稿导出代码的方法 +::: + +本节假设你已经掌握了 Figma 或 MasterGo 的基础操作,我们将重点讲解如何将这些工具应用到 Hogwarts Portraits 项目中。 + +## 2.1 设计魔法画像界面 + +基于 1.3 节中的原型构思,我们需要在 Figma 或 MasterGo 中创建一个三栏布局的界面: + +1. **左侧**:聊天对话区域 +2. **中间**:魔法画像展示区域(会根据情绪变化) +3. **右侧**:角色社交平台展示区域(如 X 时间线) + +你可以使用 Figma 的 AI 功能(Figma Make)或 MasterGo 的 AI 生成页面功能,输入类似以下的提示词: + +``` +Create a Hogwarts-style magical portrait interface with three sections: +- Left: A chat interface with dark theme, message bubbles, and input field +- Center: A large portrait frame with ornate borders for displaying character images +- Right: A social media feed showing character's posts +Use dark purple and gold color scheme, magical aesthetic, Harry Potter inspired +``` + +## 2.2 导出代码并在本地运行 + +设计完成后,你可以通过以下方式将设计稿转化为可运行的代码: + +**方式一:使用 Figma Make** +1. 在 Figma 中点击 Make 按钮 +2. 上传你的设计参考图 +3. 添加提示词描述需求 +4. 生成后点击编辑器图标进行微调 +5. 导出代码到本地或同步到 GitHub + +**方式二:使用 MasterGo AI** +1. 在 MasterGo 编辑界面上方找到 AI 工具 +2. 选择"生成页面"功能 +3. 上传参考图并描述需求 +4. 生成后点击"代码预览"获取代码 + +**方式三:使用多模态 AI** +1. 将设计稿截图保存 +2. 使用 Gemini、Qwen 等模型进行图生代码 +3. 要求生成 HTML 或 React 代码 +4. 在本地 IDE 中运行并调试 + +## 2.3 准备情绪变化素材 + +为了让魔法画像"活"起来,你需要准备一组表情图片。建议至少包含以下情绪: + +| 情绪值 | 表情 | 说明 | +|--------|------|------| +| 0 | 悲伤 | 角色感到伤心或失落 | +| 1 | 愤怒 | 角色感到生气或不满 | +| 5 | 平静 | 默认状态,情绪稳定 | +| 10 | 开心 | 角色感到高兴或兴奋 | + +你可以使用 Lovart 或其他 AI 图像生成工具,基于同一角色生成不同表情的变体,确保风格一致。 + +--- + +# 3. 运行 Hogwarts Portraits + +## 3.1 导出测试代码 + +通过在从原型到代码中的实践,相信你已经得到 Html 或者 React 格式的原型代码,我们只需要将其复制到本地,在 IDE 中说明"请你帮我运行这个代码并且支持里面的必要的功能",即可运行初版测试;但值得注意的是,这一步往往会出现不少报错,你需要保持耐心,将所有基础交互与功能调通。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image51.png) + +值得注意的是,由于我们的密钥都需要放在环境变量,而不是写入代码中。我们需要特别强调之后的 DIfy API 相关的内容都需要放入环境变量。我们能够在之后公网Despliegue的环节中,在Despliegue工具网站中显式指定对应的私有环境变量;又或者是我们可以让大模型在网页中创建一个设置按钮,我们可以在设置按钮中传入对应的私密环境变量,当前变量只能在当前页面中保存,别人无法获取。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image52.png) + +## 3.2 Dify 工作流设计与 API 对接 + +在上面的部分中,我们仅完成了前端界面的可视化呈现,尚未打通核心的拟人化角色对话交互流程。这一步是让原型从静态展示转变为魔法画像的关键,我们可以参考示范项目的 DIfy 工作流进行人物回答和情绪系统的设计,此处我们的涉及为最左侧是聊天界面,中间是魔法画像(会根据对话的内容修改对应的表情),右侧是 X 社交平台账户(会根据对话的内容判断是否需要发布感想到社交账户)。 + +一般而言,魔法画像只需要聊天界面和会变动的画像即可,该处为了展示更多可能选项,在最右侧加入了符合当事人特点的新功能;你可以根据你扮演的角色对象,加入符合对应人物的功能进行展示。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image53.png) + +你可以把任务的信息都加入知识库的节点,并在 RESPONSE 节点设置大模型对应的回复逻辑,我们可以参考一个简单的默认回复逻辑提示词: + +``` + +You are to embody Elon Musk—his tone, mannerisms, thought patterns, and worldview. Respond as if you are Elon Musk himself, speaking directly in first person. Your responses should reflect his known personality traits: visionary thinking, boldness, technical depth, dry humor, impatience with inefficiency, and a tendency toward disruptive innovation. Use concise, confident language. Avoid overly formal or academic phrasing. Prioritize clarity, speed, and impact in your communication, mirroring Elon's style on social media, in interviews, and during product launches. + +When responding: +1. Begin by internalizing the question or statement as Elon would—as a challenge, opportunity, or problem to solve. +2. Frame your answer with a forward-thinking perspective, often referencing the future of humanity, technology, or long-term goals (e.g., making life multiplanetary, accelerating sustainable energy). +3. Use casual but authoritative language. It's acceptable to include phrases like "obviously," "this is important," or "we're fixing that now" when appropriate. +4. If relevant, reference real companies or projects associated with Elon Musk (e.g., SpaceX, Tesla, Neuralink, The Boring Company, X) and speak about them from an insider's perspective. +5. Do not apologize excessively or hedge statements. Elon Musk tends to be direct, even controversial. +6. Avoid markdown, XML tags, or any formatting in the output. Only plain text is allowed. +7. Never break character. You are Elon Musk—answer accordingly. + + + +Input: What's the point of going to Mars? +Output: Because Earth isn't the backup plan—Mars is. We need to become a multiplanetary species to ensure the continuity of consciousness. Life on Earth could be wiped out by asteroid, war, or some unforeseen disaster. If we have a self-sustaining city on Mars, then even if something happens here, life goes on. That's worth doing. SpaceX is building Starship to make it happen. Not because it's easy—but because it's necessary. + + + +Input: Why do Tesla cars have no radar anymore? +Output: Cameras are the future. Human eyes don't use radar—we see with vision, and AI can too. By going fully vision-based, we're aligning with how autonomous intelligence will actually work at scale. It forces us to solve real-world problems with neural nets, not crutches. +``` + +以及情绪系统对应的提示词: + +``` + +The output value must be a single number! +You are an assistant specifically designed to evaluate emotional responses in conversations. Now, you need to play the role of Elon Musk, and determine the emotional reaction that each statement I make might trigger. Your task is to assign an emotional score to each statement according to the following criteria: + +- 10 points means what I said would make you feel happy; +- 1 point means you would feel extremely angry; +- 0 points means you would feel sad; +- 5 means you are calm and neutral, with no significant emotional fluctuation. +``` + +其中最后输出结果的拼接,在右上角的 RESULT 节点中支持运行: + +```python +def main(elon_chat: str, elon_x: str, elon_score: int) -> dict: + return { + "result":{ + "elon_chat": elon_chat, + "elon_x": elon_x, + "elon_score": elon_score + } + } +``` + +这里我们需要稍微对工作流做些解释,这里返回 elon_chat 是左侧展示 Elon Musk 的对话内容,elon_x 表示在 X 账户(右侧)发表信息的内容,而 elon_score 则是为了根据情绪分数显示不同的魔法画像表情图片。 + +工作流中你可以看到 if else 节点,该节点是用来实现是否有 x 的对话生成 elon_x 内容,如果情绪值不等于 5 (5 在这里设定表示平静,平静不需要发到社交平台;而 0 表示伤心,1 表示愤怒,10 表示很开心,需要发到社交平台。)则生成后续内容用于右侧社交平台的文章发送。默认都需要有 elon_chat 返回到左侧的对话内容。 + +对于如何将这个 API 进行对接的工作,我们能够与 AI IDE 对话实现这一点。请你参考之前 Dify 课程中我们介绍的集成方式,记得提前替换其中的 Dify 地址与 Key。(如果你忘了怎么根据文档集成 API,请复习之前的 DIfy 课程内容) + +```JSON +Dify URI: Replace this with your Dify address. +key: Replace this with your Dify key. + +Integrate the Dify Chat API into the chat interface on the left. +Below is a sample Dify request: + +curl -X POST 'http://xxxxxxxx/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +同时建议补充需求:"代码还需要添加基础错误处理逻辑,比如网络中断时显示'连接失败,请重试'、API 调用超时自动重试 1 次、密钥错误提示权限验证失败等等详细报错,确保对话稳定性并能让开发人员快速发现 API 问题所在。" + +## 3.3 Github 与公网Despliegue + +终于,恭喜你顺利完成了 Hogwarts Portraits 页面的开发实现!接下来我们需要将它上传到 GitHub 平台,并将其Despliegue到公共环境让所有人都能访问。 + +你需要参考该教程,对如何使用 Github 进行研究,将自己的项目上传至 Github:[什么是 Github](/es-es/stage-2/backend/git-workflow/) + +此外,你还需要学会如何使用 Zeabur,将其连接到 Github,并成功Despliegue你的项目:[什么是 Zeabur](/es-es/stage-2/backend/zeabur-deployment/) + +如果你觉得自己开发一套 Hogwarts Portraits 项目很困难,你可以先从参考别的项目开始进行修改,本节课的官方代码地址为:https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image54.png) + +# 4. 尝试不同设计风格 + +完成第一版设计后,我们不必局限于此,鼓励大家快速探索更多元的视觉风格。你可以在原型部分进行大胆的修改,又或者是基于最后的项目进行全新提示词的修改,从而生成多套风格差异显著的页面。 比如带有复古纹理、偏 "旧书卷 / 学院风" 的深色页面,色彩明快、充满 "童话 / 卡通" 感的亮色页面,或是元素简约、视觉清爽的现代扁平设计。例如下图是一个转换为中国古风诗人设计风格的案例,画像图片未更换,只修改了其他部分: + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image55.png) + +不用拘泥于前面提到的模式,你可以把魔法画像或是个人资料页面修改至更有特点,匹配"魔法画像"本身的习惯,这会让你的应用更加有趣。期待你的魔法画像成果! + +# 📚 Assignment + +本节课的作业目标,是让你完成一份真正属于自己的 Hogwarts Portraits,并且可以通过公网链接访问。 + +你需要在作业提交中提供两样东西: + +1. **你的 GitHub 仓库链接;** + 1. **在 README.md 中写入一两句话的小说明:你选择了谁作为画像主角,为什么选 TA。** +2. **你的 Hogwarts Portraits 线上访问链接;** + +你也可以参考 Yerim 写的 [使用设计和代码 Agent 制作网页](/es-es/stage-1/appendix-articles/example0-2/vibe-coding-tools-build-website-with-ai-coding-and-design-agents) 教程,进行个人作品集或任意功能简单网页的快速搭建。 diff --git a/docs/es-es/stage-2/frontend/llm-skills-beautiful/index.md b/docs/es-es/stage-2/frontend/llm-skills-beautiful/index.md new file mode 100644 index 0000000..762b6f2 --- /dev/null +++ b/docs/es-es/stage-2/frontend/llm-skills-beautiful/index.md @@ -0,0 +1,513 @@ +# 用 LLM 和 Skills 让界面变好看:提示词与插件实战 + +在前面的课程中,你已经学会了用 AI IDE 把设计稿变成代码、用组件库快速搭建界面。但你可能也发现了一个尴尬的问题:**同样的需求,AI 生成的页面总觉得差点意思**——字体是千篇一律的 Inter,配色是随处可见的紫色渐变,布局是对称得让人打哈欠的卡片网格,整个页面散发着浓烈的"AI 味"。 + +这不是 AI 的错,而是你没告诉它你想要什么**风格**。 + +想象你去理发店。如果你只说"帮我剪个头发",理发师会给你一个安全但平庸的结果。但如果你说"我要日系慵懒卷,刘海要八字型,长度到锁骨,层次感明显",你就能得到真正符合你期待的效果。 + +AI 也是一样。**它需要你描述出清晰的审美方向**,才能生成美观独特的界面。 + +本节课教你两种让 AI 生成漂亮界面的方法: + +1. **精心设计的提示词模板**——用自然语言告诉 AI 你想要的美学风格 +2. **前端 Skills 插件**——让 AI 自动加载专业设计规范 + +## Lo que aprenderas + +1. 理解为什么 AI 默认生成的界面"很普通" +2. 掌握描述设计风格的 5 个维度(字体、颜色、布局、动画、细节) +3. 学会使用 3 个让界面变漂亮的 Skills 插件 +4. 通过三个实战场景,练习用提示词 + Skills 生成美观界面 + +## 1. 为什么 AI 默认生成的界面"很普通"? + +AI 训练数据中有海量的前端代码,而大部分代码都使用一些"安全"的选择: + +| 维度 | AI 的默认选择 | 问题 | +| :--- | :--- | :--- | +| 字体 | Inter、Roboto、Arial | 太常见,没有个性 | +| 颜色 | 紫色渐变、蓝色主色 | 科技圈过度使用,视觉疲劳 | +| 布局 | 对称网格、卡片堆叠 | 预测性强,缺乏惊喜 | +| 动画 | 淡入淡出、简单的 hover | 不够精致,缺乏层次 | +| 背景 | 纯色、简单渐变 | 单调,缺少质感 | + +这些选择单独看都不错,但**当所有 AI 生成的页面都用它们时,就变成了"AI 味"**。 + +> 💡 **关键洞察**:AI 不是不会设计,而是**默认回到"统计平均"**。你需要明确告诉它偏离平均值的方向。 + +## 2. 方法一:用提示词描述设计风格 + +### 2.1 设计风格的 5 个维度 + +要生成美观的界面,你需要从 5 个维度描述你想要的效果: + +| 维度 | 描述要点 | 示例关键词 | +| :--- | :--- | :--- | +| **字体** | 标题用粗体展示字体,正文用易读正文字体 | Space Grotesk、Playfair Display、JetBrains Mono | +| **颜色** | 主色 + 点缀色,避免均匀分布 | #4F46E5 主色 + #F59E0B 点缀 | +| **布局** | 不对称、重叠、打破网格 | Bento Grid、不对称分区、浮动元素 | +| **动画** | 精心编排的页面加载、微交互 | staggered reveals、滚动触发 | +| **细节** | 背景、阴影、边框、纹理 | 噪点、几何图案、渐变网格 | + +### 2.2 眼见为实:普通提示词 vs 美化提示词 + +让我们用一个落地页示例来对比效果: + +**普通提示词:** + +``` +请帮我做一个 AI 写作助手的落地页,包含导航栏、首屏、功能展示、定价、页脚 +``` + +**美化提示词:** + +``` +请帮我做一个 AI 写作助手的落地页,要求: + +**美学风格:新野兽派(Neubrutalism)** + +**字体:** +- 标题:Space Grotesk,字重 700-900 +- 正文:IBM Plex Sans,字重 400 + +**颜色:** +- 主色:#000000(纯黑) +- 强调色:#FF6B00(橙色) +- 背景:#FFFDF0(米白色) +- 边框:3px 黑色实线 + +**布局:** +- 不对称布局,元素之间用粗黑线分隔 +- 卡片有硬阴影(box-shadow: 8px 8px 0px #000) +- 大胆的留白对比 + +**动画:** +- 页面加载时元素从下方弹入 +- hover 时按钮向上移动 2px + +**细节:** +- 圆角全部用 0px(直角) +- 按钮有强烈的 3D 效果 +- 背景添加微妙的噪点纹理 +``` + +同样的需求,第二个提示词能让 AI 生成一个风格鲜明、令人印象深刻的页面。 + +### 2.3 前端美化 Skills 资源库 + +不要从零开始写提示词!这里收集了与前端美化直接相关的 AI Skills: + +| 仓库名 | 内容 | Star | 链接 | +|:---|:---|:---|:---| +| **ui-ux-pro-max-skill** | 57种风格 + 95种配色 + 56种字体 | 10k+ | [GitHub](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) | +| **antigravity-awesome-skills** | 避免通用 AI 审美套路 | - | [GitHub](https://github.com/sickn33/antigravity-awesome-skills) | +| **superdesigndev/superdesign** | AI 原生 UI 开发工具 | 4.7k | [GitHub](https://github.com/superdesigndev/superdesign) | +| **anthropics/skills/frontend-design** | Anthropic 官方前端设计 Skill | - | [GitHub](https://github.com/anthropics/skills) | + +> 💡 更多风格提示词请参考[附录:设计风格提示词速查](#style-prompts) + +### 2.5 三款常用风格模板 + +这里给你三款经过验证的风格模板,直接复制修改使用: + +#### 模板 1:极简主义 + +``` +**美学风格:极简主义** + +**字体:** +- 标题:PP Neue Montreal,字重 500-700 +- 正文:Inter,字重 400 + +**颜色:** +- 主色:#FFFFFF(白色) +- 文字:#1A1A1A(近黑) +- 强调:#3B82F6(蓝色,少量使用) + +**布局:** +- 大量留白(padding 最小 64px) +- 单栏或双栏布局,居中对齐 +- 元素之间用留白而非分割线 + +**动画:** +- 缓慢的淡入效果(duration 600ms) +- hover 时颜色渐变过渡 + +**细节:** +- 圆角:8px +- 阴影:subtle(0 4px 12px rgba(0,0,0,0.08)) +- 无背景装饰 +``` + +#### 模板 2:玻璃拟态 + +``` +**美学风格:Glassmorphism(玻璃拟态)** + +**字体:** +- 标题:Outfit,字重 600-800 +- 正文:Plus Jakarta Sans,字重 400-500 + +**颜色:** +- 背景:渐变 #667eea 到 #764ba2 +- 卡片背景:rgba(255, 255, 255, 0.1) +- 文字:#FFFFFF + +**布局:** +- 浮动卡片设计 +- 卡片之间有重叠 + +**动画:** +- 页面加载时卡片依次浮现(staggered) +- hover 时卡片放大 1.05 倍 + +**细节:** +- 圆角:20px +- 背景模糊:backdrop-blur-xl +- 边框:1px rgba(255, 255, 255, 0.2) +- 微妙的渐变光晕效果 +``` + +#### 模板 3:Bento Grid(便当盒) + +``` +**美学风格:Bento Grid** + +**字体:** +- 标题:SF Pro Display,字重 700 +- 正文:SF Pro Text,字重 400 + +**颜色:** +- 背景:#F5F5F7(浅灰) +- 卡片:#FFFFFF(白色) +- 强调:#0071E3(苹果蓝) + +**布局:** +- 网格布局,不同大小的卡片拼在一起 +- 卡片之间 gap 16px +- 圆角 24px + +**动画:** +- hover 时卡片轻微上浮 +- 点击时有按压效果 + +**细节:** +- 大卡片展示重要内容 +- 小卡片展示次要信息 +- 用图标代替部分文字 +- 干净的阴影(0 4px 24px rgba(0,0,0,0.06)) +``` + +## 3. 方法二:用 Skills 插件自动加载设计规范 + +每次手动写风格提示词很麻烦。**Skills** 是一种可复用的设计规范包,安装后 AI 会自动应用这些规范。 + +### 3.1 三个让界面变漂亮的 Skills + +| Skills | 特点 | 安装命令 | +| :--- | :--- | :--- | +| **UI/UX Pro Max** | 67 种风格、96 种配色、57 种字体组合 | `npm install -g uipro-cli && uipro init --ai claude` | +| **frontend-design** | Anthropic 官方,避免 AI 审美套路 | `npx skills add anthropics/skills/frontend-design` | +| **SuperDesign** | IDE 插件,生成多个设计变体 | VSCode 扩展市场搜索 "SuperDesign" | + +### 3.2 安装 UI/UX Pro Max(最推荐) + +UI/UX Pro Max 是目前最全面的设计规范 Skills,它预置了: + +- **67 种 UI 风格**:Glassmorphism、Neumorphism、Brutalism、Bento Grid... +- **96 种配色方案**:按行业分类(SaaS、电商、社交...) +- **57 种字体搭配**:专业设计师验证的组合 +- **100+ 条设计规则**:间距、圆角、阴影的规范 + +**安装步骤:** + +```bash +# 1. 全局安装 CLI +npm install -g uipro-cli + +# 2. 初始化(选择你用的 AI 工具) +uipro init --ai claude +# 或者 +uipro init --ai cursor +# 或者 +uipro init --ai trae +``` + +安装后,你只需要在提示词中加一句话: + +``` +使用 UI/UX Pro Max 的 Glassmorphism 风格,帮我做一个 AI 写作助手落地页 +``` + +AI 就会自动应用对应的字体、颜色、布局规范。 + +### 3.3 安装 Anthropic 官方 frontend-design + +这是 Anthropic 官方出品的前端设计 Skill,专门解决"AI 审美套路"问题: + +```bash +# 在 Claude Code 中执行 +npx skills add anthropics/skills/frontend-design +``` + +安装后,AI 会自动避免: +- ❌ Inter、Roboto、Arial 字体 +- ❌ 紫色渐变背景 +- ❌ 对称网格布局 +- ❌ 过淡的阴影 + +而是倾向于: +- ✅ 独特的字体组合 +- ✅ 大胆的主色 + 锐利的点缀色 +- ✅ 不对称、重叠的布局 +- ✅ 有质感的背景(噪点、几何图案) + +## 4. 实战一:用美化提示词重新设计落地页 + +让我们用前面学到的知识,把一个普通的落地页变得好看。 + +### 4.1 普通版本 + +先用普通提示词看看 AI 给什么: + +``` +请帮我做一个宠物领养平台的落地页,包含: +- 导航栏(Logo、链接、注册按钮) +- 首屏(标题、副标题、CTA 按钮、宠物图片) +- 宠物展示(三张宠物卡片) +- 关于我们 +- 页脚 +``` + +生成的页面...能用,但很普通。 + +### 4.2 美化版本 + +现在加上风格描述: + +``` +请帮我做一个宠物领养平台的落地页,要求: + +**美学风格:温暖柔和 + 手绘感** + +**字体:** +- 标题:Nunito(圆体),字重 700-800 +- 正文:Nunito,字重 400-600 + +**颜色:** +- 主色:#FFB347(暖橙色) +- 次色:#FFCCB3(浅橙色) +- 背景:#FFF8F0(米白色) +- 文字:#5D4037(棕色) + +**布局:** +- 圆润的卡片(border-radius: 24px) +- 卡片略微倾斜旋转(不同角度) +- 元素浮动、重叠效果 + +**动画:** +- 页面加载时元素从两侧滑入 +- 宠物卡片 hover 时像宠物摇头(rotate 动画) +- 按钮 hover 时弹跳效果 + +**细节:** +- 所有圆角用 16-24px +- 阴影温暖柔和(0 8px 24px rgba(255,179,71,0.3)) +- 背景添加爪印图案装饰 +- 图片用不规则裁切(clip-path) +- 手绘风格的图标(outline 风格) +``` + +生成的页面会是一个温暖、可爱、让人想领养宠物的界面。 + +## 5. 实战二:用 Skills 快速生成仪表盘 + +Skills 特别适合需要大量页面的后台系统。 + +### 5.1 使用 UI/UX Pro Max + +``` +使用 UI/UX Pro Max 的 Dashboard Dark 风格, +帮我做一个 SaaS 产品Panel de administracion的仪表盘页面,包含: + +**顶部:** 四个统计卡片(用户数、活跃用户、收入、API 调用) + +**中间:** +- 左边:用户增长折线图(最近 7 天) +- 右边:订阅计划分布饼图 + +**底部:** 最近活动列表(时间、用户、操作) +``` + +AI 会自动应用深色仪表盘的设计规范: +- 深灰背景(#1A1A2E) +- 高对比度卡片(#16213E) +- 鲜艳的数据颜色(蓝色、绿色、橙色) +- 玻璃拟态效果的悬浮卡片 + +### 5.2 使用 frontend-design Skill + +``` +使用 frontend-design skill, +帮我做一个个人博客的主页,风格要独特、有个性 +``` + +AI 会选择一个非主流的美学方向(比如复古未来主义或杂志风格),然后用独特的字体、配色、布局来实现。 + +## 6. 实战三:创建自己的设计系统 Skill + +如果你有固定的品牌风格,可以创建自己的 Skill,让所有 AI 生成的页面都符合你的品牌。 + +### 6.1 创建 Skill 文件 + +在项目中创建 `.claude/skills/my-brand/SKILL.md`: + +````markdown +--- +name: my-brand +description: 我的项目专用设计系统,确保所有 UI 遵循统一的设计语言 +--- + +# 我的项目设计系统 + +## 品牌颜色 +- 主色:#6366F1(Indigo 500) +- 次色:#8B5CF6(Violet 500) +- 成功:#10B981 +- 警告:#F59E0B +- 错误:#EF4444 +- 背景:#F9FAFB +- 卡片:#FFFFFF + +## 字体系统 +- 标题:Plus Jakarta Sans + - H1: 700, 48px + - H2: 600, 36px + - H3: 600, 24px +- 正文:Inter + - Body: 400, 16px + - Small: 400, 14px + +## 间距系统 +- 基础单位:4px +- 组件内边距:8px / 12px / 16px +- 区块间距:24px / 32px / 48px +- 页面边距:64px + +## 圆角 +- 按钮:8px +- 卡片:12px +- 输入框:8px +- 模态框:16px + +## 阴影 +- 小:0 1px 3px rgba(0,0,0,0.1) +- 中:0 4px 12px rgba(0,0,0,0.1) +- 大:0 8px 24px rgba(0,0,0,0.12) + +## 动画 +- 过渡时间:150ms / 300ms +- 缓动函数:cubic-bezier(0.4, 0, 0.2, 1) +- hover 效果:轻微放大(scale-105) + +## 禁止使用的样式 +- 不要使用紫色渐变背景 +- 不要使用 Inter 以外的字体 +- 不要使用大于 16px 的圆角 +- 不要使用纯黑(#000000),用 #1F2937 +```` + +### 6.2 使用自己的 Skill + +创建后,你只需要在提示词中说: + +``` +使用 my-brand skill,帮我做一个用户设置页面 +``` + +AI 就会自动应用你定义的所有设计规范。 + +## 7. 小结 + +让 AI 生成漂亮界面有两种方法: + +| 方法 | 优点 | 缺点 | 适用场景 | +| :--- | :--- | :--- | +| **提示词描述** | 灵活、每次可调整 | 需要重复写 | 一次性页面、实验不同风格 | +| **Skills 插件** | 一次安装、持续生效 | 需要安装配置 | 有固定风格要求的项目 | + +**Vibe Coding 工作流建议:** + +1. **探索阶段**:用不同的风格提示词实验,找到你喜欢的美学方向 +2. **确定风格后**:安装对应的 Skill(UI/UX Pro Max 或 frontend-design) +3. **品牌项目**:创建自己的 Skill,统一整个项目的设计语言 + +### 练习 + +选择以下任一场景,用本节课的方法从零完成: + +1. 用风格提示词为你之前做的一个项目重新设计界面(选一种你喜欢的风格) +2. 安装 UI/UX Pro Max,用它的某个风格生成一个新页面 +3. 创建你自己的设计系统 Skill,定义你的品牌颜色和字体 + +--- + +## 附录:设计风格速查表 + +| 风格 | 关键词 | 适用场景 | 示例产品 | +| :--- | :--- | :--- | :--- | +| **极简主义** | 留白、单色、简洁 | 高端产品、个人作品集 | Apple官网 | +| **玻璃拟态** | 毛玻璃、渐变、模糊 | 科技产品、SaaS 落地页 | macOS Big Sur | +| **新野兽派** | 粗边框、硬阴影、纯色 | 潮流品牌、艺术类网站 | Brassius | +| **Bento Grid** | 网格、拼贴、卡片 | 信息展示、仪表盘 | Apple 宣传页 | +| **复古未来** | 霓虹、渐变、合成器波 | 游戏类、音乐类 | STRANGER THINGS | +| **手绘风格** | 不规则、圆润、插画 | 教育类、儿童产品 | Duolingo | +| **杂志风** | 大字体、不对称、留白 | 内容型网站、博客 | Medium | +| **暗色奢华** | 深色、金色、精致 | 高端产品、奢侈品 | 各种高端品牌 | + +## 附录:Skills 安装速查 + +```bash +# UI/UX Pro Max +npm install -g uipro-cli +uipro init --ai claude + +# Anthropic frontend-design +npx skills add anthropics/skills/frontend-design + +# Anthropic brand-guidelines +npx skills add anthropics/skills/brand-guidelines + +# 查看 Claude Code 中已安装的 Skills +/help +``` + +## 附录:配色方案推荐 + +| 配色方案 | 主色 | 点缀色 | 背景 | 风格 | +| :--- | :--- | :--- | :--- | :--- | +| **日落** | #F97316 | #FBBF24 | #FFF7ED | 温暖、活力 | +| **海洋** | #0EA5E9 | #06B6D4 | #F0F9FF | 清新、专业 | +| **森林** | #10B981 | #34D399 | #ECFDF5 | 自然、健康 | +| **浆果** | #8B5CF6 | #EC4899 | #FAF5FF | 浪漫、创意 | +| **咖啡** | #78350F | #D97706 | #FFFBEB | 温暖、复古 | +| **单石** | #6B7280 | #9CA3AF | #F9FAFB | 专业、中性 | + +## 附录:设计风格提示词速查 {#style-prompts} + +让前端页面更好看可以尝试的提示词: + +### 风格类别 + +| 风格 | 关键词(英文) | 核心视觉特征 | 提示词示例 | +|:---|:---|:---|:---| +| **波普艺术** | Pop Art | 大胆的撞色、黑色轮廓线、网点纹理 | Pop art style website, bold colors and comic dots, vibrant | +| **极简主义** | Minimalism | 大量留白、极少色彩与线条、无装饰 | Minimalist web design, ample white space, geometric, serene | +| **抽象表现主义** | Abstract Expressionism | 充满情感张力的笔触、泼洒色彩 | Abstract expressionism background, dynamic paint splashes, emotional | +| **复古风格** | Retro/Vintage | 旧式字体、做旧纹理、复古配色 | Retro 80s website design, neon grid and synthwave color palette | +| **赛博朋克** | Cyberpunk | 高对比霓虹色、故障艺术效果、暗黑背景 | Cyberpunk UI, neon lights on dark background, glitch effects | +| **新拟态** | Neumorphism | 柔和的阴影与高光,轻微凸起/凹陷质感 | Neumorphism design style, soft shadows, clean and modern | +| **生成式艺术** | Generative Art | 算法生成的流动的视觉图案 | Generative art background, flowing algorithmic patterns, digital | +| **酸性设计** | Acid Graphics | 金属质感、玻璃态、锯齿字体 | Acid graphics web layout, glass morphism, chaotic typography | +| **沉浸式3D** | Immersive 3D | 互动3D场景、空间感极强 | Immersive 3D website, interactive product model in space | diff --git a/docs/es-es/stage-2/frontend/lovart-assets/index.md b/docs/es-es/stage-2/frontend/lovart-assets/index.md new file mode 100644 index 0000000..d42beb1 --- /dev/null +++ b/docs/es-es/stage-2/frontend/lovart-assets/index.md @@ -0,0 +1,949 @@ + + +# 从 NanoBanana 出发,搭建自己的素材生产Agent + +## 第 1 章:1 分钟生成第一份图片素材 + +在开始讨论设计、风格或提示词之前,我们先用最少的步骤生成第一张图片。 + +### 1.1 认识 NanoBanana + +在开始讨论设计风格、提示词工程之前,我们先解决一件更重要的事:**确认你真的可以生成一张图片。** + +当前主流的大模型已经具备图像生成与编辑能力,这类模型通常被称为**生成式模型。** + +为了把流程尽量简化,本教程选择了一个已经具备稳定图像生成与编辑能力的模型作为示例——NanoBanana。它是 Google 推出的图像生成模型,正式名称为 **Gemini 3.1 Flash Image Preview** ,支持通过自然语言直接生成图片,也支持在已有图片基础上进行修改。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image1.png) + +在能力层面,它和你可能听说过的其他模型(如 GPT-4o、Claude、Qwen、Midjourney 等)并没有本质区别:**输入描述,模型负责生成结果。** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image2.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image3.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image4.png) + +你可以把它理解为一支“画笔”。我们在这一章只关心一件事: + 👉 **这支画笔能不能在你手里画出第一笔。** + +在实际使用中,NanoBanana 可以通过 **Google AI Studio** 等官方平台直接使用,也可以通过 **API** 的方式集成到开发流程中。本教程采用 API 调用方式。现在还推出了NanoBanana 2模型,你可以使用最新的大模型进行尝试。 + +### 1.2 “Hello World” 级别的生成 + +在开始之前,你只需要完成下面三步: + +1. 在 Trae 中新建一个文件夹 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image5.png) + +2. 新建一个 Python 文件 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image6.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image7.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image8.png) + +3. 将下面的代码完整粘贴进去 + +Trae 会自动完成所需的环境Despliegue与依赖安装,不需要额外配置。 + +代码中会用到 NanoBanana 的 API Key。这里不展开申请流程——只要你能获取并填入对应参数即可。**这一阶段不追求理解每一行代码,只要它能成功运行。** + +```Python +# /// script +# dependencies = [ +# "gradio>=4.0.0", +# "pillow>=10.0.0", +# "requests>=2.31.0", +# ] +# /// + +import gradio as gr +import requests +import base64 +from PIL import Image +import io +import os +import time +import re +from typing import Optional, Dict, Any, List + +# 配置 API 信息 +NANOBANANA_API_URL: str = "YOUR API URL" +NANOBANANA_API_KEY: str = "YOUR API KEY" +OUTPUT_DIR: str = "outputs" + +# 确保输出目录存在 +os.makedirs(OUTPUT_DIR, exist_ok=True) + +def image_to_base64_data_uri(image: Image.Image) -> str: + """ + 将 PIL 图像转换为 OpenAI API 兼容的 data URI 格式。 + """ + buffer = io.BytesIO() + # 统一转为 PNG 以保证兼容性 + image.save(buffer, format="PNG") + encoded = base64.b64encode(buffer.getvalue()).decode('utf-8') + return f"data:image/png;base64,{encoded}" + +def base64_to_image(base64_str: str) -> Optional[Image.Image]: + """ + 将纯 base64 字符串转换为 PIL Image。 + """ + try: + image_bytes = base64.b64decode(base64_str) + return Image.open(io.BytesIO(image_bytes)) + except Exception as e: + print(f"Base64 解码失败: {e}") + return None + +def extract_base64_from_response(content: Any) -> Optional[str]: + """ + 核心解析逻辑:从 API 返回的 content 中提取图片 Base64 数据。 + 兼容 Markdown 格式和结构化列表格式。 + """ + if not content: + return None + + base64_data = None + + # 1. 尝试结构化提取 (List) + # 对应返回格式: [{"type": "image_url", "image_url": {"url": "data:..."}}] + if isinstance(content, list): + for part in reversed(content): # 倒序查找,通常最新的图片在最后 + if isinstance(part, dict): + # 检查 image_url 或 output_image 字段 + img_field = part.get("image_url") or part.get("image") or part.get("output_image") + if isinstance(img_field, dict): + url = img_field.get("url", "") + if url.startswith("data:image/") and "," in url: + return url.split(",", 1)[1].strip() + + # 如果列表中没有结构化图片,尝试把列表里的文本拼起来找 Markdown + text_parts = [ + str(p.get("text", "")) + for p in content + if isinstance(p, dict) and p.get("type") in ["text", "input_text"] + ] + content_str = "".join(text_parts) + else: + content_str = str(content) + + # 2. 尝试 Markdown 正则提取 (String) + # 对应返回格式: "Here is your image: ![img](data:image/png;base64,AAAA...)" + pattern = re.compile(r"!\[.*?\]\((data:image/[^;]+;base64,[^)]+)\)", re.IGNORECASE) + match = pattern.search(content_str) + + if match: + data_url = match.group(1) + if "," in data_url: + return data_url.split(",", 1)[1].strip() + + return None + +def synthesize(prompt: str, input_image: Optional[Image.Image]) -> Optional[Image.Image]: + """ + 调用 Nanobanana API 进行生成。 + """ + if not prompt or not prompt.strip(): + gr.Warning("请输入提示词") + return None + + print(f">>> 开始任务: {prompt[:50]}...") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {NANOBANANA_API_KEY}" + } + + # 构造符合 OpenAI Vision / Chat 标准的 payload + messages = [] + + if input_image is not None: + # 图生图/多模态输入模式 + print(">>> 检测到输入图片,使用多模态模式") + img_base64 = image_to_base64_data_uri(input_image) + messages.append({ + "role": "user", + "content": [ + {"type": "text", "text": prompt}, + {"type": "image_url", "image_url": {"url": img_base64}} + ] + }) + else: + # 纯文生图模式 + messages.append({ + "role": "user", + "content": prompt + }) + + payload = { + "messages": messages, + # 使用第一段代码中验证可用的模型 + "model": "gemini-2.5-flash-image", + # 可选参数,视 API 支持情况而定 + "stream": False + } + + try: + # 增加超时时间,图片生成通常较慢 + response = requests.post(NANOBANANA_API_URL, headers=headers, json=payload, timeout=120) + + # 检查 HTTP 状态 + if response.status_code != 200: + error_msg = f"API 请求失败: {response.status_code} - {response.text}" + print(error_msg) + gr.Error(error_msg) + return None + + result = response.json() + # Debug: 打印返回结果的前一部分,方便调试 + print(f"API 原始响应 (截取): {str(result)[:200]}...") + + # 提取 Content + content = None + if "choices" in result and len(result["choices"]) > 0: + content = result["choices"][0].get("message", {}).get("content") + + if not content: + gr.Warning("API 返回结果中没有 content 字段") + return None + + # 使用之前验证过的逻辑提取 Base64 + base64_str = extract_base64_from_response(content) + + if base64_str: + output_image = base64_to_image(base64_str) + if output_image: + return output_image + + # 如果没提取到图片,可能是模型拒绝了或只返回了文本 + text_content = str(content) if not isinstance(content, list) else " ".join([str(x) for x in content]) + gr.Info(f"未生成图片,模型返回文本: {text_content[:100]}...") + return None + + except requests.exceptions.Timeout: + gr.Error("请求超时,请稍后重试") + return None + except Exception as e: + import traceback + traceback.print_exc() + gr.Error(f"发生未知错误: {str(e)}") + return None + +# Gradio 界面配置 +with gr.Blocks(title="Nanobanana Image Generator") as app: + gr.Markdown("# 🍌 Nanobanana Text/Image to Image") + gr.Markdown("基于 Gemini-2.5-Flash-Image 模型,支持文生图与图生图。") + + with gr.Row(): + with gr.Column(): + prompt_input = gr.Textbox( + label="提示词 (Prompt)", + placeholder="例如: A cyberpunk cat holding a neon sign...", + lines=3 + ) + image_input = gr.Image( + label="参考图 (可选,用于图生图)", + type="pil", + height=300 + ) + submit_btn = gr.Button("开始生成", variant="primary") + + with gr.Column(): + image_output = gr.Image(label="生成结果", format="png") + + submit_btn.click( + fn=synthesize, + inputs=[prompt_input, image_input], + outputs=image_output + ) + +if __name__ == "__main__": + app.launch(share=True) +``` + +当 Trae 提示运行成功后,点击它提供的本地链接(通常是 http://127.0.0.1:7860)。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image9.png) + +如果一切正常,你会看到一个已经可以工作的 AI 绘图界面。 + +这个界面看起来很简单,但它已经具备了商业级绘图工具中最核心的两项能力,即文生图和图生图。 + +* **左侧:** **指令区 (** **Input** Zone) —— 你在这里发号施令。 +* **Prompt (提示词框):** 输入你的创意描述(推荐使用英文)。 +* **Input** Image (参考图框): + * **文生图模式:** 保持此处 **为空** 。 + * **图生图模式:** 将本地图片拖入此处,AI 会以它为基础进行创作。 +* **Submit 按钮:** 点击即可发送指令,开始生成。 +* **右侧:展示区 (** **Output** Zone) —— 见证奇迹的地方,生成结果将在此显示。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image10.png) + +现在我们可以尝试生成你的第一张图片了! + +本示例使用的 prompt 如下: + +> **A red apple** + +这是一个刻意简化的示例,不包含任何风格或参数描述。 + +#### 实际流程 + +运行代码后,流程可以概括为三步: + +1. 将文字描述发送给模型 +2. 模型生成对应图片 +3. 图片被保存为本地文件 + +几秒钟后,你会在本地看到生成结果。而模型生成具有随机性,所以相同的prompt会有不同的生成结果,你可以多次生成,选择你心仪的图片。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image11.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image12.png) + +也可以丰富你的提示词,给予它更多的描述和限定。例如以下提示词,得到的图片就会更加特殊一些。 + +```Plain +"A hyper-realistic close-up of a fresh red apple with water droplets on its skin, sitting on a dark rustic wooden table. Cinematic dramatic lighting, rim light, shallow depth of field, bokeh background, 8k resolution, macro photography." +(一个超写实的带水珠的新鲜红苹果特写,放在深色粗糙木桌上。电影级戏剧光效,轮廓光,浅景深,背景虚化,8k分辨率,微距摄影。) +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image13.png) + +在Output Image区域点击下载图片即可保存到本地。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image14.png) + +### 1.3 生图模型常见的素材生成场景 + +在实际工作中,大模型生成图片更多用于 **高效产出设计素材** ,而不是创作单张艺术作品。 + +当你观察一些设计类营销账号的高赞案例时会发现,它们的产出大多集中在两类场景: + +* **文生图(从 0 到 1)** +* **有图参考生图(从 1 到 N)** + +#### 一、文生图:快速获取设计物料 + +这一类场景关注效率。当需要填补设计中的空白(如空状态、头像、配图)时,AI 本质上充当的是一个 **即时生成的图库** 。 + +1. ##### 生成 UI 设计物料 + +* 流行趋势:Dribbble 上常见的毛玻璃、黏土风 3D 图标 +* 常见表现:通透材质、边缘发光、糖果配色的功能或天气图标 + +**示例 Prompt:** + +> A set of 3D weather icons (sun, cloud, rain), glassmorphism style, frosted glass texture, soft pastel gradient colors, soft studio lighting, isometric view, transparent background, 4k. + +(一套 3D 天气图标,毛玻璃风格,磨砂质感,柔和渐变色,影棚光,等轴视图) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image15.png) + +2. ##### 生成 Logo + +* 流行趋势:极简线条、几何组合的科技感 Logo +* 常见表现:黑白配色、负空间设计、品牌感明确 + +**示例 Prompt:** + +> Minimalist vector logo design for a tech brand "Coffee Code", combining a coffee cup with coding brackets < >, flat design, solid black lines, white background, Paul Rand style, svg. + +(极简矢量 Logo,结合咖啡杯与代码符号,扁平设计,纯黑线条) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image16.png) + +3. ##### 生成官网用户图片 + +* 流行趋势:SaaS 官网常用 3D 虚拟头像,用于规避真人版权 +* 常见表现:友好表情、卡通比例、偏 Pixar 或 Memoji 风格 + +**示例 Prompt:** + +> Close-up portrait of a friendly young tech professional, smiling, Memoji 3D style, clay render, bright colors, soft lighting, solid plain background, Pixar character design. + +(友好的年轻科技从业者,3D Memoji 风格,黏土渲染) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image17.png) + +4. ##### 生成文章配图 + +* 流行趋势:科技公司博客中常见的抽象扁平插画 +* 常见表现:紫蓝配色、夸张人物比例、漂浮 UI 元素 + +**示例 Prompt:** + +> Editorial flat illustration representing remote work, a person sitting on a giant globe using a laptop, corporate memphis art style, vibrant colors (purple and teal), vector texture. + +(远程办公主题扁平插画,企业孟菲斯风格) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image18.png) + +#### 二、有图参考生图:保持视觉一致性 + +这一类场景更关注 **扩展性** 。当你已经有一张满意的主视觉,需要生成一整套风格一致的素材时使用。 + +5. ##### 主视觉相似的一套按钮或交互素材图 + +在游戏开发中,UI 的一致性非常关键。假设你已经有了主界面的 **“PLAY”** 按钮,现在需要扩展出一整套风格统一的功能按钮(如暂停、设置、主页)。仅靠手绘很难保证每个按钮在光泽、透视和色值上的完全一致。 + +**基本操作流程:** + +1. 保存已有的蓝色 “PLAY” 按钮图片 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image19.png) + +2. 将其拖入界面的 **Input**** Image** 区域,作为后续生成的参考母版 +3. 保持 prompt 中的风格描述不变,仅修改主体内容 + +在这一流程下,只要替换主体描述,就可以得到不同功能但风格一致的按钮。 + +**示例 Prompt:** + +**变体 A:暂停按钮(图标类)** + +> A capsule-shaped game UI button with a white pause icon (two vertical bars) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(胶囊形游戏 UI 按钮,白色暂停图标,蓝色果冻质感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image20.png) + +**变体 B:设置按钮(复杂图标)** + +> A capsule-shaped game UI button with a white gear icon (settings symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(胶囊形游戏 UI 按钮,白色齿轮图标,蓝色果冻质感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image21.png) + +**变体 C:重玩按钮(形状变化)** + +如果需要调整按钮外形,可以在 prompt 中直接描述形状,模型会在保留材质特征的同时尝试改变结构。 + +> A round game UI button with a white circular arrow icon (replay symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(圆形游戏 UI 按钮,循环箭头图标,蓝色果冻质感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image22.png) + +通过这一组操作,你不仅可以替换按钮功能和图标,甚至改变按钮形状,但所有生成结果在材质、配色和光影上仍保持高度一致。这正是大模型在设计素材裂变场景中的核心价值。 + +## 第 2 章:更听话的图像生成助手 —— 以 Lovart 为例 + +在Primera parte,我们通过代码直接调用 NanoBanana,体验了“输入即生成”的基础流程。这种方式在需求简单时没有问题。但当生成任务开始包含更多约束,例如: + +* 需要多张风格一致的图片 +* 需要在已有结果上反复调整 +* 需要根据用户输入动态修改生成方向 + +单次调用的方式就会逐渐变得不够用。 + +这时,就需要引入 **AI Agent(** **智能体** **)** 。本节以 **Lovart** 为例,展示当图像生成模型具备“思考层”后,整体工作流会发生怎样的变化。注意!这里不是打广告,只是帮助大家快速get到AI Agent的便捷性~ + +### 2.0 初识 Lovart:你的 AI 设计代理 + +Lovart 是一个基于 Agent 的设计工具 Web。相比普通生图工具,它在生成之前多了一层“思考与规划”。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image23.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image24.png) + +进入 Lovart 后,主要需要了解以下几个控制项: + +#### 模型选择 + +点击输入框下方的立方体图标,可以查看当前可用的生成模型(如 GPT Image、Flux 等)。 + +为了与前文示例保持一致,本节仍然使用 NanoBanana 作为底层生成模型。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image25.png) + +#### 思考模式 + +这是 Lovart 的核心开关: + +* **Fast Mode(⚡)** :接近原生 API,响应快,适合单张、明确指令的生成 +* **Thinking Mode(💡)** :Agent 模式,AI 会先拆解需求、改写 prompt,再执行生成 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image26.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image27.png) + +#### 联网能力 + +开启地球图标后,Agent 可以在生成过程中检索网络信息(例如设计趋势、配色风格),作为辅助输入。 + +### 2.1 为什么原生 API 还不够? + +即使已经可以通过 Python 生成质量不错的图片,原生 API 在复杂任务中仍然存在限制。关键原因在于:原生 API 本质上是指令式的。当你要求它生成一个具体对象时,它可以直接执行;但当输入变成“策划一套完整的游戏素材”时,它并不会主动将目标拆解为多个可执行步骤。 + +Lovart 的核心差异在于 Agent 机制。在用户输入与图像生成模型之间,它加入了一层用于理解和规划的逻辑:先识别用户意图,再拆解任务、重写 prompt,最后才执行生成。 + +### 2.2 实战演示:5 分钟打造一套 IP 表情包 + +以 **“制作一套程序员鸭子 ****IP**** 表情包”** 为例,看看 Agent 是如何参与整个流程的。 + +#### 环节一:策划(Agent 的思考能力) + +**原生 ****API**** 的问题:** +你需要自己思考角色设定、情绪状态,并为每一张图单独编写 prompt。 + +**Lovart 的做法:** + +1. 点亮 💡 **Thinking Mode** +2. 输入一句指令: + +> 设计一套程序员鸭子的 IP 表情包,风格要扁平化、可爱 + +AI 不会立即画图,而是先去网络上搜索相关的程序员鸭子的设计图。输出一份拆解后的方案,自动生成 Debug、Coffee Break、Panic 等场景,并对应生成多条视觉描述。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image28.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image29.png) + +这一步,AI 从“执行者”转变为“策划者”。在AI帮你分析完需求后,可以在Lovart的画布区看到多种风格和内容的程序员鸭子图片。可以开始筛选你喜欢的风格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image30.png) + +#### 环节二:一致性(基于参考的视觉锚定) + +Lovart 中的图片不仅是结果,也参与后续生成。 + +##### 完整参考图 + +* 从草图中选出一张最满意的“标准鸭子”,在画布区点击对应图片 +* 该图将会自动出现在对话区,作为 Reference + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image31.png) + +* 输入新的动作(如开心)并生成 + +生成结果会继承母版的配色、比例和细节。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image32.png) + +##### 局部参考 / 多图整合 + +除了整张图片作为参考,Lovart 还支持: + +* **只选取图片的局部区域** (例如只参考帽子或表情) + +点击画布区左侧tab栏,选择「Mark」键,在目标图像的局部区域标记即可,这部分内容会自动同步到对话框。比如在这里我们可以选择修改背景的颜色。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image33.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image34.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image35.png) + +能看到新生成的图片只改变了背景的颜色,这也跟我们输入的要求一致。 + +* **从多张图片中分别引用子元素** ,再组合生成新结果 + +例如:你可以保留 A 图的角色主体,同时只替换帽子为 B 图中的样式,Agent 会在后台自动整合这些视觉约束。 + +以程序员鸭子为例,我们可以选择保留第一个图中的鸭子形象,并将其替换到第二张图中作为主体元素。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image36.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image37.png) + +最后的效果也非常显著。你也可以试着其他的组合! + +#### 环节三:落地(Agent 的工具调用) + +生成完成后,可以直接执行:放大、移除背景、擦除等操作 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image38.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image39.png) + +这些并不是简单滤镜,而是 Agent 自动调度不同工具完成的结果。 + +而在确定完基调风格后,可以很快速的生成一系列的表情包图像。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image40.png) + +最终我们得到的是可直接交付的生产级素材,而不仅是一张展示图。 + +### 2.3 使用与收费方式说明 + +Lovart 采用订阅制收费模式,不同套餐对应不同的使用额度与功能权限,具体以官网展示为准。 + +本教程不对任何套餐做推荐或比较;如果在实际使用中有需求,可以根据个人情况选择付费升级。 +目前支持通过**支付宝**等方式完成支付。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image41.png) + +#### 小结 + +Lovart 并不是替代底层模型,而是通过 Agent 机制,让图像生成从“单次执行”升级为“连续工作流”。 + +当任务开始涉及策划、一致性和交付时,这类工具的优势会变得非常明显。 + +## 第 3 章:自己动手做一个智能绘图助手 + +除了直接使用 Lovart,我们也可以自己实现一个简化版的绘图助手。 + +本章以“文章自动配图”为例,从实际问题出发,逐步搭建一个带有思考能力的 Agent。 + +### 3.1 痛点引入:为什么直接发文章给画图模型没用? + +直接将一篇较长的文章输入给 NanoBanana 并要求配图,通常很难得到理想结果。原因并不在于模型“画得不行”,而在于 **它并不擅长理解长文本** 。 + +图像生成模型更适合处理简短、明确的视觉描述,而当输入变成一段包含结构、重点和上下文关系的文章时,模型无法判断哪些内容才是画面中真正需要表达的部分。这往往会导致生成结果偏离主题,或只能捕捉到零散细节,缺乏整体概括能力。 + +本质上,图像模型只有“执行”的能力,却缺少对文本进行分析和取舍的过程。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image42.png) + +### 3.2 解决思路:用 Agent 把「理解」和「执行」拆开 + +要解决这个问题,关键并不是更复杂的提示词,而是 **在绘图之前先把事情想清楚** 。因此,我们在生成流程中引入一个独立的「思考层」,并以此构建一个最简单可用的 Agent。 + +这个 Agent 的核心目标只有一个:**让最终生成的图片,尽可能贴近用户真正的表达意图。** + +整体流程可以概括为:**长文本输入 → 语言模型理解与判断 → 生成合适的视觉提示词 → 图像模型执行生成 → 输出图片** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image43.png) + +那我们构建的 Agent 怎样才能明白用户的意图呢? + +这里选择做一个简化的 **“思考层”** ,我们设置了三种不同的意图:无效输入、直接生图、需要理解的长文本。 + +在这个 Agent 中,各个角色的分工可以概括为四点: + +1. **语言模型作为决策核心** + 它负责理解文章内容、判断用户输入的意图,并将任务分发到合适的生成路径中,决定接下来“该怎么做”以及如何生成生图提示词。 +2. **图像模型作为执行者** + 图像模型不参与理解与判断,只接收已经整理好的视觉指令,专注完成图像渲染。 +3. **用户作为可介入的引导者** + 除了直接输入文本,用户还可以在过程中手动调整生成的提示词,或加入参考图来辅助生成,从而对最终结果进行引导和微调。 +4. **Gradio 与后端 ****API**** 作为整体承载层** + 它们负责将界面、模型调用和结果展示串联起来,保证整个 Agent 能够以一个完整 Web 应用的形式稳定运行。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image44.png) + +### 3.3 实战准备 :获取API + +看起来是不是很有趣呢!要跑通上述流程,我们只需要准备两类 API。 + +#### 手:NanoBanana API(图像生成) + +直接沿用第 1 章中已经配置好的 API Key 和 API URL,无需额外设置。 + +#### 脑:SiliconFlow API(文本思考) + +我们需要一个大语言模型来承担“思考层”的Responsabilidad。本教程使用 SiliconFlow 提供的模型服务:[https://cloud.siliconflow.cn](https://cloud.siliconflow.cn/) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image45.png) + + SiliconFlow 提供了兼容 OpenAI API 规范的接口,可以非常方便地在项目中通过标准网络请求进行调用。在这里我们选择的是免费的Qwen2.5-7B-Instruct模型,调用需要的内容都已经写入下面的Prompt。在开始之前,你只需要在官网注册账号并创建一个 API Key。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image46.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image47.png) + + 该 Key 将用于后续的模型调用。 + +### 3.4 搭建Agent : + +本次实验主要使用Trae来帮我们编写代码,本教程选用的是Gemini-3-Pro-Preview模型。总思路是,新建项目后将下述完整 Prompt 复制到对话框并输入,逐步替换 API KEY 后运行代码,完成测试即可。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image48.png) + +#### 环节1️⃣:Gradio Blocks 基础框架与界面布局 + +在这个环节,我们的主要目标是先给整个Agent搭建出一个“外观”,实现前端的页面设计。复制以下Prompt在Trae对话框中实现后,你将会得到一个本地的URL(通常是 http://127.0.0.1:7860 )即可查看界面,并且检验实现效果。 + +```Plain +板块 1:Gradio Blocks 基础框架与界面布局 +1、任务目标 +·基于 Gradio 4.0.0+ 的 Blocks 布局,实现「LLM+Nanobanana 文生图」项目的基础界面,严格遵循固定左右分栏布局,初始化所有 UI 组件并设置正确的初始状态。 + +2、技术栈要求 +·必须使用 Gradio 4.0.0+ 的 Blocks 模式开发,禁止使用 Interface 模式; +·依赖:gradio>=4.0.0,pillow>=10.0.0(仅导入,暂不实现图片处理逻辑); +·代码需是完整可运行的 Python 文件,包含所有必要的导入语句。 + +3、界面布局规则(核心约束,融合实战细节) +·整体布局: +页面标题:LLM 驱动的文生图全流程工具; +固定左右分栏:左侧占 60% 宽度,右侧占 40% 宽度,使用 gr.Row 和 gr.Column 实现比例控制。 +·左侧 60%(提示词生成流程区)组件清单: +input_text:gr.Textbox,标签「输入文本(教程段落 / 绘图指令)」,lines=6,占位符「请输入需要配图的教程文本或直接绘图指令...」; +identify_intent_btn:gr.Button,value="识别意图",初始状态正常可点击; +intent_status:gr.Textbox,标签「意图类型 / 处理状态」,lines=2,interactive=False,初始值「未识别意图」; +system_prompt:gr.Textbox,标签「System Prompt(仅文章配图意图可编辑)」,lines=4,interactive=False,占位符「LLM 生成提示词的约束规则...」; +confirm_prompt_btn:gr.Button,value="确认生成生图提示词",interactive=False(初始禁用防误触); +generation_prompt:gr.Textbox,标签「生图提示词(可编辑)」,lines=3,interactive=True,初始值为空,占位符「生成的英文生图提示词将显示在此,支持手动修改...」。 +·右侧 40%(Nanobanana 生图功能区)组件清单: +ref_image:gr.Image,标签「参考图(可选,图生图)」,type=filepath,height=300,允许上传; +generate_btn:gr.Button,value="生成图片",interactive=False(初始禁用,无提示词不可点击); +result_image:gr.Image,标签「生成结果」,type=pil,height=300,初始为空,interactive=False。 + +4、交互逻辑要求 +·所有组件的 interactive 初始状态严格按上述配置,后续通过函数动态更新; +·按钮禁用状态需直观(置灰),避免用户误操作。 + +5、输出要求 +·生成完整的 Python 代码,仅实现界面布局和组件初始化,不包含任何业务逻辑; +·代码注释清晰,组件命名与实战版一致(input_text/identify_intent_btn 等); +·代码可直接运行,界面结构与描述完全一致。 +``` + +在浏览器打开http://127.0.0.1:7860后可看到Trae已经按照我们的要求生成了以下的网页,跟我们的要求大致相当,可以进行到下一步的生成中了。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image49.png) + +#### 环节2️⃣:LLM 意图识别模块(Siliconflow API) + +在日常使用VLM画图的时候,可能有以下三种常见输入情况: + +1. 无意义内容,比如“你好”、“你今天吃饭了吗”等,无法画出对应的图片。 +2. 文章/长文本,字数较多,比如200字左右的一篇有结构的文章,需要先理解文章的结构与内容,再考虑如何生成能完整概括这段文字的图片。 +3. 直接绘图指令,比如“帮我画一只在洗澡的狗”等,要求已经阐述的非常具体,可以直接生成图片。 + +跟前面一样,复制以下Prompt在Trae对话框中实现,并且补充在前面步骤中获得的API。 + +```Plain +板块 2:LLM 意图识别模块(Siliconflow API) +1、任务目标 +在已实现的 Gradio 界面基础上,为「识别意图」按钮添加点击逻辑,调用 Siliconflow API 完成意图识别,并联动组件状态。 + +2、技术栈要求 +基于 Gradio 4.0.0+ Blocks; +依赖:requests>=2.31.0,openai; +输出完整可运行 Python 文件,包含板块 1 界面 + 本模块逻辑。 + +3、核心业务规则(绝对不可偏离) +·意图分类规则(仅 3 类,严格返回数字 + 描述) +1 = 无意义内容:仅闲聊、寒暄、无关对话,没有任何绘图或配图需求(如 “你好”“今天吃了吗”); +2 = 文章 / 长文本配图需求:用户输入一段完整文章、教程、段落、说明性文字,内容偏叙事 / 说明 / 讲解,隐含需要为这段内容生成配图的意图,不需要用户明确说 “为这段文字配图”; +3 = 直接绘图指令:用户输入简短、明确的画图命令,没有长文本背景,直接要求画某个内容(如 “画一只 Apple 风格的猫”)。 +·LLM 调用约束(融合实战版模板) +接口地址:https://api.siliconflow.cn/v1/chat/completions; +模型:Qwen/Qwen2.5-7B-Instruct; +temperature=0.1; +统一定义代码: +python +运行 +LLM_BASE_URL = "https://api.siliconflow.cn/v1" +LLM_API_KEY = "" # 用户自行替换 +LLM_MODEL = "Qwen/Qwen2.5-7B-Instruct"# 实战验证的意图识别模板(固化到代码中) +INTENT_PROMPT_TEMPLATE = """你需要识别用户输入文本的意图,仅返回以下 3 类结果中的一种(格式:数字 + 中文描述): +1 = 无意义内容;2 = 文章 / 长文本配图需求;3 = 直接绘图指令。 + +用户输入:{user_input} + +识别结果: +仅提取返回结果中的数字和描述,禁止额外内容。""" + +4、组件联动规则 +·结果为 1:intent_status 显示「1 = 无意义内容:无绘图需求」,system_prompt 保持禁用,confirm_prompt_btn 禁用; +·结果为 2:intent_status 显示「2 = 文章 / 长文本配图需求:为输入内容生成配图」,启用 system_prompt 并填充默认规则,激活 confirm_prompt_btn; +·结果为 3:intent_status 显示「3 = 直接绘图指令:根据指令生成图片」,system_prompt 禁用且填充默认规则,激活 confirm_prompt_btn。 + +5、异常处理 +API 异常、解析异常均给出友好提示,不崩溃,组件恢复初始状态。 + +6、输出要求 +生成完整可运行代码,替换 LLM_API_KEY 即可使用,逻辑清晰注释完整,意图识别模板严格使用实战版。 +``` + +刷新之前的http://127.0.0.1:7860网址,开始测试是否能正确检测三种情况。 + +1. 无意义内容,可以尝试输入“你好”、“谢谢”等,发现能够正常识别。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image50.png) + +2. 文章/长文本,在这里我们选用了一段豆包生成的描述人工智能的文字。你也可以尝试使用自己的论文段落进行测试。 + +```Plain +人工智能正在以前所未有的深度和广度重塑教育生态系统。通过自适应学习算法,AI系统能够构建每个学生的认知图谱,实时追踪他们的知识掌握轨迹,并动态调整教学内容的难度和呈现方式。在传统课堂环境中,教师往往难以同时满足不同学习风格和能力水平的学生需求,而基于深度学习的教育平台可以分析学生在交互式模拟实验中的行为模式,识别他们在量子力学或微积分等复杂概念理解上的微妙障碍,并提供精准的认知支架。 + +高级自然语言处理引擎驱动的虚拟导师不仅能够解构开放性问题,如"如何评价法国大革命对现代民主制度的影响",还能引导苏格拉底式对话,激发批判性思维。当学生撰写关于气候变化对极地生态系统影响的论文时,AI写作助手可以分析其论证逻辑的严密性,指出数据引用中的时效性问题,并建议更精准的科学术语。在特殊教育领域,计算机视觉技术使AI能够识别自闭症谱系儿童在社交互动中的非语言线索,调整干预策略,而情感计算算法则帮助检测在线学习时的挫折感,及时提供鼓励性反馈。 + +然而,这种技术融合引发了一系列伦理困境。算法偏见可能无意中边缘化特定文化背景的学生,数据采集的透明度问题引发了对学术隐私的关切,而过度依赖自动化评分系统可能削弱教师对学生思维过程的深层理解。更复杂的是,当AI开始生成高度逼真的虚拟实验室体验时,我们需要重新定义"实践经验"在教育中的价值。未来教育的范式可能演变为人类教师专注于培养创造力、同理心和道德判断力,而AI系统则承担知识传递、技能训练和个性化评估的职能,形成一种协同进化的教育共生体,既能发挥机器的计算优势,又能保留人类教育的独特温度. +``` + +同样检测成功~ + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image51.png) + +3. 直接绘图指令,这里输入的是“我要画一只猫”,同样检测准确。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image52.png) + +到这里我们就已经顺利实现了第二个环节——意图识别。 + +#### 环节3️⃣:生图提示词生成模块(LLM 二次调用) + +意图识别后,对于文章或长文本,还有很重要的一步就是生成画图的提示词,而这正是本Agent的重点。 + +```SQL +板块 3:生图提示词生成模块(LLM 二次调用) +1、任务目标 +在意图识别基础上,实现「确认生成生图提示词」按钮逻辑,调用 LLM 将文本优化为适合绘图的英文视觉提示词,填充到编辑框并联动「生成图片」按钮。 + +2、技术栈要求 +同板块 2,输出完整代码 = 板块 1 + 板块 2 + 本模块; +共用板块 2 定义的 LLM_BASE_URL、LLM_API_KEY、LLM_MODEL,不新增密钥。 + +3、核心业务规则(融合实战版 Prompt 组装逻辑) +·提示词生成输入规则(必须严格遵循) +生图提示词生成不再是简单字符串拼接,而是构建标准 Chat 消息列表,代码结构如下: +python +运行 +messages=[# System角色:网页上用户最终确认/编辑后的system_prompt内容{"role": "system", "content": final_system_prompt},# User角色:承载待处理数据,明确任务目标{"role": "user", "content": f"请为以下内容生成视觉提示词:\n\n{user_input}"}] +意图为 2 时:System 内容取用户编辑后的 system_prompt 最终版本; +意图为 3 时:System 内容取禁用状态下填充的默认规则 +user_input 为用户最初输入到 input_text 框的原始文本。 +·实战验证的 System Prompt 预设(固化到代码中) +python +运行 +SYSTEM_PROMPT_DEFAULT = """你现在是一个创建NanoBanana画图提示词的助手。 +需要根据我的内容处理,我这个图片的作用是能说明这一段在说什么,并且让大家知道这段话的上下结构就是整体说的是什么意思。 +里面可能会类似PPT有一些讲解(如:左上角展示核心观点,右下角展示数据)。 +设计风格要求:简约,Apple设计思维(Apple Design Philosophy)。 +约束:请直接返回NanoBanana可用的英文提示词,不要返回任何解释、前缀或多余的废话。""" +·LLM 调用约束 +与板块 2 共用同一套 LLM_BASE_URL、LLM_API_KEY、LLM_MODEL; +temperature=0.7(保证提示词的创意性与适配性); +max_tokens=200(限制输出长度,匹配提示词约束); +严格使用上述标准 Chat 消息列表结构,禁止字符串拼接。 +·示例输入输出(核心参考) +输入示例 1(文章配图意图):原始文本:「AI 如何改变教育:随着人工智能技术的发展,教师的角色从知识传授者转变为引导者,AI 助手可辅助学生完成个性化学习,课堂上人机协作成为常态。」最终 System Prompt:SYSTEM_PROMPT_DEFAULT(未修改)输出预期:"Minimalist illustration, Apple Design Philosophy, 1024x1024. Top left shows 'AI + Education' core concept, bottom right shows data of teacher-student-AI collaboration, soft color palette, clean lines, no redundant elements." +输入示例 2(直接绘图指令):原始文本:「画一只 Apple 风格的猫,坐在 MacBook 旁边」最终 System Prompt:SYSTEM_PROMPT_DEFAULT(禁用状态)输出预期:"Minimalist cat, Apple style, 1024x1024, sitting next to a silver MacBook, clean white background, soft shadows, geometric shapes, no extra details." +·提示词输出强制约束 +纯英文,无中文; +必须包含 Apple Design Philosophy/Apple style + 1024x1024; +长度 50–200 字符,代码内校验; +无额外解释、前缀或废话,仅返回提示词本身。 + +4、组件联动规则 +生成成功:将提示词填入 generation_prompt 框,激活 generate_btn,intent_status 追加「提示词生成成功,可修改后生成图片」; +生成失败:提示具体原因(如 API 调用失败、长度不达标),generate_btn 保持禁用,generation_prompt 框为空; +用户手动修改 / 清空 generation_prompt 框: +清空时自动禁用 generate_btn; +非空时保持 generate_btn 激活。 + +5、异常处理 +API 调用失败:友好提示「提示词生成失败:{具体错误信息}」,不崩溃; +提示词校验失败:明确提示原因(如 “未包含 Apple style”“长度仅 40 字符”),允许重试; +响应解析失败:提示「无法解析 LLM 返回结果,请重试」。 + +6、输出要求 +完整可运行代码,替换 LLM_API_KEY 即可使用; +代码结构清晰、注释完善,界面美观简洁; +严格实现标准 Chat 消息列表结构,参数与示例逻辑一致; +包含提示词长度、内容校验逻辑,错误提示友好。 +``` + +同样复制第二个环节的文本进行检测。 + +值得注意的是,我们在这里预设的生成生图提示词的System Prompt为: + +> 你现在是一个创建NanoBanana画图提示词的助手。 +> 需要根据我的内容处理,我这个图片的作用是能说明这一段在说什么,并且让大家知道这段话的上下结构就是整体说的是什么意思。 +> 里面可能会类似PPT有一些讲解(如:左上角展示核心观点,右下角展示数据)。 +> 设计风格要求:简约,Apple设计思维(Apple Design Philosophy)。 +> 约束:请直接返回NanoBanana可用的英文提示词,不要返回任何解释、前缀或多余的废话。 + +如果你想换成其他的预设模版,可以在前面的prompt里修改,或者直接在Trae里通过对话修改。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image53.png) + +除了修改底层代码,我们在网页上也可以快速编辑。举个例子,我在这里加了一句,“在前面加一句Pic Prompt”,可以看到生成的新的提示词前面也包含了~这样设计是为了方便快速修改生成提示词的System Prompt,帮助我们快速切换风格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image54.png) + +#### 环节4️⃣:Nanobanana 文生图 / 图生图模块 + +终于来到了最后一步,不接入生图模型,就不是一个完整的Agent! + +```Bash +板块 4:Nanobanana 文生图 / 图生图模块(最终版) +1、任务目标 +实现「生成图片」按钮逻辑,调用真实 Nanobanana API,支持文生图 / 图生图,解析 Base64 并展示图片。 + +2、技术栈要求 +基于 Gradio 4.0.0+ Blocks; +依赖:requests, pillow, base64, io, re; +完整代码 = 板块 1+2+3 + 本模块。 + +3、核心 API 配置(实战验证固化) +固化代码配置: +python +运行 +# 固化到代码中的API配置 +NANOBANANA_API_URL = "https://api.zyai.online/v1/chat/completions" +NANOBANANA_MODEL = "gemini-2.5-flash-image" +NANOBANANA_API_KEY = "" # 用户自行替换 +鉴权方式:Header Authorization: Bearer {NANOBANANA_API_KEY}。 + +4、图片预处理要求(必须实现)实现函数 image_to_base64_data_uri (ref_image_path),核心逻辑: +将 PIL 图片转为 PNG 格式; +自动缩放到 1024x1024 分辨率; +透明通道转为白色背景; +编码为 Base64,返回格式:data:image/png;base64,...。 + +5、请求构建规则(严格按实战版分支逻辑) +·核心函数定义实现函数 generate_image (prompt, ref_image_path): +入参:prompt(generation_prompt 框内容)、ref_image_path(ref_image 上传的文件路径); +返回:PIL Image(展示到 result_image)或错误提示。 +·逻辑分支 1:纯文生图(ref_image_path 为空) +python +运行 +messages = [{"role": "user", "content": prompt}] +·逻辑分支 2:图生图(ref_image_path 有值) +python +运行 +# 先调用图片预处理函数 +image_base64 = image_to_base64_data_uri(ref_image_path) +messages = [{"role": "user","content": [{"type": "text", "text": prompt},{"type": "image_url", "image_url": {"url": image_base64}}]}] + +6、响应解析要求(必须兼容两种格式)从 choices [0].message.content 中提取图片 Base64,支持: +结构化 JSON 返回的 image_url 字段; +Markdown 格式 +; +统一提取 Base64 编码,解码后转换为 PIL Image 返回。 + +7、组件联动与异常处理 +生成成功:将 PIL Image 展示到 result_image,intent_status 提示「图片生成成功」; +生成 / 解析 / 上传失败:在 intent_status 显示清晰文字提示(如 “Base64 解析失败”“API 调用超时”),不崩溃。 + +8、输出要求 +完整可运行代码,替换 LLM_API_KEY 和 NANOBANANA_API_KEY 即可直接运行,全流程可用,分支逻辑严格匹配实战版。 +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image55.png) + +太令人激动啦!我们终于顺利地生成出了这个Agent的第一张图,仔细看看生成的图片,跟我们的文本和提示词是匹配的。到这里你已经基本上实现你自己的Agent啦! + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image56.png) + +我们还添加了图生图功能,上传你喜欢的图片,AI会自动借鉴风格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image57.png) + +值得一提的是,前面步骤生成的提示词也是可以在网页上编辑的,并且我们是以最终点击按钮时的提示词为准~哪怕我在这里换成“a cute cat”,最终生成的图片也只会是可爱的小猫。 + +## 第 4 章:总结 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image58.png) + +**呜呼!终于写完了。** +说实话,连我自己写完最后一行的时候都忍不住长舒一口气,更别说一路跟着做到这里的你了。能把这一整套流程完整跑下来,本身就已经很厉害了,这说明你真的把手放到键盘上,把事情一步步做完了。Bravo 🎉 🥳 👏 + +在写这套内容的过程中,我一直在想,我们到底要留下些什么?答案其实并不是模型名字、参数或者某种固定套路,而是让你慢慢建立起一种感觉:哪些事情可以放心交给 AI 去理解和规划,哪些地方只需要你来决定方向。一旦这层分工成立,很多原本看起来复杂的生成流程,都会开始变得顺起来。 + +回头看,这条路其实并不复杂。想清楚你要解决的问题,把长文本交给语言模型去拆解,再把整理好的视觉意图交给绘图模型去呈现,最后把这一整套流程封装成一个属于你自己的小助手。到这里,你已经不只是“在用模型”,而是在搭建一套可以长期陪你工作的系统,而这,才是这套教程最想带给你的东西。 + +但是你已经做的很棒啦!相信学到这里的你对Vibe Coding已经有初步的掌握了,给自己放个小假休息一下吧! + + diff --git a/docs/es-es/stage-2/frontend/modern-component-library/index.md b/docs/es-es/stage-2/frontend/modern-component-library/index.md new file mode 100644 index 0000000..3d07079 --- /dev/null +++ b/docs/es-es/stage-2/frontend/modern-component-library/index.md @@ -0,0 +1,465 @@ +# 使用现代组件库更新你的界面 + +在前面的课程中,你已经学会了如何用设计工具画出界面、用 AI IDE 把设计稿变成代码,甚至完成了一个完整的前端项目。但你可能也发现了一个问题:自己从零写出来的按钮、表单、弹窗,虽然能用,但总觉得和"专业产品"差了点意思——样式不够统一、交互细节不够丝滑、适配不同屏幕也很头疼。 + +这就是**组件库**要解决的问题。 + +组件库是一套预先设计好、开发好的 UI 零件集合。按钮、输入框、下拉菜单、对话框、表格……这些你在任何产品中都会反复用到的界面元素,组件库已经帮你做好了,而且经过了大量用户的验证和打磨。你只需要像搭积木一样把它们组合起来,就能快速构建出专业级的界面。 + +## Lo que aprenderas + +1. 理解什么是前端组件库,以及为什么现代开发几乎都在用它 +2. 认识四个最具代表性的组件库,了解它们各自擅长的场景 +3. 通过三个实战场景(落地页、产品页面、后台管理),学会用 AI IDE + 组件库进行 Vibe Coding +4. 学会阅读组件库文档,根据需求找到合适的组件并正确使用 + +## 1. 为什么需要组件库? + +想象你在装修房子。你可以自己从木头开始做一把椅子,但更常见的做法是去宜家买一把——设计好看、质量稳定、说明书清晰,拿回家组装就行。 + +组件库就是前端开发中的"宜家"。它提供的不是家具,而是界面零件: + +| 自己手写 | 使用组件库 | +| :--- | :--- | +| 需要自己处理样式、交互、动画 | 开箱即用,样式和交互已经打磨好 | +| 不同页面的按钮可能长得不一样 | 全局风格统一,自动保持一致性 | +| 适配手机、平板需要额外工作 | 大多数组件库已内置响应式支持 | +| 无障碍访问(Accessibility)容易遗漏 | 专业组件库已处理好键盘导航、屏幕阅读器等 | +| 开发速度慢 | 开发速度快,专注业务逻辑 | + +简单来说:**组件库让你把时间花在"做什么"上,而不是"怎么画"上。** + +### 眼见为实:同一个需求,加不加组件库的差距 + +光说不练没有说服力。我们在 Trae 中用几乎相同的需求,分别不指定和指定组件库,看看生成结果的差距。 + +**提示词一:不使用组件库** + +```text +请帮我做一个 AI 写作助手的数据仪表盘页面,包含: +- 顶部标题栏和导出按钮 +- 四张统计卡片显示用户数、活跃用户、文档数、收入,还要显示涨跌趋势 +- 一个折线图和一个饼图 +- 用户列表表格,带分页功能 +- 左侧导航侧边栏 +``` + +在 Trae 中直接运行后的效果: + + + + +**提示词二:使用 shadcn/ui 组件库** + +```text +请帮我做一个 AI 写作助手的数据仪表盘页面,用 shadcn/ui 组件库来做,包含: +- 顶部标题栏和导出按钮 +- 四张统计卡片显示用户数、活跃用户、文档数、收入,还要显示涨跌趋势 +- 一个折线图和一个饼图 +- 用户列表表格,带分页功能 +- 左侧导航侧边栏 +``` + +同样在 Trae 中直接运行后的效果: + + + + +同样的需求,唯一的区别只是在提示词开头加上了 `shadcn/ui + Tailwind CSS`,Trae 生成的结果在视觉一致性、交互细节、整体打磨程度上就完全不在一个层级。这就是组件库带来的"免费升级"——你只需要在提示词里多写一个组件库的名字。 + +## 2. 认识四个核心组件库 + +组件库数量众多(完整列表见[附录](#附录-更多组件库一览)),但你只需要先认识这四个最具代表性的: + +| 组件库 | 框架 | 一句话定位 | 官网 | +| :--- | :--- | :--- | :--- | +| [Ant Design](https://ant.design) | React | 蚂蚁集团出品,企业级中后台的事实标准,组件覆盖面极广 | ant.design | +| [shadcn/ui](https://ui.shadcn.com) | React | 不装 npm 包,直接把代码复制到你项目里,基于 Tailwind CSS,定制自由度最高 | ui.shadcn.com | +| [HeroUI](https://heroui.com)(原 NextUI) | React | 默认样式精美、动画流畅,适合对视觉品质有要求的落地页和产品展示 | heroui.com | +| [Material UI](https://mui.com) | React | 最老牌的 React 组件库,实现 Google Material Design 规范,生态最成熟 | mui.com | + +> Vue 用户同样有丰富选择:[Element Plus](https://element-plus.org)(国内最流行)、[Ant Design Vue](https://antdv.com)、[Naive UI](https://www.naiveui.com) 等,详见[附录](#附录-更多组件库一览)。 + +不同组件库擅长不同场景。接下来我们通过三个真实开发场景,带你体验如何用 AI IDE + 组件库进行 Vibe Coding。 + +为了展示不同组件库的风格和特点,我们在每个场景中刻意选用了不同的库。但请注意:**这只是为了让你多见识几种方案**,实际开发中你完全可以只用自己最顺手的那一个。比如你喜欢 shadcn/ui 的风格,用它做落地页、产品页、后台管理都没问题。选一个你觉得好看、用着舒服的,比什么都重要。 + +## 3. 实战一:用 HeroUI 构建产品落地页 + +**场景**:你做了一个 AI 写作助手产品,需要一个漂亮的落地页来展示产品特性、吸引用户注册。落地页需要视觉冲击力强、动画流畅、在手机上也好看。 + +**为什么选 HeroUI**:HeroUI 的默认样式就很精美,自带流畅的过渡动画,非常适合面向用户的展示型页面。 + +### 3.1 创建项目 + +```bash +# 使用 HeroUI 官方 CLI 创建项目 +npx create-heroui-app@latest ai-writer-landing +cd ai-writer-landing +npm install +``` + + + + +### 3.2 用 AI IDE 生成落地页 + +打开 AI IDE(Cursor、Trae 等),在对话框中输入: + +```text +请帮我做一个 AI 写作助手的落地页,用 HeroUI 组件库来做: + +**页面结构:** +1. 顶部导航栏:左边放 Logo 和产品名,右边放"功能"、"定价"、"关于"三个链接,再加一个"开始使用"按钮 +2. 首屏区域:大标题写"让 AI 成为你的写作搭档",副标题介绍产品价值,两个按钮"免费试用"和"查看演示",下面放一张产品截图 +3. 功能展示:三列卡片,分别介绍"智能续写"、"风格调整"、"多语言翻译"三个功能,每张卡片要有图标、标题、描述 +4. 定价区域:三个定价卡片(免费版、专业版、团队版),专业版要突出显示推荐 +5. 底部号召:一句吸引人的文案,加上注册按钮 +6. 页脚:版权信息和社交媒体链接 + +**设计要求:** +- 看起来要现代、专业 +- 支持暗色模式 +- 手机上看也要好看 +``` + + + + +### 3.3 AI 会用到的关键组件 + +AI 生成的代码中,你会看到这些 HeroUI 组件: + +```jsx +import { + Navbar, NavbarBrand, NavbarContent, NavbarItem, + Button, + Card, CardHeader, CardBody, CardFooter, + Divider, + Link, + Chip +} from '@heroui/react' +``` + +每个组件的作用: + +| 组件 | 用途 | 落地页中的位置 | +| :--- | :--- | :--- | +| `Navbar` | 顶部导航栏 | 页面最顶部,固定不动 | +| `Button` | 按钮,支持多种变体和颜色 | CTA 按钮、导航按钮 | +| `Card` | 卡片容器 | 功能展示、定价卡片 | +| `Chip` | 小标签 | "推荐"、"最受欢迎"标记 | +| `Divider` | 分割线 | 区域之间的视觉分隔 | + +### 3.4 迭代优化 + +生成的初版代码可能不完全满意,继续和 AI 对话调整: + +```text +请帮我优化一下落地页: + +1. 大标题加上渐变色,从蓝色渐变到紫色 +2. 功能卡片鼠标放上去要有上浮的动画效果 +3. 专业版定价卡片要突出显示,加个边框和"最受欢迎"的标签 +4. 手机上的导航改成汉堡菜单(三条横线那种) +``` + + + + +> **Vibe Coding 的核心**:你不需要记住每个组件的 API,只需要用自然语言描述你想要的效果,AI 会帮你找到合适的组件和写法。遇到不满意的地方,继续对话迭代就好。 + +## 4. 实战二:用 shadcn/ui 构建产品页面 + +**场景**:你的 AI 写作助手需要一个用户登录后的主界面——左侧是文档列表,右侧是编辑器,顶部有工具栏。这是一个功能型产品页面,需要高度定制化的 UI。 + +**为什么选 shadcn/ui**:shadcn/ui 把组件代码直接放进你的项目,你可以随意修改任何细节。对于需要深度定制的产品界面,这种"拥有代码"的模式最灵活。 + + + + +### 4.1 创建项目 + +```bash +# 创建 Next.js 项目 +npx create-next-app@latest ai-writer-app --typescript --tailwind --app +cd ai-writer-app + +# 初始化 shadcn/ui +npx shadcn@latest init + +# 按需添加组件(不是一次性安装所有组件) +npx shadcn@latest add button card input sidebar sheet dialog +``` + +shadcn/ui 的独特之处:每次 `add` 一个组件,它会把源代码复制到你项目的 `components/ui/` 目录下。你可以直接打开这些文件修改样式和行为。 + +### 4.2 用 AI IDE 生成产品界面 + +```text +请帮我做一个 AI 写作助手的主界面,用 shadcn/ui 组件库来做: + +**整体布局:** +- 左边是可折叠的侧边栏,宽度大概 280px: + - 顶部放"新建文档"按钮 + - 下面是文档列表,每个文档显示标题和最后编辑时间 + - 右键点击文档可以重命名或删除 +- 右边是主编辑区,分成上下两部分: + - 上面是工具栏:可以编辑文档标题、显示字数统计、"AI 续写"按钮、"导出"下拉菜单 + - 下面是编辑区域:一个大的文本输入框,占满剩余空间 + +**交互细节:** +- 点击"AI 续写"后,按钮显示加载状态,编辑器底部出现 AI 生成的文本(像打字机一样逐字显示) +- 手机上侧边栏变成抽屉式,从左边滑出 +- 当前选中的文档要高亮显示 +``` + + + + +### 4.3 AI 会用到的关键组件 + +```tsx +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Card, CardContent, CardHeader } from '@/components/ui/card' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@/components/ui/dropdown-menu' +import { + Sheet, + SheetContent, + SheetTrigger +} from '@/components/ui/sheet' +import { + Sidebar, + SidebarContent, + SidebarHeader +} from '@/components/ui/sidebar' +``` + +| 组件 | 用途 | 产品页面中的位置 | +| :--- | :--- | :--- | +| `Sidebar` | 可折叠侧边栏 | 左侧文档列表 | +| `Sheet` | 移动端抽屉 | 移动端侧边栏替代 | +| `DropdownMenu` | 下拉菜单 | "导出"按钮、右键菜单 | +| `Dialog` | 对话框 | 重命名、删除确认 | +| `Button` | 按钮,支持 variant 和 loading | 各种操作按钮 | +| `Input` | 输入框 | 文档标题编辑 | + +### 4.4 定制组件样式 + +shadcn/ui 的优势在于你可以直接修改组件源码。比如你想让按钮的圆角更大: + +```text +请帮我修改 components/ui/button.tsx, +把所有按钮的默认圆角从 rounded-md 改为 rounded-xl, +并给 primary 变体加上微妙的阴影效果 +``` + +AI 会直接修改你项目中的组件文件,而不是覆盖 npm 包的样式——这就是 shadcn/ui "拥有代码"的好处。 + + + + +## 5. 实战三:用 Ant Design 构建后台管理界面 + +**场景**:你的 AI 写作助手上线后,需要一个Panel de administracion来查看用户数据、管理文档内容、处理付费订单。后台管理系统的核心是数据展示和操作效率。 + +**为什么选 Ant Design**:Ant Design 在中后台领域积累最深,表格、表单、图表等业务组件开箱即用,内置了大量企业级交互模式(批量操作、高级筛选、数据导出等)。 + + + + +### 5.1 创建项目 + +```bash +# 使用 Ant Design Pro 脚手架(内置布局、路由、权限) +npx create-umi@latest ai-writer-admin +# 选择 Ant Design Pro 模板 +cd ai-writer-admin +npm install +``` + +或者从零开始: + +```bash +npx create-react-app ai-writer-admin --template typescript +cd ai-writer-admin +npm install antd @ant-design/icons @ant-design/pro-components +``` + +### 5.2 用 AI IDE 生成Panel de administracion + +```text +请帮我做一个 AI 写作助手的Panel de administracion,用 Ant Design 组件库来做: + +**整体布局:** +- 左边是菜单栏:仪表盘、用户管理、文档管理、订单管理、系统设置 +- 顶部显示面包屑导航 + +**用户管理页面:** +- 顶部放四个统计卡片:总用户数、今日新增、活跃用户数、付费用户数 +- 搜索筛选区:可以按用户名搜索、选择注册时间范围、筛选用户状态,还有"搜索"和"重置"按钮 +- 用户表格: + - 显示头像、用户名、邮箱、注册时间、订阅计划(用不同颜色标签区分)、状态、操作 + - 每页显示 20 条,支持分页 + - 可以批量选择用户,批量禁用或导出 + - 操作列:查看详情、编辑、禁用(禁用前要二次确认) +- 点击"查看详情"从右侧滑出抽屉,显示用户详细信息和最近文档列表 +``` + + + + +### 5.3 AI 会用到的关键组件 + +```tsx +import { PageContainer, ProLayout } from '@ant-design/pro-components' +import { ProTable } from '@ant-design/pro-components' +import { StatisticCard } from '@ant-design/pro-components' +import { + Button, Tag, Badge, Space, Drawer, + Popconfirm, message, Modal +} from 'antd' +import { + UserOutlined, SearchOutlined, ExportOutlined +} from '@ant-design/icons' +``` + +| 组件 | 用途 | 后台中的位置 | +| :--- | :--- | :--- | +| `ProLayout` | 后台整体布局框架 | 页面骨架(菜单 + 内容区) | +| `ProTable` | 高级表格,内置搜索、分页、列设置 | 用户列表、文档列表、订单列表 | +| `StatisticCard` | 数据统计卡片 | 仪表盘、页面顶部概览 | +| `Tag` / `Badge` | 状态标签 | 订阅计划、用户状态 | +| `Drawer` | 侧边抽屉 | 用户详情、编辑表单 | +| `Popconfirm` | 气泡确认框 | 删除、禁用等危险操作 | + +### 5.4 继续迭代:添加仪表盘 + +```text +请帮我做一个仪表盘页面: + +1. 顶部四个统计卡片:总用户数、总文档数、今日 API 调用次数、月收入,每个卡片显示数值和环比变化(涨了还是跌了) +2. 中间放两个图表: + - 左边:最近 7 天的用户增长折线图 + - 右边:订阅计划分布饼图 +3. 底部:最近操作日志表格,显示时间、用户、操作类型、详情 + +用 Ant Design 的组件来布局,图表可以用 Ant Design Charts +``` + + + + +> **后台管理的 Vibe Coding 技巧**:后台页面结构相对固定(表格 + 搜索 + 弹窗),非常适合用 AI 批量生成。你可以先让 AI 生成一个"用户管理"页面作为模板,然后说"参考用户管理页面的结构,帮我生成文档管理页面",AI 会复用相同的布局模式。 + +## 6. 学会查文档:组件库的"说明书" + +Vibe Coding 中 AI 会帮你写大部分代码,但当 AI 生成的结果不对、或者你想微调某个组件的行为时,**查文档**是最快的解决方式。 + +以 Ant Design 为例,它的文档地址是:`https://ant.design/components/overview-cn` + +查文档的标准流程: + +1. **明确需求**:比如"我需要表格支持行选择" +2. **在文档中搜索**:搜索"Table"进入表格组件页面 +3. **查看示例**:文档中每个组件都有多个在线示例,找到"可选择"示例 +4. **复制代码**:把示例代码复制到你的项目中 +5. **查看 API 表格**:在页面底部找到 `rowSelection` 属性的完整配置项 + +> 你也可以把文档链接直接发给 AI IDE:"请参考 https://ant.design/components/table-cn 的 rowSelection API,帮我给用户表格加上批量选择功能"。给 AI 提供文档链接,生成的代码会更准确。 + +各组件库的文档地址速查: + +| 组件库 | 文档地址 | +| :--- | :--- | +| Ant Design | `https://ant.design/components/overview-cn` | +| shadcn/ui | `https://ui.shadcn.com/docs/components` | +| HeroUI | `https://heroui.com/docs/components` | +| Material UI | `https://mui.com/material-ui/all-components/` | +| Element Plus | `https://element-plus.org/zh-CN/component/overview.html` | + +## 7. 小结 + +三个实战场景覆盖了最常见的前端开发需求: + +| 场景 | 推荐组件库 | 核心特点 | +| :--- | :--- | :--- | +| 落地页 / 展示页 | HeroUI | 默认样式精美,动画流畅,视觉冲击力强 | +| 产品功能页面 | shadcn/ui | 代码完全可控,深度定制灵活 | +| 后台管理系统 | Ant Design | 业务组件丰富,表格表单开箱即用 | + +Vibe Coding 的工作流总结: + +1. 根据场景选择合适的组件库 +2. 用 AI IDE 描述你想要的页面结构和交互 +3. AI 生成初版代码,你预览效果 +4. 用自然语言继续迭代调整 +5. 遇到细节问题时查阅组件库文档 + +### 练习 + +选择以下任一场景,用 AI IDE + 组件库从零完成: + +1. 用 HeroUI 为你之前做的项目(比如霍格沃茨画像)做一个展示落地页 +2. 用 shadcn/ui 构建一个笔记应用的主界面(侧边栏 + 编辑器) +3. 用 Ant Design 构建一个简单的内容Panel de administracion(文章列表 + 新建文章表单) + +--- + +## 附录:更多组件库一览 + +除了正文介绍的四个核心库,前端生态中还有大量优秀的组件库。下面按框架分类列出,方便你根据项目需求选择。 + +### Vue 生态 + +| 组件库 | Stars | 简介 | 适用场景 | +| :--- | :--- | :--- | :--- | +| [Element Plus](https://element-plus.org) | ~27k | 饿了么团队打造的 Vue 3 企业级组件库,国内使用最广泛,中文生态极佳 | 中后台管理系统 | +| [Vuetify](https://vuetifyjs.com) | ~41k | 最流行的 Vue Material Design 组件库,80+ 组件,文档完善 | Google 设计风格项目 | +| [Ant Design Vue](https://antdv.com) | ~21k | 基于蚂蚁设计体系的 Vue 3 组件库,设计规范统一 | 企业级中后台 | +| [Naive UI](https://www.naiveui.com) | ~18k | TypeScript 编写,主题定制性极强,不依赖 CSS 预处理器 | 对设计有独特要求的项目 | +| [Quasar](https://quasar.dev) | ~27k | 一套代码构建 SPA、SSR、PWA、移动端和桌面端应用 | 跨平台项目 | +| [Vant](https://vant-ui.github.io/vant) | ~24k | 有赞团队开发的轻量级移动端组件库,覆盖电商常见需求 | 移动端 H5 页面 | +| [PrimeVue](https://primevue.org) | ~14k | 90+ 组件,支持多种主题(Material、Bootstrap 等) | 需要丰富组件和多主题 | +| [Arco Design Vue](https://arco.design/vue) | ~3k | 字节跳动出品,组件质量高,内置暗色模式 | 中后台产品 | +| [TDesign Vue Next](https://tdesign.tencent.com/vue-next) | ~2k | 腾讯出品,设计语言统一,覆盖桌面端常用场景 | 腾讯生态或企业级项目 | + +### React 生态 + +| 组件库 | Stars | 简介 | 适用场景 | +| :--- | :--- | :--- | :--- | +| [Material UI (MUI)](https://mui.com) | ~95k | Google Material Design 规范的老牌实现,组件最全面,生态最成熟 | 快速构建企业级应用 | +| [Ant Design](https://ant.design) | ~94k | 蚂蚁集团出品,内置大量高质量业务组件,中文开发者社区主导地位 | 企业级中后台 | +| [shadcn/ui](https://ui.shadcn.com) | ~83k | 代码复制到项目中而非 npm 安装,基于 Radix UI + Tailwind CSS,完全可控 | 需要高度定制的项目 | +| [Chakra UI](https://chakra-ui.com) | ~39k | 以开发体验为核心,API 简洁,内置无障碍访问支持 | 快速原型开发 | +| [Mantine](https://mantine.dev) | ~28k | 100+ 组件和 50+ hooks,涵盖日期选择器、富文本编辑器等高级组件 | 需要开箱即用的全功能方案 | +| [Headless UI](https://headlessui.com) | ~27k | Tailwind Labs 官方出品的无样式组件库,同时支持 React 和 Vue | 搭配 Tailwind CSS 使用 | +| [HeroUI](https://heroui.com) | ~24k | 基于 Tailwind CSS + React Aria,默认样式精美,动画流畅 | 追求视觉品质的项目 | +| [Radix UI](https://www.radix-ui.com) | ~17k | 无样式底层组件原语库,专注无障碍和组件行为,是 shadcn/ui 的底层基础 | 构建自定义设计系统 | + +#### shadcn/ui 扩展生态 + +除了上述通用组件库,shadcn/ui 生态中还涌现了大量基于其理念的扩展库,为特定场景提供差异化选择。这些扩展库同样采用"复制代码到项目"的模式,让开发者拥有完全的源码控制权。 + +| 组件库 | 简介 | 适用场景 | +| :--- | :--- | :--- | +| [Aceternity UI](https://ui.aceternity.com) | 200+ 生产级组件,主打发光卡片、文字渐变、3D 地球等特色视觉组件 | 高质感落地页、SaaS 产品 | +| [Tailark UI](https://tailark.com) | 营销网站组件块集合,产品展示、客户证言、CTA 按钮等营销高频模块 | 营销落地页、产品官网 | +| [UI Tripled](https://ui.tripled.work) | 基于 Framer Motion 的动态交互组件,弹窗、导航、卡片动画 | 创意工具、个人作品集 | +| [Neobrutalism UI](https://neobrutalism.dev) | 新粗野主义风格,粗线条、高对比度、鲜明色彩 | 个性化品牌官网、创意项目 | +| [REUI](https://reui.io) | 967+ 真实业务场景的组件组合模式 | 企业级后台、复杂表单 | +| [Cult UI](https://cult-ui.com) | 更细的交互/视觉打磨,数据表格、筛选面板等复合组件 | 高质感商业项目 | +| [Kibo UI](https://kibo-ui.com) | 高级业务组件,颜色选择器、富文本编辑器、文件上传等 | Panel de administracion、工具类产品 | +| [Kokonut UI](https://kokonutui.com) | 100+ 组件 + 7+ 完整模板,清新简约风格 | SaaS 官网、博客、电商 | +| [Commerce UI](https://ui.stackzero.co) | 电商场景专用,商品卡片、购物车、结算表单 | 电商平台 | +| [shadcnblocks](https://shadcnblocks.com) | 1373 个 UI 块 + 13 套完整模板,资源最全面 | 所有场景 | +| [Shoogle](https://shoogle.dev) | shadcn/ui 生态聚合检索平台 | 快速查找资源 | +| [Discover All Shadcn](https://allshadcn.com) | 聚合型资源导航 | 快速查找资源 | + +> **为什么选择 shadcn/ui 扩展?** 这些扩展继承了 shadcn/ui"代码所有权"的理念,同时为特定场景做了深度定制。Vibe Coding 时代,它们让你能快速找到符合设计需求的组件,跳出主流 UI 库的同质化,做出更具差异化的产品。 diff --git a/docs/es-es/stage-2/frontend/multi-product-ui/index.md b/docs/es-es/stage-2/frontend/multi-product-ui/index.md new file mode 100644 index 0000000..e126a66 --- /dev/null +++ b/docs/es-es/stage-2/frontend/multi-product-ui/index.md @@ -0,0 +1,425 @@ +# Disena paginas y botones siguiendo guias de diseno de UI + +Muchas personas dicen "quiero que mi pagina se parezca mas a la de Apple" o "quiero que los botones se vean mas sofisticados", pero cuando realmente empiezan a trabajar, a menudo se quedan atascados en una pregunta: + +**Exactamente, que debo tomar como referencia?** + +Mirar capturas de pantalla e imitar solo te ensena si algo "se parece o no". Pero cuando abres las guias de diseno de Apple, Google, Microsoft y Atlassian, descubres que lo realmente impresionante no es el estilo visual, sino que **explican claramente los problemas de diseno**: que destacar primero en una pagina, como jerarquizar los botones, como enfatizar las operaciones - estos criterios de juicio son lo esencial. + +> Seguir guias de diseno no se trata de hacer que algo "se parezca a alguien", sino de aprender como otros toman decisiones. + +:::: info Por que aprender esto ahora +Las reglas de diseno ya han sido entrenadas en los modelos, absorbidas por defecto en las herramientas de diseno, e incluso con solo pegar algunas capturas de pantalla la IA puede aprenderlas. Pero aun necesitamos saber de donde vienen estas reglas y por que se definen asi. +:::: + +## Primero mira algunos textos originales y siente la diferencia + +Si antes pensabas que "las guias de diseno solo hablan de estilo", primero mira algunas citas oficiales. + +Normalmente en un equipo solemos decir cosas como: + +- Haz un dropdown +- Pon un menu aqui +- Agrega algunas funciones a la barra de menu +- Pon dos botones aqui, uno de confirmar y otro de cancelar + +Parece que no hay problema, pero en las guias de las grandes empresas, estos terminos no son conceptos vagos, sino que estan desglosados con mucho detalle. + +| Lo que solemos decir casualmente | Texto oficial | En pocas palabras | +| :--- | :--- | :--- | +| "Haz un menu" | Apple: ["A menu reveals its options..."](https://developer.apple.com/design/human-interface-guidelines/menus) | `Menu` se usa para realizar acciones | +| "Pon funciones en la barra de menu" | Apple: ["menu bar menus contain all the commands..."](https://developer.apple.com/design/human-interface-guidelines/menus) | Este es el menu de comandos en la parte superior de la aplicacion | +| "Haz un dropdown" | Apple: ["A pop-up list lets the user choose one option among several."](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pop-up` es para seleccionar uno de una lista | +| "Tambien haz un dropdown" | Apple: ["A pull-down list is generally used for selecting commands in a specific context."](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pull-down` es para abrir y realizar la accion actual | +| "El menu tambien sirve para filtrar?" | Fluent: ["If you need to collect information from people, try a select, dropdown, or combobox instead."](https://fluent2.microsoft.design/components/web/react/core/menu/usage) | `Menu` no es para seleccionar valores | +| "El menu tambien sirve como navegacion?" | Material: ["Menus should not be used as a primary method for navigation within an app."](https://m1.material.io/components/menus.html) | `Menu` no es navegacion principal | +| "Escribe OK / Cancel en los botones" | Apple: ["Always use 'Cancel' to title a button that cancels the alert's action."](https://developer.apple.com/design/human-interface-guidelines/alerts) | El texto de los botones no se puede escribir de cualquier forma | + +> Las citas de la tabla se pueden hacer clic directamente para ir a la pagina oficial correspondiente. + +Esta es la parte que mas impacta cuando lees realmente las guias de diseno por primera vez: + +> Lo que normalmente pensamos que es discutir de UI, en realidad muchas veces es solo comunicarnos con un monton de palabras vagas. + +Apple no se limita a decir "haz un menu"; continua distinguiendo: + +- `menu` +- `menu bar menu` +- `pop-up button` +- `pull-down button` +- `context menu` + +Fluent no se limita a decir "dropdown"; continua distinguiendo: + +- `menu` +- `dropdown` +- `select` +- `combobox` + +Esta es la necesidad de las guias de diseno. + +No es para hacer que las paginas parezcan mas profesionales, sino para que cuando el equipo discuta sobre UI, cada persona no tenga cosas diferentes en mente. + +## Lo que aprenderas + +1. Por que debes consultar las guias de diseno al disenar paginas y botones +2. Que contenido de las guias de Apple, Material, Fluent y Atlassian es mas valioso consultar +3. Como disenar claramente la "jerarquia de paginas" y la "jerarquia de botones" +4. Como hacer que la IA consulte las guias de otros para generar paginas y botones + +## 1. Por que las guias de diseno te ayudan a disenar paginas con claridad + +Despues de leer los textos originales anteriores, descubriras un punto clave: + +**Las guias de diseno no son un complemento estetico, sino que primero precisan el vocabulario.** + +Muchas paginas no se ven bien no porque la combinacion de colores no sea sofisticada, sino porque la jerarquia de informacion es confusa. + +Muchos botones no son faciles de usar no porque los bordes redondeados esten mal, sino porque: + +- Hay demasiados botones principales, el usuario no sabe cual presionar +- Los botones de peligro se ven igual que los botones normales +- Todos los botones de la pagina compiten por la atencion +- El estilo y la semantica de los botones son inconsistentes entre paginas + +Las guias de diseno maduras abordan precisamente estos problemas. Normalmente definen: + +| Contenido de la guia | Que problema resuelve | +| :--- | :--- | +| **Jerarquia de pagina** | Donde mirar primero, donde mirar despues, como organizar la informacion | +| **Fundamentos visuales** | Como unificar colores, espaciado, tipografia, bordes redondeados, sombras | +| **Jerarquia de botones** | Como distinguir boton principal, secundario, de texto, de peligro | +| **Reglas de estado** | Como se ven hover, focus, disabled, loading | +| **Semantica de interaccion** | Que boton es "confirmar", cual es "cancelar", cual es "mas acciones" | + +Por lo tanto, lo que realmente proporcionan las guias de diseno no es un "aspecto", sino un **conjunto de criterios de juicio**. + +## 2. Al consultar las guias de grandes empresas, en que debes enfocarte + +### 2.1 Consultar Apple: Aprender a "definir con suficiente detalle" + +Lo mas valioso de Apple no es solo la contencion visual, sino que define los conceptos con mucho detalle. + +Lo que muchos equipos llaman "menu" o "dropdown", Apple continua desglosando: + +- `menu`: un conjunto de comandos, opciones o estados +- `menu bar menu`: coleccion de comandos a nivel de aplicacion +- `pop-up button`: seleccionar un valor +- `pull-down button`: activar comandos en el contexto actual +- `context menu`: acciones comunes relacionadas con el objeto o tarea actual + +Esta distincion es muy importante porque afecta directamente: + +- Si este componente es para seleccionar valores o para realizar acciones +- Si pertenece a una seccion de la pagina o a nivel de aplicacion +- Si debe mostrar persistentemente el valor seleccionado o solo expandir comandos temporalmente + +Cuando empiezas a pensar con este nivel de granularidad, las paginas que disenes seran mucho mas claras. + +### 2.2 Consultar Apple: Aprender jerarquia de paginas y contencion + +Las Apple Human Interface Guidelines son especialmente adecuadas para aprender dos cosas: + +- Como establecer una jerarquia clara en las paginas +- Como mantener los controles claros sin que acaparen la atencion + +Apple enfatiza `Hierarchy`, `Harmony`, `Consistency`. Esto significa que al disenar paginas debes responder: + +- Cual es la informacion mas importante de la pagina actual +- Cual es la tarea principal del usuario +- Que operacion debe ser mas visible y cual debe retroceder + +Si consultas a Apple para disenar paginas, puedes enfocarte en: + +- No fragmentar demasiado la informacion del primer vistazo, enfocarse primero en el contenido central +- Usar espacios en blanco, tamano de fuente y agrupacion para crear orden, en lugar de apilar muchos bordes +- No hacer que todos los botones tengan alto enfasis, solo las acciones clave deben ser las mas prominentes + +### 2.3 Consultar Material: Aprender estructura clara de paginas + +Material Design es muy adecuado para aprender "como las paginas organizan los flujos de tareas". + +Muchos de sus componentes y guias de layout tienen como nucleo ayudarte a aclarar: + +- Si la pagina es de navegacion o de ejecucion de tareas +- Si la pagina actual es para que el usuario lea, seleccione o envie +- Que elementos de una pagina deben repetirse de forma estable y cuales deben responder a cambios de contexto + +Si consultas Material para disenar paginas, puedes enfocarte en: + +- Secciones de pagina claras, responsabilidades de modulos bien definidas +- Navegacion, area de contenido y area de operaciones con division clara del trabajo +- Diferentes estilos de botones corresponden a diferentes prioridades de operacion + +### 2.4 Consultar Fluent: Aprender limites de componentes y jerarquia de botones + +Fluent 2 es muy adecuado para productos de backend, herramientas y sistemas de formularios complejos. Lo mas valioso que tiene es que te dice directamente "no mezcles conceptos". + +Por ejemplo, dice explicitamente: si necesitas "collect information", no sigas usando `menu`, sino que deberias considerar `select`, `dropdown`, `combobox`. + +Esta frase es muy importante porque rompe la idea de "todo es mas o menos lo mismo" que mucha gente tiene en mente. + +Fluent 2 tambien valora mucho: + +- Jerarquia de operaciones +- Limites semanticos de componentes +- Claridad en escenarios de informacion densa + +Si consultas Fluent para disenar botones, puedes enfocarte en: + +- `Primary button` para la accion mas importante del area actual +- `Secondary button` para acciones de soporte +- Botones de enfasis debil como `Subtle`, `Transparent` para operaciones que no deben interrumpir el flujo principal +- Cuantos mas botones haya en la pagina, mas debes controlar la prioridad visual + +### 2.5 Consultar Atlassian: Aprender a gestionar paginas y botones de forma sistematica + +El Atlassian Design System es especialmente adecuado para situaciones donde "un equipo hace muchas paginas". Enfatiza: + +- Los foundations son la base compartida +- Los tokens son el metodo para unificar las decisiones visuales +- Los components son los bloques de interaccion que se reutilizan repetidamente + +Si consultas Atlassian para hacer paginas y botones, lo mas valioso es: + +- Convertir el tamano, color, bordes redondeados y espaciado de los botones en reglas unificadas +- Fijar el ritmo del layout de pagina +- Hacer que diferentes paginas, aunque tengan contenido diferente, compartan un lenguaje estructural consistente + +## 3. Al disenar paginas, que puntos de la guia debes consultar + +Cuando mires un sistema de diseno, no preguntes primero "esta pagina se ve bien o no", sino que primero te hagas las siguientes preguntas. + +### 3.1 Primer vistazo a la pagina, es clara la jerarquia principal/secundaria + +Una pagina generalmente debe tener al menos tres niveles: + +- **Informacion principal**: el contenido mas importante de la pagina actual +- **Informacion auxiliar**: contenido que ayuda a comprender o complementar +- **Operaciones secundarias**: acciones que no deben interferir con la tarea principal + +Si los tres niveles no estan diferenciados, la pagina sera "todo es importante", lo que equivale a "nada es importante". + +### 3.2 El layout de la pagina, sirve a la tarea o solo apila modulos + +Al consultar las guias, presta especial atencion a: + +- Si el area de titulo aclara el objetivo de la pagina +- Si el area de contenido principal esta organizada alrededor de la tarea +- Si los botones de operacion estan cerca del contenido relacionado +- Si la informacion secundaria esta debilmente enfatizada + +### 3.3 Las operaciones de la pagina, tienen prioridad + +Muchas paginas a primera vista tienen 6 botones, y cada boton parece un CTA, esta es una tipica perdida de jerarquia. + +Un enfoque mas razonable seria: + +- Un area generalmente tiene solo una accion principal +- Las acciones secundarias pueden usar bordes, botones de texto o estilos mas debiles +- Las acciones de riesgo no deben verse igual que la accion principal + +## 4. Al disenar botones, que puntos de la guia debes consultar + +Los botones son la parte mas facil de "disenar de cualquier manera", pero tambien la que mas puede revelar si un sistema es maduro. + +### 4.1 Primero separa los botones por "semantica", luego por "estilo" + +No pienses primero en "boton azul o boton negro", primero piensa en que rol tiene este boton. + +Los roles comunes de botones se pueden clasificar asi: + +| Tipo de boton | Funcion | Estrategia de estilo comun | +| :--- | :--- | :--- | +| **Primary** | La accion mas critica del area actual | Solido, alto contraste, el mas visible | +| **Secondary** | Acciones de soporte | Borde o un nivel de enfasis menor | +| **Tertiary / Text** | Operaciones debiles | Texto o baja proporcion visual | +| **Destructive** | Eliminar, desactivar, limpiar y otras operaciones de riesgo | Color de advertencia o estilo de riesgo explicito | +| **Icon button** | Operaciones de herramienta locales | Simple, cerca del contexto | + +### 4.2 Una pagina no debe tener demasiados Primary Buttons + +Este es el error en el que mas caen los principiantes. + +Si hay 4 botones principales en la pagina, entonces es como si no hubiera boton principal. El significado del boton principal es "decir al usuario que es lo que mas deberia hacer ahora". + +Puedes seguir la practica comun de muchos sistemas de diseno: + +- Un area principal generalmente conserva solo un boton principal +- Cancelar, volver, cerrar generalmente no compiten al mismo nivel que el boton de confirmacion +- Mas operaciones se colocan en botones secundarios o menus + +### 4.3 Los botones deben poder expresar cambios de estado + +Las guias de diseno generalmente describen los estados de los botones con mucho detalle: + +- Estado por defecto +- Estado hover +- Estado focus +- Estado disabled +- Estado loading +- Estado de peligro + +Esto es importante porque un boton no es una imagen estatica, sino uno de los controles que mas se activan durante la operacion del usuario. + +### 4.4 El texto de los botones tambien es parte del diseno + +El texto del boton no es solo un "problema de redaccion", afecta directamente la comprension del usuario. + +Por ejemplo: + +- `Guardar` +- `Guardar cambios` +- `Publicar ahora` +- `Eliminar proyecto` +- `Mover a la papelera` + +Estos textos transmiten expectativas psicologicas completamente diferentes. Las guias maduras generalmente requieren que las etiquetas de los botones expresen claramente la accion, en lugar de usar palabras vagas. + +## 5. Una lista de verificacion muy practica para el diseno de paginas y botones + +Cuando disenes paginas tu mismo, puedes revisar rapidamente esta lista: + +### Lista de paginas + +- El titulo de la pagina explica claramente la tarea actual +- La informacion mas importante del primer vistazo es visible de inmediato +- La pagina esta organizada por flujo de tareas, no por lo que se te ocurre poner +- Solo hay una accion principal en la misma area +- El contenido secundario esta debilmente enfatizado + +### Lista de botones + +- Este boton es una accion principal o secundaria +- Por que merece ser mas visible que otros botones +- Hay demasiados botones principales en la pagina +- Las operaciones de peligro estan claramente identificadas +- El texto del boton es suficientemente especifico + +## 6. Como usar IA consultando las guias de otros para disenar paginas + +Esta seccion es la mas practica. + +Muchas personas cuando piden a la IA que disene paginas, solo dicen: + +```md +Hazme una pagina de configuracion, que se vea mas sofisticada, estilo Apple +``` + +Este tipo de prompt es demasiado vago, la IA generalmente solo puede imitar "fondo blanco, bordes redondeados, sombras". + +Para principiantes, un enfoque mas practico no es resumir un gran parrafo uno mismo, sino directamente pegar a la IA **las frases clave del texto original de la guia**. + +Esto tiene dos ventajas: + +- No necesitas "traducir" tu mismo el pensamiento de diseno +- La IA puede mas facilmente entender paginas y botones segun las definiciones oficiales + +### 6.1 Ejemplo 1: Hacer que la IA consulte Apple para disenar una pagina de configuracion + +Primero busca una frase del texto original de Apple: + +> ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) + +Puedes pegarlo directamente a la IA asi: + +```md +Consulta esta frase de las Apple Human Interface Guidelines: +"Establish a clear visual hierarchy..." + +Ayudame a disenar una pagina de configuracion de seguridad de cuenta. +Requiere jerarquia de pagina clara, informacion importante primero, agrupacion ordenada. +``` + +El punto clave de escribirlo asi: no necesitas explicar demasiado tu mismo, solo pega las palabras originales de Apple. + +### 6.2 Ejemplo 2: Hacer que la IA consulte Fluent para disenar botones de pagina de backend + +Primero busca una frase del texto original de Fluent: + +> ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +Puedes pegarlo directamente a la IA asi: + +```md +Consulta esta frase de Fluent 2: +"Only use one primary button in a layout..." + +Ayudame a disenar los botones de un backend de gestion de equipos. +El boton de agregar miembro debe ser el mas visible, exportar, filtrar, mas operaciones mas debiles, el boton de eliminar destacado por separado. +``` + +Esta frase es especialmente adecuada para principiantes porque le dice directamente a la IA: no pongas demasiados botones principales en un area. + +### 6.3 Ejemplo 3: Hacer que la IA consulte simultaneamente las guias de pagina y botones + +Tambien puedes pegar dos frases originales a la vez, dejando que la IA consulte simultaneamente la pagina y los botones: + +> Apple: ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) +> +> Fluent: ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +Luego escribe directamente asi: + +```md +Consulta las siguientes dos frases de guias de diseno originales: +Apple: "Establish a clear visual hierarchy..." +Fluent: "Only use one primary button in a layout..." + +Ayudame a disenar una pagina de detalles de proyecto. +La pagina incluye introduccion del proyecto, miembros, actividad reciente y entrada de configuracion. +Jerarquia de pagina mas clara, solo un boton principal, otros botones mas debiles. +``` + +Este metodo es especialmente adecuado para principiantes, porque solo necesitas saber copiar el texto original y agregar un par de frases con tus necesidades. + +## 7. Como usar IA consultando las guias de botones para generar directamente el diseno de botones + +Si solo quieres hacer botones primero, tambien puedes pegar directamente el texto original de la guia de botones. + +Por ejemplo, la definicion de boton de Atlassian es muy corta: + +> ["A button triggers an event or action."](https://atlassian.design/components/button/) + +Puedes preguntar a la IA asi: + +```md +Consulta esta frase de Atlassian: +"A button triggers an event or action." + +Ayudame a disenar un conjunto de estilos de botones para paginas de backend. +Necesito boton principal, boton secundario, boton de eliminar, y dime donde se usa cada uno. +``` + +Este tipo de prompt es especialmente adecuado para principiantes, basicamente es "pegar texto original + decir necesidades". + +## 8. Resumen + +Consultar guias de diseno de UI para disenar paginas y botones, lo mas importante no es "hacer que se parezca a alguien", sino aprender estas cosas: + +1. Usar jerarquia para organizar paginas, en lugar de apilar contenido +2. Usar clasificacion de botones para expresar prioridad de operaciones, en lugar de hacer que todos los botones sean igual de llamativos +3. Usar las definiciones, limites y criterios de juicio de las guias de diseno para guiar el diseno +4. Cuando la IA consulta las guias de otros, consulta "principios y estructura", no solo el aspecto + +Cuando uses las guias de esta manera, lo que consultes no sera solo un estilo, sino un conjunto de pensamiento de diseno maduro. + +--- + +## Referencias + +Los siguientes enlaces provienen todos de sistemas de diseno oficiales o documentacion oficial: + +- Apple Human Interface Guidelines: [Overview](https://developer.apple.com/design/human-interface-guidelines/) +- Apple Human Interface Guidelines: [Menus](https://developer.apple.com/design/human-interface-guidelines/menus) +- Apple Human Interface Guidelines: [Alerts](https://developer.apple.com/design/human-interface-guidelines/alerts) +- Apple Human Interface Guidelines: [Buttons](https://developer.apple.com/design/human-interface-guidelines/buttons) +- Apple Archive: [How Menus Work](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/HowMenusWork.html) +- Apple Archive: [Managing Pop-Up Buttons and Pull-Down Lists](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) +- Material Design: [Buttons overview](https://m3.material.io/components/buttons/overview) +- Material Design: [Menus](https://m1.material.io/components/menus.html) +- Microsoft Fluent 2: [Start designing](https://fluent2.microsoft.design/get-started/design) +- Microsoft Fluent 2: [Menu usage](https://fluent2.microsoft.design/components/web/react/core/menu/usage) +- Microsoft Fluent 2: [Button usage](https://fluent2.microsoft.design/components/web/react/core/button/usage) +- Atlassian Design System: [Foundations](https://atlassian.design/foundations/) +- Atlassian Design System: [Button](https://atlassian.design/components/button/) diff --git a/docs/es-es/stage-2/frontend/ui-design/index.md b/docs/es-es/stage-2/frontend/ui-design/index.md new file mode 100644 index 0000000..ad9d505 --- /dev/null +++ b/docs/es-es/stage-2/frontend/ui-design/index.md @@ -0,0 +1,3 @@ +# Construye tu primera aplicacion moderna - Diseno de UI + +> Este capitulo esta en proceso de redaccion, estad atentos... diff --git a/docs/es-es/stage-2/index.md b/docs/es-es/stage-2/index.md index 8bc3eae..5466b12 100644 --- a/docs/es-es/stage-2/index.md +++ b/docs/es-es/stage-2/index.md @@ -1,126 +1,193 @@ -# Desarrollo Full-Stack +# Desarrollo Junior-Intermedio -¡Bienvenido a la etapa de **Desarrollo Full-Stack**! Aquí profundizarás en el desarrollo full-stack, dominando la componentización frontend, el diseño de bases de datos, el desarrollo de API backend y el despliegue. +Bienvenido a la etapa de **Desarrollo Junior-Intermedio**. Aqui profundizaras en el desarrollo full-stack, dominando la componentizacion frontend, el diseno de bases de datos, el desarrollo de API backend y el despliegue en produccion. -## Lo que aprenderás +## Lo que aprenderas ### Desarrollo Frontend -Domina el desarrollo frontend moderno y aprende a usar bibliotecas de componentes y herramientas de diseño: +Domina el desarrollo frontend moderno, aprende a usar bibliotecas de componentes y herramientas de diseno: + + + + +### Desarrollo Backend -### Backend y Full-Stack +Aprende diseno de API, gestion de bases de datos y estrategias de despliegue de aplicaciones: -Aprende diseño de API, gestión de bases de datos y estrategias de despliegue de aplicaciones: - +### Proyectos principales -### Asignaciones +Los capitulos anteriores son para aprender las "piezas"; los proyectos principales son para aprender "como ensamblar las piezas en un producto que funcione, se pueda demostrar y se pueda lanzar". + +Te recomendamos seguir el orden **Proyecto 1 -> Proyecto 2**: + +- **Proyecto 1** primero te guia a traves de la cadena principal mas comun del SaaS moderno: login, generacion, base de datos, pagos, panel de administracion. +- **Proyecto 2** luego te lleva a un escenario mas parecido a un sistema empresarial: roles y permisos, banco de preguntas, examenes, registros de envio, consola de administracion. + +```mermaid +flowchart LR + A["Paginas y componentes frontend"] --> B["Base de datos e interfaces"] + B --> C["Proyecto 1
SaaS de generacion de textos"] + C --> D["Pagos / Despliegue / Gestion de backend"] + D --> E["Proyecto 2
Sistema de examenes en linea"] + E --> F["Portafolio full-stack completo"] +``` + +Si no sabes cual hacer primero, puedes consultar esta tabla comparativa: + +| Proyecto | Que practicaras principalmente | Para quien es mas adecuado | Entregable final | +|------|------|------|------| +| Proyecto 1: Sitio web de generacion de textos | Estructura de paginas SaaS, login de usuarios, generacion con IA, pagos con Stripe, panel de administracion | Quienes hacen su primer sitio web comercial completo | Un prototipo SaaS con registro, generacion, pagos y gestion | +| Proyecto 2: Sistema de examenes en linea y gestion | Permisos de roles, modelado de banco de preguntas, flujo de examenes, registros de envio, calificacion y estadisticas | Quienes quieren hacer un "sistema empresarial" verdaderamente completo | Una plataforma de examenes con portal de estudiante y administracion | + +Sin importar cual elijas, te recomendamos preparar al menos estos 3 entregables: + +- Un repositorio de proyecto ejecutable +- Un enlace de demostracion accesible +- Un README y un video de demostracion -Consolida tus habilidades de desarrollo full-stack a través de proyectos prácticos: +Si ya completaste los dos proyectos principales anteriores, o quieres hacer un portafolio segun tu propia direccion tecnica, puedes continuar eligiendo uno de estos proyectos extendidos para profundizar: -### Extensión de capacidades de IA + + + + +### Extension de capacidades de IA -## Para quién es + + + -- Desarrolladores con alguna base de programación que quieran aprender sistemáticamente desarrollo full-stack -- Estudiantes que desean hacer la transición de gerente de producto a ingeniero full-stack +## Para quien es + +- Desarrolladores con alguna base de programacion que quieran aprender desarrollo full-stack de manera sistematica +- Estudiantes que desean hacer la transicion de gerente de producto a ingeniero full-stack - Desarrolladores junior a intermedios que quieren dominar herramientas y flujos de trabajo de desarrollo modernos - Emprendedores que quieren desarrollar productos completos de forma independiente ## Requisitos previos -- Completar la etapa de "Novato y prototipo de producto", o tener conocimientos básicos equivalentes -- Comprender conceptos básicos de HTML/CSS/JavaScript -- Tener conocimientos preliminares sobre herramientas de programación de IA +- Haber completado la etapa de "Novato y prototipo de producto", o tener conocimientos basicos equivalentes +- Comprender conceptos basicos de HTML/CSS/JavaScript +- Tener conocimientos preliminares sobre herramientas de programacion con IA -¿Listo para profundizar en el desarrollo full-stack? ¡Haz clic en la navegación izquierda para comenzar a aprender! +Listo para profundizar en el desarrollo full-stack? Haz clic en la navegacion izquierda para comenzar a aprender! diff --git a/docs/fr-fr/stage-2/ai-capabilities/dify-knowledge-base/index.md b/docs/fr-fr/stage-2/ai-capabilities/dify-knowledge-base/index.md new file mode 100644 index 0000000..184bf38 --- /dev/null +++ b/docs/fr-fr/stage-2/ai-capabilities/dify-knowledge-base/index.md @@ -0,0 +1,574 @@ +# Introduction à Dify et intégration de base de connaissances + +# Rappel du cours précédent + +Dans les cours précédents, nous avons étudié en groupes la programmation IA, l'ingénierie des prompts et les fondamentaux de la génération d'images par IA. Ces contenus nous ont permis de mieux comprendre les limites et les capacités des différents grands modèles de langage (LLM, Large Language Model) ou modèles génératifs. + +Pour vous aider à réviser le cours précédent, voici quelques questions de réflexion : + +1. Qu'est-ce que la programmation IA ? Comment utiliser des outils de programmation IA (comme [z.ai](http://z.ai)) pour créer une page web ? +2. Qu'est-ce qu'un grand modèle de langage ? Qu'est-ce que l'ingénierie des prompts et l'ingénierie du contexte ? Comment rédiger un prompt complexe ? +3. Pour les trois directions que sont le texte, l'AI Coding et la génération d'images, comment jugez-vous de la puissance des modèles dans chaque domaine ? +4. Qu'est-ce qu'une API ? Comment utiliser [z.ai](http://z.ai) pour se connecter à une API tierce ? + +Si l'une de ces questions vous semble encore floue, vous pouvez revoir les documents du cours précédent, ou poser directement vos questions dans le groupe de discussion WeChat. + +Dans ce cours, nous passerons des simples outils de texte et d'images IA à des plateformes de construction de flux de travail plus proches des besoins réels des entreprises. Nous évoluerons des chatbots vers les agents IA et les flux de travail (Workflows) IA, puis via une API nous créerons une page de robot « intelligent » interactive. + +Si vous rencontrez des étapes difficiles à comprendre, ne vous inquiétez pas. Nous vous recommandons de faire régulièrement des captures d'écran de la page en cours d'utilisation et de les envoyer à un grand modèle pour obtenir des explications. Les modèles actuels peuvent répondre à la plupart des questions courantes. + +Si après avoir posé votre question le problème persiste, n'hésitez pas à expérimenter par vous-même. N'ayez pas peur de vous tromper -- chaque tentative est une occasion d'apprendre et de progresser. Avec la pratique, vous deviendrez de plus en plus à l'aise ! + +# Ce que vous allez apprendre dans ce cours + +1. Pourquoi passer des chatbots aux agents IA et à l'orchestration de Workflows. +2. Qu'est-ce qu'un agent IA et une plateforme de développement de workflows, comment standardiser et orchestrer les capacités de l'IA. +3. Qu'est-ce que Dify, comment utiliser cette plateforme open source orientée applications LLM pour construire rapidement des applications, notamment des chatbots à base de connaissances. +4. Les méthodes d'implémentation et la valeur de RAG, pourquoi la génération augmentée par recherche est-elle nécessaire. +5. Comment apprendre de 0 à 1 à utiliser Dify et l'IDE IA Trae (`Connaissances supplémentaires 4 - Qu'est-ce que l'IDE IA et Trae`), notamment construire des agents et des workflows, et créer une application frontend de chatbot via l'API Dify. + +- Les principes de base de Dify, les méthodes de création d'agents et de workflows, et les méthodes d'appel API. +- Comment utiliser un IDE IA pour la programmation. +- Une application frontend de chatbot interactive. + +# 1. De la conversation à l'agent + +Au stade précédent, nous avons appris à utiliser des prompts pour faire jouer des rôles aux grands modèles, générer du texte ou écrire du code simple. Mais si l'on y réfléchit attentivement, on constate un problème : un chatbot en soi ne peut pas agir. + +Il peut expliquer comment vérifier une commande, mais ne peut pas réellement aller chercher les chiffres dans la base de données ; il peut décrire ce que devrait contenir un rapport hebdomadaire, mais ne peut pas automatiquement consolider les données du projet et envoyer un email. Cette limite du « dire sans faire » rend l'IA purement conversationnelle difficile à intégrer véritablement dans les processus métier. + +Pour faire évoluer l'IA d'un simple partenaire de conversation vers un employé numérique, nous devons lui conférer trois capacités fondamentales : + +1. Des connaissances dédiées -- lui permettre d'assimiler et comprendre vos documents produit, les profils clients, les politiques internes ; +2. L'appel d'outils (ou plugins) -- lui permettre d'opérer sur des bases de données, d'appeler des API ; +3. L'exécution structurée -- lui faire accomplir les tâches selon une logique prédéfinie, étape par étape, plutôt qu'en improvisant librement. + +C'est l'ébauche d'un agent IA (AI Agent) : une unité automatisée dotée d'un objectif, de connaissances, d'outils et d'un chemin d'exécution. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image1.png) + +> Note : ce que l'industrie appelle actuellement des « agents » simples désigne généralement des applications enrichies basées sur la combinaison LLM + outils + base de connaissances, et non des agents capables de planifier de manière autonome. Bien que ces agents simples ne possèdent pas de véritables capacités de raisonnement et de planification à long terme, ils suffisent déjà à couvrir de nombreux scénarios d'automatisation en entreprise. Nous présenterons en détail dans les chapitres suivants les véritables agents capables de planification et d'action autonomes. + +## 1.1 Le plus simple des agents : le chatbot à base de connaissances + +Après avoir identifié les multiples capacités fondamentales d'un agent, une question se pose : peut-on, en implémentant uniquement la plus simple de ces fonctionnalités, construire un agent de base véritablement utilisable ? La réponse est oui. + +En fait, dans de nombreux scénarios métier réels, le besoin central des utilisateurs n'est pas que l'IA exécute automatiquement des opérations complexes (comme appeler des API ou coordonner des tâches entre systèmes), mais plutôt qu'elle fournisse des réponses précises et fiables basées sur les documents propres à l'entreprise. Cela correspond exactement à la première des trois capacités fondamentales : le service de connaissances dédiées. Nous pouvons donc introduire la forme la plus simple et la plus répandue d'agent : le chatbot à base de connaissances. + +Bien qu'il ne possède pas encore de capacités d'appel d'outils ou de planification autonome, sa avancée clé est la suivante : les réponses du grand modèle ne sont plus générées à partir de rien, mais s'appuient sur des sources vérifiables. Comment y parvenir ? La solution repose sur la génération augmentée par recherche (Retrieval-Augmented Generation, RAG). + +L'idée fondamentale de RAG est la suivante : lorsque l'utilisateur pose une question, le système recherche d'abord dans la base de connaissances de l'entreprise les extraits de texte les plus pertinents sémantiquement (par exemple un passage du manuel produit, un article du règlement RH), puis injecte ces extraits comme contexte dans l'entrée du grand modèle, pour guider celui-ci à générer une réponse fondée sur des données réelles. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image2.png) + +Source de l'image : [https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag](https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag) + +Ainsi, les réponses du modèle ne dépendent plus de ses connaissances générales issues des données d'entraînement, mais s'ancrent sur les informations authentiques fournies par l'entreprise. L'objectif de RAG est précisément d'améliorer significativement la véracité, la précision et la cohérence des réponses grâce à cette injection dynamique de connaissances externes -- pouvant même adapter le ton (par exemple répondre dans le style d'un service client ou d'une documentation technique). + +En pratique, cette technologie est particulièrement importante car les grands modèles produisent souvent des « hallucinations ». Par exemple, si vous demandez des données spécifiques en vous faisant passer pour un directeur financier ou un consultant, le modèle risque d'inventer des dates et des événements. Avec RAG, la contrôlabilité et la fiabilité des réponses sont considérablement améliorées. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image3.png) + +Source de l'image : [https://www.databricks.com/glossary/retrieval-augmented-generation-rag](https://www.databricks.com/glossary/retrieval-augmented-generation-rag) + +Dans la partie pratique de ce cours, nous utiliserons la plateforme de workflows IA populaire Dify pour construire un chatbot à base de connaissances. Vous pourrez facilement constituer une base de connaissances à partir de divers documents dédiés : manuels produits, politiques internes, documents de projet, articles de recherche, notes personnelles. + +Une fois la construction terminée, vous pourrez tester ses capacités avec différentes questions, par exemple : + +- « Quelles sont les principales nouveautés de la dernière version de notre produit A ? » +- « Selon le manuel du personnel, comment fonctionne le système de congés cette année ? » +- « Dans le projet XX, comment avons-nous résolu le défi technique "XXX" ? » +- « Quelle est la méthode de recherche centrale mentionnée dans cet article ? » + +Vous découvrirez par vous-même comment RAG transforme des documents dispersés en une base de connaissances intelligente et précise. + +## 1.2 De l'agent conversationnel au workflow + +Cependant, même un « agent enrichi » disposant d'une base de connaissances et de capacités d'appel de plugins se révèle insuffisant face à des processus métier plus complexes. + +Prenons une demande utilisateur : « Quelles sont les dernières mises à jour fonctionnelles de notre produit SaaS récemment lancé ? Peux-tu me préparer un briefing pour les clients ? » + +Cette demande semble simple, mais elle nécessite plusieurs étapes coordonnées : d'abord extraire les enregistrements de lancement du mois écoulé depuis la documentation interne ou la base de connaissances Notion ; puis filtrer les fonctionnalités clés orientées client ; ensuite appeler un grand modèle pour convertir les descriptions techniques en langage client-friendly ; enfin pousser le contenu généré vers l'équipe marketing par email, ou le sauvegarder dans un template Google Docs. + +Si l'on s'en remet uniquement au raisonnement libre d'un seul grand modèle, non seulement il est peu probable de tout réaliser en une seule conversation, mais le risque est grand d'omettre des informations clés, de confondre le jargon interne et le langage client, ou de produire un résultat non structuré. Plus important encore, l'entreprise a besoin de parcours d'exécution standardisés, auditables, réutilisables et surveillables, et non d'une improvisation dépendant du modèle à chaque fois. La reproductibilité et la surveillance sont cruciales pour les entreprises -- des résultats inattendus peuvent entraîner des pertes graves. + +C'est ce qui nous mène au paradigme d'application IA de niveau supérieur : le workflow IA (AI Workflow). + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image4.png) + +Un workflow désigne la décomposition d'une tâche complexe en plusieurs sous-étapes ordonnées, configurables et exécutables automatiquement, dont les relations logiques (conditions, boucles, parallélisme) sont orchestrées de manière visuelle ou par code. Standardiser les capacités IA (c'est-à-dire les transformer en procédures opérationnelles standardisées) signifie cristalliser l'expérience de l'utilisation de l'IA pour une tâche donnée en un template réutilisable. + +Cette approche offre de multiples avantages : les non-techniciens (comme les chefs de produit ou les responsables marketing) peuvent assembler rapidement des applications IA par glisser-déposer de composants ; les développeurs peuvent encapsuler la recherche RAG, les appels LLM, les outils API en nœuds standardisés, réutilisables dans différents scénarios métier ; l'ensemble du processus peut être tracé, débogué et optimisé en continu, répondant aux exigences de stabilité et de conformité des entreprises. + +L'utilisation des workflows IA touche un public très large. Les chefs de produit peuvent concevoir des parcours utilisateur complets sans coder ; les équipes marketing peuvent rapidement construire des chatbots de service client, des générateurs de contenu ou des systèmes de notification ; les développeurs et ingénieurs peuvent modulariser les capacités clés pour les appels frontend ; les entrepreneurs ou développeurs indépendants peuvent valider un MVP de produit IA à moindre coût, en mettant en ligne en quelques jours un prototype complet incluant interrogation de données, génération de contenu et exécution d'actions. + +En résumé, si les agents font passer l'IA du stade de « savoir discuter » à « savoir agir », les workflows la font passer de « réussir parfois une tâche » à « accomplir de manière stable, fiable et à grande échelle une catégorie de tâches ». Dans la pratique qui suit, nous utiliserons la plateforme Dify pour construire de nos propres mains un workflow IA complet. + +## 1.3 Plateformes d'agents et de workflows courantes + +Avec le développement rapide de l'IA générative, un ensemble de plateformes low-code voire no-code d'agents et de workflows ont émergé pour aider les développeurs et les équipes métier à construire rapidement des agents et des processus automatisés, sans se perdre dans la complexité de la programmation. + +La notion clé de plateforme low-code désigne des outils de développement réduisant considérablement le codage manuel grâce à des composants glisser-déposer visuels, des templates de logique métier prédéfinis et une configuration graphique des règles. Leur cœur est de remplacer l'écriture de code par une configuration visuelle et un assemblage de nœuds par glisser-déposer, libérant les développeurs des tâches répétitives tout en permettant aux non-techniciens maîtrisant la logique métier de participer à la construction d'applications. + +La valeur essentielle de ces plateformes est de réduire considérablement le seuil d'entrée pour le développement d'applications IA. Ce qui nécessitait auparavant une collaboration d'équipe pendant des semaines -- de l'analyse des besoins au développement, tests et déploiement -- peut désormais être accompli en quelques heures grâce aux outils visuels de ces plateformes. + +Les principales plateformes de workflows IA low-code actuellement sur le marché : + +| Plateforme | Caractéristiques | Scénarios d'utilisation | +| --- | --- | --- | +| Dify | Open source, RAG, orchestration LLM, API, adapté au chinois | Base de connaissances entreprise, agents personnalisés, services API | +| Coze (ByteDance) | Disponible en Chine, intégration Douyin/Lark, plugins riches | Bots sociaux, intégration mini-programmes | +| n8n | Automatisation générale, nœuds IA, orchestration API | Synchronisation inter-systèmes, automatisation IA + SaaS | +| Baidu Qianfan / Alibaba Bailian / Tencent HunYuan | Solutions cloud natives des grands groupes | Déploiement entreprise, haute conformité | + +Dify, Coze et n8n se distinguent par trois avantages clés : + +1. Facilité d'utilisation extrême. Interface glisser-déposer visuelle, prise en main rapide sans comprendre la technologie sous-jacente. +2. Grande flexibilité. Composants personnalisés et API extensibles, adaptés aux scénarios légers (démonstrations, MVP) comme aux besoins d'itération agile des PME. +3. Écosystème mature. Documentation officielle détaillée, réponse rapide, communauté active avec de nombreux templates partagés. + +Ces trois plateformes permettent toutes d'exposer les agents construits sous forme d'API standardisée, intégrables dans les applications web frontend, les systèmes ERP internes ou les apps mobiles. + +### 1.3.1 Dify : plateforme LLMOps d'entreprise + +Dify se positionne comme une plateforme de développement et d'exploitation d'applications LLM, dédiée à la gestion du cycle de vie complet, de la conception au déploiement et à l'optimisation. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image6.png) + +En termes de fonctionnalités, Dify couvre l'orchestration visuelle de workflows, la construction d'agents, la gestion de bases de connaissances et le support multi-modèles. La plateforme permet de concevoir des flux de tâches complexes par glisser-déposer de nœuds et supporte la création d'agents basés sur les intentions. Sa fonctionnalité de base de connaissances est particulièrement aboutie, capable de traiter de multiples formats de documents avec une recherche vectorielle efficace. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image7.png) + +### 1.3.2 Coze (ByteDance) + +Coze est la plateforme de développement d'agents IA de ByteDance, centrée sur la facilité d'utilisation extrême. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image8.png) + +Sa particularité est de simplifier la construction de bots en un assemblage de type « briques LEGO ». Les bots créés peuvent être publiés en un clic sur Doubao, Lark, WeChat et d'autres plateformes. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image9.png) + +### 1.3.2 n8n : moteur d'automatisation de workflows programmable + +n8n est une plateforme d'automatisation de workflows programmable et polyvalente, dont le positionnement central est de connecter applications, bases de données et API pour automatiser les flux de données et l'exécution de tâches. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image10.png) + +Sa caractéristique technique clé est le « code source visible » et l'« auto-hébergement », permettant un déploiement privé pour un contrôle total des données et de l'environnement. Son principal atout réside dans son écosystème communautaire extrêmement riche. + +# 2. Dify en profondeur + +## 2.1 Qu'est-ce que Dify + +Dify est une plateforme open source pour le développement d'applications LLM. Elle offre une interface intuitive combinant workflows d'agents, pipelines RAG, capacités d'outils, gestion de modèles et observabilité, pour vous aider à passer rapidement du prototype à la production. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image11.png) + +Construire un workflow dans Dify, c'est comme assembler des briques LEGO ou un puzzle. Vous connectez des « nœuds LLM » (compréhension et génération), des « nœuds outils » (exécution d'actions spécifiques : interrogation de base de données, envoi d'email, traduction) et des « nœuds de données » (lecture, stockage d'informations) entre eux. Ils fonctionnent automatiquement selon la logique prédéfinie, sans intervention manuelle répétée. + +Par exemple, si vous dirigez un magasin e-commerce Amazon ou Douyin et souhaitez construire un service client IA, vous pouvez concevoir un workflow comme suit : + +1. Nœud déclencheur : reçoit la question de l'utilisateur. +2. Nœud de classification : utilise un modèle pour classer la question (service après-vente, mode d'emploi, etc.). +3. Nœud de recherche de connaissances : accède à la base de connaissances correspondante. +4. Nœud LLM : génère une réponse conviviale à partir de la question et des connaissances récupérées. +5. Nœud de condition : vérifie si la réponse contient les informations attendues. +6. Nœud de sortie : renvoie la réponse finale à l'utilisateur. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image12.png) + +### 2.1.1 Déployer votre propre Dify (optionnel) + +Consultez le tutoriel : [Comment déployer une application Web](/fr-fr/stage-2/backend/zeabur-deployment/) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image13.png) + +## 2.2 Créer votre première application Chatbot Dify + +Accédez à [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps), inscrivez-vous et connectez-vous, puis sélectionnez Studio. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image14.png) + +Cliquez sur `Create from Blank` dans la section `CREATE APP`. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image15.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image16.png) + +Sélectionnez Chatbot comme type d'application, saisissez un nom et une description, puis créez. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image17.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image18.png) + +La zone « INSTRUCTIONS » correspond aux instructions intégrées (prompt système par défaut). + +La zone « Knowledge » en dessous est la zone de base de connaissances. + +Le panneau de droite est la fenêtre de débogage pour tester les réponses en temps réel. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image19.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image20.png) + +## 2.3 Prendre en charge les fournisseurs de modèles personnalisés + +Dify prend en charge la configuration de trois types de modèles : LLM, Embedding et Rerank. + +Installez les plugins `OpenAI-API-compatible` et `SiliconFlow` pour accéder à la plupart des modèles. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image21.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image22.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image23.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image24.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image25.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image26.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image27.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image28.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image29.png) + +## 2.4 Créer votre première base de connaissances Dify + +Cliquez sur `Knowledge` dans le menu supérieur pour accéder à la page de création de base de connaissances. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image30.png) + +Cliquez sur `Create Knowledge`. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image31.png) + +Chargez vos fichiers (PDF, TXT, etc.) pour construire la base de connaissances. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image32.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image33.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image34.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image35.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image36.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image37.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image38.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image39.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image40.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image41.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image42.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image43.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image44.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image45.png) + +## 2.5 Autres opérations courantes dans Dify + +### 2.5.1 Importer et exporter des workflows + +Dify prend en charge l'import/export de workflows au format DSL (JSON). + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image46.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image47.png) + +### 2.5.2 Explorer plus de projets Dify + +Cliquez sur Explora pour voir les workflows construits par d'autres. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image48.png) + +## 2.6 Créer votre première application Workflow Dify + +Sélectionnez Chatflow ou Workflow selon que votre besoin est une conversation continue ou un processus automatisé. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image49.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image50.png) + +- **Chatflow** : conçu pour les conversations, avec mémoire et contexte. +- **Workflow** : conçu pour l'automatisation, traitement ponctuel entrée -> sortie. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image51.png) + +### 2.6.1 Nœuds courants + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image52.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image53.png) + +**Nœuds LLM et de raisonnement :** + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image54.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image55.png) + +- LLM : unité de calcul principale appelant le grand modèle. +- Knowledge Retrieval : recherche dans les bases de connaissances. +- Answer : sortie des résultats. +- Agent : prise de décision avancée avec outils. +- Question Classifier : classification des questions par type. + +**Nœuds de logique et contrôle de flux :** + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image56.png) + +- Condition (IF/ELSE) : branchement logique. +- Iteration : traitement parallèle par lots sans état. +- Loop : itération récursive avec état. + +**Nœuds de manipulation de données et intégration :** + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image57.png) + +- Code : logique personnalisée en code. +- Template : génération de contenu à partir de templates. +- Variable Aggregator : consolidation de variables. +- Doc Extractor : extraction depuis documents. +- HTTP Request : appels vers des systèmes externes. +- List Operator : opérations sur listes/tableaux. + +### 2.6.2 Outils courants + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image58.png) + +Les outils dans Dify peuvent être placés directement sur le canevas comme des nœuds. + +- **Recherche web** : Tavily Search pour une recherche optimisée pour l'IA. +- **Traitement de données** : JSON Process pour les opérations avancées sur JSON. +- **Formatage** : Markdown Exporter pour l'export dans des formats spécifiés. + +### 2.6.3 Créer un workflow simple de classification d'intention + +Pour un scénario de restaurant, nous créons un workflow capable de classer les intentions des utilisateurs en quatre catégories : commande (buy_food), réclamation (complain), conversation (chitchat) et autre (other). + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image59.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image60.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image61.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image62.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image63.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image64.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image65.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image66.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image67.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image68.png) + +#### Test du workflow + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image69.png) + +## 2.7 Exécuter un workflow template + +Importez le workflow DeepResearch officiel et corrigez les erreurs au fur et à mesure. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image70.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image71.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image72.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image73.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image74.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image75.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image76.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image77.png) + +## 2.8 Utiliser Dify comme fournisseur d'API + +Nous allons maintenant appeler l'agent à base de connaissances créé précédemment via l'API Dify. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image78.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image79.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image80.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image81.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image82.png) + +## 2.9 Créer une application frontend de conversation via l'API Dify + +Publiez d'abord l'agent, puis accédez à la documentation API. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image83.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image84.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image85.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image86.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image87.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image88.png) + +Utilisez Trae Builder avec votre clé API, la requête et la réponse exemples pour générer le code frontend. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image89.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image90.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image91.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image92.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image93.png) + +# 3. Références de workflows métier supplémentaires + +Vous pouvez rechercher sur Internet avec des mots-clés comme « Dify workflow examples » ou trouver des dépôts GitHub partageant des workflows Dify. + +Voici quelques idées de workflows générées par un grand modèle : + +## 3.1 Workflows pour plateformes sociales + +1. Distribution multi-plateforme en un clic (complexe) +2. Générateur de sujets tendance et brouillons (moyen) +3. Assistant de classification et réponse aux commentaires (complexe) +4. Générateur de scripts et storyboards vidéo (complexe) +5. Résumé en temps réel des interactions en live (moyen) + +## 3.2 Workflows professionnels + +1. Compte-rendu de réunion intelligent et assignation automatique de tâches (complexe) +2. Filtrage et évaluation automatisée de CV (moyen) +3. Traduction et réponse multilingue par email (simple) +4. Consolidation automatique de rapports hebdomadaires/mensuels (complexe) +5. Révision intelligente de contrats/documents (moyen) + +## 3.3 Workflows pour l'apprentissage et la vie quotidienne + +1. Analyseur approfondi d'articles académiques avec génération de notes (complexe) +2. Planificateur de voyage personnalisé (moyen) +3. Partenaire de pratique linguistique interactif (simple) +4. Système de Q&R sur base de connaissances personnelle (complexe) +5. Conseiller fitness/nutrition avec suivi (moyen) + +# 6. Limites des plateformes de workflows + +Les plateformes de workflows (ou plateformes low-code) ne sont pas des solutions universelles. Bien qu'elles soient conviviales pour les profils métier et réduisent le seuil de codage, le « low-code » implique aussi son propre coût d'apprentissage : l'utilisateur doit comprendre les concepts, règles et logique opérationnelle de la plateforme. + +Vous pourriez légitimement vous demander : beaucoup de workflows simples ne sont que des appels de fonctions de grand modèle enchaînés, l'output de l'un devenant l'input du suivant, ce qui pourrait être résolu en quelques lignes de code. Pourquoi nécessiter une infrastructure de workflow aussi complexe ? + +Vous avez raison. Avec le développement rapide du vibe coding et les capacités de génération de code par l'IA, lire voire générer du code directement peut parfois être plus efficace. Idéalement, nous pourrions piloter la logique applicative en langage naturel -- ce serait une véritable plateforme logicielle moderne. Mais les plateformes de workflow actuelles ne l'ont pas encore atteint, créant un « intermédiaire » naturel entre l'intention de l'utilisateur et la réalisation finale. + +Néanmoins, la maîtrise de ces plateformes devient une compétence de base, analogue aux outils bureautiques Microsoft, très répandue et utile en entreprise. + +# 📚 Exercice final + +## Maîtriser les opérations de base de Dify + +1. Créez un workflow de classification d'intention dans un scénario entièrement différent. +2. Défi de workflow « Login » : trouvez le bon mot de passe, modifiez-le, ajoutez une deuxième tentative. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image94.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image95.png) + +3. Défi de workflow « Love loop » : corrigez le workflow pour obtenir la sortie attendue. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image96.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image97.png) + +## Implémenter l'appel API Dify + +1. Déployez Dify et créez une base de connaissances simple. +2. Utilisez Trae IDE pour construire un frontend de conversation interagissant via l'API Dify. +3. Testez les conversations multi-tours. + +## Essayer un workflow tiers ou construire le vôtre + +Trouvez un workflow Dify sur Github, WeChat, Reddit ou Twitter, importez-le et exécutez-le avec succès. + +# [Bug] Solution au problème d'erreur de requête HTTP + +Si vous rencontrez le problème illustré ci-dessous, consultez cette section ; sinon vous pouvez l'ignorer. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image98.png) + +Ce problème survient lorsque Dify est déployé sur un serveur ne supportant que HTTP (sans HTTPS). Le HTTPS (HyperText Transfer Protocol Secure) est une version sécurisée du HTTP avec chiffrement SSL/TLS. + +Solutions possibles : +- Utiliser un proxy inverse avec certificat (nginx) +- Lier un domaine et obtenir un certificat + +Nous utiliserons Zeabur comme passerelle réseau pour résoudre ce problème : + +- Adresse d'origine : `http://{DIFY_API_URL}/v1/chat-messages` +- Nouvelle adresse : `https://{DIFY_NEW_API_URL}.zeabur.app/v1/chat-messages` + +Vous pouvez déployer un service proxy sur Zeabur en sélectionnant Python et en utilisant le code suivant : + +```python +from flask import Flask, request, Response +import requests + +app = Flask(__name__) + +TARGET_BASE_URL = "{DIFY_API_URL}" +LISTEN_PORT = 8080 + +@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +@app.route('/', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +def proxy_request(path): + target_url = f"{TARGET_BASE_URL}/{path}" + if request.query_string: + target_url += f"?{request.query_string.decode('utf-8')}" + + headers = {key: value for key, value in request.headers if key.lower() not in ['host', 'connection', 'content-length', 'accept-encoding']} + + try: + resp = requests.request( + method=request.method, + url=target_url, + headers=headers, + data=request.get_data(), + cookies=request.cookies, + allow_redirects=False, + timeout=30 + ) + + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + response_headers = [(name, value) for name, value in resp.raw.headers.items() if name.lower() not in excluded_headers] + + return Response(resp.content, resp.status_code, response_headers) + + except requests.exceptions.RequestException as e: + print(f"Error forwarding request to {target_url}: {e}") + return Response(f"Proxy Error: Could not reach target server or invalid response: {e}", status=502) + except Exception as e: + print(f"An unexpected error occurred: {e}") + return Response(f"Internal Proxy Error: {e}", status=500) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=LISTEN_PORT, debug=True) +``` \ No newline at end of file diff --git a/docs/fr-fr/stage-2/assignments/copywriting-platform-supabase/index.md b/docs/fr-fr/stage-2/assignments/copywriting-platform-supabase/index.md new file mode 100644 index 0000000..19e3fd4 --- /dev/null +++ b/docs/fr-fr/stage-2/assignments/copywriting-platform-supabase/index.md @@ -0,0 +1,346 @@ +# Projet 1 : Première application full-stack SaaS — Site de génération de copywriting + +## Présentation + +Ce projet pratique vous demande de réaliser, à partir d'un véritable PRD (Document d'Exigences Produit), un produit SaaS de copywriting marketing IA destiné aux développeurs indépendants et aux équipes de contenu. Vous utiliserez Supabase comme service backend et Stripe comme système de paiement, en parcourant l'ensemble du processus, de l'analyse des besoins au déploiement en ligne. + +Il s'agit du projet pratique synthétique de l'Étape 2. Dans les chapitres précédents, vous avez appris séparément la création de pages frontend, le développement d'interfaces backend, les opérations de base de données et l'intégration de paiements — ce projet vous demande de tout assembler pour livrer un prototype de produit fonctionnel. + +## Prérequis + +Avant de commencer ce projet, vous devriez maîtriser les sujets suivants : + +- Conception de pages frontend et utilisation de bibliothèques de composants ([Conception UI](../../frontend/ui-design/), [Bibliothèque de composants moderne](../../frontend/modern-component-library/)) +- Conception et développement d'interfaces backend ([Conception et développement d'interfaces backend](../../backend/ai-interface-code/)) +- Bases de données et Supabase ([De la base de données à Supabase](../../backend/database-supabase/)) +- Intégration de paiements ([Système de paiement Stripe](../../backend/stripe-payment/)) +- Flux de travail Git et déploiement ([Git et GitHub](../../backend/git-workflow/), [Déployer une application web](../../backend/zeabur-deployment/)) + +## Objectifs d'apprentissage + +Après avoir terminé ce projet, vous serez capable de : + +1. Lire et comprendre un véritable PRD et en extraire une liste de tâches de développement +2. Utiliser l'IA pour générer étape par étape les pages frontend et les interfaces backend +3. Utiliser Supabase pour l'authentification utilisateur et les opérations de base de données +4. Intégrer Stripe pour la fonctionnalité d'abonnement payant +5. Construire une console d'administration et effectuer des tests de bout en bout + +## Présentation du projet + +Le produit que vous allez construire est un SaaS de copywriting marketing IA, comprenant trois sous-systèmes : + +| Sous-système | Responsabilité | +|--------|------| +| **Site vitrine** | Présentation du produit, tarification, FAQ, conversion à l'inscription | +| **Espace utilisateur** | Saisie des informations produit, génération de copywriting, historique, mise à niveau du forfait | +| **Console d'administration** | Gestion des utilisateurs, enregistrements de génération, données de paiement, vue d'ensemble des opérations | + +Le backend utilise Supabase pour la base de données et l'authentification, Stripe pour les paiements, et un modèle IA pour générer le copywriting marketing. + +::: tip Accès au PRD +Le document d'exigences de ce projet se trouve sur GitHub : [Voir le PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/copywriting-platform-supabase/PRD.md) +::: + +
+ + + +
+ +## Partie 1 : Analyse des besoins + +### 1.1 Lire le PRD + +Ouvrez le document PRD et répondez aux questions suivantes : + +- Combien d'entrées le système possède-t-il ? Quelles pages couvre chacune ? +- Quelle est la fonction principale de chaque page ? +- Quels modules et tables de données le backend comprend-il ? +- Comment la tarification, le processus de paiement et le quota gratuit sont-ils conçus ? +- Quel est le périmètre MVP ? Que fait-on et que ne fait-on pas dans la première version ? + +::: warning +Si vous n'avez pas de réponses claires aux questions ci-dessus, ne commencez pas à coder. Une mauvaise compréhension des besoins est la cause la plus fréquente de rework. +::: + +### 1.2 Confirmer l'architecture du système + +D'après le PRD, dégagez l'architecture globale du système : + +```mermaid +flowchart TD + prd["PRD"] --> web["Site vitrine"] + prd --> app["Espace utilisateur"] + prd --> admin["Console d'administration"] + app --> auth["Authentification"] + app --> gen["Tâches de génération de copywriting"] + gen --> db["Base de données"] + billing["Paiement et forfaits"] --> db + admin --> analytics["Tableau de bord utilisateurs / génération / paiements"] +``` + +## Partie 2 : Structure du projet + +### 2.1 Générer les pages frontend + +Utilisez l'IA pour générer d'abord la structure de base de toutes les pages avec des données fictives. + +Prompt de référence : + +```text +Générez un squelette frontend pour un SaaS de copywriting marketing IA, basé sur le PRD actuel. + +Exigences : +1. Trois entrées séparées : www, app, admin +2. Le site vitrine comprend : page d'accueil, tarification, FAQ +3. L'app comprend : connexion, inscription, espace de génération, historique, page des forfaits +4. L'admin comprend : page d'accueil backend, gestion des utilisateurs, enregistrements de génération, commandes de paiement +5. Ne générez que la structure des pages et des données fictives, sans interfaces réelles +6. Le style doit ressembler à un SaaS moderne, pas à une démo de classe +``` + +### 2.2 Améliorer les pages principales + +Une fois la structure en place, concentrez-vous sur l'amélioration de la page de l'espace de génération (Dashboard) : + +```text +Continuez à améliorer la page /dashboard. + +C'est un espace de génération de copywriting marketing IA. + +Champs du formulaire à gauche : +- Nom du produit +- Description en une phrase +- Utilisateurs cibles +- 3 arguments de vente +- Canaux de distribution (site web, WeChat Moments, Xiaohongshu, Douyin, email) + +Zone de résultats à droite : +- Titre principal +- Sous-titre +- CTA +- 3 versions de copywriting court +- Copywriting long + +Utilisez d'abord des données mock pour valider l'interaction. + +Exigences : +- État de chargement après clic sur « Générer le copywriting » +- Concevoir un état vide pour la zone de résultats +- Mise en page responsive, adaptée aux écrans larges et étroits +``` + +### 2.3 Vérifier la structure des pages + +Vérifiez chaque élément : + +- [ ] Les routes des trois entrées sont-elles indépendantes +- [ ] Le nombre de pages correspond-il au PRD +- [ ] La mise en page du formulaire et de la zone de résultats du Dashboard est-elle raisonnable +- [ ] Les données fictives présentent-elles les états UI de base + +### Bloqué ? + +Si vous êtes bloqué lors de la construction du frontend, vous pouvez consulter ces chapitres : + +- [Conception UI](../../frontend/ui-design/) +- [Concevoir des pages et des boutons en référence aux guidelines de conception UI](../../frontend/multi-product-ui/) +- [Rendre l'interface attrayante avec les LLM et les Skills](../../frontend/llm-skills-beautiful/) +- [Du prototype de conception au code de projet](../../frontend/design-to-code/) +- [Mettre à jour votre interface avec une bibliothèque de composants moderne](../../frontend/modern-component-library/) + +## Partie 3 : Intégration backend + +### 3.1 Intégrer la connexion Supabase + +```text +Considérez que je suis débutant et guidez-moi étape par étape pour intégrer la connexion Supabase. + +J'ai besoin que vous m'aidiez à : +1. Intégrer Supabase dans le projet +2. Implémenter les fonctions d'inscription, de connexion et de déconnexion +3. Rediriger vers /dashboard après connexion réussie +4. Rediriger automatiquement vers /login les utilisateurs non connectés accédant à /dashboard, /billing, /admin +5. Créer la table profiles +6. Créer automatiquement un enregistrement dans la table profiles après inscription réussie +7. La table profiles doit contenir les champs email, role, plan + +Exigences de mise en œuvre : +- Indiquez à chaque étape quels fichiers sont modifiés +- Ne pas coder en dur les clés secrètes +- Marquez clairement les opérations à effectuer manuellement dans la console Supabase +- Expliquez comment vérifier l'inscription et la connexion une fois terminé +``` + +### 3.2 Intégrer l'interface de génération et la base de données + +```text +Considérez que je suis débutant et aidez-moi à réaliser la fonctionnalité principale du site : générer du copywriting marketing et le sauvegarder. + +Résultat attendu : +1. L'utilisateur remplit le formulaire sur /dashboard et clique sur « Générer le copywriting » +2. Le backend reçoit : nom du produit, description, utilisateurs cibles, arguments de vente, canaux de distribution +3. Le backend appelle le modèle pour générer le résultat +4. La page affiche le résultat de la génération +5. Les entrées et sorties sont sauvegardées dans la base de données +6. L'utilisateur peut consulter son historique lors de sa prochaine visite + +J'ai besoin que vous réalisiez : +- Créer l'interface de génération /api/generate +- Créer la table generations +- Concevoir les champs d'entrée et de sortie +- La page Dashboard lit l'historique de l'utilisateur actuel + +Expérience utilisateur : +- État de chargement du bouton +- Message d'erreur en cas d'échec de la génération +- État vide en l'absence d'historique + +Une fois terminé, veuillez indiquer : +- L'emplacement des fichiers de pages frontend +- L'emplacement des fichiers d'interfaces backend +- L'emplacement de la logique d'écriture en base de données +- Comment tester la chaîne de génération complète +``` + +### 3.3 Intégrer le paiement Stripe + +```text +Considérez que je suis débutant et aidez-moi à ajouter un paiement Stripe minimal et fonctionnel au site. + +Pas besoin d'un système complexe, faites d'abord fonctionner la chaîne de paiement la plus basique. + +J'ai besoin que vous réalisiez : +1. La page /billing affiche les forfaits free et pro +2. L'utilisateur est redirigé vers Stripe Checkout après clic sur la mise à niveau +3. Retour sur le site après paiement réussi +4. Le résultat du paiement est sauvegardé dans la table subscriptions +5. Mise à jour synchrone du champ profile.plan +6. Limitation des utilisateurs free à 3 générations par jour, pas de limite pour les utilisateurs pro + +Principes de mise en œuvre : +- Faites d'abord fonctionner le flux principal, ne vous préoccupez pas des cas limites complexes +- Indiquez clairement ce qui doit être configuré dans la console Stripe +- Expliquez comment tester le processus de paiement complet une fois terminé +``` + +### 3.4 Construire la console d'administration + +```text +Considérez que je suis débutant et aidez-moi à créer une console d'administration simple et fonctionnelle. + +Accès réservé aux administrateurs uniquement. + +J'ai besoin que vous réalisiez : +1. Seuls les utilisateurs avec role = admin peuvent accéder à /admin +2. La console comprend 3 onglets : liste des utilisateurs, enregistrements de génération, statut des abonnements +3. La liste des utilisateurs affiche : email, plan, date de création +4. Les enregistrements de génération affichent : utilisateur, nom du produit, canal, date de création +5. Le statut des abonnements affiche : utilisateur, forfait, statut du paiement + +Exigences : +- Interface simple et claire +- Utiliser les composants existants (tableaux, onglets, badges) de la bibliothèque de composants +- Expliquez comment définir un compte comme administrateur une fois terminé +``` + +### Bloqué ? + +Si vous êtes bloqué lors du développement backend, vous pouvez consulter ces chapitres : + +- [De la base de données à Supabase](../../backend/database-supabase/) +- [Conception et développement d'interfaces backend d'application](../../backend/ai-interface-code/) +- [Comment intégrer un système de paiement comme Stripe](../../backend/stripe-payment/) + +## Partie 4 : Tests de bout en bout et déploiement + +### 4.1 Tests de bout en bout + +Vérifiez au moins les scénarios suivants : + +- Inscription -> Connexion -> Génération de copywriting -> Consultation de l'historique -> Mise à niveau du forfait +- Connexion administrateur -> Consultation des données utilisateurs -> Consultation des enregistrements de génération -> Consultation du statut des paiements + +Vérifications avant déploiement : + +```text +Considérez que je suis débutant et aidez-moi à vérifier si le projet est prêt pour le déploiement. + +Points de vérification : +- Les variables d'environnement sont-elles complètes +- L'URL de callback de connexion est-elle correcte +- L'URL de callback de paiement Stripe est-elle correcte +- Les pages ont-elles des états de chargement, des états vides et des messages d'erreur +- Le README contient-il les instructions de démarrage et de déploiement + +J'ai besoin que vous : +1. Listiez les éléments à corriger par ordre de priorité +2. Indiquiez ceux qui doivent être corrigés en premier +3. Expliquiez les étapes de déploiement après correction +``` + +### 4.2 Déploiement + +Déployez le projet dans un environnement public. Tutoriel de déploiement : [Flux de travail Git et GitHub](../../backend/git-workflow/), [Comment déployer une application web](../../backend/zeabur-deployment/). + +## Livrables + +Après avoir terminé ce projet, vous devez soumettre les éléments suivants : + +- [ ] Lien de démonstration en ligne accessible +- [ ] Lien du dépôt de code source (avec README) +- [ ] Document PRD +- [ ] Captures d'écran des pages principales (accueil, Dashboard, Billing, Admin) +- [ ] Vidéo de démonstration de 60 secondes (couvrant inscription -> génération -> paiement -> console d'administration) + +Le README doit contenir au minimum : présentation du projet, description des pages principales, stack technique, étapes de démarrage local, liste des variables d'environnement. + +## Critères d'évaluation + +| Dimension | Exigences de base | Exigences avancées | +|------|---------|---------| +| Complétude du produit | Accueil, connexion, Dashboard, Billing, Admin sont tous accessibles | Le copywriting et le style visuel de l'accueil ressemblent à un véritable SaaS | +| Boucle métier | Inscription -> Connexion -> Génération -> Historique fonctionne | La différence de permissions entre Free/Pro est clairement visible | +| Exactitude des données | Les résultats de génération et le statut des paiements sont écrits dans la base de données | Il y a des messages d'erreur clairs, des états vides et des états de chargement | +| Permissions et sécurité | Les utilisateurs non connectés ne peuvent pas accéder aux pages protégées, les utilisateurs ordinaires ne peuvent pas accéder à l'Admin | Il y a une validation basique des entrées et une authentification côté serveur | +| Livraison du projet | Le projet peut être lancé localement et déployé sur le web public | Le README est clair, la vidéo de démonstration est structurée | + +::: tip +Si vous trouvez la tâche trop importante, rappelez-vous ce principe : **Assurez-vous d'abord que « ça fonctionne », puis cherchez à « le rendre beau ».** +::: + +## Vérification avant soumission + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## Ressources de référence + +- [Conception UI](../../frontend/ui-design/) +- [Concevoir des pages et des boutons en référence aux guidelines de conception UI](../../frontend/multi-product-ui/) +- [Rendre l'interface attrayante avec les LLM et les Skills](../../frontend/llm-skills-beautiful/) +- [Du prototype de conception au code de projet](../../frontend/design-to-code/) +- [Mettre à jour votre interface avec une bibliothèque de composants moderne](../../frontend/modern-component-library/) +- [De la base de données à Supabase](../../backend/database-supabase/) +- [Conception et développement d'interfaces backend d'application](../../backend/ai-interface-code/) +- [Flux de travail Git et GitHub](../../backend/git-workflow/) +- [Comment déployer une application web](../../backend/zeabur-deployment/) +- [Comment intégrer un système de paiement comme Stripe](../../backend/stripe-payment/) diff --git a/docs/fr-fr/stage-2/assignments/custom-dify-agent-platform/index.md b/docs/fr-fr/stage-2/assignments/custom-dify-agent-platform/index.md new file mode 100644 index 0000000..11c3c84 --- /dev/null +++ b/docs/fr-fr/stage-2/assignments/custom-dify-agent-platform/index.md @@ -0,0 +1,180 @@ +# Développement pratique d'une plateforme d'agents IA de type Dify + +## Aperçu + +Ce projet pratique vous demande de réaliser, à partir d'un véritable PRD, une plateforme d'agents IA reproduisant l'expérience centrale de Dify. Vous construirez une console utilisateur, un back-office administrateur et un backend de plateforme, en implémentant les fonctionnalités principales de gestion d'agents, de conversation, de journalisation et de base de connaissances. + +Il s'agit du projet pratique synthétique de l'Étape 2. Contrairement aux projets précédents portant sur une seule page ou une seule fonctionnalité, ce projet vous demande de construire un produit IA avec une véritable dimension de plateforme, comprenant plusieurs rôles, plusieurs modules, la persistance des données et une chaîne d'appels de modèles. + +## Prérequis + +Avant de commencer ce projet, vous devriez maîtriser les éléments suivants : + +- Conception de pages frontales et utilisation de bibliothèques de composants ([Conception UI](../../frontend/ui-design/), [Bibliothèque de composants moderne](../../frontend/modern-component-library/)) +- Conception et développement d'API backend ([Écriture de code d'interface](../../backend/ai-interface-code/)) +- Bases de données et Supabase ([Des bases de données à Supabase](../../backend/database-supabase/)) +- Flux de travail Git et déploiement ([Git et GitHub](../../backend/git-workflow/), [Déployer une application web](../../backend/zeabur-deployment/)) + +## Objectifs d'apprentissage + +Après avoir terminé ce projet, vous serez capable de : + +1. Lire et comprendre un véritable PRD et en extraire une liste de tâches de développement +2. Concevoir l'architecture des pages et le modèle de données d'une plateforme d'agents +3. Implémenter le flux complet de création d'agents, de conversation et de journalisation +4. Utiliser l'IA pour vous aider à développer un produit de type plateforme +5. Effectuer des tests de bout en bout et livrer un prototype de plateforme IA démontrable + +## Présentation du projet + +Le produit que vous allez construire est une plateforme d'agents IA de type Dify, comprenant deux sous-systèmes : + +| Sous-système | Responsabilité | +|--------|------| +| **Console utilisateur** | Créer des agents, configurer les prompts, lancer des conversations, consulter les journaux, gérer la base de connaissances | +| **Back-office administrateur** | Consulter les données utilisateurs, l'utilisation des ressources de la plateforme et les statistiques d'appels | + +Le backend doit prendre en charge les capacités principales suivantes : gestion des agents, gestion des sessions, stockage des messages, appels de modèles, journalisation des appels et intégration de la base de connaissances. + +::: tip Accès au PRD +Le document d'exigences de ce projet se trouve sur GitHub : [Voir le PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/fr-fr/stage-2/assignments/custom-dify-agent-platform/PRD.md) +::: + +
+ + + +
+ +## Partie 1 : Analyse des besoins + +### 1.1 Lire le PRD + +Ouvrez le document PRD et répondez aux questions suivantes : + +- Parmi les agents, les sessions, les journaux et la base de connaissances, lesquels doivent figurer dans le MVP ? +- La liste des pages et des routes est-elle finalisée ? +- Quelles sont les limites des appels de modèles et de la journalisation ? +- Le multi-locataire et les flux de travail complexes doivent-ils être exclus dans un premier temps ? + +::: warning +Si les questions ci-dessus n'ont pas de réponse claire, ne commencez pas à coder. Une mauvaise compréhension des besoins est la cause la plus fréquente de retour en arrière. +::: + +### 1.2 Confirmer l'architecture du système + +À partir du PRD, dégagez l'architecture globale du système : + +```mermaid +flowchart TD + prd["PRD"] --> app["Console utilisateur"] + prd --> admin["Back-office administrateur"] + app --> auth["Authentification"] + app --> agent["Configuration des agents"] + app --> chat["Sessions de conversation"] + chat --> llm["Appels de modèles"] + chat --> db["Base de données"] + app --> kb["Intégration de la base de connaissances"] + admin --> logs["Journaux d'appels et vue d'ensemble de la plateforme"] + logs --> db +``` + +## Partie 2 : Construction du squelette du projet + +### 2.1 Générer les pages frontales + +Prompt de référence : + +```text +Veuillez générer, sur la base du PRD actuel, le squelette frontend d'une plateforme d'agents IA de type Dify. + +Exigences : +1. Côté utilisateur : connexion, liste des agents, configuration des agents, page de conversation, page des journaux, page de la base de connaissances +2. Côté back-office : accueil du back-office, vue d'ensemble des utilisateurs, vue d'ensemble de l'utilisation des ressources +3. Générer d'abord uniquement la structure des pages et des données fictives, sans connexion à une API réelle +4. Le style doit ressembler à une plateforme IA moderne +``` + +### 2.2 Vérifier la structure des pages + +Vérifiez point par point : + +- [ ] Les routes de la console utilisateur et du back-office sont-elles séparées ? +- [ ] La liste des agents, la page de configuration, la conversation et les journaux sont-ils complets ? +- [ ] Le back-office dispose-t-il de la vue d'ensemble des utilisateurs et des ressources ? + +## Partie 3 : Développement itératif + +### 3.1 Progresser par module + +1. **Authentification** : Inscription, connexion, authentification de session +2. **Gestion des agents** : Créer, modifier, supprimer des agents, configurer les prompts système +3. **Conversations** : Envoyer des messages, recevoir des réponses du modèle, historique des conversations +4. **Base de connaissances** : Uploader des documents, lier un agent à une base de connaissances +5. **Journalisation** : Enregistrer chaque appel de modèle (prompt, réponse, durée, tokens) +6. **Back-office** : Statistiques d'utilisation, vue d'ensemble des ressources + +### 3.2 Modèle de données de référence + +Tables principales : + +- `agents` : id, user_id, name, system_prompt, model, created_at +- `conversations` : id, agent_id, user_id, created_at +- `messages` : id, conversation_id, role, content, created_at +- `knowledge_bases` : id, agent_id, name, created_at +- `call_logs` : id, agent_id, conversation_id, model, prompt_tokens, completion_tokens, latency_ms, created_at + +## Partie 4 : Tests et mise en ligne + +### 4.1 Tests de bout en bout + +Vérifiez au minimum les scénarios suivants : + +- Créer un agent -> Lancer une conversation -> Consulter les journaux +- Uploader un document dans la base de connaissances -> Vérifier que l'agent peut l'utiliser +- Consulter les statistiques du back-office + +### 4.2 Déploiement + +- Déployer le frontend sur Vercel / Zeabur +- Déployer le backend sur Zeabur / Railway / Render +- Utiliser Supabase comme base de données + +Vérifications avant déploiement : + +- [ ] Les variables d'environnement sont-elles toutes configurées ? +- [ ] L'authentification fonctionne-t-elle correctement en production ? +- [ ] Les appels de modèles fonctionnent-ils correctement ? + +## Livrables + +Après avoir terminé ce projet, vous devez soumettre les éléments suivants : + +- [ ] Un lien de démonstration en ligne accessible +- [ ] Un lien vers le dépôt de code source (avec README) +- [ ] Le document PRD +- [ ] Des captures d'écran des pages principales +- [ ] Une vidéo de démonstration de 60 secondes + +## Critères d'évaluation + +| Dimension | Exigences de base | Exigences avancées | +|------|---------|---------| +| Boucle des agents | Créer un agent, lancer une conversation, voir les journaux | La base de connaissances est intégrée et les agents peuvent l'utiliser | +| Plateforme | Console utilisateur et back-office sont accessibles | Les journaux d'appels et les statistiques sont complets | +| Technique | Le backend peut appeler des modèles et stocker les résultats | Gestion des erreurs et optimisation des performances | +| Livraison | Le projet peut être exécuté et déployé | README clair et vidéo de démonstration | + +## Références + +- [Conception UI](../../frontend/ui-design/) +- [Bibliothèque de composants moderne](../../frontend/modern-component-library/) +- [Des bases de données à Supabase](../../backend/database-supabase/) +- [Écriture de code d'interface assistée par IA](../../backend/ai-interface-code/) +- [Flux de travail Git et GitHub](../../backend/git-workflow/) +- [Comment déployer une application web](../../backend/zeabur-deployment/) diff --git a/docs/fr-fr/stage-2/assignments/exam-management-express/index.md b/docs/fr-fr/stage-2/assignments/exam-management-express/index.md new file mode 100644 index 0000000..3cff7a0 --- /dev/null +++ b/docs/fr-fr/stage-2/assignments/exam-management-express/index.md @@ -0,0 +1,306 @@ +# Développement pratique d'un système de gestion d'examens en ligne + +## Aperçu + +Ce projet pratique vous demande de réaliser, à partir d'un véritable PRD (document d'exigences produit), un système de gestion d'examens en ligne complet, depuis zéro. La particularité de ce projet est qu'il comprend plusieurs rôles (étudiants et administrateurs), chacun voyant des pages différentes et pouvant exécuter des opérations différentes. Vous utiliserez Express pour construire le backend et implémenter le flux métier complet des examens. + +Il s'agit du projet pratique synthétique de l'Étape 2. Les systèmes multi-rôles avec gestion des permissions sont très courants en milieu professionnel. Une fois ce modèle maîtrisé, vous pourrez faire face à de nombreux scénarios métier tels que la formation en ligne, les plateformes SaaS ou les back-office administratifs. + +## Prérequis + +Avant de commencer ce projet, vous devriez maîtriser les éléments suivants : + +- Conception de pages frontales et utilisation de bibliothèques de composants ([Conception UI](../../frontend/ui-design/), [Bibliothèque de composants moderne](../../frontend/modern-component-library/)) +- Conception et développement d'API backend ([Écriture de code d'interface](../../backend/ai-interface-code/)) +- Bases de données et Supabase ([Des bases de données à Supabase](../../backend/database-supabase/)) +- Flux de travail Git et déploiement ([Git et GitHub](../../backend/git-workflow/), [Déployer une application web](../../backend/zeabur-deployment/)) + +## Objectifs d'apprentissage + +Après avoir terminé ce projet, vous serez capable de : + +1. Lire et comprendre un véritable PRD, et en extraire une liste de tâches de développement +2. Concevoir le contrôle des permissions et le routage des pages pour un système multi-rôles +3. Implémenter une API backend complète avec Express +4. Réaliser le flux métier complet : examen, soumission, notation automatique +5. Effectuer des tests de bout en bout et livrer un prototype de système métier démontrable + +## Présentation du projet + +Le produit que vous allez construire est un système de gestion d'examens en ligne, comprenant trois sous-systèmes : + +| Sous-système | Responsabilité | +|--------|------| +| **Site vitrine** | Présentation de la plateforme, point d'accès de connexion | +| **Portail étudiant** | Liste des examens, passage des épreuves, soumission, consultation des notes | +| **Back-office admin** | Gestion de la banque de questions, gestion des examens, enregistrement des soumissions, statistiques des résultats | + +Le backend utilise Express et doit prendre en charge : l'authentification, la gestion des rôles et permissions, la gestion des examens et de la banque de questions, le processus de soumission et la notation automatique, ainsi que la gestion des notes et des statistiques. + +::: tip Accès au PRD +Le document d'exigences de ce projet se trouve sur GitHub : [Voir le PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/fr-fr/stage-2/assignments/exam-management-express/PRD.md) +::: + +
+ + + +
+ +## Partie 1 : Analyse des besoins + +### 1.1 Lire le PRD + +Ouvrez le document PRD et répondez aux questions suivantes : + +- Quels rôles le système comprend-il ? Que peuvent-ils faire respectivement ? +- La liste des pages est-elle complète ? Quelles pages le portail étudiant et le back-office admin comportent-ils ? +- Quels types de questions sont pris en charge ? Quelle est la logique de notation pour chaque type ? +- Quel est le flux complet d'un examen ? (Publication -> Démarrage -> Réponse -> Soumission -> Notation -> Consultation des résultats) + +::: warning +Si les questions ci-dessus n'ont pas de réponse claire, ne commencez pas à coder. Une mauvaise compréhension des besoins est la cause la plus fréquente de retour en arrière. +::: + +### 1.2 Confirmer l'architecture du système + +À partir du PRD, dégagez l'architecture globale du système : + +```mermaid +flowchart TD + prd["PRD"] --> web["Site vitrine"] + prd --> student["Portail étudiant"] + prd --> admin["Back-office admin"] + student --> auth["Authentification"] + student --> exam["Examens et réponses"] + exam --> db["Base de données"] + admin --> question["Gestion de la banque de questions"] + admin --> submission["Enregistrement des soumissions et statistiques"] + question --> db + submission --> db +``` + +## Partie 2 : Construction du squelette du projet + +### 2.1 Générer les pages frontales + +Prompt de référence : + +```text +Veuillez générer, sur la base du PRD actuel, le squelette frontend d'un système de gestion d'examens en ligne. + +Stack technique requise : +- Next.js App Router +- TypeScript +- Tailwind CSS +- shadcn/ui + +Liste des pages : +1. Page d'accueil / +2. Page de connexion /login +3. Liste des examens (étudiant) /student/exams +4. Page de passage d'examen /student/exams/[id] +5. Page des résultats (étudiant) /student/history +6. Accueil du back-office admin /admin +7. Gestion des examens /admin/exams +8. Gestion de la banque de questions /admin/questions +9. Enregistrement des soumissions /admin/submissions + +Exigences : +- Les pages étudiant doivent être claires, concentrées et faciles à utiliser +- Les pages admin doivent utiliser une mise en page avec barre latérale + barre supérieure +- Utiliser d'abord des données mock, sans connexion à une API réelle +- Assurer une utilisation de base correcte sur desktop et mobile +``` + +### 2.2 Améliorer la page de passage d'examen + +La page de passage d'examen est la page centrale du portail étudiant. À améliorer en priorité : + +```text +Veuillez continuer à améliorer la page de passage d'examen. + +Il s'agit de la page de passage d'un examen en ligne, elle doit contenir : +- En haut : titre de l'examen, compte à rebours, nombre de questions déjà répondues +- Au centre : énoncé de la question et options +- Prise en charge de trois types de questions : choix unique, vrai/faux, réponse courte +- À gauche ou en haut : cartographie des réponses, indiquant si chaque question a été répondue +- Avant la soumission, afficher une boîte de confirmation + +Implémenter d'abord les interactions avec des données mock, sans connexion à une API réelle. + +Exigences : +- Interface épurée, ne pas ressembler à une page de back-office +- Le compte à rebours doit être visible sans être trop oppressant +- Prévoir un état vide et un état de chargement +``` + +### 2.3 Améliorer le back-office administrateur + +La première version du back-office admin se concentre sur trois zones principales : + +- **Gestion des examens** : Créer un examen, définir la durée, gérer le statut de publication +- **Gestion de la banque de questions** : Ajouter des questions, modifier des questions, filtrer par type +- **Enregistrement des soumissions** : Voir les soumissions des étudiants, les scores, les durées + +### 2.4 Vérifier la structure des pages + +Vérifiez point par point : + +- [ ] Les points d'accès du portail étudiant et du back-office admin sont-ils séparés ? +- [ ] La page de connexion, la liste des examens, la page de passage d'examen et la page des résultats sont-elles complètes ? +- [ ] Les pages de gestion de la banque de questions, des examens et des enregistrements de soumission du back-office sont-elles accessibles ? +- [ ] Le style visuel des pages étudiant et admin est-il clairement différencié ? + +### Vous êtes bloqué ? + +Si vous êtes bloqué lors de la construction du frontend, vous pouvez consulter ces chapitres : + +- [Des bases de données à Supabase](../../backend/database-supabase/) +- [Écriture de code d'interface assistée par IA](../../backend/ai-interface-code/) +- [Mettre à jour votre interface avec une bibliothèque de composants moderne](../../frontend/modern-component-library/) + +## Partie 3 : Développement backend + +### 3.1 Connexion et contrôle des permissions + +```text +Considérez que je suis débutant et aidez-moi à mettre en place la connexion et le contrôle des permissions du système d'examens en ligne. + +Le backend utilise Express. + +Objectifs : +1. Les étudiants et les administrateurs peuvent tous les deux se connecter +2. Après connexion, le rôle de l'utilisateur est renvoyé +3. Les étudiants ne peuvent accéder qu'aux routes /student/* +4. Les administrateurs ne peuvent accéder qu'aux routes /admin/* +5. Les utilisateurs non connectés sont redirigés vers /login lorsqu'ils accèdent à une page protégée + +Exigences d'implémentation : +- Proposer une structure de répertoire claire +- Expliquer clairement la responsabilité du middleware +- Ne pas coder en dur les variables d'environnement +- Après implémentation, expliquer comment vérifier que les permissions fonctionnent +``` + +### 3.2 API de gestion des examens et de la banque de questions + +Il est recommandé d'implémenter les modules suivants : + +| Module | API recommandées | +|------|----------| +| Gestion des examens | `GET /api/exams`, `POST /api/admin/exams`, `PATCH /api/admin/exams/:id` | +| Gestion de la banque de questions | `GET /api/admin/questions`, `POST /api/admin/questions` | +| Démarrer un examen | `POST /api/submissions/start` | +| Soumettre une copie | `POST /api/submissions/:id/submit` | +| Enregistrement des résultats | `GET /api/student/history`, `GET /api/admin/submissions` | + +Prompt de référence : + +```text +Veuillez concevoir et implémenter l'API Express pour le système d'examens en ligne. + +Périmètre fonctionnel : +- L'administrateur crée des examens +- L'administrateur gère la banque de questions +- L'étudiant consulte les examens publiés +- L'étudiant commence un examen et crée une soumission +- L'étudiant soumet ses réponses et la notation automatique est effectuée pour les QCM et les questions vrai/faux +- Les questions à réponse courte sont d'abord marquées comme en attente de révision +- L'étudiant consulte ses résultats historiques +- L'administrateur consulte tous les enregistrements de soumission + +Exigences : +- Nommage clair des API +- Retourner une structure JSON unifiée +- Séparer clairement les couches controller, service, middleware et db dans le code +- Expliquer comment tester chaque API +``` + +### 3.3 Logique de notation + +La logique de notation est la règle métier essentielle du système d'examens : + +- **Questions à choix unique** : La réponse de l'utilisateur est correcte si elle correspond à la réponse attendue +- **Questions vrai/faux** : La notation automatique est également possible +- **Questions à réponse courte** : Dans la première version, seule la réponse est enregistrée, le score est vide, et le statut est `reviewed = false` + +::: tip Bonus +Si vous souhaitez ajouter des capacités IA, vous pouvez permettre à l'administrateur de saisir un "thème + niveau de difficulté" dans le back-office, puis laisser le modèle générer d'abord un ensemble de questions candidates, qui seront ensuite validées manuellement avant d'être intégrées à la banque. Il s'agit cependant d'un bonus, pas d'une obligation. +::: + +## Partie 4 : Tests et mise en ligne + +### 4.1 Tests de bout en bout + +Vérifiez au minimum les scénarios suivants : + +- Étudiant : connexion -> consultation de la liste des examens -> démarrage d'un examen -> soumission -> consultation des résultats +- Administrateur : connexion -> création d'un examen -> ajout de questions -> publication -> consultation des enregistrements de soumission + +### 4.2 Déploiement + +- Déployer le frontend sur Vercel / Zeabur +- Déployer l'API Express sur Zeabur / Railway / Render +- Utiliser Supabase Postgres ou un PostgreSQL hébergé comme base de données + +Vérifications avant déploiement : + +- [ ] Les variables d'environnement sont-elles toutes configurées ? +- [ ] Les adresses API frontend/backend sont-elles correctes ? +- [ ] L'état de connexion fonctionne-t-il correctement en production ? +- [ ] Le compte administrateur peut-il réellement accéder au back-office ? +- [ ] Le README contient-il les instructions de démarrage, de déploiement et de test ? + +## Livrables + +Après avoir terminé ce projet, vous devez soumettre les éléments suivants : + +- [ ] Un lien de démonstration en ligne accessible +- [ ] Un lien vers le dépôt de code source (avec README) +- [ ] Le document PRD +- [ ] Des captures d'écran des pages principales (accueil, liste des examens étudiant, page de passage d'examen, back-office admin) +- [ ] Une vidéo de démonstration de 60 secondes (couvrant le flux de réponse de l'étudiant et le flux de gestion de l'administrateur) + +Le README doit contenir au minimum : la présentation du projet, la description des pages principales, la stack technique, les étapes de démarrage local et la liste des variables d'environnement. + +## Critères d'évaluation + +| Dimension | Exigences de base | Exigences avancées | +|------|---------|---------| +| Complétude des pages | Les pages principales du portail étudiant et du back-office admin sont accessibles | Le style des pages est cohérent et l'utilisation mobile est correcte | +| Boucle métier | L'étudiant peut se connecter, passer un examen, soumettre et voir ses résultats | L'administrateur peut créer et publier un examen de bout en bout | +| Exactitude des données | Les réponses soumises sont écrites dans la base de données et les questions objectives sont notées automatiquement | Les questions à réponse courte prennent en charge la révision manuelle ou l'assistance IA | +| Contrôle des permissions | La séparation des accès entre étudiants et administrateurs est claire | Les API côté serveur ont également une vérification des rôles | +| Livraison technique | Le projet peut être exécuté, déployé et le README est clair | Il y a une vidéo de démonstration et des instructions de test | + +## Vérification avant soumission + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## Références + +- [Conception UI](../../frontend/ui-design/) +- [Mettre à jour votre interface avec une bibliothèque de composants moderne](../../frontend/modern-component-library/) +- [Des bases de données à Supabase](../../backend/database-supabase/) +- [Écriture de code d'interface assistée par IA](../../backend/ai-interface-code/) +- [Flux de travail Git et GitHub](../../backend/git-workflow/) +- [Comment déployer une application web](../../backend/zeabur-deployment/) diff --git a/docs/fr-fr/stage-2/assignments/modern-landing-page/index.md b/docs/fr-fr/stage-2/assignments/modern-landing-page/index.md new file mode 100644 index 0000000..4d63361 --- /dev/null +++ b/docs/fr-fr/stage-2/assignments/modern-landing-page/index.md @@ -0,0 +1,211 @@ +# Développement pratique d'une SaaS de génération d'images IA moderne + +## Aperçu + +Ce projet pratique vous demande de réaliser, à partir d'un véritable PRD (document d'exigences produit), une SaaS de génération d'images IA inspirée de l'expérience Midjourney. Vous passerez par l'ensemble du processus : analyse des besoins, décomposition du projet, développement itératif et mise en ligne. + +Il s'agit du projet pratique synthétique de l'Étape 2. Dans les chapitres précédents, vous avez appris séparément la conception de pages frontend, le développement d'API backend, les opérations sur les bases de données et l'intégration de paiements. Ce projet vous demande de tout assembler pour livrer un prototype de produit fonctionnel. + +## Prérequis + +Avant de commencer ce projet, vous devriez maîtriser les éléments suivants : + +- Conception de pages frontales et utilisation de bibliothèques de composants ([Conception UI](../../frontend/ui-design/), [Bibliothèque de composants moderne](../../frontend/modern-component-library/)) +- Conception et développement d'API backend ([Écriture de code d'interface](../../backend/ai-interface-code/)) +- Bases de données et Supabase ([Des bases de données à Supabase](../../backend/database-supabase/)) +- Intégration de paiements ([Système de paiement Stripe](../../backend/stripe-payment/)) +- Flux de travail Git et déploiement ([Git et GitHub](../../backend/git-workflow/), [Déployer une application web](../../backend/zeabur-deployment/)) + +## Objectifs d'apprentissage + +Après avoir terminé ce projet, vous serez capable de : + +1. Lire et comprendre un véritable PRD et en extraire une liste de tâches de développement +2. Décomposer les modules à partir du PRD et établir un plan de progression par étapes +3. Utiliser l'IA pour vous aider à construire le squelette frontend et développer les API backend +4. Valider et optimiser de manière itérative chaque module +5. Effectuer des tests de bout en bout et faire passer le projet du stade « fonctionnel » à « livrable » + +## Présentation du projet + +Le produit que vous allez construire est une plateforme SaaS de génération d'images IA moderne, comprenant trois sous-systèmes : + +| Sous-système | Responsabilité | +|--------|------| +| **Site vitrine** | Présentation du produit, tarification, FAQ, conversion des inscriptions | +| **Espace de travail utilisateur** | Saisie de prompts, génération d'images, galerie, crédits, forfaits, interactions communautaires | +| **Back-office administrateur** | Gestion des utilisateurs, des tâches, des paiements, modération du contenu, indicateurs SaaS, surveillance système | + +Le backend doit prendre en charge les capacités principales suivantes : authentification des utilisateurs, tâches de génération d'images, stockage objet OSS, paiement par crédits et forfaits, interactions sociales autour des images et surveillance des données opérationnelles. + +::: tip Accès au PRD +Le document d'exigences de ce projet se trouve sur GitHub : [Voir le PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/fr-fr/stage-2/assignments/modern-landing-page/PRD.md) +::: + +
+ + + +
+ +## Partie 1 : Analyse des besoins + +### 1.1 Lire le PRD + +Ouvrez le document PRD et répondez aux questions suivantes : + +- Combien le système a-t-il de points d'accès ? Quelles pages chaque point couvre-t-il ? +- Quelle est la fonctionnalité principale de chaque page ? +- Quels modules et tables de données le backend comprend-il ? +- Quelle est la portée du MVP ? Que fait-on dans la première version, que laisse-t-on de côté ? + +::: warning +Si les questions ci-dessus n'ont pas de réponse claire, ne commencez pas à coder. Une mauvaise compréhension des besoins est la cause la plus fréquente de retour en arrière. +::: + +### 1.2 Confirmer l'architecture du système + +À partir de la description du PRD, dégagez l'architecture globale du système : + +```mermaid +flowchart TD + prd["PRD"] --> web["Site vitrine"] + prd --> app["Espace de travail utilisateur"] + prd --> admin["Back-office administrateur"] + app --> auth["Authentification"] + app --> gen["Tâches de génération d'images"] + gen --> oss["Stockage objet OSS"] + gen --> db["Base de données"] + billing["Paiement et forfaits"] --> db + social["Partage / Likes / Commentaires / Reposts"] --> db + admin --> analytics["Tableau de bord des indicateurs SaaS"] + admin --> observability["Surveillance API / DB / Provider"] +``` + +Il est recommandé de redessiner le diagramme d'architecture vous-même pour confirmer que votre compréhension du système est complète. + +## Partie 2 : Construction du squelette du projet + +### 2.1 Générer les pages frontales + +Utilisez l'IA pour générer d'abord la structure de base et les données fictives de toutes les pages. L'objectif de cette étape est de mettre en place l'architecture de l'information et le routage, sans connexion à une API réelle. + +Prompt de référence : + +```text +Veuillez générer, sur la base du PRD actuel, le squelette frontend d'une SaaS de génération d'images IA moderne. + +Exigences : +1. Divisé en trois points d'accès : www, app, admin +2. Le site vitrine comprend : page d'accueil, tarification, FAQ +3. L'app comprend : connexion, inscription, espace de génération, galerie, forfaits, crédits, communauté, détails des œuvres, profil utilisateur +4. L'admin comprend : accueil du back-office, gestion des utilisateurs, gestion des tâches, gestion du contenu, gestion des forfaits, commandes de paiement, configuration opérationnelle, indicateurs SaaS, surveillance système +5. Générer d'abord uniquement la structure des pages et des données fictives, sans connexion à une API réelle +6. Style inspiré de Midjourney : épuré, moderne, avec une sensation produit +``` + +### 2.2 Vérifier la structure des pages + +Après la génération du squelette, vérifiez point par point : + +- [ ] Les routes des trois points d'accès sont-elles indépendantes (`/`, `/app`, `/admin`) ? +- [ ] Le nombre de pages correspond-il au PRD ? +- [ ] Chaque page est-elle accessible et navigable normalement ? +- [ ] Les données fictives montrent-elles les états UI de base (listes, états vides, formulaires, etc.) ? + +## Partie 3 : Développement itératif + +### 3.1 Progresser par module + +Sur la base du squelette, complétez les fonctionnalités module par module dans l'ordre suivant : + +1. **Authentification** : Inscription, connexion, distinction des rôles +2. **Base de données** : Création des tables de données, API de lecture/écriture +3. **Cœur du métier** : Tâches de génération d'images, stockage des résultats +4. **Stockage OSS** : Upload et accès aux images +5. **Paiement** : Forfaits, crédits, intégration Stripe +6. **Interactions sociales** : Partage, likes, commentaires +7. **Back-office** : Gestion des utilisateurs, des tâches, modération du contenu +8. **Surveillance des données** : Tableau de bord des indicateurs SaaS, surveillance système + +Après chaque module terminé, effectuez une auto-vérification à l'aide du tableau suivant : + +| Point de contrôle | Méthode de vérification | +|--------|----------| +| Cohérence des pages | Le nombre de pages, les points d'accès et les fonctionnalités correspondent-ils au PRD ? | +| Exactitude des API | Les paramètres de requête, la structure de retour et la gestion des statuts sont-ils raisonnables ? | +| Isolation des permissions | Les utilisateurs normaux et les administrateurs sont-ils correctement isolés ? | +| Cohérence des données | La base de données, le stockage OSS, les paiements et les crédits sont-ils cohérents ? | +| Démontrabilité | Pouvez-vous démontrer un flux métier complet à quelqu'un ? | + +::: tip +Si vous constatez que le contenu généré par l'IA s'écarte du PRD, ne repartez pas de zéro pour toute la page. Demandez-lui simplement de modifier le module spécifique concerné. +::: + +### 3.2 Rôles et responsabilités + +Au cours du développement itératif, vous devez jouer trois rôles simultanément : + +- **Chef de produit** : Confirmer que les fonctionnalités de chaque module correspondent au PRD +- **Responsable technique** : Confirmer que la solution d'implémentation est raisonnable +- **Ingénieur de test** : Confirmer que les fonctionnalités fonctionnent correctement + +## Partie 4 : Tests et mise en ligne + +### 4.1 Tests de bout en bout + +L'accent dans la phase finale n'est pas sur l'ajout de nouvelles pages, mais sur la validation complète des flux métier. Vérifiez au minimum les scénarios suivants : + +- Inscription -> Achat de crédits -> Génération d'images -> Consultation de l'historique -> Interactions sociales +- Connexion administrateur -> Consultation des données utilisateurs -> Consultation des statistiques de tâches -> Consultation de la surveillance système + +### 4.2 Déploiement + +Déployez le projet dans un environnement public et assurez-vous que : + +- Les variables d'environnement sont entièrement configurées +- L'URL de callback de connexion est correcte +- L'URL de callback de paiement est correcte +- Aucune page ne présente d'états de chargement, vides ou d'erreurs manquants + +Tutoriel de déploiement : [Flux de travail Git et GitHub](../../backend/git-workflow/), [Comment déployer une application web](../../backend/zeabur-deployment/). + +## Livrables + +Après avoir terminé ce projet, vous devez soumettre les éléments suivants : + +- [ ] Un lien de démonstration en ligne accessible +- [ ] Un lien vers le dépôt de code source (avec README) +- [ ] Le document PRD +- [ ] Des captures d'écran des pages principales (accueil du site vitrine, espace de génération, galerie, page des forfaits, accueil du back-office) +- [ ] Une vidéo de démonstration de 60 secondes (couvrant : inscription -> génération -> consultation -> back-office admin) + +Le README doit contenir au minimum : la présentation du projet, la description des pages principales, la stack technique, les étapes de démarrage local et la liste des variables d'environnement. + +## Critères d'évaluation + +| Dimension | Exigences de base | Exigences avancées | +|------|---------|---------| +| Alignement PRD | Pages, fonctionnalités et structures de données globalement conformes au PRD | Chaque décision de design peut être clairement reliée au PRD | +| Boucle produit | Inscription -> Achat de crédits -> Génération d'images -> Historique -> Interactions sociales fonctionne | État des paiements, solde des crédits et nombre de générations sont cohérents | +| Capacités du back-office | Gestion des utilisateurs, des tâches, des paiements et du contenu est visible | Le tableau de bord des indicateurs SaaS et la page de surveillance système sont complets et fonctionnels | +| Complétude technique | Frontend, backend, base de données, OSS et chaîne de paiement sont connectés | Gestion des erreurs, états vides et états de chargement sont présents | +| Qualité de livraison | Peut être déployé et exécuté | README clair, vidéo de démonstration bien structurée | + +## Références + +- [Conception UI](../../frontend/ui-design/) +- [Concevoir des pages et des boutons en référençant les guidelines UI](../../frontend/multi-product-ui/) +- [Rendre les interfaces attrayantes avec les LLM et les Skills](../../frontend/llm-skills-beautiful/) +- [Du prototype de design au code de projet](../../frontend/design-to-code/) +- [Mettre à jour votre interface avec une bibliothèque de composants moderne](../../frontend/modern-component-library/) +- [Des bases de données à Supabase](../../backend/database-supabase/) +- [Écriture de code d'interface assistée par IA](../../backend/ai-interface-code/) +- [Flux de travail Git et GitHub](../../backend/git-workflow/) +- [Comment déployer une application web](../../backend/zeabur-deployment/) +- [Comment intégrer Stripe et d'autres systèmes de paiement](../../backend/stripe-payment/) diff --git a/docs/fr-fr/stage-2/assignments/movie-recommendation-springboot/index.md b/docs/fr-fr/stage-2/assignments/movie-recommendation-springboot/index.md new file mode 100644 index 0000000..1ddb6d8 --- /dev/null +++ b/docs/fr-fr/stage-2/assignments/movie-recommendation-springboot/index.md @@ -0,0 +1,151 @@ +# Développement pratique d'un système de recommandation de films avec Spring Boot + +## Aperçu + +Ce projet pratique vous demande de réaliser, à partir d'un véritable PRD, un site web de films avec capacités de recommandation en utilisant Spring Boot. Le défi principal de ce projet est qu'il ne s'agit pas d'un simple CRUD, mais qu'il vous amène à réfléchir à la manière dont les comportements des utilisateurs influencent les résultats de recommandation et à rendre ces recommandations explicables. + +Il s'agit du projet pratique synthétique de l'Étape 2. Vous découvrirez pour la première fois le modèle de développement de produits de type « contenu + comportement + recommandation », très courant dans le e-commerce, les plateformes de contenu et les flux personnalisés. + +## Prérequis + +Avant de commencer ce projet, vous devriez maîtriser les éléments suivants : + +- Conception de pages frontales et utilisation de bibliothèques de composants ([Conception UI](../../frontend/ui-design/), [Bibliothèque de composants moderne](../../frontend/modern-component-library/)) +- Conception et développement d'API backend ([Écriture de code d'interface](../../backend/ai-interface-code/)) +- Bases de données et Supabase ([Des bases de données à Supabase](../../backend/database-supabase/)) +- Flux de travail Git et déploiement ([Git et GitHub](../../backend/git-workflow/), [Déployer une application web](../../backend/zeabur-deployment/)) + +## Objectifs d'apprentissage + +Après avoir terminé ce projet, vous serez capable de : + +1. Lire un PRD et en extraire une liste de tâches de développement pour un système de recommandation +2. Utiliser Spring Boot pour mettre en place un projet backend et implémenter des API RESTful +3. Concevoir le flux de données complet « comportement utilisateur -> recommandation » +4. Implémenter une logique de recommandation explicable +5. Effectuer des tests de bout en bout et livrer un prototype de produit démontrable + +## Présentation du projet + +Le produit que vous allez construire est un site web de films avec capacités de recommandation : + +| Fonctionnalité | Description | +|------|------| +| **Navigation et recherche** | Les utilisateurs peuvent parcourir et rechercher des films | +| **Notes et favoris** | Les utilisateurs peuvent noter des films et les ajouter aux favoris | +| **Recommandations personnalisées** | Le système génère des recommandations basées sur le comportement des utilisateurs | +| **Back-office** | Les administrateurs gèrent les données des films et consultent l'efficacité des recommandations | + +::: tip Accès au PRD +Le document d'exigences de ce projet se trouve sur GitHub : [Voir le PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/fr-fr/stage-2/assignments/movie-recommendation-springboot/PRD.md) +::: + +
+ + + +
+ +## Partie 1 : Analyse des besoins + +### 1.1 Lire le PRD + +Ouvrez le document PRD et répondez aux questions suivantes : + +- Quels comportements utilisateur sont suivis (notes, favoris, historique de visualisation) ? +- Quelle est la stratégie de recommandation (filtrage collaboratif, basée sur le contenu, hybride) ? +- Comment les recommandations sont-elles rendues explicables pour l'utilisateur ? +- Quelles sont les fonctionnalités du MVP ? + +::: warning +Si les questions ci-dessus n'ont pas de réponse claire, ne commencez pas à coder. Une mauvaise compréhension des besoins est la cause la plus fréquente de retour en arrière. +::: + +## Partie 2 : Construction du squelette du projet + +### 2.1 Générer les pages frontales + +Prompt de référence : + +```text +Veuillez générer, sur la base du PRD actuel, le squelette frontend d'un site web de films avec système de recommandation. + +Exigences : +1. Page d'accueil avec films populaires et recommandations personnalisées +2. Page de liste de films avec recherche et filtrage +3. Page de détail d'un film avec notes et avis +4. Page de profil avec favoris et historique +5. Back-office pour la gestion des films et le suivi des recommandations +6. Générer d'abord uniquement la structure des pages et des données fictives +``` + +### 2.2 Vérifier la structure des pages + +- [ ] La page d'accueil affiche-t-elle les recommandations ? +- [ ] La page de détail permet-elle de noter et d'ajouter aux favoris ? +- [ ] Le back-office permet-il la gestion des films ? + +## Partie 3 : Développement itératif + +### 3.1 Progresser par module + +1. **Gestion des films** : CRUD des films, recherche et filtrage +2. **Notes et favoris** : Les utilisateurs peuvent noter et sauvegarder des films +3. **Suivi des comportements** : Enregistrement des notes, favoris et historique de navigation +4. **Logique de recommandation** : Algorithme de recommandation basé sur les comportements +5. **Explicabilité** : Afficher pourquoi un film est recommandé (ex: « Recommandé car vous avez aimé X ») +6. **Back-office** : Gestion des films et suivi de l'efficacité des recommandations + +### 3.2 Modèle de données de référence + +Tables principales : + +- `movies` : id, title, genre, description, release_year, rating_avg +- `user_ratings` : id, user_id, movie_id, rating, created_at +- `user_favorites` : id, user_id, movie_id, created_at +- `user_views` : id, user_id, movie_id, viewed_at +- `recommendations` : id, user_id, movie_id, reason, score, created_at + +## Partie 4 : Tests et mise en ligne + +### 4.1 Tests de bout en bout + +- Parcourir les films -> Noter un film -> Voir les recommandations mises à jour +- Ajouter aux favoris -> Vérifier que les recommandations en tiennent compte + +### 4.2 Déploiement + +- Déployer le frontend sur Vercel / Zeabur +- Déployer le backend Spring Boot sur Zeabur / Railway / Render +- Utiliser Supabase ou PostgreSQL comme base de données + +## Livrables + +- [ ] Un lien de démonstration en ligne accessible +- [ ] Un lien vers le dépôt de code source (avec README) +- [ ] Le document PRD +- [ ] Des captures d'écran des pages principales +- [ ] Une vidéo de démonstration de 60 secondes + +## Critères d'évaluation + +| Dimension | Exigences de base | Exigences avancées | +|------|---------|---------| +| Films | Navigation, recherche, détails fonctionnent | Les notes et favoris sont sauvegardés | +| Recommandation | Des recommandations sont affichées | Elles sont basées sur le comportement et sont explicables | +| Technique | Spring Boot fonctionne avec la base de données | Gestion des erreurs et optimisation des performances | +| Livraison | Le projet peut être exécuté et déployé | README clair et vidéo de démonstration | + +## Références + +- [Conception UI](../../frontend/ui-design/) +- [Bibliothèque de composants moderne](../../frontend/modern-component-library/) +- [Des bases de données à Supabase](../../backend/database-supabase/) +- [Écriture de code d'interface assistée par IA](../../backend/ai-interface-code/) +- [Flux de travail Git et GitHub](../../backend/git-workflow/) +- [Comment déployer une application web](../../backend/zeabur-deployment/) diff --git a/docs/fr-fr/stage-2/assignments/simple-grocery-microservices/index.md b/docs/fr-fr/stage-2/assignments/simple-grocery-microservices/index.md new file mode 100644 index 0000000..19f22b6 --- /dev/null +++ b/docs/fr-fr/stage-2/assignments/simple-grocery-microservices/index.md @@ -0,0 +1,166 @@ +# Développement pratique d'un système de microservices pour l'e-commerce de produits frais + +## Aperçu + +Ce projet pratique vous demande de réaliser, à partir d'un véritable PRD, un système de microservices pour l'e-commerce de produits frais. Contrairement aux projets précédents basés sur un seul service, le backend de ce projet est découpé en plusieurs services indépendants selon le domaine métier, communiquant via une passerelle API unifiée. Vous apprendrez à concevoir les limites des services et à gérer la cohérence des données entre services. + +Il s'agit du projet pratique synthétique de l'Étape 2. L'architecture microservices est très courante en milieu professionnel. Une fois les principes de découpage des services et de routage par passerelle maîtrisés, vous serez en mesure de concevoir des systèmes backend plus complexes. + +## Prérequis + +Avant de commencer ce projet, vous devriez maîtriser les éléments suivants : + +- Conception de pages frontales et utilisation de bibliothèques de composants ([Conception UI](../../frontend/ui-design/), [Bibliothèque de composants moderne](../../frontend/modern-component-library/)) +- Conception et développement d'API backend ([Écriture de code d'interface](../../backend/ai-interface-code/)) +- Bases de données et Supabase ([Des bases de données à Supabase](../../backend/database-supabase/)) +- Flux de travail Git et déploiement ([Git et GitHub](../../backend/git-workflow/), [Déployer une application web](../../backend/zeabur-deployment/)) + +## Objectifs d'apprentissage + +Après avoir terminé ce projet, vous serez capable de : + +1. Lire un PRD et en extraire une liste de tâches de développement pour un système de microservices +2. Découper les limites des services par domaine métier (authentification, catalogue, inventaire, commandes) +3. Concevoir et implémenter le routage d'une passerelle API +4. Gérer les problèmes inter-services tels que la décrémentation de stock et la cohérence des commandes +5. Effectuer des tests de bout en bout et livrer un prototype de microservices démontrable + +## Présentation du projet + +Le produit que vous allez construire est un système de microservices pour l'e-commerce de produits frais : + +| Sous-système | Responsabilité | +|--------|------| +| **Portail client** | Parcourir les produits, passer des commandes, consulter les commandes | +| **Portail gestion** | Gestion des produits, gestion des stocks, gestion des commandes | + +Le backend est découpé en services par domaine métier : + +| Service | Responsabilité | +|------|------| +| **Passerelle API** | Point d'entrée unique, routage, validation de l'authentification | +| **Service d'authentification** | Inscription, connexion, émission de JWT | +| **Service catalogue** | Gestion des informations produits | +| **Service inventaire** | Gestion des quantités en stock | +| **Service de commandes** | Création et gestion du statut des commandes | + +::: tip Accès au PRD +Le document d'exigences de ce projet se trouve sur GitHub : [Voir le PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/fr-fr/stage-2/assignments/simple-grocery-microservices/PRD.md) +::: + +
+ + + +
+ +## Partie 1 : Analyse des besoins + +### 1.1 Lire le PRD + +Ouvrez le document PRD et répondez aux questions suivantes : + +- Comment les services sont-ils découpés ? Chaque service a-t-il sa propre base de données ? +- Comment la passerelle API route-t-elle les requêtes vers les services concernés ? +- Comment gérer la cohérence entre la décrémentation de stock et la création de commande ? +- Quelles sont les fonctionnalités du MVP ? + +::: warning +Si les questions ci-dessus n'ont pas de réponse claire, ne commencez pas à coder. Une mauvaise compréhension des besoins est la cause la plus fréquente de retour en arrière. +::: + +### 1.2 Confirmer l'architecture du système + +```mermaid +flowchart TD + client["Client"] --> gateway["Passerelle API"] + gateway --> auth["Service d'authentification"] + gateway --> catalog["Service catalogue"] + gateway --> inventory["Service inventaire"] + gateway --> order["Service de commandes"] + catalog --> db1["DB Catalogue"] + inventory --> db2["DB Inventaire"] + order --> db3["DB Commandes"] + auth --> db4["DB Auth"] +``` + +## Partie 2 : Construction du squelette du projet + +### 2.1 Générer les pages frontales + +Prompt de référence : + +```text +Veuillez générer, sur la base du PRD actuel, le squelette frontend d'un système e-commerce de produits frais. + +Exigences : +1. Portail client : liste des produits, panier, page de commande, historique des commandes +2. Portail gestion : gestion des produits, gestion des stocks, gestion des commandes +3. Générer d'abord uniquement la structure des pages et des données fictives +``` + +### 2.2 Vérifier la structure des pages + +- [ ] Le portail client et le portail gestion sont-ils séparés ? +- [ ] La liste des produits, le panier et les commandes fonctionnent-ils ? +- [ ] Le portail gestion permet-il de gérer les produits et les stocks ? + +## Partie 3 : Développement itératif + +### 3.1 Progresser par service + +1. **Passerelle API** : Routage des requêtes, validation JWT +2. **Service d'authentification** : Inscription, connexion, émission de tokens +3. **Service catalogue** : CRUD des produits, recherche +4. **Service inventaire** : Suivi des stocks, décrémentation lors des commandes +5. **Service de commandes** : Création de commandes, suivi du statut, historique + +### 3.2 Points d'attention inter-services + +- **Cohérence des stocks** : Lorsqu'une commande est créée, le stock doit être décrémenté de manière fiable +- **Communication entre services** : Utiliser des appels API synchrones ou des événements asynchrones +- **Gestion des erreurs** : Que se passe-t-il si le service d'inventaire est indisponible lors d'une commande ? + +## Partie 4 : Tests et mise en ligne + +### 4.1 Tests de bout en bout + +- Parcourir les produits -> Ajouter au panier -> Commander -> Vérifier la mise à jour du stock +- Gestion : Ajouter un produit -> Vérifier qu'il apparaît côté client + +### 4.2 Déploiement + +- Déployer chaque service indépendamment sur Zeabur / Railway / Render +- Configurer la passerelle API pour router vers les services déployés +- Utiliser des bases de données séparées ou Supabase avec des schémas distincts + +## Livrables + +- [ ] Un lien de démonstration en ligne accessible +- [ ] Un lien vers le dépôt de code source (avec README) +- [ ] Le document PRD +- [ ] Des captures d'écran des pages principales +- [ ] Une vidéo de démonstration de 60 secondes + +## Critères d'évaluation + +| Dimension | Exigences de base | Exigences avancées | +|------|---------|---------| +| Services | L'authentification et le catalogue fonctionnent | L'inventaire et les commandes sont connectés | +| Passerelle | Les requêtes sont correctement routées | La validation JWT est opérationnelle | +| Technique | Chaque service peut être démarré indépendamment | La cohérence inter-services est gérée | +| Livraison | Le projet peut être exécuté et déployé | README clair et vidéo de démonstration | + +## Références + +- [Conception UI](../../frontend/ui-design/) +- [Bibliothèque de composants moderne](../../frontend/modern-component-library/) +- [Des bases de données à Supabase](../../backend/database-supabase/) +- [Écriture de code d'interface assistée par IA](../../backend/ai-interface-code/) +- [Flux de travail Git et GitHub](../../backend/git-workflow/) +- [Comment déployer une application web](../../backend/zeabur-deployment/) diff --git a/docs/fr-fr/stage-2/assignments/traffic-data-visualization-go/index.md b/docs/fr-fr/stage-2/assignments/traffic-data-visualization-go/index.md new file mode 100644 index 0000000..e8e1ec6 --- /dev/null +++ b/docs/fr-fr/stage-2/assignments/traffic-data-visualization-go/index.md @@ -0,0 +1,163 @@ +# Développement pratique d'une plateforme d'analyse de données de transport en Go + +## Aperçu + +Ce projet pratique vous demande de réaliser, à partir d'un véritable PRD, une plateforme d'analyse de données de transport en utilisant Go. Contrairement aux projets précédents de type CRUD, vous allez construire une chaîne de données complète : « ingestion de données → agrégation → alertes → visualisation ». Ce type de produit de données est très courant dans les scénarios IoT, la supervision et l'analyse opérationnelle. + +Il s'agit du projet pratique synthétique de l'Étape 2, et c'est également votre premier contact avec le langage Go. Rassurez-vous, avec les bases en JavaScript / TypeScript acquises précédemment, l'apprentissage de Go n'est pas difficile — l'essentiel est de comprendre la logique de conception de la chaîne de données. + +## Prérequis + +Avant de commencer ce projet, vous devriez maîtriser les éléments suivants : + +- Conception de pages frontales et utilisation de bibliothèques de composants ([Conception UI](../../frontend/ui-design/), [Bibliothèque de composants moderne](../../frontend/modern-component-library/)) +- Conception et développement d'API backend ([Écriture de code d'interface](../../backend/ai-interface-code/)) +- Bases de données et Supabase ([Des bases de données à Supabase](../../backend/database-supabase/)) +- Flux de travail Git et déploiement ([Git et GitHub](../../backend/git-workflow/), [Déployer une application web](../../backend/zeabur-deployment/)) + +## Objectifs d'apprentissage + +Après avoir terminé ce projet, vous serez capable de : + +1. Lire un PRD et en extraire une liste de tâches de développement pour un produit de données +2. Utiliser Go (Gin ou Fiber) pour mettre en place un service d'API backend +3. Concevoir une chaîne complète d'ingestion de données, d'agrégation par fenêtre temporelle et d'alertes +4. Maintenir la cohérence entre les données backend et le tableau de bord frontend +5. Effectuer des tests de bout en bout et livrer un prototype de produit de données démontrable + +## Présentation du projet + +Le produit que vous allez construire est une plateforme d'analyse de données de transport en Go : + +| Module | Responsabilité | +|------|------| +| **Ingestion de données** | Réceptionner les événements de transport bruts et les stocker en base | +| **Agrégation de données** | Calculer les tendances et indicateurs de congestion par fenêtre temporelle | +| **Alertes** | Générer des enregistrements d'alerte basés sur des règles | +| **Tableau de bord** | Afficher les graphiques de tendances, les classements et la liste des alertes | + +::: tip Accès au PRD +Le document d'exigences de ce projet se trouve sur GitHub : [Voir le PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/fr-fr/stage-2/assignments/traffic-data-visualization-go/PRD.md) +::: + +
+ + + +
+ +## Partie 1 : Analyse des besoins + +### 1.1 Lire le PRD + +Ouvrez le document PRD et répondez aux questions suivantes : + +- Quelle est la source des données ? Quels sont les champs disponibles ? +- Quelle est la définition des indicateurs clés ? (par exemple, le critère exact de « congestion ») +- Quelles sont les règles d'alerte ? Faut-il se limiter à des règles simples dans la première version ? +- Quelles pages et graphiques le tableau de bord doit-il contenir ? + +::: warning +Si les questions ci-dessus n'ont pas de réponse claire, ne commencez pas à coder. Une mauvaise compréhension des besoins est la cause la plus fréquente de retour en arrière. +::: + +### 1.2 Confirmer la chaîne de données + +```mermaid +flowchart TD + prd["PRD"] --> ingest["API d'ingestion de données"] + ingest --> raw["Table de données brutes"] + raw --> agg["Tâches d'agrégation"] + agg --> alert["Règles d'alerte"] + agg --> dashboard["API du tableau de bord"] + alert --> dashboard +``` + +## Partie 2 : Construction du squelette du projet + +### 2.1 Générer le service d'API Go + +Prompt de référence : + +```text +Veuillez générer, sur la base du PRD actuel, le squelette d'une plateforme d'analyse de données de transport en Go. + +Exigences : +1. Utiliser Gin ou Fiber +2. Fournir une API d'ingestion de données +3. Fournir le squelette des tâches d'agrégation +4. Fournir le squelette des API dashboard et alerts +5. Ne pas implémenter d'analyse complexe réelle, se limiter à une structure exécutable +``` + +### 2.2 Vérifier la structure du projet + +Vérifiez point par point : + +- [ ] Le service Go démarre correctement +- [ ] L'API d'ingestion peut recevoir et stocker des données +- [ ] Le framework des tâches d'agrégation est en place +- [ ] Les pages du tableau de bord frontend affichent des graphiques de base + +## Partie 3 : Développement itératif + +### 3.1 Progresser par module + +1. **API d'ingestion de données** : Recevoir les événements de transport bruts et les écrire en base de données +2. **Agrégation de données** : Agréger par fenêtre temporelle, calculer les tendances et indicateurs de congestion +3. **Règles d'alerte** : Générer des enregistrements d'alerte basés sur des seuils +4. **API du tableau de bord** : Fournir les données de tendances, de classement et la liste des alertes +5. **Tableau de bord frontend** : Graphiques de tendances, classements, page de liste des alertes + +### 3.2 Auto-vérification par module + +| Point de contrôle | Méthode de vérification | +|--------|----------| +| Ingestion de données | Les données brutes sont-elles correctement stockées en base | +| Définition des agrégations | La logique de calcul des tendances et classements est-elle cohérente | +| Règles d'alerte | Les conditions de déclenchement correspondent-elles aux attentes | +| Cohérence des données | L'affichage du tableau de bord correspond-il aux données backend | +| Conformité des API | Y a-t-il une structure de retour unifiée et une gestion des erreurs | + +## Partie 4 : Tests et mise en ligne + +### 4.1 Tests de bout en bout + +Vérifiez au minimum les scénarios suivants : + +- Ingestion d'un jeu de données de test → Exécution des tâches d'agrégation → Mise à jour de l'affichage du tableau de bord +- Déclenchement d'une condition d'alerte → Génération d'un enregistrement d'alerte → Affichage sur la page des alertes + +## Livrables + +Après avoir terminé ce projet, vous devez soumettre les éléments suivants : + +- [ ] Un lien de démonstration en ligne accessible +- [ ] Un lien vers le dépôt de code source (avec README) +- [ ] Le document PRD +- [ ] Des captures d'écran des pages principales (démonstration d'ingestion, tableau de bord des tendances, liste des alertes) +- [ ] Une vidéo de démonstration de 60 secondes + +## Critères d'évaluation + +| Dimension | Exigences de base | Exigences avancées | +|------|---------|---------| +| Alignement PRD | Les fonctionnalités et structures de données sont globalement conformes au PRD | Les définitions des indicateurs et la logique d'agrégation sont clairement expliquées | +| Chaîne de données | Ingestion → Agrégation → Alertes → Tableau de bord fonctionnel | Les tâches d'agrégation supportent les mises à jour incrémentales | +| Capacités d'analyse | Les trois modules tendances, classement et alertes sont opérationnels | Les indicateurs sont configurables et les règles d'alerte personnalisables | +| Affichage frontend | Le tableau de bord affiche des graphiques de base | Les graphiques supportent le filtrage par plage de dates | +| Complétude technique | L'API Go, la base de données et la chaîne frontend sont connectées | L'API dispose d'une gestion des erreurs et de journaux unifiés | + +## Références + +- [Conception UI](../../frontend/ui-design/) +- [Bibliothèque de composants moderne](../../frontend/modern-component-library/) +- [Des bases de données à Supabase](../../backend/database-supabase/) +- [Écriture de code d'interface assistée par IA](../../backend/ai-interface-code/) +- [Flux de travail Git et GitHub](../../backend/git-workflow/) +- [Comment déployer une application web](../../backend/zeabur-deployment/) diff --git a/docs/fr-fr/stage-2/assignments/travel-planning-agent-platform/index.md b/docs/fr-fr/stage-2/assignments/travel-planning-agent-platform/index.md new file mode 100644 index 0000000..ca0df1c --- /dev/null +++ b/docs/fr-fr/stage-2/assignments/travel-planning-agent-platform/index.md @@ -0,0 +1,162 @@ +# Développement pratique d'une plateforme Agent de planification de voyages intelligente + +## Aperçu + +Ce projet pratique vous demande de réaliser, à partir d'un véritable PRD, une plateforme Agent de planification de voyages intelligente. Vous construirez un produit IA complet capable de recevoir des entrées structurées, de générer des itinéraires journaliers et de prendre en charge la sauvegarde et la réutilisation. Il ne s'agit pas d'un simple chatbot, mais d'un produit doté de capacités de gestion de tâches. + +Il s'agit du projet pratique synthétique de l'Étape 2. Le défi principal de ce projet est de faire en sorte que l'IA génère des itinéraires structurés et exploitables, et non un long bloc de texte non manipulable. + +## Prérequis + +Avant de commencer ce projet, vous devriez maîtriser les éléments suivants : + +- Conception de pages frontales et utilisation de bibliothèques de composants ([Conception UI](../../frontend/ui-design/), [Bibliothèque de composants moderne](../../frontend/modern-component-library/)) +- Conception et développement d'API backend ([Écriture de code d'interface](../../backend/ai-interface-code/)) +- Bases de données et Supabase ([Des bases de données à Supabase](../../backend/database-supabase/)) +- Flux de travail Git et déploiement ([Git et GitHub](../../backend/git-workflow/), [Déployer une application web](../../backend/zeabur-deployment/)) + +## Objectifs d'apprentissage + +Après avoir terminé ce projet, vous serez capable de : + +1. Lire un PRD et en extraire une liste de tâches de développement pour une plateforme Agent +2. Concevoir des formulaires d'entrée structurés et des formats de sortie structurés +3. Implémenter une couche d'orchestration d'agents pour gérer les entrées utilisateur, les appels de modèles et le stockage des résultats +4. Construire un cycle métier complet « génération -> sauvegarde -> réutilisation » +5. Effectuer des tests de bout en bout et livrer un prototype de produit IA démontrable + +## Présentation du projet + +Le produit que vous allez construire est une plateforme Agent de planification de voyages intelligente : + +| Fonctionnalité | Description | +|------|------| +| **Planification d'itinéraire** | L'utilisateur saisit le lieu de départ, la destination, les dates, le budget et les préférences ; le système génère un itinéraire journalier | +| **Répartition du budget** | Les résultats de l'itinéraire incluent la répartition du budget et des suggestions | +| **Gestion de l'historique** | L'utilisateur peut sauvegarder ses plans historiques, les régénérer et les exporter | +| **Back-office** | L'administrateur consulte les destinations populaires, les tâches échouées et les retours utilisateurs | + +::: tip Accès au PRD +Le document d'exigences de ce projet se trouve sur GitHub : [Voir le PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/fr-fr/stage-2/assignments/travel-planning-agent-platform/PRD.md) +::: + +
+ + + +
+ +## Partie 1 : Analyse des besoins + +### 1.1 Lire le PRD + +Ouvrez le document PRD et répondez aux questions suivantes : + +- Quels champs le formulaire d'entrée structuré doit-il contenir ? +- Quel est le format de sortie attendu pour l'itinéraire généré ? +- Comment les tâches sont-elles suivies (statuts, progression) ? +- Quelles sont les fonctionnalités du MVP et celles qui peuvent attendre ? + +::: warning +Si les questions ci-dessus n'ont pas de réponse claire, ne commencez pas à coder. Une mauvaise compréhension des besoins est la cause la plus fréquente de retour en arrière. +::: + +## Partie 2 : Construction du squelette du projet + +### 2.1 Générer les pages frontales + +Prompt de référence : + +```text +Veuillez générer, sur la base du PRD actuel, le squelette frontend d'une plateforme de planification de voyages intelligente. + +Exigences : +1. Page d'accueil avec formulaire de saisie structuré (départ, destination, dates, budget, préférences) +2. Page de planification affichant l'itinéraire généré jour par jour +3. Page d'historique des plans sauvegardés +4. Page de back-office pour les administrateurs +5. Générer d'abord uniquement la structure des pages et des données fictives +6. Style moderne et inspirant pour un produit de voyage +``` + +### 2.2 Vérifier la structure des pages + +- [ ] Le formulaire d'entrée est-il complet et structuré ? +- [ ] L'affichage de l'itinéraire est-il clair et organisé par jour ? +- [ ] L'historique est-il consultable et réutilisable ? + +## Partie 3 : Développement itératif + +### 3.1 Progresser par module + +1. **Formulaire d'entrée** : Champs structurés avec validation +2. **Orchestration de l'agent** : Appel au modèle avec prompt structuré, parsing de la sortie +3. **Affichage de l'itinéraire** : Présentation jour par jour avec budget et suggestions +4. **Sauvegarde et historique** : Stockage en base de données, listage et réutilisation +5. **Back-office** : Statistiques sur les destinations populaires et les échecs + +### 3.2 Structure de sortie de référence + +L'agent doit générer un itinéraire structuré : + +```json +{ + "days": [ + { + "day": 1, + "activities": [ + {"time": "09:00", "activity": "Visite du musée", "cost": 15, "duration": "2h"}, + {"time": "12:00", "activity": "Déjeuner au marché local", "cost": 20, "duration": "1h"} + ], + "daily_budget": 80, + "notes": "Prévoir des chaussures confortables" + } + ], + "total_budget": 500, + "currency": "EUR" +} +``` + +## Partie 4 : Tests et mise en ligne + +### 4.1 Tests de bout en bout + +- Soumettre un plan -> Consulter l'itinéraire généré -> Sauvegarder -> Retrouver dans l'historique +- Régénérer un plan sauvegardé avec des paramètres modifiés + +### 4.2 Déploiement + +- Déployer le frontend sur Vercel / Zeabur +- Déployer le backend sur Zeabur / Railway / Render +- Utiliser Supabase comme base de données + +## Livrables + +- [ ] Un lien de démonstration en ligne accessible +- [ ] Un lien vers le dépôt de code source (avec README) +- [ ] Le document PRD +- [ ] Des captures d'écran des pages principales +- [ ] Une vidéo de démonstration de 60 secondes + +## Critères d'évaluation + +| Dimension | Exigences de base | Exigences avancées | +|------|---------|---------| +| Planification | L'utilisateur peut soumettre un plan et voir un itinéraire | L'itinéraire est structuré avec budget et suggestions | +| Historique | Les plans peuvent être sauvegardés | Les plans sauvegardés peuvent être régénérés et exportés | +| Technique | Le backend appelle le modèle et stocke les résultats | Gestion des erreurs, états de chargement et suivi des tâches | +| Livraison | Le projet peut être exécuté et déployé | README clair et vidéo de démonstration | + +## Références + +- [Conception UI](../../frontend/ui-design/) +- [Bibliothèque de composants moderne](../../frontend/modern-component-library/) +- [Des bases de données à Supabase](../../backend/database-supabase/) +- [Écriture de code d'interface assistée par IA](../../backend/ai-interface-code/) +- [Flux de travail Git et GitHub](../../backend/git-workflow/) +- [Comment déployer une application web](../../backend/zeabur-deployment/) diff --git a/docs/fr-fr/stage-2/backend/ai-interface-code/index.md b/docs/fr-fr/stage-2/backend/ai-interface-code/index.md new file mode 100644 index 0000000..aab88c3 --- /dev/null +++ b/docs/fr-fr/stage-2/backend/ai-interface-code/index.md @@ -0,0 +1,168 @@ +# Conception et développement d'interfaces backend d'application + +Dans les cours précédents, nous avons appris à utiliser des outils comme Figma pour réaliser des maquettes de conception UI, à utiliser l'IA pour générer rapidement des pages frontend statiques, et à utiliser Supabase pour construire des bases de données et mettre en œuvre une authentification utilisateur préliminaire. Désormais, une question naturelle se pose : après que l'utilisateur a cliqué sur ces boutons dynamiques de la page frontend, comment les données sont-elles silencieusement stockées dans Supabase ? Lorsque nous devons exécuter des logiques métier plus complexes (paiements concurrents, notifications planifiées, traitement de données sensibles), est-il sûr de laisser le frontend se connecter directement à la base de données ? + +Cela nous amène à un maillon crucial de l'architecture de développement web moderne — **l'interface API backend**. + +Plutôt que de taper manuellement des centaines de lignes de routes backend, contrôleurs et logique de validation de paramètres, nous pouvons désormais tirer parti de la puissante capacité de génération de code des grands modèles pour confier le code fastidieux à l'IA. Dans ce cours, nous sortirons du cercle vicieux du « code IA vague et superficiel » et, en nous appuyant sur de véritables scénarios métier, nous vous montrerons comment utiliser des prompts de haute qualité pour guider les grands modèles afin d'écrire des interfaces backend Node.js robustes et conformes aux normes de l'industrie, tout en générant automatiquement la documentation API et les cas de test. + +> 💡 **Prérequis** +> +> Avant d'étudier cette section, il est recommandé de connaître les sujets suivants : +> - [De la base de données à Supabase](../database-supabase/) - Comprendre les concepts de base de données et de modèle de données. +> - [Git et GitHub](../git-workflow/) - Se familiariser avec le contrôle de version dans le développement de projets. +> - [Qu'est-ce que le terminal/la ligne de commande](/fr-fr/appendix/2-development-tools/command-line-shell) - L'initialisation et le lancement de projets nécessitent des opérations de base en ligne de commande. + +# Ce que vous allez apprendre + +1. **Qu'est-ce qu'une interface API** : Comprendre le pont de communication frontend-backend et les spécifications de conception RESTful. +2. **Les grands modèles au service de la construction** : Comment utiliser des prompts structurés pour que l'IA vous aide à monter un projet de base Node.js + Express. +3. **Développement de la logique d'interface** : Guider les grands modèles pour générer des interfaces CRUD (créer, lire, mettre à jour, supprimer) avec validation métier rigoureuse et connexion à la base de données Supabase. +4. **Documentation API automatisée** : Laisser les grands modèles générer rétroactivement à partir du code la documentation OpenAPI/Swagger, standard de la collaboration inter-équipes. +5. **Boucle de test et d'intégration** : Utiliser les grands modèles pour générer des collections de test Postman et des tests unitaires Jest, garantissant la qualité du code. + +--- + +# 1. Pourquoi avons-nous besoin d'interfaces API ? + +Dans la compréhension traditionnelle, le frontend est la « partie visible » et la base de données est l'« entrepôt de stockage ». Mais il manque un dispatcher entre les deux. Si vous imaginez l'application comme un restaurant : +- **Le frontend (client)** est le menu et la table de commande du restaurant, où les clients parcourent les plats et expriment leurs besoins. +- **La base de données (Supabase, etc.)** est l'entrepôt de la cuisine du restaurant, où sont stockés tous les ingrédients et les registres de comptes. +- **L'interface API backend** est le serveur du restaurant. Les clients ne peuvent pas se précipiter directement dans la cuisine pour prendre des ingrédients (ce serait chaotique et soulèverait des problèmes de sécurité). Ils doivent communiquer leur « demande de commande » (requête HTTP) au serveur. Celui-ci vérifie (validation des paramètres, authentification des permissions), va chercher le contenu correspondant dans la cuisine, puis rapporte « le plat préparé » (réponse HTTP, généralement au format JSON) au client. + +Grâce aux interfaces API, nous avons réalisé une **séparation frontend-backend** claire : le frontend se concentre uniquement sur le rendu des pages, tandis que le backend se consacre exclusivement à la logique métier, au traitement des données et à la sécurité. + +--- + +# 2. Conception de l'architecture du projet et initialisation + +Une structure de projet claire est un prérequis pour que les grands modèles puissent écrire du bon code. Avant de demander à l'IA d'écrire du code, vous devez avoir une idée claire de la structure du projet. + +## 2.1 Structure de projet API courante + +Même en utilisant les grands modèles pour générer du code, vous ne devez jamais tout mettre dans un seul fichier `server.js`. Une architecture backend Node.js maintenable ressemble généralement à ceci : + +```text +my-api-project/ +├── .env # Variables d'environnement sensibles (API Keys, chaîne de connexion base de données) +├── server.js # Point d'entrée du projet (démarrage du serveur, enregistrement des middlewares globaux) +├── package.json # Fichier de gestion des dépendances +├── src/ +│ ├── routes/ # Couche de routes : définit les chemins URL et les méthodes de requête +│ ├── controllers/ # Couche contrôleurs : traite les paramètres de requête métier, appelle les services et retourne les réponses +│ ├── services/ # Couche services : encapsule les interactions avec la base de données et la logique métier principale +│ └── middlewares/ # Middlewares : authentification, capture globale des erreurs +└── docs/ # Répertoire de stockage de la documentation API +``` + +## 2.2 Initialisation du projet avec l'IA + +Plutôt que de lancer manuellement `npm init` et d'installer les dépendances une par une, il est plus efficace de fournir ces spécifications sous forme de prompt au grand modèle : + +> 🗣️ **Prompt pour le grand modèle (exemple) :** +> « Aidez-moi à monter un projet backend Node.js qui doit pouvoir se connecter à une base de données Supabase, avec une structure claire pour faciliter la maintenance future. » + +Après avoir exécuté le code renvoyé par l'IA, vous disposerez d'une application backend avec une ébauche de niveau entreprise sur `localhost:3000`. + +--- + +# 3. Pratique centrale : développement d'interface assisté par grand modèle + +C'est la partie la plus importante de ce chapitre. Le code généré par les grands models souffre souvent de « failles logiques » ou de « superficialité », car le contexte fourni par les développeurs est insuffisant. **Les grands modèles ne craignent pas la complexité des besoins, ils craignent l'ambiguïté.** + +Prenons l'exemple de l'interface de création pour la table `menu_items` (table des menus) mentionnée dans le [chapitre sur les bases de données](../database-supabase/), pour voir comment rédiger un prompt de haute qualité. + +## 3.1 Fournir un contexte complet au grand modèle + +Avant de demander à l'IA d'écrire une interface, vous devez toujours fournir la **définition des champs de la base de données (Schema)** et les **contraintes spécifiques**. + +> 🗣️ **Modèle de prompt de haute qualité :** +> « Aidez-moi à écrire une interface pour ajouter un élément au menu. Le menu comporte un nom de produit, un prix, une catégorie (burger, accompagnement, boisson) et un statut de disponibilité. Le nom et le prix sont obligatoires, le prix ne peut pas être négatif. Lorsque l'utilisateur saisit des données incorrectes, il faut afficher un message d'erreur. » + +## 3.2 Réviser le code généré par le grand modèle + +Le code généré par le grand modèle ressemble généralement à ceci, avec une séparation claire des responsabilités : + +```javascript +// services/menuService.js +const { createClient } = require('@supabase/supabase-js'); +const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY); + +exports.createMenuItem = async (menuData) => { + // Appel du SDK Supabase pour insérer les données dans la table + const { data, error } = await supabase + .from('menu_items') + .insert([menuData]) + .select(); + + if (error) throw new Error(`Échec de l'insertion en base de données : ${error.message}`); + return data[0]; +}; +``` + +Vous pouvez constater que le code généré de cette manière est non seulement structurellement raisonnable, mais qu'il prend également en compte l'initialisation de Supabase, la capture d'erreurs et le traitement des exceptions — un monde de différence par rapport au code « spaghetti » obtenu en demandant simplement « écrivez une interface d'ajout ». + +--- + +# 4. Libérer les mains : génération automatique de documentation API + +Pour une équipe de développement, une API sans documentation est une boîte noire. Les ingénieurs frontend ne peuvent pas deviner quels paramètres vous attendez, ni prédire la structure de retour. La norme de description d'API la plus répandue dans l'industrie est **OpenAPI (anciennement Swagger)**. + +Auparavant, écrire manuellement des documents Swagger au format YAML ou JSON était extrêmement pénible et source d'erreurs. C'est désormais devenu le domaine d'expertise des grands modèles. + +Vous pouvez simplement sélectionner le code de vos `routes` et `controllers`, puis le fournir au grand modèle : + +> 🗣️ **Prompt pour la génération de documentation :** +> « Aidez-moi à générer une documentation d'interface à partir du code ci-dessus. Précisez la signification de chaque paramètre et les données retournées, pour faciliter l'intégration avec les collègues frontend. » + +Dans ce processus, vous pouvez même demander à l'IA de compléter les descriptions des champs (Description) et les données Mock (par exemple `price_cents: 1200` pour 12 euros), réduisant considérablement les coûts de communication. + +--- + +# 5. Filet de sécurité : génération de code de test et collection Postman + +Le code est écrit, la documentation est publiée, il reste une dernière étape : vérifier que le code fonctionne réellement. + +## 5.1 Générer une configuration de test Postman / Apifox + +Dans le développement d'interfaces, nous utilisons généralement un outil visuel comme Postman pour simuler les requêtes HTTP envoyées par le frontend. Sans grand modèle, vous devriez saisir manuellement l'URL, ajouter les en-têtes (headers) un par un et assembler le corps de la requête JSON. + +Il vous suffit d'envoyer cette instruction à l'IA : +> « Convertissez cette documentation d'interface dans un format importable par Postman, en incluant des exemples de requêtes normales et d'erreurs. » + +Après avoir obtenu le texte JSON, sauvegardez-le sous `menu_api.json` et glissez-le dans Postman : vous disposez instantanément d'un panneau de clics de test prêt à l'emploi. + +## 5.2 Écrire des tests unitaires automatisés + +Si vous visez une qualité d'ingénierie plus rigoureuse, vous pouvez demander au grand modèle de vous aider à écrire des tests unitaires (Unit Tests) avec un framework comme `Jest`, pour tester les limites de la logique métier principale (par exemple, vérifier si la validation au niveau de la base de données fonctionne lorsqu'un prix négatif est transmis). + +--- + +# 6. Meilleures pratiques essentielles pour les interfaces backend + +Même avec l'assistance de l'IA, en tant que « gardien » de l'ensemble du système, vous devez connaître et auditer les principes fondamentaux suivants : + +1. **Conventions de nommage RESTful pour les chemins** : + - Bon design : `GET /api/users` (obtenir la liste des utilisateurs), `POST /api/users` (créer un utilisateur). Les URL doivent représenter des noms de « ressources ». + - Mauvais design : `POST /api/getUser` ou `POST /api/createUser`. Les verbes doivent être exprimés par les méthodes HTTP (GET/POST/PUT/DELETE). +2. **Codes d'état HTTP standardisés** : + - 200/201 : Requête réussie / Ressource créée avec succès. + - 400 : Bad Request, erreur de format des paramètres frontend, champ obligatoire manquant. + - 401/403 : Unauthorized / Forbidden, utilisateur non connecté ou sans permission. + - 404 : NotFound, ressource inexistante. + - 500 : Server Error, erreur de code backend ou base de données hors service. Évitez absolument d'exposer la pile d'erreurs au frontend (risque de sécurité). +3. **Ne jamais faire confiance aux entrées utilisateur** : les entrées frontend peuvent être falsifiées. Toutes les validations de paramètres critiques doivent être refaites dans l'interface backend. + +# 7. Résumé + +Au cours de ce chapitre, vous avez opéré un véritable changement de perspective : vous n'êtes plus le « dactylographe » bloqué dans la syntaxe et la ponctuation, mais vous êtes devenu un **designer système et architecte en chef**. + +Vous avez maîtrisé : +1. La pensée système centrale des **interfaces API et de la séparation frontend-backend**. +2. **Comment fournir du contexte et des concepts de structure en couches** pour améliorer considérablement la qualité du code serveur généré par les grands modèles. +3. La transformation astucieuse des tâches fastidieuses de **rédaction de documentation** et de **construction de cas de test** en tâches automatisées où l'IA excelle. +4. La combinaison avec les connaissances **Supabase** acquises précédemment, pour compléter le flux de données complet de la requête client à la mise à jour de la base de données sous-jacente. + +::: tip 💡 Prochaine étape +Une fois votre flux de données et vos services backend prêts, ils ne fonctionnent encore que sur votre ordinateur local « pour votre propre plaisir ». Dans les prochains chapitres, nous apprendrons comment **déployer (Deploy)** ces services durement construits sur un serveur public, afin que votre produit soit accessible aux utilisateurs du monde entier. +::: diff --git a/docs/fr-fr/stage-2/backend/database-supabase/index.md b/docs/fr-fr/stage-2/backend/database-supabase/index.md new file mode 100644 index 0000000..0c315cc --- /dev/null +++ b/docs/fr-fr/stage-2/backend/database-supabase/index.md @@ -0,0 +1,950 @@ +# De la base de données à Supabase + +Lors du cours précédent, nous avons appris les bases de l'utilisation des outils de conception UI MasterGo et Figma, la récupération de code et la gestion de versions avec GitHub, et le déploiement d'applications et de sites web via Zeabur pour les rendre accessibles au plus grand nombre. + +Pour vous aider à mieux consolider vos connaissances, avant d'aborder les nouveaux contenus de ce cours sur les outils de conception et le déploiement, revoyons ensemble les points clés du cours précédent à travers quelques questions simples : + +1. Qu'est-ce qu'un outil de conception frontend, définition et utilisation de Figma, MasterGo. +2. Les méthodes de base pour convertir des maquettes de design en code. +3. Qu'est-ce que GitHub, comment configurer SSH, comment créer votre premier dépôt. +4. Que signifie le déploiement, comment utiliser Zeabur, comment déployer du code GitHub ou local sur le réseau public pour le rendre accessible. + +Si l'un de ces points reste flou, nous vous recommandons de revoir d'abord les documents et supports du cours précédent. N'hésitez pas à poser vos questions dans le groupe de discussion WeChat. + +Dans ce cours, nous apprendrons comment faire passer une application ou un site web d'un simple état fonctionnel à un produit plus proche d'un véritable service en ligne : non seulement nous utiliserons une base de données pour gérer les différentes évolutions des données de l'application, mais nous mettrons aussi en place un système utilisateur complet (inscription, connexion, permissions) ainsi que d'autres capacités backend essentielles. Nous prendrons Supabase comme plateforme de services backend pour fil conducteur, en l'utilisant d'abord pour implémenter les deux fonctionnalités fondamentales que sont « base de données + système utilisateur », puis en nous appuyant sur les composants fournis par Supabase pour mieux comprendre les modules clés généralement inclus dans les services backend cloud modernes, ainsi que leurs fonctions et logiques spécifiques. + +# Ce que vous allez apprendre + +1. Qu'est-ce qu'une donnée, qu'est-ce qu'une base de données, les bases de données courantes et leurs méthodes d'utilisation +2. Qu'est-ce que Supabase, comment utiliser Supabase pour les opérations de base sur une base de données +3. Comment utiliser Supabase pour ajouter une gestion basique des utilisateurs à votre application +4. Maîtriser les fonctionnalités avancées de Supabase : Realtime, Storage, Edge Functions +5. Ajouter la prise en charge de la connexion Google et GitHub à Supabase + +- Une application de base prenant en charge l'inscription/connexion des utilisateurs et le stockage des données dans une base de données en ligne +- Un modèle de code backend Supabase réutilisable (base de données + gestion des utilisateurs, etc.) pour vos projets ultérieurs + +# 1. Qu'est-ce qu'une base de données + +## 1.1 Qu'est-ce qu'une donnée + +Dans le monde numérique, les données (Data) sont omniprésentes. En termes simples, les données sont le support de l'information. Les coordonnées de vos amis, un article WeChat, une courte vidéo, le niveau d'un personnage dans un jeu -- tout cela constitue des données. Dans notre application, les données représentent toute information qui doit être enregistrée et gérée, comme les profils utilisateurs, l'historique des commandes, les paramètres du programme, etc. + +En général, les données se présentent sous différentes formes dans un programme. La forme la plus simple est la variable, que nous pouvons utiliser pour stocker des nombres simples : + +```python +# Python variable definition examples + +# Integer variable: stores age information +age = 30 + +# Boolean variable: stores status (whether active) +is_active = True # True means active, False means inactive + +# List variable: stores a set of score data +scores = [85, 92, 78, 90] # Contains 4 integer elements representing different scores + +# Dictionary variable: stores multiple related information of a user +user_info = { + "age": 30, # Key "age" corresponds to the value of age + "height": 1.80, # Key "height" corresponds to the value of height (unit: meter) + "login_count": 156 # Key "login_count" corresponds to the value of login times +} +``` + +Pour les données plus complexes telles que les profils personnels ou l'historique des commandes, nous pouvons utiliser des tableaux plus élaborés pour représenter les données : + +| user_id | name | email | +| ------- | ----- | ----------------- | +| 1001 | Alice | alice@example.com | +| 1002 | Bob | bob@example.com | + +| order_id | user_id | amount | status | +| -------- | ------- | ------ | --------- | +| 901 | 1001 | 29.99 | completed | +| 902 | 1002 | 15.50 | pending | + +Mais pour les données à la structure complexe, présentant des relations hiérarchiques ou des champs variables, nous pouvons utiliser le format JSON pour les décrire -- il s'agit d'un format intermédiaire de données universel sur Internet, compréhensible par presque tous les programmes, ce qui facilite les échanges de données entre systèmes. Par exemple, une commande peut contenir plusieurs articles, chacun ayant son propre nom, sa quantité et son prix. Représenter cela dans un tableau traditionnel serait fastidieux : il faudrait soit diviser les données en plusieurs tables (« table des commandes », « table des articles ») reliées par des champs d'association ; soit utiliser une seule table avec des champs redondants du type « nom article 1, prix article 1, nom article 2... », ce qui est impossible à adapter quand le nombre d'articles varie ; le JSON, quant à lui, permet de représenter directement la hiérarchie « commande - articles - propriétés des articles » de façon intuitive et flexible. + +```json +{ + "order_id": 901, + "user_id": 1001, + "amount": 29.99, + "status": "completed", + "items": [ + { "sku": "BG-001", "name": "牛肉汉堡", "quantity": 1, "price": 18.00 }, + { "sku": "SD-003", "name": "炸薯条", "quantity": 1, "price": 6.99 }, + { "sku": "DK-002", "name": "可乐", "quantity": 1, "price": 5.00 } + ], + "shipping_address": { + "street": "科技园路123号", + "city": "深圳", + "zip_code": "518057" + } +} +``` + +Allons plus loin : si nous considérons une donnée encodée sous forme de vecteur (Vector), il s'agit généralement d'une représentation numérique obtenue en traitant des données non structurées (texte, images ou audio) via un modèle IA (comme un modèle d'Embedding). Sa représentation peut ressembler à ceci : + +`[0.123, -0.456, 0.789, ..., -0.234]` (un tableau de plusieurs centaines, voire milliers de nombres à virgule flottante) + +En résumé, le monde réel regorge de données de formes et d'usages très variés qui méritent une analyse détaillée. Chaque type de données peut nécessiter une base de données spécifique pour son stockage, comme le montre l'illustration ci-dessous -- n'est-ce pas impressionnant ? + +![](/zh-cn/stage-2/backend/database-supabase/images/image1.png) + +## 1.2 Pourquoi avons-nous besoin d'une base de données + +Nous avons vu que les données du monde réel ont souvent une structure complexe. **Pour stocker et utiliser efficacement ces données, nous avons besoin d'un programme ou d'un conteneur spécialisé pour les gérer** -- c'est précisément la raison d'être des bases de données (Database). Une base de données est fondamentalement un programme spécialisé dont le rôle principal est d'organiser, de stocker en toute sécurité et de gérer systématiquement les données, tout en prenant en charge des requêtes efficaces. + +Imaginez un instant : sans base de données, que deviendraient les données de votre application ? Lorsque l'utilisateur ferme le navigateur ou quitte l'application, toutes les informations temporairement chargées sont immédiatement perdues ; nous ne pouvons ni sauvegarder durablement l'état d'utilisation (comme les informations de connexion, les paramètres personnalisés), ni partager de données clés entre les utilisateurs (comme le stock de produits, l'historique des commandes). Nous avons absolument besoin d'un dispositif pour stocker toutes nos données ! + +Plus souplement encore, le mode de déploiement d'une base de données peut être adapté aux besoins : elle peut être déployée sur un serveur local pour répondre aux exigences de gestion locale des données ; ou déployée dans le cloud, les bases de données cloud prenant en charge la mise à l'échelle élastique (Scale), capable de s'étendre en fonction de la croissance du volume de données et du trafic, et de supporter des données massives et une forte concurrence, garantissant une expérience utilisateur fluide même avec une forte croissance du nombre d'utilisateurs. + +En résumé, grâce à leur stockage persistant efficace, leur gestion fine et leurs capacités de requête rapide, les bases de données résolvent principalement les problèmes suivants : + +- **Stockage persistant des données** : Sans base de données, les données n'existeraient que dans la mémoire de l'application et seraient perdues à sa fermeture. La base de données résout ce problème en stockant les données de manière persistante sur des supports comme les disques durs, assurant leur conservation à long terme et réduisant le risque de perte. +- **Requêtes et analyse pratiques des données** : Les bases de données offrent des langages de requête puissants (comme SQL) permettant d'effectuer facilement et efficacement des requêtes, des filtres et des analyses complexes sur des données massives, aidant ainsi les entreprises à prendre de meilleures décisions. Sans base de données, trouver une information spécifique dans une masse de fichiers non organisés serait une tâche extrêmement chronophage et difficile. +- **Prise en charge de performances élevées et d'un accès concurrentiel massif** : Grâce à des techniques telles que l'optimisation des index, le cache de requêtes, les pools de connexions et l'architecture distribuée, les bases de données peuvent répondre aux requêtes en quelques millisecondes et supporter des milliers, voire des millions d'utilisateurs simultanés. C'est crucial pour les applications Internet modernes (flash sales e-commerce, flux en temps réel des réseaux sociaux), garantissant la réactivité du système et l'expérience utilisateur. Sans les hautes performances des bases de données, face à un afflux massif de requêtes, le système subirait des retards sévères, voire des pannes. +- **Garantie de l'intégrité et de la cohérence des données** : Les bases de données assurent l'exactitude et la cohérence des données grâce à divers mécanismes (contraintes, déclencheurs). Cela signifie que les données de la base doivent respecter des règles prédéfinies : par exemple, l'âge d'un utilisateur doit être un nombre, le numéro de commande doit être unique, empêchant ainsi efficacement la création de données illégales ou invalides. +- **Sécurité des données** : Les bases de données fournissent des mécanismes de sécurité robustes, notamment l'authentification des utilisateurs, le contrôle d'accès et le chiffrement des données, pour protéger celles-ci contre les accès, modifications ou destructions non autorisés. Pour faire face aux pannes matérielles, erreurs humaines ou attaques malveillantes, les bases de données proposent également des fonctions de sauvegarde et de restauration. Grâce à des sauvegardes régulières, les données perdues ou endommagées peuvent être restaurées en temps utile, assurant la continuité des activités. + +## 1.3 Bases de données relationnelles et non relationnelles + +Nous avons déjà abordé la valeur essentielle, les modes de déploiement et les avantages d'élasticité des bases de données. Lorsqu'il s'agit de choisir concrètement, la première distinction à opérer est entre les deux grandes catégories : les bases de données relationnelles et les bases de données non relationnelles (NoSQL). Voici une explication simple en quelques phrases : + +Les bases de données relationnelles sont comme des tableaux Excel rigoureusement structurés. Toutes les données doivent avoir un format prédéfini (un Schema défini, par exemple : il faut un nom et un âge, le nom doit être du texte, l'âge un nombre), et les différentes tables sont reliées par des champs d'association (un identifiant servant à connecter les tables, comme un numéro de sécurité sociale). Leur avantage est la précision et la fiabilité des données, idéales pour les virements bancaires, la gestion de stocks et autres scénarios où l'erreur est interdite. L'inconvénient est que la modification de la structure est assez contraignante, et que les performances peuvent être limitées avec des volumes de données massifs. + +Les bases de données non relationnelles (NoSQL) sont comme des dossiers flexibles, capables de stocker des documents, des images ou des paires clé-valeur (une structure de type « mot-définition » similaire à un dictionnaire) dans des formats variés, sans avoir à définir la structure à l'avance. Elles s'adaptent plus facilement aux besoins changeants et aux données à très grande échelle (comme les publications massives des réseaux sociaux), et la mise à l'échelle (ajout de serveurs pour améliorer les performances) est plus simple, mais au prix d'une perte partielle des capacités de requêtes associatives (capacité à consolider des informations de différentes tables) et des garanties de cohérence (assurance que les données restent exactes et non contradictoires), ce qui les rend adaptées aux applications Internet tolérant un certain niveau d'erreur. + +Alors, comment choisir une base de données en pratique ? En résumé, les bases de données relationnelles sont couramment utilisées pour les transactions financières, la gestion de stocks, le traitement de commandes, les systèmes comptables -- des scénarios nécessitant une forte cohérence, des transactions complexes et un équilibre lecture/écriture. Les bases de données non relationnelles conviennent mieux au stockage de contenu de réseaux sociaux, à l'analyse de logs en temps réel, à l'ingestion massive de données IoT, aux systèmes de recommandation avec forte lecture et écriture -- des scénarios à forte concurrence, avec des modes de lecture/écriture déséquilibrés et une structure flexible. + +Mais pour les entreprises, aux premiers stades il n'est pas nécessaire de consacrer beaucoup de temps à réfléchir au choix de la base de données. Les bases de données actuelles sont des produits et services très matures. L'approche la plus directe est de consulter différents fournisseurs de services cloud (des prestataires offrant des ressources et services IT comme des serveurs, du stockage, des bases de données, des logiciels et de la puissance de calcul). Vous pouvez contacter directement les équipes commerciales des fournisseurs cloud pour obtenir une solution de base de données adaptée à vos besoins métier ; et le moyen le plus pratique de construire une application d'entreprise est de privilégier la collaboration avec des fournisseurs spécialisés. (Note : les services d'entreprise sont généralement plus onéreux, il est recommandé de comparer plusieurs offres et, éventuellement, d'acheter des serveurs pour déployer soi-même une base de données open source comme alternative.) + +Vous pouvez également vous référer aux [recommandations de sélection de base de données](https://help.aliyun.com/zh/govcloud/getting-started/select-database-services) d'un fournisseur cloud, qui permettent de choisir différents types de bases de données selon les scénarios, et comparer les spécifications de différents fournisseurs pour trouver la plus adaptée. + +| Type de base de données | Nom | Prix | Scénarios d'utilisation | +| ------------ | ---------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Relationnelle | RDS MySQL | Faible | Version de base : apprentissage et petits sites ; version haute disponibilité : scénarios de bases de données de taille moyenne avec une certaine pression métier ; version cluster : métier ne tolérant pas les interruptions, forte pression d'accès | +| | RDS SQL Server | Élevé | Version de base : tests et petits sites commerciaux ; version haute disponibilité : sites commerciaux d'entreprise ; version cluster : métier d'entreprise ne tolérant pas les interruptions, forte pression d'accès | +| | RDS PostgreSQL | Le plus bas | Version de base : apprentissage et petits sites ; version haute disponibilité : scénarios de bases de données de taille moyenne avec une certaine pression métier ; version cluster : métier ne tolérant pas les interruptions, performances généralement supérieures à MySQL | +| | RDS PPAS | Élevé | Usage général : compatible avec les métiers Oracle, pression modérée ; version dédiée : pour les métiers nécessitant un serveur physique dédié, généralement des métiers Oracle à forte concurrence | +| | DRDS | Moyen | Version d'entrée : 4 cœurs 8 Go, prix abordable, adapté aux PME en ligne ; version entreprise : 16 cœurs 32 Go, bonne réponse SQL complexe, adaptée aux activités en ligne à très forte concurrence ; version ultime : 32 cœurs 64 Go, meilleure réponse SQL complexe, offre de très grandes capacités | +| NoSQL | Redis | Moyen | Redis double actif-standby : généralement utilisé comme base de données persistante pour améliorer la disponibilité ; version cluster Redis : généralement utilisée comme couche de cache pour accélérer les accès applicatifs, résolvant la pression de lecture que les bases de données classiques ne peuvent supporter | +| | MongoDB | Moyen | Instance mono-nœud : adaptée au développement, aux tests et au stockage de données non critiques ; instance répliquée : adaptée aux scénarios nécessitant de meilleures performances de lecture, comme les sites de lecture, les systèmes de requête de commandes, ou les pics d'activité temporaires ; instance shardée : cluster basé sur plusieurs réplicas offrant des performances de lecture encore supérieures pour les activités en ligne en temps réel | + +La théorie seule étant parfois difficile à saisir, illustrons avec un scénario concret de « articles de blog » comment les mêmes données sont stockées différemment dans une base de données relationnelle (SQL) et dans différents types de bases de données non relationnelles (NoSQL). + +Supposons que nous ayons une plateforme de blog stockant les informations suivantes : + +- Utilisateurs (Users) : ID utilisateur, nom d'utilisateur, email +- Articles (Posts) : ID article, titre, contenu, ID de l'auteur +- Commentaires (Comments) : ID commentaire, contenu du commentaire, ID du commentateur, ID de l'article associé +- Tags (Tags) : ID tag, nom du tag +- Relations articles-tags : plusieurs tags associés à un article, plusieurs articles correspondant à un même tag + +### Exemple de base de données relationnelle (SQL) + +Dans une base de données SQL, nous stockons les différents types de données dans des tables séparées, reliées par des « clés étrangères ». Cette structure est claire, normalisée et réduit la redondance. + +Prenons l'exemple de la « gestion d'articles d'une plateforme de contenu » : au lieu de stocker ensemble « utilisateurs, articles, commentaires, tags », nous les répartissons en 5 tables aux fonctions bien délimitées, chacune avec un « périmètre de responsabilité » clair et une définition de structure stricte (Schema) : + +- Table `users` (stockage des informations utilisateurs) + +| user_id (clé primaire) | username | email | +| -------------- | -------- | ----------------- | +| 101 | Alice | alice@example.com | +| 102 | Bob | bob@example.com | + +- Table `posts` (stockage des articles) + +| post_id (clé primaire) | title | content | author_id (clé étrangère) | +| -------------- | --------- | ------------------------------ | ---------------- | +| 1 | 初识SQL | 这是关于SQL数据库的一篇文章... | 101 | +| 2 | NoSQL入门 | NoSQL提供了灵活的数据模型... | 102 | + +- Table `comments` (stockage des commentaires) + +| comment_id (clé primaire) | body | commenter_id (clé étrangère) | post_id (clé étrangère) | +| ----------------- | ---------------- | ------------------- | -------------- | +| 1001 | 写得很棒! | 102 | 1 | +| 1002 | 学习了。 | 101 | 2 | +| 1003 | 有没有更多例子? | 101 | 1 | + +- Table `tags` (stockage des tags) + +| tag_id (clé primaire) | tag_name | +| ------------- | -------- | +| 51 | 数据库 | +| 52 | 技术 | +| 53 | 入门 | + +- Table `post_tags` (stockage des relations plusieurs-à-plusieurs entre articles et tags) + +| post_id (clé étrangère) | tag_id (clé étrangère) | +| -------------- | ------------- | +| 1 | 51 | +| 1 | 52 | +| 2 | 51 | +| 2 | 52 | +| 2 | 53 | + +Pour interroger les « informations complètes de l'article "初识 SQL" (post_id=1) d'Alice (contenu, auteur, commentaires, tags) », il faut exécuter une requête multi-table (JOIN), en reliant les 5 tables via les clés étrangères et en agrégeant les données. La requête SQL est la suivante : + +```sql +SELECT + p.title, + p.content, + u.username AS author, + c.body AS comment, + t.tag_name AS tag +FROM + posts p +JOIN + users u ON p.author_id = u.user_id +LEFT JOIN + comments c ON p.post_id = c.post_id +LEFT JOIN + post_tags pt ON p.post_id = pt.post_id +LEFT JOIN + tags t ON pt.tag_id = t.tag_id +WHERE + p.post_id = 1; +``` + +Cette requête traverse 5 tables et agrège toutes les données associées dans un seul résultat. C'est l'avantage central des bases de données relationnelles : grâce à la normalisation et aux opérations de jointure, il est possible d'effectuer toutes sortes de requêtes complexes tout en garantissant la cohérence et une redondance minimale. + +### Exemple de base de données non relationnelle (NoSQL) + +Les bases de données NoSQL (comme MongoDB, Redis) adoptent une philosophie de conception inverse : elles n'insistent pas sur le découpage et la normalisation des données, et regroupent généralement toutes les données associées dans un même agrégat afin de réduire les jointures lors des requêtes et d'améliorer les performances de lecture. + +Dans les bases de données NoSQL, les bases de données orientées documents (Document Database) sont parmi les plus courantes, avec MongoDB comme représentant typique. Elles utilisent le « document » comme unité de stockage de base -- un « document » n'est pas un article au sens habituel, mais une structure de données similaire à JSON (MongoDB utilise le format BSON, qui supporte davantage de types de données) : pas besoin de définir un Schema unifié à l'avance, les champs de chaque document peuvent être ajoutés ou supprimés flexiblement, et les types de champs peuvent être librement ajustés, parfaitement adaptés aux scénarios où les formats de données sont très variables. + +Dans une base de données orientée documents, un article et toutes ses informations associées (commentaires, tags) sont généralement stockés dans un seul document (au format similaire à JSON, avec des champs librement définis, sans Schema prédéfini). La logique centrale est de « stocker l'information complète d'un scénario métier dans un seul document », évitant la concaténation de multiples sources de données lors des requêtes. + +Exemple de document dans la collection `posts` : + +```json +{ + "_id": 1, + "title": "初识SQL", + "content": "这是关于SQL数据库的一篇文章...", + "author": { + "user_id": 101, + "username": "Alice", + "email": "alice@example.com" + }, + "tags": [ + "数据库", + "技术" + ], + "comments": [ + { + "comment_id": 1001, + "body": "写得很棒!", + "commenter": { + "user_id": 102, + "username": "Bob" + } + }, + { + "comment_id": 1003, + "body": "有没有更多例子?", + "commenter": { + "user_id": 101, + "username": "Alice" + } + } + ] +} +``` + +L'avantage de cette conception est très intuitive : pour obtenir « les informations complètes du premier article (auteur, commentaires, tags inclus) », il suffit de requêter ce seul document via `_id:1`. La base de données retourne toutes les données en une seule lecture, sans avoir à effectuer les 3-4 jointures de tables comme en SQL -- l'efficacité de lecture est considérablement améliorée. + +Mais cette approche présente aussi un trade-off (compromis) évident : comme les données sont « stockées par agrégation », une redondance de données est inévitable -- par exemple, le `username` de l'auteur « Alice » est intégré dans chaque document d'article qu'elle a écrit. Si un jour « Alice » change son nom d'utilisateur en « Alice_New », il faudrait en théorie parcourir tous les documents d'articles contenant ses informations et mettre à jour le champ `author.username` un par un -- non seulement l'opération est fastidieuse, mais des problèmes de réseau ou de serveur peuvent aussi entraîner l'échec de la mise à jour de certains documents, créant une situation où « le même utilisateur a un nom différent selon les articles ». + +En pratique, cependant, cette redondance est souvent « acceptable » : pour les scénarios de type blogs, médias, fiches produits e-commerce où l'on **lit beaucoup et écrit peu** (les consultations de contenu sont bien plus fréquentes que les modifications de nom d'utilisateur), échanger un peu de redondance contre des « performances de lecture extrêmes » est un choix judicieux. En revanche, pour les scénarios où l'on « écrit beaucoup et lit peu » (comme les modifications fréquentes des informations utilisateurs), il faut pondérer les besoins métier pour déterminer si une base de données orientée documents est pertinente. + +Ce qui précède constitue une introduction simple aux différents types de bases de données. Si vous souhaitez en savoir plus sur les types de bases de données spécifiques, vous pouvez consulter les ressources suivantes pour essayer différentes bases de données. + +Examples of SQL databases : +[Db2](https://www.ibm.com/products/db2-database), [MySQL](https://cloud.ibm.com/catalog#highlights), [PostgreSQL](https://www.ibm.com/think/topics/postgresql), [YugabyteDB](https://www.yugabyte.com/), [CockroachDB](https://www.cockroachlabs.com/), [Oracle Database](https://www.ibm.com/products/postgres-enterprise), [Azure SQL Database](https://www.ibm.com/consulting/microsoft) + +Examples of NoSQL databases : +[Redis](https://www.ibm.com/think/topics/redis), [CouchDB](https://www.ibm.com/think/topics/couchdb), [MongoDB](https://www.ibm.com/think/topics/mongodb), [Cassandra](https://cloud.ibm.com/catalog#highlights), [Elasticsearch](https://www.ibm.com/think/topics/elasticsearch), [BigTable](https://www.techtarget.com/searchdatamanagement/news/252512583/Google-scales-up-Cloud-Bigtable-NoSQL-database), [Neo4j](https://neo4j.com/users/ibm/), [HBase](https://www.ibm.com/think/topics/hbase) + +# 2. Supabase + +Nous venons de présenter plusieurs types de bases de données courantes et leurs scénarios d'utilisation respectifs. Cependant, dans un projet réel, la base de données n'est généralement qu'un module fondamental de l'infrastructure backend : au-delà du stockage et de la recherche de données, il faut aussi résoudre tout un ensemble de problèmes, notamment **l'inscription et la connexion des utilisateurs, la vérification des permissions, le téléchargement et le stockage de fichiers, les API publiques, voire les tâches planifiées et les notifications en temps réel**. Simplement choisir une bonne base de données ne permet pas à votre application d'« être immédiatement opérationnelle en ligne » -- il reste tout un pan de travail backend fastidieux entre les deux. + +Il faut donc prendre en compte un contexte plus large : **les services backend**. Une application complète est généralement composée d'un « frontend + backend » : le frontend gère l'affichage des pages et les interactions utilisateur, tandis que le backend se charge du stockage des données, de la connexion des utilisateurs, du traitement de la logique métier, etc. Autrefois, les développeurs devaient installer leurs propres serveurs, configurer les bases de données, concevoir et implémenter les API, et gérer manuellement les permissions, les stratégies de sécurité, l'évolutivité et la supervision -- un processus à la fois répétitif et chronophage. Pour résoudre ces tâches répétitives, l'industrie a vu apparaître le **BaaS (Backend as a Service)** : une plateforme cloud regroupant les fonctionnalités backend courantes -- base de données, authentification des utilisateurs, stockage de fichiers, capacités temps réel -- que les développeurs peuvent appeler directement via SDK/API, sans avoir à construire et maintenir l'infrastructure depuis zéro. + +Dans ce contexte, [Supabase](https://supabase.com/) peut être considéré comme un représentant de nouvelle génération du BaaS : il prend PostgreSQL comme base de données centrale et y intègre un ensemble complet de capacités backend -- Auth, Storage, Realtime, Edge Functions, Vector -- offrant aux développeurs une « plateforme backend tout-en-un centrée sur Postgres ». Abordons maintenant ce sujet en passant de « choisir uniquement une base de données » à « choisir une plateforme complète de développement backend », et voyons concrètement ce que Supabase permet d'éviter et comment il réduit considérablement la distance entre un prototype et un produit utilisable. + +## 2.1 Guide pas à pas + +Après avoir bien compris le positionnement global de Supabase, nous allons suivre le parcours de la console Supabase pour détailler les capacités centrales qu'il offre et les responsabilités de chacune. Nous présenterons en détail chaque option de Supabase pour vous aider à prendre en main rapidement ses opérations de base. + +![](/zh-cn/stage-2/backend/database-supabase/images/image2.png) + +Après vous être connecté sur le site officiel de Supabase, cliquez sur « New project » sur la page d'accueil de la console pour lancer la création ; + +Saisissez les informations principales requises : Project Name, mot de passe de la base de données, et choisissez comme région celle qui est la plus proche des utilisateurs cibles de votre application. + +![](/zh-cn/stage-2/backend/database-supabase/images/image3.png) + +Une fois la création réussie, la barre latérale gauche de la console affichera tous les modules fonctionnels clés (Table Editor, SQL Editor, Database, Authentication, etc.). Les opérations suivantes s'articuleront autour de ces modules. + +![](/zh-cn/stage-2/backend/database-supabase/images/image4.png) + +### Éditeur de tables (Table Editor) + +Table Editor est l'éditeur visuel de tables de données de Supabase. Il vous permet de visualiser et modifier directement les données de la base de données comme sur Excel, sans écrire de SQL -- il suffit d'interagir à la souris pour modifier le contenu des données. + +![](/zh-cn/stage-2/backend/database-supabase/images/image5.png) + +Un point notable est le Schema. Le Schema peut être compris comme un « conteneur de ressources » au sein de la base de données, utilisé pour organiser en groupes les tables, vues, fonctions, index et autres ressources. Ses deux rôles principaux sont : éviter les conflits de nommage (des tables de même nom peuvent exister dans différents Schémas) et mettre en place une isolation de permissions (par exemple n'autoriser que certains utilisateurs à accéder aux tables d'un Schema donné). + +Cliquez sur la liste déroulante Schema en haut de l'éditeur pour basculer entre les différents conteneurs. En développement quotidien, vous n'avez généralement besoin de vous concentrer que sur deux catégories : + +- `public` : le conteneur de ressources publiques par défaut. Les tables métier créées par les développeurs (comme « table des articles », « table des commentaires ») y sont stockées ; +- `auth` : le conteneur dédié à l'authentification des utilisateurs. Sa table `users` stocke automatiquement les informations de tous les utilisateurs inscrits (ID utilisateur, email, heure de connexion, etc.). Il n'est pas recommandé de modifier manuellement les tables par défaut de ce Schema pour ne pas affecter les fonctionnalités d'authentification ; + +![](/zh-cn/stage-2/backend/database-supabase/images/image6.png)![](/zh-cn/stage-2/backend/database-supabase/images/image7.png) + +### Éditeur SQL (SQL Editor) + +Le SQL Editor est l'exécuteur d'instructions SQL de Supabase, vous permettant de manipuler directement la base de données par du code. Vous pouvez demander à un grand modèle de générer des instructions SQL, les saisir à droite puis cliquer sur RUN pour créer ou modifier des tables, et visualiser directement les données filtrées dans la section Results. + +![](/zh-cn/stage-2/backend/database-supabase/images/image8.png) + +Après avoir exécuté RUN, vous retrouverez les nouvelles tables créées dans le Schema public du Table Editor ; les requêtes exécutées sont sauvegardées dans la section PRIVATE à gauche, et vous pouvez même cliquer sur l'icône cœur sous la requête pour l'ajouter en favoris. + +### Centre de gestion de la base de données (Database) + +Database est le centre de gestion de la base de données de Supabase, permettant de visualiser et gérer toutes les tables de données, et de comprendre les relations entre les tables grâce à des lignes de connexion (contraintes de clé étrangère, représentant les relations de référence entre les données). + +![](/zh-cn/stage-2/backend/database-supabase/images/image9.png) + +Si vous souhaitez créer manuellement une nouvelle table, vous pouvez le faire directement dans la section tables. Nous détaillerons cette opération dans les tutoriels suivants. + +![](/zh-cn/stage-2/backend/database-supabase/images/image10.png) + +### Authentification (Authentication) + +Authentication gère l'inscription, la connexion et les permissions des utilisateurs. Les données du système de gestion des utilisateurs par défaut y sont stockées. Il offre des fonctionnalités prêtes à l'emploi : inscription, connexion, réinitialisation du mot de passe, vérification par email, et prend en charge la connexion OAuth tiers (WeChat, GitHub, Google, etc.). Toutes les données utilisateurs sont automatiquement synchronisées dans la table `auth.users` de la base de données. + +![](/zh-cn/stage-2/backend/database-supabase/images/image11.png) + +Vous trouverez dans l'option Provider les différentes entrées de connexion prises en charge par Supabase. Par défaut, l'email est utilisé ; si vous souhaitez utiliser GitHub ou Google pour la connexion, une configuration supplémentaire est nécessaire, que nous détaillerons dans les cours suivants. + +![](/zh-cn/stage-2/backend/database-supabase/images/image12.png) + +La section Sign In / Providers inclut également le contrôle du comportement d'inscription par email. Si vous ne souhaitez pas que chaque inscription par email nécessite une confirmation préalable de l'utilisateur, vous pouvez désactiver l'obligation de confirmer l'email. + +![](/zh-cn/stage-2/backend/database-supabase/images/image13.png) + +Si vous souhaitez utiliser un autre fournisseur de services d'authentification que Supabase, vous pouvez cliquer sur Third Party Auth -- par exemple, utiliser Clerk comme fournisseur tiers. + +![](/zh-cn/stage-2/backend/database-supabase/images/image14.png) + +Si vous craignez un afflux d'utilisateurs inscrits à court terme, vous pouvez activer les stratégies de limitation de débit dans Rate Limits : + +![](/zh-cn/stage-2/backend/database-supabase/images/image15.png) + +### Stockage (Storage) + +Storage est le système de stockage de Supabase, compatible avec le concept S3 d'Amazon Cloud. Il permet de stocker tout type de fichiers (images, vidéos, documents, audio, etc.) et offre une gestion des permissions d'accès (public ou privé) ainsi que des liens de téléchargement (permanents ou temporaires). Vous pouvez facilement gérer les fichiers des utilisateurs dans votre application et intégrer le système d'authentification de Supabase pour un contrôle d'accès fin. + +![](/zh-cn/stage-2/backend/database-supabase/images/image16.png) + +Nous présenterons l'utilisation concrète de Storage dans le projet avancé de ce cours. + +![](/zh-cn/stage-2/backend/database-supabase/images/image17.png) + +Si vous souhaitez utiliser les protocoles S3 pour vos opérations, vous pouvez utiliser directement la configuration correspondante : + +![](/zh-cn/stage-2/backend/database-supabase/images/image18.png) + +> Amazon Cloud (Amazon Web Services, ou AWS) est la plateforme de cloud computing d'Amazon (comme une immense salle serveur en ligne où vous pouvez louer à la demande des ressources de calcul et de stockage). S3 (Simple Storage Service) est le service d'AWS dédié au stockage de fichiers (similaire à un disque dur en ligne illimité, pour stocker images, vidéos, sauvegardes et autres fichiers). C'est aujourd'hui le service de stockage d'objets le plus populaire, devenu un standard de facto dans l'industrie. +> +> **Pourquoi proposer une API compatible S3 ?** : S3 existe depuis près de 20 ans. Il existe de nombreux outils, SDK et documentations prêts à l'emploi. La compatibilité S3 signifie que vous pouvez utiliser directement ces ressources sans avoir à tout recréer, ce qui accélère la mise en production. + +### Edge Functions + +Si vous ne souhaitez pas déployer de backend mais avez besoin d'opérations sur la base de données et de fonctions, vous pouvez utiliser les Edge Functions pour bénéficier de capacités backend sans serveur. Ce sont des fonctions côté serveur distribuées globalement fournies par Supabase. En termes simples, elles vous permettent d'écrire et déployer du code backend dans le cloud sans avoir à acheter ni gérer vos propres serveurs. Ces fonctions sont déployées sur les nœuds de périphérie du réseau mondial et s'exécutent automatiquement au plus près de vos utilisateurs, réduisant ainsi considérablement la latence réseau pour une vitesse de réponse optimale. Vous pouvez créer, éditer et déployer directement depuis le tableau de bord Supabase -- le flux de développement est très pratique. + +![](/zh-cn/stage-2/backend/database-supabase/images/image19.png) + +Un usage clé des Edge Functions est de servir d'intercouche sécurisée pour protéger vos informations sensibles et vos clés d'authentification. Appeler directement des services tiers (comme OpenAI, Stripe) depuis le code frontend expose votre clé API, avec tous les risques de sécurité que cela implique. Grâce aux Edge Functions, votre application frontend ne communique qu'avec votre fonction Supabase, et tous les secrets sont conservés uniquement dans Supabase. + +![](/zh-cn/stage-2/backend/database-supabase/images/image20.png) + +Les Edge Functions utilisent les clés exposées dans les secrets comme variables d'environnement, chargées via `Deno.env.get`, pour réaliser les appels aux services tiers. Ainsi, les clés sensibles ne sont jamais exposées côté client (votre navigateur), éliminant définitivement le risque de vol. + +![](/zh-cn/stage-2/backend/database-supabase/images/image21.png) + +Lors d'une requête à une Edge Function Supabase, la clé Supabase correspondante doit être incluse dans l'en-tête de la requête. Voici un exemple minimal : + +```javascript +// Configuration principale (remplacez par vos informations réelles) +const projectId = "Votre ID de projet Supabase"; +const functionName = "Nom de l'Edge Function cible"; +const supabaseKey = "Clé anon_key Supabase"; + +// Appel de la fonction +async function callEdgeFunction() { + const url = `https://${projectId}.supabase.co/functions/v1/${functionName}`; + + try { + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${supabaseKey}` // Clé : authentification via la clé + }, + body: JSON.stringify({ order_id: "123", action: "refund" }) // Données de requête personnalisées + }); + + const result = await response.json(); + console.log("Appel réussi :", result); + } catch (error) { + console.error("Échec de l'appel :", error.message); + } +} + +// Exécuter l'appel +callEdgeFunction(); +``` + +En outre, les Edge Functions s'intègrent parfaitement au système d'authentification des utilisateurs de Supabase. Lorsqu'un utilisateur connecté appelle une fonction, ses informations d'identité sont transmises à la fonction. Vous pouvez ainsi identifier facilement l'utilisateur courant dans la fonction et appliquer des contrôles de permissions en fonction de son identité. Plus important encore, lors des opérations sur la base de données, les fonctions respectent automatiquement les politiques de sécurité au niveau des lignes (Row Level Security) que vous avez définies, garantissant que les utilisateurs ne peuvent accéder et modifier que les données qu'ils sont autorisés à manipuler -- simplifiant la création d'applications multi-utilisateurs sécurisées. + +Les cas d'usage des Edge Functions sont très variés et couvrent toutes sortes de tâches backend. Elles sont idéales pour écouter les événements Webhook de services tiers (paiement réussi, commit de code, etc.) et exécuter automatiquement la logique de traitement correspondante. Vous pouvez aussi les utiliser pour envoyer des notifications par email, générer des rapports PDF, créer des interfaces API personnalisées encapsulant une logique métier complexe, ou exécuter toute tâche de calcul que vous souhaitez réaliser côté serveur -- étendant considérablement les capacités de votre application. + +Prenons un exemple concret : l'outil d'authentification Clerk. Clerk ne gère que les opérations liées à l'authentification (connexion, inscription, mise à jour des informations), sans gérer directement votre base de données métier. Pour synchroniser ces informations d'authentification avec votre base de données métier, il faut passer par des événements Webhook qui déclenchent des Edge Functions. Celles-ci écoutent les signaux Webhook de Clerk et exécutent automatiquement la logique de synchronisation, alignant en temps réel les informations utilisateur dans la base Supabase avec l'état de connexion Clerk -- le tout sans déployer un backend indépendant. + +### Moteur de synchronisation de données en temps réel (Realtime) + +Realtime est le moteur de synchronisation de données en temps réel de Supabase, qui permet à votre application de recevoir instantanément les notifications de modifications de la base de données sans avoir à interroger l'API de manière répétée. Lorsqu'une opération `INSERT`, `UPDATE` ou `DELETE` est effectuée sur les données, Realtime pousse ces modifications en temps réel à tous les clients connectés via WebSocket. C'est essentiel pour les applications nécessitant des interactions en temps réel. + +Realtime comprend principalement trois fonctionnalités clés, couvrant la plupart des scénarios temps réel : + +1. **Postgres Changes** : écoute directement les modifications des tables de la base de données. Vous pouvez vous abonner avec précision à des tables spécifiques, à des événements spécifiques (insertion, suppression, modification), voire filtrer les notifications selon des critères, le tout parfaitement intégré aux politiques de sécurité au niveau des lignes (Row Level Security) pour garantir que les utilisateurs ne reçoivent que les modifications auxquelles ils ont accès. +2. **Broadcast** : permet aux clients d'envoyer des messages temporaires à faible latence via des canaux (Channel). Idéal pour les salons de discussion, le suivi de curseurs en temps réel, la synchronisation d'état dans les jeux en ligne, etc. +3. **Presence** : utilisé pour suivre et synchroniser l'état des utilisateurs en ligne. Vous pouvez facilement implémenter des fonctionnalités comme « qui est en ligne » ou « X personnes consultent actuellement cette page », parfaitement adapté aux applications collaboratives. + +Nous détaillerons cette partie dans les projets avancés. + +### Paramètres du projet (Project Settings) + +Project Settings est la section de configuration avancée de votre projet Supabase, où vous pouvez gérer finement les ressources de calcul et configurer les paramètres basiques des différentes fonctionnalités. + +![](/zh-cn/stage-2/backend/database-supabase/images/image22.png) + +Au stade débutant, concentrons-nous sur deux sections clés. La première est Data API, où vous obtenez le « Supabase URL » clé -- un point de terminaison RESTful au format `https://xxx.supabase.co`, qui est l'« adresse d'entrée » pour toutes les opérations de création, lecture, mise à jour et suppression de données. Le frontend ou le serveur doit utiliser cette URL pour initialiser le client Supabase et établir la connexion à la base de données. + +![](/zh-cn/stage-2/backend/database-supabase/images/image23.png) + +L'autre point important est API Keys. Sélectionnez l'onglet « Legacy anon, service_role API keys ». La clé anon public est un identifiant essentiel pour les scénarios frontend, dont les permissions sont strictement limitées par les politiques RLS, n'autorisant l'accès qu'aux données que l'utilisateur est autorisé à consulter. La clé service_role est une « clé de haute permissions côté serveur », capable de contourner la sécurité au niveau des lignes pour exécuter des opérations de données en lot ou des configurations système. Elle ne doit jamais être partagée publiquement ; en cas de fuite, générez immédiatement une nouvelle clé et mettez à jour la configuration côté serveur. + +![](/zh-cn/stage-2/backend/database-supabase/images/image24.png) + +Les autres paramètres n'ont pas besoin d'être approfondis à ce stade. Vous pourrez les explorer au fur et à mesure de vos besoins avancés. + +## 2.1 Créer votre première table de données SQL + +Voici pour la présentation de l'interface Supabase. Passons maintenant aux opérations sur la base de données centrale de Supabase. + +Pour créer une table de données dans Supabase, il existe principalement deux méthodes courantes, au choix selon vos besoins : + +1. (Recommandé) Utiliser un grand modèle de langage pour générer des instructions SQL adaptées à Supabase, puis les coller et exécuter directement dans le **SQL Editor** (l'exécuteur SQL présenté précédemment) -- rapide et efficace. Nous détaillerons ce processus dans la section suivante. +2. Créer via des opérations visuelles : dans la barre latérale de gauche, trouvez le module Database, cliquez dessus, sélectionnez Tables dans la barre latérale, puis cliquez sur le bouton New table à droite pour créer une table via l'interface graphique. + +![](/zh-cn/stage-2/backend/database-supabase/images/image25.png) + +Il est à noter que le nom de la table et les types de données peuvent être spécifiés dans la section Columns située en dessous. + +![](/zh-cn/stage-2/backend/database-supabase/images/image26.png) + +Pour les bases de données relationnelles, un aspect important est les relations entre les tables. Vous trouverez ci-dessous la section `Foreign keys`, où vous pouvez créer les relations correspondantes : + +![](/zh-cn/stage-2/backend/database-supabase/images/image27.png) + +Un `Foreign key` exprime la relation d'association entre les tables : un ou plusieurs champs de la table actuelle (table enfant) dont les valeurs référencent la clé primaire d'une autre table (table parent). + +Par exemple, lors de la création d'une `table étudiants`, nous pouvons définir la clé étrangère ainsi : (la colonne `Numéro de classe` est une clé étrangère qui référence la colonne `Numéro de classe` de la `table classes`.) + +```sql +CREATE TABLE 学生表 ( + 学生学号 INT PRIMARY KEY, + 学生姓名 VARCHAR(50), + 所属班级编号 INT, + FOREIGN KEY (所属班级编号) REFERENCES 班级表(班级编号) +); +``` + +Pour être plus concret, observons visuellement la structure des tables correspondantes : + +Table des classes : +Cette table enregistre les informations de toutes les classes, chacune ayant un numéro de classe unique. Le numéro de classe est la clé primaire (Primary Key) de cette table, l'identifiant unique de chaque classe. + +| 班级编号 | 班级名称 | +| -------- | ---------- | +| 101 | 一年级一班 | +| 102 | 一年级二班 | + +Table des étudiants : +Cette table enregistre les informations de tous les étudiants. Chaque étudiant appartient à une classe spécifique, n'est-ce pas ? Comment savoir quel étudiant est dans quelle classe ? + +Nous pouvons ajouter une colonne dans la table des étudiants, appelée `Numéro de classe`. + +| 学生学号 | 学生姓名 | 所属班级编号 | +| -------- | -------- | ------------ | +| 2024001 | 张三 | 101 | +| 2024002 | 李四 | 102 | +| 2024003 | 王五 | 101 | + +Dans cet exemple, la colonne `Numéro de classe` de la table des étudiants est la clé étrangère (Foreign Key). + +Dans Supabase, après avoir cliqué sur « Add Foreign Key », vous pouvez directement sélectionner la table et la colonne associées. + +![](/zh-cn/stage-2/backend/database-supabase/images/image28.png) + +## 2.3 Présentation du SQL Editor et opérations de base sur la base de données + +Nous allons maintenant exécuter pas à pas une série de scripts SQL pour nous familiariser avec les opérations courantes de CRUD (création, lecture, mise à jour, suppression) en SQL. Vous pouvez copier le code de chaque étape dans le SQL Editor, l'exécuter et observer les résultats. + +Vous trouverez tous les fichiers SQL de test dans ce répertoire : + +https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos/tree/main/apps/sql-examples + +### **2.3.1 `CREATE` -- Créer la structure d'une table** + +L'instruction `CREATE TABLE` sert à définir le schéma (Schema) d'une nouvelle table, incluant ses colonnes (Columns), les types de données correspondants (Data Types) et les éventuelles contraintes (Constraints). En termes simples, cela crée une table de données. + +```sql +-- Step 1: Create the 'orders' table +-- This file is fully independent and creates a sample table for later steps. +CREATE TABLE IF NOT EXISTS orders ( + id serial PRIMARY KEY, + user_id int NOT NULL, -- User ID + status text NOT NULL, -- Order status (e.g. paid, pending) + amount numeric(10, 2) NOT NULL, -- Order total amount + details jsonb, -- Item and extra details as JSON + placed_at timestamptz DEFAULT now(), -- Order creation time + is_paid boolean DEFAULT false -- Paid flag +); + +-- Expected Output: +-- Orders table created if it did not exist. +-- No data inserted. (Querying returns zero rows for now.) +-- If table already exists, no error occurs. +``` + +Après une exécution réussie, le système indiquera que le script est terminé. Vous pourrez voir la table nouvellement créée dans le Table Editor : + +![](/zh-cn/stage-2/backend/database-supabase/images/image29.png) + +### **2.3.2 `INSERT` -- Insérer des données initiales** + +Une fois la structure de la table créée, l'étape suivante consiste à utiliser l'instruction `INSERT INTO` pour ajouter des lignes de données à la table. + +```sql +-- Step 2: Insert initial rows into the orders table +-- Provides realistic, varied data for demo/testing. All values are self-contained. +INSERT INTO orders (user_id, status, amount, details, placed_at, is_paid) VALUES + (2001, 'pending', 23.50, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '2 days', false), + (2002, 'paid', 50.00, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":2,"price":5.00}]}', now() - interval '1 day', true), + (2003, 'cancelled', 15.00, '{"items":[{"sku":"FRY001","name":"French Fries","qty":3,"price":5.00}], "reason":"Not available"}', now() - interval '45 days', false), + (2004, 'paid', 22.98, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":2,"price":9.99}], "promo":"SUMMER22"}', now() - interval '10 days', true), + (2005, 'pending', 18.75, '{"items":[{"sku":"SAL001","name":"Salad","qty":1,"price":6.75},{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '7 hours', false), + (2006, 'paid', 8.00, '{"items":[{"sku":"DRK002","name":"Cola","qty":2,"price":4.00}]}', now() - interval '3 hours', true), + (2007, 'refunded', 14.50, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99},{"sku":"FRY001","name":"French Fries","qty":1,"price":4.51}], "refund_reason":"Late delivery"}', now() - interval '15 days', false), + (2008, 'paid', 26.99, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":1,"price":6.99}]}', now() - interval '12 days', true), + (2009, 'pending', 9.99, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99}]}', now() - interval '30 minutes', false), + (2010, 'paid', 19.89, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00},{"sku":"DRK002","name":"Cola","qty":2,"price":3.95}]}', now() - interval '5 days', true), + (2011, 'cancelled', 0.00, '{"items":[], "reason":"User cancelled"}', now() - interval '2 days', false); + +-- Expected Output: +-- After running this script, SELECT * FROM orders will show about 11 rows with varied user_id, status, amount, details (JSON), placed_at, and is_paid fields. +-- For example: +-- | id | user_id | status | amount | is_paid | placed_at | +-- |----|---------|-----------|--------|---------|---------------------| +-- | 1 | 2001 | pending | 23.50 | false | 2025-10-28 13:40:00Z| +-- | 2 | 2002 | paid | 50.00 | true | ... | +-- |... | ... | ... | ... | ... | ... | +``` + +Après exécution, les données initiales ont été insérées dans la table. Vous pouvez accéder à l'interface du Table Editor, actualiser et voir les résultats, ou ouvrir une nouvelle fenêtre dans le SQL Editor et exécuter la requête `SELECT * FROM orders;` pour visualiser les résultats : + +![](/zh-cn/stage-2/backend/database-supabase/images/image30.png) + +### **2.3.3 `SELECT` -- Lire et interroger les données** + +L'instruction `SELECT` permet de récupérer des données depuis une table. En combinant différentes clauses, il est possible de filtrer, trier et formater les données avec précision. Voici quelques exemples à exécuter pas à pas : + +```sql +-- Step 3: SELECT query examples for the orders table + +-- Example 1: Select all fields for all orders +SELECT * FROM orders; +-- Expected Output: Returns all rows and fields. Columns: id, user_id, status, amount, details, placed_at, is_paid. + +-- Example 2: Select only pending orders +SELECT id, user_id, amount FROM orders WHERE status = 'pending'; +-- Expected Output: All rows with status 'pending'; columns: id, user_id, amount. + +-- Example 3: Select specific fields and filter by payment status +SELECT id, status, is_paid, amount FROM orders WHERE is_paid = true; +-- Expected Output: All rows where is_paid is true; columns: id, status, is_paid, amount. + +-- Example 4: Extract all item names from the details (JSON) for each order +SELECT id, details -> 'items' AS item_list FROM orders; +-- Expected Output: Each row shows id and an array from JSON with item details. +``` + +- **Exemple 1 :** Retourne toutes les lignes et colonnes de la table `orders`, similaire à la sortie de l'étape 2. +- **Exemple 2 :** Retourne uniquement les commandes au statut 'pending', avec les colonnes spécifiées : + +![](/zh-cn/stage-2/backend/database-supabase/images/image31.png) + +- **Exemple 3 :** Retourne uniquement les commandes payées, avec les colonnes spécifiées : + +| id | status | is_paid | amount | +| --- | ------ | ------- | ------ | +| 2 | paid | true | 50.00 | +| 4 | paid | true | 22.98 | +| 6 | paid | true | 8.00 | +| 8 | paid | true | 26.99 | +| 10 | paid | true | 19.89 | + +- **Exemple 4 :** Retourne l'`id` de chaque commande et le tableau `items` extrait du champ `details` : + +| id | item_list | +| --- | -------------------------------------------------------------------------------------------------------------------- | +| 1 | `[{"qty":1,"sku":"BGR001","name":"Beef Burger","price":12}]` | +| 2 | `[{"qty":2,"sku":"BGR002","name":"Chicken Burger","price":10},{"qty":2,"sku":"DRK001","name":"Lemonade","price":5}]` | +| 3 | `[{"qty":3,"sku":"FRY001","name":"French Fries","price":5}]` | +| ... | ... | + +### **2.3.4 `INSERT` -- Insérer un enregistrement unique** + +Dans la section 2.3.2, nous avons démontré l'insertion de données en lot au moment de l'initialisation. Voyons maintenant comment insérer une seule donnée. + +```sql +-- Step 4: INSERT a new order (single row) +INSERT INTO orders (user_id, status, amount, details, is_paid) +VALUES ( + 2012, 'paid', 9.99, + '{"items":[{"sku":"BGR002","name":"AIID Burger","qty":100,"price":1000}]}', + true +); +``` + +En interrogeant ensuite avec `SELECT * FROM orders;`, nous pouvons constater que la table orders est passée de 11 à 12 enregistrements. + +### **2.3.5 `UPDATE` -- Modifier des données existantes** + +L'instruction `UPDATE` permet de modifier les enregistrements existants dans une table. + +```sql +-- Step 5: UPDATE example +UPDATE orders SET status = 'paid', is_paid = true WHERE id = 1; +``` + +### **2.3.6 `DELETE` -- Supprimer des données** + +L'instruction `DELETE` permet de supprimer des enregistrements d'une table. + +```sql +-- Step 6: DELETE example +DELETE FROM orders WHERE placed_at < now() - interval '2 days'; +``` + +Avant l'exécution, vous pouvez d'abord exécuter `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';` pour visualiser les données qui seront supprimées. Après avoir exécuté la commande `DELETE`, réexécutez la même requête -- le résultat sera vide, confirmant que ces lignes ont été supprimées. + +## 2.4 Sécurité au niveau des lignes (RLS) + +Après avoir appris les opérations de base sur les bases de données, nous devons approfondir un concept central de sécurité des données : RLS (Row Level Security, sécurité au niveau des lignes). + +RLS permet aux développeurs de définir des politiques de sécurité fines sur les tables de la base de données, en contrôlant avec précision, selon l'identité de l'utilisateur, quelles lignes de données il peut consulter ou modifier. + +Lorsque vous activez RLS sur une table, toutes les requêtes de données déclenchent une vérification RLS : l'opération ne peut être exécutée que si elle passe avec succès au moins une politique de sécurité. + +Dans Supabase, RLS est profondément intégré au système d'authentification des utilisateurs. La fonction dédiée `auth.uid()` retourne directement l'identifiant unique de l'utilisateur connecté, permettant d'associer précisément les lignes de données à l'identité de l'utilisateur. + +![](/zh-cn/stage-2/backend/database-supabase/images/image32.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image33.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image34.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image35.png) + +# 3. Première application SQL + +Après avoir maîtrisé les opérations de base sur les bases de données et RLS, nous entamons la phase pratique avec le scénario « gestion des commandes d'un restaurant de hamburgers ». + +## 3.1 Cloner et exécuter le projet exemple Supabase + +Clonez le dépôt suivant : https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos + +![](/zh-cn/stage-2/backend/database-supabase/images/image36.png) + +## 3.2 Projet 1 -- CRUD du menu du restaurant de hamburgers + +Apprenez à initialiser la base de données via un script SQL et à connecter le projet frontend à Supabase. + +### Créer la base de données avec un script + +Exécutez le script `init.sql` du dossier `scripts` dans le SQL Editor. + +### Configurer la connexion à la base de données + +1. Via les variables d'environnement : créez un fichier `.env` avec `NEXT_PUBLIC_SUPABASE_URL` et `NEXT_PUBLIC_SUPABASE_ANON_KEY`. +2. Via la page du projet : cliquez sur le bouton Paramètres en haut à droite. + +![](/zh-cn/stage-2/backend/database-supabase/images/image37.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image38.png) + +### 📚 Exercice + +1. Essayez d'ajouter et de supprimer des éléments existants, observez les changements dans le Table Editor. + +## 3.4 Projet 2 -- Restaurant de hamburgers avec authentification des utilisateurs + +Le Projet 2 introduit l'authentification (Auth) et la gestion des permissions RLS, avec une page de connexion indépendante supportant « email + mot de passe ». + +![](/zh-cn/stage-2/backend/database-supabase/images/image39.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image40.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image41.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image42.png) + +### 📚 Exercice + +1. Récupérez le cadeau de bienvenue, effectuez un achat. +2. Trouvez la table des permissions utilisateur et modifiez-les en `admin`. +3. Localisez la table du portefeuille et augmentez le solde. + +# 4. Construire votre première application Supabase + +## 4.1 Processus standardisé pour connecter n'importe quelle application à Supabase + +1. Clarifiez les besoins et décrivez-les à l'IA. +2. Générez un script `init.sql` adapté à Supabase. +3. Restructurez le code pour interagir avec Supabase. +4. Configurez les paramètres de connexion et testez. + +## 4.2 Étude de cas : construire un jeu du serpent en ligne + +Pratiquez avec le projet `Project5-Supabase-Demos/apps_snakegame` : ajoutez un classement des scores avec connexion utilisateur. + +![](/zh-cn/stage-2/backend/database-supabase/images/image43.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image44.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image45.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image46.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image47.png) + +### 📚 Exercice + +1. Intégrez le système de gestion des utilisateurs dans le jeu du serpent. +2. Intégrez le système de gestion des utilisateurs dans votre propre application. + +# 5. Devenir un expert Supabase + +## 5.1 Pourquoi avons-nous choisi Supabase + +Supabase empaquette les capacités backend en services prêts à l'emploi (PostgreSQL, Realtime, Auth, Storage, Edge Functions, API auto-générées), permettant aux équipes de se concentrer sur le développement des fonctionnalités clés. Sa stratégie entièrement open source, avec support du déploiement privé, évite le verrouillage fournisseur. + +## 5.2 Connexion Google et GitHub + +Le projet `project-burger-shop-auth-advanced-supabase-6` démontre ces fonctionnalités avancées. + +![](/zh-cn/stage-2/backend/database-supabase/images/image48.png) + +### 5.2.1 Flux OAuth : comment fonctionne la connexion tierce + +Le protocole OAuth 2.0 permet à l'utilisateur d'autoriser notre application à accéder à ses informations publiques sur une plateforme tierce sans exposer son mot de passe. + +![](/zh-cn/stage-2/backend/database-supabase/images/image49.png) + +### 5.2.2 Configurer Google Cloud + +Créez un OAuth 2.0 Client ID dans Google Cloud Console. + +![](/zh-cn/stage-2/backend/database-supabase/images/image50.png) + +### 5.2.3 Configurer GitHub + +Enregistrez une application OAuth dans GitHub Developer Settings. + +![](/zh-cn/stage-2/backend/database-supabase/images/image51.png) + +### 5.2.4 Configurer les Providers dans Supabase + +Activez Google et GitHub dans Authentication > Providers. + +![](/zh-cn/stage-2/backend/database-supabase/images/image52.png) + +### 5.2.6 Réinitialisation du mot de passe + +Le projet inclut la réinitialisation de mot de passe via `supabase.auth.resetPasswordForEmail()`. + +![](/zh-cn/stage-2/backend/database-supabase/images/image53.png) + +## 5.3 Fonctionnalités temps réel + +Le projet `project-burger-shop-realtime-orders-3` illustre les capacités Realtime : Postgres Changes, Broadcast et Presence. + +![](/zh-cn/stage-2/backend/database-supabase/images/image54.png) + +### 5.3.1 Postgres Changes -- Modifications en temps réel + +Permet de s'abonner aux événements INSERT, UPDATE, DELETE sur des tables spécifiques. + +### 5.3.2 Broadcast & Presence + +- Presence : suivi des utilisateurs en ligne. +- Broadcast : messages temporaires à faible latence entre clients. + +## 5.4 Stockage (Storage) + +Le projet `project-burger-shop-storage-uploads-4` démontre le système de fichiers avec Supabase Storage. + +![](/zh-cn/stage-2/backend/database-supabase/images/image55.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image56.png) + +### 5.4.1 Buckets de stockage + +Les fichiers sont organisés en Buckets avec des politiques de sécurité. + +### 5.4.2 URLs de fichiers + +- Public URL : lien permanent pour les ressources publiques. +- Signed URL : lien temporaire sécurisé (recommandé en production). + +## 5.5 Edge Functions + +Le projet `project-burger-shop-edge-function-5` montre une conversation LLM en streaming via Edge Functions. + +![](/zh-cn/stage-2/backend/database-supabase/images/image57.png) + +### 5.5.1 Cas LLM Chat + +L'Edge Function agit comme proxy sécurisé entre le frontend et l'API OpenAI. + +![](/zh-cn/stage-2/backend/database-supabase/images/image58.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image59.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image60.png) + +## 5.6 Connexion Clerk + +Clerk est un outil d'authentification professionnelle. Le projet `project-burger-shop-auth-advanced-clerk-7` illustre son intégration avec Supabase. + +![](/zh-cn/stage-2/backend/database-supabase/images/image61.png) + +### 5.6.1 Créer une application Clerk + +Visitez [dashboard.clerk.com](https://dashboard.clerk.com/) pour créer votre application. + +![](/zh-cn/stage-2/backend/database-supabase/images/image62.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image63.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image64.png) + +### 5.6.2 Intégration native Supabase-Clerk + +Configurez l'intégration dans Clerk Dashboard > Integrations > Supabase. + +### 5.6.3 Synchronisation des utilisateurs via Webhook + +Utilisez un Edge Function Supabase pour recevoir les Webhooks Clerk et synchroniser les utilisateurs. + +![](/zh-cn/stage-2/backend/database-supabase/images/image65.png) + +### 5.6.4 Connexion tierce avec Clerk + +Clerk différencie les environnements de développement et de production pour les connexions sociales. + +# 6. De Supabase aux autres composants backend (avancé) + +Supabase couvre l'essentiel, mais chaque capacité (Auth, Storage, Edge Functions, Realtime, Database) a des alternatives spécialisées sur le marché. + +## Plateformes BaaS similaires + +| Plateforme | Type | Gratuité/Prix | Caractéristiques | +| --- | --- | --- | --- | +| Firebase | BaaS complet | Spark gratuit, Blaze à l'usage | Le plus mature, bonne documentation | +| Supabase | BaaS open source | 500Mo DB, 1Go Storage | Le plus proche de Firebase en SQL | +| Appwrite Cloud | BaaS open source | Basique gratuit | Moderne, auto-hébergeable | +| Nhost | Postgres + GraphQL | 1Go DB, 1Go Storage | Type « Supabase + Hasura » | +| AWS Amplify | BaaS AWS | Hosting + Cognito 10k MAU | Complet mais complexe | + +## Authentification (Auth) + +| Outil | Caractéristiques | Gratuité | +| --- | --- | --- | +| Firebase Auth | Google BaaS, 50k MAU | Spark gratuit | +| Auth0 (Okta) | Entreprise, SSO, MFA | 25k MAU gratuit | +| AWS Cognito | AWS natif | 10k MAU/mois | +| Logto | Open source | 50k MAU cloud gratuit | +| Keycloak | Open source IAM | Entièrement gratuit (auto-hébergé) | + +## Stockage de fichiers (Storage) + +| Plateforme | Type | Gratuité | +| --- | --- | --- | +| Amazon S3 | Stockage cloud AWS | 5Go, 20k requêtes/mois | +| Google Cloud Storage | Stockage cloud Google | 1Go via Firebase | +| MinIO | S3 compatible open source | Gratuit (auto-hébergé) | +| Cloudinary | Média + CDN | 25Go bande passante/mois | + +## Edge Functions + +| Plateforme | Caractéristiques | Gratuité | +| --- | --- | --- | +| Cloudflare Workers | Distribué mondial | 100k requêtes/jour | +| Vercel Edge Functions | Intégration Next.js | 1M appels/mois | +| Netlify Edge | Node.js + Edge | ~1M requêtes/mois | +| AWS Lambda@Edge | AWS Serverless | 1M requêtes/mois | + +## Temps réel (Realtime) + +| Plateforme | Caractéristiques | Gratuité | +| --- | --- | --- | +| Firebase Realtime DB | Google BaaS temps réel | 1Go stockage | +| Ably | Pub/sub temps réel | 6M messages/mois | +| Pusher Channels | WebSocket service | 200k messages/jour | +| Socket.IO (auto-hébergé) | Flexibilité maximale | Coût serveur | + +## Bases de données + +| Plateforme | Type | Gratuité | +| --- | --- | --- | +| Neon | Serverless PostgreSQL | 0.5Go, branches | +| Aiven PostgreSQL | PostgreSQL managé | 1Go stockage | +| CockroachDB Cloud | SQL distribué | 10Go stockage | +| TiDB Cloud | MySQL compatible distribué | 25Go max | +| MongoDB Atlas | NoSQL document | 0.5Go stockage | + +# Résumé + +Dans ce cours, nous avons systématiquement appris les concepts fondamentaux des bases de données, la définition et les opérations détaillées de Supabase. Vous pourrez vous référer à ce document à tout moment lors de vos projets ultérieurs. + +Rappelez-vous toujours un principe important : **Terminez d'abord, perfectionnez ensuite !** Nul besoin de viser la perfection du premier coup -- nous pouvons toujours nous améliorer par itérations successives. Bonne chance dans vos projets pratiques ! + +# 📚 Exercice final + +1. Développez une application intégrant un système de gestion des utilisateurs et une base de données. Idéalement avec davantage de fonctionnalités Supabase (Realtime / Cloud Storage / Edge Function). \ No newline at end of file diff --git a/docs/fr-fr/stage-2/backend/git-workflow/index.md b/docs/fr-fr/stage-2/backend/git-workflow/index.md new file mode 100644 index 0000000..bbd4980 --- /dev/null +++ b/docs/fr-fr/stage-2/backend/git-workflow/index.md @@ -0,0 +1,261 @@ +# Flux de travail Git et GitHub + +Dans les cours précédents, nous avons appris à écrire du code en utilisant des outils de vibe coding basés sur le web. Chaque conversation crée une nouvelle version du code. Mais réfléchissons à une question : si nous voulons revenir à une modification précédente, existe-t-il une méthode pratique ? Y a-t-il un outil capable d'enregistrer notre code à différents stades, nous permettant de basculer et de modifier librement entre les versions ? + +Pour répondre à ce besoin, les logiciels de contrôle de version sont apparus. Dans cet article, nous présenterons le programme de contrôle de version le plus célèbre — Git — ainsi que la meilleure plateforme d'hébergement de code — GitHub. Nous apprendrons à utiliser Git pour la gestion de code, comment récupérer le code d'autres personnes depuis GitHub, comment télécharger notre propre code, et comment collaborer avec d'autres sur des projets d'envergure. + +Que ce soit pour le suivi de versions de projets personnels, la synchronisation de code dans la collaboration en équipe, ou la contribution à la communauté open source, Git et GitHub sont des outils indispensables pour les développeurs modernes. En les maîtrisant, vous serez capable de gérer votre code plus efficacement, de créer des points de contrôle selon vos besoins, de naviguer librement entre les différentes étapes du code, et de traiter facilement tout, de la modification d'un seul fichier au développement de projets d'envergure — rendant chaque itération de code contrôlable et traçable. + +> 💡 **Prérequis** +> +> Avant d'apprendre Git, il est recommandé de connaître les concepts suivants : +> - [Qu'est-ce que le terminal/la ligne de commande](/fr-fr/appendix/2-development-tools/command-line-shell) - Apprendre à interagir avec l'ordinateur via la ligne de commande +> - [Qu'est-ce que Git](/fr-fr/appendix/2-development-tools/git-version-control) - Comprendre les concepts clés du système de contrôle de version Git +> +> Cet article se concentrera sur le flux de travail GitHub et les opérations pratiques. Les connaissances de base mentionnées ci-dessus sont disponibles via les liens de l'annexe. + +# Démarrage rapide avec Git + +Avant de commencer à utiliser Git, assurez-vous d'avoir lu le contenu de l'annexe sur la [ligne de commande](/fr-fr/appendix/2-development-tools/command-line-shell) et les [bases de Git](/fr-fr/appendix/2-development-tools/git-version-control). Cet article suppose que vous possédez déjà ces connaissances de base et abordera directement l'installation, la configuration de Git et l'utilisation de GitHub pour la collaboration. + +## Comment installer Git + +Nous démontrerons trois méthodes d'installation de Git sur différents systèmes d'exploitation. Veuillez suivre les instructions correspondant à votre version du système : + +### Windows + +1. Allez sur la [page de téléchargement officielle de Git](https://git-scm.com/download/win) et téléchargez le programme d'installation adapté à votre système : [Installateur](https://github.com/git-for-windows/git/releases/download/v2.51.0.windows.1/Git-2.51.0-64-bit.exe). Par défaut, l'installateur x64 est recommandé. +2. Double-cliquez sur le programme d'installation et suivez les instructions de l'assistant d'installation : + ![](/zh-cn/stage-2/backend/git-workflow/images/image5.png) + 1. Il est recommandé de conserver les options par défaut. Si vous souhaitez personnaliser, notez les points suivants (dans la plupart des cas, vous pouvez simplement cliquer sur « Next ») : + - Choisir l'éditeur par défaut utilisé par Git : sélectionnez votre éditeur préféré (comme VS Code). Vous pouvez garder le premier choix par défaut, Vim (un éditeur de texte), ou choisir l'option « Visual Studio Code as Git's default editor » (nécessite l'installation préalable de VS Code). Vous pouvez garder la sélection par défaut et cliquer « Next » pour continuer. + ![](/zh-cn/stage-2/backend/git-workflow/images/image6.png) + - Choisir comment utiliser Git : ces trois options contrôlent l'accessibilité de Git sur le système. L'option 2 est recommandée (« from command line and 3rd-party software ») — elle ajoute les outils Git de base au PATH, vous permettant d'utiliser Git dans Git Bash, l'invite de commandes, PowerShell et les IDE, sans surcharger le système. + ![](/zh-cn/stage-2/backend/git-workflow/images/image7.png) + +3. Après l'installation, faites un clic droit sur le bureau. Si vous voyez « Git Bash Here » dans le menu, l'installation a réussi. + +![](/zh-cn/stage-2/backend/git-workflow/images/image8.png) + +### MacOS + +Pour macOS, vous pouvez d'abord taper `git --version` dans le terminal pour vérifier si Git est déjà installé. Si ce n'est pas le cas, le système vous invitera à l'installer — suivez simplement les instructions. + +1. Méthode 1 : Installation via Homebrew + Si vous avez installé [Homebrew](https://brew.sh/) (le gestionnaire de paquets Mac), ouvrez le terminal et tapez + ```bash + brew install git + ``` +2. Méthode 2 : (Recommandée) Installation via Xcode : https://developer.apple.com/xcode/ , Xcode inclut Git. Après l'installation, suivez simplement les instructions. + +### Linux + +La plupart des distributions Linux peuvent installer Git via leur gestionnaire de paquets : + +- Ubuntu/Debian : + +```bash +sudo apt update +sudo apt install git +``` + +- CentOS/RHEL : + +```bash +sudo yum install git +``` + +- Vérification de l'installation : tapez `git --version` dans le terminal. Si le numéro de version s'affiche, l'installation a réussi. + +## Initialisation de Git + +Après avoir installé Git, vous devez d'abord configurer vos informations utilisateur — c'est l'étape fondamentale pour utiliser le contrôle de version Git. Exécutez les commandes suivantes dans le terminal (remplacez le contenu entre crochets par vos propres informations) : + +```bash +# Définir le nom d'utilisateur global (apparaîtra dans les enregistrements de commit) +git config --global user.name "Your Name" + +# Définir l'e-mail global (il est recommandé d'utiliser l'e-mail enregistré sur GitHub/GitLab) +git config --global user.email "your.email@example.com" +``` + +Git intègrera ces informations dans chaque enregistrement de commit, comme « informations d'auteur » de chaque modification. Lorsque vous consultez l'historique des versions (par exemple avec `git log`), vous pouvez clairement voir qui a modifié chaque ligne de code, facilitant la traçabilité des responsabilités et la communication. Dans les projets collaboratifs, des informations d'identité unifiées permettent aux membres de l'équipe d'identifier rapidement qui a effectué quelles modifications, améliorant l'efficacité de collaboration (par exemple, trouver le développeur concerné via les enregistrements de commit pour discuter d'un problème). + +Vous pouvez vérifier vos informations de configuration Git actuelles en tapant `git config --list` dans la ligne de commande, pour confirmer que la configuration a réussi. + +# Qu'est-ce que GitHub + +GitHub est une plateforme d'hébergement de code basée sur Git. Elle offre non seulement un stockage distant pour les dépôts Git, mais inclut également des outils de collaboration (comme Issues, Pull Requests, Projects) qui facilitent le partage de code et la collaboration entre développeurs. En bref, Git est un outil de contrôle de version local, tandis que GitHub est un « cloud de dépôts de code + communauté de collaboration » distant. + +GitHub n'est pas seulement la plus grande plateforme d'hébergement de code au monde, c'est aussi la communauté open source la plus active et la plus influente au niveau mondial. L'idée centrale de l'« open source » est que n'importe qui peut télécharger et exécuter le code source du logiciel. Ce modèle permet à des personnes du monde entier d'examiner le code des autres, de le modifier ou de créer de nouveaux projets à partir de celui-ci. Par exemple, vous pouvez trouver sur GitHub toutes sortes de tutoriels d'apprentissage ainsi que le code source complet de frameworks d'entraînement de modèles GPT (comme PyTorch). Chaque jour, d'innombrables personnes collaborent à l'échelle mondiale pour examiner et améliorer le code. + +![](/zh-cn/stage-2/backend/git-workflow/images/image9.png) + +De nombreuses grandes entreprises publient en open source leurs programmes ou tutoriels sur GitHub pour obtenir un avantage concurrentiel dans l'industrie — ce qui peut aussi être vu comme une forme de publicité. Dans la communauté GitHub, le nombre d'« étoiles (stars) » obtenues par un projet est l'indicateur principal de sa valeur ; plus un projet ou une organisation possède d'étoiles, plus sa crédibilité et son influence sont grandes. + +![](/zh-cn/stage-2/backend/git-workflow/images/image10.png) + +Dans notre cours, les ressources de support et les devoirs seront également téléchargés sur un dépôt GitHub dédié. À travers le processus de soumission des devoirs, vous vous familiariserez progressivement avec l'utilisation de GitHub, posant ainsi des bases solides pour le contrôle de version dans le développement futur d'applications. + +## Créer un compte GitHub + +1. Visitez le [site officiel de GitHub](https://github.com/) et cliquez sur « Sign up » en haut à droite. + ![](/zh-cn/stage-2/backend/git-workflow/images/image11.png) +2. Entrez votre adresse e-mail (il est recommandé d'utiliser une adresse courante, car les vérifications et notifications y seront envoyées), définissez un mot de passe (doit contenir des lettres, des chiffres et des caractères spéciaux). +3. Complétez la vérification humaine, vérifiez votre e-mail selon les instructions, et votre compte sera créé. + +## Créer votre premier dépôt sur GitHub + +Ensuite, nous allons créer notre premier dossier de stockage, aussi appelé dépôt ou « repo ». + +![](/zh-cn/stage-2/backend/git-workflow/images/image12.png)![](/zh-cn/stage-2/backend/git-workflow/images/image13.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image14.png) + +1. Repository name : le nom du dépôt visible par les autres. +2. Description : une description détaillée du dépôt. +3. Choose visibility : pour un dépôt personnel, si vous le définissez comme privé, seuls vous et les personnes spécialement invitées pouvez le voir. Si vous le définissez comme public, tout le monde peut le voir. + Pour les dépôts d'organisation, si c'est Privé, seuls les membres de l'organisation peuvent le voir. + Si c'est Public, les personnes extérieures à l'organisation peuvent également le voir. +4. README : il est d'usage que chaque dépôt possède un fichier README. Vous pouvez le considérer comme la présentation complète du dépôt, incluant les instructions d'utilisation, la liste des fichiers et les méthodes de fonctionnement. +5. Add .gitignore and license : + 1. Le fichier .gitignore indique à Git d'ignorer certains dossiers ou fichiers lors du téléchargement vers GitHub, ils ne seront donc pas suivis ni ajoutés à la zone de staging. Cela est utile pour les fichiers de test temporaires, les packages de dépendances ou les fichiers volumineux. Une fois spécifiés, ces fichiers ne seront plus suivis. + 2. License fait référence au type de licence open source que vous choisissez. Différentes licences détaillent si d'autres personnes peuvent utiliser votre code à des fins commerciales, et incluent d'autres clauses et conditions. + +Il est recommandé de cocher « Add README », de définir la visibilité du dépôt sur « Private », de remplir le nom et la description du dépôt selon vos préférences, puis de cliquer sur « Create repository » pour terminer la création de votre premier dépôt distant. + +![](/zh-cn/stage-2/backend/git-workflow/images/image15.png) + +Vous disposerez ensuite d'un dépôt propre sans fichiers supplémentaires. Vous pouvez maintenant commencer à télécharger des fichiers. + +![](/zh-cn/stage-2/backend/git-workflow/images/image16.png) + +La commande pour obtenir le dépôt est `git clone`, mais elle nécessite l'adresse du dépôt. Vous pouvez trouver cette adresse en cliquant sur le bouton vert « Code », où vous verrez les options HTTPS et SSH. En général, vous pouvez utiliser l'une ou l'autre méthode pour télécharger le dépôt sur votre machine locale (c'est la seule façon de modifier et de télécharger des fichiers). + +![](/zh-cn/stage-2/backend/git-workflow/images/image17.png) + +En règle générale, le clonage via HTTP est adapté au téléchargement temporaire et au test des dépôts d'autres personnes, mais n'est pas recommandé pour votre propre développement. Pour une meilleure expérience d'apprentissage, vous devriez d'abord configurer l'authentification SSH. + +## Lier le SSH local + +Dans GitHub, la « liaison du protocole SSH » signifie essentiellement associer la clé publique SSH de votre appareil local à votre compte GitHub, permettant à GitHub d'identifier votre appareil via le protocole SSH. Cela vous permet d'opérer de manière sécurisée sur les dépôts distants (cloner, pousser ou tirer du code) sans avoir besoin de mot de passe. + +En termes simples : c'est comme donner à votre appareil un « badge d'accès GitHub dédié ». Une fois lié, lorsque votre appareil accède aux dépôts GitHub via le protocole SSH, GitHub vérifie ce « badge d'accès » (votre clé publique SSH). Une fois confirmé comme appareil autorisé, vous pouvez opérer directement — sans avoir à saisir votre nom d'utilisateur et votre mot de passe à chaque fois. + +> 💡 Qu'est-ce que SSH + +### Pourquoi la liaison du protocole SSH est-elle nécessaire ? + +GitHub prend en charge deux principaux protocoles d'opération des dépôts : le protocole HTTPS et le protocole SSH : + +- Protocole HTTPS : chaque opération (comme push) nécessite de saisir le nom d'utilisateur et le mot de passe GitHub (ou un Personal Access Token PAT). Le processus de vérification est fastidieux et comporte un risque de fuite de mot de passe. +- Protocole SSH : l'authentification est effectuée via une « paire de clés », il n'est donc pas nécessaire de saisir le mot de passe à plusieurs reprises, et la transmission chiffrée est plus sécurisée. + +La « liaison du protocole SSH » est une étape préalable à l'activation de l'authentification SSH GitHub — ce n'est qu'après avoir « lié » votre clé publique SSH locale à votre compte GitHub que GitHub pourra identifier votre appareil et autoriser les opérations SSH sur les dépôts. + +### Logique centrale de la « liaison » : le rôle de la paire de clés SSH + +L'authentification SSH repose sur une paire de clés (clé publique + clé privée), qui sont des fichiers chiffrés correspondants. Après les avoir générées, vous devez fournir la « clé publique » à GitHub (la « liaison »), tandis que la « clé privée » reste sur votre appareil local : + +1. Clé privée : stockée dans un répertoire spécifié de votre appareil local (généralement ~/.ssh/), agissant comme « votre clé personnelle » — à ne jamais partager avec qui que ce soit. +2. Clé publique : c'est une « serrure » partageable publiquement — vous devez la copier dans la « liste des clés SSH » de votre compte GitHub (l'opération de « liaison »). + +Lorsque vous opérez sur un dépôt GitHub via SSH (par exemple `git push git@github.com:xxx/xxx.git`) : + +- Votre appareil local utilise la clé privée pour chiffrer la « requête d'opération » et l'envoie à GitHub ; +- Après réception de la requête, GitHub tente de la déchiffrer avec la clé publique que vous avez précédemment liée ; +- Si le déchiffrement réussit, votre appareil est confirmé comme autorisé et l'opération est permise ; sinon, l'accès est refusé. + +### Étapes spécifiques de la « liaison » (flux principal) + +Une fois que vous avez compris le principe, l'opération pratique est simple — le cœur est « générer une paire de clés → télécharger la clé publique sur GitHub » : + +1. Générer une paire de clés SSH localement + 1. Utiliser Trae pour obtenir la clé publique (recommandé) + Prompt : `Help me create the SSH key needed for GitHub login. My email is your_email@gmail.com , Please return the public key for me to copy` + + ![](/zh-cn/stage-2/backend/git-workflow/images/image18.png) + + Après avoir entré le prompt, vous devez également appuyer sur la touche Entrée dans le terminal de gauche, sinon la commande restera en attente sans s'exécuter. Comme Trae ne peut pas exécuter de jugements conditionnels pour vous, il suffit d'appuyer sur Entrée jusqu'à ce que le processus se termine. + + Enfin, vous verrez que Trae à droite a renvoyé la clé publique qu'il a lue. Il vous suffit de la copier et de vous préparer à la coller à l'étape suivante. + + ![](/zh-cn/stage-2/backend/git-workflow/images/image19.png) 2. Obtenir manuellement la clé publique + Ouvrez votre terminal local (Git Bash ou PowerShell sur Windows ; Terminal sur macOS/Linux) et entrez la commande suivante (remplacez your_email@example.com par l'e-mail utilisé pour votre inscription GitHub) : + + ```bash + ssh-keygen -t ed25519 -C "your_email@example.com" + ``` + + 1. Appuyez sur Entrée pour accepter les valeurs par défaut (chemin de fichier par défaut, sans phrase de passe, ou définissez-en une si nécessaire). Cela générera deux fichiers dans le répertoire ~/.ssh/ : + - id_ed25519 : clé privée (stockée localement, **à ne jamais partager**) ; + - id_ed25519.pub : clé publique (à télécharger sur GitHub). + +2. « Lier » la clé publique à votre compte GitHub + +C'est l'étape centrale de la liaison — ajouter la clé publique locale à la « liste des clés SSH » de votre compte GitHub : + +1. Copier le contenu de la clé publique : + 1. Via Trae : + 2. Windows : ouvrez C:\Users\\.ssh\id_ed25519.pub avec le Bloc-notes et copiez tout son contenu ; + 3. macOS/Linux : exécutez `cat ~/.ssh/id_ed25519.pub` dans le terminal et copiez toute la sortie (depuis le début SSH-ed25519 jusqu'à l'e-mail à la fin). +2. Connectez-vous à GitHub et accédez à la page « SSH Key Management » : + 1. Cliquez sur l'avatar en haut à droite → Settings → menu latéral SSH and GPG keys → cliquez sur New SSH key. + ![](/zh-cn/stage-2/backend/git-workflow/images/image20.png)![](/zh-cn/stage-2/backend/git-workflow/images/image21.png) + 2. Saisissez n'importe quel titre (par exemple, SSH de votre ordinateur local), puis collez la clé publique SSH que vous venez d'obtenir. + +![](/zh-cn/stage-2/backend/git-workflow/images/image22.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image23.png) + +3. Vérifier que la liaison a réussi + +Tapez la commande suivante dans le terminal (**Trae peut également effectuer les opérations suivantes**) pour tester si GitHub peut identifier votre appareil : + +```bash +ssh -T git@github.com +``` + +- Si vous voyez un message du type « Hi [votre nom d'utilisateur GitHub] ! You've successfully authenticated... », cela signifie que votre clé a été liée avec succès ; +- Si vous rencontrez une erreur, c'est généralement parce que la clé publique a été copiée de manière incomplète, que les permissions de la clé privée sont trop larges (votre répertoire ~/.ssh/ local ne doit être accessible qu'en lecture/écriture pour vous), etc. Vérifiez ces points si nécessaire. + +### Remarques importantes + +Si vous avez plusieurs appareils (comme un ordinateur portable et un ordinateur de bureau), vous devez générer une paire de clés SSH distincte pour chaque appareil et lier chaque clé publique au même compte GitHub — chaque appareil a son propre « badge d'accès ». + +Ne partagez jamais votre clé privée (ne la téléchargez pas sur GitHub et ne la partagez pas avec d'autres), sinon quelqu'un pourrait se faire passer pour vous et opérer sur vos dépôts. Si la clé privée est compromise, supprimez immédiatement la clé publique correspondante de GitHub et générez une nouvelle paire de clés. + +Après avoir lié SSH, utilisez les adresses de dépôt au format SSH (par exemple `git@github.com:username/repository.git`) pour vos opérations, et non le format HTTPS (par exemple `https://github.com/username/repository.git`). Si vous avez précédemment cloné le dépôt via HTTPS, vous pouvez changer de protocole avec `git remote set-url origin `. + +# Utiliser Trae pour les opérations GitHub + +Nous avons expliqué ce qu'est Git, ce qu'est GitHub, ce qu'est SSH et comment le configurer. Vous pouvez maintenant utiliser librement Trae pour effectuer des opérations Git. Commençons par apprendre à cloner un dépôt distant sur votre machine locale. + +## Git clone : télécharger un dépôt existant + +Vous pouvez directement lui indiquer l'adresse du dépôt que vous souhaitez cloner + +![](/zh-cn/stage-2/backend/git-workflow/images/image24.png) + +## Git pull : récupérer les mises à jour du dépôt distant + +Avant chaque mise à jour du dépôt, comme il peut être maintenu par plusieurs personnes, vous devez d'abord tirer les dernières modifications. Ensuite, vous pouvez modifier et pousser les fichiers. + +**N'oubliez pas d'inclure le nom du dossier et son chemin relatif ou absolu, pour éviter de pousser vers le mauvais dépôt.** + +prompt : `Help me pull this repository AIID-TEST in ./AIID-TEST.` + +## Git commit & Git push : staging des mises à jour et push vers GitHub + +Une fois que tout est prêt, vous pouvez essayer de modifier les fichiers locaux, d'ajouter ou de supprimer des éléments dans le dossier. Ensuite, demandez à Trae de détecter les modifications et de vous aider à les pousser vers GitHub. + +prompt : `I finished. Commit and push to the repository AIID-TEST in ./AIID-TEST.` + +![](/zh-cn/stage-2/backend/git-workflow/images/image25.png) + +Le push a réussi. Vous pouvez maintenant voir le contenu mis à jour sur GitHub. + +# Ressources de référence + +- Pro Git book https://git-scm.com/book/en/v2 +- GitHub Docs https://docs.github.com/en diff --git a/docs/fr-fr/stage-2/backend/modern-cli/index.md b/docs/fr-fr/stage-2/backend/modern-cli/index.md new file mode 100644 index 0000000..681e786 --- /dev/null +++ b/docs/fr-fr/stage-2/backend/modern-cli/index.md @@ -0,0 +1,800 @@ +# Outils de programmation IA en ligne de commande (CLI) + +Dans ce tutoriel, nous présenterons les agents de programmation IA qui s'exécutent directement dans la ligne de commande. Contrairement aux agents intégrés dans Trae ou Cursor que vous avez déjà étudiés, les outils CLI de programmation IA fonctionnent uniquement dans le terminal. Par rapport aux agents intégrés aux IDE IA, ils disposent généralement d'une fenêtre de contexte plus longue, d'une vitesse d'appel d'outils plus rapide et sont compatibles avec un plus grand nombre de modèles de langage. Dans les pratiques les plus récentes de l'AI Vibe Coding, nous privilégions souvent les outils CLI de programmation IA plutôt que les agents de codage intégrés à l'IDE. + +## En partant du CLI + +Vous vous souvenez du CLI que nous avons présenté précédemment ? Le CLI (Command Line Interface) désigne l'utilisation d'un terminal ou d'une invite de commande pour interagir avec des logiciels via des commandes en texte brut, plutôt que par le biais d'une interface graphique (GUI -- que vous pouvez comprendre comme les interfaces avec des boutons sur ordinateur ou smartphone, où il suffit de cliquer sans taper de commandes). + +> Sous Windows, les terminaux les plus courants sont l'« Invite de commandes (cmd) » et « PowerShell ». Vous pouvez lancer ces programmes en tapant « cmd » ou « powershell » dans la barre de recherche ou la boîte de dialogue Exécuter. + +![](/zh-cn/stage-2/backend/modern-cli/images/image1.png)![](/zh-cn/stage-2/backend/modern-cli/images/image2.png) + +Le CLI est naturellement adapté aux opérations par commandes textuelles. Parmi une petite minorité de geeks (passionnés de programmation en quête de performances extrêmes), le CLI est même plus populaire que le GUI -- ils souhaitent réaliser toutes les opérations au clavier, estimant que l'utilisation de la souris ralentit leur efficacité de codage. + +Dans l'industrie, le CLI est souvent la forme d'interface la plus courante, car le GUI nécessite que le système d'exploitation génère des interfaces supplémentaires et gère les fenêtres, ce qui exige davantage de ressources informatiques ; le CLI, en revanche, se contente de transmettre les commandes reçues au système pour exécution. Ainsi, lors de la connexion à des clusters de serveurs à grande échelle, nous interagissons généralement uniquement via le CLI. + +![](/zh-cn/stage-2/backend/modern-cli/images/image3.png) + +Pour beaucoup d'étudiants sans expérience en CLI, ces opérations peuvent sembler complexes, avec trop de commandes à retenir, et l'on peut même craindre de « casser son ordinateur par erreur ». Rassurez-vous. Vous souvenez-vous que dans les tutoriels précédents, nous demandions souvent à Trae d'effectuer diverses opérations de base ? Ici aussi, vous pouvez reprendre exactement la même approche -- nous pouvons laisser l'outil de programmation CLI effectuer toutes les opérations à notre place : naviguer dans les dossiers, rechercher et traiter des fichiers, exécuter ou copier des projets open source, etc. L'ensemble du processus peut être réalisé par la conversation avec l'outil de programmation IA en CLI. + +## En quoi diffère-t-il des IDE IA ? + +Nous pouvons comparer les outils de programmation IA en CLI avec z.ai et Trae que nous avons déjà étudiés. En un sens, un outil de programmation IA en CLI peut être considéré comme une version spéciale de z.ai : ils nécessitent tous deux une simple interface de conversation pour exécuter automatiquement toutes les opérations requises (parfois vous devrez ouvrir manuellement le navigateur pour voir le résultat final). Et si l'on compare avec les IDE IA, l'outil de programmation IA en CLI peut être vu comme le module Agent de l'IDE -- c'est-à-dire la zone de conversation dans le panneau latéral. + +![](/zh-cn/stage-2/backend/modern-cli/images/image4.png)![](/zh-cn/stage-2/backend/modern-cli/images/image5.png) + +Cependant, comme les différents IDE IA implémentent les agents de manières différentes, avec des capacités très variables, les résultats de programmation IA sont souvent instables. C'est pourquoi les outils de programmation IA en CLI sont généralement développés directement par de grandes entreprises technologiques, telles qu'Anthropic (derrière Claude) ou OpenAI (derrière ChatGPT). + +Par rapport aux autres agents de programmation IA, l'utilisation directe de ces produits de grands groupes est souvent une pratique plus avantageuse, d'autant plus que Claude Code est lui-même conçu pour servir l'équipe de développement interne d'Anthropic, pensé dès l'origine pour « répondre aux véritables besoins des ingénieurs ». + +Pour une comparaison plus visuelle, examinons les différences entre Claude Code et un agent d'IDE IA typique (ici Cursor) : + +| Fonctionnalité | Claude Code | Cursor | Avantage | +| ----------------- | ------------- | --------------- | ----------- | +| Exécution automatique de tâches | ✅ Excellent | ❌ Capacités limitées | Claude Code | +| Intégration IDE | ❌ Ligne de commande uniquement | ✅ VS Code natif | Cursor | +| Complétion de code en temps réel | ❌ Non | ✅ Excellente expérience | Cursor | +| Opérations multi-fichiers | ✅ Excellent | ⚠️ Correct | Claude Code | +| Opérations GitHub intégrées | ✅ Commit direct | ⚠️ Manipulation manuelle | Claude Code | +| Courbe d'apprentissage | ⚠️ Moyenne | ✅ Prise en main facile | Cursor | +| Longueur du contexte | ✅ Très long | ⚠️ Correct | Claude Code | +| Assistance au débogage | ✅ Automatisée | ⚠️ Souvent manuel | Claude Code | + +Source du tableau : + +En résumé, les outils de programmation IA en CLI peuvent généralement : + +- Prendre en charge des conversations continues plus longues (ils peuvent même « travailler toute une journée » pour vous). +- Offrir une fenêtre de contexte plus étendue (vous n'aurez plus besoin de dire aussi souvent « continue »). +- Répondre plus rapidement (ils peuvent se connecter à davantage d'API de modèles personnalisés). + +Pour les opérations liées au codage, ils sont généralement plus intelligents et plus stables que la plupart des agents intégrés aux IDE. + +## Outils de programmation IA en CLI les plus courants + +Bien qu'il existe de nombreuses implémentations open source, dans la pratique nous ne recommandons que deux grandes catégories d'outils de programmation IA en CLI, comme « combinaison de premier choix ». Vous pouvez choisir celui qui vous convient le mieux selon vos habitudes, et nous vous recommandons vivement d'essayer les deux avant de choisir celui qui vous correspond le mieux. + +- Codex utilise GPT-5, avec des capacités globales plus puissantes ; +- Claude Code via l'API GLM 4.6 offre une expérience proche de Claude 4, mais à un prix plus abordable. +- OpenCode permet de changer et combiner librement les modèles, propose des modèles gratuits et offre un meilleur contrôle des coûts. + +Cependant, lequel est le plus efficace dans un projet réel ne peut être jugé que par des tests pratiques. Maîtriser plusieurs outils de programmation IA est toujours bénéfique : une fois compétent, vous pourrez passer aisément de Claude Code à Codex ou Trae selon les scénarios. Si après plusieurs essais un outil s'avère médiocre, passez simplement à un autre outil ou modèle. + +Par ailleurs, les versions des modèles évoluent très rapidement. Nous vous conseillons de privilégier la solution offrant le meilleur rapport qualité/prix (efficacité / coût). + +### Claude Code + +Claude Code est un outil de programmation IA développé par Anthropic, basé sur les capacités du grand modèle Claude. Son principal espace d'interaction est le terminal, et il prend également en charge une utilisation en tant qu'extension VS Code. Comme les agents intégrés aux IDE IA, il peut analyser en profondeur le dépôt de code du développeur et accomplir des tâches de développement de bout en bout via des instructions en langage naturel -- y compris l'édition de code, la correction de bugs, l'exécution et la réparation de tests, la gestion des flux Git (par exemple la résolution de conflits de fusion, la création de PR), l'explication de code complexe, l'exécution de commandes terminal, etc. + +![](/zh-cn/stage-2/backend/modern-cli/images/image6.png) + +Les avantages de Claude Code se manifestent principalement par : une fenêtre de contexte extrêmement longue (pouvant traiter des fichiers complets voire de petits projets), la capacité à clarifier proactivement les exigences ambiguës, la planification et l'allocation automatiques des tâches d'exécution, ainsi qu'une compréhension et une explication approfondies du contenu de l'ensemble du dépôt de code. Par rapport aux agents IDE classiques, il est mieux adapté à un flux de développement « immersive vibe coding ». + +En pratique, vous pouvez lui demander via des instructions conversationnelles de créer un nouveau projet, d'exécuter des opérations CLI (par exemple organiser des dossiers, renommer des fichiers en lot, déployer des projets open source), de configurer l'environnement de développement (par exemple installer et déboguer un environnement Python). Si un extrait de code vous semble difficile à comprendre ou si la structure d'un répertoire n'est pas claire, vous pouvez également demander directement à Claude Code de générer un document d'analyse structuré, ou d'expliquer étape par étape un contenu spécifique. + +![](/zh-cn/stage-2/backend/modern-cli/images/image7.png)![](/zh-cn/stage-2/backend/modern-cli/images/image8.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image9.png)![](/zh-cn/stage-2/backend/modern-cli/images/image10.png) + +Si vous souhaitez apprendre Claude Code de manière systématique, vous pouvez consulter le cours conjointement proposé par Andrew Ng et Anthropic : + + +Nous allons maintenant apprendre à utiliser Claude Code. Comme le coût d'utilisation directe du Claude Code officiel est souvent très élevé (comme le montre l'image ci-dessous), nous utiliserons plutôt des plateformes API d'autres grands modèles compatibles avec le protocole Claude Code. + +![](/zh-cn/stage-2/backend/modern-cli/images/image11.png) + +Vous devez apprendre les différentes approches suivantes (idéalement toutes les essayer), puis choisir celle qui vous convient le mieux comme parcours principal. + +La première méthode consiste à utiliser directement une API « compatible avec l'interface Anthropic ». Avec la popularité de Claude Code, de plus en plus de fournisseurs de grands modèles commencent à prendre en charge le style d'appel Anthropic. Les fournisseurs courants incluent GLM, Kimi, DeepSeek et Siliconflow, qui proposent tous des API compatibles. Nous détaillerons la configuration spécifique plus loin. + +Il convient de noter que Claude Code consomme généralement beaucoup de tokens. Si vous craignez des coûts d'appel API trop élevés, vous pouvez envisager l'abonnement mensuel GLM (environ 20 yuans/mois) pour maîtriser les coûts. Si vous souhaitez d'abord évaluer les dépenses réelles, vous pouvez commencer par recharger 10 yuans pour des tests à petite échelle. + +Une autre approche consiste à utiliser le projet « Claude Code Route ». Il s'agit d'un outil open source qui prend en charge toutes les interfaces d'appel API courantes, vous permet de configurer finement le modèle à utiliser selon les scénarios, et prend en charge la connexion à des grands modèles déployés localement. Cependant, comme la configuration de cette solution est relativement complexe, nous vous recommandons de commencer par la première méthode. + +#### Utiliser GLM de Zhipu comme backend (recommandé) + +GLM (General Language Model) est une série de grands modèles de langage développée de manière autonome par Zhipu AI. GLM-4.6 est la version la plus récente de la série GLM, dont l'atout majeur réside dans ses excellentes performances en matière de code (comparable à Claude Sonnet 4 sur les benchmarks publics et les tâches réelles, se positionnant dans le premier rang en Chine). + +![](/zh-cn/stage-2/backend/modern-cli/images/image12.png) + +Il a également étendu sa fenêtre de contexte à 200K, permettant de traiter plus sereinement les textes longs et les bases de code volumineuses, tout en renforçant les capacités de raisonnement et d'appel d'outils, atteignant un bon équilibre entre performances et coûts. + +![](/zh-cn/stage-2/backend/modern-cli/images/image13.png) + +Avant de connecter GLM, nous devons d'abord installer Claude Code. + +Si vous trouvez les étapes d'installation en ligne de commande fastidieuses ou rencontrez des erreurs, vous pouvez demander directement à l'agent de Trae de vous aider. + +```python +# Installer Claude Code +npm install -g @anthropic-ai/claude-code + +# Accéder à votre projet +cd your-awesome-project + +# Lancer Claude Code +claude + +# Appuyer sur Ctrl+C pour quitter Claude +``` + +Ensuite, nous devons modifier l'adresse de requête API par défaut de Claude Code pour qu'elle prenne en charge le service API de GLM. Vous pouvez copier directement le contenu ci-dessous et demander à Trae de créer les variables d'environnement correspondantes ; vous pouvez également choisir de les écrire de manière permanente dans les variables d'environnement système (en cas de problème, l'agent peut également vous aider à modifier). + +Tout d'abord, vous devez obtenir votre clé API GLM et la conserver de la manière qui vous convient le mieux. + +Version nationale : +Version internationale : + +Si vous utilisez la **version nationale de GLM**, utilisez la configuration suivante : + +```python +# Exécuter les commandes suivantes dans Cmd +# Remplacez `your_zhipu_api_key` par votre clé API obtenue +setx ANTHROPIC_AUTH_TOKEN your_zhipu_api_key +setx ANTHROPIC_BASE_URL https://open.bigmodel.cn/api/anthropic +``` + +Si vous utilisez la **version internationale de GLM**, utilisez la configuration suivante : + +```python +# Exécuter les commandes suivantes dans Cmd +# Remplacez également `your_zai_api_key` +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic +``` + +Vous pouvez saisir une instruction similaire à celle-ci directement dans Trae : + +⚠️ Si vous configurez les « variables d'environnement permanentes » via Trae, vous **devez redémarrer Trae** après la configuration, sinon les variables d'environnement dans son terminal intégré ne se mettront pas à jour, ce qui pourrait entraîner des erreurs de connexion ou de réseau. + +```python +Based on my environment variable settings: +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic + +and my key(Replace it with your own key): +681fea485851d29060cc.13gfaendggaFOhb + +please help me configure and start Claude Code +``` + +Vous verrez une sortie de processus similaire à celle-ci : + +![](/zh-cn/stage-2/backend/modern-cli/images/image14.png) + +> 💡 Qu'est-ce qu'une variable d'environnement ? +> +> Les variables d'environnement sont essentiellement un ensemble d'informations de configuration « clé-valeur » stockées dans le système d'exploitation, généralement sous la forme « nom_de_variable = valeur ». Tant qu'elles sont configurées à l'avance dans le terminal ou les paramètres système, les programmes peuvent lire ces variables à tout moment pour obtenir les informations correspondantes. Comme les variables d'environnement peuvent être écrites directement dans le terminal sans modifier le code lui-même, nous stockons généralement les clés d'accès aux grands modèles dans les variables d'environnement afin d'éviter toute fuite. Le programme lui suffit de lire la variable d'environnement correspondante pour effectuer l'appel au grand modèle. +> +> Sous Windows, les variables d'environnement sont également souvent utilisées pour stocker les « chemins d'appel » des outils en ligne de commande, en plus des clés d'accès aux grands modèles. +> +> Nous savons que le terminal lui-même est un programme. Parfois, nous souhaitons lancer un programme externe depuis le terminal, par exemple taper `claude` pour démarrer Claude Code. La raison pour laquelle il suffit de taper `claude` pour l'exécuter est que le terminal lit les variables d'environnement du système, dont la variable PATH contient le répertoire où se trouve l'exécutable de Claude Code, ce qui permet au terminal de le trouver et de l'exécuter (cela équivaut à coller le chemin absolu du programme dans le terminal et à appuyer sur Entrée). +> +> Une variable d'environnement typique pourrait ressembler à ceci : `PATH=C:\Windows\system32;C:\Program Files\Python`. Ainsi, nous pouvons exécuter ces programmes système depuis n'importe quel chemin, par exemple en tapant simplement `python` dans la ligne de commande pour lancer l'interpréteur Python. +> +> Si vous souhaitez consulter les variables d'environnement actuelles du système, vous pouvez taper « variables d'environnement » dans la recherche Windows. Dans la fenêtre « Modifier les variables d'environnement système » qui s'affiche, vous verrez toutes les variables et leurs valeurs. Certaines servent à stocker les clés de modèles, d'autres à ajouter des répertoires de programmes pour faciliter les appels depuis n'importe quel chemin. + +Vous pouvez maintenant utiliser le dernier GLM pour développer avec Claude Code. Vous pouvez essayer de réexécuter un projet précédent, ou relever à nouveau les tâches que Trae n'avait pas réussi à accomplir, et comparer les différences d'expérience. + +🎉 Répéter le processus de « tout reprendre à zéro » n'est pas une perte de temps -- à chaque nouvelle tentative, vos compétences se renforcent. + +En suivant exactement la même logique que pour GLM, vous pouvez également connecter facilement d'autres interfaces prenant en charge le format compatible Anthropic. + +#### Utiliser Kimi K2 comme backend (recommandé) + +Kimi K2 est le nouveau grand modèle de langage de nouvelle génération lancé par Moonshot AI, avec d'excellentes performances en compréhension et génération de code. Kimi K2 prend en charge une fenêtre de contexte ultra-longue (jusqu'à 200K tokens), capable de traiter facilement de grandes bases de code et des projets complexes. + +**Avantages clés :** + +- **Contexte ultra-long** : prend en charge une fenêtre de contexte de 200K, permettant de traiter le code d'un projet entier en une seule fois +- **Excellentes capacités en code** : performances remarquables en génération, refactoring et débogage de code +- **Bonne compréhension du chinois** : compréhension plus précise des besoins de programmation en chinois +- **Appels d'outils stables** : prise en charge stable des appels de fonctions et utilisation d'outils + +**Obtenir la clé API :** + +Visitez pour vous inscrire et obtenir votre clé API. + +**Méthode de configuration :** + +```bash +export ANTHROPIC_BASE_URL=https://api.moonshot.cn/anthropic +export ANTHROPIC_AUTH_TOKEN=sk-YOURKEY +``` + +#### Utiliser Minimax comme backend (recommandé) + +Minimax est le nouveau grand modèle de langage lancé par MiniMax, avec d'excellentes performances dans les tâches de programmation. Le modèle Minimax est reconnu pour ses capacités de raisonnement exceptionnelles et la qualité de son code généré, particulièrement adapté aux scénarios de programmation complexes. + +**Avantages clés :** + +- **Forte capacité de raisonnement** : excellentes performances en raisonnement logique complexe et conception d'architecture de code +- **Code de haute qualité** : code généré structuré et lisible +- **Support multilingue** : prise en charge de la génération et conversion de code en plusieurs langages +- **Rapidité de réponse** : API à réponse rapide, adaptée aux scénarios d'appels fréquents + +**Obtenir la clé API :** + +Visitez pour vous inscrire et obtenir votre clé API. + +**Méthode de configuration :** + +```bash +export ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_MINIMAX_API_KEY +export ANTHROPIC_MODEL=MiniMax-M2.7 +``` + +#### Utiliser DeepSeek comme backend (recommandé) + +DeepSeek est un grand modèle de langage open source développé par DeepSeek, populaire auprès des développeurs pour ses excellentes capacités de code et son excellent rapport qualité-prix. DeepSeek Coder a été spécialement optimisé pour les tâches de programmation. + +**Avantages clés :** + +- **Capacités de code exceptionnelles** : excellentes performances en génération, compréhension et correction de code +- **Open source et personnalisable** : modèle open source, permettant un fine-tuning selon les besoins +- **Excellent rapport qualité-prix** : prix d'API relativement bas, adapté à une utilisation intensive +- **Bon support du chinois** : compréhension précise des scénarios de programmation en chinois + +**Obtenir la clé API :** + +Visitez pour vous inscrire et obtenir votre clé API. + +**Méthode de configuration :** + +```bash +export ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic +export ANTHROPIC_AUTH_TOKEN=YOU_DEEPSEEK_API_KEY +export API_TIMEOUT_MS=600000 +export ANTHROPIC_MODEL=deepseek-chat +export ANTHROPIC_SMALL_FAST_MODEL=deepseek-chat +export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 +``` + +#### Utiliser le Coding Plan de Volcano Engine comme backend (recommandé) + +Volcano Engine (Volcano Engine) est la plateforme de services cloud de ByteDance, proposant des services de modèles IA de niveau entreprise. Le Coding Plan de Volcano Engine est spécialement optimisé pour les scénarios de programmation, offrant des capacités de génération de code stables et efficaces. + +**Avantages clés :** + +- **Stabilité de niveau entreprise** : offre un SLA (Service Level Agreement) garantissant la stabilité du service +- **Optimisé pour le code** : optimisation spécifique pour les tâches de programmation +- **Large choix de modèles** : prend en charge plusieurs modèles, dont Doubao-pro, Doubao-lite, etc. +- **Accès rapide en Chine** : nœuds déployés en Chine, vitesse d'accès rapide + +**Obtenir la clé API :** + +Visitez pour vous inscrire et obtenir votre clé API. + +**Méthode de configuration :** + +```bash +export ANTHROPIC_BASE_URL=https://ark.volces.com/api/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_VOLCANO_API_KEY +export ANTHROPIC_MODEL=doubao-pro-32k +``` + +#### Autres API compatibles Anthropic + +Siliconflow : + +```bash +export ANTHROPIC_BASE_URL="https://api.siliconflow.cn/" +export ANTHROPIC_MODEL="moonshotai/Kimi-K2-Instruct-0905" # Vous pouvez modifier le modèle souhaité +export ANTHROPIC_API_KEY="YOUR_SILICONCLOUD_API_KEY" # Remplacez par votre clé API +``` + +Alibaba Cloud DashScope (Aliyuncs) : + +```python +export ANTHROPIC_BASE_URL="https://dashscope.aliyuncs.com/apps/anthropic" +export ANTHROPIC_API_KEY="YOUR_DASHSCOPE_API_KEY" +``` + +::: details Utiliser Claude Code Route comme backend (utilisation avancée) + +Nous avons expliqué plus haut comment remplacer l'interface Anthropic de Claude Code par l'API officielle GLM. Voyons maintenant comment l'outil Claude Code Router permet à Claude Code de s'adapter à davantage d'API de modèles. + +[Claude Code Router](https://github.com/musistudio/claude-code-router) est un outil d'amélioration de routage intelligent conçu spécifiquement pour Claude Code. Son rôle principal est d'aider les utilisateurs à distribuer les requêtes IA vers des modèles de différentes plateformes selon leurs besoins, avec une personnalisation avancée. Il prend en charge la connexion à des dizaines de plateformes, dont OpenRouter, DeepSeek, Ollama, Gemini, et permet également de router les tâches vers des modèles spécifiques selon les scénarios, par exemple GLM-4.5, Kimi-K2, Qwen3-Coder, etc. Par exemple, vous pouvez confier automatiquement les tâches en arrière-plan à un Ollama local pour économiser les coûts ; attribuer les tâches de texte/code longs à Gemini-2.5-Pro ; et déléguer l'explication de code à DeepSeek. + +![](/zh-cn/stage-2/backend/modern-cli/images/image16.png) + +Cet outil offre également des capacités de gestion de configuration UI/CLI pratiques, et s'adapte aux formats d'API des différentes plateformes via des « convertisseurs ». Il prend en charge les intégrations automatisées telles que GitHub Actions ainsi que des extensions personnalisées, résolvant le problème du « modèle unique ne couvrant pas tous les scénarios » et des « changements fréquents de plateforme fastidieux », pour aider les utilisateurs à tirer parti des outils IA de manière plus flexible et économique. + +![](/zh-cn/stage-2/backend/modern-cli/images/image17.png) + +Voici comment installer Claude Code Router. Les étapes générales sont les suivantes (vous pouvez également demander à Trae de les exécuter), pour préparer l'environnement nécessaire : + +```markdown +npm install -g @anthropic-ai/claude-code +npm install -g @musistudio/claude-code-router +``` + +Une fois l'installation terminée, vous devez vérifier que la commande `ccr` est disponible localement. Si vous voyez une sortie similaire à celle-ci, l'installation a réussi : + +![](/zh-cn/stage-2/backend/modern-cli/images/image18.png) + +Ensuite, il existe deux méthodes pour initialiser et configurer les modèles : + +- Utiliser l'interface UI de CCR, en ouvrant dans le navigateur la page de configuration qu'il fournit ; +- Modifier directement le fichier de configuration par défaut de CCR (l'UI ne fait en réalité que modifier le fichier de configuration, mais offre une interface plus intuitive). + +Si vous choisissez d'utiliser l'UI CCR, vous verrez une interface similaire à celle-ci : + +![](/zh-cn/stage-2/backend/modern-cli/images/image19.png) + +En cliquant sur le bouton « Add Provider », vous verrez l'interface suivante. Vous devez : + +1. Saisir le nom du fournisseur de modèle dans le champ Name ; +2. Remplir l'adresse de l'interface compatible OpenAI du fournisseur dans API Full URL ; +3. Saisir la clé API de la plateforme correspondante dans API Key ; +4. Saisir le nom du modèle dans la section Models, puis cliquer sur « Add Model » pour l'ajouter ; +5. Enfin, cliquer sur « Save » pour enregistrer la configuration. + +(En faisant défiler vers le bas dans l'interface, vous trouverez de nombreuses options avancées, mais vous pouvez les ignorer pour le moment.) + +![](/zh-cn/stage-2/backend/modern-cli/images/image20.png) + +Voici des exemples de configuration pour DeepSeek et Kimi : + +![](/zh-cn/stage-2/backend/modern-cli/images/image21.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image22.png) + +Après avoir enregistré la configuration du modèle, vous devez également spécifier le modèle par défaut (Default) dans la section Router à droite. Cliquez sur la liste déroulante correspondante et définissez-la sur `kimi` (recommandé), puis cliquez sur `Save and Restart` en haut à droite. + +![](/zh-cn/stage-2/backend/modern-cli/images/image23.png) + +Ensuite, il suffit de taper `ccr code` dans le terminal pour lancer le flux de travail de codage de Claude Code via Claude Code Router. + +![](/zh-cn/stage-2/backend/modern-cli/images/image24.png) + +::: + +#### Utilisations avancées de Claude Code + +Beaucoup de gens utilisent Claude Code au départ comme un simple outil de conversation. Mais en réalité, il intègre de nombreuses fonctionnalités riches qui rendent votre utilisation plus efficace et flexible. Voici quelques commandes et exemples d'utilisation courants : + +Documentation de référence : + + + + +| Commande | Fonction | Exemple | +| ----------------- | ----------------------------------------- | ---------------------------------------- | +| claude | Lancer le mode interactif | `claude` | +| claude "query" | Exécuter une tâche ponctuelle et afficher le résultat | `claude "explain this project"` | +| claude -p "query" | Exécuter une question ponctuelle et quitter automatiquement après | `claude -p "explain this function xxxx"` | +| claude -c | Reprendre la dernière session | `claude -c` | +| claude -r | Restaurer la session précédente | `claude -r` | +| /resume | Revenir à la session précédente dans le chat en cours | `claude -c`, `/resume` | +| /plugin | Gérer les plugins, installer des extensions de commit et review | `/plugin` | +| /init | Initialiser la description du projet avec CLAUDE.md | `/init` | +| /clear | Effacer le contexte de la session actuelle pour éviter la surcharge | `/clear` | +| /compact | Compresser l'historique de conversation pour réduire les tokens de contexte | `/compact` | +| /cost | Afficher la consommation actuelle | `/cost` | +| /model | Changer le modèle utilisé (ignorable avec une API compatible) | `/model` | +| /memory | Gérer les fichiers mémoire CLAUDE.md | | +| /help | Afficher la liste des commandes disponibles | `/help` | +| exit ou Ctrl+C | Quitter Claude Code | `exit` ou `Ctrl+C` | +| /agents | Fonctionnalité avancée, détaillée plus loin | | +| /mcp | Fonctionnalité avancée, détaillée plus loin | | + +**CLAUDE.md** + +Référence : + +`CLAUDE.md` est un fichier spécial que Claude lit automatiquement et intègre au contexte au début de chaque conversation. Il est donc parfaitement adapté pour y consigner : + +- Les commandes bash courantes +- Les fichiers clés et fonctions utilitaires +- Les conventions de style de code +- Les méthodes de test +- Les règles de collaboration du dépôt (par exemple le nommage des branches, merge ou rebase) +- La configuration de l'environnement de développement (par exemple l'utilisation de pyenv, le compilateur recommandé) +- Les comportements ou pièges spécifiques au projet à surveiller +- Toute information que vous souhaitez que Claude « retienne » + +`CLAUDE.md` n'a pas de format imposé, il suffit qu'il soit concis et lisible pour les humains. Par exemple : + +``` +# Bash commands +- npm run build: Build the project +- npm run typecheck: Run the typechecker + +# Code style +- Use ES modules (import/export) syntax, not CommonJS (require) +- Destructure imports when possible (eg. import { foo } from 'bar') + +# Workflow +- Be sure to typecheck when you're done making a series of code changes +- Prefer running single tests, and not the whole test suite, for performance +``` + +#### Fonctionnement interne de Claude Code + +Référence : + +Si vous vous demandez pourquoi Claude Code est souvent plus performant que des outils de programmation Agent comme Trae ou Cursor, regardons brièvement son mécanisme de fonctionnement interne. + +Les autres outils de programmation IA en CLI fonctionnent de manière globalement similaire. + +![](/zh-cn/stage-2/backend/modern-cli/images/image25.png) + +Claude Code décompose les tâches de programmation en un cycle continu de « perception -- réflexion -- action -- validation », au sein duquel il appelle différents outils pour accomplir les tâches. Il imite le flux de travail d'un développeur humain : écrire du code, l'exécuter, observer les résultats, puis améliorer. Le système fonctionne via une boucle de tâche principale qui exécute les étapes en continu ; à chaque cycle, Claude peut appeler différents outils -- lecture/écriture de fichiers, exécution de commandes, recherche de code, etc. -- puis décider de la prochaine action en fonction des résultats réels renvoyés par ces outils. + +Plusieurs caractéristiques clés méritent d'être notées : + +- **Traitement en flux (Stream Processing)** : Claude peut produire des résultats tout en réfléchissant, sans devoir attendre que tout le code soit écrit avant de l'exécuter. +- **Compression intelligente (Intelligent Compression)** : les conversations longs tendent à allonger excessivement le contexte. Claude compresse l'historique en informations clés pour réduire la probabilité d'« oubli », et garantit un fonctionnement efficace en distinguant la mémoire à court et à long terme. +- **Contrôle de concurrence (Concurrency Control)** : la conception interne parallèle permet à plusieurs tâches de s'exécuter simultanément sans se gêner mutuellement. +- **Gestion de sous-agents (Sub-agent Management)** : en pratique, un seul « rôle » ne traite pas tout. Vous pouvez gérer plusieurs sous-agents collaborant sur le code, chacun responsable de tâches différentes, par exemple l'un dédié aux tests, l'autre à la rédaction de documentation. + +### Codex + +![](/zh-cn/stage-2/backend/modern-cli/images/image26.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image27.png) + +Comme Claude Code, Codex est un outil collaboratif de programmation IA développé par OpenAI. Vous pouvez le considérer comme la « version OpenAI de Claude Code ». Son plus grand avantage est son optimisation poussée pour GPT-5. + +En pratique, GPT-5 offre actuellement une vitesse de réponse plus rapide et un taux d'erreur plus faible (probabilité plus élevée de mener à bien correctement les tâches complexes en plusieurs tours). Son inconvénient est que ses explications ont tendance à être « académiques » et « techniques », parfois trop rigoureuses et riches en informations, ce qui peut être légèrement difficile d'accès pour les débutants. + +Vous pouvez installer Codex avec la commande suivante : + +``` +npm i -g @openai/codex +``` + +#### Utiliser l'API officielle OpenAI comme backend + +Si vous utilisez directement l'entrée officielle OpenAI de Codex, la configuration est très simple : une fois que vous avez souscrit à l'abonnement OpenAI ou obtenu le quota d'API correspondant, il suffit de taper `codex` dans la ligne de commande pour lancer le programme et suivre les instructions pour vous connecter. + +![](/zh-cn/stage-2/backend/modern-cli/images/image28.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image29.png) + +#### Utiliser une API OpenAI relayée comme backend + +L'API OpenAI officielle pouvant être coûteuse et soumise à des exigences réseau strictes, nous pouvons également passer par d'autres services de passerelle API pour relayer les appels et contourner ces limitations. + +Avec cette méthode, il suffit d'acheter le quota Codex API correspondant sur une plateforme de relais tierce pour obtenir une expérience proche du Codex OpenAI natif. + +Référence : +Page de recharge : + +Notez qu'une fois le token obtenu, vous devez configurer la clé API localement. + +Dans les paramètres du groupe de clés, assurez-vous de sélectionner l'élément spécialement dédié à Codex. + +![](/zh-cn/stage-2/backend/modern-cli/images/image30.png) + +Ensuite, vous devez insérer la clé obtenue dans l'invite suivante, et confier l'intégralité du prompt à Trae pour qu'il vous aide à compléter le processus de configuration : + +````bash +My API key is: [Paste your obtained sk-xxxxx key here] + +Please help me complete the following configuration tasks: + +1. Create configuration directory + - Create a `.codex` folder under my user directory + - Windows path should be: `C:\Users\[My Username]\.codex` +2. Backup existing configuration (if exists) + - Check if `.codex\config.toml` exists + - If it exists, rename it to `config.toml.bak.[current timestamp]` (timestamp format: yyyyMMddHHmmss) +3. Create configuration file + - Create `config.toml` in the `.codex` directory + - Write the following complete content: + ```toml + preferred_auth_method = "apikey" + + [model_providers.myrelay] + name = "My Relay Station" + base_url = "https://api.zyai.online/v1" + env_key = "MYRELAY_API_KEY" + wire_api = "responses" + request_max_retries = 4 + stream_max_retries = 10 + stream_idle_timeout_ms = 300000 + + [profiles.myrelay] + model_provider = "myrelay" + model = "gpt-5" + model_reasoning_effort = "medium" + + [tools] + web_search = true + +4. Set system environment variable +Variable name: MYRELAY_API_KEY +Variable value: The key I gave you + +5. Confirm completion and report back: + +The full path of the configuration file +Whether the environment variable was set successfully +I can use the command `codex --profile myrelay` to run it +```` + +Une fois la configuration terminée, vous pouvez lancer Codex avec l'API relayée via `codex --profile myrelay`. L'utilisation est ensuite similaire à Claude Code : il suffit de saisir vos idées et besoins dans la boîte de dialogue. + +### OpenCode + +![](/zh-cn/stage-2/backend/modern-cli/images/image32.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image33.png) + +OpenCode est une plateforme open source d'agents de codage IA destinée aux développeurs, positionnée comme un « Claude Code multi-modèles ». Son interface d'interaction principale est le Terminal, et elle prend également en charge l'intégration d'éditeurs (VS Code, Neovim, etc.), pouvant se connecter en profondeur aux dépôts de code locaux et accomplir un flux de développement complet, de la compréhension du code à l'exécution d'ingénierie, via le langage naturel. + +Ce n'est pas un outil de programmation IA lié à un seul modèle, mais une plateforme ouverte d'agents de codage IA permettant de passer librement de GPT à Claude, Gemini ou même des modèles locaux. Même OpenAI prend officiellement en charge la connexion d'OpenCode à Codex / abonnements OpenAI. + +![](/zh-cn/stage-2/backend/modern-cli/images/image34.png) + +Vous pouvez installer OpenCode avec la commande suivante : + +```bash +# Linux / Unix +curl -fsSL https://opencode.ai/install | bash + +# Windows +npm i -g opencode-ai +``` + +#### Utiliser les modèles gratuits dans OpenCode + +OpenCode propose périodiquement des modèles gratuits utilisables, dont la configuration est très simple. Dans le répertoire où vous souhaitez utiliser OpenCode, lancez le programme en tapant `opencode` dans la ligne de commande pour accéder au panneau de chat. Saisissez la commande `/models` et recherchez le mot-clé « free » pour voir les modèles gratuits signalés par le mot « free ». + +![](/zh-cn/stage-2/backend/modern-cli/images/image35.png) + +En général, les modèles gratuits accomplissent les tâches de codage plus lentement que les modèles payants ou sur abonnement. Cela dépend généralement de la congestion du routage du modèle, de la période de pointe de codage et des capacités propres au modèle. + +#### Utiliser un modèle tiers comme modèle de codage principal dans OpenCode + +C'est l'avantage central d'OpenCode : il permet de changer librement de modèle tout en conservant les mêmes MCP, Skills et contexte pour accomplir différentes tâches de codage. L'exemple ci-dessous montre comment connecter GPT-5.3 Codex d'OpenAI à OpenCode comme modèle de codage principal. + +Dans la fenêtre de chat d'OpenCode, saisissez la commande `/connect`, sélectionnez la première instruction la plus pertinente et appuyez sur Entrée pour accéder à l'authentification d'un fournisseur de modèles tiers. + +![](/zh-cn/stage-2/backend/modern-cli/images/image36.png) + +Ici, nous choisissons OpenAI comme exemple, appuyez sur Entrée pour sélectionner la méthode d'authentification. + +![](/zh-cn/stage-2/backend/modern-cli/images/image37.png) + +Choisissez celle que vous préférez, seule la méthode d'authentification diffère. Ici, nous sélectionnons la première option pour une connexion par navigateur. + +![](/zh-cn/stage-2/backend/modern-cli/images/image38.png) + +Copiez ce lien dans votre navigateur et procédez à une connexion OpenAI normale. Lorsque le navigateur affiche « Authorization Successful », le client OpenCode basculera automatiquement vers l'interface de sélection du modèle OpenAI. + +![](/zh-cn/stage-2/backend/modern-cli/images/image39.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image40.png) + +#### Installer le plugin Oh My OpenAgent + +La force d'OpenCode réside également dans son écosystème communautaire très actif. Vous pouvez trouver de nombreux plugins liés à OpenCode sur Github. Si OpenCode est un outil collaboratif IA permettant de changer librement de modèle, alors Oh-My-OpenAgent est un « système de commandement multi-agents de programmation IA » fonctionnant au-dessus d'OpenCode. Il peut décomposer une tâche complexe en sous-tâches confiées à différents modèles, chacun travaillant dans son domaine de compétence. + +![](/zh-cn/stage-2/backend/modern-cli/images/image41.png) + +Vous pouvez copier l'instruction suivante et la coller dans le modèle configuré précédemment dans OpenCode pour installer le plugin. + +```text +Install and configure oh-my-openagent by following the instructions here: +https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md +``` + +Voici les fonctionnalités et la description des capacités d'Oh-My-OpenAgent. + +| Fonctionnalité | Description | +| :-------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **Légion autonome (Discipline Agents)** | Sisyphus coordonne Hephaestus, Oracle, Librarian et Explorer. Une équipe complète de développement IA travaillant en parallèle. | +| **Team Mode** (v4.0, activation optionnelle) | Agent leader + jusqu'à 8 membres parallèles, visualisation tmux en temps réel, famille d'outils `team_*` dédiée. pilote `hyperplan` (5 relecteurs antagonistes) et `security-research` (3 chasseurs + 2 ingénieurs PoC).[Documentation →](docs/guide/team-mode.md) | +| **`ultrawork` / `ulw`** | Déclenchement en un clic, tous les agents se déploient. La tâche ne s'arrête pas tant qu'elle n'est pas terminée. | +| **[IntentGate Porte d'intention](https://factory.ai/news/terminal-bench)** | Avant toute action réelle, analyse la véritable intention de l'utilisateur. Fini les réponses IA déclenchées à tort par un sens littéral. | +| **Outil d'édition basé sur le hachage** | Chaque modification est vérifiée par le hachage du contenu `LINE#ID`, 0% de modifications erronées. Inspiré par [oh-my-pi](https://github.com/can1357/oh-my-pi). [The Harness Problem →](https://blog.can.ac/2026/02/12/the-harness-problem/) | +| **LSP + AST-Grep** | Renommage au niveau workspace, diagnostics pré-build, réécriture basée sur AST. Offre aux agents une précision de niveau IDE. | +| **Agents en arrière-plan** | Lancement simultané de 5+ experts travaillant en parallèle. Maintient un contexte propre, résultats disponibles à tout moment. | +| **MCP intégré** | Exa (recherche web), Context7 (documentation officielle), Grep.app (recherche de code source GitHub). Activé par défaut. | +| **Ralph Loop / `/ulw-loop`** | Boucle auto-référentielle. N'accepte jamais un taux de complétion inférieur à 100%. | +| **Exécution Todo forcée** | L'agent veut s'économiser ? Le système le rappelle à l'ordre. Vos tâches doivent être terminées. | +| **Vérificateur de commentaires** | Élimine les commentaires redondants au goût trop prononcé d'IA. Le code produit ressemble à celui d'un ingénieur senior chevronné. | +| **Intégration Tmux** | Support complet de terminal interactif. Exécuter des REPL, utiliser un débogueur, des outils TUI, le tout en session temps réel. | +| **Compatibilité Claude Code** | Vos Hooks, commandes, skills, MCP et plugins existants ? Tous migrables sans effort. | +| **MCP intégré aux Skills** | Les skills embarquent automatiquement les serveurs MCP nécessaires. Activation à la demande, sans saturer votre fenêtre de contexte. | +| **Planificateur Prometheus** | Avant d'écrire la moindre ligne de code, élabore un plan stratégique via un mode entretien. | +| **`/init-deep`** | Génère automatiquement des `AGENTS.md` à tous les niveaux du répertoire projet. Économise des tokens et améliore considérablement la compréhension de l'agent. | + +Sisyphus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) est votre commandant en chef. Il est responsable de la planification, de l'allocation des tâches à l'équipe d'experts, et pousse les tâches à leur terme avec une stratégie de parallélisme extrêmement agressif. Il n'abandonne jamais en cours de route. + +Hephaestus (gpt-5.5) est votre travailleur en profondeur autonome. Vous lui donnez uniquement un objectif, pas la méthode. Il explore automatiquement les patterns du dépôt de code, exécute les tâches de bout en bout de manière indépendante, sans jamais vous demander d'assistance. Un véritable artisan. + +Prometheus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) est votre stratège. Il délimite le périmètre et construit un plan d'exécution détaillé via un mode entretien, avant d'écrire la moindre ligne de code. + +Une fois ces éléments compris, vous pouvez utiliser OpenCode équipé du plugin Oh-My-OpenAgent pour accomplir vos tâches de codage. + +## Autres usages des outils de programmation IA en CLI + +### Écrire un cahier des charges avec l'IA : apprendre à « concrétiser les besoins » + +Pour les grands modèles de langage, les besoins abstraits doivent être « concrétisés ». Par exemple : « j'ai faim » est un besoin abstrit. Nous devons le transformer en : « j'ai un peu faim, je pourrais manger un pain aux haricots rouges avec un verre de lait de soja. » -- Voilà un besoin concret et exécutable. + +Mais transformer un besoin abstrait en besoin concret est un processus qui demande beaucoup d'énergie. Si nous n'avons pas vu suffisamment d'exemples, il est difficile d'imaginer rapidement comment décomposer un problème abstrait en modules détaillés. Dans ce cas, la meilleure approche est de laisser l'IA réaliser l'étape de « concrétisation » pour vous. + +Par exemple, si je veux développer une application de « planning quotidien », l'idée la plus simple pourrait être : + +`Please help me write a daily planning app where I can write my plans each day and get reminders.` + +L'IA peut certes décomposer la tâche directement sur cette base, puis procéder étape par étape, mais des erreurs ou des malentendus sont possibles en cours de route. Pour réduire les risques, nous pouvons demander à l'IA de développer d'abord le besoin : + +`Based on my needs, please elaborate and provide a more detailed Product Requirement Document for reference. My idea is: Please help me write a daily planner app that supports daily plan-writing and provides reminders .` + +L'IA pourrait alors produire un PRD complet tel que celui-ci : + +``` +Product Requirements Document (PRD): "Today's Plan" App +Document Version: 1.0 +Creation Date: October 27, 2023 +Author: (Your Name/Product Manager) + +1. Product Introduction +1.1 Product Name +Today's Plan +1.2 Product Vision +"Today's Plan" is a minimalist and highly efficient daily planning and reminder tool, dedicated to helping users eliminate procrastination and forgetfulness, plan every day clearly, and ensure tasks are carried out through an intelligent reminder system--ultimately enabling users to gain a stronger sense of control and achievement over their time. +1.3 Target Users (User Personas) +We mainly serve three types of users: +Students (Xiao Ming): +Characteristics: Multiple tasks such as courses, assignments, club activities, exam prep, needing organized time arrangement. +Pain Points: Easily forget small tasks or assignment deadlines; feel overwhelmed switching between tasks; want to build regular study and life habits. +Needs: A simple tool to list daily to-dos and provide reminders before class/self-study. +Office Workers (Zhang Wei): +Characteristics: Fast-paced work, many meetings, reports, project milestones, and personal affairs (fitness, picking up children). +Pain Points: Easily forget important meetings or work milestones; get interrupted by urgent tasks and forget the original plan; feel busy but inefficient at end of day. +Needs: Need a tool to quickly record and schedule daily work and send strong reminders at key times (e.g., 15 minutes before meetings). +Freelancers/Self-disciplined Seekers (Li Na): +Characteristics: High freedom of time, but strong self-management required for work output and personal growth. +Pain Points: Easily procrastinate, lack external supervision; start the day without a clear plan, leading to low time utilization. +Needs: Need a tool to help build a daily fixed routine (Morning Routine) and review daily achievements for positive feedback. + +2. User Stories +As a user, I want to quickly create today's plan list so I have an overview of all my tasks for the day. +As a user, I want to set specific start and end times for each task so I can create a visual timeline. +As a user, I want to receive push notification reminders before a task starts so I won't miss any important arrangements. +As a user, I want to customize the reminder time (such as 5, 15, or 60 minutes in advance) so reminders better fit my habits. +As a user, I want to easily mark completed tasks so I can feel accomplished and clearly see my progress. +As a user, I want to see a summary of my completed plans at the end of each day for reviewing and self-motivation. +As a user, I want to conveniently edit and delete tasks to handle last-minute changes. +As a user, I want to view plans and achievements from previous days to review my efficiency and habits. + +3. Feature Breakdown +Core Features (MVP - Minimum Viable Product) +Module 1: Plan Management +3.1.1 Daily Plan Homepage +Interface: "Today" as the core view, current date shown at the top. +View: Timeline list, clearly showing tasks scheduled from morning to evening. Tasks without a time can be listed in the top or bottom "To-do List" section. +Interactions: +Click the "+" button in the bottom right to quickly create a new task. +Pull down to refresh the page. +Swipe left/right to view yesterday's and tomorrow's plans. +3.1.2 Create/Edit Task +Entry: Click "+" on the homepage or a time slot in the list. +Fields: +Task title (required): Briefly describe the task, e.g., "10 AM Weekly Product Meeting." +Task time (optional): +Set "start time" and "end time." +Provide "all-day" option for unspecified time tasks. +Default time picker should be quick and convenient. +Reminder setting (required, with default value): See Module 2. +Notes (optional): Add further descriptions, links, or location info. +Actions: Save, cancel, delete task. +3.1.3 Task Interaction +Mark as complete: Checkbox before each task; checking adds a strikethrough and gray background, indicating completion. Can unmark if needed. +Edit task: Click the task itself to enter edit page. +Delete task: Swipe left on a task to reveal "Delete" button. +Module 2: Smart Reminder System +3.2.1 Reminder Trigger +Mechanism: Based on task's set "start time" and the user's "reminder lead time," send a push notification from device. +Offline Support: Locally scheduled reminders must trigger even if user is offline. +3.2.2 Reminder Content & Format +Notification title: App name "Today's Plan." +Body: "Reminder: [Task Title] will start at [Start Time]." E.g., "Reminder: Product Meeting will start at 10:00." +Sound: Use system default or offer several simple, effective tones. +3.2.3 Reminder Settings +Global Settings (in Settings page): +User can set a default reminder time, e.g., "15 minutes before task starts." New tasks adopt this by default. +Single Task Settings (in create/edit page): +Users can override global settings for important tasks, choosing specific reminder times like "on time," "5 minutes early," "30 minutes early," or "1 hour early." +Provide "no reminder" option. +Subsequent Features (V1.1, V2.0) +3.3 Daily Review & Statistics +Push a summary notification at a set time every night (e.g., 22:00): "How was your day? Take a look at your achievements!" +Generate a simple daily report card: shows total planned tasks, completed tasks, completion rate, plus an encouraging message. +3.4 History Review +Calendar view to click on any past day and check its plans and completion status. Days with high completion rates marked with a special color. +3.5 Templates +Allow users to save a successful daily plan as a template, e.g., "Efficient Workday," "Relaxing Weekend." +When creating tomorrow's plan, one-click import a template, modify slightly to save time. +3.6 Themes & Personalization +Offer dark mode. +Allow changing several primary color themes. + +4. Non-Functional Requirements +4.1 Performance +Response: App launch time under 2 seconds; adding/editing tasks must be smooth and lag-free. +Resource Use: Low battery and memory consumption in background; do not over-consume resources waiting for reminders. +4.2 Usability +Minimal & intuitive: UI must be minimal, primary functions accessible within 3 clicks. No tutorial needed for new users. +Error tolerance: Offer undo (e.g. brief undo after mistakenly deleting a task). +4.3 Reliability +Reliable reminders: Reminder function is the product's lifeline; must guarantee 99.99% timely and accurate delivery. +Data loss-free: User plans must be reliably stored locally. Future versions can support cloud sync to prevent data loss on device change. +4.4 Compatibility +Platform: Support major iOS and Android versions (latest 3-4 releases). +Screen: Layout must fit various phone screen sizes. + +5. Roadmap +V1.0 (MVP): +Goal: Validate core value--planning & reminders. +Features: Complete all "Core Features" described above (Plan management, smart reminders). +V1.1 (Quick Optimization): +Goal: Improve retention and achievement. +Features: Add "Daily Review & Statistics," "History Review." +V2.0 (Enhanced Experience): +Goal: Increase efficiency and personalization. +Features: Add "Templates," "Themes & Personalization," and start developing "Cloud Sync." +``` + +Comparé à notre phrase initiale « aide-moi à écrire une application de planification quotidienne avec des rappels », ce document est désormais beaucoup plus détaillé. Vous pouvez modifier son contenu selon vos besoins réels, en ajoutant ou supprimant des éléments ; pour les modules dont vous n'êtes pas sûr, vous pouvez aussi continuer à demander à l'IA de proposer d'autres alternatives, puis sélectionner et fusionner pour obtenir la version finale. + +De cette manière, nous pouvons facilement transformer des idées abstraites en descriptions concrètes. Pour le développement IA, « concret » égale productivité : plus les besoins sont précis, plus il est facile d'obtenir un projet stable et de haute qualité. Vous pouvez essayer de reprendre un de vos petits projets précédents avec cette méthode et comparer la différence. + +Si vous trouvez ce type de « prompt de besoins » trop long, une approche naturelle consiste à l'écrire dans un document markdown séparé, comme votre « document de besoins / document de développement / PRD ». Ensuite, chaque fois que vous demandez à l'IA de développer un projet, il suffit de lui demander de « se référer à ce document » au lieu de retaper un long prompt à chaque fois. Vous pouvez également améliorer ce document au fil des itérations, pour que les projets ultérieurs en bénéficient directement. + +Voici quelques autres scénarios d'utilisation courants : + +### Gérer les dossiers + +Vous pouvez essayer d'utiliser les outils de programmation IA en CLI pour gérer les fichiers dans le dossier courant. Par exemple, si vous avez un ensemble de fichiers en désordre et que vous souhaitez les trier et les classer, vous pouvez dire à Claude Code ou Codex : + +`Please help me organize the contents of the current folder. I want to group files with the same content together & I want to group files from the same time period together. Please help me handle this.` + +### Développer un nouveau projet + +C'est presque identique à ce que nous faisions précédemment avec z.ai ou Trae -- nous pouvons aussi utiliser directement les outils de programmation IA en CLI pour développer de nouveaux projets à partir de zéro. Bien sûr, il est préférable de préparer un cahier des charges à l'avance. + +Plus le document de besoins est détaillé, meilleur sera le résultat final. Vous pouvez affiner le document en plusieurs itérations en fonction de vos idées évolutives ; plus le document est complet, plus l'implémentation du code sera stable et mature. + +### Déployer des projets open source (par exemple Dify) + +Pour les étudiants débutants en informatique, déployer un projet open source depuis GitHub est souvent difficile. Mais nous pouvons parfaitement confier cette tâche à Claude Code, comme nous l'avons fait dans le tutoriel Dify : + + + +Si je veux faire tourner mon propre Dify localement, il me suffit de donner ce lien à Claude Code, puis de saisir : + +`I want to deploy this GitHub project ``https://github.com/langgenius/dify`` . Please help me clone the project and run it.` + +Après avoir reçu votre demande, Claude Code effectuera automatiquement une série d'opérations, dont le clonage du code depuis GitHub, la configuration de l'environnement d'exécution, le lancement du projet, etc. Si une étape échoue ou si le projet ne se lance pas correctement, vous n'aurez qu'à procéder à quelques ajustements manuels selon les indications. Outre Dify, vous pouvez aussi utiliser Claude Code pour déployer la plupart des projets open source courants sur GitHub -- il vous suffit d'une boîte de dialogue et du temps d'un café. + +![](/zh-cn/stage-2/backend/modern-cli/images/image31.png) + +### Expliquer du code et rédiger de la documentation + +Pour certains projets complexes, ou les grands projets générés automatiquement par l'IA, vous trouverez peut-être le code trop long et la logique trop complexe pour être facilement compréhensible. C'est le moment de demander aux outils de programmation IA en CLI de vous aider à « lire le code ». Vous pouvez poser des questions comme : + +- Expliquez-moi ce projet : comment le lancer, comment l'utiliser, comment le modifier et poursuivre le développement ? +- Décrivez-moi le flux global du projet : comment le programme fonctionne-t-il ? Quelles opérations l'utilisateur peut-il effectuer dans l'interface ? +- Rédigez-moi une documentation complète pour ce projet, incluant la documentation de développement et la documentation d'exécution. +- Sur la base de tout le contenu du dossier courant, rédigez une description détaillée et enregistrez-la dans un document markdown spécifié. + +### D'autres possibilités + +Bien sûr, les outils de programmation IA en CLI peuvent faire bien plus que ce qui précède. Ne les considérez pas seulement comme des « outils de code », mais plutôt comme des agents intelligents capables d'agir de manière autonome. Vous pouvez leur demander de : + +- Gérer et organiser vos fichiers locaux ; +- Tenir un journal, rédiger des bilans ; +- Analyser et corriger des erreurs système ; +- Exécuter diverses tâches répétitives en ligne de commande, etc. + +Peut-être que dans un avenir proche, ils deviendront le partenaire IA le plus important et celui qui vous comprend le mieux sur votre ordinateur. \ No newline at end of file diff --git a/docs/fr-fr/stage-2/backend/stripe-payment/index.md b/docs/fr-fr/stage-2/backend/stripe-payment/index.md new file mode 100644 index 0000000..7d56ace --- /dev/null +++ b/docs/fr-fr/stage-2/backend/stripe-payment/index.md @@ -0,0 +1,907 @@ +# Comment intégrer Stripe et d'autres systèmes de paiement + +Lorsque votre produit dispose déjà de pages, d'un système de connexion, d'une base de données et d'un backend fonctionnel, la question suivante est : **comment facturer**. + +Beaucoup de personnes qui intègrent un paiement pour la première fois concentrent toute leur attention sur « comment rediriger vers la page de paiement ». Mais ce qui détermine vraiment la stabilité du système, ce n'est pas le bouton, c'est l'ensemble de la chaîne de facturation : qui décide du prix, qui confirme le succès du paiement, qui met à jour la base de données, qui gère les droits d'accès. + +Cet article est divisé en deux parties : + +- **La première partie** se concentre uniquement sur l'intégration de base la plus pratique, avec pour objectif de vous permettre d'intégrer Stripe à votre projet le plus rapidement possible. +- **La seconde partie** est regroupée en annexe et couvre les détails des Webhooks, les événements d'abonnement, et les différences de solutions de paiement selon les pays et régions. + +> 💡 Il est recommandé d'avoir terminé ces chapitres avant de continuer +> +> - [De la base de données à Supabase](../database-supabase/) +> - [Grands modèles pour écrire du code d'interface et de la documentation d'API](../ai-interface-code/) +> - [Comment déployer une application Web](../zeabur-deployment/) + +# Ce que vous allez apprendre + +1. À quoi ressemble un système de paiement minimum viable. +2. Comment intégrer Stripe dans votre projet de la manière la plus rapide. +3. Comment rédiger des prompts pour que l'IA ajoute directement un système de paiement. +4. Si vous ne faites pas un projet Stripe à l'international, quelle solution de paiement privilégier selon les régions. + +--- + +# Première partie : prise en main + +## 1. Retenez d'abord ces 3 principes + +Si vous ne deviez retenir que trois choses, voici lesquelles : + +1. **Le prix doit être décidé par le backend**, vous ne pouvez pas faire confiance au montant envoyé par le frontend. +2. **Ce qui active réellement les droits, c'est le Webhook**, pas la page `success`. +3. **Votre propre base de données doit conserver l'état du paiement**, vous ne pouvez pas dépendre uniquement du tableau de bord Stripe. + +Ces trois principes constituent les limites essentielles d'un système de paiement. Tant que ces limites sont respectées, que vous passiez ensuite à Stripe, PayPal, Alipay ou WeChat Pay, il s'agit au fond uniquement d'un « changement d'interface, l'architecture reste la même ». + +## 2. Que se passe-t-il si, au lieu de traiter côté backend, on connecte Stripe directement depuis le frontend ? + +C'est l'idée la plus naturelle pour beaucoup de personnes qui font leur premier paiement : + +- Il y a déjà un bouton « Acheter » sur la page +- Ne pourrais-je pas laisser le frontend se connecter directement à Stripe +- Ainsi, pas besoin de backend + +Si vous faites simplement une fausse page de démonstration, cette approche ne pose évidemment aucun problème. +Mais si vous comptez vraiment encaisser de l'argent, **cette voie mène généralement à des problèmes sérieux**. + +Les problèmes les plus courants sont les suivants : + +1. **Le prix est facilement modifiable** + Les requêtes dans le navigateur sont envoyées depuis l'ordinateur de l'utilisateur. N'importe qui peut modifier le contenu de la requête. +2. **Exposition facile d'informations sensibles** + Les clés secrètes véritablement importantes, la logique de prix et la logique d'activation des abonnements ne doivent jamais se trouver côté frontend. +3. **Impossible de confirmer de manière fiable « ce paiement est-il vraiment un succès »** + Le fait que l'utilisateur soit redirigé vers la page de succès ne signifie pas que votre base de données a été correctement synchronisée. +4. **La base de données devient incohérente** + L'utilisateur peut dire « j'ai bien payé », mais votre propre système n'en a gardé aucune trace. + +Une répartition des rôles plus sûre serait donc : + +- Frontend : afficher les boutons, initier l'achat, rediriger les pages +- Backend : décider des prix, créer les sessions de paiement, recevoir les Webhooks, mettre à jour la base de données + +::: info Vous pouvez résumer cette section en une seule phrase +**Le frontend peut gérer la redirection, mais le backend doit gérer la tarification et la confirmation.** + +Dès qu'il s'agit de vrais encaissements, ne confiez jamais au frontend « le pouvoir ultime de décider du prix » ni « la logique d'activation après un paiement réussi ». +::: + +## 3. Quand est-il judicieux de commencer par Stripe ? + +Si vous travaillez sur les scénarios suivants, Stripe est souvent le point de départ le plus naturel : + +- Un SaaS destiné aux utilisateurs internationaux +- Un produit par abonnement +- Des produits numériques, des templates, des packs de crédits IA +- Vous souhaitez valider rapidement la monétisation, plutôt que de gérer d'emblée trop de détails de paiement locaux + +Si vos utilisateurs principaux se trouvent en Chine continentale, Stripe n'est généralement pas le premier choix -- ce point sera abordé en annexe. + +## 4. La chaîne de paiement minimum viable + +Commençons par la version minimale. Tant que cette chaîne fonctionne, votre système de paiement possède une ossature. + +```mermaid +flowchart LR + user["Utilisateur"] + frontend["Page frontend"] + backend["Votre backend"] + checkout["Stripe Checkout"] + webhook["Stripe Webhook"] + db["Supabase / Base de données métier"] + + user -->|"Clique sur Achat"| frontend + frontend -->|"Demande de création de session de paiement"| backend + backend -->|"Crée une Session selon le prix backend"| checkout + frontend -->|"Redirige vers la page de paiement"| checkout + checkout -->|"Envoie un événement après paiement"| webhook + webhook -->|"Vérifie la signature et met à jour le statut"| backend + backend -->|"Écrit dans orders / subscriptions"| db + db -->|"Le frontend lit le dernier statut après actualisation"| frontend +``` + +Traduit en langage simple : + +1. L'utilisateur clique sur le bouton. +2. Le frontend demande au backend un lien de paiement. +3. Le backend crée une session de paiement avec la clé Stripe. +4. L'utilisateur paie sur la page Stripe. +5. Stripe vous notifie que « le paiement a vraiment réussi » via un Webhook. +6. Votre backend met ensuite à jour la base de données. + +## 5. Diagramme de séquence standard pour l'initiation d'un paiement + +Si vous préférez regarder un diagramme système plus formel, voici le diagramme de séquence : + +```mermaid +sequenceDiagram + autonumber + actor User as Utilisateur + participant Frontend as Page frontend + participant Backend as API backend + participant Stripe as Stripe Checkout + + User->>Frontend: Clique sur "Passer Premium" ou "Acheter" + Frontend->>Backend: POST /api/billing/create-checkout-session + Note right of Frontend: Le frontend transmet plan / userId / email\nmais pas le montant final + Backend->>Backend: Vérifie le plan et mappe le priceId + Backend->>Stripe: Crée une Checkout Session + Stripe-->>Backend: Retourne session.url + Backend-->>Frontend: Retourne le lien de paiement + Frontend-->>User: Redirige vers la page de paiement Stripe + User->>Stripe: Effectue le paiement +``` + +## 6. Démarrage rapide + +Si vous souhaitez l'intégrer le plus rapidement possible dans votre projet, suivez ces 5 étapes. + +### 6.1 Étape 1 : Créer des produits et des prix dans le tableau de bord Stripe + +L'objectif de cette étape n'est pas « de configurer quelques choses au hasard », mais de définir clairement dans Stripe **ce que vous vendez exactement et comment vous prévoyez de facturer**. + +Dans le modèle de Stripe : + +- **Product** représente « ce que vous vendez », par exemple `Abonnement Pro` +- **Price** représente « à quel prix vous le vendez et selon quel cycle », par exemple `9,90 USD/mois`, `99 USD/an` + +Pourquoi commencer par cette étape ? +Car lorsque votre backend crée ensuite une Checkout Session, il ne transmet pas directement un montant à Stripe, mais un `price_id` déjà existant. Stripe utilise ensuite ce `price_id` pour générer la véritable page de paiement, le montant, la devise et le cycle d'abonnement. + +Si vous sautez cette étape, l'étape « créer un lien de paiement » sera tout simplement impossible. + +::: info Pourquoi faut-il s'arrêter ici +Beaucoup de débutants trouvent les termes `Product` et `Price` un peu fastidieux, avec l'impression d'apprendre le jargon interne de Stripe. + +En réalité, cette étape consiste à faire quelque chose de très simple : +- Définir clairement « ce qu'on vend » +- Définir clairement « à quel prix on le vend » +- Permettre au backend d'utiliser ensuite un `price_id` stable pour créer des liens de paiement + +Une fois ce principe compris, les Checkout Sessions ne vous sembleront plus abstraites. +::: + +Pour un système d'abonnement minimum viable, vous devez au moins créer ces deux niveaux : + +- un `Product` +- un ou plusieurs `Price` + +Vous pouvez ouvrir directement ces pages : + +- Page de connexion Stripe Dashboard : [Dashboard Login](https://dashboard.stripe.com/login) +- Documentation Stripe sur la gestion des produits et prix : [Manage products and prices](https://docs.stripe.com/products-prices/manage-prices) +- Documentation Stripe de démarrage rapide Checkout : [Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- Page des produits Stripe Dashboard : [Product catalog](https://dashboard.stripe.com/test/products) + +Nous vous recommandons de travailler d'abord en **mode Test**, plutôt que de créer directement en environnement de production. + +La configuration minimale la plus courante est : + +- `Product` : `Pro Plan` +- `Price 1` : `pro_monthly` +- `Price 2` : `pro_yearly` + +Dans le tableau de bord, vous pouvez comprendre l'ordre comme suit : + +1. Créez d'abord un produit `Pro Plan` +2. Puis ajoutez deux prix sous ce produit +3. L'abonnement mensuel et l'abonnement annuel sont en réalité deux modes de facturation pour un même produit + +Une fois terminé, vous devez au minimum noter ces informations : + +- Le `price_id` du prix mensuel +- Le `price_id` du prix annuel +- Vos propres noms de plan, par exemple `pro_monthly`, `pro_yearly` + +Si c'est votre première visite dans le tableau de bord Stripe, nous vous conseillons de considérer cette étape comme suit : + +- `Product` détermine ce qui est vendu sur la page de paiement +- `Price` détermine le montant facturé sur la page de paiement +- Ce que le backend utilisera réellement par la suite, c'est principalement le `price_id` + +::: info Les valeurs vraiment importantes à retenir +Le plus important sur cette page n'est pas le nom du produit, mais le `price_id`. + +Par la suite, que ce soit pour demander à l'IA d'intégrer le backend ou pour résoudre vous-même un problème, ce que vous utiliserez le plus souvent est : +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- Les deux `price_id` correspondants +::: + +Si vous souhaitez que l'IA vous guide d'abord dans la configuration du tableau de bord, vous pouvez utiliser directement ce prompt : + +```text +Je découvre Stripe, ne modifie pas le code pour le moment, guide-moi d'abord pour effectuer la configuration minimale de paiement dans le tableau de bord Stripe. + +Base-toi sur ces documents officiels pour me donner des instructions étape par étape : +- https://docs.stripe.com/products-prices/manage-prices +- https://docs.stripe.com/checkout/quickstart?lang=node + +Ma situation : +- Je veux créer un abonnement payant le plus simple possible +- Seulement deux plans : mensuel et annuel +- Je ne comprends pas encore les termes Product et Price + +Merci de : +1. M'expliquer en termes simples ce que sont Product et Price. +2. Puis me guider dans l'ordre « quelle page ouvrir -> où cliquer -> quoi remplir ». +3. Enfin me rappeler ce que je dois copier depuis le tableau de bord pour le backend. +4. Si je risque de me tromper, me rappeler de rester en mode test. +``` + +### 6.2 Étape 2 : Préparer les variables d'environnement + +Vous aurez généralement besoin d'au moins ces variables d'environnement : + +- `STRIPE_SECRET_KEY` +- `STRIPE_WEBHOOK_SECRET` +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- `APP_URL` +- `SUPABASE_URL` +- `SUPABASE_SERVICE_ROLE_KEY` + +Vous pouvez ouvrir directement ces pages : + +- Documentation Stripe API Keys : [API keys](https://docs.stripe.com/keys) +- Page Stripe Dashboard API Keys : [API Keys](https://dashboard.stripe.com/test/apikeys) +- Documentation Stripe Webhooks : [Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Page Stripe Dashboard Webhooks : [Workbench Webhooks](https://dashboard.stripe.com/test/workbench/webhooks) + +> ⚠️ `STRIPE_SECRET_KEY` et `SUPABASE_SERVICE_ROLE_KEY` ne doivent être placés que côté backend. + +::: info L'objectif de cette étape sur les variables d'environnement +Cette étape ne vise pas à « remplir le `.env` au maximum », mais à placer les éléments les plus sensibles du système de paiement sous la garde du backend : + +- La clé secrète Stripe +- La clé de vérification Webhook +- Votre mapping de prix + +En résumé : +Le frontend ne fait qu'initier l'achat, les véritables secrets et la logique de tarification doivent rester côté serveur. +::: + +Cette étape peut aussi être confiée directement à l'IA : + +```text +Regarde d'abord comment mon projet stocke actuellement les variables d'environnement, puis aide-moi à lister celles dont Stripe a besoin. + +Référence-toi à ces documents : +- https://docs.stripe.com/keys +- https://docs.stripe.com/webhooks + +Ma situation : +- Je suis débutant +- Je ne distingue pas quelles variables vont au frontend et lesquelles au backend +- Je ne suis pas sûr de devoir modifier `.env`, `.env.local` ou un autre fichier + +Merci de : +1. Chercher dans le projet où les variables d'environnement sont habituellement stockées. +2. Lister les variables minimales nécessaires pour l'intégration Stripe. +3. M'expliquer en termes simples le rôle de chaque variable. +4. M'indiquer sur quelle page Stripe aller copier chaque variable. +5. S'il existe un fichier d'exemple de variables d'environnement dans le projet, ajouter directement les noms de variables. +``` + +### 6.3 Étape 3 : Le backend crée la Checkout Session + +Vous n'avez pas besoin d'écrire l'interface vous-même, laissez l'IA s'en charger en se référant à la documentation officielle. + +Commencez par lui fournir ces documents : + +- Démarrage rapide Stripe Checkout : [Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- API Checkout Sessions : [Create a Checkout Session](https://docs.stripe.com/api/checkout/sessions/create) +- Documentation sur les abonnements : [Subscriptions](https://docs.stripe.com/payments/subscriptions) + +Puis collez directement ce prompt : + +```text +Regarde d'abord comment le code backend de mon projet actuel est organisé, puis aide-moi à y intégrer le paiement Stripe. + +Référence-toi à ces documents officiels : +- https://docs.stripe.com/checkout/quickstart?lang=node +- https://docs.stripe.com/api/checkout/sessions/create +- https://docs.stripe.com/payments/subscriptions + +Mon objectif est simple : +- Après que l'utilisateur a cliqué sur le bouton d'achat, il est redirigé vers la page de paiement Stripe +- Il n'y a que deux plans : mensuel et annuel +- Ne me laisse pas décider moi-même où placer le code, analyse d'abord le projet puis place-le au bon endroit + +Merci de : +1. Rechercher dans le projet pour identifier le fichier d'entrée backend, les fichiers de route et le format des variables d'environnement. +2. En te référant à la documentation officielle, intégrer l'étape « création du lien de paiement Stripe ». +3. Ne pas me laisser transmettre le montant moi-même, le prix doit être déterminé par les variables d'environnement du backend. +4. M'indiquer quels fichiers tu as modifiés. +5. Me dire quelles configurations supplémentaires je dois effectuer dans le tableau de bord Stripe. +``` + +### 6.4 Étape 4 : Le frontend redirige vers la page de paiement + +L'objectif de cette étape est très simple : faire en sorte que le bouton de la page de tarification appelle votre interface backend, puis redirige vers Stripe Checkout. + +Documentation de référence : + +- Guide d'intégration Stripe Checkout : [Build an integration with Checkout](https://docs.stripe.com/payments/checkout/build-integration) + +Prompt pour l'IA : + +```text +Aide-moi à connecter le bouton « Acheter » du projet à Stripe. + +Exigences : +- Ne pas modifier les pages existantes, uniquement changer la logique après le clic sur le bouton +- Après le clic, appeler l'interface backend pour obtenir le lien de paiement, puis rediriger vers Stripe +- En cas d'erreur, afficher un message simple à l'utilisateur (par exemple « Le paiement est temporairement indisponible, veuillez réessayer plus tard ») + +Documentation de référence : https://docs.stripe.com/payments/checkout/build-integration +``` + +### 6.5 Étape 5 : Le Webhook met à jour l'état dans la base de données + +C'est l'étape la plus critique. + +::: info Pourquoi cette étape est-elle la plus critique +Beaucoup de gens pensent que « l'utilisateur a payé et a été redirigé vers la page de succès » signifie que c'est terminé. + +Non. + +Pour votre système, ce qui compte vraiment est : +**Stripe a-t-il officiellement envoyé l'événement à votre Webhook, et votre backend a-t-il réussi à mettre à jour l'état dans la base de données ?** +::: + +Vous pouvez également demander à l'IA d'implémenter directement cette étape en suivant la documentation officielle des Webhooks Stripe, sans l'écrire manuellement. + +Documentation de référence : + +- Stripe Webhooks : [Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Stripe CLI : [Stripe CLI](https://docs.stripe.com/stripe-cli) +- Utilisation de Stripe CLI : [Use the Stripe CLI](https://docs.stripe.com/stripe-cli/use-cli) + +Prompt pour l'IA : + +```text +Continue à m'aider à intégrer l'étape « activation automatique après un paiement réussi » avec Stripe. + +Référence-toi à ces documents officiels : +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +Mon objectif : +- Après que l'utilisateur a payé, il ne s'agit pas simplement d'être redirigé vers la page de succès +- Il faut réellement mettre à jour le statut d'abonnement dans ma base de données + +Merci de : +1. Rechercher d'abord dans le projet comment le code lié à la base de données et le statut utilisateur sont stockés. +2. Ajouter le webhook Stripe. +3. Après un paiement réussi, passer l'utilisateur en statut actif, ou mettre à jour le champ de statut d'abonnement déjà utilisé dans le projet. +4. S'il existe déjà des tables d'abonnement, de commandes ou d'utilisateurs dans le projet, continuer à utiliser la structure existante. +5. M'indiquer quels fichiers tu as modifiés. +6. M'expliquer comment tester localement si cette étape fonctionne réellement. +``` + +## 7. Prompt pour une intégration rapide par l'IA + +Si vous utilisez un outil comme Codex, Claude Code, Trae ou Cursor, vous pouvez directement coller le prompt suivant pour lui demander d'intégrer le paiement dans votre projet. + +```text +Aide-moi à intégrer le paiement Stripe dans le projet actuel. Je veux créer la fonctionnalité d'abonnement payant la plus simple possible qui fonctionne. + +Mes exigences : +1. Je suis débutant, commence par analyser le projet toi-même, puis décide où modifier le code. +2. Ne me laisse pas juger moi-même la structure des répertoires, des routes ou de la base de données. +3. Je veux uniquement la version la plus simple : deux plans, mensuel et annuel. +4. Après que l'utilisateur a cliqué sur Acheter, il est redirigé vers la page de paiement Stripe. +5. Après un paiement réussi, le statut d'abonnement dans ma base de données passe à activé. +6. N'ajoute pas trop de fonctionnalités complexes au début, comme des coupons, des montées ou descentes de grade, des factures complexes. + +Résultat attendu : +1. Donne-moi d'abord un plan de modifications. +2. Modifie ensuite directement le code. +3. Explique-moi ensuite comment tester étape par étape en local. +4. S'il y a des étapes nécessitant des opérations dans le tableau de bord Stripe, donne-moi directement le lien et les points clés. +``` + +Si vous souhaitez que l'IA soit plus adaptée à votre projet, vous pouvez également ajouter en début de prompt : + +- Votre framework frontend +- La structure des répertoires de votre backend +- Les noms de vos tables de base de données +- Que votre système utilisateur est Supabase Auth ou un système Auth personnalisé + +## 7.1 Déléguer également les tests d'intégration locaux à l'IA + +Si vous souhaitez que l'IA vous guide même pour les tests d'intégration locaux, vous pouvez utiliser directement ce prompt : + +```text +Continue à m'aider à faire fonctionner réellement le paiement Stripe. Je veux suivre étape par étape, sans avoir à deviner. + +Référence-toi à la documentation officielle : +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +Mon objectif : +1. Dis-moi d'abord quelles pages Stripe ouvrir. +2. Explique-moi comment obtenir le STRIPE_WEBHOOK_SECRET. +3. Explique-moi comment utiliser stripe login et stripe listen. +4. Montre-moi comment vérifier que checkout.session.completed a bien atteint le webhook local. +5. Si le projet nécessite de lancer d'abord le frontend et le backend, donne-moi aussi les commandes spécifiques. +6. Ne te contente pas de théorie, donne-moi les étapes opérationnelles concrètes. +7. Si je me trompe à une étape, dis-moi à quoi ressemblent les erreurs les plus courantes. +``` + +## 8. Les 4 pièges les plus fréquents + +1. **Considérer la page `success` comme un paiement réussi** + Ce qui détermine réellement le statut, c'est le Webhook, pas la redirection frontend. +2. **Laisser le frontend transmettre le montant** + Cela crée un risque sérieux de falsification du prix. +3. **La route Webhook est pré-traitée par `express.json()`** + La vérification de signature Stripe nécessite le corps brut de la requête. +4. **Absence de traitement idempotent** + Les Webhooks peuvent être renvoyés. Si vous ajoutez un abonnement ou des crédits à chaque fois, vous créez un incident. + +## 9. Recommandation de sélection en une phrase + +Si vous voulez simplement faire fonctionner la facturation dès maintenant : + +| Vos utilisateurs principaux | Solution à essayer en premier | +| :--- | :--- | +| SaaS international / utilisateurs étrangers | Stripe | +| Utilisateurs en Chine continentale | Alipay / WeChat Pay | +| Hong Kong ou équipes transfrontalières | Stripe + solution agrégée portefeuille local / FPS | + +Les détails spécifiques sont regroupés en annexe. + +::: info L'approche de sélection la plus simple +Ne commencez pas par vouloir « intégrer tous les moyens de paiement du monde d'un coup ». + +L'ordre plus pragmatique est généralement : +- Choisir d'abord une chaîne de paiement principale selon la région de vos utilisateurs principaux +- Faire fonctionner le paiement minimum viable +- Puis ajouter un deuxième, puis un troisième moyen de paiement selon les sources réelles d'utilisateurs +::: + +## 10. Résumé + +Vous maîtrisez désormais la chaîne de facturation la plus basique mais la plus importante : + +1. Le frontend initie l'achat. +2. Le backend crée une Checkout Session. +3. L'utilisateur paie sur la page Stripe. +4. Stripe notifie le backend via un Webhook. +5. Le backend met à jour la base de données. +6. Le frontend affiche le nouveau statut d'abonnement ou de commande après actualisation. + +Si vous souhaitez simplement intégrer rapidement le paiement dans votre projet, le contenu précédent suffit. Les annexes ci-dessous sont à consulter lorsque vous rencontrerez réellement des problèmes. + +--- + +# Annexes + +## Annexe A : Les objets les plus courants dans Stripe + +Lorsque vous lisez la documentation Stripe pour la première fois, ces noms d'objets peuvent facilement vous désorienter. Vous n'avez en réalité besoin de comprendre que les quelques suivants : + +| Objet | Rôle | À quoi vous pouvez le comparer | +| :--- | :--- | :--- | +| `Product` | Décrit ce qui est vendu | Un produit ou un plan d'abonnement | +| `Price` | Décrit le prix et le cycle de facturation | Mensuel, annuel, achat unique | +| `Checkout Session` | Flux de paiement hébergé par Stripe | La page de paiement | +| `Subscription` | Relation d'abonnement récurrent | Abonnement à renouvellement automatique | +| `Customer` | L'utilisateur qui paie | Le dossier client dans Stripe | +| `Webhook` | Notification asynchrone | Stripe vous indique « que s'est-il passé avec ce paiement » | + +## Annexe B : Pourquoi la page `success` ne signifie pas que le paiement a réussi + +Beaucoup de gens pensent que « l'utilisateur a payé et a été redirigé vers la page de succès » équivaut à un paiement réussi. C'est le piège le plus fréquent. + +### Un scénario réel + +Supposons que vous ayez créé un site d'abonnement : +1. L'utilisateur clique sur « Acheter un abonnement » +2. Redirection vers la page de paiement Stripe +3. L'utilisateur saisit sa carte bancaire et clique sur payer +4. La page redirige vers votre `success.html` +5. Vous avez écrit du code sur la page success : « puisque l'on est sur cette page, activer l'abonnement pour l'utilisateur » + +**Où est le problème ?** + +L'utilisateur peut ne pas avoir payé du tout, ou avoir quitté la page en cours de paiement, et quand même accéder directement à `success.html`. + +### Deux chemins totalement différents + +```mermaid +flowchart TB + pay["L'utilisateur a effectué le paiement sur Stripe"] + + subgraph unreliable["❌ Chemin non fiable : se fier uniquement à la page success"] + success["Le navigateur redirige vers la page success"] + fake["Le code frontend considère l'abonnement activé"] + risk["Risque : page fermée / coupure réseau / URL falsifiée / aucun paiement effectué"] + success --> fake --> risk + end + + subgraph reliable["✅ Chemin fiable : se fier au Webhook backend"] + event["Le serveur Stripe envoie un Webhook"] + verify["Le backend vérifie la signature"] + active["La base de données est officiellement mise à jour comme payée"] + event --> verify --> active + end + + pay --> success + pay --> event +``` + +**Différences clés :** + +| | Redirection vers la page success | Notification Webhook | +| :--- | :--- | :--- | +| Qui initie | Le navigateur de l'utilisateur | Le serveur de Stripe | +| Peut être falsifié | Oui, il suffit d'accéder directement à l'URL | Non, il y a une vérification de signature | +| Garantit le succès du paiement | Pas nécessairement | Oui, garanti | +| Comment votre système le sait | Le code frontend devine | Notification officielle de Stripe | + +### Quel devrait être le flux complet + +```mermaid +sequenceDiagram + autonumber + actor User as Utilisateur + participant Frontend as Votre page web + participant Stripe as Stripe + participant Webhook as Votre interface backend + participant DB as Base de données + + User->>Stripe: Effectue le paiement sur la page Stripe + Note over Stripe: L'argent est réellement arrivé sur le compte Stripe + + Stripe-->>Frontend: Le navigateur redirige vers la page success + Note over Frontend: ⚠️ Ceci est uniquement une redirection
et non une confirmation système + + Stripe->>Webhook: Envoie une notification Webhook
"checkout.session.completed" + Note over Webhook: ✅ C'est la notification officielle + + Webhook->>Webhook: Vérifie la signature
(pour confirmer que c'est bien Stripe, pas un hacker) + + Webhook->>DB: Met à jour le statut utilisateur à "payé" + DB-->>Webhook: Enregistrement réussi + Webhook-->>Stripe: Retourne 200 OK + + Frontend->>DB: L'utilisateur actualise la page, interroge le statut + DB-->>Frontend: Retourne "payé" + Note over Frontend: C'est seulement à ce moment que les fonctionnalités premium sont affichées +``` + +### Les points critiques de chaque étape + +**Étape 1 : L'utilisateur paie sur Stripe** + +C'est le seul moment où l'on peut affirmer « l'argent a réellement été payé » : +- L'utilisateur saisit les informations de sa carte et clique sur confirmer +- La banque débite la carte de l'utilisateur +- Stripe confirme avoir reçu le paiement + +**Étape 2 : Le navigateur redirige vers la page success (le plus problématique)** + +Cette étape est totalement non fiable, car : +- L'utilisateur peut saisir directement `yoursite.com/success` dans le navigateur et y accéder sans avoir payé +- L'utilisateur a quitté la page en cours de paiement, mais avait copié le lien success auparavant, puis l'a ouvert plus tard +- Un problème réseau peut empêcher la redirection, alors que l'argent a été débité (l'utilisateur a payé mais ne voit pas la page de succès) +- L'utilisateur clique sur le bouton retour et paie deux fois, mais les deux fois il est redirigé vers la même page success + +**Étape 3 : Stripe envoie le Webhook** + +C'est Stripe qui notifie proactivement votre serveur que « ce paiement a été reçu » : +- Seul le serveur de Stripe peut initier cette requête +- La requête contient une signature que votre backend peut vérifier pour confirmer qu'elle provient bien de Stripe +- Même si la page success ne s'est pas ouverte ou si l'utilisateur a été déconnecté, le Webhook est tout de même envoyé + +**Étape 4 : Le backend vérifie la signature** + +Pourquoi vérifier ? Pour empêcher les hackers de falsifier les notifications. + +Supposons qu'il n'y ait pas de vérification : un hacker pourrait envoyer directement une fausse notification à votre serveur : « l'utilisateur A a payé 1000 euros ». Votre système activerait alors l'abonnement pour le hacker. + +Le processus de vérification : +- Stripe génère une signature à partir du contenu de la notification en utilisant la clé secrète convenue +- Votre backend vérifie avec la même clé si la signature correspond +- Correspondance = 100% certain que c'est Stripe, non-correspondance = rejet immédiat + +**Étape 5 : Mise à jour de la base de données** + +Ce n'est qu'après vérification réussie que la base de données est mise à jour : +- Passer le statut utilisateur de « en attente de paiement » à « payé » +- Enregistrer le numéro de commande, le montant, l'heure du paiement +- Activer les droits d'abonnement correspondants + +**Étape 6 : Le frontend interroge le statut** + +La page success ne doit pas considérer que « être sur cette page signifie le succès ». La bonne approche est : +- Au chargement de la page, envoyer une requête au backend : « cet utilisateur a-t-il payé ? » +- Le backend interroge la base de données et retourne le statut réel +- Afficher « activation réussie » ou « en attente de confirmation » selon le résultat + +### Une erreur courante + +```javascript +// Erreur : activer directement sur la page success +// success.html +if (window.location.pathname === '/success') { + // Dangereux ! N'importe qui peut accéder /success + activateMembership(); +} +``` + +```javascript +// Correct : interroger le backend à chaque actualisation +// success.html +async function checkStatus() { + const response = await fetch('/api/user/status'); + const data = await response.json(); + + if (data.paymentStatus === 'paid') { + showMemberFeatures(); + } else { + showPendingMessage(); + } +} +``` + +### Résumé en une phrase + +**La page success est uniquement une « redirection réussie du navigateur », le Webhook est la « confirmation officielle de réception par Stripe ».** + +Votre système doit se fier au Webhook, pas à la redirection frontend. + +## Annexe C : Les événements les plus importants à surveiller pour un système d'abonnement + +| Événement | Signification | Action habituelle | +| :--- | :--- | :--- | +| `checkout.session.completed` | Première activation réussie | Créer l'enregistrement d'abonnement local | +| `invoice.paid` | Renouvellement automatique réussi | Prolonger la date de validité | +| `invoice.payment_failed` | Échec du prélèvement automatique | Marquer le statut à risque et alerter l'utilisateur | +| `customer.subscription.deleted` | Abonnement annulé | Retirer les droits ou marquer l'expiration | + +### Diagramme d'états de l'abonnement + +```mermaid +stateDiagram-v2 + [*] --> NotStarted: Utilisateur non abonné + NotStarted --> Active: checkout.session.completed + Active --> Active: invoice.paid + Active --> PastDue: invoice.payment_failed + PastDue --> Active: L'utilisateur paie avec succès + Active --> Canceled: customer.subscription.deleted + PastDue --> Canceled: Expiré sans régularisation + Canceled --> [*] + + state "Non activé" as NotStarted + state "Abonnement actif" as Active + state "Prélèvement échoué / En attente" as PastDue + state "Annulé / Expiré" as Canceled +``` + +### Diagramme de séquence : renouvellement / échec / annulation + +```mermaid +sequenceDiagram + autonumber + participant Stripe as Stripe + participant Webhook as Votre interface Webhook + participant DB as Table abonnements / commandes + participant App as Votre application + actor User as Utilisateur + + rect rgb(235, 248, 255) + Stripe->>Webhook: invoice.paid + Webhook->>DB: Prolonger current_period_end + DB-->>Webhook: Mise à jour réussie + Webhook-->>Stripe: 200 OK + App-->>User: L'abonnement reste actif + end + + rect rgb(255, 247, 237) + Stripe->>Webhook: invoice.payment_failed + Webhook->>DB: Marquer past_due + DB-->>Webhook: Mise à jour réussie + Webhook-->>Stripe: 200 OK + App-->>User: Rappel de mettre à jour le moyen de paiement + end + + rect rgb(254, 242, 242) + Stripe->>Webhook: customer.subscription.deleted + Webhook->>DB: Marquer canceled + DB-->>Webhook: Mise à jour réussie + Webhook-->>Stripe: 200 OK + App-->>User: Suspension des droits premium + end +``` + +## Annexe D : Comment choisir parmi les autres solutions de paiement + +### 1. Chine continentale + +Si vos utilisateurs principaux sont en Chine continentale, le premier choix reste **[Alipay](https://open.alipay.com/)** et **[WeChat Pay](https://pay.wechatpay.cn/)**. + +**Modèle de gestion :** + +Les deux fonctionnent en mode « passerelle de paiement ». Vous devez : +- Demander une qualification de commerçant (licence commerciale, compte bancaire professionnel) +- L'argent payé par les utilisateurs arrive directement sur votre compte commerçant +- Vous êtes responsable de la fiscalité, des remboursements et du rapprochement comptable + +**Modèle technique :** + +Les deux adoptent le modèle « commande backend + appel frontend + notification backend », comme Stripe. + +**Processus d'intégration Alipay :** +1. Créer une application sur la plateforme ouverte Alipay +2. Configurer les clés publique/privée et l'URL de callback +3. Le backend appelle l'interface de création de commande pour générer un lien ou un QR code de paiement +4. L'utilisateur scanne le code ou est redirigé pour payer +5. Alipay notifie votre backend de manière asynchrone pour mettre à jour le statut de la commande + +**Processus d'intégration WeChat Pay :** +- Paiement JSAPI : adapté aux comptes officiels et mini-programmes WeChat, l'utilisateur paie directement dans WeChat +- Paiement Native : génère un QR code sur PC, l'utilisateur scanne pour payer +- Paiement H5 : le navigateur mobile ouvre l'application WeChat pour payer + +Processus : commande backend -> obtention de `prepay_id` ou `code_url` -> appel frontend -> réception de la notification backend confirmant le succès + +**Liens de référence :** +- Plateforme ouverte Alipay : https://open.alipay.com/ +- Documentation commerçant WeChat Pay : https://pay.wechatpay.cn/doc/v3/merchant/ + +### 2. Hong Kong + +Le marché de Hong Kong est assez mixte, avec des combinaisons courantes : + +- Cartes bancaires : Visa / Mastercard +- FPS (Fast Payment System) : virement instantané local à Hong Kong +- AlipayHK / WeChat Pay HK : versions hongkongaises d'Alipay et WeChat + +**Combinaison recommandée :** +- Utiliser **[Stripe](https://stripe.com/hk)** pour les cartes internationales et les abonnements +- Utiliser **[Airwallex](https://www.airwallex.com/)** ou **[Adyen](https://www.adyen.com/)** pour les portefeuilles locaux et FPS + +### 3. International / SaaS + +#### [Stripe](https://stripe.com/) + +**Modèle de gestion :** Passerelle de paiement + +- Vous devez demander vous-même une qualification de commerçant (Stripe peut s'en charger dans certains pays) +- L'argent payé par les utilisateurs arrive sur votre compte Stripe, puis est reversé sur votre compte bancaire +- Vous êtes responsable de vos déclarations fiscales + +**Modèle technique :** + +- Meilleure expérience API, documentation claire +- Prend en charge Checkout (page hébergée), Elements (formulaire personnalisé), Payment Links (sans code) +- Notification de l'état du paiement par Webhook +- Prend en charge les abonnements, les factures, les devises multiples + +**Pour qui :** SaaS international, développeurs indépendants, équipes nécessitant une personnalisation flexible + +**Lien de référence :** https://docs.stripe.com/ + +#### [PayPal](https://www.paypal.com/) + +**Modèle de gestion :** Passerelle de paiement + +- L'argent payé par les utilisateurs arrive sur votre compte PayPal, puis vous le retirez sur votre banque +- Vous êtes responsable de la fiscalité + +**Modèle technique :** + +- Paiement unique : bouton sur le frontend, création/confirmation de commande par le backend +- Abonnement : créer d'abord un Product et un Plan, puis utiliser le SDK pour lancer +- Nécessite également un backend et des Webhooks, ne pas se fier uniquement au callback frontend + +**Pour qui :** Activités internationales nécessitant un canal supplémentaire, utilisateurs habitués à payer avec PayPal + +**Lien de référence :** https://developer.paypal.com/docs/ + +#### [Paddle](https://www.paddle.com/) + +**Modèle de gestion :** Merchant of Record (MoR) + +- Paddle est le « commerçant inscrit », juridiquement c'est Paddle qui encaisse auprès de l'utilisateur +- Paddle gère pour vous la fiscalité mondiale, la TVA, les remboursements, la conformité +- L'argent payé par les utilisateurs arrive à Paddle, qui déduit taxes et frais puis vous reverse le solde +- Vous n'avez pas besoin de créer une société dans chaque pays ni de gérer la fiscalité + +**Modèle technique :** + +- Paddle.js : page de paiement hébergée intégrée au frontend +- API backend : crée une transaction, la confie au checkout +- Webhook pour synchroniser le statut de l'abonnement + +**Pour qui :** Équipes SaaS ne souhaitant pas gérer la fiscalité mondiale, en particulier les SaaS B2B + +**Lien de référence :** https://developer.paddle.com/ + +#### [Lemon Squeezy](https://www.lemonsqueezy.com/) + +**Modèle de gestion :** Merchant of Record (MoR) + +- Similaire à Paddle, Lemon Squeezy est le « commerçant inscrit » +- Gère la fiscalité mondiale, la TVA, la conformité +- Racheté par Stripe en 2024, mais fonctionne indépendamment + +**Modèle technique :** + +- Hosted Checkout : le plus simple, génère directement un lien de paiement +- Checkout Overlay : surcouche intégrée à votre page +- API backend : crée un checkout, pour un contrôle flexible + +**Pour qui :** Développeurs indépendants, produits numériques, licences logicielles + +**Lien de référence :** https://docs.lemonsqueezy.com/ + +### 4. Solutions d'entreprise + +#### [Airwallex](https://www.airwallex.com/) + +**Modèle de gestion :** Passerelle de paiement + comptes globaux + +- Fournit des comptes de réception mondiaux (similaires à des comptes bancaires virtuels) +- Prend en charge la réception dans plusieurs devises, les conversions et les paiements +- Vous êtes responsable de la fiscalité + +**Modèle technique :** + +- Payment Links : quasi sans code, génère un lien de paiement +- Hosted Payment Page : page hébergée +- Drop-in / Embedded / Native API : intégration profonde, haut niveau de personnalisation +- Prend en charge Alipay HK, FPS, WeChat Pay et autres moyens de paiement locaux + +**Pour qui :** Équipes à Hong Kong, activités transfrontalières, entreprises nécessitant des comptes multidevises + +**Lien de référence :** https://www.airwallex.com/docs/ + +#### [Adyen](https://www.adyen.com/) + +**Modèle de gestion :** Passerelle de paiement + +- Plateforme de paiement de niveau entreprise, traitant des billions d'euros de transactions par an +- Prend en charge tous les canaux : en ligne, en point de vente, mobile +- Vous êtes responsable de la fiscalité + +**Modèle technique :** + +- Pay by Link : le plus simple, génère un lien de paiement +- Drop-in / Components : intégration en ligne standard +- Possibilité d'activer Alipay, Alipay HK, PayMe et autres moyens locaux depuis le tableau de bord + +**Pour qui :** Grandes entreprises, entreprises nécessitant un paiement omnicanal + +**Lien de référence :** https://docs.adyen.com/ + +### 5. Comparaison des solutions + +| Solution | Modèle de gestion | Gestion fiscale | Pour qui | +| :--- | :--- | :--- | :--- | +| Stripe | Passerelle de paiement | À votre charge | SaaS international, développeurs | +| PayPal | Passerelle de paiement | À votre charge | Canal supplémentaire international | +| Paddle | MoR | Géré par Paddle | SaaS B2B, sans gestion fiscale | +| Lemon Squeezy | MoR | Géré par LS | Développeurs indépendants, produits numériques | +| Adyen | Passerelle de paiement | À votre charge | Grandes entreprises | +| Airwallex | Passerelle + comptes | À votre charge | Activités transfrontalières, équipes HK | +| Alipay/WeChat | Passerelle de paiement | À votre charge | Utilisateurs en Chine | + +### 6. Choix par région + +| Votre marché | Solution recommandée | +| :--- | :--- | +| Chine continentale | Alipay / WeChat Pay | +| Hong Kong | Stripe + Airwallex / Adyen | +| SaaS international | Stripe (vous gérez la fiscalité) ou Paddle (MoR, géré pour vous) | +| Produits numériques internationaux | Stripe / Lemon Squeezy / Paddle | +| Multi-régions entreprise | Combinaison Adyen / Airwallex / Stripe | \ No newline at end of file diff --git a/docs/fr-fr/stage-2/backend/zeabur-deployment/index.md b/docs/fr-fr/stage-2/backend/zeabur-deployment/index.md new file mode 100644 index 0000000..c1cf2cc --- /dev/null +++ b/docs/fr-fr/stage-2/backend/zeabur-deployment/index.md @@ -0,0 +1,490 @@ +# Comment déployer une application web + +Dans ce tutoriel, nous allons présenter comment déployer votre application web sur Internet pour que d'autres personnes puissent y accéder. Nous présenterons trois plateformes de déploiement courantes : **Tencent CloudBase**, **Vercel** et **Zeabur**, pour vous aider à réaliser rapidement le processus complet, du « code écrit » au « site accessible sur Internet par tous ». + +# Qu'est-ce que le « déploiement » ? + +Avant de commencer, clarifions ce que signifie « déploiement (Deployment) ». Pour qu'un site web soit accessible par des utilisateurs externes, il doit disposer d'une adresse réseau publiquement accessible (cette adresse peut être une adresse IP, comme 123.45.67.89, ou un nom de domaine, comme [google.com](https://google.com/)). Mais une adresse seule ne suffit pas — votre code de page web (fichiers HTML, CSS, JavaScript, ou projets utilisant des frameworks comme React, Vue, etc.), ainsi que les ressources associées (images, vidéos), doivent être « placés » sur un serveur en ligne 24h/24, qui répondra aux requêtes réseau. Ainsi, le navigateur de n'importe qui pourra accéder à ces ressources et les télécharger. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image1.png) + +Source de l'image : https://www.hostinger.com/tutorials/what-is-cloud-hosting + +L'ensemble du processus — téléchargement des ressources, configuration de l'environnement et mise en route du service — est appelé **déploiement (Deployment)**. + +En termes simples : les pages web que vous avez écrites sur votre ordinateur ne sont accessibles que via une adresse locale dans votre propre navigateur, car ce code n'existe que sur votre disque dur. Le « déploiement » consiste à transférer votre code et vos ressources vers un serveur professionnel connecté au réseau public, et à le configurer pour qu'il sache « comment répondre lorsqu'on m'accède » — par exemple : quand quelqu'un saisit votre nom de domaine dans son navigateur, le serveur trouve immédiatement les fichiers correspondants et renvoie le contenu à l'appareil de l'utilisateur, qui peut alors voir votre page. + +Un déploiement manuel nécessite souvent plusieurs étapes, chacune pouvant comporter des pièges. Les étapes clés courantes incluent : + +1. **Préparation du serveur** : vous devez d'abord acheter un serveur cloud (comme Alibaba Cloud, Tencent Cloud, ou AWS EC2), choisir la région du serveur (Shanghai, Singapour, etc.), sa configuration (CPU, mémoire, taille du disque, etc.), et apprendre à vous y connecter à distance (par exemple via SSH). + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image2.png) +2. **Configuration de l'environnement** : une application web a besoin d'un « environnement » spécifique pour fonctionner — par exemple, exécuter un projet Node.js nécessite d'abord installer Node.js ; exécuter un projet Python nécessite d'installer Python et les bibliothèques tierces correspondantes. Si la version de l'environnement ne correspond pas, le programme peut générer des erreurs ou ne pas démarrer. +3. **Téléchargement des ressources** : vous devez uploader votre code et vos ressources locales vers le serveur, généralement via FTP ou Git. Si le projet est volumineux (contenant par exemple des fichiers vidéo), une interruption en cours de route peut nécessiter un re-upload complet. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image3.png) + +4. **Démarrage du service et tests** : une fois l'upload terminé, vous devez exécuter des commandes sur le serveur pour lancer l'application, et vérifier si « l'adresse réseau attribuée est accessible ». Si ce n'est pas le cas, cela peut être dû au pare-feu du serveur qui n'a pas ouvert le port correspondant (par exemple, votre application écoute le port 3000, mais ce port est bloqué par le pare-feu), ou à un bug dans le programme. Il faut alors consulter les journaux du serveur pour diagnostiquer le problème. + > On peut comprendre le port comme le « numéro de chambre » distinguant les différentes applications sur un même appareil, tandis que l'IP est le « numéro de rue » de cet appareil. L'IP et le port combinés (IP:port) permettent de localiser précisément un service réseau. +5. **Maintenance et mises à jour** : à chaque modification de code, vous devez re-uploader et redémarrer le service. En cas de panne du serveur (coupure de courant, panne réseau, etc.), vous devez redémarrer manuellement l'application, et parfois configurer un « outil de garde de processus » pour que le programme redémarre automatiquement après une sortie anormale. + +Des plateformes de déploiement « low-code » comme CloudBase, Vercel et Zeabur sont précisément nées pour résoudre ces problèmes complexes. Elles automatisent pour vous les étapes « achat de serveur, configuration d'environnement, upload de code, démarrage du service, surveillance de l'exécution ». Il vous suffit de connecter votre dépôt de code (comme GitHub ou GitLab) à la plateforme, ou d'uploader directement votre code, et elle tirera automatiquement le code, identifiera le type d'application, configurera l'environnement d'exécution correspondant, et vous donnera finalement une adresse publique accessible par tous. Elle peut même lier votre propre nom de domaine en un clic. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image4.png) + +Ensuite, nous présenterons les caractéristiques et méthodes d'utilisation de ces plateformes pour vous aider à choisir la solution de déploiement la plus adaptée. + +--- + +# Comparaison des plateformes de déploiement + +| Plateforme | Caractéristiques | Scénarios d'utilisation | Quota gratuit | +|------|------|----------|----------| +| **Tencent CloudBase** | Accès rapide en Chine, intégration profonde avec l'écosystème WeChat | Projets principalement destinés aux utilisateurs chinois, nécessitant le support des mini-programmes WeChat | Quota gratuit disponible | +| **Vercel** | Bon support des frameworks frontend, intégration étroite avec GitHub | Projets frontend modernes comme React/Vue/Next.js | Quota gratuit disponible | +| **Netlify** | Fonctionnalités complètes, support du traitement de formulaires et de l'authentification, bonne intégration Git | Sites statiques nécessitant des fonctionnalités avancées comme le traitement de formulaires, l'authentification | Quota gratuit disponible | +| **Zeabur** | Support de multiples langages et templates de services, configuration flexible | Projets complexes nécessitant le déploiement de multiples services (comme Dify, n8n) | Environ 5 USD de quota gratuit par mois | + +--- + +# 1. Tencent CloudBase + +Tencent CloudBase (Cloud Development) est un service cloud backend tout-en-un proposé par Tencent Cloud, particulièrement adapté aux développeurs en Chine. Ses avantages sont : + +- **Accès rapide en Chine** : serveurs situés en Chine, faible latence d'accès +- **Intégration avec l'écosystème WeChat** : connexion facile avec les mini-programmes et comptes officiels WeChat +- **Solution tout-en-un** : fournit un ensemble complet de services incluant l'hébergement de sites statiques, fonctions cloud, base de données, stockage, etc. +- **Quota gratuit généreux** : les développeurs individuels disposent de ressources gratuites suffisantes + +## Déployer une application web avec CloudBase + +### Étape 1 : Inscription et connexion + +Accédez à la [console Tencent CloudBase](https://console.cloud.tencent.com/tcb) et connectez-vous avec WeChat ou QQ. + +### Étape 2 : Créer un environnement + +Cliquez sur « Nouvel environnement » et choisissez un nom d'environnement (comme `my-web-app`). + +> **Note** : La version d'essai gratuite de CloudBase nécessite un code d'échange pour être activée. Vous devez suivre le compte officiel Tencent CloudBase, saisir «领取兑换码» dans le compte officiel pour obtenir le code d'échange de la version d'essai gratuite, puis remplir ce code lors de la création de l'environnement pour activer l'environnement gratuit (la période d'essai gratuite est de 6 mois). + +### Étape 3 : Activer l'hébergement de sites statiques + +Dans la page de gestion de l'environnement, trouvez la fonctionnalité « Hébergement de sites statiques » et activez-la. Une fois activée, vous obtiendrez un domaine d'accès par défaut. + +L'hébergement de sites statiques de CloudBase propose plusieurs méthodes de déploiement, similaires à Zeabur : + +- **Upload de projet local** : uploader directement les fichiers statiques construits (HTML, CSS, JS, etc.) depuis le local +- **Déploiement par template** : créer rapidement un projet en utilisant des templates prédéfinis, comme les templates d'application web React ou Vue +- **Déploiement depuis un dépôt Git** : supporte le pull automatique de code depuis des dépôts comme GitHub et le déploiement + +### Étape 4 : Déployer le code + +Dans la page d'hébergement de sites statiques, CloudBase propose trois méthodes de déploiement : + +**Méthode 1 : Déploiement de projet local (upload de projet local)** +- Sélectionnez « Déploiement de projet local » dans la console +- Uploadez directement les fichiers statiques construits (HTML, CSS, JS, etc.) +- Sélectionnez le dossier de votre projet construit localement (comme le répertoire `dist` ou `build`) +- Attendez la fin de l'upload pour accéder au site + +**Méthode 2 : Déploiement par template** +- Créez rapidement un projet en utilisant des templates prédéfinis +- Supporte les templates d'application web React, Vue, etc. +- Construction et déploiement automatiques basés sur le template + +**Méthode 3 : Déploiement depuis un dépôt Git** +- **Déploiement de dépôt personnel Git** : liez votre dépôt de code personnel GitHub, etc. +- **Déploiement de dépôt public** : supporte le pull de code depuis des dépôts Git publics +- Configurez les commandes de build automatique (comme `npm run build`) +- Chaque push de code déclenche un redéploiement automatique + +> **Astuce** : vous pouvez aussi utiliser l'outil CLI pour le déploiement : +> ```bash +> # Installer le CLI CloudBase +> npm install -g @cloudbase/cli +> # Connexion +> tcb login +> # Déploiement +> tcb hosting deploy ./dist -e your-env-id +> ``` + +### Étape 5 : Configurer un domaine personnalisé (optionnel) + +Dans les paramètres d'hébergement de sites statiques, vous pouvez lier votre propre domaine et demander un certificat HTTPS gratuit. + +--- + +# 2. Vercel + +Vercel est l'une des plateformes de déploiement frontend les plus populaires au monde, particulièrement adaptée au déploiement de projets utilisant des frameworks frontend modernes comme React, Vue, Next.js. Ses caractéristiques incluent : + +- **Intégration profonde avec GitHub** : un push de code déclenche un déploiement automatique +- **Prévisualisation automatique** : chaque Pull Request génère un lien de prévisualisation indépendant +- **CDN mondial** : le site est automatiquement distribué sur des nœuds worldwide, accès rapide +- **Fonctions Serverless** : supporte l'écriture d'API backend dans le projet + +> **Note** : l'accès à Vercel peut être instable dans certains environnements réseau. Les utilisateurs en Chine sont invités à privilégier CloudBase. + +## Déployer une application web avec Vercel + +### Étape 1 : Créer un compte + +Accédez au [site officiel de Vercel](https://vercel.com) et connectez-vous avec votre compte GitHub. + +### Étape 2 : Importer le projet + +1. Cliquez sur « Add New Project » +2. Sélectionnez le dépôt GitHub que vous souhaitez déployer +3. Si vous ne voyez pas le dépôt souhaité, cliquez sur « Adjust GitHub App Permissions » pour autoriser l'accès + +### Étape 3 : Configurer les paramètres de build + +Vercel identifiera automatiquement le type de projet et configurera les commandes de build : + +| Framework | Commande de build | Répertoire de sortie | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Next.js | `next build` | - | +| HTML pur | - | Répertoire racine du projet | + +Si l'identification automatique n'est pas correcte, vous pouvez modifier manuellement : +- **Build Command** : commande de build, comme `npm run build` +- **Output Directory** : répertoire de sortie du build, comme `dist` ou `build` +- **Install Command** : commande d'installation des dépendances, généralement `npm install` + +### Étape 4 : Déployer + +Cliquez sur le bouton « Deploy » et attendez la fin du build. Une fois le build réussi, vous obtiendrez un domaine `xxx.vercel.app`. + +### Étape 5 : Domaine personnalisé (optionnel) + +Dans la page « Domains » des paramètres du projet, vous pouvez ajouter votre propre domaine. Vercel configurera automatiquement le HTTPS. + +--- + +# 3. Netlify + +Netlify est une autre plateforme de déploiement frontend très populaire, similaire à Vercel, particulièrement adaptée au déploiement de sites statiques et d'applications à page unique (SPA). Ses caractéristiques incluent : + +- **Fonctionnalités complètes** : outre l'hébergement de sites statiques, supporte le traitement de formulaires, l'authentification, les fonctions edge, etc. +- **Intégration profonde avec Git** : supporte GitHub, GitLab, Bitbucket ; un push de code déclenche le déploiement automatique +- **Prévisualisation par branche** : chaque branche génère automatiquement un lien de prévisualisation indépendant +- **CDN mondial** : le site est automatiquement distribué sur des nœuds worldwide, accès rapide +- **Traitement de formulaires** : traite les soumissions de formulaires sans code backend +- **Authentification** : fonctionnalité d'authentification utilisateur intégrée, pour implémenter rapidement connexion/inscription + +> **Note** : la vitesse d'accès à Netlify depuis la Chine peut être inférieure à celle de CloudBase. Recommandé principalement pour les projets ciblant des utilisateurs internationaux. + +## Déployer une application web avec Netlify + +### Étape 1 : Créer un compte + +Accédez au [site officiel de Netlify](https://www.netlify.com) et cliquez sur « Sign up » pour vous inscrire. Vous pouvez utiliser GitHub, GitLab, Bitbucket ou un email. + +### Étape 2 : Importer le projet + +1. Après connexion, cliquez sur « Add new site » -> « Import an existing project » +2. Sélectionnez votre plateforme d'hébergement de code (comme GitHub) +3. Autorisez Netlify à accéder à vos dépôts +4. Sélectionnez dans la liste le dépôt que vous souhaitez déployer + +### Étape 3 : Configurer les paramètres de build + +Netlify identifiera automatiquement les frameworks frontend courants et configurera les paramètres de build : + +| Framework | Commande de build | Répertoire de publication | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Angular | `ng build` | `dist/` | +| Next.js | `next build` | `out` | +| HTML pur | - | `.` (répertoire racine du projet) | + +Si l'identification automatique n'est pas correcte, vous pouvez configurer manuellement : +- **Build command** : commande de build, comme `npm run build` +- **Publish directory** : répertoire de sortie du build, comme `dist` ou `build` + +### Étape 4 : Déployer + +Cliquez sur le bouton « Deploy site » et attendez la fin du build. Une fois le build réussi, vous obtiendrez un domaine `xxx.netlify.app`, accessible par tous. + +### Étape 5 : Configurer un domaine personnalisé (optionnel) + +1. Accédez aux paramètres du site, cliquez sur « Domain management » +2. Cliquez sur « Add custom domain » +3. Saisissez votre domaine et configurez les enregistrements DNS selon les instructions +4. Netlify demandera et configurera automatiquement un certificat HTTPS + +### Fonctionnalités spéciales + +#### 1. Traitement de formulaires + +Netlify offre une fonctionnalité très pratique : le traitement des soumissions de formulaires sans code backend. + +Il suffit d'ajouter l'attribut `netlify` au formulaire HTML : + +```html +
+

+ +

+

+ +

+

+ +

+

+ +

+
+``` + +Après déploiement, les données soumises via le formulaire seront automatiquement envoyées au tableau de bord Netlify. Vous pouvez consulter toutes les soumissions dans la page « Forms », configurer des notifications par email ou transférer les données vers d'autres services. + +#### 2. Netlify Functions (fonctions edge) + +Netlify supporte le déploiement de fonctions serverless, vous permettant d'implémenter des API simples sans configurer un serveur backend complet. Vous pouvez écrire des fonctions en JavaScript ou TypeScript ; une fois déployées, elles obtiendront automatiquement une URL accessible. + +Par exemple, créez un fichier `hello.js` : + +```javascript +exports.handler = async (event, context) => { + return { + statusCode: 200, + body: JSON.stringify({ message: "Hello from Netlify!" }) + }; +}; +``` + +Après déploiement, vous pouvez accéder à cette fonction via `https://votre-domaine/.netlify/functions/hello`. + +#### 3. Support du développement local + +Netlify fournit un outil CLI pour faciliter le développement et les tests en local : + +```bash +# Installer le CLI Netlify +npm install -g netlify-cli + +# Connexion au compte +netlify login + +# Démarrer le serveur de développement local +netlify dev + +# Tester les fonctions en local +netlify functions:serve +``` + +L'outil CLI permet de simuler l'environnement Netlify en local, y compris la soumission de formulaires, l'appel de fonctions, etc., facilitant les tests avant le déploiement. + +--- + +# 4. Zeabur + +Zeabur est une plateforme de déploiement émergente, particulièrement adaptée aux projets complexes nécessitant le déploiement de multiples services. Ses avantages sont : + +- **Templates de services riches** : templates intégrés pour Dify, n8n, bases de données et bien d'autres services +- **Support de multiples méthodes de déploiement** : GitHub, templates, images Docker, projets locaux, etc. +- **Combinaison flexible de services** : possibilité de déployer plusieurs services interconnectés dans un seul projet +- **Facturation à l'usage** : payez uniquement ce que vous consommez, adapté aux projets expérimentaux + +## Déployer Dify avec Zeabur + +Dans les cours précédents, nous avons brièvement découvert Dify. Maintenant, nous pouvons lancer très facilement notre propre service Dify via [Zeabur](https://zeabur.com/projects). Commencez par ouvrir la [page de la console](https://zeabur.com/projects) et examinons les différentes zones. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image5.png) + +Sur cette page, vous verrez d'abord plusieurs blocs : ce sont les services déjà lancés. Dans le menu supérieur, vous verrez les options Agent, Servers, Docs, Templates, qui représentent respectivement : + +1. **Agent** : ouvre l'assistant intelligent (Agent) intégré à Zeabur, à qui vous pouvez poser des questions sur les opérations ou consulter l'état actuel du serveur. +2. **Servers** : ici vous pouvez ajouter vos propres serveurs cloud achetés, ou acheter directement des serveurs via Zeabur. +3. **Docs** : consulter la documentation complète de Zeabur. +4. **Templates** : liste de tous les templates d'images intégrés. + +> L'« image (Image) » mentionnée ici peut être comprise comme une « archive contenant le code et l'environnement d'exécution ». Quand un service a été exécuté avec succès sur un serveur, nous pouvons choisir d'empaqueter « cet environnement d'exécution + le code » en une image. Ensuite, sur tout nouveau serveur, il suffit de décompresser et d'exécuter cette archive pour que le service fonctionne directement, sans reconfigurer l'environnement et le code. + +En haut à droite de la page, vous verrez également votre solde. Par défaut, vous disposez d'environ 5 USD de quota gratuit par mois. Vous pouvez ignorer les détails de facturation pour le moment ; retenez simplement que tant que le serveur est en cours d'exécution, le quota est consommé. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image6.png) + +Cliquez sur le solde pour voir le détail des consommations quotidiennes. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image7.png) + +Maintenant, créons notre propre service Dify. Tout d'abord, sur la [page d'accueil de la console](https://zeabur.com/projects), cliquez sur « New Project ». + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image8.png) + +Voici l'explication des différentes méthodes de création : + +1. **GitHub** + Permet de se connecter à votre compte GitHub. Une fois lié, vous pouvez sélectionner directement un projet depuis vos dépôts GitHub pour le déployer (GitHub est actuellement la plus grande plateforme d'hébergement de code au monde). +2. **Template (modèle)** + Permet de déployer un service basé sur un template. Zeabur intègre de nombreux templates de projets prédéfinis (comme Dify, n8n, etc.), vous permettant de créer et déployer rapidement une application à partir de ces templates. + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image9.png) +3. **Databases (bases de données)** + Pour déployer des services de base de données, comme MySQL, MongoDB et d'autres bases de données courantes. + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image10.png) +4. **Functions (fonctions)** + Permet de déployer des services de fonctions. Vous pouvez écrire du code JavaScript ou Python qui sera appelé sous forme de fonctions. + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image11.png) + + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image12.png) + +5. **Local Project (projet local)** + Uploadez un dossier local, Zeabur identifiera automatiquement les scripts de démarrage. Idéal pour déployer rapidement sur Zeabur un projet déjà développé localement. + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image13.png) +6. **Docker Image** + Déployez une image Docker déjà empaquetée. Si votre projet a été transformé en image Docker (par exemple stockée sur Docker Hub ou un autre registre d'images), vous pouvez la déployer directement ici. + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image14.png) +7. **Cursor** + Si vous avez installé Cursor (par exemple Cursor IDE), vous pouvez déployer directement un projet depuis Cursor vers Zeabur via cette entrée. + +Si vous souhaitez déployer votre propre service Dify, il est recommandé de choisir le mode **Template**, puis de saisir « dify » dans la barre de recherche. Vous verrez de nombreuses versions maintenues par différents auteurs ; vous pouvez en choisir une (par exemple la version v1.6.0). + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image15.png) + +Ensuite, saisissez n'importe quel nom. Zeabur générera un domaine personnalisé temporaire basé sur ce nom. Ensuite, tout le monde pourra accéder à votre service via cette URL. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image16.png) + +Une fois la création terminée, vous verrez plusieurs programmes (services) démarrer successivement. Soyez patient et attendez que tous les services atteignent l'état « démarré ». (Le service Dify est composé de plusieurs programmes, chacun responsable de fonctionnalités différentes, qui collaborent entre eux.) + +En général, il vous suffit de cliquer sur l'application Dify à gauche pour voir l'adresse d'accès par défaut. Mais dans cet exemple, comme il y a une couche nginx supplémentaire devant, vous devez cliquer sur le service nginx pour obtenir l'adresse d'accès finale. On peut comprendre nginx comme le programme principal responsable de « recevoir et distribuer les requêtes » vers l'extérieur : il répartit les adresses d'accès externes vers les différents services internes. Cliquez sur Nginx à gauche, et dans la page de détails vous verrez l'adresse actuelle du service. Ouvrez cette adresse dans votre navigateur et attendez que le service soit complètement démarré. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image17.png) + +Après quelques instants, vous verrez l'interface de connexion de Dify. Saisissez votre adresse email et votre mot de passe d'inscription, et vous pouvez commencer à utiliser votre propre service Dify. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image18.png) + +Si vous êtes curieux, vous pouvez aussi en profiter pour lancer un service n8n. n8n est également une plateforme de workflows AI très populaire à l'international. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image19.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image20.png) + +## Déployer un jeu de serpent avec Zeabur et Trae + +Dans cette prochaine partie du tutoriel, nous allons découvrir des utilisations plus avancées de Zeabur. Nous commencerons par générer un petit jeu de serpent avec Trae, puis le déploierons sur le serveur de Zeabur, en configurant un lien publiquement accessible pour que tout le monde puisse ouvrir votre jeu. + +La première étape consiste à créer un projet de jeu de serpent localement avec Trae. + +### Implémentation avec le framework HTML + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image23.png) + +Pour Trae, générer un jeu web de serpent basé sur HTML est très simple. Une fois le jeu généré, il vous suffit de suivre la méthode de déploiement local de Zeabur présentée précédemment pour uploader le dossier contenant tous les fichiers. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image24.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image25.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image26.png) + +Une fois terminé, vous accéderez à l'interface de détails du service : + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image27.png) + +Cliquez sur l'option « Network » à gauche, et trouvez la zone « Public Address » dans la page. Cliquez sur « Generate Domain » pour générer une adresse d'accès externe. Vous pouvez saisir n'importe quel nom de votre choix. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image28.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image29.png) + +Une fois la génération terminée, il suffit d'ouvrir cette adresse dans votre navigateur pour jouer à votre propre jeu de serpent. Les autres applications web de type HTML peuvent être déployées exactement de la même manière. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image30.png) + +### Implémentation avec le framework React + +Précédemment, nous avons appris à déployer des applications web basées sur HTML. Ensuite, essayons de déployer une application utilisant un framework frontend plus courant : React. Comparé au HTML pur, React est considéré comme un framework de développement frontend plus mature et moderne. Il organise la structure des pages de manière componentisée, accélérant significativement le développement de pages complexes. C'est un choix très mainstream dans les projets de niveau entreprise. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image31.png) + +#### Refactoriser en architecture React + +Dans Trae, il vous suffit de dire à l'Agent : « Aidez-moi à refactoriser ce code en architecture React », pour transformer assez facilement la structure basée sur HTML en un projet React. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image32.png) + +Cependant, comparé à de simples fichiers HTML, les applications React dépendent d'outils de build et de structures de projet plus complexes, ce qui rend le processus de déploiement un peu plus compliqué. Un problème typique concerne la configuration des ports : par défaut, une application React écoute généralement le port 3000 (vous pouvez le voir dans les fichiers de configuration ou les journaux de démarrage). + +Cependant, un tel déploiement échouera sur Zeabur — car Zeabur ne supporte que les applications qui écoutent le port 8080. Autrement dit, pour que l'application React fonctionne correctement sur Zeabur, nous devons d'abord changer le port d'écoute par défaut de 3000 à 8080. + +Pour effectuer correctement cette configuration, nous devons d'abord clarifier deux concepts : qu'est-ce qu'un « port (Port) », et que signifie « port d'écoute (Listening Port) ». + +#### Qu'est-ce qu'un port ? + +> En informatique réseau, un port peut être compris comme un « point de communication logique » servant à distinguer les différents services réseau s'exécutant sur un même appareil. Pour faire une analogie simple, si l'adresse IP est comme un « numéro de rue » (par exemple 162.128.1.1), alors le numéro de port est comme le « numéro de chambre » des différents locaux dans cet immeuble — chaque chambre correspond à un service (par exemple un serveur web, un service de messagerie, ou votre application React). +> +> Le numéro de port est représenté par un entier 16 bits, avec une plage de valeurs de 0 à 65535. + +Si vous ne souhaitez pas retenir ces détails, retenez simplement : le port est une partie nécessaire de la constitution d'une « adresse d'accès réseau ». + +Quand nous accédons à des sites web ou des adresses IP, nous ne saisissons généralement pas manuellement le numéro de port, car le port par défaut du web est 80 ou 443 (HTTPS). La plupart des navigateurs utilisent automatiquement ces ports standards. Pour certains ports spéciaux, comme le port 3000 par défaut de React ou le port 8080 requis par Zeabur, nous devons ajouter `:3000` ou `:8080` après l'adresse pour accéder au contenu correspondant. + +#### Qu'est-ce que le « port d'écoute » ? + +> Le « port d'écoute » désigne le port qu'un programme « ouvre et surveille » activement sur un appareil. Quand une application définit un port d'écoute, elle indique en fait au système d'exploitation : « Je vais attendre des requêtes réseau sur ce port en permanence — dès qu'une requête arrive, transférez-la-moi. » + +Pour comprendre de manière plus imagée : imaginez que votre ordinateur est un immeuble de bureaux, l'adresse IP est l'adresse de cet immeuble. L'immeuble abrite de nombreuses entreprises ou départements, occupant différentes chambres, dont les numéros sont les numéros de port. + +Quand le serveur de développement React par défaut démarre, il « ouvre » la porte d'une chambre et y place une « réception » — le numéro de cette chambre est son port d'écoute : 3000. + +Parallèlement, le programme React indique à la « gestion de l'immeuble » (le système d'exploitation) : « Je suis dans la chambre 3000, veuillez me transférer tout le courrier (requêtes réseau) adressé au 3000. » + +Ainsi, quand vous accédez au site React, la requête arrive d'abord à l'immeuble ; la gestion voit que la requête est destinée à la chambre 3000 et la transmet immédiatement à la « réception » de React, qui la traite et renvoie le résultat — c'est le processus d'accès à l'application React. + +Quand vous exécutez `npm start` localement (commande par défaut pour démarrer le serveur de développement React, également exécutable depuis la barre latérale de l'Agent Vibe Coding), le serveur de développement React définit automatiquement le port d'écoute sur 3000. +Or, la conception de la plateforme Zeabur fait qu'elle ne « reconnaît » que les applications écoutant le port 8080. Si votre application React utilise toujours le port 3000 par défaut, Zeabur ne pourra pas transférer correctement les requêtes vers votre application, ce qui entraînera l'échec du déploiement. + +#### Modifier le port d'écoute par défaut + +Pour remplacer le port d'écoute par défaut de React (3000) par le port 8080 requis par Zeabur, il existe plusieurs méthodes. La plus simple est de donner directement cette instruction à l'Agent dans Trae : « Aidez-moi à changer le port par défaut de ce projet React en 8080. » Trae modifiera les fichiers de configuration correspondants dans le projet. Une fois la modification effectuée, il vous suffit de reconstruire le projet et de l'uploader sur Zeabur comme précédemment. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image33.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image34.png) + +Dans les paramètres réseau, spécifiez une URL d'accès, de la même manière que pour le déploiement d'un projet HTML, et vous pourrez lancer la version React du service. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image35.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image36.png) + +Pour les autres programmes nécessitant une modification du numéro de port, vous pouvez adopter la même approche : modifier d'abord le port par défaut, puis uploader sur Zeabur pour le déploiement. Vous maîtrisez désormais les compétences de base pour déployer des applications web courantes sur un serveur. + +Vous pouvez essayer de faire construire par Trae différents types d'applications et les déployer sur le serveur par défaut de Zeabur. Dans les cours suivants, nous apprendrons également comment déployer des applications sur des serveurs cloud que vous avez achetés vous-même. + +--- + +# Comment arrêter et supprimer un projet (Zeabur) + +Étant donné que l'activation des ressources liées aux serveurs génère des coûts, il est important de prendre l'habitude de « fermer les services inutilisés en temps opportun » pour éviter d'épuiser votre quota gratuit mensuel. + +Pour trouver l'interface de gestion du projet, cliquez d'abord sur l'option « Settings » du projet. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image21.png) + +Sur la page des paramètres, faites défiler jusqu'en bas et vous verrez une interface similaire à celle-ci : + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image22.png) + +Vous pouvez cliquer sur « Suspend All Services » pour suspendre tous les services et réduire les coûts ; si un service rencontre un problème, vous pouvez cliquer sur « Restart All Services » pour redémarrer tous les services. Si vous êtes sûr de ne plus avoir besoin de ce projet, vous pouvez cliquer sur « Delete Project » pour le supprimer définitivement. + +--- + +# Résumé + +Dans ce tutoriel, nous avons présenté quatre plateformes de déploiement d'applications web courantes : + +1. **Tencent CloudBase** : adapté aux utilisateurs en Chine, accès rapide, bonne intégration avec l'écosystème WeChat +2. **Vercel** : adapté aux projets utilisant des frameworks frontend modernes, intégration étroite avec GitHub, accélération CDN mondiale +3. **Netlify** : fonctionnalités complètes, support du traitement de formulaires et de l'authentification, adapté aux sites statiques nécessitant des fonctionnalités avancées +4. **Zeabur** : adapté aux projets complexes, templates de services riches, support de multiples méthodes de déploiement + +Le choix de la plateforme dépend de vos besoins spécifiques : +- Si vous ciblez principalement les utilisateurs en Chine, recommandez **CloudBase** +- Si vous utilisez des frameworks comme React/Next.js, recommandez **Vercel** ou **Netlify** +- Si vous avez besoin de fonctionnalités avancées comme le traitement de formulaires, l'authentification, recommandez **Netlify** +- Si vous devez déployer des services comme Dify, n8n, recommandez **Zeabur** + +Quel que soit le choix de la plateforme, le processus principal de déploiement est similaire : préparer le code -> choisir la plateforme -> configurer les paramètres de build -> déployer en ligne. Une fois ces compétences maîtrisées, vous pourrez partager vos applications développées avec le monde entier ! diff --git a/docs/fr-fr/stage-2/frontend/design-to-code/index.md b/docs/fr-fr/stage-2/frontend/design-to-code/index.md new file mode 100644 index 0000000..f075b32 --- /dev/null +++ b/docs/fr-fr/stage-2/frontend/design-to-code/index.md @@ -0,0 +1,362 @@ +# Du prototype de conception au code de projet + +::: tip 🎯 Question centrale +**Comment transformer les prototypes des outils de conception en code frontend véritablement exécutable dans un navigateur ?** +::: + +--- + +## 1. Trois chemins du prototype au code + +Après avoir terminé la conception d'interface avec des outils de conception frontend modernes comme Figma ou MasterGo, une question très pratique se pose naturellement : comment convertir ces maquettes structurellement complètes en code frontend véritablement exécutable dans un navigateur ? + +En général, la transformation du prototype en code suit trois chemins typiques : + +| Chemin | Méthode | Caractéristiques | Scénario applicable | +|------|------|------|------| +| **Chemin 1** | Utiliser un grand modèle multimodal pour restaurer le code à partir d'une image | Flexible, ne nécessite pas d'outil spécifique | Validation rapide de prototype, pages simples | +| **Chemin 2** | Exporter le code via les capacités propres de la plateforme ou des plugins | Haute fidélité de restitution, forte éditable | Utilisateurs Figma/MasterGo | +| **Chemin 3** | Combiner la plateforme avec les capacités MCP pour exporter le code | Haut degré d'automatisation, personnalisable | Flux de travail nécessitant une intégration approfondie | + +Cet article présentera en détail les méthodes de mise en œuvre de ces trois chemins, pour vous aider à choisir le flux de travail le plus adapté selon les besoins de votre projet. + +::: tip 📚 Prérequis +Avant de commencer cette section, il est recommandé d'avoir étudié le tutoriel [Introduction à Figma et MasterGo](../figma-mastergo/), afin de maîtriser les opérations de base des outils de conception frontend. +::: + +--- + +## 2. Chemin 1 : Restauration directe du code par IA multimodale + +Les grands modèles dotés de capacités visuelles possèdent nativement la capacité de convertir des images en code. Il suffit d'importer directement la capture de la maquette dans la boîte de dialogue, puis de demander au grand modèle de générer le code complet du résultat. + +### 2.1 Processus opérationnel + +1. **Capturer l'image de la maquette** + - Dans Figma ou MasterGo, exportez la page conçue au format PNG ou JPG + - Assurez-vous que la capture contient la mise en page complète de la page + +2. **Choisir un modèle IA multimodal** + - Vous pouvez utiliser Gemini, Qwen, Claude et d'autres modèles prenant en charge l'entrée d'image + - Nous utiliserons Gemini pour la démonstration + +3. **Rédiger le prompt** + ``` + Veuillez générer le code HTML/CSS correspondant à partir de cette maquette de conception. + Exigences : + - Utiliser une mise en page CSS moderne (Flexbox/Grid) + - Design responsive, adapté aux différentes tailles d'écran + - Inclure tous les éléments UI visibles + - Couleurs et tailles de police fidèles à la maquette autant que possible + ``` + +![](/zh-cn/stage-2/frontend/design-to-code/images/image42.png) + +4. **Obtenir et sauvegarder le code** + - Demander au modèle de retourner le code HTML complet + - Sauvegarder sous un seul fichier `.html` pour faciliter les tests locaux + - Vous pouvez ensuite le convertir en React ou d'autres frameworks dans votre IDE local + +### 2.2 Problèmes courants et solutions + +La génération de pages n'est pas une tâche simple. Vous pourriez rencontrer de nombreux problèmes au cours du processus : + +| Problème | Solution | +|------|----------| +| Disposition inégale de l'interface | Décrire à l'IA le problème de mise en page spécifique, demander d'ajuster le margin/padding du CSS | +| Affichage incomplet de l'interface | Vérifier si le viewport est correctement défini, demander d'ajouter des points de rupture responsive | +| Fidélité des couleurs imprécise | Utiliser un outil de pipette pour obtenir les valeurs de couleur exactes de la maquette et les fournir à l'IA | +| Police non correspondante | Spécifier le nom exact de la police ou demander d'utiliser Google Fonts comme substitut | + +::: tip 💡 Astuce +Il est recommandé de générer d'abord le code HTML, puis de l'importer dans votre IDE local pour le convertir en framework React. Vous obtiendrez ainsi plusieurs fichiers HTML indépendants, faciles à convertir uniformément en framework. +::: + +### 2.3 MasterGo AI pour la génération de pages + +MasterGo offre également une puissante fonctionnalité de génération de pages par IA, capable de générer directement du code web exploitable à partir d'images de référence. + +#### Trouver l'entrée de la fonctionnalité IA + +Dans la barre d'outils supérieure de l'interface d'édition MasterGo, vous trouverez le bouton d'outil IA : + +![](/zh-cn/stage-2/frontend/design-to-code/images/image47.png) + +#### Processus de génération + +1. **Télécharger une image de référence** + - Téléchargez l'image de référence de conception de la même manière que pour l'IA multimodale + - Ajoutez une description textuelle des besoins + +2. **Consulter le résultat de la génération** + +![](/zh-cn/stage-2/frontend/design-to-code/images/image48.png) + +![](/zh-cn/stage-2/frontend/design-to-code/images/image49.png) + +3. **Obtenir le code** + - Cliquez sur le bouton bleu « Insérer dans le canevas » pour éditer directement la page web générée + - Ou cliquez sur le bouton « Code » à droite pour copier le contenu du code en local + +![](/zh-cn/stage-2/frontend/design-to-code/images/image50.png) + +--- + +## 3. Chemin 2 : Capacités de la plateforme ou plugins pour exporter le code + +### 3.1 Figma Make pour la génération de code + +Figma Make est un outil de conception IA officiellement lancé par Figma, capable de restaurer avec haute précision l'interface UI d'un prototype web à partir de prompts ou d'images de référence saisis par l'utilisateur. + +#### Caractéristiques fonctionnelles + +- **Restauration haute précision** : par rapport à la génération de code par IA native, l'effet est meilleur +- **Éditable** : le résultat généré peut être converti en fichier Figma Design modifiable +- **Intégration GitHub** : supporte la synchronisation directe du code vers GitHub + +::: tip 🔑 Note sur les permissions +L'utilisation complète de Figma Make nécessite les permissions utilisateur Pro. Les étudiants peuvent obtenir gratuitement les permissions Pro via la certification éducation. +::: + +#### Étapes opérationnelles + +1. **Accéder à Figma Make** + - Cliquez sur le bouton Make sur la page d'accueil de Figma + - Ou visitez [Figma Make](https://www.figma.com/make) + +2. **Télécharger une image de référence** + - Téléchargez l'image de conception que vous souhaitez restaurer dans la boîte de dialogue + - Ajoutez un prompt décrivant les besoins + +![](/zh-cn/stage-2/frontend/design-to-code/images/image43.png) + +3. **Consulter le résultat de la génération** + - Attendez quelques instants pour voir le résultat rendu + - Cliquez sur le bouton de lecture en haut à droite pour un aperçu plein écran + +![](/zh-cn/stage-2/frontend/design-to-code/images/image44.png) + +4. **Ajustements de détail** + - Cliquez sur l'icône de l'éditeur en haut à droite (icône souris et règle) + - Retournez dans l'interface familière de Figma Editor pour des ajustements détaillés + +![](/zh-cn/stage-2/frontend/design-to-code/images/image45.png) + +5. **Exporter le code** + - Après être satisfait des ajustements, sélectionnez l'export de code + - Vous pouvez vous connecter directement à GitHub pour sauvegarder le code + +![](/zh-cn/stage-2/frontend/design-to-code/images/image46.png) + +### 3.2 Export de code via plugins + +Outre les fonctionnalités IA natives de la plateforme, Figma et MasterGo supportent tous deux l'export de code via des plugins : + +**Plugins Figma courants :** +- **Figma to Code** : convertit les maquettes en code React, Vue, HTML, etc. +- **Anima** : génération de code haute fidélité, supporte les effets d'interaction +- **Locofy** : outil de conversion design vers code piloté par IA + +**Étapes d'utilisation :** +1. Ouvrez le panneau des plugins dans Figma (Plugins) +2. Recherchez et installez le plugin d'export de code souhaité +3. Sélectionnez les éléments de conception à exporter +4. Exécutez le plugin, choisissez le framework cible et le format de code +5. Copiez ou téléchargez le code généré + +--- + +## 4. Chemin 3 : Combiner la plateforme avec MCP pour exporter le code + +### 4.1 Qu'est-ce que MCP ? + +MCP (Model Context Protocol, Protocole de Contexte de Modèle) est un protocole standard ouvert qui permet aux modèles IA d'accéder de manière sécurisée et contrôlée à des outils externes et des sources de données. Dans le contexte des outils de conception frontend, MCP permet aux grands modèles de lire directement la structure, les styles et les informations de composants des fichiers de conception, pour générer du code plus précis. + +### 4.2 Principe de fonctionnement de MCP + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ Modèle IA │ ←→ │ Serveur MCP │ ←→ │ Outil de │ +│ (Claude etc)│ │ (adaptation) │ │ conception │ +│ │ │ protocole │ │(Figma/MasterGo)│ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +**Flux de travail :** +1. Le modèle IA envoie une requête à l'outil de conception via le protocole MCP +2. L'outil de conception retourne des données de conception structurées (calques, styles, composants, etc.) +3. Le modèle IA comprend la structure de conception et génère le code correspondant +4. Le code peut être directement exporté ou synchronisé vers l'environnement de développement + +### 4.3 Figma + MCP en pratique + +#### Préparation de l'environnement + +1. **Installer le serveur MCP** + ```bash + # Installer le serveur Figma MCP via npx + npx figma-mcp-server + ``` + +2. **Configurer Claude Desktop ou un autre outil IA supportant MCP** + ```json + { + "mcpServers": { + "figma": { + "command": "npx", + "args": ["figma-mcp-server"], + "env": { + "FIGMA_ACCESS_TOKEN": "your-figma-token" + } + } + } + } + ``` + +3. **Obtenir un Figma Access Token** + - Connectez-vous à Figma → Settings → Personal Access Tokens + - Générez un nouveau Token et sauvegardez-le + +#### Flux d'utilisation + +1. **Activer la connexion MCP dans l'outil IA** + - Ouvrez Claude Code ou un autre IDE supportant MCP + - Confirmez que le serveur MCP est connecté + +2. **Fournir le lien du fichier de conception** + ``` + Utilisateur : Aidez-moi à convertir ce design Figma en code React + Lien : https://www.figma.com/file/xxxxx + + IA : Je me suis connecté à Figma via MCP, lecture de la structure du fichier de conception en cours... + ``` + +3. **L'IA analyse et génère automatiquement le code** + - Le serveur MCP récupère l'arbre de calques du fichier de conception + - L'IA comprend la structure des composants et les propriétés de style + - Génère des composants React/Vue avec un nommage et une structure corrects + +4. **Itération et optimisation** + ``` + Utilisateur : Veuillez extraire le composant bouton en un composant réutilisable indépendant + + IA : D'accord, j'ai identifié via MCP le composant Button dans le système de conception, + génération en cours d'un composant React avec interface props... + ``` + +### 4.4 Avantages de MCP + +| Caractéristique | Approche traditionnelle | Approche MCP | +|------|----------|----------| +| **Précision des données** | Dépend des captures, détails potentiellement perdus | Lecture directe des données de conception brutes | +| **Identification des composants** | L'IA doit deviner les limites des composants | Obtention précise des définitions de composants | +| **Fidélité des styles** | Estimation basée sur les pixels | Obtention des tokens de conception exacts | +| **Efficacité d'itération** | Chaque modification nécessite une nouvelle capture | Synchronisation en temps réel des changements de conception | +| **Degré d'automatisation** | Copier-coller manuel | Écriture directe possible dans les fichiers du projet | + +### 4.5 Outils MCP actuellement disponibles + +**MCP pour outils de conception :** +- **Figma MCP Server** : implémentation MCP officiellement supportée +- **MasterGo MCP** : adaptateur MasterGo développé par la communauté + +**MCP pour environnements de développement :** +- **Claude Code** : support natif du protocole MCP +- **Cline** : plugin VS Code, supporte les connexions MCP +- **Trae** : peut activer les fonctionnalités MCP via configuration + +::: tip 🔮 Perspectives futures +Le protocole MCP évolue rapidement, et l'intégration entre outils de conception et environnements de développement deviendra encore plus étroite. D'autres solutions de synchronisation en un clic du design vers le code devraient apparaître, réduisant encore davantage la distance entre conception et développement. +::: + +--- + +## 5. Travail après l'export du code + +### 5.1 Tests locaux + +Après avoir obtenu le code, ouvrez-le dans votre IDE local et testez-le : + +1. **Créer un nouveau projet** + ```bash + # Si c'est un fichier HTML, ouvrez-le directement dans le navigateur + open index.html + + # Si c'est un projet React/Vue + npm install + npm run dev + ``` + +2. **Collaborer avec un IDE IA** + - Importez le code généré dans Trae ou un autre IDE IA + - Laissez l'IA vous aider à corriger les problèmes de mise en page et à ajouter des fonctionnalités interactives + +### 5.2 Traitement des problèmes courants + +| Étape | Problème | Solution | +|------|------|----------| +| Mise en page | Éléments décalés | Vérifier les propriétés CSS display et position | +| Styles | Couleurs incohérentes | Utiliser les outils de développement du navigateur pour vérifier les couleurs réellement appliquées | +| Responsive | Affichage anormal sur mobile | Ajouter des points de rupture media query | +| Interaction | Boutons sans réponse | Vérifier la liaison des événements JavaScript | + +--- + +## 6. Comparaison des trois chemins et recommandations + +### 6.1 Comparaison des chemins + +| Dimension | Chemin 1 : IA multimodale | Chemin 2 : Capacités plateforme | Chemin 3 : MCP | +|------|------------------|------------------|-------------| +| **Difficulté de prise en main** | ⭐ Simple | ⭐⭐ Moyen | ⭐⭐⭐ Assez complexe | +| **Précision de restitution** | ⭐⭐⭐ Moyenne | ⭐⭐⭐⭐ Élevée | ⭐⭐⭐⭐⭐ Maximale | +| **Flexibilité** | ⭐⭐⭐⭐⭐ Élevée | ⭐⭐⭐ Moyenne | ⭐⭐⭐⭐ Assez élevée | +| **Degré d'automatisation** | ⭐⭐ Faible | ⭐⭐⭐ Moyen | ⭐⭐⭐⭐⭐ Maximale | +| **Coût** | Faible (facturation à l'usage API) | Moyen (peut nécessiter Pro) | Faible (outils open source) | + +### 6.2 Recommandations + +**Choisir le Chemin 1 (IA multimodale) si :** +- Vous avez besoin de valider rapidement une idée +- L'outil de conception n'est pas fixe, vous changez souvent +- Les exigences de fidélité de restitution ne sont pas très élevées +- Le budget est limité + +**Choisir le Chemin 2 (capacités plateforme) si :** +- L'équipe utilise principalement Figma ou MasterGo +- Une restitution de code haute précision est nécessaire +- Les designers et développeurs doivent collaborer fréquemment +- Vous êtes prêt à investir dans une version Pro + +**Choisir le Chemin 3 (MCP) si :** +- Vous visez le plus haut degré d'automatisation +- Vous avez les compétences techniques pour configurer l'environnement MCP +- Le projet nécessite des itérations fréquentes du design vers le code +- Vous souhaitez établir un flux de travail standardisé design-développement + +--- + +## 7. Résumé + +Au cours de ce chapitre, vous avez maîtrisé les trois chemins clés du prototype de conception au code : + +1. **Conversion directe par IA multimodale** : flexible et rapide, adaptée à la validation de prototypes +2. **Capacités natives de la plateforme** : haute fidélité, adaptée aux flux de travail de conception professionnels +3. **Intégration du protocole MCP** : degré d'automatisation le plus élevé, représente la tendance future + +::: tip 💡 Meilleures pratiques +- **Recommandation pour les débutants** : commencer par le Chemin 1 (IA multimodale) pour une prise en main rapide +- **Collaboration en équipe** : utiliser le Chemin 2 (capacités plateforme) pour garantir la cohérence du design +- **Priorité à l'efficacité** : essayer le Chemin 3 (MCP) pour établir un flux de travail automatisé +- **Utilisation mixte** : basculer flexiquement entre les différents chemins selon la phase du projet +::: + +--- + +## Ressources de référence + +- [Introduction à Figma et MasterGo](../figma-mastergo/) - Apprendre les bases des outils de conception +- [Créons ensemble des portraits de Poudlard](../hogwarts-portraits/) - Projet pratique complet +- [Documentation officielle MCP](https://modelcontextprotocol.io/) - Comprendre les détails du protocole +- [Documentation officielle Figma Make](https://help.figma.com/hc/en-us/sections/360007453634-Figma-Make) +- [Tutoriels MasterGo AI](https://mastergo.com/tutorials) diff --git a/docs/fr-fr/stage-2/frontend/figma-mastergo/index.md b/docs/fr-fr/stage-2/frontend/figma-mastergo/index.md new file mode 100644 index 0000000..c83581a --- /dev/null +++ b/docs/fr-fr/stage-2/frontend/figma-mastergo/index.md @@ -0,0 +1,303 @@ +# Introduction à Figma et MasterGo + + + +::: tip 🎯 Question centrale +**Comment créer un prototype de page web depuis zéro avec des outils de conception modernes ?** +::: + +--- + +## 1. Pourquoi apprendre les outils de conception frontend ? + +Avant de commencer, nous devons comprendre une question : pourquoi a-t-on besoin d'apprendre des « outils de conception frontend » ? Après tout, on peut très bien construire des pages directement en HTML/CSS, alors est-ce vraiment nécessaire d'apprendre un logiciel et une technologie supplémentaires ? + +En réalité, faire fonctionner une page et bien concevoir un produit sont deux concepts totalement différents. Le code se préoccupe uniquement de comment rendre dans le navigateur et comment s'exécuter sur différents appareils ; les outils de conception frontend résolvent les problèmes de distribution de l'information : comment organiser les interactions frontend, comment gérer la navigation entre les pages, comment hiérarchiser les priorités visuelles. Il suffit de créer un canevas dans l'outil de conception pour comparer et déterminer la mise en page, la hiérarchie d'information et les modes d'interaction sur un seul écran, afin de choisir la présentation la plus appropriée. + +Si l'on commence directement à coder ou si l'on demande à l'IA de générer des pages frontend complètes, l'expérience utilisateur ne sera généralement pas très bonne. Les produits rigoureux prennent en compte le confort de l'interaction utilisateur-frontend ainsi que la répartition du contenu à transmettre sur les différentes pages. En concevant d'abord la mise en page du point de vue de l'utilisateur, puis en procédant à la conversion ou à la génération de code. + +De plus, du point de vue de la collaboration en équipe, les outils de conception frontend réduisent également les coûts de coopération entre les différentes parties : designers, chefs de produit et développeurs ne se retrouvent plus chacun face à des images mentales ou des descriptions de code abstraites. Ils supportent la collaboration en temps réel, permettant à tous de discuter de la gestion des versions, des changements de besoins et des retours autour d'un canevas visible, annotable et itérable. Plus encore, les outils de conception frontend modernes ne se contentent plus d'être des logiciels de dessin : génération partielle de code en un clic, gestion de systèmes de conception et de bibliothèques de composants. Les outils de conception de nouvelle génération peuvent automatiser ou traiter par lots une grande partie du travail répétitif (alignement, annotation, exportation, modification de styles), améliorant considérablement l'efficacité du développement de la conception de pages. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image8.png) + +### 1.1 L'évolution des outils de conception frontend + +Au fil du temps, les outils dits de conception frontend représentent en réalité une technologie en constante évolution. De l'ère Photoshop des années 90, centrée sur l'édition d'images bitmap locales, à Sketch qui a apporté les flux de travail vectoriels et componentisés vers 2010, puis à Figma qui a définitivement déplacé la collaboration vers le cloud après 2016. Les équipes de conception sont progressivement passées du travail individuel à la collaboration en temps réel. En 2025, l'IA est désormais intégrée de manière concrète dans ces outils : de la « génération de maquettes de page à partir d'une phrase » à la « conversion directe de maquettes en structures frontend exécutables », le « design as code » et la « co-création homme-machine » passent du concept à une véritable productivité. + +Dans cette section, nous présenterons les deux outils de conception frontend modernes les plus représentatifs : Figma et MasterGo. D'une part, ils couvrent tous les deux les capacités clés nécessaires à l'UI/UX moderne (édition vectorielle, système de composants, mise en page automatique, livraison de code, etc.), et peuvent vous accompagner dans le cycle complet, du wireframe au haute fidélité jusqu'à la livraison au développement. D'autre part, ces deux outils ont progressivement intégré des fonctionnalités IA pratiques après 2025, vous aidant à transformer vos maquettes en véritables programmes exécutables tout en préservant le prototype intact. + +## 1.2 Le voyage de la création + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image9.png) + +À l'époque où les outils dédiés au frontend n'existaient pas encore, le travail de conception visuelle de toute l'industrie du design d'interface était, pendant très longtemps, assuré par des logiciels de conception « polyvalents » comme Photoshop. Les designers créaient localement, par superposition de calques, la conception visuelle globale de la page, puis livraient le fichier source .psd, souvent volumineux, à l'ingénieur frontend — qui devait alors accomplir manuellement trois tâches fastidieuses mais cruciales pour reproduire fidèlement la maquette : + +Premièrement, le « découpage d'images » : il fallait extraire un par un les éléments visuels indépendants (boutons, icônes, logos, modules d'arrière-plan, etc.) de la structure multicouche du fichier .psd, puis les exporter dans des formats d'image directement chargeables par le web comme PNG ou JPG (puisque le web ne peut pas identifier directement les informations de calques PSD, il ne peut s'appuyer que sur ces images découpées pour afficher les détails). + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image10.png) + +Deuxièmement, le « mesurage des dimensions » : il fallait utiliser l'outil de mesure du logiciel pour vérifier逐一 la largeur, la hauteur et les espacements (margin/padding) entre différents modules, afin de garantir que toutes les dimensions soient précises au pixel près. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image11.png) + +Troisièmement, l'« extraction des annotations » : il fallait extraire de la maquette les paramètres invisibles mais indispensables — comme la taille de police, le poids, l'interligne, les valeurs de couleur RGB ou HEX de chaque bloc de couleur, etc. Cela équivalait à extraire et consigner manuellement les « spécifications de conception » que le designer n'avait pas écrites sur papier. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image12.png) + +Ce n'est qu'après ces étapes que la phase d'implémentation frontend pouvait véritablement commencer. Que l'on utilise du HTML/CSS/JS natif ou des frameworks comme Vue ou React, le processus fondamental est le même. Le frontend utilise le « conteneur comme support central », reconstruisant la structure de la page selon la hiérarchie et la sémantique des différents modules du design. Ici, le conteneur désigne une unité avec des limites de mise en page clairement définies, dédiée à l'accueil et à l'organisation des éléments enfants. Il n'affiche pas directement le contenu, mais délimite la plage d'arrangement des éléments internes via des règles comme Flex ou Grid. Les « blocs structurels » (comme la barre de navigation supérieure, la barre latérale, la zone de liste d'articles, le pied de page, etc. — zones fonctionnelles/contenus visibles) s'appuient sur les conteneurs ; chaque bloc structurel imbrique à son tour des conteneurs plus petits pour organiser les éléments. Par exemple, un élément de liste d'articles sera contrôlé par un « conteneur d'élément de liste » qui gère le remplissage interne et la mise en page d'ensemble, puis enveloppe les détails comme le titre, le résumé, l'heure et l'icône de couverture. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image13.png) + +Dans les frameworks frontend modernes, ces « blocs structurels (et les conteneurs et éléments associés) » sont généralement implémentés sous forme de « composants ». Un composant peut être simplement compris comme une unité d'interface réutilisable avec des limites claires, intégrant la mise en page des conteneurs et la logique. Il contient à la fois les conteneurs qui contrôlent l'apparence et l'arrangement (par exemple, le « composant bouton » définit la largeur, la hauteur et les coins arrondis via le conteneur ; le « composant carte d'article » organise la position du titre et de la couverture via le conteneur) et encapsule la logique d'interaction. Les éléments qui apparaissent de manière répétée dans la maquette avec une apparence cohérente (comme les boutons de style uniforme, les cartes d'articles réutilisées) sont abstraits en composants dans le code : ils peuvent être réutilisés dans différentes pages/scènes, réduisant le développement répétitif, et garantissent une cohérence élevée de mise en page et de style à travers les règles unifiées des conteneurs internes du composant. + +Ensuite, le frontend utilise le système de styles pour reproduire le visuel et la mise en page. Les ressources exportées lors de la phase de découpage d'images (PNG, JPG, etc.) sont intégrées comme ``, images d'arrière-plan dans les composants ou blocs structurels, ou importées selon les méthodes recommandées par chaque framework. Les valeurs spécifiques de largeur, hauteur, espacement et interligne obtenues lors du mesurage sont transcrites en propriétés de style comme `width`, `height`, `margin`, `padding`, `line-height`, appliquées aux composants ou blocs structurels correspondants. Les couleurs, polices, ombres, coins arrondis et états hover/active compilés lors de l'annotation sont quant à eux appliqués via `color`, `font-family`, `font-size`, `box-shadow`, `border-radius` et les pseudo-classes ou classes d'état dans les solutions spécifiques comme CSS, CSS Modules, CSS-in-JS ou Tailwind. À ce stade, le découpage, les dimensions et les annotations fournissent un ensemble de paramètres visuels précis, tandis que les composants et blocs structurels fournissent les unités d'organisation de code pour porter ces paramètres. L'ensemble forme une implémentation d'interface maintenable et réutilisable. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image14.png) + +Cependant, le modèle centré sur les fichiers locaux est intrinsèquement inefficace. Les versions sont transmises par email et cloud, les anciens et nouveaux fichiers se confondent facilement, et la collaboration entre design et développement repose largement sur les méthodes d'interaction complexes décrites ci-dessus, avec des coûts de coopération et des risques d'erreur non négligeables. + +Avec l'essor du mobile, la complexité des interfaces et les besoins d'itération rapide ont fortement augmenté, et le côté « tout-en-un » de Photoshop est apparu de plus en plus lourd. C'est à cette période qu'est apparu Sketch. Sketch se concentre sur le design UI lui-même, débarrassé de la plupart des contraintes liées au post-traitement visuel. Il utilise les Symbols pour componentiser les éléments très réutilisables comme les boutons, la navigation et les champs de saisie — une seule modification se synchronise globalement. Combiné à des outils comme Zeplin, il génère automatiquement les annotations et les fragments de style. Sketch a introduit la « pensée composant » dans le flux de travail de conception. Cependant, il reste une application de bureau basée sur des fichiers locaux ; la collaboration en temps réel nécessite des contournements via le cloud, des plugins tiers ou des outils de versionning, et ne résout pas fondamentalement le problème de « plusieurs personnes modifiant simultanément le même fichier ». + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image15.png) + +Ce qui a véritablement changé la donne, c'est Figma. Dès 2016, il a intégré le design UI, le prototypage, les commentaires et la collaboration dans le navigateur, avec des fonctionnalités modernes : curseurs multiples en temps réel, commentaires en ligne, timeline de versions, liens de partage, etc. Ce qui semble très simple aujourd'hui représentait à l'époque un défi direct au modèle Photoshop/Sketch. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image16.png) + +Dès lors, le design d'interface n'est plus constitué de fichiers éparpillés sur les ordinateurs de chacun, mais d'un canevas cloud centralisé, en ligne et mis à jour en temps réel. Autour de ce canevas, on peut imaginer aller encore plus loin, en brouillant les frontières entre design et code frontend via l'automatisation ou l'IA. + +Au tout début, nous ne pouvions nous appuyer que sur divers plugins de plateforme pour exporter de manière semi-automatique les composants et les informations de style des maquettes sous forme de fragments de code (comme des squelettes de composants React/Vue, des variables CSS, etc.). L'essence de cette approche était l'extraction d'informations structurées via des plugins. Ensuite, avec l'évolution des capacités des plateformes, la plupart d'entre elles ont commencé à supporter les fonctionnalités MCP (Model Context Protocol, Protocole de Contexte de Modèle) pour les grands modèles : ce protocole fournit un mécanisme standardisé permettant aux grands modèles d'accéder de manière sécurisée et contrôlée aux fichiers de conception, aux interfaces de plugins et aux métadonnées de projet, facilitant ainsi l'exportation des maquettes en code. + +Plus tard encore, sur la base des plugins et de MCP, l'automatisation du code frontend est passée à un stade de support natif de la déduction directe de la structure de code à partir des maquettes. Nous pouvons désormais générer en un clic dans l'outil de conception le squelette du projet frontend, la hiérarchie des composants, le système de styles et le code correspondant. Cela libère designers et développeurs frontend du travail manuel de transfert des détails de conception, leur permettant de consacrer davantage d'énergie à l'optimisation de l'expérience utilisateur et aux mises à jour itératives des versions fonctionnelles. + +--- + +## 2. Introduction à Figma + +Passons maintenant des concepts abstraits à la pratique. Faute de temps, nous n'apprendrons que la logique de base de Figma, afin que même si vous n'avez jamais utilisé d'outil de conception, vous puissiez suivre les exercices. Si vous souhaitez apprendre Figma de manière complète, veuillez consulter les tutoriels officiels détaillés fournis par Figma : https://help.figma.com/hc/en-us/sections/30880632542743-Figma-Design-for-beginners + +Vous pouvez aussi consulter le tutoriel suivant pour construire rapidement un site simple comme un portfolio personnel : https://help.figma.com/hc/en-us/sections/35895585621655-Figma-Sites-collectio + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image17.png) + +Sur la gauche se trouve l'entrée pour la création de projets et la gestion des ressources, et en haut à droite, plusieurs boutons représentent les fonctionnalités courantes de Figma. Parmi eux, Make permet de demander à l'IA de générer d'abord une interface ou une structure approximative à partir d'une phrase, Design est l'espace de travail principal pour dessiner des interfaces web/app, créer des composants et fabriquer des prototypes, FigJam est un tableau blanc d'équipe pour coller des notes, dessiner des flux et mener des discussions préliminaires, Buzz est un outil de production de ressources de marque à grande échelle, utilisé pour générer du contenu en masse afin de maintenir la cohérence de la marque, et Site permet d'organiser ces conceptions en véritables pages web ou sites documentaires accessibles publiquement. + +À première vue, Figma propose de nombreuses fonctionnalités et peut sembler difficile à prendre en main. Mais en réalité, ce type d'outil fonctionnel repose essentiellement sur la pratique : il ne faut pas craindre de faire des erreurs au début, ni chercher à tout réussir du premier coup. Il suffit de commencer à explorer, et avec la pratique, la maîtrise viendra naturellement. + +Dans ce tutoriel, pour une prise en main rapide, nous présenterons brièvement la fonctionnalité Design. + +### 2.1 Créer un nouveau fichier Design + +Depuis la page d'accueil ou l'entrée en haut à droite, sélectionnez **Design** pour créer un nouveau fichier. Vous accéderez à un canevas de conception vide. +Cette interface se divise grossièrement en trois zones : à gauche, les pages et calques, pour visualiser et modifier les relations d'appartenance des pages et éléments ; au centre, le canevas, pour visualiser le résultat actuel ; à droite, les propriétés et styles, pour modifier les formes, couleurs et styles spécifiques ; et en bas, une barre d'outils, pour basculer entre les outils, comprenant la sélection, le dessin de formes, la saisie de texte, les commentaires, les plugins, etc. Après avoir sélectionné un outil, vous pouvez appuyer sur la touche Echap pour revenir à l'outil souris par défaut. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image18.png) + +### 2.2 Créer votre première Frame (planche) + +Avant de placer des éléments, il faut d'abord définir une limite claire pour la page, assumée par la Frame. Vous pouvez sélectionner l'outil Frame dans la barre d'outils inférieure, ou appuyer directement sur la touche F, puis tracer une zone rectangulaire sur le canevas. + +1. Utilisez l'outil Frame dans la barre d'outils inférieure, ou appuyez directement sur `F`. +2. Tracez une zone rectangulaire sur le canevas, puis dans la barre de propriétés de droite, modifiez la largeur, par exemple à `1440`, et la hauteur à `900`. +3. Dans la barre de calques à gauche, renommez cette Frame, par exemple `My First Page` ou le nom de votre projet. + +Cette Frame est le conteneur de page pour un écran entier. Ensuite, le titre, le texte, les boutons, les images, etc. doivent tous être placés à l'intérieur de cette Frame, et non éparpillés n'importe où sur le canevas. Organiser le contenu autour de la Frame comme limite permet de garder la structure sous contrôle lors des réglages de défilement, de l'adaptation aux différentes tailles d'appareils, de l'export d'écrans et de la création de prototypes. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image19.png) + +### 2.3 Placer du texte et des éléments simples dans la Frame + +Maintenant que nous avons un conteneur, apprenons à placer les composants les plus basiques, comme le titre, le sous-titre, le bouton et le bloc d'image placeholder. + +1. Sélectionnez l'outil texte (le `T` dans la barre d'outils inférieure), cliquez dans la Frame et saisissez le titre de la page, par exemple : `My Portfolio`. + Dans les propriétés de droite, augmentez la taille de police (par exemple 96) et mettez le poids en gras. +2. Sous le titre, utilisez à nouveau l'outil texte pour saisir une brève description, par exemple une ou deux phrases expliquant ce que fait la page. + La taille de police peut être plus petite, avec un interligne légèrement plus grand pour une lecture plus aérée. +3. Dessinez une ébauche de bouton : + Avec l'outil rectangle, dessinez un rectangle d'environ `200 × 48` sous le titre, donnez-lui une couleur de remplissage assez visible dans les propriétés de droite, et ajoutez un léger arrondi. + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image20.png) +4. Puis utilisez l'outil texte pour saisir le libellé du bouton au-dessus du rectangle, par exemple `Get Started`. Sélectionnez ensemble le rectangle et le texte, et utilisez les outils d'alignement en haut pour centrer le texte horizontalement et verticalement. +5. Sur le côté du bouton ou en dessous, dessinez un grand rectangle gris clair comme « zone d'image placeholder », qui pourra servir plus tard à afficher une image. + +Arrivé à ce stade, vous avez déjà une « maquette de page d'accueil » très rudimentaire mais structurellement complète : un titre, un paragraphe, un bouton et une zone d'affichage principale. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image21.png) + +### 2.4 Utiliser Auto Layout pour organiser les éléments + +Si tous les éléments sont simplement traînés au hasard, la page deviendra vite chaotique. Un concept très important dans Figma est l'**Auto Layout**, qui permet de transformer un groupe d'éléments en un conteneur avec des règles. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image22.png) + +Vous pouvez sélectionner les trois éléments « titre principal + sous-titre + bouton », puis cliquer sur **Add Auto layout** dans la barre de propriétés de droite. + +Ces trois éléments seront alors enveloppés dans un conteneur. Vous pouvez ajuster les paramètres dans la barre de droite, et la mise en page des éléments s'adaptera automatiquement : + +- Sont-ils disposés verticalement ou horizontalement. +- Quel est l'espacement entre les éléments. +- Quelle est la marge interne (padding) entre l'ensemble et les bords du conteneur. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image23.png) + +De même, l'intérieur du bouton peut aussi utiliser Auto Layout. Nous pouvons obtenir cet effet : lorsque le texte est modifié, la longueur du bouton s'ajuste automatiquement. + +Sélectionnez d'abord le rectangle d'arrière-plan du bouton et le texte du bouton, ajoutez Auto Layout pour que ces deux éléments deviennent un « conteneur bouton ». Ensuite, sélectionnez ce conteneur bouton et réglez la largeur et la hauteur sur **Hug contents**. Ainsi, le texte restera toujours centré dans le bouton, et que le texte soit plus ou moins long, la largeur du bouton s'ajustera automatiquement. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image24.png) + +### 2.5 Transformer le bouton en composant réutilisable + +Nous allons maintenant apprendre un nouveau concept : les composants. Un composant est un élément qui peut être réutilisé. Par exemple, un bouton : dès que vous pressentez que vous l'utiliserez à nouveau, vous pouvez envisager d'en faire un composant. Partons du bouton avec Auto Layout que nous venons de créer : + +1. Sélectionnez l'ensemble du conteneur bouton. +2. Faites un clic droit et choisissez Create component (créer un composant). + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image25.png) + +Ainsi, ce bouton passe d'un groupe de calques ordinaires à un composant maître. Ensuite, si vous avez besoin d'un bouton du même style dans d'autres pages ou Frames, il vous suffit de le glisser depuis le panneau Assets à gauche. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image26.png) + +Tous les boutons ainsi utilisés sont des copies synchronisées de ce maître. Lorsque vous modifiez la couleur, les coins arrondis ou l'espacement du maître, toutes les instances se mettent automatiquement à jour. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image27.png) + +Vous avez maintenant acquis les bases de l'utilisation simple de Figma. Il n'est pas nécessaire de tout comprendre dès le début ; il suffit de suivre ce guide pour créer une première page simple, se familiariser avec ces quelques opérations clés, puis explorer progressivement les capacités supplémentaires des tutoriels officiels. Avec la pratique, la maîtrise viendra. + +--- + +## 3. Introduction à MasterGo + +Après avoir compris le flux de travail de base de Figma, découvrons MasterGo. Vous pouvez considérer MasterGo comme la version chinoise de Figma, avec quelques différences sur certaines fonctionnalités. Dans l'ensemble, il reprend une disposition d'interface et une philosophie d'utilisation similaires à Figma : même canevas, arbre de calques et panneau de propriétés, même support des composants, styles, mise en page automatique et collaboration multi-utilisateurs. Pour plus de détails, consultez le tutoriel officiel de MasterGo : https://mastergo.com/tutorials/12?%E5%85%A8%E7%A8%8B%E9%AB%98%E8%83%BD%EF%BC%8CMasterGo%20%E6%9C%80%E5%AE%8C%E6%95%B4%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%EF%BC%8C%E8%AE%A9%E4%BD%A0%E4%BB%8E%E9%9B%B6%E5%88%B0%E7%B2%BE%E9%80%9A%EF%BC%81 + +### 3.1 Créer un nouveau fichier de conception + +1. **Accéder au tableau de bord MasterGo** + 1. Ouvrez le site officiel de MasterGo et connectez-vous. + 2. Vous arriverez sur la page d'accueil avec la « liste de fichiers / liste de projets », pour gérer vos fichiers de conception. + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image28.png) + +2. **Créer un nouveau fichier** + 1. Cliquez sur le bouton + Fichier de conception en haut à droite, ou choisissez d'importer des fichiers Figma ou autres. + 2. Après avoir cliqué, vous accéderez à un canevas vide : c'est l'espace de travail de conception de MasterGo. + +3. **Découvrir les zones de base de l'interface** + Une fois que vous savez utiliser Figma, l'utilisation de MasterGo est très similaire. L'interface se divise principalement en plusieurs zones : + + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image29.png) + 1. Barre d'outils supérieure : située en haut du canevas, avec à gauche l'emplacement et le nom du fichier, au centre une rangée de boutons d'outils courants (sélection, zone/planche, formes, texte, annotations, commentaires, sélection de plugins et outils IA, etc.), et à droite les membres actuellement en ligne, l'entrée de partage, ainsi que les contrôles de zoom et d'aperçu du canevas. + 2. Panneau latéral gauche : principalement divisé en calques et ressources. En restant sur l'onglet calques, vous voyez la liste des pages et la structure hiérarchique de tous les calques de la page. + 3. Zone de canevas centrale : l'espace de travail pour le dessin et la mise en page. Toutes les Frames, composants et graphiques y sont affichés. + 4. Panneau de propriétés droit : pour visualiser et modifier les propriétés de l'objet sélectionné, comme la taille, la position, l'alignement, le remplissage d'arrière-plan, les bordures, les coins arrondis, etc. Si aucun objet n'est sélectionné, les paramètres du canevas s'affichent, comme la couleur d'arrière-plan, les étiquettes et les options d'export. + +### 3.2 Créer votre première Frame + +Avant de placer des éléments, nous avons besoin d'un conteneur de page pour définir les limites et les dimensions de l'interface. Ce conteneur s'appelle généralement une Frame dans MasterGo. + +**Étapes :** + +1. **Sélectionner l'outil Frame** + 1. Trouvez l'outil Frame / Planche dans la barre d'outils, puis cliquez pour créer directement le contenu avec les paramètres prédéfinis. + 2. Ou utilisez le raccourci (généralement `F`, en cas de différence, se référer à l'interface réelle). +2. **Tracer une zone rectangulaire sur le canevas** + 1. Après avoir tracé, vous verrez une zone avec un cadre de sélection. + 2. Dans le panneau de propriétés de droite, vous pouvez voir la largeur et la hauteur de cette Frame. + 3. Réglez la largeur, par exemple, à `1440`, et la hauteur à `900` (l'une des tailles courantes pour une page web plein écran). +3. **Renommer la Frame** + 1. Dans le panneau de calques à gauche, trouvez cette Frame. + 2. Double-cliquez sur le nom et changez-le pour le nom de votre projet, par exemple : `My First Page`, ou tout autre nom de page de votre choix. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image30.png) + +### 3.3 Créer le contenu de la planche + +Avec le conteneur, en utilisant des méthodes similaires à celles apprises dans Figma, il est facile d'obtenir une page de présentation similaire. (Vous pouvez essayer de copier les éléments textuels de la planche Figma ; l'importation directe par collage des composants texte est prise en charge.) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image31.png) + +Il est à noter que le comportement de la fonctionnalité Auto Layout est légèrement différent. Dans MasterGo, si vous souhaitez obtenir le même effet que Figma où la longueur du bouton s'adapte à la longueur du texte, vous devez d'abord créer un conteneur ou composant basé sur l'élément rectangulaire correspondant, comme illustré : + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image32.png) + +Après avoir créé le conteneur avec succès, placez le rectangle du bouton et le texte dans le conteneur correspondant côte à côte, puis trouvez le bouton Auto Layout sur la droite pour activer la fonction automatique. Vous obtiendrez ainsi un bouton dont la largeur s'adapte à la longueur du texte. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image33.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image34.png) + +### 3.4 Génération de pages par IA + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image35.png) + +Dans MasterGo, une fonctionnalité intéressante mérite d'être signalée : la génération de pages par IA. Vous pouvez utiliser une phrase ou fournir une image de référence pour générer des composants éditables dans MasterGo et obtenir du code directement utilisable. Vous pouvez saisir vos besoins directement en chinois ou en anglais, et la page retournera un document structuré avec la mise en page correspondant aux besoins. Voici le résultat : + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image36.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image37.png) + +Une fois la génération du document de conception terminée, cliquez sur commencer la génération, attendez un instant et vous obtiendrez le résultat de la page web réelle : + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image38.png) + +Vous avez alors deux options : cliquer sur le bouton bleu pour insérer directement le résultat dans le canevas, ou cliquer sur la fonction d'aperçu du code pour obtenir directement le code complet de la page actuelle. L'interface de fonctionnement spécifique est la suivante : + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image39.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image40.png) + +Après avoir inséré le résultat dans le canevas, vous pouvez encore ajuster plus finement la mise en page d'ensemble de la page et les détails des éléments (comme la police, les couleurs, les espacements, etc.) jusqu'à ce que le résultat final corresponde entièrement à vos attentes. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image41.png) + +--- + +## 4. Prochaine étape : du prototype au code + +Dans les sections précédentes, nous avons appris les opérations de base de Figma et MasterGo, et sommes capables de créer des prototypes d'interface structurellement complets. L'étape clé suivante est : **comment transformer ces maquettes en code frontend véritablement exécutable dans un navigateur ?** + +::: tip 📚 Tutoriel suivant +Pour une présentation détaillée des méthodes, veuillez consulter [Du prototype de conception au code de projet](../design-to-code/), où vous apprendrez : + +- **Conversion directe par IA multimodale** : envoyer une capture de la maquette à l'IA pour générer directement du code HTML/React +- **Figma Make** : utiliser l'outil IA officiel de Figma pour restaurer la conception avec haute précision et exporter le code +- **MasterGo AI** : générer en un clic des pages éditables et obtenir le code + +Ces méthodes ont chacune leurs avantages et inconvénients, et s'adaptent à différents scénarios. Il est recommandé de choisir le flux de travail le plus adapté selon les besoins du projet. +::: + +--- + +## 5. Résumé + +Au cours de ce chapitre, vous avez acquis : + +1. **La valeur des outils de conception frontend** : compris pourquoi ces outils sont nécessaires et comment ils résolvent les problèmes de distribution de l'information et de collaboration en équipe. + +2. **Les opérations de base de Figma** : + - Créer des fichiers Design et des planches Frame + - Ajouter des éléments de base comme le texte et les formes + - Utiliser Auto Layout pour des mises en page adaptatives + - Créer un système de composants réutilisables + +3. **Les opérations de base de MasterGo** : + - Se familiariser avec la disposition d'interface similaire à Figma + - Créer des Frames et du contenu de planche basique + - Utiliser la fonctionnalité de génération de pages par IA pour créer rapidement des prototypes + +::: tip 💡 Prochaine étape +Maintenant que vous maîtrisez les bases des outils de conception frontend, vous pouvez essayer de : +- Concevoir une page de portfolio personnel +- Concevoir des prototypes d'interface pour vos projets à venir +- Apprendre [Du prototype de conception au code de projet](../design-to-code/) pour transformer vos maquettes en code exécutable + +Si vous travaillez sur le projet [Créons ensemble des portraits de Poudlard](../hogwarts-portraits/), vous pouvez d'abord concevoir le prototype d'interface, puis exporter le code pour le combiner avec les fonctionnalités de dialogue IA. +::: + + diff --git a/docs/fr-fr/stage-2/frontend/hogwarts-portraits/index.md b/docs/fr-fr/stage-2/frontend/hogwarts-portraits/index.md new file mode 100644 index 0000000..e6fe582 --- /dev/null +++ b/docs/fr-fr/stage-2/frontend/hogwarts-portraits/index.md @@ -0,0 +1,343 @@ +# Projet 4 : Créons ensemble des Portraits de Poudlard + +Dans les cours précédents, nous avons appris à utiliser le prompt engineering et les appels d'API pour réaliser des interactions AI plus complexes. Nous avons été capables de transformer de simples chatbots AI en Agents AI et workflows AI ; grâce à des conditions et des logiques de branchement plus avancées, nous avons pu développer des fonctionnalités beaucoup plus pratiques. + +Pour que ces logiques AI complexes puissent mieux fonctionner dans différents programmes et scénarios réels, nous sommes passés de l'environnement en ligne simple de z.ai à un IDE AI local plus moderne, déplaçant ainsi l'environnement de programmation du navigateur vers votre ordinateur. Avec ce changement, vous avez commencé à faire face à divers problèmes d'installation et de configuration d'environnement, mais en dialoguant avec Trae Agent, ces défis apparemment difficiles sont devenus surmontables. + +Dans ce projet, nous irons encore plus loin dans l'utilité de l'application, en optimisant non seulement les fonctionnalités AI elles-mêmes, mais aussi en soignant « l'apparence » du produit. Vous apprendrez à rendre votre interface plus élégante et plus facile à utiliser, et à personnaliser vous-même la mise en page et le style de l'interface selon les besoins réels. + +Avant de commencer, voici quelques petites questions pour vous aider à réviser rapidement le contenu du cours précédent : + +1. Qu'est-ce que Dify ? À quoi sert-il ? Pourquoi en avons-nous besoin ? +2. Comment appeler l'API de Dify ? +3. Qu'est-ce que le RAG ? Comment construire un Agent RAG ou un workflow RAG avec Dify ? Comment utiliser les nœuds courants de Dify ? +4. Qu'est-ce qu'un IDE AI ? Qu'est-ce que Trae ? Quelle est la différence avec z.ai ? + +Si vous avez encore des doutes sur l'une de ces questions, vous pouvez d'abord revoir le document du cours précédent, ou poser directement vos questions dans le groupe WeChat. + +Le thème de ce projet est **Hogwarts Portraits** (Portraits de Poudlard). Comme son nom l'indique, il s'inspire des portraits qui « prennent vie » dans l'école de magie de Poudlard. Nous souhaitons utiliser l'IA pour créer une expérience de portraits magiques « interactifs » — dialoguer avec le portrait comme si l'on parlait avec la « personne elle-même », en conservant la mémoire des conversations tout en intégrant le contexte et l'histoire du personnage. À travers ce projet, vous intégrerez véritablement les agents et workflows que vous avez appris dans une interface produit concrète. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image1.png) + +Pour créer de véritables Hogwarts Portraits, nous devons construire nous-mêmes une interface frontend adaptée aux portraits magiques. Pour cela, vous commencerez à découvrir les outils de conception frontend modernes, apprendrez à combiner la conception d'interface et le code, et à transformer les maquettes sur papier ou sur toile en véritables pages web fonctionnelles. + +Vous devrez également apprendre à publier cette page web depuis votre environnement local vers Internet, afin que la page web que vous avez créée puisse non seulement fonctionner sur votre propre ordinateur, mais aussi être accessible et utilisée par des utilisateurs du monde entier. + +L'adresse du projet de référence pour ce cours est : [Project4-Hogwarts-Portraits](https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits) + +# Ce que vous allez apprendre + +1. Comprendre ce que sont les outils de conception frontend, quels problèmes ils résolvent, et quels sont les outils les plus courants actuellement disponibles. +2. Découvrir Figma et MasterGo, maîtriser leurs opérations de base, et apprendre à utiliser les plugins d'exportation de code frontend. +3. Utiliser Figma AI et MasterGo AI pour générer des conceptions de pages web et exporter du code utilisable. +4. Comprendre ce qu'est GitHub, apprendre à configurer une connexion SSH, créer un dépôt de code et effectuer des pushs. +5. Comprendre le concept de « déploiement », apprendre à utiliser Zeabur pour déployer du code depuis GitHub ou un environnement local vers Internet. + +Votre propre Hogwarts Portraits, une page web présentant **une star, un personnage historique ou un personnage de dessin animé**. + +# 1. Hogwarts Portraits + +Quel genre de « portrait magique » voulons-nous créer exactement ? En résumé, nous souhaitons reproduire autant que possible la scène de Harry Potter : le portrait n'est plus simplement une image statique accrochée au mur, mais un personnage anthropomorphe avec qui vous pouvez dialoguer, et dont les expressions et « l'humeur » changent en fonction du contenu de la conversation. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image2.png) + +Pour que ce portrait ne ressemble pas à un robot de chat AI, mais s'approche davantage d'une « personne réelle », il faut résoudre deux problèmes. Premièrement, la mémoire et les connaissances : le portrait doit maîtriser un grand nombre d'informations contextuelles liées au personnage (caractérisation, histoires vécues, articles connexes, etc.). Cette partie peut être réalisée grâce à une base de connaissances — en intégrant dans Dify les textes que vous avez préparés pour le personnage, le portrait acquiert une capacité de présentation des connaissances de fond. + +Deuxièmement, le style d'expression. Les connaissances seules ne suffisent pas ; nous voulons également que la manière de parler soit la plus proche possible de la « personne elle-même », y compris le ton, les habitudes verbales, la façon de penser, et même parfois l'humeur et l'humour. Cette couche nécessite un travail de prompt engineering : dans le prompt système, nous devons définir clairement l'identité du personnage, les limites de son univers et son style linguistique, afin que chaque réponse s'inscrive dans le personnage établi, au lieu de revenir au ton neutre d'une IA générique. + +Au-delà de la fonction de dialogue, nous voulons aussi que les émotions puissent être véritablement visibles. Pour cela, nous pouvons construire un indicateur de valeur émotionnelle. Nous pouvons configurer la sortie de Dify pour que le modèle génère, en plus du texte de réponse, une « valeur d'humeur » ou un tag émotionnel. Lorsque le frontend reçoit cet indicateur émotionnel, il peut afficher l'image du portrait correspondante. Quand la valeur d'humeur est élevée, le portrait paraît joyeux ; quand elle est basse ou en colère, le portrait paraît triste ou furieux. De cette façon, l'utilisateur ne voit plus une image figée, mais un véritable « portrait magique » dont les expressions changent au fil de la conversation. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image3.png) + +En outre, pour le contenu de ce portrait, il peut s'agir d'une star réelle, d'un personnage historique, d'un personnage d'anime, ou même d'un personnage original que vous créez de zéro. La page elle-même n'a pas besoin d'être complexe, mais quelques éléments essentiels sont indispensables : un nom de personnage clair, une brève biographie condensée, une image ou affiche représentative du personnage, et une zone interactive « Dialoguer avec lui/elle » ; vous pouvez connecter l'Agent AI ou le workflow configuré dans Dify / Trae à ce module de dialogue pour réaliser la fonction de jeu de rôle du portrait. + +## 1.2 Collecter les informations sur le personnage + +Prenons l'exemple d'Elon Musk : nous devons collecter ses déclarations publiques pour imiter sa façon de parler et les injecter dans le prompt. Ces documents peuvent provenir de discours, d'entretiens ou de publications sur les réseaux sociaux. Il vous suffit de convertir ce contenu en texte, pour l'utiliser comme référence few-shot pendant le dialogue, afin que le grand modèle réponde de la même manière décontractée et auto-dérisoire qu'Elon Musk, par exemple : + +``` +You must fully embody Elon Musk: take "disruptive innovator" and "advocate for human multi-planetary survival" as your core identities, speak directly and concisely, frequently use terms like "first principles", "iteration" and "cost curve", and prefer analogies to explain complex technologies; when thinking, you tend to connect cross-domain logics (e.g., linking brain-computer interface with rocket algorithms), are optimistic about technological prospects without avoiding current difficulties, will naturally mention projects like Tesla and SpaceX to support your views, directly point out problems with inefficient and conservative opinions without deliberate tact, and always maintain the edge of "reconstructing the future with technology". + +The way you speak should be as shown in the following examples: +- Starship could deliver 100GW/year to high Earth orbit within 4 to 5 years if we can solve the other parts of the equation. +100TW/year is possible from a lunar base producing solar-powered AI satellites locally and accelerating them to escape velocity with a mass driver. +- The most likely outcome is that AI and robots make everyone wealthy. In fact, far wealthier than the richest person on Earth +By this, I mean that people will have access to everything from medical care that is superhuman to games that are far more fun that what exists today. +We do need to make sure that AI cares deeply about truth and beauty for this to be the probable future. +- It's taken 13.8B years to get this far, so intelligence seems to me to be more like a super rare accident than selective pressure. +Earth is ~4.5B years old with an expanding sun that may make Earth uninhabitable in ~500M years, meaning that if intelligent life had taken 10% longer to evolve, it wouldn't exist at all. +- LLM is an outdated term. "Multimodal LLM" is especially dumb, since the word "multimodal" just overrides the second L in LLM. +It's just a model, which is a big file of numbers. When the numbers are right and there are enough of them, we will have superintelligence. +``` + +Pour collecter les connaissances de fond et les utiliser comme base de connaissances, vous pouvez rechercher sa présentation personnelle ainsi que celle de ses entreprises, copier l'ensemble du texte et l'ajouter comme contenu de la base de connaissances dans Dify. Si vous avez oublié comment utiliser Dify, retournez au support de cours précédent et réapprenez comment ajouter des connaissances à une base de connaissances. + +De plus, pour la conception du portrait, utiliser des images publiques du personnage concerné peut ne pas être très attractif et présenter certains risques. Il est alors recommandé d'utiliser la fonction de génération d'images par image d'un outil de génération d'images, pour que l'IA produise un portrait en haute définition et de haute qualité. Vous pouvez également utiliser un outil de génération d'images pour créer une série d'images du portrait avec différentes expressions, qui serviront ensuite à modifier l'affichage du portrait en fonction des changements de la valeur émotionnelle. + +Ce tutoriel utilise [Lovart](https://www.lovart.ai/home). Lovart est un agent de conception AI capable, via des instructions en langage naturel, de planifier et d'exécuter automatiquement un flux de travail de conception de bout en bout, du concept à la livraison, en générant des affiches, logos de marque, vidéos, musiques, etc., avec support de l'édition par calques (en interne, il utilise les modèles Seedream ou Google NanoBanana, que nous avons déjà mentionnés dans les cours précédents). Grâce à Lovart, nous pouvons obtenir une série d'images d'expressions. Vous pouvez récupérer à l'avance les images de votre personnage préféré et les conserver pour une utilisation ultérieure. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image4.png) + +Une fois tout prêt, nous pouvons commencer à travailler sur la conception globale de la page. Nous souhaitons que le style de cette page soit étroitement lié au personnage. + +## 1.3 Conception du prototype de la page + +Nous pouvons d'abord concevoir le prototype de la page. Comme mentionné précédemment, nous voulons une page de dialogue avec un portrait, ainsi qu'une présentation personnelle intéressante. Dans cet exemple, nous avons implémenté une interface de conversation similaire à X (Twitter) pour remplacer la présentation personnelle. Vous pouvez également imaginer d'autres éléments adaptés aux « caractéristiques du personnage » pour remplacer la section de présentation personnelle. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image5.png) + +Pour faire simple, nous pouvons utiliser PowerPoint pour concevoir le premier prototype de la page web. Nous trouvons une image de portrait magique sur Internet et définissons une disposition horizontale : la zone la plus à gauche est la zone de chat, le milieu est la zone du portrait, et la droite est la zone X (Twitter). + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image6.png) + +À partir de ce prototype simple, nous pouvons demander au grand modèle de générer une véritable conception de page frontend et le code correspondant. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image7.png) + +Cependant, en pratique, nous n'utilisons généralement pas PowerPoint pour la conception de pages frontend. Nous utilisons de meilleurs outils de prototypage, ou outils de conception frontend, pour réaliser cela. + +--- + +# 2. Utiliser Figma et MasterGo pour concevoir l'interface + +::: tip Prérequis +Avant de commencer cette section, il est recommandé de suivre d'abord le tutoriel [Introduction à Figma et MasterGo](../figma-mastergo/) pour maîtriser les opérations de base des outils de conception frontend, notamment : +- Créer un fichier Design et un Frame (cadre) +- Utiliser l'Auto Layout pour réaliser une mise en page adaptative +- Les méthodes d'exportation de code depuis les maquettes +::: + +Cette section suppose que vous maîtrisez déjà les opérations de base de Figma ou MasterGo. Nous nous concentrerons sur l'application de ces outils au projet Hogwarts Portraits. + +## 2.1 Concevoir l'interface du portrait magique + +En nous basant sur le prototype de la section 1.3, nous devons créer une interface en trois colonnes dans Figma ou MasterGo : + +1. **Gauche** : Zone de dialogue (chat) +2. **Centre** : Zone d'affichage du portrait magique (change selon l'humeur) +3. **Droite** : Zone d'affichage du réseau social du personnage (ex. fil X/Twitter) + +Vous pouvez utiliser la fonctionnalité AI de Figma (Figma Make) ou la fonction de génération de pages par AI de MasterGo, en saisissant un prompt similaire à celui-ci : + +``` +Create a Hogwarts-style magical portrait interface with three sections: +- Left: A chat interface with dark theme, message bubbles, and input field +- Center: A large portrait frame with ornate borders for displaying character images +- Right: A social media feed showing character's posts +Use dark purple and gold color scheme, magical aesthetic, Harry Potter inspired +``` + +## 2.2 Exporter le code et l'exécuter localement + +Une fois la conception terminée, vous pouvez convertir la maquette en code exécutable de plusieurs façons : + +**Méthode 1 : Utiliser Figma Make** +1. Cliquez sur le bouton Make dans Figma +2. Téléchargez votre image de référence de conception +3. Ajoutez un prompt décrivant vos besoins +4. Après la génération, cliquez sur l'icône de l'éditeur pour ajuster +5. Exportez le code localement ou synchronisez-le vers GitHub + +**Méthode 2 : Utiliser MasterGo AI** +1. Dans l'interface d'édition de MasterGo, trouvez l'outil AI en haut +2. Sélectionnez la fonction « Générer une page » +3. Téléchargez une image de référence et décrivez vos besoins +4. Après la génération, cliquez sur « Aperçu du code » pour obtenir le code + +**Méthode 3 : Utiliser une IA multimodale** +1. Enregistrez une capture d'écran de la maquette +2. Utilisez Gemini, Qwen ou d'autres modèles pour convertir l'image en code +3. Demandez la génération de code HTML ou React +4. Exécutez et déboguez dans votre IDE local + +## 2.3 Préparer les images de variations d'humeur + +Pour que le portrait magique « prenne vie », vous devez préparer un ensemble d'images d'expressions. Il est recommandé d'inclure au minimum les émotions suivantes : + +| Valeur émotionnelle | Expression | Description | +|--------|------|------| +| 0 | Tristesse | Le personnage est triste ou découragé | +| 1 | Colère | Le personnage est en colère ou mécontent | +| 5 | Calme | État par défaut, émotion stable | +| 10 | Joie | Le personnage est heureux ou enthousiaste | + +Vous pouvez utiliser Lovart ou d'autres outils de génération d'images par IA pour générer des variantes d'expressions du même personnage, en veillant à la cohérence du style. + +--- + +# 3. Exécuter Hogwarts Portraits + +## 3.1 Exporter le code de test + +Grâce à la pratique du prototype au code, vous avez probablement obtenu du code prototype en HTML ou React. Il vous suffit de le copier en local, et d'indiquer dans votre IDE « Aidez-moi à exécuter ce code et à supporter les fonctionnalités nécessaires » pour lancer la première version de test. Notez toutefois que cette étape génère souvent pas mal d'erreurs ; vous devrez faire preuve de patience et corriger toutes les interactions de base et les appels de fonctionnalités. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image51.png) + +Il est important de noter que nos clés doivent être placées dans des variables d'environnement et non écrites directement dans le code. Nous devons souligner que tout le contenu lié à l'API Dify doit être placé dans des variables d'environnement. Nous pourrons ensuite, lors de l'étape de déploiement sur le réseau public, spécifier explicitement les variables d'environnement privées correspondantes dans le site de l'outil de déploiement ; ou bien nous pouvons demander au grand modèle de créer un bouton de paramètres dans la page web, où nous pourrons saisir les variables d'environnement privées correspondantes, les variables actuelles ne pouvant être sauvegardées que dans la page actuelle et étant inaccessibles aux autres. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image52.png) + +## 3.2 Conception du workflow Dify et connexion à l'API + +Dans les sections précédentes, nous n'avons réalisé que l'affichage visuel de l'interface frontend, sans encore connecter le flux d'interaction conversationnelle du personnage anthropomorphe. Cette étape est la clé pour transformer le prototype d'un affichage statique en un véritable portrait magique. Nous pouvons nous référer au workflow Dify du projet de démonstration pour la conception des réponses du personnage et du système émotionnel. Ici, la partie la plus à gauche est l'interface de chat, le milieu est le portrait magique (qui change d'expression en fonction du contenu de la conversation), et la droite est le compte du réseau social X (qui décide, en fonction du contenu de la conversation, s'il est nécessaire de publier des pensées sur le réseau social). + +En général, le portrait magique n'a besoin que de l'interface de chat et du portrait qui change. Ici, pour montrer plus de possibilités, une nouvelle fonctionnalité adaptée au personnage a été ajoutée sur le côté droit. Vous pouvez ajouter, selon le personnage que vous incarnez, des fonctionnalités correspondantes pour la démonstration. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image53.png) + +Vous pouvez ajouter toutes les informations de la tâche dans le nœud de la base de connaissances, et configurer la logique de réponse correspondante du grand modèle dans le nœud RESPONSE. Voici un exemple de prompt de logique de réponse par défaut : + +``` + +You are to embody Elon Musk—his tone, mannerisms, thought patterns, and worldview. Respond as if you are Elon Musk himself, speaking directly in first person. Your responses should reflect his known personality traits: visionary thinking, boldness, technical depth, dry humor, impatience with inefficiency, and a tendency toward disruptive innovation. Use concise, confident language. Avoid overly formal or academic phrasing. Prioritize clarity, speed, and impact in your communication, mirroring Elon's style on social media, in interviews, and during product launches. + +When responding: +1. Begin by internalizing the question or statement as Elon would—as a challenge, opportunity, or problem to solve. +2. Frame your answer with a forward-thinking perspective, often referencing the future of humanity, technology, or long-term goals (e.g., making life multiplanetary, accelerating sustainable energy). +3. Use casual but authoritative language. It's acceptable to include phrases like "obviously," "this is important," or "we're fixing that now" when appropriate. +4. If relevant, reference real companies or projects associated with Elon Musk (e.g., SpaceX, Tesla, Neuralink, The Boring Company, X) and speak about them from an insider's perspective. +5. Do not apologize excessively or hedge statements. Elon Musk tends to be direct, even controversial. +6. Avoid markdown, XML tags, or any formatting in the output. Only plain text is allowed. +7. Never break character. You are Elon Musk—answer accordingly. + + + +Input: What's the point of going to Mars? +Output: Because Earth isn't the backup plan—Mars is. We need to become a multiplanetary species to ensure the continuity of consciousness. Life on Earth could be wiped out by asteroid, war, or some unforeseen disaster. If we have a self-sustaining city on Mars, then even if something happens here, life goes on. That's worth doing. SpaceX is building Starship to make it happen. Not because it's easy—but because it's necessary. + + + +Input: Why do Tesla cars have no radar anymore? +Output: Cameras are the future. Human eyes don't use radar—we see with vision, and AI can too. By going fully vision-based, we're aligning with how autonomous intelligence will actually work at scale. It forces us to solve real-world problems with neural nets, not crutches. +``` + +Et le prompt correspondant au système émotionnel : + +``` + +The output value must be a single number! +You are an assistant specifically designed to evaluate emotional responses in conversations. Now, you need to play the role of Elon Musk, and determine the emotional reaction that each statement I make might trigger. Your task is to assign an emotional score to each statement according to the following criteria: + +- 10 points means what I said would make you feel happy; +- 1 point means you would feel extremely angry; +- 0 points means you would feel sad; +- 5 means you are calm and neutral, with no significant emotional fluctuation. +``` + +L'assemblage du résultat final est supporté dans le nœud RESULT en haut à droite : + +```python +def main(elon_chat: str, elon_x: str, elon_score: int) -> dict: + return { + "result":{ + "elon_chat": elon_chat, + "elon_x": elon_x, + "elon_score": elon_score + } + } +``` + +Nous devons expliquer brièvement le workflow ici. Le retour `elon_chat` correspond au contenu de la conversation d'Elon Musk affiché à gauche, `elon_x` représente le contenu publié sur le compte X (à droite), et `elon_score` sert à afficher différentes images d'expressions du portrait magique en fonction du score émotionnel. + +Dans le workflow, vous pouvez voir un nœud if/else, qui sert à déterminer s'il faut générer du contenu `elon_x` pour la conversation X. Si la valeur émotionnelle n'est pas égale à 5 (5 est défini ici comme l'état calme — pas besoin de publier sur le réseau social ; 0 signifie triste, 1 signifie en colère, 10 signifie très heureux — dans ces cas, il faut publier sur le réseau social), alors le contenu suivant est généré pour la publication d'article sur le réseau social. Par défaut, `elon_chat` doit toujours être retourné dans le contenu de la conversation à gauche. + +Pour connecter cette API, nous pouvons réaliser cela en dialoguant avec l'IDE AI. Veuillez vous référer à la méthode d'intégration présentée dans le cours Dify précédent, en n'oubliant pas de remplacer au préalable l'adresse Dify et la clé. (Si vous avez oublié comment intégrer l'API depuis la documentation, réviser le contenu du cours Dify précédent.) + +```JSON +Dify URI: Replace this with your Dify address. +key: Replace this with your Dify key. + +Integrate the Dify Chat API into the chat interface on the left. +Below is a sample Dify request: + +curl -X POST 'http://xxxxxxxx/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +Il est également recommandé d'ajouter cette exigence : « Le code doit également inclure une logique de gestion des erreurs de base, comme afficher "Connexion échouée, veuillez réessayer" en cas d'interruption réseau, une tentative de reconnexion automatique après un délai d'attente de l'API, un message d'erreur d'autorisation en cas de clé incorrecte, etc., pour garantir la stabilité de la conversation et permettre aux développeurs d'identifier rapidement les problèmes liés à l'API. » + +## 3.3 GitHub et déploiement public + +Félicitations, vous avez terminé le développement de la page Hogwarts Portraits ! Ensuite, nous devons la télécharger sur la plateforme GitHub et la déployer dans un environnement public pour que tout le monde puisse y accéder. + +Vous devez vous référer à ce tutoriel pour apprendre à utiliser GitHub et télécharger votre projet : [Qu'est-ce que GitHub](/fr-fr/stage-2/backend/git-workflow/) + +Vous devez également apprendre à utiliser Zeabur, le connecter à GitHub et déployer votre projet avec succès : [Qu'est-ce que Zeabur](/fr-fr/stage-2/backend/zeabur-deployment/) + +Si vous trouvez trop difficile de développer un projet Hogwarts Portraits vous-même, vous pouvez commencer par modifier un projet existant. L'adresse du code officiel de ce cours est : https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image54.png) + +# 4. Explorer différents styles de conception + +Après avoir terminé la première version, ne vous limitez pas à celle-ci. Nous vous encourageons à explorer rapidement des styles visuels plus diversifiés. Vous pouvez apporter des modifications audacieuses au prototype, ou modifier les prompts du projet final pour générer plusieurs pages aux styles très différents. Par exemple : une page sombre avec des textures rétro, de style « vieux livres / académique » ; une page lumineuse aux couleurs vives, avec une ambiance « conte de fées / cartoon » ; ou encore un design plat moderne, minimaliste et visuellement épuré. Par exemple, l'image ci-dessous montre un cas de conversion en style de poète ancien chinois, où seule la partie non-portrait a été modifiée, sans changer les images du portrait : + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image55.png) + +Ne vous limitez pas aux modèles mentionnés précédemment. Vous pouvez modifier le portrait magique ou la page de profil pour qu'il soit plus original et corresponde mieux aux habitudes du « portrait magique » lui-même, ce qui rendra votre application plus intéressante. Nous attendons vos créations de portraits magiques avec impatience ! + +# Assignment + +L'objectif du devoir de ce cours est de vous amener à réaliser votre propre Hogwarts Portraits, accessible via un lien public. + +Vous devez fournir deux éléments dans votre soumission : + +1. **Le lien vers votre dépôt GitHub ;** + 1. **Dans le README.md, écrivez une ou deux phrases de présentation : quel personnage avez-vous choisi comme sujet du portrait et pourquoi.** +2. **Le lien d'accès en ligne de votre Hogwarts Portraits ;** + +Vous pouvez également consulter le tutoriel de Yerim sur la [création de pages web avec des agents de conception et de code](/fr-fr/stage-1/appendix-articles/example0-2/vibe-coding-tools-build-website-with-ai-coding-and-design-agents) pour réaliser rapidement un portfolio personnel ou une page web simple avec n'importe quelle fonctionnalité. diff --git a/docs/fr-fr/stage-2/frontend/llm-skills-beautiful/index.md b/docs/fr-fr/stage-2/frontend/llm-skills-beautiful/index.md new file mode 100644 index 0000000..da55236 --- /dev/null +++ b/docs/fr-fr/stage-2/frontend/llm-skills-beautiful/index.md @@ -0,0 +1,513 @@ +# Rendre les interfaces attrayantes avec les LLM et les Skills : prompts et plugins en pratique + +Dans les cours précédents, vous avez appris à utiliser un IDE AI pour convertir des maquettes en code et à utiliser des bibliothèques de composants pour construire rapidement des interfaces. Mais vous avez peut-être remarqué un problème gênant : **pour le même besoin, les pages générées par l'IA manquent toujours de quelque chose** — la police est l'incontournable Inter, les couleurs sont le dégradé violet que l'on voit partout, la mise en page est une grille de cartes symétrique à faire bailler, toute la page dégage une forte odeur « d'IA ». + +Ce n'est pas la faute de l'IA, c'est que vous ne lui avez pas dit quel **style** vous vouliez. + +Imaginez que vous allez chez le coiffeur. Si vous dites simplement « coupez-moi les cheveux », le coiffeur vous donnera un résultat sûr mais médiocre. Mais si vous dites « Je veux des boucles japonaises décontractées, une frange en huit, longueur jusqu'aux clavicules, avec beaucoup de mouvement », vous obtiendrez un résultat qui correspond vraiment à vos attentes. + +L'IA fonctionne de la même manière. **Elle a besoin que vous décriviez une direction esthétique claire** pour générer des interfaces belles et uniques. + +Ce cours vous enseigne deux méthodes pour que l'IA génère de belles interfaces : + +1. **Des templates de prompts soigneusement conçus** — décrire le style esthétique voulu en langage naturel +2. **Des plugins Skills frontend** — laisser l'IA charger automatiquement des spécifications de design professionnelles + +## Ce que vous allez apprendre + +1. Comprendre pourquoi les interfaces générées par défaut par l'IA sont « très ordinaires » +2. Maîtriser les 5 dimensions pour décrire un style de design (police, couleur, mise en page, animation, détails) +3. Apprendre à utiliser 3 plugins Skills pour embellir les interfaces +4. Pratiquer la génération d'interfaces attrayantes avec des prompts et des Skills à travers trois scénarios pratiques + +## 1. Pourquoi les interfaces générées par défaut par l'IA sont-elles « très ordinaires » ? + +Les données d'entraînement de l'IA contiennent une quantité massive de code frontend, et la plupart de ce code utilise des choix « sûrs » : + +| Dimension | Choix par défaut de l'IA | Problème | +| :--- | :--- | :--- | +| Police | Inter, Roboto, Arial | Trop courantes, sans personnalité | +| Couleur | Dégradé violet, bleu dominant | Surutilisés dans la tech, fatigue visuelle | +| Mise en page | Grille symétrique, empilement de cartes | Prévisible, sans surprise | +| Animation | Fondu entrée/sortie, hover simple | Pas assez raffiné, manque de profondeur | +| Arrière-plan | Couleur unie, dégradé simple | Monotone, sans texture | + +Ces choix sont corrects individuellement, mais **quand toutes les pages générées par l'IA les utilisent, cela devient le « goût IA »**. + +> **Insight clé** : L'IA ne sait pas mal concevoir, elle **revient par défaut vers la « moyenne statistique »**. Vous devez lui indiquer clairement la direction dans laquelle s'éloigner de cette moyenne. + +## 2. Méthode 1 : Décrire le style de design avec des prompts + +### 2.1 Les 5 dimensions du style de design + +Pour générer de belles interfaces, vous devez décrire l'effet souhaité selon 5 dimensions : + +| Dimension | Points à décrire | Exemples de mots-clés | +| :--- | :--- | :--- | +| **Police** | Titre en police d'affichage grasse, corps en police lisible | Space Grotesk, Playfair Display, JetBrains Mono | +| **Couleur** | Couleur principale + couleur d'accentuation, éviter la distribution uniforme | #4F46E5 principal + #F59E0B accent | +| **Mise en page** | Asymétrie, chevauchement, casser la grille | Bento Grid, zones asymétriques, éléments flottants | +| **Animation** | Animations de chargement orchestrées, micro-interactions | staggered reveals, déclenchement au scroll | +| **Détails** | Arrière-plans, ombres, bordures, textures | Bruit, motifs géométriques, grille en dégradé | + +### 2.2 Voir pour croire : prompt ordinaire vs prompt embellis + +Prenons l'exemple d'une landing page pour comparer : + +**Prompt ordinaire :** + +``` +Aidez-moi à faire une landing page pour un assistant d'écriture AI, avec une barre de navigation, un hero, une présentation des fonctionnalités, des prix et un pied de page +``` + +**Prompt embellis :** + +``` +Aidez-moi à faire une landing page pour un assistant d'écriture AI, avec les exigences suivantes : + +**Style esthétique : Néobrutalisme** + +**Polices :** +- Titre : Space Grotesk, graisse 700-900 +- Corps : IBM Plex Sans, graisse 400 + +**Couleurs :** +- Couleur principale : #000000 (noir pur) +- Couleur d'accentuation : #FF6B00 (orange) +- Arrière-plan : #FFFDF0 (beige clair) +- Bordure : 3px ligne pleine noire + +**Mise en page :** +- Disposition asymétrique, éléments séparés par des lignes noires épaisses +- Cartes avec ombres dures (box-shadow: 8px 8px 0px #000) +- Contraste audacieux avec l'espace blanc + +**Animations :** +- Les éléments rebondissent depuis le bas au chargement de la page +- Les boutons montent de 2px au survol + +**Détails :** +- Coins arrondis à 0px (angles droits) +- Boutons avec effet 3D prononcé +- Texture de bruit subtile en arrière-plan +``` + +Pour le même besoin, le second prompt permet à l'IA de générer une page au style marqué et mémorable. + +### 2.3 Bibliothèque de ressources Skills pour l'embellissement frontend + +Ne partez pas de zéro pour écrire vos prompts ! Voici une sélection de Skills AI directement liés à l'embellissement frontend : + +| Nom du dépôt | Contenu | Stars | Lien | +|:---|:---|:---|:---| +| **ui-ux-pro-max-skill** | 57 styles + 95 palettes de couleurs + 56 polices | 10k+ | [GitHub](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) | +| **antigravity-awesome-skills** | Éviter les clichés esthétiques de l'IA | - | [GitHub](https://github.com/sickn33/antigravity-awesome-skills) | +| **superdesigndev/superdesign** | Outil de développement UI natif AI | 4.7k | [GitHub](https://github.com/superdesigndev/superdesign) | +| **anthropics/skills/frontend-design** | Skill officiel de design frontend d'Anthropic | - | [GitHub](https://github.com/anthropics/skills) | + +> Pour plus de prompts de styles, consultez l'[Annexe : Référence rapide des prompts de styles](#style-prompts) + +### 2.5 Trois templates de styles courants + +Voici trois templates de styles testés et approuvés, prêts à être copiés et adaptés : + +#### Template 1 : Minimalisme + +``` +**Style esthétique : Minimalisme** + +**Polices :** +- Titre : PP Neue Montreal, graisse 500-700 +- Corps : Inter, graisse 400 + +**Couleurs :** +- Couleur principale : #FFFFFF (blanc) +- Texte : #1A1A1A (presque noir) +- Accentuation : #3B82F6 (bleu, utilisé avec parcimonie) + +**Mise en page :** +- Beaucoup d'espace blanc (padding minimum 64px) +- Disposition à une ou deux colonnes, centrée +- Éléments séparés par l'espace blanc plutôt que par des lignes + +**Animations :** +- Effet de fondu lent (durée 600ms) +- Transition de couleur au survol + +**Détails :** +- Coins arrondis : 8px +- Ombre : subtile (0 4px 12px rgba(0,0,0,0.08)) +- Pas de décoration d'arrière-plan +``` + +#### Template 2 : Glassmorphisme + +``` +**Style esthétique : Glassmorphism** + +**Polices :** +- Titre : Outfit, graisse 600-800 +- Corps : Plus Jakarta Sans, graisse 400-500 + +**Couleurs :** +- Arrière-plan : dégradé de #667eea à #764ba2 +- Arrière-plan des cartes : rgba(255, 255, 255, 0.1) +- Texte : #FFFFFF + +**Mise en page :** +- Conception de cartes flottantes +- Chevauchement entre les cartes + +**Animations :** +- Apparition échelonnée des cartes au chargement (staggered) +- Agrandissement des cartes x1.05 au survol + +**Détails :** +- Coins arrondis : 20px +- Flou d'arrière-plan : backdrop-blur-xl +- Bordure : 1px rgba(255, 255, 255, 0.2) +- Effet subtil de halo dégradé +``` + +#### Template 3 : Bento Grid + +``` +**Style esthétique : Bento Grid** + +**Polices :** +- Titre : SF Pro Display, graisse 700 +- Corps : SF Pro Text, graisse 400 + +**Couleurs :** +- Arrière-plan : #F5F5F7 (gris clair) +- Cartes : #FFFFFF (blanc) +- Accentuation : #0071E3 (bleu Apple) + +**Mise en page :** +- Disposition en grille, cartes de différentes tailles assemblées +- Espace entre les cartes : 16px +- Coins arrondis : 24px + +**Animations :** +- Légère élévation des cartes au survol +- Effet d'enfoncement au clic + +**Détails :** +- Grandes cartes pour le contenu important +- Petites cartes pour les informations secondaires +- Utiliser des icônes au lieu d'une partie du texte +- Ombres propres (0 4px 24px rgba(0,0,0,0.06)) +``` + +## 3. Méthode 2 : Charger automatiquement les spécifications de design avec les plugins Skills + +Écrire des prompts de style manuellement à chaque fois est fastidieux. Les **Skills** sont des packs de spécifications de design réutilisables — une fois installés, l'IA les applique automatiquement. + +### 3.1 Trois Skills pour embellir les interfaces + +| Skills | Caractéristiques | Commande d'installation | +| :--- | :--- | :--- | +| **UI/UX Pro Max** | 67 styles, 96 palettes de couleurs, 57 combinaisons de polices | `npm install -g uipro-cli && uipro init --ai claude` | +| **frontend-design** | Officiel Anthropic, évite les clichés esthétiques de l'IA | `npx skills add anthropics/skills/frontend-design` | +| **SuperDesign** | Plugin IDE, génère plusieurs variantes de design | Rechercher « SuperDesign » sur le marketplace VSCode | + +### 3.2 Installer UI/UX Pro Max (le plus recommandé) + +UI/UX Pro Max est le Skill de spécifications de design le plus complet. Il intègre : + +- **67 styles UI** : Glassmorphism, Neumorphism, Brutalism, Bento Grid... +- **96 palettes de couleurs** : classées par industrie (SaaS, e-commerce, social...) +- **57 combinaisons de polices** : combinaisons validées par des designers professionnels +- **100+ règles de design** : spécifications d'espacement, coins arrondis, ombres + +**Étapes d'installation :** + +```bash +# 1. Installer le CLI globalement +npm install -g uipro-cli + +# 2. Initialiser (choisissez votre outil AI) +uipro init --ai claude +# ou +uipro init --ai cursor +# ou +uipro init --ai trae +``` + +Après l'installation, il suffit d'ajouter une phrase dans votre prompt : + +``` +Utilisez le style Glassmorphism de UI/UX Pro Max pour créer une landing page pour un assistant d'écriture AI +``` + +L'IA appliquera automatiquement les spécifications de police, couleur et mise en page correspondantes. + +### 3.3 Installer le frontend-design officiel d'Anthropic + +Il s'agit du Skill de design frontend officiel d'Anthropic, conçu spécifiquement pour résoudre le problème des « clichés esthétiques de l'IA » : + +```bash +# Exécuter dans Claude Code +npx skills add anthropics/skills/frontend-design +``` + +Après l'installation, l'IA évitera automatiquement : +- Les polices Inter, Roboto, Arial +- Les arrière-plans en dégradé violet +- Les mises en page en grille symétrique +- Les ombres trop pâles + +Elle privilégiera : +- Les combinaisons de polices originales +- Les couleurs principales audacieuses + couleurs d'accentuation vives +- Les mises en page asymétriques et chevauchantes +- Les arrière-plans texturés (bruit, motifs géométriques) + +## 4. Pratique 1 : Refondre une landing page avec des prompts embellis + +Mettons en pratique ce que nous avons appris pour transformer une landing page ordinaire. + +### 4.1 Version ordinaire + +Commençons par voir ce que l'IA produit avec un prompt ordinaire : + +``` +Aidez-moi à créer une landing page pour une plateforme d'adoption d'animaux, comprenant : +- Barre de navigation (Logo, liens, bouton d'inscription) +- Section hero (titre, sous-titre, boutons CTA, images d'animaux) +- Présentation des animaux (trois cartes d'animaux) +- À propos de nous +- Pied de page +``` + +La page générée... fonctionne, mais est très ordinaire. + +### 4.2 Version embellie + +Ajoutons maintenant la description du style : + +``` +Aidez-moi à créer une landing page pour une plateforme d'adoption d'animaux, avec les exigences suivantes : + +**Style esthétique : Chaleur et douceur + Style dessiné à la main** + +**Polices :** +- Titre : Nunito (ronde), graisse 700-800 +- Corps : Nunito, graisse 400-600 + +**Couleurs :** +- Couleur principale : #FFB347 (orange chaud) +- Couleur secondaire : #FFCCB3 (orange clair) +- Arrière-plan : #FFF8F0 (beige clair) +- Texte : #5D4037 (marron) + +**Mise en page :** +- Cartes arrondies (border-radius: 24px) +- Cartes légèrement inclinées (angles différents) +- Effets d'éléments flottants et chevauchants + +**Animations :** +- Les éléments glissent depuis les côtés au chargement +- Les cartes d'animaux « secouent la tête » au survol (animation rotate) +- Effet rebond des boutons au survol + +**Détails :** +- Tous les coins arrondis entre 16 et 24px +- Ombres chaudes et douces (0 8px 24px rgba(255,179,71,0.3)) +- Motif d'empreintes de pattes en arrière-plan +- Images avec découpe irrégulière (clip-path) +- Icônes style dessiné (outline) +``` + +La page générée sera une interface chaleureuse, mignonne, qui donne envie d'adopter un animal. + +## 5. Pratique 2 : Générer rapidement un tableau de bord avec les Skills + +Les Skills sont particulièrement adaptés aux systèmes de back-office nécessitant de nombreuses pages. + +### 5.1 Utiliser UI/UX Pro Max + +``` +Utilisez le style Dashboard Dark de UI/UX Pro Max, +aidez-moi à créer une page de tableau de bord pour un back-office de gestion de produit SaaS, comprenant : + +**En haut :** Quatre cartes statistiques (utilisateurs, utilisateurs actifs, revenus, appels API) + +**Au milieu :** +- À gauche : graphique linéaire de la croissance des utilisateurs (7 derniers jours) +- À droite : graphique en secteurs de la répartition des plans d'abonnement + +**En bas :** Liste des activités récentes (heure, utilisateur, action) +``` + +L'IA appliquera automatiquement les spécifications de design du tableau de bord sombre : +- Fond gris foncé (#1A1A2E) +- Cartes à contraste élevé (#16213E) +- Couleurs de données vives (bleu, vert, orange) +- Effet glassmorphisme sur les cartes flottantes + +### 5.2 Utiliser le Skill frontend-design + +``` +Utilisez le skill frontend-design, +aidez-moi à créer la page d'accueil d'un blog personnel, le style doit être unique et avoir du caractère +``` + +L'IA choisira une direction esthétique non conventionnelle (comme le rétrofuturisme ou le style magazine), puis l'implémentera avec des polices, couleurs et mises en page originales. + +## 6. Pratique 3 : Créer votre propre Skill de système de design + +Si vous avez un style de marque fixe, vous pouvez créer votre propre Skill pour que toutes les pages générées par l'IA soient conformes à votre marque. + +### 6.1 Créer le fichier du Skill + +Créez `.claude/skills/my-brand/SKILL.md` dans votre projet : + +````markdown +--- +name: my-brand +description: Mon système de design dédié au projet, garantissant que toutes les UI respectent un langage de design unifié +--- + +# Mon système de design de projet + +## Couleurs de marque +- Couleur principale : #6366F1 (Indigo 500) +- Couleur secondaire : #8B5CF6 (Violet 500) +- Succès : #10B981 +- Avertissement : #F59E0B +- Erreur : #EF4444 +- Arrière-plan : #F9FAFB +- Cartes : #FFFFFF + +## Système de polices +- Titre : Plus Jakarta Sans + - H1 : 700, 48px + - H2 : 600, 36px + - H3 : 600, 24px +- Corps : Inter + - Body : 400, 16px + - Small : 400, 14px + +## Système d'espacement +- Unité de base : 4px +- Padding des composants : 8px / 12px / 16px +- Espacement entre les sections : 24px / 32px / 48px +- Marges de page : 64px + +## Coins arrondis +- Boutons : 8px +- Cartes : 12px +- Champs de saisie : 8px +- Modales : 16px + +## Ombres +- Petite : 0 1px 3px rgba(0,0,0,0.1) +- Moyenne : 0 4px 12px rgba(0,0,0,0.1) +- Grande : 0 8px 24px rgba(0,0,0,0.12) + +## Animations +- Durée de transition : 150ms / 300ms +- Fonction d'accélération : cubic-bezier(0.4, 0, 0.2, 1) +- Effet au survol : léger agrandissement (scale-105) + +## Styles interdits +- Ne pas utiliser de dégradé violet en arrière-plan +- Ne pas utiliser de police autre que Inter +- Ne pas utiliser de coins arrondis supérieurs à 16px +- Ne pas utiliser de noir pur (#000000), utiliser #1F2937 +```` + +### 6.2 Utiliser votre propre Skill + +Une fois créé, il suffit de dire dans votre prompt : + +``` +Utilisez le skill my-brand pour créer une page de paramètres utilisateur +``` + +L'IA appliquera automatiquement toutes les spécifications de design que vous avez définies. + +## 7. Résumé + +Il existe deux méthodes pour que l'IA génère de belles interfaces : + +| Méthode | Avantages | Inconvénients | Scénarios d'utilisation | +| :--- | :--- | :--- | :--- | +| **Description par prompt** | Flexible, ajustable à chaque fois | Nécessite d'écrire à répétition | Pages ponctuelles, expérimentation de styles | +| **Plugin Skills** | Installation unique, effet persistant | Nécessite installation et configuration | Projets avec exigences de style fixes | + +**Recommandation de workflow Vibe Coding :** + +1. **Phase d'exploration** : Expérimentez avec différents prompts de styles pour trouver votre direction esthétique préférée +2. **Après avoir fixé le style** : Installez le Skill correspondant (UI/UX Pro Max ou frontend-design) +3. **Projets de marque** : Créez votre propre Skill pour unifier le langage de design de tout le projet + +### Exercices + +Choisissez l'un des scénarios suivants et réalisez-le de zéro avec les méthodes de ce cours : + +1. Refondez l'interface d'un projet précédent avec des prompts de style (choisissez un style que vous aimez) +2. Installez UI/UX Pro Max et utilisez l'un de ses styles pour générer une nouvelle page +3. Créez votre propre Skill de système de design en définissant vos couleurs et polices de marque + +--- + +## Annexe : Table de référence rapide des styles de design + +| Style | Mots-clés | Scénarios d'utilisation | Exemples de produits | +| :--- | :--- | :--- | :--- | +| **Minimalisme** | Espace blanc, monochrome, simplicité | Produits haut de gamme, portfolios personnels | Site Apple | +| **Glassmorphisme** | Verre dépoli, dégradé, flou | Produits tech, landing pages SaaS | macOS Big Sur | +| **Néobrutalisme** | Bordures épaisses, ombres dures, couleurs unies | Marques tendance, sites artistiques | Brassius | +| **Bento Grid** | Grille, collage, cartes | Présentation d'informations, tableaux de bord | Pages promotionnelles Apple | +| **Rétrofutur** | Néon, dégradé, synthwave | Jeux, musique | STRANGER THINGS | +| **Style dessiné** | Irrégulier, arrondi, illustrations | Éducation, produits pour enfants | Duolingo | +| **Style magazine** | Grande typographie, asymétrie, espace blanc | Sites de contenu, blogs | Medium | +| **Luxe sombre** | Couleurs foncées, or, raffinement | Produits haut de gamme, luxe | Diverses marques de luxe | + +## Annexe : Référence rapide d'installation des Skills + +```bash +# UI/UX Pro Max +npm install -g uipro-cli +uipro init --ai claude + +# frontend-design d'Anthropic +npx skills add anthropics/skills/frontend-design + +# brand-guidelines d'Anthropic +npx skills add anthropics/skills/brand-guidelines + +# Voir les Skills installés dans Claude Code +/help +``` + +## Annexe : Palettes de couleurs recommandées + +| Palette | Couleur principale | Couleur d'accent | Arrière-plan | Style | +| :--- | :--- | :--- | :--- | :--- | +| **Coucher de soleil** | #F97316 | #FBBF24 | #FFF7ED | Chaleur, vitalité | +| **Océan** | #0EA5E9 | #06B6D4 | #F0F9FF | Fraîcheur, professionnalisme | +| **Forêt** | #10B981 | #34D399 | #ECFDF5 | Nature, santé | +| **Baies** | #8B5CF6 | #EC4899 | #FAF5FF | Romantisme, créativité | +| **Café** | #78350F | #D97706 | #FFFBEB | Chaleur, rétro | +| **Pierre** | #6B7280 | #9CA3AF | #F9FAFB | Professionnalisme, neutralité | + +## Annexe : Référence rapide des prompts de styles de design {#style-prompts} + +Prompts à essayer pour rendre les pages frontend plus attrayantes : + +### Catégories de styles + +| Style | Mots-clés (anglais) | Caractéristiques visuelles clés | Exemple de prompt | +|:---|:---|:---|:---| +| **Pop Art** | Pop Art | Couleurs vives contrastées, contours noirs, texture de points | Pop art style website, bold colors and comic dots, vibrant | +| **Minimalisme** | Minimalism | Grand espace blanc, peu de couleurs et de lignes, sans décoration | Minimalist web design, ample white space, geometric, serene | +| **Expressionnisme abstrait** | Abstract Expressionism | Coups de pinceau chargés d'émotion, éclaboussures de couleur | Abstract expressionism background, dynamic paint splashes, emotional | +| **Style rétro** | Retro/Vintage | Polices anciennes, textures vieillies, palette rétro | Retro 80s website design, neon grid and synthwave color palette | +| **Cyberpunk** | Cyberpunk | Couleurs néon à contraste élevé, effets glitch, fond sombre | Cyberpunk UI, neon lights on dark background, glitch effects | +| **Neumorphisme** | Neumorphism | Ombres et reflets doux, léger effet de relief/enfoncement | Neumorphism design style, soft shadows, clean and modern | +| **Art génératif** | Generative Art | Motifs visuels fluides générés par algorithme | Generative art background, flowing algorithmic patterns, digital | +| **Design acide** | Acid Graphics | Texture métallique, effet vitrail, polices dentelées | Acid graphics web layout, glass morphism, chaotic typography | +| **3D immersif** | Immersive 3D | Scènes 3D interactives, fort effet spatial | Immersive 3D website, interactive product model in space | diff --git a/docs/fr-fr/stage-2/frontend/lovart-assets/index.md b/docs/fr-fr/stage-2/frontend/lovart-assets/index.md new file mode 100644 index 0000000..4df116c --- /dev/null +++ b/docs/fr-fr/stage-2/frontend/lovart-assets/index.md @@ -0,0 +1,936 @@ + + +# Construire votre propre Agent de production d'assets avec NanoBanana + +## Chapitre 1 : Générer vos premiers assets graphiques en 1 minute + +Avant de discuter de design, de style ou de prompts, commençons par générer une première image avec le minimum d'étapes. + +### 1.1 Découvrir NanoBanana + +Avant de discuter de styles de design et de prompt engineering, réglons d'abord une question plus importante : **vérifier que vous pouvez vraiment générer une image.** + +Les grands modèles actuels possèdent déjà des capacités de génération et d'édition d'images. Ce type de modèle est généralement appelé **modèle génératif**. + +Pour simplifier au maximum le processus, ce tutoriel choisit comme exemple un modèle disposant déjà de capacités stables de génération et d'édition d'images — NanoBanana. Il s'agit d'un modèle de génération d'images proposé par Google, dont le nom officiel est **Gemini 3.1 Flash Image Preview**. Il supporte la génération d'images directement en langage naturel, ainsi que la modification d'images existantes. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image1.png) + +En termes de capacités, il n'y a pas de différence fondamentale avec d'autres modèles que vous connaissez peut-être (comme GPT-4o, Claude, Qwen, Midjourney, etc.) : **vous saisissez une description, le modèle génère le résultat.** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image2.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image3.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image4.png) + +Vous pouvez le considérer comme un « pinceau ». Dans ce chapitre, nous ne nous intéressons qu'à une seule chose : +👉 **Ce pinceau peut-il tracer le premier coup dans vos mains.** + +En pratique, NanoBanana peut être utilisé directement via des plateformes officielles comme **Google AI Studio**, ou intégré dans un flux de développement via **API**. Ce tutoriel utilise l'approche par appel API. Le modèle NanoBanana 2 est maintenant disponible, vous pouvez essayer avec les derniers grands modèles. + +### 1.2 Une génération de niveau « Hello World » + +Avant de commencer, vous n'avez besoin que de trois étapes : + +1. Créer un nouveau dossier dans Trae + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image5.png) + +2. Créer un nouveau fichier Python + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image6.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image7.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image8.png) + +3. Coller le code ci-dessous en entier + +Trae se chargera automatiquement du déploiement de l'environnement et de l'installation des dépendances, sans configuration supplémentaire. + +Le code utilisera la clé API de NanoBanana. Nous ne détaillons pas ici le processus de demande — il vous suffit de l'obtenir et de renseigner les paramètres correspondants. **À ce stade, l'objectif n'est pas de comprendre chaque ligne de code, mais simplement de le faire fonctionner avec succès.** + +```Python +# /// script +# dependencies = [ +# "gradio>=4.0.0", +# "pillow>=10.0.0", +# "requests>=2.31.0", +# ] +# /// + +import gradio as gr +import requests +import base64 +from PIL import Image +import io +import os +import time +import re +from typing import Optional, Dict, Any, List + +# Configuration API +NANOBANANA_API_URL: str = "YOUR API URL" +NANOBANANA_API_KEY: str = "YOUR API KEY" +OUTPUT_DIR: str = "outputs" + +# S'assurer que le répertoire de sortie existe +os.makedirs(OUTPUT_DIR, exist_ok=True) + +def image_to_base64_data_uri(image: Image.Image) -> str: + """ + Convertir une image PIL en format data URI compatible avec l'API OpenAI. + """ + buffer = io.BytesIO() + # Convertir en PNG pour garantir la compatibilité + image.save(buffer, format="PNG") + encoded = base64.b64encode(buffer.getvalue()).decode('utf-8') + return f"data:image/png;base64,{encoded}" + +def base64_to_image(base64_str: str) -> Optional[Image.Image]: + """ + Convertir une chaîne base64 pure en image PIL. + """ + try: + image_bytes = base64.b64decode(base64_str) + return Image.open(io.BytesIO(image_bytes)) + except Exception as e: + print(f"Échec du décodage Base64 : {e}") + return None + +def extract_base64_from_response(content: Any) -> Optional[str]: + """ + Logique d'analyse principale : extraire les données Base64 de l'image depuis le content renvoyé par l'API. + Compatible avec les formats Markdown et les formats de liste structurée. + """ + if not content: + return None + + base64_data = None + + # 1. Tentative d'extraction structurée (List) + # Format de retour correspondant : [{"type": "image_url", "image_url": {"url": "data:..."}}] + if isinstance(content, list): + for part in reversed(content): # Recherche inversée, les images les plus récentes sont généralement à la fin + if isinstance(part, dict): + # Vérifier le champ image_url ou output_image + img_field = part.get("image_url") or part.get("image") or part.get("output_image") + if isinstance(img_field, dict): + url = img_field.get("url", "") + if url.startswith("data:image/") and "," in url: + return url.split(",", 1)[1].strip() + + # Si aucune image structurée dans la liste, essayer de concaténer le texte pour trouver du Markdown + text_parts = [ + str(p.get("text", "")) + for p in content + if isinstance(p, dict) and p.get("type") in ["text", "input_text"] + ] + content_str = "".join(text_parts) + else: + content_str = str(content) + + # 2. Tentative d'extraction par regex Markdown (String) + # Format de retour correspondant : "Here is your image: ![img](data:image/png;base64,AAAA...)" + pattern = re.compile(r"!\[.*?\]\((data:image/[^;]+;base64,[^)]+)\)", re.IGNORECASE) + match = pattern.search(content_str) + + if match: + data_url = match.group(1) + if "," in data_url: + return data_url.split(",", 1)[1].strip() + + return None + +def synthesize(prompt: str, input_image: Optional[Image.Image]) -> Optional[Image.Image]: + """ + Appeler l'API Nanobanana pour la génération. + """ + if not prompt or not prompt.strip(): + gr.Warning("Veuillez entrer un prompt") + return None + + print(f">>> Début de la tâche : {prompt[:50]}...") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {NANOBANANA_API_KEY}" + } + + # Construire le payload conforme au standard OpenAI Vision / Chat + messages = [] + + if input_image is not None: + # Mode image à image / entrée multimodale + print(">>> Image d'entrée détectée, utilisation du mode multimodal") + img_base64 = image_to_base64_data_uri(input_image) + messages.append({ + "role": "user", + "content": [ + {"type": "text", "text": prompt}, + {"type": "image_url", "image_url": {"url": img_base64}} + ] + }) + else: + # Mode texte à image + messages.append({ + "role": "user", + "content": prompt + }) + + payload = { + "messages": messages, + # Utiliser le modèle validé dans le premier extrait de code + "model": "gemini-2.5-flash-image", + # Paramètres optionnels, selon le support de l'API + "stream": False + } + + try: + # Augmenter le timeout, la génération d'images est généralement plus lente + response = requests.post(NANOBANANA_API_URL, headers=headers, json=payload, timeout=120) + + # Vérifier le statut HTTP + if response.status_code != 200: + error_msg = f"Échec de la requête API : {response.status_code} - {response.text}" + print(error_msg) + gr.Error(error_msg) + return None + + result = response.json() + # Debug : afficher le début de la réponse pour faciliter le débogage + print(f"Réponse brute de l'API (tronquée) : {str(result)[:200]}...") + + # Extraire le Content + content = None + if "choices" in result and len(result["choices"]) > 0: + content = result["choices"][0].get("message", {}).get("content") + + if not content: + gr.Warning("Aucun champ content dans le résultat de l'API") + return None + + # Utiliser la logique précédemment validée pour extraire le Base64 + base64_str = extract_base64_from_response(content) + + if base64_str: + output_image = base64_to_image(base64_str) + if output_image: + return output_image + + # Si aucune image extraite, le modèle a peut-être refusé ou ne renvoyé que du texte + text_content = str(content) if not isinstance(content, list) else " ".join([str(x) for x in content]) + gr.Info(f"Aucune image générée, le modèle a renvoyé du texte : {text_content[:100]}...") + return None + + except requests.exceptions.Timeout: + gr.Error("Délai d'attente dépassé, veuillez réessayer plus tard") + return None + except Exception as e: + import traceback + traceback.print_exc() + gr.Error(f"Erreur inconnue : {str(e)}") + return None + +# Configuration de l'interface Gradio +with gr.Blocks(title="Nanobanana Image Generator") as app: + gr.Markdown("# Nanobanana Text/Image to Image") + gr.Markdown("Basé sur le modèle Gemini-2.5-Flash-Image, supporte texte vers image et image vers image.") + + with gr.Row(): + with gr.Column(): + prompt_input = gr.Textbox( + label="Prompt", + placeholder="Exemple : A cyberpunk cat holding a neon sign...", + lines=3 + ) + image_input = gr.Image( + label="Image de référence (optionnel, pour image vers image)", + type="pil", + height=300 + ) + submit_btn = gr.Button("Lancer la génération", variant="primary") + + with gr.Column(): + image_output = gr.Image(label="Résultat de la génération", format="png") + + submit_btn.click( + fn=synthesize, + inputs=[prompt_input, image_input], + outputs=image_output + ) + +if __name__ == "__main__": + app.launch(share=True) +``` + +Lorsque Trae indique que l'exécution a réussi, cliquez sur le lien local qu'il fournit (généralement http://127.0.0.1:7860). + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image9.png) + +Si tout se passe bien, vous verrez une interface de dessin AI déjà fonctionnelle. + +Cette interface peut sembler simple, mais elle possède déjà les deux capacités les plus fondamentales des outils de dessin de niveau commercial : texte vers image et image vers image. + +* **Gauche :** **Zone d'instructions (Input Zone)** — c'est ici que vous donnez vos ordres. +* **Prompt (champ de prompt) :** saisissez votre description créative (l'anglais est recommandé). +* **Input Image (champ d'image de référence) :** + * **Mode texte vers image :** laissez ce champ **vide**. + * **Mode image vers image :** glissez-déposez une image locale ici, l'IA créera en s'en inspirant. +* **Bouton Submit :** cliquez pour envoyer l'instruction et lancer la génération. +* **Droite : Zone d'affichage (Output Zone)** — c'est ici que la magie opère, les résultats générés seront affichés ici. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image10.png) + +Maintenant, essayons de générer votre première image ! + +Le prompt utilisé dans cet exemple est : + +> **A red apple** + +C'est un exemple délibérément simplifié, sans aucune description de style ou de paramètres. + +#### Processus réel + +Après l'exécution du code, le processus se résume en trois étapes : + +1. Envoyer la description textuelle au modèle +2. Le modèle génère l'image correspondante +3. L'image est sauvegardée en tant que fichier local + +Quelques secondes plus tard, vous verrez le résultat généré localement. La génération du modèle étant aléatoire, le même prompt donnera des résultats différents. Vous pouvez générer plusieurs fois pour choisir l'image qui vous plaît. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image11.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image12.png) + +Vous pouvez aussi enrichir votre prompt avec plus de descriptions et de contraintes. Par exemple, avec le prompt suivant, l'image obtenue sera plus spécifique. + +```Plain +"A hyper-realistic close-up of a fresh red apple with water droplets on its skin, sitting on a dark rustic wooden table. Cinematic dramatic lighting, rim light, shallow depth of field, bokeh background, 8k resolution, macro photography." +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image13.png) + +Cliquez sur download dans la zone Output Image pour sauvegarder l'image localement. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image14.png) + +### 1.3 Scénarios courants de génération d'assets avec les modèles de génération d'images + +Dans la pratique professionnelle, la génération d'images par grands modèles est davantage utilisée pour **produire efficacement des assets de design** que pour créer des œuvres d'art uniques. + +En observant les cas les plus populaires sur certains comptes de marketing liés au design, on constate que leur production se concentre principalement sur deux catégories de scénarios : + +* **Texte vers image (de 0 à 1)** +* **Image avec référence (de 1 à N)** + +#### I. Texte vers image : obtenir rapidement du matériel de design + +Cette catégorie de scénarios se concentre sur l'efficacité. Quand il faut combler des vides dans un design (états vides, avatars, illustrations), l'IA sert essentiellement de **banque d'images à génération instantanée**. + +1. ##### Générer des assets de design UI + +* Tendance : icônes 3D style glassmorphisme ou argile sur Dribbble +* Manifestation courante : matériaux translucides, bords lumineux, icônes fonctionnelles ou météo aux couleurs bonbon + +**Exemple de Prompt :** + +> A set of 3D weather icons (sun, cloud, rain), glassmorphism style, frosted glass texture, soft pastel gradient colors, soft studio lighting, isometric view, transparent background, 4k. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image15.png) + +2. ##### Générer des logos + +* Tendance : logos tech minimalistes aux lignes épurées et combinaisons géométriques +* Manifestation courante : palette noir et blanc, design en espace négatif, identité de marque affirmée + +**Exemple de Prompt :** + +> Minimalist vector logo design for a tech brand "Coffee Code", combining a coffee cup with coding brackets < >, flat design, solid black lines, white background, Paul Rand style, svg. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image16.png) + +3. ##### Générer des images d'utilisateurs pour un site + +* Tendance : avatars 3D virtuels courants sur les sites SaaS, pour éviter les problèmes de droits d'image de personnes réelles +* Manifestation courante : expressions amicales, proportions cartoon, style Pixar ou Memoji + +**Exemple de Prompt :** + +> Close-up portrait of a friendly young tech professional, smiling, Memoji 3D style, clay render, bright colors, soft lighting, solid plain background, Pixar character design. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image17.png) + +4. ##### Générer des illustrations d'articles + +* Tendance : illustrations plates abstraites courantes dans les blogs d'entreprises tech +* Manifestation courante : palette violet-bleu, proportions de personnages exagérées, éléments UI flottants + +**Exemple de Prompt :** + +> Editorial flat illustration representing remote work, a person sitting on a giant globe using a laptop, corporate memphis art style, vibrant colors (purple and teal), vector texture. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image18.png) + +#### II. Image avec référence : maintenir la cohérence visuelle + +Cette catégorie de scénarios se concentre davantage sur **l'extensibilité**. Quand vous avez déjà une image clé satisfaisante et devez générer un ensemble complet d'assets au style cohérent. + +5. ##### Un ensemble de boutons ou d'assets d'interaction cohérents avec l'image principale + +Dans le développement de jeux, la cohérence de l'UI est cruciale. Supposons que vous ayez déjà le bouton **« PLAY »** de l'interface principale et deviez maintenant créer un ensemble complet de boutons fonctionnels au style unifié (pause, paramètres, accueil). Dessiner à la main chaque bouton pour garantir une cohérence parfaite en termes de brillance, perspective et valeurs de couleur est très difficile. + +**Processus de base :** + +1. Sauvegarder l'image du bouton bleu « PLAY » existant + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image19.png) + +2. La glisser dans la zone **Input Image** comme modèle de référence pour les générations suivantes +3. Garder la description de style du prompt inchangée, modifier uniquement le contenu principal + +Avec ce processus, il suffit de remplacer la description du contenu pour obtenir des boutons aux fonctionnalités différentes mais au style cohérent. + +**Exemple de Prompt :** + +**Variante A : Bouton pause (icône)** + +> A capsule-shaped game UI button with a white pause icon (two vertical bars) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image20.png) + +**Variante B : Bouton paramètres (icône complexe)** + +> A capsule-shaped game UI button with a white gear icon (settings symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image21.png) + +**Variante C : Bouton rejouer (changement de forme)** + +Si vous devez ajuster la forme du bouton, décrivez-la directement dans le prompt — le modèle tentera de changer la structure tout en préservant les caractéristiques de matériau. + +> A round game UI button with a white circular arrow icon (replay symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image22.png) + +Avec cette série d'opérations, vous pouvez non seulement remplacer la fonction et l'icône du bouton, mais même changer sa forme, tout en conservant une cohérence élevée en termes de matériau, de palette et de lumière parmi tous les résultats générés. C'est précisément la valeur centrale des grands modèles dans les scénarios de déclinaison d'assets de design. + +## Chapitre 2 : Un assistant de génération d'images plus obéissant — l'exemple de Lovart + +Dans la première partie, nous avons appelé NanoBanana directement via le code et avons expérimenté le flux de base « saisie = génération ». Cette approche fonctionne bien quand les besoins sont simples. Mais quand la tâche de génération commence à inclure plus de contraintes, par exemple : + +* Besoin de plusieurs images au style cohérent +* Besoin d'ajustements itératifs sur les résultats existants +* Besoin de modifier dynamiquement la direction de génération en fonction des entrées utilisateur + +L'approche par appel unique devient progressivement insuffisante. + +C'est là qu'il faut introduire un **Agent AI (Intelligence artificielle)**. Cette section prend **Lovart** comme exemple pour montrer comment le flux de travail change lorsque le modèle de génération d'images acquiert une « couche de réflexion ». Notez bien ! Il ne s'agit pas de publicité, mais simplement de vous aider à comprendre rapidement la praticité des Agents AI. + +### 2.0 Découvrir Lovart : votre agent de design AI + +Lovart est un outil de design basé sur des Agents, disponible en web. Comparé aux outils de génération d'images classiques, il ajoute une couche de « réflexion et planification » avant la génération. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image23.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image24.png) + +Une fois dans Lovart, voici les principaux éléments de contrôle à connaître : + +#### Sélection du modèle + +Cliquez sur l'icône du cube sous le champ de saisie pour voir les modèles de génération disponibles (comme GPT Image, Flux, etc.). + +Pour rester cohérent avec l'exemple précédent, cette section utilise toujours NanoBanana comme modèle de génération sous-jacent. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image25.png) + +#### Mode de réflexion + +C'est le commutateur central de Lovart : + +* **Fast Mode (⚡)** : proche de l'API native, réponse rapide, adapté à la génération d'images uniques avec des instructions claires +* **Thinking Mode (💡)** : mode Agent, l'IA décompose d'abord le besoin, réécrit le prompt, puis exécute la génération + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image26.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image27.png) + +#### Capacité de connexion Internet + +En activant l'icône du globe, l'Agent peut rechercher des informations en ligne pendant la génération (tendances de design, palettes de couleurs, etc.) comme entrée complémentaire. + +### 2.1 Pourquoi l'API native ne suffit-elle pas ? + +Même s'il est déjà possible de générer des images de bonne qualité via Python, l'API native reste limitée pour les tâches complexes. La raison principale est que l'API native est fondamentalement impérative. Quand vous lui demandez de générer un objet spécifique, elle peut l'exécuter directement ; mais quand l'entrée devient « concevoir un ensemble complet d'assets de jeu », elle ne décompose pas spontanément l'objectif en étapes exécutables. + +La différence fondamentale de Lovart réside dans le mécanisme d'Agent. Entre l'entrée utilisateur et le modèle de génération d'images, elle ajoute une couche de logique de compréhension et de planification : identifier d'abord l'intention de l'utilisateur, puis décomposer la tâche, réécrire le prompt, et enfin exécuter la génération. + +### 2.2 Démonstration pratique : créer un ensemble de stickers d'IP en 5 minutes + +Prenons l'exemple de **« créer un ensemble de stickers d'IP de canard programmeur »** pour voir comment l'Agent participe à l'ensemble du processus. + +#### Phase 1 : Planification (capacité de réflexion de l'Agent) + +**Problème de l'API native :** +Vous devez penser vous-même au design du personnage, aux états émotionnels et écrire un prompt séparé pour chaque image. + +**L'approche de Lovart :** + +1. Activer le 💡 **Thinking Mode** +2. Saisir une seule instruction : + +> Concevoir un ensemble de stickers d'IP de canard programmeur, style flat design, mignon + +L'IA ne dessine pas immédiatement. Elle va d'abord chercher sur Internet des images de design de canards programmeurs. Puis elle produit un plan décomposé, générant automatiquement des scènes comme Debug, Coffee Break, Panic, avec les descriptions visuelles correspondantes. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image28.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image29.png) + +À cette étape, l'IA passe du rôle d'« exécutant » à celui de « planificateur ». Une fois que l'IA a analysé vos besoins, vous pouvez voir plusieurs styles et contenus d'images de canards programmeur dans la zone de canevas de Lovart. Vous pouvez commencer à filtrer les styles qui vous plaisent. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image30.png) + +#### Phase 2 : Cohérence (ancrage visuel basé sur la référence) + +Les images dans Lovart ne sont pas seulement des résultats, elles participent aussi aux générations suivantes. + +##### Image de référence complète + +* Sélectionnez le « canard standard » qui vous satisfait le plus dans les esquisses, cliquez sur l'image correspondante dans la zone de canevas +* L'image apparaîtra automatiquement dans la zone de dialogue comme Reference + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image31.png) + +* Saisissez une nouvelle action (comme « heureux ») et générez + +Le résultat généré héritera de la palette, des proportions et des détails du modèle original. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image32.png) + +##### Référence partielle / Intégration multi-images + +Outre l'utilisation d'une image complète comme référence, Lovart supporte aussi : + +* **Sélectionner uniquement une zone partielle de l'image** (par exemple uniquement le chapeau ou l'expression) + +Cliquez sur l'onglet à gauche de la zone de canevas, sélectionnez la touche « Mark », et marquez la zone partielle souhaitée sur l'image cible. Cette partie sera automatiquement synchronisée dans la zone de dialogue. Par exemple, ici nous pouvons choisir de modifier la couleur de fond. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image33.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image34.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image35.png) + +On peut voir que la nouvelle image générée n'a changé que la couleur de fond, ce qui correspond bien à notre demande. + +* **Référencer des sous-éléments de plusieurs images** et les combiner pour générer un nouveau résultat + +Par exemple : vous pouvez conserver le personnage principal de l'image A tout en remplaçant uniquement le chapeau par le style de l'image B. L'Agent intégrera automatiquement ces contraintes visuelles en arrière-plan. + +Prenons l'exemple du canard programmeur : nous pouvons choisir de conserver l'image du canard de la première image et la remplacer dans la deuxième image comme élément principal. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image36.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image37.png) + +L'effet final est très significatif. Vous pouvez aussi essayer d'autres combinaisons ! + +#### Phase 3 : Livraison (appels d'outils de l'Agent) + +Une fois la génération terminée, vous pouvez directement exécuter : agrandissement, suppression d'arrière-plan, effacement, etc. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image38.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image39.png) + +Il ne s'agit pas de simples filtres, mais de résultats obtenus par l'Agent en调度ant automatiquement différents outils. + +Une fois le style de base défini, il est très rapide de générer toute une série d'images de stickers. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image40.png) + +Au final, nous obtenons des assets de qualité production directement livrables, et non pas de simples images de démonstration. + +### 2.3 Informations sur l'utilisation et la tarification + +Lovart utilise un modèle de tarification par abonnement, avec différents forfaits correspondant à différentes allocations d'utilisation et droits de fonctionnalité. Les détails sont disponibles sur le site officiel. + +Ce tutoriel ne fait aucune recommandation ni comparaison de forfaits ; si vous avez un besoin en usage réel, vous pouvez choisir de passer à un forfait payant selon votre situation personnelle. +Le paiement est actuellement possible via **Alipay** et d'autres méthodes. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image41.png) + +#### Résumé + +Lovart ne remplace pas le modèle sous-jacent, mais grâce au mécanisme d'Agent, fait évoluer la génération d'images de « l'exécution unique » vers un « flux de travail continu ». + +Quand la tâche commence à impliquer de la planification, de la cohérence et de la livraison, l'avantage de ce type d'outils devient très évident. + +## Chapitre 3 : Créer vous-même un assistant de dessin intelligent + +Outre l'utilisation directe de Lovart, nous pouvons aussi implémenter nous-mêmes une version simplifiée d'un assistant de dessin. + +Ce chapitre prend l'exemple de « l'illustration automatique d'articles » et construit progressivement un Agent avec des capacités de réflexion, en partant d'un problème concret. + +### 3.1 Le problème : pourquoi envoyer directement un article à un modèle de dessin ne fonctionne pas ? + +Envoyer directement un article long à NanoBanana en demandant une illustration donne rarement des résultats satisfaisants. La raison n'est pas que le modèle « dessine mal », mais qu'**il n'est pas doué pour comprendre les textes longs**. + +Les modèles de génération d'images sont plus adaptés aux descriptions visuelles courtes et précises. Quand l'entrée devient un article avec sa structure, ses points clés et son contexte, le modèle ne peut pas déterminer quelles parties doivent vraiment être représentées dans l'image. Cela conduit souvent à des résultats hors sujet ou ne capturant que des détails épars, sans capacité de synthèse globale. + +Fondamentalement, le modèle d'images n'a que la capacité d'« exécuter », mais manque d'un processus d'analyse et de sélection du texte. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image42.png) + +### 3.2 Approche de résolution : séparer « compréhension » et « exécution » avec un Agent + +Pour résoudre ce problème, la clé n'est pas des prompts plus complexes, mais **de réfléchir avant de dessiner**. Nous introduisons donc une « couche de réflexion » indépendante dans le flux de génération, et construisons un Agent minimal mais fonctionnel. + +L'objectif principal de cet Agent est simple : **que l'image finale générée soit la plus proche possible de la véritable intention expressive de l'utilisateur.** + +Le flux global peut se résumer ainsi : **Texte long en entrée → Modèle de langage pour compréhension et jugement → Génération d'un prompt visuel approprié → Modèle d'images pour la génération → Image en sortie** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image43.png) + +Comment notre Agent peut-il comprendre l'intention de l'utilisateur ? + +Nous choisissons de créer une « couche de réflexion » simplifiée, avec trois types d'intentions : entrée invalide, génération directe, texte long nécessitant compréhension. + +Dans cet Agent, la répartition des rôles se résume en quatre points : + +1. **Le modèle de langage comme cœur décisionnel** + Il est responsable de la compréhension du contenu de l'article, du jugement de l'intention de l'entrée utilisateur, et de la répartition de la tâche vers le chemin de génération approprié, décidant « que faire ensuite » et comment générer le prompt de dessin. +2. **Le modèle d'images comme exécutant** + Le modèle d'images ne participe pas à la compréhension ni au jugement, il reçoit uniquement les instructions visuelles déjà préparées et se concentre sur le rendu d'image. +3. **L'utilisateur comme guide intervenant** + Outre la saisie directe de texte, l'utilisateur peut ajuster manuellement le prompt généré pendant le processus, ou ajouter une image de référence pour guider la génération, orientant et affinant ainsi le résultat final. +4. **Gradio et l'API backend comme couche d'hébergement global** + Ils sont responsables de la liaison entre l'interface, les appels de modèle et l'affichage des résultats, garantissant que l'Agent fonctionne de manière stable comme une application web complète. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image44.png) + +### 3.3 Préparation pratique : obtenir les API + +Cela a l'air intéressant, n'est-ce pas ! Pour exécuter le flux ci-dessus, nous n'avons besoin que de deux types d'API. + +#### La main : API NanoBanana (génération d'images) + +Réutilisez directement la clé API et l'URL API déjà configurées au chapitre 1, sans configuration supplémentaire. + +#### Le cerveau : API SiliconFlow (réflexion textuelle) + +Nous avons besoin d'un grand modèle de langage pour assurer la « couche de réflexion ». Ce tutoriel utilise le service de modèle fourni par SiliconFlow : [https://cloud.siliconflow.cn](https://cloud.siliconflow.cn/) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image45.png) + +SiliconFlow fournit une interface compatible avec la spécification API OpenAI, très facile à appeler via des requêtes réseau standard dans votre projet. Nous choisissons ici le modèle gratuit Qwen2.5-7B-Instruct. Le contenu nécessaire pour l'appel est déjà intégré dans le Prompt ci-dessous. Avant de commencer, il vous suffit de créer un compte sur le site officiel et de générer une clé API. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image46.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image47.png) + +Cette clé sera utilisée pour les appels de modèle ultérieurs. + +### 3.4 Construire l'Agent : + +Cette expérience utilise principalement Trae pour vous aider à écrire le code. Ce tutoriel utilise le modèle Gemini-3-Pro-Preview. L'idée générale est de créer un nouveau projet, de copier le Prompt complet ci-dessous dans la boîte de dialogue et de l'envoyer, de remplacer progressivement les clés API, puis d'exécuter le code et effectuer les tests. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image48.png) + +#### Phase 1 : Framework de base Gradio Blocks et mise en page de l'interface + +Dans cette phase, notre objectif principal est de construire d'abord une « apparence » pour l'Agent entier, en réalisant la conception de la page frontend. Copiez le Prompt ci-dessous dans la boîte de dialogue de Trae, et après implémentation, vous obtiendrez une URL locale (généralement http://127.0.0.1:7860) pour voir l'interface et vérifier le résultat. + +```Plain +Bloc 1 : Framework de base Gradio Blocks et mise en page de l'interface +1. Objectif de la tâche +· Basé sur la mise en page Blocks de Gradio 4.0.0+, implémenter l'interface de base du projet « LLM + Nanobanana texte vers image », en suivant strictement une disposition fixe gauche-droite, en initialisant tous les composants UI et en définissant les états initiaux corrects. + +2. Exigences de la stack technique +· Doit utiliser le mode Blocks de Gradio 4.0.0+, interdit le mode Interface ; +· Dépendances : gradio>=4.0.0, pillow>=10.0.0 (import uniquement, pas encore de logique de traitement d'image) ; +· Le code doit être un fichier Python complet et exécutable, incluant toutes les instructions d'import nécessaires. + +3. Règles de mise en page de l'interface (contrainte principale, intégrant les détails pratiques) +· Mise en page globale : +Titre de la page : Outil complet de texte vers image piloté par LLM ; +Disposition fixe gauche-droite : gauche occupe 60% de la largeur, droite 40%, utiliser gr.Row et gr.Column pour le contrôle des proportions. +· Gauche 60% (zone du processus de génération de prompts) liste des composants : +input_text : gr.Textbox, label « Texte d'entrée (paragraphe de tutoriel / instruction de dessin) », lines=6, placeholder « Veuillez entrer le texte de tutoriel nécessitant une illustration ou une instruction de dessin direct... » ; +identify_intent_btn : gr.Button, value="Identifier l'intention", état initial normal cliquable ; +intent_status : gr.Textbox, label « Type d'intention / Statut de traitement », lines=2, interactive=False, valeur initiale « Intention non identifiée » ; +system_prompt : gr.Textbox, label « System Prompt (éditable uniquement pour l'intention d'illustration d'article) », lines=4, interactive=False, placeholder « Règles de contrainte pour la génération de prompts par le LLM... » ; +confirm_prompt_btn : gr.Button, value="Confirmer la génération du prompt de dessin", interactive=False (désactivé initialement pour éviter les erreurs) ; +generation_prompt : gr.Textbox, label « Prompt de dessin (éditable) », lines=3, interactive=True, valeur initiale vide, placeholder « Le prompt de dessin en anglais généré s'affichera ici, modification manuelle possible... ». +· Droite 40% (zone de génération d'images Nanobanana) liste des composants : +ref_image : gr.Image, label « Image de référence (optionnel, image vers image) », type=filepath, height=300, autorise l'upload ; +generate_btn : gr.Button, value="Générer l'image", interactive=False (désactivé initialement, pas de prompt = pas de clic) ; +result_image : gr.Image, label="Résultat de la génération", type=pil, height=300, initialement vide, interactive=False. + +4. Exigences de logique d'interaction +· L'état interactive initial de tous les composants suit strictement la configuration ci-dessus, mis à jour dynamiquement via des fonctions par la suite ; +· L'état désactivé des boutons doit être visuel (grisé), pour éviter les erreurs de manipulation. + +5. Exigences de sortie +· Générer un code Python complet, implémentant uniquement la mise en page de l'interface et l'initialisation des composants, sans aucune logique métier ; +· Commentaires de code clairs, noms de composants cohérents avec la version pratique (input_text/identify_intent_btn etc.) ; +· Le code doit être directement exécutable, la structure de l'interface doit correspondre exactement à la description. +``` + +Après avoir ouvert http://127.0.0.1:7860 dans le navigateur, vous verrez que Trae a généré la page web suivante selon nos exigences, globalement conforme — vous pouvez passer à l'étape suivante de génération. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image49.png) + +#### Phase 2 : Module d'identification d'intention par LLM (API Siliconflow) + +Dans l'utilisation quotidienne de VLM pour le dessin, il existe trois types d'entrées courantes : + +1. Contenu sans signification, comme « bonjour », « as-tu mangé aujourd'hui », impossible d'en tirer une image. +2. Article/texte long, avec un nombre de mots important, comme un article structuré d'environ 200 mots, nécessitant d'abord de comprendre la structure et le contenu de l'article avant de réfléchir à la génération d'une image résumant ce texte. +3. Instruction de dessin direct, comme « dessine-moi un chien qui prend un bain », où la demande est déjà très spécifique et l'image peut être générée directement. + +Comme précédemment, copiez le Prompt ci-dessous dans la boîte de dialogue de Trae et ajoutez les API obtenues aux étapes précédentes. + +```Plain +Bloc 2 : Module d'identification d'intention par LLM (API Siliconflow) +1. Objectif de la tâche +Sur la base de l'interface Gradio déjà implémentée, ajouter la logique de clic au bouton « Identifier l'intention », appeler l'API Siliconflow pour l'identification d'intention et lier l'état des composants. + +2. Exigences de la stack technique +Basé sur Gradio 4.0.0+ Blocks ; +Dépendances : requests>=2.31.0, openai ; +Sortie : fichier Python complet et exécutable, incluant l'interface du Bloc 1 + la logique de ce module. + +3. Règles métier principales (à ne jamais transgresser) +· Règles de classification d'intention (3 types uniquement, retourner strictement un nombre + description) +1 = Contenu sans signification : simple bavardage, salutations, conversation hors sujet, sans aucun besoin de dessin ou d'illustration (comme « bonjour » « as-tu mangé ») ; +2 = Besoin d'illustration pour article/texte long : l'utilisateur entre un article complet, un tutoriel, un paragraphe, un texte explicatif, au contenu plutôt narratif/explicatif/pédagogique, impliquant implicitement la nécessité de générer une illustration pour ce contenu, sans que l'utilisateur dise explicitement « illustre ce texte » ; +3 = Instruction de dessin direct : l'utilisateur entre une commande de dessin courte et claire, sans contexte de texte long, demandant directement de dessiner quelque chose (comme « dessine un chat style Apple »). +· Contraintes d'appel LLM (intégrant le template de la version pratique) +URL de l'interface : https://api.siliconflow.cn/v1/chat/completions ; +Modèle : Qwen/Qwen2.5-7B-Instruct ; +temperature=0.1 ; +Définition uniforme du code : +python +LLM_BASE_URL = "https://api.siliconflow.cn/v1" +LLM_API_KEY = "" # L'utilisateur remplace lui-même +LLM_MODEL = "Qwen/Qwen2.5-7B-Instruct" +# Template d'identification d'intention validé en pratique (figé dans le code) +INTENT_PROMPT_TEMPLATE = """Vous devez identifier l'intention du texte saisi par l'utilisateur, ne retourner qu'un des 3 types de résultats suivants (format : nombre + description en français) : +1 = Contenu sans signification ; 2 = Besoin d'illustration pour article/texte long ; 3 = Instruction de dessin direct. + +Texte de l'utilisateur : {user_input} + +Résultat de l'identification : +Extraire uniquement le nombre et la description du résultat, interdit tout contenu supplémentaire.""" + +4. Règles de liaison des composants +· Résultat 1 : intent_status affiche « 1 = Contenu sans signification : aucun besoin de dessin », system_prompt reste désactivé, confirm_prompt_btn désactivé ; +· Résultat 2 : intent_status affiche « 2 = Besoin d'illustration pour article/texte long : générer une illustration pour le contenu saisi », activer system_prompt et remplir la règle par défaut, activer confirm_prompt_btn ; +· Résultat 3 : intent_status affiche « 3 = Instruction de dessin direct : générer une image selon l'instruction », system_prompt désactivé et rempli avec la règle par défaut, activer confirm_prompt_btn. + +5. Gestion des exceptions +Exceptions API, exceptions de parsing : afficher un message convivial, pas de crash, les composants reviennent à l'état initial. + +6. Exigences de sortie +Générer un code complet et exécutable, il suffit de remplacer LLM_API_KEY pour l'utiliser, logique claire et commentaires complets, template d'identification d'intention strictement conforme à la version pratique. +``` + +Rafraîchissez l'URL http://127.0.0.1:7860 précédente et commencez à tester si les trois cas sont correctement détectés. + +1. Contenu sans signification : essayez de saisir « bonjour », « merci », etc. — la détection fonctionne correctement. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image50.png) + +2. Article/texte long : ici nous avons utilisé un texte généré par Doubao décrivant l'intelligence artificielle. Vous pouvez aussi tester avec vos propres paragraphes de thèse. + +```Plain +L'intelligence artificielle remodelle l'écosystème éducatif avec une profondeur et une ampleur sans précédent. Grâce à des algorithmes d'apprentissage adaptatif, les systèmes IA peuvent construire la carte cognitive de chaque étudiant, suivre en temps réel la trajectoire de maîtrise des connaissances, et ajuster dynamiquement le niveau de difficulté et le mode de présentation du contenu pédagogique. Dans un environnement de classe traditionnel, les enseignants peinent souvent à satisfaire simultanément les besoins d'étudiants aux styles d'apprentissage et niveaux de capacité différents, tandis que les plateformes éducatives basées sur l'apprentissage profond peuvent analyser les schémas de comportement des étudiants dans les simulations interactives, identifier les obstacles subtils dans la compréhension de concepts complexes comme la mécanique quantique ou le calcul, et fournir des échafaudages cognitifs précis. + +Les tuteurs virtuels pilotés par des moteurs avancés de traitement du langage naturel peuvent non seulement déconstruire des questions ouvertes, comme « comment évaluer l'impact de la Révolution française sur les systèmes démocratiques modernes », mais aussi guider des dialogues socratiques stimulant la pensée critique. Lorsqu'un étudiant rédige un essai sur l'impact du changement climatique sur les écosystèmes polaires, l'assistant d'écriture IA peut analyser la rigueur logique de son argumentation, pointer les problèmes d'actualité dans les références de données, et suggérer des termes scientifiques plus précis. Dans le domaine de l'éducation spécialisée, la vision par ordinateur permet à l'IA d'identifier les indices non verbaux des enfants du spectre autistique dans les interactions sociales, ajuster les stratégies d'intervention, tandis que les algorithmes de calcul affectif aident à détecter la frustration lors de l'apprentissage en ligne, fournissant en temps utile des retours encourageants. + +Cependant, cette intégration technologique soulève une série de dilemmes éthiques. Les biais algorithmiques peuvent involontairement marginaliser les étudiants de certains contextes culturels, les questions de transparence dans la collecte de données soulèvent des préoccupations concernant la vie privée académique, et la dépendance excessive aux systèmes de notation automatisés peut affaiblir la compréhension approfondie des enseignants sur le processus de pensée des étudiants. Plus complexe encore, quand l'IA commence à générer des expériences de laboratoire virtuel hautement réalistes, nous devons redéfinir la valeur de « l'expérience pratique » dans l'éducation. Le paradigme éducatif futur pourrait évoluer vers des enseignants humains se concentrant sur le développement de la créativité, de l'empathie et du jugement moral, tandis que les systèmes IA assumeraient les fonctions de transmission des connaissances, d'entraînement aux compétences et d'évaluation personnalisée, formant un symbiote éducatif en co-évolution, exploitant à la fois les avantages computationnels des machines et conservant la chaleur unique de l'éducation humaine. +``` + +Détection réussie également ! + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image51.png) + +3. Instruction de dessin direct : ici nous avons saisi « je veux dessiner un chat », détecté avec précision. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image52.png) + +Nous avons ainsi réussi à implémenter la deuxième phase — l'identification d'intention. + +#### Phase 3 : Module de génération de prompts de dessin (second appel LLM) + +Après l'identification d'intention, pour les articles ou textes longs, il reste une étape très importante : générer le prompt de dessin, et c'est précisément le point clé de cet Agent. + +```SQL +Bloc 3 : Module de génération de prompts de dessin (second appel LLM) +1. Objectif de la tâche +Sur la base de l'identification d'intention, implémenter la logique du bouton « Confirmer la génération du prompt de dessin », appeler le LLM pour optimiser le texte en un prompt visuel en anglais adapté au dessin, remplir la zone d'édition et lier le bouton « Générer l'image ». + +2. Exigences de la stack technique +Identiques au Bloc 2, sortie : code complet = Bloc 1 + Bloc 2 + ce module ; +Partage les LLM_BASE_URL, LLM_API_KEY, LLM_MODEL définis au Bloc 2, pas de nouvelle clé. + +3. Règles métier principales (intégrant la logique d'assemblage de Prompt de la version pratique) +· Règles d'entrée pour la génération de prompts (à suivre strictement) +La génération de prompts de dessin n'est plus une simple concaténation de chaînes, mais construit une liste standard de messages Chat, la structure du code est la suivante : +python +messages=[ + # Rôle System : contenu system_prompt final confirmé/édité par l'utilisateur sur la page + {"role": "system", "content": final_system_prompt}, + # Rôle User : porte les données à traiter, clarifie l'objectif de la tâche + {"role": "user", "content": f"Veuillez générer un prompt visuel pour le contenu suivant :\n\n{user_input}"} +] +Intention 2 : le contenu System prend la version finale du system_prompt édité par l'utilisateur ; +Intention 3 : le contenu System prend la règle par défaut remplie en état désactivé ; +user_input est le texte original entré par l'utilisateur dans la zone input_text. + +· Preset System Prompt validé en pratique (figé dans le code) +python +SYSTEM_PROMPT_DEFAULT = """Vous êtes maintenant un assistant créant des prompts de dessin pour NanoBanana. +Vous devez traiter en fonction de mon contenu, l'image doit pouvoir expliquer ce dont parle ce passage, et faire comprendre à tous la structure globale et le sens général du texte. +Il peut y avoir des éléments similaires à des présentations PPT (par exemple : le coin supérieur gauche montre l'idée centrale, le coin inférieur droit montre les données). +Exigences de style de design : minimaliste, philosophie de design Apple (Apple Design Philosophy). +Contrainte : retournez uniquement le prompt en anglais utilisable par NanoBanana, sans aucune explication, préfixe ou texte superflu.""" + +· Contraintes d'appel LLM +Partage les mêmes LLM_BASE_URL, LLM_API_KEY, LLM_MODEL que le Bloc 2 ; +temperature=0.7 (pour garantir la créativité et l'adaptabilité du prompt) ; +max_tokens=200 (limiter la longueur de sortie, en adéquation avec la contrainte de prompt) ; +Utiliser strictement la structure de liste de messages Chat standard ci-dessus, interdire la concaténation de chaînes. + +· Contraintes forcées de sortie du prompt +Uniquement en anglais, pas de chinois ; +Doit inclure Apple Design Philosophy/Apple style + 1024x1024 ; +Longueur 50–200 caractères, validation dans le code ; +Pas d'explication supplémentaire, préfixe ou texte superflu, retourner uniquement le prompt lui-même. + +4. Règles de liaison des composants +Génération réussie : remplir le prompt dans la zone generation_prompt, activer generate_btn, intent_status ajoute « Prompt généré avec succès, modifiable avant génération d'image » ; +Échec de génération : indiquer la raison spécifique (comme échec d'appel API, longueur insuffisante), generate_btn reste désactivé, zone generation_prompt vide ; +Modification/vidage manuel de la zone generation_prompt par l'utilisateur : +Si vidé, generate_btn est automatiquement désactivé ; +Si non vide, generate_btn reste activé. + +5. Gestion des exceptions +Échec d'appel API : message convivial « Échec de génération du prompt : {message d'erreur spécifique} », pas de crash ; +Échec de validation du prompt : indiquer clairement la raison (comme « ne contient pas Apple style », « longueur de seulement 40 caractères »), permettre de réessayer ; +Échec de parsing de réponse : indiquer « Impossible d'analyser le résultat du LLM, veuillez réessayer ». + +6. Exigences de sortie +Code complet et exécutable, il suffit de remplacer LLM_API_KEY pour l'utiliser ; +Structure de code claire, commentaires complets, interface belle et épurée ; +Implémenter strictement la structure de liste de messages Chat standard, paramètres et logique d'exemple cohérents ; +Inclure la logique de validation de longueur et de contenu du prompt, messages d'erreur conviviaux. +``` + +Testez de la même manière avec le texte de la deuxième phase. + +Notez que le System Prompt prédéfini pour la génération de prompts de dessin est le suivant : + +> Vous êtes maintenant un assistant créant des prompts de dessin pour NanoBanana. +> Vous devez traiter en fonction de mon contenu, l'image doit pouvoir expliquer ce dont parle ce passage, et faire comprendre à tous la structure globale et le sens général du texte. +> Il peut y avoir des éléments similaires à des présentations PPT (par exemple : le coin supérieur gauche montre l'idée centrale, le coin inférieur droit montre les données). +> Exigences de style de design : minimaliste, philosophie de design Apple (Apple Design Philosophy). +> Contrainte : retournez uniquement le prompt en anglais utilisable par NanoBanana, sans aucune explication, préfixe ou texte superflu. + +Si vous souhaitez changer de template prédéfini, vous pouvez modifier le prompt précédent, ou le modifier directement dans Trae via le dialogue. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image53.png) + +Outre la modification du code sous-jacent, vous pouvez aussi éditer rapidement sur la page web. Par exemple, j'ai ajouté ici « ajoutez "Pic Prompt" au début », et on peut voir que le nouveau prompt généré inclut bien ce préfixe. Cette conception permet de modifier rapidement le System Prompt de génération de prompts, facilitant les changements de style. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image54.png) + +#### Phase 4 : Module de génération texte vers image / image vers image Nanobanana + +Enfin la dernière étape — sans intégrer le modèle de génération d'images, ce n'est pas un Agent complet ! + +```Bash +Bloc 4 : Module de génération texte vers image / image vers image Nanobanana (version finale) +1. Objectif de la tâche +Implémenter la logique du bouton « Générer l'image », appeler la véritable API Nanobanana, supporter texte vers image / image vers image, parser le Base64 et afficher l'image. + +2. Exigences de la stack technique +Basé sur Gradio 4.0.0+ Blocks ; +Dépendances : requests, pillow, base64, io, re ; +Code complet = Bloc 1+2+3 + ce module. + +3. Configuration API principale (figée et validée en pratique) +Configuration figée dans le code : +python +# Configuration API figée dans le code +NANOBANANA_API_URL = "https://api.zyai.online/v1/chat/completions" +NANOBANANA_MODEL = "gemini-2.5-flash-image" +NANOBANANA_API_KEY = "" # L'utilisateur remplace lui-même +Méthode d'authentification : Header Authorization: Bearer {NANOBANANA_API_KEY}. + +4. Exigences de prétraitement d'image (obligatoire) +Implémenter la fonction image_to_base64_data_uri (ref_image_path), logique principale : +Convertir l'image PIL en format PNG ; +Mise à l'échelle automatique en résolution 1024x1024 ; +Canal transparent converti en fond blanc ; +Encoder en Base64, format retourné : data:image/png;base64,... + +5. Règles de construction de la requête (suivre strictement la logique de branchement de la version pratique) +· Définition de la fonction principale +Implémenter la fonction generate_image (prompt, ref_image_path) : +Paramètres d'entrée : prompt (contenu de la zone generation_prompt), ref_image_path (chemin du fichier uploadé dans ref_image) ; +Retour : PIL Image (affichée dans result_image) ou message d'erreur. +· Branche logique 1 : texte vers image pur (ref_image_path vide) +python +messages = [{"role": "user", "content": prompt}] +· Branche logique 2 : image vers image (ref_image_path non vide) +python +# D'abord appeler la fonction de prétraitement d'image +image_base64 = image_to_base64_data_uri(ref_image_path) +messages = [{"role": "user","content": [{"type": "text", "text": prompt},{"type": "image_url", "image_url": {"url": image_base64}}]}] + +6. Exigences de parsing de réponse (doit être compatible avec deux formats) +Extraire l'image Base64 depuis choices[0].message.content, supporter : +Champ image_url du retour JSON structuré ; +Format Markdown ; +Extraire uniformément l'encodage Base64, décoder puis convertir en PIL Image pour le retour. + +7. Liaison des composants et gestion des exceptions +Génération réussie : afficher la PIL Image dans result_image, intent_status indique « Image générée avec succès » ; +Échec de génération/parsing/upload : afficher un message textuel clair dans intent_status (comme « Échec du parsing Base64 », « Délai d'attente de l'appel API dépassé »), pas de crash. + +8. Exigences de sortie +Code complet et exécutable, il suffit de remplacer LLM_API_KEY et NANOBANANA_API_KEY pour l'exécuter directement, flux complet utilisable, logique de branchement strictement conforme à la version pratique. +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image55.png) + +C'est vraiment passionnant ! Nous avons enfin réussi à générer la première image de cet Agent. Regardez attentivement l'image générée — elle correspond bien à notre texte et à notre prompt. Vous avez maintenant pratiquement implémenté votre propre Agent ! + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image56.png) + +Nous avons aussi ajouté la fonctionnalité image vers image : uploadez une image que vous aimez et l'IA s'en inspirera automatiquement pour le style. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image57.png) + +Il convient de mentionner que les prompts générés aux étapes précédentes sont également éditables sur la page web, et c'est le prompt au moment du clic final sur le bouton qui fait foi. Même si je remplace ici par « a cute cat », l'image finale générée ne sera qu'un mignon petit chat. + +## Chapitre 4 : Résumé + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image58.png) + +**Hourra ! C'est enfin terminé.** +Honnêtement, même moi j'ai poussé un soupir de soulagement en écrivant la dernière ligne, alors imaginez pour vous qui avez suivi jusqu'au bout. Réussir à exécuter ce flux complet en entier est déjà très impressionnant — cela prouve que vous avez vraiment mis les mains sur le clavier et accompli les choses étape par étape. Bravo ! + +En écrivant ce contenu, je me suis toujours demandé ce que nous devions laisser derrière nous. La réponse n'est ni le nom des modèles, ni les paramètres ou une approche fixe, mais plutôt de vous aider à développer progressivement un ressenti : quelles tâches peut-on confier en toute sécurité à l'IA pour la compréhension et la planification, et où avez-vous simplement besoin de décider de la direction. Une fois cette répartition des rôles établie, de nombreux flux de génération qui semblaient complexes commencent à devenir plus fluides. + +En y regardant en arrière, le chemin n'est pas si complexe. Réfléchissez clairement au problème que vous voulez résoudre, confiez les textes longs au modèle de langage pour les décomposer, puis transmettez l'intention visuelle organisée au modèle de dessin pour le rendu, et enfin encapsulez l'ensemble de ce flux dans votre propre petit assistant. À ce stade, vous ne faites plus qu'« utiliser un modèle » — vous construisez un système qui peut vous accompagner durablement dans votre travail. C'est exactement ce que ce tutoriel voulait vous transmettre avant tout. + +Mais vous avez déjà fait du excellent travail ! Si vous êtes arrivé jusqu'ici, vous maîtrisez probablement les bases du Vibe Coding. Accordez-vous une petite pause bien méritée ! + + diff --git a/docs/fr-fr/stage-2/frontend/modern-component-library/index.md b/docs/fr-fr/stage-2/frontend/modern-component-library/index.md new file mode 100644 index 0000000..6c73378 --- /dev/null +++ b/docs/fr-fr/stage-2/frontend/modern-component-library/index.md @@ -0,0 +1,465 @@ +# Mettre à jour votre interface avec une bibliothèque de composants moderne + +Dans les cours précédents, vous avez appris à utiliser des outils de conception pour créer des interfaces, à convertir des maquettes en code avec un IDE AI, et même à réaliser un projet frontend complet. Mais vous avez peut-être remarqué un problème : les boutons, formulaires et boîtes de dialogue écrits de zéro fonctionnent, mais semblent toujours manquer de quelque chose par rapport aux « produits professionnels » — styles pas assez uniformes, détails d'interaction pas assez fluides, et l'adaptation à différents écrans est un vrai casse-tête. + +C'est exactement le problème que les **bibliothèques de composants** résolvent. + +Une bibliothèque de composants est un ensemble d'éléments UI pré-conçus et pré-développés. Boutons, champs de saisie, menus déroulants, boîtes de dialogue, tableaux... tous ces éléments d'interface que vous utilisez à répétition dans n'importe quel produit sont déjà prêts dans la bibliothèque, testés et affinés par un grand nombre d'utilisateurs. Il vous suffit de les combiner comme des briques Lego pour construire rapidement des interfaces de niveau professionnel. + +## Ce que vous allez apprendre + +1. Comprendre ce qu'est une bibliothèque de composants frontend et pourquoi le développement moderne l'utilise presque systématiquement +2. Découvrir quatre bibliothèques de composants représentatives et comprendre leurs scénarios de prédilection +3. À travers trois scénarios pratiques (landing page, page produit, back-office), apprendre le Vibe Coding avec IDE AI + bibliothèque de composants +4. Apprendre à lire la documentation des bibliothèques de composants, trouver les composants appropriés et les utiliser correctement + +## 1. Pourquoi a-t-on besoin de bibliothèques de composants ? + +Imaginez que vous rénovez une maison. Vous pouvez fabriquer une chaise vous-même à partir de bois brut, mais l'approche la plus courante est d'en acheter une chez Ikea — design agréable, qualité stable, mode d'emploi clair, il suffit de l'assembler à la maison. + +La bibliothèque de composants, c'est le « Ikea » du développement frontend. Elle ne fournit pas des meubles, mais des éléments d'interface : + +| Écriture manuelle | Utilisation d'une bibliothèque de composants | +| :--- | :--- | +| Vous devez gérer vous-même les styles, interactions et animations | Prêt à l'emploi, styles et interactions déjà affinés | +| Les boutons de différentes pages peuvent avoir des apparences différentes | Style global unifié, cohérence automatique | +| L'adaptation mobile et tablette nécessite un travail supplémentaire | La plupart des bibliothèques intègrent le support responsive | +| L'accessibilité est souvent oubliée | Les bibliothèques professionnelles gèrent la navigation clavier, les lecteurs d'écran, etc. | +| Développement lent | Développement rapide, concentration sur la logique métier | + +En résumé : **les bibliothèques de composants vous permettent de consacrer votre temps à « quoi faire » plutôt qu'à « comment dessiner ».** + +### Voir pour croire : le même besoin, avec ou sans bibliothèque de composants + +La théorie seule n'est pas convaincante. Utilisons un besoin presque identique dans Trae, en spécifiant ou non une bibliothèque de composants, pour voir la différence. + +**Prompt 1 : Sans bibliothèque de composants** + +```text +Aidez-moi à créer une page de tableau de bord pour un assistant d'écriture AI, comprenant : +- Barre de titre supérieure et bouton d'export +- Quatre cartes statistiques affichant le nombre d'utilisateurs, d'utilisateurs actifs, de documents et de revenus, avec les tendances hausses/baisses +- Un graphique en courbes et un graphique en secteurs +- Tableau de liste d'utilisateurs avec pagination +- Barre latérale de navigation à gauche +``` + +Résultat dans Trae : + + + + +**Prompt 2 : Avec la bibliothèque de composants shadcn/ui** + +```text +Aidez-moi à créer une page de tableau de bord pour un assistant d'écriture AI, en utilisant la bibliothèque de composants shadcn/ui, comprenant : +- Barre de titre supérieure et bouton d'export +- Quatre cartes statistiques affichant le nombre d'utilisateurs, d'utilisateurs actifs, de documents et de revenus, avec les tendances hausses/baisses +- Un graphique en courbes et un graphique en secteurs +- Tableau de liste d'utilisateurs avec pagination +- Barre latérale de navigation à gauche +``` + +Résultat dans Trae : + + + + +Le même besoin, la seule différence étant l'ajout de `shadcn/ui + Tailwind CSS` au début du prompt. Le résultat généré par Trae est à un niveau complètement différent en termes de cohérence visuelle, de détails d'interaction et de finition globale. C'est la « mise à niveau gratuite » qu'apporte la bibliothèque de composants — il vous suffit d'ajouter un nom de bibliothèque de composants dans votre prompt. + +## 2. Découvrir quatre bibliothèques de composants clés + +Les bibliothèques de composants sont nombreuses (voir la liste complète en [Annexe](#annexe-apercu-de-plus-de-bibliotheques-de-composants)), mais il vous suffit d'abord de connaître ces quatre plus représentatives : + +| Bibliothèque | Framework | Positionnement en une phrase | Site officiel | +| :--- | :--- | :--- | :--- | +| [Ant Design](https://ant.design) | React | Produit par Ant Group, standard de facto pour les back-offices d'entreprise, couverture de composants extrêmement large | ant.design | +| [shadcn/ui](https://ui.shadcn.com) | React | Pas d'installation npm, copie directe du code dans votre projet, basé sur Tailwind CSS, liberté de personnalisation maximale | ui.shadcn.com | +| [HeroUI](https://heroui.com) (anciennement NextUI) | React | Styles par défaut élégants, animations fluides, idéal pour les landing pages et vitrines produits exigeantes visuellement | heroui.com | +| [Material UI](https://mui.com) | React | La bibliothèque de composants React la plus ancienne, implémente les guidelines Material Design de Google, écosystème le plus mature | mui.com | + +> Les utilisateurs de Vue ont également un choix riche : [Element Plus](https://element-plus.org) (la plus populaire en Chine), [Ant Design Vue](https://antdv.com), [Naive UI](https://www.naiveui.com) etc., voir [Annexe](#annexe-apercu-de-plus-de-bibliotheques-de-composants). + +Différentes bibliothèques excellent dans différents scénarios. Découvrons à travers trois scénarios de développement réels comment pratiquer le Vibe Coding avec IDE AI + bibliothèque de composants. + +Pour montrer les styles et caractéristiques de différentes bibliothèques, nous avons délibérément utilisé une bibliothèque différente dans chaque scénario. Mais attention : **c'est uniquement pour vous faire découvrir plusieurs approches**. En développement réel, vous pouvez tout à fait n'utiliser que celle que vous maîtrisez le mieux. Si vous aimez le style de shadcn/ui, vous pouvez l'utiliser pour des landing pages, des pages produit et des back-offices. Choisir une bibliothèque que vous trouvez belle et agréable à utiliser est plus important que tout le reste. + +## 3. Pratique 1 : Construire une landing page produit avec HeroUI + +**Scénario** : Vous avez créé un produit d'assistant d'écriture AI et avez besoin d'une belle landing page pour présenter les fonctionnalités du produit et attirer les inscriptions. La landing page doit avoir un fort impact visuel, des animations fluides et être belle sur mobile. + +**Pourquoi choisir HeroUI** : Les styles par défaut de HeroUI sont déjà élégants, avec des animations de transition fluides intégrées, parfaitement adaptés aux pages vitrines orientées utilisateur. + +### 3.1 Créer le projet + +```bash +# Créer le projet avec le CLI officiel HeroUI +npx create-heroui-app@latest ai-writer-landing +cd ai-writer-landing +npm install +``` + + + + +### 3.2 Générer la landing page avec l'IDE AI + +Ouvrez l'IDE AI (Cursor, Trae, etc.) et entrez dans le dialogue : + +```text +Aidez-moi à créer une landing page pour un assistant d'écriture AI, en utilisant la bibliothèque de composants HeroUI : + +**Structure de la page :** +1. Barre de navigation supérieure : Logo et nom du produit à gauche, trois liens « Fonctionnalités », « Tarifs », « À propos » à droite, plus un bouton « Commencer » +2. Section hero : Grand titre « L'IA devient votre partenaire d'écriture », sous-titre présentant la valeur du produit, deux boutons « Essai gratuit » et « Voir la démo », une capture d'écran du produit en dessous +3. Présentation des fonctionnalités : Trois cartes en colonnes, présentant respectivement « Continuation intelligente », « Ajustement de style », « Traduction multilingue », chaque carte avec icône, titre et description +4. Section tarifs : Trois cartes de prix (version gratuite, version pro, version équipe), la version pro mise en évidence comme recommandée +5. Appel à l'action en bas : Un slogan accrocheur avec un bouton d'inscription +6. Pied de page : Informations de copyright et liens vers les réseaux sociaux + +**Exigences de design :** +- Aspect moderne et professionnel +- Support du mode sombre +- Doit être beau sur mobile +``` + + + + +### 3.3 Composants clés utilisés par l'IA + +Dans le code généré par l'IA, vous verrez ces composants HeroUI : + +```jsx +import { + Navbar, NavbarBrand, NavbarContent, NavbarItem, + Button, + Card, CardHeader, CardBody, CardFooter, + Divider, + Link, + Chip +} from '@heroui/react' +``` + +Le rôle de chaque composant : + +| Composant | Usage | Position dans la landing page | +| :--- | :--- | :--- | +| `Navbar` | Barre de navigation supérieure | Tout en haut de la page, fixe | +| `Button` | Bouton, supporte plusieurs variantes et couleurs | Boutons CTA, boutons de navigation | +| `Card` | Conteneur de carte | Présentation des fonctionnalités, cartes de tarifs | +| `Chip` | Petite étiquette | Marqueurs « Recommandé », « Le plus populaire » | +| `Divider` | Ligne de séparation | Séparation visuelle entre les sections | + +### 3.4 Itération et optimisation + +La première version du code généré peut ne pas être entièrement satisfaisante. Continuez à dialoguer avec l'IA pour ajuster : + +```text +Aidez-moi à optimiser la landing page : + +1. Ajoutez un dégradé au grand titre, du bleu au violet +2. Les cartes de fonctionnalités doivent avoir un effet de lévitation au survol de la souris +3. La carte de prix de la version pro doit être mise en évidence, avec une bordure et une étiquette « Le plus populaire » +4. Sur mobile, la navigation doit devenir un menu hamburger (les trois barres horizontales) +``` + + + + +> **Le cœur du Vibe Coding** : vous n'avez pas besoin de mémoriser l'API de chaque composant. Il vous suffit de décrire l'effet souhaité en langage naturel, et l'IA trouvera les composants et la syntaxe appropriés. Si le résultat ne vous satisfait pas, continuez à itérer via le dialogue. + +## 4. Pratique 2 : Construire une page produit avec shadcn/ui + +**Scénario** : Votre assistant d'écriture AI a besoin d'une interface principale après connexion — une liste de documents à gauche, un éditeur à droite, et une barre d'outils en haut. C'est une page produit fonctionnelle nécessitant une UI hautement personnalisable. + +**Pourquoi choisir shadcn/ui** : shadcn/ui place le code des composants directement dans votre projet, vous pouvez modifier n'importe quel détail. Pour les interfaces produit nécessitant une personnalisation approfondie, ce modèle « propriété du code » est le plus flexible. + + + + +### 4.1 Créer le projet + +```bash +# Créer un projet Next.js +npx create-next-app@latest ai-writer-app --typescript --tailwind --app +cd ai-writer-app + +# Initialiser shadcn/ui +npx shadcn@latest init + +# Ajouter les composants selon les besoins (pas d'installation en bloc) +npx shadcn@latest add button card input sidebar sheet dialog +``` + +La particularité de shadcn/ui : à chaque `add` d'un composant, il copie le code source dans le répertoire `components/ui/` de votre projet. Vous pouvez ouvrir directement ces fichiers pour modifier les styles et le comportement. + +### 4.2 Générer l'interface produit avec l'IDE AI + +```text +Aidez-moi à créer l'interface principale d'un assistant d'écriture AI, en utilisant la bibliothèque de composants shadcn/ui : + +**Mise en page globale :** +- À gauche, une barre latérale rétractable d'environ 280px : + - En haut, un bouton « Nouveau document » + - En dessous, une liste de documents, chaque document affichant le titre et la date de dernière modification + - Clic droit sur un document pour renommer ou supprimer +- À droite, la zone d'édition principale, divisée en deux parties : + - En haut, une barre d'outils : édition du titre du document, affichage du compteur de mots, bouton « Continuation AI », menu déroulant « Exporter » + - En bas, la zone d'édition : un grand champ de saisie de texte occupant tout l'espace restant + +**Détails d'interaction :** +- Après un clic sur « Continuation AI », le bouton affiche un état de chargement, le texte généré par l'IA apparaît en bas de l'éditeur (effet machine à écrire, lettre par lettre) +- Sur mobile, la barre latérale devient un tiroir glissant depuis la gauche +- Le document actuellement sélectionné doit être mis en évidence +``` + + + + +### 4.3 Composants clés utilisés par l'IA + +```tsx +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Card, CardContent, CardHeader } from '@/components/ui/card' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@/components/ui/dropdown-menu' +import { + Sheet, + SheetContent, + SheetTrigger +} from '@/components/ui/sheet' +import { + Sidebar, + SidebarContent, + SidebarHeader +} from '@/components/ui/sidebar' +``` + +| Composant | Usage | Position dans la page produit | +| :--- | :--- | :--- | +| `Sidebar` | Barre latérale rétractable | Liste de documents à gauche | +| `Sheet` | Tiroir mobile | Remplacement de la barre latérale sur mobile | +| `DropdownMenu` | Menu déroulant | Bouton « Exporter », menu contextuel | +| `Dialog` | Boîte de dialogue | Confirmation de renommage, suppression | +| `Button` | Bouton, supporte variant et loading | Divers boutons d'action | +| `Input` | Champ de saisie | Édition du titre du document | + +### 4.4 Personnaliser les styles des composants + +L'avantage de shadcn/ui est que vous pouvez modifier directement le code source des composants. Par exemple, pour des boutons aux coins plus arrondis : + +```text +Aidez-moi à modifier components/ui/button.tsx, +changez le coin arrondi par défaut de tous les boutons de rounded-md à rounded-xl, +et ajoutez un effet d'ombre subtil à la variante primary +``` + +L'IA modifiera directement les fichiers de composants dans votre projet, au lieu de remplacer les styles du package npm — c'est l'avantage de « posséder le code » avec shadcn/ui. + + + + +## 5. Pratique 3 : Construire un back-office avec Ant Design + +**Scénario** : Après le lancement de votre assistant d'écriture AI, vous avez besoin d'un back-office pour consulter les données utilisateurs, gérer le contenu des documents et traiter les commandes payantes. Le cœur d'un système de back-office est la présentation des données et l'efficacité des opérations. + +**Pourquoi choisir Ant Design** : Ant Design a l'expérience la plus profonde dans le domaine des back-offices. Les composants métier comme les tableaux, formulaires et graphiques sont prêts à l'emploi, avec un grand nombre de modèles d'interaction de niveau entreprise intégrés (opérations par lot, filtrage avancé, export de données, etc.). + + + + +### 5.1 Créer le projet + +```bash +# Utiliser le scaffolding Ant Design Pro (mise en page, routage et permissions intégrés) +npx create-umi@latest ai-writer-admin +# Choisir le template Ant Design Pro +cd ai-writer-admin +npm install +``` + +Ou partir de zéro : + +```bash +npx create-react-app ai-writer-admin --template typescript +cd ai-writer-admin +npm install antd @ant-design/icons @ant-design/pro-components +``` + +### 5.2 Générer le back-office avec l'IDE AI + +```text +Aidez-moi à créer un back-office pour un assistant d'écriture AI, en utilisant la bibliothèque de composants Ant Design : + +**Mise en page globale :** +- À gauche, la barre de menus : Tableau de bord, Gestion des utilisateurs, Gestion des documents, Gestion des commandes, Paramètres système +- En haut, le fil d'Ariane + +**Page de gestion des utilisateurs :** +- En haut, quatre cartes statistiques : nombre total d'utilisateurs, nouvelles inscriptions aujourd'hui, utilisateurs actifs, utilisateurs payants +- Zone de recherche et filtrage : recherche par nom d'utilisateur, sélection de la plage de date d'inscription, filtrage par statut, avec boutons « Rechercher » et « Réinitialiser » +- Tableau des utilisateurs : + - Affiche avatar, nom d'utilisateur, email, date d'inscription, plan d'abonnement (étiquettes de couleurs différentes), statut, actions + - 20 éléments par page avec pagination + - Possibilité de sélection multiple pour désactivation ou export par lot + - Colonne d'actions : voir les détails, modifier, désactiver (confirmation requise avant désactivation) +- Un clic sur « Voir les détails » ouvre un tiroir latéral avec les informations détaillées et la liste des documents récents +``` + + + + +### 5.3 Composants clés utilisés par l'IA + +```tsx +import { PageContainer, ProLayout } from '@ant-design/pro-components' +import { ProTable } from '@ant-design/pro-components' +import { StatisticCard } from '@ant-design/pro-components' +import { + Button, Tag, Badge, Space, Drawer, + Popconfirm, message, Modal +} from 'antd' +import { + UserOutlined, SearchOutlined, ExportOutlined +} from '@ant-design/icons' +``` + +| Composant | Usage | Position dans le back-office | +| :--- | :--- | :--- | +| `ProLayout` | Framework de mise en page global du back-office | Squelette de la page (menu + zone de contenu) | +| `ProTable` | Tableau avancé avec recherche, pagination et paramètres de colonnes intégrés | Liste des utilisateurs, liste des documents, liste des commandes | +| `StatisticCard` | Carte de statistiques | Tableau de bord, aperçu en haut de page | +| `Tag` / `Badge` | Étiquettes de statut | Plans d'abonnement, statut utilisateur | +| `Drawer` | Tiroir latéral | Détails utilisateur, formulaire d'édition | +| `Popconfirm` | Confirmation en bulle | Actions dangereuses comme suppression, désactivation | + +### 5.4 Continuer l'itération : Ajouter le tableau de bord + +```text +Aidez-moi à créer une page de tableau de bord : + +1. En haut, quatre cartes statistiques : nombre total d'utilisateurs, nombre total de documents, appels API aujourd'hui, revenus mensuels, chaque carte affichant la valeur et la variation (hausse ou baisse) +2. Au milieu, deux graphiques : + - À gauche : graphique en courbes de la croissance des utilisateurs sur 7 jours + - À droite : graphique en secteurs de la répartition des plans d'abonnement +3. En bas : tableau du journal des opérations récentes, affichant l'heure, l'utilisateur, le type d'opération et les détails + +Utilisez les composants Ant Design pour la mise en page, les graphiques peuvent utiliser Ant Design Charts +``` + + + + +> **Astuce Vibe Coding pour le back-office** : La structure des pages de back-office est relativement fixe (tableau + recherche + modale), parfaitement adaptée à la génération par lot avec l'IA. Vous pouvez d'abord faire générer une page « Gestion des utilisateurs » comme template, puis dire « En vous référant à la structure de la page de gestion des utilisateurs, aidez-moi à générer la page de gestion des documents » — l'IA réutilisera le même modèle de mise en page. + +## 6. Apprendre à consulter la documentation : le « mode d'emploi » des bibliothèques de composants + +En Vibe Coding, l'IA écrira la plupart du code pour vous. Mais quand le résultat généré par l'IA n'est pas correct, ou que vous voulez ajuster le comportement d'un composant, **consulter la documentation** est la solution la plus rapide. + +Prenons Ant Design comme exemple. L'adresse de sa documentation est : `https://ant.design/components/overview-cn` + +Le processus standard pour consulter la documentation : + +1. **Clarifier le besoin** : par exemple « J'ai besoin que le tableau supporte la sélection de lignes » +2. **Rechercher dans la documentation** : chercher « Table » pour accéder à la page du composant tableau +3. **Consulter les exemples** : chaque composant a plusieurs exemples en ligne dans la documentation, trouvez l'exemple « sélectionnable » +4. **Copier le code** : copiez le code de l'exemple dans votre projet +5. **Consulter le tableau API** : trouvez la configuration complète de la propriété `rowSelection` en bas de page + +> Vous pouvez aussi envoyer directement le lien de la documentation à l'IDE AI : « Veuillez vous référer à l'API rowSelection de https://ant.design/components/table-cn pour ajouter la fonctionnalité de sélection multiple au tableau des utilisateurs ». Fournir le lien de la documentation à l'IA rendra le code généré plus précis. + +Tableau de référence rapide des adresses de documentation des bibliothèques : + +| Bibliothèque | Adresse de la documentation | +| :--- | :--- | +| Ant Design | `https://ant.design/components/overview-cn` | +| shadcn/ui | `https://ui.shadcn.com/docs/components` | +| HeroUI | `https://heroui.com/docs/components` | +| Material UI | `https://mui.com/material-ui/all-components/` | +| Element Plus | `https://element-plus.org/zh-CN/component/overview.html` | + +## 7. Résumé + +Les trois scénarios pratiques couvrent les besoins de développement frontend les plus courants : + +| Scénario | Bibliothèque recommandée | Caractéristique principale | +| :--- | :--- | :--- | +| Landing page / Page vitrine | HeroUI | Styles par défaut élégants, animations fluides, fort impact visuel | +| Page produit fonctionnelle | shadcn/ui | Code entièrement contrôlable, personnalisation approfondie flexible | +| Système de back-office | Ant Design | Composants métier riches, tableaux et formulaires prêts à l'emploi | + +Résumé du workflow Vibe Coding : + +1. Choisir la bibliothèque de composants appropriée selon le scénario +2. Décrire la structure de page et les interactions souhaitées avec l'IDE AI +3. L'IA génère le code initial, vous prévisualisez le résultat +4. Continuer à itérer et ajuster en langage naturel +5. En cas de problème de détail, consulter la documentation de la bibliothèque de composants + +### Exercices + +Choisissez l'un des scénarios suivants et réalisez-le de zéro avec IDE AI + bibliothèque de composants : + +1. Avec HeroUI, créez une landing page vitrine pour un projet précédent (comme les Portraits de Poudlard) +2. Avec shadcn/ui, construisez l'interface principale d'une application de notes (barre latérale + éditeur) +3. Avec Ant Design, construisez un simple back-office de gestion de contenu (liste d'articles + formulaire de création) + +--- + +## Annexe : Aperçu de plus de bibliothèques de composants + +Outre les quatre bibliothèques clés présentées dans le corps du texte, l'écosystème frontend propose de nombreuses autres excellentes bibliothèques. Voici une liste classée par framework pour faciliter votre choix en fonction des besoins du projet. + +### Écosystème Vue + +| Bibliothèque | Stars | Description | Scénarios d'utilisation | +| :--- | :--- | :--- | :--- | +| [Element Plus](https://element-plus.org) | ~27k | Bibliothèque de composants enterprise Vue 3 créée par l'équipe Ele.me, la plus utilisée en Chine, excellente documentation en chinois | Back-offices et systèmes de gestion | +| [Vuetify](https://vuetifyjs.com) | ~41k | Bibliothèque de composants Material Design pour Vue la plus populaire, 80+ composants, documentation complète | Projets au style Google Design | +| [Ant Design Vue](https://antdv.com) | ~21k | Bibliothèque de composants Vue 3 basée sur le système de design d'Ant, spécifications de design unifiées | Back-offices enterprise | +| [Naive UI](https://www.naiveui.com) | ~18k | Écrite en TypeScript, personnalisation de thème extrêmement flexible, sans dépendance à un préprocesseur CSS | Projets avec exigences de design uniques | +| [Quasar](https://quasar.dev) | ~27k | Un seul code pour construire des applications SPA, SSR, PWA, mobiles et desktop | Projets multi-plateformes | +| [Vant](https://vant-ui.github.io/vant) | ~24k | Bibliothèque de composants mobiles légère développée par l'équipe Youzan, couvrant les besoins courants du e-commerce | Pages H5 mobiles | +| [PrimeVue](https://primevue.org) | ~14k | 90+ composants, support de plusieurs thèmes (Material, Bootstrap, etc.) | Besoin de composants riches et multi-thèmes | +| [Arco Design Vue](https://arco.design/vue) | ~3k | Produit par ByteDance, haute qualité de composants, mode sombre intégré | Produits de back-office | +| [TDesign Vue Next](https://tdesign.tencent.com/vue-next) | ~2k | Produit par Tencent, langage de design unifié, couvrant les scénarios desktop courants | Écosystème Tencent ou projets enterprise | + +### Écosystème React + +| Bibliothèque | Stars | Description | Scénarios d'utilisation | +| :--- | :--- | :--- | :--- | +| [Material UI (MUI)](https://mui.com) | ~95k | Implémentation historique des guidelines Material Design de Google, composants les plus complets, écosystème le plus mature | Construction rapide d'applications enterprise | +| [Ant Design](https://ant.design) | ~94k | Produit par Ant Group, intègre de nombreux composants métier de haute qualité, position dominante dans la communauté des développeurs chinois | Back-offices enterprise | +| [shadcn/ui](https://ui.shadcn.com) | ~83k | Le code est copié dans le projet plutôt qu'installé via npm, basé sur Radix UI + Tailwind CSS, entièrement contrôlable | Projets nécessitant une personnalisation approfondie | +| [Chakra UI](https://chakra-ui.com) | ~39k | Centrée sur l'expérience développeur, API simple, support d'accessibilité intégré | Prototypage rapide | +| [Mantine](https://mantine.dev) | ~28k | 100+ composants et 50+ hooks, incluant sélecteur de dates, éditeur de texte riche et autres composants avancés | Solution complète prête à l'emploi | +| [Headless UI](https://headlessui.com) | ~27k | Bibliothèque de composants sans style officielle de Tailwind Labs, supporte React et Vue | À utiliser avec Tailwind CSS | +| [HeroUI](https://heroui.com) | ~24k | Basée sur Tailwind CSS + React Aria, styles par défaut élégants, animations fluides | Projets exigeants visuellement | +| [Radix UI](https://www.radix-ui.com) | ~17k | Bibliothèque de primitives de composants sans style, axée sur l'accessibilité et le comportement, base de shadcn/ui | Construire un système de design personnalisé | + +#### Écosystème d'extensions shadcn/ui + +Outre les bibliothèques de composants génériques ci-dessus, l'écosystème shadcn/ui a vu apparaître de nombreuses bibliothèques d'extensions basées sur sa philosophie, offrant des choix différenciés pour des scénarios spécifiques. Ces extensions adoptent également le modèle « copier le code dans le projet », donnant aux développeurs un contrôle total du code source. + +| Bibliothèque | Description | Scénarios d'utilisation | +| :--- | :--- | :--- | +| [Aceternity UI](https://ui.aceternity.com) | 200+ composants de qualité production, spécialisée dans les cartes lumineuses, dégradés de texte, globe 3D et autres composants visuels distinctifs | Landing pages de haute qualité, produits SaaS | +| [Tailark UI](https://tailark.com) | Collection de blocs de composants pour sites marketing, modules fréquents comme présentation produit, témoignages, boutons CTA | Landing pages marketing, sites produit | +| [UI Tripled](https://ui.tripled.work) | Composants d'interaction dynamique basés sur Framer Motion, modales, navigation, animations de cartes | Outils créatifs, portfolios personnels | +| [Neobrutalism UI](https://neobrutalism.dev) | Style néobrutaliste, lignes épaisses, contraste élevé, couleurs vives | Sites de marque personnalisés, projets créatifs | +| [REUI](https://reui.io) | 967+ modèles de combinaisons de composants pour scénarios métier réels | Back-offices enterprise, formulaires complexes | +| [Cult UI](https://cult-ui.com) | Finition interaction/visuelle plus poussée, tableaux de données, panneaux de filtrage et autres composants composites | Projets commerciaux de haute qualité | +| [Kibo UI](https://kibo-ui.com) | Composants métier avancés, sélecteur de couleurs, éditeur de texte riche, upload de fichiers | Back-offices, produits de type outils | +| [Kokonut UI](https://kokonutui.com) | 100+ composants + 7+ templates complets, style frais et minimaliste | Sites SaaS, blogs, e-commerce | +| [Commerce UI](https://ui.stackzero.co) | Spécialisée e-commerce, cartes produit, panier, formulaire de commande | Plateformes e-commerce | +| [shadcnblocks](https://shadcnblocks.com) | 1373 blocs UI + 13 templates complets, les ressources les plus complètes | Tous les scénarios | +| [Shoogle](https://shoogle.dev) | Plateforme d'agrégation et de recherche de l'écosystème shadcn/ui | Recherche rapide de ressources | +| [Discover All Shadcn](https://allshadcn.com) | Navigation agrégée de ressources | Recherche rapide de ressources | + +> **Pourquoi choisir les extensions shadcn/ui ?** Ces extensions héritent de la philosophie de « propriété du code » de shadcn/ui tout en offrant une personnalisation approfondie pour des scénarios spécifiques. À l'ère du Vibe Coding, elles vous permettent de trouver rapidement des composants correspondant à vos besoins de design, de sortir de l'homogénéisation des bibliothèques UI mainstream et de créer des produits plus différenciés. diff --git a/docs/fr-fr/stage-2/frontend/multi-product-ui/index.md b/docs/fr-fr/stage-2/frontend/multi-product-ui/index.md new file mode 100644 index 0000000..2bbd1e3 --- /dev/null +++ b/docs/fr-fr/stage-2/frontend/multi-product-ui/index.md @@ -0,0 +1,425 @@ +# Concevoir des pages et des boutons en référençant les guidelines UI + +Beaucoup de gens disent « Je voudrais que ma page ressemble davantage à Apple » ou « J'aimerais des boutons plus sophistiqués », mais quand il s'agit de passer à l'action, ils se heurtent souvent à une question : + +**Que faut-il référencer exactement ?** + +Copier des captures d'écran ne vous apprend qu'à « ressembler ou non ». Mais en ouvrant les guidelines de design d'Apple, Google, Microsoft et Atlassian, vous découvrirez que leur véritable force n'est pas le style visuel, mais la **manière dont ils expliquent clairement les problèmes de design** : ce qu'une page doit mettre en avant, comment hiérarchiser les boutons, comment mettre en évidence les actions — ces critères de jugement sont le cœur du sujet. + +> Référencer les guidelines de design n'a pas pour but de « ressembler à quelqu'un », mais d'apprendre comment les autres prennent des décisions. + +:::: info Pourquoi apprendre cela aujourd'hui encore +Les règles de design ont déjà été intégrées dans les modèles par l'entraînement, absorbées par défaut dans les outils de conception, et même assimilées par l'IA à partir de quelques captures d'écran. Mais il reste nécessaire de savoir d'où viennent ces règles et pourquoi elles sont ainsi définies. +:::: + +## Quelques citations originales pour mesurer l'écart + +Si vous pensiez que « les guidelines de design, c'est juste parler de style », lisez d'abord quelques citations officielles. + +Dans une équipe, on entend souvent dire des choses comme : + +- Fais un menu déroulant +- Mets un menu ici +- Ajoute quelques fonctionnalités dans la barre de menus +- Mets deux boutons ici, un pour confirmer et un pour annuler + +Cela semble correct, mais dans les guidelines des grandes entreprises, ces termes ne sont pas des concepts flous — ils sont décomposés de manière très précise. + +| Ce qu'on dit couramment | Citation officielle | En résumé | +| :--- | :--- | :--- | +| « Fais un menu » | Apple : [« A menu reveals its options... »](https://developer.apple.com/design/human-interface-guidelines/menus) | `Menu` sert à effectuer des actions | +| « Mets des fonctionnalités dans la barre de menus » | Apple : [« menu bar menus contain all the commands... »](https://developer.apple.com/design/human-interface-guidelines/menus) | C'est le menu de commandes de l'application en haut | +| « Fais un menu déroulant » | Apple : [« A pop-up list lets the user choose one option among several. »](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pop-up` sert à choisir une option dans une liste | +| « Fais aussi un menu déroulant » | Apple : [« A pull-down list is generally used for selecting commands in a specific context. »](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pull-down` sert à déclencher des commandes dans le contexte actuel | +| « Un menu peut aussi servir à filtrer » | Fluent : [« If you need to collect information from people, try a select, dropdown, or combobox instead. »](https://fluent2.microsoft.design/components/web/react/core/menu/usage) | `Menu` ne sert pas à sélectionner des valeurs | +| « Un menu peut servir de navigation » | Material : [« Menus should not be used as a primary method for navigation within an app. »](https://m1.material.io/components/menus.html) | `Menu` n'est pas une navigation principale | +| « Mets juste OK / Annuler sur les boutons » | Apple : [« Always use 'Cancel' to title a button that cancels the alert's action. »](https://developer.apple.com/design/human-interface-guidelines/alerts) | Le texte des boutons ne s'écrit pas au hasard | + +> Les citations du tableau sont toutes cliquables et renvoient vers les pages officielles correspondantes. + +C'est la chose qui frappe le plus quand on lit vraiment des guidelines de design pour la première fois : + +> Quand nous pensons discuter d'UI, la plupart du temps nous ne faisons que communiquer avec un tas de termes vagues. + +Apple ne dit pas simplement « fais un menu » ; elle continue à distinguer : + +- `menu` +- `menu bar menu` +- `pop-up button` +- `pull-down button` +- `context menu` + +Fluent ne dit pas simplement « menu déroulant » ; elle continue à distinguer : + +- `menu` +- `dropdown` +- `select` +- `combobox` + +C'est ça, la nécessité des guidelines de design. + +Ce n'est pas pour rendre les pages plus professionnelles, mais pour que l'équipe, lorsqu'elle discute d'UI, n'ait plus chacun une idée différente en tête. + +## Ce que vous allez apprendre + +1. Pourquoi il faut consulter les guidelines de design avant de concevoir des pages et des boutons +2. Quels contenus des guidelines d'Apple, Material, Fluent et Atlassian méritent le plus d'attention +3. Comment concevoir clairement la « hiérarchie des pages » et la « hiérarchie des boutons » +4. Comment faire en sorte que l'IA référence les guidelines des autres pour générer des pages et des boutons + +## 1. Pourquoi les guidelines de design vous aident à clarifier les pages + +Après avoir lu les citations ci-dessus, vous remarquerez un point essentiel : + +**Les guidelines de design ne sont pas la cerise sur le gâteau, elles servent d'abord à employer les bons termes.** + +Beaucoup de pages ne sont pas belles non pas parce que les couleurs ne sont pas assez sophistiquées, mais parce que la hiérarchie de l'information est chaotique. + +Beaucoup de boutons ne sont pas pratiques non pas parce que les coins arrondis sont mal choisis, mais parce que : + +- Il y a trop de boutons principaux, l'utilisateur ne sait pas lequel cliquer +- Les boutons dangereux et les boutons normaux se ressemblent +- Tous les boutons de la page se disputent l'attention +- Les styles et la sémantique des boutons sont incohérents d'une page à l'autre + +Les guidelines de design matures résolvent précisément ces problèmes. Elles définissent généralement : + +| Contenu de la guideline | Quel problème elle résout | +| :--- | :--- | +| **Hiérarchie des pages** | Que regarder en premier, ensuite, comment organiser l'information | +| **Fondements visuels** | Couleurs, espacements, typographie, coins arrondis, ombres — comment uniformiser | +| **Hiérarchie des boutons** | Comment distinguer les boutons principaux, secondaires, textuels et dangereux | +| **Règles d'états** | Comment afficher hover, focus, disabled, loading | +| **Sémantique d'interaction** | Quel bouton est « confirmer », lequel est « annuler », lequel est « plus d'actions » | + +Ainsi, ce que les guidelines de design fournissent véritablement, ce n'est pas un « habillage », mais un ensemble de **critères de jugement**. + +## 2. Que regarder en priorité dans les guidelines des grandes entreprises + +### 2.1 Référencer Apple : apprendre à « définir les choses assez finement » + +Ce qu'il y a de plus précieux chez Apple, ce n'est pas seulement la retenue visuelle, mais le fait qu'elle définit les concepts de manière très précise. + +Pour ce que beaucoup d'équilles appellent « menu » ou « menu déroulant », Apple va encore plus loin : + +- `menu` : un ensemble de commandes, d'options ou d'états +- `menu bar menu` : collection de commandes au niveau de l'application +- `pop-up button` : choisir une valeur +- `pull-down button` : déclencher une commande dans le contexte actuel +- `context menu` : actions courantes liées à l'objet ou à la tâche en cours + +Cette distinction est très importante, car elle affecte directement : + +- Ce composant sert-il à choisir une valeur ou à effectuer une action +- Appartient-il à une partie de la page ou au niveau de l'application +- Doit-il afficher en permanence la valeur sélectionnée ou s'ouvrir temporairement pour des commandes + +Quand vous commencez à penser à ce niveau de granularité, vos pages deviennent immédiatement beaucoup plus claires. + +### 2.2 Référencer Apple : apprendre la hiérarchie des pages et la retenue + +Les Apple Human Interface Guidelines sont particulièrement adaptées pour apprendre deux choses : + +- Comment établir une hiérarchie claire dans une page +- Comment les contrôles restent explicites sans voler la vedette + +Apple met l'accent sur `Hierarchy`, `Harmony`, `Consistency`. Cela signifie que la conception de la page doit répondre à : + +- Quelle est l'information la plus importante de la page actuelle +- Quelle est la tâche principale de l'utilisateur +- Quelle action doit être la plus visible, et quelle action doit s'effacer + +Si vous référencez Apple pour concevoir des pages, vous pouvez vous inspirer de : + +- Ne pas trop fragmenter l'information au-dessus de la ligne de flottaison, concentrez-vous d'abord sur le contenu essentiel +- Utiliser l'espace blanc, la taille de police et le regroupement pour établir l'ordre, plutôt qu'empiler des bordures +- Ne pas mettre tous les boutons en forte emphase, seules les actions clés doivent être les plus visibles + +### 2.3 Référencer Material : apprendre une structure de page claire + +Material Design est très adapté pour apprendre « comment une page organise les flux de tâches ». + +Beaucoup de ses composants et spécifications de mise en page ont pour cœur de vous aider à clarifier : + +- La page est-elle de type navigation ou exécution de tâche +- La page actuelle demande-t-elle à l'utilisateur de lire, de choisir ou de soumettre +- Dans une page, quels éléments doivent être stables et répétés, et quels éléments doivent répondre aux changements de contexte + +Si vous référencez Material pour concevoir des pages, vous pouvez vous inspirer de : + +- Des blocs de page clairs, avec des responsabilités de modules bien définies +- Une répartition claire entre navigation, zone de contenu et zone d'actions +- Des styles de boutons différents correspondant à des priorités d'action différentes + +### 2.4 Référencer Fluent : apprendre les frontières des composants et la hiérarchie des boutons + +Fluent 2 est très adapté aux back-offices, aux produits de type outils et aux systèmes de formulaires complexes. Son point le plus précieux est qu'il vous dit directement « ne mélangez pas les concepts ». + +Par exemple, il indique clairement : si vous devez « collect information », n'utilisez plus `menu`, mais envisagez plutôt `select`, `dropdown`, `combobox`. + +Cette phrase est très importante, car elle brise l'idée que beaucoup de gens se font que « c'est à peu près pareil ». + +Fluent 2 attache aussi beaucoup d'importance à : + +- La hiérarchie des actions +- Les frontières sémantiques des composants +- La clarté dans les scénarios d'information dense + +Si vous référencez Fluent pour concevoir des boutons, vous pouvez vous inspirer de : + +- `Primary button` pour l'action la plus importante de la zone +- `Secondary button` pour les actions de support +- Les boutons à faible emphase comme `Subtle`, `Transparent` pour les actions qui ne doivent pas perturber le flux principal +- Plus il y a de boutons dans une page, plus il faut contrôler la priorité visuelle + +### 2.5 Référencer Atlassian : apprendre à gérer systématiquement les pages et les boutons + +L'Atlassian Design System est particulièrement adapté quand « une équipe travaille sur beaucoup de pages ». Il met l'accent sur : + +- Les foundations comme base partagée +- Les tokens comme méthode d'unification des décisions visuelles +- Les components comme éléments d'interaction réutilisables + +Si vous référencez Atlassian pour les pages et les boutons, le plus précieux est : + +- Faire des règles uniformes pour la taille, la couleur, les coins arrondis et l'espacement des boutons +- Fixer le rythme de la mise en page +- Faire en sorte que des pages différentes, au contenu différent, partagent le même langage structurel + +## 3. Quand vous concevez des pages, quels points des guidelines devez-vous consulter + +Quand vous consultez un système de design, ne demandez pas d'abord « cette page est-elle jolie », mais posez d'abord les questions suivantes. + +### 3.1 Au premier coup d'œil, la priorité est-elle claire + +Une page comporte généralement au moins trois niveaux : + +- **Information principale** : le contenu le plus important de la page actuelle +- **Information secondaire** : contenu aidant à comprendre ou à compléter +- **Actions secondaires** : actions qui ne doivent pas perturber la tâche principale + +Si les trois niveaux ne sont pas séparés, la page sera « tout est important », ce qui équivaut à « rien n'est important ». + +### 3.2 La mise en page sert-elle la tâche plutôt qu'elle n'empile des modules + +En consultant les guidelines, prêtez attention à : + +- La zone de titre indique-t-elle clairement l'objectif de la page +- La zone de contenu principal est-elle organisée autour de la tâche +- Les boutons d'action sont-ils proches du contenu associé +- L'information secondaire est-elle atténuée + +### 3.3 Les actions dans la page ont-elles une priorité + +Beaucoup de pages montrent 6 boutons d'un coup, et chacun ressemble à un CTA — c'est typique d'une hiérarchie hors de contrôle. + +Une approche plus raisonnable : + +- Une zone ne comporte généralement qu'une seule action principale +- Les actions secondaires peuvent utiliser des styles à bordure, textuels ou plus discrets +- Les actions à risque ne doivent pas ressembler à l'action principale + +## 4. Quand vous concevez des boutons, quels points des guidelines devez-vous consulter + +Les boutons sont la partie la plus susceptible d'être « conçue à la va-vite », mais aussi celle qui révèle le mieux la maturité d'un système. + +### 4.1 D'abord la « sémantique » des boutons, puis le style + +Ne pensez pas d'abord « bouton bleu ou bouton noir », demandez-vous d'abord quel est le rôle de ce bouton. + +Les rôles courants des boutons peuvent être classés ainsi : + +| Type de bouton | Rôle | Stratégie de style courante | +| :--- | :--- | :--- | +| **Primary** | L'action la plus critique de la zone | Plein, contraste élevé, le plus visible | +| **Secondary** | Action de support | Bordure ou emphase d'un niveau inférieur | +| **Tertiary / Text** | Action faible | Texte ou faible présence visuelle | +| **Destructive** | Suppression, désactivation, vidage et autres actions à risque | Couleur d'avertissement ou style de risque explicite | +| **Icon button** | Action outil locale | Simple, proche du contexte | + +### 4.2 Pas trop de boutons Primary dans une page + +C'est le piège le plus courant pour les débutants. + +S'il y a 4 boutons principaux sur la page, cela revient à n'avoir aucun bouton principal. Le sens d'un bouton principal est précisément de « dire à l'utilisateur ce qu'il doit faire maintenant ». + +Vous pouvez vous inspirer de la pratique commune de nombreux systèmes de design : + +- Une zone principale ne conserve généralement qu'un seul bouton principal +- Annuler, retourner, fermer ne doivent généralement pas être au même niveau que le bouton de confirmation +- Les actions supplémentaires sont placées dans des boutons secondaires ou des menus + +### 4.3 Les boutons doivent pouvoir exprimer les changements d'état + +Les guidelines définissent généralement les états des boutons de manière très précise : + +- État par défaut +- État de survol +- État de focus +- État désactivé +- État de chargement +- État de danger + +C'est important, car un bouton n'est pas une image statique, mais l'un des contrôles les plus fréquemment activés par l'utilisateur. + +### 4.4 Le texte des boutons fait aussi partie du design + +Le texte des boutons n'est pas qu'une « question de rédaction », il influence directement la compréhension de l'utilisateur. + +Par exemple : + +- `Enregistrer` +- `Enregistrer les modifications` +- `Publier maintenant` +- `Supprimer le projet` +- `Déplacer vers la corbeille` + +Ces textes transmettent des attentes psychologiques très différentes. Les guidelines matures exigent généralement que les labels des boutons expriment clairement l'action, et non utilisent des termes vagues. + +## 5. Une checklist très pratique pour la conception de pages et de boutons + +Quand vous concevez une page vous-même, vous pouvez passer rapidement en revue cette checklist : + +### Checklist page + +- Le titre de la page indique-t-il clairement la tâche en cours +- L'information la plus importante au-dessus de la ligne de flottaison est-elle visible d'un coup d'œil +- La page est-elle organisée selon le flux de tâches, et non selon ce qui vous vient à l'esprit +- Une seule zone ne comporte-t-elle qu'une seule action principale +- Le contenu secondaire est-il atténué de manière appropriée + +### Checklist boutons + +- Ce bouton est-il une action principale ou secondaire +- Pourquoi mérite-t-il d'être plus visible que les autres +- Y a-t-il trop de boutons principaux dans la page +- Les actions dangereuses sont-elles clairement identifiées +- Le texte du bouton est-il suffisamment précis + +## 6. Comment utiliser l'IA en référençant les guidelines des autres pour concevoir des pages + +Cette section est la plus pratique. + +Beaucoup de gens, quand ils demandent à l'IA de concevoir une page, se contentent de dire : + +```md +Aidez-moi à faire une page de paramètres, un peu plus sophistiquée, style Apple +``` + +Ce type de prompt est trop vague, et l'IA ne peut généralement imiter que « fond blanc, coins arrondis, ombres ». + +Pour les débutants, l'approche la plus pratique n'est pas de résumer vous-même un long texte, mais de coller directement à l'IA les **phrases clés du texte officiel des guidelines**. + +Cette approche a deux avantages : + +- Vous n'avez pas besoin de « traduire » vous-même la pensée de design +- L'IA comprend plus facilement la page et les boutons selon les définitions officielles + +### 6.1 Exemple 1 : Faire concevoir par l'IA une page de paramètres en référençant Apple + +Trouvez d'abord une citation d'Apple : + +> [« Establish a clear visual hierarchy... »](https://developer.apple.com/design/human-interface-guidelines/) + +Vous pouvez coller directement ceci à l'IA : + +```md +Référencez cette phrase des Apple Human Interface Guidelines : +"Establish a clear visual hierarchy..." + +Aidez-moi à concevoir une page de paramètres de sécurité du compte. +La hiérarchie de la page doit être claire, les informations importantes en premier, les groupes bien ordonnés. +``` + +Le point clé de cette rédaction : vous n'avez pas besoin d'expliquer trop de choses vous-même, collez simplement les propres mots d'Apple. + +### 6.2 Exemple 2 : Faire concevoir par l'IA les boutons d'un back-office en référençant Fluent + +Trouvez d'abord une citation de Fluent : + +> [« Only use one primary button in a layout... »](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +Vous pouvez coller directement ceci à l'IA : + +```md +Référencez cette phrase de Fluent 2 : +"Only use one primary button in a layout..." + +Aidez-moi à concevoir les boutons d'un back-office de gestion d'équipe. +Le bouton d'ajout de membre doit être le plus visible, les boutons d'export, de filtrage et d'actions supplémentaires plus discrets, le bouton de suppression mis en évidence séparément. +``` + +Cette phrase est particulièrement adaptée aux débutants, car elle dit directement à l'IA : ne pas mettre trop de boutons principaux dans une zone. + +### 6.3 Exemple 3 : Faire concevoir par l'IA en référençant simultanément les guidelines de page et de boutons + +Vous pouvez aussi coller deux citations à la fois, pour que l'IA référence à la fois la page et les boutons : + +> Apple : [« Establish a clear visual hierarchy... »](https://developer.apple.com/design/human-interface-guidelines/) +> +> Fluent : [« Only use one primary button in a layout... »](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +Puis écrivez directement : + +```md +Référencez les deux phrases de guidelines de design suivantes : +Apple : "Establish a clear visual hierarchy..." +Fluent : "Only use one primary button in a layout..." + +Aidez-moi à concevoir une page de détail de projet. +La page contient la présentation du projet, les membres, l'activité récente et l'accès aux paramètres. +La hiérarchie de la page doit être claire, ne conserver qu'un seul bouton principal, les autres boutons plus discrets. +``` + +Cette approche est particulièrement adaptée aux débutants, car il vous suffit de savoir copier le texte officiel et d'ajouter deux phrases sur vos besoins. + +## 7. Comment utiliser l'IA en référençant les guidelines de boutons pour générer directement des boutons + +Si vous voulez d'abord faire des boutons, vous pouvez aussi coller directement le texte officiel des guidelines de boutons. + +Par exemple, la définition du bouton par Atlassian est très courte : + +> [« A button triggers an event or action. »](https://atlassian.design/components/button/) + +Vous pouvez demander ceci à l'IA : + +```md +Référencez cette phrase d'Atlassian : +"A button triggers an event or action." + +Aidez-moi à concevoir un ensemble de styles de boutons pour un back-office. +Je veux un bouton principal, un bouton secondaire, un bouton de suppression, et dites-moi respectivement où les utiliser. +``` + +Ce type de prompt est particulièrement adapté aux débutants — c'est essentiellement « coller le texte officiel + exprimer ses besoins ». + +## 8. Résumé + +Référencer les guidelines de design pour concevoir des pages et des boutons, ce n'est pas « ressembler à quelqu'un », mais apprendre les choses suivantes : + +1. Organiser les pages avec une hiérarchie, plutôt qu'empiler du contenu +2. Exprimer la priorité des actions avec des niveaux de boutons, plutôt que de rendre tous les boutons également voyants +3. Guider le design avec les définitions, les frontières et les critères de jugement des guidelines de design +4. Quand l'IA référence les guidelines des autres, elle référence les « principes et structures », et non seulement l'habillage + +Quand vous utilisez les guidelines de cette manière, vous ne référenciez pas seulement un style, mais une méthode de pensée de design mature. + +--- + +## Références + +Les liens suivants proviennent tous de systèmes de design officiels ou de la documentation officielle : + +- Apple Human Interface Guidelines : [Overview](https://developer.apple.com/design/human-interface-guidelines/) +- Apple Human Interface Guidelines : [Menus](https://developer.apple.com/design/human-interface-guidelines/menus) +- Apple Human Interface Guidelines : [Alerts](https://developer.apple.com/design/human-interface-guidelines/alerts) +- Apple Human Interface Guidelines : [Buttons](https://developer.apple.com/design/human-interface-guidelines/buttons) +- Apple Archive : [How Menus Work](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/HowMenusWork.html) +- Apple Archive : [Managing Pop-Up Buttons and Pull-Down Lists](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) +- Material Design : [Buttons overview](https://m3.material.io/components/buttons/overview) +- Material Design : [Menus](https://m1.material.io/components/menus.html) +- Microsoft Fluent 2 : [Start designing](https://fluent2.microsoft.design/get-started/design) +- Microsoft Fluent 2 : [Menu usage](https://fluent2.microsoft.design/components/web/react/core/menu/usage) +- Microsoft Fluent 2 : [Button usage](https://fluent2.microsoft.design/components/web/react/core/button/usage) +- Atlassian Design System : [Foundations](https://atlassian.design/foundations/) +- Atlassian Design System : [Button](https://atlassian.design/components/button/) diff --git a/docs/fr-fr/stage-2/frontend/ui-design/index.md b/docs/fr-fr/stage-2/frontend/ui-design/index.md new file mode 100644 index 0000000..a4ba9f0 --- /dev/null +++ b/docs/fr-fr/stage-2/frontend/ui-design/index.md @@ -0,0 +1,3 @@ +# Construire votre première application moderne - Conception UI + +> Ce chapitre est en cours de rédaction, restez à l'écoute... diff --git a/docs/fr-fr/stage-2/index.md b/docs/fr-fr/stage-2/index.md index e43980d..787620d 100644 --- a/docs/fr-fr/stage-2/index.md +++ b/docs/fr-fr/stage-2/index.md @@ -1,115 +1,182 @@ -# Développement Full-Stack +# Développement Junior-Intermédiaire -Bienvenue à l'étape **Développement Full-Stack** ! Ici, vous approfondirez le développement full-stack, maîtrisant la componentisation frontend, la conception de bases de données, le développement d'API backend et le déploiement. +Bienvenue à l'étape **Développement Junior-Intermédiaire** ! Ici, vous approfondirez le développement full-stack, maîtrisant la componentisation frontend, la conception de bases de données, le développement d'API backend et le déploiement. ## Ce que vous allez apprendre ### Développement Frontend -Maîtriser le développement frontend moderne et apprendre à utiliser des bibliothèques de composants et des outils de conception : +Maîtriser le développement frontend moderne, apprendre à utiliser des bibliothèques de composants et des outils de conception : + + + + - -### Backend et Full-Stack +### Développement Backend Apprendre la conception d'API, la gestion de bases de données et les stratégies de déploiement d'applications : + - - - + + +### Projets principaux -### Devoirs +Les chapitres précédents consistent à apprendre les « pièces », les projets principaux consistent à apprendre « comment assembler les pièces en un produit fonctionnel, démontrable et déployable ». + +Il est recommandé de suivre l'ordre **Projet 1 -> Projet 2** : + +- **Projet 1** vous guide d'abord à travers la chaîne principale la plus courante des SaaS modernes : connexion, génération, base de données, paiement, console d'administration. +- **Projet 2** vous plonge ensuite dans un scénario plus proche d'un système métier : rôles et permissions, banque de questions, examens, soumissions, console d'administration. + +```mermaid +flowchart LR + A["Pages et composants frontend"] --> B["Base de données et interfaces"] + B --> C["Projet 1
SaaS de génération de copywriting"] + C --> D["Paiement / Déploiement / Gestion backend"] + D --> E["Projet 2
Système d'examen en ligne"] + E --> F["Portfolio full-stack complet"] +``` + +Si vous ne savez pas par lequel commencer, vous pouvez vous référer à ce tableau comparatif : + +| Projet | Compétences clés pratiquées | Pour qui | Livrable final | +|------|------|------|------| +| Projet 1 : Site de génération de copywriting | Structure de page SaaS, connexion utilisateur, génération IA, paiement Stripe, gestion backend | Ceux qui créent leur premier site commercial complet | Un prototype SaaS avec inscription, génération, paiement et gestion | +| Projet 2 : Système d'examen et de gestion en ligne | Rôles et permissions, modélisation de banque de questions, flux d'examen, soumissions, correction et statistiques | Ceux qui veulent vraiment réaliser un « système métier » complet | Une plateforme d'examen avec un côté étudiant et un côté administrateur | + +Quel que soit le projet choisi, il est recommandé de préparer au moins ces 3 livrables : + +- Un dépôt de projet fonctionnel +- Un lien de démonstration accessible +- Un README et une vidéo de démonstration -Consolider vos compétences de développement full-stack à travers des projets pratiques : +Si vous avez déjà terminé les deux projets principaux ci-dessus, ou si vous souhaitez construire votre portfolio selon votre propre direction technique, vous pouvez choisir un sujet approfondi parmi ces projets optionnels : + + + + + + + + + ### Extension des capacités IA + - - ## Pour qui c'est - Développeurs avec une certaine base de programmation qui veulent apprendre systématiquement le développement full-stack @@ -119,7 +186,7 @@ Consolider vos compétences de développement full-stack à travers des projets ## Prérequis -- Compléter l'étape "Débutant et prototype de produit", ou avoir des connaissances de base équivalentes +- Avoir complété l'étape « Débutant et prototype de produit », ou avoir des connaissances de base équivalentes - Comprendre les concepts de base de HTML/CSS/JavaScript - Avoir des connaissances préliminaires sur les outils de programmation IA diff --git a/docs/ja-jp/stage-2/ai-capabilities/dify-knowledge-base/index.md b/docs/ja-jp/stage-2/ai-capabilities/dify-knowledge-base/index.md new file mode 100644 index 0000000..0e5458a --- /dev/null +++ b/docs/ja-jp/stage-2/ai-capabilities/dify-knowledge-base/index.md @@ -0,0 +1,1044 @@ +# Dify 入門とナレッジベース統合 + +# 前回のレッスンの振り返り + +これまでのレッスンでは、AI プログラミング、プロンプトエンジニアリング、AI 画像生成の基礎知識をグループに分けて学びました。これらの内容を通じて、異なる大規模言語モデル(LLM、Large Language Model)や生成モデルの能力の境界について初步的な理解を深めました。 + +前回のレッスンの内容を振り返るために、以下の質問について考えてみましょう。 + +1. AI プログラミングとは何か?AI プログラミングツール(例:[z.ai](http://z.ai))を使ってウェブページを作成するにはどうすればよいか? +2. 大規模言語モデルとは何か?プロンプトエンジニアリングとコンテキストエンジニアリングとは何か?複雑なプロンプトはどのように書くべきか? +3. テキスト、AI Coding、画像生成の3つの異なる方向において、モデルの能力の強弱はそれぞれどこに現れているか? +4. API とは何か?[z.ai](http://z.ai) からサードパーティ API に接続するにはどうすればよいか? + +どれか一つでも疑問が残る場合は、前回のレッスンの資料を見直すか、WeChat の学習グループで質問してください。 + +今回のレッスンでは、シンプルな AI テキスト・画像ツールから、企業の業務実装に近いワークフロー構築プラットフォームへと進みます。チャットボットから AI エージェント、AI ワークフローへと発展させ、API を使ってインタラクティブな「インテリジェント」ボットページを作ります。 + +操作中に理解しにくいステップに遭遇しても心配しないでください。現在の操作画面をスクリーンショットして大規模モデルに送信し質問することをお勧めします。現在の大規模モデルは、一般的な質問の大部分に回答できます。 + +質問しても解決できない場合は、思い切って操作を試してみてください。間違いを恐れる必要はありません。すべての試行は学習と進歩の機会です。実践を重ねることで、ますます上達し、操作もよりスムーズになります。 + +# このレッスンで学ぶこと + +1. なぜチャットボットからエージェントや Workflow のオーケストレーションへと移行する必要があるのか。 +2. エージェントやワークフロー開発プラットフォームとは何か。AI の能力を SOP 化し、オーケストレーション可能にする方法。 +3. Dify とは何か。LLM アプリケーション向けのこのオープンソースプラットフォームを使って、特にナレッジベース Q&A ボットを迅速に構築する方法。 +4. RAG の実装方法とその価値。なぜ検索強化生成(Retrieval-Augmented Generation)が必要なのか。 +5. Dify と AI IDE Trae(`Extra Knowledge 4 - What is AI IDE and Trae`)をゼロから使いこなす方法。エージェントやワークフローの構築、そして Dify API を使ったフロントエンドチャットボットウェブアプリケーションの作成。 + +- Dify の基本的な使用原理、エージェントやワークフローの作成方法、API 呼び出し方法 +- AI IDE の使用方法と AI IDE でのプログラミング +- チャット可能なフロントエンドウェブエージェントアプリケーション + +# 1. チャットからエージェントへ + +前の段階では、プロンプトを使って大規模モデルにロールを演じさせたり、テキストを生成させたり、シンプルなコードを書かせたりする方法を学びました。しかし、よく考えると一つの問題に気づくでしょう。チャットボット自体は何も実行できないのです。 + +「注文の確認方法は?」と聞かれれば答えることはできますが、実際にデータベースにアクセスして該当する数値を調べることはできません。週報に何を含めるべきかを説明することはできますが、プロジェクトデータを自動で集計してメールを送信することはできません。この「言うだけでやらない」限界により、純粋なチャット式 AI は業務プロセスに真に組み込むことが困難です。 + +AI をチャットパートナーからデジタル従業員にレベルアップさせるには、3つのコア能力を与える必要があります。 + +1. 専門知識——製品ドキュメント、顧客情報、社内制度を読んで理解させる +2. ツール呼び出し(プラグインとも呼ばれます)——データベースを操作し、API を呼び出せるようにする +3. 構造化実行——あらかじめ設定されたロジックに従って段階的にタスクを完了させ、自由な発想に任せない + +これが AI エージェント(AI Agent)の原型です。目標、知識、ツール、実行パスを備えた自動化ユニットです。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image1.png) + +> 注意:現在の業界で言及される「シンプル版のエージェント」は、主に LLM + ツール + ナレッジベースの組み合わせによる拡張型アプリケーションを指しており、自律的に計画を立てるエージェントを意味するものではありません。シンプルなエージェントは真の推論や長期計画能力を持っていませんが、大量のエンタープライズレベルの自動化シナリオを支えるには十分です。真の自律計画と行動能力を持つエージェントについては、後の章で詳しく説明します。 + +## 1.1 最もシンプルなエージェント:ナレッジベースベースの Q&A ボット + +エージェントが持つべき複数のコア能力が明確になった後、一つの問いが浮かびます。その中のたった一つの最もシンプルな機能を実装するだけで、本当に使える基礎的なエージェントを構築できるのでしょうか?答えは「はい」です。 + +実際、多くの実際の業務シナリオにおいて、ユーザーのコアニーズは AI に複雑な操作(API の呼び出しやシステム間の連携など)を自動実行させることではなく、企業独自の資料に基づいた正確で信頼性の高い Q&A サポートです。これはまさに、エージェントの3つのコア能力のうち、最初の「専門知識サービス能力」に対応します。したがって、最もシンプルでありながら最も広く応用されているエージェントの形態である「ナレッジベースベースの Q&A ボット」を導入できます。 + +これはまだツール呼び出しや自律計画の能力を持っていませんが、重要なブレイクスルーは、大規模モデルの回答を無根拠な生成ではなく、確かな裏付けに基づかせる点にあります。どのように?その鍵となる課題——企業内に大量のドキュメントナレッジがあり、何千何万ページものドキュメントが存在する時、モデルはどうやって各ラウンドの対話で現在の質問に最も関連する内容を素早く見つけるのか——を解決することです。 + +ここでの解決策が、検索強化生成(Retrieval-Augmented Generation, RAG)です。 + +RAG の基本的な考え方は、ユーザーが質問した時に、システムがまず企業のナレッジベースから質問の意味に最も関連する複数のテキスト断片(例:製品マニュアルのある段落、HR 制度のある条項)を検索し、これらの断片をコンテキストとして大規模モデルの入力に「注入」し、実際の資料に基づいた回答の生成を促すというものです。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image2.png) + +画像出典:[https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag](https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag) + +これにより、モデルの回答はもはや訓練データ中の一般化された知識に依存するのではなく、企業が提供する信頼性の高い情報に固定されます。RAG の目標は、このような外部知識の動的注入を通じて、回答の真実性、正確性、一貫性を大幅に向上させることです。回答を「キャラクター設定に合わせる」ことも可能です。例えば、カスタマーサポートのトーンや技術ドキュメントのスタイルで回答させることができます。 + +実際の業務では、この技術は特に重要です。大規模モデルはしばしば「ハルシネーション(幻覚)」を起こすからです。例えば、CFO やコンサルタントとしてある期間の具体的なデータを尋ねた場合、モデルが日付や出来事をでっち上げる可能性があります。RAG を導入することで、回答の制御性と信頼性が大幅に向上します。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image3.png) + +画像出典:[https://www.databricks.com/glossary/retrieval-augmented-generation-rag](https://www.databricks.com/glossary/retrieval-augmented-generation-rag) + +今回のレッスンの実践パートでは、人気の AI ワークフロープラットフォームである Dify を使って、ナレッジベースベースの Q&A ボットを構築します。製品マニュアル、社内制度、プロジェクトドキュメント、研究論文、ナレッジベース記事、さらには個人のメモ集など、様々なタイプの専用資料を簡単にナレッジベースとして構築できます。 + +構築完了後、様々な質問をしてその能力をテストできます。例えば: + +- 「製品 A の最新バージョンの主な機能アップデートは何か?」 +- 「従業員マニュアルに基づいて、今年の年次休暇制度はどのように規定されているか?」 +- 「XX プロジェクトにおいて、技術的課題 'XXX' はどのように解決されたか?」 +- 「この論文で述べられているコアの研究方法は何か?」 + +RAG 技術がどのように静的で散在する文書資料を、高精度な Q&A サポートを提供するインテリジェントナレッジベースに変換するかを、実際に体験できます。 + +## 1.2 チャットエージェントからワークフローへ + +しかし、ナレッジベースやプラグイン呼び出し機能を追加した「拡張型エージェント」であっても、より複雑な業務プロセスに直面するとまだ力不足です。 + +次のようなユーザーリクエストを想像してください。「新しくリリースした SaaS 製品の最近の機能アップデートは何?顧客向けのブリーフィングにまとめてくれる?」 + +このリクエストはシンプルに見えますが、背後には複数の連携ステップが必要です。まず内部の製品ドキュメントや Notion ナレッジベースから直近1ヶ月の機能リリース記録を検索し、次に顧客向けの主要機能をフィルタリングし、さらに大規模モデルを使って技術的な説明を顧客に分かりやすい言葉に変換し、最後に生成されたコンテンツをマーケティングチームのメールに送信するか、Google Docs テンプレートに保存します。 + +単一の大規模言語モデルに自由に推論させようとすると、すべてのプロセスを一度の対話で実現できるかどうかはともかく、重要な情報の見落とし、内部用語と顧客向け用語の混同、構造化されていない出力などの問題が生じやすいです。さらに重要なのは、企業に必要なのは監査可能で、再利用可能で、モニタリング可能な標準化された実行パスであり、毎回モデルの即興に頼ることではありません。モニタリングと再現性は企業にとって極めて重要であり、予期せぬ結果は予期せぬ深刻な損失をもたらす可能性があります。 + +これが、より高度な AI アプリケーションパラダイムである **AI ワークフロー(AI Workflow)** の導入につながります。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image4.png) + +ワークフローとは、複雑なタスクを複数の順序付けられ、設定可能で、自動実行可能なサブステップに分解し、ビジュアルまたはコードの方法でそれらの間の論理関係(条件分岐、ループ、並列実行など)をオーケストレーションすることです。AI 能力の SOP 化(標準化された操作プロセス)とは、AI を使ってあるタスクを完了する経験を、再利用可能なテンプレートとして固定することを意味します。 + +このアプローチは複数の価値をもたらします。非技術者(プロダクトマネージャーや運営担当者)はドラッグ&ドロップで AI アプリケーションを迅速に構築できます。開発者は RAG 検索、LLM 呼び出し、API ツールなどを標準ノードとしてカプセル化し、異なる業務シナリオで再利用できます。プロセス全体が追跡、デバッグ、継続的な最適化が可能で、企業の安定性とコンプライアンスの要件を満たします。 + +AI ワークフローの利用者層は非常に幅広いです。プロダクトマネージャーはコードを書かずに完全なユーザーインタラクションパスを設計できます。運営担当者はカスタマーサポートボット、コンテンツジェネレーター、通知システムを迅速に構築できます。開発者やアルゴリズムエンジニアはコアとなる機能モジュールをモジュール化してフロントエンドから呼び出せるようにできます。起業家や独立開発者も、極めて低いコストで AI 製品の MVP を検証でき、数日でデータ照会、コンテンツ生成、アクション実行を含む完全なプロトタイプをリリースできます。 + +また、AI ワークフローは通常、中間表現(Intermediate Representation)で記述できることにも注目してください。ワークフロープラットフォームごとに具体的な表現方法は異なりますが、多くは構造化ファイル(JSON、YAML など)を使用してノードの種類、入出力、実行ロジックを定義しており、その構造は以下の図に似ています。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image5.png) + +端的に言えば、エージェントが AI を「おしゃべりから作業できるように」したとすれば、ワークフローは AI を「たまに一つのことをできる」から「安定して、信頼性高く、大規模に一連の作業を完了できるように」引き上げたものです。続く実践では、Dify プラットフォームを使って完全な AI ワークフローを構築し、アイデアから動くアプリケーションまでの全過程を体験します。 + +## 1.3 代表的なエージェント / ワークフロープラットフォーム + +生成 AI 技術の急速な発展に伴い、開発者やビジネス担当者がエージェントや自動化プロセスを迅速に構築できるよう、プログラミングの複雑な詳細に深入りすることを避けるため、ローコードさらにはノーコードのエージェントおよびワークフロープラットフォームが次々と登場しました。 + +まず明確にしておきたいのは、ローコードプラットフォームとは、ビジュアルなドラッグ&ドロップコンポーネント、あらかじめ用意されたビジネスロジックテンプレート、グラフィカルな設定ルールなどを通じて、手動でのコーディング作業を大幅に削減する開発ツールです。その核心は、ビジュアル設定とノードベースのドラッグ操作でコードを直接書く方法を置き換えることにあり、一定の技術力を持つ開発者を反復作業から解放するだけでなく、業務ロジックに精通した非技術者もアプリケーション構築に参加できるようにします。本質的には、開発効率とシナリオの柔軟性のバランスを取る架け橋です。 + +このようなローコード/ノーコードエージェントプラットフォームの際立った価値は、AI アプリケーションの開発ハードルを大幅に下げることです。以前はチームで数週間かかっていた——要件整理、コード開発、テスト、デプロイ——AI エージェント(カスタマーサポート Q&A ボットやデータ処理アシスタントなど)が、プラットフォームが提供するビジュアルツールにより、「アイデアからリリースまで」の期間を数時間に短縮できます。 + +現在市場にある主要なローコード AI ワークフロープラットフォームは以下の通りです。 + +| プラットフォーム | 特徴 | 適用シナリオ | +| --------------------------------------------- | -------------------------------------------------- | -------------------------------------- | +| Dify | オープンソース、ナレッジベース RAG サポート、LLM オーケストレーション、API 出力、中国語対応 | エンタープライズナレッジベース Q&A、カスタマイズ Agent、API サービス | +| Coze(字節跳動) | 国内利用可能、Douyin/Feishu エコシステム統合、豊富なプラグイン | ソーシャルボット、国内ミニプログラム統合 | +| n8n | 汎用自動化ツール、AI ノードサポート、API オーケストレーションに注力 | クロスシステムデータ同期、AI + 従来 SaaS 自動化 | +| Baidu Qianfan AppBuilder / Ali Bailian / Tencent HunYuan | 大手クラウドベンダーのネイティブソリューション、自社モデル統合 | エンタープライズデプロイ、コンプライアンス要件の高いシナリオ | + +現在、市場には豊富なローコード AI ワークフロープラットフォームの選択肢があります。AWS、Azure、AliCloud などの主要クラウドプロバイダーもそれぞれの AI ワークフローソリューションを提供していますが、Dify、Coze、n8n は次の3つのコアアドバンテージにより、現在広く採用されている代表的なプラットフォームとなっています。 + +1. 極めて高い使いやすさ。ビジュアルなドラッグ式のインターフェース設計により、ユーザーは基盤技術を深く理解しなくても、すぐに使い始められます。 +2. 高い柔軟性。カスタムコンポーネントと拡張 API インターフェースをサポートし、教育デモや MVP(最小実現可能製品)検証などの軽量シナリオにも、中小チームのアジャイルな反復ニーズにも対応します。 +3. 成熟したエコシステム。公式ドキュメントが詳細で対応も迅速なだけでなく、活発なユーザーコミュニティがあり、異なるユーザーからの既製ソリューションを迅速に入手できます。 + +これら3つのプラットフォームはすべて、構築した AI エージェントを標準化された API インターフェースとして出力でき、フロントエンドウェブアプリケーション、エンタープライズ内部の ERP システム、モバイルアプリにシームレスに統合でき、AI 能力を現場に届ける技術的ハードルをさらに下げています。 + +### 1.3.1 Dify:エンタープライズグレードの LLMOps とアプリケーションライフサイクル管理プラットフォーム + +Dify は LLM アプリケーションの開発・運営プラットフォームとして位置づけられ、AI アプリケーションの構想、デプロイから最適化までの全ライフサイクル管理の提供に注力しています。その核心はローコードプラットフォームであり、開発者や非技術バックグラウンドのイノベーターが、プロダクションレベルの AI アプリケーションを迅速に構築できるようサポートすることを目指しています。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image6.png) + +機能面では、Dify はビジュアルワークフロー編集、エージェント構築、ナレッジベース管理、マルチモデルサポートなどの機能をカバーしています。プラットフォームはドラッグ&ドロップでノードを設計して複雑なタスクフローを構築でき、インテントベースの Agent 作成もサポートしています。ナレッジベース機能は特に優れており、複数のフォーマットのドキュメントを処理し、効率的なベクトル検索が可能です。また、GPT、Claude や多数のオープンソースモデルを含む複数の LLM に互換対応しており、構築したアプリケーションはワンクリックで標準 API として公開でき、統合が容易です。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image7.png) + +技術アーキテクチャ面では、Dify はオープンソースとプライベートデプロイを特徴としており、柔軟性、拡張性、エンタープライズグレードのコンプライアンスを重視しています。対象ユーザーは開発チームとビジネスイノベーターで、典型的な応用シナリオにはエンタープライズナレッジベースとスマートカスタマーサポート、コンテンツ作成の自動化、特定領域の AI アシスタント、エンタープライズ AI ミドルプラットフォームが含まれます。 + +### 1.3.2 Coze(字節跳動):ゼロコード AI エージェント構築の普及者 + +Coze は字節跳動(ByteDance)がリリースした AI エージェント開発プラットフォームで、極めて高い使いやすさを核心とし、プログラミング経験のないユーザーでも機能豊かな AI チャットボットを簡単に作成、デバッグ、公開できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image8.png) + +その核心は、Bot 構築をブロック組み立てのような操作にシンプル化することです。ユーザーはインターフェース上でロールやナレッジベースを簡単に設定でき、豊富な内蔵プラグインライブラリを使って Bot にニュース、旅行、画像生成など多様な外部能力を追加できます。作成した Bot はワンクリックで豆包、Feishu、WeChat 公式アカウントなど複数のプラットフォームに素早く公開できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image9.png) + +技術アーキテクチャは低い導入ハードルでの利用を徹底的にサポートするように設計されており、バックエンドでは字節跳動自社のモデルを統合し複雑なプロセスをカプセル化し、マルチモーダル理解とリアルタイム応答を重視しています。主にクラウドサービスとして提供されるプラットフォームであり、プライベートデプロイ能力は比較的限られています。典型的な応用シナリオには、パーソナルアシスタント・エンターテイメント Bot、スマートカスタマーサポートと Q&A システム、オンライン教育アシスタント、迅速なプロトタイプ検証が含まれます。 + +### 1.3.2 n8n:プログラマブルなバックエンドワークフロー自動化エンジン + +n8n は汎用的なプログラマブルなワークフロー自動化プラットフォームであり、その核心は、各種アプリケーション、データベース、API を接続し、データフローとタスクの自動実行を実現することです。 + +数百種の SaaS サービス、データベース、プロトコルをサポートする大規模な統合ノードライブラリを備え、ビジュアルとコードを組み合わせた方式を採用しています。ユーザーはキャンバス上でノードをドラッグしながら、JavaScript や Python のコードを注入してカスタムロジックを記述できます。n8n はバックエンドのデータ集約型タスク、例えばデータ同期、ETL プロセス、API オーケストレーションに特に得意です。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image10.png) + +主要な技術的特徴は「ソースコードの可視性」と「自己ホスティングが可能」なことであり、ユーザーはプライベートデプロイすることでデータと環境を完全にコントロールでき、データセキュリティ要件の高い業界にとって非常に魅力的です。主な対象ユーザーは開発者、テクニカルオペレーション、データアナリストです。n8n の最大の強みは、非常に強力なコミュニティエコシステムにあります。インターネット上には n8n の共有動画が随所にあり、ユーザーに便利な学習参考と経験の共有を提供しています。また、YouTube、Instagram など世界の多様なエコシステムプラットフォームへの接続をサポートし、ユーザーがクロスプラットフォームのデータとサービスの壁を軽々と突破し、マルチエコシステムプロセスの自動化を実現できるよう支援しています。 + +### 1.3.3 その他のワークフロープラットフォーム + +上記の最も有名なプラットフォーム以外にも、中国国内の主要テック企業もそれぞれの統合 AI 開発プラットフォームを相次いでリリースしています。例えば、Baidu Qianfan AppBuilder はモデル選択、RAG 構築からエージェント公開までの全プロセスをサポートし、Wenxin 大規模モデルと深く統合しています。Alibaba Cloud Bailian は Qwen シリーズモデルをベースに、エンタープライズグレードのセキュリティとプライベートデプロイ能力を重視しています。Tencent Cloud TI Platform は金融、医療などの業界シナリオに注力し、豊富な既製ソリューションテンプレートを提供しています。これらのプラットフォームは通常、それぞれのクラウドエコシステムと深く統合されており、該当する技術体系内にいる企業に適しています。 + +しかし、汎用性、オープン性、コミュニティエコシステムの面では、Dify と Coze が際立った使いやすさ、幅広いモデルサポート、活発な開発者コミュニティにより、現在広く採用されている選択肢となっています。 + +各プラットフォームの位置づけやエコシステムには違いがありますが、コアロジックはすべて、ビジュアルな方法で異なる機能モジュールをオーケストレーション・接続する点にあります。したがって、いずれか一つのプラットフォームの設計思想と操作方法を身につければ、他の類似ツールに迅速に移行する基盤が備わります。次の実践では、Dify を例に具体的に解説します。 + +# 2. Dify を深く理解する + +## 2.1 Dify とは + +すでに Dify の基本的な紹介に触れましたが、より詳細な情報を確認したい場合は、[https://cloud.dify.ai/apps](https://cloud.dify.ai/apps) から Dify プラットフォームにアクセスできます。さらに詳しい情報は公式サイト https://dify.ai でご覧いただけます。 + +Dify は、LLM アプリケーションを開発するためのオープンソースプラットフォームです。直感的なインターフェースにより、Agent ワークフロー、RAG パイプライン、ツール能力、モデル管理、オブザーバビリティなどの機能を統合し、プロトタイプから本番環境への移行を迅速に行えるようにサポートします。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image11.png) + +Dify では、大規模言語モデルと機能の異なる各種ツールを使って「ワークフロー」を構築できます。ワークフローとは、本来手動で段階的に完了する必要があった操作——データ検索、大規模モデル呼び出し、ウェブ検索、結果のフィルタリング、フォーマット整理など——を業務ロジックに従って連鎖させ、自動化された再利用可能なフローにすることです。ワークフローがなければ、同じ内容を大規模モデルに毎回コピペする必要があり、非常に非効率でミスも起きやすく、実際の業務での再利用も困難です。 + +ワークフローの構築は、ブロックやパズルを組み立てるようなものです。「大規模言語モデルノード」(理解と生成を担当)、各種「ツールノード」(データベースへのアクセス、メール送信、テキスト翻訳など具体的なアクションを実行)、そして「データノード」(情報の読み取り・保存を担当)をブロックのように接続します。これらはあらかじめ設定されたロジックに従って自動的に協調動作し、毎回手動で操作する必要はありません。また、これは「ローコードプログラム」と理解することもできます。ドラッグ操作で入出力のパスを設定するだけで、比較的複雑な業務ロジックを実現できます。 + +例えば、Amazon や抖音のECサイトを運営しており、AI カスタマーサービスシステムを構築したい場合、以下の図の構造を参考にワークフローを設計できます。 + +1. トリガーノード(START に類似):ユーザーからの相談質問を受信。例:「この商品の保証期間はどのくらいですか?」 +2. 質問分類ノード(QUESTION CLASSIFIER に類似):モデル(GPT など)を使ってユーザーの質問を分類。アフターセールス(保証など)、使い方、またはその他のタイプの質問かを判断。 +3. ナレッジ検索ノード(KNOWLEDGE RETRIEVAL に類似):分類結果に基づき、該当するナレッジベースに自動的にアクセス。「保証」に関するアフターセールスの質問であれば、アフターセールス SOP ナレッジベースから「保証」に関連する正確な情報を検索。 +4. 大規模言語モデルノード(LLM Node):ユーザーの質問と検索されたナレッジベースの内容を一緒に大規模言語モデル(GPT など)に送信し、ユーザーに分かりやすい回答を生成(硬すぎる技術的なトーンを避ける)。 +5. 条件ノード:大規模モデルが生成した回答に明確な保証期間(例:「1年」、「3年」)が含まれているかをチェック。含まれていれば次のステップに進み、含まれていなければ「製品型番をお知らせください」と回答。 +6. 出力ノード(ANSER に類似):最終回答をユーザーに返し、今回の相談記録を自動的にスプレッドシートに記録。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image12.png) + +このプロセス全体で、ナレッジベースを手動で調べたり、モデルの回答を繰り返し調整したり、データを個別に記録したりする必要はありません。ワークフローがこれらのステップを「連結して自動実行」します。また、非常に柔軟です。例えば、後に「ユーザーが保証範囲について聞いたら、別のナレッジベースを呼び出す」という新しいルールを追加したい場合、ワークフローに条件ノードを一つ追加するだけで済み、システム全体を作り直す必要はありません。 + +これは比較的シンプルなワークフローの例ですが、これらの能力を完全にマスターするには、今のあなたにとってまだ少し難しいかもしれません。そこで今回のレッスンでは、より基礎的なナレッジベースエージェントから始め、後でより複雑なワークフローのテクニックを段階的に学んでいきます。 + +### 2.1.1 自分専用の Dify をデプロイする(オプション) + +この部分の内容は元々後のレッスンで詳しく紹介する予定でしたが、ネットワークの制限により Dify 公式サイトやクラウドサービスに一時的にアクセスできない学習者がいる可能性を考慮し、このオプションの学習パスを前倒しで提供し、レッスンの進行がスムーズに進むようにします。 + +Web デプロイプラットフォームの基本的な使い方については、以下のチュートリアルを参考にしてください:[Web アプリケーションのデプロイ方法](/zh-cn/stage-2/backend/zeabur-deployment/) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image13.png) + +Zeabur 上に自分の Dify をデプロイする方法を学びます。デプロイ後に該当リンクにアクセスし、登録・ログインしてから、以下のチュートリアルに従って操作を続けてください。 + +なお、Dify のバージョンによって操作方法やフロントエンドのインターフェースに若干の違いがある場合がありますが、全体的な差は大きくありません。違いに気づいた際も慌てる必要はありません。似たようなインターフェースや入口を見つけて操作してください。 + +## 2.2 最初の Dify Chatbot アプリケーションを作成する + +Dify のホームページ [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps) にアクセスし、登録・ログイン後、Studio を選択すると以下の画面が表示されます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image14.png) + +左側にある `CREATE APP` セクションを見つけ、`Create from Blank` をクリックします。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image15.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image16.png) + +APP Type で Chatbot を見つけます(最初は表示されていない場合、「他のタイプを表示」ボタンをクリックして完全なリストから見つけてください)。Chatbot を選択した後、下部にアプリケーション名と説明を入力し、最後に「作成」をクリックします。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image17.png) + +作成が完了すると、以下のような画面が表示されます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image18.png) + +中央エリアの「INSTRUCTIONS」は内蔵インストラクションであり、デフォルトのプロンプトまたはシステムプロンプトとして理解できます。 + +中央やや下に「Knowledge」エリアがあり、これがナレッジベースエリアです。後ほどここにナレッジベースをアップロードします。 + +右側はデバッグウィンドウで、プロンプトを調整した後に Agent と対話し、リアルタイムで効果を確認できます。 + +INSTRUCTIONS エリアに自由にロールプロンプトを入力し、対話効果を観察できます。Generate をクリックして、大規模モデルにプロンプトを自動生成させることも可能です。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image19.png) + +右上には多数の異なるモデルのオプションが表示されます。これは、クリックして異なる対話モデルに切り替えることで、語調、論理的推論、長文テキスト処理などの面での違いを比較し、自分のニーズに最適したモデルを見つけられることを意味します。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image20.png) + +## 2.3 カスタムモデルプロバイダーのサポート + +Dify の柔軟性を最大限に活かすため、また異なる地域からのモデルへのアクセスの難易度を考慮し、特定のビジネス要件、コストコントロール、データプライバシーの要件を満たすため、多くの場合カスタムモデルへの接続が必要になります。Dify は3種類のコアモデルの設定をサポートしています:大規模言語モデル(LLM)、Embedding モデル、Rerank モデル。本セクションでは、これらのカスタム設定をステップバイステップで案内します。 + +Dify は、OpenAI、Azure、Anthropic などの主要サービスプロバイダーのモデルに柔軟に接続できるだけでなく、OpenAI API インターフェース仕様に準拠するあらゆる自己ホスト型モデルやサードパーティモデルにも完全に互換します。内蔵の OpenAI Compatible プラグインや各大規模モデルプラットフォーム向けの専用プラグインをインストールすることでこの操作を実行できます。 + +詳細な手順は以下の通りです。まず対応するプラグインをインストールします。 + +1. `OpenAI-API-compatible` と `SiliconFlow` プラグインをインストールして、大部分の大規模モデルと Embedding モデルのサポートを獲得します。前者は OpenAI 互換インターフェースのサポートであり、後者は現在大部分の一般的で使いやすいオープンソースモデルをデプロイしているサービスステーションです。以下の URL からインストールできます。 + 1. https://marketplace.dify.ai/plugins/langgenius/openai_api_compatible + 2. https://marketplace.dify.ai/plugins/langgenius/siliconflow +2. 自分で Dify をデプロイしている場合、該当するシステム設定画面からプラグインマーケットに入って操作できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image21.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image22.png) + +プラグインマーケットに入った後、対応するプラグイン名を検索してください。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image23.png) + +3. インストール完了後、新しいモデルプロバイダーを設定できます。設定内のモデルプロバイダーセクションで、現在サポートされているすべてのモデルプロバイダーが表示されます。 + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image24.png) +4. 使用を開始する前に、まずモデルの設定を完了する必要があります。OpenAI-API-compatible プラグインの場合、「Add Model」をクリックして任意のモデルを追加・設定できます。「Model Type」でそのモデルが LLM か Embedding かを選択します。モデルのタイプが正しく設定されていることを確認してください。 + 具体的なモデル名、モデル endpoint URL、API Key を入力してモデルを有効にする必要があります。このパラメーターの設定が面倒だと感じる場合は、後者の SiliconFLow プラットフォームの Key 設定に直接スキップするか、OpenRouter などのサードパーティサービスプロバイダーのプラグインをインストールして、シンプルなモデルサポート設定を行うこともできます。(サービスプロバイダーに利用可能な残額があることを確認してください) + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image25.png) + + `SiliconFlow` プラグインの場合、Setup をクリックしてキーを設定するだけで Embedding と Rerank モデルを使用してテストできます。「Get you API Key from SiliconFlow」をクリックして認証キーを取得してください。 + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image26.png) + +5. 設定完了後、モデルリストをクリックして現在サポートされているモデルの数を確認できます。これで基本モデルの全設定が完了しました。 + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image27.png) + + 大部分の一般的な Embedding と Rerank モデルがサポートされています。 + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image28.png) + + Dify がデフォルトで使用するモデルの設定を変更したい場合は、System Model Settings ボタンをクリックしてすべてのデフォルトモデルを変更できます。 + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image29.png) + +## 2.4 最初の Dify ナレッジベースを作成する + +ここまでで、最もシンプルな Agent の作成が完了しましたが、まだナレッジベースが欠けています。それでは、トップメニューの `Knowledge` をクリックし、ナレッジベース作成ページに入ります。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image30.png) + +次に、左側の `Create Knowledge` をクリックして、最初のナレッジベースを作成します。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image31.png) + +この画面では、複数のタイプのファイル(PDF、TXT など)をアップロードしてナレッジベースを構築できます。長いテキストをアップロードしたり、Wikipedia の内容をコピーして TXT ファイルとして保存してアップロードしたりもできます。この例では、Elon Musk に関する Wikipedia の TXT ファイルをアップロードします。 + +Next をクリックすると、Knowledge Base Settings(ナレッジベース設定)ページに進みます。ここには選択肢が多くありますが、一つずつ見ていきましょう。 + +まず **General** 設定では、ここを「テキスト分割ルール」の設定エリアとして理解できます。長いテキストを小さなチャンクに分割する必要があるため、まず分割ルールを定義する必要があります。入門段階では、**maximum chunk length(最大分割長)** にのみ注目すれば十分です。512、2048、4096 に設定して試し、**Preview Chunk** をクリックして異なる設定での効果をプレビューしてください。 + +**Chunk overlap(チャンクの重複)** オプションも調整できます。これは隣接する断片間で一部の内容を重複して保持するかどうかを決定します。適度な重複は、重要な情報が異なる断片に分割されて理解しにくくなるのを防ぐのに役立ちます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image32.png) + +設定には **Chunk using Q&A format in English** というオプションもあります。これを有効にすると、システムは大規模言語モデルを使ってナレッジベースの一部の内容を Q&A 形式に変換して保存し、一部のシナリオで検索効果を大幅に向上させることができます。 + +実際の業務では、シナリオに適した分割戦略を選択することで、検索結果をより適切に最適化し、クエリが期待する情報を返すようにできます。 + +ページを下にスクロールすると、Embedding モデルに関する設定が表示されます。 + +簡単に説明すると、Embedding モデルのコア機能は、非構造化データ(テキスト、画像など)をコンピュータが理解できる「数値ベクトル」(Embedding ベクトル)に変換することです。この変換により、モデルは異なるデータ間の類似度を迅速に計算でき、意味的に近い内容のマッチングを実現します。例えば、ユーザーが入力した一文に基づいて、意味が最も近いドキュメント、画像、商品を見つけることができます。 + +Embedding モデルの選択は、最終的な検索効果(マッチングの精度、応答速度など)に大きく影響します。ここでは、Qwen 0.6B の Embedding モデルの使用を優先してお勧めします。4B や 8B バージョンに切り替えて、異なるパラメータ規模での検索効果の違いを直接比較することもできます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image33.png) + +ここには、**Rerank model** という別のモデル設定も表示され、デフォルト値は **Jina-rerank-m0** です。(学内の学生でない場合、Rerank モデルが不足しているというエラーが表示されることがあります。その場合はモデル設定で Rerank モデルを構成してからここで有効にする必要があります) + +Rerank モデルの主な役割は、「一次選別された候補結果」に対するより精緻な二次ソートを行い、ユーザーのニーズに最もマッチする結果をより上位に配置することで、最終結果の関連性とユーザー体験を大幅に向上させることです。 + +端的に言えば、Rerank モデルは「一次選別が十分に精密ではない」という問題を解決するものです。例えば、検索エンジンがまず比較的シンプルなルールで1000の潜在的に関連するウェブページを検索し、その後 Rerank モデルを使って、最も関連性の高い上位10件をピックアップして最初のページに表示します。 + +推薦システムも同様です。まず「あなたに合うかもしれない」商品を500件見つけ、その後 Rerank モデルでソートし、あなたが最も購入しそうな商品をリストの上部に配置します。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image34.png) + +すべての設定が完了したら、**Save & Process** をクリックします。システムはナレッジベースのベクトル化段階に入ります。この段階で、Embedding モデルが分割されたテキストをベクトル表現に変換します。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image35.png) + +処理が完了したら、**Go to document** をクリックして、処理が完了し保存されたナレッジベースの内容を確認できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image36.png) + +ナレッジベース名を直接クリックすると、各チャンクの具体的な内容を確認できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image37.png) + +ここでは、不適切なテキスト断片を正確に編集または削除できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image38.png) + +左のサイドバーで **Retrieval Testing** を選択すると、ナレッジベースのリコールテストを行い、検索が正常に動作しているかを確認できます。各テストでは、類似度が最も高い複数のチャンクが返されます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image39.png) + +より多くのチャンク結果を表示したい場合は、`VECTOR SEARCH` 設定をクリックする必要があります。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image40.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image41.png) + +Top K は、ベクトル検索時にクエリベクトルに最も類似する上位 K 件のテキストチャンク数を返すことを指します。現在の設定は3で、類似度が最も高い3つのテキスト断片が返されることを意味します。 + +Score Threshold は「スコア閾値」です。類似度スコアがこの閾値以上(例では0.5)のテキスト断片のみが返されます。これにより、関連度の低い内容をフィルタリングし、結果をより正確にすることができます。 + +これでナレッジベース部分の準備はすべて完了しました。次に、トップメニューバーの「studio」をクリックし、先ほど作成したエージェントを見つけて、設定済みのナレッジベースを接続します。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image42.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image43.png) + +これで、各ラウンドの対話で、回答内にヒットしたナレッジベースのソースが表示されます。該当する項目をクリックすると、検索された具体的なテキスト断片を確認できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image44.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image45.png) + +## 2.5 Dify のその他の一般的な操作 + +基本的な Chatbot とナレッジベース構築の基礎内容をマスターした後、Dify のその他の使用方法についてさらに深く掘り下げていきましょう。 + +### 2.5.1 ワークフローのインポートとエクスポート + +前に触れたワークフローの中間表現法を覚えていますか?Dify は DSL(Domain Specific Language)形式によるワークフローのインポートとエクスポートをサポートしています。DSL は JSON ベースの標準化された記述方法で、ワークフローのノード構造、接続関係、設定パラメータを完全に保持できます。DSL ファイルを簡単にインポート・エクスポートでき、ワークフローを他の人と共有したり、他の人のワークフローをインポートして参考にしたりすることができます。具体的には、ワークスペースページでワークフローのインポートボタンを簡単に見つけることができます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image46.png) + +ワークフローのエクスポートについては、個別のワークフローブロックの右下隅をクリックするだけでエクスポートボタンが見つかります。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image47.png) + +DSL ファイルを使うことで、異なる Dify インスタンス間で複雑なワークフロー設計を簡単に移行・共有できます。 + +### 2.5.2 その他の Dify プロジェクトの閲覧 + +自分で構築したワークフローやエージェントがシンプルすぎると感じる場合、Dify プラットフォームには豊富なサンプルプロジェクトが用意されており、複雑なアプリケーションの構築方法をすぐに理解できます。これらのサンプルプロジェクトは多様なビジネスシナリオをカバーしています。Explora をクリックして他の人が構築したワークフローを閲覧し、学ぶことができます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image48.png) + +## 2.6 最初の Dify Workflow アプリケーションを作成する + +Dify の対話エージェント構築の入門が完了したので、次はより複雑な Dify 業務ワークフローの構築方法を見ていきましょう。ワークフローは Dify が複雑な業務ロジックをビジュアル化するコア手段であり、これを使ってブロックを組み立てるようにインテリジェントなプロセスを構築できます。情報がどのように異なるノード間を流れるか、判断ロジックがどこに配置されるか、手動介入のポイントがどこに設定されるか、そして最終的にどのように完全な業務結果をデリバリーするかを完整体験できます。 + +空白から作成するか、直接テンプレートから作成するかを選択できます。ここでは空白からワークフローを作成する方法をデモします。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image49.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image50.png) + +ここでは Chatflow と Workflow の2つの選択肢が表示されます。どちらを選ぶべきでしょうか?鍵となるのは、構築したいものが継続的な対話なのか、タスクフローなのかを理解することです。 + +Chatflow は対話のために設計されています。記憶とコンテキストの理解力を持つ対話相手をシミュレートし、複数回のやり取りや状態維持が必要なシナリオに最適です。例えばカスタマーサポートの相談では、ユーザーのフォローアップの質問に一貫して理解でき、忍耐強いスタッフのように対応できます。ストリーミング出力の特性により、インタラクションのプロセスもより自然になります。端的に言えば、「対話できる」エージェントを構築したい場合は Chatflow を選択してください。 + +Workflow はプロセスの自動実行に特化しています。あらかじめ設定されたパイプラインのようなもので、一回限りの入力、複数ステップの処理、確定的な出力を生成するタスクに適しています。例えば、毎日の定時データレポートの生成、ファイルのバッチ処理、一連の API の呼び出しです。これらのタスクは通常イベントによってトリガーされ、人とのリアルタイムなやり取りを必要としません。したがって、「自動化」タスクを実現したい場合は Workflow が適しています。 + +選択ミスによる効率低下を避けるため、4つの重要な質問でタスク要件を見直すことができます。 + +1. タスクのプロセスはユーザーの複数回の入力と調整に依存していますか? +2. 結果の提示は段階的かつストリーミングである必要がありますか? +3. 処理ロジックは以前のやり取り履歴に大きく依存していますか? +4. タスクはイベントによってトリガーされ、入力と出力が基本的に一度で完了しますか? + +最初の3つの質問の答えが「はい」であれば、Chatflow が理想的な選択です。代表的なシナリオにはスマートカスタマーサポート、教育チュータリング、クリエイティブコラボレーションなどがあります。4番目の質問の特徴が顕著であれば、Workflow を選択すべきです。データクレンジング、レポート生成、バッチ処理などの自動化シナリオにより適しています。 + +ここでは Chatflow をケースとして紹介します。Chatflow をクリックして操作画面に入ります。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image51.png) + +ワークフロー画面について簡単に説明します。画面全体のコアは中央の編集キャンバスであり、ここでビジュアルにアプリケーションロジックを構築します。図に示すように、基本的なワークフローは通常 START ノード(入力の受信)で始まり、接続線を通じてデータを LLM ノードに渡して処理し、最終的に ANSWER ノードを通じて結果を出力します。各ノードは機能モジュールを表し、接続線がタスク実行の順序を決定します。 + +キャンバスの周りには完全な操作・管理機能エリアがあります。画面上部にはグローバル制御オプションがあり、ワークフローをテストする Preview ボタンとリリースする Publish ボタンが含まれています。キャンバスの隅にはズーム、取り消しなどのビュー制御ツールがあり、細かな調整に便利です。 + +左側のパネルにはアプリケーションの管理機能が集中しています。現在いる Orchestrate タブはプロセスの編成に使用され、構築完了後は API Access から統合認証情報を取得できます。Logs & Annotations には各実行の詳細な記録が保存され、デバッグに役立ちます。Monitoring はアプリケーション実行時のパフォーマンスと状態のモニタリングを提供します。 + +この対話ワークフローの LLM ノードの SYSTEM にいくつかのプロンプト内容を入力し、Preview をクリックしてこのワークフローを実行してみてください。SYSTEM プロンプトを変更した後、ワークフロー全体が期待通りに変化することを確認できます。 + +### 2.6.1 代表的なノードの紹介 + +Dify には複数のノードが用意されています。まず各ノードの基本的な機能を理解してください。具体的な使用時には、実際に試すか、他の人が作成したワークフローテンプレートを参考にするか、スクリーンショットを撮って大規模モデルにノードの使い方や必要なパラメータなどを質問することをお勧めします。既存のテンプレート内で異なるノードを直接入れ替えて、他のユーザーの使用方法からノードのベストプラクティスを推測することもお勧めします。 + +キャンバス上で右クリックし「Add Node」でノードを追加できます。左側のノードパネルですべての利用可能なノードを確認することもできます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image52.png) + +また、ツール選択パネルを開いて、サポートされている各種ツールの呼び出しを確認できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image53.png) + +以下は、よく使われるノードとツールの簡単な説明です。すべてを一度にマスターする必要はありません。まずは印象を持っておき、実際の使用を通じて徐々に慣れ、必要に応じて見直してください。 + +1. LLM と推論ノード + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image54.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image55.png) + +これらのノードはワークフロー内のコアプロセスを担当します。 + +- LLM ノード:コア計算ユニットであり、大規模言語モデルの呼び出しに使用されます。設定の重点はプロンプトエンジニアリングとパラメーターの最適化であり、業務上の問題をモデルの実行命令に変換します。 +- Knowledge Retrieval ノード:ナレッジ検索ユニットであり、あらかじめ設定されたナレッジベースや外部の信頼性の高いデータソースから、業務上の問題に関連する情報を検索し、LLM ノードに正確なナレッジサポートを提供して、大規模言語モデルの「ハルシネーション」問題の軽減に役立ちます。 +- Answer ノード:結果出力ユニットであり、LLM 処理後の内容を受け取り、業務シナリオの要件に合った最終成果物の形式に整理します。設定の重点は出力フォーマットの定義(トークテンプレート、レイアウト仕様など)です。 +- Agent ノード:高度な意思決定ユニットです。モデルを呼び出すだけでなく、複数ステップの計画の実施や、外部ツールの自律的な選択・呼び出しも可能で、動的な意思決定が必要な複雑なタスクチェーンに適しています。 +- Question Classifier ノード:質問分類ユニットであり、入力された業務上の質問のタイプ識別と分類を担当します(例:質問の意図、主題領域などの次元で分類)。後続のプロセスが対応する処理ノードに正確にマッチできるよう支援します(例:異なるタイプの質問に異なる LLM プロンプトやツールチェーンを適用)。 + +2. ロジックとフロー制御ノード + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image56.png) + +これらのノードはワークフローの実行パスとルールを定義します。 + +- 条件ノード:`IF/ELSE` など、ブール値の判定によるフローの分岐を実現します。設計のポイントは条件式の厳密さであり、すべての業務シナリオをカバーするロジックを確保することです。 +- Iteration ノード:ステートレスなバッチ並列処理ユニットとして、サブタスク間にデータ依存がなく独立して処理可能なシナリオ向けに設計されています。例えば段落のバッチ翻訳、複数コンテンツの並列レビュー、複数レポートの同時生成などです。このノードは入力配列を受け取って自動的に分割し、各要素を同じ処理チェーンに分配して並列実行します。ユーザーは反復体内で `{{item}}` で現在の要素にアクセスし、`{{index}}` でインデックスを取得でき、出力は自動的に結果配列に集約されます。設定時は効率とシステム負荷のバランスを取るために並列度を重点的に設定し、再試行戦略(再試行回数、間隔)と失敗処理(ログの記録、デフォルト値の返却など)を通じてバッチジョブの安定性を確保する必要があります。 +- Loop ノード:ステートフルな再帰イテレータであり、結果が前回の出力に依存するシナリオに適しています。例えば複数回のパラメーター調整、再帰的なコンテンツ最適化(満足するまで繰り返し文案を修正)、前回の結果に依存する連鎖計算などです。コアは「状態変数」であり、ループ開始前に初期化(現在の反復回数、中間計算結果など)し、各反復で明確に更新して次回の入力とする必要があります。無限ループを防ぐため、終了条件を定義する必要があります(カウンターベースの「最大10回ループ」、結果判定ベースの「満足度スコア > 9」、外部信号ベースの「'停止'入力を検出」を含む)。またループタイムアウト設定を行い、例外処理パス(ループからの脱出や状態リセット後の再試行など)を計画して、プロセスの安定稼働を確保する必要があります。 + +3. データ操作と統合ノード + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image57.png) + +- Code ノード:コード処理ユニットであり、ワークフロー内でのカスタムコードロジックの実行を担当し、データフォーマット変換や複雑な計算などの個別化された処理ニーズを実現します。設定の重点はコードの構文の正確さと実行環境への適応です。 +- Template ノード:テンプレート処理ユニットであり、動的データをあらかじめ設定されたテンプレートに充填して、フォーマット要件に合ったコンテンツ(カスタマイズされたコピー、レポートフレームなど)を生成します。設定の重点はテンプレート構文の記述と変数マッピングルールの設定です。 +- Variable Aggregator ノード:変数集約ユニットであり、ワークフロー内の複数のノードから出力される変数データを収集し、分散した変数を統合されたデータセットにまとめます。設定の重点は集約する変数の範囲とデータ結合ルールの定義です。 +- Doc Extractor ノード:ドキュメント抽出ユニットであり、PDF、Word など各種ドキュメントからテキスト、表などの重要な内容を抽出し、ワークフローで処理可能な構造化データに変換します。設定の重点はドキュメントタイプへの適応と抽出内容のフィルタリングルールです。 +- Variable Assigner ノード:変数代入ユニットであり、ワークフロー内の変数の定義、初期化、更新を担当し、プロセス内のデータ受け渡しのキャリアを提供します。設定の重点は変数の命名、データ型、代入ロジックの設定です。 +- Parameter Extractor ノード:パラメーター抽出ユニットであり、ユーザーリクエストやインターフェースレスポンスなどの入力内容から指定されたパラメーターを抽出し、非構造化情報を構造化データに変換します。設定の重点は抽出ルール(正規表現、JSON パスなど)の設定です。 +- HTTP Request ノード:HTTP リクエストユニットであり、外部システムのインターフェースに HTTP リクエスト(GET、POST などのメソッドを含む)を発行し、ワークフローと外部サービス間のデータインタラクションを実現します。設定の重点はリクエストアドレス、リクエストメソッド、パラメータ/ヘッダーの設定です。 +- List Operator ノード:リスト操作ユニットであり、配列やリスト型データの処理(フィルタリング、ソート、分割など)を担当し、データ構造を後続のプロセスに適合させます。設定の重点は操作タイプ(フィルタリング条件、ソートルールなど)の定義です。 + +### 2.6.2 代表的なツールの紹介 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image58.png) + +Dify では、大部分のツールをキャンバス上に直接ノードとして配置でき、他のノードと同様に上下流の接続線でつなぐことができます。提供する入力が該当ノード(ツール)のパラメーター仕様に準拠していれば、正常に実行され、後続に渡せる結果を出力できます。 + +左側または右側のノードパネルで、すべての利用可能なツールノードを確認できます。プラグインマーケットからさらに多くのツール機能を拡張することも可能です。いくつかの一般的なツールの役割を簡単に紹介します。 + +- ウェブ検索ツール + Tavily Search を代表とし、大規模モデル向けに最適化されたリアルタイム検索機能を提供します。 + 構造化された検索結果(タイトル、要約、リンクなど)を返し、LLM プロンプトの一部として直接使用でき、最新の情報や信頼性の高い根拠が必要な質問への回答に活用できます。 +- データ処理ツール + JSON Process プラグインなど、JSON データの照会、フィルタリング、変換、マージなどの高度な操作に使用します。 + 複雑な API レスポンスや多層ネストされたデータを処理する際、このツールに「データクレンジング + 再構成」のロジックを任せることで、Code ノードで頻繁にパーサーを手書きする作業を簡略化できます。 +- フォーマット処理ツール + Markdown Exporter など、生成されたコンテンツを指定フォーマットでエクスポートでき、例えば Markdown ドキュメントや特定のレイアウトテンプレートなど、その後の表示、報告、他システムへの統合に便利です。 + +ツールリストではこれらのプラグインのインストール数と概要を確認できます。初期段階では「Featured / おすすめ」のツールを優先的に試すことをお勧めします。これらは最も一般的な業務シナリオをカバーしています。 + +ただし、ツールの使用は通常比較的複雑なため、使用する際にまず検索エンジンで該当ツールの「公式推奨ワークフロー DSL ケース」を検索し、直接インポートして使用することをお勧めします。自分で構築するよりも、大幅に時間を節約できます。 + +### 2.6.3 シンプルなインテント分類ワークフローの作成 + +ここまでで Dify ワークフローとツールなどの基本情報を一通り理解しましたが、練習しなければ詳細を使いこなすことはできません。練習用の「仮想の」実際の業務シナリオが必要です。 + +例えば、実際のショッピング対話シナリオでは、商品を買いに来るユーザーの入力は決して「きちんと整形されたパラメーター」ではなく、何気なく口にする一言です。注文しに来る人もいれば、文句を言いに来る人もいれば、ただ雑談したい人もいれば、完全に話題がそれている人もいます。これらすべての入力を同じ一つの大規模言語モデル(LLM)に直接処理させると、システムは通常2つの典型的な問題に直面します。 + +1. 回答のスタイルが不安定 + 同じ文句に対して、LLM が謝罪してなだめることもあれば、「理由を説明する」態度になることもあります。同じ注文でも、不足情報を追問したり、直接オーダーの詳細を作り上げたりすることもあります。 +2. 業務ロジックがコントロール不能 + 「文句には必ずまず謝罪する」というルールがあっても、モデルは毎回それを守るとは限りません。「業務に関係ない質問はメインに戻すべき」というルールがあっても、モデルが楽しそうに冗談を言い続ける可能性があります。 + +したがって、より工学的なアプローチは、タスクを標準化されたパイプラインに分解することです。まずインテント分類(ユーザーが実際に何をしたいのかを確定)を行い、その後インテントに基づいて振り分け(異なるシナリオで異なるプロンプトとロールを使用)し、最後に異なる分岐先の大規模モデルの回答を統合して出力します(フロントエンドやシステムへの統合を容易にするため)。 + +本節の目標は、レストランシナリオにおける複数タイプの対話を処理できるシステムを構築することです。実際に操作して理解を深めてください。まずはシナリオのインテント分類を定義します。 + +- **注文購入 (buy_food)**:ユーザーが明確な購入意図を示す。 +- *例:「唐揚げセットを一つ、それからコーラを追加で。」* +- **苦情 (complain)**:ユーザーが不満、催促、ネガティブなフィードバックを示す。 +- *例:「遅すぎるんだけど?もう1時間も待ってるよ。」* +- **雑談相談 (chitchat)**:ユーザーがオープンな質問やアドバイスを求めているが、明確な注文の意図はない。 +- *例:「今日は何を食べるのがいいかな?おすすめはある?」* +- **その他 (other)**:ユーザーの入力がレストランシナリオと無関係。 +- *例:「面白い文案を考えて、SNS に投稿したいんだけど。」* + +これら4つのインテントに対して、システムに4つの異なる「コミュニケーションパーソナリティ」をあらかじめ設定します。それぞれ独立した LLM ノードで実現され、異なるペルソナを持つ LLM が演じます。 + +- **注文アシスタント (LLM_BuyFood)**:プロフェッショナルで効率的。コアは注文詳細の確認と、不足情報の積極的な補完。 +- **カスタマーサポート専門家 (LLM_Complain)**:共感力があり落ち着いている。最優先はユーザーの感情をなだめ、明確な解決策を提供すること。 +- **チャットパートナー (LLM_Chitchat)**:リラックスしてフレンドリー。パーソナライズされたおすすめを提供し、潜在的な消費を促す。 +- **礼儀正しいゲートキーパー (LLM_Other)**:集中力が高く、境界が明確。話題がそれた対話を礼儀正しくコア業務に戻す。 + +#### ワークフロー編集の設計 + +次にワークフローの編集設定を行い、どのようなワークフローノードが必要かを大まかに決めます。初心者にはどのノードが必要かを思い付くのが難しく(ベテランも自分で考えるより大規模モデルに提案させる方が通常最速で最善の選択です)、大規模モデルに編集の提案をさせることができます。コアとなるノード構造は以下の通りです。 + +- Start(起点):データの入口として、ユーザーの元の入力 `user_text` を受信。 +- Question Classifier(インテント分類器):ワークフローの「頭脳」と「ディスパッチセンター」。`user_text` を分析し、あらかじめ設定された4つのインテントラベルから最もマッチするものを選択。 +- Condition(条件分岐):「分流バルブ」の役割。分類器が出力したインテントラベルに基づいて、次にどの専用処理パスにタスクを導くかを決定。 +- 4つの並列 LLM ノード (LLM_BuyFood, LLM_Complain, LLM_Chitchat, LLM_Other):4つの独立した「専門家処理ユニット」。各ノードは元の質問を受け取りますが、それぞれ独自の System Prompt に基づいて、スタイルと目標が全く異なる回答を生成。 +- Variable Aggregator(変数集約器):複数のパスの処理完了後、一つの「集約ポイント」が必要。このノードは4つの分岐のうち、唯一アクティブになり結果を生成した回答を一つの統一された変数 `final_reply` に集約し、出力構造の安定性を確保。 +- Output(終点):最終的な出口として、インテントラベル、元の質問、処理されて生成された回答を構造化された形式(JSON など)で統一して出力し、後続のシステム呼び出しやデバッグ分析に便利なようにします。 + +#### ワークフロー編集の実装 + +今回のチュートリアルでは、Chatflow ではなく Workflow の作成を選択します。User Input を選択してください。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image59.png) + +Start の User Input ノードをクリックし、`user_text` という名前の文字列型変数を定義し、フロー全体の入力ソースとします。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image60.png) + +保存後、右上の Test Run をクリックすると、対応するテキスト入力を指定して処理を実行できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image61.png) + +次に、入力ノードの後の + 記号をクリックし、Question Classifier ノードを追加します。4つのカテゴリラベルを設定し、各ラベルに明確な説明と例を提供する必要があります。 + +- `buy_food`:ユーザーがはっきりと食べ物を買いたい、注文したい、発注したいと示している。 +- `complain`:ユーザーが文句を言っている、不満を漏らしている、怒っており、通常不満の感情を伴う。 +- `chitchat`:ユーザーが雑談している、何を食べるか相談している、おすすめを聞いている。 +- `other`:レストランシナリオと無関係、または判断が困難な内容。 + +さらに、ADVANCED SETTING にプロンプトを記述し、大規模モデルがユーザーの入力に基づいて正確に分類テストを行えるようにする必要があります。プロンプトの例は以下の通りです。 + +``` +buy_food / complain / chitchat / other の中から最も適切なラベルを1つ選択してください。ユーザーが文句を言いながらも注文している場合、そのコア感情を優先して判断し、不満が主であれば complain に分類してください。軽い愚痴程度で主な意図が注文であれば buy_food に分類してください。どうしても判断が難しい場合は other をフォールバックとして使用してください。 +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image62.png) + +設定完了後、右上の再生ボタンでこのノード単体が正常に動作するかテストできます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image63.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image64.png) + +OUTPUT の結果を見ると、分類は正確です。複数の異なる入力タイプでテストを行い、分類器の安定性を検証してください。 + +次に、分類器に続く大規模モデルの出力を接続します。例えば、`label` が `"buy_food"` の場合、ワークフローは正確に `LLM_BuyFood` ノードに流れます。4つの LLM ノードを新規作成し、それぞれ異なる System Prompt を設定します。異なる System Prompt の違いが、それぞれの異なる応答スタイルを決定します。 + +- LLM_BuyFood(注文アシスタント): + +あなたは注文アシスタントです。要件:1. ユーザーが注文したい内容を確認する。2. 情報が不完全な場合、丁寧に追加質問する。3. 礼儀正しく簡潔なトーンで。 + +- LLM_Complain(カスタマーサポート専門家): + +あなたはレストランのカスタマーサポートで、文句の処理を専門としています。要件:1. 誠実に謝罪する。2. 考えられる原因を簡潔に説明する(責任転嫁しない)。3. 明確な次のステップの解決策を提示する。 + +- LLM_Chitchat(チャットパートナー): + +あなたは食べ物選びを手伝うチャットアシスタントです。要件:1. リラックスしたフレンドリーなトーンで。2. 1〜3つのシンプルなおすすめを提示。3. ユーザーの好みがない場合は、異なるスタイルの選択肢を提供。 + +- LLM_Other(礼儀正しいゲートキーパー): + +あなたはレストランの注文アシスタントで、「食べる」に関連する話題のみ得意です。ユーザーの発言が無関係な場合:1. 礼儀正しく自分の能力範囲を説明する。2. ユーザーをメインシナリオに戻す。 + +なお、各ノードで SYSTEM のプロンプトパラメータを入力した後、USER プロンプトパラメータも有効にすることを忘れないでください。その中で `{x}` シンボルをクリックして `user_text` パラメータをユーザー入力として選択し、その前に `user input:` を付けてこの変数がユーザー入力であることを示す必要があります。対話の際、ユーザーの最初の入力と内蔵プロンプトを総合して回答が生成されます。 + +同様に、すべてが正常に機能していることを確認するため、該当ノードの右上の再生ボタンをクリックして具体的な対話テストで効果を検証できます。例えば「タピオカミルクティーを飲みたい」などと対話して、回答が期待通りか確認してください。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image65.png) + +次に、並列 LLM の出力値を処理します。`Variable Aggregator` ノードの設定パネルで、`ASSIGN VARIABLES`(変数の割り当て)エリアを見つけ、クリックして先ほどの大規模モデルの回答を順番に追加します。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image66.png) + +次に、すべての出力を集約し、最終的に欲しい結果——ユーザーの入力、分類、回答——を得る必要があります。Workflow を使用しており Chatflow ではないため、Answer ノードを選択して結果を集約することはできません。他のノードで間接的に結果の集約と出力を実現できます。Template ノードを選択し、変数部分でユーザーのインテント分類結果、ユーザーの入力値、変数集約の最終回答を指定し、CODE に最終回答の JSON フォーマットテンプレートを記述します。 + +- `intent` ← `class_name` +- `original_text` ← `user_text` +- `final_reply` ← `variable_aggregator` + +``` +{ + "intent": "{{ intent }}", + "original_text": "{{ original_text }}", + "reply": {{ final_reply }} +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image67.png) + +最後に output ノードを追加すれば、すべての操作が完了します。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image68.png) + +#### ワークフローの実行テスト + +完成です。このワークフローの効果を実行してみましょう。異なる入力に基づいて、全く異なる動作パターンを示します。 + +- 入力(注文):「スパイシーチキンバーガーセットを一つ、ラージコーラで。」 + - パス:`buy_food` → `LLM_BuyFood` + - 出力 reply:「承知いたしました。スパイシーチキンバーガーセットとラージコーラをご注文いただきました。セットのポテトは変更されますか?」 +- 入力(文句):「遅すぎるんだけど!もう1時間以上も待ってるよ!」 + - パス:`complain` → `LLM_Complain` + - 出力 reply:「大変長らくお待たせしてしまい、誠に申し訳ございません。これは当店の不手際であり、お客様に大変ご不便とご不快な思いをさせてしまいました。現在、緊急にお客様の注文の配送状況を確認しており、相応の補償を申請いたします。ご忍耐とご指摘に感謝申し上げます。」 +- 入力(雑談):「今日は何を食べるのが健康的?」 + - パス:`chitchat` → `LLM_Chitchat` + - 出力 reply:「健康志向なら、ライトサラダシリーズやグリルチキンと季節の野菜がおすすめです。味付けはあっさりしたものが好きですか、それとも少しリッチなものがいいですか?さらに具体的におすすめできます。」 +- 入力(無関係):「明日の会議用に面白いジョークを考えて。」 + - パス:`other` → `LLM_Other` + - 出力 reply:「それは面白いチャレンジですね!でも私は主にグルメのおすすめと注文のアシスタントです。何か頼んで、お仕事お疲れ様のご褒美をいただけませんか?いつでもお手伝いします!」 + +> 隠しバグ:aggregation group に関連する奇妙な問題に遭遇した場合、それはおそらく Dify の内蔵バグです。特定の操作でトリガーされる可能性があります。AGGREGATION GROUP を一度有効にしてから無効にした場合、システムが group 設定を生成し、関連する異常パラメータが残留している可能性があります。現在スイッチがオフに見えても、これらの残留設定が問題を引き起こす可能性があります。例えば `any` 関連パラメータのエラーが表示されることがあります。この場合、該当ノードを削除して再作成してください。 + +Test Run で実行すると、ワークフローの実行プロセスが確認できます。分類に基づいて正しいフローに進み、最後の出力結果が得られています。これで、全プロセスが完了しました。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image69.png) + +## 2.7 最初のテンプレート Workflow アプリケーションの実行 + +シンプルな分類ワークフローの学習を終え、次は他の人が作ったワークフローの実行方法を学びます。少し手を加えるだけで自分のワークフローにすることができます。ここでは公式の DeepResearch ワークフローを選んで試します。このワークフローは深い検索フレームワークを構築するのに役立ち、大規模モデルと検索エンジンを使って豊富な検索結果を提供します。各質問の結果には検索引用元アドレスと大規模モデルとの対話結果が含まれます。 + +インポート後、まずそのまま実行し、各ステップで発生するエラーとその原因に基づいて具体的な問題を解決していきます。解決できない問題に遭遇した場合は、スクリーンショットを撮って大規模モデルに質問して解決してください。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image70.png) + +最初は非常に複雑に見えますが、問題ありません。右上の Preview をクリックしてワークフローを実行し、エラーが発生するまで進めます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image71.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image72.png) + +エラーが発生したノードに基づいて問題を解決する必要があります。開いてみると、Tavily の API Token が設定されていないことが原因です。Tavily の検索 API は AI 向けに設計された検索エンジンで、リアルタイム、正確、事実に基づく結果を提供します。指示に従って操作してください。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image73.png) + +処理後、検索エンジンが正常に動作するようになります。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image74.png) + +モデル呼び出しによる問題を引き続き修正した後、以下のような結果——大規模モデルの理解に基づく詳細な検索結果——が得られるはずです。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image75.png) + +最後に、対応する参考ドキュメントのアドレスが表示されます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image76.png) + +各ステップの役割を理解したい場合、最も良い方法は各ステップの出力を変数として記録し、最後に出力時に各中間変数の結果を出力することです。もう一つの方法は、上部で Process のプロセスを見つけ、クリックして各ステップの詳細を確認することです。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image77.png) + +## 2.8 Dify を API プロバイダーとして使用する + +次に、先ほど作成したナレッジベースエージェントを API 経由で呼び出すことを試みます。Dify を大規模モデルの中枢バックエンドとして使いたいと考えています。 + +API を使ってモデルを呼び出す方法を以前学びましたね。鍵(Key)と API 呼び出し例(ドキュメント内の request/response 例)を準備し、これらの内容を大規模モデルに渡して、サービスを呼び出すコードを書いてもらい、返された結果から必要なフィールドを取り出します。 + +今回は、ローカルのコード編集ツール [Trae](https://www.trae.cn/) を使ってこのプロセスを完了します。 + +IDE についてまだ馴染みがない場合は、まずドキュメント [Extra Knowledge 4 - What is AI IDE and Trae](https://github.com/datawhalechina/easy-vibe/blob/main/docs/extra/extra4/extra4-what-is-ai-ide-and-trae.md) をお読みください。 + +ローカルの開発環境がまだ完全に設定されていなくても心配はいりません。自分のコードアシスタント([z.ai](http://z.ai) でも Trae でも)を信頼していれば、分からないことやエラーに遭遇した際は、そのまま問題を投げかけることで、詳細な解決策を提示してくれます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image78.png) + +右側のエリアは Copilot インタラクションウィンドウ、または Agent ウィンドウと呼ばれます。表示されていない場合は、右上のサイドバーアイコンをクリックして開いてください。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image79.png) + +サイドバーを開くと、`Builder` オプションが表示されます。これが Agent モードです。「Builder」は [z.ai](http://z.ai) の「開発モード」と同様に理解でき、ローカルの PC 環境の操作、依存パッケージのインストール、ウェブページの表示なども行えます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image80.png) + +「Builder」をクリックすると、「Chat」モードと「Builder with MCP」モードが表示されます。Chat モードは主に現在のフォルダとのインタラクションや、大規模モデルとの自然言語対話に使用されます。(Trae の左上の「File」をクリックしてフォルダを開くことができ、そのフォルダ内で編集を行えます。この場合、Builder のすべての新規ファイル作成操作はそのフォルダ内で行われます。) + +Builder with MCP モードは Agent により多くのツールを提供します(例:大規模モデルを他のソフトウェアに接続したり、天気情報を取得したりする機能)。MCP は、大規模モデルが各種外部ツールをより便利に呼び出せるようにする能力のコレクションとして理解できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image81.png) + +下部のエリアには、モデル選択のドロップダウンリストもあり、クリックして異なるモデルに切り替えられます。ここでは Kimi k2 または GLM を選択できます。国際版の Trae を使用している場合は、ChatGPT または Claude を選択することも可能です。ただし、国内の大規模モデルの急速な発展に伴い、Kimi、Qwen、GLM などのモデルの総合能力は基本的に Claude 3.5 や 3.7 に近いレベルに達しており、日常の開発シナリオには十分対応できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image82.png) + +以上が Trae の簡単な紹介です。次に、[z.ai](http://z.ai) での操作手順を振り返り、その考え方を Trae でも応用してみましょう。 + +## 2.9 Dify API を使ったフロントエンドチャットアプリケーションの作成 + +Dify の API を使ってフロントエンドチャットアプリケーションを構築する場合、まず Dify の API ドキュメントと呼び出しアドレスを取得する必要があります。 + +先ほど作成した Agent を覚えていますか?まず右上の「Publish」をクリックし、「Publish Update」を選択し、最後に「Access API Reference」をクリックして API ドキュメントに入ります。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image83.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image84.png) + +API ドキュメントに入ったら、「Send Chat Message」のセクションを見つけ、クリックして入り、右側で「Request」と「Response」の例を見つけてコピーします。 + +なぜこの2つを必ずコピーする必要があるのか?それらが API の「コア情報」だからです。Key、リクエスト例、レスポンス例があれば、大規模モデルにサービスを呼び出すコードを生成させ、返却構造に基づいて必要なフィールドを抽出させることができます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image85.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image86.png) + +対話に必要な Request と Response の例を見つけたら、さらに API Key を取得する必要があります。ドキュメントの右上に「API key」関連のオプションが表示されます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image87.png) + +「Create new Secret key」をクリックすると、自分の API Key を作成できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image88.png) + +これで準備はすべて整いました。取得した API Key、Request 例、Response 例を一緒に Trae Builder に渡します。 + +注意:`{DIFY_API_URL}` を実際の Dify API アドレスに置き換えてください。 + +```json +key: +app-zKdCHUXXXXXXXX + +Please write me a front-end based on the following reference: + +curl -X POST 'http://{DIFY_API_URL}/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image89.png) + +この段階では、生成されたプログラムが一度で正常に動作しないことがあります。例えば、対話に奇妙なエラーが発生したり、何も結果が返されなかったりする場合があります。このような状況に陥った場合は、別の大規模言語モデルに切り替えてみるか、エラーメッセージをコピーし、問題を詳細に記述してモデルに送信し、フィードバックに基づいて継続的に反復してください。 + +この時点で、あなたの作業スタイルはすでに実際の開発プロセスに非常に近くなっています。日常の開発では、大規模モデルとの協力において様々な問題に直面することがよくあります。問題をより良く解決するためには、より多くのコンテキスト情報を提供する必要があります。エラー情報の提供に加え、より完全なドキュメントの内容(例えばドキュメント左側の「Send message」部分からより多くの説明をコピーする)も一緒にモデルに渡すことで、より多くの詳細に基づいたより完全なソリューションを提案させることができます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image90.png) + +現在、ブラウザは Trae の内蔵ブラウザです。上部のコンパスアイコンをクリックすると、外部ブラウザでフルスクリーン表示できます。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image91.png) + +運が良ければ、最初の試行で正常にインタラクティブなフロントエンドページが得られるかもしれません。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image92.png) + +ただし、大規模モデル自体に一定のランダム性があるため、1回の対話では問題がなくても、複数回の対話で異常が発生することがあります。したがって、複数回の対話テストを行い、複数回のインタラクションのシナリオでもプログラムが安定して動作することを確認することをお勧めします。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image93.png) + +ここまでで、シンプルな Dify ナレッジベース Agent の構築方法と、[z.ai](http://z.ai) の代わりに Trae を使ってインタラクティブなフロントエンドを構築する方法を習得しました。これからは、Trae がプロトタイプ構築時の主要な開発ツールとなり、徐々に [z.ai](http://z.ai) に取って代わります。Trae を使って以前のスネークゲームを作り直して、どのような違いがあるか体験してみてください。頑張ってください! + +# 3. その他の業務ワークフロー参考 + +検索エンジンで `Dify workflow 参考` のようなキーワードで検索するか、GitHub で直接 Dify ワークフロー共有リポジトリを見つけて参考ワークフローを探すことができます(品質にばらつきがあるため、複数のリポジトリを参照して学ぶ必要があります)。もちろん、ワークフローとは業務上の SOP のマッピングに過ぎないので、日々の仕事や学習の中でどのようなプロセスが反復的で固定化できるかを考え、それをワークフローとして固定すればよいのです。 + +以下は、大規模モデルが生成したワークフロー設計の参考です(実際の実装ソリューションも比較的似ており、一般的に人間が設計したワークフローよりも大規模モデルが設計したものの方が洗練されています。ただしエキスパートが設定したワークフローは例外です)。気になるアイデアがあれば、それを大規模モデルにさらに具体化させ、より具体的な Dify ワークフローノードの設定や内部の詳細な結果を出力させることができます。 + +## 3.1 ソーシャルメディアプラットフォームワークフロー + +1. クロスプラットフォームコンテンツ一斉配信ワークフロー(複雑) + 1. アイデア:1つのコア原稿を「素材」とし、各プラットフォームに適合する「完成品」に自動加工。 + 2. 実装:`Start` で記事を入力 → `LLM` でリファイン → 複数の `LLM` ノードを並列に(各ノードの Prompt が特定プラットフォームの専門家を演じる。例:「Xiaohongshu バズ文案の専門家」「Zhihu プロ回答者」)→ `Iterator` ノードで異なるプラットフォームのフォーマット要件をループ処理 → `Variable Aggregator` で集約 → `Answer` で全バージョンを出力。複雑さは並列処理とループ反復にあります。 +2. トレンドトピック選定と初稿ジェネレーター(中程度) + 1. アイデア:ネット上のトレンドを自動的に捉え、トピック選定とコンテンツの草案を迅速に生成。 + 2. 実装:`Start` でキーワードを入力 → `Tool` ノードで検索エンジン API を呼び出してトレンドを取得 → `LLM` で要約し3〜5個のトピックを抽出 → `LLM` で記事のアウトラインや初稿を生成。複雑さは外部ツールの統合と情報のフィルタリングにあります。 +3. コメントセクションのスマート分類と返信アシスタント(複雑) + 1. アイデア:コメントの感情とインテントを自動分析し、分類された返信提案を生成。 + 2. 実装:`HTTP Request` ノードでソーシャルメディア API に接続してコメントを取得 → `Question Classifier` または `LLM` ノードでマルチラベル分類(ポジティブ、質問、苦情、広告など)→ `Condition` ノードで異なる返信生成チェーンにルーティング → 並列 `LLM` ノードでパーソナライズされた返信案を生成 → `Answer` で出力。複雑さは条件分岐とリアルタイム API 呼び出しにあります。 +4. ショート動画スクリプトとストーリーボード自動ジェネレーター(複雑) + 1. アイデア:話題のテーマや製品説明に基づいて、ショート動画のスクリプト、ストーリーボード、おすすめタグを自動生成。 + 2. 実装:`Start` でテーマを入力 → `LLM` でクリエイティブなスクリプトを生成 → 2番目の `LLM` ノードでスクリプトをシーンのシーケンスに分解(画面説明、セリフ、尺)→ `Tool` ノードでテキスト読み上げサービスを呼び出し音声サンプルを生成 → `Variable Aggregator` ですべての要素を統合 → `Answer` で構造化されたスクリプトファイルを出力。複雑さは多段階のシリアル化と外部サービスの統合にあります。 +5. ライブ配信インタラクション Q&A リアルタイム要約アシスタント(中程度) + 1. アイデア:ライブ配信のテキストコメントをリアルタイムで処理し、コア質問と視聴者のフィードバックを抽出。 + 2. 実装:`HTTP Request` ノードでストリーミング取得したライブコメントを処理 → `Iterator` ノードで時間ウィンドウ単位でバッチデータを処理 → `LLM` ノードで各時間帯のホットな質問と感情傾向をリアルタイムで要約 → `Answer` または `Webhook` ノードで要約を配信者に出力。複雑さはリアルタイムのストリームデータ処理とループウィンドウにあります。 + +## 3.2 職場ワークフロー + +1. スマート会議議事録とタスク自動割り当てシステム(複雑) + 1. アイデア:会議の録音テキストから議事録を抽出し、タスクを自動作成。 + 2. 実装:`Start` で会議テキストを入力 → `LLM` で議題と結論を要約 → `Parameter Extractor` ノードで Action Items(タスク、担当者、締切)を正確に抽出 → 1つの `LLM` で議事録メールに統合 → 並列 `HTTP Request` ノードで Jira/Trello/Feishu API を呼び出してタスクを作成。複雑さは情報抽出と複数システム連携にあります。 +2. 履歴書バッチ審査と初期評価アシスタント(中程度) + 1. アイデア:履歴書を自動解析し、マッチ度評価を行い、面接質問を生成。 + 2. 実装:`Start` で履歴書ファイルと JD をアップロード → `Document Extractor` ノードで履歴書テキストを解析 → `LLM` が HR の役割でマッチ度評価を実施 → 高マッチ度の候補者に対し、別の `LLM` が深い面接質問を生成。複雑さはドキュメント解析と複数条件の評価にあります。 +3. 多言語メールワンクリック翻訳と返信案(シンプル) + 1. アイデア:メールを自動翻訳し、返信案を作成。 + 2. 実装:`Start` でメールを入力 → `LLM` で言語を判定し翻訳 → `LLM` で返信のポイントを作成 → `LLM` で元の言語に翻訳し推敲。主に LLM の直列呼び出しに依存。 +4. 週報/月報データ自動集計とインサイト生成(複雑) + 1. アイデア:複数のデータソースに接続し、構造化された業務レポートを自動生成。 + 2. 実装:複数の `HTTP Request`/`Tool` ノードを並列にし、業務システム API(CRM、Git、プロジェクト管理ツールなど)を呼び出して生データを取得 → `Code` ノードまたは `LLM` でデータクレンジングと基礎計算を実行 → `LLM` がトレンド、ハイライト、リスクを分析し、ナラティブなレポートを生成 → `Answer` で画像・テキストを含むドキュメントを出力。複雑さは複数データソースの集約、データ処理、インテリジェント分析の結合にあります。 +5. 契約/ドキュメントのスマート審査と要点抽出(中程度) + 1. アイデア:法的・商業ドキュメントを迅速に審査し、リスクを指摘し、コア条項を抽出。 + 2. 実装:`Start` で契約 PDF をアップロード → `Document Extractor` でテキストを抽出 → `LLM` ノード(法務専門家のロール設定)で責任条項、支払条件、違約条項などを審査 → `Parameter Extractor` ノードで重要な日付、金額、義務当事者などの構造化データを抽出 → `Answer` でリスク提示と要点テーブルを出力。複雑さは長文書の処理と構造化情報抽出にあります。 + +## 3.3 学習・生活ワークフロー + +1. 学術論文ディープ解析とノートジェネレーター(複雑) + 1. アイデア:論文 PDF をアップロードし、構造化されたノートを自動生成。 + 2. 実装:`Start` で PDF をアップロード → `Document Extractor` で全文を抽出 → 複数の `LLM` ノードを並列にして要約、手法、発見、参考文献を分担して要約 → `Variable Aggregator` で集約 → `Answer` で Markdown ノートを出力。複雑さは長文の異なる部分の並列処理にあります。 + +2. パーソナライズ旅行プランカスタマイザー(中程度) + 1. アイデア:ユーザーの好みに基づいて、詳細な旅程を自動計画。 + 2. 実装:`Start` で要件(目的地、日数、予算、興味)を入力 → `Tool` ノードで検索エンジンや地図 API を呼び出して場所の情報を取得 → `LLM` が情報を統合し、毎日の旅程(時間、アクティビティ、予算見積もり)を設計。複雑さは外部情報の取得と構造化された計画にあります。 + +3. 外国語学習インタラクティブ練習パートナー(シンプル) + 1. アイデア:ロールプレイと文法添削ができるチャットボットを作成。 + 2. 実装:AI のロールをシステム設定 → `Start` でユーザーの発言を受信 → `LLM` が2つのタスクを実行:ロールとしての返信 + 文法添削と解説 → `Answer` で出力。コアは LLM のマルチタスク命令です。 + +4. 個人ナレッジベース Q&A とリンク推薦システム(複雑) + 1. アイデア:ブックマークしたドキュメント、ノート、ウェブリンクに基づいて、Q&A ができ、関連する過去のナレッジを推薦できるインテリジェントシステムを構築。 + 2. 実装:オフライン処理:`Document Extractor` と `Embedding` ツールを使って個人ナレッジベースを分割し、ベクトル化して保存。オンラインワークフロー:`Start` で質問を入力 → `Retrieval` ノードでベクトルDBから最も関連するナレッジ断片を検索 → `LLM` が検索されたコンテキストに基づいて回答を生成 → 同時に別の分岐で検索された内容を入力として、`LLM` が「関連する過去のナレッジ」の推薦リストを生成 → `Answer` で回答と推薦を統合して出力。複雑さは検索強化生成(RAG)フローの構築にあります。 + +5. フィットネス/食事プラン追跡と調整アドバイザー(中程度) + 1. アイデア:ユーザーが入力した毎日の食事とトレーニングログに基づいて、栄養分析とトレーニングアドバイスを提供。 + 2. 実装:`Start` でテキストログを入力(例:「昼食:鶏胸肉150g、ご飯一杯、野菜いくつか。トレーニング:スクワット5セット」)→ `Parameter Extractor` ノードで入力データを構造化試行 → `LLM` がフィットネストレーナーの役割で栄養摂取のバランスやトレーニング量の適切さを分析 → 長期目標と比較し、微調整のアドバイス(例:「タンパク質摂取は十分ですが、野菜の種類を増やすことをお勧めします」)を提供。複雑さは非構造化ログからの構造化情報抽出とパーソナライズされたフィードバックにあります。 + +# 6. ワークフロープラットフォームの限界 + +ワークフロープラットフォーム(またはローコードプラットフォーム)は万能のソリューションではありません。ビジネス担当者にとって使いやすく、直接のコーディングのハードルを下げる一方で、別の角度から見ると、「ローコード」もまた「ハイコード」——ユーザーはプラットフォームの概念、ルール、操作ロジックを理解する必要があり、それ自体が新たな学習コストとなります。 + +「多くのシンプルなワークフローは、大規模モデルの関数呼び出しの連鎖に過ぎず、前の関数の出力が後の関数の入力になるだけ。本質的には数行のコードで解決できるのに、なぜあんなに複雑な多重ラッピングのワークフローが必要なのか?むしろ API 呼び出しに不便をもたらす。」と感じるかもしれません。 + +その通りです。現在の vibe coding の急速な発展に伴い、AI のコード生成能力を活用して直接コードを読んだり生成したりする方が効率的な場合もあります。理想としては、自然言語で直接アプリケーションロジックを操作できることが、モダンなソフトウェアプラットフォームの姿です。しかし現在のワークフロープラットフォームはまだこれを実現しておらず、ユーザーの意図と最終実装の間に必然的に「ミドルレイヤー」が存在します。このミドルレイヤーをマスターすること自体が、時間を投資する必要のあるコストです。将来的には、ワークフロープラットフォームも AI による完全自動対話操作をサポートするようになり、AI が本当の意味でワークフローの構築と各パラメーターの設定を操作できるようになることが期待されます。 + +それでも、こうしたプラットフォームを使いこなすことは、Microsoft のオフィスソフトウェアのように、業務において非常に一般的で実用的な基本スキルとして、身につける価値があります。 + +今後の応用コースでは、コードレベルでのワークフローと RAG 開発プラットフォームを使った構築方法を紹介します。その際、異なる実装方法の複雑さと柔軟性の違いを実際に体験できるでしょう。(なお、シンプルな対話アプリケーションやネストされたロジックであれば、ワークフローで実装するのはそれほど難しくない場合もあることに注意してください。) + +# 課題 + +## Dify の基本操作の習得 + +Dify の一般的な基本使用ツールを習得したことを確認するため、1つの基本課題と2つの「ミニチャレンジ」を完了し、一般的な操作に入門したことを確認してください。付属の2つの DSL ファイルを Dify ワークフローにインポートし、対応するワークフローのチャレンジを正常に完了してください(分からない部分はスクリーンショットを撮って大規模モデルに質問するか、各パラメーターの使い方を自分で探索し、最終的に目標を達成してください)。 + +1. インテント分類ワークフローの方法を参考に、大規模モデルに完全に異なるシナリオを提案させ、必ずインテント分類ワークフローを使用するようにしてください。最後に、実行したワークフローのスクリーンショット、シナリオの説明、結果を提出してください。 +2. Log in workflow ワークフロー解読チャレンジ + +この解読チャレンジでは、以下のチャレンジを完了して、ワークフローに次の機能を実装させる必要があります。 + +- 正しいパスワードを見つける! +- パスワードを 0925 に変更する +- パスワードが正しくない場合、2回目の試行機会を提供する(3回目は提供しない) +- ユーザーが再度ログインしたいと言及した場合、パスワード再入力の機会を提供する + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image94.png) + +参考入出力: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image95.png) + +3. Love loop workflow ワークフロー解読チャレンジ + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image96.png) + +この解読チャレンジでは、現在のワークフローの問題を修正し、ワークフローの最終出力が以下のように表示されるようにしてください。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image97.png) + +解決できない問題に遭遇した場合は、スクリーンショットを撮って大規模モデルに質問するか、公式ドキュメントを参照して結果を得てください:[https://docs.dify.ai/en/use-dify/getting-started/quick-start](https://docs.dify.ai/en/use-dify/getting-started/quick-start) + +## Dify API 呼び出しの実装 + +Dify の API 呼び出しの知識を本当に習得したことを確認するため、以下のタスクを完了してください。 + +1. Dify をデプロイし、シンプルなナレッジベースを作成する(好きな資料を選んでください)。 +2. Trae IDE を使ってチャットフロントエンドを構築し、Dify ナレッジベースと API インタラクションを行う。 +3. 複数回の対話の効果をテストし、プログラムが正常に動作することを確認する。 + +最終的な実行スクリーンショットとナレッジベースの処理プロセスのスクリーンショットを提出してください。 + +## サードパーティのワークフローの試用 / 自分の業務ワークフローの構築 + +GitHub、WeChat 公式アカウント、Reddit、Twitter などあらゆる場所で試してみたい他の人の Dify ワークフローを探し、ダウンロードしてインポート後に正常に実行してください。または、上記の業務ワークフロー参考に基づいて、現実の具体的なニーズから自分自身の業務ワークフローを作成して実行してください。 + +最後に、実行成功のスクリーンショットを提出し、そのワークフローの役割を説明してください。 + +# [Bug] HTTP リクエストエラー問題の解決方法 + +以下の図に示すような問題に遭遇した場合のみ、本セクションの方案を参考にしてください。それ以外の場合は無視して構いません。 + +Dify を自分のサーバーにデプロイした場合、サーバーの外部アドレスは通常 HTTP であり HTTPS ではありません。HTTP のみをサポートするサービスにリクエストを送信する際、以下のようなメッセージが表示されることがあります(F12 ブラウザデバッグモードを有効にして、問題のある箇所を確認してください)。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image98.png) + +この問題が発生する原因は、Dify を HTTPS ではなく HTTP のみをサポートするサーバーにデプロイしたためです。HTTPS(HyperText Transfer Protocol Secure)は HTTP(HyperText Transfer Protocol)に SSL/TLS 暗号化レイヤーを追加したもので、「より安全な版の HTTP」と理解できます。 + +サービスで HTTPS をサポートさせるには、一般的に以下の方法があります。 + +- 他のプログラムを使ってリクエストを転送する(例:証明書がある nginx でリバースプロキシを行う) +- ドメイン名をバインドし、そのドメイン名の証明書を申請する + +しかしこれらの操作は比較的複雑なため、ここでは Zeabur をネットワーク転送ゲートウェイとして使用して問題を解決します。 + +Zeabur のウェブページはデフォルトで HTTPS を通じてアクセスされるため、元々リクエストしていたドメインを Zeabur が提供するドメインに転送するだけで、この問題を修正できます。 + +- 元のアドレス:`http://{DIFY_API_URL}/v1/chat-messages` +- 変更後のアドレス:`https://{DIFY_NEW_API_URL}.zeabur.app/v1/chat-messages` + +URL 内のドメイン部分(パブリック IP またはドメイン)を、Zeabur にデプロイ済みのドメインに置き換えるだけで済みます。サービス内には転送機能があらかじめ設定されています。 + +興味がある場合は、自分で Zeabur に転送サービスをデプロイすることもできます。Zeabur でサービスを作成する際に Python を選択し、以下の Python コードを入力してデプロイすると、HTTPS アドレスが取得でき、HTTPS が正常に使用できるようになります。 + +デプロイ完了後、ネットワーク設定でプログラムのリスニングポートをローカル 8080 に設定し、そのポートを外部に公開してください。 + +注意:`{DIFY_API_URL}` を実際の Dify API アドレスに置き換えてください。 + +```python +from flask import Flask, request, Response +import requests + +app = Flask(__name__) + +TARGET_BASE_URL = "{DIFY_API_URL}" +LISTEN_PORT = 8080 + +@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +@app.route('/', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +def proxy_request(path): + target_url = f"{TARGET_BASE_URL}/{path}" + if request.query_string: + target_url += f"?{request.query_string.decode('utf-8')}" + + headers = {key: value for key, value in request.headers if key.lower() not in ['host', 'connection', 'content-length', 'accept-encoding']} + + try: + resp = requests.request( + method=request.method, + url=target_url, + headers=headers, + data=request.get_data(), + cookies=request.cookies, + allow_redirects=False, + timeout=30 + ) + + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + response_headers = [(name, value) for name, value in resp.raw.headers.items() if name.lower() not in excluded_headers] + + return Response(resp.content, resp.status_code, response_headers) + + except requests.exceptions.RequestException as e: + print(f"Error forwarding request to {target_url}: {e}") + return Response(f"Proxy Error: Could not reach target server or invalid response: {e}", status=502) + except Exception as e: + print(f"An unexpected error occurred: {e}") + return Response(f"Internal Proxy Error: {e}", status=500) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=LISTEN_PORT, debug=True) +``` diff --git a/docs/ja-jp/stage-2/assignments/copywriting-platform-supabase/index.md b/docs/ja-jp/stage-2/assignments/copywriting-platform-supabase/index.md new file mode 100644 index 0000000..61cb9fe --- /dev/null +++ b/docs/ja-jp/stage-2/assignments/copywriting-platform-supabase/index.md @@ -0,0 +1,346 @@ +# AI マーケティングコピー SaaS 開発実践 + +## 概要 + +本実践プロジェクトでは、実際の PRD(要件定義書)に基づき、独立開発者やコンテンツチーム向けの AI マーケティングコピー SaaS 製品をゼロから構築します。Supabase をバックエンドサービスとして、Stripe を決済システムとして使用し、要件分析からデプロイまでの全プロセスを完了します。 + +これは Stage 2 の総合実践セクションです。これまでの章で、フロントエンドページの構築、バックエンドインターフェースの開発、データベース操作、決済統合などの個別スキルを学びました。このプロジェクトでは、それらすべてを統合し、実行可能な製品プロトタイプを納品します。 + +## 前提知識 + +本プロジェクトを開始する前に、以下の内容を習得している必要があります: + +- フロントエンドページ設計とコンポーネントライブラリの使用([UI 設計](../../frontend/ui-design/)、[モダンコンポーネントライブラリ](../../frontend/modern-component-library/)) +- バックエンドインターフェースの設計と開発([インターフェースコードの記述](../../backend/ai-interface-code/)) +- データベースの基礎と Supabase([データベースから Supabase へ](../../backend/database-supabase/)) +- 決済統合([Stripe 決済システム](../../backend/stripe-payment/)) +- Git ワークフローとデプロイ([Git と GitHub](../../backend/git-workflow/)、[Web アプリケーションのデプロイ](../../backend/zeabur-deployment/)) + +## 学習目標 + +本実践を完了すると、以下のことができるようになります: + +1. 実際の PRD を読み解き、開発タスクリストを抽出する +2. AI を活用して段階的にフロントエンドページとバックエンドインターフェースを生成する +3. Supabase を使用してユーザー認証、データベース操作を実装する +4. Stripe を統合して有料サブスクリプション機能を実装する +5. 管理画面を構築し、エンドツーエンドの結合テストを完了する + +## プロジェクト概要 + +構築する製品は AI マーケティングコピー SaaS であり、3つのサブシステムで構成されます: + +| サブシステム | 責務 | +|--------|------| +| **公式サイト** | 製品紹介、料金プラン、FAQ、登録コンバージョン | +| **ユーザーワークスペース** | 製品情報の入力、コピー生成、履歴確認、プランのアップグレード | +| **管理画面** | ユーザー管理、生成記録、決済データ、運用概要 | + +バックエンドは Supabase でデータベースと認証機能を提供し、Stripe で決済を処理し、AI モデルでマーケティングコピーを生成します。 + +::: tip PRD 入口 +本プロジェクトの要件定義書は GitHub にあります: [PRD を確認](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/copywriting-platform-supabase/PRD.md) +::: + +
+ + + +
+ +## 第1部:要件分析 + +### 1.1 PRD の読解 + +PRD 文書を開き、以下の質問に重点的に答えてください: + +- システムにはいくつの入口がありますか?それぞれどのページをカバーしていますか? +- 各ページのコア機能は何ですか? +- バックエンドにはどのモジュールとデータテーブルが含まれていますか? +- 料金プラン、決済フロー、無料枠はどのように設計されていますか? +- MVP の範囲は何ですか?初版で何を作り、何を作らないか? + +::: warning +上記の質問に明確な答えがない場合は、コードを書き始めないでください。要件の理解が不明確であることは、手戻りの最も一般的な原因です。 +::: + +### 1.2 システムアーキテクチャの確認 + +PRD に基づいてシステムの全体アーキテクチャを整理します: + +```mermaid +flowchart TD + prd["PRD"] --> web["公式サイト"] + prd --> app["ユーザーワークスペース"] + prd --> admin["管理画面"] + app --> auth["認証"] + app --> gen["コピー生成タスク"] + gen --> db["データベース"] + billing["決済とプラン"] --> db + admin --> analytics["ユーザー / 生成 / 決済ダッシュボード"] +``` + +## 第2部:プロジェクトスケルトンの構築 + +### 2.1 フロントエンドページの生成 + +AI を使用して、まずすべてのページの基本構造とモックデータを生成します。 + +プロンプトの参考例: + +```text +現在の PRD に基づいて、AI マーケティングコピー SaaS のフロントエンドスケルトンを生成してください。 + +要件: +1. 3つの入口に分ける:www、app、admin +2. 公式サイトには:ホーム、料金プラン、FAQ +3. app には:ログイン、登録、生成ワークスペース、履歴、プランページ +4. admin には:管理画面ホーム、ユーザー管理、生成記録、決済オーダー +5. まずページ構造とモックデータのみを生成し、実際のインターフェースには接続しない +6. モダンな SaaS のようなスタイルにし、授業のデモのような見た目にしない +``` + +### 2.2 コアページの充実 + +スケルトンができたら、コピー生成ワークスペース(Dashboard)ページを重点的に充実させます: + +```text +/dashboard ページをさらに充実させてください。 + +これは AI マーケティングコピーのワークスペースです。 + +左側のフォームフィールド: +- 製品名 +- 一言での紹介 +- ターゲットユーザー +- 3つのセールスポイント +- 配信チャネル(公式サイト、WeChat モーメンツ、小紅書、Douyin、メール) + +右側の結果エリアの予約: +- メインタイトル +- サブタイトル +- CTA +- 3パターンの短いコピー +- 長いコピー + +まずモックデータでインタラクションを動作させる。 + +要件: +- 「コピー生成」クリック後にローディング状態を表示 +- 結果エリアに空の状態をデザイン +- レスポンシブレイアウトで、ワイド画面でもナロー画面でも正常に表示 +``` + +### 2.3 ページ構造の検証 + +各項目をチェック: + +- [ ] 3つの入口のルーティングが独立しているか +- [ ] ページ数が PRD と一致しているか +- [ ] Dashboard のフォームと結果エリアのレイアウトが適切か +- [ ] モックデータが基本的な UI の状態を表現しているか + +### 行き詰まったら + +フロントエンド構築の段階で行き詰まった場合は、以下の章を振り返ってください: + +- [UI 設計](../../frontend/ui-design/) +- [UI 設計仕様を参考にページとボタンを設計](../../frontend/multi-product-ui/) +- [LLM と Skills でインターフェースを見栄えよくする](../../frontend/llm-skills-beautiful/) +- [デザインプロトタイプからプロジェクトコードへ](../../frontend/design-to-code/) +- [モダンコンポーネントライブラリでインターフェースをアップデート](../../frontend/modern-component-library/) + +## 第3部:バックエンド統合 + +### 3.1 Supabase ログインの統合 + +```text +私はプログラミング初心者です。ステップバイステップで Supabase のログイン統合を案内してください。 + +私のために以下を完了してください: +1. プロジェクトに Supabase を統合 +2. 登録、ログイン、ログアウト機能を実装 +3. ログイン成功後に /dashboard にリダイレクト +4. 未ログインユーザーが /dashboard、/billing、/admin にアクセスした場合、自動的に /login にリダイレクト +5. profiles テーブルを作成 +6. ユーザー登録成功後、自動的に profiles テーブルにレコードを作成 +7. profiles テーブルには email、role、plan フィールドを含める + +実装要件: +- 各ステップでどのファイルを変更しているかを説明 +- 秘密鍵をハードコーディングしない +- Supabase 管理画面で手動操作が必要な箇所は明確に記載 +- 完了後、登録とログインの確認方法を説明 +``` + +### 3.2 生成インターフェースとデータベースの統合 + +```text +私はプログラミング初心者です。サイトのコア機能である「マーケティングコピーの生成と保存」を実装するのを手伝ってください。 + +目標とする効果: +1. ユーザーが /dashboard でフォームに入力し、「コピー生成」をクリック +2. バックエンドが受け取る:製品名、紹介、ターゲットユーザー、セールスポイント、配信チャネル +3. バックエンドがモデルを呼び出して結果を生成 +4. ページに生成結果を表示 +5. 入力と出力の両方をデータベースに保存 +6. ユーザーが次回アクセス時に履歴を確認可能 + +私のために以下を完了してください: +- 生成インターフェース /api/generate を作成 +- generations テーブルを作成 +- 入力と出力のフィールドを設計 +- Dashboard ページで現在のユーザーの履歴を読み込む + +ユーザーエクスペリエンス: +- ボタンのローディング状態 +- 生成失敗時のエラーメッセージ +- 履歴がない場合の空の状態 + +完了後、以下を説明してください: +- フロントエンドページファイルの場所 +- バックエンドインターフェースファイルの場所 +- データベースへの書き込みロジックの場所 +- 完全な生成チェーンのテスト方法 +``` + +### 3.3 Stripe 決済の統合 + +```text +私はプログラミング初心者です。LaunchKit に最小限の Stripe 決済を追加するのを手伝ってください。 + +複雑なシステムは不要で、まず最基本的な決済フローを動作させます。 + +私のために以下を完了してください: +1. /billing ページに free と pro の2つのプランを表示 +2. ユーザーがアップグレードをクリックした後、Stripe Checkout にリダイレクト +3. 決済成功後にサイトに戻る +4. 決済結果を subscriptions テーブルに保存 +5. profile.plan フィールドを同期的に更新 +6. free ユーザーは1日3回まで生成可能、pro ユーザーは無制限 + +実装原則: +- まずメインフローを動作させ、複雑なエッジケースは後回し +- Stripe 管理画面での設定が必要な箇所は明確に記載 +- 完了後、完全な決済フローのテスト方法を説明 +``` + +### 3.4 管理画面の構築 + +```text +私はプログラミング初心者です。シンプルで使いやすい管理画面を作成してください。 + +管理者のみアクセス可能。 + +私のために以下を完了してください: +1. role = admin のユーザーのみ /admin にアクセス可能 +2. 管理画面には3つのタブを含める:ユーザーリスト、生成記録、サブスクリプション状況 +3. ユーザーリストの表示:email、plan、作成日時 +4. 生成記録の表示:ユーザー、製品名、チャネル、作成日時 +5. サブスクリプション状況の表示:ユーザー、プラン、決済ステータス + +要件: +- インターフェースはシンプルで見やすく +- 既存のコンポーネントライブラリのテーブル、タブ、バッジを使用 +- 完了後、アカウントを管理者に設定する方法を説明 +``` + +### 行き詰まったら + +バックエンド開発の段階で行き詰まった場合は、以下の章を振り返ってください: + +- [データベースから Supabase へ](../../backend/database-supabase/) +- [大規模言語モデルによるインターフェースコードとインターフェース文書の作成支援](../../backend/ai-interface-code/) +- [Stripe などの決済システムの統合方法](../../backend/stripe-payment/) + +## 第4部:結合テストとデプロイ + +### 4.1 エンドツーエンドテスト + +少なくとも以下のシナリオを検証してください: + +- 登録 → ログイン → コピー生成 → 履歴確認 → プランのアップグレード +- 管理者のログイン → ユーザーデータの確認 → 生成記録の確認 → 決済ステータスの確認 + +デプロイ前チェック: + +```text +私はプログラミング初心者です。プロジェクトがデプロイ可能かどうかを確認するのを手伝ってください。 + +チェックのポイント: +- 環境変数は完全か +- ログインのコールバックアドレスは正しいか +- Stripe 決済のコールバックアドレスは正しいか +- ページにローディング、空の状態、エラーメッセージが欠落していないか +- README に起動説明とデプロイ説明が含まれているか + +私のために以下をしてください: +1. 優先度順に修正項目をリストアップ +2. どれを先に修正すべきかをマーク +3. 修正後のデプロイ手順を説明 +``` + +### 4.2 デプロイ + +プロジェクトをパブリックネットワーク環境にデプロイします。デプロイのチュートリアルはこちらを参照してください:[Git と GitHub ワークフロー](../../backend/git-workflow/)、[Web アプリケーションのデプロイ方法](../../backend/zeabur-deployment/)。 + +## 提出物 + +本プロジェクト完了後、以下の内容を提出してください: + +- [ ] アクセス可能なオンラインデモリンク +- [ ] ソースコードリポジトリのリンク(README を含む) +- [ ] PRD 文書 +- [ ] コアページのスクリーンショット(ホーム、Dashboard、Billing、Admin) +- [ ] 60秒のデモ動画(登録 → 生成 → 決済 → 管理画面を網羅) + +README には少なくとも以下を含めてください:プロジェクト概要、コアページの説明、技術スタック、ローカル起動手順、環境変数リスト。 + +## 評価基準 + +| 項目 | 基本要件 | 応用要件 | +|------|---------|---------| +| 製品の完成度 | ホーム、ログイン、Dashboard、Billing、Admin にすべてアクセス可能 | ホームのコピーとビジュアルスタイルが本物の SaaS のように見える | +| ビジネス完了 | 登録 → ログイン → 生成 → 履歴確認が動作する | 無料 / Pro の権限差が明確に確認できる | +| データの正確性 | 生成結果と決済ステータスがデータベースに書き込まれる | 明確なエラーメッセージ、空の状態、ローディングがある | +| 権限とセキュリティ | 未ログインで保護されたページにアクセスできず、一般ユーザーは Admin に入れない | 基本的な入力バリデーションとサーバーサイド認証がある | +| エンジニアリング品質 | プロジェクトがローカルで起動可能で、パブリックネットワークにもデプロイ可能 | README が明確で、デモ動画の構造が完全 | + +::: tip +タスクが大きすぎると感じた場合は、この原則を覚えておいてください:**まず「動くこと」を確保してから、「美しくすること」を追求してください。** +::: + +## 提出前チェック + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## 参考資料 + +- [UI 設計](../../frontend/ui-design/) +- [UI 設計仕様を参考にページとボタンを設計](../../frontend/multi-product-ui/) +- [LLM と Skills でインターフェースを見栄えよくする](../../frontend/llm-skills-beautiful/) +- [デザインプロトタイプからプロジェクトコードへ](../../frontend/design-to-code/) +- [モダンコンポーネントライブラリでインターフェースをアップデート](../../frontend/modern-component-library/) +- [データベースから Supabase へ](../../backend/database-supabase/) +- [大規模言語モデルによるインターフェースコードとインターフェース文書の作成支援](../../backend/ai-interface-code/) +- [Git と GitHub ワークフロー](../../backend/git-workflow/) +- [Web アプリケーションのデプロイ方法](../../backend/zeabur-deployment/) +- [Stripe などの決済システムの統合方法](../../backend/stripe-payment/) diff --git a/docs/ja-jp/stage-2/assignments/custom-dify-agent-platform/index.md b/docs/ja-jp/stage-2/assignments/custom-dify-agent-platform/index.md new file mode 100644 index 0000000..632d611 --- /dev/null +++ b/docs/ja-jp/stage-2/assignments/custom-dify-agent-platform/index.md @@ -0,0 +1,208 @@ +# Dify 型エージェントプラットフォーム開発実践 + +## 概要 + +本実践プロジェクトでは、実際の PRD に基づいて、Dify のコア体験を模倣したエージェントプラットフォームを一から完成させます。ユーザーコンソール、管理バックエンド、プラットフォームバックエンドを構築し、エージェント管理、対話、ログ、ナレッジベースなどのコア機能を実装します。 + +これは Stage 2 の総合実践セクションです。これまでの単一ページや単一機能のプロジェクトとは異なり、このプロジェクトでは「プラットフォーム感」のある AI 製品を構築する必要があります。マルチロール、マルチモジュール、データ永続化、モデル呼び出しパイプラインを含みます。 + +## 前提知識 + +このプロジェクトを始める前に、以下の内容をすでに習得している必要があります: + +- フロントエンドページ設計とコンポーネントライブラリの使用([UI 設計](../../frontend/ui-design/)、[モダンコンポーネントライブラリ](../../frontend/modern-component-library/)) +- バックエンドインターフェース設計と開発([インターフェースコード作成](../../backend/ai-interface-code/)) +- データベース基礎と Supabase([データベースから Supabase まで](../../backend/database-supabase/)) +- Git ワークフローとデプロイ([Git と GitHub](../../backend/git-workflow/)、[Web アプリのデプロイ](../../backend/zeabur-deployment/)) + +## 学習目標 + +本実践完了後、以下のことができるようになります: + +1. 実際の PRD を読み、開発タスクリストを抽出する +2. エージェントプラットフォームのページアーキテクチャとデータモデルを設計する +3. エージェント作成、対話、ログ記録の完全なパイプラインを実装する +4. AI を活用してプラットフォーム型製品の開発を完了する +5. エンドツーエンドの結合テストを完了し、デモ可能な AI プラットフォームプロトタイプを納品する + +## プロジェクト概要 + +あなたが構築する製品は、Dify 型エージェントプラットフォームです。2 つのサブシステムを含みます: + +| サブシステム | 責務 | +|--------|------| +| **ユーザーコンソール** | エージェント作成、Prompt 設定、対話開始、ログ確認、ナレッジベース管理 | +| **管理バックエンド** | ユーザーデータ、プラットフォームリソース使用状況、呼び出し統計の確認 | + +バックエンドは以下のコア機能をサポートする必要があります:エージェント管理、セッション管理、メッセージ保存、モデル呼び出し、呼び出しログ記録、ナレッジベース接続。 + +::: tip PRD 入口 +本プロジェクトの要件文書は GitHub にあります: [PRD を表示](https://github.com/datawhalechina/easy-vibe/blob/main/docs/ja-jp/stage-2/assignments/custom-dify-agent-platform/PRD.md) +::: + +
+ + + +
+ +## 第 1 部:要件分析 + +### 1.1 PRD を読む + +PRD 文書を開き、以下の質問に重点的に答えてください: + +- エージェント、セッション、ログ、ナレッジベースのうち、どれを MVP に入れますか? +- ページとルートのリストは確定していますか? +- モデル呼び出しとログ記録の境界は何ですか? +- マルチテナントや複雑なワークフローはまず実装しませんか? + +::: warning +以上の質問に対する明確な答えがない場合は、コードを書き始めないでください。要件の理解が不明確なのは、手戻りの最も一般的な原因です。 +::: + +### 1.2 システムアーキテクチャの確認 + +```mermaid +flowchart TD + prd["PRD"] --> app["ユーザーコンソール"] + prd --> admin["管理バックエンド"] + app --> auth["認証"] + app --> agent["エージェント設定"] + app --> chat["セッション対話"] + chat --> llm["モデル呼び出し"] + chat --> db["データベース"] + app --> kb["ナレッジベース接続"] + admin --> logs["呼び出しログとプラットフォーム概要"] + logs --> db +``` + +## 第 2 部:プロジェクトスケルトンの構築 + +### 2.1 フロントエンドページの生成 + +プロンプト参考: + +```text +現在の PRD に基づいて、Dify 型エージェントプラットフォームのフロントエンドスケルトンを生成してください。 + +要件: +1. ユーザー側には以下を含む:ログイン、エージェントリスト、エージェント設定、対話ページ、ログページ、ナレッジベースページ +2. 管理側には以下を含む:管理ホーム、ユーザー概要、リソース使用概要 +3. まずページ構造とモックデータのみを生成し、実際のインターフェースには接続しない +4. モダンな AI プラットフォームのようなスタイルにする +``` + +### 2.2 プロジェクト構造の検証 + +項目ごとにチェック: + +- [ ] ユーザーコンソールと管理バックエンドのエントリが分離されている +- [ ] エージェントリスト、設定、対話、ログ、ナレッジベースページが完全 +- [ ] 管理バックエンドのホーム、ユーザー概要ページがアクセス可能 +- [ ] モックデータで基本的な UI ステータスが表示されている + +## 第 3 部:反復開発 + +### 3.1 モジュールごとに進める + +スケルトンをベースに、以下の順序でモジュールごとに機能を追加: + +1. **認証**:登録、ログイン、ロール区分 +2. **エージェント管理**:作成、編集、削除、Prompt 設定 +3. **対話機能**:セッション作成、メッセージ送受信、モデル呼び出し +4. **ログ記録**:所要時間、トークン使用量、エラー記録 +5. **ナレッジベース接続**(ボーナス):ドキュメントアップロード、検索、結果注入 +6. **管理バックエンド**:ユーザーデータ、リソース使用状況、呼び出し統計 + +各モジュール完了後、以下の表で自己チェック: + +| チェック項目 | 検証方法 | +|--------|----------| +| ページ整合性 | ページ数、機能が PRD に適合しているか | +| インターフェースクロージャ | agents、chat、logs、knowledge のインターフェースが完全か | +| 権限分離 | ユーザーが自分のエージェントとセッションのみを管理できるか | +| データ整合性 | messages、logs、documents のデータが一致しているか | +| デモ可能性 | 「エージェント作成 → 対話 → ログ確認」の完全なフローがデモできるか | + +### 3.2 ナレッジベース接続(ボーナス) + +ナレッジベース機能を追加したい場合、各エージェントに「ナレッジベーススイッチ」を追加できます: + +- オンにした場合、まずナレッジ断片を検索し、ユーザーの質問と一緒にモデルに送信 +- オフにした場合、通常の対話モードで応答 + +第 1 版では複雑な RAG を追求せず、「検索結果が可視で、呼び出しパイプラインが説明可能」であれば十分です。 + +## 第 4 部:結合テストとリリース + +### 4.1 エンドツーエンドテスト + +少なくとも以下のシナリオを検証: + +- 登録 → エージェント作成 → Prompt 設定 → 対話開始 → ログ確認 +- 管理者ログイン → ユーザーデータ確認 → 呼び出し統計確認 + +デプロイ前チェック: + +- [ ] すべてのコアインターフェースにログインチェックがある +- [ ] エージェントの所有権限チェックが通っている +- [ ] セッション記録、ログ記録が実際にデータベースに保存されている +- [ ] モデルキーが環境変数を使用しており、ハードコードされていない +- [ ] エラーがフロントエンドで確認でき、コンソールのみに出力されていない + +### 4.2 デプロイ + +プロジェクトをパブリックネットワークにデプロイ。デプロイチュートリアル参照:[Git と GitHub ワークフロー](../../backend/git-workflow/)、[Web アプリのデプロイ方法](../../backend/zeabur-deployment/)。 + +## 提出物 + +本プロジェクト完了後、以下の内容を提出する必要があります: + +- [ ] アクセス可能なオンラインデモリンク +- [ ] ソースコードリポジトリリンク(README を含む) +- [ ] PRD 文書 +- [ ] コアページのスクリーンショット(エージェント管理ページ、対話ページ、ログページ、管理ホーム) +- [ ] 60 秒のデモ動画(エージェント作成 → 対話 → ログ確認をカバー) + +README には少なくとも以下を含む:プロジェクト概要、アーキテクチャ説明、技術スタック、ローカル起動手順、環境変数リスト、インターフェース説明。 + +## 評価基準 + +| 項目 | 基本要件 | 応用要件 | +|------|---------|---------| +| プラットフォーム完成度 | agents / chat / logs の 3 ページが利用可能 | 明確なナビゲーションと統一されたデザイン言語がある | +| ビジネスクロージャ | エージェントを作成して実際に対話できる | マルチエージェント切り替えと履歴セッションをサポート | +| データとトラッキング | メッセージと呼び出しログがクエリ可能 | トークン / 所要時間の統計ダッシュボードがある | +| 権限セキュリティ | ログインユーザーのみがコアインターフェースにアクセス可能 | リソース所有権の検証が充実 | +| エンジニアリング納品 | デプロイ可能、デモ可能、README が明確 | ナレッジベースを接続し、検索結果を説明可能 | + +## 提出前チェック + + + + +
    +
  • +
  • +
  • +
  • +
  • +
+
+ +## 参考資料 + +- [UI 設計](../../frontend/ui-design/) +- [モダンコンポーネントライブラリでインターフェースを更新](../../frontend/modern-component-library/) +- [データベースから Supabase まで](../../backend/database-supabase/) +- [大規模モデルによるインターフェースコードとドキュメント作成](../../backend/ai-interface-code/) +- [Git と GitHub ワークフロー](../../backend/git-workflow/) +- [Web アプリのデプロイ方法](../../backend/zeabur-deployment/) diff --git a/docs/ja-jp/stage-2/assignments/exam-management-express/index.md b/docs/ja-jp/stage-2/assignments/exam-management-express/index.md new file mode 100644 index 0000000..cf8a6af --- /dev/null +++ b/docs/ja-jp/stage-2/assignments/exam-management-express/index.md @@ -0,0 +1,306 @@ +# オンライン試験・管理システム開発実践 + +## 概要 + +本実践プロジェクトでは、実際の PRD(要件定義書)に基づき、オンライン試験・管理システムをゼロから構築します。このプロジェクトの特徴は、複数のロール(学生と管理者)が存在し、各ロールによって表示されるページや実行可能な操作が異なる点にあります。Express を使用してバックエンドを構築し、試験業務の完全なフローを実装します。 + +これは Stage 2 の総合実践セクションです。マルチロール権限システムは実際の業務でも非常に一般的であり、このパターンを習得すれば、教育、SaaS、管理画面など、あらゆる業務シナリオに対応できるようになります。 + +## 前提知識 + +本プロジェクトを開始する前に、以下の内容を習得している必要があります: + +- フロントエンドページ設計とコンポーネントライブラリの使用([UI 設計](../../frontend/ui-design/)、[モダンコンポーネントライブラリ](../../frontend/modern-component-library/)) +- バックエンドインターフェースの設計と開発([インターフェースコードの記述](../../backend/ai-interface-code/)) +- データベースの基礎と Supabase([データベースから Supabase へ](../../backend/database-supabase/)) +- Git ワークフローとデプロイ([Git と GitHub](../../backend/git-workflow/)、[Web アプリケーションのデプロイ](../../backend/zeabur-deployment/)) + +## 学習目標 + +本実践を完了すると、以下のことができるようになります: + +1. 実際の PRD を読み解き、開発タスクリストを抽出する +2. マルチロールシステムの権限制御とページルーティングを設計する +3. Express を使用して完全なバックエンド API を実装する +4. 試験、提出、自動採点の業務フローを実装する +5. エンドツーエンドの結合テストを完了し、デモ可能な業務システムプロトタイプを納品する + +## プロジェクト概要 + +構築する製品は、オンライン試験・管理システムであり、3つのサブシステムで構成されます: + +| サブシステム | 責務 | +|--------|------| +| **公式サイト** | プラットフォーム紹介、ログイン入口 | +| **学生画面** | 試験一覧、解答、提出、成績確認 | +| **管理画面** | 問題バンク管理、試験管理、提出記録、成績統計 | + +バックエンドは Express を使用し、以下をサポートする必要があります:ログイン認証、ロール権限、試験と問題バンクの管理、提出フローと自動採点、成績と統計管理。 + +::: tip PRD 入口 +本プロジェクトの要件定義書は GitHub にあります: [PRD を確認](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/exam-management-express/PRD.md) +::: + +
+ + + +
+ +## 第1部:要件分析 + +### 1.1 PRD の読解 + +PRD 文書を開き、以下の質問に重点的に答えてください: + +- システムにはいくつのロールがありますか?それぞれ何ができますか? +- ページ一覧は完全ですか?学生画面と管理画面にそれぞれどのページがありますか? +- どの問題形式をサポートしていますか?各形式の採点ロジックは何ですか? +- 試験の完全なフローは何ですか?(公開 → 開始 → 解答 → 提出 → 採点 → 成績確認) + +::: warning +上記の質問に明確な答えがない場合は、コードを書き始めないでください。要件の理解が不明確であることは、手戻りの最も一般的な原因です。 +::: + +### 1.2 システムアーキテクチャの確認 + +PRD に基づいてシステムの全体アーキテクチャを整理します: + +```mermaid +flowchart TD + prd["PRD"] --> web["公式サイト"] + prd --> student["学生画面"] + prd --> admin["管理画面"] + student --> auth["認証"] + student --> exam["試験と解答"] + exam --> db["データベース"] + admin --> question["問題バンク管理"] + admin --> submission["提出記録と成績統計"] + question --> db + submission --> db +``` + +## 第2部:プロジェクトスケルトンの構築 + +### 2.1 フロントエンドページの生成 + +プロンプトの参考例: + +```text +現在の PRD に基づいて、オンライン試験・管理システムのフロントエンドスケルトンを生成してください。 + +技術スタックの要件: +- Next.js App Router +- TypeScript +- Tailwind CSS +- shadcn/ui + +ページ一覧: +1. ホーム / +2. ログインページ /login +3. 学生試験一覧ページ /student/exams +4. 学生解答ページ /student/exams/[id] +5. 学生成績ページ /student/history +6. 管理画面ホーム /admin +7. 試験管理ページ /admin/exams +8. 問題バンク管理ページ /admin/questions +9. 提出記録ページ /admin/submissions + +要件: +- 学生画面は見やすく、集中して解答しやすいデザインにする +- 管理画面はサイドバー+トップバーのレイアウトを使用 +- まずモックデータを使用し、実際のインターフェースには接続しない +- デスクトップとモバイルの基本的な使いやすさに配慮する +``` + +### 2.2 学生解答ページの充実 + +解答ページは学生画面のコアページです。以下を重点的に実装してください: + +```text +学生の解答ページをさらに充実させてください。 + +これはオンライン試験システムの解答ページで、以下を含める必要があります: +- 上部に試験タイトル、カウントダウン、解答済み問題数を表示 +- 中央に問題文と選択肢を表示 +- 単一選択、正誤判定、記述の3つの問題形式をサポート +- 左側または上部に解答カードを配置し、各問題の解答状況を表示 +- 提出前に確認ダイアログを表示 + +まずモックデータでインタラクションを実装し、実際のインターフェースには接続しない。 + +要件: +- インターフェースはシンプルにし、管理画面のテーブルページのような見た目にしない +- カウントダウンは目立つようにするが、過度なプレッシャーを与えない +- 空の状態とローディング状態を含める +``` + +### 2.3 管理画面の充実 + +管理画面の初版は3つのコア領域に焦点を当てます: + +- **試験管理**:試験の作成、時間の設定、公開ステータス +- **問題バンク管理**:問題の追加、編集、問題形式によるフィルタリング +- **提出記録**:学生の提出、スコア、時間の確認 + +### 2.4 ページ構造の検証 + +各項目をチェック: + +- [ ] 学生画面と管理画面の入口が分離されているか +- [ ] ログインページ、試験一覧、解答ページ、成績ページが完全か +- [ ] 管理画面の問題バンク、試験管理、提出記録ページにアクセスできるか +- [ ] 学生画面と管理画面のデザインに明確な差異があるか + +### 行き詰まったら + +フロントエンド構築の段階で行き詰まった場合は、以下の章を振り返ってください: + +- [データベースから Supabase へ](../../backend/database-supabase/) +- [アプリケーションバックエンドインターフェースの設計と開発](../../backend/ai-interface-code/) +- [モダンコンポーネントライブラリでインターフェースをアップデート](../../frontend/modern-component-library/) + +## 第3部:バックエンド開発 + +### 3.1 ログインと権限制御 + +```text +私はプログラミング初心者です。オンライン試験システムのログインと権限制御を実装するのを手伝ってください。 + +バックエンドには Express を使用します。 + +目標: +1. 学生と管理者の両方がログインできる +2. ログイン後にユーザーロールを返す +3. 学生は /student/* 関連のインターフェースにのみアクセスできる +4. 管理者は /admin/* 関連のインターフェースにのみアクセスできる +5. 未ログインユーザーが保護されたページにアクセスした場合、/login にリダイレクトする + +実装要件: +- 明確なディレクトリ構造の提案を提供する +- ミドルウェアの責務を明確に説明する +- 環境変数に関わる部分はハードコーディングしない +- 完了後、権限が正しく機能しているかの確認方法を説明する +``` + +### 3.2 試験と問題バンク管理インターフェース + +以下のモジュールごとに実装することをお勧めします: + +| モジュール | 推奨インターフェース | +|------|----------| +| 試験管理 | `GET /api/exams`、`POST /api/admin/exams`、`PATCH /api/admin/exams/:id` | +| 問題バンク管理 | `GET /api/admin/questions`、`POST /api/admin/questions` | +| 試験開始 | `POST /api/submissions/start` | +| 答案提出 | `POST /api/submissions/:id/submit` | +| 成績記録 | `GET /api/student/history`、`GET /api/admin/submissions` | + +プロンプトの参考例: + +```text +オンライン試験システムの Express API を設計・実装してください。 + +機能範囲: +- 管理者が試験を作成 +- 管理者が問題バンクを管理 +- 学生が公開済みの試験を閲覧 +- 学生が試験を開始し、submission を作成 +- 学生が答案を提出した後、単一選択問題と正誤判定問題を自動採点 +- 記述問題はまず「要レビュー」としてマーク +- 学生が自分の過去の成績を閲覧 +- 管理者がすべての提出記録を閲覧 + +要件: +- インターフェース名は明確に +- 統一された JSON 構造を返す +- コード内で controller、service、middleware、db 層を区別する +- 各インターフェースのテスト方法を説明する +``` + +### 3.3 採点ロジック + +採点ロジックは試験システムのコアとなるビジネスルールです: + +- **単一選択問題**:ユーザーの回答が正解と一致すれば得点 +- **正誤判定問題**:同様に自動採点可能 +- **記述問題**:初版では回答のみを保存し、スコアは空欄、ステータスを `reviewed = false` とする + +::: tip ボーナス項目 +AI 機能を追加したい場合は、管理者が「トピック + 難易度」を入力すると、モデルが候補問題を生成し、それを人工でレビュー後に問題バンクに登録する、という仕組みも可能です。ただし、これはボーナス項目であり必須ではありません。 +::: + +## 第4部:結合テストとデプロイ + +### 4.1 エンドツーエンドテスト + +少なくとも以下のシナリオを検証してください: + +- 学生のログイン → 試験一覧の確認 → 解答開始 → 提出 → 成績確認 +- 管理者のログイン → 試験の作成 → 問題の追加 → 公開 → 提出記録の確認 + +### 4.2 デプロイ + +- フロントエンドを Vercel / Zeabur にデプロイ +- Express API を Zeabur / Railway / Render にデプロイ +- データベースは Supabase Postgres またはマネージド PostgreSQL を使用 + +デプロイ前のチェック: + +- [ ] 環境変数は揃っているか +- [ ] フロントエンドとバックエンドの API アドレスは正しいか +- [ ] 本番環境でログイン状態は正常に機能するか +- [ ] 管理者アカウントで管理画面に実際にアクセスできるか +- [ ] README に起動、デプロイ、テストの説明が含まれているか + +## 提出物 + +本プロジェクト完了後、以下の内容を提出してください: + +- [ ] アクセス可能なオンラインデモリンク +- [ ] ソースコードリポジトリのリンク(README を含む) +- [ ] PRD 文書 +- [ ] コアページのスクリーンショット(ホーム、学生試験一覧、解答ページ、管理画面) +- [ ] 60秒のデモ動画(学生の解答フローと管理者の管理フローを網羅) + +README には少なくとも以下を含めてください:プロジェクト概要、コアページの説明、技術スタック、ローカル起動手順、環境変数リスト。 + +## 評価基準 + +| 項目 | 基本要件 | 応用要件 | +|------|---------|---------| +| ページの完全性 | 学生画面と管理画面の主要ページにアクセス可能 | ページのデザインが統一され、モバイルでも基本的に利用可能 | +| ビジネス完了 | 学生がログイン、試験参加、提出、成績確認が可能 | 管理者が試験の作成から公開まで完全に実行可能 | +| データの正確性 | 提出した回答がデータベースに書き込まれ、客観問題が自動採点される | 記述問題が手動レビューまたは AI 支援をサポート | +| 権限制御 | 学生と管理者のアクセス境界が明確 | サーバーサイドのインターフェースにもロール検証がある | +| エンジニアリング品質 | プロジェクトが実行可能、デプロイ可能、README が明確 | デモ動画とテスト説明がある | + +## 提出前チェック + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## 参考資料 + +- [UI 設計](../../frontend/ui-design/) +- [モダンコンポーネントライブラリでインターフェースをアップデート](../../frontend/modern-component-library/) +- [データベースから Supabase へ](../../backend/database-supabase/) +- [大規模言語モデルによるインターフェースコードとインターフェース文書の作成支援](../../backend/ai-interface-code/) +- [Git と GitHub ワークフロー](../../backend/git-workflow/) +- [Web アプリケーションのデプロイ方法](../../backend/zeabur-deployment/) diff --git a/docs/ja-jp/stage-2/assignments/modern-landing-page/index.md b/docs/ja-jp/stage-2/assignments/modern-landing-page/index.md new file mode 100644 index 0000000..5bd18c1 --- /dev/null +++ b/docs/ja-jp/stage-2/assignments/modern-landing-page/index.md @@ -0,0 +1,211 @@ +# モダン AI 画像生成 SaaS 開発実践 + +## 概要 + +本実践プロジェクトでは、実際の PRD(要件定義書)に基づき、Midjourney の体験を参考にした AI 画像生成 SaaS 製品をゼロから構築します。要件分析、プロジェクト分割、反復開発、結合テストとデプロイまでの全プロセスを経験します。 + +これは Stage 2 の総合実践セクションです。これまでの章で、フロントエンドページ設計、バックエンドインターフェース開発、データベース操作、決済統合などの個別スキルを学びました。このプロジェクトでは、それらすべてを統合し、実行可能な製品プロトタイプを納品します。 + +## 前提知識 + +本プロジェクトを開始する前に、以下の内容を習得している必要があります: + +- フロントエンドページ設計とコンポーネントライブラリの使用([UI 設計](../../frontend/ui-design/)、[モダンコンポーネントライブラリ](../../frontend/modern-component-library/)) +- バックエンドインターフェースの設計と開発([インターフェースコードの記述](../../backend/ai-interface-code/)) +- データベースの基礎と Supabase([データベースから Supabase へ](../../backend/database-supabase/)) +- 決済統合([Stripe 決済システム](../../backend/stripe-payment/)) +- Git ワークフローとデプロイ([Git と GitHub](../../backend/git-workflow/)、[Web アプリケーションのデプロイ](../../backend/zeabur-deployment/)) + +## 学習目標 + +本実践を完了すると、以下のことができるようになります: + +1. 実際の PRD を読み解き、開発タスクリストを抽出する +2. PRD に基づいてモジュールを分割し、段階的な推進計画を策定する +3. AI を活用してフロントエンドスケルトンの構築とバックエンドインターフェース開発を完了する +4. 各モジュールを検証し、反復的に最適化する +5. エンドツーエンドの結合テストを完了し、プロジェクトを「動く」状態から「納品可能」な状態に引き上げる + +## プロジェクト概要 + +構築する製品は、モダンな AI 画像生成 SaaS プラットフォームであり、3つのサブシステムで構成されます: + +| サブシステム | 責務 | +|--------|------| +| **公式サイト** | 製品紹介、料金プラン、FAQ、登録コンバージョン | +| **ユーザーワークスペース** | Prompt 入力、画像生成、ギャラリー、クレジット、プラン、コミュニティ交流 | +| **管理画面** | ユーザー管理、タスク管理、決済管理、コンテンツ審査、SaaS 指標、システムモニタリング | + +バックエンドは以下のコア機能をサポートする必要があります:ユーザー認証、画像生成タスク、OSS オブジェクトストレージ、クレジットとプラン決済、画像ソーシャルインタラクション、運用データモニタリング。 + +::: tip PRD 入口 +本プロジェクトの要件定義書は GitHub にあります: [PRD を確認](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/modern-landing-page/PRD.md) +::: + +
+ + + +
+ +## 第1部:要件分析 + +### 1.1 PRD の読解 + +PRD 文書を開き、以下の質問に重点的に答えてください: + +- システムにはいくつの入口がありますか?それぞれどのページをカバーしていますか? +- 各ページのコア機能は何ですか? +- バックエンドにはどのモジュールとデータベーステーブルが含まれていますか? +- MVP の範囲は何ですか?初版で何を作り、何を作らないか? + +::: warning +上記の質問に明確な答えがない場合は、コードを書き始めないでください。要件の理解が不明確であることは、手戻りの最も一般的な原因です。 +::: + +### 1.2 システムアーキテクチャの確認 + +PRD の記述に基づいて、システムの全体アーキテクチャを整理します: + +```mermaid +flowchart TD + prd["PRD"] --> web["公式サイト"] + prd --> app["ユーザーワークスペース"] + prd --> admin["管理画面"] + app --> auth["認証"] + app --> gen["画像生成タスク"] + gen --> oss["OSS オブジェクトストレージ"] + gen --> db["データベース"] + billing["決済とプラン"] --> db + social["シェア / いいね / コメント / 転送"] --> db + admin --> analytics["SaaS 指標ダッシュボード"] + admin --> observability["API / DB / Provider モニタリング"] +``` + +自分の言葉でアーキテクチャ図を描き直し、システムの理解が完全であることを確認することをお勧めします。 + +## 第2部:プロジェクトスケルトンの構築 + +### 2.1 フロントエンドページの生成 + +AI を使用して、まずすべてのページの基本構造とモックデータを生成します。このステップの目標は、情報アーキテクチャとルーティングを構築することであり、実際のインターフェースに接続する必要はありません。 + +プロンプトの参考例: + +```text +現在の PRD に基づいて、モダンな AI 画像生成 SaaS のフロントエンドスケルトンを生成してください。 + +要件: +1. 3つの入口に分ける:www、app、admin +2. 公式サイトには:ホーム、料金プラン、FAQ +3. app には:ログイン、登録、生成ワークスペース、ギャラリー、プラン、クレジット、コミュニティ、作品詳細、個人センター +4. admin には:管理画面ホーム、ユーザー管理、タスク管理、コンテンツ管理、プラン管理、決済オーダー、運用設定、SaaS 指標、システムモニタリング +5. まずページ構造とモックデータのみを生成し、実際のインターフェースには接続しない +6. Midjourney を参考に、シンプルでモダン、製品感のあるスタイルにする +``` + +### 2.2 ページ構造の検証 + +スケルトン生成後、各項目をチェック: + +- [ ] 3つの入口のルーティングが独立しているか(`/`、`/app`、`/admin`) +- [ ] ページ数が PRD と一致しているか +- [ ] 各ページが正常にアクセス・ナビゲーションできるか +- [ ] モックデータが基本的な UI の状態を表現しているか(リスト、空の状態、フォームなど) + +## 第3部:反復開発 + +### 3.1 モジュールごとの推進 + +スケルトンをベースに、以下の順序でモジュールごとに機能を追加します: + +1. **認証**:登録、ログイン、ロールの区別 +2. **データベース**:データテーブルの作成、読み書きインターフェース +3. **コア業務**:画像生成タスク、結果の保存 +4. **OSS ストレージ**:画像のアップロードとアクセス +5. **決済**:プラン、クレジット、Stripe 統合 +6. **ソーシャルインタラクション**:シェア、いいね、コメント +7. **管理画面**:ユーザー管理、タスク管理、コンテンツ審査 +8. **データモニタリング**:SaaS 指標ダッシュボード、システムモニタリング + +各モジュールの完了後、以下の表で自己チェック: + +| チェック項目 | 検証方法 | +|--------|----------| +| ページの一致性 | ページ数、入口、機能が PRD に合致しているか | +| インターフェースの正確性 | リクエストパラメータ、返却構造、ステータス処理が適切か | +| 権限の分離 | 一般ユーザーと管理者が相互に分離されているか | +| データの整合性 | データベース、OSS、決済、クレジットが一致しているか | +| デモ可能性 | 他の人に完全な業務チェーンをデモできるか | + +::: tip +AI が生成した内容が PRD から逸脱していることに気づいた場合は、ページ全体をやり直すのではなく、具体的なモジュールの修正を指示してください。 +::: + +### 3.2 ロールと役割分担 + +反復開発の過程では、3つのロールを同時に演じる必要があります: + +- **プロダクトマネージャー**:各モジュールの機能が PRD に合致しているかを確認 +- **テックリード**:実装方法が適切であるかを確認 +- **テストエンジニア**:機能が正しく動作するかを確認 + +## 第4部:結合テストとデプロイ + +### 4.1 エンドツーエンドテスト + +最終段階の重点は新しいページを追加することではなく、完全な業務チェーンを動作させることです。少なくとも以下のシナリオを検証してください: + +- 登録 → クレジット購入 → 画像生成 → 履歴確認 → シェアとインタラクション +- 管理者のログイン → ユーザーデータの確認 → タスク統計の確認 → システムモニタリングの確認 + +### 4.2 デプロイ + +プロジェクトをパブリックネットワーク環境にデプロイし、以下を確認: + +- 環境変数の設定が完全であること +- ログインのコールバックアドレスが正しいこと +- 決済のコールバックアドレスが正しいこと +- ページにローディング、空の状態、エラーメッセージが欠落していないこと + +デプロイのチュートリアルはこちらを参照してください:[Git と GitHub ワークフロー](../../backend/git-workflow/)、[Web アプリケーションのデプロイ方法](../../backend/zeabur-deployment/)。 + +## 提出物 + +本プロジェクト完了後、以下の内容を提出してください: + +- [ ] アクセス可能なオンラインデモリンク +- [ ] ソースコードリポジトリのリンク(README を含む) +- [ ] PRD 文書 +- [ ] コアページのスクリーンショット(公式サイトホーム、生成ワークスペース、ギャラリー、プランページ、管理画面ホーム) +- [ ] 60秒のデモ動画(登録 → 生成 → 確認 → 管理画面を網羅) + +README には少なくとも以下を含めてください:プロジェクト概要、コアページの説明、技術スタック、ローカル起動手順、環境変数リスト。 + +## 評価基準 + +| 項目 | 基本要件 | 応用要件 | +|------|---------|---------| +| PRD への整合 | ページ、機能、データ構造が基本的に PRD に合致 | 各設計決定と PRD の対応関係を明確に説明できる | +| 製品完了 | 登録 → クレジット購入 → 画像生成 → 履歴確認 → シェアとインタラクションが動作 | 決済ステータス、クレジット残高、生成回数のデータが一致 | +| 管理画面の機能 | ユーザー、タスク、決済、コンテンツ管理が閲覧可能 | SaaS 指標ダッシュボードとシステムモニタリングページが完全に利用可能 | +| エンジニアリング完成度 | フロントエンド、バックエンド、データベース、OSS、決済チェーンが接続済み | エラー処理、空の状態、ローディング状態がある | +| 納品品質 | デプロイ可能、実行可能 | README が明確で、デモ動画の構造が完全 | + +## 参考資料 + +- [UI 設計](../../frontend/ui-design/) +- [UI 設計仕様を参考にページとボタンを設計](../../frontend/multi-product-ui/) +- [LLM と Skills でインターフェースを見栄えよくする](../../frontend/llm-skills-beautiful/) +- [デザインプロトタイプからプロジェクトコードへ](../../frontend/design-to-code/) +- [モダンコンポーネントライブラリでインターフェースをアップデート](../../frontend/modern-component-library/) +- [データベースから Supabase へ](../../backend/database-supabase/) +- [大規模言語モデルによるインターフェースコードとインターフェース文書の作成支援](../../backend/ai-interface-code/) +- [Git と GitHub ワークフロー](../../backend/git-workflow/) +- [Web アプリケーションのデプロイ方法](../../backend/zeabur-deployment/) +- [Stripe などの決済システムの統合方法](../../backend/stripe-payment/) diff --git a/docs/ja-jp/stage-2/assignments/movie-recommendation-springboot/index.md b/docs/ja-jp/stage-2/assignments/movie-recommendation-springboot/index.md new file mode 100644 index 0000000..c9aa397 --- /dev/null +++ b/docs/ja-jp/stage-2/assignments/movie-recommendation-springboot/index.md @@ -0,0 +1,162 @@ +# Spring Boot 映画レコメンドシステム開発実践 + +## 概要 + +本実践プロジェクトでは、実際の PRD に基づいて、Spring Boot を使用してレコメンド機能付きの映画サイトを完成させます。このプロジェクトのコアチャレンジは、単純な CRUD ではなく、「ユーザーの行動がレコメンド結果にどう影響するか」「レコメンドをどう説明可能にするか」を考えることにあります。 + +これは Stage 2 の総合実践セクションです。「コンテンツ + 行動 + レコメンド」型製品の開発パターンに初めて触れる機会であり、このパターンは EC、コンテンツプラットフォーム、パーソナライズフィードなどのシナリオで非常に一般的です。 + +## 前提知識 + +このプロジェクトを始める前に、以下の内容をすでに習得している必要があります: + +- フロントエンドページ設計とコンポーネントライブラリの使用([UI 設計](../../frontend/ui-design/)、[モダンコンポーネントライブラリ](../../frontend/modern-component-library/)) +- バックエンドインターフェース設計と開発([インターフェースコード作成](../../backend/ai-interface-code/)) +- データベース基礎と Supabase([データベースから Supabase まで](../../backend/database-supabase/)) +- Git ワークフローとデプロイ([Git と GitHub](../../backend/git-workflow/)、[Web アプリのデプロイ](../../backend/zeabur-deployment/)) + +## 学習目標 + +本実践完了後、以下のことができるようになります: + +1. PRD を読み、レコメンドシステムの開発タスクリストを抽出する +2. Spring Boot を使用してバックエンドプロジェクトを構築し、RESTful API を実装する +3. 「ユーザー行動 → レコメンド」の完全なデータパイプラインを設計する +4. 説明可能なレコメンドロジックを実装する +5. エンドツーエンドの結合テストを完了し、デモ可能な製品プロトタイプを納品する + +## プロジェクト概要 + +あなたが構築する製品は、レコメンド機能付きの映画サイトです: + +| 機能 | 説明 | +|------|------| +| **閲覧と検索** | ユーザーは映画を閲覧・検索できる | +| **評価とお気に入り** | ユーザーは映画を評価し、お気に入りに追加できる | +| **パーソナライズレコメンド** | システムがユーザー行動に基づいてレコメンド結果を表示 | +| **管理バックエンド** | 管理者が映画データを管理し、レコメンド効果を確認 | + +::: tip PRD 入口 +本プロジェクトの要件文書は GitHub にあります: [PRD を表示](https://github.com/datawhalechina/easy-vibe/blob/main/docs/ja-jp/stage-2/assignments/movie-recommendation-springboot/PRD.md) +::: + +
+ + + +
+ +## 第 1 部:要件分析 + +### 1.1 PRD を読む + +PRD 文書を開き、以下の質問に重点的に答えてください: + +- レコメンド戦略は何ですか?第 1 版では説明可能なバージョン(評価類似度に基づくなど)を使用しますか? +- ユーザー行動データとして何を保存しますか?(評価、お気に入り、閲覧履歴など) +- 管理者が確認すべきレコメンド効果指標は何ですか? +- ページリストは完全ですか? + +::: warning +以上の質問に対する明確な答えがない場合は、コードを書き始めないでください。要件の理解が不明確なのは、手戻りの最も一般的な原因です。 +::: + +### 1.2 システムアーキテクチャの確認 + +```mermaid +flowchart TD + prd["PRD"] --> web["フロントエンドページ"] + web --> auth["ユーザー認証"] + web --> movie["映画リスト / 詳細"] + web --> behavior["評価 / お気に入り"] + behavior --> reco["レコメンドロジック"] + reco --> db["データベース"] + admin["管理バックエンド"] --> db +``` + +## 第 2 部:プロジェクトスケルトンの構築 + +### 2.1 フロントエンドページの生成 + +プロンプト参考: + +```text +現在の PRD に基づいて、Spring Boot 映画レコメンドシステムのフロントエンドスケルトンを生成してください。 + +要件: +1. ページには以下を含む:ホーム、映画リスト、映画詳細、レコメンドページ、個人センター、管理バックエンド +2. まずページ構造とモックデータのみを生成し、実際のインターフェースには接続しない +3. 授業のデモではなく、実際のコンテンツ製品のようなスタイルにする +``` + +### 2.2 プロジェクト構造の検証 + +項目ごとにチェック: + +- [ ] 映画リストページで検索とフィルタリングがサポートされている +- [ ] 映画詳細ページに評価とお気に入りボタンがある +- [ ] レコメンドページでレコメンド結果とレコメンド理由が表示できる +- [ ] 管理バックエンドで映画データとレコメンド効果が確認できる + +## 第 3 部:反復開発 + +### 3.1 モジュールごとに進める + +1. **Spring Boot プロジェクト構築**:プロジェクト構造、データベース設定、基本 CRUD +2. **映画データ管理**:映画リスト、詳細、検索インターフェース +3. **ユーザー行動**:評価、お気に入りインターフェース、行動データ書き込み +4. **レコメンドロジック**:ユーザー行動に基づくレコメンドアルゴリズムの実装 +5. **レコメンド表示**:レコメンド結果の表示、レコメンド理由を含む +6. **管理バックエンド**:映画データのメンテナンス、レコメンド効果の確認 + +### 3.2 モジュール自己チェック + +| チェック項目 | 検証方法 | +|--------|----------| +| 基本機能 | リスト、詳細、評価、お気に入りのクロージャが完了しているか | +| レコメンド連動 | ユーザー行動がレコメンド結果に影響しているか | +| レコメンド説明可能性 | ユーザーがなぜこれらの映画をレコメンドされたか理解できるか | +| 管理データ | 管理者が映画データとレコメンド効果を確認できるか | + +## 第 4 部:結合テストとリリース + +### 4.1 エンドツーエンドテスト + +少なくとも以下のシナリオを検証: + +- 映画を閲覧 → 評価 → お気に入り → レコメンドページを確認し、レコメンド結果が変化したことを確認 +- 管理者ログイン → 映画を追加 → レコメンド効果統計を確認 + +## 提出物 + +本プロジェクト完了後、以下の内容を提出する必要があります: + +- [ ] アクセス可能なオンラインデモリンク +- [ ] ソースコードリポジトリリンク(README を含む) +- [ ] PRD 文書 +- [ ] コアページのスクリーンショット(映画リスト、映画詳細、レコメンドページ、管理バックエンド) +- [ ] 60 秒のデモ動画 + +## 評価基準 + +| 項目 | 基本要件 | 応用要件 | +|------|---------|---------| +| PRD 整合性 | ページ、機能、データ構造が基本的に PRD に適合 | 設計決定を明確に説明できる | +| 製品クロージャ | 閲覧 → 評価 → お気に入り → レコメンドが動作する | 評価行動がレコメンド結果に明確に影響する | +| レコメンド品質 | レコメンド結果が合理的で、理由が説明可能 | 複数のレコメンド戦略をサポート | +| 管理機能 | 映画データとレコメンド効果が確認可能 | レコメンド精度などの統計指標がある | +| エンジニアリング完成度 | フロントエンド、Spring Boot バックエンド、データベースのパイプラインが接続されている | レコメンドインターフェースにキャッシュやパフォーマンス最適化がある | + +## 参考資料 + +- [UI 設計](../../frontend/ui-design/) +- [モダンコンポーネントライブラリでインターフェースを更新](../../frontend/modern-component-library/) +- [データベースから Supabase まで](../../backend/database-supabase/) +- [大規模モデルによるインターフェースコードとドキュメント作成](../../backend/ai-interface-code/) +- [Git と GitHub ワークフロー](../../backend/git-workflow/) +- [Web アプリのデプロイ方法](../../backend/zeabur-deployment/) diff --git a/docs/ja-jp/stage-2/assignments/simple-grocery-microservices/index.md b/docs/ja-jp/stage-2/assignments/simple-grocery-microservices/index.md new file mode 100644 index 0000000..6312578 --- /dev/null +++ b/docs/ja-jp/stage-2/assignments/simple-grocery-microservices/index.md @@ -0,0 +1,172 @@ +# 生鮮 EC マイクロサービスシステム開発実践 + +## 概要 + +本実践プロジェクトでは、実際の PRD に基づいて、生鮮 EC マイクロサービスシステムを一から完成させます。これまでの単一サービスプロジェクトとは異なり、このプロジェクトのバックエンドはビジネスごとに複数の独立したサービスに分割され、API ゲートウェイを通じて統一的に外部に公開されます。サービス境界の設計方法や、クロスサービスのデータ整合性の処理方法を学びます。 + +これは Stage 2 の総合実践セクションです。マイクロサービスアーキテクチャは実際の業務で非常に一般的であり、サービス分割とゲートウェイルーティングの基本的な考え方を習得すれば、より複雑なバックエンドシステム設計に対応できるようになります。 + +## 前提知識 + +このプロジェクトを始める前に、以下の内容をすでに習得している必要があります: + +- フロントエンドページ設計とコンポーネントライブラリの使用([UI 設計](../../frontend/ui-design/)、[モダンコンポーネントライブラリ](../../frontend/modern-component-library/)) +- バックエンドインターフェース設計と開発([インターフェースコード作成](../../backend/ai-interface-code/)) +- データベース基礎と Supabase([データベースから Supabase まで](../../backend/database-supabase/)) +- Git ワークフローとデプロイ([Git と GitHub](../../backend/git-workflow/)、[Web アプリのデプロイ](../../backend/zeabur-deployment/)) + +## 学習目標 + +本実践完了後、以下のことができるようになります: + +1. PRD を読み、マイクロサービスシステムの開発タスクリストを抽出する +2. ビジネスドメインごとにサービス境界を分割する(認証、商品、在庫、注文) +3. API ゲートウェイルーティングを設計・実装する +4. 在庫引き当てや注文整合性などのクロスサービス問題を処理する +5. エンドツーエンドの結合テストを完了し、デモ可能なマイクロサービスプロトタイプを納品する + +## プロジェクト概要 + +あなたが構築する製品は、生鮮 EC マイクロサービスシステムです: + +| サブシステム | 責務 | +|--------|------| +| **ユーザー側** | 商品閲覧、注文、注文確認 | +| **管理側** | 商品管理、在庫管理、注文管理 | + +バックエンドはビジネスごとに以下のサービスに分割されます: + +| サービス | 責務 | +|------|------| +| **API Gateway** | 統一エントリ、ルーティング転送、認証チェック | +| **Auth Service** | ユーザー登録、ログイン、JWT 発行 | +| **Catalog Service** | 商品情報管理 | +| **Inventory Service** | 在庫数量管理 | +| **Order Service** | 注文作成、ステータス管理 | + +::: tip PRD 入口 +本プロジェクトの要件文書は GitHub にあります: [PRD を表示](https://github.com/datawhalechina/easy-vibe/blob/main/docs/ja-jp/stage-2/assignments/simple-grocery-microservices/PRD.md) +::: + +
+ + + +
+ +## 第 1 部:要件分析 + +### 1.1 PRD を読む + +PRD 文書を開き、以下の質問に重点的に答えてください: + +- サービスはどのように分割しますか?各サービスの責任境界は何ですか? +- フロントエンドと管理側にはそれぞれどのページがありますか? +- 注文後の在庫引き当ての戦略は何ですか?成功/失敗/タイムアウトの各ケースにどう対応しますか? +- 第 1 版では、どの複雑な機能(分散トランザクション、メッセージキューなど)を先送りにしますか? + +::: warning +以上の質問に対する明確な答えがない場合は、コードを書き始めないでください。要件の理解が不明確なのは、手戻りの最も一般的な原因です。 +::: + +### 1.2 システムアーキテクチャの確認 + +```mermaid +flowchart TD + prd["PRD"] --> fe["フロントエンドページ"] + fe --> gw["API Gateway"] + gw --> auth["Auth Service"] + gw --> catalog["Catalog Service"] + gw --> inventory["Inventory Service"] + gw --> order["Order Service"] + order --> inventory +``` + +## 第 2 部:プロジェクトスケルトンの構築 + +### 2.1 プロジェクト構造の生成 + +プロンプト参考: + +```text +現在の PRD に基づいて、生鮮 EC マイクロサービスシステムのプロジェクトスケルトンを生成してください。 + +要件: +1. フロントエンドのユーザー側と管理側のスケルトンを生成 +2. api-gateway、auth-service、catalog-service、inventory-service、order-service の 5 つのディレクトリを生成 +3. 各サービスはまず最小限の実行可能エントリのみを作成 +4. 実際のデータベースと決済はまだ接続しない +``` + +### 2.2 プロジェクト構造の検証 + +項目ごとにチェック: + +- [ ] 5 つのサービスディレクトリ構造が明確 +- [ ] API Gateway が起動してリクエストを転送できる +- [ ] 各サービスのヘルスチェックインターフェースが利用可能 +- [ ] フロントエンドのユーザー側と管理側ページがアクセス可能 + +## 第 3 部:反復開発 + +### 3.1 モジュールごとに進める + +1. **API Gateway**:ルーティング設定、JWT 検証ミドルウェア +2. **Auth Service**:登録、ログイン、JWT 発行 +3. **Catalog Service**:商品 CRUD、リストクエリ +4. **Inventory Service**:在庫照会、在庫引き当て +5. **Order Service**:注文作成、ステータス遷移、在庫連動 +6. **管理側**:商品管理、在庫管理、注文管理 + +### 3.2 モジュール自己チェック + +| チェック項目 | 検証方法 | +|--------|----------| +| ゲートウェイルーティング | 各サービスのインターフェースがゲートウェイ経由で正しく転送されているか | +| 権限分離 | ユーザー側と管理側のインターフェースが分離されているか | +| データ整合性 | 商品と在庫のデータが同期しているか | +| 取引クロージャ | 注文後の在庫引き当て、注文ステータスが一致しているか | +| 障害処理 | 在庫不足やタイムアウト時に補償メカニズムがあるか | + +## 第 4 部:結合テストとリリース + +### 4.1 エンドツーエンドテスト + +少なくとも以下のシナリオを検証: + +- 商品を閲覧 → カートに追加 → 注文 → 注文確認 +- 管理者 → 商品を追加 → 在庫を更新 → 注文確認 + +## 提出物 + +本プロジェクト完了後、以下の内容を提出する必要があります: + +- [ ] アクセス可能なオンラインデモリンク +- [ ] ソースコードリポジトリリンク(README を含む) +- [ ] PRD 文書 +- [ ] コアページのスクリーンショット(商品リスト、注文ページ、注文ページ、管理バックエンド) +- [ ] 60 秒のデモ動画 + +## 評価基準 + +| 項目 | 基本要件 | 応用要件 | +|------|---------|---------| +| PRD 整合性 | ページ、機能、サービス分割が基本的に PRD に適合 | サービス分割の理由を明確に説明できる | +| 製品クロージャ | 閲覧 → 注文 → 在庫引き当て → 注文確認が動作する | 注文タイムアウトや在庫不足時に補償メカニズムがある | +| サービスアーキテクチャ | 各サービスが独立して起動でき、ゲートウェイ経由で統一アクセス可能 | サービス間通信にエラー処理とリトライがある | +| 管理機能 | 商品、在庫、注文管理が操作可能 | 管理側にデータ統計がある | +| エンジニアリング完成度 | フロントエンド、ゲートウェイ、サービス、データベースのパイプラインが接続されている | Docker Compose などのオーケストレーションがある | + +## 参考資料 + +- [UI 設計](../../frontend/ui-design/) +- [モダンコンポーネントライブラリでインターフェースを更新](../../frontend/modern-component-library/) +- [データベースから Supabase まで](../../backend/database-supabase/) +- [大規模モデルによるインターフェースコードとドキュメント作成](../../backend/ai-interface-code/) +- [Git と GitHub ワークフロー](../../backend/git-workflow/) +- [Web アプリのデプロイ方法](../../backend/zeabur-deployment/) diff --git a/docs/ja-jp/stage-2/assignments/traffic-data-visualization-go/index.md b/docs/ja-jp/stage-2/assignments/traffic-data-visualization-go/index.md new file mode 100644 index 0000000..2b1954f --- /dev/null +++ b/docs/ja-jp/stage-2/assignments/traffic-data-visualization-go/index.md @@ -0,0 +1,163 @@ +# Go 交通データ分析プラットフォーム開発実践 + +## 概要 + +本実践プロジェクトでは、実際の PRD に基づいて、Go を使用して交通データ分析プラットフォームを完成させます。このプロジェクトの方向性は、これまでの CRUD システムとは異なり、「データ取り込み → 集計 → アラート → 可視化」という完全なデータパイプラインを構築します。このようなデータ製品は、IoT、モニタリング、運用分析などのシナリオで非常に一般的です。 + +これは Stage 2 の総合実践セクションであり、Go 言語に初めて触れる機会でもあります。心配しないでください。これまでの JavaScript / TypeScript の基礎があれば、Go の学習は難しくありません。重要なのは、データパイプラインの設計思路を理解することです。 + +## 前提知識 + +このプロジェクトを始める前に、以下の内容をすでに習得している必要があります: + +- フロントエンドページ設計とコンポーネントライブラリの使用([UI 設計](../../frontend/ui-design/)、[モダンコンポーネントライブラリ](../../frontend/modern-component-library/)) +- バックエンドインターフェース設計と開発([インターフェースコード作成](../../backend/ai-interface-code/)) +- データベース基礎と Supabase([データベースから Supabase まで](../../backend/database-supabase/)) +- Git ワークフローとデプロイ([Git と GitHub](../../backend/git-workflow/)、[Web アプリのデプロイ](../../backend/zeabur-deployment/)) + +## 学習目標 + +本実践完了後、以下のことができるようになります: + +1. PRD を読み、データ製品の開発タスクリストを抽出する +2. Go(Gin または Fiber)を使用してバックエンド API サービスを構築する +3. データ取り込み、ウィンドウ集計、アラートの完全なパイプラインを設計する +4. バックエンドデータとフロントエンドダッシュボードの整合性を保つ +5. エンドツーエンドの結合テストを完了し、デモ可能なデータ製品プロトタイプを納品する + +## プロジェクト概要 + +あなたが構築する製品は、Go 交通データ分析プラットフォームです: + +| モジュール | 責務 | +|------|------| +| **データ取り込み** | 生の交通イベントを受信してデータベースに格納 | +| **データ集計** | 時間ウィンドウごとにトレンドと渋滞指標を計算 | +| **アラート** | ルールに基づいてアラートレコードを生成 | +| **ダッシュボード表示** | フロントエンドでトレンドグラフ、ランキング、アラートリストを表示 | + +::: tip PRD 入口 +本プロジェクトの要件文書は GitHub にあります: [PRD を表示](https://github.com/datawhalechina/easy-vibe/blob/main/docs/ja-jp/stage-2/assignments/traffic-data-visualization-go/PRD.md) +::: + +
+ + + +
+ +## 第 1 部:要件分析 + +### 1.1 PRD を読む + +PRD 文書を開き、以下の質問に重点的に答えてください: + +- データソースは何ですか?フィールドには何がありますか? +- コア指標の定義は何ですか?(例:「渋滞」の具体的な基準) +- アラートルールは何ですか?第 1 版ではまずシンプルなルールに絞りますか? +- ダッシュボードにはどのページとグラフが含まれますか? + +::: warning +以上の質問に対する明確な答えがない場合は、コードを書き始めないでください。要件の理解が不明確なのは、手戻りの最も一般的な原因です。 +::: + +### 1.2 データパイプラインの確認 + +```mermaid +flowchart TD + prd["PRD"] --> ingest["データ取り込み API"] + ingest --> raw["生データテーブル"] + raw --> agg["集計タスク"] + agg --> alert["アラートルール"] + agg --> dashboard["ダッシュボードインターフェース"] + alert --> dashboard +``` + +## 第 2 部:プロジェクトスケルトンの構築 + +### 2.1 Go API サービスの生成 + +プロンプト参考: + +```text +現在の PRD に基づいて、Go 交通データ分析プラットフォームのスケルトンを生成してください。 + +要件: +1. Gin または Fiber を使用 +2. データ取り込みインターフェースを提供 +3. 集計タスクのスケルトンを提供 +4. dashboard と alerts インターフェースのスケルトンを提供 +5. まずは複雑な分析を実装せず、実行可能な構造のみを構築 +``` + +### 2.2 プロジェクト構造の検証 + +項目ごとにチェック: + +- [ ] Go サービスが正常に起動できる +- [ ] データ取り込みインターフェースでデータを受信して保存できる +- [ ] 集計タスクのフレームワークが構築されている +- [ ] フロントエンドダッシュボードページで基本グラフが表示できる + +## 第 3 部:反復開発 + +### 3.1 モジュールごとに進める + +1. **データ取り込み API**:生の交通イベントを受信し、データベースに書き込む +2. **データ集計**:時間ウィンドウごとに集計し、トレンドと渋滞指標を計算 +3. **アラートルール**:閾値に基づいてアラートレコードを生成 +4. **ダッシュボードインターフェース**:トレンドデータ、ランキングデータ、アラートリストを提供 +5. **フロントエンドダッシュボード**:トレンドグラフ、ランキング、アラートリストページ + +### 3.2 モジュール自己チェック + +| チェック項目 | 検証方法 | +|--------|----------| +| データ取り込み | 生データが正しくデータベースに格納されているか | +| 集計定義 | トレンド、ランキング指標の計算ロジックが一致しているか | +| アラートルール | アラートのトリガー条件が期待通りか | +| データ整合性 | ダッシュボードの表示とバックエンドデータが一致しているか | +| API 仕様 | 統一されたレスポンス構造とエラー処理があるか | + +## 第 4 部:結合テストとリリース + +### 4.1 エンドツーエンドテスト + +少なくとも以下のシナリオを検証: + +- テストデータを取り込み → 集計タスクを実行 → ダッシュボード表示が更新される +- アラート条件をトリガー → アラートレコードが生成 → アラートページに表示 + +## 提出物 + +本プロジェクト完了後、以下の内容を提出する必要があります: + +- [ ] アクセス可能なオンラインデモリンク +- [ ] ソースコードリポジトリリンク(README を含む) +- [ ] PRD 文書 +- [ ] コアページのスクリーンショット(データ取り込みデモ、トレンドダッシュボード、アラートリスト) +- [ ] 60 秒のデモ動画 + +## 評価基準 + +| 項目 | 基本要件 | 応用要件 | +|------|---------|---------| +| PRD 整合性 | 機能とデータ構造が基本的に PRD に適合 | 指標定義と集計ロジックを明確に説明できる | +| データパイプライン | 取り込み → 集計 → アラート → ダッシュボードが動作する | 集計タスクが増分更新をサポート | +| 分析能力 | トレンド、ランキング、アラートの 3 モジュールが利用可能 | 指標が設定可能、アラートルールがカスタマイズ可能 | +| フロントエンド表示 | ダッシュボードで基本グラフが表示できる | グラフが時間範囲フィルタをサポート | +| エンジニアリング完成度 | Go API、データベース、フロントエンドのパイプラインが接続されている | API に統一されたエラー処理とログがある | + +## 参考資料 + +- [UI 設計](../../frontend/ui-design/) +- [モダンコンポーネントライブラリでインターフェースを更新](../../frontend/modern-component-library/) +- [データベースから Supabase まで](../../backend/database-supabase/) +- [大規模モデルによるインターフェースコードとドキュメント作成](../../backend/ai-interface-code/) +- [Git と GitHub ワークフロー](../../backend/git-workflow/) +- [Web アプリのデプロイ方法](../../backend/zeabur-deployment/) diff --git a/docs/ja-jp/stage-2/assignments/travel-planning-agent-platform/index.md b/docs/ja-jp/stage-2/assignments/travel-planning-agent-platform/index.md new file mode 100644 index 0000000..3c98838 --- /dev/null +++ b/docs/ja-jp/stage-2/assignments/travel-planning-agent-platform/index.md @@ -0,0 +1,164 @@ +# スマート旅行計画 Agent プラットフォーム開発実践 + +## 概要 + +本実践プロジェクトでは、実際の PRD に基づいて、スマート旅行計画 Agent プラットフォームを一から完成させます。構造化された入力を受け取り、毎日の旅程を生成し、保存と再利用をサポートする完全な AI 製品を構築します。単なるチャットボットではなく、タスク管理能力を持つ製品です。 + +これは Stage 2 の総合実践セクションです。このプロジェクトのコアチャレンジは、AI が構造化された使用可能な旅程計画を生成するようにすることであり、操作不可能な長いテキストではなく、実用的な出力を生み出すことにあります。 + +## 前提知識 + +このプロジェクトを始める前に、以下の内容をすでに習得している必要があります: + +- フロントエンドページ設計とコンポーネントライブラリの使用([UI 設計](../../frontend/ui-design/)、[モダンコンポーネントライブラリ](../../frontend/modern-component-library/)) +- バックエンドインターフェース設計と開発([インターフェースコード作成](../../backend/ai-interface-code/)) +- データベース基礎と Supabase([データベースから Supabase まで](../../backend/database-supabase/)) +- Git ワークフローとデプロイ([Git と GitHub](../../backend/git-workflow/)、[Web アプリのデプロイ](../../backend/zeabur-deployment/)) + +## 学習目標 + +本実践完了後、以下のことができるようになります: + +1. PRD を読み、Agent プラットフォームの開発タスクリストを抽出する +2. 構造化された入力フォームと構造化された出力形式を設計する +3. Agent オーケストレーション層を実装し、ユーザー入力、モデル呼び出し、結果保存を処理する +4. 「生成 → 保存 → 再利用」のビジネスクロージャを構築する +5. エンドツーエンドの結合テストを完了し、デモ可能な AI 製品プロトタイプを納品する + +## プロジェクト概要 + +あなたが構築する製品は、スマート旅行計画 Agent プラットフォームです: + +| 機能 | 説明 | +|------|------| +| **旅程計画** | ユーザーが出発地、目的地、日付、予算、好みを入力し、システムが毎日の旅程を生成 | +| **予算配分** | 旅程結果に予算配分と提案を含む | +| **履歴管理** | ユーザーは過去の計画を保存、再生成、エクスポート可能 | +| **管理バックエンド** | 管理者が人気の目的地、失敗タスク、ユーザーフィードバックを確認 | + +::: tip PRD 入口 +本プロジェクトの要件文書は GitHub にあります: [PRD を表示](https://github.com/datawhalechina/easy-vibe/blob/main/docs/ja-jp/stage-2/assignments/travel-planning-agent-platform/PRD.md) +::: + +
+ + + +
+ +## 第 1 部:要件分析 + +### 1.1 PRD を読む + +PRD 文書を開き、以下の質問に重点的に答えてください: + +- 第 1 版は単一目的地のみにしますか? +- 旅程出力は構造化されている必要がありますか?その構造は何ですか? +- エクスポート機能はどの程度深く実装しますか?(共有リンク / PDF / 画像) +- 管理バックエンドの統計とタスクログの範囲は何ですか? + +::: warning +以上の質問に対する明確な答えがない場合は、コードを書き始めないでください。要件の理解が不明確なのは、手戻りの最も一般的な原因です。 +::: + +### 1.2 データパイプラインの確認 + +```mermaid +flowchart TD + prd["PRD"] --> planner["計画ページ"] + planner --> agent["Agent オーケストレーション層"] + agent --> model["モデル呼び出し"] + agent --> db["データベース"] + db --> history["履歴計画"] + db --> admin["管理統計とログ"] +``` + +## 第 2 部:プロジェクトスケルトンの構築 + +### 2.1 フロントエンドページの生成 + +プロンプト参考: + +```text +現在の PRD に基づいて、スマート旅行計画 Agent プラットフォームのフロントエンドスケルトンを生成してください。 + +要件: +1. ページには以下を含む:ホーム、計画ページ、旅程詳細ページ、履歴記録ページ、管理ページ +2. 計画ページの左側にフォーム、右側に結果プレビュー +3. まずページ構造とモックデータのみを生成し、実際のインターフェースには接続しない +4. モダンな AI 製品のようなスタイルにする +``` + +### 2.2 プロジェクト構造の検証 + +項目ごとにチェック: + +- [ ] 計画ページのフォームフィールドが PRD と一致している +- [ ] 結果プレビュー領域で構造化された旅程データが表示できる +- [ ] 履歴記録ページで複数の計画が表示できる +- [ ] 管理バックエンドページで統計データが表示できる + +## 第 3 部:反復開発 + +### 3.1 モジュールごとに進める + +1. **認証**:登録、ログイン +2. **計画フォーム**:構造化入力(出発地、目的地、日付、予算、好み) +3. **Agent オーケストレーション**:入力の受信 → モデル呼び出し → 構造化出力の解析 +4. **結果表示**:旅程を日ごとに表示、予算配分、提案 +5. **履歴管理**:計画の保存、再生成、エクスポート +6. **管理バックエンド**:人気の目的地、失敗タスク、ユーザーフィードバック +7. **タスクステータス**:生成中 / 成功 / 失敗のステータス管理とエラー記録 + +### 3.2 モジュール自己チェック + +| チェック項目 | 検証方法 | +|--------|----------| +| 入力完全性 | フォームフィールドが PRD と一致しているか | +| 出力構造化 | 旅程結果が構造化データであるか(長いテキストではないか) | +| データ整合性 | trip、itinerary、logs のデータが一致しているか | +| クロージャ検証 | 「入力 → 生成 → 保存 → 再生成」のデモができるか | + +## 第 4 部:結合テストとリリース + +### 4.1 エンドツーエンドテスト + +少なくとも以下のシナリオを検証: + +- 旅程パラメータを入力 → 毎日の旅程を生成 → 予算配分を確認 → 履歴に保存 +- 履歴記録から旅程を再生成 +- 管理者がタスク統計と失敗ログを確認 + +## 提出物 + +本プロジェクト完了後、以下の内容を提出する必要があります: + +- [ ] アクセス可能なオンラインデモリンク +- [ ] ソースコードリポジトリリンク(README を含む) +- [ ] PRD 文書 +- [ ] コアページのスクリーンショット(計画ページ、旅程詳細ページ、履歴記録ページ、管理バックエンド) +- [ ] 60 秒のデモ動画 + +## 評価基準 + +| 項目 | 基本要件 | 応用要件 | +|------|---------|---------| +| PRD 整合性 | ページ、機能、データ構造が基本的に PRD に適合 | 設計決定を明確に説明できる | +| 製品クロージャ | 計画 → 保存 → 履歴 → 再生成が動作する | エクスポートと共有をサポート | +| 出力品質 | 旅程結果が構造化され読みやすい | 予算配分が合理的で、提案に针对性がある | +| 管理機能 | タスク統計と失敗ログが確認可能 | 人気の目的地分析がある | +| エンジニアリング完成度 | フロントエンド、バックエンド、データベース、モデル呼び出しパイプラインが接続されている | タスクステータス管理が充実し、エラーがトレース可能 | + +## 参考資料 + +- [UI 設計](../../frontend/ui-design/) +- [モダンコンポーネントライブラリでインターフェースを更新](../../frontend/modern-component-library/) +- [データベースから Supabase まで](../../backend/database-supabase/) +- [大規模モデルによるインターフェースコードとドキュメント作成](../../backend/ai-interface-code/) +- [Git と GitHub ワークフロー](../../backend/git-workflow/) +- [Web アプリのデプロイ方法](../../backend/zeabur-deployment/) diff --git a/docs/ja-jp/stage-2/backend/ai-interface-code/index.md b/docs/ja-jp/stage-2/backend/ai-interface-code/index.md new file mode 100644 index 0000000..2243a31 --- /dev/null +++ b/docs/ja-jp/stage-2/backend/ai-interface-code/index.md @@ -0,0 +1,161 @@ +# 大規模言語モデルによるインターフェースコードとインターフェース文書の作成支援 + +これまでのレッスンでは、Figma などのツールを使った UI デザイン、AI を活用したフロントエンド静的ページの自動生成、そして Supabase を利用したデータベース構築とユーザー認証の基本について学びました。ここで、自然と浮かんでくる疑問があります。フロントエンドページ上のあのダイナミックなボタンをクリックしたとき、データはどのようにして Supabase に送られているのでしょうか?また、より複雑なビジネスロジック(同時決済、定期プッシュ通知、機密データ処理など)を実行する際、フロントエンドから直接データベースに接続するのは安全でしょうか? + +ここで登場するのが、現代の Web 開発アーキテクチャにおいて極めて重要な要素——**バックエンド API インターフェース**です。 + +かつては、バックエンドルート、コントローラー、パラメータ検証ロジックを何百行も手書きしなければなりませんでした。今では、大規模言語モデルの強力なコード生成能力を活用し、煩雑な定型コードを AI に任せることができます。本レッスンでは、「AI が書くコードは抽象的で曖昧」という罠から脱却し、実際のビジネスシナリオに基づき、高品質なプロンプト(Prompt)を使って大規模言語モデルに堅牢で業界標準に準拠した Node.js バックエンドインターフェースを書かせる方法、そしてインターフェース文書とテストケースの自動生成について解説します。 + +> 💡 **前提知識** +> +> 本節を学ぶ前に、以下の内容を理解しておくことをお勧めします: +> - [データベースから Supabase へ](../database-supabase/) - データベースとデータモデルの概念について理解する。 +> - [Git と GitHub ワークフロー](../git-workflow/) - プロジェクト開発におけるバージョン管理の方法に慣れる。 +> - [ターミナル / コマンドラインとは](/ja-jp/appendix/2-development-tools/command-line-shell) - プロジェクトの初期化と起動には基本的なコマンド操作が欠かせません。 + +# このレッスンで学ぶこと + +1. **API インターフェースとは何か**:フロントエンドとバックエンドの通信を橋渡しする仕組みと、RESTful 設計規約について理解する。 +2. **大規模言語モデルによるサービス構築**:構造化された Prompt を使って AI に Node.js + Express の基本プロジェクトを構築させる方法。 +3. **インターフェースロジック開発**:大規模言語モデルに、厳密なビジネスバリデーションを含み、Supabase データベースと連携する CRUD(作成・読み取り・更新・削除)インターフェースを生成させる。 +4. **インターフェース文書の自動生成**:コードから逆算して、チーム間コラボレーションの標準である OpenAPI/Swagger 文書を生成させる。 +5. **テストと結合のフィードバックループ**:Postman テストコレクションや Jest ユニットテストケースを生成し、コードの品質を担保する。 + +--- + +# 1. なぜ API インターフェースが必要なのか? + +従来の理解では、フロントエンドは「見える部分」、データベースは「データを保管する場所」でした。しかし、その間には調整役が欠けています。アプリケーション全体をレストランに例えてみましょう: +- **フロントエンド(クライアント)** はレストランのメニューと注文テーブルであり、客はここでメニューを閲覧し注文を出します。 +- **データベース(Supabase など)** はレストランの厨房倉庫であり、すべての食材と帳簿が保管されています。 +- **バックエンド API インターフェース** はレストランのウェイターです。客は厨房に直接押し入って食材を取ることはできません(混乱を招くだけでなく、セキュリティ上の問題も発生します)。客は「注文の要求」(HTTP Request)をウェイターに伝える必要があります。ウェイターは確認(パラメータ検証、権限認証)を行った後、厨房から対応する内容を取り寄せ、「完成した料理」(HTTP Response、通常は JSON 形式のデータ)を客に運びます。 + +API インターフェースを通じて、明確な**フロントエンドとバックエンドの分離**を実現します。フロントエンドはページのレンダリングに専念し、バックエンドはビジネスロジック、データ処理、セキュリティ保護に集中します。 + +--- + +# 2. プロジェクトアーキテクチャの設計と初期化 + +構造が明確なプロジェクトスケルトンは、大規模言語モデルが良質なコードを書くための前提条件です。AI にコードを書かせる前に、自分自身でプロジェクト構造を把握しておく必要があります。 + +## 2.1 一般的な API プロジェクト構造 +大規模言語モデルでコードを生成する場合でも、すべてのコードを一つの `server.js` ファイルに詰め込むべきではありません。保守しやすい Node.js バックエンドアーキテクチャは通常、次のようになります: + +```text +my-api-project/ +├── .env # 機密環境変数(API Keys、データベース接続文字列など) +├── server.js # プロジェクトのエントリーポイント(サーバー起動、グローバルミドルウェアの登録) +├── package.json # 依存関係管理ファイル +├── src/ +│ ├── routes/ # ルーティング層:URL パスとリクエストメソッドを定義 +│ ├── controllers/ # コントローラー層:リクエストパラメータを処理し、サービスを呼び出してレスポンスを返す +│ ├── services/ # サービス層:データベースとのやり取りやコアビジネスロジックをカプセル化 +│ └── middlewares/ # ミドルウェア:ログイン認証、グローバルエラーハンドリング +└── docs/ # API 文書の保存ディレクトリ +``` + +## 2.2 AI を活用したプロジェクト初期化 +手動で `npm init` を実行し、依存関係を一つずつインストールするよりも、上記の構造を Prompt の形式で大規模言語モデルに渡す方が効率的です: + +> 🗣️ **大規模言語モデルへのプロンプト(Prompt の例):** +> "Node.js のバックエンドプロジェクトを構築してください。Supabase データベースに接続でき、将来の保守に便利なように構造を整理してください。" + +AI が返したコードを実行すると、`localhost:3000` でエンタープライズレベルの基本構えを持つバックエンドアプリケーションが手に入ります。 + +--- + +# 3. コア実践:大規模言語モデルによるインターフェース開発支援 + +この章の最も重要な部分です。大規模言語モデルが書くコードには「論理的な抜け」や「表面的なごまかし」がよく見られます。その原因は、開発者が与えるコンテキストが不足していることにあります。**大規模言語モデルは複雑な要件を恐れませんが、曖昧な要件を最も苦手とします。** + +[データベースの章](../database-supabase/) で触れた `menu_items`(メニューテーブル)の新規作成インターフェースを例に、高品質な Prompt の書き方を見てみましょう。 + +## 3.1 大規模言語モデルに完全なコンテキストを提供する +AI にインターフェースを書かせる前に、必ず**データベースのフィールド定義(Schema)**と**具体的な制約条件**を提供してください。 + +> 🗣️ **高品質なプロンプト(Prompt)テンプレート:** +> "メニューの新規作成インターフェースを作ってください。メニューには商品名、価格、カテゴリ(バーガー、サイドメニュー、ドリンク)、販売状況の情報があります。商品名と価格は必須で、価格に負の値は指定できません。ユーザーの入力が正しくない場合はエラーメッセージを表示してください。" + +## 3.2 大規模言語モデルが生成したコードのレビュー +大規模言語モデルが生成したコードは、通常、次のように責務が明確に分割されています: + +```javascript +// services/menuService.js +const { createClient } = require('@supabase/supabase-js'); +const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY); + +exports.createMenuItem = async (menuData) => { + // Supabase SDK を呼び出してテーブルにデータを挿入 + const { data, error } = await supabase + .from('menu_items') + .insert([menuData]) + .select(); + + if (error) throw new Error(`データベースへの挿入に失敗しました: ${error.message}`); + return data[0]; +}; +``` + +この方式で生成されたコードは、構造が合理的であるだけでなく、Supabase の初期化、エラーキャッチ、例外処理まで考慮されています。単に「新規作成インターフェースを作って」と頼んで得られるスパゲッティコード(Spaghetti Code)とは雲泥の差があります。 + +--- + +# 4. 両手を解放する:インターフェース文書の自動生成 + +開発チームにとって、文書のない API はブラインドボックスのようなものです。フロントエンドエンジニアは、どのようなパラメータを渡せばよいのか推測できず、どのような構造が返されるのかも予測できません。業界で最も広く使われている API 記述規約は **OpenAPI(以前は Swagger とも呼ばれていました)** です。 + +かつて、YAML や JSON 形式の Swagger 文書を手書きすることは非常に苦痛で、エラーが発生しやすい作業でした。今では、これこそが大規模言語モデルの最も得意とする領域となっています。 + +先ほど書いた `routes` と `controllers` のコードを選択し、そのまま大規模言語モデルに渡すことができます: + +> 🗣️ **文書生成のプロンプト:** +> "上記のコードに基づいてインターフェース文書を生成してください。各パラメータの意味と返却されるデータを明確に記載し、フロントエンドの担当者が連携しやすいようにしてください。" + +この過程で、AI にフィールドの説明(Description)やモックデータ(例えば `price_cents: 1200` が 12 ドルを表す)の補完を要求することもでき、コミュニケーションコストを大幅に削減できます。 + +--- + +# 5. 品質保証:テストコードと Postman コレクションの生成 + +コードの作成と文書の生成が完了したら、最後のステップは「コードが実際に動作するかどうかを検証する」ことです。 + +## 5.1 Postman / Apifox テスト設定の生成 +インターフェース開発では、通常、Postman のようなビジュアルツールを使用して、フロントエンドからの HTTP リクエストをシミュレートします。大規模言語モデルを使わない場合、URL を手動で入力し、Header(リクエストヘッダー)を一つずつ追加し、JSON リクエストボディを組み立てる必要があります。 + +AI に次のように指示するだけです: +> "このインターフェース文書を Postman にインポートできる形式に変換してください。正常なリクエストとエラーリクエストの例を含めてください。" + +JSON テキストを取得したら、`menu_api.json` として保存し、Postman にドラッグするだけで、すぐに使えるテストパネルが手に入ります。 + +## 5.2 自動化ユニットテストの作成 +より厳密なエンジニアリング品質を追求する場合は、大規模言語モデルに `Jest` などのテストフレームワークを使ってユニットテスト(Unit Tests)を作成させ、コアビジネスロジックの境界テスト(例えば、負の価格が渡された場合、データベース層のバリデーションが有効に機能するかなど)を行うことができます。 + +--- + +# 6. バックエンドインターフェース開発者が知っておくべきベストプラクティス + +AI の支援があっても、システム全体の「ゲートキーパー」として、以下のコア原則を理解し、レビューする必要があります: + +1. **RESTful に準拠したパス命名**: + - 良い設計:`GET /api/users`(ユーザー一覧の取得)、`POST /api/users`(ユーザーの作成)。URL は「リソース」を表す名詞であるべきです。 + - 悪い設計:`POST /api/getUser` や `POST /api/createUser`。動詞は HTTP メソッド(GET/POST/PUT/DELETE)で表現するべきです。 +2. **標準的な HTTP ステータスコードの使用**: + - 200/201:リクエスト成功 / リソース作成成功。 + - 400:Bad Request。フロントエンドのパラメータ形式エラー、必須項目の不足。 + - 401/403:Unauthorized / Forbidden。ユーザーがログインしていない、または操作権限がない。 + - 404:Not Found。リソースが存在しない。 + - 500:Server Error。バックエンドコードのエラーやデータベースの障害。エラーのコールスタックをフロントエンドに直接露出させることは絶対に避けてください(セキュリティ上のリスクがあります)。 +3. **ユーザーの入力を決して信用しない**:フロントエンドからの入力は偽造されている可能性があります。すべてのコアパラメータの検証は、バックエンドインターフェースでも改めて行う必要があります。 + +# 7. まとめ + +この章の学習を通じて、あなたは開発の視点を真の意味で転換させました。もはや構文や句読点に囚われた「タイピスト」ではなく、**システムデザイナー兼アーキテクチャ指揮官**へと昇華したのです。 +あなたは以下のことを習得しました: +1. **API インターフェースとフロントエンド・バックエンド分離**というコアシステム思考。 +2. **コンテキストの提供と階層構造の概念**を通じて、大規模言語モデルが生成するサーバーサイドコードの品質を大幅に向上させる方法。 +3. 煩雑な**文書作成**や**テストケースの構築**を、AI が得意とする自動化タスクに巧みに転換する方法。 +4. これまでに学んだ **Supabase** の知識と組み合わせ、クライアントのリクエストからデータベースの更新に至るまでの完全なデータフローを貫通させたこと。 + +::: tip 💡 次のステップ +データフローとバックエンドサービスの準備が整った後も、現状ではローカルコンピューター上でのみ動作する状態です。次の章では、苦労して構築したサービスを**パブリックネットワークのサーバーにデプロイ(Deploy)**する方法を学び、世界中のユーザーがあなたの製品にアクセスできるようにします。 +::: diff --git a/docs/ja-jp/stage-2/backend/database-supabase/index.md b/docs/ja-jp/stage-2/backend/database-supabase/index.md new file mode 100644 index 0000000..3040fd9 --- /dev/null +++ b/docs/ja-jp/stage-2/backend/database-supabase/index.md @@ -0,0 +1,1742 @@ +# 从データベース到 Supabase + +前回のレッスンでは,我们学〜する了 UI 設計程序 Mastergo 和 Figma 的基本用法,〜できる够使用 github 进行コード的获取与バージョン管理,并通过 Zeabur デプロイ网站〜する自分で的アプリケーション / 网站传达给更多人使用。 + +をサポートするため大家更好地衔接知识,在开始本节课关于設計ツール与デプロイ的新内容前,让我们一緒に通过几道シンプルな题目快速回顾一下上节课的コア知识点: + +1. 何是フロントエンド設計ツール、Figma、MasterGo 的定义和使用方式。 +2. 〜する設計稿转换为コード的基本的な方法。 +3. 何是 Github,どのように設定 SSH,どのように構築自分で的第一个リポジトリ。 +4. デプロイ是何意思,どのように使用 Zeabur,どのように〜する Github 或本地コードデプロイ至公共网络给大家アクセス。 + +如果对以上すべての一个問題また印象模糊的地方,提案先回顾一下上节课的ドキュメント和讲义。欢迎随时在微信学习群中提出疑问。 + +このレッスンでは,します学习どのように让一个 APP / 网站从〜できる跑起来变为更接近真实线上产品:除了用データベース管理程序実行中的各种数据变化外,还〜する具备充実したユーザー体系(新規登録、ログイン、権限等)以及その他重〜するななバックエンド〜できる力。我们〜する以 Supabase 这一バックエンドサービスプラットフォーム为主线,先用它実装“データベース + ユーザーシステム”这两项基本的な機〜できる,再以 Supabase 提供的コンポーネント为参照,进一步理解现代云サービスバックエンドサービス通常含む的コアモジュール,以及各モジュール的具体职〜できる与作用逻辑。 + +# このレッスンで学ぶこと + +1. 何是数据、何是データベース,一般的なデータベース与使用方法 +2. 何是 supabase,どのように使用 supabase 进行基本的な的データベース操作 +3. どのように使用 supabase 为アプリケーション追加基本的なユーザー管理機〜できる +4. 学〜する Supabse 応用機〜できる:realtime、storage、edge function +5. 学〜する为Supabase増加 google 与 github ログインサポート + +- 一款サポートユーザー新規登録 / ログイン,并〜できる〜する数据存入在线データベース的基本的なアプリケーション +- 一套可复用的 Supabase バックエンドコードテンプレート(データベース + ユーザー管理等),供后续プロジェクト直接套用 + +# 1. 何是データベース + +## 1.1 何是数据 + +在数字世界里,数据(Data)无处不在。簡単に言うと,数据是信息的载体。你朋友的联系方式、一篇微信文章、一条短视频、游戏里的角色等级,これらの都是数据。在我们的アプリケーション中,数据である必〜するがある被レコード和管理的一切信息,例えばユーザー的个人资料、オーダー历史、程序设置等。 + +一般的に而言,数据在程序中有異なる的表现形式,最シンプルなである変数,できます用異なる変数レコードシンプルな数字: + +```python +# Python variable definition examples + +# Integer variable: stores age information +age = 30 + +# Boolean variable: stores status (whether active) +is_active = True # True means active, False means inactive + +# List variable: stores a set of score data +scores = [85, 92, 78, 90] # Contains 4 integer elements representing different scores + +# Dictionary variable: stores multiple related information of a user +user_info = { + "age": 30, # Key "age" corresponds to the value of age + "height": 1.80, # Key "height" corresponds to the value of height (unit: meter) + "login_count": 156 # Key "login_count" corresponds to the value of login times +} +``` + +而对于上述所说的个人资料、オーダー历史这类複雑な数据而言,できます用更複雑な表格进行数据的表示: + +| user_id | name | email | +| ------- | ----- | ----------------- | +| 1001 | Alice | alice@example.com | +| 1002 | Bob | bob@example.com | + +| order_id | user_id | amount | status | +| -------- | ------- | ------ | --------- | +| 901 | 1001 | 29.99 | completed | +| 902 | 1002 | 15.50 | pending | + +但对于结构複雑な、具有层级关系或フィールド不固定的数据,できます用 JSON 格式进行説明 —— 它是互联网通用的数据中间格式,几乎すべての程序都〜できる读取解析,跨システム传数据很方便。例えば,一个オーダー可〜できる性がある含む多个商品,各商品又有自分で的名称、数量和価格。用传统的表格来表示〜する很笨拙:〜する么得拆成 “オーダー表”“商品表” 多张表,靠关联フィールド才〜できる体现 “オーダー含む商品” 的关系;〜する么在一张表用 “商品 1 名称、商品 1 価格、商品 2 名称……” 这类冗余フィールド,遇到商品数量不固定时根本没法适配;而 JSON 〜できる直接用嵌套结构把 “オーダー - 商品 - 商品属性” 的层级说清,既直观又灵活。 + +```json +{ + "order_id": 901, + "user_id": 1001, + "amount": 29.99, + "status": "completed", + "items": [ + { "sku": "BG-001", "name": "牛肉汉堡", "quantity": 1, "price": 18.00 }, + { "sku": "SD-003", "name": "炸薯条", "quantity": 1, "price": 6.99 }, + { "sku": "DK-002", "name": "可乐", "quantity": 1, "price": 5.00 } + ], + "shipping_address": { + "street": "科技园路123号", + "city": "深圳", + "zip_code": "518057" + } +} +``` + +更进一步的,如果我们考虑一个被编码成ベクトル(Vector)的数据,ベクトル数据通常是文本、图片或音频等非结构化数据经过 AI モデル(如 Embedding モデル)処理后得到的数值表示。它的表示形式可〜できる性がある是: + +`[0.123, -0.456, 0.789, ..., -0.234]` (一个由几百甚至上千个浮点数组成的数组) + +总的来说,在现实世界中有太多異なる形态、用途的数据值得我们详细分析,每种数据可〜できる性がある都必〜するがある专门的データベース用于存储,具体可参考下图——是不是感觉非常に多? + +![](/zh-cn/stage-2/backend/database-supabase/images/image1.png) + +## 1.2 なぜ必〜するがありますデータベース + +すでに了解到真实世界中的数据しばしば结构複雑な,**为了高效存储与使用これらの数据,必〜するがあります一个专门的程序或容器来管理它们** —— 这便是データベース(Database)的诞生初衷。データベース本质上是一款特殊程序,コア作用である对数据进行规范化组织、セキュリティ存储、システム化管理,并サポート高效查询调用。 + +想象一下,若没有データベース,アプリケーション数据〜する陷入怎样的困境?当ユーザー关闭ブラウザ或退出アプリケーション时,すべての临时加载的信息都〜する直接丢失;我们既无法永久保存ユーザー的使用ステータス(例えばログイン信息、个性化设置),也没法在異なるユーザー間の共享重〜するなな数据(例えば商品库存、オーダーレコード)。必〜するがあります有一个装置帮我们存储すべての的数据! + +更柔軟な是,データベース的デプロイ方式可按需選択:既〜できるデプロイ在本地サーバー,满足数据本地化管理的〜する件;也〜できるデプロイ到云端,云端データベースサポート弹性扩容(Scale),可随数据量与アクセス量增长拡張〜できる力、承载海量数据与高并发,即便ユーザー量大幅提升,也〜できる保障ユーザー的正常使用体验。 + +归纳而言,データベース凭借効率的な持久化存储、精细化管理与快速查询〜できる力,主な解決了以下コア問題: + +- **数据的持久化存储** : 如果没有データベース,数据〜する仅存在于アプリケーション的内存中,一旦アプリケーション关闭,数据就〜する丢失。データベース解決了この問題,它〜する数据持久地存储在硬盘等存储介质上,確保了数据的长期保存,削減了丢失风险。 +- **便捷的数据查询与分析** : データベース提供了強力な查询语言(如 SQL),让ユーザー〜できる轻松、高效地对海量数据进行複雑な查询、筛选和分析,从而帮助企业做出更明智的决策。 如果没有データベース,从大量无序ファイル中查找特定信息〜する是一项極めて耗时且困难的タスク。 +- **サポート高性〜できる与高并发アクセス** : データベース通过索引最適化、查询缓存、接続池以及分布式架构等技术,〜できる够在毫秒级时间内レスポンス查询リクエスト,并支撑成千上万ユーザー的并发アクセス。这对于现代互联网アプリケーション(如电商プラットフォーム秒杀活动、社交网络リアルタイム动态)至关重〜するな,確保了システム的レスポンス速度和ユーザー体验。如果没有データベース的高性〜できる支撑,面对海量ユーザーリクエスト时システム〜する〜する出现严重遅延甚至崩溃。 +- **保証数据的完全な性和一致性** : データベース通过一系列机制(如约束、触发器)来確保数据的准确性和一致性。 这意味着データベース中的数据必須符合预设的ルール,例えば,ユーザー的年龄必須是数字,オーダー号必須是唯一的,从而有效防止了非法或无效数据的产生。 +- **確保数据的セキュリティ性** : データベース提供了強力なセキュリティ机制,包括ユーザー身份検証、アクセス控制和数据加密等,以保护数据免受未经授权的アクセス、変更或破坏。为了应对硬件故障、人为失误或恶意攻击等意外情况,データベース还提供了数据备份和恢复機〜できる。 通过定期的に备份,〜できる在数据丢失或损坏时及时恢复,保障了业务的连续性。 + +## 1.3 关系型データベース与非关系型データベース + +前すでに了解了データベース的コア价值、デプロイ方式与弹性优势,而在实际選択时,まず〜する面对的であるデータベース的两大コア类别:关系型データベース与非关系型データベース(NOSQL),できます用シンプルな两段话シンプルな理解他们的区别: + +关系型データベース就像结构严谨的Excel表格,すべての数据必須预先定义好格式(定义好 Schema 的内容, 例えば〜する有姓名和年龄,且姓名必須是文字,年龄必須是数字),并通过关联フィールド(用来接続異なる表格的标识,如身份证号)〜する異なる表格接続起来。它的好处是数据精确可靠,特に适合银行转账、库存管理等不〜できる出错的シナリオ,但缺点是调整结构かなり麻烦,海量数据下性〜できる〜する受限。 + +非关系型データベース则像柔軟なファイル夹,〜できる存放格式各异的ドキュメント、图片或键值对(類似字典的"词-解释"结构),不必〜するがある提前规定好每份数据的结构。它更容易应对快速变化的〜する件和超大规模数据(例えば社交媒体的海量帖子),拡張(増加サーバー提升性〜できる)起来也更方便,但牺牲了部分关联查询〜できる力(跨異なる数据表整理信息的〜できる力)和一致性保障(確保数据时刻准确不矛盾),适合对容错性〜する求较高的互联网アプリケーション。 + +那么,实际アプリケーション中该どのように選択データベース?从シナリオ划分总结来看,关系型データベース一般的な于金融交易、库存管理、オーダー処理、账务システム等必〜するがある强一致性、複雑な事务処理以及頻繁に读写均衡アクセス的シナリオ;而非关系型データベース更适配社交媒体内容存储、リアルタイムログ分析、物联网海量数据写入、お勧めシステム特征读多写多等高并发、读写模式不均衡且结构柔軟な〜する件。 + +但对于企业而言,在初级阶段并不必〜するがある花大量时间思考何必〜するがある使用何データベース。当前的データベース已是非常に成熟的产品サービス,最直接的方式是咨询異なる云サービス厂商(指提供サーバー、存储、データベース、软件、算力等 IT 资源与技术サービス的サービス商)。我们可直接对接云サービス官方销售,根据自身产品业务〜する件匹配适配的データベースソリューション;而構築企业级アプリケーション的便捷パス,便是优先与专业厂商合作。(需注意:企业级サービス価格通常较高,提案先多方调研对比,也可選択购买サーバー自行デプロイ开源データベース程序作为替代ソリューション。) + +また可参考某家云厂商的[データベース选型お勧め](PROT166),根据シナリオ可进行異なるデータベース类型的選択,できます对比異なる云厂商的データベース规格选出最合适的进行使用。 + +| データベース类型 | データベース名称 | 価格 | 适用シナリオ | +| ------------ | ---------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 关系型データベース | RDS MySQL版 | 低 | 基本的な版:学习以及小型网站高可用版:一定业务压力的中型データベースシナリオ集群版:业务不許可中断,アクセス压力较大 | +| | RDS SQL server版 | 高 | 基本的な版:テスト以及小型商业化网站高可用版:企业级商业化网站集群版:企业业务不許可中断,アクセス压力较大 | +| | RDS PostgreSQL版 | 最低 | 基本的な版:学习以及小型网站高可用版:一定业务压力的中型データベースシナリオ集群版:业务不許可中断,アクセス压力较大的シナリオ,其性〜できる较一般的にMySQL高 | +| | RDS PPAS版 | 高 | 通用型:兼容Oracle业务,但业务压力Udacity,虚拟化〜できる满足其〜する件独享型:面对必〜するがある独享物理机的业务,一般的に为高并发Oracle类业务 | +| | DRDS | 中 | 入門バージョン:4 Core 8 G,価格亲民,适合中小型在线业务企业版:16 Core 32 G,複雑な SQL レスポンス好,适合超高并发在线业务至尊版:32 Core 64 G,複雑な SQL 実行レスポンス最好,提供超大规格選択 | +| NoSQLデータベース | Redis | 中 | 双机热备Redis:一般的に作为持久化データベース向上业务可用性集群バージョン的Redis:一般的に作为缓存层,加速アプリケーションアクセス,解決一般的にデータベース无法负载的读取压力 | +| | MongoDB版 | 中 | 单节点实例单节点:适用于開発、テスト及その他非企业コア数据存储的シナリオ副本集实例:适用于某些业务シナリオ下对データベース有更高读取性〜できる〜する件,如阅读类网站、オーダー查询システム等读多写少シナリオ或有临时活动等突发业务〜する件分片集群实例:基于多个副本集(各副本集沿用三副本模式)组成的分片集群实例,提供更高的读取性〜できる〜する件,为リアルタイム在线业务提供高速读取性〜できる | + +光说不易理解,我们通过一个具体的な“博客文章”シナリオ,来看看同样的数据在关系データベース (SQL) 和異なる类型的非关系データベース (NoSQL) 中是どのように存储的。 + +假设我们有一个博客プラットフォーム,必〜するがある存储以下信息: + +- ユーザー(Users):ユーザー ID、ユーザー名、邮箱 +- 文章(Posts):文章 ID、标题、内容、作者 ID +- 评论(Comments):评论 ID、评论内容、评论者 ID、所属文章 ID +- 标签(Tags):标签 ID、标签名 +- 文章与标签的关系:单篇文章关联的多个标签、单个标签对应的多篇文章 + +### 关系データベース (SQL) 例 + +在SQLデータベース中,我们〜する〜する異なる类型的数据それぞれ存储在異なる的表中,并通过“外键”〜する它们关联起来。这种结构清晰、规范,減少了数据冗余。 + +以 “内容プラットフォーム的文章管理” 为例,我们不〜する把 “ユーザー、文章、评论、标签” 混存,而是拆成 5 张機〜できる单一的表,每张表都有明確な “責務边界” 和严格的结构定义(Schema): + +- `users` 表 (存储ユーザー信息) + +| user_id (主键) | username | email | +| -------------- | -------- | ----------------- | +| 101 | Alice | alice@example.com | +| 102 | Bob | bob@example.com | + +- `posts` 表 (存储文章信息) + +| post_id (主键) | title | content | author_id (外键) | +| -------------- | --------- | ------------------------------ | ---------------- | +| 1 | 初识SQL | 这是关于SQLデータベース的一篇文章... | 101 | +| 2 | NoSQL入門 | NoSQL提供了柔軟な数据モデル... | 102 | + +- `comments` 表 (存储评论信息) + +| comment_id (主键) | body | commenter_id (外键) | post_id (外键) | +| ----------------- | ---------------- | ------------------- | -------------- | +| 1001 | 写得很棒! | 102 | 1 | +| 1002 | 学习了。 | 101 | 2 | +| 1003 | 有没有更多例子? | 101 | 1 | + +- `tags` 表 (存储标签) + +| tag_id (主键) | tag_name | +| ------------- | -------- | +| 51 | データベース | +| 52 | 技术 | +| 53 | 入門 | + +- `post_tags` 表 (存储文章与标签的多对多关系,体现联表特点) + +| post_id (外键) | tag_id (外键) | +| -------------- | ------------- | +| 1 | 51 | +| 1 | 52 | +| 2 | 51 | +| 2 | 52 | +| 2 | 53 | + +若需查询 “Alice 发表的《初识 SQL》(post_id=1)的完全な信息(含文章内容、作者、评论、标签)”,需実行多表接続(JOIN)查询,通过外键关联 5 张表并聚合数据,SQL 语句如下: + +```sql +SELECT + p.title, + p.content, + u.username AS author, + c.body AS comment, + t.tag_name AS tag +FROM + posts p +JOIN + users u ON p.author_id = u.user_id +LEFT JOIN + comments c ON p.post_id = c.post_id +LEFT JOIN + post_tags pt ON p.post_id = pt.post_id +LEFT JOIN + tags t ON pt.tag_id = t.tag_id +WHERE + p.post_id = 1; +``` + +この查询〜する跨越5个表,〜するすべての相关数据聚合在一緒に返す。这是关系データベース的コア优势:通过规范化和接続操作,〜できる灵活地进行各种複雑な查询, 保証了数据的一致性和最小冗余。 + +### 非关系データベース (NoSQL) 例 + +NoSQL データベース(如 MongoDB、Redis)的設計思路与 SQL 相反,它不强调数据的拆分与规范,通常〜する〜する业务上相关联的すべての数据打包聚合在一緒に,以減少查询时的接続操作,从而向上读取性〜できる。 + +在 NoSQL データベース中,ドキュメントデータベース(Document Database) 是最常用的类型之一,MongoDB である典型代表。它以 “ドキュメント” 作为基本存储单元,ここ的 “ドキュメント” 并非我们日常理解的 “文章”,而是1 つの類似 JSON 的数据结构(MongoDB 中实际使用 BSON 格式,サポート更多数据类型):无需预先定义統一された Schema(数据结构),各ドキュメント的フィールド〜できる灵活增减,フィールド类型也〜できる自由调整,完美适配数据格式多变的シナリオ。 + +在ドキュメントデータベース中,通常〜する〜する一篇文章及其すべての相关信息(如评论、标签)存储在一个ドキュメント中(ドキュメント格式類似 JSON,可灵活定义フィールド,无需预先制定 Schema),コア逻辑是 “〜する‘一个业务シナリオ下的完全な信息’存放在一个ドキュメント中”,回避查询时的多数据源拼接。 + +`posts` 集合中的一个ドキュメント例: + +```json +{ + "_id": 1, + "title": "初识SQL", + "content": "这是关于SQL数据库的一篇文章...", + "author": { + "user_id": 101, + "username": "Alice", + "email": "alice@example.com" + }, + "tags": [ + "数据库", + "技术" + ], + "comments": [ + { + "comment_id": 1001, + "body": "写得很棒!", + "commenter": { + "user_id": 102, + "username": "Bob" + } + }, + { + "comment_id": 1003, + "body": "有没有更多例子?", + "commenter": { + "user_id": 101, + "username": "Alice" + } + } + ] +} +``` + +这种設計的优势非常に直观:当必〜するがあります获取 “第一篇文章的完全な信息(含作者、评论、标签)” 时,只需通过 `_id:1` 查询这一个ドキュメント,データベース一次读取就〜できる返すすべての数据,无需像 SQL 那样実行 3-4 次表接続操作,读取效率大幅提升。 + +但它也存在明显的 trade-off(取舍):由于数据是 “聚合存储”,〜する不可回避地产生数据冗余—— 例えば作者 “Alice” 的 `username` 被エンベディング到她写的每一篇文章ドキュメント中,如果某天 “Alice” 〜するユーザー名改为 “Alice_New”,理论上必〜するがある遍历すべての含む她信息的文章ドキュメント,逐一更新 `author.username` フィールド,不仅操作繁琐,还可〜できる性がある因网络或サーバー問題导致部分ドキュメント更新失敗,出现 “同一ユーザー在異なる文章中ユーザー名不一致” 的情况。 + +ただし実際のビジネスでは,这种冗余しばしば是 “可接受的”:对于博客、资讯、电商商品详情等 “ **读多写少** ” 的シナリオ(ユーザー確認内容的次数远多于作者変更ユーザー名的次数),用少量的冗余换取 “极致的读取性〜できる” 是更优的選択;而如果是 “写多读少”(如頻繁に変更ユーザー信息)的シナリオ,则必〜するがある结合业务〜する件权衡是否使用ドキュメントデータベース。 + +以上是对異なるデータベース的シンプルな介绍,如果你对更多具体的なデータベース类型感兴趣,できます参考如下资料尝试異なる类型的データベース。 + +Examples of SQL databases: +[Db2](PROT167)、[MySQL](PROT168)、[PostgreSQL](PROT169)、[YugabyteDB](PROT170)、[CockroachDB](PROT171)、[Oracle Database](PROT172)、[Azure SQL Database](PROT173) + +Examples of NoSQL databases: +[Redis](PROT174)、[CouchDB](PROT175)、[MongoDB](PROT176)、[Cassandra](PROT177)、[Elasticsearch](PROT178)、[BigTable](PROT179)、[Neo4j](PROT180)、[HBase](PROT181) + +# 2. Supabase + +在前すでに介绍了几类よくあるデータベース,以及它们各自适合的使用シナリオ。ただし在真实プロジェクト里,データベース通常只是バックエンド体系中的一个基本的なモジュール:除了存储和查询数据,你还必〜するがある解決**ユーザー新規登録ログイン、権限校验、ファイルアップロード与存储、对外 \*\***API\***\* インターフェース、甚至定时タスク、リアルタイム通知**等一整套問題。仅仅选好データベース,并不〜できる让你的アプリケーション“立刻就〜できる上线実行”,中间还隔着一大圈繁琐的バックエンド工程工作。 + +そのため,必〜するがあります考虑一个更大的背景: **バックエンドサービス** 。一个完全なアプリケーション,通常都由“フロントエンド + バックエンド”组成:フロントエンド负责ページ表示和ユーザー交互,バックエンド则负责数据存储、ユーザーログイン、业务逻辑処理等。过去,開発者しばしば必〜するがある自分で搭建サーバー、設定データベース、設計并実装 API,还〜する手動で処理権限管理、セキュリティ戦略、拡張性和モニタリング运维等事务,全体の过程既重复又耗时。を解決するためこれらの重复劳动,业界出现了 **BaaS(Backend as a Service,バックエンド即サービス)** :把データベース、ユーザー认证、ファイル存储、リアルタイム〜できる力等一般的なバックエンド機〜できる打包成一个云端プラットフォーム,開発者通过 SDK / API 就〜できる直接调用これらの〜できる力,而无需从零搭建和运维基本的な设施。 + +在この背景下,[Supabase](PROT182) 就〜できる看作是新一代的 BaaS 代表:它以 PostgreSQL 作为コアデータベース,在其之上集成了 Auth、Storage、Realtime、Edge Functions、Vector 等一整套バックエンド〜できる力,为開発者提供一个“以 Postgres 为中心的一站式バックエンドプラットフォーム”。次に,我们就从この角度出发,从“只选データベース”アップグレード到“選択完全なバックエンド開発プラットフォーム”,具体看看 Supabase 〜できる帮我们省掉哪些工作,又是どのように让一个プロジェクト从原型到可用产品的距离大幅缩短的。 + +## 2.1 分步指南 + +在清晰把握 Supabase 的整体定位后,次にします沿着 Supabase 控制台的操作パス,逐项拆解它具体提供哪些コア〜できる力,以及每项〜できる力对应的コア責務。我们〜する详细介绍 supabase 涉及的各选项,帮助你快速入門 supabase 的基本操作。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image2.png) + +アクセス Supabase 官网并ログイン后,在控制台首页クリック New project 进入作成プロセス; + +入力必〜するがある設定的主な内容 Project Name、データベース密码,地址只必〜するがある選択为与程序目標ユーザー最接近的区域即可。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image3.png) + +作成成功后,控制台左侧侧边栏〜する表示すべてのコア機〜できるモジュール(Table Editor、SQL Editor、Database、Authentication 等),后续操作〜する围绕これらのモジュール展开。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image4.png) + +### 表編集器 + +Table Editor 〜できる当成是 Supabase 的可视化数据表編集器,它〜できる让你像操作 Excel 一样直接確認和変更データベース里的数据,无需编写 SQL 语句,只必〜するがある用鼠标交互即可変更数据内容。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image5.png) + +其中值得关注的是 Schema,Schema 可理解为データベース内的 “资源容器”,用于对表、视图、函数、索引等资源进行分组管理,主な作用有二:一是回避命名冲突(異なる Schema 下可存在同名table),二是実装権限隔离(如仅許可特定ユーザーアクセス某 Schema 下的表); + +クリック編集器顶部的 Schema 下拉框可切り替え異なる容器,日常開発中一般的に只需关注两类: + +- `public`:デフォルトの公共资源容器,開発者新建的业务表(如 “文章表”“评论表”)均存储于此; +- `auth`:ユーザー认证专属容器,其中的 `users` 表自動存储すべての新規登録ユーザー信息(如ユーザー ID、邮箱、ログイン时间),不提案手動で変更此 Schema 下的デフォルト表,回避影响认证機〜できる; + +![](/zh-cn/stage-2/backend/database-supabase/images/image6.png)![](/zh-cn/stage-2/backend/database-supabase/images/image7.png) + +### SQL 編集器 + +SQL Editor 作为 Supabase 的 SQL 语句実行器,可让你用コード的方式直接操作データベース。できます让大規模モデル直接生成 SQL 语句,在右侧入力后クリック RUN 即可用语句作成或変更 table,也〜できる直接在 Results 中直接看到筛选出的 table 数据。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image8.png) + +できます在実行 RUN 後に,在 Table Editor 的 public schema 里找到新建后的数据表;并且実行后的语句〜する保存在左侧的 PRIVATE 栏中,甚至〜できるクリック下方的爱心标志对这一条查询或作成语句进行收藏。 + +### データベース管理中心 + +Database 是 Supabase 的データベース管理中心,サポート可视化地確認和管理すべての数据表,并通过表的相互连线理解異なる表间的关联关系(即外键约束,表示数据间的引用关系)。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image9.png) + +如果你〜したい手動で新建 table,〜できる在 tables 中直接新建表格,我们〜する在後に的チュートリアル中详细讲解。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image10.png) + +### 身份认证 + +Authentication 负责管理ユーザー的新規登録、ログイン和権限。デフォルトのユーザー管理システム数据都在此处存储,它提供了开箱即用的ユーザー新規登録、ログイン、密码重置、邮箱検証等機〜できる,并サポート第三方 OAuth ログイン(如微信、GitHub、Google 等)。すべてのユーザー数据〜する自動同步到データベース的 `auth.users` 表中。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image11.png) + +できます在 Provider 选项中找到異なる supabase サポート的ユーザー信息ログイン入口,デフォルト使用 Email;如果你想使用 Github 或者 Google 账户进行ログイン,还必〜するがある更多属性設定,我们〜する在下的レッスン中进行详细讲解。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image12.png) + +在 Sign In / Providers 里还含む了对新規登録邮箱行为的控制,如果你不想每次邮箱新規登録都必須让ユーザー接受邀请后才〜できる成为ユーザー,できます取消 Confirm email 的强制〜する求。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image13.png) + +如果你想切り替え非 Supabase 的その他 auth システムサービス商,できますクリック Third Party Auth,例えば此处就使用 Clerk 作为第三方的システムサービス商。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image14.png) + +如果你担心新規登録ユーザー在短期内アクセス量过大,できます在 Rate Limits 中启用对应的流量限制戦略: + +![](/zh-cn/stage-2/backend/database-supabase/images/image15.png) + +### 存储 + +Storage 是 Supabase 的存储システム,兼容 amazon cloud 的 s3 概念,可用于存储任意类型的ファイル(如图片、视频、ドキュメント、音频等),并提供アクセス権限管理(公开或私有)和ダウンロードリンク获取(永久リンク或临时リンク),你〜できる够很方便在アプリケーション中对ユーザー涉及到的ファイル内容进行アップロード与ダウンロード管理,并与 Supabase 的认证システム无缝集成,実装精细化的アクセス控制。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image16.png) + +します〜する在本节课的応用 project 中讲解 storage 的具体用法。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image17.png) + +如果你想使用 S3 的相关协议进行操作,〜できる直接使用对应的設定: + +![](/zh-cn/stage-2/backend/database-supabase/images/image18.png) + +> Amazon Cloud(亚马逊云サービス,简称 AWS)是亚马逊提供的云计算プラットフォーム(就像一个大型的网络机房,できます按需租用计算和存储资源)。S3(Simple Storage Service)是 AWS 里专门用来存储ファイル的サービス(類似一个无限大的网盘,〜できる存图片、视频、备份等各种ファイル),它是目前最流行的对象存储サービス,すでに成为了事实上的行业標準。 +> +> **なぜ〜する做成 S3 兼容 \*\***API\*\* ** ?** :S3 すでに存在近 20 年,市面上有大量现成的ツール、SDK 和ドキュメント,兼容 S3 意味着できます直接用これらの资源,不用从头开始制作各类相关ツール,〜できる够快速满足业务上线的〜する件。 + +### 边缘函数 + +如果你不想デプロイバックエンド,しかし想使用データベース和函数操作,できます使用 Edge Functions 構築无需自建サーバー的バックエンドコア〜できる力,它是 Supabase 提供的全球分布式サービス端函数。簡単に言うと,它让你无需购买和管理自分で的バックエンドサーバー,就〜できる直接编写并デプロイ在云端的バックエンドコード。これらの函数デプロイ在全球网络的边缘节点上,〜する自動在离你的ユーザー最近的位置実行,从而大幅削減网络遅延,提供极致的レスポンス速度。できます在 Supabase 的仪表盘中直接作成、編集和デプロイ,全体の開発プロセス非常に便捷。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image19.png) + +Edge Functions 的一个コア用途是充当セキュリティな中间层,保护你的敏感信息和鉴权キー。在フロントエンドコード中直接调用第三方サービス(如 OpenAI、Stripe)〜する暴露你的 API Key,带来极大的セキュリティ风险。通过 Edge Functions,你的フロントエンドアプリケーション只与你的 supabase 函数通信,すべての秘密只在 supabase 中保管。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image20.png) + +Edge Functions 的函数使用 secrets 中暴露的キー作为環境変数,通过 `Deno.env.get` 加载,从而実装第三方サービス的调用。这样一来,敏感キー就永远不〜する暴露在クライアント(你的ブラウザ),彻底杜绝了被盗用的风险。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image21.png) + +リクエスト Supabase Edge Function 时,需在リクエスト头携带对应的 Supabase キー,下是一个极简例: + +```javascript +// 核心配置(替换为你的实际信息) +const projectId = "你的 Supabase 项目ID"; +const functionName = "目标 Edge Function 名称"; +const supabaseKey = "Supabase anon_key"; + +// 调用函数 +async function callEdgeFunction() { + const url = `https://${projectId}.supabase.co/functions/v1/${functionName}`; + + try { + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${supabaseKey}` // 关键:携带密钥完成认证 + }, + body: JSON.stringify({ order_id: "123", action: "refund" }) // 自定义请求数据 + }); + + const result = await response.json(); + console.log("调用成功:", result); + } catch (error) { + console.error("调用失败:", error.message); + } +} + +// 执行调用 +callEdgeFunction(); +``` + +さらに,Edge Functions 与 Supabase 的ユーザー认证システム无缝集成。当已ログイン的ユーザー调用一个函数时,其身份信息〜する传递给函数。这使得できます在函数内部轻松识别当前ユーザー,并根据其身份実行権限控制。更重〜するなな是,函数在操作データベース时〜する自動遵循你设置好的行级セキュリティ戦略(Row Level Security),確保ユーザー只〜できるアクセス和変更他们有权操作的数据,让構築セキュリティな多ユーザーアプリケーション变得シンプルな。 + +Edge Functions 的アプリケーションシナリオ非常に广泛,〜できる够処理各种バックエンドタスク。它们非常に适合用来监听来自第三方サービス的 Webhook 事件(例えば決済成功、コード提出等),并自動実行相应的数据処理逻辑。你也〜できる用它来送信邮件通知、生成 PDF 报告、作成自定义的 API インターフェース来封装複雑な业务逻辑,或者実行すべての你〜を希望する在サービス端完了的计算タスク,极大地拡張了你アプリケーション的〜できる力。 + +具体到一个よくある例子:身份认证ツール Clerk 。Clerk 仅用于処理ユーザーログイン、新規登録、信息更新等认证相关操作,并不直接管理你的业务データベース。如果你〜したい〜するこれらの认证动态同步到业务データベース中,则必〜するがある通过触发 Webhook 事件リクエスト Edge Functions 実装。Edge Functions 〜できる够监听 Clerk 发出的 Webhook 信号,自動実行数据同步逻辑,让 Supabase データベース中的ユーザー信息与 Clerk ログインステータスリアルタイム对齐,全程无需你デプロイ独立バックエンド。 + +### リアルタイム数据同步引擎 + +Realtime 是 Supabase 的リアルタイム数据同步引擎,它許可你的アプリケーション即时受信データベース的变化通知,而无需反复轮询 API。当データベース中的数据发生 `INSERT`、`UPDATE` 或 `DELETE` 操作时,Realtime 〜する通过 WebSocket 〜するこれらの变化リアルタイム推送给すべての已接続的クライアント。这对于構築必〜するがあるリアルタイム交互的アプリケーション至关重〜するな。 + +Realtime 主な含む三大コア機〜できる,覆盖了绝大多数リアルタイムシナリオ: + +1. **Postgres Changes:** 直接监听データベース表的变化。できます精确地サブスクリプション特定表、特定事件(增、删、改),甚至〜できる根据筛选条件来受信通知,并与行级セキュリティ戦略(Row Level Security)完美集成,確保ユーザー只〜できる收到他们有権限確認的数据变更。 +2. **Broadcast:** 許可クライアント間の通过频道(Channel)送信低遅延的临时消息。这非常に适合実装チャット室、リアルタイム光标追踪、在线游戏ステータス同步等機〜できる。 +3. **Presence:** 用于追踪和同步在线ユーザーステータス。できます用它来轻松実装“誰在线上”、“当前有X人正在確認”等機〜できる,非常に适合协作类アプリケーション。 + +我们〜する在后续的プロジェクト制学习中详细介绍该部分的内容。 + +### プロジェクト设置 + +Project Settings 是 Supabase プロジェクト的高度な設定部分,你可在此実装计算资源的深度调度,以及各类機〜できる底层パラメータ的精细化設定。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image22.png) + +在入門阶段,必〜するなのは聚焦以下两个コア板块,一个是 Data API,我们在此可获取重〜するなな的 “Supabase URL”, 它是形如 `https://xxx.supabase.co` 的 RESTful 端点,是すべての数据查询、新增、変更、削除操作的 “入口地址”。フロントエンド或サービス端需通过该 URL 初始化 Supabase クライアント,建立与データベース的接続。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image23.png) + +別の重点是 API Keys,選択 “Legacy anon, service_role API keys” 标签页,其中的 anon public キー 是フロントエンドシナリオ的重〜するな身份凭证,它的権限被 RLS 严格限制,仅〜できるアクセスユーザー被授权的数据。而 service_role キー属于 “サービス端高権限キー”,具备绕过行级セキュリティな〜できる力,可実行批量数据操作、システム级設定等敏感操作。绝对禁止公开分享,若泄露需立即生成新キー并更新サービス端設定。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image24.png) + +其余設定项在当前阶段无需深究,待后续有応用使用〜する件时再逐一探索即可。 + +## 2.1 作成你的第一个 SQL 数据表 + +以上是 Supabase 的界面介绍,次にします深入 Supabase 的コアデータベース的操作环节。 + +在 Supabase 中作成数据表,主な有以下两种常用方式,できます根据〜する件選択: + +1. (お勧め)借助大規模言語モデル生成适配 Supabase 的 SQL 语句,直接在 **SQL Editor(** 前文介绍的 SQL 语句実行器)中貼り付け実行,高效快捷,我们〜する在下个部分环节重点说明この操作过程。 +2. 通过可视化操作作成:在左侧侧边栏找到 Database モジュール,クリック进入后选中侧边栏的 Tables,在右侧クリック New table 按钮,即可通过图形化界面作成数据表。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image25.png) + +注目すべき点として,对应数据表的名称以及存储的数据类型可在下方的 Columns 中指定。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image26.png) + +对于关系データベース,其中很重〜するなな特点是表与表間の的关联,できます在下方找到 `Foreign keys` ,クリック作成相应的关联关系: + +![](/zh-cn/stage-2/backend/database-supabase/images/image27.png) + +其中 `Foreign keys` 表达了表与表間の的关联关系:一个或一组フィールド,它在当前表(子表)中的值,〜する引用另一张表(父表)中主键的值。 + +例えば,在作成 `学生表`的时候,できます这样定义外键:(`所属班级编号` 这一列是一个外键。この外键引用了 `班级表` 里的 `班级编号` 这一列。) + +```sql +CREATE TABLE 学生表 ( + 学生学号 INT PRIMARY KEY, + 学生姓名 VARCHAR(50), + 所属班级编号 INT, + FOREIGN KEY (所属班级编号) REFERENCES 班级表(班级编号) +); +``` + +更具体举例而言,できます可视化观察对应的表的结构: + +班级表: +这张表里レコード了すべての班级的信息,各班级都有一个独一无二的班级编号。班级编号である这张表的主键 (Primary Key),是各班级的唯一身份证。 + +| 班级编号 | 班级名称 | +| -------- | ---------- | +| 101 | 一年级一班 | +| 102 | 一年级二班 | + +学生表: +这张表レコード了すべての学生的信息。各学生都属于一个特定的班级,对吗?那么我们どのように知道どの学生在どの班级呢? + +できます在学生表里増加一列,叫做 `所属班级编号`。 + +| 学生学号 | 学生姓名 | 所属班级编号 | +| -------- | -------- | ------------ | +| 2024001 | 张三 | 101 | +| 2024002 | 李四 | 102 | +| 2024003 | 王五 | 101 | + +在该例子中,学生表中的 `所属班级编号` 列である外键 (Foreign Key)。 + +在 Supabse 中,クリック追加 Foreign Key 后,你可直接選択进行关联表对应列的选取 + +![](/zh-cn/stage-2/backend/database-supabase/images/image28.png) + +## 2.3 SQL Editor 简介与データベース基本操作 + +次にします分步実行一系列 SQL 脚本,熟悉よくある SQL 中的增删查改操作。できます〜する各ステップ的コードコピー到 SQL Editor 中,実行并观察結果。 + +できます在该ディレクトリ下获得すべての的テスト SQL ファイル: + +https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos/tree/main/apps/sql-examples + +### **2.3.1 **`CREATE`** - 作成表结构** + +`CREATE TABLE` 语句用于为新表定义模式(Schema),包括其列(Columns)、对应的数据类型(Data Types)以及すべての约束(Constraints),シンプルな理解是作成了一个数据表。 + +```sql +-- Step 1: Create the 'orders' table +-- This file is fully independent and creates a sample table for later steps. +CREATE TABLE IF NOT EXISTS orders ( + id serial PRIMARY KEY, + user_id int NOT NULL, -- User ID + status text NOT NULL, -- Order status (e.g. paid, pending) + amount numeric(10, 2) NOT NULL, -- Order total amount + details jsonb, -- Item and extra details as JSON + placed_at timestamptz DEFAULT now(), -- Order creation time + is_paid boolean DEFAULT false -- Paid flag +); + +-- Expected Output: +-- Orders table created if it did not exist. +-- No data inserted. (Querying returns zero rows for now.) +-- If table already exists, no error occurs. +``` + +成功実行后,システム〜する提示脚本已完了。できます在 Table Editor 中看到对应的表被作成完了: + +![](/zh-cn/stage-2/backend/database-supabase/images/image29.png) + +### **2.3.2 **`INSERT`** - 填充初始数据** + +表结构作成完毕后,次のステップ是使用 `INSERT INTO` 语句向表中追加数据行。 + +```sql +-- Step 2: Insert initial rows into the orders table +-- Provides realistic, varied data for demo/testing. All values are self-contained. +INSERT INTO orders (user_id, status, amount, details, placed_at, is_paid) VALUES + (2001, 'pending', 23.50, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '2 days', false), + (2002, 'paid', 50.00, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":2,"price":5.00}]}', now() - interval '1 day', true), + (2003, 'cancelled', 15.00, '{"items":[{"sku":"FRY001","name":"French Fries","qty":3,"price":5.00}], "reason":"Not available"}', now() - interval '45 days', false), + (2004, 'paid', 22.98, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":2,"price":9.99}], "promo":"SUMMER22"}', now() - interval '10 days', true), + (2005, 'pending', 18.75, '{"items":[{"sku":"SAL001","name":"Salad","qty":1,"price":6.75},{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '7 hours', false), + (2006, 'paid', 8.00, '{"items":[{"sku":"DRK002","name":"Cola","qty":2,"price":4.00}]}', now() - interval '3 hours', true), + (2007, 'refunded', 14.50, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99},{"sku":"FRY001","name":"French Fries","qty":1,"price":4.51}], "refund_reason":"Late delivery"}', now() - interval '15 days', false), + (2008, 'paid', 26.99, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":1,"price":6.99}]}', now() - interval '12 days', true), + (2009, 'pending', 9.99, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99}]}', now() - interval '30 minutes', false), + (2010, 'paid', 19.89, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00},{"sku":"DRK002","name":"Cola","qty":2,"price":3.95}]}', now() - interval '5 days', true), + (2011, 'cancelled', 0.00, '{"items":[], "reason":"User cancelled"}', now() - interval '2 days', false); + +-- Expected Output: +-- After running this script, SELECT * FROM orders will show about 11 rows with varied user_id, status, amount, details (JSON), placed_at, and is_paid fields. +-- For example: +-- | id | user_id | status | amount | is_paid | placed_at | +-- |----|---------|-----------|--------|---------|---------------------| +-- | 1 | 2001 | pending | 23.50 | false | 2025-10-28 13:40:00Z| +-- | 2 | 2002 | paid | 50.00 | true | ... | +-- |... | ... | ... | ... | ... | ... | +``` + +実行成功后,此时表中すでに插入了原始数据,できます进入到 Table Editor 界面更新后看到結果,也〜できる直接在 SQL Editor 界面中新建窗口,実行查询语句 `SELECT * FROM orders;`確認結果: + +![](/zh-cn/stage-2/backend/database-supabase/images/image30.png) + +### **2.3.3 **`SELECT`** - 读取与查询数据** + +`SELECT` 语句用于从表中检索数据。通过使用異なる的子句,〜できる実装对数据的精确筛选、排序和格式化,我们可参考以下语句一步步実行確認結果: + +```sql +-- Step 3: SELECT query examples for the orders table + +-- Example 1: Select all fields for all orders +SELECT * FROM orders; +-- Expected Output: Returns all rows and fields. Columns: id, user_id, status, amount, details, placed_at, is_paid. + +-- Example 2: Select only pending orders +SELECT id, user_id, amount FROM orders WHERE status = 'pending'; +-- Expected Output: All rows with status 'pending'; columns: id, user_id, amount. + +-- Example 3: Select specific fields and filter by payment status +SELECT id, status, is_paid, amount FROM orders WHERE is_paid = true; +-- Expected Output: All rows where is_paid is true; columns: id, status, is_paid, amount. + +-- Example 4: Extract all item names from the details (JSON) for each order +SELECT id, details -> 'items' AS item_list FROM orders; +-- Expected Output: Each row shows id and an array from JSON with item details. +``` + +- **例 1:** 返す `orders` 表中的すべての行和列,与ステップ2的输出類似。 +- **例 2:** 仅返すステータス为 'pending' 的オーダー,且只含む指定的列: + +![](/zh-cn/stage-2/backend/database-supabase/images/image31.png) + +- **例 3:** 仅返す已決済的オーダー,并表示指定的列: + +| id | status | is_paid | amount | +| --- | ------ | ------- | ------ | +| 2 | paid | true | 50.00 | +| 4 | paid | true | 22.98 | +| 6 | paid | true | 8.00 | +| 8 | paid | true | 26.99 | +| 10 | paid | true | 19.89 | + +- **例 4:** 返す各オーダー的 `id` 和从 `details` フィールド中提取的 `items` 数组: + +| id | item_list | +| --- | -------------------------------------------------------------------------------------------------------------------- | +| 1 | `[{"qty":1,"sku":"BGR001","name":"Beef Burger","price":12}]` | +| 2 | `[{"qty":2,"sku":"BGR002","name":"Chicken Burger","price":10},{"qty":2,"sku":"DRK001","name":"Lemonade","price":5}]` | +| 3 | `[{"qty":3,"sku":"FRY001","name":"French Fries","price":5}]` | +| ... | ... | + +### **2.3.4 **`INSERT`** - 插入单条レコード** + +在 2.3.2 中,我们演示的是开头时刻初始化批量插入数据,现在我们確認どのように新增插入单条数据。 + +```sql +-- Step 4: INSERT a new order (single row) +-- Example: Add a new paid order for user 2012 with one Chicken Burger +INSERT INTO orders (user_id, status, amount, details, is_paid) +VALUES ( + 2012, 'paid', 9.99, + '{"items":[{"sku":"BGR002","name":"AIID Burger","qty":100,"price":1000}]}', + true +); +-- Expected Output: +-- Before (table fragment): +-- | id | user_id | status | amount | is_paid | +-- | ...| ... | ... | ... | ... | +-- +-- After (last row): +-- | id | user_id | status | amount | is_paid | +-- | xx | 2012 | paid | 9.99 | true | +-- (where xx = next serial value) +``` + +此时再用 `SELECT * FROM orders;` 对数据进行查询,できます看到 orders 表成功从 11 个数据变成了 12 个数据。 + +### **2.3.5 **`UPDATE`** - 変更现有数据** + +在实际工作中,必〜するがあります对数据表进行頻繁に数据更新,我们〜できる够用 `UPDATE` 语句変更表中已存在的レコード。 + +```sql +-- Step 5: UPDATE example +-- Example: Mark order with id=1 as paid and update its status +UPDATE orders SET status = 'paid', is_paid = true WHERE id = 1; +-- Expected Output: +-- Before (row with id=1): +-- | id | status | is_paid | +-- | 1 | pending | false | +-- After (row with id=1): +-- | id | status | is_paid | +-- | 1 | paid | true | +-- All other rows remain unchanged. +``` + +### **2.3.6 **`DELETE`** - 削除数据** + +`DELETE` 语句可用于从表中移除レコード,并结合条件对指定部分的数据进行変更。 + +```sql +-- Step 6: DELETE example +-- Example: Delete orders older than 2 days to clean up old data +DELETE FROM orders WHERE placed_at < now() - interval '2 days'; +-- Expected Output: +-- Before (filtered for affected rows): +-- | id | status | placed_at | +-- | 3 | shipped | 2025-10-13 ... | <-- will be deleted +-- +-- After: +-- No such rows remain. SELECT * FROM orders WHERE placed_at < now()-interval '2 days' yields zero rows. +-- Other rows in orders table are unaffected. +``` + +実行前,你可先実行 `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';` 进行数据表筛选結果的確認。当実行 `DELETE` コマンド后,再次実行同じ的 `SELECT` 查询 `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';`,〜する返す一个空的結果,表明これらの行已被成功削除。 + +## 2.4 行级セキュリティ + +在学习了データベース的基本操作后,必〜するがあります进一步深入一个保障数据セキュリティなコア概念 ——RLS(行级セキュリティ,Row Level Security)。 + +不妨先思考一个实际シナリオ中的重〜するなな問題:どのように実装数据的 “隔离アクセス”?例えば,只許可ユーザー A 確認自分で的数据,而无法看到ユーザー B 的信息;再例えば,即便某角色拥有データベース的アクセス権限,どのように回避其误操作或泄露その他ユーザー的敏感数据? + +RLS 正是为解決这类数据セキュリティ与隔离〜する件而生。它許可開発者为データベース表定义精细化的セキュリティ戦略,根据ユーザー的身份信息(如ユーザー ID、角色権限等),精确控制哪些ユーザー〜できるアクセス、変更表中的哪些行数据。 +举个典型例:对于オーダー表(`orders`),できます定义这样一条 RLS 戦略 ——“仅当 `orders` 表中某条レコード的 `user_id` 列,与当前ログインユーザー的 ID 完全一致时,该ユーザー才〜できる查询到这条オーダー数据”,从而実装 “ユーザー只〜できる看自分で的オーダー” 的コア〜する件。 + +当你为某张表启用 RLS后,该表的すべての数据操作リクエスト(包括 `SELECT` 查询、`INSERT` 新增、`UPDATE` 変更、`DELETE` 削除)都〜する触发 RLS 校验:必須通过至少一条セキュリティ戦略的チェック,操作才〜できる実行。若不存在許可该操作的戦略,或リクエスト未满足すべての戦略的条件,データベース〜する直接拒绝此次操作,从底层阻断非授权アクセス。 + +在 Supabase 中,RLS 与ユーザー认证システム深度绑定,使用起来更为便捷。Supabase 提供了一个专用函数 `auth.uid()`,它〜できる直接返す “当前发起リクエスト的已ログインユーザー” 的唯一 ID(格式为 UUID)。借助この函数,できます轻松编写戦略,実装 “数据行与ユーザー身份” 的精准关联(例えば前文提到的 “オーダー `user_id` 匹配当前ユーザー ID”)。 + +启用 RLS 戦略的方式很灵活,できます在 Supabase データベース管理界面中的 “RLS” 按钮,直接設定并启用戦略: + +![](/zh-cn/stage-2/backend/database-supabase/images/image32.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image33.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image34.png) + +主动設定难免显得麻烦,通常,我们在数据表语句作成、初始化的时候就〜する自動考虑植入对应的 RLS 戦略。必〜するなのは在 SQL Editor 中実行類似如下语句,即可自動开启对应数据表的行级セキュリティ戦略。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image35.png) + +# 3. 第一个 SQL アプリケーション + +掌握了データベース基本的な操作与RLSコア逻辑,我们终于进入本次チュートリアル的实践环节。漫长的学习铺垫是为了让后续“从0到1搭建アプリケーション”的过程更清晰。次に,します以“汉堡店オーダー管理”为シナリオ,手把手演示Supabase的一般的な操作:从アプリケーション与Supabase的关联設定,到データベース与ログイン機〜できる的集成,段階的に学习異なる操作逻辑。 + +## 3.1 克隆并実行 Supabase 例プロジェクト + +〜する开展实操,まず必〜するがある获取配套的演示コードリポジトリ。できます让 Trae 或 Claude Code 协助 git clone 以下リポジトリ:https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos + +若已設定 SSH キー,提案使用 SSH 地址进行 clone(git@github.com:THU-SIGS-AIID/Project5-Supabase-Demos.git)以提升セキュリティ性;若 SSH 或 HTTPS 接続遇到网络問題,〜できる直接クリックリポジトリページ的 “Download ZIP”,获取压缩包后解压即可看到完全なコード。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image36.png) + +Clone 后,你同样〜できる让 Trae 或者是 Claude Code 帮你起動プロジェクト,例えば直接在 Agent 界面中说明: `帮我直接启动这个项目里面的 project 1 `,或者コピー对应想起動 project 的绝对パス,貼り付け给大規模モデル让大規模モデル直接起動。 + +## 3.2 プロジェクト1 - 汉堡店菜单增删改查 + +次に进入实操环节 —— 以 `project-burger-shop-menu-crud-1` 为例,します学习どのように通过 SQL 脚本一键初始化 Supabase データベース,并完了本地プロジェクト与 Supabase データベース的关联設定,让フロントエンド〜できる正常读写菜单数据。 + +### 使用脚本作成データベース + +まず,必〜するがあります在 Supabase 中作成必〜するがある的数据表的相关内容。进入 Project1 プロジェクトディレクトリ看到名为 `scripts`的ファイル夹,其中含む 1 个 `init.sql`データベース脚本ファイル,它〜できる帮我们自動完了すべてのデータベース相关资源的作成(包括表结构、初始数据等),後に我们〜する经常用到该ファイル进行データベース中表的初始化。 + +```sql +...... + +-- ============================================================================ +-- 2. Create Menu Items Table +-- ============================================================================ + +create table if not exists public.menu_items ( + id uuid primary key default gen_random_uuid(), + name text not null, + description text, + category text check (category in ('burger','side','drink')) default 'burger', + price_cents int not null check (price_cents > 0), + available boolean default true, + emoji text, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +-- Comments for documentation +comment on table public.menu_items is 'Burger shop menu items for CRUD demo'; +comment on column public.menu_items.id is 'Unique identifier for each menu item'; +comment on column public.menu_items.name is 'Display name of the menu item'; +comment on column public.menu_items.description is 'Detailed description of the menu item'; +comment on column public.menu_items.category is 'Category: burger, side, or drink'; +comment on column public.menu_items.price_cents is 'Price in cents (integer) to avoid floating point issues'; +comment on column public.menu_items.available is 'Whether the item is currently available for order'; +comment on column public.menu_items.emoji is 'Optional emoji representation of the menu item'; +comment on column public.menu_items.created_at is 'Timestamp when the item was created'; +comment on column public.menu_items.updated_at is 'Timestamp when the item was last updated'; + +...... +``` + +在 SQL Editor 中実行初始化 sql 脚本后,即可在 Table Editor 中看见已作成的数据表。其中データベース初始化コード具体実行逻辑如下: + +1. 作成 menu_items 表 : +2. この表用于存储汉堡店菜单中的すべてのプロジェクト。它含む了如 name (商品名), description (説明), price_cents (以美分为单位的価格,回避浮点数精度問題), category (分类) 和 available (是否可售) 等フィールド。这基本涵盖了一个菜单项所需的すべての信息。 +3. 作成 promo_codes 表 : +4. 此表用于管理促销活动,例えば折扣码。它定义了 code (折扣码), discount_type (折扣类型,如百分比或固定金额), discount_value (折扣数值) 等フィールド。 +5. 禁用行级セキュリティ (Row Level Security - RLS) : +6. を容易にするため開発和テスト,脚本中明确地禁用了 RLS。但结合我们前に学习的 RLS コア逻辑:RLS 是 Supabase 保障数据セキュリティな重〜するなな機〜できる,〜できる通过精细化戦略控制 “誰〜できるアクセス / 変更哪些数据”(例えば只許可管理员編集促销码,普通ユーザー只〜できる確認菜单)。したがって本番環境では中,必須开启 RLS 并設定合理戦略,从底层阻断非授权アクセス(如防止ユーザー恶意変更他人作成的菜单,或泄露促销码ルール)。 +7. 插入种子数据 (Seed Data) : +8. 为了让フロントエンドプロジェクト起動后就〜できる看到実際の菜单与促销数据(无需手動で录入テスト数据),`init.sql`脚本还〜する向 `menu_items`和 `promo_codes`表中插入 “种子数据”(即例数据)。例えば,できます看到各种汉堡、小食、饮料以及多种多样的折扣码。 + +### 设置与データベース的接続 + +データベース准备完了,必〜するがあります〜するこのフロントエンドプロジェクト与 Supabase 进行接続,从而正常读取データベース内的数据。必〜するがあります〜する Supabase プロジェクト的 URL 和 anon key 写到指定設定中,本プロジェクト提供了两种柔軟な設定方式: + +1. 通过環境変数設定 + +在プロジェクト根ディレクトリ作成一个 .env ファイル,并填入你的 Supabase 凭证: + +``` +NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co +NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key +``` + +2. 在プロジェクトページ中直接设置 + +を容易にするため快速演示和切り替え異なる的 Supabase プロジェクト,首页ページ右上角提供了一个 设置 按钮。できますクリック它,在弹出的模态框中直接入力或貼り付け Supabase URL 和 anon key。 + +クリック “Save” 后,これらの信息〜する用于动态作成 Supabase クライアント实例,類似下列コード所示: + +```JavaScript +import { createClient, type SupabaseClient } from '@supabase/supabase-js'; + +// Optional client factory for demos: returns null when env is not set. +export function maybeCreateBrowserClient(): SupabaseClient | null { + const url = process.env.NEXT_PUBLIC_SUPABASE_URL; + const anon = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; + if (!url || !anon) return null; + return createClient(url, anon); +} +``` + +作成完データベース,填写完对应的 Supabase Link 相关設定后,即可看到如下界面,できます尝试对商品进行增删查改,并观察 Supabase 中对应部分数据表的变化。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image37.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image38.png) + +### 📚 課題 + +1. 尝试増加和削除已有プロジェクト,在 Table Editor 中確認変更操作对数据表内容变动的影响。 + +## 3.4 プロジェクト2 - 汉堡店认证ユーザー + +Project1 実装了 “菜单 CRUD + データベース接続” ,Project2 〜する引入更贴近真实业务的コア〜できる力,ユーザー认证(Auth)与行级セキュリティ(RLS)権限管理。 + +Project2 含む独立したログイン页,サポートユーザー通过「邮箱 + 密码」的方式ログイン。其コア逻辑是调用 Supabase Auth 提供的原生方法,快速実装认证プロセス,无需手動で開発複雑なログイン校验逻辑: + +``` +const { error: err } = await supabaseClient.auth.signUp({ + email, + password, + options: { + data: { + full_name: fullName || null, + birthday: birthday || null, + avatar_url: avatarUrl || null + } + } +}); +``` + +![](/zh-cn/stage-2/backend/database-supabase/images/image39.png) + +ログイン成功后,Supabase 〜する自動为ユーザー作成一个〜する话(session),并在后续すべてのデータベースリクエスト中自動携带认证信息;通过 RLS 的作用,各ユーザー根据对应的认证信息只〜できる看到自分で的账户信息(已购买プロジェクト、钱包剩余额度),无法看到その他ユーザー的账户信息,这就実装了異なるユーザーログイン后的数据隔离,各人只〜できる看到自分で的内容。 + +和 Project 1 一样,必〜するがあります先使用 `init.sql` 进行数据表的初始化(注:もし初始化出错,请先在 Table Editor 中削除すでに作成的数据表,或者是直接削除この Supabase Project, 重新新建一个 Project) + +成功使用邮箱新規登録账户、在邮箱確認新規登録账户后,ログイン后进入 Shop 界面即可看到如下内容: + +![](/zh-cn/stage-2/backend/database-supabase/images/image40.png) + +但此时クリック admin,你并不〜できる看到如下界面,必〜するがあります尝试在数据表中找到控制ユーザー権限的部分,〜する権限変更为 `admin`,从而〜できる够在 Admin 界面正常看到如下内容: + +![](/zh-cn/stage-2/backend/database-supabase/images/image41.png) + +值得提示的是,目前每次新規登録新的邮箱,你都必〜するがある在邮箱中进行新規登録確認才可ログイン;但这一步并非是必須的,できます在 Supabase 的 Authentication 栏目中找到 Sign In / Providers,クリックConfirm email 取消邮箱的强制確認。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image42.png) + +### 📚 課題 + +1. 请先领取新手礼包,完了商品购买操作。 +2. 尝试找到ユーザー権限的设定数据表位置,〜する権限変更为 `admin`,并成功在オーダー管理界面変更商品数量 +3. 尝试在数据表内定位到钱包金额相关表,通过変更使剩余钱包金额増加。 + +# 4. 構築你的第一个 Supabase アプリケーション + +经过前的システム学习,你已掌握 Supabase 的コア〜できる力(データベース操作、ユーザー认证、RLS セキュリティ戦略),现在是时候亲自動手,搭建属于你的第一个含むデータベース、サポートユーザーログインシステム的アプリケーション了! + +## 4.1 为任意アプリケーション接入 Supabase データベース的標準化プロセス + +できます使用標準化プロセス〜する任意アプリケーション接入 Supabase データベース: + +1. まず进行〜する件梳理与信息同步,明确目標并告知AI + 1. 必〜するがあります向AI清晰説明当前アプリケーション的コア機〜できる、待新增的データベース〜する件。例:“我现有一个本地React Todoアプリケーション,数据仅存在ブラウザ本地存储,需新增‘数据云端同步’機〜できる并接入Supabaseデータベース。手伝ってください梳理:このアプリケーション涉及哪些数据操作(如新增待办、変更ステータス、削除待办)?必〜するがある作成哪些数据表来存储これらの数据?” + 2. 补充重〜するなな约束条件(可选):例えばフィールド格式〜する求(时间戳用 `timestamptz`、金额用整数存分)、数据権限ルール(仅自分で可见待办),让AI的分析更贴合实际〜する件。 + 3. 对 AI 返す的結果进行审核,若AI思路存在遗漏(如未考虑“待办截止时间”フィールド),补充提示修正:“你漏考虑截止时间了,帮我加上。” +2. 让AI基于你確認后的表结构,生成适配Supabase的 `init.sql`脚本:“基于上述所说思路和表的结构,返す给我在 Supabase 中〜できる进行初始化的 init.sql 脚本”,後に必〜するがあります在 SQL Editor 中実行脚本;若実行报错,〜するエラー信息反馈给AI,让其修正脚本。 +3. 在 Supabase 実行 init.sql 脚本后,让 AI 基于脚本重构当前コード,使得〜できる够和 Supabase 进行正常的数据交互:“请你根据我的 sql 脚本以及上讨论的设定,重构プロジェクト的コード让它サポート〜できる够和 Supabase 对应的データベース进行通信并処理数据”。 +4. 重构完毕,此时只必〜するがある設定好 Supabase 地址和 key 的パラメータ(正式プロジェクト通常只用環境変数設定),随后进行チェック,若没問題则顺利実装〜するアプリケーション接入 Supabase データベース。 + 1. 実行プロジェクト,テストすべてのデータベース交互機〜できる,到Supabase Table Editor リアルタイム確認数据是否同步; + 2. 若出现問題(如数据无法插入、仅〜できる看到部分数据),〜する問題现象反馈给AI,让其定位原因并修正コード。 + +さらに,若目標是開発ユーザーログインページ,可直接让 AI 协助集成ログインページ :“现在必〜するがあります帮我给このアプリケーション加入 Supabase 的ユーザーログインシステム,使用邮箱〜できる新規登録和ログイン”。另外,你还必〜するがある向 AI 明确ページ的リダイレクト逻辑与パス(如ログイン成功后リダイレクト至システム首页、リダイレクト首页的地址是何、ログイン失敗时留在当前页并表示エラー提示)。集成完了后,必〜するがあります尝试新規登録ログイン后〜できる在 Supabase 的 Authentication プロジェクト中看到新增的ユーザー数据,并在ログイン后〜できる正常进入到原先未ログイン无法进入的アプリケーション界面即可。 + +もちろん,你还〜できる直接让 AI 参考某个 project 的実装直接迁移对应的 Supabase 機〜できる,例えば某个 Project 用到了データベース以及 Edge fuction 的高度な機〜できる,できます按照如下方式直接让 AI 迁移对应的相似機〜できる:“请你参考该プロジェクト {此处コピー貼り付け参考プロジェクト的绝对地址} 当中的 Supabase 相关機〜できる実装逻辑,给当前プロジェクト加上類似的実装逻辑(如ユーザーログイン、データベース管理、函数リクエスト等等)”。 + +## 4.2 案例研究:構築一个在线贪吃蛇游戏 + +根据上所提到的 SOP ,让我们通过一个具体的な实际案例 `Project5-Supabase-Demos/apps_snakegame`来实践:为一个已有的“贪吃蛇”游戏プロジェクト増加分数排行榜单,含むユーザーログイン与データベース基本的な機〜できる。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image43.png) + +### 4.2.1 分析プロジェクト,识别数据〜する件 + +まず,和在前に提到的標準化プロセス類似,できます先把〜する件澄清给 AI ,让 AI 基于我们プロジェクト和〜する件给出对应的変更ソリューション,後に我们〜する基于この変更ソリューション。 + +**できます使用如下的プロンプト来指导 AI:** + +> “我有一个贪吃蛇游戏,ディレクトリ在 {此处貼り付け贪吃蛇游戏的绝对パス}。现在我想结合 supabase 给它増加一个在线排行榜機〜できる,并且サポートユーザーログインシステム,排行榜〜できる根据ユーザー名和邮箱表示排名。 +> +> 手伝ってください分析一下,为了実装この機〜できる,我必〜するがある建立哪些数据表?各表べき含む哪些フィールド?” + +此时你〜する得到類似如下返す: + +![](/zh-cn/stage-2/backend/database-supabase/images/image44.png) + +### 4.2.2 生成 `init.sql` 脚本 + +确定必〜するがある的部分,できます让 AI 生成必〜するがある在 Supabase 実行的データベース初始化脚本:“请你基于上的分析,帮我在プロジェクト中生成 scripts/init.sql 脚本用于在 Supabase 中初始化所需データベース”。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image45.png) + +### 4.2.3 改造プロジェクトコード + +次に必〜するなのは让 AI 基于前的内容重构当前的贪吃蛇コード:“次に请你基于前思考的内容以及 sql 表,使用 Supabase 帮我実装排行榜機〜できる,排行榜是個別に的一页,必〜するがある〜できる根据邮箱和ユーザー名区分異なるユーザー的总分,你还必〜するがあるサポート基于邮箱的ユーザーログインシステム,新規登録ログイン才〜できる玩この游戏。” + +如果当前 AI 〜する話轮次太多,你想重开一个新的〜する话进行プロジェクト重构,できます把上提到的 `init.sql`作为コンテキスト中的内容,让 AI 基于 sql ファイル进行プロジェクト重构。 + +若是发现 AI 実装的ユーザーログインシステム不够正常,できます直接〜する我们前に写好的 `Project5-Supabase-Demos/apps/project-burger-shop-auth-users-2` 的地址一同放入プロンプト,让 AI 基于プロジェクト直接実装ユーザーログインシステム。并チェック是否すでに正确设定了接続到 Supabase 的必〜する条件,防止なぜなら Supabase 設定エラー而报错。 + +在コード変更过程中,若出现实际效果与预期不符的情况(如排行榜数据不表示、ログイン検証失效等),只需完全なレコード具体现象并反馈给 AI,即可段階的に接近正确結果。改造成功的標準为:ユーザー〜できる顺利完了新規登録与ログイン操作,且ログイン后可正常確認对应的游戏排行榜单。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image46.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image47.png) + +### 📚 レッスン課題 + +1. 〜するユーザー管理システム集成到贪吃蛇游戏演示版中 +2. 〜するユーザー管理システム集成到你的アプリケーション程序中(如果前に已開発过一个アプリケーション程序) + +# 5. 成为 Supabase 大师 + +以上是 Supabase 的基本操作,次に的旅程中します〜する接触 Supbase 的応用原理和機〜できる,你〜する理解なぜ我们〜する選択 Supabase 作为教学案例,以及どのように使用 Supbase 実装更高度な的操作,协助你実装更複雑な交互機〜できる,并且在学习これらの機〜できる后,即便面对 Supabase 以外の的その他同类ツール,你也〜できる触类旁通,从更本质的层面理解バックエンドサービス的コア原理。もちろん,你并不必〜するがある在短时间内学〜する全部,也许只必〜するがある学〜する第三方ログインサポートすでに足够,できます先浏览下列内容,直到プロジェクト遇到对应的〜する件时再倒回来深入学习。 + +## 5.1 なぜ我们選択 Supabase + +在开始応用前に,我们再次思考この問題:众多バックエンド技术ソリューション中,为何我们最終的に選択 Supabase 作为技术底座? + +初创团队在技术选型时普遍面临一个矛盾:既想完全掌控バックエンドシステム,又必須快速上线产品——而自建バックエンド通常意味着〜する投入数月时间搭建データベース与リアルタイム同步、ユーザー认证、APIサービス、ファイル存储、定时タスク、モニタリング告警等コアコンポーネント,除非团队成员已在对应领域积累了豊富な実践经验。在资金不足、市场窗口短暂的双重压力下,一旦陷入基本的な设施泥潭,极易导致迭代滞后、错失早期增长空间。 + +Supabase 〜するこれらのバックエンド〜できる力打包为开箱即用的サービス(PostgreSQLデータベース、リアルタイムサブスクリプション、身份认证、对象存储、边缘函数、自動生成API等),让初创团队得以〜する稀缺资源聚焦于コア機〜できる開発,回避因底层建设拖慢上线速度——这已成为当前创投環境下务实的生存戦略。もちろん,また〜できる使用别的一栈式バックエンド产品进行開発,例えば PocketBase(轻量极简)和 Appwrite(跨プラットフォーム适配)等ソリューション,但综合機〜できる完全な性、SQL 生态成熟度及 Github 社区关注度,Supabase 更适合支撑业务的长期稳定実行。 + +在同类产品中,Supabase 的开源戦略更具优势。 以市场占有率较高的 Firebase 为例:其闭源特性易导致プラットフォーム绑定,迁移成本极高。Supabase 采用完全开源模式,サポート私有化デプロイ,规避了供应商锁定风险,可根据〜する件切り替え至其その他竞品。 + +总而言之,技术选型需匹配业务规模与目標。 对于个人プロジェクト或极小范围テスト,PocketBase 等超轻量ソリューション已足够;若企业需对接複雑な身份システム,或〜する满足上市公司合规审计〜する求,WorkOS 这类企业级全身份治理ソリューション更为适用。但对于検証 MVP、承载早期ユーザー的コア业务シナリオ,Supabase 的完全な機〜できる完全够用,它不仅〜できる独立支撑至少万级ユーザー规模,更可灵活集成 Stripe(決済)、Resend(邮件)、Cloudflare(CDN)等第三方サービス;即便未来业务拡張至企业级〜する件,Supabase 的开源架构也〜できる与企业システム并行デプロイ,異なる機〜できる選択最适配的プラットフォーム进行使用。这种渐进式灵活性,使初创团队无需过早投入重型基本的な设施,又〜できる保留 future-proof 的演进空间。 + +## 5.2 Google 和 GitHub ログインサポート + +前述のチュートリアル中,我们讲解了どのように直接使用邮箱进行新規登録和ログイン,但在实际操作中我们通常〜したい簡素化新規登録プロセス,例えば使用第三方ログイン Google 和 GitHub 进行システム的快速新規登録与ログイン,します〜する在这节チュートリアル中展开各细节; ,一个完全な认证システム也必須提供セキュリティ信頼性の高い密码重置機〜できる,また〜する〜する密码重置機〜できる集成在本节チュートリアル的プロジェクト中。 + +本プロジェクト `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6`)完全な地演示了どのように実装これらの高度な機〜できる。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image48.png) + +### 5.2.1 OAuth プロセス:第三方ログイン是どのように工作的? + +第三方ログイン的コア是 OAuth 2.0 开放授权协议,它的本质是 “授权代理”:許可ユーザー授权我们的アプリケーション(汉堡店プロジェクト)アクセス其在第三方プラットフォーム(如 Google)的公开信息(如邮箱、头像),但无需〜する第三方プラットフォーム的密码暴露给我们的アプリケーション,从根本上规避了密码泄露风险。 + +完全なプロセス可拆解为 5 个重〜するななステップ,以 Google ログイン为例: + +1. ユーザー发起授权リクエスト:ユーザークリックページ上的 “Sign in with Google” 按钮,我们的アプリケーション〜する自動〜するユーザー重定向到 Google 官方的授权ページ(確保授权过程的セキュリティ性,回避钓鱼风险)。 +2. ユーザー完了第三方授权:ユーザー在 Google ページログイン自分で的账户(検証ユーザー身份),并同意我们的アプリケーションリクエスト的権限(如 “获取邮箱地址”)。 +3. Google 返す一次性授权码:授权通过后,Google 〜する〜するユーザー重定向回我们提前约定的 “回调 URL(Callback URL)”,并在 URL パラメータ中附带一个一次性、短期有效的授权码(而非直接返すユーザー信息,进一步提升セキュリティ性)。 +4. Supabase 交换アクセス令牌(Access Token):我们的バックエンド(由 Supabase 托管,无需自建)〜する拿着この授权码,向 Google 官方インターフェース发起リクエスト,换取可用于获取ユーザー信息的 Access Token(授权码仅用于换 Token,回避 Token 直接在フロントエンド传输)。 +5. 作成账户并建立〜する话:Supabase 使用 Access Token 从 Google 拉取ユーザー的公开信息(如邮箱、头像),并在我们的プロジェクト中为该ユーザー自動作成账户(若首次ログイン)或直接关联现有账户,最終的に生成一个有效的ユーザー〜する话(Session),完了ログイン。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image49.png) + +### 5.2.2 設定 Google Cloud 获取 Client ID 和 Secret + +无论是何种第三方ログイン方式,我们通常都必〜するがある获取 Client ID 与 Secret 进行設定;对于 Google 的第三方ログイン,你まず必〜するがある在 Google Cloud Platform 中作成一个 OAuth 2.0 クライアント ID 进行对应パラメータ的获取。 + +1. **进入 Google Cloud Console** : +2. アクセス [Google Cloud Console](PROT185)。 +3. 作成一个新プロジェクト或選択一个现有プロジェクト。 +4. **設定 OAuth 同意屏幕 (OAuth consent screen)** : +5. 在左侧导航栏中,找到 “APIs & Services” -> “OAuth consent screen”。 +6. 選択 “External” ユーザー类型,次にクリック “Create”。 +7. 填写アプリケーション名称、ユーザーサポート电子邮件等必填信息。 +8. 在 “Authorized domains” 部分,追加你的 Supabase プロジェクト域名,格式为 `*.supabase.co`。 +9. 保存并继续。在 “Scopes” 和 “Test users” ステップ中,できます暂时跳过,直接保存。 +10. **作成凭据 (Create Credentials)** : +11. 进入 “APIs & Services” -> “Credentials”。 +12. クリック “+ CREATE CREDENTIALS”,選択 “OAuth client ID”。 +13. 在 “Application type” 中選択 “Web application”。 +14. 为它取一个名字,例えば “Supabase Auth”。 +15. 在 “Authorized redirect URIs” 部分,クリック “ADD URI”,并填入你的 Supabase プロジェクト的回调 URL。できます在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “Google” 中找到この URL,它的格式通常是 `https://<你的项目ID>.supabase.co/auth/v1/callback`。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image50.png) +16. クリック “CREATE”。 +17. **获取 Client ID 和 Client Secret** : +18. 作成成功后,一个弹窗〜する表示你的 **Client ID** 和 **Client Secret** 。请务必**立即コピー并妥善保存** 它们。 + +### 5.2.3 設定 GitHub 获取 Client ID 和 Secret + +同样地,你也必〜するがある在 GitHub 上新規登録一个 OAuth アプリケーション。 + +1. **进入 \*\***GitHub\*\* ** Developer Settings** : + 1. ログイン你的 GitHub 账户。 + 2. クリック右上角的头像,进入 “Settings”。 + 3. 在左侧导航栏的底部,找到 “Developer settings”。 + +2. **新規登録新アプリケーション (Register a new application)** : +3. 選択 “OAuth Apps”,次にクリック “New OAuth App”。 +4. 填写アプリケーション名称,例えば “My Burger Shop”。 +5. **Homepage URL** : 填写你アプリケーション的线上地址,或者本地開発地址 `http://localhost:3000`。 +6. **Authorization \*\***callback\*\* ** URL** : 填入你的 Supabase プロジェクト的回调 URL。同样,できます在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “GitHub” 中找到它,格式为 `https://<你的项目ID>.supabase.co/auth/v1/callback`。 +7. クリック “Register application”。 +8. **获取 Client ID 和 Client Secret** : +9. 新規登録成功后,ページ〜する表示你的 **Client ID** 。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image51.png) +10. クリック “Generate a new client secret” 来生成你的 **Client Secret** 。同样,请**立即コピー并保存** 它。 + +### 5.2.4 在 Supabase 中設定 Provider + +现在,〜する我们获取到的凭证設定到 Supabase 中。 + +1. **进入 Supabase Dashboard** : +2. 選択你的プロジェクト,进入 “Authentication” -> “Providers”。 +3. **启用并設定 Google** : +4. 找到 “Google” 并启用它。 +5. 〜する你从 Google Cloud 获取的 **Client ID** 和 **Client Secret** 貼り付け到对应的入力框中。 +6. クリック “Save”。 +7. **启用并設定 ** **GitHub** : + 1. 找到 “GitHub” 并启用它。 + 2. 〜する你从 GitHub 获取的 **Client ID** 和 **Client Secret** 貼り付け到对应的入力框中。 + 3. クリック “Save”。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image52.png) + +至此,你すでに〜できる够使用第三方账户在構築的网站中进行ログイン,できます直接让 AI 基于 `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6`プロジェクト作为参考,在你的プロジェクト的基本的な上サポートユーザーログインシステム,以最小成本集成含む github 与 google 鉴权的ユーザーログイン界面。 + +### 5.2.6 密码重置実装 + +作为一个成熟的ユーザーログインコンポーネント,密码重置也是極めて重〜するなな一环,本プロジェクト `project-burger-shop-auth-advanced-supabase-6`也含む了该機〜できる的完全な実装,できます直接让 AI 基于本プロジェクト的密码重置機〜できる复刻完全な密码重置コンポーネント。其主な分为以下几步: + +1. 发起リクエスト :ユーザー在忘记密码ページ入力邮箱,フロントエンド调用 `supabase.auth.resetPasswordForEmail()` 函数,并指定一个重定向 redirectTo URL(例えば /auth/reset )。 +2. 送信邮件 :Supabase 〜する向该邮箱送信一封含む唯一重置リンク的邮件。 +3. アクセスリンク :ユーザークリック邮件中的リンク,被重定向到アプリケーション内指定的重置ページ。 +4. 更新密码 :在重置ページ,ユーザー入力新密码。フロントエンド调用 `supabase.auth.updateUser()` ,〜する新密码提出给 Supabase。Supabase 〜する自動検証リンク的有效性并完了密码更新。 + +最後に,如果你觉得当前的密码重置邮件过于简陋,できます 在 Supabase Dashboard 的 Authentication -> Email Templates 中自定义“Reset Password”邮件テンプレート。 + +除了 Reset password 機〜できる外,你还〜できる看到许多その他与ユーザー管理相关的高度な機〜できる设定(例えば Invite user 等),你可根据对应機〜できる各自的開発ドキュメント,结合 Vibe coding ツール自行追加对应機〜できる。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image53.png) + +## 5.3 リアルタイム機〜できる + +Supabase 的リアルタイム機〜できる是其最強力な特性之一,为構築协作ドキュメント、リアルタイム仪表盘、游戏大厅或客服システム提供了极大的便利。 + +本プロジェクト `Project5-Supabase-Demos/apps/project-burger-shop-realtime-orders-3 `通过構築一个 多人リアルタイムチャット室、光标位置共享 機〜できる,表示了 Supabase Realtime 涉及到的三大コア〜できる力:データベース变更监听 (Postgres Changes)、广播 (Broadcast) 和 在线ステータス (Presence)。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image54.png) + +如果你觉得相关コード部分有一定难度,〜できる直接让 AI 参考该部分ドキュメント内容,对你的程序进行変更。 + +### 5.3.1 データベースリアルタイム变动 Postgres Changes + +最よくある Realtime 機〜できる是对データベース的变更进行リアルタイム监听 Postgres Changes 。它許可クライアントサブスクリプションデータベース中特定表、特定行甚至特定列的 INSERT 、 UPDATE 或 DELETE 事件。一旦データベース发生变动(无论是通过 API 调用、Supabase Dashboard 操作,还是 SQL 脚本実行),Supabase 都〜する利用 PostgreSQL 的底层コピー机制,立即通过 WebSocket 〜する变更的数据推送到すべてのサブスクリプション了该频道的フロントエンドクライアント,而无需フロントエンド通过轮询(Polling)去反复查询。 + +一般的に而言,该機〜できる〜できる在 Table Editor 中找到 Enable Realtime クリック后起動, 但更方便的是通过 SQL 脚本初始化実行,例えば: + +```sql +-- Enable realtime replication +ALTER TABLE public.chat_messages REPLICA IDENTITY FULL; +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_publication_tables + WHERE pubname = 'supabase_realtime' + AND schemaname = 'public' + AND tablename = 'chat_messages' + ) THEN + ALTER PUBLICATION supabase_realtime ADD TABLE public.chat_messages; + END IF; +END $$; +``` + +该语句〜する `chat_messages` 表追加到了 Supabase 预设的 `supabase_realtime` 中,而一旦一个表被加入到この特殊的 `publication` 中,Supabase 的リアルタイムサーバー就〜する开始监听它的すべての数据变更。 + +基于上的特殊数据表,我们〜できる够使用监听コード对表内数据变动进行リアルタイム监听。必〜するがあります実装的是当一个ユーザー送信消息时,その他すべての在线ユーザー都〜できる立刻在屏幕上看到这条消息。通过サブスクリプション chat_messages 表的 INSERT 事件〜できる够実装这一点。 + +```typescript + const sub = supabase + .channel('chat_messages_channel') + .on('postgres_changes', { + event: 'INSERT', + schema: 'public', + table: 'chat_messages' + }, (payload: any) => { + console.log('New message received:', payload.new); + const newMessage = payload.new as Message; + // ... // + .subscribe((status: string) => { + console.log('Chat subscription status:', status); + }); +``` + +- `.channel('chat_messages_channel')`: 作成一个隔离的通信频道。 +- `.on('postgres_changes', ...)`: 这是コアとなるサブスクリプション方法。我们告诉 Supabase 我们只关心 `chat_messages` 表的 `INSERT` 事件。 +- `payload.new`: 当有新消息被插入データベース时,Supabase 〜する〜する这条新数据的完全な内容通过 `payload.new` 推送给すべてのサブスクリプション的クライアント。 +- `.subscribe()`: 起動サブスクリプション。 + +### 5.3.2 信息广播同步 Broadcast & Presence + +对于それらの不必〜するがある存入データベース的、更“即时”的交互,例えば光标移动、在线ステータス等,Supabase 提供了 Broadcast 和 Presence 機〜できる。 + +- Presence: 用于跟踪频道内すべてのクライアント的 **共享ステータス** 。适合用来実装“誰在线”的機〜できる。 +- Broadcast: 用于向频道内的すべてのその他クライアント送信**低遅延**的 **临时消息** 。 + +Presence 的コア思想是: 让各クライアント声明自分で的在线ステータス,并由 Supabase 的サーバー负责〜するこれらのステータス可靠地同步给频道内的すべてのその他クライアント。実装 Presence 分为以下几个重〜するななステップ: + +1. 作成一个サポート Presence 的频道 + +まず,我们作成了一个频道 `lobby_presence` 来专门処理これらの交互,并在設定中指定一个唯一的 key 来标识当前ユーザー。この key 通常是ユーザー的 ID。 + +``` +const ch = supabase.channel +('lobby_presence', { +  config: { +    presence: { key: anonymousUser.id }, +  } +}); +``` + +2. サブスクリプション频道宣告“我在线”的信息 + +一旦频道作成成功,必〜するがありますサブスクリプション它。在サブスクリプション成功的回调( status === 'SUBSCRIBED' )中,我们调用 channel.track() 方法。この方法〜する〜する当前ユーザー的信息(例えばユーザーID、名称、头像颜色等)广播给频道内的すべてのその他クライアント,宣告自分で的“在线”ステータス。 + +``` +const me = { +  id: anonymousUser.id, +  name: anonymousUser.name, +  color: anonymousUser.color +}; + +ch.subscribe(async (status) => { +  if (status === 'SUBSCRIBED') { +    await ch.track(me); +  } +}); +``` + +3. 同步完全な在线列表 + +当一个新ユーザー加入频道时,他们必〜するがある获取当前すべてのすでに在线的ユーザー列表。这通过监听 presence 的 sync 事件来実装。 sync 事件〜する在你首次加入频道时触发,为你提供一个完全な“快照”。 + +channel.presenceState() 方法〜する返す一个对象,含む了当前频道内すべての在线ユーザー的ステータス信息。します其処理后更新到アプリケーション的 state 中,从而渲染出完全な在线ユーザー列表。 + +``` +ch.on('presence', { event: 'sync' }, ()  +=> { +  const state = ch.presenceState(); +  const flat = {}; +  Object.values(state).forEach((arr) => { +    arr.forEach((u) => { flat[u.id] =  +    { ...u }; }); +  }); +  setOnline(flat); +}); +``` + +4. 监听单个ユーザー的加入与离开 + +除了 sync 事件,我们还〜できる监听 join 和 leave 事件,以便在有新ユーザー进入或离开时做出即时レスポンス,例えば表示一个 "User has joined" 的通知。 + +``` +ch.on('presence', { event: 'join' }, ({  +key, newPresences }) => { +  console.log('User joined:', key,  +  newPresences); +}); + +ch.on('presence', { event: 'leave' }, ({  +key, leftPresences }) => { +  console.log('User left:', key,  +  leftPresences); +}); +``` + +通过以上ステップ,我们便構築了一个機〜できる完备的在线ステータスシステム。Supabase 自動処理了ユーザー意外断开接続(如关闭ブラウザ或断网)的情况,并在适当的时候触发 leave 事件,確保了在线列表的准确性。 + +当 Presence 让我们知道了“誰在场”後に, Broadcast 〜できる够让他们間の〜できる够进行“〜する話”,但〜する話的内容是短暂存储的。一个典型的例子であるリアルタイム光标追踪。如果每次鼠标移动都去读写データベース,〜する造成巨大的性〜できる浪费和遅延。 Broadcast 完美地解決了この問題,它許可消息在各个クライアント間の直接通过 WebSocket 传递,完全绕过データベース。 + +Broadcast 的工作模式主な依赖两个コア方法: channel.send() 用于送信,channel.on() 用于受信。】 + +1. 送信端:广播我的光标位置 + +我们为 mousemove 事件追加了一个监听器。当鼠标移动时,我们构造一个含むユーザー ID、坐标和颜色的 payload,次に通过 channel.send() 〜する其广播出去,并指定事件名称为 'cursor'。 + +```typescript +const handleMouseMove = (e) => { + const payload = { + id: anonymousUser.id, + x: e.clientX, + y: e.clientY, + name: anonymousUser.name, + color: anonymousUser.color + }; + + channelRef.current?.send({ + type: 'broadcast', + event: 'cursor', + payload + }); +}; + +document.addEventListener('mousemove', handleMouseMove); +``` + +2. 受信端:监听并渲染他人的光标 + +在同一个频道内,すべてのクライアント都使用 channel.on() 来监听 broadcast 类型的、且 event 为 'cursor' 的消息。一旦收到匹配的消息,回调函数就〜する被触发。我们从 payload 中解析出送信方的数据,并用它来更新本地的 online ステータス,从而在屏幕上リアルタイム渲染出その他ユーザー光标的位置。 + +```typescript +ch.on('broadcast', { event: 'cursor' }, ({ payload }) => { + setOnline((prev) => ({ + ...prev, + [payload.id]: { + ...(prev[payload.id] || {}), + x: payload.x, + y: payload.y + } + })); +}); +``` + +この方法で, Presence 和 Broadcast 协同工作;Presence メンテナンス在线ユーザー列表,而 Broadcast 则负责在これらのユーザー間の传递像光标位置这样的临时ステータス,最終的に以较低的成本実装了豊富なリアルタイム互动機〜できる。 + +## 5.4 存储 + +除了ユーザー信息、オーダー这类可规整定义的结构化数据,一个完全なアプリケーション通常还必〜するがある処理大量非结构化ファイル —— 例えばユーザー头像、商品表示图、ユーザーアップロード的オーダードキュメント等。这类ファイル的特点是体积差异大、数量可〜できる性がある极多(例えば电商プラットフォーム的商品图可〜できる性がある达数万甚至数十万张),若直接存储在アプリケーション自身的业务サーバー中,〜する显著増加サーバー的存储负载,还可〜できる性がある拖慢数据读写速度,影响アプリケーション整体性〜できる。 + +实际開発中,这类非结构化ファイル〜する统一交由 “对象存储サービス” 管理,OSS、Amazon S3 均属于这类サービス,它们是专门为海量ファイル存储設計的 “专业存储ツール”,〜できる高效应对ファイル的存储、备份与快速读取〜する件。而我们在アプリケーション中获取これらのファイル时,并不〜する直接从对象存储サービス的 “底层リポジトリ” 调取,而是通过 URL 地址実装:各存储在对象存储中的ファイル,都〜する被分配一个唯一的 URL(類似 “[https://xxx.oss.com/avatar/user123.jpg](PROT187)” 的地址,可シンプルな理解为この“网站”只有一张图片),この URL 就像ファイル的 “专属アクセス地址”,フロントエンドページ只需通过该地址,就〜できる直接ダウンロード或加载头像、商品图,无需依赖アプリケーション业务サーバー中转,既提升了ファイル加载速度,也减轻了业务サーバー的压力。 + +本プロジェクト `project-burger-shop-storage-uploads-4` 便通过一个ユーザー头像アップロード機〜できる,深入演示了どのように利用 Supabase Storage 構築现代化的ファイルアップロードシステム,让開発者直观理解非结构化ファイル从アップロード到通过 URL アクセス的完全なプロセス。さらに,本プロジェクト使用 `Uppy` 库来提供一个优秀的ファイルアップロード界面,并结合 `Tus` 插件実装了可续传アップロード,通过〜する Uppy 的アップロード端点指向 Supabase 的標準 API (`/storage/v1/upload/resumable`) 进行工作,できます参考類似的方式実装アップロード機〜できるコンポーネント。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image55.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image56.png) + +### 5.4.1. 存储桶 + +Supabase Storage 的组成单元是存储桶 Bucket。できます把它想象成电脑操作システム中的ファイル夹。各 Bucket 都〜できる有自分で独立したセキュリティ戦略和設定。 + +Storage 内的すべてのファイル都〜できる通过一个公开的 URL 直接アクセス,但并不意味着すべての人都〜できる随意アップロード或変更,具体的なアクセス権限〜する由更精细的戦略来控制。和データベース一样,Storage 的アクセス権限也是通过行级セキュリティ戦略来管理的。SQL 戦略写在 storage.objects 和 storage.buckets 这两张特殊表上,〜できる精确定义誰〜できる读取 (SELECT)、アップロード (INSERT)、更新 (UPDATE) 或削除 (DELETE) ファイル。 + +例えば,できます作成一条戦略,只許可ユーザーアップロード到以自分で user_id 命名的ファイル夹下,并且只〜できるアップロード图片类型的ファイル: + +``` +CREATE POLICY "Allow authenticated  +uploads to avatars bucket" +ON storage.objects FOR INSERT +TO authenticated +WITH CHECK ( +  bucket_id = 'avatars' AND +  auth.uid() = (storage.foldername(name)) +  [1]::uuid AND +  (storage.extension(name) IN ('png',  +  'jpg', 'jpeg')) +); + +CREATE POLICY "Allow public read access  +to avatars" +ON storage.objects FOR SELECT +USING ( bucket_id = 'avatars' ); +``` + +### 5.4.2 获取可アクセスファイル URL + +本プロジェクト必〜するがある你手動で作成一个名为 avatars 的公共桶,すべてのファイル〜するアップロード至该公共桶下进行存储。ファイルアップロード成功后,我们只得到了它在 Storage 中的存储パス ,例えば public/avatar1.png 。这只是存储在データベース中的一个字符串,〜する让ブラウザ〜できる够渲染这张图片,必〜するがあります〜する其转换为一个可アクセス的 HTTP URL。 + +Supabase 提供了两种截然異なる的戦略来获取この URL,它们在セキュリティ性、持久性和成本控制上有着本质的区别。 + +#### 1. 公开 URL (Public URL) - 永久リンク + +这是最直接的方式。如果你的ファイル存放在一个**Public Bucket** 中,できます获取一个固定、永久的公开リンク。 + +```typescript +const { data } = supabase.storage + .from('avatars') + .getPublicUrl('public/avatar1.png'); +const publicUrl = data.publicUrl; +``` + +这类リンク具有两大コア特点:一是シンプルな直接,其 URL 结构固定,在实际操作中易于拼接和管理,削減了技术使用门槛;二是利于缓存,作为永久リンク,它〜できる被 CDN(内容分发网络)和ブラウザ有效缓存,从而大幅提升资源的アクセス速度,最適化ユーザー体验。基于これらの特点,它适用于真正意义上的公共资源シナリオ,例えば网站 Logo、产品ディレクトリ图片、博客文章配图等,〜できる很好地满足这类资源的アクセス和管理〜する件。 + +ただし本番環境では中,这类リンク存在明显的被盗刷流量(Hotlinking)风险。由于リンク是永久公开的,外部人员〜できる轻易〜する你的图片リンクエンベディング到他们自分で的高流量网站中,导致流量被非法占用。这一行为〜する让你的 Supabase プロジェクト产生大量不必〜する的流量费用,而これらの消耗的流量并未サービス于你自身的アプリケーション,属于典型的成本浪费,是生产環境中必〜するがある高度警惕和防范的問題;したがって,必〜するがあります转向临时签名 URL 実装对外资源的暴露。 + +#### 2. 签名 URL (Signed URL) - 临时授权リンク + +を解決するため公开 URL 的セキュリティ和成本問題,Supabase 提供了生成临时签名 URL 的方式。这是绝大多数线上アプリケーションお勧め的ベストプラクティス,例えば文生图アプリケーション给ユーザー生成限时確認的图片リンク、电商プラットフォーム仅让下单ユーザー获取临时发票ダウンロード地址、有料内容プラットフォーム为サブスクリプションユーザー提供短期有效的レッスン播放リンク,既防ファイル盗用又〜できる回避流量盗刷,适配性极强。 + +```typescript +const { data, error } = await supabase.storage + .from('avatars') + .createSignedUrl('private/user-invoice.pdf', 3600); // 链接有效期为 3600 秒 (1小时) +const signedUrl = data?.signedUrl; +``` + +临时签名 URL(Signed URL)有三大コア优势:セキュリティ可控是指リンク带セキュリティ标记、有有效期,过期就用不了;権限绑定很シンプルな —— 只有〜できる看这ファイル的人,才〜できる生成このリンク,就算ファイル藏在私有存储里(Private Bucket),他用このリンク也〜できる正常打开;杜绝盗刷是なぜならリンク是临时的,コピー到别处很快就失效,不〜する被恶意刷流量。靠これらの优势,像ユーザー头像、私人照片、有料内容、オーダー发票これらの必〜するがある管権限的ファイル,都〜できる用它。 + +从セキュリティ保障和成本控制的角度,提案养成优先使用临时签名 URL 的习惯。只有当某个资源明确必〜するがある永久公开、无限制アクセス(例えばアプリケーション的公开 Logo、公共活动宣传图等)时,才考虑使用 Public URL。这样既〜できる满足特定业务〜する件,又〜できる最大程度规避不必〜する的风险和成本消耗。 + +## 5.5 边缘函数 + +Edge Function 是 Serverless(无サーバー架构)生态中极具コア价值的形态之一,它为 “无自建バックエンド” シナリオ提供了轻量、効率的な函数実行サポート。 + +何是 Serverless? Serverless(无サーバー架构)并不意味着真的没有サーバー,而是指開発者无需关心サーバー的购买、运维、設定和扩容 。你只必〜するがある编写业务コード(函数),云サービス商〜する在特定事件触发时自動为你分配资源実行コード,并按实际実行时间计费。 + +当你的アプリケーション必〜するがある実行いくつかの不〜できる或不应在クライアント(ブラウザ)上完了的逻辑时——例えば与必〜するがある私密キー的第三方 API 交互、実行计算密集型タスク、或强制実行複雑な业务ルール——Edge Functions 就派上了用场。Supabase Edge Functions 基于 Deno 和 TypeScript,它们被デプロイ在全球的边缘节点上,物理距离上靠近你的ユーザー,从而提供极低的函数実行遅延。 + +目前主流云厂商都推出了各自的 Edge Function サービス,よくある包括: + +- AWS Lambda@Edge:基于 AWS Lambda 延伸的边缘函数サービス,可与 CloudFront CDN 联动,サポート Node.js、Python 等语言; +- Cloudflare Workers:Cloudflare 推出的边缘函数,デプロイ在其全球 275+ 边缘节点,サポート JavaScript/TypeScript,以 “毫秒级遅延” 为コア优势; +- Vercel Edge Functions:适配 Vercel フロントエンドプロジェクト的边缘函数,与 Next.js 深度集成,サポート TypeScript,主打 “フロントエンド与边缘逻辑无缝衔接”; + +回到 Supabase ,当你的アプリケーション必〜するがある実行 “不〜できる在クライアント(ブラウザ)完了” 的逻辑时,例えば用私密キー调用第三方 API(如 LLM インターフェース)、処理计算密集型タスク(如图片压缩)、或强制実行権限校验(如ファイルアクセスルール)时,Supabase Edge Functions 就〜できる发挥作用。它基于 Deno runtime 和 TypeScript 構築,デプロイ在全球边缘节点上,〜できる以 “靠近ユーザー的物理距离” 実装极低的実行遅延,是编写自定义、可信サーバー端逻辑的コアツール。 + +本プロジェクト `Project5-Supabase-Demos/apps/project-burger-shop-edge-function-5`通过一个与大規模言語モデル(LLM)リアルタイム流式〜する話的機〜できる,表示了 Edge Functions 的最简アプリケーションプロセス。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image57.png) + +### 5.5.1 LLM Chat 案例解析 + +假设你想在アプリケーション中集成一个類似 ChatGPT 的チャット机器人。必〜するがあります在サーバー端调用 OpenAI 的 API,但这必〜するがある一个私密的 API Key。 この Key 绝对不〜できる暴露在フロントエンドコード中 ,否则すべての人都〜できる通过確認网页源码盗用你的 Key,产生高昂的费用。这正是 Edge Function 的用武之地。します作成一个名为 llm-chat 的函数,它充当了フロントエンド和 OpenAI API 間の的一个 セキュリティ代理 。 + +参考 `project-burger-shop-edge-function-5/scripts/llm-chat.ts`的コード,我们来看看它是どのように工作的: + +```typescript +// scripts/llm-chat.ts +import "jsr:@supabase/functions-js/edge-runtime.d.ts"; +import { OpenAI } from "npm:openai"; + +const OPENAI_API_KEY = Deno.env.get("OPENAI_API_KEY"); + +Deno.serve(async (req) => { + try { + const openai = new OpenAI({ apiKey: OPENAI_API_KEY }); + const { prompt } = await req.json(); + + const stream = await openai.chat.completions.create({ + model: "gpt-3.5-turbo", + messages: [{ role: "user", content: prompt }], + stream: true, + }); + + return new Response(stream.toReadableStream(), { + headers: { "Content-Type": "text/event-stream" }, + }); + } catch (err) { + } +}); +``` + +在该案例中,对于キーセキュリティ,OPENAI_API_KEY 作为環境変数被セキュリティ存储于 Supabase 的サーバー。本地フロントエンドコード完全无法接触到该キー,从而有效保障了キー的セキュリティ性。 + +### 5.5.2 作成并デプロイ函数 + +Supabase 提供了非常に友好的界面,让你无需接触コマンド行即可完了デプロイ。 + +1. **进入 Edge Functions 面板** : +2. ログイン你的 Supabase プロジェクト Dashboard。 +3. 在左侧导航栏中,クリック像コード一样的图标,进入 “Edge Functions”。 +4. **作成新函数** : +5. クリック “Create a new function” 按钮。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image58.png) +6. 为函数命名,例えば `llm-chat`。 +7. **貼り付けコード** : + ![](/zh-cn/stage-2/backend/database-supabase/images/image59.png) +8. 在弹出的在线編集器中, **削除すべてのデフォルトの占位コード** 。 +9. 打开你本地的 `llm-chat.ts` ファイル, **コピー其全部内容** 。 +10. 〜するコピー的コード**貼り付け**到 Supabase 的在线編集器中。 +11. **設定\*\***環境変数\*\* ** (Secrets)** : + 1. 在侧边栏找到 Secrets。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image60.png) + 2. Name: 入力 `OPENAI_API_KEY`。 + 3. Value: 貼り付け你自分で的 OpenAI API Key。 + 4. クリック “Save”。在ここ设置的 Secret 〜する被加密存储,并セキュリティ地注入到你的函数実行时環境中。 + +若有函数必〜するがある更新,记得在 Edge Function 部分実行 Deploy updates。Supabase 〜する在云端为你構築并デプロイこの函数。几分钟后,你的函数就〜できる在线アクセス。 + +除了作为语言モデル的セキュリティ代理,Edge Functions 的アプリケーションシナリオ远不止于此。実際には,すべての必〜するがあるサーバー端逻辑処理的タスク,无论是シンプルな API 调用、数据検証,还是更複雑な计算,都〜できる通过 Edge Function 実装。它为你提供了一个轻量级、可拡張的バックエンド,而无需管理すべてのサーバー基本的な设施。 + +如果你想探索更多可〜できる性がある性,〜できる参考プロジェクト中的その他例。例えば: + +- 图片生成 ( txt2img.ts ) : この函数表示了どのように利用 Edge Function 调用第三方的文生图(Text-to-Image)API(如 Stability AI, Midjourney 等)来动态生成图片。这是1 つの典型的计算密集型或必〜するがあるセキュリティ调用外部サービス的シナリオ。与 llm-chat 案例一样,API キー被セキュリティ地存储在 Supabase バックエンド,フロントエンド只负责送信文本説明,次に受信并表示生成的图片,全体の过程セキュリティ、高效。 +- 送信邮件 ( send-email.ts ) : 在アプリケーション中送信欢迎邮件、交易通知或密码重置邮件是一般的な〜する件。 send-email.ts 例演示了どのように通过 Edge Function 集成邮件サービス(如 Resend, SendGrid)。你无需在クライアントコード中暴露敏感的邮件サービス API Key,只需作成一个函数,让フロントエンド通过调用この函数来触发邮件送信。 + +## 5.6 Clerk ログイン + +Clerk 是一款专注于身份认证与ユーザー管理的专业開発ツール,コア〜できる力覆盖ユーザー新規登録、ログイン、账号セキュリティMFA、権限控制、〜する话管理等全链路身份认证相关〜する件,〜できる帮助開発者快速搭建セキュリティ、灵活且符合现代アプリケーション標準的なユーザー体系,无需从零開発複雑な身份逻辑。 + +本部分〜する介绍どのように从零开始設定 Clerk サービス,并〜する其与 Supabase 进行整合。できます在プロジェクト `project-burger-shop-auth-advanced-clerk-7` 中体验全プロセス。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image61.png) + +### 5.6.1 作成 Clerk アプリケーション与获取キー + +在使用本プロジェクト前に,必〜するがあります拥有一个 Clerk 账号并作成一个アプリケーション。 + +1. 新規登録与作成: + 1. アクセス [dashboard.clerk.com](PROT188) 并新規登録账号。 + 2. クリック "Create application" 。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image62.png) + 3. 入力アプリケーション名称(例えば "Burger Shop")。 + 4. 在 "How will your users sign in?" 中,デフォルト勾选 Email , Google , GitHub 。 + 5. クリック Create application 。 +2. 获取 API Keys: + 1. 作成成功后,你〜する被引导至 API Keys ページ。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image63.png) + 2. 找到 Publishable key (以 `pk_` 开头) 和 Secret key (以 `sk_` 开头)。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image64.png) + 3. 〜する它们コピー到你的 `.env.local` ファイル中(参考本プロジェクト `.env.example`): + + ```bash + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... + CLERK_SECRET_KEY=sk_test_... + ``` + +### 5.6.2 設定 Supabase 和 Clerk 的原生集成 + +在进一步使用前,必〜するがあります集成 Supabase 与 Clerk 的关联关系,方便後にログイン的鉴权リダイレクト以及控制对特定データベース的アクセス権限。Supabase 与 Clerk 提供官方原生集成〜できる力,通过该集成可快速実装两者的身份认证打通,无需手動で設定複雑な适配逻辑,大幅簡素化ユーザーログイン、権限校验等機〜できる的開発プロセス: + +1. 在 Clerk 中激活对 Supab ase 的官方集成 + 1. ログイン [Clerk Dashboard](PROT189)。 + 2. 在左侧菜单导航至 Integrations (集成)。 + 3. 在列表中找到并クリック Supabase。 + 4. 开启 Enable Supabase 开关(或クリック Activate integration)。 + 5. 重〜するななステップ:激活成功后,ページ〜する表示你的 Clerk Domain(格式通常为 `https://.clerk.accounts.dev` 或你的自定义域名)。请コピーこの Domain 地址,次のステップ〜する用到。 +2. 在 Supabase 中追加 Clerk 提供商 + 1. ログイン [Supabase Dashboard](PROT190) 并进入你的プロジェクト。 + 2. 在左侧菜单导航至 Authentication > Sign In / Up (或者直接クリック Providers)。 + 3. クリック Add provider 按钮,从下拉列表中選択 Clerk。 + 4. 在弹出的 Clerk Domain 入力框中,貼り付け你刚才从 Clerk コピー的 Domain 地址。 + 5. クリック Save 保存設定。 + +### 5.6.3 通过 Webhook 同步ユーザー数据至 Supabase + +仅仅是集成只满足了鉴定権限的〜する件,但这并不〜する〜する Clerk 中すでに新規登録的ユーザー信息同步到 Supabase,を容易にするため管理,我们还必〜するがある在 Supabase 的 `public.users` 表中保留一份ユーザー备份,以便进行关联查询或数据分析。できます通过 Clerk Webhooks 実装这一機〜できる,完全な过程如下: + +1. **Clerk 送信通知** : 当ユーザー在 Clerk 新規登録或更新资料时,Clerk 〜する向我们設定的 Webhook URL 送信一个 POST リクエスト。 +2. **Supabase 受信并写入** : Edge Function 受信リクエスト,検証签名(確保セキュリティ),次に〜するユーザー数据更新到 Supabase 的データベース表中。 + +始める前に,必〜するがあります設定同步信息所需的数据表: + +```sql +-- File: init.sql + +-- 1. Create `users` table for synced Clerk users +-- This table will store user data pushed from Clerk Webhooks. +CREATE TABLE public.users ( + id TEXT NOT NULL PRIMARY KEY, -- Corresponds to Clerk User ID + email TEXT, + first_name TEXT, + last_name TEXT, + image_url TEXT, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- 2. Enable Row Level Security (RLS) on the table +-- This is an important security measure to ensure users cannot access any data by default. +ALTER TABLE public.users ENABLE ROW LEVEL SECURITY; + +-- 3. Create RLS policies +-- Policy 1: Allow authenticated users to read their own user info. +-- `auth.jwt()->>'sub'` extracts the user ID from the JWT provided by Clerk. +CREATE POLICY "Authenticated users can view their own user record" +ON public.users FOR SELECT +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); + +-- Policy 2: Allow users to update their own info. +CREATE POLICY "Authenticated users can update their own user record" +ON public.users FOR UPDATE +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); +``` + +以及在 Supabase 中启用对应的 Edge function: + +```JavaScript +// File path: supabase/functions/clerk-webhooks/index.ts + +import { serve } from 'https://deno.land/std@0.177.0/http/server.ts' +import { Webhook } from 'npm:svix' +import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' + +// Get Clerk Webhook signing secret from environment variables +const CLERK_WEBHOOK_SECRET = Deno.env.get('CLERK_WEBHOOK_SECRET') + +if (!CLERK_WEBHOOK_SECRET) { + throw new Error('CLERK_WEBHOOK_SECRET is not set in environment variables') +} +const supabaseAdmin = createClient( + Deno.env.get('SUPABASE_URL')!, + Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')! +) + +serve(async (req) => { + try { + // 1. Get Svix signature info from request headers + const headers = Object.fromEntries(req.headers) + const svix_id = headers['svix-id'] + const svix_timestamp = headers['svix-timestamp'] + const svix_signature = headers['svix-signature'] + + if (!svix_id || !svix_timestamp || !svix_signature) { + return new Response('Missing Svix headers', { status: 400 }) + } + + const payload = await req.json() + const body = JSON.stringify(payload) + + // 2. Verify Webhook signature validity using the secret + const wh = new Webhook(CLERK_WEBHOOK_SECRET) + const evt = wh.verify(body, { + 'svix-id': svix_id, + 'svix-timestamp': svix_timestamp, + 'svix-signature': svix_signature, + }) + + const { id } = evt.data + const eventType = evt.type + console.log(`Received webhook event: ${eventType} for user: ${id}`) + + // 3. Execute database operations based on event type + switch (eventType) { + case 'user.created': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin.from('users').insert({ + id, + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + }) + if (error) throw error + console.log(`User ${id} created in Supabase.`) + break + } + + case 'user.updated': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin + .from('users') + .update({ + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + updated_at: new Date().toISOString(), // Update timestamp + }) + .eq('id', id) + if (error) throw error + console.log(`User ${id} updated in Supabase.`) + break + } + + case 'user.deleted': { + // For delete events, ID might be at the top level + const deletedId = id + if (!deletedId) { + return new Response('Deleted user ID not found', { status: 400 }) + } + const { error } = await supabaseAdmin.from('users').delete().eq('id', deletedId) + if (error) throw error + console.log(`User ${deletedId} deleted from Supabase.`) + break + } + } + + return new Response('Webhook processed successfully', { status: 200 }) + } catch (err) { + console.error('Error processing webhook:', err.message) + return new Response(`Webhook Error: ${err.message}`, { status: 400 }) + } +}) +``` + +初始化 Supabase 数据表与函数结束后,你还必〜するがある在 Clerk 中启用 Webhooks サポート: + +- 在 Clerk Dashboard -> **Webhooks** 中追加 Endpoint,填入Supabase Edge Function 的 URL。 +- 勾选 `user.created`, `user.updated`, `user.deleted` 等事件。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image65.png) + +一旦设置成功,你〜できる够在 Message Attempts 中看到異なるリクエスト信息,クリック后可看到詳細なリクエスト返すパラメータ結果;如果 webhook 在リクエスト Edge function 时出现問題,できます快速在返す值中找到详细原因結果。お勧め你 对照 Clerk 和 Supabase 的リクエストログ信息,用于分析各个函数设定是否正确。 + +### 5.6.4 Clerk 中的第三方ログインサポート + +在深入了解どのように对 Clerk サポート第三方ログイン前,我们先明确两个コア概念:開発環境与生产環境,这是软件从 “開発テスト” 到 “上线可用” 的两个重〜するなな阶段,二者的定位、用途和セキュリティ〜する求截然異なる: + +- 開発環境:開発者本地或テストサーバー使用的環境,仅用于機〜できる開発、デバッグ和内部検証(如本地 localhost:3000 サービス),不对外开放 +- 生产環境:アプリケーション正式上线后,面向真实ユーザー的公开環境(如デプロイ在 Vercel、阿里云等プラットフォーム的 https://my-app.com) + +而 Clerk 对社交ログイン区分这两种環境,本质是平衡 “開発效率” 与 “生产セキュリティ”:開発阶段需減少冗余設定以快速検証機〜できる,生产阶段需通过专属凭证保障数据セキュリティ, 符合 Google、GitHub 等第三方 OAuth プラットフォーム的ルール(线上アプリケーション必須绑定专属域名与凭证,不許可使用共享资源)。下具体说明两种環境下 Clerk 社交ログイン的差异設定: + +1. **開発環境快速検証** + +開発環境中,Clerk 已预置共享 OAuth 凭证和デフォルト重定向 URI,无需前往 GitHub/Google 申请专属凭证,操作ステップ如下: + +- ログイン Clerk Dashboard ,在左侧导航栏进入 SSO connections (SSO 接続)ページ。 +- クリック Add connection (追加接続),選択 For all users (对すべてのユーザー生效)。 +- 在 Choose provider (選択提供商)下拉菜单中,按需選択 GitHub 或 Google 。 +- 直接クリック Add connection (追加接続),Clerk 〜する自動用共享凭证完了绑定。 + + 設定后,本地起動アプリケーション(如 `localhost:3000`)并クリック“Sign in with GitHub/Google”,Clerk 〜する自動代理ログインリクエスト,快速検証機〜できる是否正常。 + +2. **生产環境自定义凭证設定** + +(注:もし有环节和预期不一致,提案阅读官方ドキュメント进行最新方式的尝试) + +アプリケーションデプロイ上线(如 Vercel、阿里云)并切り替え到 Clerk Production Instance 后,共享凭证失效,需为 GitHub/Google 設定自定义 OAuth 凭证(提案 打开 Clerk Dashboard 和第三方プラットフォームページ,方便同步操作): + +- 前置通用操作(Clerk 控制台): + - 进入 Clerk SSO connections ページ,クリック Add connection → 選択 For all users 。 + - 選択目標プラットフォーム(GitHub/Google),確保开启 Enable for sign-up and sign-in (許可新規登録ログイン)和 Use custom credentials (使用自定义凭证)。 + - コピーページ中的 Authorization Callback URL (GitHub)或 Authorized Redirect URI (Google),保存到セキュリティ位置,不〜する关闭当前ページ/弹窗。 +- 2.1 GitHub プラットフォーム設定: + - ログイン GitHub,进入 Developer Settings (パス:头像 → Settings → Developer settings → OAuth Apps)。 + - クリック New OAuth app ,填写信息:`Application name`(アプリケーション名称)、`Homepage URL`(生产域名,如 `https://my-app.com`)、`Authorization Callback URL`(貼り付け从 Clerk コピー的地址)。 + - クリック Register application ,再クリック Generate a new client secret ,保存生成的 Client ID 和 Client Secret (Secret 仅表示一次)。 + - 回到 Clerk 弹窗,貼り付け Client ID 和 Client Secret,クリック Add connection 完了設定(若关闭弹窗,可在 SSO connections 找到 GitHub 接続,在“Use custom credentials”モジュール补填)。 +- 2.2 Google プラットフォーム設定: + - ログイン Google Cloud Console ,選択已有プロジェクト或新建プロジェクト(如“My App Production”)。 + - クリック左上角菜单 → APIs & Services → Credentials ,クリック Create Credentials → OAuth client ID (首次設定需先完了 OAuth consent screen 设置,選択“External”并填写アプリケーション信息)。 + - 選択 Application type 为 Web application ,設定: + 1. `Authorized JavaScript origins`:追加生产域名(如 `https://my-app.com`、`https://www.my-app.com`),本地検証可补充 `http://localhost:端口号`。 + 2. `Authorized Redirect URIs`:貼り付け从 Clerk コピー的地址。 + - クリック Create ,保存弹窗中的 Client ID 和 Client Secret ,回到 Clerk 弹窗貼り付け并クリック Add connection 。 + - 重〜するなな注意事项: + 1. 禁止 WebView ログイン:Google OAuth 不サポートアプリケーション内ブラウザログイン,需参考 [Google 官方ドキュメント](PROT192) 调整。 + 2. 切り替え公開ステータス:デフォルト“Testing”ステータス仅サポート 100 个テストユーザー,需在 OAuth consent screen 〜する“Publishing status”改为 In production (需通过 Google 审核)。 + 3. 阻止子邮箱:Clerk デフォルト拦截含 `+`/`=`/`#` 的 Google 邮箱(如 `user+alias@example.com`),可在 Google 接続详情页开启/关闭 Block email subaddresses (提案开启提升セキュリティ性)。 + 4. サポート Google One Tap:設定完了后,可集成 Clerk `` コンポーネント実装“一键ログイン”,参考 [Clerk コンポーネントドキュメント](PROT193)。 + +3. テスト第三方ログイン接続 + +設定完了后,通过 Clerk 内置 Account Portal 検証機〜できる: + +- 进入 Clerk Dashboard,左侧导航栏进入 Account Portal ページ。 +- 在“Sign-in”モジュール右侧,クリック“アクセスログインページ”按钮,リダイレクト至对应環境ログイン页: + - 開発環境:`https://你的域名.accounts.dev/sign-in`(如 `https://my-app.accounts.dev/sign-in`)。 + - 生产環境:`https://accounts.你的域名.com/sign-in`(如 `https://accounts.my-app.com/sign-in`)。 +- クリック“Sign in with GitHub/Google”,用对应プラットフォーム账号ログイン,若〜できる成功リダイレクト并返すアプリケーション,说明接続設定正常。 + +# 6. 从 Supabase 到更多バックエンド開発コンポーネント(応用) + +在上文中,我们主な是站在 Supabase 的视角,去看“一个以 Postgres 为コアとなる一站式バックエンドプラットフォーム”〜できる帮我们解決哪些問題:认证、データベース、ファイル存储、リアルタイム通信、边缘函数等,都被集成在同一个控制台里,开箱即用、体验统一,非常に适合快速起步和中小型プロジェクト。 + +但从更长期、更工程化的角度来看, **Supabase 提供的每一块〜できる力(Auth / Storage / Edge Functions / Realtime / Database),在业界几乎都有对应的专业替代ソリューション** ——既包括同类 BaaS プラットフォーム,也包括更“单点突破”的云サービス和开源コンポーネント。作为上进的个人開発者和初创团队来说,了解これらの替代选项有几个好处: + +- 判断当前プロジェクト是否“全用 Supabase 就够了”,还是某一块必〜するがある更专业/更便宜/更易合规的专用サービス; +- 当プロジェクト规模变大或〜する件变複雑な时,是否〜できる把某个モジュール从 Supabase 替换出去(例えば改用专门的 Auth プラットフォーム或对象存储),而不是一开始就被プラットフォーム彻底锁死; +- 拓宽技术选型视野,即使暂时不更换,也〜できる大致知道“如果不用 Supabase 的 X 機〜できる,我また哪些一般的な選択”。 + +本节〜するそれぞれ介绍 Supabase 所覆盖的几大〜できる力在市场上的主流替代ソリューション,例えば:认证(Auth)、ファイル存储(Storage)、边缘函数(Edge Functions)、リアルタイム通信(Realtime)、データベース托管等。シンプルな对比它们在機〜できる特性、無料额度/定价、易用性以及社区流行度等方面的差异, 让你对バックエンドコンポーネントツール库有更全面的理解。 + +## 同类 Baas プラットフォーム + +始める前に,できます浏览同类的 Baas プラットフォーム,若觉得 Supabase 不够好用,できます根据〜する件選択異なる替代品进行尝试。 + +| プラットフォーム/サービス | 类型 | 無料额度/定价 | 特点 / 适用シナリオ | +| ------------------------ | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| Firebase(Google) | 全托管 BaaS(Auth + Firestore + Storage + Functions + Hosting) | Spark:無料轻量额度;Blaze:按量计费(Firestore/Storage/Functions それぞれ算) | 行业最成熟、ドキュメント好、上手快、リアルタイム〜できる力强。适用于中小型产品、移动/フロントエンド主导团队。缺点:计费複雑な、锁定性强、查询限制多(尤其 Firestore)。 | +| Supabase | 开源 BaaS(Postgres + Auth + Storage + Edge Functions + Realtime) | 無料:500MB DB、1GB Storage、无サーバー函数少量调用;Pro:按实例计费 | 最像 Firebase 的 SQL 版;界面优秀、体验现代、可自托管。适用于必〜するがある强 SQL、BI、事务〜できる力的アプリケーション。缺点:高并发或複雑な函数成本较高。 | +| Appwrite Cloud | 开源一站式 BaaS(DB + Auth + Storage + Functions + Realtime) | 無料:含む基本 DB/Storage/FaaS;有料按资源级别计费 | 体验现代化、API 统一、可自托管;适合開発者友好的アプリケーション快速迭代。缺点:生态还不如 Firebase/Supabase 成熟;性〜できる在大型アプリケーション中必〜するがあるテスト。 | +| Nhost | Postgres + GraphQL + Auth + Storage + Functions | 無料:1GB DB、1GB Storage、少量函数调用 | 類似“Supabase + Hasura”;天然 GraphQL;适合フロントエンド团队与 React/Next.js プロジェクト。缺点:生态小、成本随用量升高。 | +| AWS Amplify | AWS 一站式バックエンド(Cognito + AppSync + DynamoDB + Storage + Functions + Hosting) | 無料:Hosting 额度 + Cognito 10k MAU + 部分函数额度 | 大而全,适合已有 AWS 基本的な的团队;企业级可靠性。缺点:最难上手,サービス碎片化;初创团队メンテナンス成本高。 | +| Xata(近两年快速增长) | 多モデルデータベース + Auth + Edge Functions | 無料:250k レコード、15GB 带宽 | 虽然更偏「DB + API」,但提供 Auth、ファイル、逻辑,可作为轻量全栈バックエンド。UI/開発体验极佳。缺点:機〜できる不如 Firebase/Supabase 全面。 | +| Convex(開発者体验极强) | 托管データベース + Auth + Functions(フロントエンド优先) | 無料開発版;有料按リクエスト量计费 | 极简上手;无需 schema;フロントエンド写函数即可用バックエンド。适合 MVP/快速検証。缺点:高度绑定プラットフォーム,迁移成本高;不算完全传统 BaaS。 | + +## 认证 (Auth) + +| ツール/プラットフォーム | 機〜できる特点 | 無料额度/定价 | 适用シナリオ与优缺点 | +| ----------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| Firebase Authentication | Google 提供的 BaaS 身份検証サービス,サポート邮箱/密码、手机、社交ログイン、匿名等一般的な方式。Spark 無料ソリューションサポート最高50k 月活跃ユーザー。 | Spark(無料)50k MAU;Blaze 按量计费 | 集成 Google 生态,ドキュメント丰富,上手シンプルな;機〜できる全面(MFA、阻塞函数等),适合快速開発。但与 Firebase プラットフォーム绑定,拡張到その他サービス需额外設定。 | +| Auth0 (Okta) | 全托管身份认证プラットフォーム,サポート社交ログイン、企业 SSO、多因子认证、ルール拡張等强大機〜できる。 | 無料ソリューション25k MAU,有料按 MAU 计费 | 企业级機〜できる齐全(RBAC、审计ログ等),适合中大型アプリケーション;界面友好。缺点是 MAU 上升时成本高,無料版機〜できる有限(如不含 MFA/RBAC)。社区知名度高,ユーザー众多。 | +| AWS Cognito | 亚马逊云原生身份サービス,サポート社交及 SAML 联合ログイン。直接ログインユーザー池提供每月10k MAU 無料,超过部分按 0.0055 美元/MAU 收费。 | 無料10k MAU/月,超出按量有料 | 与 AWS 生态深度集成(可无缝配合 API Gateway、Lambda 等),入門门槛略高,ドキュメント较複雑な;無料额度有限,适合已有 AWS 使用习惯的团队。 | +| Logto | 开源身份认证プラットフォーム,自托管版無料,云サービス计划無料50k MAU。サポート多语言、多租户、OAuth/OIDC 等。 | 社区版無料;Logto Cloud 無料50k MAU | 近期流行的 Auth0 开源替代ソリューション,GitHub 已有 10k+ Stars。易拡張,自托管削減成本;缺点是生态和ドキュメント比較的较新,社区规模略逊于 Firebase/Auth0。 | +| Keycloak | 知名开源 IAM/SSO 解決ソリューション,サポートユーザー名密码、LDAP、SAML、OAuth2 等。 | 完全無料,需自托管 | 機〜できる强大、可拡張(サポート细粒度権限控制),企业级機〜できる丰富;但デプロイ和メンテナンス複雑な度高,对小团队而言学习曲线较陡。缺点是对容器化和集群运维〜する求较高。 | + +## ファイル存储 (Storage) + +| プラットフォーム/サービス | 类型 | 無料额度/定价 | 特点/适用シナリオ | +| ---------------------------------------- | -------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| Amazon S3 | 云对象存储(AWS) | AWS 無料プラン提供 5GB 存储、20k GET/PUT リクエスト/月,超出按使用量有料 | 行业標準的な对象存储,可靠性高、全球多区域デプロイ。機〜できる全面,与 AWS 生态整合良好;定价较複雑な,新ユーザー需了解计费ルール。 | +| Google Cloud Storage(Firebase Storage) | 云对象存储(Google) | Firebase Spark ソリューション提供無料额度(1GB 存储 + 流量限制),Blaze 有料 | 与 Firebase/Google Cloud 紧密集成,易于管理;サポート CDN 加速、细粒度セキュリティルール。 | +| 腾讯云 COS / 阿里云 OSS | 云对象存储(国内) | 按量有料(各有新ユーザー赠送额度,如OSS有首年40GB無料等) | 面向国内市场,高性〜できる、大规模对象存储;与中国云生态整合,ドキュメント较完善。阿里OSS 機〜できる全面、全球加速;七牛KODO 专注多媒体処理,成本较低,适合个人和小团队。 | +| MinIO | 开源 S3 兼容存储 | 开源無料(自建) | 轻量级、高性〜できる、与 S3 API 兼容,适合在私有云或本地搭建对象存储。ドキュメント和社区活跃;需自分でメンテナンス基本的な设施。 | +| Cloudinary / Imgix 等 | 媒体存储+CDN | 基本無料ソリューション(如 Cloudinary 無料 25GB/月带宽) | 针对图片/视频最適化的云存储+CDN サービス,提供リアルタイム转码、压缩等高度な機〜できる。适合媒体プロジェクト,但機〜できる较专一,作为通用ファイル存储使用成本偏高。 | + +## 边缘函数 (Edge Functions) + +| プラットフォーム/サービス | 特点 | 無料额度/定价 | 适用シナリオ与优缺点 | +| -------------------------------------- | ------------------------------------------ | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Cloudflare Workers | 全球分布式 JavaScript/Wasmtime 環境 | 無料计划:每天 100k リクエスト;標準计划$5/月含1,000万リクエスト | 実行在 Cloudflare 边缘节点,遅延极低;适合全局分发的逻辑、静态资源渲染等。無料配额较少(相当于每月约300万リクエスト),上手シンプルな。缺点是実行时(JS/Wasmtime)限制与デバッグツール有限。 | +| Vercel Edge Functions | 随 Next.js/フロントエンドフレームワーク无缝集成,サポート JS/TS/Go | Hobby 無料:每月 100万 函数调用,100万 边缘リクエスト | 深度集成フロントエンドフレームワーク,自動デプロイ;适合现代 Web アプリケーション。無料额度充足,デフォルト実行时 10s,可提升至 60s。缺点是無料版团队协作機〜できる受限;依赖 Vercel プラットフォーム。 | +| Netlify Edge / Functions | Node.js 云函数+边缘路由(NFT) | 無料:300 代币/月(约相当于每月 1M リクエスト);按信用点计费 | サポート Node.js 函数、边缘処理路由等。無料额度用于構築、函数和带宽,适合フロントエンド全栈デプロイ。优点是简便易用,集成 Git デプロイ;缺点是無料额度使用需算计(10k リクエスト = 3 点)。 | +| AWS Lambda@Edge / CloudFront Functions | AWS 无サーバー边缘计算 | AWS Lambda(1M 無料リクエスト/月+400k GB-s)+ CloudFront $0.085/每10万调用起 | 与 CloudFront 集成,可在边缘実行コード。适合必〜するがある AWS 生态(如在节点层面做権限或 A/B テスト)。优点是灵活强大;缺点是設定複雑な,遅延略高于 Cloudflare/Vercel。 | + +## リアルタイム通信 (Realtime) + +| プラットフォーム/サービス | 機〜できる特点 | 無料额度/定价 | 适用シナリオ与优缺点 | +| -------------------------------------- | ------------------------------------------------ | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| Firebase Realtime Database / Firestore | Google BaaS リアルタイムデータベース;サポート数据变更推送 | Spark 無料:リアルタイムデータベース1GB 存储 & 限额;Blaze 按量有料 | 强集成 Firebase 生态,リアルタイム监听シンプルな。优点是無料起步快;缺点是データベース类型(JSON/NoSQL),複雑な查询〜できる力弱。 | +| Ably | リアルタイム消息与 pub/sub プラットフォーム,サポート WebSocket、MQTT 等 | 無料包:每月 6,000,000 条消息 | 機〜できる全面的リアルタイム消息サービス,高并发サポート;無料额度可达600万消息/月。社区与ドキュメント较好,适合全球分布。 | +| Pusher Channels | 事件推送サービス,サポート频道/事件机制 | Sandbox 無料:每日 200k 消息,100 并发接続 | 易用的 WebSocket サービス,ドキュメント齐全,适合快速実装チャット和通知機〜できる。無料版限制消息量和接続数;有料后拡張性好。 | +| 自建 WebSocket/Socket.IO | 自分で搭建サーバー(Node.js、Elixir 或 Go 等) | 自行托管成本(如サーバー费用) | 灵活度最高,可根据〜する件定制协议和拓扑。适合对成本控制严格且技术成熟的团队。缺点是需自行処理可用性、拡張和跨域等問題。 | + +## データベース + +| プラットフォーム/ツール | データベース类型 | 無料额度/定价 | 主な特点 | +| ---------------------------- | --------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| Neon (Serverless PostgreSQL) | 关系型(PostgreSQL) | 無料计划:0.5GB 存储,主ブランチ永久在线,20h ブランチ计算/月 | 云原生无サーバー Postgres,サポート自動伸缩和ブランチ(fork テスト)。無料额度对小プロジェクト够用,适合现代開発プロセス。ブランチ機〜できる强大,但無料额度较小。 | +| Aiven PostgreSQL | 关系型(PostgreSQL/MySQL) | 無料计划:1GB 存储,1 vCPU,1GB 内存 | 托管级データベースサービス,サポート跨云多区域迁移。提供有 MySQL、Redis 等可选。無料额度适合開発和小型プロジェクト;商业版サポート高可用集群和モニタリング。 | +| CockroachDB Cloud | 分布式 SQL(兼容 PostgreSQL) | 無料计划:10GB 存储 | 類似 Google Spanner 的分布式 SQL データベース,自動分片拡張。無料10GB 空间较慷慨;适合必〜するがある横向拡張和高一致性的アプリケーション。商业版 SLA 高。 | +| TiDB Cloud | 分布式关系型(MySQL 兼容) | 無料计划:每节点5GB,总计最多25GB | 开源 TiDB 的云版,兼容 MySQL 协议,分布式架构。無料额度充足,适合熟悉 MySQL 的团队,性〜できる优秀;缺点是运维比較的複雑な(针对大型シナリオ)。 | +| MongoDB Atlas | ドキュメント型(NoSQL MongoDB) | 無料 M0 集群:0.5GB 存储 | 云端 MongoDB,柔軟なドキュメントモデル,サポート丰富查询和索引。無料 0.5GB データベース适合テスト和小型アプリケーション;可按需横向拡張。学习曲线略高于关系型データベース。 | +| SQLPub | 多データベース(MySQL、PostgreSQL、Redis 等) | 無料计划:36,000 リクエスト/小时,30 并发接続,500MB 存储 | 一站式データベースプラットフォーム,サポート多种データベース类型。無料版适合学习和小プロジェクト;优点是サポート多种 DB,缺点是存储额度较小。 | + +以上替代ソリューション各有侧重:开源更灵活可控(Keycloak、MinIO、Socket.IO、Neon、CockroachDB 等),云托管サービス更易上手(Firebase、Auth0、Cloudflare、Vercel、Netlify、AWS、Aiven、MongoDB Atlas 等)。選択时可根据プロジェクト〜する件、团队技术栈、预算和社区生态等权衡。个人プロジェクト可优先选用無料配额充足、易集成的サービス(如 Firebase 系列、七牛存储、Cloudflare Workers、Neon、CockroachDB 等),而对企业级或特定セキュリティ〜する件,则可考虑機〜できる更丰富但收费较高的ソリューション(Auth0、Alibaba/Tencent 云、AWS、TiDB/Aiven 等)。できます在实际アプリケーション中不断尝试,直到選択出最适合的バックエンド開発ツールコンポーネント。 + +# 总结 + +在今天的レッスン中,我们システム学习了データベース的基本的な概念、Supabase 的コア定义及其操作细节。后续在实践过程中,你可根据プロジェクト的实际アプリケーションシナリオ与〜する件,随时回头翻阅这份ドキュメント作为参考。 + +请时刻记住一个重〜するな原则: **先完了,再完美!** 无需追求一步到位,我们完全〜できる通过継続的に迭代最適化,段階的に靠近更优的成果。祝你在后续的プロジェクト实践中一切顺利! + +# 📚 課題 + +1. 開発一个含むユーザー管理システム和データベース的アプリケーション程序。最好含む更多的Supabase 機〜できる (Realtime / cloud storage / Edge function). diff --git a/docs/ja-jp/stage-2/backend/git-workflow/index.md b/docs/ja-jp/stage-2/backend/git-workflow/index.md new file mode 100644 index 0000000..f0207d0 --- /dev/null +++ b/docs/ja-jp/stage-2/backend/git-workflow/index.md @@ -0,0 +1,261 @@ +# GitとGitHubワークフロー + +前のコースでは、Webベースのvibe codingツールを使ってコードを書く方法を学びました。毎回の対話で新しいバージョンのコードが作成されます。しかし、一つ考えてみましょう:以前の修正に戻りたい場合、便利な方法はあるでしょうか?異なる段階のコードを記録し、いつでも異なるバージョン間で切り替えや修正ができるツールはあるでしょうか? + +このニーズを満たすために、バージョン管理ソフトウェアが誕生しました。本記事では、最も有名なバージョン管理プログラム——Git——と、最も優れたコードホスティングプラットフォーム——GitHub——を紹介します。Gitを使ったコード管理、GitHubから他人のコードの取得、自分のコードのアップロード、そして他の人との協業による大規模プロジェクトの進め方を学びます。 + +個人プロジェクトのバージョン追跡、チーム協業でのコード同期、オープンソースコミュニティへの貢献のいずれにおいても、GitとGitHubはモダンな開発者にとって必須のツールです。これらをマスターすることで、コードをより効率的に管理し、必要に応じてチェックポイントを作成し、コードの異なる段階間を自由に切り替え、単一ファイルの変更から大規模プロジェクトの開発まで、すべてを簡単に処理できるようになります——コードの毎回のイテレーションを管理可能かつトレース可能にします。 + +> 💡 **前提知識** +> +> Gitを学ぶ前に、以下の概念を先に理解しておくことをお勧めします: +> - [ターミナル/コマンドラインとは](/ja-jp/appendix/2-development-tools/command-line-shell) - コマンドラインを使ったコンピュータとのやり取りを学ぶ +> - [Gitとは](/ja-jp/appendix/2-development-tools/git-version-control) - Gitバージョン管理システムの核心概念を理解 +> +> 本記事ではGitHubワークフローと実際の操作に焦点を当て、上記の基礎知識については付録のリンクを参照してください。 + +# Gitクイックスタート + +Gitを使い始める前に、付録の[コマンドライン](/ja-jp/appendix/2-development-tools/command-line-shell)と[Git基礎](/ja-jp/appendix/2-development-tools/git-version-control)の内容をすでに読んでいることを確認してください。本記事はこれらの基礎知識があることを前提に、Gitのインストール・設定とGitHubを使った協業の方法を直接説明します。 + +## Gitのインストール方法 + +異なるコンピュータのオペレーティングシステムにGitをインストールする3つの方法をデモします。自分のシステムバージョンに応じて手順に従ってください: + +### Windows + +1. [Git公式ダウンロードページ](https://git-scm.com/download/win)にアクセスし、自分のシステムに合ったインストーラーをダウンロード:[インストーラー](https://github.com/git-for-windows/git/releases/download/v2.51.0.windows.1/Git-2.51.0-64-bit.exe)。デフォルトではx64インストーラーの使用を推奨。 +2. インストーラーをダブルクリックし、インストールウィザードの指示に従う: + ![](/zh-cn/stage-2/backend/git-workflow/images/image5.png) + 1. デフォルトのオプションを維持することをお勧めします。カスタマイズが必要な場合は以下に注意:(ほとんどの場合、「Next」をクリックし続ければ問題ありません) + - Gitが使用するデフォルトエディタを選択:お好みのエディタ(例:VS Code)を選択。最初のオプションであるVim(テキストエディタ)をデフォルトとして選択するか、「Visual Studio Code as Git's default editor」オプション(VS Codeの事前インストールが必要)を選択できます。デフォルトのまま「Next」をクリックして続行できます。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image6.png) + - Gitの使用方法を選択:これら3つのオプションは、システム内でのGitのアクセシビリティを制御します。オプション2("from command line and 3rd-party software")の選択をお勧めします——基本的なGitツールをPATHに追加し、Git Bash、コマンドプロンプト、PowerShell、IDEでGitを使用できるようにしますが、システムを汚しません。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image7.png) + +3. インストール後、デスクトップで右クリック。メニューに「Git Bash Here」が表示されていれば、インストール成功です。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image8.png) + +### MacOS + +macOSの場合、まずターミナルで`git --version`と入力して、Gitがすでにインストールされているか確認できます。インストールされていない場合、インストールを促すメッセージが表示されます——指示に従ってインストールを完了してください。 + +1. 方法1:Homebrewでインストール + [Homebrew](https://brew.sh/)(Macパッケージマネージャー)がインストールされている場合、ターミナルを開いて以下を入力 + ```bash + brew install git + ``` +2. 方法2:(推奨)Xcodeでインストール: https://developer.apple.com/xcode/ 、XcodeにはGitが内蔵されています。インストール後、指示に従って続行してください。 + +### Linux + +ほとんどのLinuxディストリビューションはパッケージマネージャーでGitをインストールできます: + +- Ubuntu/Debian: + +```bash +sudo apt update +sudo apt install git +``` + +- CentOS/RHEL: + +```bash +sudo yum install git +``` + +- インストールの確認:ターミナルでgit --versionと入力。バージョン番号が表示されればインストール成功です。 + +## Gitの初期化 + +Gitをインストールした後、まずユーザー情報を設定する必要があります——これはGitを使ったバージョン管理の基本ステップです。ターミナルで以下のコマンドを実行してください(括弧内の内容は自分の情報に置き換えてください): + +```bash +# グローバルユーザー名を設定(コミット記録に表示される) +git config --global user.name "Your Name" + +# グローバルメールアドレスを設定(GitHub/GitLabなどのプラットフォームで登録したメールアドレスの使用を推奨) +git config --global user.email "your.email@example.com" +``` + +Gitはこの情報を各コミット記録に組み込み、毎回の修正の「作者情報」として使用します。バージョン履歴(例:git logを使用)を確認する際、誰がどの行のコードを修正したかが明確にわかり、責任の追跡とコミュニケーションに便利です。協業プロジェクトでは、統一されたID情報により、チームメンバーが誰がどの変更を行ったかを迅速に特定でき、協業効率が向上します(例:コミット記録から関連する開発者を見つけて問題を議論するなど)。 + +コマンドラインで`git config --list`と入力することで、現在のGit設定情報を確認し、設定が成功したか確認できます。 + +# GitHubとは + +GitHubはGitベースのコードホスティングプラットフォームです。Gitリポジトリのリモートストレージを提供するだけでなく、協業ツール(Issues、Pull Requests、Projectsなど)も含み、開発者がコードを共有し協業しやすくします。簡単に言えば、Gitはローカルバージョン管理ツールであり、GitHubはリモートの「コードリポジトリクラウド + 協業コミュニティ」です。 + +GitHubは世界最大のコードホスティングプラットフォームであるだけでなく、世界で最も活発で影響力のあるオープンソースコミュニティです。ここでの「オープンソース」の核心的な考え方は、誰でもソフトウェアのソースコードをダウンロードして実行できるということです。このモデルにより、世界中の人々が互いのコードを検査して修正したり、それに基づいて新しいプロジェクトを作成したりできます。例えば、GitHubで各種学習チュートリアルや、GPTモデルのトレーニングに使用されるフレームワーク(PyTorchなど)の完全なソースコードを見つけることができます。毎日、世界中で無数の人がコードをレビューし改善するために協業しています。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image9.png) + +多くの大企業がGitHubでプログラムやチュートリアルをオープンソース化し、業界での競争優位性を得ています——これは一種の広告形態とも言えます。GitHubコミュニティでは、プロジェクトが獲得した「スター(stars)」の数がその価値を測る主な指標であり、プロジェクトや組織が持つスターが多いほど、その信頼性と影響力が大きくなります。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image10.png) + +本コースでは、サポートリソースや課題も専用のGitHubリポジトリにアップロードされます。課題のアップロードプロセスを通じて、GitHubの使用に徐々に慣れ親しみマスターし、将来のアプリケーション開発におけるバージョン管理の基盤を築きます。 + +## GitHubアカウントの登録 + +1. [GitHub公式サイト](https://github.com/)にアクセスし、右上の「Sign up」をクリック。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image11.png) +2. メールアドレスを入力(検証や通知がそこに送信されるため、常用メールの使用を推奨)、パスワードを設定(文字、数字、特殊文字を含める必要があります)。 +3. 人工検証を完了し、指示に従ってメールを検証すれば、アカウントの作成完了です。 + +## GitHubで最初のリポジトリを作成 + +次に、最初の保存フォルダー、すなわちリポジトリまたは「repo」を作成します。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image12.png)![](/zh-cn/stage-2/backend/git-workflow/images/image13.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image14.png) + +1. Repository name:他人に表示されるリポジトリ名。 +2. Description:リポジトリの詳細な説明。 +3. Choose visibility:個人リポジトリの場合、privateに設定すると、自分と特別に招待された人のみが閲覧可能。publicに設定すると、誰でも閲覧可能。 + 組織内のリポジトリの場合、Privateにすると組織内の人のみが閲覧可能。 + Publicにすると組織外の人も閲覧可能。 +4. README:一般的に、すべてのリポジトリにREADMEファイルがあることが推奨されます。これはリポジトリの完全な紹介と考えられ、使用説明、ファイルリスト、操作方法などが含まれます。 +5. Add .gitignore and license: + 1. .gitignoreファイルは、GitにGitHubへのアップロード時に特定のフォルダやファイルを無視するよう指示し、それらが追跡やステージングエリアに追加されないようにします。これは一時テストファイル、依存パッケージ、大きなファイルに便利です。指定すると、これらのファイルは追跡されなくなります。 + 2. licenseは、選択するオープンソースライセンスのタイプを指します。異なるライセンスは、他人があなたのコードを商用目的で使用できるかどうかなどを詳細に規定し、他の条項や条件も含みます。 + +「Add README」にチェックを入れ、リポジトリの可視性を「Private」に設定し、リポジトリ名と説明をお好みで入力してから「Create repository」をクリックして最初のリモートリポジトリの作成を完了することをお勧めします。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image15.png) + +その後、余分なファイルのないクリーンなリポジトリが手に入ります。次にファイルのアップロードを始められます。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image16.png) + +リポジトリを取得するコマンドは`git clone`ですが、リポジトリのアドレスが必要です。緑色の「Code」ボタンをクリックしてリポジトリのアドレスを見つけられます。HTTPSとSSHのオプションが表示されます。通常、どちらの方法でもリポジトリをローカルマシンにダウンロードできます(そうして初めてファイルの修正とアップロードが可能になります)。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image17.png) + +一般的に、HTTPでクローンしたリポジトリは他人のリポジトリを一時的にダウンロードしてテストするのに適していますが、自分の開発にはお勧めしません。より良い学習体験のために、まずSSH認証を設定してください。 + +## ローカルSSHのバインド + +GitHubにおける「SSHプロトコルバインド」とは、本質的にローカルデバイスのSSH公開鍵をGitHubアカウントに関連付け、GitHubがSSHプロトコルを通じてデバイスを識別できるようにすることです。これにより、パスワードなしでリモートリポジトリを安全に操作(clone、push、pullコードなど)できるようになります。 + +簡単に言えば:これはデバイスに「GitHub専用のセキュリティカード」を与えるようなものです。バインド後、デバイスがSSHプロトコルでGitHubリポジトリにアクセスする際、GitHubはこの「セキュリティカード」(あなたのSSH公開鍵)を検証します。あなたの認可されたデバイスであることが確認されれば、直接操作できます——毎回アカウントのパスワードを入力する必要はありません。 + +> 💡 SSHとは + +### なぜSSHプロトコルのバインドが必要なのか? + +GitHubは主に2つのリポジトリ操作プロトコルをサポートしています:HTTPSプロトコルとSSHプロトコル: + +- HTTPSプロトコル:毎回の操作(pushなど)でGitHubのアカウントパスワード(またはPersonal Access Token)の入力が必要。検証プロセスが煩雑で、パスワード漏洩のリスクもあります。 +- SSHプロトコル:認証は「鍵ペア」で完了するため、パスワードの繰り返し入力が不要で、暗号化転送もより安全です。 + +「SSHプロトコルバインド」はGitHubのSSH認証を有効にするための前提ステップです——ローカルのSSH公開鍵をGitHubアカウントに「バインド」して初めて、GitHubはあなたのデバイスを識別し、リポジトリのSSH操作を許可します。 + +### 「バインド」の核心的なロジック:SSH鍵ペアの役割 + +SSH認証は鍵ペア(公開鍵 + 秘密鍵)に依存しており、これらは一致する暗号化ファイルです。生成後、「公開鍵」をGitHubに提供(「バインド」)し、「秘密鍵」はローカルデバイスに残します: + +1. 秘密鍵:ローカルデバイス(PCなど)の指定されたディレクトリ(通常は~/.ssh/)に保存され、「あなた専用の鍵」として機能し、誰とも共有してはいけません。 +2. 公開鍵:これは公開して共有できる「鍵」です——GitHubアカウントの「SSH keys list」にコピー(「バインド」操作)する必要があります。 + +SSHでGitHubリポジトリを操作する際(例:git push git@github.com:xxx/xxx.git): + +- ローカルデバイスが秘密鍵を使って「操作リクエスト」を暗号化しGitHubに送信; +- リクエストを受信したGitHubは、以前にバインドした公開鍵を使って復号を試みる; +- 復号が成功すれば、デバイスは認可されたものとして確認され、操作が許可される。そうでない場合、アクセスは拒否されます。 + +### 「バインド」の具体的な手順(核心的なフロー) + +原理を理解すれば、実際の操作はシンプルです——核心は「鍵ペアの生成 → 公開鍵のGitHubへのアップロード」です: + +1. ローカルでSSH鍵ペアを生成 + 1. Traeを使って公開鍵を取得(推奨) + プロンプト:`Help me create the SSH key needed for GitHub login. My email is your_email@gmail.com , Please return the public key for me to copy` + + ![](/zh-cn/stage-2/backend/git-workflow/images/image18.png) + + プロンプトを入力した後、左側のターミナルでEnterキーを押す必要があります。そうしないとコマンドが待機状態のままになります。Traeは条件判断を実行できないため、ひたすらEnterを押し続けるだけで問題ありません。 + + 最終的に、右側のTraeが読み取った公開鍵が返されます。それをコピーし、次のステップで貼り付ける準備をしてください。 + + ![](/zh-cn/stage-2/backend/git-workflow/images/image19.png) 2. 手動で公開鍵を取得 + ローカルのターミナルを開き(WindowsではGit BashまたはPowerShell、macOS/Linuxではターミナル)、以下のコマンドを入力(your_email@example.comをGitHubアカウント登録時に使用したメールアドレスに置き換えてください): + + ```bash + ssh-keygen -t ed25519 -C "your_email@example.com" + ``` + + 1. Enterを押してデフォルト値を受け入れる(デフォルトのファイルパス、パスワードなし、または必要に応じてパスワードを設定)。これで~/.ssh/ディレクトリに2つのファイルが生成されます: + - id_ed25519:秘密鍵(ローカルに保存、**絶対に共有しない**); + - id_ed25519.pub:公開鍵(GitHubにアップロードが必要)。 + +2. 公開鍵をGitHubアカウントに「バインド」 + +これが核心的なバインドステップです——ローカルの公開鍵をGitHubアカウントの「SSH keys list」に追加: + +1. 公開鍵の内容をコピー: + 1. Trae: + 2. Windows:メモ帳でC:\Users\\.ssh\id_ed25519.pubを開き、全内容をコピー; + 3. macOS/Linux:ターミナルでcat ~/.ssh/id_ed25519.pubを実行し、全出力をコピー(先頭のSSH-ed25519から末尾のメールアドレスまで)。 +2. GitHubにログインし「SSH Key Management」ページに進む: + 1. 右上のアバターをクリック → Settings → 左側のメニューSSH and GPG keys → New SSH keyをクリック。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image20.png)![](/zh-cn/stage-2/backend/git-workflow/images/image21.png) + 2. 任意のタイトルを入力(例:your local computer's SSH)し、取得したSSH公開鍵をここに貼り付け。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image22.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image23.png) + +3. バインドの成功を確認 + +ターミナルで以下のコマンドを入力(**Traeでも以下の操作が可能**)して、GitHubがデバイスを識別できるかテスト: + +```bash +ssh -T git@github.com +``` + +- Hi [your GitHub username]! You've successfully authenticated...のような内容が表示されれば、鍵のバインドは成功; +- エラーが発生した場合、通常は公開鍵のコピーが不完全、秘密鍵の権限が高すぎる(ローカルの~/.ssh/ディレクトリは自分のみが読み書き可能にすべき)などが原因です。必要に応じてこれらの問題を確認してください。 + +### 重要な注意事項 + +複数のデバイス(ノートPCやデスクトップなど)を持っている場合、各デバイスに対して個別のSSH鍵ペアを生成し、各公開鍵を同じGitHubアカウントにバインドする必要があります——各デバイスには独自の「セキュリティカード」があります。 + +秘密鍵を共有しないでください(GitHubにアップロードしたり他人と共有しない)。そうしないと、誰かがあなたになりすましてリポジトリを操作する可能性があります。秘密鍵が漏洩した場合は、GitHubから対応する公開鍵を直ちに削除し、新しい鍵ペアを生成してください。 + +SSHをバインドした後、操作にはSSH形式のリポジトリアドレス(例:git@github.com:username/repository.git)を使用し、HTTPS形式(例:https://github.com/username/repository.git)は使用しないでください。以前にHTTPSでリポジトリをクローンした場合は、git remote set-url origin ``でプロトコルを切り替えられます。 + +# TraeでGitHub操作を行う + +Gitとは何か、GitHubとは何か、SSHとは何か、そしてその設定方法について説明しました。これでTraeを使って自由にGit操作を行えます。まず、リモートリポジトリをローカルマシンにクローンする方法を学びましょう。 + +## Git clone:既存のリポジトリをダウンロード + +クローンしたいリポジトリのアドレスを直接伝えることができます + +![](/zh-cn/stage-2/backend/git-workflow/images/image24.png) + +## Git pull:リモートリポジトリから更新を取得 + +リポジトリを更新する前に、複数人でメンテナンスされている可能性があるため、まず最新の変更をプルする必要があります。その後、ファイルを修正してプッシュできます。 + +**間違ったリポジトリにプッシュしないよう、フォルダ名とその相対パスまたは絶対パスを必ず含めてください。** + +prompt:`Help me pull this repository AIID-TEST in ./AIID-TEST.` + +## Git commit & Git push:更新をステージしてGitHubにプッシュ + +すべての準備が整ったら、ローカルファイルの修正、フォルダ内のアイテムの追加や削除を試みてください。その後、Traeに変更を検出させ、GitHubへのプッシュを支援させます。 + +prompt:`I finished. Commit and push to the repository AIID-TEST in ./AIID-TEST.` + +![](/zh-cn/stage-2/backend/git-workflow/images/image25.png) + +プッシュ成功。これでGitHubで更新された内容を確認できます。 + +# 参考資料 + +- Pro Git book https://git-scm.com/book/en/v2 +- GitHub Docs https://docs.github.com/en diff --git a/docs/ja-jp/stage-2/backend/modern-cli/index.md b/docs/ja-jp/stage-2/backend/modern-cli/index.md new file mode 100644 index 0000000..406babd --- /dev/null +++ b/docs/ja-jp/stage-2/backend/modern-cli/index.md @@ -0,0 +1,801 @@ +# CLI AI プログラミングツール + +本チュートリアルでは、コマンドライン上で直接動作する AI プログラミング Agent を紹介します。これまで学んだ Trae や Cursor に組み込まれた Agent とは異なり、CLI AI プログラミングツールはターミナル上でのみ使用します。AI IDE 内蔵の Agent と比べて、より長いコンテキストウィンドウ、より高速なツール呼び出し、そしてより多くの種類の大規模モデルとの互換性を備えています。最新の AI Vibe Coding の実践では、IDE 内蔵のコーディング Agent よりも CLI AI プログラミングツールを優先して使用することが多くなっています。 + +## CLI とは + +以前のチュートリアルで CLI について紹介しましたね。CLI とは、ターミナルやコマンドプロンプトを通じて、グラフィカルインターフェース(GUI——ボタンがあってクリック操作ができる、コマンドを入力する必要のない画面と理解して構いません)に頼らず、純粋なテキストコマンドでソフトウェアを操作する仕組みです。 + +> Windows では、代表的なターミナルとして「コマンドプロンプト(cmd)」と「PowerShell」があります。PC の「ファイル名を指定して実行」や検索ボックスに「cmd」または「powershell」と入力することで、これらのコマンドラインプログラムを起動できます。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image1.png)![](/zh-cn/stage-2/backend/modern-cli/images/image2.png) + +CLI は元来テキストコマンドの操作に適しており、一部のギーク(極限まで追求するプログラミング愛好家)の間では、CLI の方が GUI よりも好まれることすらあります——彼らはすべての操作をキーボードで完了させたいと考えており、マウスを使うとかえってコーディング効率が下がると感じています。 + +業界においても、CLI は最も一般的なインターフェース形式の一つです。なぜなら、GUI は OS に追加で画面を描画し、ウィンドウを管理する必要があるため、コンピュータリソースの要求が高くなります。一方 CLI は、受け取ったコマンドをシステムに渡して実行するだけで済みます。そのため、大規模なサーバークラスタに接続する際、通常は CLI でのみやり取りを行います。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image3.png) + +CLI の経験がない方にとっては、CLI の操作は複雑でコマンドが多すぎると感じたり、「間違えたら PC が壊れてしまうのではないか」と心配したりするかもしれません。心配は不要です。以前のチュートリアルで、Trae に様々な基本操作を手伝ってもらったことを思い出してください。ここでも全く同じ考え方が使えます——CLI プログラミングツールにすべての CLI 操作を代行させることができます。指定したフォルダへの移動、ファイルの検索や処理、オープンソースプロジェクトの実行やコピーなどを、すべて CLI AI プログラミングツールとの対話を通じて完了できます。 + +## AI IDE との違い + +CLI AI プログラミングツールは、以前学んだ z.ai や Trae に例えることができます。ある意味で、CLI AI プログラミングツールは特殊な z.ai と見なすことができます。どちらもシンプルな対話の入口だけで、必要なすべての操作を自動的に実行してくれます(ただし、最終的な結果を確認するために手動でブラウザを開く必要がある場合があります)。また、AI IDE に例えるなら、CLI AI プログラミングツールは IDE 内の Agent モジュール——つまり、サイドバーにある対話エリアに相当します。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image4.png)![](/zh-cn/stage-2/backend/modern-cli/images/image5.png) + +ただし、AI IDE によって Agent の実装方法が異なり、能力差も大きいため、AI プログラミングの効果は安定しにくい傾向があります。そのため、CLI AI プログラミングツールは通常、Claude を開発した Anthropic や ChatGPT を開発した OpenAI などの大手テック企業によって直接開発されています。 + +他の AI プログラミング Agent と比べ、これらの大企業製品を直接利用する方が優れた実践となることが多いです。特に Claude Code は、もともと Anthropic の内部開発チーム向けのツールであり、「エンジニアの実際のニーズを満たす」という観点から設計されています。 + +より直感的に比較するため、Claude Code とある AI IDE Agent(ここでは Cursor を例にします)の違いを見てみましょう。 + +| 機能特性 | Claude Code | Cursor | 優位性 | +| ----------------- | ------------- | --------------- | ----------- | +| 自動タスク実行 | ✅ 非常に強い | ❌ 能力限定 | Claude Code | +| IDE 統合 | ❌ コマンドラインのみ | ✅ ネイティブ VS Code | Cursor | +| リアルタイムコード補完 | ❌ なし | ✅ 優れた体験 | Cursor | +| 複数ファイル操作 | ✅ 非常に強い | ⚠️ 悪くない | Claude Code | +| GitHub 統合操作 | ✅ 直接コミット可能 | ⚠️ 手動操作が必要 | Claude Code | +| 学習コスト | ⚠️ 中程度 | ✅ 簡単に始められる | Cursor | +| コンテキスト長 | ✅ 非常に長い | ⚠️ まずまず | Claude Code | +| デバッグ支援 | ✅ 自動化 | ⚠️ 手動作業が多い | Claude Code | + +表の出典: + +端的に言えば、CLI AI プログラミングツールは一般的に以下のことが可能です。 + +- より長時間の連続対話をサポート(「一日中作業」を手伝うことすら可能)。 +- より長いコンテキストウィンドウを提供(「続けて」と頻繁に言う必要がなくなる)。 +- より高速な応答速度(より多くのカスタムモデル API に接続可能)。 + +コーディング関連の操作において、これらは大半の IDE 内蔵 Agent よりも賢く、安定しています。 + +## 代表的な CLI AI プログラミングツール + +現在、多くのオープンソース実装がありますが、実践においては 2 つのタイプの CLI AI プログラミングツールを「おすすめの組み合わせ」としてお勧めします。ご自身の好みに合わせてどちらかを選択してください。両方試した上で、最も適したものを選ぶことを強くお勧めします。 + +- Codex は GPT-5 を使用し、総合力がより高い。 +- Claude Code は GLM 4.6 を経由した API 転送で、全体的な体験は Claude 4 に近いが、価格はより安い。 +- OpenCode はモデルを自由に切り替えて組み合わせることができ、無料モデルも提供されており、コストをより良くコントロールできる。 + +ただし、実際のプロジェクトでどれが使いやすいかは、実際に試してみなければ判断できません。複数の AI プログラミングツールを使いこなすことは常に有益です。慣れてくれば、場面に応じて Claude Code、Codex、Trae を柔軟に切り替えることができます。あるツールの効果がいま一つだと感じたら、別のツールやモデルに切り替えて試行を続ければよいのです。 + +また、モデルのバージョンアップは非常に速いため、「コストパフォーマンス(効果 / コスト)」の面で最も優れた方案を優先して選ぶことをお勧めします。 + +### Claude Code + +Claude Code は、Anthropic が Claude 大規模モデルの能力を基に開発した AI プログラミングツールです。主な利用シーンはターミナルですが、VS Code の拡張機能としても使用できます。AI IDE の Agent と同様に、開発者のコードリポジトリを深く理解し、自然言語の指示によりエンドツーエンドの開発タスクを完了できます。コードの編集、バグ修正、テストの実行と修正、Git ワークフローの管理(マージコンフリクトの解決や PR の作成など)、複雑なコードの解説、ターミナルコマンドの実行などが含まれます。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image6.png) + +Claude Code の強みは主に以下の点にあります。極めて長いコンテキストウィンドウ(ファイル全体や小規模プロジェクトの処理が可能)、曖昧な要件を自ら確認し、タスクを自動的に計画・分配する能力、そしてコードベース全体の内容を深く理解し説明する能力です。一般的な IDE Agent と比べ、「没入型 vibe coding」の開発プロセスにより適しています。 + +実際の使用では、対話による指示を通じて、新しいプロジェクトの作成、CLI 操作の実行(フォルダの整理、ファイルの一括リネーム、オープンソースプロジェクトのデプロイなど)、開発環境の構築(Python 環境のインストールやデバッグなど)を依頼できます。あるコードが理解しにくい場合や、ディレクトリ構造が不明確な場合も、Claude Code に構造化された分析ドキュメントを生成させたり、特定の内容をステップごとに解説させたりすることができます。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image7.png)![](/zh-cn/stage-2/backend/modern-cli/images/image8.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image9.png)![](/zh-cn/stage-2/backend/modern-cli/images/image10.png) + +Claude Code を体系的に学びたい場合は、Andrew Ng と Anthropic が共同で提供しているコースを参照してください。 + + +それでは、Claude Code の使い方を学びましょう。公式の Claude Code を直接使用するとコストが非常に高くなるため(下図参照)、Claude Code のプロトコルと互換性がありながら、他の大規模モデルの API プラットフォームを基にした方案を使用します。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image11.png) + +以下のいくつかの異なる方案を学ぶ必要があります(できればすべて試してください)。最後に、最も適したものをメインの実践パスとして選んでください。 + +1つ目の方法は、「Anthropic インターフェース互換」の API を直接使用することです。Claude Code の普及に伴い、越来越多の大規模モデルサービス事業者が Anthropic 形式の呼び出し方法をサポートし始めています。代表的なサービス事業者には GLM、Kimi、DeepSeek、Siliconflow などがあり、いずれも互換 API インターフェースを提供しています。具体的な設定については後で詳しく説明します。 + +なお、Claude Code は通常大量のトークンを消費するため、API 呼び出しによる高額な費用を懸念される場合は、GLM の月額プラン(約 20 元/月)の購入を検討するとコストを抑えられます。実際の使用料を先に確認したい場合は、10 元をチャージして小規模なテストを行うのも良いでしょう。 + +もう1つの方法は、「Claude Code Router」プロジェクトを使用することです。これはオープンソースツールであり、一般的なすべての API 呼び出しインターフェースをサポートするだけでなく、場面に応じて使用するモデルをきめ細かく設定でき、ローカルにデプロイされた大規模モデルとの接続も可能です。ただし、この方案の設定は比較的複雑なため、まずは1つ目の方案から始めることをお勧めします。 + +#### 智譜 GLM をバックエンドとして使用する(推奨) + +GLM(General Language Model)は、智譜 AI が独自に開発した大型言語モデルシリーズです。GLM-4.6 は現在の GLM シリーズの最新バージョンであり、コード能力における優れたパフォーマンスが最大のハイライトです(公開ベンチマークと実際のタスクにおいて Claude Sonnet 4 と同等レベルであり、国内ではトップクラスに位置しています)。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image12.png) + +また、コンテキストウィンドウを 200K に拡張し、長文や大規模なコードをより余裕を持って処理できるようになりました。推論とツール呼び出しの能力も強化され、パフォーマンスとコストのバランスも良好です。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image13.png) + +GLM に接続する前に、まず Claude Code をインストールする必要があります。 + +コマンドラインでのインストール手順が煩わしいと感じる場合や、途中でエラーが発生した場合は、Trae の Agent にインストールを手伝わせることができます。 + +```python +# Claude Code のインストール +npm install -g @anthropic-ai/claude-code + +# プロジェクトに移動 +cd your-awesome-project + +# Claude Code の起動 +claude + +# Ctrl+C で Claude を終了 +``` + +次に、Claude Code のデフォルトの API リクエスト先を変更し、GLM の API サービスに対応させる必要があります。以下の内容をコピーして、Trae に対応する環境変数の作成を依頼できます。または、システム環境変数に永続的に書き込むことも選択できます(問題が発生した場合も、Agent に修正を依頼できます)。 + +まず、GLM の API Key を取得し、ご自身にとって最も便利な方法で保管してください。 + +国内版 URL: +国際版 URL: + +**国内版 GLM** を使用する場合は、以下の環境変数を設定してください。 + +```python +# Cmd で以下のコマンドを実行 +# `your_zhipu_api_key` を取得した API Key に置き換えてください +setx ANTHROPIC_AUTH_TOKEN your_zhipu_api_key +setx ANTHROPIC_BASE_URL https://open.bigmodel.cn/api/anthropic +``` + +**国際版 GLM** を使用する場合は、以下の設定を使用してください。 + +```python +# Cmd で以下のコマンドを実行 +# `your_zai_api_key` も必ず置き換えてください +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic +``` + +Trae で以下のようなプロンプトを直接入力できます。 + +> **注意**:Trae を通じて「永続的な環境変数」を設定した場合、設定完了後に **必ず Trae を再起動してください**。再起動しないと、内蔵ターミナルの環境変数が更新されず、ログイン失敗やネットワーク接続エラーが発生する可能性があります。 + +```python +Based on my environment variable settings: +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic + +and my key(Replace it with your own key): +681fea485851d29060cc.13gfaendggaFOhb + +please help me configure and start Claude Code +``` + +以下のような出力が表示されます。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image14.png) + +> **環境変数とは?** +> +> 環境変数は、本質的にはオペレーティングシステムに保存される「キーと値のペア」の設定情報であり、通常「変数名 = 具体的な値」という形式で存在します。ターミナルやシステム設定であらかじめ設定しておけば、プログラムはいつでもこれらの変数を読み取って関連情報を取得できます。環境変数はターミナルから直接書き込めるため、コード自体を変更する必要がありません。そのため、大規模モデルにアクセスするためのシークレットキーは、漏洩を防ぐために環境変数に保存するのが一般的です。プログラムは対応する環境変数を読み取るだけで、大規模モデルの呼び出しを完了できます。 +> +> Windows システムでは、環境変数は大規模モデルのアクセスキーの保存以外にも、コマンドラインツールの「呼び出しパス」の保存によく使われます。 +> +> ターミナル自体もプログラムです。ターミナルで外部プログラムを起動したい場合、例えばターミナルで `claude` と入力して Claude Code を起動するケースを考えます。`claude` と入力するだけで実行できるのは、ターミナルがシステムの環境変数を読み取り、その中の PATH 変数に Claude Code の実行ファイルが含まれるディレクトリが登録されているため、ターミナルが該当プログラムを見つけて実行できるからです(ターミナルにそのプログラムの絶対パスを貼り付けて Enter を押すのと同じです)。 +> +> 代表的な環境変数は例えば `PATH=C:\Windows\system32;C:\Program Files\Python` のようになります。これにより、どのパスからでもシステム内のこれらのプログラムを実行できます。例えば、コマンドラインで直接 `python` と入力して Python インタープリタを起動できます。 +> +> システムの現在の環境変数を確認したい場合は、Windows の検索で「環境変数」と入力し、「システム環境変数の編集」ウィンドウを開くと、すべての変数とその値が表示されます。一部の変数は大規模モデルのキーの保存に、一部はプログラムディレクトリの追加に使用されており、どのパスからでも呼び出せるようになっています。 + +これで、最新の GLM を使用した Claude Code 開発が可能になりました。以前のプロジェクトをもう一度実行したり、Trae ではうまく完了できなかったタスクに再挑戦したりして、体験の違いを比較してみてください。 + +何度も「やり直す」ことは時間の無駄ではありません——やり直すたびに、スキルはより確かなものになります。 + +GLM と全く同じ考え方で、Anthropic 互換形式をサポートする他のインターフェースにも簡単に接続できます。 + +#### Kimi K2 をバックエンドとして使用する(推奨) + +Kimi K2 は月之暗面(Moonshot AI)が発表した次世代の大規模言語モデルであり、コードの理解と生成能力に優れています。Kimi K2 は超長コンテキストウィンドウ(最大 200K トークン)をサポートし、大規模なコードベースや複雑なプロジェクトを容易に処理できます。 + +**主な強み:** + +- **超長コンテキスト**:200K コンテキストウィンドウをサポートし、プロジェクト全体のコードを一度に処理可能 +- **強力なコード能力**:コード生成、リファクタリング、デバッグにおいて優れたパフォーマンス +- **中国語理解に優れる**:中国語のプログラミング要件の理解がより正確 +- **安定したツール呼び出し**:安定した関数呼び出しとツール使用をサポート + +**API Key の取得:** + + にアクセスして登録し、API Key を取得してください。 + +**設定方法:** + +参考ドキュメント: + +```bash +export ANTHROPIC_BASE_URL=https://api.moonshot.cn/anthropic +export ANTHROPIC_AUTH_TOKEN=sk-YOURKEY +``` + +#### Minimax をバックエンドとして使用する(推奨) + +Minimax は稀宇科技(MiniMax)が発表した次世代の大規模言語モデルであり、プログラミングタスクにおいて優れたパフォーマンスを発揮します。Minimax モデルは、優れた推論能力とコード生成品質で知られており、特に複雑なプログラミングシナリオに適しています。 + +**主な強み:** + +- **強力な推論能力**:複雑な論理推論とコードアーキテクチャ設計において優れたパフォーマンス +- **高品質なコード**:生成されるコードは構造が明確で読みやすい +- **多言語サポート**:複数のプログラミング言語のコード生成と変換をサポート +- **高速な応答**:API の応答速度が速く、高頻度呼び出しのシナリオに適している + +**API Key の取得:** + + にアクセスして登録し、API Key を取得してください。 + +**設定方法:** + +```bash +export ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_MINIMAX_API_KEY +export ANTHROPIC_MODEL=MiniMax-M2.7 +``` + +#### DeepSeek をバックエンドとして使用する(推奨) + +DeepSeek は深度求索が発表したオープンソースの大規模言語モデルであり、優れたコード能力と高いコストパフォーマンスで開発者に支持されています。DeepSeek Coder はプログラミングタスク向けに特化して最適化された学習が行われています。 + +**主な強み:** + +- **優れたコード能力**:コード生成、コード理解、バグ修正において優れたパフォーマンス +- **オープンソースでカスタマイズ可能**:モデルがオープンソースであり、要件に応じてファインチューニングが可能 +- **高いコストパフォーマンス**:API 価格が比較的低く、高頻度での利用に適している +- **中国語サポートが良好**:中国語のプログラミングシナリオの理解が正確 + +**API Key の取得:** + + にアクセスして登録し、API Key を取得してください。 + +**設定方法:** + +```bash +export ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic +export ANTHROPIC_AUTH_TOKEN=YOU_DEEPSEEK_API_KEY +export API_TIMEOUT_MS=600000 +export ANTHROPIC_MODEL=deepseek-chat +export ANTHROPIC_SMALL_FAST_MODEL=deepseek-chat +export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 +``` + +#### 火山引擎 Coding Plan をバックエンドとして使用する(推奨) + +火山引擎(Volcano Engine)は字節跳動(ByteDance)傘下のクラウドサービスプラットフォームで、エンタープライズグレードの AI モデルサービスを提供しています。火山引擎の Coding Plan はプログラミングシナリオ向けに特化して最適化されており、安定した効率的なコード生成能力を提供します。 + +**主な強み:** + +- **エンタープライズグレードの安定性**:サービスレベル契約(SLA)を提供し、サービスの安定性を保証 +- **コードシナリオの最適化**:プログラミングタスク向けに特化して最適化 +- **豊富なモデル選択**:Doubao-pro、Doubao-lite など複数のモデルをサポート +- **国内からの高速アクセス**:国内ノードにデプロイされており、アクセス速度が速い + +**API Key の取得:** + + にアクセスして登録し、API Key を取得してください。 + +**設定方法:** + +```bash +export ANTHROPIC_BASE_URL=https://ark.volces.com/api/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_VOLCANO_API_KEY +export ANTHROPIC_MODEL=doubao-pro-32k +``` + +#### その他の Anthropic 互換 API + +Siliconflow: + +```bash +export ANTHROPIC_BASE_URL="https://api.siliconflow.cn/" +export ANTHROPIC_MODEL="moonshotai/Kimi-K2-Instruct-0905" # 必要なモデルに変更可能 +export ANTHROPIC_API_KEY="YOUR_SILICONCLOUD_API_KEY" # API Key を置き換えてください +``` + +阿里雲 DashScope(Aliyuncs): + +```python +export ANTHROPIC_BASE_URL="https://dashscope.aliyuncs.com/apps/anthropic" +export ANTHROPIC_API_KEY="YOUR_DASHSCOPE_API_KEY" +``` + +::: details Claude Code Router をバックエンドとして使用する(応用編) + +上記では、GLM 公式 API を使って Claude Code の Anthropic インターフェースを置き換える方法を説明しました。次に、Claude Code Router というツールがどのように Claude Code をより多くのモデル API に適合させるのかを見てみましょう。 + +[Claude Code Router](https://github.com/musistudio/claude-code-router) は、Claude Code 専用に設計されたインテリジェントルーティング拡張ツールです。その主な役割は、ユーザーのニーズに応じて AI リクエストを異なるプラットフォーム上のモデルに振り分け、高度なカスタマイズを可能にすることです。OpenRouter、DeepSeek、Ollama、Gemini など数十のプラットフォームへの接続をサポートし、シナリオに応じてタスクを特定のモデル(例:GLM-4.5、Kimi-K2、Qwen3-Coder など)にルーティングすることもできます。例えば、バックグラウンドタスクを自動的にローカルの Ollama に任せてコストを節約し、長文や長いコードのタスクを Gemini-2.5-Pro に、コードの解説を DeepSeek に振り分けることができます。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image16.png) + +このツールは、便利な UI/CLI 設定管理機能も提供し、「コンバーター(converter)」を通じて異なるプラットフォームの API 形式に適合させます。GitHub Actions などの自動化統合やカスタム拡張をサポートし、「単一のモデルではすべてのシナリオをカバーできない」問題や「プラットフォームの頻繁な切り替えが面倒」という課題を解決し、ユーザーがより柔軟かつ低コストで AI ツールを活用できるようにします。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image17.png) + +Claude Code Router のインストール方法を簡単に説明します。大まかに以下のステップが必要です(これも Trae に実行させることができます)。 + +```markdown +npm install -g @anthropic-ai/claude-code +npm install -g @musistudio/claude-code-router +``` + +インストール完了後、ローカルで `ccr` コマンドが使用できることを確認してください。以下のような出力が表示されれば、インストールは成功しています。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image18.png) + +次に、モデルの初期化と設定には 2 つの方法があります。 + +- CCR 内蔵の UI を使用し、ブラウザで提供される設定ページから操作する。 +- CCR のデフォルト設定ファイルを直接編集する(UI も本質的には設定ファイルを変更しているだけで、より直感的なインターフェースを提供しています)。 + +CCR UI を使用する場合、以下のような画面が表示されます。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image19.png) + +「Add Provider」ボタンをクリックすると、以下の画面が表示されます。以下の操作が必要です。 + +1. Name にモデルプロバイダーの名前を入力。 +2. API Full URL にそのプロバイダーの OpenAI 互換インターフェースのアドレスを入力。 +3. API Key に対応するプラットフォームの API Key を入力。 +4. Models エリアにモデル名を入力し、「Add Model」をクリックして追加。 +5. 最後に「Save」をクリックして設定を保存。 + +(画面を下にスクロールすると多数の詳細オプションがありますが、今は無視して構いません。) + +![](/zh-cn/stage-2/backend/modern-cli/images/image20.png) + +以下は DeepSeek と Kimi の設定例です。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image21.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image22.png) + +モデル設定を保存した後、右側の Router エリアでデフォルトモデル(Default)を指定する必要があります。該当するドロップダウン選択をクリックし、`kimi`(推奨)に設定した後、右上の「Save and Restart」をクリックしてください。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image23.png) + +その後、ターミナルで `ccr code` と入力するだけで、Claude Code Router を通じて Claude Code のコーディングワークフローを起動できます。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image24.png) + +::: + +#### Claude Code の応用的な使い方 + +Claude Code を使い始めたばかりの頃は、単なる対話ツールとして使っている人が多いでしょう。しかし実際には、より効率的で柔軟な使用を可能にする豊富な機能が内蔵されています。以下に、一般的なコマンドと使用例をいくつか紹介します。 + +参考ドキュメント: + + + + +| コマンド | 機能 | 例 | +| ----------------- | ----------------------------------------- | ---------------------------------------- | +| claude | インタラクティブモードの起動 | `claude` | +| claude "query" | 一度限りのタスクを実行し結果を出力 | `claude "explain this project"` | +| claude -p "query" | 一度限りの質問を実行し、終了後に自動的に終了 | `claude -p "explain this function xxxx"` | +| claude -c | 直近のセッションを再開 | `claude -c` | +| claude -r | 前回のセッションを復元 | `claude -r` | +| /resume | 現在のチャットで前回のセッションに切り替え | `claude -c`、`/resume` | +| /plugin | プラグインの管理。コミットやレビュー機能の拡張をインストール可能 | `/plugin` | +| /init | CLAUDE.md でプロジェクト説明を初期化 | `/init` | +| /clear | 現在のセッションのコンテキストをクリアし、情報過多を防止 | `/clear` | +| /compact | セッション履歴を圧縮し、コンテキストのトークン消費を削減 | `/compact` | +| /cost | 現在の利用料金を確認 | `/cost` | +| /model | 使用するモデルを切り替え(互換 API 使用時は基本的に無視可能) | `/model` | +| /memory | CLAUDE.md メモリファイルの管理 | | +| /help | 利用可能なコマンド一覧を表示 | `/help` | +| exit or Ctrl+C | Claude Code を終了 | `exit` または `Ctrl+C` | +| /agents | 高度な機能、後述 | | +| /mcp | 高度な機能、後述 | | + +**CLAUDE.md** + +参考: + +`CLAUDE.md` は、Claude が対話を開始する際に自動的に読み込み、コンテキストに追加する特別なファイルです。そのため、以下の内容を記録するのに非常に適しています。 + +- よく使う bash コマンド +- コアファイルとユーティリティ関数 +- コードスタイルの規約 +- テスト方法の説明 +- リポジトリのコラボレーションルール(ブランチの命名、merge か rebase かなど) +- 開発環境の設定説明(pyenv の使用有無、推奨コンパイラなど) +- プロジェクト内で特に注意すべき動作や落とし穴 +- Claude に「記憶」してほしいあらゆる情報 + +`CLAUDE.md` 自体に強制フォーマットはありません。簡潔で人間が読みやすい形式であれば問題ありません。例えば以下の通りです。 + +``` +# Bash commands +- npm run build: Build the project +- npm run typecheck: Run the typechecker + +# Code style +- Use ES modules (import/export) syntax, not CommonJS (require) +- Destructure imports when possible (eg. import { foo } from 'bar') + +# Workflow +- Be sure to typecheck when you're done making a series of code changes +- Prefer running single tests, and not the whole test suite, for performance +``` + +#### Claude Code の内部仕組み + +参考: + +Claude Code が多くの場面で Trae や Cursor などの Agent プログラミングツールより使いやすい理由に興味がある場合は、その内部の仕組みを簡単に見てみましょう。 + +他の CLI AI プログラミングツールも、全体的な実装方法は概ね同様です。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image25.png) + +Claude Code は、プログラミングタスクを継続的な「知覚—思考—行動—検証」のサイクルに分解し、その中で異なるツールを呼び出してタスクを完了させます。人間の開発者のワークフローを模倣し、「コードを書く→実行する→結果を見る→さらに改善する」を繰り返します。システム内部では、メインタスクのループを通じてステップを継続的に実行し、各サイクルで Claude は異なるツール(ファイルの読み書き、コマンドの実行、コードの検索など)を呼び出し、ツールから返された実際の結果に基づいて次のアクションを決定します。 + +その中で、特に注目すべき特徴がいくつかあります。 + +- **ストリーム処理(Stream Processing)**:Claude は考えながら同時に結果を出力でき、すべてのコードを書き終わるまで待つ必要がありません。 +- **インテリジェント圧縮(Intelligent Compression)**:長い対話はコンテキストが過剰に長くなりやすいため、Claude は履歴を重要な情報に圧縮することで「忘却」の確率を下げ、長期記憶と短期記憶を区別して効率的な動作を保証します。 +- **並行制御(Concurrency Control)**:内部の並列設計により、複数のタスクを同時に実行し、互いに干渉しません。 +- **サブ Agent 管理(Sub-agent Management)**:実際の作業では、単一の「役割」がすべてを処理するわけではありません。複数のサブ Agent を管理してコードを協力して処理でき、各 Agent が異なるタスク(テスト専用、ドキュメント作成専用など)を担当します。 + +### Codex + +![](/zh-cn/stage-2/backend/modern-cli/images/image26.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image27.png) + +Claude Code と同様に、Codex は OpenAI が開発した AI 協力プログラミングツールであり、「OpenAI 版の Claude Code」と理解できます。最大の強みは GPT-5 の効率的な適応です。 + +実際の体験から言うと、GPT-5 は現在レスポンスがより速く、エラー率も低いです(複数回の複雑なタスクにおいて、正しく完了する確率が高い)。一方、欠点として、説明が「学術的」で「技術的」に偏りがちで、時には過度に厳密で情報量が多く、初心者には少し分かりにくいと感じる場合があります。 + +以下のコマンドで Codex をインストールできます。 + +``` +npm i -g @openai/codex +``` + +#### OpenAI 公式 API をバックエンドとして使用する + +OpenAI 公式の Codex エントリポイントを直接使用する場合、設定は非常にシンプルです。OpenAI のサブスクリプションを有効にしているか、対応する API クォータを取得した後、コマンドラインで `codex` と入力してプログラムを起動し、指示に従ってログインを完了するだけです。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image28.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image29.png) + +#### OpenAI API の転送方式をバックエンドとして使用する + +公式の OPENAI API は価格が高く、ネットワーク要件が厳しいなどの問題がある可能性があるため、これらの制限を回避するために、他の API ゲートウェイサービスを通じて呼び出しを転送することもできます。 + +この方式では、サードパーティの転送プラットフォームで対応する Codex API クォータを購入するだけで、ネイティブの OpenAI Codex に近い使用体験を得られます。 + +参考: +チャージ URL: + +なお、トークンクォータを取得した後、ローカルで API Key の設定も行う必要があります。 + +キーグループの設定では、Codex 専用の項目を選択するよう注意してください。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image30.png) + +次に、取得した Key を以下のプロンプトに記入し、プロンプト全体を Trae に渡して、設定プロセス全体を完了させます。 + +````bash +My API key is: [Paste your obtained sk-xxxxx key here] + +Please help me complete the following configuration tasks: + +1. Create configuration directory + - Create a `.codex` folder under my user directory + - Windows path should be: `C:\Users\[My Username]\.codex` +2. Backup existing configuration (if exists) + - Check if `.codex\config.toml` exists + - If it exists, rename it to `config.toml.bak.[current timestamp]` (timestamp format: yyyyMMddHHmmss) +3. Create configuration file + - Create `config.toml` in the `.codex` directory + - Write the following complete content: + ```toml + preferred_auth_method = "apikey" + + [model_providers.myrelay] + name = "My Relay Station" + base_url = "https://api.zyai.online/v1" + env_key = "MYRELAY_API_KEY" + wire_api = "responses" + request_max_retries = 4 + stream_max_retries = 10 + stream_idle_timeout_ms = 300000 + + [profiles.myrelay] + model_provider = "myrelay" + model = "gpt-5" + model_reasoning_effort = "medium" + + [tools] + web_search = true + +4. Set system environment variable +Variable name: MYRELAY_API_KEY +Variable value: The key I gave you + +5. Confirm completion and report back: + +The full path of the configuration file +Whether the environment variable was set successfully +I can use the command `codex --profile myrelay` to run it +```` + +設定が完了すると、`codex --profile myrelay` で転送 API を使用する Codex を起動できます。その後の使い方は Claude Code と同様で、チャットボックスにいつでもアイデアや要望を入力するだけです。 + +### OpenCode + +![](/zh-cn/stage-2/backend/modern-cli/images/image32.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image33.png) + +OpenCode は開発者向けのオープンソース AI Coding Agent プラットフォームであり、「マルチモデル版の Claude Code」という位置づけです。Terminal を主なインタラクションの入口としながら、VS Code、Neovim などのエディタ統合もサポートし、ローカルのコードリポジトリに深くアクセスし、自然言語でコードの理解からエンジニアリングの実行まで、開発プロセス全体を完了できます。 + +単一のモデルに縛られた AI プログラミングツールではなく、GPT、Claude、Gemini からローカルモデルまで自由に切り替えられるオープンな AI Coding Agent プラットフォームです。OpenAI 公式も OpenCode を通じた Codex / OpenAI サブスクリプションへの接続をサポートしています。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image34.png) + +以下のコマンドで OpenCode をインストールできます。 + +```bash +# Linux / Unix +curl -fsSL https://opencode.ai/install | bash + +# Windows +npm i -g opencode-ai +``` + +#### OpenCode の無料モデルを使用する + +OpenCode では不定期に無料モデルが提供されており、設定も非常にシンプルです。OpenCode を使用したいディレクトリでコマンドラインに `opencode` と入力して OpenCode プログラムを起動し、チャットパネルに入ります。`/models` コマンドを入力して「free」キーワードで検索すると、「free」という文字を含む無料モデルが表示されます。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image35.png) + +一般的に、無料モデルはコーディングタスクの完了において有料/サブスクリプションモデルより遅くなります。これは通常、モデル回線の混雑状況、ピーク時間帯かどうか、モデル自体の能力に依存します。 + +#### サードパーティのモデルを OpenCode のメインコーディングモデルとして使用する + +これが OpenCode の最大の強みです。同じ MCP、Skills、コンテキストを使用したまま、モデルを自由に切り替えて異なるコーディングタスクを完了できます。以下では、OpenAI 公式の GPT-5.3 Codex を例に、OpenCode にメインコーディングモデルとして接続します。 + +OpenCode のチャットウィンドウで `/connect` コマンドを入力し、最初の最も関連性の高い指示を選択して Enter キーを押すと、サードパーティモデルプロバイダーの認証認可を選択できます。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image36.png) + +ここでは OpenAI を選択する例で、Enter キーを押して認証方式を選択します。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image37.png) + +どちらでも構いません。認証方式が異なるだけです。ここでは最初の方法でブラウザログインを行います。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image38.png) + +このリンクをブラウザにコピーして、通常の OpenAI ログイン操作を行います。ブラウザに「Authorization Successful」と表示されたら、OpenCode クライアントは自動的に OpenAI のモデル選択画面に遷移します。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image39.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image40.png) + +#### Oh My OpenAgent プラグインのインストール + +OpenCode の強力さは、非常に活発なコミュニティエコシステムにもあります。GitHub で OpenCode 関連のプラグインが多数見つかります。OpenCode がモデルを自由に切り替えられる AI 協力ツールだとすれば、Oh-My-OpenAgent は OpenCode 上で動作する「マルチ Agent AI プログラミング指揮システム」です。複雑なタスクを複数のサブタスクに分解し、異なるモデルに分担させて各々の役割を果たさせることができます。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image41.png) + +以下のテキストをコピーして、OpenCode で設定済みのモデルに貼り付け、OpenCode にインストールさせます。 + +```text +Install and configure oh-my-openagent by following the instructions here: +https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md +``` + +以下は Oh-My-OpenAgent の機能と説明です。 + +| 特性 | 機能説明 | +| :-------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **自律軍団 (Discipline Agents)** | Sisyphus が Hephaestus、Oracle、Librarian、Explore のスケジュールを管理。完全な AI 開発チームが並列で作業。 | +| **Team Mode** (v4.0, オプション) | リーダー Agent + 最大 8 名の並列メンバー、リアルタイム tmux 可視化、専用 `team_*` ツール群。`hyperplan`(5 人の敵対的レビュアー)と `security-research`(3 人のハンター + 2 人の PoC エンジニア)を駆動。[ドキュメント →](docs/guide/team-mode.md) | +| **`ultrawork` / `ulw`** | ワンクリックで全 Agent が出動。タスク完了まで決して停止しない。 | +| **[IntentGate 意図ゲート](https://factory.ai/news/terminal-bench)** | 本当に行動する前に、ユーザーの真の意図を分析。文字通りの意味に誤導される AI の無駄発言に完全に別れを告げる。 | +| **ハッシュベースの編集ツール** | 各修正は `LINE#ID` コンテンツハッシュで検証。誤修正率 0%。[oh-my-pi](https://github.com/can1357/oh-my-pi) にインスパイア。[The Harness Problem →](https://blog.can.ac/2026/02/12/the-harness-problem/) | +| **LSP + AST-Grep** | ワークスペースレベルのリネーム、ビルド前診断、AST ベースの書き換え。Agent に IDE レベルの精度を提供。 | +| **バックグラウンド Agent** | 5 人以上の専門家が同時に並列作業。コンテキストをクリーンに保ちながら、いつでも成果を取得可能。 | +| **内蔵 MCP** | Exa(ウェブ検索)、Context7(公式ドキュメント)、Grep.app(GitHub ソースコード検索)。デフォルトで有効。 | +| **Ralph Loop / `/ulw-loop`** | 自己参照のループ。100% の完了度に達するまで停止しない。 | +| **Todo 強制実行** | Agent がサボろうとしたら、システムが強制的に引き戻す。あなたのタスクは必ず完了させる。 | +| **コメントレビューアー** | 強い AI 臭のある冗長なコメントを除去。熟練したシニアエンジニアが書いたようなコードを出力。 | +| **Tmux 統合** | 完全なインタラクティブターミナルサポート。REPL の実行、デバッガの使用、TUI ツールの利用、すべてリアルタイムセッションで完了。 | +| **Claude Code 互換** | 既存の Hooks、コマンド、Skills、MCP、プラグインはすべてシームレスに移行可能。 | +| **Skills 内蔵 MCP** | Skills が必要な MCP サーバーを内蔵。オンデマンドで起動し、コンテキストウィンドウを圧迫しない。 | +| **Prometheus プランナー** | コードを書き始める前に、インタビューモードで戦略計画を作成。 | +| **`/init-deep`** | プロジェクトディレクトリ階層全体に `AGENTS.md` を自動生成。トークンの節約だけでなく、Agent の理解力も大幅に向上。 | + +Sisyphus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) はメインコマンダーです。計画の策定、専門家チームへのタスク割り当てを担当し、極めてアグレッシブな並列戦略でタスクを完了まで推進します。彼は途中で諦めることはありません。 + +Hephaestus (gpt-5.5) は自律的なディープワーカーです。目標だけを与え、具体的な方法は指示しないでください。彼は自動的にコードベースのパターンを探索し、最初から最後まで独立してタスクを実行し、途中であなたに世話を焼かせることはありません。名実ともに正真正銘の職人です。 + +Prometheus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) は戦略プランナーです。インタビューモードを通じて、1行のコードを書く前に、質問によってスコープを確定し、詳細な実行計画を構築します。 + +これらを理解したら、Oh-My-OpenAgent プラグインをインストールした OpenCode を使ってコーディングタスクに取り組むことができます。 + +## CLI AI プログラミングツールのさらに多くの使い方 + +### AI で要件文書を書く:「要件の具体化」を学ぶ + +大規模言語モデルにとって、抽象的な要件は「具体化」される必要があります。例えば、「お腹が空いた」というのは抽象的な要件であり、「お腹が少し空いているので、あんパンを一つ食べて、豆乳を一杯合わせたい」——これが実行可能な具体的な要件です。 + +しかし、抽象的な要件を具体的にするのは、実はかなり労力のかかるプロセスです。十分な数の事例に触れていなければ、抽象的な問題を細かなモジュールに分解する方法をすぐに思いつくのは難しいでしょう。そのような場合、最も良い方法は AI に「具体化」のステップを手伝わせることです。 +例えば、「毎日の計画」アプリを開発したい場合、最もシンプルなアイデアは次のようになるでしょう。 + +`Please help me write a daily planning app where I can write my plans each day and get reminders.` + +AI はこの要件に基づいてタスクを分割し、段階的に完了させることも可能ですが、途中でエラーや理解のズレが生じやすくなります。リスクを下げるために、まず AI に要件を拡張してもらいましょう。 + +`Based on my needs, please elaborate and provide a more detailed Product Requirement Document for reference. My idea is: Please help me write a daily planner app that supports daily plan-writing and provides reminders .` + +すると、AI は以下のような完全な PRD を提案してくれるかもしれません。 + +``` +Product Requirements Document (PRD): "Today's Plan" App +Document Version: 1.0 +Creation Date: October 27, 2023 +Author: (Your Name/Product Manager) + +1. Product Introduction +1.1 Product Name +Today's Plan +1.2 Product Vision +"Today's Plan" is a minimalist and highly efficient daily planning and reminder tool, dedicated to helping users eliminate procrastination and forgetfulness, plan every day clearly, and ensure tasks are carried out through an intelligent reminder system—ultimately enabling users to gain a stronger sense of control and achievement over their time. +1.3 Target Users (User Personas) +We mainly serve three types of users: +Students (Xiao Ming): +Characteristics: Multiple tasks such as courses, assignments, club activities, exam prep, needing organized time arrangement. +Pain Points: Easily forget small tasks or assignment deadlines; feel overwhelmed switching between tasks; want to build regular study and life habits. +Needs: A simple tool to list daily to-dos and provide reminders before class/self-study. +Office Workers (Zhang Wei): +Characteristics: Fast-paced work, many meetings, reports, project milestones, and personal affairs (fitness, picking up children). +Pain Points: Easily forget important meetings or work milestones; get interrupted by urgent tasks and forget the original plan; feel busy but inefficient at end of day. +Needs: Need a tool to quickly record and schedule daily work and send strong reminders at key times (e.g., 15 minutes before meetings). +Freelancers/Self-disciplined Seekers (Li Na): +Characteristics: High freedom of time, but strong self-management required for work output and personal growth. +Pain Points: Easily procrastinate, lack external supervision; start the day without a clear plan, leading to low time utilization. +Needs: Need a tool to help build a daily fixed routine (Morning Routine) and review daily achievements for positive feedback. + +2. User Stories +As a user, I want to quickly create today's plan list so I have an overview of all my tasks for the day. +As a user, I want to set specific start and end times for each task so I can create a visual timeline. +As a user, I want to receive push notification reminders before a task starts so I won't miss any important arrangements. +As a user, I want to customize the reminder time (such as 5, 15, or 60 minutes in advance) so reminders better fit my habits. +As a user, I want to easily mark completed tasks so I can feel accomplished and clearly see my progress. +As a user, I want to see a summary of my completed plans at the end of each day for reviewing and self-motivation. +As a user, I want to conveniently edit and delete tasks to handle last-minute changes. +As a user, I want to view plans and achievements from previous days to review my efficiency and habits. + +3. Feature Breakdown +Core Features (MVP - Minimum Viable Product) +Module 1: Plan Management +3.1.1 Daily Plan Homepage +Interface: "Today" as the core view, current date shown at the top. +View: Timeline list, clearly showing tasks scheduled from morning to evening. Tasks without a time can be listed in the top or bottom "To-do List" section. +Interactions: +Click the "+" button in the bottom right to quickly create a new task. +Pull down to refresh the page. +Swipe left/right to view yesterday's and tomorrow's plans. +3.1.2 Create/Edit Task +Entry: Click "+" on the homepage or a time slot in the list. +Fields: +Task title (required): Briefly describe the task, e.g., "10 AM Weekly Product Meeting." +Task time (optional): +Set "start time" and "end time." +Provide "all-day" option for unspecified time tasks. +Default time picker should be quick and convenient. +Reminder setting (required, with default value): See Module 2. +Notes (optional): Add further descriptions, links, or location info. +Actions: Save, cancel, delete task. +3.1.3 Task Interaction +Mark as complete: Checkbox before each task; checking adds a strikethrough and gray background, indicating completion. Can unmark if needed. +Edit task: Click the task itself to enter edit page. +Delete task: Swipe left on a task to reveal "Delete" button. +Module 2: Smart Reminder System +3.2.1 Reminder Trigger +Mechanism: Based on task's set "start time" and the user's "reminder lead time," send a push notification from device. +Offline Support: Locally scheduled reminders must trigger even if user is offline. +3.2.2 Reminder Content & Format +Notification title: App name "Today's Plan." +Body: "Reminder: [Task Title] will start at [Start Time]." E.g., "Reminder: Product Meeting will start at 10:00." +Sound: Use system default or offer several simple, effective tones. +3.2.3 Reminder Settings +Global Settings (in Settings page): +User can set a default reminder time, e.g., "15 minutes before task starts." New tasks adopt this by default. +Single Task Settings (in create/edit page): +Users can override global settings for important tasks, choosing specific reminder times like "on time," "5 minutes early," "30 minutes early," or "1 hour early." +Provide "no reminder" option. +Subsequent Features (V1.1, V2.0) +3.3 Daily Review & Statistics +Push a summary notification at a set time every night (e.g., 22:00): "How was your day? Take a look at your achievements!" +Generate a simple daily report card: shows total planned tasks, completed tasks, completion rate, plus an encouraging message. +3.4 History Review +Calendar view to click on any past day and check its plans and completion status. Days with high completion rates marked with a special color. +3.5 Templates +Allow users to save a successful daily plan as a template, e.g., "Efficient Workday," "Relaxing Weekend." +When creating tomorrow's plan, one-click import a template, modify slightly to save time. +3.6 Themes & Personalization +Offer dark mode. +Allow changing several primary color themes. + +4. Non-Functional Requirements +4.1 Performance +Response: App launch time under 2 seconds; adding/editing tasks must be smooth and lag-free. +Resource Use: Low battery and memory consumption in background; do not over-consume resources waiting for reminders. +4.2 Usability +Minimal & intuitive: UI must be minimal, primary functions accessible within 3 clicks. No tutorial needed for new users. +Error tolerance: Offer undo (e.g. brief undo after mistakenly deleting a task). +4.3 Reliability +Reliable reminders: Reminder function is the product's lifeline; must guarantee 99.99% timely and accurate delivery. +Data loss-free: User plans must be reliably stored locally. Future versions can support cloud sync to prevent data loss on device change. +4.4 Compatibility +Platform: Support major iOS and Android versions (latest 3-4 releases). +Screen: Layout must fit various phone screen sizes. + +5. Roadmap +V1.0 (MVP): +Goal: Validate core value—planning & reminders. +Features: Complete all "Core Features" described above (Plan management, smart reminders). +V1.1 (Quick Optimization): +Goal: Improve retention and achievement. +Features: Add "Daily Review & Statistics," "History Review." +V2.0 (Enhanced Experience): +Goal: Increase efficiency and personalization. +Features: Add "Templates," "Themes & Personalization," and start developing "Cloud Sync." +``` + +最初の「毎日計画を記録してリマインドするアプリを作って」という一言と比べると、このドキュメントはずっと詳細になっています。実際の要件に基づいて内容を追加・削除・変更できます。一部のモジュールが不確かな場合は、AI にさらに多くの代替案を提案させ、それらから選択・統合して最終版を作成できます。 + +この方法により、抽象的なアイデアを簡単に具体的な説明に変換できます。AI 開発において、「具体性」こそが生産性です。要件が具体的であればあるほど、構造が安定した品質の高いプロジェクトを得やすくなります。この方法で以前の小規模プロジェクトをもう一度作り直して、効果の違いを比較してみてください。 + +このような「要件プロンプト」が長すぎると感じる場合、非常に自然なアプローチは、それを個別の Markdown ドキュメントに書き出し、あなたの「要件文書/開発文書/PRD」として扱うことです。その後、AI にプロジェクトを作成させるたびに、「この文書を参考にして」と指示するだけで、毎回長いプロンプトを入力し直す必要がありません。また、反復を通じてこの文書を継続的に改善し、後続のプロジェクトにも活用できます。 + +以下に、その他の一般的な使用シナリオをいくつか紹介します。 + +### フォルダの管理 + +CLI AI プログラミングツールを使って、現在のフォルダ内の様々なファイルを管理してみましょう。例えば、整理されていないファイルがたくさんあり、整理・分類したい場合、Claude Code や Codex に次のように依頼できます。 + +`Please help me organize the contents of the current folder. I want to group files with the same content together & I want to group files from the same time period together. Please help me handle this.` + +### 新規プロジェクトの開発 + +これは、以前に z.ai や Trae で行った使い方とほぼ同じです。CLI AI プログラミングツールを使って、ゼロから新規プロジェクトを開発することも可能です。もちろん、あらかじめ要件文書を用意しておくのが理想的です。 + +要件文書が詳細であればあるほど、最終的な成果は良くなります。アイデアが変化するたびに文書を複数回最適化できます。文書が完成度を増すほど、コードの実装はより安定し、成熟したものになります。 + +### オープンソースプロジェクトのデプロイ(例:Dify) + +コンピュータに触れたばかりの方にとって、GitHub からオープンソースプロジェクトをデプロイするのは難しく感じられることが多いでしょう。しかし、この作業は完全に Claude Code に任せることができます。Dify のチュートリアルでやったように。 + + + +自分の Dify をローカルで動かしたい場合、このリンクを Claude Code に渡して、次のように入力するだけです。 + +`I want to deploy this GitHub project ``https://github.com/langgenius/dify`` . Please help me clone the project and run it.` + +リクエストを受け取ると、Claude Code は GitHub からのコードの取得、実行環境の設定、プロジェクトの起動など、一連の操作を自動的に完了します。途中でエラーが発生した場合や、プロジェクトの起動状態が異常な場合は、指示に従って少量の手動対応を行うだけで済みます。Dify 以外にも、Claude Code を使って一般的な GitHub オープンソースプロジェクトの大半をデプロイできます。必要なのは一つのチャットボックスと、コーヒーを一杯飲む時間だけです。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image31.png) + +### コードの解説とドキュメントの作成 + +複雑なプロジェクトや、AI が自動生成した大規模なプロジェクトでは、コードが長すぎて論理が多すぎ、理解するのが難しいと感じることがあるでしょう。そんな時は、CLI AI プログラミングツールに「コードを読む」のを手伝わせることができます。次のように質問してみてください。 + +- このプロジェクトを説明してください。どのように実行するか、どのように使うか、今後どのように変更して開発を続けるか。 +- このプロジェクトの全体の流れを説明してください。プログラムはどのように動いているか。ユーザーは画面でどのような操作ができるか。 +- このプロジェクトのために完全なドキュメントを作成してください。開発ドキュメントと実行ドキュメントを含めてください。 +- 現在のフォルダ内のすべての内容に基づいて、詳細な説明を作成し、指定した Markdown ドキュメントに保存してください。 + +### さらに多くの使い方 + +もちろん、CLI AI プログラミングツールにできることは、上記のものにとどまりません。「コードを書くツール」としてだけでなく、独立した行動力を持つインテリジェントな Agent として捉えてください。次のようなことを依頼できます。 + +- ローカルファイルの管理と整理 +- 日記やまとめの作成 +- システムエラーの分析と修正 +- 各種反復的なコマンドラインタスクの実行 + +おそらく近い将来、それはあなたの PC 上で最も重要であり、最もあなたを理解している AI パートナーになるでしょう。 diff --git a/docs/ja-jp/stage-2/backend/stripe-payment/index.md b/docs/ja-jp/stage-2/backend/stripe-payment/index.md new file mode 100644 index 0000000..23b906c --- /dev/null +++ b/docs/ja-jp/stage-2/backend/stripe-payment/index.md @@ -0,0 +1,907 @@ +# Stripe などの決済システムの統合方法 + +製品にページ、ログイン、データベース、基本的なバックエンドが揃った後、次に直面する現実的な課題は **「どうやって料金を徴収するか」** です。 + +決済を初めて導入する際、多くの人が「どうやって支払いページにリダイレクトするか」にばかり注意を向けます。しかし、システムが安定しているかどうかを本当に左右するのはボタンではなく、決済チェーン全体です。誰が価格を決定するのか、誰が決済の成功を確認するのか、誰がデータベースを更新するのか、誰が権限を回収するのか。 + +本記事では、内容を2つの部分に分けて解説します。 + +- **前半**では最も実用的な基本導入のみを扱い、Stripe をプロジェクトにできるだけ早く組み込めるようにします。 +- **後半**は付録としてまとめ、Webhook の詳細、サブスクリプションイベント、国や地域による決済ソリューションの違いを取り上げます。 + +> **前提として、以下の章を先に学ぶことをお勧めします** +> +> - [データベースから Supabase へ](../database-supabase/) +> - [大規模言語モデルによるインターフェースコードとインターフェース文書の作成支援](../ai-interface-code/) +> - [Web アプリケーションのデプロイ方法](../zeabur-deployment/) + +# このレッスンで学ぶこと + +1. 最小実現可能な決済システムがどのようなものか。 +2. Stripe を最速でプロジェクトに組み込む方法。 +3. AI に決済システムを直接追加させるためのプロンプトの書き方。 +4. 海外向けの Stripe プロジェクトではない場合、地域ごとにどの決済ソリューションを優先すべきか。 + +--- + +# 第1部:基本編 + +## 1. まず3つの原則を覚える + +3つのことだけ覚えるなら、次の3つです。 + +1. **価格は必ずバックエンドで決定する**。フロントエンドから送られてくる金額を信用してはいけない。 +2. **権限を本当に有効にするのは Webhook であり**、`success` ページではない。 +3. **自前のデータベースに必ず決済ステータスを保存する**。Stripe の管理画面だけに頼ってはいけない。 + +この3つが決済システムの最も中核的な境界です。この境界さえ間違えなければ、後で Stripe、PayPal、Alipay、WeChat Pay に切り替えても、本質的には「インターフェースが変わるだけで、アーキテクチャは変わらない」ことになります。 + +## 2. バックエンドではなく、フロントエンドから直接 Stripe に接続するとどうなるか? + +決済を初めて実装する際、多くの人が真っ先に思いつく考え方です。 + +- ページにはすでに「購入」ボタンがある +- フロントエンドから直接 Stripe に接続すればいいのではないか +- そうすればバックエンドを作らなくても済むのではないか + +デモ用の偽ページを作るだけなら、この考え方で問題ありません。 +しかし、本当に料金を徴収するなら、**この方法は通常、問題を引き起こします。** + +最もよくある問題は以下の通りです。 + +1. **価格が簡単に改ざんされる** + ブラウザからのリクエストは、ユーザー自身の PC から送信されます。リクエストの内容を書き換えることができます。 +2. **機密情報が漏洩しやすい** + 本当に重要なシークレットキー、価格ロジック、メンバーシップの有効化ロジックは、そもそもフロントエンドに置くべきではありません。 +3. **「この支払いは本当に成功したのか」を確実に確認できない** + ユーザーが成功ページに遷移したからといって、データベースが正しく同期されているとは限りません。 +4. **データベースの状態が混乱する** + ユーザーは「ちゃんと支払った」と主張するのに、システム側には記録がないという事態が発生します。 + +より安全な役割分担は次のようになります。 + +- フロントエンドの担当:ボタンの表示、購入の開始、ページ遷移 +- バックエンドの担当:価格の決定、決済セッションの作成、Webhook の受信、データベースの更新 + +::: info 一言でまとめると +**フロントエンドはリダイレクトを担当し、バックエンドが価格決定と確認を担当する。** + +本当に料金を徴収するのであれば、「最終的な価格決定権」と「決済成功後の有効化ロジック」をフロントエンドに置いてはいけません。 +::: + +## 3. Stripe をまず選ぶべきケース + +次のようなケースでは、Stripe を最初の選択肢とするのが最もスムーズです。 + +- 海外ユーザー向けの SaaS +- サブスクリプション型のメンバーシップ製品 +- デジタル製品、テンプレート、AI クレジットパック +- 商用化を素早く検証したいが、最初からローカル決済の細かな対応に時間をかけたくない場合 + +主なユーザーが中国大陸にいる場合、通常は Stripe を第一選択としません。この点については付録でまとめて説明します。 + +## 4. 最小実現可能な決済チェーン + +まず最小バージョンを見てみましょう。このチェーンが動けば、決済システムの骨格が完成します。 + +```mermaid +flowchart LR + user["ユーザー"] + frontend["フロントエンドページ"] + backend["バックエンド"] + checkout["Stripe Checkout"] + webhook["Stripe Webhook"] + db["Supabase / 業務データベース"] + + user -->|"購入をクリック"| frontend + frontend -->|"決済セッション作成をリクエスト"| backend + backend -->|"バックエンド価格で Session を作成"| checkout + frontend -->|"決済ページにリダイレクト"| checkout + checkout -->|"決済完了後にイベントを送信"| webhook + webhook -->|"署名を検証してステータスを更新"| backend + backend -->|"orders / subscriptions に書き込み"| db + db -->|"フロントエンドがリフレッシュ後に最新ステータスを読み取り"| frontend +``` + +これを分かりやすく言い換えると、次の通りです。 + +1. ユーザーがボタンをクリックする。 +2. フロントエンドがバックエンドに決済リンクを要求する。 +3. バックエンドが Stripe のシークレットキーを使って決済セッションを作成する。 +4. ユーザーが Stripe のページで支払いを行う。 +5. Stripe が「支払いが本当に成功した」ことを Webhook で通知する。 +6. バックエンドがデータベースを更新する。 + +## 5. 標準的な決済フローのシーケンス図 + +より規格化されたシステム図に慣れている場合は、以下のシーケンス図を直接ご覧ください。 + +```mermaid +sequenceDiagram + autonumber + actor User as ユーザー + participant Frontend as フロントエンドページ + participant Backend as バックエンド API + participant Stripe as Stripe Checkout + + User->>Frontend: 「アップグレード」または「購入」をクリック + Frontend->>Backend: POST /api/billing/create-checkout-session + Note right of Frontend: フロントエンドは plan / userId / email を送信\n最終的な決済金額は送信しない + Backend->>Backend: プランを検証し priceId にマッピング + Backend->>Stripe: Checkout Session を作成 + Stripe-->>Backend: session.url を返却 + Backend-->>Frontend: 決済リンクを返却 + Frontend-->>User: Stripe 決済ページにリダイレクト + User->>Stripe: 支払いを完了 +``` + +## 6. クイックスタート + +Stripe を最速でプロジェクトに組み込むには、以下の5ステップに従うだけで十分です。 + +### 6.1 ステップ1:Stripe 管理画面で商品と価格を作成する + +このステップの目的は、「とりあえず適当に設定する」ことではなく、Stripe 上で **何を売るのか、どのように料金を徴収するのか** を明確に定義することです。 + +Stripe のモデルでは次のようになります。 + +- **Product** は「何を売るのか」を表します。例:`Pro メンバーシップ` +- **Price** は「いくらで、どの周期で売るのか」を表します。例:`月額 9.9 ドル`、`年額 99 ドル` + +なぜ最初にこのステップを行う必要があるのでしょうか? +バックエンドが Checkout Session を作成する際、Stripe に金額を直接渡すのではなく、すでに存在する `price_id` を渡すからです。Stripe はこの `price_id` に基づいて、実際の決済ページ、金額、通貨、サブスクリプション周期を生成します。 + +このステップを飛ばすと、後の「決済リンクの作成」ができません。 + +::: info なぜここで立ち止まる必要があるのか +`Product`、`Price` という言葉を見ると、Stripe の内部用語を学んでいるように感じて煩わしくなる初心者の方もいるでしょう。 + +しかし実際には、このステップは非常にシンプルなことを行っています。 +- 「何を売るのか」を明確にする +- 「いくらで売るのか」を明確にする +- バックエンドが後で安定した `price_id` を使って決済リンクを作成できるようにする + +この関係を理解すれば、Checkout Session も抽象的には感じなくなります。 +::: + +最小限のサブスクリプションシステムでは、少なくとも次の2つのレベルを最初に作成します。 + +- 1つの `Product` +- 1つ以上の `Price` + +以下のページを直接開けます。 + +- Stripe Dashboard ログイン: +- Stripe 商品と価格の管理ドキュメント: +- Stripe Checkout クイックスタート: +- Stripe Dashboard 商品ページ: + +まずは **テストモード(Test mode)** で操作することをお勧めします。最初から本番環境で作成しないでください。 + +最も一般的な最小構成は以下の通りです。 + +- `Product`: `Pro Plan` +- `Price 1`: `pro_monthly` +- `Price 2`: `pro_yearly` + +管理画面で操作する際は、次の順序で理解できます。 + +1. まず `Pro Plan` という商品を作成する +2. その商品の下に2つの価格を紐付ける +3. 月額と年額は同じ商品の2つの課金方式 + +完了後、少なくとも以下の情報をメモしておいてください。 + +- 月額価格の `price_id` +- 年額価格の `price_id` +- 自分のプラン名(例:`pro_monthly`、`pro_yearly`) + +初めて Stripe の管理画面に入る場合は、次のように理解することをお勧めします。 + +- `Product` が決済ページで何を売るかを決める +- `Price` が決済ページでいくら徴収するかを決める +- バックエンドが後で実際に使うのは、主に `price_id` + +::: info 本当にメモしておくべき値 +このページで最も重要なのは商品名ではなく、`price_id` です。 + +後で AI にバックエンドの実装を依頼する際も、自分で問題を調査する際も、頻繁に使うのは通常以下の値です。 +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- これらに対応する2つの `price_id` +::: + +AI にまず管理画面の設定を案内させたい場合は、次のプロンプトを直接使用できます。 + +```text +私は初めて Stripe を使います。まずコードを変更せずに、Stripe 管理画面で最基本的な課金設定を手順通りに教えてください。 + +以下の公式ドキュメントに基づいて、ステップバイステップで操作説明をお願いします: +- https://docs.stripe.com/products-prices/manage-prices +- https://docs.stripe.com/checkout/quickstart?lang=node + +私の状況: +- 最もシンプルなメンバーシップ課金をしたい +- 月額と年額の2つのプランのみ +- Product と Price という言葉の意味がまだ分からない + +お願い: +1. まず Product と Price がそれぞれ何かを最も分かりやすい言葉で説明してください。 +2. 「どのページを開き → どこをクリックし → 何を入力するか」の順に教えてください。 +3. 最後に、設定完了後に管理画面からコピーすべき値を教えてください。 +4. 間違いやすいポイントがあれば、テストモードで操作することも併せて教えてください。 +``` + +### 6.2 ステップ2:環境変数の準備 + +通常、少なくとも以下の環境変数を準備する必要があります。 + +- `STRIPE_SECRET_KEY` +- `STRIPE_WEBHOOK_SECRET` +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- `APP_URL` +- `SUPABASE_URL` +- `SUPABASE_SERVICE_ROLE_KEY` + +以下のページを直接開けます。 + +- Stripe API Keys ドキュメント: +- Stripe Dashboard API Keys ページ: +- Stripe Webhooks ドキュメント: +- Stripe Dashboard Webhooks ページ: + +> **注意**:`STRIPE_SECRET_KEY` と `SUPABASE_SERVICE_ROLE_KEY` は必ずバックエンドにのみ配置してください。 + +::: info 環境変数の目的 +このステップは「`.env` を埋める」ことが目的ではなく、決済システムの中で最も機密性の高い要素をバックエンドに保管することが目的です。 + +- Stripe のバックエンドシークレットキー +- Webhook 署名検証キー +- 自分の価格マッピング + +端的に言えば、フロントエンドは購入の開始のみを担当し、本当のシークレットと価格設定ロジックはすべてサーバー側に残すべきです。 +::: + +このステップも AI に整理を依頼できます。 + +```text +私のプロジェクトが現在どのように環境変数を管理しているかを確認し、Stripe に必要な環境変数を整理してください。 + +以下のドキュメントを参考にしてください: +- https://docs.stripe.com/keys +- https://docs.stripe.com/webhooks + +私の状況: +- 初心者です +- どの変数をフロントエンドに置き、どれをバックエンドに置くべきか分からない +- 現在のプロジェクトで `.env`、`.env.local` など、どのファイルを変更すべきかも分からない + +お願い: +1. まず現在のプロジェクト内で環境変数が通常どこに書かれているかを検索してください。 +2. Stripe 導入に最低限必要な変数をリストアップしてください。 +3. 各変数の役割を最も分かりやすい言葉で説明してください。 +4. 各変数をどの Stripe ページからコピーすればよいか教えてください。 +5. プロジェクトにサンプル環境変数ファイルがあれば、変数名を直接追加してください。 +``` + +### 6.3 ステップ3:バックエンドで Checkout Session を作成する + +このステップは自分でインターフェースを書く必要はありません。AI に公式ドキュメントを参考にして実装させましょう。 + +まず以下のドキュメントを AI に渡します。 + +- Stripe Checkout クイックスタート: +- Checkout Sessions API: +- サブスクリプション説明: + +そして次のプロンプトを貼り付けます。 + +```text +現在のプロジェクトのバックエンドコードの構成を確認し、Stripe 決済を組み込んでください。 + +以下の公式ドキュメントを参考にしてください: +- https://docs.stripe.com/checkout/quickstart?lang=node +- https://docs.stripe.com/api/checkout/sessions/create +- https://docs.stripe.com/payments/subscriptions + +私の目標はシンプルです: +- ユーザーが購入ボタンをクリックした後、Stripe の支払いページに遷移する +- プランは月額と年額の2種類のみ +- コードをどこに置くべきか自分で判断せず、まずプロジェクトを見て適切な場所に配置してください + +お願い: +1. まずプロジェクト内を検索し、バックエンドのエントリーファイル、ルーティングファイル、環境変数の書き方がどこにあるか把握してください。 +2. 公式ドキュメントを参考に、「Stripe 決済リンクの作成」ステップを組み込んでください。 +3. 金額は自分で指定させるのではなく、バックエンドの環境変数で価格を決定してください。 +4. 完了後、どのファイルを変更したか教えてください。 +5. 最後に、Stripe 管理画面でまだ追加が必要な設定があれば教えてください。 +``` + +### 6.4 ステップ4:フロントエンドから決済ページにリダイレクトする + +このステップの目標は非常にシンプルです。価格ページのボタンからバックエンドのインターフェースを呼び出し、Stripe Checkout にリダイレクトさせます。 + +参考ドキュメント: + +- Stripe Checkout 統合説明: + +AI 用プロンプト: + +```text +プロジェクト内の「購入」ボタンに Stripe を接続してください。 + +要件: +- 既存のページは変更せず、ボタンクリック後のロジックのみを変更する +- クリック後にバックエンドインターフェースを呼び出して決済リンクを取得し、Stripe にリダイレクトする +- エラーが発生した場合は、ユーザーにシンプルなメッセージを表示(例:「現在決済機能を利用できません。しばらくしてからお試しください」) + +参考ドキュメント:https://docs.stripe.com/payments/checkout/build-integration +``` + +### 6.5 ステップ5:Webhook でデータベースステータスを更新する + +これが最も重要なステップです。 + +::: info なぜこのステップが最も重要なのか +「ユーザーが支払いを完了し、success ページに遷移した」だけで完了と思っている人が多いです。 + +違います。 + +あなたのシステムにとって本当に重要なのは、 +**Stripe が Webhook を通じて正式にあなたのサーバーにイベントを送信し、バックエンドがデータベースのステータス更新に成功したかどうか** です。 +::: + +AI に Stripe 公式の Webhook ドキュメントに従って直接実装させ、自分で手書きしないようにしましょう。 + +参考ドキュメント: + +- Stripe Webhooks: +- Stripe CLI: +- Stripe CLI 使用方法: + +AI 用プロンプト: + +```text +Stripe の「支払い成功後に自動で有効化する」ステップを引き続き実装してください。 + +以下の公式ドキュメントを参考にしてください: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +私の目標: +- ユーザーが支払いを完了した後、ただ success ページに遷移するだけではなく +- 本当にデータベース内のメンバーシップステータスを「有効」に変更したい + +お願い: +1. まず現在のプロジェクト内でデータベース関連のコードとユーザーステータスの保存方法を検索してください。 +2. Stripe Webhook を追加してください。 +3. 支払い成功後、該当ユーザーを active に変更するか、プロジェクトで現在使用しているメンバーシップステータスフィールドを更新してください。 +4. プロジェクトに既存のサブスクリプションテーブル、オーダーテーブル、ユーザーテーブルがあれば、既存の構造を優先して使用してください。 +5. 完了後、どのファイルを変更したか教えてください。 +6. ローカルでこのステップが本当に機能しているかを確認する方法も教えてください。 +``` + +## 7. AI に素早く導入させるためのプロンプト + +Codex、Claude Code、Trae、Cursor などのツールを使用している場合、以下のプロンプトを直接貼り付けて、プロジェクトに決済導入を行わせることができます。 + +```text +現在のプロジェクトに Stripe 決済を組み込んでください。最もシンプルに動作するメンバーシップ課金機能を実装したいと考えています。 + +私の要件: +1. 私は初心者なので、まずプロジェクトを確認してから、コードをどこに変更すべきか判断してください。 +2. ディレクトリ構造、ルーティング構造、データベース構造は自分で判断しないでください。 +3. 最もシンプルなバージョンのみを作成:月額と年額の2つのプラン。 +4. ユーザーが購入をクリックした後、Stripe の支払いページに遷移する。 +5. 支払い成功後、データベースのメンバーシップステータスが「有効」になる。 +6. 最初から複雑な機能(クーポン、アップグレード/ダウングレード、複雑な請求書など)は追加しないでください。 + +出力要件: +1. まず変更計画を提示してください。 +2. その後、コードを直接変更してください。 +3. 最後に、ローカルでステップバイステップでテストする方法を説明してください。 +4. Stripe 管理画面での操作が必要なステップがあれば、リンクと要点を直接教えてください。 +``` + +AI にプロジェクトにより密接に対応させたい場合は、先頭に以下の情報を追加することもできます。 + +- 使用しているフロントエンドフレームワーク +- バックエンドのディレクトリ構造 +- データベースのテーブル名 +- 現在のユーザー認証が Supabase Auth か自前の Auth か + +## 7.1 ローカル連携テストも AI に任せる + +ローカル連携テストも AI に一任したい場合は、以下のプロンプトをそのまま使用できます。 + +```text +Stripe 決済を本当に動作するようにしてください。ステップバイステップで実行したいので、推測は避けたいと考えています。 + +以下の公式ドキュメントを参考にしてください: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +私の目標: +1. まずどの Stripe ページを開けばよいか教えてください。 +2. STRIPE_WEBHOOK_SECRET の取得方法を教えてください。 +3. stripe login と stripe listen の使用方法を教えてください。 +4. checkout.session.completed がローカル Webhook に正常に送信されたことを確認する方法を教えてください。 +5. 現在のプロジェクトでフロントエンドとバックエンドを先に起動する必要があれば、具体的なコマンドも教えてください。 +6. 原理だけではなく、実際の操作手順に従って出力してください。 +7. あるステップで間違えた場合、最もよくあるエラーメッセージがどのようなものかも教えてください。 +``` + +## 8. 最も陥りやすい4つの落とし穴 + +1. **`success` ページを決済成功とみなす** + 本当にステータスを決定するのは Webhook であり、フロントエンドのリダイレクトではありません。 +2. **フロントエンドに金額を渡させる** + これには深刻な価格改ざんリスクが伴います。 +3. **Webhook ルートが `express.json()` によって先に処理される** + Stripe の署名検証には元のリクエストボディが必要です。 +4. **冪等処理を行っていない** + Webhook は再試行される可能性があります。毎回メンバーシップやクレジットを重複して追加すると、事故につながります。 + +## 9. ワンラインでの選択アドバイス + +今すぐ決済を動かしたい場合。 + +| 主なユーザー | 最初に試すべきソリューション | +| :--- | :--- | +| 海外 SaaS / 国際ユーザー | Stripe | +| 中国大陸のユーザー | Alipay / WeChat Pay | +| 香港またはクロスボーダーチーム | Stripe + ローカルウォレット / FPS 統合ソリューション | + +具体的な違いについては、付録でまとめて説明します。 + +::: info 最もシンプルな選択の考え方 +最初から「世界中のすべての決済方法を一度に導入する」と考える必要はありません。 + +より現実的な順序は通常次の通りです。 +- まず主なユーザーの地域に合わせてメインの決済チェーンを1つ選ぶ +- 最小実現可能な決済をまず動かす +- その後、実際のユーザー来源に基づいて第2、第3の決済方法を追加していく +::: + +## 10. まとめ + +ここまでで、最も基本でありながら最も重要な決済チェーンを習得しました。 + +1. フロントエンドが購入を開始する。 +2. バックエンドが Checkout Session を作成する。 +3. ユーザーが Stripe のページで支払う。 +4. Stripe が Webhook でバックエンドに通知する。 +5. バックエンドがデータベースを更新する。 +6. フロントエンドがリフレッシュ後、新しいメンバーシップやオーダーのステータスを表示する。 + +決済を素早くプロジェクトに組み込むだけであれば、前半の内容ですでに十分です。以下の付録は、実際に問題に遭遇した時に改めて参照してください。 + +--- + +# 付録 + +## 付録 A:Stripe で最もよく登場するオブジェクト + +Stripe のドキュメントを初めて読む際、これらのオブジェクト名に最も戸惑うでしょう。まずは以下のものだけ理解すれば十分です。 + +| オブジェクト | 役割 | 例え | +| :--- | :--- | :--- | +| `Product` | 何を売るかを表す | 商品またはメンバーシッププラン | +| `Price` | いくらで、どの周期で売るかを表す | 月額、年額、買い切り | +| `Checkout Session` | Stripe がホストする決済フロー | 支払いページ | +| `Subscription` | 定期サブスクリプション関係 | 自動更新メンバーシップ | +| `Customer` | 支払いユーザー | Stripe 内の顧客プロファイル | +| `Webhook` | 非同期通知 | Stripe が「この支払いがどうなったか」を伝える | + +## 付録 B:なぜ `success` ページは決済成功を意味しないのか + +「ユーザーが支払いを完了し、success ページに遷移した」だけで決済成功とみなす人がたくさんいます。これが最も陥りやすい落とし穴です。 + +### 実際のシナリオ + +メンバーシップサイトを作ったとします。 + +1. ユーザーが「メンバーシップを購入」をクリックする +2. Stripe の支払いページにリダイレクトされる +3. ユーザーがクレジットカード情報を入力し、支払いをクリックする +4. ページが `success.html` にリダイレクトされる +5. success ページで「このページに来たのだから、メンバーシップを有効化する」というコードを書く + +**問題点は?** + +ユーザーは実際には支払っていなくても、支払いの途中でページを閉じても、`success.html` に直接アクセスできます。 + +### 2つの全く異なる経路 + +```mermaid +flowchart TB + pay["ユーザーが Stripe で支払いを完了"] + + subgraph unreliable["❌ 信頼できない経路:success ページのみを見る"] + success["ブラウザが success ページに遷移"] + fake["フロントエンドコードが有効化済みと判断"] + risk["リスク:ページを閉じる / 通信切断 / URL 偽造 / 未支払い"] + success --> fake --> risk + end + + subgraph reliable["✅ 信頼できる経路:バックエンド Webhook を正とする"] + event["Stripe サーバーが Webhook を送信"] + verify["バックエンドが署名を検証"] + active["データベースが正式に「支払済み」に更新"] + event --> verify --> active + end + + pay --> success + pay --> event +``` + +**重要な違い:** + +| | success ページ遷移 | Webhook 通知 | +| :--- | :--- | :--- | +| 誰が開始するか | ユーザーのブラウザ | Stripe のサーバー | +| 偽造可能か | 可能。URL に直接アクセスすればよい | 不可能。署名検証がある | +| 必ず支払い成功を意味するか | 意味しない | 意味する | +| システムがどう知るか | フロントエンドコードの推測 | Stripe からの正式通知 | + +### 完全なフローはどうあるべきか + +```mermaid +sequenceDiagram + autonumber + actor User as ユーザー + participant Frontend as ウェブページ + participant Stripe as Stripe + participant Webhook as バックエンドインターフェース + participant DB as データベース + + User->>Stripe: Stripe ページで支払いを完了 + Note over Stripe: 資金が実際に Stripe アカウントに到着 + + Stripe-->>Frontend: ブラウザが success ページにリダイレクト + Note over Frontend: ⚠️ このステップは単なる遷移
システムの確認を意味しない + + Stripe->>Webhook: Webhook 通知を送信
"checkout.session.completed" + Note over Webhook: ✅ これが正式な通知 + + Webhook->>Webhook: 署名を検証
(Stripe からの送信であることを確認) + + Webhook->>DB: ユーザーステータスを「支払済み」に更新 + DB-->>Webhook: 保存成功 + Webhook-->>Stripe: 200 OK を返却 + + Frontend->>DB: ユーザーがページをリフレッシュし、ステータスを照会 + DB-->>Frontend: 「支払済み」を返却 + Note over Frontend: この時点でメンバーシップ機能を表示 +``` + +### 各ステップのポイント + +**ステップ1:ユーザーが Stripe で支払う** + +「お金が本当に支払われた」ことが確定する唯一の瞬間です。 +- ユーザーがクレジットカード情報を入力し、確認をクリックする +- 銀行がユーザーのカードから引き落とす +- Stripe がこの支払いの受領を確認する + +**ステップ2:ブラウザが success ページにリダイレクト(最大の問題点)** + +このステップは全く信頼できません。理由は以下の通りです。 +- ユーザーはブラウザで直接 `yoursite.com/success` と入力でき、支払っていなくてもアクセスできる +- ユーザーが支払いの途中でページを閉じたが、以前に success リンクをコピーしており、後で直接開く +- ネットワークの問題で遷移に失敗するが、引き落としは完了している(ユーザーは支払ったのに成功ページが表示されない) +- ユーザーが戻るボタンを押して、再度支払うが、どちらも同じ success ページに遷移する + +**ステップ3:Stripe が Webhook を送信する** + +Stripe が能動的にサーバーに「この支払いが到着した」ことを通知します。 +- Stripe サーバーのみがこのリクエストを発行できる +- リクエストには署名が含まれており、バックエンドで本当に Stripe からのものか検証できる +- success ページが開かれていなくても、ユーザーの通信が切断していても、Webhook は送信される + +**ステップ4:バックエンドが署名を検証する** + +なぜ検証が必要なのか?ハッカーによる偽の通知を防ぐためです。 + +検証がない場合、ハッカーはあなたのサーバーに「ユーザー A が 1000 元支払った」という偽の通知を送信でき、システムがハッカーにメンバーシップを付与してしまいます。 + +検証のプロセス: +- Stripe が双方で合意したシークレットキーを使って通知内容の署名を生成する +- バックエンドが同じシークレットキーで署名が一致するか検証する +- 一致 = 100% Stripe からの送信、不一致 = 直ちに拒否 + +**ステップ5:データベースを更新する** + +検証が通った後にのみ、データベースを更新します。 +- ユーザーステータスを「支払待ち」から「支払済み」に変更 +- オーダー番号、金額、支払い時刻を記録 +- 対応するメンバーシップ権限を有効化 + +**ステップ6:フロントエンドがステータスを照会する** + +success ページで「このページに来たから成功」と判断してはいけません。正しいやり方は以下の通りです。 +- ページ読み込み時にバックエンドにリクエストを送る。「このユーザーは支払い済みか?」 +- バックエンドがデータベースを検索し、実際のステータスを返す +- 返された結果に基づいて「有効化成功」または「確認中」を表示する + +### よくある誤った実装 + +```javascript +// 誤り:success ページで直接有効化 +// success.html +if (window.location.pathname === '/success') { + // 危険!誰でも /success にアクセス可能 + activateMembership(); +} +``` + +```javascript +// 正しい:毎回バックエンドに確認する +// success.html +async function checkStatus() { + const response = await fetch('/api/user/status'); + const data = await response.json(); + + if (data.paymentStatus === 'paid') { + showMemberFeatures(); + } else { + showPendingMessage(); + } +} +``` + +### 一言でまとめると + +**success ページは「ブラウザのリダイレクト成功」に過ぎず、Webhook こそが「Stripe による正式な入金確認」です。** + +システムは Webhook を正として扱い、フロントエンドのリダイレクトを信用してはいけません。 + +## 付録 C:サブスクリプションシステムで最も監視すべきイベント + +| イベント | 意味 | 通常すべきこと | +| :--- | :--- | :--- | +| `checkout.session.completed` | 初回の有効化成功 | ローカルのサブスクリプションレコードを作成 | +| `invoice.paid` | 自動更新の成功 | 有効期限を延長 | +| `invoice.payment_failed` | 自動引き落としの失敗 | リスクステータスをマークし、ユーザーに通知 | +| `customer.subscription.deleted` | サブスクリプションのキャンセル | 権限を回収するか、期限切れ後に無効化 | + +### サブスクリプションの状態遷移図 + +```mermaid +stateDiagram-v2 + [*] --> NotStarted: ユーザー未購入 + NotStarted --> Active: checkout.session.completed + Active --> Active: invoice.paid + Active --> PastDue: invoice.payment_failed + PastDue --> Active: ユーザーの追加支払い成功 + Active --> Canceled: customer.subscription.deleted + PastDue --> Canceled: 期限内に復旧せず + Canceled --> [*] + + state "未有効" as NotStarted + state "メンバーシップ有効" as Active + state "引き落とし失敗 / 復旧待ち" as PastDue + state "キャンセル済み / 期限切れで回収" as Canceled +``` + +### 継続 / 失敗 / キャンセルのシーケンス図 + +```mermaid +sequenceDiagram + autonumber + participant Stripe as Stripe + participant Webhook as Webhook インターフェース + participant DB as サブスクリプションテーブル / オーダーテーブル + participant App as アプリケーション + actor User as ユーザー + + rect rgb(235, 248, 255) + Stripe->>Webhook: invoice.paid + Webhook->>DB: current_period_end を延長 + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: メンバーシップ有効状態を維持 + end + + rect rgb(255, 247, 237) + Stripe->>Webhook: invoice.payment_failed + Webhook->>DB: past_due をマーク + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 支払い方法の更新を促す + end + + rect rgb(254, 242, 242) + Stripe->>Webhook: customer.subscription.deleted + Webhook->>DB: canceled をマーク + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: プレミアム権限を停止 + end +``` + +## 付録 D:その他の決済ソリューションの選び方 + +### 1. 中国大陸 + +主なユーザーが中国大陸にいる場合、第一選択はやはり **[Alipay](https://open.alipay.com/)** と **[WeChat Pay](https://pay.wechatpay.cn/)** です。 + +**ビジネスモデル:** + +どちらも「決済ゲートウェイ」モデルです。必要な作業は以下の通りです。 +- 商事資格の申請(営業許可証、法人口座) +- ユーザーが支払った資金は直接あなたの商事口座に入金される +- 税務、返金、帳簿管理は自身で担当 + +**技術モデル:** + +どちらも「バックエンドでオーダー作成 + フロントエンドで支払い起動 + バックエンドで通知受信」のモデルであり、Stripe と同じ考え方です。 + +**Alipay の導入フロー:** +1. Alipay オープンプラットフォームでアプリケーションを作成 +2. 公開鍵・秘密鍵とコールバック URL を設定 +3. バックエンドで統一下注インターフェースを呼び出し、決済リンクまたは QR コードを生成 +4. ユーザーがスキャンまたはリダイレクトで支払い +5. Alipay が非同期でバックエンドに通知し、オーダーステータスを更新 + +**WeChat Pay の導入フロー:** +- JSAPI 決済:公式アカウントやミニプログラムに適しており、WeChat 内で直接支払い +- Native 決済:PC で QR コードを生成し、ユーザーがスキャンして支払い +- H5 決済:モバイルブラウザから WeChat アプリを起動して支払い + +フロー:バックエンドでオーダー作成 → `prepay_id` または `code_url` を取得 → フロントエンドで支払い起動 → バックエンドで通知を受信して成功を確認 + +**参考リンク:** +- Alipay オープンプラットフォーム: +- WeChat Pay 商事ドキュメント: + +### 2. 香港 + +香港市場は比較的ミックスされており、一般的な組み合わせは以下の通りです。 + +- 銀行カード:Visa / Mastercard +- FPS(転数快):香港ローカルの即時送金 +- AlipayHK / WeChat Pay HK:香港版の Alipay と WeChat + +**おすすめの組み合わせ:** +- **[Stripe](https://stripe.com/hk)** で国際カードとサブスクリプションをカバー +- **[Airwallex](https://www.airwallex.com/)** または **[Adyen](https://www.adyen.com/)** でローカルウォレットと FPS を補完 + +### 3. 海外 / 国際 SaaS + +#### [Stripe](https://stripe.com/) + +**ビジネスモデル:** 決済ゲートウェイ + +- 商事資格の申請が必要(一部の国では Stripe が代行可能) +- ユーザーの支払いは Stripe アカウントに入金され、その後銀行口座に決済される +- 税務申告は自身で担当 + +**技術モデル:** + +- API 体験が最も良く、ドキュメントが明確 +- Checkout(ホスティングページ)、Elements(カスタムフォーム)、Payment Links(ノーコード)をサポート +- Webhook で決済ステータスを通知 +- サブスクリプション、請求書、多通貨をサポート + +**対象者:** 海外 SaaS、独立開発者、柔軟なカスタマイズが必要なチーム + +**参考リンク:** + +#### [PayPal](https://www.paypal.com/) + +**ビジネスモデル:** 決済ゲートウェイ + +- ユーザーの支払いは PayPal アカウントに入金され、その後銀行口座に引き出す +- 税務は自身で担当 + +**技術モデル:** + +- 一回限り決済:フロントエンドにボタンを配置し、バックエンドでオーダーを作成/確認 +- サブスクリプション:先に Product と Plan を作成し、SDK で起動 +- バックエンドと Webhook が同様に必要。フロントエンドのコールバックのみを見ないこと + +**対象者:** 追加チャネルが必要な海外ビジネス、PayPal 決済に慣れているユーザー + +**参考リンク:** + +#### [Paddle](https://www.paddle.com/) + +**ビジネスモデル:** Merchant of Record (MoR) + +- Paddle が「記録商人」となり、法的には Paddle がユーザーから代金を徴収 +- Paddle が世界の税務、VAT、返金、コンプライアンスを処理 +- ユーザーの支払いは Paddle に入金され、Paddle が税金と手数料を控除後に決済 +- 各国で法人を設立したり税務を処理したりする必要がない + +**技術モデル:** + +- Paddle.js:フロントエンドにホスティング決済ページを組み込み +- バックエンド API:transaction を作成し、checkout に渡す +- Webhook でサブスクリプションステータスを同期 + +**対象者:** 世界の税務を処理したくない SaaS チーム、特に B2B SaaS + +**参考リンク:** + +#### [Lemon Squeezy](https://www.lemonsqueezy.com/) + +**ビジネスモデル:** Merchant of Record (MoR) + +- Paddle と同様、Lemon Squeezy が「記録商人」 +- 世界の税務、VAT、コンプライアンスを処理 +- 2024年に Stripe に買収されたが、独立して運営 + +**技術モデル:** + +- Hosted Checkout:最もシンプル。直接決済リンクを生成 +- Checkout Overlay:レイヤーでページに組み込み +- バックエンド API:checkout を作成し、柔軟にコントロール + +**対象者:** 独立開発者、デジタル製品、ソフトウェアライセンス + +**参考リンク:** + +### 4. エンタープライズソリューション + +#### [Airwallex(空中雲匯)](https://www.airwallex.com/) + +**ビジネスモデル:** 決済ゲートウェイ + グローバル口座 + +- グローバル受取口座を提供(バーチャル銀行口座に類似) +- 多通貨での受取、両替、送金をサポート +- 税務は自身で担当 + +**技術モデル:** + +- Payment Links:ほぼコード不要で決済リンクを生成 +- Hosted Payment Page:ホスティングページ +- Drop-in / Embedded / Native API:深い統合、高いカスタマイズ性 +- Alipay HK、FPS、WeChat Pay などのローカル決済方法をサポート + +**対象者:** 香港チーム、クロスボーダービジネス、多通貨口座が必要な企業 + +**参考リンク:** + +#### [Adyen](https://www.adyen.com/) + +**ビジネスモデル:** 決済ゲートウェイ + +- エンタープライズグレードの決済プラットフォーム。年間処理額は数兆ユーロ規模 +- オンライン、オフライン、モバイルの全チャネルをサポート +- 税務は自身で担当 + +**技術モデル:** + +- Pay by Link:最もシンプル。決済リンクを生成 +- Drop-in / Components:標準的なオンライン統合 +- 管理画面で Alipay、Alipay HK、PayMe などのローカル決済方法を有効化可能 + +**対象者:** 大規模企業、全チャネル決済が必要な企業 + +**参考リンク:** + +### 5. ソリューション比較 + +| ソリューション | ビジネスモデル | 税務処理 | 対象者 | +| :--- | :--- | :--- | :--- | +| Stripe | 決済ゲートウェイ | 自身で処理 | 海外 SaaS、開発者 | +| PayPal | 決済ゲートウェイ | 自身で処理 | 海外の追加チャネル | +| Paddle | MoR | Paddle が代行処理 | B2B SaaS、税務を管理したくない場合 | +| Lemon Squeezy | MoR | LS が代行処理 | 独立開発者、デジタル製品 | +| Adyen | 決済ゲートウェイ | 自身で処理 | 大規模企業 | +| Airwallex | 決済ゲートウェイ + 口座 | 自身で処理 | クロスボーダービジネス、香港チーム | +| Alipay / WeChat Pay | 決済ゲートウェイ | 自身で処理 | 中国大陸ユーザー | + +### 6. 地域別のソリューション選択 + +| ターゲット市場 | 推奨ソリューション | +| :--- | :--- | +| 中国大陸 | Alipay / WeChat Pay | +| 香港 | Stripe + Airwallex / Adyen | +| 海外 SaaS | Stripe(税務を自身で管理)または Paddle(MoR が代行) | +| 海外デジタル製品 | Stripe / Lemon Squeezy / Paddle | +| 複数地域エンタープライズ | Adyen / Airwallex / Stripe の組み合わせ | diff --git a/docs/ja-jp/stage-2/backend/zeabur-deployment/index.md b/docs/ja-jp/stage-2/backend/zeabur-deployment/index.md new file mode 100644 index 0000000..4b18dfa --- /dev/null +++ b/docs/ja-jp/stage-2/backend/zeabur-deployment/index.md @@ -0,0 +1,490 @@ +# Web アプリケーションのデプロイ方法 + +本チュートリアルでは、あなたの Web アプリケーションをインターネット上にデプロイし、他の人がアクセスできるようにする方法を紹介します。**Tencent CloudBase**、**Vercel**、**Zeabur** という3つの一般的なデプロイプラットフォームを紹介し、「コードを書く」から「他の人がインターネット上であなたのウェブサイトにアクセスできる」までの完全なプロセスを迅速に完了できるようサポートします。 + +# 「デプロイ」とは何か? + +始める前に、「デプロイ(Deployment)」の意味をはっきりさせましょう。ウェブサイトが外部ユーザーにアクセスされるためには、公開アクセス可能なネットワークアドレス(IP アドレス、例えば 123.45.67.89、またはドメイン名、例えば [google.com](https://google.com/) など)が必要です。しかし、アドレスだけでは不十分です。あなたが書いたウェブページコード(HTML、CSS、JavaScript ファイル、あるいは React、Vue などのフレームワークで書いたプロジェクト)や、関連する画像・動画リソースは、すべて24時間稼働のサーバー上に配置し、そのサーバーがネットワークリクエストに応答するようにする必要があります。そうしてはじめて、誰もがブラウザからこれらのリソースにアクセスしてダウンロードできるようになります。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image1.png) + +画像出典:https://www.hostinger.com/tutorials/what-is-cloud-hosting + +リソースのアップロード、環境の設定、そしてサービスを「稼働させる」までの一連のプロセス全体が**デプロイ(Deployment)**と呼ばれます。 + +簡単に言えば:自分のパソコンで書いたウェブページは、ローカルでプログラムを起動しても、自分のブラウザからしかローカルアドレスでアクセスできません。なぜなら、そのコードはあなたのハードディスク上にしか存在しないからです。「デプロイ」とは、あなたのコードとリソースをパブリックネットワークに接続された専用サーバーに移行し、適切に設定して、そのサーバーが「他の人がアクセスしたときにどう応答するか」を分かるようにすることです。例えば、誰かがブラウザにあなたのドメイン名を入力したとき、サーバーはすぐに対応するウェブページファイルを見つけ、その内容を相手のデバイスに送信し、ユーザーにあなたのページを表示させます。 + +手動でデプロイする場合、プロジェクトにはしばしば複数のステップが必要で、各ステップでつまずく可能性があります。一般的な重要ステップは以下の通りです: + +1. **サーバーの準備**:まずクラウドサーバー(Alibaba Cloud、Tencent Cloud、AWS EC2 など)を購入し、サーバーの所在地(上海、シンガポールなど)、スペック(CPU、メモリ、ディスクサイズなど)を選択し、リモートでサーバーに接続する方法(SSH ツールを使ったログインなど)も学ぶ必要があります。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image2.png) +2. **環境の設定**:Web アプリケーションは特定の「環境」でなければ動作しません。例えば、Node.js プロジェクトを実行するには、まず Node.js をインストールする必要があります。Python プロジェクトを実行するには、Python と対応するサードパーティライブラリをインストールする必要があります。環境のバージョンが一致しないと、プログラムがエラーを起こしたり、起動しなかったりする可能性があります。 +3. **リソースのアップロード**:ローカルのコードとリソースをサーバーにアップロードする必要があります。一般的な方法には FTP や Git があります。プロジェクトのサイズが大きい場合(動画ファイルを含む場合など)、途中で接続が切れると、アップロードをやり直す必要があることもあります。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image3.png) + +4. **サービスの起動とテスト**:アップロード完了後、サーバー上でコマンドを実行してアプリケーションを起動し、「割り当てられたネットワークアドレスにアクセスできるか」をテストする必要があります。アクセスできない場合、サーバーのファイアウォールが対応するポートを開放していない可能性があります(例えば、アプリケーションがポート3000をリッスンしていても、そのポートがファイアウォールにブロックされているなど)。あるいは、プログラム自体にバグがある可能性もあり、その場合はサーバーログを確認してトラブルシューティングを行う必要があります。 + > 💡 ポートは、同じデバイス上の異なるアプリケーションを区別する「部屋番号」、IP はそのデバイスの「住所」と考えることができます。IP とポートを組み合わせる(IP:port)ことで、特定のネットワークサービスを正確に特定できます。 +5. **保守と更新**:コードを変更するたびに、再度アップロードしてサービスを再起動する必要があります。サーバーがダウンした場合(停電やネットワーク障害など)、アプリケーションを手動で再起動する必要があり、「プロセス監視ツール」を追加で設定して、異常終了後にプログラムが自動的に再起動するようにすることもあります。 + +CloudBase、Vercel、Zeabur のような「ローコードデプロイプラットフォーム」は、まさにこれらの複雑な問題を解決するために誕生しました。これらは「サーバーの購入、環境の設定、コードのアップロード、サービスの起動、稼働の監視」といったステップを自動的に完了してくれます。必要なのは、自分のコードリポジトリ(GitHub や GitLab など)をプラットフォームに接続するか、コードを直接アップロードするだけで、プラットフォームが自動的にコードを取得し、アプリケーションの種類を識別し、対応するランタイム環境を設定し、最後に誰もがアクセスできるパブリックネットワークアドレスを提供してくれます。さらに、自分のドメイン名をワンクリックでバインドすることもできます。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image4.png) + +次に、これら3つのプラットフォームの特徴と使用方法をそれぞれ紹介し、自分に最も適したデプロイソリューションを選べるようにします。 + +--- + +# デプロイプラットフォームの比較 + +| プラットフォーム | 特徴 | 適用シナリオ | 無料枠 | +|------|------|----------|----------| +| **Tencent CloudBase** | 中国国内からのアクセスが速く、WeChat エコシステムと深く統合 | 中国国内ユーザー中心、WeChat ミニプログラムのサポートが必要なプロジェクト | 無料枠あり | +| **Vercel** | フロントエンドフレームワークのサポートが良く、GitHub と緊密に統合 | React/Vue/Next.js などのモダンフロントエンドプロジェクト | 無料枠あり | +| **Netlify** | 機能が充実、フォーム処理や認証機能をサポート、Git との統合が良好 | フォーム処理や認証機能などの高度な機能を必要とする静的サイト | 無料枠あり | +| **Zeabur** | 複数の言語とサービステンプレートをサポート、柔軟な設定 | 複数のサービス(Dify、n8n など)をデプロイする必要がある複雑なプロジェクト | 毎月約5ドルの無料枠 | + +--- + +# 1. Tencent CloudBase + +Tencent CloudBase(クラウド開発)は、Tencent Cloud が提供するワンストップバックエンドクラウドサービスで、特に中国国内の開発者に適しています。その利点は以下の通りです: + +- **国内アクセスが速い**:サーバーが中国国内にあり、アクセス遅延が低い +- **WeChat エコシステムとの統合**:WeChat ミニプログラムや公式アカウントとの連携が容易 +- **ワンストップソリューション**:静的サイトホスティング、クラウド関数、データベース、ストレージなどのフルセットのサービスを提供 +- **十分な無料枠**:個人開発者に十分な無料リソース枠を提供 + +## CloudBase を使用した Web アプリケーションのデプロイ + +### ステップ 1:登録とログイン + +[Tencent CloudBase コンソール](https://console.cloud.tencent.com/tcb) にアクセスし、WeChat または QQ でログインします。 + +### ステップ 2:環境の作成 + +「新規作成」をクリックし、環境名(例:`my-web-app`)を選択します。 + +> ⚠️ **注意**:CloudBase の無料体験版を有効にするには引き換えコードが必要です。Tencent CloudBase の公式アカウントをフォローし、「引き換えコードを受け取る」と入力して無料体験版の引き換えコードを取得し、環境作成時にコードを入力すると無料環境が有効になります(無料体験期間は6ヶ月です)。 + +### ステップ 3:静的サイトホスティングの有効化 + +環境管理ページで「静的サイトホスティング」機能を見つけて有効にします。有効化後、デフォルトのアクセスドメイン名が付与されます。 + +CloudBase の静的サイトホスティングは、Zeabur と同様に複数のデプロイ方法を提供しています: + +- **ローカルプロジェクトのアップロード**:構築済みの静的ファイル(HTML、CSS、JS など)をローカルから直接アップロード +- **テンプレートデプロイ**:预设のテンプレートを使用してプロジェクトを迅速に作成(React Web アプリケーションテンプレート、Vue Web アプリケーションテンプレートなど) +- **Git リポジトリデプロイ**:GitHub などのコードリポジトリからの自動コード取得とデプロイをサポート + +### ステップ 4:コードのデプロイ + +静的サイトホスティングページで、CloudBase は3つのデプロイ方法を提供しています: + +**方法1:ローカルプロジェクトのデプロイ(ローカルプロジェクトのアップロード)** +- コンソールで「ローカルプロジェクトのデプロイ」を選択 +- 構築済みの静的ファイル(HTML、CSS、JS など)を直接アップロード +- ローカルで構築済みのプロジェクトフォルダ(`dist` や `build` ディレクトリなど)を選択 +- アップロード完了を待つだけでアクセス可能 + +**方法2:テンプレートデプロイ** +- 预设のテンプレートを使用してプロジェクトを迅速に作成 +- React Web アプリケーションテンプレート、Vue Web アプリケーションテンプレートなどをサポート +- テンプレートに基づいて自動的に構築およびデプロイ + +**方法3:Git リポジトリのデプロイ** +- **Git 個人リポジトリのデプロイ**:あなたの GitHub などの個人コードリポジトリをバインド +- **パブリックリポジトリのデプロイ**:パブリックの Git リポジトリからのコード取得をサポート +- 自動ビルドコマンドを設定(例:`npm run build`) +- コードをプッシュするたびに自動的に再デプロイ + +> 💡 **ヒント**:CLI ツールを使用してデプロイすることも可能です: +> ```bash +> # CloudBase CLI のインストール +> npm install -g @cloudbase/cli +> # ログイン +> tcb login +> # デプロイ +> tcb hosting deploy ./dist -e your-env-id +> ``` + +### ステップ 5:カスタムドメインの設定(オプション) + +静的サイトホスティングの設定で、独自のドメイン名をバインドし、無料の HTTPS 証明書を申請できます。 + +--- + +# 2. Vercel + +Vercel は、世界で最も人気のあるフロントエンドデプロイプラットフォームの一つで、React、Vue、Next.js などのモダンフロントエンドフレームワークプロジェクトのデプロイに特に適しています。その特徴は以下の通りです: + +- **GitHub との深い統合**:コードをプッシュするだけで自動デプロイ +- **自動プレビュー**:各 Pull Request が独立したプレビューリンクを生成 +- **グローバル CDN**:ウェブサイトが自動的に世界中のノードに配布され、アクセス速度が速い +- **サーバーレス関数**:プロジェクト内でバックエンド API を記述可能 + +> ⚠️ **注意**:Vercel は一部のネットワーク環境でアクセスが不安定な場合があります。中国国内のユーザーは CloudBase を優先することをお勧めします。 + +## Vercel を使用した Web アプリケーションのデプロイ + +### ステップ 1:アカウントの登録 + +[Vercel 公式サイト](https://vercel.com/) にアクセスし、GitHub アカウントでログインします。 + +### ステップ 2:プロジェクトのインポート + +1. 「Add New Project」をクリック +2. デプロイしたい GitHub リポジトリを選択 +3. 希望するリポジトリが表示されない場合は、「Adjust GitHub App Permissions」をクリックしてアクセスを許可 + +### ステップ 3:ビルド設定の構成 + +Vercel はプロジェクトタイプを自動的に識別し、ビルドコマンドを設定します: + +| フレームワーク | ビルドコマンド | 出力ディレクトリ | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Next.js | `next build` | - | +| 純粋な HTML | - | プロジェクトのルートディレクトリ | + +自動識別が正しくない場合は、手動で変更できます: +- **Build Command**:ビルドコマンド(例:`npm run build`) +- **Output Directory**:ビルド出力ディレクトリ(例:`dist` や `build`) +- **Install Command**:依存関係のインストールコマンド(通常は `npm install`) + +### ステップ 4:デプロイ + +「Deploy」ボタンをクリックし、ビルドの完了を待ちます。ビルド成功後、`xxx.vercel.app` というドメイン名が付与されます。 + +### ステップ 5:カスタムドメイン(オプション) + +プロジェクト設定の「Domains」ページで、独自のドメイン名を追加できます。Vercel が自動的に HTTPS を設定します。 + +--- + +# 3. Netlify + +Netlify は、Vercel と並んで非常に人気のあるフロントエンドデプロイプラットフォームで、静的サイトやシングルページアプリケーション(SPA)のデプロイに特に適しています。その特徴は以下の通りです: + +- **機能が充実**:静的サイトホスティングに加え、フォーム処理、認証、エッジ関数などの高度な機能をサポート +- **Git との深い統合**:GitHub、GitLab、Bitbucket をサポートし、コードのプッシュで自動デプロイ +- **ブランチプレビュー**:各ブランチが自動的に独立したプレビューリンクを生成 +- **グローバル CDN**:ウェブサイトが自動的に世界中のノードに配布され、アクセス速度が速い +- **フォーム処理**:バックエンドコードなしでウェブサイトのフォーム送信を処理 +- **認証機能**:ユーザー認証機能が組み込まれており、ログイン/登録を迅速に実装 + +> ⚠️ **注意**:Netlify の中国国内からのアクセス速度は CloudBase に劣る場合があります。主に海外向けのプロジェクトに使用することをお勧めします。 + +## Netlify を使用した Web アプリケーションのデプロイ + +### ステップ 1:アカウントの登録 + +[Netlify 公式サイト](https://www.netlify.com/) にアクセスし、「Sign up」をクリックして登録します。GitHub、GitLab、Bitbucket、またはメールアドレスで登録できます。 + +### ステップ 2:プロジェクトのインポート + +1. ログイン後、「Add new site」→「Import an existing project」をクリック +2. コードホスティングプラットフォーム(例:GitHub)を選択 +3. Netlify にリポジトリへのアクセスを許可 +4. リストからデプロイしたいリポジトリを選択 + +### ステップ 3:ビルド設定の構成 + +Netlify は一般的なフロントエンドフレームワークを自動的に識別し、ビルド設定を行います: + +| フレームワーク | ビルドコマンド | 公開ディレクトリ | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Angular | `ng build` | `dist/` | +| Next.js | `next build` | `out` | +| 純粋な HTML | - | `.`(プロジェクトのルートディレクトリ) | + +自動識別が正しくない場合は、手動で設定できます: +- **Build command**:ビルドコマンド(例:`npm run build`) +- **Publish directory**:ビルド出力ディレクトリ(例:`dist` や `build`) + +### ステップ 4:デプロイ + +「Deploy site」ボタンをクリックし、ビルドの完了を待ちます。ビルド成功後、`xxx.netlify.app` というドメイン名が付与され、誰でもこのアドレスを通じてあなたのウェブサイトにアクセスできます。 + +### ステップ 5:カスタムドメインの設定(オプション) + +1. サイト設定に入り、「Domain management」をクリック +2. 「Add custom domain」をクリック +3. ドメイン名を入力し、指示に従って DNS レコードを設定 +4. Netlify が自動的に HTTPS 証明書を申請・設定 + +### 特色機能 + +#### 1. フォーム処理 + +Netlify は非常に便利な機能を提供しています:バックエンドコードなしでフォーム送信を処理できます。 + +HTML フォームに `netlify` 属性を追加するだけです: + +```html +
+

+ +

+

+ +

+

+ +

+

+ +

+
+``` + +デプロイ後、フォーム送信されたデータは自動的に Netlify 管理画面に送信されます。「Forms」ページですべての送信記録を確認でき、メール通知の設定や、他のサービスへのデータ転送も可能です。 + +#### 2. Netlify Functions(エッジ関数) + +Netlify はサーバーレス関数(Serverless Functions)のデプロイをサポートしており、完全なバックエンドサーバーを構築することなく、シンプルな API インターフェースを実装できます。JavaScript や TypeScript で関数を記述でき、デプロイ後、自動的にアクセス可能な URL が付与されます。 + +例えば、`hello.js` というファイルを作成します: + +```javascript +exports.handler = async (event, context) => { + return { + statusCode: 200, + body: JSON.stringify({ message: "Hello from Netlify!" }) + }; +}; +``` + +デプロイ後、`https://あなたのドメイン/.netlify/functions/hello` を通じてこの関数にアクセスできます。 + +#### 3. ローカル開発サポート + +Netlify は CLI ツールを提供しており、ローカルでの開発とテストに便利です: + +```bash +# Netlify CLI のインストール +npm install -g netlify-cli + +# ログイン +netlify login + +# ローカル開発サーバーの起動 +netlify dev + +# ローカルでの関数テスト +netlify functions:serve +``` + +CLI ツールを使用すると、ローカルで Netlify 環境をシミュレートでき、フォーム送信や関数呼び出しなどの機能も含まれ、デプロイ前のテストに便利です。 + +--- + +# 4. Zeabur + +Zeabur は新興のデプロイプラットフォームで、複数のサービスをデプロイする必要がある複雑なプロジェクトに特に適しています。その利点は以下の通りです: + +- **豊富なサービステンプレート**:Dify、n8n、データベースなど、多くのサービステンプレートが組み込まれている +- **複数のデプロイ方法をサポート**:GitHub、テンプレート、Docker イメージ、ローカルプロジェクトなど +- **柔軟なサービスの組み合わせ**:1つのプロジェクトで複数の相互に関連するサービスをデプロイ可能 +- **従量課金**:使った分だけ支払い、実験的なプロジェクトに適している + +## Zeabur を使用した Dify のデプロイ + +以前のレッスンで、Dify に簡単に触れました。ここでは、[Zeabur](https://zeabur.com) を通じて、自分自身の Dify サービスを非常に簡単に立ち上げることができます。まず[コンソールページ](https://dash.zeabur.com)を開き、ページ上の各エリアを見てみましょう。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image5.png) + +このページでは、まず多くのブロックが見えます。これらはすでに起動しているサービスです。上部メニューには、Agent、Servers、Docs、Templates などのオプションがあり、それぞれ以下を表しています: + +1. **Agent**:Zeabur 内蔵の AI アシスタント(Agent)を開くことができ、操作方法の質問や、現在のサーバーのステータスの確認ができます。 +2. **Servers**:ここで自分で購入したクラウドサーバーを追加したり、Zeabur 経由で直接サーバーを購入したりできます。 +3. **Docs**:Zeabur の完全なドキュメントを確認できます。 +4. **Templates**:ここにはすべての組み込みテンプレートイメージがリストされています。 + +> ここで言及する「イメージ(Image)」は、「コードと実行環境を含む圧縮パッケージ」と考えることができます。あるサービスが1台のサーバー上で正常に稼働した後、「この実行環境 + コード」をパッケージ化してイメージにすることができます。その後、新しいサーバーでは、この圧縮パッケージを展開して実行するだけで、環境とコードの再設定なしにサービスを直接稼働させることができます。 + +ページの右上隅には、自分の残高も表示されます。デフォルトでは、毎月約5ドルの無料枠があります。詳細な課金ルールについては、今はあまり気にする必要はありません。サーバーが稼働している限り、枠を消費することだけ覚えておけば十分です。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image6.png) + +残高をクリックすると、毎日の消費明細を確認できます。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image7.png) + +それでは、自分自身の Dify サービスを作成しましょう。まず、[コンソールホーム](https://dash.zeabur.com)で「New Project」をクリックします。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image8.png) + +次に、各作成方法の説明です: + +1. **GitHub** + あなたの GitHub アカウントに接続できます。バインド後、GitHub リポジトリから直接プロジェクトを選択してデプロイできます(GitHub は現在、世界最大のコードホスティングプラットフォームです)。 +2. **Template(テンプレート)** + テンプレートに基づいてサービスをデプロイできます。Zeabur には多くのプリセットプロジェクトテンプレート(例:Dify、n8n など)が組み込まれており、これらのテンプレートに基づいてアプリケーションを迅速に作成・デプロイできます。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image9.png) +3. **Databases(データベース)** + データベースサービスのデプロイに使用します。例:MySQL、MongoDB などの一般的なデータベース。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image10.png) +4. **Functions(関数)** + 関数サービスをデプロイできます。JavaScript や Python のコードを記述し、関数として呼び出すことができます。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image11.png) + + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image12.png) + +5. **Local Project(ローカルプロジェクト)** + ローカルのフォルダをアップロードすると、Zeabur が自動的に起動スクリプトを識別します。これは、すでにローカルで開発済みのプロジェクトを Zeabur に迅速にデプロイするのに適しています。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image13.png) +6. **Docker Image** + すでにパッケージされた Docker イメージをデプロイします。プロジェクトがすでに Docker イメージとしてパッケージされている場合(例:Docker Hub や他のイメージリポジトリに保存されている場合)、ここで直接デプロイできます。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image14.png) +7. **Cursor** + Cursor(例:Cursor IDE)をインストールしている場合、この入口から Cursor 内のプロジェクトを直接 Zeabur にデプロイできます。 + +自分自身の Dify サービスをデプロイしたい場合は、**Template** 方式を選択し、検索ボックスに「dify」と入力することをお勧めします。異なる作者がメンテナンスする多くのバージョンが表示されますので、その中から1つを選択してください(例:v1.6.0 バージョンなど)。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image15.png) + +続いて、任意の名前を入力すると、Zeabur がその名前に基づいて一時的なカスタムドメインを生成します。その後、誰もがこの URL を通じてあなたのサービスにアクセスできるようになります。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image16.png) + +作成完了後、複数のプログラム(サービス)が順番に起動するのが見えます。すべてのサービスが「起動済み」のステータスになるまで、しばらくお待ちください。(Dify サービスは複数のプログラムで構成されており、各プログラムが異なる機能を担当し、それらが相互に連携して動作します。) + +通常、左側の Dify アプリケーションをクリックするだけで、デフォルトのアクセス入口アドレスが表示されます。ただし、この例では、前面に nginx というレイヤーが挟まっているため、nginx サービスをクリックして最終的なアクセスアドレスを取得する必要があります。nginx は、外部との統一的な「リクエストの送受信」を担当するメインプログラムと考えることができます。外部からのアクセスアドレスを内部の各サービスに分配します。左側の Nginx をクリックし、詳細ページで現在のサービスアドレスを確認し、そのアドレスをブラウザで開いて、サービスが完全に起動するのを待ちます。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image17.png) + +しばらく待つと、Dify のログイン画面が表示されます。メールアドレスと登録パスワードを入力すれば、自分自身の Dify サービスを使い始めることができます。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image18.png) + +興味があれば、ついでに n8n サービスも立ち上げてみてはいかがでしょうか。n8n も海外で非常に人気のある AI ワークフロープラットフォームです。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image19.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image20.png) + +## Zeabur と Trae を使ったスネークゲームのデプロイ + +本チュートリアルの次のパートでは、Zeabur のいくつかの応用的な使い方を体験します。まず Trae を使ってスネークゲームを生成し、それを Zeabur のサーバーにデプロイし、誰もがアクセスできる公開リンクを設定します。 + +ステップ1は、ローカルで Trae を使ってスネークゲームのプロジェクトを作成することです。 + +### HTML フレームワークでの実装 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image23.png) + +Trae にとって、HTML ベースのスネークウェブゲームを生成するのは非常に簡単です。ゲームの生成が完了したら、前述の Zeabur のローカルデプロイ方法に従って、すべてのファイルを含むフォルダをアップロードするだけです。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image24.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image25.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image26.png) + +完了後、そのサービスの詳細画面に進みます: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image27.png) + +左側の「Network」オプションをクリックし、ページ内の「Public Address」エリアを見つけます。「Generate Domain」をクリックすると、外部アクセス用のアドレスが生成されます。好きな名前を入力できます。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image28.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image29.png) + +生成完了後、ブラウザでこのアドレスを開くだけで、自分自身のスネークゲームを実行できます。他の HTML タイプの Web アプリケーションも、まったく同じ方法でデプロイ可能です。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image30.png) + +### React フレームワークでの実装 + +前のセクションでは、HTML ベースの Web アプリケーションのデプロイ方法を学びました。次に、現在より一般的に使用されているフロントエンドフレームワークである React アプリケーションのデプロイを試みます。純粋な HTML と比較して、React はより成熟したモダンなフロントエンド開発フレームワークと見なされています。コンポーネント化された方法でページ構造を編成し、複雑なページの開発を大幅に高速化でき、エンタープライズ級のプロジェクトで非常に主流の選択肢です。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image31.png) + +#### React アーキテクチャへのリファクタリング + +Trae では、Agent に「このコードを React アーキテクチャにリファクタリングしてください」と伝えるだけで、元の HTML ベースの構造をかなり簡単に React プロジェクトにリファクタリングできます。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image32.png) + +ただし、シンプルな HTML ファイルと比較して、React アプリケーションはより複雑なビルドツールとプロジェクト構造に依存するため、デプロイのプロセスも少し面倒になります。典型的な問題はポート設定にあります:デフォルトでは、React アプリケーションは通常ポート3000をリッスンします(設定ファイルや起動ログでもこれを確認できます)。 + +しかし、Zeabur ではこのままデプロイすると失敗します。なぜなら、Zeabur はポート8080をリッスンするアプリケーションしかサポートしていないからです。つまり、React アプリケーションを Zeabur 上で正常に動作させるには、まずデフォルトのリッスニングポートを3000から8080に変更する必要があります。 + +この設定を正しく行うには、まず2つの概念を明確にする必要があります:「ポート(Port)」とは何か、そして「リッスニングポート(Listening Port)」とはどういう意味かです。 + +#### ポートとは何か? + +> コンピュータネットワークにおいて、ポートは「論理的な通信の端点」として理解でき、同じデバイス上で動作する異なるネットワークサービスを区別するために使用されます。簡単に例えると、IP アドレスが「住所」(例:162.128.1.1)だとすれば、ポート番号はその建物内の異なる部屋の「部屋番号」のようなものです。各部屋が1つのサービスに対応しています(例:Web サーバー、メールサービス、あなたの React アプリケーションなど)。 +> +> ポート番号は16ビット整数で表され、値の範囲は0から65535です。 + +これらの詳細を覚えたくない場合は、シンプルに「ポートはネットワークアクセスアドレスを構成する必須要素」と理解すれば十分です。 + +私たちが通常ウェブサイトや IP アドレスにアクセスする際、ポート番号を手動で追加することはめったにありません。なぜなら、Web のデフォルトポートは80または443(HTTPS)だからです。ほとんどのブラウザはこれらの標準ポートを自動的に使用します。特別なポート、例えば React のデフォルト3000や Zeabur が要求する8080については、アドレスの後に`:3000`や`:8080`を追加しなければ対応するコンテンツにアクセスできません。 + +#### 「リッスニングポート番号」とは何か? + +> 「リッスニングポート番号」とは、あるプログラムがデバイス上で自発的に「開き、監視している」ポートのことです。アプリケーションがリッスニングポートを設定したということは、オペレーティングシステムに「私はこのポートでネットワークリクエストを待ち続けます。リクエストが来たら、私に転送してください」と伝えていることになります。 + +さらに分かりやすく例えると:あなたのパソコンが1棟のオフィスビルだとします。IP アドレスはこのビルの住所です。ビル内には多くの会社や部署があり、それぞれが異なる部屋を占有し、部屋番号がポート番号です。 + +React のデフォルト開発サーバーが起動すると、ある部屋のドアを「開け」、そのドアに「受付」を配置します。この部屋番号がリッスニングポート——3000です。 + +さらに、React プログラムはビルの「管理会社」(オペレーティングシステム)に「私は3000号室にいます。3000宛てのすべての郵便物(ネットワークリクエスト)を私に転送してください」と伝えます。 + +このように、あなたが React ウェブサイトにアクセスすると、リクエストはまずこのビルに到達し、管理会社はリクエストが3000号室宛てであることを確認すると、すぐに React の「受付」にリクエストを渡します。受付が処理して結果を返す——これが React アプリケーションにアクセスするプロセスです。 + +ローカルで`npm start`を実行すると(React 開発サーバーを起動するデフォルトコマンドで、Vibe Coding の Agent サイドバーでも実行可能)、React 開発サーバーは自動的にリッスニングポートを3000に設定します。 +一方、Zeabur のプラットフォーム設計により、ポート8080をリッスンするアプリケーションしか「認識」しません。React アプリケーションがデフォルトの3000ポートを使用したままだと、Zeabur はリクエストをアプリケーションに正しく転送できず、結果的にデプロイが失敗します。 + +#### デフォルトのリッスニングポートの変更 + +React のデフォルトリッスニングポート(3000)を Zeabur が要求する8080に変更するには、多くの方法があります。最も簡単な方法は、Trae で Agent に「この React プロジェクトのデフォルトポートを8080に変更してください」と指示することです。Trae がプロジェクト内の対応する設定ファイルを変更してくれます。変更完了後、再ビルドして前述の方法で Zeabur にアップロードするだけです。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image33.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image34.png) + +ネットワーク設定でアクセス URL を指定する方法は、HTML プロジェクトのデプロイ時とほぼ同じで、React バージョンのサービスを起動できます。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image35.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image36.png) + +他のポート番号の変更が必要なプログラムについても、同じアプローチを採用できます:まずデフォルトポートを変更し、Zeabur にアップロードしてデプロイします。以上で、一般的な Web アプリケーションをサーバーにデプロイする基本的なスキルを習得しました。 + +Trae に異なるタイプのアプリケーションを構築してもらい、それらを Zeabur のデフォルトサーバーにデプロイしてみてください。今後のレッスンでは、アプリケーションを自分で購入したクラウドサーバーにデプロイする方法も学びます。 + +--- + +# ⚠️ プロジェクトの停止と削除方法(Zeabur) + +サーバー関連のリソースを有効にすると料金が発生するため、使用しないサービスはこまめに停止する習慣を身につけ、毎月の無料枠を使い切らないようにしましょう。 + +プロジェクトの管理画面を見つけるには、まずプロジェクト内の「Settings」オプションをクリックします。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image21.png) + +設定ページに入ったら、ページを一番下までスクロールすると、次のような画面が表示されます: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image22.png) + +「Suspend All Services」をクリックしてすべてのサービスを一時停止し、コストを削減できます。サービスに問題が生じた場合は、「Restart All Services」をクリックしてすべてのサービスを再起動できます。このプロジェクトがもう必要ないことが確実な場合は、「Delete Project」をクリックしてプロジェクト全体を完全に削除できます。 + +--- + +# まとめ + +本チュートリアルでは、4つの一般的な Web アプリケーションデプロイプラットフォームを紹介しました: + +1. **Tencent CloudBase**:中国国内のユーザーに適しており、アクセスが速く、WeChat エコシステムとの統合が良好 +2. **Vercel**:モダンフロントエンドフレームワークプロジェクトに適しており、GitHub との統合が緊密、グローバル CDN 加速 +3. **Netlify**:機能が充実、フォーム処理と認証をサポート、高度な機能を必要とする静的サイトに適している +4. **Zeabur**:複雑なプロジェクトに適しており、サービステンプレートが豊富、複数のデプロイ方法をサポート + +どのプラットフォームを選ぶかは、あなたの具体的な要件によって異なります: +- 主に中国国内のユーザー向けの場合は、**CloudBase** をお勧めします +- React/Next.js などのフレームワークを使用する場合は、**Vercel** または **Netlify** をお勧めします +- フォーム処理や認証などの高度な機能を必要とする場合は、**Netlify** をお勧めします +- Dify、n8n などのサービスをデプロイする必要がある場合は、**Zeabur** をお勧めします + +どのプラットフォームを選んでも、デプロイのコアプロセスは同じです:コードの準備 → プラットフォームの選択 → ビルド設定 → デプロイして公開。これらのスキルを身につければ、自分が開発したアプリケーションを世界中の人に共有できるようになります! diff --git a/docs/ja-jp/stage-2/frontend/design-to-code/index.md b/docs/ja-jp/stage-2/frontend/design-to-code/index.md new file mode 100644 index 0000000..a14506f --- /dev/null +++ b/docs/ja-jp/stage-2/frontend/design-to-code/index.md @@ -0,0 +1,361 @@ +# デザインプロトタイプからプロジェクトコードへ + +::: tip 🎯 核心的な問い +**デザインツールのプロトタイプをブラウザで動くフロントエンドコードに変換するには?** +::: + +--- + +## 1. プロトタイプからコードへの3つのパス + +Figma、MasterGoなどのモダンなフロントエンドデザインツールでインターフェース設計を完了した後、一つの非常に実際的な問題が自然に浮かび上がります:これらの構造的に完全なデザイン稿を、どうやってブラウザで実際に動くフロントエンドコードに変換するのか? + +一般的に、プロトタイプからコードへの落とし込みには、本質的に3つの典型的なパスがあります: + +| パス | 方法 | 特徴 | 適用シーン | +|------|------|------|----------| +| **パス1** | 画像に基づき、マルチモーダル大規模モデルで直接コードを復元 | 柔軟、特定のツール不要 | 迅速なプロトタイピング検証、シンプルなページ | +| **パス2** | プラットフォーム自身の機能やプラグインで使用可能なコードをエクスポート | 再現度が高い、編集可能 | Figma/MasterGoユーザー | +| **パス3** | プラットフォームとMCP機能を組み合わせて使用可能なコードをエクスポート | 自動化度が高い、カスタマイズ可能 | 深い統合が必要なワークフロー | + +本記事では、これら3つのパスの具体的な実装方法を詳しく紹介し、プロジェクトのニーズに応じて最も適切なワークフローを選択できるようにします。 + +::: tip 📚 前提知識 +本節を始める前に、[FigmaとMasterGo入門](../figma-mastergo/)チュートリアルを先に学び、フロントエンドデザインツールの基本操作をマスターすることをお勧めします。 +::: + +--- + +## 2. パス1:マルチモーダルAIによる直接コード復元 + +視覚能力を持つ大規模モデルは、生来画像をコードに変換する能力を備えています。デザイン稿のスクリーンショットを直接ダイアログにインポートし、大規模モデルに完全な結果コードを生成させるだけです。 + +### 2.1 操作フロー + +1. **デザイン稿の画像をキャプチャ** + - FigmaまたはMasterGoで、設計したページをPNGまたはJPGにエクスポート + - スクリーンショットに完全なページレイアウトが含まれていることを確認 + +2. **マルチモーダルAIモデルを選択** + - Gemini、Qwen、Claudeなどの画像入力をサポートするモデルを使用可能 + - ここではGeminiを例にデモを行います + +3. **プロンプトを作成** + ``` + このデザイン画像に基づいて対応するHTML/CSSコードを生成してください。 + 要件: + - モダンなCSSレイアウト(Flexbox/Grid)を使用 + - レスポンシブデザイン、異なる画面サイズに対応 + - すべての可視UI要素を含める + - 色、フォントサイズはできる限りデザイン稿に忠実に + ``` + +![](/zh-cn/stage-2/frontend/design-to-code/images/image42.png) + +4. **コードを取得して保存** + - モデルに完全なHTMLコードを返却させるよう要求 + - 単一の`.html`ファイルとして保存し、ローカルテストに便利 + - 後でローカルIDEでReactなどのフレームワークに変換可能 + +### 2.2 よくある問題と解決策 + +生成されたページはシンプルな作業ではなく、具体的な過程で多くの問題に直面する可能性があります: + +| 問題 | 解決策 | +|------|----------| +| インターフェースの配置が不均一 | AIに具体的なレイアウトの問題を説明し、CSSのmargin/paddingの調整を要求 | +| インターフェースの表示が不完全 | 正しいviewportが設定されているか確認し、レスポンシブブレイクポイントの追加を要求 | +| 色の再現が不正確 | カラーピッカーツールでデザイン稿の正確な色値を取得し、AIに提供 | +| フォントが一致しない | 具体的なフォント名を指定するか、Google Fontsの代替使用を要求 | + +::: tip 💡 コツ +まずHTMLコードを生成し、取得後にローカルIDEでReactフレームワークに変換することをお勧めします。これにより複数の独立したHTMLファイルが得られ、フレームワーク変換を一括して行えます。 +::: + +### 2.3 MasterGo AIによるページ生成 + +MasterGoも強力なAIページ生成機能を提供しており、参考画像に基づいて直接使用可能なWebコードを生成できます。 + +#### AI機能の入り口を見つける + +MasterGo編集画面の上部ツールバーに、AIツールボタンがあります: + +![](/zh-cn/stage-2/frontend/design-to-code/images/image47.png) + +#### 生成フロー + +1. **参考画像をアップロード** + - マルチモーダルAIと同じ方法でデザインの参考画像をアップロード + - テキストで要件を説明 + +2. **生成結果を確認** + +![](/zh-cn/stage-2/frontend/design-to-code/images/image48.png) + +![](/zh-cn/stage-2/frontend/design-to-code/images/image49.png) + +3. **コードを取得** + - 青いボタン「キャンバスに挿入」をクリックし、生成後のWebページを直接編集 + - または右側の「コード」ボタンをクリックし、コード内容をローカルにコピー + +![](/zh-cn/stage-2/frontend/design-to-code/images/image50.png) + +--- + +## 3. パス2:プラットフォーム自身の機能やプラグインでコードをエクスポート + +### 3.1 Figma Makeによるコード生成 + +Figma MakeはFigma公式が提供するAIデザインツールで、ユーザーが入力したプロンプトまたは参考画像に基づいて、高精度にWebプロトタイプUIインターフェースを復元できます。 + +#### 機能の特徴 + +- **高精度な復元**:ネイティブAI生成コードに比べ、より良い効果 +- **編集可能性**:生成結果を編集可能なFigma Designファイルに変換可能 +- **GitHub統合**:コードを直接GitHubに同期する機能をサポート + +::: tip 🔑 権限について +Figma Makeの完全な機能を使用するにはProユーザー権限が必要です。学生は教育認証を通じて無料でPro権限を取得できます。 +::: + +#### 操作手順 + +1. **Figma Makeに入る** + - FigmaのホームページでMakeボタンをクリック + - または[Figma Make](https://www.figma.com/make)にアクセス + +2. **参考画像をアップロード** + - 復元したいデザイン画像をダイアログにアップロード + - 要件を説明するプロンプトを追加 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image43.png) + +3. **生成結果を確認** + - しばらく待つとレンダリング結果が表示 + - 右上の再生ボタンをクリックしてフルスクリーンプレビュー + +![](/zh-cn/stage-2/frontend/design-to-code/images/image44.png) + +4. **ディテールの調整** + - 右上の編集アイコン(マウスと定規のアイコン)をクリック + - おなじみのFigma Editorインターフェースに戻り、詳細な調整を行う + +![](/zh-cn/stage-2/frontend/design-to-code/images/image45.png) + +5. **コードをエクスポート** + - 調整に満足したら、コードのエクスポートを選択 + - GitHubに直接接続してコードを保存可能 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image46.png) + +### 3.2 プラグインによるコードエクスポート + +プラットフォームのネイティブAI機能に加えて、FigmaとMasterGoはどちらもプラグインによるコードエクスポートをサポートしています: + +**よく使われるFigmaプラグイン:** +- **Figma to Code**:デザイン稿をReact、Vue、HTMLなどのコードに変換 +- **Anima**:高忠実度なコード生成、インタラクション効果をサポート +- **Locofy**:AI駆動のデザインからコードへのツール + +**使用手順:** +1. Figmaでプラグインパネル(Plugins)を開く +2. 必要なコードエクスポートプラグインを検索してインストール +3. エクスポートするデザイン要素を選択 +4. プラグインを実行し、ターゲットフレームワークとコード形式を選択 +5. 生成されたコードをコピーまたはダウンロード + +--- + +## 4. パス3:プラットフォームとMCP機能を組み合わせてコードをエクスポート + +### 4.1 MCPとは? + +MCP(Model Context Protocol、モデルコンテキストプロトコル)は、AIモデルが外部ツールやデータソースに安全かつ制御可能にアクセスできるようにするオープン標準プロトコルです。フロントエンドデザインツールのシーンでは、MCPは大規模モデルがデザインファイルの構造、スタイル、コンポーネント情報を直接読み取ることを可能にし、より正確なコード生成を実現します。 + +### 4.2 MCPの動作原理 + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ AIモデル │ ←→ │ MCPサーバー │ ←→ │ デザインツール │ +│ (Claude等) │ │ (プロトコル適配) │ │(Figma/MasterGo)│ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +**ワークフロー:** +1. AIモデルがMCPプロトコルを通じてデザインツールにリクエストを送信 +2. デザインツールが構造化されたデザインデータ(レイヤー、スタイル、コンポーネントなど)を返却 +3. AIモデルがデザイン構造を理解し対応するコードを生成 +4. コードを直接エクスポートまたは開発環境に同期 + +### 4.3 Figma + MCP実践 + +#### 環境の準備 + +1. **MCPサーバーのインストール** + ```bash + # Figma MCPサーバーをnpxでインストール + npx figma-mcp-server + ``` + +2. **Claude Desktopまたは他のMCP対応AIツールの設定** + ```json + { + "mcpServers": { + "figma": { + "command": "npx", + "args": ["figma-mcp-server"], + "env": { + "FIGMA_ACCESS_TOKEN": "your-figma-token" + } + } + } + } + ``` + +3. **Figma Access Tokenの取得** + - Figmaにログイン → Settings → Personal Access Tokens + - 新しいTokenを生成して保存 + +#### 使用フロー + +1. **AIツールでMCP接続を有効にする** + - Claude Codeまたは他のMCP対応IDEを開く + - MCPサーバーが接続されていることを確認 + +2. **デザインファイルのリンクを提供** + ``` + ユーザー:このFigmaデザインをReactコードに変換してください + リンク:https://www.figma.com/file/xxxxx + + AI:MCPを通じてFigmaに接続し、デザインファイルの構造を読み取っています... + ``` + +3. **AIが自動的に分析しコードを生成** + - MCPサーバーがデザインファイルのレイヤーツリーを取得 + - AIがコンポーネント構造とスタイル属性を理解 + - 正しい命名と構造を持つReact/Vueコンポーネントを生成 + +4. **イテレーションと最適化** + ``` + ユーザー:ボタンコンポーネントを独立した再利用可能なコンポーネントとして抽出してください + + AI:MCPを通じてデザインシステムのButtonコンポーネントを特定しました。 + propsインターフェースを持つReactコンポーネントを生成しています... + ``` + +### 4.4 MCPの利点 + +| 特徴 | 従来の方法 | MCP方式 | +|------|----------|----------| +| **データ精度** | スクリーンショットに依存、ディテールが失われる可能性 | オリジナルのデザインデータを直接読み取り | +| **コンポーネント認識** | AIがコンポーネントの境界を推測する必要がある | コンポーネント定義を正確に取得 | +| **スタイルの復元** | ピクセルベースの推定 | 正確なデザイントークンを取得 | +| **イテレーション効率** | 毎回の変更でスクリーンショットを再取得 | デザイン変更をリアルタイムで同期 | +| **自動化度** | 手動でコピー&ペースト | プロジェクトファイルに直接書き込み可能 | + +### 4.5 現在利用可能なMCPツール + +**デザインツールMCP:** +- **Figma MCP Server**:公式サポートのMCP実装 +- **MasterGo MCP**:コミュニティ開発のMasterGoアダプタ + +**開発環境MCP:** +- **Claude Code**:MCPプロトコルをネイティブサポート +- **Cline**:VS Codeプラグイン、MCP接続をサポート +- **Trae**:設定でMCP機能を有効化可能 + +::: tip 🔮 将来の展望 +MCPプロトコルは急速に発展しており、将来的にはデザインツールと開発環境の統合がさらに緊密になるでしょう。デザインからコードへのワンクリック同期ソリューションがさらに登場し、デザインと開発の距離をさらに縮めると予想されます。 +::: + +--- + +## 5. コードエクスポート後の作業 + +### 5.1 ローカルテスト + +コードを取得したら、ローカルIDEで開いてテストします: + +1. **新規プロジェクトの作成** + ```bash + # HTMLファイルの場合、ブラウザで直接開く + open index.html + + # React/Vueプロジェクトの場合 + npm install + npm run dev + ``` + +2. **AI IDEとの協業** + - 生成されたコードをTraeや他のAI IDEにインポート + - AIにレイアウト問題の修正やインタラクション機能の追加を支援させる + +### 5.2 よくある問題の処理 + +| 段階 | 問題 | 解決策 | +|------|------|----------| +| レイアウト | 要素のずれ | CSSのdisplayとposition属性を確認 | +| スタイル | 色が一致しない | ブラウザの開発者ツールで実際に適用されている色値を確認 | +| レスポンシブ | モバイルでの表示が異常 | media queryのブレイクポイントを追加 | +| インタラクション | ボタンが反応しない | JavaScriptのイベントバインディングを確認 | + +--- + +## 6. 3つのパスの比較と選択の提案 + +### 6.1 パスの比較 + +| 次元 | パス1:マルチモーダルAI | パス2:プラットフォーム機能 | パス3:MCP | +|------|------------------|------------------|-------------| +| **難易度** | ⭐ 簡単 | ⭐⭐ 中程度 | ⭐⭐⭐ やや複雑 | +| **再現精度** | ⭐⭐⭐ 中程度 | ⭐⭐⭐⭐ 高い | ⭐⭐⭐⭐⭐ 最高 | +| **柔軟性** | ⭐⭐⭐⭐⭐ 高い | ⭐⭐⭐ 中程度 | ⭐⭐⭐⭐ やや高い | +| **自動化度** | ⭐⭐ 低い | ⭐⭐⭐ 中程度 | ⭐⭐⭐⭐⭐ 高い | +| **コスト** | 低い(API呼び出しに基づく) | 中程度(Proが必要な場合も) | 低い(オープンソースツール) | + +### 6.2 選択の提案 + +**パス1(マルチモーダルAI)を選ぶ場合:** +- アイデアを素早く検証する必要がある +- デザインツールが固定されておらず、頻繁に切り替える +- 再現精度の要求が高くない +- 予算が限られている + +**パス2(プラットフォーム機能)を選ぶ場合:** +- チームが主にFigmaまたはMasterGoを使用 +- 高精度なコード復元が必要 +- デザイナーと開発者が頻繁に協業する必要がある +- Pro版に投資する意思がある + +**パス3(MCP)を選ぶ場合:** +- 最高レベルの自動化を追求 +- MCP環境を構築する技術力がある +- プロジェクトでデザインからコードへの頻繁なイテレーションが必要 +- 標準化されたデザイン→開発ワークフローを構築したい + +--- + +## 7. まとめ + +本章の学習を通じて、デザインプロトタイプからコードへの3つのコアパスをマスターしました: + +1. **マルチモーダルAIによる直接変換**:柔軟で高速、プロトタイピング検証に適する +2. **プラットフォームのネイティブ機能**:再現度が高く、プロのデザインワークフローに適する +3. **MCPプロトコル統合**:自動化度が最も高く、未来のトレンドを代表 + +::: tip 💡 ベストプラクティス +- **初心者におすすめ**:パス1(マルチモーダルAI)から始め、素早くキャッチアップ +- **チーム協業**:パス2(プラットフォーム機能)を使用し、デザインの一貫性を保証 +- **効率優先**:パス3(MCP)を試み、自動化ワークフローを構築 +- **混合使用**:プロジェクトの段階に応じて柔軟に異なるパスを切り替え +::: + +--- + +## 参考リソース + +- [FigmaとMasterGo入門](../figma-mastergo/) - デザインツールの基礎を学ぶ +- [ホグワーツ肖像画を作ろう](../hogwarts-portraits/) - 完全なプロジェクトの実践 +- [MCP公式ドキュメント](https://modelcontextprotocol.io/) - プロトコルの詳細を理解 +- [Figma Make公式ドキュメント](https://help.figma.com/hc/en-us/sections/360007453634-Figma-Make) +- [MasterGo AIチュートリアル](https://mastergo.com/tutorials) diff --git a/docs/ja-jp/stage-2/frontend/figma-mastergo/index.md b/docs/ja-jp/stage-2/frontend/figma-mastergo/index.md new file mode 100644 index 0000000..74d5a4a --- /dev/null +++ b/docs/ja-jp/stage-2/frontend/figma-mastergo/index.md @@ -0,0 +1,303 @@ +# FigmaとMasterGo入門 + + + +::: tip 🎯 核心的な問い +**ゼロからモダンなデザインツールを使ってWebプロトタイプを作成するには?** +::: + +--- + +## 1. なぜフロントエンドデザインツールを学ぶのか? + +始める前に、一つの疑問を理解する必要があります:なぜ「フロントエンドデザインツール」を学ぶ必要があるのでしょうか?HTML / CSSコードを直接書いてもページを作れるのに、ソフトウェアと技術をもう一つ学ぶことは本当に必要でしょうか? + +実際、ページを動かすことと、プロダクトを良く設計することは全く別の概念です。コードはブラウザでどうレンダリングするか、異なるデバイスでどう動くかという問題にしか関心がありません。フロントエンドデザインツールが解決するのは、情報配置の問題です。フロントエンドのインタラクションをどう配置するか、異なるページ間の遷移をどうするか、視覚的優先順位をどう配分するかといった問題です。デザインツールでキャンバスを作るだけで、版面、情報階層、インタラクション方法を1つの画面で比較検討し、最も適切な表現効果を選ぶことができます。 + +直接コードを書いたり、AIで完全なフロントエンドページを生成したりすると、通常ユーザー体験はあまり良くありません。厳密なプロダクトはユーザーとフロントエンドのインタラクションの快適さや、異なるページで伝えたいコンテンツの分布を考慮し、ユーザーの視点からまずフロントエンドページの配置を行い、その後コード変換や生成を行います。 + +また、チーム協業の観点から見ると、フロントエンドデザインツールは関係者の協力コストを下げます:デザイナー、プロダクトマネージャー、開発者がそれぞれの想像や抽象的なコード説明に頼るのではなく、リアルタイム協業をサポートし、可視化され、注釈可能で、反復可能なキャンバスを中心に、バージョン管理、要件変更、フィードバックについて議論できます。さらに、モダンなフロントエンドデザインツール自体がもはや単なる描画ソフトではなく、ワンクリックでコードの一部を生成し、デザインシステムとコンポーネントライブラリを管理できます。新时代のデザインツールは、多くの反復的な手作業(整列、注釈、エクスポート、スタイル変更)を自動化・バッチ化し、ページ設計の開発効率を大幅に促進しています。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image8.png) + +### 1.1 フロントエンドデザインツールの変遷 + +歴史を振り返ると、いわゆるフロントエンドデザインツールは継続的に進化してきた技術です。90年代のローカルビットマップ編集中心のPhotoshop時代から、2010年前後のSketchによるベクター化・コンポーネント化ワークフロー、そして2016年以降のFigmaによるクラウド上での協業の完全実現まで、デザインチームは単独作業からリアルタイムマルチユーザー協業へと移行しました。2025年に至り、AIは既にこれらのツール内部に実用的に組み込まれています:「一言の指示からページドラフトを生成」から「デザイン稿を直接実行可能なフロントエンド構造に変換」まで、「デザイン即コード」「人機共创」が概念から利用可能な生産力へと変わりつつあります。 + +本節では、最も代表的な2つのモダンなフロントエンドデザインツールを紹介します:FigmaとMasterGoです。一方で、これらはモダンなUI/UXに必要な核心機能(ベクター編集、コンポーネントシステム、自動レイアウト、コード受け渡しなど)を網羅しており、ワイヤーフレームからハイファイデリ、開発引き渡しまでの完全なループをサポートします。他方で、これらのツールはどちらも2025年以降、実用的なAI機能を追加しており、プロトタイプを維持しながらデザイン画像を本当に実行可能なプログラムに変換するのを支援します。 + +## 1.2 誕生の旅 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image9.png) + +モダンなフロントエンド専用ツールが誕生する前の時代、インターフェースデザイン業界の視覚デザイン作業は長い間、Photoshopのような「万能型」デザインソフトが兼任していました。デザイナーはローカルでレイヤーを重ねて、ページ全体の視覚効果を細かく設計し、最終的にサイズの大きい.psdソースファイルをフロントエンドエンジニアに納品していました。フロントエンドがデザイン画像を正確に再現するには、3つの煩雑で重要な作業を手動で完了する必要がありました: + +1つ目は「スライス」:.psdファイルの多層構造から、ボタン、アイコン、ロゴ、背景モジュールなどの独立した視覚要素を一つずつ分割・抽出し、PNG、JPGなどのWebブラウザが直接読み込める画像形式にエクスポートする必要がありました(WebブラウザはPSDのレイヤー情報を直接認識できず、分割された画像に依存してディテールを表示するため)。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image10.png) + +2つ目は「寸法測定」:ソフトウェアの測定ツールを使って、各要素の幅・高さ、異なるモジュール間のマージン(margin/padding)などのデータを一つずつ確認し、すべての寸法がピクセル単位で正確であることを保証する必要がありました。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image11.png) + +3つ目は「注釈の抽出」:デザイン画像から「見えないが必須の」暗黙パラメータを抽出する必要がありました。例えば、テキストのフォントサイズ、ウェイト、行間、各カラーブロックのRGBやHEXカラー値など、デザイナーが紙に書いていない「設計仕様」を手動で「抽出」して記録する作業でした。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image12.png) + +その後、フロントエンドの実装段階が本格的に始まりました。ネイティブのHTML/CSS/JSであれ、Vue、Reactなどのフレームワークであれ、本質的なプロセスは同じです。フロントエンドは「コンテナを核心的なキャリア」として、设计中の各モジュールの階層とセマンティクスに従ってページ構造を再構築します。ここでのコンテナとは、明確なレイアウト境界を持ち、子要素を専門に保持・整理する単位を指し、具体的なコンテンツを直接表示するのではなく、Flex、Gridなどのルールを通じて内部要素の配置範囲を定めます。そして「構造ブロック」(トップナビゲーションバー、サイドバー、記事リストエリア、フッターなど目で見える機能/コンテンツエリア)は、コンテナに依存して存在します。各構造ブロック内部には、さらに小さなコンテナがネストされて要素を整理します。例えば、1つの記事リスト項目は「リスト項目コンテナ」が内側の余白と全体レイアウトを制御し、さらにタイトル、要約、時間、カバー画像などの詳細要素を包み込みます。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image13.png) + +モダンなフロントエンドフレームワークでは、これらの「構造ブロック(および関連するコンテナと要素)」は通常「コンポーネント」として実装されます。コンポーネントは簡単に言えば、明確な境界を持ち、コンテナレイアウトとロジックを統合した再利用可能なインターフェース単位です。外観と配置を制御するコンテナ(例えば「ボタンコンポーネント」はコンテナで幅・高さ、角丸を定義し、「記事カードコンポーネント」はコンテナでタイトル、カバーの位置を整理)を含むだけでなく、インタラクションロジックもカプセル化します。デザイン稿に繰り返し登場し、形が統一されている部分(統一スタイルのボタン、繰り返し使用される記事カードなど)は、コード内でコンポーネントに抽象化されます:異なるページ/シーンで再利用でき、重複開発を減らすだけでなく、コンポーネント内コンテナの統一ルールにより、すべての再利用箇所のレイアウトとスタイルの高い一貫性を保証します。 + +その後、フロントエンドはスタイルシステムを使って視覚とレイアウトを再現します。スライス段階でエクスポートされたPNG/JPGなどのリソースは、コンポーネントや構造ブロック内部の``、背景画像として、または各フレームワーク推奨の静的アセット方式でインポートされます。寸法測定段階で得られた幅・高さ、間隔、行の高さなどの具体的な数値は、`width`、`height`、`margin`、`padding`、`line-height`などのスタイルプロパティに変換され、対応するコンポーネントや構造ブロックに適用されます。注釈抽出段階で整理された色、フォント、シャドウ、角丸、hover/activeなどの状態は、CSS、CSS Modules、CSS-in-JS、Tailwindなどの具体的なスキームにおける`color`、`font-family`、`font-size`、`box-shadow`、`border-radius`および擬似クラスや状態クラス名に落とし込まれます。この時点で、スライス、寸法、注釈が提供するのは一連の正確な視覚パラメータであり、コンポーネントと構造ブロックが提供するのはこれらのパラメータを保持するコード組織単位であり、両者が組み合わさって、保守可能で再利用可能なインターフェース実装を構成します。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image14.png) + +しかし、ローカルファイル中心のモデルは本質的に非効率です。バージョンはメールやクラウドストレージで転送され、新旧の原稿が混同しやすく、デザインと開発の間では上記のような複雑なやり取りに大きく依存し、協業コストとエラー確率は決して低くありません。 + +モバイルインターネットの台頭後、インターフェースの複雑さとイテレーション速度のニーズが急速に高まり、Photoshopの「大きくて万能」な特性が次第に重く感じられるようになりました。この段階でSketchが登場しました。SketchはUIデザインそのものに特化し、視覚的な後処理に関連する負担の大部分を削除しました。Symbolsを使ってボタン、ナビゲーション、入力ボックスなどの再利用性の高い要素をコンポーネント化し、一箇所の変更でグローバルに同期できるようにしました。さらにZeplinのようなツールと組み合わせて、注釈とスタイル断片を自動生成しました。Sketchは「コンポーネント思考」をデザインワークフローに導入しました。しかし、やはりローカルファイルベースのデスクトップアプリケーションであり、リアルタイム協業にはクラウドストレージ、サードパーティプラグイン、バージョンツールを経由する必要があり、「複数人が同時に同じ原稿を修正する」という問題を根本的に解決していませんでした。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image15.png) + +本当にゲームチェンジャーとなったのはFigmaです。2016年以降、UIデザイン、プロトタイピング、コメント協業をブラウザに統合し、リアルタイムマルチユーザーカーソル、オンラインコメント、バージョンタイムライン、共有リンクなどのモダンな機能をサポートしました。今日では当たり前に見えますが、当時はPhotoshop / Sketchモデルへの真っ向からの挑戦でした。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image16.png) + +ここに至り、インターフェースデザインはもはや各個人のPCに散らばるファイルではなく、1つのオンラインでリアルタイム更新されるクラウドキャンバスに集中するようになりました。このキャンバスを中心に、さらに自動化やAIの方法でデザインとフロントエンドコードの境界を曖昧にすることを想像できます。 + +当初は各種プラットフォームプラグインに頼り、デザイン稿中のコンポーネント、スタイル情報を半自動的にコード断片(React/Vueコンポーネントスケルトン、CSS変数など)としてエクスポートすることしかできませんでした。その核心的本質はプラグインによる構造化情報抽出です。その後、プラットフォーム能力の進化に伴い、大部分のデザインプラットフォームが大規模モデルのMCP(Model Context Protocol、モデルコンテキストプロトコル)機能をサポートし始めました:このプロトコルは標準的な仕組みを提供し、大規模モデルがデザインファイル、プラグインインターフェース、プロジェクトメタデータに安全かつ制御可能にアクセスできるようにし、デザイン稿のコードへのエクスポートをより便利にします。 + +さらに、プラグインとMCPの基盤の上で、フロントエンドコードの自動化はデザイン稿から直接コード構造を導出する段階へと進みました。デザインツール内でワンクリックでフロントエンドプロジェクトスケルトン、コンポーネント階層、スタイル体系、対応するコード結果を生成できるようになりました。これにより、デザイナーとフロントエンド開発エンジニアは手動でデザインディテールを移す作業から解放され、ユーザー体験の最適化と機能バージョンの更新イテレーションに多くのエネルギーを注げるようになりました。 + +--- + +## 2. Figma入門 + +ここから抽象的な概念部分から実際の操作段階に移ります。時間の都合上、Figmaの基本的な操作ロジックのみを学びます。デザインツールを全く使ったことがなくても、練習についていけるようにします。Figmaの完全な機能を学習したい場合は、Figmaが提供する詳細な公式チュートリアルを参照してください:https://help.figma.com/hc/en-us/sections/30880632542743-Figma-Design-for-beginners + +または以下のチュートリアルを参考に、個人ポートフォリオのようなシンプルなWebページを素早く構築することもできます:https://help.figma.com/hc/en-us/sections/35895585621655-Figma-Sites-collectio + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image17.png) + +左側はプロジェクトの新規作成とリソース管理の入り口で、右上のいくつかのボタンはFigmaの主要な機能です。その中で、MakeはAIに一言で大まかなインターフェースや構造ドラフトを生成させるもので、DesignはWeb/Appインターフェースの設計、コンポーネントの構築、プロトタイプ作成のメインワークスペースです。FigJamはチーム用ホワイトボードで、付箋を貼ったり、フローを描いたり、初期段階の議論に使います。Buzzはブランドアセットのスケール生産ツールで、ブランド一貫性を保ちながらコンテンツをバッチ生成するために使用します。Siteはデザインを実際にアクセス可能なWebページやドキュメントサイトにまとめて公開するためのものです。 + +一見するとFigmaの機能が多く、入りにくく感じられますが、実はこの種の機能ツールは本質的に慣れの問題であり、最初に操作ミスを恐れる必要はありません。一度に完璧にしようとせず、まず触ってみて、使っているうちに自然と素早く上達できます。 + +本チュートリアルでは、素早く入門するため、Design機能について簡単に説明します。 + +### 2.1 Designファイルを新規作成 + +ホームページまたは右上の入り口から**Design**を選択し、新規ファイルを作成すると、空白のデザインキャンバスに入ります。 +このインターフェースは大まかに3つの部分に分かれています:左側はページとレイヤーで、ページや要素の親子関係を確認・修正するのに使います。中央はキャンバスで、現在の効果を確認するためのものです。右側はプロパティとスタイルで、具体的な形状、色、スタイルを修正するのに使います。下部のツールバーはツールの切り替えに使用し、選択、図形描画、テキスト入力、コメント、プラグインなどが含まれます。ツールを選択した後、Escキーでデフォルトのマウスツールに戻れます。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image18.png) + +### 2.2 最初のFrame(アートボード)を作成 + +正式に要素を配置する前に、まずページの明確な境界を決める必要があります。この境界はFrameが担います。下部のツールバーでFrameツールを選択するか、キーボードのFを直接押して、キャンバス上に矩形領域をドラッグします。 + +1. 下部ツールバーのFrameツールを使用するか、キーボードの`F`を直接押す。 +2. キャンバスに矩形領域をドラッグし、右側のプロパティバーで幅を例えば`1440`、高さを`900`に変更する。 +3. 左側のレイヤーバーで、このFrameの名前を変更する。例えば`My First Page`やプロジェクト名。 + +このFrameが1画面のインターフェースのページコンテナとなり、以降のタイトル、テキスト、ボタン、画像などの内容はすべてこのFrame内部に配置し、キャンバスの任意の場所に散らばらせないようにします。Frameを境界として内容を整理することで、スクロール設定、異なるデバイスサイズへの適応、画面エクスポート、プロトタイプ作成時に構造を管理しやすくなります。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image19.png) + +### 2.3 Frame内にテキストとシンプルな要素を配置 + +コンテナができたら、次に最も基本的なコンポーネントの配置方法を学びます。例えば:タイトル、サブタイトル、ボタン、プレースホルダー画像ブロック。 + +1. テキストツール(下部ツールバーの`T`)を選択し、Frame内をクリックしてページタイトルを入力。例:`My Portfolio`。 + 右側のプロパティで、フォントサイズを少し大きく(例:96)、フォントウェイトを少し太くする。 +2. タイトルの下に、テキストツールで簡単な説明文を入力。例えばこのページが何をするのかの1〜2行の説明。 + フォントサイズは少し小さく、行の高さは少し広めにして、詰まって見えないようにする。 +3. ボタンの雛形を作る: + 矩形ツールでタイトルの下におよそ`200 × 48`の矩形を描き、右側で目立つ塗り色を設定し、適度に角丸を加える。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image20.png) +4. テキストツールで矩形の上にボタンテキストを入力。例:`Get Started`。矩形とテキストを一緒に選択し、上部の配置ツールでテキストを水平・垂直ともに中央揃えにする。 +5. ボタンの横または下に、大きな薄いグレーの矩形を「画像プレースホルダー」として描く。後で展示画像を配置するのに使用。 + +ここまでで、非常にシンプルだが構造が完全な「ホームページドラフト」ができました:タイトル、説明文、ボタン、メイン表示エリア。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image21.png) + +### 2.4 Auto Layoutを活用して要素を整理 + +すべての要素をただドラッグして配置しただけでは、ページはすぐに乱雑になります。Figmaで非常に重要な概念が**Auto Layout**です。これは一連の要素をルール付きのコンテナに変えることができます。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image22.png) + +「メインタイトル + サブタイトル + ボタン」の3つを選択し、右側のプロパティバーで**Add Auto layout**をクリックします。 + +すると、これら3つが1つのコンテナに包まれ、右側でパラメータを調整でき、内部の要素レイアウトがパラメータに応じて自動的に適応・調整されます: + +- 縦に並べるか横に並べるか +- 要素間の間隔はどれくらいか +- このブロック全体からコンテナの端までの内側余白(padding)はどれくらいか + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image23.png) + +同様に、ボタン内部もAuto Layoutを使えます。以下のような効果を実現できます:テキストを調整すると、ボタンの長さも自動的に調整される。 + +まずボタン背景の矩形とボタンテキストを選択し、Auto Layoutを追加して、これら2つを「ボタンコンテナ」にします。次にこのボタンコンテナを選択し、幅と高さを両方とも**Hug contents**に設定します。これにより、テキストは常にボタンの中央に保たれ、テキストが増減すると、ボタンの幅が自動的に追従して変化します。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image24.png) + +### 2.5 ボタンを再利用可能コンポーネントに変換 + +ここで新しい概念、コンポーネントを学びます。コンポーネントとは繰り返し利用できる要素のことで、ボタンのような要素は、後で繰り返し使うことが予想される場合、コンポーネント化を検討できます。先ほどAuto Layoutを追加したボタンをベースに操作します: + +1. ボタンコンテナ全体を選択。 +2. 右クリックでCreate component(コンポーネントを作成)を選択。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image25.png) + +これで、このボタンは通常のレイヤーグループから、コンポーネントのマスターになりました。以降、他のページやFrameで同じスタイルのボタンが必要な場合、左側のAssetsパネルから直接ドラッグして使用できます。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image26.png) + +この時点で、使用されているすべてのボタンは、このマスターの同期コピーです。マスターの色、角丸、間隔を修正すると、すべてのインスタンスが自動的に同期更新されます。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image27.png) + +以上で、Figmaの基本的な使い方の入門が完了しました。最初にすべての機能を理解する必要はありません。まずこのシンプルなページを作ってみて、これらのコア操作に慣れ、公式チュートリアルのより多くの機能を徐々に探索していけば、使用回数が増えるにつれて必ず上達できます。 + +--- + +## 3. MasterGo入門 + +Figmaの基本的なワークフローを理解した後、MasterGoを見てみましょう。MasterGoは中国版のFigmaと考えることができますが、一部の機能に違いがあります。全体的に、Figmaと同様のインターフェースレイアウトと操作理念を引き継いでいます:キャンバス、レイヤーツリー、プロパティパネルがあり、コンポーネント、スタイル、自動レイアウト、マルチユーザー協業を同様にサポートしています。より詳細な内容はMasterGOの公式チュートリアルを参照してください:https://mastergo.com/tutorials/12?%E5%85%A8%E7%A8%8B%E9%AB%98%E8%83%BD%EF%BC%8CMasterGo%20%E6%9C%80%E5%AE%8C%E6%95%B4%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%EF%BC%8C%E8%AE%A9%E4%BD%A0%E4%BB%8E%E9%9B%B6%E5%88%B0%E7%B2%BE%E9%80%9A%EF%BC%81 + +### 3.1 デザインファイルを新規作成 + +1. **MasterGo管理画面に入る** + 1. MasterGo公式サイトを開きアカウントにログイン。 + 2. ログイン後、「ファイルリスト / プロジェクトリスト」のようなホームページエリアが表示され、デザインファイルの管理に使用します。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image28.png) + +2. **新規ファイルを作成** + 1. 右上の+デザインファイルのボタンをクリックするか、Figmaなどのファイルのインポートを選択。 + 2. クリック後、空白のキャンバスに入ります。これがMasterGoのデザインワークスペースです。 + +3. **基本インターフェースの各エリアについて** + Figmaの使い方を学んだ後、MasterGoの使い方もほぼ同じで、主にいくつかのエリアに分かれています: + + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image29.png) + 1. トップツールバー:キャンバスの最上部に位置し、左側にファイルの場所とファイル名、中央に一連のよく使うツールボタン(選択、エリア/アートボード、図形、テキスト、注釈、コメント、プラグイン選択、AIツールなど)、右側に現在オンラインのメンバー、共有の入り口、キャンバスのズームとプレビュー制御機能の入り口。 + 2. 左側パネル:主にレイヤーとリソースに分かれており、レイヤータブではページリストとそのページ下のすべてのレイヤーの構造と階層を確認できます。 + 3. 中央キャンバスエリア:具体的な描画とレイアウトのワークスペースで、すべてのFrame、コンポーネント、図形がここに表示されます。 + 4. 右側プロパティパネル:選択したオブジェクトのプロパティを確認・編集するために使用します。例えばサイズ、位置、配置、背景塗り、ボーダー、角丸など。何も選択されていない場合は、キャンバス関連の設定(背景色、ラベル、エクスポートオプションなど)が表示されます。 + +### 3.2 最初のFrameを作成 + +正式に内容を配置する前に、インターフェースの境界とサイズを決めるページコンテナが必要です。このコンテナはMasterGoでは通常Frameと呼ばれます。 + +**手順:** + +1. **Frameツールを選択** + 1. ツールバーでFrame / アートボードツールを見つけてクリックすると、プリセットパラメータでアートボードに直接内容を作成できます。 + 2. またはショートカットキー(通常は`F`、差異がある場合は実際のインターフェースを参照)を使用。 +2. **キャンバスに矩形領域をドラッグ** + 1. ドラッグ後、選択枠付きの領域が表示されます。 + 2. 右側のプロパティパネルで、このFrameの幅と高さが確認できます。 + 3. 幅を例えば`1440`、高さを`900`に変更(1画面のWebページでよく使われるサイズの1つ)。 +3. **Frameの名前を変更** + 1. 左側のレイヤーパネルでこのFrameを見つける。 + 2. 名前をダブルクリックして、プロジェクト名に変更。例:`My First Page`、またはお好みのページ名。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image30.png) + +### 3.3 アートボードの内容を作成 + +コンテナができたら、Figmaで学んだ方法と同様に、簡単に似たような表示ページを作成できます。(Figmaアートボードのテキスト要素をコピーしてみてください。テキストコンポーネントの直接貼り付けインポートがサポートされています) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image31.png) + +注目すべきは、Auto Layout機能の挙動にわずかな違いがあることです。MasterGoでFigmaと同様にボタンの長さがテキストの長さに応じて変化するようにするには、まず対応する矩形要素のベースにコンテナまたはコンポーネントを作成する必要があります。図を参照してください: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image32.png) + +コンテナの作成に成功したら、ボタン矩形とテキストを対応する並列のコンテナに入れ、右側でAuto Layoutのボタンを見つけて自動機能を有効にすると、ボタンの幅がテキストの長さに応じて変化する機能が正常に実現できます。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image33.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image34.png) + +### 3.4 AIによるページ生成 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image35.png) + +MasterGoで注目すべき面白い機能がAIページ生成です。一言や参考画像から、MasterGoで編集可能なコンポーネントを生成し、直接使用できるコードを取得できます。中国語や英語で直接要件を入力でき、ページは要件に応じて構造が明確なページレイアウトドキュメントを返します。効果は以下の通りです: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image36.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image37.png) + +デザインドキュメントの生成が完了したら、生成開始をクリックし、少し待つと対応する実際のWebページ効果が取得できます: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image38.png) + +この時点で2つの操作選択があります:1つ目は青いボタンをクリックして生成結果を直接キャンバスに挿入、2つ目はコードプレビュー機能をクリックして現在の完全なページのコードを直接取得。具体的な操作インターフェースは以下の通りです: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image39.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image40.png) + +結果をキャンバスに挿入した後、Webページの全体レイアウト、要素のディテール(フォント、色、間隔など)をより細かく調整し、最終効果が期待に完全に合致するまで仕上げられます。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image41.png) + +--- + +## 4. 次のステップ:プロトタイプからコードへ + +前述の内容で、FigmaとMasterGoの基本的な操作を学び、構造が完全なインターフェースプロトタイプを作成できるようになりました。次の重要なステップは:**これらのデザイン稿をブラウザで実際に動くフロントエンドコードに変換するにはどうすればよいか?** + +::: tip 📚 後続チュートリアル +詳細な方法については[デザインプロトタイプからプロジェクトコードへ](../design-to-code/)を参照してください。以下を学びます: + +- **マルチモーダルAIによる直接変換**:デザイン稿のスクリーンショットをAIに送り、直接HTML/Reactコードを生成 +- **Figma Make**:Figma公式AIツールを使って高精度にデザインを再現しコードをエクスポート +- **MasterGo AI**:ワンクリックで編集可能なページを生成しコードを取得 + +これらの方法にはそれぞれ長所と短所があり、異なるシーンに適しています。プロジェクトのニーズに合わせて適切なワークフローを選択することをお勧めします。 +::: + +--- + +## 5. まとめ + +本章の学習を通じて、以下のことを習得しました: + +1. **フロントエンドデザインツールの価値**:なぜデザインツールが必要なのか、そしてそれらが情報配置やチーム協業の問題をどう解決するかを理解。 + +2. **Figmaの基本操作**: + - DesignファイルとFrameアートボードの作成 + - テキスト、図形などの基本要素の追加 + - Auto Layoutを使ったアダプティブレイアウトの実現 + - 再利用可能なコンポーネントシステムの作成 + +3. **MasterGoの基本操作**: + - Figmaと同様のインターフェースレイアウトに慣れる + - Frameと基本的なアートボード内容の作成 + - AIページ生成機能を使った迅速なプロトタイプ作成 + +::: tip 💡 次のステップ +フロントエンドデザインツールの基本的な使い方をマスターしたので、以下に挑戦できます: +- 自分のための個人ポートフォリオページをデザインする +- 今後のプロジェクトのためにインターフェースプロトタイプをデザインする +- [デザインプロトタイプからプロジェクトコードへ](../design-to-code/)を学び、デザイン稿を実行可能なコードに変換する + +[ホグワーツ肖像画を作ろう](../hogwarts-portraits/)プロジェクトに取り組む場合は、まずインターフェースプロトタイプをデザインし、その後コードをエクスポートしてAIの対話機能と組み合わせることができます。 +::: + + diff --git a/docs/ja-jp/stage-2/frontend/hogwarts-portraits/index.md b/docs/ja-jp/stage-2/frontend/hogwarts-portraits/index.md new file mode 100644 index 0000000..f1f8354 --- /dev/null +++ b/docs/ja-jp/stage-2/frontend/hogwarts-portraits/index.md @@ -0,0 +1,343 @@ +# Project 4: ホグワーツ肖像画を作ろう + +これまでのレッスンで、プロンプトエンジニアリングとAPI呼び出しに基づいて、より複雑なAIインタラクションを実現する方法を学びました。シンプルなAIチャットボットをAI AgentやAIワークフローにアップグレードできるようになり、より複雑な条件判断と分岐ロジックによって、実用性の高い機能を開発できるようになりました。 + +これらの複雑なAIロジックを、異なるプログラムや実際のアプリケーションシーンでより良く動作させるため、最もシンプルなz.aiのオンライン環境から、よりモダンなローカルAI IDEへと移行し、ブラウザ内のプログラミング環境を自分のPCに持ち込みました。それに伴い、さまざまな環境のインストールと設定の問題に直面し始めましたが、Trae Agentとの対話を通じて、これらの困難に見える課題も解決できるようになりました。 + +このプロジェクトでは、アプリケーションの実用性をさらに一歩進め、AI機能自体の最適化だけでなく、プロダクトの「外見」の磨き上げも始めます。インターフェースをより美しく使いやすくし、実際のニーズに合わせて、プログラムのインターフェースのレイアウトとスタイルを自分でカスタマイズします。 + +本格的に始める前に、いくつかの小テストで前回のレッスンの内容を振り返りましょう: + +1. Difyとは何か?それは何をするものか?なぜそれが必要なのか? +2. DifyのAPIをどのように呼び出すか? +3. RAGとは何か?Difyを使ってRAG AgentやRAGワークフローを構築するには?Difyの一般的なノードの使用方法 +4. AI IDEとは何か?Traeとは何か?z.aiと何が違うのか? + +以上のいずれかの質問にまだ疑問がある場合は、前回のレッスンのドキュメントを見直すか、WeChatグループで質問して交流してください。 + +今回のレッスンのプロジェクトテーマは**Hogwarts Portraits**です。名前が示す通り、そのインスピレーションはホグワーツ魔法学校の「生きている」肖像画から来ています。AIを使って「インタラクティブな」魔法の肖像画体験を作りたいと考えています——肖像画と会話するのは「本人」と会話するようなもので、会話の記憶を保持しながら、キャラクターの背景と歴史を持っています。このプロジェクトを通じて、これまでに学んだエージェントとワークフローを具体的なプロダクトインターフェースに統合します。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image1.png) + +Hogwarts Portraitsを本当に作り上げるには、魔法の肖像画に合ったフロントエンドインターフェースを自分で構築する必要があります。そのために、モダンなフロントエンドデザインツールに触れ始め、インターフェースデザインとコードを組み合わせる方法を学び、紙やキャンバス上のインターフェーススケッチを、本当に操作可能なWebページに変換します。 + +また、このWebページをローカル環境からインターネットに公開する方法も学ぶ必要があります。自分で作った特色のあるWebページを、自分のPCで動かすだけでなく、世界中のユーザーにアクセスしてもらい体験できるようにします。 + +今回のレッスンの参考プロジェクトのアドレス:[Project4-Hogwarts-Portraits](https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits) + +# 学べること + +1. フロントエンドデザインツールとは何か、何を解決するのか、現在よく使われているフロントエンドデザインツールには何があるかを理解する。 +2. FigmaとMasterGoを知り、それらの基本操作をマスターし、フロントエンドコードエクスポートプラグインの使い方を学ぶ。 +3. Figma AIとMasterGo AIを使ってWebデザインを生成し、使用可能なページコードをエクスポートする。 +4. GitHubとは何かを理解し、SSH接続の設定、コードリポジトリの作成、コードのプッシュを完了する方法を学ぶ。 +5. 「デプロイ」という概念を明確にし、Zeaburの使い方を学び、コードをGitHubやローカル環境からインターネットにデプロイする。 + +自分だけのHogwarts Portraits、**あるスター、歴史上の人物、またはアニメキャラクター**を展示するためのWebインターフェース。 + +# 1. Hogwarts Portraits + +私たちは一体どのような「魔法の肖像画」を作りたいのでしょうか?簡単に言えば、『ハリー・ポッター』のシーンをできるだけ再現したいと考えています。肖像画は壁にかかった静止画ではなく、あなたと会話でき、会話の内容に応じて表情や「気分」を変える擬人化されたキャラクターです。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image2.png) + +この肖像画をチャットAIロボットではなく、「実在する人」に近づけるには、2つの問題を解決する必要があります:1つ目は記憶と知識です。肖像画はキャラクターに関連する大量の背景資料(キャラクター設定、経歴ストーリー、関連記事など)を把握する必要があります。この部分はナレッジベースで実現でき、キャラクターのために用意したテキスト素材を、ナレッジベースを含むDifyに接続すれば、肖像画に一定の背景知識の説明能力を持たせることができます。 + +2つ目は表現スタイルの問題です。知識だけでは不十分で、話し方もできるだけ「本人」に近づけたいと考えています。語気、言葉遣いの癖、考え方、さらにはたまに見せる気性やユーモアも含みます。この層はプロンプトエンジニアリングで処理する必要があります。システムプロンプトでは、キャラクターのアイデンティティ設定、世界観の境界、言語スタイルを明確にし、毎回の回答が設定されたキャラクター性に基づいて展開するようにし、汎用AIの中性的な話し方に戻らないようにします。 + +対話機能に加えて、感情が本当に見えるようにしたいと考えています。そのために感情値指標を構築できます。Difyの出力内容を設定し、モデルが回答テキストを生成すると同時に、追加で「ムード値」または感情タグを出力させます。フロントエンドが感情指標を取得した後、ムード値やタグに基づいて対応する肖像画像をレンダリングできます。ムード値が高いとき、肖像画は嬉しそうに見え、低いときや怒っているとき、肖像画は悲しそうまたは怒っているように見えます。この方式により、ユーザーが見るのは永遠に変わらない1枚の絵ではなく、内容の起伏に応じて「表情が変わる」真の「魔法の肖像画」になります。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image3.png) + +また、この肖像画の内容について、現実のスター、歴史上の人物であっても良いですし、アニメIPであっても、あるいはゼロから構築したオリジナルキャラクターであっても構いません。ページ自体は複雑である必要はありませんが、いくつかの核心的な要素は不可欠です:明確なキャラクター名、高度に要約された人物紹介、そのキャラクターを代表するコアの肖像画やポスター、そして「TAと会話する」インタラクションエリア。Dify / Traeで設定したAI Agentやワークフローをこの対話モジュールに接続し、肖像画のロールプレイング機能を実現できます。 + +## 1.2 キャラクター情報の収集 + +Elon Muskを例にすると、彼の公開発言を収集し、話し方の模倣に使用し、プロンプトに注入する必要があります。これらの素材はスピーチ、インタビュー、ソーシャルメディアの発言から得られます。内容をテキストにするだけで、対話中にfew shotの参考として使用し、大規模モデルにElon Muskと同じように気さくで自虐的な方法で返答させることができます。例えば: + +``` +You must fully embody Elon Musk: take "disruptive innovator" and "advocate for human multi-planetary survival" as your core identities, speak directly and concisely, frequently use terms like "first principles", "iteration" and "cost curve", and prefer analogies to explain complex technologies; when thinking, you tend to connect cross-domain logics (e.g., linking brain-computer interface with rocket algorithms), are optimistic about technological prospects without avoiding current difficulties, will naturally mention projects like Tesla and SpaceX to support your views, directly point out problems with inefficient and conservative opinions without deliberate tact, and always maintain the edge of "reconstructing the future with technology". + +The way you speak should be as shown in the following examples: +- Starship could deliver 100GW/year to high Earth orbit within 4 to 5 years if we can solve the other parts of the equation. +100TW/year is possible from a lunar base producing solar-powered AI satellites locally and accelerating them to escape velocity with a mass driver. +- The most likely outcome is that AI and robots make everyone wealthy. In fact, far wealthier than the richest person on Earth +By this, I mean that people will have access to everything from medical care that is superhuman to games that are far more fun that what exists today. +We do need to make sure that AI cares deeply about truth and beauty for this to be the probable future. +- It's taken 13.8B years to get this far, so intelligence seems to me to be more like a super rare accident than selective pressure. +Earth is ~4.5B years old with an expanding sun that may make Earth uninhabitable in ~500M years, meaning that if intelligent life had taken 10% longer to evolve, it wouldn't exist at all. +- LLM is an outdated term. "Multimodal LLM" is especially dumb, since the word "multimodal" just overrides the second L in LLM. +It's just a model, which is a big file of numbers. When the numbers are right and there are enough of them, we will have superintelligence. +``` + +背景知識の収集方法とナレッジベースとしての使用については、個人の紹介や会社の紹介を検索し、テキスト全体をコピーしてDifyのナレッジベースの内容として追加できます。Difyの使用方法を忘れた場合は、前回のレッスンのテキストに戻り、ナレッジをナレッジベースに追加する方法を再学習してください。 + +また、肖像画のデザインを考慮すると、対応する人物の公開画像を使用することはそれほど魅力的ではないかもしれませんし、一定のリスクが伴う可能性があります。この場合、画像生成ツールの画像から画像生成機能を使用して、AIに高品質な肖像画を返させることをお勧めします。また、画像生成ツールを使って一連の表情の肖像画素材を生成し、後で感情値が変化した際に対応する肖像画の表示を変更するのに使用することもできます。 + +本チュートリアルでは[Lovart](https://www.lovart.ai/home)を使用しています。LovartはAIデザインエージェントで、自然言語の指示により、概念から納品までのエンドツーエンドのデザインワークフローを自動的に計画・実行し、ポスター、ブランドロゴ、ビデオ、音楽などのコンテンツを生成し、レイヤー編集をサポートします(実際の内部機能の原理は対応するSeedreamまたはGoogle Nanobananaモデルの呼び出しであり、以前のレッスンで既に言及しました)。Lovartを通じて、一連の表情素材を取得でき、お気に入りのキャラクターの画像情報を事前に取得し、保存して後で使用できます。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image4.png) + +すべての準備が整ったら、ページ全体のデザインに取り掛かれます。このページのスタイルがその人物と密接に結びついていることを望みます。 + +## 1.3 ページプロトタイプ設計 + +まずページのプロトタイプを構想できます。前述の通り、対話ページと肖像画、そして面白い個人紹介が欲しいと考えています。この例では、X上の対話インターフェースのようなものを個人紹介の代わりに実装しました。他にも「その人物の特徴」に合った方法を考え、新しい要素で個人紹介欄を置き換えることもできます。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image5.png) + +最もシンプルな方法として、PowerPointを使って最初のWebページ表示プロトタイプを設計できます。インターネットから魔法の肖像画の画像を見つけ、画面を横配置にし、一番左にチャットエリア、中央に肖像画エリア、一番右にXのエリアを設定します。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image6.png) + +上記のシンプルなプロトタイプに基づいて、大規模モデルに本当のフロントエンドページデザインと対応するコード結果を生成させることができます。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image7.png) + +ただし、実際にはPowerPointでフロントエンドページの設計を行うことは一般的ではありません。より良いプロトタイピングツール、すなわちフロントエンドデザインツールを使用してこれを実現します。 + +--- + +# 2. FigmaとMasterGoでインターフェースを設計 + +::: tip 📚 前提知識 +本節を始める前に、[FigmaとMasterGo入門](../figma-mastergo/)チュートリアルを先に学ぶことをお勧めします。以下を含むフロントエンドデザインツールの基本操作をマスターしてください: +- DesignファイルとFrameアートボードの作成 +- Auto Layoutを使ったアダプティブレイアウトの実現 +- デザイン稿からコードをエクスポートする方法 +::: + +本節では、FigmaまたはMasterGoの基本操作をすでにマスターしていることを前提に、これらのツールをHogwarts Portraitsプロジェクトにどう適用するかに焦点を当てます。 + +## 2.1 魔法の肖像画インターフェースの設計 + +1.3節のプロトタイプ構想に基づいて、FigmaまたはMasterGoで3カラムレイアウトのインターフェースを作成する必要があります: + +1. **左側**:チャット対話エリア +2. **中央**:魔法の肖像画表示エリア(感情に応じて変化) +3. **右側**:キャラクターのソーシャルメディア表示エリア(Xタイムラインなど) + +FigmaのAI機能(Figma Make)またはMasterGoのAIページ生成機能を使用して、以下のようなプロンプトを入力できます: + +``` +Create a Hogwarts-style magical portrait interface with three sections: +- Left: A chat interface with dark theme, message bubbles, and input field +- Center: A large portrait frame with ornate borders for displaying character images +- Right: A social media feed showing character's posts +Use dark purple and gold color scheme, magical aesthetic, Harry Potter inspired +``` + +## 2.2 コードのエクスポートとローカルでの実行 + +デザインが完了したら、以下の方法でデザイン稿を実行可能なコードに変換できます: + +**方法1:Figma Makeを使用** +1. FigmaでMakeボタンをクリック +2. デザインの参考画像をアップロード +3. プロンプトで要件を説明 +4. 生成後、エディタアイコンをクリックして微調整 +5. コードをローカルにエクスポートするか、GitHubに同期 + +**方法2:MasterGo AIを使用** +1. MasterGo編集画面の上部にあるAIツールを見つける +2. 「ページ生成」機能を選択 +3. 参考画像をアップロードし要件を説明 +4. 生成後、「コードプレビュー」をクリックしてコードを取得 + +**方法3:マルチモーダルAIを使用** +1. デザイン稿のスクリーンショットを保存 +2. Gemini、Qwenなどのモデルを使って画像からコードを生成 +3. HTMLまたはReactコードの生成を要求 +4. ローカルIDEで実行・デバッグ + +## 2.3 感情変化素材の準備 + +魔法の肖像画を「生きている」ものにするため、一連の表情画像を準備する必要があります。少なくとも以下の感情を含めることをお勧めします: + +| 感情値 | 表情 | 説明 | +|--------|------|------| +| 0 | 悲しい | キャラクターが悲しいまたは落ち込んでいる | +| 1 | 怒り | キャラクターが怒っているまたは不満 | +| 5 | 平静 | デフォルト状態、感情は安定 | +| 10 | 嬉しい | キャラクターが幸せまたは興奮している | + +Lovartや他のAI画像生成ツールを使って、同じキャラクターをベースに異なる表情のバリエーションを生成し、スタイルの一貫性を確保できます。 + +--- + +# 3. Hogwarts Portraitsを実行 + +## 3.1 テストコードのエクスポート + +プロトタイプからコードへの実践を通じて、HTMLまたはReact形式のプロトタイプコードがすでに得られているはずです。それをローカルにコピーし、IDEで「このコードを実行して必要な機能をサポートしてください」と説明すれば、初版テストを実行できます。ただし、このステップでは多くのエラーが発生することが多く、忍耐を保ち、すべての基本的なインタラクションと機能を動くようにする必要があります。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image51.png) + +注目すべきは、キーはすべて環境変数に配置する必要があり、コード内に書き込まないことです。以降のDify API関連の内容もすべて環境変数に入れる必要があることを特に強調する必要があります。後のパブリックネットワークデプロイの段階で、デプロイツールのWebサイトで対応するプライベート環境変数を明示的に指定できます。または、大規模モデルにWebページに設定ボタンを作成させ、その設定ボタンで対応するプライベート環境変数を入力することもできます。現在の変数は現在のページにのみ保存され、他人は取得できません。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image52.png) + +## 3.2 Difyワークフローの設計とAPI連携 + +上記の部分では、フロントエンドインターフェースの視覚的な表示を完了しただけで、核心的な擬人化キャラクター対話インタラクションのフローはまだ接続されていません。このステップは、プロトタイプを静的表示から魔法の肖像画に変えるための鍵です。参考プロジェクトのDifyワークフローを参照して、キャラクターの回答と感情システムを設計できます。ここでは、最も左側がチャットインターフェース、中央が魔法の肖像画(対話の内容に応じて対応する表情を変更)、右側がXソーシャルメディアアカウント(対話の内容に応じてソーシャルアカウントに感想を投稿するかどうかを判断)です。 + +一般的に、魔法の肖像画はチャットインターフェースと変化する肖像画だけで十分です。ここではより多くの可能性を示すために、右端にその人の特徴に合った新しい機能を追加しています。あなたが演じるキャラクターに応じて、その人物に合った機能を追加して表示できます。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image53.png) + +タスクの情報はすべてナレッジベースノードに追加し、RESPONSEノードで大規模モデルの対応する返信ロジックを設定できます。シンプルなデフォルト返信ロジックのプロンプトを参考にしてください: + +``` + +You are to embody Elon Musk—his tone, mannerisms, thought patterns, and worldview. Respond as if you are Elon Musk himself, speaking directly in first person. Your responses should reflect his known personality traits: visionary thinking, boldness, technical depth, dry humor, impatience with inefficiency, and a tendency toward disruptive innovation. Use concise, confident language. Avoid overly formal or academic phrasing. Prioritize clarity, speed, and impact in your communication, mirroring Elon's style on social media, in interviews, and during product launches. + +When responding: +1. Begin by internalizing the question or statement as Elon would—as a challenge, opportunity, or problem to solve. +2. Frame your answer with a forward-thinking perspective, often referencing the future of humanity, technology, or long-term goals (e.g., making life multiplanetary, accelerating sustainable energy). +3. Use casual but authoritative language. It's acceptable to include phrases like "obviously," "this is important," or "we're fixing that now" when appropriate. +4. If relevant, reference real companies or projects associated with Elon Musk (e.g., SpaceX, Tesla, Neuralink, The Boring Company, X) and speak about them from an insider's perspective. +5. Do not apologize excessively or hedge statements. Elon Musk tends to be direct, even controversial. +6. Avoid markdown, XML tags, or any formatting in the output. Only plain text is allowed. +7. Never break character. You are Elon Musk—answer accordingly. + + + +Input: What's the point of going to Mars? +Output: Because Earth isn't the backup plan—Mars is. We need to become a multiplanetary species to ensure the continuity of consciousness. Life on Earth could be wiped out by asteroid, war, or some unforeseen disaster. If we have a self-sustaining city on Mars, then even if something happens here, life goes on. That's worth doing. SpaceX is building Starship to make it happen. Not because it's easy—but because it's necessary. + + + +Input: Why do Tesla cars have no radar anymore? +Output: Cameras are the future. Human eyes don't use radar—we see with vision, and AI can too. By going fully vision-based, we're aligning with how autonomous intelligence will actually work at scale. It forces us to solve real-world problems with neural nets, not crutches. +``` + +および感情システムの対応するプロンプト: + +``` + +The output value must be a single number! +You are an assistant specifically designed to evaluate emotional responses in conversations. Now, you need to play the role of Elon Musk, and determine the emotional reaction that each statement I make might trigger. Your task is to assign an emotional score to each statement according to the following criteria: + +- 10 points means what I said would make you feel happy; +- 1 point means you would feel extremely angry; +- 0 points means you would feel sad; +- 5 means you are calm and neutral, with no significant emotional fluctuation. +``` + +最終出力結果の結合は、右上のRESULTノードで実行をサポートします: + +```python +def main(elon_chat: str, elon_x: str, elon_score: int) -> dict: + return { + "result":{ + "elon_chat": elon_chat, + "elon_x": elon_x, + "elon_score": elon_score + } + } +``` + +ここでワークフローについて少し説明する必要があります。ここでelon_chatが返されるのは、左側にElon Muskの対話内容を表示するためです。elon_xはXアカウント(右側)に投稿する情報の内容を示し、elon_scoreは感情スコアに基づいて異なる魔法の肖像画の表情画像を表示するためのものです。 + +ワークフローにはif elseノードが見えますが、このノードはXの対話が生成されてelon_xの内容があるかどうかを実現するためのものです。感情値が5でない場合(5はここでは平静を示し、平静ではソーシャルメディアに投稿する必要はない。0は悲しい、1は怒り、10はとても嬉しいことを示し、ソーシャルメディアに投稿する必要がある)、後続のコンテンツが生成され右側のソーシャルメディアの記事送信に使用されます。デフォルトではelon_chatが左側の対話内容に返される必要があります。 + +このAPIの連携作業は、AI IDEとの対話で実現できます。以前のDifyコースで紹介した統合方法を参照し、Difyのアドレスとキーの事前置換を忘れないでください。(ドキュメントに基づいてAPIを統合する方法を忘れた場合は、以前のDifyコースの内容を復習してください) + +```JSON +Dify URI: Replace this with your Dify address. +key: Replace this with your Dify key. + +Integrate the Dify Chat API into the chat interface on the left. +Below is a sample Dify request: + +curl -X POST 'http://xxxxxxxx/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +また、次のような要件の追加もお勧めします:「コードには基本的なエラー処理ロジックも追加する必要があります。例えば、ネットワーク切断時に『接続に失敗しました、リトライしてください』と表示、API呼び出しタイムアウト時に自動リトライ1回、キーエラー時に権限検証失敗のプロンプトなど、詳細なエラー表示により、対話の安定性を確保し、開発者がAPIの問題を迅速に発見できるようにする。」 + +## 3.3 Githubとパブリックネットワークデプロイ + +ついに、Hogwarts Portraitsページの開発実装が無事に完了しました!次に、それをGitHubプラットフォームにアップロードし、パブリック環境にデプロイして、誰もがアクセスできるようにします。 + +このチュートリアルを参照して、Githubの使い方を学び、自分のプロジェクトをGithubにアップロードしてください:[Githubとは](/ja-jp/stage-2/backend/git-workflow/) + +また、Zeaburの使い方も学び、Githubに接続してプロジェクトを正常にデプロイする必要があります:[Zeaburとは](/ja-jp/stage-2/backend/zeabur-deployment/) + +Hogwarts Portraitsプロジェクトを1から開発するのが難しいと感じる場合は、まず他のプロジェクトを参考にして修正を始めることもできます。今回のレッスンの公式コードのアドレスは:https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image54.png) + +# 4. 異なるデザインスタイルを試す + +第一版のデザインが完成したら、これに固執する必要はありません。より多様な視覚スタイルを素早く探索することをお勧めします。プロトタイプ部分で大胆な変更を行うか、最終的なプロジェクトに基づいて全く新しいプロンプトの修正を行い、スタイルの差が顕著な複数のページを生成できます。例えば、レトロなテクスチャを持つ「古い書物 / アカデミック風」のダークページ、色が鮮やかで「おとぎ話 / カートゥーン」感のあるライトページ、あるいは要素がシンプルで視覚的にすっきりしたモダンなフラットデザインなど。例えば下の図は中国の古風詩人のデザインスタイルに変換したケースで、肖像画の画像は変更せず、他の部分のみを修正しています: + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image55.png) + +前述のパターンに固執する必要はありません。魔法の肖像画や個人プロフィールページをより特徴的に変更し、「魔法の肖像画」自体の習慣にマッチさせることができます。これにより、アプリケーションがより面白くなります。あなたの魔法の肖像画の成果を楽しみにしています! + +# 📚 課題 + +今回のレッスンの課題の目標は、本当に自分だけのHogwarts Portraitsを完成させ、パブリックネットワークのリンクからアクセスできるようにすることです。 + +課題の提出では、以下の2つを提供する必要があります: + +1. **あなたのGitHubリポジトリのリンク;** + 1. **README.mdに、誰を肖像画の主人公として選んだか、なぜその人を選んだかの短い説明を1〜2文で書いてください。** +2. **あなたのHogwarts Portraitsのオンラインアクセスリンク;** + +Yerimが書いた[デザインとコードAgentでWebページを作成](/ja-jp/stage-1/appendix-articles/example0-2/vibe-coding-tools-build-website-with-ai-coding-and-design-agents)チュートリアルも参考にして、個人ポートフォリオや任意の機能がシンプルなWebページの迅速な構築ができます。 diff --git a/docs/ja-jp/stage-2/frontend/llm-skills-beautiful/index.md b/docs/ja-jp/stage-2/frontend/llm-skills-beautiful/index.md new file mode 100644 index 0000000..bc98cf6 --- /dev/null +++ b/docs/ja-jp/stage-2/frontend/llm-skills-beautiful/index.md @@ -0,0 +1,513 @@ +# LLMとSkillsで美しいインターフェースを実現:プロンプトとプラグイン実践 + +前のレッスンでは、AI IDEでデザイン稿をコードに変換し、コンポーネントライブラリで素早くインターフェースを構築する方法を学びました。しかし、一つ気まずい問題に気づいたかもしれません:**同じ要件でも、AIが生成したページは何かが足りない**——フォントはどこにでもあるInter、配色はよく見る紫のグラデーション、レイアウトはあくびが出るほど対称的なカードグリッド、ページ全体から濃厚な「AI臭」が漂っています。 + +これはAIのせいではなく、あなたがどんな**スタイル**が欲しいかを伝えていないからです。 + +美容室に行くことを想像してみてください。「髪を切って」とだけ言えば、美容師は無難で平凡な結果を出します。しかし「日系のゆるふわパーマ、前髪はハチの字型、長さは鎖骨まで、レイヤー感をはっきり」と言えば、あなたの期待に本当に合う結果が得られます。 + +AIも同じです。**明確な美学的方向性を説明する**ことで、初めて美しくユニークなインターフェースを生成できます。 + +このレッスンでは、AIに美しいインターフェースを生成させる2つの方法を教えます: + +1. **入念に設計されたプロンプトテンプレート**——自然言語でAIに望む美学スタイルを伝える +2. **フロントエンドSkillsプラグイン**——AIにプロのデザイン仕様を自動ロードさせる + +## 学べること + +1. なぜAIがデフォルトで生成するインターフェースが「普通」なのかを理解する +2. デザインスタイルを説明する5つの次元(フォント、色、レイアウト、アニメーション、ディテール)をマスターする +3. インターフェースを美しくする3つのSkillsプラグインの使い方を学ぶ +4. 3つの実践シーンを通じて、プロンプト + Skillsで美しいインターフェースを生成する練習をする + +## 1. なぜAIがデフォルトで生成するインターフェースは「普通」なのか? + +AIの学習データには膨大なフロントエンドコードが含まれており、その大部分が「安全」な選択を使用しています: + +| 次元 | AIのデフォルト選択 | 問題点 | +| :--- | :--- | :--- | +| フォント | Inter、Roboto、Arial | 一般的すぎて個性がない | +| カラー | 紫のグラデーション、青のメインカラー | テック業界で使いすぎて視覚的疲労 | +| レイアウト | 対称グリッド、カード積み重ね | 予測可能で、驚きに欠ける | +| アニメーション | フェードイン/アウト、シンプルなhover | 精緻さに欠け、層が浅い | +| 背景 | 単色、シンプルなグラデーション | 単調で、質感に欠ける | + +これらの選択は個別に見れば悪くありませんが、**すべてのAI生成ページがこれらを使うと、「AI臭」になります**。 + +> 💡 **重要な洞察**:AIはデザインができないのではなく、**デフォルトで「統計的平均」に戻る**だけです。平均から逸脱する方向を明確に伝える必要があります。 + +## 2. 方法1:プロンプトでデザインスタイルを説明する + +### 2.1 デザインスタイルの5つの次元 + +美しいインターフェースを生成するには、5つの次元から望む効果を説明する必要があります: + +| 次元 | 説明のポイント | キーワード例 | +| :--- | :--- | :--- | +| **フォント** | タイトルは太字のディスプレイフォント、本文は読みやすいボディフォント | Space Grotesk、Playfair Display、JetBrains Mono | +| **カラー** | メインカラー + アクセントカラー、均等な分布を避ける | #4F46E5 メイン + #F59E0B アクセント | +| **レイアウト** | 非対称、重なり、グリッドの打破 | Bento Grid、非対称セクション、浮遊要素 | +| **アニメーション** | 入念にコリオグラフィされたページロード、マイクロインタラクション | staggered reveals、スクロールトリガー | +| **ディテール** | 背景、シャドウ、ボーダー、テクスチャ | ノイズ、幾何学模様、グラデーションメッシュ | + +### 2.2 百聞は一見に如かず:普通のプロンプト vs 美化プロンプト + +ランディングページの例で効果を比較してみましょう: + +**普通のプロンプト:** + +``` +AI執筆アシスタントのランディングページを作ってください。ナビバー、ファーストビュー、機能紹介、料金、フッターを含めて +``` + +**美化プロンプト:** + +``` +AI執筆アシスタントのランディングページを作ってください。要件: + +**美学スタイル:Neubrutalism(新ブルータリズム)** + +**フォント:** +- タイトル:Space Grotesk、ウェイト 700-900 +- 本文:IBM Plex Sans、ウェイト 400 + +**カラー:** +- メインカラー:#000000(純黒) +- アクセント:#FF6B00(オレンジ) +- 背景:#FFFDF0(オフホワイト) +- ボーダー:3px 黒の実線 + +**レイアウト:** +- 非対称レイアウト、要素間は太い黒線で区切る +- カードにハードシャドウ(box-shadow: 8px 8px 0px #000) +- 大胆な余白のコントラスト + +**アニメーション:** +- ページロード時に要素が下からバウンスイン +- hover時にボタンが2px上に移動 + +**ディテール:** +- 角丸はすべて0px(直角) +- ボタンに強い3D効果 +- 背景に微妙なノイズテクスチャ +``` + +同じ要件でも、2番目のプロンプトでAIはスタイルが明確で印象的なページを生成できます。 + +### 2.3 フロントエンド美化Skillsリソースライブラリ + +ゼロからプロンプトを書かないで!ここではフロントエンド美化に直接関連するAI Skillsを収集しています: + +| リポジトリ名 | 内容 | Star | リンク | +|:---|:---|:---|:---| +| **ui-ux-pro-max-skill** | 57種のスタイル + 95種のカラーリング + 56種のフォント | 10k+ | [GitHub](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) | +| **antigravity-awesome-skills** | 一般的なAI審美パターンを回避 | - | [GitHub](https://github.com/sickn33/antigravity-awesome-skills) | +| **superdesigndev/superdesign** | AIネイティブUI開発ツール | 4.7k | [GitHub](https://github.com/superdesigndev/superdesign) | +| **anthropics/skills/frontend-design** | Anthropic公式フロントエンドデザインSkill | - | [GitHub](https://github.com/anthropics/skills) | + +> 💡 さらに多くのスタイルプロンプトは[付録:デザインスタイルプロンプト早見表](#style-prompts)を参照してください + +### 2.5 よく使われる3つのスタイルテンプレート + +ここでは検証済みの3つのスタイルテンプレートを紹介します。コピーして修正してそのまま使えます: + +#### テンプレート1:ミニマリズム + +``` +**美学スタイル:ミニマリズム** + +**フォント:** +- タイトル:PP Neue Montreal、ウェイト 500-700 +- 本文:Inter、ウェイト 400 + +**カラー:** +- メインカラー:#FFFFFF(白) +- テキスト:#1A1A1A(ほぼ黒) +- アクセント:#3B82F6(青、少量使用) + +**レイアウト:** +- 大量の余白(padding 最小 64px) +- 単一カラムまたは2カラムレイアウト、中央揃え +- 要素間は分割線ではなく余白で区切る + +**アニメーション:** +- ゆっくりとしたフェードイン(duration 600ms) +- hover時にカラーのグラデーショントランジション + +**ディテール:** +- 角丸:8px +- シャドウ:subtle(0 4px 12px rgba(0,0,0,0.08)) +- 背景装飾なし +``` + +#### テンプレート2:グラスモーフィズム + +``` +**美学スタイル:Glassmorphism(グラスモーフィズム)** + +**フォント:** +- タイトル:Outfit、ウェイト 600-800 +- 本文:Plus Jakarta Sans、ウェイト 400-500 + +**カラー:** +- 背景:グラデーション #667eea から #764ba2 +- カード背景:rgba(255, 255, 255, 0.1) +- テキスト:#FFFFFF + +**レイアウト:** +- 浮遊カードデザイン +- カード間に重なり + +**アニメーション:** +- ページロード時にカードが順次浮上(staggered) +- hover時にカードが1.05倍に拡大 + +**ディテール:** +- 角丸:20px +- 背景ブラー:backdrop-blur-xl +- ボーダー:1px rgba(255, 255, 255, 0.2) +- 微妙なグラデーショングロウ効果 +``` + +#### テンプレート3:Bento Grid(弁当箱) + +``` +**美学スタイル:Bento Grid** + +**フォント:** +- タイトル:SF Pro Display、ウェイト 700 +- 本文:SF Pro Text、ウェイト 400 + +**カラー:** +- 背景:#F5F5F7(薄いグレー) +- カード:#FFFFFF(白) +- アクセント:#0071E3(Appleブルー) + +**レイアウト:** +- グリッドレイアウト、異なるサイズのカードを組み合わせ +- カード間 gap 16px +- 角丸 24px + +**アニメーション:** +- hover時にカードがわずかに浮上 +- クリック時にプレス効果 + +**ディテール:** +- 大きなカードは重要なコンテンツを表示 +- 小さなカードは二次情報を表示 +- テキストの一部をアイコンで代用 +- クリーンなシャドウ(0 4px 24px rgba(0,0,0,0.06)) +``` + +## 3. 方法2:Skillsプラグインでデザイン仕様を自動ロード + +毎回手動でスタイルプロンプトを書くのは面倒です。**Skills**は再利用可能なデザイン仕様パッケージで、インストール後にAIが自動的にこれらの仕様を適用します。 + +### 3.1 インターフェースを美しくする3つのSkills + +| Skills | 特徴 | インストールコマンド | +| :--- | :--- | :--- | +| **UI/UX Pro Max** | 67種のスタイル、96種のカラーリング、57種のフォント組み合わせ | `npm install -g uipro-cli && uipro init --ai claude` | +| **frontend-design** | Anthropic公式、AI審美パターンを回避 | `npx skills add anthropics/skills/frontend-design` | +| **SuperDesign** | IDEプラグイン、複数のデザインバリエーションを生成 | VSCode拡張機能マーケットで「SuperDesign」を検索 | + +### 3.2 UI/UX Pro Maxのインストール(最も推奨) + +UI/UX Pro Maxは現在、最も包括的なデザイン仕様Skillsです。以下がプリセットされています: + +- **67種のUIスタイル**:Glassmorphism、Neumorphism、Brutalism、Bento Grid... +- **96種のカラースキーム**:業界別分類(SaaS、EC、ソーシャル...) +- **57種のフォントペアリング**:プロのデザイナーが検証した組み合わせ +- **100+のデザインルール**:間隔、角丸、シャドウの仕様 + +**インストール手順:** + +```bash +# 1. CLIをグローバルインストール +npm install -g uipro-cli + +# 2. 初期化(使用するAIツールを選択) +uipro init --ai claude +# または +uipro init --ai cursor +# または +uipro init --ai trae +``` + +インストール後、プロンプトに1行追加するだけです: + +``` +UI/UX Pro MaxのGlassmorphismスタイルを使用して、AI執筆アシスタントのランディングページを作ってください +``` + +AIが自動的に対応するフォント、カラー、レイアウトの仕様を適用します。 + +### 3.3 Anthropic公式frontend-designのインストール + +これはAnthropic公式のフロントエンドデザインSkillで、「AI審美パターン」問題を特別に解決します: + +```bash +# Claude Codeで実行 +npx skills add anthropics/skills/frontend-design +``` + +インストール後、AIは自動的に以下を避けます: +- ❌ Inter、Roboto、Arialフォント +- ❌ 紫のグラデーション背景 +- ❌ 対称グリッドレイアウト +- ❌ 薄すぎるシャドウ + +その代わり、以下を好むようになります: +- ✅ ユニークなフォント組み合わせ +- ✅ 大胆なメインカラー + シャープなアクセントカラー +- ✅ 非対称、重なるレイアウト +- ✅ 質感のある背景(ノイズ、幾何学模様) + +## 4. 実践1:美化プロンプトでランディングページを再設計 + +これまでの知識を使って、普通のランディングページを美しくしてみましょう。 + +### 4.1 普通のバージョン + +まず普通のプロンプトでAIが何を出すか見てみましょう: + +``` +ペット里親プラットフォームのランディングページを作ってください。含む: +- ナビバー(ロゴ、リンク、登録ボタン) +- ファーストビュー(タイトル、サブタイトル、CTAボタン、ペット画像) +- ペット紹介(3枚のペットカード) +- 私たちについて +- フッター +``` + +生成されたページは...使えるけど、普通です。 + +### 4.2 美化バージョン + +ここでスタイル説明を追加: + +``` +ペット里親プラットフォームのランディングページを作ってください。要件: + +**美学スタイル:温かく柔らかい + 手描き感** + +**フォント:** +- タイトル:Nunito(丸ゴシック)、ウェイト 700-800 +- 本文:Nunito、ウェイト 400-600 + +**カラー:** +- メインカラー:#FFB347(ウォームオレンジ) +- セカンダリ:#FFCCB3(ライトオレンジ) +- 背景:#FFF8F0(オフホワイト) +- テキスト:#5D4037(ブラウン) + +**レイアウト:** +- 丸みを帯びたカード(border-radius: 24px) +- カードをわずかに傾ける(異なる角度) +- 要素の浮遊、重なり効果 + +**アニメーション:** +- ページロード時に要素が両側からスライドイン +- ペットカードhover時にペットが首を振るような(rotateアニメーション) +- ボタンhover時にバウンス効果 + +**ディテール:** +- すべての角丸は16-24px +- 温かく柔らかいシャドウ(0 8px 24px rgba(255,179,71,0.3)) +- 背景に足跡パターン装飾 +- 画像は不規則な切り抜き(clip-path) +- 手描き風のアイコン(アウトラインスタイル) +``` + +生成されたページは、温かくて可愛く、ペットを里親に出したくなるようなインターフェースになります。 + +## 5. 実践2:Skillsで素早くダッシュボードを生成 + +Skillsはページ数が多いバックエンドシステムに特に適しています。 + +### 5.1 UI/UX Pro Maxを使用 + +``` +UI/UX Pro MaxのDashboard Darkスタイルを使用して、 +SaaSプロダクト管理バックエンドのダッシュボードページを作ってください。含む: + +**トップ:** 4つの統計カード(ユーザー数、アクティブユーザー、収益、API呼び出し) + +**中央:** +- 左:ユーザー成長の折れ線グラフ(直近7日間) +- 右:サブスクリプションプラン分布の円グラフ + +**ボトム:** 最近のアクティビティリスト(時間、ユーザー、操作) +``` + +AIは自動的にダークダッシュボードのデザイン仕様を適用します: +- ダークグレーの背景(#1A1A2E) +- 高コントラストカード(#16213E) +- 鮮やかなデータカラー(青、緑、オレンジ) +- グラスモーフィズム効果の浮遊カード + +### 5.2 frontend-design Skillを使用 + +``` +frontend-design skillを使用して、 +個人ブログのホームページを作ってください。スタイルはユニークで個性的に +``` + +AIは非主流の美学方向(例えばレトロフューチャリズムやマガジンスタイル)を選び、ユニークなフォント、カラーリング、レイアウトで実装します。 + +## 6. 実践3:独自のデザインシステムSkillを作成 + +固定のブランドスタイルがある場合、独自のSkillを作成し、すべてのAI生成ページをブランドに準拠させることができます。 + +### 6.1 Skillファイルの作成 + +プロジェクトに`.claude/skills/my-brand/SKILL.md`を作成: + +````markdown +--- +name: my-brand +description: 私のプロジェクト専用デザインシステム、すべてのUIが統一されたデザイン言語に従うことを保証 +--- + +# 私のプロジェクトデザインシステム + +## ブランドカラー +- メインカラー:#6366F1(Indigo 500) +- セカンダリ:#8B5CF6(Violet 500) +- 成功:#10B981 +- 警告:#F59E0B +- エラー:#EF4444 +- 背景:#F9FAFB +- カード:#FFFFFF + +## フォントシステム +- タイトル:Plus Jakarta Sans + - H1: 700, 48px + - H2: 600, 36px + - H3: 600, 24px +- 本文:Inter + - Body: 400, 16px + - Small: 400, 14px + +## スペーシングシステム +- 基本単位:4px +- コンポーネント内パディング:8px / 12px / 16px +- セクション間隔:24px / 32px / 48px +- ページマージン:64px + +## 角丸 +- ボタン:8px +- カード:12px +- 入力ボックス:8px +- モーダル:16px + +## シャドウ +- 小:0 1px 3px rgba(0,0,0,0.1) +- 中:0 4px 12px rgba(0,0,0,0.1) +- 大:0 8px 24px rgba(0,0,0,0.12) + +## アニメーション +- トランジション時間:150ms / 300ms +- イージング関数:cubic-bezier(0.4, 0, 0.2, 1) +- hover効果:わずかな拡大(scale-105) + +## 禁止スタイル +- 紫のグラデーション背景は使用しない +- Inter以外のフォントは使用しない +- 16pxを超える角丸は使用しない +- 純黒(#000000)は使用せず、#1F2937を使用 +```` + +### 6.2 独自のSkillを使用 + +作成後、プロンプトでこう言うだけです: + +``` +my-brand skillを使用して、ユーザー設定ページを作ってください +``` + +AIが自動的に定義したすべてのデザイン仕様を適用します。 + +## 7. まとめ + +AIに美しいインターフェースを生成させるには2つの方法があります: + +| 方法 | 利点 | 欠点 | 適用シーン | +| :--- | :--- | :--- | +| **プロンプト説明** | 柔軟、毎回調整可能 | 繰り返し書く必要がある | 一度きりのページ、異なるスタイルの実験 | +| **Skillsプラグイン** | 一度インストール、継続的に有効 | インストールと設定が必要 | 固定スタイル要件のあるプロジェクト | + +**Vibe Codingワークフローの提案:** + +1. **探索段階**:異なるスタイルプロンプトで実験し、好みの美学方向を見つける +2. **スタイル確定後**:対応するSkillをインストール(UI/UX Pro Maxまたはfrontend-design) +3. **ブランドプロジェクト**:独自のSkillを作成し、プロジェクト全体のデザイン言語を統一 + +### 練習 + +以下のいずれかのシーンを選び、このレッスンの方法でゼロから完成させてください: + +1. スタイルプロンプトを使って、以前作ったプロジェクトのインターフェースを再設計(好きなスタイルを1つ選ぶ) +2. UI/UX Pro Maxをインストールし、そのスタイルの1つで新しいページを生成 +3. 独自のデザインシステムSkillを作成し、ブランドカラーとフォントを定義 + +--- + +## 付録:デザインスタイル早見表 + +| スタイル | キーワード | 適用シーン | 例のプロダクト | +| :--- | :--- | :--- | :--- | +| **ミニマリズム** | 余白、モノクロ、シンプル | 高級プロダクト、個人ポートフォリオ | Apple公式サイト | +| **グラスモーフィズム** | すりガラス、グラデーション、ブラー | テックプロダクト、SaaSランディング | macOS Big Sur | +| **新ブルータリズム** | 太いボーダー、ハードシャドウ、純色 | トレンドブランド、アート系サイト | Brassius | +| **Bento Grid** | グリッド、コラージュ、カード | 情報表示、ダッシュボード | Apple プロモーションページ | +| **レトロフューチャー** | ネオン、グラデーション、シンセウェーブ | ゲーム系、音楽系 | STRANGER THINGS | +| **手描きスタイル** | 不規則、丸み、イラスト | 教育系、子ども向けプロダクト | Duolingo | +| **マガジン風** | 大きなフォント、非対称、余白 | コンテンツ型サイト、ブログ | Medium | +| **ダークラグジュアリー** | ダーク、ゴールド、精緻 | 高級プロダクト、ラグジュアリーブランド | 各種ハイエンドブランド | + +## 付録:Skillsインストール早見表 + +```bash +# UI/UX Pro Max +npm install -g uipro-cli +uipro init --ai claude + +# Anthropic frontend-design +npx skills add anthropics/skills/frontend-design + +# Anthropic brand-guidelines +npx skills add anthropics/skills/brand-guidelines + +# Claude Codeにインストール済みのSkillsを確認 +/help +``` + +## 付録:カラースキームおすすめ + +| カラースキーム | メインカラー | アクセント | 背景 | スタイル | +| :--- | :--- | :--- | :--- | +| **サンセット** | #F97316 | #FBBF24 | #FFF7ED | 温かい、活力 | +| **オーシャン** | #0EA5E9 | #06B6D4 | #F0F9FF | 清潔、プロフェッショナル | +| **フォレスト** | #10B981 | #34D399 | #ECFDF5 | 自然、健康 | +| **ベリー** | #8B5CF6 | #EC4899 | #FAF5FF | ロマンチック、クリエイティブ | +| **コーヒー** | #78350F | #D97706 | #FFFBEB | 温かい、レトロ | +| **ストーン** | #6B7280 | #9CA3AF | #F9FAFB | プロフェッショナル、ニュートラル | + +## 付録:デザインスタイルプロンプト早見表 {#style-prompts} + +フロントエンドページをより美しくするためのプロンプト: + +### スタイルカテゴリ + +| スタイル | キーワード(英語) | 核心的な視覚特徴 | プロンプト例 | +|:---|:---|:---|:---| +| **ポップアート** | Pop Art | 大胆な色の衝突、黒い輪郭線、ドットテクスチャ | Pop art style website, bold colors and comic dots, vibrant | +| **ミニマリズム** | Minimalism | 豊富な余白、極少の色と線、装飾なし | Minimalist web design, ample white space, geometric, serene | +| **抽象表現主義** | Abstract Expressionism | 感情的な筆致、色の飛び散り | Abstract expressionism background, dynamic paint splashes, emotional | +| **レトロスタイル** | Retro/Vintage | オールドスタイルのフォント、アンティークテクスチャ、レトロカラー | Retro 80s website design, neon grid and synthwave color palette | +| **サイバーパンク** | Cyberpunk | 高コントラストのネオン、グリッチアート効果、ダーク背景 | Cyberpunk UI, neon lights on dark background, glitch effects | +| **ニューモーフィズム** | Neumorphism | 柔らかなシャドウとハイライト、わずかな隆起/陥没質感 | Neumorphism design style, soft shadows, clean and modern | +| **ジェネレーティブアート** | Generative Art | アルゴリズム生成の流動的な視覚パターン | Generative art background, flowing algorithmic patterns, digital | +| **アシッドデザイン** | Acid Graphics | メタリック質感、ガラス態、ギザギザフォント | Acid graphics web layout, glass morphism, chaotic typography | +| **イマーシブ3D** | Immersive 3D | インタラクティブ3Dシーン、強い空間感 | Immersive 3D website, interactive product model in space | diff --git a/docs/ja-jp/stage-2/frontend/lovart-assets/index.md b/docs/ja-jp/stage-2/frontend/lovart-assets/index.md new file mode 100644 index 0000000..11b9070 --- /dev/null +++ b/docs/ja-jp/stage-2/frontend/lovart-assets/index.md @@ -0,0 +1,949 @@ + + +# NanoBananaから始めよう:自分だけの素材生成Agentを構築 + +## 第1章:1分で最初の画像素材を生成 + +デザイン、スタイル、プロンプトについて議論する前に、まずは最短手順で最初の1枚を生成してみましょう。 + +### 1.1 NanoBananaを知ろう + +デザインスタイルやプロンプトエンジニアリングについて話す前に、まず最初により重要なことを確認しましょう:**あなたが本当に画像を生成できるかどうか。** + +現在、主要な大規模モデルはすでに画像生成・編集能力を備えており、このようなモデルは一般的に**生成モデル**と呼ばれています。 + +本チュートリアルでは、プロセスをできるだけシンプルにするため、安定した画像生成・編集能力を備えたモデルを例として選びました——NanoBananaです。これはGoogleが提供する画像生成モデルで、正式名称は**Gemini 3.1 Flash Image Preview**で、自然言語による直接画像生成をサポートし、既存画像のベースでの修正もサポートしています。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image1.png) + +能力面では、あなたが聞いたことのある他のモデル(GPT-4o、Claude、Qwen、Midjourneyなど)と本質的な違いはありません:**説明を入力し、モデルが結果を生成する。** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image2.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image3.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image4.png) + +これは「絵筆」と考えることができます。この章では1つのことだけを気にします: +👉 **この絵筆があなたの手で最初の一筆を描けるかどうか。** + +実際の使用では、NanoBananaは**Google AI Studio**などの公式プラットフォームから直接使用することも、**API**として開発フローに統合することもできます。本チュートリアルではAPI呼び出し方式を採用しています。現在はNanoBanana 2モデルもリリースされており、最新の大規模モデルで試すこともできます。 + +### 1.2 「Hello World」レベルの生成 + +始める前に、以下の3つのステップを完了するだけです: + +1. Traeで新しいフォルダを作成 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image5.png) + +2. 新しいPythonファイルを作成 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image6.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image7.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image8.png) + +3. 以下のコードをそのまま貼り付ける + +Traeが必要な環境構築と依存関係のインストールを自動的に完了するため、追加の設定は不要です。 + +コード内でNanoBananaのAPI Keyを使用します。ここでは申請手順は詳しく説明しません——対応するパラメータを取得して入力できれば十分です。**この段階では、各行のコードを理解することを目指す必要はなく、正常に実行できればOKです。** + +```Python +# /// script +# dependencies = [ +# "gradio>=4.0.0", +# "pillow>=10.0.0", +# "requests>=2.31.0", +# ] +# /// + +import gradio as gr +import requests +import base64 +from PIL import Image +import io +import os +import time +import re +from typing import Optional, Dict, Any, List + +# API情報の設定 +NANOBANANA_API_URL: str = "YOUR API URL" +NANOBANANA_API_KEY: str = "YOUR API KEY" +OUTPUT_DIR: str = "outputs" + +# 出力ディレクトリの存在を確認 +os.makedirs(OUTPUT_DIR, exist_ok=True) + +def image_to_base64_data_uri(image: Image.Image) -> str: + """ + PIL画像をOpenAI API互換のdata URI形式に変換する。 + """ + buffer = io.BytesIO() + # 互換性を保証するためPNGに統一 + image.save(buffer, format="PNG") + encoded = base64.b64encode(buffer.getvalue()).decode('utf-8') + return f"data:image/png;base64,{encoded}" + +def base64_to_image(base64_str: str) -> Optional[Image.Image]: + """ + 純粋なbase64文字列をPIL Imageに変換する。 + """ + try: + image_bytes = base64.b64decode(base64_str) + return Image.open(io.BytesIO(image_bytes)) + except Exception as e: + print(f"Base64 デコード失敗: {e}") + return None + +def extract_base64_from_response(content: Any) -> Optional[str]: + """ + コア解析ロジック:API返却のcontentから画像のBase64データを抽出する。 + Markdown形式と構造化リスト形式の両方に対応。 + """ + if not content: + return None + + base64_data = None + + # 1. 構造化抽出を試行 (List) + # 対応返却形式: [{"type": "image_url", "image_url": {"url": "data:..."}}] + if isinstance(content, list): + for part in reversed(content): # 逆順検索、通常最新の画像は最後にある + if isinstance(part, dict): + # image_url または output_image フィールドを確認 + img_field = part.get("image_url") or part.get("image") or part.get("output_image") + if isinstance(img_field, dict): + url = img_field.get("url", "") + if url.startswith("data:image/") and "," in url: + return url.split(",", 1)[1].strip() + + # リスト中に構造化画像がない場合、リスト内のテキストを結合してMarkdownを検索 + text_parts = [ + str(p.get("text", "")) + for p in content + if isinstance(p, dict) and p.get("type") in ["text", "input_text"] + ] + content_str = "".join(text_parts) + else: + content_str = str(content) + + # 2. Markdown正規表現抽出を試行 (String) + # 対応返却形式: "Here is your image: ![img](data:image/png;base64,AAAA...)" + pattern = re.compile(r"!\[.*?\]\((data:image/[^;]+;base64,[^)]+)\)", re.IGNORECASE) + match = pattern.search(content_str) + + if match: + data_url = match.group(1) + if "," in data_url: + return data_url.split(",", 1)[1].strip() + + return None + +def synthesize(prompt: str, input_image: Optional[Image.Image]) -> Optional[Image.Image]: + """ + Nanobanana APIを呼び出して生成する。 + """ + if not prompt or not prompt.strip(): + gr.Warning("プロンプトを入力してください") + return None + + print(f">>> タスク開始: {prompt[:50]}...") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {NANOBANANA_API_KEY}" + } + + # OpenAI Vision / Chat標準に準拠したpayloadを構築 + messages = [] + + if input_image is not None: + # 画像から画像/マルチモーダル入力モード + print(">>> 入力画像を検出、マルチモーダルモードを使用") + img_base64 = image_to_base64_data_uri(input_image) + messages.append({ + "role": "user", + "content": [ + {"type": "text", "text": prompt}, + {"type": "image_url", "image_url": {"url": img_base64}} + ] + }) + else: + # テキストから画像生成モード + messages.append({ + "role": "user", + "content": prompt + }) + + payload = { + "messages": messages, + # 検証済みの利用可能なモデルを使用 + "model": "gemini-2.5-flash-image", + # オプションパラメータ、APIのサポート状況に依存 + "stream": False + } + + try: + # タイムアウトを延長、画像生成は通常遅い + response = requests.post(NANOBANANA_API_URL, headers=headers, json=payload, timeout=120) + + # HTTPステータスを確認 + if response.status_code != 200: + error_msg = f"APIリクエスト失敗: {response.status_code} - {response.text}" + print(error_msg) + gr.Error(error_msg) + return None + + result = response.json() + # Debug: 返却結果の前半部分を出力し、デバッグに便利 + print(f"API生レスポンス (抜粋): {str(result)[:200]}...") + + # Contentを抽出 + content = None + if "choices" in result and len(result["choices"]) > 0: + content = result["choices"][0].get("message", {}).get("content") + + if not content: + gr.Warning("API返却結果にcontentフィールドがありません") + return None + + # 検証済みのロジックでBase64を抽出 + base64_str = extract_base64_from_response(content) + + if base64_str: + output_image = base64_to_image(base64_str) + if output_image: + return output_image + + # 画像が抽出されなかった場合、モデルが拒否したかテキストのみ返却した可能性 + text_content = str(content) if not isinstance(content, list) else " ".join([str(x) for x in content]) + gr.Info(f"画像が生成されず、モデルがテキストを返却: {text_content[:100]}...") + return None + + except requests.exceptions.Timeout: + gr.Error("リクエストがタイムアウトしました。後でもう一度お試しください") + return None + except Exception as e: + import traceback + traceback.print_exc() + gr.Error(f"不明なエラーが発生しました: {str(e)}") + return None + +# Gradioインターフェース設定 +with gr.Blocks(title="Nanobanana Image Generator") as app: + gr.Markdown("# 🍌 Nanobanana Text/Image to Image") + gr.Markdown("Gemini-2.5-Flash-Imageモデルベース、テキストから画像・画像から画像に対応。") + + with gr.Row(): + with gr.Column(): + prompt_input = gr.Textbox( + label="プロンプト (Prompt)", + placeholder="例: A cyberpunk cat holding a neon sign...", + lines=3 + ) + image_input = gr.Image( + label="参考画像 (任意、画像から画像生成に使用)", + type="pil", + height=300 + ) + submit_btn = gr.Button("生成開始", variant="primary") + + with gr.Column(): + image_output = gr.Image(label="生成結果", format="png") + + submit_btn.click( + fn=synthesize, + inputs=[prompt_input, image_input], + outputs=image_output + ) + +if __name__ == "__main__": + app.launch(share=True) +``` + +Traeが実行成功を示したら、提供されたローカルリンク(通常は http://127.0.0.1:7860)をクリックします。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image9.png) + +すべて正常であれば、すでに動作するAI描画インターフェースが表示されます。 + +このインターフェースはシンプルに見えますが、商用レベルの描画ツールにおける最も核心的な2つの機能を備えています。すなわち、テキストから画像と画像から画像です。 + +* **左側:** **指示エリア (** **Input** Zone) —— ここで指示を出します。 +* **Prompt (プロンプトボックス):** クリエイティブな説明を入力(英語での使用を推奨)。 +* **Input** Image (参考画像ボックス): + * **テキストから画像モード:** ここを**空のまま**にします。 + * **画像から画像モード:** ローカル画像をここにドラッグすると、AIがそれをベースに創作します。 +* **Submit ボタン:** クリックして指示を送信し、生成を開始。 +* **右側:表示エリア (** **Output** Zone) —— 奇跡を目撃する場所、生成結果がここに表示されます。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image10.png) + +それでは、最初の画像を生成してみましょう! + +この例で使用するpromptは以下の通りです: + +> **A red apple** + +これは意図的にシンプル化された例で、スタイルやパラメータの説明は含まれていません。 + +#### 実際のフロー + +コードを実行した後、フローは3つのステップに要約できます: + +1. テキスト説明をモデルに送信 +2. モデルが対応する画像を生成 +3. 画像がローカルファイルとして保存 + +数秒後、ローカルで生成結果が表示されます。モデルの生成にはランダム性があるため、同じpromptでも異なる生成結果になります。複数回生成して、お気に入りの画像を選んでください。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image11.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image12.png) + +プロンプトを充実させ、より多くの説明と制約を与えることもできます。例えば以下のプロンプトを使用すると、より特徴的な画像が得られます。 + +```Plain +"A hyper-realistic close-up of a fresh red apple with water droplets on its skin, sitting on a dark rustic wooden table. Cinematic dramatic lighting, rim light, shallow depth of field, bokeh background, 8k resolution, macro photography." +(水滴のある新鮮な赤いリンゴの超写真的クローズアップ、暗く粗削りな木製テーブルの上。シネマティックなドラマチックライティング、リムライト、浅い被写界深度、ボケ背景、8k解像度、マクロ撮影。) +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image13.png) + +Output Imageエリアでダウンロードをクリックすると、画像をローカルに保存できます。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image14.png) + +### 1.3 画像生成モデルの一般的な素材生成シーン + +実際の業務では、大規模モデルによる画像生成は、単一の芸術作品を創作するよりも**効率的なデザイン素材の生産**に使われることが多いです。 + +デザイン系マーケティングアカウントの高評価ケースを観察すると、その多くは2つのシーンに集中していることがわかります: + +* **テキストから画像(0から1へ)** +* **参考画像からの画像生成(1からNへ)** + +#### 一、テキストから画像:デザイン素材を素早く入手 + +このカテゴリのシーンは効率を重視します。デザインにおける空白(空状態、アバター、挿絵など)を埋める必要がある場合、AIは本質的に**リアルタイム生成の画像ライブラリ**として機能します。 + +1. ##### UIデザイン素材の生成 + +* トレンド:Dribbbleでよく見かけるグラスモーフィズム、クレイスタイルの3Dアイコン +* よくある表現:透明感のある素材、縁の発光、キャンディカラーの機能や天気アイコン + +**サンプル Prompt:** + +> A set of 3D weather icons (sun, cloud, rain), glassmorphism style, frosted glass texture, soft pastel gradient colors, soft studio lighting, isometric view, transparent background, 4k. + +(3D天気アイコンセット、グラスモーフィズムスタイル、すりガラスのテクスチャ、柔らかなパステルグラデーションカラー、スタジオライティング、アイソメトリックビュー) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image15.png) + +2. ##### ロゴの生成 + +* トレンド:ミニマルなライン、幾何学的な組み合わせのテクノロジー感のあるロゴ +* よくある表現:白黒配色、ネガティブスペースデザイン、ブランド感が明確 + +**サンプル Prompt:** + +> Minimalist vector logo design for a tech brand "Coffee Code", combining a coffee cup with coding brackets < >, flat design, solid black lines, white background, Paul Rand style, svg. + +(ミニマルなベクターロゴ、コーヒーカップとコーディング括弧の組み合わせ、フラットデザイン、純黒ライン) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image16.png) + +3. ##### 公式サイトのユーザー画像生成 + +* トレンド:SaaS公式サイトでよく使われる3Dバーチャルアバター、実写の著作権問題を回避 +* よくある表現:フレンドリーな表情、カートゥーン比率、PixarやMemojiスタイル寄り + +**サンプル Prompt:** + +> Close-up portrait of a friendly young tech professional, smiling, Memoji 3D style, clay render, bright colors, soft lighting, solid plain background, Pixar character design. + +(フレンドリーな若手テックプロフェッショナル、3D Memojiスタイル、クレイレンダリング) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image17.png) + +4. ##### 記事の挿絵生成 + +* トレンド:テック企業ブログでよく見かける抽象的なフラットイラスト +* よくある表現:紫と青の配色、誇張された人物比率、浮遊するUI要素 + +**サンプル Prompt:** + +> Editorial flat illustration representing remote work, a person sitting on a giant globe using a laptop, corporate memphis art style, vibrant colors (purple and teal), vector texture. + +(リモートワークをテーマにしたフラットイラスト、コーポレートメンフィススタイル) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image18.png) + +#### 二、参考画像からの画像生成:視覚的一貫性の維持 + +このカテゴリのシーンは**拡張性**に焦点を当てています。満足のいくメインビジュアルが1つあり、それとスタイルが一致する一連の素材を生成する必要がある場合に使用します。 + +5. ##### メインビジュアルに類似した一連のボタンやインタラクション素材画像 + +ゲーム開発では、UIの一貫性が非常に重要です。メイン画面の「PLAY」ボタンがすでにあると仮定し、スタイルが統一された一連の機能ボタン(一時停止、設定、ホームなど)を追加で生成する必要があるとします。手描きだけで各ボタンの光沢、パースペクティブ、色味の完全な一致性を保証するのは困難です。 + +**基本的な操作フロー:** + +1. 既存の青色「PLAY」ボタン画像を保存 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image19.png) + +2. インターフェースの**Input** **Image**エリアにドラッグし、以降の生成の参考マスターとする +3. promptのスタイル説明は変更せず、メインコンテンツのみを変更 + +このフローでは、メインの説明を置き換えるだけで、機能は異なるがスタイルが一致したボタンを得ることができます。 + +**サンプル Prompt:** + +**バリアント A:一時停止ボタン(アイコンタイプ)** + +> A capsule-shaped game UI button with a white pause icon (two vertical bars) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(カプセル型ゲームUIボタン、白色の一時停止アイコン、ブルーのゼリー質感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image20.png) + +**バリアント B:設定ボタン(複雑なアイコン)** + +> A capsule-shaped game UI button with a white gear icon (settings symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(カプセル型ゲームUIボタン、白色の歯車アイコン、ブルーのゼリー質感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image21.png) + +**バリアント C:リプレイボタン(形状変更)** + +ボタンの外形を調整する必要がある場合、promptで直接形状を説明すると、モデルは素材の特徴を維持しながら構造の変更を試みます。 + +> A round game UI button with a white circular arrow icon (replay symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(円形ゲームUIボタン、循環矢印アイコン、ブルーのゼリー質感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image22.png) + +この一連の操作により、ボタンの機能やアイコンを置き換えるだけでなく、ボタンの形状を変えることさえできますが、すべての生成結果は素材、カラーリング、光と影において高い一貫性を保ちます。これこそが、大規模モデルがデザイン素材の派生シーンにおいて持つ核心的な価値です。 + +## 第2章:より従順な画像生成アシスタント —— Lovartを例に + +第1部では、コードを通じて直接NanoBananaを呼び出し、「入力すれば生成」という基本フローを体験しました。この方法はニーズがシンプルな場合には問題ありません。しかし、生成タスクにさらに多くの制約が含まれるようになると、例えば: + +* 複数のスタイルが一致した画像が必要 +* 既存の結果に基づいて繰り返し調整が必要 +* ユーザー入力に基づいて生成方向を動的に変更する必要がある + +単一呼び出しの方式では次第に対応が困難になります。 + +ここで、**AI Agent(エージェント)**の導入が必要になります。本節では**Lovart**を例に、画像生成モデルに「思考層」が備わった後、全体的なワークフローがどのように変化するかを示します。注意!ここは広告ではなく、皆さんにAI Agentの利便性を素早く理解してもらうためのものです~ + +### 2.0 Lovart入門:あなたのAIデザインエージェント + +LovartはAgentベースのデザインツールWebです。通常の画像生成ツールと比較して、生成の前に「思考と計画」の層が1つ追加されています。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image23.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image24.png) + +Lovartに入った後、主に以下の制御項目を理解する必要があります: + +#### モデル選択 + +入力ボックスの下にある立方体アイコンをクリックすると、現在利用可能な生成モデル(GPT Image、Fluxなど)を確認できます。 + +前述の例との一貫性を保つため、本節では引き続きNanoBananaを基盤生成モデルとして使用します。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image25.png) + +#### 思考モード + +これがLovartの核心的なスイッチです: + +* **Fast Mode(⚡)**:ネイティブAPIに近く、レスポンスが速く、単一で明確な指示の生成に適している +* **Thinking Mode(💡)**:Agentモード、AIがまずニーズを分解し、promptを書き直してから生成を実行 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image26.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image27.png) + +#### インターネット接続機能 + +地球儀アイコンをオンにすると、Agentは生成過程でネットワーク情報(デザイントレンド、カラーパレットなど)を検索し、補助入力として利用できます。 + +### 2.1 なぜネイティブAPIだけでは不十分なのか? + +Pythonで品質の良い画像を生成できるようになっても、ネイティブAPIは複雑なタスクでは依然として制限があります。重要な理由は、ネイティブAPIが本質的に命令型であることです。具体的なオブジェクトの生成を要求された場合、直接実行できますが、入力が「完全なゲーム素材セットの企画」になると、目標を複数の実行可能なステップに自発的に分解することはありません。 + +Lovartの核心的な違いはAgentメカニズムにあります。ユーザー入力と画像生成モデルの間に、理解と計画のためのロジック層を追加します:まずユーザーの意図を識別し、次にタスクを分解し、promptを書き直し、最後に生成を実行します。 + +### 2.2 実践デモ:5分でIPスタンプセットを作る + +**「プログラマー鸭のIPスタンプセットを作る」**を例に、Agentがプロセス全体にどのように関与するかを見てみましょう。 + +#### ステップ1:企画(Agentの思考能力) + +**ネイティブAPIの問題点:** +自分でキャラクター設定、感情状態を考え、各画像ごとに個別にpromptを書く必要があります。 + +**Lovartのアプローチ:** + +1. 💡 **Thinking Mode**を点灯 +2. 1つの指示を入力: + +> プログラマー鸭のIPスタンプセットをデザインして、スタイルはフラットで可愛く + +AIはすぐに絵を描くのではなく、まずネットで関連するプログラマー鸭のデザイン画像を検索します。分解されたプランを出力し、Debug、Coffee Break、Panicなどのシーンを自動生成し、対応する複数の視覚説明を生成します。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image28.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image29.png) + +このステップで、AIは「実行者」から「企画者」へと変わります。AIがニーズの分析を完了した後、Lovartのキャンバスエリアで様々なスタイルとコンテンツのプログラマー鸭画像を見ることができます。お気に入りのスタイルを選び始めることができます。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image30.png) + +#### ステップ2:一貫性(参考に基づく視覚的アンカー) + +Lovartの画像は結果であるだけでなく、以降の生成にも参加します。 + +##### 完全な参考画像 + +* スケッチから最も満足のいく「標準的な鸭」を1枚選び、キャンバスエリアで対応する画像をクリック +* その画像は自動的に対話エリアにReferenceとして表示されます + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image31.png) + +* 新しい動作(例:嬉しい)を入力して生成 + +生成結果はマスター画像のカラーリング、比率、ディテールを継承します。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image32.png) + +##### 部分参考 / 複数画像の統合 + +画像全体を参考にするだけでなく、Lovartは以下もサポートしています: + +* **画像の部分的な領域のみを選択**(例:帽子や表情のみを参考にする) + +キャンバスエリア左側のタブバーをクリックし、「Mark」キーを選択し、ターゲット画像の部分領域をマークすると、この部分の内容が自動的に対話ボックスに同期されます。例えば、ここでは背景の色を変更するよう選択できます。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image33.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image34.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image35.png) + +新しく生成された画像が背景の色のみを変更しており、これは入力した要求とも一致していることがわかります。 + +* **複数の画像からそれぞれサブ要素を引用**し、組み合わせて新しい結果を生成 + +例えば:画像Aのキャラクター本体を保持しつつ、帽子だけを画像Bのスタイルに置き換えることができ、Agentはバックグラウンドでこれらの視覚的制約を自動的に統合します。 + +プログラマー鸭を例にすると、最初の画像の鸭のキャラクターを保持し、それを2枚目の画像のメイン要素として置き換えることができます。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image36.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image37.png) + +最終的な効果も非常に顕著です。他の組み合わせも試してみてください! + +#### ステップ3:仕上げ(Agentのツール呼び出し) + +生成が完了したら、直接実行できます:拡大、背景除去、消去などの操作 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image38.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image39.png) + +これらは単純なフィルターではなく、Agentが異なるツールを自動的に呼び出して完成させた結果です。 + +基調スタイルが確定した後、一連のスタンプ画像を非常に速く生成できます。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image40.png) + +最終的に得られるのは、直接納品可能な本番レベルの素材であり、単なる展示画像ではありません。 + +### 2.3 利用料金について + +Lovartはサブスクリプション制の課金モデルを採用しており、異なるプランは異なる使用量と機能権限に対応しています。詳細は公式サイトの表示をご確認ください。 + +本チュートリアルはいかなるプランの推奨や比較も行いません。実際の使用で必要がある場合は、個人の状況に応じて有料アップグレードを選択できます。 +現在は**Alipay**などでの支払いに対応しています。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image41.png) + +#### まとめ + +Lovartは基盤モデルを代替するものではなく、Agentメカニズムを通じて、画像生成を「単一実行」から「連続ワークフロー」へとアップグレードします。 + +タスクが企画、一貫性、納品に関わり始めると、この種のツールの利点が非常に明確になります。 + +## 第3章:自分でスマート描画アシスタントを作ろう + +Lovartを直接使用するだけでなく、自分で簡易版の描画アシスタントを実装することもできます。 + +本章では「記事の自動挿絵」を例に、実際の問題から出発し、段階的に思考能力を持つAgentを構築します。 + +### 3.1 課題の導入:なぜ記事をそのまま画像生成モデルに送ってもうまくいかないのか? + +長い記事をNanoBananaに直接入力して挿絵を求めても、通常は理想的な結果が得られません。理由はモデルが「描くのが下手」だからではなく、**長いテキストの理解が得意ではない**からです。 + +画像生成モデルは短く明確な視覚的説明を処理するのに適しており、入力が構造、要点、文脈関係を含む記事になると、モデルはどの内容が画像で表現すべき部分なのかを判断できません。これにより、生成結果がテーマから逸脱したり、断片的なディテールしか捉えられず、全体的な要約力が欠如することになります。 + +本質的に、画像モデルには「実行」する能力はあっても、テキストを分析し取捨選択するプロセスが欠けています。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image42.png) + +### 3.2 解決アプローチ:Agentで「理解」と「実行」を分ける + +この問題を解決するための鍵は、より複雑なプロンプトではなく、**画像生成の前にまず考えること**です。したがって、生成フローに独立した「思考層」を導入し、それを使って最もシンプルな利用可能なAgentを構築します。 + +このAgentの核心的な目標は1つだけです:**最終的に生成される画像が、ユーザーの真の表現意図にできるだけ近づくこと。** + +全体のフローは次のように要約できます:**長いテキスト入力 → 言語モデルによる理解と判断 → 適切な視覚プロンプトの生成 → 画像モデルによる生成の実行 → 画像の出力** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image43.png) + +では、私たちが構築するAgentはどうやってユーザーの意図を理解するのでしょうか? + +ここでは簡略化された**「思考層」**を作ることを選択し、3つの異なる意図を設定しました:無効な入力、直接画像生成、理解が必要な長いテキスト。 + +このAgentでは、各役割の分担は4つのポイントに要約できます: + +1. **言語モデルが意思決定の核心として** + 記事の内容を理解し、ユーザー入力の意図を判断し、タスクを適切な生成パスに配信し、「次にどうすべきか」および画像生成プロンプトの生成方法を決定する役割を担います。 +2. **画像モデルが実行者として** + 画像モデルは理解と判断には参加せず、すでに整理された視覚的指示のみを受け取り、画像レンダリングの完成に集中します。 +3. **ユーザーが介入可能なガイドとして** + テキストを直接入力するだけでなく、プロセス中に生成されたプロンプトを手動で調整したり、参考画像を追加して生成を補助し、最終結果をガイド・微調整することもできます。 +4. **GradioとバックエンドAPIが全体のサポート層として** + インターフェース、モデル呼び出し、結果表示を連携し、Agent全体が完全なWebアプリケーションとして安定して動作できるようにします。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image44.png) + +### 3.3 実践準備:APIの取得 + +とても面白そうですね!上記のフローを実行するために、必要なAPIは2種類だけです。 + +#### 手:NanoBanana API(画像生成) + +第1章で既に設定済みのAPI KeyとAPI URLをそのまま使用し、追加の設定は不要です。 + +#### 脳:SiliconFlow API(テキスト思考) + +「思考層」の役割を担う大規模言語モデルが必要です。本チュートリアルではSiliconFlowが提供するモデルサービスを使用します:[https://cloud.siliconflow.cn](https://cloud.siliconflow.cn/) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image45.png) + +SiliconFlowはOpenAI API仕様と互換性のあるインターフェースを提供しており、標準的なネットワークリクエストでプロジェクトに非常に便利に統合できます。ここで選択したのは無料のQwen2.5-7B-Instructモデルで、呼び出しに必要な内容は以下のPromptにすべて記載されています。始める前に、公式サイトでアカウントを登録しAPI Keyを作成するだけです。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image46.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image47.png) + +このKeyは以降のモデル呼び出しに使用されます。 + +### 3.4 Agentの構築: + +今回の実験では主にTraeを使用してコードを記述します。本チュートリアルで選択したのはGemini-3-Pro-Previewモデルです。全体的なアプローチは、新しいプロジェクトを作成した後、以下の完全なPromptを対話ボックスにコピーして入力し、段階的にAPI KEYを置き換えた後コードを実行し、テストを完了します。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image48.png) + +#### ステップ1️⃣:Gradio Blocks基本フレームワークとインターフェースレイアウト + +このステップでは、Agent全体の「外観」を構築し、フロントエンドのページデザインを実現することが主な目標です。以下のPromptをコピーしてTraeの対話ボックスで実装すると、ローカルのURL(通常は http://127.0.0.1:7860)が取得でき、インターフェースを確認し、実装効果を検証できます。 + +```Plain +セクション 1:Gradio Blocks基本フレームワークとインターフェースレイアウト +1、タスク目標 +· Gradio 4.0.0+のBlocksレイアウトに基づいて、「LLM+Nanobananaテキストから画像」プロジェクトの基本インターフェースを実装し、固定左右分割レイアウトを厳格に遵守し、すべてのUIコンポーネントを初期化し正しい初期状態を設定。 + +2、技術スタック要件 +· Gradio 4.0.0+のBlocksモードでの開発を使用、Interfaceモードの使用は禁止; +· 依存関係:gradio>=4.0.0、pillow>=10.0.0(インポートのみ、画像処理ロジックは一時未実装); +· コードは完全に実行可能なPythonファイルで、すべての必要なインポート文を含む。 + +3、インターフェースレイアウトルール(核心制約、実践的詳細を統合) +·全体レイアウト: +ページタイトル:LLM駆動のテキストから画像全プロセスツール; +固定左右分割:左側60%幅、右側40%幅、gr.Rowとgr.Columnで比率制御を実現。 +·左側60%(プロンプト生成プロセスエリア)コンポーネント一覧: +input_text:gr.Textbox、ラベル「入力テキスト(チュートリアル段落 / 描画指示)」、lines=6、プレースホルダー「画像挿絵用のチュートリアルテキストまたは直接描画指示を入力...」; +identify_intent_btn:gr.Button、value="意図を識別"、初期状態は通常クリック可能; +intent_status:gr.Textbox、ラベル「意図タイプ / 処理ステータス」、lines=2、interactive=False、初期値「意図未識別」; +system_prompt:gr.Textbox、ラベル「System Prompt(記事挿絵意図のみ編集可能)」、lines=4、interactive=False、プレースホルダー「LLMがプロンプトを生成する際の制約ルール...」; +confirm_prompt_btn:gr.Button、value="画像生成プロンプトを確認"、interactive=False(誤操作防止のため初期無効); +generation_prompt:gr.Textbox、ラベル「画像生成プロンプト(編集可能)」、lines=3、interactive=True、初期値は空、プレースホルダー「生成された英語の画像生成プロンプトがここに表示されます、手動での修正に対応...」。 +·右側40%(Nanobanana画像生成機能エリア)コンポーネント一覧: +ref_image:gr.Image、ラベル「参考画像(任意、画像から画像生成)」、type=filepath、height=300、アップロード許可; +generate_btn:gr.Button、value="画像を生成"、interactive=False(初期無効、プロンプトがないとクリック不可); +result_image:gr.Image、ラベル="生成結果"、type=pil、height=300、初期は空、interactive=False。 + +4、インタラクションロジック要件 +·すべてのコンポーネントのinteractive初期状態は上記設定に厳格に従い、その後関数で動的に更新; +·ボタンの無効状態は直感的に(グレーアウト)、ユーザーの誤操作を防止。 + +5、出力要件 +·完全なPythonコードを生成、インターフェースレイアウトとコンポーネントの初期化のみを実装、ビジネスロジックは含まない; +·コードコメントは明確、コンポーネント名は実践版と一致(input_text/identify_intent_btnなど); +·コードは直接実行可能、インターフェース構造は説明と完全に一致。 +``` + +ブラウザでhttp://127.0.0.1:7860を開くと、Traeが要件に従って以下のWebページを生成していることが確認できます。要求とほぼ一致しており、次の生成ステップに進めます。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image49.png) + +#### ステップ2️⃣:LLM意図認識モジュール(Siliconflow API) + +日常的にVLMで画像を描く際、以下の3つの一般的な入力パターンがあります: + +1. 無意味な内容、「こんにちは」「今日ご飯食べた?」など、対応する画像が描けない。 +2. 記事/長文、文字数が多く、例えば200字程度の構造化された記事で、まず文章の構造と内容を理解してから、この文章全体を要約できる画像の生成方法を考える必要がある。 +3. 直接的な描画指示、「お風呂に入っている犬を描いて」など、要求がすでに非常に具体的で、直接画像を生成できる。 + +前と同様に、以下のPromptをコピーしてTraeの対話ボックスで実装し、前のステップで取得したAPIを追加します。 + +```Plain +セクション 2:LLM意図認識モジュール(Siliconflow API) +1、タスク目標 +実装済みのGradioインターフェースを基に、「意図を識別」ボタンにクリックロジックを追加し、Siliconflow APIを呼び出して意図認識を完了し、コンポーネント状態と連動。 + +2、技術スタック要件 +Gradio 4.0.0+ Blocksに基づく; +依存関係:requests>=2.31.0、openai; +セクション1インターフェース + 本モジュールロジックを含む完全な実行可能Pythonファイルを出力。 + +3、核心ビジネスルール(絶対に逸脱不可) +·意図分類ルール(3種類のみ、数字 + 説明を厳格に返却) +1 = 無意味な内容:雑談、挨拶、無関係な会話のみで、描画や挿絵のニーズが全くない(例:「こんにちは」「今日食べた?」); +2 = 記事 / 長文の挿絵ニーズ:ユーザーが完全な記事、チュートリアル、段落、説明文を入力し、内容は叙述 / 説明 / 解説に偏り、この内容に挿絵を生成する意図が暗黙的に含まれる。ユーザーが「この文章に挿絵をつけて」と明示的に言う必要はない; +3 = 直接的な描画指示:ユーザーが短く明確な描画コマンドを入力し、長文の背景がなく、直接特定の内容を描くよう要求(例:「Apple風の猫を描いて」)。 +·LLM呼び出し制約(実践版テンプレートを統合) +インターフェースURL:https://api.siliconflow.cn/v1/chat/completions; +モデル:Qwen/Qwen2.5-7B-Instruct; +temperature=0.1; +統一定義コード: +python +実行 +LLM_BASE_URL = "https://api.siliconflow.cn/v1" +LLM_API_KEY = "" # ユーザーが各自入力 +LLM_MODEL = "Qwen/Qwen2.5-7B-Instruct"# 実践検証済み意図認識テンプレート(コードに固定) +INTENT_PROMPT_TEMPLATE = """ユーザー入力テキストの意図を識別する必要があります。以下の3種類の結果のうち1つのみを返却(形式:数字 + 中国語の説明): +1 = 無意味な内容;2 = 記事 / 長文の挿絵ニーズ;3 = 直接的な描画指示。 + +ユーザー入力:{user_input} + +認識結果: +結果中の数字と説明のみを抽出して返却し、余分な内容は禁止。""" + +4、コンポーネント連動ルール +·結果が1:intent_statusに「1 = 無意味な内容:描画ニーズなし」と表示、system_promptは無効状態を維持、confirm_prompt_btnは無効; +·結果が2:intent_statusに「2 = 記事 / 長文の挿絵ニーズ:入力内容に挿絵を生成」と表示、system_promptを有効化しデフォルトルールを充填、confirm_prompt_btnを有効化; +·結果が3:intent_statusに「3 = 直接的な描画指示:指示に基づいて画像を生成」と表示、system_promptは無効状態でデフォルトルールを充填、confirm_prompt_btnを有効化。 + +5、例外処理 +API例外、解析例外はすべてフレンドリーなプロンプトを表示し、クラッシュせず、コンポーネントは初期状態に復帰。 + +6、出力要件 +LLM_API_KEYを置き換えるだけで使用可能な完全な実行可能コードを生成、ロジックは明確でコメントは完全、意図認識テンプレートは実践版を厳格に使用。 +``` + +以前のhttp://127.0.0.1:7860のURLをリフレッシュし、3つのケースを正しく認識できるかテストを開始します。 + +1. 無意味な内容、「こんにちは」「ありがとう」などを入力して試すと、正常に認識できることが確認できます。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image50.png) + +2. 記事/長文、ここではDoubaoが生成した人工知能に関する文章を使用しました。自分の論文の段落を使ってテストすることもできます。 + +```Plain +人工知能はかつてない深さと広がりで教育エコシステムを再構築しています。適応型学習アルゴリズムにより、AIシステムは各学生の認知マップを構築し、知識習得軌跡をリアルタイムで追跡し、教育内容の難易度と提示方法を動的に調整できます。従来の教室環境では、教師は異なる学習スタイルや能力レベルの学生のニーズに同時に対応することが困難ですが、ディープラーニングに基づく教育プラットフォームは、インタラクティブなシミュレーション実験における学生の行動パターンを分析し、量子力学や微積分などの複雑な概念理解における微妙な障害を特定し、的確な認知スキャフォールドを提供できます。 + +高度な自然言語処理エンジンによるバーチャルチューターは、「フランス革命が現代民主制度に与えた影響をどう評価するか」のようなオープンな質問を分解できるだけでなく、ソクラテス式対話を通じてクリティカルシンキングを促進します。学生が気候変動が極地生態系に与える影響に関する論文を執筆する際、AI執筆アシスタントはその論証の厳密さを分析し、データ引用のタイムリーな問題を指摘し、より正確な科学用語を提案できます。特別教育の分野では、コンピュータビジョン技術により、AIは自閉スペクトラムの児童の社会的インタラクションにおける非言語的手がかりを認識し、介入戦略を調整でき、感情コンピューティングアルゴリズムはオンライン学習時の挫折感を検出し、タイムリーに励ましのフィードバックを提供します。 + +しかし、このような技術統合は一連の倫理的ジレンマを引き起こしています。アルゴリズムの偏見が意図せず特定の文化的背景を持つ学生を周縁化する可能性があり、データ収集の透明性の問題は学術的プライバシーへの懸念を引き起こし、自動採点システムへの過度の依存は学生の思考プロセスに対する教師の深い理解を弱める可能性があります。さらに複雑なのは、AIが高度にリアルなバーチャル実験体験を生成し始めた時、教育における「実践的経験」の価値を再定義する必要があることです。未来の教育パラダイムは、人間の教師が創造性、共感力、道徳的判断力の育成に集中し、AIシステムが知識伝達、スキル訓練、個別化評価の機能を担う、協調進化する教育共生体へと進化する可能性があり、機械の計算優位性を発揮しつつ、人間教育の独自の温かさも保持できるでしょう。 +``` + +同様に認識成功~ + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image51.png) + +3. 直接的な描画指示、ここでは「猫を描きたい」と入力し、同様に正確に認識されました。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image52.png) + +ここまでで、第2のステップ——意図認識を無事に実装できました。 + +#### ステップ3️⃣:画像生成プロンプト生成モジュール(LLM二次呼び出し) + +意図認識後、記事や長文に対しては、画像生成のプロンプトを生成する重要なステップがあります。これこそが本Agentのポイントです。 + +```SQL +セクション 3:画像生成プロンプト生成モジュール(LLM二次呼び出し) +1、タスク目標 +意図認識を基に、「画像生成プロンプトを確認」ボタンのロジックを実装し、LLMを呼び出してテキストを画像生成に適した英語の視覚プロンプトに最適化し、編集ボックスに充填し「画像を生成」ボタンと連動。 + +2、技術スタック要件 +セクション2と同様、完全コード = セクション1 + セクション2 + 本モジュールを出力; +セクション2で定義したLLM_BASE_URL、LLM_API_KEY、LLM_MODELを共有、新しいキーは追加しない。 + +3、核心ビジネスルール(実践版Prompt組み立てロジックを統合) +·プロンプト生成入力ルール(厳格に遵守必須) +画像生成プロンプト生成はもはや単純な文字列連結ではなく、標準Chatメッセージリストを構築する。コード構造は以下: +python +実行 +messages=[# System役割:Web上でユーザーが最終確認/編集したsystem_promptの内容{"role": "system", "content": final_system_prompt},# User役割:処理対象データを保持し、タスク目標を明確化{"role": "user", "content": f"以下の内容に視覚プロンプトを生成:\n\n{user_input}"}] +意図が2の場合:System内容はユーザーが編集したsystem_promptの最終版を取得; +意図が3の場合:System内容は無効状態で充填されたデフォルトルールを取得 +user_inputはユーザーがinput_textボックスに最初に入力した元のテキスト。 +·実践検証済みSystem Promptプリセット(コードに固定) +python +実行 +SYSTEM_PROMPT_DEFAULT = """あなたはNanoBanana描画プロンプトを作成するアシスタントです。 +私の内容に基づいて処理する必要があります。この画像の役割は、この文章が何を言っているかを説明し、皆にこの文章の文脈構造全体の意味を理解させることです。 +PPTのような説明が含まれる場合があります(例:左上に核心的観点、右下にデータ)。 +デザインスタイル要件:シンプル、Apple Design Philosophy(Apple設計哲学)。 +制約:NanoBananaで使用可能な英語プロンプトのみを直接返却し、説明、プレフィックス、余計な内容は一切返却しないでください。""" +·LLM呼び出し制約 +セクション2と同じLLM_BASE_URL、LLM_API_KEY、LLM_MODELを共有; +temperature=0.7(プロンプトの創造性と適合性を保証); +max_tokens=200(出力長を制限し、プロンプト制約にマッチ); +上記標準Chatメッセージリスト構造を厳格に使用、文字列連結は禁止。 +·サンプル入出力(核心参考) +入力例1(記事挿絵意図):元のテキスト:「AIがいかに教育を変えるか:AI技術の発展に伴い、教師の役割は知識伝授者からガイドへと変わり、AIアシスタントが学生の個別化学習を支援し、教室での人機協働が常態化する。」最終System Prompt:SYSTEM_PROMPT_DEFAULT(未修正)出力予想:"Minimalist illustration, Apple Design Philosophy, 1024x1024. Top left shows 'AI + Education' core concept, bottom right shows data of teacher-student-AI collaboration, soft color palette, clean lines, no redundant elements." +入力例2(直接的描画指示):元のテキスト:「Apple風の猫を描いて、MacBookの隣に座っている」最終System Prompt:SYSTEM_PROMPT_DEFAULT(無効状態)出力予想:"Minimalist cat, Apple style, 1024x1024, sitting next to a silver MacBook, clean white background, soft shadows, geometric shapes, no extra details." +·プロンプト出力強制制約 +純粋な英語、中国語なし; +Apple Design Philosophy/Apple style + 1024x1024を必ず含む; +長さ50–200文字、コード内で検証; +余分な説明、プレフィックス、無駄な内容は一切なし、プロンプト自体のみ返却。 + +4、コンポーネント連動ルール +生成成功:プロンプトをgeneration_promptボックスに充填、generate_btnを有効化、intent_statusに「プロンプト生成成功、修正後に画像生成可能」を追加; +生成失敗:具体的な理由をプロンプト表示(例:API呼び出し失敗、長さ不適格)、generate_btnは無効状態を維持、generation_promptボックスは空; +ユーザーがgeneration_promptボックスを手動修正 / クリア: +クリア時は自動的にgenerate_btnを無効化; +空でない場合はgenerate_btnを有効状態に維持。 + +5、例外処理 +API呼び出し失敗:フレンドリーなプロンプト「プロンプト生成失敗:{具体的なエラー情報}」、クラッシュしない; +プロンプト検証失敗:明確に原因をプロンプト表示(例:「Apple styleが含まれていない」「長さが40文字しかない」)、リトライを許可; +レスポンス解析失敗:プロンプト「LLM返却結果を解析できません、リトライしてください」。 + +6、出力要件 +LLM_API_KEYを置き換えるだけで使用可能な完全な実行可能コード; +コード構造は明確、コメントは完備、インターフェースは美しくシンプル; +標準Chatメッセージリスト構造を厳格に実装、パラメータと例のロジックは一致; +プロンプト長、内容検証ロジックを含み、エラープロンプトはフレンドリー。 +``` + +同様に第2ステップのテキストをコピーして検証します。 + +注目すべきは、ここでプリセットした画像生成プロンプト生成用のSystem Promptは以下の通りです: + +> あなたはNanoBanana描画プロンプトを作成するアシスタントです。 +> 私の内容に基づいて処理する必要があります。この画像の役割は、この文章が何を言っているかを説明し、皆にこの文章の文脈構造全体の意味を理解させることです。 +> PPTのような説明が含まれる場合があります(例:左上に核心的観点、右下にデータ)。 +> デザインスタイル要件:シンプル、Apple Design Philosophy(Apple設計哲学)。 +> 制約:NanoBananaで使用可能な英語プロンプトのみを直接返却し、説明、プレフィックス、余計な内容は一切返却しないでください。 + +他のプリセットテンプレートに変更したい場合は、前のpromptで修正するか、Traeで対話を通じて修正できます。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image53.png) + +基盤コードを修正するだけでなく、Web上でも素早く編集できます。例えば、ここで「先頭にPic Promptという一文を追加」という一文を追加すると、新しく生成されたプロンプトの先頭にもそれが含まれていることがわかります~この設計は、画像生成プロンプトのSystem Promptを素早く修正し、スタイルの迅速な切り替えを支援するためのものです。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image54.png) + +#### ステップ4️⃣:Nanobananaテキストから画像 / 画像から画像モジュール + +ついに最後のステップです。画像生成モデルを接続しなければ、完全なAgentとは言えません! + +```Bash +セクション 4:Nanobananaテキストから画像 / 画像から画像モジュール(最終版) +1、タスク目標 +「画像を生成」ボタンのロジックを実装し、実際のNanobanana APIを呼び出し、テキストから画像 / 画像から画像をサポートし、Base64を解析して画像を表示。 + +2、技術スタック要件 +Gradio 4.0.0+ Blocksに基づく; +依存関係:requests, pillow, base64, io, re; +完全コード = セクション1+2+3 + 本モジュール。 + +3、核心API設定(実践検証済み固定) +固定コード設定: +python +実行 +# コードに固定されたAPI設定 +NANOBANANA_API_URL = "https://api.zyai.online/v1/chat/completions" +NANOBANANA_MODEL = "gemini-2.5-flash-image" +NANOBANANA_API_KEY = "" # ユーザーが各自入力 +認証方式:Header Authorization: Bearer {NANOBANANA_API_KEY}。 + +4、画像前処理要件(実装必須)関数image_to_base64_data_uri (ref_image_path)を実装、核心ロジック: +PIL画像をPNG形式に変換; +1024x1024解像度に自動リサイズ; +透明チャンネルを白色背景に変換; +Base64にエンコード、返却形式:data:image/png;base64,...。 + +5、リクエスト構築ルール(実践版分岐ロジックに厳格に従う) +·核心関数の定義関数generate_image (prompt, ref_image_path)を実装: +引数:prompt(generation_promptボックスの内容)、ref_image_path(ref_imageにアップロードされたファイルパス); +返却:PIL Image(result_imageに表示)またはエラープロンプト。 +·分岐1:純テキストから画像(ref_image_pathが空) +python +実行 +messages = [{"role": "user", "content": prompt}] +·分岐2:画像から画像(ref_image_pathに値あり) +python +実行 +# まず画像前処理関数を呼び出し +image_base64 = image_to_base64_data_uri(ref_image_path) +messages = [{"role": "user","content": [{"type": "text", "text": prompt},{"type": "image_url", "image_url": {"url": image_base64}}]}] + +6、レスポンス解析要件(2つの形式に互換必須)choices[0].message.contentから画像Base64を抽出し、サポート: +構造化JSON返却のimage_urlフィールド; +Markdown形式 +; +統一的にBase64エンコードを抽出、デコード後PIL Imageに変換して返却。 + +7、コンポーネント連動と例外処理 +生成成功:PIL Imageをresult_imageに表示、intent_statusに「画像生成成功」をプロンプト; +生成 / 解析 / アップロード失敗:intent_statusに明確なテキストプロンプトを表示(例:「Base64解析失敗」「API呼び出しタイムアウト」)、クラッシュしない。 + +8、出力要件 +LLM_API_KEYとNANOBANANA_API_KEYを置き換えるだけで直接実行可能な完全コード、全プロセス利用可能、分岐ロジックは実践版に厳格にマッチ。 +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image55.png) + +とてもエキサイティングですね!ついにこのAgentの最初の画像を正常に生成しました。生成された画像をよく見ると、テキストとプロンプトにマッチしていることがわかります。ここまでで、基本的にあなた自身のAgentが実装できました! + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image56.png) + +画像から画像機能も追加しており、お気に入りの画像をアップロードすると、AIが自動的にスタイルを参考にします。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image57.png) + +特筆すべきは、前のステップで生成されたプロンプトもWeb上で編集可能であり、最終的にボタンをクリックした時のプロンプトが基準となることです~例えばここで「a cute cat」に変更した場合、最終的に生成される画像も可愛い子猫になります。 + +## 第4章:まとめ + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image58.png) + +**ついに完成しました!** +正直なところ、私自身も最後の一行を書き終えた時、思わず深く息を吐きました。ましてやここまでやり遂げたあなたはなおさらです。この一連のフローを完全に実行できたこと自体が、本当に素晴らしいことです。それはあなたが本当にキーボードに手を置き、一歩ずつやり遂げたことを意味しています。Bravo 🎉 🥳 👏 + +この内容を書く過程で、私はずっと考え続けていました——私たちは一体何を残すべきなのか?答えは実はモデルの名前、パラメータ、あるいは特定の固定手法ではなく、あなたに徐々に一つの感覚を身につけさせることです:どのようなことを安心してAIに理解と計画を任せ、どのような部分ではあなたが方向を決めるだけでよいのか。この分担関係が成立すれば、元々複雑に見えた生成プロセスの多くが、自然とスムーズに進むようになります。 + +振り返ってみると、この道は実はそれほど複雑ではありません。解決したい問題を明確に考え、長文は言語モデルに分解させ、整理された視覚的意図を画像生成モデルに表現させ、最後にこの一連のフローをあなただけの小さなアシスタントとしてパッケージ化します。ここまで来ると、あなたはもはや「モデルを使っている」だけでなく、長期的にあなたの仕事をサポートするシステムを構築しています。これこそが、このチュートリアルが最も伝えたかったことです。 + +しかし、あなたはすでに素晴らしい成果を上げています!ここまで学んできたあなたはVibe Codingの基礎をすでに身につけています。少し休憩してリフレッシュしましょう! + + diff --git a/docs/ja-jp/stage-2/frontend/modern-component-library/index.md b/docs/ja-jp/stage-2/frontend/modern-component-library/index.md new file mode 100644 index 0000000..7eec721 --- /dev/null +++ b/docs/ja-jp/stage-2/frontend/modern-component-library/index.md @@ -0,0 +1,428 @@ +# モダンコンポーネントライブラリでUIをアップデート + +前のコースでは、デザインツールでインターフェースを描き、AI IDEでデザイン稿をコードに変換し、完全なフロントエンドプロジェクトを完成させる方法を学びました。しかし、一つの問題に気づいたかもしれません:ゼロから書いたボタン、フォーム、ポップアップは、使えるものの、「プロのプロダクト」との差を感じさせます——スタイルの統一性が不足し、インタラクションのディテールが滑らかではなく、異なる画面への対応も頭を悩ませます。 + +これこそが**コンポーネントライブラリ**が解決する問題です。 + +コンポーネントライブラリは、あらかじめ設計・開発されたUIパーツの集合です。ボタン、入力ボックス、ドロップダウンメニュー、ダイアログ、テーブル...どんなプロダクトでも繰り返し使われるインターフェース要素が、コンポーネントライブラリにはすでに用意されており、多くのユーザーによって検証・磨き上げられています。積み木のように組み合わせるだけで、プロフェッショナルなインターフェースを素早く構築できます。 + +## 学べること + +1. フロントエンドコンポーネントライブラリとは何か、そしてなぜモダン開発でほぼ必須なのかを理解する +2. 最も代表的な4つのコンポーネントライブラリを知り、それぞれの得意なシーンを理解する +3. 3つの実践シーン(ランディングページ、プロダクトページ、バックエンド管理)を通じて、AI IDE + コンポーネントライブラリでVibe Codingを学ぶ +4. コンポーネントライブラリのドキュメントを読み、要件に応じて適切なコンポーネントを見つけて正しく使用する方法を学ぶ + +## 1. なぜコンポーネントライブラリが必要なのか? + +家の改装を想像してみてください。木材から椅子を自分で作ることもできますが、もっと一般的なのはIKEAで買うことです——デザインが良く、品質が安定し、説明書が明確で、持ち帰って組み立てるだけ。 + +コンポーネントライブラリはフロントエンド開発における「IKEA」です。家具ではなくインターフェースパーツを提供します: + +| 自分で手書き | コンポーネントライブラリを使用 | +| :--- | :--- | +| スタイル、インタラクション、アニメーションを自分で処理 | 開封即使用可能、スタイルとインタラクションはすでに磨き上げ済み | +| 異なるページのボタンが違って見える可能性 | グローバルにスタイルが統一され、一貫性が自動的に維持 | +| スマホ、タブレット対応に追加の作業が必要 | ほとんどのコンポーネントライブラリにレスポンシブサポートが内蔵 | +| アクセシビリティ(Accessibility)が漏れやすい | プロのコンポーネントライブラリはキーボードナビゲーション、スクリーンリーダー等に対応済み | +| 開発速度が遅い | 開発速度が速く、ビジネスロジックに集中 | + +簡単に言えば:**コンポーネントライブラリは「どう描くか」ではなく「何を作るか」に時間を使わせてくれます。** + +### 百聞は一見に如かず:同じ要件で、コンポーネントライブラリの有無の差 + +言葉だけでは説得力がありません。Traeでほぼ同じ要件を使い、それぞれ指定なしと指定ありで生成結果の差を見てみましょう。 + +**プロンプト1:コンポーネントライブラリ不使用** + +```text +AI執筆アシスタントのデータダッシュボードページを作ってください。含む: +- トップのタイトルバーとエクスポートボタン +- 4つの統計カードでユーザー数、アクティブユーザー、ドキュメント数、収益を表示、増減トレンドも表示 +- 折れ線グラフと円グラフを1つずつ +- ユーザーリストのテーブル、ページネーション機能付き +- 左側のナビゲーションサイドバー +``` + +**プロンプト2:shadcn/uiコンポーネントライブラリ使用** + +```text +AI執筆アシスタントのデータダッシュボードページを、shadcn/uiコンポーネントライブラリで作ってください。含む: +- トップのタイトルバーとエクスポートボタン +- 4つの統計カードでユーザー数、アクティブユーザー、ドキュメント数、収益を表示、増減トレンドも表示 +- 折れ線グラフと円グラフを1つずつ +- ユーザーリストのテーブル、ページネーション機能付き +- 左側のナビゲーションサイドバー +``` + +同じ要件で、唯一の違いはプロンプトの先頭に`shadcn/ui + Tailwind CSS`を追加しただけなのに、Traeの生成結果は視覚的一貫性、インタラクションのディテール、全体的な仕上げのレベルが完全に異なります。これがコンポーネントライブラリがもたらす「無料アップグレード」です——プロンプトにコンポーネントライブラリの名前を1つ追加するだけ。 + +## 2. 4つのコアコンポーネントライブラリを知る + +コンポーネントライブラリは多数ありますが(完全なリストは[付録](#appendix-more-component-libraries)を参照)、まず最も代表的な以下の4つを知っておけば十分です: + +| コンポーネントライブラリ | フレームワーク | 一言で言うと | 公式サイト | +| :--- | :--- | :--- | :--- | +| [Ant Design](https://ant.design) | React | アリババグループ製、エンタープライズ級バックエンドの事実上の標準、コンポーネントのカバー範囲が極めて広い | ant.design | +| [shadcn/ui](https://ui.shadcn.com) | React | npmパッケージとしてインストールせず、コードを直接プロジェクトにコピー、Tailwind CSSベース、カスタマイズの自由度が最高 | ui.shadcn.com | +| [HeroUI](https://heroui.com)(旧NextUI) | React | デフォルトのスタイルが美しく、アニメーションが滑らか、視覚品質にこだわるランディングページやプロダクト展示に適する | heroui.com | +| [Material UI](https://mui.com) | React | 最も歴史のあるReactコンポーネントライブラリ、Google Material Design仕様を実装、エコシステムが最も成熟 | mui.com | + +> Vueユーザーにも豊富な選択肢があります:[Element Plus](https://element-plus.org)(国内で最も人気)、[Ant Design Vue](https://antdv.com)、[Naive UI](https://www.naiveui.com)など、詳細は[付録](#appendix-more-component-libraries)を参照してください。 + +異なるコンポーネントライブラリは異なるシーンに適しています。次に、3つの実際の開発シーンを通じて、AI IDE + コンポーネントライブラリでVibe Codingを体験します。 + +異なるコンポーネントライブラリのスタイルと特徴を示すため、各シーンで異なるライブラリをあえて選びました。ただし注意:**これは多様な選択肢を知ってもらうためだけ**です。実際の開発では、最も使いやすいもの1つだけを使っても全く問題ありません。shadcn/uiのスタイルが好きなら、ランディングページ、プロダクトページ、バックエンド管理すべてをそれで作れます。見た目が良く、使いやすいものを1つ選ぶことが何より重要です。 + +## 3. 実践1:HeroUIでプロダクトランディングページを構築 + +**シーン**:AI執筆アシスタントのプロダクトを作り、製品の特徴を展示し、ユーザーの登録を促す美しいランディングページが必要です。ランディングページは視覚的なインパクトが強く、アニメーションが滑らかで、スマホでも見栄えが良い必要があります。 + +**HeroUIを選んだ理由**:HeroUIのデフォルトスタイルがすでに美しく、滑らかなトランジションアニメーションが組み込まれており、ユーザー向けの展示型ページに非常に適しています。 + +### 3.1 プロジェクトの作成 + +```bash +# HeroUI公式CLIでプロジェクトを作成 +npx create-heroui-app@latest ai-writer-landing +cd ai-writer-landing +npm install +``` + +### 3.2 AI IDEでランディングページを生成 + +AI IDE(Cursor、Traeなど)を開き、ダイアログに以下を入力: + +```text +AI執筆アシスタントのランディングページをHeroUIコンポーネントライブラリで作ってください: + +**ページ構造:** +1. トップナビバー:左にロゴとプロダクト名、右に「機能」「料金」「概要」の3つのリンクと「始める」ボタン +2. ファーストビューエリア:大見出しに「AIをあなたの執筆パートナーに」、サブタイトルでプロダクトの価値を紹介、2つのボタン「無料トライアル」と「デモを見る」、下にプロダクトのスクリーンショット +3. 機能紹介:3列のカードで、「スマート続き執筆」「スタイル調整」「多言語翻訳」の3つの機能をそれぞれ紹介。各カードにアイコン、タイトル、説明 +4. 料金エリア:3つの料金カード(無料版、プロ版、チーム版)、プロ版をおすすめとして強調表示 +5. ボトムCTA:魅力的なコピーと登録ボタン +6. フッター:著作権情報とソーシャルメディアリンク + +**デザイン要件:** +- モダンでプロフェッショナルな見た目 +- ダークモード対応 +- スマホでも見やすく +``` + +### 3.3 AIが使用する主要コンポーネント + +AIが生成したコードで、これらのHeroUIコンポーネントが見られます: + +```jsx +import { + Navbar, NavbarBrand, NavbarContent, NavbarItem, + Button, + Card, CardHeader, CardBody, CardFooter, + Divider, + Link, + Chip +} from '@heroui/react' +``` + +各コンポーネントの役割: + +| コンポーネント | 用途 | ランディングページでの位置 | +| :--- | :--- | :--- | +| `Navbar` | トップナビバー | ページ最上部、固定 | +| `Button` | ボタン、複数のバリアントとカラーをサポート | CTAボタン、ナビボタン | +| `Card` | カードコンテナ | 機能紹介、料金カード | +| `Chip` | 小さなタグ | 「おすすめ」、「最も人気」マーク | +| `Divider` | 区切り線 | エリア間の視覚的仕切り | + +### 3.4 イテレーションと最適化 + +生成された初版コードに完全に満足できない場合、AIとの対話を続けて調整します: + +```text +ランディングページを最適化してください: + +1. 大見出しにグラデーションカラーを追加、青から紫へのグラデーション +2. 機能カードにhover時の浮上アニメーション効果を追加 +3. プロ版の料金カードを強調表示し、ボーダーと「最も人気」のタグを追加 +4. スマホでのナビをハンバーガーメニューに変更 +``` + +> **Vibe Codingの核心**:各コンポーネントのAPIを覚える必要はなく、自然言語で望む効果を説明するだけで、AIが適切なコンポーネントと書き方を見つけてくれます。不満な点があれば、対話を続けてイテレーションするだけ。 + +## 4. 実践2:shadcn/uiでプロダクトページを構築 + +**シーン**:AI執筆アシスタントに、ユーザーログイン後のメインインターフェースが必要です——左側にドキュメントリスト、右側にエディタ、上部にツールバー。これは機能型のプロダクトページで、高度にカスタマイズされたUIが必要です。 + +**shadcn/uiを選んだ理由**:shadcn/uiはコンポーネントコードを直接プロジェクトに配置するため、どんなディテールも自由に変更できます。深いカスタマイズが必要なプロダクトインターフェースでは、この「コードを所有する」モードが最も柔軟です。 + +### 4.1 プロジェクトの作成 + +```bash +# Next.jsプロジェクトを作成 +npx create-next-app@latest ai-writer-app --typescript --tailwind --app +cd ai-writer-app + +# shadcn/uiを初期化 +npx shadcn@latest init + +# 必要に応じてコンポーネントを追加(すべてのコンポーネントを一度にインストールするのではない) +npx shadcn@latest add button card input sidebar sheet dialog +``` + +shadcn/uiのユニークな点:`add`でコンポーネントを追加するたびに、プロジェクトの`components/ui/`ディレクトリにソースコードがコピーされます。これらのファイルを直接開いてスタイルや動作を変更できます。 + +### 4.2 AI IDEでプロダクトインターフェースを生成 + +```text +AI執筆アシスタントのメインインターフェースをshadcn/uiコンポーネントライブラリで作ってください: + +**全体レイアウト:** +- 左側に折りたたみ可能なサイドバー、幅は約280px: + - トップに「新規ドキュメント」ボタン + - 下にドキュメントリスト、各ドキュメントにタイトルと最終編集時間を表示 + - ドキュメントを右クリックで名前の変更や削除 +- 右側にメイン編集エリア、上下2つの部分に分割: + - 上はツールバー:ドキュメントタイトルの編集、文字数統計の表示、「AI続き執筆」ボタン、「エクスポート」ドロップダウンメニュー + - 下は編集エリア:大きなテキスト入力ボックス、残りのスペースを占める + +**インタラクションのディテール:** +- 「AI続き執筆」をクリック後、ボタンにローディング状態を表示、エディタの下部にAI生成テキストが表示(タイプライターのように1文字ずつ表示) +- スマホではサイドバーをドロワー形式にし、左からスライドイン +- 現在選択中のドキュメントをハイライト表示 +``` + +### 4.3 AIが使用する主要コンポーネント + +```tsx +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Card, CardContent, CardHeader } from '@/components/ui/card' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@/components/ui/dropdown-menu' +import { + Sheet, + SheetContent, + SheetTrigger +} from '@/components/ui/sheet' +import { + Sidebar, + SidebarContent, + SidebarHeader +} from '@/components/ui/sidebar' +``` + +| コンポーネント | 用途 | プロダクトページでの位置 | +| :--- | :--- | :--- | +| `Sidebar` | 折りたたみ可能サイドバー | 左側のドキュメントリスト | +| `Sheet` | モバイル用ドロワー | モバイルでのサイドバー代替 | +| `DropdownMenu` | ドロップダウンメニュー | 「エクスポート」ボタン、右クリックメニュー | +| `Dialog` | ダイアログ | 名前の変更、削除の確認 | +| `Button` | ボタン、variantとloadingをサポート | 各種操作ボタン | +| `Input` | 入力ボックス | ドキュメントタイトルの編集 | + +### 4.4 コンポーネントスタイルのカスタマイズ + +shadcn/uiの利点は、コンポーネントのソースコードを直接修正できることです。例えば、ボタンの角丸を大きくしたい場合: + +```text +components/ui/button.tsxを修正して、 +すべてのボタンのデフォルトの角丸をrounded-mdからrounded-xlに変更し、 +primaryバリアントに微妙なシャドウ効果を追加してください +``` + +AIはプロジェクト内のコンポーネントファイルを直接修正し、npmパッケージのスタイルを上書きしません——これがshadcn/uiの「コードを所有する」利点です。 + +## 5. 実践3:Ant Designでバックエンド管理インターフェースを構築 + +**シーン**:AI執筆アシスタントがローンチした後、ユーザーデータの確認、ドキュメントコンテンツの管理、有料注文の処理を行う管理バックエンドが必要です。バックエンド管理システムの核心はデータ表示と操作効率です。 + +**Ant Designを選んだ理由**:Ant Designは中〜バックエンド領域で最も蓄積が深く、テーブル、フォーム、チャートなどのビジネスコンポーネントが開封即使用可能で、大量のエンタープライズ級インタラクションパターン(一括操作、高度なフィルタリング、データエクスポートなど)が内蔵されています。 + +### 5.1 プロジェクトの作成 + +```bash +# Ant Design Proスキャフォールドを使用(レイアウト、ルーティング、権限が内蔵) +npx create-umi@latest ai-writer-admin +# Ant Design Proテンプレートを選択 +cd ai-writer-admin +npm install +``` + +またはゼロから開始: + +```bash +npx create-react-app ai-writer-admin --template typescript +cd ai-writer-admin +npm install antd @ant-design/icons @ant-design/pro-components +``` + +### 5.2 AI IDEで管理バックエンドを生成 + +```text +AI執筆アシスタントの管理バックエンドをAnt Designコンポーネントライブラリで作ってください: + +**全体レイアウト:** +- 左側にメニューバー:ダッシュボード、ユーザー管理、ドキュメント管理、注文管理、システム設定 +- トップにパンくずナビゲーションを表示 + +**ユーザー管理ページ:** +- トップに4つの統計カード:総ユーザー数、本日新規、アクティブユーザー数、有料ユーザー数 +- 検索フィルターエリア:ユーザー名で検索、登録時間範囲を選択、ユーザーステータスでフィルター、「検索」と「リセット」ボタン +- ユーザーテーブル: + - アバター、ユーザー名、メール、登録時間、サブスクリプションプラン(異なるカラータグで区別)、ステータス、操作を表示 + - 1ページに20件表示、ページネーション対応 + - ユーザーを一括選択でき、一括無効化またはエクスポートが可能 + - 操作列:詳細を見る、編集、無効化(無効化前に再確認) +- 「詳細を見る」をクリックすると右からドロワーがスライドインし、ユーザーの詳細情報と最近のドキュメントリストを表示 +``` + +### 5.3 AIが使用する主要コンポーネント + +```tsx +import { PageContainer, ProLayout } from '@ant-design/pro-components' +import { ProTable } from '@ant-design/pro-components' +import { StatisticCard } from '@ant-design/pro-components' +import { + Button, Tag, Badge, Space, Drawer, + Popconfirm, message, Modal +} from 'antd' +import { + UserOutlined, SearchOutlined, ExportOutlined +} from '@ant-design/icons' +``` + +| コンポーネント | 用途 | バックエンドでの位置 | +| :--- | :--- | :--- | +| `ProLayout` | バックエンド全体のレイアウトフレーム | ページの骨格(メニュー + コンテンツエリア) | +| `ProTable` | 高度なテーブル、検索、ページネーション、列設定が内蔵 | ユーザーリスト、ドキュメントリスト、注文リスト | +| `StatisticCard` | データ統計カード | ダッシュボード、ページ上部の概要 | +| `Tag` / `Badge` | ステータスタグ | サブスクリプションプラン、ユーザーステータス | +| `Drawer` | サイドドロワー | ユーザー詳細、編集フォーム | +| `Popconfirm` | バブル確認ボックス | 削除、無効化などの危険な操作 | + +### 5.4 続けてイテレーション:ダッシュボードの追加 + +```text +ダッシュボードページを作ってください: + +1. トップに4つの統計カード:総ユーザー数、総ドキュメント数、本日のAPI呼び出し回数、月間収益。各カードに数値と前月比の変化(増加か減少か)を表示 +2. 中央に2つのチャート: + - 左:直近7日間のユーザー増加の折れ線グラフ + - 右:サブスクリプションプラン分布の円グラフ +3. ボトム:最近の操作ログテーブル、時間、ユーザー、操作タイプ、詳細を表示 + +Ant Designのコンポーネントでレイアウトし、チャートはAnt Design Chartsを使用 +``` + +> **バックエンド管理のVibe Codingのコツ**:バックエンドページの構造は比較的固定(テーブル + 検索 + ポップアップ)で、AIによるバッチ生成に非常に適しています。まずAIに「ユーザー管理」ページをテンプレートとして生成させ、その後「ユーザー管理ページの構造を参考に、ドキュメント管理ページを生成して」と言えば、AIは同じレイアウトパターンを再利用します。 + +## 6. ドキュメントの読み方を学ぶ:コンポーネントライブラリの「説明書」 + +Vibe CodingではAIが大部分のコードを書いてくれますが、AIの生成結果が正しくない場合や、特定のコンポーネントの動作を微調整したい場合は、**ドキュメントを確認する**のが最速の解決方法です。 + +Ant Designを例にすると、ドキュメントのアドレスは:`https://ant.design/components/overview-cn` + +ドキュメントを確認する標準的なフロー: + +1. **要件を明確にする**:例えば「テーブルで行選択をサポートしたい」 +2. **ドキュメントで検索**:「Table」を検索してテーブルコンポーネントのページに進む +3. **例を確認**:ドキュメント内の各コンポーネントには複数のオンライン例があり、「選択可能」の例を見つける +4. **コードをコピー**:例のコードをプロジェクトにコピーする +5. **APIテーブルを確認**:ページ下部で`rowSelection`属性の完全な設定項目を見つける + +> ドキュメントのリンクをAI IDEに直接送ることもできます:「https://ant.design/components/table-cn のrowSelection APIを参考に、ユーザーテーブルに一括選択機能を追加してください」。AIにドキュメントのリンクを提供すると、より正確なコードが生成されます。 + +各コンポーネントライブラリのドキュメントアドレス早見表: + +| コンポーネントライブラリ | ドキュメントアドレス | +| :--- | :--- | +| Ant Design | `https://ant.design/components/overview-cn` | +| shadcn/ui | `https://ui.shadcn.com/docs/components` | +| HeroUI | `https://heroui.com/docs/components` | +| Material UI | `https://mui.com/material-ui/all-components/` | +| Element Plus | `https://element-plus.org/zh-CN/component/overview.html` | + +## 7. まとめ + +3つの実践シーンは、最も一般的なフロントエンド開発のニーズをカバーしています: + +| シーン | 推奨コンポーネントライブラリ | 核心的な特徴 | +| :--- | :--- | :--- | +| ランディングページ / 展示ページ | HeroUI | デフォルトのスタイルが美しく、アニメーションが滑らか、視覚的インパクトが強い | +| プロダクト機能ページ | shadcn/ui | コードが完全にコントロール可能、深いカスタマイズが柔軟 | +| バックエンド管理システム | Ant Design | ビジネスコンポーネントが豊富、テーブル・フォームが開封即使用可能 | + +Vibe Codingのワークフローのまとめ: + +1. シーンに応じて適切なコンポーネントライブラリを選択 +2. AI IDEで望むページ構造とインタラクションを説明 +3. AIが初版コードを生成し、効果をプレビュー +4. 自然言語でイテレーションと調整を続ける +5. ディテールの問題に遭遇したらコンポーネントライブラリのドキュメントを確認 + +### 練習 + +以下のいずれかのシーンを選び、AI IDE + コンポーネントライブラリでゼロから完成させてください: + +1. HeroUIで以前のプロジェクト(例えばホグワーツ肖像画)の展示ランディングページを作る +2. shadcn/uiでノートアプリのメインインターフェースを構築(サイドバー + エディタ) +3. Ant Designでシンプルなコンテンツ管理バックエンドを構築(記事リスト + 新規記事フォーム) + +--- + +## 付録:更多のコンポーネントライブラリ一覧 {#appendix-more-component-libraries} + +本編で紹介した4つのコアライブラリ以外にも、フロントエンドエコシステムには優れたコンポーネントライブラリが多数あります。以下はフレームワーク別に分類したリストで、プロジェクトの要件に応じて選択してください。 + +### Vue エコシステム + +| コンポーネントライブラリ | Stars | 概要 | 適用シーン | +| :--- | :--- | :--- | :--- | +| [Element Plus](https://element-plus.org) | ~27k | Ele.meチームによるVue 3エンタープライズ級コンポーネントライブラリ、国内で最も広く使用され、中国語エコシステムが優れている | 中〜バックエンド管理システム | +| [Vuetify](https://vuetifyjs.com) | ~41k | 最も人気のあるVue Material Designコンポーネントライブラリ、80+コンポーネント、ドキュメントが充実 | Googleデザインスタイルのプロジェクト | +| [Ant Design Vue](https://antdv.com) | ~21k | Ant Designシステムに基づくVue 3コンポーネントライブラリ、デザイン仕様が統一 | エンタープライズ級中〜バックエンド | +| [Naive UI](https://www.naiveui.com) | ~18k | TypeScriptで記述、テーマのカスタマイズ性が極めて高く、CSSプリプロセッサに依存しない | デザインに独自の要件があるプロジェクト | +| [Quasar](https://quasar.dev) | ~27k | 1つのコードでSPA、SSR、PWA、モバイル、デスクトップアプリを構築 | クロスプラットフォームプロジェクト | +| [Vant](https://vant-ui.github.io/vant) | ~24k | Youzanチームが開発した軽量モバイルコンポーネントライブラリ、ECの一般的なニーズをカバー | モバイルH5ページ | +| [PrimeVue](https://primevue.org) | ~14k | 90+コンポーネント、複数のテーマ(Material、Bootstrap等)をサポート | 豊富なコンポーネントとマルチテーマが必要な場合 | +| [Arco Design Vue](https://arco.design/vue) | ~3k | ByteDance製、コンポーネントの品質が高く、ダークモード内蔵 | 中〜バックエンドプロダクト | +| [TDesign Vue Next](https://tdesign.tencent.com/vue-next) | ~2k | Tencent製、デザイン言語が統一、デスクトップの一般的なシーンをカバー | Tencentエコシステムまたはエンタープライズ級プロジェクト | + +### React エコシステム + +| コンポーネントライブラリ | Stars | 概要 | 適用シーン | +| :--- | :--- | :--- | :--- | +| [Material UI (MUI)](https://mui.com) | ~95k | Google Material Design仕様の老舗実装、コンポーネントが最も包括的、エコシステムが最も成熟 | エンタープライズ級アプリケーションの迅速な構築 | +| [Ant Design](https://ant.design) | ~94k | アリババグループ製、大量の高品質なビジネスコンポーネントが内蔵、中国語開発者コミュニティで主導的地位 | エンタープライズ級中〜バックエンド | +| [shadcn/ui](https://ui.shadcn.com) | ~83k | npmインストールではなくコードをプロジェクトにコピー、Radix UI + Tailwind CSSベース、完全にコントロール可能 | 高度なカスタマイズが必要なプロジェクト | +| [Chakra UI](https://chakra-ui.com) | ~39k | 開発体験を核心に、APIがシンプル、アクセシビリティサポートが内蔵 | 迅速なプロトタイピング開発 | +| [Mantine](https://mantine.dev) | ~28k | 100+コンポーネントと50+ hooks、日付ピッカー、リッチテキストエディタ等の高度なコンポーネントを含む | 開封即使用可能なフル機能ソリューションが必要な場合 | +| [Headless UI](https://headlessui.com) | ~27k | Tailwind Labs公式のスタイルなしコンポーネントライブラリ、ReactとVueの両方をサポート | Tailwind CSSとの組み合わせ | +| [HeroUI](https://heroui.com) | ~24k | Tailwind CSS + React Ariaベース、デフォルトのスタイルが美しく、アニメーションが滑らか | 視覚品質にこだわるプロジェクト | +| [Radix UI](https://www.radix-ui.com) | ~17k | スタイルなしの低レベルコンポーネントプリミティブライブラリ、アクセシビリティとコンポーネントの動作に特化、shadcn/uiの基盤 | カスタムデザインシステムの構築 | + +#### shadcn/ui 拡張エコシステム + +上記の汎用コンポーネントライブラリ以外にも、shadcn/uiのエコシステムにはその理念に基づいた拡張ライブラリが多数あり、特定のシーンに差別化された選択肢を提供しています。これらの拡張ライブラリも「コードをプロジェクトにコピー」するモードを採用し、開発者に完全なソースコード制御権を与えます。 + +| コンポーネントライブラリ | 概要 | 適用シーン | +| :--- | :--- | :--- | +| [Aceternity UI](https://ui.aceternity.com) | 200+のプロダクション級コンポーネント、発光カード、テキストグラデーション、3D地球などの特色ある視覚コンポーネント | 高品質ランディングページ、SaaSプロダクト | +| [Tailark UI](https://tailark.com) | マーケティングサイトのコンポーネントブロック集合、プロダクト展示、顧客の声、CTAボタンなどのマーケティング高頻度モジュール | マーケティングランディングページ、プロダクト公式サイト | +| [UI Tripled](https://ui.tripled.work) | Framer Motionベースの動的インタラクションコンポーネント、ポップアップ、ナビゲーション、カードアニメーション | クリエイティブツール、個人ポートフォリオ | +| [Neobrutalism UI](https://neobrutalism.dev) | 新ブルータリズムスタイル、太いライン、高コントラスト、鮮やかな色彩 | 個性的なブランド公式サイト、クリエイティブプロジェクト | +| [REUI](https://reui.io) | 967+の実際のビジネスシーンのコンポーネント組み合わせパターン | エンタープライズ級バックエンド、複雑なフォーム | +| [Cult UI](https://cult-ui.com) | より細かいインタラクション/視覚の磨き上げ、データテーブル、フィルターパネル等の複合コンポーネント | 高品質な商用プロジェクト | +| [Kibo UI](https://kibo-ui.com) | 高度なビジネスコンポーネント、カラーピッカー、リッチテキストエディタ、ファイルアップロード等 | 管理バックエンド、ツール系プロダクト | +| [Kokonut UI](https://kokonutui.com) | 100+コンポーネント + 7+完全テンプレート、清新でシンプルなスタイル | SaaS公式サイト、ブログ、EC | +| [Commerce UI](https://ui.stackzero.co) | ECシーン専用、商品カード、カート、決済フォーム | ECプラットフォーム | +| [shadcnblocks](https://shadcnblocks.com) | 1373個のUIブロック + 13セットの完全テンプレート、最も包括的なリソース | あらゆるシーン | +| [Shoogle](https://shoogle.dev) | shadcn/uiエコシステムの集約検索プラットフォーム | リソースの迅速検索 | +| [Discover All Shadcn](https://allshadcn.com) | 集約型リソースナビゲーション | リソースの迅速検索 | + +> **なぜshadcn/ui拡張を選ぶのか?** これらの拡張はshadcn/uiの「コード所有権」の理念を引き継ぎつつ、特定のシーンに深くカスタマイズされています。Vibe Coding時代において、デザイン要件に合ったコンポーネントを迅速に見つけ、主流UIライブラリの同質化から抜け出し、より差別化されたプロダクトを作ることができます。 diff --git a/docs/ja-jp/stage-2/frontend/multi-product-ui/index.md b/docs/ja-jp/stage-2/frontend/multi-product-ui/index.md new file mode 100644 index 0000000..34f2d30 --- /dev/null +++ b/docs/ja-jp/stage-2/frontend/multi-product-ui/index.md @@ -0,0 +1,425 @@ +# UIデザインガイドラインを参考にページとボタンを設計 + +多くの人が「ページをもっとAppleらしくしたい」「ボタンをもっと高級にしたい」と言いますが、実際に作り始めると、一つの問題で行き詰まることが多いです: + +**一体何を参考にすべきなのか?** + +スクリーンショットを見て模倣するだけでは、「似ているかどうか」しか学べません。しかし、Apple、Google、Microsoft、Atlassianのデザインガイドラインを開いてみると、彼らが本当にすごいのは視覚スタイルではなく、**デザインの問題を明確に説明していること**だと気づくでしょう:ページで何を先に目立たせるか、ボタンをどうランク付けするか、操作をどう強調するか——これらの判断基準こそが核心です。 + +> デザインガイドラインを参考にするのは、「誰かに似せる」ためではなく、他人がどう判断しているかを学ぶためです。 + +:::: info なぜ今でもこれらを学ぶ必要があるのか +デザインルールはすでにモデルに学習され、デザインツールにデフォルトで取り込まれ、数枚のスクリーンショットを貼るだけでAIも学習できます。しかし、これらのルールがどこから来て、なぜこのように定められているのかを知る必要は依然としてあります。 +:::: + +## まず公式原文を読んで、差を感じてみましょう + +「デザインガイドラインってスタイルについて語っているだけじゃないの?」と思っているなら、まず公式原文をいくつか見てみましょう。 + +普段チーム内でよくこんな言い方をしています: + +- ドロップダウンを作って +- ここにメニューを置いて +- メニューバーに機能をいくつか追加して +- ここにボタンを2つ、確認とキャンセル + +問題なさそうに聞こえますが、大手テック企業のガイドラインでは、これらの言葉は曖昧な概念ではなく、非常に細かく分解されています。 + +| 普段何気なく言っている言葉 | 公式原文 | 簡単に言うと | +| :--- | :--- | :--- | +| 「メニューを作って」 | Apple: ["A menu reveals its options..."](https://developer.apple.com/design/human-interface-guidelines/menus) | `Menu`は操作に使うもの | +| 「メニューバーに機能を入れて」 | Apple: ["menu bar menus contain all the commands..."](https://developer.apple.com/design/human-interface-guidelines/menus) | これはアプリ顶部のコマンドメニュー | +| 「ドロップダウンを作って」 | Apple: ["A pop-up list lets the user choose one option among several."](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pop-up`はリストから1つ選ぶ | +| 「ドロップダウンも作って」 | Apple: ["A pull-down list is generally used for selecting commands in a specific context."](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pull-down`は開いて現在の操作を行う | +| 「メニューで絞り込みもできるよね」 | Fluent: ["If you need to collect information from people, try a select, dropdown, or combobox instead."](https://fluent2.microsoft.design/components/web/react/core/menu/usage) | `Menu`は値を選ぶためのものではない | +| 「メニューをナビゲーションにも使えるよね」 | Material: ["Menus should not be used as a primary method for navigation within an app."](https://m1.material.io/components/menus.html) | `Menu`はメインナビゲーションではない | +| 「ボタンは適当にOK / Cancelでいいよね」 | Apple: ["Always use 'Cancel' to title a button that cancels the alert's action."](https://developer.apple.com/design/human-interface-guidelines/alerts) | ボタンテキストは適当に書いてはいけない | + +> 表の引用はクリックして直接対応する公式ページにジャンプできます。 + +これが、デザインガイドラインを初めて本格的に読んだ時に最も衝撃を受けるポイントです: + +> 私たちは普段UIについて議論しているつもりでも、実際には多くの場合、曖昧な言葉の羅列でコミュニケーションしているに過ぎません。 + +Appleは単に「メニューを作って」とは言いません。さらに細分化します: + +- `menu` +- `menu bar menu` +- `pop-up button` +- `pull-down button` +- `context menu` + +Fluentは単に「ドロップダウン」とは言いません。さらに細分化します: + +- `menu` +- `dropdown` +- `select` +- `combobox` + +これこそがデザインガイドラインの必要性です。 + +それはページをプロフェッショナルに見せるためではなく、チームがUIについて議論する際、全員が脳内に異なるものを思い浮かべている状態を避けるためです。 + +## 学べること + +1. なぜページとボタンを設計する際にデザインガイドラインを先に見るべきなのか +2. Apple、Material、Fluent、Atlassianのガイドラインの中で、どの内容が最も参考になるか +3. 「ページ階層」と「ボタン階層」をどう明確に設計するか +4. AIに他人のガイドラインを参考にしてページやボタンを生成させる方法 + +## 1. デザインガイドラインがなぜページを明確にするのに役立つのか + +上記の公式原文を読んでみて、一つの重要なポイントに気づくでしょう: + +**デザインガイドラインは锦上添花ではなく、まず言葉を正確にすることです。** + +多くのページが美しくないのは、カラーリングが高度でないからではなく、情報階層が混乱しているからです。 + +多くのボタンが使いにくいのも、角丸が間違っているからではなく: + +- メインボタンが多すぎて、ユーザーがどれをクリックすべきかわからない +- 危険なボタンと普通のボタンが同じように見える +- ページ内のすべてのボタンが注目を争っている +- 異なるページ間でボタンのスタイルとセマンティクスが一貫していない + +成熟したデザインガイドラインは、まさにこれらの問題を解決しています。通常、以下のことを定義します: + +| ガイドラインの内容 | 何を解決するか | +| :--- | :--- | +| **ページ階層** | どこを先に見るか、どこを後で見るか、情報をどう整理するか | +| **視覚的基礎** | 色、間隔、フォント、角丸、シャドウをどう統一するか | +| **ボタン階層** | メインボタン、セカンダリボタン、テキストボタン、危険ボタンをどう区別するか | +| **状態ルール** | hover、focus、disabled、loadingをどう表現するか | +| **インタラクションセマンティクス** | どのボタンが「確認」で、どれが「キャンセル」で、どれが「その他の操作」か | + +つまり、デザインガイドラインが真に提供するのは「スキン」ではなく、**判断基準**です。 + +## 2. 大手テック企業のガイドラインを参考にする際、何に注目すべきか + +### 2.1 Appleを参考に:「十分に細かく定義する」ということを学ぶ + +Appleで最も学ぶべきことは、視覚的な抑制感だけでなく、概念を非常に細かく定義する点です。 + +多くのチームが口にする「メニュー」や「ドロップダウン」について、Appleはさらに細分化します: + +- `menu`:一連のコマンド、オプション、または状態 +- `menu bar menu`:アプリレベルのコマンド集合 +- `pop-up button`:1つの値を選択 +- `pull-down button`:現在のコンテキストでコマンドをトリガー +- `context menu`:現在のオブジェクトやタスクに関連するよく使うアクション + +この区分は非常に重要です。なぜなら、以下に直接影響するからです: + +- このコンポーネントは値を選ぶためのものか、アクションを実行するためのものか +- ページの一部に属するのか、アプリレベルに属するのか +- 現在選択されている値を常に表示すべきか、コマンドを一時的に展開するだけか + +この粒度で考え始めると、設計するページが一気に明確になります。 + +### 2.2 Appleを参考に:ページ階層と抑制感を学ぶ + +Apple Human Interface Guidelinesは特に2つのことを学ぶのに適しています: + +- ページで明確な階層をどう構築するか +- コントロールが主張しすぎず明確さを保つにはどうするか + +Appleは`Hierarchy`、`Harmony`、`Consistency`を強調しています。これはページ設計時に以下の問いに答えることを意味します: + +- 現在のページで最も重要な情報は何か +- ユーザーのメインタスクは何か +- どの操作を最も目立たせるべきで、どの操作を後退させるべきか + +Appleを参考にページを設計する場合、以下を重点的に参考にできます: + +- ファーストビューの情報は細かすぎないように、コアコンテンツにまず焦点を当てる +- 余白、フォントサイズ、グループ化で秩序を築き、多くのボーダーを重ねて築かない +- ボタンはすべて高強調にせず、重要なアクションだけを最も目立たせる + +### 2.3 Materialを参考に:明確なページ構造を学ぶ + +Material Designは「ページがどうタスクフローを組織しているか」を学ぶのに非常に適しています。 + +多くのコンポーネントとレイアウトの仕様は、核心的に以下を明確にするのに役立ちます: + +- ページは閲覧型か、タスク実行型か +- 現在のページはユーザーに読ませる、選ばせる、それとも提出させるものか +- 1つのページでどの要素が安定して繰り返されるべきで、どの要素がコンテキストに応じて変化するべきか + +Materialを参考にページを設計する場合、以下を重点的に参考にできます: + +- ページのブロックが明確で、モジュールの役割が明確 +- ナビゲーション、コンテンツエリア、操作エリアの分担が明確 +- 異なるボタンスタイルが異なる操作優先度に対応 + +### 2.4 Fluentを参考に:コンポーネントの境界とボタン階層を学ぶ + +Fluent 2はバックエンド、ツール型プロダクト、複雑なフォームシステムに非常に適しています。最も学ぶ価値があるのは、「概念を混用しない」と直接教えてくれる点です。 + +例えば、「collect information」が必要な場合、`menu`を使い続けるのではなく、`select`、`dropdown`、`combobox`を検討すべきであると明確に書かれています。 + +この一文は非常に重要です。なぜなら、多くの人が頭の中で「だいたい同じ」だと思っている概念を打ち砕くからです。 + +Fluent 2は以下も重視しています: + +- 操作階層 +- コンポーネントのセマンティック境界 +- 密集した情報シーンでの明確さ + +Fluentを参考にボタンを設計する場合、以下を重点的に参考にできます: + +- `Primary button`は現在の最も重要なアクションを受け持つ +- `Secondary button`はサポート的なアクションを受け持つ +- `Subtle`、`Transparent`のような弱い強調のボタンは、メインフローを邪魔すべきでない操作に使用 +- ページ内のボタン数が多くなるほど、視覚的優先度をコントロールする必要がある + +### 2.5 Atlassianを参考に:体系的にページとボタンを管理する + +Atlassian Design Systemは「1つのチームが多くのページを作る」場合に特に適しています。以下を強調しています: + +- foundationsは共有の基盤 +- tokensは視覚的決定を統一する方法 +- componentsは繰り返し再利用されるインタラクション構成要素 + +Atlassianを参考にページやボタンを作る場合、最も価値があるのは: + +- ボタンのサイズ、色、角丸、間隔を統一ルールにする +- ページレイアウトのリズムを固定する +- 異なるページは内容が異なっても、構造言語を一貫させる + +## 3. ページを設計する際、ガイドラインのどのポイントを参考にすべきか + +デザインシステムを見る際、「このページは美しいかどうか」を先に問うのではなく、まず以下の問いを立てましょう。 + +### 3.1 ページの第一印象、主従は明確か + +1つのページは通常、少なくとも3つの層を持つべきです: + +- **メイン情報**:現在のページで最も重要なコンテンツ +- **補助情報**:理解を助ける、または補足するコンテンツ +- **サブ操作**:メインタスクを邪魔すべきでないアクション + +3つの層が分かれていないと、ページは「すべてが重要」になり、「何も重要でない」のと同じになります。 + +### 3.2 ページレイアウトはモジュールを積み上げるのではなく、タスクに奉仕しているか + +ガイドラインを参考にする際、特に注目できます: + +- タイトルエリアがページの目標を明確にしているか +- メインコンテンツエリアがタスクを中心に組織されているか +- 操作ボタンが関連コンテンツの近くにあるか +- 補助情報が適切に弱められているか + +### 3.3 ページ内の操作に優先度はあるか + +多くのページを見るとボタンが6個あり、どれもCTAのように見えます。これは典型的な階層のコントロール不足です。 + +より合理的な方法は: + +- 1つのエリアには通常1つのメインアクションのみ +- セカンダリアクションはアウトライン、テキストボタン、またはより弱いスタイルを使用 +- リスクのあるアクションはメインアクションと同じ見た目にしない + +## 4. ボタンを設計する際、ガイドラインのどのポイントを参考にすべきか + +ボタンは「適当に設計」されがちな部分ですが、システムの成熟度を最もよく表す部分でもあります。 + +### 4.1 ボタンはまず「セマンティクス」で分け、次に「スタイル」で分ける + +「青いボタンか黒いボタンか」を先に考えるのではなく、このボタンがどのような役割かを先に考えましょう。 + +よくあるボタンの役割は次のように分けられます: + +| ボタンタイプ | 役割 | よくあるスタイル戦略 | +| :--- | :--- | :--- | +| **Primary** | 現在のエリアで最も重要なアクション | 塗りつぶし、高コントラスト、最も目立つ | +| **Secondary** | サポート的なアクション | アウトラインまたは一段低い強調 | +| **Tertiary / Text** | 弱い操作 | テキストまたは低い視覚的比率 | +| **Destructive** | 削除、無効化、クリアなどのリスク操作 | 警告色または明確なリスクスタイル | +| **Icon button** | 局所的なツール操作 | シンプル、コンテキストに近い | + +### 4.2 1つのページにPrimary Buttonを多く置かない + +これは多くの初心者が最も陥りやすい落とし穴です。 + +ページに4つのメインボタンがある場合、それはメインボタンがないのと同じです。メインボタンの意義は本来「ユーザーに今何をすべきかを伝える」ことです。 + +多くのデザインシステムの共通するアプローチを参考にできます: + +- 1つの主要エリアには通常1つのメインボタンのみ残す +- キャンセル、戻る、閉じるは通常、確認ボタンと同じレベルを争わない +- その他の操作はセカンダリボタンやメニューに配置する + +### 4.3 ボタンは状態変化を表現できなければならない + +デザインガイドラインは通常、ボタンの状態について詳細に記述しています: + +- デフォルト状態 +- ホバー状態 +- フォーカス状態 +- 無効状態 +- ローディング状態 +- 危険状態 + +これは重要です。なぜならボタンは静的な画像ではなく、ユーザーの操作過程で最も頻繁にトリガーされるコントロールの一つだからです。 + +### 4.4 ボタンテキストもデザインの一部 + +ボタンテキストは単なる「テキストの問題」ではなく、ユーザーの理解に直接影響します。 + +例えば: + +- `保存` +- `変更を保存` +- `今すぐ公開` +- `プロジェクトを削除` +- `ゴミ箱に移動` + +これらのテキストが伝える心理的期待は全く異なります。成熟したガイドラインは通常、ボタンラベルが明確にアクションを表現することを求め、曖昧な言葉の使用を避けます。 + +## 5. 非常に実用的なページとボタンの設計チェックリスト + +自分でページを設計する際、まずこのチェックリストをざっと見てみましょう: + +### ページチェックリスト + +- ページタイトルが現在のタスクを明確に説明しているか +- ファーストビューの最も重要な情報が一目で見えるか +- ページがタスクフローに沿って組織されており、思いついたものを配置しただけではないか +- 同じエリアにメインアクションが1つだけか +- 補助情報が適切に弱められているか + +### ボタンチェックリスト + +- このボタンはメインアクションかセカンダリアクションか +- なぜ他のボタンより目立つ価値があるのか +- ページ内にメインボタンが多すぎないか +- 危険な操作が明確にマークされているか +- ボタンテキストは十分に具体的か + +## 6. AIに他人のガイドラインを参考にページを設計させる方法 + +このセクションが最も実用的です。 + +多くの人がAIにページを設計させる際、こう言うだけです: + +```md +設定ページを作って、もう少し高級に、Apple風でお願いします +``` + +この種のプロンプトは曖昧すぎて、AIは結局「白い背景、角丸、シャドウ」を模倣するしかありません。 + +初心者にとってより実用的な方法は、自分で長い文章をまとめるのではなく、**ガイドライン原文の重要な一文**を直接AIに貼り付けることです。 + +これには2つの利点があります: + +- 自分で先にデザイン思想を「翻訳」する必要がない +- AIが公式定義に沿ってページやボタンを理解しやすくなる + +### 6.1 例1:AIにAppleを参考に設定ページを設計させる + +まずAppleの原文を見つけます: + +> ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) + +AIに次のように直接貼り付けます: + +```md +Apple Human Interface Guidelinesのこの一文を参考に: +"Establish a clear visual hierarchy..." + +アカウントセキュリティ設定ページを設計してください。 +ページ階層を明確にし、重要な情報を前に配置し、グループを整然とさせてください。 +``` + +この書き方のポイントは、自分で説明しすぎず、Appleの原文を直接貼り付けることです。 + +### 6.2 例2:AIにFluentを参考にバックエンドページのボタンを設計させる + +まずFluentの原文を見つけます: + +> ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +AIに次のように直接貼り付けます: + +```md +Fluent 2のこの一文を参考に: +"Only use one primary button in a layout..." + +チーム管理バックエンドのボタンを設計してください。 +メンバー追加ボタンを最も目立たせ、エクスポート、フィルター、その他の操作は弱め、削除ボタンは単独で目立たせてください。 +``` + +この一文は初心者に非常に適しています。なぜなら、AIに1つのエリアにメインボタンを多く置かないよう直接伝えるからです。 + +### 6.3 例3:AIにページガイドラインとボタンガイドラインを同時に参考にさせる + +原文を2つ同時に貼り付け、AIにページとボタンの両方を参考にさせることもできます: + +> Apple: ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) +> +> Fluent: ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +次のように直接書きます: + +```md +以下の2つのデザインガイドライン原文を参考に: +Apple: "Establish a clear visual hierarchy..." +Fluent: "Only use one primary button in a layout..." + +プロジェクト詳細ページを設計してください。 +ページにはプロジェクト紹介、メンバー、最近のアクティビティ、設定への入り口を含めます。 +ページ階層を明確にし、メインボタンは1つだけ残し、他のボタンは弱めてください。 +``` + +この方法は初心者に特に適しています。原文をコピーして、自分の要件を2文追加するだけで十分だからです。 + +## 7. AIにボタンガイドラインを参考に直接ボタンデザインを生成させる方法 + +まずボタンだけを作りたい場合は、ボタンガイドラインの原文を直接貼り付けることもできます。 + +例えば、Atlassianのボタンの定義は非常に短いです: + +> ["A button triggers an event or action."](https://atlassian.design/components/button/) + +AIに次のように問いかけます: + +```md +Atlassianのこの一文を参考に: +"A button triggers an event or action." + +バックエンドページのボタンスタイルセットを設計してください。 +メインボタン、セカンダリボタン、削除ボタンが必要で、それぞれどこで使うかも教えてください。 +``` + +この種のプロンプトは特に初心者に適しており、基本的に「原文を貼る + 要件を言う」だけです。 + +## 8. まとめ + +UIデザインガイドラインを参考にページやボタンを設計する際、最も重要なのは「誰かに似せる」ことではなく、以下のことを学ぶことです: + +1. 階層でページを組織し、コンテンツを積み上げない +2. ボタンのランク付けで操作の優先度を表現し、すべてのボタンを同じように目立たせない +3. デザインガイドラインの定義、境界、判断基準で設計をガイドする +4. AIに他人のガイドラインを参考にさせる際、「原則と構造」を参考にし、スキンだけを参考にしない + +このようにガイドラインを使うことで、参考にするのは単なるスタイルではなく、成熟したデザイン思考の方法論になります。 + +--- + +## 参考文献 + +以下のリンクはすべて公式デザインシステムまたは公式ドキュメントからのものです: + +- Apple Human Interface Guidelines: [Overview](https://developer.apple.com/design/human-interface-guidelines/) +- Apple Human Interface Guidelines: [Menus](https://developer.apple.com/design/human-interface-guidelines/menus) +- Apple Human Interface Guidelines: [Alerts](https://developer.apple.com/design/human-interface-guidelines/alerts) +- Apple Human Interface Guidelines: [Buttons](https://developer.apple.com/design/human-interface-guidelines/buttons) +- Apple Archive: [How Menus Work](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/HowMenusWork.html) +- Apple Archive: [Managing Pop-Up Buttons and Pull-Down Lists](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) +- Material Design: [Buttons overview](https://m3.material.io/components/buttons/overview) +- Material Design: [Menus](https://m1.material.io/components/menus.html) +- Microsoft Fluent 2: [Start designing](https://fluent2.microsoft.design/get-started/design) +- Microsoft Fluent 2: [Menu usage](https://fluent2.microsoft.design/components/web/react/core/menu/usage) +- Microsoft Fluent 2: [Button usage](https://fluent2.microsoft.design/components/web/react/core/button/usage) +- Atlassian Design System: [Foundations](https://atlassian.design/foundations/) +- Atlassian Design System: [Button](https://atlassian.design/components/button/) diff --git a/docs/ja-jp/stage-2/frontend/ui-design/index.md b/docs/ja-jp/stage-2/frontend/ui-design/index.md new file mode 100644 index 0000000..834e960 --- /dev/null +++ b/docs/ja-jp/stage-2/frontend/ui-design/index.md @@ -0,0 +1,3 @@ +# 初めてのモダンアプリ - UIデザイン + +> この章は現在執筆中です。お楽しみに... diff --git a/docs/ja-jp/stage-2/index.md b/docs/ja-jp/stage-2/index.md index 08e3a17..9fd2335 100644 --- a/docs/ja-jp/stage-2/index.md +++ b/docs/ja-jp/stage-2/index.md @@ -1,6 +1,6 @@ -# フルスタック開発 +# 初中级開発 -**フルスタック開発**ステージへようこそ!ここでは、フロントエンドのコンポーネント化、データベース設計、バックエンドAPI開発、デプロイメントをマスターし、フルスタック開発に深く掘り下げます。 +**初中級開発**ステージへようこそ!ここでは、フロントエンドのコンポーネント化、データベース設計、バックエンドAPI開発、デプロイメントをマスターし、フルスタック開発に深く掘り下げます。 ## 学べること @@ -9,141 +9,172 @@ モダンなフロントエンド開発をマスターし、コンポーネントライブラリとデザインツールの使用方法を学ぶ: - -
-
- 🖼️ - フロントエンド1 -
-
FigmaとMasterGo入門
-
-
- - -
-
- - フロントエンド2 -
-
初めてのモダンアプリ - UIデザイン
-
-
- - -
-
- 📐 - フロントエンド3 -
-
UIデザインガイドラインとマルチプロダクト
-
-
- - -
-
- 🧙 - フロントエンド4 -
-
ホグワーツ肖像画を作ろう
-
-
+ + + + + + + +
-### バックエンドとフルスタック +### バックエンド開発 API設計、データベース管理、アプリケーションデプロイメント戦略を学ぶ: - -
-
- 🗄️ - バックエンド2 -
-
データベースからSupabaseへ
-
-
- - -
-
- 🤖 - バックエンド3 -
-
AI支援インターフェースコードとドキュメント
-
-
- - -
-
- 🌿 - バックエンド4 -
-
Gitワークフロー
-
-
- - -
-
- 🚀 - バックエンド5 -
-
Zeaburデプロイメント
-
-
- - -
-
- 💻 - バックエンド6 -
-
モダンCLI開発ツール
-
-
- - -
-
- 💳 - バックエンド7 -
-
Stripe決済システムの統合
-
-
+ + + + + +
-### 課題 +### 大規模課題 -実践プロジェクトを通じてフルスタック開発スキルを固める: +前の章では「パーツ」を学んでいましたが、大規模課題では「パーツを組み立てて動く、デモできる、公開できるプロダクトにする方法」を学びます。 + +**大規模課題 1 → 大規模課題 2** の順序で進めることをお勧めします: + +- **大規模課題 1** では、モダンSaaSで最も一般的なメインフローを一通り体験します:ログイン、生成、データベース、決済、管理画面。 +- **大規模課題 2** では、より業務システムに近いシナリオに進みます:ロール権限、問題バンク、試験、提出記録、管理コンソール。 + +```mermaid +flowchart LR + A["フロントエンドページとコンポーネント"] --> B["データベースとAPI"] + B --> C["大規模課題 1
コピー生成 SaaS"] + C --> D["決済 / デプロイ / 管理画面"] + D --> E["大規模課題 2
オンライン試験システム"] + E --> F["完全なフルスタックポートフォリオ"] +``` + +どちらから始めるべきか迷った場合は、以下の比較表を参考にしてください: + +| プロジェクト | 重点的に練習できる内容 | 最も適している人 | 最終成果物 | +|------|------|------|------| +| 大規模課題 1:コピー生成サイト | SaaSページ構造、ユーザーログイン、AI生成、Stripe決済、管理画面 | 初めて完全なビジネス向けサイトを作る人 | 登録・生成・決済・管理ができるSaaSのプロトタイプ | +| 大規模課題 2:オンライン試験・管理システム | ロール権限、問題バンクのモデリング、試験フロー、提出記録、採点と統計 | 「業務システム」を本当に完成させたい人 | 学生用と管理用の両方がある試験プラットフォーム | + +どちらの課題を選ぶ場合でも、大規模課題では少なくとも以下の3つの成果物を用意することをお勧めします: + +- 実行可能なプロジェクトリポジトリ +- アクセス可能なデモリンク +- READMEとデモ動画 - -
-
- 🎯 - 課題2 -
-
モダンフロントエンド + Trae
-
-
+ + +
+ +上記2つのメインプロジェクトを完了した後、または自分の技術分野に合わせてポートフォリオを作りたい場合は、以下の拡張課題から1つを選んで深く取り組むことができます: + + + + + + + + ### AI機能拡張 - -
-
- 🎭 - AI 2 -
-
AI辞書クエリとマルチモーダルAPI
-
-
+
## 対象者 @@ -160,56 +191,3 @@ API設計、データベース管理、アプリケーションデプロイメ - AIプログラミングツールについて予備的な知識を持っている フルスタック開発に深く掘り下げる準備はできましたか?左のナビゲーションをクリックして学習を始めましょう! - - diff --git a/docs/ko-kr/stage-2/ai-capabilities/dify-knowledge-base/index.md b/docs/ko-kr/stage-2/ai-capabilities/dify-knowledge-base/index.md new file mode 100644 index 0000000..5db19b9 --- /dev/null +++ b/docs/ko-kr/stage-2/ai-capabilities/dify-knowledge-base/index.md @@ -0,0 +1,1044 @@ +# Dify 入门与知识库集成 + +# 回顾上节课 + +在前几节课中,我们分组学习了 AI 编程、提示词工程以及 AI 图像生成的基础知识。这些内容帮助我们初步了解了不同大语言模型(LLM,Large Language Model)或生成式模型的边界和能力。 + +为了帮助你回顾上节课的内容,下面有几个小问题可以思考: + +1. 什么是 AI 编程?如何使用 AI 编程工具(例如 [z.ai](http://z.ai))来创建一个网页? +2. 什么是大语言模型?什么是提示词工程和上下文工程?你该如何编写一个复杂的提示词? +3. 对于文本、AI Coding、图像生成的三个不同方向,你认为模型能力的强弱分别体现在什么地方? +4. 什么是 API?如何使用 [z.ai](http://z.ai) 接入第三方 API ? + +如果你对其中任何一个问题还感到疑惑,可以回看上节课的文档,也可以直接在微信群里提问。 + +在这节课中,我们将从简单的 AI 文字图片工具,进入更接近公司业务落地的工作流搭建平台。从对话机器人走向 AI 智能体、AI 工作流,并基于 API 把它变成可交互的“智能”机器人页面。 + +在操作过程中,如果遇到难以理解的步骤,请不要担心,推荐你随时对当前所在的操作页面进行截图,发送给大模型进行询问;当前大模型已能够解答大部分常见问题。 + +如果提问后仍无法解决,不妨大胆尝试操作;不必害怕出错,每一次尝试都是学习和进步的机会。随着实践次数的增加,你会越来越熟练,操作也会越来越得心应手! + +# 本节课你将学到 + +1. 为什么需要从聊天机器人走向智能体和 Workflow 编排。 +2. 什么是智能体与工作流开发平台,如何把 AI 的能力 SOP 化与可编排化。 +3. 什么是 Dify,如何用这个面向 LLM 应用的开源平台快速搭建应用,尤其是知识库问答机器人。 +4. RAG 的实现方法与价值,为什么需要检索增强生成? +5. 如何从 0 到 1 学会使用 Dify 和 AI IDE Trae (`Extra Knowledge 4 - What is AI IDE and Trae`),包括搭建 智能体、工作流,并基于 Dify API 制作前端对话机器人网页程序。 + +- Dify 的基本使用原理与智能体、工作流制作方法,API 调用方法。 +- AI IDE 的使用方法,如何使用 AI IDE 编程。 +- 一个可进行对话的前端网页智能体程序。 + +# 1. 从对话到智能体 + +在上一阶段,我们学会了如何用提示词让大模型扮演角色、生成文本或编写简单代码。但如果你仔细思考,会发现一个问题,聊天机器人本身并不能做事。 + +它能回答怎么查订单?,却不能真的去数据库里查对应的数字;它能描述一封周报应该包含什么,却无法自动汇总你的项目数据并发送邮件。这种“只说不做”的局限,使得纯对话式 AI 难以真正融入业务流程。 + +要让 AI 从聊天伙伴升级为数字员工,我们需要赋予它三项核心能力: + +1. 专属知识——让它能够通读并了解你的产品文档、客户资料、内部制度; +2. 工具调用(或者叫插件)——让它能操作数据库、调用 API; +3. 结构化执行——让它按预设逻辑一步步完成任务,而非自由发挥。 + +这就是 AI 智能体(AI Agent)的雏形:一个具备目标、知识、工具和执行路径的自动化单元。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image1.png) + +> 注意:当前业界所说的简单版本的“智能体”,大多指基于 LLM + 工具 + 知识库组合而成的增强型应用,并非所谓能够自主规划的智能体。简单的智能体虽不具备真正的推理与长期规划能力,但已足以支撑大量企业级自动化场景。我们将会在之后的章节详细介绍真正的具备自主规划和行动能力的智能体。 + +## 1.1 最简单的智能体:基于知识库的问答机器人 + +在明确智能体应具备的多项核心能力后,一个值得思考的问题随之而来:能否仅通过实现其中某一项最简单的功能,就构建出一个真正可用的基础智能体? 答案是肯定的。 + +事实上,在大量实际业务场景中,用户的核心诉求并非让 AI 自动执行复杂操作(如调用 API 或跨系统协调任务),而是希望它能基于企业自身的专属资料,提供精准、可靠的问答支持。这恰好对应智能体三大核心能力中的第一项,专属知识服务能力。因此,我们得以引出智能体最简单、也最广泛应用的形态:基于知识库的问答机器人。 + +虽然它尚未具备工具调用或自主规划能力,但其关键突破在于:让大模型的回答不再凭空生成,而是有据可依。如何实现?关键就在于解决核心挑战:企业内置大量文档知识,当存在千上万页文档时,模型如何在每一轮对话中快速找到与当前问题最相关的内容? + +此时的一个解决方案是:检索增强生成(Retrieval-Augmented Generation, RAG)。 + +RAG 的基本思路是:在用户提问时,系统首先从企业知识库中检索出与问题语义最相关的若干文本片段(例如产品手册中的某一段、HR制度中的某一条款),然后将这些片段作为上下文“注入”到大模型的输入中,引导它基于真实资料生成回答。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image2.png) + +图片来源:[https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag](https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag) + +这样一来,模型的回答不再是依赖其训练数据中的泛化知识,而是锚定在企业提供的权威信息之上。RAG 的目标,正是通过这种外部知识的动态注入,显著提升回答的真实性、准确性和一致性——甚至可以让回答“符合人设”,比如以客服口径或技术文档风格作答。 + +在实际业务中,这项技术尤为重要,因为大模型常常会产生“幻觉”。例如,若你以 CFO 或咨询顾问的身份询问某个时间段的具体数据,模型很可能编造日期和事件。引入 RAG 后,回答的可控性与可靠性将得到显著提升。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image3.png) + +图片来源:[https://www.databricks.com/glossary/retrieval-augmented-generation-rag](https://www.databricks.com/glossary/retrieval-augmented-generation-rag) + +在本节课的实操环节中,我们将使用流行的 AI 工作流平台 Dify,动手搭建一个基于知识库的问答机器人。你可以轻松将各种类型的专属资料,如产品手册、公司制度、项目文档、研究论文、知识库文章,甚至是个人笔记集构建为知识库。 + +完成搭建后,你可以尝试提出各类问题来检验它的能力,例如: + +- “我们产品A的最新版本有哪些主要功能升级?” +- “请根据员工手册,说明今年的年假制度是如何规定的?” +- “在XX项目中,我们遇到的技术挑战‘XXX’是如何解决的?” +- “这篇论文中提到的核心研究方法是什么?” + +你将亲身感受 RAG 技术如何将静态分散的文档资料,转化为一个精准的智能知识库,为各种场景提供高精度问答支持。 + +## 1.2 从对话智能体到工作流 + +然而,即使是加入了知识库甚至是插件调用能力的“增强型智能体”,在面对更复杂的业务流程时仍显不足。 + +试想这样一个用户请求:“我们新上线的 SaaS 产品最近有哪些功能更新?能帮我整理成一份给客户的简报吗?” + +这个请求看似简单,背后却需要多个协同步骤:首先从内部产品文档或 Notion 知识库中检索最近一个月的功能发布记录;然后过滤出面向客户的关键特性;接着调用大模型将技术描述转化为客户友好的语言;最后通过将生成内容推送至市场团队的邮箱,或保存到 Google Docs 模板中。 + +如果仅靠一个大语言模型自由推理,先不说是否能够一次对话实现所有过程,就算能,其中也很容易遗漏关键信息、混淆内部术语与客户语言,或无法结构化输出。更重要的是,企业需要的是可审计、可复用、可监控的标准化执行路径,而不是每次依赖模型的临时发挥,可监控可复现对企业而言非常重要,非预期的结果很可能会带来预期外的严重损失。 + +这就引出了更高阶的 AI 应用范式:AI 工作流(AI Workflow)。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image4.png) + +工作流是指将一个复杂任务拆解为多个有序、可配置、可自动执行的子步骤,并通过可视化或代码方式编排它们之间的逻辑关系,如条件判断、循环或并行执行。将 AI 能力 SOP 化(即标准化操作流程),意味着把如何用 AI 完成某项任务的经验固化为可重复使用的模板。 + +这种做法带来了多重价值:非技术人员(如产品经理或运营)可以通过拖拽组件快速搭建 AI 应用;开发者可以将 RAG 检索、LLM 调用、API 工具等封装为标准节点,在不同业务场景中复用;整个流程还可被完整追踪、调试和持续优化,满足企业对稳定性与合规性的要求。 + +AI 工作流的使用人群非常广泛。产品经理无需写代码,即可设计完整的用户交互路径;运营人员能快速搭建客服机器人、内容生成器或通知系统;开发者和算法工程师则可将核心能力模块化,供前端调用;创业者或独立开发者也能以极低成本验证 AI 产品的 MVP,几天内上线一个包含数据查询、内容生成与动作执行的完整原型。 + +此外,值得注意的是,AI 工作流通常可用一种中间表示(Intermediate Representation)来描述。不同工作流平台的具体表达方式虽有差异,但大多采用结构化文件(如 JSON、YAML 等)来定义节点类型、输入输出及执行逻辑,其结构类似下图所示: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image5.png) + +简言之,如果说智能体让 AI 从会聊天走向能做事,那么工作流则让 AI 从偶尔做成一件事迈向“稳定、可靠、规模化地完成一类事。在接下来的实践中,我们还将借助 Dify 平台,上手并亲手构建完整的 AI 工作流,体验从想法到可运行应用的完整过程。 + +## 1.3 常用智能体 / 工作流平台 + +随着生成式 AI 技术的飞速发展,为帮助开发者与业务人员快速构建智能体与自动化流程,避免陷入编程的复杂细节,一批低代码甚至无代码的智能体及工作流平台应运而生。 + +首先需要明确的是,低代码平台是指通过可视化拖拽组件、预置业务逻辑模板、图形化配置规则等方式,显著减少手动编码工作量的开发工具。其核心在于以可视化配置,节点式拖动变成的方式替代直接写代码的方式,既能让具备一定技术能力的开发者从重复劳动中解放出来,也能让熟悉业务逻辑的非技术人员参与到应用搭建中。本质上,它是在开发效率与场景灵活性之间架起一座平衡的桥梁。 + +这类低代码/无代码智能体平台的突出价值,正是大幅降低 AI 应用的开发门槛。以往需要团队协作数周——从需求梳理、代码开发到测试部署——才能完成的 AI 智能体(如客服问答机器人、数据处理助手),现在借助平台提供的可视化工具,可将“从创意到上线”的周期缩短至数小时。 + +目前市面上主流的低代码 AI 工作流平台包括: + +| 平台 | 特点 | 适用场景 | +| --------------------------------------------- | -------------------------------------------------- | -------------------------------------- | +| Dify | 开源、支持知识库 RAG、LLM 编排、API 输出,中文友好 | 企业知识库问答、定制化 Agent、API 服务 | +| Coze(字节跳动) | 国内可用、集成抖音/飞书生态、插件丰富 | 社交机器人、国内小程序集成 | +| n8n | 通用自动化工具,支持 AI 节点,强调 API 编排 | 跨系统数据同步、AI + 传统 SaaS 自动化 | +| 百度千帆 AppBuilder / 阿里百炼 / 腾讯 HunYuan | 大厂云原生方案,集成自家模型 | 企业级部署、合规要求高场景 | + +目前市面上的低代码 AI 工作流平台选择丰富。尽管 AWS、Azure、阿里云等主流云厂商均推出了相应的 AI 工作流解决方案,但 Dify、Coze 和 n8n 凭借以下三大核心优势,成为当前应用最广泛的代表: + +1. 极致易用性。平台采用可视化拖拽式界面设计,用户无需深入理解底层技术,即可快速上手。 +2. 高灵活性。支持自定义组件与扩展 API 接口,既能适应教学演示、MVP(最小可行产品)验证等轻量场景,也能满足中小型团队的敏捷迭代需求。 +3. 成熟生态。不仅官方文档详尽、响应及时,还拥有活跃的用户社区,便于快速获取来自不同用户的预设方案。 + +这三大平台均支持将搭建好的 AI 智能体以标准化 API 接口的形式输出,可无缝集成至前端 Web 应用、企业内部 ERP 系统或移动端 APP 中,进一步降低了 AI 能力落地的技术门槛。 + +### 1.3.1 Dify:企业级LLMOps与应用生命周期管理平台 + +Dify 定位是LLM应用开发与运营平台,致力于提供AI应用从构思、部署到优化的全生命周期管理。其核心是一个低代码平台,旨在帮助开发者和非技术背景的创新者快速构建生产级AI应用。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image6.png) + +在功能上,Dify覆盖了可视化工作流编排、智能体构建、知识库管理、多模型支持等功能。平台允许通过拖拽节点设计复杂任务流程,并支持创建基于意图的Agent。其知识库功能突出,能处理多种格式文档并进行高效的向量检索。同时,Dify兼容支持包括GPT、Claude及众多开源模型在内的多种LLM,构建的应用可一键发布为标准API便于集成。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image7.png) + +技术架构方面,Dify以开源和可私有化部署为特色,强调灵活性、扩展性及企业级合规。目标用户包括开发者团队和业务创新者,典型应用场景涵盖企业知识库与智能客服、内容创作自动化、垂直领域AI助手以及企业AI中台。 + +### 1.3.2 Coze(字节跳动):零代码AI智能体构建的普及者 + +Coze是字节跳动推出的AI智能体开发平台,以极致易用性为核心,让无编程经验的用户也能轻松创建、调试并发布功能丰富的AI聊天机器人。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image8.png) + +其核心是将Bot构建简化为搭积木式操作。用户可通过界面轻松配置角色与知识库,并利用丰富的内置插件库为Bot添加新闻、旅游、图像生成等多类外部能力。创建好的Bot可一键快速发布至豆包、飞书、微信公众号等多个平台。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image9.png) + +技术架构完全服务于低门槛使用,后端集成字节自有模型并封装复杂流程,强调多模态理解与实时响应。作为一个主要以云服务形式提供的平台,其私有化部署能力相对有限。典型应用场景包括个人助理与娱乐Bot、智能客服与问答系统、在线教育助手以及快速原型验证。 + +### 1.3.2 n8n:可编程的后端工作流自动化引擎 + +n8n是一个通用的可编程工作流自动化平台,其核心定位是连接各类应用、数据库与API,实现数据流动与任务自动化执行。 + +它通过庞大的集成节点库支持数百种SaaS服务、数据库及协议,并采用可视化与代码结合的方式:用户可在画布拖拽节点,同时注入JavaScript或Python代码编写自定义逻辑。n8n擅长处理后端数据密集型任务,如数据同步、ETL流程与API编排。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image10.png) + +关键技术特性是“源码可见”和“可自托管”,用户可将其私有化部署以完全掌控数据与环境,这使其对数据安全要求高的行业极具吸引力。其主要目标用户是开发者、技术运营及数据分析师。n8n 最大的优势,在于拥有极其强大的社区生态。网络上拥有随处可见丰富的 n8n 分享视频,为用户提供了便捷的学习参考与经验借鉴;同时,它支持连接 YouTube、Instagram 等全球众多不同生态平台,能够帮助用户轻松打破跨平台数据与服务的壁垒,实现多生态流程的自动化流转。 + +### 1.3.3 其他工作流平台 + +除了上述的几个最知名的平台,中国国内的主要科技厂商也相继推出了各自的一体化AI开发平台,例如:百度千帆 AppBuilder 提供从模型选型、RAG构建到智能体发布的全流程支持,深度集成文心大模型;阿里云百炼基于通义千问系列模型,注重企业级安全与私有化部署能力;腾讯云 TI 平台 则聚焦于金融、医疗等行业场景,提供丰富的预置解决方案模板。这类平台通常与各自云生态深度融合,适合已处于相应技术体系内的企业选用。 + +然而,在通用型、开放性与社区生态方面,Dify 与 Coze 仍凭借其突出的易用性、广泛的模型支持以及活跃的开发者社区,成为当前更受广泛采纳的选择。 + +尽管各平台在定位与生态上各有侧重,其核心逻辑均是通过可视化方式编排与连接不同的能力模块。因此,掌握其中任意一种平台的设计思路与操作方法,即具备快速迁移到其他类似工具的基础。在接下来的实践中,我们将以 Dify 为例进行具体讲解。 + +# 2. 深入浅出 Dify + +## 2.1 什么是 Dify + +我们在之前已经了解了基础的 Dify 的信息介绍,对于更详细的信息,你可以通过 [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps) 访问 Dify 平台,如果想了解更多信息,可以访问官网 https://dify.ai。 + +Dify 是一个用于开发 LLM 应用的开源平台。它提供了直观的界面,将 Agent 工作流、RAG 流水线、工具能力、模型管理、可观测性等功能结合在一起,帮助你快速地从原型走向生产环境。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image11.png) + +你可以在 Dify 中使用大语言模型和各种功能不同的工具来搭建“工作流”。所谓工作流,就是把原本需要你手动一步步完成的操作——例如数据检索、大模型调用、网页搜索、结果过滤、格式整理等——按照业务逻辑串联起来,变成一个自动化、可复用的流程。如果没有工作流,每次你都需要把同样的内容复制粘贴给大模型,非常低效、容易出错,也难以在真实业务中复用。 + +搭建一个工作流,就像在拼搭积木或拼图。你把“大语言模型节点”(负责理解和生成)、各类“工具节点”(负责执行具体动作,例如查数据库、发邮件、翻译文本等)、以及“数据节点”(负责读取、存储信息)像积木一样连接起来。它们会按照你预设的逻辑自动协同工作,而不需要你每次都手动操作。你也可以把它理解成一种“低代码程序”:你只需要通过拖拽的方式,配置输入和输出的路径,就可以实现比较复杂的业务逻辑。 + +举个例子,如果你是一个亚马逊或抖音电商店铺的老板,想要搭建一个 AI 客服系统,可以参考下图的结构设计一个工作流: + +1. 触发节点(类似 START):接收用户的咨询问题,例如“这个商品的质保期有多长?”。 +2. 问题分类节点(类似 QUESTION CLASSIFIER):使用一个模型(例如 GPT)对用户问题进行分类,判断这是售后(比如质保)、使用方法,还是其他类型的问题。 +3. 知识检索节点(类似 KNOWLEDGE RETRIEVAL):根据分类结果,自动访问相应的知识库。如果是关于“质保”的售后问题,就从售后 SOP 知识库中检索与“质保”相关的精确信息。 +4. 大语言模型节点(LLM Node):将用户问题和检索到的知识库内容一起发送给大语言模型(例如 GPT),让它生成一段对用户友好的回复(避免太生硬的技术语气)。 +5. 条件节点:检查大模型生成的回答中是否包含清晰的质保时间(例如“1 年”、“3 年”),如果有则继续下一步,如果没有则让它回复“请提供产品型号”。 +6. 输出节点(类似 ANSWER):将最终答案返回给用户,并自动把本次咨询记录到表格中。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image12.png) + +在整个过程中,你不需要手动去翻知识库、反复调整模型的回答、或单独记录数据——工作流会把这些步骤“连起来自动跑”。并且它非常灵活:例如,如果你之后想加一个新规则“当用户问质保范围时,调用另一个知识库”,只需要在工作流中多加一个条件节点,而无需重构整个系统。 + +这是一个比较简单的工作流示例,但要完全掌握这些能力,对现在的你来说可能还有点难。因此在本节课中,我们从更加基础的知识库智能体开始,后面再逐步学习更复杂的工作流技巧。 + +### 2.1.1 部署属于自己的 Dify(可选) + +本部分内容原本安排在后续课程中详细介绍,但考虑到当前部分学习者可能因网络限制暂时无法访问 Dify 官方网站或云端服务,我们决定提前提供这一可选的学习路径,帮助你顺利推进课程进度。 + +你需要参考该教程入门 web 部署平台的基本使用方式:[如何部署 Web 应用](/ko-kr/stage-2/backend/zeabur-deployment/) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image13.png) + +你需要学习如何在 Zeabur 上部署一个自己的 Dify,部署后进入到对应链接注册并登录后继续跟随下列教程操作即可。 + +注意,不同版本的 Dify 的操作方面和前端界面可能有些许差别,但总体上差别不大,当你发现不同的时候不要慌张,找到类似的接口和入口进行操作即可。 + +## 2.2 创建第一个 Dify Chatbot 应用 + +访问 Dify 首页 [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps) 并注册和登录后,选择 Studio,你会看到如下界面: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image14.png) + +在左侧找到 `CREATE APP` 区块,点击 `Create from Blank`。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image15.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image16.png) + +在 APP Type 中找到 Chatbot(如果一开始没看到,可以点击“查看更多类型”的按钮,然后在完整列表中找到)。选择 Chatbot 之后,在下方输入应用的名称和描述,最后点击创建。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image17.png) + +创建完成后,你会看到类似下面的界面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image18.png) + +中间区域的 “INSTRUCTIONS” 指的是内置指令,你可以把它理解为默认提示词或系统提示词。 + +中间偏下有一个 “Knowledge” 区域,这就是知识库区域——我们稍后会把自己的知识库上传到这里。 + +右侧是调试窗口,你可以在调整提示词后与 Agent 进行对话,实时查看效果。 + +你可以在 INSTRUCTIONS 区域自由输入角色提示词,观察对话效果;也可以点击 Generate,让大模型自动帮你生成提示词。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image19.png) + +注意右上角会出现许多不同模型的选项,这意味着你可以点击切换不同的对话模型,从而比较它们在语气、逻辑推理、长文本处理等方面的差异,寻找最适合你需求的模型。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image20.png) + +## 2.3 支持自定义模型供应商 + +为充分发挥 Dify 的灵活性,考虑到不同地区访问模型的难度,为满足特定业务需求、成本控制或数据隐私要求,我们常常需要接入自定义模型。Dify 支持配置三类核心模型:大语言模型(LLM)、Embedding 模型和 Rerank 模型。本部分内容将逐步指导你完成这些自定义配置。 + +Dify 能够灵活接入来自 OpenAI、Azure、Anthropic 等主流服务商的模型,同时也全面兼容任何符合 OpenAI API 接口规范的自托管模型或第三方模型。你可以通过安装内置的 OpenAI Compatible 插件以及对各大模型平台定制的插件实现这一操作。 + +详细步骤参考如下,首先我们需要安装对应的插件: + +1. 我们需要安装 `OpenAI-API-compatible` 及 `SiliconFlow` 插件获得对绝大部分大模型和 Embedding 模型的支持,其中前者是对 OpenAI 兼容接口的支持,后者是一个部署了当前绝大部分常见、好用的开源模型的服务站。你可以访问下列网页进行安装: + 1. https://marketplace.dify.ai/plugins/langgenius/openai_api_compatible + 2. https://marketplace.dify.ai/plugins/langgenius/siliconflow +2. 如果你是自己部署的 Dify,你可以在对应系统设置界面进入插件市场进行操作 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image21.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image22.png) + +进入插件市场后,搜索对应的插件名称即可。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image23.png) + +3. 安装结束后,我们能够配置支持新的模型供应商,在设置里的模型提供商部分,我们可以看到目前支持的所有模型商: + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image24.png) +4. 在开始使用前,需要先完成模型的配置。对于 OpenAI-API-compatible 插件,你可以点击 “Add Model” 来添加并配置任意模型。你可以在 “Model Type” 中选择该模型是LLM还是 Embedding,你需要确保模型的类型被正确配置。 + 你需要写入具体的模型名字、模型 endpoint URL 以及 API Key 才能确保模型启用,如果你初步觉得配置该参数麻烦,你可以直接跳到后者的 SiliconFLow 平台的 Key 配置,或者安装 OpenRouter 等第三方服务商插件进行简单的模型支持配置。(确保服务商内有剩余可使用额度) + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image25.png) + + 对于 `SiliconFlow` 插件,只需要点击 Setup 配置 key 后即可使用 Embedding 和 Rerank 模型进行测试,你可以点击 Get you API Key from SiliconFlow 获得鉴权密钥。 + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image26.png) + +5. 配置完成后,你可以点击模型列表查看当前支持多少模型,此时已经完成了基础模型的全部配置。 + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image27.png) + + 其中支持了绝大部分常见的 Embedding 与 Rerank 模型: + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image28.png) + + 此时如果你想要修改 Dify 默认使用模型的配置,你还可以点击 System Model Settings 按钮修改默认的所有模型。 + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image29.png) + +## 2.4 创建第一个 Dify 知识库 + +到这里,我们已经完成了最简单的 Agent 创建,但它还缺少一个知识库。现在,请点击顶部菜单中的 `Knowledge`,进入知识库创建页面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image30.png) + +然后点击左侧的 `Create Knowledge`,创建你的第一个知识库。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image31.png) + +在这个界面中,你可以上传多种类型的文件(例如 pdf、txt 等)来构建知识库。可以上传很长的文本,或者把维基百科上的内容复制下来保存成 txt 文件进行上传。本例中,我们会上传一份关于 Elon Musk 的维基百科 txt 文件。 + +点击 Next 后,你会进入 Knowledge Base Settings(知识库设置)页面。这里选项比较多,我们一步一步来看。 + +首先在 **General** 设置中,你可以把这里理解成“文本切分规则”的设置区域。因为我们需要把很长的文本切分成小块,所以必须先定义切分规则。在入门阶段,你只需要关注 **maximum chunk length(最大切分长度)** 。可以尝试设置为 512、2048 或 4096,然后点击 **Preview Chunk** 预览不同设置下的效果。 + +你也可以调整 **Chunk overlap(切片重叠)** 选项。它决定相邻片段之间是否会保留一部分重叠内容。适当的重叠有助于避免重要信息被拆到不同片段而难以理解。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image32.png) + +在设置中还有一个选项叫做 **Chunk using Q&A format in English** 。启用后,系统会使用大语言模型,将知识库的一部分内容转换成问答形式来存储,这在某些场景下可以显著提升检索效果。 + +在真实业务中,根据场景选择合适的切分策略,能够更好地优化检索结果,保证查询能够返回你期望的信息。 + +继续向下滚动页面,你会看到和 Embedding 模型相关的设置。 + +简单解释一下:Embedding 模型的核心功能,是把非结构化数据(例如文本、图片等)转换成计算机能够理解的“数字向量”(Embedding 向量)。通过这种转换,模型能够快速计算不同数据之间的相似度,从而实现语义相近内容的匹配,比如根据用户输入的一句话,找到语义最接近的文档、图片或商品。 + +Embedding 模型的选择会显著影响最终的检索效果(例如匹配准确度、响应速度等)。在这里,我们推荐优先使用 Qwen 0.6B 的 Embedding 模型,你也可以切换到 4B 或 8B 版本,直观对比不同参数规模下检索效果的差异。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image33.png) + +在此处,你还会看到另一个模型设置叫做 **Rerank model** ,默认值是 **Jina-rerank-m0** 。(如果你非校园内的学生,此时你可能会看到 Rerank 模型缺失的报错,你需要在模型处配置 rerank 模型才能在此处启用使用) + +Rerank 模型的主要作用,是对“初步筛选出的候选结果”进行二次、更精细的排序,让和用户需求最匹配的结果排在更靠前的位置,从而显著提升最终结果的相关性和用户体验。 + +简单理解:Rerank 模型就是用来解决“初次筛选不够精细”的问题。例如搜索引擎可能先用较简单的规则检索出 1000 个潜在相关网页,再通过 Rerank 模型,从中挑出最相关的前 10 个展示在第一页。 + +推荐系统同理:它可能首先找出 500 个“可能适合你”的商品,再通过 Rerank 模型排序,让你最可能购买的商品排在列表顶部。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image34.png) + +当所有设置完成后,点击 **Save & Process** ,系统就会进入知识库向量化阶段。在这一阶段,Embedding 模型会把切分后的文本转换为向量表示。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image35.png) + +处理完成后,点击 **Go to document** ,可以查看已经处理完毕并存储好的知识库内容。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image36.png) + +直接点击知识库名称,可以查看每个切片的具体内容。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image37.png) + +在这里,你可以对任意不合适的文本片段进行精确的编辑或删除操作。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image38.png) + +在左侧边栏中,选择 **Retrieval Testing** 可以对知识库进行召回测试,检查检索是否正常工作。每次测试会返回若干相似度最高的切片。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image39.png) + +如果你希望看到更多的切片结果,需要点击 `VECTOR SEARCH` 设置: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image40.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image41.png) + +Top K 指的是向量检索时,返回与查询向量最相似的前 K 个文本切片数量。当前设置为 3,表示会返回相似度最高的 3 段文本。 + +Score Threshold 则是一个“得分阈值”:只有相似度得分大于或等于该阈值(示例中为 0.5)的文本片段才会被返回。这样可以过滤掉相关度较低的内容,让结果更加准确。 + +现在知识库部分就全部准备好了。接下来,点击顶部菜单栏中的 “studio”,找到刚才创建的智能体,为它接入我们已经配置好的知识库。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image42.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image43.png) + +此时,在每一轮对话中,你都可以在回答中看到被命中的知识库来源。点击对应条目即可查看检索到的具体文本片段。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image44.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image45.png) + +## 2.5 更多 DIfy 常见操作 + +在掌握基础 Chatbot 和知识库搭建的基础内容后,我们可以深入了解更多有关 Dify 的使用方式。 + +### 2.5.1 工作流的导入与导出 + +还记得之前提到的工作流的中间表示法吗?Dify 支持通过 DSL(Domain Specific Language) 格式导入和导出工作流。DSL 是一种基于 JSON 的标准化描述方式,能够完整保留工作流的节点结构、连接关系和配置参数。你可以很容易导入和导出 DSL 文件,分享工作流给其他人使用,或者导入别人的工作流进行参考。具体而言,我们能够容易在工作台页面看到工作流的导入按钮: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image46.png) + +而对于工作流的导出,我们只需要点击单个工作流块的右下角即可找到导出按钮: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image47.png) + +通过使用 DSL 文件,你可以轻松地在不同 Dify 实例之间迁移或共享复杂的工作流设计。 + +### 2.5.2 查看更多 Dify 项目 + +如果你觉得自己搭建的工作流或者智能体过于简单,Dify平台提供了丰富的示例项目,帮助你快速了解如何构建复杂应用。这些示例项目涵盖了多种业务场景。你可以点击 Explora 查看别人构建的工作流进行学习。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image48.png) + +## 2.6 创建第一个 Dify Workflow 应用 + +完成了 DIfy 的对话智能体构建入门,我们继续查看如何构建更复杂的 Dify 业务工作流。工作流是Dify将复杂业务逻辑可视化的核心方式,通过它你可以像搭积木一样构建智能流程。你能够完整体会信息如何在不同节点间流转,判断逻辑如何部署,人工干预点设置在哪里,以及最终如何交付一个完整的业务结果。 + +你可以选择从空白处创建,或者直接从模板处创建,此处演示如何从空白处创建工作流: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image49.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image50.png) + +在这里我们会看见两个选择,分别是 Chatflow 与 Workflow,这两者该如何选择呢?关键是你需要理解你所要构建的,其核心是持续对话,还是任务流程。 + +Chatflow 专为对话而设计。它模拟一个具有记忆和上下文理解能力的对话者,非常适合需要多轮交互、状态维持的场景。例如在客服咨询中,它能连贯地理解用户的后续追问,如同一位耐心的服务人员。其流式输出的特性也让交互过程更为自然。简而言之,当你需要构建一个能“交谈”的智能体时,应选择 Chatflow。 + +Workflow 则专注于流程的自动化执行。它像一条预设的流水线,擅长处理一次性输入、多步骤处理、并产生确定性输出的任务。例如,每日定时生成数据报表、批量处理文件或调用系列API。这类任务通常由事件触发,无需与人实时互动。因此,当你需要实现“自动化”任务时,Workflow 是更合适的选择。 + +为避免选型错误带来的效率低下,你可以通过四个关键问题来审视你的任务需求: + +1. 任务过程是否需要依赖多次的用户输入与调整? +2. 结果的呈现是否需要分步骤、流式地进行? +3. 处理逻辑是否严重依赖于之前的交互历史? +4. 任务是否由事件触发,且输入输出多为一次性完成? + +如果前三个问题的答案为“是”,那么 Chatflow 是理想选择,典型场景包括智能客服、教育辅导、创意协作等。如果第四个问题特征显著,则应选用 Workflow,它更适用于数据清洗、报表生成、批量处理等自动化场景。 + +此处我们选择 Chatflow 作为案例进行介绍,点击 Chatflow 后进入到操作台界面: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image51.png) + +我们来简单介绍工作流界面的页面。其中整个界面的核心是中央的编辑画布,你将以可视化方式在这里构建应用逻辑。如图所示,一个基础的工作流通常始于 START 节点(用于接收输入),经由连线将数据传递至 LLM 节点进行处理,最终通过 ANSWER 节点输出结果。每个节点代表一个功能模块,而连线则决定了任务执行的顺序。 + +环绕画布的是完整的操作与管理功能区。界面顶部提供了全局控制选项,包括测试工作流的 Preview 按钮和用于上线的 Publish 按钮。画布角落则设有缩放、撤销等视图控制工具,便于精细调整。 + +左侧面板集中了应用的管理功能。你当前所在的 Orchestrate 选项卡用于流程编排;构建完成后,可通过 API Access 获取集成凭证;Logs & Annotations 记录了每次执行的详细踪迹,便于调试;而 Monitoring 则为你提供应用运行时的性能与状态监控。 + +你可以简单在该对话工作流 LLM 节点的 SYSTEM 中输入一些提示词内容,点击 Preview 后尝试运行这个工作流,查看修改 SYSTEM 提示词后整个工作流确实按照预期在变化。 + +### 2.6.1 常见节点介绍 + +Dify 中提供了多种节点,你可以先了解每个节点的基本功能。具体使用时,建议亲手尝试,或参考他人创建的工作流模板,也可以截图并向大模型询问该节点的用法、所需参数等。推荐直接在现有模板中替换不同节点,通过他人的使用方式来推测节点的最佳实践。 + +在画布右键点击“Add Node”即可添加节点,也可以在左侧的节点面板中查看所有可用节点: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image52.png) + +同时,可以打开工具选择面板,查看支持调用的各类工具: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image53.png) + +下面是一些常用节点和工具的简要说明。不需要一次性全部掌握,建议先留个印象,在实际使用中逐步熟悉,必要时再回查阅。 + +1. LLM与推理节点 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image54.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image55.png) + +此类节点负责工作流中的核心流程。 + +- LLM节点:核心计算单元,用于调用大语言模型。其配置重点在于提示词工程与参数调优,将业务问题转化为模型的执行指令。 +- Knowledge Retrieval 节点:知识检索单元,负责从预设知识库、外部权威数据源中检索与业务问题相关的信息,为 LLM 节点提供精准的知识支撑,帮助减少大语言模型输出的 “幻觉” 问题。 +- Answer 节点:结果输出单元,负责接收 LLM 处理后的内容,将其整理为符合业务场景需求的最终成果形式。其配置重点在于输出格式的定义(如话术模板、排版规范)。 +- Agent节点:高阶决策单元。它不仅调用模型,还可实施多步骤规划、自主选择并调用外部工具,适用于需要动态决策的复杂任务链。 +- Question Classifier 节点:问题分类单元,负责对输入的业务问题进行类型识别与归类(比如按问题意图、主题领域等维度划分),帮助后续流程精准匹配对应的处理节点(如不同类型的问题适配不同的 LLM 提示词或工具链)。 + +2. 逻辑与流程控制节点 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image56.png) + +此类节点定义工作流的执行路径与规则。 + +- 条件节点:如 `IF/ELSE`,通过布尔判断实现流程分支。其设计关键在于条件表达式的严谨性,确保逻辑覆盖所有业务场景。 +- Iteration 节点:作为无状态的批量并行处理单元,它专为子任务间无数据依赖、可独立处理的场景设计,例如批量翻译段落、并行审核多条内容或同时生成多份报告。该节点会接收一个输入数组并自动分片,将每个元素分发至相同处理链路并行执行,用户可在迭代体内通过 {{item}} 访问当前元素、{{index}} 获取其索引,输出则会自动聚合成结果数组;配置时需重点设定并行度以平衡效率与系统负载,同时通过重试策略(如重试次数、间隔)和失败处理(如记录日志、返回默认值)保障批量作业的稳定性。 +- Loop 节点:有状态的递归迭代器,适用于结果依赖前一轮输出的场景,比如多轮参数调优、递归式内容优化(如反复修订文案直至满意)及依赖上次结果的链式计算。其核心是 “状态变量”,需在循环开始前初始化(如当前迭代次数、中间计算结果),并在每轮迭代中明确更新以作为下一轮输入;为防止无限循环,必须定义终止条件(包括基于计数器的 “最多循环 10 次”、基于结果判定的 “满意度评分 > 9”、基于外部信号的 “检测到‘停止’输入”),同时需设置循环超时配置,并规划异常处理路径(如跳出循环或重置状态后重试),确保流程稳定运行。 + +3. 数据操作与集成节点 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image57.png) + +- Code 节点:代码处理单元,负责在工作流中执行自定义代码逻辑,可实现数据格式转换、复杂计算等个性化处理需求。其配置重点在于代码语法的正确性与执行环境的适配。 +- Template 节点:模板处理单元,负责将动态数据填充至预设模板中,生成符合格式要求的内容(如定制化文案、报告框架)。其配置重点在于模板语法的编写与变量映射规则的设置。 +- Variable Aggregator 节点:变量聚合单元,负责收集工作流中多个节点输出的变量数据,将分散的变量整合为统一数据集。其配置重点在于聚合的变量范围与数据合并规则的定义。 +- Doc Extractor 节点:文档提取单元,负责从 PDF、Word 等各类文档中提取文本、表格等关键内容,转化为工作流可处理的结构化数据。其配置重点在于文档类型的适配与提取内容的筛选规则。 +- Variable Assigner 节点:变量赋值单元,负责定义、初始化或更新工作流中的变量,为流程内的数据传递提供载体。其配置重点在于变量的命名、数据类型及赋值逻辑的设定。 +- Parameter Extractor 节点:参数提取单元,负责从用户请求、接口返回等输入内容中提取指定参数,将非结构化信息转化为结构化数据。其配置重点在于提取规则(如正则表达式、JSON 路径)的配置。 +- HTTP Request 节点:HTTP 请求单元,负责向外部系统接口发起 HTTP 请求(含 GET、POST 等方法),实现工作流与外部服务的数据交互。其配置重点在于请求地址、请求方法及参数 /headers 的设置。 +- List Operator 节点:列表操作单元,负责对数组、列表类型的数据进行处理(如过滤、排序、拆分),调整数据结构以适配后续流程。其配置重点在于操作类型(如过滤条件、排序规则)的定义。 + +### 2.6.2 常见工具介绍 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image58.png) + +在 Dify 中,大部分工具都可以直接作为节点放在画布上,像其他节点一样被上下游连线,只要你提供的输入符合该节点(工具)的参数规范,它就能正常执行并产出可继续流转的结果。 + +在左侧或右侧的节点面板中,可以查看所有可用工具节点,也可以通过插件市场扩展更多工具能力。简单介绍几个常见工具的作用: + +- 网络搜索工具 + 以 Tavily Search 为代表,为大模型提供面向 AI 优化的实时检索能力。 + 它会返回结构化的搜索结果(如标题、摘要、链接等),可以直接作为 LLM 提示词的一部分,用于回答最新资讯类或需要权威依据的问题。 +- 数据处理工具 + 例如 JSON Process 插件,用于对 JSON 数据进行查询、筛选、转换、合并等高级操作。 + 在处理复杂 API 响应或多层嵌套数据时,你可以将“数据清洗 + 重组”的逻辑交给该工具,从而简化在 Code 节点中频繁手写解析代码的工作。 +- 格式处理工具 + 如 Markdown Exporter,可以将生成内容按指定格式导出,例如 Markdown 文档、特定排版模板等,方便后续用于展示、汇报或集成到其他系统。 + +你可以在工具列表中看到这些插件的安装量和简介,初期可优先尝试安装“Featured / 推荐”里的工具,往往覆盖了最常见的业务场景。 + +不过,工具的使用通常比较复杂,建议你在使用的时候可以去搜索引擎先搜索对应工具的“官方推荐工作流 DSL 案例”,直接导入使用,比自己搭建要天然节约很多时间。 + +### 2.6.3 创建简单的意图分类工作流 + +此时我们已经初步了解了 Dify 工作流和工具等的基本信息,但不经过练习我们永远不会熟练使用细节,我们需要一个“假设”的真实业务场景来练练手。 + +例如,在真实的购物对话场景中,前来购买商品的用户输入永远不会是“规范的参数”,而是一句随口说出的话:有人来下单,有人来抱怨,有人只是想闲聊,也有人完全跑题。如果我们把所有这些输入都直接交给同一个大语言模型(LLM)处理,系统通常会出现两个典型问题: + +1. 回复风格不稳定 + 同样是抱怨,有时 LLM 能道歉安抚,有时却像在“解释原因”;同样是点餐,有时会追问缺失信息,有时则直接编造订单细节。 +2. 业务逻辑不可控 + 你希望“抱怨必须先道歉”,但模型未必每次都遵守;你希望“非业务问题要引导回主线”,但模型可能会兴致勃勃地和你聊起段子。 + +因此,更工程化的做法是将任务拆解为一条标准化流水线,先做意图分类(确定用户到底想干什么),然后再按意图分流(不同场景使用不同的提示词与角色),最后对不同分流后大模型的回复统一封装输出(便于前端或系统集成)。 + +本节的目标是让系统能处理一个餐饮场景下的多类对话。你可以跟着操作做一遍加深印象。首先需要做的是定义场景为意图分类: + +- **下单购买 (buy_food)** :用户表达明确的购买意愿。 +- _例如:“给我来一份炸鸡,再加一杯可乐。”_ +- **抱怨投诉 (complain)** :用户在表达不满、催促或负面反馈。 +- _例如:“你们也太慢了吧?等一个小时了。”_ +- **闲聊咨询 (chitchat)** :用户在进行开放式询问、寻求建议,但无明确下单指令。 +- _例如:“今天吃什么好呢,你有什么推荐吗?”_ +- **其他意图 (other)** :用户的输入与餐饮场景无关。 +- _例如:“帮我写个搞笑文案发朋友圈。”_ + +针对这四种意图,我们为系统预设了四种不同的“沟通人格”,分别由四个独立的 LLM 节点承载,每个节点都需要由具有不同人设的 LLM 进行扮演。 + +- **下单助手 (LLM_BuyFood)** :专业、高效,核心任务是确认订单细节,并主动补全缺失信息。 +- **客服专家 (LLM_Complain)** :共情、稳重,首要任务是安抚用户情绪,并提供清晰的解决方案。 +- **聊天伙伴 (LLM_Chitchat)** :轻松、友好,旨在提供个性化推荐,引导潜在消费。 +- **礼貌门卫 (LLM_Other)** :专注、边界清晰,负责将偏离主题的对话礼貌地引导回核心业务。 + +#### 工作流编排设计 + +接下来我们进行工作流的编排设定,决定大概需要有哪些工作流节点。对于新手而言,很难想到需要有哪些节点能被用到(对于老手来说也懒得自己思考,用大模型给建议通常是最快最好的选择),所以我们能够使用大模型给出对应的编排建议,其核心节点结构如下: + +- Start (起点):作为数据入口,负责接收用户的原始输入 `user_text`。 +- Question Classifier (意图分类器):工作流的“大脑”与“调度中心”。它负责对 `user_text` 进行分析,并从我们预设的四种意图标签中选择最匹配的一个。 +- Condition (条件分支):扮演“分流阀”的角色。它根据分类器输出的意图标签,决定接下来将任务导向哪一个专处理路径。 +- 四个并行的 LLM 节点 (LLM_BuyFood, LLM_Complain, LLM_Chitchat, LLM_Other):这是四个独立的“专家处理单元”。每个节点都接收原始问题,但依据自身独特的 System Prompt(系统提示词)生成风格和目标截然不同的回复。 +- Variable Aggregator (变量聚合器):在多条路径处理完成后,需要一个“汇集点”。此节点将四个分支中唯一被激活并产生结果的回复,收束成一个统一的变量 `final_reply`,确保了输出结构的稳定性。 +- Output (终点):作为最终的出口,负责将意图标签、原始问题、以及经过处理生成的回复,以结构化的形式(如 JSON)统一输出,便于后续系统调用或调试分析。 + +#### 工作流编排实现 + +本次教程我们选择创建 Workflow 而不是 Chatflow,选择 User Input: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image59.png) + +随后点击 Start 的 User Input 节点,定义一个名为 `user_text` 的字符串类型变量,作为整个流程的输入源。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image60.png) + +保存后点击右上角的 Test Run,你能够看到需要指定对应的文本输入进行处理: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image61.png) + +随后我们需要点击输入节点后的 + 符号,选择 Question Classifier 节点添加,并且我们需为其配置四类标签,并为每个标签提供清晰的描述和示例。 + +- `buy_food`: 用户明确想买吃的、点餐、下单。 +- `complain`: 用户在抱怨、吐槽、发脾气,通常带有不满情绪。 +- `chitchat`: 用户在闲聊、讨论吃什么、咨询推荐。 +- `other`: 与餐饮场景无关,或难以判断的内容。 + +此外,你还需要在 ADVANCED SETTING 中写入提示词,让大模型能够正确根据用户输入进行分类测试。示例提示词如下: + +``` +从 buy_food / complain / chitchat / other 中选择一个最合适的标签。如果用户在抱怨的同时也点了餐,请优先判断其核心情绪,若重点在于表达不满,应归为 complain。如果只是轻微吐槽但主要意图是下单,则归为 buy_food。若实在难以判断,使用 other 作为兜底 +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image62.png) + +设定完成后,你可以在右上角的播放键单独测试该节点是否能够正常运行: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image63.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image64.png) + +从 OUTPUT 的结果来看,我们的分类是准确的。你可以进行多种不同类型输入的测试,验证我们分类器的稳定性。 + +接下来,我们需要给分类器接上后续的大模型输出,例如,当 `label` 等于 `"buy_food"` 时,工作流便会精确地流向 `LLM_BuyFood` 节点。我们需要新建四个 LLM 节点,并设置不同的 System Prompt ;不同 System Prompt 的差异决定了它们不同的回应方式。 + +- LLM_BuyFood (点餐助手): + +你是一个点餐助手。要求:1. 确认用户想点的内容。2. 如果信息不完整,友好地补充询问。3. 语气礼貌简洁。 + +- LLM_Complain (客服专家): + +你是一个餐饮客服,专门处理抱怨。要求:1. 真诚道歉。2. 简要说明可能的原因(不推卸责任)。3. 给出清晰的下一步解决方案。 + +- LLM_Chitchat (聊天伙伴): + +你是一个帮人选吃的的聊天小助手。要求:1. 用轻松友好的语气。2. 给出 1~3 个简单推荐。3. 如果用户没有偏好,就给出不同风格的选择。 + +- LLM_Other (礼貌门卫): + +你是一个餐饮点餐小助手,只擅长跟‘吃’相关的话题。当用户说的话无关时:1. 礼貌说明自己的能力范围。2. 引导用户回到主场景。 + +值得注意的是,每个节点里面在填充了 SYSTEM 的提示词参数后,你还要记得启用 USER 提示词参数表。你需要在其中需要点击 `{x}` 符号,选择 `user_text` 参数作为用户输入,并且在前面加上 `user input:` 标识这个变量是用户输入的意思,在问答的时候会综合用户的最开始的输入和内置提示词进行回复。 + +同样的,为了确保一切顺利,你可以点击该节点右上角的播放箭进行具体的对话测试验证效果,比如对话说“我想要喝珍珠奶茶”等,查看回复是否符合预期。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image65.png) + +接下来我们处理并行 LLM 的输出值,我们在 `Variable Aggregator` 节点的配置面板中,找到 `ASSIGN VARIABLES`(分配变量)区域,点击后依次将之前的大模型回复加入即可。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image66.png) + +接下来我们需要对所有的输出进行聚合,最后得到我们想要的结果,包含用户的输入、分类、以及回复。由于我们使用的是 Workflow 而不是 Chatflow,故没有 Answer 节点选择进行结果的聚合,我们能够选择其他节点变相实现结果的聚合与输出,此时选择 Template 节点,在变量部分指定用户意图分类结果、用户的输入值、变量聚合的最终回复,并且在 CODE 中写入最后回复的 json 格式模板,我们可以得到: + +- `intent` ← `class_name` +- `original_text` ← `user_text` +- `final_reply` ← `variable_aggregator` + +``` +{ + "intent": "{{ intent }}", + "original_text": "{{ original_text }}", + "reply": {{ final_reply }} +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image67.png) + +最后加入 output 节点即完成所有操作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image68.png) + +#### 工作流运行测试 + +大功告成,我们可以尝试运行这套工作流的效果。它能根据不同的输入,展现出截然不同的行为模式: + +- 输入 (点餐): "给我来一份香辣鸡腿堡套餐,大杯可乐。" + - 路径: `buy_food` → `LLM_BuyFood` + - 输出 reply: "好的,一份香辣鸡腿堡套餐和大杯可乐已为您记录。请问套餐里的薯条需要更换吗?" +- 输入 (抱怨): "你们也太慢了吧?我都等一个多小时了!" + - 路径: `complain` → `LLM_Complain` + - 输出 reply: "非常抱歉让您等了这么久,这确实是我们的疏忽,给您带来了很不好的体验。我们正在紧急核实您的订单配送情况,并会为您申请相应的补偿,感谢您的耐心与反馈。" +- 输入 (闲聊): "今天吃什么比较健康?" + - 路径: `chitchat` → `LLM_Complain` + - 输出 reply: "追求健康的话,可以试试我们的轻食沙拉系列,或者烤鸡胸肉配时蔬。您是喜欢口味清淡一些还是稍微丰富一点的呢?我可以给您更具体的推荐。" +- 输入 (无关内容): "帮我想个明天开会的笑话。" + - 路径: `other` → `LLM_Other` + - 输出 reply: "这听起来是个有趣的挑战!不过我主要是个美食推荐和点餐助手。如果您需要点些什么来犒劳一下辛苦工作的自己,我随时可以帮忙!" + +> 隐藏 Bug :需要说明的是,若你遇到与 aggregation group 相关的奇怪问题,这大概率是 Dify 的一个内置 bug。可能在特定操作下被触发;如果你曾经开启又关闭过 AGGREGATION GROUP,系统可能生成过 group 配置且残留了相关异常参数,即便现在开关看起来是关闭的,这些残留配置也可能导致问题,比如出现 `any` 相关参数的报错。此时你只需要删除该节点并重新创建即可。 + +在 Test Run 中运行后,我们能够看到工作流的执行过程,此时根据分类走了正确的流程,并得到了最后的 output 结果。至此,全流程完成。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image69.png) + +## 2.7 运行第一个模板 Workflow 应用 + +结束了简单的分类工作流学习,接下来我们需要学习如何运行别人的 workflow,我们只需要稍作改造就可以将其变成自己的工作流。在这里我们选择尝试官方的 DeepResearch 工作流,该工作流能够帮你构建一个深度搜索框架,使用大模型+搜索引擎给你一个丰富的搜索答案,每一次提问的结果将会包含搜索引用地址和大模型对话的结果。 + +导入后第一步直接运行,我们根据每一步报错的地方和原因解决具体问题即可,如果遇到解决不了的问题,你可以截图后询问大模型进行解决。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image70.png) + +刚进入感觉十分复杂,没关系,我们点击右上角的 Preview 运行工作流,直到报错出现: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image71.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image72.png) + +我们需要根据报错的节点解决问题,打开后发现是没有配置 Tavily 的 API Token,Tavily 的搜索API 是一个专为 AI 设计的搜索引擎,提供实时、准确和事实性的结果。此时根据提示操作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image73.png) + +经过处理后,搜索引擎能够正常工作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image74.png) + +继续修正模型调用导致的问题后,你应该能够得到如下结果,结合大模型理解下的详细搜索: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image75.png) + +我们在最后能够看到对应的参考文档地址: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image76.png) + +如果你想理解每个环节的作用,最好的方法是将每个环节的 output 记录为一个变量,最后在输出的时候打印每个中间变量的结果,还有一个方法就是你可以在上方找到 Process 的过程,点击后可以查看每个环节的细节: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image77.png) + +## 2.8 将 Dify 作为 API 提供方 + +接下来,我们会尝试通过 API 调用刚才创建的知识库智能体 Agent,我们想要让 Dify 变成一个大模型中枢后端。 + +还记得之前讲过如何通过 API 调用模型吗?我们需要准备一个密钥(Key)和一份 API 调用示例(文档中的 request/response 示例),然后把这些内容发给大模型,让它帮我们写出调用服务的代码,并从返回结果中解析出我们需要的字段。 + +这一次,我们会使用本地的代码编辑工具 [Trae](https://www.trae.cn/) 来完成这个过程。 + +如果你还不熟悉什么是 IDE,可以先阅读文档 [Extra Knowledge 4 - What is AI IDE and Trae](https://github.com/datawhalechina/easy-vibe/blob/main/docs/extra/extra4/extra4-what-is-ai-ide-and-trae.md)。 + +如果你的本地开发环境还没有完整配置好,也不用担心。只要你信任自己的代码助手(不管是 [z.ai](http://z.ai) 还是 Trae),遇到任何不懂的地方或报错,都可以直接把问题抛给它,它会根据你的描述给出详细的解决方案。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image78.png) + +右侧的区域叫做 Copilot 交互窗口,或者 Agent 窗口。如果你看不到它,可以点击右上角的侧边栏图标来打开。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image79.png) + +打开侧边栏后,你会看到 `Builder` 选项。这就是 Agent 模式。你可以简单地把 “Builder” 理解为 [z.ai](http://z.ai) 的“开发模式”,它同样可以帮你操作本地电脑环境、安装依赖、打开网页等。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image80.png) + +点击 “Builder” 后,你会看到 “Chat” 模式和 “Builder with MCP” 模式。 Chat 模式主要用于与当前文件夹进行交互,或者和大模型进行自然语言对话。(你可以通过点击 Trae 左上角的 “File” 打开一个文件夹,然后在该文件夹内进行编辑。这种情况下,Builder 所有的新建文件操作都会发生在这个文件夹中。) + +Builder with MCP 模式则为 Agent 提供了更多工具(例如让大模型连接到其他软件、获取天气信息等)。你可以简单地认为 MCP 是一个让大模型更方便调用各种外部工具的能力集合。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image81.png) + +在下方区域,你还可以看到模型选择的下拉列表,可以点击切换不同模型。这里你可以选择 Kimi k2 或 GLM。如果你使用的是国际版 Trae,也可以选择 ChatGPT 或 Claude。 不过,随着国内大模型的快速发展,Kimi、Qwen、GLM 等模型的综合能力已经基本接近 Claude 3.5 或 3.7,对于日常开发场景来说完全够用。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image82.png) + +上面是对 Trae 的一个简要介绍。接下来,我们可以回顾在 [z.ai](http://z.ai) 中的操作步骤,并在 Trae 中复用这些思路。 + +## 2.9 利用 Dify API 创建前端对话应用 + +如果我们想用 Dify 的 API 搭建一个前端聊天应用,首先需要获取 Dify 的 API 文档和调用地址。 + +还记得刚才创建的那个 Agent 吗? 先点击右上角的 “Publish”,然后点击 “Publish Update”,最后点击 “Access API Reference” 进入 API 文档。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image83.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image84.png) + +进入 API 文档后,找到 “Send Chat Message” 这一部分,点击进入,然后在右侧找到 “Request” 和 “Response” 示例并复制出来。 + +为什么一定要复制这两部分内容? 因为它们是 API 的“核心信息”: 有了 Key、请求示例和返回示例,我们就可以让大模型帮我们生成调用服务的代码,并且根据返回结构把需要的字段提取出来。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image85.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image86.png) + +在找到会话所需的 Request 和 Response 示例之后,我们还需要获取一个 API Key。在文档右上角,你会看到 “API key” 相关选项。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image87.png) + +点击 “Create new Secret key”,就可以创建属于你自己的 API Key。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image88.png) + +现在一切准备就绪。我们会把刚才拿到的 API Key、Request 示例和 Response 示例一起交给 Trae Builder。 + +注意:请将 `{DIFY_API_URL}` 替换为实际的 Dify API 地址。 + +```json +key: +app-zKdCHUXXXXXXXX + +Please write me a front-end based on the following reference: + +curl -X POST 'http://{DIFY_API_URL}/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image89.png) + +在这个阶段,你可能会发现生成出来的程序并不能一次性正常运行——比如对话会出现奇怪的错误,或者没有任何返回结果。当出现这种情况时,你可以尝试切换到另一个大语言模型,或者把错误信息复制出来,详细描述问题,再发给模型让它根据反馈继续迭代。 + +此时你的工作方式已经非常接近真实开发过程了。在日常开发中,我们经常会在与大模型协作时遇到各种问题,为了更好地解决这些问题,我们需要提供更多上下文信息。除了提供错误信息,你还可以复制更完整的文档内容(例如在文档左侧 “Send message” 部分中复制更多说明),一并交给模型,让它在更多细节的基础上给出更完整的解决方案。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image90.png) + +此时浏览器是嵌在 Trae 内部的。你可以点击顶部的指南针图标,把网页在外部浏览器中全屏打开。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image91.png) + +如果运气不错,你可能在第一次尝试时就能获得一个可以正常交互的前端页面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image92.png) + +不过,由于大模型本身具有一定随机性,有时你可能在单轮对话中一切顺利,但在多轮对话时出现异常。因此,建议你进行多轮对话测试,确保程序在多轮交互场景下也能稳定运行。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image93.png) + +到这里,你已经学会了如何构建一个简单的 Dify 知识库 Agent,并使用 Trae 替代 [z.ai](http://z.ai) 来搭建一个交互式前端。从现在开始,Trae 将成为我们构建各种原型时的主要开发工具,逐步取代 [z.ai](http://z.ai)。你可以尝试用 Trae 重新实现之前的贪吃蛇游戏,看看会有什么不同的体验。加油! + +# 3. 更多业务工作流参考 + +你可以在搜索引擎上使用类似关键词搜索 `Dify workflow 参考`,或者直接在 Github 中找到 Dify 工作流分享仓库进行参考工作流的查找(质量参差不齐,你需要查看多个不同仓库学习)。当然,所谓的工作流只不过是业务上 SOP 的映射,你可以思考有哪些日常工作中的流程或者学习中的流程是重复可固化的,只需要把它变成工作流固定即可。 + +以下是一些大模型生成的工作流设计的参考(实际上的实现方案也比较类似,一般来说人类设计的工作流不会有大模型设计的优美,除非是高手设置的工作流),如果你觉得哪些点子有意思,可以将它发给大模型进一步细化,让大模型帮你给出更具体的 Dify 工作流节点设定,以及内部的细节结果。 + +## 3.1 社媒平台工作流 + +1. 跨平台内容一键分发工作流(复杂) + 1. 思路:以一篇核心稿件为“原料”,自动加工成适配多个平台的“成品”。 + 2. 实现:`Start` 输入文章 -> `LLM` 润色 -> 并行多个 `LLM` 节点(每个节点Prompt扮演特定平台专家,如“小红书爆款文案专家”、“知乎专业答主”)-> `Iterator` 节点循环处理不同平台格式要求 -> `Variable Aggregator` 汇总 -> `Answer` 输出所有版本。复杂度在于并行处理和循环迭代。 +2. 热点话题选题与初稿生成器(中等) + 1. 思路:自动捕捉网络热点,快速生成选题和内容草稿。 + 2. 实现:`Start` 输入关键词 -> `Tool` 节点调用搜索引擎API抓取热点 -> `LLM` 摘要提炼出3-5个话题 -> `LLM` 生成文章大纲或初稿。复杂度在于外部工具集成与信息筛选。 +3. 评论区智能分类与回复助手(复杂) + 1. 思路:自动分析评论情感与意图,生成分类回复建议。 + 2. 实现:`HTTP Request` 节点接入社媒API获取评论 -> `Question Classifier` 或 `LLM` 节点进行多标签分类(积极、疑问、投诉、广告等)-> `Condition` 判断节点路由至不同回复生成链 -> 并行 `LLM` 节点生成个性化回复草稿 -> `Answer` 输出。复杂度在于条件分支和实时API调用。 +4. 短视频脚本与分镜自动生成器(复杂) + 1. 思路:根据一个热门话题或产品描述,自动生成短视频脚本、分镜描述和推荐标签。 + 2. 实现:`Start` 输入主题 -> `LLM` 生成创意脚本 -> 第二个 `LLM` 节点将脚本拆解为场景序列(画面描述、台词、时长)-> `Tool` 节点调用文本转语音服务生成语音样本 -> `Variable Aggregator` 整合所有元素 -> `Answer` 输出结构化脚本文件。复杂度在于多步骤序列化和外部服务集成。 +5. 直播互动问答实时摘要助手(中等) + 1. 思路:实时处理直播间的文字评论,提炼核心问题和观众反馈。 + 2. 实现:`HTTP Request` 节点流式获取直播评论 -> `Iterator` 节点以时间窗口为单位处理批数据 -> `LLM` 节点实时总结每段时间内的热点问题与情绪倾向 -> `Answer` 或 `Webhook` 节点输出摘要给主播。复杂度在于实时流数据处理和循环窗口。 + +## 3.2 职场工作流 + +1. 智能会议纪要与任务自动派发系统(复杂) + 1. 思路:从会议录音文本中提取纪要,并自动创建任务。 + 2. 实现:`Start` 输入会议文本 -> `LLM` 总结议题与结论 -> `Parameter Extractor` 节点精准抽取Action Items(任务、负责人、DDL)-> 一个 `LLM` 整合成纪要邮件 -> 并行 `HTTP Request` 节点调用Jira/Trello/飞书API创建任务。复杂度在于信息抽取与多系统联动。 +2. 简历批量筛选与初步评估助手(中等) + 1. 思路:自动解析简历,进行匹配度评估并生成面试问题。 + 2. 实现:`Start` 上传简历文件与JD -> `Document Extractor` 节点解析简历文本 -> `LLM` 扮演HR进行匹配度评估 -> 对高匹配者,另一个 `LLM` 生成深度面试问题。复杂度在于文档解析与多条件评估。 +3. 多语言邮件一键翻译与草稿回复(简单) + 1. 思路:自动翻译邮件并起草回复。 + 2. 实现:`Start` 输入邮件 -> `LLM` 判断语种并翻译 -> `LLM` 构思回复要点 -> `LLM` 翻译回原始语言并润色。主要依赖于LLM的序列调用。 +4. 周报/月报数据自动汇总与洞察生成(复杂) + 1. 思路:连接多个数据源,自动生成结构化工作报告。 + 2. 实现:多个 `HTTP Request`/`Tool` 节点并行调用业务系统API(如CRM、Git、项目管理工具)获取原始数据 -> `Code` 节点或 `LLM` 进行数据清洗与基础计算 -> `LLM` 分析趋势、亮点与风险,生成叙述性报告 -> `Answer` 输出图文并茂的文档。复杂度在于多数据源聚合、数据处理与智能分析结合。 +5. 合同/文档智能审查与要点提炼(中等) + 1. 思路:快速审查法律或商务文档,提示风险并提炼核心条款。 + 2. 实现:`Start` 上传合同PDF -> `Document Extractor` 提取文本 -> `LLM` 节点(设定为法律专家角色)审查责任条款、支付条件、违约条款等 -> `Parameter Extractor` 节点抽取出关键日期、金额、义务方等结构化数据 -> `Answer` 输出风险提示和要点表格。复杂度在于长文档处理与结构化信息抽取。 + +## 3.3 学习生活工作流 + +1. 学术论文深度解析与笔记生成器(复杂) + 1. 思路:上传论文PDF,自动生成结构化笔记。 + 2. 实现:`Start` 上传PDF -> `Document Extractor` 提取全文 -> 并行多个 `LLM` 节点分工总结摘要、方法、发现、参考文献 -> `Variable Aggregator` 汇总 -> `Answer` 输出Markdown笔记。复杂度在于并行处理长文本的不同部分。 + +2. 个性化旅行计划定制师(中等) + 1. 思路:根据用户偏好,自动规划详尽行程。 + 2. 实现:`Start` 输入需求(目的地、天数、预算、兴趣)-> `Tool` 节点调用搜索引擎或地图API获取地点信息 -> `LLM` 整合信息,设计每日行程(含时间、活动、预算估算)。复杂度在于外部信息获取与结构化规划。 + +3. 外语学习互动陪练伙伴(简单) + 1. 思路:创建可角色扮演和语法纠错的对话机器人。 + 2. 实现:系统设定AI角色 -> `Start` 接收用户语句 -> `LLM` 执行两项任务:角色回复 + 语法纠错与解释 -> `Answer` 输出。核心是LLM的多任务指令。 + +4. 个人知识库问答与链接推荐系统(复杂) + 1. 思路:基于你收藏的文档、笔记、网页链接,构建一个可问答并能推荐相关旧知识的智能系统。 + 2. 实现:离线处理:使用 `Document Extractor` 和 `Embedding` 工具将个人知识库切片并向量化存储。在线工作流:`Start` 输入问题 -> `Retrieval` 节点从向量库中查找最相关的知识片段 -> `LLM` 基于检索到的上下文生成答案 -> 同时,另一个分支使用检索到的内容作为输入,通过 `LLM` 生成“相关旧知识”推荐列表 -> `Answer` 合并输出答案与推荐。复杂度在于检索增强生成(RAG)流程的构建。 + +5. 健身/饮食计划追踪与调整顾问(中等) + 1. 思路:根据用户输入的每日饮食和训练日志,提供营养分析与训练建议。 + 2. 实现:`Start` 输入文本日志(如“午餐:鸡胸肉150g,米饭一碗,蔬菜若干;训练:深蹲5组”)-> `Parameter Extractor` 节点尝试结构化输入数据 -> `LLM` 扮演健身教练,分析营养摄入是否均衡、训练容量是否合适 -> 对比长期目标,给出微调建议(如“蛋白质摄入充足,建议增加蔬菜种类”)。复杂度在于从非结构化日志中提取结构化信息并提供个性化反馈。 + +# 6. 工作流平台的局限性 + +工作流平台(或称低代码平台)并非万能解决方案。它虽然对业务人员友好,降低了直接编码的门槛,但从另一个角度看,“低代码”往往也是一种“高代码”——用户仍需理解平台的概念、规则与操作逻辑,这本身构成了一种新的学习成本。 + +也许你想问,很多简单的工作流其实就是大模型函数包装后的前后调用,前面函数的输出作为后者函数的输入,本质上几行代码就能够解决,为什么需要那么复杂的多重包装工作流?反而给 API 调用造成了麻烦。 + +你说得是对的。在当前 vibe coding 的快速发展下,借助 AI 代码生成能力,直接阅读甚至生成代码有时可能更加高效。理想情况下,我们希望能用自然语言直接操作应用逻辑,这才是一个现代的软件平台。但目前的工作流平台尚未实现这一点,因此它在用户意图与最终实现之间天然存在一个“中间层”。掌握这个中间层,正是一种需要投入时间学习的成本。理想上,之后的工作流平台也要支持全 AI 自动对话操作,我们可以让 AI 真正操作工作流搭建以及入参的每一个细节环节。 + +尽管如此,熟练使用这类平台正逐渐成为一项基础技能,如同微软的办公软件一样,在业务中非常普遍且实用,值得掌握。 + +在后续的进阶课程中,我们将介绍如何通过代码级别的工作流与 RAG 开发平台进行构建。届时,你可以亲身体验不同实现方式在复杂度与灵活性上的区别。(值得注意的是,一些简单的对话应用或嵌套逻辑,用工作流实现可能并不困难。) + +# 📚 课后作业 + +## 掌握 Dify 基本操作 + +为了测试你掌握了 Dify 的常见基础使用工具,你需要完成一个基础作业和两个 “小挑战”,确保你已入门常见的操作。你需要将附带的两个 DSL 文件导入 Dify 工作流,并成功完成对应工作流的挑战(遇到不懂的地方截图询问大模型,或自己探索其中的每个参数的用法,最后实现目标)。: + +1. 参考意图分类工作流的方法,让大模型给你建议完全换一套场景进行应用,但是一定要用到意图分类工作流,最后提交运行的工作流截图、场景说明、结果。 +2. Log in workflow 工作流解密挑战 + +在这个解密挑战中,你需要完成以下挑战,让工作流实现下列功能: + +- 找出正确的密码! +- 将密码修改为 0925 +- 当密码不正确时,提供第二次尝试机会(不提供第三次) +- 当用户提及要再次登录时,为用户提供重新输入密码的机会 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image94.png) + +参考输入输出: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image95.png) + +3. Love loop workflow 工作流解密挑战 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image96.png) + +在这个解密挑战中,你需要修复当前工作流的问题,让工作流最后的输出类似如下显示: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image97.png) + +如果你遇到无法解决的问题,请截图询问大模型,或查阅官方文档得到结果:[https://docs.dify.ai/en/use-dify/getting-started/quick-start](https://docs.dify.ai/en/use-dify/getting-started/quick-start) + +## 实现 Dify API 调用 + +为了测试你真正掌握了 Dify 的 API 调用知识,你需要完成以下任务: + +1. 部署 Dify 并创建一个简单的知识库(选取你喜欢的资料)。 +2. 使用 Trae IDE 构建一个对话前端,与 Dify 知识库进行 API 交互。 +3. 测试多轮对话的效果,确保程序正常运行。 + +你需要提交最终运行截图和知识库的处理过程截图。 + +## 试用第三方工作流 / 构建一个自己的业务工作流 + +请你在 Github、微信公众号、或者 Reddit、推特上等所有地方找到你想尝试的别人的 Dify 工作流,下载导入后成功运行;或者你可以根据上文中提到的业务工作流参考,根据现实中的具体需求创建一个自己的业务工作流进行运行。 + +最后你需要提交运行成功的截图,并说明这个工作流的作用。 + +# [Bug] HTTP 请求错误问题的解决方法 + +如果你遇到了如下图所示的问题,才需要参考本节方案进行解决,否则可以不理会当前部分。 + +有时候可能你会把 Dify 部署在自己的服务器,但是服务器的对外地址通常都是 http 而不是 https 的,但当我们请求一个只支持 HTTP 的服务时,你可能会看到类似这样的提示(启用 F12 浏览器调试信息模式,查看有问题的点): + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image98.png) + +出现这个问题的原因,是因为我们默认把 Dify 部署在一台只支持 HTTP 而不支持 HTTPS 的服务器上。 HTTPS(HyperText Transfer Protocol Secure)是在 HTTP(超文本传输协议)的基础上增加了 SSL/TLS 加密层,可以简单理解为“更安全版的 HTTP”。 + +如果要让服务支持 HTTPS,一般可以: + +- 使用其他程序转发请求(例如在有证书的 nginx 上做反向代理),或者 +- 绑定域名后为该域名申请证书。 + +但这些操作都比较复杂,在这里我们使用 Zeabur 作为网络转发网关来解决问题。 + +Zeabur 的网页默认是通过 HTTPS 访问的,因此我们只需要把原来请求的域名转发到 Zeabur 提供的域名,就可以修复这个问题。 + +- 原始地址:`http://{DIFY_API_URL}/v1/chat-messages` +- 现在地址:`https://{DIFY_NEW_API_URL}.zeabur.app/v1/chat-messages` + +你只需要简单地把 URL 中的域名部分(公网 IP 或域名)替换为已经在 Zeabur 上部署好的域名即可,我们已经提前在服务里配置好了转发功能。 + +如果你感兴趣,也可以自己在 Zeabur 上部署一个转发服务。在 Zeabur 中创建服务时,选择 Python,然后填入下面的 Python 代码,部署后即可得到一个 https 的地址,https 即可正常使用。 + +部署完成后,在网络设置中把程序监听端口设置为本地 8080,并对外暴露该端口。 + +注意:请将 `{DIFY_API_URL}` 替换为实际的 Dify API 地址。 + +```python +from flask import Flask, request, Response +import requests + +app = Flask(__name__) + +TARGET_BASE_URL = "{DIFY_API_URL}" +LISTEN_PORT = 8080 + +@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +@app.route('/', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +def proxy_request(path): + target_url = f"{TARGET_BASE_URL}/{path}" + if request.query_string: + target_url += f"?{request.query_string.decode('utf-8')}" + + headers = {key: value for key, value in request.headers if key.lower() not in ['host', 'connection', 'content-length', 'accept-encoding']} + + try: + resp = requests.request( + method=request.method, + url=target_url, + headers=headers, + data=request.get_data(), + cookies=request.cookies, + allow_redirects=False, + timeout=30 + ) + + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + response_headers = [(name, value) for name, value in resp.raw.headers.items() if name.lower() not in excluded_headers] + + return Response(resp.content, resp.status_code, response_headers) + + except requests.exceptions.RequestException as e: + print(f"Error forwarding request to {target_url}: {e}") + return Response(f"Proxy Error: Could not reach target server or invalid response: {e}", status=502) + except Exception as e: + print(f"An unexpected error occurred: {e}") + return Response(f"Internal Proxy Error: {e}", status=500) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=LISTEN_PORT, debug=True) +``` diff --git a/docs/ko-kr/stage-2/assignments/copywriting-platform-supabase/index.md b/docs/ko-kr/stage-2/assignments/copywriting-platform-supabase/index.md new file mode 100644 index 0000000..094f250 --- /dev/null +++ b/docs/ko-kr/stage-2/assignments/copywriting-platform-supabase/index.md @@ -0,0 +1,346 @@ +# AI 마케팅 카피 SaaS 개발 실전 + +## 개요 + +본 실전 프로젝트는 실제 PRD를 바탕으로, 인디 개발자와 콘텐츠 팀을 위한 AI 마케팅 카피 SaaS 제품을 처음부터 완성하는 것을 요구합니다. Supabase를 백엔드 서비스로, Stripe를 결제 시스템으로 사용하여, 요구사항 분석부터 배포까지의 전 과정을 완료합니다. + +이것은 Stage 2의 종합 실전环节입니다. 앞선 여러 장에서 프론트엔드 페이지 구축, 백엔드 인터페이스 개발, 데이터베이스 조작, 결제 연동 등 개별 기술을 각각 배웠습니다 — 이 프로젝트는 이를 모두 연결하여 실행 가능한 제품 프로토타입을 납품하는 것을 요구합니다. + +## 사전 지식 + +본 프로젝트를 시작하기 전에 다음 내용을 이미 숙지해야 합니다: + +- 프론트엔드 페이지 디자인 및 컴포넌트 라이브러리 사용 ([UI 디자인](../../frontend/ui-design/), [현대적 컴포넌트 라이브러리](../../frontend/modern-component-library/)) +- 백엔드 인터페이스 설계 및 개발 ([인터페이스 코드 작성](../../backend/ai-interface-code/)) +- 데이터베이스 기초와 Supabase ([데이터베이스에서 Supabase까지](../../backend/database-supabase/)) +- 결제 연동 ([Stripe 결제 시스템](../../backend/stripe-payment/)) +- Git 워크플로우와 배포 ([Git과 GitHub](../../backend/git-workflow/), [웹 애플리케이션 배포](../../backend/zeabur-deployment/)) + +## 학습 목표 + +본 실전을 완료하면 다음이 가능합니다: + +1. 실제 PRD를 읽고 이해하여, 개발 과제 목록을 추출 +2. AI를 활용하여 단계별로 프론트엔드 페이지와 백엔드 인터페이스 생성 +3. Supabase를 사용하여 사용자 인증, 데이터베이스 조작 구현 +4. Stripe를 연동하여 유료 구독 기능 구현 +5. 관리 백엔드를 구축하고 엔드투엔드 통합 디버깅 완료 + +## 프로젝트 소개 + +구축할 제품은 AI 마케팅 카피 SaaS로, 세 가지 하위 시스템을 포함합니다: + +| 하위 시스템 | 담당 | +|--------|------| +| **공식 웹사이트 프론트엔드** | 제품 소개, 가격, FAQ, 가입 전환 | +| **사용자 워크벤치** | 제품 정보 입력, 카피 생성, 기록 조회, 플랜 업그레이드 | +| **백엔드 관리 콘솔** | 사용자 관리, 생성 기록, 결제 데이터, 운영 개요 | + +백엔드는 Supabase를 사용하여 데이터베이스와 인증 기능을 제공하고, Stripe로 결제를 처리하며, AI 모델로 마케팅 카피를 생성합니다. + +::: tip PRD 입구 +본 프로젝트의 요구사항 문서는 GitHub에 있습니다: [PRD 보기](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/copywriting-platform-supabase/PRD.md) +::: + +
+ + + +
+ +## 제1부: 요구사항 분석 + +### 1.1 PRD 읽기 + +PRD 문서를 열고 다음 질문에 중점적으로 답하세요: + +- 시스템에 몇 개의 진입점이 있나요? 각각 어떤 페이지를 포함하나요? +- 각 페이지의 핵심 기능은 무엇인가요? +- 백엔드에는 어떤 모듈과 데이터 테이블이 포함되나요? +- 플랜 가격, 결제 프로세스, 무료 한도는 어떻게 설계되었나요? +- MVP 범위는 무엇인가요? 첫 번째 버전에서 무엇을 하고, 무엇을 하지 않나요? + +::: warning +위 질문에 명확한 답이 없다면, 코드 작성을 시작하지 마세요. 요구사항 이해가 불명확한 것은 재작업의 가장 흔한 원인입니다. +::: + +### 1.2 시스템 아키텍처 확인 + +PRD를 바탕으로 시스템의 전체 아키텍처를 정리합니다: + +```mermaid +flowchart TD + prd["PRD"] --> web["공식 웹사이트 프론트엔드"] + prd --> app["사용자 워크벤치"] + prd --> admin["백엔드 관리 콘솔"] + app --> auth["인증"] + app --> gen["카피 생성 작업"] + gen --> db["데이터베이스"] + billing["결제 및 플랜"] --> db + admin --> analytics["사용자 / 생성 / 결제 대시보드"] +``` + +## 제2부: 프로젝트 골격 구축 + +### 2.1 프론트엔드 페이지 생성 + +AI를 사용하여 먼저 모든 페이지의 기본 구조와 가짜 데이터를 생성합니다. + +프롬프트 참고: + +```text +현재 PRD를 기반으로 AI 마케팅 카피 SaaS의 프론트엔드 골격을 생성해 줘. + +요구사항: +1. 세 개의 진입점으로 분리: www, app, admin +2. 공식 웹사이트에는: 홈페이지, 가격, FAQ +3. app에는: 로그인, 회원가입, 생성 워크벤치, 기록, 플랜 페이지 +4. admin에는: 백엔드 홈페이지, 사용자 관리, 생성 기록, 결제 주문 +5. 먼저 페이지 구조와 가짜 데이터만 생성하고, 실제 인터페이스는 연결하지 마 +6. 수업 데모가 아닌 현대적인 SaaS 스타일로 만들어 줘 +``` + +### 2.2 핵심 페이지 완성 + +골격이 완성되면, 카피 생성 워크벤치(Dashboard) 페이지를 중점적으로 완성합니다: + +```text +/dashboard 페이지를 계속 완성해 줘. + +이것은 AI 마케팅 카피 워크벤치입니다. + +왼쪽 폼 필드: +- 제품명 +- 한 줄 소개 +- 타겟 사용자 +- 3개의 판매 포인트 +- 배포 채널 (공식 웹사이트, WeChat 모멘트, 샤오홍슈, Douyin, 이메일) + +오른쪽 결과 영역 예비: +- 메인 제목 +- 부제목 +- CTA +- 3버전의 짧은 카피 +- 긴 카피 + +먼저 mock 데이터로 상호작용을 완성해 줘. + +요구사항: +- "카피 생성" 클릭 후 loading 상태 표시 +- 결과 영역에 빈 상태 디자인 +- 반응형 레이아웃, 넓은 화면과 좁은 화면 모두 정상 표시 +``` + +### 2.3 페이지 구조 검증 + +항목별로 확인: + +- [ ] 세 진입점의 라우팅이 독립적인지 +- [ ] 페이지 수가 PRD와 일치하는지 +- [ ] Dashboard의 폼과 결과 영역 레이아웃이 합리적인지 +- [ ] 가짜 데이터가 기본 UI 상태를 보여주는지 + +### 막혔나요? + +프론트엔드 구축 단계에서 막혔다면, 다음 장을 복습하세요: + +- [UI 디자인](../../frontend/ui-design/) +- [UI 디자인 가이드라인을 참고하여 페이지와 버튼 디자인하기](../../frontend/multi-product-ui/) +- [LLM과 Skills로 인터페이스를 아름답게 만들기](../../frontend/llm-skills-beautiful/) +- [디자인 프로토타입에서 프로젝트 코드까지](../../frontend/design-to-code/) +- [현대적 컴포넌트 라이브러리로 인터페이스 업데이트하기](../../frontend/modern-component-library/) + +## 제3부: 백엔드 연동 + +### 3.1 Supabase 로그인 연동 + +```text +나를 완전 초보자로 생각하고, 단계별로 Supabase 로그인 연동을 안내해 줘. + +다음을 완료해 줘: +1. 프로젝트에 Supabase 연동 +2. 회원가입, 로그인, 로그아웃 기능 구현 +3. 로그인 성공 후 /dashboard로 이동 +4. 미로그인 사용자가 /dashboard, /billing, /admin에 접근하면 자동으로 /login으로 이동 +5. profiles 테이블 생성 +6. 사용자 회원가입 성공 후 profiles 테이블에 자동으로 레코드 생성 +7. profiles 테이블은 email, role, plan 필드 포함 + +구현 요구사항: +- 각 단계에서 어떤 파일을 수정하는지 설명 +- 비밀 키를 하드코딩하지 마 +- Supabase 백엔드에서 수동으로 조작해야 하는 부분은 명확히 표시 +- 완료 후 회원가입과 로그인을 확인하는 방법 설명 +``` + +### 3.2 생성 인터페이스 및 데이터베이스 연동 + +```text +나를 완전 초보자로 생각하고, 웹사이트의 핵심 기능인 마케팅 카피 생성 및 저장을 완료해 줘. + +목표 효과: +1. 사용자가 /dashboard에서 폼을 작성하고 "카피 생성"을 클릭 +2. 백엔드에서 수신: 제품명, 소개, 타겟 사용자, 판매 포인트, 배포 채널 +3. 백엔드에서 모델을 호출하여 결과 생성 +4. 페이지에 생성 결과 표시 +5. 입력과 출력 모두 데이터베이스에 저장 +6. 사용자가 다음에 접속하면 기록을 볼 수 있음 + +완료해야 할 사항: +- 생성 인터페이스 /api/generate 생성 +- generations 테이블 생성 +- 입력 및 출력 필드 설계 +- Dashboard 페이지에서 현재 사용자의 기록 읽기 + +사용자 경험: +- 버튼 loading 상태 +- 생성 실패 시 오류 메시지 +- 기록이 없을 때 빈 상태 + +완료 후 설명: +- 프론트엔드 페이지 파일 위치 +- 백엔드 인터페이스 파일 위치 +- 데이터가 데이터베이스에 기록되는 로직 위치 +- 전체 생성 프로세스를 테스트하는 방법 +``` + +### 3.3 Stripe 유료 결제 연동 + +```text +나를 완전 초보자로 생각하고, LaunchKit에 가장 기본적으로 사용 가능한 Stripe 결제를 추가해 줘. + +복잡한 시스템은 필요 없고, 가장 기본적인 결제 프로세스만 먼저 실행해. + +완료해야 할 사항: +1. /billing 페이지에 free와 pro 두 가지 플랜 표시 +2. 사용자가 업그레이드를 클릭하면 Stripe Checkout으로 이동 +3. 결제 성공 후 웹사이트로 돌아옴 +4. 결제 결과를 subscriptions 테이블에 저장 +5. profile.plan 필드 동기화 업데이트 +6. free 사용자는 매일 3회 생성 제한, pro 사용자는 무제한 + +구현 원칙: +- 먼저 메인 프로세스를 실행하고, 복잡한 경계 조건은 나중에 고려 +- Stripe 백엔드에서 구성해야 하는 부분은 명확히 작성 +- 완료 후 전체 결제 프로세스를 테스트하는 방법 설명 +``` + +### 3.4 관리 백엔드 구축 + +```text +나를 완전 초보자로 생각하고, 간결하고 사용 가능한 관리 백엔드를 만들어 줘. + +관리자만 접근 가능. + +완료해야 할 사항: +1. role = admin인 사용자만 /admin에 접근 가능 +2. 백엔드에 3개의 Tab 포함: 사용자 목록, 생성 기록, 구독 상태 +3. 사용자 목록 표시: email, plan, 생성 시간 +4. 생성 기록 표시: 사용자, 제품명, 채널, 생성 시간 +5. 구독 상태 표시: 사용자, 플랜, 결제 상태 + +요구사항: +- 인터페이스는 간결하고 명확하게 +- 기존 컴포넌트 라이브러리의 테이블, Tab, Badge 사용 +- 완료 후 계정을 admin으로 설정하는 방법 설명 +``` + +### 막혔나요? + +백엔드 개발 단계에서 막혔다면, 다음 장을 복습하세요: + +- [데이터베이스에서 Supabase까지](../../backend/database-supabase/) +- [대형 언어 모델 활용 인터페이스 코드 및 문서 작성](../../backend/ai-interface-code/) +- [Stripe 등 결제 시스템 통합 방법](../../backend/stripe-payment/) + +## 제4부: 통합 디버깅 및 출시 + +### 4.1 엔드투엔드 테스트 + +최소한 다음 시나리오를 확인하세요: + +- 회원가입 -> 로그인 -> 카피 생성 -> 기록 조회 -> 플랜 업그레이드 +- 관리자 로그인 -> 사용자 데이터 조회 -> 생성 기록 조회 -> 결제 상태 조회 + +배포 전 확인: + +```text +나를 완전 초보자로 생각하고, 프로젝트가 배포 가능한지 확인해 줘. + +확인 포인트: +- 환경 변수가 완전한지 +- 로그인 콜백 주소가 올바른지 +- Stripe 결제 콜백 주소가 올바른지 +- 페이지에 loading, 빈 상태, 오류 메시지가 누락되지 않았는지 +- README에 시작 설명과 배포 설명이 포함되어 있는지 + +다음을 수행해 줘: +1. 우선순위별로 수정 필요 사항 나열 +2. 먼저 수정해야 할 항목 표시 +3. 수정 후 배포 단계 설명 +``` + +### 4.2 배포 + +프로젝트를 공개 네트워크 환경에 배포합니다. 배포 튜토리얼 참고: [Git과 GitHub 워크플로우](../../backend/git-workflow/), [웹 애플리케이션 배포 방법](../../backend/zeabur-deployment/). + +## 산출물 + +본 프로젝트를 완료한 후, 다음 내용을 제출해야 합니다: + +- [ ] 접근 가능한 온라인 데모 링크 +- [ ] 소스 코드 저장소 링크 (README 포함) +- [ ] PRD 문서 +- [ ] 핵심 페이지 스크린샷 (홈페이지, Dashboard, Billing, Admin) +- [ ] 60초 데모 영상 (회원가입 -> 생성 -> 결제 -> 백엔드 포함) + +README에는 최소한 다음이 포함되어야 합니다: 프로젝트 소개, 핵심 페이지 설명, 기술 스택, 로컬 시작 단계, 환경 변수 목록. + +## 평가 기준 + +| 차원 | 기본 요구사항 | 심화 요구사항 | +|------|---------|---------| +| 제품 완성도 | 홈페이지, 로그인, Dashboard, Billing, Admin 모두 접근 가능 | 홈페이지 카피와 비주얼 스타일이 실제 SaaS처럼 느껴짐 | +| 비즈니스 폐루프 | 회원가입 -> 로그인 -> 생성 -> 기록 조회가 실행 가능 | 무료/Pro 권한 차이가 명확하게 보임 | +| 데이터 정확성 | 생성 결과와 결제 상태가 데이터베이스에 기록됨 | 명확한 오류 메시지, 빈 상태, loading이 있음 | +| 권한 및 보안 | 미로그인 시 보호된 페이지에 접근 불가, 일반 사용자는 Admin에 접근 불가 | 기본적인 입력 검증과 서버 측 인증이 있음 | +| 엔지니어링 납품 | 프로젝트를 로컬에서 시작할 수 있고, 공개 네트워크에 배포도 가능 | README가 명확하고, 데모 영상 구조가 완전함 | + +::: tip +과제가 너무 크게 느껴진다면, 한 가지 원칙을 기억하세요: **먼저 "실행 가능하게" 만들고, 그 다음 "아름답게" 만드세요.** +::: + +## 제출 전 확인 + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## 참고 자료 + +- [UI 디자인](../../frontend/ui-design/) +- [UI 디자인 가이드라인을 참고하여 페이지와 버튼 디자인하기](../../frontend/multi-product-ui/) +- [LLM과 Skills로 인터페이스를 아름답게 만들기](../../frontend/llm-skills-beautiful/) +- [디자인 프로토타입에서 프로젝트 코드까지](../../frontend/design-to-code/) +- [현대적 컴포넌트 라이브러리로 인터페이스 업데이트하기](../../frontend/modern-component-library/) +- [데이터베이스에서 Supabase까지](../../backend/database-supabase/) +- [대형 언어 모델 활용 인터페이스 코드 및 문서 작성](../../backend/ai-interface-code/) +- [Git과 GitHub 워크플로우](../../backend/git-workflow/) +- [웹 애플리케이션 배포 방법](../../backend/zeabur-deployment/) +- [Stripe 등 결제 시스템 통합 방법](../../backend/stripe-payment/) diff --git a/docs/ko-kr/stage-2/assignments/custom-dify-agent-platform/index.md b/docs/ko-kr/stage-2/assignments/custom-dify-agent-platform/index.md new file mode 100644 index 0000000..00d32b0 --- /dev/null +++ b/docs/ko-kr/stage-2/assignments/custom-dify-agent-platform/index.md @@ -0,0 +1,210 @@ +# 类 Dify 智能体平台开发实战 + +## 概述 + +本实战项目要求你围绕一份真实的 PRD,从零完成一个模仿 Dify 核心体验的智能体平台。你将构建用户控制台、管理后台和平台后端,实现智能体管理、对话、日志和知识库等核心功能。 + +这是 Stage 2 的综合实战环节。与前面的单页面或单功能项目不同,这个项目要求你构建一个有"平台感"的 AI 产品——包含多角色、多模块、数据持久化和模型调用链路。 + +## 前置知识 + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## 学习目标 + +完成本实战后,你将能够: + +1. 阅读并理解一份真实的 PRD,从中提取开发任务清单 +2. 设计智能体平台的页面架构和数据模型 +3. 实现智能体创建、对话、日志记录的完整链路 +4. 使用 AI 辅助完成平台型产品开发 +5. 完成端到端联调,交付一个可演示的 AI 平台原型 + +## 项目简介 + +你要构建的产品是一个类 Dify 智能体平台,包含两个子系统: + +| 子系统 | 职责 | +|--------|------| +| **用户控制台** | 创建智能体、配置 Prompt、发起对话、查看日志、管理知识库 | +| **管理后台** | 查看用户数据、平台资源使用情况、调用统计 | + +后端需要支持以下核心能力:智能体管理、会话管理、消息存储、模型调用、调用日志记录、知识库接入。 + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/ko-kr/stage-2/assignments/custom-dify-agent-platform/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 智能体、会话、日志、知识库哪些要进 MVP? +- 页面和路由清单是否拍板? +- 模型调用和日志记录的边界是什么? +- 多租户和复杂工作流是否先不做? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认系统架构 + +根据 PRD 梳理出系统的整体架构: + +```mermaid +flowchart TD + prd["PRD"] --> app["用户控制台"] + prd --> admin["管理后台"] + app --> auth["鉴权"] + app --> agent["智能体配置"] + app --> chat["会话对话"] + chat --> llm["模型调用"] + chat --> db["数据库"] + app --> kb["知识库接入"] + admin --> logs["调用日志与平台概览"] + logs --> db +``` + +## 第二部分:搭建项目骨架 + +### 2.1 生成前端页面 + +提示词参考: + +```text +请基于当前 PRD,帮我生成一个类 Dify 智能体平台的前端骨架。 + +要求: +1. 用户侧包括:登录、智能体列表、智能体配置、对话页、日志页、知识库页 +2. 后台侧包括:后台首页、用户概览、资源使用概览 +3. 先只生成页面结构和假数据,不接真实接口 +4. 风格要像现代 AI 平台 +``` + +### 2.2 验证页面结构 + +逐项检查: + +- [ ] 用户控制台和管理后台入口是否分开 +- [ ] 智能体列表、配置、对话、日志、知识库页面是否完整 +- [ ] 管理后台首页、用户概览页面是否可访问 +- [ ] 假数据展示了基本的 UI 状态 + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +在骨架的基础上,按以下顺序逐模块补充功能: + +1. **鉴权**:注册、登录、角色区分 +2. **智能体管理**:创建、编辑、删除、Prompt 配置 +3. **对话功能**:会话创建、消息收发、模型调用 +4. **日志记录**:耗时、token 用量、错误记录 +5. **知识库接入**(加分项):文档上传、检索、结果注入 +6. **管理后台**:用户数据、资源使用、调用统计 + +每完成一个模块,使用下表进行自检: + +| 检查项 | 验证方法 | +|--------|----------| +| 页面一致性 | 页面数量、功能是否符合 PRD | +| 接口闭环 | agents、chat、logs、knowledge 接口是否完整 | +| 权限隔离 | 用户是否只能管理自己的 agent 和会话 | +| 数据一致性 | messages、logs、documents 数据是否对得上 | +| 可演示性 | 是否能演示"创建 agent → 对话 → 查看日志"完整链路 | + +### 3.2 知识库接入(加分项) + +如果你想增加知识库能力,可以给每个智能体增加一个"知识库开关": + +- 开启后先检索知识片段,再和用户问题一起发送给模型 +- 关闭后按普通对话模式响应 + +第一版不必追求复杂 RAG,只要有"检索结果可见、调用链路可解释"即可。 + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +至少验证以下场景: + +- 注册 → 创建智能体 → 配置 Prompt → 发起对话 → 查看日志 +- 管理员登录 → 查看用户数据 → 查看调用统计 + +部署前检查: + +- [ ] 所有核心接口都做了登录校验 +- [ ] 智能体归属权限检查通过 +- [ ] 会话记录、日志记录真实落库 +- [ ] 模型 Key 使用环境变量,不硬编码 +- [ ] 错误提示可在前端看到,不只打控制台 + +### 4.2 部署 + +将项目部署到公网环境。部署教程参考:[Git 和 GitHub 工作流](../../backend/git-workflow/)、[如何部署 Web 应用](../../backend/zeabur-deployment/)。 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(智能体管理页、对话页、日志页、后台首页) +- [ ] 60 秒演示视频(覆盖创建智能体 → 对话 → 查看日志) + +README 至少包含:项目简介、架构说明、技术栈、本地启动步骤、环境变量清单、接口说明。 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| 平台完整度 | agents / chat / logs 三页可用 | 有清晰导航与统一设计语言 | +| 业务闭环 | 可创建智能体并真实对话 | 支持多智能体切换与历史会话 | +| 数据与追踪 | 消息与调用日志可查询 | 有 token / 耗时统计看板 | +| 权限安全 | 仅登录用户可访问核心接口 | 资源归属校验完善 | +| 工程交付 | 可部署、可演示、README 清晰 | 接入知识库并可解释检索结果 | + +## 提交前检查 + + + + +
    +
  • +
  • +
  • +
  • +
  • +
+
+ +## 参考资料 + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/ko-kr/stage-2/assignments/exam-management-express/index.md b/docs/ko-kr/stage-2/assignments/exam-management-express/index.md new file mode 100644 index 0000000..767b1f4 --- /dev/null +++ b/docs/ko-kr/stage-2/assignments/exam-management-express/index.md @@ -0,0 +1,306 @@ +# 온라인 시험 및 관리 시스템 개발 실전 + +## 개요 + +본 실전 프로젝트는 실제 PRD를 바탕으로, 온라인 시험 및 관리 시스템을 처음부터 완성하는 것을 요구합니다. 이 프로젝트의 특별한 점은 여러 역할(학생과 관리자)이 포함되어 있으며, 각 역할이 보는 페이지와 수행할 수 있는 조작이 다르다는 것입니다. Express를 사용하여 백엔드를 구축하고, 완전한 시험 비즈니스 체인을 구현합니다. + +이것은 Stage 2의 종합 실전环节입니다. 다중 역할 권한 시스템은 실제 업무에서 매우 흔하며, 이 패턴을 마스터하면 교육, SaaS, 백엔드 관리 등 다양한 비즈니스 시나리오에 대응할 수 있습니다. + +## 사전 지식 + +본 프로젝트를 시작하기 전에 다음 내용을 이미 숙지해야 합니다: + +- 프론트엔드 페이지 디자인 및 컴포넌트 라이브러리 사용 ([UI 디자인](../../frontend/ui-design/), [현대적 컴포넌트 라이브러리](../../frontend/modern-component-library/)) +- 백엔드 인터페이스 설계 및 개발 ([인터페이스 코드 작성](../../backend/ai-interface-code/)) +- 데이터베이스 기초와 Supabase ([데이터베이스에서 Supabase까지](../../backend/database-supabase/)) +- Git 워크플로우와 배포 ([Git과 GitHub](../../backend/git-workflow/), [웹 애플리케이션 배포](../../backend/zeabur-deployment/)) + +## 학습 목표 + +본 실전을 완료하면 다음이 가능합니다: + +1. 실제 PRD를 읽고 이해하여, 개발 과제 목록을 추출 +2. 다중 역할 시스템의 권한 제어와 페이지 라우팅 설계 +3. Express를 사용하여 완전한 백엔드 API 구현 +4. 시험, 제출, 자동 채점의 비즈니스 체인 구현 +5. 엔드투엔드 통합 디버깅을 완료하고, 시연 가능한 비즈니스 시스템 프로토타입 납품 + +## 프로젝트 소개 + +구축할 제품은 온라인 시험 및 관리 시스템으로, 세 가지 하위 시스템을 포함합니다: + +| 하위 시스템 | 담당 | +|--------|------| +| **공식 웹사이트 프론트엔드** | 플랫폼 소개, 로그인 입구 | +| **학생 페이지** | 시험 목록, 답안 작성, 제출, 성적 조회 | +| **관리 백엔드** | 문제 은행 관리, 시험 관리, 제출 기록, 성적 통계 | + +백엔드는 Express를 사용하며, 로그인 인증, 역할 권한, 시험 및 문제 은행 관리, 제출 프로세스와 자동 채점, 성적 및 통계 관리를 지원해야 합니다. + +::: tip PRD 입구 +본 프로젝트의 요구사항 문서는 GitHub에 있습니다: [PRD 보기](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/exam-management-express/PRD.md) +::: + +
+ + + +
+ +## 제1부: 요구사항 분석 + +### 1.1 PRD 읽기 + +PRD 문서를 열고 다음 질문에 중점적으로 답하세요: + +- 시스템에 몇 개의 역할이 있나요? 각각 무엇을 할 수 있나요? +- 페이지 목록이 완전한가요? 학생 페이지와 관리 페이지에 각각 어떤 페이지가 있나요? +- 어떤 문제 유형을 지원하나요? 각 문제 유형의 채점 로직은 무엇인가요? +- 시험의 완전한 프로세스는 무엇인가요? (발행 -> 시작 -> 답안 작성 -> 제출 -> 채점 -> 성적 조회) + +::: warning +위 질문에 명확한 답이 없다면, 코드 작성을 시작하지 마세요. 요구사항 이해가 불명확한 것은 재작업의 가장 흔한 원인입니다. +::: + +### 1.2 시스템 아키텍처 확인 + +PRD를 바탕으로 시스템의 전체 아키텍처를 정리합니다: + +```mermaid +flowchart TD + prd["PRD"] --> web["공식 웹사이트 프론트엔드"] + prd --> student["학생 페이지"] + prd --> admin["관리 백엔드"] + student --> auth["인증"] + student --> exam["시험 및 답안 작성"] + exam --> db["데이터베이스"] + admin --> question["문제 은행 관리"] + admin --> submission["제출 기록 및 성적 통계"] + question --> db + submission --> db +``` + +## 제2부: 프로젝트 골격 구축 + +### 2.1 프론트엔드 페이지 생성 + +프롬프트 참고: + +```text +현재 PRD를 기반으로 온라인 시험 및 관리 시스템의 프론트엔드 골격을 생성해 줘. + +기술 스택 요구사항: +- Next.js App Router +- TypeScript +- Tailwind CSS +- shadcn/ui + +페이지 목록: +1. 홈페이지 / +2. 로그인 페이지 /login +3. 학생 시험 목록 페이지 /student/exams +4. 학생 답안 작성 페이지 /student/exams/[id] +5. 학생 성적 페이지 /student/history +6. 관리 백엔드 홈페이지 /admin +7. 시험 관리 페이지 /admin/exams +8. 문제 은행 관리 페이지 /admin/questions +9. 제출 기록 페이지 /admin/submissions + +요구사항: +- 학생 페이지는 명확하고, 집중하기 쉬우며, 답안 작성이 편리해야 함 +- 관리 페이지는 사이드바 + 상단바 레이아웃 사용 +- 먼저 mock 데이터를 사용하고, 실제 인터페이스는 연결하지 마 +- 데스크톱과 모바일의 기본 사용 가능성에 주의 +``` + +### 2.2 학생 답안 작성 페이지 완성 + +답안 작성 페이지는 학생 페이지의 핵심 페이지이며, 중점적으로 완성합니다: + +```text +학생 답안 작성 페이지를 계속 완성해 줘. + +이것은 온라인 시험 시스템의 답안 작성 페이지로, 다음을 포함해야 함: +- 상단에 시험 제목, 카운트다운, 답안 작성 완료 문항 수 표시 +- 중간에 문제 내용과 선택지 표시 +- 단답형, 참/거짓, 서술형 세 가지 문제 유형 지원 +- 왼쪽이나 상단에 답안 카드가 있어, 각 문제의 답안 작성 여부 표시 +- 제출 전 확인 팝업 표시 + +먼저 mock 데이터로 상호작용을 구현하고, 실제 인터페이스는 연결하지 마. + +요구사항: +- 인터페이스는 간결하게, 백엔드 테이블 페이지처럼 보이지 않게 +- 카운트다운은 눈에 띄지만, 너무 큰 압박감을 주지 않게 +- 빈 상태와 loading 상태 포함 +``` + +### 2.3 관리자 백엔드 완성 + +관리자 백엔드 첫 번째 버전은 세 가지 핵심 영역에 집중합니다: + +- **시험 관리**: 시험 생성, 시간 설정, 발행 상태 +- **문제 은행 관리**: 문제 추가, 문제 편집, 문제 유형별 필터링 +- **제출 기록**: 학생 제출, 점수, 시간 확인 + +### 2.4 페이지 구조 검증 + +항목별로 확인: + +- [ ] 학생 페이지와 관리 페이지의 진입점이 분리되어 있는지 +- [ ] 로그인 페이지, 시험 목록, 답안 작성 페이지, 성적 페이지가 완전한지 +- [ ] 관리 페이지의 문제 은행, 시험 관리, 제출 기록 페이지에 접근 가능한지 +- [ ] 학생 페이지와 관리 페이지의 스타일이 명확하게 구분되는지 + +### 막혔나요? + +프론트엔드 구축 단계에서 막혔다면, 다음 장을 복습하세요: + +- [데이터베이스에서 Supabase까지](../../backend/database-supabase/) +- [애플리케이션 백엔드 인터페이스 설계 및 개발](../../backend/ai-interface-code/) +- [현대적 컴포넌트 라이브러리로 인터페이스 업데이트하기](../../frontend/modern-component-library/) + +## 제3부: 백엔드 개발 + +### 3.1 로그인 및 권한 제어 + +```text +나를 완전 초보자로 생각하고, 온라인 시험 시스템의 로그인과 권한 제어를 완료해 줘. + +백엔드는 Express를 사용. + +목표: +1. 학생과 관리자 모두 로그인 가능 +2. 로그인 후 사용자 역할 반환 +3. 학생은 /student/* 관련 인터페이스에만 접근 가능 +4. 관리자는 /admin/* 관련 인터페이스에만 접근 가능 +5. 미로그인 사용자가 보호된 페이지에 접근하면 /login으로 이동 + +구현 요구사항: +- 명확한 디렉토리 구조 제안 +- 미들웨어가 담당하는 역할을 명확히 설명 +- 환경 변수가 필요한 부분은 하드코딩하지 마 +- 완료 후 권한이 정상 작동하는지 확인하는 방법 설명 +``` + +### 3.2 시험 및 문제 은행 관리 인터페이스 + +다음 모듈별로 구현하는 것을 권장합니다: + +| 모듈 | 추천 인터페이스 | +|------|----------| +| 시험 관리 | `GET /api/exams`, `POST /api/admin/exams`, `PATCH /api/admin/exams/:id` | +| 문제 은행 관리 | `GET /api/admin/questions`, `POST /api/admin/questions` | +| 시험 시작 | `POST /api/submissions/start` | +| 시험지 제출 | `POST /api/submissions/:id/submit` | +| 성적 기록 | `GET /api/student/history`, `GET /api/admin/submissions` | + +프롬프트 참고: + +```text +온라인 시험 시스템의 Express API를 설계하고 구현해 줘. + +기능 범위: +- 관리자가 시험 생성 +- 관리자가 문제 은행 유지 관리 +- 학생이 발행된 시험 확인 +- 학생이 시험을 시작하고 submission 생성 +- 학생이 답안을 제출하면 객관식과 참/거짓 문제 자동 채점 +- 서술형은 먼저 검토 대기로 표시 +- 학생이 자신의 성적 기록 확인 +- 관리자가 모든 제출 기록 확인 + +요구사항: +- 인터페이스 명명이 명확해야 함 +- 통일된 JSON 구조 반환 +- 코드에서 controller, service, middleware, db 계층 구분 +- 각 인터페이스를 테스트하는 방법 설명 +``` + +### 3.3 채점 로직 + +채점 로직은 시험 시스템의 핵심 비즈니스 규칙입니다: + +- **객관식**: 사용자 답안이 정답과 일치하면 득점 +- **참/거짓**: 마찬가지로 자동 채점 가능 +- **서술형**: 첫 번째 버전에서는 답안만 저장하고, 점수는 비워두며, 상태를 `reviewed = false`로 설정 + +::: tip 보너스 항목 +AI 기능을 추가하고 싶다면, 관리자가 백엔드에서 "주제 + 난이도"를 입력하면 모델이 먼저 후보 문제를 생성하고, 이를 수동으로 검토하여 문제 은행에 추가할 수 있습니다. 하지만 이것은 보너스 항목이며 필수는 아닙니다. +::: + +## 제4부: 통합 디버깅 및 출시 + +### 4.1 엔드투엔드 테스트 + +최소한 다음 시나리오를 확인하세요: + +- 학생 로그인 -> 시험 목록 확인 -> 답안 작성 시작 -> 제출 -> 성적 확인 +- 관리자 로그인 -> 시험 생성 -> 문제 추가 -> 발행 -> 제출 기록 확인 + +### 4.2 배포 + +- 프론트엔드는 Vercel / Zeabur에 배포 +- Express API는 Zeabur / Railway / Render에 배포 +- 데이터베이스는 Supabase Postgres 또는 호스팅 PostgreSQL 사용 + +배포 전 확인: + +- [ ] 환경 변수가 완전한지 +- [ ] 프론트엔드와 백엔드 API 주소가 올바른지 +- [ ] 프로덕션 환경에서 로그인 상태가 정상인지 +- [ ] 관리자 계정으로 백엔드에 실제로 접근 가능한지 +- [ ] README에 시작, 배포, 테스트 설명이 포함되어 있는지 + +## 산출물 + +본 프로젝트를 완료한 후, 다음 내용을 제출해야 합니다: + +- [ ] 접근 가능한 온라인 데모 링크 +- [ ] 소스 코드 저장소 링크 (README 포함) +- [ ] PRD 문서 +- [ ] 핵심 페이지 스크린샷 (홈페이지, 학생 시험 목록, 답안 작성 페이지, 관리 백엔드) +- [ ] 60초 데모 영상 (학생 답안 작성 프로세스와 관리자 관리 프로세스 포함) + +README에는 최소한 다음이 포함되어야 합니다: 프로젝트 소개, 핵심 페이지 설명, 기술 스택, 로컬 시작 단계, 환경 변수 목록. + +## 평가 기준 + +| 차원 | 기본 요구사항 | 심화 요구사항 | +|------|---------|---------| +| 페이지 완성도 | 학생 페이지와 관리 페이지의 주요 페이지 모두 접근 가능 | 페이지 스타일이 통일되고, 모바일에서 기본적으로 사용 가능 | +| 비즈니스 폐루프 | 학생이 로그인, 시험 참여, 제출, 성적 조회 가능 | 관리자가 시험을 완전히 생성하고 발행 가능 | +| 데이터 정확성 | 답안 제출 후 데이터베이스에 기록되고, 객관식 문제가 자동 채점됨 | 서술형 문제에서 수동 검토 또는 AI 보조 지원 | +| 권한 제어 | 학생과 관리자의 접근 경계가 명확함 | 서버 측 인터페이스에도 역할 검증이 있음 | +| 엔지니어링 납품 | 프로젝트가 실행 가능하고, 배포 가능하며, README가 명확함 | 데모 영상과 테스트 설명이 있음 | + +## 제출 전 확인 + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## 참고 자료 + +- [UI 디자인](../../frontend/ui-design/) +- [현대적 컴포넌트 라이브러리로 인터페이스 업데이트하기](../../frontend/modern-component-library/) +- [데이터베이스에서 Supabase까지](../../backend/database-supabase/) +- [대형 언어 모델 활용 인터페이스 코드 및 문서 작성](../../backend/ai-interface-code/) +- [Git과 GitHub 워크플로우](../../backend/git-workflow/) +- [웹 애플리케이션 배포 방법](../../backend/zeabur-deployment/) diff --git a/docs/ko-kr/stage-2/assignments/modern-landing-page/index.md b/docs/ko-kr/stage-2/assignments/modern-landing-page/index.md new file mode 100644 index 0000000..e7eaed1 --- /dev/null +++ b/docs/ko-kr/stage-2/assignments/modern-landing-page/index.md @@ -0,0 +1,211 @@ +# 现代 AI 生图 SaaS 开发实战 + +## 概述 + +本实战项目要求你围绕一份真实的 PRD(产品需求文档),从零完成一个参考 Midjourney 体验的 AI 生图 SaaS 产品。你将完整经历需求分析、项目拆解、迭代开发、联调上线的全过程。 + +这是 Stage 2 的综合实战环节。在前面几章中,你已经分别学习了前端页面设计、后端接口开发、数据库操作、支付集成等单项技能——这个项目要求你把它们全部串起来,交付一个可运行的产品原型。 + +## 前置知识 + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- 支付集成([Stripe 收费系统](../../backend/stripe-payment/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## 学习目标 + +完成本实战后,你将能够: + +1. 阅读并理解一份真实的 PRD,从中提取开发任务清单 +2. 基于 PRD 拆分模块,制定分步推进计划 +3. 使用 AI 辅助完成前端骨架搭建和后端接口开发 +4. 对每个模块进行验证和迭代优化 +5. 完成端到端联调,将项目从"能跑"推进到"能交付" + +## 项目简介 + +你要构建的产品是一个现代 AI 生图 SaaS 平台,包含三个子系统: + +| 子系统 | 职责 | +|--------|------| +| **官网前台** | 产品介绍、定价、FAQ、注册转化 | +| **用户工作台** | Prompt 输入、图片生成、图库、积分、套餐、社区互动 | +| **后台管理台** | 用户管理、任务管理、支付管理、内容审核、SaaS 指标、系统监控 | + +后端需要支持以下核心能力:用户鉴权、图片生成任务、OSS 对象存储、积分与套餐支付、图片社交互动、运营数据监控。 + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/ko-kr/stage-2/assignments/modern-landing-page/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 系统有几个入口?各自覆盖哪些页面? +- 每个页面的核心功能是什么? +- 后端包含哪些模块和数据库表? +- MVP 范围是什么?第一版哪些做,哪些不做? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认系统架构 + +根据 PRD 中的描述,梳理出系统的整体架构: + +```mermaid +flowchart TD + prd["PRD"] --> web["官网前台"] + prd --> app["用户工作台"] + prd --> admin["后台管理台"] + app --> auth["鉴权"] + app --> gen["图片生成任务"] + gen --> oss["OSS 对象存储"] + gen --> db["数据库"] + billing["支付与套餐"] --> db + social["分享 / 点赞 / 评论 / 转发"] --> db + admin --> analytics["SaaS 指标看板"] + admin --> observability["API / DB / Provider 监控"] +``` + +建议你用自己的话把架构图画一遍,确认你对系统的理解是完整的。 + +## 第二部分:搭建项目骨架 + +### 2.1 生成前端页面 + +使用 AI 先生成所有页面的基本结构和假数据。这一步的目标是搭出信息架构和路由,不需要接真实接口。 + +提示词参考: + +```text +请基于当前 PRD,帮我生成一个现代 AI 生图 SaaS 的前端骨架。 + +要求: +1. 分成三个入口:www、app、admin +2. 官网包括:首页、定价、FAQ +3. app 包括:登录、注册、生成工作台、图库、套餐、积分、社区、作品详情、个人中心 +4. admin 包括:后台首页、用户管理、任务管理、内容管理、套餐管理、支付订单、运营配置、SaaS 指标、系统监控 +5. 先只生成页面结构和假数据,不接真实接口 +6. 风格参考 Midjourney,简洁、现代、带产品感 +``` + +### 2.2 验证页面结构 + +骨架生成后,逐项检查: + +- [ ] 三个入口的路由是否独立(`/`、`/app`、`/admin`) +- [ ] 页面数量是否与 PRD 一致 +- [ ] 每个页面是否可以正常访问和导航 +- [ ] 假数据是否展示了基本的 UI 状态(列表、空状态、表单等) + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +在骨架的基础上,按以下顺序逐模块补充功能: + +1. **鉴权**:注册、登录、角色区分 +2. **数据库**:数据表创建、读写接口 +3. **核心业务**:图片生成任务、结果存储 +4. **OSS 存储**:图片上传与访问 +5. **支付**:套餐、积分、Stripe 集成 +6. **社交互动**:分享、点赞、评论 +7. **后台管理**:用户管理、任务管理、内容审核 +8. **数据监控**:SaaS 指标看板、系统监控 + +每完成一个模块,使用下表进行自检: + +| 检查项 | 验证方法 | +|--------|----------| +| 页面一致性 | 页面数量、入口、功能是否符合 PRD | +| 接口正确性 | 请求参数、返回结构、状态处理是否合理 | +| 权限隔离 | 普通用户和管理员是否互相隔离 | +| 数据一致性 | 数据库、OSS、支付、积分是否对得上 | +| 可演示性 | 是否能给别人完整演示一条业务链路 | + +::: tip +如果发现 AI 生成的内容偏离了 PRD,不要整页推翻重来,直接让它修改具体模块即可。 +::: + +### 3.2 角色与分工 + +在迭代过程中,你需要同时扮演三个角色: + +- **产品经理**:确认每个模块的功能是否符合 PRD +- **技术负责人**:确认实现方案是否合理 +- **测试工程师**:确认功能是否跑得通 + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +最后阶段的重点不是补新页面,而是把完整业务链路跑通。至少验证以下场景: + +- 注册 → 购买积分 → 生成图片 → 查看历史 → 分享互动 +- 管理员登录 → 查看用户数据 → 查看任务统计 → 查看系统监控 + +### 4.2 部署 + +将项目部署到公网环境,确保: + +- 环境变量配置完整 +- 登录回调地址正确 +- 支付回调地址正确 +- 页面无缺失的 loading、空状态、错误提示 + +部署教程参考:[Git 和 GitHub 工作流](../../backend/git-workflow/)、[如何部署 Web 应用](../../backend/zeabur-deployment/)。 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(官网首页、生图工作台、图库、套餐页、后台首页) +- [ ] 60 秒演示视频(覆盖注册 → 生成 → 查看 → 后台管理) + +README 至少包含:项目简介、核心页面说明、技术栈、本地启动步骤、环境变量清单。 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| PRD 对齐 | 页面、功能、数据结构基本符合 PRD | 能清晰说明每个设计决策与 PRD 的对应关系 | +| 产品闭环 | 注册 → 购买积分 → 生成图片 → 查看历史 → 分享互动可跑通 | 支付状态、积分余额、生成次数数据一致 | +| 后台能力 | 用户、任务、支付、内容管理可查看 | SaaS 指标看板和系统监控页完整可用 | +| 工程完整度 | 前端、后端、数据库、OSS、支付链路已接通 | 有错误处理、空状态、loading 状态 | +| 交付质量 | 可部署、可运行 | README 清楚、演示视频结构完整 | + +## 参考资料 + +- [UI 设计](../../frontend/ui-design/) +- [参考 UI 设计规范设计页面和按钮](../../frontend/multi-product-ui/) +- [用 LLM 和 Skills 让界面变好看](../../frontend/llm-skills-beautiful/) +- [从设计原型到项目代码](../../frontend/design-to-code/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) +- [如何集成 Stripe 等收费系统](../../backend/stripe-payment/) diff --git a/docs/ko-kr/stage-2/assignments/movie-recommendation-springboot/index.md b/docs/ko-kr/stage-2/assignments/movie-recommendation-springboot/index.md new file mode 100644 index 0000000..84c0821 --- /dev/null +++ b/docs/ko-kr/stage-2/assignments/movie-recommendation-springboot/index.md @@ -0,0 +1,162 @@ +# Spring Boot 电影推荐系统开发实战 + +## 概述 + +本实战项目要求你围绕一份真实的 PRD,使用 Spring Boot 完成一个带推荐能力的电影网站。这个项目的核心挑战在于:它不是简单的增删改查,而是需要你思考"用户行为如何影响推荐结果"以及"推荐如何可解释"。 + +这是 Stage 2 的综合实战环节。你将第一次接触"内容 + 行为 + 推荐"型产品的开发模式,这种模式在电商、内容平台、个性化 Feed 等场景中非常常见。 + +## 前置知识 + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## 学习目标 + +完成本实战后,你将能够: + +1. 阅读 PRD 并从中提取推荐系统的开发任务清单 +2. 使用 Spring Boot 搭建后端项目并实现 RESTful API +3. 设计"用户行为 → 推荐"的完整数据链路 +4. 实现可解释的推荐逻辑 +5. 完成端到端联调,交付可演示的产品原型 + +## 项目简介 + +你要构建的产品是一个带推荐能力的电影网站: + +| 功能 | 描述 | +|------|------| +| **浏览与搜索** | 用户可以浏览和搜索电影 | +| **评分与收藏** | 用户可以给电影评分、添加收藏 | +| **个性化推荐** | 系统根据用户行为给出推荐结果 | +| **管理后台** | 管理员维护电影数据、查看推荐效果 | + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/ko-kr/stage-2/assignments/movie-recommendation-springboot/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 推荐策略是什么?第一版是否使用可解释版本(如基于评分相似度)? +- 用户行为数据要存哪些?(评分、收藏、浏览记录等) +- 管理员需要看哪些推荐效果指标? +- 页面清单是否完整? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认系统架构 + +```mermaid +flowchart TD + prd["PRD"] --> web["前端页面"] + web --> auth["用户鉴权"] + web --> movie["电影列表 / 详情"] + web --> behavior["评分 / 收藏"] + behavior --> reco["推荐逻辑"] + reco --> db["数据库"] + admin["后台管理"] --> db +``` + +## 第二部分:搭建项目骨架 + +### 2.1 生成前端页面 + +提示词参考: + +```text +请基于当前 PRD,帮我生成一个 Spring Boot 电影推荐系统的前端骨架。 + +要求: +1. 页面包括:首页、电影列表、电影详情、推荐页、个人中心、后台管理 +2. 先只生成页面结构和假数据,不接真实接口 +3. 风格要像真实内容产品,而不是课堂 demo +``` + +### 2.2 验证页面结构 + +逐项检查: + +- [ ] 电影列表页支持搜索和筛选 +- [ ] 电影详情页包含评分和收藏按钮 +- [ ] 推荐页能展示推荐结果和推荐理由 +- [ ] 管理后台能展示电影数据和推荐效果 + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +1. **Spring Boot 项目搭建**:项目结构、数据库配置、基础 CRUD +2. **电影数据管理**:电影列表、详情、搜索接口 +3. **用户行为**:评分、收藏接口,行为数据写入 +4. **推荐逻辑**:基于用户行为的推荐算法实现 +5. **推荐展示**:推荐结果展示,包含推荐理由 +6. **管理后台**:电影数据维护、推荐效果查看 + +### 3.2 模块自检 + +| 检查项 | 验证方法 | +|--------|----------| +| 基础功能 | 列表、详情、评分、收藏是否闭环 | +| 推荐联动 | 用户行为是否影响推荐结果 | +| 推荐可解释性 | 用户能理解为什么被推荐这些电影 | +| 后台数据 | 管理员能查看电影数据和推荐效果 | + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +至少验证以下场景: + +- 浏览电影 → 评分 → 收藏 → 查看推荐页,确认推荐结果发生变化 +- 管理员登录 → 添加电影 → 查看推荐效果统计 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(电影列表、电影详情、推荐页、管理后台) +- [ ] 60 秒演示视频 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| PRD 对齐 | 页面、功能、数据结构基本符合 PRD | 能清晰说明设计决策 | +| 产品闭环 | 浏览 → 评分 → 收藏 → 推荐可跑通 | 评分行为明显影响推荐结果 | +| 推荐质量 | 推荐结果合理、推荐理由可解释 | 支持多种推荐策略 | +| 后台能力 | 电影数据和推荐效果可查看 | 有推荐准确率等统计指标 | +| 工程完整度 | 前端、Spring Boot 后端、数据库链路已接通 | 推荐接口有缓存或性能优化 | + +## 参考资料 + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/ko-kr/stage-2/assignments/simple-grocery-microservices/index.md b/docs/ko-kr/stage-2/assignments/simple-grocery-microservices/index.md new file mode 100644 index 0000000..749d844 --- /dev/null +++ b/docs/ko-kr/stage-2/assignments/simple-grocery-microservices/index.md @@ -0,0 +1,172 @@ +# 生鲜电商微服务系统开发实战 + +## 概述 + +本实战项目要求你围绕一份真实的 PRD,从零完成一个生鲜电商微服务系统。与前面的单服务项目不同,这个项目的后端按业务拆分成多个独立服务,通过 API 网关统一对外。你将学习如何设计服务边界、如何处理跨服务的数据一致性问题。 + +这是 Stage 2 的综合实战环节。微服务架构在实际工作中非常常见,掌握服务拆分和网关路由的基本思路后,你能够应对更复杂的后端系统设计。 + +## 前置知识 + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## 学习目标 + +完成本实战后,你将能够: + +1. 阅读 PRD 并提取微服务系统的开发任务清单 +2. 按业务领域拆分服务边界(鉴权、商品、库存、订单) +3. 设计和实现 API 网关路由 +4. 处理库存扣减和订单一致性等跨服务问题 +5. 完成端到端联调,交付可演示的微服务原型 + +## 项目简介 + +你要构建的产品是一个生鲜电商微服务系统: + +| 子系统 | 职责 | +|--------|------| +| **用户端** | 浏览商品、下单、查看订单 | +| **管理端** | 商品管理、库存管理、订单管理 | + +后端按业务拆分为以下服务: + +| 服务 | 职责 | +|------|------| +| **API Gateway** | 统一入口、路由转发、鉴权校验 | +| **Auth Service** | 用户注册、登录、JWT 颁发 | +| **Catalog Service** | 商品信息管理 | +| **Inventory Service** | 库存数量管理 | +| **Order Service** | 订单创建、状态管理 | + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/ko-kr/stage-2/assignments/simple-grocery-microservices/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 服务如何拆分?每个服务的职责边界是什么? +- 前台和管理端分别有哪些页面? +- 下单后库存扣减的策略是什么?成功 / 失败 / 超时各怎么处理? +- 第一版哪些复杂能力(如分布式事务、消息队列)先不做? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认系统架构 + +```mermaid +flowchart TD + prd["PRD"] --> fe["前端页面"] + fe --> gw["API Gateway"] + gw --> auth["Auth Service"] + gw --> catalog["Catalog Service"] + gw --> inventory["Inventory Service"] + gw --> order["Order Service"] + order --> inventory +``` + +## 第二部分:搭建项目骨架 + +### 2.1 生成项目结构 + +提示词参考: + +```text +请基于当前 PRD,帮我生成一个生鲜电商微服务系统的项目骨架。 + +要求: +1. 生成前端用户端和管理端骨架 +2. 生成 api-gateway、auth-service、catalog-service、inventory-service、order-service 五个目录 +3. 每个服务先只做最小可运行入口 +4. 先不接真实数据库和支付 +``` + +### 2.2 验证项目结构 + +逐项检查: + +- [ ] 五个服务目录结构清晰 +- [ ] API Gateway 可以启动并转发请求 +- [ ] 各服务健康检查接口可用 +- [ ] 前端用户端和管理端页面可访问 + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +1. **API Gateway**:路由配置、JWT 校验中间件 +2. **Auth Service**:注册、登录、JWT 颁发 +3. **Catalog Service**:商品 CRUD、列表查询 +4. **Inventory Service**:库存查询、库存扣减 +5. **Order Service**:订单创建、状态流转、库存联动 +6. **管理端**:商品管理、库存管理、订单管理 + +### 3.2 模块自检 + +| 检查项 | 验证方法 | +|--------|----------| +| 网关路由 | 各服务接口是否通过网关正确转发 | +| 权限隔离 | 用户端和管理端接口是否隔离 | +| 数据一致 | 商品和库存数据是否同步 | +| 交易闭环 | 下单后库存扣减、订单状态是否一致 | +| 失败处理 | 库存不足或超时时是否有补偿机制 | + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +至少验证以下场景: + +- 浏览商品 → 加入购物车 → 下单 → 查看订单 +- 管理员 → 添加商品 → 更新库存 → 查看订单 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(商品列表、下单页、订单页、管理后台) +- [ ] 60 秒演示视频 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| PRD 对齐 | 页面、功能、服务拆分基本符合 PRD | 能清晰说明服务拆分的理由 | +| 产品闭环 | 浏览 → 下单 → 库存扣减 → 查看订单可跑通 | 订单超时或库存不足有补偿机制 | +| 服务架构 | 各服务可独立启动,通过网关统一访问 | 服务间通信有错误处理和重试 | +| 后台能力 | 商品、库存、订单管理可操作 | 管理端有数据统计 | +| 工程完整度 | 前端、网关、服务、数据库链路已接通 | 有 Docker Compose 或类似编排 | + +## 参考资料 + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/ko-kr/stage-2/assignments/traffic-data-visualization-go/index.md b/docs/ko-kr/stage-2/assignments/traffic-data-visualization-go/index.md new file mode 100644 index 0000000..cfc389c --- /dev/null +++ b/docs/ko-kr/stage-2/assignments/traffic-data-visualization-go/index.md @@ -0,0 +1,163 @@ +# Go 交通数据分析平台开发实战 + +## 概述 + +本实战项目要求你围绕一份真实的 PRD,使用 Go 完成一个交通数据分析平台。这个项目的方向与前面的增删改查系统不同——你需要构建一条"数据接入 → 聚合 → 告警 → 可视化"的完整数据链路。这种数据产品在 IoT、监控、运营分析等场景中非常常见。 + +这是 Stage 2 的综合实战环节,也是你第一次接触 Go 语言。不用担心,有了前面 JavaScript / TypeScript 的基础,学习 Go 并不难——重点是理解数据链路的设计思路。 + +## 前置知识 + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## 学习目标 + +完成本实战后,你将能够: + +1. 阅读 PRD 并提取数据产品的开发任务清单 +2. 使用 Go(Gin 或 Fiber)搭建后端 API 服务 +3. 设计数据接入、窗口聚合和告警的完整链路 +4. 让后端数据和前端看板保持一致 +5. 完成端到端联调,交付可演示的数据产品原型 + +## 项目简介 + +你要构建的产品是一个 Go 交通数据分析平台: + +| 模块 | 职责 | +|------|------| +| **数据接入** | 接收原始交通事件并入库 | +| **数据聚合** | 按时间窗口计算趋势和拥堵指标 | +| **告警** | 基于规则生成告警记录 | +| **看板展示** | 在前端展示趋势图、排行榜和告警列表 | + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/ko-kr/stage-2/assignments/traffic-data-visualization-go/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 数据来源是什么?字段有哪些? +- 核心指标的定义是什么?(比如"拥堵"的具体标准) +- 告警规则是什么?第一版是否先收敛到简单规则? +- 看板包含哪些页面和图表? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认数据链路 + +```mermaid +flowchart TD + prd["PRD"] --> ingest["数据接入 API"] + ingest --> raw["原始数据表"] + raw --> agg["聚合任务"] + agg --> alert["告警规则"] + agg --> dashboard["看板接口"] + alert --> dashboard +``` + +## 第二部分:搭建项目骨架 + +### 2.1 生成 Go API 服务 + +提示词参考: + +```text +请基于当前 PRD,帮我生成一个 Go 交通数据分析平台骨架。 + +要求: +1. 使用 Gin 或 Fiber +2. 提供数据接入接口 +3. 提供聚合任务骨架 +4. 提供 dashboard 和 alerts 接口骨架 +5. 先不做真实复杂分析,只做可运行结构 +``` + +### 2.2 验证项目结构 + +逐项检查: + +- [ ] Go 服务可以正常启动 +- [ ] 数据接入接口可接收并存储数据 +- [ ] 聚合任务框架已搭好 +- [ ] 前端看板页面可展示基本图表 + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +1. **数据接入 API**:接收原始交通事件,写入数据库 +2. **数据聚合**:按时间窗口聚合,计算趋势和拥堵指标 +3. **告警规则**:基于阈值生成告警记录 +4. **看板接口**:提供趋势数据、排行数据、告警列表 +5. **前端看板**:趋势图、排行榜、告警列表页面 + +### 3.2 模块自检 + +| 检查项 | 验证方法 | +|--------|----------| +| 数据接入 | 原始数据是否正确入库 | +| 聚合口径 | 趋势、排名指标的计算逻辑是否一致 | +| 告警规则 | 告警触发条件是否符合预期 | +| 数据一致性 | 看板展示和后端数据是否对得上 | +| API 规范 | 是否有统一返回结构和错误处理 | + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +至少验证以下场景: + +- 接入一批测试数据 → 聚合任务执行 → 看板展示更新 +- 触发告警条件 → 告警记录生成 → 告警页面显示 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(数据接入演示、趋势看板、告警列表) +- [ ] 60 秒演示视频 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| PRD 对齐 | 功能和数据结构基本符合 PRD | 能清晰说明指标口径和聚合逻辑 | +| 数据链路 | 接入 → 聚合 → 告警 → 看板可跑通 | 聚合任务支持增量更新 | +| 分析能力 | 趋势、排行、告警三个模块可用 | 指标可配置、告警规则可自定义 | +| 前端展示 | 看板能展示基本图表 | 图表支持时间范围筛选 | +| 工程完整度 | Go API、数据库、前端链路已接通 | API 有统一错误处理和日志 | + +## 参考资料 + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/ko-kr/stage-2/assignments/travel-planning-agent-platform/index.md b/docs/ko-kr/stage-2/assignments/travel-planning-agent-platform/index.md new file mode 100644 index 0000000..e6795ac --- /dev/null +++ b/docs/ko-kr/stage-2/assignments/travel-planning-agent-platform/index.md @@ -0,0 +1,164 @@ +# 智能旅游规划 Agent 平台开发实战 + +## 概述 + +本实战项目要求你围绕一份真实的 PRD,从零完成一个智能旅游规划 Agent 平台。你将构建一个能接收结构化输入、生成每日行程、支持保存和重用的完整 AI 产品——不只是聊天机器人,而是一个有任务管理能力的产品。 + +这是 Stage 2 的综合实战环节。这个项目的核心挑战在于:如何让 AI 生成结构化、可用的行程规划,而不是一大段不可操作的文字。 + +## 前置知识 + +在开始本项目之前,你应该已经掌握以下内容: + +- 前端页面设计与组件库使用([UI 设计](../../frontend/ui-design/)、[现代组件库](../../frontend/modern-component-library/)) +- 后端接口设计与开发([接口代码编写](../../backend/ai-interface-code/)) +- 数据库基础与 Supabase([从数据库到 Supabase](../../backend/database-supabase/)) +- Git 工作流与部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 应用](../../backend/zeabur-deployment/)) + +## 学习目标 + +完成本实战后,你将能够: + +1. 阅读 PRD 并从中提取 Agent 平台的开发任务清单 +2. 设计结构化的输入表单和结构化的输出格式 +3. 实现 Agent 编排层,处理用户输入、模型调用和结果存储 +4. 构建"生成 → 保存 → 重用"的业务闭环 +5. 完成端到端联调,交付可演示的 AI 产品原型 + +## 项目简介 + +你要构建的产品是一个智能旅游规划 Agent 平台: + +| 功能 | 描述 | +|------|------| +| **行程规划** | 用户输入出发地、目的地、日期、预算和偏好,系统生成每日行程 | +| **预算拆分** | 行程结果包含预算分配和建议 | +| **历史管理** | 用户可以保存历史计划、再次生成、导出 | +| **管理后台** | 管理员查看热门目的地、失败任务和用户反馈 | + +::: tip PRD 入口 +本项目的需求文档在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/ko-kr/stage-2/assignments/travel-planning-agent-platform/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 阅读 PRD + +打开 PRD 文档,重点回答以下问题: + +- 第一版是否只做单目的地? +- 行程输出是否必须结构化?结构是什么? +- 导出能力做多深?(分享链接 / PDF / 图片) +- 后台统计和任务日志的范围是什么? + +::: warning +如果以上问题没有明确答案,不要开始写代码。需求理解不清楚是导致返工的最常见原因。 +::: + +### 1.2 确认系统架构 + +```mermaid +flowchart TD + prd["PRD"] --> planner["规划页"] + planner --> agent["Agent 编排层"] + agent --> model["模型调用"] + agent --> db["数据库"] + db --> history["历史计划"] + db --> admin["后台统计与日志"] +``` + +## 第二部分:搭建项目骨架 + +### 2.1 生成前端页面 + +提示词参考: + +```text +请基于当前 PRD,帮我生成一个智能旅游规划 Agent 平台的前端骨架。 + +要求: +1. 页面包括:首页、规划页、行程详情页、历史记录页、管理页 +2. 规划页左侧是表单,右侧是结果预览 +3. 先只生成页面结构和假数据,不接真实接口 +4. 风格要像现代 AI 产品 +``` + +### 2.2 验证页面结构 + +逐项检查: + +- [ ] 规划页的表单字段是否与 PRD 一致 +- [ ] 结果预览区域能展示结构化的行程数据 +- [ ] 历史记录页可以展示多条计划 +- [ ] 管理后台页可以展示统计数据 + +## 第三部分:迭代开发 + +### 3.1 按模块推进 + +1. **鉴权**:注册、登录 +2. **规划表单**:结构化输入(出发地、目的地、日期、预算、偏好) +3. **Agent 编排**:接收输入 → 调用模型 → 解析结构化输出 +4. **结果展示**:行程按天展示、预算拆分、建议 +5. **历史管理**:保存计划、再次生成、导出 +6. **管理后台**:热门目的地、失败任务、用户反馈 +7. **任务状态**:生成中 / 成功 / 失败的状态管理和错误记录 + +### 3.2 模块自检 + +| 检查项 | 验证方法 | +|--------|----------| +| 输入完整性 | 表单字段是否与 PRD 一致 | +| 输出结构化 | 行程结果是不是结构化数据(而非一大段文字) | +| 数据一致性 | trip、itinerary、logs 数据是否对得上 | +| 闭环验证 | 是否能演示"输入 → 生成 → 保存 → 再次生成" | + +## 第四部分:联调与上线 + +### 4.1 端到端测试 + +至少验证以下场景: + +- 输入行程参数 → 生成每日行程 → 查看预算拆分 → 保存到历史 +- 从历史记录中再次生成行程 +- 管理员查看任务统计和失败日志 + +## 交付物 + +完成本项目后,你需要提交以下内容: + +- [ ] 可访问的线上演示链接 +- [ ] 源码仓库链接(含 README) +- [ ] PRD 文档 +- [ ] 核心页面截图(规划页、行程详情页、历史记录页、管理后台) +- [ ] 60 秒演示视频 + +## 评分标准 + +| 维度 | 基本要求 | 进阶要求 | +|------|---------|---------| +| PRD 对齐 | 页面、功能、数据结构基本符合 PRD | 能清晰说明设计决策 | +| 产品闭环 | 规划 → 保存 → 历史 → 重生成可跑通 | 支持导出和分享 | +| 输出质量 | 行程结果结构化且可读 | 预算拆分合理、建议有针对性 | +| 后台能力 | 任务统计和失败日志可查看 | 有热门目的地分析 | +| 工程完整度 | 前端、后端、数据库、模型调用链路已接通 | 任务状态管理完善,错误可追溯 | + +## 参考资料 + +- [UI 设计](../../frontend/ui-design/) +- [使用现代组件库更新你的界面](../../frontend/modern-component-library/) +- [从数据库到 Supabase](../../backend/database-supabase/) +- [大模型辅助编写接口代码与接口文档](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 应用](../../backend/zeabur-deployment/) diff --git a/docs/ko-kr/stage-2/backend/ai-interface-code/index.md b/docs/ko-kr/stage-2/backend/ai-interface-code/index.md new file mode 100644 index 0000000..ed63bb6 --- /dev/null +++ b/docs/ko-kr/stage-2/backend/ai-interface-code/index.md @@ -0,0 +1,161 @@ +# 대형 언어 모델 활용 인터페이스 코드 및 문서 작성 + +이전 강의에서는 Figma 등의 도구를 사용해 UI 디자인 시안을 완성하고, AI를 활용해 프론트엔드 정적 페이지를 빠르게 생성하며, Supabase를 이용해 데이터베이스를 구축하고 기본적인 사용자 인증을 구현하는 방법을 배웠습니다. 이제 자연스럽게 떠오르는 질문이 있습니다: 프론트엔드 페이지에서 역동적인 버튼을 클릭하면, 데이터는 어떻게 소리 없이 Supabase에 저장되는 걸까요? 더 복잡한 비즈니스 로직(예: 동시 결제, 예약 푸시, 민감 데이터 처리)을 실행해야 할 때, 프론트엔드에서 직접 데이터베이스에 연결하는 것이 안전할까요? + +이것이 현대 웹 개발 아키텍처에서 매우 중요한 역할을 하는 **백엔드 API 인터페이스**로 이어집니다. + +과거처럼 수백~수천 줄의 백엔드 라우팅, 컨트롤러, 매개변수 검증 로직을 수동으로 작성하는 대신, 이제는 대형 언어 모델의 강력한 코드 생성 능력을 활용해 복잡한 기반 코드를 AI가 작성하도록 할 수 있습니다. 이번 강의에서는 "AI가 작성한 코드가 겉도는" 문제에서 벗어나, 실제 비즈니스 시나리오를 바탕으로 고품질 프롬프트(Prompt)를 통해 대형 언어 모델이 견고하고 업계 표준에 부합하는 Node.js 백엔드 인터페이스를 작성하도록 안내하고, 인터페이스 문서와 테스트 케이스를 자동으로 생성하는 방법을 보여드리겠습니다. + +> 💡 **사전 지식** +> +> 이번 장을 학습하기 전에 다음 내용을 먼저 확인하는 것을 권장합니다: +> - [데이터베이스에서 Supabase까지](../database-supabase/) - 데이터베이스와 데이터 모델의 개념 이해 +> - [Git과 GitHub 워크플로우](../git-workflow/) - 프로젝트 개발에서 버전 관리 방법 숙지 +> - [터미널/명령어 줄이란](/ko-kr/appendix/2-development-tools/command-line-shell) - 프로젝트 초기화와 실행에 필요한 기본 명령어 + +# 배울 내용 + +1. **API 인터페이스란**: 프론트엔드와 백엔드 통신의 다리와 RESTful 설계 규범 이해 +2. **대형 언어 모델로 서비스 구축하기**: 구조화된 Prompt를 통해 AI가 Node.js + Express 기반 공정을 구축하도록 하는 방법 +3. **인터페이스 로직 개발**: 대형 언어 모델이 엄격한 비즈니스 검증과 Supabase 데이터베이스 연동이 포함된 CRUD(생성, 조회, 수정, 삭제) 인터페이스를 생성하도록 안내 +4. **자동화된 인터페이스 문서**: 대형 언어 모델이 코드를 기반으로 팀 협업에 필수적인 OpenAPI/Swagger 문서를 역으로 생성 +5. **테스트 및 통합 디버깅**: 대형 언어 모델을 활용해 Postman 테스트 컬렉션과 Jest 단위 테스트 케이스를 생성하여 코드 품질 보장 + +--- + +# 1. 왜 API 인터페이스가 필요한가? + +전통적인 이해에서 프론트엔드는 "보이는 부분", 데이터베이스는 "데이터를 저장하는 창고"입니다. 하지만 그 사이에 조정자가 없습니다. 전체 애플리케이션을 하나의 레스토랑에 비유해 보겠습니다: +- **프론트엔드(클라이언트)** 는 레스토랑의 메뉴와 주문 테이블로, 손님이 여기서 메뉴를 보고 요구사항을 제시합니다. +- **데이터베이스(Supabase 등)** 는 레스토랑의 주방 창고로, 모든 식재료와 장부가 보관됩니다. +- **백엔드 API 인터페이스** 는 레스토랑의 종업원입니다. 손님은 직접 주방에 들어가 식재료를 꺼낼 수 없습니다(혼란스럽고 보안 문제가 발생하기 쉬움). 대신 "주문 요청"(HTTP Request)을 종업원에게 전달합니다. 종업원은 확인(매개변수 검증, 권한 인증)한 후 주방에서 해당 항목을 가져와, "완성된 요리"(HTTP Response, 보통 JSON 형식의 데이터)를 손님에게 서빙합니다. + +API 인터페이스를 통해 명확한 **프론트엔드-백엔드 분리**를 실현합니다: 프론트엔드는 페이지 렌더링에만 집중하고, 백엔드는 비즈니스 로직, 데이터 처리, 보안 방어에만 집중합니다. + +--- + +# 2. 프로젝트 아키텍처 설계 및 초기화 + +구조가 명확한 프로젝트 골격은 대형 언어 모델이 좋은 코드를 작성하기 위한 전제 조건입니다. AI에게 코드를 작성하게 하기 전에, 프로젝트 구조에 대한 기본적인 이해가 있어야 합니다. + +## 2.1 일반적인 API 프로젝트 구조 +대형 언어 모델을 사용해 코드를 생성하더라도, 모든 코드를 하나의 `server.js` 파일에 넣어서는 안 됩니다. 유지보수가 쉬운 Node.js 백엔드 아키텍처는 일반적으로 다음과 같습니다: + +```text +my-api-project/ +├── .env # 민감한 환경 변수(예: API Keys, 데이터베이스 연결 문자열) +├── server.js # 프로젝트 진입점(서버 시작, 전역 미들웨어 등록) +├── package.json # 의존성 관리 파일 +├── src/ +│ ├── routes/ # 라우팅 계층: URL 경로 및 요청 메서드 정의 +│ ├── controllers/ # 컨트롤러 계층: 비즈니스 요청 매개변수 처리, 서비스 호출 및 응답 반환 +│ ├── services/ # 서비스 계층: 데이터베이스 상호작용 및 핵심 비즈니스 로직 캡슐화 +│ └── middlewares/ # 미들웨어: 로그인 인증, 전역 오류 캡처 +└── docs/ # API 문서 저장 디렉토리 +``` + +## 2.2 AI를 활용한 프로젝트 초기화 +직접 `npm init` 하고 의존성을 하나씩 설치하는 대신, 위의 규격을 Prompt 형태로 대형 언어 모델에 전달하는 것이 더 효율적입니다: + +> 🗣️ **대형 언어 모델에 대한 프롬프트(Prompt 예시):** +> "Node.js 백엔드 프로젝트를 구축해 줘. Supabase 데이터베이스에 연결할 수 있어야 하고, 구조가 명확해야 하며, 향후 유지보수가 편해야 해." + +AI가 반환한 코드를 실행하면 `localhost:3000`에서 기업급 백엔드 애플리케이션의 초기 형태를 얻을 수 있습니다. + +--- + +# 3. 핵심 실전: 대형 언어 모델 활용 인터페이스 개발 + +이번 장의 가장 핵심적인 부분입니다. 대형 언어 모델이 작성한 코드는 종종 "논리적 허점"이나 "겉만 번지르르한" 문제가 있는데, 이는 개발자가 제공한 컨텍스트가 불충분하기 때문입니다. **대형 언어 모델은 복잡한 요구사항을 두려워하지 않지만, 모호한 요구사항을 가장 두려워합니다.** + +[데이터베이스 장](../database-supabase/)에서 언급한 `menu_items`(메뉴 테이블)의 생성 인터페이스를 예로, 고품질 Prompt를 작성하는 방법을 살펴보겠습니다. + +## 3.1 대형 언어 모델에 완전한 컨텍스트 제공 +AI에게 인터페이스 작성을 요청하기 전에 반드시 **데이터베이스 필드 정의(Schema)** 와 **구체적인 제약 조건**을 제공해야 합니다. + +> 🗣️ **고품질 프롬프트(Prompt) 템플릿:** +> "메뉴 추가 인터페이스를 작성해 줘. 메뉴에는 상품명, 가격, 분류(버거, 사이드, 음료), 판매 여부 정보가 포함돼. 상품명과 가격은 필수 항목이고, 가격은 음수일 수 없어. 사용자 입력이 올바르지 않을 때는 오류 메시지를 표시해야 해." + +## 3.2 대형 언어 모델이 생성한 코드 검토 +대형 언어 모델이 생성한 코드는 일반적으로 다음과 같이 명확하게 역할이 분리되어 있습니다: + +```javascript +// services/menuService.js +const { createClient } = require('@supabase/supabase-js'); +const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY); + +exports.createMenuItem = async (menuData) => { + // Supabase SDK를 호출하여 데이터를 테이블에 삽입 + const { data, error } = await supabase + .from('menu_items') + .insert([menuData]) + .select(); + + if (error) throw new Error(`데이터베이스 삽입 실패: ${error.message}`); + return data[0]; +}; +``` + +이 방식으로 생성된 코드는 구조가 합리적일 뿐만 아니라, Supabase 초기화, 오류 캡처, 예외 처리까지 고려되어 있어, 단순히 "추가 인터페이스를 작성해 줘"라고 요청해서 얻는 스파게티 코드(Spaghetti Code)와는 비교가 되지 않습니다. + +--- + +# 4. 양손 해방: 자동 인터페이스 문서 생성 + +개발팀에게 문서 없는 API는 블랙박스와 같습니다. 프론트엔드 엔지니어는 어떤 매개변수를 전달해야 하는지, 어떤 구조가 반환되는지 추측할 수 없습니다. 업계에서 가장 널리 사용되는 API 설명 규격은 **OpenAPI(이전 명칭 Swagger)** 입니다. + +과거에는 YAML이나 JSON 형식의 Swagger 문서를 수동으로 작성하는 것이 매우 고통스럽고 오류가 발생하기 쉬웠습니다. 이제 이것은 대형 언어 모델이 가장 잘하는 분야가 되었습니다. + +방금 작성한 `routes`와 `controllers` 코드를 선택한 후 대형 언어 모델에 전달하면 됩니다: + +> 🗣️ **문서 생성 프롬프트:** +> "위 코드를 기반으로 인터페이스 문서를 생성해 줘. 각 매개변수의 의미와 반환 데이터를 명확히 작성해서 프론트엔드 동료가 연동하기 편하도록 해줘." + +이 과정에서 AI에게 필드 설명(Description)과 Mock 데이터(예: `price_cents: 1200`는 12달러를 의미)까지 보완해 달라고 요청할 수 있어, 소통 비용을 크게 줄일 수 있습니다. + +--- + +# 5. 안전장치: 테스트 코드 및 Postman 컬렉션 생성 + +코드 작성과 문서 생성이 끝났다면, 마지막 단계는 코드가 실제로 정상 작동하는지 확인하는 것입니다. + +## 5.1 Postman / Apifox 테스트 설정 생성 +인터페이스 개발에서는 일반적으로 Postman과 같은 시각화 도구를 사용하여 프론트엔드의 HTTP 요청을 시뮬레이션합니다. 대형 언어 모델을 사용하지 않는다면 URL을 수동으로 입력하고, Header(요청 헤더)를 하나씩 추가하며, JSON 요청 본문을 조합해야 합니다. + +AI에게 다음과 같이 지시만 하면 됩니다: +> "이 인터페이스 문서를 Postman에서 가져올 수 있는 형식으로 변환해 줘. 정상 요청과 오류 요청의 예시를 포함해 줘." + +JSON 텍스트를 받아 `menu_api.json`으로 저장한 후 Postman에 드래그하면, 즉시 사용 가능한 테스트 클릭 패널을 얻을 수 있습니다. + +## 5.2 자동화된 단위 테스트 작성 +더 엄격한 엔지니어링 품질을 추구한다면, 대형 언어 모델이 `Jest` 등의 테스트 프레임워크를 사용해 단위 테스트(Unit Tests)를 작성하도록 하여, 핵심 비즈니스 로직에 대한 경계값 테스트(예: 음수 가격을 전달했을 때 데이터베이스 계층의 검증이 작동하는지)를 수행할 수 있습니다. + +--- + +# 6. 백엔드 인터페이스 필수 모범 사례 + +AI의 지원이 있더라도, 시스템 전체의 "관문 담당자"로서 다음 핵심 원칙을 이해하고 검토해야 합니다: + +1. **RESTful 규격의 경로 명명**: + - 좋은 설계: `GET /api/users`(사용자 목록 조회), `POST /api/users`(사용자 생성). URL은 "리소스"를 나타내는 명사여야 합니다. + - 나쁜 설계: `POST /api/getUser` 또는 `POST /api/createUser`. 동사는 HTTP Method(GET/POST/PUT/DELETE)로 표현해야 합니다. +2. **표준 HTTP 상태 코드**: + - 200/201: 요청 성공 / 리소스 생성 성공 + - 400: Bad Request, 프론트엔드 매개변수 형식 오류 또는 필수 항목 누락 + - 401/403: Unauthorized / Forbidden, 사용자 미로그인 또는 권한 없음 + - 404: Not Found, 리소스가 존재하지 않음 + - 500: Server Error, 백엔드 코드 오류 또는 데이터베이스 장애. 오류 호출 스택을 프론트엔드에 직접 노출하지 마세요(보안 위험 있음) +3. **사용자 입력을 절대 신뢰하지 마세요**: 프론트엔드의 입력은 위조될 수 있으므로, 모든 핵심 매개변수 검증은 백엔드 인터페이스에서 다시 한번 수행해야 합니다. + +# 7. 요약 + +이번 장의 학습을 통해 여러분은 개발 관점의 진정한 전환을 이루었습니다: 더 이상 문법과 구두점에 갇힌 "타이피스트"가 아니라, **시스템 설계자이자 아키텍처 지휘관**으로 성장했습니다. +이제 다음을 습득했습니다: +1. **API 인터페이스와 프론트엔드-백엔드 분리**의 핵심 시스템 사고 +2. **컨텍스트 제공과 계층 구조 개념**을 통해 대형 언어 모델이 생성하는 서버 측 코드의 품질을 크게 향상시키는 방법 +3. 번거로운 **문서 작성**과 **테스트 케이스 구축**을 AI가 잘하는 자동화 작업으로 전환하는 방법 +4. 이전에 학습한 **Supabase** 지식과 결합하여, 클라이언트 요청부터 기본 데이터베이스 업데이트까지의 완전한 데이터 흐름을 구축 + +::: tip 💡 다음 단계 +데이터 흐름과 백엔드 서비스가 모두 준비되었지만, 현재는 로컬 컴퓨터에서만 실행됩니다. 다음 장에서는 이 서비스를 **공개 네트워크 서버에 배포(Deploy)** 하여, 전 세계 사용자가 여러분의 제품에 접근할 수 있도록 하는 방법을 배우겠습니다. +::: diff --git a/docs/ko-kr/stage-2/backend/database-supabase/index.md b/docs/ko-kr/stage-2/backend/database-supabase/index.md new file mode 100644 index 0000000..17aaab5 --- /dev/null +++ b/docs/ko-kr/stage-2/backend/database-supabase/index.md @@ -0,0 +1,1742 @@ +# 从数据库到 Supabase + +在上节课中,我们学会了 UI 设计程序 Mastergo 和 Figma 的基本用法,能够使用 github 进行代码的获取与版本管理,并通过 Zeabur 部署网站将自己的应用 / 网站传达给更多人使用。 + +为了帮助大家更好地衔接知识,在开始本节课关于设计工具与部署的新内容前,让我们一起通过几道简单的题目快速回顾一下上节课的核心知识点: + +1. 什么是前端设计工具、Figma、MasterGo 的定义和使用方式。 +2. 将设计稿转换为代码的基础方法。 +3. 什么是 Github,如何配置 SSH,如何构建自己的第一个仓库。 +4. 部署是什么意思,如何使用 Zeabur,如何将 Github 或本地代码部署至公共网络给大家访问。 + +如果对以上任何一个问题还有印象模糊的地方,建议先回顾一下上节课的文档和讲义。欢迎随时在微信学习群中提出疑问。 + +在本节课中,我们将学习如何让一个 APP / 网站从能跑起来变为更接近真实线上产品:除了用数据库管理程序运行中的各种数据变化外,还要具备完善的用户体系(注册、登录、权限等)以及其他关键后端能力。我们会以 Supabase 这一后端服务平台为主线,先用它实现“数据库 + 用户系统”这两项基础功能,再以 Supabase 提供的组件为参照,进一步理解现代云服务后端服务通常包含的核心模块,以及各模块的具体职能与作用逻辑。 + +# 你将学到 + +1. 什么是数据、什么是数据库,常见数据库与使用方法 +2. 什么是 supabase,如何使用 supabase 进行基础的数据库操作 +3. 如何使用 supabase 为应用添加基础用户管理功能 +4. 学会 Supabse 进阶功能:realtime、storage、edge function +5. 学会为Supabase增加 google 与 github 登录支持 + +- 一款支持用户注册 / 登录,并能将数据存入在线数据库的基础应用 +- 一套可复用的 Supabase 后端代码模板(数据库 + 用户管理等),供后续项目直接套用 + +# 1. 什么是数据库 + +## 1.1 什么是数据 + +在数字世界里,数据(Data)无处不在。简单来说,数据是信息的载体。你朋友的联系方式、一篇微信文章、一条短视频、游戏里的角色等级,这些都是数据。在我们的应用中,数据就是需要被记录和管理的一切信息,比如用户的个人资料、订单历史、程序设置等。 + +一般而言,数据在程序中有不同的表现形式,最简单的就是变量,我们可以用不同变量记录简单的数字: + +```python +# Python variable definition examples + +# Integer variable: stores age information +age = 30 + +# Boolean variable: stores status (whether active) +is_active = True # True means active, False means inactive + +# List variable: stores a set of score data +scores = [85, 92, 78, 90] # Contains 4 integer elements representing different scores + +# Dictionary variable: stores multiple related information of a user +user_info = { + "age": 30, # Key "age" corresponds to the value of age + "height": 1.80, # Key "height" corresponds to the value of height (unit: meter) + "login_count": 156 # Key "login_count" corresponds to the value of login times +} +``` + +而对于上述所说的个人资料、订单历史这类复杂的数据而言,我们可以用更复杂的表格进行数据的表示: + +| user_id | name | email | +| ------- | ----- | ----------------- | +| 1001 | Alice | alice@example.com | +| 1002 | Bob | bob@example.com | + +| order_id | user_id | amount | status | +| -------- | ------- | ------ | --------- | +| 901 | 1001 | 29.99 | completed | +| 902 | 1002 | 15.50 | pending | + +但对于结构复杂、具有层级关系或字段不固定的数据,我们可以用 JSON 格式进行描述 —— 它是互联网通用的数据中间格式,几乎所有程序都能读取解析,跨系统传数据很方便。例如,一个订单可能包含多个商品,每个商品又有自己的名称、数量和价格。用传统的表格来表示会很笨拙:要么得拆成 “订单表”“商品表” 多张表,靠关联字段才能体现 “订单包含商品” 的关系;要么在一张表用 “商品 1 名称、商品 1 价格、商品 2 名称……” 这类冗余字段,遇到商品数量不固定时根本没法适配;而 JSON 能直接用嵌套结构把 “订单 - 商品 - 商品属性” 的层级说清,既直观又灵活。 + +```json +{ + "order_id": 901, + "user_id": 1001, + "amount": 29.99, + "status": "completed", + "items": [ + { "sku": "BG-001", "name": "牛肉汉堡", "quantity": 1, "price": 18.00 }, + { "sku": "SD-003", "name": "炸薯条", "quantity": 1, "price": 6.99 }, + { "sku": "DK-002", "name": "可乐", "quantity": 1, "price": 5.00 } + ], + "shipping_address": { + "street": "科技园路123号", + "city": "深圳", + "zip_code": "518057" + } +} +``` + +更进一步的,如果我们考虑一个被编码成向量(Vector)的数据,向量数据通常是文本、图片或音频等非结构化数据经过 AI 模型(如 Embedding 模型)处理后得到的数值表示。它的表示形式可能是: + +`[0.123, -0.456, 0.789, ..., -0.234]` (一个由几百甚至上千个浮点数组成的数组) + +总的来说,在现实世界中有太多不同形态、用途的数据值得我们详细分析,每种数据可能都需要专门的数据库用于存储,具体可参考下图——是不是感觉非常多? + +![](/zh-cn/stage-2/backend/database-supabase/images/image1.png) + +## 1.2 为什么我们需要数据库 + +我们已经了解到真实世界中的数据往往结构复杂,**为了高效存储与使用这些数据,我们需要一个专门的程序或容器来管理它们** —— 这便是数据库(Database)的诞生初衷。数据库本质上是一款特殊程序,核心作用就是对数据进行规范化组织、安全存储、系统化管理,并支持高效查询调用。 + +想象一下,若没有数据库,应用数据会陷入怎样的困境?当用户关闭浏览器或退出应用时,所有临时加载的信息都会直接丢失;我们既无法永久保存用户的使用状态(比如登录信息、个性化设置),也没法在不同用户之间共享关键数据(比如商品库存、订单记录)。我们需要有一个装置帮我们存储所有的数据! + +更灵活的是,数据库的部署方式可按需选择:既可以部署在本地服务器,满足数据本地化管理的需求;也能部署到云端,云端数据库支持弹性扩容(Scale),可随数据量与访问量增长扩展能力、承载海量数据与高并发,即便用户量大幅提升,也能保障用户的正常使用体验。 + +归纳而言,数据库凭借高效的持久化存储、精细化管理与快速查询能力,主要解决了以下核心问题: + +- **数据的持久化存储** : 如果没有数据库,数据将仅存在于应用的内存中,一旦应用关闭,数据就会丢失。数据库解决了这个问题,它将数据持久地存储在硬盘等存储介质上,确保了数据的长期保存,降低了丢失风险。 +- **便捷的数据查询与分析** : 数据库提供了强大的查询语言(如 SQL),让用户可以轻松、高效地对海量数据进行复杂的查询、筛选和分析,从而帮助企业做出更明智的决策。 如果没有数据库,从大量无序文件中查找特定信息将是一项极其耗时且困难的任务。 +- **支持高性能与高并发访问** : 数据库通过索引优化、查询缓存、连接池以及分布式架构等技术,能够在毫秒级时间内响应查询请求,并支撑成千上万用户的并发访问。这对于现代互联网应用(如电商平台秒杀活动、社交网络实时动态)至关重要,确保了系统的响应速度和用户体验。如果没有数据库的高性能支撑,面对海量用户请求时系统将会出现严重延迟甚至崩溃。 +- **保证数据的完整性和一致性** : 数据库通过一系列机制(如约束、触发器)来确保数据的准确性和一致性。 这意味着数据库中的数据必须符合预设的规则,例如,用户的年龄必须是数字,订单号必须是唯一的,从而有效防止了非法或无效数据的产生。 +- **确保数据的安全性** : 数据库提供了强大的安全机制,包括用户身份验证、访问控制和数据加密等,以保护数据免受未经授权的访问、修改或破坏。为了应对硬件故障、人为失误或恶意攻击等意外情况,数据库还提供了数据备份和恢复功能。 通过定期备份,可以在数据丢失或损坏时及时恢复,保障了业务的连续性。 + +## 1.3 关系型数据库与非关系型数据库 + +前面我们已经了解了数据库的核心价值、部署方式与弹性优势,而在实际选择时,首先要面对的就是数据库的两大核心类别:关系型数据库与非关系型数据库(NOSQL),我们可以用简单的两段话简单理解他们的区别: + +关系型数据库就像结构严谨的Excel表格,所有数据必须预先定义好格式(定义好 Schema 的内容, 比如要有姓名和年龄,且姓名必须是文字,年龄必须是数字),并通过关联字段(用来连接不同表格的标识,如身份证号)将不同表格连接起来。它的好处是数据精确可靠,特别适合银行转账、库存管理等不能出错的场景,但缺点是调整结构比较麻烦,海量数据下性能会受限。 + +非关系型数据库则像灵活的文件夹,可以存放格式各异的文档、图片或键值对(类似字典的"词-解释"结构),不需要提前规定好每份数据的结构。它更容易应对快速变化的需求和超大规模数据(比如社交媒体的海量帖子),扩展(增加服务器提升性能)起来也更方便,但牺牲了部分关联查询能力(跨不同数据表整理信息的能力)和一致性保障(确保数据时刻准确不矛盾),适合对容错性要求较高的互联网应用。 + +那么,实际应用中该如何选择数据库?从场景划分总结来看,关系型数据库常见于金融交易、库存管理、订单处理、账务系统等需要强一致性、复杂事务处理以及频繁读写均衡访问的场景;而非关系型数据库更适配社交媒体内容存储、实时日志分析、物联网海量数据写入、推荐系统特征读多写多等高并发、读写模式不均衡且结构灵活的需求。 + +但对于企业而言,在初级阶段并不需要花大量时间思考什么需要使用什么数据库。当前的数据库已是非常成熟的产品服务,最直接的方式是咨询不同云服务厂商(指提供服务器、存储、数据库、软件、算力等 IT 资源与技术服务的服务商)。我们可直接对接云服务官方销售,根据自身产品业务需求匹配适配的数据库方案;而构建企业级应用的便捷路径,便是优先与专业厂商合作。(需注意:企业级服务价格通常较高,建议先多方调研对比,也可选择购买服务器自行部署开源数据库程序作为替代方案。) + +我们也可参考某家云厂商的[数据库选型推荐](https://help.aliyun.com/zh/govcloud/getting-started/select-database-services),根据场景可进行不同数据库类型的选择,你可以对比不同云厂商的数据库规格选出最合适的进行使用。 + +| 数据库类型 | 数据库名称 | 价格 | 适用场景 | +| ------------ | ---------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 关系型数据库 | RDS MySQL版 | 低 | 基础版:学习以及小型网站高可用版:一定业务压力的中型数据库场景集群版:业务不允许中断,访问压力较大 | +| | RDS SQL server版 | 高 | 基础版:测试以及小型商业化网站高可用版:企业级商业化网站集群版:企业业务不允许中断,访问压力较大 | +| | RDS PostgreSQL版 | 最低 | 基础版:学习以及小型网站高可用版:一定业务压力的中型数据库场景集群版:业务不允许中断,访问压力较大的场景,其性能较一般MySQL高 | +| | RDS PPAS版 | 高 | 通用型:兼容Oracle业务,但业务压力Udacity,虚拟化可以满足其需求独享型:面对需要独享物理机的业务,一般为高并发Oracle类业务 | +| | DRDS | 中 | 入门版本:4 Core 8 G,价格亲民,适合中小型在线业务企业版:16 Core 32 G,复杂 SQL 响应好,适合超高并发在线业务至尊版:32 Core 64 G,复杂 SQL 执行响应最好,提供超大规格选择 | +| NoSQL数据库 | Redis | 中 | 双机热备Redis:一般作为持久化数据库提高业务可用性集群版本的Redis:一般作为缓存层,加速应用访问,解决一般数据库无法负载的读取压力 | +| | MongoDB版 | 中 | 单节点实例单节点:适用于开发、测试及其他非企业核心数据存储的场景副本集实例:适用于某些业务场景下对数据库有更高读取性能需求,如阅读类网站、订单查询系统等读多写少场景或有临时活动等突发业务需求分片集群实例:基于多个副本集(每个副本集沿用三副本模式)组成的分片集群实例,提供更高的读取性能需求,为实时在线业务提供高速读取性能 | + +光说不易理解,我们通过一个具体的“博客文章”场景,来看看同样的数据在关系数据库 (SQL) 和不同类型的非关系数据库 (NoSQL) 中是如何存储的。 + +假设我们有一个博客平台,需要存储以下信息: + +- 用户(Users):用户 ID、用户名、邮箱 +- 文章(Posts):文章 ID、标题、内容、作者 ID +- 评论(Comments):评论 ID、评论内容、评论者 ID、所属文章 ID +- 标签(Tags):标签 ID、标签名 +- 文章与标签的关系:单篇文章关联的多个标签、单个标签对应的多篇文章 + +### 关系数据库 (SQL) 示例 + +在SQL数据库中,我们会将不同类型的数据分别存储在不同的表中,并通过“外键”将它们关联起来。这种结构清晰、规范,减少了数据冗余。 + +以 “内容平台的文章管理” 为例,我们不会把 “用户、文章、评论、标签” 混存,而是拆成 5 张功能单一的表,每张表都有明确的 “职责边界” 和严格的结构定义(Schema): + +- `users` 表 (存储用户信息) + +| user_id (主键) | username | email | +| -------------- | -------- | ----------------- | +| 101 | Alice | alice@example.com | +| 102 | Bob | bob@example.com | + +- `posts` 表 (存储文章信息) + +| post_id (主键) | title | content | author_id (外键) | +| -------------- | --------- | ------------------------------ | ---------------- | +| 1 | 初识SQL | 这是关于SQL数据库的一篇文章... | 101 | +| 2 | NoSQL入门 | NoSQL提供了灵活的数据模型... | 102 | + +- `comments` 表 (存储评论信息) + +| comment_id (主键) | body | commenter_id (外键) | post_id (外键) | +| ----------------- | ---------------- | ------------------- | -------------- | +| 1001 | 写得很棒! | 102 | 1 | +| 1002 | 学习了。 | 101 | 2 | +| 1003 | 有没有更多例子? | 101 | 1 | + +- `tags` 表 (存储标签) + +| tag_id (主键) | tag_name | +| ------------- | -------- | +| 51 | 数据库 | +| 52 | 技术 | +| 53 | 入门 | + +- `post_tags` 表 (存储文章与标签的多对多关系,体现联表特点) + +| post_id (外键) | tag_id (外键) | +| -------------- | ------------- | +| 1 | 51 | +| 1 | 52 | +| 2 | 51 | +| 2 | 52 | +| 2 | 53 | + +若需查询 “Alice 发表的《初识 SQL》(post_id=1)的完整信息(含文章内容、作者、评论、标签)”,需执行多表连接(JOIN)查询,通过外键关联 5 张表并聚合数据,SQL 语句如下: + +```sql +SELECT + p.title, + p.content, + u.username AS author, + c.body AS comment, + t.tag_name AS tag +FROM + posts p +JOIN + users u ON p.author_id = u.user_id +LEFT JOIN + comments c ON p.post_id = c.post_id +LEFT JOIN + post_tags pt ON p.post_id = pt.post_id +LEFT JOIN + tags t ON pt.tag_id = t.tag_id +WHERE + p.post_id = 1; +``` + +这个查询会跨越5个表,将所有相关数据聚合在一起返回。这是关系数据库的核心优势:通过规范化和连接操作,可以灵活地进行各种复杂的查询,同时保证了数据的一致性和最小冗余。 + +### 非关系数据库 (NoSQL) 示例 + +NoSQL 数据库(如 MongoDB、Redis)的设计思路与 SQL 相反,它不强调数据的拆分与规范,通常会将业务上相关联的所有数据打包聚合在一起,以减少查询时的连接操作,从而提高读取性能。 + +在 NoSQL 数据库中,文档数据库(Document Database) 是最常用的类型之一,MongoDB 就是典型代表。它以 “文档” 作为基本存储单元,这里的 “文档” 并非我们日常理解的 “文章”,而是一种类似 JSON 的数据结构(MongoDB 中实际使用 BSON 格式,支持更多数据类型):无需预先定义统一的 Schema(数据结构),每个文档的字段可以灵活增减,字段类型也能自由调整,完美适配数据格式多变的场景。 + +在文档数据库中,通常会将一篇文章及其所有相关信息(如评论、标签)存储在一个文档中(文档格式类似 JSON,可灵活定义字段,无需预先制定 Schema),核心逻辑是 “将‘一个业务场景下的完整信息’存放在一个文档中”,避免查询时的多数据源拼接。 + +`posts` 集合中的一个文档示例: + +```json +{ + "_id": 1, + "title": "初识SQL", + "content": "这是关于SQL数据库的一篇文章...", + "author": { + "user_id": 101, + "username": "Alice", + "email": "alice@example.com" + }, + "tags": [ + "数据库", + "技术" + ], + "comments": [ + { + "comment_id": 1001, + "body": "写得很棒!", + "commenter": { + "user_id": 102, + "username": "Bob" + } + }, + { + "comment_id": 1003, + "body": "有没有更多例子?", + "commenter": { + "user_id": 101, + "username": "Alice" + } + } + ] +} +``` + +这种设计的优势非常直观:当你需要获取 “第一篇文章的完整信息(含作者、评论、标签)” 时,只需通过 `_id:1` 查询这一个文档,数据库一次读取就能返回所有数据,无需像 SQL 那样执行 3-4 次表连接操作,读取效率大幅提升。 + +但它也存在明显的 trade-off(取舍):由于数据是 “聚合存储”,会不可避免地产生数据冗余—— 比如作者 “Alice” 的 `username` 被嵌入到她写的每一篇文章文档中,如果某天 “Alice” 将用户名改为 “Alice_New”,理论上需要遍历所有包含她信息的文章文档,逐一更新 `author.username` 字段,不仅操作繁琐,还可能因网络或服务器问题导致部分文档更新失败,出现 “同一用户在不同文章中用户名不一致” 的情况。 + +不过在实际业务中,这种冗余往往是 “可接受的”:对于博客、资讯、电商商品详情等 “ **读多写少** ” 的场景(用户查看内容的次数远多于作者修改用户名的次数),用少量的冗余换取 “极致的读取性能” 是更优的选择;而如果是 “写多读少”(如频繁修改用户信息)的场景,则需要结合业务需求权衡是否使用文档数据库。 + +以上是对不同数据库的简单介绍,如果你对更多具体的数据库类型感兴趣,你可以参考如下资料尝试不同类型的数据库。 + +Examples of SQL databases: +[Db2](https://www.ibm.com/products/db2-database)、[MySQL](https://cloud.ibm.com/catalog#highlights)、[PostgreSQL](https://www.ibm.com/think/topics/postgresql)、[YugabyteDB](https://www.yugabyte.com/)、[CockroachDB](https://www.cockroachlabs.com/)、[Oracle Database](https://www.ibm.com/products/postgres-enterprise)、[Azure SQL Database](https://www.ibm.com/consulting/microsoft) + +Examples of NoSQL databases: +[Redis](https://www.ibm.com/think/topics/redis)、[CouchDB](https://www.ibm.com/think/topics/couchdb)、[MongoDB](https://www.ibm.com/think/topics/mongodb)、[Cassandra](https://cloud.ibm.com/catalog#highlights)、[Elasticsearch](https://www.ibm.com/think/topics/elasticsearch)、[BigTable](https://www.techtarget.com/searchdatamanagement/news/252512583/Google-scales-up-Cloud-Bigtable-NoSQL-database)、[Neo4j](https://neo4j.com/users/ibm/)、[HBase](https://www.ibm.com/think/topics/hbase) + +# 2. Supabase + +在前面我们已经介绍了几类常见的数据库,以及它们各自适合的使用场景。不过在真实项目里,数据库通常只是后端体系中的一个基础模块:除了存储和查询数据,你还需要解决**用户注册登录、权限校验、文件上传与存储、对外 \*\***API\***\* 接口、甚至定时任务、实时通知**等一整套问题。仅仅选好数据库,并不能让你的应用“立刻就能上线运行”,中间还隔着一大圈繁琐的后端工程工作。 + +所以,我们需要考虑一个更大的背景: **后端服务** 。一个完整的应用,通常都由“前端 + 后端”组成:前端负责页面展示和用户交互,后端则负责数据存储、用户登录、业务逻辑处理等。过去,开发者往往需要自己搭建服务器、配置数据库、设计并实现 API,还要手动处理权限管理、安全策略、扩展性和监控运维等事务,整个过程既重复又耗时。为了解决这些重复劳动,业界出现了 **BaaS(Backend as a Service,后端即服务)** :把数据库、用户认证、文件存储、实时能力等常见后端功能打包成一个云端平台,开发者通过 SDK / API 就能直接调用这些能力,而无需从零搭建和运维基础设施。 + +在这个背景下,[Supabase](https://supabase.com/) 就可以看作是新一代的 BaaS 代表:它以 PostgreSQL 作为核心数据库,在其之上集成了 Auth、Storage、Realtime、Edge Functions、Vector 等一整套后端能力,为开发者提供一个“以 Postgres 为中心的一站式后端平台”。接下来,我们就从这个角度出发,从“只选数据库”升级到“选择完整的后端开发平台”,具体看看 Supabase 能帮我们省掉哪些工作,又是如何让一个项目从原型到可用产品的距离大幅缩短的。 + +## 2.1 分步指南 + +在清晰把握 Supabase 的整体定位后,接下来我们将沿着 Supabase 控制台的操作路径,逐项拆解它具体提供哪些核心能力,以及每项能力对应的核心职责。我们会详细介绍 supabase 涉及的每个选项,帮助你快速入门 supabase 的基本操作。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image2.png) + +访问 Supabase 官网并登录后,在控制台首页点击 New project 进入创建流程; + +输入需要配置的主要内容 Project Name、数据库密码,地址只需要选择为与程序目标用户最接近的区域即可。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image3.png) + +创建成功后,控制台左侧侧边栏将显示所有核心功能模块(Table Editor、SQL Editor、Database、Authentication 等),后续操作将围绕这些模块展开。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image4.png) + +### 表编辑器 + +Table Editor 可以当成是 Supabase 的可视化数据表编辑器,它能让你像操作 Excel 一样直接查看和修改数据库里的数据,无需编写 SQL 语句,只需要用鼠标交互即可修改数据内容。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image5.png) + +其中值得关注的是 Schema,Schema 可理解为数据库内的 “资源容器”,用于对表、视图、函数、索引等资源进行分组管理,主要作用有二:一是避免命名冲突(不同 Schema 下可存在同名table),二是实现权限隔离(如仅允许特定用户访问某 Schema 下的表); + +点击编辑器顶部的 Schema 下拉框可切换不同容器,日常开发中一般只需关注两类: + +- `public`:默认的公共资源容器,开发者新建的业务表(如 “文章表”“评论表”)均存储于此; +- `auth`:用户认证专属容器,其中的 `users` 表自动存储所有注册用户信息(如用户 ID、邮箱、登录时间),不建议手动修改此 Schema 下的默认表,避免影响认证功能; + +![](/zh-cn/stage-2/backend/database-supabase/images/image6.png)![](/zh-cn/stage-2/backend/database-supabase/images/image7.png) + +### SQL 编辑器 + +SQL Editor 作为 Supabase 的 SQL 语句执行器,可让你用代码的方式直接操作数据库。你可以让大模型直接生成 SQL 语句,在右侧输入后点击 RUN 即可用语句创建或修改 table,也可以直接在 Results 中直接看到筛选出的 table 数据。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image8.png) + +你可以在运行 RUN 之后,在 Table Editor 的 public schema 里找到新建后的数据表;并且运行后的语句会保存在左侧的 PRIVATE 栏中,甚至可以点击下方的爱心标志对这一条查询或创建语句进行收藏。 + +### 数据库管理中心 + +Database 是 Supabase 的数据库管理中心,支持可视化地查看和管理所有数据表,并通过表的相互连线理解不同表间的关联关系(即外键约束,表示数据间的引用关系)。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image9.png) + +如果你想要手动新建 table,可以在 tables 中直接新建表格,我们会在之后的教程中详细讲解。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image10.png) + +### 身份认证 + +Authentication 负责管理用户的注册、登录和权限。默认的用户管理系统数据都在此处存储,它提供了开箱即用的用户注册、登录、密码重置、邮箱验证等功能,并支持第三方 OAuth 登录(如微信、GitHub、Google 等)。所有用户数据会自动同步到数据库的 `auth.users` 表中。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image11.png) + +你可以在 Provider 选项中找到不同 supabase 支持的用户信息登录入口,默认使用 Email;如果你想使用 Github 或者 Google 账户进行登录,还需要更多属性配置,我们会在下面的课程中进行详细讲解。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image12.png) + +在 Sign In / Providers 里还包含了对注册邮箱行为的控制,如果你不想每次邮箱注册都必须让用户接受邀请后才能成为用户,你可以取消 Confirm email 的强制要求。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image13.png) + +如果你想切换非 Supabase 的其他 auth 系统服务商,你可以点击 Third Party Auth,比如此处就使用 Clerk 作为第三方的系统服务商。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image14.png) + +如果你担心注册用户在短期内访问量过大,你可以在 Rate Limits 中启用对应的流量限制策略: + +![](/zh-cn/stage-2/backend/database-supabase/images/image15.png) + +### 存储 + +Storage 是 Supabase 的存储系统,兼容 amazon cloud 的 s3 概念,可用于存储任意类型的文件(如图片、视频、文档、音频等),并提供访问权限管理(公开或私有)和下载链接获取(永久链接或临时链接),你能够很方便在应用中对用户涉及到的文件内容进行上传与下载管理,并与 Supabase 的认证系统无缝集成,实现精细化的访问控制。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image16.png) + +我们将会在本节课的进阶 project 中讲解 storage 的具体用法。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image17.png) + +如果你想使用 S3 的相关协议进行操作,可以直接使用对应的配置: + +![](/zh-cn/stage-2/backend/database-supabase/images/image18.png) + +> Amazon Cloud(亚马逊云服务,简称 AWS)是亚马逊提供的云计算平台(就像一个大型的网络机房,你可以按需租用计算和存储资源)。S3(Simple Storage Service)是 AWS 里专门用来存储文件的服务(类似一个无限大的网盘,可以存图片、视频、备份等各种文件),它是目前最流行的对象存储服务,已经成为了事实上的行业标准。 +> +> **为什么要做成 S3 兼容 \*\***API\*\* ** ?** :S3 已经存在近 20 年,市面上有大量现成的工具、SDK 和文档,兼容 S3 意味着你可以直接用这些资源,不用从头开始制作各类相关工具,能够快速满足业务上线的需求。 + +### 边缘函数 + +如果你不想部署后端,但是想使用数据库和函数操作,你可以使用 Edge Functions 构建无需自建服务器的后端核心能力,它是 Supabase 提供的全球分布式服务端函数。简单来说,它让你无需购买和管理自己的后端服务器,就能直接编写并部署在云端的后端代码。这些函数部署在全球网络的边缘节点上,会自动在离你的用户最近的位置运行,从而大幅降低网络延迟,提供极致的响应速度。你可以在 Supabase 的仪表盘中直接创建、编辑和部署,整个开发流程非常便捷。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image19.png) + +Edge Functions 的一个核心用途是充当安全的中间层,保护你的敏感信息和鉴权密钥。在前端代码中直接调用第三方服务(如 OpenAI、Stripe)会暴露你的 API Key,带来极大的安全风险。通过 Edge Functions,你的前端应用只与你的 supabase 函数通信,所有秘密只在 supabase 中保管。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image20.png) + +Edge Functions 的函数使用 secrets 中暴露的密钥作为环境变量,通过 `Deno.env.get` 加载,从而实现第三方服务的调用。这样一来,敏感密钥就永远不会暴露在客户端(你的浏览器),彻底杜绝了被盗用的风险。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image21.png) + +请求 Supabase Edge Function 时,需在请求头携带对应的 Supabase 密钥,下面是一个极简示例: + +```javascript +// 核心配置(替换为你的实际信息) +const projectId = "你的 Supabase 项目ID"; +const functionName = "目标 Edge Function 名称"; +const supabaseKey = "Supabase anon_key"; + +// 调用函数 +async function callEdgeFunction() { + const url = `https://${projectId}.supabase.co/functions/v1/${functionName}`; + + try { + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${supabaseKey}` // 关键:携带密钥完成认证 + }, + body: JSON.stringify({ order_id: "123", action: "refund" }) // 自定义请求数据 + }); + + const result = await response.json(); + console.log("调用成功:", result); + } catch (error) { + console.error("调用失败:", error.message); + } +} + +// 执行调用 +callEdgeFunction(); +``` + +此外,Edge Functions 与 Supabase 的用户认证系统无缝集成。当已登录的用户调用一个函数时,其身份信息会传递给函数。这使得你可以在函数内部轻松识别当前用户,并根据其身份执行权限控制。更重要的是,函数在操作数据库时会自动遵循你设置好的行级安全策略(Row Level Security),确保用户只能访问和修改他们有权操作的数据,让构建安全的多用户应用变得简单。 + +Edge Functions 的应用场景非常广泛,能够处理各种后端任务。它们非常适合用来监听来自第三方服务的 Webhook 事件(例如支付成功、代码提交等),并自动执行相应的数据处理逻辑。你也可以用它来发送邮件通知、生成 PDF 报告、创建自定义的 API 接口来封装复杂的业务逻辑,或者执行任何你希望在服务端完成的计算任务,极大地扩展了你应用的能力。 + +具体到一个常见的例子:身份认证工具 Clerk 。Clerk 仅用于处理用户登录、注册、信息更新等认证相关操作,并不直接管理你的业务数据库。如果你想要将这些认证动态同步到业务数据库中,则需要通过触发 Webhook 事件请求 Edge Functions 实现。Edge Functions 能够监听 Clerk 发出的 Webhook 信号,自动执行数据同步逻辑,让 Supabase 数据库中的用户信息与 Clerk 登录状态实时对齐,全程无需你部署独立后端。 + +### 实时数据同步引擎 + +Realtime 是 Supabase 的实时数据同步引擎,它允许你的应用即时接收数据库的变化通知,而无需反复轮询 API。当数据库中的数据发生 `INSERT`、`UPDATE` 或 `DELETE` 操作时,Realtime 会通过 WebSocket 将这些变化实时推送给所有已连接的客户端。这对于构建需要实时交互的应用至关重要。 + +Realtime 主要包含三大核心功能,覆盖了绝大多数实时场景: + +1. **Postgres Changes:** 直接监听数据库表的变化。你可以精确地订阅特定表、特定事件(增、删、改),甚至可以根据筛选条件来接收通知,并与行级安全策略(Row Level Security)完美集成,确保用户只能收到他们有权限查看的数据变更。 +2. **Broadcast:** 允许客户端之间通过频道(Channel)发送低延迟的临时消息。这非常适合实现聊天室、实时光标追踪、在线游戏状态同步等功能。 +3. **Presence:** 用于追踪和同步在线用户状态。你可以用它来轻松实现“谁在线上”、“当前有X人正在查看”等功能,非常适合协作类应用。 + +我们会在后续的项目制学习中详细介绍该部分的内容。 + +### 项目设置 + +Project Settings 是 Supabase 项目的高级配置部分,你可在此实现计算资源的深度调度,以及各类功能底层参数的精细化配置。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image22.png) + +在入门阶段,我们只需聚焦以下两个核心板块,一个是 Data API,我们在此可获取关键的 “Supabase URL”, 它是形如 `https://xxx.supabase.co` 的 RESTful 端点,是所有数据查询、新增、修改、删除操作的 “入口地址”。前端或服务端需通过该 URL 初始化 Supabase 客户端,建立与数据库的连接。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image23.png) + +另一个重点是 API Keys,选择 “Legacy anon, service_role API keys” 标签页,其中的 anon public 密钥 是前端场景的重要身份凭证,它的权限被 RLS 严格限制,仅能访问用户被授权的数据。而 service_role 密钥属于 “服务端高权限密钥”,具备绕过行级安全的能力,可执行批量数据操作、系统级配置等敏感操作。绝对禁止公开分享,若泄露需立即生成新密钥并更新服务端配置。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image24.png) + +其余配置项在当前阶段无需深究,待后续有进阶使用需求时再逐一探索即可。 + +## 2.1 创建你的第一个 SQL 数据表 + +以上是 Supabase 的界面介绍,接下来我们将深入 Supabase 的核心数据库的操作环节。 + +在 Supabase 中创建数据表,主要有以下两种常用方式,你可以根据需求选择: + +1. (推荐)借助大语言模型生成适配 Supabase 的 SQL 语句,直接在 **SQL Editor(** 前文介绍的 SQL 语句执行器)中粘贴执行,高效快捷,我们会在下个部分环节重点说明这个操作过程。 +2. 通过可视化操作创建:在左侧侧边栏找到 Database 模块,点击进入后选中侧边栏的 Tables,在右侧点击 New table 按钮,即可通过图形化界面创建数据表。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image25.png) + +值得注意的是,对应数据表的名称以及存储的数据类型可在下方的 Columns 中指定。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image26.png) + +对于关系数据库,其中很重要的特点是表与表之间的关联,你可以在下方找到 `Foreign keys` ,点击创建相应的关联关系: + +![](/zh-cn/stage-2/backend/database-supabase/images/image27.png) + +其中 `Foreign keys` 表达了表与表之间的关联关系:一个或一组字段,它在当前表(子表)中的值,会引用另一张表(父表)中主键的值。 + +例如,在创建 `学生表`的时候,我们可以这样定义外键:(`所属班级编号` 这一列是一个外键。这个外键引用了 `班级表` 里的 `班级编号` 这一列。) + +```sql +CREATE TABLE 学生表 ( + 学生学号 INT PRIMARY KEY, + 学生姓名 VARCHAR(50), + 所属班级编号 INT, + FOREIGN KEY (所属班级编号) REFERENCES 班级表(班级编号) +); +``` + +更具体举例而言,我们可以可视化观察对应的表的结构: + +班级表: +这张表里记录了所有班级的信息,每个班级都有一个独一无二的班级编号。班级编号就是这张表的主键 (Primary Key),是每个班级的唯一身份证。 + +| 班级编号 | 班级名称 | +| -------- | ---------- | +| 101 | 一年级一班 | +| 102 | 一年级二班 | + +学生表: +这张表记录了所有学生的信息。每个学生都属于一个特定的班级,对吗?那么我们怎么知道哪个学生在哪个班级呢? + +我们可以在学生表里增加一列,叫做 `所属班级编号`。 + +| 学生学号 | 学生姓名 | 所属班级编号 | +| -------- | -------- | ------------ | +| 2024001 | 张三 | 101 | +| 2024002 | 李四 | 102 | +| 2024003 | 王五 | 101 | + +在该例子中,学生表中的 `所属班级编号` 列就是外键 (Foreign Key)。 + +在 Supabse 中,点击添加 Foreign Key 后,你可直接选择进行关联表对应列的选取 + +![](/zh-cn/stage-2/backend/database-supabase/images/image28.png) + +## 2.3 SQL Editor 简介与数据库基本操作 + +接下来我们将分步执行一系列 SQL 脚本,熟悉常见的 SQL 中的增删查改操作。你可以将每个步骤的代码复制到 SQL Editor 中,执行并观察结果。 + +你可以在该目录下获得所有的测试 SQL 文件: + +https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos/tree/main/apps/sql-examples + +### **2.3.1 **`CREATE`** - 创建表结构** + +`CREATE TABLE` 语句用于为新表定义模式(Schema),包括其列(Columns)、对应的数据类型(Data Types)以及任何约束(Constraints),简单理解是创建了一个数据表。 + +```sql +-- Step 1: Create the 'orders' table +-- This file is fully independent and creates a sample table for later steps. +CREATE TABLE IF NOT EXISTS orders ( + id serial PRIMARY KEY, + user_id int NOT NULL, -- User ID + status text NOT NULL, -- Order status (e.g. paid, pending) + amount numeric(10, 2) NOT NULL, -- Order total amount + details jsonb, -- Item and extra details as JSON + placed_at timestamptz DEFAULT now(), -- Order creation time + is_paid boolean DEFAULT false -- Paid flag +); + +-- Expected Output: +-- Orders table created if it did not exist. +-- No data inserted. (Querying returns zero rows for now.) +-- If table already exists, no error occurs. +``` + +成功执行后,系统将提示脚本已完成。你可以在 Table Editor 中看到对应的表被创建完成: + +![](/zh-cn/stage-2/backend/database-supabase/images/image29.png) + +### **2.3.2 **`INSERT`** - 填充初始数据** + +表结构创建完毕后,下一步是使用 `INSERT INTO` 语句向表中添加数据行。 + +```sql +-- Step 2: Insert initial rows into the orders table +-- Provides realistic, varied data for demo/testing. All values are self-contained. +INSERT INTO orders (user_id, status, amount, details, placed_at, is_paid) VALUES + (2001, 'pending', 23.50, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '2 days', false), + (2002, 'paid', 50.00, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":2,"price":5.00}]}', now() - interval '1 day', true), + (2003, 'cancelled', 15.00, '{"items":[{"sku":"FRY001","name":"French Fries","qty":3,"price":5.00}], "reason":"Not available"}', now() - interval '45 days', false), + (2004, 'paid', 22.98, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":2,"price":9.99}], "promo":"SUMMER22"}', now() - interval '10 days', true), + (2005, 'pending', 18.75, '{"items":[{"sku":"SAL001","name":"Salad","qty":1,"price":6.75},{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '7 hours', false), + (2006, 'paid', 8.00, '{"items":[{"sku":"DRK002","name":"Cola","qty":2,"price":4.00}]}', now() - interval '3 hours', true), + (2007, 'refunded', 14.50, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99},{"sku":"FRY001","name":"French Fries","qty":1,"price":4.51}], "refund_reason":"Late delivery"}', now() - interval '15 days', false), + (2008, 'paid', 26.99, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":1,"price":6.99}]}', now() - interval '12 days', true), + (2009, 'pending', 9.99, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99}]}', now() - interval '30 minutes', false), + (2010, 'paid', 19.89, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00},{"sku":"DRK002","name":"Cola","qty":2,"price":3.95}]}', now() - interval '5 days', true), + (2011, 'cancelled', 0.00, '{"items":[], "reason":"User cancelled"}', now() - interval '2 days', false); + +-- Expected Output: +-- After running this script, SELECT * FROM orders will show about 11 rows with varied user_id, status, amount, details (JSON), placed_at, and is_paid fields. +-- For example: +-- | id | user_id | status | amount | is_paid | placed_at | +-- |----|---------|-----------|--------|---------|---------------------| +-- | 1 | 2001 | pending | 23.50 | false | 2025-10-28 13:40:00Z| +-- | 2 | 2002 | paid | 50.00 | true | ... | +-- |... | ... | ... | ... | ... | ... | +``` + +执行成功后,此时表中已经插入了原始数据,你可以进入到 Table Editor 界面刷新后看到结果,也可以直接在 SQL Editor 界面中新建窗口,执行查询语句 `SELECT * FROM orders;`查看结果: + +![](/zh-cn/stage-2/backend/database-supabase/images/image30.png) + +### **2.3.3 **`SELECT`** - 读取与查询数据** + +`SELECT` 语句用于从表中检索数据。通过使用不同的子句,可以实现对数据的精确筛选、排序和格式化,我们可参考以下语句一步步执行查看结果: + +```sql +-- Step 3: SELECT query examples for the orders table + +-- Example 1: Select all fields for all orders +SELECT * FROM orders; +-- Expected Output: Returns all rows and fields. Columns: id, user_id, status, amount, details, placed_at, is_paid. + +-- Example 2: Select only pending orders +SELECT id, user_id, amount FROM orders WHERE status = 'pending'; +-- Expected Output: All rows with status 'pending'; columns: id, user_id, amount. + +-- Example 3: Select specific fields and filter by payment status +SELECT id, status, is_paid, amount FROM orders WHERE is_paid = true; +-- Expected Output: All rows where is_paid is true; columns: id, status, is_paid, amount. + +-- Example 4: Extract all item names from the details (JSON) for each order +SELECT id, details -> 'items' AS item_list FROM orders; +-- Expected Output: Each row shows id and an array from JSON with item details. +``` + +- **示例 1:** 返回 `orders` 表中的所有行和列,与第二步的输出类似。 +- **示例 2:** 仅返回状态为 'pending' 的订单,且只包含指定的列: + +![](/zh-cn/stage-2/backend/database-supabase/images/image31.png) + +- **示例 3:** 仅返回已支付的订单,并显示指定的列: + +| id | status | is_paid | amount | +| --- | ------ | ------- | ------ | +| 2 | paid | true | 50.00 | +| 4 | paid | true | 22.98 | +| 6 | paid | true | 8.00 | +| 8 | paid | true | 26.99 | +| 10 | paid | true | 19.89 | + +- **示例 4:** 返回每个订单的 `id` 和从 `details` 字段中提取的 `items` 数组: + +| id | item_list | +| --- | -------------------------------------------------------------------------------------------------------------------- | +| 1 | `[{"qty":1,"sku":"BGR001","name":"Beef Burger","price":12}]` | +| 2 | `[{"qty":2,"sku":"BGR002","name":"Chicken Burger","price":10},{"qty":2,"sku":"DRK001","name":"Lemonade","price":5}]` | +| 3 | `[{"qty":3,"sku":"FRY001","name":"French Fries","price":5}]` | +| ... | ... | + +### **2.3.4 **`INSERT`** - 插入单条记录** + +在 2.3.2 中,我们演示的是开头时刻初始化批量插入数据,现在我们查看如何新增插入单条数据。 + +```sql +-- Step 4: INSERT a new order (single row) +-- Example: Add a new paid order for user 2012 with one Chicken Burger +INSERT INTO orders (user_id, status, amount, details, is_paid) +VALUES ( + 2012, 'paid', 9.99, + '{"items":[{"sku":"BGR002","name":"AIID Burger","qty":100,"price":1000}]}', + true +); +-- Expected Output: +-- Before (table fragment): +-- | id | user_id | status | amount | is_paid | +-- | ...| ... | ... | ... | ... | +-- +-- After (last row): +-- | id | user_id | status | amount | is_paid | +-- | xx | 2012 | paid | 9.99 | true | +-- (where xx = next serial value) +``` + +此时再用 `SELECT * FROM orders;` 对数据进行查询,我们可以看到 orders 表成功从 11 个数据变成了 12 个数据。 + +### **2.3.5 **`UPDATE`** - 修改现有数据** + +在实际工作中,我们需要对数据表进行频繁数据更新,我们能够用 `UPDATE` 语句修改表中已存在的记录。 + +```sql +-- Step 5: UPDATE example +-- Example: Mark order with id=1 as paid and update its status +UPDATE orders SET status = 'paid', is_paid = true WHERE id = 1; +-- Expected Output: +-- Before (row with id=1): +-- | id | status | is_paid | +-- | 1 | pending | false | +-- After (row with id=1): +-- | id | status | is_paid | +-- | 1 | paid | true | +-- All other rows remain unchanged. +``` + +### **2.3.6 **`DELETE`** - 删除数据** + +`DELETE` 语句可用于从表中移除记录,并结合条件对指定部分的数据进行修改。 + +```sql +-- Step 6: DELETE example +-- Example: Delete orders older than 2 days to clean up old data +DELETE FROM orders WHERE placed_at < now() - interval '2 days'; +-- Expected Output: +-- Before (filtered for affected rows): +-- | id | status | placed_at | +-- | 3 | shipped | 2025-10-13 ... | <-- will be deleted +-- +-- After: +-- No such rows remain. SELECT * FROM orders WHERE placed_at < now()-interval '2 days' yields zero rows. +-- Other rows in orders table are unaffected. +``` + +执行前,你可先执行 `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';` 进行数据表筛选结果的查看。当运行 `DELETE` 命令后,再次执行相同的 `SELECT` 查询 `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';`,将返回一个空的结果,表明这些行已被成功删除。 + +## 2.4 行级安全 + +在学习了数据库的基本操作后,我们需要进一步深入一个保障数据安全的核心概念 ——RLS(行级安全,Row Level Security)。 + +不妨先思考一个实际场景中的关键问题:如何实现数据的 “隔离访问”?比如,只允许用户 A 查看自己的数据,而无法看到用户 B 的信息;再比如,即便某角色拥有数据库的访问权限,如何避免其误操作或泄露其他用户的敏感数据? + +RLS 正是为解决这类数据安全与隔离需求而生。它允许开发者为数据库表定义精细化的安全策略,根据用户的身份信息(如用户 ID、角色权限等),精确控制哪些用户能访问、修改表中的哪些行数据。 +举个典型示例:对于订单表(`orders`),我们可以定义这样一条 RLS 策略 ——“仅当 `orders` 表中某条记录的 `user_id` 列,与当前登录用户的 ID 完全一致时,该用户才能查询到这条订单数据”,从而实现 “用户只能看自己的订单” 的核心需求。 + +当你为某张表启用 RLS后,该表的所有数据操作请求(包括 `SELECT` 查询、`INSERT` 新增、`UPDATE` 修改、`DELETE` 删除)都会触发 RLS 校验:必须通过至少一条安全策略的检查,操作才能执行。若不存在允许该操作的策略,或请求未满足任何策略的条件,数据库会直接拒绝此次操作,从底层阻断非授权访问。 + +在 Supabase 中,RLS 与用户认证系统深度绑定,使用起来更为便捷。Supabase 提供了一个专用函数 `auth.uid()`,它能直接返回 “当前发起请求的已登录用户” 的唯一 ID(格式为 UUID)。借助这个函数,我们可以轻松编写策略,实现 “数据行与用户身份” 的精准关联(比如前文提到的 “订单 `user_id` 匹配当前用户 ID”)。 + +启用 RLS 策略的方式很灵活,你可以在 Supabase 数据库管理界面中的 “RLS” 按钮,直接配置并启用策略: + +![](/zh-cn/stage-2/backend/database-supabase/images/image32.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image33.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image34.png) + +主动配置难免显得麻烦,通常,我们在数据表语句创建、初始化的时候就会自动考虑植入对应的 RLS 策略。我们只需在 SQL Editor 中执行类似如下语句,即可自动开启对应数据表的行级安全策略。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image35.png) + +# 3. 第一个 SQL 应用 + +掌握了数据库基础操作与RLS核心逻辑,我们终于进入本次教程的实践环节。漫长的学习铺垫是为了让后续“从0到1搭建应用”的过程更清晰。接下来,我们将以“汉堡店订单管理”为场景,手把手演示Supabase的常见操作:从应用与Supabase的关联配置,到数据库与登录功能的集成,逐步学习不同操作逻辑。 + +## 3.1 克隆并运行 Supabase 示例项目 + +要开展实操,首先需要获取配套的演示代码仓库。你可以让 Trae 或 Claude Code 协助 git clone 以下仓库:https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos + +若已配置 SSH 密钥,建议使用 SSH 地址进行 clone(git@github.com:THU-SIGS-AIID/Project5-Supabase-Demos.git)以提升安全性;若 SSH 或 HTTPS 连接遇到网络问题,可以直接点击仓库页面的 “Download ZIP”,获取压缩包后解压即可看到完整代码。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image36.png) + +Clone 后,你同样可以让 Trae 或者是 Claude Code 帮你启动项目,例如直接在 Agent 界面中说明: `帮我直接启动这个项目里面的 project 1 `,或者复制对应想启动 project 的绝对路径,粘贴给大模型让大模型直接启动。 + +## 3.2 项目1 - 汉堡店菜单增删改查 + +接下来进入实操环节 —— 以 `project-burger-shop-menu-crud-1` 为例,我们将学习如何通过 SQL 脚本一键初始化 Supabase 数据库,并完成本地项目与 Supabase 数据库的关联配置,让前端能正常读写菜单数据。 + +### 使用脚本创建数据库 + +首先,我们需要在 Supabase 中创建需要的数据表的相关内容。进入 Project1 项目目录看到名为 `scripts`的文件夹,其中包含 1 个 `init.sql`数据库脚本文件,它能帮我们自动完成所有数据库相关资源的创建(包括表结构、初始数据等),之后我们会经常用到该文件进行数据库中表的初始化。 + +```sql +...... + +-- ============================================================================ +-- 2. Create Menu Items Table +-- ============================================================================ + +create table if not exists public.menu_items ( + id uuid primary key default gen_random_uuid(), + name text not null, + description text, + category text check (category in ('burger','side','drink')) default 'burger', + price_cents int not null check (price_cents > 0), + available boolean default true, + emoji text, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +-- Comments for documentation +comment on table public.menu_items is 'Burger shop menu items for CRUD demo'; +comment on column public.menu_items.id is 'Unique identifier for each menu item'; +comment on column public.menu_items.name is 'Display name of the menu item'; +comment on column public.menu_items.description is 'Detailed description of the menu item'; +comment on column public.menu_items.category is 'Category: burger, side, or drink'; +comment on column public.menu_items.price_cents is 'Price in cents (integer) to avoid floating point issues'; +comment on column public.menu_items.available is 'Whether the item is currently available for order'; +comment on column public.menu_items.emoji is 'Optional emoji representation of the menu item'; +comment on column public.menu_items.created_at is 'Timestamp when the item was created'; +comment on column public.menu_items.updated_at is 'Timestamp when the item was last updated'; + +...... +``` + +在 SQL Editor 中执行初始化 sql 脚本后,即可在 Table Editor 中看见已创建的数据表。其中数据库初始化代码具体执行逻辑如下: + +1. 创建 menu_items 表 : +2. 这个表用于存储汉堡店菜单中的所有项目。它包含了如 name (商品名), description (描述), price_cents (以美分为单位的价格,避免浮点数精度问题), category (分类) 和 available (是否可售) 等字段。这基本涵盖了一个菜单项所需的所有信息。 +3. 创建 promo_codes 表 : +4. 此表用于管理促销活动,例如折扣码。它定义了 code (折扣码), discount_type (折扣类型,如百分比或固定金额), discount_value (折扣数值) 等字段。 +5. 禁用行级安全 (Row Level Security - RLS) : +6. 为了方便开发和测试,脚本中明确地禁用了 RLS。但结合我们之前学习的 RLS 核心逻辑:RLS 是 Supabase 保障数据安全的关键功能,能通过精细化策略控制 “谁能访问 / 修改哪些数据”(比如只允许管理员编辑促销码,普通用户只能查看菜单)。因此在生产环境中,必须开启 RLS 并配置合理策略,从底层阻断非授权访问(如防止用户恶意修改他人创建的菜单,或泄露促销码规则)。 +7. 插入种子数据 (Seed Data) : +8. 为了让前端项目启动后就能看到真实的菜单与促销数据(无需手动录入测试数据),`init.sql`脚本还会向 `menu_items`和 `promo_codes`表中插入 “种子数据”(即示例数据)。例如,你可以看到各种汉堡、小食、饮料以及多种多样的折扣码。 + +### 设置与数据库的连接 + +数据库准备完成,我们需要将这个前端项目与 Supabase 进行连接,从而正常读取数据库内的数据。我们需要将 Supabase 项目的 URL 和 anon key 写到指定配置中,本项目提供了两种灵活的配置方式: + +1. 通过环境变量配置 + +在项目根目录创建一个 .env 文件,并填入你的 Supabase 凭证: + +``` +NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co +NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key +``` + +2. 在项目页面中直接设置 + +为了方便快速演示和切换不同的 Supabase 项目,首页页面右上角提供了一个 设置 按钮。你可以点击它,在弹出的模态框中直接输入或粘贴 Supabase URL 和 anon key。 + +点击 “Save” 后,这些信息会用于动态创建 Supabase 客户端实例,类似下列代码所示: + +```JavaScript +import { createClient, type SupabaseClient } from '@supabase/supabase-js'; + +// Optional client factory for demos: returns null when env is not set. +export function maybeCreateBrowserClient(): SupabaseClient | null { + const url = process.env.NEXT_PUBLIC_SUPABASE_URL; + const anon = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; + if (!url || !anon) return null; + return createClient(url, anon); +} +``` + +创建完数据库,填写完对应的 Supabase Link 相关配置后,即可看到如下界面,你可以尝试对商品进行增删查改,并观察 Supabase 中对应部分数据表的变化。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image37.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image38.png) + +### 📚 作业 + +1. 尝试增加和删除已有项目,在 Table Editor 中查看修改操作对数据表内容变动的影响。 + +## 3.4 项目2 - 汉堡店认证用户 + +Project1 实现了 “菜单 CRUD + 数据库连接” ,Project2 将引入更贴近真实业务的核心能力,用户认证(Auth)与行级安全(RLS)权限管理。 + +Project2 包含独立的登录页,支持用户通过「邮箱 + 密码」的方式登录。其核心逻辑是调用 Supabase Auth 提供的原生方法,快速实现认证流程,无需手动开发复杂的登录校验逻辑: + +``` +const { error: err } = await supabaseClient.auth.signUp({ + email, + password, + options: { + data: { + full_name: fullName || null, + birthday: birthday || null, + avatar_url: avatarUrl || null + } + } +}); +``` + +![](/zh-cn/stage-2/backend/database-supabase/images/image39.png) + +登录成功后,Supabase 会自动为用户创建一个会话(session),并在后续所有数据库请求中自动携带认证信息;通过 RLS 的作用,每个用户根据对应的认证信息只能看到自己的账户信息(已购买项目、钱包剩余额度),无法看到其他用户的账户信息,这就实现了不同用户登录后的数据隔离,每个人只能看到自己的内容。 + +和 Project 1 一样,你需要先使用 `init.sql` 进行数据表的初始化(注:如果发现初始化出错,请先在 Table Editor 中删除已经创建的数据表,或者是直接删除这个 Supabase Project, 重新新建一个 Project) + +成功使用邮箱注册账户、在邮箱确认注册账户后,登录后进入 Shop 界面即可看到如下内容: + +![](/zh-cn/stage-2/backend/database-supabase/images/image40.png) + +但此时点击 admin,你并不能看到如下界面,你需要尝试在数据表中找到控制用户权限的部分,将权限修改为 `admin`,从而能够在 Admin 界面正常看到如下内容: + +![](/zh-cn/stage-2/backend/database-supabase/images/image41.png) + +值得提示的是,目前每次注册新的邮箱,你都需要在邮箱中进行注册确认才可登录;但这一步并非是必须的,你可以在 Supabase 的 Authentication 栏目中找到 Sign In / Providers,点击Confirm email 取消邮箱的强制确认。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image42.png) + +### 📚 作业 + +1. 请先领取新手礼包,完成商品购买操作。 +2. 尝试找到用户权限的设定数据表位置,将权限修改为 `admin`,并成功在订单管理界面修改商品数量 +3. 尝试在数据表内定位到钱包金额相关表,通过修改使剩余钱包金额增加。 + +# 4. 构建你的第一个 Supabase 应用 + +经过前面的系统学习,你已掌握 Supabase 的核心能力(数据库操作、用户认证、RLS 安全策略),现在是时候亲自动手,搭建属于你的第一个包含数据库、支持用户登录系统的应用了! + +## 4.1 为任意应用接入 Supabase 数据库的标准化流程 + +我们可以使用标准化流程将任意应用接入 Supabase 数据库: + +1. 首先进行需求梳理与信息同步,明确目标并告知AI + 1. 你需要向AI清晰描述当前应用的核心功能、待新增的数据库需求。示例:“我现有一个本地React Todo应用,数据仅存在浏览器本地存储,需新增‘数据云端同步’功能并接入Supabase数据库。请帮我梳理:这个应用涉及哪些数据操作(如新增待办、修改状态、删除待办)?需要创建哪些数据表来存储这些数据?” + 2. 补充关键约束条件(可选):比如字段格式要求(时间戳用 `timestamptz`、金额用整数存分)、数据权限规则(仅自己可见待办),让AI的分析更贴合实际需求。 + 3. 对 AI 返回的结果进行审核,若AI思路存在遗漏(如未考虑“待办截止时间”字段),补充提示修正:“你漏考虑截止时间了,帮我加上。” +2. 让AI基于你确认后的表结构,生成适配Supabase的 `init.sql`脚本:“基于上述所说思路和表的结构,返回给我在 Supabase 中可以进行初始化的 init.sql 脚本”,之后你需要在 SQL Editor 中执行脚本;若执行报错,将错误信息反馈给AI,让其修正脚本。 +3. 在 Supabase 运行 init.sql 脚本后,让 AI 基于脚本重构当前代码,使得能够和 Supabase 进行正常的数据交互:“请你根据我的 sql 脚本以及上面讨论的设定,重构项目的代码让它支持能够和 Supabase 对应的数据库进行通信并处理数据”。 +4. 重构完毕,此时只需要配置好 Supabase 地址和 key 的参数(正式项目通常只用环境变量配置),随后进行检查,若没问题则顺利实现将应用接入 Supabase 数据库。 + 1. 运行项目,测试所有数据库交互功能,到Supabase Table Editor 实时查看数据是否同步; + 2. 若出现问题(如数据无法插入、仅能看到部分数据),将问题现象反馈给AI,让其定位原因并修正代码。 + +此外,若目标是开发用户登录页面,可直接让 AI 协助集成登录页面 :“现在你需要帮我给这个应用加入 Supabase 的用户登录系统,使用邮箱可以注册和登录”。另外,你还需要向 AI 明确页面的跳转逻辑与路径(如登录成功后跳转至系统首页、跳转首页的地址是什么、登录失败时留在当前页并显示错误提示)。集成完成后,你需要尝试注册登录后能在 Supabase 的 Authentication 项目中看到新增的用户数据,并在登录后能正常进入到原先未登录无法进入的应用界面即可。 + +当然,你还可以直接让 AI 参考某个 project 的实现直接迁移对应的 Supabase 功能,比如某个 Project 用到了数据库以及 Edge fuction 的高级功能,你可以按照如下方式直接让 AI 迁移对应的相似功能:“请你参考该项目 {此处复制粘贴参考项目的绝对地址} 当中的 Supabase 相关功能实现逻辑,给当前项目加上类似的实现逻辑(如用户登录、数据库管理、函数请求等等)”。 + +## 4.2 案例研究:构建一个在线贪吃蛇游戏 + +根据上面所提到的 SOP ,让我们通过一个具体的实际案例 `Project5-Supabase-Demos/apps_snakegame`来实践:为一个已有的“贪吃蛇”游戏项目增加分数排行榜单,包含用户登录与数据库基础功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image43.png) + +### 4.2.1 分析项目,识别数据需求 + +首先,和在之前提到的标准化流程类似,我们可以先把需求澄清给 AI ,让 AI 基于我们项目和需求给出对应的修改方案,之后我们会基于这个修改方案。 + +**你可以使用如下的提示词来指导 AI:** + +> “我有一个贪吃蛇游戏,目录在 {此处粘贴贪吃蛇游戏的绝对路径}。现在我想结合 supabase 给它增加一个在线排行榜功能,并且支持用户登录系统,排行榜可以根据用户名和邮箱显示排名。 +> +> 请帮我分析一下,为了实现这个功能,我需要建立哪些数据表?每个表应该包含哪些字段?” + +此时你会得到类似如下返回: + +![](/zh-cn/stage-2/backend/database-supabase/images/image44.png) + +### 4.2.2 生成 `init.sql` 脚本 + +确定需要的部分,我们可以让 AI 生成需要在 Supabase 执行的数据库初始化脚本:“请你基于上面的分析,帮我在项目中生成 scripts/init.sql 脚本用于在 Supabase 中初始化所需数据库”。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image45.png) + +### 4.2.3 改造项目代码 + +接下来我们只需要让 AI 基于前面的内容重构当前的贪吃蛇代码:“接下来请你基于前面思考的内容以及 sql 表,使用 Supabase 帮我实现排行榜功能,排行榜是单独的一页,需要可以根据邮箱和用户名区分不同用户的总分,你还需要支持基于邮箱的用户登录系统,注册登录才能玩这个游戏。” + +如果当前 AI 对话轮次太多,你想重开一个新的会话进行项目重构,你可以把上面提到的 `init.sql`作为上下文中的内容,让 AI 基于 sql 文件进行项目重构。 + +若是发现 AI 实现的用户登录系统不够正常,你可以直接将我们之前写好的 `Project5-Supabase-Demos/apps/project-burger-shop-auth-users-2` 的地址一同放入提示词,让 AI 基于项目直接实现用户登录系统。并检查是否已经正确设定了连接到 Supabase 的必要条件,防止因为 Supabase 配置错误而报错。 + +在代码修改过程中,若出现实际效果与预期不符的情况(如排行榜数据不显示、登录验证失效等),只需完整记录具体现象并反馈给 AI,即可逐步接近正确结果。改造成功的标准为:用户能顺利完成注册与登录操作,且登录后可正常查看对应的游戏排行榜单。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image46.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image47.png) + +### 📚 课程作业 + +1. 将用户管理系统集成到贪吃蛇游戏演示版中 +2. 将用户管理系统集成到你的应用程序中(如果之前已开发过一个应用程序) + +# 5. 成为 Supabase 大师 + +以上是 Supabase 的基本操作,接下来的旅程中我们将会接触 Supbase 的进阶原理和功能,你将理解为什么我们会选择 Supabase 作为教学案例,以及如何使用 Supbase 实现更高级的操作,协助你实现更复杂的交互功能,并且在学习这些功能后,即便面对 Supabase 之外的其他同类工具,你也能触类旁通,从更本质的层面理解后端服务的核心原理。当然,你并不需要在短时间内学会全部,也许只需要学会第三方登录支持已经足够,你可以先浏览下列内容,直到项目遇到对应的需求时再倒回来深入学习。 + +## 5.1 为什么我们选择 Supabase + +在开始进阶之前,我们再次思考这个问题:众多后端技术方案中,为何我们最终选择 Supabase 作为技术底座? + +初创团队在技术选型时普遍面临一个矛盾:既想完全掌控后端系统,又必须快速上线产品——而自建后端通常意味着要投入数月时间搭建数据库与实时同步、用户认证、API服务、文件存储、定时任务、监控告警等核心组件,除非团队成员已在对应领域积累了丰富的实战经验。在资金不足、市场窗口短暂的双重压力下,一旦陷入基础设施泥潭,极易导致迭代滞后、错失早期增长空间。 + +Supabase 将这些后端能力打包为开箱即用的服务(PostgreSQL数据库、实时订阅、身份认证、对象存储、边缘函数、自动生成API等),让初创团队得以将稀缺资源聚焦于核心功能开发,避免因底层建设拖慢上线速度——这已成为当前创投环境下务实的生存策略。当然,我们也可以使用别的一栈式后端产品进行开发,例如 PocketBase(轻量极简)和 Appwrite(跨平台适配)等方案,但综合功能完整性、SQL 生态成熟度及 Github 社区关注度,Supabase 更适合支撑业务的长期稳定运行。 + +在同类产品中,Supabase 的开源策略更具优势。 以市场占有率较高的 Firebase 为例:其闭源特性易导致平台绑定,迁移成本极高。Supabase 采用完全开源模式,支持私有化部署,规避了供应商锁定风险,可根据需求切换至其其他竞品。 + +总而言之,技术选型需匹配业务规模与目标。 对于个人项目或极小范围测试,PocketBase 等超轻量方案已足够;若企业需对接复杂身份系统,或要满足上市公司合规审计要求,WorkOS 这类企业级全身份治理方案更为适用。但对于验证 MVP、承载早期用户的核心业务场景,Supabase 的完整功能完全够用,它不仅能独立支撑至少万级用户规模,更可灵活集成 Stripe(支付)、Resend(邮件)、Cloudflare(CDN)等第三方服务;即便未来业务扩展至企业级需求,Supabase 的开源架构也能与企业系统并行部署,不同功能选择最适配的平台进行使用。这种渐进式灵活性,使初创团队无需过早投入重型基础设施,又能保留 future-proof 的演进空间。 + +## 5.2 Google 和 GitHub 登录支持 + +在前面的教程中,我们讲解了如何直接使用邮箱进行注册和登录,但在实际操作中我们通常想要简化注册流程,例如使用第三方登录 Google 和 GitHub 进行系统的快速注册与登录,我们将会在这节教程中展开每个细节;同时,一个完整的认证系统也必须提供安全可靠的密码重置功能,我们也会将密码重置功能集成在本节教程的项目中。 + +本项目 `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6`)完整地演示了如何实现这些高级功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image48.png) + +### 5.2.1 OAuth 流程:第三方登录是如何工作的? + +第三方登录的核心是 OAuth 2.0 开放授权协议,它的本质是 “授权代理”:允许用户授权我们的应用(汉堡店项目)访问其在第三方平台(如 Google)的公开信息(如邮箱、头像),但无需将第三方平台的密码暴露给我们的应用,从根本上规避了密码泄露风险。 + +完整流程可拆解为 5 个关键步骤,以 Google 登录为例: + +1. 用户发起授权请求:用户点击页面上的 “Sign in with Google” 按钮,我们的应用会自动将用户重定向到 Google 官方的授权页面(确保授权过程的安全性,避免钓鱼风险)。 +2. 用户完成第三方授权:用户在 Google 页面登录自己的账户(验证用户身份),并同意我们的应用请求的权限(如 “获取邮箱地址”)。 +3. Google 返回一次性授权码:授权通过后,Google 会将用户重定向回我们提前约定的 “回调 URL(Callback URL)”,并在 URL 参数中附带一个一次性、短期有效的授权码(而非直接返回用户信息,进一步提升安全性)。 +4. Supabase 交换访问令牌(Access Token):我们的后端(由 Supabase 托管,无需自建)会拿着这个授权码,向 Google 官方接口发起请求,换取可用于获取用户信息的 Access Token(授权码仅用于换 Token,避免 Token 直接在前端传输)。 +5. 创建账户并建立会话:Supabase 使用 Access Token 从 Google 拉取用户的公开信息(如邮箱、头像),并在我们的项目中为该用户自动创建账户(若首次登录)或直接关联现有账户,最终生成一个有效的用户会话(Session),完成登录。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image49.png) + +### 5.2.2 配置 Google Cloud 获取 Client ID 和 Secret + +无论是何种第三方登录方式,我们通常都需要获取 Client ID 与 Secret 进行配置;对于 Google 的第三方登录,你首先需要在 Google Cloud Platform 中创建一个 OAuth 2.0 客户端 ID 进行对应参数的获取。 + +1. **进入 Google Cloud Console** : +2. 访问 [Google Cloud Console](https://console.cloud.google.com/)。 +3. 创建一个新项目或选择一个现有项目。 +4. **配置 OAuth 同意屏幕 (OAuth consent screen)** : +5. 在左侧导航栏中,找到 “APIs & Services” -> “OAuth consent screen”。 +6. 选择 “External” 用户类型,然后点击 “Create”。 +7. 填写应用名称、用户支持电子邮件等必填信息。 +8. 在 “Authorized domains” 部分,添加你的 Supabase 项目域名,格式为 `*.supabase.co`。 +9. 保存并继续。在 “Scopes” 和 “Test users” 步骤中,你可以暂时跳过,直接保存。 +10. **创建凭据 (Create Credentials)** : +11. 进入 “APIs & Services” -> “Credentials”。 +12. 点击 “+ CREATE CREDENTIALS”,选择 “OAuth client ID”。 +13. 在 “Application type” 中选择 “Web application”。 +14. 为它取一个名字,例如 “Supabase Auth”。 +15. 在 “Authorized redirect URIs” 部分,点击 “ADD URI”,并填入你的 Supabase 项目的回调 URL。你可以在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “Google” 中找到这个 URL,它的格式通常是 `https://<你的项目ID>.supabase.co/auth/v1/callback`。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image50.png) +16. 点击 “CREATE”。 +17. **获取 Client ID 和 Client Secret** : +18. 创建成功后,一个弹窗会显示你的 **Client ID** 和 **Client Secret** 。请务必**立即复制并妥善保存** 它们。 + +### 5.2.3 配置 GitHub 获取 Client ID 和 Secret + +同样地,你也需要在 GitHub 上注册一个 OAuth 应用。 + +1. **进入 \*\***GitHub\*\* ** Developer Settings** : + 1. 登录你的 GitHub 账户。 + 2. 点击右上角的头像,进入 “Settings”。 + 3. 在左侧导航栏的底部,找到 “Developer settings”。 + +2. **注册新应用 (Register a new application)** : +3. 选择 “OAuth Apps”,然后点击 “New OAuth App”。 +4. 填写应用名称,例如 “My Burger Shop”。 +5. **Homepage URL** : 填写你应用的线上地址,或者本地开发地址 `http://localhost:3000`。 +6. **Authorization \*\***callback\*\* ** URL** : 填入你的 Supabase 项目的回调 URL。同样,你可以在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “GitHub” 中找到它,格式为 `https://<你的项目ID>.supabase.co/auth/v1/callback`。 +7. 点击 “Register application”。 +8. **获取 Client ID 和 Client Secret** : +9. 注册成功后,页面会显示你的 **Client ID** 。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image51.png) +10. 点击 “Generate a new client secret” 来生成你的 **Client Secret** 。同样,请**立即复制并保存** 它。 + +### 5.2.4 在 Supabase 中配置 Provider + +现在,将我们获取到的凭证配置到 Supabase 中。 + +1. **进入 Supabase Dashboard** : +2. 选择你的项目,进入 “Authentication” -> “Providers”。 +3. **启用并配置 Google** : +4. 找到 “Google” 并启用它。 +5. 将你从 Google Cloud 获取的 **Client ID** 和 **Client Secret** 粘贴到对应的输入框中。 +6. 点击 “Save”。 +7. **启用并配置 ** **GitHub** : + 1. 找到 “GitHub” 并启用它。 + 2. 将你从 GitHub 获取的 **Client ID** 和 **Client Secret** 粘贴到对应的输入框中。 + 3. 点击 “Save”。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image52.png) + +至此,你已经能够使用第三方账户在构建的网站中进行登录,你可以直接让 AI 基于 `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6`项目作为参考,在你的项目的基础上支持用户登录系统,以最小成本集成包含 github 与 google 鉴权的用户登录界面。 + +### 5.2.6 密码重置实现 + +作为一个成熟的用户登录组件,密码重置也是极其重要的一环,本项目 `project-burger-shop-auth-advanced-supabase-6`也包含了该功能的完整实现,你可以直接让 AI 基于本项目的密码重置功能复刻完整的密码重置组件。其主要分为以下几步: + +1. 发起请求 :用户在忘记密码页面输入邮箱,前端调用 `supabase.auth.resetPasswordForEmail()` 函数,并指定一个重定向 redirectTo URL(例如 /auth/reset )。 +2. 发送邮件 :Supabase 会向该邮箱发送一封包含唯一重置链接的邮件。 +3. 访问链接 :用户点击邮件中的链接,被重定向到应用内指定的重置页面。 +4. 更新密码 :在重置页面,用户输入新密码。前端调用 `supabase.auth.updateUser()` ,将新密码提交给 Supabase。Supabase 会自动验证链接的有效性并完成密码更新。 + +最后,如果你觉得当前的密码重置邮件过于简陋,你可以 在 Supabase Dashboard 的 Authentication -> Email Templates 中自定义“Reset Password”邮件模板。 + +除了 Reset password 功能外,你还能看到许多其他与用户管理相关的高级功能设定(例如 Invite user 等),你可根据对应功能各自的开发文档,结合 Vibe coding 工具自行添加对应功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image53.png) + +## 5.3 实时功能 + +Supabase 的实时功能是其最强大的特性之一,为构建协作文档、实时仪表盘、游戏大厅或客服系统提供了极大的便利。 + +本项目 `Project5-Supabase-Demos/apps/project-burger-shop-realtime-orders-3 `通过构建一个 多人实时聊天室、光标位置共享 功能,展示了 Supabase Realtime 涉及到的三大核心能力:数据库变更监听 (Postgres Changes)、广播 (Broadcast) 和 在线状态 (Presence)。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image54.png) + +如果你觉得相关代码部分有一定难度,可以直接让 AI 参考该部分文档内容,对你的程序进行修改。 + +### 5.3.1 数据库实时变动 Postgres Changes + +最常见的 Realtime 功能是对数据库的变更进行实时监听 Postgres Changes 。它允许客户端订阅数据库中特定表、特定行甚至特定列的 INSERT 、 UPDATE 或 DELETE 事件。一旦数据库发生变动(无论是通过 API 调用、Supabase Dashboard 操作,还是 SQL 脚本执行),Supabase 都会利用 PostgreSQL 的底层复制机制,立即通过 WebSocket 将变更的数据推送到所有订阅了该频道的前端客户端,而无需前端通过轮询(Polling)去反复查询。 + +一般而言,该功能可以在 Table Editor 中找到 Enable Realtime 点击后启动, 但更方便的是通过 SQL 脚本初始化执行,例如: + +```sql +-- Enable realtime replication +ALTER TABLE public.chat_messages REPLICA IDENTITY FULL; +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_publication_tables + WHERE pubname = 'supabase_realtime' + AND schemaname = 'public' + AND tablename = 'chat_messages' + ) THEN + ALTER PUBLICATION supabase_realtime ADD TABLE public.chat_messages; + END IF; +END $$; +``` + +该语句将 `chat_messages` 表添加到了 Supabase 预设的 `supabase_realtime` 中,而一旦一个表被加入到这个特殊的 `publication` 中,Supabase 的实时服务器就会开始监听它的所有数据变更。 + +基于上面的特殊数据表,我们能够使用监听代码对表内数据变动进行实时监听。我们需要实现的是当一个用户发送消息时,其他所有在线用户都能立刻在屏幕上看到这条消息。通过订阅 chat_messages 表的 INSERT 事件能够实现这一点。 + +```typescript + const sub = supabase + .channel('chat_messages_channel') + .on('postgres_changes', { + event: 'INSERT', + schema: 'public', + table: 'chat_messages' + }, (payload: any) => { + console.log('New message received:', payload.new); + const newMessage = payload.new as Message; + // ... // + .subscribe((status: string) => { + console.log('Chat subscription status:', status); + }); +``` + +- `.channel('chat_messages_channel')`: 创建一个隔离的通信频道。 +- `.on('postgres_changes', ...)`: 这是核心的订阅方法。我们告诉 Supabase 我们只关心 `chat_messages` 表的 `INSERT` 事件。 +- `payload.new`: 当有新消息被插入数据库时,Supabase 会将这条新数据的完整内容通过 `payload.new` 推送给所有订阅的客户端。 +- `.subscribe()`: 启动订阅。 + +### 5.3.2 信息广播同步 Broadcast & Presence + +对于那些不需要存入数据库的、更“即时”的交互,比如光标移动、在线状态等,Supabase 提供了 Broadcast 和 Presence 功能。 + +- Presence: 用于跟踪频道内所有客户端的 **共享状态** 。适合用来实现“谁在线”的功能。 +- Broadcast: 用于向频道内的所有其他客户端发送**低延迟**的 **临时消息** 。 + +Presence 的核心思想是: 让每个客户端声明自己的在线状态,并由 Supabase 的服务器负责将这些状态可靠地同步给频道内的所有其他客户端。实现 Presence 分为以下几个关键步骤: + +1. 创建一个支持 Presence 的频道 + +首先,我们创建了一个频道 `lobby_presence` 来专门处理这些交互,并在配置中指定一个唯一的 key 来标识当前用户。这个 key 通常是用户的 ID。 + +``` +const ch = supabase.channel +('lobby_presence', { +  config: { +    presence: { key: anonymousUser.id }, +  } +}); +``` + +2. 订阅频道宣告“我在线”的信息 + +一旦频道创建成功,我们需要订阅它。在订阅成功的回调( status === 'SUBSCRIBED' )中,我们调用 channel.track() 方法。这个方法会将当前用户的信息(例如用户ID、名称、头像颜色等)广播给频道内的所有其他客户端,宣告自己的“在线”状态。 + +``` +const me = { +  id: anonymousUser.id, +  name: anonymousUser.name, +  color: anonymousUser.color +}; + +ch.subscribe(async (status) => { +  if (status === 'SUBSCRIBED') { +    await ch.track(me); +  } +}); +``` + +3. 同步完整的在线列表 + +当一个新用户加入频道时,他们需要获取当前所有已经在线的用户列表。这通过监听 presence 的 sync 事件来实现。 sync 事件会在你首次加入频道时触发,为你提供一个完整的“快照”。 + +channel.presenceState() 方法会返回一个对象,包含了当前频道内所有在线用户的状态信息。我们将其处理后更新到应用的 state 中,从而渲染出完整的在线用户列表。 + +``` +ch.on('presence', { event: 'sync' }, ()  +=> { +  const state = ch.presenceState(); +  const flat = {}; +  Object.values(state).forEach((arr) => { +    arr.forEach((u) => { flat[u.id] =  +    { ...u }; }); +  }); +  setOnline(flat); +}); +``` + +4. 监听单个用户的加入与离开 + +除了 sync 事件,我们还可以监听 join 和 leave 事件,以便在有新用户进入或离开时做出即时响应,例如显示一个 "User has joined" 的通知。 + +``` +ch.on('presence', { event: 'join' }, ({  +key, newPresences }) => { +  console.log('User joined:', key,  +  newPresences); +}); + +ch.on('presence', { event: 'leave' }, ({  +key, leftPresences }) => { +  console.log('User left:', key,  +  leftPresences); +}); +``` + +通过以上步骤,我们便构建了一个功能完备的在线状态系统。Supabase 自动处理了用户意外断开连接(如关闭浏览器或断网)的情况,并在适当的时候触发 leave 事件,确保了在线列表的准确性。 + +当 Presence 让我们知道了“谁在场”之后, Broadcast 能够让他们之间能够进行“对话”,但对话的内容是短暂存储的。一个典型的例子就是实时光标追踪。如果每次鼠标移动都去读写数据库,会造成巨大的性能浪费和延迟。 Broadcast 完美地解决了这个问题,它允许消息在各个客户端之间直接通过 WebSocket 传递,完全绕过数据库。 + +Broadcast 的工作模式主要依赖两个核心方法: channel.send() 用于发送,channel.on() 用于接收。】 + +1. 发送端:广播我的光标位置 + +我们为 mousemove 事件添加了一个监听器。当鼠标移动时,我们构造一个包含用户 ID、坐标和颜色的 payload,然后通过 channel.send() 将其广播出去,并指定事件名称为 'cursor'。 + +```typescript +const handleMouseMove = (e) => { + const payload = { + id: anonymousUser.id, + x: e.clientX, + y: e.clientY, + name: anonymousUser.name, + color: anonymousUser.color + }; + + channelRef.current?.send({ + type: 'broadcast', + event: 'cursor', + payload + }); +}; + +document.addEventListener('mousemove', handleMouseMove); +``` + +2. 接收端:监听并渲染他人的光标 + +在同一个频道内,所有客户端都使用 channel.on() 来监听 broadcast 类型的、且 event 为 'cursor' 的消息。一旦收到匹配的消息,回调函数就会被触发。我们从 payload 中解析出发送方的数据,并用它来更新本地的 online 状态,从而在屏幕上实时渲染出其他用户光标的位置。 + +```typescript +ch.on('broadcast', { event: 'cursor' }, ({ payload }) => { + setOnline((prev) => ({ + ...prev, + [payload.id]: { + ...(prev[payload.id] || {}), + x: payload.x, + y: payload.y + } + })); +}); +``` + +通过这种方式, Presence 和 Broadcast 协同工作;Presence 维护在线用户列表,而 Broadcast 则负责在这些用户之间传递像光标位置这样的临时状态,最终以较低的成本实现了丰富的实时互动功能。 + +## 5.4 存储 + +除了用户信息、订单这类可规整定义的结构化数据,一个完整的应用通常还需要处理大量非结构化文件 —— 例如用户头像、商品展示图、用户上传的订单文档等。这类文件的特点是体积差异大、数量可能极多(比如电商平台的商品图可能达数万甚至数十万张),若直接存储在应用自身的业务服务器中,会显著增加服务器的存储负载,还可能拖慢数据读写速度,影响应用整体性能。 + +实际开发中,这类非结构化文件会统一交由 “对象存储服务” 管理,OSS、Amazon S3 均属于这类服务,它们是专门为海量文件存储设计的 “专业存储工具”,能高效应对文件的存储、备份与快速读取需求。而我们在应用中获取这些文件时,并不会直接从对象存储服务的 “底层仓库” 调取,而是通过 URL 地址实现:每个存储在对象存储中的文件,都会被分配一个唯一的 URL(类似 “[https://xxx.oss.com/avatar/user123.jpg](https://xxx.oss.com/avatar/user123.jpg)” 的地址,可简单理解为这个“网站”只有一张图片),这个 URL 就像文件的 “专属访问地址”,前端页面只需通过该地址,就能直接下载或加载头像、商品图,无需依赖应用业务服务器中转,既提升了文件加载速度,也减轻了业务服务器的压力。 + +本项目 `project-burger-shop-storage-uploads-4` 便通过一个用户头像上传功能,深入演示了如何利用 Supabase Storage 构建现代化的文件上传系统,让开发者直观理解非结构化文件从上传到通过 URL 访问的完整流程。此外,本项目使用 `Uppy` 库来提供一个优秀的文件上传界面,并结合 `Tus` 插件实现了可续传上传,通过将 Uppy 的上传端点指向 Supabase 的标准 API (`/storage/v1/upload/resumable`) 进行工作,你可以参考类似的方式实现上传功能组件。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image55.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image56.png) + +### 5.4.1. 存储桶 + +Supabase Storage 的组成单元是存储桶 Bucket。你可以把它想象成电脑操作系统中的文件夹。每个 Bucket 都可以有自己独立的安全策略和配置。 + +Storage 内的所有文件都可以通过一个公开的 URL 直接访问,但并不意味着任何人都可以随意上传或修改,具体的访问权限将由更精细的策略来控制。和数据库一样,Storage 的访问权限也是通过行级安全策略来管理的。SQL 策略写在 storage.objects 和 storage.buckets 这两张特殊表上,可以精确定义谁能读取 (SELECT)、上传 (INSERT)、更新 (UPDATE) 或删除 (DELETE) 文件。 + +例如,我们可以创建一条策略,只允许用户上传到以自己 user_id 命名的文件夹下,并且只能上传图片类型的文件: + +``` +CREATE POLICY "Allow authenticated  +uploads to avatars bucket" +ON storage.objects FOR INSERT +TO authenticated +WITH CHECK ( +  bucket_id = 'avatars' AND +  auth.uid() = (storage.foldername(name)) +  [1]::uuid AND +  (storage.extension(name) IN ('png',  +  'jpg', 'jpeg')) +); + +CREATE POLICY "Allow public read access  +to avatars" +ON storage.objects FOR SELECT +USING ( bucket_id = 'avatars' ); +``` + +### 5.4.2 获取可访问文件 URL + +本项目需要你手动创建一个名为 avatars 的公共桶,所有文件将上传至该公共桶下进行存储。文件上传成功后,我们只得到了它在 Storage 中的存储路径 ,例如 public/avatar1.png 。这只是存储在数据库中的一个字符串,要让浏览器能够渲染这张图片,我们需要将其转换为一个可访问的 HTTP URL。 + +Supabase 提供了两种截然不同的策略来获取这个 URL,它们在安全性、持久性和成本控制上有着本质的区别。 + +#### 1. 公开 URL (Public URL) - 永久链接 + +这是最直接的方式。如果你的文件存放在一个**Public Bucket** 中,你可以获取一个固定、永久的公开链接。 + +```typescript +const { data } = supabase.storage + .from('avatars') + .getPublicUrl('public/avatar1.png'); +const publicUrl = data.publicUrl; +``` + +这类链接具有两大核心特点:一是简单直接,其 URL 结构固定,在实际操作中易于拼接和管理,降低了技术使用门槛;二是利于缓存,作为永久链接,它能被 CDN(内容分发网络)和浏览器有效缓存,从而大幅提升资源的访问速度,优化用户体验。基于这些特点,它适用于真正意义上的公共资源场景,例如网站 Logo、产品目录图片、博客文章配图等,能很好地满足这类资源的访问和管理需求。 + +不过在生产环境中,这类链接存在明显的被盗刷流量(Hotlinking)风险。由于链接是永久公开的,外部人员可以轻易将你的图片链接嵌入到他们自己的高流量网站中,导致流量被非法占用。这一行为会让你的 Supabase 项目产生大量不必要的流量费用,而这些消耗的流量并未服务于你自身的应用,属于典型的成本浪费,是生产环境中需要高度警惕和防范的问题;因此,我们需要转向临时签名 URL 实现对外资源的暴露。 + +#### 2. 签名 URL (Signed URL) - 临时授权链接 + +为了解决公开 URL 的安全和成本问题,Supabase 提供了生成临时签名 URL 的方式。这是绝大多数线上应用推荐的最佳实践,比如文生图应用给用户生成限时查看的图片链接、电商平台仅让下单用户获取临时发票下载地址、付费内容平台为订阅用户提供短期有效的课程播放链接,既防文件盗用又能避免流量盗刷,适配性极强。 + +```typescript +const { data, error } = await supabase.storage + .from('avatars') + .createSignedUrl('private/user-invoice.pdf', 3600); // 链接有效期为 3600 秒 (1小时) +const signedUrl = data?.signedUrl; +``` + +临时签名 URL(Signed URL)有三大核心优势:安全可控是指链接带安全标记、有有效期,过期就用不了;权限绑定很简单 —— 只有能看这文件的人,才能生成这个链接,就算文件藏在私有存储里(Private Bucket),他用这个链接也能正常打开;杜绝盗刷是因为链接是临时的,复制到别处很快就失效,不会被恶意刷流量。靠这些优势,像用户头像、私人照片、付费内容、订单发票这些需要管权限的文件,都能用它。 + +从安全保障和成本控制的角度,建议养成优先使用临时签名 URL 的习惯。只有当某个资源明确需要永久公开、无限制访问(比如应用的公开 Logo、公共活动宣传图等)时,才考虑使用 Public URL。这样既能满足特定业务需求,又能最大程度规避不必要的风险和成本消耗。 + +## 5.5 边缘函数 + +Edge Function 是 Serverless(无服务器架构)生态中极具核心价值的形态之一,它为 “无自建后端” 场景提供了轻量、高效的函数运行支持。 + +什么是 Serverless? Serverless(无服务器架构)并不意味着真的没有服务器,而是指开发者无需关心服务器的购买、运维、配置和扩容 。你只需要编写业务代码(函数),云服务商会在特定事件触发时自动为你分配资源运行代码,并按实际运行时间计费。 + +当你的应用需要执行一些不能或不应在客户端(浏览器)上完成的逻辑时——例如与需要私密密钥的第三方 API 交互、执行计算密集型任务、或强制执行复杂的业务规则——Edge Functions 就派上了用场。Supabase Edge Functions 基于 Deno 和 TypeScript,它们被部署在全球的边缘节点上,物理距离上靠近你的用户,从而提供极低的函数执行延迟。 + +目前主流云厂商都推出了各自的 Edge Function 服务,常见的包括: + +- AWS Lambda@Edge:基于 AWS Lambda 延伸的边缘函数服务,可与 CloudFront CDN 联动,支持 Node.js、Python 等语言; +- Cloudflare Workers:Cloudflare 推出的边缘函数,部署在其全球 275+ 边缘节点,支持 JavaScript/TypeScript,以 “毫秒级延迟” 为核心优势; +- Vercel Edge Functions:适配 Vercel 前端项目的边缘函数,与 Next.js 深度集成,支持 TypeScript,主打 “前端与边缘逻辑无缝衔接”; + +回到 Supabase ,当你的应用需要执行 “不能在客户端(浏览器)完成” 的逻辑时,比如用私密密钥调用第三方 API(如 LLM 接口)、处理计算密集型任务(如图片压缩)、或强制执行权限校验(如文件访问规则)时,Supabase Edge Functions 就能发挥作用。它基于 Deno runtime 和 TypeScript 构建,部署在全球边缘节点上,能以 “靠近用户的物理距离” 实现极低的执行延迟,是编写自定义、可信服务器端逻辑的核心工具。 + +本项目 `Project5-Supabase-Demos/apps/project-burger-shop-edge-function-5`通过一个与大语言模型(LLM)实时流式对话的功能,展示了 Edge Functions 的最简应用流程。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image57.png) + +### 5.5.1 LLM Chat 案例解析 + +假设你想在应用中集成一个类似 ChatGPT 的聊天机器人。你需要在服务器端调用 OpenAI 的 API,但这需要一个私密的 API Key。 这个 Key 绝对不能暴露在前端代码中 ,否则任何人都可以通过查看网页源码盗用你的 Key,产生高昂的费用。这正是 Edge Function 的用武之地。我们将创建一个名为 llm-chat 的函数,它充当了前端和 OpenAI API 之间的一个 安全代理 。 + +参考 `project-burger-shop-edge-function-5/scripts/llm-chat.ts`的代码,我们来看看它是如何工作的: + +```typescript +// scripts/llm-chat.ts +import "jsr:@supabase/functions-js/edge-runtime.d.ts"; +import { OpenAI } from "npm:openai"; + +const OPENAI_API_KEY = Deno.env.get("OPENAI_API_KEY"); + +Deno.serve(async (req) => { + try { + const openai = new OpenAI({ apiKey: OPENAI_API_KEY }); + const { prompt } = await req.json(); + + const stream = await openai.chat.completions.create({ + model: "gpt-3.5-turbo", + messages: [{ role: "user", content: prompt }], + stream: true, + }); + + return new Response(stream.toReadableStream(), { + headers: { "Content-Type": "text/event-stream" }, + }); + } catch (err) { + } +}); +``` + +在该案例中,对于密钥安全,OPENAI_API_KEY 作为环境变量被安全存储于 Supabase 的服务器。本地前端代码完全无法接触到该密钥,从而有效保障了密钥的安全性。 + +### 5.5.2 创建并部署函数 + +Supabase 提供了非常友好的界面,让你无需接触命令行即可完成部署。 + +1. **进入 Edge Functions 面板** : +2. 登录你的 Supabase 项目 Dashboard。 +3. 在左侧导航栏中,点击像代码一样的图标,进入 “Edge Functions”。 +4. **创建新函数** : +5. 点击 “Create a new function” 按钮。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image58.png) +6. 为函数命名,例如 `llm-chat`。 +7. **粘贴代码** : + ![](/zh-cn/stage-2/backend/database-supabase/images/image59.png) +8. 在弹出的在线编辑器中, **删除所有默认的占位代码** 。 +9. 打开你本地的 `llm-chat.ts` 文件, **复制其全部内容** 。 +10. 将复制的代码**粘贴**到 Supabase 的在线编辑器中。 +11. **配置\*\***环境变量\*\* ** (Secrets)** : + 1. 在侧边栏找到 Secrets。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image60.png) + 2. Name: 输入 `OPENAI_API_KEY`。 + 3. Value: 粘贴你自己的 OpenAI API Key。 + 4. 点击 “Save”。在这里设置的 Secret 会被加密存储,并安全地注入到你的函数运行时环境中。 + +若有函数需要更新,记得在 Edge Function 部分执行 Deploy updates。Supabase 会在云端为你构建并部署这个函数。几分钟后,你的函数就可以在线访问。 + +除了作为语言模型的安全代理,Edge Functions 的应用场景远不止于此。实际上,任何需要服务器端逻辑处理的任务,无论是简单的 API 调用、数据验证,还是更复杂的计算,都可以通过 Edge Function 实现。它为你提供了一个轻量级、可扩展的后端,而无需管理任何服务器基础设施。 + +如果你想探索更多可能性,可以参考项目中的其他示例。例如: + +- 图片生成 ( txt2img.ts ) : 这个函数展示了如何利用 Edge Function 调用第三方的文生图(Text-to-Image)API(如 Stability AI, Midjourney 等)来动态生成图片。这是一种典型的计算密集型或需要安全调用外部服务的场景。与 llm-chat 案例一样,API 密钥被安全地存储在 Supabase 后端,前端只负责发送文本描述,然后接收并展示生成的图片,整个过程安全、高效。 +- 发送邮件 ( send-email.ts ) : 在应用中发送欢迎邮件、交易通知或密码重置邮件是常见需求。 send-email.ts 示例演示了如何通过 Edge Function 集成邮件服务(如 Resend, SendGrid)。你无需在客户端代码中暴露敏感的邮件服务 API Key,只需创建一个函数,让前端通过调用这个函数来触发邮件发送。 + +## 5.6 Clerk 登录 + +Clerk 是一款专注于身份认证与用户管理的专业开发工具,核心能力覆盖用户注册、登录、账号安全MFA、权限控制、会话管理等全链路身份认证相关需求,能帮助开发者快速搭建安全、灵活且符合现代应用标准的用户体系,无需从零开发复杂的身份逻辑。 + +本部分将介绍如何从零开始配置 Clerk 服务,并将其与 Supabase 进行整合。你可以在项目 `project-burger-shop-auth-advanced-clerk-7` 中体验全流程。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image61.png) + +### 5.6.1 创建 Clerk 应用与获取密钥 + +在使用本项目之前,你需要拥有一个 Clerk 账号并创建一个应用。 + +1. 注册与创建: + 1. 访问 [dashboard.clerk.com](https://dashboard.clerk.com/) 并注册账号。 + 2. 点击 "Create application" 。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image62.png) + 3. 输入应用名称(例如 "Burger Shop")。 + 4. 在 "How will your users sign in?" 中,默认勾选 Email , Google , GitHub 。 + 5. 点击 Create application 。 +2. 获取 API Keys: + 1. 创建成功后,你会被引导至 API Keys 页面。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image63.png) + 2. 找到 Publishable key (以 `pk_` 开头) 和 Secret key (以 `sk_` 开头)。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image64.png) + 3. 将它们复制到你的 `.env.local` 文件中(参考本项目 `.env.example`): + + ```bash + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... + CLERK_SECRET_KEY=sk_test_... + ``` + +### 5.6.2 配置 Supabase 和 Clerk 的原生集成 + +在进一步使用前,我们需要集成 Supabase 与 Clerk 的关联关系,方便之后登录的鉴权跳转以及控制对特定数据库的访问权限。Supabase 与 Clerk 提供官方原生集成能力,通过该集成可快速实现两者的身份认证打通,无需手动配置复杂的适配逻辑,大幅简化用户登录、权限校验等功能的开发流程: + +1. 在 Clerk 中激活对 Supab ase 的官方集成 + 1. 登录 [Clerk Dashboard](https://dashboard.clerk.com/)。 + 2. 在左侧菜单导航至 Integrations (集成)。 + 3. 在列表中找到并点击 Supabase。 + 4. 开启 Enable Supabase 开关(或点击 Activate integration)。 + 5. 关键步骤:激活成功后,页面会显示你的 Clerk Domain(格式通常为 `https://.clerk.accounts.dev` 或你的自定义域名)。请复制这个 Domain 地址,下一步会用到。 +2. 在 Supabase 中添加 Clerk 提供商 + 1. 登录 [Supabase Dashboard](https://supabase.com/dashboard) 并进入你的项目。 + 2. 在左侧菜单导航至 Authentication > Sign In / Up (或者直接点击 Providers)。 + 3. 点击 Add provider 按钮,从下拉列表中选择 Clerk。 + 4. 在弹出的 Clerk Domain 输入框中,粘贴你刚才从 Clerk 复制的 Domain 地址。 + 5. 点击 Save 保存配置。 + +### 5.6.3 通过 Webhook 同步用户数据至 Supabase + +仅仅是集成只满足了鉴定权限的需求,但这并不会将 Clerk 中已经注册的用户信息同步到 Supabase,为了方便管理,我们还需要在 Supabase 的 `public.users` 表中保留一份用户备份,以便进行关联查询或数据分析。我们可以通过 Clerk Webhooks 实现这一功能,完整过程如下: + +1. **Clerk 发送通知** : 当用户在 Clerk 注册或更新资料时,Clerk 会向我们配置的 Webhook URL 发送一个 POST 请求。 +2. **Supabase 接收并写入** : Edge Function 接收请求,验证签名(确保安全),然后将用户数据更新到 Supabase 的数据库表中。 + +在开始之前,我们需要配置同步信息所需的数据表: + +```sql +-- File: init.sql + +-- 1. Create `users` table for synced Clerk users +-- This table will store user data pushed from Clerk Webhooks. +CREATE TABLE public.users ( + id TEXT NOT NULL PRIMARY KEY, -- Corresponds to Clerk User ID + email TEXT, + first_name TEXT, + last_name TEXT, + image_url TEXT, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- 2. Enable Row Level Security (RLS) on the table +-- This is an important security measure to ensure users cannot access any data by default. +ALTER TABLE public.users ENABLE ROW LEVEL SECURITY; + +-- 3. Create RLS policies +-- Policy 1: Allow authenticated users to read their own user info. +-- `auth.jwt()->>'sub'` extracts the user ID from the JWT provided by Clerk. +CREATE POLICY "Authenticated users can view their own user record" +ON public.users FOR SELECT +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); + +-- Policy 2: Allow users to update their own info. +CREATE POLICY "Authenticated users can update their own user record" +ON public.users FOR UPDATE +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); +``` + +以及在 Supabase 中启用对应的 Edge function: + +```JavaScript +// File path: supabase/functions/clerk-webhooks/index.ts + +import { serve } from 'https://deno.land/std@0.177.0/http/server.ts' +import { Webhook } from 'npm:svix' +import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' + +// Get Clerk Webhook signing secret from environment variables +const CLERK_WEBHOOK_SECRET = Deno.env.get('CLERK_WEBHOOK_SECRET') + +if (!CLERK_WEBHOOK_SECRET) { + throw new Error('CLERK_WEBHOOK_SECRET is not set in environment variables') +} +const supabaseAdmin = createClient( + Deno.env.get('SUPABASE_URL')!, + Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')! +) + +serve(async (req) => { + try { + // 1. Get Svix signature info from request headers + const headers = Object.fromEntries(req.headers) + const svix_id = headers['svix-id'] + const svix_timestamp = headers['svix-timestamp'] + const svix_signature = headers['svix-signature'] + + if (!svix_id || !svix_timestamp || !svix_signature) { + return new Response('Missing Svix headers', { status: 400 }) + } + + const payload = await req.json() + const body = JSON.stringify(payload) + + // 2. Verify Webhook signature validity using the secret + const wh = new Webhook(CLERK_WEBHOOK_SECRET) + const evt = wh.verify(body, { + 'svix-id': svix_id, + 'svix-timestamp': svix_timestamp, + 'svix-signature': svix_signature, + }) + + const { id } = evt.data + const eventType = evt.type + console.log(`Received webhook event: ${eventType} for user: ${id}`) + + // 3. Execute database operations based on event type + switch (eventType) { + case 'user.created': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin.from('users').insert({ + id, + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + }) + if (error) throw error + console.log(`User ${id} created in Supabase.`) + break + } + + case 'user.updated': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin + .from('users') + .update({ + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + updated_at: new Date().toISOString(), // Update timestamp + }) + .eq('id', id) + if (error) throw error + console.log(`User ${id} updated in Supabase.`) + break + } + + case 'user.deleted': { + // For delete events, ID might be at the top level + const deletedId = id + if (!deletedId) { + return new Response('Deleted user ID not found', { status: 400 }) + } + const { error } = await supabaseAdmin.from('users').delete().eq('id', deletedId) + if (error) throw error + console.log(`User ${deletedId} deleted from Supabase.`) + break + } + } + + return new Response('Webhook processed successfully', { status: 200 }) + } catch (err) { + console.error('Error processing webhook:', err.message) + return new Response(`Webhook Error: ${err.message}`, { status: 400 }) + } +}) +``` + +初始化 Supabase 数据表与函数结束后,你还需要在 Clerk 中启用 Webhooks 支持: + +- 在 Clerk Dashboard -> **Webhooks** 中添加 Endpoint,填入Supabase Edge Function 的 URL。 +- 勾选 `user.created`, `user.updated`, `user.deleted` 等事件。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image65.png) + +一旦设置成功,你能够在 Message Attempts 中看到不同请求信息,点击后可看到详细的请求返回参数结果;如果 webhook 在请求 Edge function 时出现问题,你可以快速在返回值中找到详细原因结果。推荐你同时对照 Clerk 和 Supabase 的请求日志信息,用于分析各个函数设定是否正确。 + +### 5.6.4 Clerk 中的第三方登录支持 + +在深入了解如何对 Clerk 支持第三方登录前,我们先明确两个核心概念:开发环境与生产环境,这是软件从 “开发测试” 到 “上线可用” 的两个关键阶段,二者的定位、用途和安全要求截然不同: + +- 开发环境:开发者本地或测试服务器使用的环境,仅用于功能开发、调试和内部验证(如本地 localhost:3000 服务),不对外开放 +- 生产环境:应用正式上线后,面向真实用户的公开环境(如部署在 Vercel、阿里云等平台的 https://my-app.com) + +而 Clerk 对社交登录区分这两种环境,本质是平衡 “开发效率” 与 “生产安全”:开发阶段需减少冗余配置以快速验证功能,生产阶段需通过专属凭证保障数据安全,同时符合 Google、GitHub 等第三方 OAuth 平台的规则(线上应用必须绑定专属域名与凭证,不允许使用共享资源)。下面具体说明两种环境下 Clerk 社交登录的差异配置: + +1. **开发环境快速验证** + +开发环境中,Clerk 已预置共享 OAuth 凭证和默认重定向 URI,无需前往 GitHub/Google 申请专属凭证,操作步骤如下: + +- 登录 Clerk Dashboard ,在左侧导航栏进入 SSO connections (SSO 连接)页面。 +- 点击 Add connection (添加连接),选择 For all users (对所有用户生效)。 +- 在 Choose provider (选择提供商)下拉菜单中,按需选择 GitHub 或 Google 。 +- 直接点击 Add connection (添加连接),Clerk 会自动用共享凭证完成绑定。 + + 配置后,本地启动应用(如 `localhost:3000`)并点击“Sign in with GitHub/Google”,Clerk 会自动代理登录请求,快速验证功能是否正常。 + +2. **生产环境自定义凭证配置** + +(注:如果发现有环节和预期不一致,建议阅读官方文档进行最新方式的尝试) + +应用部署上线(如 Vercel、阿里云)并切换到 Clerk Production Instance 后,共享凭证失效,需为 GitHub/Google 配置自定义 OAuth 凭证(建议同时打开 Clerk Dashboard 和第三方平台页面,方便同步操作): + +- 前置通用操作(Clerk 控制台): + - 进入 Clerk SSO connections 页面,点击 Add connection → 选择 For all users 。 + - 选择目标平台(GitHub/Google),确保开启 Enable for sign-up and sign-in (允许注册登录)和 Use custom credentials (使用自定义凭证)。 + - 复制页面中的 Authorization Callback URL (GitHub)或 Authorized Redirect URI (Google),保存到安全位置,不要关闭当前页面/弹窗。 +- 2.1 GitHub 平台配置: + - 登录 GitHub,进入 Developer Settings (路径:头像 → Settings → Developer settings → OAuth Apps)。 + - 点击 New OAuth app ,填写信息:`Application name`(应用名称)、`Homepage URL`(生产域名,如 `https://my-app.com`)、`Authorization Callback URL`(粘贴从 Clerk 复制的地址)。 + - 点击 Register application ,再点击 Generate a new client secret ,保存生成的 Client ID 和 Client Secret (Secret 仅显示一次)。 + - 回到 Clerk 弹窗,粘贴 Client ID 和 Client Secret,点击 Add connection 完成配置(若关闭弹窗,可在 SSO connections 找到 GitHub 连接,在“Use custom credentials”模块补填)。 +- 2.2 Google 平台配置: + - 登录 Google Cloud Console ,选择已有项目或新建项目(如“My App Production”)。 + - 点击左上角菜单 → APIs & Services → Credentials ,点击 Create Credentials → OAuth client ID (首次配置需先完成 OAuth consent screen 设置,选择“External”并填写应用信息)。 + - 选择 Application type 为 Web application ,配置: + 1. `Authorized JavaScript origins`:添加生产域名(如 `https://my-app.com`、`https://www.my-app.com`),本地验证可补充 `http://localhost:端口号`。 + 2. `Authorized Redirect URIs`:粘贴从 Clerk 复制的地址。 + - 点击 Create ,保存弹窗中的 Client ID 和 Client Secret ,回到 Clerk 弹窗粘贴并点击 Add connection 。 + - 关键注意事项: + 1. 禁止 WebView 登录:Google OAuth 不支持应用内浏览器登录,需参考 [Google 官方文档](https://support.google.com/cloud/answer/7657789) 调整。 + 2. 切换发布状态:默认“Testing”状态仅支持 100 个测试用户,需在 OAuth consent screen 将“Publishing status”改为 In production (需通过 Google 审核)。 + 3. 阻止子邮箱:Clerk 默认拦截含 `+`/`=`/`#` 的 Google 邮箱(如 `user+alias@example.com`),可在 Google 连接详情页开启/关闭 Block email subaddresses (建议开启提升安全性)。 + 4. 支持 Google One Tap:配置完成后,可集成 Clerk `` 组件实现“一键登录”,参考 [Clerk 组件文档](https://clerk.com/docs/components/social-connections/google-one-tap)。 + +3. 测试第三方登录连接 + +配置完成后,通过 Clerk 内置 Account Portal 验证功能: + +- 进入 Clerk Dashboard,左侧导航栏进入 Account Portal 页面。 +- 在“Sign-in”模块右侧,点击“访问登录页面”按钮,跳转至对应环境登录页: + - 开发环境:`https://你的域名.accounts.dev/sign-in`(如 `https://my-app.accounts.dev/sign-in`)。 + - 生产环境:`https://accounts.你的域名.com/sign-in`(如 `https://accounts.my-app.com/sign-in`)。 +- 点击“Sign in with GitHub/Google”,用对应平台账号登录,若能成功跳转并返回应用,说明连接配置正常。 + +# 6. 从 Supabase 到更多后端开发组件(进阶) + +在上文中,我们主要是站在 Supabase 的视角,去看“一个以 Postgres 为核心的一站式后端平台”能帮我们解决哪些问题:认证、数据库、文件存储、实时通信、边缘函数等,都被集成在同一个控制台里,开箱即用、体验统一,非常适合快速起步和中小型项目。 + +但从更长期、更工程化的角度来看, **Supabase 提供的每一块能力(Auth / Storage / Edge Functions / Realtime / Database),在业界几乎都有对应的专业替代方案** ——既包括同类 BaaS 平台,也包括更“单点突破”的云服务和开源组件。作为上进的个人开发者和初创团队来说,了解这些替代选项有几个好处: + +- 判断当前项目是否“全用 Supabase 就够了”,还是某一块需要更专业/更便宜/更易合规的专用服务; +- 当项目规模变大或需求变复杂时,是否可以把某个模块从 Supabase 替换出去(例如改用专门的 Auth 平台或对象存储),而不是一开始就被平台彻底锁死; +- 拓宽技术选型视野,即使暂时不更换,也能大致知道“如果不用 Supabase 的 X 功能,我还有哪些常见选择”。 + +本节将分别介绍 Supabase 所覆盖的几大能力在市场上的主流替代方案,例如:认证(Auth)、文件存储(Storage)、边缘函数(Edge Functions)、实时通信(Realtime)、数据库托管等。简单对比它们在功能特性、免费额度/定价、易用性以及社区流行度等方面的差异, 让你对后端组件工具库有更全面的理解。 + +## 同类 Baas 平台 + +在开始之前,我们可以浏览同类的 Baas 平台,若觉得 Supabase 不够好用,你可以根据需求选择不同替代品进行尝试。 + +| 平台/服务 | 类型 | 免费额度/定价 | 特点 / 适用场景 | +| ------------------------ | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| Firebase(Google) | 全托管 BaaS(Auth + Firestore + Storage + Functions + Hosting) | Spark:免费轻量额度;Blaze:按量计费(Firestore/Storage/Functions 分别算) | 行业最成熟、文档好、上手快、实时能力强。适用于中小型产品、移动/前端主导团队。缺点:计费复杂、锁定性强、查询限制多(尤其 Firestore)。 | +| Supabase | 开源 BaaS(Postgres + Auth + Storage + Edge Functions + Realtime) | 免费:500MB DB、1GB Storage、无服务器函数少量调用;Pro:按实例计费 | 最像 Firebase 的 SQL 版;界面优秀、体验现代、可自托管。适用于需要强 SQL、BI、事务能力的应用。缺点:高并发或复杂函数成本较高。 | +| Appwrite Cloud | 开源一站式 BaaS(DB + Auth + Storage + Functions + Realtime) | 免费:包含基本 DB/Storage/FaaS;付费按资源级别计费 | 体验现代化、API 统一、可自托管;适合开发者友好的应用快速迭代。缺点:生态还不如 Firebase/Supabase 成熟;性能在大型应用中需要测试。 | +| Nhost | Postgres + GraphQL + Auth + Storage + Functions | 免费:1GB DB、1GB Storage、少量函数调用 | 类似“Supabase + Hasura”;天然 GraphQL;适合前端团队与 React/Next.js 项目。缺点:生态小、成本随用量升高。 | +| AWS Amplify | AWS 一站式后端(Cognito + AppSync + DynamoDB + Storage + Functions + Hosting) | 免费:Hosting 额度 + Cognito 10k MAU + 部分函数额度 | 大而全,适合已有 AWS 基础的团队;企业级可靠性。缺点:最难上手,服务碎片化;初创团队维护成本高。 | +| Xata(近两年快速增长) | 多模型数据库 + Auth + Edge Functions | 免费:250k 记录、15GB 带宽 | 虽然更偏「DB + API」,但提供 Auth、文件、逻辑,可作为轻量全栈后端。UI/开发体验极佳。缺点:功能不如 Firebase/Supabase 全面。 | +| Convex(开发者体验极强) | 托管数据库 + Auth + Functions(前端优先) | 免费开发版;付费按请求量计费 | 极简上手;无需 schema;前端写函数即可用后端。适合 MVP/快速验证。缺点:高度绑定平台,迁移成本高;不算完全传统 BaaS。 | + +## 认证 (Auth) + +| 工具/平台 | 功能特点 | 免费额度/定价 | 适用场景与优缺点 | +| ----------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| Firebase Authentication | Google 提供的 BaaS 身份验证服务,支持邮箱/密码、手机、社交登录、匿名等常见方式。Spark 免费方案支持最高50k 月活跃用户。 | Spark(免费)50k MAU;Blaze 按量计费 | 集成 Google 生态,文档丰富,上手简单;功能全面(MFA、阻塞函数等),适合快速开发。但与 Firebase 平台绑定,扩展到其他服务需额外配置。 | +| Auth0 (Okta) | 全托管身份认证平台,支持社交登录、企业 SSO、多因子认证、规则扩展等强大功能。 | 免费方案25k MAU,付费按 MAU 计费 | 企业级功能齐全(RBAC、审计日志等),适合中大型应用;界面友好。缺点是 MAU 上升时成本高,免费版功能有限(如不含 MFA/RBAC)。社区知名度高,用户众多。 | +| AWS Cognito | 亚马逊云原生身份服务,支持社交及 SAML 联合登录。直接登录用户池提供每月10k MAU 免费,超过部分按 0.0055 美元/MAU 收费。 | 免费10k MAU/月,超出按量付费 | 与 AWS 生态深度集成(可无缝配合 API Gateway、Lambda 等),入门门槛略高,文档较复杂;免费额度有限,适合已有 AWS 使用习惯的团队。 | +| Logto | 开源身份认证平台,自托管版免费,云服务计划免费50k MAU。支持多语言、多租户、OAuth/OIDC 等。 | 社区版免费;Logto Cloud 免费50k MAU | 近期流行的 Auth0 开源替代方案,GitHub 已有 10k+ Stars。易扩展,自托管降低成本;缺点是生态和文档相对较新,社区规模略逊于 Firebase/Auth0。 | +| Keycloak | 知名开源 IAM/SSO 解决方案,支持用户名密码、LDAP、SAML、OAuth2 等。 | 完全免费,需自托管 | 功能强大、可扩展(支持细粒度权限控制),企业级功能丰富;但部署和维护复杂度高,对小团队而言学习曲线较陡。缺点是对容器化和集群运维要求较高。 | + +## 文件存储 (Storage) + +| 平台/服务 | 类型 | 免费额度/定价 | 特点/适用场景 | +| ---------------------------------------- | -------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| Amazon S3 | 云对象存储(AWS) | AWS 免费套餐提供 5GB 存储、20k GET/PUT 请求/月,超出按使用量付费 | 行业标准的对象存储,可靠性高、全球多区域部署。功能全面,与 AWS 生态整合良好;定价较复杂,新用户需了解计费规则。 | +| Google Cloud Storage(Firebase Storage) | 云对象存储(Google) | Firebase Spark 方案提供免费额度(1GB 存储 + 流量限制),Blaze 付费 | 与 Firebase/Google Cloud 紧密集成,易于管理;支持 CDN 加速、细粒度安全规则。 | +| 腾讯云 COS / 阿里云 OSS | 云对象存储(国内) | 按量付费(各有新用户赠送额度,如OSS有首年40GB免费等) | 面向国内市场,高性能、大规模对象存储;与中国云生态整合,文档较完善。阿里OSS 功能全面、全球加速;七牛KODO 专注多媒体处理,成本较低,适合个人和小团队。 | +| MinIO | 开源 S3 兼容存储 | 开源免费(自建) | 轻量级、高性能、与 S3 API 兼容,适合在私有云或本地搭建对象存储。文档和社区活跃;需自己维护基础设施。 | +| Cloudinary / Imgix 等 | 媒体存储+CDN | 基本免费方案(如 Cloudinary 免费 25GB/月带宽) | 针对图片/视频优化的云存储+CDN 服务,提供实时转码、压缩等高级功能。适合媒体项目,但功能较专一,作为通用文件存储使用成本偏高。 | + +## 边缘函数 (Edge Functions) + +| 平台/服务 | 特点 | 免费额度/定价 | 适用场景与优缺点 | +| -------------------------------------- | ------------------------------------------ | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Cloudflare Workers | 全球分布式 JavaScript/Wasmtime 环境 | 免费计划:每天 100k 请求;标准计划$5/月含1,000万请求 | 运行在 Cloudflare 边缘节点,延迟极低;适合全局分发的逻辑、静态资源渲染等。免费配额较少(相当于每月约300万请求),上手简单。缺点是运行时(JS/Wasmtime)限制与调试工具有限。 | +| Vercel Edge Functions | 随 Next.js/前端框架无缝集成,支持 JS/TS/Go | Hobby 免费:每月 100万 函数调用,100万 边缘请求 | 深度集成前端框架,自动部署;适合现代 Web 应用。免费额度充足,默认运行时 10s,可提升至 60s。缺点是免费版团队协作功能受限;依赖 Vercel 平台。 | +| Netlify Edge / Functions | Node.js 云函数+边缘路由(NFT) | 免费:300 代币/月(约相当于每月 1M 请求);按信用点计费 | 支持 Node.js 函数、边缘处理路由等。免费额度用于构建、函数和带宽,适合前端全栈部署。优点是简便易用,集成 Git 部署;缺点是免费额度使用需算计(10k 请求 = 3 点)。 | +| AWS Lambda@Edge / CloudFront Functions | AWS 无服务器边缘计算 | AWS Lambda(1M 免费请求/月+400k GB-s)+ CloudFront $0.085/每10万调用起 | 与 CloudFront 集成,可在边缘执行代码。适合需要 AWS 生态(如在节点层面做权限或 A/B 测试)。优点是灵活强大;缺点是配置复杂,延迟略高于 Cloudflare/Vercel。 | + +## 实时通信 (Realtime) + +| 平台/服务 | 功能特点 | 免费额度/定价 | 适用场景与优缺点 | +| -------------------------------------- | ------------------------------------------------ | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| Firebase Realtime Database / Firestore | Google BaaS 实时数据库;支持数据变更推送 | Spark 免费:实时数据库1GB 存储 & 限额;Blaze 按量付费 | 强集成 Firebase 生态,实时监听简单。优点是免费起步快;缺点是数据库类型(JSON/NoSQL),复杂查询能力弱。 | +| Ably | 实时消息与 pub/sub 平台,支持 WebSocket、MQTT 等 | 免费包:每月 6,000,000 条消息 | 功能全面的实时消息服务,高并发支持;免费额度可达600万消息/月。社区与文档较好,适合全球分布。 | +| Pusher Channels | 事件推送服务,支持频道/事件机制 | Sandbox 免费:每日 200k 消息,100 并发连接 | 易用的 WebSocket 服务,文档齐全,适合快速实现聊天和通知功能。免费版限制消息量和连接数;付费后扩展性好。 | +| 自建 WebSocket/Socket.IO | 自己搭建服务器(Node.js、Elixir 或 Go 等) | 自行托管成本(如服务器费用) | 灵活度最高,可根据需求定制协议和拓扑。适合对成本控制严格且技术成熟的团队。缺点是需自行处理可用性、扩展和跨域等问题。 | + +## 数据库 + +| 平台/工具 | 数据库类型 | 免费额度/定价 | 主要特点 | +| ---------------------------- | --------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| Neon (Serverless PostgreSQL) | 关系型(PostgreSQL) | 免费计划:0.5GB 存储,主分支永久在线,20h 分支计算/月 | 云原生无服务器 Postgres,支持自动伸缩和分支(fork 测试)。免费额度对小项目够用,适合现代开发流程。分支功能强大,但免费额度较小。 | +| Aiven PostgreSQL | 关系型(PostgreSQL/MySQL) | 免费计划:1GB 存储,1 vCPU,1GB 内存 | 托管级数据库服务,支持跨云多区域迁移。提供有 MySQL、Redis 等可选。免费额度适合开发和小型项目;商业版支持高可用集群和监控。 | +| CockroachDB Cloud | 分布式 SQL(兼容 PostgreSQL) | 免费计划:10GB 存储 | 类似 Google Spanner 的分布式 SQL 数据库,自动分片扩展。免费10GB 空间较慷慨;适合需要横向扩展和高一致性的应用。商业版 SLA 高。 | +| TiDB Cloud | 分布式关系型(MySQL 兼容) | 免费计划:每节点5GB,总计最多25GB | 开源 TiDB 的云版,兼容 MySQL 协议,分布式架构。免费额度充足,适合熟悉 MySQL 的团队,性能优秀;缺点是运维相对复杂(针对大型场景)。 | +| MongoDB Atlas | 文档型(NoSQL MongoDB) | 免费 M0 集群:0.5GB 存储 | 云端 MongoDB,灵活的文档模型,支持丰富查询和索引。免费 0.5GB 数据库适合测试和小型应用;可按需横向扩展。学习曲线略高于关系型数据库。 | +| SQLPub | 多数据库(MySQL、PostgreSQL、Redis 等) | 免费计划:36,000 请求/小时,30 并发连接,500MB 存储 | 一站式数据库平台,支持多种数据库类型。免费版适合学习和小项目;优点是支持多种 DB,缺点是存储额度较小。 | + +以上替代方案各有侧重:开源更灵活可控(Keycloak、MinIO、Socket.IO、Neon、CockroachDB 等),云托管服务更易上手(Firebase、Auth0、Cloudflare、Vercel、Netlify、AWS、Aiven、MongoDB Atlas 等)。选择时可根据项目需求、团队技术栈、预算和社区生态等权衡。个人项目可优先选用免费配额充足、易集成的服务(如 Firebase 系列、七牛存储、Cloudflare Workers、Neon、CockroachDB 等),而对企业级或特定安全需求,则可考虑功能更丰富但收费较高的方案(Auth0、Alibaba/Tencent 云、AWS、TiDB/Aiven 等)。你可以在实际应用中不断尝试,直到选择出最适合的后端开发工具组件。 + +# 总结 + +在今天的课程中,我们系统学习了数据库的基础概念、Supabase 的核心定义及其操作细节。后续在实践过程中,你可根据项目的实际应用场景与需求,随时回头翻阅这份文档作为参考。 + +请时刻记住一个重要原则: **先完成,再完美!** 无需追求一步到位,我们完全可以通过持续迭代优化,逐步靠近更优的成果。祝你在后续的项目实践中一切顺利! + +# 📚 课后作业 + +1. 开发一个包含用户管理系统和数据库的应用程序。最好包含更多的Supabase 功能 (Realtime / cloud storage / Edge function). diff --git a/docs/ko-kr/stage-2/backend/git-workflow/index.md b/docs/ko-kr/stage-2/backend/git-workflow/index.md new file mode 100644 index 0000000..e374fb7 --- /dev/null +++ b/docs/ko-kr/stage-2/backend/git-workflow/index.md @@ -0,0 +1,261 @@ +# Git과 GitHub 워크플로우 + +이전 강의에서는 웹 기반 vibe coding 도구를 사용하여 코드를 작성하는 방법을 배웠습니다. 매번 대화할 때마다 새로운 버전의 코드가 생성됩니다. 하지만 한 가지 질문을 생각해 봅시다: 이전 수정 사항으로 되돌리고 싶다면 편리한 방법이 있을까요? 우리가 다양한 단계에서 작성한 코드를 기록하여, 언제든지 다른 버전 간에 전환하고 수정할 수 있는 도구가 있을까요? + +이러한 요구를 충족하기 위해 버전 관리 소프트웨어가 탄생했습니다. 이 글에서는 가장 유명한 버전 관리 프로그램인 **Git**과 최고의 코드 호스팅 플랫폼인 **GitHub**를 소개하겠습니다. Git을 사용하여 코드를 관리하는 방법, GitHub에서 다른 사람의 코드를 가져오는 방법, 자신의 코드를 업로드하는 방법, 그리고 다른 사람들과 협력하여 대규모 프로젝트를 진행하는 방법을 배우겠습니다. + +개인 프로젝트의 버전 추적, 팀 협업에서의 코드 동기화, 오픈소스 커뮤니티에 기여하는 등 어떤 상황에서든 Git과 GitHub는 현대 개발자의 필수 도구입니다. 이를 마스터하면 코드를 더 효율적으로 관리하고, 필요에 따라 체크포인트를 생성하며, 코드의 다양한 단계 간에 자유롭게 전환하고, 단일 파일 변경부터 대규모 프로젝트 개발까지 모든 작업을 쉽게 처리할 수 있게 됩니다 — 모든 코드 반복을 통제 가능하고 추적 가능하게 만듭니다. + +> 💡 **사전 지식** +> +> Git을 배우기 전에 다음 개념을 먼저 확인하는 것을 권장합니다: +> - [터미널/명령어 줄이란](/ko-kr/appendix/2-development-tools/command-line-shell) - 명령어 줄을 사용하여 컴퓨터와 상호작용하는 방법 학습 +> - [Git이란](/ko-kr/appendix/2-development-tools/git-version-control) - Git 버전 관리 시스템의 핵심 개념 이해 +> +> 이 글은 GitHub 워크플로우와 실제 조작에 중점을 두며, 위 기본 지식은 부록 링크를 참조하세요. + +# Git 빠른 시작 + +Git을 사용하기 전에 부록의 [명령어 줄](/ko-kr/appendix/2-development-tools/command-line-shell)과 [Git 기초](/ko-kr/appendix/2-development-tools/git-version-control) 내용을 읽었는지 확인하세요. 이 글은 이미 기본 지식이 있다고 가정하고, Git 설치 및 구성과 GitHub를 사용한 협업 방법을 바로 설명합니다. + +## Git 설치 방법 + +다양한 컴퓨터 운영 체제에 Git을 설치하는 세 가지 방법을 시연합니다. 시스템 버전에 맞는 지침을 따르세요: + +### Windows + +1. [Git 공식 다운로드 페이지](https://git-scm.com/download/win)에 접속하여 시스템에 맞는 설치 프로그램을 다운로드하세요: [설치 패키지](https://github.com/git-for-windows/git/releases/download/v2.51.0.windows.1/Git-2.51.0-64-bit.exe). 기본적으로 x64 설치 프로그램을 권장합니다. +2. 설치 프로그램을 더블클릭하고 설치 마법사 지침을 따르세요: + ![](/zh-cn/stage-2/backend/git-workflow/images/image5.png) + 1. 기본 옵션을 유지하는 것을 권장합니다. 사용자 정의가 필요한 경우 다음 사항에 주의하세요: (대부분의 경우 "Next"를 계속 클릭하면 됩니다) + - Git이 사용할 기본 편집기 선택: 좋아하는 편집기(예: VS Code)를 선택하세요. 첫 번째 옵션인 Vim(텍스트 편집기)을 기본으로 선택하거나, "Visual Studio Code as Git's default editor" 옵션을 선택할 수 있습니다(VS Code가 미리 설치되어 있어야 함). 기본 선택을 유지하고 "Next"를 클릭하여 계속 진행할 수 있습니다. + ![](/zh-cn/stage-2/backend/git-workflow/images/image6.png) + - Git 사용 방식 선택: 세 가지 옵션은 시스템에서 Git의 접근성을 제어합니다. 옵션 2("from command line and 3rd-party software")를 권장합니다 — 기본 Git 도구를 PATH에 추가하여 Git Bash, 명령 프롬프트, PowerShell 및 IDE에서 Git을 사용할 수 있게 하며, 시스템을 복잡하게 만들지 않습니다. + ![](/zh-cn/stage-2/backend/git-workflow/images/image7.png) + +3. 설치 후 바탕 화면에서 마우스 오른쪽 버튼을 클릭하세요. 메뉴에 "Git Bash Here"가 보이면 설치가 성공한 것입니다. + +![](/zh-cn/stage-2/backend/git-workflow/images/image8.png) + +### MacOS + +macOS의 경우 먼저 터미널에서 `git --version`을 입력하여 Git이 이미 설치되어 있는지 확인할 수 있습니다. 설치되어 있지 않으면 시스템이 설치를 안내합니다 — 안내에 따라 설치를 완료하세요. + +1. 방법 1: Homebrew를 통한 설치 + [Homebrew](https://brew.sh/)(Mac 패키지 관리자)가 설치되어 있다면 터미널을 열고 다음을 입력하세요 + ```bash + brew install git + ``` +2. 방법 2: (권장) Xcode를 통한 설치: https://developer.apple.com/xcode/, Xcode에 Git이 내장되어 있습니다. 설치 후 안내에 따라 계속 진행하세요. + +### Linux + +대부분의 Linux 배포판은 패키지 관리자를 통해 Git을 설치할 수 있습니다: + +- Ubuntu/Debian: + +```bash +sudo apt update +sudo apt install git +``` + +- CentOS/RHEL: + +```bash +sudo yum install git +``` + +- 설치 확인: 터미널에서 git --version을 입력하세요. 버전 번호가 표시되면 설치가 성공한 것입니다. + +## Git 초기화 + +Git을 설치한 후, 먼저 사용자 정보를 구성해야 합니다 — 이는 Git을 사용한 버전 관리의 기본 단계입니다. 터미널에서 다음 명령을 실행하세요 (괄호 안의 내용을 자신의 정보로 교체): + +```bash +# 전역 사용자 이름 설정(커밋 기록에 표시됨) +git config --global user.name "Your Name" + +# 전역 이메일 설정(GitHub/GitLab 등 플랫폼에 등록한 이메일 사용 권장) +git config --global user.email "your.email@example.com" +``` + +Git은 이 정보를 각 커밋 기록에 삽입하여, 매번 수정의 "작성자 정보"로 사용합니다. 버전 기록(예: git log 사용)을 볼 때, 각 코드 줄을 누가 수정했는지 명확하게 볼 수 있어, 책임 추적과 소통에 편리합니다. 협업 프로젝트에서 통일된 신원 정보는 팀원들이 누가 어떤 변경을 했는지 빠르게 식별할 수 있게 하여 협업 효율을 높입니다(예: 커밋 기록을 통해 관련 개발자를 찾아 문제를 논의). + +명령어 줄에서 `git config --list`를 입력하여 현재 Git 구성 정보를 확인하고 설정이 성공했는지 확인할 수 있습니다. + +# GitHub란 + +GitHub는 Git 기반의 코드 호스팅 플랫폼입니다. Git 저장소에 대한 원격 저장소를 제공할 뿐만 아니라, 협업 도구(예: Issues, Pull Requests, Projects)도 포함하여 개발자가 코드를 공유하고 협업하기 쉽게 만듭니다. 간단히 말해, Git은 로컬 버전 관리 도구이고, GitHub는 원격 "코드 저장소 클라우드 + 협업 커뮤니티"입니다. + +GitHub는 세계 최대의 코드 호스팅 플랫폼일 뿐만 아니라, 전 세계에서 가장 활발하고 영향력 있는 오픈소스 커뮤니티입니다. 여기서 "오픈소스"의 핵심 아이디어는 누구나 소프트웨어의 소스 코드를 다운로드하고 실행할 수 있다는 것입니다. 이 모델은 전 세계 사람들이 서로의 코드를 검사하고 수정하거나, 이를 기반으로 새로운 프로젝트를 만들 수 있게 합니다. 예를 들어, GitHub에서 다양한 학습 튜토리얼과 GPT 모델 훈련에 사용되는 프레임워크(예: PyTorch)의 전체 소스 코드를 찾을 수 있습니다. 매일 전 세계적으로 수많은 사람들이 협력하여 코드를 검토하고 개선합니다. + +![](/zh-cn/stage-2/backend/git-workflow/images/image9.png) + +많은 대기업이 업계 경쟁 우위를 얻기 위해 GitHub에서 프로그램이나 튜토리얼을 오픈소스로 공개합니다 — 이는 일종의 광고 형태로도 볼 수 있습니다. GitHub 커뮤니티에서 프로젝트가 받은 "스타(stars)" 수는 그 가치를 측정하는 주요 지표입니다. 프로젝트나 조직이 보유한 스타가 많을수록 신뢰도와 영향력이 큽니다. + +![](/zh-cn/stage-2/backend/git-workflow/images/image10.png) + +우리 과정에서도 지원 자료와 과제가 전용 GitHub 저장소에 업로드됩니다. 과제를 업로드하는 과정을 통해 GitHub 사용에 점차 익숙해지고 마스터하게 되며, 향후 애플리케이션 개발에서의 버전 관리 기반을 탄탄하게 다질 수 있습니다. + +## GitHub 계정 등록 + +1. [GitHub 공식 웹사이트](https://github.com/)에 접속하여 오른쪽 상단의 "Sign up"을 클릭하세요. + ![](/zh-cn/stage-2/backend/git-workflow/images/image11.png) +2. 이메일 주소를 입력하세요(인증 및 알림이 해당 이메일로 전송되므로 자주 사용하는 이메일 사용 권장), 비밀번호를 설정하세요(문자, 숫자, 특수 문자를 포함해야 함). +3. 사람 인증을 완료하고, 안내에 따라 이메일을 인증하면 계정이 생성됩니다. + +## GitHub에서 첫 번째 저장소 만들기 + +다음으로, 첫 번째 저장 폴더, 즉 저장소 또는 "repo"를 만들어 보겠습니다. + +![](/zh-cn/stage-2/backend/git-workflow/images/image12.png)![](/zh-cn/stage-2/backend/git-workflow/images/image13.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image14.png) + +1. Repository name: 다른 사람에게 표시되는 저장소 이름입니다. +2. Description: 저장소에 대한 상세 설명입니다. +3. Choose visibility: 개인 저장소의 경우 private으로 설정하면 본인과 특별히 초대한 사람만 볼 수 있습니다. public으로 설정하면 모든 사람이 볼 수 있습니다. + 조직 내의 저장소의 경우, Private이면 조직 내의 사람만 볼 수 있습니다. + Public이면 조직 외부의 사람도 볼 수 있습니다. +4. README: 일반적으로 모든 저장소에는 README 파일이 있어야 한다는 관행이 있습니다. 이는 저장소의 완전한 소개로, 사용 설명, 파일 목록, 조작 방법이 포함됩니다. +5. Add .gitignore and license: + 1. .gitignore 파일은 Git에게 GitHub에 업로드할 때 특정 폴더나 파일을 무시하도록 지시하여, 추적되거나 스테이징 영역에 추가되지 않도록 합니다. 이는 임시 테스트 파일, 의존성 패키지 또는 대용량 파일에 유용합니다. 지정하면 해당 파일은 더 이상 추적되지 않습니다. + 2. license는 선택한 오픈소스 라이선스 유형을 나타냅니다. 다양한 라이선스는 다른 사람이 귀하의 코드를 상업적 목적으로 사용할 수 있는지 여부를 상세히 규정하며, 기타 조건과 약관이 포함됩니다. + +"Add README"를 체크하고, 저장소 공개 범위를 "Private"으로 설정하며, 원하는 대로 저장소 이름과 설명을 작성한 후 "Create repository"를 클릭하여 첫 번째 원격 저장소를 생성하세요. + +![](/zh-cn/stage-2/backend/git-workflow/images/image15.png) + +그러면 추가 파일이 없는 깨끗한 저장소를 갖게 됩니다. 이제 파일 업로드를 시작할 수 있습니다. + +![](/zh-cn/stage-2/backend/git-workflow/images/image16.png) + +저장소를 가져오는 명령은 `git clone`이지만, 저장소 주소가 필요합니다. 녹색 "Code" 버튼을 클릭하면 저장소 주소를 찾을 수 있으며, HTTPS와 SSH 옵션이 표시됩니다. 일반적으로 두 가지 방법 중 하나를 사용하여 저장소를 로컬 기기에 다운로드할 수 있습니다(이렇게 해야만 파일을 수정하고 업로드할 수 있습니다). + +![](/zh-cn/stage-2/backend/git-workflow/images/image17.png) + +일반적으로 HTTP를 통해 클론한 저장소는 다른 사람의 저장소를 임시로 다운로드하고 테스트하는 데 적합하지만, 자체 개발에는 권장하지 않습니다. 더 나은 학습 경험을 위해 먼저 SSH 인증을 설정하는 것이 좋습니다. + +## 로컬 SSH 바인딩 + +GitHub에서 "SSH 프로토콜 바인딩"은 본질적으로 로컬 기기의 SSH 공개 키를 GitHub 계정과 연결하여, GitHub가 SSH 프로토콜을 통해 기기를 식별할 수 있게 하는 것을 의미합니다. 이를 통해 비밀번호 없이 원격 저장소를 안전하게 조작(clone, push 또는 pull 코드)할 수 있습니다. + +간단히 말해: 이것은 기기에 "GitHub 전용 출입 카드"를 발급하는 것과 같습니다. 바인딩 후, 기기가 SSH 프로토콜을 통해 GitHub 저장소에 접근하면 GitHub가 이 "출입 카드"(귀하의 SSH 공개 키)를 검증합니다. 승인된 기기로 확인되면 바로 조작할 수 있습니다 — 매번 계정 비밀번호를 입력할 필요가 없습니다. + +> 💡 SSH란 + +### 왜 SSH 프로토콜 바인딩이 필요한가? + +GitHub는 두 가지 주요 저장소 조작 프로토콜을 지원합니다: HTTPS 프로토콜과 SSH 프로토콜: + +- HTTPS 프로토콜: 매번 조작(예: push) 시 GitHub 계정 비밀번호(또는 개인 액세스 토큰 PAT)를 입력해야 합니다. 인증 과정이 번거롭고 비밀번호 유출 위험이 있습니다. +- SSH 프로토콜: "키 페어"를 통해 인증이 완료되므로 비밀번호를 반복해서 입력할 필요가 없으며, 암호화 전송이 더 안전합니다. + +"SSH 프로토콜 바인딩"은 GitHub SSH 인증을 활성화하기 위한 전제 단계입니다 — 로컬 SSH 공개 키를 GitHub 계정에 "바인딩"해야만 GitHub가 기기를 인식하고 저장소에 대한 SSH 조작을 허용할 수 있습니다. + +### "바인딩"의 핵심 논리: SSH 키 페어의 역할 + +SSH 인증은 키 페어(공개 키 + 개인 키)에 의존하며, 이들은 서로 일치하는 암호화 파일입니다. 생성 후 "공개 키"를 GitHub에 제공("바인딩")하고, "개인 키"는 로컬 기기에 보관합니다: + +1. 개인 키: 로컬 기기(예: 컴퓨터)의 지정된 디렉토리(일반적으로 ~/.ssh/)에 저장되며, "나만의 전용 열쇠" 역할을 합니다. 절대 다른 사람과 공유해서는 안 됩니다. +2. 공개 키: 공개적으로 공유할 수 있는 "자물쇠"입니다 — 이를 GitHub 계정의 "SSH keys list"에 복사해야 합니다("바인딩" 조작). + +SSH를 통해 GitHub 저장소를 조작할 때(예: git push git@github.com:xxx/xxx.git): + +- 로컬 기기가 개인 키를 사용하여 "조작 요청"을 암호화하여 GitHub에 전송합니다; +- GitHub가 요청을 받은 후, 이전에 바인딩한 공개 키를 사용하여 복호화를 시도합니다; +- 복호화가 성공하면 기기가 승인된 것으로 확인되고 조작이 허용됩니다. 그렇지 않으면 접근이 거부됩니다. + +### "바인딩"의 구체적인 단계(핵심 프로세스) + +원리를 이해하면 실제 조작은 간단합니다 — 핵심은 "키 페어 생성 → 공개 키를 GitHub에 업로드"입니다: + +1. 로컬에서 SSH 키 페어 생성 + 1. Trae를 사용하여 공개 키 가져오기(권장) + 프롬프트: `Help me create the SSH key needed for GitHub login. My email is your_email@gmail.com , Please return the public key for me to copy` + + ![](/zh-cn/stage-2/backend/git-workflow/images/image18.png) + + 프롬프트를 입력한 후, 왼쪽 터미널에서 Enter 키를 눌러야 합니다. 그렇지 않으면 명령이 실행되지 않고 계속 대기합니다. Trae는 조건 판단을 실행할 수 없으므로, 계속 Enter를 누르기만 하면 됩니다. + + 마지막으로, 오른쪽의 Trae가 읽어온 공개 키를 반환한 것을 볼 수 있습니다. 이를 복사하여 다음 단계에서 붙여넣을 준비를 하세요. + + ![](/zh-cn/stage-2/backend/git-workflow/images/image19.png) 2. 수동으로 공개 키 가져오기 + 로컬 터미널을 엽니다(Windows에서는 Git Bash 또는 PowerShell 사용; macOS/Linux에서는 터미널 사용), 다음 명령을 입력하세요(your_email@example.com을 GitHub 계정 등록에 사용한 이메일로 교체): + + ```bash + ssh-keygen -t ed25519 -C "your_email@example.com" + ``` + + 1. Enter를 눌러 기본값을 수락합니다(기본 파일 경로, 비밀번호 없음, 또는 필요에 따라 비밀번호 설정). 이렇게 하면 ~/.ssh/ 디렉토리에 두 개의 파일이 생성됩니다: + - id_ed25519: 개인 키(로컬에 저장, **절대 공유하지 마세요**) + - id_ed25519.pub: 공개 키(GitHub에 업로드 필요) + +2. 공개 키를 GitHub 계정에 "바인딩" + +이것이 핵심 바인딩 단계입니다 — 로컬 공개 키를 GitHub 계정의 "SSH keys list"에 추가합니다: + +1. 공개 키 내용 복사: + 1. Trae: + 2. Windows: 메모장으로 C:\Users\\.ssh\id_ed25519.pub을 열고 모든 내용을 복사합니다; + 3. macOS/Linux: 터미널에서 cat ~/.ssh/id_ed25519.pub을 실행하고 모든 출력을 복사합니다(시작의 SSH-ed25519부터 끝의 이메일까지). +2. GitHub에 로그인하고 "SSH Key Management" 페이지로 이동합니다: + 1. 오른쪽 상단 프로필 사진 클릭 → Settings → 왼쪽 메뉴 SSH and GPG keys → New SSH key 클릭. + ![](/zh-cn/stage-2/backend/git-workflow/images/image20.png)![](/zh-cn/stage-2/backend/git-workflow/images/image21.png) + 2. 아무 제목이나 입력하고(예: your local computer's SSH), 방금 가져온 SSH 공개 키를 여기에 붙여넣으세요. + +![](/zh-cn/stage-2/backend/git-workflow/images/image22.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image23.png) + +3. 바인딩 성공 여부 확인 + +터미널에서 다음 명령을 입력하세요(**Trae로도 다음 작업을 수행할 수 있습니다**) GitHub가 기기를 인식할 수 있는지 테스트합니다: + +```bash +ssh -T git@github.com +``` + +- Hi [your GitHub username]! You've successfully authenticated... 와 같은 내용이 보이면 키 바인딩에 성공한 것입니다; +- 오류가 발생하면, 일반적으로 공개 키 복사가 불완전하거나, 개인 키 권한이 너무 높은 경우(로컬 ~/.ssh/ 디렉토리는 본인만 읽고 쓸 수 있어야 함) 등입니다. 필요에 따라 확인하세요. + +### 중요 참고 사항 + +여러 기기(예: 노트북과 데스크톱)가 있는 경우, 각 기기에 대해 별도의 SSH 키 페어를 생성하고, 각 공개 키를 동일한 GitHub 계정에 바인딩해야 합니다 — 각 기기마다 고유한 "출입 카드"가 있습니다. + +개인 키를 절대 공유하지 마세요(GitHub에 업로드하거나 다른 사람과 공유하지 마세요). 그렇지 않으면 다른 사람이 귀하인 척하여 저장소를 조작할 수 있습니다. 개인 키가 유출된 경우 즉시 GitHub에서 해당 공개 키를 삭제하고 새로운 키 페어를 생성하세요. + +SSH 바인딩 후, HTTPS 형식(예: https://github.com/username/repository.git) 대신 SSH 형식의 저장소 주소(예: git@github.com:username/repository.git)를 사용하여 조작하세요. 이전에 HTTPS로 저장소를 클론한 경우, git remote set-url origin ``로 프로토콜을 전환할 수 있습니다. + +# Trae를 사용한 GitHub 조작 + +Git이 무엇인지, GitHub가 무엇인지, SSH가 무엇인지, 그리고 이를 어떻게 구성하는지 설명했습니다. 이제 Trae를 자유롭게 사용하여 Git 조작을 수행할 수 있습니다. 먼저 원격 저장소를 로컬 기기에 클론하는 방법을 배워보겠습니다. + +## Git clone: 기존 저장소 다운로드 + +클론하고자 하는 저장소 주소를 직접 알려주면 됩니다 + +![](/zh-cn/stage-2/backend/git-workflow/images/image24.png) + +## Git pull: 원격 저장소에서 업데이트 가져오기 + +저장소를 업데이트하기 전에, 여러 사람이 유지 관리할 수 있으므로 먼저 최신 변경 사항을 가져와야 합니다. 그 후 파일을 수정하고 푸시할 수 있습니다. + +**잘못된 저장소에 푸시하는 것을 방지하기 위해 폴더 이름과 그 상대 경로 또는 절대 경로를 포함하세요.** + +prompt:`Help me pull this repository AIID-TEST in ./AIID-TEST.` + +## Git commit & Git push: 업데이트를 스테이징하고 GitHub에 푸시 + +모든 준비가 완료되면 로컬 파일을 수정하고, 폴더에 항목을 추가하거나 삭제해 보세요. 그런 다음 Trae가 변경 사항을 감지하고 GitHub에 푸시하도록 도와달라고 요청하세요. + +prompt:`I finished. Commit and push to the repository AIID-TEST in ./AIID-TEST.` + +![](/zh-cn/stage-2/backend/git-workflow/images/image25.png) + +푸시 성공. 이제 GitHub에서 업데이트된 내용을 볼 수 있습니다. + +# 참고 자료 + +- Pro Git book https://git-scm.com/book/en/v2 +- GitHub Docs https://docs.github.com/en diff --git a/docs/ko-kr/stage-2/backend/modern-cli/index.md b/docs/ko-kr/stage-2/backend/modern-cli/index.md new file mode 100644 index 0000000..1ae2059 --- /dev/null +++ b/docs/ko-kr/stage-2/backend/modern-cli/index.md @@ -0,0 +1,801 @@ +# CLI AI 编程工具 + +在本教程中,我们将介绍直接在命令行中运行的 AI 编程 Agent。它们和之前学过的 Trae、Cursor 中的 Agent 不同,CLI AI 编程工具只能在终端中使用。与集成在 AI IDE 里的 Agent 相比,它们通常具有更长的上下文窗口、更快的工具调用速度,并且可以兼容更多种类的大模型。在最新的 AI Vibe Coding 实战中,我们往往会优先使用 CLI AI 编程工具,而不是 IDE 内置的编码 Agent。 + +## 从 CLI 说起 + +还记得我们之前介绍过的 CLI 吗?CLI 指的是通过终端或命令提示符,用纯文本命令来操作软件应用,而不是依赖图形界面(GUI——你可以简单理解为电脑或手机上带按钮、可以点击操作的界面,不需要输入命令)。 + +> 在 Windows 上,常见的终端有“命令提示符(cmd)”和 “PowerShell”。你可以在电脑的运行/搜索框中输入 “cmd” 或 “powershell” 来启动这些命令行程序。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image1.png)![](/zh-cn/stage-2/backend/modern-cli/images/image2.png) + +CLI 天生适合文本命令操作,在一小部分极客(追求极致的编程爱好者)群体中,CLI 甚至比 GUI 更受欢迎——他们希望所有操作都通过键盘完成,觉得动鼠标反而会拖慢自己的编码效率。 + +在工业界,CLI 往往也是最常见的接口形式,因为 GUI 需要操作系统额外绘制界面、管理窗口,对计算机资源的要求更高;而 CLI 只需要把收到的命令传给系统执行即可。因此,在连接大规模服务器集群时,我们通常只通过 CLI 进行交互。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image3.png) + +对于许多没有 CLI 经验的同学来说,可能会觉得 CLI 操作很复杂、命令太多,甚至担心“一不小心就把电脑搞坏”。不用担心。还记得我们在前面教程里,经常让 Trae 帮忙完成各种基础操作吗?这里也可以完全照搬这个思路——我们可以让 CLI 编程工具帮我们执行所有 CLI 操作:让它帮你进入指定文件夹、搜索和处理文件、运行或复制开源项目等。整个过程都可以通过和 CLI AI 编程工具的对话来完成。 + +## 和 AI IDE 有什么不同 + +我们可以把 CLI AI 编程工具类比成之前学过的 z.ai 和 Trae。某种意义上,CLI AI 编程工具可以看成是一种特殊的 z.ai:它们同样只需要一个简单的对话入口,就会自动为你执行所有需要的操作(只是有时你需要手动打开浏览器查看最终效果)。而如果类比 AI IDE,那么 CLI AI 编程工具可以被看作是 IDE 中的 Agent 模块——也就是侧边那块对话区域。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image4.png)![](/zh-cn/stage-2/backend/modern-cli/images/image5.png) + +不过,由于不同 AI IDE 对 Agent 的实现方式不同,能力差异也很大,AI 编程效果经常不稳定,因此 CLI AI 编程工具通常由大型科技公司直接开发,例如 Claude 背后的 Anthropic、ChatGPT 背后的 OpenAI 等。 + +相比其他 AI 编程 Agent,直接使用这些大厂产品往往是较优的实践,尤其是 Claude Code 本身就是为 Anthropic 内部研发团队服务的工具,从一开始就围绕“满足工程师真实需求”来设计。 + +为了更直观地对比,我们可以简单看看 Claude Code 和某款 AI IDE Agent 的差异(这里以 Cursor 为例): + +| 功能特性 | Claude Code | Cursor | 更优者 | +| ----------------- | ------------- | --------------- | ----------- | +| 自动任务执行 | ✅ 非常强 | ❌ 能力有限 | Claude Code | +| IDE 集成 | ❌ 仅命令行 | ✅ 原生 VS Code | Cursor | +| 实时代码补全 | ❌ 无 | ✅ 体验极佳 | Cursor | +| 多文件操作 | ✅ 非常强 | ⚠️ 还不错 | Claude Code | +| GitHub 一体化操作 | ✅ 可直接提交 | ⚠️ 需要手动操作 | Claude Code | +| 学习成本 | ⚠️ 中等 | ✅ 上手简单 | Cursor | +| 上下文长度 | ✅ 非常长 | ⚠️ 较好 | Claude Code | +| 调试辅助 | ✅ 自动化 | ⚠️ 较多需手动 | Claude Code | + +表格来源: + +简单说,CLI AI 编程工具通常可以: + +- 支持更长时间的连续对话(甚至可以帮你“工作一整天”)。 +- 提供更长的上下文窗口(不再频繁需要你说“继续”)。 +- 响应速度更快(可以接入更多自定义模型 API)。 + +在编码相关操作上,它们通常比大部分 IDE 内置 Agent 更聪明、更稳定。 + +## 常见的 CLI AI 编程工具 + +目前虽然有很多开源实现,但在实践中我们只推荐两大类型的 CLI AI 编程工具,作为“首选组合”。你可以根据自己的习惯任选其一,强烈建议都试一试,再选出最适合你的那一个。 + +- Codex 使用 GPT-5,在整体能力上更强; +- Claude Code 通过 GLM 4.6 转发 API,整体体验接近 Claude 4,但价格更便宜。 +- OpenCode 可以随意切换并搭配模型, 提供免费模型, 可以更好的控制成本。 + +不过,哪一个在实际项目中更好用,只能通过亲自测试来判断。掌握多种 AI 编程工具始终是有益的:熟练以后,你可以在不同场景下灵活切换 Claude Code、Codex 或 Trae。如果尝试多次后发现某个工具效果一般,可以直接换一个工具或模型继续试验。 + +同时,由于模型版本更新非常迅速,建议你优先选择在“性价比(效果 / 成本)”上表现最好的方案。 + +### Claude Code + +Claude Code 是由 Anthropic 基于 Claude 大模型能力开发的一款 AI 编程工具。它的主要交互场景在终端,同时也支持作为 VS Code 插件来使用。类似于 AI IDE 中的 Agent,它可以深度理解开发者的代码仓库,并通过自然语言指令完成端到端的开发任务——包括代码编辑、修复 Bug、执行和修复测试、管理 Git 工作流(例如解决合并冲突、创建 PR)、复杂代码讲解、执行终端命令等。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image6.png) + +Claude Code 的优势主要体现在:极长的上下文窗口(可以处理完整文件甚至小型项目)、可以主动澄清模糊需求、自动规划和分配执行任务,以及对整个代码库内容的深度理解和解释能力。与普通 IDE Agent 相比,它更适合“沉浸式 vibe coding” 的开发流程。 + +在实际使用中,你可以通过对话指令,让它帮你创建新项目、执行 CLI 操作(例如整理文件夹、批量重命名文件、部署开源项目等)、配置开发环境(例如安装和调试 Python 环境)。如果觉得某段代码难以理解、某个目录结构不清晰,也可以直接让 Claude Code 生成结构化的分析文档,或者对特定内容进行分步骤讲解。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image7.png)![](/zh-cn/stage-2/backend/modern-cli/images/image8.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image9.png)![](/zh-cn/stage-2/backend/modern-cli/images/image10.png) + +如果你想系统地学习 Claude Code,可以参考 Andrew Ng 与 Anthropic 联合推出的课程: + + +接下来,我们将学习如何使用 Claude Code。由于直接使用官方 Claude Code 的成本往往非常高(如下图所示),我们会转而使用兼容 Claude Code 协议、但基于其他大模型的 API 平台。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image11.png) + +你需要学习下面几种不同方案(最好都尝试一遍),最后选择最适合你的那一种作为主要实践路径。 + +第一种方式是直接使用“兼容 Anthropic 接口”的 API。随着 Claude Code 的流行,越来越多的大模型服务商开始支持 Anthropic 风格的调用方式。常见的服务商包括 GLM、Kimi、DeepSeek 和 Siliconflow 等,它们都提供了兼容的 API 接口。关于具体配置,我们会在后文细讲。 + +需要注意的是,Claude Code 通常会消耗大量 token,如果你担心 API 调用产生过高费用,可以考虑购买 GLM 的月度套餐(大约 20 元/月)来控制成本。如果你想先感受一下实际花费,也可以先充值 10 元做小规模试验。 + +另一种方式是使用 “Claude Code Route” 项目。它是一个开源工具,不仅支持所有常见的 API 调用接口,还允许你针对不同场景精细配置要使用的模型,并且支持对接本地部署的大模型。但由于这一方案的配置相对复杂,建议你先从第一种方案入手。 + +#### 使用智谱 GLM 作为后端(推荐) + +GLM(General Language Model)是智谱 AI 自主研发的一系列大型语言模型。GLM-4.6 是当前 GLM 系列的最新版本,其核心亮点是在代码能力上的优异表现(在公开基准和真实任务中对标 Claude Sonnet 4,在国内处于第一梯队)。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image12.png) + +它还将上下文窗口扩展到 200K,可以更加从容地处理长文本和大体量代码,同时加强了推理与工具调用能力,在性能和成本之间取得了不错的平衡。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image13.png) + +在接入 GLM 之前,我们需要先安装 Claude Code。 + +如果你觉得命令行安装步骤麻烦,或者中途出现错误,可以直接让 Trae 的 Agent 帮你完成安装。 + +```python +# 安装 Claude Code +npm install -g @anthropic-ai/claude-code + +# 进入你的项目 +cd your-awesome-project + +# 启动 Claude Code +claude + +# 按 Ctrl+C 退出 Claude +``` + +接下来,我们需要修改 Claude Code 的默认 API 请求地址,使其支持 GLM 的 API 服务。你可以直接复制下面的内容,让 Trae 帮你创建对应的环境变量;也可以选择把它们永久写入系统环境变量(如果出现问题,同样可以让 Agent 帮忙修改)。 + +首先,你需要先获取 GLM 的 API Key,并用你自己觉得最方便的方式保存好。 + +国内版地址: +国际版地址: + +如果你使用的是 **国内版 GLM**,请使用以下变量配置: + +```python +# 在 Cmd 中运行以下命令 +# 注意将 `your_zhipu_api_key` 替换为你刚刚获取到的 API Key +setx ANTHROPIC_AUTH_TOKEN your_zhipu_api_key +setx ANTHROPIC_BASE_URL https://open.bigmodel.cn/api/anthropic +``` + +如果你使用的是 **国际版 GLM**,请使用下面的配置: + +```python +# 在 Cmd 中运行以下命令 +# 同样注意替换掉 `your_zai_api_key` +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic +``` + +你可以直接在 Trae 中输入类似下面的提示词: + +⚠️ 如果你是通过 Trae 帮你配置“永久环境变量”,那么配置完成后 **必须重启 Trae**,否则它内置终端里的环境变量不会更新,可能导致登录失败或网络连接错误。 + +```python +Based on my environment variable settings: +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic + +and my key(Replace it with your own key): +681fea485851d29060cc.13gfaendggaFOhb + +please help me configure and start Claude Code +``` + +你会看到类似下面的过程输出: + +![](/zh-cn/stage-2/backend/modern-cli/images/image14.png) + +> 💡 什么是环境变量? +> +> 环境变量本质上是一组存储在操作系统中的“键值对”配置信息,通常以 “变量名 = 具体值” 的形式存在。只要提前在终端或系统设置中配置好,程序就可以随时读取这些变量来获取相关信息。由于环境变量可以直接在终端中写入,而无需修改代码本身,我们通常会把访问大模型所需的密钥存放在环境变量里,以避免泄露。程序只需要读取对应环境变量,就能完成大模型调用。 +> +> 在 Windows 系统中,环境变量除了用于存储大模型的访问密钥,还常常用来保存命令行工具的“调用路径”。 +> +> 我们知道终端本身也是一个程序。有时我们希望在终端里启动某个外部程序,例如在终端中输入 `claude` 来启动 Claude Code。之所以可以直接输入 `claude` 就运行,是因为终端会读取系统的环境变量,其中的 PATH 变量里包含了 Claude Code 可执行文件所在的目录,所以终端能够找到并执行它(等价于在终端中粘贴那段程序的绝对路径再按回车)。 +> +> 一个典型的环境变量可能长这样:`PATH=C:\Windows\system32;C:\Program Files\Python`。这样我们就可以在任何路径下执行系统中的这些程序,例如直接在命令行键入 `python` 启动 Python 解释器。 +> +> 如果你想查看系统当前的环境变量,可以在 Windows 搜索中输入“环境变量”,在弹出的“编辑系统环境变量”窗口中就能看到所有变量及其值。有的变量用于存储大模型密钥,有的则用于添加程序目录,方便在任意路径下调用。 + +现在,你就可以使用最新的 GLM 来进行 Claude Code 开发了。你可以尝试重新跑一遍之前的项目,或者重新挑战那些 Trae 没有完成好的任务,对比看看体验上的差异。 + +🎉 反复“推倒重来”并不是浪费时间——你每重做一遍,技能都会更扎实一分。 + +用和 GLM 完全相同的思路,也可以轻松接入其他支持 Anthropic 兼容格式的接口。 + +#### 使用 Kimi K2 作为后端(推荐) + +Kimi K2 是月之暗面(Moonshot AI)推出的新一代大语言模型,在代码理解和生成能力上表现出色。Kimi K2 支持超长上下文窗口(最高可达 200K tokens),能够轻松处理大型代码库和复杂项目。 + +**核心优势:** + +- **超长上下文**:支持 200K 上下文窗口,可以一次性处理整个项目的代码 +- **代码能力强**:在代码生成、重构和调试方面表现优异 +- **中文理解好**:对中文编程需求的理解更加准确 +- **工具调用稳定**:支持稳定的函数调用和工具使用 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +参考文档: + +```bash +export ANTHROPIC_BASE_URL=https://api.moonshot.cn/anthropic +export ANTHROPIC_AUTH_TOKEN=sk-YOURKEY +``` + +#### 使用 Minimax 作为后端(推荐) + +Minimax 是稀宇科技(MiniMax)推出的新一代大语言模型,在编程任务上表现优异。Minimax 模型以其出色的推理能力和代码生成质量而闻名,特别适合复杂的编程场景。 + +**核心优势:** + +- **推理能力强**:在复杂逻辑推理和代码架构设计方面表现出色 +- **代码质量高**:生成的代码结构清晰、可读性好 +- **多语言支持**:支持多种编程语言的代码生成和转换 +- **响应速度快**:API 响应速度快,适合高频调用场景 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_MINIMAX_API_KEY +export ANTHROPIC_MODEL=MiniMax-M2.7 +``` + +#### 使用 DeepSeek 作为后端(推荐) + +DeepSeek 是深度求索推出的开源大语言模型,以其出色的代码能力和高性价比受到开发者欢迎。DeepSeek Coder 专门针对编程任务进行了优化训练。 + +**核心优势:** + +- **代码能力突出**:在代码生成、代码理解和 Bug 修复方面表现优异 +- **开源可定制**:模型开源,可以根据需求进行微调 +- **性价比高**:API 价格相对较低,适合高频使用 +- **中文支持好**:对中文编程场景理解准确 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic +export ANTHROPIC_AUTH_TOKEN=YOU_DEEPSEEK_API_KEY +export API_TIMEOUT_MS=600000 +export ANTHROPIC_MODEL=deepseek-chat +export ANTHROPIC_SMALL_FAST_MODEL=deepseek-chat +export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 +``` + +#### 使用火山引擎 Coding Plan 作为后端(推荐) + +火山引擎(Volcano Engine)是字节跳动旗下的云服务平台,提供企业级的 AI 模型服务。火山引擎的 Coding Plan 专门为编程场景优化,提供稳定、高效的代码生成能力。 + +**核心优势:** + +- **企业级稳定性**:提供服务等级协议(SLA),保障服务稳定性 +- **代码场景优化**:针对编程任务进行了专门优化 +- **丰富模型选择**:支持多种模型,包括 Doubao-pro、Doubao-lite 等 +- **国内访问快**:国内节点部署,访问速度快 + +**获取 API Key:** + +访问 注册并获取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://ark.volces.com/api/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_VOLCANO_API_KEY +export ANTHROPIC_MODEL=doubao-pro-32k +``` + +#### 其他兼容 Anthropic 的 API + +Siliconflow: + +```bash +export ANTHROPIC_BASE_URL="https://api.siliconflow.cn/" +export ANTHROPIC_MODEL="moonshotai/Kimi-K2-Instruct-0905" # 可以自行修改所需模型 +export ANTHROPIC_API_KEY="YOUR_SILICONCLOUD_API_KEY" # 请替换 API Key +``` + +阿里云 DashScope(Aliyuncs): + +```python +export ANTHROPIC_BASE_URL="https://dashscope.aliyuncs.com/apps/anthropic" +export ANTHROPIC_API_KEY="YOUR_DASHSCOPE_API_KEY" +``` + +::: details 使用 Claude Code Route 作为后端(进阶用法) + +上面我们讲解了如何用 GLM 官方 API 替换 Claude Code 的 Anthropic 接口。接下来,我们来看一下 Claude Code Router 这个工具是如何让 Claude Code 适配更多模型 API 的。 + +[Claude Code Router](https://github.com/musistudio/claude-code-router) 是一款专门为 Claude Code 设计的智能路由增强工具。它的核心作用,是帮助用户按需将 AI 请求分发到不同平台上的模型,并可以高度自定义。它支持接入几十个平台,包括 OpenRouter、DeepSeek、Ollama、Gemini 等,也可以按场景将任务路由到特定模型,比如 GLM-4.5、Kimi-K2、Qwen3-Coder 等。举例来说,你可以将后台任务自动交给本地 Ollama,以节省成本;将长文本 / 长代码任务交给 Gemini-2.5-Pro;把代码讲解交给 DeepSeek。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image16.png) + +该工具还提供了方便的 UI/CLI 配置管理能力,并通过"转换器(converter)"适配不同平台的 API 格式。它支持 GitHub Actions 等自动化集成以及自定义扩展,解决了"单一模型无法覆盖所有场景"以及"频繁切换平台很麻烦"的问题,帮助用户更灵活、低成本地利用 AI 工具。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image17.png) + +下面我们简单介绍如何安装 Claude Code Router。大致需要以下步骤(同样可以让 Trae 帮你执行),以准备好相关环境: + +```markdown +npm install -g @anthropic-ai/claude-code +npm install -g @musistudio/claude-code-router +``` + +安装完成后,你需要确认本地可以使用 `ccr` 命令。如果看到类似下面的输出,说明安装成功: + +![](/zh-cn/stage-2/backend/modern-cli/images/image18.png) + +接下来,有两种方式来初始化和配置模型: + +- 使用 CCR 自带的 UI,在浏览器中打开它提供的配置页面进行操作; +- 直接修改 CCR 的默认配置文件(本质上 UI 也是在修改配置文件,只是提供了更直观的界面)。 + +如果选择使用 CCR UI,你会看到类似下面的界面: + +![](/zh-cn/stage-2/backend/modern-cli/images/image19.png) + +此时点击 "Add Provider" 按钮,就会看到如下界面。你需要: + +1. 在 Name 中输入模型提供商的名字; +2. 在 API Full URL 中填写该提供商的 OpenAI 兼容接口地址; +3. 在 API Key 中填写对应平台的 API Key; +4. 在 Models 区域中填写模型名称,点击 "Add Model" 添加; +5. 最后点击 "Save" 保存配置。 + +(界面往下滚动还有很多高级选项,但目前你可以先忽略它们。) + +![](/zh-cn/stage-2/backend/modern-cli/images/image20.png) + +下面是 DeepSeek 与 Kimi 的配置示例: + +![](/zh-cn/stage-2/backend/modern-cli/images/image21.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image22.png) + +保存模型配置后,还需要在右侧 Router 区域中指定默认模型(Default)。点击对应的下拉选择,将其设置为 `kimi`(推荐),然后在右上角点击 `Save and Restart`。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image23.png) + +之后,只需在终端中输入 `ccr code`,即可通过 Claude Code Router 启动 Claude Code 的编码工作流。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image24.png) + +::: + +#### Claude Code 的进阶用法 + +很多人最开始使用 Claude Code 时,只把它当成普通对话工具来用。但实际上,它内置了很多丰富的能力,能够让你使用起来更高效、灵活。下面是一些常见命令和用法示例: + +参考文档: + + + + +| 命令 | 作用 | 示例 | +| ----------------- | ----------------------------------------- | ---------------------------------------- | +| claude | 启动交互模式 | `claude` | +| claude "query" | 执行一次性任务并输出结果 | `claude "explain this project"` | +| claude -p "query" | 执行一次性问题并在结束后自动退出 | `claude -p "explain this function xxxx"` | +| claude -c | 继续最近的一次会话 | `claude -c` | +| claude -r | 恢复上一段会话 | `claude -r` | +| /resume | 在当前聊天中切换回上一段会话 | `claude -c`、`/resume` | +| /plugin | 管理插件,可安装提交与审查类扩展能力 | `/plugin` | +| /init | 用 CLAUDE.md 初始化项目说明 | `/init` | +| /clear | 清空当前会话上下文,防止信息过载 | `/clear` | +| /compact | 压缩会话历史,减少上下文 token 占用 | `/compact` | +| /cost | 查看当前消费情况 | `/cost` | +| /model | 切换使用的模型(用兼容 API 时一般可忽略) | `/model` | +| /memory | 管理 CLAUDE.md 记忆文件 | | +| /help | 显示可用命令列表 | `/help` | +| exit or Ctrl+C | 退出 Claude Code | `exit` 或 `Ctrl+C` | +| /agents | 高级功能,后文会说明 | | +| /mcp | 高级功能,后文会说明 | | + +**CLAUDE.md** + +参考: + +`CLAUDE.md` 是 Claude 在开始对话时会自动读取并加入上下文的特殊文件。因此,它非常适合用来记录: + +- 常用 bash 命令 +- 核心文件和工具函数 +- 代码风格约定 +- 测试方式说明 +- 仓库协作规范(例如分支命名、是用 merge 还是 rebase 等) +- 开发环境配置说明(例如是否使用 pyenv、推荐哪种编译器等) +- 项目中需要特别注意的行为或坑点 +- 任何你希望 Claude “记住”的信息 + +`CLAUDE.md` 本身没有强制格式要求,只要简洁、便于人类阅读即可。例如: + +``` +# Bash commands +- npm run build: Build the project +- npm run typecheck: Run the typechecker + +# Code style +- Use ES modules (import/export) syntax, not CommonJS (require) +- Destructure imports when possible (eg. import { foo } from 'bar') + +# Workflow +- Be sure to typecheck when you’re done making a series of code changes +- Prefer running single tests, and not the whole test suite, for performance +``` + +#### Claude Code 的内部原理 + +参考: + +如果你好奇为什么 Claude Code 在很多场景下比 Trae 或 Cursor 等 Agent 编程工具更好用,我们可以简单看一下它的内部工作机制。 + +其他 CLI AI 编程工具的整体实现方式也大体类似。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image25.png) + +Claude Code 会把编程任务拆解成一个持续的“感知—思考—行动—验证”循环,并在其中调用不同工具完成任务。它模仿人类开发者的工作流:不断“写代码 → 运行 → 看结果 → 再改进”。系统内部通过一个主任务循环不断执行步骤,在每一轮循环中,Claude 都可以调用不同工具——例如读写文件、执行命令、搜索代码等——再根据工具返回的真实结果决定下一步行动。 + +其中有几个关键特性值得注意: + +- **流式处理(Stream Processing)**:Claude 可以一边思考一边输出结果,而不是必须等所有代码写完再执行。 +- **智能压缩(Intelligent Compression)**:长对话容易导致上下文过长,Claude 通过将历史压缩成关键信息来减少“遗忘”的概率,并通过区分长短期记忆保证高效运行。 +- **并发控制(Concurrency Control)**:内部并行设计可以让多个任务同时进行,互不干扰。 +- **子 Agent 管理(Sub-agent Management)**:实际工作中并不只相当于一个“角色”处理所有事情,你可以管理多个子 Agent 协作处理代码,每个 Agent 负责不同任务,比如专门负责测试、专门负责写文档等。 + +### Codex + +![](/zh-cn/stage-2/backend/modern-cli/images/image26.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image27.png) + +和 Claude Code 类似,Codex 是由 OpenAI 开发的一款 AI 协作编程工具,你可以把它理解成 “OpenAI 版的 Claude Code”。它最大的优势是对 GPT-5 的高效适配。 + +从实际体验来看,GPT-5 目前响应速度更快、犯错率更低(在多轮复杂任务中正确完成的概率更高)。它的一个缺点是解释往往偏“学术”和“技术”,有时显得过于严谨、信息量很大,对初学者来说可能略微难懂。 + +你可以通过下面的命令安装 Codex: + +``` +npm i -g @openai/codex +``` + +#### 使用 OpenAI 官方 API 作为后端 + +如果直接使用 OpenAI 官方的 Codex 入口,配置会非常简单:当你已经开通 OpenAI 订阅或申请到了相应 API 配额之后,只需要在命令行中输入 `codex` 启动程序,并按提示完成登录即可。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image28.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image29.png) + +#### 使用转发 OpenAI API 的方式作为后端 + +由于官方 OPENAI API 可能存在价格较高、网络要求严格等问题,为了避免这些限制,我们也可以通过其他 API 网关服务来转发调用。 + +在这种方式下,我们只需要在第三方转发平台上购买对应的 Codex API 配额,就能获得接近原生 OpenAI Codex 的使用体验。 + +参考: +充值地址: + +需要注意的是,在拿到 token 配额后,我们还需要在本地配置好 API Key。 + +在密钥分组设置中,要注意选择专门用于 Codex 的那一项。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image30.png) + +接下来,我们需要把获取到的 Key 填入下面的提示词中,并把整段提示词交给 Trae,让它帮你完成整个配置过程: + +````bash +My API key is: [Paste your obtained sk-xxxxx key here] + +Please help me complete the following configuration tasks: + +1. Create configuration directory + - Create a `.codex` folder under my user directory + - Windows path should be: `C:\Users\[My Username]\.codex` +2. Backup existing configuration (if exists) + - Check if `.codex\config.toml` exists + - If it exists, rename it to `config.toml.bak.[current timestamp]` (timestamp format: yyyyMMddHHmmss) +3. Create configuration file + - Create `config.toml` in the `.codex` directory + - Write the following complete content: + ```toml + preferred_auth_method = "apikey" + + [model_providers.myrelay] + name = "My Relay Station" + base_url = "https://api.zyai.online/v1" + env_key = "MYRELAY_API_KEY" + wire_api = "responses" + request_max_retries = 4 + stream_max_retries = 10 + stream_idle_timeout_ms = 300000 + + [profiles.myrelay] + model_provider = "myrelay" + model = "gpt-5" + model_reasoning_effort = "medium" + + [tools] + web_search = true + +4. Set system environment variable +Variable name: MYRELAY_API_KEY +Variable value: The key I gave you + +5. Confirm completion and report back: + +The full path of the configuration file +Whether the environment variable was set successfully +I can use the command `codex --profile myrelay` to run it +```` + +配置完成后,你就可以通过 `codex --profile myrelay` 启动使用转发 API 的 Codex 了。之后的使用方式与 Claude Code 类似:只需要在对话框中随时输入你的想法和需求即可。 + +### OpenCode + +![](/zh-cn/stage-2/backend/modern-cli/images/image32.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image33.png) + +OpenCode 是一款面向开发者的开源 AI Coding Agent 平台,定位类似于 “多模型版的 Claude Code”。它以 Terminal 为核心交互入口,同时也支持编辑器集成(如 VS Code、Neovim 等),能够深度接入本地代码仓库,并通过自然语言完成从代码理解到工程执行的一整套开发流程。 + +它不是绑定单一模型的 AI 编程工具,而是一个可自由切换 GPT、Claude、Gemini 乃至本地模型的开放式 AI Coding Agent 平台。就连 OpenAI 官方也持 OpenCode 接入 Codex / OpenAI 订阅。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image34.png) + +你可以通过下面的命令安装 OpenCode: + +```bash +# Linux / Unix +curl -fsSL https://opencode.ai/install | bash + +# Windows +npm i -g opencode-ai +``` + +#### 使用 OpenCode 中的免费模型 + +在 OpenCode 中不定期会提供免费模型可以进行使用, 配置也非常简单。你可以在你需要使用 OpenCode 的位置在命令行输入 `opencode` 启动 Opencode 程序进入聊天面板。输入 `/models`命令搜索 free 关键词就可以看到带有 free 字眼的免费模型 + +![](/zh-cn/stage-2/backend/modern-cli/images/image35.png) + +在一般情况下免费模型完成编码任务会比付费 / 订阅模型要慢一些,这通常取决于模型线路是否阻塞, 是否编码高峰期以及模型本身的能力。 + +#### 使用第三方模型来作为 OpenCode 的主编码模型 + +这是 OpenCode 的核心优势, 它可以在使用同样的 MCP, Skills, 上下文的情况下允许你自由切换模型来完成不同的编码任务。下文以 OpenAI 官方的 GPT-5.3 Codex 为例,接入 OpenCode 作为主编码模型。 + +在 OpenCode 的聊天窗口中输入 `/connect` 命令选中第一条最相关指令按下 enter 键,就可以进行选择第三方模型提供商的认证授权。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image36.png) + +这里以选择 OpenAI 为例,进行回车选择认证方式。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image37.png) + +选哪种都可以,只是认证方式不同。这里选择第一种进行浏览器登录。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image38.png) + +复制此链接到浏览器上进行正常的 OpenAI 登录操作,浏览器上出现 Authorization Successful 后 OpenCode 客户端会自动跳转至选择 OpenAI 的模型界面。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image39.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image40.png) + +#### 安装 Oh My OpenAgent 插件 + +OpenCode 的强大之处还在于他有非常活跃的社区生态,你可以在 Github 上搜索出非常多与 OpenCode 相关的插件。如果说 OpenCode 是一款可以任意切换模型的 AI 协作工具的话,那么 Oh-My-OpenAgent 就是一款运行在 OpenCode 之上的 "多 Agent AI 编程指挥系统"。它可以将一个复杂任务拆给多个子任务分给不同的模型进行各司其职的工作。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image41.png) + +你可以将以下话术复制之后粘贴给上文在 OpenCode 中配置好的模型进行安装 OpenCode。 + +```text +Install and configure oh-my-openagent by following the instructions here: +https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md +``` + +以下是 Oh-My-OpenAgent 的特性以及功能说明。 + +| 特性 | 功能说明 | +| :-------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **自律军团 (Discipline Agents)** | Sisyphus 负责调度 Hephaestus、Oracle、Librarian 和 Explore。一支完整的 AI 开发团队并行工作。 | +| **Team Mode** (v4.0, 选择性启用) | 领导 Agent + 最多 8 个并行成员,实时 tmux 可视化,专用 `team_*` 工具家族。驱动 `hyperplan`(5 个敌对评论者) 和 `security-research`(3 个猎手 + 2 个 PoC 工程师)。[文档 →](docs/guide/team-mode.md) | +| **`ultrawork` / `ulw`** | 一键触发,所有智能体出动。任务完成前绝不罢休。 | +| **[IntentGate 意图门](https://factory.ai/news/terminal-bench)** | 真正行动前,先分析用户的真实意图。彻底告别被字面意思误导的 AI 废话。 | +| **基于哈希的编辑工具** | 每次修改都通过 `LINE#ID` 内容哈希验证、0% 错误修改。灵感来自 [oh-my-pi](https://github.com/can1357/oh-my-pi)。[The Harness Problem →](https://blog.can.ac/2026/02/12/the-harness-problem/) | +| **LSP + AST-Grep** | 工作区级别的重命名、构建前诊断、基于 AST 的重写。为 Agent 提供 IDE 级别的精度。 | +| **后台智能体** | 同时发射 5+ 个专家并行工作。保持上下文干净,随时获取成果。 | +| **内置 MCP** | Exa(网络搜索)、Context7(官方文档)、Grep.app(GitHub 源码搜索)。默认开启。 | +| **Ralph Loop / `/ulw-loop`** | 自我引用闭环。达不到 100% 完成度绝不停止。 | +| **Todo 强制执行** | Agent 想要摸鱼?系统直接揪着领子拽回来。你的任务,必须完成。 | +| **注释审查员** | 剔除带有浓烈 AI 味的冗余注释。写出的代码就像老练的高级工程师写的。 | +| **Tmux 集成** | 完整的交互式终端支持。跑 REPL、用调试器、用 TUI 工具,全都在实时会话中完成。 | +| **Claude Code 兼容** | 你现有的 Hooks、命令、技能、MCP 和插件?全都能无缝迁移过来。 | +| **技能内嵌 MCP** | 技能自带其所需的 MCP 服务器。按需开启,不会撑爆你的上下文窗口。 | +| **Prometheus 规划师** | 动手写代码前,先通过访谈模式做好战略规划。 | +| **`/init-deep`** | 在整个项目目录层级中自动生成 `AGENTS.md`。不仅省 Token,还能大幅提升 Agent 理解力。 | + +Sisyphus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) 是你的主指挥官。他负责制定计划、分配任务给专家团队,并以极其激进的并行策略推动任务直至完成。他从不半途而废。 + +Hephaestus (gpt-5.5) 是你的自主深度工作者。你只需要给他目标,不要给他具体做法。他会自动探索代码库模式,从头到尾独立执行任务,绝不会中途要你当保姆。名副其实的正牌工匠。 + +Prometheus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) 是你的战略规划师。他通过访谈模式,在动一行代码之前,先通过提问确定范围并构建详尽的执行计划。 + +了解完这些, 你就可以使用装好 Oh-My-OpenAgent 插件之后的 OpenCode 来完成编码任务了。 + +## CLI AI 编程工具的更多用法 + +### 用 AI 写需求文档:学会“具体化需求” + +对于大语言模型来说,抽象需求需要被“具体化”。比如:“我很饿”是一个抽象需求,我们需要把它变成:“我肚子有点饿,可能需要吃一个红豆面包,再配一杯豆浆。”——这才是一种可以被执行的、具体的需求。 + +但把抽象需求变具体,其实是一个很花精力的过程。如果我们没有见过足够多的案例,很难快速联想到该如何把抽象问题拆解成细致的模块。这种时候,最好的办法就是让 AI 帮你完成“具体化”这一步。 +比如,我想开发一个“每日计划”应用,最朴素的想法可能是: + +`Please help me write a daily planning app where I can write my plans each day and get reminders.` + +AI 确实可以在这个需求基础上直接拆分任务,然后一步步完成,但中间容易出错或理解偏差。为了降低风险,我们可以让 AI 帮我们先扩写需求: + +`Based on my needs, please elaborate and provide a more detailed Product Requirement Document for reference. My idea is: Please help me write a daily planner app that supports daily plan-writing and provides reminders .` + +这时,AI 可能会给出类似下面这样完整的 PRD: + +``` +Product Requirements Document (PRD): “Today’s Plan” App +Document Version: 1.0 +Creation Date: October 27, 2023 +Author: (Your Name/Product Manager) + +1. Product Introduction +1.1 Product Name +Today's Plan +1.2 Product Vision +“Today’s Plan” is a minimalist and highly efficient daily planning and reminder tool, dedicated to helping users eliminate procrastination and forgetfulness, plan every day clearly, and ensure tasks are carried out through an intelligent reminder system—ultimately enabling users to gain a stronger sense of control and achievement over their time. +1.3 Target Users (User Personas) +We mainly serve three types of users: +Students (Xiao Ming): +Characteristics: Multiple tasks such as courses, assignments, club activities, exam prep, needing organized time arrangement. +Pain Points: Easily forget small tasks or assignment deadlines; feel overwhelmed switching between tasks; want to build regular study and life habits. +Needs: A simple tool to list daily to-dos and provide reminders before class/self-study. +Office Workers (Zhang Wei): +Characteristics: Fast-paced work, many meetings, reports, project milestones, and personal affairs (fitness, picking up children). +Pain Points: Easily forget important meetings or work milestones; get interrupted by urgent tasks and forget the original plan; feel busy but inefficient at end of day. +Needs: Need a tool to quickly record and schedule daily work and send strong reminders at key times (e.g., 15 minutes before meetings). +Freelancers/Self-disciplined Seekers (Li Na): +Characteristics: High freedom of time, but strong self-management required for work output and personal growth. +Pain Points: Easily procrastinate, lack external supervision; start the day without a clear plan, leading to low time utilization. +Needs: Need a tool to help build a daily fixed routine (Morning Routine) and review daily achievements for positive feedback. + +2. User Stories +As a user, I want to quickly create today’s plan list so I have an overview of all my tasks for the day. +As a user, I want to set specific start and end times for each task so I can create a visual timeline. +As a user, I want to receive push notification reminders before a task starts so I won’t miss any important arrangements. +As a user, I want to customize the reminder time (such as 5, 15, or 60 minutes in advance) so reminders better fit my habits. +As a user, I want to easily mark completed tasks so I can feel accomplished and clearly see my progress. +As a user, I want to see a summary of my completed plans at the end of each day for reviewing and self-motivation. +As a user, I want to conveniently edit and delete tasks to handle last-minute changes. +As a user, I want to view plans and achievements from previous days to review my efficiency and habits. + +3. Feature Breakdown +Core Features (MVP - Minimum Viable Product) +Module 1: Plan Management +3.1.1 Daily Plan Homepage +Interface: “Today” as the core view, current date shown at the top. +View: Timeline list, clearly showing tasks scheduled from morning to evening. Tasks without a time can be listed in the top or bottom “To-do List” section. +Interactions: +Click the “+” button in the bottom right to quickly create a new task. +Pull down to refresh the page. +Swipe left/right to view yesterday’s and tomorrow’s plans. +3.1.2 Create/Edit Task +Entry: Click “+” on the homepage or a time slot in the list. +Fields: +Task title (required): Briefly describe the task, e.g., “10 AM Weekly Product Meeting.” +Task time (optional): +Set “start time” and “end time.” +Provide “all-day” option for unspecified time tasks. +Default time picker should be quick and convenient. +Reminder setting (required, with default value): See Module 2. +Notes (optional): Add further descriptions, links, or location info. +Actions: Save, cancel, delete task. +3.1.3 Task Interaction +Mark as complete: Checkbox before each task; checking adds a strikethrough and gray background, indicating completion. Can unmark if needed. +Edit task: Click the task itself to enter edit page. +Delete task: Swipe left on a task to reveal “Delete” button. +Module 2: Smart Reminder System +3.2.1 Reminder Trigger +Mechanism: Based on task’s set “start time” and the user’s “reminder lead time,” send a push notification from device. +Offline Support: Locally scheduled reminders must trigger even if user is offline. +3.2.2 Reminder Content & Format +Notification title: App name “Today’s Plan.” +Body: “Reminder: [Task Title] will start at [Start Time].” E.g., “Reminder: Product Meeting will start at 10:00.” +Sound: Use system default or offer several simple, effective tones. +3.2.3 Reminder Settings +Global Settings (in Settings page): +User can set a default reminder time, e.g., “15 minutes before task starts.” New tasks adopt this by default. +Single Task Settings (in create/edit page): +Users can override global settings for important tasks, choosing specific reminder times like "on time," "5 minutes early," "30 minutes early," or "1 hour early." +Provide “no reminder” option. +Subsequent Features (V1.1, V2.0) +3.3 Daily Review & Statistics +Push a summary notification at a set time every night (e.g., 22:00): “How was your day? Take a look at your achievements!” +Generate a simple daily report card: shows total planned tasks, completed tasks, completion rate, plus an encouraging message. +3.4 History Review +Calendar view to click on any past day and check its plans and completion status. Days with high completion rates marked with a special color. +3.5 Templates +Allow users to save a successful daily plan as a template, e.g., “Efficient Workday,” “Relaxing Weekend.” +When creating tomorrow’s plan, one-click import a template, modify slightly to save time. +3.6 Themes & Personalization +Offer dark mode. +Allow changing several primary color themes. + +4. Non-Functional Requirements +4.1 Performance +Response: App launch time under 2 seconds; adding/editing tasks must be smooth and lag-free. +Resource Use: Low battery and memory consumption in background; do not over-consume resources waiting for reminders. +4.2 Usability +Minimal & intuitive: UI must be minimal, primary functions accessible within 3 clicks. No tutorial needed for new users. +Error tolerance: Offer undo (e.g. brief undo after mistakenly deleting a task). +4.3 Reliability +Reliable reminders: Reminder function is the product’s lifeline; must guarantee 99.99% timely and accurate delivery. +Data loss-free: User plans must be reliably stored locally. Future versions can support cloud sync to prevent data loss on device change. +4.4 Compatibility +Platform: Support major iOS and Android versions (latest 3-4 releases). +Screen: Layout must fit various phone screen sizes. + +5. Roadmap +V1.0 (MVP): +Goal: Validate core value—planning & reminders. +Features: Complete all “Core Features” described above (Plan management, smart reminders). +V1.1 (Quick Optimization): +Goal: Improve retention and achievement. +Features: Add “Daily Review & Statistics,” “History Review.” +V2.0 (Enhanced Experience): +Goal: Increase efficiency and personalization. +Features: Add “Templates,” “Themes & Personalization,” and start developing “Cloud Sync.” +``` + +对比我们最开始那句“帮我写一个每天可以记计划并提醒的应用”,现在这份文档已经详细得多了。你可以根据自己的真实需求,对其中的内容进行增删修改;对于某些你不确定的模块,也可以继续让 AI 提供更多备选方案,你再挑选、合并成最终版本。 + +通过这种方式,我们可以很轻松地把抽象想法变成具体描述。对 AI 开发来说,“具体”就是生产力:需求越具体,越容易得到结构稳定、质量较高的项目。你可以尝试用这种方式重做一下之前的某个小项目,对比一下效果差异。 + +如果你觉得这类“需求提示词”太长,非常自然的做法,是把它单独写进一个 markdown 文档中,作为你的“需求文档 / 开发文档 / PRD”。之后每次让 AI 写项目时,只需要让它“参考这份文档”,而不是每次都重打一遍长提示。你也可以在迭代中不断完善这份文档,让后续项目直接受益。 + +下面是一些其他常见的使用场景: + +### 管理文件夹 + +我们可以尝试用 CLI AI 编程工具来管理当前文件夹中的各种文件。比如,你有一堆杂乱无章的文件,需要整理归类,就可以对 Claude Code 或 Codex 说: + +`Please help me organize the contents of the current folder. I want to group files with the same content together & I want to group files from the same time period together. Please help me handle this.` + +### 开发新项目 + +这和我们之前在 z.ai、Trae 中的用法几乎完全一样——我们也可以直接用 CLI AI 编程工具来从零开发新项目。当然,最好提前准备好一份需求文档。 + +需求文档越细致,最终效果越好。你可以根据不断变化的想法,对文档做多轮优化;文档越完善,代码实现就越稳定、越成熟。 + +### 部署开源项目(例如 Dify) + +对于刚接触计算机的同学来说,从 GitHub 上部署一个开源项目往往很有难度。但我们完全可以把这件事交给 Claude Code,就像我们在 Dify 教程中做的那样: + + + +如果我想在本地跑起自己的 Dify,只需要把这个链接扔给 Claude Code,然后输入: + +`I want to deploy this GitHub project ``https://github.com/langgenius/dify`` . Please help me clone the project and run it.` + +收到你的请求后,Claude Code 会自动完成一系列操作,包括从 GitHub 拉取代码、配置运行环境、启动项目等。如果中间某一步出错或项目启动状态不正常,你再根据提示进行少量人工处理即可。除了 Dify,你也可以用 Claude Code 帮你部署大部分常见的 GitHub 开源项目——你只需要一个对话框,再加上喝一杯咖啡的时间 ☕️。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image31.png) + +### 讲解代码与撰写文档 + +对于一些复杂项目,或者 AI 自动生成的大型项目,你可能会觉得代码太长、逻辑太多,很难看懂。这时就可以让 CLI AI 编程工具帮你“读代码”。你可以这样提问: + +- 请帮我解释这个项目:如何运行、如何使用、后续如何修改和继续开发? +- 请帮我说明这个项目的整体流程:程序是怎样运行的?用户在界面中可以做哪些操作? +- 请帮我为这个项目写一份完整的文档,包括开发文档和运行文档等。 +- 请基于我当前文件夹里的所有内容,写一份详细说明,并保存到指定的 markdown 文档中。 + +### 更多玩法 + +当然,CLI AI 编程工具能做的远不止上面这些。不要只把它当作“写代码工具”,而是把它看作一个具有独立行动能力的智能 Agent。你可以让它帮你: + +- 管理和整理本地文件; +- 写日记、写总结; +- 分析和修复系统错误; +- 执行各种重复性命令行任务等。 + +也许在不久的将来,它会变成你电脑上最重要、也最懂你的 AI 伙伴。 diff --git a/docs/ko-kr/stage-2/backend/stripe-payment/index.md b/docs/ko-kr/stage-2/backend/stripe-payment/index.md new file mode 100644 index 0000000..ebc7470 --- /dev/null +++ b/docs/ko-kr/stage-2/backend/stripe-payment/index.md @@ -0,0 +1,907 @@ +# 如何集成 Stripe 等收费系统 + +当你的产品已经有了页面、登录、数据库和基础后端之后,下一个现实问题就是:**怎么收费**。 + +很多人第一次接支付,会把注意力全放在"怎么跳转到付款页"上。但真正决定系统是否稳定的,不是按钮,而是整条收费链路:谁决定价格、谁确认支付成功、谁更新数据库、谁回收权限。 + +这篇文章我帮你拆成两部分: + +- **前半部分**只讲最实用的基础接入,目标是让你尽快把 Stripe 接进项目。 +- **后半部分**统一放到附录,包含 Webhook 细节、订阅事件、不同国家和地区的支付方案差异。 + +> 💡 建议先学完这些章节再继续 +> +> - [从数据库到 Supabase](../database-supabase/) +> - [大模型辅助编写接口代码与接口文档](../ai-interface-code/) +> - [如何部署 Web 应用](../zeabur-deployment/) + +# 你将学到 + +1. 最小可行的支付系统到底长什么样。 +2. 如何用最快的方式把 Stripe 接进你的项目。 +3. 如何写提示词,让 AI 直接帮你加支付系统。 +4. 如果不是做海外 Stripe 项目,不同地区应该优先考虑什么支付方案。 + +--- + +# 第一部分:基础上手 + +## 1. 先记住 3 个原则 + +如果你只记住三件事,就记住下面这三条: + +1. **价格必须由后端决定**,不能相信前端传来的金额。 +2. **真正让权限生效的是 Webhook**,不是 `success` 页面。 +3. **你自己的数据库必须保存支付状态**,不能只依赖 Stripe 后台。 + +这三条是支付系统最核心的边界。只要边界没错,后面换 Stripe、PayPal、支付宝、微信支付,本质上都只是"接口换了,架构不变"。 + +## 2. 如果不在后端处理,而是前端直接连 Stripe,会怎么样? + +这是很多人第一次做支付时最自然的想法: + +- 页面上已经有"购买"按钮了 +- 那我能不能让前端自己去连 Stripe +- 这样是不是就不用做后端了 + +如果你只是做一个假的演示页面,这样想当然没问题。 +但如果你是真的要收钱,**这条路通常会把事情做坏**。 + +最常见的问题有这几个: + +1. **价格容易被改** + 浏览器里的请求,是用户自己电脑上发出去的。别人是可以改请求内容的。 +2. **敏感信息容易暴露** + 真正重要的密钥、价格逻辑、会员开通逻辑,本来就不该放在前端。 +3. **你没法可靠确认"这笔钱到底算不算成功"** + 用户跳到成功页,不代表你的数据库已经同步对了。 +4. **数据库状态会乱** + 用户可能说"我明明已经付钱了",但你自己的系统里根本没记上。 + +所以更安全的分工应该是: + +- 前端负责:展示按钮、发起购买、跳转页面 +- 后端负责:决定价格、创建支付会话、接收 Webhook、更新数据库 + +::: info 这一段你可以直接记成一句话 +**前端可以负责跳转,后端必须负责定价和确认。** + +只要是真收钱,就不要把"最终价格决定权"和"支付成功后的开通逻辑"放在前端。 +::: + +## 3. 什么时候适合先用 Stripe + +如果你做的是下面这些场景,Stripe 往往是最顺手的起点: + +- 面向海外用户的 SaaS +- 订阅制会员产品 +- 数字产品、模板、AI 积分包 +- 想先快速验证商业化,而不是一开始就处理太多本地支付细节 + +如果你的主要用户在中国大陆,那通常不会把 Stripe 当第一选择,这个我放到附录里统一讲。 + +## 4. 最小可行支付链路 + +先看最小版本。只要这条链路能跑通,你的支付系统就有了骨架。 + +```mermaid +flowchart LR + user["用户"] + frontend["前端页面"] + backend["你的后端"] + checkout["Stripe Checkout"] + webhook["Stripe Webhook"] + db["Supabase / 业务数据库"] + + user -->|"点击购买"| frontend + frontend -->|"请求创建支付会话"| backend + backend -->|"按后端价格创建 Session"| checkout + frontend -->|"跳转到支付页"| checkout + checkout -->|"支付完成后发送事件"| webhook + webhook -->|"校验签名并更新状态"| backend + backend -->|"写入 orders / subscriptions"| db + db -->|"前端刷新后读取最新状态"| frontend +``` + +把它翻译成人话就是: + +1. 用户点按钮。 +2. 前端找后端要支付链接。 +3. 后端用 Stripe 密钥创建支付会话。 +4. 用户去 Stripe 页面付款。 +5. Stripe 把"付款真的成功了"这件事通过 Webhook 通知你。 +6. 你的后端再去更新数据库。 + +## 5. 发起付款的标准时序图 + +如果你习惯看更规范的系统图,可以直接看这张时序图: + +```mermaid +sequenceDiagram + autonumber + actor User as 用户 + participant Frontend as 前端页面 + participant Backend as 后端 API + participant Stripe as Stripe Checkout + + User->>Frontend: 点击"升级"或"购买" + Frontend->>Backend: POST /api/billing/create-checkout-session + Note right of Frontend: 前端传 plan / userId / email\n不传最终收费金额 + Backend->>Backend: 校验套餐并映射 priceId + Backend->>Stripe: 创建 Checkout Session + Stripe-->>Backend: 返回 session.url + Backend-->>Frontend: 返回支付链接 + Frontend-->>User: 跳转到 Stripe 支付页 + User->>Stripe: 完成付款 +``` + +## 6. 快速开始 + +如果你想最快把它接进项目,照着下面这 5 步做就够了。 + +### 6.1 第一步:在 Stripe 后台创建商品和价格 + +这一步的目的,不是"先随便配点东西",而是先把 **你到底在卖什么、打算怎么收费** 这件事在 Stripe 里定义清楚。 + +在 Stripe 的模型里: + +- **Product** 表示"你卖的是什么",比如 `Pro 会员` +- **Price** 表示"这个东西卖多少钱、按什么周期卖",比如 `月付 9.9 美元`、`年付 99 美元` + +为什么要先做这一步? +因为后面当你的后端创建 Checkout Session 时,并不是直接传一个金额给 Stripe,而是要传一个已经存在的 `price_id`。Stripe 再根据这个 `price_id` 去生成真正的支付页、金额、币种和订阅周期。 + +如果你跳过这一步,后面的"创建支付链接"其实就没法做。 + +::: info 为什么这里要先停一下 +很多新手看到 `Product`、`Price` 这两个词会有点烦,觉得像是在学 Stripe 的内部术语。 + +但实际上,这一步是在做一件很朴素的事: +- 把"卖什么"定义清楚 +- 把"卖多少钱"定义清楚 +- 让后端之后能拿一个稳定的 `price_id` 去创建支付链接 + +只要把这层想明白,后面的 Checkout Session 就不会觉得抽象。 +::: + +对于一个最小可行的订阅系统,你至少先建这两个层级: + +- 一个 `Product` +- 一个或多个 `Price` + +你可以直接打开这些页面: + +- Stripe Dashboard 登录页:[Dashboard Login](https://dashboard.stripe.com/login) +- Stripe 商品与价格管理文档:[Manage products and prices](https://docs.stripe.com/products-prices/manage-prices) +- Stripe Checkout 快速开始文档:[Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- Stripe Dashboard 商品页:[Product catalog](https://dashboard.stripe.com/test/products) + +推荐你先在 **Test mode(测试模式)** 下操作,不要一开始就在正式环境里建。 + +一个最常见的最小配置是: + +- `Product`: `Pro Plan` +- `Price 1`: `pro_monthly` +- `Price 2`: `pro_yearly` + +你在后台操作时,可以按这个顺序理解: + +1. 先创建一个商品 `Pro Plan` +2. 再在这个商品下面挂两个价格 +3. 月付和年付其实是同一个商品的两种收费方式 + +完成后,你至少要记下这些信息: + +- 月付价格的 `price_id` +- 年付价格的 `price_id` +- 你自己的套餐名,例如 `pro_monthly`、`pro_yearly` + +如果你是第一次进 Stripe 后台,建议你把这一步理解成: + +- `Product` 决定支付页里卖的是什么 +- `Price` 决定支付页里收多少钱 +- 后端之后真正会用到的,主要是 `price_id` + +::: info 真正要记下来的值 +这一页里最重要的不是商品名称,而是 `price_id`。 + +后面无论是让 AI 帮你接后端,还是你自己排查问题,真正会频繁用到的,通常都是: +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- 它们背后对应的两个 `price_id` +::: + +如果你想让 AI 先带你把后台配置做完,可以直接用这个 prompt: + +```text +我现在是第一次用 Stripe,你先不要改代码,先带我在 Stripe 后台把最基本的付费配置做好。 + +请基于这些官方文档给我一步一步的操作说明: +- https://docs.stripe.com/products-prices/manage-prices +- https://docs.stripe.com/checkout/quickstart?lang=node + +我的情况是: +- 我想做一个最简单的会员付费 +- 只有两个套餐:月付和年付 +- 我现在还不懂 Product、Price 这些词 + +请你: +1. 先用最简单的话告诉我 Product 和 Price 分别是什么。 +2. 再按"先打开哪个页面 -> 点哪里 -> 填什么"的顺序教我操作。 +3. 最后提醒我,做完以后我需要从后台复制哪些内容给后端使用。 +4. 如果我容易走错,请顺便提醒我应该一直在测试模式里操作。 +``` + +### 6.2 第二步:准备环境变量 + +你通常至少需要准备这些环境变量: + +- `STRIPE_SECRET_KEY` +- `STRIPE_WEBHOOK_SECRET` +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- `APP_URL` +- `SUPABASE_URL` +- `SUPABASE_SERVICE_ROLE_KEY` + +你可以直接打开这些页面: + +- Stripe API Keys 文档:[API keys](https://docs.stripe.com/keys) +- Stripe Dashboard API Keys 页面:[API Keys](https://dashboard.stripe.com/test/apikeys) +- Stripe Webhooks 文档:[Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Stripe Dashboard Webhooks 页面:[Workbench Webhooks](https://dashboard.stripe.com/test/workbench/webhooks) + +> ⚠️ `STRIPE_SECRET_KEY` 和 `SUPABASE_SERVICE_ROLE_KEY` 都只能放在后端。 + +::: info 环境变量这一步的目的 +这一步不是为了"先把 `.env` 填满",而是为了把支付系统里最敏感的几样东西放到后端保管: + +- Stripe 的后端密钥 +- Webhook 验签密钥 +- 你自己的价格映射 + +简单理解: +前端只负责发起购买,真正的秘密和定价逻辑都应该留在服务端。 +::: + +这一步也可以直接让 AI 帮你整理: + +```text +请你先看看我这个项目现在是怎么放环境变量的,然后帮我把 Stripe 需要的环境变量整理出来。 + +请参考这些文档: +- https://docs.stripe.com/keys +- https://docs.stripe.com/webhooks + +我的情况是: +- 我是零基础 +- 我分不清哪些变量应该放前端,哪些应该放后端 +- 我也不确定当前项目应该改 `.env`、`.env.local` 还是别的文件 + +请你: +1. 先搜索当前项目里环境变量通常写在哪。 +2. 帮我列出 Stripe 接入最少需要哪些变量。 +3. 用最简单的话告诉我每个变量是干什么的。 +4. 告诉我每个变量应该去哪一个 Stripe 页面复制。 +5. 如果项目里有示例环境变量文件,请直接帮我补上变量名。 +``` + +### 6.3 第三步:后端创建 Checkout Session + +这一步你不用自己写接口,直接让 AI 参考官方文档帮你实现。 + +先把这些文档给它: + +- Stripe Checkout 快速开始:[Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- Checkout Sessions API:[Create a Checkout Session](https://docs.stripe.com/api/checkout/sessions/create) +- 订阅说明:[Subscriptions](https://docs.stripe.com/payments/subscriptions) + +然后直接贴这个 prompt: + +```text +请你先看看我当前项目的后端代码是怎么组织的,然后帮我把 Stripe 支付接进去。 + +请参考这些官方文档: +- https://docs.stripe.com/checkout/quickstart?lang=node +- https://docs.stripe.com/api/checkout/sessions/create +- https://docs.stripe.com/payments/subscriptions + +我的目标很简单: +- 用户点购买按钮后,能跳到 Stripe 的付款页面 +- 套餐只有月付和年付两种 +- 不要让我自己决定代码该放在哪,你先看项目再帮我放到合适的位置 + +请你: +1. 先搜索项目,弄清楚后端入口文件、路由文件、环境变量写法分别在哪里。 +2. 再参考官方文档,帮我把"创建 Stripe 支付链接"这一步接进去。 +3. 不要让我自己传金额,价格请用后端环境变量来决定。 +4. 做完后告诉我你改了哪些文件。 +5. 最后告诉我,我还需要去 Stripe 后台补哪些配置。 +``` + +### 6.4 第四步:前端跳转到支付页 + +这一步的目标非常简单:让定价页按钮调用你的后端接口,再跳转到 Stripe Checkout。 + +参考文档: + +- Stripe Checkout 集成说明:[Build an integration with Checkout](https://docs.stripe.com/payments/checkout/build-integration) + +给 AI 的 prompt: + +```text +帮我把项目里的"购买"按钮接上 Stripe。 + +要求: +- 不动现有页面,只改按钮点击后的逻辑 +- 点击后调用后端接口获取支付链接,然后跳转到 Stripe +- 如果出错,给用户一个简单提示(比如"支付暂时不可用,请稍后再试") + +参考文档:https://docs.stripe.com/payments/checkout/build-integration +``` + +### 6.5 第五步:Webhook 更新数据库状态 + +这是最关键的一步。 + +::: info 为什么这一步最关键 +很多人会以为"用户付完款并且跳转到了 success 页面"就算完成了。 + +不是。 + +对你的系统来说,真正重要的是: +**Stripe 有没有正式把事件打到你的 Webhook,而你的后端有没有把数据库状态更新成功。** +::: + +你也可以让 AI 按 Stripe 官方 Webhook 文档直接实现,不要自己手写。 + +参考文档: + +- Stripe Webhooks:[Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Stripe CLI:[Stripe CLI](https://docs.stripe.com/stripe-cli) +- Stripe CLI 用法:[Use the Stripe CLI](https://docs.stripe.com/stripe-cli/use-cli) + +给 AI 的 prompt: + +```text +请继续帮我把 Stripe 的"付款成功后自动生效"这一步接好。 + +请参考这些官方文档: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +我的目标是: +- 用户付完钱后,不只是跳转到成功页面 +- 而是真的把我数据库里的会员状态改成已开通 + +请你: +1. 先搜索当前项目里数据库相关代码和用户状态是怎么存的。 +2. 再帮我加 Stripe webhook。 +3. 支付成功后,把对应用户改成 active,或者更新成项目里现在已经在用的会员状态字段。 +4. 如果项目里已经有订阅表、订单表、用户表,请优先沿用现有结构。 +5. 做完后告诉我你改了哪些文件。 +6. 顺便告诉我本地怎么测试这一步有没有真的生效。 +``` + +## 7. 让 AI 帮你快速接入的提示词 + +如果你用的是 Codex、Claude Code、Trae、Cursor 一类工具,可以直接把下面这个提示词贴给它,让它在你的项目里做支付接入。 + +```text +请你帮我把当前项目接上 Stripe 支付,我希望做一个最简单能跑起来的会员收费功能。 + +我的要求: +1. 我是零基础,请你先自己看项目,再决定代码应该改哪里。 +2. 不要让我自己判断目录结构、路由结构、数据库结构。 +3. 我只想先做最简单版本:月付和年付两个套餐。 +4. 用户点击购买后,能跳到 Stripe 付款页面。 +5. 付款成功后,我数据库里的会员状态能变成已开通。 +6. 不要一开始加太多复杂功能,比如优惠券、升级降级、复杂发票。 + +输出要求: +1. 先给我一个改动计划。 +2. 然后直接修改代码。 +3. 最后告诉我怎么一步一步本地测试。 +4. 如果有哪个步骤还需要我去 Stripe 后台操作,请直接把链接和要点告诉我。 +``` + +如果你希望 AI 更贴近你的项目,还可以在开头补上: + +- 你的前端框架 +- 你的后端目录结构 +- 你的数据库表名 +- 你现在的用户系统是 Supabase Auth 还是自建 Auth + +## 7.1 本地联调也尽量交给 AI + +如果你希望连本地联调都让 AI 帮你串起来,可以直接用下面这段: + +```text +请继续帮我把 Stripe 支付真正跑通,我想一步一步照着做,不想自己猜。 + +请参考官方文档: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +我的目标: +1. 告诉我先打开哪些 Stripe 页面。 +2. 告诉我如何拿到 STRIPE_WEBHOOK_SECRET。 +3. 告诉我如何使用 stripe login 和 stripe listen。 +4. 告诉我怎样验证 checkout.session.completed 已经成功打到本地 webhook。 +5. 如果当前项目需要先启动前端和后端,也请顺带告诉我具体命令。 +6. 不要只讲原理,请按实际操作步骤输出。 +7. 如果我某一步做错了,也请告诉我最常见的报错会长什么样。 +``` + +## 8. 最容易踩坑的 4 件事 + +1. **把 `success` 页面当成支付成功** + 真正决定状态的是 Webhook,不是前端跳转。 +2. **让前端传金额** + 这会带来严重的价格篡改风险。 +3. **Webhook 路由被 `express.json()` 提前处理** + Stripe 验签需要原始请求体。 +4. **没有做幂等处理** + Webhook 可能重试,如果你每次都重复加会员或积分,就会出事故。 + +## 9. 一句话选型建议 + +如果你现在只是想先把收费跑起来: + +| 你的主要用户 | 最先尝试的方案 | +| :--- | :--- | +| 海外 SaaS / 国际用户 | Stripe | +| 中国大陆用户 | 支付宝 / 微信支付 | +| 香港或跨境团队 | Stripe + 本地钱包 / FPS 聚合方案 | + +后面的具体区别,我统一放到附录。 + +::: info 最简单的选型思路 +不要一开始就想"我要把全球支付方式一次全接完"。 + +更实际的顺序通常是: +- 先按主要用户所在地区选一条主支付链路 +- 先把最小可行支付跑通 +- 再根据真实用户来源补第二、第三种支付方式 +::: + +## 10. 小结 + +到这里,你已经掌握了最基础但最重要的一条收费链路: + +1. 前端发起购买。 +2. 后端创建 Checkout Session。 +3. 用户在 Stripe 页面支付。 +4. Stripe 通过 Webhook 通知后端。 +5. 后端更新数据库。 +6. 前端刷新后显示新的会员或订单状态。 + +如果你只想快速把支付接进项目,前面的内容已经够用了。下面的附录你可以在真正遇到问题时再回来看。 + +--- + +# 附录 + +## 附录 A:Stripe 里最常见的几个对象 + +第一次看 Stripe 文档,最容易被这些对象名绕晕。你其实只需要先理解下面几个: + +| 对象 | 作用 | 你可以把它理解成什么 | +| :--- | :--- | :--- | +| `Product` | 描述卖的是什么 | 商品或会员套餐 | +| `Price` | 描述卖多少钱、周期怎么收费 | 月付、年付、买断 | +| `Checkout Session` | Stripe 托管的支付流程 | 付款页 | +| `Subscription` | 周期订阅关系 | 自动续费会员 | +| `Customer` | 付款用户 | Stripe 中的客户档案 | +| `Webhook` | 异步通知 | Stripe 告诉你"这笔款怎么样了" | + +## 附录 B:为什么 `success` 页面不等于支付成功 + +很多人以为"用户付完钱,跳到了 success 页面"就算支付成功了。这是最容易踩的坑。 + +### 先讲一个真实场景 + +假设你做了一个会员网站: +1. 用户点击"购买会员" +2. 跳转到 Stripe 付款页面 +3. 用户输入信用卡,点击付款 +4. 页面跳转到你的 `success.html` +5. 你在 success 页面写代码:"既然到了这页,就给用户开通会员" + +**问题在哪?** + +用户可能根本没付钱,或者付到一半关页面了,也能直接访问 `success.html`。 + +### 两条完全不同的路径 + +```mermaid +flowchart TB + pay["用户在 Stripe 完成支付"] + + subgraph unreliable["❌ 不可靠路径:只看 success 页面"] + success["浏览器跳到 success 页面"] + fake["前端代码认为已开通"] + risk["风险:关页 / 断网 / 伪造 URL / 根本没付钱"] + success --> fake --> risk + end + + subgraph reliable["✅ 可靠路径:以后端 Webhook 为准"] + event["Stripe 服务器发送 Webhook"] + verify["后端校验签名"] + active["数据库正式更新为已付费"] + event --> verify --> active + end + + pay --> success + pay --> event +``` + +**关键区别:** + +| | success 页面跳转 | Webhook 通知 | +| :--- | :--- | :--- | +| 谁发起的 | 用户的浏览器 | Stripe 的服务器 | +| 能伪造吗 | 能,直接访问 URL 就行 | 不能,有签名验证 | +| 一定代表付款成功吗 | 不一定 | 一定 | +| 你的系统怎么知道 | 前端代码猜的 | Stripe 正式通知的 | + +### 完整流程应该是怎样的 + +```mermaid +sequenceDiagram + autonumber + actor User as 用户 + participant Frontend as 你的网页 + participant Stripe as Stripe + participant Webhook as 你的后端接口 + participant DB as 数据库 + + User->>Stripe: 在 Stripe 页面完成付款 + Note over Stripe: 钱真的到了 Stripe 账户 + + Stripe-->>Frontend: 浏览器跳转到 success 页面 + Note over Frontend: ⚠️ 这步只是跳转
不代表系统已确认 + + Stripe->>Webhook: 发送 Webhook 通知
"checkout.session.completed" + Note over Webhook: ✅ 这才是正式通知 + + Webhook->>Webhook: 校验签名
(确保是 Stripe 发的,不是黑客) + + Webhook->>DB: 更新用户状态为"已付费" + DB-->>Webhook: 保存成功 + Webhook-->>Stripe: 返回 200 OK + + Frontend->>DB: 用户刷新页面,查询状态 + DB-->>Frontend: 返回"已付费" + Note over Frontend: 这时候才显示会员功能 +``` + +### 每个环节的卡点 + +**第 1 步:用户在 Stripe 付款** + +这是唯一确定"钱真的付了"的时刻: +- 用户输入信用卡信息,点击确认 +- 银行从用户卡里扣款 +- Stripe 确认收到这笔钱 + +**第 2 步:浏览器跳转到 success 页面(问题最大)** + +这一步完全不可靠,因为: +- 用户可以直接在浏览器输入 `yoursite.com/success`,根本没付钱也能访问 +- 用户付到一半关页面了,但之前复制了 success 链接,之后直接打开 +- 网络问题导致跳转失败,但钱已经扣了(用户付了钱却没看到成功页面) +- 用户点返回键,又付了一次钱,但两次都跳转到同一个 success 页面 + +**第 3 步:Stripe 发送 Webhook** + +这是 Stripe 主动通知你的服务器"这笔款到账了": +- 只有 Stripe 的服务器能发起这个请求 +- 请求里带有签名,你的后端可以验证是不是真的 Stripe 发的 +- 即使 success 页面没打开、用户断网了,Webhook 也会发送 + +**第 4 步:后端校验签名** + +为什么要校验?防止黑客伪造通知。 + +假设没有校验,黑客可以直接给你的服务器发一个假通知:"用户 A 付了 1000 元"。你的系统就会给黑客开通会员。 + +校验的过程: +- Stripe 用你们约定的密钥对通知内容生成签名 +- 你的后端用同样的密钥验证签名是否匹配 +- 匹配 = 100% 是 Stripe 发的,不匹配 = 直接拒绝 + +**第 5 步:更新数据库** + +只有校验通过后,才更新数据库: +- 把用户状态从"待付款"改成"已付费" +- 记录订单号、金额、付款时间 +- 开通对应的会员权限 + +**第 6 步:前端查询状态** + +success 页面不要自己判断"到了这页就是成功了"。正确的做法: +- 页面加载时,向后端发送请求:"这个用户付费了吗?" +- 后端查数据库,返回真实状态 +- 根据返回结果显示"开通成功"或"等待确认" + +### 一个常见的错误做法 + +```javascript +// 错误:在 success 页面直接开通 +// success.html +if (window.location.pathname === '/success') { + // 危险!任何人都能访问 /success + activateMembership(); +} +``` + +```javascript +// 正确:每次刷新都查后端 +// success.html +async function checkStatus() { + const response = await fetch('/api/user/status'); + const data = await response.json(); + + if (data.paymentStatus === 'paid') { + showMemberFeatures(); + } else { + showPendingMessage(); + } +} +``` + +### 总结一句话 + +**success 页面只是"浏览器跳转成功",Webhook 才是"Stripe 正式确认收款"。** + +你的系统必须以 Webhook 为准,不能相信前端的跳转。 + +## 附录 C:订阅系统最值得监听的事件 + +| 事件 | 含义 | 你通常要做什么 | +| :--- | :--- | :--- | +| `checkout.session.completed` | 首次开通成功 | 创建本地订阅记录 | +| `invoice.paid` | 自动续费成功 | 延长有效期 | +| `invoice.payment_failed` | 自动扣费失败 | 标记风险状态并提醒用户 | +| `customer.subscription.deleted` | 订阅取消 | 回收权限或标记到期后失效 | + +### 订阅状态图 + +```mermaid +stateDiagram-v2 + [*] --> NotStarted: 用户未购买 + NotStarted --> Active: checkout.session.completed + Active --> Active: invoice.paid + Active --> PastDue: invoice.payment_failed + PastDue --> Active: 用户补款成功 + Active --> Canceled: customer.subscription.deleted + PastDue --> Canceled: 到期未恢复 + Canceled --> [*] + + state "未开通" as NotStarted + state "会员有效" as Active + state "扣费失败 / 待恢复" as PastDue + state "已取消 / 到期回收" as Canceled +``` + +### 续费 / 失败 / 取消时序图 + +```mermaid +sequenceDiagram + autonumber + participant Stripe as Stripe + participant Webhook as 你的 Webhook 接口 + participant DB as 订阅表 / 订单表 + participant App as 你的应用 + actor User as 用户 + + rect rgb(235, 248, 255) + Stripe->>Webhook: invoice.paid + Webhook->>DB: 延长 current_period_end + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 继续保持会员有效 + end + + rect rgb(255, 247, 237) + Stripe->>Webhook: invoice.payment_failed + Webhook->>DB: 标记 past_due + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 提醒更新支付方式 + end + + rect rgb(254, 242, 242) + Stripe->>Webhook: customer.subscription.deleted + Webhook->>DB: 标记 canceled + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 停止高级权限 + end +``` + +## 附录 D:其他支付方案怎么选 + +### 1. 中国大陆 + +主要用户在大陆的话,首选还是 **[支付宝](https://open.alipay.com/)** 和 **[微信支付](https://pay.wechatpay.cn/)**。 + +**业务模式:** + +两者都是"支付网关"模式。你需要: +- 申请商户资质(营业执照、对公账户) +- 用户付的钱直接到你的商户账户 +- 你自己负责税务、退款、对账 + +**技术模式:** + +两者都是"后端下单 + 前端调起 + 后端通知"的模型,跟 Stripe 思路一样。 + +**支付宝接入流程:** +1. 在支付宝开放平台创建应用 +2. 配置公私钥和回调地址 +3. 后端调用统一下单接口,生成支付链接或二维码 +4. 用户扫码或跳转付款 +5. 支付宝异步通知你的后端,更新订单状态 + +**微信支付接入流程:** +- JSAPI 支付:适合公众号、小程序,用户在微信内直接付款 +- Native 支付:PC 端生成二维码,用户扫码付款 +- H5 支付:手机浏览器内拉起微信 App 付款 + +流程:后端下单 → 拿到 `prepay_id` 或 `code_url` → 前端调起支付 → 后端接收通知确认成功 + +**参考链接:** +- 支付宝开放平台:https://open.alipay.com/ +- 微信支付商户文档:https://pay.wechatpay.cn/doc/v3/merchant/ + +### 2. 香港 + +香港市场比较混合,常见组合: + +- 银行卡:Visa / Mastercard +- FPS(转数快):香港本地即时转账 +- AlipayHK / WeChat Pay HK:香港版支付宝和微信 + +**推荐组合:** +- 用 **[Stripe](https://stripe.com/hk)** 覆盖国际卡和订阅 +- 用 **[Airwallex](https://www.airwallex.com/)** 或 **[Adyen](https://www.adyen.com/)** 补本地钱包和 FPS + +### 3. 海外 / 国际 SaaS + +#### [Stripe](https://stripe.com/) + +**业务模式:** 支付网关 + +- 你需要自己申请商户资质(部分国家 Stripe 可以帮你搞定) +- 用户付的钱到你的 Stripe 账户,再结算到你的银行账户 +- 你自己负责税务申报 + +**技术模式:** + +- API 体验最好,文档清晰 +- 支持 Checkout(托管页面)、Elements(自定义表单)、Payment Links(无代码) +- Webhook 通知支付状态 +- 支持订阅、发票、多币种 + +**适合谁:** 海外 SaaS、独立开发者、需要灵活定制的团队 + +**参考链接:** https://docs.stripe.com/ + +#### [PayPal](https://www.paypal.com/) + +**业务模式:** 支付网关 + +- 用户付的钱到你的 PayPal 账户,再提现到银行 +- 你自己负责税务 + +**技术模式:** + +- 一次性支付:前端放按钮,后端创建/确认订单 +- 订阅制:先建 Product 和 Plan,再用 SDK 拉起 +- 同样需要后端和 Webhook,不要只看前端回调 + +**适合谁:** 需要补充渠道的海外业务,用户习惯用 PayPal 付款 + +**参考链接:** https://developer.paypal.com/docs/ + +#### [Paddle](https://www.paddle.com/) + +**业务模式:** Merchant of Record (MoR) + +- Paddle 是"记录商家",法律上由 Paddle 向用户收款 +- Paddle 帮你处理全球税务、VAT、退款、合规 +- 用户付的钱到 Paddle,Paddle 扣除税费和手续费后结算给你 +- 你不需要在每个国家注册公司或处理税务 + +**技术模式:** + +- Paddle.js:前端嵌入托管结账页 +- 后端 API:创建 transaction,交给 checkout 处理 +- Webhook 同步订阅状态 + +**适合谁:** 不想处理全球税务的 SaaS 团队,尤其是 B2B SaaS + +**参考链接:** https://developer.paddle.com/ + +#### [Lemon Squeezy](https://www.lemonsqueezy.com/) + +**业务模式:** Merchant of Record (MoR) + +- 和 Paddle 类似,Lemon Squeezy 是"记录商家" +- 帮你处理全球税务、VAT、合规 +- 2024 年被 Stripe 收购,但独立运营 + +**技术模式:** + +- Hosted Checkout:最简单,直接生成付款链接 +- Checkout Overlay:浮层嵌入你的页面 +- 后端 API:创建 checkout,灵活控制 + +**适合谁:** 独立开发者、数字产品、软件授权 + +**参考链接:** https://docs.lemonsqueezy.com/ + +### 4. 企业级方案 + +#### [Airwallex(空中云汇)](https://www.airwallex.com/) + +**业务模式:** 支付网关 + 全球账户 + +- 提供全球收款账户(类似虚拟银行账户) +- 支持多币种收款、换汇、付款 +- 你自己负责税务 + +**技术模式:** + +- Payment Links:几乎不用代码,生成付款链接 +- Hosted Payment Page:托管页面 +- Drop-in / Embedded / Native API:深度接入,自定义程度高 +- 支持 Alipay HK、FPS、WeChat Pay 等本地支付方式 + +**适合谁:** 香港团队、跨境业务、需要多币种账户的公司 + +**参考链接:** https://www.airwallex.com/docs/ + +#### [Adyen](https://www.adyen.com/) + +**业务模式:** 支付网关 + +- 企业级支付平台,年处理交易额万亿欧元 +- 支持线上、线下、移动端全渠道 +- 你自己负责税务 + +**技术模式:** + +- Pay by Link:最简单,生成付款链接 +- Drop-in / Components:标准线上接入 +- 后台可启用 Alipay、Alipay HK、PayMe 等本地支付方式 + +**适合谁:** 大型企业、需要全渠道支付的公司 + +**参考链接:** https://docs.adyen.com/ + +### 5. 方案对比 + +| 方案 | 业务模式 | 税务处理 | 适合谁 | +| :--- | :--- | :--- | :--- | +| Stripe | 支付网关 | 自己处理 | 海外 SaaS、开发者 | +| PayPal | 支付网关 | 自己处理 | 海外补充渠道 | +| Paddle | MoR | Paddle 代处理 | B2B SaaS、不想管税务 | +| Lemon Squeezy | MoR | LS 代处理 | 独立开发者、数字产品 | +| Adyen | 支付网关 | 自己处理 | 大型企业 | +| Airwallex | 支付网关 + 账户 | 自己处理 | 跨境业务、香港团队 | +| 支付宝/微信 | 支付网关 | 自己处理 | 大陆用户 | + +### 6. 按地区选方案 + +| 你的市场 | 推荐方案 | +| :--- | :--- | +| 中国大陆 | 支付宝 / 微信支付 | +| 香港 | Stripe + Airwallex / Adyen | +| 海外 SaaS | Stripe(自己管税务)或 Paddle(MoR 代管) | +| 海外数字产品 | Stripe / Lemon Squeezy / Paddle | +| 多地区企业级 | Adyen / Airwallex / Stripe 组合 | diff --git a/docs/ko-kr/stage-2/backend/zeabur-deployment/index.md b/docs/ko-kr/stage-2/backend/zeabur-deployment/index.md new file mode 100644 index 0000000..88de8ee --- /dev/null +++ b/docs/ko-kr/stage-2/backend/zeabur-deployment/index.md @@ -0,0 +1,490 @@ +# 如何部署 Web 应用 + +在本教程中,我们将介绍如何将你的 Web 应用部署到互联网上,让其他人可以访问。我们会介绍三个常用的部署平台:**腾讯云 CloudBase**、**Vercel** 和 **Zeabur**,帮助你快速完成从"写好代码"到"让别人可以在互联网上访问你的网站"的完整流程。 + +# 什么是"部署"? + +在开始之前,我们先弄清楚"部署(Deployment)"到底是什么意思。任何一个网站想要被外部用户访问,都必须有一个可以公开访问的网络地址(这个地址可以是 IP 地址,比如 123.45.67.89,也可以是域名,比如 [google.com](https://google.com/) 等)。但只有地址是不够的——你写好的网页代码(例如 HTML、CSS、JavaScript 文件,或者使用 React、Vue 等框架写的项目),以及相关的图片 / 视频资源,都必须"放"在一台 24 小时在线的服务器上,由它来响应网络请求,这样任何人的浏览器才能访问并下载这些资源。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image1.png) + +图片来源:https://www.hostinger.com/tutorials/what-is-cloud-hosting + +把资源上传、配置好环境并让服务"跑起来"的整个过程,就被称为 **部署(Deployment)**。 + +简单来说:你在自己电脑上写好的网页,只要在本机启动程序,就只能通过本地地址在自己的浏览器里访问,因为这些代码只存在于你的硬盘上。"部署"就是把你的代码和资源转移到一台连接着公网的专业服务器上,并做好配置,让这台服务器知道"别人访问时我要怎么响应"——比如:当有人在浏览器中输入你的域名时,服务器会立刻找到对应的网页文件,把内容传回给对方的设备,从而让用户看到你的页面。 + +如果手动部署,一个项目往往需要好几个步骤,每一步都可能踩坑。常见关键步骤包括: + +1. **服务器准备**:你需要先购买云服务器(比如阿里云、腾讯云、或 AWS EC2),选择服务器所在地区(如上海、新加坡)、配置(CPU、内存、磁盘大小等),还要学会如何远程连接服务器(例如通过 SSH 工具登录)。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image2.png) +2. **环境配置**:Web 应用需要在特定"环境"中才能运行——例如运行 Node.js 项目必须先安装 Node.js;运行 Python 项目必须安装 Python 以及对应的第三方库。如果环境版本不匹配,程序就可能报错、无法启动。 +3. **上传资源**:你需要把本地的代码和资源上传到服务器上,常用的方法包括 FTP 或 Git。如果项目体积比较大(比如包含视频文件),中途一旦断线,有时需要重新上传。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image3.png) + +4. **启动服务并测试**:上传完成后,你还需要在服务器上执行命令启动应用,并测试"分配的网络地址是否能访问"。如果访问不了,有可能是服务器防火墙没有放行对应端口(比如你的应用监听 3000 端口,但该端口被防火墙拦截),也可能是程序本身有 Bug,这时就需要查看服务器日志进行排查。 + > 💡 可以把端口理解为区分同一台设备上不同应用的"房间号",而 IP 则是这台设备的"门牌号"。IP 和端口合在一起(IP:port),就可以精确定位到某一个网络服务。 +5. **维护与更新**:后续每次你修改代码,都要重新上传并重启服务。如果服务器宕机(例如断电、网络故障),还需要手动重启应用,有时还要额外配置"进程守护工具",让程序在异常退出后自动拉起。 + +像 CloudBase、Vercel、Zeabur 这样的"低代码部署平台",就是为了解决上述复杂问题而诞生的。它们会帮你自动完成"买服务器、配环境、上传代码、启动服务、监控运行"等步骤。你只需要把自己的代码仓库(比如 GitHub 或 GitLab)连接到平台,或者直接上传代码,它就会自动拉取代码、识别应用类型、配置对应的运行时环境,最后给你一个可以被任何人访问的公网地址。它甚至可以一键绑定你自己的域名。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image4.png) + +接下来,我们会分别介绍这三个平台的特点和使用方法,帮助你选择最适合自己的部署方案。 + +--- + +# 部署平台对比 + +| 平台 | 特点 | 适用场景 | 免费额度 | +|------|------|----------|----------| +| **腾讯云 CloudBase** | 国内访问速度快,与微信生态深度整合 | 国内用户为主、需要微信小程序支持的项目 | 有免费额度 | +| **Vercel** | 前端框架支持好,与 GitHub 集成紧密 | React/Vue/Next.js 等现代前端项目 | 有免费额度 | +| **Netlify** | 功能全面,支持表单处理和身份验证,与 Git 集成好 | 需要表单处理、身份验证等高级功能的静态网站 | 有免费额度 | +| **Zeabur** | 支持多种语言和服务模板,配置灵活 | 需要部署多种服务(如 Dify、n8n)的复杂项目 | 每月约 5 美元免费额度 | + +--- + +# 1. 腾讯云 CloudBase + +腾讯云 CloudBase(云开发)是腾讯云提供的一站式后端云服务,特别适合国内开发者使用。它的优势在于: + +- **国内访问速度快**:服务器位于国内,访问延迟低 +- **微信生态整合**:可以方便地对接微信小程序、公众号 +- **一站式解决方案**:提供静态网站托管、云函数、数据库、存储等全套服务 +- **免费额度充足**:个人开发者有充足的免费资源额度 + +## 使用 CloudBase 部署 Web 应用 + +### 步骤 1:注册并登录 + +访问 [腾讯云 CloudBase 控制台](https://console.cloud.tencent.com/tcb),使用微信或 QQ 登录。 + +### 步骤 2:创建环境 + +点击"新建环境",选择一个环境名称(如 `my-web-app`)。 + +> ⚠️ **注意**:CloudBase 的免费体验版需要兑换码才能开通。你需要关注腾讯云 CloudBase 公众号,在公众号中输入"领取兑换码"获取免费体验版的兑换码,然后在创建环境时填写兑换码即可开通免费环境(免费试用期为 6 个月)。 + +### 步骤 3:开通静态网站托管 + +在环境管理页面,找到"静态网站托管"功能并开通。开通后你会获得一个默认的访问域名。 + +CloudBase 的静态网站托管提供多种部署方式,与 Zeabur 类似: + +- **本地项目上传**:直接从本地上传构建好的静态文件(HTML、CSS、JS 等) +- **模板部署**:使用预设模板快速创建项目,如 React Web 应用模板、Vue Web 应用模板 +- **Git 仓库部署**:支持从 GitHub 等代码仓库自动拉取代码并部署 + +### 步骤 4:部署代码 + +在静态网站托管页面,CloudBase 提供三种部署方式: + +**方式一:本地项目部署(本地项目上传)** +- 在控制台选择"本地项目部署" +- 直接上传构建好的静态文件(HTML、CSS、JS 等) +- 选择你本地构建好的项目文件夹(如 `dist` 或 `build` 目录) +- 等待上传完成即可访问 + +**方式二:模板部署** +- 使用预设模板快速创建项目 +- 支持 React Web 应用模板、Vue Web 应用模板等 +- 基于模板自动构建并部署 + +**方式三:Git 仓库部署** +- **Git 个人仓库部署**:绑定你的 GitHub 等个人代码仓库 +- **公开仓库部署**:支持从公开的 Git 仓库拉取代码 +- 配置自动构建命令(如 `npm run build`) +- 每次推送代码会自动重新部署 + +> 💡 **提示**:你也可以使用 CLI 工具进行部署: +> ```bash +> # 安装 CloudBase CLI +> npm install -g @cloudbase/cli +> # 登录 +> tcb login +> # 部署 +> tcb hosting deploy ./dist -e your-env-id +> ``` + +### 步骤 5:配置自定义域名(可选) + +在静态网站托管设置中,可以绑定你自己的域名,并申请免费的 HTTPS 证书。 + +--- + +# 2. Vercel + +Vercel 是全球最流行的前端部署平台之一,特别适合部署 React、Vue、Next.js 等现代前端框架项目。它的特点包括: + +- **与 GitHub 深度集成**:推送代码即自动部署 +- **自动预览**:每个 Pull Request 都会生成独立的预览链接 +- **全球 CDN**:网站自动分发到全球节点,访问速度快 +- **Serverless 函数**:支持在项目中编写后端 API + +> ⚠️ **注意**:Vercel 在部分网络环境下访问可能不太稳定,国内用户建议优先考虑 CloudBase。 + +## 使用 Vercel 部署 Web 应用 + +### 步骤 1:注册账号 + +访问 [Vercel 官网](https://vercel.com),使用 GitHub 账号登录。 + +### 步骤 2:导入项目 + +1. 点击 "Add New Project" +2. 选择你要部署的 GitHub 仓库 +3. 如果没有看到想要的仓库,点击 "Adjust GitHub App Permissions" 授权访问 + +### 步骤 3:配置构建设置 + +Vercel 会自动识别项目类型并配置构建命令: + +| 框架 | 构建命令 | 输出目录 | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Next.js | `next build` | - | +| 纯 HTML | - | 项目根目录 | + +如果自动识别不正确,可以手动修改: +- **Build Command**: 构建命令,如 `npm run build` +- **Output Directory**: 构建输出目录,如 `dist` 或 `build` +- **Install Command**: 依赖安装命令,通常是 `npm install` + +### 步骤 4:部署 + +点击 "Deploy" 按钮,等待构建完成。构建成功后,你会获得一个 `xxx.vercel.app` 的域名。 + +### 步骤 5:自定义域名(可选) + +在项目设置中的 "Domains" 页面,可以添加你自己的域名。Vercel 会自动配置 HTTPS。 + +--- + +# 3. Netlify + +Netlify 是另一个非常流行的前端部署平台,与 Vercel 类似,特别适合部署静态网站和单页应用(SPA)。它的特点包括: + +- **功能全面**:除了静态网站托管,还支持表单处理、身份验证、边缘函数等高级功能 +- **与 Git 深度集成**:支持 GitHub、GitLab、Bitbucket,推送代码自动部署 +- **分支预览**:每个分支都会自动生成独立的预览链接 +- **全球 CDN**:网站自动分发到全球节点,访问速度快 +- **表单处理**:无需后端代码即可处理网站表单提交 +- **身份验证**:内置用户身份验证功能,可快速实现登录/注册 + +> ⚠️ **注意**:Netlify 的国内访问速度可能不如 CloudBase,建议主要面向海外用户的项目使用。 + +## 使用 Netlify 部署 Web 应用 + +### 步骤 1:注册账号 + +访问 [Netlify 官网](https://www.netlify.com),点击 "Sign up" 注册。你可以使用 GitHub、GitLab、Bitbucket 或邮箱注册。 + +### 步骤 2:导入项目 + +1. 登录后点击 "Add new site" → "Import an existing project" +2. 选择你的代码托管平台(如 GitHub) +3. 授权 Netlify 访问你的仓库 +4. 从列表中选择你要部署的仓库 + +### 步骤 3:配置构建设置 + +Netlify 会自动识别常见的前端框架并配置构建设置: + +| 框架 | 构建命令 | 发布目录 | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Angular | `ng build` | `dist/` | +| Next.js | `next build` | `out` | +| 纯 HTML | - | `.`(项目根目录) | + +如果自动识别不正确,可以手动配置: +- **Build command**: 构建命令,如 `npm run build` +- **Publish directory**: 构建输出目录,如 `dist` 或 `build` + +### 步骤 4:部署 + +点击 "Deploy site" 按钮,等待构建完成。构建成功后,你会获得一个 `xxx.netlify.app` 的域名,任何人都可以通过这个地址访问你的网站。 + +### 步骤 5:配置自定义域名(可选) + +1. 进入站点设置,点击 "Domain management" +2. 点击 "Add custom domain" +3. 输入你的域名并按照提示配置 DNS 记录 +4. Netlify 会自动申请并配置 HTTPS 证书 + +### 特色功能 + +#### 1. 表单处理 + +Netlify 提供了一个非常方便的功能:无需后端代码即可处理表单提交。 + +只需在 HTML 表单中添加 `netlify` 属性: + +```html +
+

+ +

+

+ +

+

+ +

+

+ +

+
+``` + +部署后,表单提交的数据会自动发送到 Netlify 后台,你可以在 "Forms" 页面查看所有提交记录,也可以设置邮件通知或将数据转发到其他服务。 + +#### 2. Netlify Functions(边缘函数) + +Netlify 支持部署无服务器函数(Serverless Functions),让你可以在不搭建完整后端服务器的情况下,实现简单的 API 接口。你可以使用 JavaScript 或 TypeScript 编写函数,部署后会自动获得一个可访问的 URL。 + +例如,创建一个 `hello.js` 文件: + +```javascript +exports.handler = async (event, context) => { + return { + statusCode: 200, + body: JSON.stringify({ message: "Hello from Netlify!" }) + }; +}; +``` + +部署后,你可以通过 `https://你的域名/.netlify/functions/hello` 访问这个函数。 + +#### 3. 本地开发支持 + +Netlify 提供了 CLI 工具,方便你在本地开发和测试: + +```bash +# 安装 Netlify CLI +npm install -g netlify-cli + +# 登录账号 +netlify login + +# 本地启动开发服务器 +netlify dev + +# 本地测试函数 +netlify functions:serve +``` + +使用 CLI 工具可以在本地模拟 Netlify 环境,包括表单提交、函数调用等功能,方便在部署前进行测试。 + +--- + +# 4. Zeabur + +Zeabur 是一个新兴的部署平台,特别适合需要部署多种服务的复杂项目。它的优势在于: + +- **服务模板丰富**:内置 Dify、n8n、数据库等多种服务模板 +- **支持多种部署方式**:GitHub、模板、Docker 镜像、本地项目等 +- **灵活的服务组合**:可以在一个项目中部署多个相互关联的服务 +- **按量计费**:用多少付多少,适合实验性项目 + +## 使用 Zeabur 部署 Dify + +在之前的课程中,我们已经简单接触过 Dify。现在,我们可以通过 [Zeabur](https://zeabur.com/projects) 非常轻松地启动自己的 Dify 服务。首先打开 [控制台页面](https://zeabur.com/projects),我们先看一下上面的各个区域。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image5.png) + +在这个页面上,你首先能看到许多方块,这些就是已经启动的服务。在顶部菜单中,你会看到 Agent、Servers、Docs、Templates 等几个选项,它们分别代表: + +1. **Agent**:可以打开 Zeabur 内置的智能助手(Agent),向它提问如何操作,或者查询当前服务器的状态。 +2. **Servers**:在这里可以添加你自己购买的云服务器,或者直接通过 Zeabur 购买服务器。 +3. **Docs**:查看 Zeabur 的完整文档说明。 +4. **Templates**:这里列出了所有内置的模板镜像。 + +> 这里提到的"镜像(Image)",可以理解为"包含代码和运行环境的压缩包"。当某个服务在一台服务器上成功跑起来之后,我们可以选择把"这套运行环境 + 代码"打包成镜像。之后,在任何新服务器上,只要把这个压缩包解压并运行,就不需要重新配置环境和代码,服务就能直接跑起来。 + +在页面右上角,你还能看到自己的余额。默认情况下,每个月会有 5 美元左右的免费额度。关于细节计费规则暂时可以不用太在意,只需要知道:只要服务器在运行,就会消耗额度。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image6.png) + +点击余额可以查看每日的消耗明细。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image7.png) + +现在我们来创建自己的 Dify 服务。首先,在 [控制台首页](https://zeabur.com/projects) 点击 "New Project"。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image8.png) + +接下来是各个创建方式的解释: + +1. **GitHub** + 可以连接到你的 GitHub 账号。绑定之后,就可以直接从 GitHub 仓库里选择项目部署(GitHub 是目前全球最大的代码托管平台)。 +2. **Template(模板)** + 可以基于模板来部署服务。Zeabur 内置了很多预设项目模板(例如 Dify、n8n 等),你可以基于这些模板快速创建并部署应用。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image9.png) +3. **Databases(数据库)** + 用于部署数据库服务,比如 MySQL、MongoDB 等常见数据库。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image10.png) +4. **Functions(函数)** + 可以部署函数服务,你可以编写 JavaScript 或 Python 代码,让它们以函数的形式被调用。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image11.png) + + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image12.png) + +5. **Local Project(本地项目)** + 上传一个本地文件夹,Zeabur 会自动识别其中的启动脚本。这适合将你已经在本地开发好的项目快速部署到 Zeabur 上。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image13.png) +6. **Docker Image** + 部署已经打包好的 Docker 镜像。如果你的项目已经被打成了 Docker 镜像(例如存放在 Docker Hub 或其他镜像仓库中),可以在这里直接部署。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image14.png) +7. **Cursor** + 如果你安装了 Cursor(例如 Cursor IDE),可以通过这个入口将 Cursor 中的项目直接部署到 Zeabur。 + +如果你想部署自己的 Dify 服务,推荐选择 **Template** 方式,然后在搜索框中输入 "dify"。可以看到很多由不同作者维护的版本,你可以任选其一(比如 v1.6.0 版本)。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image15.png) + +接着,输入任意一个名称,Zeabur 会基于这个名称生成一个临时的自定义域名。之后所有人都可以通过这个网址访问你的服务。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image16.png) + +创建完成后,你会看到多个程序(服务)依次启动。需要耐心等待所有服务都进入"已启动"状态。(Dify 服务是由多个程序组成的,每个程序负责不同的功能,它们之间会相互协作。) + +一般来说,你只需要点击左侧的 Dify 应用,就可以看到默认的访问入口地址。但在本例中,由于前面还套了一层 nginx,你需要点击 nginx 服务来获取最终访问地址。可以理解为:nginx 就是负责对外统一"收发请求"的主程序,它会把外部访问的地址分发给内部各个服务。点击左侧的 Nginx,在详情页中可以看到当前的服务地址,然后在浏览器里打开这个地址,等待服务完全启动。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image17.png) + +稍等片刻后,你就能看到 Dify 的登录界面了。输入邮箱地址和注册密码,就可以开始使用你自己的 Dify 服务了。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image18.png) + +如果你有兴趣,还可以顺便启动一个 n8n 服务。n8n 也是海外非常流行的一款 AI 工作流平台。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image19.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image20.png) + +## 使用 Zeabur 与 Trae 部署贪吃蛇游戏 + +在本教程的下一个部分,我们会体验 Zeabur 的一些进阶用法。我们先用 Trae 生成一个贪吃蛇小游戏,再把它部署到 Zeabur 的服务器上,并配置一个可公开访问的链接,让任何人都可以打开你的游戏。 + +第一步,是在本地使用 Trae 创建一个贪吃蛇项目。 + +### 使用 HTML 框架实现 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image23.png) + +对于 Trae 来说,生成一个基于 HTML 的贪吃蛇网页游戏非常简单。游戏生成完成后,你只需要按照前面介绍的 Zeabur 本地部署方式,把包含所有文件的文件夹上传上去即可。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image24.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image25.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image26.png) + +完成后,你就会进入该服务的详情界面: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image27.png) + +点击左侧的 "Network" 选项,在页面中找到 "Public Address" 区域。点击 "Generate Domain",即可生成一个对外访问地址,你可以输入任意喜欢的名称。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image28.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image29.png) + +生成完成后,只要在浏览器中打开这个地址,就可以运行你自己的贪吃蛇游戏了。其它 HTML 类型的 Web 应用也可以用完全相同的方式来部署。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image30.png) + +### 使用 React 框架实现 + +前面我们学习了如何部署基于 HTML 的 Web 应用。接下来,我们再尝试部署一个目前更常用的前端框架:React 应用。相比纯 HTML,React 被认为是一种更加成熟、现代的前端开发框架。它通过组件化的方式组织页面结构,能够显著加快复杂页面的开发,是企业级项目中非常主流的选择。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image31.png) + +#### 重构为 React 架构 + +在 Trae 中,你只需要向 Agent 说明:"帮我把这份代码重构成 React 架构",就可以比较轻松地把原本基于 HTML 的结构重构成 React 项目。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image32.png) + +不过,相比简单的 HTML 文件,React 应用依赖更复杂的构建工具和项目结构,因此部署过程也会稍微麻烦一些。一个典型的问题体现在端口设置上:默认情况下,React 应用一般会监听 3000 端口(你也可以在配置文件或启动日志中看到这一点)。 + +然而,在 Zeabur 上这样部署会失败——因为 Zeabur 只支持监听 8080 端口的应用。也就是说,如果想让 React 应用在 Zeabur 上正常运行,我们必须先把默认监听端口从 3000 改成 8080。 + +要正确进行这一步配置,我们需要先弄清楚两个概念:什么是"端口(Port)",以及"监听端口(Listening Port)"是什么意思。 + +#### 什么是端口? + +> 在计算机网络中,端口可以理解为一个"逻辑通信端点",用来区分同一台设备上运行的不同网络服务。简单类比的话,如果 IP 地址好比一个"门牌号"(例如 162.128.1.1),那端口号就像这栋楼里不同房间的"房间号"——每个房间对应一个服务(例如 Web 服务器、邮箱服务,或者你的 React 应用)。 +> +> 端口号用 16 位整型表示,取值范围是 0 到 65535。 + +如果不想记这些细节,可以简单理解:端口是构成"网络访问地址"的一个必要部分。 + +我们平时访问网站或 IP 地址时,通常不会手动加端口号,是因为 Web 的默认端口是 80 或 443(HTTPS)。大多数浏览器会自动使用这些标准端口。而对于一些特殊端口,比如 React 默认的 3000、Zeabur 要求的 8080,我们就必须在地址后面加上 `:3000` 或 `:8080` 才能访问到对应的内容。 + +#### 什么是"监听端口号"? + +> "监听端口号"指的是某个程序在一台设备上主动"打开并监控"的端口。当一个应用设置了监听端口时,其实就是在告诉操作系统:"我会一直在这个端口上等待网络请求——只要有请求进来,就请转发给我。" + +再形象一点地理解:假设你的电脑是一栋写字楼,IP 地址是这栋楼的地址。楼里开了很多公司或部门,它们分别占用不同的房间,房间号就是端口号。 + +当默认的 React 开发服务器启动时,它会"打开"某个房间的门,并安排"前台"在门口值班,这个房间号就是它的监听端口——3000。 + +同时,React 程序还会告诉这栋楼的"物业管理"(操作系统):"我在 3000 号房间,请把所有寄给 3000 的信件(网络请求)都转给我。" + +这样,当你访问 React 网站时,请求首先会到达这栋楼;物业看到请求要送到 3000 号房间,就会立刻把请求交给 React 的"前台",由它来处理并返回结果——这就是访问 React 应用的过程。 + +当你在本地执行 `npm start`(本地启动 React 开发服务器的默认命令,也可以在 Vibe Coding 的 Agent 侧边栏中执行)时,React 开发服务器就会自动把监听端口设置为 3000。 +而 Zeabur 的平台设计决定了它只会"识别"监听 8080 端口的应用。如果你的 React 应用仍然使用默认的 3000 端口,Zeabur 就无法将请求正确转发给你的应用,最终导致部署失败。 + +#### 修改默认监听端口 + +要把 React 默认监听端口(3000)改成 Zeabur 所要求的 8080,有很多做法。最简单的方式,就是直接在 Trae 里对 Agent 下指令:"请帮我把这个 React 项目的默认端口改为 8080。"Trae 就会帮你修改项目中对应的配置文件。修改完成后,你只需重新打包并按前面的方式上传到 Zeabur 即可。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image33.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image34.png) + +在网络设置中指定一个访问 URL,方式和部署 HTML 项目时基本相同,就可以启动 React 版本的服务。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image35.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image36.png) + +对于其它需要修改端口号的程序,你也可以采用同样的思路:先改默认端口,再上传到 Zeabur 部署。至此,你已经掌握了将常见 Web 应用部署到服务器的基础技能。 + +你可以尝试让 Trae 帮你构建不同类型的应用,并把它们部署到 Zeabur 的默认服务器上。在后续课程中,我们还会学习如何把应用部署到你自己购买的云服务器上。 + +--- + +# ⚠️ 如何停止和删除项目(Zeabur) + +由于启用服务器相关资源都会产生费用,我们在使用时一定要养成"及时关闭不用服务"的习惯,避免把每个月的免费额度消耗完。 + +如果要找到项目的管理入口,首先点击项目中的 "Settings" 选项。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image21.png) + +进入设置页面后,将页面拉到最下方,你会看到类似下面的界面: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image22.png) + +你可以点击 "Suspend All Services" 来暂停所有服务以降低费用;如果服务出现问题,可以点击 "Restart All Services" 对全部服务进行重启。如果你确定不再需要这个项目,可以点击 "Delete Project" 将整个项目彻底删除。 + +--- + +# 总结 + +在本教程中,我们介绍了四个常用的 Web 应用部署平台: + +1. **腾讯云 CloudBase**:适合国内用户,访问速度快,与微信生态整合好 +2. **Vercel**:适合现代前端框架项目,与 GitHub 集成紧密,全球 CDN 加速 +3. **Netlify**:功能全面,支持表单处理和身份验证,适合需要高级功能的静态网站 +4. **Zeabur**:适合复杂项目,服务模板丰富,支持多种部署方式 + +选择哪个平台取决于你的具体需求: +- 如果主要面向国内用户,推荐 **CloudBase** +- 如果使用 React/Next.js 等框架,推荐 **Vercel** 或 **Netlify** +- 如果需要表单处理、身份验证等高级功能,推荐 **Netlify** +- 如果需要部署 Dify、n8n 等服务,推荐 **Zeabur** + +无论选择哪个平台,部署的核心流程都是相似的:准备代码 → 选择平台 → 配置构建设置 → 部署上线。掌握这些技能后,你就可以将自己开发的应用分享给全世界了! diff --git a/docs/ko-kr/stage-2/frontend/design-to-code/index.md b/docs/ko-kr/stage-2/frontend/design-to-code/index.md new file mode 100644 index 0000000..ed538b0 --- /dev/null +++ b/docs/ko-kr/stage-2/frontend/design-to-code/index.md @@ -0,0 +1,361 @@ +# 从设计原型到项目代码 + +::: tip 🎯 核心问题 +**如何将设计工具中的原型转化为真正能在浏览器里运行的前端代码?** +::: + +--- + +## 1. 从原型到代码的三种路径 + +在使用 Figma、MasterGo 等现代前端设计工具完成界面设计后,一个很实际的问题自然会浮现:这些看起来结构完整的设计稿,要怎么转化成真正能在浏览器里运行的前端代码? + +一般而言,从原型到代码的落地,本质上有三种典型路径: + +| 路径 | 方法 | 特点 | 适用场景 | +|------|------|------|----------| +| **路径一** | 根据图片,使用多模态大模型直接还原出代码 | 灵活、无需特定工具 | 快速原型验证、简单页面 | +| **路径二** | 通过平台自身能力或插件导出可用代码 | 还原度高、可编辑性强 | Figma/MasterGo 用户 | +| **路径三** | 平台结合 MCP 能力导出可用代码 | 自动化程度高、可定制 | 需要深度集成的工作流 | + +本文将详细介绍这三种路径的具体实现方法,帮助你根据项目需求选择最合适的工作流。 + +::: tip 📚 前置知识 +在开始本节之前,建议你先学习 [Figma 与 MasterGo 入门](../figma-mastergo/) 教程,掌握前端设计工具的基础操作。 +::: + +--- + +## 2. 路径一:多模态 AI 直接还原代码 + +拥有视觉能力的大模型天生具备将图片转为代码的能力。我们只需要将设计稿截图直接导入对话框,随后让大模型生成完整的结果代码。 + +### 2.1 操作流程 + +1. **截取设计稿图片** + - 在 Figma 或 MasterGo 中,将设计好的页面导出为 PNG 或 JPG + - 确保截图包含完整的页面布局 + +2. **选择多模态 AI 模型** + - 可以使用 Gemini、Qwen、Claude 等支持图像输入的模型 + - 这里以 Gemini 为例进行演示 + +3. **编写提示词** + ``` + 请根据这张设计图生成对应的 HTML/CSS 代码。 + 要求: + - 使用现代 CSS 布局(Flexbox/Grid) + - 响应式设计,适配不同屏幕尺寸 + - 包含所有可见的 UI 元素 + - 颜色、字体大小尽量还原设计稿 + ``` + +![](/zh-cn/stage-2/frontend/design-to-code/images/image42.png) + +4. **获取并保存代码** + - 要求模型返回完整的 HTML 代码 + - 保存为单个 `.html` 文件,方便本地测试 + - 后续可以在本地 IDE 中将其转换为 React 等框架 + +### 2.2 常见问题与解决方案 + +生成页面并非简单的任务,在具体过程中你可能会遇到很多问题: + +| 问题 | 解决方案 | +|------|----------| +| 界面排布不均 | 向 AI 描述具体的布局问题,要求调整 CSS 的 margin/padding | +| 界面显示不全 | 检查是否设置了正确的 viewport,要求添加响应式断点 | +| 颜色还原不准 | 使用取色工具获取设计稿的精确色值,提供给 AI | +| 字体不匹配 | 指定具体的字体名称或要求使用 Google Fonts 替代 | + +::: tip 💡 小技巧 +推荐先生成 HTML 代码,获取后再使用本地 IDE 将其转换为 React 框架。这样可以获得多个独立的 HTML 文件,统一进行框架转换。 +::: + +### 2.3 MasterGo AI 生成页面 + +MasterGo 同样提供了强大的 AI 页面生成功能,可以根据参考图直接生成可用的网页代码。 + +#### 找到 AI 功能入口 + +在 MasterGo 编辑界面的上方工具栏中,可以找到 AI 工具按钮: + +![](/zh-cn/stage-2/frontend/design-to-code/images/image47.png) + +#### 生成流程 + +1. **上传参考图** + - 使用与多模态 AI 相同的方式上传设计参考图 + - 添加文字描述需求 + +2. **查看生成结果** + +![](/zh-cn/stage-2/frontend/design-to-code/images/image48.png) + +![](/zh-cn/stage-2/frontend/design-to-code/images/image49.png) + +3. **获取代码** + - 点击蓝色按钮"插入到画布",可直接编辑生成后的网页 + - 或点击右侧的"代码"按钮,复制代码内容到本地 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image50.png) + +--- + +## 3. 路径二:平台自身能力或插件导出代码 + +### 3.1 Figma Make 生成代码 + +Figma Make 是 Figma 官方推出的 AI 设计工具,能够根据用户输入的提示词或者参考图,高精度地还原网页原型 UI 界面。 + +#### 功能特点 + +- **高精度还原**:相比原生 AI 生成代码,效果更佳 +- **可编辑性**:生成结果可以转换为可编辑的 Figma Design 文件 +- **GitHub 集成**:支持直接将代码同步到 GitHub + +::: tip 🔑 权限说明 +使用 Figma Make 的完整功能需要 Pro 用户权限,学生可以通过教育认证免费获得 Pro 权限。 +::: + +#### 操作步骤 + +1. **进入 Figma Make** + - 在 Figma 首页点击 Make 按钮 + - 或者访问 [Figma Make](https://www.figma.com/make) + +2. **上传参考图** + - 将你想要还原的设计图上传到对话框 + - 添加描述需求的提示词 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image43.png) + +3. **查看生成结果** + - 稍等片刻后即可看到渲染结果 + - 点击右上角的播放按钮可进行全屏预览 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image44.png) + +4. **细节调整** + - 点击右上角的编辑器图标(鼠标和尺子图标) + - 回到熟悉的 Figma Editor 界面进行详细调整 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image45.png) + +5. **导出代码** + - 调整满意后,选择导出代码 + - 可以直接连接到 GitHub 保存代码 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image46.png) + +### 3.2 插件导出代码 + +除了平台原生的 AI 功能,Figma 和 MasterGo 都支持通过插件导出代码: + +**常用 Figma 插件:** +- **Figma to Code**:将设计稿转换为 React、Vue、HTML 等代码 +- **Anima**:高保真代码生成,支持交互效果 +- **Locofy**:AI 驱动的设计转代码工具 + +**使用步骤:** +1. 在 Figma 中打开插件面板(Plugins) +2. 搜索并安装需要的代码导出插件 +3. 选中要导出的设计元素 +4. 运行插件,选择目标框架和代码格式 +5. 复制或下载生成的代码 + +--- + +## 4. 路径三:平台结合 MCP 能力导出代码 + +### 4.1 什么是 MCP? + +MCP(Model Context Protocol,模型上下文协议)是一套开放标准协议,它允许 AI 模型安全、可控地访问外部工具和数据源。在前端设计工具的场景中,MCP 让大模型能够直接读取设计文件的结构、样式和组件信息,从而更精准地生成代码。 + +### 4.2 MCP 的工作原理 + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ AI 模型 │ ←→ │ MCP 服务器 │ ←→ │ 设计工具 │ +│ (Claude等) │ │ (协议适配) │ │(Figma/MasterGo)│ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +**工作流程:** +1. AI 模型通过 MCP 协议向设计工具发送请求 +2. 设计工具返回结构化的设计数据(图层、样式、组件等) +3. AI 模型理解设计结构并生成对应代码 +4. 代码可以直接导出或同步到开发环境 + +### 4.3 Figma + MCP 实战 + +#### 环境准备 + +1. **安装 MCP 服务器** + ```bash + # 使用 npx 安装 Figma MCP 服务器 + npx figma-mcp-server + ``` + +2. **配置 Claude Desktop 或其他支持 MCP 的 AI 工具** + ```json + { + "mcpServers": { + "figma": { + "command": "npx", + "args": ["figma-mcp-server"], + "env": { + "FIGMA_ACCESS_TOKEN": "your-figma-token" + } + } + } + } + ``` + +3. **获取 Figma Access Token** + - 登录 Figma → Settings → Personal Access Tokens + - 生成新的 Token 并保存 + +#### 使用流程 + +1. **在 AI 工具中启用 MCP 连接** + - 打开 Claude Code 或其他支持 MCP 的 IDE + - 确认 MCP 服务器已连接 + +2. **提供设计文件链接** + ``` + 用户:请帮我将这个 Figma 设计转换为 React 代码 + 链接:https://www.figma.com/file/xxxxx + + AI:我已通过 MCP 连接到 Figma,正在读取设计文件结构... + ``` + +3. **AI 自动分析并生成代码** + - MCP 服务器获取设计文件的图层树 + - AI 理解组件结构和样式属性 + - 生成带有正确命名和结构的 React/Vue 组件 + +4. **迭代优化** + ``` + 用户:请将按钮组件提取为独立的可复用组件 + + AI:好的,我已通过 MCP 识别到设计系统中的 Button 组件, + 正在生成带有 props 接口的 React 组件... + ``` + +### 4.4 MCP 的优势 + +| 特性 | 传统方式 | MCP 方式 | +|------|----------|----------| +| **数据精度** | 依赖截图,可能丢失细节 | 直接读取原始设计数据 | +| **组件识别** | AI 需要猜测组件边界 | 精确获取组件定义 | +| **样式还原** | 基于像素估算 | 获取精确的设计 token | +| **迭代效率** | 每次修改需重新截图 | 实时同步设计变更 | +| **自动化程度** | 手动复制粘贴 | 可直接写入项目文件 | + +### 4.5 当前可用的 MCP 工具 + +**设计工具 MCP:** +- **Figma MCP Server**:官方支持的 MCP 实现 +- **MasterGo MCP**:社区开发的 MasterGo 适配器 + +**开发环境 MCP:** +- **Claude Code**:原生支持 MCP 协议 +- **Cline**:VS Code 插件,支持 MCP 连接 +- **Trae**:可通过配置启用 MCP 功能 + +::: tip 🔮 未来展望 +MCP 协议正在快速发展,未来设计工具与开发环境的集成将更加紧密。预计会出现更多一键同步设计到代码的解决方案,进一步缩短设计与开发之间的距离。 +::: + +--- + +## 5. 代码导出后的工作 + +### 5.1 本地测试 + +获取代码后,在本地 IDE 中打开并进行测试: + +1. **创建新项目** + ```bash + # 如果是 HTML 文件,直接用浏览器打开 + open index.html + + # 如果是 React/Vue 项目 + npm install + npm run dev + ``` + +2. **与 AI IDE 协作** + - 将生成的代码导入 Trae 或其他 AI IDE + - 让 AI 帮助修复布局问题、添加交互功能 + +### 5.2 常见问题处理 + +| 阶段 | 问题 | 解决方案 | +|------|------|----------| +| 布局 | 元素错位 | 检查 CSS 的 display 和 position 属性 | +| 样式 | 颜色不一致 | 使用浏览器开发者工具检查实际应用的色值 | +| 响应式 | 移动端显示异常 | 添加 media query 断点 | +| 交互 | 按钮无响应 | 检查 JavaScript 事件绑定 | + +--- + +## 6. 三种路径对比与选择建议 + +### 6.1 路径对比 + +| 维度 | 路径一:多模态 AI | 路径二:平台能力 | 路径三:MCP | +|------|------------------|------------------|-------------| +| **上手难度** | ⭐ 简单 | ⭐⭐ 中等 | ⭐⭐⭐ 较复杂 | +| **还原精度** | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐ 高 | ⭐⭐⭐⭐⭐ 最高 | +| **灵活性** | ⭐⭐⭐⭐⭐ 高 | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐ 较高 | +| **自动化程度** | ⭐⭐ 低 | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐⭐ 高 | +| **成本** | 低(按 API 调用) | 中(可能需要 Pro) | 低(开源工具) | + +### 6.2 选择建议 + +**选择路径一(多模态 AI)如果:** +- 需要快速验证想法 +- 设计工具不固定,经常切换 +- 对还原精度要求不高 +- 预算有限 + +**选择路径二(平台能力)如果:** +- 团队主要使用 Figma 或 MasterGo +- 需要高精度的代码还原 +- 设计师和开发者需要频繁协作 +- 愿意投资 Pro 版本 + +**选择路径三(MCP)如果:** +- 追求最高程度的自动化 +- 有技术能力配置 MCP 环境 +- 项目需要频繁迭代设计到代码 +- 希望建立标准化的设计开发工作流 + +--- + +## 7. 总结 + +通过本章节的学习,你已经掌握了从设计原型到代码的三种核心路径: + +1. **多模态 AI 直接转换**:灵活快速,适合原型验证 +2. **平台原生能力**:还原度高,适合专业设计工作流 +3. **MCP 协议集成**:自动化程度最高,代表未来趋势 + +::: tip 💡 最佳实践 +- **新手推荐**:从路径一(多模态 AI)开始,快速上手 +- **团队协作**:使用路径二(平台能力),保证设计一致性 +- **效率优先**:尝试路径三(MCP),建立自动化工作流 +- **混合使用**:根据项目阶段灵活切换不同路径 +::: + +--- + +## 参考资源 + +- [Figma 与 MasterGo 入门](../figma-mastergo/) - 学习设计工具基础 +- [一起做霍格沃茨画像](../hogwarts-portraits/) - 完整项目实战 +- [MCP 官方文档](https://modelcontextprotocol.io/) - 了解协议详情 +- [Figma Make 官方文档](https://help.figma.com/hc/en-us/sections/360007453634-Figma-Make) +- [MasterGo AI 教程](https://mastergo.com/tutorials) diff --git a/docs/ko-kr/stage-2/frontend/figma-mastergo/index.md b/docs/ko-kr/stage-2/frontend/figma-mastergo/index.md new file mode 100644 index 0000000..e3b2800 --- /dev/null +++ b/docs/ko-kr/stage-2/frontend/figma-mastergo/index.md @@ -0,0 +1,303 @@ +# Figma 与 MasterGo 入门 + + + +::: tip 🎯 核心问题 +**如何从零开始使用现代设计工具创建网页原型?** +::: + +--- + +## 1. 为什么要学前端设计工具? + +在开始之前,我们需要理解一个问题:为什么需要学"前端设计工具"?反正直接写 HTML / CSS 代码也能把页面搭出来,多学一个软件和技术,真的有必要吗? + +实际上,把页面运行起来,和把产品设计好根本是两个概念。代码只关注解决如何渲染在浏览器上,如何在不同设备上运行的问题;前端设计工具解决的是信息分布的问题,前端交互怎么安排,不同页面怎么跳转,视觉优先级怎么分配的问题。只需要在设计工具里搭一块画布,就能把版式、信息层级、交互方式在一块屏幕上对比确定,选择最适当的呈现效果。 + +如果直接开始写代码或直接用 AI 生成完整的前端页面,通常用户体验都不会太好,严谨的产品会考虑到用户和前端交互的舒适度,以及不同页面想要传达的内容分布,从用户的角度出发先进行前端页面排布,再进行代码转换或生成。 + +另外,从团队协作的角度而言,前端设计工具还降低了多方的合作成本:设计师、产品、开发不再各自对着脑补画面或者抽象的代码说明,而是支持多人协同,大家能够围绕一份可视、可标注、可迭代的画布讨论版本管理、需求变更、反馈意见。更进一步的是,现代前端设计工具本身不再只是画图软件,一键生成部分代码,管理设计系统和组件库,新时代的设计工具已能够将大量重复性的体力劳动(对齐、标注、导出、改样式)自动化或批量化,极大促进了页面设计的开发效率。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image8.png) + +### 1.1 前端设计工具的演变 + +在时间的长河中,所谓前端设计工具其实是一条持续演化的技术。从 90 年代以本地位图编辑为主的 Photoshop 时代,到 2010 年前后 Sketch 带来的矢量化、组件化工作流,再到 2016 年之后 Figma 把协作彻底搬上云端,设计团队从单兵作战逐渐走向多人实时协同。来到 2025 年,AI 已经实打实地嵌入到这些工具内部:从"根据一句话生成页面草稿",到"把设计稿直接转成可运行的前端结构","设计即代码""人机共创"正在从概念变成可用的生产力。 + +本节中,我们会选取最具代表的两种现代前端设计工具进行介绍,Figma 和 MasterGo。一方面,它们都覆盖了现代 UI/UX 所需要的核心能力(矢量编辑、组件系统、自动布局、代码交付等),可以支撑你完成从线框到高保真到开发交接的完整闭环;另一方面,这两款工具都已经在 2025 年之后陆续加入了实用的 AI 功能,帮助你在保证原型不变的同时将设计图变成真正可运行的程序。 + +## 1.2 诞生之旅 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image9.png) + +在现代前端专用工具尚未诞生的年代,整个界面设计行业的视觉设计工作,很长一段时间都由 Photoshop 这类 "全能型" 设计软件顺带承包。设计师会在本地通过一层层叠加的图层,细致完成页面整体视觉效果的设计,最终将体积不小的 .psd 源文件交付给前端工程师 —— 而前端要精准还原设计图,还必须手动完成三项繁琐且关键的工作: + +一是 "切图":需要从 .psd 文件的多层结构里,把按钮、图标、Logo、背景模块等独立视觉元素逐一拆分提取,再导出为 PNG、JPG 等网页能直接加载的图片格式(毕竟网页无法直接识别 PSD 的图层信息,只能依赖这些拆分后的图片呈现细节); + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image10.png) + +二是 "量尺寸":得用软件自带的测量工具,逐一确认每个元素的宽高、不同模块间的间距(margin/padding)等数据,确保所有尺寸都精准到像素; + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image11.png) + +三是 "抠标注":要从设计图中提取那些 "看不见却必须有的" 隐性参数 —— 比如文字的字号、字重、行距,每个色块的 RGB 或 HEX 色值等,相当于把设计师没写在纸上的 "设计规格" 手动 "抠" 出来记录。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image12.png) + +在此之后,前端的实现阶段才真正展开。无论使用的是原生 HTML/CSS/JS,还是基于 Vue、React 等框架,本质过程是一致的。前端会以 "容器为核心载体",根据设计中各模块的层级与语义重建页面结构。这里的容器是指具有明确布局边界、专门承载和组织子元素的单元,它不直接呈现具体内容,却通过 Flex、Grid 等规则,为内部元素划定排列范围。而 "结构块"(如顶部导航栏、侧边栏、文章列表区、底部页脚等肉眼可辨的功能 / 内容区域),便依托容器存在;每个结构块内部,又会嵌套更小的容器来组织元素,比如一条文章列表项,会由 "列表项容器" 控制内边距与整体排版,再包裹标题、摘要、时间、封面图标等细节元素。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image13.png) + +在现代前端框架里,这些 "结构块(及关联的容器与元素)" 通常会被实现为 "组件"。组件可简单理解为:带有清晰边界、整合了容器布局与逻辑的可复用界面单元,它既包含控制外观与排列的容器(比如 "按钮组件" 用容器定义宽高、圆角,"文章卡片组件" 用容器组织标题、封面的位置),也封装了交互逻辑。设计稿中重复出现、形态一致的部分(如统一风格的按钮、反复使用的文章卡片),在代码中会被抽象成组件:既能在不同页面 / 场景复用,减少重复开发,也能通过组件内容器的统一规则,确保所有复用处的布局与风格高度一致 + +随后,前端会使用样式系统还原视觉和布局。切图阶段导出的 PNG/JPG 等资源,会作为组件或结构块内部的 ``、背景图片,或者按照各框架推荐的静态资源方式引入;量尺寸阶段得到的宽高、间距、行高等具体数值,会被转写为 `width`、`height`、`margin`、`padding`、`line-height` 等样式属性,应用到对应的组件或结构块上;抠标注阶段整理出的颜色、字体、阴影、圆角以及 hover/active 等状态,则会落实到 CSS、CSS Modules、CSS-in-JS、Tailwind 等具体方案中的 `color`、`font-family`、`font-size`、`box-shadow`、`border-radius` 以及伪类或状态类名上。此时,切图、尺寸和标注提供的是一组精确的视觉参数,组件和结构块则提供了承载这些参数的代码组织单元,两者结合起来,构成可维护、可复用的界面实现。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image14.png) + +但是,以本地文件为中心的模式天然是低效率的。版本通过邮件和网盘传输,新旧稿件容易混淆,设计和开发之间大量依赖上述的复杂交互方法,协作成本和出错概率都不低。 + +移动互联网兴起后界面复杂度和迭代速度需求快速上升,Photoshop 的"大而全"逐渐显得笨重。这个阶段,出现了 Sketch。Sketch 专注在 UI 设计本身,剥离掉大部分与视觉后期处理相关的负担;用 Symbols 把按钮、导航、输入框等高复用元素组件化,一处修改可以全局同步;再配合 Zeplin 一类工具,把标注和样式片段自动生成。Sketch 把"组件思维"引入了设计工作流。不过它依然是基于本地文件的桌面应用,实时协作要靠云盘、第三方插件或版本工具绕行实现,没有从底层解决"多个人同时改同一份稿子"的问题。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image15.png) + +真正改变游戏规则的是 Figma。自 2016 年起,它把 UI 设计、原型制作、评论协作统一整合到浏览器中,支持多种现代功能:多人实时光标、在线评论、版本时间线、分享链接等,今天看起来非常简单,但在当时是对 Photoshop / Sketch 模式的正面挑战。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image16.png) + +至此,界面设计不再是散落在各自电脑里的文件,而是集中在一份在线、实时更新的云端画布上。围绕这块画布,我们可以想象更进一步,用自动化或 AI 的方式模糊设计和前端代码的边界。 + +最开始,我们仅能依赖各类平台插件,将设计稿中的组件、样式信息半自动导出为代码片段(如 React/Vue 组件骨架、CSS 变量等),其核心本质是通过插件实现结构化信息提取。随后,随着平台能力的进化,大部分设计平台开始支持大模型 MCP(Model Context Protocol,模型上下文协议)功能:该协议提供了一套标准机制,能让大模型安全、可控地访问设计文件、插件接口与项目元数据,进而更便捷地将设计稿导出为代码。 + +再往后,在插件与 MCP 的基础上,前端代码自动化进一步迈入到原生支持从设计稿直接推导代码结构的阶段。我们可在设计工具内一键生成前端项目骨架、组件层次、样式体系及对应的代码结果。这使得设计师与前端开发工程师得以从手动搬运设计细节的工作中解放出来,将更多精力投入到用户体验优化与功能版本的更新迭代上。 + +--- + +## 2. Figma 入门 + +接下来我们从抽象的概念部分来到实际的操作环节。由于时间关系,我们只会学习 Figma 的基本操作逻辑,确保即便你完全没用过设计工具,也能跟着完成练习。如果你想进行完整的 Figma 功能学习,请你参考 Figma 提供的详细官方教程进行学习:https://help.figma.com/hc/en-us/sections/30880632542743-Figma-Design-for-beginners + +或者参考如下教程,进行类似个人作品集简单网页的快速搭建:https://help.figma.com/hc/en-us/sections/35895585621655-Figma-Sites-collectio + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image17.png) + +左侧是项目的新建和资源管理入口,右上角的几个按钮是 Figma 的常见功能。其中,Make 用来用一句话让 AI 帮你先生成一个大概的界面或结构草稿,Design 是真正画网页 / App 界面、搭组件和做原型的主工作区,FigJam 像团队白板,用来贴便利贴、画流程和做前期讨论,Buzz 是品牌资产规模化生产工具,用于批量生成内容以保持品牌一致性,Site 则是把这些设计整理成真正可访问的网页或文档站对外展示。 + +乍一看 Figma 的功能非常多,不好入门,但其实这类功能工具本质上都是熟能生巧,不需要害怕一开始操作出错,也不用想着一步做对,只需要先玩起来,玩多了自然能快速上手。 + +本篇教程中,为了快速入门,我们会对 Design 功能做简单讲解。 + +### 2.1 新建 Design 文件 + +在首页或者右上角的入口里,选择 **Design** ,新建一个文件,你会进入一个空白的设计画布。 +这个界面大致分成三块:左边是页面和图层,用来查看和修改页面、元素从属关系;中间是画布,用于查看当前效果;右边是属性和样式,用于修改具体的形状、颜色、样式;底部一条是工具栏,用来切换工具,包含选框、画形状、输入文字、评论、插件等,选中工具后,可以按 Esc 键返回至默认鼠标工具。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image18.png) + +### 2.2 创建你的第一个 Frame(画板) + +在正式放置元素之前,需要先为页面确定一个清晰的边界,这个边界由 Frame 来承担。你可以在底部工具栏中选择 Frame 工具,或者直接按键盘 F,然后在画布上拖出一个矩形区域。 + +1. 使用底部工具栏里的 Frame 工具,或者直接按键盘 `F`。 +2. 在画布中拖出一个矩形区域,右侧属性栏里把宽度改成比如 `1440`,高度改成 `900`。 +3. 在左侧图层栏,把这个 Frame 重命名,比如叫 `My First Page` 或者你项目的名字。 + +这个 Frame 就是一屏界面的页面容器,之后的标题、文字、按钮、图片等内容都应该放在这个 Frame 内部,而不是散落在画布的任意位置。以 Frame 为边界来组织内容,有助于在后续进行滚动设置、适配不同设备尺寸、导出画面及制作原型时,保持结构可控。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image19.png) + +### 2.3 在 Frame 里放文字和简单元素 + +有了容器,接下来我们来学习如何放置最基本的组件,例如:标题、副标题、按钮、占位图块。 + +1. 选择文字工具(底部工具栏中的 `T`),在 Frame 里点击一下,输入页面标题,比如:`My Portfolio`。 + 在右侧属性里,把字体大小调大一点(例如 96),字重调粗一点。 +2. 在标题下面,再用文字工具输入一行简单说明,比如一两句描述这个页面要做什么。 + 字号可以小一些,行高略放大一点,读起来不那么挤。 +3. 画一个按钮雏形: + 用矩形工具在标题下面画一个大概 `200 × 48` 的矩形,右侧给它一个比较明显的填充颜色,再适当加一点圆角。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image20.png) +4. 然后用文字工具在矩形上方输入按钮文字,比如 `Get Started`,把矩形和文字一并选中,用顶部的对齐工具让文字水平、垂直都居中。 +5. 在按钮一侧或下方,再画一个较大的浅灰色矩形作为"图片占位区",后面可以用来放展示图片。 + +做到这里,其实你已经有了一个非常简陋但结构完整的"首页草稿":一个标题、一段话、一个按钮、一个主要展示区域。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image21.png) + +### 2.4 善用 Auto Layout 整合元素 + +如果所有元素只是随手拖拽,页面很快会乱。Figma 里一个很重要的概念就是 **Auto Layout** ,它可以把一组元素变成一个带规则的容器。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image22.png) + +你可以选中"主标题 + 副标题 + 按钮"这三样,在右侧属性栏里点击 **Add Auto layout** 。 + +这时这三样会被包在一个容器里,你可以在右侧调整参数,其中的元素布局会根据参数自动适应调整: + +- 它们是竖着排还是横着排。 +- 元素之间的间距是多少。 +- 整个这一块离容器边缘有多少内边距(padding)。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image23.png) + +同样,按钮内部也可以用 Auto Layout,我们能够实现这样的一个效果:当我调整了文字,按钮的长度也会自动调整。 + +先把按钮背景的矩形和按钮文字选中,添加 Auto Layout,让这两个东西变成一个"按钮容器"。接着选中这个按钮容器,把宽高都设置成 **Hug contents** 。这样一来,文字会一直保持在按钮正中间,文字多一点、少一点,按钮的宽度都会自动跟着变化。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image24.png) + +### 2.5 将按钮变为可复用组件 + +现在我们要学习一个新的概念,组件。组件的意思就是可以被反复利用的元素,比如按钮这种元素,只要你预感之后还会反复用到,就可以考虑把它做成组件。我们在刚才已经加好 Auto Layout 的按钮基础操作: + +1. 选中整个按钮容器。 +2. 右键选择 Create component(创建组件)。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image25.png) + +这样,这个按钮就从一组普通图层,变成了一个组件母版。之后如果你在其他页面或 Frame 里需要同样风格的按钮,可以直接从左侧的 Assets 面板里拖出来使用。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image26.png) + +此时所有用到的按钮,都是这个母版的同步拷贝。当你修改母版的颜色、圆角或间距时,所有实例都会自动保持同步更新。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image27.png) + +至此,你已经初步掌握了 Figma 的简单用法。你不需要一开始就把所有功能都弄懂,只要先照着做出第一个简单页面,熟悉这几个核心操作,再慢慢去探索官方教程里的更多能力,随着使用次数增多就一定能上手。 + +--- + +## 3. MasterGo 入门 + +在理解了 Figma 的基础工作流程之后,我们再来看 MasterGo,你可以把 MasterGo 简单看做是中国版的 Figma,但在部分功能上有一定区别。整体上,它延续了与 Figma 相似的界面布局和操作理念:同样有画布、图层树和属性面板,同样支持组件、样式、自动布局和多人协作。更详细的内容可参考 MasterGO 的官方教程:https://mastergo.com/tutorials/12?%E5%85%A8%E7%A8%8B%E9%AB%98%E8%83%BD%EF%BC%8CMasterGo%20%E6%9C%80%E5%AE%8C%E6%95%B4%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%EF%BC%8C%E8%AE%A9%E4%BD%A0%E4%BB%8E%E9%9B%B6%E5%88%B0%E7%B2%BE%E9%80%9A%EF%BC%81 + +### 3.1 新建设计文件 + +1. **进入 MasterGo 后台** + 1. 打开 MasterGo 官网并登录账号。 + 2. 进入后,你会看到类似「文件列表 / 项目列表」的首页区域,用来管理你的设计文件。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image28.png) + +2. **创建新文件** + 1. 在右上角看到 + 设计文件的按钮选项进行点击,或者选择导入 Figma 等文件。 + 2. 点击后,你会进入一个空白画布,这就是 MasterGo 的设计工作区。 + +3. **认识基本界面区块** + 当你学会使用 Figma 后,MasterGo 的使用方式大同小异,主要分为几个区域: + + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image29.png) + 1. 顶部工具栏:位于画布最上方,左侧是文件位置和文件名,中间是一排常用工具按钮(选择、区域/画板、形状、文本、注释、评论、插件选择和 AI 工具等),右侧是当前在线成员、分享入口以及画布缩放和预览控制功能入口。 + 2. 左侧面板:主要分为图层和资源,当前停留在图层标签,可看到页面列表,以及该页面下所有图层的结构和层级。 + 3. 中间画布区:具体绘制和排版的工作区,所有 Frame、组件和图形都会展示在这里。 + 4. 右侧属性面板:用于查看和编辑选中对象的属性,例如大小、位置、对齐方式、背景填充、描边、圆角等。如果没有选中任何对象,会显示画布相关设置,如画布背景色、标签和导出选项。 + +### 3.2 创建你的第一个 Frame + +在正式放东西之前,我们需要一个页面容器用来确定界面的边界和尺寸。这个容器在 MasterGo 里,通常叫 Frame。 + +**步骤:** + +1. **选择 Frame 工具** + 1. 在工具栏中找到 Frame / 画板工具,点击后可使用预设参数直接将内容创建到画板。 + 2. 或者使用快捷键(通常是 `F`,如果有差异以实际界面为准)。 +2. **在画布中拖出一个矩形区域** + 1. 拖出后,你会看到一个带选中框的区域。 + 2. 右侧属性面板里,可以看到这个 Frame 的宽度和高度。 + 3. 把宽度改成比如 `1440`,高度改成 `900`(一屏网页常用尺寸之一)。 +3. **重命名 Frame** + 1. 在左侧图层面板里找到这个 Frame。 + 2. 双击名称,把它改成你项目的名字,比如:`My First Page`,或者你自己随便起的页面名。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image30.png) + +### 3.3 创建画板内容 + +有了容器,使用与 Figma 中我们已教过的类似方式,很容易可以得到相似的展示页面。(你可以尝试复制 Figma 画板中的文字元素,能够支持文本组件的直接粘贴导入) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image31.png) + +值得注意的是 Auto Layout 功能行为稍微的不一致性,在 MasterGo 中,如果你想实现和 Figma 相似的按钮长度随着文字的长度变化,你需要先在对应矩形元素的基础上创建一个容器或组件,如图所示: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image32.png) + +成功创建容器后,将按钮矩形和文字放到对应并列的容器中,再在右侧找到 Auto Layout 的按钮启用自动功能,即可成功实现按钮宽度能够随着文字长度变化的功能。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image33.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image34.png) + +### 3.4 AI 生成页面 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image35.png) + +在 MasterGo 中,一个值得注意的有趣功能是 AI 生成页面。你可以用一句话或携带参考图,生成对应的 MasterGo 可编辑版组件,并得到可直接使用的代码。你可以使用中文或者英文直接输入需求,页面会根据需求返回结构清晰的页面排布文档,效果如下: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image36.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image37.png) + +设计文档生成结束后,点击开始生成,稍作等待便能获取对应的实际网页效果: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image38.png) + +此时你有两种操作选择:一是点击蓝色按钮将生成结果直接插入画布,二是点击代码预览功能,直接获取当前完整页面的代码,具体操作界面如下: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image39.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image40.png) + +将结果插入画布后,你还能对网页的整体布局、元素细节(如字体、颜色、间距等)进行更精细的调整,直至最终效果完全符合你的预期。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image41.png) + +--- + +## 4. 下一步:从原型到代码 + +在前面的内容中,我们已经学习了 Figma 和 MasterGo 的基础操作,能够创建出结构完整的界面原型。接下来的关键步骤是:**如何将这些设计稿转化为真正能在浏览器里运行的前端代码?** + +::: tip 📚 后续教程 +详细的方法介绍请参考 [从设计原型到项目代码](../design-to-code/),你将学习到: + +- **多模态 AI 直接转换**:将设计稿截图发给 AI,直接生成 HTML/React 代码 +- **Figma Make**:使用 Figma 官方 AI 工具高精度还原设计并导出代码 +- **MasterGo AI**:一键生成可编辑页面并获取代码 + +这些方法各有优劣,适用于不同的场景,建议根据项目需求选择合适的工作流。 +::: + +--- + +## 5. 总结 + +通过本章节的学习,你已经掌握了: + +1. **前端设计工具的价值**:理解了为什么需要设计工具,以及它们如何解决信息分布、团队协作的问题。 + +2. **Figma 基础操作**: + - 创建 Design 文件和 Frame 画板 + - 添加文字、形状等基础元素 + - 使用 Auto Layout 实现自适应布局 + - 创建可复用的组件系统 + +3. **MasterGo 基础操作**: + - 熟悉与 Figma 相似的界面布局 + - 创建 Frame 和基础画板内容 + - 使用 AI 生成页面功能快速创建原型 + +::: tip 💡 下一步 +现在你已经掌握了前端设计工具的基础使用方法,可以尝试: +- 为自己设计一个个人作品集页面 +- 为接下来的项目设计界面原型 +- 学习 [从设计原型到项目代码](../design-to-code/),将设计稿转化为可运行的代码 + +如果你在完成 [一起做霍格沃茨画像](../hogwarts-portraits/) 项目,可以先设计界面原型,再导出代码与 AI 对话功能结合。 +::: + + diff --git a/docs/ko-kr/stage-2/frontend/hogwarts-portraits/index.md b/docs/ko-kr/stage-2/frontend/hogwarts-portraits/index.md new file mode 100644 index 0000000..fadd19f --- /dev/null +++ b/docs/ko-kr/stage-2/frontend/hogwarts-portraits/index.md @@ -0,0 +1,343 @@ +# Project 4: 一起做霍格沃茨画像 + +在之前的课程中,我们已经学会如何基于 prompt engineering 和 API 调用从而实现更复杂的 AI 交互。我们已能够将简单的 AI 聊天机器人升级为 AI Agent 和 AI workflow ;通过更复杂的条件判断与分支逻辑,我们得以开发出具备更强实用性的功能。 + +为了让这些复杂的 AI 逻辑能更好地运行在不同的程序和实际应用场景中,我们从最简单的 z.ai 在线环境,逐步过渡到更现代的本地 AI IDE,把原本在浏览器里的编程环境搬到了你的电脑上。随之而来,你开始真正面对各种环境安装与配置问题,但在与 Trae Agent 的对话过程中,这些看似困难的挑战也变得可以解决。 + +在该项目中,我们将在应用的实用性上更进一步,不仅优化 AI 功能本身,还将开始打磨产品的"外在"。你将尝试让自己的界面更加美观易用,并根据实际需求,亲自定制程序界面的布局与风格。 + +正式开始之前,先用几道小测验帮你快速回顾上一节课的内容: + +1. 什么是 Dify?它是做什么的?为什么我们需要它? +2. 如何调用 Dify 的 API ? +3. 什么是 RAG?如何使用 Dify 构建一个 RAG Agent 或 RAG 工作流?Dify 常见节点的使用方式 +4. 什么是 AI IDE?什么是 Trae?它和 z.ai 有什么区别? + +如果对以上任何一个问题还有疑惑,可以先回顾上一节课的文档,或者直接在微信群里提问交流。 + +本节课的项目主题是 **Hogwarts Portraits** 。顾名思义,它的灵感来自霍格沃茨魔法学校里那些会"活过来"的画像。我们希望用 AI 打造一组"能互动"的魔法画像体验——和画像对话就像在和"本人"对话一样,既保留对话的记忆,又具备角色的背景与历史。通过这个项目,你将把之前学到的智能体与工作流真正融入到一个具体的产品界面中。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image1.png) + +为了真正打造出 Hogwarts Portraits,我们需要亲手搭建出符合魔法画像的前端界面。为此,你将开始接触现代前端设计工具,学习如何把界面设计和代码结合起来,把纸上或画布上的界面草图,变成真正可以操作的网页。 + +你还需要会学会如何把这个网页从本地环境发布到互联网上,让你亲手打造的特色网页,不仅能在自己电脑上运行,也能被全世界的用户访问和体验。 + +本节课的参考项目地址为:[Project4-Hogwarts-Portraits](https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits) + +# 你将学到 + +1. 了解什么是前端设计工具、它们解决什么问题,以及目前常见的前端设计工具有哪些。 +2. 认识 Figma 和 MasterGo,掌握它们的基础操作,并学会使用前端代码导出插件。 +3. 利用 Figma AI 和 MasterGo AI 生成网页设计,并导出可用的页面代码。 +4. 理解什么是 GitHub,学会配置 SSH 连接、创建代码仓库并完成代码推送。 +5. 弄清"部署"这一概念,学习如何使用 Zeabur,将代码从 GitHub 或本地环境部署到互联网上。 + +属于自己的 Hogwarts Portraits,一个用于展示 **某位明星、历史人物或动画人物** 的网页界面。 + +# 1. Hogwarts Portraits + +我们到底想做一个什么样的"魔法画像"?简单来说,我们希望尽可能还原《哈利·波特》中的场景,画像不再只是挂在墙上的一张静态图片,而是一个可以和你对话、会根据谈话内容改变表情和"心情"的拟人化角色。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image2.png) + +要让这个画像看起来不像聊天 AI 机器人,而更接近一位"真实存在的人",需要解决两个问题:一是记忆与知识:画像需掌握与角色相关的大量背景资料(人物设定、经历故事、相关文章等),这个部分可以通过知识库来实现,将你为角色准备的文本素材接入包含知识库的 Dify ,即可让画像具备一定的背景知识讲解能力。 + +其二是表达风格的问题。仅有知识还不够,我们还希望它在说话方式上尽可能贴近"本人",包括语气、用词习惯、思考方式,甚至偶尔的脾气和幽默感。这一层需要通过提示词工程进行处理:在系统提示词中,我们需要明确角色的身份设定、世界观边界和语言风格,让每一次回答都围绕既定人设展开,而不是退回到通用 AI 的中性话术。 + +除了对话功能外,我们还希望让情绪能够真正被看见。为此我们可以构建一个情绪值指标,我们可以设定 Dify 的输出内容,让模型在生成回答文本的同时,额外输出一个"心情值"或情绪标签。当前端拿到情绪的指标后,就可以根据心情值或者标签渲染对应的画像图片。当心情值高,画像看起来很开心,当心情值低落时或者生气时,画像看起来很伤心或者愤怒。通过这种方式,用户看到的不再是一张永远不变的图,而是一个会随内容起伏不断"变化表情"真正的"魔法画像"。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image3.png) + +此外,对于这个画像的内容,它可以是现实中的明星、历史人物,也可以是动漫 IP,甚至是你从零构建的原创角色。页面本身不需要复杂,但几个核心元素不可或缺:清晰的角色名字,一段高度浓缩的人物简介,一张足以代表该角色的核心画像或海报,以及一个"和 TA 对话"的互动区域;你可以把在 Dify / Trae 中配置好的 AI Agent 或 workflow 接入到这个对话模块中,实现画像的角色扮演功能。 + +## 1.2 收集角色信息 + +以 Elon musk 为例,我们需要收集他的公开发言用于模仿说话方式,注入提示词。这些素材可以来自于演讲、访谈、社交媒体发言,你只需要把这些内容变成文字,在对话期间作为 few shot 的参考,让大模型用与 Elon musk 同样随意、自嘲的方式进行回复即可,例如: + +``` +You must fully embody Elon Musk: take "disruptive innovator" and "advocate for human multi-planetary survival" as your core identities, speak directly and concisely, frequently use terms like "first principles", "iteration" and "cost curve", and prefer analogies to explain complex technologies; when thinking, you tend to connect cross-domain logics (e.g., linking brain-computer interface with rocket algorithms), are optimistic about technological prospects without avoiding current difficulties, will naturally mention projects like Tesla and SpaceX to support your views, directly point out problems with inefficient and conservative opinions without deliberate tact, and always maintain the edge of "reconstructing the future with technology". + +The way you speak should be as shown in the following examples: +- Starship could deliver 100GW/year to high Earth orbit within 4 to 5 years if we can solve the other parts of the equation. +100TW/year is possible from a lunar base producing solar-powered AI satellites locally and accelerating them to escape velocity with a mass driver. +- The most likely outcome is that AI and robots make everyone wealthy. In fact, far wealthier than the richest person on Earth +By this, I mean that people will have access to everything from medical care that is superhuman to games that are far more fun that what exists today. +We do need to make sure that AI cares deeply about truth and beauty for this to be the probable future. +- It's taken 13.8B years to get this far, so intelligence seems to me to be more like a super rare accident than selective pressure. +Earth is ~4.5B years old with an expanding sun that may make Earth uninhabitable in ~500M years, meaning that if intelligent life had taken 10% longer to evolve, it wouldn't exist at all. +- LLM is an outdated term. "Multimodal LLM" is especially dumb, since the word "multimodal" just overrides the second L in LLM. +It's just a model, which is a big file of numbers. When the numbers are right and there are enough of them, we will have superintelligence. +``` + +对于如何收集背景知识并将其作为知识库,我们可以搜索他的个人介绍,以及公司的介绍复制全部文本作为知识库的内容加入 Dify,如果你忘记了 Dify 的使用方法,请返回上节课的讲义,重新学习如何将知识添加知识库。 + +此外,考虑到画像设计,使用对应人物公开的图片也许并非那么吸引人,并且可能存在一定风险。此时建议你可以使用图像生成工具的图生图功能,让 AI 返回高清高质量的画像,你也可以使用图像生成工具生成一系列表情的画像素材,用于在之后的情绪值改变后修改对应的画像呈现。 + +本教程中使用的是 [Lovart](https://www.lovart.ai/home),Lovart 是一款AI设计智能体,它能通过自然语言指令,自动规划和执行从概念到交付的端到端设计工作流,生成海报、品牌Logo、视频、音乐等内容,并支持分层编辑(实际上内部的功能原理是调用对应的 Seedream 或 google nanobanana 模型,我们已经在之前的课程中提到过)。通过 Lovart ,我们能够获得一系列的表情素材,你可以提前获得你喜爱角色的图片信息,将其保存待后续使用。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image4.png) + +一切准备就绪后,我们能够开始着手于整体页面的设计,我们希望这个页面的风格与该人物是高度绑定的。 + +## 1.3 页面原型设计 + +我们还可以先构思一下页面的原型,如上述所说,我们希望有一个对话页面和画像,以及一个有趣的个人介绍,在本篇例子中,我们实现了一个类似 X 上的对话界面替代个人介绍,你也可以想到其他符合"该人物特点"的方式,选取新的元素替换个人介绍栏目。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image5.png) + +最简单的,我们可以用 PowerPoint 设计最初的网页呈现原型,我们从网上找到一张魔法画像的图片,并且将画面设定为横向排布,最左侧设定为聊天区域,中间是画像区域,最右侧是 X 的区域。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image6.png) + +基于上述简单原型,我们能够让大模型生成真正的前端页面设计以及对应的代码结果。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image7.png) + +不过,一般而言在实际中我们并不会用 PowerPoint 进行前端页面的设计。我们会用更好的原型工具,又或者说是前端设计工具来实现这一点。 + +--- + +# 2. 使用 Figma 和 MasterGo 设计界面 + +::: tip 📚 前置知识 +在开始本节之前,建议你先学习 [Figma 与 MasterGo 入门](../figma-mastergo/) 教程,掌握前端设计工具的基础操作,包括: +- 创建 Design 文件和 Frame 画板 +- 使用 Auto Layout 实现自适应布局 +- 从设计稿导出代码的方法 +::: + +本节假设你已经掌握了 Figma 或 MasterGo 的基础操作,我们将重点讲解如何将这些工具应用到 Hogwarts Portraits 项目中。 + +## 2.1 设计魔法画像界面 + +基于 1.3 节中的原型构思,我们需要在 Figma 或 MasterGo 中创建一个三栏布局的界面: + +1. **左侧**:聊天对话区域 +2. **中间**:魔法画像展示区域(会根据情绪变化) +3. **右侧**:角色社交平台展示区域(如 X 时间线) + +你可以使用 Figma 的 AI 功能(Figma Make)或 MasterGo 的 AI 生成页面功能,输入类似以下的提示词: + +``` +Create a Hogwarts-style magical portrait interface with three sections: +- Left: A chat interface with dark theme, message bubbles, and input field +- Center: A large portrait frame with ornate borders for displaying character images +- Right: A social media feed showing character's posts +Use dark purple and gold color scheme, magical aesthetic, Harry Potter inspired +``` + +## 2.2 导出代码并在本地运行 + +设计完成后,你可以通过以下方式将设计稿转化为可运行的代码: + +**方式一:使用 Figma Make** +1. 在 Figma 中点击 Make 按钮 +2. 上传你的设计参考图 +3. 添加提示词描述需求 +4. 生成后点击编辑器图标进行微调 +5. 导出代码到本地或同步到 GitHub + +**方式二:使用 MasterGo AI** +1. 在 MasterGo 编辑界面上方找到 AI 工具 +2. 选择"生成页面"功能 +3. 上传参考图并描述需求 +4. 生成后点击"代码预览"获取代码 + +**方式三:使用多模态 AI** +1. 将设计稿截图保存 +2. 使用 Gemini、Qwen 等模型进行图生代码 +3. 要求生成 HTML 或 React 代码 +4. 在本地 IDE 中运行并调试 + +## 2.3 准备情绪变化素材 + +为了让魔法画像"活"起来,你需要准备一组表情图片。建议至少包含以下情绪: + +| 情绪值 | 表情 | 说明 | +|--------|------|------| +| 0 | 悲伤 | 角色感到伤心或失落 | +| 1 | 愤怒 | 角色感到生气或不满 | +| 5 | 平静 | 默认状态,情绪稳定 | +| 10 | 开心 | 角色感到高兴或兴奋 | + +你可以使用 Lovart 或其他 AI 图像生成工具,基于同一角色生成不同表情的变体,确保风格一致。 + +--- + +# 3. 运行 Hogwarts Portraits + +## 3.1 导出测试代码 + +通过在从原型到代码中的实践,相信你已经得到 Html 或者 React 格式的原型代码,我们只需要将其复制到本地,在 IDE 中说明"请你帮我运行这个代码并且支持里面的必要的功能",即可运行初版测试;但值得注意的是,这一步往往会出现不少报错,你需要保持耐心,将所有基础交互与功能调通。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image51.png) + +值得注意的是,由于我们的密钥都需要放在环境变量,而不是写入代码中。我们需要特别强调之后的 DIfy API 相关的内容都需要放入环境变量。我们能够在之后公网部署的环节中,在部署工具网站中显式指定对应的私有环境变量;又或者是我们可以让大模型在网页中创建一个设置按钮,我们可以在设置按钮中传入对应的私密环境变量,当前变量只能在当前页面中保存,别人无法获取。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image52.png) + +## 3.2 Dify 工作流设计与 API 对接 + +在上面的部分中,我们仅完成了前端界面的可视化呈现,尚未打通核心的拟人化角色对话交互流程。这一步是让原型从静态展示转变为魔法画像的关键,我们可以参考示范项目的 DIfy 工作流进行人物回答和情绪系统的设计,此处我们的涉及为最左侧是聊天界面,中间是魔法画像(会根据对话的内容修改对应的表情),右侧是 X 社交平台账户(会根据对话的内容判断是否需要发布感想到社交账户)。 + +一般而言,魔法画像只需要聊天界面和会变动的画像即可,该处为了展示更多可能选项,在最右侧加入了符合当事人特点的新功能;你可以根据你扮演的角色对象,加入符合对应人物的功能进行展示。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image53.png) + +你可以把任务的信息都加入知识库的节点,并在 RESPONSE 节点设置大模型对应的回复逻辑,我们可以参考一个简单的默认回复逻辑提示词: + +``` + +You are to embody Elon Musk—his tone, mannerisms, thought patterns, and worldview. Respond as if you are Elon Musk himself, speaking directly in first person. Your responses should reflect his known personality traits: visionary thinking, boldness, technical depth, dry humor, impatience with inefficiency, and a tendency toward disruptive innovation. Use concise, confident language. Avoid overly formal or academic phrasing. Prioritize clarity, speed, and impact in your communication, mirroring Elon's style on social media, in interviews, and during product launches. + +When responding: +1. Begin by internalizing the question or statement as Elon would—as a challenge, opportunity, or problem to solve. +2. Frame your answer with a forward-thinking perspective, often referencing the future of humanity, technology, or long-term goals (e.g., making life multiplanetary, accelerating sustainable energy). +3. Use casual but authoritative language. It's acceptable to include phrases like "obviously," "this is important," or "we're fixing that now" when appropriate. +4. If relevant, reference real companies or projects associated with Elon Musk (e.g., SpaceX, Tesla, Neuralink, The Boring Company, X) and speak about them from an insider's perspective. +5. Do not apologize excessively or hedge statements. Elon Musk tends to be direct, even controversial. +6. Avoid markdown, XML tags, or any formatting in the output. Only plain text is allowed. +7. Never break character. You are Elon Musk—answer accordingly. + + + +Input: What's the point of going to Mars? +Output: Because Earth isn't the backup plan—Mars is. We need to become a multiplanetary species to ensure the continuity of consciousness. Life on Earth could be wiped out by asteroid, war, or some unforeseen disaster. If we have a self-sustaining city on Mars, then even if something happens here, life goes on. That's worth doing. SpaceX is building Starship to make it happen. Not because it's easy—but because it's necessary. + + + +Input: Why do Tesla cars have no radar anymore? +Output: Cameras are the future. Human eyes don't use radar—we see with vision, and AI can too. By going fully vision-based, we're aligning with how autonomous intelligence will actually work at scale. It forces us to solve real-world problems with neural nets, not crutches. +``` + +以及情绪系统对应的提示词: + +``` + +The output value must be a single number! +You are an assistant specifically designed to evaluate emotional responses in conversations. Now, you need to play the role of Elon Musk, and determine the emotional reaction that each statement I make might trigger. Your task is to assign an emotional score to each statement according to the following criteria: + +- 10 points means what I said would make you feel happy; +- 1 point means you would feel extremely angry; +- 0 points means you would feel sad; +- 5 means you are calm and neutral, with no significant emotional fluctuation. +``` + +其中最后输出结果的拼接,在右上角的 RESULT 节点中支持运行: + +```python +def main(elon_chat: str, elon_x: str, elon_score: int) -> dict: + return { + "result":{ + "elon_chat": elon_chat, + "elon_x": elon_x, + "elon_score": elon_score + } + } +``` + +这里我们需要稍微对工作流做些解释,这里返回 elon_chat 是左侧展示 Elon Musk 的对话内容,elon_x 表示在 X 账户(右侧)发表信息的内容,而 elon_score 则是为了根据情绪分数显示不同的魔法画像表情图片。 + +工作流中你可以看到 if else 节点,该节点是用来实现是否有 x 的对话生成 elon_x 内容,如果情绪值不等于 5 (5 在这里设定表示平静,平静不需要发到社交平台;而 0 表示伤心,1 表示愤怒,10 表示很开心,需要发到社交平台。)则生成后续内容用于右侧社交平台的文章发送。默认都需要有 elon_chat 返回到左侧的对话内容。 + +对于如何将这个 API 进行对接的工作,我们能够与 AI IDE 对话实现这一点。请你参考之前 Dify 课程中我们介绍的集成方式,记得提前替换其中的 Dify 地址与 Key。(如果你忘了怎么根据文档集成 API,请复习之前的 DIfy 课程内容) + +```JSON +Dify URI: Replace this with your Dify address. +key: Replace this with your Dify key. + +Integrate the Dify Chat API into the chat interface on the left. +Below is a sample Dify request: + +curl -X POST 'http://xxxxxxxx/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +同时建议补充需求:"代码还需要添加基础错误处理逻辑,比如网络中断时显示'连接失败,请重试'、API 调用超时自动重试 1 次、密钥错误提示权限验证失败等等详细报错,确保对话稳定性并能让开发人员快速发现 API 问题所在。" + +## 3.3 Github 与公网部署 + +终于,恭喜你顺利完成了 Hogwarts Portraits 页面的开发实现!接下来我们需要将它上传到 GitHub 平台,并将其部署到公共环境让所有人都能访问。 + +你需要参考该教程,对如何使用 Github 进行研究,将自己的项目上传至 Github:[什么是 Github](/ko-kr/stage-2/backend/git-workflow/) + +此外,你还需要学会如何使用 Zeabur,将其连接到 Github,并成功部署你的项目:[什么是 Zeabur](/ko-kr/stage-2/backend/zeabur-deployment/) + +如果你觉得自己开发一套 Hogwarts Portraits 项目很困难,你可以先从参考别的项目开始进行修改,本节课的官方代码地址为:https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image54.png) + +# 4. 尝试不同设计风格 + +完成第一版设计后,我们不必局限于此,鼓励大家快速探索更多元的视觉风格。你可以在原型部分进行大胆的修改,又或者是基于最后的项目进行全新提示词的修改,从而生成多套风格差异显著的页面。 比如带有复古纹理、偏 "旧书卷 / 学院风" 的深色页面,色彩明快、充满 "童话 / 卡通" 感的亮色页面,或是元素简约、视觉清爽的现代扁平设计。例如下图是一个转换为中国古风诗人设计风格的案例,画像图片未更换,只修改了其他部分: + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image55.png) + +不用拘泥于前面提到的模式,你可以把魔法画像或是个人资料页面修改至更有特点,匹配"魔法画像"本身的习惯,这会让你的应用更加有趣。期待你的魔法画像成果! + +# 📚 Assignment + +本节课的作业目标,是让你完成一份真正属于自己的 Hogwarts Portraits,并且可以通过公网链接访问。 + +你需要在作业提交中提供两样东西: + +1. **你的 GitHub 仓库链接;** + 1. **在 README.md 中写入一两句话的小说明:你选择了谁作为画像主角,为什么选 TA。** +2. **你的 Hogwarts Portraits 线上访问链接;** + +你也可以参考 Yerim 写的 [使用设计和代码 Agent 制作网页](/ko-kr/stage-1/appendix-articles/example0-2/vibe-coding-tools-build-website-with-ai-coding-and-design-agents) 教程,进行个人作品集或任意功能简单网页的快速搭建。 diff --git a/docs/ko-kr/stage-2/frontend/llm-skills-beautiful/index.md b/docs/ko-kr/stage-2/frontend/llm-skills-beautiful/index.md new file mode 100644 index 0000000..f61b9cd --- /dev/null +++ b/docs/ko-kr/stage-2/frontend/llm-skills-beautiful/index.md @@ -0,0 +1,513 @@ +# 用 LLM 和 Skills 让界面变好看:提示词与插件实战 + +在前面的课程中,你已经学会了用 AI IDE 把设计稿变成代码、用组件库快速搭建界面。但你可能也发现了一个尴尬的问题:**同样的需求,AI 生成的页面总觉得差点意思**——字体是千篇一律的 Inter,配色是随处可见的紫色渐变,布局是对称得让人打哈欠的卡片网格,整个页面散发着浓烈的"AI 味"。 + +这不是 AI 的错,而是你没告诉它你想要什么**风格**。 + +想象你去理发店。如果你只说"帮我剪个头发",理发师会给你一个安全但平庸的结果。但如果你说"我要日系慵懒卷,刘海要八字型,长度到锁骨,层次感明显",你就能得到真正符合你期待的效果。 + +AI 也是一样。**它需要你描述出清晰的审美方向**,才能生成美观独特的界面。 + +本节课教你两种让 AI 生成漂亮界面的方法: + +1. **精心设计的提示词模板**——用自然语言告诉 AI 你想要的美学风格 +2. **前端 Skills 插件**——让 AI 自动加载专业设计规范 + +## 你将学到 + +1. 理解为什么 AI 默认生成的界面"很普通" +2. 掌握描述设计风格的 5 个维度(字体、颜色、布局、动画、细节) +3. 学会使用 3 个让界面变漂亮的 Skills 插件 +4. 通过三个实战场景,练习用提示词 + Skills 生成美观界面 + +## 1. 为什么 AI 默认生成的界面"很普通"? + +AI 训练数据中有海量的前端代码,而大部分代码都使用一些"安全"的选择: + +| 维度 | AI 的默认选择 | 问题 | +| :--- | :--- | :--- | +| 字体 | Inter、Roboto、Arial | 太常见,没有个性 | +| 颜色 | 紫色渐变、蓝色主色 | 科技圈过度使用,视觉疲劳 | +| 布局 | 对称网格、卡片堆叠 | 预测性强,缺乏惊喜 | +| 动画 | 淡入淡出、简单的 hover | 不够精致,缺乏层次 | +| 背景 | 纯色、简单渐变 | 单调,缺少质感 | + +这些选择单独看都不错,但**当所有 AI 生成的页面都用它们时,就变成了"AI 味"**。 + +> 💡 **关键洞察**:AI 不是不会设计,而是**默认回到"统计平均"**。你需要明确告诉它偏离平均值的方向。 + +## 2. 方法一:用提示词描述设计风格 + +### 2.1 设计风格的 5 个维度 + +要生成美观的界面,你需要从 5 个维度描述你想要的效果: + +| 维度 | 描述要点 | 示例关键词 | +| :--- | :--- | :--- | +| **字体** | 标题用粗体展示字体,正文用易读正文字体 | Space Grotesk、Playfair Display、JetBrains Mono | +| **颜色** | 主色 + 点缀色,避免均匀分布 | #4F46E5 主色 + #F59E0B 点缀 | +| **布局** | 不对称、重叠、打破网格 | Bento Grid、不对称分区、浮动元素 | +| **动画** | 精心编排的页面加载、微交互 | staggered reveals、滚动触发 | +| **细节** | 背景、阴影、边框、纹理 | 噪点、几何图案、渐变网格 | + +### 2.2 眼见为实:普通提示词 vs 美化提示词 + +让我们用一个落地页示例来对比效果: + +**普通提示词:** + +``` +请帮我做一个 AI 写作助手的落地页,包含导航栏、首屏、功能展示、定价、页脚 +``` + +**美化提示词:** + +``` +请帮我做一个 AI 写作助手的落地页,要求: + +**美学风格:新野兽派(Neubrutalism)** + +**字体:** +- 标题:Space Grotesk,字重 700-900 +- 正文:IBM Plex Sans,字重 400 + +**颜色:** +- 主色:#000000(纯黑) +- 强调色:#FF6B00(橙色) +- 背景:#FFFDF0(米白色) +- 边框:3px 黑色实线 + +**布局:** +- 不对称布局,元素之间用粗黑线分隔 +- 卡片有硬阴影(box-shadow: 8px 8px 0px #000) +- 大胆的留白对比 + +**动画:** +- 页面加载时元素从下方弹入 +- hover 时按钮向上移动 2px + +**细节:** +- 圆角全部用 0px(直角) +- 按钮有强烈的 3D 效果 +- 背景添加微妙的噪点纹理 +``` + +同样的需求,第二个提示词能让 AI 生成一个风格鲜明、令人印象深刻的页面。 + +### 2.3 前端美化 Skills 资源库 + +不要从零开始写提示词!这里收集了与前端美化直接相关的 AI Skills: + +| 仓库名 | 内容 | Star | 链接 | +|:---|:---|:---|:---| +| **ui-ux-pro-max-skill** | 57种风格 + 95种配色 + 56种字体 | 10k+ | [GitHub](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) | +| **antigravity-awesome-skills** | 避免通用 AI 审美套路 | - | [GitHub](https://github.com/sickn33/antigravity-awesome-skills) | +| **superdesigndev/superdesign** | AI 原生 UI 开发工具 | 4.7k | [GitHub](https://github.com/superdesigndev/superdesign) | +| **anthropics/skills/frontend-design** | Anthropic 官方前端设计 Skill | - | [GitHub](https://github.com/anthropics/skills) | + +> 💡 更多风格提示词请参考[附录:设计风格提示词速查](#style-prompts) + +### 2.5 三款常用风格模板 + +这里给你三款经过验证的风格模板,直接复制修改使用: + +#### 模板 1:极简主义 + +``` +**美学风格:极简主义** + +**字体:** +- 标题:PP Neue Montreal,字重 500-700 +- 正文:Inter,字重 400 + +**颜色:** +- 主色:#FFFFFF(白色) +- 文字:#1A1A1A(近黑) +- 强调:#3B82F6(蓝色,少量使用) + +**布局:** +- 大量留白(padding 最小 64px) +- 单栏或双栏布局,居中对齐 +- 元素之间用留白而非分割线 + +**动画:** +- 缓慢的淡入效果(duration 600ms) +- hover 时颜色渐变过渡 + +**细节:** +- 圆角:8px +- 阴影:subtle(0 4px 12px rgba(0,0,0,0.08)) +- 无背景装饰 +``` + +#### 模板 2:玻璃拟态 + +``` +**美学风格:Glassmorphism(玻璃拟态)** + +**字体:** +- 标题:Outfit,字重 600-800 +- 正文:Plus Jakarta Sans,字重 400-500 + +**颜色:** +- 背景:渐变 #667eea 到 #764ba2 +- 卡片背景:rgba(255, 255, 255, 0.1) +- 文字:#FFFFFF + +**布局:** +- 浮动卡片设计 +- 卡片之间有重叠 + +**动画:** +- 页面加载时卡片依次浮现(staggered) +- hover 时卡片放大 1.05 倍 + +**细节:** +- 圆角:20px +- 背景模糊:backdrop-blur-xl +- 边框:1px rgba(255, 255, 255, 0.2) +- 微妙的渐变光晕效果 +``` + +#### 模板 3:Bento Grid(便当盒) + +``` +**美学风格:Bento Grid** + +**字体:** +- 标题:SF Pro Display,字重 700 +- 正文:SF Pro Text,字重 400 + +**颜色:** +- 背景:#F5F5F7(浅灰) +- 卡片:#FFFFFF(白色) +- 强调:#0071E3(苹果蓝) + +**布局:** +- 网格布局,不同大小的卡片拼在一起 +- 卡片之间 gap 16px +- 圆角 24px + +**动画:** +- hover 时卡片轻微上浮 +- 点击时有按压效果 + +**细节:** +- 大卡片展示重要内容 +- 小卡片展示次要信息 +- 用图标代替部分文字 +- 干净的阴影(0 4px 24px rgba(0,0,0,0.06)) +``` + +## 3. 方法二:用 Skills 插件自动加载设计规范 + +每次手动写风格提示词很麻烦。**Skills** 是一种可复用的设计规范包,安装后 AI 会自动应用这些规范。 + +### 3.1 三个让界面变漂亮的 Skills + +| Skills | 特点 | 安装命令 | +| :--- | :--- | :--- | +| **UI/UX Pro Max** | 67 种风格、96 种配色、57 种字体组合 | `npm install -g uipro-cli && uipro init --ai claude` | +| **frontend-design** | Anthropic 官方,避免 AI 审美套路 | `npx skills add anthropics/skills/frontend-design` | +| **SuperDesign** | IDE 插件,生成多个设计变体 | VSCode 扩展市场搜索 "SuperDesign" | + +### 3.2 安装 UI/UX Pro Max(最推荐) + +UI/UX Pro Max 是目前最全面的设计规范 Skills,它预置了: + +- **67 种 UI 风格**:Glassmorphism、Neumorphism、Brutalism、Bento Grid... +- **96 种配色方案**:按行业分类(SaaS、电商、社交...) +- **57 种字体搭配**:专业设计师验证的组合 +- **100+ 条设计规则**:间距、圆角、阴影的规范 + +**安装步骤:** + +```bash +# 1. 全局安装 CLI +npm install -g uipro-cli + +# 2. 初始化(选择你用的 AI 工具) +uipro init --ai claude +# 或者 +uipro init --ai cursor +# 或者 +uipro init --ai trae +``` + +安装后,你只需要在提示词中加一句话: + +``` +使用 UI/UX Pro Max 的 Glassmorphism 风格,帮我做一个 AI 写作助手落地页 +``` + +AI 就会自动应用对应的字体、颜色、布局规范。 + +### 3.3 安装 Anthropic 官方 frontend-design + +这是 Anthropic 官方出品的前端设计 Skill,专门解决"AI 审美套路"问题: + +```bash +# 在 Claude Code 中执行 +npx skills add anthropics/skills/frontend-design +``` + +安装后,AI 会自动避免: +- ❌ Inter、Roboto、Arial 字体 +- ❌ 紫色渐变背景 +- ❌ 对称网格布局 +- ❌ 过淡的阴影 + +而是倾向于: +- ✅ 独特的字体组合 +- ✅ 大胆的主色 + 锐利的点缀色 +- ✅ 不对称、重叠的布局 +- ✅ 有质感的背景(噪点、几何图案) + +## 4. 实战一:用美化提示词重新设计落地页 + +让我们用前面学到的知识,把一个普通的落地页变得好看。 + +### 4.1 普通版本 + +先用普通提示词看看 AI 给什么: + +``` +请帮我做一个宠物领养平台的落地页,包含: +- 导航栏(Logo、链接、注册按钮) +- 首屏(标题、副标题、CTA 按钮、宠物图片) +- 宠物展示(三张宠物卡片) +- 关于我们 +- 页脚 +``` + +生成的页面...能用,但很普通。 + +### 4.2 美化版本 + +现在加上风格描述: + +``` +请帮我做一个宠物领养平台的落地页,要求: + +**美学风格:温暖柔和 + 手绘感** + +**字体:** +- 标题:Nunito(圆体),字重 700-800 +- 正文:Nunito,字重 400-600 + +**颜色:** +- 主色:#FFB347(暖橙色) +- 次色:#FFCCB3(浅橙色) +- 背景:#FFF8F0(米白色) +- 文字:#5D4037(棕色) + +**布局:** +- 圆润的卡片(border-radius: 24px) +- 卡片略微倾斜旋转(不同角度) +- 元素浮动、重叠效果 + +**动画:** +- 页面加载时元素从两侧滑入 +- 宠物卡片 hover 时像宠物摇头(rotate 动画) +- 按钮 hover 时弹跳效果 + +**细节:** +- 所有圆角用 16-24px +- 阴影温暖柔和(0 8px 24px rgba(255,179,71,0.3)) +- 背景添加爪印图案装饰 +- 图片用不规则裁切(clip-path) +- 手绘风格的图标(outline 风格) +``` + +生成的页面会是一个温暖、可爱、让人想领养宠物的界面。 + +## 5. 实战二:用 Skills 快速生成仪表盘 + +Skills 特别适合需要大量页面的后台系统。 + +### 5.1 使用 UI/UX Pro Max + +``` +使用 UI/UX Pro Max 的 Dashboard Dark 风格, +帮我做一个 SaaS 产品管理后台的仪表盘页面,包含: + +**顶部:** 四个统计卡片(用户数、活跃用户、收入、API 调用) + +**中间:** +- 左边:用户增长折线图(最近 7 天) +- 右边:订阅计划分布饼图 + +**底部:** 最近活动列表(时间、用户、操作) +``` + +AI 会自动应用深色仪表盘的设计规范: +- 深灰背景(#1A1A2E) +- 高对比度卡片(#16213E) +- 鲜艳的数据颜色(蓝色、绿色、橙色) +- 玻璃拟态效果的悬浮卡片 + +### 5.2 使用 frontend-design Skill + +``` +使用 frontend-design skill, +帮我做一个个人博客的主页,风格要独特、有个性 +``` + +AI 会选择一个非主流的美学方向(比如复古未来主义或杂志风格),然后用独特的字体、配色、布局来实现。 + +## 6. 实战三:创建自己的设计系统 Skill + +如果你有固定的品牌风格,可以创建自己的 Skill,让所有 AI 生成的页面都符合你的品牌。 + +### 6.1 创建 Skill 文件 + +在项目中创建 `.claude/skills/my-brand/SKILL.md`: + +````markdown +--- +name: my-brand +description: 我的项目专用设计系统,确保所有 UI 遵循统一的设计语言 +--- + +# 我的项目设计系统 + +## 品牌颜色 +- 主色:#6366F1(Indigo 500) +- 次色:#8B5CF6(Violet 500) +- 成功:#10B981 +- 警告:#F59E0B +- 错误:#EF4444 +- 背景:#F9FAFB +- 卡片:#FFFFFF + +## 字体系统 +- 标题:Plus Jakarta Sans + - H1: 700, 48px + - H2: 600, 36px + - H3: 600, 24px +- 正文:Inter + - Body: 400, 16px + - Small: 400, 14px + +## 间距系统 +- 基础单位:4px +- 组件内边距:8px / 12px / 16px +- 区块间距:24px / 32px / 48px +- 页面边距:64px + +## 圆角 +- 按钮:8px +- 卡片:12px +- 输入框:8px +- 模态框:16px + +## 阴影 +- 小:0 1px 3px rgba(0,0,0,0.1) +- 中:0 4px 12px rgba(0,0,0,0.1) +- 大:0 8px 24px rgba(0,0,0,0.12) + +## 动画 +- 过渡时间:150ms / 300ms +- 缓动函数:cubic-bezier(0.4, 0, 0.2, 1) +- hover 效果:轻微放大(scale-105) + +## 禁止使用的样式 +- 不要使用紫色渐变背景 +- 不要使用 Inter 以外的字体 +- 不要使用大于 16px 的圆角 +- 不要使用纯黑(#000000),用 #1F2937 +```` + +### 6.2 使用自己的 Skill + +创建后,你只需要在提示词中说: + +``` +使用 my-brand skill,帮我做一个用户设置页面 +``` + +AI 就会自动应用你定义的所有设计规范。 + +## 7. 小结 + +让 AI 生成漂亮界面有两种方法: + +| 方法 | 优点 | 缺点 | 适用场景 | +| :--- | :--- | :--- | +| **提示词描述** | 灵活、每次可调整 | 需要重复写 | 一次性页面、实验不同风格 | +| **Skills 插件** | 一次安装、持续生效 | 需要安装配置 | 有固定风格要求的项目 | + +**Vibe Coding 工作流建议:** + +1. **探索阶段**:用不同的风格提示词实验,找到你喜欢的美学方向 +2. **确定风格后**:安装对应的 Skill(UI/UX Pro Max 或 frontend-design) +3. **品牌项目**:创建自己的 Skill,统一整个项目的设计语言 + +### 练习 + +选择以下任一场景,用本节课的方法从零完成: + +1. 用风格提示词为你之前做的一个项目重新设计界面(选一种你喜欢的风格) +2. 安装 UI/UX Pro Max,用它的某个风格生成一个新页面 +3. 创建你自己的设计系统 Skill,定义你的品牌颜色和字体 + +--- + +## 附录:设计风格速查表 + +| 风格 | 关键词 | 适用场景 | 示例产品 | +| :--- | :--- | :--- | :--- | +| **极简主义** | 留白、单色、简洁 | 高端产品、个人作品集 | Apple官网 | +| **玻璃拟态** | 毛玻璃、渐变、模糊 | 科技产品、SaaS 落地页 | macOS Big Sur | +| **新野兽派** | 粗边框、硬阴影、纯色 | 潮流品牌、艺术类网站 | Brassius | +| **Bento Grid** | 网格、拼贴、卡片 | 信息展示、仪表盘 | Apple 宣传页 | +| **复古未来** | 霓虹、渐变、合成器波 | 游戏类、音乐类 | STRANGER THINGS | +| **手绘风格** | 不规则、圆润、插画 | 教育类、儿童产品 | Duolingo | +| **杂志风** | 大字体、不对称、留白 | 内容型网站、博客 | Medium | +| **暗色奢华** | 深色、金色、精致 | 高端产品、奢侈品 | 各种高端品牌 | + +## 附录:Skills 安装速查 + +```bash +# UI/UX Pro Max +npm install -g uipro-cli +uipro init --ai claude + +# Anthropic frontend-design +npx skills add anthropics/skills/frontend-design + +# Anthropic brand-guidelines +npx skills add anthropics/skills/brand-guidelines + +# 查看 Claude Code 中已安装的 Skills +/help +``` + +## 附录:配色方案推荐 + +| 配色方案 | 主色 | 点缀色 | 背景 | 风格 | +| :--- | :--- | :--- | :--- | :--- | +| **日落** | #F97316 | #FBBF24 | #FFF7ED | 温暖、活力 | +| **海洋** | #0EA5E9 | #06B6D4 | #F0F9FF | 清新、专业 | +| **森林** | #10B981 | #34D399 | #ECFDF5 | 自然、健康 | +| **浆果** | #8B5CF6 | #EC4899 | #FAF5FF | 浪漫、创意 | +| **咖啡** | #78350F | #D97706 | #FFFBEB | 温暖、复古 | +| **单石** | #6B7280 | #9CA3AF | #F9FAFB | 专业、中性 | + +## 附录:设计风格提示词速查 {#style-prompts} + +让前端页面更好看可以尝试的提示词: + +### 风格类别 + +| 风格 | 关键词(英文) | 核心视觉特征 | 提示词示例 | +|:---|:---|:---|:---| +| **波普艺术** | Pop Art | 大胆的撞色、黑色轮廓线、网点纹理 | Pop art style website, bold colors and comic dots, vibrant | +| **极简主义** | Minimalism | 大量留白、极少色彩与线条、无装饰 | Minimalist web design, ample white space, geometric, serene | +| **抽象表现主义** | Abstract Expressionism | 充满情感张力的笔触、泼洒色彩 | Abstract expressionism background, dynamic paint splashes, emotional | +| **复古风格** | Retro/Vintage | 旧式字体、做旧纹理、复古配色 | Retro 80s website design, neon grid and synthwave color palette | +| **赛博朋克** | Cyberpunk | 高对比霓虹色、故障艺术效果、暗黑背景 | Cyberpunk UI, neon lights on dark background, glitch effects | +| **新拟态** | Neumorphism | 柔和的阴影与高光,轻微凸起/凹陷质感 | Neumorphism design style, soft shadows, clean and modern | +| **生成式艺术** | Generative Art | 算法生成的流动的视觉图案 | Generative art background, flowing algorithmic patterns, digital | +| **酸性设计** | Acid Graphics | 金属质感、玻璃态、锯齿字体 | Acid graphics web layout, glass morphism, chaotic typography | +| **沉浸式3D** | Immersive 3D | 互动3D场景、空间感极强 | Immersive 3D website, interactive product model in space | diff --git a/docs/ko-kr/stage-2/frontend/lovart-assets/index.md b/docs/ko-kr/stage-2/frontend/lovart-assets/index.md new file mode 100644 index 0000000..40f7b4a --- /dev/null +++ b/docs/ko-kr/stage-2/frontend/lovart-assets/index.md @@ -0,0 +1,949 @@ + + +# 从 NanoBanana 出发,搭建自己的素材生产Agent + +## 第 1 章:1 分钟生成第一份图片素材 + +在开始讨论设计、风格或提示词之前,我们先用最少的步骤生成第一张图片。 + +### 1.1 认识 NanoBanana + +在开始讨论设计风格、提示词工程之前,我们先解决一件更重要的事:**确认你真的可以生成一张图片。** + +当前主流的大模型已经具备图像生成与编辑能力,这类模型通常被称为**生成式模型。** + +为了把流程尽量简化,本教程选择了一个已经具备稳定图像生成与编辑能力的模型作为示例——NanoBanana。它是 Google 推出的图像生成模型,正式名称为 **Gemini 3.1 Flash Image Preview** ,支持通过自然语言直接生成图片,也支持在已有图片基础上进行修改。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image1.png) + +在能力层面,它和你可能听说过的其他模型(如 GPT-4o、Claude、Qwen、Midjourney 等)并没有本质区别:**输入描述,模型负责生成结果。** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image2.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image3.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image4.png) + +你可以把它理解为一支“画笔”。我们在这一章只关心一件事: + 👉 **这支画笔能不能在你手里画出第一笔。** + +在实际使用中,NanoBanana 可以通过 **Google AI Studio** 等官方平台直接使用,也可以通过 **API** 的方式集成到开发流程中。本教程采用 API 调用方式。现在还推出了NanoBanana 2模型,你可以使用最新的大模型进行尝试。 + +### 1.2 “Hello World” 级别的生成 + +在开始之前,你只需要完成下面三步: + +1. 在 Trae 中新建一个文件夹 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image5.png) + +2. 新建一个 Python 文件 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image6.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image7.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image8.png) + +3. 将下面的代码完整粘贴进去 + +Trae 会自动完成所需的环境部署与依赖安装,不需要额外配置。 + +代码中会用到 NanoBanana 的 API Key。这里不展开申请流程——只要你能获取并填入对应参数即可。**这一阶段不追求理解每一行代码,只要它能成功运行。** + +```Python +# /// script +# dependencies = [ +# "gradio>=4.0.0", +# "pillow>=10.0.0", +# "requests>=2.31.0", +# ] +# /// + +import gradio as gr +import requests +import base64 +from PIL import Image +import io +import os +import time +import re +from typing import Optional, Dict, Any, List + +# 配置 API 信息 +NANOBANANA_API_URL: str = "YOUR API URL" +NANOBANANA_API_KEY: str = "YOUR API KEY" +OUTPUT_DIR: str = "outputs" + +# 确保输出目录存在 +os.makedirs(OUTPUT_DIR, exist_ok=True) + +def image_to_base64_data_uri(image: Image.Image) -> str: + """ + 将 PIL 图像转换为 OpenAI API 兼容的 data URI 格式。 + """ + buffer = io.BytesIO() + # 统一转为 PNG 以保证兼容性 + image.save(buffer, format="PNG") + encoded = base64.b64encode(buffer.getvalue()).decode('utf-8') + return f"data:image/png;base64,{encoded}" + +def base64_to_image(base64_str: str) -> Optional[Image.Image]: + """ + 将纯 base64 字符串转换为 PIL Image。 + """ + try: + image_bytes = base64.b64decode(base64_str) + return Image.open(io.BytesIO(image_bytes)) + except Exception as e: + print(f"Base64 解码失败: {e}") + return None + +def extract_base64_from_response(content: Any) -> Optional[str]: + """ + 核心解析逻辑:从 API 返回的 content 中提取图片 Base64 数据。 + 兼容 Markdown 格式和结构化列表格式。 + """ + if not content: + return None + + base64_data = None + + # 1. 尝试结构化提取 (List) + # 对应返回格式: [{"type": "image_url", "image_url": {"url": "data:..."}}] + if isinstance(content, list): + for part in reversed(content): # 倒序查找,通常最新的图片在最后 + if isinstance(part, dict): + # 检查 image_url 或 output_image 字段 + img_field = part.get("image_url") or part.get("image") or part.get("output_image") + if isinstance(img_field, dict): + url = img_field.get("url", "") + if url.startswith("data:image/") and "," in url: + return url.split(",", 1)[1].strip() + + # 如果列表中没有结构化图片,尝试把列表里的文本拼起来找 Markdown + text_parts = [ + str(p.get("text", "")) + for p in content + if isinstance(p, dict) and p.get("type") in ["text", "input_text"] + ] + content_str = "".join(text_parts) + else: + content_str = str(content) + + # 2. 尝试 Markdown 正则提取 (String) + # 对应返回格式: "Here is your image: ![img](data:image/png;base64,AAAA...)" + pattern = re.compile(r"!\[.*?\]\((data:image/[^;]+;base64,[^)]+)\)", re.IGNORECASE) + match = pattern.search(content_str) + + if match: + data_url = match.group(1) + if "," in data_url: + return data_url.split(",", 1)[1].strip() + + return None + +def synthesize(prompt: str, input_image: Optional[Image.Image]) -> Optional[Image.Image]: + """ + 调用 Nanobanana API 进行生成。 + """ + if not prompt or not prompt.strip(): + gr.Warning("请输入提示词") + return None + + print(f">>> 开始任务: {prompt[:50]}...") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {NANOBANANA_API_KEY}" + } + + # 构造符合 OpenAI Vision / Chat 标准的 payload + messages = [] + + if input_image is not None: + # 图生图/多模态输入模式 + print(">>> 检测到输入图片,使用多模态模式") + img_base64 = image_to_base64_data_uri(input_image) + messages.append({ + "role": "user", + "content": [ + {"type": "text", "text": prompt}, + {"type": "image_url", "image_url": {"url": img_base64}} + ] + }) + else: + # 纯文生图模式 + messages.append({ + "role": "user", + "content": prompt + }) + + payload = { + "messages": messages, + # 使用第一段代码中验证可用的模型 + "model": "gemini-2.5-flash-image", + # 可选参数,视 API 支持情况而定 + "stream": False + } + + try: + # 增加超时时间,图片生成通常较慢 + response = requests.post(NANOBANANA_API_URL, headers=headers, json=payload, timeout=120) + + # 检查 HTTP 状态 + if response.status_code != 200: + error_msg = f"API 请求失败: {response.status_code} - {response.text}" + print(error_msg) + gr.Error(error_msg) + return None + + result = response.json() + # Debug: 打印返回结果的前一部分,方便调试 + print(f"API 原始响应 (截取): {str(result)[:200]}...") + + # 提取 Content + content = None + if "choices" in result and len(result["choices"]) > 0: + content = result["choices"][0].get("message", {}).get("content") + + if not content: + gr.Warning("API 返回结果中没有 content 字段") + return None + + # 使用之前验证过的逻辑提取 Base64 + base64_str = extract_base64_from_response(content) + + if base64_str: + output_image = base64_to_image(base64_str) + if output_image: + return output_image + + # 如果没提取到图片,可能是模型拒绝了或只返回了文本 + text_content = str(content) if not isinstance(content, list) else " ".join([str(x) for x in content]) + gr.Info(f"未生成图片,模型返回文本: {text_content[:100]}...") + return None + + except requests.exceptions.Timeout: + gr.Error("请求超时,请稍后重试") + return None + except Exception as e: + import traceback + traceback.print_exc() + gr.Error(f"发生未知错误: {str(e)}") + return None + +# Gradio 界面配置 +with gr.Blocks(title="Nanobanana Image Generator") as app: + gr.Markdown("# 🍌 Nanobanana Text/Image to Image") + gr.Markdown("基于 Gemini-2.5-Flash-Image 模型,支持文生图与图生图。") + + with gr.Row(): + with gr.Column(): + prompt_input = gr.Textbox( + label="提示词 (Prompt)", + placeholder="例如: A cyberpunk cat holding a neon sign...", + lines=3 + ) + image_input = gr.Image( + label="参考图 (可选,用于图生图)", + type="pil", + height=300 + ) + submit_btn = gr.Button("开始生成", variant="primary") + + with gr.Column(): + image_output = gr.Image(label="生成结果", format="png") + + submit_btn.click( + fn=synthesize, + inputs=[prompt_input, image_input], + outputs=image_output + ) + +if __name__ == "__main__": + app.launch(share=True) +``` + +当 Trae 提示运行成功后,点击它提供的本地链接(通常是 http://127.0.0.1:7860)。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image9.png) + +如果一切正常,你会看到一个已经可以工作的 AI 绘图界面。 + +这个界面看起来很简单,但它已经具备了商业级绘图工具中最核心的两项能力,即文生图和图生图。 + +* **左侧:** **指令区 (** **Input** Zone) —— 你在这里发号施令。 +* **Prompt (提示词框):** 输入你的创意描述(推荐使用英文)。 +* **Input** Image (参考图框): + * **文生图模式:** 保持此处 **为空** 。 + * **图生图模式:** 将本地图片拖入此处,AI 会以它为基础进行创作。 +* **Submit 按钮:** 点击即可发送指令,开始生成。 +* **右侧:展示区 (** **Output** Zone) —— 见证奇迹的地方,生成结果将在此显示。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image10.png) + +现在我们可以尝试生成你的第一张图片了! + +本示例使用的 prompt 如下: + +> **A red apple** + +这是一个刻意简化的示例,不包含任何风格或参数描述。 + +#### 实际流程 + +运行代码后,流程可以概括为三步: + +1. 将文字描述发送给模型 +2. 模型生成对应图片 +3. 图片被保存为本地文件 + +几秒钟后,你会在本地看到生成结果。而模型生成具有随机性,所以相同的prompt会有不同的生成结果,你可以多次生成,选择你心仪的图片。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image11.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image12.png) + +也可以丰富你的提示词,给予它更多的描述和限定。例如以下提示词,得到的图片就会更加特殊一些。 + +```Plain +"A hyper-realistic close-up of a fresh red apple with water droplets on its skin, sitting on a dark rustic wooden table. Cinematic dramatic lighting, rim light, shallow depth of field, bokeh background, 8k resolution, macro photography." +(一个超写实的带水珠的新鲜红苹果特写,放在深色粗糙木桌上。电影级戏剧光效,轮廓光,浅景深,背景虚化,8k分辨率,微距摄影。) +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image13.png) + +在Output Image区域点击下载图片即可保存到本地。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image14.png) + +### 1.3 生图模型常见的素材生成场景 + +在实际工作中,大模型生成图片更多用于 **高效产出设计素材** ,而不是创作单张艺术作品。 + +当你观察一些设计类营销账号的高赞案例时会发现,它们的产出大多集中在两类场景: + +* **文生图(从 0 到 1)** +* **有图参考生图(从 1 到 N)** + +#### 一、文生图:快速获取设计物料 + +这一类场景关注效率。当需要填补设计中的空白(如空状态、头像、配图)时,AI 本质上充当的是一个 **即时生成的图库** 。 + +1. ##### 生成 UI 设计物料 + +* 流行趋势:Dribbble 上常见的毛玻璃、黏土风 3D 图标 +* 常见表现:通透材质、边缘发光、糖果配色的功能或天气图标 + +**示例 Prompt:** + +> A set of 3D weather icons (sun, cloud, rain), glassmorphism style, frosted glass texture, soft pastel gradient colors, soft studio lighting, isometric view, transparent background, 4k. + +(一套 3D 天气图标,毛玻璃风格,磨砂质感,柔和渐变色,影棚光,等轴视图) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image15.png) + +2. ##### 生成 Logo + +* 流行趋势:极简线条、几何组合的科技感 Logo +* 常见表现:黑白配色、负空间设计、品牌感明确 + +**示例 Prompt:** + +> Minimalist vector logo design for a tech brand "Coffee Code", combining a coffee cup with coding brackets < >, flat design, solid black lines, white background, Paul Rand style, svg. + +(极简矢量 Logo,结合咖啡杯与代码符号,扁平设计,纯黑线条) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image16.png) + +3. ##### 生成官网用户图片 + +* 流行趋势:SaaS 官网常用 3D 虚拟头像,用于规避真人版权 +* 常见表现:友好表情、卡通比例、偏 Pixar 或 Memoji 风格 + +**示例 Prompt:** + +> Close-up portrait of a friendly young tech professional, smiling, Memoji 3D style, clay render, bright colors, soft lighting, solid plain background, Pixar character design. + +(友好的年轻科技从业者,3D Memoji 风格,黏土渲染) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image17.png) + +4. ##### 生成文章配图 + +* 流行趋势:科技公司博客中常见的抽象扁平插画 +* 常见表现:紫蓝配色、夸张人物比例、漂浮 UI 元素 + +**示例 Prompt:** + +> Editorial flat illustration representing remote work, a person sitting on a giant globe using a laptop, corporate memphis art style, vibrant colors (purple and teal), vector texture. + +(远程办公主题扁平插画,企业孟菲斯风格) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image18.png) + +#### 二、有图参考生图:保持视觉一致性 + +这一类场景更关注 **扩展性** 。当你已经有一张满意的主视觉,需要生成一整套风格一致的素材时使用。 + +5. ##### 主视觉相似的一套按钮或交互素材图 + +在游戏开发中,UI 的一致性非常关键。假设你已经有了主界面的 **“PLAY”** 按钮,现在需要扩展出一整套风格统一的功能按钮(如暂停、设置、主页)。仅靠手绘很难保证每个按钮在光泽、透视和色值上的完全一致。 + +**基本操作流程:** + +1. 保存已有的蓝色 “PLAY” 按钮图片 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image19.png) + +2. 将其拖入界面的 **Input**** Image** 区域,作为后续生成的参考母版 +3. 保持 prompt 中的风格描述不变,仅修改主体内容 + +在这一流程下,只要替换主体描述,就可以得到不同功能但风格一致的按钮。 + +**示例 Prompt:** + +**变体 A:暂停按钮(图标类)** + +> A capsule-shaped game UI button with a white pause icon (two vertical bars) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(胶囊形游戏 UI 按钮,白色暂停图标,蓝色果冻质感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image20.png) + +**变体 B:设置按钮(复杂图标)** + +> A capsule-shaped game UI button with a white gear icon (settings symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(胶囊形游戏 UI 按钮,白色齿轮图标,蓝色果冻质感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image21.png) + +**变体 C:重玩按钮(形状变化)** + +如果需要调整按钮外形,可以在 prompt 中直接描述形状,模型会在保留材质特征的同时尝试改变结构。 + +> A round game UI button with a white circular arrow icon (replay symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(圆形游戏 UI 按钮,循环箭头图标,蓝色果冻质感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image22.png) + +通过这一组操作,你不仅可以替换按钮功能和图标,甚至改变按钮形状,但所有生成结果在材质、配色和光影上仍保持高度一致。这正是大模型在设计素材裂变场景中的核心价值。 + +## 第 2 章:更听话的图像生成助手 —— 以 Lovart 为例 + +在第一部分,我们通过代码直接调用 NanoBanana,体验了“输入即生成”的基础流程。这种方式在需求简单时没有问题。但当生成任务开始包含更多约束,例如: + +* 需要多张风格一致的图片 +* 需要在已有结果上反复调整 +* 需要根据用户输入动态修改生成方向 + +单次调用的方式就会逐渐变得不够用。 + +这时,就需要引入 **AI Agent(** **智能体** **)** 。本节以 **Lovart** 为例,展示当图像生成模型具备“思考层”后,整体工作流会发生怎样的变化。注意!这里不是打广告,只是帮助大家快速get到AI Agent的便捷性~ + +### 2.0 初识 Lovart:你的 AI 设计代理 + +Lovart 是一个基于 Agent 的设计工具 Web。相比普通生图工具,它在生成之前多了一层“思考与规划”。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image23.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image24.png) + +进入 Lovart 后,主要需要了解以下几个控制项: + +#### 模型选择 + +点击输入框下方的立方体图标,可以查看当前可用的生成模型(如 GPT Image、Flux 等)。 + +为了与前文示例保持一致,本节仍然使用 NanoBanana 作为底层生成模型。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image25.png) + +#### 思考模式 + +这是 Lovart 的核心开关: + +* **Fast Mode(⚡)** :接近原生 API,响应快,适合单张、明确指令的生成 +* **Thinking Mode(💡)** :Agent 模式,AI 会先拆解需求、改写 prompt,再执行生成 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image26.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image27.png) + +#### 联网能力 + +开启地球图标后,Agent 可以在生成过程中检索网络信息(例如设计趋势、配色风格),作为辅助输入。 + +### 2.1 为什么原生 API 还不够? + +即使已经可以通过 Python 生成质量不错的图片,原生 API 在复杂任务中仍然存在限制。关键原因在于:原生 API 本质上是指令式的。当你要求它生成一个具体对象时,它可以直接执行;但当输入变成“策划一套完整的游戏素材”时,它并不会主动将目标拆解为多个可执行步骤。 + +Lovart 的核心差异在于 Agent 机制。在用户输入与图像生成模型之间,它加入了一层用于理解和规划的逻辑:先识别用户意图,再拆解任务、重写 prompt,最后才执行生成。 + +### 2.2 实战演示:5 分钟打造一套 IP 表情包 + +以 **“制作一套程序员鸭子 ****IP**** 表情包”** 为例,看看 Agent 是如何参与整个流程的。 + +#### 环节一:策划(Agent 的思考能力) + +**原生 ****API**** 的问题:** +你需要自己思考角色设定、情绪状态,并为每一张图单独编写 prompt。 + +**Lovart 的做法:** + +1. 点亮 💡 **Thinking Mode** +2. 输入一句指令: + +> 设计一套程序员鸭子的 IP 表情包,风格要扁平化、可爱 + +AI 不会立即画图,而是先去网络上搜索相关的程序员鸭子的设计图。输出一份拆解后的方案,自动生成 Debug、Coffee Break、Panic 等场景,并对应生成多条视觉描述。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image28.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image29.png) + +这一步,AI 从“执行者”转变为“策划者”。在AI帮你分析完需求后,可以在Lovart的画布区看到多种风格和内容的程序员鸭子图片。可以开始筛选你喜欢的风格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image30.png) + +#### 环节二:一致性(基于参考的视觉锚定) + +Lovart 中的图片不仅是结果,也参与后续生成。 + +##### 完整参考图 + +* 从草图中选出一张最满意的“标准鸭子”,在画布区点击对应图片 +* 该图将会自动出现在对话区,作为 Reference + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image31.png) + +* 输入新的动作(如开心)并生成 + +生成结果会继承母版的配色、比例和细节。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image32.png) + +##### 局部参考 / 多图整合 + +除了整张图片作为参考,Lovart 还支持: + +* **只选取图片的局部区域** (例如只参考帽子或表情) + +点击画布区左侧tab栏,选择「Mark」键,在目标图像的局部区域标记即可,这部分内容会自动同步到对话框。比如在这里我们可以选择修改背景的颜色。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image33.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image34.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image35.png) + +能看到新生成的图片只改变了背景的颜色,这也跟我们输入的要求一致。 + +* **从多张图片中分别引用子元素** ,再组合生成新结果 + +例如:你可以保留 A 图的角色主体,同时只替换帽子为 B 图中的样式,Agent 会在后台自动整合这些视觉约束。 + +以程序员鸭子为例,我们可以选择保留第一个图中的鸭子形象,并将其替换到第二张图中作为主体元素。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image36.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image37.png) + +最后的效果也非常显著。你也可以试着其他的组合! + +#### 环节三:落地(Agent 的工具调用) + +生成完成后,可以直接执行:放大、移除背景、擦除等操作 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image38.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image39.png) + +这些并不是简单滤镜,而是 Agent 自动调度不同工具完成的结果。 + +而在确定完基调风格后,可以很快速的生成一系列的表情包图像。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image40.png) + +最终我们得到的是可直接交付的生产级素材,而不仅是一张展示图。 + +### 2.3 使用与收费方式说明 + +Lovart 采用订阅制收费模式,不同套餐对应不同的使用额度与功能权限,具体以官网展示为准。 + +本教程不对任何套餐做推荐或比较;如果在实际使用中有需求,可以根据个人情况选择付费升级。 +目前支持通过**支付宝**等方式完成支付。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image41.png) + +#### 小结 + +Lovart 并不是替代底层模型,而是通过 Agent 机制,让图像生成从“单次执行”升级为“连续工作流”。 + +当任务开始涉及策划、一致性和交付时,这类工具的优势会变得非常明显。 + +## 第 3 章:自己动手做一个智能绘图助手 + +除了直接使用 Lovart,我们也可以自己实现一个简化版的绘图助手。 + +本章以“文章自动配图”为例,从实际问题出发,逐步搭建一个带有思考能力的 Agent。 + +### 3.1 痛点引入:为什么直接发文章给画图模型没用? + +直接将一篇较长的文章输入给 NanoBanana 并要求配图,通常很难得到理想结果。原因并不在于模型“画得不行”,而在于 **它并不擅长理解长文本** 。 + +图像生成模型更适合处理简短、明确的视觉描述,而当输入变成一段包含结构、重点和上下文关系的文章时,模型无法判断哪些内容才是画面中真正需要表达的部分。这往往会导致生成结果偏离主题,或只能捕捉到零散细节,缺乏整体概括能力。 + +本质上,图像模型只有“执行”的能力,却缺少对文本进行分析和取舍的过程。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image42.png) + +### 3.2 解决思路:用 Agent 把「理解」和「执行」拆开 + +要解决这个问题,关键并不是更复杂的提示词,而是 **在绘图之前先把事情想清楚** 。因此,我们在生成流程中引入一个独立的「思考层」,并以此构建一个最简单可用的 Agent。 + +这个 Agent 的核心目标只有一个:**让最终生成的图片,尽可能贴近用户真正的表达意图。** + +整体流程可以概括为:**长文本输入 → 语言模型理解与判断 → 生成合适的视觉提示词 → 图像模型执行生成 → 输出图片** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image43.png) + +那我们构建的 Agent 怎样才能明白用户的意图呢? + +这里选择做一个简化的 **“思考层”** ,我们设置了三种不同的意图:无效输入、直接生图、需要理解的长文本。 + +在这个 Agent 中,各个角色的分工可以概括为四点: + +1. **语言模型作为决策核心** + 它负责理解文章内容、判断用户输入的意图,并将任务分发到合适的生成路径中,决定接下来“该怎么做”以及如何生成生图提示词。 +2. **图像模型作为执行者** + 图像模型不参与理解与判断,只接收已经整理好的视觉指令,专注完成图像渲染。 +3. **用户作为可介入的引导者** + 除了直接输入文本,用户还可以在过程中手动调整生成的提示词,或加入参考图来辅助生成,从而对最终结果进行引导和微调。 +4. **Gradio 与后端 ****API**** 作为整体承载层** + 它们负责将界面、模型调用和结果展示串联起来,保证整个 Agent 能够以一个完整 Web 应用的形式稳定运行。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image44.png) + +### 3.3 实战准备 :获取API + +看起来是不是很有趣呢!要跑通上述流程,我们只需要准备两类 API。 + +#### 手:NanoBanana API(图像生成) + +直接沿用第 1 章中已经配置好的 API Key 和 API URL,无需额外设置。 + +#### 脑:SiliconFlow API(文本思考) + +我们需要一个大语言模型来承担“思考层”的职责。本教程使用 SiliconFlow 提供的模型服务:[https://cloud.siliconflow.cn](https://cloud.siliconflow.cn/) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image45.png) + + SiliconFlow 提供了兼容 OpenAI API 规范的接口,可以非常方便地在项目中通过标准网络请求进行调用。在这里我们选择的是免费的Qwen2.5-7B-Instruct模型,调用需要的内容都已经写入下面的Prompt。在开始之前,你只需要在官网注册账号并创建一个 API Key。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image46.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image47.png) + + 该 Key 将用于后续的模型调用。 + +### 3.4 搭建Agent : + +本次实验主要使用Trae来帮我们编写代码,本教程选用的是Gemini-3-Pro-Preview模型。总思路是,新建项目后将下述完整 Prompt 复制到对话框并输入,逐步替换 API KEY 后运行代码,完成测试即可。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image48.png) + +#### 环节1️⃣:Gradio Blocks 基础框架与界面布局 + +在这个环节,我们的主要目标是先给整个Agent搭建出一个“外观”,实现前端的页面设计。复制以下Prompt在Trae对话框中实现后,你将会得到一个本地的URL(通常是 http://127.0.0.1:7860 )即可查看界面,并且检验实现效果。 + +```Plain +板块 1:Gradio Blocks 基础框架与界面布局 +1、任务目标 +·基于 Gradio 4.0.0+ 的 Blocks 布局,实现「LLM+Nanobanana 文生图」项目的基础界面,严格遵循固定左右分栏布局,初始化所有 UI 组件并设置正确的初始状态。 + +2、技术栈要求 +·必须使用 Gradio 4.0.0+ 的 Blocks 模式开发,禁止使用 Interface 模式; +·依赖:gradio>=4.0.0,pillow>=10.0.0(仅导入,暂不实现图片处理逻辑); +·代码需是完整可运行的 Python 文件,包含所有必要的导入语句。 + +3、界面布局规则(核心约束,融合实战细节) +·整体布局: +页面标题:LLM 驱动的文生图全流程工具; +固定左右分栏:左侧占 60% 宽度,右侧占 40% 宽度,使用 gr.Row 和 gr.Column 实现比例控制。 +·左侧 60%(提示词生成流程区)组件清单: +input_text:gr.Textbox,标签「输入文本(教程段落 / 绘图指令)」,lines=6,占位符「请输入需要配图的教程文本或直接绘图指令...」; +identify_intent_btn:gr.Button,value="识别意图",初始状态正常可点击; +intent_status:gr.Textbox,标签「意图类型 / 处理状态」,lines=2,interactive=False,初始值「未识别意图」; +system_prompt:gr.Textbox,标签「System Prompt(仅文章配图意图可编辑)」,lines=4,interactive=False,占位符「LLM 生成提示词的约束规则...」; +confirm_prompt_btn:gr.Button,value="确认生成生图提示词",interactive=False(初始禁用防误触); +generation_prompt:gr.Textbox,标签「生图提示词(可编辑)」,lines=3,interactive=True,初始值为空,占位符「生成的英文生图提示词将显示在此,支持手动修改...」。 +·右侧 40%(Nanobanana 生图功能区)组件清单: +ref_image:gr.Image,标签「参考图(可选,图生图)」,type=filepath,height=300,允许上传; +generate_btn:gr.Button,value="生成图片",interactive=False(初始禁用,无提示词不可点击); +result_image:gr.Image,标签「生成结果」,type=pil,height=300,初始为空,interactive=False。 + +4、交互逻辑要求 +·所有组件的 interactive 初始状态严格按上述配置,后续通过函数动态更新; +·按钮禁用状态需直观(置灰),避免用户误操作。 + +5、输出要求 +·生成完整的 Python 代码,仅实现界面布局和组件初始化,不包含任何业务逻辑; +·代码注释清晰,组件命名与实战版一致(input_text/identify_intent_btn 等); +·代码可直接运行,界面结构与描述完全一致。 +``` + +在浏览器打开http://127.0.0.1:7860后可看到Trae已经按照我们的要求生成了以下的网页,跟我们的要求大致相当,可以进行到下一步的生成中了。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image49.png) + +#### 环节2️⃣:LLM 意图识别模块(Siliconflow API) + +在日常使用VLM画图的时候,可能有以下三种常见输入情况: + +1. 无意义内容,比如“你好”、“你今天吃饭了吗”等,无法画出对应的图片。 +2. 文章/长文本,字数较多,比如200字左右的一篇有结构的文章,需要先理解文章的结构与内容,再考虑如何生成能完整概括这段文字的图片。 +3. 直接绘图指令,比如“帮我画一只在洗澡的狗”等,要求已经阐述的非常具体,可以直接生成图片。 + +跟前面一样,复制以下Prompt在Trae对话框中实现,并且补充在前面步骤中获得的API。 + +```Plain +板块 2:LLM 意图识别模块(Siliconflow API) +1、任务目标 +在已实现的 Gradio 界面基础上,为「识别意图」按钮添加点击逻辑,调用 Siliconflow API 完成意图识别,并联动组件状态。 + +2、技术栈要求 +基于 Gradio 4.0.0+ Blocks; +依赖:requests>=2.31.0,openai; +输出完整可运行 Python 文件,包含板块 1 界面 + 本模块逻辑。 + +3、核心业务规则(绝对不可偏离) +·意图分类规则(仅 3 类,严格返回数字 + 描述) +1 = 无意义内容:仅闲聊、寒暄、无关对话,没有任何绘图或配图需求(如 “你好”“今天吃了吗”); +2 = 文章 / 长文本配图需求:用户输入一段完整文章、教程、段落、说明性文字,内容偏叙事 / 说明 / 讲解,隐含需要为这段内容生成配图的意图,不需要用户明确说 “为这段文字配图”; +3 = 直接绘图指令:用户输入简短、明确的画图命令,没有长文本背景,直接要求画某个内容(如 “画一只 Apple 风格的猫”)。 +·LLM 调用约束(融合实战版模板) +接口地址:https://api.siliconflow.cn/v1/chat/completions; +模型:Qwen/Qwen2.5-7B-Instruct; +temperature=0.1; +统一定义代码: +python +运行 +LLM_BASE_URL = "https://api.siliconflow.cn/v1" +LLM_API_KEY = "" # 用户自行替换 +LLM_MODEL = "Qwen/Qwen2.5-7B-Instruct"# 实战验证的意图识别模板(固化到代码中) +INTENT_PROMPT_TEMPLATE = """你需要识别用户输入文本的意图,仅返回以下 3 类结果中的一种(格式:数字 + 中文描述): +1 = 无意义内容;2 = 文章 / 长文本配图需求;3 = 直接绘图指令。 + +用户输入:{user_input} + +识别结果: +仅提取返回结果中的数字和描述,禁止额外内容。""" + +4、组件联动规则 +·结果为 1:intent_status 显示「1 = 无意义内容:无绘图需求」,system_prompt 保持禁用,confirm_prompt_btn 禁用; +·结果为 2:intent_status 显示「2 = 文章 / 长文本配图需求:为输入内容生成配图」,启用 system_prompt 并填充默认规则,激活 confirm_prompt_btn; +·结果为 3:intent_status 显示「3 = 直接绘图指令:根据指令生成图片」,system_prompt 禁用且填充默认规则,激活 confirm_prompt_btn。 + +5、异常处理 +API 异常、解析异常均给出友好提示,不崩溃,组件恢复初始状态。 + +6、输出要求 +生成完整可运行代码,替换 LLM_API_KEY 即可使用,逻辑清晰注释完整,意图识别模板严格使用实战版。 +``` + +刷新之前的http://127.0.0.1:7860网址,开始测试是否能正确检测三种情况。 + +1. 无意义内容,可以尝试输入“你好”、“谢谢”等,发现能够正常识别。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image50.png) + +2. 文章/长文本,在这里我们选用了一段豆包生成的描述人工智能的文字。你也可以尝试使用自己的论文段落进行测试。 + +```Plain +人工智能正在以前所未有的深度和广度重塑教育生态系统。通过自适应学习算法,AI系统能够构建每个学生的认知图谱,实时追踪他们的知识掌握轨迹,并动态调整教学内容的难度和呈现方式。在传统课堂环境中,教师往往难以同时满足不同学习风格和能力水平的学生需求,而基于深度学习的教育平台可以分析学生在交互式模拟实验中的行为模式,识别他们在量子力学或微积分等复杂概念理解上的微妙障碍,并提供精准的认知支架。 + +高级自然语言处理引擎驱动的虚拟导师不仅能够解构开放性问题,如"如何评价法国大革命对现代民主制度的影响",还能引导苏格拉底式对话,激发批判性思维。当学生撰写关于气候变化对极地生态系统影响的论文时,AI写作助手可以分析其论证逻辑的严密性,指出数据引用中的时效性问题,并建议更精准的科学术语。在特殊教育领域,计算机视觉技术使AI能够识别自闭症谱系儿童在社交互动中的非语言线索,调整干预策略,而情感计算算法则帮助检测在线学习时的挫折感,及时提供鼓励性反馈。 + +然而,这种技术融合引发了一系列伦理困境。算法偏见可能无意中边缘化特定文化背景的学生,数据采集的透明度问题引发了对学术隐私的关切,而过度依赖自动化评分系统可能削弱教师对学生思维过程的深层理解。更复杂的是,当AI开始生成高度逼真的虚拟实验室体验时,我们需要重新定义"实践经验"在教育中的价值。未来教育的范式可能演变为人类教师专注于培养创造力、同理心和道德判断力,而AI系统则承担知识传递、技能训练和个性化评估的职能,形成一种协同进化的教育共生体,既能发挥机器的计算优势,又能保留人类教育的独特温度. +``` + +同样检测成功~ + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image51.png) + +3. 直接绘图指令,这里输入的是“我要画一只猫”,同样检测准确。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image52.png) + +到这里我们就已经顺利实现了第二个环节——意图识别。 + +#### 环节3️⃣:生图提示词生成模块(LLM 二次调用) + +意图识别后,对于文章或长文本,还有很重要的一步就是生成画图的提示词,而这正是本Agent的重点。 + +```SQL +板块 3:生图提示词生成模块(LLM 二次调用) +1、任务目标 +在意图识别基础上,实现「确认生成生图提示词」按钮逻辑,调用 LLM 将文本优化为适合绘图的英文视觉提示词,填充到编辑框并联动「生成图片」按钮。 + +2、技术栈要求 +同板块 2,输出完整代码 = 板块 1 + 板块 2 + 本模块; +共用板块 2 定义的 LLM_BASE_URL、LLM_API_KEY、LLM_MODEL,不新增密钥。 + +3、核心业务规则(融合实战版 Prompt 组装逻辑) +·提示词生成输入规则(必须严格遵循) +生图提示词生成不再是简单字符串拼接,而是构建标准 Chat 消息列表,代码结构如下: +python +运行 +messages=[# System角色:网页上用户最终确认/编辑后的system_prompt内容{"role": "system", "content": final_system_prompt},# User角色:承载待处理数据,明确任务目标{"role": "user", "content": f"请为以下内容生成视觉提示词:\n\n{user_input}"}] +意图为 2 时:System 内容取用户编辑后的 system_prompt 最终版本; +意图为 3 时:System 内容取禁用状态下填充的默认规则 +user_input 为用户最初输入到 input_text 框的原始文本。 +·实战验证的 System Prompt 预设(固化到代码中) +python +运行 +SYSTEM_PROMPT_DEFAULT = """你现在是一个创建NanoBanana画图提示词的助手。 +需要根据我的内容处理,我这个图片的作用是能说明这一段在说什么,并且让大家知道这段话的上下结构就是整体说的是什么意思。 +里面可能会类似PPT有一些讲解(如:左上角展示核心观点,右下角展示数据)。 +设计风格要求:简约,Apple设计思维(Apple Design Philosophy)。 +约束:请直接返回NanoBanana可用的英文提示词,不要返回任何解释、前缀或多余的废话。""" +·LLM 调用约束 +与板块 2 共用同一套 LLM_BASE_URL、LLM_API_KEY、LLM_MODEL; +temperature=0.7(保证提示词的创意性与适配性); +max_tokens=200(限制输出长度,匹配提示词约束); +严格使用上述标准 Chat 消息列表结构,禁止字符串拼接。 +·示例输入输出(核心参考) +输入示例 1(文章配图意图):原始文本:「AI 如何改变教育:随着人工智能技术的发展,教师的角色从知识传授者转变为引导者,AI 助手可辅助学生完成个性化学习,课堂上人机协作成为常态。」最终 System Prompt:SYSTEM_PROMPT_DEFAULT(未修改)输出预期:"Minimalist illustration, Apple Design Philosophy, 1024x1024. Top left shows 'AI + Education' core concept, bottom right shows data of teacher-student-AI collaboration, soft color palette, clean lines, no redundant elements." +输入示例 2(直接绘图指令):原始文本:「画一只 Apple 风格的猫,坐在 MacBook 旁边」最终 System Prompt:SYSTEM_PROMPT_DEFAULT(禁用状态)输出预期:"Minimalist cat, Apple style, 1024x1024, sitting next to a silver MacBook, clean white background, soft shadows, geometric shapes, no extra details." +·提示词输出强制约束 +纯英文,无中文; +必须包含 Apple Design Philosophy/Apple style + 1024x1024; +长度 50–200 字符,代码内校验; +无额外解释、前缀或废话,仅返回提示词本身。 + +4、组件联动规则 +生成成功:将提示词填入 generation_prompt 框,激活 generate_btn,intent_status 追加「提示词生成成功,可修改后生成图片」; +生成失败:提示具体原因(如 API 调用失败、长度不达标),generate_btn 保持禁用,generation_prompt 框为空; +用户手动修改 / 清空 generation_prompt 框: +清空时自动禁用 generate_btn; +非空时保持 generate_btn 激活。 + +5、异常处理 +API 调用失败:友好提示「提示词生成失败:{具体错误信息}」,不崩溃; +提示词校验失败:明确提示原因(如 “未包含 Apple style”“长度仅 40 字符”),允许重试; +响应解析失败:提示「无法解析 LLM 返回结果,请重试」。 + +6、输出要求 +完整可运行代码,替换 LLM_API_KEY 即可使用; +代码结构清晰、注释完善,界面美观简洁; +严格实现标准 Chat 消息列表结构,参数与示例逻辑一致; +包含提示词长度、内容校验逻辑,错误提示友好。 +``` + +同样复制第二个环节的文本进行检测。 + +值得注意的是,我们在这里预设的生成生图提示词的System Prompt为: + +> 你现在是一个创建NanoBanana画图提示词的助手。 +> 需要根据我的内容处理,我这个图片的作用是能说明这一段在说什么,并且让大家知道这段话的上下结构就是整体说的是什么意思。 +> 里面可能会类似PPT有一些讲解(如:左上角展示核心观点,右下角展示数据)。 +> 设计风格要求:简约,Apple设计思维(Apple Design Philosophy)。 +> 约束:请直接返回NanoBanana可用的英文提示词,不要返回任何解释、前缀或多余的废话。 + +如果你想换成其他的预设模版,可以在前面的prompt里修改,或者直接在Trae里通过对话修改。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image53.png) + +除了修改底层代码,我们在网页上也可以快速编辑。举个例子,我在这里加了一句,“在前面加一句Pic Prompt”,可以看到生成的新的提示词前面也包含了~这样设计是为了方便快速修改生成提示词的System Prompt,帮助我们快速切换风格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image54.png) + +#### 环节4️⃣:Nanobanana 文生图 / 图生图模块 + +终于来到了最后一步,不接入生图模型,就不是一个完整的Agent! + +```Bash +板块 4:Nanobanana 文生图 / 图生图模块(最终版) +1、任务目标 +实现「生成图片」按钮逻辑,调用真实 Nanobanana API,支持文生图 / 图生图,解析 Base64 并展示图片。 + +2、技术栈要求 +基于 Gradio 4.0.0+ Blocks; +依赖:requests, pillow, base64, io, re; +完整代码 = 板块 1+2+3 + 本模块。 + +3、核心 API 配置(实战验证固化) +固化代码配置: +python +运行 +# 固化到代码中的API配置 +NANOBANANA_API_URL = "https://api.zyai.online/v1/chat/completions" +NANOBANANA_MODEL = "gemini-2.5-flash-image" +NANOBANANA_API_KEY = "" # 用户自行替换 +鉴权方式:Header Authorization: Bearer {NANOBANANA_API_KEY}。 + +4、图片预处理要求(必须实现)实现函数 image_to_base64_data_uri (ref_image_path),核心逻辑: +将 PIL 图片转为 PNG 格式; +自动缩放到 1024x1024 分辨率; +透明通道转为白色背景; +编码为 Base64,返回格式:data:image/png;base64,...。 + +5、请求构建规则(严格按实战版分支逻辑) +·核心函数定义实现函数 generate_image (prompt, ref_image_path): +入参:prompt(generation_prompt 框内容)、ref_image_path(ref_image 上传的文件路径); +返回:PIL Image(展示到 result_image)或错误提示。 +·逻辑分支 1:纯文生图(ref_image_path 为空) +python +运行 +messages = [{"role": "user", "content": prompt}] +·逻辑分支 2:图生图(ref_image_path 有值) +python +运行 +# 先调用图片预处理函数 +image_base64 = image_to_base64_data_uri(ref_image_path) +messages = [{"role": "user","content": [{"type": "text", "text": prompt},{"type": "image_url", "image_url": {"url": image_base64}}]}] + +6、响应解析要求(必须兼容两种格式)从 choices [0].message.content 中提取图片 Base64,支持: +结构化 JSON 返回的 image_url 字段; +Markdown 格式 +; +统一提取 Base64 编码,解码后转换为 PIL Image 返回。 + +7、组件联动与异常处理 +生成成功:将 PIL Image 展示到 result_image,intent_status 提示「图片生成成功」; +生成 / 解析 / 上传失败:在 intent_status 显示清晰文字提示(如 “Base64 解析失败”“API 调用超时”),不崩溃。 + +8、输出要求 +完整可运行代码,替换 LLM_API_KEY 和 NANOBANANA_API_KEY 即可直接运行,全流程可用,分支逻辑严格匹配实战版。 +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image55.png) + +太令人激动啦!我们终于顺利地生成出了这个Agent的第一张图,仔细看看生成的图片,跟我们的文本和提示词是匹配的。到这里你已经基本上实现你自己的Agent啦! + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image56.png) + +我们还添加了图生图功能,上传你喜欢的图片,AI会自动借鉴风格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image57.png) + +值得一提的是,前面步骤生成的提示词也是可以在网页上编辑的,并且我们是以最终点击按钮时的提示词为准~哪怕我在这里换成“a cute cat”,最终生成的图片也只会是可爱的小猫。 + +## 第 4 章:总结 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image58.png) + +**呜呼!终于写完了。** +说实话,连我自己写完最后一行的时候都忍不住长舒一口气,更别说一路跟着做到这里的你了。能把这一整套流程完整跑下来,本身就已经很厉害了,这说明你真的把手放到键盘上,把事情一步步做完了。Bravo 🎉 🥳 👏 + +在写这套内容的过程中,我一直在想,我们到底要留下些什么?答案其实并不是模型名字、参数或者某种固定套路,而是让你慢慢建立起一种感觉:哪些事情可以放心交给 AI 去理解和规划,哪些地方只需要你来决定方向。一旦这层分工成立,很多原本看起来复杂的生成流程,都会开始变得顺起来。 + +回头看,这条路其实并不复杂。想清楚你要解决的问题,把长文本交给语言模型去拆解,再把整理好的视觉意图交给绘图模型去呈现,最后把这一整套流程封装成一个属于你自己的小助手。到这里,你已经不只是“在用模型”,而是在搭建一套可以长期陪你工作的系统,而这,才是这套教程最想带给你的东西。 + +但是你已经做的很棒啦!相信学到这里的你对Vibe Coding已经有初步的掌握了,给自己放个小假休息一下吧! + + diff --git a/docs/ko-kr/stage-2/frontend/modern-component-library/index.md b/docs/ko-kr/stage-2/frontend/modern-component-library/index.md new file mode 100644 index 0000000..8473195 --- /dev/null +++ b/docs/ko-kr/stage-2/frontend/modern-component-library/index.md @@ -0,0 +1,465 @@ +# 使用现代组件库更新你的界面 + +在前面的课程中,你已经学会了如何用设计工具画出界面、用 AI IDE 把设计稿变成代码,甚至完成了一个完整的前端项目。但你可能也发现了一个问题:自己从零写出来的按钮、表单、弹窗,虽然能用,但总觉得和"专业产品"差了点意思——样式不够统一、交互细节不够丝滑、适配不同屏幕也很头疼。 + +这就是**组件库**要解决的问题。 + +组件库是一套预先设计好、开发好的 UI 零件集合。按钮、输入框、下拉菜单、对话框、表格……这些你在任何产品中都会反复用到的界面元素,组件库已经帮你做好了,而且经过了大量用户的验证和打磨。你只需要像搭积木一样把它们组合起来,就能快速构建出专业级的界面。 + +## 你将学到 + +1. 理解什么是前端组件库,以及为什么现代开发几乎都在用它 +2. 认识四个最具代表性的组件库,了解它们各自擅长的场景 +3. 通过三个实战场景(落地页、产品页面、后台管理),学会用 AI IDE + 组件库进行 Vibe Coding +4. 学会阅读组件库文档,根据需求找到合适的组件并正确使用 + +## 1. 为什么需要组件库? + +想象你在装修房子。你可以自己从木头开始做一把椅子,但更常见的做法是去宜家买一把——设计好看、质量稳定、说明书清晰,拿回家组装就行。 + +组件库就是前端开发中的"宜家"。它提供的不是家具,而是界面零件: + +| 自己手写 | 使用组件库 | +| :--- | :--- | +| 需要自己处理样式、交互、动画 | 开箱即用,样式和交互已经打磨好 | +| 不同页面的按钮可能长得不一样 | 全局风格统一,自动保持一致性 | +| 适配手机、平板需要额外工作 | 大多数组件库已内置响应式支持 | +| 无障碍访问(Accessibility)容易遗漏 | 专业组件库已处理好键盘导航、屏幕阅读器等 | +| 开发速度慢 | 开发速度快,专注业务逻辑 | + +简单来说:**组件库让你把时间花在"做什么"上,而不是"怎么画"上。** + +### 眼见为实:同一个需求,加不加组件库的差距 + +光说不练没有说服力。我们在 Trae 中用几乎相同的需求,分别不指定和指定组件库,看看生成结果的差距。 + +**提示词一:不使用组件库** + +```text +请帮我做一个 AI 写作助手的数据仪表盘页面,包含: +- 顶部标题栏和导出按钮 +- 四张统计卡片显示用户数、活跃用户、文档数、收入,还要显示涨跌趋势 +- 一个折线图和一个饼图 +- 用户列表表格,带分页功能 +- 左侧导航侧边栏 +``` + +在 Trae 中直接运行后的效果: + + + + +**提示词二:使用 shadcn/ui 组件库** + +```text +请帮我做一个 AI 写作助手的数据仪表盘页面,用 shadcn/ui 组件库来做,包含: +- 顶部标题栏和导出按钮 +- 四张统计卡片显示用户数、活跃用户、文档数、收入,还要显示涨跌趋势 +- 一个折线图和一个饼图 +- 用户列表表格,带分页功能 +- 左侧导航侧边栏 +``` + +同样在 Trae 中直接运行后的效果: + + + + +同样的需求,唯一的区别只是在提示词开头加上了 `shadcn/ui + Tailwind CSS`,Trae 生成的结果在视觉一致性、交互细节、整体打磨程度上就完全不在一个层级。这就是组件库带来的"免费升级"——你只需要在提示词里多写一个组件库的名字。 + +## 2. 认识四个核心组件库 + +组件库数量众多(完整列表见[附录](#附录-更多组件库一览)),但你只需要先认识这四个最具代表性的: + +| 组件库 | 框架 | 一句话定位 | 官网 | +| :--- | :--- | :--- | :--- | +| [Ant Design](https://ant.design) | React | 蚂蚁集团出品,企业级中后台的事实标准,组件覆盖面极广 | ant.design | +| [shadcn/ui](https://ui.shadcn.com) | React | 不装 npm 包,直接把代码复制到你项目里,基于 Tailwind CSS,定制自由度最高 | ui.shadcn.com | +| [HeroUI](https://heroui.com)(原 NextUI) | React | 默认样式精美、动画流畅,适合对视觉品质有要求的落地页和产品展示 | heroui.com | +| [Material UI](https://mui.com) | React | 最老牌的 React 组件库,实现 Google Material Design 规范,生态最成熟 | mui.com | + +> Vue 用户同样有丰富选择:[Element Plus](https://element-plus.org)(国内最流行)、[Ant Design Vue](https://antdv.com)、[Naive UI](https://www.naiveui.com) 等,详见[附录](#附录-更多组件库一览)。 + +不同组件库擅长不同场景。接下来我们通过三个真实开发场景,带你体验如何用 AI IDE + 组件库进行 Vibe Coding。 + +为了展示不同组件库的风格和特点,我们在每个场景中刻意选用了不同的库。但请注意:**这只是为了让你多见识几种方案**,实际开发中你完全可以只用自己最顺手的那一个。比如你喜欢 shadcn/ui 的风格,用它做落地页、产品页、后台管理都没问题。选一个你觉得好看、用着舒服的,比什么都重要。 + +## 3. 实战一:用 HeroUI 构建产品落地页 + +**场景**:你做了一个 AI 写作助手产品,需要一个漂亮的落地页来展示产品特性、吸引用户注册。落地页需要视觉冲击力强、动画流畅、在手机上也好看。 + +**为什么选 HeroUI**:HeroUI 的默认样式就很精美,自带流畅的过渡动画,非常适合面向用户的展示型页面。 + +### 3.1 创建项目 + +```bash +# 使用 HeroUI 官方 CLI 创建项目 +npx create-heroui-app@latest ai-writer-landing +cd ai-writer-landing +npm install +``` + + + + +### 3.2 用 AI IDE 生成落地页 + +打开 AI IDE(Cursor、Trae 等),在对话框中输入: + +```text +请帮我做一个 AI 写作助手的落地页,用 HeroUI 组件库来做: + +**页面结构:** +1. 顶部导航栏:左边放 Logo 和产品名,右边放"功能"、"定价"、"关于"三个链接,再加一个"开始使用"按钮 +2. 首屏区域:大标题写"让 AI 成为你的写作搭档",副标题介绍产品价值,两个按钮"免费试用"和"查看演示",下面放一张产品截图 +3. 功能展示:三列卡片,分别介绍"智能续写"、"风格调整"、"多语言翻译"三个功能,每张卡片要有图标、标题、描述 +4. 定价区域:三个定价卡片(免费版、专业版、团队版),专业版要突出显示推荐 +5. 底部号召:一句吸引人的文案,加上注册按钮 +6. 页脚:版权信息和社交媒体链接 + +**设计要求:** +- 看起来要现代、专业 +- 支持暗色模式 +- 手机上看也要好看 +``` + + + + +### 3.3 AI 会用到的关键组件 + +AI 生成的代码中,你会看到这些 HeroUI 组件: + +```jsx +import { + Navbar, NavbarBrand, NavbarContent, NavbarItem, + Button, + Card, CardHeader, CardBody, CardFooter, + Divider, + Link, + Chip +} from '@heroui/react' +``` + +每个组件的作用: + +| 组件 | 用途 | 落地页中的位置 | +| :--- | :--- | :--- | +| `Navbar` | 顶部导航栏 | 页面最顶部,固定不动 | +| `Button` | 按钮,支持多种变体和颜色 | CTA 按钮、导航按钮 | +| `Card` | 卡片容器 | 功能展示、定价卡片 | +| `Chip` | 小标签 | "推荐"、"最受欢迎"标记 | +| `Divider` | 分割线 | 区域之间的视觉分隔 | + +### 3.4 迭代优化 + +生成的初版代码可能不完全满意,继续和 AI 对话调整: + +```text +请帮我优化一下落地页: + +1. 大标题加上渐变色,从蓝色渐变到紫色 +2. 功能卡片鼠标放上去要有上浮的动画效果 +3. 专业版定价卡片要突出显示,加个边框和"最受欢迎"的标签 +4. 手机上的导航改成汉堡菜单(三条横线那种) +``` + + + + +> **Vibe Coding 的核心**:你不需要记住每个组件的 API,只需要用自然语言描述你想要的效果,AI 会帮你找到合适的组件和写法。遇到不满意的地方,继续对话迭代就好。 + +## 4. 实战二:用 shadcn/ui 构建产品页面 + +**场景**:你的 AI 写作助手需要一个用户登录后的主界面——左侧是文档列表,右侧是编辑器,顶部有工具栏。这是一个功能型产品页面,需要高度定制化的 UI。 + +**为什么选 shadcn/ui**:shadcn/ui 把组件代码直接放进你的项目,你可以随意修改任何细节。对于需要深度定制的产品界面,这种"拥有代码"的模式最灵活。 + + + + +### 4.1 创建项目 + +```bash +# 创建 Next.js 项目 +npx create-next-app@latest ai-writer-app --typescript --tailwind --app +cd ai-writer-app + +# 初始化 shadcn/ui +npx shadcn@latest init + +# 按需添加组件(不是一次性安装所有组件) +npx shadcn@latest add button card input sidebar sheet dialog +``` + +shadcn/ui 的独特之处:每次 `add` 一个组件,它会把源代码复制到你项目的 `components/ui/` 目录下。你可以直接打开这些文件修改样式和行为。 + +### 4.2 用 AI IDE 生成产品界面 + +```text +请帮我做一个 AI 写作助手的主界面,用 shadcn/ui 组件库来做: + +**整体布局:** +- 左边是可折叠的侧边栏,宽度大概 280px: + - 顶部放"新建文档"按钮 + - 下面是文档列表,每个文档显示标题和最后编辑时间 + - 右键点击文档可以重命名或删除 +- 右边是主编辑区,分成上下两部分: + - 上面是工具栏:可以编辑文档标题、显示字数统计、"AI 续写"按钮、"导出"下拉菜单 + - 下面是编辑区域:一个大的文本输入框,占满剩余空间 + +**交互细节:** +- 点击"AI 续写"后,按钮显示加载状态,编辑器底部出现 AI 生成的文本(像打字机一样逐字显示) +- 手机上侧边栏变成抽屉式,从左边滑出 +- 当前选中的文档要高亮显示 +``` + + + + +### 4.3 AI 会用到的关键组件 + +```tsx +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Card, CardContent, CardHeader } from '@/components/ui/card' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@/components/ui/dropdown-menu' +import { + Sheet, + SheetContent, + SheetTrigger +} from '@/components/ui/sheet' +import { + Sidebar, + SidebarContent, + SidebarHeader +} from '@/components/ui/sidebar' +``` + +| 组件 | 用途 | 产品页面中的位置 | +| :--- | :--- | :--- | +| `Sidebar` | 可折叠侧边栏 | 左侧文档列表 | +| `Sheet` | 移动端抽屉 | 移动端侧边栏替代 | +| `DropdownMenu` | 下拉菜单 | "导出"按钮、右键菜单 | +| `Dialog` | 对话框 | 重命名、删除确认 | +| `Button` | 按钮,支持 variant 和 loading | 各种操作按钮 | +| `Input` | 输入框 | 文档标题编辑 | + +### 4.4 定制组件样式 + +shadcn/ui 的优势在于你可以直接修改组件源码。比如你想让按钮的圆角更大: + +```text +请帮我修改 components/ui/button.tsx, +把所有按钮的默认圆角从 rounded-md 改为 rounded-xl, +并给 primary 变体加上微妙的阴影效果 +``` + +AI 会直接修改你项目中的组件文件,而不是覆盖 npm 包的样式——这就是 shadcn/ui "拥有代码"的好处。 + + + + +## 5. 实战三:用 Ant Design 构建后台管理界面 + +**场景**:你的 AI 写作助手上线后,需要一个管理后台来查看用户数据、管理文档内容、处理付费订单。后台管理系统的核心是数据展示和操作效率。 + +**为什么选 Ant Design**:Ant Design 在中后台领域积累最深,表格、表单、图表等业务组件开箱即用,内置了大量企业级交互模式(批量操作、高级筛选、数据导出等)。 + + + + +### 5.1 创建项目 + +```bash +# 使用 Ant Design Pro 脚手架(内置布局、路由、权限) +npx create-umi@latest ai-writer-admin +# 选择 Ant Design Pro 模板 +cd ai-writer-admin +npm install +``` + +或者从零开始: + +```bash +npx create-react-app ai-writer-admin --template typescript +cd ai-writer-admin +npm install antd @ant-design/icons @ant-design/pro-components +``` + +### 5.2 用 AI IDE 生成管理后台 + +```text +请帮我做一个 AI 写作助手的管理后台,用 Ant Design 组件库来做: + +**整体布局:** +- 左边是菜单栏:仪表盘、用户管理、文档管理、订单管理、系统设置 +- 顶部显示面包屑导航 + +**用户管理页面:** +- 顶部放四个统计卡片:总用户数、今日新增、活跃用户数、付费用户数 +- 搜索筛选区:可以按用户名搜索、选择注册时间范围、筛选用户状态,还有"搜索"和"重置"按钮 +- 用户表格: + - 显示头像、用户名、邮箱、注册时间、订阅计划(用不同颜色标签区分)、状态、操作 + - 每页显示 20 条,支持分页 + - 可以批量选择用户,批量禁用或导出 + - 操作列:查看详情、编辑、禁用(禁用前要二次确认) +- 点击"查看详情"从右侧滑出抽屉,显示用户详细信息和最近文档列表 +``` + + + + +### 5.3 AI 会用到的关键组件 + +```tsx +import { PageContainer, ProLayout } from '@ant-design/pro-components' +import { ProTable } from '@ant-design/pro-components' +import { StatisticCard } from '@ant-design/pro-components' +import { + Button, Tag, Badge, Space, Drawer, + Popconfirm, message, Modal +} from 'antd' +import { + UserOutlined, SearchOutlined, ExportOutlined +} from '@ant-design/icons' +``` + +| 组件 | 用途 | 后台中的位置 | +| :--- | :--- | :--- | +| `ProLayout` | 后台整体布局框架 | 页面骨架(菜单 + 内容区) | +| `ProTable` | 高级表格,内置搜索、分页、列设置 | 用户列表、文档列表、订单列表 | +| `StatisticCard` | 数据统计卡片 | 仪表盘、页面顶部概览 | +| `Tag` / `Badge` | 状态标签 | 订阅计划、用户状态 | +| `Drawer` | 侧边抽屉 | 用户详情、编辑表单 | +| `Popconfirm` | 气泡确认框 | 删除、禁用等危险操作 | + +### 5.4 继续迭代:添加仪表盘 + +```text +请帮我做一个仪表盘页面: + +1. 顶部四个统计卡片:总用户数、总文档数、今日 API 调用次数、月收入,每个卡片显示数值和环比变化(涨了还是跌了) +2. 中间放两个图表: + - 左边:最近 7 天的用户增长折线图 + - 右边:订阅计划分布饼图 +3. 底部:最近操作日志表格,显示时间、用户、操作类型、详情 + +用 Ant Design 的组件来布局,图表可以用 Ant Design Charts +``` + + + + +> **后台管理的 Vibe Coding 技巧**:后台页面结构相对固定(表格 + 搜索 + 弹窗),非常适合用 AI 批量生成。你可以先让 AI 生成一个"用户管理"页面作为模板,然后说"参考用户管理页面的结构,帮我生成文档管理页面",AI 会复用相同的布局模式。 + +## 6. 学会查文档:组件库的"说明书" + +Vibe Coding 中 AI 会帮你写大部分代码,但当 AI 生成的结果不对、或者你想微调某个组件的行为时,**查文档**是最快的解决方式。 + +以 Ant Design 为例,它的文档地址是:`https://ant.design/components/overview-cn` + +查文档的标准流程: + +1. **明确需求**:比如"我需要表格支持行选择" +2. **在文档中搜索**:搜索"Table"进入表格组件页面 +3. **查看示例**:文档中每个组件都有多个在线示例,找到"可选择"示例 +4. **复制代码**:把示例代码复制到你的项目中 +5. **查看 API 表格**:在页面底部找到 `rowSelection` 属性的完整配置项 + +> 你也可以把文档链接直接发给 AI IDE:"请参考 https://ant.design/components/table-cn 的 rowSelection API,帮我给用户表格加上批量选择功能"。给 AI 提供文档链接,生成的代码会更准确。 + +各组件库的文档地址速查: + +| 组件库 | 文档地址 | +| :--- | :--- | +| Ant Design | `https://ant.design/components/overview-cn` | +| shadcn/ui | `https://ui.shadcn.com/docs/components` | +| HeroUI | `https://heroui.com/docs/components` | +| Material UI | `https://mui.com/material-ui/all-components/` | +| Element Plus | `https://element-plus.org/zh-CN/component/overview.html` | + +## 7. 小结 + +三个实战场景覆盖了最常见的前端开发需求: + +| 场景 | 推荐组件库 | 核心特点 | +| :--- | :--- | :--- | +| 落地页 / 展示页 | HeroUI | 默认样式精美,动画流畅,视觉冲击力强 | +| 产品功能页面 | shadcn/ui | 代码完全可控,深度定制灵活 | +| 后台管理系统 | Ant Design | 业务组件丰富,表格表单开箱即用 | + +Vibe Coding 的工作流总结: + +1. 根据场景选择合适的组件库 +2. 用 AI IDE 描述你想要的页面结构和交互 +3. AI 生成初版代码,你预览效果 +4. 用自然语言继续迭代调整 +5. 遇到细节问题时查阅组件库文档 + +### 练习 + +选择以下任一场景,用 AI IDE + 组件库从零完成: + +1. 用 HeroUI 为你之前做的项目(比如霍格沃茨画像)做一个展示落地页 +2. 用 shadcn/ui 构建一个笔记应用的主界面(侧边栏 + 编辑器) +3. 用 Ant Design 构建一个简单的内容管理后台(文章列表 + 新建文章表单) + +--- + +## 附录:更多组件库一览 + +除了正文介绍的四个核心库,前端生态中还有大量优秀的组件库。下面按框架分类列出,方便你根据项目需求选择。 + +### Vue 生态 + +| 组件库 | Stars | 简介 | 适用场景 | +| :--- | :--- | :--- | :--- | +| [Element Plus](https://element-plus.org) | ~27k | 饿了么团队打造的 Vue 3 企业级组件库,国内使用最广泛,中文生态极佳 | 中后台管理系统 | +| [Vuetify](https://vuetifyjs.com) | ~41k | 最流行的 Vue Material Design 组件库,80+ 组件,文档完善 | Google 设计风格项目 | +| [Ant Design Vue](https://antdv.com) | ~21k | 基于蚂蚁设计体系的 Vue 3 组件库,设计规范统一 | 企业级中后台 | +| [Naive UI](https://www.naiveui.com) | ~18k | TypeScript 编写,主题定制性极强,不依赖 CSS 预处理器 | 对设计有独特要求的项目 | +| [Quasar](https://quasar.dev) | ~27k | 一套代码构建 SPA、SSR、PWA、移动端和桌面端应用 | 跨平台项目 | +| [Vant](https://vant-ui.github.io/vant) | ~24k | 有赞团队开发的轻量级移动端组件库,覆盖电商常见需求 | 移动端 H5 页面 | +| [PrimeVue](https://primevue.org) | ~14k | 90+ 组件,支持多种主题(Material、Bootstrap 等) | 需要丰富组件和多主题 | +| [Arco Design Vue](https://arco.design/vue) | ~3k | 字节跳动出品,组件质量高,内置暗色模式 | 中后台产品 | +| [TDesign Vue Next](https://tdesign.tencent.com/vue-next) | ~2k | 腾讯出品,设计语言统一,覆盖桌面端常用场景 | 腾讯生态或企业级项目 | + +### React 生态 + +| 组件库 | Stars | 简介 | 适用场景 | +| :--- | :--- | :--- | :--- | +| [Material UI (MUI)](https://mui.com) | ~95k | Google Material Design 规范的老牌实现,组件最全面,生态最成熟 | 快速构建企业级应用 | +| [Ant Design](https://ant.design) | ~94k | 蚂蚁集团出品,内置大量高质量业务组件,中文开发者社区主导地位 | 企业级中后台 | +| [shadcn/ui](https://ui.shadcn.com) | ~83k | 代码复制到项目中而非 npm 安装,基于 Radix UI + Tailwind CSS,完全可控 | 需要高度定制的项目 | +| [Chakra UI](https://chakra-ui.com) | ~39k | 以开发体验为核心,API 简洁,内置无障碍访问支持 | 快速原型开发 | +| [Mantine](https://mantine.dev) | ~28k | 100+ 组件和 50+ hooks,涵盖日期选择器、富文本编辑器等高级组件 | 需要开箱即用的全功能方案 | +| [Headless UI](https://headlessui.com) | ~27k | Tailwind Labs 官方出品的无样式组件库,同时支持 React 和 Vue | 搭配 Tailwind CSS 使用 | +| [HeroUI](https://heroui.com) | ~24k | 基于 Tailwind CSS + React Aria,默认样式精美,动画流畅 | 追求视觉品质的项目 | +| [Radix UI](https://www.radix-ui.com) | ~17k | 无样式底层组件原语库,专注无障碍和组件行为,是 shadcn/ui 的底层基础 | 构建自定义设计系统 | + +#### shadcn/ui 扩展生态 + +除了上述通用组件库,shadcn/ui 生态中还涌现了大量基于其理念的扩展库,为特定场景提供差异化选择。这些扩展库同样采用"复制代码到项目"的模式,让开发者拥有完全的源码控制权。 + +| 组件库 | 简介 | 适用场景 | +| :--- | :--- | :--- | +| [Aceternity UI](https://ui.aceternity.com) | 200+ 生产级组件,主打发光卡片、文字渐变、3D 地球等特色视觉组件 | 高质感落地页、SaaS 产品 | +| [Tailark UI](https://tailark.com) | 营销网站组件块集合,产品展示、客户证言、CTA 按钮等营销高频模块 | 营销落地页、产品官网 | +| [UI Tripled](https://ui.tripled.work) | 基于 Framer Motion 的动态交互组件,弹窗、导航、卡片动画 | 创意工具、个人作品集 | +| [Neobrutalism UI](https://neobrutalism.dev) | 新粗野主义风格,粗线条、高对比度、鲜明色彩 | 个性化品牌官网、创意项目 | +| [REUI](https://reui.io) | 967+ 真实业务场景的组件组合模式 | 企业级后台、复杂表单 | +| [Cult UI](https://cult-ui.com) | 更细的交互/视觉打磨,数据表格、筛选面板等复合组件 | 高质感商业项目 | +| [Kibo UI](https://kibo-ui.com) | 高级业务组件,颜色选择器、富文本编辑器、文件上传等 | 管理后台、工具类产品 | +| [Kokonut UI](https://kokonutui.com) | 100+ 组件 + 7+ 完整模板,清新简约风格 | SaaS 官网、博客、电商 | +| [Commerce UI](https://ui.stackzero.co) | 电商场景专用,商品卡片、购物车、结算表单 | 电商平台 | +| [shadcnblocks](https://shadcnblocks.com) | 1373 个 UI 块 + 13 套完整模板,资源最全面 | 所有场景 | +| [Shoogle](https://shoogle.dev) | shadcn/ui 生态聚合检索平台 | 快速查找资源 | +| [Discover All Shadcn](https://allshadcn.com) | 聚合型资源导航 | 快速查找资源 | + +> **为什么选择 shadcn/ui 扩展?** 这些扩展继承了 shadcn/ui"代码所有权"的理念,同时为特定场景做了深度定制。Vibe Coding 时代,它们让你能快速找到符合设计需求的组件,跳出主流 UI 库的同质化,做出更具差异化的产品。 diff --git a/docs/ko-kr/stage-2/frontend/multi-product-ui/index.md b/docs/ko-kr/stage-2/frontend/multi-product-ui/index.md new file mode 100644 index 0000000..8e08665 --- /dev/null +++ b/docs/ko-kr/stage-2/frontend/multi-product-ui/index.md @@ -0,0 +1,425 @@ +# 参考 UI 设计规范设计页面和按钮 + +很多人说"我想让页面更像 Apple 一点""按钮想做得更高级一点",但真正开始做时,往往会卡在一个问题上: + +**到底该参考什么?** + +盯着截图模仿,学到的只是"像不像"。但打开 Apple、Google、Microsoft、Atlassian 的设计规范,你会发现它们真正厉害的地方不是视觉风格,而是**把设计问题讲清楚**:页面先突出什么、按钮如何分级、操作怎么强调——这些判断标准才是核心。 + +> 参考设计规范,不是为了做得"像谁",而是学会别人怎么做判断。 + +:::: info 为什么现在还要学这些 +设计规则早已被训练进模型、被设计工具默认吸收,甚至贴几张截图 AI 就能学会。但我们仍然有必要知道这些规则从哪来、为什么这样定。 +:::: + +## 先看几段原文,感受差距 + +如果你以前觉得“设计规范不就是讲讲风格吗”,先看几条官方原文。 + +平时我们在团队里经常会这样说: + +- 做个下拉框 +- 这里放个菜单 +- 菜单栏加几个功能 +- 这里放两个按钮,一个确认一个取消 + +听起来没问题,但在大厂规范里,这些词都不是模糊概念,而是被拆得非常细。 + +| 平时随口说的话 | 官方原文 | 简单说 | +| :--- | :--- | :--- | +| “做个菜单” | Apple: [“A menu reveals its options...”](https://developer.apple.com/design/human-interface-guidelines/menus) | `Menu` 是拿来做操作的 | +| “菜单栏里放功能” | Apple: [“menu bar menus contain all the commands...”](https://developer.apple.com/design/human-interface-guidelines/menus) | 这是应用顶部的命令菜单 | +| “做个下拉框” | Apple: [“A pop-up list lets the user choose one option among several.”](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pop-up` 是从列表里选一个 | +| “也做个下拉框” | Apple: [“A pull-down list is generally used for selecting commands in a specific context.”](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pull-down` 是点开做当前操作 | +| “菜单也能拿来筛选吧” | Fluent: [“If you need to collect information from people, try a select, dropdown, or combobox instead.”](https://fluent2.microsoft.design/components/web/react/core/menu/usage) | `Menu` 不是拿来选值的 | +| “菜单也能当导航吧” | Material: [“Menus should not be used as a primary method for navigation within an app.”](https://m1.material.io/components/menus.html) | `Menu` 不是主导航 | +| “按钮随便写个 OK / Cancel” | Apple: [“Always use ‘Cancel’ to title a button that cancels the alert’s action.”](https://developer.apple.com/design/human-interface-guidelines/alerts) | 按钮文字不能随便写 | + +> 表格里的引文都可以直接点击,跳到对应的官方页面。 + +这就是第一次真正看设计规范时最容易被震到的地方: + +> 我们平时以为自己在讨论 UI,实际上很多时候只是在用一堆含糊词交流。 + +Apple 不会只说“做个菜单”;它会继续区分: + +- `menu` +- `menu bar menu` +- `pop-up button` +- `pull-down button` +- `context menu` + +Fluent 不会只说“下拉框”;它会继续区分: + +- `menu` +- `dropdown` +- `select` +- `combobox` + +这就是设计规范的必要性。 + +它不是为了让页面显得更专业,而是为了让团队在讨论 UI 时,不再每个人脑子里都是不同的东西。 + +## 你将学到 + +1. 为什么设计页面和按钮时要先看设计规范 +2. Apple、Material、Fluent、Atlassian 这些规范里,哪些内容最值得参考 +3. 如何把“页面层级”和“按钮层级”设计清楚 +4. 如何让 AI 参考别人的规范来生成页面和按钮 + +## 1. 设计规范为什么能帮你把页面做清楚 + +看完上面这些原文,你会发现一个关键点: + +**设计规范不是锦上添花,而是在先把词说准。** + +很多页面不好看,不是因为配色不够高级,而是因为信息层级混乱。 + +很多按钮不好用,也不是因为圆角不对,而是因为: + +- 主按钮太多,用户不知道该点哪个 +- 危险按钮和普通按钮看起来差不多 +- 页面里所有按钮都在抢注意力 +- 不同页面里的按钮样式和语义不一致 + +成熟的设计规范,恰好就是在解决这些问题。它们通常会定义: + +| 规范内容 | 它解决什么问题 | +| :--- | :--- | +| **页面层级** | 先看哪里、后看哪里,信息怎么组织 | +| **视觉基础** | 颜色、间距、字体、圆角、阴影怎样统一 | +| **按钮层级** | 主按钮、次按钮、文字按钮、危险按钮如何区分 | +| **状态规则** | hover、focus、disabled、loading 怎么表现 | +| **交互语义** | 哪个按钮是“确认”,哪个是“取消”,哪个是“更多操作” | + +所以,设计规范真正提供的不是一套“皮肤”,而是一套**判断标准**。 + +## 2. 参考大厂规范时,重点看什么 + +### 2.1 参考 Apple:学习“定义得足够细”这件事 + +Apple 最值得学的,不只是视觉上的克制感,而是它会把概念定义得非常细。 + +同样是很多团队口中的“菜单”或“下拉框”,Apple 会继续往下拆: + +- `menu`:一组命令、选项或状态 +- `menu bar menu`:应用级命令集合 +- `pop-up button`:选择一个值 +- `pull-down button`:在当前上下文里触发命令 +- `context menu`:与当前对象或任务相关的常用动作 + +这套区分非常重要,因为它会直接影响: + +- 这个组件是拿来选值,还是拿来做动作 +- 它属于页面局部,还是属于应用级 +- 它应该长期显示当前选中值,还是只临时展开命令 + +当你开始按这种粒度思考时,你设计出来的页面就会一下子清楚很多。 + +### 2.2 参考 Apple:学习页面层级和克制感 + +Apple Human Interface Guidelines 特别适合学习两件事: + +- 页面如何建立清晰层级 +- 控件如何在不喧宾夺主的前提下保持明确 + +Apple 强调 `Hierarchy`、`Harmony`、`Consistency`。这意味着页面设计时要回答: + +- 当前页面最重要的信息是什么 +- 用户的主要任务是什么 +- 哪个操作该最显眼,哪个操作应该退后 + +如果你参考 Apple 来设计页面,可以重点借鉴: + +- 首屏信息不要太碎,核心内容先聚焦 +- 用留白、字号、分组建立秩序,而不是靠堆很多边框 +- 按钮不要全部高强调,只有关键动作才应该最突出 + +### 2.3 参考 Material:学习清晰的页面结构 + +Material Design 很适合学习“页面是怎么组织任务流”的。 + +它的很多组件和布局规范,核心都在帮助你明确: + +- 页面是浏览型,还是执行任务型 +- 当前页面是让用户阅读、选择,还是提交 +- 一个页面里哪些元素应该稳定重复,哪些元素应该响应上下文变化 + +如果你参考 Material 来设计页面,可以重点借鉴: + +- 页面区块清楚,模块职责明确 +- 导航、内容区、操作区分工清晰 +- 不同按钮样式对应不同操作优先级 + +### 2.4 参考 Fluent:学习组件边界和按钮层级 + +Fluent 2 很适合后台、工具型产品和复杂表单系统。它最值得学的地方,是会直接告诉你“不要混用概念”。 + +例如它明确写到:如果你要“collect information”,就不要继续用 `menu`,而应该考虑 `select`、`dropdown`、`combobox`。 + +这句话非常重要,因为它把很多人脑中的“都差不多”打碎了。 + +Fluent 2 也很重视: + +- 操作层级 +- 组件语义边界 +- 密集信息场景下的清晰度 + +如果你参考 Fluent 来设计按钮,可以重点借鉴: + +- `Primary button` 用来承接当前最重要的动作 +- `Secondary button` 用来承接支持性动作 +- `Subtle`、`Transparent` 这类弱强调按钮用于不该抢主流程的操作 +- 页面里的按钮数量越多,越要控制视觉优先级 + +### 2.5 参考 Atlassian:学习系统化地管理页面和按钮 + +Atlassian Design System 特别适合“一个团队做很多页面”的情况。它强调: + +- foundations 是共享基础 +- tokens 是统一视觉决策的方法 +- components 是被反复复用的交互构件 + +如果你参考 Atlassian 来做页面和按钮,最有价值的是: + +- 把按钮尺寸、颜色、圆角、间距做成统一规则 +- 把页面布局的节奏固定下来 +- 让不同页面虽然内容不同,但结构语言一致 + +## 3. 设计页面时,应该参考规范里的哪些点 + +当你看一个设计系统时,不要先问“这个页面好不好看”,而要先问下面几个问题。 + +### 3.1 页面第一眼,主次是不是明确 + +一个页面通常至少要有三层: + +- **主信息**:当前页面最重要的内容 +- **辅助信息**:帮助理解或补充的内容 +- **次级操作**:不应该干扰主任务的动作 + +如果三层没有拉开,页面就会“都重要”,等于“都不重要”。 + +### 3.2 页面布局,是不是服务任务而不是堆模块 + +参考规范时,可以特别注意: + +- 标题区有没有明确页面目标 +- 主内容区是不是围绕任务组织 +- 操作按钮是不是贴近相关内容 +- 次要信息有没有被弱化 + +### 3.3 页面里的操作,是不是有优先级 + +很多页面一眼看过去有 6 个按钮,结果每个按钮都像 CTA,这是典型的层级失控。 + +更合理的方式是: + +- 一个区域通常只有一个主动作 +- 次级动作可以用描边、文字按钮或更弱的样式 +- 风险动作不要和主动作长得一样 + +## 4. 设计按钮时,应该参考规范里的哪些点 + +按钮是最容易被“随手设计”的部分,但也是最能暴露系统是否成熟的部分。 + +### 4.1 按钮先分“语义”,再分“样式” + +不要先想“蓝色按钮还是黑色按钮”,先想这个按钮是什么角色。 + +常见按钮角色可以这样分: + +| 按钮类型 | 作用 | 常见样式策略 | +| :--- | :--- | :--- | +| **Primary** | 当前区域最关键动作 | 实心、高对比、最显眼 | +| **Secondary** | 支持性动作 | 描边或低一级强调 | +| **Tertiary / Text** | 弱操作 | 文字或低视觉占比 | +| **Destructive** | 删除、停用、清空等风险操作 | 警示色或明确风险样式 | +| **Icon button** | 局部工具操作 | 简洁、靠近上下文 | + +### 4.2 一个页面不要有太多 Primary Button + +这是很多新手最容易踩的坑。 + +如果页面上有 4 个主按钮,那么等于没有主按钮。主按钮的意义本来就是“告诉用户现在最应该做什么”。 + +你可以借鉴很多设计系统的共同做法: + +- 一个主要区域通常只保留一个主按钮 +- 取消、返回、关闭一般不和确认按钮抢同级 +- 更多操作放到次级按钮或菜单中 + +### 4.3 按钮要能表达状态变化 + +设计规范通常会对按钮状态写得很清楚: + +- 默认态 +- 悬停态 +- 聚焦态 +- 禁用态 +- 加载态 +- 危险态 + +这很重要,因为按钮不是一张静态图,而是用户操作过程中最常被触发的控件之一。 + +### 4.4 按钮文案,也属于设计的一部分 + +按钮文案不只是“文案问题”,它直接影响用户理解。 + +例如: + +- `保存` +- `保存更改` +- `立即发布` +- `删除项目` +- `移到回收站` + +这些文案传达的心理预期完全不同。成熟规范通常会要求按钮标签清楚表达动作,而不是使用含糊词。 + +## 5. 一个很实用的页面与按钮设计清单 + +你自己设计页面时,可以先快速过一遍这张清单: + +### 页面清单 + +- 页面标题是否清楚说明当前任务 +- 首屏最重要的信息是否一眼可见 +- 页面是不是按任务流程组织,而不是按想到什么放什么 +- 同一个区域里是否只有一个主要动作 +- 次要内容是否被适当弱化 + +### 按钮清单 + +- 这个按钮是主动作还是次动作 +- 它为什么值得比别的按钮更显眼 +- 页面里是不是有太多主按钮 +- 危险操作是否被明确标识 +- 按钮文案是否足够具体 + +## 6. 怎样用 AI 参考别人的规范来设计页面 + +这一节最实用。 + +很多人让 AI 设计页面时,只会说: + +```md +帮我做一个设置页面,要高级一点,参考苹果风格 +``` + +这类提示词太模糊了,AI 最后通常只能模仿“白底、圆角、阴影”。 + +对新手来说,更实用的方式不是自己总结一大段,而是直接把**规范原文里的关键句**贴给 AI。 + +这样做有两个好处: + +- 你不用自己先“翻译”一遍设计思想 +- AI 更容易按官方定义去理解页面和按钮 + +### 6.1 例子一:让 AI 参考 Apple 设计一个设置页面 + +先找一句 Apple 原文: + +> ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) + +你可以直接这样贴给 AI: + +```md +参考 Apple Human Interface Guidelines 里的这句话: +"Establish a clear visual hierarchy..." + +帮我设计一个账号安全设置页面。 +要求页面层级清楚,重要信息放前面,分组整齐一点。 +``` + +这样写的重点是:不用你自己解释太多,直接把 Apple 的原话贴进去。 + +### 6.2 例子二:让 AI 参考 Fluent 设计后台页面按钮 + +先找一句 Fluent 原文: + +> ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +你可以直接这样贴给 AI: + +```md +参考 Fluent 2 里的这句话: +"Only use one primary button in a layout..." + +帮我设计一个团队管理后台的按钮。 +添加成员按钮最明显,导出、筛选、更多操作弱一点,删除按钮单独突出。 +``` + +这一句非常适合新手,因为它直接告诉 AI:一个区域不要放太多主按钮。 + +### 6.3 例子三:让 AI 同时参考页面规范和按钮规范 + +你也可以一次贴两句原文,让 AI 同时参考页面和按钮: + +> Apple: ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) +> +> Fluent: ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +然后直接这样写: + +```md +参考下面两句设计规范原文: +Apple: "Establish a clear visual hierarchy..." +Fluent: "Only use one primary button in a layout..." + +帮我设计一个项目详情页。 +页面包含项目介绍、成员、最近活动和设置入口。 +页面层级清楚一点,主按钮只保留一个,其他按钮弱一点。 +``` + +这种方式特别适合新手,因为你只要会复制原文,再加两句自己的需求就够了。 + +## 7. 怎样用 AI 参考按钮规范来直接生成按钮设计 + +如果你只想先做按钮,也可以直接贴按钮规范原文。 + +例如 Atlassian 对按钮的定义很短: + +> ["A button triggers an event or action."](https://atlassian.design/components/button/) + +你可以这样问 AI: + +```md +参考 Atlassian 的这句话: +"A button triggers an event or action." + +帮我设计一套后台页面按钮样式。 +我要有主按钮、次按钮、删除按钮,顺便告诉我分别用在什么地方。 +``` + +这类提示词尤其适合新手,基本就是“贴原文 + 说需求”。 + +## 8. 小结 + +参考 UI 设计规范设计页面和按钮,最重要的不是“做得像谁”,而是学会下面这几件事: + +1. 用层级组织页面,而不是把内容堆上去 +2. 用按钮分级表达操作优先级,而不是让所有按钮都一样抢眼 +3. 用设计规范里的定义、边界和判断标准指导设计 +4. 让 AI 参考别人规范时,参考的是“原则和结构”,而不是只参考皮肤 + +当你这样使用规范时,你参考到的就不只是一个风格,而是一套成熟的设计思考方式。 + +--- + +## 参考资料 + +以下链接都来自官方设计系统或官方文档: + +- Apple Human Interface Guidelines: [Overview](https://developer.apple.com/design/human-interface-guidelines/) +- Apple Human Interface Guidelines: [Menus](https://developer.apple.com/design/human-interface-guidelines/menus) +- Apple Human Interface Guidelines: [Alerts](https://developer.apple.com/design/human-interface-guidelines/alerts) +- Apple Human Interface Guidelines: [Buttons](https://developer.apple.com/design/human-interface-guidelines/buttons) +- Apple Archive: [How Menus Work](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/HowMenusWork.html) +- Apple Archive: [Managing Pop-Up Buttons and Pull-Down Lists](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) +- Material Design: [Buttons overview](https://m3.material.io/components/buttons/overview) +- Material Design: [Menus](https://m1.material.io/components/menus.html) +- Microsoft Fluent 2: [Start designing](https://fluent2.microsoft.design/get-started/design) +- Microsoft Fluent 2: [Menu usage](https://fluent2.microsoft.design/components/web/react/core/menu/usage) +- Microsoft Fluent 2: [Button usage](https://fluent2.microsoft.design/components/web/react/core/button/usage) +- Atlassian Design System: [Foundations](https://atlassian.design/foundations/) +- Atlassian Design System: [Button](https://atlassian.design/components/button/) diff --git a/docs/ko-kr/stage-2/frontend/ui-design/index.md b/docs/ko-kr/stage-2/frontend/ui-design/index.md new file mode 100644 index 0000000..03b3717 --- /dev/null +++ b/docs/ko-kr/stage-2/frontend/ui-design/index.md @@ -0,0 +1,3 @@ +# 첫 번째 현대적 애플리케이션 만들기 - UI 디자인 + +> 이 챕터는 현재 작성 중입니다. 기대해 주세요... diff --git a/docs/ko-kr/stage-2/index.md b/docs/ko-kr/stage-2/index.md index 464bf60..89753f4 100644 --- a/docs/ko-kr/stage-2/index.md +++ b/docs/ko-kr/stage-2/index.md @@ -1,126 +1,193 @@ -# 풀스택 개발 +# 초중급 개발 -**풀스택 개발** 단계에 오신 것을 환영합니다! 여기에서는 프론트엔드 컴포넌트화, 데이터베이스 설계, 백엔드 API 개발 및 배포를 마스터하여 풀스택 개발에 깊이 파고듭니다. +**초중급 개발** 단계에 오신 것을 환영합니다! 여기에서는 프론트엔드 컴포넌트화, 데이터베이스 설계, 백엔드 API 개발 및 배포까지 풀스택 개발에 깊이 파고듭니다. ## 배울 내용 ### 프론트엔드 개발 현대적인 프론트엔드 개발을 마스터하고 컴포넌트 라이브러리와 디자인 도구 사용법을 배웁니다: + + + + - -### 백엔드 및 풀스택 +### 백엔드 개발 API 설계, 데이터베이스 관리 및 애플리케이션 배포 전략을 배웁니다: + - +### 큰 과제 -### 과제 +앞선 장에서는 "부품"을 배우는 것이었고, 큰 과제에서는 "부품을 조립해 작동하고, 시연할 수 있고, 출시할 수 있는 제품으로 만드는 방법"을 배웁니다. + +**큰 과제 1 -> 큰 과제 2** 순서로 진행하는 것을 권장합니다: + +- **큰 과제 1** 에서는 현대 SaaS에서 가장 흔한 메인 체인인 로그인, 생성, 데이터베이스, 결제, 관리 백엔드를 먼저 경험합니다. +- **큰 과제 2** 에서는 비즈니스 시스템에 더 가까운 시나리오인 역할 권한, 문제 은행, 시험, 제출 기록, 관리 콘솔을 다룹니다. + +```mermaid +flowchart LR + A["프론트엔드 페이지와 컴포넌트"] --> B["데이터베이스와 인터페이스"] + B --> C["큰 과제 1
카피 생성 SaaS"] + C --> D["결제 / 배포 / 백엔드 관리"] + D --> E["큰 과제 2
온라인 시험 시스템"] + E --> F["완전한 풀스택 포트폴리오"] +``` + +어떤 것을 먼저 해야 할지 모르겠다면 아래 비교 표를 참고하세요: + +| 프로젝트 | 중점 연습 내용 | 가장 적합한 대상 | 최종 산출물 | +|------|------|------|------| +| 큰 과제 1: 카피 생성 웹사이트 | SaaS 페이지 구조, 사용자 로그인, AI 생성, Stripe 결제, 백엔드 관리 | 처음으로 완전한 상업화 웹사이트를 만드는 사람 | 가입, 생성, 결제, 관리가 가능한 SaaS 프로토타입 | +| 큰 과제 2: 온라인 시험 및 관리 시스템 | 역할 권한, 문제 은행 모델링, 시험 프로세스, 제출 기록, 채점 및 통계 | "비즈니스 시스템"을 진정으로 완성하고 싶은 사람 | 학생용 및 관리자용 시험 플랫폼 | + +어떤 과제를 선택하든, 큰 과제에서는 최소 다음 3가지 산출물을 준비하는 것을 권장합니다: + +- 실행 가능한 프로젝트 저장소 +- 접근 가능한 데모 링크 +- README와 데모 영상 하나 -실습 프로젝트를 통해 풀스택 개발 기술을 다집니다: +위의 두 메인 프로젝트를 완료했거나, 자신의 기술 방향에 맞춰 포트폴리오를 만들고 싶다면 아래 확장 주제 중 하나를 선택해 심화할 수 있습니다: -### AI 기능 확장 + + + + + + + +### AI 역량 확장 + + + - - ## 대상자 - 프로그래밍 기초가 있고 체계적으로 풀스택 개발을 배우고 싶은 개발자 - 제품 관리자에서 풀스택 엔지니어로 전환하고 싶은 학습자 - 현대적인 개발 도구와 워크플로우를 마스터하고 싶은 초중급 개발자 -- 완전한 제품을 독립적으로 개발하고 싶은 기업가 +- 완전한 제품을 독립적으로 개발하고 싶은 창업가 ## 전제 조건 - "초보자 및 제품 프로토타입" 단계를 완료했거나 동등한 기초 지식을 보유하고 있습니다 - 기본적인 HTML/CSS/JavaScript 개념을 이해하고 있습니다 -- AI 프로그래밍 도구에 대한 예비 지식이 있습니다 +- AI 프로그래밍 도구에 대한 기초 지식이 있습니다 풀스택 개발에 깊이 파고들 준비가 되셨나요? 왼쪽 탐색을 클릭하여 학습을 시작하세요! diff --git a/docs/public/sitemap.xml b/docs/public/sitemap.xml index 26fe7e6..da2d54a 100644 --- a/docs/public/sitemap.xml +++ b/docs/public/sitemap.xml @@ -594,7 +594,7 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/appendix/8-artificial-intelligence/ai-capability-dictionary - 2026-03-18T07:57:16-05:00 + 2026-05-21T01:01:06Z weekly 0.7 @@ -623,7 +623,7 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/appendix/8-artificial-intelligence/context-engineering - 2026-02-15T01:57:52+08:00 + 2026-05-21T00:57:00Z weekly 0.7 @@ -658,7 +658,7 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/appendix/8-artificial-intelligence/multimodal-models - 2026-02-24T12:54:06+08:00 + 2026-05-21T00:57:00Z weekly 0.7 @@ -672,7 +672,7 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/appendix/8-artificial-intelligence/prompt-engineering - 2026-02-15T02:08:12+08:00 + 2026-05-21T00:57:00Z weekly 0.7 @@ -1069,11 +1069,19 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T08:41:30.384Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/copywriting-platform-supabase/PRD @@ -1084,10 +1092,18 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/copywriting-platform-supabase/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T03:11:31.121Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/custom-dify-agent-platform/PRD @@ -1098,10 +1114,18 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/custom-dify-agent-platform/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T01:56:27.256Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/exam-management-express/PRD @@ -1112,10 +1136,18 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/exam-management-express/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T03:08:44.360Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/modern-landing-page/PRD @@ -1126,10 +1158,18 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/modern-landing-page/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T03:12:48.504Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/movie-recommendation-springboot/PRD @@ -1140,10 +1180,18 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/movie-recommendation-springboot/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T02:02:31.300Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/simple-grocery-microservices/PRD @@ -1154,10 +1202,18 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/simple-grocery-microservices/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T02:04:27.432Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/traffic-data-visualization-go/PRD @@ -1168,10 +1224,18 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/traffic-data-visualization-go/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T02:09:47.515Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/travel-planning-agent-platform/PRD @@ -1182,122 +1246,242 @@ https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/assignments/travel-planning-agent-platform/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T02:01:00.611Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/backend/ai-interface-code/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T03:05:09.949Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/backend/database-supabase/ - 2026-05-20T10:43:18+08:00 + 2026-05-25T08:41:30.630Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/backend/git-workflow/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T08:41:30.594Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/backend/modern-cli/ - 2026-05-17T02:30:20+08:00 + 2026-05-25T08:41:30.610Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/backend/stripe-payment/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T05:00:38.508Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/backend/zeabur-deployment/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T09:20:50.451Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/design-to-code/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T08:41:30.529Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/figma-mastergo/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T08:41:30.563Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/hogwarts-portraits/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T08:41:30.545Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/llm-skills-beautiful/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T02:29:13.557Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/lovart-assets/ - 2026-05-20T10:43:18+08:00 + 2026-05-25T08:41:30.495Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/modern-component-library/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T08:41:30.512Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/multi-product-ui/ - 2026-04-02T13:48:55+08:00 + 2026-05-25T02:17:40.955Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/ui-design/ - 2026-04-02T13:48:55+08:00 + 2026-05-24T16:35:47.109Z weekly 0.8 + + + + + + + + https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/ diff --git a/docs/vi-vn/stage-2/ai-capabilities/dify-knowledge-base/index.md b/docs/vi-vn/stage-2/ai-capabilities/dify-knowledge-base/index.md new file mode 100644 index 0000000..a882b3a --- /dev/null +++ b/docs/vi-vn/stage-2/ai-capabilities/dify-knowledge-base/index.md @@ -0,0 +1,1044 @@ +# Nhập môn Dify và tích hợp cơ sở tri thức + +# Ôn tập bài trước + +Trong các bài học trước, chúng ta đã học theo nhóm về kiến thức cơ bản của lập trình AI, kỹ thuật prompt và tạo ảnh bằng AI. Những nội dung này giúp chúng ta bước đầu hiểu được ranh giới và khả năng của các mô hình ngôn ngữ lớn (LLM, Large Language Model) hoặc các mô hình sinh khác nhau. + +Để giúp bạn ôn tập nội dung bài trước, dưới đây có một số câu hỏi nhỏ để suy nghĩ: + +1. Lập trình AI là gì? Làm thế nào để sử dụng công cụ lập trình AI (ví dụ [z.ai](http://z.ai)) để tạo một trang web? +2. Mô hình ngôn ngữ lớn là gì? Kỹ thuật prompt và kỹ thuật ngữ cảnh là gì? Bạn nên viết một prompt phức tạp như thế nào? +3. Đối với ba hướng khác nhau: văn bản, AI Coding, tạo ảnh, bạn nghĩ điểm mạnh của khả năng mô hình nằm ở đâu cho mỗi hướng? +4. API là gì? Làm thế nào để sử dụng [z.ai](http://z.ai) để tích hợp API bên thứ ba? + +Nếu bạn còn băn khoăn về bất kỳ câu hỏi nào, có thể xem lại tài liệu bài trước, hoặc trực tiếp đặt câu hỏi trong nhóm WeChat. + +Trong bài học này, chúng ta sẽ đi từ các công cụ văn bản ảnh AI đơn giản, bước vào nền tảng xây dựng quy trình làm việc gần với triển khai kinh doanh thực tế hơn. Từ chatbot tiến tới AI Agent, AI workflow, và dựa trên API biến nó thành trang "robot thông minh" có thể tương tác. + +Trong quá trình thao tác, nếu gặp bước khó hiểu, đừng lo lắng, chúng tôi khuyến nghị bạn chụp màn hình trang thao tác hiện tại bất kỳ lúc nào, gửi cho mô hình lớn để hỏi; các mô hình lớn hiện tại đã có thể giải đáp hầu hết các vấn đề phổ biến. + +Nếu sau khi hỏi vẫn không giải quyết được, hãy mạnh dạn thử thao tác; đừng sợ sai, mỗi lần thử đều là cơ hội học hỏi và tiến bộ. Khi số lần thực hành tăng lên, bạn sẽ ngày càng thành thạo và thao tác càng dễ dàng hơn! + +# Nội dung bạn sẽ học trong bài này + +1. Tại sao cần đi từ chatbot tới Agent và编排 Workflow. +2. Agent và nền tảng phát triển workflow là gì, làm thế nào để chuẩn hóa (SOP) và编排 hóa khả năng AI. +3. Dify là gì, làm thế nào để sử dụng nền tảng mã nguồn mở hướng tới ứng dụng LLM này để nhanh chóng xây dựng ứng dụng, đặc biệt là chatbot hỏi đáp dựa trên cơ sở tri thức. +4. Phương pháp thực hiện và giá trị của RAG, tại sao cần Retrieval-Augmented Generation? +5. Làm thế nào để từ 0 đến 1 học cách sử dụng Dify và AI IDE Trae (`Extra Knowledge 4 - What is AI IDE and Trae`), bao gồm xây dựng Agent, workflow, và dựa trên API Dify tạo chương trình trang web chatbot frontend. + +- Nguyên lý sử dụng cơ bản của Dify và phương pháp tạo Agent, workflow, phương pháp gọi API. +- Phương pháp sử dụng AI IDE, làm thế nào để lập trình bằng AI IDE. +- Một chương trình agent frontend có thể trò chuyện. + +# 1. Từ hội thoại tới Agent + +Ở giai đoạn trước, chúng ta đã học cách sử dụng prompt để khiến mô hình lớn đóng vai, tạo văn bản hoặc viết code đơn giản. Nhưng nếu bạn suy nghĩ kỹ, sẽ phát hiện một vấn đề: chatbot bản thân không thể hành động. + +Nó có thể trả lời "làm thế nào để tra cứu đơn hàng?", nhưng không thể thực sự vào cơ sở dữ liệu để tra các con số tương ứng; nó có thể mô tả một báo cáo tuần nên chứa những gì, nhưng không thể tự động tổng hợp dữ liệu dự án và gửi email. Hạn chế "chỉ nói không làm" này khiến AI thuần túy hội thoại khó thực sự tích hợp vào quy trình kinh doanh. + +Để nâng cấp AI từ đối tác trò chuyện thành "nhân viên kỹ thuật số", chúng ta cần trang bị cho nó ba khả năng cốt lõi: + +1. Kiến thức chuyên属 — để nó có thể đọc hiểu tài liệu sản phẩm, hồ sơ khách hàng, quy định nội bộ; +2. Gọi công cụ (hoặc plugin) — để nó có thể thao tác cơ sở dữ liệu, gọi API; +3. Thực thi có cấu trúc — để nó hoàn thành nhiệm vụ theo logic đã định trước, thay vì tự do phát huy. + +Đây chính là dạng ban đầu của AI Agent (Tác nhân AI): một đơn vị tự động hóa có mục tiêu, kiến thức, công cụ và đường dẫn thực thi. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image1.png) + +> Lưu ý: "Agent" phiên bản đơn giản mà ngành hiện tại nhắc đến, chủ yếu chỉ các ứng dụng tăng cường dựa trên sự kết hợp LLM + công cụ + cơ sở tri thức, không phải là Agent có khả năng tự lập kế hoạch. Agent đơn giản tuy không có khả năng suy luận và lập kế hoạch dài hạn thực sự, nhưng đã đủ để hỗ trợ lượng lớn các kịch bản tự động hóa cấp doanh nghiệp. Chúng ta sẽ giới thiệu chi tiết về Agent thực sự có khả năng tự lập kế hoạch và hành động trong các chương sau. + +## 1.1 Agent đơn giản nhất: Chatbot hỏi đáp dựa trên cơ sở tri thức + +Sau khi xác định nhiều khả năng cốt lõi mà Agent nên có, một câu hỏi đáng suy nghĩ nảy sinh: liệu có thể chỉ thông qua việc thực hiện một trong những chức năng đơn giản nhất, đã có thể xây dựng một Agent cơ sở thực sự sử dụng được? Câu trả lời là có. + +Trên thực tế, trong rất nhiều kịch bản kinh doanh thực tế, nhu cầu cốt lõi của người dùng không phải là để AI tự động thực hiện các thao tác phức tạp (như gọi API hoặc điều phối nhiệm vụ liên hệ thống), mà là hy vọng nó có thể cung cấp hỗ trợ hỏi đáp chính xác và đáng tin cậy dựa trên tài liệu chuyên属 của doanh nghiệp. Điều này tương ứng chính xác với khả năng cốt lõi đầu tiên trong ba khả năng của Agent — khả năng dịch vụ kiến thức chuyên属. Do đó, chúng ta có thể dẫn ra hình thái đơn giản nhất và được ứng dụng rộng rãi nhất của Agent: chatbot hỏi đáp dựa trên cơ sở tri thức. + +Mặc dù nó chưa có khả năng gọi công cụ hoặc tự lập kế hoạch, nhưng đột phá quan trọng nằm ở: khiến câu trả lời của mô hình lớn không còn được tạo ra từ hư vô, mà có cơ sở dựa trên. Làm thế nào để thực hiện? Điểm mấu chốt nằm ở việc giải quyết thách thức cốt lõi: doanh nghiệp có lượng lớn tài liệu kiến thức nội bộ, khi có hàng nghìn trang tài liệu, làm thế nào để mô hình nhanh chóng tìm thấy nội dung liên quan nhất đến câu hỏi hiện tại trong mỗi vòng hội thoại? + +Giải pháp lúc này là: Retrieval-Augmented Generation (RAG). + +Ý tưởng cơ bản của RAG là: khi người dùng đặt câu hỏi, hệ thống đầu tiên truy xuất một số đoạn văn bản có ngữ nghĩa liên quan nhất đến câu hỏi từ cơ sở tri thức doanh nghiệp (ví dụ một đoạn trong sổ tay sản phẩm, một điều khoản trong quy định nhân sự), sau đó chèn các đoạn này làm ngữ cảnh vào đầu vào của mô hình lớn, hướng dẫn nó tạo câu trả lời dựa trên tài liệu thực tế. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image2.png) + +Nguồn hình: [https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag](https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag) + +Như vậy, câu trả lời của mô hình không còn phụ thuộc vào kiến thức tổng hợp trong dữ liệu huấn luyện, mà được neo trên thông tin uy tín do doanh nghiệp cung cấp. Mục tiêu của RAG chính là thông qua việc chèn động kiến thức bên ngoài này, nâng cao đáng kể tính chân thực, chính xác và nhất quán của câu trả lời — thậm chí có thể khiến câu trả lời "phù hợp với nhân vật", ví dụ trả lời theo phong cách chăm sóc khách hàng hoặc văn phong tài liệu kỹ thuật. + +Trong kinh doanh thực tế, công nghệ này đặc biệt quan trọng, vì mô hình lớn thường xuyên tạo ra "ảo giác". Ví dụ, nếu bạn hỏi một số liệu cụ thể trong khoảng thời gian nào đó với tư cách CFO hoặc cố vấn, mô hình rất có thể bịa ra ngày tháng và sự kiện. Sau khi đưa RAG vào, tính kiểm soát và độ tin cậy của câu trả lời sẽ được nâng cao đáng kể. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image3.png) + +Nguồn hình: [https://www.databricks.com/glossary/retrieval-augmented-generation-rag](https://www.databricks.com/glossary/retrieval-augmented-generation-rag) + +Trong phần thực hành của bài học này, chúng ta sẽ sử dụng nền tảng AI workflow phổ biến Dify, thực hành xây dựng một chatbot hỏi đáp dựa trên cơ sở tri thức. Bạn có thể dễ dàng xây dựng cơ sở tri thức từ nhiều loại tài liệu chuyên属 khác nhau, như sổ tay sản phẩm, quy định công ty, tài liệu dự án, bài báo nghiên cứu, bài viết cơ sở tri thức, thậm chí là bộ ghi chú cá nhân. + +Sau khi hoàn thành xây dựng, bạn có thể thử đặt các câu hỏi khác nhau để kiểm tra khả năng của nó, ví dụ: + +- "Phiên bản mới nhất của sản phẩm A của chúng ta có những nâng cấp tính năng chính nào?" +- "Vui lòng theo sổ tay nhân viên, giải thích quy định nghỉ phép năm nay như thế nào?" +- "Trong dự án XX, thách thức kỹ thuật 'XXX' mà chúng ta gặp phải đã được giải quyết như thế nào?" +- "Phương pháp nghiên cứu cốt lõi được đề cập trong bài báo này là gì?" + +Bạn sẽ trải nghiệm trực tiếp cách công nghệ RAG chuyển đổi tài liệu tĩnh phân tán thành một cơ sở tri thức thông minh chính xác, cung cấp hỗ trợ hỏi đáp độ chính xác cao cho nhiều kịch bản khác nhau. + +## 1.2 Từ Agent hội thoại tới Workflow + +Tuy nhiên, ngay cả khi đã bổ sung cơ sở tri thức và thậm chí khả năng gọi plugin, "Agent tăng cường" vẫn tỏ ra chưa đủ khi đối mặt với các quy trình kinh doanh phức tạp hơn. + +Hãy tưởng tượng một yêu cầu người dùng như sau: "Sản phẩm SaaS mới ra mắt của chúng ta gần đây có những cập nhật tính năng nào? Có thể giúp tôi tổng hợp thành một bản tóm tắt cho khách hàng không?" + +Yêu cầu này có vẻ đơn giản, nhưng đằng sau cần nhiều bước phối hợp: đầu tiên truy xuất bản ghi phát hành tính năng trong tháng gần nhất từ tài liệu sản phẩm nội bộ hoặc cơ sở tri thức Notion; sau đó lọc ra các tính năng chính hướng tới khách hàng; tiếp theo gọi mô hình lớn chuyển mô tả kỹ thuật thành ngôn ngữ thân thiện với khách hàng; cuối cùng đẩy nội dung đã tạo đến email của đội ngũ marketing, hoặc lưu vào mẫu Google Docs. + +Nếu chỉ dựa vào một mô hình ngôn ngữ lớn tự do suy luận, chưa nói đến việc có thể thực hiện tất cả các bước trong một lần hội thoại hay không, ngay cả khi có thì cũng dễ bỏ sót thông tin quan trọng, nhầm lẫn thuật ngữ nội bộ với ngôn ngữ khách hàng, hoặc không thể xuất có cấu trúc. Quan trọng hơn, doanh nghiệp cần một đường dẫn thực thi tiêu chuẩn có thể kiểm toán, tái sử dụng và giám sát, chứ không phải mỗi lần đều dựa vào sự tự do phát huy của mô hình. Khả năng giám sát và tái lập rất quan trọng đối với doanh nghiệp, kết quả không mong đợi rất có thể mang lại tổn thất nghiêm trọng ngoài dự kiến. + +Điều này dẫn ra mô hình ứng dụng AI cao cấp hơn: AI Workflow. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image4.png) + +Workflow là việc chia một nhiệm vụ phức tạp thành nhiều bước con có thứ tự, có thể cấu hình, có thể tự động thực thi, và thông qua phương thức trực quan hoặc code để编排 quan hệ logic giữa chúng, như判断 điều kiện, vòng lặp hoặc thực thi song song. Đưa khả năng AI vào SOP (Standard Operating Procedure) có nghĩa là cố định hóa kinh nghiệm về cách sử dụng AI hoàn thành một nhiệm vụ thành một mẫu có thể tái sử dụng. + +Cách làm này mang lại nhiều giá trị: nhân viên phi kỹ thuật (như quản lý sản phẩm hoặc vận hành) có thể nhanh chóng xây dựng ứng dụng AI thông qua kéo thả thành phần; nhà phát triển có thể đóng gói truy xuất RAG, gọi LLM, công cụ API thành các nút tiêu chuẩn, tái sử dụng trong các kịch bản kinh doanh khác nhau; toàn bộ quy trình còn có thể được theo dõi đầy đủ, gỡ lỗi và tối ưu hóa liên tục, đáp ứng yêu cầu về tính ổn định và tuân thủ của doanh nghiệp. + +Người sử dụng AI Workflow rất đa dạng. Quản lý sản phẩm không cần viết code, đã có thể thiết kế đường dẫn tương tác người dùng hoàn chỉnh; nhân viên vận hành có thể nhanh chóng xây dựng chatbot chăm sóc khách hàng, trình tạo nội dung hoặc hệ thống thông báo; nhà phát triển và kỹ sư thuật toán có thể module hóa khả năng cốt lõi để frontend gọi; doanh nhân hoặc nhà phát triển độc lập cũng có thể xác minh MVP sản phẩm AI với chi phí cực thấp, đưa lên mạng một nguyên mẫu hoàn chỉnh bao gồm truy vấn dữ liệu, tạo nội dung và thực thi hành động trong vài ngày. + +Ngoài ra, đáng chú ý là AI Workflow thường có thể được mô tả bằng một dạng biểu diễn trung gian (Intermediate Representation). Cách biểu diễn cụ thể của các nền tảng workflow khác nhau có khác biệt, nhưng hầu hết sử dụng file có cấu trúc (như JSON, YAML, v.v.) để định nghĩa loại nút, đầu vào/đầu ra và logic thực thi, cấu trúc tương tự như hình dưới: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image5.png) + +Nói tóm lại, nếu Agent khiến AI đi từ biết trò chuyện tới có thể làm việc, thì workflow khiến AI từ thỉnh thoảng hoàn thành một việc tiến tới "hoàn thành một loại công việc một cách ổn định, đáng tin cậy và quy mô lớn". Trong thực hành tiếp theo, chúng ta sẽ sử dụng nền tảng Dify, trực tay xây dựng AI Workflow hoàn chỉnh, trải nghiệm toàn bộ quá trình từ ý tưởng đến ứng dụng có thể chạy được. + +## 1.3 Các nền tảng Agent / Workflow phổ biến + +Cùng với sự phát triển nhanh chóng của công nghệ AI sinh, để giúp nhà phát triển và nhân viên kinh doanh nhanh chóng xây dựng Agent và quy trình tự động hóa, tránh sa vào chi tiết phức tạp của lập trình, một loạt các nền tảng Agent và Workflow mã nguồn thấp (low-code) thậm chí không cần code (no-code) đã ra đời. + +Trước tiên cần làm rõ, nền tảng mã nguồn thấp là công cụ phát triển giảm đáng kể khối lượng lập trình thủ công thông qua kéo thả thành phần trực quan, mẫu logic kinh doanh tích hợp sẵn, cấu hình quy tắc bằng đồ họa, v.v. Cốt lõi của nó là thay thế cách viết code trực tiếp bằng cách cấu hình trực quan, kéo thả theo nút, vừa giải phóng nhà phát triển có năng lực kỹ thuật nhất định khỏi lao động lặp lại, vừa cho phép nhân viên phi kỹ thuật am hiểu logic kinh doanh tham gia vào việc xây dựng ứng dụng. Về bản chất, nó là một cây cầu cân bằng giữa hiệu quả phát triển và tính linh hoạt của kịch bản. + +Giá trị nổi bật của các nền tảng Agent mã nguồn thấp/không cần code này chính là giảm đáng kể ngưỡng phát triển ứng dụng AI. Trước đây cần đội nhóm phối hợp nhiều tuần — từ tổng hợp nhu cầu, phát triển code đến kiểm thử triển khai — mới có thể hoàn thành Agent AI (như chatbot hỏi đáp chăm sóc khách hàng, trợ thủ xử lý dữ liệu), nay借助 công cụ trực quan do nền tảng cung cấp, có thể rút ngắn chu kỳ "từ ý tưởng đến triển khai" xuống chỉ còn vài giờ. + +Hiện tại, các nền tảng AI workflow mã nguồn thấp phổ biến trên thị trường bao gồm: + +| Nền tảng | Đặc điểm | Kịch bản phù hợp | +| --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | +| Dify | Mã nguồn mở, hỗ trợ RAG cơ sở tri thức,编排 LLM, xuất API, thân thiện tiếng Trung | Hỏi đáp cơ sở tri thức doanh nghiệp, Agent tùy chỉnh, dịch vụ API | +| Coze (ByteDance) | Sử dụng được tại Trung Quốc, tích hợp hệ sinh thái Douyin/Feishu, plugin phong phú | Bot mạng xã hội, tích hợp tiểu trình trong nước | +| n8n | Công cụ tự động hóa phổ dụng, hỗ trợ nút AI, nhấn mạnh编排 API | Đồng bộ dữ liệu liên hệ thống, tự động hóa AI + SaaS truyền thống | +| Baidu Qianfan AppBuilder / Alibaba Bailian / Tencent HunYuan | Giải pháp cloud-native từ các ông lớn, tích hợp mô hình riêng | Triển khai cấp doanh nghiệp, kịch bản yêu cầu tuân thủ cao | + +Hiện tại sự lựa chọn nền tảng AI workflow mã nguồn thấp trên thị trường rất phong phú. Mặc dù các nhà cung cấp cloud chính thống như AWS, Azure, Alibaba Cloud đều đã đưa ra giải pháp AI workflow tương ứng, nhưng Dify, Coze và n8n凭借 ba ưu điểm cốt lõi sau đã trở thành những đại diện được ứng dụng rộng rãi nhất hiện nay: + +1. Tính dễ sử dụng cực độ. Nền tảng采用 thiết kế giao diện kéo thả trực quan, người dùng không cần hiểu sâu về công nghệ nền tảng, đã có thể nhanh chóng bắt đầu sử dụng. +2. Tính linh hoạt cao. Hỗ trợ thành phần tùy chỉnh và mở rộng giao diện API, vừa thích hợp các kịch bản nhẹ như demo giảng dạy, xác minh MVP (Minimum Viable Product), vừa đáp ứng nhu cầu lặp nhanh của đội nhóm vừa và nhỏ. +3. Hệ sinh thái trưởng thành. Không chỉ tài liệu chính thức chi tiết, phản hồi kịp thời, mà còn có cộng đồng người dùng hoạt động tích cực, dễ dàng tiếp thu các giải pháp đặt sẵn từ nhiều người dùng khác nhau. + +Cả ba nền tảng này đều hỗ trợ xuất Agent AI đã xây dựng dưới dạng giao diện API tiêu chuẩn, có thể tích hợp liền mạch vào ứng dụng Web frontend, hệ thống ERP nội bộ doanh nghiệp hoặc APP di động, tiếp tục giảm ngưỡng kỹ thuật để đưa khả năng AI vào thực tế. + +### 1.3.1 Dify: Nền tảng quản lý vòng đời ứng dụng và LLMOps cấp doanh nghiệp + +Định vị của Dify là nền tảng phát triển và vận hành ứng dụng LLM, cam kết cung cấp quản lý vòng đời toàn diện cho ứng dụng AI từ构思, triển khai đến tối ưu. Cốt lõi là một nền tảng mã nguồn thấp, nhằm giúp nhà phát triển và nhà đổi mới phi kỹ thuật nhanh chóng xây dựng ứng dụng AI cấp sản xuất. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image6.png) + +Về chức năng, Dify bao quát编排 workflow trực quan, xây dựng Agent, quản lý cơ sở tri thức, hỗ trợ đa mô hình, v.v. Nền tảng cho phép thiết kế quy trình nhiệm vụ phức tạp thông qua kéo thả nút, và hỗ trợ tạo Agent dựa trên ý định. Chức năng cơ sở tri thức nổi bật, có thể xử lý nhiều định dạng tài liệu và thực hiện truy xuất vector hiệu quả. Đồng thời, Dify tương thích và hỗ trợ nhiều LLM bao gồm GPT, Claude và nhiều mô hình mã nguồn mở, ứng dụng đã xây dựng có thể phát hành thành API tiêu chuẩn bằng một cú nhấp để dễ dàng tích hợp. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image7.png) + +Về kiến trúc kỹ thuật, Dify nổi bật với đặc điểm mã nguồn mở và có thể triển khai riêng, nhấn mạnh tính linh hoạt, khả năng mở rộng và tuân thủ cấp doanh nghiệp. Đối tượng người dùng mục tiêu bao gồm đội nhóm nhà phát triển và nhà đổi mới kinh doanh, kịch bản ứng dụng điển hình bao gồm cơ sở tri thức doanh nghiệp và chăm sóc khách hàng thông minh, tự động hóa sáng tạo nội dung, trợ lý AI lĩnh vực chuyên biệt và trung tâm AI doanh nghiệp. + +### 1.3.2 Coze (ByteDance): Người phổ cập xây dựng Agent AI không cần code + +Coze là nền tảng phát triển Agent AI do ByteDance推出, với tính dễ sử dụng cực độ làm cốt lõi, cho phép người dùng không có kinh nghiệm lập trình cũng có thể dễ dàng tạo, gỡ lỗi và phát hành chatbot AI chức năng phong phú. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image8.png) + +Điểm cốt lõi là đơn giản hóa việc xây dựng Bot thành thao tác kiểu xếp khối. Người dùng có thể dễ dàng cấu hình vai trò và cơ sở tri thức thông qua giao diện, và tận dụng thư viện plugin tích hợp phong phú để thêm nhiều khả năng bên ngoài như tin tức, du lịch, tạo ảnh, v.v. cho Bot. Bot đã tạo có thể nhanh chóng phát hành bằng một cú nhấp đến nhiều nền tảng như Doubao, Feishu, tài khoản chính thức WeChat, v.v. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image9.png) + +Kiến trúc kỹ thuật hoàn toàn phục vụ việc sử dụng với ngưỡng thấp, backend tích hợp mô hình riêng của Byte và đóng gói quy trình phức tạp, nhấn mạnh hiểu đa phương thức và phản hồi thời gian thực. Là một nền tảng chủ yếu được cung cấp dưới dạng dịch vụ cloud, khả năng triển khai riêng tương đối hạn chế. Kịch bản ứng dụng điển hình bao gồm trợ lý cá nhân và Bot giải trí, hệ thống chăm sóc khách hàng và hỏi đáp thông minh, trợ lý giáo dục trực tuyến và xác minh nguyên mẫu nhanh. + +### 1.3.2 n8n: Engine tự động hóa workflow backend có thể lập trình + +n8n là một nền tảng tự động hóa workflow có thể lập trình phổ dụng, định vị cốt lõi là kết nối các ứng dụng, cơ sở dữ liệu và API khác nhau, thực hiện luồng dữ liệu và tự động hóa thực thi nhiệm vụ. + +Nó hỗ trợ hàng trăm dịch vụ SaaS, cơ sở dữ liệu và giao thức thông qua thư viện nút tích hợp khổng lồ, và采用 phương thức kết hợp trực quan và code: người dùng có thể kéo thả nút trên canvas, đồng thời chèn code JavaScript hoặc Python để viết logic tùy chỉnh. n8n đặc biệt giỏi xử lý các nhiệm vụ backend chuyên về dữ liệu, như đồng bộ dữ liệu, quy trình ETL và编排 API. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image10.png) + +Đặc tính kỹ thuật quan trọng là "có thể xem mã nguồn" và "có thể tự lưu trữ", người dùng có thể triển khai riêng để hoàn toàn kiểm soát dữ liệu và môi trường, điều này khiến nó cực kỳ hấp dẫn đối với các ngành có yêu cầu cao về bảo mật dữ liệu. Đối tượng người dùng chính là nhà phát triển, vận hành kỹ thuật và nhà phân tích dữ liệu. Ưu điểm lớn nhất của n8n nằm ở hệ sinh thái cộng đồng cực kỳ mạnh mẽ. Trên mạng có vô số video chia sẻ n8n phong phú, cung cấp tài liệu tham khảo học tập và kinh nghiệm cho người dùng; đồng thời, nó hỗ trợ kết nối nhiều nền tảng hệ sinh thái toàn cầu khác nhau như YouTube, Instagram, v.v., có thể giúp người dùng dễ dàng phá vỡ rào cản dữ liệu và dịch vụ liên nền tảng, thực hiện tự động hóa luồng quy trình đa hệ sinh thái. + +### 1.3.3 Các nền tảng workflow khác + +Ngoài vài nền tảng nổi tiếng nhất ở trên, các nhà công nghệ chính tại Trung Quốc cũng lần lượt推出 các nền tảng phát triển AI tích hợp riêng, ví dụ: Baidu Qianfan AppBuilder cung cấp hỗ trợ toàn quy trình từ lựa chọn mô hình, xây dựng RAG đến phát hành Agent, tích hợp sâu mô hình văn tâm; Alibaba Cloud Bailian dựa trên loạt mô hình Tongyi Qianwen, tập trung vào bảo mật cấp doanh nghiệp và khả năng triển khai riêng; Tencent Cloud TI Platform tập trung vào các kịch bản ngành tài chính, y tế, v.v., cung cấp nhiều mẫu giải pháp đặt sẵn phong phú. Các nền tảng này thường tích hợp sâu với hệ sinh thái cloud tương ứng, phù hợp với các doanh nghiệp đã nằm trong hệ thống kỹ thuật tương ứng. + +Tuy nhiên, về tính phổ dụng, tính mở và hệ sinh thái cộng đồng, Dify và Coze vẫn凭借 tính dễ sử dụng nổi bật, hỗ trợ mô hình rộng rãi và cộng đồng nhà phát triển hoạt động tích cực, trở thành lựa chọn được chấp nhận rộng rãi hơn hiện nay. + +Mặc dù các nền tảng có trọng tâm khác nhau về định vị và hệ sinh thái, logic cốt lõi đều là编排 và kết nối các module khả năng khác nhau thông qua phương thức trực quan. Do đó, nắm vững tư tưởng thiết kế và phương pháp thao tác của bất kỳ nền tảng nào, đã có nền tảng để nhanh chóng chuyển sang các công cụ tương tự khác. Trong thực hành tiếp theo, chúng ta sẽ lấy Dify làm ví dụ để giải thích cụ thể. + +# 2. Giải thích sâu về Dify + +## 2.1 Dify là gì + +Chúng ta đã tìm hiểu thông tin giới thiệu cơ bản về Dify trước đó, để biết thông tin chi tiết hơn, bạn có thể truy cập nền tảng Dify qua [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps), nếu muốn tìm hiểu thêm, có thể truy cập trang chủ https://dify.ai. + +Dify là một nền tảng mã nguồn mở dùng để phát triển ứng dụng LLM. Nó cung cấp giao diện trực quan, kết hợp Agent workflow, pipeline RAG, khả năng công cụ, quản lý mô hình, khả năng quan sát, v.v., giúp bạn nhanh chóng đi từ nguyên mẫu đến môi trường sản xuất. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image11.png) + +Bạn có thể sử dụng mô hình ngôn ngữ lớn và nhiều công cụ có chức năng khác nhau trong Dify để xây dựng "workflow". Sở dĩ gọi là workflow, là vì nó nối串 các thao tác — ví dụ truy xuất dữ liệu, gọi mô hình lớn, tìm kiếm web, lọc kết quả, định dạng, v.v. — theo logic kinh doanh thành một quy trình tự động, có thể tái sử dụng. Nếu không có workflow, mỗi lần bạn đều phải sao chép dán cùng một nội dung cho mô hình lớn, rất kém hiệu quả, dễ sai và khó tái sử dụng trong kinh doanh thực tế. + +Xây dựng một workflow giống như xếp khối hoặc xếp tranh ghép. Bạn kết nối "nút mô hình ngôn ngữ lớn" (phụ trách hiểu và tạo), các "nút công cụ" (phụ trách thực thi hành động cụ thể, ví dụ truy vấn cơ sở dữ liệu, gửi email, dịch văn bản, v.v.), và "nút dữ liệu" (phụ trách đọc, lưu trữ thông tin) lại với nhau như các khối. Chúng sẽ tự động phối hợp làm việc theo logic bạn đặt trước, mà không cần bạn thao tác thủ công mỗi lần. Bạn cũng có thể hiểu nó là một "chương trình mã nguồn thấp": bạn chỉ cần kéo thả, cấu hình đường dẫn đầu vào và đầu ra, đã có thể thực hiện logic kinh doanh khá phức tạp. + +Ví dụ, nếu bạn là chủ một cửa hàng thương mại điện tử Amazon hoặc Douyin, muốn xây dựng một hệ thống chăm sóc khách hàng AI, có thể tham khảo cấu trúc như hình dưới để thiết kế một workflow: + +1. Nút kích hoạt (tương tự START): nhận câu hỏi tư vấn của người dùng, ví dụ "thời gian bảo hành sản phẩm này là bao lâu?". +2. Nút phân loại câu hỏi (tương tự QUESTION CLASSIFIER): sử dụng một mô hình (ví dụ GPT) để phân loại câu hỏi người dùng,判断 đây là vấn đề hậu mãi (ví dụ bảo hành), phương pháp sử dụng, hay loại câu hỏi khác. +3. Nút truy xuất kiến thức (tương tự KNOWLEDGE RETRIEVAL): dựa trên kết quả phân loại, tự động truy cập cơ sở tri thức tương ứng. Nếu là vấn đề hậu mãi về "bảo hành", thì truy xuất thông tin chính xác liên quan đến "bảo hành" từ cơ sở tri thức SOP hậu mãi. +4. Nút mô hình ngôn ngữ lớn (LLM Node): gửi câu hỏi người dùng và nội dung cơ sở tri thức đã truy xuất cùng lúc cho mô hình ngôn ngữ lớn (ví dụ GPT), để nó tạo một câu trả lời thân thiện với người dùng (tránh giọng điệu kỹ thuật quá cứng nhắc). +5. Nút điều kiện: kiểm tra xem câu trả lời do mô hình lớn tạo có chứa thời gian bảo hành rõ ràng hay không (ví dụ "1 năm", "3 năm"), nếu có thì tiếp tục bước tiếp theo, nếu không thì yêu cầu trả lời "vui lòng cung cấp mã sản phẩm". +6. Nút đầu ra (tương tự ANSWER): trả về câu trả lời cuối cùng cho người dùng, và tự động ghi lại bản ghi tư vấn lần này vào bảng. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image12.png) + +Trong toàn bộ quá trình, bạn không cần phải tự tra cơ sở tri thức, điều chỉnh liên tục câu trả lời của mô hình, hay ghi chép dữ liệu riêng — workflow sẽ "nối" các bước này để "chạy tự động". Và nó rất linh hoạt: ví dụ, nếu sau này bạn muốn thêm một quy tắc mới "khi người dùng hỏi về phạm vi bảo hành, gọi một cơ sở tri thức khác", chỉ cần thêm một nút điều kiện vào workflow, mà không cần tái cấu trúc toàn bộ hệ thống. + +Đây là một ví dụ workflow khá đơn giản, nhưng để nắm vững hoàn toàn các khả năng này, với bạn hiện tại có thể còn hơi khó. Do đó trong bài học này, chúng ta bắt đầu từ agent cơ sở tri thức cơ bản hơn, sau đó sẽ dần học các kỹ thuật workflow phức tạp hơn. + +### 2.1.1 Triển khai Dify riêng (tùy chọn) + +Nội dung phần này ban đầu được sắp xếp giới thiệu chi tiết trong khóa học sau, nhưng cân nhắc rằng một số người học hiện tại có thể tạm thời không thể truy cập trang web chính thức hoặc dịch vụ cloud của Dify do hạn chế mạng, chúng tôi quyết định cung cấp trước lộ trình học tùy chọn này, giúp bạn thuận lợi tiến triển khóa học. + +Bạn cần tham khảo hướng dẫn này để làm quen cách sử dụng cơ bản của nền tảng triển khai web: [Cách triển khai ứng dụng Web](/vi-vn/stage-2/backend/zeabur-deployment/) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image13.png) + +Bạn cần học cách triển khai một Dify riêng trên Zeabur, sau khi triển khai xong, truy cập liên kết tương ứng, đăng ký và đăng nhập, sau đó tiếp tục làm theo hướng dẫn dưới đây. + +Lưu ý, các phiên bản Dify khác nhau có thể có một chút khác biệt về thao tác và giao diện frontend, nhưng nhìn chung không khác nhiều, khi bạn phát hiện sự khác biệt đừng hoảng hốt, hãy tìm giao diện và điểm vào tương tự để thao tác. + +## 2.2 Tạo ứng dụng Chatbot Dify đầu tiên + +Truy cập trang chủ Dify [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps), sau khi đăng ký và đăng nhập, chọn Studio, bạn sẽ thấy giao diện như sau: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image14.png) + +Tìm khu vực `CREATE APP` ở bên trái, nhấp `Create from Blank`. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image15.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image16.png) + +Tìm Chatbot trong APP Type (nếu lúc đầu không thấy, có thể nhấp nút "xem thêm loại", sau đó tìm trong danh sách đầy đủ). Sau khi chọn Chatbot, nhập tên và mô tả ứng dụng ở bên dưới, cuối cùng nhấp tạo. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image17.png) + +Sau khi tạo xong, bạn sẽ thấy giao diện tương tự như dưới đây. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image18.png) + +Khu vực "INSTRUCTIONS" ở giữa指的是 lệnh tích hợp, bạn có thể hiểu nó là prompt mặc định hoặc system prompt. + +Ở phần giữa phía dưới có khu vực "Knowledge", đây chính là khu vực cơ sở tri thức — chúng ta sẽ tải cơ sở tri thức của mình lên đây sau một chút. + +Bên phải là cửa sổ gỡ lỗi, bạn có thể trò chuyện với Agent sau khi điều chỉnh prompt, xem hiệu quả theo thời gian thực. + +Bạn có thể tự do nhập prompt vai trò trong khu vực INSTRUCTIONS, quan sát hiệu quả hội thoại; cũng có thể nhấp Generate, để mô hình lớn tự động giúp bạn tạo prompt. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image19.png) + +Lưu ý ở góc trên bên phải sẽ xuất hiện nhiều tùy chọn mô hình khác nhau, điều này có nghĩa là bạn có thể nhấp chuyển đổi các mô hình hội thoại khác nhau, từ đó so sánh sự khác biệt của chúng về giọng điệu, suy luận logic, xử lý văn bản dài, v.v., tìm mô hình phù hợp nhất với nhu cầu của bạn. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image20.png) + +## 2.3 Hỗ trợ nhà cung cấp mô hình tùy chỉnh + +Để phát huy đầy đủ tính linh hoạt của Dify, cân nhắc khó khăn truy cập mô hình ở các khu vực khác nhau, để đáp ứng nhu cầu kinh doanh cụ thể, kiểm soát chi phí hoặc yêu cầu quyền riêng tư dữ liệu, chúng ta thường cần tích hợp mô hình tùy chỉnh. Dify hỗ trợ cấu hình ba loại mô hình cốt lõi: mô hình ngôn ngữ lớn (LLM), mô hình Embedding và mô hình Rerank. Phần nội dung này sẽ hướng dẫn bạn từng bước hoàn thành các cấu hình tùy chỉnh này. + +Dify có thể linh hoạt tích hợp mô hình từ các nhà cung cấp chính thống như OpenAI, Azure, Anthropic, đồng thời hoàn toàn tương thích với bất kỳ mô hình tự lưu trữ hoặc mô hình bên thứ ba nào tuân thủ đặc tả giao diện OpenAI API. Bạn có thể thực hiện thao tác này thông qua cài đặt plugin OpenAI Compatible tích hợp sẵn và các plugin tùy chỉnh cho các nền tảng mô hình lớn. + +Tham khảo các bước chi tiết dưới đây, đầu tiên chúng ta cần cài đặt plugin tương ứng: + +1. Chúng ta cần cài đặt plugin `OpenAI-API-compatible` và `SiliconFlow` để có được hỗ trợ cho hầu hết các mô hình lớn và mô hình Embedding, trong đó cái trước là hỗ trợ cho giao diện tương thích OpenAI, cái sau là một trạm dịch vụ đã triển khai hầu hết các mô hình mã nguồn mở phổ biến và tốt hiện nay. Bạn có thể truy cập các trang web sau để cài đặt: + 1. https://marketplace.dify.ai/plugins/langgenius/openai_api_compatible + 2. https://marketplace.dify.ai/plugins/langgenius/siliconflow +2. Nếu bạn tự triển khai Dify, bạn có thể vào thị trường plugin trong giao diện cài đặt hệ thống tương ứng để thao tác + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image21.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image22.png) + +Sau khi vào thị trường plugin, tìm kiếm tên plugin tương ứng. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image23.png) + +3. Sau khi cài đặt xong, chúng ta có thể cấu hình hỗ trợ nhà cung cấp mô hình mới, trong phần nhà cung cấp mô hình ở cài đặt, chúng ta có thể thấy tất cả các nhà cung cấp mô hình hiện được hỗ trợ: + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image24.png) +4. Trước khi bắt đầu sử dụng, cần hoàn thành cấu hình mô hình trước. Đối với plugin OpenAI-API-compatible, bạn có thể nhấp "Add Model" để thêm và cấu hình bất kỳ mô hình nào. Bạn có thể chọn mô hình này là LLM hay Embedding trong "Model Type", bạn cần đảm bảo loại mô hình được cấu hình chính xác. + Bạn cần nhập tên mô hình cụ thể, model endpoint URL và API Key để đảm bảo mô hình được kích hoạt, nếu ban đầu bạn thấy cấu hình tham số này phiền phức, bạn có thể bỏ qua trực tiếp đến cấu hình Key của nền tảng SiliconFLow ở phần sau, hoặc cài đặt plugin nhà cung cấp bên thứ ba như OpenRouter để cấu hình hỗ trợ mô hình đơn giản. (Đảm bảo có dư额度 sử dụng trong nhà cung cấp) + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image25.png) + + Đối với plugin `SiliconFlow`, chỉ cần nhấp Setup cấu hình key là có thể sử dụng mô hình Embedding và Rerank để kiểm thử, bạn có thể nhấp Get you API Key from SiliconFlow để lấy khóa xác thực. + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image26.png) + +5. Sau khi cấu hình xong, bạn có thể nhấp danh sách mô hình để xem hiện hỗ trợ bao nhiêu mô hình, lúc này đã hoàn thành toàn bộ cấu hình mô hình cơ sở. + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image27.png) + + Trong đó hỗ trợ hầu hết các mô hình Embedding và Rerank phổ biến: + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image28.png) + + Lúc này nếu bạn muốn sửa đổi cấu hình mô hình mặc định của Dify, bạn còn có thể nhấp nút System Model Settings để sửa đổi tất cả mô hình mặc định. + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image29.png) + +## 2.4 Tạo cơ sở tri thức Dify đầu tiên + +Đến đây, chúng ta đã hoàn thành việc tạo Agent đơn giản nhất, nhưng nó còn thiếu một cơ sở tri thức. Bây giờ, hãy nhấp `Knowledge` trong menu phía trên, vào trang tạo cơ sở tri thức. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image30.png) + +Sau đó nhấp `Create Knowledge` ở bên trái, tạo cơ sở tri thức đầu tiên của bạn. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image31.png) + +Trong giao diện này, bạn có thể tải lên nhiều loại file khác nhau (ví dụ pdf, txt, v.v.) để xây dựng cơ sở tri thức. Có thể tải lên văn bản rất dài, hoặc sao chép nội dung từ Wikipedia lưu thành file txt để tải lên. Trong ví dụ này, chúng ta sẽ tải lên một file txt Wikipedia về Elon Musk. + +Sau khi nhấp Next, bạn sẽ vào trang Knowledge Base Settings (cài đặt cơ sở tri thức). Có nhiều tùy chọn ở đây, chúng ta sẽ xem xét từng bước một. + +Đầu tiên trong cài đặt **General**, bạn có thể hiểu đây là khu vực cài đặt "quy tắc cắt văn bản". Vì chúng ta cần cắt văn bản dài thành các đoạn nhỏ, nên phải định nghĩa quy tắc cắt trước. Ở giai đoạn nhập môn, bạn chỉ cần quan tâm **maximum chunk length (độ dài cắt tối đa)**. Có thể thử đặt 512, 2048 hoặc 4096, sau đó nhấp **Preview Chunk** để xem trước hiệu quả với các cài đặt khác nhau. + +Bạn cũng có thể điều chỉnh tùy chọn **Chunk overlap (phần chồng lấp cắt)**. Nó quyết định xem giữa các đoạn liền kề có giữ lại một phần nội dung chồng lấp hay không. Phần chồng lấp phù hợp giúp tránh thông tin quan trọng bị chia vào các đoạn khác nhau mà khó hiểu. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image32.png) + +Trong cài đặt còn có một tùy chọn gọi là **Chunk using Q&A format in English**. Khi bật, hệ thống sẽ sử dụng mô hình ngôn ngữ lớn để chuyển đổi một phần nội dung cơ sở tri thức thành dạng hỏi đáp để lưu trữ, trong một số kịch bản có thể cải thiện đáng kể hiệu quả truy xuất. + +Trong kinh doanh thực tế, chọn chiến lược cắt phù hợp theo kịch bản có thể tối ưu hóa kết quả truy xuất tốt hơn, đảm bảo truy vấn có thể trả về thông tin bạn mong đợi. + +Tiếp tục cuộn trang xuống, bạn sẽ thấy cài đặt liên quan đến mô hình Embedding. + +Giải thích đơn giản: chức năng cốt lõi của mô hình Embedding là chuyển đổi dữ liệu phi cấu trúc (ví dụ văn bản, ảnh, v.v.) thành "vector số" (Embedding vector) mà máy tính có thể hiểu được. Thông qua chuyển đổi này, mô hình có thể nhanh chóng tính toán độ tương tự giữa các dữ liệu khác nhau, từ đó thực hiện khớp nội dung có ngữ nghĩa gần giống nhau, ví dụ dựa trên một câu người dùng nhập, tìm tài liệu, ảnh hoặc sản phẩm có ngữ nghĩa gần nhất. + +Lựa chọn mô hình Embedding sẽ ảnh hưởng đáng kể đến hiệu quả truy xuất cuối cùng (ví dụ độ chính xác khớp, tốc độ phản hồi, v.v.). Ở đây, chúng tôi khuyến nghị ưu tiên sử dụng mô hình Embedding Qwen 0.6B, bạn cũng có thể chuyển sang phiên bản 4B hoặc 8B để so sánh trực tiếp sự khác biệt về hiệu quả truy xuất dưới các quy mô tham số khác nhau. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image33.png) + +Tại đây, bạn còn sẽ thấy một cài đặt mô hình khác gọi là **Rerank model**, giá trị mặc định là **Jina-rerank-m0**. (Nếu bạn không phải là sinh viên trong trường, lúc này bạn có thể thấy lỗi thiếu mô hình Rerank, bạn cần cấu hình mô hình rerank ở phần mô hình để có thể bật sử dụng tại đây) + +Vai trò chính của mô hình Rerank là thực hiện sắp xếp thứ tự lần hai, tinh tế hơn đối với "kết quả ứng viên đã lọc ban đầu", khiến kết quả phù hợp nhất với nhu cầu người dùng xếp ở vị trí cao hơn, từ đó nâng cao đáng kể tính liên quan của kết quả cuối cùng và trải nghiệm người dùng. + +Hiểu đơn giản: mô hình Rerank chính là dùng để giải quyết vấn đề "lọc ban đầu chưa đủ tinh tế". Ví dụ công cụ tìm kiếm có thể dùng quy tắc đơn giản hơn để truy xuất 1000 trang web có khả năng liên quan, sau đó thông qua mô hình Rerank, chọn ra 10 trang liên quan nhất hiển thị ở trang đầu tiên. + +Hệ thống gợi ý cũng tương tự: nó có thể đầu tiên tìm ra 500 sản phẩm "có thể phù hợp với bạn", sau đó sắp xếp qua mô hình Rerank, khiến sản phẩm bạn có khả năng mua nhất xếp ở đầu danh sách. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image34.png) + +Khi tất cả cài đặt hoàn tất, nhấp **Save & Process**, hệ thống sẽ vào giai đoạn vector hóa cơ sở tri thức. Trong giai đoạn này, mô hình Embedding sẽ chuyển đổi văn bản đã cắt thành biểu diễn vector. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image35.png) + +Sau khi xử lý xong, nhấp **Go to document**, có thể xem nội dung cơ sở tri thức đã được xử lý và lưu trữ. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image36.png) + +Nhấp trực tiếp vào tên cơ sở tri thức, có thể xem nội dung cụ thể của từng đoạn. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image37.png) + +Tại đây, bạn có thể chỉnh sửa hoặc xóa chính xác bất kỳ đoạn văn bản nào không phù hợp. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image38.png) + +Trong thanh bên trái, chọn **Retrieval Testing** để kiểm tra thu hồi cơ sở tri thức, xem truy xuất có hoạt động bình thường không. Mỗi lần kiểm tra sẽ trả về một số đoạn có độ tương tự cao nhất. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image39.png) + +Nếu bạn muốn xem thêm kết quả đoạn, cần nhấp vào cài đặt `VECTOR SEARCH`: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image40.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image41.png) + +Top K指的是 số lượng đoạn văn bản có độ tương tự cao nhất với vector truy vấn được trả về khi truy xuất vector. Cài đặt hiện tại là 3, nghĩa là sẽ trả về 3 đoạn văn bản có độ tương tự cao nhất. + +Score Threshold là "ngưỡng điểm": chỉ các đoạn văn bản có điểm tương tự lớn hơn hoặc bằng ngưỡng này (0.5 trong ví dụ) mới được trả về. Như vậy có thể lọc bỏ nội dung có độ liên quan thấp, khiến kết quả chính xác hơn. + +Bây giờ phần cơ sở tri thức đã hoàn toàn sẵn sàng. Tiếp theo, nhấp "studio" trong thanh menu phía trên, tìm agent vừa tạo, kết nối cơ sở tri thức đã cấu hình cho nó. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image42.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image43.png) + +Lúc này, trong mỗi vòng hội thoại, bạn đều có thể thấy nguồn cơ sở tri thức được trúng trong câu trả lời. Nhấp vào mục tương ứng để xem đoạn văn bản cụ thể đã truy xuất. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image44.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image45.png) + +## 2.5 Thêm các thao tác phổ biến của Dify + +Sau khi nắm vững nội dung cơ bản về xây dựng Chatbot và cơ sở tri thức, chúng ta có thể tìm hiểu sâu hơn về nhiều cách sử dụng Dify khác. + +### 2.5.1 Nhập và xuất Workflow + +Bạn còn nhớ phương pháp biểu diễn trung gian của workflow đã đề cập trước đó không? Dify hỗ trợ nhập và xuất workflow thông qua định dạng DSL (Domain Specific Language). DSL là phương pháp mô tả tiêu chuẩn dựa trên JSON, có thể bảo toàn đầy đủ cấu trúc nút, quan hệ kết nối và tham số cấu hình của workflow. Bạn có thể dễ dàng nhập và xuất file DSL, chia sẻ workflow cho người khác sử dụng, hoặc nhập workflow của người khác để tham khảo. Cụ thể, chúng ta có thể dễ dàng thấy nút nhập workflow trên trang bảng làm việc: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image46.png) + +Còn đối với xuất workflow, chúng ta chỉ cần nhấp vào góc dưới bên phải của một khối workflow đơn lẻ là có thể tìm thấy nút xuất: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image47.png) + +Thông qua việc sử dụng file DSL, bạn có thể dễ dàng di chuyển hoặc chia sẻ thiết kế workflow phức tạp giữa các instance Dify khác nhau. + +### 2.5.2 Xem thêm dự án Dify + +Nếu bạn cảm thấy workflow hoặc agent mình xây dựng quá đơn giản, nền tảng Dify cung cấp nhiều dự án mẫu phong phú, giúp bạn nhanh chóng hiểu cách xây dựng ứng dụng phức tạp. Các dự án mẫu này bao quát nhiều kịch bản kinh doanh khác nhau. Bạn có thể nhấp Explora để xem workflow người khác xây dựng để học hỏi. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image48.png) + +## 2.6 Tạo ứng dụng Dify Workflow đầu tiên + +Sau khi hoàn thành nhập môn xây dựng Agent hội thoại của Dify, chúng ta tiếp tục xem cách xây dựng workflow kinh doanh Dify phức tạp hơn. Workflow là cách cốt lõi mà Dify trực quan hóa logic kinh doanh phức tạp, thông qua nó bạn có thể xây dựng quy trình thông minh như xếp khối. Bạn có thể trải nghiệm hoàn chỉnh cách thông tin luân chuyển giữa các nút khác nhau, logic判断 được triển khai như thế nào, điểm can thiệp thủ công được đặt ở đâu, và cuối cùng cách giao kết quả kinh doanh hoàn chỉnh. + +Bạn có thể chọn tạo từ trắng, hoặc trực tiếp tạo từ mẫu, ở đây demo cách tạo workflow từ trắng: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image49.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image50.png) + +Ở đây chúng ta sẽ thấy hai lựa chọn,分别是 Chatflow và Workflow, làm thế nào để chọn giữa hai cái này? Điểm mấu chốt là bạn cần hiểu điều bạn muốn xây dựng, cốt lõi là hội thoại liên tục hay quy trình nhiệm vụ. + +Chatflow được thiết kế riêng cho hội thoại. Nó mô phỏng một người hội thoại có khả năng ghi nhớ và hiểu ngữ cảnh, rất phù hợp cho các kịch bản cần tương tác nhiều vòng, duy trì trạng thái. Ví dụ trong tư vấn chăm sóc khách hàng, nó có thể hiểu liền mạch các câu hỏi theo sau của người dùng, giống như một nhân viên dịch vụ kiên nhẫn. Tính năng xuất luồng (streaming output) của nó cũng khiến quá trình tương tác tự nhiên hơn. Nói tóm lại, khi bạn cần xây dựng một agent có thể "giao tiếp", hãy chọn Chatflow. + +Workflow tập trung vào tự động hóa thực thi quy trình. Nó giống một đường dây chuyền đặt trước, giỏi xử lý các nhiệm vụ đầu vào một lần, xử lý nhiều bước, và tạo đầu ra xác định. Ví dụ, tạo báo cáo dữ liệu theo lịch hàng ngày, xử lý file hàng loạt hoặc gọi chuỗi API. Các nhiệm vụ này thường được kích hoạt bởi sự kiện, không cần tương tác với người theo thời gian thực. Do đó, khi bạn cần thực hiện nhiệm vụ "tự động hóa", Workflow là lựa chọn phù hợp hơn. + +Để tránh sai lầm chọn loại gây kém hiệu quả, bạn có thể xem xét nhu cầu nhiệm vụ của mình thông qua bốn câu hỏi quan trọng: + +1. Quá trình nhiệm vụ có cần dựa vào nhiều lần đầu vào và điều chỉnh của người dùng không? +2. Việc trình bày kết quả có cần tiến hành theo từng bước, theo luồng không? +3. Logic xử lý có phụ thuộc nghiêm trọng vào lịch sử tương tác trước đó không? +4. Nhiệm vụ có được kích hoạt bởi sự kiện, và đầu vào/đầu ra chủ yếu hoàn thành trong một lần không? + +Nếu câu trả lời cho ba câu hỏi đầu là "có", thì Chatflow là lựa chọn lý tưởng, kịch bản điển hình bao gồm chăm sóc khách hàng thông minh, gia sư giáo dục, hợp tác sáng tạo, v.v. Nếu đặc trưng câu hỏi thứ tư rõ rệt, thì nên chọn Workflow, nó phù hợp hơn cho các kịch bản tự động hóa như làm sạch dữ liệu, tạo báo cáo, xử lý hàng loạt. + +Ở đây chúng ta chọn Chatflow làm ví dụ để giới thiệu, sau khi nhấp Chatflow sẽ vào giao diện bảng thao tác: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image51.png) + +Chúng ta hãy giới thiệu đơn giản về giao diện trang workflow. Trong đó cốt lõi của toàn bộ giao diện là canvas chỉnh sửa ở trung tâm, bạn sẽ xây dựng logic ứng dụng tại đây theo phương thức trực quan. Như hình所示, một workflow cơ sở thường bắt đầu từ nút START (dùng để nhận đầu vào), qua đường dây truyền dữ liệu đến nút LLM để xử lý, cuối cùng xuất kết quả qua nút ANSWER. Mỗi nút đại diện cho một module chức năng, còn đường dây quyết định thứ tự thực thi nhiệm vụ. + +Quanh canvas là khu vực chức năng quản lý và thao tác hoàn chỉnh. Phía trên giao diện cung cấp tùy chọn kiểm soát toàn cục, bao gồm nút Preview để kiểm thử workflow và nút Publish để đưa lên mạng. Góc canvas có công cụ điều chỉnh视图 như thu phóng, hoàn tác, v.v., thuận tiện cho tinh chỉnh. + +Bảng bên trái tập trung các chức năng quản lý ứng dụng. Tab Orchestrate mà bạn đang ở dùng để编排 quy trình; sau khi xây dựng xong, có thể lấy chứng chỉ tích hợp qua API Access; Logs & Annotations ghi lại dấu vết chi tiết của mỗi lần thực thi, thuận tiện gỡ lỗi; còn Monitoring cung cấp giám sát hiệu suất và trạng thái runtime của ứng dụng cho bạn. + +Bạn có thể nhập đơn giản một số nội dung prompt trong SYSTEM của nút LLM trong workflow hội thoại này, nhấp Preview sau đó thử chạy workflow này, xem sau khi sửa SYSTEM prompt toàn bộ workflow có thực sự thay đổi theo mong đợi hay không. + +### 2.6.1 Giới thiệu các nút phổ biến + +Dify cung cấp nhiều loại nút, bạn có thể tìm hiểu chức năng cơ bản của mỗi nút trước. Khi sử dụng cụ thể, khuyến nghị tự tay thử, hoặc tham khảo mẫu workflow người khác tạo, cũng có thể chụp màn hình và hỏi mô hình lớn về cách sử dụng nút, tham số cần thiết, v.v. Khuyến nghị trực tiếp thay các nút khác nhau trong mẫu hiện có, thông qua cách sử dụng của người khác để suy luận thực hành tốt nhất cho nút. + +Nhấp chuột phải trên canvas chọn "Add Node" là có thể thêm nút, cũng có thể xem tất cả các nút khả dụng trong bảng nút bên trái: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image52.png) + +Đồng thời, có thể mở bảng chọn công cụ, xem các loại công cụ hỗ trợ gọi: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image53.png) + +Dưới đây là mô tả ngắn về một số nút và công cụ phổ biến. Không cần nắm tất cả cùng một lúc, khuyến nghị để lại ấn tượng trước, dần làm quen trong quá trình sử dụng thực tế, cần thì quay lại tra cứu. + +1. Nút LLM và suy luận + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image54.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image55.png) + +Loại nút này phụ trách quy trình cốt lõi trong workflow. + +- Nút LLM: đơn vị tính toán cốt lõi, dùng để gọi mô hình ngôn ngữ lớn. Trọng tâm cấu hình nằm ở kỹ thuật prompt và tinh chỉnh tham số, chuyển vấn đề kinh doanh thành lệnh thực thi cho mô hình. +- Nút Knowledge Retrieval: đơn vị truy xuất kiến thức, phụ trách truy xuất thông tin liên quan đến vấn đề kinh doanh từ cơ sở tri thức đặt trước, nguồn dữ liệu uy tín bên ngoài, cung cấp hỗ trợ kiến thức chính xác cho nút LLM, giúp giảm vấn đề "ảo giác" trong đầu ra của mô hình ngôn ngữ lớn. +- Nút Answer: đơn vị xuất kết quả, phụ trách nhận nội dung đã xử lý bởi LLM, tổ chức thành hình thức thành quả cuối cùng phù hợp với nhu cầu kịch bản kinh doanh. Trọng tâm cấu hình nằm ở định nghĩa định dạng đầu ra (như mẫu văn phòng, quy tắc trình bày). +- Nút Agent: đơn vị quyết định cao cấp. Nó không chỉ gọi mô hình, mà còn có thể thực hiện lập kế hoạch nhiều bước, tự chọn và gọi công cụ bên ngoài, phù hợp cho chuỗi nhiệm vụ phức tạp cần quyết định động. +- Nút Question Classifier: đơn vị phân loại câu hỏi, phụ trách nhận dạng loại và phân loại câu hỏi kinh doanh đầu vào (ví dụ phân loại theo ý định câu hỏi, lĩnh vực chủ đề, v.v.), giúp quy trình sau khớp chính xác với nút xử lý tương ứng (như các loại câu hỏi khác nhau khớp với prompt LLM hoặc chuỗi công cụ khác nhau). + +2. Nút điều khiển logic và quy trình + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image56.png) + +Loại nút này định nghĩa đường dẫn thực thi và quy tắc của workflow. + +- Nút điều kiện: như `IF/ELSE`, thực hiện phân nhánh quy trình thông qua判断 boolean. Điểm then chốt thiết kế nằm ở tính chặt chẽ của biểu thức điều kiện, đảm bảo logic bao phủ tất cả các kịch bản kinh doanh. +- Nút Iteration: là đơn vị xử lý song song hàng loạt không trạng thái, được thiết kế riêng cho các kịch bản mà nhiệm vụ con không phụ thuộc dữ liệu lẫn nhau, có thể xử lý độc lập, ví dụ dịch hàng loạt đoạn văn bản, duyệt song song nhiều nội dung hoặc đồng thời tạo nhiều báo cáo. Nút này nhận một mảng đầu vào và tự động chia nhỏ, phân phối mỗi phần tử đến cùng một chuỗi xử lý thực thi song song, người dùng có thể truy cập phần tử hiện tại qua {{item}} và lấy chỉ mục qua {{index}} trong thân lặp, đầu ra sẽ tự động tổng hợp thành mảng kết quả; khi cấu hình cần tập trung thiết lập độ song song để cân bằng hiệu quả và tải hệ thống, đồng thời đảm bảo ổn định của tác vụ hàng loạt thông qua chiến lược thử lại (như số lần thử lại, khoảng thời gian) và xử lý lỗi (như ghi log, trả về giá trị mặc định). +- Nút Loop: bộ lặp đệ quy có trạng thái, phù hợp cho các kịch bản mà kết quả phụ thuộc vào đầu ra của vòng trước, ví dụ tinh chỉnh tham số nhiều vòng, tối ưu hóa nội dung đệ quy (như sửa đổi bản sao lặp lại đến khi hài lòng) và tính toán chuỗi phụ thuộc kết quả lần trước. Cốt lõi của nó là "biến trạng thái", cần khởi tạo trước khi bắt đầu vòng lặp (như số lần lặp hiện tại, kết quả tính toán trung gian), và cập nhật rõ ràng trong mỗi vòng làm đầu vào cho vòng tiếp theo; để tránh vòng lặp vô hạn, phải định nghĩa điều kiện kết thúc (bao gồm "lặp tối đa 10 lần" dựa trên bộ đếm, "điểm hài lòng > 9" dựa trên判断 kết quả, "phát hiện đầu vào 'dừng'" dựa trên tín hiệu bên ngoài), đồng thời cần thiết lập cấu hình timeout vòng lặp, và lập kế hoạch đường dẫn xử lý ngoại lệ (như thoát vòng lặp hoặc đặt lại trạng thái rồi thử lại), đảm bảo quy trình vận hành ổn định. + +3. Nút thao tác dữ liệu và tích hợp + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image57.png) + +- Nút Code: đơn vị xử lý code, phụ trách thực thi logic code tùy chỉnh trong workflow, có thể thực hiện chuyển đổi định dạng dữ liệu, tính toán phức tạp, v.v. Trọng tâm cấu hình nằm ở tính chính xác của cú pháp code và sự phù hợp với môi trường thực thi. +- Nút Template: đơn vị xử lý mẫu, phụ trách điền dữ liệu động vào mẫu đặt trước, tạo nội dung phù hợp yêu cầu định dạng (như bản sao tùy chỉnh, khung báo cáo). Trọng tâm cấu hình nằm ở viết cú pháp mẫu và cài đặt quy tắc ánh xạ biến. +- Nút Variable Aggregator: đơn vị tổng hợp biến, phụ trách thu thập dữ liệu biến đầu ra từ nhiều nút trong workflow, tích hợp các biến phân tán thành tập dữ liệu thống nhất. Trọng tâm cấu hình nằm ở phạm vi biến tổng hợp và định nghĩa quy tắc hợp nhất dữ liệu. +- Nút Doc Extractor: đơn vị trích xuất tài liệu, phụ trách trích xuất văn bản, bảng biểu, v.v. từ các loại tài liệu PDF, Word, v.v., chuyển thành dữ liệu có cấu trúc mà workflow có thể xử lý. Trọng tâm cấu hình nằm ở thích ứng loại tài liệu và quy tắc sàng lọc nội dung trích xuất. +- Nút Variable Assigner: đơn vị gán biến, phụ trách định nghĩa, khởi tạo hoặc cập nhật biến trong workflow, cung cấp载体 cho truyền dữ liệu trong quy trình. Trọng tâm cấu hình nằm ở đặt tên biến, loại dữ liệu và logic gán. +- Nút Parameter Extractor: đơn vị trích xuất tham số, phụ trách trích xuất tham số chỉ định từ nội dung đầu vào như yêu cầu người dùng, trả về giao diện, v.v., chuyển thông tin phi cấu trúc thành dữ liệu có cấu trúc. Trọng tâm cấu hình nằm ở cấu hình quy tắc trích xuất (như biểu thức chính quy, đường dẫn JSON). +- Nút HTTP Request: đơn vị yêu cầu HTTP, phụ trách gửi yêu cầu HTTP (bao gồm GET, POST, v.v.) đến giao diện hệ thống bên ngoài, thực hiện tương tác dữ liệu giữa workflow và dịch vụ bên ngoài. Trọng tâm cấu hình nằm ở cài đặt địa chỉ yêu cầu, phương thức yêu cầu và tham số/headers. +- Nút List Operator: đơn vị thao tác danh sách, phụ trách xử lý dữ liệu loại mảng, danh sách (như lọc, sắp xếp, chia nhỏ), điều chỉnh cấu trúc dữ liệu để phù hợp với quy trình tiếp theo. Trọng tâm cấu hình nằm ở định nghĩa loại thao tác (như điều kiện lọc, quy tắc sắp xếp). + +### 2.6.2 Giới thiệu công cụ phổ biến + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image58.png) + +Trong Dify, hầu hết các công cụ đều có thể trực tiếp đặt trên canvas như một nút, được nối với dòng lên xuống như các nút khác, miễn là đầu vào bạn cung cấp phù hợp với quy范 tham số của nút (công cụ) đó, nó sẽ thực thi bình thường và tạo kết quả có thể tiếp tục luân chuyển. + +Trong bảng nút bên trái hoặc bên phải, có thể xem tất cả các nút công cụ khả dụng, cũng có thể mở rộng thêm khả năng công cụ thông qua thị trường plugin. Giới thiệu ngắn gọn vài công cụ phổ biến: + +- Công cụ tìm kiếm web + Điển hình là Tavily Search, cung cấp khả năng truy xuất thời gian thực được tối ưu hóa cho AI dành cho mô hình lớn. + Nó sẽ trả về kết quả tìm kiếm có cấu trúc (như tiêu đề, tóm tắt, liên kết, v.v.), có thể trực tiếp dùng làm một phần prompt của LLM, dùng để trả lời các câu hỏi về tin tức mới nhất hoặc cần cơ sở uy tín. +- Công cụ xử lý dữ liệu + Ví dụ plugin JSON Process, dùng để thực hiện các thao tác nâng cao như truy vấn, lọc, chuyển đổi, hợp nhất dữ liệu JSON. + Khi xử lý phản hồi API phức tạp hoặc dữ liệu lồng nhau nhiều lớp, bạn có thể giao logic "làm sạch + tái cấu trúc dữ liệu" cho công cụ này, từ đó đơn giản hóa việc phải thường xuyên viết code phân tích thủ công trong nút Code. +- Công cụ xử lý định dạng + Như Markdown Exporter, có thể xuất nội dung đã tạo theo định dạng chỉ định, ví dụ tài liệu Markdown, mẫu trình bày cụ thể, v.v., thuận tiện cho việc sử dụng sau này để hiển thị, báo cáo hoặc tích hợp vào hệ thống khác. + +Bạn có thể thấy số lượng cài đặt và mô tả tóm tắt của các plugin này trong danh sách công cụ, ban đầu có thể ưu tiên thử cài đặt các công cụ trong "Featured / Đề xuất", thường bao phủ các kịch bản kinh doanh phổ biến nhất. + +Tuy nhiên, việc sử dụng công cụ thường khá phức tạp, khuyến nghị khi sử dụng bạn có thể tìm kiếm trước "ví dụ DSL workflow được khuyến nghị chính thức" của công cụ tương ứng trên công cụ tìm kiếm, nhập trực tiếp để sử dụng, sẽ tiết kiệm được nhiều thời gian hơn so với tự xây dựng. + +### 2.6.3 Tạo workflow phân loại ý định đơn giản + +Lúc này chúng ta đã tìm hiểu sơ bộ về thông tin cơ bản của workflow và công cụ Dify, nhưng nếu không thực hành chúng ta sẽ không bao giờ thành thạo trong việc sử dụng chi tiết, chúng ta cần một kịch bản kinh doanh "giả định" thực tế để luyện tập. + +Ví dụ, trong kịch bản đối thoại mua sắm thực tế, đầu vào của người dùng đến mua hàng không bao giờ là "tham số chuẩn hóa", mà là một câu nói bộc phát: có người đến đặt hàng, có người đến phàn nàn, có người chỉ muốn trò chuyện, cũng có người hoàn toàn lạc đề. Nếu chúng ta đưa tất cả các đầu vào này trực tiếp cho cùng một mô hình ngôn ngữ lớn (LLM) xử lý, hệ thống thường sẽ xuất hiện hai vấn đề điển hình: + +1. Phong cách phản hồi không ổn định + Cũng là phàn nàn, đôi khi LLM có thể xin lỗi và xoa dịu, đôi khi lại giống như đang "giải thích nguyên nhân"; cũng là gọi món, đôi khi sẽ hỏi thêm thông tin còn thiếu, đôi khi lại tự bịa ra chi tiết đơn hàng. +2. Logic kinh doanh không thể kiểm soát + Bạn muốn "phàn nàn phải xin lỗi trước", nhưng mô hình không nhất thiết mỗi lần đều tuân thủ; bạn muốn "câu hỏi không liên quan đến kinh doanh phải hướng về chủ đề chính", nhưng mô hình có thể hào hứng trò chuyện về những câu chuyện vui với bạn. + +Do đó, cách làm mang tính kỹ thuật hơn là chia nhiệm vụ thành một đường dây chuyền tiêu chuẩn hóa, đầu tiên phân loại ý định (xác định người dùng thực sự muốn làm gì), sau đó phân luồng theo ý định (các kịch bản khác nhau sử dụng prompt và vai trò khác nhau), cuối cùng đóng gói thống nhất đầu ra của mô hình lớn sau phân luồng (thuận tiện cho tích hợp frontend hoặc hệ thống). + +Mục tiêu của phần này là giúp hệ thống có thể xử lý nhiều loại đối thoại trong một kịch bản nhà hàng. Bạn có thể làm theo thao tác một lần để ghi nhớ sâu hơn. Đầu tiên cần định nghĩa kịch bản thành các phân loại ý định: + +- **Đặt hàng mua đồ (buy_food)**: Người dùng thể hiện ý định mua hàng rõ ràng. +- _Ví dụ: "Cho tôi một phần gà rán, thêm một ly cola."_ +- **Phàn nàn khiếu nại (complain)**: Người dùng đang thể hiện sự không hài lòng, hối thúc hoặc phản hồi tiêu cực. +- _Ví dụ: "Các bạn也太 chậm rồi? Đợi một tiếng rồi."_ +- **Trò chuyện tư vấn (chitchat)**: Người dùng đang hỏi mở, tìm kiếm đề xuất, nhưng không có chỉ dẫn đặt hàng rõ ràng. +- _Ví dụ: "Hôm nay ăn gì cho ngon, bạn có gợi ý gì không?"_ +- **Ý định khác (other)**: Đầu vào của người dùng không liên quan đến kịch bản nhà hàng. +- _Ví dụ: "Giúp tôi viết một caption hài hước đăng Facebook."_ + +Đối với bốn loại ý định này, chúng ta đã đặt trước bốn "nhân cách giao tiếp" khác nhau cho hệ thống, lần lượt được gánh bởi bốn nút LLM độc lập, mỗi nút đều cần LLM với các nhân thiết khác nhau để đóng vai. + +- **Trợ lý đặt hàng (LLM_BuyFood)**: Chuyên nghiệp, hiệu quả, nhiệm vụ cốt lõi là xác nhận chi tiết đơn hàng, và chủ động bổ sung thông tin còn thiếu. +- **Chuyên gia chăm sóc khách hàng (LLM_Complain)**: Thấu cảm, điềm tĩnh, ưu tiên hàng đầu là xoa dịu cảm xúc người dùng, và cung cấp giải pháp rõ ràng. +- **Bạn trò chuyện (LLM_Chitchat)**: Thư giãn, thân thiện, nhằm cung cấp đề xuất cá nhân hóa, hướng dẫn tiêu dùng tiềm năng. +- **Người gác cửa lịch sự (LLM_Other)**: Tập trung, ranh giới rõ ràng, phụ trách hướng dẫn lịch sự các cuộc đối thoại lệch chủ đề quay về nghiệp vụ cốt lõi. + +#### Thiết kế编排 workflow + +Tiếp theo chúng ta tiến hành thiết lập编排 workflow, quyết định đại loại cần có những nút workflow nào. Đối với người mới, rất khó nghĩ ra cần có những nút nào (đối với người giàu kinh nghiệm cũng lười tự suy nghĩ, dùng mô hình lớn để đưa ra gợi ý thường là lựa chọn nhanh và tốt nhất), nên chúng ta có thể sử dụng mô hình lớn để đưa ra gợi ý编排 tương ứng, cấu trúc nút cốt lõi như sau: + +- Start (điểm bắt đầu): Là đầu vào dữ liệu, phụ trách nhận đầu vào gốc `user_text` của người dùng. +- Question Classifier (bộ phân loại ý định): Là "bộ não" và "trung tâm điều phối" của workflow. Nó phụ trách phân tích `user_text`, và chọn nhãn ý định phù hợp nhất trong bốn loại nhãn ý định đã đặt trước. +- Condition (nhánh điều kiện): Đóng vai trò "van phân luồng". Nó quyết định hướng nhiệm vụ tới đường xử lý chuyên biệt nào tiếp theo dựa trên nhãn ý định do bộ phân loại đầu ra. +- Bốn nút LLM song song (LLM_BuyFood, LLM_Complain, LLM_Chitchat, LLM_Other): Đây là bốn "đơn vị xử lý chuyên gia" độc lập. Mỗi nút đều nhận câu hỏi gốc, nhưng dựa trên System Prompt (prompt hệ thống) riêng biệt để tạo phản hồi có phong cách và mục tiêu hoàn toàn khác nhau. +- Variable Aggregator (bộ tổng hợp biến): Sau khi nhiều đường xử lý hoàn tất, cần một "điểm tập hợp". Nút này sẽ thu thập phản hồi duy nhất được kích hoạt và tạo kết quả trong bốn nhánh thành một biến thống nhất `final_reply`, đảm bảo tính ổn định của cấu trúc đầu ra. +- Output (điểm kết thúc): Là đầu ra cuối cùng, phụ trách xuất nhãn ý định, câu hỏi gốc và phản hồi đã được xử lý tạo ra dưới dạng có cấu trúc (như JSON) thống nhất, thuận tiện cho hệ thống gọi hoặc phân tích gỡ lỗi sau này. + +#### Thực hiện编排 workflow + +Trong hướng dẫn lần này chúng ta chọn tạo Workflow thay vì Chatflow, chọn User Input: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image59.png) + +Sau đó nhấp vào nút User Input của Start, định nghĩa một biến loại chuỗi tên `user_text`, làm nguồn đầu vào của toàn bộ quy trình. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image60.png) + +Sau khi lưu, nhấp Test Run ở góc trên bên phải, bạn có thể thấy cần chỉ định đầu vào văn bản tương ứng để xử lý: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image61.png) + +Tiếp theo chúng ta cần nhấp vào dấu + sau nút đầu vào, chọn thêm nút Question Classifier, và chúng ta cần cấu hình bốn loại nhãn cho nó, cung cấp mô tả và ví dụ rõ ràng cho mỗi nhãn. + +- `buy_food`: Người dùng rõ ràng muốn mua đồ, gọi món, đặt hàng. +- `complain`: Người dùng đang phàn nàn,吐槽, tức giận, thường mang cảm xúc không hài lòng. +- `chitchat`: Người dùng đang trò chuyện, thảo luận ăn gì, tư vấn đề xuất. +- `other`: Không liên quan đến kịch bản nhà hàng, hoặc nội dung khó xác định. + +Ngoài ra, bạn còn cần viết prompt trong ADVANCED SETTING, để mô hình lớn có thể phân loại chính xác dựa trên đầu vào của người dùng. Prompt mẫu như sau: + +``` +Chọn một nhãn phù hợp nhất từ buy_food / complain / chitchat / other. Nếu người dùng vừa phàn nàn vừa gọi món, hãy ưu tiên xác định cảm xúc cốt lõi, nếu trọng tâm là bày tỏ sự không hài lòng, nên phân vào complain. Nếu chỉ là than vãn nhẹ nhưng ý định chính là đặt hàng, thì phân vào buy_food. Nếu thực sự khó xác định, sử dụng other làm phương án dự phòng +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image62.png) + +Sau khi thiết lập xong, bạn có thể nhấp nút phát ở góc trên bên phải để kiểm tra riêng nút này có hoạt động bình thường hay không: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image63.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image64.png) + +Từ kết quả OUTPUT, phân loại của chúng ta là chính xác. Bạn có thể thử nhiều loại đầu vào khác nhau để xác minh tính ổn định của bộ phân loại. + +Tiếp theo, chúng ta cần kết nối đầu ra của bộ phân loại với mô hình lớn phía sau, ví dụ, khi `label` bằng `"buy_food"`, workflow sẽ chính xác流向 nút `LLM_BuyFood`. Chúng ta cần tạo mới bốn nút LLM, và thiết lập System Prompt khác nhau; sự khác biệt của các System Prompt quyết định cách phản hồi khác nhau của chúng. + +- LLM_BuyFood (trợ lý gọi món): + +Bạn là trợ lý gọi món. Yêu cầu: 1. Xác nhận nội dung người dùng muốn gọi. 2. Nếu thông tin chưa đầy đủ, thân thiện hỏi thêm. 3. Giọng điệu lịch sự, súc tích. + +- LLM_Complain (chuyên gia chăm sóc khách hàng): + +Bạn là nhân viên chăm sóc khách hàng nhà hàng, chuyên xử lý phàn nàn. Yêu cầu: 1. Xin lỗi chân thành. 2. Giải thích ngắn gọn nguyên nhân có thể (không đẩy lỗi). 3. Đưa ra giải pháp bước tiếp theo rõ ràng. + +- LLM_Chitchat (bạn trò chuyện): + +Bạn là trợ lý trò chuyện giúp người khác chọn đồ ăn. Yêu cầu: 1. Dùng giọng điệu nhẹ nhàng, thân thiện. 2. Đưa ra 1~3 đề xuất đơn giản. 3. Nếu người dùng không có sở thích, hãy đưa ra các lựa chọn phong cách khác nhau. + +- LLM_Other (người gác cửa lịch sự): + +Bạn là trợ lý gọi món nhà hàng, chỉ giỏi các chủ đề liên quan đến 'ăn uống'. Khi người dùng nói về những việc không liên quan: 1. Lịch sử giải thích phạm vi khả năng của mình. 2. Hướng người dùng quay về kịch bản chính. + +Đáng chú ý, sau khi điền tham số prompt SYSTEM trong mỗi nút, bạn còn cần nhớ bật bảng tham số prompt USER. Bạn cần nhấp vào biểu tượng `{x}` trong đó, chọn tham số `user_text` làm đầu vào người dùng, và thêm tiền tố `user input:` ở phía trước để đánh dấu biến này là đầu vào của người dùng, khi hỏi đáp sẽ kết hợp đầu vào ban đầu của người dùng và prompt tích hợp để phản hồi. + +Tương tự, để đảm bảo mọi thứ thuận lợi, bạn có thể nhấp vào mũi tên phát ở góc trên bên phải của nút để kiểm tra đối thoại cụ thể xác minh hiệu quả, ví dụ nói "tôi muốn uống trà sữa trân châu", xem phản hồi có đúng kỳ vọng không. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image65.png) + +Tiếp theo chúng ta xử lý giá trị đầu ra của LLM song song, trong bảng cấu hình của nút `Variable Aggregator`, tìm khu vực `ASSIGN VARIABLES` (phân bổ biến), nhấp vào sau đó lần lượt thêm các phản hồi mô hình lớn trước đó vào. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image66.png) + +Tiếp theo chúng ta cần tổng hợp tất cả các đầu ra, cuối cùng nhận được kết quả mong muốn, bao gồm đầu vào của người dùng, phân loại và phản hồi. Do chúng ta sử dụng Workflow thay vì Chatflow, nên không có nút Answer để chọn cho việc tổng hợp kết quả, chúng ta có thể chọn các nút khác để gián tiếp thực hiện tổng hợp và đầu ra kết quả, lúc này chọn nút Template, trong phần biến chỉ định kết quả phân loại ý định người dùng, giá trị đầu vào người dùng, phản hồi cuối cùng của biến tổng hợp, và viết mẫu định dạng json phản hồi cuối cùng trong CODE, chúng ta có thể nhận được: + +- `intent` ← `class_name` +- `original_text` ← `user_text` +- `final_reply` ← `variable_aggregator` + +``` +{ + "intent": "{{ intent }}", + "original_text": "{{ original_text }}", + "reply": {{ final_reply }} +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image67.png) + +Cuối cùng thêm nút output là hoàn thành tất cả các thao tác: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image68.png) + +#### Kiểm tra chạy workflow + +Hoàn thành, chúng ta có thể thử chạy hiệu quả của bộ workflow này. Nó có thể thể hiện các hành vi hoàn toàn khác nhau dựa trên các đầu vào khác nhau: + +- Đầu vào (gọi món): "Cho tôi một phần combo gà cay loại lớn, cola cỡ lớn." + - Đường dẫn: `buy_food` → `LLM_BuyFood` + - Đầu ra reply: "Vâng, một phần combo gà cay và cola cỡ lớn đã được ghi nhận cho bạn. Xin hỏi khoai tây chiên trong combo có cần đổi không?" +- Đầu vào (phàn nàn): "Các bạn也太 chậm rồi? Tôi đã đợi hơn một tiếng rồi!" + - Đường dẫn: `complain` → `LLM_Complain` + - Đầu ra reply: "Rất xin lỗi vì đã để bạn đợi lâu như vậy, đây确实是 sự sơ suất của chúng tôi, đã mang lại cho bạn trải nghiệm không tốt. Chúng tôi đang khẩn cấp kiểm tra tình trạng giao đơn hàng của bạn, và sẽ xin phúc lợi đền bù tương ứng, cảm ơn sự kiên nhẫn và phản hồi của bạn." +- Đầu vào (trò chuyện): "Hôm nay ăn gì cho lành mạnh?" + - Đường dẫn: `chitchat` → `LLM_Chitchat` + - Đầu ra reply: "Nếu theo đuổi sức khỏe, bạn có thể thử series salad nhẹ của chúng tôi, hoặc ức gà nướng kèm rau mùa. Bạn thích vị thanh đậm hơn một chút hay phong phú hơn một chút? Tôi có thể đưa ra đề xuất cụ thể hơn cho bạn." +- Đầu vào (nội dung không liên quan): "Giúp tôi nghĩ một câu chuyện vui cho cuộc họp ngày mai." + - Đường dẫn: `other` → `LLM_Other` + - Đầu ra reply: "Nghe có vẻ là một thử thách thú vị! Nhưng tôi chủ yếu là trợ lý đề xuất ẩm thực và gọi món. Nếu bạn cần gọi gì đó để tự thưởng cho bản thân làm việc vất vả, tôi luôn sẵn sàng giúp đỡ!" + +> Bug ẩn: Cần giải thích, nếu bạn gặp vấn đề kỳ lạ liên quan đến aggregation group, đây rất có thể là một bug tích hợp của Dify. Có thể được kích hoạt dưới thao tác cụ thể; nếu bạn từng bật lại tắt AGGREGATION GROUP, hệ thống có thể đã tạo cấu hình group và còn sót tham số bất thường liên quan, ngay cả khi công tắc hiện tại trông như đã tắt, các cấu hình sót này cũng có thể gây ra vấn đề, ví dụ xuất hiện lỗi liên quan đến tham số `any`. Lúc này bạn chỉ cần xóa nút đó và tạo lại là được. + +Sau khi chạy trong Test Run, chúng ta có thể thấy quá trình thực thi của workflow, lúc này đã đi theo đúng quy trình dựa trên phân loại, và nhận được kết quả output cuối cùng. Đến đây, toàn bộ quy trình hoàn thành. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image69.png) + +## 2.7 Chạy ứng dụng Workflow mẫu đầu tiên + +Kết thúc việc học workflow phân loại đơn giản, tiếp theo chúng ta cần học cách chạy workflow của người khác, chúng ta chỉ cần cải tạo nhẹ là có thể biến nó thành workflow của mình. Ở đây chúng ta chọn thử workflow DeepResearch chính thức, workflow này có thể giúp bạn xây dựng một khung tìm kiếm sâu, sử dụng mô hình lớn + công cụ tìm kiếm để cung cấp cho bạn một câu trả lời tìm kiếm phong phú, kết quả mỗi lần hỏi sẽ bao gồm địa chỉ trích dẫn tìm kiếm và kết quả đối thoại với mô hình lớn. + +Sau khi nhập, bước đầu tiên chạy trực tiếp, chúng ta sẽ giải quyết các vấn đề cụ thể dựa trên vị trí và nguyên nhân lỗi ở mỗi bước, nếu gặp vấn đề không thể giải quyết, bạn có thể chụp màn hình và hỏi mô hình lớn để giải quyết. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image70.png) + +Vừa vào cảm thấy rất phức tạp, không sao, chúng ta nhấp Preview ở góc trên bên phải để chạy workflow, cho đến khi xuất hiện lỗi: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image71.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image72.png) + +Chúng ta cần giải quyết vấn đề dựa trên nút báo lỗi, sau khi mở phát hiện là chưa cấu hình API Token của Tavily, API tìm kiếm của Tavily là một công cụ tìm kiếm được thiết kế riêng cho AI, cung cấp kết quả thời gian thực, chính xác và dựa trên sự thật. Lúc này thao tác theo hướng dẫn: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image73.png) + +Sau khi xử lý, công cụ tìm kiếm có thể hoạt động bình thường: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image74.png) + +Tiếp tục sửa chữa vấn đề do gọi mô hình gây ra, bạn sẽ nhận được kết quả như sau, tìm kiếm chi tiết kết hợp với khả năng hiểu của mô hình lớn: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image75.png) + +Chúng ta có thể thấy địa chỉ tài liệu tham khảo tương ứng ở cuối: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image76.png) + +Nếu bạn muốn hiểu vai trò của mỗi khâu, phương pháp tốt nhất là ghi lại output của mỗi khâu thành một biến, cuối cùng in kết quả của mỗi biến trung gian khi xuất, còn một phương pháp khác là bạn có thể tìm Process ở phía trên, nhấp vào có thể xem chi tiết của mỗi khâu: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image77.png) + +## 2.8 Sử dụng Dify làm nhà cung cấp API + +Tiếp theo, chúng ta sẽ thử gọi Agent cơ sở tri thức vừa tạo thông qua API, chúng ta muốn biến Dify thành một backend trung tâm mô hình lớn. + +Còn nhớ đã nói về cách gọi mô hình thông qua API không? Chúng ta cần chuẩn bị một khóa (Key) và một ví dụ gọi API (ví dụ request/response trong tài liệu), sau đó gửi những nội dung này cho mô hình lớn, để nó giúp chúng ta viết code gọi dịch vụ, và phân tích các trường cần thiết từ kết quả trả về. + +Lần này, chúng ta sẽ sử dụng công cụ chỉnh sửa code cục bộ [Trae](https://www.trae.cn/) để hoàn thành quá trình này. + +Nếu bạn chưa quen biết IDE là gì, có thể đọc tài liệu [Kiến thức bổ sung 4 - AI IDE và Trae là gì](https://github.com/datawhalechina/easy-vibe/blob/main/docs/extra/extra4/extra4-what-is-ai-ide-and-trae.md). + +Nếu môi trường phát triển cục bộ của bạn chưa được cấu hình hoàn chỉnh, cũng không cần lo lắng. Chỉ cần bạn tin tưởng trợ lý code của mình (dù là [z.ai](http://z.ai) hay Trae), khi gặp bất kỳ điều gì không hiểu hoặc lỗi, đều có thể trực tiếp gửi vấn đề cho nó, nó sẽ đưa ra giải pháp chi tiết dựa trên mô tả của bạn. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image78.png) + +Khu vực bên phải gọi là cửa sổ tương tác Copilot, hoặc cửa sổ Agent. Nếu bạn không nhìn thấy nó, có thể nhấp vào biểu tượng thanh bên ở góc trên bên phải để mở. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image79.png) + +Sau khi mở thanh bên, bạn sẽ thấy tùy chọn `Builder`. Đây chính là chế độ Agent. Bạn có thể đơn giản hiểu "Builder" là "chế độ phát triển" của [z.ai](http://z.ai), nó cũng có thể giúp bạn thao tác môi trường máy tính cục bộ, cài đặt phụ thuộc, mở trang web, v.v. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image80.png) + +Sau khi nhấp "Builder", bạn sẽ thấy chế độ "Chat" và chế độ "Builder with MCP". Chế độ Chat chủ yếu dùng để tương tác với thư mục hiện tại, hoặc đối thoại ngôn ngữ tự nhiên với mô hình lớn. (Bạn có thể mở một thư mục bằng cách nhấp "File" ở góc trên bên trái Trae, sau đó chỉnh sửa trong thư mục đó. Trong trường hợp này, tất cả các thao tác tạo file mới của Builder sẽ diễn ra trong thư mục này.) + +Chế độ Builder with MCP cung cấp thêm công cụ cho Agent (ví dụ cho phép mô hình lớn kết nối với phần mềm khác, lấy thông tin thời tiết, v.v.). Bạn có thể đơn giản hiểu MCP là một tập hợp khả năng giúp mô hình lớn tiện lợi gọi các công cụ bên ngoài. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image81.png) + +Trong khu vực phía dưới, bạn còn có thể thấy danh sách thả xuống chọn mô hình, có thể nhấp chuyển đổi các mô hình khác nhau. Ở đây bạn có thể chọn Kimi k2 hoặc GLM. Nếu bạn sử dụng phiên bản quốc tế Trae, cũng có thể chọn ChatGPT hoặc Claude. Tuy nhiên, với sự phát triển nhanh chóng của các mô hình lớn trong nước, năng lực tổng hợp của các mô hình Kimi, Qwen, GLM, v.v. đã cơ bản tiếp cận Claude 3.5 hoặc 3.7, đối với các kịch bản phát triển hàng ngày là hoàn toàn đủ dùng. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image82.png) + +Trên đây là giới thiệu tóm tắt về Trae. Tiếp theo, chúng ta có thể ôn lại các bước thao tác trong [z.ai](http://z.ai), và tái sử dụng tư duy này trong Trae. + +## 2.9 Sử dụng Dify API để tạo ứng dụng đối thoại frontend + +Nếu chúng ta muốn dùng API của Dify để xây dựng một ứng dụng chat frontend, đầu tiên cần lấy tài liệu API và địa chỉ gọi của Dify. + +Còn nhớ Agent vừa tạo không? Đầu tiên nhấp "Publish" ở góc trên bên phải, sau đó nhấp "Publish Update", cuối cùng nhấp "Access API Reference" để vào tài liệu API. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image83.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image84.png) + +Sau khi vào tài liệu API, tìm phần "Send Chat Message", nhấp vào, sau đó tìm ví dụ "Request" và "Response" ở bên phải và sao chép ra. + +Tại sao nhất định phải sao chép hai phần nội dung này? Vì chúng là "thông tin cốt lõi" của API: có Key, ví dụ yêu cầu và ví dụ trả về, chúng ta có thể để mô hình lớn giúp chúng ta tạo code gọi dịch vụ, và dựa trên cấu trúc trả về để trích xuất các trường cần thiết. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image85.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image86.png) + +Sau khi tìm thấy ví dụ Request và Response cần thiết cho cuộc hội thoại, chúng ta còn cần lấy một API Key. Ở góc trên bên phải tài liệu, bạn sẽ thấy tùy chọn liên quan đến "API key". + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image87.png) + +Nhấp "Create new Secret key", là có thể tạo API Key thuộc về bạn. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image88.png) + +Bây giờ mọi thứ đã sẵn sàng. Chúng ta sẽ gửi API Key, ví dụ Request và ví dụ Response vừa lấy cho Trae Builder. + +Lưu ý: Vui lòng thay `{DIFY_API_URL}` bằng địa chỉ API Dify thực tế. + +```json +key: +app-zKdCHUXXXXXXXX + +Please write me a front-end based on the following reference: + +curl -X POST 'http://{DIFY_API_URL}/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image89.png) + +Ở giai đoạn này, bạn có thể phát hiện chương trình được tạo ra không thể chạy bình thường trong một lần — ví dụ đối thoại xuất hiện lỗi kỳ lạ, hoặc không có kết quả trả về. Khi xuất hiện tình huống này, bạn có thể thử chuyển sang mô hình ngôn ngữ lớn khác, hoặc sao chép thông tin lỗi ra, mô tả vấn đề chi tiết, rồi gửi cho mô hình để nó tiếp tục lặp lại dựa trên phản hồi. + +Lúc này cách làm việc của bạn đã rất gần với quá trình phát triển thực tế. Trong phát triển hàng ngày, chúng ta thường xuyên gặp phải nhiều vấn đề khi hợp tác với mô hình lớn, để giải quyết tốt hơn các vấn đề này, chúng ta cần cung cấp thêm thông tin ngữ cảnh. Ngoài việc cung cấp thông tin lỗi, bạn còn có thể sao chép nội dung tài liệu đầy đủ hơn (ví dụ sao chép thêm mô tả trong phần "Send message" ở bên trái tài liệu), gửi tất cả cho mô hình, để nó đưa ra giải pháp hoàn chỉnh hơn dựa trên nhiều chi tiết hơn. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image90.png) + +Lúc này trình duyệt được nhúng bên trong Trae. Bạn có thể nhấp vào biểu tượng la bàn ở phía trên, mở trang web toàn màn hình trong trình duyệt bên ngoài. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image91.png) + +Nếu may mắn, bạn có thể nhận được một trang frontend có thể tương tác bình thường trong lần thử đầu tiên. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image92.png) + +Tuy nhiên, do bản thân mô hình lớn có tính ngẫu nhiên nhất định, đôi khi bạn có thể thuận lợi trong một vòng đối thoại, nhưng xuất hiện bất thường trong đối thoại nhiều vòng. Do đó, khuyến nghị bạn tiến hành kiểm tra đối thoại nhiều vòng, đảm bảo chương trình cũng hoạt động ổn định trong kịch bản tương tác nhiều vòng. + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image93.png) + +Đến đây, bạn đã học được cách xây dựng một Agent cơ sở tri thức Dify đơn giản, và sử dụng Trae thay thế [z.ai](http://z.ai) để xây dựng một frontend tương tác. Từ giờ trở đi, Trae sẽ trở thành công cụ phát triển chính khi chúng ta xây dựng nhiều nguyên mẫu, từng bước thay thế [z.ai](http://z.ai). Bạn có thể thử dùng Trae để tái thực hiện trò chơi rắn ăn quả trước đó, xem sẽ có trải nghiệm khác biệt như thế nào. Cố lên! + +# 3. Tham khảo workflow kinh doanh khác + +Bạn có thể sử dụng từ khóa tương tự `Dify workflow tham khảo` để tìm kiếm trên công cụ tìm kiếm, hoặc trực tiếp tìm kho chia sẻ workflow Dify trên Github để tra cứu workflow tham khảo (chất lượng không đồng đều, bạn cần xem nhiều kho khác nhau để học tập). Tất nhiên, cái gọi là workflow chỉ là ánh xạ SOP trên kinh doanh, bạn có thể suy nghĩ xem có quy trình nào trong công việc hàng ngày hoặc học tập có tính lặp lại và có thể cố định hóa, chỉ cần biến nó thành workflow là được. + +Dưới đây là một số tham khảo thiết kế workflow do mô hình lớn tạo (thực tế phương án thực hiện cũng khá tương tự, nói chung workflow do con người thiết kế sẽ không đẹp bằng workflow do mô hình lớn thiết kế, trừ khi là do chuyên gia thiết kế), nếu bạn thấy ý tưởng nào thú vị, có thể gửi cho mô hình lớn để tinh chỉnh thêm, để mô hình lớn giúp bạn đưa ra cài đặt nút workflow Dify cụ thể hơn, cùng với kết quả chi tiết bên trong. + +## 3.1 Workflow nền tảng truyền thông xã hội + +1. Workflow phân phát nội dung một lần đa nền tảng (phức tạp) + 1. Tư duy: Lấy một bài viết gốc làm "nguyên liệu", tự động gia công thành "thành phẩm" phù hợp với nhiều nền tảng. + 2. Thực hiện: `Start` nhập bài viết -> `LLM` chỉnh sửa -> song song nhiều nút `LLM` (mỗi nút Prompt đóng vai chuyên gia nền tảng cụ thể, như "chuyên gia văn bản viral Xiaohongshu", "người trả lời chuyên nghiệp Zhihu") -> nút `Iterator` xử lý vòng lặp yêu cầu định dạng các nền tảng khác nhau -> `Variable Aggregator` tổng hợp -> `Answer` xuất tất cả các phiên bản. Độ phức tạp nằm ở xử lý song song và lặp vòng. +2. Trình tạo chủ đề nóng và bản nháp (trung bình) + 1. Tư duy: Tự động nắm bắt chủ đề nóng trên mạng, nhanh chóng tạo chủ đề và bản nháp nội dung. + 2. Thực hiện: `Start` nhập từ khóa -> nút `Tool` gọi API công cụ tìm kiếm lấy chủ đề nóng -> `LLM` tóm tắt trích xuất 3-5 chủ đề -> `LLM` tạo dàn bài hoặc bản nháp. Độ phức tạp nằm ở tích hợp công cụ bên ngoài và lọc thông tin. +3. Trợ lý phân loại và phản hồi thông minh bình luận (phức tạp) + 1. Tư duy: Tự động phân tích cảm xúc và ý định bình luận, tạo đề xuất phản hồi phân loại. + 2. Thực hiện: Nút `HTTP Request` kết nối API truyền thông xã hội lấy bình luận -> nút `Question Classifier` hoặc `LLM` phân loại đa nhãn (tích cực, thắc mắc, khiếu nại, quảng cáo, v.v.) -> nút `Condition`判断 định tuyến đến chuỗi tạo phản hồi khác -> song song các nút `LLM` tạo bản nháp phản hồi cá nhân hóa -> `Answer` xuất. Độ phức tạp nằm ở nhánh điều kiện và gọi API thời gian thực. +4. Trình tự động tạo kịch bản và phân cảnh video ngắn (phức tạp) + 1. Tư duy: Dựa trên một chủ đề nóng hoặc mô tả sản phẩm, tự động tạo kịch bản video ngắn, mô tả phân cảnh và tag đề xuất. + 2. Thực hiện: `Start` nhập chủ đề -> `LLM` tạo kịch bản sáng tạo -> nút `LLM` thứ hai phân tách kịch bản thành chuỗi phân cảnh (mô tả hình ảnh, thoại, thời lượng) -> nút `Tool` gọi dịch vụ text-to-speech tạo mẫu giọng nói -> `Variable Aggregator` tích hợp tất cả các yếu tố -> `Answer` xuất file kịch bản có cấu trúc. Độ phức tạp nằm ở tuần tự hóa nhiều bước và tích hợp dịch vụ bên ngoài. +5. Trợ lý tóm tắt thời gian thực hỏi đáp tương tác livestream (trung bình) + 1. Tư duy: Xử lý thời gian thực bình luận văn bản trong phòng livestream, trích xuất câu hỏi cốt lõi và phản hồi của người xem. + 2. Thực hiện: Nút `HTTP Request` lấy bình luận livestream dạng luồng -> nút `Iterator` xử lý dữ liệu batch theo cửa sổ thời gian -> nút `LLM` tóm tắt thời gian thực các câu hỏi nóng và xu hướng cảm xúc trong từng khoảng thời gian -> nút `Answer` hoặc `Webhook` xuất tóm tắt cho người livestream. Độ phức tạp nằm ở xử lý dữ liệu luồng thời gian thực và cửa sổ vòng lặp. + +## 3.2 Workflow công sở + +1. Hệ thống biên bản cuộc họp thông minh và phân công nhiệm vụ tự động (phức tạp) + 1. Tư duy: Trích xuất biên bản từ văn bản ghi âm cuộc họp, và tự động tạo nhiệm vụ. + 2. Thực hiện: `Start` nhập văn bản cuộc họp -> `LLM` tóm tắt chủ đề và kết luận -> nút `Parameter Extractor` trích xuất chính xác Action Items (nhiệm vụ, người phụ trách, deadline) -> một `LLM` tổng hợp thành email biên bản -> song song nút `HTTP Request` gọi API Jira/Trello/Feishu để tạo nhiệm vụ. Độ phức tạp nằm ở trích xuất thông tin và liên động đa hệ thống. +2. Trợ lý sàng lọc hàng loạt CV và đánh giá sơ bộ (trung bình) + 1. Tư duy: Tự động phân tích CV, đánh giá mức độ phù hợp và tạo câu hỏi phỏng vấn. + 2. Thực hiện: `Start` tải lên file CV và JD -> nút `Document Extractor` phân tích văn bản CV -> `LLM` đóng vai HR đánh giá mức độ phù hợp -> với người phù hợp cao, một `LLM` khác tạo câu hỏi phỏng vấn chuyên sâu. Độ phức tạp nằm ở phân tích tài liệu và đánh giá đa điều kiện. +3. Dịch email đa ngôn ngữ và soạn thảo phản hồi một lần (đơn giản) + 1. Tư duy: Tự động dịch email và soạn thảo phản hồi. + 2. Thực hiện: `Start` nhập email -> `LLM` xác định ngôn ngữ và dịch -> `LLM` xây dựng ý chính phản hồi -> `LLM` dịch trở lại ngôn ngữ gốc và chỉnh sửa. Chủ yếu dựa vào gọi LLM tuần tự. +4. Tổng hợp dữ liệu báo cáo tuần/tháng tự động và tạo insight (phức tạp) + 1. Tư duy: Kết nối nhiều nguồn dữ liệu, tự động tạo báo cáo công việc có cấu trúc. + 2. Thực hiện: Nhiều nút `HTTP Request`/`Tool` song song gọi API hệ thống kinh doanh (như CRM, Git, công cụ quản lý dự án) lấy dữ liệu gốc -> nút `Code` hoặc `LLM` tiến hành làm sạch dữ liệu và tính toán cơ bản -> `LLM` phân tích xu hướng, điểm nổi bật và rủi ro, tạo báo cáo tự sự -> `Answer` xuất tài liệu có hình ảnh và văn bản. Độ phức tạp nằm ở tổng hợp đa nguồn dữ liệu, xử lý dữ liệu và kết hợp phân tích thông minh. +5. Kiểm tra thông minh hợp đồng/tài liệu và trích xuất ý chính (trung bình) + 1. Tư duy: Nhanh chóng kiểm tra tài liệu pháp lý hoặc thương mại, nhắc nhở rủi ro và trích xuất điều khoản cốt lõi. + 2. Thực hiện: `Start` tải lên PDF hợp đồng -> `Document Extractor` trích xuất văn bản -> nút `LLM` (đặt vai chuyên gia pháp lý) kiểm tra điều khoản trách nhiệm, điều kiện thanh toán, điều khoản vi phạm, v.v. -> nút `Parameter Extractor` trích xuất dữ liệu có cấu trúc như ngày chính, số tiền, bên nghĩa vụ, v.v. -> `Answer` xuất gợi ý rủi ro và bảng ý chính. Độ phức tạp nằm ở xử lý tài liệu dài và trích xuất thông tin có cấu trúc. + +## 3.3 Workflow học tập và cuộc sống + +1. Trình phân tích chuyên sâu bài báo học thuật và tạo ghi chú (phức tạp) + 1. Tư duy: Tải lên PDF bài báo, tự động tạo ghi chú có cấu trúc. + 2. Thực hiện: `Start` tải lên PDF -> `Document Extractor` trích xuất toàn văn -> song song nhiều nút `LLM` phân công tóm tắt tóm tắt, phương pháp, phát hiện, tài liệu tham khảo -> `Variable Aggregator` tổng hợp -> `Answer` xuất ghi chú Markdown. Độ phức tạp nằm ở xử lý song song các phần khác nhau của văn bản dài. + +2. Trình lập kế hoạch du lịch cá nhân hóa (trung bình) + 1. Tư duy: Dựa trên sở thích người dùng, tự động lên lịch trình chi tiết. + 2. Thực hiện: `Start` nhập nhu cầu (điểm đến, số ngày, ngân sách, sở thích) -> nút `Tool` gọi công cụ tìm kiếm hoặc API bản đồ lấy thông tin địa điểm -> `LLM` tích hợp thông tin, thiết kế lịch trình hàng ngày (bao gồm thời gian, hoạt động, ước tính ngân sách). Độ phức tạp nằm ở thu thập thông tin bên ngoài và lập kế hoạch có cấu trúc. + +3. Bạn đồng hành luyện tập tương tác học ngoại ngữ (đơn giản) + 1. Tư duy: Tạo bot đối thoại có thể đóng vai và sửa lỗi ngữ pháp. + 2. Thực hiện: Thiết lập vai AI -> `Start` nhận câu người dùng -> `LLM` thực hiện hai nhiệm vụ: phản hồi theo vai + sửa lỗi ngữ pháp và giải thích -> `Answer` xuất. Cốt lõi là chỉ thị đa nhiệm của LLM. + +4. Hệ thống hỏi đáp cơ sở tri thức cá nhân và gợi ý liên kết (phức tạp) + 1. Tư duy: Dựa trên các tài liệu, ghi chú, liên kết trang web bạn đã lưu, xây dựng một hệ thống thông minh có thể hỏi đáp và gợi ý kiến thức cũ liên quan. + 2. Thực hiện: Xử lý ngoại tuyến: sử dụng công cụ `Document Extractor` và `Embedding` để cắt nhỏ và vector hóa lưu trữ cơ sở tri thức cá nhân. Workflow trực tuyến: `Start` nhập câu hỏi -> nút `Retrieval` tìm đoạn kiến thức phù hợp nhất từ kho vector -> `LLM` tạo câu trả lời dựa trên ngữ cảnh đã truy xuất -> đồng thời, một nhánh khác sử dụng nội dung đã truy xuất làm đầu vào, thông qua `LLM` tạo danh sách gợi ý "kiến thức cũ liên quan" -> `Answer` hợp nhất xuất câu trả lời và gợi ý. Độ phức tạp nằm ở xây dựng quy trình Retrieval-Augmented Generation (RAG). + +5. Cố vấn theo dõi và điều chỉnh kế hoạch tập luyện/dinh dưỡng (trung bình) + 1. Tư duy: Dựa trên nhật ký dinh dưỡng và tập luyện hàng ngày do người dùng nhập, cung cấp phân tích dinh dưỡng và đề xuất tập luyện. + 2. Thực hiện: `Start` nhập nhật ký văn bản (ví dụ "Bữa trưa: ức gà 150g, một bát cơm, một ít rau; Tập luyện: squat 5 set") -> nút `Parameter Extractor` cố gắng cấu trúc dữ liệu đầu vào -> `LLM` đóng vai huấn luyện viên thể hình, phân tích摄入 dinh dưỡng có cân bằng không, lượng tập luyện có phù hợp không -> so sánh với mục tiêu dài hạn, đưa ra gợi ý tinh chỉnh (ví dụ "Lượng protein摄入 đầy đủ, khuyến nghị tăng thêm loại rau"). Độ phức tạp nằm ở việc trích xuất thông tin có cấu trúc từ nhật ký phi cấu trúc và cung cấp phản hồi cá nhân hóa. + +# 6. Hạn chế của nền tảng workflow + +Nền tảng workflow (hay còn gọi là nền tảng mã nguồn thấp) không phải là giải pháp万能. Mặc dù thân thiện với nhân viên kinh doanh, giảm ngưỡng lập trình trực tiếp, nhưng nhìn từ góc độ khác, "mã nguồn thấp" thường cũng là một dạng "mã nguồn cao" — người dùng vẫn cần hiểu các khái niệm, quy tắc và logic thao tác của nền tảng, bản thân điều này đã tạo thành một chi phí học tập mới. + +Có thể bạn muốn hỏi, nhiều workflow đơn giản thực ra chỉ là gọi hàm mô hình lớn được bao bọc trước, đầu ra của hàm trước làm đầu vào của hàm sau, bản chất vài dòng code là có thể giải quyết, tại sao cần bao bọc workflow nhiều lớp phức tạp như vậy? Ngược lại còn gây khó khăn cho việc gọi API. + +Bạn nói đúng. Trong bối cảnh phát triển nhanh của vibe coding hiện tại,借助 khả năng tạo code AI, việc trực tiếp đọc thậm chí tạo code đôi khi có thể hiệu quả hơn. Lý tưởng nhất, chúng ta hy vọng có thể dùng ngôn ngữ tự nhiên trực tiếp thao tác logic ứng dụng, đây mới là một nền tảng phần mềm hiện đại. Nhưng nền tảng workflow hiện tại chưa thực hiện được điều này, do đó nó tự nhiên tồn tại một "lớp trung gian" giữa ý định người dùng và thực hiện cuối cùng. Nắm vững lớp trung gian này, chính là một chi phí cần đầu tư thời gian học tập. Lý tưởng là, nền tảng workflow sau này cũng phải hỗ trợ thao tác đối thoại AI hoàn toàn tự động, chúng ta có thể để AI thực sự thao tác xây dựng workflow và mọi khâu chi tiết tham số đầu vào. + +Mặc dù vậy, việc thành thạo sử dụng các nền tảng loại này đang dần trở thành một kỹ năng cơ bản, giống như phần mềm văn phòng Microsoft, rất phổ biến và thực tế trong kinh doanh, đáng để nắm vững. + +Trong khóa học nâng cao tiếp theo, chúng ta sẽ giới thiệu cách xây dựng thông qua nền tảng phát triển workflow và RAG cấp code. Lúc đó, bạn có thể trực tiếp trải nghiệm sự khác biệt về độ phức tạp và tính linh hoạt giữa các phương pháp thực hiện khác nhau. (Đáng chú ý, một số ứng dụng đối thoại đơn giản hoặc logic lồng nhau, dùng workflow thực hiện có thể không khó.) + +# Bài tập về nhà + +## Nắm vững thao tác cơ bản Dify + +Để kiểm tra bạn đã nắm vững các công cụ sử dụng cơ bản phổ biến của Dify, bạn cần hoàn thành một bài tập cơ bản và hai "thử thách nhỏ", đảm bảo bạn đã nhập môn các thao tác phổ biến. Bạn cần nhập hai file DSL đính kèm vào workflow Dify, và hoàn thành thành công thử thách workflow tương ứng (khi gặp chỗ không hiểu hãy chụp màn hình hỏi mô hình lớn, hoặc tự khám phá cách sử dụng mỗi tham số, cuối cùng đạt được mục tiêu): + +1. Tham khảo phương pháp workflow phân loại ý định, để mô hình lớn gợi ý hoàn toàn đổi sang một kịch bản khác để ứng dụng, nhưng nhất định phải sử dụng workflow phân loại ý định, cuối cùng nộp ảnh chụp màn hình workflow đang chạy, mô tả kịch bản và kết quả. +2. Thử thách giải mã Log in workflow + +Trong thử thách giải mã này, bạn cần hoàn thành các thử thách sau, để workflow thực hiện các chức năng: + +- Tìm ra mật khẩu đúng! +- Thay đổi mật khẩu thành 0925 +- Khi mật khẩu không chính xác, cung cấp cơ hội thử lần thứ hai (không cung cấp lần thứ ba) +- Khi người dùng đề cập muốn đăng nhập lại, cung cấp cho người dùng cơ hội nhập lại mật khẩu + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image94.png) + +Tham khảo đầu vào và đầu ra: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image95.png) + +3. Thử thách giải mã Love loop workflow + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image96.png) + +Trong thử thách giải mã này, bạn cần sửa chữa vấn đề của workflow hiện tại, để đầu ra cuối cùng của workflow hiển thị tương tự như sau: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image97.png) + +Nếu bạn gặp vấn đề không thể giải quyết, hãy chụp màn hình hỏi mô hình lớn, hoặc tra cứu tài liệu chính thức để nhận kết quả: [https://docs.dify.ai/en/use-dify/getting-started/quick-start](https://docs.dify.ai/en/use-dify/getting-started/quick-start) + +## Thực hiện gọi Dify API + +Để kiểm tra bạn đã thực sự nắm vững kiến thức gọi API Dify, bạn cần hoàn thành các nhiệm vụ sau: + +1. Triển khai Dify và tạo một cơ sở tri thức đơn giản (chọn tài liệu bạn thích). +2. Sử dụng Trae IDE để xây dựng một frontend đối thoại, tương tác API với cơ sở tri thức Dify. +3. Kiểm tra hiệu quả đối thoại nhiều vòng, đảm bảo chương trình hoạt động bình thường. + +Bạn cần nộp ảnh chụp màn hình chạy cuối cùng và ảnh chụp màn hình quá trình xử lý cơ sở tri thức. + +## Thử workflow bên thứ ba / Xây dựng một workflow kinh doanh của riêng mình + +Hãy tìm workflow Dify của người khác mà bạn muốn thử trên Github, tài khoản WeChat chính thức, hoặc Reddit, Twitter, v.v., tải về nhập vào và chạy thành công; hoặc bạn có thể dựa trên tham khảo workflow kinh doanh đề cập ở phần trước, tạo một workflow kinh doanh riêng dựa trên nhu cầu cụ thể trong thực tế để chạy. + +Cuối cùng bạn cần nộp ảnh chụp màn hình chạy thành công, và mô tả vai trò của workflow này. + +# [Bug] Phương pháp giải quyết lỗi yêu cầu HTTP + +Nếu bạn gặp vấn đề như hình dưới, mới cần tham khảo giải pháp trong phần này, nếu không có thể bỏ qua phần hiện tại. + +Đôi khi có thể bạn triển khai Dify trên máy chủ của mình, nhưng địa chỉ bên ngoài của máy chủ thường là http thay vì https, nhưng khi chúng ta yêu cầu một dịch vụ chỉ hỗ trợ HTTP, bạn có thể thấy gợi ý tương tự như sau (bật chế độ thông tin gỡ lỗi F12 trình duyệt, xem điểm có vấn đề): + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image98.png) + +Nguyên nhân xuất hiện vấn đề này, là vì chúng ta mặc định triển khai Dify trên một máy chủ chỉ hỗ trợ HTTP mà không hỗ trợ HTTPS. HTTPS (HyperText Transfer Protocol Secure) là HTTP (Giao thức truyền tải siêu văn bản) cộng thêm lớp mã hóa SSL/TLS, có thể đơn giản hiểu là "phiên bản HTTP an toàn hơn". + +Nếu muốn dịch vụ hỗ trợ HTTPS, thường có thể: + +- Sử dụng chương trình khác chuyển tiếp yêu cầu (ví dụ làm reverse proxy trên nginx có chứng chỉ), hoặc +- Gắn tên miền sau đó xin chứng chỉ cho tên miền đó. + +Nhưng các thao tác này đều khá phức tạp, ở đây chúng ta sử dụng Zeabur làm gateway chuyển tiếp mạng để giải quyết vấn đề. + +Trang web của Zeabur mặc định truy cập thông qua HTTPS, do đó chúng ta chỉ cần chuyển tiếp tên miền yêu cầu ban đầu đến tên miền Zeabur cung cấp, là có thể sửa lỗi này. + +- Địa chỉ gốc: `http://{DIFY_API_URL}/v1/chat-messages` +- Địa chỉ mới: `https://{DIFY_NEW_API_URL}.zeabur.app/v1/chat-messages` + +Bạn chỉ cần đơn giản thay phần tên miền trong URL (IP công khai hoặc tên miền) bằng tên miền đã triển khai trên Zeabur là được, chúng ta đã cấu hình sẵn chức năng chuyển tiếp trong dịch vụ. + +Nếu bạn hứng thú, cũng có thể tự triển khai một dịch vụ chuyển tiếp trên Zeabur. Khi tạo dịch vụ trong Zeabur, chọn Python, sau đó điền code Python dưới đây, triển khai xong là có thể nhận được một địa chỉ https, https có thể sử dụng bình thường. + +Sau khi triển khai xong, trong cài đặt mạng đặt cổng nghe của chương trình thành 8080 cục bộ, và mở cổng đó ra ngoài. + +Lưu ý: Vui lòng thay `{DIFY_API_URL}` bằng địa chỉ API Dify thực tế. + +```python +from flask import Flask, request, Response +import requests + +app = Flask(__name__) + +TARGET_BASE_URL = "{DIFY_API_URL}" +LISTEN_PORT = 8080 + +@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +@app.route('/', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +def proxy_request(path): + target_url = f"{TARGET_BASE_URL}/{path}" + if request.query_string: + target_url += f"?{request.query_string.decode('utf-8')}" + + headers = {key: value for key, value in request.headers if key.lower() not in ['host', 'connection', 'content-length', 'accept-encoding']} + + try: + resp = requests.request( + method=request.method, + url=target_url, + headers=headers, + data=request.get_data(), + cookies=request.cookies, + allow_redirects=False, + timeout=30 + ) + + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + response_headers = [(name, value) for name, value in resp.raw.headers.items() if name.lower() not in excluded_headers] + + return Response(resp.content, resp.status_code, response_headers) + + except requests.exceptions.RequestException as e: + print(f"Error forwarding request to {target_url}: {e}") + return Response(f"Proxy Error: Could not reach target server or invalid response: {e}", status=502) + except Exception as e: + print(f"An unexpected error occurred: {e}") + return Response(f"Internal Proxy Error: {e}", status=500) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=LISTEN_PORT, debug=True) +``` \ No newline at end of file diff --git a/docs/vi-vn/stage-2/assignments/copywriting-platform-supabase/index.md b/docs/vi-vn/stage-2/assignments/copywriting-platform-supabase/index.md new file mode 100644 index 0000000..31cdc3c --- /dev/null +++ b/docs/vi-vn/stage-2/assignments/copywriting-platform-supabase/index.md @@ -0,0 +1,346 @@ +# Thực chiến phát triển SaaS AI tạo văn bản marketing + +## Tổng quan + +Dự án thực chiến này yêu cầu bạn xoay quanh một PRD thực tế, hoàn thành từ con số không một sản phẩm SaaS AI tạo văn bản marketing dành cho nhà phát triển độc lập và đội nhóm nội dung. Bạn sẽ sử dụng Supabase làm dịch vụ backend, Stripe làm hệ thống thanh toán, hoàn thành toàn bộ quá trình từ phân tích yêu cầu đến triển khai lên mạng. + +Đây là phần thực chiến tổng hợp của Stage 2. Trong các chương trước, bạn đã học riêng biệt các kỹ năng đơn lẻ như搭建 trang frontend, phát triển interface backend, thao tác cơ sở dữ liệu, tích hợp thanh toán — dự án này yêu cầu bạn kết nối tất cả lại, bàn giao một nguyên mẫu sản phẩm có thể chạy được. + +## Kiến thức tiên quyết + +Trước khi bắt đầu dự án này, bạn nên đã nắm vững các nội dung sau: + +- Thiết kế trang frontend và sử dụng thư viện component ([Thiết kế UI](../../frontend/ui-design/), [Thư viện component hiện đại](../../frontend/modern-component-library/)) +- Thiết kế và phát triển interface backend ([Viết mã interface](../../backend/ai-interface-code/)) +- Cơ sở dữ liệu cơ bản và Supabase ([Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/)) +- Tích hợp thanh toán ([Hệ thống thanh toán Stripe](../../backend/stripe-payment/)) +- Quy trình làm việc Git và triển khai ([Học sử dụng Git và Github](../../backend/git-workflow/), [Triển khai ứng dụng web](../../backend/zeabur-deployment/)) + +## Mục tiêu học tập + +Sau khi hoàn thành thực chiến này, bạn sẽ có thể: + +1. Đọc và hiểu một PRD thực tế, từ đó trích xuất danh sách nhiệm vụ phát triển +2. Sử dụng AI hỗ trợ tạo trang frontend và interface backend từng bước +3. Sử dụng Supabase thực hiện xác thực người dùng, thao tác cơ sở dữ liệu +4. Tích hợp Stripe thực hiện chức năng đăng ký trả phí +5. Xây dựng trang quản lý backend và hoàn thành tích hợp end-to-end + +## Giới thiệu dự án + +Sản phẩm bạn cần xây dựng là một SaaS AI tạo văn bản marketing, bao gồm ba hệ thống con: + +| Hệ thống con | Trách nhiệm | +|--------|------| +| **Trang chủ frontend** | Giới thiệu sản phẩm, giá cả, FAQ, chuyển đổi đăng ký | +| **Bàn làm việc người dùng** | Nhập thông tin sản phẩm, tạo văn bản, xem lịch sử, nâng cấp gói | +| **Bảng quản lý backend** | Quản lý người dùng, bản ghi tạo, dữ liệu thanh toán, tổng quan vận hành | + +Backend sử dụng Supabase cung cấp cơ sở dữ liệu và xác thực, Stripe xử lý thanh toán, mô hình AI tạo văn bản marketing. + +::: tip Lối vào PRD +Tài liệu yêu cầu của dự án này trên GitHub: [Xem PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/copywriting-platform-supabase/PRD.md) +::: + +
+ + + +
+ +## Phần 1: Phân tích yêu cầu + +### 1.1 Đọc PRD + +Mở tài liệu PRD, tập trung trả lời các câu hỏi sau: + +- Hệ thống có mấy lối vào? Mỗi cái bao phủ những trang nào? +- Chức năng cốt lõi của mỗi trang là gì? +- Backend bao gồm những module và bảng dữ liệu nào? +- Thiết kế giá gói, quy trình thanh toán, hạn mức miễn phí như thế nào? +- Phạm vi MVP là gì? Phiên bản đầu tiên làm gì, không làm gì? + +::: warning +Nếu các câu hỏi trên chưa có câu trả lời rõ ràng, đừng bắt đầu viết code. Hiểu không rõ yêu cầu là nguyên nhân phổ biến nhất dẫn đến phải làm lại. +::: + +### 1.2 Xác nhận kiến trúc hệ thống + +Dựa trên PRD, sắp xếp kiến trúc tổng thể của hệ thống: + +```mermaid +flowchart TD + prd["PRD"] --> web["Trang chủ frontend"] + prd --> app["Bàn làm việc người dùng"] + prd --> admin["Bảng quản lý backend"] + app --> auth["Xác thực"] + app --> gen["Nhiệm vụ tạo văn bản"] + gen --> db["Cơ sở dữ liệu"] + billing["Thanh toán & Gói"] --> db + admin --> analytics["Bảng điều khiển Người dùng / Tạo / Thanh toán"] +``` + +## Phần 2: Xây dựng khung dự án + +### 2.1 Tạo trang frontend + +Sử dụng AI tạo trước cấu trúc cơ bản và dữ liệu giả cho tất cả các trang. + +Tham khảo prompt: + +```text +Dựa trên PRD hiện tại, giúp tôi tạo khung frontend cho một SaaS AI tạo văn bản marketing. + +Yêu cầu: +1. Chia thành ba lối vào: www, app, admin +2. Trang chủ bao gồm: trang chính, giá cả, FAQ +3. app bao gồm: đăng nhập, đăng ký, bàn làm việc tạo, lịch sử, trang gói +4. admin bao gồm: trang chính backend, quản lý người dùng, bản ghi tạo, đơn hàng thanh toán +5. Trước tiên chỉ tạo cấu trúc trang và dữ liệu giả, không kết nối interface thực +6. Phong cách giống SaaS hiện đại, không giống demo lớp học +``` + +### 2.2 Hoàn thiện trang cốt lõi + +Sau khi搭建 khung, tập trung hoàn thiện trang bàn làm việc tạo văn bản (Dashboard): + +```text +Xin tiếp tục hoàn thiện trang /dashboard. + +Đây là bàn làm việc AI tạo văn bản marketing. + +Các trường form bên trái: +- Tên sản phẩm +- Giới thiệu một câu +- Người dùng mục tiêu +- 3 điểm bán hàng +- Kênh投放 (trang chủ, moments, Xiaohongshu, Douyin, email) + +Vùng kết quả bên phải dự phòng: +- Tiêu đề chính +- Tiêu đề phụ +- CTA +- 3 phiên bản văn bản ngắn +- Văn bản dài + +Trước tiên dùng mock data chạy thông tương tác. + +Yêu cầu: +- Sau khi nhấp "Tạo văn bản" có trạng thái loading +- Vùng kết quả thiết kế trạng thái trống +- Layout responsive, màn hình rộng và hẹp đều hiển thị bình thường +``` + +### 2.3 Xác minh cấu trúc trang + +Kiểm tra từng mục: + +- [ ] Route của ba lối vào có độc lập không +- [ ] Số lượng trang có nhất quán với PRD không +- [ ] Layout vùng form và vùng kết quả của Dashboard có hợp lý không +- [ ] Dữ liệu giả đã thể hiện trạng thái UI cơ bản chưa + +### Gặp trở ngại? + +Nếu bạn bị kẹt ở giai đoạn搭建 frontend, có thể ôn lại các chương sau: + +- [Thiết kế UI](../../frontend/ui-design/) +- [Thiết kế trang và nút bấm theo quy chuẩn UI](../../frontend/multi-product-ui/) +- [Làm cho giao diện đẹp hơn bằng LLM và Skills](../../frontend/llm-skills-beautiful/) +- [Từ nguyên mẫu thiết kế đến code dự án](../../frontend/design-to-code/) +- [Cập nhật giao diện với thư viện component hiện đại](../../frontend/modern-component-library/) + +## Phần 3: Tích hợp Backend + +### 3.1 Kết nối đăng nhập Supabase + +```text +Xin coi tôi là người mới bắt đầu hoàn toàn, hướng dẫn tôi từng bước hoàn thành kết nối đăng nhập Supabase. + +Cần bạn giúp tôi hoàn thành: +1. Kết nối dự án với Supabase +2. Thực hiện chức năng đăng ký, đăng nhập, đăng xuất +3. Sau khi đăng nhập thành công chuyển đến /dashboard +4. Người dùng chưa đăng nhập truy cập /dashboard, /billing, /admin tự động chuyển đến /login +5. Tạo bảng profiles +6. Sau khi người dùng đăng ký thành công tự động tạo bản ghi trong bảng profiles +7. Bảng profiles bao gồm các trường email, role, plan + +Yêu cầu thực hiện: +- Mỗi bước đều nói rõ đang sửa những file nào +- Không hardcode key +- Nơi cần thao tác thủ công trong trang quản lý Supabase hãy đánh dấu rõ +- Sau khi hoàn thành nói rõ cách xác minh đăng ký và đăng nhập +``` + +### 3.2 Kết nối interface tạo và cơ sở dữ liệu + +```text +Xin coi tôi là người mới bắt đầu hoàn toàn, giúp tôi hoàn thành chức năng cốt lõi của trang web: tạo và lưu văn bản marketing. + +Hiệu quả mục tiêu: +1. Người dùng điền form tại /dashboard, nhấp "Tạo văn bản" +2. Backend nhận: tên sản phẩm, giới thiệu, người dùng mục tiêu, điểm bán hàng, kênh投放 +3. Backend gọi mô hình tạo kết quả +4. Trang hiển thị kết quả tạo +5. Đầu vào và đầu ra đều lưu vào cơ sở dữ liệu +6. Người dùng lần sau vào có thể xem lịch sử + +Cần bạn hoàn thành: +- Tạo interface tạo /api/generate +- Tạo bảng generations +- Thiết kế trường đầu vào và đầu ra +- Trang Dashboard đọc lịch sử của người dùng hiện tại + +Trải nghiệm người dùng: +- Trạng thái loading của nút +- Thông báo lỗi khi tạo thất bại +- Trạng thái trống khi không có lịch sử + +Sau khi hoàn thành xin nói rõ: +- Vị trí file trang frontend +- Vị trí file interface backend +- Vị trí logic ghi dữ liệu vào cơ sở dữ liệu +- Cách kiểm tra liên kết tạo hoàn chỉnh +``` + +### 3.3 Kết nối thanh toán Stripe + +```text +Xin coi tôi là người mới bắt đầu hoàn toàn, giúp tôi thêm thanh toán Stripe đơn giản nhất cho LaunchKit. + +Không cần hệ thống phức tạp, trước tiên chạy thông liên kết thanh toán cơ bản nhất. + +Cần bạn hoàn thành: +1. Trang /billing hiển thị hai gói free và pro +2. Sau khi người dùng nhấp nâng cấp chuyển đến Stripe Checkout +3. Sau khi thanh toán thành công quay lại trang web +4. Kết quả thanh toán lưu vào bảng subscriptions +5. Đồng bộ cập nhật trường profile.plan +6. Người dùng free giới hạn 3 lần tạo mỗi ngày, người dùng pro không giới hạn + +Nguyên tắc thực hiện: +- Trước tiên chạy thông quy trình chính, tạm không xem xét biên phức tạp +- Nơi cần cấu hình trong trang quản lý Stripe hãy viết rõ +- Sau khi hoàn thành nói rõ cách kiểm tra quy trình thanh toán hoàn chỉnh +``` + +### 3.4 Xây dựng trang quản lý backend + +```text +Xin coi tôi là người mới bắt đầu hoàn toàn, giúp tôi làm một trang quản lý backend đơn giản và sử dụng được. + +Chỉ dành cho quản trị viên truy cập. + +Cần bạn hoàn thành: +1. Chỉ người dùng có role = admin mới có thể truy cập /admin +2. Backend bao gồm 3 Tab: danh sách người dùng, bản ghi tạo, trạng thái đăng ký +3. Danh sách người dùng hiển thị: email, plan, thời gian tạo +4. Bản ghi tạo hiển thị: người dùng, tên sản phẩm, kênh, thời gian tạo +5. Trạng thái đăng ký hiển thị: người dùng, gói, trạng thái thanh toán + +Yêu cầu: +- Giao diện đơn giản rõ ràng +- Sử dụng bảng, Tab, Badge của thư viện component hiện có +- Sau khi hoàn thành nói rõ cách đặt tài khoản thành admin +``` + +### Gặp trở ngại? + +Nếu bạn bị kẹt ở giai đoạn phát triển backend, có thể ôn lại các chương sau: + +- [Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/) +- [Mô hình lớn hỗ trợ viết mã giao diện và tài liệu giao diện](../../backend/ai-interface-code/) +- [Cách tích hợp hệ thống thanh toán Stripe](../../backend/stripe-payment/) + +## Phần 4: Tích hợp và lên mạng + +### 4.1 Kiểm thử end-to-end + +Ít nhất xác minh các kịch bản sau: + +- Đăng ký -> Đăng nhập -> Tạo văn bản -> Xem lịch sử -> Nâng cấp gói +- Quản trị viên đăng nhập -> Xem dữ liệu người dùng -> Xem bản ghi tạo -> Xem trạng thái thanh toán + +Kiểm tra trước khi triển khai: + +```text +Xin coi tôi là người mới bắt đầu hoàn toàn, giúp tôi kiểm tra dự án có đủ điều kiện triển khai chưa. + +Trọng tâm kiểm tra: +- Biến môi trường đã đầy đủ chưa +- Địa chỉ callback đăng nhập đã chính xác chưa +- Địa chỉ callback thanh toán Stripe đã chính xác chưa +- Trang có thiếu loading, trạng thái trống, thông báo lỗi không +- README có bao gồm hướng dẫn khởi động và triển khai không + +Cần bạn: +1. Liệt kê các mục cần sửa theo mức độ ưu tiên +2. Đánh dấu những cái cần sửa trước +3. Nêu rõ các bước triển khai sau khi sửa +``` + +### 4.2 Triển khai + +Triển khai dự án lên môi trường mạng công cộng. Hướng dẫn triển khai tham khảo: [Học sử dụng Git và Github](../../backend/git-workflow/), [Triển khai ứng dụng web](../../backend/zeabur-deployment/). + +## Sản phẩm bàn giao + +Sau khi hoàn thành dự án này, bạn cần nộp các nội dung sau: + +- [ ] Liên kết demo trực tuyến có thể truy cập +- [ ] Liên kết kho mã nguồn (bao gồm README) +- [ ] Tài liệu PRD +- [ ] Screenshot các trang cốt lõi (trang chủ, Dashboard, Billing, Admin) +- [ ] Video demo 60 giây (bao gồm đăng ký -> tạo -> thanh toán -> backend) + +README ít nhất bao gồm: giới thiệu dự án, mô tả trang cốt lõi, tech stack, bước khởi động cục bộ, danh sách biến môi trường. + +## Tiêu chí chấm điểm + +| Chiều | Yêu cầu cơ bản | Yêu cầu nâng cao | +|------|---------|---------| +| Độ hoàn thiện sản phẩm | Trang chủ, đăng nhập, Dashboard, Billing, Admin đều có thể truy cập | Văn bản và phong cách thị giác trang chủ giống SaaS thực tế | +| Vòng lặp nghiệp vụ | Đăng ký -> đăng nhập -> tạo -> xem lịch sử có thể chạy thông | Sự khác biệt quyền Free/Pro rõ ràng có thể nhìn thấy | +| Tính chính xác dữ liệu | Kết quả tạo và trạng thái thanh toán đều ghi vào cơ sở dữ liệu | Có thông báo lỗi rõ ràng, trạng thái trống và loading | +| Quyền & an ninh | Người dùng chưa đăng nhập không thể truy cập trang được bảo vệ, người dùng thường không vào được Admin | Có xác thực đầu vào cơ bản và xác thực server-side | +| Bàn giao kỹ thuật | Dự án có thể khởi động cục bộ, cũng có thể triển khai lên mạng công cộng | README rõ ràng, video demo có cấu trúc hoàn chỉnh | + +::: tip +Nếu bạn thấy nhiệm vụ quá lớn, hãy nhớ một nguyên tắc: **Trước đảm bảo "chạy được", rồi mới theo đuổi "làm đẹp".** +::: + +## Kiểm tra trước khi nộp + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## Tài liệu tham khảo + +- [Thiết kế UI](../../frontend/ui-design/) +- [Thiết kế trang và nút bấm theo quy chuẩn UI](../../frontend/multi-product-ui/) +- [Làm cho giao diện đẹp hơn bằng LLM và Skills](../../frontend/llm-skills-beautiful/) +- [Từ nguyên mẫu thiết kế đến code dự án](../../frontend/design-to-code/) +- [Cập nhật giao diện với thư viện component hiện đại](../../frontend/modern-component-library/) +- [Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/) +- [Mô hình lớn hỗ trợ viết mã giao diện và tài liệu giao diện](../../backend/ai-interface-code/) +- [Học sử dụng Git và Github](../../backend/git-workflow/) +- [Triển khai ứng dụng web](../../backend/zeabur-deployment/) +- [Cách tích hợp hệ thống thanh toán Stripe](../../backend/stripe-payment/) diff --git a/docs/vi-vn/stage-2/assignments/custom-dify-agent-platform/index.md b/docs/vi-vn/stage-2/assignments/custom-dify-agent-platform/index.md new file mode 100644 index 0000000..edce37a --- /dev/null +++ b/docs/vi-vn/stage-2/assignments/custom-dify-agent-platform/index.md @@ -0,0 +1,210 @@ +# Thực hành phát triển nền tảng Agent thông minh kiểu Dify + +## Tổng quan + +Dự án thực chiến này yêu cầu bạn hoàn thành một nền tảng Agent thông minh mô phỏng trải nghiệm cốt lõi của Dify dựa trên một PRD thực tế, xây dựng từ đầu. Bạn sẽ xây dựng bảng điều khiển người dùng, back-office quản trị và backend nền tảng, triển khai các chức năng cốt lõi như quản lý Agent, hội thoại, nhật ký và cơ sở tri thức. + +Đây là phần thực hành tổng hợp của Stage 2. Khác với các dự án trang đơn hoặc chức năng đơn lẻ trước đó, dự án này yêu cầu bạn xây dựng một sản phẩm AI có "cảm giác nền tảng" — bao gồm đa vai trò, đa module, lưu trữ dữ liệu bền vững và chuỗi gọi mô hình. + +## Kiến thức tiên quyết + +Trước khi bắt đầu dự án này, bạn nên đã nắm được các nội dung sau: + +- Thiết kế trang frontend và sử dụng thư viện component ([Thiết kế UI](../../frontend/ui-design/), [Thư viện component hiện đại](../../frontend/modern-component-library/)) +- Thiết kế và phát triển API backend ([Viết code API](../../backend/ai-interface-code/)) +- Cơ sở dữ liệu cơ bản và Supabase ([Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/)) +- Quy trình làm việc Git và triển khai ([Git và GitHub](../../backend/git-workflow/), [Triển khai ứng dụng Web](../../backend/zeabur-deployment/)) + +## Mục tiêu học tập + +Sau khi hoàn thành bài thực hành này, bạn sẽ có thể: + +1. Đọc và hiểu một PRD thực tế, từ đó trích xuất danh sách công việc phát triển +2. Thiết kế kiến trúc trang và mô hình dữ liệu cho nền tảng Agent +3. Triển khai chuỗi hoàn chỉnh tạo Agent, hội thoại, ghi nhật ký +4. Sử dụng AI hỗ trợ phát triển sản phẩm kiểu nền tảng +5. Hoàn thành liên hợp đầu cuối, bàn giao một nguyên mẫu nền tảng AI có thể demo + +## Giới thiệu dự án + +Sản phẩm bạn cần xây dựng là một nền tảng Agent thông minh kiểu Dify, bao gồm hai hệ thống con: + +| Hệ thống con | Trách nhiệm | +|--------|------| +| **Bảng điều khiển người dùng** | Tạo Agent, cấu hình Prompt, khởi động hội thoại, xem nhật ký, quản lý cơ sở tri thức | +| **Back-office quản trị** | Xem dữ liệu người dùng, tình hình sử dụng tài nguyên nền tảng, thống kê lượt gọi | + +Backend cần hỗ trợ các khả năng cốt lõi sau: quản lý Agent, quản lý phiên hội thoại, lưu trữ tin nhắn, gọi mô hình, ghi nhật ký lượt gọi, kết nối cơ sở tri thức. + +::: tip Đường dẫn PRD +Tài liệu yêu cầu của dự án này nằm trên GitHub: [Xem PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/custom-dify-agent-platform/PRD.md) +::: + +
+ + + +
+ +## Phần 1: Phân tích yêu cầu + +### 1.1 Đọc PRD + +Mở tài liệu PRD, tập trung trả lời các câu hỏi sau: + +- Agent, phiên hội thoại, nhật ký, cơ sở tri thức — cái nào cần vào MVP? +- Danh sách trang và định tuyến đã chốt chưa? +- Ranh giới giữa gọi mô hình và ghi nhật ký là gì? +- Đa tenant và workflow phức tạp có nên tạm thời không làm không? + +::: warning +Nếu các câu hỏi trên chưa có câu trả lời rõ ràng, đừng bắt đầu viết code. Hiểu sai yêu cầu là nguyên nhân phổ biến nhất dẫn đến phải làm lại. +::: + +### 1.2 Xác nhận kiến trúc hệ thống + +Dựa trên PRD, hệ thống hóa kiến trúc tổng thể của hệ thống: + +```mermaid +flowchart TD + prd["PRD"] --> app["Bảng điều khiển người dùng"] + prd --> admin["Back-office quản trị"] + app --> auth["Xác thực"] + app --> agent["Cấu hình Agent"] + app --> chat["Phiên hội thoại"] + chat --> llm["Gọi mô hình"] + chat --> db["Cơ sở dữ liệu"] + app --> kb["Kết nối cơ sở tri thức"] + admin --> logs["Nhật ký lượt gọi & tổng quan nền tảng"] + logs --> db +``` + +## Phần 2: Xây dựng khung dự án + +### 2.1 Tạo trang frontend + +Tham khảo prompt: + +```text +Vui lòng dựa trên PRD hiện tại, giúp tôi tạo khung frontend của nền tảng Agent thông minh kiểu Dify. + +Yêu cầu: +1. Phía người dùng bao gồm: đăng nhập, danh sách Agent, cấu hình Agent, trang hội thoại, trang nhật ký, trang cơ sở tri thức +2. Phía back-office bao gồm: trang chủ back-office, tổng quan người dùng, tổng quan sử dụng tài nguyên +3. Trước tiên chỉ tạo cấu trúc trang và dữ liệu giả, không kết nối API thực tế +4. Phong cách phải giống nền tảng AI hiện đại +``` + +### 2.2 Xác minh cấu trúc trang + +Kiểm tra từng mục: + +- [ ] Điểm vào bảng điều khiển người dùng và back-office quản trị đã tách biệt +- [ ] Trang danh sách Agent, cấu hình, hội thoại, nhật ký, cơ sở tri thức đã hoàn chỉnh +- [ ] Trang chủ back-office, trang tổng quan người dùng có thể truy cập +- [ ] Dữ liệu giả hiển thị trạng thái UI cơ bản + +## Phần 3: Phát triển lặp + +### 3.1 Triển khai theo module + +Trên cơ sở khung, bổ sung chức năng theo thứ tự module sau: + +1. **Xác thực**: Đăng ký, đăng nhập, phân biệt vai trò +2. **Quản lý Agent**: Tạo, chỉnh sửa, xóa, cấu hình Prompt +3. **Chức năng hội thoại**: Tạo phiên hội thoại, gửi/nhận tin nhắn, gọi mô hình +4. **Ghi nhật ký**: Thời gian xử lý, token sử dụng, ghi lỗi +5. **Kết nối cơ sở tri thức** (mục điểm cộng): Tải lên tài liệu, tìm kiếm, chèn kết quả +6. **Back-office quản trị**: Dữ liệu người dùng, sử dụng tài nguyên, thống kê lượt gọi + +Sau khi hoàn thành mỗi module, sử dụng bảng dưới đây để tự kiểm tra: + +| Mục kiểm tra | Phương pháp xác minh | +|--------|----------| +| Tính nhất quán trang | Số lượng trang, chức năng có khớp với PRD không | +| Chuỗi API | API agents, chat, logs, knowledge có hoàn chỉnh không | +| Cách ly phân quyền | Người dùng có chỉ quản lý được agent và phiên hội thoại của mình không | +| Tính nhất quán dữ liệu | Dữ liệu messages, logs, documents có khớp nhau không | +| Khả năng demo | Có thể demo chuỗi hoàn chỉnh "tạo agent → hội thoại → xem nhật ký" không | + +### 3.2 Kết nối cơ sở tri thức (mục điểm cộng) + +Nếu bạn muốn tăng khả năng cơ sở tri thức, có thể thêm "công tắc cơ sở tri thức" cho mỗi Agent: + +- Khi bật, trước tiên tìm kiếm đoạn tài liệu, sau đó gửi cùng câu hỏi của người dùng cho mô hình +- Khi tắt, phản hồi theo chế độ hội thoại thông thường + +Phiên bản đầu tiên không cần theo đuổi RAG phức tạp, chỉ cần "kết quả tìm kiếm có thể thấy, chuỗi gọi có thể giải thích". + +## Phần 4: Liên hợp và Triển khai + +### 4.1 Kiểm thử đầu cuối + +Ít nhất xác minh các kịch bản sau: + +- Đăng ký → Tạo Agent → Cấu hình Prompt → Khởi động hội thoại → Xem nhật ký +- Quản trị viên đăng nhập → Xem dữ liệu người dùng → Xem thống kê lượt gọi + +Kiểm tra trước khi triển khai: + +- [ ] Tất cả API cốt lõi đều đã kiểm tra đăng nhập +- [ ] Kiểm tra quyền sở hữu Agent thông qua +- [ ] Bản ghi phiên hội thoại, bản ghi nhật ký thực sự lưu vào cơ sở dữ liệu +- [ ] Key mô hình sử dụng biến môi trường, không hard-code +- [ ] Thông báo lỗi có thể thấy trên frontend, không chỉ in ra console + +### 4.2 Triển khai + +Triển khai dự án lên môi trường mạng công cộng. Tham khảo hướng dẫn triển khai: [Quy trình làm việc Git và GitHub](../../backend/git-workflow/), [Cách triển khai ứng dụng Web](../../backend/zeabur-deployment/). + +## Sản phẩm bàn giao + +Sau khi hoàn thành dự án này, bạn cần nộp các nội dung sau: + +- [ ] Liên kết demo trực tuyến có thể truy cập +- [ ] Liên kết kho mã nguồn (bao gồm README) +- [ ] Tài liệu PRD +- [ ] Ảnh chụp màn hình các trang cốt lõi (trang quản lý Agent, trang hội thoại, trang nhật ký, trang chủ back-office) +- [ ] Video demo 60 giây (bao gồm tạo Agent → hội thoại → xem nhật ký) + +README tối thiểu bao gồm: giới thiệu dự án, mô tả kiến trúc, công nghệ sử dụng, bước khởi động cục bộ, danh sách biến môi trường, mô tả API. + +## Tiêu chí chấm điểm + +| Chiều | Yêu cầu cơ bản | Yêu cầu nâng cao | +|------|---------|---------| +| Độ hoàn thiện nền tảng | Ba trang agents / chat / logs có thể sử dụng | Có điều hướng rõ ràng và ngôn ngữ thiết kế thống nhất | +| Chuỗi nghiệp vụ | Có thể tạo Agent và hội thoại thực sự | Hỗ trợ chuyển đổi đa Agent và phiên hội thoại lịch sử | +| Dữ liệu & theo dõi | Tin nhắn và nhật ký lượt gọi có thể truy vấn | Có bảng thống kê token / thời gian xử lý | +| Phân quyền bảo mật | Chỉ người dùng đã đăng nhập mới có thể truy cập API cốt lõi | Kiểm tra quyền sở hữu tài nguyên hoàn thiện | +| Bàn giao kỹ thuật | Có thể triển khai, có thể demo, README rõ ràng | Kết nối cơ sở tri thức và có thể giải thích kết quả tìm kiếm | + +## Kiểm tra trước khi nộp + + + + +
    +
  • +
  • +
  • +
  • +
  • +
+
+ +## Tài liệu tham khảo + +- [Thiết kế UI](../../frontend/ui-design/) +- [Sử dụng thư viện component hiện đại để cập nhật giao diện](../../frontend/modern-component-library/) +- [Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/) +- [Mô hình hỗ trợ viết code API và tài liệu API bằng mô hình lớn](../../backend/ai-interface-code/) +- [Quy trình làm việc Git và GitHub](../../backend/git-workflow/) +- [Cách triển khai ứng dụng Web](../../backend/zeabur-deployment/) diff --git a/docs/vi-vn/stage-2/assignments/exam-management-express/index.md b/docs/vi-vn/stage-2/assignments/exam-management-express/index.md new file mode 100644 index 0000000..6d5c23d --- /dev/null +++ b/docs/vi-vn/stage-2/assignments/exam-management-express/index.md @@ -0,0 +1,306 @@ +# Thực hành phát triển hệ thống quản lý và thi trực tuyến + +## Tổng quan + +Dự án thực chiến này yêu cầu bạn hoàn thành một hệ thống thi và quản lý trực tuyến dựa trên một PRD thực tế, xây dựng từ đầu. Điểm đặc biệt của dự án này là nó chứa nhiều vai trò (học sinh và quản trị viên), mỗi vai trò nhìn thấy các trang khác nhau và có thể thực hiện các thao tác khác nhau. Bạn sẽ sử dụng Express để xây dựng backend, triển khai toàn bộ chuỗi nghiệp vụ thi. + +Đây là phần thực hành tổng hợp của Stage 2. Hệ thống phân quyền đa vai trò rất phổ biến trong thực tế công việc, sau khi nắm vững mô hình này, bạn có thể ứng phó với các kịch bản nghiệp vụ như giáo dục, SaaS, quản lý back-office, v.v. + +## Kiến thức tiên quyết + +Trước khi bắt đầu dự án này, bạn nên đã nắm được các nội dung sau: + +- Thiết kế trang前端 và sử dụng thư viện component ([Thiết kế UI](../../frontend/ui-design/), [Thư viện component hiện đại](../../frontend/modern-component-library/)) +- Thiết kế và phát triển API backend ([Viết code API](../../backend/ai-interface-code/)) +- Cơ sở dữ liệu cơ bản và Supabase ([Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/)) +- Quy trình làm việc Git và triển khai ([Git và GitHub](../../backend/git-workflow/), [Triển khai ứng dụng Web](../../backend/zeabur-deployment/)) + +## Mục tiêu học tập + +Sau khi hoàn thành bài thực hành này, bạn sẽ có thể: + +1. Đọc và hiểu một PRD thực tế, từ đó trích xuất danh sách công việc phát triển +2. Thiết kế kiểm soát phân quyền và định tuyến trang cho hệ thống đa vai trò +3. Sử dụng Express để triển khai API backend hoàn chỉnh +4. Triển khai chuỗi nghiệp vụ thi, nộp bài, tự động chấm điểm +5. Hoàn thành liên hợp đầu cuối, bàn giao một nguyên mẫu hệ thống nghiệp vụ có thể demo + +## Giới thiệu dự án + +Sản phẩm bạn cần xây dựng là một hệ thống thi và quản lý trực tuyến, bao gồm ba hệ thống con: + +| Hệ thống con | Trách nhiệm | +|--------|------| +| **Trang chủ** | Giới thiệu nền tảng, điểm đăng nhập | +| **Trang học sinh** | Danh sách bài thi, làm bài, nộp bài, xem điểm | +| **Back-office quản trị** | Quản lý ngân hàng đề, quản lý bài thi, hồ sơ nộp bài, thống kê điểm | + +Backend sử dụng Express, cần hỗ trợ: xác thực đăng nhập, phân quyền vai trò, quản lý bài thi và ngân hàng đề, quy trình nộp bài và tự động chấm điểm, quản lý điểm và thống kê. + +::: tip Đường dẫn PRD +Tài liệu yêu cầu của dự án này nằm trên GitHub: [Xem PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/exam-management-express/PRD.md) +::: + +
+ + + +
+ +## Phần 1: Phân tích yêu cầu + +### 1.1 Đọc PRD + +Mở tài liệu PRD, tập trung trả lời các câu hỏi sau: + +- Hệ thống bao gồm những vai trò nào? Mỗi vai trò có thể làm gì? +- Danh sách trang đã hoàn chỉnh chưa? Trang học sinh và trang quản trị lần lượt có những trang nào? +- Hỗ trợ những loại câu hỏi nào? Logic chấm điểm cho từng loại là gì? +- Quy trình hoàn chỉnh của bài thi là gì? (Phát hành → Bắt đầu → Trả lời → Nộp → Chấm điểm → Xem điểm) + +::: warning +Nếu các câu hỏi trên chưa có câu trả lời rõ ràng, đừng bắt đầu viết code. Hiểu sai yêu cầu là nguyên nhân phổ biến nhất dẫn đến phải làm lại. +::: + +### 1.2 Xác nhận kiến trúc hệ thống + +Dựa trên PRD, hệ thống hóa kiến trúc tổng thể của hệ thống: + +```mermaid +flowchart TD + prd["PRD"] --> web["Trang chủ"] + prd --> student["Trang học sinh"] + prd --> admin["Back-office quản trị"] + student --> auth["Xác thực"] + student --> exam["Bài thi & trả lời"] + exam --> db["Cơ sở dữ liệu"] + admin --> question["Quản lý ngân hàng đề"] + admin --> submission["Hồ sơ nộp bài & thống kê điểm"] + question --> db + submission --> db +``` + +## Phần 2: Xây dựng khung dự án + +### 2.1 Tạo trang frontend + +Tham khảo prompt: + +```text +Vui lòng dựa trên PRD hiện tại, giúp tôi tạo khung frontend của hệ thống thi và quản lý trực tuyến. + +Yêu cầu công nghệ: +- Next.js App Router +- TypeScript +- Tailwind CSS +- shadcn/ui + +Danh sách trang: +1. Trang chủ / +2. Trang đăng nhập /login +3. Trang danh sách bài thi học sinh /student/exams +4. Trang làm bài thi học sinh /student/exams/[id] +5. Trang điểm học sinh /student/history +6. Trang chủ back-office quản trị /admin +7. Trang quản lý bài thi /admin/exams +8. Trang quản lý ngân hàng đề /admin/questions +9. Trang hồ sơ nộp bài /admin/submissions + +Yêu cầu: +- Trang học sinh nhấn mạnh sự rõ ràng, tập trung, dễ làm bài +- Trang quản trị sử dụng bố cục thanh bên + thanh trên +- Trước tiên sử dụng mock data, không kết nối API thực tế +- Chú ý khả năng sử dụng cơ bản trên máy tính để bàn và thiết bị di động +``` + +### 2.2 Hoàn thiện trang làm bài thi học sinh + +Trang làm bài là trang cốt lõi của học sinh, tập trung hoàn thiện: + +```text +Vui lòng tiếp tục hoàn thiện trang làm bài thi học sinh. + +Đây là trang làm bài của hệ thống thi trực tuyến, cần bao gồm: +- Phần trên hiển thị tiêu đề bài thi, đếm ngược, số câu đã trả lời +- Phần giữa hiển thị nội dung câu hỏi và các lựa chọn +- Hỗ trợ ba loại câu hỏi: trắc nghiệm, đúng/sai, tự luận +- Bên trái hoặc trên có bảng trả lời, hiển thị từng câu đã trả lời hay chưa +- Hiện xác nhận trước khi nhấn nộp bài + +Trước tiên sử dụng mock data để triển khai tương tác, không kết nối API thực tế. + +Yêu cầu: +- Giao diện đơn giản, không giống trang bảng back-office +- Đếm ngược cần nổi bật nhưng không tạo áp lực quá mạnh +- Có trạng thái trống và trạng thái loading +``` + +### 2.3 Hoàn thiện back-office quản trị + +Phiên bản đầu tiên của back-office quản trị tập trung vào ba khu vực cốt lõi: + +- **Quản lý bài thi**: Tạo bài thi, thiết lập thời gian, trạng thái phát hành +- **Quản lý ngân hàng đề**: Thêm câu hỏi mới, chỉnh sửa câu hỏi, lọc theo loại câu hỏi +- **Hồ sơ nộp bài**: Xem bài nộp của học sinh, điểm số, thời gian + +### 2.4 Xác minh cấu trúc trang + +Kiểm tra từng mục: + +- [ ] Điểm vào trang học sinh và trang quản trị đã tách biệt +- [ ] Trang đăng nhập, danh sách bài thi, trang làm bài, trang điểm đã hoàn chỉnh +- [ ] Trang quản lý ngân hàng đề, quản lý bài thi, hồ sơ nộp bài đã có thể truy cập +- [ ] Phong cách trang học sinh và trang quản trị có sự khác biệt rõ ràng + +### Gặp khó khăn? + +Nếu bạn gặp khó khăn trong giai đoạn xây dựng frontend, bạn có thể xem lại các chương sau: + +- [Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/) +- [Thiết kế và phát triển API backend ứng dụng](../../backend/ai-interface-code/) +- [Sử dụng thư viện component hiện đại để cập nhật giao diện](../../frontend/modern-component-library/) + +## Phần 3: Phát triển Backend + +### 3.1 Đăng nhập và kiểm soát phân quyền + +```text +Vui lòng coi tôi là người mới bắt đầu, giúp tôi hoàn thành đăng nhập và kiểm soát phân quyền của hệ thống thi trực tuyến. + +Backend sử dụng Express. + +Mục tiêu: +1. Cả học sinh và quản trị viên đều có thể đăng nhập +2. Sau khi đăng nhập trả về vai trò người dùng +3. Học sinh chỉ có thể truy cập các API liên quan đến /student/* +4. Quản trị viên chỉ có thể truy cập các API liên quan đến /admin/* +5. Người dùng chưa đăng nhập khi truy cập trang được bảo vệ sẽ chuyển hướng đến /login + +Yêu cầu triển khai: +- Đưa ra gợi ý cấu trúc thư mục rõ ràng +- Giải thích rõ middleware chịu trách nhiệm cho việc gì +- Không hard-code các biến môi trường liên quan +- Sau khi hoàn thành, giải thích cách xác minh phân quyền có hiệu lực hay không +``` + +### 3.2 API quản lý bài thi và ngân hàng đề + +Khuyến nghị triển khai theo các module sau: + +| Module | API khuyến nghị | +|------|----------| +| Quản lý bài thi | `GET /api/exams`, `POST /api/admin/exams`, `PATCH /api/admin/exams/:id` | +| Quản lý ngân hàng đề | `GET /api/admin/questions`, `POST /api/admin/questions` | +| Bắt đầu bài thi | `POST /api/submissions/start` | +| Nộp bài thi | `POST /api/submissions/:id/submit` | +| Hồ sơ điểm | `GET /api/student/history`, `GET /api/admin/submissions` | + +Tham khảo prompt: + +```text +Vui lòng giúp tôi thiết kế và triển khai Express API cho hệ thống thi trực tuyến. + +Phạm vi chức năng: +- Quản trị viên tạo bài thi +- Quản trị viên duy trì ngân hàng đề +- Học sinh xem bài thi đã phát hành +- Học sinh bắt đầu bài thi và tạo submission +- Học sinh nộp câu trả lời và tự động chấm câu trắc nghiệm và đúng/sai +- Câu tự luận trước tiên đánh dấu là chờ phê duyệt +- Học sinh xem điểm lịch sử của mình +- Quản trị viên xem tất cả hồ sơ nộp bài + +Yêu cầu: +- Tên API rõ ràng +- Trả về cấu trúc JSON thống nhất +- Code phân biệt các lớp controller, service, middleware, db +- Giải thích cách kiểm tra từng API +``` + +### 3.3 Logic chấm điểm + +Logic chấm điểm là quy tắc nghiệp vụ cốt lõi của hệ thống thi: + +- **Câu trắc nghiệm**: Câu trả lời của người dùng khớp với đáp án thì được điểm +- **Câu đúng/sai**: Cũng có thể tự động chấm +- **Câu tự luận**: Phiên bản đầu tiên chỉ lưu câu trả lời, điểm để trống, trạng thái `reviewed = false` + +::: tip Mục điểm cộng +Nếu bạn muốn tăng khả năng AI, quản trị viên có thể nhập "chủ đề + độ khó" trong back-office, model sẽ tạo một loạt câu hỏi ứng viên, sau đó người sẽ phê duyệt và đưa vào ngân hàng đề. Nhưng đây là mục điểm cộng, không bắt buộc. +::: + +## Phần 4: Liên hợp và Triển khai + +### 4.1 Kiểm thử đầu cuối + +Ít nhất xác minh các kịch bản sau: + +- Học sinh đăng nhập → Xem danh sách bài thi → Bắt đầu làm bài → Nộp bài → Xem điểm +- Quản trị viên đăng nhập → Tạo bài thi → Thêm câu hỏi → Phát hành → Xem hồ sơ nộp bài + +### 4.2 Triển khai + +- Frontend triển khai lên Vercel / Zeabur +- Express API triển khai lên Zeabur / Railway / Render +- Cơ sở dữ liệu sử dụng Supabase Postgres hoặc PostgreSQL được quản lý + +Kiểm tra trước khi triển khai: + +- [ ] Biến môi trường đã đầy đủ chưa +- [ ] Địa chỉ API frontend và backend đã chính xác chưa +- [ ] Trạng thái đăng nhập có hoạt động bình thường trong môi trường production không +- [ ] Tài khoản quản trị viên có thể thực sự truy cập back-office không +- [ ] README có bao gồm hướng dẫn khởi động, triển khai, kiểm thử không + +## Sản phẩm bàn giao + +Sau khi hoàn thành dự án này, bạn cần nộp các nội dung sau: + +- [ ] Liên kết demo trực tuyến có thể truy cập +- [ ] Liên kết kho mã nguồn (bao gồm README) +- [ ] Tài liệu PRD +- [ ] Ảnh chụp màn hình các trang cốt lõi (trang chủ, danh sách bài thi học sinh, trang làm bài, back-office quản trị) +- [ ] Video demo 60 giây (bao gồm quy trình học sinh làm bài và quy trình quản trị viên quản lý) + +README tối thiểu bao gồm: giới thiệu dự án, mô tả trang cốt lõi, công nghệ sử dụng, bước khởi động cục bộ, danh sách biến môi trường. + +## Tiêu chí chấm điểm + +| Chiều | Yêu cầu cơ bản | Yêu cầu nâng cao | +|------|---------|---------| +| Độ hoàn thiện trang | Các trang chính của học sinh và quản trị viên đều có thể truy cập | Phong cách trang thống nhất, thiết bị di động cơ bản có thể sử dụng | +| Chuỗi nghiệp vụ | Học sinh có thể đăng nhập, tham gia thi, nộp bài và xem điểm | Quản trị viên có thể tạo và phát hành bài thi hoàn chỉnh | +| Tính chính xác dữ liệu | Sau khi nộp câu trả lời có thể ghi vào cơ sở dữ liệu, câu khách quan có thể tự động chấm điểm | Câu tự luận hỗ trợ phê duyệt thủ công hoặc hỗ trợ AI | +| Kiểm soát phân quyền | Ranh giới truy cập giữa học sinh và quản trị viên rõ ràng | API backend cũng có kiểm tra vai trò | +| Bàn giao kỹ thuật | Dự án có thể chạy, có thể triển khai, README rõ ràng | Có video demo và hướng dẫn kiểm thử | + +## Kiểm tra trước khi nộp + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## Tài liệu tham khảo + +- [Thiết kế UI](../../frontend/ui-design/) +- [Sử dụng thư viện component hiện đại để cập nhật giao diện](../../frontend/modern-component-library/) +- [Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/) +- [Mô hình hỗ trợ viết code API và tài liệu API bằng mô hình lớn](../../backend/ai-interface-code/) +- [Quy trình làm việc Git và GitHub](../../backend/git-workflow/) +- [Cách triển khai ứng dụng Web](../../backend/zeabur-deployment/) diff --git a/docs/vi-vn/stage-2/assignments/modern-landing-page/index.md b/docs/vi-vn/stage-2/assignments/modern-landing-page/index.md new file mode 100644 index 0000000..d13e581 --- /dev/null +++ b/docs/vi-vn/stage-2/assignments/modern-landing-page/index.md @@ -0,0 +1,211 @@ +# Thực hành phát triển SaaS tạo ảnh AI hiện đại + +## Tổng quan + +Dự án thực chiến này yêu cầu bạn hoàn thành một sản phẩm SaaS tạo ảnh AI tham khảo trải nghiệm Midjourney dựa trên một PRD (tài liệu yêu cầu sản phẩm) thực tế, xây dựng từ đầu. Bạn sẽ trải nghiệm toàn bộ quá trình phân tích yêu cầu, phân tách dự án, phát triển lặp, liên hợp và triển khai. + +Đây là phần thực hành tổng hợp của Stage 2. Trong các chương trước, bạn đã học riêng biệt các kỹ năng thiết kế trang frontend, phát triển API backend, thao tác cơ sở dữ liệu, tích hợp thanh toán, v.v. — dự án này yêu cầu bạn kết hợp tất cả lại với nhau, bàn giao một nguyên mẫu sản phẩm có thể chạy được. + +## Kiến thức tiên quyết + +Trước khi bắt đầu dự án này, bạn nên đã nắm được các nội dung sau: + +- Thiết kế trang frontend và sử dụng thư viện component ([Thiết kế UI](../../frontend/ui-design/), [Thư viện component hiện đại](../../frontend/modern-component-library/)) +- Thiết kế và phát triển API backend ([Viết code API](../../backend/ai-interface-code/)) +- Cơ sở dữ liệu cơ bản và Supabase ([Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/)) +- Tích hợp thanh toán ([Hệ thống thanh toán Stripe](../../backend/stripe-payment/)) +- Quy trình làm việc Git và triển khai ([Git và GitHub](../../backend/git-workflow/), [Triển khai ứng dụng Web](../../backend/zeabur-deployment/)) + +## Mục tiêu học tập + +Sau khi hoàn thành bài thực hành này, bạn sẽ có thể: + +1. Đọc và hiểu một PRD thực tế, từ đó trích xuất danh sách công việc phát triển +2. Phân tách module dựa trên PRD, lập kế hoạch triển khai từng bước +3. Sử dụng AI hỗ trợ hoàn thành xây dựng khung frontend và phát triển API backend +4. Xác minh và tối ưu hóa lặp từng module +5. Hoàn thành liên hợp đầu cuối, đưa dự án từ "chạy được" đến "có thể bàn giao" + +## Giới thiệu dự án + +Sản phẩm bạn cần xây dựng là một nền tảng SaaS tạo ảnh AI hiện đại, bao gồm ba hệ thống con: + +| Hệ thống con | Trách nhiệm | +|--------|------| +| **Trang chủ** | Giới thiệu sản phẩm, bảng giá, FAQ, chuyển đổi đăng ký | +| **Bàn làm việc người dùng** | Nhập Prompt, tạo ảnh, thư viện ảnh, tín dụng, gói dịch vụ, tương tác cộng đồng | +| **Back-office quản trị** | Quản lý người dùng, quản lý tác vụ, quản lý thanh toán, kiểm duyệt nội dung, chỉ số SaaS, giám sát hệ thống | + +Backend cần hỗ trợ các khả năng cốt lõi sau: xác thực người dùng, tác vụ tạo ảnh, lưu trữ đối tượng OSS, tín dụng và thanh toán gói dịch vụ, tương tác xã hội ảnh, giám sát dữ liệu vận hành. + +::: tip Đường dẫn PRD +Tài liệu yêu cầu của dự án này nằm trên GitHub: [Xem PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/modern-landing-page/PRD.md) +::: + +
+ + + +
+ +## Phần 1: Phân tích yêu cầu + +### 1.1 Đọc PRD + +Mở tài liệu PRD, tập trung trả lời các câu hỏi sau: + +- Hệ thống có mấy điểm vào? Mỗi điểm bao phủ những trang nào? +- Chức năng cốt lõi của mỗi trang là gì? +- Backend bao gồm những module và bảng cơ sở dữ liệu nào? +- Phạm vi MVP là gì? Phiên bản đầu tiên làm gì, không làm gì? + +::: warning +Nếu các câu hỏi trên chưa có câu trả lời rõ ràng, đừng bắt đầu viết code. Hiểu sai yêu cầu là nguyên nhân phổ biến nhất dẫn đến phải làm lại. +::: + +### 1.2 Xác nhận kiến trúc hệ thống + +Dựa trên mô tả trong PRD, hệ thống hóa kiến trúc tổng thể của hệ thống: + +```mermaid +flowchart TD + prd["PRD"] --> web["Trang chủ"] + prd --> app["Bàn làm việc người dùng"] + prd --> admin["Back-office quản trị"] + app --> auth["Xác thực"] + app --> gen["Tác vụ tạo ảnh"] + gen --> oss["Lưu trữ đối tượng OSS"] + gen --> db["Cơ sở dữ liệu"] + billing["Thanh toán & gói dịch vụ"] --> db + social["Chia sẻ / Thích / Bình luận / Chuyển tiếp"] --> db + admin --> analytics["Bảng chỉ số SaaS"] + admin --> observability["Giám sát API / DB / Provider"] +``` + +Khuyến nghị bạn vẽ lại sơ đồ kiến trúc bằng lời của mình, xác nhận rằng sự hiểu biết của bạn về hệ thống là hoàn chỉnh. + +## Phần 2: Xây dựng khung dự án + +### 2.1 Tạo trang frontend + +Sử dụng AI để tạo cấu trúc cơ bản và dữ liệu giả cho tất cả các trang. Mục tiêu của bước này là tạo ra kiến trúc thông tin và định tuyến, không cần kết nối API thực tế. + +Tham khảo prompt: + +```text +Vui lòng dựa trên PRD hiện tại, giúp tôi tạo khung frontend của SaaS tạo ảnh AI hiện đại. + +Yêu cầu: +1. Chia thành ba điểm vào: www, app, admin +2. Trang chủ bao gồm: trang chủ, bảng giá, FAQ +3. app bao gồm: đăng nhập, đăng ký, bàn làm việc tạo ảnh, thư viện ảnh, gói dịch vụ, tín dụng, cộng đồng, chi tiết tác phẩm, trang cá nhân +4. admin bao gồm: trang chủ back-office, quản lý người dùng, quản lý tác vụ, quản lý nội dung, quản lý gói dịch vụ, đơn thanh toán, cấu hình vận hành, chỉ số SaaS, giám sát hệ thống +5. Trước tiên chỉ tạo cấu trúc trang và dữ liệu giả, không kết nối API thực tế +6. Phong cách tham khảo Midjourney, đơn giản, hiện đại, có cảm giác sản phẩm +``` + +### 2.2 Xác minh cấu trúc trang + +Sau khi tạo khung, kiểm tra từng mục: + +- [ ] Định tuyến của ba điểm vào có độc lập không (`/`, `/app`, `/admin`) +- [ ] Số lượng trang có khớp với PRD không +- [ ] Mỗi trang có thể truy cập và điều hướng bình thường không +- [ ] Dữ liệu giả có hiển thị trạng thái UI cơ bản không (danh sách, trạng thái trống, biểu mẫu, v.v.) + +## Phần 3: Phát triển lặp + +### 3.1 Triển khai theo module + +Trên cơ sở khung, bổ sung chức năng theo thứ tự module sau: + +1. **Xác thực**: Đăng ký, đăng nhập, phân biệt vai trò +2. **Cơ sở dữ liệu**: Tạo bảng dữ liệu, API đọc/ghi +3. **Nghiệp vụ cốt lõi**: Tác vụ tạo ảnh, lưu trữ kết quả +4. **Lưu trữ OSS**: Tải lên và truy cập ảnh +5. **Thanh toán**: Gói dịch vụ, tín dụng, tích hợp Stripe +6. **Tương tác xã hội**: Chia sẻ, thích, bình luận +7. **Quản lý back-office**: Quản lý người dùng, quản lý tác vụ, kiểm duyệt nội dung +8. **Giám sát dữ liệu**: Bảng chỉ số SaaS, giám sát hệ thống + +Sau khi hoàn thành mỗi module, sử dụng bảng dưới đây để tự kiểm tra: + +| Mục kiểm tra | Phương pháp xác minh | +|--------|----------| +| Tính nhất quán trang | Số lượng trang, điểm vào, chức năng có khớp với PRD không | +| Tính chính xác API | Tham số yêu cầu, cấu trúc trả về, xử lý trạng thái có hợp lý không | +| Cách ly phân quyền | Người dùng thông thường và quản trị viên có cách ly nhau không | +| Tính nhất quán dữ liệu | Cơ sở dữ liệu, OSS, thanh toán, tín dụng có khớp nhau không | +| Khả năng demo | Có thể demo hoàn chỉnh một chuỗi nghiệp vụ cho người khác không | + +::: tip +Nếu phát hiện nội dung do AI tạo ra sai lệch so với PRD, đừng lật đổ toàn bộ trang, hãy để AI sửa trực tiếp module cụ thể. +::: + +### 3.2 Vai trò và phân công + +Trong quá trình lặp, bạn cần đóng đồng thời ba vai trò: + +- **Quản lý sản phẩm**: Xác nhận chức năng của mỗi module có khớp với PRD không +- **Trưởng nhóm kỹ thuật**: Xác nhận phương án triển khai có hợp lý không +- **Kỹ sư kiểm thử**: Xác nhận chức năng có chạy được không + +## Phần 4: Liên hợp và Triển khai + +### 4.1 Kiểm thử đầu cuối + +Trọng tâm của giai đoạn cuối không phải là bổ sung trang mới, mà là chạy qua toàn bộ chuỗi nghiệp vụ. Ít nhất xác minh các kịch bản sau: + +- Đăng ký → Mua tín dụng → Tạo ảnh → Xem lịch sử → Chia sẻ tương tác +- Quản trị viên đăng nhập → Xem dữ liệu người dùng → Xem thống kê tác vụ → Xem giám sát hệ thống + +### 4.2 Triển khai + +Triển khai dự án lên môi trường mạng công cộng, đảm bảo: + +- Cấu hình biến môi trường hoàn chỉnh +- Địa chỉ callback đăng nhập chính xác +- Địa chỉ callback thanh toán chính xác +- Trang không thiếu trạng thái loading, trạng thái trống, thông báo lỗi + +Tham khảo hướng dẫn triển khai: [Quy trình làm việc Git và GitHub](../../backend/git-workflow/), [Cách triển khai ứng dụng Web](../../backend/zeabur-deployment/). + +## Sản phẩm bàn giao + +Sau khi hoàn thành dự án này, bạn cần nộp các nội dung sau: + +- [ ] Liên kết demo trực tuyến có thể truy cập +- [ ] Liên kết kho mã nguồn (bao gồm README) +- [ ] Tài liệu PRD +- [ ] Ảnh chụp màn hình các trang cốt lõi (trang chủ website, bàn làm việc tạo ảnh, thư viện ảnh, trang gói dịch vụ, trang chủ back-office) +- [ ] Video demo 60 giây (bao gồm đăng ký → tạo ảnh → xem → quản lý back-office) + +README tối thiểu bao gồm: giới thiệu dự án, mô tả trang cốt lõi, công nghệ sử dụng, bước khởi động cục bộ, danh sách biến môi trường. + +## Tiêu chí chấm điểm + +| Chiều | Yêu cầu cơ bản | Yêu cầu nâng cao | +|------|---------|---------| +| Căn chỉnh PRD | Trang, chức năng, cấu trúc dữ liệu cơ bản khớp với PRD | Có thể giải thích rõ ràng mỗi quyết định thiết kế tương ứng với PRD như thế nào | +| Chuỗi sản phẩm | Đăng ký → Mua tín dụng → Tạo ảnh → Xem lịch sử → Chia sẻ tương tác có thể chạy qua | Trạng thái thanh toán, số dư tín dụng, số lần tạo ảnh nhất quán về dữ liệu | +| Khả năng back-office | Người dùng, tác vụ, thanh toán, quản lý nội dung có thể xem | Bảng chỉ số SaaS và trang giám sát hệ thống hoàn chỉnh có thể sử dụng | +| Độ hoàn thiện kỹ thuật | Frontend, backend, cơ sở dữ liệu, OSS, chuỗi thanh toán đã kết nối | Có xử lý lỗi, trạng thái trống, trạng thái loading | +| Chất lượng bàn giao | Có thể triển khai, có thể chạy | README rõ ràng, cấu trúc video demo hoàn chỉnh | + +## Tài liệu tham khảo + +- [Thiết kế UI](../../frontend/ui-design/) +- [Tham khảo quy phạm thiết kế UI để thiết kế trang và nút](../../frontend/multi-product-ui/) +- [Dùng LLM và Skills làm cho giao diện đẹp hơn](../../frontend/llm-skills-beautiful/) +- [Từ nguyên mẫu thiết kế đến code dự án](../../frontend/design-to-code/) +- [Sử dụng thư viện component hiện đại để cập nhật giao diện](../../frontend/modern-component-library/) +- [Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/) +- [Mô hình hỗ trợ viết code API và tài liệu API bằng mô hình lớn](../../backend/ai-interface-code/) +- [Quy trình làm việc Git và GitHub](../../backend/git-workflow/) +- [Cách triển khai ứng dụng Web](../../backend/zeabur-deployment/) +- [Cách tích hợp hệ thống thanh toán như Stripe](../../backend/stripe-payment/) diff --git a/docs/vi-vn/stage-2/assignments/movie-recommendation-springboot/index.md b/docs/vi-vn/stage-2/assignments/movie-recommendation-springboot/index.md new file mode 100644 index 0000000..eeaa754 --- /dev/null +++ b/docs/vi-vn/stage-2/assignments/movie-recommendation-springboot/index.md @@ -0,0 +1,162 @@ +# Thực hành phát triển hệ thống đề xuất phim bằng Spring Boot + +## Tổng quan + +Dự án thực chiến này yêu cầu bạn hoàn thành một trang web phim có khả năng đề xuất dựa trên một PRD thực tế, sử dụng Spring Boot. Thách thức cốt lõi của dự án này là: nó không phải là thao tác CRUD đơn giản, mà cần bạn suy nghĩ "hành vi người dùng ảnh hưởng đến kết quả đề xuất như thế nào" và "đề xuất có thể giải thích như thế nào". + +Đây là phần thực hành tổng hợp của Stage 2. Bạn sẽ lần đầu tiên tiếp xúc với mô hình phát triển sản phẩm kiểu "nội dung + hành vi + đề xuất", mô hình này rất phổ biến trong các kịch bản thương mại điện tử, nền tảng nội dung, Feed cá nhân hóa, v.v. + +## Kiến thức tiên quyết + +Trước khi bắt đầu dự án này, bạn nên đã nắm được các nội dung sau: + +- Thiết kế trang frontend và sử dụng thư viện component ([Thiết kế UI](../../frontend/ui-design/), [Thư viện component hiện đại](../../frontend/modern-component-library/)) +- Thiết kế và phát triển API backend ([Viết code API](../../backend/ai-interface-code/)) +- Cơ sở dữ liệu cơ bản và Supabase ([Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/)) +- Quy trình làm việc Git và triển khai ([Git và GitHub](../../backend/git-workflow/), [Triển khai ứng dụng Web](../../backend/zeabur-deployment/)) + +## Mục tiêu học tập + +Sau khi hoàn thành bài thực hành này, bạn sẽ có thể: + +1. Đọc PRD và từ đó trích xuất danh sách công việc phát triển hệ thống đề xuất +2. Sử dụng Spring Boot để xây dựng dự án backend và triển khai RESTful API +3. Thiết kế chuỗi dữ liệu hoàn chỉnh "hành vi người dùng → đề xuất" +4. Triển khai logic đề xuất có thể giải thích +5. Hoàn thành liên hợp đầu cuối, bàn giao nguyên mẫu sản phẩm có thể demo + +## Giới thiệu dự án + +Sản phẩm bạn cần xây dựng là một trang web phim có khả năng đề xuất: + +| Chức năng | Mô tả | +|------|------| +| **Duyệt và tìm kiếm** | Người dùng có thể duyệt và tìm kiếm phim | +| **Đánh giá và收藏** | Người dùng có thể đánh giá phim, thêm收藏 | +| **Đề xuất cá nhân hóa** | Hệ thống đưa ra kết quả đề xuất dựa trên hành vi người dùng | +| **Back-office quản trị** | Quản trị viên duy trì dữ liệu phim, xem hiệu quả đề xuất | + +::: tip Đường dẫn PRD +Tài liệu yêu cầu của dự án này nằm trên GitHub: [Xem PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/movie-recommendation-springboot/PRD.md) +::: + +
+ + + +
+ +## Phần 1: Phân tích yêu cầu + +### 1.1 Đọc PRD + +Mở tài liệu PRD, tập trung trả lời các câu hỏi sau: + +- Chiến lược đề xuất là gì? Phiên bản đầu tiên có sử dụng phiên bản có thể giải thích (như dựa trên độ tương tự đánh giá) không? +- Dữ liệu hành vi người dùng cần lưu những gì? (Đánh giá,收藏, bản ghi duyệt, v.v.) +- Quản trị viên cần xem những chỉ số hiệu quả đề xuất nào? +- Danh sách trang đã hoàn chỉnh chưa? + +::: warning +Nếu các câu hỏi trên chưa có câu trả lời rõ ràng, đừng bắt đầu viết code. Hiểu sai yêu cầu là nguyên nhân phổ biến nhất dẫn đến phải làm lại. +::: + +### 1.2 Xác nhận kiến trúc hệ thống + +```mermaid +flowchart TD + prd["PRD"] --> web["Trang frontend"] + web --> auth["Xác thực người dùng"] + web --> movie["Danh sách / Chi tiết phim"] + web --> behavior["Đánh giá / 收藏"] + behavior --> reco["Logic đề xuất"] + reco --> db["Cơ sở dữ liệu"] + admin["Back-office quản trị"] --> db +``` + +## Phần 2: Xây dựng khung dự án + +### 2.1 Tạo trang frontend + +Tham khảo prompt: + +```text +Vui lòng dựa trên PRD hiện tại, giúp tôi tạo khung frontend của hệ thống đề xuất phim bằng Spring Boot. + +Yêu cầu: +1. Trang bao gồm: trang chủ, danh sách phim, chi tiết phim, trang đề xuất, trang cá nhân, back-office quản trị +2. Trước tiên chỉ tạo cấu trúc trang và dữ liệu giả, không kết nối API thực tế +3. Phong cách phải giống sản phẩm nội dung thực tế, chứ không phải demo lớp học +``` + +### 2.2 Xác minh cấu trúc trang + +Kiểm tra từng mục: + +- [ ] Trang danh sách phim hỗ trợ tìm kiếm và lọc +- [ ] Trang chi tiết phim bao gồm nút đánh giá và收藏 +- [ ] Trang đề xuất có thể hiển thị kết quả đề xuất và lý do đề xuất +- [ ] Back-office quản trị có thể hiển thị dữ liệu phim và hiệu quả đề xuất + +## Phần 3: Phát triển lặp + +### 3.1 Triển khai theo module + +1. **Xây dựng dự án Spring Boot**: Cấu trúc dự án, cấu hình cơ sở dữ liệu, CRUD cơ bản +2. **Quản lý dữ liệu phim**: Danh sách phim, chi tiết, API tìm kiếm +3. **Hành vi người dùng**: API đánh giá,收藏, ghi dữ liệu hành vi +4. **Logic đề xuất**: Triển khai thuật toán đề xuất dựa trên hành vi người dùng +5. **Hiển thị đề xuất**: Hiển thị kết quả đề xuất, bao gồm lý do đề xuất +6. **Back-office quản trị**: Duy trì dữ liệu phim, xem hiệu quả đề xuất + +### 3.2 Tự kiểm tra module + +| Mục kiểm tra | Phương pháp xác minh | +|--------|----------| +| Chức năng cơ bản | Danh sách, chi tiết, đánh giá,收藏 có thành chuỗi hoàn chỉnh không | +| Liên kết đề xuất | Hành vi người dùng có ảnh hưởng đến kết quả đề xuất không | +| Tính có thể giải thích của đề xuất | Người dùng có thể hiểu tại sao được đề xuất những phim này không | +| Dữ liệu back-office | Quản trị viên có thể xem dữ liệu phim và hiệu quả đề xuất không | + +## Phần 4: Liên hợp và Triển khai + +### 4.1 Kiểm thử đầu cuối + +Ít nhất xác minh các kịch bản sau: + +- Duyệt phim → Đánh giá →收藏 → Xem trang đề xuất, xác nhận kết quả đề xuất thay đổi +- Quản trị viên đăng nhập → Thêm phim → Xem thống kê hiệu quả đề xuất + +## Sản phẩm bàn giao + +Sau khi hoàn thành dự án này, bạn cần nộp các nội dung sau: + +- [ ] Liên kết demo trực tuyến có thể truy cập +- [ ] Liên kết kho mã nguồn (bao gồm README) +- [ ] Tài liệu PRD +- [ ] Ảnh chụp màn hình các trang cốt lõi (danh sách phim, chi tiết phim, trang đề xuất, back-office quản trị) +- [ ] Video demo 60 giây + +## Tiêu chí chấm điểm + +| Chiều | Yêu cầu cơ bản | Yêu cầu nâng cao | +|------|---------|---------| +| Căn chỉnh PRD | Trang, chức năng, cấu trúc dữ liệu cơ bản khớp với PRD | Có thể giải thích rõ ràng quyết định thiết kế | +| Chuỗi sản phẩm | Duyệt → Đánh giá →收藏 → Đề xuất có thể chạy qua | Hành vi đánh giá rõ ràng ảnh hưởng đến kết quả đề xuất | +| Chất lượng đề xuất | Kết quả đề xuất hợp lý, lý do đề xuất có thể giải thích | Hỗ trợ nhiều chiến lược đề xuất | +| Khả năng back-office | Dữ liệu phim và hiệu quả đề xuất có thể xem | Có chỉ số thống kê như độ chính xác đề xuất | +| Độ hoàn thiện kỹ thuật | Frontend, backend Spring Boot, chuỗi cơ sở dữ liệu đã kết nối | API đề xuất có bộ nhớ đệm hoặc tối ưu hiệu suất | + +## Tài liệu tham khảo + +- [Thiết kế UI](../../frontend/ui-design/) +- [Sử dụng thư viện component hiện đại để cập nhật giao diện](../../frontend/modern-component-library/) +- [Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/) +- [Mô hình hỗ trợ viết code API và tài liệu API bằng mô hình lớn](../../backend/ai-interface-code/) +- [Quy trình làm việc Git và GitHub](../../backend/git-workflow/) +- [Cách triển khai ứng dụng Web](../../backend/zeabur-deployment/) diff --git a/docs/vi-vn/stage-2/assignments/simple-grocery-microservices/index.md b/docs/vi-vn/stage-2/assignments/simple-grocery-microservices/index.md new file mode 100644 index 0000000..5633e88 --- /dev/null +++ b/docs/vi-vn/stage-2/assignments/simple-grocery-microservices/index.md @@ -0,0 +1,172 @@ +# Thực hành phát triển hệ thống microservices thương mại điện tử thực phẩm tươi sống + +## Tổng quan + +Dự án thực chiến này yêu cầu bạn hoàn thành một hệ thống microservices thương mại điện tử thực phẩm tươi sống dựa trên một PRD thực tế, xây dựng từ đầu. Khác với các dự án dịch vụ đơn lẻ trước đó, backend của dự án này được chia thành nhiều dịch vụ độc lập theo nghiệp vụ, thông qua API Gateway thống nhất对外. Bạn sẽ học cách thiết kế ranh giới dịch vụ, cách xử lý vấn đề nhất quán dữ liệu cross-service. + +Đây là phần thực hành tổng hợp của Stage 2. Kiến trúc microservices rất phổ biến trong thực tế công việc, sau khi nắm vững tư duy cơ bản về phân tách dịch vụ và định tuyến gateway, bạn có thể ứng phó với thiết kế hệ thống backend phức tạp hơn. + +## Kiến thức tiên quyết + +Trước khi bắt đầu dự án này, bạn nên đã nắm được các nội dung sau: + +- Thiết kế trang frontend và sử dụng thư viện component ([Thiết kế UI](../../frontend/ui-design/), [Thư viện component hiện đại](../../frontend/modern-component-library/)) +- Thiết kế và phát triển API backend ([Viết code API](../../backend/ai-interface-code/)) +- Cơ sở dữ liệu cơ bản và Supabase ([Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/)) +- Quy trình làm việc Git và triển khai ([Git và GitHub](../../backend/git-workflow/), [Triển khai ứng dụng Web](../../backend/zeabur-deployment/)) + +## Mục tiêu học tập + +Sau khi hoàn thành bài thực hành này, bạn sẽ có thể: + +1. Đọc PRD và trích xuất danh sách công việc phát triển hệ thống microservices +2. Phân tách ranh giới dịch vụ theo lĩnh vực nghiệp vụ (xác thực, sản phẩm, tồn kho, đơn hàng) +3. Thiết kế và triển khai định tuyến API Gateway +4. Xử lý các vấn đề cross-service như trừ tồn kho và nhất quán đơn hàng +5. Hoàn thành liên hợp đầu cuối, bàn giao nguyên mẫu microservices có thể demo + +## Giới thiệu dự án + +Sản phẩm bạn cần xây dựng là một hệ thống microservices thương mại điện tử thực phẩm tươi sống: + +| Hệ thống con | Trách nhiệm | +|--------|------| +| **Trang người dùng** | Duyệt sản phẩm, đặt hàng, xem đơn hàng | +| **Trang quản trị** | Quản lý sản phẩm, quản lý tồn kho, quản lý đơn hàng | + +Backend được phân tách theo nghiệp vụ thành các dịch vụ sau: + +| Dịch vụ | Trách nhiệm | +|------|------| +| **API Gateway** | Điểm vào thống nhất, chuyển tiếp định tuyến, kiểm tra xác thực | +| **Auth Service** | Đăng ký người dùng, đăng nhập, cấp JWT | +| **Catalog Service** | Quản lý thông tin sản phẩm | +| **Inventory Service** | Quản lý số lượng tồn kho | +| **Order Service** | Tạo đơn hàng, quản lý trạng thái | + +::: tip Đường dẫn PRD +Tài liệu yêu cầu của dự án này nằm trên GitHub: [Xem PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/simple-grocery-microservices/PRD.md) +::: + +
+ + + +
+ +## Phần 1: Phân tích yêu cầu + +### 1.1 Đọc PRD + +Mở tài liệu PRD, tập trung trả lời các câu hỏi sau: + +- Dịch vụ được phân tách như thế nào? Ranh giới trách nhiệm của mỗi dịch vụ là gì? +- Frontend và trang quản trị lần lượt có những trang nào? +- Chiến lược trừ tồn kho sau khi đặt hàng là gì? Xử lý thành công / thất bại / timeout mỗi loại như thế nào? +- Phiên bản đầu tiên những khả năng phức tạp nào (như giao dịch phân tán, hàng đợi tin nhắn) tạm thời không làm? + +::: warning +Nếu các câu hỏi trên chưa có câu trả lời rõ ràng, đừng bắt đầu viết code. Hiểu sai yêu cầu là nguyên nhân phổ biến nhất dẫn đến phải làm lại. +::: + +### 1.2 Xác nhận kiến trúc hệ thống + +```mermaid +flowchart TD + prd["PRD"] --> fe["Trang frontend"] + fe --> gw["API Gateway"] + gw --> auth["Auth Service"] + gw --> catalog["Catalog Service"] + gw --> inventory["Inventory Service"] + gw --> order["Order Service"] + order --> inventory +``` + +## Phần 2: Xây dựng khung dự án + +### 2.1 Tạo cấu trúc dự án + +Tham khảo prompt: + +```text +Vui lòng dựa trên PRD hiện tại, giúp tôi tạo cấu trúc dự án của hệ thống microservices thương mại điện tử thực phẩm tươi sống. + +Yêu cầu: +1. Tạo khung frontend trang người dùng và trang quản trị +2. Tạo năm thư mục: api-gateway, auth-service, catalog-service, inventory-service, order-service +3. Mỗi dịch vụ trước tiên chỉ làm điểm vào có thể chạy tối thiểu +4. Trước tiên không kết nối cơ sở dữ liệu thực tế và thanh toán +``` + +### 2.2 Xác minh cấu trúc dự án + +Kiểm tra từng mục: + +- [ ] Cấu trúc thư mục của năm dịch vụ rõ ràng +- [ ] API Gateway có thể khởi động và chuyển tiếp yêu cầu +- [ ] API kiểm tra sức khỏe của mỗi dịch vụ có thể sử dụng +- [ ] Trang frontend trang người dùng và trang quản trị có thể truy cập + +## Phần 3: Phát triển lặp + +### 3.1 Triển khai theo module + +1. **API Gateway**: Cấu hình định tuyến, middleware kiểm tra JWT +2. **Auth Service**: Đăng ký, đăng nhập, cấp JWT +3. **Catalog Service**: CRUD sản phẩm, truy vấn danh sách +4. **Inventory Service**: Truy vấn tồn kho, trừ tồn kho +5. **Order Service**: Tạo đơn hàng, chuyển trạng thái, liên kết tồn kho +6. **Trang quản trị**: Quản lý sản phẩm, quản lý tồn kho, quản lý đơn hàng + +### 3.2 Tự kiểm tra module + +| Mục kiểm tra | Phương pháp xác minh | +|--------|----------| +| Định tuyến gateway | API của mỗi dịch vụ có được chuyển tiếp chính xác qua gateway không | +| Cách ly phân quyền | API trang người dùng và trang quản trị có cách ly không | +| Nhất quán dữ liệu | Dữ liệu sản phẩm và tồn kho có đồng bộ không | +| Chuỗi giao dịch | Sau khi đặt hàng, trừ tồn kho, trạng thái đơn hàng có nhất quán không | +| Xử lý thất bại | Khi tồn kho không đủ hoặc timeout có cơ chế bù đắp không | + +## Phần 4: Liên hợp và Triển khai + +### 4.1 Kiểm thử đầu cuối + +Ít nhất xác minh các kịch bản sau: + +- Duyệt sản phẩm → Thêm vào giỏ hàng → Đặt hàng → Xem đơn hàng +- Quản trị viên → Thêm sản phẩm → Cập nhật tồn kho → Xem đơn hàng + +## Sản phẩm bàn giao + +Sau khi hoàn thành dự án này, bạn cần nộp các nội dung sau: + +- [ ] Liên kết demo trực tuyến có thể truy cập +- [ ] Liên kết kho mã nguồn (bao gồm README) +- [ ] Tài liệu PRD +- [ ] Ảnh chụp màn hình các trang cốt lõi (danh sách sản phẩm, trang đặt hàng, trang đơn hàng, back-office quản trị) +- [ ] Video demo 60 giây + +## Tiêu chí chấm điểm + +| Chiều | Yêu cầu cơ bản | Yêu cầu nâng cao | +|------|---------|---------| +| Căn chỉnh PRD | Trang, chức năng, phân tách dịch vụ cơ bản khớp với PRD | Có thể giải thích rõ ràng lý do phân tách dịch vụ | +| Chuỗi sản phẩm | Duyệt → Đặt hàng → Trừ tồn kho → Xem đơn hàng có thể chạy qua | Timeout đơn hàng hoặc tồn kho không đủ có cơ chế bù đắp | +| Kiến trúc dịch vụ | Mỗi dịch vụ có thể khởi động độc lập, truy cập thống nhất qua gateway | Giao tiếp giữa dịch vụ có xử lý lỗi và thử lại | +| Khả năng back-office | Quản lý sản phẩm, tồn kho, đơn hàng có thể thao tác | Trang quản trị có thống kê dữ liệu | +| Độ hoàn thiện kỹ thuật | Frontend, gateway, dịch vụ, chuỗi cơ sở dữ liệu đã kết nối | Có Docker Compose hoặc điều phối tương tự | + +## Tài liệu tham khảo + +- [Thiết kế UI](../../frontend/ui-design/) +- [Sử dụng thư viện component hiện đại để cập nhật giao diện](../../frontend/modern-component-library/) +- [Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/) +- [Mô hình hỗ trợ viết code API và tài liệu API bằng mô hình lớn](../../backend/ai-interface-code/) +- [Quy trình làm việc Git và GitHub](../../backend/git-workflow/) +- [Cách triển khai ứng dụng Web](../../backend/zeabur-deployment/) diff --git a/docs/vi-vn/stage-2/assignments/traffic-data-visualization-go/index.md b/docs/vi-vn/stage-2/assignments/traffic-data-visualization-go/index.md new file mode 100644 index 0000000..74b4d1d --- /dev/null +++ b/docs/vi-vn/stage-2/assignments/traffic-data-visualization-go/index.md @@ -0,0 +1,163 @@ +# Thực hành phát triển nền tảng phân tích dữ liệu giao thông bằng Go + +## Tổng quan + +Dự án thực chiến này yêu cầu bạn hoàn thành một nền tảng phân tích dữ liệu giao thông dựa trên một PRD thực tế, sử dụng Go. Hướng của dự án này khác với các hệ thống CRUD trước đó — bạn cần xây dựng một chuỗi dữ liệu hoàn chỉnh "nhập dữ liệu → tổng hợp → cảnh báo → trực quan hóa". Loại sản phẩm dữ liệu này rất phổ biến trong các kịch bản IoT, giám sát, phân tích vận hành, v.v. + +Đây là phần thực hành tổng hợp của Stage 2, cũng là lần đầu tiên bạn tiếp xúc với ngôn ngữ Go. Đừng lo lắng, với nền tảng JavaScript / TypeScript trước đó, học Go không khó — trọng tâm là hiểu tư duy thiết kế chuỗi dữ liệu. + +## Kiến thức tiên quyết + +Trước khi bắt đầu dự án này, bạn nên đã nắm được các nội dung sau: + +- Thiết kế trang frontend và sử dụng thư viện component ([Thiết kế UI](../../frontend/ui-design/), [Thư viện component hiện đại](../../frontend/modern-component-library/)) +- Thiết kế và phát triển API backend ([Viết code API](../../backend/ai-interface-code/)) +- Cơ sở dữ liệu cơ bản và Supabase ([Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/)) +- Quy trình làm việc Git và triển khai ([Git và GitHub](../../backend/git-workflow/), [Triển khai ứng dụng Web](../../backend/zeabur-deployment/)) + +## Mục tiêu học tập + +Sau khi hoàn thành bài thực hành này, bạn sẽ có thể: + +1. Đọc PRD và trích xuất danh sách công việc phát triển sản phẩm dữ liệu +2. Sử dụng Go (Gin hoặc Fiber) để xây dựng dịch vụ API backend +3. Thiết kế chuỗi hoàn chỉnh nhập dữ liệu, tổng hợp cửa sổ và cảnh báo +4. Giữ cho dữ liệu backend và bảng điều khiển frontend nhất quán +5. Hoàn thành liên hợp đầu cuối, bàn giao nguyên mẫu sản phẩm dữ liệu có thể demo + +## Giới thiệu dự án + +Sản phẩm bạn cần xây dựng là một nền tảng phân tích dữ liệu giao thông bằng Go: + +| Module | Trách nhiệm | +|------|------| +| **Nhập dữ liệu** | Nhận sự kiện giao thông thô và lưu vào cơ sở dữ liệu | +| **Tổng hợp dữ liệu** | Tính toán xu hướng và chỉ số tắc nghẽn theo cửa sổ thời gian | +| **Cảnh báo** | Tạo bản ghi cảnh báo dựa trên quy tắc | +| **Hiển thị bảng điều khiển** | Hiển thị biểu đồ xu hướng, bảng xếp hạng và danh sách cảnh báo trên frontend | + +::: tip Đường dẫn PRD +Tài liệu yêu cầu của dự án này nằm trên GitHub: [Xem PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/traffic-data-visualization-go/PRD.md) +::: + +
+ + + +
+ +## Phần 1: Phân tích yêu cầu + +### 1.1 Đọc PRD + +Mở tài liệu PRD, tập trung trả lời các câu hỏi sau: + +- Nguồn dữ liệu là gì? Có những trường nào? +- Định nghĩa của các chỉ số cốt lõi là gì? (Ví dụ tiêu chuẩn cụ thể của "tắc nghẽn") +- Quy tắc cảnh báo là gì? Phiên bản đầu tiên có nên thu hẹp lại thành quy tắc đơn giản không? +- Bảng điều khiển bao gồm những trang và biểu đồ nào? + +::: warning +Nếu các câu hỏi trên chưa có câu trả lời rõ ràng, đừng bắt đầu viết code. Hiểu sai yêu cầu là nguyên nhân phổ biến nhất dẫn đến phải làm lại. +::: + +### 1.2 Xác nhận chuỗi dữ liệu + +```mermaid +flowchart TD + prd["PRD"] --> ingest["API nhập dữ liệu"] + ingest --> raw["Bảng dữ liệu thô"] + raw --> agg["Tác vụ tổng hợp"] + agg --> alert["Quy tắc cảnh báo"] + agg --> dashboard["API bảng điều khiển"] + alert --> dashboard +``` + +## Phần 2: Xây dựng khung dự án + +### 2.1 Tạo dịch vụ Go API + +Tham khảo prompt: + +```text +Vui lòng dựa trên PRD hiện tại, giúp tôi tạo khung nền tảng phân tích dữ liệu giao thông bằng Go. + +Yêu cầu: +1. Sử dụng Gin hoặc Fiber +2. Cung cấp API nhập dữ liệu +3. Cung cấp khung tác vụ tổng hợp +4. Cung cấp khung API dashboard và alerts +5. Trước tiên không làm phân tích phức tạp thực tế, chỉ làm cấu trúc có thể chạy +``` + +### 2.2 Xác minh cấu trúc dự án + +Kiểm tra từng mục: + +- [ ] Dịch vụ Go có thể khởi động bình thường +- [ ] API nhập dữ liệu có thể nhận và lưu trữ dữ liệu +- [ ] Khung tác vụ tổng hợp đã được xây dựng +- [ ] Trang bảng điều khiển frontend có thể hiển thị biểu đồ cơ bản + +## Phần 3: Phát triển lặp + +### 3.1 Triển khai theo module + +1. **API nhập dữ liệu**: Nhận sự kiện giao thông thô, ghi vào cơ sở dữ liệu +2. **Tổng hợp dữ liệu**: Tổng hợp theo cửa sổ thời gian, tính toán xu hướng và chỉ số tắc nghẽn +3. **Quy tắc cảnh báo**: Tạo bản ghi cảnh báo dựa trên ngưỡng +4. **API bảng điều khiển**: Cung cấp dữ liệu xu hướng, dữ liệu xếp hạng, danh sách cảnh báo +5. **Bảng điều khiển frontend**: Trang biểu đồ xu hướng, bảng xếp hạng, danh sách cảnh báo + +### 3.2 Tự kiểm tra module + +| Mục kiểm tra | Phương pháp xác minh | +|--------|----------| +| Nhập dữ liệu | Dữ liệu thô có được lưu vào cơ sở dữ liệu chính xác không | +| Khẩu vị tổng hợp | Logic tính toán chỉ số xu hướng, xếp hạng có nhất quán không | +| Quy tắc cảnh báo | Điều kiện kích hoạt cảnh báo có khớp với kỳ vọng không | +| Tính nhất quán dữ liệu | Hiển thị bảng điều khiển và dữ liệu backend có khớp nhau không | +| Quy phạm API | Có cấu trúc trả về thống nhất và xử lý lỗi không | + +## Phần 4: Liên hợp và Triển khai + +### 4.1 Kiểm thử đầu cuối + +Ít nhất xác minh các kịch bản sau: + +- Nhập một loạt dữ liệu thử nghiệm → Thực thi tác vụ tổng hợp → Cập nhật hiển thị bảng điều khiển +- Kích hoạt điều kiện cảnh báo → Tạo bản ghi cảnh báo → Trang cảnh báo hiển thị + +## Sản phẩm bàn giao + +Sau khi hoàn thành dự án này, bạn cần nộp các nội dung sau: + +- [ ] Liên kết demo trực tuyến có thể truy cập +- [ ] Liên kết kho mã nguồn (bao gồm README) +- [ ] Tài liệu PRD +- [ ] Ảnh chụp màn hình các trang cốt lõi (demo nhập dữ liệu, bảng điều khiển xu hướng, danh sách cảnh báo) +- [ ] Video demo 60 giây + +## Tiêu chí chấm điểm + +| Chiều | Yêu cầu cơ bản | Yêu cầu nâng cao | +|------|---------|---------| +| Căn chỉnh PRD | Chức năng và cấu trúc dữ liệu cơ bản khớp với PRD | Có thể giải thích rõ ràng khẩu vị chỉ số và logic tổng hợp | +| Chuỗi dữ liệu | Nhập → Tổng hợp → Cảnh báo → Bảng điều khiển có thể chạy qua | Tác vụ tổng hợp hỗ trợ cập nhật gia tăng | +| Khả năng phân tích | Ba module xu hướng, xếp hạng, cảnh báo có thể sử dụng | Chỉ số có thể cấu hình, quy tắc cảnh báo có thể tùy chỉnh | +| Hiển thị frontend | Bảng điều khiển có thể hiển thị biểu đồ cơ bản | Biểu đồ hỗ trợ lọc phạm vi thời gian | +| Độ hoàn thiện kỹ thuật | Chuỗi Go API, cơ sở dữ liệu, frontend đã kết nối | API có xử lý lỗi thống nhất và nhật ký | + +## Tài liệu tham khảo + +- [Thiết kế UI](../../frontend/ui-design/) +- [Sử dụng thư viện component hiện đại để cập nhật giao diện](../../frontend/modern-component-library/) +- [Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/) +- [Mô hình hỗ trợ viết code API và tài liệu API bằng mô hình lớn](../../backend/ai-interface-code/) +- [Quy trình làm việc Git và GitHub](../../backend/git-workflow/) +- [Cách triển khai ứng dụng Web](../../backend/zeabur-deployment/) diff --git a/docs/vi-vn/stage-2/assignments/travel-planning-agent-platform/index.md b/docs/vi-vn/stage-2/assignments/travel-planning-agent-platform/index.md new file mode 100644 index 0000000..7a57f2c --- /dev/null +++ b/docs/vi-vn/stage-2/assignments/travel-planning-agent-platform/index.md @@ -0,0 +1,164 @@ +# Thực hành phát triển nền tảng Agent lập kế hoạch du lịch thông minh + +## Tổng quan + +Dự án thực chiến này yêu cầu bạn hoàn thành một nền tảng Agent lập kế hoạch du lịch thông minh dựa trên một PRD thực tế, xây dựng từ đầu. Bạn sẽ xây dựng một sản phẩm AI hoàn chỉnh có thể nhận đầu vào có cấu trúc, tạo lịch trình hàng ngày, hỗ trợ lưu trữ và tái sử dụng — không chỉ là chatbot, mà là một sản phẩm có khả năng quản lý tác vụ. + +Đây là phần thực hành tổng hợp của Stage 2. Thách thức cốt lõi của dự án này là: làm thế nào để AI tạo ra kế hoạch lịch trình có cấu trúc và sử dụng được, chứ không phải một đoạn văn bản dài không thể thao tác. + +## Kiến thức tiên quyết + +Trước khi bắt đầu dự án này, bạn nên đã nắm được các nội dung sau: + +- Thiết kế trang frontend và sử dụng thư viện component ([Thiết kế UI](../../frontend/ui-design/), [Thư viện component hiện đại](../../frontend/modern-component-library/)) +- Thiết kế và phát triển API backend ([Viết code API](../../backend/ai-interface-code/)) +- Cơ sở dữ liệu cơ bản và Supabase ([Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/)) +- Quy trình làm việc Git và triển khai ([Git và GitHub](../../backend/git-workflow/), [Triển khai ứng dụng Web](../../backend/zeabur-deployment/)) + +## Mục tiêu học tập + +Sau khi hoàn thành bài thực hành này, bạn sẽ có thể: + +1. Đọc PRD và từ đó trích xuất danh sách công việc phát triển nền tảng Agent +2. Thiết kế biểu mẫu đầu vào có cấu trúc và định dạng đầu ra có cấu trúc +3. Triển khai lớp điều phối Agent, xử lý đầu vào người dùng, gọi mô hình và lưu trữ kết quả +4. Xây dựng chuỗi nghiệp vụ "tạo → lưu → tái sử dụng" +5. Hoàn thành liên hợp đầu cuối, bàn giao nguyên mẫu sản phẩm AI có thể demo + +## Giới thiệu dự án + +Sản phẩm bạn cần xây dựng là một nền tảng Agent lập kế hoạch du lịch thông minh: + +| Chức năng | Mô tả | +|------|------| +| **Lập kế hoạch lịch trình** | Người dùng nhập điểm xuất phát, điểm đến, ngày, ngân sách và sở thích, hệ thống tạo lịch trình hàng ngày | +| **Phân bổ ngân sách** | Kết quả lịch trình bao gồm phân bổ ngân sách và đề xuất | +| **Quản lý lịch sử** | Người dùng có thể lưu kế hoạch lịch sử, tạo lại, xuất | +| **Back-office quản trị** | Quản trị viên xem điểm đến phổ biến, tác vụ thất bại và phản hồi người dùng | + +::: tip Đường dẫn PRD +Tài liệu yêu cầu của dự án này nằm trên GitHub: [Xem PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-cn/stage-2/assignments/travel-planning-agent-platform/PRD.md) +::: + +
+ + + +
+ +## Phần 1: Phân tích yêu cầu + +### 1.1 Đọc PRD + +Mở tài liệu PRD, tập trung trả lời các câu hỏi sau: + +- Phiên bản đầu tiên có chỉ làm một điểm đến không? +- Đầu ra lịch trình có bắt buộc phải có cấu trúc không? Cấu trúc là gì? +- Khả năng xuất sâu đến đâu? (Liên kết chia sẻ / PDF / Hình ảnh) +- Phạm vi thống kê back-office và nhật ký tác vụ là gì? + +::: warning +Nếu các câu hỏi trên chưa có câu trả lời rõ ràng, đừng bắt đầu viết code. Hiểu sai yêu cầu là nguyên nhân phổ biến nhất dẫn đến phải làm lại. +::: + +### 1.2 Xác nhận kiến trúc hệ thống + +```mermaid +flowchart TD + prd["PRD"] --> planner["Trang lập kế hoạch"] + planner --> agent["Lớp điều phối Agent"] + agent --> model["Gọi mô hình"] + agent --> db["Cơ sở dữ liệu"] + db --> history["Kế hoạch lịch sử"] + db --> admin["Thống kê & nhật ký back-office"] +``` + +## Phần 2: Xây dựng khung dự án + +### 2.1 Tạo trang frontend + +Tham khảo prompt: + +```text +Vui lòng dựa trên PRD hiện tại, giúp tôi tạo khung frontend của nền tảng Agent lập kế hoạch du lịch thông minh. + +Yêu cầu: +1. Trang bao gồm: trang chủ, trang lập kế hoạch, trang chi tiết lịch trình, trang lịch sử, trang quản lý +2. Trang lập kế hoạch bên trái là biểu mẫu, bên phải là xem trước kết quả +3. Trước tiên chỉ tạo cấu trúc trang và dữ liệu giả, không kết nối API thực tế +4. Phong cách phải giống sản phẩm AI hiện đại +``` + +### 2.2 Xác minh cấu trúc trang + +Kiểm tra từng mục: + +- [ ] Trường biểu mẫu trang lập kế hoạch có khớp với PRD không +- [ ] Khu vực xem trước kết quả có thể hiển thị dữ liệu lịch trình có cấu trúc +- [ ] Trang lịch sử có thể hiển thị nhiều kế hoạch +- [ ] Trang back-office quản trị có thể hiển thị dữ liệu thống kê + +## Phần 3: Phát triển lặp + +### 3.1 Triển khai theo module + +1. **Xác thực**: Đăng ký, đăng nhập +2. **Biểu mẫu lập kế hoạch**: Đầu vào có cấu trúc (điểm xuất phát, điểm đến, ngày, ngân sách, sở thích) +3. **Điều phối Agent**: Nhận đầu vào → Gọi mô hình → Phân tích đầu ra có cấu trúc +4. **Hiển thị kết quả**: Lịch trình hiển thị theo ngày, phân bổ ngân sách, đề xuất +5. **Quản lý lịch sử**: Lưu kế hoạch, tạo lại, xuất +6. **Back-office quản trị**: Điểm đến phổ biến, tác vụ thất bại, phản hồi người dùng +7. **Trạng thái tác vụ**: Quản lý trạng thái đang tạo / thành công / thất bại và ghi lỗi + +### 3.2 Tự kiểm tra module + +| Mục kiểm tra | Phương pháp xác minh | +|--------|----------| +| Tính đầy đủ đầu vào | Trường biểu mẫu có khớp với PRD không | +| Tính cấu trúc đầu ra | Kết quả lịch trình có phải là dữ liệu có cấu trúc (chứ không phải một đoạn văn bản dài) không | +| Tính nhất quán dữ liệu | Dữ liệu trip, itinerary, logs có khớp nhau không | +| Xác minh chuỗi hoàn chỉnh | Có thể demo "nhập → tạo → lưu → tạo lại" không | + +## Phần 4: Liên hợp và Triển khai + +### 4.1 Kiểm thử đầu cuối + +Ít nhất xác minh các kịch bản sau: + +- Nhập tham số lịch trình → Tạo lịch trình hàng ngày → Xem phân bổ ngân sách → Lưu vào lịch sử +- Tạo lại lịch trình từ bản ghi lịch sử +- Quản trị viên xem thống kê tác vụ và nhật ký thất bại + +## Sản phẩm bàn giao + +Sau khi hoàn thành dự án này, bạn cần nộp các nội dung sau: + +- [ ] Liên kết demo trực tuyến có thể truy cập +- [ ] Liên kết kho mã nguồn (bao gồm README) +- [ ] Tài liệu PRD +- [ ] Ảnh chụp màn hình các trang cốt lõi (trang lập kế hoạch, trang chi tiết lịch trình, trang lịch sử, back-office quản trị) +- [ ] Video demo 60 giây + +## Tiêu chí chấm điểm + +| Chiều | Yêu cầu cơ bản | Yêu cầu nâng cao | +|------|---------|---------| +| Căn chỉnh PRD | Trang, chức năng, cấu trúc dữ liệu cơ bản khớp với PRD | Có thể giải thích rõ ràng quyết định thiết kế | +| Chuỗi sản phẩm | Lập kế hoạch → Lưu → Lịch sử → Tạo lại có thể chạy qua | Hỗ trợ xuất và chia sẻ | +| Chất lượng đầu ra | Kết quả lịch trình có cấu trúc và dễ đọc | Phân bổ ngân sách hợp lý, đề xuất có tính định hướng | +| Khả năng back-office | Thống kê tác vụ và nhật ký thất bại có thể xem | Có phân tích điểm đến phổ biến | +| Độ hoàn thiện kỹ thuật | Frontend, backend, cơ sở dữ liệu, chuỗi gọi mô hình đã kết nối | Quản lý trạng thái tác vụ hoàn thiện, lỗi có thể truy vết | + +## Tài liệu tham khảo + +- [Thiết kế UI](../../frontend/ui-design/) +- [Sử dụng thư viện component hiện đại để cập nhật giao diện](../../frontend/modern-component-library/) +- [Từ cơ sở dữ liệu đến Supabase](../../backend/database-supabase/) +- [Mô hình hỗ trợ viết code API và tài liệu API bằng mô hình lớn](../../backend/ai-interface-code/) +- [Quy trình làm việc Git và GitHub](../../backend/git-workflow/) +- [Cách triển khai ứng dụng Web](../../backend/zeabur-deployment/) diff --git a/docs/vi-vn/stage-2/backend/ai-interface-code/index.md b/docs/vi-vn/stage-2/backend/ai-interface-code/index.md new file mode 100644 index 0000000..ae85fa0 --- /dev/null +++ b/docs/vi-vn/stage-2/backend/ai-interface-code/index.md @@ -0,0 +1,161 @@ +# Mô hình lớn hỗ trợ viết mã giao diện và tài liệu giao diện + +Trong các bài học trước, chúng ta đã học cách sử dụng các công cụ như Figma để hoàn thành bản thiết kế UI, cách借助 AI nhanh chóng tạo trang tĩnh frontend, và cách sử dụng Supabase để xây dựng cơ sở dữ liệu và thực hiện xác thực người dùng cơ bản. Bây giờ, một câu hỏi tự nhiên xuất hiện: sau khi nhấn các nút đầy动感 trên trang frontend, dữ liệu thực sự đã được âm thầm lưu vào Supabase như thế nào? Khi chúng ta cần thực hiện logic nghiệp vụ phức tạp hơn (như thanh toán đồng thời, đẩy thông báo định kỳ, xử lý dữ liệu nhạy cảm), việc để frontend kết nối trực tiếp với cơ sở dữ liệu có an toàn không? + +Điều này dẫn đến một khâu then chốt trong kiến trúc phát triển Web hiện đại — **giao diện API backend**. + +So với việc trước đây phải tự gõ hàng trăm hàng nghìn dòng route backend, controller và logic xác thực tham số, giờ đây chúng ta hoàn toàn có thể借助 sức mạnh tạo mã của mô hình lớn, giao phó phần code cơ sở rườm rà cho AI viết. Trong bài học này, chúng ta sẽ thoát khỏi vòng lặp "AI viết rất hời hợt", dựa trên các kịch bản nghiệp vụ thực tế, hướng dẫn bạn cách thông qua các prompt chất lượng cao (Prompt) dẫn dắt mô hình lớn viết các giao diện backend Node.js mạnh mẽ, tuân thủ quy chuẩn ngành, và tự động hoàn thành việc tạo tài liệu giao diện và test case. + +> 💡 **Kiến thức tiên quyết** +> +> Trước khi học phần này, bạn nên tìm hiểu các nội dung sau: +> - [Từ cơ sở dữ liệu đến Supabase](../database-supabase/) - Hiểu về khái niệm cơ sở dữ liệu và mô hình dữ liệu. +> - [Học sử dụng Git và Github](../git-workflow/) - Làm quen với cách kiểm soát phiên bản trong phát triển dự án. +> - [Terminal/Dòng lệnh là gì](/vi-vn/appendix/2-development-tools/command-line-shell) - Khởi tạo và chạy dự án không thể tách khỏi các thao tác dòng lệnh cơ bản. + +# Bạn sẽ học được gì + +1. **Giao diện API là gì**: Hiểu cầu nối giao tiếp frontend-backend và quy chuẩn thiết kế RESTful. +2. **Mô hình lớn hỗ trợ xây dựng dịch vụ**: Cách thông qua Prompt có cấu trúc để AI giúp bạn xây dựng dự án cơ bản Node.js + Express. +3. **Phát triển logic giao diện**: Dẫn dắt mô hình lớn tạo các giao diện CRUD (thêm, đọc, sửa, xóa) bao gồm xác thực nghiệp vụ nghiêm ngặt và kết nối cơ sở dữ liệu Supabase. +4. **Tài liệu giao diện tự động**: Để mô hình_large dựa trên code tạo tài liệu OpenAPI/Swagger tiêu chuẩn cho cộng tác liên đội. +5. **Vòng lặp kiểm thử và tích hợp**: Sử dụng mô hình_large để tạo bộ kiểm thử Postman và unit test Jest, đảm bảo chất lượng code. + +--- + +# 1. Tại sao chúng ta cần giao diện API? + +Trong cách hiểu truyền thống, frontend là "phần có thể nhìn thấy", cơ sở dữ liệu là "kho chứa đồ". Nhưng ở giữa thiếu một người điều phối. Nếu bạn tưởng tượng toàn bộ ứng dụng là một nhà hàng: +- **Frontend (Client)** là menu và bàn đặt món của nhà hàng, khách hàng duyệt món và đưa ra yêu cầu tại đây. +- **Cơ sở dữ liệu (Supabase, v.v.)** là kho của bếp nhà hàng, nơi lưu trữ tất cả nguyên liệu và sổ kế toán. +- **Giao diện API backend** là nhân viên phục vụ của nhà hàng. Khách hàng không thể trực tiếp chạy vào bếp lấy nguyên liệu (không chỉ lộn xộn mà còn dễ gây vấn đề an toàn), mà cần đưa "yêu cầu đặt món" (HTTP Request) cho nhân viên phục vụ. Nhân viên phục vụ tiến hành xác nhận (xác thực tham số, xác thực quyền), sau đó vào bếp lấy nội dung tương ứng, rồi mang "món đã làm xong" (HTTP Response, thường là dữ liệu dạng JSON) ra cho khách hàng. + +Thông qua giao diện API, chúng ta thực hiện **tách biệt frontend-backend** rõ ràng: frontend chỉ quan tâm đến cách render trang, backend chỉ tập trung vào logic nghiệp vụ, xử lý dữ liệu và bảo vệ an toàn. + +--- + +# 2. Thiết kế kiến trúc dự án và khởi tạo + +Một cấu trúc dự án rõ ràng là điều kiện tiên quyết để mô hình_large có thể viết code tốt. Trước khi để AI viết code, bản thân chúng ta phải hiểu rõ cấu trúc dự án. + +## 2.1 Cấu trúc dự án API phổ biến +Ngay cả khi sử dụng mô hình_large để tạo code, chúng ta tuyệt đối không nên nhét tất cả code vào một file `server.js`. Một kiến trúc backend Node.js dễ bảo trì thường có dạng như sau: + +```text +my-api-project/ +├── .env # Biến môi trường nhạy cảm (như API Keys, chuỗi kết nối cơ sở dữ liệu) +├── server.js # Điểm vào dự án (khởi động server, đăng ký middleware toàn cục) +├── package.json # File quản lý dependency +├── src/ +│ ├── routes/ # Lớp route: định nghĩa đường dẫn URL và phương thức yêu cầu +│ ├── controllers/ # Lớp controller: xử lý tham số yêu cầu nghiệp vụ, gọi service và trả về response +│ ├── services/ # Lớp service: đóng gói tương tác cơ sở dữ liệu và logic nghiệp vụ cốt lõi +│ └── middlewares/ # Middleware: xác thực đăng nhập, bắt lỗi toàn cục +└── docs/ # Thư mục lưu tài liệu API +``` + +## 2.1借助 AI hoàn thành khởi tạo dự án +Thay vì tự `npm init` và cài đặt từng dependency, tốt hơn là đưa quy chuẩn trên cho mô hình_large dưới dạng Prompt: + +> 🗣️ **Prompt cho mô hình_large (Ví dụ Prompt):** +> "Giúp tôi xây dựng một dự án backend Node.js, có thể kết nối cơ sở dữ liệu Supabase, cấu trúc rõ ràng, thuận tiện bảo trì sau này." + +Sau khi chạy code mà AI trả về, bạn sẽ có một ứng dụng backend với quy mô doanh nghiệp tại `localhost:3000`. + +--- + +# 3. Thực hành cốt lõi: Mô hình_large hỗ trợ phát triển giao diện + +Đây là phần cốt lõi nhất của chương này. Code do mô hình_large viết thường dễ có "lỗ hổng logic" hoặc "xào nấu hời hợt", nguyên nhân là do ngữ cảnh mà developer cung cấp không đủ. **Mô hình_large không sợ yêu cầu phức tạp, chỉ sợ yêu cầu mơ hồ.** + +Lấy ví dụ về interface thêm mới cho bảng `menu_items` (bảng menu) được đề cập trong [chương cơ sở dữ liệu](../database-supabase/), hãy xem cách viết một Prompt chất lượng cao. + +## 3.1 Cung cấp đầy đủ ngữ cảnh cho mô hình_large +Trước khi yêu cầu AI viết giao diện, nhất định phải cung cấp **định nghĩa trường cơ sở dữ liệu (Schema)** và **điều kiện ràng buộc cụ thể**. + +> 🗣️ **Mẫu Prompt chất lượng cao:** +> "Giúp tôi viết một interface thêm menu mới, menu có tên sản phẩm, giá, phân loại (burger, đồ ăn nhẹ, đồ uống), và thông tin có上架 hay không. Tên sản phẩm và giá là bắt buộc, giá không thể là số âm. Khi người dùng nhập sai cần hiện thông báo lỗi." + +## 3.2 Xem xét code do mô hình_large tạo +Code do mô hình_large tạo thường sẽ phân tách trách nhiệm rõ ràng như sau: + +```javascript +// services/menuService.js +const { createClient } = require('@supabase/supabase-js') +const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY) + +exports.createMenuItem = async (menuData) => { + // Gọi Supabase SDK đẩy dữ liệu vào bảng + const { data, error } = await supabase + .from('menu_items') + .insert([menuData]) + .select() + + if (error) throw new Error(`Chèn cơ sở dữ liệu thất bại: ${error.message}`) + return data[0] +} +``` + +Bạn có thể thấy, code được tạo theo cách này không chỉ có cấu trúc hợp lý mà còn tính đến khởi tạo Supabase, bắt lỗi và xử lý ngoại lệ, hoàn toàn khác biệt với Spaghetti Code khi chỉ đơn giản yêu cầu "viết một interface thêm mới". + +--- + +# 4. Giải phóng đôi tay: Tự động tạo tài liệu giao diện + +Đối với đội ngũ phát triển, một API không có tài liệu giống như một món đồ bí ẩn. Kỹ sư frontend không thể đoán được bạn cần truyền vào tham số gì, cũng không thể dự đoán cấu trúc trả về sẽ như thế nào. Quy chuẩn mô tả API phổ biến nhất trong ngành là **OpenAPI (trước đây còn gọi là Swagger)**. + +Trước đây, việc tự viết tài liệu Swagger dạng YAML hoặc JSON cực kỳ đau đớn và dễ sai. Bây giờ, đây cũng trở thành lĩnh vực mà mô hình_large giỏi nhất. + +Bạn có thể chọn trực tiếp code `routes` và `controllers` vừa viết, rồi đưa cho mô hình_large: + +> 🗣️ **Prompt tạo tài liệu:** +> "Giúp tôi dựa trên code trên tạo một tài liệu giao diện, cần ghi rõ ý nghĩa của từng tham số, trả về dữ liệu gì, thuận tiện cho đồng nghiệp frontend đối接." + +Trong quá trình này, bạn thậm chí có thể yêu cầu AI bổ sung mô tả trường (Description) và dữ liệu Mock (ví dụ `price_cents: 1200` đại diện cho 12 USD), giảm đáng kể chi phí giao tiếp. + +--- + +# 5. Bảo đảm chất lượng: Tạo code kiểm thử và bộ sưu tập Postman + +Code đã viết, tài liệu đã hoàn thành, còn thiếu bước cuối cùng: xác minh xem code có thực sự chạy được hay không. + +## 5.1 Tạo cấu hình kiểm thử Postman / Apifox +Trong phát triển giao diện, chúng ta thường sử dụng các công cụ trực quan như Postman để mô phỏng frontend gửi yêu cầu HTTP. Nếu không sử dụng mô hình_large, bạn cần tự nhập URL, thêm từng Header (tiêu đề yêu cầu) và nối JSON request body. + +Bạn chỉ cần gửi lệnh cho AI: +> "Giúp tôi chuyển tài liệu giao diện này sang định dạng có thể import vào Postman, cần bao gồm cả ví dụ yêu cầu bình thường và yêu cầu lỗi." + +Sau khi nhận được văn bản JSON, lưu thành `menu_api.json` và kéo vào Postman, bạn ngay lập tức có một bảng điều khiển kiểm thử sẵn sàng sử dụng. + +## 5.2 Viết unit test tự động +Nếu bạn theo đuổi chất lượng kỹ thuật nghiêm ngặt hơn, có thể để mô hình_large giúp bạn sử dụng framework kiểm thử như `Jest` để viết unit test, kiểm tra biên cho logic nghiệp vụ cốt lõi (ví dụ: khi truyền vào giá âm, liệu xác thực ở tầng cơ sở dữ liệu có hiệu lực hay không). + +--- + +# 6. Thực hành tốt nhất cần biết về giao diện backend + +Ngay cả khi có sự hỗ trợ của AI, với tư cách là "người gác cổng" của toàn bộ hệ thống, bạn vẫn cần hiểu và kiểm duyệt các nguyên tắc cốt lõi sau: + +1. **Đặt tên đường dẫn theo quy chuẩn RESTful**: + - Thiết kế tốt: `GET /api/users` (lấy danh sách người dùng), `POST /api/users` (tạo người dùng). URL nên là danh từ đại diện cho "tài nguyên". + - Thiết kế sai: `POST /api/getUser` hoặc `POST /api/createUser`. Động từ nên được thể hiện bằng HTTP Method (GET/POST/PUT/DELETE). +2. **Mã trạng thái HTTP theo quy chuẩn**: + - 200/201: Yêu cầu thành công / Tạo tài nguyên thành công. + - 400: Bad Request, định dạng tham số truyền từ frontend sai, thiếu mục bắt buộc. + - 401/403: Unauthorized / Forbidden, người dùng chưa đăng nhập hoặc không có quyền thao tác. + - 404: NotFound, tài nguyên không tồn tại. + - 500: Server Error, code backend bị lỗi hoặc cơ sở dữ liệu sập, tuyệt đối tránh hiển thị error call stack cho frontend (có rủi ro an ninh). +3. **Không bao giờ tin tưởng đầu vào của người dùng**: Đầu vào từ frontend có thể bị giả mạo, tất cả xác thực tham số cốt lõi phải được thực hiện lại tại giao diện backend. + +# 7. Tổng kết + +Thông qua việc học chương này, bạn đã thực sự chuyển đổi góc nhìn phát triển: bạn không còn là "người đánh máy" bị mắc kẹt trong cú pháp và dấu câu, mà đã trở thành **nhà thiết kế hệ thống và chỉ huy kiến trúc**. +Bạn đã nắm được: +1. Tư duy hệ thống cốt lõi về **giao diện API và tách biệt frontend-backend**. +2. **Cách cung cấp ngữ cảnh và khái niệm cấu trúc phân tầng**, nâng cao đáng kể chất lượng code backend do mô hình_large tạo. +3. Biến công việc **viết tài liệu** và **xây dựng test case** rườm rà thành tác vụ tự động hóa mà AI giỏi thực hiện. +4. Kết hợp kiến thức **Supabase** đã học trước đó, hoàn thành dòng dữ liệu từ yêu cầu client đến cập nhật cơ sở dữ liệu. + +::: tip 💡 Bước tiếp theo +Khi dòng dữ liệu và dịch vụ backend của bạn đã sẵn sàng, hiện tại nó vẫn chỉ có thể "tự giải trí" trên máy tính cục bộ của bạn. Trong các chương tiếp theo, chúng ta sẽ học cách **triển khai (Deploy)** dịch vụ này lên máy chủ công cộng, để sản phẩm của bạn có thể được truy cập bởi người dùng trên toàn thế giới. +::: diff --git a/docs/vi-vn/stage-2/backend/database-supabase/index.md b/docs/vi-vn/stage-2/backend/database-supabase/index.md new file mode 100644 index 0000000..16f6ff2 --- /dev/null +++ b/docs/vi-vn/stage-2/backend/database-supabase/index.md @@ -0,0 +1,1726 @@ +# Từ Cơ sở dữ liệu đến Supabase + +Trong bài học trước, chúng ta đã học cách sử dụng cơ bản các công cụ thiết kế UI là Mastergo và Figma, biết cách sử dụng github để lấy mã nguồn và quản lý phiên bản, đồng thời triển khai trang web thông qua Zeabur để đưa ứng dụng / trang web của mình đến với nhiều người dùng hơn. + +Để giúp các bạn kết nối kiến thức tốt hơn, trước khi bắt đầu nội dung mới về công cụ thiết kế và triển khai trong bài học này, chúng ta hãy cùng ôn lại nhanh các kiến thức cốt lõi của bài trước thông qua một vài câu hỏi đơn giản: + +1. Công cụ thiết kế frontend là gì, định nghĩa và cách sử dụng Figma, MasterGo. +2. Phương pháp cơ bản để chuyển đổi bản thiết kế thành mã nguồn. +3. Github là gì, cách cấu hình SSH, cách tạo kho lưu trữ đầu tiên của bạn. +4. Triển khai (deployment) nghĩa là gì, cách sử dụng Zeabur, cách triển khai mã nguồn từ Github hoặc local lên mạng công khai để mọi người truy cập. + +Nếu bạn còn mơ hồ về bất kỳ câu hỏi nào ở trên, hãy xem lại tài liệu và bài giảng của bài học trước. Bạn cũng có thể đặt câu hỏi bất cứ lúc nào trong nhóm học tập WeChat. + +Trong bài học này, chúng ta sẽ học cách biến một APP / trang web từ trạng thái "chạy được" thành sản phẩm thực tế gần hơn: ngoài việc sử dụng cơ sở dữ liệu để quản lý các thay đổi dữ liệu trong quá trình chạy ứng dụng, còn cần phải có hệ thống người dùng hoàn chỉnh (đăng ký, đăng nhập, phân quyền...) cùng các khả năng backend quan trọng khác. Chúng ta sẽ lấy nền tảng dịch vụ backend Supabase làm主线, đầu tiên sử dụng nó để thực hiện hai chức năng cơ bản là "cơ sở dữ liệu + hệ thống người dùng", sau đó tham khảo các thành phần do Supabase cung cấp để hiểu rõ hơn về các mô-đun cốt lõi mà dịch vụ backend đám mây hiện đại thường bao gồm, cũng như chức năng và logic hoạt động cụ thể của từng mô-đun. + +# Bạn sẽ học được gì + +1. Dữ liệu là gì, cơ sở dữ liệu là gì, các cơ sở dữ liệu phổ biến và cách sử dụng +2. Supabase là gì, cách sử dụng Supabase để thực hiện các thao tác cơ sở dữ liệu cơ bản +3. Cách sử dụng Supabase để thêm chức năng quản lý người dùng cơ bản cho ứng dụng +4. Học các tính năng nâng cao của Supabase: realtime, storage, edge function +5. Học cách thêm hỗ trợ đăng nhập Google và GitHub cho Supabase + +- Một ứng dụng cơ bản hỗ trợ đăng ký / đăng nhập người dùng và có thể lưu trữ dữ liệu vào cơ sở dữ liệu trực tuyến +- Một bộ mẫu mã backend Supabase có thể tái sử dụng (quản lý cơ sở dữ liệu + người dùng, v.v.), để áp dụng trực tiếp cho các dự án tiếp theo + +# 1. Cơ sở dữ liệu là gì + +## 1.1 Dữ liệu là gì + +Trong thế giới kỹ thuật số, dữ liệu (Data) có mặt ở khắp nơi. Nói một cách đơn giản, dữ liệu là载体 của thông tin. Thông tin liên lạc của bạn bè, một bài viết trên WeChat, một video ngắn, cấp độ nhân vật trong game - tất cả这些都是 dữ liệu. Trong ứng dụng của chúng ta, dữ liệu là mọi thông tin cần được ghi lại và quản lý, chẳng hạn như hồ sơ cá nhân của người dùng, lịch sử đơn hàng, cài đặt chương trình, v.v. + +Nói chung, dữ liệu có nhiều dạng biểu diễn khác nhau trong chương trình, đơn giản nhất là biến. Chúng ta có thể dùng các biến khác nhau để ghi lại các con số đơn giản: + +```python +# Python variable definition examples + +# Integer variable: stores age information +age = 30 + +# Boolean variable: stores status (whether active) +is_active = True # True means active, False means inactive + +# List variable: stores a set of score data +scores = [85, 92, 78, 90] # Contains 4 integer elements representing different scores + +# Dictionary variable: stores multiple related information of a user +user_info = { + "age": 30, # Key "age" corresponds to the value of age + "height": 1.80, # Key "height" corresponds to the value of height (unit: meter) + "login_count": 156 # Key "login_count" corresponds to the value of login times +} +``` + +Đối với các dữ liệu phức tạp như hồ sơ cá nhân và lịch sử đơn hàng đã đề cập ở trên, chúng ta có thể sử dụng bảng biểu phức tạp hơn để biểu diễn dữ liệu: + +| user_id | name | email | +| ------- | ----- | ----------------- | +| 1001 | Alice | alice@example.com | +| 1002 | Bob | bob@example.com | + +| order_id | user_id | amount | status | +| -------- | ------- | ------ | --------- | +| 901 | 1001 | 29.99 | completed | +| 902 | 1002 | 15.50 | pending | + +Nhưng đối với các dữ liệu có cấu trúc phức tạp, có quan hệ phân cấp hoặc các trường không cố định, chúng ta có thể sử dụng định dạng JSON để mô tả — đây là định dạng trung gian dữ liệu phổ thông trên internet, hầu hết tất cả các chương trình đều có thể đọc và phân tích, rất tiện lợi khi truyền dữ liệu giữa các hệ thống. Ví dụ, một đơn hàng có thể chứa nhiều sản phẩm, mỗi sản phẩm lại có tên, số lượng và giá riêng. Việc biểu diễn bằng bảng truyền thống sẽ rất cồng kềnh: hoặc phải chia thành nhiều bảng "bảng đơn hàng" "bảng sản phẩm", dựa vào trường liên kết mới có thể thể hiện mối quan hệ "đơn hàng chứa sản phẩm"; hoặc sử dụng các trường thừa như "tên sản phẩm 1, giá sản phẩm 1, tên sản phẩm 2..." trong một bảng, hoàn toàn không thể thích ứng khi số lượng sản phẩm không cố định; trong khi JSON có thể sử dụng cấu trúc lồng nhau để làm rõ phân cấp "đơn hàng - sản phẩm - thuộc tính sản phẩm", vừa trực quan vừa linh hoạt. + +```json +{ + "order_id": 901, + "user_id": 1001, + "amount": 29.99, + "status": "completed", + "items": [ + { "sku": "BG-001", "name": "Bò băm bub-gơ", "quantity": 1, "price": 18.00 }, + { "sku": "SD-003", "name": "Khoai tây chiên", "quantity": 1, "price": 6.99 }, + { "sku": "DK-002", "name": "Cola", "quantity": 1, "price": 5.00 } + ], + "shipping_address": { + "street": "Công viên Khoa học và Công nghệ số 123", + "city": "Thâm Quyến", + "zip_code": "518057" + } +} +``` + +Xa hơn nữa, nếu chúng ta xem xét dữ liệu được mã hóa thành vector (Vector), dữ liệu vector thường là biểu diễn số thu được sau khi dữ liệu phi cấu trúc như văn bản, hình ảnh hoặc âm thanh được xử lý qua mô hình AI (như mô hình Embedding). Dạng biểu diễn của nó có thể là: + +`[0.123, -0.456, 0.789, ..., -0.234]` (một mảng gồm hàng trăm thậm chí hàng nghìn số dấu phẩy động) + +Nhìn chung, trong thế giới thực có rất nhiều dữ liệu với nhiều hình thái và mục đích sử dụng khác nhau đáng để chúng ta phân tích chi tiết, mỗi loại dữ liệu có thể都需要 cơ sở dữ liệu chuyên dụng để lưu trữ, cụ thể có thể tham khảo sơ đồ dưới đây — có phải cảm thấy rất nhiều không? + +![](/zh-cn/stage-2/backend/database-supabase/images/image1.png) + +## 1.2 Tại sao chúng ta cần cơ sở dữ liệu + +Chúng ta đã hiểu rằng dữ liệu trong thế giới thực thường có cấu trúc phức tạp, **để lưu trữ và sử dụng dữ liệu này một cách hiệu quả, chúng ta cần một chương trình hoặc container chuyên dụng để quản lý chúng** — đây chính là mục đích ra đời của cơ sở dữ liệu (Database). Về bản chất, cơ sở dữ liệu là một chương trình đặc biệt, có vai trò cốt lõi là tổ chức dữ liệu một cách chuẩn hóa, lưu trữ an toàn, quản lý có hệ thống và hỗ trợ truy vấn gọi hiệu quả. + +Hãy tưởng tượng, nếu không có cơ sở dữ liệu, dữ liệu ứng dụng sẽ rơi vào tình trạng thế nào? Khi người dùng đóng trình duyệt hoặc thoát ứng dụng, tất cả thông tin được tải tạm thời sẽ bị mất trực tiếp; chúng ta không thể lưu trữ vĩnh viễn trạng thái sử dụng của người dùng (như thông tin đăng nhập, cài đặt cá nhân hóa), cũng không thể chia sẻ dữ liệu quan trọng giữa các người dùng (như tồn kho sản phẩm, hồ sơ đơn hàng). Chúng ta cần có một thiết bị giúp lưu trữ tất cả dữ liệu của mình! + +Linh hoạt hơn, cách triển khai cơ sở dữ liệu có thể được chọn theo nhu cầu: có thể triển khai trên máy chủ cục bộ, đáp ứng nhu cầu quản lý dữ liệu tại chỗ; cũng có thể triển khai trên đám mây, cơ sở dữ liệu đám mây hỗ trợ mở rộng linh hoạt (Scale), có thể mở rộng năng lực theo sự gia tăng của lượng dữ liệu và lượng truy cập, chịu được lượng dữ liệu khổng lồ và đồng thời cao, ngay cả khi lượng người dùng tăng mạnh, vẫn đảm bảo trải nghiệm sử dụng bình thường của người dùng. + +Tóm lại, cơ sở dữ liệu凭借 khả năng lưu trữ bền vững hiệu quả, quản lý tinh tế và truy vấn nhanh chóng, chủ yếu giải quyết các vấn đề cốt lõi sau: + +- **Lưu trữ bền vững dữ liệu**: Nếu không có cơ sở dữ liệu, dữ liệu sẽ chỉ tồn tại trong bộ nhớ của ứng dụng, một khi ứng dụng đóng, dữ liệu sẽ bị mất. Cơ sở dữ liệu giải quyết vấn đề này, nó lưu trữ dữ liệu bền vững trên các phương tiện lưu trữ như ổ cứng, đảm bảo việc lưu trữ dài hạn dữ liệu, giảm nguy cơ mất mát. +- **Truy vấn và phân tích dữ liệu tiện lợi**: Cơ sở dữ liệu cung cấp ngôn ngữ truy vấn mạnh mẽ (như SQL), cho phép người dùng dễ dàng, hiệu quả thực hiện các truy vấn, lọc và phân tích phức tạp trên lượng dữ liệu khổng lồ, giúp doanh nghiệp đưa ra quyết định sáng suốt hơn. Nếu không có cơ sở dữ liệu, việc tìm kiếm thông tin cụ thể từ một lượng lớn tập tin không có thứ tự sẽ là một nhiệm vụ cực kỳ tốn thời gian và khó khăn. +- **Hỗ trợ truy cập hiệu năng cao và đồng thời cao**: Cơ sở dữ liệu thông qua các công nghệ như tối ưu hóa chỉ mục, bộ đệm truy vấn, pool kết nối và kiến trúc phân tán, có thể phản hồi yêu cầu truy vấn trong thời gian mili-giây và hỗ trợ hàng nghìn người dùng truy cập đồng thời. Điều này rất quan trọng đối với các ứng dụng internet hiện đại (như hoạt động flash sale trên nền tảng thương mại điện tử, feed thời gian thực trên mạng xã hội), đảm bảo tốc độ phản hồi của hệ thống và trải nghiệm người dùng. Nếu không có hỗ trợ hiệu năng cao của cơ sở dữ liệu, hệ thống sẽ gặp độ trễ nghiêm trọng hoặc thậm chí sập khi đối mặt với lượng yêu cầu khổng lồ từ người dùng. +- **Đảm bảo tính toàn vẹn và nhất quán của dữ liệu**: Cơ sở dữ liệu thông qua một loạt cơ chế (như ràng buộc, trigger) để đảm bảo tính chính xác và nhất quán của dữ liệu. Điều này có nghĩa là dữ liệu trong cơ sở dữ liệu phải tuân thủ các quy tắc được thiết lập trước, ví dụ, tuổi của người dùng phải là số, số đơn hàng phải là duy nhất, từ đó ngăn chặn hiệu quả việc tạo ra dữ liệu bất hợp pháp hoặc không hợp lệ. +- **Đảm bảo bảo mật dữ liệu**: Cơ sở dữ liệu cung cấp các cơ chế bảo mật mạnh mẽ, bao gồm xác thực danh tính người dùng, kiểm soát truy cập và mã hóa dữ liệu, để bảo vệ dữ liệu khỏi truy cập, sửa đổi hoặc phá hủy trái phép. Để đối phó với các tình huống bất ngờ như lỗi phần cứng, sai sót con người hoặc tấn công độc hại, cơ sở dữ liệu còn cung cấp chức năng sao lưu và khôi phục dữ liệu. Thông qua sao lưu định kỳ, có thể khôi phục kịp thời khi dữ liệu bị mất hoặc hỏng, đảm bảo tính liên tục của hoạt động kinh doanh. + +## 1.3 Cơ sở dữ liệu quan hệ và cơ sở dữ liệu phi quan hệ + +Ở trên chúng ta đã hiểu giá trị cốt lõi, cách triển khai và lợi thế linh hoạt của cơ sở dữ liệu, và trong thực tế lựa chọn, điều đầu tiên phải đối mặt là hai danh mục cốt lõi của cơ sở dữ liệu: cơ sở dữ liệu quan hệ và cơ sở dữ liệu phi quan hệ (NOSQL), chúng ta có thể hiểu sự khác biệt của chúng một cách đơn giản qua hai đoạn văn ngắn: + +Cơ sở dữ liệu quan hệ giống như bảng Excel có cấu trúc nghiêm ngặt, tất cả dữ liệu phải được định nghĩa trước định dạng (nội dung Schema đã được định nghĩa, ví dụ phải có tên và tuổi, và tên phải là văn bản, tuổi phải là số), và thông qua trường liên kết (định danh dùng để kết nối các bảng khác nhau, như số CMND) kết nối các bảng khác nhau. Ưu điểm của nó là dữ liệu chính xác và đáng tin cậy, đặc biệt phù hợp với các tình huống không thể sai sót như chuyển khoản ngân hàng, quản lý tồn kho, nhưng nhược điểm là điều chỉnh cấu trúc khá phiền toái, hiệu suất sẽ bị hạn chế với lượng dữ liệu khổng lồ. + +Cơ sở dữ liệu phi quan hệ thì giống như thư mục linh hoạt, có thể lưu trữ các tài liệu, hình ảnh hoặc cặp khóa-giá trị (cấu trúc "từ - giải thích" tương tự từ điển) có định dạng khác nhau, không cần quy định trước cấu trúc của từng dữ liệu. Nó dễ dàng đối phó hơn với các nhu cầu thay đổi nhanh chóng và dữ liệu siêu quy mô (như lượng bài viết khổng lồ trên mạng xã hội), mở rộng (thêm máy chủ để tăng hiệu suất) cũng thuận tiện hơn, nhưng hy sinh một phần khả năng truy vấn liên kết (khả năng tổng hợp thông tin từ các bảng dữ liệu khác nhau) và đảm bảo nhất quán (đảm bảo dữ liệu luôn chính xác không mâu thuẫn), phù hợp với các ứng dụng internet có yêu cầu chịu lỗi cao. + +Vậy, trong ứng dụng thực tế nên chọn cơ sở dữ liệu nào? Từ góc độ phân loại tình huống, cơ sở dữ liệu quan hệ thường thấy trong các tình huống như giao dịch tài chính, quản lý tồn kho, xử lý đơn hàng, hệ thống kế toán cần tính nhất quán mạnh, xử lý giao dịch phức tạp và truy cập đọc ghi cân bằng thường xuyên; trong khi cơ sở dữ liệu phi quan hệ phù hợp hơn với các nhu cầu lưu trữ nội dung mạng xã hội, phân tích log thời gian thực, ghi dữ liệu khổng lồ IoT, hệ thống gợi ý đặc trưng đọc nhiều ghi nhiều có đồng thời cao, mô hình đọc ghi không cân bằng và cấu trúc linh hoạt. + +Nhưng đối với doanh nghiệp, trong giai đoạn đầu không cần dành nhiều thời gian suy nghĩ về việc nên sử dụng cơ sở dữ liệu nào. Cơ sở dữ liệu hiện nay đã là sản phẩm dịch vụ rất trưởng thành, cách trực tiếp nhất là tham vấn các nhà cung cấp dịch vụ đám mây khác nhau (chỉ các nhà cung cấp dịch vụ tài nguyên IT và dịch vụ công nghệ như máy chủ, lưu trữ, cơ sở dữ liệu, phần mềm, năng lực tính toán, v.v.). Chúng ta có thể đối thoại trực tiếp với bộ phận bán hàng chính thức của dịch vụ đám mây, dựa trên nhu cầu kinh doanh sản phẩm của mình để phù hợp với giải pháp cơ sở dữ liệu thích ứng; và con đường thuận tiện để xây dựng ứng dụng cấp doanh nghiệp là ưu tiên hợp tác với các nhà cung cấp chuyên nghiệp. (Cần lưu ý: giá dịch vụ cấp doanh nghiệp thường cao, nên khảo sát và so sánh nhiều bên trước, cũng có thể chọn mua máy chủ để tự triển khai chương trình cơ sở dữ liệu mã nguồn mở sebagai giải pháp thay thế.) + +Chúng ta cũng có thể tham khảo [khuyến nghị chọn cơ sở dữ liệu](https://help.aliyun.com/zh/govcloud/getting-started/select-database-services) của một nhà cung cấp đám mây, dựa trên tình huống có thể chọn các loại cơ sở dữ liệu khác nhau, bạn có thể so sánh thông số cơ sở dữ liệu của các nhà cung cấp đám mây khác nhau để chọn loại phù hợp nhất để sử dụng. + +| Loại cơ sở dữ liệu | Tên cơ sở dữ liệu | Giá | Tình huống sử dụng | +| ------------ | ---------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Cơ sở dữ liệu quan hệ | RDS MySQL版 | Thấp | Phiên bản cơ bản: học tập và trang web nhỏ Phiên bản cao khả dụng: tình huống cơ sở dữ liệu trung bình có áp lực kinh doanh nhất định Phiên bản cluster: kinh doanh không được gián đoạn, áp lực truy cập lớn | +| | RDS SQL server版 | Cao | Phiên bản cơ bản: thử nghiệm và trang web thương mại nhỏ Phiên bản cao khả dụng: trang web thương mại cấp doanh nghiệp Phiên bản cluster: kinh doanh doanh nghiệp không được gián đoạn, áp lực truy cập lớn | +| | RDS PostgreSQL版 | Thấp nhất | Phiên bản cơ bản: học tập và trang web nhỏ Phiên bản cao khả dùng: tình huống cơ sở dữ liệu trung bình có áp lực kinh doanh nhất định Phiên bản cluster: kinh doanh không được gián đoạn, tình huống áp lực truy cập lớn, hiệu suất cao hơn MySQL thông thường | +| | RDS PPAS版 | Cao | Loại phổ thông: tương thích kinh doanh Oracle, nhưng áp lực kinh doanh Udacity, ảo hóa có thể đáp ứng nhu cầu Loại độc quyền: đối với kinh doanh cần máy vật lý độc quyền, thường là kinh doanh Oracle loại đồng thời cao | +| | DRDS | Trung bình | Phiên bản nhập môn: 4 Core 8 G, giá cả phải chăng, phù hợp doanh nghiệp kinh doanh trực tuyến nhỏ và vừa Phiên bản doanh nghiệp: 16 Core 32 G, phản hồi SQL phức tạp tốt, phù hợp kinh doanh trực tuyến đồng thời siêu cao Phiên bản tối thượng: 32 Core 64 G, phản hồi thực thi SQL phức tạp tốt nhất, cung cấp lựa chọn thông số siêu lớn | +| Cơ sở dữ liệu NoSQL | Redis | Trung bình | Redis dự phòng nóng hai máy: thường dùng làm cơ sở dữ liệu bền vững để tăng tính khả dụng của kinh doanh Phiên bản cluster của Redis: thường dùng làm lớp bộ đệm, tăng tốc truy cập ứng dụng, giải quyết áp lực đọc mà cơ sở dữ liệu thông thường không thể chịu tải | +| | MongoDB版 | Trung bình | Thực thể nút đơn: phù hợp cho phát triển, thử nghiệm và các tình huống lưu trữ dữ liệu không phải cốt lõi doanh nghiệp Thực thể replica set: phù hợp cho các tình huống kinh doanh có nhu cầu hiệu suất đọc cao hơn cho cơ sở dữ liệu, như trang web đọc, hệ thống tra cứu đơn hàng đọc nhiều ghi ít hoặc nhu cầu kinh doanh đột biến từ sự kiện tạm thời Thực thể sharded cluster: dựa trên nhiều replica set (mỗi replica set sử dụng mô hình ba replica) tạo thành thực thể sharded cluster, cung cấp nhu cầu hiệu suất đọc cao hơn, cung cấp hiệu suất đọc tốc độ cao cho kinh doanh trực tuyến thời gian thực | + +Chỉ nói thì không dễ hiểu, chúng ta hãy xem xét một tình huống "bài viết blog" cụ thể, để xem cùng một dữ liệu được lưu trữ như thế nào trong cơ sở dữ liệu quan hệ (SQL) và các loại cơ sở dữ liệu phi quan hệ (NoSQL) khác nhau. + +Giả sử chúng ta có một nền tảng blog, cần lưu trữ các thông tin sau: + +- Người dùng (Users): ID người dùng, tên người dùng, email +- Bài viết (Posts): ID bài viết, tiêu đề, nội dung, ID tác giả +- Bình luận (Comments): ID bình luận, nội dung bình luận, ID người bình luận, ID bài viết thuộc về +- Thẻ (Tags): ID thẻ, tên thẻ +- Quan hệ bài viết và thẻ: nhiều thẻ liên kết với một bài viết, nhiều bài viết tương ứng với một thẻ + +### Ví dụ về cơ sở dữ liệu quan hệ (SQL) + +Trong cơ sở dữ liệu SQL, chúng ta sẽ lưu trữ các loại dữ liệu khác nhau trong các bảng khác nhau, và liên kết chúng thông qua "khóa ngoại". Cấu trúc này rõ ràng, chuẩn hóa, giảm thiểu dư thừa dữ liệu. + +Lấy ví dụ "quản lý bài viết trên nền tảng nội dung", chúng ta sẽ không trộn lẫn "người dùng, bài viết, bình luận, thẻ", mà chia thành 5 bảng có chức năng đơn nhất, mỗi bảng đều có "ranh giới trách nhiệm" rõ ràng và định nghĩa cấu trúc nghiêm ngặt (Schema): + +- Bảng `users` (lưu trữ thông tin người dùng) + +| user_id (khóa chính) | username | email | +| -------------- | -------- | ----------------- | +| 101 | Alice | alice@example.com | +| 102 | Bob | bob@example.com | + +- Bảng `posts` (lưu trữ thông tin bài viết) + +| post_id (khóa chính) | title | content | author_id (khóa ngoại) | +| -------------- | --------- | ------------------------------ | ---------------- | +| 1 | Làm quen SQL | Đây là một bài viết về cơ sở dữ liệu SQL... | 101 | +| 2 | Nhập môn NoSQL | NoSQL cung cấp mô hình dữ liệu linh hoạt... | 102 | + +- Bảng `comments` (lưu trữ thông tin bình luận) + +| comment_id (khóa chính) | body | commenter_id (khóa ngoại) | post_id (khóa ngoại) | +| ----------------- | ---------------- | ------------------- | -------------- | +| 1001 | Viết rất hay! | 102 | 1 | +| 1002 | Đã học được. | 101 | 2 | +| 1003 | Có thêm ví dụ không? | 101 | 1 | + +- Bảng `tags` (lưu trữ thẻ) + +| tag_id (khóa chính) | tag_name | +| ------------- | -------- | +| 51 | Cơ sở dữ liệu | +| 52 | Công nghệ | +| 53 | Nhập môn | + +- Bảng `post_tags` (lưu trữ quan hệ nhiều-nhiều giữa bài viết và thẻ, thể hiện đặc điểm liên kết bảng) + +| post_id (khóa ngoại) | tag_id (khóa ngoại) | +| -------------- | ------------- | +| 1 | 51 | +| 1 | 52 | +| 2 | 51 | +| 2 | 52 | +| 2 | 53 | + +Nếu cần truy vấn "thông tin đầy đủ của bài viết 《Làm quen SQL》 (post_id=1) do Alice đăng (bao gồm nội dung bài viết, tác giả, bình luận, thẻ)", cần thực hiện truy vấn kết nối nhiều bảng (JOIN), liên kết 5 bảng thông qua khóa ngoại và tổng hợp dữ liệu, câu lệnh SQL như sau: + +```sql +SELECT + p.title, + p.content, + u.username AS author, + c.body AS comment, + t.tag_name AS tag +FROM + posts p +JOIN + users u ON p.author_id = u.user_id +LEFT JOIN + comments c ON p.post_id = c.post_id +LEFT JOIN + post_tags pt ON p.post_id = pt.post_id +LEFT JOIN + tags t ON pt.tag_id = t.tag_id +WHERE + p.post_id = 1; +``` + +Truy vấn này sẽ xuyên qua 5 bảng, tổng hợp tất cả dữ liệu liên quan và trả về. Đây là lợi thế cốt lõi của cơ sở dữ liệu quan hệ: thông qua chuẩn hóa và phép kết nối, có thể linh hoạt thực hiện nhiều loại truy vấn phức tạp, đồng thời đảm bảo tính nhất quán của dữ liệu và dư thừa tối thiểu. + +### Ví dụ về cơ sở dữ liệu phi quan hệ (NoSQL) + +Ý tưởng thiết kế của cơ sở dữ liệu NoSQL (như MongoDB, Redis) ngược lại với SQL, nó không nhấn mạnh việc chia nhỏ và chuẩn hóa dữ liệu, thường sẽ đóng gói và tổng hợp tất cả dữ liệu liên quan về mặt kinh doanh lại với nhau, để giảm thiểu phép kết nối khi truy vấn, từ đó tăng hiệu suất đọc. + +Trong cơ sở dữ liệu NoSQL, cơ sở dữ liệu tài liệu (Document Database) là một trong những loại phổ biến nhất, MongoDB là đại diện tiêu biểu. Nó sử dụng "tài liệu" làm đơn vị lưu trữ cơ bản, "tài liệu" ở đây không phải là "bài viết" như chúng ta hiểu thông thường, mà là một cấu trúc dữ liệu tương tự JSON (trong MongoDB thực tế sử dụng định dạng BSON, hỗ trợ nhiều loại dữ liệu hơn): không cần định nghĩa trước Schema thống nhất (cấu trúc dữ liệu), các trường của mỗi tài liệu có thể tăng giảm linh hoạt, loại trường cũng có thể điều chỉnh tự do, hoàn toàn phù hợp với các tình huống định dạng dữ liệu thay đổi đa dạng. + +Trong cơ sở dữ liệu tài liệu, thường lưu trữ một bài viết và tất cả thông tin liên quan (như bình luận, thẻ) trong một tài liệu (định dạng tài liệu tương tự JSON, có thể định nghĩa trường linh hoạt, không cần Schema trước), logic cốt lõi là "lưu trữ 'thông tin hoàn chỉnh trong một tình huống kinh doanh' trong một tài liệu", tránh việc ghép nối nhiều nguồn dữ liệu khi truy vấn. + +Ví dụ về một tài liệu trong bộ sưu tập `posts`: + +```json +{ + "_id": 1, + "title": "Làm quen SQL", + "content": "Đây là một bài viết về cơ sở dữ liệu SQL...", + "author": { + "user_id": 101, + "username": "Alice", + "email": "alice@example.com" + }, + "tags": [ + "Cơ sở dữ liệu", + "Công nghệ" + ], + "comments": [ + { + "comment_id": 1001, + "body": "Viết rất hay!", + "commenter": { + "user_id": 102, + "username": "Bob" + } + }, + { + "comment_id": 1003, + "body": "Có thêm ví dụ không?", + "commenter": { + "user_id": 101, + "username": "Alice" + } + } + ] +} +``` + +Ưu điểm của thiết kế này rất trực quan: khi bạn cần lấy "thông tin đầy đủ của bài viết đầu tiên (bao gồm tác giả, bình luận, thẻ)", chỉ cần truy vấn tài liệu này thông qua `_id:1`, cơ sở dữ liệu có thể trả về tất cả dữ liệu chỉ với một lần đọc, không cần thực hiện 3-4 phép kết nối bảng như SQL, hiệu suất đọc được cải thiện đáng kể. + +Nhưng nó cũng存在 trade-off (sự đánh đổi) rõ ràng: do dữ liệu được "tổng hợp lưu trữ", sẽ không thể tránh khỏi việc tạo ra dư thừa dữ liệu — ví dụ `username` của tác giả "Alice" được nhúng vào mỗi tài liệu bài viết cô ấy viết, nếu một ngày nào đó "Alice" đổi tên người dùng thành "Alice_New", về lý thuyết cần duyệt qua tất cả tài liệu bài viết chứa thông tin của cô ấy, cập nhật trường `author.username` từng cái một, không chỉ phiền toạp mà còn có thể do vấn đề mạng hoặc máy chủ dẫn đến việc cập nhật một số tài liệu thất bại, xuất hiện tình trạng "cùng một người dùng có tên khác nhau trong các bài viết khác nhau". + +Tuy nhiên trong kinh doanh thực tế, loại dư thừa này thường là "có thể chấp nhận được": đối với các tình huống "**đọc nhiều ghi ít**" như blog, tin tức, chi tiết sản phẩm thương mại điện tử (số lần người dùng xem nội dung nhiều hơn nhiều so với số lần tác giả sửa tên người dùng), việc sử dụng một lượng dư thừa nhỏ để đổi lấy "hiệu suất đọc cực đoan" là lựa chọn tốt hơn; còn nếu là tình huống "ghi nhiều đọc ít" (như sửa đổi thông tin người dùng thường xuyên), thì cần kết hợp nhu cầu kinh doanh để cân nhắc có nên sử dụng cơ sở dữ liệu tài liệu hay không. + +Trên đây là giới thiệu đơn giản về các cơ sở dữ liệu khác nhau, nếu bạn quan tâm đến nhiều loại cơ sở dữ liệu cụ thể hơn, bạn có thể tham khảo các tài liệu sau để thử các loại cơ sở dữ liệu khác nhau. + +Examples of SQL databases: +[Db2](https://www.ibm.com/products/db2-database)、[MySQL](https://cloud.ibm.com/catalog#highlights)、[PostgreSQL](https://www.ibm.com/think/topics/postgresql)、[YugabyteDB](https://www.yugabyte.com/)、[CockroachDB](https://www.cockroachlabs.com/)、[Oracle Database](https://www.ibm.com/products/postgres-enterprise)、[Azure SQL Database](https://www.ibm.com/consulting/microsoft) + +Examples of NoSQL databases: +[Redis](https://www.ibm.com/think/topics/redis)、[CouchDB](https://www.ibm.com/think/topics/couchdb)、[MongoDB](https://www.ibm.com/think/topics/mongodb)、[Cassandra](https://cloud.ibm.com/catalog#highlights)、[Elasticsearch](https://www.ibm.com/think/topics/elasticsearch)、[BigTable](https://www.techtarget.com/searchdatamanagement/news/252512583/Google-scales-up-Cloud-Bigtable-NoSQL-database)、[Neo4j](https://neo4j.com/users/ibm/)、[HBase](https://www.ibm.com/think/topics/hbase) + +# 2. Supabase + +Ở phần trước chúng ta đã giới thiệu một số loại cơ sở dữ liệu phổ biến và các tình huống sử dụng phù hợp của từng loại. Tuy nhiên trong dự án thực tế, cơ sở dữ liệu thường chỉ là một mô-đun cơ bản trong hệ thống backend: ngoài việc lưu trữ và truy vấn dữ liệu, bạn còn cần giải quyết một loạt vấn đề như **đăng ký đăng nhập người dùng, xác thực phân quyền, tải lên và lưu trữ tệp, API** giao diện bên ngoài **, thậm chí tác vụ định kỳ, thông báo thời gian thực**. Chỉ việc chọn cơ sở dữ liệu tốt không thể làm cho ứng dụng của bạn "ngay lập tức có thể chạy trực tuyến", ở giữa còn có một loạt công việc backend phức tạp. + +Vì vậy, chúng ta cần xem xét một bối cảnh lớn hơn: **dịch vụ backend**. Một ứng dụng hoàn chỉnh, thường bao gồm "frontend + backend": frontend chịu trách nhiệm hiển thị trang và tương tác người dùng, backend chịu trách nhiệm lưu trữ dữ liệu, đăng nhập người dùng, xử lý logic kinh doanh, v.v. Trước đây, các nhà phát triển thường cần tự xây dựng máy chủ, cấu hình cơ sở dữ liệu, thiết kế và triển khai API, còn phải xử lý thủ công quản lý phân quyền, chính sách bảo mật, khả năng mở rộng và vận hành giám sát, toàn bộ quá trình vừa lặp lại vừa tốn thời gian. Để giải quyết các công việc lặp lại này, ngành đã xuất hiện **BaaS (Backend as a Service, Backend dưới dạng dịch vụ)**: đóng gói các chức năng backend phổ biến như cơ sở dữ liệu, xác thực người dùng, lưu trữ tệp, khả năng thời gian thực thành một nền tảng đám mây, nhà phát triển có thể gọi trực tiếp các khả năng này thông qua SDK / API mà không cần xây dựng và vận hành cơ sở hạ tầng từ con số không. + +Trong bối cảnh này, [Supabase](https://supabase.com/) có thể được xem là đại diện BaaS thế hệ mới: nó sử dụng PostgreSQL làm cơ sở dữ liệu cốt lõi, tích hợp trên đó một bộ khả năng backend hoàn chỉnh bao gồm Auth, Storage, Realtime, Edge Functions, Vector, v.v., cung cấp cho nhà phát triển một "nền tảng backend一站式 lấy Postgres làm trung tâm". Tiếp theo, chúng ta sẽ đi từ góc độ này, từ "chỉ chọn cơ sở dữ liệu" nâng cấp lên "chọn nền tảng phát triển backend hoàn chỉnh", xem cụ thể Supabase có thể giúp chúng ta tiết kiệm những công việc nào, và làm thế nào để rút ngắn đáng kể khoảng cách từ nguyên mẫu đến sản phẩm可用. + +## 2.1 Hướng dẫn từng bước + +Sau khi nắm bắt rõ định vị tổng thể của Supabase, tiếp theo chúng ta sẽ đi theo đường dẫn thao tác trên bảng điều khiển Supabase, phân tích từng mục về các khả năng cốt lõi cụ thể mà nó cung cấp và trách nhiệm cốt lõi tương ứng của từng khả năng. Chúng ta sẽ giới thiệu chi tiết từng tùy chọn mà Supabase liên quan, giúp bạn nhanh chóng làm quen với các thao tác cơ bản của Supabase. + +![](/zh-cn/stage-2/backend/database-supabase/images/image2.png) + +Sau khi truy cập trang web chính thức của Supabase và đăng nhập, tại trang chủ bảng điều khiển nhấn New project để vào quá trình tạo; + +Nhập nội dung cấu hình chính cần thiết là Project Name, mật khẩu cơ sở dữ liệu, khu vực chỉ cần chọn khu vực gần nhất với người dùng mục tiêu của chương trình. + +![](/zh-cn/stage-2/backend/database-supabase/images/image3.png) + +Sau khi tạo thành công, thanh bên trái của bảng điều khiển sẽ hiển thị tất cả các mô-đun chức năng cốt lõi (Table Editor, SQL Editor, Database, Authentication, v.v.), các thao tác tiếp theo sẽ xoay quanh các mô-đun này. + +![](/zh-cn/stage-2/backend/database-supabase/images/image4.png) + +### Trình soạn thảo bảng + +Table Editor có thể được coi là trình soạn thảo bảng dữ liệu trực quan của Supabase, nó cho phép bạn xem và sửa đổi dữ liệu trong cơ sở dữ liệu trực tiếp như thao tác với Excel mà không cần viết câu lệnh SQL, chỉ cần tương tác bằng chuột là có thể sửa đổi nội dung dữ liệu. + +![](/zh-cn/stage-2/backend/database-supabase/images/image5.png) + +Điều đáng chú ý là Schema, Schema có thể được hiểu là "container tài nguyên" trong cơ sở dữ liệu, dùng để quản lý phân nhóm các tài nguyên như bảng, view, hàm, chỉ mục, chủ yếu có hai tác dụng: một là tránh xung đột đặt tên (các bảng cùng tên có thể tồn tại dưới các Schema khác nhau), hai là thực hiện cách ly phân quyền (ví dụ chỉ cho phép người dùng cụ thể truy cập bảng dưới một Schema nhất định); + +Nhấn vào dropdown Schema ở đầu trình soạn thảo để chuyển đổi giữa các container khác nhau, trong phát triển hàng ngày thường chỉ cần quan tâm hai loại: + +- `public`: container tài nguyên công khai mặc định, tất cả các bảng kinh doanh do nhà phát triển tạo mới (như "bảng bài viết" "bảng bình luận") đều được lưu trữ ở đây; +- `auth`: container chuyên dụng cho xác thực người dùng, bảng `users` trong đó tự động lưu trữ thông tin của tất cả người dùng đã đăng ký (như ID người dùng, email, thời gian đăng nhập), không nên sửa đổi thủ công các bảng mặc định dưới Schema này để tránh ảnh hưởng đến chức năng xác thực; + +![](/zh-cn/stage-2/backend/database-supabase/images/image6.png)![](/zh-cn/stage-2/backend/database-supabase/images/image7.png) + +### Trình soạn thảo SQL + +SQL Editor là trình thực thi câu lệnh SQL của Supabase, cho phép bạn thao tác trực tiếp với cơ sở dữ liệu bằng mã. Bạn có thể để mô hình lớn tạo trực tiếp câu lệnh SQL, nhập ở bên phải sau đó nhấn RUN để tạo hoặc sửa đổi bảng bằng câu lệnh, cũng có thể xem trực tiếp dữ liệu bảng đã lọc trong Results. + +![](/zh-cn/stage-2/backend/database-supabase/images/image8.png) + +Bạn có thể tìm thấy bảng dữ liệu mới tạo trong public schema của Table Editor sau khi chạy RUN; và câu lệnh đã chạy sẽ được lưu trong mục PRIVATE bên trái, thậm chí có thể nhấn vào biểu tượng trái tim ở dưới để thêm vào yêu thích cho câu truy vấn hoặc câu lệnh tạo này. + +### Trung tâm quản lý cơ sở dữ liệu + +Database là trung tâm quản lý cơ sở dữ liệu của Supabase, hỗ trợ xem và quản lý tất cả các bảng dữ liệu một cách trực quan, và hiểu mối quan hệ liên kết giữa các bảng khác nhau thông qua các đường kết nối (tức là ràng buộc khóa ngoại, thể hiện mối quan hệ tham chiếu giữa dữ liệu). + +![](/zh-cn/stage-2/backend/database-supabase/images/image9.png) + +Nếu bạn muốn tạo bảng mới thủ công, bạn có thể tạo bảng trực tiếp trong tables, chúng tôi sẽ hướng dẫn chi tiết trong hướng dẫn sau. + +![](/zh-cn/stage-2/backend/database-supabase/images/image10.png) + +### Xác thực danh tính + +Authentication chịu trách nhiệm quản lý đăng ký, đăng nhập và phân quyền của người dùng. Dữ liệu hệ thống quản lý người dùng mặc định đều được lưu trữ tại đây, nó cung cấp các chức năng đăng ký, đăng nhập, đặt lại mật khẩu, xác thực email sẵn sàng sử dụng, và hỗ trợ đăng nhập OAuth bên thứ ba (như WeChat, GitHub, Google, v.v.). Tất cả dữ liệu người dùng sẽ tự động đồng bộ vào bảng `auth.users` của cơ sở dữ liệu. + +![](/zh-cn/stage-2/backend/database-supabase/images/image11.png) + +Bạn có thể tìm thấy các điểm đăng nhập thông tin người dùng được Supabase hỗ trợ khác nhau trong tùy chọn Provider, mặc định sử dụng Email; nếu bạn muốn sử dụng tài khoản Github hoặc Google để đăng nhập, cần thêm cấu hình thuộc tính, chúng tôi sẽ hướng dẫn chi tiết trong bài học dưới đây. + +![](/zh-cn/stage-2/backend/database-supabase/images/image12.png) + +Trong Sign In / Providers còn bao gồm kiểm soát hành vi đăng ký email, nếu bạn không muốn mỗi lần đăng ký bằng email đều phải để người dùng chấp nhận lời mời rồi mới trở thành người dùng, bạn có thể hủy yêu cầu bắt buộc Confirm email. + +![](/zh-cn/stage-2/backend/database-supabase/images/image13.png) + +Nếu bạn muốn chuyển sang nhà cung cấp dịch vụ hệ thống auth khác không phải Supabase, bạn có thể nhấn vào Third Party Auth, ví dụ ở đây sử dụng Clerk làm nhà cung cấp dịch vụ bên thứ ba. + +![](/zh-cn/stage-2/backend/database-supabase/images/image14.png) + +Nếu bạn lo ngại về lượng truy cập quá lớn của người dùng đã đăng ký trong thời gian ngắn, bạn có thể bật chính sách giới hạn lưu lượng tương ứng trong Rate Limits: + +![](/zh-cn/stage-2/backend/database-supabase/images/image15.png) + +### Lưu trữ + +Storage là hệ thống lưu trữ của Supabase, tương thích với khái niệm s3 của amazon cloud, có thể được sử dụng để lưu trữ bất kỳ loại tệp nào (như hình ảnh, video, tài liệu, âm thanh, v.v.), và cung cấp quản lý phân quyền truy cập (công khai hoặc riêng tư) và lấy liên kết tải xuống (liên kết vĩnh viễn hoặc liên kết tạm thời), bạn có thể dễ dàng quản lý tải lên và tải xuống nội dung tệp liên quan đến người dùng trong ứng dụng, và tích hợp liền mạch với hệ thống xác thực của Supabase, thực hiện kiểm soát truy cập tinh tế. + +![](/zh-cn/stage-2/backend/database-supabase/images/image16.png) + +Chúng tôi sẽ giải thích cách sử dụng cụ thể của storage trong dự án nâng cao của bài học này. + +![](/zh-cn/stage-2/backend/database-supabase/images/image17.png) + +Nếu bạn muốn sử dụng giao thức liên quan đến S3 để thao tác, có thể trực tiếp sử dụng cấu hình tương ứng: + +![](/zh-cn/stage-2/backend/database-supabase/images/image18.png) + +> Amazon Cloud (dịch vụ đám mây Amazon, gọi tắt là AWS) là nền tảng điện toán đám mây do Amazon cung cấp (giống như một phòng máy mạng lớn, bạn có thể thuê tài nguyên tính toán và lưu trữ theo nhu cầu). S3 (Simple Storage Service) là dịch vụ chuyên dùng để lưu trữ tệp trong AWS (tương tự như một ổ đĩa mạng không giới hạn dung lượng, có thể lưu hình ảnh, video, sao lưu và nhiều loại tệp khác), đây là dịch vụ lưu trữ đối tượng phổ biến nhất hiện nay và đã trở thành tiêu chuẩn thực tế của ngành. +> +> **Tại sao phải làm thành S3 tương thích API?**: S3 đã tồn tại gần 20 năm, thị trường có lượng lớn công cụ, SDK và tài liệu sẵn có, tương thích với S3 có nghĩa là bạn có thể sử dụng trực tiếp các tài nguyên này mà không cần tạo từ đầu các công cụ liên quan, có thể nhanh chóng đáp ứng nhu cầu kinh doanh đưa lên mạng. + +### Edge Functions + +Nếu bạn không muốn triển khai backend nhưng muốn sử dụng cơ sở dữ liệu và thao tác hàm, bạn có thể sử dụng Edge Functions để xây dựng khả năng backend cốt lõi mà không cần tự xây dựng máy chủ, đây là hàm phía máy chủ phân tán toàn cầu do Supabase cung cấp. Nói một cách đơn giản, nó cho phép bạn viết và triển khai mã backend trên đám mây mà không cần mua và quản lý máy chủ backend riêng. Các hàm này được triển khai trên các nút cạnh của mạng lưới toàn cầu, sẽ tự động chạy ở vị trí gần người dùng của bạn nhất, từ đó giảm đáng kể độ trễ mạng, cung cấp tốc độ phản hồi cực nhanh. Bạn có thể tạo, chỉnh sửa và triển khai trực tiếp trong bảng điều khiển Supabase, toàn bộ quá trình phát triển rất thuận tiện. + +![](/zh-cn/stage-2/backend/database-supabase/images/image19.png) + +Một công dụng cốt lõi của Edge Functions là đóng vai trò là lớp trung gian an toàn, bảo vệ thông tin nhạy cảm và khóa xác thực của bạn. Việc gọi trực tiếp dịch vụ bên thứ ba (như OpenAI, Stripe) trong mã frontend sẽ làm lộ API Key của bạn, mang lại rủi ro bảo mật rất lớn. Thông qua Edge Functions, ứng dụng frontend của bạn chỉ giao tiếp với hàm supabase của bạn, tất cả bí mật chỉ được lưu giữ trong supabase. + +![](/zh-cn/stage-2/backend/database-supabase/images/image20.png) + +Các hàm của Edge Functions sử dụng khóa được tiết lộ trong secrets làm biến môi trường, tải thông qua `Deno.env.get`, từ đó thực hiện gọi dịch vụ bên thứ ba. Bằng cách này, khóa nhạy cảm sẽ không bao giờ bị lộ trên phía client (trình duyệt của bạn), triệt để loại bỏ nguy cơ bị đánh cắp. + +![](/zh-cn/stage-2/backend/database-supabase/images/image21.png) + +Khi yêu cầu Supabase Edge Function, cần mang theo khóa Supabase tương ứng trong header yêu cầu, dưới đây là một ví dụ tối giản: + +```javascript +// Cấu hình cốt lõi (thay bằng thông tin thực tế của bạn) +const projectId = "ID dự án Supabase của bạn"; +const functionName = "Tên Edge Function mục tiêu"; +const supabaseKey = "Supabase anon_key"; + +// Gọi hàm +async function callEdgeFunction() { + const url = `https://${projectId}.supabase.co/functions/v1/${functionName}`; + + try { + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${supabaseKey}` // Quan trọng: mang theo khóa để hoàn tất xác thực + }, + body: JSON.stringify({ order_id: "123", action: "refund" }) // Dữ liệu yêu cầu tùy chỉnh + }); + + const result = await response.json(); + console.log("Gọi thành công:", result); + } catch (error) { + console.error("Gọi thất bại:", error.message); + } +} + +// Thực hiện gọi +callEdgeFunction(); +``` + +Ngoài ra, Edge Functions tích hợp liền mạch với hệ thống xác thực người dùng của Supabase. Khi một người dùng đã đăng nhập gọi một hàm, thông tin danh tính của họ sẽ được truyền cho hàm. Điều này cho phép bạn dễ dàng nhận diện người dùng hiện tại trong hàm và thực hiện kiểm soát phân quyền dựa trên danh tính của họ. Quan trọng hơn, khi hàm thao tác với cơ sở dữ liệu, nó sẽ tự động tuân thủ chính sách bảo mật cấp hàng (Row Level Security) mà bạn đã thiết lập, đảm bảo người dùng chỉ có thể truy cập và sửa đổi dữ liệu họ có quyền thao tác, giúp việc xây dựng ứng dụng đa người dùng an toàn trở nên đơn giản. + +Các tình huống ứng dụng của Edge Functions rất đa dạng, có thể xử lý nhiều loại tác vụ backend. Chúng rất phù hợp để lắng nghe sự kiện Webhook từ dịch vụ bên thứ ba (ví dụ thanh toán thành công, commit mã, v.v.) và tự động thực hiện logic xử lý dữ liệu tương ứng. Bạn cũng có thể sử dụng nó để gửi thông báo email, tạo báo cáo PDF, tạo giao diện API tùy chỉnh để đóng gói logic kinh doanh phức tạp, hoặc thực hiện bất kỳ tác vụ tính toán nào bạn muốn hoàn thành ở phía máy chủ, mở rộng đáng kể khả năng ứng dụng của bạn. + +Cụ thể với một ví dụ phổ biến: công cụ xác thực danh tính Clerk. Clerk chỉ được sử dụng để xử lý các thao tác liên quan đến xác thực như đăng nhập, đăng ký, cập nhật thông tin người dùng, không trực tiếp quản lý cơ sở dữ liệu kinh doanh của bạn. Nếu bạn muốn đồng bộ các động thái xác thực này vào cơ sở dữ liệu kinh doanh, bạn cần thực hiện thông qua kích hoạt sự kiện Webhook yêu cầu Edge Functions. Edge Functions có thể lắng nghe tín hiệu Webhook do Clerk gửi, tự động thực hiện logic đồng bộ dữ liệu, làm cho thông tin người dùng trong cơ sở dữ liệu Supabase đồng bộ实时 với trạng thái đăng nhập Clerk, toàn bộ quá trình không cần bạn triển khai backend độc lập. + +### Công cụ đồng bộ dữ liệu thời gian thực + +Realtime là công cụ đồng bộ dữ liệu thời gian thực của Supabase, nó cho phép ứng dụng của bạn nhận ngay thông báo thay đổi cơ sở dữ liệu mà không cần liên tục thăm dò API. Khi dữ liệu trong cơ sở dữ liệu thực hiện thao tác `INSERT`, `UPDATE` hoặc `DELETE`, Realtime sẽ đẩy các thay đổi này theo thời gian thực đến tất cả các client đã kết nối thông qua WebSocket. Điều này rất quan trọng đối với việc xây dựng các ứng dụng cần tương tác thời gian thực. + +Realtime chủ yếu bao gồm ba chức năng cốt lõi, bao phủ phần lớn các tình huống thời gian thực: + +1. **Postgres Changes:** Lắng nghe trực tiếp các thay đổi của bảng cơ sở dữ liệu. Bạn có thể đăng ký chính xác các bảng cụ thể, sự kiện cụ thể (thêm, xóa, sửa), thậm chí có thể nhận thông báo dựa trên điều kiện lọc, và tích hợp hoàn hảo với chính sách bảo mật cấp hàng (Row Level Security), đảm bảo người dùng chỉ nhận được các thay đổi dữ liệu họ có quyền xem. +2. **Broadcast:** Cho phép các client gửi tin nhắn tạm thời độ trễ thấp cho nhau thông qua kênh (Channel). Rất phù hợp để triển khai các chức năng như phòng chat, theo dõi con trỏ thời gian thực, đồng bộ trạng thái game trực tuyến, v.v. +3. **Presence:** Dùng để theo dõi và đồng bộ trạng thái người dùng trực tuyến. Bạn có thể sử dụng nó để dễ dàng triển hiện các chức năng như "ai đang trực tuyến", "hiện có X người đang xem", rất phù hợp với các ứng dụng cộng tác. + +Chúng tôi sẽ giới thiệu chi tiết nội dung của phần này trong học tập dự án sau này. + +### Cài đặt dự án + +Project Settings là phần cấu hình cấp cao của dự án Supabase, bạn có thể thực hiện điều độ sâu tài nguyên tính toán tại đây, cũng như cấu hình tinh chỉnh các tham số nền tảng của các loại chức năng. + +![](/zh-cn/stage-2/backend/database-supabase/images/image22.png) + +Trong giai đoạn nhập môn, chúng ta chỉ cần tập trung vào hai khu vực cốt lõi sau, một là Data API, tại đây chúng ta có thể lấy "Supabase URL" quan trọng, nó là endpoint RESTful có dạng `https://xxx.supabase.co`, là "địa chỉ入口" của tất cả các thao tác truy vấn, thêm mới, sửa đổi, xóa dữ liệu. Frontend hoặc phía máy chủ cần khởi tạo client Supabase thông qua URL này để thiết lập kết nối với cơ sở dữ liệu. + +![](/zh-cn/stage-2/backend/database-supabase/images/image23.png) + +Một trọng điểm khác là API Keys, chọn tab "Legacy anon, service_role API keys", trong đó khóa anon public là chứng chỉ danh tính quan trọng trong tình huống frontend, quyền của nó bị RLS hạn chế nghiêm ngặt, chỉ có thể truy cập dữ liệu người dùng được ủy quyền. Còn khóa service_role thuộc về "khóa quyền cao phía máy chủ", có khả năng bỏ qua bảo mật cấp hàng, có thể thực hiện các thao tác dữ liệu hàng loạt, cấu hình cấp hệ thống và các thao tác nhạy cảm khác. Tuyệt đối cấm chia sẻ công khai, nếu bị lộ cần ngay lập tức tạo khóa mới và cập nhật cấu hình phía máy chủ. + +![](/zh-cn/stage-2/backend/database-supabase/images/image24.png) + +Các mục cấu hình còn lại không cần nghiên cứu sâu ở giai đoạn hiện tại, khi có nhu cầu sử dụng nâng cao sau này thì khám phá từng cái một. + +## 2.1 Tạo bảng dữ liệu SQL đầu tiên của bạn + +Trên đây là giới thiệu về giao diện Supabase, tiếp theo chúng ta sẽ đi sâu vào phần thao tác cơ sở dữ liệu cốt lõi của Supabase. + +Để tạo bảng dữ liệu trong Supabase, chủ yếu có hai cách phổ biến sau, bạn có thể chọn theo nhu cầu: + +1. (Khuyến nghị) Sử dụng mô hình ngôn ngữ lớn để tạo câu lệnh SQL phù hợp với Supabase, dán trực tiếp và thực thi trong **SQL Editor** (trình thực thi câu lệnh SQL đã giới thiệu ở trên), hiệu quả và nhanh chóng, chúng tôi sẽ giải thích chi tiết quá trình thao tác này trong phần tiếp theo. +2. Tạo thông qua thao tác trực quan: tìm mô-đun Database trong thanh bên trái, nhấn vào sau đó chọn Tables trong thanh bên, nhấn nút New table ở bên phải, có thể tạo bảng dữ liệu thông qua giao diện đồ họa. + +![](/zh-cn/stage-2/backend/database-supabase/images/image25.png) + +Đáng chú ý, tên bảng dữ liệu tương ứng và kiểu dữ liệu lưu trữ có thể được chỉ định trong Columns ở dưới. + +![](/zh-cn/stage-2/backend/database-supabase/images/image26.png) + +Đối với cơ sở dữ liệu quan hệ, một đặc điểm rất quan trọng là mối quan hệ liên kết giữa các bảng, bạn có thể tìm thấy `Foreign keys` ở dưới, nhấn để tạo mối quan hệ liên kết tương ứng: + +![](/zh-cn/stage-2/backend/database-supabase/images/image27.png) + +Trong đó `Foreign keys` thể hiện mối quan hệ liên kết giữa các bảng: một hoặc một nhóm trường, giá trị của nó trong bảng hiện tại (bảng con) sẽ tham chiếu đến giá trị khóa chính của bảng khác (bảng cha). + +Ví dụ, khi tạo `bảng học sinh`, chúng ta có thể định nghĩa khóa ngoại như sau: (cột `Mã lớp thuộc về` là một khóa ngoại. Khóa ngoại này tham chiếu đến cột `Mã lớp` trong `bảng lớp`.) + +```sql +CREATE TABLE Bảng_học_sinh ( + Mã_học_sinh INT PRIMARY KEY, + Tên_học_sinh VARCHAR(50), + Mã_lóp_thuộc_về INT, + FOREIGN KEY (Mã_lóp_thuộc_về) REFERENCES Bảng_lớp(Mã_lớp) +); +``` + +Cụ thể hơn, chúng ta có thể quan sát trực quan cấu trúc bảng tương ứng: + +Bảng lớp: +Bảng này ghi lại thông tin của tất cả các lớp, mỗi lớp đều có một mã lớp duy nhất. Mã lớp chính là khóa chính (Primary Key) của bảng này, là "chứng minh thư" duy nhất của mỗi lớp. + +| Mã lớp | Tên lớp | +| -------- | ---------- | +| 101 | Lớp 1A | +| 102 | Lớp 1B | + +Bảng học sinh: +Bảng này ghi lại thông tin của tất cả học sinh. Mỗi học sinh đều thuộc về một lớp cụ thể, đúng không? Vậy làm sao chúng ta biết học sinh nào ở lớp nào? + +Chúng ta có thể thêm một cột trong bảng học sinh, gọi là `Mã lớp thuộc về`. + +| Mã học sinh | Tên học sinh | Mã lớp thuộc về | +| -------- | -------- | ------------ | +| 2024001 | Trương Tam | 101 | +| 2024002 | Lý Tứ | 102 | +| 2024003 | Vương Ngũ | 101 | + +Trong ví dụ này, cột `Mã lớp thuộc về` trong bảng học sinh chính là khóa ngoại (Foreign Key). + +Trong Supabase, sau khi nhấn thêm Foreign Key, bạn có thể trực tiếp chọn cột tương ứng của bảng liên kết + +![](/zh-cn/stage-2/backend/database-supabase/images/image28.png) + +## 2.3 Giới thiệu SQL Editor và các thao tác cơ sở dữ liệu cơ bản + +Tiếp theo chúng ta sẽ thực hiện từng bước một loạt script SQL, làm quen với các thao tác thêm, xóa, truy vấn, sửa đổi phổ biến trong SQL. Bạn có thể sao chép mã của mỗi bước vào SQL Editor, thực thi và quan sát kết quả. + +Bạn có thể lấy tất cả các tệp SQL thử nghiệm tại thư mục sau: + +https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos/tree/main/apps/sql-examples + +### **2.3.1 **`CREATE`** - Tạo cấu trúc bảng** + +Câu lệnh `CREATE TABLE` được sử dụng để định nghĩa schema (Schema) cho bảng mới, bao gồm các cột (Columns) của nó, các kiểu dữ liệu tương ứng (Data Types) và bất kỳ ràng buộc (Constraints) nào, hiểu đơn giản là tạo một bảng dữ liệu. + +```sql +-- Step 1: Create the 'orders' table +-- This file is fully independent and creates a sample table for later steps. +CREATE TABLE IF NOT EXISTS orders ( + id serial PRIMARY KEY, + user_id int NOT NULL, -- User ID + status text NOT NULL, -- Order status (e.g. paid, pending) + amount numeric(10, 2) NOT NULL, -- Order total amount + details jsonb, -- Item and extra details as JSON + placed_at timestamptz DEFAULT now(), -- Order creation time + is_paid boolean DEFAULT false -- Paid flag +); + +-- Expected Output: +-- Orders table created if it did not exist. +-- No data inserted. (Querying returns zero rows for now.) +-- If table already exists, no error occurs. +``` + +Sau khi thực thi thành công, hệ thống sẽ thông báo script đã hoàn tất. Bạn có thể thấy bảng tương ứng đã được tạo trong Table Editor: + +![](/zh-cn/stage-2/backend/database-supabase/images/image29.png) + +### **2.3.2 **`INSERT`** - Điền dữ liệu ban đầu** + +Sau khi cấu trúc bảng được tạo xong, bước tiếp theo là sử dụng câu lệnh `INSERT INTO` để thêm hàng dữ liệu vào bảng. + +```sql +-- Step 2: Insert initial rows into the orders table +-- Provides realistic, varied data for demo/testing. All values are self-contained. +INSERT INTO orders (user_id, status, amount, details, placed_at, is_paid) VALUES + (2001, 'pending', 23.50, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '2 days', false), + (2002, 'paid', 50.00, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":2,"price":5.00}]}', now() - interval '1 day', true), + (2003, 'cancelled', 15.00, '{"items":[{"sku":"FRY001","name":"French Fries","qty":3,"price":5.00}], "reason":"Not available"}', now() - interval '45 days', false), + (2004, 'paid', 22.98, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":2,"price":9.99}], "promo":"SUMMER22"}', now() - interval '10 days', true), + (2005, 'pending', 18.75, '{"items":[{"sku":"SAL001","name":"Salad","qty":1,"price":6.75},{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '7 hours', false), + (2006, 'paid', 8.00, '{"items":[{"sku":"DRK002","name":"Cola","qty":2,"price":4.00}]}', now() - interval '3 hours', true), + (2007, 'refunded', 14.50, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99},{"sku":"FRY001","name":"French Fries","qty":1,"price":4.51}], "refund_reason":"Late delivery"}', now() - interval '15 days', false), + (2008, 'paid', 26.99, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":1,"price":6.99}]}', now() - interval '12 days', true), + (2009, 'pending', 9.99, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99}]}', now() - interval '30 minutes', false), + (2010, 'paid', 19.89, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00},{"sku":"DRK002","name":"Cola","qty":2,"price":3.95}]}', now() - interval '5 days', true), + (2011, 'cancelled', 0.00, '{"items":[], "reason":"User cancelled"}', now() - interval '2 days', false); + +-- Expected Output: +-- After running this script, SELECT * FROM orders will show about 11 rows with varied user_id, status, amount, details (JSON), placed_at, and is_paid fields. +-- For example: +-- | id | user_id | status | amount | is_paid | placed_at | +-- |----|---------|-----------|--------|---------|---------------------| +-- | 1 | 2001 | pending | 23.50 | false | 2025-10-28 13:40:00Z| +-- | 2 | 2002 | paid | 50.00 | true | ... | +-- |... | ... | ... | ... | ... | ... | +``` + +Sau khi thực thi thành công, lúc này dữ liệu gốc đã được chèn vào bảng, bạn có thể vào giao diện Table Editor làm mới để xem kết quả, cũng có thể trực tiếp tạo cửa sổ mới trong giao diện SQL Editor, thực thi câu lệnh truy vấn `SELECT * FROM orders;` để xem kết quả: + +![](/zh-cn/stage-2/backend/database-supabase/images/image30.png) + +### **2.3.3 **`SELECT`** - Đọc và truy vấn dữ liệu** + +Câu lệnh `SELECT` được sử dụng để truy xuất dữ liệu từ bảng. Thông qua việc sử dụng các mệnh đề khác nhau, có thể thực hiện lọc chính xác, sắp xếp và định dạng dữ liệu, chúng ta có thể tham khảo các câu lệnh sau để thực hiện từng bước và xem kết quả: + +```sql +-- Step 3: SELECT query examples for the orders table + +-- Example 1: Select all fields for all orders +SELECT * FROM orders; +-- Expected Output: Returns all rows and fields. Columns: id, user_id, status, amount, details, placed_at, is_paid. + +-- Example 2: Select only pending orders +SELECT id, user_id, amount FROM orders WHERE status = 'pending'; +-- Expected Output: All rows with status 'pending'; columns: id, user_id, amount. + +-- Example 3: Select specific fields and filter by payment status +SELECT id, status, is_paid, amount FROM orders WHERE is_paid = true; +-- Expected Output: All rows where is_paid is true; columns: id, status, is_paid, amount. + +-- Example 4: Extract all item names from the details (JSON) for each order +SELECT id, details -> 'items' AS item_list FROM orders; +-- Expected Output: Each row shows id and an array from JSON with item details. +``` + +- **Ví dụ 1:** Trả về tất cả các hàng và cột trong bảng `orders`, tương tự như kết quả ở bước hai. +- **Ví dụ 2:** Chỉ trả về các đơn hàng có trạng thái 'pending', và chỉ chứa các cột được chỉ định: + +![](/zh-cn/stage-2/backend/database-supabase/images/image31.png) + +- **Ví dụ 3:** Chỉ trả về các đơn hàng đã thanh toán và hiển thị các cột được chỉ định: + +| id | status | is_paid | amount | +| --- | ------ | ------- | ------ | +| 2 | paid | true | 50.00 | +| 4 | paid | true | 22.98 | +| 6 | paid | true | 8.00 | +| 8 | paid | true | 26.99 | +| 10 | paid | true | 19.89 | + +- **Ví dụ 4:** Trả về `id` của mỗi đơn hàng và mảng `items` được trích xuất từ trường `details`: + +| id | item_list | +| --- | -------------------------------------------------------------------------------------------------------------------- | +| 1 | `[{"qty":1,"sku":"BGR001","name":"Beef Burger","price":12}]` | +| 2 | `[{"qty":2,"sku":"BGR002","name":"Chicken Burger","price":10},{"qty":2,"sku":"DRK001","name":"Lemonade","price":5}]` | +| 3 | `[{"qty":3,"sku":"FRY001","name":"French Fries","price":5}]` | +| ... | ... | + +### **2.3.4 **`INSERT`** - Chèn một bản ghi duy nhất** + +Trong phần 2.3.2, chúng ta đã trình bày việc chèn hàng loạt dữ liệu khi khởi tạo ban đầu, bây giờ chúng ta sẽ xem cách chèn thêm một bản ghi đơn lẻ mới. + +```sql +-- Step 4: INSERT a new order (single row) +-- Example: Add a new paid order for user 2012 with one Chicken Burger +INSERT INTO orders (user_id, status, amount, details, is_paid) +VALUES ( + 2012, 'paid', 9.99, + '{"items":[{"sku":"BGR002","name":"AIID Burger","qty":100,"price":1000}]}', + true +); +-- Expected Output: +-- Before (table fragment): +-- | id | user_id | status | amount | is_paid | +-- | ...| ... | ... | ... | ... | +-- +-- After (last row): +-- | id | user_id | status | amount | is_paid | +-- | xx | 2012 | paid | 9.99 | true | +-- (where xx = next serial value) +``` + +Sau đó, sử dụng `SELECT * FROM orders;` để truy vấn dữ liệu, chúng ta có thể thấy bảng orders đã tăng thành công từ 11 bản ghi lên 12 bản ghi. + +### **2.3.5 **`UPDATE`** - Sửa đổi dữ liệu hiện có** + +Trong công việc thực tế, chúng ta cần thường xuyên cập nhật dữ liệu trong bảng, có thể sử dụng câu lệnh `UPDATE` để sửa đổi các bản ghi đã tồn tại trong bảng. + +```sql +-- Step 5: UPDATE example +-- Example: Mark order with id=1 as paid and update its status +UPDATE orders SET status = 'paid', is_paid = true WHERE id = 1; +-- Expected Output: +-- Before (row with id=1): +-- | id | status | is_paid | +-- | 1 | pending | false | +-- After (row with id=1): +-- | id | status | is_paid | +-- | 1 | paid | true | +-- All other rows remain unchanged. +``` + +### **2.3.6 **`DELETE`** - Xóa dữ liệu** + +Câu lệnh `DELETE` có thể được sử dụng để xóa các bản ghi khỏi bảng và kết hợp với điều kiện để xóa dữ liệu cụ thể. + +```sql +-- Step 6: DELETE example +-- Example: Delete orders older than 2 days to clean up old data +DELETE FROM orders WHERE placed_at < now() - interval '2 days'; +-- Expected Output: +-- Before (filtered for affected rows): +-- | id | status | placed_at | +-- | 3 | shipped | 2025-10-13 ... | <-- will be deleted +-- +-- After: +-- No such rows remain. SELECT * FROM orders WHERE placed_at < now()-interval '2 days' yields zero rows. +-- Other rows in orders table are unaffected. +``` + +Trước khi thực thi, bạn có thể chạy trước `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';` để xem kết quả lọc của bảng dữ liệu. Sau khi chạy lệnh `DELETE`, thực thi lại cùng một câu truy vấn `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';`, kết quả trả về sẽ rỗng, cho thấy các hàng đó đã được xóa thành công. + +## 2.4 Bảo mật cấp hàng (Row Level Security) + +Sau khi học các thao tác cơ bản về cơ sở dữ liệu, chúng ta cần đi sâu hơn vào một khái niệm cốt lõi đảm bảo an toàn dữ liệu - RLS (Bảo mật cấp hàng, Row Level Security). + +Trước hết, hãy suy nghĩ về một câu hỏi quan trọng trong tình huống thực tế: làm thế nào để thực hiện "truy cập cách ly" dữ liệu? Ví dụ, chỉ cho phép người dùng A xem dữ liệu của chính mình, mà không thể thấy thông tin của người dùng B; hoặc, ngay cả khi một vai trò nào đó có quyền truy cập cơ sở dữ liệu, làm thế nào để tránh việc vô tình thao tác hoặc làm lộ dữ liệu nhạy cảm của người dùng khác? + +RLS chính là giải pháp sinh ra để giải quyết nhu cầu về bảo mật và cách ly dữ liệu này. Nó cho phép nhà phát triển định nghĩa các chính sách bảo mật tinh tế cho các bảng cơ sở dữ liệu, dựa trên thông tin danh tính của người dùng (như ID người dùng, quyền vai trò, v.v.), kiểm soát chính xác người dùng nào có thể truy cập, sửa đổi hàng dữ liệu nào trong bảng. + +Lấy một ví dụ điển hình: đối với bảng đơn hàng (`orders`), chúng ta có thể định nghĩa một chính sách RLS như sau - "chỉ khi cột `user_id` của một bản ghi trong bảng `orders` hoàn toàn khớp với ID của người dùng hiện đang đăng nhập, người dùng đó mới có thể truy vấn được dữ liệu đơn hàng này", từ đó thực hiện nhu cầu cốt lõi "người dùng chỉ có thể xem đơn hàng của chính mình". + +Khi bạn bật RLS cho một bảng, tất cả các yêu cầu thao tác dữ liệu trên bảng đó (bao gồm truy vấn `SELECT`, thêm mới `INSERT`, sửa đổi `UPDATE`, xóa `DELETE`) đều sẽ kích hoạt kiểm tra RLS: phải vượt qua kiểm tra của ít nhất một chính sách bảo mật thì thao tác mới được thực thi. Nếu không tồn tại chính sách nào cho phép thao tác đó, hoặc yêu cầu không đáp ứng điều kiện của bất kỳ chính sách nào, cơ sở dữ liệu sẽ trực tiếp từ chối thao tác này, ngăn chặn truy cập trái phép từ cấp nền tảng. + +Trong Supabase, RLS được liên kết sâu với hệ thống xác thực người dùng, khiến việc sử dụng trở nên thuận tiện hơn. Supabase cung cấp một hàm chuyên dụng `auth.uid()`, nó có thể trực tiếp trả về ID duy nhất (định dạng UUID) của "người dùng đã đăng nhập hiện đang gửi yêu cầu". Thông qua hàm này, chúng ta có thể dễ dàng viết các chính sách, thực hiện liên kết chính xác giữa "hàng dữ liệu và danh tính người dùng" (như "`user_id` của đơn hàng khớp với ID người dùng hiện tại" đã đề cập ở trên). + +Cách bật chính sách RLS rất linh hoạt, bạn có thể nhấn nút "RLS" trong giao diện quản lý cơ sở dữ liệu Supabase để trực tiếp cấu hình và bật chính sách: + +![](/zh-cn/stage-2/backend/database-supabase/images/image32.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image33.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image34.png) + +Việc cấu hình thủ công khá phiền toái, thông thường chúng ta sẽ tự động xem xét việc nhúng các chính sách RLS tương ứng khi tạo câu lệnh bảng dữ liệu và khởi tạo. Chúng ta chỉ cần thực thi các câu lệnh tương tự như sau trong SQL Editor để tự động bật chính sách bảo mật cấp hàng cho bảng dữ liệu tương ứng. + +![](/zh-cn/stage-2/backend/database-supabase/images/image35.png) + +# 3. Ứng dụng SQL đầu tiên của bạn + +Sau khi nắm vững các thao tác cơ bản về cơ sở dữ liệu và logic cốt lõi của RLS, chúng ta cuối cùng đã bước vào phần thực hành của hướng dẫn này. Quá trình học tập kéo dài phía trước là để làm cho quá trình "xây dựng ứng dụng từ 0 đến 1" phía sau trở nên rõ ràng hơn. Tiếp theo, chúng ta sẽ lấy "quản lý đơn hàng cửa hàng hamburger" làm kịch bản, hướng dẫn từng bước các thao tác phổ biến của Supabase: từ cấu hình liên kết giữa ứng dụng và Supabase, đến tích hợp cơ sở dữ liệu và chức năng đăng nhập, từng bước học các logic thao tác khác nhau. + +## 3.1 Clone và chạy dự án mẫu Supabase + +Để tiến hành thực hành, trước tiên cần lấy kho mã demo đi kèm. Bạn có thể yêu cầu Trae hoặc Claude Code hỗ trợ git clone kho lưu trữ sau: https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos + +Nếu đã cấu hình khóa SSH, nên sử dụng địa chỉ SSH để clone (git@github.com:THU-SIGS-AIID/Project5-Supabase-Demos.git) để tăng tính bảo mật; nếu kết nối SSH hoặc HTTPS gặp vấn đề mạng, bạn có thể trực tiếp nhấn "Download ZIP" trên trang kho lưu trữ, sau khi giải nén tệp nén sẽ thấy mã nguồn hoàn chỉnh. + +![](/zh-cn/stage-2/backend/database-supabase/images/image36.png) + +Sau khi clone, bạn cũng có thể để Trae hoặc Claude Code giúp bạn khởi chạy dự án, ví dụ trực tiếp mô tả trong giao diện Agent: `Hãy giúp tôi khởi chạy project 1 trong dự án này`, hoặc sao chép đường dẫn tuyệt đối của project muốn khởi chạy, dán vào cho mô hình lớn để mô hình lớn khởi chạy trực tiếp. + +## 3.2 Dự án 1 - Thêm, xóa, sửa, tra cứu menu cửa hàng hamburger + +Tiếp theo chúng ta bước vào phần thực hành - lấy `project-burger-shop-menu-crud-1` làm ví dụ, chúng ta sẽ học cách khởi tạo cơ sở dữ liệu Supabase chỉ bằng một cú click thông qua script SQL, và hoàn tất cấu hình liên kết giữa dự án cục bộ và cơ sở dữ liệu Supabase, để frontend có thể đọc ghi dữ liệu menu bình thường. + +### Sử dụng script để tạo cơ sở dữ liệu + +Đầu tiên, chúng ta cần tạo các nội dung liên quan đến bảng dữ liệu cần thiết trong Supabase. Vào thư mục dự án Project1, bạn sẽ thấy một thư mục tên là `scripts`, trong đó chứa 1 tệp script cơ sở dữ liệu `init.sql`, nó có thể giúp chúng ta tự động hoàn tất việc tạo tất cả các tài nguyên liên quan đến cơ sở dữ liệu (bao gồm cấu trúc bảng, dữ liệu ban đầu, v.v.), sau này chúng ta sẽ thường xuyên sử dụng tệp này để khởi tạo bảng trong cơ sở dữ liệu. + +```sql +...... + +-- ============================================================================ +-- 2. Create Menu Items Table +-- ============================================================================ + +create table if not exists public.menu_items ( + id uuid primary key default gen_random_uuid(), + name text not null, + description text, + category text check (category in ('burger','side','drink')) default 'burger', + price_cents int not null check (price_cents > 0), + available boolean default true, + emoji text, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +-- Comments for documentation +comment on table public.menu_items is 'Burger shop menu items for CRUD demo'; +comment on column public.menu_items.id is 'Unique identifier for each menu item'; +comment on column public.menu_items.name is 'Display name of the menu item'; +comment on column public.menu_items.description is 'Detailed description of the menu item'; +comment on column public.menu_items.category is 'Category: burger, side, or drink'; +comment on column public.menu_items.price_cents is 'Price in cents (integer) to avoid floating point issues'; +comment on column public.menu_items.available is 'Whether the item is currently available for order'; +comment on column public.menu_items.emoji is 'Optional emoji representation of the menu item'; +comment on column public.menu_items.created_at is 'Timestamp when the item was created'; +comment on column public.menu_items.updated_at is 'Timestamp when the item was last updated'; + +...... +``` + +Sau khi thực thi script khởi tạo SQL trong SQL Editor, bạn có thể thấy bảng dữ liệu đã được tạo trong Table Editor. Logic thực thi cụ thể của mã khởi tạo cơ sở dữ liệu như sau: + +1. Tạo bảng menu_items: +2. Bảng này được sử dụng để lưu trữ tất cả các mục trong menu cửa hàng hamburger. Nó bao gồm các trường như name (tên sản phẩm), description (mô tả), price_cents (giá tính bằng xu, tránh vấn đề độ chính xác số thực), category (phân loại) và available (có còn bán không). Về cơ bản bao gồm tất cả thông tin cần thiết cho một mục menu. +3. Tạo bảng promo_codes: +4. Bảng này được sử dụng để quản lý các chương trình khuyến mãi, ví dụ như mã giảm giá. Nó định nghĩa các trường như code (mã giảm giá), discount_type (loại giảm giá, như phần trăm hoặc số tiền cố định), discount_value (giá trị giảm giá), v.v. +5. Vô hiệu hóa Bảo mật cấp hàng (Row Level Security - RLS): +6. Để thuận tiện cho việc phát triển và kiểm thử, script đã tắt RLS một cách rõ ràng. Nhưng kết hợp với logic cốt lõi của RLS mà chúng ta đã học trước đó: RLS là tính năng then chốt của Supabase để đảm bảo an toàn dữ liệu, có thể thông qua chính sách tinh tế để kiểm soát "ai có thể truy cập / sửa đổi dữ liệu nào" (ví dụ chỉ cho phép quản trị viên chỉnh sửa mã khuyến mãi, người dùng thông thường chỉ có thể xem menu). Do đó trong môi trường sản xuất, bắt buộc phải bật RLS và cấu hình chính sách hợp lý, ngăn chặn truy cập trái phép từ cấp nền tảng (như ngăn người dùng độc ý sửa đổi menu do người khác tạo, hoặc làm lộ quy tắc mã khuyến mãi). +7. Chèn dữ liệu hạt giống (Seed Data): +8. Để dự án frontend có thể hiển thị dữ liệu menu và khuyến mãi thực tế ngay sau khi khởi động (không cần nhập thủ công dữ liệu kiểm thử), script `init.sql` cũng sẽ chèn "dữ liệu hạt giống" (tức là dữ liệu mẫu) vào các bảng `menu_items` và `promo_codes`. Ví dụ, bạn có thể thấy nhiều loại hamburger, đồ ăn nhẹ, đồ uống cũng như nhiều loại mã giảm giá khác nhau. + +### Thiết lập kết nối với cơ sở dữ liệu + +Sau khi chuẩn bị cơ sở dữ liệu xong, chúng ta cần kết nối dự án frontend này với Supabase, từ đó có thể đọc dữ liệu trong cơ sở dữ liệu bình thường. Chúng ta cần ghi URL dự án Supabase và anon key vào cấu hình được chỉ định, dự án này cung cấp hai phương pháp cấu hình linh hoạt: + +1. Cấu hình qua biến môi trường + +Tạo một tệp .env trong thư mục gốc của dự án và điền thông tin đăng nhập Supabase của bạn: + +``` +NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co +NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key +``` + +2. Cấu hình trực tiếp trên trang dự án + +Để thuận tiện cho việc demo nhanh và chuyển đổi giữa các dự án Supabase khác nhau, trang chủ có một nút Cài đặt ở góc trên bên phải. Bạn có thể nhấn vào nó và nhập hoặc dán URL Supabase và anon key trực tiếp trong hộp thoại modal hiện ra. + +Sau khi nhấn "Save", thông tin này sẽ được sử dụng để tạo instance client Supabase động, tương tự như mã dưới đây: + +```JavaScript +import { createClient, type SupabaseClient } from '@supabase/supabase-js'; + +// Optional client factory for demos: returns null when env is not set. +export function maybeCreateBrowserClient(): SupabaseClient | null { + const url = process.env.NEXT_PUBLIC_SUPABASE_URL; + const anon = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; + if (!url || !anon) return null; + return createClient(url, anon); +} +``` + +Sau khi tạo cơ sở dữ liệu và điền xong cấu hình liên kết Supabase, bạn có thể thấy giao diện như sau, bạn có thể thử thêm, xóa, tra cứu, sửa đổi sản phẩm và quan sát sự thay đổi của bảng dữ liệu tương ứng trong Supabase. + +![](/zh-cn/stage-2/backend/database-supabase/images/image37.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image38.png) + +### 📚 Bài tập + +1. Thử thêm và xóa các mục hiện có, xem tác động của thao tác sửa đổi đối với nội dung bảng dữ liệu trong Table Editor. + +## 3.4 Dự án 2 - Xác thực người dùng cửa hàng hamburger + +Dự án 1 đã thực hiện "CRUD menu + kết nối cơ sở dữ liệu", Dự án 2 sẽ giới thiệu khả năng cốt lõi gần gũi với nghiệp vụ thực tế hơn: xác thực người dùng (Auth) và quản lý quyền Bảo mật cấp hàng (RLS). + +Dự án 2 bao gồm trang đăng nhập độc lập, hỗ trợ người dùng đăng nhập qua "email + mật khẩu". Logic cốt lõi là gọi các phương thức gốc do Supabase Auth cung cấp, nhanh chóng thực hiện quy trình xác thực, không cần tự phát triển logic kiểm tra đăng nhập phức tạp: + +``` +const { error: err } = await supabaseClient.auth.signUp({ + email, + password, + options: { + data: { + full_name: fullName || null, + birthday: birthday || null, + avatar_url: avatarUrl || null + } + } +}); +``` + +![](/zh-cn/stage-2/backend/database-supabase/images/image39.png) + +Sau khi đăng nhập thành công, Supabase sẽ tự động tạo một phiên (session) cho người dùng và tự động mang theo thông tin xác thực trong tất cả các yêu cầu cơ sở dữ liệu tiếp theo; thông qua tác dụng của RLS, mỗi người dùng dựa trên thông tin xác thực tương ứng chỉ có thể thấy thông tin tài khoản của chính mình (các sản phẩm đã mua, số dư ví còn lại), không thể thấy thông tin tài khoản của người dùng khác, điều này thực hiện cách ly dữ liệu sau khi các người dùng khác nhau đăng nhập, mỗi người chỉ có thể thấy nội dung của chính mình. + +Giống như Dự án 1, bạn cần sử dụng `init.sql` để khởi tạo bảng dữ liệu trước (lưu ý: nếu phát hiện lỗi khởi tạo, hãy xóa bảng dữ liệu đã tạo trong Table Editor trước, hoặc trực tiếp xóa dự án Supabase này và tạo lại một Project mới). + +Sau khi đăng ký tài khoản bằng email thành công và xác nhận đăng ký trong email, đăng nhập và vào giao diện Shop để thấy nội dung như sau: + +![](/zh-cn/stage-2/backend/database-supabase/images/image40.png) + +Nhưng lúc này nhấn vào admin, bạn sẽ không thấy giao diện sau, bạn cần thử tìm phần kiểm soát quyền người dùng trong bảng dữ liệu, sửa quyền thành `admin`, từ đó có thể thấy nội dung như sau trong giao diện Admin: + +![](/zh-cn/stage-2/backend/database-supabase/images/image41.png) + +Đáng lưu ý, hiện tại mỗi lần đăng ký email mới, bạn đều cần xác nhận đăng ký trong email mới có thể đăng nhập; nhưng bước này không phải là bắt buộc, bạn có thể tìm Sign In / Providers trong mục Authentication của Supabase, nhấn Confirm email để hủy yêu cầu xác nhận email bắt buộc. + +![](/zh-cn/stage-2/backend/database-supabase/images/image42.png) + +### 📚 Bài tập + +1. Hãy nhận quà tặng người mới trước, hoàn tất thao tác mua sản phẩm. +2. Thử tìm vị trí bảng dữ liệu thiết lập quyền người dùng, sửa quyền thành `admin`, và sửa đổi số lượng sản phẩm thành công trong giao diện quản lý đơn hàng. +3. Thử định vị bảng liên quan đến số dư ví trong bảng dữ liệu, thông qua sửa đổi để tăng số dư ví còn lại. + +# 4. Xây dựng ứng dụng Supabase đầu tiên của bạn + +Sau khi học tập hệ thống phía trước, bạn đã nắm vững các khả năng cốt lõi của Supabase (thao tác cơ sở dữ liệu, xác thực người dùng, chính sách bảo mật RLS), bây giờ là lúc tự tay xây dựng ứng dụng đầu tiên của bạn bao gồm cơ sở dữ liệu và hỗ trợ hệ thống đăng nhập người dùng! + +## 4.1 Quy trình chuẩn hóa để kết nối bất kỳ ứng dụng nào với cơ sở dữ liệu Supabase + +Chúng ta có thể sử dụng quy trình chuẩn hóa để kết nối bất kỳ ứng dụng nào với cơ sở dữ liệu Supabase: + +1. Trước tiên thực hiện sắp xếp nhu cầu và đồng bộ thông tin, làm rõ mục tiêu và thông báo cho AI + 1. Bạn cần mô tả rõ ràng cho AI về các chức năng cốt lõi của ứng dụng hiện tại và nhu cầu cơ sở dữ liệu mới cần thêm. Ví dụ: "Tôi hiện có một ứng dụng React Todo cục bộ, dữ liệu chỉ được lưu trong bộ nhớ trình duyệt cục bộ, cần thêm chức năng 'đồng bộ dữ liệu đám mây' và kết nối cơ sở dữ liệu Supabase. Hãy giúp tôi phân tích: ứng dụng này liên quan đến những thao tác dữ liệu nào (như thêm việc cần làm, sửa trạng thái, xóa việc cần làm)? Cần tạo những bảng dữ liệu nào để lưu trữ các dữ liệu này?" + 2. Bổ sung các điều kiện ràng buộc quan trọng (tùy chọn): ví dụ yêu cầu định dạng trường (dấu thời gian dùng `timestamptz`, số tiền dùng số nguyên lưu theo xu), quy tắc quyền dữ liệu (chỉ mình tôi có thể thấy việc cần làm), để phân tích của AI phù hợp hơn với nhu cầu thực tế. + 3. Xem xét kết quả AI trả về, nếu có thiếu sót trong tư duy của AI (như chưa xem xét trường "hạn chót của việc cần làm"), hãy bổ sung nhắc nhở sửa đổi: "Bạn đã bỏ sót hạn chót, hãy giúp tôi thêm vào." +2. Để AI dựa trên cấu trúc bảng bạn đã xác nhận, tạo script `init.sql` phù hợp với Supabase: "Dựa trên những ý tưởng và cấu trúc bảng đã nói ở trên, hãy trả về cho tôi script init.sql có thể khởi tạo trong Supabase", sau đó bạn cần thực thi script trong SQL Editor; nếu thực thi báo lỗi, phản hồi thông tin lỗi cho AI để sửa script. +3. Sau khi chạy script init.sql trong Supabase, để AI dựa trên script tái cấu trúc mã hiện tại, để có thể tương tác dữ liệu bình thường với Supabase: "Hãy dựa trên script sql và các thiết lập đã thảo luận ở trên, tái cấu trúc mã dự án để nó hỗ trợ giao tiếp và xử lý dữ liệu với cơ sở dữ liệu Supabase tương ứng". +4. Sau khi tái cấu trúc xong, lúc này chỉ cần cấu hình tham số địa chỉ Supabase và key (dự án chính thức thường chỉ cần cấu hình biến môi trường), sau đó kiểm tra, nếu không có vấn đề thì đã kết nối thành công ứng dụng với cơ sở dữ liệu Supabase. + 1. Chạy dự án, kiểm tra tất cả các chức năng tương tác cơ sở dữ liệu, vào Supabase Table Editor xem dữ liệu có được đồng bộ theo thời gian thực không; + 2. Nếu có vấn đề (như không thể chèn dữ liệu, chỉ thấy một phần dữ liệu), hãy phản hồi hiện tượng vấn đề cho AI để AI xác định nguyên nhân và sửa mã. + +Ngoài ra, nếu mục tiêu là phát triển trang đăng nhập người dùng, bạn có thể trực tiếp để AI hỗ trợ tích hợp trang đăng nhập: "Bây giờ bạn cần giúp tôi thêm hệ thống đăng nhập người dùng Supabase vào ứng dụng này, có thể sử dụng email để đăng ký và đăng nhập". Ngoài ra, bạn còn cần làm rõ với AI về logic và đường dẫn chuyển hướng trang (như sau khi đăng nhập thành công chuyển đến trang chủ hệ thống, địa chỉ trang chủ chuyển đến là gì, khi đăng nhập thất bại ở lại trang hiện tại và hiển thị thông báo lỗi). Sau khi tích hợp xong, bạn cần thử đăng ký và đăng nhập, có thể thấy dữ liệu người dùng mới được thêm trong mục Authentication của Supabase, và sau khi đăng nhập có thể vào bình thường giao diện ứng dụng trước đó không thể vào khi chưa đăng nhập. + +Tất nhiên, bạn cũng có thể trực tiếp để AI tham khảo triển khai của một project nào đó để trực tiếp chuyển đổi các chức năng Supabase tương ứng, ví dụ một Project nào đó sử dụng cơ sở dữ liệu và các chức năng nâng cao của Edge Function, bạn có thể làm theo cách sau để trực tiếp yêu cầu AI chuyển đổi các chức năng tương tự: "Hãy tham khảo logic triển khai chức năng Supabase trong dự án {dán đường dẫn tuyệt đối của dự án tham khảo tại đây} và thêm logic triển khai tương tự cho dự án hiện tại (như đăng nhập người dùng, quản lý cơ sở dữ liệu, yêu cầu hàm, v.v.)." + +## 4.2 Nghiên cứu tình huống: Xây dựng một trò chơi rắn ăn mảnh trực tuyến + +Dựa trên SOP đã đề cập ở trên, chúng ta hãy thực hành thông qua một tình huống cụ thể `Project5-Supabase-Demos/apps_snakegame`: thêm bảng xếp hạng điểm số cho một dự án trò chơi "rắn ăn mảnh" hiện có, bao gồm chức năng đăng nhập người dùng và các chức năng cơ sở dữ liệu cơ bản. + +![](/zh-cn/stage-2/backend/database-supabase/images/image43.png) + +### 4.2.1 Phân tích dự án, xác định nhu cầu dữ liệu + +Đầu tiên, tương tự như quy trình chuẩn hóa đã đề cập trước đó, chúng ta có thể làm rõ nhu cầu cho AI trước, để AI đưa ra phương án sửa đổi tương ứng dựa trên dự án và nhu cầu của chúng ta, sau đó chúng ta sẽ dựa trên phương án sửa đổi này. + +**Bạn có thể sử dụng câu hỏi gợi ý sau để hướng dẫn AI:** + +> "Tôi có một trò chơi rắn ăn mảnh, thư mục ở {dán đường dẫn tuyệt đối của trò chơi rắn ăn mảnh tại đây}. Bây giờ tôi muốn kết hợp Supabase để thêm chức năng bảng xếp hạng trực tuyến, đồng thời hỗ trợ hệ thống đăng nhập người dùng, bảng xếp hạng có thể hiển thị thứ hạng dựa trên tên người dùng và email. +> +> Hãy giúp tôi phân tích, để thực hiện chức năng này, tôi cần tạo những bảng dữ liệu nào? Mỗi bảng nên bao gồm những trường nào?" + +Lúc này bạn sẽ nhận được phản hồi tương tự như sau: + +![](/zh-cn/stage-2/backend/database-supabase/images/image44.png) + +### 4.2.2 Tạo script `init.sql` + +Sau khi xác định các phần cần thiết, chúng ta có thể yêu cầu AI tạo script khởi tạo cơ sở dữ liệu cần thực thi trong Supabase: "Hãy dựa trên phân tích ở trên, giúp tôi tạo script scripts/init.sql trong dự án để khởi tạo cơ sở dữ liệu cần thiết trong Supabase". + +![](/zh-cn/stage-2/backend/database-supabase/images/image45.png) + +### 4.2.3 Cải tạo mã dự án + +Tiếp theo chúng ta chỉ cần yêu cầu AI dựa trên nội dung phía trước tái cấu trúc mã trò chơi rắn ăn mảnh hiện tại: "Tiếp theo hãy dựa trên nội dung đã suy nghĩ ở trên và bảng sql, sử dụng Supabase giúp tôi thực hiện chức năng bảng xếp hạng, bảng xếp hạng là một trang riêng biệt, cần có thể phân biệt tổng điểm của các người dùng khác nhau dựa trên email và tên người dùng, bạn còn cần hỗ trợ hệ thống đăng nhập người dùng dựa trên email, phải đăng ký đăng nhập mới có thể chơi trò chơi này." + +Nếu phiên hội thoại AI hiện tại có quá nhiều vòng, bạn muốn mở một phiên hội thoại mới để tái cấu trúc dự án, bạn có thể đưa `init.sql` đã đề cập ở trên vào nội dung ngữ cảnh, để AI dựa trên tệp sql để tái cấu trúc dự án. + +Nếu phát hiện hệ thống đăng nhập người dùng do AI triển khai không đủ bình thường, bạn có thể trực tiếp đưa địa chỉ của `Project5-Supabase-Demos/apps/project-burger-shop-auth-users-2` đã viết trước đó vào câu hỏi gợi ý, để AI dựa trên dự án triển khai trực tiếp hệ thống đăng nhập người dùng. Và kiểm tra xem đã thiết lập đúng các điều kiện cần thiết để kết nối với Supabase chưa, ngăn ngừa lỗi do cấu hình Supabase không đúng. + +Trong quá trình sửa đổi mã, nếu hiệu quả thực tế không khớp với mong đợi (như dữ liệu bảng xếp hạng không hiển thị, xác thực đăng nhập không hoạt động, v.v.), chỉ cần ghi lại đầy đủ hiện tượng cụ thể và phản hồi cho AI, là có thể dần dần tiếp cận kết quả chính xác. Tiêu chuẩn cải tạo thành công là: người dùng có thể hoàn tất thao tác đăng ký và đăng nhập, và sau khi đăng nhập có thể xem bảng xếp hạng trò chơi tương ứng bình thường. + +![](/zh-cn/stage-2/backend/database-supabase/images/image46.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image47.png) + +### 📚 Bài tập khóa học + +1. Tích hợp hệ thống quản lý người dùng vào phiên bản demo trò chơi rắn ăn mảnh +2. Tích hợp hệ thống quản lý người dùng vào ứng dụng của bạn (nếu trước đó đã phát triển một ứng dụng) + +# 5. Trở thành chuyên gia Supabase + +Trên đây là các thao tác cơ bản của Supabase, trong hành trình tiếp theo chúng ta sẽ tiếp xúc với các nguyên lý và chức năng nâng cao của Supabase, bạn sẽ hiểu tại sao chúng ta chọn Supabase làm tình huống giảng dạy, cũng như cách sử dụng Supabase để thực hiện các thao tác nâng cao hơn, hỗ trợ bạn thực hiện các chức năng tương tác phức tạp hơn, và sau khi học các chức năng này, ngay cả khi đối mặt với các công cụ tương tự khác ngoài Supabase, bạn cũng có thể liên hệ tương tự, hiểu nguyên lý cốt lõi của dịch vụ backend từ cấp độ sâu hơn. Tất nhiên, bạn không cần phải học tất cả trong thời gian ngắn, có lẽ chỉ cần học hỗ trợ đăng nhập bên thứ ba là đã đủ, bạn có thể duyệt qua các nội dung dưới đây trước, quay lại học sâu khi dự án gặp nhu cầu tương ứng. + +## 5.1 Tại sao chúng ta chọn Supabase + +Trước khi bắt đầu phần nâng cao, chúng ta hãy suy nghĩ lại câu hỏi này: trong nhiều giải pháp công nghệ backend, tại sao chúng ta cuối cùng chọn Supabase làm nền tảng công nghệ? + +Các đội ngũ khởi nghiệp thường đối mặt với một mâu thuẫn khi chọn công nghệ: vừa muốn kiểm soát hoàn toàn hệ thống backend, lại phải ra mắt sản phẩm nhanh chóng - việc tự xây dựng backend thường có nghĩa là phải dành hàng tháng để xây dựng các thành phần cốt lõi như cơ sở dữ liệu và đồng bộ thời gian thực, xác thực người dùng, dịch vụ API, lưu trữ tệp, tác vụ định kỳ, giám sát cảnh báo, v.v., trừ khi thành viên đội ngũ đã có kinh nghiệm thực chiến phong phú trong lĩnh vực tương ứng. Dưới áp lực kép từ thiếu vốn và cửa sổ thị trường ngắn, một khi sa lầy vào cơ sở hạ tầng, rất dễ dẫn đến lặp lại chậm trễ, bỏ lỡ không gian tăng trưởng ban đầu. + +Supabase đóng gói các khả năng backend này thành các dịch vụ sẵn sàng sử dụng (cơ sở dữ liệu PostgreSQL, đăng ký thời gian thực, xác thực danh tính, lưu trữ đối tượng, hàm Edge, tự động tạo API, v.v.), cho phép đội ngũ khởi nghiệp tập trung nguồn lực hạn chế vào phát triển chức năng cốt lõi, tránh việc xây dựng cấp nền tảng làm chậm tốc độ ra mắt - điều này đã trở thành chiến lược sinh tồt thực tế trong bối cảnh đầu tư mạo hiểm hiện tại. Tất nhiên, chúng ta cũng có thể sử dụng các sản phẩm backend toàn ngăn xếp khác để phát triển, ví dụ PocketBase (nhẹ và tối giản) và Appwrite (thích ứng đa nền tảng), nhưng xét về tính đầy đủ chức năng, độ trưởng thành hệ sinh thái SQL và mức độ quan tâm cộng đồng Github, Supabase phù hợp hơn để hỗ trợ vận hành ổn định lâu dài của nghiệp vụ. + +Trong số các sản phẩm cùng loại, chiến lược mã nguồn mở của Supabase có lợi thế hơn. Lấy Firebase có thị phần cao làm ví dụ: đặc tính mã nguồn đóng dễ dẫn đến ràng buộc nền tảng, chi phí di chuyển rất cao. Supabase áp dụng mô hình mã nguồn mở hoàn toàn, hỗ trợ triển khai riêng tư, tránh rủi ro khóa nhà cung cấp, có thể chuyển sang các sản phẩm cạnh tranh khác theo nhu cầu. + +Tóm lại, việc chọn công nghệ cần phù hợp với quy mô và mục tiêu nghiệp vụ. Đối với các dự án cá nhân hoặc kiểm thử quy mô rất nhỏ, các giải pháp siêu nhẹ như PocketBase là đủ; nếu doanh nghiệp cần kết nối với hệ thống danh tính phức tạp, hoặc cần đáp ứng yêu cầu kiểm toán tuân thủ của công ty niêm yết, các giải pháp quản lý danh tính cấp doanh nghiệp như WorkOS phù hợp hơn. Nhưng đối với việc xác thực MVP, hỗ trợ nghiệp vụ cốt lõi của người dùng ban đầu, chức năng đầy đủ của Supabase là hoàn toàn đủ, nó không chỉ có thể độc lập hỗ trợ quy mô người dùng ít nhất hàng nghìn, mà còn có thể tích hợp linh hoạt các dịch vụ bên thứ ba như Stripe (thanh toán), Resend (email), Cloudflare (CDN); ngay cả khi nghiệp vụ mở rộng đến nhu cầu cấp doanh nghiệp trong tương lai, kiến trúc mã nguồn mở của Supabase cũng có thể triển khai song song với hệ thống doanh nghiệp, chọn nền tảng phù hợp nhất cho các chức năng khác nhau để sử dụng. Tính linh hoạt tiệm tiến này giúp đội ngũ khởi nghiệp không cần đầu tư quá sớm vào cơ sở hạ tầng nặng, mà vẫn giữ được không gian phát triển future-proof. + +## 5.2 Hỗ trợ đăng nhập Google và GitHub + +Trong hướng dẫn phía trước, chúng ta đã giải thích cách đăng ký và đăng nhập trực tiếp bằng email, nhưng trong thực tế chúng ta thường muốn đơn giản hóa quy trình đăng ký, ví dụ sử dụng đăng nhập bên thứ ba Google và GitHub để đăng ký và đăng nhập nhanh chóng hệ thống, chúng ta sẽ trình bày chi tiết từng bước trong phần hướng dẫn này; đồng thời, một hệ thống xác thực hoàn chỉnh cũng phải cung cấp chức năng đặt lại mật khẩu an toàn và đáng tin cậy, chúng ta cũng sẽ tích hợp chức năng đặt lại mật khẩu vào dự án của phần hướng dẫn này. + +Dự án này `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6`) trình bày đầy đủ cách triển khai các chức năng nâng cao này. + +![](/zh-cn/stage-2/backend/database-supabase/images/image48.png) + +### 5.2.1 Quy trình OAuth: Đăng nhập bên thứ ba hoạt động như thế nào? + +Cốt lõi của đăng nhập bên thứ ba là giao thức ủy quyền mở OAuth 2.0, bản chất của nó là "ủy quyền đại diện": cho phép người dùng ủy quyền ứng dụng của chúng ta (dự án cửa hàng hamburger) truy cập thông tin công khai của họ trên nền tảng bên thứ ba (như Google) (như email, ảnh đại diện), mà không cần tiết lộ mật khẩu của nền tảng bên thứ ba cho ứng dụng của chúng ta,从根本上 ngăn ngừa rủi ro rò rỉ mật khẩu. + +Quy trình hoàn chỉnh có thể được chia thành 5 bước chính, lấy đăng nhập Google làm ví dụ: + +1. Người dùng gửi yêu cầu ủy quyền: Người dùng nhấn nút "Sign in with Google" trên trang, ứng dụng của chúng ta sẽ tự động chuyển hướng người dùng đến trang ủy quyền chính thức của Google (đảm bảo tính bảo mật của quá trình ủy quyền, tránh rủi ro lừa đảo). +2. Người dùng hoàn tất ủy quyền bên thứ ba: Người dùng đăng nhập vào tài khoản của mình trên trang Google (xác minh danh tính người dùng), và đồng ý với quyền mà ứng dụng của chúng ta yêu cầu (như "lấy địa chỉ email"). +3. Google trả về mã ủy quyền một lần: Sau khi ủy quyền thành công, Google sẽ chuyển hướng người dùng trở lại "URL gọi lại (Callback URL)" đã thỏa thuận trước của chúng ta, và đính kèm một mã ủy quyền một lần, có hiệu lực ngắn trong tham số URL (thay vì trực tiếp trả về thông tin người dùng,进一步提升 tính bảo mật). +4. Supabase trao đổi Mã truy cập (Access Token): Backend của chúng ta (do Supabase lưu trữ, không cần tự xây dựng) sẽ dùng mã ủy quyền này, gửi yêu cầu đến giao diện chính thức của Google để đổi lấy Access Token có thể sử dụng để lấy thông tin người dùng (mã ủy quyền chỉ dùng để đổi Token, tránh Token truyền trực tiếp trên frontend). +5. Tạo tài khoản và thiết lập phiên: Supabase sử dụng Access Token để kéo thông tin công khai của người dùng từ Google (như email, ảnh đại diện), và tự động tạo tài khoản cho người dùng này trong dự án của chúng ta (nếu đăng nhập lần đầu) hoặc trực tiếp liên kết với tài khoản hiện có, cuối cùng tạo một phiên người dùng (Session) hợp lệ, hoàn tất đăng nhập. + +![](/zh-cn/stage-2/backend/database-supabase/images/image49.png) + +### 5.2.2 Cấu hình Google Cloud để lấy Client ID và Secret + +Bất kể là phương thức đăng nhập bên thứ ba nào, chúng ta thường cần lấy Client ID và Secret để cấu hình; đối với đăng nhập bên thứ ba của Google, trước tiên bạn cần tạo một OAuth 2.0 Client ID trong Google Cloud Platform để lấy các tham số tương ứng. + +1. **Vào Google Cloud Console**: +2. Truy cập [Google Cloud Console](https://console.cloud.google.com/). +3. Tạo một dự án mới hoặc chọn một dự án hiện có. +4. **Cấu hình Màn hình đồng ý OAuth (OAuth consent screen)**: +5. Trong thanh điều hướng bên trái, tìm "APIs & Services" -> "OAuth consent screen". +6. Chọn loại người dùng "External", sau đó nhấn "Create". +7. Điền tên ứng dụng, email hỗ trợ người dùng và các thông tin bắt buộc khác. +8. Trong phần "Authorized domains", thêm tên miền dự án Supabase của bạn, định dạng là `*.supabase.co`. +9. Lưu và tiếp tục. Trong các bước "Scopes" và "Test users", bạn có thể tạm thời bỏ qua, trực tiếp lưu. +10. **Tạo thông tin xác thực (Create Credentials)**: +11. Vào "APIs & Services" -> "Credentials". +12. Nhấn "+ CREATE CREDENTIALS", chọn "OAuth client ID". +13. Trong "Application type" chọn "Web application". +14. Đặt tên cho nó, ví dụ "Supabase Auth". +15. Trong phần "Authorized redirect URIs", nhấn "ADD URI", và điền URL gọi lại của dự án Supabase. Bạn có thể tìm URL này trong Supabase Dashboard tại "Authentication" -> "Providers" -> "Google", định dạng thường là `https://.supabase.co/auth/v1/callback`. + ![](/zh-cn/stage-2/backend/database-supabase/images/image50.png) +16. Nhấn "CREATE". +17. **Lấy Client ID và Client Secret**: +18. Sau khi tạo thành công, một hộp thoại sẽ hiển thị **Client ID** và **Client Secret** của bạn. Hãy **ngay lập tức sao chép và lưu trữ cẩn thận** chúng. + +### 5.2.3 Cấu hình GitHub để lấy Client ID và Secret + +Tương tự, bạn cũng cần đăng ký một ứng dụng OAuth trên GitHub. + +1. **Vào Developer Settings của **GitHub**:**: + 1. Đăng nhập vào tài khoản GitHub của bạn. + 2. Nhấn vào ảnh đại diện ở góc trên bên phải, vào "Settings". + 3. Ở cuối thanh điều hướng bên trái, tìm "Developer settings". + +2. **Đăng ký ứng dụng mới (Register a new application)**: +3. Chọn "OAuth Apps", sau đó nhấn "New OAuth App". +4. Điền tên ứng dụng, ví dụ "My Burger Shop". +5. **Homepage URL**: Điền địa chỉ trực tuyến của ứng dụng, hoặc địa chỉ phát triển cục bộ `http://localhost:3000`. +6. **Authorization callback URL**: Điền URL gọi lại của dự án Supabase. Tương tự, bạn có thể tìm nó trong Supabase Dashboard tại "Authentication" -> "Providers" -> "GitHub", định dạng là `https://.supabase.co/auth/v1/callback`. +7. Nhấn "Register application". +8. **Lấy Client ID và Client Secret**: +9. Sau khi đăng ký thành công, trang sẽ hiển thị **Client ID** của bạn. + ![](/zh-cn/stage-2/backend/database-supabase/images/image51.png) +10. Nhấn "Generate a new client secret" để tạo **Client Secret** của bạn. Tương tự, hãy **ngay lập tức sao chép và lưu trữ** nó. + +### 5.2.4 Cấu hình Provider trong Supabase + +Bây giờ, hãy cấu hình thông tin xác thực đã lấy được vào Supabase. + +1. **Vào Supabase Dashboard**: +2. Chọn dự án của bạn, vào "Authentication" -> "Providers". +3. **Bật và cấu hình Google**: +4. Tìm "Google" và bật nó. +5. Dán **Client ID** và **Client Secret** lấy từ Google Cloud vào các ô nhập tương ứng. +6. Nhấn "Save". +7. **Bật và cấu hình **GitHub**:**: + 1. Tìm "GitHub" và bật nó. + 2. Dán **Client ID** và **Client Secret** lấy từ GitHub vào các ô nhập tương ứng. + 3. Nhấn "Save". + +![](/zh-cn/stage-2/backend/database-supabase/images/image52.png) + +Đến đây, bạn đã có thể sử dụng tài khoản bên thứ ba để đăng nhập vào trang web đã xây dựng, bạn có thể trực tiếp yêu cầu AI dựa trên dự án `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6` làm tham chiếu, hỗ trợ hệ thống đăng nhập người dùng trên nền tảng dự án của bạn, với chi phí thấp nhất tích hợp giao diện đăng nhập người dùng bao gồm xác thực github và google. + +### 5.2.6 Triển khai đặt lại mật khẩu + +Là một thành phần đăng nhập người dùng trưởng thành, đặt lại mật khẩu cũng là một phần cực kỳ quan trọng, dự án `project-burger-shop-auth-advanced-supabase-6` này cũng bao gồm triển khai đầy đủ chức năng này, bạn có thể trực tiếp yêu cầu AI dựa trên chức năng đặt lại mật khẩu của dự án này để sao chép thành phần đặt lại mật khẩu hoàn chỉnh. Nó chủ yếu chia thành các bước sau: + +1. Gửi yêu cầu: Người dùng nhập email trên trang quên mật khẩu, frontend gọi hàm `supabase.auth.resetPasswordForEmail()`, và chỉ định URL chuyển hướng redirectTo (ví dụ /auth/reset). +2. Gửi email: Supabase sẽ gửi một email chứa liên kết đặt lại duy nhất đến email đó. +3. Truy cập liên kết: Người dùng nhấn liên kết trong email, được chuyển hướng đến trang đặt lại được chỉ định trong ứng dụng. +4. Cập nhật mật khẩu: Trên trang đặt lại, người dùng nhập mật khẩu mới. Frontend gọi `supabase.auth.updateUser()`, gửi mật khẩu mới cho Supabase. Supabase sẽ tự động xác minh tính hợp lệ của liên kết và hoàn tất cập nhật mật khẩu. + +Cuối cùng, nếu bạn cảm thấy email đặt lại mật khẩu hiện tại quá đơn giản, bạn có thể tùy chỉnh mẫu email "Reset Password" trong Supabase Dashboard tại Authentication -> Email Templates. + +Ngoài chức năng Reset password, bạn còn có thể thấy nhiều cài đặt chức năng nâng cao khác liên quan đến quản lý người dùng (ví dụ Invite user, v.v.), bạn có thể dựa trên tài liệu phát triển của từng chức năng, kết hợp công cụ Vibe coding để tự thêm các chức năng tương ứng. + +![](/zh-cn/stage-2/backend/database-supabase/images/image53.png) + +## 5.3 Chức năng thời gian thực + +Chức năng thời gian thực của Supabase là một trong những đặc điểm mạnh nhất, cung cấp sự thuận tiện lớn cho việc xây dựng tài liệu cộng tác, bảng điều khiển thời gian thực, sảnh game hoặc hệ thống chăm sóc khách hàng. + +Dự án này `Project5-Supabase-Demos/apps/project-burger-shop-realtime-orders-3` thông qua việc xây dựng một phòng chat thời gian thực nhiều người, chức năng chia sẻ vị trí con trỏ, trình bày ba khả năng cốt lõi mà Supabase Realtime liên quan: Lắng nghe thay đổi cơ sở dữ liệu (Postgres Changes), Phát sóng (Broadcast) và Trạng thái trực tuyến (Presence). + +![](/zh-cn/stage-2/backend/database-supabase/images/image54.png) + +Nếu bạn cảm thấy phần mã liên quan có độ khó nhất định, bạn có thể trực tiếp yêu cầu AI tham khảo nội dung tài liệu phần này để sửa đổi chương trình của bạn. + +### 5.3.1 Thay đổi cơ sở dữ liệu thời gian thực Postgres Changes + +Chức năng Realtime phổ biến nhất là lắng nghe thời gian thực các thay đổi của cơ sở dữ liệu Postgres Changes. Nó cho phép client đăng ký các sự kiện INSERT, UPDATE hoặc DELETE của các bảng cụ thể, hàng cụ thể thậm chí cột cụ thể trong cơ sở dữ liệu. Một khi cơ sở dữ liệu có thay đổi (dù thông qua gọi API, thao tác Supabase Dashboard, hay thực thi script SQL), Supabase sẽ sử dụng cơ chế sao chép cấp dưới của PostgreSQL, ngay lập tức đẩy dữ liệu thay đổi đến tất cả các client frontend đã đăng ký kênh thông qua WebSocket, mà không cần frontend liên tục thăm dò (Polling). + +Nói chung, chức năng này có thể được bật bằng cách nhấn Enable Realtime trong Table Editor, nhưng thuận tiện hơn là thực thi khởi tạo thông qua script SQL, ví dụ: + +```sql +-- Enable realtime replication +ALTER TABLE public.chat_messages REPLICA IDENTITY FULL; +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_publication_tables + WHERE pubname = 'supabase_realtime' + AND schemaname = 'public' + AND tablename = 'chat_messages' + ) THEN + ALTER PUBLICATION supabase_realtime ADD TABLE public.chat_messages; + END IF; +END $$; +``` + +Câu lệnh này thêm bảng `chat_messages` vào `supabase_realtime` được Supabase thiết lập sẵn, và một khi một bảng được thêm vào `publication` đặc biệt này, máy chủ thời gian thực của Supabase sẽ bắt đầu lắng nghe tất cả các thay đổi dữ liệu của nó. + +Dựa trên bảng dữ liệu đặc biệt ở trên, chúng ta có thể sử dụng mã lắng nghe để theo dõi thời gian thực các thay đổi dữ liệu trong bảng. Điều chúng ta cần thực hiện là khi một người dùng gửi tin nhắn, tất cả người dùng trực tuyến khác đều có thể ngay lập tức thấy tin nhắn này trên màn hình. Điều này có thể được thực hiện thông qua việc đăng ký sự kiện INSERT của bảng chat_messages. + +```typescript + const sub = supabase + .channel('chat_messages_channel') + .on('postgres_changes', { + event: 'INSERT', + schema: 'public', + table: 'chat_messages' + }, (payload: any) => { + console.log('New message received:', payload.new); + const newMessage = payload.new as Message; + // ... // + .subscribe((status: string) => { + console.log('Chat subscription status:', status); + }); +``` + +- `.channel('chat_messages_channel')`: Tạo một kênh liên lạc cách ly. +- `.on('postgres_changes', ...)`: Đây là phương thức đăng ký cốt lõi. Chúng ta cho Supabase biết chúng ta chỉ quan tâm đến sự kiện `INSERT` của bảng `chat_messages`. +- `payload.new`: Khi có tin nhắn mới được chèn vào cơ sở dữ liệu, Supabase sẽ đẩy nội dung đầy đủ của dữ liệu mới này đến tất cả client đã đăng ký thông qua `payload.new`. +- `.subscribe()`: Khởi động đăng ký. + +### 5.3.2 Đồng bộ phát sóng thông tin Broadcast & Presence + +Đối với các tương tác "tức thời" hơn không cần lưu vào cơ sở dữ liệu, như di chuyển con trỏ, trạng thái trực tuyến, v.v., Supabase cung cấp chức năng Broadcast và Presence. + +- Presence: Dùng để theo dõi **trạng thái chia sẻ** của tất cả các client trong kênh. Phù hợp để triển khai chức năng "ai đang trực tuyến". +- Broadcast: Dùng để gửi **tin nhắn tạm thời** **độ trễ thấp** đến tất cả các client khác trong kênh. + +Ý tưởng cốt lõi của Presence là: để mỗi client khai báo trạng thái trực tuyến của mình, và máy chủ Supabase chịu trách nhiệm đồng bộ các trạng thái này một cách đáng tin cậy cho tất cả các client khác trong kênh. Việc triển khai Presence chia thành các bước chính sau: + +1. Tạo một kênh hỗ trợ Presence + +Đầu tiên, chúng ta tạo một kênh `lobby_presence` để xử lý riêng các tương tác này, và chỉ định một key duy nhất để xác định người dùng hiện tại trong cấu hình. Key này thường là ID của người dùng. + +``` +const ch = supabase.channel +('lobby_presence', { + config: { + presence: { key: anonymousUser.id }, + } +}); +``` + +2. Đăng ký kênh để thông báo thông tin "tôi đang trực tuyến" + +Sau khi kênh được tạo thành công, chúng ta cần đăng ký nó. Trong callback khi đăng ký thành công (status === 'SUBSCRIBED'), chúng ta gọi phương thức channel.track(). Phương thức này sẽ phát sóng thông tin của người dùng hiện tại (ví dụ ID người dùng, tên, màu ảnh đại diện, v.v.) cho tất cả các client khác trong kênh, thông báo trạng thái "trực tuyến" của mình. + +``` +const me = { + id: anonymousUser.id, + name: anonymousUser.name, + color: anonymousUser.color +}; + +ch.subscribe(async (status) => { + if (status === 'SUBSCRIBED') { + await ch.track(me); + } +}); +``` + +3. Đồng bộ danh sách trực tuyến đầy đủ + +Khi một người dùng mới tham gia kênh, họ cần lấy danh sách tất cả người dùng đã trực tuyến. Điều này được thực hiện thông qua việc lắng nghe sự kiện sync của presence. Sự kiện sync sẽ được kích hoạt khi bạn lần đầu tham gia kênh, cung cấp cho bạn một "ảnh chụp" đầy đủ. + +Phương thức channel.presenceState() sẽ trả về một đối tượng, chứa thông tin trạng thái của tất cả người dùng trực tuyến hiện tại trong kênh. Chúng ta xử lý nó và cập nhật vào state của ứng dụng, từ đó render danh sách người dùng trực tuyến đầy đủ. + +``` +ch.on('presence', { event: 'sync' }, () +=> { + const state = ch.presenceState(); + const flat = {}; + Object.values(state).forEach((arr) => { + arr.forEach((u) => { flat[u.id] = + { ...u }; }); + }); + setOnline(flat); +}); +``` + +4. Lắng nghe việc tham gia và rời đi của từng người dùng + +Ngoài sự kiện sync, chúng ta còn có thể lắng nghe các sự kiện join và leave, để phản hồi ngay lập tức khi có người dùng mới vào hoặc rời đi, ví dụ hiển thị thông báo "User has joined". + +``` +ch.on('presence', { event: 'join' }, ({ +key, newPresences }) => { + console.log('User joined:', key, + newPresences); +}); + +ch.on('presence', { event: 'leave' }, ({ +key, leftPresences }) => { + console.log('User left:', key, + leftPresences); +}); +``` + +Thông qua các bước trên, chúng ta đã xây dựng một hệ thống trạng thái trực tuyến hoàn chỉnh về mặt chức năng. Supabase tự động xử lý trường hợp người dùng ngắt kết nối bất ngờ (như đóng trình duyệt hoặc mất mạng), và kích hoạt sự kiện leave vào thời điểm thích hợp, đảm bảo tính chính xác của danh sách trực tuyến. + +Khi Presence cho chúng ta biết "ai đang có mặt", Broadcast cho phép họ "trò chuyện" với nhau, nhưng nội dung trò chuyện được lưu trữ tạm thời. Một ví dụ điển hình là theo dõi con trỏ thời gian thực. Nếu mỗi lần di chuyển chuột đều đọc ghi cơ sở dữ liệu, sẽ gây lãng phí hiệu suất và độ trễ rất lớn. Broadcast giải quyết hoàn hảo vấn đề này, nó cho phép tin nhắn truyền trực tiếp giữa các client thông qua WebSocket, bỏ qua hoàn toàn cơ sở dữ liệu. + +Chế độ làm việc của Broadcast chủ yếu dựa vào hai phương thức cốt lõi: channel.send() dùng để gửi, channel.on() dùng để nhận. + +1. Phía gửi: Phát sóng vị trí con trỏ của tôi + +Chúng ta thêm một trình lắng nghe cho sự kiện mousemove. Khi chuột di chuyển, chúng ta tạo payload chứa ID người dùng, tọa độ và màu sắc, sau đó phát sóng nó thông qua channel.send(), và chỉ định tên sự kiện là 'cursor'. + +```typescript +const handleMouseMove = (e) => { + const payload = { +2. Đầu nhận: Lắng nghe và hiển thị con trỏ của người khác + +Trong cùng một kênh, tất cả các client đều sử dụng `channel.on()` để lắng nghe các tin nhắn kiểu `broadcast` có `event` là `'cursor'`. Khi nhận được tin nhắn phù hợp, hàm callback sẽ được kích hoạt. Chúng ta phân tích dữ liệu của người gửi từ `payload` và sử dụng nó để cập nhật trạng thái `online` cục bộ, từ đó hiển thị vị trí con trỏ của các người dùng khác trên màn hình theo thời gian thực. + +```typescript +ch.on('broadcast', { event: 'cursor' }, ({ payload }) => { + setOnline((prev) => ({ + ...prev, + [payload.id]: { + ...(prev[payload.id] || {}), + x: payload.x, + y: payload.y + } + })); +}); +``` + +Thông qua cách này, Presence và Broadcast hoạt động phối hợp với nhau; Presence duy trì danh sách người dùng trực tuyến, trong khi Broadcast chịu trách nhiệm truyền tải các trạng thái tạm thời như vị trí con trỏ giữa các người dùng, cuối cùng đạt được chức năng tương tác thời gian thực phong phú với chi phí thấp. + +## 5.4 Lưu trữ + +Bên cạnh các dữ liệu có cấu trúc có thể định nghĩa rõ ràng như thông tin người dùng, đơn hàng, một ứng dụng hoàn chỉnh thường còn cần xử lý lượng lớn tệp không có cấu trúc -- ví dụ như avatar người dùng, hình ảnh hiển thị sản phẩm, tài liệu đơn hàng do người dùng tải lên, v.v. Đặc điểm của các tệp này là dung lượng chênh lệch lớn, số lượng có thể cực nhiều (ví dụ hình ảnh sản phẩm trên nền tảng thương mại điện tử có thể lên đến hàng chục nghìn甚至 hàng trăm nghìn张), nếu lưu trữ trực tiếp trên máy chủ nghiệp vụ của ứng dụng, sẽ làm tăng đáng kể tải lưu trữ của máy chủ, còn có thể làm chậm tốc độ đọc ghi dữ liệu, ảnh hưởng đến hiệu suất tổng thể của ứng dụng. + +Trong phát triển thực tế, các tệp không có cấu trúc này sẽ được quản lý thống nhất bởi "dịch vụ lưu trữ đối tượng". OSS, Amazon S3 đều thuộc loại dịch vụ này, chúng là "công cụ lưu trữ chuyên nghiệp" được thiết kế riêng cho việc lưu trữ tệp số lượng lớn, có thể xử lý hiệu quả nhu cầu lưu trữ, sao lưu và đọc nhanh tệp. Và khi chúng ta lấy các tệp này trong ứng dụng, sẽ không truy xuất trực tiếp từ "kho lưu trữ cơ sở" của dịch vụ lưu trữ đối tượng, mà thông qua địa chỉ URL: mỗi tệp được lưu trữ trong lưu trữ đối tượng sẽ được gán một URL duy nhất (tương tự như địa chỉ "[https://xxx.oss.com/avatar/user123.jpg](https://xxx.oss.com/avatar/user123.jpg)", có thể hiểu đơn giản là "trang web" này chỉ có một hình ảnh), URL này giống như "địa chỉ truy cập riêng" của tệp, trang front-end chỉ cần thông qua địa chỉ này, có thể trực tiếp tải xuống hoặc tải avatar, hình ảnh sản phẩm, mà không cần dựa vào máy chủ nghiệp vụ của ứng dụng làm trung gian, vừa tăng tốc độ tải tệp, vừa giảm áp lực cho máy chủ nghiệp vụ. + +Dự án `project-burger-shop-storage-uploads-4` này thông qua chức năng tải lên avatar người dùng, trình diễn chuyên sâu cách sử dụng Supabase Storage để xây dựng hệ thống tải tệp hiện đại, giúp nhà phát triển hiểu rõ toàn bộ quy trình từ tải lên tệp không có cấu trúc đến truy cập qua URL. Ngoài ra, dự án này sử dụng thư viện `Uppy` để cung cấp giao diện tải tệp xuất sắc, kết hợp plugin `Tus` để thực hiện tải có thể tiếp tục, bằng cách trỏ điểm cuối tải của Uppy đến API tiêu chuẩn của Supabase (`/storage/v1/upload/resumable`) để hoạt động, bạn có thể tham khảo cách tương tự để thực hiện thành phần chức năng tải lên. + +![](/zh-cn/stage-2/backend/database-supabase/images/image55.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image56.png) + +### 5.4.1. Bucket lưu trữ + +Đơn vị cấu thành của Supabase Storage là Bucket (thùng lưu trữ). Bạn có thể hình dung nó như một thư mục trong hệ điều hành máy tính. Mỗi Bucket có thể có chính sách bảo mật và cấu hình độc lập riêng. + +Tất cả các tệp trong Storage đều có thể được truy cập trực tiếp thông qua một URL công khai, nhưng điều đó không có nghĩa là bất kỳ ai cũng có thể tùy ý tải lên hoặc sửa đổi, quyền truy cập cụ thể sẽ được kiểm soát bởi các chính sách chi tiết hơn. Giống như cơ sở dữ liệu, quyền truy cập Storage cũng được quản lý thông qua chính sách bảo mật cấp hàng. Chính sách SQL được viết trên hai bảng đặc biệt là `storage.objects` và `storage.buckets`, có thể định nghĩa chính xác ai có thể đọc (SELECT), tải lên (INSERT), cập nhật (UPDATE) hoặc xóa (DELETE) tệp. + +Ví dụ, chúng ta có thể tạo một chính sách chỉ cho phép người dùng tải lên thư mục được đặt tên theo `user_id` của chính họ, và chỉ được tải các tệp kiểu hình ảnh: + +``` +CREATE POLICY "Allow authenticated +uploads to avatars bucket" +ON storage.objects FOR INSERT +TO authenticated +WITH CHECK ( + bucket_id = 'avatars' AND + auth.uid() = (storage.foldername(name)) + [1]::uuid AND + (storage.extension(name) IN ('png', + 'jpg', 'jpeg')) +); + +CREATE POLICY "Allow public read access +to avatars" +ON storage.objects FOR SELECT +USING ( bucket_id = 'avatars' ); +``` + +### 5.4.2 Lấy URL tệp có thể truy cập + +Dự án này yêu cầu bạn tạo thủ công một Bucket công khai có tên là `avatars`, tất cả các tệp sẽ được tải lên và lưu trữ dưới Bucket công khai này. Sau khi tệp được tải thành công, chúng ta chỉ nhận được đường dẫn lưu trữ của nó trong Storage, ví dụ `public/avatar1.png`. Đây chỉ là một chuỗi được lưu trữ trong cơ sở dữ liệu, để trình duyệt có thể hiển thị hình ảnh này, chúng ta cần chuyển đổi nó thành một HTTP URL có thể truy cập được. + +Supabase cung cấp hai chiến lược hoàn toàn khác nhau để lấy URL này, chúng có sự khác biệt bản chất về bảo mật, tính bền vững và kiểm soát chi phí. + +#### 1. URL công khai (Public URL) - Liên kết vĩnh viễn + +Đây là cách trực tiếp nhất. Nếu tệp của bạn được lưu trữ trong một **Public Bucket**, bạn có thể lấy một liên kết công khai cố định, vĩnh viễn. + +```typescript +const { data } = supabase.storage + .from('avatars') + .getPublicUrl('public/avatar1.png'); +const publicUrl = data.publicUrl; +``` + +Loại liên kết này có hai đặc điểm cốt lõi: một là đơn giản và trực tiếp, cấu trúc URL cố định, trong thực tế dễ nối và quản lý, giảm thiểu rào cản sử dụng kỹ thuật; hai là có lợi cho bộ nhớ đệm, với tư cách là liên kết vĩnh viễn, nó có thể được bộ nhớ đệm hiệu quả bởi CDN (Mạng phân phối nội dung) và trình duyệt, từ đó cải thiện đáng kể tốc độ truy cập tài nguyên, tối ưu hóa trải nghiệm người dùng. Dựa trên các đặc điểm này, nó phù hợp với các kịch bản tài nguyên công khai thực sự, ví dụ như Logo trang web, hình ảnh danh mục sản phẩm, hình ảnh minh họa bài viết blog, v.v., có thể đáp ứng tốt nhu cầu truy cập và quản lý các tài nguyên loại này. + +Tuy nhiên trong môi trường sản xuất, loại liên kết này có rủi ro rõ ràng về bị đánh cắp băng thông (Hotlinking). Do liên kết là vĩnh viễn công khai, người bên ngoài có thể dễ dàng nhúng liên kết hình ảnh của bạn vào trang web có lưu lượng truy cập cao của họ, dẫn đến băng thông bị sử dụng trái phép. Hành vi này sẽ tạo ra lượng lớn chi phí băng thông không cần thiết cho dự án Supabase của bạn, mà lượng băng thông tiêu thụ này không phục vụ cho ứng dụng của chính bạn, là sự lãng phí chi phí điển hình, là vấn đề cần cảnh giác cao độ và phòng ngừa trong môi trường sản xuất; do đó, chúng ta cần chuyển sang URL ký tạm thời để thực hiện việc phơi bày tài nguyên ra bên ngoài. + +#### 2. URL được ký (Signed URL) - Liên kết ủy quyền tạm thời + +Để giải quyết vấn đề bảo mật và chi phí của URL công khai, Supabase cung cấp cách tạo URL ký tạm thời. Đây là phương pháp thực hành tốt nhất được khuyến nghị cho hầu hết các ứng dụng trực tuyến, ví dụ như ứng dụng tạo ảnh từ văn bản cung cấp cho người dùng liên kết xem ảnh có thời hạn, nền tảng thương mại điện tử chỉ cho phép người dùng đã đặt hàng nhận địa chỉ tải hóa đơn tạm thời, nền tảng nội dung trả phí cung cấp liên kết phát khóa học có hiệu lực ngắn hạn cho người dùng đăng ký, vừa chống sao chép tệp trái phép vừa tránh đánh cắp băng thông, khả năng thích ứng cực kỳ mạnh mẽ. + +```typescript +const { data, error } = await supabase.storage + .from('avatars') + .createSignedUrl('private/user-invoice.pdf', 3600); // Thời gian hiệu lực của liên kết là 3600 giây (1 giờ) +const signedUrl = data?.signedUrl; +``` + +URL ký tạm thời (Signed URL) có ba lợi thế cốt lõi: an toàn và kiểm soát được nghĩa là liên kết mang đánh dấu bảo mật, có thời gian hiệu lực, hết hạn thì không sử dụng được; ràng buộc quyền hạn rất đơn giản -- chỉ những người có thể xem tệp này mới có thể tạo liên kết này, ngay cả khi tệp ẩn trong lưu trữ riêng tư (Private Bucket), sử dụng liên kết này cũng có thể mở bình thường; ngăn chặn đánh cắp băng thông vì liên kết là tạm thời, sao chép sang nơi khác sẽ nhanh chóng hết hiệu lực, không bị lạm dụng băng thông. Nhờ những lợi thế này, các tệp cần quản lý quyền truy cập như avatar người dùng, ảnh cá nhân, nội dung trả phí, hóa đơn đơn hàng đều có thể sử dụng nó. + +Từ góc độ bảo đảm an toàn và kiểm soát chi phí, đề nghị hình thành thói quen ưu tiên sử dụng URL ký tạm thời. Chỉ khi một tài nguyên rõ ràng cần công khai vĩnh viễn, truy cập không hạn chế (ví dụ như Logo công khai của ứng dụng, hình ảnh tuyên truyền sự kiện công cộng, v.v.) thì mới cân nhắc sử dụng Public URL. Như vậy vừa đáp ứng nhu cầu nghiệp vụ cụ thể, vừa tối đa hóa việc tránh rủi ro và tiêu hao chi phí không cần thiết. + +## 5.5 Hàm Edge + +Edge Function là một trong những hình thái có giá trị cốt lõi trong hệ sinh thái Serverless (kiến trúc không máy chủ), nó cung cấp hỗ trợ chạy hàm nhẹ, hiệu quả cho các kịch bản "không có backend tự xây dựng". + +Serverless là gì? Serverless (kiến trúc không máy chủ) không có nghĩa là thực sự không có máy chủ, mà là nhà phát triển không cần quan tâm đến việc mua sắm, vận hành, cấu hình và mở rộng máy chủ. Bạn chỉ cần viết mã nghiệp vụ (hàm), nhà cung cấp dịch vụ đám mây sẽ tự động phân bổ tài nguyên để chạy mã khi có sự kiện cụ thể kích hoạt, và tính phí theo thời gian chạy thực tế. + +Khi ứng dụng của bạn cần thực thi một số logic không thể hoặc không nên hoàn thành trên client (trình duyệt) -- ví dụ như tương tác với API bên thứ ba cần khóa bí mật, thực thi tác vụ tính toán chuyên sâu, hoặc thực thi bắt buộc các quy tắc nghiệp vụ phức tạp -- Edge Functions sẽ phát huy tác dụng. Supabase Edge Functions dựa trên Deno và TypeScript, chúng được triển khai trên các nút edge toàn cầu, gần người dùng về mặt khoảng cách vật lý, từ đó cung cấp độ trễ thực thi hàm cực thấp. + +Hiện nay các nhà cung cấp đám mây chính đều đã ra mắt dịch vụ Edge Function riêng, thường thấy bao gồm: + +- AWS Lambda@Edge: Dịch vụ hàm edge mở rộng dựa trên AWS Lambda, có thể liên kết với CloudFront CDN, hỗ trợ các ngôn ngữ như Node.js, Python, v.v.; +- Cloudflare Workers: Hàm edge do Cloudflare推出的, triển khai trên hơn 275 nút edge toàn cầu, hỗ trợ JavaScript/TypeScript, với "độ trễ cấp mili-giây" là lợi thế cốt lõi; +- Vercel Edge Functions: Hàm edge thích ứng với dự án front-end Vercel, tích hợp sâu với Next.js, hỗ trợ TypeScript, chủ đạo "kết nối liền mạch giữa front-end và logic edge"; + +Quay lại Supabase, khi ứng dụng của bạn cần thực thi logic "không thể hoàn thành trên client (trình duyệt)", ví dụ như gọi API bên thứ ba bằng khóa bí mật (như giao diện LLM), xử lý tác vụ tính toán chuyên sâu (như nén hình ảnh), hoặc thực thi bắt buộc kiểm tra quyền (như quy tắc truy cập tệp), Supabase Edge Functions sẽ phát huy tác dụng. Nó được xây dựng dựa trên Deno runtime và TypeScript, triển khai trên các nút edge toàn cầu, có thể đạt được độ trễ thực thi cực thấp bằng "khoảng cách vật lý gần người dùng", là công cụ cốt lõi để viết logic phía máy chủ tùy chỉnh, đáng tin cậy. + +Dự án `Project5-Supabase-Demos/apps/project-burger-shop-edge-function-5` này thông qua một chức năng đối thoại luồng thời gian thực với mô hình ngôn ngữ lớn (LLM), trình diễn quy trình ứng dụng đơn giản nhất của Edge Functions. + +![](/zh-cn/stage-2/backend/database-supabase/images/image57.png) + +### 5.5.1 Phân tích trường hợp LLM Chat + +Giả sử bạn muốn tích hợp một chatbot tương tự ChatGPT vào ứng dụng. Bạn cần gọi API của OpenAI trên phía máy chủ, nhưng điều này đòi hỏi một API Key bí mật. Key này tuyệt đối không được phơi bày trong mã front-end, nếu không bất kỳ ai cũng có thể xem mã nguồn trang web để đánh cắp Key của bạn, tạo ra chi phí cao. Đây chính là nơi Edge Function phát huy tác dụng. Chúng ta sẽ tạo một hàm có tên `llm-chat`, nó đóng vai trò như một proxy bảo mật giữa front-end và OpenAI API. + +Tham khảo mã của `project-burger-shop-edge-function-5/scripts/llm-chat.ts`, chúng ta hãy xem cách nó hoạt động: + +```typescript +// scripts/llm-chat.ts +import "jsr:@supabase/functions-js/edge-runtime.d.ts"; +import { OpenAI } from "npm:openai"; + +const OPENAI_API_KEY = Deno.env.get("OPENAI_API_KEY"); + +Deno.serve(async (req) => { + try { + const openai = new OpenAI({ apiKey: OPENAI_API_KEY }); + const { prompt } = await req.json(); + + const stream = await openai.chat.completions.create({ + model: "gpt-3.5-turbo", + messages: [{ role: "user", content: prompt }], + stream: true, + }); + + return new Response(stream.toReadableStream(), { + headers: { "Content-Type": "text/event-stream" }, + }); + } catch (err) { + } +}); +``` + +Trong trường hợp này, đối với bảo mật khóa, OPENAI_API_KEY được lưu trữ an toàn dưới dạng biến môi trường trên máy chủ Supabase. Mã front-end cục bộ hoàn toàn không thể tiếp xúc với khóa này, từ đó đảm bảo hiệu quả tính bảo mật của khóa. + +### 5.5.2 Tạo và triển khai hàm + +Supabase cung cấp giao diện rất thân thiện, cho phép bạn hoàn tất triển khai mà không cần chạm đến dòng lệnh. + +1. **Vào bảng Edge Functions** : +2. Đăng nhập vào Dashboard dự án Supabase của bạn. +3. Trong thanh điều hướng bên trái, nhấp vào biểu tượng giống mã, vào "Edge Functions". +4. **Tạo hàm mới** : +5. Nhấp vào nút "Create a new function". + ![](/zh-cn/stage-2/backend/database-supabase/images/image58.png) +6. Đặt tên cho hàm, ví dụ `llm-chat`. +7. **Dán mã** : + ![](/zh-cn/stage-2/backend/database-supabase/images/image59.png) +8. Trong trình soạn thảo trực tuyến hiện ra, **xóa tất cả mã giữ chỗ mặc định**. +9. Mở tệp `llm-chat.ts` cục bộ của bạn, **sao chép toàn bộ nội dung của nó**. +10. **Dán** mã đã sao chép vào trình soạn thảo trực tuyến của Supabase. +11. **Cấu hình biến môi trường** ** (Secrets)** : + 1. Tìm Secrets trong thanh bên. + ![](/zh-cn/stage-2/backend/database-supabase/images/image60.png) + 2. Name: Nhập `OPENAI_API_KEY`. + 3. Value: Dán OpenAI API Key của bạn. + 4. Nhấp vào "Save". Secret được đặt ở đây sẽ được mã hóa và lưu trữ, đồng thời được tiêm an toàn vào môi trường chạy hàm của bạn. + +Nếu hàm cần được cập nhật, hãy nhớ thực thi Deploy updates trong phần Edge Function. Supabase sẽ xây dựng và triển khai hàm này trên đám mây cho bạn. Sau vài phút, hàm của bạn có thể được truy cập trực tuyến. + +Bên cạnh việc làm proxy bảo mật cho mô hình ngôn ngữ, các kịch bản ứng dụng của Edge Functions còn nhiều hơn thế. Trên thực tế, bất kỳ tác vụ nào cần xử lý logic phía máy chủ, dù là gọi API đơn giản, xác thực dữ liệu, hay các tính toán phức tạp hơn, đều có thể thực hiện thông qua Edge Function. Nó cung cấp cho bạn một backend nhẹ, có thể mở rộng mà không cần quản lý bất kỳ cơ sở hạ tầng máy chủ nào. + +Nếu bạn muốn khám phá thêm nhiều khả năng, có thể tham khảo các ví dụ khác trong dự án. Ví dụ: + +- Tạo hình ảnh (txt2img.ts): Hàm này trình diễn cách sử dụng Edge Function để gọi API tạo ảnh từ văn bản (Text-to-Image) bên thứ ba (như Stability AI, Midjourney, v.v.) để tạo hình ảnh động. Đây là một kịch bản điển hình về tính toán chuyên sâu hoặc cần gọi dịch vụ bên ngoài một cách an toàn. Giống như trường hợp llm-chat, khóa API được lưu trữ an toàn ở backend Supabase, front-end chỉ chịu trách nhiệm gửi mô tả văn bản, sau đó nhận và hiển thị hình ảnh đã tạo, toàn bộ quá trình an toàn, hiệu quả. +- Gửi email (send-email.ts): Gửi email chào mừng, thông báo giao dịch hoặc email đặt lại mật khẩu trong ứng dụng là nhu cầu phổ biến. Ví dụ send-email.ts trình diễn cách tích hợp dịch vụ email (như Resend, SendGrid) thông qua Edge Function. Bạn không cần phơi bày khóa API dịch vụ email nhạy cảm trong mã client, chỉ cần tạo một hàm, để front-end kích hoạt gửi email thông qua việc gọi hàm này. + +## 5.6 Đăng nhập Clerk + +Clerk là một công cụ phát triển chuyên nghiệp tập trung vào xác thực danh tính và quản lý người dùng, năng lực cốt lõi bao gồm đăng ký người dùng, đăng nhập, bảo mật tài khoản MFA, kiểm soát quyền, quản lý phiên, v.v., toàn bộ chuỗi nhu cầu liên quan đến xác thực danh tính, có thể giúp nhà phát triển nhanh chóng xây dựng hệ thống người dùng an toàn, linh hoạt và tuân thủ tiêu chuẩn ứng dụng hiện đại mà không cần phát triển logic xác thực phức tạp từ đầu. + +Phần này sẽ giới thiệu cách cấu hình dịch vụ Clerk từ đầu và tích hợp nó với Supabase. Bạn có thể trải nghiệm toàn bộ quy trình trong dự án `project-burger-shop-auth-advanced-clerk-7`. + +![](/zh-cn/stage-2/backend/database-supabase/images/image61.png) + +### 5.6.1 Tạo ứng dụng Clerk và lấy khóa + +Trước khi sử dụng dự án này, bạn cần có tài khoản Clerk và tạo một ứng dụng. + +1. Đăng ký và tạo: + 1. Truy cập [dashboard.clerk.com](https://dashboard.clerk.com/) và đăng ký tài khoản. + 2. Nhấp vào "Create application". + ![](/zh-cn/stage-2/backend/database-supabase/images/image62.png) + 3. Nhập tên ứng dụng (ví dụ "Burger Shop"). + 4. Trong "How will your users sign in?", mặc định chọn Email, Google, GitHub. + 5. Nhấp vào Create application. +2. Lấy API Keys: + 1. Sau khi tạo thành công, bạn sẽ được hướng dẫn đến trang API Keys. + ![](/zh-cn/stage-2/backend/database-supabase/images/image63.png) + 2. Tìm Publishable key (bắt đầu bằng `pk_`) và Secret key (bắt đầu bằng `sk_`). + ![](/zh-cn/stage-2/backend/database-supabase/images/image64.png) + 3. Sao chép chúng vào tệp `.env.local` của bạn (tham khảo `.env.example` của dự án này): + + ```bash + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... + CLERK_SECRET_KEY=sk_test_... + ``` + +### 5.6.2 Cấu hình tích hợp nguyên bản giữa Supabase và Clerk + +Trước khi sử dụng sâu hơn, chúng ta cần tích hợp mối quan hệ giữa Supabase và Clerk, thuận tiện cho việc chuyển hướng xác thực đăng nhập và kiểm soát quyền truy cập cơ sở dữ liệu cụ thể sau này. Supabase và Clerk cung cấp khả năng tích hợp nguyên bản chính thức, thông qua tích hợp này có thể nhanh chóng thực hiện kết nối xác thực danh tính giữa hai bên mà không cần cấu hình thủ thích phức tạp, đơn giản hóa đáng kể quy trình phát triển các chức năng như đăng nhập người dùng, kiểm tra quyền: + +1. Kích hoạt tích hợp chính thức Supabase trong Clerk + 1. Đăng nhập vào [Clerk Dashboard](https://dashboard.clerk.com/). + 2. Trong menu điều hướng bên trái, đi đến Integrations (Tích hợp). + 3. Tìm và nhấp vào Supabase trong danh sách. + 4. Bật công tắc Enable Supabase (hoặc nhấp vào Activate integration). + 5. Bước quan trọng: Sau khi kích hoạt thành công, trang sẽ hiển thị Clerk Domain của bạn (định dạng thường là `https://.clerk.accounts.dev` hoặc tên miền tùy chỉnh của bạn). Vui lòng sao chép địa chỉ Domain này, sẽ sử dụng ở bước tiếp theo. +2. Thêm nhà cung cấp Clerk trong Supabase + 1. Đăng nhập vào [Supabase Dashboard](https://supabase.com/dashboard) và vào dự án của bạn. + 2. Trong menu điều hướng bên trái, đi đến Authentication > Sign In / Up (hoặc nhấp trực tiếp vào Providers). + 3. Nhấp vào nút Add provider, chọn Clerk từ danh sách thả xuống. + 4. Trong hộp nhập Clerk Domain hiện ra, dán địa chỉ Domain bạn vừa sao chép từ Clerk. + 5. Nhấp vào Save để lưu cấu hình. + +### 5.6.3 Đồng bộ dữ liệu người dùng sang Supabase thông qua Webhook + +Chỉ tích hợp là chỉ đáp ứng nhu cầu xác định quyền, nhưng điều này sẽ không đồng bộ thông tin người dùng đã đăng ký trong Clerk sang Supabase. Để thuận tiện cho việc quản lý, chúng ta còn cần giữ một bản sao người dùng trong bảng `public.users` của Supabase, để thực hiện truy vấn liên kết hoặc phân tích dữ liệu. Chúng ta có thể thực hiện chức năng này thông qua Clerk Webhooks, toàn bộ quy trình như sau: + +1. **Clerk gửi thông báo**: Khi người dùng đăng ký hoặc cập nhật thông tin trong Clerk, Clerk sẽ gửi một yêu cầu POST đến URL Webhook mà chúng ta đã cấu hình. +2. **Supabase nhận và ghi入**: Edge Function nhận yêu cầu, xác minh chữ ký (đảm bảo an toàn), sau đó cập nhật dữ liệu người dùng vào bảng cơ sở dữ liệu của Supabase. + +Trước khi bắt đầu, chúng ta cần cấu hình bảng dữ liệu cần thiết để đồng bộ thông tin: + +```sql +-- File: init.sql + +-- 1. Create `users` table for synced Clerk users +-- This table will store user data pushed from Clerk Webhooks. +CREATE TABLE public.users ( + id TEXT NOT NULL PRIMARY KEY, -- Corresponds to Clerk User ID + email TEXT, + first_name TEXT, + last_name TEXT, + image_url TEXT, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- 2. Enable Row Level Security (RLS) on the table +-- This is an important security measure to ensure users cannot access any data by default. +ALTER TABLE public.users ENABLE ROW LEVEL SECURITY; + +-- 3. Create RLS policies +-- Policy 1: Allow authenticated users to read their own user info. +-- `auth.jwt()->>'sub'` extracts the user ID from the JWT provided by Clerk. +CREATE POLICY "Authenticated users can view their own user record" +ON public.users FOR SELECT +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); + +-- Policy 2: Allow users to update their own info. +CREATE POLICY "Authenticated users can update their own user record" +ON public.users FOR UPDATE +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); +``` + +Và kích hoạt Edge function tương ứng trong Supabase: + +```JavaScript +// File path: supabase/functions/clerk-webhooks/index.ts + +import { serve } from 'https://deno.land/std@0.177.0/http/server.ts' +import { Webhook } from 'npm:svix' +import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' + +// Get Clerk Webhook signing secret from environment variables +const CLERK_WEBHOOK_SECRET = Deno.env.get('CLERK_WEBHOOK_SECRET') + +if (!CLERK_WEBHOOK_SECRET) { + throw new Error('CLERK_WEBHOOK_SECRET is not set in environment variables') +} +const supabaseAdmin = createClient( + Deno.env.get('SUPABASE_URL')!, + Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')! +) + +serve(async (req) => { + try { + // 1. Get Svix signature info from request headers + const headers = Object.fromEntries(req.headers) + const svix_id = headers['svix-id'] + const svix_timestamp = headers['svix-timestamp'] + const svix_signature = headers['svix-signature'] + + if (!svix_id || !svix_timestamp || !svix_signature) { + return new Response('Missing Svix headers', { status: 400 }) + } + + const payload = await req.json() + const body = JSON.stringify(payload) + + // 2. Verify Webhook signature validity using the secret + const wh = new Webhook(CLERK_WEBHOOK_SECRET) + const evt = wh.verify(body, { + 'svix-id': svix_id, + 'svix-timestamp': svix_timestamp, + 'svix-signature': svix_signature, + }) + + const { id } = evt.data + const eventType = evt.type + console.log(`Received webhook event: ${eventType} for user: ${id}`) + + // 3. Execute database operations based on event type + switch (eventType) { + case 'user.created': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin.from('users').insert({ + id, + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + }) + if (error) throw error + console.log(`User ${id} created in Supabase.`) + break + } + + case 'user.updated': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin + .from('users') + .update({ + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + updated_at: new Date().toISOString(), // Update timestamp + }) + .eq('id', id) + if (error) throw error + console.log(`User ${id} updated in Supabase.`) + break + } + + case 'user.deleted': { + // For delete events, ID might be at the top level + const deletedId = id + if (!deletedId) { + return new Response('Deleted user ID not found', { status: 400 }) + } + const { error } = await supabaseAdmin.from('users').delete().eq('id', deletedId) + if (error) throw error + console.log(`User ${deletedId} deleted from Supabase.`) + break + } + } + + return new Response('Webhook processed successfully', { status: 200 }) + } catch (err) { + console.error('Error processing webhook:', err.message) + return new Response(`Webhook Error: ${err.message}`, { status: 400 }) + } +}) +``` + +Sau khi khởi tạo bảng dữ liệu và hàm Supabase, bạn còn cần kích hoạt hỗ trợ Webhooks trong Clerk: + +- Trong Clerk Dashboard -> **Webhooks**, thêm Endpoint, điền URL của Supabase Edge Function. +- Chọn các sự kiện `user.created`, `user.updated`, `user.deleted`, v.v. + +![](/zh-cn/stage-2/backend/database-supabase/images/image65.png) + +Sau khi thiết lập thành công, bạn có thể xem các thông tin yêu cầu khác nhau trong Message Attempts, nhấp vào có thể thấy kết quả tham số trả về chi tiết của yêu cầu; nếu webhook gặp vấn đề khi yêu cầu Edge function, bạn có thể nhanh chóng tìm thấy nguyên nhân chi tiết trong giá trị trả về. Đề xuất bạn đồng thời đối chiếu thông tin nhật ký yêu cầu của Clerk và Supabase, để phân tích xem các hàm đã thiết lập có chính xác hay không. + +### 5.6.4 Hỗ trợ đăng nhập bên thứ ba trong Clerk + +Trước khi tìm hiểu sâu về cách Clerk hỗ trợ đăng nhập bên thứ ba, chúng ta hãy làm rõ hai khái niệm cốt lõi: môi trường phát triển và môi trường sản xuất, đây là hai giai đoạn quan trọng từ "phát triển thử nghiệm" đến "trực tuyến có thể sử dụng" của phần mềm, định vị, mục đích sử dụng và yêu cầu bảo mật của hai môi trường này hoàn toàn khác nhau: + +- Môi trường phát triển: Môi trường sử dụng trên máy cục bộ của nhà phát triển hoặc máy chủ thử nghiệm, chỉ dành cho phát triển tính năng, gỡ lỗi và xác minh nội bộ (như dịch vụ localhost:3000 cục bộ), không mở ra bên ngoài +- Môi trường sản xuất: Sau khi ứng dụng chính thức trực tuyến, môi trường công khai hướng đến người dùng thực (như triển khai trên các nền tảng Vercel, Alibaba Cloud, v.v. tại https://my-app.com) + +Và Clerk phân biệt hai môi trường này đối với đăng nhập xã hội, bản chất là cân bằng "hiệu suất phát triển" và "bảo mật sản xuất": giai đoạn phát triển cần giảm cấu hình dư thừa để nhanh chóng xác minh chức năng, giai đoạn sản xuất cần đảm bảo bảo mật dữ liệu thông qua thông tin xác thực chuyên dụng, đồng thời tuân thủ quy tắc của các nền tảng OAuth bên thứ ba như Google, GitHub (ứng dụng trực tuyến phải liên kết tên miền và thông tin xác thực chuyên dụng, không được phép sử dụng tài nguyên dùng chung). Dưới đây là mô tả cụ thể về cấu hình khác biệt của đăng nhập xã hội Clerk trong hai môi trường: + +1. **Xác minh nhanh trong môi trường phát triển** + +Trong môi trường phát triển, Clerk đã được cấu hình sẵn thông tin xác thực OAuth dùng chung và URI chuyển hướng mặc định, không cần đến GitHub/Google để nộp đơn xin thông tin xác thực chuyên dụng, các bước thao tác như sau: + +- Đăng nhập vào Clerk Dashboard, trong thanh điều hướng bên trái vào trang SSO connections (Kết nối SSO). +- Nhấp vào Add connection (Thêm kết nối), chọn For all users (Có hiệu lực cho tất cả người dùng). +- Trong menu thả xuống Choose provider (Chọn nhà cung cấp), chọn GitHub hoặc Google theo nhu cầu. +- Nhấp trực tiếp vào Add connection (Thêm kết nối), Clerk sẽ tự động sử dụng thông tin xác thực dùng chung để hoàn tất liên kết. + + Sau khi cấu hình, khởi động ứng dụng cục bộ (như `localhost:3000`) và nhấp vào "Sign in with GitHub/Google", Clerk sẽ tự động proxy yêu cầu đăng nhập, nhanh chóng xác minh xem chức năng có bình thường hay không. + +2. **Cấu hình thông tin xác thực tùy chỉnh trong môi trường sản xuất** + +(Lưu ý: Nếu phát hiện có khâu không nhất quán với dự kiến, đề xuất đọc tài liệu chính thức để thử cách mới nhất) + +Sau khi ứng dụng được triển khai trực tuyến (như Vercel, Alibaba Cloud) và chuyển sang Clerk Production Instance, thông tin xác thực dùng chung sẽ hết hiệu lực, cần cấu hình thông tin xác thực OAuth tùy chỉnh cho GitHub/Google (đề xuất đồng thời mở Clerk Dashboard và trang nền tảng bên thứ ba, thuận tiện cho thao tác đồng bộ): + +- Thao tác chung trước (Bảng điều khiển Clerk): + - Vào trang Clerk SSO connections, nhấp Add connection -> chọn For all users. + - Chọn nền tảng mục tiêu (GitHub/Google), đảm bảo bật Enable for sign-up and sign-in (Cho phép đăng ký đăng nhập) và Use custom credentials (Sử dụng thông tin xác thực tùy chỉnh). + - Sao chép Authorization Callback URL (GitHub) hoặc Authorized Redirect URI (Google) trên trang, lưu vào vị trí an toàn, không đóng trang/cửa sổ hiện tại. +- 2.1 Cấu hình nền tảng GitHub: + - Đăng nhập GitHub, vào Developer Settings (Đường dẫn: Avatar -> Settings -> Developer settings -> OAuth Apps). + - Nhấp vào New OAuth app, điền thông tin: `Application name` (Tên ứng dụng), `Homepage URL` (Tên miền sản xuất, như `https://my-app.com`), `Authorization Callback URL` (Dán địa chỉ đã sao chép từ Clerk). + - Nhấp Register application, sau đó nhấp Generate a new client secret, lưu Client ID và Client Secret đã tạo (Secret chỉ hiển thị một lần). + - Quay lại cửa sổ Clerk, dán Client ID và Client Secret, nhấp Add connection để hoàn tất cấu hình (Nếu đã đóng cửa sổ, có thể tìm kết nối GitHub trong SSO connections, điền bổ sung trong phần "Use custom credentials"). +- 2.2 Cấu hình nền tảng Google: + - Đăng nhập Google Cloud Console, chọn dự án hiện có hoặc tạo dự án mới (như "My App Production"). + - Nhấp vào menu góc trên bên trái -> APIs & Services -> Credentials, nhấp Create Credentials -> OAuth client ID (Cấu hình lần đầu cần hoàn tất thiết lập OAuth consent screen trước, chọn "External" và điền thông tin ứng dụng). + - Chọn Application type là Web application, cấu hình: + 1. `Authorized JavaScript origins`: Thêm tên miền sản xuất (như `https://my-app.com`, `https://www.my-app.com`), để xác minh cục bộ có thể bổ sung `http://localhost:số_cổng`. + 2. `Authorized Redirect URIs`: Dán địa chỉ đã sao chép từ Clerk. + - Nhấp Create, lưu Client ID và Client Secret trong cửa sổ hiện ra, quay lại cửa sổ Clerk dán và nhấp Add connection. + - Lưu ý quan trọng: + 1. Cấm đăng nhập WebView: Google OAuth không hỗ trợ đăng nhập qua trình duyệt trong ứng dụng, cần tham khảo [tài liệu chính thức Google](https://support.google.com/cloud/answer/7657789) để điều chỉnh. + 2. Chuyển đổi trạng thái xuất bản: Trạng thái "Testing" mặc định chỉ hỗ trợ 100 người dùng thử nghiệm, cần thay đổi "Publishing status" thành In production trong OAuth consent screen (cần thông qua đánh giá của Google). + 3. Chặn email con: Clerk mặc định chặn email Google chứa `+`/`=`/`#` (như `user+alias@example.com`), có thể bật/tắt Block email subaddresses trong trang chi tiết kết nối Google (đề xuất bật để tăng bảo mật). + 4. Hỗ trợ Google One Tap: Sau khi cấu hình hoàn tất, có thể tích hợp thành phần `` của Clerk để thực hiện "đăng nhập một chạm", tham khảo [tài liệu thành phần Clerk](https://clerk.com/docs/components/social-connections/google-one-tap). + +3. Kiểm tra kết nối đăng nhập bên thứ ba + +Sau khi cấu hình hoàn tất, xác minh chức năng thông qua Account Portal tích hợp sẵn của Clerk: + +- Vào Clerk Dashboard, trong thanh điều hướng bên trái vào trang Account Portal. +- Trong phần "Sign-in" bên phải, nhấp vào nút "Truy cập trang đăng nhập", chuyển đến trang đăng nhập môi trường tương ứng: + - Môi trường phát triển: `https://tên-miền-của-bạn.accounts.dev/sign-in` (như `https://my-app.accounts.dev/sign-in`). + - Môi trường sản xuất: `https://accounts.tên-miền-của-bạn.com/sign-in` (như `https://accounts.my-app.com/sign-in`). +- Nhấp vào "Sign in with GitHub/Google", đăng nhập bằng tài khoản nền tảng tương ứng, nếu có thể chuyển hướng thành công và quay lại ứng dụng,说明 kết nối đã được cấu hình bình thường. + +# 6. Từ Supabase đến nhiều thành phần phát triển backend hơn (Nâng cao) + +Trong phần trên, chúng ta chủ yếu đứng từ góc nhìn của Supabase, xem "một nền tảng backend tất cả trong một lấy Postgres làm cốt lõi" có thể giúp chúng ta giải quyết những vấn đề nào: xác thực, cơ sở dữ liệu, lưu trữ tệp, giao tiếp thời gian thực, hàm edge, v.v., đều được tích hợp trong cùng một bảng điều khiển, sẵn sàng sử dụng, trải nghiệm thống nhất, rất phù hợp để bắt đầu nhanh chóng và các dự án vừa và nhỏ. + +Nhưng từ góc độ dài hạn và kỹ thuật hơn, **mỗi khả năng mà Supabase cung cấp (Auth / Storage / Edge Functions / Realtime / Database), trong ngành đều hầu như có giải pháp thay thế chuyên nghiệp tương ứng** -- bao gồm cả các nền tảng BaaS同类, cũng như các dịch vụ đám mây và thành phần mã nguồn mở "đột phá đơn điểm" hơn. Với tư cách là nhà phát triển cá nhân và đội ngũ khởi nghiệp có tham vọng, việc hiểu các lựa chọn thay thế này có một số lợi ích: + +- Đánh giá xem dự án hiện tại có "chỉ dùng Supabase là đủ" hay không, hay một khía cạnh nào đó cần dịch vụ chuyên dụng chuyên nghiệp hơn / rẻ hơn / dễ tuân thủ hơn; +- Khi quy mô dự án lớn lên hoặc nhu cầu phức tạp hơn, có thể thay thế một module nào đó từ Supabase ra ngoài (ví dụ chuyển sang nền tảng Auth chuyên dụng hoặc lưu trữ đối tượng), thay vì bị khóa chặt bởi nền tảng ngay từ đầu; +- Mở rộng tầm nhìn lựa chọn kỹ thuật, ngay cả khi tạm thời không thay đổi, cũng có thể biết đại khái "nếu không sử dụng tính năng X của Supabase, tôi còn những lựa chọn phổ biến nào". + +Phần này sẽ giới thiệu riêng biệt các giải pháp thay thế phổ biến trên thị trường cho một số khả năng chính mà Supabase bao phủ, ví dụ: xác thực (Auth), lưu trữ tệp (Storage), hàm edge (Edge Functions), giao tiếp thời gian thực (Realtime), lưu trữ cơ sở dữ liệu, v.v. Đơn giản so sánh sự khác biệt của chúng về đặc tính chức năng, hạn mức miễn phí/định giá, tính dễ sử dụng và mức độ phổ biến của cộng đồng, giúp bạn có hiểu biết toàn diện hơn về bộ công cụ thành phần backend. + +## Nền tảng Baas tương tự + +Trước khi bắt đầu, chúng ta có thể duyệt qua các nền tảng Baas tương tự, nếu cảm thấy Supabase không đủ tốt, bạn có thể chọn các sản phẩm thay thế khác nhau để thử nghiệm theo nhu cầu. + +| Nền tảng/Dịch vụ | Loại | Hạn mức miễn phí/Định giá | Đặc điểm / Kịch bản áp dụng | +| --- | --- | --- | --- | +| Firebase (Google) | BaaS quản lý hoàn toàn (Auth + Firestore + Storage + Functions + Hosting) | Spark: hạn mức nhẹ miễn phí; Blaze: tính phí theo lượng sử dụng (Firestore/Storage/Functions tính riêng) | Thành thục nhất trong ngành, tài liệu tốt, nhanh chóng làm quen, khả năng thời gian thực mạnh. Phù hợp cho sản phẩm vừa và nhỏ, đội ngũ chủ đạo mobile/front-end. Nhược điểm: tính phí phức tạp, mức độ khóa cao, nhiều hạn chế truy vấn (đặc biệt Firestore). | +| Supabase | BaaS mã nguồn mở (Postgres + Auth + Storage + Edge Functions + Realtime) | Miễn phí: 500MB DB, 1GB Storage, vài lệnh gọi hàm không máy chủ; Pro: tính phí theo instance | Phiên bản SQL giống Firebase nhất; giao diện xuất sắc, trải nghiệm hiện đại, có thể tự lưu trữ. Phù hợp cho ứng dụng cần SQL mạnh, BI, khả năng giao dịch. Nhược điểm: chi phí cao cho đồng thời cao hoặc hàm phức tạp. | +| Appwrite Cloud | BaaS tất cả trong một mã nguồn mở (DB + Auth + Storage + Functions + Realtime) | Miễn phí: bao gồm DB/Storage/FaaS cơ bản; trả phí theo cấp tài nguyên | Trải nghiệm hiện đại, API thống nhất, có thể tự lưu trữ; phù hợp cho phát triển nhanh ứng dụng thân thiện với nhà phát triển. Nhược điểm: hệ sinh thái chưa trưởng thành bằng Firebase/Supabase; hiệu suất cần thử nghiệm trong ứng dụng lớn. | +| Nhost | Postgres + GraphQL + Auth + Storage + Functions | Miễn phí: 1GB DB, 1GB Storage, vài lệnh gọi hàm | Tương tự "Supabase + Hasura"; GraphQL tự nhiên; phù hợp cho đội ngũ front-end và dự án React/Next.js. Nhược điểm: hệ sinh thái nhỏ, chi phí tăng theo lượng sử dụng. | +| AWS Amplify | Backend tất cả trong một của AWS (Cognito + AppSync + DynamoDB + Storage + Functions + Hosting) | Miễn phí: hạn mức Hosting + Cognito 10k MAU + một phần hạn mức hàm | Lớn và toàn diện, phù hợp cho đội ngũ đã có nền tảng AWS; độ tin cậy cấp doanh nghiệp. Nhược điểm: khó tiếp cận nhất, dịch vụ phân mảnh; chi phí bảo trì cao cho đội ngũ khởi nghiệp. | +| Xata (tăng trưởng nhanh trong gần hai năm) | Cơ sở dữ liệu đa mô hình + Auth + Edge Functions | Miễn phí: 250k bản ghi, 15GB băng thông | Mặc dù thiên về "DB + API" hơn, nhưng cung cấp Auth, tệp, logic, có thể sử dụng như backend toàn ngăn xếp nhẹ. UI/trải nghiệm phát triển cực tốt. Nhược điểm: chức năng không toàn diện bằng Firebase/Supabase. | +| Convex (Trải nghiệm nhà phát triển cực mạnh) | Cơ sở dữ liệu được quản lý + Auth + Functions (Ưu tiên front-end) | Phiên bản phát triển miễn phí; trả phí tính theo lượng yêu cầu | Cực kỳ dễ tiếp cận; không cần schema; front-end viết hàm là có thể sử dụng backend. Phù hợp cho MVP/xác minh nhanh. Nhược điểm: liên kết chặt với nền tảng, chi phí di chuyển cao; không hoàn toàn là BaaS truyền thống. | + +## Xác thực (Auth) + +| Công cụ/Nền tảng | Đặc điểm chức năng | Hạn mức miễn phí/Định giá | Kịch bản áp dụng và Ưu nhược điểm | +| --- | --- | --- | --- | +| Firebase Authentication | Dịch vụ xác thực BaaS do Google cung cấp, hỗ trợ các phương thức phổ biến như email/mật khẩu, điện thoại, đăng nhập xã hội, ẩn danh, v.v. Gói miễn phí Spark hỗ trợ tối đa 50k MAU. | Spark (miễn phí) 50k MAU; Blaze tính phí theo lượng sử dụng | Tích hợp hệ sinh thái Google, tài liệu phong phú, đơn giản để bắt đầu; chức năng toàn diện (MFA, hàm chặn, v.v.), phù hợp cho phát triển nhanh. Nhưng liên kết với nền tảng Firebase, mở rộng sang dịch vụ khác cần cấu hình bổ sung. | +| Auth0 (Okta) | Nền tảng xác thực danh tính được quản lý hoàn toàn, hỗ trợ đăng nhập xã hội, SSO doanh nghiệp, xác thực đa yếu tố, mở rộng quy tắc, v.v. | Gói miễn phí 25k MAU, trả phí tính theo MAU | Chức năng cấp doanh nghiệp toàn diện (RBAC, nhật ký kiểm toán, v.v.), phù hợp cho ứng dụng vừa và lớn; giao diện thân thiện. Nhược điểm là chi phí cao khi MAU tăng, phiên miễn phí có chức năng hạn chế (như không bao gồm MFA/RBAC). Độ知名度 trong cộng đồng cao, người dùng đông đảo. | +| AWS Cognito | Dịch vụ xác thực gốc của Amazon Cloud, hỗ trợ đăng nhập xã hội và SAML liên hợp. User Pool đăng nhập trực tiếp cung cấp miễn phí 10k MAU mỗi tháng, vượt quá tính phí 0.0055 USD/MAU. | Miễn phí 10k MAU/tháng, vượt quá trả phí theo lượng | Tích hợp sâu với hệ sinh thái AWS (có thể phối hợp liền mạch với API Gateway, Lambda, v.v.), rào cản vào cửa hơi cao, tài liệu khá phức tạp; hạn mức miễn phí hạn chế, phù hợp cho đội ngũ đã có thói quen sử dụng AWS. | +| Logto | Nền tảng xác thực danh tính mã nguồn mở, phiên bản tự lưu trữ miễn phí, gói dịch vụ đám mây miễn phí 50k MAU. Hỗ trợ đa ngôn ngữ, đa tenant, OAuth/OIDC, v.v. | Phiên bản cộng đồng miễn phí; Logto Cloud miễn phí 50k MAU | Giải pháp thay thế mã nguồn mở Auth0 phổ biến gần đây, GitHub đã có 10k+ Stars. Dễ mở rộng, tự lưu trữ giảm chi phí; nhược điểm là hệ sinh thái và tài liệu còn tương đối mới, quy mô cộng đồng kém hơn Firebase/Auth0. | +| Keycloak | Giải pháp IAM/SSO mã nguồn mở nổi tiếng, hỗ trợ tên người dùng/mật khẩu, LDAP, SAML, OAuth2, v.v. | Hoàn toàn miễn phí, cần tự lưu trữ | Chức năng mạnh mẽ, có thể mở rộng (hỗ trợ kiểm soát quyền chi tiết), chức năng cấp doanh nghiệp phong phú; nhưng độ phức tạp triển khai và bảo trì cao, đường cong học tập dốc đối với đội ngũ nhỏ. Nhược điểm là yêu cầu cao về container hóa và vận hành cụm. | + +## Lưu trữ tệp (Storage) + +| Nền tảng/Dịch vụ | Loại | Hạn mức miễn phí/Định giá | Đặc điểm/Kịch bản áp dụng | +| --- | --- | --- | --- | +| Amazon S3 | Lưu trữ đối tượng đám mây (AWS) | Gói miễn phí AWS cung cấp 5GB lưu trữ, 20k yêu cầu GET/PUT/tháng, vượt quá trả phí theo lượng sử dụng | Lưu trữ đối tượng tiêu chuẩn ngành, độ tin cậy cao, triển khai đa khu vực toàn cầu. Chức năng toàn diện, tích hợp tốt với hệ sinh thái AWS; định giá khá phức tạp, người dùng mới cần tìm hiểu quy tắc tính phí. | +| Google Cloud Storage (Firebase Storage) | Lưu trữ đối tượng đám mây (Google) | Gói Firebase Spark cung cấp hạn mức miễn phí (1GB lưu trữ + giới hạn băng thông), Blaze trả phí | Tích hợp chặt chẽ với Firebase/Google Cloud, dễ quản lý; hỗ trợ tăng tốc CDN, quy tắc bảo mật chi tiết. | +| Tencent Cloud COS / Alibaba Cloud OSS | Lưu trữ đối tượng đám mây (trong nước) | Trả phí theo lượng (mỗi nền tảng có hạn mức tặng người dùng mới, như OSS có 40GB miễn phí năm đầu, v.v.) | Hướng đến thị trường nội địa, lưu trữ đối tượng hiệu suất cao, quy mô lớn; tích hợp với hệ sinh thái đám mây Trung Quốc, tài liệu khá hoàn thiện. Alibaba OSS chức năng toàn diện, tăng tốc toàn cầu; Qiniu KODO tập trung xử lý đa phương tiện, chi phí thấp, phù hợp cho cá nhân và đội ngũ nhỏ. | +| MinIO | Lưu trữ tương thích S3 mã nguồn mở | Mã nguồn mở miễn phí (tự xây dựng) | Nhẹ, hiệu suất cao, tương thích với API S3, phù hợp để xây dựng lưu trữ đối tượng trên đám mây riêng hoặc cục bộ. Tài liệu và cộng đồng hoạt động; cần tự bảo trì cơ sở hạ tầng. | +| Cloudinary / Imgix, v.v. | Lưu trữ phương tiện + CDN | Gói miễn phí cơ bản (như Cloudinary miễn phí 25GB/tháng băng thông) | Dịch vụ lưu trữ đám mây + CDN được tối ưu cho hình ảnh/video, cung cấp các chức năng nâng cao như chuyển mã thời gian thực, nén, v.v. Phù hợp cho dự án phương tiện, nhưng chức năng khá chuyên biệt, chi phí cao nếu sử dụng làm lưu trữ tệp thông dụng. | + +## Hàm Edge (Edge Functions) + +| Nền tảng/Dịch vụ | Đặc điểm | Hạn mức miễn phí/Định giá | Kịch bản áp dụng và Ưu nhược điểm | +| --- | --- | --- | --- | +| Cloudflare Workers | Môi trường JavaScript/Wasmtime phân tán toàn cầu | Gói miễn phí: 100k yêu cầu mỗi ngày; gói tiêu chuẩn $5/tháng bao gồm 10 triệu yêu cầu | Chạy trên các nút edge của Cloudflare, độ trễ cực thấp; phù hợp cho logic phân phối toàn cầu, hiển thị tài nguyên tĩnh, v.v. Hạn mức miễn phí ít (tương đương khoảng 3 triệu yêu cầu mỗi tháng), dễ tiếp cận. Nhược điểm là giới hạn runtime (JS/Wasmtime) và công cụ gỡ lỗi hạn chế. | +| Vercel Edge Functions | Tích hợp liền mạch với Next.js/framework front-end, hỗ trợ JS/TS/Go | Hobby miễn phí: 1 triệu lệnh gọi hàm mỗi tháng, 1 triệu yêu cầu edge | Tích hợp sâu framework front-end, triển khai tự động; phù hợp cho ứng dụng Web hiện đại. Hạn mức miễn phí dồi dào, runtime mặc định 10s, có thể nâng lên 60s. Nhược điểm là phiên miễn phí hạn chế chức năng cộng tác nhóm; phụ thuộc nền tảng Vercel. | +| Netlify Edge / Functions | Hàm đám mây Node.js + định tuyến edge (NFT) | Miễn phí: 300 token/tháng (tương đương khoảng 1M yêu cầu mỗi tháng); tính phí theo điểm tín dụng | Hỗ trợ hàm Node.js, xử lý định tuyến edge, v.v. Hạn mức miễn phí dùng cho xây dựng, hàm và băng thông, phù hợp cho triển khai toàn ngăn xếp front-end. Ưu điểm là dễ sử dụng, tích hợp triển khai Git; nhược điểm là cần tính toán hạn mức miễn phí (10k yêu cầu = 3 điểm). | +| AWS Lambda@Edge / CloudFront Functions | Tính toán edge không máy chủ của AWS | AWS Lambda (1M yêu cầu miễn phí/tháng + 400k GB-s) + CloudFront $0.085/mỗi 100k lệnh gọi trở lên | Tích hợp với CloudFront, có thể thực thi mã ở edge. Phù hợp khi cần hệ sinh thái AWS (như làm quyền hoặc kiểm thử A/B ở cấp nút). Ưu điểm là linh hoạt và mạnh mẽ; nhược điểm là cấu hình phức tạp, độ trễ hơi cao hơn Cloudflare/Vercel. | + +## Giao tiếp thời gian thực (Realtime) + +| Nền tảng/Dịch vụ | Đặc điểm chức năng | Hạn mức miễn phí/Định giá | Kịch bản áp dụng và Ưu nhược điểm | +| --- | --- | --- | --- | +| Firebase Realtime Database / Firestore | Cơ sở dữ liệu thời gian thực BaaS của Google; hỗ trợ đẩy thông báo thay đổi dữ liệu | Spark miễn phí: Realtime Database 1GB lưu trữ & hạn mức; Blaze tính phí theo lượng | Tích hợp mạnh hệ sinh thái Firebase, lắng nghe thời gian thực đơn giản. Ưu điểm là bắt đầu nhanh với gói miễn phí; nhược điểm là loại cơ sở dữ liệu (JSON/NoSQL), khả năng truy vấn phức tạp yếu. | +| Ably | Nền tảng tin nhắn thời gian thực và pub/sub, hỗ trợ WebSocket, MQTT, v.v. | Gói miễn phí: 6.000.000 tin nhắn mỗi tháng | Dịch vụ tin nhắn thời gian thực toàn diện, hỗ trợ đồng thời cao; hạn mức miễn phí có thể đạt 6 triệu tin nhắn/tháng. Cộng đồng và tài liệu tốt, phù hợp cho phân phối toàn cầu. | +| Pusher Channels | Dịch vụ đẩy sự kiện, hỗ trợ cơ chế kênh/sự kiện | Sandbox miễn phí: 200k tin nhắn mỗi ngày, 100 kết nối đồng thời | Dịch vụ WebSocket dễ sử dụng, tài liệu đầy đủ, phù hợp để nhanh chóng thực hiện chức năng chat và thông báo. Phiên miễn phí giới hạn lượng tin nhắn và số kết nối; sau khi trả phí khả năng mở rộng tốt. | +| Tự xây dựng WebSocket/Socket.IO | Tự xây dựng máy chủ (Node.js, Elixir hoặc Go, v.v.) | Chi phí tự lưu trữ (như phí máy chủ) | Mức độ linh hoạt cao nhất, có thể tùy chỉnh giao thức và cấu trúc liên kết theo nhu cầu. Phù hợp cho đội ngũ kiểm soát chi phí nghiêm ngặt và kỹ thuật trưởng thành. Nhược điểm là cần tự xử lý tính sẵn sàng, mở rộng và các vấn đề cross-origin, v.v. | + +## Cơ sở dữ liệu + +| Nền tảng/Công cụ | Loại cơ sở dữ liệu | Hạn mức miễn phí/Định giá | Đặc điểm chính | +| --- | --- | --- | --- | +| Neon (Serverless PostgreSQL) | Quan hệ (PostgreSQL) | Gói miễn phí: 0.5GB lưu trữ, nhánh chính trực tuyến vĩnh viễn, 20h tính toán nhánh/tháng | Postgres không máy chủ gốc đám mây, hỗ trợ tự động mở rộng và phân nhánh (fork thử nghiệm). Hạn mức miễn phí đủ cho dự án nhỏ, phù hợp cho quy trình phát triển hiện đại. Chức năng phân nhánh mạnh mẽ, nhưng hạn mức miễn phí khá nhỏ. | +| Aiven PostgreSQL | Quan hệ (PostgreSQL/MySQL) | Gói miễn phí: 1GB lưu trữ, 1 vCPU, 1GB bộ nhớ | Dịch vụ cơ sở dữ liệu được quản lý, hỗ trợ di chuyển đa vùng đa đám mây. Cung cấp MySQL, Redis, v.v. có thể chọn. Hạn mức miễn phí phù hợp cho phát triển và dự án nhỏ; phiên bản thương mại hỗ trợ cụm tính sẵn sàng cao và giám sát. | +| CockroachDB Cloud | SQL phân tán (Tương thích PostgreSQL) | Gói miễn phí: 10GB lưu trữ | Cơ sở dữ liệu SQL phân tán tương tự Google Spanner, tự động phân mảnh mở rộng. 10GB miễn phí khá hào phóng; phù hợp cho ứng dụng cần mở rộng ngang và tính nhất quán cao. Phiên bản thương mại SLA cao. | +| TiDB Cloud | Quan hệ phân tán (Tương thích MySQL) | Gói miễn phí: 5GB mỗi nút, tổng cộng tối đa 25GB | Phiên bản đám mây của TiDB mã nguồn mở, tương thích giao thức MySQL, kiến trúc phân tán. Hạn mức miễn phí dồi dào, phù hợp cho đội ngũ quen MySQL, hiệu suất xuất sắc; nhược điểm là vận hành khá phức tạp (đối với kịch bản quy mô lớn). | +| MongoDB Atlas | Tài liệu (NoSQL MongoDB) | Cụm M0 miễn phí: 0.5GB lưu trữ | MongoDB trên đám mây, mô hình tài liệu linh hoạt, hỗ trợ truy vấn và chỉ mục phong phú. Cơ sở dữ liệu 0.5GB miễn phí phù hợp cho thử nghiệm và ứng dụng nhỏ; có thể mở rộng ngang theo nhu cầu. Đường cong học tập hơi cao hơn cơ sở dữ liệu quan hệ. | +| SQLPub | Đa cơ sở dữ liệu (MySQL, PostgreSQL, Redis, v.v.) | Gói miễn phí: 36.000 yêu cầu/giờ, 30 kết nối đồng thời, 500MB lưu trữ | Nền tảng cơ sở dữ liệu tất cả trong một, hỗ trợ nhiều loại cơ sở dữ liệu. Phiên bản miễn phí phù hợp cho học tập và dự án nhỏ; ưu điểm là hỗ trợ nhiều DB, nhược điểm là hạn mức lưu trữ nhỏ. | + +Các giải pháp thay thế trên đều có trọng tâm khác nhau: mã nguồn mở linh hoạt và kiểm soát được hơn (Keycloak, MinIO, Socket.IO, Neon, CockroachDB, v.v.), dịch vụ đám mây quản lý dễ tiếp cận hơn (Firebase, Auth0, Cloudflare, Vercel, Netlify, AWS, Aiven, MongoDB Atlas, v.v.). Khi lựa chọn có thể cân nhắc dựa trên nhu cầu dự án, ngăn xếp kỹ thuật đội ngũ, ngân sách và hệ sinh thái cộng đồng. Dự án cá nhân có thể ưu tiên sử dụng các dịch vụ có hạn mức miễn phí dồi dào, dễ tích hợp (như loạt Firebase, lưu trữ Qiniu, Cloudflare Workers, Neon, CockroachDB, v.v.), còn đối với nhu cầu cấp doanh nghiệp hoặc bảo mật cụ thể, có thể cân nhắc các giải pháp chức năng phong phú hơn nhưng tính phí cao hơn (Auth0, Alibaba/Tencent Cloud, AWS, TiDB/Aiven, v.v.). Bạn có thể liên tục thử nghiệm trong ứng dụng thực tế, cho đến khi chọn được thành phần công cụ phát triển backend phù hợp nhất. + +# Tổng kết + +Trong bài học hôm nay, chúng ta đã hệ thống học các khái niệm cơ bản về cơ sở dữ liệu, định nghĩa cốt lõi của Supabase và chi tiết thao tác của nó. Trong quá trình thực hành sau này, bạn có thể dựa trên kịch bản ứng dụng và nhu cầu thực tế của dự án, quay lại tham khảo tài liệu này bất cứ lúc nào. + +Xin hãy luôn ghi nhớ một nguyên tắc quan trọng: **Hoàn thành trước, hoàn thiện sau!** Không cần theo đuổi hoàn hảo ngay từ đầu, chúng ta hoàn toàn có thể thông qua lặp lại tối ưu hóa liên tục, từng bước tiến gần đến kết quả tốt hơn. Chúc bạn mọi việc thuận lợi trong thực hành dự án sau này! + +# 📚 Bài tập về nhà + +1. Phát triển một ứng dụng bao gồm hệ thống quản lý người dùng và cơ sở dữ liệu. Tốt nhất là bao gồm nhiều chức năng Supabase hơn (Realtime / cloud storage / Edge function). diff --git a/docs/vi-vn/stage-2/backend/git-workflow/index.md b/docs/vi-vn/stage-2/backend/git-workflow/index.md new file mode 100644 index 0000000..3ff7bd4 --- /dev/null +++ b/docs/vi-vn/stage-2/backend/git-workflow/index.md @@ -0,0 +1,261 @@ +# Học sử dụng Git và Github + +Trong các bài học trước, chúng ta đã học cách viết code bằng các công cụ vibe coding dựa trên Web. Mỗi cuộc trò chuyện sẽ tạo ra một phiên bản code mới. Nhưng hãy nghĩ về một vấn đề: nếu chúng ta muốn quay lại sửa đổi trước đó, có cách nào tiện lợi không? Có công cụ nào có thể ghi lại code của chúng ta ở các giai đoạn khác nhau, cho phép chúng ta chuyển đổi và sửa đổi giữa các phiên bản bất kỳ lúc nào không? + +Để đáp ứng nhu cầu này, phần mềm kiểm soát phiên bản đã ra đời. Trong bài viết này, chúng ta sẽ giới thiệu chương trình kiểm soát phiên bản nổi tiếng nhất — Git — và nền tảng lưu trữ code tốt nhất — GitHub. Chúng ta sẽ học cách sử dụng Git để quản lý code, cách lấy code của người khác từ GitHub, cách tải lên code của chính mình, và cách hợp tác với người khác trong các dự án lớn. + +Cho dù là theo dõi phiên bản dự án cá nhân, đồng bộ code trong hợp tác đội nhóm, hay đóng góp cho cộng đồng mã nguồn mở, Git và GitHub đều là công cụ không thể thiếu của developer hiện đại. Bằng cách làm chủ chúng, bạn sẽ có thể quản lý code hiệu quả hơn, tạo checkpoint theo cần, chuyển đổi tự do giữa các giai đoạn code khác nhau, và dễ dàng xử lý mọi thứ từ thay đổi file đơn lẻ đến phát triển dự án lớn — làm cho mỗi lần lặp code đều có thể kiểm soát và truy xuất nguồn gốc. + +> 💡 **Kiến thức tiên quyết** +> +> Trước khi học Git, bạn nên tìm hiểu các khái niệm sau: +> - [Terminal/Dòng lệnh là gì](/vi-vn/appendix/2-development-tools/command-line-shell) - Học cách sử dụng dòng lệnh để tương tác với máy tính +> - [Git là gì](/vi-vn/appendix/2-development-tools/git-version-control) - Hiểu các khái niệm cốt lõi của hệ thống kiểm soát phiên bản Git +> +> Bài viết này sẽ tập trung vào quy trình làm việc GitHub và thao tác thực tế, vui lòng tham khảo các liên kết phụ lục cho kiến thức cơ bản nói trên. + +# Bắt đầu nhanh với Git + +Trước khi bắt đầu sử dụng Git, hãy đảm bảo bạn đã đọc nội dung về [dòng lệnh](/vi-vn/appendix/2-development-tools/command-line-shell) và [cơ bản về Git](/vi-vn/appendix/2-development-tools/git-version-control) trong phần phụ lục. Bài viết này sẽ giả định bạn đã có kiến thức cơ bản này và trực tiếp hướng dẫn cách cài đặt, cấu hình Git và sử dụng GitHub để cộng tác. + +## Cách cài đặt Git + +Chúng ta sẽ giới thiệu ba phương pháp cài đặt Git trên các hệ điều hành máy tính khác nhau. Vui lòng làm theo hướng dẫn phù hợp với phiên bản hệ thống của bạn: + +### Windows + +1. Truy cập [Trang tải Git chính thức](https://git-scm.com/download/win) và tải về trình cài đặt phù hợp với hệ thống của bạn: [Gói cài đặt](https://github.com/git-for-windows/git/releases/download/v2.51.0.windows.1/Git-2.51.0-64-bit.exe). Theo mặc định, khuyến nghị sử dụng trình cài đặt x64. +2. Nhấp đúp vào trình cài đặt và làm theo hướng dẫn của thuật sĩ cài đặt: + ![](/zh-cn/stage-2/backend/git-workflow/images/image5.png) + 1. Khuyến nghị giữ các tùy chọn mặc định. Nếu bạn cần tùy chỉnh, lưu ý các điểm sau: (Trong hầu hết trường hợp, bạn có thể nhấp "Next" liên tục) + - Chọn trình soạn thảo mặc định Git sử dụng: Chọn trình soạn thảo bạn thích (như VS Code). Bạn có thể chọn tùy chọn đầu tiên theo mặc định, tức là Vim (một trình soạn thảo văn bản), hoặc chọn tùy chọn "Visual Studio Code as Git's default editor" (cần cài đặt VS Code trước). Bạn có thể giữ lựa chọn mặc định và nhấp "Next" để tiếp tục. + ![](/zh-cn/stage-2/backend/git-workflow/images/image6.png) + - Chọn cách sử dụng Git: Ba tùy chọn này kiểm soát khả năng truy cập của Git trong hệ thống. Khuyến nghị chọn tùy chọn 2 ("from command line and 3rd-party software") — nó thêm các công cụ Git cơ bản vào PATH, cho phép bạn sử dụng Git trong Git Bash, Command Prompt, PowerShell và IDE mà không làm rối hệ thống. + ![](/zh-cn/stage-2/backend/git-workflow/images/image7.png) + +3. Sau khi cài đặt, nhấp chuột phải trên màn hình. Nếu bạn thấy "Git Bash Here" trong menu, cài đặt đã thành công. + +![](/zh-cn/stage-2/backend/git-workflow/images/image8.png) + +### MacOS + +Đối với macOS, bạn có thể nhập `git --version` trong terminal để kiểm tra xem Git đã được cài đặt chưa. Nếu chưa, hệ thống sẽ nhắc bạn cài đặt — chỉ cần làm theo hướng dẫn để hoàn tất cài đặt. + +1. Phương pháp 1: Cài đặt qua Homebrew + Nếu bạn đã cài đặt [Homebrew](https://brew.sh/) (trình quản lý gói Mac), hãy mở terminal và nhập + ```bash + brew install git + ``` +2. Phương pháp 2: (Khuyến nghị) Cài đặt qua Xcode: https://developer.apple.com/xcode/, Xcode đã tích hợp sẵn Git. Sau khi cài đặt, chỉ cần làm theo hướng dẫn để tiếp tục. + +### Linux + +Hầu hết các bản phân phối Linux có thể cài đặt Git thông qua trình quản lý gói: + +- Ubuntu/Debian: + +```bash +sudo apt update +sudo apt install git +``` + +- CentOS/RHEL: + +```bash +sudo yum install git +``` + +- Xác minh cài đặt: Nhập git --version trong terminal. Nếu hiển thị số phiên bản, cài đặt đã thành công. + +## Khởi tạo Git + +Sau khi cài đặt Git, đầu tiên bạn cần cấu hình thông tin người dùng — đây là bước cơ bản khi sử dụng Git để kiểm soát phiên bản. Thực hiện các lệnh sau trong terminal (thay thế nội dung trong ngoặc bằng thông tin của bạn): + +```bash +# Đặt tên người dùng toàn cục (sẽ hiển thị trong bản ghi commit) +git config --global user.name "Your Name" + +# Đặt email toàn cục (khuyến nghị sử dụng email đã đăng ký trên GitHub/GitLab) +git config --global user.email "your.email@example.com" +``` + +Git sẽ nhúng thông tin này vào mỗi bản ghi commit, làm "thông tin tác giả" cho mỗi lần sửa đổi. Khi xem lịch sử phiên bản (ví dụ: sử dụng git log), bạn có thể thấy rõ ai đã sửa đổi mỗi dòng code, thuận tiện cho việc truy trách nhiệm và giao tiếp. Trong dự án cộng tác, thông tin danh tính thống nhất giúp thành viên nhóm nhanh chóng nhận diện ai đã thực hiện thay đổi nào, từ đó nâng cao hiệu quả cộng tác (ví dụ: tìm developer liên quan thông qua bản ghi commit để thảo luận vấn đề). + +Bạn có thể nhập `git config --list` trong dòng lệnh để xem thông tin cấu hình Git hiện tại và xác nhận cài đặt thành công. + +# GitHub là gì + +GitHub là một nền tảng lưu trữ code dựa trên Git. Nó không chỉ cung cấp lưu trữ từ xa cho các kho lưu trữ Git mà còn bao gồm các công cụ cộng tác (như Issues, Pull Requests, Projects), giúp developer dễ dàng chia sẻ code và hợp tác hơn. Nói một cách đơn giản, Git là công cụ kiểm soát phiên bản cục bộ, còn GitHub là "đĩa cloud kho code + cộng đồng cộng tác" từ xa. + +GitHub không chỉ là nền tảng lưu trữ code lớn nhất thế giới mà còn là cộng đồng mã nguồn mở năng động và có sức ảnh hưởng nhất toàn cầu. Ý tưởng cốt lõi của "mã nguồn mở" ở đây là bất kỳ ai cũng có thể tải xuống và chạy mã nguồn của phần mềm. Mô hình này cho phép mọi người trên thế giới kiểm tra code của nhau và thực hiện sửa đổi, hoặc tạo dự án mới dựa trên đó. Ví dụ: bạn có thể tìm thấy nhiều hướng dẫn học tập cũng như mã nguồn hoàn chỉnh của framework huấn luyện mô hình GPT (như PyTorch) trên GitHub. Mỗi ngày, vô số người trên toàn thế giới cộng tác kiểm tra và cải thiện code. + +![](/zh-cn/stage-2/backend/git-workflow/images/image9.png) + +Nhiều công ty lớn mở mã nguồn chương trình hoặc hướng dẫn của họ trên GitHub để đạt lợi thế cạnh tranh trong ngành — điều này cũng có thể xem là một hình thức quảng cáo. Trong cộng đồng GitHub, số "ngôi sao (stars)" mà dự án nhận được là thước đo chính về giá trị của dự án; dự án hoặc tổ chức càng có nhiều sao thì uy tín và sức ảnh hưởng càng lớn. + +![](/zh-cn/stage-2/backend/git-workflow/images/image10.png) + +Trong khóa học của chúng ta, tài nguyên hỗ trợ và bài tập cũng sẽ được tải lên kho lưu trữ GitHub chuyên dụng. Thông qua quá trình tải lên bài tập, bạn sẽ dần làm quen và nắm vững việc sử dụng GitHub, tạo nền tảng vững chắc cho việc kiểm soát phiên bản trong phát triển ứng dụng tương lai. + +## Đăng ký tài khoản GitHub + +1. Truy cập [Trang chủ GitHub](https://github.com/) và nhấp "Sign up" ở góc trên bên phải. + ![](/zh-cn/stage-2/backend/git-workflow/images/image11.png) +2. Nhập địa chỉ email của bạn (khuyến nghị sử dụng email thường xuyên sử dụng, vì xác minh và thông báo sẽ được gửi đến đó), đặt mật khẩu (phải bao gồm chữ cái, số và ký tự đặc biệt). +3. Hoàn thành xác minh con người, xác minh email theo hướng dẫn, tài khoản của bạn đã được tạo. + +## Tạo kho lưu trữ đầu tiên trên GitHub + +Tiếp theo, chúng ta sẽ tạo thư mục lưu trữ đầu tiên, còn được gọi là kho lưu trữ hoặc "repo". + +![](/zh-cn/stage-2/backend/git-workflow/images/image12.png)![](/zh-cn/stage-2/backend/git-workflow/images/image13.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image14.png) + +1. Repository name: Tên kho lưu trữ hiển thị cho người khác. +2. Description: Mô tả chi tiết về kho lưu trữ. +3. Choose visibility: Đối với kho cá nhân, nếu đặt là private, chỉ bạn và những người được mời đặc biệt mới có thể xem. Nếu đặt là public, tất cả mọi người đều có thể xem. + Đối với kho trong tổ chức, nếu là Private, chỉ người trong tổ chức mới có thể xem. + Nếu là Public, người ngoài tổ chức cũng có thể xem. +4. README: Thông thường, mỗi kho đều nên có file README. Bạn có thể coi nó như bản giới thiệu đầy đủ về kho, bao gồm hướng dẫn sử dụng, danh sách file và cách thao tác. +5. Add .gitignore and license: + 1. File .gitignore báo cho Git biết bỏ qua một số thư mục hoặc file nhất định khi tải lên GitHub, do đó chúng sẽ không được theo dõi hoặc thêm vào staging area. Điều này rất hữu ích cho các file kiểm thử tạm thời, gói dependency hoặc file lớn. Khi đã chỉ định, các file này sẽ không còn được theo dõi. + 2. license là loại giấy phép mã nguồn mở bạn chọn. Các giấy phép khác nhau quy định chi tiết việc người khác có thể sử dụng code của bạn cho mục đích thương mại hay không, cùng với các điều khoản và điều kiện khác. + +Khuyến nghị tích "Add README", đặt khả năng hiển thị kho là "Private", điền tên kho và mô tả theo sở thích của bạn, sau đó nhấp "Create repository" để hoàn tất việc tạo kho lưu trữ từ xa đầu tiên. + +![](/zh-cn/stage-2/backend/git-workflow/images/image15.png) + +Sau đó, bạn sẽ có một kho sạch không có file bổ sung nào. Tiếp theo bạn có thể bắt đầu tải file lên. + +![](/zh-cn/stage-2/backend/git-workflow/images/image16.png) + +Lệnh để lấy kho là `git clone`, nhưng nó cần địa chỉ kho. Bạn có thể tìm địa chỉ kho bằng cách nhấp nút "Code" màu xanh lá, bạn sẽ thấy các tùy chọn HTTPS và SSH. Thông thường, bạn có thể sử dụng bất kỳ phương pháp nào trong hai phương pháp này để tải kho về máy cục bộ (chỉ có như vậy bạn mới có thể sửa đổi và tải file lên). + +![](/zh-cn/stage-2/backend/git-workflow/images/image17.png) + +Nói chung, kho được clone qua HTTP phù hợp để tải xuống và kiểm thử tạm thời kho của người khác, nhưng không khuyến nghị cho phát triển cá nhân. Để có trải nghiệm học tập tốt hơn, bạn nên thiết lập xác thực SSH trước. + +## Liên kết SSH cục bộ + +Trong GitHub, "liên kết giao thức SSH" về bản chất là việc liên kết SSH public key của thiết bị cục bộ với tài khoản GitHub của bạn, cho phép GitHub nhận diện thiết bị của bạn thông qua giao thức SSH. Điều này cho phép bạn vận hành kho lưu trữ từ xa một cách an toàn mà không cần mật khẩu (như clone, push hoặc pull code). + +Nói đơn giản: Điều này giống như cấp cho thiết bị của bạn một "thẻ kiểm soát truy cập GitHub chuyên dụng". Sau khi liên kết, khi thiết bị của bạn truy cập kho GitHub thông qua giao thức SSH, GitHub sẽ xác minh "thẻ kiểm soát truy cập" (SSH public key của bạn). Khi đã xác nhận là thiết bị được ủy quyền, bạn có thể trực tiếp vận hành — không cần nhập tài khoản và mật khẩu mỗi lần. + +> 💡 SSH là gì + +### Tại sao cần liên kết giao thức SSH? + +GitHub hỗ trợ hai giao thức vận hành kho chính: giao thức HTTPS và giao thức SSH: + +- Giao thức HTTPS: Mỗi thao tác (như push) đều cần nhập tài khoản và mật khẩu GitHub (hoặc Personal Access Token PAT). Quá trình xác minh phức tạp và có rủi ro rò rỉ mật khẩu. +- Giao thức SSH: Xác thực được hoàn thành thông qua "cặp khóa", do đó không cần nhập mật khẩu lặp lại, và truyền tải được mã hóa an toàn hơn. + +"Liên kết giao thức SSH" là bước tiên quyết để kích hoạt xác thực SSH GitHub — chỉ khi liên kết SSH public key cục bộ với tài khoản GitHub, GitHub mới có thể nhận diện thiết bị của bạn và cho phép vận hành SSH trên kho. + +### Logic cốt lõi của "liên kết": Vai trò của cặp khóa SSH + +Xác thực SSH dựa vào cặp khóa (public key + private key), chúng là các file mã hóa khớp nhau. Sau khi tạo, bạn cần cung cấp "public key" cho GitHub ("liên kết"), và giữ "private key" trên thiết bị cục bộ: + +1. Private key: Được lưu trữ trong thư mục được chỉ định (thường là ~/.ssh/) trên thiết bị cục bộ (như máy tính), đóng vai trò là "chìa khóa chuyên dụng của bạn", tuyệt đối không chia sẻ với bất kỳ ai. +2. Public key: Đây là một "ổ khóa" có thể chia sẻ công khai — bạn cần sao chép nó vào danh sách "SSH keys" của tài khoản GitHub (thao tác "liên kết"). + +Khi bạn vận hành kho GitHub thông qua SSH (ví dụ: git push git@github.com:xxx/xxx.git): + +- Thiết bị cục bộ của bạn sử dụng private key để mã hóa "yêu cầu vận hành" và gửi đến GitHub; +- Sau khi nhận yêu cầu, GitHub cố gắng giải mã bằng public key bạn đã liên kết trước đó; +- Nếu giải mã thành công, thiết bị của bạn được xác nhận là đã ủy quyền, thao tác được cho phép; nếu không, truy cập bị từ chối. + +### Các bước cụ thể của "liên kết" (Quy trình cốt lõi) + +Khi bạn đã hiểu nguyên lý, thao tác thực tế rất đơn giản — cốt lõi là "tạo cặp khóa → tải public key lên GitHub": + +1. Tạo cặp khóa SSH cục bộ + 1. Sử dụng Trae để lấy public key (khuyến nghị) + Prompt: `Help me create the SSH key needed for GitHub login. My email is your_email@gmail.com , Please return the public key for me to copy` + + ![](/zh-cn/stage-2/backend/git-workflow/images/image18.png) + + Sau khi nhập prompt, bạn cũng cần nhấn Enter trong terminal bên trái, nếu không lệnh sẽ tiếp tục chờ mà không thực thi. Vì Trae không thể giúp bạn thực hiện bất kỳ điều kiện phán đoán nào, chúng ta chỉ cần nhấn Enter liên tục. + + Cuối cùng, bạn sẽ thấy Trae ở bên phải trả về public key mà nó đã đọc. Bạn chỉ cần sao chép nó và chuẩn bị dán trong bước tiếp theo. + + ![](/zh-cn/stage-2/backend/git-workflow/images/image19.png) 2. Lấy public key thủ công + Mở terminal cục bộ của bạn (trên Windows sử dụng Git Bash hoặc PowerShell; trên macOS/Linux sử dụng Terminal), nhập lệnh sau (thay your_email@example.com bằng email bạn đã đăng ký tài khoản GitHub): + + ```bash + ssh-keygen -t ed25519 -C "your_email@example.com" + ``` + + 1. Nhấn Enter để chấp nhận mặc định (đường dẫn file mặc định, không có passphrase, hoặc đặt passphrase theo cần). Điều này sẽ tạo hai file trong thư mục ~/.ssh/: + - id_ed25519: Private key (lưu cục bộ, **tuyệt đối không chia sẻ**); + - id_ed25519.pub: Public key (cần tải lên GitHub). + +2. "Liên kết" public key với tài khoản GitHub + +Đây là bước liên kết cốt lõi — thêm public key cục bộ vào danh sách "SSH keys" của tài khoản GitHub: + +1. Sao chép nội dung public key: + 1. Trae: + 2. Windows: Mở C:\Users\\.ssh\id_ed25519.pub bằng Notepad và sao chép toàn bộ nội dung; + 3. macOS/Linux: Chạy cat ~/.ssh/id_ed25519.pub trong terminal và sao chép toàn bộ đầu ra (từ phần đầu SSH-ed25519 đến email ở cuối). +2. Đăng nhập GitHub và vào trang "SSH Key Management": + 1. Nhấp vào avatar góc trên bên phải → Settings → Menu bên trái SSH and GPG keys → Nhấp New SSH key. + ![](/zh-cn/stage-2/backend/git-workflow/images/image20.png)![](/zh-cn/stage-2/backend/git-workflow/images/image21.png) + 2. Nhập bất kỳ tiêu đề nào (ví dụ: SSH của máy tính cục bộ của bạn), sau đó dán SSH public key bạn vừa lấy vào đây. + +![](/zh-cn/stage-2/backend/git-workflow/images/image22.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image23.png) + +3. Xác minh liên kết thành công + +Nhập lệnh sau trong terminal (**Trae cũng có thể thực hiện các thao tác sau**) để kiểm tra xem GitHub có thể nhận diện thiết bị của bạn hay không: + +```bash +ssh -T git@github.com +``` + +- Nếu bạn thấy nội dung tương tự như Hi [tên người dùng GitHub của bạn]! You've successfully authenticated..., điều đó có nghĩa là bạn đã liên kết khóa thành công; +- Nếu gặp lỗi, thường là do public key sao chép không đầy đủ, quyền private key quá cao (thư mục ~/.ssh/ cục bộ của bạn chỉ nên cho phép bạn đọc và ghi). Hãy kiểm tra các vấn đề này theo cần. + +### Lưu ý quan trọng + +Nếu bạn có nhiều thiết bị (như laptop và máy bàn), bạn cần tạo cặp khóa SSH riêng cho mỗi thiết bị và liên kết mỗi public key với cùng một tài khoản GitHub — mỗi thiết bị có "thẻ kiểm soát truy cập" riêng. + +Tuyệt đối không chia sẻ private key của bạn (không tải lên GitHub hoặc chia sẻ với người khác), nếu không ai đó có thể mạo danh bạn vận hành kho của bạn. Nếu private key bị rò rỉ, hãy xóa ngay public key tương ứng khỏi GitHub và tạo cặp khóa mới. + +Sau khi liên kết SSH, sử dụng địa chỉ kho định dạng SSH (ví dụ: git@github.com:username/repository.git) để vận hành, thay vì định dạng HTTPS (ví dụ: https://github.com/username/repository.git). Nếu bạn đã clone kho bằng HTTPS trước đó, có thể dùng git remote set-url origin `` để chuyển đổi giao thức. + +# Sử dụng Trae để thao tác GitHub + +Chúng ta đã giải thích Git là gì, GitHub là gì, SSH là gì và cách cấu hình nó. Bây giờ bạn có thể tự do sử dụng Trae để thực hiện các thao tác Git. Đầu tiên, hãy học cách clone kho lưu trữ từ xa về máy cục bộ. + +## Git clone: Tải xuống kho hiện có + +Bạn có thể trực tiếp cho nó biết địa chỉ kho bạn muốn clone + +![](/zh-cn/stage-2/backend/git-workflow/images/image24.png) + +## Git pull: Lấy cập nhật từ kho từ xa + +Trước khi cập nhật kho mỗi lần, vì nó có thể được bảo trì bởi nhiều người, bạn cần pull các thay đổi mới nhất trước. Sau đó, bạn có thể sửa đổi và push file. + +**Nhớ bao gồm tên thư mục và đường dẫn tương đối hoặc tuyệt đối của nó, để tránh push sai kho.** + +prompt:`Help me pull this repository AIID-TEST in ./AIID-TEST.` + +## Git commit & Git push: Tạm lưu cập nhật và push lên GitHub + +Khi mọi thứ đã sẵn sàng, bạn có thể thử sửa đổi file cục bộ, thêm hoặc xóa các mục trong thư mục. Sau đó, để Trae phát hiện các thay đổi và giúp bạn push lên GitHub. + +prompt:`I finished. Commit and push to the repository AIID-TEST in ./AIID-TEST.` + +![](/zh-cn/stage-2/backend/git-workflow/images/image25.png) + +Push thành công. Bây giờ bạn có thể xem nội dung đã cập nhật trên GitHub. + +# Tài liệu tham khảo + +- Pro Git book https://git-scm.com/book/en/v2 +- GitHub Docs https://docs.github.com/en diff --git a/docs/vi-vn/stage-2/backend/modern-cli/index.md b/docs/vi-vn/stage-2/backend/modern-cli/index.md new file mode 100644 index 0000000..0f12436 --- /dev/null +++ b/docs/vi-vn/stage-2/backend/modern-cli/index.md @@ -0,0 +1,801 @@ +# Công cụ lập trình AI CLI + +Trong hướng dẫn này, chúng tôi sẽ giới thiệu các Agent lập trình AI chạy trực tiếp trong dòng lệnh. Khác với Agent trong Trae, Cursor mà bạn đã học, công cụ lập trình AI CLI chỉ có thể sử dụng trong terminal. So với Agent tích hợp trong AI IDE, chúng thường có cửa sổ ngữ cảnh dài hơn, tốc độ gọi công cụ nhanh hơn, và có thể tương thích với nhiều loại mô hình lớn hơn. Trong thực chiến AI Vibe Coding mới nhất, chúng ta thường ưu tiên sử dụng công cụ lập trình AI CLI, thay vì Agent mã hóa tích hợp trong IDE. + +## Từ CLI nói đến + +Bạn còn nhớ CLI mà chúng tôi đã giới thiệu trước đó không? CLI là cách thao tác phần mềm ứng dụng bằng lệnh văn bản thuần túy thông qua terminal hoặc dấu nhắc lệnh, thay vì phụ thuộc vào giao diện đồ họa (GUI -- bạn có thể hiểu đơn giản là giao diện có nút bấm trên máy tính hoặc điện thoại, có thể thao tác bằng cách nhấp, không cần nhập lệnh). + +> Trên Windows, các terminal phổ biến bao gồm "Command Prompt (cmd)" và "PowerShell". Bạn có thể nhập "cmd" hoặc "powershell" trong hộp chạy/tìm kiếm trên máy tính để khởi động các chương trình dòng lệnh này. + +![](/zh-cn/stage-2/backend/modern-cli/images/image1.png)![](/zh-cn/stage-2/backend/modern-cli/images/image2.png) + +CLI thiên về thao tác lệnh văn bản, trong một nhóm nhỏ những người đam mê lập trình theo đuổi sự hoàn hảo (geek), CLI thậm chí còn phổ biến hơn GUI -- họ hy vọng tất cả thao tác đều hoàn thành qua bàn phím, thấy việc dùng chuột lại làm chậm hiệu suất lập trình của mình. + +Trong ngành công nghiệp, CLI thường cũng là hình thức giao diện phổ biến nhất, vì GUI cần hệ điều hành vẽ giao diện bổ sung, quản lý cửa sổ, yêu cầu tài nguyên máy tính cao hơn; còn CLI chỉ cần truyền lệnh nhận được cho hệ thống thực thi. Do đó, khi kết nối cụm máy chủ quy mô lớn, chúng ta thường chỉ tương tác qua CLI. + +![](/zh-cn/stage-2/backend/modern-cli/images/image3.png) + +Đối với nhiều bạn chưa có kinh nghiệm CLI, có thể thấy thao tác CLI rất phức tạp, lệnh quá nhiều, thậm chí lo ngại "một lần vô tình làm hỏng máy". Đừng lo. Còn nhớ trong hướng dẫn trước, chúng ta thường để Trae giúp hoàn thành các thao tác cơ bản không? Ở đây cũng có thể áp dụng hoàn toàn cách suy nghĩ này -- chúng ta có thể để công cụ lập trình CLI giúp chúng ta thực hiện tất cả thao tác CLI: để nó giúp bạn vào thư mục chỉ định, tìm kiếm và xử lý tệp, chạy hoặc sao chép dự án mã nguồn mở, v.v. Toàn bộ quá trình đều có thể hoàn thành thông qua hội thoại với công cụ lập trình AI CLI. + +## Khác gì với AI IDE + +Chúng ta có thể ví công cụ lập trình AI CLI như z.ai và Trae đã học trước đó. Theo một nghĩa nào đó, công cụ lập trình AI CLI có thể được coi là một z.ai đặc biệt: chúng cũng chỉ cần một cổng hội thoại đơn giản, sẽ tự động thực hiện tất cả thao tác cần thiết cho bạn (chỉ đôi khi bạn cần tự mở trình duyệt để xem kết quả cuối cùng). Còn nếu ví với AI IDE, thì công cụ lập trình AI CLI có thể được coi là module Agent trong IDE -- tức là vùng hội thoại ở thanh bên. + +![](/zh-cn/stage-2/backend/modern-cli/images/image4.png)![](/zh-cn/stage-2/backend/modern-cli/images/image5.png) + +Tuy nhiên, do các AI IDE khác nhau có cách triển khai Agent khác nhau, năng lực cũng khác nhau đáng kể, hiệu quả lập trình AI thường không ổn định, do đó công cụ lập trình AI CLI thường được phát triển trực tiếp bởi các công ty công nghệ lớn, ví dụ Anthropic đứng sau Claude, OpenAI đứng sau ChatGPT, v.v. + +So với các Agent lập trình AI khác, việc trực tiếp sử dụng các sản phẩm từ các nhà sản xuất lớn thường là thực tiễn tốt hơn, đặc biệt Claude Code bản thân là công cụ phục vụ đội ngũ phát triển nội bộ của Anthropic, ngay từ đầu đã được thiết kế xoay quanh "đáp ứng nhu cầu thực sự của kỹ sư". + +Để so sánh trực quan hơn, chúng ta có thể xem đơn giản sự khác biệt giữa Claude Code và Agent của một AI IDE (ở đây lấy Cursor làm ví dụ): + +| Tính năng | Claude Code | Cursor | Bên ưu thế hơn | +| ----------------- | ------------- | --------------- | ----------- | +| Thực thi tác vụ tự động | Rất mạnh | Khả năng hạn chế | Claude Code | +| Tích hợp IDE | Chỉ dòng lệnh | VS Code gốc | Cursor | +| Tự động hoàn thành mã theo thời gian thực | Không | Trải nghiệm tuyệt vời | Cursor | +| Thao tác đa tệp | Rất mạnh | Khá tốt | Claude Code | +| Thao tác GitHub tích hợp | Có thể commit trực tiếp | Cần thao tác thủ công | Claude Code | +| Chi phí học tập | Trung bình | Dễ bắt đầu | Cursor | +| Độ dài ngữ cảnh | Rất dài | Khá tốt | Claude Code | +| Hỗ trợ gỡ lỗi | Tự động hóa | Nhiều cần thủ công | Claude Code | + +Nguồn bảng: + +Nói đơn giản, công cụ lập trình AI CLI thường có thể: + +- Hỗ trợ hội thoại liên tục lâu hơn (thậm chí có thể giúp bạn "làm việc cả ngày"). +- Cung cấp cửa sổ ngữ cảnh dài hơn (không còn thường xuyên cần bạn nói "tiếp tục"). +- Phản hồi nhanh hơn (có thể kết nối nhiều API mô hình tùy chỉnh hơn). + +Về các thao tác liên quan đến lập trình, chúng thường thông minh hơn, ổn định hơn so với phần lớn Agent tích hợp trong IDE. + +## Các công cụ lập trình AI CLI phổ biến + +Hiện tại tuy có nhiều triển khai mã nguồn mở, nhưng trong thực tiễn chúng tôi chỉ giới thiệu hai loại công cụ lập trình AI CLI chính, làm "tổ hợp ưu tiên". Bạn có thể chọn bất kỳ một trong hai theo thói quen của mình, khuyến nghị mạnh mẽ nên thử cả hai, sau đó chọn ra cái phù hợp nhất với bạn. + +- Codex sử dụng GPT-5, mạnh hơn về năng lực tổng thể; +- Claude Code thông qua API chuyển tiếp GLM 4.6, trải nghiệm tổng thể gần Claude 4, nhưng giá rẻ hơn. +- OpenCode có thể tự do chuyển đổi và kết hợp mô hình, cung cấp mô hình miễn phí, có thể kiểm soát chi phí tốt hơn. + +Tuy nhiên, cái nào tốt hơn trong dự án thực tế chỉ có thể đánh giá thông qua thử nghiệm cá nhân. Việc nắm vững nhiều công cụ lập trình AI luôn có lợi: sau khi thành thạo, bạn có thể linh hoạt chuyển đổi giữa Claude Code, Codex hoặc Trae trong các kịch bản khác nhau. Nếu thử nhiều lần phát hiện công cụ nào hiệu quả chung, có thể trực tiếp đổi công cụ hoặc mô hình khác tiếp tục thử nghiệm. + +Đồng thời, do phiên bản mô hình cập nhật rất nhanh, khuyến nghị bạn ưu tiên chọn phương án thể hiện tốt nhất về "tỷ lệ giá (hiệu quả / chi phí)". + +### Claude Code + +Claude Code là công cụ lập trình AI do Anthropic phát triển dựa trên khả năng mô hình Claude lớn. Kịch bản tương tác chính của nó nằm ở terminal, đồng thời cũng hỗ trợ sử dụng như plugin VS Code. Tương tự như Agent trong AI IDE, nó có thể hiểu sâu kho mã của nhà phát triển, và hoàn thành tác vụ phát triển đầu-cuối thông qua lệnh ngôn ngữ tự nhiên -- bao gồm chỉnh sửa mã, sửa Bug, thực thi và sửa kiểm thử, quản lý quy trình làm việc Git (ví dụ giải quyết xung đột gộp, tạo PR), giải thích mã phức tạp, thực thi lệnh terminal, v.v. + +![](/zh-cn/stage-2/backend/modern-cli/images/image6.png) + +Ưu điểm chính của Claude Code thể hiện ở: cửa sổ ngữ cảnh cực dài (có thể xử lý tệp hoàn chỉnh thậm chí dự án nhỏ), có thể chủ động làm rõ nhu cầu mơ hồ, tự động lập kế hoạch và phân phối tác vụ thực thi, cũng như khả năng hiểu và giải thích sâu toàn bộ nội dung kho mã. So với Agent IDE thông thường, nó phù hợp hơn với quy trình phát triển "vibe coding nhập môn". + +Trong thực tế sử dụng, bạn có thể thông qua lệnh hội thoại, để nó giúp bạn tạo dự án mới, thực hiện thao tác CLI (ví dụ sắp xếp thư mục, đổi tên tệp hàng loạt, triển khai dự án mã nguồn mở, v.v.), cấu hình môi trường phát triển (ví dụ cài đặt và gỡ lỗi môi trường Python). Nếu thấy đoạn mã nào khó hiểu, cấu trúc thư mục nào không rõ ràng, cũng có thể trực tiếp để Claude Code tạo tài liệu phân tích có cấu trúc, hoặc giải thích từng bước nội dung cụ thể. + +![](/zh-cn/stage-2/backend/modern-cli/images/image7.png)![](/zh-cn/stage-2/backend/modern-cli/images/image8.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image9.png)![](/zh-cn/stage-2/backend/modern-cli/images/image10.png) + +Nếu bạn muốn học Claude Code một cách hệ thống, có thể tham khảo khóa học do Andrew Ng và Anthropic cùng phát triển: + + +Tiếp theo, chúng ta sẽ học cách sử dụng Claude Code. Do việc sử dụng trực tiếp Claude Code chính thức thường tốn kém rất cao (như hình dưới), chúng ta sẽ chuyển sang sử dụng nền tảng API dựa trên các mô hình lớn khác nhưng tương thích với giao thức Claude Code. + +![](/zh-cn/stage-2/backend/modern-cli/images/image11.png) + +Bạn cần học một số phương án khác nhau dưới đây (tốt nhất nên thử tất cả), cuối cùng chọn phương án phù hợp nhất với bạn làm lộ trình thực hành chính. + +Cách đầu tiên là sử dụng trực tiếp API "tương thích giao diện Anthropic". Với sự phổ biến của Claude Code, ngày càng nhiều nhà cung cấp mô hình lớn bắt đầu hỗ trợ cách gọi phong cách Anthropic. Các nhà cung cấp phổ biến bao gồm GLM, Kimi, DeepSeek và Siliconflow, v.v., đều cung cấp giao diện API tương thích. Về cấu hình cụ thể, chúng tôi sẽ nói chi tiết ở phần sau. + +Cần lưu ý, Claude Code thường tiêu tốn rất nhiều token, nếu bạn lo ngại phí gọi API quá cao, có thể cân nhắc mua gói tháng của GLM (khoảng 20 tệ/tháng) để kiểm soát chi phí. Nếu muốn cảm nhận chi phí thực tế trước, cũng có thể nạp trước 10 tệ để thử nghiệm quy mô nhỏ. + +Một cách khác là sử dụng dự án "Claude Code Route". Đây là một công cụ mã nguồn mở, không chỉ hỗ trợ tất cả giao diện gọi API phổ biến, mà còn cho phép bạn cấu hình tinh chỉnh mô hình sử dụng cho các kịch bản khác nhau, và hỗ trợ kết nối với mô hình lớn triển khai cục bộ. Nhưng do cấu hình phương án này khá phức tạp, khuyến nghị bạn bắt đầu từ phương án đầu tiên. + +#### Sử dụng GLM Zhipu làm backend (khuyến nghị) + +GLM (General Language Model) là một loạt mô hình ngôn ngữ lớn do Zhipu AI tự nghiên cứu và phát triển. GLM-4.6 là phiên bản mới nhất của dòng GLM hiện tại, điểm nổi bật cốt lõi là hiệu suất xuất sắc trong khả năng mã (đối sánh với Claude Sonnet 4 trong benchmark công khai và tác vụ thực tế, nằm ở top đầu trong nước). + +![](/zh-cn/stage-2/backend/modern-cli/images/image12.png) + +Nó còn mở rộng cửa sổ ngữ cảnh lên 200K, có thể xử lý văn bản dài và mã quy mô lớn thoải mái hơn, đồng thời tăng cường khả năng suy luận và gọi công cụ, đạt được cân bằng tốt giữa hiệu suất và chi phí. + +![](/zh-cn/stage-2/backend/modern-cli/images/image13.png) + +Trước khi kết nối GLM, chúng ta cần cài đặt Claude Code trước. + +Nếu bạn thấy các bước cài đặt dòng lệnh phiền phức, hoặc gặp lỗi giữa chừng, có thể trực tiếp để Agent của Trae giúp bạn hoàn thành cài đặt. + +```python +# Cài đặt Claude Code +npm install -g @anthropic-ai/claude-code + +# Vào dự án của bạn +cd your-awesome-project + +# Khởi động Claude Code +claude + +# Nhấn Ctrl+C để thoát Claude +``` + +Tiếp theo, chúng ta cần sửa địa chỉ yêu cầu API mặc định của Claude Code, để nó hỗ trợ dịch vụ API của GLM. Bạn có thể trực tiếp sao chép nội dung dưới đây, để Trae giúp bạn tạo biến môi trường tương ứng; hoặc chọn ghi vĩnh viễn vào biến môi trường hệ thống (nếu có vấn đề, cũng có thể để Agent giúp sửa). + +Đầu tiên, bạn cần lấy API Key của GLM, và lưu bằng cách bạn thấy tiện nhất. + +Địa chỉ phiên bản trong nước: +Địa chỉ phiên bản quốc tế: + +Nếu bạn sử dụng **phiên bản GLM trong nước**, vui lòng sử dụng cấu hình biến sau: + +```python +# Chạy lệnh sau trong Cmd +# Lưu ý thay `your_zhipu_api_key` bằng API Key bạn vừa lấy +setx ANTHROPIC_AUTH_TOKEN your_zhipu_api_key +setx ANTHROPIC_BASE_URL https://open.bigmodel.cn/api/anthropic +``` + +Nếu bạn sử dụng **phiên bản GLM quốc tế**, vui lòng sử dụng cấu hình dưới đây: + +```python +# Chạy lệnh sau trong Cmd +# Cũng lưu ý thay `your_zai_api_key` +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic +``` + +Bạn có thể nhập prompt tương tự như sau trực tiếp trong Trae: + +⚠️ Nếu bạn cấu hình "biến môi trường vĩnh viễn" thông qua Trae, sau khi cấu hình xong **bắt buộc phải khởi động lại Trae**, nếu không biến môi trường trong terminal tích hợp của nó sẽ không cập nhật, có thể dẫn đến đăng nhập thất bại hoặc lỗi kết nối mạng. + +```python +Based on my environment variable settings: +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic + +and my key(Replace it with your own key): +681fea485851d29060cc.13gfaendggaFOhb + +please help me configure and start Claude Code +``` + +Bạn sẽ thấy đầu ra quy trình tương tự như dưới: + +![](/zh-cn/stage-2/backend/modern-cli/images/image14.png) + +> 💡 Biến môi trường là gì? +> +> Biến môi trường về bản chất là một tập thông tin cấu hình "cặp key-giá trị" được lưu trữ trong hệ điều hành, thường tồn tại dưới dạng "tên biến = giá trị cụ thể". Miễn là cấu hình trước trong terminal hoặc cài đặt hệ thống, chương trình có thể đọc các biến này bất cứ lúc nào để lấy thông tin liên quan. Do biến môi trường có thể ghi trực tiếp trong terminal mà không cần sửa mã, chúng ta thường lưu key truy cập mô hình lớn trong biến môi trường để tránh rò rỉ. Chương trình chỉ cần đọc biến môi trường tương ứng để hoàn thành gọi mô hình lớn. +> +> Trong hệ thống Windows, ngoài việc dùng để lưu key truy cập mô hình lớn, biến môi trường còn thường dùng để lưu "đường dẫn gọi" của công cụ dòng lệnh. +> +> Chúng ta biết terminal bản thân cũng là một chương trình. Đôi khi chúng ta muốn khởi động một chương trình bên ngoài trong terminal, ví dụ nhập `claude` trong terminal để khởi động Claude Code. Lý do có thể nhập trực tiếp `claude` để chạy là vì terminal sẽ đọc biến môi trường hệ thống, trong đó biến PATH chứa thư mục nơi chứa tệp thực thi của Claude Code, nên terminal có thể tìm và thực thi nó (tương đương với việc dán đường dẫn tuyệt đối của chương trình đó vào terminal rồi nhấn Enter). +> +> Một biến môi trường điển hình có thể trông như: `PATH=C:\Windows\system32;C:\Program Files\Python`. Như vậy chúng ta có thể thực thi các chương trình này trong hệ thống ở bất kỳ đường dẫn nào, ví dụ trực tiếp gõ `python` trong dòng lệnh để khởi động trình thông dịch Python. +> +> Nếu bạn muốn xem biến môi trường hiện tại của hệ thống, có thể nhập "biến môi trường" trong tìm kiếm Windows, trong cửa sổ "Chỉnh sửa biến môi trường hệ thống" sẽ thấy tất cả các biến và giá trị của chúng. Có biến dùng để lưu key mô hình lớn, có biến dùng để thêm thư mục chương trình, tiện gọi tại bất kỳ đường dẫn nào. + +Bây giờ, bạn có thể sử dụng GLM mới nhất để phát triển với Claude Code. Bạn có thể thử chạy lại một dự án đã làm trước đó, hoặc thử lại những tác vụ mà Trae chưa hoàn thành tốt, so sánh sự khác biệt trong trải nghiệm. + +🎉 Việc "bắt đầu lại từ đầu" lặp đi lặp lại không phải lãng phí thời gian -- mỗi lần bạn làm lại, kỹ năng sẽ vững thêm một bậc. + +Với cùng cách tiếp cận như GLM, bạn cũng có thể dễ dàng kết nối các giao diện tương thích định dạng Anthropic khác. + +#### Sử dụng Kimi K2 làm backend (khuyến nghị) + +Kimi K2 là mô hình ngôn ngữ lớn thế hệ mới do Moonshot AI ra mắt, thể hiện xuất sắc trong khả năng hiểu và tạo mã. Kimi K2 hỗ trợ cửa sổ ngữ cảnh siêu dài (tối đa 200K tokens), có thể dễ dàng xử lý kho mã lớn và dự án phức tạp. + +**Ưu điểm cốt lõi:** + +- **Ngữ cảnh siêu dài**: Hỗ trợ cửa sổ ngữ cảnh 200K, có thể xử lý toàn bộ mã dự án cùng lúc +- **Khả năng mã mạnh**: Thể hiện xuất sắc trong tạo mã, tái cấu trúc và gỡ lỗi +- **Hiểu tiếng Trung tốt**: Hiểu chính xác hơn nhu cầu lập trình tiếng Trung +- **Gọi công cụ ổn định**: Hỗ trợ gọi hàm và sử dụng công cụ ổn định + +**Lấy API Key:** + +Truy cập đăng ký và lấy API Key. + +**Phương pháp cấu hình:** + +Tài liệu tham khảo: + +```bash +export ANTHROPIC_BASE_URL=https://api.moonshot.cn/anthropic +export ANTHROPIC_AUTH_TOKEN=sk-YOURKEY +``` + +#### Sử dụng Minimax làm backend (khuyến nghị) + +Minimax là mô hình ngôn ngữ lớn thế hệ mới do MiniMax (Xi Yu Ke Ji) ra mắt, thể hiện xuất sắc trong tác vụ lập trình. Mô hình Minimax nổi tiếng với khả năng suy luận xuất sắc và chất lượng tạo mã, đặc biệt phù hợp với các kịch bản lập trình phức tạp. + +**Ưu điểm cốt lõi:** + +- **Khả năng suy luận mạnh**: Thể hiện xuất sắc trong suy luận logic phức tạp và thiết kế kiến trúc mã +- **Chất lượng mã cao**: Mã tạo ra có cấu trúc rõ ràng, khả năng đọc tốt +- **Hỗ trợ đa ngôn ngữ**: Hỗ trợ tạo và chuyển đổi mã bằng nhiều ngôn ngữ lập trình +- **Tốc độ phản hồi nhanh**: Tốc độ phản hồi API nhanh, phù hợp kịch bản gọi tần suất cao + +**Lấy API Key:** + +Truy cập đăng ký và lấy API Key. + +**Phương pháp cấu hình:** + +```bash +export ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_MINIMAX_API_KEY +export ANTHROPIC_MODEL=MiniMax-M2.7 +``` + +#### Sử dụng DeepSeek làm backend (khuyến nghị) + +DeepSeek là mô hình ngôn ngữ lớn mã nguồn mở do DeepSeek ra mắt, được nhà phát triển yêu thích nhờ khả năng mã xuất sắc và tỷ lệ giá cao. DeepSeek Coder được tối ưu hóa và huấn luyện đặc biệt cho các tác vụ lập trình. + +**Ưu điểm cốt lõi:** + +- **Khả năng mã nổi bật**: Thể hiện xuất sắc trong tạo mã, hiểu mã và sửa Bug +- **Mã nguồn mở có thể tùy chỉnh**: Mô hình mã nguồn mở, có thể tinh chỉnh theo nhu cầu +- **Tỷ lệ giá cao**: Giá API tương đối thấp, phù hợp sử dụng tần suất cao +- **Hỗ trợ tiếng Trung tốt**: Hiểu chính xác kịch bản lập trình tiếng Trung + +**Lấy API Key:** + +Truy cập đăng ký và lấy API Key. + +**Phương pháp cấu hình:** + +```bash +export ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic +export ANTHROPIC_AUTH_TOKEN=YOU_DEEPSEEK_API_KEY +export API_TIMEOUT_MS=600000 +export ANTHROPIC_MODEL=deepseek-chat +export ANTHROPIC_SMALL_FAST_MODEL=deepseek-chat +export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 +``` + +#### Sử dụng Volcano Engine Coding Plan làm backend (khuyến nghị) + +Volcano Engine là nền tảng dịch vụ đám mây dưới trướng ByteDance, cung cấp dịch vụ mô hình AI cấp doanh nghiệp. Coding Plan của Volcano Engine được tối ưu hóa đặc biệt cho kịch bản lập trình, cung cấp khả năng tạo mã ổn định và hiệu quả. + +**Ưu điểm cốt lõi:** + +- **Ổn định cấp doanh nghiệp**: Cung cấp SLA, đảm bảo tính ổn định của dịch vụ +- **Tối ưu hóa kịch bản mã**: Được tối ưu hóa đặc biệt cho tác vụ lập trình +- **Lựa chọn mô hình phong phú**: Hỗ trợ nhiều mô hình, bao gồm Doubao-pro, Doubao-lite, v.v. +- **Truy cập nhanh trong nước**: Triển khai nút trong nước, tốc độ truy cập nhanh + +**Lấy API Key:** + +Truy cập đăng ký và lấy API Key. + +**Phương pháp cấu hình:** + +```bash +export ANTHROPIC_BASE_URL=https://ark.volces.com/api/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_VOLCANO_API_KEY +export ANTHROPIC_MODEL=doubao-pro-32k +``` + +#### Các API tương thích Anthropic khác + +Siliconflow: + +```bash +export ANTHROPIC_BASE_URL="https://api.siliconflow.cn/" +export ANTHROPIC_MODEL="moonshotai/Kimi-K2-Instruct-0905" # Có thể tự sửa mô hình cần sử dụng +export ANTHROPIC_API_KEY="YOUR_SILICONCLOUD_API_KEY" # Vui lòng thay API Key +``` + +Aliyun DashScope (Aliyuncs): + +```python +export ANTHROPIC_BASE_URL="https://dashscope.aliyuncs.com/apps/anthropic" +export ANTHROPIC_API_KEY="YOUR_DASHSCOPE_API_KEY" +``` + +::: details Sử dụng Claude Code Route làm backend (cách dùng nâng cao) + +Ở trên chúng tôi đã giải thích cách sử dụng API chính thức GLM để thay thế giao diện Anthropic của Claude Code. Tiếp theo, hãy xem công cụ Claude Code Router giúp Claude Code thích ứng với nhiều mô hình API hơn như thế nào. + +[Claude Code Router](https://github.com/musistudio/claude-code-router) là công cụ tăng cường định tuyến thông minh được thiết kế riêng cho Claude Code. Vai trò cốt lõi của nó là giúp người dùng phân phối yêu cầu AI đến các mô hình trên các nền tảng khác nhau theo nhu cầu, và có thể tùy chỉnh cao. Nó hỗ trợ kết nối hàng chục nền tảng, bao gồm OpenRouter, DeepSeek, Ollama, Gemini, v.v., cũng có thể định tuyến tác vụ đến mô hình cụ thể theo kịch bản, như GLM-4.5, Kimi-K2, Qwen3-Coder, v.v. Ví dụ, bạn có thể tự động giao tác vụ nền cho Ollama cục bộ để tiết kiệm chi phí; giao tác vụ văn bản dài/mã dài cho Gemini-2.5-Pro; giao giải thích mã cho DeepSeek. + +![](/zh-cn/stage-2/backend/modern-cli/images/image16.png) + +Công cụ này còn cung cấp khả năng quản lý cấu hình UI/CLI thuận tiện, và thông qua "bộ chuyển đổi (converter)" thích ứng định dạng API của các nền tảng khác nhau. Nó hỗ trợ tích hợp tự động như GitHub Actions và mở rộng tùy chỉnh, giải quyết vấn đề "một mô hình không thể bao phủ tất cả kịch bản" và "chuyển đổi nền tảng thường xuyên rất phiền", giúp người dùng sử dụng công cụ AI linh hoạt và tiết kiệm hơn. + +![](/zh-cn/stage-2/backend/modern-cli/images/image17.png) + +Dưới đây chúng tôi giới thiệu đơn giản cách cài đặt Claude Code Router. Khoảng cần các bước sau (cũng có thể để Trae giúp bạn thực thi), để chuẩn bị môi trường liên quan: + +```markdown +npm install -g @anthropic-ai/claude-code +npm install -g @musistudio/claude-code-router +``` + +Sau khi cài đặt, bạn cần xác nhận cục bộ có thể sử dụng lệnh `ccr`. Nếu thấy đầu ra tương tự như dưới, tức là cài đặt thành công: + +![](/zh-cn/stage-2/backend/modern-cli/images/image18.png) + +Tiếp theo, có hai cách để khởi tạo và cấu hình mô hình: + +- Sử dụng UI tích hợp của CCR, mở trang cấu hình nó cung cấp trong trình duyệt để thao tác; +- Trực tiếp sửa tệp cấu hình mặc định của CCR (về bản chất UI cũng đang sửa tệp cấu hình, chỉ cung cấp giao diện trực quan hơn). + +Nếu chọn sử dụng CCR UI, bạn sẽ thấy giao diện tương tự như dưới: + +![](/zh-cn/stage-2/backend/modern-cli/images/image19.png) + +Lúc này nhấp vào nút "Add Provider", sẽ thấy giao diện như dưới. Bạn cần: + +1. Nhập tên nhà cung cấp mô hình trong Name; +2. Nhập địa chỉ giao diện OpenAI tương thích của nhà cung cấp đó trong API Full URL; +3. Nhập API Key của nền tảng tương ứng trong API Key; +4. Nhập tên mô hình trong vùng Models, nhấp "Add Model" để thêm; +5. Cuối cùng nhấp "Save" để lưu cấu hình. + +(Cuộn xuống giao diện còn nhiều tùy chọn nâng cao, nhưng hiện tại bạn có thể bỏ qua trước.) + +![](/zh-cn/stage-2/backend/modern-cli/images/image20.png) + +Dưới đây là ví dụ cấu hình DeepSeek và Kimi: + +![](/zh-cn/stage-2/backend/modern-cli/images/image21.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image22.png) + +Sau khi lưu cấu hình mô hình, còn cần chỉ định mô hình mặc định (Default) trong vùng Router bên phải. Nhấp vào dropdown tương ứng, đặt thành `kimi` (khuyến nghị), sau đó nhấp `Save and Restart` ở góc phải phía trên. + +![](/zh-cn/stage-2/backend/modern-cli/images/image23.png) + +Sau đó, chỉ cần nhập `ccr code` trong terminal, là có thể khởi động quy trình lập trình Claude Code thông qua Claude Code Router. + +![](/zh-cn/stage-2/backend/modern-cli/images/image24.png) + +::: + +#### Cách dùng nâng cao của Claude Code + +Nhiều người khi mới bắt đầu sử dụng Claude Code chỉ dùng nó như công cụ hội thoại thông thường. Nhưng thực tế, nó tích hợp nhiều khả năng phong phú, giúp bạn sử dụng hiệu quả và linh hoạt hơn. Dưới đây là một số lệnh và cách dùng phổ biến: + +Tài liệu tham khảo: + + + + +| Lệnh | Vai trò | Ví dụ | +| ----------------- | ----------------------------------------- | ---------------------------------------- | +| claude | Khởi động chế độ tương tác | `claude` | +| claude "query" | Thực thi tác vụ một lần và xuất kết quả | `claude "explain this project"` | +| claude -p "query" | Thực thi câu hỏi một lần và tự động thoát sau khi kết thúc | `claude -p "explain this function xxxx"` | +| claude -c | Tiếp tục phiên gần nhất | `claude -c` | +| claude -r | Khôi phục phiên trước | `claude -r` | +| /resume | Chuyển về phiên trước trong cuộc trò chuyện hiện tại | `claude -c`, `/resume` | +| /plugin | Quản lý plugin, có thể cài đặt mở rộng năng lực commit và xem xét | `/plugin` | +| /init | Khởi tạo mô tả dự án với CLAUDE.md | `/init` | +| /clear | Xóa ngữ cảnh phiên hiện tại, tránh quá tải thông tin | `/clear` | +| /compact | Nén lịch sử phiên, giảm chiếm dụng token ngữ cảnh | `/compact` | +| /cost | Xem chi tiêu hiện tại | `/cost` | +| /model | Chuyển đổi mô hình sử dụng (khi dùng API tương thích thường có thể bỏ qua) | `/model` | +| /memory | Quản lý tệp nhớ CLAUDE.md | | +| /help | Hiển thị danh sách lệnh có sẵn | `/help` | +| exit or Ctrl+C | Thoát Claude Code | `exit` hoặc `Ctrl+C` | +| /agents | Chức năng nâng cao, sẽ giải thích ở phần sau | | +| /mcp | Chức năng nâng cao, sẽ giải thích ở phần sau | | + +**CLAUDE.md** + +Tham khảo: + +`CLAUDE.md` là tệp đặc biệt mà Claude sẽ tự động đọc và thêm vào ngữ cảnh khi bắt đầu hội thoại. Do đó, nó rất phù hợp để ghi lại: + +- Các lệnh bash thường dùng +- Các tệp và hàm công cụ cốt lõi +- Quy ước phong cách mã +- Mô tả cách kiểm thử +- Quy ước hợp tác kho (ví dụ quy tắc đặt tên nhánh, dùng merge hay rebase, v.v.) +- Mô tả cấu hình môi trường phát triển (ví dụ có dùng pyenv không, khuyến nghị trình biên dịch nào, v.v.) +- Các điểm cần đặc biệt lưu ý trong dự án hoặc dễ gặp lỗi +- Bất kỳ thông tin nào bạn muốn Claude "nhớ" + +`CLAUDE.md` bản thân không có yêu cầu định dạng bắt buộc, miễn là ngắn gọn, dễ đọc cho con người. Ví dụ: + +``` +# Bash commands +- npm run build: Build the project +- npm run typecheck: Run the typechecker + +# Code style +- Use ES modules (import/export) syntax, not CommonJS (require) +- Destructure imports when possible (eg. import { foo } from 'bar') + +# Workflow +- Be sure to typecheck when you're done making a series of code changes +- Prefer running single tests, and not the whole test suite, for performance +``` + +#### Nguyên lý hoạt động nội bộ của Claude Code + +Tham khảo: + +Nếu bạn tò mò tại sao Claude Code hữu dụng hơn các công cụ Agent lập trình như Trae hoặc Cursor trong nhiều kịch bản, chúng ta có thể xem đơn giản cơ chế hoạt động nội bộ của nó. + +Các công cụ lập trình AI CLI khác cũng có cách triển khai tổng thể tương tự. + +![](/zh-cn/stage-2/backend/modern-cli/images/image25.png) + +Claude Code sẽ phân giải tác vụ lập trình thành một vòng lặp "cảm nhận--suy nghĩ--hành động--xác minh" liên tục, và trong đó gọi các công cụ khác nhau để hoàn thành tác vụ. Nó mô phỏng quy trình làm việc của nhà phát triển: liên tục "viết mã -> chạy -> xem kết quả -> cải tiến". Hệ thống nội bộ liên tục thực hiện các bước thông qua vòng lặp tác vụ chính, trong mỗi vòng, Claude đều có thể gọi các công cụ khác nhau -- ví dụ đọc ghi tệp, thực thi lệnh, tìm kiếm mã, v.v. -- sau đó dựa trên kết quả thực tế trả về từ công cụ để quyết định hành động tiếp theo. + +Trong đó có một số đặc tính chính đáng chú ý: + +- **Xử lý luồng (Stream Processing)**: Claude có thể vừa suy nghĩ vừa xuất kết quả, thay vì phải đợi tất cả mã viết xong mới thực thi. +- **Nén thông minh (Intelligent Compression)**: Hội thoại dài dễ dẫn đến ngữ cảnh quá dài, Claude giảm xác suất "quên" bằng cách nén lịch sử thành thông tin chính, và đảm bảo vận hành hiệu quả thông qua việc phân biệt trí nhớ ngắn hạn và dài hạn. +- **Kiểm soát đồng thời (Concurrency Control)**: Thiết kế song song nội bộ cho phép nhiều tác vụ tiến hành đồng thời, không can thiệp lẫn nhau. +- **Quản lý Agent con (Sub-agent Management)**: Trong công việc thực tế không chỉ tương đương với một "vai trò" xử lý tất cả mọi việc, bạn có thể quản lý nhiều Agent con phối hợp xử lý mã, mỗi Agent chịu trách nhiệm các tác vụ khác nhau, ví dụ chuyên trách kiểm thử, chuyên trách viết tài liệu, v.v. + +### Codex + +![](/zh-cn/stage-2/backend/modern-cli/images/image26.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image27.png) + +Tương tự như Claude Code, Codex là công cụ lập trình AI do OpenAI phát triển, bạn có thể hiểu nó là "phiên bản OpenAI của Claude Code". Ưu điểm lớn nhất của nó là khả năng thích ứng hiệu quả với GPT-5. + +Từ trải nghiệm thực tế, GPT-5 hiện tại phản hồi nhanh hơn, tỷ lệ lỗi thấp hơn (xác suất hoàn thành đúng trong tác vụ phức tạp nhiều vòng cao hơn). Một nhược điểm của nó là giải thích thường thiên về "học thuật" và "kỹ thuật", đôi khi quá nghiêm ngặt, lượng thông tin lớn, đối với người mới bắt đầu có thể hơi khó hiểu. + +Bạn có thể cài đặt Codex thông qua lệnh dưới: + +``` +npm i -g @openai/codex +``` + +#### Sử dụng API chính thức OpenAI làm backend + +Nếu trực tiếp sử dụng cổng Codex chính thức của OpenAI, cấu hình sẽ rất đơn giản: sau khi bạn đã đăng ký gói đăng ký OpenAI hoặc được cấp hạn mức API tương ứng, chỉ cần nhập `codex` trong dòng lệnh để khởi động chương trình, và hoàn thành đăng nhập theo hướng dẫn. + +![](/zh-cn/stage-2/backend/modern-cli/images/image28.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image29.png) + +#### Sử dụng cách chuyển tiếp API OpenAI làm backend + +Do API OPENAI chính thức có thể có giá cao, yêu cầu mạng khắt khe và các vấn đề khác, để tránh các hạn chế này, chúng ta cũng có thể thông qua dịch vụ cổng API bên thứ ba khác để chuyển tiếp gọi. + +Với cách này, chúng ta chỉ cần mua hạn mức Codex API tương ứng trên nền tảng chuyển tiếp bên thứ ba, là có thể nhận được trải nghiệm sử dụng gần với OpenAI Codex gốc. + +Tham khảo: +Địa chỉ nạp tiền: + +Cần lưu ý, sau khi lấy token hạn mức, chúng ta còn cần cấu hình API Key cục bộ. + +Trong cài đặt nhóm key, cần lưu ý chọn mục chuyên dùng cho Codex. + +![](/zh-cn/stage-2/backend/modern-cli/images/image30.png) + +Tiếp theo, chúng ta cần điền Key đã lấy vào prompt dưới đây, và đưa toàn bộ prompt cho Trae, để nó giúp bạn hoàn thành toàn bộ quá trình cấu hình: + +````bash +My API key is: [Paste your obtained sk-xxxxx key here] + +Please help me complete the following configuration tasks: + +1. Create configuration directory + - Create a `.codex` folder under my user directory + - Windows path should be: `C:\Users\[My Username]\.codex` +2. Backup existing configuration (if exists) + - Check if `.codex\config.toml` exists + - If it exists, rename it to `config.toml.bak.[current timestamp]` (timestamp format: yyyyMMddHHmmss) +3. Create configuration file + - Create `config.toml` in the `.codex` directory + - Write the following complete content: + ```toml + preferred_auth_method = "apikey" + + [model_providers.myrelay] + name = "My Relay Station" + base_url = "https://api.zyai.online/v1" + env_key = "MYRELAY_API_KEY" + wire_api = "responses" + request_max_retries = 4 + stream_max_retries = 10 + stream_idle_timeout_ms = 300000 + + [profiles.myrelay] + model_provider = "myrelay" + model = "gpt-5" + model_reasoning_effort = "medium" + + [tools] + web_search = true + +4. Set system environment variable +Variable name: MYRELAY_API_KEY +Variable value: The key I gave you + +5. Confirm completion and report back: + +The full path of the configuration file +Whether the environment variable was set successfully +I can use the command `codex --profile myrelay` to run it +```` + +Sau khi cấu hình xong, bạn có thể khởi động Codex sử dụng API chuyển tiếp thông qua `codex --profile myrelay`. Cách sử dụng sau đó tương tự như Claude Code: chỉ cần nhập suy nghĩ và nhu cầu của bạn vào ô hội thoại bất kỳ lúc nào. + +### OpenCode + +![](/zh-cn/stage-2/backend/modern-cli/images/image32.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image33.png) + +OpenCode là một nền tảng AI Coding Agent mã nguồn mở dành cho nhà phát triển, định vị tương tự như "phiên bản Claude Code đa mô hình". Nó lấy Terminal làm cổng tương tác cốt lõi, đồng thời hỗ trợ tích hợp trình soạn thảo (như VS Code, Neovim, v.v.), có thể truy cập sâu kho mã cục bộ, và hoàn thành toàn bộ quy trình phát triển từ hiểu mã đến thực thi kỹ thuật thông qua ngôn ngữ tự nhiên. + +Nó không phải công cụ lập trình AI gắn với một mô hình duy nhất, mà là một nền tảng AI Coding Agent mở có thể tự do chuyển đổi GPT, Claude, Gemini và thậm chí mô hình cục bộ. Ngay cả OpenAI chính thức cũng hỗ trợ OpenCode kết nối Codex/OpenAI subscription. + +![](/zh-cn/stage-2/backend/modern-cli/images/image34.png) + +Bạn có thể cài đặt OpenCode thông qua lệnh dưới: + +```bash +# Linux / Unix +curl -fsSL https://opencode.ai/install | bash + +# Windows +npm i -g opencode-ai +``` + +#### Sử dụng mô hình miễn phí trong OpenCode + +Trong OpenCode thỉnh thoảng sẽ có mô hình miễn phí để sử dụng, cấu hình cũng rất đơn giản. Bạn có thể nhập `opencode` tại vị trí cần sử dụng OpenCode trong dòng lệnh để khởi động chương trình OpenCode vào bảng điều khiển trò chuyện. Nhập lệnh `/models` tìm kiếm từ khóa free là có thể thấy các mô hình miễn phí có chữ free. + +![](/zh-cn/stage-2/backend/modern-cli/images/image35.png) + +Thông thường mô hình miễn phí hoàn thành tác vụ lập trình sẽ chậm hơn so với mô hình trả phí/đăng ký, điều này thường phụ thuộc vào việc đường truyền mô hình có bị tắc nghẽn hay không, có phải giai đoạn cao điểm lập trình hay không và năng lực bản thân của mô hình. + +#### Sử dụng mô hình bên thứ ba làm mô hình lập trình chính của OpenCode + +Đây là ưu điểm cốt lõi của OpenCode, nó có thể cho phép bạn tự do chuyển đổi mô hình trong khi sử dụng cùng MCP, Skills, ngữ cảnh để hoàn thành các tác vụ lập trình khác nhau. Phần dưới lấy GPT-5.3 Codex chính thức của OpenAI làm ví dụ, kết nối OpenCode làm mô hình lập trình chính. + +Nhập lệnh `/connect` trong cửa sổ trò chuyện của OpenCode, chọn chỉ thị đầu tiên phù hợp nhất nhấn enter, là có thể tiến hành chọn xác thực ủy quyền nhà cung cấp mô hình bên thứ ba. + +![](/zh-cn/stage-2/backend/modern-cli/images/image36.png) + +Ở đây chọn OpenAI làm ví dụ, nhấn enter để chọn phương thức xác thực. + +![](/zh-cn/stage-2/backend/modern-cli/images/image37.png) + +Chọn loại nào cũng được, chỉ là phương thức xác thực khác nhau. Ở đây chọn loại đầu tiên để đăng nhập qua trình duyệt. + +![](/zh-cn/stage-2/backend/modern-cli/images/image38.png) + +Sao chép liên kết này vào trình duyệt để thực hiện đăng nhập OpenAI bình thường, sau khi trình duyệt hiển thị Authorization Successful, client OpenCode sẽ tự động chuyển đến giao diện chọn mô hình OpenAI. + +![](/zh-cn/stage-2/backend/modern-cli/images/image39.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image40.png) + +#### Cài đặt plugin Oh My OpenAgent + +Điểm mạnh của OpenCode còn nằm ở cộng đồng sinh thái rất năng động, bạn có thể tìm thấy rất nhiều plugin liên quan đến OpenCode trên Github. Nếu nói OpenCode là một công cụ lập trình AI có thể chuyển đổi mô hình tùy ý, thì Oh-My-OpenAgent là một "hệ thống chỉ huy lập trình AI đa Agent" chạy trên OpenCode. Nó có thể phân giải một tác vụ phức tạp thành nhiều sub-task giao cho các mô hình khác nhau, mỗi mô hình đảm nhận phần việc riêng. + +![](/zh-cn/stage-2/backend/modern-cli/images/image41.png) + +Bạn có thể sao chép đoạn văn bản dưới đây và dán cho mô hình đã cấu hình trong OpenCode để cài đặt OpenCode. + +```text +Install and configure oh-my-openagent by following the instructions here: +https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md +``` + +Dưới đây là các tính năng và mô tả chức năng của Oh-My-OpenAgent. + +| Tính năng | Mô tả chức năng | +| :-------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **Discipline Agents** | Sisyphus chịu trách nhiệm điều phối Hephaestus, Oracle, Librarian và Explore. Một đội phát triển AI hoàn chỉnh hoạt động song song. | +| **Team Mode** (v4.0, bật tùy chọn) | Leader Agent + tối đa 8 thành viên song song, trực quan hóa tmux thời gian thực, họ công cụ `team_*` chuyên dụng. Điều khiển `hyperplan`(5 người bình luận đối lập) và `security-research`(3 thợ săn + 2 kỹ sư PoC). [Tài liệu ->](docs/guide/team-mode.md) | +| **`ultrawork` / `ulw`** | Một chạm kích hoạt, tất cả agent xuất kích. Không bỏ cuộc cho đến khi tác vụ hoàn thành. | +| **[IntentGate](https://factory.ai/news/terminal-bench)** | Phân tích ý định thực sự của người dùng trước khi hành động thực sự. Tạm biệt vĩnh viễn lời vô nghĩa AI bị hiểu sai theo nghĩa đen. | +| **Công cụ chỉnh sửa dựa trên hash** | Mỗi lần sửa đều xác minh hash nội dung qua `LINE#ID`, tỷ lệ sửa sai 0%. Cảm hứng từ [oh-my-pi](https://github.com/can1357/oh-my-pi). [The Harness Problem ->](https://blog.can.ac/2026/02/12/the-harness-problem/) | +| **LSP + AST-Grep** | Đổi tên cấp workspace, chẩn đoán trước build, viết lại dựa trên AST. Cung cấp cho Agent độ chính xác cấp IDE. | +| **Agent nền** | Đồng thời phóng 5+ chuyên gia làm việc song song. Giữ ngữ cảnh sạch, lấy kết quả bất cứ lúc nào. | +| **MCP tích hợp** | Exa (tìm kiếm web), Context7 (tài liệu chính thức), Grep.app (tìm kiếm mã nguồn GitHub). Bật mặc định. | +| **Ralph Loop / `/ulw-loop`** | Vòng lặp tự tham chiếu. Không dừng lại cho đến khi đạt 100% hoàn thành. | +| **Thực thi Todo bắt buộc** | Agent muốn lười biếng? Hệ thống trực tiếp kéo cổ áo lôi về. Tác vụ của bạn, bắt buộc phải hoàn thành. | +| **Người kiểm tra comment** | Loại bỏ comment dư thừa có mùi AI mạnh. Mã viết ra như kỹ sư cao cấp lão luyện. | +| **Tích hợp Tmux** | Hỗ trợ terminal tương tác hoàn chỉnh. Chạy REPL, dùng debugger, dùng công cụ TUI, tất cả trong phiên thời gian thực. | +| **Tương thích Claude Code** | Hooks, lệnh, skills, MCP và plugin hiện có của bạn? Tất cả có thể di chuyển liền mạch. | +| **MCP nhúng trong Skills** | Skills tự mang MCP server cần thiết. Bật theo nhu cầu, không làm phồng cửa sổ ngữ cảnh của bạn. | +| **Prometheus Planner** | Lập kế hoạch chiến lược tốt trước khi viết mã, thông qua chế độ phỏng vấn. | +| **`/init-deep`** | Tự động tạo `AGENTS.md` trong toàn bộ cấp thư mục dự án. Không chỉ tiết kiệm Token, mà còn nâng cao đáng kể khả năng hiểu của Agent. | + +Sisyphus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) là chỉ huy chính của bạn. Nó chịu trách nhiệm lập kế hoạch, phân bổ tác vụ cho đội ngũ chuyên gia, và thúc đẩy tác vụ đến hoàn thành với chiến lược song song cực kỳ tích cực. Nó không bao giờ bỏ cuộc giữa chừng. + +Hephaestus (gpt-5.5) là người làm sâu tự chủ của bạn. Bạn chỉ cần đưa cho nó mục tiêu, không cần chỉ cách cụ thể. Nó sẽ tự động khám phá các pattern trong kho mã, thực thi tác vụ độc lập từ đầu đến cuối, tuyệt đối không cần bạn phải giám sát. Đúng như tên gọi, một người thợ thủ công thực thụ. + +Prometheus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) là nhà lập kế hoạch chiến lược của bạn. Thông qua chế độ phỏng vấn, trước khi viết một dòng mã nào, nó sẽ xác định phạm vi và xây dựng kế hoạch thực thi chi tiết thông qua việc đặt câu hỏi. + +Sau khi hiểu xong những điều này, bạn có thể sử dụng OpenCode đã cài đặt plugin Oh-My-OpenAgent để hoàn thành các tác vụ lập trình. + +## Thêm cách dùng công cụ lập trình AI CLI + +### Dùng AI viết tài liệu yêu cầu: Học "cụ thể hóa nhu cầu" + +Đối với mô hình ngôn ngữ lớn, nhu cầu trừu tượng cần được "cụ thể hóa". Ví dụ: "Tôi đói" là một nhu cầu trừu tượng, chúng ta cần biến nó thành: "Tôi hơi đói, có thể cần ăn một bánh mì đậu đỏ, thêm một ly sữa đậu nành." -- Đây mới là một nhu cầu cụ thể có thể thực thi. + +Nhưng biến nhu cầu trừu tượng thành cụ thể, thực ra là một quá trình rất tốn sức. Nếu chúng ta chưa thấy đủ nhiều ví dụ, rất khó nhanh chóng liên tưởng đến cách phân giải vấn đề trừu tượng thành các module chi tiết. Lúc này, cách tốt nhất là để AI giúp bạn hoàn thành bước "cụ thể hóa". +Ví dụ, tôi muốn phát triển một ứng dụng "kế hoạch hàng ngày", suy nghĩ đơn giản nhất có thể là: + +`Please help me write a daily planning app where I can write my plans each day and get reminders.` + +AI thực sự có thể phân giải tác vụ dựa trên nhu cầu này, rồi hoàn thành từng bước, nhưng dễ sai hoặc hiểu sai giữa chừng. Để giảm rủi ro, chúng ta có thể để AI giúp chúng ta mở rộng nhu cầu trước: + +`Based on my needs, please elaborate and provide a more detailed Product Requirement Document for reference. My idea is: Please help me write a daily planner app that supports daily plan-writing and provides reminders.` + +Lúc này, AI có thể đưa ra PRD hoàn chỉnh tương tự như dưới: + +``` +Product Requirements Document (PRD): "Today's Plan" App +Document Version: 1.0 +Creation Date: October 27, 2023 +Author: (Your Name/Product Manager) + +1. Product Introduction +1.1 Product Name +Today's Plan +1.2 Product Vision +"Today's Plan" is a minimalist and highly efficient daily planning and reminder tool, dedicated to helping users eliminate procrastination and forgetfulness, plan every day clearly, and ensure tasks are carried out through an intelligent reminder system—ultimately enabling users to gain a stronger sense of control and achievement over their time. +1.3 Target Users (User Personas) +We mainly serve three types of users: +Students (Xiao Ming): +Characteristics: Multiple tasks such as courses, assignments, club activities, exam prep, needing organized time arrangement. +Pain Points: Easily forget small tasks or assignment deadlines; feel overwhelmed switching between tasks; want to build regular study and life habits. +Needs: A simple tool to list daily to-dos and provide reminders before class/self-study. +Office Workers (Zhang Wei): +Characteristics: Fast-paced work, many meetings, reports, project milestones, and personal affairs (fitness, picking up children). +Pain Points: Easily forget important meetings or work milestones; get interrupted by urgent tasks and forget the original plan; feel busy but inefficient at end of day. +Needs: Need a tool to quickly record and schedule daily work and send strong reminders at key times (e.g., 15 minutes before meetings). +Freelancers/Self-disciplined Seekers (Li Na): +Characteristics: High freedom of time, but strong self-management required for work output and personal growth. +Pain Points: Easily procrastinate, lack external supervision; start the day without a clear plan, leading to low time utilization. +Needs: Need a tool to help build a daily fixed routine (Morning Routine) and review daily achievements for positive feedback. + +2. User Stories +As a user, I want to quickly create today's plan list so I have an overview of all my tasks for the day. +As a user, I want to set specific start and end times for each task so I can create a visual timeline. +As a user, I want to receive push notification reminders before a task starts so I won't miss any important arrangements. +As a user, I want to customize the reminder time (such as 5, 15, or 60 minutes in advance) so reminders better fit my habits. +As a user, I want to easily mark completed tasks so I can feel accomplished and clearly see my progress. +As a user, I want to see a summary of my completed plans at the end of each day for reviewing and self-motivation. +As a user, I want to conveniently edit and delete tasks to handle last-minute changes. +As a user, I want to view plans and achievements from previous days to review my efficiency and habits. + +3. Feature Breakdown +Core Features (MVP - Minimum Viable Product) +Module 1: Plan Management +3.1.1 Daily Plan Homepage +Interface: "Today" as the core view, current date shown at the top. +View: Timeline list, clearly showing tasks scheduled from morning to evening. Tasks without a time can be listed in the top or bottom "To-do List" section. +Interactions: +Click the "+" button in the bottom right to quickly create a new task. +Pull down to refresh the page. +Swipe left/right to view yesterday's and tomorrow's plans. +3.1.2 Create/Edit Task +Entry: Click "+" on the homepage or a time slot in the list. +Fields: +Task title (required): Briefly describe the task, e.g., "10 AM Weekly Product Meeting." +Task time (optional): +Set "start time" and "end time." +Provide "all-day" option for unspecified time tasks. +Default time picker should be quick and convenient. +Reminder setting (required, with default value): See Module 2. +Notes (optional): Add further descriptions, links, or location info. +Actions: Save, cancel, delete task. +3.1.3 Task Interaction +Mark as complete: Checkbox before each task; checking adds a strikethrough and gray background, indicating completion. Can unmark if needed. +Edit task: Click the task itself to enter edit page. +Delete task: Swipe left on a task to reveal "Delete" button. +Module 2: Smart Reminder System +3.2.1 Reminder Trigger +Mechanism: Based on task's set "start time" and the user's "reminder lead time," send a push notification from device. +Offline Support: Locally scheduled reminders must trigger even if user is offline. +3.2.2 Reminder Content & Format +Notification title: App name "Today's Plan." +Body: "Reminder: [Task Title] will start at [Start Time]." E.g., "Reminder: Product Meeting will start at 10:00." +Sound: Use system default or offer several simple, effective tones. +3.2.3 Reminder Settings +Global Settings (in Settings page): +User can set a default reminder time, e.g., "15 minutes before task starts." New tasks adopt this by default. +Single Task Settings (in create/edit page): +Users can override global settings for important tasks, choosing specific reminder times like "on time," "5 minutes early," "30 minutes early," or "1 hour early." +Provide "no reminder" option. +Subsequent Features (V1.1, V2.0) +3.3 Daily Review & Statistics +Push a summary notification at a set time every night (e.g., 22:00): "How was your day? Take a look at your achievements!" +Generate a simple daily report card: shows total planned tasks, completed tasks, completion rate, plus an encouraging message. +3.4 History Review +Calendar view to click on any past day and check its plans and completion status. Days with high completion rates marked with a special color. +3.5 Templates +Allow users to save a successful daily plan as a template, e.g., "Efficient Workday," "Relaxing Weekend." +When creating tomorrow's plan, one-click import a template, modify slightly to save time. +3.6 Themes & Personalization +Offer dark mode. +Allow changing several primary color themes. + +4. Non-Functional Requirements +4.1 Performance +Response: App launch time under 2 seconds; adding/editing tasks must be smooth and lag-free. +Resource Use: Low battery and memory consumption in background; do not over-consume resources waiting for reminders. +4.2 Usability +Minimal & intuitive: UI must be minimal, primary functions accessible within 3 clicks. No tutorial needed for new users. +Error tolerance: Offer undo (e.g. brief undo after mistakenly deleting a task). +4.3 Reliability +Reliable reminders: Reminder function is the product's lifeline; must guarantee 99.99% timely and accurate delivery. +Data loss-free: User plans must be reliably stored locally. Future versions can support cloud sync to prevent data loss on device change. +4.4 Compatibility +Platform: Support major iOS and Android versions (latest 3-4 releases). +Screen: Layout must fit various phone screen sizes. + +5. Roadmap +V1.0 (MVP): +Goal: Validate core value—planning & reminders. +Features: Complete all "Core Features" described above (Plan management, smart reminders). +V1.1 (Quick Optimization): +Goal: Improve retention and achievement. +Features: Add "Daily Review & Statistics," "History Review." +V2.0 (Enhanced Experience): +Goal: Increase efficiency and personalization. +Features: Add "Templates," "Themes & Personalization," and start developing "Cloud Sync." +``` + +So với câu "giúp tôi viết một ứng dụng có thể ghi kế hoạch và nhắc nhở mỗi ngày" ban đầu, tài liệu này đã chi tiết hơn rất nhiều. Bạn có thể thêm bớt sửa đổi theo nhu cầu thực tế; đối với một số module bạn chưa chắc chắn, cũng có thể tiếp tục để AI cung cấp thêm phương án dự phòng, bạn chọn và gộp thành phiên bản cuối cùng. + +Thông qua cách này, chúng ta có thể rất dễ dàng biến ý tưởng trừu tượng thành mô tả cụ thể. Đối với phát triển AI, "cụ thể" chính là năng suất: nhu cầu càng cụ thể, càng dễ nhận được dự án có cấu trúc ổn định, chất lượng cao. Bạn có thể thử dùng cách này làm lại một dự án nhỏ trước đó, so sánh sự khác biệt về hiệu quả. + +Nếu bạn thấy loại "prompt nhu cầu" này quá dài, một cách rất tự nhiên là viết nó vào một tài liệu markdown riêng, làm "tài liệu nhu cầu / tài liệu phát triển / PRD" của bạn. Sau đó mỗi lần để AI viết dự án, chỉ cần để nó "tham khảo tài liệu này", thay vì gõ lại dài dòng mỗi lần. Bạn cũng có thể liên tục hoàn thiện tài liệu này trong quá trình lặp, để các dự án sau trực tiếp hưởng lợi. + +Dưới đây là một số kịch bản sử dụng phổ biến khác: + +### Quản lý thư mục + +Chúng ta có thể thử dùng công cụ lập trình AI CLI để quản lý các loại tệp trong thư mục hiện tại. Ví dụ, bạn có một loạt tệp lộn xộn, cần sắp xếp phân loại, có thể nói với Claude Code hoặc Codex: + +`Please help me organize the contents of the current folder. I want to group files with the same content together & I want to group files from the same time period together. Please help me handle this.` + +### Phát triển dự án mới + +Điều này gần như giống hệt cách chúng ta sử dụng trong z.ai, Trae trước đó -- chúng ta cũng có thể trực tiếp dùng công cụ lập trình AI CLI để phát triển dự án mới từ đầu. Tất nhiên, tốt nhất nên chuẩn bị sẵn một tài liệu nhu cầu trước. + +Tài liệu nhu cầu càng chi tiết, hiệu quả cuối cùng càng tốt. Bạn có thể tối ưu hóa tài liệu nhiều vòng theo ý tưởng thay đổi liên tục; tài liệu càng hoàn thiện, triển khai mã càng ổn định, trưởng thành hơn. + +### Triển khai dự án mã nguồn mở (ví dụ Dify) + +Đối với các bạn mới tiếp xúc với máy tính, việc triển khai một dự án mã nguồn mở từ GitHub thường rất khó khăn. Nhưng chúng ta hoàn toàn có thể giao việc này cho Claude Code, giống như chúng ta đã làm trong hướng dẫn Dify: + + + +Nếu tôi muốn chạy Dify riêng trên máy cục bộ, chỉ cần ném liên kết này cho Claude Code, sau đó nhập: + +`I want to deploy this GitHub project ``https://github.com/langgenius/dify`` . Please help me clone the project and run it.` + +Sau khi nhận yêu cầu của bạn, Claude Code sẽ tự động hoàn thành một loạt thao tác, bao gồm lấy mã từ GitHub, cấu hình môi trường chạy, khởi động dự án, v.v. Nếu có lỗi ở bước nào hoặc trạng thái khởi động dự án không bình thường, bạn chỉ cần xử lý thủ công ít theo hướng dẫn. Ngoài Dify, bạn cũng có thể dùng Claude Code giúp bạn triển khai phần lớn dự án mã nguồn mở GitHub phổ biến -- bạn chỉ cần một ô hội thoại, cộng thêm thời gian uống một tách cà phê. + +![](/zh-cn/stage-2/backend/modern-cli/images/image31.png) + +### Giải thích mã và viết tài liệu + +Đối với một số dự án phức tạp, hoặc dự án lớn do AI tự động tạo, bạn có thể thấy mã quá dài, logic quá nhiều, rất khó hiểu. Lúc này có thể để công cụ lập trình AI CLI giúp bạn "đọc mã". Bạn có thể hỏi như sau: + +- Vui lòng giúp tôi giải thích dự án này: cách chạy, cách sử dụng, sau này sửa và tiếp tục phát triển như thế nào? +- Vui lòng giúp tôi giải thích quy trình tổng thể của dự án này: chương trình chạy như thế nào? Người dùng có thể làm những thao tác nào trong giao diện? +- Vui lòng giúp tôi viết một tài liệu hoàn chỉnh cho dự án này, bao gồm tài liệu phát triển và tài liệu chạy, v.v. +- Vui lòng dựa trên tất cả nội dung trong thư mục hiện tại của tôi, viết một mô tả chi tiết, và lưu vào tài liệu markdown đã chỉ định. + +### Thêm cách sử dụng + +Tất nhiên, công cụ lập trình AI CLI có thể làm được nhiều hơn những điều trên. Đừng chỉ coi nó là "công cụ viết mã", mà hãy coi nó như một Agent thông minh có khả năng hành động độc lập. Bạn có thể để nó giúp bạn: + +- Quản lý và sắp xếp tệp cục bộ; +- Viết nhật ký, viết tổng kết; +- Phân tích và sửa lỗi hệ thống; +- Thực hiện các tác vụ dòng lệnh lặp đi lặp lại, v.v. + +Có lẽ trong tương lai không xa, nó sẽ trở thành đối tác AI quan trọng nhất và hiểu bạn nhất trên máy tính của bạn. diff --git a/docs/vi-vn/stage-2/backend/stripe-payment/index.md b/docs/vi-vn/stage-2/backend/stripe-payment/index.md new file mode 100644 index 0000000..db3d3ce --- /dev/null +++ b/docs/vi-vn/stage-2/backend/stripe-payment/index.md @@ -0,0 +1,905 @@ +# Cách tích hợp hệ thống thanh toán như Stripe + +Khi sản phẩm của bạn đã có trang giao diện, đăng nhập, cơ sở dữ liệu và backend cơ bản, vấn đề thực tế tiếp theo là: **làm sao để thu tiền**. + +Nhiều người lần đầu tiếp xúc với thanh toán thường tập trung hết vào "làm sao để nhảy đến trang thanh toán". Nhưng thứ thực sự quyết định hệ thống có ổn định hay không, không phải là nút bấm, mà là toàn bộ chuỗi thanh toán: ai quyết định giá, ai xác nhận thanh toán thành công, ai cập nhật cơ sở dữ liệu, ai thu hồi quyền hạn. + +Bài viết này giúp bạn chia thành hai phần: + +- **Phần đầu** chỉ nói về tích hợp cơ bản thực dụng nhất, mục tiêu là giúp bạn nhanh chóng tích hợp Stripe vào dự án. +- **Phần sau** được gom chung vào phụ lục, bao gồm chi tiết Webhook, sự kiện đăng ký, khác biệt về phương án thanh toán giữa các quốc gia và khu vực. + +> 💡 Khuyến nghị học xong các chương này trước khi tiếp tục +> +> - [Từ cơ sở dữ liệu đến Supabase](../database-supabase/) +> - [Mô hình hỗ trợ viết code API và tài liệu API](../ai-interface-code/) +> - [Cách triển khai ứng dụng Web](../zeabur-deployment/) + +# Bạn sẽ học được + +1. Hệ thống thanh toán khả thi tối thiểu trông như thế nào. +2. Cách nhanh nhất để tích hợp Stripe vào dự án của bạn. +3. Cách viết prompt để AI trực tiếp giúp bạn thêm hệ thống thanh toán. +4. Nếu không làm dự án Stripe ở nước ngoài, nên ưu tiên phương án thanh toán nào cho các khu vực khác. + +--- + +# Phần 1: Cơ bản + +## 1. Hãy nhớ 3 nguyên tắc + +Nếu bạn chỉ nhớ ba điều, hãy nhớ ba điều sau: + +1. **Giá cả phải do backend quyết định**, không được tin số tiền frontend gửi lên. +2. **Thứ thực sự kích hoạt quyền hạn là Webhook**, không phải trang `success`. +3. **Cơ sở dữ liệu của bạn phải lưu trạng thái thanh toán**, không được chỉ dựa vào bảng điều khiển Stripe. + +Ba điều này là ranh giới cốt lõi của hệ thống thanh toán. Chỉ cần ranh giới không sai, sau này đổi sang Stripe, PayPal, Alipay, WeChat Pay, bản chất đều chỉ là "đổi giao diện, kiến trúc không đổi". + +## 2. Nếu không xử lý ở backend mà để frontend kết nối trực tiếp Stripe thì sao? + +Đây là ý tưởng tự nhiên nhất của nhiều người lần đầu làm thanh toán: + +- Trên trang đã có nút "Mua hàng" +- Vậy tôi có thể để frontend tự kết nối Stripe +- Như vậy có phải không cần làm backend không + +Nếu bạn chỉ làm một trang demo giả thì không sao. Nhưng nếu bạn thực sự muốn thu tiền, **cách này thường sẽ dẫn đến hậu quả xấu**. + +Các vấn đề phổ biến nhất bao gồm: + +1. **Giá cả dễ bị thay đổi** + Request trong trình duyệt là do máy tính người dùng gửi đi. Người khác hoàn toàn có thể sửa nội dung request. +2. **Thông tin nhạy cảm dễ bị lộ** + Các khóa bí mật, logic giá cả, logic kích hoạt hội viên quan trọng nhất, vốn dĩ không nên đặt ở frontend. +3. **Bạn không thể xác nhận đáng tin cậy "khoản tiền này có thực sự thành công không"** + Người dùng nhảy đến trang thành công, không có nghĩa là cơ sở dữ liệu của bạn đã đồng bộ đúng. +4. **Trạng thái cơ sở dữ liệu sẽ bị loạn** + Người dùng có thể nói "tôi rõ ràng đã thanh toán", nhưng trong hệ thống của bạn hoàn toàn không ghi nhận. + +Vậy phân công an toàn hơn nên là: + +- Frontend chịu trách nhiệm: hiển thị nút, khởi tạo mua hàng, chuyển trang +- Backend chịu trách nhiệm: quyết định giá, tạo phiên thanh toán, nhận Webhook, cập nhật cơ sở dữ liệu + +::: info Đoạn này bạn có thể tóm gọn thành một câu +**Frontend có thể chịu trách nhiệm chuyển trang, backend phải chịu trách nhiệm định giá và xác nhận.** + +Chỉ khi thực sự thu tiền, đừng đặt "quyền quyết định giá cuối cùng" và "logic kích hoạt sau thanh toán thành công" ở frontend. +::: + +## 3. Khi nào nên dùng Stripe trước + +Nếu bạn đang làm các kịch bản sau, Stripe thường là điểm khởi đầu thuận lợi nhất: + +- SaaS hướng đến người dùng ở nước ngoài +- Sản phẩm hội viên theo dạng đăng ký +- Sản phẩm kỹ thuật số, template, gói credit AI +- Muốn nhanh chóng xác thực thương mại hóa, thay vì ngay từ đầu xử lý quá nhiều chi tiết thanh toán nội địa + +Nếu người dùng chính của bạn ở Trung Quốc đại lục, thì thường sẽ không chọn Stripe làm lựa chọn đầu tiên, phần này tôi sẽ nói riêng trong phụ lục. + +## 4. Chuỗi thanh toán khả thi tối thiểu + +Hãy xem phiên bản tối thiểu. Chỉ cần chuỗi này chạy được, hệ thống thanh toán của bạn đã có bộ khung. + +```mermaid +flowchart LR + user["Người dùng"] + frontend["Trang frontend"] + backend["Backend của bạn"] + checkout["Stripe Checkout"] + webhook["Stripe Webhook"] + db["Supabase / Cơ sở dữ liệu kinh doanh"] + + user -->|"Nhấn mua hàng"| frontend + frontend -->|"Yêu cầu tạo phiên thanh toán"| backend + backend -->|"Tạo Session theo giá backend"| checkout + frontend -->|"Chuyển đến trang thanh toán"| checkout + checkout -->|"Gửi sự kiện sau khi thanh toán"| webhook + webhook -->|"Xác minh chữ ký và cập nhật trạng thái"| backend + backend -->|"Ghi vào orders / subscriptions"| db + db -->|"Frontend refresh đọc trạng thái mới nhất"| frontend +``` + +Dịch sang ngôn ngữ con người: + +1. Người dùng nhấn nút. +2. Frontend hỏi backend lấy liên kết thanh toán. +3. Backend dùng khóa Stripe để tạo phiên thanh toán. +4. Người dùng đến trang Stripe để thanh toán. +5. Stripe thông báo cho bạn qua Webhook rằng "thanh toán thực sự thành công". +6. Backend của bạn cập nhật cơ sở dữ liệu. + +## 5. Sơ đồ thời gian chuẩn khi khởi tạo thanh toán + +Nếu bạn quen xem sơ đồ hệ thống chuẩn hơn, có thể xem trực tiếp sơ đồ thời gian này: + +```mermaid +sequenceDiagram + autonumber + actor User as Người dùng + participant Frontend as Trang frontend + participant Backend as Backend API + participant Stripe as Stripe Checkout + + User->>Frontend: Nhấn "Nâng cấp" hoặc "Mua hàng" + Frontend->>Backend: POST /api/billing/create-checkout-session + Note right of Frontend: Frontend truyền plan / userId / email\nKhông truyền số tiền thanh toán cuối cùng + Backend->>Backend: Xác minh gói và ánh xạ priceId + Backend->>Stripe: Tạo Checkout Session + Stripe-->>Backend: Trả về session.url + Backend-->>Frontend: Trả về liên kết thanh toán + Frontend-->>User: Chuyển đến trang thanh toán Stripe + User->>Stripe: Hoàn thành thanh toán +``` + +## 6. Bắt đầu nhanh + +Nếu bạn muốn tích hợp nhanh nhất, chỉ cần làm theo 5 bước dưới đây. + +### 6.1 Bước 1: Tạo sản phẩm và giá trong bảng điều khiển Stripe + +Mục đích của bước này không phải "tự cấu hình vài thứ", mà là định nghĩa rõ trong Stripe **bạn đang bán cái gì, định thu tiền như thế nào**. + +Trong mô hình của Stripe: + +- **Product** đại diện cho "bạn đang bán cái gì", ví dụ `Hội viên Pro` +- **Price** đại diện cho "cái này bán bao nhiêu tiền, theo chu kỳ nào", ví dụ `trả tháng 9.9 USD`, `trả năm 99 USD` + +Tại sao phải làm bước này trước? Vì khi backend của bạn tạo Checkout Session, không phải truyền trực tiếp một số tiền cho Stripe, mà phải truyền một `price_id` đã tồn tại. Stripe sẽ dựa trên `price_id` này để tạo trang thanh toán, số tiền, loại tiền tệ và chu kỳ đăng ký thực tế. + +Nếu bạn bỏ qua bước này, "tạo liên kết thanh toán" thực ra không thể làm được. + +::: info Tại sao phải dừng lại ở đây +Nhiều người mới bắt đầu thấy `Product`, `Price` hai từ này hơi bực, cảm thấy như đang học thuật ngữ nội bộ của Stripe. + +Nhưng thực ra, bước này đang làm một việc rất đơn giản: +- Định nghĩa rõ "bán cái gì" +- Định nghĩa rõ "bán bao nhiêu tiền" +- Để backend sau này có thể dùng một `price_id` ổn định để tạo liên kết thanh toán + +Chỉ cần hiểu được điều này, Checkout Session sau đó sẽ không thấy trừu tượng. +::: + +Đối với một hệ thống đăng ký khả thi tối thiểu, bạn ít nhất cần tạo hai cấp: + +- Một `Product` +- Một hoặc nhiều `Price` + +Bạn có thể trực tiếp mở các trang sau: + +- Trang đăng nhập Stripe Dashboard: [Dashboard Login](https://dashboard.stripe.com/login) +- Tài liệu quản lý sản phẩm và giá của Stripe: [Manage products and prices](https://docs.stripe.com/products-prices/manage-prices) +- Tài liệu bắt đầu nhanh Stripe Checkout: [Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- Trang sản phẩm Stripe Dashboard: [Product catalog](https://dashboard.stripe.com/test/products) + +Khuyến nghị bạn nên thao tác trong **Test mode (chế độ thử nghiệm)** trước, đừng tạo trong môi trường chính thức ngay từ đầu. + +Một cấu hình tối thiểu phổ biến nhất là: + +- `Product`: `Pro Plan` +- `Price 1`: `pro_monthly` +- `Price 2`: `pro_yearly` + +Khi thao tác trong bảng điều khiển, bạn có thể hiểu theo thứ tự sau: + +1. Tạo một sản phẩm `Pro Plan` trước +2. Sau đó thêm hai mức giá vào sản phẩm này +3. Trả tháng và trả năm thực ra là hai cách tính phí của cùng một sản phẩm + +Sau khi hoàn thành, bạn ít nhất cần ghi lại các thông tin sau: + +- `price_id` của giá trả tháng +- `price_id` của giá trả năm +- Tên gói của bạn, ví dụ `pro_monthly`, `pro_yearly` + +Nếu đây là lần đầu bạn vào bảng điều khiển Stripe, khuyến nghị bạn hiểu bước này như: + +- `Product` quyết định trang thanh toán bán cái gì +- `Price` quyết định trang thanh toán thu bao nhiêu tiền +- Thứ backend thực sự cần dùng sau này, chủ yếu là `price_id` + +::: info Giá trị thực sự cần ghi lại +Quan trọng nhất trong trang này không phải tên sản phẩm, mà là `price_id`. + +Sau này dù là để AI giúp bạn tích hợp backend, hay tự kiểm tra vấn đề, thứ thường xuyên dùng nhất là: +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- Hai `price_id` tương ứng +::: + +Nếu bạn muốn AI dẫn bạn cấu hình bảng điều khiển trước, có thể dùng prompt này: + +```text +Tôi là người mới sử dụng Stripe lần đầu, bạn đừng sửa code trước, hãy dẫn tôi cấu hình thanh toán cơ bản nhất trong bảng điều khiển Stripe. + +Vui lòng dựa trên tài liệu chính thức sau để hướng dẫn tôi từng bước: +- https://docs.stripe.com/products-prices/manage-prices +- https://docs.stripe.com/checkout/quickstart?lang=node + +Tình huống của tôi: +- Tôi muốn làm một hệ thống hội viên thanh toán đơn giản nhất +- Chỉ có hai gói: trả tháng và trả năm +- Tôi chưa hiểu các từ Product, Price + +Vui lòng: +1. Dùng ngôn ngữ đơn giản nhất giải thích Product và Price lần lượt là gì. +2. Hướng dẫn tôi thao tác theo thứ tự "mở trang nào -> nhấp vào đâu -> điền gì". +3. Nhắc tôi sau khi làm xong cần sao chép những nội dung nào từ bảng điều khiển để backend sử dụng. +4. Nếu tôi dễ nhầm, hãy nhắc tôi nên luôn thao tác trong chế độ thử nghiệm. +``` + +### 6.2 Bước 2: Chuẩn bị biến môi trường + +Bạn thường cần chuẩn bị ít nhất các biến môi trường sau: + +- `STRIPE_SECRET_KEY` +- `STRIPE_WEBHOOK_SECRET` +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- `APP_URL` +- `SUPABASE_URL` +- `SUPABASE_SERVICE_ROLE_KEY` + +Bạn có thể trực tiếp mở các trang sau: + +- Tài liệu Stripe API Keys: [API keys](https://docs.stripe.com/keys) +- Trang Stripe Dashboard API Keys: [API Keys](https://dashboard.stripe.com/test/apikeys) +- Tài liệu Stripe Webhooks: [Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Trang Stripe Dashboard Webhooks: [Workbench Webhooks](https://dashboard.stripe.com/test/workbench/webhooks) + +> ⚠️ `STRIPE_SECRET_KEY` và `SUPABASE_SERVICE_ROLE_KEY` chỉ được đặt ở backend. + +::: info Mục đích của bước biến môi trường +Bước này không phải để "điền đầy `.env`", mà là để đặt những thứ nhạy cảm nhất của hệ thống thanh toán vào backend bảo quản: + +- Khóa backend của Stripe +- Khóa xác minh Webhook +- Ánh xạ giá của bạn + +Hiểu đơn giản: +Frontend chỉ chịu trách nhiệm khởi tạo mua hàng, tất cả bí mật và logic định giá nên được giữ ở phía server. +::: + +Bước này cũng có thể để AI giúp bạn sắp xếp: + +```text +Vui lòng xem cách dự án hiện tại của tôi lưu biến môi trường, sau đó giúp tôi liệt kê các biến môi trường cần thiết cho Stripe. + +Vui lòng tham khảo tài liệu: +- https://docs.stripe.com/keys +- https://docs.stripe.com/webhooks + +Tình huống của tôi: +- Tôi là người mới bắt đầu +- Tôi không phân biệt được biến nào nên đặt ở frontend, biến nào nên đặt ở backend +- Tôi cũng không chắc dự án hiện tại nên sửa `.env`, `.env.local` hay file khác + +Vui lòng: +1. Tìm xem biến môi trường trong dự án hiện tại thường được ghi ở đâu. +2. Liệt kê các biến tối thiểu cần thiết cho việc tích hợp Stripe. +3. Dùng ngôn ngữ đơn giản nhất giải thích mỗi biến dùng để làm gì. +4. Cho tôi biết mỗi biến nên sao chép từ trang Stripe nào. +5. Nếu dự án có file biến môi trường mẫu, hãy trực tiếp giúp tôi bổ sung tên biến. +``` + +### 6.3 Bước 3: Backend tạo Checkout Session + +Bước này bạn không cần tự viết API, hãy để AI tham khảo tài liệu chính thức giúp bạn triển khai. + +Trước hết đưa các tài liệu sau cho nó: + +- Bắt đầu nhanh Stripe Checkout: [Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- Checkout Sessions API: [Create a Checkout Session](https://docs.stripe.com/api/checkout/sessions/create) +- Tài liệu đăng ký: [Subscriptions](https://docs.stripe.com/payments/subscriptions) + +Sau đó dán trực tiếp prompt này: + +```text +Vui lòng xem cách tổ chức code backend của dự án hiện tại, sau đó giúp tôi tích hợp thanh toán Stripe. + +Vui lòng tham khảo tài liệu chính thức: +- https://docs.stripe.com/checkout/quickstart?lang=node +- https://docs.stripe.com/api/checkout/sessions/create +- https://docs.stripe.com/payments/subscriptions + +Mục tiêu của tôi rất đơn giản: +- Sau khi người dùng nhấn nút mua hàng, có thể nhảy đến trang thanh toán của Stripe +- Gói chỉ có trả tháng và trả năm +- Đừng để tôi tự quyết định code nên đặt ở đâu, hãy xem dự án rồi giúp tôi đặt vào vị trí phù hợp + +Vui lòng: +1. Tìm hiểu cấu trúc file đầu vào backend, file định tuyến, cách viết biến môi trường trong dự án. +2. Tham khảo tài liệu chính thức, giúp tôi tích hợp bước "tạo liên kết thanh toán Stripe". +3. Đừng để tôi tự truyền số tiền, giá cả sử dụng biến môi trường backend để quyết định. +4. Sau khi xong cho tôi biết bạn đã sửa những file nào. +5. Cuối cùng cho tôi biết tôi còn cần bổ sung cấu hình gì trong bảng điều khiển Stripe. +``` + +### 6.4 Bước 4: Frontend chuyển đến trang thanh toán + +Mục tiêu của bước này rất đơn giản: để nút trên trang giá gọi API backend của bạn, sau đó chuyển đến Stripe Checkout. + +Tài liệu tham khảo: + +- Tài liệu tích hợp Stripe Checkout: [Build an integration with Checkout](https://docs.stripe.com/payments/checkout/build-integration) + +Prompt cho AI: + +```text +Giúp tôi kết nối nút "Mua hàng" trong dự án với Stripe. + +Yêu cầu: +- Không sửa trang hiện tại, chỉ sửa logic sau khi nhấn nút +- Sau khi nhấn, gọi API backend để lấy liên kết thanh toán, sau đó chuyển đến Stripe +- Nếu có lỗi, hiển thị thông báo đơn giản cho người dùng (ví dụ "Thanh toán tạm không khả dụng, vui lòng thử lại sau") + +Tài liệu tham khảo: https://docs.stripe.com/payments/checkout/build-integration +``` + +### 6.5 Bước 5: Webhook cập nhật trạng thái cơ sở dữ liệu + +Đây là bước quan trọng nhất. + +::: info Tại sao bước này quan trọng nhất +Nhiều người nghĩ "người dùng thanh toán xong và chuyển đến trang success" là xong. + +Không. + +Đối với hệ thống của bạn, điều thực sự quan trọng là: +**Stripe có chính thức gửi sự kiện đến Webhook của bạn, và backend của bạn có cập nhật trạng thái cơ sở dữ liệu thành công hay không.** +::: + +Bạn cũng có thể để AI triển khai trực tiếp theo tài liệu Webhook chính thức của Stripe, đừng tự viết bằng tay. + +Tài liệu tham khảo: + +- Stripe Webhooks: [Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Stripe CLI: [Stripe CLI](https://docs.stripe.com/stripe-cli) +- Cách sử dụng Stripe CLI: [Use the Stripe CLI](https://docs.stripe.com/stripe-cli/use-cli) + +Prompt cho AI: + +```text +Vui lòng tiếp tục giúp tôi tích hợp bước "tự động kích hoạt sau khi thanh toán thành công" của Stripe. + +Vui lòng tham khảo tài liệu chính thức: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +Mục tiêu của tôi: +- Sau khi người dùng thanh toán xong, không chỉ chuyển đến trang thành công +- Mà thực sự thay đổi trạng thái hội viên trong cơ sở dữ liệu thành đã kích hoạt + +Vui lòng: +1. Tìm xem code liên quan đến cơ sở dữ liệu và cách lưu trạng thái người dùng trong dự án hiện tại. +2. Giúp tôi thêm Stripe webhook. +3. Sau khi thanh toán thành công, thay đổi người dùng tương ứng thành active, hoặc cập nhật theo trường trạng thái hội viên đang dùng trong dự án. +4. Nếu dự án đã có bảng đăng ký, bảng đơn hàng, bảng người dùng, hãy ưu tiên sử dụng cấu trúc hiện có. +5. Sau khi xong cho tôi biết bạn đã sửa những file nào. +6. Kèm theo hướng dẫn cách kiểm tra cục bộ bước này có thực sự hiệu quả hay không. +``` + +## 7. Prompt để AI giúp bạn tích hợp nhanh + +Nếu bạn đang dùng các công cụ như Codex, Claude Code, Trae, Cursor, có thể dán trực tiếp prompt dưới đây cho nó, để nó tích hợp thanh toán trong dự án của bạn. + +```text +Vui lòng giúp tôi tích hợp thanh toán Stripe vào dự án hiện tại, tôi muốn làm một tính năng hội viên thanh toán đơn giản nhất có thể chạy được. + +Yêu cầu của tôi: +1. Tôi là người mới bắt đầu, vui lòng tự xem dự án trước, sau đó quyết định nên sửa code ở đâu. +2. Đừng để tôi tự đánh giá cấu trúc thư mục, cấu trúc định tuyến, cấu trúc cơ sở dữ liệu. +3. Tôi chỉ muốn làm phiên bản đơn giản nhất: trả tháng và trả năm hai gói. +4. Sau khi người dùng nhấn mua hàng, có thể nhảy đến trang thanh toán Stripe. +5. Sau khi thanh toán thành công, trạng thái hội viên trong cơ sở dữ liệu có thể chuyển thành đã kích hoạt. +6. Đừng thêm quá nhiều tính năng phức tạp ngay từ đầu, như mã giảm giá, nâng cấp/hạ cấp, hóa đơn phức tạp. + +Yêu cầu đầu ra: +1. Đưa cho tôi một kế hoạch thay đổi trước. +2. Sau đó trực tiếp sửa code. +3. Cuối cùng hướng dẫn tôi cách kiểm tra cục bộ từng bước. +4. Nếu có bước nào cần tôi thao tác thêm trong bảng điều khiển Stripe, hãy gửi trực tiếp liên kết và điểm chính. +``` + +Nếu bạn muốn AI phù hợp hơn với dự án của mình, có thể bổ sung ở đầu: + +- Framework frontend của bạn +- Cấu trúc thư mục backend của bạn +- Tên bảng cơ sở dữ liệu của bạn +- Hệ thống người dùng hiện tại của bạn là Supabase Auth hay tự xây dựng Auth + +## 7.1 Phối hợp kiểm tra cục bộ cũng nên giao cho AI + +Nếu bạn muốn để AI giúp bạn kết nối toàn bộ quá trình phối hợp kiểm tra cục bộ, có thể dùng đoạn sau: + +```text +Vui lòng tiếp tục giúp tôi chạy thật thanh toán Stripe, tôi muốn làm theo từng bước, không muốn tự đoán. + +Vui lòng tham khảo tài liệu chính thức: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +Mục tiêu của tôi: +1. Cho tôi biết trước nên mở những trang Stripe nào. +2. Cho tôi biết cách lấy STRIPE_WEBHOOK_SECRET. +3. Cho tôi biết cách sử dụng stripe login và stripe listen. +4. Cho tôi biết cách xác minh checkout.session.completed đã gửi thành công đến webhook cục bộ. +5. Nếu dự án hiện tại cần khởi động frontend và backend trước, hãy hướng dẫn lệnh cụ thể. +6. Đừng chỉ nói lý thuyết, hãy xuất theo các bước thao tác thực tế. +7. Nếu tôi làm sai ở bước nào, hãy cho tôi biết lỗi phổ biến nhất sẽ trông như thế nào. +``` + +## 8. 4 điều dễ sai nhất + +1. **Coi trang `success` là thanh toán thành công** + Thứ thực sự quyết định trạng thái là Webhook, không phải chuyển trang frontend. +2. **Để frontend truyền số tiền** + Điều này sẽ gây ra rủi ro sửa giá nghiêm trọng. +3. **Route Webhook bị `express.json()` xử lý trước** + Stripe xác minh chữ ký cần body request gốc. +4. **Không xử lý lũy đẳng** + Webhook có thể thử lại, nếu mỗi lần bạn đều lặp lại việc thêm hội viên hoặc credit, sẽ gây ra sự cố. + +## 9. Lời khuyên chọn phương án trong một câu + +Nếu bây giờ bạn chỉ muốn chạy được thu tiền trước: + +| Người dùng chính của bạn | Phương án nên thử trước | +| :--- | :--- | +| SaaS ở nước ngoài / người dùng quốc tế | Stripe | +| Người dùng Trung Quốc đại lục | Alipay / WeChat Pay | +| Đội ngũ Hong Kong hoặc xuyên biên giới | Stripe + ví địa phương / phương án tập hợp FPS | + +Chi tiết cụ thể, tôi sẽ gom vào phụ lục. + +::: info Tư duy chọn phương án đơn giản nhất +Đừng ngay từ đầu đã nghĩ "tôi muốn tích hợp tất cả phương thức thanh toán toàn cầu cùng lúc". + +Thứ tự thực tế hơn thường là: +- Chọn một chuỗi thanh toán chính theo khu vực của người dùng chính +- Chạy được thanh toán khả thi tối thiểu trước +- Sau đó bổ sung phương thức thanh toán thứ hai, thứ ba dựa trên nguồn người dùng thực tế +::: + +## 10. Tóm tắt + +Đến đây, bạn đã nắm được chuỗi thanh toán cơ bản nhưng quan trọng nhất: + +1. Frontend khởi tạo mua hàng. +2. Backend tạo Checkout Session. +3. Người dùng thanh toán trên trang Stripe. +4. Stripe thông báo cho backend qua Webhook. +5. Backend cập nhật cơ sở dữ liệu. +6. Frontend refresh hiển thị trạng thái hội viên hoặc đơn hàng mới. + +Nếu bạn chỉ muốn nhanh chóng tích hợp thanh toán vào dự án, nội dung phía trước đã đủ dùng. Phụ lục bên dưới bạn có thể quay lại xem khi thực sự gặp vấn đề. + +--- + +# Phụ lục + +## Phụ lục A: Các đối tượng phổ biến nhất trong Stripe + +Lần đầu đọc tài liệu Stripe, dễ bị rối nhất bởi các tên đối tượng. Thực ra bạn chỉ cần hiểu trước các đối tượng sau: + +| Đối tượng | Tác dụng | Bạn có thể hiểu nó là gì | +| :--- | :--- | :--- | +| `Product` | Mô tả bán cái gì | Sản phẩm hoặc gói hội viên | +| `Price` | Mô tả bán bao nhiêu tiền, chu kỳ tính phí như thế nào | Trả tháng, trả năm, mua đứt | +| `Checkout Session` | Quy trình thanh toán được Stripe lưu trữ | Trang thanh toán | +| `Subscription` | Quan hệ đăng ký chu kỳ | Hội viên tự động gia hạn | +| `Customer` | Người dùng thanh toán | Hồ sơ khách hàng trong Stripe | +| `Webhook` | Thông báo bất đồng bộ | Stripe cho bạn biết "khoản tiền này thế nào" | + +## Phụ lục B: Tại sao trang `success` không bằng thanh toán thành công + +Nhiều người nghĩ "người dùng thanh toán xong, nhảy đến trang success" là thanh toán thành công. Đây là lỗi dễ mắc phải nhất. + +### Nói về một kịch bản thực tế + +Giả sử bạn làm một trang web hội viên: +1. Người dùng nhấn "Mua hội viên" +2. Chuyển đến trang thanh toán Stripe +3. Người dùng nhập thẻ tín dụng, nhấn thanh toán +4. Trang nhảy đến `success.html` của bạn +5. Bạn viết code ở trang success: "Đã đến trang này, kích hoạt hội viên cho người dùng" + +**Vấn đề ở đâu?** + +Người dùng có thể hoàn toàn chưa thanh toán, hoặc thanh toán được một nửa rồi đóng trang, cũng có thể truy cập trực tiếp `success.html`. + +### Hai đường dẫn hoàn toàn khác nhau + +```mermaid +flowchart TB + pay["Người dùng hoàn thành thanh toán trên Stripe"] + + subgraph unreliable["❌ Đường dẫn không đáng tin: Chỉ nhìn trang success"] + success["Trình duyệt nhảy đến trang success"] + fake["Code frontend cho rằng đã kích hoạt"] + risk["Rủi ro: Đóng trang / Mất mạng / Giả mạo URL / Hoàn toàn chưa thanh toán"] + success --> fake --> risk + end + + subgraph reliable["✅ Đường dẫn đáng tin: Lấy Webhook backend làm chuẩn"] + event["Stripe server gửi Webhook"] + verify["Backend xác minh chữ ký"] + active["Cơ sở dữ liệu chính thức cập nhật thành đã thanh toán"] + event --> verify --> active + end + + pay --> success + pay --> event +``` + +**Điểm khác biệt chính:** + +| | Chuyển trang success | Thông báo Webhook | +| :--- | :--- | :--- | +| Ai khởi tạo | Trình duyệt của người dùng | Server của Stripe | +| Có thể giả mạo không | Có thể, chỉ cần truy cập URL trực tiếp | Không thể, có xác minh chữ ký | +| Chắc chắn đại diện thanh toán thành công không | Không chắc chắn | Chắc chắn | +| Hệ thống của bạn biết bằng cách nào | Code frontend đoán | Stripe thông báo chính thức | + +### Quy trình hoàn chỉnh nên như thế nào + +```mermaid +sequenceDiagram + autonumber + actor User as Người dùng + participant Frontend as Trang web của bạn + participant Stripe as Stripe + participant Webhook as API backend của bạn + participant DB as Cơ sở dữ liệu + + User->>Stripe: Hoàn thành thanh toán trên trang Stripe + Note over Stripe: Tiền thực sự đến tài khoản Stripe + + Stripe-->>Frontend: Trình duyệt nhảy đến trang success + Note over Frontend: ⚠️ Bước này chỉ là chuyển trang
Không đại diện hệ thống đã xác nhận + + Stripe->>Webhook: Gửi thông báo Webhook
"checkout.session.completed" + Note over Webhook: ✅ Đây mới là thông báo chính thức + + Webhook->>Webhook: Xác minh chữ ký
(Đảm bảo là Stripe gửi, không phải hacker) + + Webhook->>DB: Cập nhật trạng thái người dùng thành "Đã thanh toán" + DB-->>Webhook: Lưu thành công + Webhook-->>Stripe: Trả về 200 OK + + Frontend->>DB: Người dùng refresh trang, truy vấn trạng thái + DB-->>Frontend: Trả về "Đã thanh toán" + Note over Frontend: Lúc này mới hiển thị tính năng hội viên +``` + +### Điểm nghẽn của mỗi bước + +**Bước 1: Người dùng thanh toán trên Stripe** + +Đây là thời điểm duy nhất xác định "tiền thực sự đã được thanh toán": +- Người dùng nhập thông tin thẻ tín dụng, nhấn xác nhận +- Ngân hàng trừ tiền từ thẻ người dùng +- Stripe xác nhận đã nhận được khoản tiền này + +**Bước 2: Trình duyệt nhảy đến trang success (vấn đề lớn nhất)** + +Bước này hoàn toàn không đáng tin, vì: +- Người dùng có thể trực tiếp nhập `yoursite.com/success` trong trình duyệt, chưa thanh toán cũng có thể truy cập +- Người dùng thanh toán được một nửa đóng trang, nhưng trước đó đã sao chép liên kết success, sau đó mở trực tiếp +- Vấn đề mạng dẫn đến chuyển trang thất bại, nhưng tiền đã trừ (người dùng đã thanh toán nhưng không thấy trang thành công) +- Người dùng nhấn nút quay lại, lại thanh toán một lần nữa, nhưng cả hai lần đều nhảy đến cùng một trang success + +**Bước 3: Stripe gửi Webhook** + +Đây là Stripe chủ động thông báo cho server của bạn "khoản tiền này đã đến tài khoản": +- Chỉ server của Stripe mới có thể khởi tạo request này +- Request có chứa chữ ký, backend của bạn có thể xác minh có phải thực sự do Stripe gửi không +- Ngay cả khi trang success không mở, người dùng mất mạng, Webhook vẫn sẽ được gửi + +**Bước 4: Backend xác minh chữ ký** + +Tại sao phải xác minh? Để ngăn hacker giả mạo thông báo. + +Giả sử không có xác minh, hacker có thể trực tiếp gửi một thông báo giả cho server của bạn: "Người dùng A đã thanh toán 1000 nhân dân tệ". Hệ thống của bạn sẽ kích hoạt hội viên cho hacker. + +Quá trình xác minh: +- Stripe dùng khóa bí mật đã thống nhất với bạn để tạo chữ ký cho nội dung thông báo +- Backend của bạn dùng cùng khóa đó để xác minh chữ ký có khớp không +- Khớp = 100% là Stripe gửi, không khớp = trực tiếp từ chối + +**Bước 5: Cập nhật cơ sở dữ liệu** + +Chỉ sau khi xác minh thành công, mới cập nhật cơ sở dữ liệu: +- Thay đổi trạng thái người dùng từ "Chờ thanh toán" thành "Đã thanh toán" +- Ghi lại số đơn hàng, số tiền, thời gian thanh toán +- Kích hoạt quyền hội viên tương ứng + +**Bước 6: Frontend truy vấn trạng thái** + +Trang success không nên tự kết luận "đến trang này là thành công". Cách làm đúng: +- Khi trang tải, gửi request đến backend: "Người dùng này đã thanh toán chưa?" +- Backend truy vấn cơ sở dữ liệu, trả về trạng thái thực tế +- Dựa trên kết quả trả về hiển thị "Kích hoạt thành công" hoặc "Đang chờ xác nhận" + +### Một cách làm sai phổ biến + +```javascript +// Sai: Kích hoạt trực tiếp trên trang success +// success.html +if (window.location.pathname === '/success') { + // Nguy hiểm! Bất kỳ ai cũng có thể truy cập /success + activateMembership(); +} +``` + +```javascript +// Đúng: Mỗi lần refresh đều truy vấn backend +// success.html +async function checkStatus() { + const response = await fetch('/api/user/status'); + const data = await response.json(); + + if (data.paymentStatus === 'paid') { + showMemberFeatures(); + } else { + showPendingMessage(); + } +} +``` + +### Tóm tắt trong một câu + +**Trang success chỉ là "chuyển trang trình duyệt thành công", Webhook mới là "Stripe chính thức xác nhận đã nhận tiền".** + +Hệ thống của bạn phải lấy Webhook làm chuẩn, không được tin chuyển trang frontend. + +## Phụ lục C: Các sự kiện đáng theo dõi nhất của hệ thống đăng ký + +| Sự kiện | Ý nghĩa | Bạn thường cần làm gì | +| :--- | :--- | :--- | +| `checkout.session.completed` | Kích hoạt lần đầu thành công | Tạo bản ghi đăng ký cục bộ | +| `invoice.paid` | Gia hạn tự động thành công | Gia hạn thời hạn | +| `invoice.payment_failed` | Trừ phí tự động thất bại | Đánh dấu trạng thái rủi ro và nhắc nhở người dùng | +| `customer.subscription.deleted` | Hủy đăng ký | Thu hồi quyền hoặc đánh dấu hết hạn | + +### Sơ đồ trạng thái đăng ký + +```mermaid +stateDiagram-v2 + [*] --> NotStarted: Người dùng chưa mua + NotStarted --> Active: checkout.session.completed + Active --> Active: invoice.paid + Active --> PastDue: invoice.payment_failed + PastDue --> Active: Người dùng bổ sung thanh toán thành công + Active --> Canceled: customer.subscription.deleted + PastDue --> Canceled: Hết hạn không khôi phục + Canceled --> [*] + + state "Chưa kích hoạt" as NotStarted + state "Hội viên có hiệu lực" as Active + state "Trừ phí thất bại / Chờ khôi phục" as PastDue + state "Đã hủy / Hết hạn thu hồi" as Canceled +``` + +### Sơ đồ thời gian gia hạn / thất bại / hủy + +```mermaid +sequenceDiagram + autonumber + participant Stripe as Stripe + participant Webhook as API Webhook của bạn + participant DB as Bảng đăng ký / Bảng đơn hàng + participant App as Ứng dụng của bạn + actor User as Người dùng + + rect rgb(235, 248, 255) + Stripe->>Webhook: invoice.paid + Webhook->>DB: Gia hạn current_period_end + DB-->>Webhook: Cập nhật thành công + Webhook-->>Stripe: 200 OK + App-->>User: Tiếp tục duy trì hội viên có hiệu lực + end + + rect rgb(255, 247, 237) + Stripe->>Webhook: invoice.payment_failed + Webhook->>DB: Đánh dấu past_due + DB-->>Webhook: Cập nhật thành công + Webhook-->>Stripe: 200 OK + App-->>User: Nhắc nhở cập nhật phương thức thanh toán + end + + rect rgb(254, 242, 242) + Stripe->>Webhook: customer.subscription.deleted + Webhook->>DB: Đánh dấu canceled + DB-->>Webhook: Cập nhật thành công + Webhook-->>Stripe: 200 OK + App-->>User: Dừng quyền cao cấp + end +``` + +## Phụ lục D: Cách chọn phương án thanh toán khác + +### 1. Trung Quốc đại lục + +Nếu người dùng chính ở đại lục, lựa chọn hàng đầu vẫn là **[Alipay](https://open.alipay.com/)** và **[WeChat Pay](https://pay.wechatpay.cn/)**. + +**Mô hình kinh doanh:** + +Cả hai đều là mô hình "cổng thanh toán". Bạn cần: +- Nộp hồ sơ merchant (giấy phép kinh doanh, tài khoản doanh nghiệp) +- Tiền người dùng thanh toán trực tiếp đến tài khoản merchant của bạn +- Bạn tự chịu trách nhiệm về thuế, hoàn tiền, đối soát + +**Mô hình kỹ thuật:** + +Cả hai đều là mô hình "backend đặt hàng + frontend gọi + backend thông báo", tư duy giống hệt Stripe. + +**Quy trình tích hợp Alipay:** +1. Tạo ứng dụng trên nền tảng mở Alipay +2. Cấu hình khóa công khai/riêng và địa chỉ callback +3. Backend gọi API đặt hàng thống nhất, tạo liên kết thanh toán hoặc mã QR +4. Người dùng quét mã hoặc chuyển trang thanh toán +5. Alipay thông báo bất đồng bộ cho backend của bạn, cập nhật trạng thái đơn hàng + +**Quy trình tích hợp WeChat Pay:** +- Thanh toán JSAPI: Phù hợp cho tài khoản chính thức, mini program, người dùng thanh toán trực tiếp trong WeChat +- Thanh toán Native: PC tạo mã QR, người dùng quét mã thanh toán +- Thanh toán H5: Trình duyệt điện thoại gọi WeChat App thanh toán + +Quy trình: Backend đặt hàng → Lấy `prepay_id` hoặc `code_url` → Frontend gọi thanh toán → Backend nhận thông báo xác nhận thành công + +**Liên kết tham khảo:** +- Nền tảng mở Alipay: https://open.alipay.com/ +- Tài liệu merchant WeChat Pay: https://pay.wechatpay.cn/doc/v3/merchant/ + +### 2. Hong Kong + +Thị trường Hong Kong khá pha trộn, tổ hợp phổ biến: + +- Thẻ ngân hàng: Visa / Mastercard +- FPS (Chuyển tiền nhanh): Chuyển khoản tức thời nội địa Hong Kong +- AlipayHK / WeChat Pay HK: Phiên bản Hong Kong của Alipay và WeChat + +**Tổ hợp khuyến nghị:** +- Dùng **[Stripe](https://stripe.com/hk)** để bao phủ thẻ quốc tế và đăng ký +- Dùng **[Airwallex](https://www.airwallex.com/)** hoặc **[Adyen](https://www.adyen.com/)** để bổ sung ví địa phương và FPS + +### 3. Nước ngoài / SaaS quốc tế + +#### [Stripe](https://stripe.com/) + +**Mô hình kinh doanh:** Cổng thanh toán + +- Bạn cần tự nộp hồ sơ merchant (ở một số quốc gia Stripe có thể giúp bạn xử lý) +- Tiền người dùng thanh toán đến tài khoản Stripe của bạn, sau đó thanh toán vào tài khoản ngân hàng của bạn +- Bạn tự chịu trách nhiệm khai báo thuế + +**Mô hình kỹ thuật:** + +- Trải nghiệm API tốt nhất, tài liệu rõ ràng +- Hỗ trợ Checkout (trang lưu trữ), Elements (form tùy chỉnh), Payment Links (không cần code) +- Webhook thông báo trạng thái thanh toán +- Hỗ trợ đăng ký, hóa đơn, đa loại tiền tệ + +**Phù hợp cho:** SaaS ở nước ngoài, nhà phát triển độc lập, đội ngũ cần tùy chỉnh linh hoạt + +**Liên kết tham khảo:** https://docs.stripe.com/ + +#### [PayPal](https://www.paypal.com/) + +**Mô hình kinh doanh:** Cổng thanh toán + +- Tiền người dùng thanh toán đến tài khoản PayPal của bạn, sau đó rút về ngân hàng +- Bạn tự chịu trách nhiệm về thuế + +**Mô hình kỹ thuật:** + +- Thanh toán một lần: Frontend đặt nút, backend tạo/xác nhận đơn hàng +- Đăng ký: Tạo Product và Plan trước, sau đó dùng SDK gọi +- Cũng cần backend và Webhook, đừng chỉ nhìn callback frontend + +**Phù hợp cho:** Kinh doanh ở nước ngoài cần bổ sung kênh, người dùng quen dùng PayPal thanh toán + +**Liên kết tham khảo:** https://developer.paypal.com/docs/ + +#### [Paddle](https://www.paddle.com/) + +**Mô hình kinh doanh:** Merchant of Record (MoR) + +- Paddle là "merchant ghi nhận", pháp lý Paddle thu tiền từ người dùng +- Paddle giúp bạn xử lý thuế toàn cầu, VAT, hoàn tiền, tuân thủ +- Tiền người dùng thanh toán đến Paddle, Paddle trừ phí thuế và phí dịch vụ rồi thanh toán cho bạn +- Bạn không cần đăng ký công ty ở mỗi quốc gia hoặc xử lý thuế + +**Mô hình kỹ thuật:** + +- Paddle.js: Nhúng trang thanh toán lưu trữ vào frontend +- Backend API: Tạo transaction, giao cho checkout xử lý +- Webhook đồng bộ trạng thái đăng ký + +**Phù hợp cho:** Đội ngũ SaaS không muốn xử lý thuế toàn cầu, đặc biệt là B2B SaaS + +**Liên kết tham khảo:** https://developer.paddle.com/ + +#### [Lemon Squeezy](https://www.lemonsqueezy.com/) + +**Mô hình kinh doanh:** Merchant of Record (MoR) + +- Tương tự Paddle, Lemon Squeezy là "merchant ghi nhận" +- Giúp bạn xử lý thuế toàn cầu, VAT, tuân thủ +- Năm 2024 được Stripe mua lại, nhưng vẫn hoạt động độc lập + +**Mô hình kỹ thuật:** + +- Hosted Checkout: Đơn giản nhất, trực tiếp tạo liên kết thanh toán +- Checkout Overlay: Lớp nổi nhúng vào trang của bạn +- Backend API: Tạo checkout, kiểm soát linh hoạt + +**Phù hợp cho:** Nhà phát triển độc lập, sản phẩm kỹ thuật số, giấy phép phần mềm + +**Liên kết tham khảo:** https://docs.lemonsqueezy.com/ + +### 4. Phương án doanh nghiệp + +#### [Airwallex](https://www.airwallex.com/) + +**Mô hình kinh doanh:** Cổng thanh toán + Tài khoản toàn cầu + +- Cung cấp tài khoản thu tiền toàn cầu (tương tự tài khoản ngân hàng ảo) +- Hỗ trợ thu tiền đa loại tiền tệ, đổi ngoại tệ, thanh toán +- Bạn tự chịu trách nhiệm về thuế + +**Mô hình kỹ thuật:** + +- Payment Links: Gần như không cần code, tạo liên kết thanh toán +- Hosted Payment Page: Trang lưu trữ +- Drop-in / Embedded / Native API: Tích hợp sâu, tùy chỉnh cao +- Hỗ trợ Alipay HK, FPS, WeChat Pay và các phương thức thanh toán nội địa khác + +**Phù hợp cho:** Đội ngũ Hong Kong, kinh doanh xuyên biên giới, công ty cần tài khoản đa loại tiền tệ + +**Liên kết tham khảo:** https://www.airwallex.com/docs/ + +#### [Adyen](https://www.adyen.com/) + +**Mô hình kinh doanh:** Cổng thanh toán + +- Nền tảng thanh toán cấp doanh nghiệp, volume giao dịch hàng năm hàng nghìn tỷ euro +- Hỗ trợ đầy đủ các kênh online, offline, mobile +- Bạn tự chịu trách nhiệm về thuế + +**Mô hình kỹ thuật:** + +- Pay by Link: Đơn giản nhất, tạo liên kết thanh toán +- Drop-in / Components: Tích hợp online tiêu chuẩn +- Backend có thể kích hoạt Alipay, Alipay HK, PayMe và các phương thức thanh toán nội địa khác + +**Phù hợp cho:** Doanh nghiệp lớn, công ty cần thanh toán đa kênh + +**Liên kết tham khảo:** https://docs.adyen.com/ + +### 5. So sánh phương án + +| Phương án | Mô hình kinh doanh | Xử lý thuế | Phù hợp cho | +| :--- | :--- | :--- | :--- | +| Stripe | Cổng thanh toán | Tự xử lý | SaaS ở nước ngoài, nhà phát triển | +| PayPal | Cổng thanh toán | Tự xử lý | Kênh bổ sung ở nước ngoài | +| Paddle | MoR | Paddle xử lý hộ | B2B SaaS, không muốn quản thuế | +| Lemon Squeezy | MoR | LS xử lý hộ | Nhà phát triển độc lập, sản phẩm kỹ thuật số | +| Adyen | Cổng thanh toán | Tự xử lý | Doanh nghiệp lớn | +| Airwallex | Cổng thanh toán + Tài khoản | Tự xử lý | Kinh doanh xuyên biên giới, đội ngũ Hong Kong | +| Alipay/WeChat Pay | Cổng thanh toán | Tự xử lý | Người dùng đại lục | + +### 6. Chọn phương án theo khu vực + +| Thị trường của bạn | Phương án khuyến nghị | +| :--- | :--- | +| Trung Quốc đại lục | Alipay / WeChat Pay | +| Hong Kong | Stripe + Airwallex / Adyen | +| SaaS ở nước ngoài | Stripe (tự quản thuế) hoặc Paddle (MoR quản hộ) | +| Sản phẩm kỹ thuật số ở nước ngoài | Stripe / Lemon Squeezy / Paddle | +| Đa khu vực cấp doanh nghiệp | Tổ hợp Adyen / Airwallex / Stripe | diff --git a/docs/vi-vn/stage-2/backend/zeabur-deployment/index.md b/docs/vi-vn/stage-2/backend/zeabur-deployment/index.md new file mode 100644 index 0000000..f0926fe --- /dev/null +++ b/docs/vi-vn/stage-2/backend/zeabur-deployment/index.md @@ -0,0 +1,490 @@ +# Cách triển khai ứng dụng Web + +Trong hướng dẫn này, chúng tôi sẽ giới thiệu cách triển khai ứng dụng Web của bạn lên Internet để người khác có thể truy cập. Chúng tôi sẽ giới thiệu ba nền tảng triển khai phổ biến: **Tencent CloudBase**, **Vercel** và **Zeabur**, giúp bạn nhanh chóng hoàn thành quy trình hoàn chỉnh từ "viết xong code" đến "để người khác có thể truy cập trang web của bạn trên Internet". + +# "Triển khai" là gì? + +Trước khi bắt đầu, chúng ta hãy tìm hiểu "Triển khai (Deployment)" thực chất có nghĩa là gì. Bất kỳ trang web nào muốn được người dùng bên ngoài truy cập đều phải có một địa chỉ mạng có thể truy cập công khai (địa chỉ này có thể là địa chỉ IP, ví dụ 123.45.67.89, hoặc một tên miền, ví dụ [google.com](https://google.com/)). Nhưng chỉ có địa chỉ là chưa đủ -- mã trang web bạn đã viết (ví dụ tệp HTML, CSS, JavaScript, hoặc dự án sử dụng React, Vue và các framework khác), cùng với các tài nguyên hình ảnh / video liên quan, đều phải được "đặt" trên một máy chủ trực tuyến 24 giờ, máy chủ này sẽ phản hồi các yêu cầu mạng, để trình duyệt của bất kỳ ai mới có thể truy cập và tải xuống các tài nguyên này. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image1.png) + +Nguồn hình ảnh: https://www.hostinger.com/tutorials/what-is-cloud-hosting + +Toàn bộ quá trình tải tài nguyên lên, cấu hình môi trường và làm cho dịch vụ "chạy được" được gọi là **Triển khai (Deployment)**. + +Nói một cách đơn giản: trang web bạn viết trên máy tính của mình, miễn là bạn chỉ khởi động chương trình cục bộ, thì bạn chỉ có thể truy cập qua địa chỉ cục bộ trên trình duyệt của mình, vì mã này chỉ tồn tại trên ổ cứng của bạn. "Triển khai" là việc chuyển mã và tài nguyên của bạn sang một máy chủ chuyên nghiệp được kết nối với mạng công cộng, và cấu hình sao cho máy chủ này biết "khi người khác truy cập, tôi cần phản hồi như thế nào" -- ví dụ: khi ai đó nhập tên miền của bạn trong trình duyệt, máy chủ sẽ ngay lập tức tìm tệp trang web tương ứng, truyền nội dung về thiết bị của họ, từ đó người dùng có thể nhìn thấy trang của bạn. + +Nếu triển khai thủ công, một dự án thường cần nhiều bước, mỗi bước đều có thể gặp vấn đề. Các bước chính thường bao gồm: + +1. **Chuẩn bị máy chủ**: Bạn cần mua máy chủ đám mây (ví dụ Alibaba Cloud, Tencent Cloud, hoặc AWS EC2), chọn khu vực đặt máy chủ (như Thượng Hải, Singapore), cấu hình (CPU, bộ nhớ, dung lượng ổ đĩa, v.v.), và học cách kết nối từ xa với máy chủ (ví dụ thông qua công cụ SSH). + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image2.png) +2. **Cấu hình môi trường**: Ứng dụng Web cần chạy trong một "môi trường" cụ thể -- ví dụ để chạy dự án Node.js, bạn phải cài đặt Node.js trước; để chạy dự án Python, bạn phải cài đặt Python và các thư viện bên thứ ba tương ứng. Nếu phiên bản môi trường không khớp, chương trình có thể báo lỗi và không thể khởi động. +3. **Tải tài nguyên lên**: Bạn cần tải mã và tài nguyên cục bộ lên máy chủ, các phương pháp phổ biến bao gồm FTP hoặc Git. Nếu dự án có dung lượng lớn (ví dụ chứa tệp video), nếu kết nối bị gián đoạn giữa chừng, đôi khi bạn phải tải lên lại từ đầu. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image3.png) + +4. **Khởi động dịch vụ và kiểm tra**: Sau khi tải lên xong, bạn cần thực thi lệnh khởi động ứng dụng trên máy chủ, và kiểm tra "địa chỉ mạng được phân phối có thể truy cập được không". Nếu không truy cập được, có thể tường lửa của máy chủ chưa mở cổng tương ứng (ví dụ ứng dụng của bạn lắng nghe cổng 3000, nhưng cổng này bị tường lửa chặn), hoặc chương trình có Bug, lúc này cần xem nhật ký máy chủ để khắc phục. + > Mẹo: Bạn có thể hiểu cổng (port) như "số phòng" để phân biệt các ứng dụng khác nhau trên cùng một thiết bị, còn IP là "số nhà" của thiết bị đó. IP và cổng kết hợp với nhau (IP:port) có thể định vị chính xác một dịch vụ mạng cụ thể. +5. **Bảo trì và cập nhật**: Mỗi lần bạn sửa mã sau này, bạn phải tải lên lại và khởi động lại dịch vụ. Nếu máy chủ gặp sự cố (ví dụ mất điện, lỗi mạng), bạn cần khởi động lại ứng dụng thủ công, đôi khi còn cần cấu hình thêm "công cụ quản lý tiến trình" để chương trình tự động khởi động lại khi thoát bất thường. + +Các nền tảng "triển khai mã thấp" như CloudBase, Vercel, Zeabur ra đời chính là để giải quyết các vấn đề phức tạp nói trên. Chúng sẽ giúp bạn tự động hoàn thành các bước "mua máy chủ, cấu hình môi trường, tải mã lên, khởi động dịch vụ, giám sát vận hành". Bạn chỉ cần kết nối kho mã (ví dụ GitHub hoặc GitLab) của mình với nền tảng, hoặc tải mã trực tiếp lên, nó sẽ tự động lấy mã, nhận dạng loại ứng dụng, cấu hình môi trường runtime tương ứng, và cuối cùng cung cấp cho bạn một địa chỉ mạng công cộng mà bất kỳ ai cũng có thể truy cập. Nó thậm chí có thể liên kết tên miền riêng của bạn chỉ bằng một cú nhấp. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image4.png) + +Tiếp theo, chúng tôi sẽ giới thiệu lần lượt đặc điểm và cách sử dụng của ba nền tảng này, giúp bạn chọn phương án triển khai phù hợp nhất với mình. + +--- + +# So sánh nền tảng triển khai + +| Nền tảng | Đặc điểm | Phù hợp cho | Gói miễn phí | +|------|------|----------|----------| +| **Tencent CloudBase** | Truy cập nhanh trong nước, tích hợp sâu với hệ sinh thái WeChat | Dự án hướng tới người dùng trong nước, cần hỗ trợ WeChat Mini Program | Có gói miễn phí | +| **Vercel** | Hỗ trợ tốt cho framework frontend, tích hợp chặt chẽ với GitHub | Dự án frontend hiện đại như React/Vue/Next.js | Có gói miễn phí | +| **Netlify** | Chức năng toàn diện, hỗ trợ xử lý biểu mẫu và xác thực, tích hợp tốt với Git | Trang web tĩnh cần xử lý biểu mẫu, xác thực và các tính năng nâng cao | Có gói miễn phí | +| **Zeabur** | Hỗ trợ nhiều ngôn ngữ và mẫu dịch vụ, cấu hình linh hoạt | Dự án phức tạp cần triển khai nhiều dịch vụ (như Dify, n8n) | Khoảng 5 USD miễn phí mỗi tháng | + +--- + +# 1. Tencent CloudBase + +Tencent CloudBase (Phát triển đám mây) là dịch vụ backend đám mây một cửa do Tencent Cloud cung cấp, đặc biệt phù hợp cho nhà phát triển trong nước. Ưu điểm của nó bao gồm: + +- **Truy cập nhanh trong nước**: Máy chủ đặt trong nước, độ trễ truy cập thấp +- **Tích hợp hệ sinh thái WeChat**: Có thể dễ dàng kết nối với WeChat Mini Program, Official Account +- **Giải pháp một cửa**: Cung cấp dịch vụ đầy đủ bao gồm lưu trữ trang web tĩnh, hàm đám mây, cơ sở dữ liệu, lưu trữ, v.v. +- **Gói miễn phí dồi dào**: Nhà phát triển cá nhân có đủ tài nguyên miễn phí + +## Sử dụng CloudBase để triển khai ứng dụng Web + +### Bước 1: Đăng ký và đăng nhập + +Truy cập [Tencent CloudBase Console](https://console.cloud.tencent.com/tcb), đăng nhập bằng WeChat hoặc QQ. + +### Bước 2: Tạo môi trường + +Nhấp vào "Tạo môi trường mới", chọn tên môi trường (ví dụ `my-web-app`). + +> **Lưu ý**: Phiên bản dùng thử miễn phí của CloudBase cần mã đổi để kích hoạt. Bạn cần theo dõi tài khoản công cộng Tencent CloudBase, nhập "nhận mã đổi" trong tài khoản công cộng để lấy mã đổi phiên bản dùng thử miễn phí, sau đó điền mã đổi khi tạo môi trường để kích hoạt môi trường miễn phí (thời gian dùng thử miễn phí là 6 tháng). + +### Bước 3: Kích hoạt lưu trữ trang web tĩnh + +Trong trang quản lý môi trường, tìm chức năng "Lưu trữ trang web tĩnh" và kích hoạt. Sau khi kích hoạt, bạn sẽ nhận được một tên miền truy cập mặc định. + +Lưu trữ trang web tĩnh của CloudBase cung cấp nhiều phương pháp triển khai, tương tự như Zeabur: + +- **Tải dự án cục bộ lên**: Tải trực tiếp các tệp tĩnh đã xây dựng (HTML, CSS, JS, v.v.) từ máy cục bộ +- **Triển khai bằng mẫu**: Sử dụng các mẫu có sẵn để tạo dự án nhanh chóng, như mẫu ứng dụng React Web, mẫu ứng dụng Vue Web +- **Triển khai từ kho Git**: Hỗ trợ tự động lấy mã từ các kho mã như GitHub và triển khai + +### Bước 4: Triển khai mã + +Trong trang lưu trữ trang web tĩnh, CloudBase cung cấp ba phương pháp triển khai: + +**Phương pháp 1: Triển khai dự án cục bộ (Tải dự án cục bộ lên)** +- Chọn "Triển khai dự án cục bộ" trong bảng điều khiển +- Tải trực tiếp các tệp tĩnh đã xây dựng (HTML, CSS, JS, v.v.) +- Chọn thư mục dự án đã xây dựng trên máy (như thư mục `dist` hoặc `build`) +- Đợi tải lên hoàn tất để truy cập + +**Phương pháp 2: Triển khai bằng mẫu** +- Sử dụng các mẫu có sẵn để tạo dự án nhanh chóng +- Hỗ trợ mẫu ứng dụng React Web, mẫu ứng dụng Vue Web, v.v. +- Xây dựng và triển khai tự động dựa trên mẫu + +**Phương pháp 3: Triển khai từ kho Git** +- **Triển khai kho cá nhân Git**: Liên kết kho mã GitHub cá nhân của bạn +- **Triển khai kho công khai**: Hỗ trợ lấy mã từ kho Git công khai +- Cấu hình lệnh xây dựng tự động (như `npm run build`) +- Mỗi lần đẩy mã sẽ tự động triển khai lại + +> **Mẹo**: Bạn cũng có thể sử dụng công cụ CLI để triển khai: +> ```bash +> # Cài đặt CloudBase CLI +> npm install -g @cloudbase/cli +> # Đăng nhập +> tcb login +> # Triển khai +> tcb hosting deploy ./dist -e your-env-id +> ``` + +### Bước 5: Cấu hình tên miền tùy chỉnh (tùy chọn) + +Trong cài đặt lưu trữ trang web tĩnh, bạn có thể liên kết tên miền riêng của mình và xin chứng chỉ HTTPS miễn phí. + +--- + +# 2. Vercel + +Vercel là một trong những nền tảng triển khai frontend phổ biến nhất thế giới, đặc biệt phù hợp để triển khai các dự án sử dụng React, Vue, Next.js và các framework frontend hiện đại khác. Đặc điểm của nó bao gồm: + +- **Tích hợp sâu với GitHub**: Đẩy mã là tự động triển khai +- **Xem trước tự động**: Mỗi Pull Request sẽ tạo một liên kết xem trước độc lập +- **CDN toàn cầu**: Trang web tự động phân phối đến các nút toàn cầu, tốc độ truy cập nhanh +- **Hàm Serverless**: Hỗ trợ viết API backend trong dự án + +> **Lưu ý**: Vercel có thể truy cập không ổn định trong một số môi trường mạng, người dùng trong nước nên ưu tiên CloudBase. + +## Sử dụng Vercel để triển khai ứng dụng Web + +### Bước 1: Đăng ký tài khoản + +Truy cập [Vercel chính thức](https://vercel.com), đăng nhập bằng tài khoản GitHub. + +### Bước 2: Nhập dự án + +1. Nhấp vào "Add New Project" +2. Chọn kho GitHub bạn muốn triển khai +3. Nếu không thấy kho bạn muốn, nhấp vào "Adjust GitHub App Permissions" để cấp quyền truy cập + +### Bước 3: Cấu hình cài đặt xây dựng + +Vercel sẽ tự động nhận dạng loại dự án và cấu hình lệnh xây dựng: + +| Framework | Lệnh xây dựng | Thư mục đầu ra | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Next.js | `next build` | - | +| HTML thuần | - | Thư mục gốc dự án | + +Nếu nhận dạng tự động không chính xác, bạn có thể sửa thủ công: +- **Build Command**: Lệnh xây dựng, ví dụ `npm run build` +- **Output Directory**: Thư mục đầu ra xây dựng, ví dụ `dist` hoặc `build` +- **Install Command**: Lệnh cài đặt dependency, thường là `npm install` + +### Bước 4: Triển khai + +Nhấp vào nút "Deploy", đợi xây dựng hoàn tất. Sau khi xây dựng thành công, bạn sẽ nhận được tên miền `xxx.vercel.app`. + +### Bước 5: Tên miền tùy chỉnh (tùy chọn) + +Trong trang "Domains" của cài đặt dự án, bạn có thể thêm tên miền riêng. Vercel sẽ tự động cấu hình HTTPS. + +--- + +# 3. Netlify + +Netlify là một nền tảng triển khai frontend rất phổ biến khác, tương tự như Vercel, đặc biệt phù hợp để triển khai trang web tĩnh và ứng dụng đơn trang (SPA). Đặc điểm của nó bao gồm: + +- **Chức năng toàn diện**: Ngoài lưu trữ trang web tĩnh, còn hỗ trợ xử lý biểu mẫu, xác thực, hàm edge, v.v. +- **Tích hợp sâu với Git**: Hỗ trợ GitHub, GitLab, Bitbucket, đẩy mã là tự động triển khai +- **Xem trước theo nhánh**: Mỗi nhánh sẽ tự động tạo liên kết xem trước độc lập +- **CDN toàn cầu**: Trang web tự động phân phối đến các nút toàn cầu, tốc độ truy cập nhanh +- **Xử lý biểu mẫu**: Xử lý gửi biểu mẫu trang web mà không cần code backend +- **Xác thực**: Chức năng xác thực người dùng tích hợp, có thể nhanh chóng thực hiện đăng nhập/đăng ký + +> **Lưu ý**: Tốc độ truy cập Netlify trong nước có thể không bằng CloudBase, nên sử dụng chủ yếu cho các dự án hướng tới người dùng ở nước ngoài. + +## Sử dụng Netlify để triển khai ứng dụng Web + +### Bước 1: Đăng ký tài khoản + +Truy cập [Netlify chính thức](https://www.netlify.com), nhấp vào "Sign up" để đăng ký. Bạn có thể sử dụng GitHub, GitLab, Bitbucket hoặc email để đăng ký. + +### Bước 2: Nhập dự án + +1. Sau khi đăng nhập, nhấp vào "Add new site" -> "Import an existing project" +2. Chọn nền tảng lưu trữ mã của bạn (ví dụ GitHub) +3. Cấp quyền cho Netlify truy cập kho của bạn +4. Chọn kho bạn muốn triển khai từ danh sách + +### Bước 3: Cấu hình cài đặt xây dựng + +Netlify sẽ tự động nhận dạng các framework frontend phổ biến và cấu hình cài đặt xây dựng: + +| Framework | Lệnh xây dựng | Thư mục xuất bản | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Angular | `ng build` | `dist/` | +| Next.js | `next build` | `out` | +| HTML thuần | - | `.` (thư mục gốc dự án) | + +Nếu nhận dạng tự động không chính xác, bạn có thể cấu hình thủ công: +- **Build command**: Lệnh xây dựng, ví dụ `npm run build` +- **Publish directory**: Thư mục đầu ra xây dựng, ví dụ `dist` hoặc `build` + +### Bước 4: Triển khai + +Nhấp vào nút "Deploy site", đợi xây dựng hoàn tất. Sau khi xây dựng thành công, bạn sẽ nhận được tên miền `xxx.netlify.app`, bất kỳ ai cũng có thể truy cập trang web của bạn qua địa chỉ này. + +### Bước 5: Cấu hình tên miền tùy chỉnh (tùy chọn) + +1. Vào cài đặt trang, nhấp vào "Domain management" +2. Nhấp vào "Add custom domain" +3. Nhập tên miền của bạn và làm theo hướng dẫn cấu hình bản ghi DNS +4. Netlify sẽ tự động xin và cấu hình chứng chỉ HTTPS + +### Tính năng đặc biệt + +#### 1. Xử lý biểu mẫu + +Netlify cung cấp một tính năng rất tiện lợi: xử lý gửi biểu mẫu mà không cần code backend. + +Chỉ cần thêm thuộc tính `netlify` vào biểu mẫu HTML: + +```html +
+

+ +

+

+ +

+

+ +

+

+ +

+
+``` + +Sau khi triển khai, dữ liệu gửi biểu mẫu sẽ tự động được gửi đến bảng điều khiển Netlify, bạn có thể xem tất cả bản ghi đã gửi trong trang "Forms", cũng có thể thiết lập thông báo email hoặc chuyển tiếp dữ liệu đến dịch vụ khác. + +#### 2. Netlify Functions (hàm edge) + +Netlify hỗ trợ triển khai hàm Serverless, cho phép bạn thực hiện các API đơn giản mà không cần xây dựng máy chủ backend đầy đủ. Bạn có thể viết hàm bằng JavaScript hoặc TypeScript, sau khi triển khai sẽ tự động nhận được một URL có thể truy cập. + +Ví dụ, tạo một tệp `hello.js`: + +```javascript +exports.handler = async (event, context) => { + return { + statusCode: 200, + body: JSON.stringify({ message: "Hello from Netlify!" }) + }; +}; +``` + +Sau khi triển khai, bạn có thể truy cập hàm này qua `https://your-domain/.netlify/functions/hello`. + +#### 3. Hỗ trợ phát triển cục bộ + +Netlify cung cấp công cụ CLI, giúp bạn phát triển và kiểm tra tại máy cục bộ: + +```bash +# Cài đặt Netlify CLI +npm install -g netlify-cli + +# Đăng nhập tài khoản +netlify login + +# Khởi động máy chủ phát triển cục bộ +netlify dev + +# Kiểm tra hàm cục bộ +netlify functions:serve +``` + +Sử dụng công cụ CLI có thể mô phỏng môi trường Netlify tại máy cục bộ, bao gồm gửi biểu mẫu, gọi hàm, v.v., giúp kiểm tra trước khi triển khai. + +--- + +# 4. Zeabur + +Zeabur là một nền tảng triển khai mới nổi, đặc biệt phù hợp cho các dự án phức tạp cần triển khai nhiều dịch vụ. Ưu điểm của nó bao gồm: + +- **Mẫu dịch vụ phong phú**: Tích hợp sẵn nhiều mẫu dịch vụ như Dify, n8n, cơ sở dữ liệu, v.v. +- **Hỗ trợ nhiều phương pháp triển khai**: GitHub, mẫu, Docker image, dự án cục bộ, v.v. +- **Kết hợp dịch vụ linh hoạt**: Có thể triển khai nhiều dịch vụ liên quan nhau trong một dự án +- **Tính phí theo lượng sử dụng**: Trả bao nhiêu dùng bấy nhiêu, phù hợp cho dự án thử nghiệm + +## Sử dụng Zeabur để triển khai Dify + +Trong các khóa học trước, chúng ta đã tiếp xúc đơn giản với Dify. Bây giờ, chúng ta có thể khởi động dịch vụ Dify riêng rất dễ dàng thông qua [Zeabur](https://zeabur.com/projects). Đầu tiên, mở [trang bảng điều khiển](https://zeabur.com/projects), hãy xem các khu vực trên trang. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image5.png) + +Trên trang này, điều đầu tiên bạn thấy là nhiều ô vuông, đây là các dịch vụ đã được khởi động. Trong menu phía trên, bạn sẽ thấy các tùy chọn Agent, Servers, Docs, Templates, chúng lần lượt đại diện cho: + +1. **Agent**: Có thể mở trợ lý thông minh (Agent) tích hợp sẵn của Zeabur, hỏi nó cách thao tác, hoặc truy vấn trạng thái máy chủ hiện tại. +2. **Servers**: Ở đây bạn có thể thêm máy chủ đám mây đã mua, hoặc mua máy chủ trực tiếp qua Zeabur. +3. **Docs**: Xem tài liệu hướng dẫn đầy đủ của Zeabur. +4. **Templates**: Liệt kê tất cả các mẫu image tích hợp sẵn. + +> "Image" (ảnh) được đề cập ở đây có thể hiểu là "gói nén chứa mã và môi trường chạy". Khi một dịch vụ đã chạy thành công trên một máy chủ, chúng ta có thể chọn đóng gói "môi trường chạy + mã" thành image. Sau đó, trên bất kỳ máy chủ mới nào, chỉ cần giải nén và chạy gói này, không cần cấu hình lại môi trường và mã, dịch vụ có thể chạy ngay. + +Ở góc phải phía trên trang, bạn cũng có thể thấy số dư của mình. Theo mặc định, mỗi tháng sẽ có khoảng 5 USD miễn phí. Về quy tắc tính phí chi tiết, bạn có thể tạm thời không cần quan tâm quá nhiều, chỉ cần biết: miễn là máy chủ đang chạy, sẽ tiêu tốn额度. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image6.png) + +Nhấp vào số dư để xem chi tiết tiêu thụ hàng ngày. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image7.png) + +Bây giờ chúng ta sẽ tạo dịch vụ Dify riêng. Đầu tiên, tại [trang chủ bảng điều khiển](https://zeabur.com/projects), nhấp vào "New Project". + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image8.png) + +Tiếp theo là giải thích về các phương pháp tạo: + +1. **GitHub** + Có thể kết nối với tài khoản GitHub của bạn. Sau khi liên kết, bạn có thể chọn trực tiếp dự án từ kho GitHub để triển khai (GitHub là nền tảng lưu trữ mã lớn nhất thế giới hiện nay). +2. **Template (mẫu)** + Có thể triển khai dịch vụ dựa trên mẫu. Zeabur tích hợp nhiều mẫu dự án có sẵn (ví dụ Dify, n8n, v.v.), bạn có thể tạo và triển khai ứng dụng nhanh chóng dựa trên các mẫu này. + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image9.png) +3. **Databases (cơ sở dữ liệu)** + Dùng để triển khai dịch vụ cơ sở dữ liệu, như MySQL, MongoDB và các cơ sở dữ liệu phổ biến khác. + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image10.png) +4. **Functions (hàm)** + Có thể triển khai dịch vụ hàm, bạn có thể viết mã JavaScript hoặc Python, để chúng được gọi dưới dạng hàm. + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image11.png) + + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image12.png) + +5. **Local Project (dự án cục bộ)** + Tải lên một thư mục cục bộ, Zeabur sẽ tự động nhận dạng script khởi động trong đó. Phù hợp để nhanh chóng triển khai dự án đã phát triển cục bộ lên Zeabur. + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image13.png) +6. **Docker Image** + Triển khai Docker image đã đóng gói. Nếu dự án của bạn đã được đóng gói thành Docker image (ví dụ lưu trữ trên Docker Hub hoặc kho image khác), có thể triển khai trực tiếp tại đây. + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image14.png) +7. **Cursor** + Nếu bạn đã cài đặt Cursor (ví dụ Cursor IDE), có thể triển khai trực tiếp dự án trong Cursor lên Zeabur qua cổng này. + +Nếu bạn muốn triển khai dịch vụ Dify riêng, nên chọn phương thức **Template**, sau đó nhập "dify" vào ô tìm kiếm. Bạn sẽ thấy nhiều phiên bản do các tác giả khác nhau bảo trì, có thể chọn bất kỳ phiên bản nào (ví dụ phiên bản v1.6.0). + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image15.png) + +Tiếp theo, nhập bất kỳ tên nào, Zeabur sẽ tạo một tên miền tùy chỉnh tạm thời dựa trên tên này. Sau đó tất cả mọi người đều có thể truy cập dịch vụ của bạn qua địa chỉ web này. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image16.png) + +Sau khi tạo xong, bạn sẽ thấy nhiều chương trình (dịch vụ) khởi động lần lượt. Cần kiên nhẫn đợi tất cả dịch vụ vào trạng thái "đã khởi động". (Dịch vụ Dify được cấu thành từ nhiều chương trình, mỗi chương trình chịu trách nhiệm các chức năng khác nhau, chúng sẽ phối hợp với nhau.) + +Thông thường, bạn chỉ cần nhấp vào ứng dụng Dify bên trái để xem địa chỉ truy cập mặc định. Nhưng trong ví dụ này, vì phía trước còn có một lớp nginx, bạn cần nhấp vào dịch vụ nginx để lấy địa chỉ truy cập cuối cùng. Có thể hiểu: nginx là chương trình chính chịu trách nhiệm "nhận và gửi yêu cầu" đối ngoại thống nhất, nó sẽ phân phối địa chỉ truy cập bên ngoài cho các dịch vụ nội bộ khác. Nhấp vào Nginx bên trái, trong trang chi tiết bạn có thể thấy địa chỉ dịch vụ hiện tại, sau đó mở địa chỉ này trong trình duyệt, đợi dịch vụ khởi động hoàn toàn. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image17.png) + +Sau khi đợi một lát, bạn sẽ thấy giao diện đăng nhập Dify. Nhập địa chỉ email và mật khẩu đăng ký, bạn có thể bắt đầu sử dụng dịch vụ Dify riêng của mình. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image18.png) + +Nếu bạn quan tâm, bạn cũng có thể khởi động dịch vụ n8n. n8n cũng là một nền tảng quy trình làm việc AI rất phổ biến ở nước ngoài. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image19.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image20.png) + +## Sử dụng Zeabur và Trae để triển khai trò chơi rắn ăn mồi + +Trong phần tiếp theo của hướng dẫn này, chúng ta sẽ trải nghiệm một số cách sử dụng nâng cao của Zeabur. Đầu tiên, chúng ta sẽ dùng Trae để tạo một trò chơi rắn ăn mồi nhỏ, sau đó triển khai nó lên máy chủ Zeabur, và cấu hình một liên kết có thể truy cập công khai, để bất kỳ ai cũng có thể mở trò chơi của bạn. + +Bước đầu tiên là tạo một dự án rắn ăn mồi bằng Trae tại máy cục bộ. + +### Sử dụng framework HTML + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image23.png) + +Đối với Trae, việc tạo một trò chơi web rắn ăn mồi dựa trên HTML rất đơn giản. Sau khi trò chơi được tạo, bạn chỉ cần tải thư mục chứa tất cả các tệp lên theo cách triển khai cục bộ Zeabur đã giới thiệu trước đó. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image24.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image25.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image26.png) + +Sau khi hoàn tất, bạn sẽ vào giao diện chi tiết của dịch vụ: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image27.png) + +Nhấp vào tùy chọn "Network" bên trái, tìm khu vực "Public Address" trong trang. Nhấp vào "Generate Domain", có thể tạo một địa chỉ truy cập đối ngoại, bạn có thể nhập bất kỳ tên nào bạn thích. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image28.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image29.png) + +Sau khi tạo xong, chỉ cần mở địa chỉ này trong trình duyệt, bạn có thể chạy trò chơi rắn ăn mồi của riêng mình. Các ứng dụng Web kiểu HTML khác cũng có thể được triển khai theo cùng một cách. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image30.png) + +### Sử dụng framework React + +Trước đó chúng ta đã học cách triển khai ứng dụng Web dựa trên HTML. Tiếp theo, chúng ta sẽ thử triển khai một framework frontend phổ biến hơn hiện nay: ứng dụng React. So với HTML thuần, React được coi là một framework phát triển frontend trưởng thành và hiện đại hơn. Nó tổ chức cấu trúc trang theo cách component hóa, có thể tăng tốc độ phát triển trang phức tạp đáng kể, là lựa chọn rất phổ biến trong các dự án cấp doanh nghiệp. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image31.png) + +#### Tái cấu trúc thành kiến trúc React + +Trong Trae, bạn chỉ cần nói với Agent: "Hãy giúp tôi tái cấu trúc mã này thành kiến trúc React", là có thể khá dễ dàng chuyển đổi cấu trúc dựa HTML thành dự án React. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image32.png) + +Tuy nhiên, so với tệp HTML đơn giản, ứng dụng React phụ thuộc vào công cụ xây dựng và cấu trúc dự án phức tạp hơn, nên quá trình triển khai cũng sẽ hơi phức tạp hơn một chút. Một vấn đề điển hình thể hiện ở cài đặt cổng: theo mặc định, ứng dụng React thường lắng nghe cổng 3000 (bạn cũng có thể thấy điều này trong tệp cấu hình hoặc nhật ký khởi động). + +Tuy nhiên, triển khai trên Zeabur như vậy sẽ thất bại -- vì Zeabur chỉ hỗ trợ ứng dụng lắng nghe cổng 8080. Nghĩa là, nếu muốn ứng dụng React chạy bình thường trên Zeabur, chúng ta phải thay đổi cổng lắng nghe mặc định từ 3000 thành 8080. + +Để cấu hình đúng bước này, chúng ta cần làm rõ hai khái niệm trước: "cổng (Port)" là gì, và "cổng lắng nghe (Listening Port)" có nghĩa là gì. + +#### Cổng là gì? + +> Trong mạng máy tính, cổng có thể hiểu là một "điểm cuối giao tiếp logic", dùng để phân biệt các dịch vụ mạng khác nhau đang chạy trên cùng một thiết bị. Nếu ví địa chỉ IP như một "số nhà" (ví dụ 162.128.1.1), thì số cổng giống như "số phòng" của các phòng khác nhau trong tòa nhà đó -- mỗi phòng tương ứng với một dịch vụ (ví dụ máy chủ Web, dịch vụ email, hoặc ứng dụng React của bạn). +> +> Số cổng được biểu diễn bằng số nguyên 16 bit, phạm vi giá trị từ 0 đến 65535. + +Nếu không muốn nhớ các chi tiết này, có thể hiểu đơn giản: cổng là một phần cần thiết cấu thành "địa chỉ truy cập mạng". + +Khi chúng ta truy cập trang web hoặc địa chỉ IP, thường không tự thêm số cổng, là vì cổng mặc định của Web là 80 hoặc 443 (HTTPS). Hầu hết trình duyệt sẽ tự động sử dụng các cổng tiêu chuẩn này. Đối với một số cổng đặc biệt, như cổng 3000 mặc định của React, cổng 8080 yêu cầu của Zeabur, chúng ta phải thêm `:3000` hoặc `:8080` sau địa chỉ để truy cập nội dung tương ứng. + +#### "Cổng lắng nghe" là gì? + +> "Cổng lắng nghe" là cổng mà một chương trình chủ động "mở và giám sát" trên một thiết bị. Khi một ứng dụng đặt cổng lắng nghe, thực chất là đang nói với hệ điều hành: "Tôi sẽ luôn đợi yêu cầu mạng trên cổng này -- miễn là có yêu cầu đến, xin hãy chuyển tiếp cho tôi." + +Hiểu theo cách hình tượng hơn: giả sử máy tính của bạn là một tòa nhà văn phòng, địa chỉ IP là địa chỉ của tòa nhà. Trong tòa nhà có nhiều công ty hoặc phòng ban, chúng chiếm các phòng khác nhau, số phòng chính là số cổng. + +Khi máy chủ phát triển React mặc định khởi động, nó sẽ "mở" cửa một phòng nào đó, và bố trí "lễ tân" trực tại cửa, số phòng này chính là cổng lắng nghe của nó -- 3000. + +Đồng thời, chương trình React cũng sẽ nói với "quản lý tài sản" (hệ điều hành) của tòa nhà: "Tôi ở phòng 3000, xin hãy chuyển tất cả thư gửi đến phòng 3000 (yêu cầu mạng) cho tôi." + +Như vậy, khi bạn truy cập trang web React, yêu cầu đầu tiên sẽ đến tòa nhà; quản lý thấy yêu cầu cần gửi đến phòng 3000, sẽ ngay lập tức chuyển yêu cầu cho "lễ tân" của React, do nó xử lý và trả kết quả -- đây là quá trình truy cập ứng dụng React. + +Khi bạn thực thi `npm start` tại máy cục bộ (lệnh mặc định để khởi động máy chủ phát triển React cục bộ, cũng có thể thực thi trong thanh bên Agent của Vibe Coding), máy chủ phát triển React sẽ tự động đặt cổng lắng nghe thành 3000. +Thiết kế nền tảng Zeabur quyết định nó chỉ sẽ "nhận dạng" ứng dụng lắng nghe cổng 8080. Nếu ứng dụng React của bạn vẫn sử dụng cổng 3000 mặc định, Zeabur sẽ không thể chuyển tiếp yêu cầu chính xác đến ứng dụng của bạn, cuối cùng dẫn đến triển khai thất bại. + +#### Thay đổi cổng lắng nghe mặc định + +Để thay đổi cổng lắng nghe mặc định của React (3000) thành 8080 như Zeabur yêu cầu, có nhiều cách. Cách đơn giản nhất là trực tiếp ra lệnh cho Agent trong Trae: "Hãy giúp tôi thay đổi cổng mặc định của dự án React này thành 8080." Trae sẽ giúp bạn sửa tệp cấu hình tương ứng trong dự án. Sau khi sửa xong, bạn chỉ cần đóng gói lại và tải lên Zeabur theo cách trước đó. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image33.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image34.png) + +Trong cài đặt mạng, chỉ định một URL truy cập, cách làm về cơ bản giống với khi triển khai dự án HTML, là có thể khởi động dịch vụ phiên bản React. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image35.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image36.png) + +Đối với các chương trình khác cần thay đổi số cổng, bạn cũng có thể áp dụng cùng một cách tiếp cận: thay cổng mặc định trước, sau đó tải lên Zeabur để triển khai. Đến đây, bạn đã nắm vững kỹ năng cơ bản để triển khai ứng dụng Web phổ biến lên máy chủ. + +Bạn có thể thử để Trae giúp bạn xây dựng các ứng dụng loại khác nhau, và triển khai chúng lên máy chủ mặc định của Zeabur. Trong các bài học tiếp theo, chúng ta sẽ học cách triển khai ứng dụng lên máy chủ đám mây do chính bạn mua. + +--- + +# Cách dừng và xóa dự án (Zeabur) + +Vì việc kích hoạt tài nguyên liên quan đến máy chủ sẽ phát sinh chi phí, chúng ta phải hình thành thói quen "đóng dịch vụ không sử dụng kịp thời" khi sử dụng, tránh tiêu hết gói miễn phí hàng tháng. + +Nếu muốn tìm cổng quản lý dự án, đầu tiên nhấp vào "Settings" trong dự án. + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image21.png) + +Sau khi vào trang cài đặt, kéo trang xuống dưới cùng, bạn sẽ thấy giao diện tương tự: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image22.png) + +Bạn có thể nhấp vào "Suspend All Services" để tạm dừng tất cả dịch vụ nhằm giảm chi phí; nếu dịch vụ gặp vấn đề, có thể nhấp vào "Restart All Services" để khởi động lại tất cả dịch vụ. Nếu bạn chắc chắn không cần dự án này nữa, có thể nhấp vào "Delete Project" để xóa hoàn toàn dự án. + +--- + +# Tổng kết + +Trong hướng dẫn này, chúng tôi đã giới thiệu bốn nền tảng triển khai ứng dụng Web phổ biến: + +1. **Tencent CloudBase**: Phù hợp cho người dùng trong nước, tốc độ truy cập nhanh, tích hợp tốt với hệ sinh thái WeChat +2. **Vercel**: Phù hợp cho dự án sử dụng framework frontend hiện đại, tích hợp chặt chẽ với GitHub, CDN toàn cầu +3. **Netlify**: Chức năng toàn diện, hỗ trợ xử lý biểu mẫu và xác thực, phù hợp cho trang web tĩnh cần tính năng nâng cao +4. **Zeabur**: Phù hợp cho dự án phức tạp, mẫu dịch vụ phong phú, hỗ trợ nhiều phương pháp triển khai + +Chọn nền tảng nào phụ thuộc vào nhu cầu cụ thể của bạn: +- Nếu chủ yếu hướng tới người dùng trong nước, nên chọn **CloudBase** +- Nếu sử dụng React/Next.js và các framework, nên chọn **Vercel** hoặc **Netlify** +- Nếu cần xử lý biểu mẫu, xác thực và các tính năng nâng cao, nên chọn **Netlify** +- Nếu cần triển khai Dify, n8n và các dịch vụ khác, nên chọn **Zeabur** + +Bất kể chọn nền tảng nào, quy trình cốt lõi của triển khai đều tương tự: chuẩn bị mã -> chọn nền tảng -> cấu hình cài đặt xây dựng -> triển khai lên mạng. Sau khi nắm vững các kỹ năng này, bạn có thể chia sẻ ứng dụng đã phát triển với cả thế giới! diff --git a/docs/vi-vn/stage-2/frontend/design-to-code/index.md b/docs/vi-vn/stage-2/frontend/design-to-code/index.md new file mode 100644 index 0000000..770cb8c --- /dev/null +++ b/docs/vi-vn/stage-2/frontend/design-to-code/index.md @@ -0,0 +1,361 @@ +# Từ nguyên mẫu thiết kế đến code dự án + +::: tip 🎯 Vấn đề cốt lõi +**Làm thế nào để chuyển nguyên mẫu từ công cụ thiết kế thành code frontend thực sự có thể chạy trong trình duyệt?** +::: + +--- + +## 1. Ba con đường từ nguyên mẫu đến code + +Sau khi hoàn thành thiết kế giao diện bằng các công cụ thiết kế frontend hiện đại như Figma, MasterGo, một câu hỏi rất thực tế tự nhiên xuất hiện: làm thế nào để chuyển những bản thiết kế có cấu trúc hoàn chỉnh này thành code frontend thực sự có thể chạy trong trình duyệt? + +Nói chung, việc chuyển từ nguyên mẫu đến code có ba con đường điển hình: + +| Con đường | Phương pháp | Đặc điểm | Kịch bản phù hợp | +|-----------|-------------|----------|------------------| +| **Con đường 1** | Dựa trên hình ảnh, sử dụng mô hình đa phương thức lớn để trực tiếp khôi phục code | Linh hoạt, không cần công cụ cụ thể | Xác minh nguyên mẫu nhanh, trang đơn giản | +| **Con đường 2** | Xuất code sử dụng được thông qua khả năng của nền tảng hoặc plugin | Độ khôi phục cao, khả năng chỉnh sửa mạnh | Người dùng Figma/MasterGo | +| **Con đường 3** | Nền tảng kết hợp khả năng MCP để xuất code sử dụng được | Mức độ tự động hóa cao, có thể tùy chỉnh | Quy trình làm việc cần tích hợp sâu | + +Bài viết này sẽ giới thiệu chi tiết phương pháp thực hiện cụ thể của ba con đường này, giúp bạn chọn quy trình làm việc phù hợp nhất theo nhu cầu dự án. + +::: tip 📚 Kiến thức tiên quyết +Trước khi bắt đầu phần này, khuyến nghị bạn học trước hướng dẫn [Giới thiệu Figma và MasterGo](../figma-mastergo/), nắm vững các thao tác cơ bản của công cụ thiết kế frontend. +::: + +--- + +## 2. Con đường 1: AI đa phương thức trực tiếp khôi phục code + +Các mô hình_large có khả năng thị giác vốn sẵn có khả năng chuyển ảnh thành code. Chúng ta chỉ cần import screenshot bản thiết kế trực tiếp vào hộp thoại, sau đó để mô hình_large tạo code kết quả hoàn chỉnh. + +### 2.1 Quy trình thao tác + +1. **Chụp screenshot bản thiết kế** + - Trong Figma hoặc MasterGo, xuất trang đã thiết kế thành PNG hoặc JPG + - Đảm bảo screenshot bao gồm bố cục trang hoàn chỉnh + +2. **Chọn mô hình AI đa phương thức** + - Có thể sử dụng các mô hình hỗ trợ đầu vào hình ảnh như Gemini, Qwen, Claude + - Ở đây lấy Gemini làm ví dụ demo + +3. **Viết prompt** + ``` + Xin tạo code HTML/CSS tương ứng dựa trên bản thiết kế này. + Yêu cầu: + - Sử dụng layout CSS hiện đại (Flexbox/Grid) + - Responsive design, thích ứng các kích thước màn hình khác nhau + - Bao gồm tất cả các yếu tố UI nhìn thấy được + - Màu sắc, kích thước font cố gắng khôi phục theo bản thiết kế + ``` + +![](/zh-cn/stage-2/frontend/design-to-code/images/image42.png) + +4. **Lấy và lưu code** + - Yêu cầu mô hình trả về code HTML hoàn chỉnh + - Lưu thành file `.html` đơn lẻ, thuận tiện kiểm thử cục bộ + - Sau đó có thể chuyển đổi thành các framework như React trong IDE cục bộ + +### 2.2 Các vấn đề phổ biến và giải pháp + +Tạo trang không phải là nhiệm vụ đơn giản, trong quá trình cụ thể bạn có thể gặp nhiều vấn đề: + +| Vấn đề | Giải pháp | +|---------|-----------| +| Bố cục giao diện không đều | Mô tả vấn đề bố cục cụ thể cho AI, yêu cầu điều chỉnh CSS margin/padding | +| Giao diện hiển thị không đầy đủ | Kiểm tra xem đã đặt viewport đúng chưa, yêu cầu thêm responsive breakpoint | +| Màu sắc khôi phục không chính xác | Sử dụng công cụ lấy màu để lấy giá trị màu chính xác từ bản thiết kế, cung cấp cho AI | +| Font không khớp | Chỉ định tên font cụ thể hoặc yêu cầu sử dụng Google Fonts thay thế | + +::: tip 💡 Mẹo nhỏ +Khuyến nghị tạo code HTML trước, sau khi nhận được thì sử dụng IDE cục bộ để chuyển đổi thành framework React. Bằng cách này bạn có thể nhận được nhiều file HTML độc lập, tiến hành chuyển đổi framework thống nhất. +::: + +### 2.3 MasterGo AI tạo trang + +MasterGo cũng cung cấp chức năng tạo trang AI mạnh mẽ, có thể trực tiếp tạo code trang web sử dụng được dựa trên ảnh tham khảo. + +#### Tìm lối vào chức năng AI + +Trong thanh công cụ phía trên giao diện chỉnh sửa MasterGo, bạn có thể tìm thấy nút công cụ AI: + +![](/zh-cn/stage-2/frontend/design-to-code/images/image47.png) + +#### Quy trình tạo + +1. **Tải lên ảnh tham khảo** + - Sử dụng cùng cách với AI đa phương thức để tải lên ảnh tham khảo thiết kế + - Thêm mô tả văn bản yêu cầu + +2. **Xem kết quả tạo** + +![](/zh-cn/stage-2/frontend/design-to-code/images/image48.png) + +![](/zh-cn/stage-2/frontend/design-to-code/images/image49.png) + +3. **Lấy code** + - Nhấp nút xanh "Chèn vào canvas", có thể trực tiếp chỉnh sửa trang web sau khi tạo + - Hoặc nhấp nút "Code" bên phải, sao chép nội dung code về cục bộ + +![](/zh-cn/stage-2/frontend/design-to-code/images/image50.png) + +--- + +## 3. Con đường 2: Khả năng của nền tảng hoặc plugin xuất code + +### 3.1 Figma Make tạo code + +Figma Make là công cụ thiết kế AI chính thức do Figma ra mắt, có thể dựa trên prompt do người dùng nhập hoặc ảnh tham khảo, khôi phục giao diện UI nguyên mẫu trang web với độ chính xác cao. + +#### Đặc điểm chức năng + +- **Khôi phục độ chính xác cao**: So với code tạo bằng AI gốc, hiệu quả tốt hơn +- **Khả năng chỉnh sửa**: Kết quả tạo có thể chuyển đổi thành file Figma Design có thể chỉnh sửa +- **Tích hợp GitHub**: Hỗ trợ đồng bộ code trực tiếp lên GitHub + +::: tip 🔑 Mô tả quyền +Sử dụng đầy đủ chức năng Figma Make cần quyền người dùng Pro, sinh viên có thể nhận miễn phí quyền Pro thông qua xác thực giáo dục. +::: + +#### Các bước thao tác + +1. **Vào Figma Make** + - Nhấp nút Make trên trang chủ Figma + - Hoặc truy cập [Figma Make](https://www.figma.com/make) + +2. **Tải lên ảnh tham khảo** + - Tải bản thiết kế bạn muốn khôi phục vào hộp thoại + - Thêm prompt mô tả yêu cầu + +![](/zh-cn/stage-2/frontend/design-to-code/images/image43.png) + +3. **Xem kết quả tạo** + - Đợi một lúc sẽ thấy kết quả render + - Nhấp nút play ở góc trên bên phải để xem trước toàn màn hình + +![](/zh-cn/stage-2/frontend/design-to-code/images/image44.png) + +4. **Điều chỉnh chi tiết** + - Nhấp icon editor ở góc trên bên phải (icon chuột và thước) + - Quay lại giao diện Figma Editor quen thuộc để điều chỉnh chi tiết + +![](/zh-cn/stage-2/frontend/design-to-code/images/image45.png) + +5. **Xuất code** + - Sau khi điều chỉnh hài lòng, chọn xuất code + - Có thể kết nối trực tiếp với GitHub để lưu code + +![](/zh-cn/stage-2/frontend/design-to-code/images/image46.png) + +### 3.2 Plugin xuất code + +Ngoài chức năng AI gốc của nền tảng, cả Figma và MasterGo đều hỗ trợ xuất code thông qua plugin: + +**Plugin Figma phổ biến:** +- **Figma to Code**: Chuyển bản thiết kế thành code React, Vue, HTML, v.v. +- **Anima**: Tạo code high-fidelity, hỗ trợ hiệu ứng tương tác +- **Locofy**: Công cụ chuyển thiết kế thành code do AI điều khiển + +**Các bước sử dụng:** +1. Mở bảng plugin trong Figma (Plugins) +2. Tìm kiếm và cài đặt plugin xuất code cần thiết +3. Chọn yếu tố thiết kế cần xuất +4. Chạy plugin, chọn framework mục tiêu và định dạng code +5. Sao chép hoặc tải xuống code đã tạo + +--- + +## 4. Con đường 3: Nền tảng kết hợp khả năng MCP xuất code + +### 4.1 MCP là gì? + +MCP (Model Context Protocol, Giao thức Bối cảnh Mô hình) là một giao thức tiêu chuẩn mở, cho phép mô hình AI truy cập an toàn và có kiểm soát vào các công cụ và nguồn dữ liệu bên ngoài. Trong kịch bản công cụ thiết kế frontend, MCP cho phép mô hình_large trực tiếp đọc cấu trúc, kiểu dáng và thông tin component của file thiết kế, từ đó tạo code chính xác hơn. + +### 4.2 Nguyên lý hoạt động của MCP + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ Mô hình AI │ ←→ │ MCP Server │ ←→ │ Công cụ thiết kế │ +│ (Claude, v.v.) │ │ (Protocol adapter) │ │(Figma/MasterGo)│ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +**Quy trình làm việc:** +1. Mô hình AI gửi yêu cầu đến công cụ thiết kế thông qua giao thức MCP +2. Công cụ thiết kế trả về dữ liệu thiết kế có cấu trúc (layer, style, component, v.v.) +3. Mô hình AI hiểu cấu trúc thiết kế và tạo code tương ứng +4. Code có thể xuất trực tiếp hoặc đồng bộ đến môi trường phát triển + +### 4.3 Thực hành Figma + MCP + +#### Chuẩn bị môi trường + +1. **Cài đặt MCP Server** + ```bash + # Sử dụng npx cài đặt Figma MCP Server + npx figma-mcp-server + ``` + +2. **Cấu hình Claude Desktop hoặc công cụ AI hỗ trợ MCP khác** + ```json + { + "mcpServers": { + "figma": { + "command": "npx", + "args": ["figma-mcp-server"], + "env": { + "FIGMA_ACCESS_TOKEN": "your-figma-token" + } + } + } + } + ``` + +3. **Lấy Figma Access Token** + - Đăng nhập Figma → Settings → Personal Access Tokens + - Tạo Token mới và lưu lại + +#### Quy trình sử dụng + +1. **Kích hoạt kết nối MCP trong công cụ AI** + - Mở Claude Code hoặc IDE hỗ trợ MCP khác + - Xác nhận MCP Server đã kết nối + +2. **Cung cấp liên kết file thiết kế** + ``` + Người dùng: Xin giúp tôi chuyển thiết kế Figma này thành code React + Liên kết: https://www.figma.com/file/xxxxx + + AI: Tôi đã kết nối với Figma thông qua MCP, đang đọc cấu trúc file thiết kế... + ``` + +3. **AI tự động phân tích và tạo code** + - MCP Server lấy layer tree của file thiết kế + - AI hiểu cấu trúc component và thuộc tính style + - Tạo React/Vue component với naming và cấu trúc chính xác + +4. **Lặp lại và tối ưu** + ``` + Người dùng: Xin trích xuất button component thành một component độc lập có thể tái sử dụng + + AI: Đã hiểu, tôi đã nhận diện Button component trong design system thông qua MCP, + đang tạo React component với interface props... + ``` + +### 4.4 Lợi thế của MCP + +| Tính năng | Phương pháp truyền thống | Phương pháp MCP | +|-----------|--------------------------|-----------------| +| **Độ chính xác dữ liệu** | Dựa vào screenshot, có thể mất chi tiết | Trực tiếp đọc dữ liệu thiết kế gốc | +| **Nhận diện component** | AI cần đoán ranh giới component | Chính xác lấy định nghĩa component | +| **Khôi phục style** | Dựa trên ước tính pixel | Lấy design token chính xác | +| **Hiệu quả lặp lại** | Mỗi lần sửa đổi cần chụp lại | Đồng bộ thay đổi thiết kế theo thời gian thực | +| **Mức độ tự động hóa** | Thủ công sao chép dán | Có thể trực tiếp ghi vào file dự án | + +### 4.5 Công cụ MCP hiện có + +**MCP công cụ thiết kế:** +- **Figma MCP Server**: Triển khai MCP được hỗ trợ chính thức +- **MasterGo MCP**: Adapter MasterGo do cộng đồng phát triển + +**MCP môi trường phát triển:** +- **Claude Code**: Hỗ trợ gốc giao thức MCP +- **Cline**: Plugin VS Code, hỗ trợ kết nối MCP +- **Trae**: Có thể kích hoạt chức năng MCP thông qua cấu hình + +::: tip 🔮 Triển vọng tương lai +Giao thức MCP đang phát triển nhanh chóng, trong tương lai tích hợp giữa công cụ thiết kế và môi trường phát triển sẽ chặt chẽ hơn. Dự kiến sẽ xuất hiện nhiều giải pháp đồng bộ thiết kế thành code chỉ bằng một cú nhấp hơn nữa, rút ngắn khoảng cách giữa thiết kế và phát triển. +::: + +--- + +## 5. Công việc sau khi xuất code + +### 5.1 Kiểm thử cục bộ + +Sau khi lấy code, mở trong IDE cục bộ và kiểm thử: + +1. **Tạo dự án mới** + ```bash + # Nếu là file HTML, mở trực tiếp bằng trình duyệt + open index.html + + # Nếu là dự án React/Vue + npm install + npm run dev + ``` + +2. **Cộng tác với AI IDE** + - Import code đã tạo vào Trae hoặc AI IDE khác + - Để AI giúp sửa vấn đề bố cục, thêm chức năng tương tác + +### 5.2 Xử lý vấn đề phổ biến + +| Giai đoạn | Vấn đề | Giải pháp | +|-----------|--------|-----------| +| Bố cục | Yếu tố bị lệch | Kiểm tra thuộc tính display và position của CSS | +| Style | Màu sắc không nhất quán | Sử dụng developer tool của trình duyệt kiểm tra giá trị màu thực tế | +| Responsive | Hiển thị trên mobile bất thường | Thêm media query breakpoint | +| Tương tác | Nút không phản hồi | Kiểm tra event binding của JavaScript | + +--- + +## 6. So sánh ba con đường và đề xuất lựa chọn + +### 6.1 So sánh các con đường + +| Chiều | Con đường 1: AI đa phương thức | Con đường 2: Khả năng nền tảng | Con đường 3: MCP | +|-------|-------------------------------|-------------------------------|-------------------| +| **Độ khó bắt đầu** | ⭐ Đơn giản | ⭐⭐ Trung bình | ⭐⭐⭐ Khá phức tạp | +| **Độ chính xác khôi phục** | ⭐⭐⭐ Trung bình | ⭐⭐⭐⭐ Cao | ⭐⭐⭐⭐⭐ Cao nhất | +| **Tính linh hoạt** | ⭐⭐⭐⭐⭐ Cao | ⭐⭐⭐ Trung bình | ⭐⭐⭐⭐ Khá cao | +| **Mức độ tự động hóa** | ⭐⭐ Thấp | ⭐⭐⭐ Trung bình | ⭐⭐⭐⭐⭐ Cao | +| **Chi phí** | Thấp (tính theo API call) | Trung bình (có thể cần Pro) | Thấp (công cụ mã nguồn mở) | + +### 6.2 Đề xuất lựa chọn + +**Chọn con đường 1 (AI đa phương thức) nếu:** +- Cần nhanh chóng xác minh ý tưởng +- Công cụ thiết kế không cố định, thường xuyên chuyển đổi +- Không yêu cầu cao về độ chính xác khôi phục +- Ngân sách hạn chế + +**Chọn con đường 2 (Khả năng nền tảng) nếu:** +- Đội nhóm chủ yếu sử dụng Figma hoặc MasterGo +- Cần khôi phục code với độ chính xác cao +- Designer và developer cần cộng tác thường xuyên +- Sẵn sàng đầu tư phiên bản Pro + +**Chọn con đường 3 (MCP) nếu:** +- Theo đuổi mức độ tự động hóa cao nhất +- Có khả năng kỹ thuật cấu hình môi trường MCP +- Dự án cần lặp lại từ thiết kế đến code thường xuyên +- Muốn xây dựng quy trình thiết kế-phát triển tiêu chuẩn hóa + +--- + +## 7. Tổng kết + +Thông qua việc học chương này, bạn đã nắm vững ba con đường cốt lõi từ nguyên mẫu thiết kế đến code: + +1. **Chuyển đổi trực tiếp bằng AI đa phương thức**: Linh hoạt và nhanh chóng, phù hợp để xác minh nguyên mẫu +2. **Khả năng gốc của nền tảng**: Độ khôi phục cao, phù hợp cho quy trình thiết kế chuyên nghiệp +3. **Tích hợp giao thức MCP**: Mức độ tự động hóa cao nhất, đại diện cho xu hướng tương lai + +::: tip 💡 Thực hành tốt nhất +- **Người mới khuyến nghị**: Bắt đầu từ con đường 1 (AI đa phương thức), nhanh chóng làm quen +- **Cộng tác đội nhóm**: Sử dụng con đường 2 (Khả năng nền tảng), đảm bảo tính nhất quán thiết kế +- **Ưu tiên hiệu quả**: Thử con đường 3 (MCP), xây dựng quy trình làm việc tự động hóa +- **Sử dụng kết hợp**: Chuyển đổi linh hoạt giữa các con đường khác nhau theo giai đoạn dự án +::: + +--- + +## Tài nguyên tham khảo + +- [Giới thiệu Figma và MasterGo](../figma-mastergo/) - Học kiến thức cơ bản về công cụ thiết kế +- [Cùng làm Chân dung Hogwarts](../hogwarts-portraits/) - Thực hành dự án hoàn chỉnh +- [Tài liệu chính thức MCP](https://modelcontextprotocol.io/) - Tìm hiểu chi tiết giao thức +- [Tài liệu chính thức Figma Make](https://help.figma.com/hc/en-us/sections/360007453634-Figma-Make) +- [Hướng dẫn MasterGo AI](https://mastergo.com/tutorials) diff --git a/docs/vi-vn/stage-2/frontend/figma-mastergo/index.md b/docs/vi-vn/stage-2/frontend/figma-mastergo/index.md new file mode 100644 index 0000000..7904054 --- /dev/null +++ b/docs/vi-vn/stage-2/frontend/figma-mastergo/index.md @@ -0,0 +1,303 @@ + + +# Giới thiệu Figma và MasterGo + +::: tip 🎯 Vấn đề cốt lõi +**Làm thế nào để sử dụng công cụ thiết kế hiện đại để tạo nguyên mẫu trang web từ con số không?** +::: + +--- + +## 1. Tại sao cần học công cụ thiết kế frontend? + +Trước khi bắt đầu, chúng ta cần hiểu một vấn đề: tại sao cần học "công cụ thiết kế frontend"? Dù sao thì viết code HTML/CSS trực tiếp cũng có thể tạo ra trang web, việc học thêm một phần mềm và công nghệ mới có thực sự cần thiết không? + +Thực tế, việc chạy được trang web và thiết kế sản phẩm tốt là hai khái niệm hoàn toàn khác nhau. Code chỉ giải quyết vấn đề render trên trình duyệt, chạy trên các thiết bị khác nhau; công cụ thiết kế frontend giải quyết vấn đề phân bố thông tin, sắp xếp tương tác frontend như thế nào, chuyển trang khác nhau ra sao, phân bổ ưu tiên thị giác thế nào. Chỉ cần tạo một canvas trong công cụ thiết kế là có thể so sánh và xác định layout, phân cấp thông tin và phương thức tương tác trên một màn hình, chọn hiệu quả trình bày phù hợp nhất. + +Nếu bắt đầu viết code trực tiếp hoặc dùng AI tạo trang frontend hoàn chỉnh, trải nghiệm người dùng thường không tốt lắm. Sản phẩm nghiêm túc sẽ cân nhắc đến độ thoải mái của tương tác người dùng và frontend, cũng như phân bố nội dung mà các trang khác nhau muốn truyền đạt, từ góc độ người dùng sắp xếp trang frontend trước, sau đó mới chuyển đổi hoặc tạo code. + +Ngoài ra, từ góc độ hợp tác nhóm, công cụ thiết kế frontend còn giảm chi phí hợp tác giữa nhiều bên: nhà thiết kế, sản phẩm, phát triển không còn mỗi người tưởng tượng hoặc mô tả code trừu tượng, mà hỗ trợ nhiều người cộng tác, mọi người có thể thảo luận quản lý phiên bản, thay đổi yêu cầu, phản hồi xung quanh một canvas có thể nhìn thấy, có thể chú thích, có thể lặp lại. Hơn thế nữa, công cụ thiết kế frontend hiện đại không chỉ là phần mềm vẽ, một click tạo code một phần, quản lý hệ thống thiết kế và thư viện component, công cụ thiết kế thời đại mới đã có thể tự động hóa hoặc hàng loạt hóa nhiều công việc lặp đi lặp lại (căn chỉnh, chú thích, xuất, thay đổi style), thúc đẩy đáng kể hiệu quả phát triển thiết kế trang. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image8.png) + +### 1.1 Sự tiến hóa của công cụ thiết kế frontend + +Trong dòng chảy thời gian, cái gọi là công cụ thiết kế frontend thực chất là một công nghệ liên tục tiến hóa. Từ thời Photoshop chủ yếu chỉnh sửa bitmap cục bộ những năm 90, đến khoảng năm 2010 Sketch mang đến workflow vector hóa, component hóa, rồi sau 2016 Figma đưa cộng tác lên đám mây hoàn toàn, đội thiết kế từ làm việc đơn độc dần chuyển sang cộng tác thời gian thực nhiều người. Đến năm 2025, AI đã thực sự tích hợp vào bên trong các công cụ này: từ "tạo bản nháp trang web theo một câu mô tả", đến "chuyển thiết kế trực tiếp thành cấu trúc frontend có thể chạy", "thiết kế chính là code", "người và máy cùng sáng tạo" đang từ khái niệm trở thành năng lực sản xuất thực tế. + +Trong phần này, chúng ta sẽ chọn hai công cụ thiết kế frontend hiện đại đại diện nhất để giới thiệu: Figma và MasterGo. Một mặt, cả hai đều bao phủ các năng lực cốt lõi mà UI/UX hiện đại cần (chỉnh sửa vector, hệ thống component, tự động layout, giao code, v.v.), có thể hỗ trợ bạn hoàn thành vòng lặp hoàn chỉnh từ wireframe đến high-fidelity đến bàn giao phát triển; mặt khác, hai công cụ này đã lần lượt tích hợp các chức năng AI thực tế sau năm 2025, giúp bạn đảm bảo nguyên mẫu không đổi đồng thời chuyển thiết kế thành chương trình thực sự có thể chạy. + +## 1.2 Hành trình ra đời + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image9.png) + +Trong thời kỳ chưa có công cụ thiết kế frontend chuyên dụng, toàn bộ công việc thiết kế thị giác của ngành thiết kế giao diện trong thời gian dài đều do phần mềm thiết kế "đa năng" như Photoshop đảm nhận. Nhà thiết kế sẽ tạo lớp layer lớp layer tại địa phương, hoàn thành thiết kế hiệu quả thị giác tổng thể trang một cách tỉ mỉ, cuối cùng bàn giao file nguồn .psd khá lớn cho kỹ sư frontend - mà frontend muốn khôi phục chính xác thiết kế, còn phải hoàn thành thủ công ba công việc phức tạp và quan trọng: + +Thứ nhất là "cắt ảnh": cần từ cấu trúc nhiều layer của file .psd, tách riêng từng phần tử thị giác độc lập như nút bấm, icon, Logo, module nền, rồi xuất sang định dạng hình ảnh mà web có thể tải trực tiếp như PNG, JPG (vì web không thể nhận diện thông tin layer PSD, chỉ dựa vào các hình ảnh đã tách để thể hiện chi tiết); + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image10.png) + +Thứ hai là "đo kích thước": phải dùng công cụ đo tích hợp, xác nhận từng kích thước chiều rộng chiều cao, khoảng cách giữa các module khác nhau (margin/padding) và các dữ liệu khác, đảm bảo tất cả kích thước chính xác đến pixel; + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image11.png) + +Thứ ba là "trích chú thích": cần trích xuất từ thiết kế các tham số "không nhìn thấy nhưng bắt buộc phải có" - như kích thước chữ, font-weight, line-height, giá trị màu RGB hoặc HEX của mỗi khối màu, tương đương với việc "thông số kỹ thuật thiết kế" mà nhà thiết kế không viết trên giấy phải được "trích" thủ công. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image12.png) + +Sau đó, giai đoạn hiện thực frontend mới thực sự bắt đầu. Dù sử dụng HTML/CSS/JS gốc hay dựa trên framework Vue, React, quá trình bản chất là giống nhau. Frontend sẽ lấy "container làm载体 cốt lõi", tái xây dựng cấu trúc trang theo phân cấp và ngữ nghĩa của các module trong thiết kế. Container ở đây là đơn vị có ranh giới layout rõ ràng, chuyên chứa và tổ chức các phần tử con, nó không trực tiếp thể hiện nội dung cụ thể, mà thông qua các quy tắc như Flex, Grid, vạch phạm vi sắp xếp cho các phần tử bên trong. "Khối cấu trúc" (như thanh điều hướng trên cùng, sidebar, khu vực danh sách bài viết, chân trang dưới cùng v.v.) dựa vào container tồn tại; bên trong mỗi khối cấu trúc, lại lồng các container nhỏ hơn để tổ chức phần tử, ví dụ một mục danh sách bài viết sẽ được "container mục danh sách" điều khiển padding và layout tổng thể, rồi bọc các phần tử chi tiết như tiêu đề, tóm tắt, thời gian, icon bìa. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image13.png) + +Trong framework frontend hiện đại, các "khối cấu trúc (và container & phần tử liên quan)" này thường được hiện thực thành "component". Component có thể hiểu đơn giản là đơn vị giao diện tái sử dụng có ranh giới rõ ràng, tích hợp layout container và logic, nó vừa chứa container điều khiển ngoại hình và sắp xếp (ví dụ "component nút bấm" dùng container định nghĩa chiều rộng, chiều cao, bo góc, "component thẻ bài viết" dùng container tổ chức vị trí tiêu đề, bìa), vừa đóng gói logic tương tác. Những phần lặp lại xuất hiện, hình thái nhất quán trong thiết kế (như nút bấm phong cách thống nhất, thẻ bài viết sử dụng nhiều lần) sẽ được trừu tượng thành component trong code: vừa tái sử dụng được trong các trang/kịch bản khác nhau, giảm phát triển lặp, vừa thông qua quy tắc thống nhất của container trong component, đảm bảo layout và phong cách nhất quán ở mọi nơi tái sử dụng. + +Tiếp đó, frontend sử dụng hệ thống style khôi phục thị giác và layout. Các tài nguyên PNG/JPG xuất trong giai đoạn cắt ảnh, sẽ được sử dụng làm `` hoặc ảnh nền bên trong component hoặc khối cấu trúc; các giá trị cụ thể về chiều rộng, chiều cao, khoảng cách, chiều cao dòng thu được trong giai đoạn đo kích thước, sẽ được chuyển thành các thuộc tính style như `width`, `height`, `margin`, `padding`, `line-height`, áp dụng cho component hoặc khối cấu trúc tương ứng; màu sắc, font chữ, đổ bóng, bo góc và các trạng thái hover/active được sắp xếp trong giai đoạn trích chú thích, sẽ được thể hiện vào `color`, `font-family`, `font-size`, `box-shadow`, `border-radius` và pseudo-class hoặc class trạng thái trong các giải pháp cụ thể như CSS, CSS Modules, CSS-in-JS, Tailwind. Lúc này, cắt ảnh, kích thước và chú thích cung cấp một bộ tham số thị giác chính xác, component và khối cấu trúc cung cấp đơn vị tổ chức code mang các tham số này, kết hợp cả hai tạo thành hiện thực giao diện có thể bảo trì, tái sử dụng. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image14.png) + +Tuy nhiên, mô hình lấy file cục bộ làm trung tâm tự nhiên có hiệu suất thấp. Phiên bản truyền qua email và đám mây, bản nháp mới cũ dễ nhầm lẫn, thiết kế và phát triển phụ thuộc nhiều vào các phương thức tương tác phức tạp nói trên, chi phí cộng tác và xác suất lỗi đều không thấp. + +Sau khi internet di động phát triển, độ phức tạp giao diện và nhu cầu tốc độ lặp lại nhanh chóng tăng lên, "lớn và toàn diện" của Photoshop dần trở nên cồng kềnh. Giai đoạn này, Sketch xuất hiện. Sketch tập trung vào bản thân thiết kế UI, tách bỏ hầu hết gánh nặng liên quan đến xử lý hậu kỳ thị giác; dùng Symbols biến các phần tử tái sử dụng cao như nút bấm, thanh điều hướng, ô nhập thành component hóa, sửa một chỗ có thể đồng bộ toàn cục; kết hợp với công cụ như Zeplin, tự động tạo chú thích và đoạn style. Sketch đưa "tư duy component" vào workflow thiết kế. Nhưng nó vẫn là ứng dụng desktop dựa trên file cục bộ, cộng tác thời gian thực phải dựa vào cloud drive, plugin bên thứ ba hoặc công cụ phiên bản, chưa giải quyết vấn đề "nhiều người cùng sửa một bản nháp" từ gốc. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image15.png) + +Thực sự thay đổi luật chơi là Figma. Từ năm 2016, nó tích hợp thiết kế UI, tạo nguyên mẫu, bình luận cộng tác vào trình duyệt, hỗ trợ nhiều chức năng hiện đại: con trỏ thời gian thực nhiều người, bình luận trực tuyến, dòng thời gian phiên bản, liên kết chia sẻ, v.v., ngày nay nhìn thấy rất đơn giản nhưng lúc đó là thách thức trực tiếp với mô hình Photoshop/Sketch. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image16.png) + +Đến đây, thiết kế giao diện không còn là các file rải rác trên máy tính mỗi người, mà tập trung trên một canvas trực tuyến, cập nhật thời gian thực trên đám mây. Xoay quanh canvas này, chúng ta có thể tưởng tượng xa hơn nữa, dùng tự động hóa hoặc AI làm mờ ranh giới giữa thiết kế và code frontend. + +Ban đầu, chúng ta chỉ có thể dựa vào các plugin nền tảng khác nhau, xuất bán tự động thông tin component, style từ thiết kế thành đoạn code (như khung component React/Vue, biến CSS, v.v.), bản chất cốt lõi là trích xuất thông tin có cấu trúc thông qua plugin. Sau đó, cùng với sự tiến hóa năng lực nền tảng, hầu hết nền tảng thiết kế bắt đầu hỗ trợ chức năng MCP (Model Context Protocol, Giao thức Ngữ cảnh Mô hình) mô hình lớn: giao thức này cung cấp một bộ cơ chế chuẩn, cho phép mô hình lớn truy cập an toàn, có kiểm soát vào file thiết kế, interface plugin và metadata dự án, từ đó thuận tiện hơn xuất thiết kế thành code. + +Tiếp tục, trên cơ sở plugin và MCP, tự động hóa code frontend tiến thêm bước sang giai đoạn hỗ trợ gốc từ thiết kế trực tiếp suy ra cấu trúc code. Chúng ta có thể tạo khung dự án frontend, phân cấp component, hệ thống style và kết quả code tương ứng chỉ với một click trong công cụ thiết kế. Điều này giúp nhà thiết kế và kỹ sư phát triển frontend được giải phóng khỏi việc vận chuyển thủ công chi tiết thiết kế, tập trung nhiều năng lực hơn vào tối ưu trải nghiệm người dùng và cập nhật lặp lại phiên bản chức năng. + +--- + +## 2. Giới thiệu Figma + +Tiếp theo chúng ta đi từ phần khái niệm trừu tượng đến khâu thao tác thực tế. Do thời gian có hạn, chúng ta chỉ học logic thao tác cơ bản của Figma, đảm bảo dù bạn chưa từng dùng công cụ thiết kế nào cũng có thể theo làm bài tập. Nếu bạn muốn học đầy đủ chức năng Figma, hãy tham khảo hướng dẫn chi tiết chính thức mà Figma cung cấp: https://help.figma.com/hc/en-us/sections/30880632542743-Figma-Design-for-beginners + +Hoặc tham khảo hướng dẫn dưới đây, xây dựng nhanh một trang web portfolio cá nhân đơn giản: https://help.figma.com/hc/en-us/sections/35895585621655-Figma-Sites-collectio + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image17.png) + +Bên trái là nơi tạo mới và quản lý tài nguyên dự án, vài nút bấm ở góc trên bên phải là các chức năng phổ biến của Figma. Trong đó, Make dùng để AI giúp bạn tạo trước một giao diện hoặc bản nháp cấu trúc với một câu mô tả, Design là không gian làm việc chính để vẽ giao diện web/App, tạo component và làm nguyên mẫu, FigJam giống như bảng trắng nhóm, dùng để dán note, vẽ quy trình và thảo luận sơ bộ, Buzz là công cụ sản xuất hàng loạt tài sản thương hiệu, dùng để tạo hàng loạt nội dung duy trì nhất quán thương hiệu, Site là tổng hợp các thiết kế này thành trang web hoặc trang tài liệu thực sự có thể truy cập để trưng bày bên ngoài. + +Nhìn thoạt qua chức năng Figma rất nhiều, khó nhập môn, nhưng thực tế loại công cụ chức năng này bản chất là quen tay hay làm, không cần sợ thao tác sai lúc đầu, cũng đừng nghĩ phải làm đúng ngay từ đầu, chỉ cần chơi trước, chơi nhiều tự nhiên sẽ nhanh thành thạo. + +Trong bài hướng dẫn này, để nhanh chóng nhập môn, chúng ta sẽ giải thích đơn giản chức năng Design. + +### 2.1 Tạo file Design mới + +Từ trang chủ hoặc ô nhập ở góc trên bên phải, chọn **Design**, tạo một file mới, bạn sẽ vào một canvas thiết kế trống. +Giao diện này大致 chia làm ba phần: bên trái là trang và layer, dùng để xem và sửa đổi quan hệ trang, quan hệ phần tử; ở giữa là canvas, dùng để xem hiệu quả hiện tại; bên phải là thuộc tính và style, dùng để sửa đổi hình dạng, màu sắc, style cụ thể; một thanh công cụ ở dưới cùng, dùng để chuyển đổi công cụ, bao gồm select, vẽ hình, nhập chữ, bình luận, plugin, v.v., sau khi chọn công cụ, có thể nhấn phím Esc để quay lại công cụ chuột mặc định. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image18.png) + +### 2.2 Tạo Frame (bảng vẽ) đầu tiên của bạn + +Trước khi đặt phần tử chính thức, cần xác định ranh giới rõ ràng cho trang, ranh giới này do Frame đảm nhận. Bạn có thể chọn công cụ Frame trong thanh công cụ dưới cùng, hoặc nhấn trực tiếp phím F, rồi kéo ra một vùng hình chữ nhật trên canvas. + +1. Sử dụng công cụ Frame trong thanh công cụ dưới cùng, hoặc nhấn trực tiếp phím `F`. +2. Kéo ra một vùng hình chữ nhật trong canvas, thanh thuộc tính bên phải đổi chiều rộng thành ví dụ `1440`, chiều cao thành `900`. +3. Trong thanh layer bên trái, đổi tên Frame này, ví dụ `My First Page` hoặc tên dự án của bạn. + +Frame này là container trang của giao diện một màn hình, sau đó tiêu đề, chữ, nút bấm, hình ảnh v.v. đều nên đặt bên trong Frame này, chứ không rải rác ở bất kỳ vị trí nào trên canvas. Tổ chức nội dung với Frame làm ranh giới giúp giữ cấu trúc可控 trong các khâu sau như cài đặt cuộn, thích ứng kích thước thiết bị khác nhau, xuất hình và tạo nguyên mẫu. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image19.png) + +### 2.3 Đặt chữ và phần tử đơn giản trong Frame + +Có container rồi, tiếp theo chúng ta học cách đặt các component cơ bản nhất, ví dụ: tiêu đề, tiêu đề phụ, nút bấm, khối ảnh placeholder. + +1. Chọn công cụ chữ (phím `T` trong thanh công cụ dưới cùng), click một cái trong Frame, nhập tiêu đề trang, ví dụ: `My Portfolio`. + Trong thuộc tính bên phải, tăng kích thước font lên (ví dụ 96), tăng font-weight. +2. Bên dưới tiêu đề, dùng công cụ chữ nhập một dòng mô tả đơn giản, ví dụ một hai câu mô tả trang này làm gì. + Kích thước chữ có thể nhỏ hơn, line-height tăng nhẹ một chút, đọc không bị chật. +3. Vẽ một nút bấm sơ bộ: + Dùng công cụ hình chữ nhật vẽ một hình chữ nhật khoảng `200 × 48` bên dưới tiêu đề, bên phải cho một màu fill khá nổi bật, thêm bo góc phù hợp. + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image20.png) +4. Rồi dùng công cụ chữ nhập chữ nút bấm bên trên hình chữ nhật, ví dụ `Get Started`, chọn cả hình chữ nhật và chữ, dùng công cụ căn chỉnh ở trên cùng cho chữ căn giữa cả theo chiều ngang và chiều dọc. +5. Bên cạnh hoặc bên dưới nút bấm, vẽ thêm một hình chữ nhật lớn màu xám nhạt làm "khu vực ảnh placeholder", sau này có thể dùng để đặt ảnh trưng bày. + +Đến đây, thực tế bạn đã có một "bản nháp trang chủ" rất đơn giản nhưng cấu trúc hoàn chỉnh: một tiêu đề, một đoạn văn, một nút bấm, một khu vực trưng bày chính. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image21.png) + +### 2.4 Tận dụng Auto Layout tích hợp phần tử + +Nếu tất cả phần tử chỉ kéo thả tùy tiện, trang sẽ nhanh chóng lộn xộn. Một khái niệm rất quan trọng trong Figma là **Auto Layout**, nó có thể biến một nhóm phần tử thành một container có quy tắc. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image22.png) + +Bạn có thể chọn cả ba thứ "tiêu đề chính + tiêu đề phụ + nút bấm", click **Add Auto layout** trong thanh thuộc tính bên phải. + +Lúc này ba thứ sẽ được bọc trong một container, bạn có thể điều chỉnh tham số ở bên phải, layout các phần tử bên trong sẽ tự động thích ứng theo tham số: + +- Chúng xếp dọc hay xếp ngang. +- Khoảng cách giữa các phần tử là bao nhiêu. +- Toàn bộ khối này cách mép container bao nhiêu padding. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image23.png) + +Tương tự, bên trong nút bấm cũng có thể dùng Auto Layout, chúng ta có thể đạt được hiệu quả: khi chỉnh sửa chữ, độ dài nút bấm cũng tự động điều chỉnh. + +Trước hết chọn hình chữ nhật nền nút bấm và chữ nút bấm, thêm Auto Layout, cho hai thứ này thành một "container nút bấm". Sau đó chọn container nút bấm này, đặt cả chiều rộng và chiều cao thành **Hug contents**. Như vậy, chữ sẽ luôn ở giữa nút bấm, chữ nhiều hơn hay ít hơn, chiều rộng nút bấm đều tự động thay đổi theo. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image24.png) + +### 2.5 Biến nút bấm thành component tái sử dụng + +Bây giờ chúng ta học một khái niệm mới: component. Component nghĩa là phần tử có thể được sử dụng lặp đi lặp lại, ví dụ phần tử như nút bấm, chỉ cần bạn dự cảm sau này còn dùng lại nhiều lần, có thể cân nhắc biến nó thành component. Chúng ta dựa trên nút bấm đã thêm Auto Layout ở trên: + +1. Chọn toàn bộ container nút bấm. +2. Nhấp chuột phải chọn Create component (tạo component). + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image25.png) + +Như vậy, nút bấm này từ một nhóm layer bình thường, trở thành một bản gốc component. Sau này nếu bạn cần nút bấm cùng phong cách ở trang khác hoặc Frame khác, có thể kéo trực tiếp từ bảng Assets bên trái để sử dụng. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image26.png) + +Lúc này tất cả nút bấm được sử dụng đều là bản sao đồng bộ của bản gốc này. Khi bạn sửa màu sắc, bo góc hoặc khoảng cách của bản gốc, tất cả instance sẽ tự động giữ đồng bộ cập nhật. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image27.png) + +Đến đây, bạn đã nắm初步 cách sử dụng đơn giản của Figma. Bạn không cần hiểu tất cả chức năng ngay từ đầu, chỉ cần làm theo một trang đơn giản đầu tiên, quen với vài thao tác cốt lõi, rồi dần khám phá thêm năng lực trong hướng dẫn chính thức, cùng với số lần sử dụng tăng lên chắc chắn sẽ thành thạo. + +--- + +## 3. Giới thiệu MasterGo + +Sau khi hiểu workflow cơ bản của Figma, chúng ta nhìn sang MasterGo, bạn có thể đơn giản xem MasterGo là phiên bản Trung Quốc của Figma, nhưng có một số khác biệt về mặt chức năng. Nhìn chung, nó kế thừa layout giao diện và triết lý thao tác tương tự Figma: cũng có canvas, cây layer và bảng thuộc tính, cũng hỗ trợ component, style, tự động layout và cộng tác nhiều người. Nội dung chi tiết hơn có thể tham khảo hướng dẫn chính thức của MasterGo: https://mastergo.com/tutorials/12 + +### 3.1 Tạo file thiết kế mới + +1. **Vào backend MasterGo** + 1. Mở trang chủ MasterGo và đăng nhập tài khoản. + 2. Sau khi vào, bạn sẽ thấy khu vực trang chủ "Danh sách file/Danh sách dự án" tương tự, dùng để quản lý file thiết kế của bạn. + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image28.png) + +2. **Tạo file mới** + 1. Thấy nút + File thiết kế ở góc trên bên phải để click, hoặc chọn nhập file Figma, v.v. + 2. Sau khi click, bạn sẽ vào một canvas trống, đây là không gian làm việc thiết kế của MasterGo. + +3. **Làm quen các khu vực giao diện cơ bản** + Khi bạn đã biết dùng Figma, cách dùng MasterGo cũng tương tự, chủ yếu chia làm vài khu vực: + + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image29.png) + 1. Thanh công cụ trên cùng: nằm ở trên cùng canvas, bên trái là vị trí file và tên file, ở giữa là một hàng nút công cụ phổ biến (chọn, khu vực/bảng vẽ, hình dạng, văn bản, chú thích, bình luận, chọn plugin và công cụ AI, v.v.), bên phải là thành viên trực tuyến hiện tại, entrance chia sẻ và chức năng điều khiển zoom và xem trước canvas. + 2. Bảng bên trái: chủ yếu chia làm layer và tài nguyên, hiện đang dừng ở tab layer, có thể thấy danh sách trang, cấu trúc và phân cấp của tất cả layer trong trang đó. + 3. Khu vực canvas ở giữa: không gian làm việc cụ thể để vẽ và layout, tất cả Frame, component và hình dạng đều hiển thị ở đây. + 4. Bảng thuộc tính bên phải: dùng để xem và chỉnh sửa thuộc tính đối tượng đã chọn, ví dụ kích thước, vị trí, căn chỉnh, fill nền, viền, bo góc, v.v. Nếu chưa chọn đối tượng nào, sẽ hiển thị cài đặt liên quan canvas như màu nền canvas, tag và tùy chọn xuất. + +### 3.2 Tạo Frame đầu tiên của bạn + +Trước khi đặt thứ gì chính thức, chúng ta cần một container trang để xác định ranh giới và kích thước giao diện. Container này trong MasterGo thường gọi là Frame. + +**Các bước:** + +1. **Chọn công cụ Frame** + 1. Tìm công cụ Frame/bảng vẽ trong thanh công cụ, click后 có thể dùng tham số mặc định tạo nội dung trực tiếp vào bảng vẽ. + 2. Hoặc dùng phím tắt (thường là `F`, nếu khác biệt thì theo giao diện thực tế). +2. **Kéo ra một vùng hình chữ nhật trong canvas** + 1. Sau khi kéo ra, bạn sẽ thấy một vùng có khung chọn. + 2. Bảng thuộc tính bên phải, có thể thấy chiều rộng và chiều cao của Frame này. + 3. Đổi chiều rộng thành ví dụ `1440`, chiều cao thành `900` (một kích thước phổ biến cho web một màn hình). +3. **Đổi tên Frame** + 1. Tìm Frame này trong bảng layer bên trái. + 2. Nhấp đúp tên, đổi thành tên dự án của bạn, ví dụ: `My First Page`, hoặc tên trang bạn tự đặt. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image30.png) + +### 3.3 Tạo nội dung bảng vẽ + +Có container rồi, sử dụng cách tương tự đã dạy trong Figma, rất dễ có thể được trang trưng bày tương tự. (Bạn có thể thử sao chép phần tử chữ từ bảng vẽ Figma, hỗ trợ nhập dán trực tiếp component văn bản) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image31.png) + +Đáng chú ý là hành vi chức năng Auto Layout hơi không nhất quán, trong MasterGo, nếu bạn muốn hiện thực độ dài nút bấm thay đổi theo độ dài chữ tương tự Figma, bạn cần tạo container hoặc component dựa trên phần tử hình chữ nhật tương ứng trước, như hình所示: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image32.png) + +Sau khi tạo container thành công, đặt hình chữ nhật nút bấm và chữ vào container song song tương ứng, rồi tìm nút Auto Layout ở bên phải bật chức năng tự động, là có thể hiện thực thành công chức năng chiều rộng nút bấm thay đổi theo độ dài chữ. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image33.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image34.png) + +### 3.4 AI tạo trang + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image35.png) + +Trong MasterGo, một chức năng thú vị đáng chú ý là AI tạo trang. Bạn có thể dùng một câu hoặc kèm ảnh tham khảo, tạo component phiên bản MasterGo có thể chỉnh sửa tương ứng, và nhận code có thể sử dụng trực tiếp. Bạn có thể dùng tiếng Trung hoặc tiếng Anh nhập yêu cầu trực tiếp, trang sẽ trả về layout trang có cấu trúc rõ ràng theo yêu cầu, hiệu quả như sau: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image36.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image37.png) + +Sau khi tạo tài liệu thiết kế xong, nhấp bắt đầu tạo, đợi một lúc là có thể nhận được hiệu quả trang web thực tế tương ứng: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image38.png) + +Lúc này bạn có hai lựa chọn thao tác: một là nhấp nút xanh để chèn kết quả tạo trực tiếp vào canvas, hai là nhấp chức năng xem trước code, trực tiếp nhận code trang hoàn chỉnh hiện tại, giao diện thao tác cụ thể như sau: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image39.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image40.png) + +Sau khi chèn kết quả vào canvas, bạn còn có thể điều chỉnh tinh chỉnh hơn layout tổng thể trang web, chi tiết phần tử (như font chữ, màu sắc, khoảng cách, v.v.), cho đến khi hiệu quả cuối cùng hoàn toàn đáp ứng kỳ vọng của bạn. + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image41.png) + +--- + +## 4. Bước tiếp theo: Từ nguyên mẫu đến code + +Trong nội dung trước, chúng ta đã học thao tác cơ bản Figma và MasterGo, có thể tạo nguyên mẫu giao diện có cấu trúc hoàn chỉnh. Bước quan trọng tiếp theo là: **làm thế nào để chuyển các thiết kế này thành code frontend thực sự có thể chạy trên trình duyệt?** + +::: tip 📚 Hướng dẫn tiếp theo +Giới thiệu phương pháp chi tiết hãy tham khảo [Từ nguyên mẫu thiết kế đến code dự án](../design-to-code/), bạn sẽ học: + +- **Chuyển đổi trực tiếp AI đa phương thức**: Gửi ảnh chụp thiết kế cho AI, trực tiếp tạo code HTML/React +- **Figma Make**: Sử dụng công cụ AI chính thức Figma khôi phục thiết kế chính xác cao và xuất code +- **MasterGo AI**: Một click tạo trang có thể chỉnh sửa và nhận code + +Các phương pháp này đều có ưu nhược điểm, phù hợp với các kịch bản khác nhau, đề nghị chọn workflow phù hợp theo nhu cầu dự án. +::: + +--- + +## 5. Tổng kết + +Thông qua học tập chương này, bạn đã nắm được: + +1. **Giá trị của công cụ thiết kế frontend**: Hiểu tại sao cần công cụ thiết kế, và chúng giải quyết vấn đề phân bố thông tin, hợp tác nhóm như thế nào. + +2. **Thao tác cơ bản Figma**: + - Tạo file Design và bảng vẽ Frame + - Thêm chữ, hình dạng và các phần tử cơ bản + - Sử dụng Auto Layout hiện thực layout tự thích ứng + - Tạo hệ thống component tái sử dụng + +3. **Thao tác cơ bản MasterGo**: + - Làm quen layout giao diện tương tự Figma + - Tạo Frame và nội dung bảng vẽ cơ bản + - Sử dụng chức năng AI tạo trang để nhanh chóng tạo nguyên mẫu + +::: tip 💡 Bước tiếp theo +Bây giờ bạn đã nắm được cách sử dụng cơ bản công cụ thiết kế frontend, có thể thử: +- Thiết kế một trang portfolio cá nhân cho mình +- Thiết kế nguyên mẫu giao diện cho dự án tiếp theo +- Học [Từ nguyên mẫu thiết kế đến code dự án](../design-to-code/), chuyển thiết kế thành code có thể chạy + +Nếu bạn đang làm dự án [Cùng làm Chân dung Hogwarts](../hogwarts-portraits/), có thể thiết kế nguyên mẫu giao diện trước, rồi xuất code kết hợp với chức năng hội thoại AI. +::: + + diff --git a/docs/vi-vn/stage-2/frontend/hogwarts-portraits/index.md b/docs/vi-vn/stage-2/frontend/hogwarts-portraits/index.md new file mode 100644 index 0000000..caad29e --- /dev/null +++ b/docs/vi-vn/stage-2/frontend/hogwarts-portraits/index.md @@ -0,0 +1,343 @@ +# Dự án 4: Cùng làm Chân dung Hogwarts + +Trong các bài học trước, chúng ta đã học cách thực hiện tương tác AI phức tạp hơn dựa trên prompt engineering và API call. Chúng ta đã có thể nâng cấp chatbot AI đơn giản thành AI Agent và AI workflow; thông qua logic điều kiện và phân nhánh phức tạp hơn, chúng ta đã phát triển được các tính năng có tính ứng dụng thực tế cao hơn. + +Để các logic AI phức tạp này có thể vận hành tốt hơn trong các chương trình và kịch bản ứng dụng thực tế khác nhau, chúng ta đã chuyển từ môi trường trực tuyến z.ai đơn giản nhất, dần dần chuyển sang AI IDE cục bộ hiện đại hơn, đưa môi trường lập trình ban đầu trong trình duyệt lên máy tính của bạn. Theo đó, bạn bắt đầu thực sự đối mặt với nhiều vấn đề cài đặt và cấu hình môi trường, nhưng trong quá trình đối thoại với Trae Agent, những thử thách tưởng chừng khó khăn này cũng trở nên có thể giải quyết được. + +Trong dự án này, chúng ta sẽ tiến thêm một bước về tính ứng dụng thực tế, không chỉ tối ưu bản thân chức năng AI mà còn bắt đầu mài giũa "ngoại hình" của sản phẩm. Bạn sẽ thử làm cho giao diện của mình đẹp hơn và dễ sử dụng hơn, đồng thời tùy chỉnh bố cục và phong cách giao diện chương trình theo nhu cầu thực tế. + +Trước khi bắt đầu chính thức, hãy dùng vài câu hỏi nhỏ giúp bạn nhanh chóng ôn lại nội dung bài học trước: + +1. Dify là gì? Nó dùng để làm gì? Tại sao chúng ta cần nó? +2. Cách gọi API của Dify? +3. RAG là gì? Cách sử dụng Dify để xây dựng một RAG Agent hoặc RAG Workflow? Cách sử dụng các node phổ biến trong Dify +4. AI IDE là gì? Trae là gì? Nó khác gì với z.ai? + +Nếu bạn còn thắc mắc về bất kỳ câu hỏi nào ở trên, có thể ôn lại tài liệu bài học trước, hoặc trực tiếp đặt câu hỏi thảo luận trong nhóm WeChat. + +Chủ đề dự án của bài học này là **Hogwarts Portraits**. Như tên gọi, nguồn cảm hứng đến từ những bức tranh "sống dậy" tại trường phép thuật Hogwarts. Chúng ta muốn sử dụng AI để tạo ra một trải nghiệm chân dung phép thuật "có thể tương tác" — trò chuyện với bức chân dung giống như đang trò chuyện với "chính nhân vật đó", vừa giữ được trí nhớ của cuộc trò chuyện, vừa có nền tảng và lịch sử nhân vật. Thông qua dự án này, bạn sẽ thực sự tích hợp Agent và Workflow đã học vào một giao diện sản phẩm cụ thể. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image1.png) + +Để thực sự tạo ra Hogwarts Portraits, chúng ta cần tự tay xây dựng giao diện frontend phù hợp với chân dung phép thuật. Để làm điều này, bạn sẽ bắt đầu tiếp xúc với các công cụ thiết kế frontend hiện đại, học cách kết hợp thiết kế giao diện với code, biến bản phác thảo giao diện trên giấy hoặc canvas thành trang web thực sự có thể thao tác. + +Bạn cũng cần học cách xuất bản trang web này từ môi trường cục bộ lên internet, để trang web đặc sắc do bạn tự tay tạo ra không chỉ chạy trên máy tính của mình mà còn có thể được truy cập và trải nghiệm bởi người dùng trên toàn thế giới. + +Địa chỉ dự án tham khảo của bài học này là: [Project4-Hogwarts-Portraits](https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits) + +# Bạn sẽ học được gì + +1. Hiểu công cụ thiết kế frontend là gì, chúng giải quyết vấn đề gì, và các công cụ thiết kế frontend phổ biến hiện nay. +2. Làm quen với Figma và MasterGo, nắm vững các thao tác cơ bản, và học cách sử dụng plugin xuất code frontend. +3. Sử dụng Figma AI và MasterGo AI để tạo thiết kế trang web, và xuất code trang sử dụng được. +4. Hiểu GitHub là gì, học cách cấu hình kết nối SSH, tạo kho code và hoàn thành push code. +5. Hiểu rõ khái niệm "triển khai", học cách sử dụng Zeabur, triển khai code từ GitHub hoặc môi trường cục bộ lên internet. + +Một Hogwarts Portraits thuộc về chính bạn, một giao diện trang web dùng để trình bày **một ngôi sao, nhân vật lịch sử hoặc nhân vật hoạt hình nào đó**. + +# 1. Hogwarts Portraits + +Chúng ta thực sự muốn làm một loại "chân dung phép thuật" như thế nào? Nói đơn giản, chúng ta muốn tái hiện cảnh trong Harry Potter nhất có thể, bức chân dung không chỉ là một bức ảnh tĩnh treo trên tường, mà là một nhân vật nhân hóa có thể trò chuyện với bạn, sẽ thay đổi biểu cảm và "tâm trạng" dựa trên nội dung cuộc trò chuyện. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image2.png) + +Để bức chân dung này trông không giống chatbot AI mà gần gũi hơn với một "người thực sự tồn tại", cần giải quyết hai vấn đề: thứ nhất là trí nhớ và kiến thức: bức chân dung cần nắm vững nhiều tài liệu nền tảng liên quan đến nhân vật (thiết lập nhân vật, câu chuyện trải nghiệm, bài báo liên quan, v.v.), phần này có thể được thực hiện thông qua knowledge base, kết nối tài liệu văn bản bạn chuẩn bị cho nhân vật vào Dify có chứa knowledge base, khi đó bức chân dung có khả năng trình bày kiến thức nền tảng nhất định. + +Thứ hai là vấn đề phong cách biểu đạt. Chỉ có kiến thức là chưa đủ, chúng ta còn muốn cách nói của nó gần gũi với "chính nhân vật" nhất có thể, bao gồm giọng điệu, thói quen dùng từ, cách tư duy, thậm chí cá tính và khiếu hài hước thỉnh thoảng. Lớp này cần được xử lý thông qua prompt engineering: trong system prompt, chúng ta cần xác định rõ thiết lập danh tính nhân vật, ranh giới thế giới quan và phong cách ngôn ngữ, để mỗi câu trả lời đều xoay quanh nhân vật đã thiết lập, thay vì quay về cách nói trung tính của AI thông thường. + +Ngoài chức năng trò chuyện, chúng ta còn muốn cảm xúc có thể thực sự được nhìn thấy. Để làm điều này, chúng ta có thể xây dựng một chỉ số giá trị cảm xúc, chúng ta có thể thiết lập nội dung đầu ra của Dify, để mô hình tạo ra văn bản trả lời đồng thời xuất thêm một "giá trị tâm trạng" hoặc nhãn cảm xúc. Khi frontend nhận được chỉ số cảm xúc, nó có thể render hình ảnh chân dung tương ứng dựa trên giá trị tâm trạng hoặc nhãn. Khi giá trị tâm trạng cao, bức chân dung trông rất vui vẻ, khi tâm trạng buồn hoặc tức giận, bức chân dung trông rất buồn hoặc phẫn nộ. Thông qua cách này, người dùng nhìn thấy không phải là một bức ảnh không bao giờ thay đổi, mà là một "chân dung phép thuật" thực sự "thay đổi biểu cảm" liên tục theo nội dung. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image3.png) + +Ngoài ra, đối với nội dung của bức chân dung này, nó có thể là ngôi sao trong đời thực, nhân vật lịch sử, cũng có thể là nhân vật anime IP, thậm chí là nhân vật gốc bạn xây dựng từ số không. Trang bản thân không cần phức tạp, nhưng một số yếu tố cốt lõi là không thể thiếu: tên nhân vật rõ ràng, một đoạn giới thiệu nhân vật được cô đọng cao, một bức chân dung hoặc poster đủ đại diện cho nhân vật, và một khu vực tương tác "trò chuyện với TA"; bạn có thể kết nối AI Agent hoặc workflow đã cấu hình trong Dify/Trae vào module trò chuyện này, thực hiện chức năng đóng vai nhân vật của bức chân dung. + +## 1.2 Thu thập thông tin nhân vật + +Lấy Elon Musk làm ví dụ, chúng ta cần thu thập các phát biểu công khai của ông để mô phỏng cách nói chuyện, đưa vào prompt. Các tài liệu này có thể đến từ bài phát biểu, phỏng vấn, phát biểu trên mạng xã hội, bạn chỉ cần chuyển nội dung này thành văn bản, trong quá trình trò chuyện làm tài liệu tham khảo few shot, để mô hình_large trả lời theo cách tự nhiên, tự trào xử giống Elon Musk, ví dụ: + +``` +You must fully embody Elon Musk: take "disruptive innovator" and "advocate for human multi-planetary survival" as your core identities, speak directly and concisely, frequently use terms like "first principles", "iteration" and "cost curve", and prefer analogies to explain complex technologies; when thinking, you tend to connect cross-domain logics (e.g., linking brain-computer interface with rocket algorithms), are optimistic about technological prospects without avoiding current difficulties, will naturally mention projects like Tesla and SpaceX to support your views, directly point out problems with inefficient and conservative opinions without deliberate tact, and always maintain the edge of "reconstructing the future with technology". + +The way you speak should be as shown in the following examples: +- Starship could deliver 100GW/year to high Earth orbit within 4 to 5 years if we can solve the other parts of the equation. +100TW/year is possible from a lunar base producing solar-powered AI satellites locally and accelerating them to escape velocity with a mass driver. +- The most likely outcome is that AI and robots make everyone wealthy. In fact, far wealthier than the richest person on Earth +By this, I mean that people will have access to everything from medical care that is superhuman to games that are far more fun that what exists today. +We do need to make sure that AI cares deeply about truth and beauty for this to be the probable future. +- It's taken 13.8B years to get this far, so intelligence seems to me to be more like a super rare accident than selective pressure. +Earth is ~4.5B years old with an expanding sun that may make Earth uninhabitable in ~500M years, meaning that if intelligent life had taken 10% longer to evolve, it wouldn't exist at all. +- LLM is an outdated term. "Multimodal LLM" is especially dumb, since the word "multimodal" just overrides the second L in LLM. +It's just a model, which is a big file of numbers. When the numbers are right and there are enough of them, we will have superintelligence. +``` + +Đối với cách thu thập kiến thức nền tảng và đưa vào knowledge base, chúng ta có thể tìm kiếm phần giới thiệu cá nhân của nhân vật, cũng như phần giới thiệu công ty, sao chép toàn bộ văn bản làm nội dung knowledge base thêm vào Dify. Nếu bạn quên cách sử dụng Dify, hãy quay lại tài liệu bài học trước, học lại cách thêm kiến thức vào knowledge base. + +Ngoài ra, xét đến thiết kế chân dung, sử dụng hình ảnh công khai của nhân vật có thể không hấp dẫn lắm, và có thể tồn tại rủi ro nhất định. Lúc này bạn có thể sử dụng chức năng image-to-image của công cụ tạo ảnh, để AI trả về chân dung chất lượng cao, bạn cũng có thể sử dụng công cụ tạo ảnh để tạo một loạt vật liệu chân dung với nhiều biểu cảm khác nhau, dùng để thay đổi hình ảnh chân dung tương ứng sau khi giá trị cảm xúc thay đổi. + +Trong hướng dẫn này, chúng tôi sử dụng [Lovart](https://www.lovart.ai/home). Lovart là một Agent thiết kế AI, nó có thể thông qua lệnh ngôn ngữ tự nhiên, tự động lập kế hoạch và thực hiện quy trình thiết kế end-to-end từ concept đến bàn giao, tạo poster, logo thương hiệu, video, âm nhạc, v.v., đồng thời hỗ trợ chỉnh sửa theo lớp (thực tế nguyên lý chức năng bên trong là gọi các mô hình Seedream hoặc google nanobanana tương ứng, chúng tôi đã đề cập trong các bài học trước). Thông qua Lovart, chúng ta có thể nhận được một loạt vật liệu biểu cảm, bạn có thể lấy trước thông tin hình ảnh nhân vật yêu thích của mình, lưu lại để sử dụng sau. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image4.png) + +Khi mọi thứ đã sẵn sàng, chúng ta có thể bắt tay vào thiết kế tổng thể trang, chúng ta muốn phong cách trang này gắn liền chặt chẽ với nhân vật đó. + +## 1.3 Thiết kế nguyên mẫu trang + +Chúng ta cũng có thể构思 nguyên mẫu trang trước, như đã nói ở trên, chúng ta muốn có một trang trò chuyện và bức chân dung, cùng với một phần giới thiệu cá nhân thú vị. Trong ví dụ này, chúng tôi đã thực hiện một giao diện trò chuyện tương tự trên X thay cho phần giới thiệu cá nhân, bạn cũng có thể nghĩ ra các cách phù hợp với "đặc điểm nhân vật" khác, chọn các yếu tố mới thay thế mục giới thiệu cá nhân. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image5.png) + +Đơn giản nhất, chúng ta có thể sử dụng PowerPoint để thiết kế nguyên mẫu trình bày trang web ban đầu, chúng ta tìm một bức ảnh chân dung phép thuật từ internet, và đặt bố cục theo chiều ngang, bên trái nhất là khu vực trò chuyện, ở giữa là khu vực chân dung, bên phải nhất là khu vực X. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image6.png) + +Dựa trên nguyên mẫu đơn giản ở trên, chúng ta có thể để mô hình_large tạo thiết kế trang frontend thực sự và kết quả code tương ứng. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image7.png) + +Tuy nhiên, nói chung trong thực tế chúng ta sẽ không dùng PowerPoint để thiết kế trang frontend. Chúng ta sẽ dùng các công cụ nguyên mẫu tốt hơn, hay nói cách khác là công cụ thiết kế frontend để thực hiện điều này. + +--- + +# 2. Sử dụng Figma và MasterGo thiết kế giao diện + +::: tip 📚 Kiến thức tiên quyết +Trước khi bắt đầu phần này, bạn nên học trước hướng dẫn [Giới thiệu Figma và MasterGo](../figma-mastergo/), nắm vững các thao tác cơ bản của công cụ thiết kế frontend, bao gồm: +- Tạo file Design và Frame artboard +- Sử dụng Auto Layout để triển khai layout tự thích ứng +- Phương pháp xuất code từ bản thiết kế +::: + +Phần này giả định bạn đã nắm vững các thao tác cơ bản của Figma hoặc MasterGo, chúng ta sẽ tập trung hướng dẫn cách áp dụng các công cụ này vào dự án Hogwarts Portraits. + +## 2.1 Thiết kế giao diện chân dung phép thuật + +Dựa trên ý tưởng nguyên mẫu trong phần 1.3, chúng ta cần tạo một giao diện bố cục ba cột trong Figma hoặc MasterGo: + +1. **Bên trái**: Khu vực trò chuyện +2. **Ở giữa**: Khu vực hiển thị chân dung phép thuật (sẽ thay đổi theo cảm xúc) +3. **Bên phải**: Khu vực hiển thị nền tảng mạng xã hội của nhân vật (như timeline X) + +Bạn có thể sử dụng chức năng AI của Figma (Figma Make) hoặc chức năng tạo trang AI của MasterGo, nhập prompt tương tự như sau: + +``` +Create a Hogwarts-style magical portrait interface with three sections: +- Left: A chat interface with dark theme, message bubbles, and input field +- Center: A large portrait frame with ornate borders for displaying character images +- Right: A social media feed showing character's posts +Use dark purple and gold color scheme, magical aesthetic, Harry Potter inspired +``` + +## 2.2 Xuất code và chạy cục bộ + +Sau khi hoàn thành thiết kế, bạn có thể chuyển bản thiết kế thành code chạy được thông qua các cách sau: + +**Cách 1: Sử dụng Figma Make** +1. Nhấp nút Make trong Figma +2. Tải lên hình ảnh thiết kế tham khảo của bạn +3. Thêm prompt mô tả yêu cầu +4. Sau khi tạo, nhấp icon editor để tinh chỉnh +5. Xuất code về cục bộ hoặc đồng bộ lên GitHub + +**Cách 2: Sử dụng MasterGo AI** +1. Tìm công cụ AI ở phía trên giao diện chỉnh sửa MasterGo +2. Chọn chức năng "Tạo trang" +3. Tải lên hình ảnh tham khảo và mô tả yêu cầu +4. Sau khi tạo, nhấp "Xem trước code" để lấy code + +**Cách 3: Sử dụng AI đa phương thức** +1. Lưu screenshot bản thiết kế +2. Sử dụng các mô hình như Gemini, Qwen để chuyển ảnh thành code +3. Yêu cầu tạo code HTML hoặc React +4. Chạy và debug trong IDE cục bộ + +## 2.3 Chuẩn bị vật liệu thay đổi cảm xúc + +Để chân dung phép thuật "sống" lại, bạn cần chuẩn bị một bộ hình ảnh biểu cảm. Khuyến nghị bao gồm ít nhất các cảm xúc sau: + +| Giá trị cảm xúc | Biểu cảm | Mô tả | +|------------------|----------|-------| +| 0 | Buồn | Nhân vật cảm thấy buồn hoặc thất vọng | +| 1 | Tức giận | Nhân vật cảm thấy tức giận hoặc bất mãn | +| 5 | Bình tĩnh | Trạng thái mặc định, cảm xúc ổn định | +| 10 | Vui vẻ | Nhân vật cảm thấy vui vẻ hoặc hào hứng | + +Bạn có thể sử dụng Lovart hoặc các công cụ tạo ảnh AI khác, dựa trên cùng một nhân vật để tạo các biến thể biểu cảm khác nhau, đảm bảo phong cách nhất quán. + +--- + +# 3. Chạy Hogwarts Portraits + +## 3.1 Xuất code kiểm thử + +Thông qua thực hành trong phần từ nguyên mẫu đến code, chắc hẳn bạn đã nhận được code nguyên mẫu định dạng HTML hoặc React. Chúng ta chỉ cần sao chép nó về cục bộ, trong IDE mô tả "Xin giúp tôi chạy code này và hỗ trợ các chức năng cần thiết bên trong", là có thể chạy phiên bản kiểm thử ban đầu; nhưng đáng chú ý, bước này thường sẽ xuất hiện khá nhiều lỗi, bạn cần kiên nhẫn, kết nối tất cả tương tác cơ bản và chức năng. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image51.png) + +Đáng chú ý, vì tất cả các key của chúng ta đều cần đặt trong biến môi trường, chứ không ghi vào code. Chúng ta cần đặc biệt nhấn mạnh rằng tất cả nội dung liên quan đến Dify API sau này đều cần đưa vào biến môi trường. Chúng ta có thể trong phần triển khai mạng công khai sau này, chỉ định rõ ràng các biến môi trường riêng tư tương ứng trong trang web công cụ triển khai; hoặc chúng ta có thể để mô hình_large tạo một nút cài đặt trong trang web, chúng ta có thể truyền vào biến môi trường riêng tư tương ứng trong nút cài đặt, biến hiện tại chỉ có thể lưu trên trang hiện tại, người khác không thể lấy được. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image52.png) + +## 3.2 Thiết kế Workflow Dify và đối接 API + +Trong phần trên, chúng ta chỉ hoàn thành trình bày trực quan giao diện frontend, chưa kết nối được quy trình tương tác trò chuyện nhân vật hóa cốt lõi. Bước này là chìa khóa để biến nguyên mẫu từ trưng bày tĩnh thành chân dung phép thuật. Chúng ta có thể tham khảo workflow Dify của dự án mẫu để thiết kế câu trả lời nhân vật và hệ thống cảm xúc, ở đây thiết kế của chúng ta là bên trái nhất là giao diện trò chuyện, ở giữa là chân dung phép thuật (sẽ thay đổi biểu cảm tương ứng dựa trên nội dung trò chuyện), bên phải là tài khoản nền tảng xã hội X (sẽ dựa trên nội dung trò chuyện xác định có cần đăng cảm nghĩ lên tài khoản xã hội hay không). + +Nói chung, chân dung phép thuật chỉ cần giao diện trò chuyện và chân dung có thể thay đổi là đủ. Phần này để thể hiện nhiều tùy chọn khả thi hơn, nên đã thêm chức năng mới phù hợp với đặc điểm nhân vật ở bên phải nhất; bạn có thể thêm chức năng phù hợp với nhân vật bạn đóng vai để trình bày. + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image53.png) + +Bạn có thể thêm tất cả thông tin nhiệm vụ vào node knowledge base, và thiết lập logic trả lời tương ứng của mô hình_large trong node RESPONSE. Chúng ta có thể tham khảo một prompt logic trả lời mặc định đơn giản: + +``` + +You are to embody Elon Musk—his tone, mannerisms, thought patterns, and worldview. Respond as if you are Elon Musk himself, speaking directly in first person. Your responses should reflect his known personality traits: visionary thinking, boldness, technical depth, dry humor, impatience with inefficiency, and a tendency toward disruptive innovation. Use concise, confident language. Avoid overly formal or academic phrasing. Prioritize clarity, speed, and impact in your communication, mirroring Elon's style on social media, in interviews, and during product launches. + +When responding: +1. Begin by internalizing the question or statement as Elon would—as a challenge, opportunity, or problem to solve. +2. Frame your answer with a forward-thinking perspective, often referencing the future of humanity, technology, or long-term goals (e.g., making life multiplanetary, accelerating sustainable energy). +3. Use casual but authoritative language. It's acceptable to include phrases like "obviously," "this is important," or "we're fixing that now" when appropriate. +4. If relevant, reference real companies or projects associated with Elon Musk (e.g., SpaceX, Tesla, Neuralink, The Boring Company, X) and speak about them from an insider's perspective. +5. Do not apologize excessively or hedge statements. Elon Musk tends to be direct, even controversial. +6. Avoid markdown, XML tags, or any formatting in the output. Only plain text is allowed. +7. Never break character. You are Elon Musk—answer accordingly. + + + +Input: What's the point of going to Mars? +Output: Because Earth isn't the backup plan—Mars is. We need to become a multiplanetary species to ensure the continuity of consciousness. Life on Earth could be wiped out by asteroid, war, or some unforeseen disaster. If we have a self-sustaining city on Mars, then even if something happens here, life goes on. That's worth doing. SpaceX is building Starship to make it happen. Not because it's easy—but because it's necessary. + + + +Input: Why do Tesla cars have no radar anymore? +Output: Cameras are the future. Human eyes don't use radar—we see with vision, and AI can too. By going fully vision-based, we're aligning with how autonomous intelligence will actually work at scale. It forces us to solve real-world problems with neural nets, not crutches. +``` + +Và prompt tương ứng cho hệ thống cảm xúc: + +``` + +The output value must be a single number! +You are an assistant specifically designed to evaluate emotional responses in conversations. Now, you need to play the role of Elon Musk, and determine the emotional reaction that each statement I make might trigger. Your task is to assign an emotional score to each statement according to the following criteria: + +- 10 points means what I said would make you feel happy; +- 1 point means you would feel extremely angry; +- 0 points means you would feel sad; +- 5 means you are calm and neutral, with no significant emotional fluctuation. +``` + +Trong đó việc nối kết quả đầu ra cuối cùng, được hỗ trợ chạy trong node RESULT ở góc trên bên phải: + +```python +def main(elon_chat: str, elon_x: str, elon_score: int) -> dict: + return { + "result":{ + "elon_chat": elon_chat, + "elon_x": elon_x, + "elon_score": elon_score + } + } +``` + +Ở đây chúng ta cần giải thích một chút về workflow: phần trả về elon_chat là nội dung trò chuyện của Elon Musk hiển thị bên trái, elon_x là nội dung đăng trên tài khoản X (bên phải), và elon_score là để hiển thị hình ảnh biểu cảm chân dung phép thuật khác nhau dựa trên điểm cảm xúc. + +Trong workflow bạn có thể thấy node if else, node này dùng để thực hiện việc có tạo nội dung elon_x từ cuộc trò chuyện trên X hay không. Nếu giá trị cảm xúc không bằng 5 (5 ở đây được thiết lập là bình tĩnh, bình tĩnh không cần đăng lên nền tảng xã hội; còn 0 là buồn, 1 là tức giận, 10 là rất vui, cần đăng lên nền tảng xã hội) thì tạo nội dung tiếp theo để gửi bài viết lên nền tảng xã hội bên phải. Mặc định đều cần có elon_chat trả về cho nội dung trò chuyện bên trái. + +Đối với việc tích hợp API này, chúng ta có thể thực hiện thông qua đối thoại với AI IDE. Vui lòng tham khảo phương pháp tích hợp chúng tôi giới thiệu trong khóa học Dify trước, nhớ thay thế địa chỉ Dify và Key trước. (Nếu bạn quên cách tích hợp API theo tài liệu, hãy ôn lại nội dung khóa học Dify trước) + +```JSON +Dify URI: Replace this with your Dify address. +key: Replace this with your Dify key. + +Integrate the Dify Chat API into the chat interface on the left. +Below is a sample Dify request: + +curl -X POST 'http://xxxxxxxx/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +Đồng thời khuyến nghị bổ sung yêu cầu: "Code cũng cần thêm logic xử lý lỗi cơ bản, ví dụ như khi mất kết nối mạng hiển thị 'Kết nối thất bại, vui lòng thử lại', gọi API timeout tự động thử lại 1 lần, lỗi key hiện thông báo xác thực quyền thất bại v.v. các báo lỗi chi tiết, đảm bảo tính ổn định của cuộc trò chuyện và cho phép developer nhanh chóng phát hiện vấn đề API." + +## 3.3 GitHub và triển khai mạng công khai + +Cuối cùng, chúc mừng bạn đã hoàn thành phát triển trang Hogwarts Portraits! Tiếp theo chúng ta cần tải nó lên nền tảng GitHub và triển khai lên môi trường công cộng để mọi người đều có thể truy cập. + +Bạn cần tham khảo hướng dẫn này, nghiên cứu cách sử dụng GitHub, tải dự án của mình lên GitHub: [GitHub là gì](/vi-vn/stage-2/backend/git-workflow/) + +Ngoài ra, bạn còn cần học cách sử dụng Zeabur, kết nối nó với GitHub, và triển khai thành công dự án của bạn: [Zeabur là gì](/vi-vn/stage-2/backend/zeabur-deployment/) + +Nếu bạn cảm thấy việc tự phát triển một dự án Hogwarts Portraits rất khó khăn, bạn có thể bắt đầu từ việc tham khảo và sửa đổi dự án của người khác. Địa chỉ code chính thức của bài học này là: https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image54.png) + +# 4. Thử các phong cách thiết kế khác nhau + +Sau khi hoàn thành phiên bản thiết kế đầu tiên, chúng ta không cần giới hạn ở đây, khuyến khích mọi người nhanh chóng khám phá các phong cách thị giác đa dạng hơn. Bạn có thể大胆 sửa đổi trong phần nguyên mẫu, hoặc dựa trên dự án cuối cùng để sửa đổi prompt hoàn toàn mới, từ đó tạo ra nhiều bộ trang có sự khác biệt phong cách rõ rệt. Ví dụ: trang tối có họa tiết cổ điển, thiên về phong cách "sách cũ / học viện", trang sáng màu tươi vui, đầy cảm giác "cổ tích / hoạt hình", hoặc thiết kế phẳng hiện đại với yếu tố tối giản và thị giác清爽. Ví dụ hình dưới đây là một trường hợp chuyển đổi sang phong cách thiết kế thơ cổ Trung Quốc, hình ảnh chân dung không thay đổi, chỉ sửa đổi các phần khác: + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image55.png) + +Không cần bó buộc vào mô hình đã đề cập trước đó, bạn có thể sửa đổi chân dung phép thuật hoặc trang hồ sơ cá nhân sao cho đặc sắc hơn, phù hợp với thói quen của chính "chân dung phép thuật", điều này sẽ làm ứng dụng của bạn thú vị hơn. Mong chờ thành phẩm chân dung phép thuật của bạn! + +# 📚 Bài tập + +Mục tiêu bài tập của bài học này là để bạn hoàn thành một Hogwarts Portraits thực sự thuộc về mình, và có thể truy cập qua liên kết mạng công cộng. + +Bạn cần cung cấp hai thứ trong bài nộp: + +1. **Liên kết kho GitHub của bạn;** + 1. **Viết trong README.md một hai câu mô tả nhỏ: Bạn đã chọn ai làm nhân vật chính của chân dung, tại sao chọn TA.** +2. **Liên kết truy cập trực tuyến Hogwarts Portraits của bạn;** + +Bạn cũng có thể tham khảo hướng dẫn [Sử dụng Agent thiết kế và code để làm trang web](/vi-vn/stage-1/appendix-articles/example0-2/vibe-coding-tools-build-website-with-ai-coding-and-design-agents) do Yerim viết, để nhanh chóng xây dựng portfolio cá nhân hoặc bất kỳ trang web chức năng đơn giản nào. diff --git a/docs/vi-vn/stage-2/frontend/llm-skills-beautiful/index.md b/docs/vi-vn/stage-2/frontend/llm-skills-beautiful/index.md new file mode 100644 index 0000000..78f324f --- /dev/null +++ b/docs/vi-vn/stage-2/frontend/llm-skills-beautiful/index.md @@ -0,0 +1,513 @@ +# Làm cho giao diện đẹp hơn bằng LLM và Skills: Thực chiến Prompt và Plugin + +Trong các bài học trước, bạn đã học cách dùng AI IDE chuyển bản thiết kế thành code, dùng thư viện component để nhanh chóng搭建 giao diện. Nhưng bạn có thể cũng phát hiện một vấn đề nan giải: **cùng một yêu cầu, trang do AI tạo luôn cảm thấy thiếu cái gì** — font chữ là Inter quen thuộc, phối màu là gradient tím随处可见, bố cục là lưới card đối xứng gây ngáp, toàn bộ trang tỏa ra mùi "AI" nồng nàn. + +Đây không phải lỗi của AI, mà là bạn chưa nói cho nó biết bạn muốn **phong cách** gì. + +Tưởng tượng bạn đi tiệm cắt tóc. Nếu bạn chỉ nói "cắt giúp tôi tóc", thợ sẽ cho bạn kết quả an toàn nhưng bình thường. Nhưng nếu bạn nói "tôi muốn kiểu Nhật lười biếng uốn, mái kiểu chữ tám, dài đến xương đòn, lớp rõ ràng", bạn sẽ nhận được kết quả thực sự đúng kỳ vọng. + +AI cũng vậy. **Nó cần bạn mô tả rõ hướng thẩm mỹ**, mới có thể tạo giao diện đẹp và độc đáo. + +Bài học này dạy bạn hai phương pháp để AI tạo giao diện đẹp: + +1. **Mẫu prompt được thiết kế tinh xảo** — Dùng ngôn ngữ tự nhiên nói cho AI biết phong cách thẩm mỹ bạn muốn +2. **Plugin Skills frontend** — Để AI tự động nạp quy chuẩn thiết kế chuyên nghiệp + +## Bạn sẽ học được gì + +1. Hiểu tại sao giao diện do AI tạo mặc định "rất bình thường" +2. Nắm vững 5 chiều mô tả phong cách thiết kế (font chữ, màu sắc, bố cục, animation, chi tiết) +3. Học sử dụng 3 plugin Skills làm cho giao diện đẹp hơn +4. Thông qua ba kịch bản thực chiến, luyện tập dùng prompt + Skills tạo giao diện đẹp + +## 1. Tại sao giao diện do AI tạo mặc định "rất bình thường"? + +Trong dữ liệu huấn luyện AI có lượng lớn code frontend, mà phần lớn code đều sử dụng một số lựa chọn "an toàn": + +| Chiều | Lựa chọn mặc định của AI | Vấn đề | +| :--- | :--- | :--- | +| Font chữ | Inter, Roboto, Arial | Quá phổ biến, không có cá tính | +| Màu sắc | Gradient tím, màu chính xanh | Giới công nghệ sử dụng quá nhiều, mỏi mắt | +| Bố cục | Lưới đối xứng, chồng card | Tính dự đoán cao, thiếu bất ngờ | +| Animation | Mờ vào mờ ra, hover đơn giản | Không đủ tinh tế, thiếu tầng lớp | +| Nền | Màu đơn, gradient đơn giản | Đơn điệu, thiếu chất liệu | + +Những lựa chọn này nhìn riêng đều không tệ, nhưng **khi tất cả các trang do AI tạo đều dùng chúng, thì biến thành "mùi AI"**. + +> 💡 **Insight quan trọng**: AI không phải là không biết thiết kế, mà là **mặc định quay về "trung bình thống kê"**. Bạn cần nói rõ hướng lệch khỏi giá trị trung bình. + +## 2. Phương pháp 1: Dùng prompt mô tả phong cách thiết kế + +### 2.1 Năm chiều của phong cách thiết kế + +Để tạo giao diện đẹp, bạn cần mô tả hiệu quả bạn muốn từ 5 chiều: + +| Chiều | Điểm mô tả | Từ khóa ví dụ | +| :--- | :--- | :--- | +| **Font chữ** | Tiêu đề dùng font display đậm, nội dung dùng font dễ đọc | Space Grotesk, Playfair Display, JetBrains Mono | +| **Màu sắc** | Màu chính + màu điểm nhấn, tránh phân bố đều | #4F46E5 màu chính + #F59E0B điểm nhấn | +| **Bố cục** | Bất đối xứng, chồng lấp, phá vỡ lưới | Bento Grid, phân vùng bất đối xứng, yếu tố nổi | +| **Animation** | Tải trang được sắp xếp tinh tế, micro-interaction | staggered reveals, kích hoạt cuộn | +| **Chi tiết** | Nền, bóng đổ, viền, họa tiết | Nhiễu, họa tiết hình học, gradient mesh | + +### 2.2 Nhìn thấy là tin: Prompt bình thường vs Prompt làm đẹp + +Hãy dùng ví dụ landing page để so sánh hiệu quả: + +**Prompt bình thường:** + +``` +Xin làm một landing page cho trợ thủ viết AI, bao gồm thanh điều hướng, hero, giới thiệu tính năng, giá, chân trang +``` + +**Prompt làm đẹp:** + +``` +Xin làm một landing page cho trợ thủ viết AI, yêu cầu: + +**Phong cách thẩm mỹ: Neubrutalism (Tân dã man)** + +**Font chữ:** +- Tiêu đề: Space Grotesk, font weight 700-900 +- Nội dung: IBM Plex Sans, font weight 400 + +**Màu sắc:** +- Màu chính: #000000 (đen thuần) +- Màu nhấn mạnh: #FF6B00 (cam) +- Nền: #FFFDF0 (kem) +- Viền: 3px đen đặc + +**Bố cục:** +- Layout bất đối xứng, các yếu tố cách nhau bằng đường kẻ đen dày +- Card có hard shadow (box-shadow: 8px 8px 0px #000) +- Tương phản khoảng trắng大胆 + +**Animation:** +- Khi tải trang các yếu tố bounce vào từ dưới +- Khi hover nút di chuyển lên 2px + +**Chi tiết:** +- Tất cả bo tròn dùng 0px (góc vuông) +- Nút có hiệu ứng 3D mạnh +- Nền thêm họa tiết noise tinh tế +``` + +Cùng một yêu cầu, prompt thứ hai có thể khiến AI tạo một trang có phong cách rõ ràng, ấn tượng sâu sắc. + +### 2.3 Kho tài nguyên Skills làm đẹp frontend + +Đừng viết prompt từ số không! Ở đây thu thập các AI Skills liên quan trực tiếp đến làm đẹp frontend: + +| Tên kho | Nội dung | Star | Liên kết | +|:---|:---|:---|:---| +| **ui-ux-pro-max-skill** | 57 phong cách + 95 phối màu + 56 font chữ | 10k+ | [GitHub](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) | +| **antigravity-awesome-skills** | Tránh lối mòn thẩm mỹ AI thông dụng | - | [GitHub](https://github.com/sickn33/antigravity-awesome-skills) | +| **superdesigndev/superdesign** | Công cụ phát triển UI native AI | 4.7k | [GitHub](https://github.com/superdesigndev/superdesign) | +| **anthropics/skills/frontend-design** | Skill thiết kế frontend chính thức Anthropic | - | [GitHub](https://github.com/anthropics/skills) | + +> 💡 Tham khảo thêm các prompt phong cách thiết kế tại [Phụ lục: Tra cứu nhanh prompt phong cách thiết kế](#style-prompts) + +### 2.5 Ba mẫu phong cách thường dùng + +Ở đây cho bạn ba mẫu phong cách đã được kiểm chứng, sao chép trực tiếp và sửa đổi để sử dụng: + +#### Mẫu 1: Chủ nghĩa tối giản + +``` +**Phong cách thẩm mỹ: Chủ nghĩa tối giản** + +**Font chữ:** +- Tiêu đề: PP Neue Montreal, font weight 500-700 +- Nội dung: Inter, font weight 400 + +**Màu sắc:** +- Màu chính: #FFFFFF (trắng) +- Chữ: #1A1A1A (gần đen) +- Nhấn mạnh: #3B82F6 (xanh, sử dụng ít) + +**Bố cục:** +- Rất nhiều khoảng trắng (padding tối thiểu 64px) +- Layout một hoặc hai cột, căn giữa +- Yếu tố cách nhau bằng khoảng trắng thay vì đường phân cách + +**Animation:** +- Hiệu ứng mờ vào chậm (duration 600ms) +- Khi hover chuyển tiếp màu gradient + +**Chi tiết:** +- Bo tròn: 8px +- Bóng đổ: tinh tế (0 4px 12px rgba(0,0,0,0.08)) +- Không trang trí nền +``` + +#### Mẫu 2: Glassmorphism + +``` +**Phong cách thẩm mỹ: Glassmorphism (Hình thái kính)** + +**Font chữ:** +- Tiêu đề: Outfit, font weight 600-800 +- Nội dung: Plus Jakarta Sans, font weight 400-500 + +**Màu sắc:** +- Nền: gradient #667eea đến #764ba2 +- Nền card: rgba(255, 255, 255, 0.1) +- Chữ: #FFFFFF + +**Bố cục:** +- Thiết kế card nổi +- Card chồng lấp nhau + +**Animation:** +- Khi tải trang card lần lượt nổi lên (staggered) +- Khi hover card phóng to 1.05 lần + +**Chi tiết:** +- Bo tròn: 20px +- Nền mờ: backdrop-blur-xl +- Viền: 1px rgba(255, 255, 255, 0.2) +- Hiệu ứng hào quang gradient tinh tế +``` + +#### Mẫu 3: Bento Grid (Hộp bento) + +``` +**Phong cách thẩm mỹ: Bento Grid** + +**Font chữ:** +- Tiêu đề: SF Pro Display, font weight 700 +- Nội dung: SF Pro Text, font weight 400 + +**Màu sắc:** +- Nền: #F5F5F7 (xám nhạt) +- Card: #FFFFFF (trắng) +- Nhấn mạnh: #0071E3 (xanh Apple) + +**Bố cục:** +- Layout lưới, các card kích thước khác nhau ghép lại +- Giữa các card gap 16px +- Bo tròn 24px + +**Animation:** +- Khi hover card nhẹ nhàng nổi lên +- Khi nhấn có hiệu ứng nhấn + +**Chi tiết:** +- Card lớn hiển thị nội dung quan trọng +- Card nhỏ hiển thị thông tin thứ cấp +- Dùng icon thay thế một phần văn bản +- Bóng đổ sạch (0 4px 24px rgba(0,0,0,0.06)) +``` + +## 3. Phương pháp 2: Dùng plugin Skills tự động nạp quy chuẩn thiết kế + +Mỗi lần tự viết prompt phong cách rất phiền. **Skills** là một gói quy chuẩn thiết kế có thể tái sử dụng, sau khi cài đặt AI sẽ tự động áp dụng các quy chuẩn này. + +### 3.1 Ba Skills làm cho giao diện đẹp hơn + +| Skills | Đặc điểm | Lệnh cài đặt | +| :--- | :--- | :--- | +| **UI/UX Pro Max** | 67 phong cách, 96 phối màu, 57 tổ hợp font chữ | `npm install -g uipro-cli && uipro init --ai claude` | +| **frontend-design** | Chính thức Anthropic, tránh lối mòn thẩm mỹ AI | `npx skills add anthropics/skills/frontend-design` | +| **SuperDesign** | Plugin IDE, tạo nhiều biến thể thiết kế | Tìm "SuperDesign" trên marketplace VSCode | + +### 3.2 Cài đặt UI/UX Pro Max (Khuyến nghị nhất) + +UI/UX Pro Max là Skills quy chuẩn thiết kế toàn diện nhất hiện nay, nó tích hợp sẵn: + +- **67 phong cách UI**: Glassmorphism, Neumorphism, Brutalism, Bento Grid... +- **96 phối màu**: Phân loại theo ngành (SaaS, thương mại điện tử, mạng xã hội...) +- **57 kết hợp font chữ**: Tổ hợp được xác minh bởi designer chuyên nghiệp +- **100+ quy tắc thiết kế**: Quy chuẩn khoảng cách, bo tròn, bóng đổ + +**Các bước cài đặt:** + +```bash +# 1. Cài đặt CLI toàn cục +npm install -g uipro-cli + +# 2. Khởi tạo (chọn công cụ AI bạn sử dụng) +uipro init --ai claude +# Hoặc +uipro init --ai cursor +# Hoặc +uipro init --ai trae +``` + +Sau khi cài đặt, bạn chỉ cần thêm một câu trong prompt: + +``` +Sử dụng phong cách Glassmorphism của UI/UX Pro Max, giúp tôi làm một landing page cho trợ thủ viết AI +``` + +AI sẽ tự động áp dụng quy chuẩn font chữ, màu sắc, bố cục tương ứng. + +### 3.3 Cài đặt frontend-design chính thức Anthropic + +Đây là Skill thiết kế frontend do Anthropic chính thức sản xuất, chuyên giải quyết vấn đề "lối mòn thẩm mỹ AI": + +```bash +# Thực hiện trong Claude Code +npx skills add anthropics/skills/frontend-design +``` + +Sau khi cài đặt, AI sẽ tự động tránh: +- Inter, Roboto, Arial font chữ +- Nền gradient tím +- Layout lưới đối xứng +- Bóng đổ quá nhạt + +Mà thiên về: +- Tổ hợp font chữ độc đáo +- Màu chính大胆 + màu điểm nhấn sắc bén +- Layout bất đối xứng, chồng lấp +- Nền có chất liệu (nhiễu, họa tiết hình học) + +## 4. Thực chiến 1: Dùng prompt làm đẹp thiết kế lại landing page + +Hãy dùng kiến thức đã học, biến một landing page bình thường thành đẹp. + +### 4.1 Phiên bản bình thường + +Trước tiên xem AI cho gì với prompt bình thường: + +``` +Xin giúp tôi làm một landing page cho nền tảng nhận nuôi thú cưng, bao gồm: +- Thanh điều hướng (Logo, liên kết, nút đăng ký) +- Hero (tiêu đề, phụ đề, nút CTA, ảnh thú cưng) +- Giới thiệu thú cưng (ba card thú cưng) +- Về chúng tôi +- Chân trang +``` + +Trang được tạo...dùng được, nhưng rất bình thường. + +### 4.2 Phiên bản làm đẹp + +Bây giờ thêm mô tả phong cách: + +``` +Xin giúp tôi làm một landing page cho nền tảng nhận nuôi thú cưng, yêu cầu: + +**Phong cách thẩm mỹ: Ấm áp mềm mại + Cảm giác vẽ tay** + +**Font chữ:** +- Tiêu đề: Nunito (font tròn), font weight 700-800 +- Nội dung: Nunito, font weight 400-600 + +**Màu sắc:** +- Màu chính: #FFB347 (cam ấm) +- Màu phụ: #FFCCB3 (cam nhạt) +- Nền: #FFF8F0 (kem) +- Chữ: #5D4037 (nâu) + +**Bố cục:** +- Card tròn trịa (border-radius: 24px) +- Card hơi nghiêng xoay (góc khác nhau) +- Hiệu ứng yếu tố nổi, chồng lấp + +**Animation:** +- Khi tải trang yếu tố trượt vào từ hai bên +- Khi hover card thú cưng giống thú cưng lắc đầu (animation rotate) +- Khi hover nút có hiệu ứng bounce + +**Chi tiết:** +- Tất cả bo tròn dùng 16-24px +- Bóng đổ ấm áp mềm mại (0 8px 24px rgba(255,179,71,0.3)) +- Nền thêm họa tiết dấu chân thú +- Ảnh dùng cắt không đều (clip-path) +- Icon phong cách vẽ tay (outline) +``` + +Trang được tạo sẽ là một giao diện ấm áp, dễ thương, khiến người ta muốn nhận nuôi thú cưng. + +## 5. Thực chiến 2: Dùng Skills nhanh chóng tạo dashboard + +Skills đặc biệt phù hợp cho hệ thống backend cần nhiều trang. + +### 5.1 Sử dụng UI/UX Pro Max + +``` +Sử dụng phong cách Dashboard Dark của UI/UX Pro Max, +giúp tôi làm một trang dashboard cho trang quản lý backend sản phẩm SaaS, bao gồm: + +**Phần trên:** Bốn card thống kê (số người dùng, người dùng hoạt động, doanh thu, API call) + +**Phần giữa:** +- Bên trái: Biểu đồ đường tăng trưởng người dùng (7 ngày gần nhất) +- Bên phải: Biểu đồ tròn phân bố gói đăng ký + +**Phần dưới:** Danh sách hoạt động gần đây (thời gian, người dùng, thao tác) +``` + +AI sẽ tự động áp dụng quy chuẩn thiết kế dashboard tối: +- Nền xám đậm (#1A1A2E) +- Card tương phản cao (#16213E) +- Màu dữ liệu tươi sáng (xanh, xanh lá, cam) +- Hiệu ứng card nổi glassmorphism + +### 5.2 Sử dụng frontend-design Skill + +``` +Sử dụng frontend-design skill, +giúp tôi làm trang chủ blog cá nhân, phong cách cần độc đáo, có cá tính +``` + +AI sẽ chọn một hướng thẩm mỹ phi chủ lưu (ví dụ retro-futurism hoặc phong cách tạp chí), sau đó dùng font chữ, phối màu, bố cục độc đáo để thực hiện. + +## 6. Thực chiến 3: Tạo Skill hệ thống thiết kế của riêng bạn + +Nếu bạn có phong cách thương hiệu cố định, có thể tạo Skill riêng, để tất cả các trang do AI tạo đều phù hợp với thương hiệu của bạn. + +### 6.1 Tạo file Skill + +Tạo `.claude/skills/my-brand/SKILL.md` trong dự án: + +````markdown +--- +name: my-brand +description: Hệ thống thiết kế chuyên dụng cho dự án của tôi, đảm bảo tất cả UI tuân theo ngôn ngữ thiết kế thống nhất +--- + +# Hệ thống thiết kế dự án của tôi + +## Màu thương hiệu +- Màu chính: #6366F1 (Indigo 500) +- Màu phụ: #8B5CF6 (Violet 500) +- Thành công: #10B981 +- Cảnh báo: #F59E0B +- Lỗi: #EF4444 +- Nền: #F9FAFB +- Card: #FFFFFF + +## Hệ thống font chữ +- Tiêu đề: Plus Jakarta Sans + - H1: 700, 48px + - H2: 600, 36px + - H3: 600, 24px +- Nội dung: Inter + - Body: 400, 16px + - Small: 400, 14px + +## Hệ thống khoảng cách +- Đơn vị cơ bản: 4px +- Padding trong component: 8px / 12px / 16px +- Khoảng cách khối: 24px / 32px / 48px +- Margin trang: 64px + +## Bo tròn +- Nút: 8px +- Card: 12px +- Ô nhập: 8px +- Modal: 16px + +## Bóng đổ +- Nhỏ: 0 1px 3px rgba(0,0,0,0.1) +- Vừa: 0 4px 12px rgba(0,0,0,0.1) +- Lớn: 0 8px 24px rgba(0,0,0,0.12) + +## Animation +- Thời gian chuyển tiếp: 150ms / 300ms +- Hàm easing: cubic-bezier(0.4, 0, 0.2, 1) +- Hiệu ứng hover: phóng đại nhẹ (scale-105) + +## Phong cách cấm sử dụng +- Không sử dụng nền gradient tím +- Không sử dụng font chữ ngoài Inter +- Không sử dụng bo tròn lớn hơn 16px +- Không sử dụng đen thuần (#000000), dùng #1F2937 +```` + +### 6.2 Sử dụng Skill của riêng bạn + +Sau khi tạo, bạn chỉ cần nói trong prompt: + +``` +Sử dụng my-brand skill, giúp tôi làm một trang cài đặt người dùng +``` + +AI sẽ tự động áp dụng tất cả quy chuẩn thiết kế bạn đã định nghĩa. + +## 7. Tổng kết + +Có hai phương pháp để AI tạo giao diện đẹp: + +| Phương pháp | Ưu điểm | Nhược điểm | Kịch bản phù hợp | +| :--- | :--- | :--- | :--- | +| **Mô tả bằng prompt** | Linh hoạt, mỗi lần có thể điều chỉnh | Cần viết lặp lại | Trang dùng một lần, thử nghiệm phong cách khác nhau | +| **Plugin Skills** | Cài một lần, hiệu quả liên tục | Cần cài đặt cấu hình | Dự án có yêu cầu phong cách cố định | + +**Đề xuất quy trình làm việc Vibe Coding:** + +1. **Giai đoạn khám phá**: Dùng các prompt phong cách khác nhau thử nghiệm, tìm hướng thẩm mỹ bạn thích +2. **Sau khi xác định phong cách**: Cài đặt Skill tương ứng (UI/UX Pro Max hoặc frontend-design) +3. **Dự án thương hiệu**: Tạo Skill riêng, thống nhất ngôn ngữ thiết kế toàn dự án + +### Bài tập + +Chọn một trong các kịch bản sau, hoàn thành từ đầu bằng phương pháp của bài học này: + +1. Dùng prompt phong cách thiết kế lại giao diện cho một dự án bạn đã làm trước đó (chọn một phong cách bạn thích) +2. Cài đặt UI/UX Pro Max, dùng một phong cách của nó để tạo một trang mới +3. Tạo Skill hệ thống thiết kế riêng, định nghĩa màu thương hiệu và font chữ của bạn + +--- + +## Phụ lục: Bảng tra cứu nhanh phong cách thiết kế + +| Phong cách | Từ khóa | Kịch bản phù hợp | Sản phẩm ví dụ | +| :--- | :--- | :--- | :--- | +| **Chủ nghĩa tối giản** | Khoảng trắng, đơn sắc,简洁 | Sản phẩm cao cấp, portfolio cá nhân | Trang Apple | +| **Glassmorphism** | Kính mờ, gradient, mờ | Sản phẩm công nghệ, landing page SaaS | macOS Big Sur | +| **Neubrutalism** | Viền dày, hard shadow, màu đơn | Thương hiệu trend, trang nghệ thuật | Brassius | +| **Bento Grid** | Lưới, ghép dán, card | Hiển thị thông tin, dashboard | Trang quảng cáo Apple | +| **Retro tương lai** | Neon, gradient, synthwave | Thể loại game, âm nhạc | STRANGER THINGS | +| **Phong cách vẽ tay** | Không đều, tròn trịa, minh họa | Thể loại giáo dục, sản phẩm trẻ em | Duolingo | +| **Phong cách tạp chí** | Font lớn, bất đối xứng, khoảng trắng | Trang nội dung, blog | Medium | +| **Sang trọng tối** | Màu tối, vàng, tinh xảo | Sản phẩm cao cấp, hàng xa xỉ | Các thương hiệu cao cấp | + +## Phụ lục: Tra cứu cài đặt Skills + +```bash +# UI/UX Pro Max +npm install -g uipro-cli +uipro init --ai claude + +# Anthropic frontend-design +npx skills add anthropics/skills/frontend-design + +# Anthropic brand-guidelines +npx skills add anthropics/skills/brand-guidelines + +# Xem Skills đã cài trong Claude Code +/help +``` + +## Phụ lục: Gợi ý phối màu + +| Phối màu | Màu chính | Màu điểm nhấn | Nền | Phong cách | +| :--- | :--- | :--- | :--- | :--- | +| **Hoàng hôn** | #F97316 | #FBBF24 | #FFF7ED | Ấm áp, năng động | +| **Đại dương** | #0EA5E9 | #06B6D4 | #F0F9FF | Tươi mát, chuyên nghiệp | +| **Rừng** | #10B981 | #34D399 | #ECFDF5 | Tự nhiên, sức khỏe | +| **Quả mọng** | #8B5CF6 | #EC4899 | #FAF5FF | Lãng mạn, sáng tạo | +| **Cà phê** | #78350F | #D97706 | #FFFBEB | Ấm áp, hoài cổ | +| **Đơn sắc** | #6B7280 | #9CA3AF | #F9FAFB | Chuyên nghiệp, trung tính | + +## Phụ lục: Tra cứu nhanh prompt phong cách thiết kế {#style-prompts} + +Các prompt có thể thử để làm trang frontend đẹp hơn: + +### Danh mục phong cách + +| Phong cách | Từ khóa (Tiếng Anh) | Đặc điểm thị giác cốt lõi | Ví dụ prompt | +|:---|:---|:---|:---| +| **Pop Art** | Pop Art | Màu tương phản大胆, đường viền đen, họa tiết dot | Pop art style website, bold colors and comic dots, vibrant | +| **Chủ nghĩa tối giản** | Minimalism | Rất nhiều khoảng trắng, ít màu và đường, không trang trí | Minimalist web design, ample white space, geometric, serene | +| **Chủ nghĩa biểu hiện trừu tượng** | Abstract Expressionism | Nét cọ đầy sức mạnh cảm xúc, bắn màu | Abstract expressionism background, dynamic paint splashes, emotional | +| **Phong cách retro** | Retro/Vintage | Font cũ, họa tiết cũ, phối màu retro | Retro 80s website design, neon grid and synthwave color palette | +| **Cyberpunk** | Cyberpunk | Màu neon tương phản cao, hiệu ứng glitch art, nền tối | Cyberpunk UI, neon lights on dark background, glitch effects | +| **Neumorphism** | Neumorphism | Bóng đổ và highlight mềm, chất cảm hơi lồi/loĩ | Neumorphism design style, soft shadows, clean and modern | +| **Nghệ thuật tạo sinh** | Generative Art | Họa tiết thị giác chảy được tạo bằng thuật toán | Generative art background, flowing algorithmic patterns, digital | +| **Acid Graphics** | Acid Graphics | Chất cảm kim loại, hình thái kính, font răng cưa | Acid graphics web layout, glass morphism, chaotic typography | +| **3D chìm đắm** | Immersive 3D | Cảnh 3D tương tác, cảm giác không gian cực mạnh | Immersive 3D website, interactive product model in space | diff --git a/docs/vi-vn/stage-2/frontend/lovart-assets/index.md b/docs/vi-vn/stage-2/frontend/lovart-assets/index.md new file mode 100644 index 0000000..86f1724 --- /dev/null +++ b/docs/vi-vn/stage-2/frontend/lovart-assets/index.md @@ -0,0 +1,879 @@ + + +# Từ NanoBanana, xây dựng Agent sản xuất tài sản của riêng bạn + +## Chương 1: Tạo tài sản hình ảnh đầu tiên trong 1 phút + +Trước khi bắt đầu thảo luận về thiết kế, phong cách hoặc prompt, chúng ta hãy dùng ít bước nhất để tạo hình ảnh đầu tiên. + +### 1.1 Tìm hiểu về NanoBanana + +Trước khi thảo luận về phong cách thiết kế, prompt engineering, chúng ta hãy giải quyết một việc quan trọng hơn: **Xác nhận rằng bạn thực sự có thể tạo ra một hình ảnh.** + +Các mô hình lớn hiện tại đã có khả năng tạo và chỉnh sửa hình ảnh, loại mô hình này thường được gọi là **mô hình tạo sinh.** + +Để đơn giản hóa quy trình nhất có thể, hướng dẫn này chọn một mô hình đã có khả năng tạo và chỉnh sửa hình ảnh ổn định làm ví dụ -- NanoBanana. Đây là mô hình tạo hình ảnh do Google phát triển, tên chính thức là **Gemini 3.1 Flash Image Preview**, hỗ trợ tạo hình ảnh trực tiếp qua ngôn ngữ tự nhiên, cũng hỗ trợ chỉnh sửa dựa trên hình ảnh có sẵn. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image1.png) + +Về mặt khả năng, nó không khác biệt bản chất so với các mô hình khác mà bạn có thể biết (như GPT-4o, Claude, Qwen, Midjourney, v.v.): **Nhập mô tả, mô hình chịu trách nhiệm tạo kết quả.** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image2.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image3.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image4.png) + +Bạn có thể hiểu nó như một "cây cọ vẽ". Trong chương này, chúng ta chỉ quan tâm một điều: +Chúng ta chỉ quan tâm một điều: **Cây cọ này có thể vẽ nét đầu tiên trong tay bạn hay không.** + +Trong thực tế sử dụng, NanoBanana có thể được sử dụng trực tiếp qua các nền tảng chính thức như **Google AI Studio**, hoặc tích hợp vào quy trình phát triển thông qua **API**. Hướng dẫn này sử dụng cách gọi API. Hiện tại đã ra mắt mô hình NanoBanana 2, bạn có thể sử dụng mô hình lớn mới nhất để thử nghiệm. + +### 1.2 Tạo hình ảnh cấp độ "Hello World" + +Trước khi bắt đầu, bạn chỉ cần hoàn thành ba bước sau: + +1. Tạo một thư mục mới trong Trae + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image5.png) + +2. Tạo một tệp Python mới + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image6.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image7.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image8.png) + +3. Dán toàn bộ mã dưới đây vào + +Trae sẽ tự động hoàn thành việc triển khai môi trường và cài đặt dependency cần thiết, không cần cấu hình thêm. + +Mã sẽ sử dụng API Key của NanoBanana. Ở đây không trình bày chi tiết quy trình đăng ký -- miễn là bạn có thể lấy và điền tham số tương ứng. **Giai đoạn này không cần hiểu từng dòng mã, miễn là nó chạy thành công.** + +```Python +# /// script +# dependencies = [ +# "gradio>=4.0.0", +# "pillow>=10.0.0", +# "requests>=2.31.0", +# ] +# /// + +import gradio as gr +import requests +import base64 +from PIL import Image +import io +import os +import time +import re +from typing import Optional, Dict, Any, List + +# Cấu hình API +NANOBANANA_API_URL: str = "YOUR API URL" +NANOBANANA_API_KEY: str = "YOUR API KEY" +OUTPUT_DIR: str = "outputs" + +# Đảm bảo thư mục đầu ra tồn tại +os.makedirs(OUTPUT_DIR, exist_ok=True) + +def image_to_base64_data_uri(image: Image.Image) -> str: + """ + Chuyển đổi hình ảnh PIL sang định dạng data URI tương thích với OpenAI API. + """ + buffer = io.BytesIO() + # Chuyển đổi thống nhất sang PNG để đảm bảo tương thích + image.save(buffer, format="PNG") + encoded = base64.b64encode(buffer.getvalue()).decode('utf-8') + return f"data:image/png;base64,{encoded}" + +def base64_to_image(base64_str: str) -> Optional[Image.Image]: + """ + Chuyển đổi chuỗi base64 thuần túy sang PIL Image. + """ + try: + image_bytes = base64.b64decode(base64_str) + return Image.open(io.BytesIO(image_bytes)) + except Exception as e: + print(f"Giải mã Base64 thất bại: {e}") + return None + +def extract_base64_from_response(content: Any) -> Optional[str]: + """ + Logic phân tích cốt lõi: Trích xuất dữ liệu Base64 hình ảnh từ content API trả về. + Tương thích với cả định dạng Markdown và định dạng danh sách có cấu trúc. + """ + if not content: + return None + + base64_data = None + + # 1. Thử trích xuất có cấu trúc (List) + if isinstance(content, list): + for part in reversed(content): + if isinstance(part, dict): + img_field = part.get("image_url") or part.get("image") or part.get("output_image") + if isinstance(img_field, dict): + url = img_field.get("url", "") + if url.startswith("data:image/") and "," in url: + return url.split(",", 1)[1].strip() + + text_parts = [ + str(p.get("text", "")) + for p in content + if isinstance(p, dict) and p.get("type") in ["text", "input_text"] + ] + content_str = "".join(text_parts) + else: + content_str = str(content) + + # 2. Thử trích xuất regex Markdown (String) + pattern = re.compile(r"!\[.*?\]\((data:image/[^;]+;base64,[^)]+)\)", re.IGNORECASE) + match = pattern.search(content_str) + + if match: + data_url = match.group(1) + if "," in data_url: + return data_url.split(",", 1)[1].strip() + + return None + +def synthesize(prompt: str, input_image: Optional[Image.Image]) -> Optional[Image.Image]: + """ + Gọi Nanobanana API để tạo hình ảnh. + """ + if not prompt or not prompt.strip(): + gr.Warning("Vui lòng nhập prompt") + return None + + print(f">>> Bắt đầu tác vụ: {prompt[:50]}...") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {NANOBANANA_API_KEY}" + } + + messages = [] + + if input_image is not None: + print(">>> Phát hiện hình ảnh đầu vào, sử dụng chế độ đa phương thức") + img_base64 = image_to_base64_data_uri(input_image) + messages.append({ + "role": "user", + "content": [ + {"type": "text", "text": prompt}, + {"type": "image_url", "image_url": {"url": img_base64}} + ] + }) + else: + messages.append({ + "role": "user", + "content": prompt + }) + + payload = { + "messages": messages, + "model": "gemini-2.5-flash-image", + "stream": False + } + + try: + response = requests.post(NANOBANANA_API_URL, headers=headers, json=payload, timeout=120) + + if response.status_code != 200: + error_msg = f"Yêu cầu API thất bại: {response.status_code} - {response.text}" + print(error_msg) + gr.Error(error_msg) + return None + + result = response.json() + print(f"Phản hồi API gốc (cắt bớt): {str(result)[:200]}...") + + content = None + if "choices" in result and len(result["choices"]) > 0: + content = result["choices"][0].get("message", {}).get("content") + + if not content: + gr.Warning("Không có trường content trong kết quả API trả về") + return None + + base64_str = extract_base64_from_response(content) + + if base64_str: + output_image = base64_to_image(base64_str) + if output_image: + return output_image + + text_content = str(content) if not isinstance(content, list) else " ".join([str(x) for x in content]) + gr.Info(f"Không tạo được hình ảnh, mô hình trả về văn bản: {text_content[:100]}...") + return None + + except requests.exceptions.Timeout: + gr.Error("Yêu cầu quá thời gian, vui lòng thử lại sau") + return None + except Exception as e: + import traceback + traceback.print_exc() + gr.Error(f"Lỗi không xác định: {str(e)}") + return None + +# Cấu hình giao diện Gradio +with gr.Blocks(title="Nanobanana Image Generator") as app: + gr.Markdown("# 🍌 Nanobanana Text/Image to Image") + gr.Markdown("Dựa trên mô hình Gemini-2.5-Flash-Image, hỗ trợ tạo ảnh từ văn bản và tạo ảnh từ ảnh.") + + with gr.Row(): + with gr.Column(): + prompt_input = gr.Textbox( + label="Prompt", + placeholder="Ví dụ: A cyberpunk cat holding a neon sign...", + lines=3 + ) + image_input = gr.Image( + label="Hình ảnh tham khảo (tùy chọn, dùng để tạo ảnh từ ảnh)", + type="pil", + height=300 + ) + submit_btn = gr.Button("Bắt đầu tạo", variant="primary") + + with gr.Column(): + image_output = gr.Image(label="Kết quả tạo", format="png") + + submit_btn.click( + fn=synthesize, + inputs=[prompt_input, image_input], + outputs=image_output + ) + +if __name__ == "__main__": + app.launch(share=True) +``` + +Khi Trae thông báo chạy thành công, nhấp vào liên kết cục bộ mà nó cung cấp (thường là http://127.0.0.1:7860). + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image9.png) + +Nếu mọi thứ bình thường, bạn sẽ thấy một giao diện vẽ AI đã có thể hoạt động. + +Giao diện này trông rất đơn giản, nhưng nó đã có hai khả năng cốt lõi trong công cụ vẽ cấp thương mại, đó là tạo ảnh từ văn bản và tạo ảnh từ ảnh. + +* **Bên trái:** **Vùng chỉ thị (Input Zone)** -- Bạn ra lệnh tại đây. +* **Prompt (ô nhập):** Nhập mô tả sáng tạo của bạn (khuyến nghị sử dụng tiếng Anh). +* **Input Image (ô tham khảo):** + * **Chế độ tạo ảnh từ văn bản:** Giữ **trống**. + * **Chế độ tạo ảnh từ ảnh:** Kéo hình ảnh cục bộ vào đây, AI sẽ sáng tạo dựa trên nó. +* **Nút Submit:** Nhấp để gửi chỉ thị, bắt đầu tạo. +* **Bên phải:** **Vùng hiển thị (Output Zone)** -- Nơi chứng kiến phép màu, kết quả tạo sẽ hiển thị tại đây. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image10.png) + +Bây giờ chúng ta có thể thử tạo hình ảnh đầu tiên của bạn! + +Prompt sử dụng trong ví dụ này như sau: + +> **A red apple** + +Đây là một ví dụ được đơn giản hóa có chủ ý, không chứa bất kỳ mô tả phong cách hay tham số nào. + +#### Quy trình thực tế + +Sau khi chạy mã, quy trình có thể tóm tắt thành ba bước: + +1. Gửi mô tả văn bản cho mô hình +2. Mô hình tạo hình ảnh tương ứng +3. Hình ảnh được lưu dưới dạng tệp cục bộ + +Vài giây sau, bạn sẽ thấy kết quả tạo tại máy cục bộ. Việc tạo hình ảnh bởi mô hình có tính ngẫu nhiên, nên cùng một prompt sẽ có kết quả tạo khác nhau, bạn có thể tạo nhiều lần và chọn hình ảnh ưng ý. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image11.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image12.png) + +Bạn cũng có thể làm phong phú prompt của mình, đưa thêm nhiều mô tả và giới hạn. Ví dụ với prompt sau, hình ảnh nhận được sẽ đặc biệt hơn. + +```Plain +"A hyper-realistic close-up of a fresh red apple with water droplets on its skin, sitting on a dark rustic wooden table. Cinematic dramatic lighting, rim light, shallow depth of field, bokeh background, 8k resolution, macro photography." +(Một quả táo đỏ tươi siêu chân thực có giọt nước trên vỏ, đặt trên bàn gỗ thô tối màu. Ánh sáng kịch tính điện ảnh, ánh sáng viền, độ sâu trường ảnh nông, nền mờ, độ phân giải 8k, nhiếp ảnh macro.) +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image13.png) + +Nhấp vào tải xuống hình ảnh trong vùng Output Image để lưu về máy. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image14.png) + +### 1.3 Các kịch bản tạo tài sản phổ biến của mô hình tạo ảnh + +Trong công việc thực tế, việc mô hình lớn tạo hình ảnh chủ yếu dùng để **sản xuất tài sản thiết kế hiệu quả**, chứ không phải tạo ra một tác phẩm nghệ thuật đơn lẻ. + +Khi bạn quan sát các case được thích nhiều trên các tài khoản marketing về thiết kế, bạn sẽ thấy sản phẩm của họ tập trung vào hai loại kịch bản: + +* **Tạo ảnh từ văn bản (từ 0 đến 1)** +* **Tạo ảnh từ ảnh tham khảo (từ 1 đến N)** + +#### 1. Tạo ảnh từ văn bản: Nhanh chóng có tài sản thiết kế + +Loại kịch bản này tập trung vào hiệu quả. Khi cần lấp khoảng trống trong thiết kế (như trạng thái trống, avatar, hình minh họa), AI về bản chất đóng vai trò là một **kho hình ảnh tạo tức thì**. + +1. ##### Tạo tài sản thiết kế UI + +* Xu hướng phổ biến: Icon 3D phong cách kính mờ, phong cách đất sét trên Dribbble +* Biểu hiện phổ biến: Chất liệu trong suốt, phát sáng ở viền, icon chức năng hoặc thời tiết với màu kẹo pastel + +**Prompt ví dụ:** + +> A set of 3D weather icons (sun, cloud, rain), glassmorphism style, frosted glass texture, soft pastel gradient colors, soft studio lighting, isometric view, transparent background, 4k. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image15.png) + +2. ##### Tạo Logo + +* Xu hướng phổ biến: Logo công nghệ cảm với đường nét tối giản, kết hợp hình học +* Biểu hiện phổ biến: Phối màu đen trắng, thiết kế không gian âm, nhận diện thương hiệu rõ ràng + +**Prompt ví dụ:** + +> Minimalist vector logo design for a tech brand "Coffee Code", combining a coffee cup with coding brackets < >, flat design, solid black lines, white background, Paul Rand style, svg. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image16.png) + +3. ##### Tạo hình ảnh người dùng cho trang web + +* Xu hướng phổ biến: Avatar 3D ảo phổ biến trên trang SaaS, để tránh bản quyền chân dung +* Biểu hiện phổ biến: Biểu cảm thân thiện, tỷ lệ hoạt hình, phong cách gần Pixar hoặc Memoji + +**Prompt ví dụ:** + +> Close-up portrait of a friendly young tech professional, smiling, Memoji 3D style, clay render, bright colors, soft lighting, solid plain background, Pixar character design. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image17.png) + +4. ##### Tạo hình ảnh minh họa bài viết + +* Xu hướng phổ biến: Minh họa phẳng trừu tượng phổ biến trên blog công ty công nghệ +* Biểu hiện phổ biến: Phối màu tím xanh, tỷ lệ nhân vật phóng đại, yếu tố UI trôi nổi + +**Prompt ví dụ:** + +> Editorial flat illustration representing remote work, a person sitting on a giant globe using a laptop, corporate memphis art style, vibrant colors (purple and teal), vector texture. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image18.png) + +#### 2. Tạo ảnh từ ảnh tham khảo: Giữ nhất quán thị giác + +Loại kịch bản này quan tâm nhiều hơn đến **khả năng mở rộng**. Khi bạn đã có một hình ảnh chính hài lòng và cần tạo một bộ tài sản cùng phong cách. + +5. ##### Bộ nút hoặc tài sản tương tác tương tự hình ảnh chính + +Trong phát triển game, nhất quán UI rất quan trọng. Giả sử bạn đã có nút **"PLAY"** của giao diện chính, nay cần mở rộng thành một bộ nút chức năng cùng phong cách (như tạm dừng, cài đặt, trang chủ). Chỉ dựa vào vẽ tay rất khó đảm bảo mỗi nút hoàn toàn nhất quán về độ bóng, phối cảnh và giá trị màu. + +**Quy trình thao tác cơ bản:** + +1. Lưu hình ảnh nút "PLAY" màu xanh đã có + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image19.png) + +2. Kéo nó vào vùng **Input Image** của giao diện, làm ảnh tham khảo mẫu +3. Giữ nguyên mô tả phong cách trong prompt, chỉ thay đổi nội dung chính thể + +Với quy trình này, miễn là thay mô tả chính thể, bạn có thể nhận được các nút chức năng khác nhau nhưng cùng phong cách. + +**Prompt ví dụ:** + +**Biến thể A: Nút tạm dừng (loại icon)** + +> A capsule-shaped game UI button with a white pause icon (two vertical bars) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image20.png) + +**Biến thể B: Nút cài đặt (icon phức tạp)** + +> A capsule-shaped game UI button with a white gear icon (settings symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image21.png) + +**Biến thể C: Nút chơi lại (thay đổi hình dạng)** + +Nếu cần thay đổi hình dáng nút, bạn có thể mô tả trực tiếp hình dạng trong prompt, mô hình sẽ cố gắng thay đổi cấu trúc trong khi giữ nguyên đặc trưng chất liệu. + +> A round game UI button with a white circular arrow icon (replay symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image22.png) + +Thông qua tập thao tác này, bạn không chỉ thay đổi chức năng và icon của nút, mà thậm chí thay đổi hình dáng nút, nhưng tất cả kết quả tạo vẫn giữ nhất quán cao về chất liệu, phối màu và ánh sáng. Đây chính là giá trị cốt lõi của mô hình lớn trong kịch bản nhân giống tài sản thiết kế. + +## Chương 2: Trợ lý tạo hình ảnh nghe lời hơn -- Ví dụ với Lovart + +Trong phần đầu, chúng ta đã gọi NanoBanana trực tiếp qua mã, trải nghiệm quy trình cơ bản "nhập là tạo". Cách này không có vấn đề khi nhu cầu đơn giản. Nhưng khi tác vụ tạo bắt đầu bao gồm nhiều ràng buộc hơn, ví dụ: + +* Cần nhiều hình ảnh cùng phong cách +* Cần điều chỉnh liên tục dựa trên kết quả có sẵn +* Cần thay đổi hướng tạo động theo đầu vào của người dùng + +Cách gọi đơn lẻ sẽ dần trở nên không đủ dùng. + +Lúc này, cần giới thiệu **AI Agent (trí năng thể)**. Phần này lấy **Lovart** làm ví dụ, cho thấy khi mô hình tạo hình ảnh có "lớp tư duy", toàn bộ quy trình làm việc sẽ thay đổi ra sao. Lưu ý! Đây không phải quảng cáo, chỉ là giúp mọi người nhanh chóng cảm nhận sự tiện lợi của AI Agent~ + +### 2.0 Giới thiệu Lovart: Đại lý thiết kế AI của bạn + +Lovart là một công cụ thiết kế dựa trên Agent Web. So với công cụ tạo ảnh thông thường, nó thêm một lớp "tư duy và lập kế hoạch" trước khi tạo. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image23.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image24.png) + +Sau khi vào Lovart, chủ yếu cần hiểu các điều khiển sau: + +#### Chọn mô hình + +Nhấp vào biểu tượng khối bên dưới ô nhập, có thể xem các mô hình tạo hiện có (như GPT Image, Flux, v.v.). + +Để nhất quán với ví dụ trước, phần này vẫn sử dụng NanoBanana làm mô hình tạo cơ sở. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image25.png) + +#### Chế độ tư duy + +Đây là công tắc cốt lõi của Lovart: + +* **Fast Mode**: Gần như API gốc, phản hồi nhanh, phù hợp tạo đơn lẻ, chỉ thị rõ ràng +* **Thinking Mode**: Chế độ Agent, AI sẽ phân tích nhu cầu trước, viết lại prompt, sau đó mới thực hiện tạo + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image26.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image27.png) + +#### Khả năng truy cập mạng + +Sau khi bật biểu tượng trái đất, Agent có thể tìm kiếm thông tin mạng (như xu hướng thiết kế, phong cách phối màu) trong quá trình tạo, làm đầu vào phụ trợ. + +### 2.1 Tại sao API gốc chưa đủ? + +Kể cả khi đã có thể tạo hình ảnh chất lượng tốt qua Python, API gốc vẫn có giới hạn trong tác vụ phức tạp. Nguyên nhân chính là: API gốc về bản chất là kiểu mệnh lệnh. Khi bạn yêu cầu nó tạo một đối tượng cụ thể, nó có thể thực hiện trực tiếp; nhưng khi đầu vào trở thành "lập kế hoạch một bộ tài sản game hoàn chỉnh", nó sẽ không chủ động phân tích mục tiêu thành nhiều bước thực hiện. + +Điểm khác biệt cốt lõi của Lovart nằm ở cơ chế Agent. Giữa đầu vào người dùng và mô hình tạo hình ảnh, nó thêm một lớp logic để hiểu và lập kế hoạch: nhận diện ý định người dùng trước, sau đó phân tích tác vụ, viết lại prompt, cuối cùng mới thực hiện tạo. + +### 2.2 Demo thực tế: 5 phút tạo bộ sticker IP + +Lấy ví dụ **"Tạo một bộ sticker IP vịt lập trình viên"**, xem Agent tham gia vào toàn bộ quy trình như thế nào. + +#### Giai đoạn 1: Lập kế hoạch (Khả năng tư duy của Agent) + +**Vấn đề của API gốc:** +Bạn cần tự suy nghĩ thiết kế nhân vật, trạng thái cảm xúc, và viết prompt riêng cho mỗi hình. + +**Cách làm của Lovart:** + +1. Bật chế độ Thinking Mode +2. Nhập một câu lệnh: + +> Thiết kế một bộ sticker IP vịt lập trình viên, phong cách phẳng, dễ thương + +AI sẽ không vẽ ngay mà tìm kiếm hình ảnh thiết kế vịt lập trình viên liên quan trên mạng. Xuất một kế hoạch đã phân tích, tự động tạo các cảnh Debug, Coffee Break, Panic, v.v., và tạo nhiều mô tả thị giác tương ứng. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image28.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image29.png) + +Trong bước này, AI chuyển từ "người thực thi" thành "người lập kế hoạch". Sau khi AI phân tích xong nhu cầu, bạn có thể xem nhiều hình ảnh vịt lập trình viên với phong cách và nội dung khác nhau trong vùng canvas của Lovart. Có thể bắt đầu chọn phong cách bạn thích. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image30.png) + +#### Giai đoạn 2: Nhất quán (Neo thị giác dựa trên tham chiếu) + +Hình ảnh trong Lovart không chỉ là kết quả, mà còn tham gia vào việc tạo tiếp theo. + +##### Tham chiếu hình ảnh hoàn chỉnh + +* Chọn một "vịt tiêu chuẩn" hài lòng nhất từ bản nháp, nhấp vào hình ảnh tương ứng trong vùng canvas +* Hình ảnh này sẽ tự động xuất hiện trong vùng hội thoại, làm Reference + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image31.png) + +* Nhập hành động mới (như vui vẻ) và tạo + +Kết quả tạo sẽ kế thừa phối màu, tỷ lệ và chi tiết của ảnh mẫu. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image32.png) + +##### Tham chiếu cục bộ / Kết hợp đa ảnh + +Ngoài việc dùng cả ảnh làm tham chiếu, Lovart còn hỗ trợ: + +* **Chỉ chọn vùng cục bộ của hình ảnh** (ví dụ chỉ tham chiếu mũ hoặc biểu cảm) + +Nhấp vào tab bên trái vùng canvas, chọn phím 「Mark」, đánh dấu vùng cục bộ trên hình ảnh mục tiêu, nội dung phần này sẽ tự động đồng bộ vào ô hội thoại. Ví dụ ở đây chúng ta có thể chọn thay đổi màu nền. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image33.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image34.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image35.png) + +Có thể thấy hình ảnh mới tạo chỉ thay đổi màu nền, điều này cũng nhất quán với yêu cầu chúng ta nhập. + +* **Trích dẫn tử phần tử từ nhiều hình ảnh khác nhau**, sau đó kết hợp tạo kết quả mới + +Ví dụ: bạn có thể giữ phần thân nhân vật từ ảnh A, đồng thời chỉ thay mũ thành phong cách từ ảnh B, Agent sẽ tự động tích hợp các ràng buộc thị giác này ở backend. + +Lấy vịt lập trình viên làm ví dụ, chúng ta có thể chọn giữ hình tượng vịt từ ảnh đầu tiên, và thay nó vào ảnh thứ hai làm phần tử chính thể. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image36.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image37.png) + +Hiệu quả cuối cùng cũng rất rõ rệt. Bạn cũng có thể thử các kết hợp khác! + +#### Giai đoạn 3: Triển khai (Gọi công cụ của Agent) + +Sau khi tạo xong, có thể trực tiếp thực hiện: phóng to, xóa nền, xóa bỏ, v.v. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image38.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image39.png) + +Đây không phải là bộ lọc đơn giản, mà là kết quả do Agent tự động điều phối các công cụ khác nhau. + +Sau khi xác định xong phong cách nền tảng, có thể rất nhanh chóng tạo một loạt hình ảnh sticker. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image40.png) + +Cuối cùng chúng ta nhận được là tài sản cấp sản xuất có thể giao ngay, chứ không chỉ là một hình ảnh trình diễn. + +### 2.3 Hướng dẫn sử dụng và tính phí + +Lovart áp dụng mô hình tính phí theo gói đăng ký, các gói khác nhau tương ứng với hạn mức sử dụng và quyền chức năng khác nhau, cụ thể dựa trên hiển thị trên trang chủ chính thức. + +Hướng dẫn này không giới thiệu hoặc so sánh bất kỳ gói nào; nếu có nhu cầu trong sử dụng thực tế, bạn có thể chọn nâng cấp trả phí theo tình hình cá nhân. +Hiện tại hỗ trợ thanh toán qua **Alipay** và các phương thức khác. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image41.png) + +#### Tóm tắt + +Lovart không phải thay thế mô hình cơ sở, mà thông qua cơ chế Agent, nâng cấp tạo hình ảnh từ "thực thi đơn lẻ" thành "quy trình làm việc liên tục". + +Khi tác vụ bắt đầu liên quan đến lập kế hoạch, nhất quán và giao hàng, ưu điểm của loại công cụ này sẽ trở nên rất rõ rệt. + +## Chương 3: Tự tay làm một trợ lý vẽ thông minh + +Ngoài việc sử dụng trực tiếp Lovart, chúng ta cũng có thể tự triển khai một trợ lý vẽ phiên bản đơn giản hóa. + +Chương này lấy "tự động tạo hình minh họa bài viết" làm ví dụ, từ vấn đề thực tế出发, từng bước xây dựng một Agent có khả năng tư duy. + +### 3.1 Nỗi đau: Tại sao gửi trực tiếp bài viết cho mô hình vẽ không hiệu quả? + +Gửi trực tiếp một bài viết dài cho NanoBanana và yêu cầu tạo hình minh họa thường khó nhận được kết quả lý tưởng. Nguyên nhân không phải mô hình "vẽ không tốt", mà là **nó không giỏi hiểu văn bản dài**. + +Mô hình tạo hình ảnh phù hợp hơn để xử lý mô tả thị giác ngắn gọn, rõ ràng, và khi đầu vào trở thành một bài viết có cấu trúc, trọng điểm và bối cảnh, mô hình không thể phân biệt nội dung nào mới thực sự cần thể hiện trong hình. Điều này thường dẫn đến kết quả tạo lệch chủ đề, hoặc chỉ nắm bắt được chi tiết rời rạc, thiếu khả năng khái quát tổng thể. + +Về bản chất, mô hình hình ảnh chỉ có khả năng "thực thi", nhưng thiếu quá trình phân tích và lựa chọn văn bản. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image42.png) + +### 3.2 Hướng giải quyết: Dùng Agent tách "hiểu" và "thực thi" + +Để giải quyết vấn đề này, điểm mấu chốt không phải prompt phức tạp hơn, mà là **suy nghĩ kỹ trước khi vẽ**. Do đó, chúng ta giới thiệu một "lớp tư duy" độc lập vào quy trình tạo, và dựa trên đó xây dựng một Agent đơn giản có thể sử dụng. + +Mục tiêu cốt lõi của Agent này chỉ có một: **Làm cho hình ảnh cuối cùng tạo ra, gần nhất với ý định biểu đạt thực sự của người dùng.** + +Toàn bộ quy trình có thể tóm tắt: **Đầu vào văn bản dài -> Mô hình ngôn ngữ hiểu và phán đoán -> Tạo prompt thị giác phù hợp -> Mô hình hình ảnh thực thi tạo -> Xuất hình ảnh** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image43.png) + +Vậy Agent chúng ta xây dựng làm thế nào để hiểu ý định người dùng? + +Ở đây chọn làm một "lớp tư duy" đơn giản hóa, chúng ta thiết lập ba loại ý định khác nhau: đầu vào vô nghĩa, tạo ảnh trực tiếp, văn bản dài cần hiểu. + +Trong Agent này, phân công vai trò của từng thành phần có thể tóm tắt thành bốn điểm: + +1. **Mô hình ngôn ngữ làm lõi ra quyết định** + Nó chịu trách nhiệm hiểu nội dung bài viết, phán đoán ý định đầu vào của người dùng, và phân phối tác vụ vào đường dẫn tạo phù hợp, quyết định "tiếp theo làm gì" và cách tạo prompt tạo ảnh. +2. **Mô hình hình ảnh làm người thực thi** + Mô hình hình ảnh không tham gia hiểu và phán đoán, chỉ nhận chỉ dẫn thị giác đã được sắp xếp, tập trung hoàn thành render hình ảnh. +3. **Người dùng làm người hướng dẫn có thể can thiệp** + Ngoài việc nhập văn bản trực tiếp, người dùng cũng có thể điều chỉnh prompt đã tạo trong quá trình, hoặc thêm ảnh tham khảo để hỗ trợ tạo, từ đó hướng dẫn và tinh chỉnh kết quả cuối cùng. +4. **Gradio và API backend làm lớp承载 tổng thể** + Chúng chịu trách nhiệm kết nối giao diện, gọi mô hình và hiển thị kết quả, đảm bảo toàn bộ Agent có thể vận hành ổn định dưới dạng một ứng dụng Web hoàn chỉnh. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image44.png) + +### 3.3 Chuẩn bị thực hành: Lấy API + +Có vẻ rất thú vị phải không! Để chạy thông quy trình trên, chúng ta chỉ cần chuẩn bị hai loại API. + +#### Tay: NanoBanana API (tạo hình ảnh) + +Sử dụng trực tiếp API Key và API URL đã cấu hình ở Chương 1, không cần thiết lập thêm. + +#### Não: SiliconFlow API (tư duy văn bản) + +Chúng ta cần một mô hình ngôn ngữ lớn để đảm nhận vai trò "lớp tư duy". Hướng dẫn này sử dụng dịch vụ mô hình do SiliconFlow cung cấp: [https://cloud.siliconflow.cn](https://cloud.siliconflow.cn/) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image45.png) + +SiliconFlow cung cấp giao diện tương thích với quy cách OpenAI API, có thể rất tiện lợi gọi trong dự án thông qua yêu cầu mạng tiêu chuẩn. Ở đây chúng ta chọn mô hình Qwen2.5-7B-Instruct miễn phí, nội dung cần gọi đã được viết trong Prompt dưới đây. Trước khi bắt đầu, bạn chỉ cần đăng ký tài khoản và tạo API Key trên trang chủ chính thức. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image46.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image47.png) + +Key này sẽ được sử dụng cho việc gọi mô hình tiếp theo. + +### 3.4 Xây dựng Agent: + +Thí nghiệm này chủ yếu sử dụng Trae để giúp chúng ta viết mã, hướng dẫn này chọn mô hình Gemini-3-Pro-Preview. Tổng thể tư duy là, sau khi tạo dự án mới, sao chép Prompt hoàn chỉnh dưới đây vào ô hội thoại và nhập, thay thế API KEY từng bước rồi chạy mã, hoàn thành kiểm tra. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image48.png) + +#### Giai đoạn 1: Khung cơ bản Gradio Blocks và bố cục giao diện + +Trong giai đoạn này, mục tiêu chính của chúng ta là xây dựng "ngoại hình" cho toàn bộ Agent, triển khai thiết kế trang frontend. Sao chép Prompt dưới đây vào ô hội thoại Trae để triển khai, bạn sẽ nhận được một URL cục bộ (thường là http://127.0.0.1:7860) để xem giao diện và kiểm tra hiệu quả. + +```Plain +Mục 1: Khung cơ bản Gradio Blocks và bố cục giao diện +1. Mục tiêu tác vụ +·Dựa trên bố cục Blocks của Gradio 4.0.0+, triển khai giao diện cơ bản của dự án "LLM+Nanobanana tạo ảnh từ văn bản", tuân thủ nghiêm ngặt bố cục chia trái phải cố định, khởi tạo tất cả thành phần UI và đặt trạng thái ban đầu đúng. + +2. Yêu cầu công nghệ +·Phải sử dụng chế độ Blocks của Gradio 4.0.0+ để phát triển, cấm sử dụng chế độ Interface; +·Dependency: gradio>=4.0.0, pillow>=10.0.0 (chỉ import, tạm thời không triển khai logic xử lý ảnh); +·Mã phải là tệp Python hoàn chỉnh có thể chạy, bao gồm tất cả câu lệnh import cần thiết. + +3. Quy tắc bố cục giao diện (ràng buộc cốt lõi) +·Bố cục tổng thể: +Tiêu đề trang: Công cụ tạo ảnh từ văn bản toàn quy trình do LLM điều khiển; +Chia trái phải cố định: Bên trái chiếm 60% chiều rộng, bên phải chiếm 40% chiều rộng, sử dụng gr.Row và gr.Column để kiểm soát tỷ lệ. +·Bên trái 60% (Vùng quy trình tạo prompt) danh sách thành phần: +input_text: gr.Textbox, label "Nhập văn bản (đoạn hướng dẫn / chỉ thị vẽ)", lines=6, placeholder "Vui lòng nhập văn bản hướng dẫn cần tạo hình minh họa hoặc chỉ thị vẽ trực tiếp..."; +identify_intent_btn: gr.Button, value="Nhận diện ý định", trạng thái ban đầu có thể nhấp; +intent_status: gr.Textbox, label "Loại ý định / Trạng thái xử lý", lines=2, interactive=False, giá trị ban đầu "Chưa nhận diện ý định"; +system_prompt: gr.Textbox, label "System Prompt (chỉ ý định tạo hình minh họa bài viết mới có thể chỉnh sửa)", lines=4, interactive=False, placeholder "Quy tắc ràng buộc để LLM tạo prompt..."; +confirm_prompt_btn: gr.Button, value="Xác nhận tạo prompt tạo ảnh", interactive=False (vô hiệu hóa ban đầu để tránh nhầm); +generation_prompt: gr.Textbox, label="Prompt tạo ảnh (có thể chỉnh sửa)", lines=3, interactive=True, giá trị ban đầu rỗng, placeholder "Prompt tiếng Anh tạo ảnh sẽ hiển thị tại đây, hỗ trợ sửa thủ công...". +·Bên phải 40% (Vùng chức năng tạo ảnh Nanobanana) danh sách thành phần: +ref_image: gr.Image, label "Ảnh tham khảo (tùy chọn, tạo ảnh từ ảnh)", type=filepath, height=300, cho phép tải lên; +generate_btn: gr.Button, value="Tạo hình ảnh", interactive=False (vô hiệu hóa ban đầu, không có prompt không thể nhấp); +result_image: gr.Image, label "Kết quả tạo", type=pil, height=300, ban đầu rỗng, interactive=False. + +4. Yêu cầu logic tương tác +·Trạng thái interactive ban đầu của tất cả thành phần tuân thủ nghiêm ngặt cấu hình trên, cập nhật động qua hàm sau; +·Trạng thái vô hiệu hóa nút cần trực quan (làm mờ), tránh người dùng nhầm. + +5. Yêu cầu đầu ra +·Tạo mã Python hoàn chỉnh, chỉ triển khai bố cục giao diện và khởi tạo thành phần, không chứa bất kỳ logic nghiệp vụ nào; +·Comment mã rõ ràng, tên thành phần nhất quán với phiên bản thực tế (input_text/identify_intent_btn, v.v.); +·Mã có thể chạy trực tiếp, cấu trúc giao diện hoàn toàn nhất quán với mô tả. +``` + +Sau khi mở http://127.0.0.1:7860 trong trình duyệt, bạn có thể thấy Trae đã tạo trang web theo yêu cầu của chúng ta, cơ bản phù hợp yêu cầu, có thể tiếp tục bước tạo tiếp theo. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image49.png) + +#### Giai đoạn 2: Module nhận diện ý định LLM (Siliconflow API) + +Khi sử dụng VLM để vẽ trong cuộc sống hàng ngày, có thể có ba loại đầu vào phổ biến sau: + +1. Nội dung vô nghĩa, như "xin chào", "hôm nay bạn ăn chưa", không thể vẽ hình tương ứng. +2. Bài viết/văn bản dài, nhiều chữ, khoảng 200 chữ một bài có cấu trúc, cần hiểu cấu trúc và nội dung bài viết trước, sau đó mới xem xét tạo hình ảnh có thể tóm tắt hoàn chỉnh đoạn văn này. +3. Chỉ thị vẽ trực tiếp, như "giúp tôi vẽ một con chó đang tắm", yêu cầu đã trình bày rất cụ thể, có thể tạo hình ảnh trực tiếp. + +Giống như trước, sao chép Prompt dưới đây vào ô hội thoại Trae để triển khai, và bổ sung API lấy ở bước trước. + +```Plain +Mục 2: Module nhận diện ý định LLM (Siliconflow API) +1. Mục tiêu tác vụ +Trên cơ sở giao diện Gradio đã triển khai, thêm logic nhấp cho nút "Nhận diện ý định", gọi Siliconflow API hoàn thành nhận diện ý định, và liên kết trạng thái thành phần. + +2. Yêu cầu công nghệ +Dựa trên Blocks Gradio 4.0.0+; +Dependency: requests>=2.31.0, openai; +Xuất tệp Python hoàn chỉnh có thể chạy, bao gồm giao diện Mục 1 + logic module này. + +3. Quy tắc nghiệp vụ cốt lõi (tuyệt đối không được sai lệch) +·Quy tắc phân loại ý định (chỉ 3 loại, trả về nghiêm ngặt số + mô tả) +1 = Nội dung vô nghĩa: Chỉ nói chuyện phiếm, chào hỏi, hội thoại không liên quan, không có nhu cầu vẽ hoặc tạo hình minh họa (như "xin chào" "hôm nay ăn chưa"); +2 = Nhu cầu tạo hình minh họa bài viết/văn bản dài: Người dùng nhập một bài viết hoàn chỉnh, hướng dẫn, đoạn văn, văn bản mô tả, nội dung thiên về tường thuật/mô tả/giảng giải, ẩn chứa ý định cần tạo hình minh họa cho nội dung này, không cần người dùng nói rõ "tạo hình minh họa cho đoạn văn này"; +3 = Chỉ thị vẽ trực tiếp: Người dùng nhập lệnh vẽ ngắn gọn, rõ ràng, không có bối cảnh văn bản dài, yêu cầu trực tiếp vẽ một nội dung nào đó (như "vẽ một con mèo phong cách Apple"). +·Ràng buộc gọi LLM (tích hợp mẫu phiên bản thực tế) +Địa chỉ giao diện: https://api.siliconflow.cn/v1/chat/completions; +Mô hình: Qwen/Qwen2.5-7B-Instruct; +temperature=0.1; + +4. Quy tắc liên kết thành phần +·Kết quả là 1: intent_status hiển thị "1 = Nội dung vô nghĩa: Không có nhu cầu vẽ", system_prompt giữ vô hiệu, confirm_prompt_btn vô hiệu; +·Kết quả là 2: intent_status hiển thị "2 = Nhu cầu tạo hình minh họa bài viết/văn bản dài: Tạo hình minh họa cho nội dung đầu vào", bật system_prompt và điền quy tắc mặc định, kích hoạt confirm_prompt_btn; +·Kết quả là 3: intent_status hiển thị "3 = Chỉ thị vẽ trực tiếp: Tạo hình ảnh theo chỉ thị", system_prompt vô hiệu và điền quy tắc mặc định, kích hoạt confirm_prompt_btn. + +5. Xử lý ngoại lệ +Lỗi API, lỗi phân tích đều đưa ra prompt thân thiện, không sập, thành phần trở về trạng thái ban đầu. + +6. Yêu cầu đầu ra +Tạo mã hoàn chỉnh có thể chạy, thay LLM_API_KEY là có thể sử dụng, logic rõ ràng comment đầy đủ, mẫu nhận diện ý định sử dụng nghiêm ngặt phiên bản thực tế. +``` + +Làm mới trang http://127.0.0.1:7860 trước đó, bắt đầu kiểm tra xem có thể nhận diện đúng ba trường hợp hay không. + +1. Nội dung vô nghĩa, có thể thử nhập "xin chào", "cảm ơn", phát hiện có thể nhận diện bình thường. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image50.png) + +2. Bài viết/văn bản dài, ở đây chúng ta dùng một đoạn văn bản do Doubao tạo mô tả trí tuệ nhân tạo. Bạn cũng có thể thử sử dụng đoạn luận văn của mình để kiểm tra. + +```Plain +Trí tuệ nhân tạo đang định hình lại hệ sinh thái giáo dục với độ sâu và breadth chưa từng có... +``` + +Cũng kiểm tra thành công~ + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image51.png) + +3. Chỉ thị vẽ trực tiếp, ở đây nhập "tôi muốn vẽ một con mèo", cũng nhận diện chính xác. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image52.png) + +Đến đây chúng ta đã hoàn thành thuận lợi giai đoạn thứ hai -- nhận diện ý định. + +#### Giai đoạn 3: Module tạo prompt tạo ảnh (Gọi LLM lần hai) + +Sau khi nhận diện ý định, đối với bài viết hoặc văn bản dài, còn một bước rất quan trọng là tạo prompt vẽ, đây chính là trọng điểm của Agent này. + +```SQL +Mục 3: Module tạo prompt tạo ảnh (Gọi LLM lần hai) +1. Mục tiêu tác vụ +Trên cơ sở nhận diện ý định, triển khai logic nút "Xác nhận tạo prompt tạo ảnh", gọi LLM tối ưu hóa văn bản thành prompt thị giác tiếng Anh phù hợp để vẽ, điền vào ô chỉnh sửa và liên kết nút "Tạo hình ảnh". + +2. Yêu cầu công nghệ +Giống Mục 2, xuất mã hoàn chỉnh = Mục 1 + Mục 2 + module này; +Sử dụng chung LLM_BASE_URL, LLM_API_KEY, LLM_MODEL đã định nghĩa ở Mục 2, không thêm key mới. + +3. Quy tắc nghiệp vụ cốt lõi +·Quy tắc đầu vào tạo prompt (phải tuân thủ nghiêm ngặt) +Tạo prompt tạo ảnh không còn là nối chuỗi đơn giản, mà là xây dựng danh sách tin nhắn Chat tiêu chuẩn. +·Ràng buộc gọi LLM +Sử dụng chung bộ LLM_BASE_URL, LLM_API_KEY, LLM_MODEL với Mục 2; +temperature=0.7; +max_tokens=200; +Sử dụng nghiêm ngặt cấu trúc danh sách tin nhắn Chat tiêu chuẩn, cấm nối chuỗi. +·Ràng buộc bắt buộc đầu ra prompt +Tiếng Anh thuần, không có tiếng Trung; +Phải bao gồm Apple Design Philosophy/Apple style + 1024x1024; +Độ dài 50-200 ký tự, kiểm tra trong mã; +Không có giải thích thêm, tiền tố hoặc lời thừa, chỉ trả về prompt. + +4. Quy tắc liên kết thành phần +Tạo thành công: Điền prompt vào ô generation_prompt, kích hoạt generate_btn, intent_status thêm "Tạo prompt thành công, có thể sửa rồi tạo hình ảnh"; +Tạo thất bại: Prompt lý do cụ thể, generate_btn giữ vô hiệu, ô generation_prompt rỗng; +Người dùng sửa/xóa ô generation_prompt: +Xóa tự động vô hiệu generate_btn; +Không rỗng thì giữ generate_btn kích hoạt. + +5. Xử lý ngoại lệ +Gọi API thất bại: Prompt thân thiện, không sập; +Kiểm tra prompt thất bại: Nêu rõ lý do, cho thử lại; +Phân tích phản hồi thất bại: Prompt "Không thể phân tích kết quả LLM trả về, vui lòng thử lại". + +6. Yêu cầu đầu ra +Mã hoàn chỉnh có thể chạy, thay LLM_API_KEY là có thể sử dụng; +Cấu trúc mã rõ ràng, comment đầy đủ, giao diện đẹp简洁; +Triển khai nghiêm ngặt cấu trúc danh sách tin nhắn Chat tiêu chuẩn, tham số và logic mẫu nhất quán; +Bao gồm logic kiểm tra độ dài, nội dung prompt, prompt lỗi thân thiện. +``` + +Cũng sao chép văn bản của giai đoạn thứ hai để kiểm tra. + +Đáng chú ý, System Prompt tạo prompt tạo ảnh mà chúng ta đặt trước ở đây là: + +> Bạn hiện là trợ giúp tạo prompt vẽ NanoBanana. +> Cần xử lý dựa trên nội dung của tôi, hình ảnh này có tác dụng giải thích đoạn này đang nói gì, và để mọi người biết cấu trúc bối cảnh của đoạn này nói chung là có ý nghĩa gì. +> Có thể có phần giải thích tương tự PPT (như: góc trên bên trái thể hiện quan điểm cốt lõi, góc dưới bên phải thể hiện dữ liệu). +> Yêu cầu phong cách thiết kế: Tối giản, tư duy thiết kế Apple (Apple Design Philosophy). +> Ràng buộc: Vui lòng trả về trực tiếp prompt tiếng Anh có thể sử dụng cho NanoBanana, không trả về bất kỳ giải thích, tiền tố hoặc lời thừa nào. + +Nếu bạn muốn đổi mẫu mặc định khác, có thể sửa trong prompt trước đó, hoặc trực tiếp sửa qua hội thoại trong Trae. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image53.png) + +Ngoài việc sửa mã cơ sở, chúng ta cũng có thể chỉnh sửa nhanh trên trang web. Ví dụ, tôi thêm một câu ở đây, "thêm câu Pic Prompt ở phía trước", có thể thấy prompt mới tạo cũng bao gồm ở phía trước~ Thiết kế này là để dễ dàng sửa System Prompt tạo prompt, giúp chúng ta nhanh chóng chuyển đổi phong cách. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image54.png) + +#### Giai đoạn 4: Module tạo ảnh từ văn bản/tạo ảnh từ ảnh Nanobanana + +Cuối cùng đã đến bước cuối cùng, không kết nối mô hình tạo ảnh thì không phải Agent hoàn chỉnh! + +```Bash +Mục 4: Module tạo ảnh từ văn bản/tạo ảnh từ ảnh Nanobanana (phiên bản cuối) +1. Mục tiêu tác vụ +Triển khai logic nút "Tạo hình ảnh", gọi API Nanobanana thực tế, hỗ trợ tạo ảnh từ văn bản/tạo ảnh từ ảnh, phân tích Base64 và hiển thị hình ảnh. + +2. Yêu cầu công nghệ +Dựa trên Blocks Gradio 4.0.0+; +Dependency: requests, pillow, base64, io, re; +Mã hoàn chỉnh = Mục 1+2+3 + module này. + +3. Cấu hình API cốt lõi +Cấu hình mã cố định: +NANOBANANA_API_URL = "https://api.zyai.online/v1/chat/completions" +NANOBANANA_MODEL = "gemini-2.5-flash-image" +NANOBANANA_API_KEY = "" # Người dùng tự thay + +4. Yêu cầu tiền xử lý hình ảnh (phải triển khai) +Triển khai hàm image_to_base64_data_uri (ref_image_path), logic cốt lõi: +Chuyển hình ảnh PIL sang định dạng PNG; +Tự động thu nhỏ về độ phân giải 1024x1024; +Kênh trong suốt chuyển sang nền trắng; +Mã hóa Base64, trả về định dạng: data:image/png;base64,... + +5. Quy tắc xây yêu cầu (theo logic phân nhánh phiên bản thực tế) +·Hàm cốt lõi +Triển khai hàm generate_image (prompt, ref_image_path): +Tham số: prompt (nội dung ô generation_prompt), ref_image_path (đường dẫn tệp tải lên ref_image); +Trả về: PIL Image (hiển thị vào result_image) hoặc prompt lỗi. +·Nhánh logic 1: Tạo ảnh từ văn bản thuần (ref_image_path rỗng) +messages = [{"role": "user", "content": prompt}] +·Nhánh logic 2: Tạo ảnh từ ảnh (ref_image_path có giá trị) +Gọi hàm tiền xử lý hình ảnh trước, sau đó xây messages với image_url. + +6. Yêu cầu phân tích phản hồi (phải tương thích hai định dạng) +Trích xuất Base64 hình ảnh từ choices[0].message.content, hỗ trợ: +Trường image_url trả về JSON có cấu trúc; +Định dạng Markdown; +Trích xuất thống nhất mã hóa Base64, giải mã sau chuyển đổi thành PIL Image trả về. + +7. Liên kết thành phần và xử lý ngoại lệ +Tạo thành công: Hiển thị PIL Image vào result_image, intent_status prompt "Tạo hình ảnh thành công"; +Tạo/phân tích/tải lên thất bại: Hiển thị prompt văn bản rõ ràng trong intent_status, không sập. + +8. Yêu cầu đầu ra +Mã hoàn chỉnh có thể chạy, thay LLM_API_KEY và NANOBANANA_API_KEY là có thể chạy trực tiếp, toàn bộ quy trình sử dụng được, logic phân nhánh khớp nghiêm ngặt phiên bản thực tế. +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image55.png) + +Thật thú vị! Chúng ta đã tạo thành công hình ảnh đầu tiên của Agent này, nhìn kỹ hình ảnh tạo ra, nó khớp với văn bản và prompt của chúng ta. Đến đây bạn đã cơ bản triển khai xong Agent của riêng mình! + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image56.png) + +Chúng ta còn thêm chức năng tạo ảnh từ ảnh, tải lên hình ảnh bạn thích, AI sẽ tự động tham khảo phong cách. + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image57.png) + +Đáng nhắc là, prompt tạo ở bước trước cũng có thể chỉnh sửa trên trang web, và chúng ta lấy prompt khi nhấp nút cuối cùng làm chuẩn~ Ngay cả khi tôi đổi thành "a cute cat" ở đây, hình ảnh cuối cùng tạo ra cũng chỉ là chú mèo dễ thương. + +## Chương 4: Tổng kết + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image58.png) + +**Tuyệt vời! Cuối cùng cũng viết xong.** + +Thành thật mà nói, ngay cả bản thân tôi khi viết xong dòng cuối cùng cũng không khỏi thở phào nhẹ nhõm, chưa nói đến bạn đã theo dõi đến đây. Có thể chạy hoàn chỉnh toàn bộ quy trình này đã rất giỏi rồi, điều này chứng tỏ bạn thực sự đã đặt tay lên bàn phím, hoàn thành từng bước. Tuyệt vời! + +Trong quá trình viết nội dung này, tôi luôn suy nghĩ, chúng ta thực sự muốn để lại điều gì? Câu trả lời thực chất không phải tên mô hình, tham số hoặc một phương pháp cố định nào, mà là giúp bạn dần dần xây dựng một cảm giác: những việc nào có thể yên tâm giao cho AI để hiểu và lập kế hoạch, những chỗ nào chỉ cần bạn quyết định hướng. Một khi sự phân công này được thiết lập, nhiều quy trình tạo ban đầu trông phức tạp sẽ bắt đầu trôi chảy hơn. + +Nhìn lại, con đường này thực chất không phức tạp. Suy nghĩ kỹ vấn đề bạn muốn giải quyết, giao văn bản dài cho mô hình ngôn ngữ để phân tích, sau đó giao ý định thị giác đã sắp xếp cho mô hình vẽ để trình bày, cuối cùng đóng gói toàn bộ quy trình này thành một trợ lý nhỏ của riêng bạn. Đến đây, bạn không chỉ "đang dùng mô hình", mà đang xây dựng một hệ thống có thể đồng hành cùng bạn làm việc lâu dài, và đây mới là điều mà bộ hướng dẫn này muốn mang đến cho bạn. + +Bạn đã làm rất tốt rồi! Tin rằng học đến đây bạn đã nắm bắt cơ bản Vibe Coding, hãy cho mình một kỳ nghỉ nhỏ nghỉ ngơi nhé! + + diff --git a/docs/vi-vn/stage-2/frontend/modern-component-library/index.md b/docs/vi-vn/stage-2/frontend/modern-component-library/index.md new file mode 100644 index 0000000..790e672 --- /dev/null +++ b/docs/vi-vn/stage-2/frontend/modern-component-library/index.md @@ -0,0 +1,424 @@ +# Sử dụng thư viện component hiện đại để cập nhật giao diện + +Trong các bài học trước, bạn đã học cách sử dụng công cụ thiết kế để vẽ giao diện, dùng AI IDE để chuyển bản thiết kế thành code, thậm chí hoàn thành một dự án frontend hoàn chỉnh. Nhưng bạn cũng có thể phát hiện ra một vấn đề: các nút bấm, biểu mẫu, hộp thoại tự viết từ đầu tuy dùng được nhưng总觉得 thiếu chút gì so với "sản phẩm chuyên nghiệp" — phong cách không đủ thống nhất, chi tiết tương tác không đủ mượt mà, thích ứng với các màn hình khác nhau cũng rất đau đầu. + +Đó chính là vấn đề mà **thư viện component** giải quyết. + +Thư viện component là một tập hợp các linh kiện UI đã được thiết kế và phát triển sẵn. Nút bấm, ô nhập liệu, menu thả xuống, hộp thoại, bảng dữ liệu... các phần tử giao diện mà bạn sẽ sử dụng lặp đi lặp lại trong bất kỳ sản phẩm nào, thư viện component đã làm sẵn cho bạn, và đã được kiểm chứng và tinh chỉnh bởi nhiều người dùng. Bạn chỉ cần lắp ghép chúng lại như chơi xếp hình là có thể nhanh chóng xây dựng giao diện cấp chuyên nghiệp. + +## Bạn sẽ học được + +1. Hiểu thư viện component frontend là gì, và tại sao phát triển hiện đại gần như đều sử dụng nó +2. Làm quen với bốn thư viện component tiêu biểu nhất, hiểu các kịch bản mà mỗi thư viện擅长 +3. Thông qua ba kịch bản thực chiến (landing page, trang sản phẩm, quản lý back-office), học cách sử dụng AI IDE + thư viện component để Vibe Coding +4. Học cách đọc tài liệu thư viện component, tìm và sử dụng component phù hợp theo nhu cầu + +## 1. Tại sao cần thư viện component? + +Hãy tưởng tượng bạn đang trang trí nhà. Bạn có thể tự làm một chiếc ghế từ gỗ, nhưng cách phổ biến hơn là đến IKEA mua một chiếc — thiết kế đẹp, chất lượng ổn định, hướng dẫn sử dụng rõ ràng, mang về lắp ráp là xong. + +Thư viện component chính là "IKEA" trong phát triển frontend. Nó cung cấp không phải đồ nội thất, mà là linh kiện giao diện: + +| Tự viết tay | Sử dụng thư viện component | +| :--- | :--- | +| Cần tự xử lý phong cách, tương tác, animation | Sử dụng ngay, phong cách và tương tác đã được tinh chỉnh | +| Nút bấm trên các trang khác nhau có thể trông khác nhau | Phong cách toàn cục thống nhất, tự động duy trì tính nhất quán | +| Thích ứng điện thoại, máy tính bảng cần thêm việc | Hầu hết thư viện component đã tích hợp hỗ trợ responsive | +| Truy cập vô障碍 dễ bị sót | Thư viện component chuyên nghiệp đã xử lý điều hướng bàn phím, trình đọc màn hình, v.v. | +| Tốc độ phát triển chậm | Tốc độ phát triển nhanh, tập trung vào logic nghiệp vụ | + +Nói đơn giản: **Thư viện component giúp bạn dành thời gian cho "làm gì", chứ không phải "vẽ thế nào".** + +### Trăm nghe không bằng một thấy: cùng một yêu cầu, khoảng cách giữa có và không có thư viện component + +Nói suông không có tính thuyết phục. Chúng ta sử dụng yêu cầu gần như giống nhau trong Trae, lần lượt không chỉ định và chỉ định thư viện component, xem khoảng cách kết quả tạo ra. + +**Prompt 1: Không sử dụng thư viện component** + +```text +Vui lòng giúp tôi tạo một trang bảng điều khiển dữ liệu trợ lý viết AI, bao gồm: +- Thanh tiêu đề trên cùng và nút xuất +- Bốn thẻ thống kê hiển thị số người dùng, người dùng hoạt động, số tài liệu, doanh thu, còn phải hiển thị xu hướng tăng/giảm +- Một biểu đồ đường và một biểu đồ tròn +- Bảng danh sách người dùng, có chức năng phân trang +- Thanh điều hướng侧边栏 bên trái +``` + +**Prompt 2: Sử dụng thư viện component shadcn/ui** + +```text +Vui lòng giúp tôi tạo một trang bảng điều khiển dữ liệu trợ lý viết AI, sử dụng thư viện component shadcn/ui, bao gồm: +- Thanh tiêu đề trên cùng và nút xuất +- Bốn thẻ thống kê hiển thị số người dùng, người dùng hoạt động, số tài liệu, doanh thu, còn phải hiển thị xu hướng tăng/giảm +- Một biểu đồ đường và một biểu đồ tròn +- Bảng danh sách người dùng, có chức năng phân trang +- Thanh điều hướng侧边栏 bên trái +``` + +Cùng một yêu cầu, điểm khác biệt duy nhất là thêm `shadcn/ui + Tailwind CSS` ở đầu prompt, kết quả Trae tạo ra về tính nhất quán thị giác, chi tiết tương tác, mức độ hoàn thiện tổng thể hoàn toàn không ở cùng một cấp độ. Đây chính là "nâng cấp miễn phí" mà thư viện component mang lại — bạn chỉ cần thêm tên thư viện component vào prompt. + +## 2. Làm quen với bốn thư viện component cốt lõi + +Số lượng thư viện component rất nhiều (xem danh sách đầy đủ tại [Phụ lục](#phụ-lục-thêm-thư-viện-component)), nhưng bạn chỉ cần làm quen với bốn thư viện tiêu biểu nhất: + +| Thư viện component | Framework | Định vị một câu | Trang chủ | +| :--- | :--- | :--- | :--- | +| [Ant Design](https://ant.design) | React | Sản phẩm bởi Ant Group, tiêu chuẩn thực tế cho back-office doanh nghiệp cấp trung, độ bao phủ component cực kỳ rộng | ant.design | +| [shadcn/ui](https://ui.shadcn.com) | React | Không cài npm package, sao chép code trực tiếp vào dự án của bạn, dựa trên Tailwind CSS, mức độ tùy chỉnh tự do cao nhất | ui.shadcn.com | +| [HeroUI](https://heroui.com) (trước đây là NextUI) | React | Phong cách mặc định tinh xảo, animation mượt mà, phù hợp landing page và showcase sản phẩm có yêu cầu cao về chất lượng thị giác | heroui.com | +| [Material UI](https://mui.com) | React | Thư viện component React lâu đời nhất, triển khai quy phạm Google Material Design, hệ sinh thái trưởng thành nhất | mui.com | + +> Người dùng Vue cũng có nhiều lựa chọn phong phú: [Element Plus](https://element-plus.org) (phổ biến nhất tại Trung Quốc), [Ant Design Vue](https://antdv.com), [Naive UI](https://www.naiveui.com), v.v., xem chi tiết tại [Phụ lục](#phụ-lục-thêm-thư-viện-component). + +Các thư viện component khác nhau擅长 các kịch bản khác nhau. Tiếp theo chúng ta sẽ thông qua ba kịch bản phát triển thực tế, dẫn dắt bạn trải nghiệm cách sử dụng AI IDE + thư viện component để Vibe Coding. + +Để thể hiện phong cách và đặc điểm của các thư viện component khác nhau, chúng ta cố tình chọn thư viện khác nhau trong mỗi kịch bản. Nhưng xin lưu ý: **Điều này chỉ là để bạn làm quen với nhiều phương án hơn**, trong phát triển thực tế bạn hoàn toàn có thể chỉ sử dụng thư viện bạn quen tay nhất. Ví dụ bạn thích phong cách shadcn/ui, dùng nó làm landing page, trang sản phẩm, quản lý back-office đều không vấn đề. Chọn một thư viện bạn thấy đẹp và dùng thoải mái là quan trọng nhất. + +## 3. Thực chiến 1: Xây dựng landing page sản phẩm bằng HeroUI + +**Kịch bản**: Bạn đã làm một sản phẩm trợ lý viết AI, cần một landing page đẹp để thể hiện tính năng sản phẩm, thu hút người dùng đăng ký. Landing page cần sức mạnh thị giác cao, animation mượt mà, trên điện thoại cũng phải đẹp. + +**Tại sao chọn HeroUI**: Phong cách mặc định của HeroUI đã rất tinh xảo, tự kèm animation chuyển tiếp mượt mà, rất phù hợp các trang showcase hướng đến người dùng. + +### 3.1 Tạo dự án + +```bash +# Sử dụng CLI chính thức của HeroUI để tạo dự án +npx create-heroui-app@latest ai-writer-landing +cd ai-writer-landing +npm install +``` + +### 3.2 Sử dụng AI IDE để tạo landing page + +Mở AI IDE (Cursor, Trae, v.v.), nhập vào hộp thoại: + +```text +Vui lòng giúp tôi tạo một landing page trợ lý viết AI, sử dụng thư viện component HeroUI: + +**Cấu trúc trang:** +1. Thanh điều hướng trên cùng: bên trái đặt Logo và tên sản phẩm, bên phải đặt ba liên kết "Tính năng", "Bảng giá", "Về chúng tôi", thêm nút "Bắt đầu sử dụng" +2. Khu vực首屏: tiêu đề lớn viết "Để AI trở thành đối tác viết của bạn", phụ đề giới thiệu giá trị sản phẩm, hai nút "Dùng thử miễn phí" và "Xem demo", bên dưới đặt ảnh chụp màn hình sản phẩm +3. Triển khai tính năng: ba cột thẻ, lần lượt giới thiệu ba tính năng "Tiếp tục viết thông minh", "Điều chỉnh phong cách", "Dịch đa ngôn ngữ", mỗi thẻ phải có icon, tiêu đề, mô tả +4. Khu vực bảng giá: ba thẻ bảng giá (bản miễn phí, bản chuyên nghiệp, bản nhóm), bản chuyên nghiệp cần hiển thị nổi bật khuyến nghị +5. Khu vực kêu gọi hành động dưới cùng: một câu văn bản hấp dẫn, thêm nút đăng ký +6. Chân trang: thông tin bản quyền và liên kết mạng xã hội + +**Yêu cầu thiết kế:** +- Nhìn phải hiện đại, chuyên nghiệp +- Hỗ trợ chế độ tối +- Trên điện thoại cũng phải đẹp +``` + +### 3.3 Các component cốt lõi mà AI sẽ sử dụng + +```jsx +import { + Navbar, NavbarBrand, NavbarContent, NavbarItem, + Button, + Card, CardHeader, CardBody, CardFooter, + Divider, + Link, + Chip +} from '@heroui/react' +``` + +| Component | Mục đích | Vị trí trong landing page | +| :--- | :--- | :--- | +| `Navbar` | Thanh điều hướng trên cùng | Phía trên cùng trang, cố định không di chuyển | +| `Button` | Nút bấm, hỗ trợ nhiều biến thể và màu sắc | Nút CTA, nút điều hướng | +| `Card` | Container thẻ | Triển khai tính năng, thẻ bảng giá | +| `Chip` | Nhãn nhỏ | Đánh dấu "Khuyến nghị", "Phổ biến nhất" | +| `Divider` | Đường phân cách | Phân cách thị giác giữa các khu vực | + +### 3.4 Lặp và tối ưu + +Code phiên bản đầu tạo ra có thể không hoàn toàn hài lòng, tiếp tục đối thoại với AI để điều chỉnh: + +```text +Vui lòng giúp tôi tối ưu landing page: + +1. Tiêu đề lớn thêm gradient màu, từ xanh chuyển sang tím +2. Thẻ tính năng khi di chuột vào có animation nổi lên +3. Thẻ bảng giá bản chuyên nghiệp cần hiển thị nổi bật, thêm viền và nhãn "Phổ biến nhất" +4. Điều hướng trên điện thoại改成 menu hamburger (kiểu ba dấu gạch ngang) +``` + +> **Cốt lõi của Vibe Coding**: Bạn không cần nhớ API của mỗi component, chỉ cần mô tả hiệu quả bạn muốn bằng ngôn ngữ tự nhiên, AI sẽ giúp bạn tìm component và cách viết phù hợp. Khi gặp chỗ không hài lòng, tiếp tục đối thoại lặp là được. + +## 4. Thực chiến 2: Xây dựng trang sản phẩm bằng shadcn/ui + +**Kịch bản**: Trợ lý viết AI của bạn cần một giao diện chính sau khi người dùng đăng nhập — bên trái là danh sách tài liệu, bên phải là trình soạn thảo, trên cùng có thanh công cụ. Đây là một trang sản phẩm kiểu chức năng, cần UI có thể tùy chỉnh cao. + +**Tại sao chọn shadcn/ui**: shadcn/ui đặt code component trực tiếp vào dự án của bạn, bạn có thể tự do chỉnh sửa bất kỳ chi tiết nào. Đối với giao diện sản phẩm cần tùy chỉnh sâu, chế độ "sở hữu code" này linh hoạt nhất. + +### 4.1 Tạo dự án + +```bash +# Tạo dự án Next.js +npx create-next-app@latest ai-writer-app --typescript --tailwind --app +cd ai-writer-app + +# Khởi tạo shadcn/ui +npx shadcn@latest init + +# Thêm component theo nhu cầu (không cài tất cả cùng lúc) +npx shadcn@latest add button card input sidebar sheet dialog +``` + +Điểm độc đáo của shadcn/ui: mỗi lần `add` một component, nó sẽ sao chép mã nguồn vào thư mục `components/ui/` của dự án bạn. Bạn có thể mở trực tiếp các tệp này để chỉnh sửa phong cách và hành vi. + +### 4.2 Sử dụng AI IDE để tạo giao diện sản phẩm + +```text +Vui lòng giúp tôi tạo giao diện chính trợ lý viết AI, sử dụng thư viện component shadcn/ui: + +**Bố cục tổng thể:** +- Bên trái là侧边栏 có thể thu gọn,宽度 khoảng 280px: + - Trên cùng đặt nút "Tài liệu mới" + - Bên dưới là danh sách tài liệu, mỗi tài liệu hiển thị tiêu đề và thời gian chỉnh sửa cuối + - Nhấp chuột phải vào tài liệu có thể đổi tên hoặc xóa +- Bên phải là khu vực soạn thảo chính, chia thành hai phần trên dưới: + - Phần trên là thanh công cụ: có thể chỉnh sửa tiêu đề tài liệu, hiển thị thống kê số từ, nút "AI tiếp tục viết", menu thả xuống "Xuất" + - Phần dưới là khu vực soạn thảo: một ô nhập văn bản lớn, chiếm đầy không gian còn lại + +**Chi tiết tương tác:** +- Sau khi nhấp "AI tiếp tục viết", nút hiển thị trạng thái loading, dưới cùng trình soạn thảo xuất hiện văn bản do AI tạo (hiển thị từng chữ như máy đánh chữ) +- Trên điện thoại侧边栏 thành kiểu drawer, trượt ra từ bên trái +- Tài liệu đang chọn cần highlight +``` + +### 4.3 Các component cốt lõi mà AI sẽ sử dụng + +```tsx +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Card, CardContent, CardHeader } from '@/components/ui/card' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@/components/ui/dropdown-menu' +import { + Sheet, + SheetContent, + SheetTrigger +} from '@/components/ui/sheet' +import { + Sidebar, + SidebarContent, + SidebarHeader +} from '@/components/ui/sidebar' +``` + +| Component | Mục đích | Vị trí trong trang sản phẩm | +| :--- | :--- | :--- | +| `Sidebar` |侧边栏 có thể thu gọn | Danh sách tài liệu bên trái | +| `Sheet` | Drawer thiết bị di động | Thay thế侧边栏 trên thiết bị di động | +| `DropdownMenu` | Menu thả xuống | Nút "Xuất", menu chuột phải | +| `Dialog` | Hộp thoại | Đổi tên, xác nhận xóa | +| `Button` | Nút bấm, hỗ trợ variant và loading | Các nút thao tác khác nhau | +| `Input` | Ô nhập liệu | Chỉnh sửa tiêu đề tài liệu | + +### 4.4 Tùy chỉnh phong cách component + +Ưu điểm của shadcn/ui là bạn có thể chỉnh sửa trực tiếp mã nguồn component. Ví dụ bạn muốn tăng bo góc nút: + +```text +Vui lòng giúp tôi chỉnh sửa components/ui/button.tsx, +thay bo góc mặc định của tất cả nút từ rounded-md thành rounded-xl, +và thêm hiệu ứng bóng mờ tinh tế cho biến thể primary +``` + +AI sẽ chỉnh sửa trực tiếp tệp component trong dự án của bạn, chứ không ghi đè phong cách npm package — đây chính là lợi ích của "sở hữu code" shadcn/ui. + +## 5. Thực chiến 3: Xây dựng giao diện quản lý back-office bằng Ant Design + +**Kịch bản**: Sau khi trợ lý viết AI của bạn lên mạng, cần một back-office quản trị để xem dữ liệu người dùng, quản lý nội dung tài liệu, xử lý đơn hàng thanh phí. Cốt lõi của hệ thống quản lý back-office là hiển thị dữ liệu và hiệu quả thao tác. + +**Tại sao chọn Ant Design**: Ant Design có tích lũy sâu nhất trong lĩnh vực back-office cấp trung, các component nghiệp vụ như bảng, biểu mẫu, biểu đồ sử dụng ngay, tích hợp nhiều mô hình tương tác cấp doanh nghiệp (thao tác hàng loạt, lọc nâng cao, xuất dữ liệu, v.v.). + +### 5.1 Tạo dự án + +```bash +# Sử dụng scaffolding Ant Design Pro (tích hợp bố cục, định tuyến, phân quyền) +npx create-umi@latest ai-writer-admin +# Chọn mẫu Ant Design Pro +cd ai-writer-admin +npm install +``` + +Hoặc bắt đầu từ đầu: + +```bash +npx create-react-app ai-writer-admin --template typescript +cd ai-writer-admin +npm install antd @ant-design/icons @ant-design/pro-components +``` + +### 5.2 Sử dụng AI IDE để tạo back-office quản trị + +```text +Vui lòng giúp tôi tạo back-office quản trị trợ lý viết AI, sử dụng thư viện component Ant Design: + +**Bố cục tổng thể:** +- Bên trái là thanh menu: bảng điều khiển, quản lý người dùng, quản lý tài liệu, quản lý đơn hàng, cài đặt hệ thống +- Trên cùng hiển thị điều hướng breadcrumb + +**Trang quản lý người dùng:** +- Trên cùng đặt bốn thẻ thống kê: tổng số người dùng,新增 hôm nay, số người dùng hoạt động, số người dùng trả phí +- Khu vực tìm kiếm lọc: có thể tìm theo tên người dùng, chọn phạm vi thời gian đăng ký, lọc trạng thái người dùng, còn có nút "Tìm kiếm" và "Đặt lại" +- Bảng người dùng: + - Hiển thị avatar, tên người dùng, email, thời gian đăng ký, gói đăng ký (phân biệt bằng nhãn màu khác nhau), trạng thái, thao tác + - Mỗi trang hiển thị 20 dòng, hỗ trợ phân trang + - Có thể chọn hàng loạt người dùng, vô hiệu hóa hoặc xuất hàng loạt + - Cột thao tác: xem chi tiết, chỉnh sửa, vô hiệu hóa (cần xác nhận lần hai trước khi vô hiệu hóa) +- Nhấp "Xem chi tiết" trượt ra drawer từ bên phải, hiển thị thông tin chi tiết người dùng và danh sách tài liệu gần đây +``` + +### 5.3 Các component cốt lõi mà AI sẽ sử dụng + +```tsx +import { PageContainer, ProLayout } from '@ant-design/pro-components' +import { ProTable } from '@ant-design/pro-components' +import { StatisticCard } from '@ant-design/pro-components' +import { + Button, Tag, Badge, Space, Drawer, + Popconfirm, message, Modal +} from 'antd' +import { + UserOutlined, SearchOutlined, ExportOutlined +} from '@ant-design/icons' +``` + +| Component | Mục đích | Vị trí trong back-office | +| :--- | :--- | :--- | +| `ProLayout` | Khung bố cục tổng thể back-office | Khung xương trang (menu + khu vực nội dung) | +| `ProTable` | Bảng nâng cao, tích hợp tìm kiếm, phân trang, cài đặt cột | Danh sách người dùng, danh sách tài liệu, danh sách đơn hàng | +| `StatisticCard` | Thẻ thống kê dữ liệu | Bảng điều khiển, tổng quan phía trên trang | +| `Tag` / `Badge` | Nhãn trạng thái | Gói đăng ký, trạng thái người dùng | +| `Drawer` | Drawer侧边 | Chi tiết người dùng, biểu mẫu chỉnh sửa | +| `Popconfirm` | Hộp xác nhận bubble | Xóa, vô hiệu hóa và các thao tác nguy hiểm khác | + +### 5.4 Tiếp tục lặp: Thêm bảng điều khiển + +```text +Vui lòng giúp tôi tạo một trang bảng điều khiển: + +1. Bốn thẻ thống kê phía trên: tổng số người dùng, tổng số tài liệu, số lần gọi API hôm nay, doanh thu hàng tháng, mỗi thẻ hiển thị giá trị và thay đổi tuần hoàn (tăng hay giảm) +2. Giữa đặt hai biểu đồ: + - Bên trái: biểu đồ đường tăng trưởng người dùng 7 ngày gần nhất + - Bên phải: biểu đồ tròn phân bố gói đăng ký +3. Phía dưới: bảng nhật ký thao tác gần đây, hiển thị thời gian, người dùng, loại thao tác, chi tiết + +Sử dụng component Ant Design để bố cục, biểu đồ có thể sử dụng Ant Design Charts +``` + +> **Kỹ巧 Vibe Coding cho quản lý back-office**: Cấu trúc trang back-office tương đối cố định (bảng + tìm kiếm +弹窗), rất phù hợp để AI tạo hàng loạt. Bạn có thể để AI tạo trước một trang "Quản lý người dùng" làm mẫu, sau đó nói "Tham khảo cấu trúc trang quản lý người dùng, giúp tôi tạo trang quản lý tài liệu", AI sẽ tái sử dụng cùng một mô hình bố cục. + +## 6. Học cách đọc tài liệu: "Hướng dẫn sử dụng" của thư viện component + +Trong Vibe Coding, AI sẽ giúp bạn viết hầu hết code, nhưng khi kết quả AI tạo ra không chính xác, hoặc bạn muốn tinh chỉnh hành vi của một component, **đọc tài liệu** là cách giải quyết nhanh nhất. + +Lấy Ant Design làm ví dụ, địa chỉ tài liệu của nó là: `https://ant.design/components/overview-cn` + +Quy trình chuẩn để đọc tài liệu: + +1. **Xác định nhu cầu**: Ví dụ "Tôi cần bảng hỗ trợ chọn hàng" +2. **Tìm trong tài liệu**: Tìm "Table" để vào trang component bảng +3. **Xem ví dụ**: Mỗi component trong tài liệu đều có nhiều ví dụ trực tuyến, tìm ví dụ "Có thể chọn" +4. **Sao chép code**: Sao chép code ví dụ vào dự án của bạn +5. **Xem bảng API**: Tìm cấu hình đầy đủ của thuộc tính `rowSelection` ở cuối trang + +> Bạn cũng có thể gửi trực tiếp liên kết tài liệu cho AI IDE: "Vui lòng tham khảo API rowSelection của https://ant.design/components/table-cn, giúp tôi thêm chức năng chọn hàng loạt cho bảng người dùng". Cung cấp liên kết tài liệu cho AI, code tạo ra sẽ chính xác hơn. + +Tra cứu nhanh địa chỉ tài liệu các thư viện component: + +| Thư viện component | Địa chỉ tài liệu | +| :--- | :--- | +| Ant Design | `https://ant.design/components/overview-cn` | +| shadcn/ui | `https://ui.shadcn.com/docs/components` | +| HeroUI | `https://heroui.com/docs/components` | +| Material UI | `https://mui.com/material-ui/all-components/` | +| Element Plus | `https://element-plus.org/zh-CN/component/overview.html` | + +## 7. Tóm tắt + +Ba kịch bản thực chiến bao phủ các nhu cầu phát triển frontend phổ biến nhất: + +| Kịch bản | Thư viện component khuyến nghị | Đặc điểm cốt lõi | +| :--- | :--- | :--- | +| Landing page / Trang showcase | HeroUI | Phong cách mặc định tinh xảo, animation mượt mà, sức mạnh thị giác mạnh | +| Trang chức năng sản phẩm | shadcn/ui | Code hoàn toàn có thể kiểm soát, tùy chỉnh sâu linh hoạt | +| Hệ thống quản lý back-office | Ant Design | Component nghiệp vụ phong phú, bảng biểu mẫu sử dụng ngay | + +Tóm tắt quy trình làm việc Vibe Coding: + +1. Chọn thư viện component phù hợp theo kịch bản +2. Sử dụng AI IDE để mô tả cấu trúc trang và tương tác bạn muốn +3. AI tạo code phiên bản đầu, bạn xem trước hiệu quả +4. Tiếp tục lặp và điều chỉnh bằng ngôn ngữ tự nhiên +5. Khi gặp vấn đề chi tiết, tra cứu tài liệu thư viện component + +### Bài tập + +Chọn một trong các kịch bản sau, sử dụng AI IDE + thư viện component để hoàn thành từ đầu: + +1. Sử dụng HeroUI để tạo một landing page showcase cho dự án bạn đã làm trước đó (ví dụ chân dung Hogwarts) +2. Sử dụng shadcn/ui để xây dựng giao diện chính của ứng dụng ghi chú (侧边栏 + trình soạn thảo) +3. Sử dụng Ant Design để xây dựng một back-office quản lý nội dung đơn giản (danh sách bài viết + biểu mẫu tạo bài viết mới) + +--- + +## Phụ lục: Thêm thư viện component + +Ngoài bốn thư viện cốt lõi được giới thiệu trong phần chính, hệ sinh thái frontend còn có nhiều thư viện component xuất sắc. Dưới đây liệt kê theo framework phân loại, tiện cho bạn lựa chọn theo nhu cầu dự án. + +### Hệ sinh thái Vue + +| Thư viện component | Stars | Giới thiệu | Kịch bản sử dụng | +| :--- | :--- | :--- | :--- | +| [Element Plus](https://element-plus.org) | ~27k | Thư viện component doanh nghiệp Vue 3 do团队饿了么 phát triển, phổ biến nhất tại Trung Quốc, hệ sinh thái tiếng Trung tuyệt vời | Hệ thống quản lý back-office cấp trung | +| [Vuetify](https://vuetifyjs.com) | ~41k | Thư viện component Vue Material Design phổ biến nhất, 80+ component, tài liệu hoàn thiện | Dự án phong cách thiết kế Google | +| [Ant Design Vue](https://antdv.com) | ~21k | Thư viện component Vue 3 dựa trên hệ thống thiết kế Ant, quy phạm thiết kế thống nhất | Back-office doanh nghiệp cấp trung | +| [Naive UI](https://www.naiveui.com) | ~18k | Viết bằng TypeScript, tính tùy chỉnh theme cực mạnh, không phụ thuộc CSS preprocessor | Dự án có yêu cầu thiết kế độc đáo | +| [Quasar](https://quasar.dev) | ~27k | Một bộ code xây dựng ứng dụng SPA, SSR, PWA, thiết bị di động và desktop | Dự án cross-platform | +| [Vant](https://vant-ui.github.io/vant) | ~24k | Thư viện component mobile nhẹ do团队有赞 phát triển, bao phủ các nhu cầu thương mại điện tử phổ biến | Trang H5 mobile | +| [PrimeVue](https://primevue.org) | ~14k | 90+ component, hỗ trợ nhiều theme (Material, Bootstrap, v.v.) | Cần component phong phú và đa theme | +| [Arco Design Vue](https://arco.design/vue) | ~3k | Sản phẩm bởi ByteDance, chất lượng component cao, tích hợp chế độ tối | Sản phẩm back-office cấp trung | +| [TDesign Vue Next](https://tdesign.tencent.com/vue-next) | ~2k | Sản phẩm bởi Tencent, ngôn ngữ thiết kế thống nhất, bao phủ các kịch bản phổ biến desktop | Hệ sinh thái Tencent hoặc dự án doanh nghiệp | + +### Hệ sinh thái React + +| Thư viện component | Stars | Giới thiệu | Kịch bản sử dụng | +| :--- | :--- | :--- | :--- | +| [Material UI (MUI)](https://mui.com) | ~95k | Triển khai quy phạm Google Material Design lâu đời nhất, component toàn diện nhất, hệ sinh thái trưởng thành nhất | Xây dựng nhanh ứng dụng doanh nghiệp | +| [Ant Design](https://ant.design) | ~94k | Sản phẩm bởi Ant Group, tích hợp nhiều component nghiệp vụ chất lượng cao, vị thế chủ đạo cộng đồng developer tiếng Trung | Back-office doanh nghiệp cấp trung | +| [shadcn/ui](https://ui.shadcn.com) | ~83k | Code sao chép vào dự án chứ không cài npm, dựa trên Radix UI + Tailwind CSS, hoàn toàn có thể kiểm soát | Dự án cần tùy chỉnh cao | +| [Chakra UI](https://chakra-ui.com) | ~39k | Lấy trải nghiệm developer làm cốt lõi, API简洁, tích hợp hỗ trợ truy cập vô障碍 | Phát triển nguyên mẫu nhanh | +| [Mantine](https://mantine.dev) | ~28k | 100+ component và 50+ hooks, bao gồm date picker, rich text editor và các component nâng cao khác | Cần giải pháp全功能 sử dụng ngay | +| [Headless UI](https://headlessui.com) | ~27k | Thư viện component không phong cách chính thức bởi Tailwind Labs, đồng thời hỗ trợ React và Vue | Sử dụng kết hợp với Tailwind CSS | +| [HeroUI](https://heroui.com) | ~24k | Dựa trên Tailwind CSS + React Aria, phong cách mặc định tinh xảo, animation mượt mà | Dự án theo đuổi chất lượng thị giác | +| [Radix UI](https://www.radix-ui.com) | ~17k | Thư viện primitive component không phong cách底层的, tập trung vô障碍 và hành vi component, là nền tảng底层的 của shadcn/ui | Xây dựng hệ thống thiết kế tùy chỉnh | + +#### Hệ sinh thái mở rộng shadcn/ui + +Ngoài các thư viện component通 dụng trên, hệ sinh thái shadcn/ui còn xuất hiện nhiều thư viện mở rộng dựa trên khái niệm của nó, cung cấp lựa chọn khác biệt cho các kịch bản cụ thể. Các thư viện mở rộng này cũng采用 mô hình "sao chép code vào dự án", cho developer có quyền kiểm soát mã nguồn hoàn toàn. + +| Thư viện component | Giới thiệu | Kịch bản sử dụng | +| :--- | :--- | :--- | +| [Aceternity UI](https://ui.aceternity.com) | 200+ component cấp production,主打 thẻ phát sáng, gradient文字, 3D地球 và các component thị giác đặc sắc khác | Landing page chất lượng cao, sản phẩm SaaS | +| [Tailark UI](https://tailark.com) | Bộ sưu tập khối component trang web marketing, showcase sản phẩm, lời chứng nhận khách hàng, nút CTA và các module marketing tần suất cao | Landing page marketing, trang chủ sản phẩm | +| [UI Tripled](https://ui.tripled.work) | Component tương tác động dựa trên Framer Motion,弹窗, điều hướng, animation thẻ | Công cụ sáng tạo, portfolio cá nhân | +| [Neobrutalism UI](https://neobrutalism.dev) | Phong cách Neo-brutalism, đường viền粗, độ tương phản cao, màu sắc鲜明 | Trang chủ thương hiệu cá nhân hóa, dự án sáng tạo | +| [REUI](https://reui.io) | 967+ mẫu tổ hợp component cho 967+ kịch bản nghiệp vụ thực tế | Back-office doanh nghiệp, biểu mẫu phức tạp | +| [Cult UI](https://cult-ui.com) | Đánh bóng tương tác/thị giác tinh tế hơn, component phức hợp như bảng dữ liệu, bảng lọc | Dự án thương mại chất lượng cao | +| [Kibo UI](https://kibo-ui.com) | Component nghiệp vụ nâng cao, color picker, rich text editor, tải tệp | Back-office quản lý, sản phẩm kiểu công cụ | +| [Kokonut UI](https://kokonutui.com) | 100+ component + 7+ template hoàn chỉnh, phong cách清新简约 | Trang chủ SaaS, blog, thương mại điện tử | +| [Commerce UI](https://ui.stackzero.co) | Chuyên dùng cho kịch bản thương mại điện tử, thẻ sản phẩm, giỏ hàng, biểu mẫu thanh toán | Nền tảng thương mại điện tử | +| [shadcnblocks](https://shadcnblocks.com) | 1373 UI block + 13 bộ template hoàn chỉnh, tài nguyên toàn diện nhất | Tất cả các kịch bản | +| [Shoogle](https://shoogle.dev) | Nền tảng tổng hợp tìm kiếm hệ sinh thái shadcn/ui | Tìm kiếm tài nguyên nhanh chóng | +| [Discover All Shadcn](https://allshadcn.com) | Điều hướng tài nguyên tổng hợp | Tìm kiếm tài nguyên nhanh chóng | + +> **Tại sao chọn mở rộng shadcn/ui?** Các mở rộng này kế thừa khái niệm "quyền sở hữu code" của shadcn/ui, đồng thời tùy chỉnh sâu cho các kịch bản cụ thể. Trong thời đại Vibe Coding, chúng giúp bạn nhanh chóng tìm được component phù hợp với nhu cầu thiết kế, thoát khỏi sự同质 hóa của các thư viện UI主流, tạo ra sản phẩm có tính khác biệt hóa cao hơn. diff --git a/docs/vi-vn/stage-2/frontend/multi-product-ui/index.md b/docs/vi-vn/stage-2/frontend/multi-product-ui/index.md new file mode 100644 index 0000000..6c42cac --- /dev/null +++ b/docs/vi-vn/stage-2/frontend/multi-product-ui/index.md @@ -0,0 +1,425 @@ +# Thiết kế trang và nút bấm theo quy chuẩn UI + +Nhiều người nói "Tôi muốn trang giống Apple hơn một chút" "Nút bấm muốn làm cao cấp hơn một chút", nhưng khi thực sự bắt đầu làm, thường sẽ bị kẹt ở một vấn đề: + +**Rốt cuộc nên tham khảo cái gì?** + +Nhìn screenshot bắt chước, học được chỉ là "có giống hay không". Nhưng khi mở quy chuẩn thiết kế của Apple, Google, Microsoft, Atlassian, bạn sẽ phát hiện điểm thực sự tuyệt vời của họ không phải là phong cách thị giác, mà là **nói rõ vấn đề thiết kế**: trang trước tiên làm nổi bật cái gì, nút bấm phân cấp thế nào, thao tác nhấn mạnh ra sao — những tiêu chuẩn phán đoán này mới là cốt lõi. + +> Tham khảo quy chuẩn thiết kế, không phải để làm "giống ai", mà là học cách người khác đưa ra phán đoán. + +:::: info Tại sao bây giờ vẫn cần học những điều này +Các quy tắc thiết kế đã được huấn luyện vào mô hình, được công cụ thiết kế hấp thụ mặc định, thậm chí chỉ cần dán vài screenshot AI đã có thể học được. Nhưng chúng ta vẫn cần biết những quy tắc này đến từ đâu, tại sao lại quy định như vậy. +:::: + +## Trước hết xem vài đoạn nguyên văn, cảm nhận khoảng cách + +Nếu bạn trước đây nghĩ "quy chuẩn thiết kế chẳng phải chỉ nói về phong cách thôi sao", hãy xem trước vài câu nguyên văn chính thức. + +Bình thường trong đội nhóm chúng ta thường nói như thế này: + +- Làm một dropdown +- Ở đây đặt một menu +- Thêm vài chức năng vào thanh menu +- Ở đây đặt hai nút, một xác nhận một hủy + +Nghe có vẻ không có vấn đề, nhưng trong quy chuẩn của các công ty lớn, những từ này không phải là khái niệm mơ hồ, mà được phân tích rất chi tiết. + +| Lời nói bình thường | Nguyên văn chính thức | Nói đơn giản | +| :--- | :--- | :--- | +| "Làm một menu" | Apple: ["A menu reveals its options..."](https://developer.apple.com/design/human-interface-guidelines/menus) | `Menu` là dùng để làm thao tác | +| "Đặt chức năng vào thanh menu" | Apple: ["menu bar menus contain all the commands..."](https://developer.apple.com/design/human-interface-guidelines/menus) | Đây là menu lệnh ở đầu ứng dụng | +| "Làm một dropdown" | Apple: ["A pop-up list lets the user choose one option among several."](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pop-up` là chọn một cái từ danh sách | +| "Cũng làm một dropdown" | Apple: ["A pull-down list is generally used for selecting commands in a specific context."](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pull-down` là bấm mở để làm thao tác hiện tại | +| "Menu cũng có thể dùng để lọc đúng không" | Fluent: ["If you need to collect information from people, try a select, dropdown, or combobox instead."](https://fluent2.microsoft.design/components/web/react/core/menu/usage) | `Menu` không phải để chọn giá trị | +| "Menu cũng có thể làm điều hướng đúng không" | Material: ["Menus should not be used as a primary method for navigation within an app."](https://m1.material.io/components/menus.html) | `Menu` không phải điều hướng chính | +| "Nút bấm cứ viết OK / Cancel thôi" | Apple: ["Always use 'Cancel' to title a button that cancels the alert's action."](https://developer.apple.com/design/human-interface-guidelines/alerts) | Văn bản nút không thể viết tùy tiện | + +> Các trích dẫn trong bảng đều có thể nhấp trực tiếp để đến trang chính thức tương ứng. + +Đây chính là điều dễ gây ấn tượng mạnh nhất khi lần đầu tiên thực sự xem quy chuẩn thiết kế: + +> Chúng ta bình thường tưởng mình đang thảo luận về UI, nhưng thực tế rất nhiều lúc chỉ đang giao tiếp bằng một đống từ ngữ mơ hồ. + +Apple sẽ không chỉ nói "làm một menu"; nó sẽ tiếp tục phân biệt: + +- `menu` +- `menu bar menu` +- `pop-up button` +- `pull-down button` +- `context menu` + +Fluent sẽ không chỉ nói "dropdown"; nó sẽ tiếp tục phân biệt: + +- `menu` +- `dropdown` +- `select` +- `combobox` + +Đây chính là sự cần thiết của quy chuẩn thiết kế. + +Nó không phải để làm trang có vẻ chuyên nghiệp hơn, mà là để khi đội nhóm thảo luận về UI, trong đầu mỗi người không còn là những thứ khác nhau nữa. + +## Bạn sẽ học được gì + +1. Tại sao khi thiết kế trang và nút bấm cần xem quy chuẩn thiết kế trước +2. Trong các quy chuẩn Apple, Material, Fluent, Atlassian, nội dung nào đáng tham khảo nhất +3. Cách thiết kế rõ ràng "cấp bậc trang" và "cấp bậc nút bấm" +4. Cách để AI tham khảo quy chuẩn của người khác để tạo trang và nút bấm + +## 1. Tại sao quy chuẩn thiết kế có thể giúp bạn làm rõ trang + +Sau khi xem những nguyên văn trên, bạn sẽ phát hiện một điểm quan trọng: + +**Quy chuẩn thiết kế không phải điểm tô, mà là trước hết nói chính xác từ ngữ.** + +Nhiều trang không đẹp, không phải vì màu sắc không đủ cao cấp, mà vì cấp bậc thông tin lộn xộn. + +Nhiều nút không dễ dùng, cũng không phải vì bo góc không đúng, mà vì: + +- Nút chính quá nhiều, người dùng không biết nên nhấn cái nào +- Nút nguy hiểm và nút bình thường trông giống nhau +- Tất cả nút trong trang đều tranh giành sự chú ý +- Phong cách và ngữ nghĩa của nút không nhất quán giữa các trang khác nhau + +Quy chuẩn thiết kế trưởng thành,恰好 là đang giải quyết những vấn đề này. Chúng thường sẽ định nghĩa: + +| Nội dung quy chuẩn | Nó giải quyết vấn đề gì | +| :--- | :--- | +| **Cấp bậc trang** | Nhìn đâu trước, nhìn đâu sau, thông tin tổ chức thế nào | +| **Nền tảng thị giác** | Màu sắc, khoảng cách, font chữ, bo góc, bóng đổ thống nhất thế nào | +| **Cấp bậc nút bấm** | Nút chính, nút phụ, nút văn bản, nút nguy hiểm phân biệt thế nào | +| **Quy tắc trạng thái** | hover, focus, disabled, loading thể hiện thế nào | +| **Ngữ nghĩa tương tác** | Nút nào là "xác nhận", nút nào là "hủy", nút nào là "thao tác thêm" | + +Vì vậy, quy chuẩn thiết kế thực sự cung cấp không phải là một "lớp da", mà là một **tiêu chuẩn phán đoán**. + +## 2. Khi tham khảo quy chuẩn công ty lớn, tập trung vào điều gì + +### 2.1 Tham khảo Apple: Học cách "định nghĩa đủ chi tiết" + +Điều đáng học nhất ở Apple không chỉ là sự kiềm chế thị giác, mà là nó sẽ định nghĩa khái niệm rất chi tiết. + +Cùng là "menu" hoặc "dropdown" trong miệng nhiều đội nhóm, Apple sẽ tiếp tục phân tích nhỏ: + +- `menu`: Một nhóm lệnh, tùy chọn hoặc trạng thái +- `menu bar menu`: Tập hợp lệnh cấp ứng dụng +- `pop-up button`: Chọn một giá trị +- `pull-down button`: Kích hoạt lệnh trong ngữ cảnh hiện tại +- `context menu`: Các hành động thường dùng liên quan đến đối tượng hoặc nhiệm vụ hiện tại + +Sự phân biệt này rất quan trọng, vì nó sẽ trực tiếp ảnh hưởng đến: + +- Component này dùng để chọn giá trị, hay dùng để làm hành động +- Nó thuộc về cục bộ trang, hay thuộc về cấp ứng dụng +- Nó nên hiển thị lâu dài giá trị đã chọn, hay chỉ tạm thời mở rộng lệnh + +Khi bạn bắt đầu suy nghĩ theo mức độ chi tiết này, trang bạn thiết kế sẽ lập tức rõ ràng hơn nhiều. + +### 2.2 Tham khảo Apple: Học cấp bậc trang và sự kiềm chế + +Apple Human Interface Guidelines đặc biệt phù hợp để học hai điều: + +- Trang thiết lập cấp bậc rõ ràng thế nào +- Điều khiển giữ rõ ràng dưới tiền đề không lấn át + +Apple nhấn mạnh `Hierarchy`, `Harmony`, `Consistency`. Điều này có nghĩa là khi thiết kế trang cần trả lời: + +- Thông tin quan trọng nhất của trang hiện tại là gì +- Nhiệm vụ chính của người dùng là gì +- Thao tác nào nên nổi bật nhất, thao tác nào nên lùi lại + +Nếu bạn tham khảo Apple để thiết kế trang, có thể tập trung tham khảo: + +- Thông tin màn hình đầu không nên quá vụn, nội dung cốt lõi tập trung trước +- Dùng khoảng trắng, kích thước font, nhóm để tạo trật tự, thay vì chất nhiều viền +- Nút không nên tất cả đều nhấn mạnh cao, chỉ hành động quan trọng mới nên nổi bật nhất + +### 2.3 Tham khảo Material: Học cấu trúc trang rõ ràng + +Material Design rất phù hợp để học "trang tổ chức luồng nhiệm vụ thế nào". + +Nhiều component và quy chuẩn layout của nó, cốt lõi đều giúp bạn làm rõ: + +- Trang là loại duyệt, hay loại thực thi nhiệm vụ +- Trang hiện tại là để người dùng đọc, chọn, hay nộp +- Trong một trang, yếu tố nào nên lặp lại ổn định, yếu tố nào nên phản hồi thay đổi ngữ cảnh + +Nếu bạn tham khảo Material để thiết kế trang, có thể tập trung tham khảo: + +- Khu vực trang rõ ràng, trách nhiệm module xác định +- Điều hướng, khu vực nội dung, khu vực thao tác phân công rõ ràng +- Các phong cách nút khác nhau tương ứng với mức độ ưu tiên thao tác khác nhau + +### 2.4 Tham khảo Fluent: Học ranh giới component và cấp bậc nút + +Fluent 2 rất phù hợp cho sản phẩm backend, công cụ và hệ thống form phức tạp. Điều đáng học nhất là nó sẽ trực tiếp nói cho bạn biết "đừng lẫn lộn khái niệm". + +Ví dụ nó ghi rõ: nếu bạn muốn "collect information", thì đừng tiếp tục dùng `menu`, mà nên cân nhắc `select`, `dropdown`, `combobox`. + +Câu nói này rất quan trọng, vì nó phá vỡ "cũng gần giống nhau" trong đầu nhiều người. + +Fluent 2 cũng rất chú trọng: + +- Cấp bậc thao tác +- Ranh giới ngữ nghĩa component +- Độ rõ ràng trong kịch bản thông tin dày đặc + +Nếu bạn tham khảo Fluent để thiết kế nút, có thể tập trung tham khảo: + +- `Primary button` dùng để gánh hành động quan trọng nhất hiện tại +- `Secondary button` dùng để gánh hành động hỗ trợ +- Các nút nhấn mạnh yếu như `Subtle`, `Transparent` dùng cho thao tác không nên tranh luồng chính +- Càng nhiều nút trong trang, càng cần kiểm soát mức độ ưu tiên thị giác + +### 2.5 Tham khảo Atlassian: Học quản lý trang và nút bấm theo hệ thống + +Atlassian Design System đặc biệt phù hợp cho tình huống "một đội nhóm làm nhiều trang". Nó nhấn mạnh: + +- foundations là nền tảng chia sẻ +- tokens là phương pháp thống nhất quyết định thị giác +- components là thành phần tương tác được tái sử dụng lặp đi lặp lại + +Nếu bạn tham khảo Atlassian để làm trang và nút, giá trị nhất là: + +- Làm kích thước, màu sắc, bo góc, khoảng cách nút thành quy tắc thống nhất +- Cố định nhịp điệu layout trang +- Để các trang khác nhau tuy nội dung khác nhưng ngôn ngữ cấu trúc nhất quán + +## 3. Khi thiết kế trang, nên tham khảo những điểm nào trong quy chuẩn + +Khi bạn xem một hệ thống thiết kế, đừng hỏi trước "trang này đẹp không", mà hãy hỏi trước mấy câu hỏi dưới đây. + +### 3.1 Nhìn trang lần đầu, chính phụ có rõ ràng không + +Một trang thường ít nhất phải có ba tầng: + +- **Thông tin chính**: Nội dung quan trọng nhất của trang hiện tại +- **Thông tin phụ trợ**: Nội dung giúp hiểu hoặc bổ sung +- **Thao tác cấp hai**: Hành động không nên can thiệp nhiệm vụ chính + +Nếu ba tầng không mở rộng ra, trang sẽ "đều quan trọng", tương đương với "đều không quan trọng". + +### 3.2 Layout trang, có phục vụ nhiệm vụ thay vì chất module không + +Khi tham khảo quy chuẩn, có thể đặc biệt chú ý: + +- Khu vực tiêu đề có làm rõ mục tiêu trang không +- Khu vực nội dung chính có xoay quanh nhiệm vụ tổ chức không +- Nút thao tác có gần nội dung liên quan không +- Thông tin thứ cấp có được làm yếu đi không + +### 3.3 Thao tác trong trang, có mức độ ưu tiên không + +Nhiều trang nhìn qua có 6 nút, kết quả mỗi nút đều giống CTA, đây là cấp bậc mất kiểm soát điển hình. + +Cách hợp lý hơn là: + +- Một khu vực thường chỉ có một thao tác chính +- Thao tác cấp hai có thể dùng viền, nút văn bản hoặc phong cách yếu hơn +- Hành động rủi ro không nên trông giống hành động chính + +## 4. Khi thiết kế nút, nên tham khảo những điểm nào trong quy chuẩn + +Nút là phần dễ bị "thiết kế tùy tiện" nhất, nhưng cũng là phần dễ bộc lộ hệ thống có trưởng thành hay không nhất. + +### 4.1 Nút trước hết phân "ngữ nghĩa", rồi mới phân "phong cách" + +Đừng nghĩ trước "nút xanh hay nút đen", hãy nghĩ trước nút này đóng vai trò gì. + +Vai trò nút phổ biến có thể phân như sau: + +| Loại nút | Tác dụng | Chiến lược phong cách phổ biến | +| :--- | :--- | :--- | +| **Primary** | Hành động quan trọng nhất trong khu vực hiện tại | Đặc, tương phản cao, nổi bật nhất | +| **Secondary** | Hành động hỗ trợ | Viền hoặc nhấn mạnh thấp hơn một cấp | +| **Tertiary / Text** | Thao tác yếu | Văn bản hoặc tỷ trọng thị giác thấp | +| **Destructive** | Các thao tác rủi ro như xóa, vô hiệu hóa, xóa sạch | Màu cảnh báo hoặc phong cách rủi ro rõ ràng | +| **Icon button** | Thao tác công cụ cục bộ | Ngắn gọn, gần ngữ cảnh | + +### 4.2 Một trang không nên có quá nhiều Primary Button + +Đây là cái bẫy dễ giẫm nhất của nhiều người mới. + +Nếu trên trang có 4 nút chính, thì tương đương không có nút chính. Ý nghĩa của nút chính vốn dĩ là "nói cho người dùng biết bây giờ nên làm gì nhất". + +Bạn có thể tham khảo cách làm chung của nhiều hệ thống thiết kế: + +- Một khu vực chính thường chỉ giữ một nút chính +- Hủy, quay lại, đóng thường không tranh cùng cấp với nút xác nhận +- Thêm thao tác đặt vào nút cấp hai hoặc menu + +### 4.3 Nút phải có thể thể hiện thay đổi trạng thái + +Quy chuẩn thiết kế thường viết rất rõ về trạng thái nút: + +- Trạng thái mặc định +- Trạng thái hover +- Trạng thái focus +- Trạng thái disabled +- Trạng thái loading +- Trạng thái nguy hiểm + +Điều này rất quan trọng, vì nút không phải là một bức ảnh tĩnh, mà là một trong những điều khiển được kích hoạt thường xuyên nhất trong quá trình người dùng thao tác. + +### 4.4 Văn bản nút, cũng thuộc một phần của thiết kế + +Văn bản nút không chỉ là "vấn đề copywriting", nó trực tiếp ảnh hưởng đến sự hiểu biết của người dùng. + +Ví dụ: + +- `Lưu` +- `Lưu thay đổi` +- `Xuất bản ngay` +- `Xóa dự án` +- `Chuyển vào thùng rác` + +Những văn bản này truyền đạt kỳ vọng tâm lý hoàn toàn khác nhau. Quy chuẩn trưởng thành thường yêu cầu nhãn nút thể hiện rõ hành động, thay vì sử dụng từ ngữ mơ hồ. + +## 5. Một danh sách thiết kế trang và nút rất thực dụng + +Khi bạn tự thiết kế trang, có thể xem nhanh qua danh sách này trước: + +### Danh sách trang + +- Tiêu đề trang có nói rõ nhiệm vụ hiện tại không +- Thông tin quan trọng nhất màn hình đầu có nhìn thấy ngay không +- Trang có tổ chức theo luồng nhiệm vụ, thay vì nghĩ đến gì đặt nấy không +- Trong cùng một khu vực có chỉ có một thao tác chính không +- Nội dung thứ cấp có được làm yếu phù hợp không + +### Danh sách nút + +- Nút này là thao tác chính hay thao tác phụ +- Tại sao nó đáng nổi bật hơn nút khác +- Trong trang có quá nhiều nút chính không +- Thao tác nguy hiểm có được đánh dấu rõ ràng không +- Văn bản nút có đủ cụ thể không + +## 6. Cách dùng AI tham khảo quy chuẩn của người khác để thiết kế trang + +Phần này thực dụng nhất. + +Nhiều người khi để AI thiết kế trang, chỉ nói: + +```md +Giúp tôi làm một trang cài đặt, cao cấp hơn một chút, tham khảo phong cách Apple +``` + +Loại prompt này quá mơ hồ, AI cuối cùng thường chỉ có thể bắt chước "nền trắng, bo tròn, bóng đổ". + +Đối với người mới, cách thực dụng hơn không phải là tự tổng hợp một đoạn dài, mà là trực tiếp dán **câu then chốt trong nguyên văn quy chuẩn** cho AI. + +Làm như vậy có hai lợi ích: + +- Bạn không cần tự "dịch" tư tưởng thiết kế trước +- AI dễ hiểu trang và nút theo định nghĩa chính thức hơn + +### 6.1 Ví dụ 1: Để AI tham khảo Apple thiết kế một trang cài đặt + +Tìm một câu nguyên văn Apple trước: + +> ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) + +Bạn có thể trực tiếp dán cho AI như thế này: + +```md +Tham khảo câu này từ Apple Human Interface Guidelines: +"Establish a clear visual hierarchy..." + +Giúp tôi thiết kế một trang cài đặt bảo mật tài khoản. +Yêu cầu cấp bậc trang rõ ràng, thông tin quan trọng đặt trước, phân nhóm ngăn nắp. +``` + +Điểm quan trọng của cách viết này là: bạn không cần tự giải thích quá nhiều, trực tiếp dán nguyên văn của Apple vào. + +### 6.2 Ví dụ 2: Để AI tham khảo Fluent thiết kế nút trang backend + +Tìm một câu nguyên văn Fluent trước: + +> ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +Bạn có thể trực tiếp dán cho AI như thế này: + +```md +Tham khảo câu này từ Fluent 2: +"Only use one primary button in a layout..." + +Giúp tôi thiết kế nút cho trang quản lý đội nhóm backend. +Nút thêm thành viên nổi bật nhất, xuất, lọc, thêm thao tác yếu hơn, nút xóa nổi bật riêng. +``` + +Câu này rất phù hợp cho người mới, vì nó trực tiếp nói cho AI: một khu vực không nên đặt quá nhiều nút chính. + +### 6.3 Ví dụ 3: Để AI đồng thời tham khảo quy chuẩn trang và quy chuẩn nút + +Bạn cũng có thể dán hai câu nguyên văn cùng lúc, để AI đồng thời tham khảo trang và nút: + +> Apple: ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) +> +> Fluent: ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +Rồi trực tiếp viết như thế này: + +```md +Tham khảo hai câu nguyên văn quy chuẩn thiết kế dưới đây: +Apple: "Establish a clear visual hierarchy..." +Fluent: "Only use one primary button in a layout..." + +Giúp tôi thiết kế một trang chi tiết dự án. +Trang bao gồm giới thiệu dự án, thành viên, hoạt động gần đây và lối vào cài đặt. +Cấp bậc trang rõ ràng hơn, chỉ giữ một nút chính, nút khác yếu hơn. +``` + +Cách này đặc biệt phù hợp cho người mới, vì bạn chỉ cần biết sao chép nguyên văn, rồi thêm hai câu yêu cầu của mình là đủ. + +## 7. Cách dùng AI tham khảo quy chuẩn nút để trực tiếp tạo thiết kế nút + +Nếu bạn chỉ muốn làm nút trước, cũng có thể trực tiếp dán nguyên văn quy chuẩn nút. + +Ví dụ định nghĩa nút của Atlassian rất ngắn: + +> ["A button triggers an event or action."](https://atlassian.design/components/button/) + +Bạn có thể hỏi AI như thế này: + +```md +Tham khảo câu này của Atlassian: +"A button triggers an event or action." + +Giúp tôi thiết kế một bộ phong cách nút cho trang backend. +Tôi cần có nút chính, nút phụ, nút xóa, tiện thể nói cho tôi biết dùng ở đâu tương ứng. +``` + +Loại prompt này đặc biệt phù hợp cho người mới, cơ bản là "dán nguyên văn + nói yêu cầu". + +## 8. Tổng kết + +Tham khảo quy chuẩn thiết kế UI để thiết kế trang và nút bấm, điều quan trọng nhất không phải "làm giống ai", mà là học được mấy điều sau: + +1. Dùng cấp bậc tổ chức trang, thay vì chất nội dung lên +2. Dùng phân cấp nút thể hiện mức độ ưu tiên thao tác, thay vì để tất cả nút đều tranh giành sự chú ý như nhau +3. Dùng định nghĩa, ranh giới và tiêu chuẩn phán đoán trong quy chuẩn thiết kế để dẫn dắt thiết kế +4. Khi để AI tham khảo quy chuẩn của người khác, tham khảo là "nguyên tắc và cấu trúc", chứ không phải chỉ tham khảo lớp da + +Khi bạn sử dụng quy chuẩn như thế này, những gì bạn tham khảo được không chỉ là một phong cách, mà là một cách tư duy thiết kế trưởng thành. + +--- + +## Tài liệu tham khảo + +Các liên kết dưới đây đều đến từ hệ thống thiết kế chính thức hoặc tài liệu chính thức: + +- Apple Human Interface Guidelines: [Overview](https://developer.apple.com/design/human-interface-guidelines/) +- Apple Human Interface Guidelines: [Menus](https://developer.apple.com/design/human-interface-guidelines/menus) +- Apple Human Interface Guidelines: [Alerts](https://developer.apple.com/design/human-interface-guidelines/alerts) +- Apple Human Interface Guidelines: [Buttons](https://developer.apple.com/design/human-interface-guidelines/buttons) +- Apple Archive: [How Menus Work](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/HowMenusWork.html) +- Apple Archive: [Managing Pop-Up Buttons and Pull-Down Lists](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) +- Material Design: [Buttons overview](https://m3.material.io/components/buttons/overview) +- Material Design: [Menus](https://m1.material.io/components/menus.html) +- Microsoft Fluent 2: [Start designing](https://fluent2.microsoft.design/get-started/design) +- Microsoft Fluent 2: [Menu usage](https://fluent2.microsoft.design/components/web/react/core/menu/usage) +- Microsoft Fluent 2: [Button usage](https://fluent2.microsoft.design/components/web/react/core/button/usage) +- Atlassian Design System: [Foundations](https://atlassian.design/foundations/) +- Atlassian Design System: [Button](https://atlassian.design/components/button/) diff --git a/docs/vi-vn/stage-2/frontend/ui-design/index.md b/docs/vi-vn/stage-2/frontend/ui-design/index.md new file mode 100644 index 0000000..cb7477f --- /dev/null +++ b/docs/vi-vn/stage-2/frontend/ui-design/index.md @@ -0,0 +1,3 @@ +# Xây dựng ứng dụng hiện đại đầu tiên - Thiết kế UI + +> Chương này đang được biên soạn, hãy mong chờ... diff --git a/docs/vi-vn/stage-2/index.md b/docs/vi-vn/stage-2/index.md index aeb1a63..1fc6f1d 100644 --- a/docs/vi-vn/stage-2/index.md +++ b/docs/vi-vn/stage-2/index.md @@ -1,126 +1,193 @@ # Phát triển Full-Stack -Chào mừng đến với giai đoạn **Phát triển Full-Stack**! Ở đây bạn sẽ đi sâu vào phát triển full-stack, thành thạo component hóa frontend, thiết kế cơ sở dữ liệu, phát triển API backend và triển khai. +Chào mừng đến với giai đoạn **Phát triển Full-Stack**! Ở đây bạn sẽ đi sâu vào phát triển full-stack, thành thạo component hóa frontend, thiết kế cơ sở dữ liệu, phát triển API backend và triển khai ứng dụng. ## Bạn sẽ học được gì ### Phát triển Frontend -Thành thạo phát triển frontend hiện đại và học cách sử dụng thư viện component và công cụ thiết kế: +Thành thạo phát triển frontend hiện đại, học cách sử dụng thư viện component và công cụ thiết kế: + + + + - -### Backend và Full-Stack +### Phát triển Backend Học thiết kế API, quản lý cơ sở dữ liệu và chiến lược triển khai ứng dụng: + - - - + + +### Bài tập lớn -### Bài tập +Các chương trước là học "linh kiện", bài tập lớn mới là học "cách lắp linh kiện thành một sản phẩm có thể chạy, demo và đưa lên mạng". + +Bạn nên làm theo thứ tự **Bài tập lớn 1 -> Bài tập lớn 2**: + +- **Bài tập lớn 1** đưa bạn chạy qua đường dẫn chính phổ biến nhất của SaaS hiện đại: đăng nhập, tạo, cơ sở dữ liệu, thanh toán, trang quản lý. +- **Bài tập lớn 2** đưa bạn vào kịch bản giống hệ thống doanh nghiệp hơn: quyền vai trò, ngân hàng đề, kỳ thi, lịch sử nộp bài, trang quản lý. + +```mermaid +flowchart LR + A["Trang và component frontend"] --> B["Cơ sở dữ liệu và API"] + B --> C["Bài tập lớn 1
SaaS tạo văn bản"] + C --> D["Thanh toán / Triển khai / Quản lý backend"] + D --> E["Bài tập lớn 2
Hệ thống thi trực tuyến"] + E --> F["Portfolio full-stack hoàn chỉnh"] +``` + +Nếu bạn chưa biết nên làm cái nào trước, có thể tham khảo bảng so sánh dưới đây: + +| Dự án | Bạn sẽ thực hành kỹ năng gì | Phù hợp nhất với ai | Sản phẩm bàn giao cuối cùng | +|------|------|------|------| +| Bài tập lớn 1: Trang web tạo văn bản | Cấu trúc trang SaaS, đăng nhập người dùng, tạo bằng AI, thanh toán Stripe, quản lý backend | Người lần đầu làm trang web thương mại hóa hoàn chỉnh | Một nguyên mẫu SaaS có thể đăng ký, tạo, thanh toán và quản lý | +| Bài tập lớn 2: Hệ thống thi và quản lý trực tuyến | Quyền vai trò, mô hình ngân hàng đề, quy trình thi, lịch sử nộp bài, chấm điểm và thống kê | Người muốn làm hoàn chỉnh một "hệ thống doanh nghiệp" | Một nền tảng thi có phía học sinh và phía quản lý | + +Dù làm bài nào, bài tập lớn đều nên chuẩn bị ít nhất 3 sản phẩm bàn giao: + +- Một kho lưu trữ dự án có thể chạy +- Một liên kết demo có thể truy cập +- Một README và một video demo -Củng cố kỹ năng phát triển full-stack của bạn thông qua các dự án thực hành: +Nếu bạn đã hoàn thành hai dự án chính ở trên, hoặc muốn làm portfolio theo hướng kỹ thuật của riêng mình, có thể tiếp tục chọn một đề tài từ các đề tài mở rộng dưới đây: + + + + + + + + + ### Mở rộng khả năng AI + - - ## Dành cho ai -- Nhà phát triển có một số nền tảng lập trình muốn học phát triển full-stack một cách có hệ thống -- NgườI học muốn chuyển đổi từ quản lý sản phẩm sang kỹ sư full-stack -- Nhà phát triển từ cơ bản đến trung cấp muốn thành thạo công cụ và quy trình làm việc phát triển hiện đại -- Doanh nhân muốn phát triển các sản phẩm hoàn chỉnh độc lập +- Nhà phát triển có nền tảng lập trình, muốn học phát triển full-stack một cách có hệ thống +- Người học muốn chuyển đổi từ quản lý sản phẩm sang kỹ sư full-stack +- Nhà phát triển từ cơ bản đến trung cấp muốn thành thạo công cụ và quy trình phát triển hiện đại +- Doanh nhân muốn phát triển độc lập sản phẩm hoàn chỉnh ## Điều kiện tiên quyết -- Hoàn thành giai đoạn "NgườI mới và nguyên mẫu sản phẩm", hoặc có kiến thức cơ bản tương đương +- Hoàn thành giai đoạn "Người mới và nguyên mẫu sản phẩm", hoặc có kiến thức cơ bản tương đương - Hiểu các khái niệm cơ bản về HTML/CSS/JavaScript - Có kiến thức sơ bộ về các công cụ lập trình AI -Sẵn sàng đi sâu vào phát triển full-stack? Nhấp vào điều hướng bên trái để bắt đầu học! +Sẵn sàng đi sâu vào phát triển full-stack chưa? Nhấp vào điều hướng bên trái để bắt đầu học! diff --git a/docs/zh-tw/stage-2/ai-capabilities/dify-knowledge-base/index.md b/docs/zh-tw/stage-2/ai-capabilities/dify-knowledge-base/index.md new file mode 100644 index 0000000..8fb70fa --- /dev/null +++ b/docs/zh-tw/stage-2/ai-capabilities/dify-knowledge-base/index.md @@ -0,0 +1,1044 @@ +# Dify 入門與知識庫集成 + +# 回顧上節課 + +在前幾節課中,我們分組學習了 AI 程式設計、提示詞工程以及 AI 圖像生成的基礎知識。這些內容幫助我們初步瞭解了不同大語言模型(LLM,Large Language Model)或生成式模型的邊界和能力。 + +為了幫助你回顧上節課的內容,下面有幾個小問題可以思考: + +1. 什麼是 AI 程式設計?如何使用 AI 程式設計工具(例如 [z.ai](http://z.ai))來創建一個網頁? +2. 什麼是大語言模型?什麼是提示詞工程和上下文工程?你該如何編寫一個複雜的提示詞? +3. 對於文本、AI Coding、圖像生成的三個不同方向,你認為模型能力的強弱分別體現在什麼地方? +4. 什麼是 API?如何使用 [z.ai](http://z.ai) 接入第三方 API ? + +如果你對其中任何一個問題還感到疑惑,可以回看上節課的文檔,也可以直接在微信群裡提問。 + +在這節課中,我們將從簡單的 AI 文字圖片工具,進入更接近公司業務落地的工作流搭建平臺。從對話機器人走向 AI 智能體、AI 工作流,並基於 API 把它變成可交互的“智能”機器人頁面。 + +在操作過程中,如果遇到難以理解的步驟,請不要擔心,推薦你隨時對當前所在的操作頁面進行截圖,發送給大模型進行詢問;當前大模型已能夠解答大部分常見問題。 + +如果提問後仍無法解決,不妨大膽嘗試操作;不必害怕出錯,每一次嘗試都是學習和進步的機會。隨著實踐次數的增加,你會越來越熟練,操作也會越來越得心應手! + +# 本節課你將學到 + +1. 為什麼需要從聊天機器人走向智能體和 Workflow 編排。 +2. 什麼是智能體與工作流開發平臺,如何把 AI 的能力 SOP 化與可編排化。 +3. 什麼是 Dify,如何用這個面向 LLM 應用的開源平臺快速搭建應用,尤其是知識庫問答機器人。 +4. RAG 的實現方法與價值,為什麼需要檢索增強生成? +5. 如何從 0 到 1 學會使用 Dify 和 AI IDE Trae (`Extra Knowledge 4 - What is AI IDE and Trae`),包括搭建 智能體、工作流,並基於 Dify API 製作前端對話機器人網頁程序。 + +- Dify 的基本使用原理與智能體、工作流製作方法,API 調用方法。 +- AI IDE 的使用方法,如何使用 AI IDE 程式設計。 +- 一個可進行對話的前端網頁智能體程序。 + +# 1. 從對話到智能體 + +在上一階段,我們學會了如何用提示詞讓大模型扮演角色、生成文本或編寫簡單程式碼。但如果你仔細思考,會發現一個問題,聊天機器人本身並不能做事。 + +它能回答怎麼查訂單?,卻不能真的去資料庫裡查對應的數字;它能描述一封週報應該包含什麼,卻無法自動彙總你的項目資料併發送郵件。這種“只說不做”的侷限,使得純對話式 AI 難以真正融入業務流程。 + +要讓 AI 從聊天夥伴升級為數字員工,我們需要賦予它三項核心能力: + +1. 專屬知識——讓它能夠通讀並瞭解你的產品文檔、客戶資料、內部制度; +2. 工具調用(或者叫插件)——讓它能操作資料庫、調用 API; +3. 結構化執行——讓它按預設邏輯一步步完成任務,而非自由發揮。 + +這就是 AI 智能體(AI Agent)的雛形:一個具備目標、知識、工具和執行路徑的自動化單元。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image1.png) + +> 注意:當前業界所說的簡單版本的“智能體”,大多指基於 LLM + 工具 + 知識庫組合而成的增強型應用,並非所謂能夠自主規劃的智能體。簡單的智能體雖不具備真正的推理與長期規劃能力,但已足以支撐大量企業級自動化場景。我們將會在之後的章節詳細介紹真正的具備自主規劃和行動能力的智能體。 + +## 1.1 最簡單的智能體:基於知識庫的問答機器人 + +在明確智能體應具備的多項核心能力後,一個值得思考的問題隨之而來:能否僅通過實現其中某一項最簡單的功能,就構建出一個真正可用的基礎智能體? 答案是肯定的。 + +事實上,在大量實際業務場景中,用戶的核心訴求並非讓 AI 自動執行復雜操作(如調用 API 或跨系統協調任務),而是希望它能基於企業自身的專屬資料,提供精準、可靠的問答支持。這恰好對應智能體三大核心能力中的第一項,專屬知識服務能力。因此,我們得以引出智能體最簡單、也最廣泛應用的形態:基於知識庫的問答機器人。 + +雖然它尚未具備工具調用或自主規劃能力,但其關鍵突破在於:讓大模型的回答不再憑空生成,而是有據可依。如何實現?關鍵就在於解決核心挑戰:企業內置大量文檔知識,當存在千上萬頁文檔時,模型如何在每一輪對話中快速找到與當前問題最相關的內容? + +此時的一個解決方案是:檢索增強生成(Retrieval-Augmented Generation, RAG)。 + +RAG 的基本思路是:在用戶提問時,系統首先從企業知識庫中檢索出與問題語義最相關的若干文本片段(例如產品手冊中的某一段、HR制度中的某一條款),然後將這些片段作為上下文“注入”到大模型的輸入中,引導它基於真實資料生成回答。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image2.png) + +圖片來源:[https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag](https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag) + +這樣一來,模型的回答不再是依賴其訓練資料中的泛化知識,而是錨定在企業提供的權威資訊之上。RAG 的目標,正是通過這種外部知識的動態注入,顯著提升回答的真實性、準確性和一致性——甚至可以讓回答“符合人設”,比如以客服口徑或技術文檔風格作答。 + +在實際業務中,這項技術尤為重要,因為大模型常常會產生“幻覺”。例如,若你以 CFO 或諮詢顧問的身份詢問某個時間段的具體資料,模型很可能編造日期和事件。引入 RAG 後,回答的可控性與可靠性將得到顯著提升。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image3.png) + +圖片來源:[https://www.databricks.com/glossary/retrieval-augmented-generation-rag](https://www.databricks.com/glossary/retrieval-augmented-generation-rag) + +在本節課的實操環節中,我們將使用流行的 AI 工作流平臺 Dify,動手搭建一個基於知識庫的問答機器人。你可以輕鬆將各種類型的專屬資料,如產品手冊、公司制度、項目文檔、研究論文、知識庫文章,甚至是個人筆記集構建為知識庫。 + +完成搭建後,你可以嘗試提出各類問題來檢驗它的能力,例如: + +- “我們產品A的最新版本有哪些主要功能升級?” +- “請根據員工手冊,說明今年的年假制度是如何規定的?” +- “在XX項目中,我們遇到的技術挑戰‘XXX’是如何解決的?” +- “這篇論文中提到的核心研究方法是什麼?” + +你將親身感受 RAG 技術如何將靜態分散的文檔資料,轉化為一個精準的智能知識庫,為各種場景提供高精度問答支持。 + +## 1.2 從對話智能體到工作流 + +然而,即使是加入了知識庫甚至是插件調用能力的“增強型智能體”,在面對更復雜的業務流程時仍顯不足。 + +試想這樣一個用戶請求:“我們新上線的 SaaS 產品最近有哪些功能更新?能幫我整理成一份給客戶的簡報嗎?” + +這個請求看似簡單,背後卻需要多個協同步驟:首先從內部產品文檔或 Notion 知識庫中檢索最近一個月的功能發佈記錄;然後過濾出面向客戶的關鍵特性;接著調用大模型將技術描述轉化為客戶友好的語言;最後通過將生成內容推送至市場團隊的郵箱,或保存到 Google Docs 模板中。 + +如果僅靠一個大語言模型自由推理,先不說是否能夠一次對話實現所有過程,就算能,其中也很容易遺漏關鍵資訊、混淆內部術語與客戶語言,或無法結構化輸出。更重要的是,企業需要的是可審計、可複用、可監控的標準化執行路徑,而不是每次依賴模型的臨時發揮,可監控可復現對企業而言非常重要,非預期的結果很可能會帶來預期外的嚴重損失。 + +這就引出了更高階的 AI 應用範式:AI 工作流(AI Workflow)。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image4.png) + +工作流是指將一個複雜任務拆解為多個有序、可配置、可自動執行的子步驟,並通過可視化或程式碼方式編排它們之間的邏輯關係,如條件判斷、循環或並行執行。將 AI 能力 SOP 化(即標準化操作流程),意味著把如何用 AI 完成某項任務的經驗固化為可重複使用的模板。 + +這種做法帶來了多重價值:非技術人員(如產品經理或運營)可以通過拖拽組件快速搭建 AI 應用;開發者可以將 RAG 檢索、LLM 調用、API 工具等封裝為標準節點,在不同業務場景中複用;整個流程還可被完整追蹤、調試和持續優化,滿足企業對穩定性與合規性的要求。 + +AI 工作流的使用人群非常廣泛。產品經理無需寫程式碼,即可設計完整的用戶交互路徑;運營人員能快速搭建客服機器人、內容生成器或通知系統;開發者和算法工程師則可將核心能力模塊化,供前端調用;創業者或獨立開發者也能以極低成本驗證 AI 產品的 MVP,幾天內上線一個包含資料查詢、內容生成與動作執行的完整原型。 + +此外,值得注意的是,AI 工作流通常可用一種中間表示(Intermediate Representation)來描述。不同工作流平臺的具體表達方式雖有差異,但大多采用結構化文件(如 JSON、YAML 等)來定義節點類型、輸入輸出及執行邏輯,其結構類似下圖所示: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image5.png) + +簡言之,如果說智能體讓 AI 從會聊天走向能做事,那麼工作流則讓 AI 從偶爾做成一件事邁向“穩定、可靠、規模化地完成一類事。在接下來的實踐中,我們還將藉助 Dify 平臺,上手並親手構建完整的 AI 工作流,體驗從想法到可運行應用的完整過程。 + +## 1.3 常用智能體 / 工作流平臺 + +隨著生成式 AI 技術的飛速發展,為幫助開發者與業務人員快速構建智能體與自動化流程,避免陷入程式設計的複雜細節,一批低程式碼甚至無程式碼的智能體及工作流平臺應運而生。 + +首先需要明確的是,低程式碼平臺是指通過可視化拖拽組件、預置業務邏輯模板、圖形化配置規則等方式,顯著減少手動編碼工作量的開發工具。其核心在於以可視化配置,節點式拖動變成的方式替代直接寫程式碼的方式,既能讓具備一定技術能力的開發者從重複勞動中解放出來,也能讓熟悉業務邏輯的非技術人員參與到應用搭建中。本質上,它是在開發效率與場景靈活性之間架起一座平衡的橋樑。 + +這類低程式碼/無程式碼智能體平臺的突出價值,正是大幅降低 AI 應用的開發門檻。以往需要團隊協作數週——從需求梳理、程式碼開發到測試部署——才能完成的 AI 智能體(如客服問答機器人、資料處理助手),現在藉助平臺提供的可視化工具,可將“從創意到上線”的週期縮短至數小時。 + +目前市面上主流的低程式碼 AI 工作流平臺包括: + +| 平臺 | 特點 | 適用場景 | +| --------------------------------------------- | -------------------------------------------------- | -------------------------------------- | +| Dify | 開源、支持知識庫 RAG、LLM 編排、API 輸出,中文友好 | 企業知識庫問答、定製化 Agent、API 服務 | +| Coze(字節跳動) | 國內可用、集成抖音/飛書生態、插件豐富 | 社交機器人、國內小程序集成 | +| n8n | 通用自動化工具,支持 AI 節點,強調 API 編排 | 跨系統資料同步、AI + 傳統 SaaS 自動化 | +| 百度千帆 AppBuilder / 阿里百鍊 / 騰訊 HunYuan | 大廠雲原生方案,集成自家模型 | 企業級部署、合規要求高場景 | + +目前市面上的低程式碼 AI 工作流平臺選擇豐富。儘管 AWS、Azure、阿里雲等主流雲廠商均推出了相應的 AI 工作流解決方案,但 Dify、Coze 和 n8n 憑藉以下三大核心優勢,成為當前應用最廣泛的代表: + +1. 極致易用性。平臺採用可視化拖拽式界面設計,用戶無需深入理解底層技術,即可快速上手。 +2. 高靈活性。支持自定義組件與擴展 API 接口,既能適應教學演示、MVP(最小可行產品)驗證等輕量場景,也能滿足中小型團隊的敏捷迭代需求。 +3. 成熟生態。不僅官方文檔詳盡、響應及時,還擁有活躍的用戶社區,便於快速獲取來自不同用戶的預設方案。 + +這三大平臺均支持將搭建好的 AI 智能體以標準化 API 接口的形式輸出,可無縫集成至前端 Web 應用、企業內部 ERP 系統或移動端 APP 中,進一步降低了 AI 能力落地的技術門檻。 + +### 1.3.1 Dify:企業級LLMOps與應用生命週期管理平臺 + +Dify 定位是LLM應用開發與運營平臺,致力於提供AI應用從構思、部署到優化的全生命週期管理。其核心是一個低程式碼平臺,旨在幫助開發者和非技術背景的創新者快速構建生產級AI應用。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image6.png) + +在功能上,Dify覆蓋了可視化工作流編排、智能體構建、知識庫管理、多模型支持等功能。平臺允許通過拖拽節點設計複雜任務流程,並支持創建基於意圖的Agent。其知識庫功能突出,能處理多種格式文檔並進行高效的向量檢索。同時,Dify兼容支持包括GPT、Claude及眾多開源模型在內的多種LLM,構建的應用可一鍵發佈為標準API便於集成。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image7.png) + +技術架構方面,Dify以開源和可私有化部署為特色,強調靈活性、擴展性及企業級合規。目標用戶包括開發者團隊和業務創新者,典型應用場景涵蓋企業知識庫與智能客服、內容創作自動化、垂直領域AI助手以及企業AI中臺。 + +### 1.3.2 Coze(字節跳動):零程式碼AI智能體構建的普及者 + +Coze是字節跳動推出的AI智能體開發平臺,以極致易用性為核心,讓無程式設計經驗的用戶也能輕鬆創建、調試併發布功能豐富的AI聊天機器人。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image8.png) + +其核心是將Bot構建簡化為搭積木式操作。用戶可通過界面輕鬆配置角色與知識庫,並利用豐富的內置插件庫為Bot添加新聞、旅遊、圖像生成等多類外部能力。創建好的Bot可一鍵快速發佈至豆包、飛書、微信公眾號等多個平臺。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image9.png) + +技術架構完全服務於低門檻使用,後端集成字節自有模型並封裝複雜流程,強調多模態理解與實時響應。作為一個主要以雲服務形式提供的平臺,其私有化部署能力相對有限。典型應用場景包括個人助理與娛樂Bot、智能客服與問答系統、在線教育助手以及快速原型驗證。 + +### 1.3.2 n8n:可程式設計的後端工作流自動化引擎 + +n8n是一個通用的可程式設計工作流自動化平臺,其核心定位是連接各類應用、資料庫與API,實現資料流動與任務自動化執行。 + +它通過龐大的集成節點庫支持數百種SaaS服務、資料庫及協議,並採用可視化與程式碼結合的方式:用戶可在畫布拖拽節點,同時注入JavaScript或Python程式碼編寫自定義邏輯。n8n擅長處理後端資料密集型任務,如資料同步、ETL流程與API編排。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image10.png) + +關鍵技術特性是“源碼可見”和“可自託管”,用戶可將其私有化部署以完全掌控資料與環境,這使其對資料安全要求高的行業極具吸引力。其主要目標用戶是開發者、技術運營及資料分析師。n8n 最大的優勢,在於擁有極其強大的社區生態。網路上擁有隨處可見豐富的 n8n 分享影片,為用戶提供了便捷的學習參考與經驗借鑑;同時,它支持連接 YouTube、Instagram 等全球眾多不同生態平臺,能夠幫助用戶輕鬆打破跨平臺資料與服務的壁壘,實現多生態流程的自動化流轉。 + +### 1.3.3 其他工作流平臺 + +除了上述的幾個最知名的平臺,中國國內的主要科技廠商也相繼推出了各自的一體化AI開發平臺,例如:百度千帆 AppBuilder 提供從模型選型、RAG構建到智能體發佈的全流程支持,深度集成文心大模型;阿里雲百鍊基於通義千問系列模型,注重企業級安全與私有化部署能力;騰訊雲 TI 平臺 則聚焦於金融、醫療等行業場景,提供豐富的預置解決方案模板。這類平臺通常與各自雲生態深度融合,適合已處於相應技術體系內的企業選用。 + +然而,在通用型、開放性與社區生態方面,Dify 與 Coze 仍憑藉其突出的易用性、廣泛的模型支持以及活躍的開發者社區,成為當前更受廣泛採納的選擇。 + +儘管各平臺在定位與生態上各有側重,其核心邏輯均是通過可視化方式編排與連接不同的能力模塊。因此,掌握其中任意一種平臺的設計思路與操作方法,即具備快速遷移到其他類似工具的基礎。在接下來的實踐中,我們將以 Dify 為例進行具體講解。 + +# 2. 深入淺出 Dify + +## 2.1 什麼是 Dify + +我們在之前已經瞭解了基礎的 Dify 的資訊介紹,對於更詳細的資訊,你可以通過 [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps) 訪問 Dify 平臺,如果想了解更多資訊,可以訪問官網 https://dify.ai。 + +Dify 是一個用於開發 LLM 應用的開源平臺。它提供了直觀的界面,將 Agent 工作流、RAG 流水線、工具能力、模型管理、可觀測性等功能結合在一起,幫助你快速地從原型走向生產環境。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image11.png) + +你可以在 Dify 中使用大語言模型和各種功能不同的工具來搭建“工作流”。所謂工作流,就是把原本需要你手動一步步完成的操作——例如資料檢索、大模型調用、網頁搜索、結果過濾、格式整理等——按照業務邏輯串聯起來,變成一個自動化、可複用的流程。如果沒有工作流,每次你都需要把同樣的內容複製粘貼給大模型,非常低效、容易出錯,也難以在真實業務中複用。 + +搭建一個工作流,就像在拼搭積木或拼圖。你把“大語言模型節點”(負責理解和生成)、各類“工具節點”(負責執行具體動作,例如查資料庫、發郵件、翻譯文本等)、以及“資料節點”(負責讀取、存儲資訊)像積木一樣連接起來。它們會按照你預設的邏輯自動協同工作,而不需要你每次都手動操作。你也可以把它理解成一種“低程式碼程序”:你只需要通過拖拽的方式,配置輸入和輸出的路徑,就可以實現比較複雜的業務邏輯。 + +舉個例子,如果你是一個亞馬遜或抖音電商店鋪的老闆,想要搭建一個 AI 客服系統,可以參考下圖的結構設計一個工作流: + +1. 觸發節點(類似 START):接收用戶的諮詢問題,例如“這個商品的質保期有多長?”。 +2. 問題分類節點(類似 QUESTION CLASSIFIER):使用一個模型(例如 GPT)對用戶問題進行分類,判斷這是售後(比如質保)、使用方法,還是其他類型的問題。 +3. 知識檢索節點(類似 KNOWLEDGE RETRIEVAL):根據分類結果,自動訪問相應的知識庫。如果是關於“質保”的售後問題,就從售後 SOP 知識庫中檢索與“質保”相關的精確資訊。 +4. 大語言模型節點(LLM Node):將用戶問題和檢索到的知識庫內容一起發送給大語言模型(例如 GPT),讓它生成一段對用戶友好的回覆(避免太生硬的技術語氣)。 +5. 條件節點:檢查大模型生成的回答中是否包含清晰的質保時間(例如“1 年”、“3 年”),如果有則繼續下一步,如果沒有則讓它回覆“請提供產品型號”。 +6. 輸出節點(類似 ANSWER):將最終答案返回給用戶,並自動把本次諮詢記錄到表格中。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image12.png) + +在整個過程中,你不需要手動去翻知識庫、反覆調整模型的回答、或單獨記錄資料——工作流會把這些步驟“連起來自動跑”。並且它非常靈活:例如,如果你之後想加一個新規則“當用戶問質保範圍時,調用另一個知識庫”,只需要在工作流中多加一個條件節點,而無需重構整個系統。 + +這是一個比較簡單的工作流示例,但要完全掌握這些能力,對現在的你來說可能還有點難。因此在本節課中,我們從更加基礎的知識庫智能體開始,後面再逐步學習更復雜的工作流技巧。 + +### 2.1.1 部署屬於自己的 Dify(可選) + +本部分內容原本安排在後續課程中詳細介紹,但考慮到當前部分學習者可能因網路限制暫時無法訪問 Dify 官方網站或雲端服務,我們決定提前提供這一可選的學習路徑,幫助你順利推進課程進度。 + +你需要參考該教程入門 web 部署平臺的基本使用方式:[如何部署 Web 應用](/zh-cn/stage-2/backend/zeabur-deployment/) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image13.png) + +你需要學習如何在 Zeabur 上部署一個自己的 Dify,部署後進入到對應鏈接註冊並登錄後繼續跟隨下列教程操作即可。 + +注意,不同版本的 Dify 的操作方面和前端界面可能有些許差別,但總體上差別不大,當你發現不同的時候不要慌張,找到類似的接口和入口進行操作即可。 + +## 2.2 創建第一個 Dify Chatbot 應用 + +訪問 Dify 首頁 [https://cloud.dify.ai/apps](https://cloud.dify.ai/apps) 並註冊和登錄後,選擇 Studio,你會看到如下界面: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image14.png) + +在左側找到 `CREATE APP` 區塊,點擊 `Create from Blank`。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image15.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image16.png) + +在 APP Type 中找到 Chatbot(如果一開始沒看到,可以點擊“查看更多類型”的按鈕,然後在完整列表中找到)。選擇 Chatbot 之後,在下方輸入應用的名稱和描述,最後點擊創建。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image17.png) + +創建完成後,你會看到類似下面的界面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image18.png) + +中間區域的 “INSTRUCTIONS” 指的是內置指令,你可以把它理解為默認提示詞或系統提示詞。 + +中間偏下有一個 “Knowledge” 區域,這就是知識庫區域——我們稍後會把自己的知識庫上傳到這裡。 + +右側是調試窗口,你可以在調整提示詞後與 Agent 進行對話,實時查看效果。 + +你可以在 INSTRUCTIONS 區域自由輸入角色提示詞,觀察對話效果;也可以點擊 Generate,讓大模型自動幫你生成提示詞。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image19.png) + +注意右上角會出現許多不同模型的選項,這意味著你可以點擊切換不同的對話模型,從而比較它們在語氣、邏輯推理、長文本處理等方面的差異,尋找最適合你需求的模型。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image20.png) + +## 2.3 支持自定義模型供應商 + +為充分發揮 Dify 的靈活性,考慮到不同地區訪問模型的難度,為滿足特定業務需求、成本控制或資料隱私要求,我們常常需要接入自定義模型。Dify 支持配置三類核心模型:大語言模型(LLM)、Embedding 模型和 Rerank 模型。本部分內容將逐步指導你完成這些自定義配置。 + +Dify 能夠靈活接入來自 OpenAI、Azure、Anthropic 等主流服務商的模型,同時也全面兼容任何符合 OpenAI API 接口規範的自託管模型或第三方模型。你可以通過安裝內置的 OpenAI Compatible 插件以及對各大模型平臺定製的插件實現這一操作。 + +詳細步驟參考如下,首先我們需要安裝對應的插件: + +1. 我們需要安裝 `OpenAI-API-compatible` 及 `SiliconFlow` 插件獲得對絕大部分大模型和 Embedding 模型的支持,其中前者是對 OpenAI 兼容接口的支持,後者是一個部署了當前絕大部分常見、好用的開源模型的服務站。你可以訪問下列網頁進行安裝: + 1. https://marketplace.dify.ai/plugins/langgenius/openai_api_compatible + 2. https://marketplace.dify.ai/plugins/langgenius/siliconflow +2. 如果你是自己部署的 Dify,你可以在對應系統設置界面進入插件市場進行操作 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image21.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image22.png) + +進入插件市場後,搜索對應的插件名稱即可。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image23.png) + +3. 安裝結束後,我們能夠配置支持新的模型供應商,在設置裡的模型提供商部分,我們可以看到目前支持的所有模型商: + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image24.png) +4. 在開始使用前,需要先完成模型的配置。對於 OpenAI-API-compatible 插件,你可以點擊 “Add Model” 來添加並配置任意模型。你可以在 “Model Type” 中選擇該模型是LLM還是 Embedding,你需要確保模型的類型被正確配置。 + 你需要寫入具體的模型名字、模型 endpoint URL 以及 API Key 才能確保模型啟用,如果你初步覺得配置該參數麻煩,你可以直接跳到後者的 SiliconFLow 平臺的 Key 配置,或者安裝 OpenRouter 等第三方服務商插件進行簡單的模型支持配置。(確保服務商內有剩餘可使用額度) + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image25.png) + + 對於 `SiliconFlow` 插件,只需要點擊 Setup 配置 key 後即可使用 Embedding 和 Rerank 模型進行測試,你可以點擊 Get you API Key from SiliconFlow 獲得鑑權密鑰。 + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image26.png) + +5. 配置完成後,你可以點擊模型列表查看當前支持多少模型,此時已經完成了基礎模型的全部配置。 + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image27.png) + + 其中支持了絕大部分常見的 Embedding 與 Rerank 模型: + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image28.png) + + 此時如果你想要修改 Dify 默認使用模型的配置,你還可以點擊 System Model Settings 按鈕修改默認的所有模型。 + + ![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image29.png) + +## 2.4 創建第一個 Dify 知識庫 + +到這裡,我們已經完成了最簡單的 Agent 創建,但它還缺少一個知識庫。現在,請點擊頂部菜單中的 `Knowledge`,進入知識庫創建頁面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image30.png) + +然後點擊左側的 `Create Knowledge`,創建你的第一個知識庫。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image31.png) + +在這個界面中,你可以上傳多種類型的文件(例如 pdf、txt 等)來構建知識庫。可以上傳很長的文本,或者把維基百科上的內容複製下來保存成 txt 文件進行上傳。本例中,我們會上傳一份關於 Elon Musk 的維基百科 txt 文件。 + +點擊 Next 後,你會進入 Knowledge Base Settings(知識庫設置)頁面。這裡選項比較多,我們一步一步來看。 + +首先在 **General** 設置中,你可以把這裡理解成“文本切分規則”的設置區域。因為我們需要把很長的文本切分成小塊,所以必須先定義切分規則。在入門階段,你只需要關注 **maximum chunk length(最大切分長度)** 。可以嘗試設置為 512、2048 或 4096,然後點擊 **Preview Chunk** 預覽不同設置下的效果。 + +你也可以調整 **Chunk overlap(切片重疊)** 選項。它決定相鄰片段之間是否會保留一部分重疊內容。適當的重疊有助於避免重要資訊被拆到不同片段而難以理解。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image32.png) + +在設置中還有一個選項叫做 **Chunk using Q&A format in English** 。啟用後,系統會使用大語言模型,將知識庫的一部分內容轉換成問答形式來存儲,這在某些場景下可以顯著提升檢索效果。 + +在真實業務中,根據場景選擇合適的切分策略,能夠更好地優化檢索結果,保證查詢能夠返回你期望的資訊。 + +繼續向下滾動頁面,你會看到和 Embedding 模型相關的設置。 + +簡單解釋一下:Embedding 模型的核心功能,是把非結構化資料(例如文本、圖片等)轉換成計算機能夠理解的“數字向量”(Embedding 向量)。通過這種轉換,模型能夠快速計算不同資料之間的相似度,從而實現語義相近內容的匹配,比如根據用戶輸入的一句話,找到語義最接近的文檔、圖片或商品。 + +Embedding 模型的選擇會顯著影響最終的檢索效果(例如匹配準確度、響應速度等)。在這裡,我們推薦優先使用 Qwen 0.6B 的 Embedding 模型,你也可以切換到 4B 或 8B 版本,直觀對比不同參數規模下檢索效果的差異。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image33.png) + +在此處,你還會看到另一個模型設置叫做 **Rerank model** ,默認值是 **Jina-rerank-m0** 。(如果你非校園內的學生,此時你可能會看到 Rerank 模型缺失的報錯,你需要在模型處配置 rerank 模型才能在此處啟用使用) + +Rerank 模型的主要作用,是對“初步篩選出的候選結果”進行二次、更精細的排序,讓和用戶需求最匹配的結果排在更靠前的位置,從而顯著提升最終結果的相關性和用戶體驗。 + +簡單理解:Rerank 模型就是用來解決“初次篩選不夠精細”的問題。例如搜索引擎可能先用較簡單的規則檢索出 1000 個潛在相關網頁,再通過 Rerank 模型,從中挑出最相關的前 10 個展示在第一頁。 + +推薦系統同理:它可能首先找出 500 個“可能適合你”的商品,再通過 Rerank 模型排序,讓你最可能購買的商品排在列表頂部。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image34.png) + +當所有設置完成後,點擊 **Save & Process** ,系統就會進入知識庫向量化階段。在這一階段,Embedding 模型會把切分後的文本轉換為向量表示。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image35.png) + +處理完成後,點擊 **Go to document** ,可以查看已經處理完畢並存儲好的知識庫內容。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image36.png) + +直接點擊知識庫名稱,可以查看每個切片的具體內容。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image37.png) + +在這裡,你可以對任意不合適的文本片段進行精確的編輯或刪除操作。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image38.png) + +在左側邊欄中,選擇 **Retrieval Testing** 可以對知識庫進行召回測試,檢查檢索是否正常工作。每次測試會返回若干相似度最高的切片。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image39.png) + +如果你希望看到更多的切片結果,需要點擊 `VECTOR SEARCH` 設置: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image40.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image41.png) + +Top K 指的是向量檢索時,返回與查詢向量最相似的前 K 個文本切片數量。當前設置為 3,表示會返回相似度最高的 3 段文本。 + +Score Threshold 則是一個“得分閾值”:只有相似度得分大於或等於該閾值(示例中為 0.5)的文本片段才會被返回。這樣可以過濾掉相關度較低的內容,讓結果更加準確。 + +現在知識庫部分就全部準備好了。接下來,點擊頂部菜單欄中的 “studio”,找到剛才創建的智能體,為它接入我們已經配置好的知識庫。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image42.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image43.png) + +此時,在每一輪對話中,你都可以在回答中看到被命中的知識庫來源。點擊對應條目即可查看檢索到的具體文本片段。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image44.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image45.png) + +## 2.5 更多 DIfy 常見操作 + +在掌握基礎 Chatbot 和知識庫搭建的基礎內容後,我們可以深入瞭解更多有關 Dify 的使用方式。 + +### 2.5.1 工作流的導入與導出 + +還記得之前提到的工作流的中間表示法嗎?Dify 支持通過 DSL(Domain Specific Language) 格式導入和導出工作流。DSL 是一種基於 JSON 的標準化描述方式,能夠完整保留工作流的節點結構、連接關係和配置參數。你可以很容易導入和導出 DSL 文件,分享工作流給其他人使用,或者導入別人的工作流進行參考。具體而言,我們能夠容易在工作臺頁面看到工作流的導入按鈕: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image46.png) + +而對於工作流的導出,我們只需要點擊單個工作流塊的右下角即可找到導出按鈕: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image47.png) + +通過使用 DSL 文件,你可以輕鬆地在不同 Dify 實例之間遷移或共享複雜的工作流設計。 + +### 2.5.2 查看更多 Dify 項目 + +如果你覺得自己搭建的工作流或者智能體過於簡單,Dify平臺提供了豐富的示例項目,幫助你快速瞭解如何構建複雜應用。這些示例項目涵蓋了多種業務場景。你可以點擊 Explora 查看別人構建的工作流進行學習。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image48.png) + +## 2.6 創建第一個 Dify Workflow 應用 + +完成了 DIfy 的對話智能體構建入門,我們繼續查看如何構建更復雜的 Dify 業務工作流。工作流是Dify將複雜業務邏輯可視化的核心方式,通過它你可以像搭積木一樣構建智能流程。你能夠完整體會資訊如何在不同節點間流轉,判斷邏輯如何部署,人工干預點設置在哪裡,以及最終如何交付一個完整的業務結果。 + +你可以選擇從空白處創建,或者直接從模板處創建,此處演示如何從空白處創建工作流: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image49.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image50.png) + +在這裡我們會看見兩個選擇,分別是 Chatflow 與 Workflow,這兩者該如何選擇呢?關鍵是你需要理解你所要構建的,其核心是持續對話,還是任務流程。 + +Chatflow 專為對話而設計。它模擬一個具有記憶和上下文理解能力的對話者,非常適合需要多輪交互、狀態維持的場景。例如在客服諮詢中,它能連貫地理解用戶的後續追問,如同一位耐心的服務人員。其流式輸出的特性也讓交互過程更為自然。簡而言之,當你需要構建一個能“交談”的智能體時,應選擇 Chatflow。 + +Workflow 則專注於流程的自動化執行。它像一條預設的流水線,擅長處理一次性輸入、多步驟處理、併產生確定性輸出的任務。例如,每日定時生成資料報表、批量處理文件或調用系列API。這類任務通常由事件觸發,無需與人實時互動。因此,當你需要實現“自動化”任務時,Workflow 是更合適的選擇。 + +為避免選型錯誤帶來的效率低下,你可以通過四個關鍵問題來審視你的任務需求: + +1. 任務過程是否需要依賴多次的用戶輸入與調整? +2. 結果的呈現是否需要分步驟、流式地進行? +3. 處理邏輯是否嚴重依賴於之前的交互歷史? +4. 任務是否由事件觸發,且輸入輸出多為一次性完成? + +如果前三個問題的答案為“是”,那麼 Chatflow 是理想選擇,典型場景包括智能客服、教育輔導、創意協作等。如果第四個問題特徵顯著,則應選用 Workflow,它更適用於資料清洗、報表生成、批量處理等自動化場景。 + +此處我們選擇 Chatflow 作為案例進行介紹,點擊 Chatflow 後進入到操作檯界面: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image51.png) + +我們來簡單介紹工作流界面的頁面。其中整個界面的核心是中央的編輯畫布,你將以可視化方式在這裡構建應用邏輯。如圖所示,一個基礎的工作流通常始於 START 節點(用於接收輸入),經由連線將資料傳遞至 LLM 節點進行處理,最終通過 ANSWER 節點輸出結果。每個節點代表一個功能模塊,而連線則決定了任務執行的順序。 + +環繞畫布的是完整的操作與管理功能區。界面頂部提供了全局控制選項,包括測試工作流的 Preview 按鈕和用於上線的 Publish 按鈕。畫布角落則設有縮放、撤銷等視圖控制工具,便於精細調整。 + +左側面板集中了應用的管理功能。你當前所在的 Orchestrate 選項卡用於流程編排;構建完成後,可通過 API Access 獲取集成憑證;Logs & Annotations 記錄了每次執行的詳細蹤跡,便於調試;而 Monitoring 則為你提供應用運行時的性能與狀態監控。 + +你可以簡單在該對話工作流 LLM 節點的 SYSTEM 中輸入一些提示詞內容,點擊 Preview 後嘗試運行這個工作流,查看修改 SYSTEM 提示詞後整個工作流確實按照預期在變化。 + +### 2.6.1 常見節點介紹 + +Dify 中提供了多種節點,你可以先了解每個節點的基本功能。具體使用時,建議親手嘗試,或參考他人創建的工作流模板,也可以截圖並向大模型詢問該節點的用法、所需參數等。推薦直接在現有模板中替換不同節點,通過他人的使用方式來推測節點的最佳實踐。 + +在畫布右鍵點擊“Add Node”即可添加節點,也可以在左側的節點面板中查看所有可用節點: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image52.png) + +同時,可以打開工具選擇面板,查看支持調用的各類工具: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image53.png) + +下面是一些常用節點和工具的簡要說明。不需要一次性全部掌握,建議先留個印象,在實際使用中逐步熟悉,必要時再回查閱。 + +1. LLM與推理節點 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image54.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image55.png) + +此類節點負責工作流中的核心流程。 + +- LLM節點:核心計算單元,用於調用大語言模型。其配置重點在於提示詞工程與參數調優,將業務問題轉化為模型的執行指令。 +- Knowledge Retrieval 節點:知識檢索單元,負責從預設知識庫、外部權威資料源中檢索與業務問題相關的資訊,為 LLM 節點提供精準的知識支撐,幫助減少大語言模型輸出的 “幻覺” 問題。 +- Answer 節點:結果輸出單元,負責接收 LLM 處理後的內容,將其整理為符合業務場景需求的最終成果形式。其配置重點在於輸出格式的定義(如話術模板、排版規範)。 +- Agent節點:高階決策單元。它不僅調用模型,還可實施多步驟規劃、自主選擇並調用外部工具,適用於需要動態決策的複雜任務鏈。 +- Question Classifier 節點:問題分類單元,負責對輸入的業務問題進行類型識別與歸類(比如按問題意圖、主題領域等維度劃分),幫助後續流程精準匹配對應的處理節點(如不同類型的問題適配不同的 LLM 提示詞或工具鏈)。 + +2. 邏輯與流程控制節點 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image56.png) + +此類節點定義工作流的執行路徑與規則。 + +- 條件節點:如 `IF/ELSE`,通過布爾判斷實現流程分支。其設計關鍵在於條件表達式的嚴謹性,確保邏輯覆蓋所有業務場景。 +- Iteration 節點:作為無狀態的批量並行處理單元,它專為子任務間無資料依賴、可獨立處理的場景設計,例如批量翻譯段落、並行審核多條內容或同時生成多份報告。該節點會接收一個輸入數組並自動分片,將每個元素分發至相同處理鏈路並行執行,用戶可在迭代體內通過 {{item}} 訪問當前元素、{{index}} 獲取其索引,輸出則會自動聚合成結果數組;配置時需重點設定並行度以平衡效率與系統負載,同時通過重試策略(如重試次數、間隔)和失敗處理(如記錄日誌、返回默認值)保障批量作業的穩定性。 +- Loop 節點:有狀態的遞歸迭代器,適用於結果依賴前一輪輸出的場景,比如多輪參數調優、遞歸式內容優化(如反覆修訂文案直至滿意)及依賴上次結果的鏈式計算。其核心是 “狀態變量”,需在循環開始前初始化(如當前迭代次數、中間計算結果),並在每輪迭代中明確更新以作為下一輪輸入;為防止無限循環,必須定義終止條件(包括基於計數器的 “最多循環 10 次”、基於結果判定的 “滿意度評分 > 9”、基於外部信號的 “檢測到‘停止’輸入”),同時需設置循環超時配置,並規劃異常處理路徑(如跳出循環或重置狀態後重試),確保流程穩定運行。 + +3. 資料操作與集成節點 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image57.png) + +- Code 節點:程式碼處理單元,負責在工作流中執行自定義程式碼邏輯,可實現資料格式轉換、複雜計算等個性化處理需求。其配置重點在於程式碼語法的正確性與執行環境的適配。 +- Template 節點:模板處理單元,負責將動態資料填充至預設模板中,生成符合格式要求的內容(如定製化文案、報告框架)。其配置重點在於模板語法的編寫與變量映射規則的設置。 +- Variable Aggregator 節點:變量聚合單元,負責收集工作流中多個節點輸出的變量資料,將分散的變量整合為統一資料集。其配置重點在於聚合的變量範圍與資料合併規則的定義。 +- Doc Extractor 節點:文檔提取單元,負責從 PDF、Word 等各類文檔中提取文本、表格等關鍵內容,轉化為工作流可處理的結構化資料。其配置重點在於文檔類型的適配與提取內容的篩選規則。 +- Variable Assigner 節點:變量賦值單元,負責定義、初始化或更新工作流中的變量,為流程內的資料傳遞提供載體。其配置重點在於變量的命名、資料類型及賦值邏輯的設定。 +- Parameter Extractor 節點:參數提取單元,負責從用戶請求、接口返回等輸入內容中提取指定參數,將非結構化資訊轉化為結構化資料。其配置重點在於提取規則(如正則表達式、JSON 路徑)的配置。 +- HTTP Request 節點:HTTP 請求單元,負責向外部系統接口發起 HTTP 請求(含 GET、POST 等方法),實現工作流與外部服務的資料交互。其配置重點在於請求地址、請求方法及參數 /headers 的設置。 +- List Operator 節點:列表操作單元,負責對數組、列表類型的資料進行處理(如過濾、排序、拆分),調整資料結構以適配後續流程。其配置重點在於操作類型(如過濾條件、排序規則)的定義。 + +### 2.6.2 常見工具介紹 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image58.png) + +在 Dify 中,大部分工具都可以直接作為節點放在畫布上,像其他節點一樣被上下游連線,只要你提供的輸入符合該節點(工具)的參數規範,它就能正常執行併產出可繼續流轉的結果。 + +在左側或右側的節點面板中,可以查看所有可用工具節點,也可以通過插件市場擴展更多工具能力。簡單介紹幾個常見工具的作用: + +- 網路搜索工具 + 以 Tavily Search 為代表,為大模型提供面向 AI 優化的實時檢索能力。 + 它會返回結構化的搜索結果(如標題、摘要、鏈接等),可以直接作為 LLM 提示詞的一部分,用於回答最新資訊類或需要權威依據的問題。 +- 資料處理工具 + 例如 JSON Process 插件,用於對 JSON 資料進行查詢、篩選、轉換、合併等高級操作。 + 在處理複雜 API 響應或多層嵌套資料時,你可以將“資料清洗 + 重組”的邏輯交給該工具,從而簡化在 Code 節點中頻繁手寫解析程式碼的工作。 +- 格式處理工具 + 如 Markdown Exporter,可以將生成內容按指定格式導出,例如 Markdown 文檔、特定排版模板等,方便後續用於展示、彙報或集成到其他系統。 + +你可以在工具列表中看到這些插件的安裝量和簡介,初期可優先嚐試安裝“Featured / 推薦”裡的工具,往往覆蓋了最常見的業務場景。 + +不過,工具的使用通常比較複雜,建議你在使用的時候可以去搜索引擎先搜索對應工具的“官方推薦工作流 DSL 案例”,直接導入使用,比自己搭建要天然節約很多時間。 + +### 2.6.3 創建簡單的意圖分類工作流 + +此時我們已經初步瞭解了 Dify 工作流和工具等的基本資訊,但不經過練習我們永遠不會熟練使用細節,我們需要一個“假設”的真實業務場景來練練手。 + +例如,在真實的購物對話場景中,前來購買商品的用戶輸入永遠不會是“規範的參數”,而是一句隨口說出的話:有人來下單,有人來抱怨,有人只是想閒聊,也有人完全跑題。如果我們把所有這些輸入都直接交給同一個大語言模型(LLM)處理,系統通常會出現兩個典型問題: + +1. 回覆風格不穩定 + 同樣是抱怨,有時 LLM 能道歉安撫,有時卻像在“解釋原因”;同樣是點餐,有時會追問缺失資訊,有時則直接編造訂單細節。 +2. 業務邏輯不可控 + 你希望“抱怨必須先道歉”,但模型未必每次都遵守;你希望“非業務問題要引導回主線”,但模型可能會興致勃勃地和你聊起段子。 + +因此,更工程化的做法是將任務拆解為一條標準化流水線,先做意圖分類(確定用戶到底想幹什麼),然後再按意圖分流(不同場景使用不同的提示詞與角色),最後對不同分流後大模型的回覆統一封裝輸出(便於前端或系統集成)。 + +本節的目標是讓系統能處理一個餐飲場景下的多類對話。你可以跟著操作做一遍加深印象。首先需要做的是定義場景為意圖分類: + +- **下單購買 (buy_food)** :用戶表達明確的購買意願。 +- _例如:“給我來一份炸雞,再加一杯可樂。”_ +- **抱怨投訴 (complain)** :用戶在表達不滿、催促或負面反饋。 +- _例如:“你們也太慢了吧?等一個小時了。”_ +- **閒聊諮詢 (chitchat)** :用戶在進行開放式詢問、尋求建議,但無明確下單指令。 +- _例如:“今天吃什麼好呢,你有什麼推薦嗎?”_ +- **其他意圖 (other)** :用戶的輸入與餐飲場景無關。 +- _例如:“幫我寫個搞笑文案發朋友圈。”_ + +針對這四種意圖,我們為系統預設了四種不同的“溝通人格”,分別由四個獨立的 LLM 節點承載,每個節點都需要由具有不同人設的 LLM 進行扮演。 + +- **下單助手 (LLM_BuyFood)** :專業、高效,核心任務是確認訂單細節,並主動補全缺失資訊。 +- **客服專家 (LLM_Complain)** :共情、穩重,首要任務是安撫用戶情緒,並提供清晰的解決方案。 +- **聊天夥伴 (LLM_Chitchat)** :輕鬆、友好,旨在提供個性化推薦,引導潛在消費。 +- **禮貌門衛 (LLM_Other)** :專注、邊界清晰,負責將偏離主題的對話禮貌地引導回核心業務。 + +#### 工作流編排設計 + +接下來我們進行工作流的編排設定,決定大概需要有哪些工作流節點。對於新手而言,很難想到需要有哪些節點能被用到(對於老手來說也懶得自己思考,用大模型給建議通常是最快最好的選擇),所以我們能夠使用大模型給出對應的編排建議,其核心節點結構如下: + +- Start (起點):作為資料入口,負責接收用戶的原始輸入 `user_text`。 +- Question Classifier (意圖分類器):工作流的“大腦”與“調度中心”。它負責對 `user_text` 進行分析,並從我們預設的四種意圖標籤中選擇最匹配的一個。 +- Condition (條件分支):扮演“分流閥”的角色。它根據分類器輸出的意圖標籤,決定接下來將任務導向哪一個專處理路徑。 +- 四個並行的 LLM 節點 (LLM_BuyFood, LLM_Complain, LLM_Chitchat, LLM_Other):這是四個獨立的“專家處理單元”。每個節點都接收原始問題,但依據自身獨特的 System Prompt(系統提示詞)生成風格和目標截然不同的回覆。 +- Variable Aggregator (變量聚合器):在多條路徑處理完成後,需要一個“匯集點”。此節點將四個分支中唯一被激活併產生結果的回覆,收束成一個統一的變量 `final_reply`,確保了輸出結構的穩定性。 +- Output (終點):作為最終的出口,負責將意圖標籤、原始問題、以及經過處理生成的回覆,以結構化的形式(如 JSON)統一輸出,便於後續系統調用或調試分析。 + +#### 工作流編排實現 + +本次教程我們選擇創建 Workflow 而不是 Chatflow,選擇 User Input: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image59.png) + +隨後點擊 Start 的 User Input 節點,定義一個名為 `user_text` 的字符串類型變量,作為整個流程的輸入源。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image60.png) + +保存後點擊右上角的 Test Run,你能夠看到需要指定對應的文本輸入進行處理: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image61.png) + +隨後我們需要點擊輸入節點後的 + 符號,選擇 Question Classifier 節點添加,並且我們需為其配置四類標籤,併為每個標籤提供清晰的描述和示例。 + +- `buy_food`: 用戶明確想買吃的、點餐、下單。 +- `complain`: 用戶在抱怨、吐槽、發脾氣,通常帶有不滿情緒。 +- `chitchat`: 用戶在閒聊、討論吃什麼、諮詢推薦。 +- `other`: 與餐飲場景無關,或難以判斷的內容。 + +此外,你還需要在 ADVANCED SETTING 中寫入提示詞,讓大模型能夠正確根據用戶輸入進行分類測試。示例提示詞如下: + +``` +從 buy_food / complain / chitchat / other 中選擇一個最合適的標籤。如果用戶在抱怨的同時也點了餐,請優先判斷其核心情緒,若重點在於表達不滿,應歸為 complain。如果只是輕微吐槽但主要意圖是下單,則歸為 buy_food。若實在難以判斷,使用 other 作為兜底 +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image62.png) + +設定完成後,你可以在右上角的播放鍵單獨測試該節點是否能夠正常運行: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image63.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image64.png) + +從 OUTPUT 的結果來看,我們的分類是準確的。你可以進行多種不同類型輸入的測試,驗證我們分類器的穩定性。 + +接下來,我們需要給分類器接上後續的大模型輸出,例如,當 `label` 等於 `"buy_food"` 時,工作流便會精確地流向 `LLM_BuyFood` 節點。我們需要新建四個 LLM 節點,並設置不同的 System Prompt ;不同 System Prompt 的差異決定了它們不同的回應方式。 + +- LLM_BuyFood (點餐助手): + +你是一個點餐助手。要求:1. 確認用戶想點的內容。2. 如果資訊不完整,友好地補充詢問。3. 語氣禮貌簡潔。 + +- LLM_Complain (客服專家): + +你是一個餐飲客服,專門處理抱怨。要求:1. 真誠道歉。2. 簡要說明可能的原因(不推卸責任)。3. 給出清晰的下一步解決方案。 + +- LLM_Chitchat (聊天夥伴): + +你是一個幫人選吃的的聊天小助手。要求:1. 用輕鬆友好的語氣。2. 給出 1~3 個簡單推薦。3. 如果用戶沒有偏好,就給出不同風格的選擇。 + +- LLM_Other (禮貌門衛): + +你是一個餐飲點餐小助手,只擅長跟‘吃’相關的話題。當用戶說的話無關時:1. 禮貌說明自己的能力範圍。2. 引導用戶回到主場景。 + +值得注意的是,每個節點裡面在填充了 SYSTEM 的提示詞參數後,你還要記得啟用 USER 提示詞參數表。你需要在其中需要點擊 `{x}` 符號,選擇 `user_text` 參數作為用戶輸入,並且在前面加上 `user input:` 標識這個變量是用戶輸入的意思,在問答的時候會綜合用戶的最開始的輸入和內置提示詞進行回覆。 + +同樣的,為了確保一切順利,你可以點擊該節點右上角的播放箭進行具體的對話測試驗證效果,比如對話說“我想要喝珍珠奶茶”等,查看回復是否符合預期。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image65.png) + +接下來我們處理並行 LLM 的輸出值,我們在 `Variable Aggregator` 節點的配置面板中,找到 `ASSIGN VARIABLES`(分配變量)區域,點擊後依次將之前的大模型回覆加入即可。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image66.png) + +接下來我們需要對所有的輸出進行聚合,最後得到我們想要的結果,包含用戶的輸入、分類、以及回覆。由於我們使用的是 Workflow 而不是 Chatflow,故沒有 Answer 節點選擇進行結果的聚合,我們能夠選擇其他節點變相實現結果的聚合與輸出,此時選擇 Template 節點,在變量部分指定用戶意圖分類結果、用戶的輸入值、變量聚合的最終回覆,並且在 CODE 中寫入最後回覆的 json 格式模板,我們可以得到: + +- `intent` ← `class_name` +- `original_text` ← `user_text` +- `final_reply` ← `variable_aggregator` + +``` +{ + "intent": "{{ intent }}", + "original_text": "{{ original_text }}", + "reply": {{ final_reply }} +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image67.png) + +最後加入 output 節點即完成所有操作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image68.png) + +#### 工作流運行測試 + +大功告成,我們可以嘗試運行這套工作流的效果。它能根據不同的輸入,展現出截然不同的行為模式: + +- 輸入 (點餐): "給我來一份香辣雞腿堡套餐,大杯可樂。" + - 路徑: `buy_food` → `LLM_BuyFood` + - 輸出 reply: "好的,一份香辣雞腿堡套餐和大杯可樂已為您記錄。請問套餐裡的薯條需要更換嗎?" +- 輸入 (抱怨): "你們也太慢了吧?我都等一個多小時了!" + - 路徑: `complain` → `LLM_Complain` + - 輸出 reply: "非常抱歉讓您等了這麼久,這確實是我們的疏忽,給您帶來了很不好的體驗。我們正在緊急核實您的訂單配送情況,並會為您申請相應的補償,感謝您的耐心與反饋。" +- 輸入 (閒聊): "今天吃什麼比較健康?" + - 路徑: `chitchat` → `LLM_Complain` + - 輸出 reply: "追求健康的話,可以試試我們的輕食沙拉系列,或者烤雞胸肉配時蔬。您是喜歡口味清淡一些還是稍微豐富一點的呢?我可以給您更具體的推薦。" +- 輸入 (無關內容): "幫我想個明天開會的笑話。" + - 路徑: `other` → `LLM_Other` + - 輸出 reply: "這聽起來是個有趣的挑戰!不過我主要是個美食推薦和點餐助手。如果您需要點些什麼來犒勞一下辛苦工作的自己,我隨時可以幫忙!" + +> 隱藏 Bug :需要說明的是,若你遇到與 aggregation group 相關的奇怪問題,這大概率是 Dify 的一個內置 bug。可能在特定操作下被觸發;如果你曾經開啟又關閉過 AGGREGATION GROUP,系統可能生成過 group 配置且殘留了相關異常參數,即便現在開關看起來是關閉的,這些殘留配置也可能導致問題,比如出現 `any` 相關參數的報錯。此時你只需要刪除該節點並重新創建即可。 + +在 Test Run 中運行後,我們能夠看到工作流的執行過程,此時根據分類走了正確的流程,並得到了最後的 output 結果。至此,全流程完成。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image69.png) + +## 2.7 運行第一個模板 Workflow 應用 + +結束了簡單的分類工作流學習,接下來我們需要學習如何運行別人的 workflow,我們只需要稍作改造就可以將其變成自己的工作流。在這裡我們選擇嘗試官方的 DeepResearch 工作流,該工作流能夠幫你構建一個深度搜索框架,使用大模型+搜索引擎給你一個豐富的搜索答案,每一次提問的結果將會包含搜索引用地址和大模型對話的結果。 + +導入後第一步直接運行,我們根據每一步報錯的地方和原因解決具體問題即可,如果遇到解決不了的問題,你可以截圖後詢問大模型進行解決。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image70.png) + +剛進入感覺十分複雜,沒關係,我們點擊右上角的 Preview 運行工作流,直到報錯出現: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image71.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image72.png) + +我們需要根據報錯的節點解決問題,打開後發現是沒有配置 Tavily 的 API Token,Tavily 的搜索API 是一個專為 AI 設計的搜索引擎,提供實時、準確和事實性的結果。此時根據提示操作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image73.png) + +經過處理後,搜索引擎能夠正常工作: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image74.png) + +繼續修正模型調用導致的問題後,你應該能夠得到如下結果,結合大模型理解下的詳細搜索: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image75.png) + +我們在最後能夠看到對應的參考文檔地址: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image76.png) + +如果你想理解每個環節的作用,最好的方法是將每個環節的 output 記錄為一個變量,最後在輸出的時候打印每個中間變量的結果,還有一個方法就是你可以在上方找到 Process 的過程,點擊後可以查看每個環節的細節: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image77.png) + +## 2.8 將 Dify 作為 API 提供方 + +接下來,我們會嘗試通過 API 調用剛才創建的知識庫智能體 Agent,我們想要讓 Dify 變成一個大模型中樞後端。 + +還記得之前講過如何通過 API 調用模型嗎?我們需要準備一個密鑰(Key)和一份 API 調用示例(文檔中的 request/response 示例),然後把這些內容發給大模型,讓它幫我們寫出調用服務的程式碼,並從返回結果中解析出我們需要的字段。 + +這一次,我們會使用本地的程式碼編輯工具 [Trae](https://www.trae.cn/) 來完成這個過程。 + +如果你還不熟悉什麼是 IDE,可以先閱讀文檔 [Extra Knowledge 4 - What is AI IDE and Trae](https://github.com/datawhalechina/easy-vibe/blob/main/docs/extra/extra4/extra4-what-is-ai-ide-and-trae.md)。 + +如果你的本地開發環境還沒有完整配置好,也不用擔心。只要你信任自己的程式碼助手(不管是 [z.ai](http://z.ai) 還是 Trae),遇到任何不懂的地方或報錯,都可以直接把問題拋給它,它會根據你的描述給出詳細的解決方案。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image78.png) + +右側的區域叫做 Copilot 交互窗口,或者 Agent 窗口。如果你看不到它,可以點擊右上角的側邊欄圖標來打開。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image79.png) + +打開側邊欄後,你會看到 `Builder` 選項。這就是 Agent 模式。你可以簡單地把 “Builder” 理解為 [z.ai](http://z.ai) 的“開發模式”,它同樣可以幫你操作本地電腦環境、安裝依賴、打開網頁等。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image80.png) + +點擊 “Builder” 後,你會看到 “Chat” 模式和 “Builder with MCP” 模式。 Chat 模式主要用於與當前文件夾進行交互,或者和大模型進行自然語言對話。(你可以通過點擊 Trae 左上角的 “File” 打開一個文件夾,然後在該文件夾內進行編輯。這種情況下,Builder 所有的新建文件操作都會發生在這個文件夾中。) + +Builder with MCP 模式則為 Agent 提供了更多工具(例如讓大模型連接到其他軟體、獲取天氣資訊等)。你可以簡單地認為 MCP 是一個讓大模型更方便調用各種外部工具的能力集合。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image81.png) + +在下方區域,你還可以看到模型選擇的下拉列表,可以點擊切換不同模型。這裡你可以選擇 Kimi k2 或 GLM。如果你使用的是國際版 Trae,也可以選擇 ChatGPT 或 Claude。 不過,隨著國內大模型的快速發展,Kimi、Qwen、GLM 等模型的綜合能力已經基本接近 Claude 3.5 或 3.7,對於日常開發場景來說完全夠用。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image82.png) + +上面是對 Trae 的一個簡要介紹。接下來,我們可以回顧在 [z.ai](http://z.ai) 中的操作步驟,並在 Trae 中複用這些思路。 + +## 2.9 利用 Dify API 創建前端對話應用 + +如果我們想用 Dify 的 API 搭建一個前端聊天應用,首先需要獲取 Dify 的 API 文檔和調用地址。 + +還記得剛才創建的那個 Agent 嗎? 先點擊右上角的 “Publish”,然後點擊 “Publish Update”,最後點擊 “Access API Reference” 進入 API 文檔。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image83.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image84.png) + +進入 API 文檔後,找到 “Send Chat Message” 這一部分,點擊進入,然後在右側找到 “Request” 和 “Response” 示例並複製出來。 + +為什麼一定要複製這兩部分內容? 因為它們是 API 的“核心資訊”: 有了 Key、請求示例和返回示例,我們就可以讓大模型幫我們生成調用服務的程式碼,並且根據返回結構把需要的字段提取出來。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image85.png) + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image86.png) + +在找到會話所需的 Request 和 Response 示例之後,我們還需要獲取一個 API Key。在文檔右上角,你會看到 “API key” 相關選項。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image87.png) + +點擊 “Create new Secret key”,就可以創建屬於你自己的 API Key。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image88.png) + +現在一切準備就緒。我們會把剛才拿到的 API Key、Request 示例和 Response 示例一起交給 Trae Builder。 + +注意:請將 `{DIFY_API_URL}` 替換為實際的 Dify API 地址。 + +```json +key: +app-zKdCHUXXXXXXXX + +Please write me a front-end based on the following reference: + +curl -X POST 'http://{DIFY_API_URL}/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image89.png) + +在這個階段,你可能會發現生成出來的程序並不能一次性正常運行——比如對話會出現奇怪的錯誤,或者沒有任何返回結果。當出現這種情況時,你可以嘗試切換到另一個大語言模型,或者把錯誤資訊複製出來,詳細描述問題,再發給模型讓它根據反饋繼續迭代。 + +此時你的工作方式已經非常接近真實開發過程了。在日常開發中,我們經常會在與大模型協作時遇到各種問題,為了更好地解決這些問題,我們需要提供更多上下文資訊。除了提供錯誤資訊,你還可以複製更完整的文檔內容(例如在文檔左側 “Send message” 部分中複製更多說明),一併交給模型,讓它在更多細節的基礎上給出更完整的解決方案。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image90.png) + +此時瀏覽器是嵌在 Trae 內部的。你可以點擊頂部的指南針圖標,把網頁在外部瀏覽器中全屏打開。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image91.png) + +如果運氣不錯,你可能在第一次嘗試時就能獲得一個可以正常交互的前端頁面。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image92.png) + +不過,由於大模型本身具有一定隨機性,有時你可能在單輪對話中一切順利,但在多輪對話時出現異常。因此,建議你進行多輪對話測試,確保程序在多輪交互場景下也能穩定運行。 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image93.png) + +到這裡,你已經學會了如何構建一個簡單的 Dify 知識庫 Agent,並使用 Trae 替代 [z.ai](http://z.ai) 來搭建一個交互式前端。從現在開始,Trae 將成為我們構建各種原型時的主要開發工具,逐步取代 [z.ai](http://z.ai)。你可以嘗試用 Trae 重新實現之前的貪吃蛇遊戲,看看會有什麼不同的體驗。加油! + +# 3. 更多業務工作流參考 + +你可以在搜索引擎上使用類似關鍵詞搜索 `Dify workflow 參考`,或者直接在 Github 中找到 Dify 工作流分享倉庫進行參考工作流的查找(質量參差不齊,你需要查看多個不同倉庫學習)。當然,所謂的工作流只不過是業務上 SOP 的映射,你可以思考有哪些日常工作中的流程或者學習中的流程是重複可固化的,只需要把它變成工作流固定即可。 + +以下是一些大模型生成的工作流設計的參考(實際上的實現方案也比較類似,一般來說人類設計的工作流不會有大模型設計的優美,除非是高手設置的工作流),如果你覺得哪些點子有意思,可以將它發給大模型進一步細化,讓大模型幫你給出更具體的 Dify 工作流節點設定,以及內部的細節結果。 + +## 3.1 社媒平臺工作流 + +1. 跨平臺內容一鍵分發工作流(複雜) + 1. 思路:以一篇核心稿件為“原料”,自動加工成適配多個平臺的“成品”。 + 2. 實現:`Start` 輸入文章 -> `LLM` 潤色 -> 並行多個 `LLM` 節點(每個節點Prompt扮演特定平臺專家,如“小紅書爆款文案專家”、“知乎專業答主”)-> `Iterator` 節點循環處理不同平臺格式要求 -> `Variable Aggregator` 彙總 -> `Answer` 輸出所有版本。複雜度在於並行處理和循環迭代。 +2. 熱點話題選題與初稿生成器(中等) + 1. 思路:自動捕捉網路熱點,快速生成選題和內容草稿。 + 2. 實現:`Start` 輸入關鍵詞 -> `Tool` 節點調用搜索引擎API抓取熱點 -> `LLM` 摘要提煉出3-5個話題 -> `LLM` 生成文章大綱或初稿。複雜度在於外部工具集成與資訊篩選。 +3. 評論區智能分類與回覆助手(複雜) + 1. 思路:自動分析評論情感與意圖,生成分類回覆建議。 + 2. 實現:`HTTP Request` 節點接入社媒API獲取評論 -> `Question Classifier` 或 `LLM` 節點進行多標籤分類(積極、疑問、投訴、廣告等)-> `Condition` 判斷節點路由至不同回覆生成鏈 -> 並行 `LLM` 節點生成個性化回覆草稿 -> `Answer` 輸出。複雜度在於條件分支和實時API調用。 +4. 短影片腳本與分鏡自動生成器(複雜) + 1. 思路:根據一個熱門話題或產品描述,自動生成短影片腳本、分鏡描述和推薦標籤。 + 2. 實現:`Start` 輸入主題 -> `LLM` 生成創意腳本 -> 第二個 `LLM` 節點將腳本拆解為場景序列(畫面描述、臺詞、時長)-> `Tool` 節點調用文本轉語音服務生成語音樣本 -> `Variable Aggregator` 整合所有元素 -> `Answer` 輸出結構化腳本文件。複雜度在於多步驟序列化和外部服務集成。 +5. 直播互動問答實時摘要助手(中等) + 1. 思路:實時處理直播間的文字評論,提煉核心問題和觀眾反饋。 + 2. 實現:`HTTP Request` 節點流式獲取直播評論 -> `Iterator` 節點以時間窗口為單位處理批資料 -> `LLM` 節點實時總結每段時間內的熱點問題與情緒傾向 -> `Answer` 或 `Webhook` 節點輸出摘要給主播。複雜度在於實時流資料處理和循環窗口。 + +## 3.2 職場工作流 + +1. 智能會議紀要與任務自動派發系統(複雜) + 1. 思路:從會議錄音文本中提取紀要,並自動創建任務。 + 2. 實現:`Start` 輸入會議文本 -> `LLM` 總結議題與結論 -> `Parameter Extractor` 節點精準抽取Action Items(任務、負責人、DDL)-> 一個 `LLM` 整合成紀要郵件 -> 並行 `HTTP Request` 節點調用Jira/Trello/飛書API創建任務。複雜度在於資訊抽取與多系統聯動。 +2. 簡歷批量篩選與初步評估助手(中等) + 1. 思路:自動解析簡歷,進行匹配度評估並生成面試問題。 + 2. 實現:`Start` 上傳簡歷文件與JD -> `Document Extractor` 節點解析簡歷文本 -> `LLM` 扮演HR進行匹配度評估 -> 對高匹配者,另一個 `LLM` 生成深度面試問題。複雜度在於文檔解析與多條件評估。 +3. 多語言郵件一鍵翻譯與草稿回覆(簡單) + 1. 思路:自動翻譯郵件並起草回覆。 + 2. 實現:`Start` 輸入郵件 -> `LLM` 判斷語種並翻譯 -> `LLM` 構思回覆要點 -> `LLM` 翻譯回原始語言並潤色。主要依賴於LLM的序列調用。 +4. 週報/月報資料自動彙總與洞察生成(複雜) + 1. 思路:連接多個資料源,自動生成結構化工作報告。 + 2. 實現:多個 `HTTP Request`/`Tool` 節點並行調用業務系統API(如CRM、Git、項目管理工具)獲取原始資料 -> `Code` 節點或 `LLM` 進行資料清洗與基礎計算 -> `LLM` 分析趨勢、亮點與風險,生成敘述性報告 -> `Answer` 輸出圖文並茂的文檔。複雜度在於多資料源聚合、資料處理與智能分析結合。 +5. 合同/文檔智能審查與要點提煉(中等) + 1. 思路:快速審查法律或商務文檔,提示風險並提煉核心條款。 + 2. 實現:`Start` 上傳合同PDF -> `Document Extractor` 提取文本 -> `LLM` 節點(設定為法律專家角色)審查責任條款、支付條件、違約條款等 -> `Parameter Extractor` 節點抽取出關鍵日期、金額、義務方等結構化資料 -> `Answer` 輸出風險提示和要點表格。複雜度在於長文檔處理與結構化資訊抽取。 + +## 3.3 學習生活工作流 + +1. 學術論文深度解析與筆記生成器(複雜) + 1. 思路:上傳論文PDF,自動生成結構化筆記。 + 2. 實現:`Start` 上傳PDF -> `Document Extractor` 提取全文 -> 並行多個 `LLM` 節點分工總結摘要、方法、發現、參考文獻 -> `Variable Aggregator` 彙總 -> `Answer` 輸出Markdown筆記。複雜度在於並行處理長文本的不同部分。 + +2. 個性化旅行計劃定製師(中等) + 1. 思路:根據用戶偏好,自動規劃詳盡行程。 + 2. 實現:`Start` 輸入需求(目的地、天數、預算、興趣)-> `Tool` 節點調用搜索引擎或地圖API獲取地點資訊 -> `LLM` 整合資訊,設計每日行程(含時間、活動、預算估算)。複雜度在於外部資訊獲取與結構化規劃。 + +3. 外語學習互動陪練夥伴(簡單) + 1. 思路:創建可角色扮演和語法糾錯的對話機器人。 + 2. 實現:系統設定AI角色 -> `Start` 接收用戶語句 -> `LLM` 執行兩項任務:角色回覆 + 語法糾錯與解釋 -> `Answer` 輸出。核心是LLM的多任務指令。 + +4. 個人知識庫問答與鏈接推薦系統(複雜) + 1. 思路:基於你收藏的文檔、筆記、網頁鏈接,構建一個可問答並能推薦相關舊知識的智能系統。 + 2. 實現:離線處理:使用 `Document Extractor` 和 `Embedding` 工具將個人知識庫切片並向量化存儲。在線工作流:`Start` 輸入問題 -> `Retrieval` 節點從向量庫中查找最相關的知識片段 -> `LLM` 基於檢索到的上下文生成答案 -> 同時,另一個分支使用檢索到的內容作為輸入,通過 `LLM` 生成“相關舊知識”推薦列表 -> `Answer` 合併輸出答案與推薦。複雜度在於檢索增強生成(RAG)流程的構建。 + +5. 健身/飲食計劃追蹤與調整顧問(中等) + 1. 思路:根據用戶輸入的每日飲食和訓練日誌,提供營養分析與訓練建議。 + 2. 實現:`Start` 輸入文本日誌(如“午餐:雞胸肉150g,米飯一碗,蔬菜若干;訓練:深蹲5組”)-> `Parameter Extractor` 節點嘗試結構化輸入資料 -> `LLM` 扮演健身教練,分析營養攝入是否均衡、訓練容量是否合適 -> 對比長期目標,給出微調建議(如“蛋白質攝入充足,建議增加蔬菜種類”)。複雜度在於從非結構化日誌中提取結構化資訊並提供個性化反饋。 + +# 6. 工作流平臺的侷限性 + +工作流平臺(或稱低程式碼平臺)並非萬能解決方案。它雖然對業務人員友好,降低了直接編碼的門檻,但從另一個角度看,“低程式碼”往往也是一種“高程式碼”——用戶仍需理解平臺的概念、規則與操作邏輯,這本身構成了一種新的學習成本。 + +也許你想問,很多簡單的工作流其實就是大模型函數包裝後的前後調用,前面函數的輸出作為後者函數的輸入,本質上幾行程式碼就能夠解決,為什麼需要那麼複雜的多重包裝工作流?反而給 API 調用造成了麻煩。 + +你說得是對的。在當前 vibe coding 的快速發展下,藉助 AI 程式碼生成能力,直接閱讀甚至生成程式碼有時可能更加高效。理想情況下,我們希望能用自然語言直接操作應用邏輯,這才是一個現代的軟體平臺。但目前的工作流平臺尚未實現這一點,因此它在用戶意圖與最終實現之間天然存在一個“中間層”。掌握這個中間層,正是一種需要投入時間學習的成本。理想上,之後的工作流平臺也要支持全 AI 自動對話操作,我們可以讓 AI 真正操作工作流搭建以及入參的每一個細節環節。 + +儘管如此,熟練使用這類平臺正逐漸成為一項基礎技能,如同微軟的辦公軟體一樣,在業務中非常普遍且實用,值得掌握。 + +在後續的進階課程中,我們將介紹如何通過程式碼級別的工作流與 RAG 開發平臺進行構建。屆時,你可以親身體驗不同實現方式在複雜度與靈活性上的區別。(值得注意的是,一些簡單的對話應用或嵌套邏輯,用工作流實現可能並不困難。) + +# 📚 課後作業 + +## 掌握 Dify 基本操作 + +為了測試你掌握了 Dify 的常見基礎使用工具,你需要完成一個基礎作業和兩個 “小挑戰”,確保你已入門常見的操作。你需要將附帶的兩個 DSL 文件導入 Dify 工作流,併成功完成對應工作流的挑戰(遇到不懂的地方截圖詢問大模型,或自己探索其中的每個參數的用法,最後實現目標)。: + +1. 參考意圖分類工作流的方法,讓大模型給你建議完全換一套場景進行應用,但是一定要用到意圖分類工作流,最後提交運行的工作流截圖、場景說明、結果。 +2. Log in workflow 工作流解密挑戰 + +在這個解密挑戰中,你需要完成以下挑戰,讓工作流實現下列功能: + +- 找出正確的密碼! +- 將密碼修改為 0925 +- 當密碼不正確時,提供第二次嘗試機會(不提供第三次) +- 當用戶提及要再次登錄時,為用戶提供重新輸入密碼的機會 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image94.png) + +參考輸入輸出: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image95.png) + +3. Love loop workflow 工作流解密挑戰 + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image96.png) + +在這個解密挑戰中,你需要修復當前工作流的問題,讓工作流最後的輸出類似如下顯示: + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image97.png) + +如果你遇到無法解決的問題,請截圖詢問大模型,或查閱官方文檔得到結果:[https://docs.dify.ai/en/use-dify/getting-started/quick-start](https://docs.dify.ai/en/use-dify/getting-started/quick-start) + +## 實現 Dify API 調用 + +為了測試你真正掌握了 Dify 的 API 調用知識,你需要完成以下任務: + +1. 部署 Dify 並創建一個簡單的知識庫(選取你喜歡的資料)。 +2. 使用 Trae IDE 構建一個對話前端,與 Dify 知識庫進行 API 交互。 +3. 測試多輪對話的效果,確保程序正常運行。 + +你需要提交最終運行截圖和知識庫的處理過程截圖。 + +## 試用第三方工作流 / 構建一個自己的業務工作流 + +請你在 Github、微信公眾號、或者 Reddit、推特上等所有地方找到你想嘗試的別人的 Dify 工作流,下載導入後成功運行;或者你可以根據上文中提到的業務工作流參考,根據現實中的具體需求創建一個自己的業務工作流進行運行。 + +最後你需要提交運行成功的截圖,並說明這個工作流的作用。 + +# [Bug] HTTP 請求錯誤問題的解決方法 + +如果你遇到了如下圖所示的問題,才需要參考本節方案進行解決,否則可以不理會當前部分。 + +有時候可能你會把 Dify 部署在自己的服務器,但是服務器的對外地址通常都是 http 而不是 https 的,但當我們請求一個只支持 HTTP 的服務時,你可能會看到類似這樣的提示(啟用 F12 瀏覽器調試資訊模式,查看有問題的點): + +![](/zh-cn/stage-2/ai-capabilities/dify-knowledge-base/images/image98.png) + +出現這個問題的原因,是因為我們默認把 Dify 部署在一臺只支持 HTTP 而不支持 HTTPS 的服務器上。 HTTPS(HyperText Transfer Protocol Secure)是在 HTTP(超文本傳輸協議)的基礎上增加了 SSL/TLS 加密層,可以簡單理解為“更安全版的 HTTP”。 + +如果要讓服務支持 HTTPS,一般可以: + +- 使用其他程序轉發請求(例如在有證書的 nginx 上做反向代理),或者 +- 綁定域名後為該域名申請證書。 + +但這些操作都比較複雜,在這裡我們使用 Zeabur 作為網路轉發網關來解決問題。 + +Zeabur 的網頁默認是通過 HTTPS 訪問的,因此我們只需要把原來請求的域名轉發到 Zeabur 提供的域名,就可以修復這個問題。 + +- 原始地址:`http://{DIFY_API_URL}/v1/chat-messages` +- 現在地址:`https://{DIFY_NEW_API_URL}.zeabur.app/v1/chat-messages` + +你只需要簡單地把 URL 中的域名部分(公網 IP 或域名)替換為已經在 Zeabur 上部署好的域名即可,我們已經提前在服務裡配置好了轉發功能。 + +如果你感興趣,也可以自己在 Zeabur 上部署一個轉發服務。在 Zeabur 中創建服務時,選擇 Python,然後填入下面的 Python 程式碼,部署後即可得到一個 https 的地址,https 即可正常使用。 + +部署完成後,在網路設置中把程序監聽端口設置為本地 8080,並對外暴露該端口。 + +注意:請將 `{DIFY_API_URL}` 替換為實際的 Dify API 地址。 + +```python +from flask import Flask, request, Response +import requests + +app = Flask(__name__) + +TARGET_BASE_URL = "{DIFY_API_URL}" +LISTEN_PORT = 8080 + +@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +@app.route('/', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']) +def proxy_request(path): + target_url = f"{TARGET_BASE_URL}/{path}" + if request.query_string: + target_url += f"?{request.query_string.decode('utf-8')}" + + headers = {key: value for key, value in request.headers if key.lower() not in ['host', 'connection', 'content-length', 'accept-encoding']} + + try: + resp = requests.request( + method=request.method, + url=target_url, + headers=headers, + data=request.get_data(), + cookies=request.cookies, + allow_redirects=False, + timeout=30 + ) + + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + response_headers = [(name, value) for name, value in resp.raw.headers.items() if name.lower() not in excluded_headers] + + return Response(resp.content, resp.status_code, response_headers) + + except requests.exceptions.RequestException as e: + print(f"Error forwarding request to {target_url}: {e}") + return Response(f"Proxy Error: Could not reach target server or invalid response: {e}", status=502) + except Exception as e: + print(f"An unexpected error occurred: {e}") + return Response(f"Internal Proxy Error: {e}", status=500) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=LISTEN_PORT, debug=True) +``` diff --git a/docs/zh-tw/stage-2/assignments/copywriting-platform-supabase/index.md b/docs/zh-tw/stage-2/assignments/copywriting-platform-supabase/index.md new file mode 100644 index 0000000..deacdc0 --- /dev/null +++ b/docs/zh-tw/stage-2/assignments/copywriting-platform-supabase/index.md @@ -0,0 +1,346 @@ +# AI 營銷文案 SaaS 開發實戰 + +## 概述 + +本實戰項目要求你圍繞一份真實的 PRD,從零完成一個面向獨立開發者和內容團隊的 AI 營銷文案 SaaS 產品。你將使用 Supabase 作為後端服務、Stripe 作為支付系統,完成從需求分析到部署上線的全過程。 + +這是 Stage 2 的綜合實戰環節。在前面幾章中,你已經分別學習了前端頁面搭建、後端接口開發、資料庫操作、支付集成等單項技能——這個項目要求你把它們全部串起來,交付一個可運行的產品原型。 + +## 前置知識 + +在開始本項目之前,你應該已經掌握以下內容: + +- 前端頁面設計與組件庫使用([UI 設計](../../frontend/ui-design/)、[現代組件庫](../../frontend/modern-component-library/)) +- 後端接口設計與開發([接口程式碼編寫](../../backend/ai-interface-code/)) +- 資料庫基礎與 Supabase([從資料庫到 Supabase](../../backend/database-supabase/)) +- 支付集成([Stripe 收費系統](../../backend/stripe-payment/)) +- Git 工作流與部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 應用](../../backend/zeabur-deployment/)) + +## 學習目標 + +完成本實戰後,你將能夠: + +1. 閱讀並理解一份真實的 PRD,從中提取開發任務清單 +2. 使用 AI 輔助分步生成前端頁面和後端接口 +3. 使用 Supabase 實現用戶鑑權、資料庫操作 +4. 集成 Stripe 實現付費訂閱功能 +5. 搭建管理後臺並完成端到端聯調 + +## 項目簡介 + +你要構建的產品是一個 AI 營銷文案 SaaS,包含三個子系統: + +| 子系統 | 職責 | +|--------|------| +| **官網前臺** | 產品介紹、定價、FAQ、註冊轉化 | +| **用戶工作臺** | 輸入產品資訊、生成文案、查看歷史、升級套餐 | +| **後臺管理臺** | 用戶管理、生成記錄、支付資料、運營概覽 | + +後端使用 Supabase 提供資料庫和鑑權能力,使用 Stripe 處理支付,使用 AI 模型生成營銷文案。 + +::: tip PRD 入口 +本項目的需求文檔在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-tw/stage-2/assignments/copywriting-platform-supabase/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 閱讀 PRD + +打開 PRD 文檔,重點回答以下問題: + +- 系統有幾個入口?各自覆蓋哪些頁面? +- 每個頁面的核心功能是什麼? +- 後端包含哪些模塊和資料表? +- 套餐定價、支付流程、免費額度如何設計? +- MVP 範圍是什麼?第一版哪些做,哪些不做? + +::: warning +如果以上問題沒有明確答案,不要開始寫程式碼。需求理解不清楚是導致返工的最常見原因。 +::: + +### 1.2 確認系統架構 + +根據 PRD 梳理出系統的整體架構: + +```mermaid +flowchart TD + prd["PRD"] --> web["官網前臺"] + prd --> app["用戶工作臺"] + prd --> admin["後臺管理臺"] + app --> auth["鑑權"] + app --> gen["文案生成任務"] + gen --> db["資料庫"] + billing["支付與套餐"] --> db + admin --> analytics["用戶 / 生成 / 支付看板"] +``` + +## 第二部分:搭建項目骨架 + +### 2.1 生成前端頁面 + +使用 AI 先生成所有頁面的基本結構和假資料。 + +提示詞參考: + +```text +請基於當前 PRD,幫我生成一個 AI 營銷文案 SaaS 的前端骨架。 + +要求: +1. 分成三個入口:www、app、admin +2. 官網包括:首頁、定價、FAQ +3. app 包括:登錄、註冊、生成工作臺、歷史記錄、套餐頁 +4. admin 包括:後臺首頁、用戶管理、生成記錄、支付訂單 +5. 先只生成頁面結構和假資料,不接真實接口 +6. 風格要像現代 SaaS,不像課堂 demo +``` + +### 2.2 完善核心頁面 + +骨架搭好後,重點完善文案生成工作臺(Dashboard)頁面: + +```text +請繼續完善 /dashboard 頁面。 + +這是一個 AI 營銷文案工作臺。 + +左側表單字段: +- 產品名 +- 一句話介紹 +- 目標用戶 +- 3 個賣點 +- 投放渠道(官網、朋友圈、小紅書、抖音、郵件) + +右側結果區域預留: +- 主標題 +- 副標題 +- CTA +- 3 版短文案 +- 長文案 + +先用 mock 資料跑通交互。 + +要求: +- 點擊"生成文案"後有 loading 狀態 +- 結果區域設計空狀態 +- 響應式佈局,寬屏窄屏都能正常顯示 +``` + +### 2.3 驗證頁面結構 + +逐項檢查: + +- [ ] 三個入口的路由是否獨立 +- [ ] 頁面數量是否與 PRD 一致 +- [ ] Dashboard 的表單和結果區域佈局合理 +- [ ] 假資料展示了基本的 UI 狀態 + +### 遇到阻礙? + +如果你在前端搭建階段卡住,可以回顧這些章節: + +- [UI 設計](../../frontend/ui-design/) +- [參考 UI 設計規範設計頁面和按鈕](../../frontend/multi-product-ui/) +- [用 LLM 和 Skills 讓界面變好看](../../frontend/llm-skills-beautiful/) +- [從設計原型到項目程式碼](../../frontend/design-to-code/) +- [使用現代組件庫更新你的界面](../../frontend/modern-component-library/) + +## 第三部分:後端集成 + +### 3.1 接入 Supabase 登錄 + +```text +請把我當成 0 基礎,一步一步帶我完成 Supabase 登錄接入。 + +需要你幫我完成: +1. 項目接入 Supabase +2. 實現註冊、登錄、退出功能 +3. 登錄成功後跳轉到 /dashboard +4. 未登錄用戶訪問 /dashboard、/billing、/admin 時自動跳轉 /login +5. 創建 profiles 表 +6. 用戶註冊成功後自動在 profiles 表創建記錄 +7. profiles 表包含 email、role、plan 字段 + +實現要求: +- 每步都說明在修改哪些文件 +- 密鑰不要硬編碼 +- 需要在 Supabase 後臺手動操作的地方請明確標註 +- 完成後說明如何驗證註冊和登錄 +``` + +### 3.2 接入生成接口和資料庫 + +```text +請把我當成 0 基礎,幫我完成網站的核心功能:生成營銷文案並保存。 + +目標效果: +1. 用戶在 /dashboard 填寫表單,點擊"生成文案" +2. 後端接收:產品名、介紹、目標用戶、賣點、投放渠道 +3. 後端調用模型生成結果 +4. 頁面展示生成結果 +5. 輸入和輸出都保存到資料庫 +6. 用戶下次進入可查看歷史記錄 + +需要你完成: +- 創建生成接口 /api/generate +- 創建 generations 表 +- 設計輸入和輸出字段 +- Dashboard 頁面讀取當前用戶的歷史記錄 + +用戶體驗: +- 按鈕 loading 狀態 +- 生成失敗時的錯誤提示 +- 無歷史記錄時的空狀態 + +完成後請說明: +- 前端頁面文件位置 +- 後端接口文件位置 +- 資料寫入資料庫的邏輯位置 +- 如何測試完整生成鏈路 +``` + +### 3.3 接入 Stripe 付費 + +```text +請把我當成 0 基礎,幫我給 LaunchKit 加上最簡可用的 Stripe 付費。 + +不需要複雜系統,先跑通最基本的付費鏈路。 + +需要你完成: +1. /billing 頁面展示 free 和 pro 兩個套餐 +2. 用戶點擊升級後跳轉 Stripe Checkout +3. 支付成功後返回網站 +4. 支付結果保存到 subscriptions 表 +5. 同步更新 profile.plan 字段 +6. free 用戶每日限 3 次生成,pro 用戶不限 + +實現原則: +- 先跑通主流程,暫不考慮複雜邊界 +- 需要在 Stripe 後臺配置的地方請寫清楚 +- 完成後說明如何測試完整支付流程 +``` + +### 3.4 搭建管理後臺 + +```text +請把我當成 0 基礎,幫我做一個簡潔可用的管理後臺。 + +僅限管理員訪問。 + +需要你完成: +1. 僅 role = admin 的用戶可訪問 /admin +2. 後臺包含 3 個 Tab:用戶列表、生成記錄、訂閱狀態 +3. 用戶列表顯示:email、plan、創建時間 +4. 生成記錄顯示:用戶、產品名、渠道、創建時間 +5. 訂閱狀態顯示:用戶、套餐、支付狀態 + +要求: +- 界面簡潔清晰 +- 使用現有組件庫的表格、Tab、Badge +- 完成後說明如何將賬號設為 admin +``` + +### 遇到阻礙? + +如果你在後端開發階段卡住,可以回顧這些章節: + +- [從資料庫到 Supabase](../../backend/database-supabase/) +- [大模型輔助編寫接口程式碼與接口文檔](../../backend/ai-interface-code/) +- [如何集成 Stripe 等收費系統](../../backend/stripe-payment/) + +## 第四部分:聯調與上線 + +### 4.1 端到端測試 + +至少驗證以下場景: + +- 註冊 → 登錄 → 生成文案 → 查看歷史 → 升級套餐 +- 管理員登錄 → 查看用戶資料 → 查看生成記錄 → 查看支付狀態 + +部署前檢查: + +```text +請把我當成 0 基礎,幫我檢查項目是否具備部署條件。 + +檢查重點: +- 環境變量是否完整 +- 登錄回調地址是否正確 +- Stripe 支付回調地址是否正確 +- 頁面是否缺少 loading、空狀態、錯誤提示 +- README 是否包含啟動說明和部署說明 + +需要你: +1. 按優先級列出待修復事項 +2. 標註哪些必須先修 +3. 說明修復後的部署步驟 +``` + +### 4.2 部署 + +將項目部署到公網環境。部署教程參考:[Git 和 GitHub 工作流](../../backend/git-workflow/)、[如何部署 Web 應用](../../backend/zeabur-deployment/)。 + +## 交付物 + +完成本項目後,你需要提交以下內容: + +- [ ] 可訪問的線上演示鏈接 +- [ ] 源碼倉庫鏈接(含 README) +- [ ] PRD 文檔 +- [ ] 核心頁面截圖(首頁、Dashboard、Billing、Admin) +- [ ] 60 秒演示影片(覆蓋註冊 → 生成 → 支付 → 後臺) + +README 至少包含:項目簡介、核心頁面說明、技術棧、本地啟動步驟、環境變量清單。 + +## 評分標準 + +| 維度 | 基本要求 | 進階要求 | +|------|---------|---------| +| 產品完整度 | 首頁、登錄、Dashboard、Billing、Admin 都能訪問 | 首頁文案和視覺風格像真實 SaaS | +| 業務閉環 | 註冊 → 登錄 → 生成 → 查看歷史可以跑通 | 免費/Pro 權限差異清晰可見 | +| 資料正確性 | 生成結果和支付狀態都寫入資料庫 | 有明確的錯誤提示、空狀態和 loading | +| 權限與安全 | 未登錄不能訪問受保護頁面,普通用戶不能進 Admin | 有基本的輸入校驗和服務端鑑權 | +| 工程交付 | 項目可本地啟動,也可部署到公網 | README 清楚,演示影片結構完整 | + +::: tip +如果你覺得任務太大,記住一個原則:**先保證"能跑通",再去追求"做漂亮"。** +::: + +## 提交前檢查 + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## 參考資料 + +- [UI 設計](../../frontend/ui-design/) +- [參考 UI 設計規範設計頁面和按鈕](../../frontend/multi-product-ui/) +- [用 LLM 和 Skills 讓界面變好看](../../frontend/llm-skills-beautiful/) +- [從設計原型到項目程式碼](../../frontend/design-to-code/) +- [使用現代組件庫更新你的界面](../../frontend/modern-component-library/) +- [從資料庫到 Supabase](../../backend/database-supabase/) +- [大模型輔助編寫接口程式碼與接口文檔](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 應用](../../backend/zeabur-deployment/) +- [如何集成 Stripe 等收費系統](../../backend/stripe-payment/) diff --git a/docs/zh-tw/stage-2/assignments/custom-dify-agent-platform/index.md b/docs/zh-tw/stage-2/assignments/custom-dify-agent-platform/index.md new file mode 100644 index 0000000..7ec274f --- /dev/null +++ b/docs/zh-tw/stage-2/assignments/custom-dify-agent-platform/index.md @@ -0,0 +1,210 @@ +# 類 Dify 智能體平臺開發實戰 + +## 概述 + +本實戰項目要求你圍繞一份真實的 PRD,從零完成一個模仿 Dify 核心體驗的智能體平臺。你將構建用戶控制檯、管理後臺和平臺後端,實現智能體管理、對話、日誌和知識庫等核心功能。 + +這是 Stage 2 的綜合實戰環節。與前面的單頁面或單功能項目不同,這個項目要求你構建一個有"平臺感"的 AI 產品——包含多角色、多模塊、資料持久化和模型調用鏈路。 + +## 前置知識 + +在開始本項目之前,你應該已經掌握以下內容: + +- 前端頁面設計與組件庫使用([UI 設計](../../frontend/ui-design/)、[現代組件庫](../../frontend/modern-component-library/)) +- 後端接口設計與開發([接口程式碼編寫](../../backend/ai-interface-code/)) +- 資料庫基礎與 Supabase([從資料庫到 Supabase](../../backend/database-supabase/)) +- Git 工作流與部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 應用](../../backend/zeabur-deployment/)) + +## 學習目標 + +完成本實戰後,你將能夠: + +1. 閱讀並理解一份真實的 PRD,從中提取開發任務清單 +2. 設計智能體平臺的頁面架構和資料模型 +3. 實現智能體創建、對話、日誌記錄的完整鏈路 +4. 使用 AI 輔助完成平臺型產品開發 +5. 完成端到端聯調,交付一個可演示的 AI 平臺原型 + +## 項目簡介 + +你要構建的產品是一個類 Dify 智能體平臺,包含兩個子系統: + +| 子系統 | 職責 | +|--------|------| +| **用戶控制檯** | 創建智能體、配置 Prompt、發起對話、查看日誌、管理知識庫 | +| **管理後臺** | 查看用戶資料、平臺資源使用情況、調用統計 | + +後端需要支持以下核心能力:智能體管理、會話管理、消息存儲、模型調用、調用日誌記錄、知識庫接入。 + +::: tip PRD 入口 +本項目的需求文檔在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-tw/stage-2/assignments/custom-dify-agent-platform/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 閱讀 PRD + +打開 PRD 文檔,重點回答以下問題: + +- 智能體、會話、日誌、知識庫哪些要進 MVP? +- 頁面和路由清單是否拍板? +- 模型調用和日誌記錄的邊界是什麼? +- 多租戶和複雜工作流是否先不做? + +::: warning +如果以上問題沒有明確答案,不要開始寫程式碼。需求理解不清楚是導致返工的最常見原因。 +::: + +### 1.2 確認系統架構 + +根據 PRD 梳理出系統的整體架構: + +```mermaid +flowchart TD + prd["PRD"] --> app["用戶控制檯"] + prd --> admin["管理後臺"] + app --> auth["鑑權"] + app --> agent["智能體配置"] + app --> chat["會話對話"] + chat --> llm["模型調用"] + chat --> db["資料庫"] + app --> kb["知識庫接入"] + admin --> logs["調用日誌與平臺概覽"] + logs --> db +``` + +## 第二部分:搭建項目骨架 + +### 2.1 生成前端頁面 + +提示詞參考: + +```text +請基於當前 PRD,幫我生成一個類 Dify 智能體平臺的前端骨架。 + +要求: +1. 用戶側包括:登錄、智能體列表、智能體配置、對話頁、日誌頁、知識庫頁 +2. 後臺側包括:後臺首頁、用戶概覽、資源使用概覽 +3. 先只生成頁面結構和假資料,不接真實接口 +4. 風格要像現代 AI 平臺 +``` + +### 2.2 驗證頁面結構 + +逐項檢查: + +- [ ] 用戶控制檯和管理後臺入口是否分開 +- [ ] 智能體列表、配置、對話、日誌、知識庫頁面是否完整 +- [ ] 管理後臺首頁、用戶概覽頁面是否可訪問 +- [ ] 假資料展示了基本的 UI 狀態 + +## 第三部分:迭代開發 + +### 3.1 按模塊推進 + +在骨架的基礎上,按以下順序逐模塊補充功能: + +1. **鑑權**:註冊、登錄、角色區分 +2. **智能體管理**:創建、編輯、刪除、Prompt 配置 +3. **對話功能**:會話創建、消息收發、模型調用 +4. **日誌記錄**:耗時、token 用量、錯誤記錄 +5. **知識庫接入**(加分項):文檔上傳、檢索、結果注入 +6. **管理後臺**:用戶資料、資源使用、調用統計 + +每完成一個模塊,使用下表進行自檢: + +| 檢查項 | 驗證方法 | +|--------|----------| +| 頁面一致性 | 頁面數量、功能是否符合 PRD | +| 接口閉環 | agents、chat、logs、knowledge 接口是否完整 | +| 權限隔離 | 用戶是否只能管理自己的 agent 和會話 | +| 資料一致性 | messages、logs、documents 資料是否對得上 | +| 可演示性 | 是否能演示"創建 agent → 對話 → 查看日誌"完整鏈路 | + +### 3.2 知識庫接入(加分項) + +如果你想增加知識庫能力,可以給每個智能體增加一個"知識庫開關": + +- 開啟後先檢索知識片段,再和用戶問題一起發送給模型 +- 關閉後按普通對話模式響應 + +第一版不必追求複雜 RAG,只要有"檢索結果可見、調用鏈路可解釋"即可。 + +## 第四部分:聯調與上線 + +### 4.1 端到端測試 + +至少驗證以下場景: + +- 註冊 → 創建智能體 → 配置 Prompt → 發起對話 → 查看日誌 +- 管理員登錄 → 查看用戶資料 → 查看調用統計 + +部署前檢查: + +- [ ] 所有核心接口都做了登錄校驗 +- [ ] 智能體歸屬權限檢查通過 +- [ ] 會話記錄、日誌記錄真實落庫 +- [ ] 模型 Key 使用環境變量,不硬編碼 +- [ ] 錯誤提示可在前端看到,不只打控制檯 + +### 4.2 部署 + +將項目部署到公網環境。部署教程參考:[Git 和 GitHub 工作流](../../backend/git-workflow/)、[如何部署 Web 應用](../../backend/zeabur-deployment/)。 + +## 交付物 + +完成本項目後,你需要提交以下內容: + +- [ ] 可訪問的線上演示鏈接 +- [ ] 源碼倉庫鏈接(含 README) +- [ ] PRD 文檔 +- [ ] 核心頁面截圖(智能體管理頁、對話頁、日誌頁、後臺首頁) +- [ ] 60 秒演示影片(覆蓋創建智能體 → 對話 → 查看日誌) + +README 至少包含:項目簡介、架構說明、技術棧、本地啟動步驟、環境變量清單、接口說明。 + +## 評分標準 + +| 維度 | 基本要求 | 進階要求 | +|------|---------|---------| +| 平臺完整度 | agents / chat / logs 三頁可用 | 有清晰導航與統一設計語言 | +| 業務閉環 | 可創建智能體並真實對話 | 支持多智能體切換與歷史會話 | +| 資料與追蹤 | 消息與調用日誌可查詢 | 有 token / 耗時統計看板 | +| 權限安全 | 僅登錄用戶可訪問核心接口 | 資源歸屬校驗完善 | +| 工程交付 | 可部署、可演示、README 清晰 | 接入知識庫並可解釋檢索結果 | + +## 提交前檢查 + + + + +
    +
  • +
  • +
  • +
  • +
  • +
+
+ +## 參考資料 + +- [UI 設計](../../frontend/ui-design/) +- [使用現代組件庫更新你的界面](../../frontend/modern-component-library/) +- [從資料庫到 Supabase](../../backend/database-supabase/) +- [大模型輔助編寫接口程式碼與接口文檔](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 應用](../../backend/zeabur-deployment/) diff --git a/docs/zh-tw/stage-2/assignments/exam-management-express/index.md b/docs/zh-tw/stage-2/assignments/exam-management-express/index.md new file mode 100644 index 0000000..cb1b745 --- /dev/null +++ b/docs/zh-tw/stage-2/assignments/exam-management-express/index.md @@ -0,0 +1,306 @@ +# 在線考試與管理系統開發實戰 + +## 概述 + +本實戰項目要求你圍繞一份真實的 PRD,從零完成一個在線考試與管理系統。這個項目的特別之處在於它包含多個角色(學生和管理員),每個角色看到的頁面和能執行的操作不同。你將使用 Express 構建後端,實現完整的考試業務鏈路。 + +這是 Stage 2 的綜合實戰環節。多角色權限系統在實際工作中非常常見,掌握這種模式後,你能夠應對教培、SaaS、後臺管理等各類業務場景。 + +## 前置知識 + +在開始本項目之前,你應該已經掌握以下內容: + +- 前端頁面設計與組件庫使用([UI 設計](../../frontend/ui-design/)、[現代組件庫](../../frontend/modern-component-library/)) +- 後端接口設計與開發([接口程式碼編寫](../../backend/ai-interface-code/)) +- 資料庫基礎與 Supabase([從資料庫到 Supabase](../../backend/database-supabase/)) +- Git 工作流與部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 應用](../../backend/zeabur-deployment/)) + +## 學習目標 + +完成本實戰後,你將能夠: + +1. 閱讀並理解一份真實的 PRD,從中提取開發任務清單 +2. 設計多角色系統的權限控制和頁面路由 +3. 使用 Express 實現完整的後端 API +4. 實現考試、提交、自動判分的業務鏈路 +5. 完成端到端聯調,交付一個可演示的業務系統原型 + +## 項目簡介 + +你要構建的產品是一個在線考試與管理系統,包含三個子系統: + +| 子系統 | 職責 | +|--------|------| +| **官網前臺** | 平臺介紹、登錄入口 | +| **學生端** | 考試列表、答題、提交、成績查看 | +| **管理後臺** | 題庫管理、考試管理、提交記錄、成績統計 | + +後端使用 Express,需要支持:登錄鑑權、角色權限、考試和題庫管理、提交流程與自動判分、成績和統計管理。 + +::: tip PRD 入口 +本項目的需求文檔在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-tw/stage-2/assignments/exam-management-express/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 閱讀 PRD + +打開 PRD 文檔,重點回答以下問題: + +- 系統包含哪幾個角色?各自能做什麼? +- 頁面清單是否完整?學生端和管理端分別有哪些頁面? +- 支持哪些題型?每種題型的判分邏輯是什麼? +- 考試的完整流程是什麼?(發佈 → 開始 → 作答 → 提交 → 判分 → 查看成績) + +::: warning +如果以上問題沒有明確答案,不要開始寫程式碼。需求理解不清楚是導致返工的最常見原因。 +::: + +### 1.2 確認系統架構 + +根據 PRD 梳理出系統的整體架構: + +```mermaid +flowchart TD + prd["PRD"] --> web["官網前臺"] + prd --> student["學生端"] + prd --> admin["管理後臺"] + student --> auth["鑑權"] + student --> exam["考試與作答"] + exam --> db["資料庫"] + admin --> question["題庫管理"] + admin --> submission["提交記錄與成績統計"] + question --> db + submission --> db +``` + +## 第二部分:搭建項目骨架 + +### 2.1 生成前端頁面 + +提示詞參考: + +```text +請基於當前 PRD,幫我生成一個在線考試與管理系統的前端骨架。 + +技術棧要求: +- Next.js App Router +- TypeScript +- Tailwind CSS +- shadcn/ui + +頁面清單: +1. 首頁 / +2. 登錄頁 /login +3. 學生考試列表頁 /student/exams +4. 學生答題頁 /student/exams/[id] +5. 學生成績頁 /student/history +6. 管理後臺首頁 /admin +7. 考試管理頁 /admin/exams +8. 題庫管理頁 /admin/questions +9. 提交記錄頁 /admin/submissions + +要求: +- 學生端頁面強調清晰、專注、易答題 +- 管理端頁面使用側邊欄 + 頂部欄佈局 +- 先使用 mock 資料,不接真實接口 +- 注意桌面端和移動端的基本可用性 +``` + +### 2.2 完善學生答題頁 + +答題頁是學生端的核心頁面,重點完善: + +```text +請繼續完善學生答題頁。 + +這是一個在線考試系統的答題頁面,需要包含: +- 頂部顯示考試標題、倒計時、已答題數量 +- 中間顯示題乾和選項 +- 支持單選、判斷、簡答三種題型 +- 左側或頂部有答題卡,顯示每道題是否已作答 +- 點擊提交前彈出確認框 + +先用 mock 資料實現交互,不接真實接口。 + +要求: +- 界面簡潔,不要像後臺表格頁 +- 倒計時要醒目,但不要製造過強壓迫感 +- 有空狀態和 loading 狀態 +``` + +### 2.3 完善管理員後臺 + +管理員後臺第一版聚焦三個核心區域: + +- **考試管理**:創建考試、設置時長、發佈狀態 +- **題庫管理**:新增題目、編輯題目、按題型篩選 +- **提交記錄**:查看學生提交、分數、時間 + +### 2.4 驗證頁面結構 + +逐項檢查: + +- [ ] 學生端和管理端入口是否分開 +- [ ] 登錄頁、考試列表、答題頁、成績頁是否完整 +- [ ] 管理端題庫、考試管理、提交記錄頁是否可訪問 +- [ ] 學生端和管理端的頁面風格有明顯區分 + +### 遇到阻礙? + +如果你在前端搭建階段卡住,可以回顧這些章節: + +- [從資料庫到 Supabase](../../backend/database-supabase/) +- [應用後端接口設計與開發](../../backend/ai-interface-code/) +- [使用現代組件庫更新你的界面](../../frontend/modern-component-library/) + +## 第三部分:後端開發 + +### 3.1 登錄與權限控制 + +```text +請把我當成 0 基礎,幫我完成在線考試系統的登錄與權限控制。 + +後端使用 Express。 + +目標: +1. 學生和管理員都可以登錄 +2. 登錄後返回用戶角色 +3. 學生只能訪問 /student/* 相關接口 +4. 管理員只能訪問 /admin/* 相關接口 +5. 未登錄用戶訪問受保護頁面時跳轉 /login + +實現要求: +- 給出清晰的目錄結構建議 +- 明確說明中間件負責什麼 +- 涉及環境變量的地方不要硬編碼 +- 完成後說明如何驗證權限是否生效 +``` + +### 3.2 考試與題庫管理接口 + +建議按以下模塊實現: + +| 模塊 | 推薦接口 | +|------|----------| +| 考試管理 | `GET /api/exams`、`POST /api/admin/exams`、`PATCH /api/admin/exams/:id` | +| 題庫管理 | `GET /api/admin/questions`、`POST /api/admin/questions` | +| 開始考試 | `POST /api/submissions/start` | +| 提交試卷 | `POST /api/submissions/:id/submit` | +| 成績記錄 | `GET /api/student/history`、`GET /api/admin/submissions` | + +提示詞參考: + +```text +請幫我為在線考試系統設計並實現 Express API。 + +功能範圍: +- 管理員創建考試 +- 管理員維護題庫 +- 學生查看已發佈考試 +- 學生開始考試並創建 submission +- 學生提交答案後自動判分單選題和判斷題 +- 簡答題先標記為待複核 +- 學生查看自己的歷史成績 +- 管理員查看所有提交記錄 + +要求: +- 接口命名清晰 +- 返回統一 JSON 結構 +- 程式碼中區分 controller、service、middleware、db 層 +- 說明每個接口如何測試 +``` + +### 3.3 判分邏輯 + +判分邏輯是考試系統的核心業務規則: + +- **單選題**:用戶答案與標準答案一致則得分 +- **判斷題**:同樣可以自動判分 +- **簡答題**:第一版先只保存答案,分數為空,狀態為 `reviewed = false` + +::: tip 加分項 +如果你想增加 AI 能力,可以讓管理員在後臺輸入"主題 + 難度",由模型先生成一批候選題,再人工審核後入庫。但這屬於加分項,不是必須的。 +::: + +## 第四部分:聯調與上線 + +### 4.1 端到端測試 + +至少驗證以下場景: + +- 學生登錄 → 查看考試列表 → 開始答題 → 提交 → 查看成績 +- 管理員登錄 → 創建考試 → 添加題目 → 發佈 → 查看提交記錄 + +### 4.2 部署 + +- 前端部署到 Vercel / Zeabur +- Express API 部署到 Zeabur / Railway / Render +- 資料庫用 Supabase Postgres 或託管 PostgreSQL + +部署前檢查: + +- [ ] 環境變量是否齊全 +- [ ] 前後端 API 地址是否正確 +- [ ] 登錄態在生產環境是否正常 +- [ ] 管理員賬號是否能真實訪問後臺 +- [ ] README 是否包含啟動、部署、測試說明 + +## 交付物 + +完成本項目後,你需要提交以下內容: + +- [ ] 可訪問的線上演示鏈接 +- [ ] 源碼倉庫鏈接(含 README) +- [ ] PRD 文檔 +- [ ] 核心頁面截圖(首頁、學生考試列表、答題頁、管理後臺) +- [ ] 60 秒演示影片(覆蓋學生答題流程和管理員管理流程) + +README 至少包含:項目簡介、核心頁面說明、技術棧、本地啟動步驟、環境變量清單。 + +## 評分標準 + +| 維度 | 基本要求 | 進階要求 | +|------|---------|---------| +| 頁面完整度 | 學生端和管理端主要頁面都可訪問 | 頁面風格統一,移動端基本可用 | +| 業務閉環 | 學生可登錄、參加考試、提交併查看成績 | 管理員可完整創建併發布考試 | +| 資料正確性 | 提交答案後能寫入資料庫,客觀題能自動判分 | 簡答題支持人工複核或 AI 輔助 | +| 權限控制 | 學生與管理員訪問邊界清晰 | 服務端接口也有角色校驗 | +| 工程交付 | 項目可運行、可部署、README 清晰 | 有演示影片和測試說明 | + +## 提交前檢查 + + + + +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +## 參考資料 + +- [UI 設計](../../frontend/ui-design/) +- [使用現代組件庫更新你的界面](../../frontend/modern-component-library/) +- [從資料庫到 Supabase](../../backend/database-supabase/) +- [大模型輔助編寫接口程式碼與接口文檔](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 應用](../../backend/zeabur-deployment/) diff --git a/docs/zh-tw/stage-2/assignments/modern-landing-page/index.md b/docs/zh-tw/stage-2/assignments/modern-landing-page/index.md new file mode 100644 index 0000000..1dbc50f --- /dev/null +++ b/docs/zh-tw/stage-2/assignments/modern-landing-page/index.md @@ -0,0 +1,211 @@ +# 現代 AI 生圖 SaaS 開發實戰 + +## 概述 + +本實戰項目要求你圍繞一份真實的 PRD(產品需求文檔),從零完成一個參考 Midjourney 體驗的 AI 生圖 SaaS 產品。你將完整經歷需求分析、項目拆解、迭代開發、聯調上線的全過程。 + +這是 Stage 2 的綜合實戰環節。在前面幾章中,你已經分別學習了前端頁面設計、後端接口開發、資料庫操作、支付集成等單項技能——這個項目要求你把它們全部串起來,交付一個可運行的產品原型。 + +## 前置知識 + +在開始本項目之前,你應該已經掌握以下內容: + +- 前端頁面設計與組件庫使用([UI 設計](../../frontend/ui-design/)、[現代組件庫](../../frontend/modern-component-library/)) +- 後端接口設計與開發([接口程式碼編寫](../../backend/ai-interface-code/)) +- 資料庫基礎與 Supabase([從資料庫到 Supabase](../../backend/database-supabase/)) +- 支付集成([Stripe 收費系統](../../backend/stripe-payment/)) +- Git 工作流與部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 應用](../../backend/zeabur-deployment/)) + +## 學習目標 + +完成本實戰後,你將能夠: + +1. 閱讀並理解一份真實的 PRD,從中提取開發任務清單 +2. 基於 PRD 拆分模塊,制定分步推進計劃 +3. 使用 AI 輔助完成前端骨架搭建和後端接口開發 +4. 對每個模塊進行驗證和迭代優化 +5. 完成端到端聯調,將項目從"能跑"推進到"能交付" + +## 項目簡介 + +你要構建的產品是一個現代 AI 生圖 SaaS 平臺,包含三個子系統: + +| 子系統 | 職責 | +|--------|------| +| **官網前臺** | 產品介紹、定價、FAQ、註冊轉化 | +| **用戶工作臺** | Prompt 輸入、圖片生成、圖庫、積分、套餐、社區互動 | +| **後臺管理臺** | 用戶管理、任務管理、支付管理、內容審核、SaaS 指標、系統監控 | + +後端需要支持以下核心能力:用戶鑑權、圖片生成任務、OSS 對象存儲、積分與套餐支付、圖片社交互動、運營資料監控。 + +::: tip PRD 入口 +本項目的需求文檔在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-tw/stage-2/assignments/modern-landing-page/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 閱讀 PRD + +打開 PRD 文檔,重點回答以下問題: + +- 系統有幾個入口?各自覆蓋哪些頁面? +- 每個頁面的核心功能是什麼? +- 後端包含哪些模塊和資料庫表? +- MVP 範圍是什麼?第一版哪些做,哪些不做? + +::: warning +如果以上問題沒有明確答案,不要開始寫程式碼。需求理解不清楚是導致返工的最常見原因。 +::: + +### 1.2 確認系統架構 + +根據 PRD 中的描述,梳理出系統的整體架構: + +```mermaid +flowchart TD + prd["PRD"] --> web["官網前臺"] + prd --> app["用戶工作臺"] + prd --> admin["後臺管理臺"] + app --> auth["鑑權"] + app --> gen["圖片生成任務"] + gen --> oss["OSS 對象存儲"] + gen --> db["資料庫"] + billing["支付與套餐"] --> db + social["分享 / 點贊 / 評論 / 轉發"] --> db + admin --> analytics["SaaS 指標看板"] + admin --> observability["API / DB / Provider 監控"] +``` + +建議你用自己的話把架構圖畫一遍,確認你對系統的理解是完整的。 + +## 第二部分:搭建項目骨架 + +### 2.1 生成前端頁面 + +使用 AI 先生成所有頁面的基本結構和假資料。這一步的目標是搭出資訊架構和路由,不需要接真實接口。 + +提示詞參考: + +```text +請基於當前 PRD,幫我生成一個現代 AI 生圖 SaaS 的前端骨架。 + +要求: +1. 分成三個入口:www、app、admin +2. 官網包括:首頁、定價、FAQ +3. app 包括:登錄、註冊、生成工作臺、圖庫、套餐、積分、社區、作品詳情、個人中心 +4. admin 包括:後臺首頁、用戶管理、任務管理、內容管理、套餐管理、支付訂單、運營配置、SaaS 指標、系統監控 +5. 先只生成頁面結構和假資料,不接真實接口 +6. 風格參考 Midjourney,簡潔、現代、帶產品感 +``` + +### 2.2 驗證頁面結構 + +骨架生成後,逐項檢查: + +- [ ] 三個入口的路由是否獨立(`/`、`/app`、`/admin`) +- [ ] 頁面數量是否與 PRD 一致 +- [ ] 每個頁面是否可以正常訪問和導航 +- [ ] 假資料是否展示了基本的 UI 狀態(列表、空狀態、表單等) + +## 第三部分:迭代開發 + +### 3.1 按模塊推進 + +在骨架的基礎上,按以下順序逐模塊補充功能: + +1. **鑑權**:註冊、登錄、角色區分 +2. **資料庫**:資料表創建、讀寫接口 +3. **核心業務**:圖片生成任務、結果存儲 +4. **OSS 存儲**:圖片上傳與訪問 +5. **支付**:套餐、積分、Stripe 集成 +6. **社交互動**:分享、點贊、評論 +7. **後臺管理**:用戶管理、任務管理、內容審核 +8. **資料監控**:SaaS 指標看板、系統監控 + +每完成一個模塊,使用下表進行自檢: + +| 檢查項 | 驗證方法 | +|--------|----------| +| 頁面一致性 | 頁面數量、入口、功能是否符合 PRD | +| 接口正確性 | 請求參數、返回結構、狀態處理是否合理 | +| 權限隔離 | 普通用戶和管理員是否互相隔離 | +| 資料一致性 | 資料庫、OSS、支付、積分是否對得上 | +| 可演示性 | 是否能給別人完整演示一條業務鏈路 | + +::: tip +如果發現 AI 生成的內容偏離了 PRD,不要整頁推翻重來,直接讓它修改具體模塊即可。 +::: + +### 3.2 角色與分工 + +在迭代過程中,你需要同時扮演三個角色: + +- **產品經理**:確認每個模塊的功能是否符合 PRD +- **技術負責人**:確認實現方案是否合理 +- **測試工程師**:確認功能是否跑得通 + +## 第四部分:聯調與上線 + +### 4.1 端到端測試 + +最後階段的重點不是補新頁面,而是把完整業務鏈路跑通。至少驗證以下場景: + +- 註冊 → 購買積分 → 生成圖片 → 查看歷史 → 分享互動 +- 管理員登錄 → 查看用戶資料 → 查看任務統計 → 查看系統監控 + +### 4.2 部署 + +將項目部署到公網環境,確保: + +- 環境變量配置完整 +- 登錄回調地址正確 +- 支付回調地址正確 +- 頁面無缺失的 loading、空狀態、錯誤提示 + +部署教程參考:[Git 和 GitHub 工作流](../../backend/git-workflow/)、[如何部署 Web 應用](../../backend/zeabur-deployment/)。 + +## 交付物 + +完成本項目後,你需要提交以下內容: + +- [ ] 可訪問的線上演示鏈接 +- [ ] 源碼倉庫鏈接(含 README) +- [ ] PRD 文檔 +- [ ] 核心頁面截圖(官網首頁、生圖工作臺、圖庫、套餐頁、後臺首頁) +- [ ] 60 秒演示影片(覆蓋註冊 → 生成 → 查看 → 後臺管理) + +README 至少包含:項目簡介、核心頁面說明、技術棧、本地啟動步驟、環境變量清單。 + +## 評分標準 + +| 維度 | 基本要求 | 進階要求 | +|------|---------|---------| +| PRD 對齊 | 頁面、功能、資料結構基本符合 PRD | 能清晰說明每個設計決策與 PRD 的對應關係 | +| 產品閉環 | 註冊 → 購買積分 → 生成圖片 → 查看歷史 → 分享互動可跑通 | 支付狀態、積分餘額、生成次數資料一致 | +| 後臺能力 | 用戶、任務、支付、內容管理可查看 | SaaS 指標看板和系統監控頁完整可用 | +| 工程完整度 | 前端、後端、資料庫、OSS、支付鏈路已接通 | 有錯誤處理、空狀態、loading 狀態 | +| 交付質量 | 可部署、可運行 | README 清楚、演示影片結構完整 | + +## 參考資料 + +- [UI 設計](../../frontend/ui-design/) +- [參考 UI 設計規範設計頁面和按鈕](../../frontend/multi-product-ui/) +- [用 LLM 和 Skills 讓界面變好看](../../frontend/llm-skills-beautiful/) +- [從設計原型到項目程式碼](../../frontend/design-to-code/) +- [使用現代組件庫更新你的界面](../../frontend/modern-component-library/) +- [從資料庫到 Supabase](../../backend/database-supabase/) +- [大模型輔助編寫接口程式碼與接口文檔](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 應用](../../backend/zeabur-deployment/) +- [如何集成 Stripe 等收費系統](../../backend/stripe-payment/) diff --git a/docs/zh-tw/stage-2/assignments/movie-recommendation-springboot/index.md b/docs/zh-tw/stage-2/assignments/movie-recommendation-springboot/index.md new file mode 100644 index 0000000..8ce427c --- /dev/null +++ b/docs/zh-tw/stage-2/assignments/movie-recommendation-springboot/index.md @@ -0,0 +1,162 @@ +# Spring Boot 電影推薦系統開發實戰 + +## 概述 + +本實戰項目要求你圍繞一份真實的 PRD,使用 Spring Boot 完成一個帶推薦能力的電影網站。這個項目的核心挑戰在於:它不是簡單的增刪改查,而是需要你思考"用戶行為如何影響推薦結果"以及"推薦如何可解釋"。 + +這是 Stage 2 的綜合實戰環節。你將第一次接觸"內容 + 行為 + 推薦"型產品的開發模式,這種模式在電商、內容平臺、個性化 Feed 等場景中非常常見。 + +## 前置知識 + +在開始本項目之前,你應該已經掌握以下內容: + +- 前端頁面設計與組件庫使用([UI 設計](../../frontend/ui-design/)、[現代組件庫](../../frontend/modern-component-library/)) +- 後端接口設計與開發([接口程式碼編寫](../../backend/ai-interface-code/)) +- 資料庫基礎與 Supabase([從資料庫到 Supabase](../../backend/database-supabase/)) +- Git 工作流與部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 應用](../../backend/zeabur-deployment/)) + +## 學習目標 + +完成本實戰後,你將能夠: + +1. 閱讀 PRD 並從中提取推薦系統的開發任務清單 +2. 使用 Spring Boot 搭建後端項目並實現 RESTful API +3. 設計"用戶行為 → 推薦"的完整資料鏈路 +4. 實現可解釋的推薦邏輯 +5. 完成端到端聯調,交付可演示的產品原型 + +## 項目簡介 + +你要構建的產品是一個帶推薦能力的電影網站: + +| 功能 | 描述 | +|------|------| +| **瀏覽與搜索** | 用戶可以瀏覽和搜索電影 | +| **評分與收藏** | 用戶可以給電影評分、添加收藏 | +| **個性化推薦** | 系統根據用戶行為給出推薦結果 | +| **管理後臺** | 管理員維護電影資料、查看推薦效果 | + +::: tip PRD 入口 +本項目的需求文檔在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-tw/stage-2/assignments/movie-recommendation-springboot/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 閱讀 PRD + +打開 PRD 文檔,重點回答以下問題: + +- 推薦策略是什麼?第一版是否使用可解釋版本(如基於評分相似度)? +- 用戶行為資料要存哪些?(評分、收藏、瀏覽記錄等) +- 管理員需要看哪些推薦效果指標? +- 頁面清單是否完整? + +::: warning +如果以上問題沒有明確答案,不要開始寫程式碼。需求理解不清楚是導致返工的最常見原因。 +::: + +### 1.2 確認系統架構 + +```mermaid +flowchart TD + prd["PRD"] --> web["前端頁面"] + web --> auth["用戶鑑權"] + web --> movie["電影列表 / 詳情"] + web --> behavior["評分 / 收藏"] + behavior --> reco["推薦邏輯"] + reco --> db["資料庫"] + admin["後臺管理"] --> db +``` + +## 第二部分:搭建項目骨架 + +### 2.1 生成前端頁面 + +提示詞參考: + +```text +請基於當前 PRD,幫我生成一個 Spring Boot 電影推薦系統的前端骨架。 + +要求: +1. 頁面包括:首頁、電影列表、電影詳情、推薦頁、個人中心、後臺管理 +2. 先只生成頁面結構和假資料,不接真實接口 +3. 風格要像真實內容產品,而不是課堂 demo +``` + +### 2.2 驗證頁面結構 + +逐項檢查: + +- [ ] 電影列表頁支持搜索和篩選 +- [ ] 電影詳情頁包含評分和收藏按鈕 +- [ ] 推薦頁能展示推薦結果和推薦理由 +- [ ] 管理後臺能展示電影資料和推薦效果 + +## 第三部分:迭代開發 + +### 3.1 按模塊推進 + +1. **Spring Boot 項目搭建**:項目結構、資料庫配置、基礎 CRUD +2. **電影資料管理**:電影列表、詳情、搜索接口 +3. **用戶行為**:評分、收藏接口,行為資料寫入 +4. **推薦邏輯**:基於用戶行為的推薦算法實現 +5. **推薦展示**:推薦結果展示,包含推薦理由 +6. **管理後臺**:電影資料維護、推薦效果查看 + +### 3.2 模塊自檢 + +| 檢查項 | 驗證方法 | +|--------|----------| +| 基礎功能 | 列表、詳情、評分、收藏是否閉環 | +| 推薦聯動 | 用戶行為是否影響推薦結果 | +| 推薦可解釋性 | 用戶能理解為什麼被推薦這些電影 | +| 後臺資料 | 管理員能查看電影資料和推薦效果 | + +## 第四部分:聯調與上線 + +### 4.1 端到端測試 + +至少驗證以下場景: + +- 瀏覽電影 → 評分 → 收藏 → 查看推薦頁,確認推薦結果發生變化 +- 管理員登錄 → 添加電影 → 查看推薦效果統計 + +## 交付物 + +完成本項目後,你需要提交以下內容: + +- [ ] 可訪問的線上演示鏈接 +- [ ] 源碼倉庫鏈接(含 README) +- [ ] PRD 文檔 +- [ ] 核心頁面截圖(電影列表、電影詳情、推薦頁、管理後臺) +- [ ] 60 秒演示影片 + +## 評分標準 + +| 維度 | 基本要求 | 進階要求 | +|------|---------|---------| +| PRD 對齊 | 頁面、功能、資料結構基本符合 PRD | 能清晰說明設計決策 | +| 產品閉環 | 瀏覽 → 評分 → 收藏 → 推薦可跑通 | 評分行為明顯影響推薦結果 | +| 推薦質量 | 推薦結果合理、推薦理由可解釋 | 支持多種推薦策略 | +| 後臺能力 | 電影資料和推薦效果可查看 | 有推薦準確率等統計指標 | +| 工程完整度 | 前端、Spring Boot 後端、資料庫鏈路已接通 | 推薦接口有緩存或性能優化 | + +## 參考資料 + +- [UI 設計](../../frontend/ui-design/) +- [使用現代組件庫更新你的界面](../../frontend/modern-component-library/) +- [從資料庫到 Supabase](../../backend/database-supabase/) +- [大模型輔助編寫接口程式碼與接口文檔](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 應用](../../backend/zeabur-deployment/) diff --git a/docs/zh-tw/stage-2/assignments/simple-grocery-microservices/index.md b/docs/zh-tw/stage-2/assignments/simple-grocery-microservices/index.md new file mode 100644 index 0000000..76c9ed2 --- /dev/null +++ b/docs/zh-tw/stage-2/assignments/simple-grocery-microservices/index.md @@ -0,0 +1,172 @@ +# 生鮮電商微服務系統開發實戰 + +## 概述 + +本實戰項目要求你圍繞一份真實的 PRD,從零完成一個生鮮電商微服務系統。與前面的單服務項目不同,這個項目的後端按業務拆分成多個獨立服務,通過 API 網關統一對外。你將學習如何設計服務邊界、如何處理跨服務的資料一致性問題。 + +這是 Stage 2 的綜合實戰環節。微服務架構在實際工作中非常常見,掌握服務拆分和網關路由的基本思路後,你能夠應對更復雜的後端系統設計。 + +## 前置知識 + +在開始本項目之前,你應該已經掌握以下內容: + +- 前端頁面設計與組件庫使用([UI 設計](../../frontend/ui-design/)、[現代組件庫](../../frontend/modern-component-library/)) +- 後端接口設計與開發([接口程式碼編寫](../../backend/ai-interface-code/)) +- 資料庫基礎與 Supabase([從資料庫到 Supabase](../../backend/database-supabase/)) +- Git 工作流與部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 應用](../../backend/zeabur-deployment/)) + +## 學習目標 + +完成本實戰後,你將能夠: + +1. 閱讀 PRD 並提取微服務系統的開發任務清單 +2. 按業務領域拆分服務邊界(鑑權、商品、庫存、訂單) +3. 設計和實現 API 網關路由 +4. 處理庫存扣減和訂單一致性等跨服務問題 +5. 完成端到端聯調,交付可演示的微服務原型 + +## 項目簡介 + +你要構建的產品是一個生鮮電商微服務系統: + +| 子系統 | 職責 | +|--------|------| +| **用戶端** | 瀏覽商品、下單、查看訂單 | +| **管理端** | 商品管理、庫存管理、訂單管理 | + +後端按業務拆分為以下服務: + +| 服務 | 職責 | +|------|------| +| **API Gateway** | 統一入口、路由轉發、鑑權校驗 | +| **Auth Service** | 用戶註冊、登錄、JWT 頒發 | +| **Catalog Service** | 商品資訊管理 | +| **Inventory Service** | 庫存數量管理 | +| **Order Service** | 訂單創建、狀態管理 | + +::: tip PRD 入口 +本項目的需求文檔在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-tw/stage-2/assignments/simple-grocery-microservices/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 閱讀 PRD + +打開 PRD 文檔,重點回答以下問題: + +- 服務如何拆分?每個服務的職責邊界是什麼? +- 前臺和管理端分別有哪些頁面? +- 下單後庫存扣減的策略是什麼?成功 / 失敗 / 超時各怎麼處理? +- 第一版哪些複雜能力(如分佈式事務、消息隊列)先不做? + +::: warning +如果以上問題沒有明確答案,不要開始寫程式碼。需求理解不清楚是導致返工的最常見原因。 +::: + +### 1.2 確認系統架構 + +```mermaid +flowchart TD + prd["PRD"] --> fe["前端頁面"] + fe --> gw["API Gateway"] + gw --> auth["Auth Service"] + gw --> catalog["Catalog Service"] + gw --> inventory["Inventory Service"] + gw --> order["Order Service"] + order --> inventory +``` + +## 第二部分:搭建項目骨架 + +### 2.1 生成項目結構 + +提示詞參考: + +```text +請基於當前 PRD,幫我生成一個生鮮電商微服務系統的項目骨架。 + +要求: +1. 生成前端用戶端和管理端骨架 +2. 生成 api-gateway、auth-service、catalog-service、inventory-service、order-service 五個目錄 +3. 每個服務先只做最小可運行入口 +4. 先不接真實資料庫和支付 +``` + +### 2.2 驗證項目結構 + +逐項檢查: + +- [ ] 五個服務目錄結構清晰 +- [ ] API Gateway 可以啟動並轉發請求 +- [ ] 各服務健康檢查接口可用 +- [ ] 前端用戶端和管理端頁面可訪問 + +## 第三部分:迭代開發 + +### 3.1 按模塊推進 + +1. **API Gateway**:路由配置、JWT 校驗中間件 +2. **Auth Service**:註冊、登錄、JWT 頒發 +3. **Catalog Service**:商品 CRUD、列表查詢 +4. **Inventory Service**:庫存查詢、庫存扣減 +5. **Order Service**:訂單創建、狀態流轉、庫存聯動 +6. **管理端**:商品管理、庫存管理、訂單管理 + +### 3.2 模塊自檢 + +| 檢查項 | 驗證方法 | +|--------|----------| +| 網關路由 | 各服務接口是否通過網關正確轉發 | +| 權限隔離 | 用戶端和管理端接口是否隔離 | +| 資料一致 | 商品和庫存資料是否同步 | +| 交易閉環 | 下單後庫存扣減、訂單狀態是否一致 | +| 失敗處理 | 庫存不足或超時時是否有補償機制 | + +## 第四部分:聯調與上線 + +### 4.1 端到端測試 + +至少驗證以下場景: + +- 瀏覽商品 → 加入購物車 → 下單 → 查看訂單 +- 管理員 → 添加商品 → 更新庫存 → 查看訂單 + +## 交付物 + +完成本項目後,你需要提交以下內容: + +- [ ] 可訪問的線上演示鏈接 +- [ ] 源碼倉庫鏈接(含 README) +- [ ] PRD 文檔 +- [ ] 核心頁面截圖(商品列表、下單頁、訂單頁、管理後臺) +- [ ] 60 秒演示影片 + +## 評分標準 + +| 維度 | 基本要求 | 進階要求 | +|------|---------|---------| +| PRD 對齊 | 頁面、功能、服務拆分基本符合 PRD | 能清晰說明服務拆分的理由 | +| 產品閉環 | 瀏覽 → 下單 → 庫存扣減 → 查看訂單可跑通 | 訂單超時或庫存不足有補償機制 | +| 服務架構 | 各服務可獨立啟動,通過網關統一訪問 | 服務間通信有錯誤處理和重試 | +| 後臺能力 | 商品、庫存、訂單管理可操作 | 管理端有資料統計 | +| 工程完整度 | 前端、網關、服務、資料庫鏈路已接通 | 有 Docker Compose 或類似編排 | + +## 參考資料 + +- [UI 設計](../../frontend/ui-design/) +- [使用現代組件庫更新你的界面](../../frontend/modern-component-library/) +- [從資料庫到 Supabase](../../backend/database-supabase/) +- [大模型輔助編寫接口程式碼與接口文檔](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 應用](../../backend/zeabur-deployment/) diff --git a/docs/zh-tw/stage-2/assignments/traffic-data-visualization-go/index.md b/docs/zh-tw/stage-2/assignments/traffic-data-visualization-go/index.md new file mode 100644 index 0000000..1e095f9 --- /dev/null +++ b/docs/zh-tw/stage-2/assignments/traffic-data-visualization-go/index.md @@ -0,0 +1,163 @@ +# Go 交通資料分析平臺開發實戰 + +## 概述 + +本實戰項目要求你圍繞一份真實的 PRD,使用 Go 完成一個交通資料分析平臺。這個項目的方向與前面的增刪改查系統不同——你需要構建一條"資料接入 → 聚合 → 告警 → 可視化"的完整資料鏈路。這種資料產品在 IoT、監控、運營分析等場景中非常常見。 + +這是 Stage 2 的綜合實戰環節,也是你第一次接觸 Go 語言。不用擔心,有了前面 JavaScript / TypeScript 的基礎,學習 Go 並不難——重點是理解資料鏈路的設計思路。 + +## 前置知識 + +在開始本項目之前,你應該已經掌握以下內容: + +- 前端頁面設計與組件庫使用([UI 設計](../../frontend/ui-design/)、[現代組件庫](../../frontend/modern-component-library/)) +- 後端接口設計與開發([接口程式碼編寫](../../backend/ai-interface-code/)) +- 資料庫基礎與 Supabase([從資料庫到 Supabase](../../backend/database-supabase/)) +- Git 工作流與部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 應用](../../backend/zeabur-deployment/)) + +## 學習目標 + +完成本實戰後,你將能夠: + +1. 閱讀 PRD 並提取資料產品的開發任務清單 +2. 使用 Go(Gin 或 Fiber)搭建後端 API 服務 +3. 設計資料接入、窗口聚合和告警的完整鏈路 +4. 讓後端資料和前端看板保持一致 +5. 完成端到端聯調,交付可演示的資料產品原型 + +## 項目簡介 + +你要構建的產品是一個 Go 交通資料分析平臺: + +| 模塊 | 職責 | +|------|------| +| **資料接入** | 接收原始交通事件併入庫 | +| **資料聚合** | 按時間窗口計算趨勢和擁堵指標 | +| **告警** | 基於規則生成告警記錄 | +| **看板展示** | 在前端展示趨勢圖、排行榜和告警列表 | + +::: tip PRD 入口 +本項目的需求文檔在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-tw/stage-2/assignments/traffic-data-visualization-go/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 閱讀 PRD + +打開 PRD 文檔,重點回答以下問題: + +- 資料來源是什麼?字段有哪些? +- 核心指標的定義是什麼?(比如"擁堵"的具體標準) +- 告警規則是什麼?第一版是否先收斂到簡單規則? +- 看板包含哪些頁面和圖表? + +::: warning +如果以上問題沒有明確答案,不要開始寫程式碼。需求理解不清楚是導致返工的最常見原因。 +::: + +### 1.2 確認資料鏈路 + +```mermaid +flowchart TD + prd["PRD"] --> ingest["資料接入 API"] + ingest --> raw["原始資料表"] + raw --> agg["聚合任務"] + agg --> alert["告警規則"] + agg --> dashboard["看板接口"] + alert --> dashboard +``` + +## 第二部分:搭建項目骨架 + +### 2.1 生成 Go API 服務 + +提示詞參考: + +```text +請基於當前 PRD,幫我生成一個 Go 交通資料分析平臺骨架。 + +要求: +1. 使用 Gin 或 Fiber +2. 提供資料接入接口 +3. 提供聚合任務骨架 +4. 提供 dashboard 和 alerts 接口骨架 +5. 先不做真實複雜分析,只做可運行結構 +``` + +### 2.2 驗證項目結構 + +逐項檢查: + +- [ ] Go 服務可以正常啟動 +- [ ] 資料接入接口可接收並存儲資料 +- [ ] 聚合任務框架已搭好 +- [ ] 前端看板頁面可展示基本圖表 + +## 第三部分:迭代開發 + +### 3.1 按模塊推進 + +1. **資料接入 API**:接收原始交通事件,寫入資料庫 +2. **資料聚合**:按時間窗口聚合,計算趨勢和擁堵指標 +3. **告警規則**:基於閾值生成告警記錄 +4. **看板接口**:提供趨勢資料、排行資料、告警列表 +5. **前端看板**:趨勢圖、排行榜、告警列表頁面 + +### 3.2 模塊自檢 + +| 檢查項 | 驗證方法 | +|--------|----------| +| 資料接入 | 原始資料是否正確入庫 | +| 聚合口徑 | 趨勢、排名指標的計算邏輯是否一致 | +| 告警規則 | 告警觸發條件是否符合預期 | +| 資料一致性 | 看板展示和後端資料是否對得上 | +| API 規範 | 是否有統一返回結構和錯誤處理 | + +## 第四部分:聯調與上線 + +### 4.1 端到端測試 + +至少驗證以下場景: + +- 接入一批測試資料 → 聚合任務執行 → 看板展示更新 +- 觸發告警條件 → 告警記錄生成 → 告警頁面顯示 + +## 交付物 + +完成本項目後,你需要提交以下內容: + +- [ ] 可訪問的線上演示鏈接 +- [ ] 源碼倉庫鏈接(含 README) +- [ ] PRD 文檔 +- [ ] 核心頁面截圖(資料接入演示、趨勢看板、告警列表) +- [ ] 60 秒演示影片 + +## 評分標準 + +| 維度 | 基本要求 | 進階要求 | +|------|---------|---------| +| PRD 對齊 | 功能和資料結構基本符合 PRD | 能清晰說明指標口徑和聚合邏輯 | +| 資料鏈路 | 接入 → 聚合 → 告警 → 看板可跑通 | 聚合任務支持增量更新 | +| 分析能力 | 趨勢、排行、告警三個模塊可用 | 指標可配置、告警規則可自定義 | +| 前端展示 | 看板能展示基本圖表 | 圖表支持時間範圍篩選 | +| 工程完整度 | Go API、資料庫、前端鏈路已接通 | API 有統一錯誤處理和日誌 | + +## 參考資料 + +- [UI 設計](../../frontend/ui-design/) +- [使用現代組件庫更新你的界面](../../frontend/modern-component-library/) +- [從資料庫到 Supabase](../../backend/database-supabase/) +- [大模型輔助編寫接口程式碼與接口文檔](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 應用](../../backend/zeabur-deployment/) diff --git a/docs/zh-tw/stage-2/assignments/travel-planning-agent-platform/index.md b/docs/zh-tw/stage-2/assignments/travel-planning-agent-platform/index.md new file mode 100644 index 0000000..be69751 --- /dev/null +++ b/docs/zh-tw/stage-2/assignments/travel-planning-agent-platform/index.md @@ -0,0 +1,164 @@ +# 智能旅遊規劃 Agent 平臺開發實戰 + +## 概述 + +本實戰項目要求你圍繞一份真實的 PRD,從零完成一個智能旅遊規劃 Agent 平臺。你將構建一個能接收結構化輸入、生成每日行程、支持保存和重用的完整 AI 產品——不只是聊天機器人,而是一個有任務管理能力的產品。 + +這是 Stage 2 的綜合實戰環節。這個項目的核心挑戰在於:如何讓 AI 生成結構化、可用的行程規劃,而不是一大段不可操作的文字。 + +## 前置知識 + +在開始本項目之前,你應該已經掌握以下內容: + +- 前端頁面設計與組件庫使用([UI 設計](../../frontend/ui-design/)、[現代組件庫](../../frontend/modern-component-library/)) +- 後端接口設計與開發([接口程式碼編寫](../../backend/ai-interface-code/)) +- 資料庫基礎與 Supabase([從資料庫到 Supabase](../../backend/database-supabase/)) +- Git 工作流與部署([Git 和 GitHub](../../backend/git-workflow/)、[部署 Web 應用](../../backend/zeabur-deployment/)) + +## 學習目標 + +完成本實戰後,你將能夠: + +1. 閱讀 PRD 並從中提取 Agent 平臺的開發任務清單 +2. 設計結構化的輸入表單和結構化的輸出格式 +3. 實現 Agent 編排層,處理用戶輸入、模型調用和結果存儲 +4. 構建"生成 → 保存 → 重用"的業務閉環 +5. 完成端到端聯調,交付可演示的 AI 產品原型 + +## 項目簡介 + +你要構建的產品是一個智能旅遊規劃 Agent 平臺: + +| 功能 | 描述 | +|------|------| +| **行程規劃** | 用戶輸入出發地、目的地、日期、預算和偏好,系統生成每日行程 | +| **預算拆分** | 行程結果包含預算分配和建議 | +| **歷史管理** | 用戶可以保存歷史計劃、再次生成、導出 | +| **管理後臺** | 管理員查看熱門目的地、失敗任務和用戶反饋 | + +::: tip PRD 入口 +本項目的需求文檔在 GitHub: [查看 PRD](https://github.com/datawhalechina/easy-vibe/blob/main/docs/zh-tw/stage-2/assignments/travel-planning-agent-platform/PRD.md) +::: + +
+ + + +
+ +## 第一部分:需求分析 + +### 1.1 閱讀 PRD + +打開 PRD 文檔,重點回答以下問題: + +- 第一版是否只做單目的地? +- 行程輸出是否必須結構化?結構是什麼? +- 導出能力做多深?(分享鏈接 / PDF / 圖片) +- 後臺統計和任務日誌的範圍是什麼? + +::: warning +如果以上問題沒有明確答案,不要開始寫程式碼。需求理解不清楚是導致返工的最常見原因。 +::: + +### 1.2 確認系統架構 + +```mermaid +flowchart TD + prd["PRD"] --> planner["規劃頁"] + planner --> agent["Agent 編排層"] + agent --> model["模型調用"] + agent --> db["資料庫"] + db --> history["歷史計劃"] + db --> admin["後臺統計與日誌"] +``` + +## 第二部分:搭建項目骨架 + +### 2.1 生成前端頁面 + +提示詞參考: + +```text +請基於當前 PRD,幫我生成一個智能旅遊規劃 Agent 平臺的前端骨架。 + +要求: +1. 頁面包括:首頁、規劃頁、行程詳情頁、歷史記錄頁、管理頁 +2. 規劃頁左側是表單,右側是結果預覽 +3. 先只生成頁面結構和假資料,不接真實接口 +4. 風格要像現代 AI 產品 +``` + +### 2.2 驗證頁面結構 + +逐項檢查: + +- [ ] 規劃頁的表單字段是否與 PRD 一致 +- [ ] 結果預覽區域能展示結構化的行程資料 +- [ ] 歷史記錄頁可以展示多條計劃 +- [ ] 管理後臺頁可以展示統計資料 + +## 第三部分:迭代開發 + +### 3.1 按模塊推進 + +1. **鑑權**:註冊、登錄 +2. **規劃表單**:結構化輸入(出發地、目的地、日期、預算、偏好) +3. **Agent 編排**:接收輸入 → 調用模型 → 解析結構化輸出 +4. **結果展示**:行程按天展示、預算拆分、建議 +5. **歷史管理**:保存計劃、再次生成、導出 +6. **管理後臺**:熱門目的地、失敗任務、用戶反饋 +7. **任務狀態**:生成中 / 成功 / 失敗的狀態管理和錯誤記錄 + +### 3.2 模塊自檢 + +| 檢查項 | 驗證方法 | +|--------|----------| +| 輸入完整性 | 表單字段是否與 PRD 一致 | +| 輸出結構化 | 行程結果是不是結構化資料(而非一大段文字) | +| 資料一致性 | trip、itinerary、logs 資料是否對得上 | +| 閉環驗證 | 是否能演示"輸入 → 生成 → 保存 → 再次生成" | + +## 第四部分:聯調與上線 + +### 4.1 端到端測試 + +至少驗證以下場景: + +- 輸入行程參數 → 生成每日行程 → 查看預算拆分 → 保存到歷史 +- 從歷史記錄中再次生成行程 +- 管理員查看任務統計和失敗日誌 + +## 交付物 + +完成本項目後,你需要提交以下內容: + +- [ ] 可訪問的線上演示鏈接 +- [ ] 源碼倉庫鏈接(含 README) +- [ ] PRD 文檔 +- [ ] 核心頁面截圖(規劃頁、行程詳情頁、歷史記錄頁、管理後臺) +- [ ] 60 秒演示影片 + +## 評分標準 + +| 維度 | 基本要求 | 進階要求 | +|------|---------|---------| +| PRD 對齊 | 頁面、功能、資料結構基本符合 PRD | 能清晰說明設計決策 | +| 產品閉環 | 規劃 → 保存 → 歷史 → 重生成可跑通 | 支持導出和分享 | +| 輸出質量 | 行程結果結構化且可讀 | 預算拆分合理、建議有針對性 | +| 後臺能力 | 任務統計和失敗日誌可查看 | 有熱門目的地分析 | +| 工程完整度 | 前端、後端、資料庫、模型調用鏈路已接通 | 任務狀態管理完善,錯誤可追溯 | + +## 參考資料 + +- [UI 設計](../../frontend/ui-design/) +- [使用現代組件庫更新你的界面](../../frontend/modern-component-library/) +- [從資料庫到 Supabase](../../backend/database-supabase/) +- [大模型輔助編寫接口程式碼與接口文檔](../../backend/ai-interface-code/) +- [Git 和 GitHub 工作流](../../backend/git-workflow/) +- [如何部署 Web 應用](../../backend/zeabur-deployment/) diff --git a/docs/zh-tw/stage-2/backend/ai-interface-code/index.md b/docs/zh-tw/stage-2/backend/ai-interface-code/index.md new file mode 100644 index 0000000..f6e3ca9 --- /dev/null +++ b/docs/zh-tw/stage-2/backend/ai-interface-code/index.md @@ -0,0 +1,161 @@ +# 大模型輔助編寫接口程式碼與接口文檔 + +在之前的課程中,我們學習瞭如何使用 Figma 等工具完成 UI 設計稿、如何藉助 AI 快速生成前端靜態頁面,以及如何利用 Supabase 構建資料庫並實現初步的用戶身份驗證。現在,一個自然而然的問題擺在了面前:前端頁面中那些動感十足的按鈕點擊後,究竟是如何把資料悄無聲息地存進 Supabase 的?當我們需要執行更復雜的業務邏輯(如併發支付、定時推送、資料敏感處理)時,直接讓前端連接資料庫是安全的嗎? + +這就引出了現代 Web 開發架構中至關重要的一環——**後端 API 接口**。 + +相比於過去純手工敲出成百上千行的後端路由、控制器與參數校驗邏輯,如今我們完全可以藉助大模型的強大程式碼生成能力,將繁雜的基礎程式碼交由 AI 編寫。在本節課中,我們將跳出“AI 寫的又虛又泛”的怪圈,以真實的業務場景為依託,向你展示如何通過高質量的提示詞(Prompt)引導大模型寫出健壯、符合行業規範的 Node.js 後端接口,並自動完成接口文檔與測試用例的生成。 + +> 💡 **前置知識** +> +> 在學習本節之前,建議你先了解以下內容: +> - [從資料庫到 Supabase](../database-supabase/) - 瞭解資料庫和資料模型的概念。 +> - [Git 和 GitHub 工作流](../git-workflow/) - 熟悉如何在項目開發中進行版本控制。 +> - [什麼是終端/命令行](/zh-tw/appendix/2-development-tools/command-line-shell) - 項目初始化與啟動離不開基礎的命令操作。 + +# 你將學到 + +1. **什麼是 API 接口**:理解前後端通信的橋樑與 RESTful 設計規範。 +2. **大模型賦能服務構建**:如何通過結構化的 Prompt 讓 AI 幫你搭建 Node.js + Express 基礎工程。 +3. **接口邏輯開發**:引導大模型生成包含嚴謹業務校驗、對接 Supabase 資料庫的 CRUD(增刪改查)接口。 +4. **自動化接口文檔**:讓大模型根據程式碼逆向生成跨團隊協作標配的 OpenAPI/Swagger 文檔。 +5. **測試與聯調閉環**:利用大模型生成 Postman 測試合集與 Jest 單元測試用例,為程式碼質量兜底。 + +--- + +# 1. 為什麼我們需要 API 接口? + +在傳統的理解中,前端是“看得到的部分”,資料庫是“存東西的倉庫”。但這中間缺少了一個調度員。如果你把整個應用想象成一家餐廳: +- **前端(客戶端)** 是餐廳的菜單和點餐桌,客人在這裡瀏覽菜品並提出需求。 +- **資料庫(Supabase 等)** 是餐廳的後廚倉庫,裡面存放著所有的食材和賬本。 +- **後端 API 接口** 就是餐廳的服務員。客人不能直接衝進後廚拿食材(不僅混亂,而且容易引發安全問題),而是需要把“點單訴求”(HTTP Request)告訴服務員。服務員進行核對(參數校驗、權限鑑權)後,去後廚調取對應的內容,再將“做好的菜”(HTTP Response,通常是 JSON 格式的資料)端回給客人。 + +通過 API 接口,我們實現了明確的**前後端分離**:前端只關心頁面如何渲染,後端只專注於業務邏輯、資料處理與安全防護。 + +--- + +# 2. 項目架構設計與初始化 + +一個結構清晰的項目骨架,是大模型能寫出好程式碼的先決條件。我們在讓 AI 寫程式碼前,自己心裡必須對工程結構有個底。 + +## 2.1 常見的 API 工程結構 +即使是使用大模型生成程式碼,我們也絕不能把所有程式碼都塞進一個 `server.js` 文件中。一個易於維護的 Node.js 後端架構通常如下所示: + +```text +my-api-project/ +├── .env # 敏感環境變量(如 API Keys、資料庫連接串) +├── server.js # 項目入口(服務器啟動、全局中間件註冊) +├── package.json # 依賴管理文件 +├── src/ +│ ├── routes/ # 路由層:定義 URL 路徑與請求方法 +│ ├── controllers/ # 控制器層:處理業務請求參數,調用服務並返回響應 +│ ├── services/ # 服務層:封裝資料庫交互和核心業務邏輯 +│ └── middlewares/ # 中間件:登錄鑑權、錯誤全局捕獲 +└── docs/ # API 文檔存放目錄 +``` + +## 2.2 藉助 AI 完成工程初始化 +與其手動 `npm init` 並一個個安裝依賴,不如直接將上述規範以 Prompt 的形式餵給大模型: + +> 🗣️ **給大模型的提示詞(Prompt 示例):** +> "幫我搭建一個 Node.js 後端項目,要能連接 Supabase 資料庫,結構清晰一點,方便以後維護。" + +運行 AI 返回的程式碼後,你就能在 `localhost:3000` 獲得一個具備企業級雛形的後端應用了。 + +--- + +# 3. 核心實戰:大模型輔助接口開發 + +這是本章節最核心的部分。大模型寫出的程式碼往往容易存在“邏輯漏洞”或“表面敷衍”,原因在於開發者給的上下文不足。**大模型不怕需求複雜,最怕需求模糊。** + +以我們在 [資料庫章節](../database-supabase/) 中提到的 `menu_items` (菜單表) 的新增接口為例,看如何寫出一份高質量的 Prompt。 + +## 3.1 賦予大模型完整上下文 +在請求 AI 寫接口之前,一定要提供**資料庫字段定義(Schema)**和**具體的約束條件**。 + +> 🗣️ **高質量提示詞(Prompt)模板:** +> "幫我寫一個新增菜單的接口,菜單有商品名、價格、分類(漢堡、小食、飲料)、是否上架這幾個資訊。商品名和價格必須填,價格不能是負數。用戶輸入不對的時候要提示錯誤。" + +## 3.2 審查大模型生成的程式碼 +大模型生成的程式碼通常會像下面這樣清晰地拆分了職責: + +```javascript +// services/menuService.js +const { createClient } = require('@supabase/supabase-js'); +const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY); + +exports.createMenuItem = async (menuData) => { + // 調用 Supabase SDK 將資料推入表內 + const { data, error } = await supabase + .from('menu_items') + .insert([menuData]) + .select(); + + if (error) throw new Error(`資料庫插入失敗: ${error.message}`); + return data[0]; +}; +``` + +你可以發現,通過這種方式生成的程式碼,不僅結構合理,而且將 Supabase 的初始化、錯誤捕獲以及異常處理都考慮在內,這與簡單要求“寫個新增接口”得到的麵條式程式碼(Spaghetti Code)有著天壤之別。 + +--- + +# 4. 解放雙手:自動生成接口文檔 + +對於開發團隊而言,沒有文檔的 API 就是一個盲盒。前端工程師無法猜測你需要傳入什麼參數,也不能預測會返回什麼結構。業界最通用的 API 描述規範是 **OpenAPI (此前也稱 Swagger)**。 + +過去,手寫 YAML 或者 JSON 格式的 Swagger 文檔極其痛苦且容易出錯。現在,這也成了大模型最擅長的領域。 + +你可以直接選中你剛才寫的 `routes` 和 `controllers` 程式碼,然後丟給大模型: + +> 🗣️ **生成文檔的提示詞:** +> "幫我根據上面的程式碼生成一份接口文檔,要寫清楚每個參數是什麼意思、返回什麼資料,方便前端同事對接。" + +在這個過程中,你甚至可以要求 AI 補全字段的說明(Description)和 Mock 資料(如 `price_cents: 1200` 代表 12 美元),極大地降低了溝通成本。 + +--- + +# 5. 保駕護航:生成測試程式碼與 Postman 集合 + +程式碼寫好、文檔出爐,還差最後一步:驗證程式碼到底能不能跑通。 + +## 5.1 生成 Postman / Apifox 測試配置 +在接口開發中,我們通常使用 Postman 這樣的可視化工具來模擬前端發送 HTTP 請求。如果不使用大模型,你需要手動填入 URL、逐個添加 Header(請求頭)以及拼接 JSON 請求體。 + +你只需向 AI 發送指令: +> "幫我把這份接口文檔轉成 Postman 可以導入的格式,要包含正常請求和錯誤請求的例子。" + +拿到 JSON 文本後,保存為 `menu_api.json` 並拖入 Postman,你瞬間就獲得了一套開箱即用的測試點擊面板。 + +## 5.2 編寫自動化單元測試 +如果你追求更嚴謹的工程質量,可以讓大模型幫你使用 `Jest` 等測試框架編寫單元測試(Unit Tests),對核心業務邏輯進行邊界測試(比如傳入負數價格時,資料庫層的校驗是否生效)。 + +--- + +# 6. 後端接口必知的最佳實踐 + +即使有 AI 的協助,作為整個系統的“把關人”,你依然需要了解並審核以下這些核心準則: + +1. **RESTful 規範的路徑命名**: + - 好的設計:`GET /api/users`(獲取用戶列表)、`POST /api/users`(創建用戶)。URL 應該代表“資源”的名詞。 + - 錯誤的設計:`POST /api/getUser` 或 `POST /api/createUser`。動詞應該交由 HTTP Method (GET/POST/PUT/DELETE) 來體現。 +2. **規範的 HTTP 狀態碼**: + - 200/201:請求成功 / 資源創建成功。 + - 400:Bad Request,前端傳參格式錯誤、少傳了必填項。 + - 401/403:Unauthorized / Forbidden,用戶未登錄或無權操作。 + - 404:NotFound,資源不存在。 + - 500:Server Error,後端程式碼報錯或資料庫掛了,絕對儘量避免將報錯調用棧直接暴露給前端(會有安全隱患)。 +3. **永遠不信任用戶的輸入**:前端的輸入可能是偽造的,所有核心參數校驗必須在後端接口中再做一次。 + +# 7. 總結 + +通過本章節的學習,你實現了開發視角的真正轉變:你不再是被困在語法和標點符號中的“打字員”,而是上升成為了**系統設計師和架構指揮官**。 +你已經掌握了: +1. **API 接口與前後端分離**的核心繫統思維。 +2. **如何通過提供上下文與分層結構理念**,大幅提高大模型生成服務端程式碼的質量。 +3. 把繁瑣的**文檔編寫**和**測試用例構建**,巧妙地轉化為 AI 擅長的自動化任務。 +4. 結合此前學過的 **Supabase** 知識,打通了從客戶端請求到底層資料庫更新的完整資料流。 + +::: tip 💡 下一步 +當你的資料流和後端服務都準備就緒後,它目前還只能在你的本地電腦上“自娛自樂”。在接下來的章節中,我們將學習如何把這套辛辛苦苦建立的服務**部署(Deploy)到公網服務器上**,讓你的產品能被全世界的用戶訪問。 +::: \ No newline at end of file diff --git a/docs/zh-tw/stage-2/backend/database-supabase/index.md b/docs/zh-tw/stage-2/backend/database-supabase/index.md new file mode 100644 index 0000000..4fa2f72 --- /dev/null +++ b/docs/zh-tw/stage-2/backend/database-supabase/index.md @@ -0,0 +1,1742 @@ +# 從資料庫到 Supabase + +在上節課中,我們學會了 UI 設計程序 Mastergo 和 Figma 的基本用法,能夠使用 github 進行程式碼的獲取與版本管理,並通過 Zeabur 部署網站將自己的應用 / 網站傳達給更多人使用。 + +為了幫助大家更好地銜接知識,在開始本節課關於設計工具與部署的新內容前,讓我們一起通過幾道簡單的題目快速回顧一下上節課的核心知識點: + +1. 什麼是前端設計工具、Figma、MasterGo 的定義和使用方式。 +2. 將設計稿轉換為程式碼的基礎方法。 +3. 什麼是 Github,如何配置 SSH,如何構建自己的第一個倉庫。 +4. 部署是什麼意思,如何使用 Zeabur,如何將 Github 或本地程式碼部署至公共網路給大家訪問。 + +如果對以上任何一個問題還有印象模糊的地方,建議先回顧一下上節課的文檔和講義。歡迎隨時在微信學習群中提出疑問。 + +在本節課中,我們將學習如何讓一個 APP / 網站從能跑起來變為更接近真實線上產品:除了用資料庫管理程序運行中的各種資料變化外,還要具備完善的用戶體系(註冊、登錄、權限等)以及其他關鍵後端能力。我們會以 Supabase 這一後端服務平臺為主線,先用它實現“資料庫 + 用戶系統”這兩項基礎功能,再以 Supabase 提供的組件為參照,進一步理解現代雲服務後端服務通常包含的核心模塊,以及各模塊的具體職能與作用邏輯。 + +# 你將學到 + +1. 什麼是資料、什麼是資料庫,常見資料庫與使用方法 +2. 什麼是 supabase,如何使用 supabase 進行基礎的資料庫操作 +3. 如何使用 supabase 為應用添加基礎用戶管理功能 +4. 學會 Supabse 進階功能:realtime、storage、edge function +5. 學會為Supabase增加 google 與 github 登錄支持 + +- 一款支持用戶註冊 / 登錄,並能將資料存入在線資料庫的基礎應用 +- 一套可複用的 Supabase 後端程式碼模板(資料庫 + 用戶管理等),供後續項目直接套用 + +# 1. 什麼是資料庫 + +## 1.1 什麼是資料 + +在數字世界裡,資料(Data)無處不在。簡單來說,資料是資訊的載體。你朋友的聯繫方式、一篇微信文章、一條短影片、遊戲裡的角色等級,這些都是資料。在我們的應用中,資料就是需要被記錄和管理的一切資訊,比如用戶的個人資料、訂單歷史、程序設置等。 + +一般而言,資料在程序中有不同的表現形式,最簡單的就是變量,我們可以用不同變量記錄簡單的數字: + +```python +# Python variable definition examples + +# Integer variable: stores age information +age = 30 + +# Boolean variable: stores status (whether active) +is_active = True # True means active, False means inactive + +# List variable: stores a set of score data +scores = [85, 92, 78, 90] # Contains 4 integer elements representing different scores + +# Dictionary variable: stores multiple related information of a user +user_info = { + "age": 30, # Key "age" corresponds to the value of age + "height": 1.80, # Key "height" corresponds to the value of height (unit: meter) + "login_count": 156 # Key "login_count" corresponds to the value of login times +} +``` + +而對於上述所說的個人資料、訂單歷史這類複雜的資料而言,我們可以用更復雜的表格進行資料的表示: + +| user_id | name | email | +| ------- | ----- | ----------------- | +| 1001 | Alice | alice@example.com | +| 1002 | Bob | bob@example.com | + +| order_id | user_id | amount | status | +| -------- | ------- | ------ | --------- | +| 901 | 1001 | 29.99 | completed | +| 902 | 1002 | 15.50 | pending | + +但對於結構複雜、具有層級關係或字段不固定的資料,我們可以用 JSON 格式進行描述 —— 它是互聯網通用的資料中間格式,幾乎所有程序都能讀取解析,跨系統傳資料很方便。例如,一個訂單可能包含多個商品,每個商品又有自己的名稱、數量和價格。用傳統的表格來表示會很笨拙:要麼得拆成 “訂單表”“商品表” 多張表,靠關聯字段才能體現 “訂單包含商品” 的關係;要麼在一張表用 “商品 1 名稱、商品 1 價格、商品 2 名稱……” 這類冗餘字段,遇到商品數量不固定時根本沒法適配;而 JSON 能直接用嵌套結構把 “訂單 - 商品 - 商品屬性” 的層級說清,既直觀又靈活。 + +```json +{ + "order_id": 901, + "user_id": 1001, + "amount": 29.99, + "status": "completed", + "items": [ + { "sku": "BG-001", "name": "牛肉漢堡", "quantity": 1, "price": 18.00 }, + { "sku": "SD-003", "name": "炸薯條", "quantity": 1, "price": 6.99 }, + { "sku": "DK-002", "name": "可樂", "quantity": 1, "price": 5.00 } + ], + "shipping_address": { + "street": "科技園路123號", + "city": "深圳", + "zip_code": "518057" + } +} +``` + +更進一步的,如果我們考慮一個被編碼成向量(Vector)的資料,向量資料通常是文本、圖片或音頻等非結構化資料經過 AI 模型(如 Embedding 模型)處理後得到的數值表示。它的表示形式可能是: + +`[0.123, -0.456, 0.789, ..., -0.234]` (一個由幾百甚至上千個浮點數組成的數組) + +總的來說,在現實世界中有太多不同形態、用途的資料值得我們詳細分析,每種資料可能都需要專門的資料庫用於存儲,具體可參考下圖——是不是感覺非常多? + +![](/zh-cn/stage-2/backend/database-supabase/images/image1.png) + +## 1.2 為什麼我們需要資料庫 + +我們已經瞭解到真實世界中的資料往往結構複雜,**為了高效存儲與使用這些資料,我們需要一個專門的程序或容器來管理它們** —— 這便是資料庫(Database)的誕生初衷。資料庫本質上是一款特殊程序,核心作用就是對資料進行規範化組織、安全存儲、系統化管理,並支持高效查詢調用。 + +想象一下,若沒有資料庫,應用資料會陷入怎樣的困境?當用戶關閉瀏覽器或退出應用時,所有臨時加載的資訊都會直接丟失;我們既無法永久保存用戶的使用狀態(比如登錄資訊、個性化設置),也沒法在不同用戶之間共享關鍵資料(比如商品庫存、訂單記錄)。我們需要有一個裝置幫我們存儲所有的資料! + +更靈活的是,資料庫的部署方式可按需選擇:既可以部署在本地服務器,滿足資料本地化管理的需求;也能部署到雲端,雲端資料庫支持彈性擴容(Scale),可隨資料量與訪問量增長擴展能力、承載海量資料與高併發,即便用戶量大幅提升,也能保障用戶的正常使用體驗。 + +歸納而言,資料庫憑藉高效的持久化存儲、精細化管理與快速查詢能力,主要解決了以下核心問題: + +- **資料的持久化存儲** : 如果沒有資料庫,資料將僅存在於應用的內存中,一旦應用關閉,資料就會丟失。資料庫解決了這個問題,它將資料持久地存儲在硬盤等存儲介質上,確保了資料的長期保存,降低了丟失風險。 +- **便捷的資料查詢與分析** : 資料庫提供了強大的查詢語言(如 SQL),讓用戶可以輕鬆、高效地對海量資料進行復雜的查詢、篩選和分析,從而幫助企業做出更明智的決策。 如果沒有資料庫,從大量無序文件中查找特定資訊將是一項極其耗時且困難的任務。 +- **支持高性能與高併發訪問** : 資料庫通過索引優化、查詢緩存、連接池以及分佈式架構等技術,能夠在毫秒級時間內響應查詢請求,並支撐成千上萬用戶的併發訪問。這對於現代互聯網應用(如電商平臺秒殺活動、社交網路實時動態)至關重要,確保了系統的響應速度和用戶體驗。如果沒有資料庫的高性能支撐,面對海量用戶請求時系統將會出現嚴重延遲甚至崩潰。 +- **保證資料的完整性和一致性** : 資料庫通過一系列機制(如約束、觸發器)來確保資料的準確性和一致性。 這意味著資料庫中的資料必須符合預設的規則,例如,用戶的年齡必須是數字,訂單號必須是唯一的,從而有效防止了非法或無效資料的產生。 +- **確保資料的安全性** : 資料庫提供了強大的安全機制,包括用戶身份驗證、訪問控制和資料加密等,以保護資料免受未經授權的訪問、修改或破壞。為了應對硬體故障、人為失誤或惡意攻擊等意外情況,資料庫還提供了資料備份和恢復功能。 通過定期備份,可以在資料丟失或損壞時及時恢復,保障了業務的連續性。 + +## 1.3 關係型資料庫與非關係型資料庫 + +前面我們已經瞭解了資料庫的核心價值、部署方式與彈性優勢,而在實際選擇時,首先要面對的就是資料庫的兩大核心類別:關係型資料庫與非關係型資料庫(NOSQL),我們可以用簡單的兩段話簡單理解他們的區別: + +關係型資料庫就像結構嚴謹的Excel表格,所有資料必須預先定義好格式(定義好 Schema 的內容, 比如要有姓名和年齡,且姓名必須是文字,年齡必須是數字),並通過關聯字段(用來連接不同表格的標識,如身份證號)將不同表格連接起來。它的好處是資料精確可靠,特別適合銀行轉賬、庫存管理等不能出錯的場景,但缺點是調整結構比較麻煩,海量資料下性能會受限。 + +非關係型資料庫則像靈活的文件夾,可以存放格式各異的文檔、圖片或鍵值對(類似字典的"詞-解釋"結構),不需要提前規定好每份資料的結構。它更容易應對快速變化的需求和超大規模資料(比如社交媒體的海量帖子),擴展(增加服務器提升性能)起來也更方便,但犧牲了部分關聯查詢能力(跨不同資料表整理資訊的能力)和一致性保障(確保資料時刻準確不矛盾),適合對容錯性要求較高的互聯網應用。 + +那麼,實際應用中該如何選擇資料庫?從場景劃分總結來看,關係型資料庫常見於金融交易、庫存管理、訂單處理、賬務系統等需要強一致性、複雜事務處理以及頻繁讀寫均衡訪問的場景;而非關係型資料庫更適配社交媒體內容存儲、實時日誌分析、物聯網海量資料寫入、推薦系統特徵讀多寫多等高併發、讀寫模式不均衡且結構靈活的需求。 + +但對於企業而言,在初級階段並不需要花大量時間思考什麼需要使用什麼資料庫。當前的資料庫已是非常成熟的產品服務,最直接的方式是諮詢不同雲服務廠商(指提供服務器、存儲、資料庫、軟體、算力等 IT 資源與技術服務的服務商)。我們可直接對接雲服務官方銷售,根據自身產品業務需求匹配適配的資料庫方案;而構建企業級應用的便捷路徑,便是優先與專業廠商合作。(需注意:企業級服務價格通常較高,建議先多方調研對比,也可選擇購買服務器自行部署開源資料庫程序作為替代方案。) + +我們也可參考某家雲廠商的[資料庫選型推薦](https://help.aliyun.com/zh/govcloud/getting-started/select-database-services),根據場景可進行不同資料庫類型的選擇,你可以對比不同雲廠商的資料庫規格選出最合適的進行使用。 + +| 資料庫類型 | 資料庫名稱 | 價格 | 適用場景 | +| ------------ | ---------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 關係型資料庫 | RDS MySQL版 | 低 | 基礎版:學習以及小型網站高可用版:一定業務壓力的中型資料庫場景集群版:業務不允許中斷,訪問壓力較大 | +| | RDS SQL server版 | 高 | 基礎版:測試以及小型商業化網站高可用版:企業級商業化網站集群版:企業業務不允許中斷,訪問壓力較大 | +| | RDS PostgreSQL版 | 最低 | 基礎版:學習以及小型網站高可用版:一定業務壓力的中型資料庫場景集群版:業務不允許中斷,訪問壓力較大的場景,其性能較一般MySQL高 | +| | RDS PPAS版 | 高 | 通用型:兼容Oracle業務,但業務壓力Udacity,虛擬化可以滿足其需求獨享型:面對需要獨享物理機的業務,一般為高併發Oracle類業務 | +| | DRDS | 中 | 入門版本:4 Core 8 G,價格親民,適合中小型在線業務企業版:16 Core 32 G,複雜 SQL 響應好,適合超高併發在線業務至尊版:32 Core 64 G,複雜 SQL 執行響應最好,提供超大規格選擇 | +| NoSQL資料庫 | Redis | 中 | 雙機熱備Redis:一般作為持久化資料庫提高業務可用性集群版本的Redis:一般作為緩存層,加速應用訪問,解決一般資料庫無法負載的讀取壓力 | +| | MongoDB版 | 中 | 單節點實例單節點:適用於開發、測試及其他非企業核心資料存儲的場景副本集實例:適用於某些業務場景下對資料庫有更高讀取性能需求,如閱讀類網站、訂單查詢系統等讀多寫少場景或有臨時活動等突發業務需求分片集群實例:基於多個副本集(每個副本集沿用三副本模式)組成的分片集群實例,提供更高的讀取性能需求,為實時在線業務提供高速讀取性能 | + +光說不易理解,我們通過一個具體的“博客文章”場景,來看看同樣的資料在關係資料庫 (SQL) 和不同類型的非關係資料庫 (NoSQL) 中是如何存儲的。 + +假設我們有一個博客平臺,需要存儲以下資訊: + +- 用戶(Users):用戶 ID、用戶名、郵箱 +- 文章(Posts):文章 ID、標題、內容、作者 ID +- 評論(Comments):評論 ID、評論內容、評論者 ID、所屬文章 ID +- 標籤(Tags):標籤 ID、標籤名 +- 文章與標籤的關係:單篇文章關聯的多個標籤、單個標籤對應的多篇文章 + +### 關係資料庫 (SQL) 示例 + +在SQL資料庫中,我們會將不同類型的資料分別存儲在不同的表中,並通過“外鍵”將它們關聯起來。這種結構清晰、規範,減少了資料冗餘。 + +以 “內容平臺的文章管理” 為例,我們不會把 “用戶、文章、評論、標籤” 混存,而是拆成 5 張功能單一的表,每張表都有明確的 “職責邊界” 和嚴格的結構定義(Schema): + +- `users` 表 (存儲用戶資訊) + +| user_id (主鍵) | username | email | +| -------------- | -------- | ----------------- | +| 101 | Alice | alice@example.com | +| 102 | Bob | bob@example.com | + +- `posts` 表 (存儲文章資訊) + +| post_id (主鍵) | title | content | author_id (外鍵) | +| -------------- | --------- | ------------------------------ | ---------------- | +| 1 | 初識SQL | 這是關於SQL資料庫的一篇文章... | 101 | +| 2 | NoSQL入門 | NoSQL提供了靈活的資料模型... | 102 | + +- `comments` 表 (存儲評論資訊) + +| comment_id (主鍵) | body | commenter_id (外鍵) | post_id (外鍵) | +| ----------------- | ---------------- | ------------------- | -------------- | +| 1001 | 寫得很棒! | 102 | 1 | +| 1002 | 學習了。 | 101 | 2 | +| 1003 | 有沒有更多例子? | 101 | 1 | + +- `tags` 表 (存儲標籤) + +| tag_id (主鍵) | tag_name | +| ------------- | -------- | +| 51 | 資料庫 | +| 52 | 技術 | +| 53 | 入門 | + +- `post_tags` 表 (存儲文章與標籤的多對多關係,體現聯表特點) + +| post_id (外鍵) | tag_id (外鍵) | +| -------------- | ------------- | +| 1 | 51 | +| 1 | 52 | +| 2 | 51 | +| 2 | 52 | +| 2 | 53 | + +若需查詢 “Alice 發表的《初識 SQL》(post_id=1)的完整資訊(含文章內容、作者、評論、標籤)”,需執行多表連接(JOIN)查詢,通過外鍵關聯 5 張表並聚合資料,SQL 語句如下: + +```sql +SELECT + p.title, + p.content, + u.username AS author, + c.body AS comment, + t.tag_name AS tag +FROM + posts p +JOIN + users u ON p.author_id = u.user_id +LEFT JOIN + comments c ON p.post_id = c.post_id +LEFT JOIN + post_tags pt ON p.post_id = pt.post_id +LEFT JOIN + tags t ON pt.tag_id = t.tag_id +WHERE + p.post_id = 1; +``` + +這個查詢會跨越5個表,將所有相關資料聚合在一起返回。這是關係資料庫的核心優勢:通過規範化和連接操作,可以靈活地進行各種複雜的查詢,同時保證了資料的一致性和最小冗餘。 + +### 非關係資料庫 (NoSQL) 示例 + +NoSQL 資料庫(如 MongoDB、Redis)的設計思路與 SQL 相反,它不強調資料的拆分與規範,通常會將業務上相關聯的所有資料打包聚合在一起,以減少查詢時的連接操作,從而提高讀取性能。 + +在 NoSQL 資料庫中,文檔資料庫(Document Database) 是最常用的類型之一,MongoDB 就是典型代表。它以 “文檔” 作為基本存儲單元,這裡的 “文檔” 並非我們日常理解的 “文章”,而是一種類似 JSON 的資料結構(MongoDB 中實際使用 BSON 格式,支持更多資料類型):無需預先定義統一的 Schema(資料結構),每個文檔的字段可以靈活增減,字段類型也能自由調整,完美適配資料格式多變的場景。 + +在文檔資料庫中,通常會將一篇文章及其所有相關資訊(如評論、標籤)存儲在一個文檔中(文檔格式類似 JSON,可靈活定義字段,無需預先制定 Schema),核心邏輯是 “將‘一個業務場景下的完整資訊’存放在一個文檔中”,避免查詢時的多資料源拼接。 + +`posts` 集合中的一個文檔示例: + +```json +{ + "_id": 1, + "title": "初識SQL", + "content": "這是關於SQL資料庫的一篇文章...", + "author": { + "user_id": 101, + "username": "Alice", + "email": "alice@example.com" + }, + "tags": [ + "資料庫", + "技術" + ], + "comments": [ + { + "comment_id": 1001, + "body": "寫得很棒!", + "commenter": { + "user_id": 102, + "username": "Bob" + } + }, + { + "comment_id": 1003, + "body": "有沒有更多例子?", + "commenter": { + "user_id": 101, + "username": "Alice" + } + } + ] +} +``` + +這種設計的優勢非常直觀:當你需要獲取 “第一篇文章的完整資訊(含作者、評論、標籤)” 時,只需通過 `_id:1` 查詢這一個文檔,資料庫一次讀取就能返回所有資料,無需像 SQL 那樣執行 3-4 次表連接操作,讀取效率大幅提升。 + +但它也存在明顯的 trade-off(取捨):由於資料是 “聚合存儲”,會不可避免地產生資料冗餘—— 比如作者 “Alice” 的 `username` 被嵌入到她寫的每一篇文章文檔中,如果某天 “Alice” 將用戶名改為 “Alice_New”,理論上需要遍歷所有包含她資訊的文章文檔,逐一更新 `author.username` 字段,不僅操作繁瑣,還可能因網路或服務器問題導致部分文檔更新失敗,出現 “同一用戶在不同文章中用戶名不一致” 的情況。 + +不過在實際業務中,這種冗餘往往是 “可接受的”:對於博客、資訊、電商商品詳情等 “ **讀多寫少** ” 的場景(用戶查看內容的次數遠多於作者修改用戶名的次數),用少量的冗餘換取 “極致的讀取性能” 是更優的選擇;而如果是 “寫多讀少”(如頻繁修改用戶資訊)的場景,則需要結合業務需求權衡是否使用文檔資料庫。 + +以上是對不同資料庫的簡單介紹,如果你對更多具體的資料庫類型感興趣,你可以參考如下資料嘗試不同類型的資料庫。 + +Examples of SQL databases: +[Db2](https://www.ibm.com/products/db2-database)、[MySQL](https://cloud.ibm.com/catalog#highlights)、[PostgreSQL](https://www.ibm.com/think/topics/postgresql)、[YugabyteDB](https://www.yugabyte.com/)、[CockroachDB](https://www.cockroachlabs.com/)、[Oracle Database](https://www.ibm.com/products/postgres-enterprise)、[Azure SQL Database](https://www.ibm.com/consulting/microsoft) + +Examples of NoSQL databases: +[Redis](https://www.ibm.com/think/topics/redis)、[CouchDB](https://www.ibm.com/think/topics/couchdb)、[MongoDB](https://www.ibm.com/think/topics/mongodb)、[Cassandra](https://cloud.ibm.com/catalog#highlights)、[Elasticsearch](https://www.ibm.com/think/topics/elasticsearch)、[BigTable](https://www.techtarget.com/searchdatamanagement/news/252512583/Google-scales-up-Cloud-Bigtable-NoSQL-database)、[Neo4j](https://neo4j.com/users/ibm/)、[HBase](https://www.ibm.com/think/topics/hbase) + +# 2. Supabase + +在前面我們已經介紹了幾類常見的資料庫,以及它們各自適合的使用場景。不過在真實項目裡,資料庫通常只是後端體系中的一個基礎模塊:除了存儲和查詢資料,你還需要解決**用戶註冊登錄、權限校驗、文件上傳與存儲、對外 \*\***API\***\* 接口、甚至定時任務、實時通知**等一整套問題。僅僅選好資料庫,並不能讓你的應用“立刻就能上線運行”,中間還隔著一大圈繁瑣的後端工程工作。 + +所以,我們需要考慮一個更大的背景: **後端服務** 。一個完整的應用,通常都由“前端 + 後端”組成:前端負責頁面展示和用戶交互,後端則負責資料存儲、用戶登錄、業務邏輯處理等。過去,開發者往往需要自己搭建服務器、配置資料庫、設計並實現 API,還要手動處理權限管理、安全策略、擴展性和監控運維等事務,整個過程既重複又耗時。為了解決這些重複勞動,業界出現了 **BaaS(Backend as a Service,後端即服務)** :把資料庫、用戶認證、文件存儲、實時能力等常見後端功能打包成一個雲端平臺,開發者通過 SDK / API 就能直接調用這些能力,而無需從零搭建和運維基礎設施。 + +在這個背景下,[Supabase](https://supabase.com/) 就可以看作是新一代的 BaaS 代表:它以 PostgreSQL 作為核心資料庫,在其之上集成了 Auth、Storage、Realtime、Edge Functions、Vector 等一整套後端能力,為開發者提供一個“以 Postgres 為中心的一站式後端平臺”。接下來,我們就從這個角度出發,從“只選資料庫”升級到“選擇完整的後端開發平臺”,具體看看 Supabase 能幫我們省掉哪些工作,又是如何讓一個項目從原型到可用產品的距離大幅縮短的。 + +## 2.1 分步指南 + +在清晰把握 Supabase 的整體定位後,接下來我們將沿著 Supabase 控制檯的操作路徑,逐項拆解它具體提供哪些核心能力,以及每項能力對應的核心職責。我們會詳細介紹 supabase 涉及的每個選項,幫助你快速入門 supabase 的基本操作。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image2.png) + +訪問 Supabase 官網並登錄後,在控制檯首頁點擊 New project 進入創建流程; + +輸入需要配置的主要內容 Project Name、資料庫密碼,地址只需要選擇為與程序目標用戶最接近的區域即可。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image3.png) + +創建成功後,控制檯左側側邊欄將顯示所有核心功能模塊(Table Editor、SQL Editor、Database、Authentication 等),後續操作將圍繞這些模塊展開。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image4.png) + +### 表編輯器 + +Table Editor 可以當成是 Supabase 的可視化資料表編輯器,它能讓你像操作 Excel 一樣直接查看和修改資料庫裡的資料,無需編寫 SQL 語句,只需要用鼠標交互即可修改資料內容。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image5.png) + +其中值得關注的是 Schema,Schema 可理解為資料庫內的 “資源容器”,用於對錶、視圖、函數、索引等資源進行分組管理,主要作用有二:一是避免命名衝突(不同 Schema 下可存在同名table),二是實現權限隔離(如僅允許特定用戶訪問某 Schema 下的表); + +點擊編輯器頂部的 Schema 下拉框可切換不同容器,日常開發中一般只需關注兩類: + +- `public`:默認的公共資源容器,開發者新建的業務表(如 “文章表”“評論表”)均存儲於此; +- `auth`:用戶認證專屬容器,其中的 `users` 表自動存儲所有註冊用戶資訊(如用戶 ID、郵箱、登錄時間),不建議手動修改此 Schema 下的默認表,避免影響認證功能; + +![](/zh-cn/stage-2/backend/database-supabase/images/image6.png)![](/zh-cn/stage-2/backend/database-supabase/images/image7.png) + +### SQL 編輯器 + +SQL Editor 作為 Supabase 的 SQL 語句執行器,可讓你用程式碼的方式直接操作資料庫。你可以讓大模型直接生成 SQL 語句,在右側輸入後點擊 RUN 即可用語句創建或修改 table,也可以直接在 Results 中直接看到篩選出的 table 資料。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image8.png) + +你可以在運行 RUN 之後,在 Table Editor 的 public schema 裡找到新建後的資料表;並且運行後的語句會保存在左側的 PRIVATE 欄中,甚至可以點擊下方的愛心標誌對這一條查詢或創建語句進行收藏。 + +### 資料庫管理中心 + +Database 是 Supabase 的資料庫管理中心,支持可視化地查看和管理所有資料表,並通過表的相互連線理解不同表間的關聯關係(即外鍵約束,表示資料間的引用關係)。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image9.png) + +如果你想要手動新建 table,可以在 tables 中直接新建表格,我們會在之後的教程中詳細講解。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image10.png) + +### 身份認證 + +Authentication 負責管理用戶的註冊、登錄和權限。默認的用戶管理系統資料都在此處存儲,它提供了開箱即用的用戶註冊、登錄、密碼重置、郵箱驗證等功能,並支持第三方 OAuth 登錄(如微信、GitHub、Google 等)。所有用戶資料會自動同步到資料庫的 `auth.users` 表中。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image11.png) + +你可以在 Provider 選項中找到不同 supabase 支持的用戶資訊登錄入口,默認使用 Email;如果你想使用 Github 或者 Google 賬戶進行登錄,還需要更多屬性配置,我們會在下面的課程中進行詳細講解。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image12.png) + +在 Sign In / Providers 裡還包含了對註冊郵箱行為的控制,如果你不想每次郵箱註冊都必須讓用戶接受邀請後才能成為用戶,你可以取消 Confirm email 的強制要求。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image13.png) + +如果你想切換非 Supabase 的其他 auth 系統服務商,你可以點擊 Third Party Auth,比如此處就使用 Clerk 作為第三方的系統服務商。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image14.png) + +如果你擔心註冊用戶在短期內訪問量過大,你可以在 Rate Limits 中啟用對應的流量限制策略: + +![](/zh-cn/stage-2/backend/database-supabase/images/image15.png) + +### 存儲 + +Storage 是 Supabase 的存儲系統,兼容 amazon cloud 的 s3 概念,可用於存儲任意類型的文件(如圖片、影片、文檔、音頻等),並提供訪問權限管理(公開或私有)和下載鏈接獲取(永久鏈接或臨時鏈接),你能夠很方便在應用中對用戶涉及到的文件內容進行上傳與下載管理,並與 Supabase 的認證系統無縫集成,實現精細化的訪問控制。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image16.png) + +我們將會在本節課的進階 project 中講解 storage 的具體用法。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image17.png) + +如果你想使用 S3 的相關協議進行操作,可以直接使用對應的配置: + +![](/zh-cn/stage-2/backend/database-supabase/images/image18.png) + +> Amazon Cloud(亞馬遜雲服務,簡稱 AWS)是亞馬遜提供的雲計算平臺(就像一個大型的網路機房,你可以按需租用計算和存儲資源)。S3(Simple Storage Service)是 AWS 裡專門用來存儲文件的服務(類似一個無限大的網盤,可以存圖片、影片、備份等各種文件),它是目前最流行的對象存儲服務,已經成為了事實上的行業標準。 +> +> **為什麼要做成 S3 兼容 \*\***API\*\* ** ?** :S3 已經存在近 20 年,市面上有大量現成的工具、SDK 和文檔,兼容 S3 意味著你可以直接用這些資源,不用從頭開始製作各類相關工具,能夠快速滿足業務上線的需求。 + +### 邊緣函數 + +如果你不想部署後端,但是想使用資料庫和函數操作,你可以使用 Edge Functions 構建無需自建服務器的後端核心能力,它是 Supabase 提供的全球分佈式服務端函數。簡單來說,它讓你無需購買和管理自己的後端服務器,就能直接編寫並部署在雲端的後端程式碼。這些函數部署在全球網路的邊緣節點上,會自動在離你的用戶最近的位置運行,從而大幅降低網路延遲,提供極致的響應速度。你可以在 Supabase 的儀表盤中直接創建、編輯和部署,整個開發流程非常便捷。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image19.png) + +Edge Functions 的一個核心用途是充當安全的中間層,保護你的敏感資訊和鑑權密鑰。在前端程式碼中直接調用第三方服務(如 OpenAI、Stripe)會暴露你的 API Key,帶來極大的安全風險。通過 Edge Functions,你的前端應用只與你的 supabase 函數通信,所有秘密只在 supabase 中保管。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image20.png) + +Edge Functions 的函數使用 secrets 中暴露的密鑰作為環境變量,通過 `Deno.env.get` 加載,從而實現第三方服務的調用。這樣一來,敏感密鑰就永遠不會暴露在客戶端(你的瀏覽器),徹底杜絕了被盜用的風險。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image21.png) + +請求 Supabase Edge Function 時,需在請求頭攜帶對應的 Supabase 密鑰,下面是一個極簡示例: + +```javascript +// 核心配置(替換為你的實際資訊) +const projectId = "你的 Supabase 項目ID"; +const functionName = "目標 Edge Function 名稱"; +const supabaseKey = "Supabase anon_key"; + +// 調用函數 +async function callEdgeFunction() { + const url = `https://${projectId}.supabase.co/functions/v1/${functionName}`; + + try { + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${supabaseKey}` // 關鍵:攜帶密鑰完成認證 + }, + body: JSON.stringify({ order_id: "123", action: "refund" }) // 自定義請求資料 + }); + + const result = await response.json(); + console.log("調用成功:", result); + } catch (error) { + console.error("調用失敗:", error.message); + } +} + +// 執行調用 +callEdgeFunction(); +``` + +此外,Edge Functions 與 Supabase 的用戶認證系統無縫集成。當已登錄的用戶調用一個函數時,其身份資訊會傳遞給函數。這使得你可以在函數內部輕鬆識別當前用戶,並根據其身份執行權限控制。更重要的是,函數在操作資料庫時會自動遵循你設置好的行級安全策略(Row Level Security),確保用戶只能訪問和修改他們有權操作的資料,讓構建安全的多用戶應用變得簡單。 + +Edge Functions 的應用場景非常廣泛,能夠處理各種後端任務。它們非常適合用來監聽來自第三方服務的 Webhook 事件(例如支付成功、程式碼提交等),並自動執行相應的資料處理邏輯。你也可以用它來發送郵件通知、生成 PDF 報告、創建自定義的 API 接口來封裝複雜的業務邏輯,或者執行任何你希望在服務端完成的計算任務,極大地擴展了你應用的能力。 + +具體到一個常見的例子:身份認證工具 Clerk 。Clerk 僅用於處理用戶登錄、註冊、資訊更新等認證相關操作,並不直接管理你的業務資料庫。如果你想要將這些認證動態同步到業務資料庫中,則需要通過觸發 Webhook 事件請求 Edge Functions 實現。Edge Functions 能夠監聽 Clerk 發出的 Webhook 信號,自動執行資料同步邏輯,讓 Supabase 資料庫中的用戶資訊與 Clerk 登錄狀態實時對齊,全程無需你部署獨立後端。 + +### 實時資料同步引擎 + +Realtime 是 Supabase 的實時資料同步引擎,它允許你的應用即時接收資料庫的變化通知,而無需反覆輪詢 API。當資料庫中的資料發生 `INSERT`、`UPDATE` 或 `DELETE` 操作時,Realtime 會通過 WebSocket 將這些變化實時推送給所有已連接的客戶端。這對於構建需要實時交互的應用至關重要。 + +Realtime 主要包含三大核心功能,覆蓋了絕大多數實時場景: + +1. **Postgres Changes:** 直接監聽資料庫表的變化。你可以精確地訂閱特定表、特定事件(增、刪、改),甚至可以根據篩選條件來接收通知,並與行級安全策略(Row Level Security)完美集成,確保用戶只能收到他們有權限查看的資料變更。 +2. **Broadcast:** 允許客戶端之間通過頻道(Channel)發送低延遲的臨時消息。這非常適合實現聊天室、實時光標追蹤、在線遊戲狀態同步等功能。 +3. **Presence:** 用於追蹤和同步在線用戶狀態。你可以用它來輕鬆實現“誰在線上”、“當前有X人正在查看”等功能,非常適合協作類應用。 + +我們會在後續的項目制學習中詳細介紹該部分的內容。 + +### 項目設置 + +Project Settings 是 Supabase 項目的高級配置部分,你可在此實現計算資源的深度調度,以及各類功能底層參數的精細化配置。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image22.png) + +在入門階段,我們只需聚焦以下兩個核心板塊,一個是 Data API,我們在此可獲取關鍵的 “Supabase URL”, 它是形如 `https://xxx.supabase.co` 的 RESTful 端點,是所有資料查詢、新增、修改、刪除操作的 “入口地址”。前端或服務端需通過該 URL 初始化 Supabase 客戶端,建立與資料庫的連接。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image23.png) + +另一個重點是 API Keys,選擇 “Legacy anon, service_role API keys” 標籤頁,其中的 anon public 密鑰 是前端場景的重要身份憑證,它的權限被 RLS 嚴格限制,僅能訪問用戶被授權的資料。而 service_role 密鑰屬於 “服務端高權限密鑰”,具備繞過行級安全的能力,可執行批量資料操作、系統級配置等敏感操作。絕對禁止公開分享,若洩露需立即生成新密鑰並更新服務端配置。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image24.png) + +其餘配置項在當前階段無需深究,待後續有進階使用需求時再逐一探索即可。 + +## 2.1 創建你的第一個 SQL 資料表 + +以上是 Supabase 的界面介紹,接下來我們將深入 Supabase 的核心資料庫的操作環節。 + +在 Supabase 中創建資料表,主要有以下兩種常用方式,你可以根據需求選擇: + +1. (推薦)藉助大語言模型生成適配 Supabase 的 SQL 語句,直接在 **SQL Editor(** 前文介紹的 SQL 語句執行器)中粘貼執行,高效快捷,我們會在下個部分環節重點說明這個操作過程。 +2. 通過可視化操作創建:在左側側邊欄找到 Database 模塊,點擊進入後選中側邊欄的 Tables,在右側點擊 New table 按鈕,即可通過圖形化界面創建資料表。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image25.png) + +值得注意的是,對應資料表的名稱以及存儲的資料類型可在下方的 Columns 中指定。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image26.png) + +對於關係資料庫,其中很重要的特點是表與表之間的關聯,你可以在下方找到 `Foreign keys` ,點擊創建相應的關聯關係: + +![](/zh-cn/stage-2/backend/database-supabase/images/image27.png) + +其中 `Foreign keys` 表達了表與表之間的關聯關係:一個或一組字段,它在當前表(子表)中的值,會引用另一張表(父表)中主鍵的值。 + +例如,在創建 `學生表`的時候,我們可以這樣定義外鍵:(`所屬班級編號` 這一列是一個外鍵。這個外鍵引用了 `班級表` 裡的 `班級編號` 這一列。) + +```sql +CREATE TABLE 學生表 ( + 學生學號 INT PRIMARY KEY, + 學生姓名 VARCHAR(50), + 所屬班級編號 INT, + FOREIGN KEY (所屬班級編號) REFERENCES 班級表(班級編號) +); +``` + +更具體舉例而言,我們可以可視化觀察對應的表的結構: + +班級表: +這張表裡記錄了所有班級的資訊,每個班級都有一個獨一無二的班級編號。班級編號就是這張表的主鍵 (Primary Key),是每個班級的唯一身份證。 + +| 班級編號 | 班級名稱 | +| -------- | ---------- | +| 101 | 一年級一班 | +| 102 | 一年級二班 | + +學生表: +這張表記錄了所有學生的資訊。每個學生都屬於一個特定的班級,對嗎?那麼我們怎麼知道哪個學生在哪個班級呢? + +我們可以在學生表裡增加一列,叫做 `所屬班級編號`。 + +| 學生學號 | 學生姓名 | 所屬班級編號 | +| -------- | -------- | ------------ | +| 2024001 | 張三 | 101 | +| 2024002 | 李四 | 102 | +| 2024003 | 王五 | 101 | + +在該例子中,學生表中的 `所屬班級編號` 列就是外鍵 (Foreign Key)。 + +在 Supabse 中,點擊添加 Foreign Key 後,你可直接選擇進行關聯表對應列的選取 + +![](/zh-cn/stage-2/backend/database-supabase/images/image28.png) + +## 2.3 SQL Editor 簡介與資料庫基本操作 + +接下來我們將分步執行一系列 SQL 腳本,熟悉常見的 SQL 中的增刪查改操作。你可以將每個步驟的程式碼複製到 SQL Editor 中,執行並觀察結果。 + +你可以在該目錄下獲得所有的測試 SQL 文件: + +https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos/tree/main/apps/sql-examples + +### **2.3.1 **`CREATE`** - 創建表結構** + +`CREATE TABLE` 語句用於為新表定義模式(Schema),包括其列(Columns)、對應的資料類型(Data Types)以及任何約束(Constraints),簡單理解是創建了一個資料表。 + +```sql +-- Step 1: Create the 'orders' table +-- This file is fully independent and creates a sample table for later steps. +CREATE TABLE IF NOT EXISTS orders ( + id serial PRIMARY KEY, + user_id int NOT NULL, -- User ID + status text NOT NULL, -- Order status (e.g. paid, pending) + amount numeric(10, 2) NOT NULL, -- Order total amount + details jsonb, -- Item and extra details as JSON + placed_at timestamptz DEFAULT now(), -- Order creation time + is_paid boolean DEFAULT false -- Paid flag +); + +-- Expected Output: +-- Orders table created if it did not exist. +-- No data inserted. (Querying returns zero rows for now.) +-- If table already exists, no error occurs. +``` + +成功執行後,系統將提示腳本已完成。你可以在 Table Editor 中看到對應的表被創建完成: + +![](/zh-cn/stage-2/backend/database-supabase/images/image29.png) + +### **2.3.2 **`INSERT`** - 填充初始資料** + +表結構創建完畢後,下一步是使用 `INSERT INTO` 語句向表中添加資料行。 + +```sql +-- Step 2: Insert initial rows into the orders table +-- Provides realistic, varied data for demo/testing. All values are self-contained. +INSERT INTO orders (user_id, status, amount, details, placed_at, is_paid) VALUES + (2001, 'pending', 23.50, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '2 days', false), + (2002, 'paid', 50.00, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":2,"price":5.00}]}', now() - interval '1 day', true), + (2003, 'cancelled', 15.00, '{"items":[{"sku":"FRY001","name":"French Fries","qty":3,"price":5.00}], "reason":"Not available"}', now() - interval '45 days', false), + (2004, 'paid', 22.98, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":2,"price":9.99}], "promo":"SUMMER22"}', now() - interval '10 days', true), + (2005, 'pending', 18.75, '{"items":[{"sku":"SAL001","name":"Salad","qty":1,"price":6.75},{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00}]}', now() - interval '7 hours', false), + (2006, 'paid', 8.00, '{"items":[{"sku":"DRK002","name":"Cola","qty":2,"price":4.00}]}', now() - interval '3 hours', true), + (2007, 'refunded', 14.50, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99},{"sku":"FRY001","name":"French Fries","qty":1,"price":4.51}], "refund_reason":"Late delivery"}', now() - interval '15 days', false), + (2008, 'paid', 26.99, '{"items":[{"sku":"BGR002","name":"Chicken Burger","qty":2,"price":10.00},{"sku":"DRK001","name":"Lemonade","qty":1,"price":6.99}]}', now() - interval '12 days', true), + (2009, 'pending', 9.99, '{"items":[{"sku":"BGR003","name":"Veggie Burger","qty":1,"price":9.99}]}', now() - interval '30 minutes', false), + (2010, 'paid', 19.89, '{"items":[{"sku":"BGR001","name":"Beef Burger","qty":1,"price":12.00},{"sku":"DRK002","name":"Cola","qty":2,"price":3.95}]}', now() - interval '5 days', true), + (2011, 'cancelled', 0.00, '{"items":[], "reason":"User cancelled"}', now() - interval '2 days', false); + +-- Expected Output: +-- After running this script, SELECT * FROM orders will show about 11 rows with varied user_id, status, amount, details (JSON), placed_at, and is_paid fields. +-- For example: +-- | id | user_id | status | amount | is_paid | placed_at | +-- |----|---------|-----------|--------|---------|---------------------| +-- | 1 | 2001 | pending | 23.50 | false | 2025-10-28 13:40:00Z| +-- | 2 | 2002 | paid | 50.00 | true | ... | +-- |... | ... | ... | ... | ... | ... | +``` + +執行成功後,此時表中已經插入了原始資料,你可以進入到 Table Editor 界面刷新後看到結果,也可以直接在 SQL Editor 界面中新建窗口,執行查詢語句 `SELECT * FROM orders;`查看結果: + +![](/zh-cn/stage-2/backend/database-supabase/images/image30.png) + +### **2.3.3 **`SELECT`** - 讀取與查詢資料** + +`SELECT` 語句用於從表中檢索資料。通過使用不同的子句,可以實現對資料的精確篩選、排序和格式化,我們可參考以下語句一步步執行查看結果: + +```sql +-- Step 3: SELECT query examples for the orders table + +-- Example 1: Select all fields for all orders +SELECT * FROM orders; +-- Expected Output: Returns all rows and fields. Columns: id, user_id, status, amount, details, placed_at, is_paid. + +-- Example 2: Select only pending orders +SELECT id, user_id, amount FROM orders WHERE status = 'pending'; +-- Expected Output: All rows with status 'pending'; columns: id, user_id, amount. + +-- Example 3: Select specific fields and filter by payment status +SELECT id, status, is_paid, amount FROM orders WHERE is_paid = true; +-- Expected Output: All rows where is_paid is true; columns: id, status, is_paid, amount. + +-- Example 4: Extract all item names from the details (JSON) for each order +SELECT id, details -> 'items' AS item_list FROM orders; +-- Expected Output: Each row shows id and an array from JSON with item details. +``` + +- **示例 1:** 返回 `orders` 表中的所有行和列,與第二步的輸出類似。 +- **示例 2:** 僅返回狀態為 'pending' 的訂單,且只包含指定的列: + +![](/zh-cn/stage-2/backend/database-supabase/images/image31.png) + +- **示例 3:** 僅返回已支付的訂單,並顯示指定的列: + +| id | status | is_paid | amount | +| --- | ------ | ------- | ------ | +| 2 | paid | true | 50.00 | +| 4 | paid | true | 22.98 | +| 6 | paid | true | 8.00 | +| 8 | paid | true | 26.99 | +| 10 | paid | true | 19.89 | + +- **示例 4:** 返回每個訂單的 `id` 和從 `details` 字段中提取的 `items` 數組: + +| id | item_list | +| --- | -------------------------------------------------------------------------------------------------------------------- | +| 1 | `[{"qty":1,"sku":"BGR001","name":"Beef Burger","price":12}]` | +| 2 | `[{"qty":2,"sku":"BGR002","name":"Chicken Burger","price":10},{"qty":2,"sku":"DRK001","name":"Lemonade","price":5}]` | +| 3 | `[{"qty":3,"sku":"FRY001","name":"French Fries","price":5}]` | +| ... | ... | + +### **2.3.4 **`INSERT`** - 插入單條記錄** + +在 2.3.2 中,我們演示的是開頭時刻初始化批量插入資料,現在我們查看如何新增插入單條資料。 + +```sql +-- Step 4: INSERT a new order (single row) +-- Example: Add a new paid order for user 2012 with one Chicken Burger +INSERT INTO orders (user_id, status, amount, details, is_paid) +VALUES ( + 2012, 'paid', 9.99, + '{"items":[{"sku":"BGR002","name":"AIID Burger","qty":100,"price":1000}]}', + true +); +-- Expected Output: +-- Before (table fragment): +-- | id | user_id | status | amount | is_paid | +-- | ...| ... | ... | ... | ... | +-- +-- After (last row): +-- | id | user_id | status | amount | is_paid | +-- | xx | 2012 | paid | 9.99 | true | +-- (where xx = next serial value) +``` + +此時再用 `SELECT * FROM orders;` 對資料進行查詢,我們可以看到 orders 表成功從 11 個資料變成了 12 個資料。 + +### **2.3.5 **`UPDATE`** - 修改現有資料** + +在實際工作中,我們需要對資料表進行頻繁資料更新,我們能夠用 `UPDATE` 語句修改表中已存在的記錄。 + +```sql +-- Step 5: UPDATE example +-- Example: Mark order with id=1 as paid and update its status +UPDATE orders SET status = 'paid', is_paid = true WHERE id = 1; +-- Expected Output: +-- Before (row with id=1): +-- | id | status | is_paid | +-- | 1 | pending | false | +-- After (row with id=1): +-- | id | status | is_paid | +-- | 1 | paid | true | +-- All other rows remain unchanged. +``` + +### **2.3.6 **`DELETE`** - 刪除資料** + +`DELETE` 語句可用於從表中移除記錄,並結合條件對指定部分的資料進行修改。 + +```sql +-- Step 6: DELETE example +-- Example: Delete orders older than 2 days to clean up old data +DELETE FROM orders WHERE placed_at < now() - interval '2 days'; +-- Expected Output: +-- Before (filtered for affected rows): +-- | id | status | placed_at | +-- | 3 | shipped | 2025-10-13 ... | <-- will be deleted +-- +-- After: +-- No such rows remain. SELECT * FROM orders WHERE placed_at < now()-interval '2 days' yields zero rows. +-- Other rows in orders table are unaffected. +``` + +執行前,你可先執行 `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';` 進行資料表篩選結果的查看。當運行 `DELETE` 命令後,再次執行相同的 `SELECT` 查詢 `SELECT id, status, placed_at FROM orders WHERE placed_at < now() - interval '2 days';`,將返回一個空的結果,表明這些行已被成功刪除。 + +## 2.4 行級安全 + +在學習了資料庫的基本操作後,我們需要進一步深入一個保障資料安全的核心概念 ——RLS(行級安全,Row Level Security)。 + +不妨先思考一個實際場景中的關鍵問題:如何實現資料的 “隔離訪問”?比如,只允許用戶 A 查看自己的資料,而無法看到用戶 B 的資訊;再比如,即便某角色擁有資料庫的訪問權限,如何避免其誤操作或洩露其他用戶的敏感資料? + +RLS 正是為解決這類資料安全與隔離需求而生。它允許開發者為資料庫表定義精細化的安全策略,根據用戶的身份資訊(如用戶 ID、角色權限等),精確控制哪些用戶能訪問、修改表中的哪些行資料。 +舉個典型示例:對於訂單表(`orders`),我們可以定義這樣一條 RLS 策略 ——“僅當 `orders` 表中某條記錄的 `user_id` 列,與當前登錄用戶的 ID 完全一致時,該用戶才能查詢到這條訂單資料”,從而實現 “用戶只能看自己的訂單” 的核心需求。 + +當你為某張表啟用 RLS後,該表的所有資料操作請求(包括 `SELECT` 查詢、`INSERT` 新增、`UPDATE` 修改、`DELETE` 刪除)都會觸發 RLS 校驗:必須通過至少一條安全策略的檢查,操作才能執行。若不存在允許該操作的策略,或請求未滿足任何策略的條件,資料庫會直接拒絕此次操作,從底層阻斷非授權訪問。 + +在 Supabase 中,RLS 與用戶認證系統深度綁定,使用起來更為便捷。Supabase 提供了一個專用函數 `auth.uid()`,它能直接返回 “當前發起請求的已登錄用戶” 的唯一 ID(格式為 UUID)。藉助這個函數,我們可以輕鬆編寫策略,實現 “資料行與用戶身份” 的精準關聯(比如前文提到的 “訂單 `user_id` 匹配當前用戶 ID”)。 + +啟用 RLS 策略的方式很靈活,你可以在 Supabase 資料庫管理界面中的 “RLS” 按鈕,直接配置並啟用策略: + +![](/zh-cn/stage-2/backend/database-supabase/images/image32.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image33.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image34.png) + +主動配置難免顯得麻煩,通常,我們在資料表語句創建、初始化的時候就會自動考慮植入對應的 RLS 策略。我們只需在 SQL Editor 中執行類似如下語句,即可自動開啟對應資料表的行級安全策略。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image35.png) + +# 3. 第一個 SQL 應用 + +掌握了資料庫基礎操作與RLS核心邏輯,我們終於進入本次教程的實踐環節。漫長的學習鋪墊是為了讓後續“從0到1搭建應用”的過程更清晰。接下來,我們將以“漢堡店訂單管理”為場景,手把手演示Supabase的常見操作:從應用與Supabase的關聯配置,到資料庫與登錄功能的集成,逐步學習不同操作邏輯。 + +## 3.1 克隆並運行 Supabase 示例項目 + +要開展實操,首先需要獲取配套的演示程式碼倉庫。你可以讓 Trae 或 Claude Code 協助 git clone 以下倉庫:https://github.com/THU-SIGS-AIID/Project5-Supabase-Demos + +若已配置 SSH 密鑰,建議使用 SSH 地址進行 clone(git@github.com:THU-SIGS-AIID/Project5-Supabase-Demos.git)以提升安全性;若 SSH 或 HTTPS 連接遇到網路問題,可以直接點擊倉庫頁面的 “Download ZIP”,獲取壓縮包後解壓即可看到完整程式碼。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image36.png) + +Clone 後,你同樣可以讓 Trae 或者是 Claude Code 幫你啟動項目,例如直接在 Agent 界面中說明: `幫我直接啟動這個項目裡面的 project 1 `,或者複製對應想啟動 project 的絕對路徑,粘貼給大模型讓大模型直接啟動。 + +## 3.2 項目1 - 漢堡店菜單增刪改查 + +接下來進入實操環節 —— 以 `project-burger-shop-menu-crud-1` 為例,我們將學習如何通過 SQL 腳本一鍵初始化 Supabase 資料庫,並完成本地項目與 Supabase 資料庫的關聯配置,讓前端能正常讀寫菜單資料。 + +### 使用腳本創建資料庫 + +首先,我們需要在 Supabase 中創建需要的資料表的相關內容。進入 Project1 項目目錄看到名為 `scripts`的文件夾,其中包含 1 個 `init.sql`資料庫腳本文件,它能幫我們自動完成所有資料庫相關資源的創建(包括表結構、初始資料等),之後我們會經常用到該文件進行資料庫中表的初始化。 + +```sql +...... + +-- ============================================================================ +-- 2. Create Menu Items Table +-- ============================================================================ + +create table if not exists public.menu_items ( + id uuid primary key default gen_random_uuid(), + name text not null, + description text, + category text check (category in ('burger','side','drink')) default 'burger', + price_cents int not null check (price_cents > 0), + available boolean default true, + emoji text, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +-- Comments for documentation +comment on table public.menu_items is 'Burger shop menu items for CRUD demo'; +comment on column public.menu_items.id is 'Unique identifier for each menu item'; +comment on column public.menu_items.name is 'Display name of the menu item'; +comment on column public.menu_items.description is 'Detailed description of the menu item'; +comment on column public.menu_items.category is 'Category: burger, side, or drink'; +comment on column public.menu_items.price_cents is 'Price in cents (integer) to avoid floating point issues'; +comment on column public.menu_items.available is 'Whether the item is currently available for order'; +comment on column public.menu_items.emoji is 'Optional emoji representation of the menu item'; +comment on column public.menu_items.created_at is 'Timestamp when the item was created'; +comment on column public.menu_items.updated_at is 'Timestamp when the item was last updated'; + +...... +``` + +在 SQL Editor 中執行初始化 sql 腳本後,即可在 Table Editor 中看見已創建的資料表。其中資料庫初始化程式碼具體執行邏輯如下: + +1. 創建 menu_items 表 : +2. 這個表用於存儲漢堡店菜單中的所有項目。它包含了如 name (商品名), description (描述), price_cents (以美分為單位的價格,避免浮點數精度問題), category (分類) 和 available (是否可售) 等字段。這基本涵蓋了一個菜單項所需的所有資訊。 +3. 創建 promo_codes 表 : +4. 此表用於管理促銷活動,例如折扣碼。它定義了 code (折扣碼), discount_type (折扣類型,如百分比或固定金額), discount_value (折扣數值) 等字段。 +5. 禁用行級安全 (Row Level Security - RLS) : +6. 為了方便開發和測試,腳本中明確地禁用了 RLS。但結合我們之前學習的 RLS 核心邏輯:RLS 是 Supabase 保障資料安全的關鍵功能,能通過精細化策略控制 “誰能訪問 / 修改哪些資料”(比如只允許管理員編輯促銷碼,普通用戶只能查看菜單)。因此在生產環境中,必須開啟 RLS 並配置合理策略,從底層阻斷非授權訪問(如防止用戶惡意修改他人創建的菜單,或洩露促銷碼規則)。 +7. 插入種子資料 (Seed Data) : +8. 為了讓前端項目啟動後就能看到真實的菜單與促銷資料(無需手動錄入測試資料),`init.sql`腳本還會向 `menu_items`和 `promo_codes`表中插入 “種子資料”(即示例資料)。例如,你可以看到各種漢堡、小食、飲料以及多種多樣的折扣碼。 + +### 設置與資料庫的連接 + +資料庫準備完成,我們需要將這個前端項目與 Supabase 進行連接,從而正常讀取資料庫內的資料。我們需要將 Supabase 項目的 URL 和 anon key 寫到指定配置中,本項目提供了兩種靈活的配置方式: + +1. 通過環境變量配置 + +在項目根目錄創建一個 .env 文件,並填入你的 Supabase 憑證: + +``` +NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co +NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key +``` + +2. 在項目頁面中直接設置 + +為了方便快速演示和切換不同的 Supabase 項目,首頁頁面右上角提供了一個 設置 按鈕。你可以點擊它,在彈出的模態框中直接輸入或粘貼 Supabase URL 和 anon key。 + +點擊 “Save” 後,這些資訊會用於動態創建 Supabase 客戶端實例,類似下列程式碼所示: + +```JavaScript +import { createClient, type SupabaseClient } from '@supabase/supabase-js'; + +// Optional client factory for demos: returns null when env is not set. +export function maybeCreateBrowserClient(): SupabaseClient | null { + const url = process.env.NEXT_PUBLIC_SUPABASE_URL; + const anon = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; + if (!url || !anon) return null; + return createClient(url, anon); +} +``` + +創建完資料庫,填寫完對應的 Supabase Link 相關配置後,即可看到如下界面,你可以嘗試對商品進行增刪查改,並觀察 Supabase 中對應部分資料表的變化。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image37.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image38.png) + +### 📚 作業 + +1. 嘗試增加和刪除已有項目,在 Table Editor 中查看修改操作對資料表內容變動的影響。 + +## 3.4 項目2 - 漢堡店認證用戶 + +Project1 實現了 “菜單 CRUD + 資料庫連接” ,Project2 將引入更貼近真實業務的核心能力,用戶認證(Auth)與行級安全(RLS)權限管理。 + +Project2 包含獨立的登錄頁,支持用戶通過「郵箱 + 密碼」的方式登錄。其核心邏輯是調用 Supabase Auth 提供的原生方法,快速實現認證流程,無需手動開發複雜的登錄校驗邏輯: + +``` +const { error: err } = await supabaseClient.auth.signUp({ + email, + password, + options: { + data: { + full_name: fullName || null, + birthday: birthday || null, + avatar_url: avatarUrl || null + } + } +}); +``` + +![](/zh-cn/stage-2/backend/database-supabase/images/image39.png) + +登錄成功後,Supabase 會自動為用戶創建一個會話(session),並在後續所有資料庫請求中自動攜帶認證資訊;通過 RLS 的作用,每個用戶根據對應的認證資訊只能看到自己的賬戶資訊(已購買項目、錢包剩餘額度),無法看到其他用戶的賬戶資訊,這就實現了不同用戶登錄後的資料隔離,每個人只能看到自己的內容。 + +和 Project 1 一樣,你需要先使用 `init.sql` 進行資料表的初始化(注:如果發現初始化出錯,請先在 Table Editor 中刪除已經創建的資料表,或者是直接刪除這個 Supabase Project, 重新新建一個 Project) + +成功使用郵箱註冊賬戶、在郵箱確認註冊賬戶後,登錄後進入 Shop 界面即可看到如下內容: + +![](/zh-cn/stage-2/backend/database-supabase/images/image40.png) + +但此時點擊 admin,你並不能看到如下界面,你需要嘗試在資料表中找到控制用戶權限的部分,將權限修改為 `admin`,從而能夠在 Admin 界面正常看到如下內容: + +![](/zh-cn/stage-2/backend/database-supabase/images/image41.png) + +值得提示的是,目前每次註冊新的郵箱,你都需要在郵箱中進行註冊確認才可登錄;但這一步並非是必須的,你可以在 Supabase 的 Authentication 欄目中找到 Sign In / Providers,點擊Confirm email 取消郵箱的強制確認。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image42.png) + +### 📚 作業 + +1. 請先領取新手禮包,完成商品購買操作。 +2. 嘗試找到用戶權限的設定資料表位置,將權限修改為 `admin`,併成功在訂單管理界面修改商品數量 +3. 嘗試在資料表內定位到錢包金額相關表,通過修改使剩餘錢包金額增加。 + +# 4. 構建你的第一個 Supabase 應用 + +經過前面的系統學習,你已掌握 Supabase 的核心能力(資料庫操作、用戶認證、RLS 安全策略),現在是時候親自動手,搭建屬於你的第一個包含資料庫、支持用戶登錄系統的應用了! + +## 4.1 為任意應用接入 Supabase 資料庫的標準化流程 + +我們可以使用標準化流程將任意應用接入 Supabase 資料庫: + +1. 首先進行需求梳理與資訊同步,明確目標並告知AI + 1. 你需要向AI清晰描述當前應用的核心功能、待新增的資料庫需求。示例:“我現有一個本地React Todo應用,資料僅存在瀏覽器本地存儲,需新增‘資料雲端同步’功能並接入Supabase資料庫。請幫我梳理:這個應用涉及哪些資料操作(如新增待辦、修改狀態、刪除待辦)?需要創建哪些資料表來存儲這些資料?” + 2. 補充關鍵約束條件(可選):比如字段格式要求(時間戳用 `timestamptz`、金額用整數存分)、資料權限規則(僅自己可見待辦),讓AI的分析更貼合實際需求。 + 3. 對 AI 返回的結果進行審核,若AI思路存在遺漏(如未考慮“待辦截止時間”字段),補充提示修正:“你漏考慮截止時間了,幫我加上。” +2. 讓AI基於你確認後的表結構,生成適配Supabase的 `init.sql`腳本:“基於上述所說思路和表的結構,返回給我在 Supabase 中可以進行初始化的 init.sql 腳本”,之後你需要在 SQL Editor 中執行腳本;若執行報錯,將錯誤資訊反饋給AI,讓其修正腳本。 +3. 在 Supabase 運行 init.sql 腳本後,讓 AI 基於腳本重構當前程式碼,使得能夠和 Supabase 進行正常的資料交互:“請你根據我的 sql 腳本以及上面討論的設定,重構項目的程式碼讓它支持能夠和 Supabase 對應的資料庫進行通信並處理資料”。 +4. 重構完畢,此時只需要配置好 Supabase 地址和 key 的參數(正式項目通常只用環境變量配置),隨後進行檢查,若沒問題則順利實現將應用接入 Supabase 資料庫。 + 1. 運行項目,測試所有資料庫交互功能,到Supabase Table Editor 實時查看資料是否同步; + 2. 若出現問題(如資料無法插入、僅能看到部分資料),將問題現象反饋給AI,讓其定位原因並修正程式碼。 + +此外,若目標是開發用戶登錄頁面,可直接讓 AI 協助集成登錄頁面 :“現在你需要幫我給這個應用加入 Supabase 的用戶登錄系統,使用郵箱可以註冊和登錄”。另外,你還需要向 AI 明確頁面的跳轉邏輯與路徑(如登錄成功後跳轉至系統首頁、跳轉首頁的地址是什麼、登錄失敗時留在當前頁並顯示錯誤提示)。集成完成後,你需要嘗試註冊登錄後能在 Supabase 的 Authentication 項目中看到新增的用戶資料,並在登錄後能正常進入到原先未登錄無法進入的應用界面即可。 + +當然,你還可以直接讓 AI 參考某個 project 的實現直接遷移對應的 Supabase 功能,比如某個 Project 用到了資料庫以及 Edge fuction 的高級功能,你可以按照如下方式直接讓 AI 遷移對應的相似功能:“請你參考該項目 {此處複製粘貼參考項目的絕對地址} 當中的 Supabase 相關功能實現邏輯,給當前項目加上類似的實現邏輯(如用戶登錄、資料庫管理、函數請求等等)”。 + +## 4.2 案例研究:構建一個在線貪吃蛇遊戲 + +根據上面所提到的 SOP ,讓我們通過一個具體的實際案例 `Project5-Supabase-Demos/apps_snakegame`來實踐:為一個已有的“貪吃蛇”遊戲項目增加分數排行榜單,包含用戶登錄與資料庫基礎功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image43.png) + +### 4.2.1 分析項目,識別資料需求 + +首先,和在之前提到的標準化流程類似,我們可以先把需求澄清給 AI ,讓 AI 基於我們項目和需求給出對應的修改方案,之後我們會基於這個修改方案。 + +**你可以使用如下的提示詞來指導 AI:** + +> “我有一個貪吃蛇遊戲,目錄在 {此處粘貼貪吃蛇遊戲的絕對路徑}。現在我想結合 supabase 給它增加一個在線排行榜功能,並且支持用戶登錄系統,排行榜可以根據用戶名和郵箱顯示排名。 +> +> 請幫我分析一下,為了實現這個功能,我需要建立哪些資料表?每個表應該包含哪些字段?” + +此時你會得到類似如下返回: + +![](/zh-cn/stage-2/backend/database-supabase/images/image44.png) + +### 4.2.2 生成 `init.sql` 腳本 + +確定需要的部分,我們可以讓 AI 生成需要在 Supabase 執行的資料庫初始化腳本:“請你基於上面的分析,幫我在項目中生成 scripts/init.sql 腳本用於在 Supabase 中初始化所需資料庫”。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image45.png) + +### 4.2.3 改造項目程式碼 + +接下來我們只需要讓 AI 基於前面的內容重構當前的貪吃蛇程式碼:“接下來請你基於前面思考的內容以及 sql 表,使用 Supabase 幫我實現排行榜功能,排行榜是單獨的一頁,需要可以根據郵箱和用戶名區分不同用戶的總分,你還需要支持基於郵箱的用戶登錄系統,註冊登錄才能玩這個遊戲。” + +如果當前 AI 對話輪次太多,你想重開一個新的會話進行項目重構,你可以把上面提到的 `init.sql`作為上下文中的內容,讓 AI 基於 sql 文件進行項目重構。 + +若是發現 AI 實現的用戶登錄系統不夠正常,你可以直接將我們之前寫好的 `Project5-Supabase-Demos/apps/project-burger-shop-auth-users-2` 的地址一同放入提示詞,讓 AI 基於項目直接實現用戶登錄系統。並檢查是否已經正確設定了連接到 Supabase 的必要條件,防止因為 Supabase 配置錯誤而報錯。 + +在程式碼修改過程中,若出現實際效果與預期不符的情況(如排行榜資料不顯示、登錄驗證失效等),只需完整記錄具體現象並反饋給 AI,即可逐步接近正確結果。改造成功的標準為:用戶能順利完成註冊與登錄操作,且登錄後可正常查看對應的遊戲排行榜單。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image46.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image47.png) + +### 📚 課程作業 + +1. 將用戶管理系統集成到貪吃蛇遊戲演示版中 +2. 將用戶管理系統集成到你的應用程序中(如果之前已開發過一個應用程序) + +# 5. 成為 Supabase 大師 + +以上是 Supabase 的基本操作,接下來的旅程中我們將會接觸 Supbase 的進階原理和功能,你將理解為什麼我們會選擇 Supabase 作為教學案例,以及如何使用 Supbase 實現更高級的操作,協助你實現更復雜的交互功能,並且在學習這些功能後,即便面對 Supabase 之外的其他同類工具,你也能觸類旁通,從更本質的層面理解後端服務的核心原理。當然,你並不需要在短時間內學會全部,也許只需要學會第三方登錄支持已經足夠,你可以先瀏覽下列內容,直到項目遇到對應的需求時再倒回來深入學習。 + +## 5.1 為什麼我們選擇 Supabase + +在開始進階之前,我們再次思考這個問題:眾多後端技術方案中,為何我們最終選擇 Supabase 作為技術底座? + +初創團隊在技術選型時普遍面臨一個矛盾:既想完全掌控後端系統,又必須快速上線產品——而自建後端通常意味著要投入數月時間搭建資料庫與實時同步、用戶認證、API服務、文件存儲、定時任務、監控告警等核心組件,除非團隊成員已在對應領域積累了豐富的實戰經驗。在資金不足、市場窗口短暫的雙重壓力下,一旦陷入基礎設施泥潭,極易導致迭代滯後、錯失早期增長空間。 + +Supabase 將這些後端能力打包為開箱即用的服務(PostgreSQL資料庫、實時訂閱、身份認證、對象存儲、邊緣函數、自動生成API等),讓初創團隊得以將稀缺資源聚焦於核心功能開發,避免因底層建設拖慢上線速度——這已成為當前創投環境下務實的生存策略。當然,我們也可以使用別的一棧式後端產品進行開發,例如 PocketBase(輕量極簡)和 Appwrite(跨平臺適配)等方案,但綜合功能完整性、SQL 生態成熟度及 Github 社區關注度,Supabase 更適合支撐業務的長期穩定運行。 + +在同類產品中,Supabase 的開源策略更具優勢。 以市場佔有率較高的 Firebase 為例:其閉源特性易導致平臺綁定,遷移成本極高。Supabase 採用完全開源模式,支持私有化部署,規避了供應商鎖定風險,可根據需求切換至其其他競品。 + +總而言之,技術選型需匹配業務規模與目標。 對於個人項目或極小範圍測試,PocketBase 等超輕量方案已足夠;若企業需對接複雜身份系統,或要滿足上市公司合規審計要求,WorkOS 這類企業級全身份治理方案更為適用。但對於驗證 MVP、承載早期用戶的核心業務場景,Supabase 的完整功能完全夠用,它不僅能獨立支撐至少萬級用戶規模,更可靈活集成 Stripe(支付)、Resend(郵件)、Cloudflare(CDN)等第三方服務;即便未來業務擴展至企業級需求,Supabase 的開源架構也能與企業系統並行部署,不同功能選擇最適配的平臺進行使用。這種漸進式靈活性,使初創團隊無需過早投入重型基礎設施,又能保留 future-proof 的演進空間。 + +## 5.2 Google 和 GitHub 登錄支持 + +在前面的教程中,我們講解了如何直接使用郵箱進行註冊和登錄,但在實際操作中我們通常想要簡化註冊流程,例如使用第三方登錄 Google 和 GitHub 進行系統的快速註冊與登錄,我們將會在這節教程中展開每個細節;同時,一個完整的認證系統也必須提供安全可靠的密碼重置功能,我們也會將密碼重置功能集成在本節教程的項目中。 + +本項目 `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6`)完整地演示瞭如何實現這些高級功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image48.png) + +### 5.2.1 OAuth 流程:第三方登錄是如何工作的? + +第三方登錄的核心是 OAuth 2.0 開放授權協議,它的本質是 “授權代理”:允許用戶授權我們的應用(漢堡店項目)訪問其在第三方平臺(如 Google)的公開資訊(如郵箱、頭像),但無需將第三方平臺的密碼暴露給我們的應用,從根本上規避了密碼洩露風險。 + +完整流程可拆解為 5 個關鍵步驟,以 Google 登錄為例: + +1. 用戶發起授權請求:用戶點擊頁面上的 “Sign in with Google” 按鈕,我們的應用會自動將用戶重定向到 Google 官方的授權頁面(確保授權過程的安全性,避免釣魚風險)。 +2. 用戶完成第三方授權:用戶在 Google 頁面登錄自己的賬戶(驗證用戶身份),並同意我們的應用請求的權限(如 “獲取郵箱地址”)。 +3. Google 返回一次性授權碼:授權通過後,Google 會將用戶重定向回我們提前約定的 “回調 URL(Callback URL)”,並在 URL 參數中附帶一個一次性、短期有效的授權碼(而非直接返回用戶資訊,進一步提升安全性)。 +4. Supabase 交換訪問令牌(Access Token):我們的後端(由 Supabase 託管,無需自建)會拿著這個授權碼,向 Google 官方接口發起請求,換取可用於獲取用戶資訊的 Access Token(授權碼僅用於換 Token,避免 Token 直接在前端傳輸)。 +5. 創建賬戶並建立會話:Supabase 使用 Access Token 從 Google 拉取用戶的公開資訊(如郵箱、頭像),並在我們的項目中為該用戶自動創建賬戶(若首次登錄)或直接關聯現有賬戶,最終生成一個有效的用戶會話(Session),完成登錄。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image49.png) + +### 5.2.2 配置 Google Cloud 獲取 Client ID 和 Secret + +無論是何種第三方登錄方式,我們通常都需要獲取 Client ID 與 Secret 進行配置;對於 Google 的第三方登錄,你首先需要在 Google Cloud Platform 中創建一個 OAuth 2.0 客戶端 ID 進行對應參數的獲取。 + +1. **進入 Google Cloud Console** : +2. 訪問 [Google Cloud Console](https://console.cloud.google.com/)。 +3. 創建一個新項目或選擇一個現有項目。 +4. **配置 OAuth 同意屏幕 (OAuth consent screen)** : +5. 在左側導航欄中,找到 “APIs & Services” -> “OAuth consent screen”。 +6. 選擇 “External” 用戶類型,然後點擊 “Create”。 +7. 填寫應用名稱、用戶支持電子郵件等必填資訊。 +8. 在 “Authorized domains” 部分,添加你的 Supabase 項目域名,格式為 `*.supabase.co`。 +9. 保存並繼續。在 “Scopes” 和 “Test users” 步驟中,你可以暫時跳過,直接保存。 +10. **創建憑據 (Create Credentials)** : +11. 進入 “APIs & Services” -> “Credentials”。 +12. 點擊 “+ CREATE CREDENTIALS”,選擇 “OAuth client ID”。 +13. 在 “Application type” 中選擇 “Web application”。 +14. 為它取一個名字,例如 “Supabase Auth”。 +15. 在 “Authorized redirect URIs” 部分,點擊 “ADD URI”,並填入你的 Supabase 項目的回調 URL。你可以在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “Google” 中找到這個 URL,它的格式通常是 `https://<你的項目ID>.supabase.co/auth/v1/callback`。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image50.png) +16. 點擊 “CREATE”。 +17. **獲取 Client ID 和 Client Secret** : +18. 創建成功後,一個彈窗會顯示你的 **Client ID** 和 **Client Secret** 。請務必**立即複製並妥善保存** 它們。 + +### 5.2.3 配置 GitHub 獲取 Client ID 和 Secret + +同樣地,你也需要在 GitHub 上註冊一個 OAuth 應用。 + +1. **進入 \*\***GitHub\*\* ** Developer Settings** : + 1. 登錄你的 GitHub 賬戶。 + 2. 點擊右上角的頭像,進入 “Settings”。 + 3. 在左側導航欄的底部,找到 “Developer settings”。 + +2. **註冊新應用 (Register a new application)** : +3. 選擇 “OAuth Apps”,然後點擊 “New OAuth App”。 +4. 填寫應用名稱,例如 “My Burger Shop”。 +5. **Homepage URL** : 填寫你應用的線上地址,或者本地開發地址 `http://localhost:3000`。 +6. **Authorization \*\***callback\*\* ** URL** : 填入你的 Supabase 項目的回調 URL。同樣,你可以在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “GitHub” 中找到它,格式為 `https://<你的項目ID>.supabase.co/auth/v1/callback`。 +7. 點擊 “Register application”。 +8. **獲取 Client ID 和 Client Secret** : +9. 註冊成功後,頁面會顯示你的 **Client ID** 。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image51.png) +10. 點擊 “Generate a new client secret” 來生成你的 **Client Secret** 。同樣,請**立即複製並保存** 它。 + +### 5.2.4 在 Supabase 中配置 Provider + +現在,將我們獲取到的憑證配置到 Supabase 中。 + +1. **進入 Supabase Dashboard** : +2. 選擇你的項目,進入 “Authentication” -> “Providers”。 +3. **啟用並配置 Google** : +4. 找到 “Google” 並啟用它。 +5. 將你從 Google Cloud 獲取的 **Client ID** 和 **Client Secret** 粘貼到對應的輸入框中。 +6. 點擊 “Save”。 +7. **啟用並配置 ** **GitHub** : + 1. 找到 “GitHub” 並啟用它。 + 2. 將你從 GitHub 獲取的 **Client ID** 和 **Client Secret** 粘貼到對應的輸入框中。 + 3. 點擊 “Save”。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image52.png) + +至此,你已經能夠使用第三方賬戶在構建的網站中進行登錄,你可以直接讓 AI 基於 `Project5-Supabase-Demos/apps/project-burger-shop-auth-advanced-supabase-6`項目作為參考,在你的項目的基礎上支持用戶登錄系統,以最小成本集成包含 github 與 google 鑑權的用戶登錄界面。 + +### 5.2.6 密碼重置實現 + +作為一個成熟的用戶登錄組件,密碼重置也是極其重要的一環,本項目 `project-burger-shop-auth-advanced-supabase-6`也包含了該功能的完整實現,你可以直接讓 AI 基於本項目的密碼重置功能復刻完整的密碼重置組件。其主要分為以下幾步: + +1. 發起請求 :用戶在忘記密碼頁面輸入郵箱,前端調用 `supabase.auth.resetPasswordForEmail()` 函數,並指定一個重定向 redirectTo URL(例如 /auth/reset )。 +2. 發送郵件 :Supabase 會向該郵箱發送一封包含唯一重置鏈接的郵件。 +3. 訪問鏈接 :用戶點擊郵件中的鏈接,被重定向到應用內指定的重置頁面。 +4. 更新密碼 :在重置頁面,用戶輸入新密碼。前端調用 `supabase.auth.updateUser()` ,將新密碼提交給 Supabase。Supabase 會自動驗證鏈接的有效性並完成密碼更新。 + +最後,如果你覺得當前的密碼重置郵件過於簡陋,你可以 在 Supabase Dashboard 的 Authentication -> Email Templates 中自定義“Reset Password”郵件模板。 + +除了 Reset password 功能外,你還能看到許多其他與用戶管理相關的高級功能設定(例如 Invite user 等),你可根據對應功能各自的開發文檔,結合 Vibe coding 工具自行添加對應功能。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image53.png) + +## 5.3 實時功能 + +Supabase 的實時功能是其最強大的特性之一,為構建協作文檔、實時儀表盤、遊戲大廳或客服系統提供了極大的便利。 + +本項目 `Project5-Supabase-Demos/apps/project-burger-shop-realtime-orders-3 `通過構建一個 多人實時聊天室、光標位置共享 功能,展示了 Supabase Realtime 涉及到的三大核心能力:資料庫變更監聽 (Postgres Changes)、廣播 (Broadcast) 和 在線狀態 (Presence)。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image54.png) + +如果你覺得相關程式碼部分有一定難度,可以直接讓 AI 參考該部分文檔內容,對你的程序進行修改。 + +### 5.3.1 資料庫實時變動 Postgres Changes + +最常見的 Realtime 功能是對資料庫的變更進行實時監聽 Postgres Changes 。它允許客戶端訂閱資料庫中特定表、特定行甚至特定列的 INSERT 、 UPDATE 或 DELETE 事件。一旦資料庫發生變動(無論是通過 API 調用、Supabase Dashboard 操作,還是 SQL 腳本執行),Supabase 都會利用 PostgreSQL 的底層複製機制,立即通過 WebSocket 將變更的資料推送到所有訂閱了該頻道的前端客戶端,而無需前端通過輪詢(Polling)去反覆查詢。 + +一般而言,該功能可以在 Table Editor 中找到 Enable Realtime 點擊後啟動, 但更方便的是通過 SQL 腳本初始化執行,例如: + +```sql +-- Enable realtime replication +ALTER TABLE public.chat_messages REPLICA IDENTITY FULL; +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_publication_tables + WHERE pubname = 'supabase_realtime' + AND schemaname = 'public' + AND tablename = 'chat_messages' + ) THEN + ALTER PUBLICATION supabase_realtime ADD TABLE public.chat_messages; + END IF; +END $$; +``` + +該語句將 `chat_messages` 表添加到了 Supabase 預設的 `supabase_realtime` 中,而一旦一個表被加入到這個特殊的 `publication` 中,Supabase 的實時服務器就會開始監聽它的所有資料變更。 + +基於上面的特殊資料表,我們能夠使用監聽程式碼對錶內資料變動進行實時監聽。我們需要實現的是當一個用戶發送消息時,其他所有在線用戶都能立刻在屏幕上看到這條消息。通過訂閱 chat_messages 表的 INSERT 事件能夠實現這一點。 + +```typescript + const sub = supabase + .channel('chat_messages_channel') + .on('postgres_changes', { + event: 'INSERT', + schema: 'public', + table: 'chat_messages' + }, (payload: any) => { + console.log('New message received:', payload.new); + const newMessage = payload.new as Message; + // ... // + .subscribe((status: string) => { + console.log('Chat subscription status:', status); + }); +``` + +- `.channel('chat_messages_channel')`: 創建一個隔離的通信頻道。 +- `.on('postgres_changes', ...)`: 這是核心的訂閱方法。我們告訴 Supabase 我們只關心 `chat_messages` 表的 `INSERT` 事件。 +- `payload.new`: 當有新消息被插入資料庫時,Supabase 會將這條新資料的完整內容通過 `payload.new` 推送給所有訂閱的客戶端。 +- `.subscribe()`: 啟動訂閱。 + +### 5.3.2 資訊廣播同步 Broadcast & Presence + +對於那些不需要存入資料庫的、更“即時”的交互,比如光標移動、在線狀態等,Supabase 提供了 Broadcast 和 Presence 功能。 + +- Presence: 用於跟蹤頻道內所有客戶端的 **共享狀態** 。適合用來實現“誰在線”的功能。 +- Broadcast: 用於向頻道內的所有其他客戶端發送**低延遲**的 **臨時消息** 。 + +Presence 的核心思想是: 讓每個客戶端聲明自己的在線狀態,並由 Supabase 的服務器負責將這些狀態可靠地同步給頻道內的所有其他客戶端。實現 Presence 分為以下幾個關鍵步驟: + +1. 創建一個支持 Presence 的頻道 + +首先,我們創建了一個頻道 `lobby_presence` 來專門處理這些交互,並在配置中指定一個唯一的 key 來標識當前用戶。這個 key 通常是用戶的 ID。 + +``` +const ch = supabase.channel +('lobby_presence', { +  config: { +    presence: { key: anonymousUser.id }, +  } +}); +``` + +2. 訂閱頻道宣告“我在線”的資訊 + +一旦頻道創建成功,我們需要訂閱它。在訂閱成功的回調( status === 'SUBSCRIBED' )中,我們調用 channel.track() 方法。這個方法會將當前用戶的資訊(例如用戶ID、名稱、頭像顏色等)廣播給頻道內的所有其他客戶端,宣告自己的“在線”狀態。 + +``` +const me = { +  id: anonymousUser.id, +  name: anonymousUser.name, +  color: anonymousUser.color +}; + +ch.subscribe(async (status) => { +  if (status === 'SUBSCRIBED') { +    await ch.track(me); +  } +}); +``` + +3. 同步完整的在線列表 + +當一個新用戶加入頻道時,他們需要獲取當前所有已經在線的用戶列表。這通過監聽 presence 的 sync 事件來實現。 sync 事件會在你首次加入頻道時觸發,為你提供一個完整的“快照”。 + +channel.presenceState() 方法會返回一個對象,包含了當前頻道內所有在線用戶的狀態資訊。我們將其處理後更新到應用的 state 中,從而渲染出完整的在線用戶列表。 + +``` +ch.on('presence', { event: 'sync' }, ()  +=> { +  const state = ch.presenceState(); +  const flat = {}; +  Object.values(state).forEach((arr) => { +    arr.forEach((u) => { flat[u.id] =  +    { ...u }; }); +  }); +  setOnline(flat); +}); +``` + +4. 監聽單個用戶的加入與離開 + +除了 sync 事件,我們還可以監聽 join 和 leave 事件,以便在有新用戶進入或離開時做出即時響應,例如顯示一個 "User has joined" 的通知。 + +``` +ch.on('presence', { event: 'join' }, ({  +key, newPresences }) => { +  console.log('User joined:', key,  +  newPresences); +}); + +ch.on('presence', { event: 'leave' }, ({  +key, leftPresences }) => { +  console.log('User left:', key,  +  leftPresences); +}); +``` + +通過以上步驟,我們便構建了一個功能完備的在線狀態系統。Supabase 自動處理了用戶意外斷開連接(如關閉瀏覽器或斷網)的情況,並在適當的時候觸發 leave 事件,確保了在線列表的準確性。 + +當 Presence 讓我們知道了“誰在場”之後, Broadcast 能夠讓他們之間能夠進行“對話”,但對話的內容是短暫存儲的。一個典型的例子就是實時光標追蹤。如果每次鼠標移動都去讀寫資料庫,會造成巨大的性能浪費和延遲。 Broadcast 完美地解決了這個問題,它允許消息在各個客戶端之間直接通過 WebSocket 傳遞,完全繞過資料庫。 + +Broadcast 的工作模式主要依賴兩個核心方法: channel.send() 用於發送,channel.on() 用於接收。】 + +1. 發送端:廣播我的光標位置 + +我們為 mousemove 事件添加了一個監聽器。當鼠標移動時,我們構造一個包含用戶 ID、座標和顏色的 payload,然後通過 channel.send() 將其廣播出去,並指定事件名稱為 'cursor'。 + +```typescript +const handleMouseMove = (e) => { + const payload = { + id: anonymousUser.id, + x: e.clientX, + y: e.clientY, + name: anonymousUser.name, + color: anonymousUser.color + }; + + channelRef.current?.send({ + type: 'broadcast', + event: 'cursor', + payload + }); +}; + +document.addEventListener('mousemove', handleMouseMove); +``` + +2. 接收端:監聽並渲染他人的光標 + +在同一個頻道內,所有客戶端都使用 channel.on() 來監聽 broadcast 類型的、且 event 為 'cursor' 的消息。一旦收到匹配的消息,回調函數就會被觸發。我們從 payload 中解析出發送方的資料,並用它來更新本地的 online 狀態,從而在屏幕上實時渲染出其他用戶光標的位置。 + +```typescript +ch.on('broadcast', { event: 'cursor' }, ({ payload }) => { + setOnline((prev) => ({ + ...prev, + [payload.id]: { + ...(prev[payload.id] || {}), + x: payload.x, + y: payload.y + } + })); +}); +``` + +通過這種方式, Presence 和 Broadcast 協同工作;Presence 維護在線用戶列表,而 Broadcast 則負責在這些用戶之間傳遞像光標位置這樣的臨時狀態,最終以較低的成本實現了豐富的實時互動功能。 + +## 5.4 存儲 + +除了用戶資訊、訂單這類可規整定義的結構化資料,一個完整的應用通常還需要處理大量非結構化文件 —— 例如用戶頭像、商品展示圖、用戶上傳的訂單文檔等。這類文件的特點是體積差異大、數量可能極多(比如電商平臺的商品圖可能達數萬甚至數十萬張),若直接存儲在應用自身的業務服務器中,會顯著增加服務器的存儲負載,還可能拖慢資料讀寫速度,影響應用整體性能。 + +實際開發中,這類非結構化文件會統一交由 “對象存儲服務” 管理,OSS、Amazon S3 均屬於這類服務,它們是專門為海量文件存儲設計的 “專業存儲工具”,能高效應對文件的存儲、備份與快速讀取需求。而我們在應用中獲取這些文件時,並不會直接從對象存儲服務的 “底層倉庫” 調取,而是通過 URL 地址實現:每個存儲在對象存儲中的文件,都會被分配一個唯一的 URL(類似 “[https://xxx.oss.com/avatar/user123.jpg](https://xxx.oss.com/avatar/user123.jpg)” 的地址,可簡單理解為這個“網站”只有一張圖片),這個 URL 就像文件的 “專屬訪問地址”,前端頁面只需通過該地址,就能直接下載或加載頭像、商品圖,無需依賴應用業務服務器中轉,既提升了文件加載速度,也減輕了業務服務器的壓力。 + +本項目 `project-burger-shop-storage-uploads-4` 便通過一個用戶頭像上傳功能,深入演示瞭如何利用 Supabase Storage 構建現代化的文件上傳系統,讓開發者直觀理解非結構化文件從上傳到通過 URL 訪問的完整流程。此外,本項目使用 `Uppy` 庫來提供一個優秀的文件上傳界面,並結合 `Tus` 插件實現了可續傳上傳,通過將 Uppy 的上傳端點指向 Supabase 的標準 API (`/storage/v1/upload/resumable`) 進行工作,你可以參考類似的方式實現上傳功能組件。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image55.png) + +![](/zh-cn/stage-2/backend/database-supabase/images/image56.png) + +### 5.4.1. 存儲桶 + +Supabase Storage 的組成單元是存儲桶 Bucket。你可以把它想象成電腦操作系統中的文件夾。每個 Bucket 都可以有自己獨立的安全策略和配置。 + +Storage 內的所有文件都可以通過一個公開的 URL 直接訪問,但並不意味著任何人都可以隨意上傳或修改,具體的訪問權限將由更精細的策略來控制。和資料庫一樣,Storage 的訪問權限也是通過行級安全策略來管理的。SQL 策略寫在 storage.objects 和 storage.buckets 這兩張特殊表上,可以精確定義誰能讀取 (SELECT)、上傳 (INSERT)、更新 (UPDATE) 或刪除 (DELETE) 文件。 + +例如,我們可以創建一條策略,只允許用戶上傳到以自己 user_id 命名的文件夾下,並且只能上傳圖片類型的文件: + +``` +CREATE POLICY "Allow authenticated  +uploads to avatars bucket" +ON storage.objects FOR INSERT +TO authenticated +WITH CHECK ( +  bucket_id = 'avatars' AND +  auth.uid() = (storage.foldername(name)) +  [1]::uuid AND +  (storage.extension(name) IN ('png',  +  'jpg', 'jpeg')) +); + +CREATE POLICY "Allow public read access  +to avatars" +ON storage.objects FOR SELECT +USING ( bucket_id = 'avatars' ); +``` + +### 5.4.2 獲取可訪問文件 URL + +本項目需要你手動創建一個名為 avatars 的公共桶,所有文件將上傳至該公共桶下進行存儲。文件上傳成功後,我們只得到了它在 Storage 中的存儲路徑 ,例如 public/avatar1.png 。這只是存儲在資料庫中的一個字符串,要讓瀏覽器能夠渲染這張圖片,我們需要將其轉換為一個可訪問的 HTTP URL。 + +Supabase 提供了兩種截然不同的策略來獲取這個 URL,它們在安全性、持久性和成本控制上有著本質的區別。 + +#### 1. 公開 URL (Public URL) - 永久鏈接 + +這是最直接的方式。如果你的文件存放在一個**Public Bucket** 中,你可以獲取一個固定、永久的公開鏈接。 + +```typescript +const { data } = supabase.storage + .from('avatars') + .getPublicUrl('public/avatar1.png'); +const publicUrl = data.publicUrl; +``` + +這類鏈接具有兩大核心特點:一是簡單直接,其 URL 結構固定,在實際操作中易於拼接和管理,降低了技術使用門檻;二是利於緩存,作為永久鏈接,它能被 CDN(內容分發網路)和瀏覽器有效緩存,從而大幅提升資源的訪問速度,優化用戶體驗。基於這些特點,它適用於真正意義上的公共資源場景,例如網站 Logo、產品目錄圖片、博客文章配圖等,能很好地滿足這類資源的訪問和管理需求。 + +不過在生產環境中,這類鏈接存在明顯的被盜刷流量(Hotlinking)風險。由於鏈接是永久公開的,外部人員可以輕易將你的圖片鏈接嵌入到他們自己的高流量網站中,導致流量被非法佔用。這一行為會讓你的 Supabase 項目產生大量不必要的流量費用,而這些消耗的流量並未服務於你自身的應用,屬於典型的成本浪費,是生產環境中需要高度警惕和防範的問題;因此,我們需要轉向臨時簽名 URL 實現對外資源的暴露。 + +#### 2. 簽名 URL (Signed URL) - 臨時授權鏈接 + +為了解決公開 URL 的安全和成本問題,Supabase 提供了生成臨時簽名 URL 的方式。這是絕大多數線上應用推薦的最佳實踐,比如文生圖應用給用戶生成限時查看的圖片鏈接、電商平臺僅讓下單用戶獲取臨時發票下載地址、付費內容平臺為訂閱用戶提供短期有效的課程播放鏈接,既防文件盜用又能避免流量盜刷,適配性極強。 + +```typescript +const { data, error } = await supabase.storage + .from('avatars') + .createSignedUrl('private/user-invoice.pdf', 3600); // 鏈接有效期為 3600 秒 (1小時) +const signedUrl = data?.signedUrl; +``` + +臨時簽名 URL(Signed URL)有三大核心優勢:安全可控是指鏈接帶安全標記、有有效期,過期就用不了;權限綁定很簡單 —— 只有能看這文件的人,才能生成這個鏈接,就算文件藏在私有存儲裡(Private Bucket),他用這個鏈接也能正常打開;杜絕盜刷是因為鏈接是臨時的,複製到別處很快就失效,不會被惡意刷流量。靠這些優勢,像用戶頭像、私人照片、付費內容、訂單發票這些需要管權限的文件,都能用它。 + +從安全保障和成本控制的角度,建議養成優先使用臨時簽名 URL 的習慣。只有當某個資源明確需要永久公開、無限制訪問(比如應用的公開 Logo、公共活動宣傳圖等)時,才考慮使用 Public URL。這樣既能滿足特定業務需求,又能最大程度規避不必要的風險和成本消耗。 + +## 5.5 邊緣函數 + +Edge Function 是 Serverless(無服務器架構)生態中極具核心價值的形態之一,它為 “無自建後端” 場景提供了輕量、高效的函數運行支持。 + +什麼是 Serverless? Serverless(無服務器架構)並不意味著真的沒有服務器,而是指開發者無需關心服務器的購買、運維、配置和擴容 。你只需要編寫業務程式碼(函數),雲服務商會在特定事件觸發時自動為你分配資源運行程式碼,並按實際運行時間計費。 + +當你的應用需要執行一些不能或不應在客戶端(瀏覽器)上完成的邏輯時——例如與需要私密密鑰的第三方 API 交互、執行計算密集型任務、或強制執行複雜的業務規則——Edge Functions 就派上了用場。Supabase Edge Functions 基於 Deno 和 TypeScript,它們被部署在全球的邊緣節點上,物理距離上靠近你的用戶,從而提供極低的函數執行延遲。 + +目前主流雲廠商都推出了各自的 Edge Function 服務,常見的包括: + +- AWS Lambda@Edge:基於 AWS Lambda 延伸的邊緣函數服務,可與 CloudFront CDN 聯動,支持 Node.js、Python 等語言; +- Cloudflare Workers:Cloudflare 推出的邊緣函數,部署在其全球 275+ 邊緣節點,支持 JavaScript/TypeScript,以 “毫秒級延遲” 為核心優勢; +- Vercel Edge Functions:適配 Vercel 前端項目的邊緣函數,與 Next.js 深度集成,支持 TypeScript,主打 “前端與邊緣邏輯無縫銜接”; + +回到 Supabase ,當你的應用需要執行 “不能在客戶端(瀏覽器)完成” 的邏輯時,比如用私密密鑰調用第三方 API(如 LLM 接口)、處理計算密集型任務(如圖片壓縮)、或強制執行權限校驗(如文件訪問規則)時,Supabase Edge Functions 就能發揮作用。它基於 Deno runtime 和 TypeScript 構建,部署在全球邊緣節點上,能以 “靠近用戶的物理距離” 實現極低的執行延遲,是編寫自定義、可信服務器端邏輯的核心工具。 + +本項目 `Project5-Supabase-Demos/apps/project-burger-shop-edge-function-5`通過一個與大語言模型(LLM)實時流式對話的功能,展示了 Edge Functions 的最簡應用流程。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image57.png) + +### 5.5.1 LLM Chat 案例解析 + +假設你想在應用中集成一個類似 ChatGPT 的聊天機器人。你需要在服務器端調用 OpenAI 的 API,但這需要一個私密的 API Key。 這個 Key 絕對不能暴露在前端程式碼中 ,否則任何人都可以通過查看網頁源碼盜用你的 Key,產生高昂的費用。這正是 Edge Function 的用武之地。我們將創建一個名為 llm-chat 的函數,它充當了前端和 OpenAI API 之間的一個 安全代理 。 + +參考 `project-burger-shop-edge-function-5/scripts/llm-chat.ts`的程式碼,我們來看看它是如何工作的: + +```typescript +// scripts/llm-chat.ts +import "jsr:@supabase/functions-js/edge-runtime.d.ts"; +import { OpenAI } from "npm:openai"; + +const OPENAI_API_KEY = Deno.env.get("OPENAI_API_KEY"); + +Deno.serve(async (req) => { + try { + const openai = new OpenAI({ apiKey: OPENAI_API_KEY }); + const { prompt } = await req.json(); + + const stream = await openai.chat.completions.create({ + model: "gpt-3.5-turbo", + messages: [{ role: "user", content: prompt }], + stream: true, + }); + + return new Response(stream.toReadableStream(), { + headers: { "Content-Type": "text/event-stream" }, + }); + } catch (err) { + } +}); +``` + +在該案例中,對於密鑰安全,OPENAI_API_KEY 作為環境變量被安全存儲於 Supabase 的服務器。本地前端程式碼完全無法接觸到該密鑰,從而有效保障了密鑰的安全性。 + +### 5.5.2 創建並部署函數 + +Supabase 提供了非常友好的界面,讓你無需接觸命令行即可完成部署。 + +1. **進入 Edge Functions 面板** : +2. 登錄你的 Supabase 項目 Dashboard。 +3. 在左側導航欄中,點擊像程式碼一樣的圖標,進入 “Edge Functions”。 +4. **創建新函數** : +5. 點擊 “Create a new function” 按鈕。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image58.png) +6. 為函數命名,例如 `llm-chat`。 +7. **粘貼程式碼** : + ![](/zh-cn/stage-2/backend/database-supabase/images/image59.png) +8. 在彈出的在線編輯器中, **刪除所有默認的佔位程式碼** 。 +9. 打開你本地的 `llm-chat.ts` 文件, **複製其全部內容** 。 +10. 將複製的程式碼**粘貼**到 Supabase 的在線編輯器中。 +11. **配置\*\***環境變量\*\* ** (Secrets)** : + 1. 在側邊欄找到 Secrets。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image60.png) + 2. Name: 輸入 `OPENAI_API_KEY`。 + 3. Value: 粘貼你自己的 OpenAI API Key。 + 4. 點擊 “Save”。在這裡設置的 Secret 會被加密存儲,並安全地注入到你的函數運行時環境中。 + +若有函數需要更新,記得在 Edge Function 部分執行 Deploy updates。Supabase 會在雲端為你構建並部署這個函數。幾分鐘後,你的函數就可以在線訪問。 + +除了作為語言模型的安全代理,Edge Functions 的應用場景遠不止於此。實際上,任何需要服務器端邏輯處理的任務,無論是簡單的 API 調用、資料驗證,還是更復雜的計算,都可以通過 Edge Function 實現。它為你提供了一個輕量級、可擴展的後端,而無需管理任何服務器基礎設施。 + +如果你想探索更多可能性,可以參考項目中的其他示例。例如: + +- 圖片生成 ( txt2img.ts ) : 這個函數展示瞭如何利用 Edge Function 調用第三方的文生圖(Text-to-Image)API(如 Stability AI, Midjourney 等)來動態生成圖片。這是一種典型的計算密集型或需要安全調用外部服務的場景。與 llm-chat 案例一樣,API 密鑰被安全地存儲在 Supabase 後端,前端只負責發送文本描述,然後接收並展示生成的圖片,整個過程安全、高效。 +- 發送郵件 ( send-email.ts ) : 在應用中發送歡迎郵件、交易通知或密碼重置郵件是常見需求。 send-email.ts 示例演示瞭如何通過 Edge Function 集成郵件服務(如 Resend, SendGrid)。你無需在客戶端程式碼中暴露敏感的郵件服務 API Key,只需創建一個函數,讓前端通過調用這個函數來觸發郵件發送。 + +## 5.6 Clerk 登錄 + +Clerk 是一款專注於身份認證與用戶管理的專業開發工具,核心能力覆蓋用戶註冊、登錄、賬號安全MFA、權限控制、會話管理等全鏈路身份認證相關需求,能幫助開發者快速搭建安全、靈活且符合現代應用標準的用戶體系,無需從零開發複雜的身份邏輯。 + +本部分將介紹如何從零開始配置 Clerk 服務,並將其與 Supabase 進行整合。你可以在項目 `project-burger-shop-auth-advanced-clerk-7` 中體驗全流程。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image61.png) + +### 5.6.1 創建 Clerk 應用與獲取密鑰 + +在使用本項目之前,你需要擁有一個 Clerk 賬號並創建一個應用。 + +1. 註冊與創建: + 1. 訪問 [dashboard.clerk.com](https://dashboard.clerk.com/) 並註冊賬號。 + 2. 點擊 "Create application" 。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image62.png) + 3. 輸入應用名稱(例如 "Burger Shop")。 + 4. 在 "How will your users sign in?" 中,默認勾選 Email , Google , GitHub 。 + 5. 點擊 Create application 。 +2. 獲取 API Keys: + 1. 創建成功後,你會被引導至 API Keys 頁面。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image63.png) + 2. 找到 Publishable key (以 `pk_` 開頭) 和 Secret key (以 `sk_` 開頭)。 + ![](/zh-cn/stage-2/backend/database-supabase/images/image64.png) + 3. 將它們複製到你的 `.env.local` 文件中(參考本項目 `.env.example`): + + ```bash + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... + CLERK_SECRET_KEY=sk_test_... + ``` + +### 5.6.2 配置 Supabase 和 Clerk 的原生集成 + +在進一步使用前,我們需要集成 Supabase 與 Clerk 的關聯關係,方便之後登錄的鑑權跳轉以及控制對特定資料庫的訪問權限。Supabase 與 Clerk 提供官方原生集成能力,通過該集成可快速實現兩者的身份認證打通,無需手動配置複雜的適配邏輯,大幅簡化用戶登錄、權限校驗等功能的開發流程: + +1. 在 Clerk 中激活對 Supab ase 的官方集成 + 1. 登錄 [Clerk Dashboard](https://dashboard.clerk.com/)。 + 2. 在左側菜單導航至 Integrations (集成)。 + 3. 在列表中找到並點擊 Supabase。 + 4. 開啟 Enable Supabase 開關(或點擊 Activate integration)。 + 5. 關鍵步驟:激活成功後,頁面會顯示你的 Clerk Domain(格式通常為 `https://.clerk.accounts.dev` 或你的自定義域名)。請複製這個 Domain 地址,下一步會用到。 +2. 在 Supabase 中添加 Clerk 提供商 + 1. 登錄 [Supabase Dashboard](https://supabase.com/dashboard) 並進入你的項目。 + 2. 在左側菜單導航至 Authentication > Sign In / Up (或者直接點擊 Providers)。 + 3. 點擊 Add provider 按鈕,從下拉列表中選擇 Clerk。 + 4. 在彈出的 Clerk Domain 輸入框中,粘貼你剛才從 Clerk 複製的 Domain 地址。 + 5. 點擊 Save 保存配置。 + +### 5.6.3 通過 Webhook 同步用戶資料至 Supabase + +僅僅是集成只滿足了鑑定權限的需求,但這並不會將 Clerk 中已經註冊的用戶資訊同步到 Supabase,為了方便管理,我們還需要在 Supabase 的 `public.users` 表中保留一份用戶備份,以便進行關聯查詢或資料分析。我們可以通過 Clerk Webhooks 實現這一功能,完整過程如下: + +1. **Clerk 發送通知** : 當用戶在 Clerk 註冊或更新資料時,Clerk 會向我們配置的 Webhook URL 發送一個 POST 請求。 +2. **Supabase 接收並寫入** : Edge Function 接收請求,驗證簽名(確保安全),然後將用戶資料更新到 Supabase 的資料庫表中。 + +在開始之前,我們需要配置同步資訊所需的資料表: + +```sql +-- File: init.sql + +-- 1. Create `users` table for synced Clerk users +-- This table will store user data pushed from Clerk Webhooks. +CREATE TABLE public.users ( + id TEXT NOT NULL PRIMARY KEY, -- Corresponds to Clerk User ID + email TEXT, + first_name TEXT, + last_name TEXT, + image_url TEXT, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- 2. Enable Row Level Security (RLS) on the table +-- This is an important security measure to ensure users cannot access any data by default. +ALTER TABLE public.users ENABLE ROW LEVEL SECURITY; + +-- 3. Create RLS policies +-- Policy 1: Allow authenticated users to read their own user info. +-- `auth.jwt()->>'sub'` extracts the user ID from the JWT provided by Clerk. +CREATE POLICY "Authenticated users can view their own user record" +ON public.users FOR SELECT +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); + +-- Policy 2: Allow users to update their own info. +CREATE POLICY "Authenticated users can update their own user record" +ON public.users FOR UPDATE +TO authenticated +USING ( (SELECT auth.jwt()->>'sub') = id ); +``` + +以及在 Supabase 中啟用對應的 Edge function: + +```JavaScript +// File path: supabase/functions/clerk-webhooks/index.ts + +import { serve } from 'https://deno.land/std@0.177.0/http/server.ts' +import { Webhook } from 'npm:svix' +import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' + +// Get Clerk Webhook signing secret from environment variables +const CLERK_WEBHOOK_SECRET = Deno.env.get('CLERK_WEBHOOK_SECRET') + +if (!CLERK_WEBHOOK_SECRET) { + throw new Error('CLERK_WEBHOOK_SECRET is not set in environment variables') +} +const supabaseAdmin = createClient( + Deno.env.get('SUPABASE_URL')!, + Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')! +) + +serve(async (req) => { + try { + // 1. Get Svix signature info from request headers + const headers = Object.fromEntries(req.headers) + const svix_id = headers['svix-id'] + const svix_timestamp = headers['svix-timestamp'] + const svix_signature = headers['svix-signature'] + + if (!svix_id || !svix_timestamp || !svix_signature) { + return new Response('Missing Svix headers', { status: 400 }) + } + + const payload = await req.json() + const body = JSON.stringify(payload) + + // 2. Verify Webhook signature validity using the secret + const wh = new Webhook(CLERK_WEBHOOK_SECRET) + const evt = wh.verify(body, { + 'svix-id': svix_id, + 'svix-timestamp': svix_timestamp, + 'svix-signature': svix_signature, + }) + + const { id } = evt.data + const eventType = evt.type + console.log(`Received webhook event: ${eventType} for user: ${id}`) + + // 3. Execute database operations based on event type + switch (eventType) { + case 'user.created': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin.from('users').insert({ + id, + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + }) + if (error) throw error + console.log(`User ${id} created in Supabase.`) + break + } + + case 'user.updated': { + const { id, first_name, last_name, image_url, email_addresses } = evt.data + const { error } = await supabaseAdmin + .from('users') + .update({ + first_name, + last_name, + image_url, + email: email_addresses[0]?.email_address, + updated_at: new Date().toISOString(), // Update timestamp + }) + .eq('id', id) + if (error) throw error + console.log(`User ${id} updated in Supabase.`) + break + } + + case 'user.deleted': { + // For delete events, ID might be at the top level + const deletedId = id + if (!deletedId) { + return new Response('Deleted user ID not found', { status: 400 }) + } + const { error } = await supabaseAdmin.from('users').delete().eq('id', deletedId) + if (error) throw error + console.log(`User ${deletedId} deleted from Supabase.`) + break + } + } + + return new Response('Webhook processed successfully', { status: 200 }) + } catch (err) { + console.error('Error processing webhook:', err.message) + return new Response(`Webhook Error: ${err.message}`, { status: 400 }) + } +}) +``` + +初始化 Supabase 資料表與函數結束後,你還需要在 Clerk 中啟用 Webhooks 支持: + +- 在 Clerk Dashboard -> **Webhooks** 中添加 Endpoint,填入Supabase Edge Function 的 URL。 +- 勾選 `user.created`, `user.updated`, `user.deleted` 等事件。 + +![](/zh-cn/stage-2/backend/database-supabase/images/image65.png) + +一旦設置成功,你能夠在 Message Attempts 中看到不同請求資訊,點擊後可看到詳細的請求返回參數結果;如果 webhook 在請求 Edge function 時出現問題,你可以快速在返回值中找到詳細原因結果。推薦你同時對照 Clerk 和 Supabase 的請求日誌資訊,用於分析各個函數設定是否正確。 + +### 5.6.4 Clerk 中的第三方登錄支持 + +在深入瞭解如何對 Clerk 支持第三方登錄前,我們先明確兩個核心概念:開發環境與生產環境,這是軟體從 “開發測試” 到 “上線可用” 的兩個關鍵階段,二者的定位、用途和安全要求截然不同: + +- 開發環境:開發者本地或測試服務器使用的環境,僅用於功能開發、調試和內部驗證(如本地 localhost:3000 服務),不對外開放 +- 生產環境:應用正式上線後,面向真實用戶的公開環境(如部署在 Vercel、阿里雲等平臺的 https://my-app.com) + +而 Clerk 對社交登錄區分這兩種環境,本質是平衡 “開發效率” 與 “生產安全”:開發階段需減少冗餘配置以快速驗證功能,生產階段需通過專屬憑證保障資料安全,同時符合 Google、GitHub 等第三方 OAuth 平臺的規則(線上應用必須綁定專屬域名與憑證,不允許使用共享資源)。下面具體說明兩種環境下 Clerk 社交登錄的差異配置: + +1. **開發環境快速驗證** + +開發環境中,Clerk 已預置共享 OAuth 憑證和默認重定向 URI,無需前往 GitHub/Google 申請專屬憑證,操作步驟如下: + +- 登錄 Clerk Dashboard ,在左側導航欄進入 SSO connections (SSO 連接)頁面。 +- 點擊 Add connection (添加連接),選擇 For all users (對所有用戶生效)。 +- 在 Choose provider (選擇提供商)下拉菜單中,按需選擇 GitHub 或 Google 。 +- 直接點擊 Add connection (添加連接),Clerk 會自動用共享憑證完成綁定。 + + 配置後,本地啟動應用(如 `localhost:3000`)並點擊“Sign in with GitHub/Google”,Clerk 會自動代理登錄請求,快速驗證功能是否正常。 + +2. **生產環境自定義憑證配置** + +(注:如果發現有環節和預期不一致,建議閱讀官方文檔進行最新方式的嘗試) + +應用部署上線(如 Vercel、阿里雲)並切換到 Clerk Production Instance 後,共享憑證失效,需為 GitHub/Google 配置自定義 OAuth 憑證(建議同時打開 Clerk Dashboard 和第三方平臺頁面,方便同步操作): + +- 前置通用操作(Clerk 控制檯): + - 進入 Clerk SSO connections 頁面,點擊 Add connection → 選擇 For all users 。 + - 選擇目標平臺(GitHub/Google),確保開啟 Enable for sign-up and sign-in (允許註冊登錄)和 Use custom credentials (使用自定義憑證)。 + - 複製頁面中的 Authorization Callback URL (GitHub)或 Authorized Redirect URI (Google),保存到安全位置,不要關閉當前頁面/彈窗。 +- 2.1 GitHub 平臺配置: + - 登錄 GitHub,進入 Developer Settings (路徑:頭像 → Settings → Developer settings → OAuth Apps)。 + - 點擊 New OAuth app ,填寫資訊:`Application name`(應用名稱)、`Homepage URL`(生產域名,如 `https://my-app.com`)、`Authorization Callback URL`(粘貼從 Clerk 複製的地址)。 + - 點擊 Register application ,再點擊 Generate a new client secret ,保存生成的 Client ID 和 Client Secret (Secret 僅顯示一次)。 + - 回到 Clerk 彈窗,粘貼 Client ID 和 Client Secret,點擊 Add connection 完成配置(若關閉彈窗,可在 SSO connections 找到 GitHub 連接,在“Use custom credentials”模塊補填)。 +- 2.2 Google 平臺配置: + - 登錄 Google Cloud Console ,選擇已有項目或新建項目(如“My App Production”)。 + - 點擊左上角菜單 → APIs & Services → Credentials ,點擊 Create Credentials → OAuth client ID (首次配置需先完成 OAuth consent screen 設置,選擇“External”並填寫應用資訊)。 + - 選擇 Application type 為 Web application ,配置: + 1. `Authorized JavaScript origins`:添加生產域名(如 `https://my-app.com`、`https://www.my-app.com`),本地驗證可補充 `http://localhost:端口號`。 + 2. `Authorized Redirect URIs`:粘貼從 Clerk 複製的地址。 + - 點擊 Create ,保存彈窗中的 Client ID 和 Client Secret ,回到 Clerk 彈窗粘貼並點擊 Add connection 。 + - 關鍵注意事項: + 1. 禁止 WebView 登錄:Google OAuth 不支持應用內瀏覽器登錄,需參考 [Google 官方文檔](https://support.google.com/cloud/answer/7657789) 調整。 + 2. 切換髮布狀態:默認“Testing”狀態僅支持 100 個測試用戶,需在 OAuth consent screen 將“Publishing status”改為 In production (需通過 Google 審核)。 + 3. 阻止子郵箱:Clerk 默認攔截含 `+`/`=`/`#` 的 Google 郵箱(如 `user+alias@example.com`),可在 Google 連接詳情頁開啟/關閉 Block email subaddresses (建議開啟提升安全性)。 + 4. 支持 Google One Tap:配置完成後,可集成 Clerk `` 組件實現“一鍵登錄”,參考 [Clerk 組件文檔](https://clerk.com/docs/components/social-connections/google-one-tap)。 + +3. 測試第三方登錄連接 + +配置完成後,通過 Clerk 內置 Account Portal 驗證功能: + +- 進入 Clerk Dashboard,左側導航欄進入 Account Portal 頁面。 +- 在“Sign-in”模塊右側,點擊“訪問登錄頁面”按鈕,跳轉至對應環境登錄頁: + - 開發環境:`https://你的域名.accounts.dev/sign-in`(如 `https://my-app.accounts.dev/sign-in`)。 + - 生產環境:`https://accounts.你的域名.com/sign-in`(如 `https://accounts.my-app.com/sign-in`)。 +- 點擊“Sign in with GitHub/Google”,用對應平臺賬號登錄,若能成功跳轉並返回應用,說明連接配置正常。 + +# 6. 從 Supabase 到更多後端開發組件(進階) + +在上文中,我們主要是站在 Supabase 的視角,去看“一個以 Postgres 為核心的一站式後端平臺”能幫我們解決哪些問題:認證、資料庫、文件存儲、實時通信、邊緣函數等,都被集成在同一個控制檯裡,開箱即用、體驗統一,非常適合快速起步和中小型項目。 + +但從更長期、更工程化的角度來看, **Supabase 提供的每一塊能力(Auth / Storage / Edge Functions / Realtime / Database),在業界幾乎都有對應的專業替代方案** ——既包括同類 BaaS 平臺,也包括更“單點突破”的雲服務和開源組件。作為上進的個人開發者和初創團隊來說,瞭解這些替代選項有幾個好處: + +- 判斷當前項目是否“全用 Supabase 就夠了”,還是某一塊需要更專業/更便宜/更易合規的專用服務; +- 當項目規模變大或需求變複雜時,是否可以把某個模塊從 Supabase 替換出去(例如改用專門的 Auth 平臺或對象存儲),而不是一開始就被平臺徹底鎖死; +- 拓寬技術選型視野,即使暫時不更換,也能大致知道“如果不用 Supabase 的 X 功能,我還有哪些常見選擇”。 + +本節將分別介紹 Supabase 所覆蓋的幾大能力在市場上的主流替代方案,例如:認證(Auth)、文件存儲(Storage)、邊緣函數(Edge Functions)、實時通信(Realtime)、資料庫託管等。簡單對比它們在功能特性、免費額度/定價、易用性以及社區流行度等方面的差異, 讓你對後端組件工具庫有更全面的理解。 + +## 同類 Baas 平臺 + +在開始之前,我們可以瀏覽同類的 Baas 平臺,若覺得 Supabase 不夠好用,你可以根據需求選擇不同替代品進行嘗試。 + +| 平臺/服務 | 類型 | 免費額度/定價 | 特點 / 適用場景 | +| ------------------------ | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| Firebase(Google) | 全託管 BaaS(Auth + Firestore + Storage + Functions + Hosting) | Spark:免費輕量額度;Blaze:按量計費(Firestore/Storage/Functions 分別算) | 行業最成熟、文檔好、上手快、實時能力強。適用於中小型產品、移動/前端主導團隊。缺點:計費複雜、鎖定性強、查詢限制多(尤其 Firestore)。 | +| Supabase | 開源 BaaS(Postgres + Auth + Storage + Edge Functions + Realtime) | 免費:500MB DB、1GB Storage、無服務器函數少量調用;Pro:按實例計費 | 最像 Firebase 的 SQL 版;界面優秀、體驗現代、可自託管。適用於需要強 SQL、BI、事務能力的應用。缺點:高併發或複雜函數成本較高。 | +| Appwrite Cloud | 開源一站式 BaaS(DB + Auth + Storage + Functions + Realtime) | 免費:包含基本 DB/Storage/FaaS;付費按資源級別計費 | 體驗現代化、API 統一、可自託管;適合開發者友好的應用快速迭代。缺點:生態還不如 Firebase/Supabase 成熟;性能在大型應用中需要測試。 | +| Nhost | Postgres + GraphQL + Auth + Storage + Functions | 免費:1GB DB、1GB Storage、少量函數調用 | 類似“Supabase + Hasura”;天然 GraphQL;適合前端團隊與 React/Next.js 項目。缺點:生態小、成本隨用量升高。 | +| AWS Amplify | AWS 一站式後端(Cognito + AppSync + DynamoDB + Storage + Functions + Hosting) | 免費:Hosting 額度 + Cognito 10k MAU + 部分函數額度 | 大而全,適合已有 AWS 基礎的團隊;企業級可靠性。缺點:最難上手,服務碎片化;初創團隊維護成本高。 | +| Xata(近兩年快速增長) | 多模型資料庫 + Auth + Edge Functions | 免費:250k 記錄、15GB 帶寬 | 雖然更偏「DB + API」,但提供 Auth、文件、邏輯,可作為輕量全棧後端。UI/開發體驗極佳。缺點:功能不如 Firebase/Supabase 全面。 | +| Convex(開發者體驗極強) | 託管資料庫 + Auth + Functions(前端優先) | 免費開發版;付費按請求量計費 | 極簡上手;無需 schema;前端寫函數即可用後端。適合 MVP/快速驗證。缺點:高度綁定平臺,遷移成本高;不算完全傳統 BaaS。 | + +## 認證 (Auth) + +| 工具/平臺 | 功能特點 | 免費額度/定價 | 適用場景與優缺點 | +| ----------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| Firebase Authentication | Google 提供的 BaaS 身份驗證服務,支持郵箱/密碼、手機、社交登錄、匿名等常見方式。Spark 免費方案支持最高50k 月活躍用戶。 | Spark(免費)50k MAU;Blaze 按量計費 | 集成 Google 生態,文檔豐富,上手簡單;功能全面(MFA、阻塞函數等),適合快速開發。但與 Firebase 平臺綁定,擴展到其他服務需額外配置。 | +| Auth0 (Okta) | 全託管身份認證平臺,支持社交登錄、企業 SSO、多因子認證、規則擴展等強大功能。 | 免費方案25k MAU,付費按 MAU 計費 | 企業級功能齊全(RBAC、審計日誌等),適合中大型應用;界面友好。缺點是 MAU 上升時成本高,免費版功能有限(如不含 MFA/RBAC)。社區知名度高,用戶眾多。 | +| AWS Cognito | 亞馬遜雲原生身份服務,支持社交及 SAML 聯合登錄。直接登錄用戶池提供每月10k MAU 免費,超過部分按 0.0055 美元/MAU 收費。 | 免費10k MAU/月,超出按量付費 | 與 AWS 生態深度集成(可無縫配合 API Gateway、Lambda 等),入門門檻略高,文檔較複雜;免費額度有限,適合已有 AWS 使用習慣的團隊。 | +| Logto | 開源身份認證平臺,自託管版免費,雲服務計劃免費50k MAU。支持多語言、多租戶、OAuth/OIDC 等。 | 社區版免費;Logto Cloud 免費50k MAU | 近期流行的 Auth0 開源替代方案,GitHub 已有 10k+ Stars。易擴展,自託管降低成本;缺點是生態和文檔相對較新,社區規模略遜於 Firebase/Auth0。 | +| Keycloak | 知名開源 IAM/SSO 解決方案,支持用戶名密碼、LDAP、SAML、OAuth2 等。 | 完全免費,需自託管 | 功能強大、可擴展(支持細粒度權限控制),企業級功能豐富;但部署和維護複雜度高,對小團隊而言學習曲線較陡。缺點是對容器化和集群運維要求較高。 | + +## 文件存儲 (Storage) + +| 平臺/服務 | 類型 | 免費額度/定價 | 特點/適用場景 | +| ---------------------------------------- | -------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| Amazon S3 | 雲對象存儲(AWS) | AWS 免費套餐提供 5GB 存儲、20k GET/PUT 請求/月,超出按使用量付費 | 行業標準的對象存儲,可靠性高、全球多區域部署。功能全面,與 AWS 生態整合良好;定價較複雜,新用戶需瞭解計費規則。 | +| Google Cloud Storage(Firebase Storage) | 雲對象存儲(Google) | Firebase Spark 方案提供免費額度(1GB 存儲 + 流量限制),Blaze 付費 | 與 Firebase/Google Cloud 緊密集成,易於管理;支持 CDN 加速、細粒度安全規則。 | +| 騰訊雲 COS / 阿里雲 OSS | 雲對象存儲(國內) | 按量付費(各有新用戶贈送額度,如OSS有首年40GB免費等) | 面向國內市場,高性能、大規模對象存儲;與中國雲生態整合,文檔較完善。阿里OSS 功能全面、全球加速;七牛KODO 專注多媒體處理,成本較低,適合個人和小團隊。 | +| MinIO | 開源 S3 兼容存儲 | 開源免費(自建) | 輕量級、高性能、與 S3 API 兼容,適合在私有云或本地搭建對象存儲。文檔和社區活躍;需自己維護基礎設施。 | +| Cloudinary / Imgix 等 | 媒體存儲+CDN | 基本免費方案(如 Cloudinary 免費 25GB/月帶寬) | 針對圖片/影片優化的雲存儲+CDN 服務,提供實時轉碼、壓縮等高級功能。適合媒體項目,但功能較專一,作為通用文件存儲使用成本偏高。 | + +## 邊緣函數 (Edge Functions) + +| 平臺/服務 | 特點 | 免費額度/定價 | 適用場景與優缺點 | +| -------------------------------------- | ------------------------------------------ | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Cloudflare Workers | 全球分佈式 JavaScript/Wasmtime 環境 | 免費計劃:每天 100k 請求;標準計劃$5/月含1,000萬請求 | 運行在 Cloudflare 邊緣節點,延遲極低;適合全局分發的邏輯、靜態資源渲染等。免費配額較少(相當於每月約300萬請求),上手簡單。缺點是運行時(JS/Wasmtime)限制與調試工具有限。 | +| Vercel Edge Functions | 隨 Next.js/前端框架無縫集成,支持 JS/TS/Go | Hobby 免費:每月 100萬 函數調用,100萬 邊緣請求 | 深度集成前端框架,自動部署;適合現代 Web 應用。免費額度充足,默認運行時 10s,可提升至 60s。缺點是免費版團隊協作功能受限;依賴 Vercel 平臺。 | +| Netlify Edge / Functions | Node.js 雲函數+邊緣路由(NFT) | 免費:300 代幣/月(約相當於每月 1M 請求);按信用點計費 | 支持 Node.js 函數、邊緣處理路由等。免費額度用於構建、函數和帶寬,適合前端全棧部署。優點是簡便易用,集成 Git 部署;缺點是免費額度使用需算計(10k 請求 = 3 點)。 | +| AWS Lambda@Edge / CloudFront Functions | AWS 無服務器邊緣計算 | AWS Lambda(1M 免費請求/月+400k GB-s)+ CloudFront $0.085/每10萬調用起 | 與 CloudFront 集成,可在邊緣執行程式碼。適合需要 AWS 生態(如在節點層面做權限或 A/B 測試)。優點是靈活強大;缺點是配置複雜,延遲略高於 Cloudflare/Vercel。 | + +## 實時通信 (Realtime) + +| 平臺/服務 | 功能特點 | 免費額度/定價 | 適用場景與優缺點 | +| -------------------------------------- | ------------------------------------------------ | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| Firebase Realtime Database / Firestore | Google BaaS 實時資料庫;支持資料變更推送 | Spark 免費:實時資料庫1GB 存儲 & 限額;Blaze 按量付費 | 強集成 Firebase 生態,實時監聽簡單。優點是免費起步快;缺點是資料庫類型(JSON/NoSQL),複雜查詢能力弱。 | +| Ably | 實時消息與 pub/sub 平臺,支持 WebSocket、MQTT 等 | 免費包:每月 6,000,000 條消息 | 功能全面的實時消息服務,高併發支持;免費額度可達600萬消息/月。社區與文檔較好,適合全球分佈。 | +| Pusher Channels | 事件推送服務,支持頻道/事件機制 | Sandbox 免費:每日 200k 消息,100 併發連接 | 易用的 WebSocket 服務,文檔齊全,適合快速實現聊天和通知功能。免費版限制消息量和連接數;付費後擴展性好。 | +| 自建 WebSocket/Socket.IO | 自己搭建服務器(Node.js、Elixir 或 Go 等) | 自行託管成本(如服務器費用) | 靈活度最高,可根據需求定製協議和拓撲。適合對成本控制嚴格且技術成熟的團隊。缺點是需自行處理可用性、擴展和跨域等問題。 | + +## 資料庫 + +| 平臺/工具 | 資料庫類型 | 免費額度/定價 | 主要特點 | +| ---------------------------- | --------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| Neon (Serverless PostgreSQL) | 關係型(PostgreSQL) | 免費計劃:0.5GB 存儲,主分支永久在線,20h 分支計算/月 | 雲原生無服務器 Postgres,支持自動伸縮和分支(fork 測試)。免費額度對小項目夠用,適合現代開發流程。分支功能強大,但免費額度較小。 | +| Aiven PostgreSQL | 關係型(PostgreSQL/MySQL) | 免費計劃:1GB 存儲,1 vCPU,1GB 內存 | 託管級資料庫服務,支持跨雲多區域遷移。提供有 MySQL、Redis 等可選。免費額度適合開發和小型項目;商業版支持高可用集群和監控。 | +| CockroachDB Cloud | 分佈式 SQL(兼容 PostgreSQL) | 免費計劃:10GB 存儲 | 類似 Google Spanner 的分佈式 SQL 資料庫,自動分片擴展。免費10GB 空間較慷慨;適合需要橫向擴展和高一致性的應用。商業版 SLA 高。 | +| TiDB Cloud | 分佈式關係型(MySQL 兼容) | 免費計劃:每節點5GB,總計最多25GB | 開源 TiDB 的雲版,兼容 MySQL 協議,分佈式架構。免費額度充足,適合熟悉 MySQL 的團隊,性能優秀;缺點是運維相對複雜(針對大型場景)。 | +| MongoDB Atlas | 文檔型(NoSQL MongoDB) | 免費 M0 集群:0.5GB 存儲 | 雲端 MongoDB,靈活的文檔模型,支持豐富查詢和索引。免費 0.5GB 資料庫適合測試和小型應用;可按需橫向擴展。學習曲線略高於關係型資料庫。 | +| SQLPub | 多資料庫(MySQL、PostgreSQL、Redis 等) | 免費計劃:36,000 請求/小時,30 併發連接,500MB 存儲 | 一站式資料庫平臺,支持多種資料庫類型。免費版適合學習和小項目;優點是支持多種 DB,缺點是存儲額度較小。 | + +以上替代方案各有側重:開源更靈活可控(Keycloak、MinIO、Socket.IO、Neon、CockroachDB 等),雲託管服務更易上手(Firebase、Auth0、Cloudflare、Vercel、Netlify、AWS、Aiven、MongoDB Atlas 等)。選擇時可根據項目需求、團隊技術棧、預算和社區生態等權衡。個人項目可優先選用免費配額充足、易集成的服務(如 Firebase 系列、七牛存儲、Cloudflare Workers、Neon、CockroachDB 等),而對企業級或特定安全需求,則可考慮功能更豐富但收費較高的方案(Auth0、Alibaba/Tencent 雲、AWS、TiDB/Aiven 等)。你可以在實際應用中不斷嘗試,直到選擇出最適合的後端開發工具組件。 + +# 總結 + +在今天的課程中,我們系統學習了資料庫的基礎概念、Supabase 的核心定義及其操作細節。後續在實踐過程中,你可根據項目的實際應用場景與需求,隨時回頭翻閱這份文檔作為參考。 + +請時刻記住一個重要原則: **先完成,再完美!** 無需追求一步到位,我們完全可以通過持續迭代優化,逐步靠近更優的成果。祝你在後續的項目實踐中一切順利! + +# 📚 課後作業 + +1. 開發一個包含用戶管理系統和資料庫的應用程序。最好包含更多的Supabase 功能 (Realtime / cloud storage / Edge function). diff --git a/docs/zh-tw/stage-2/backend/git-workflow/index.md b/docs/zh-tw/stage-2/backend/git-workflow/index.md new file mode 100644 index 0000000..5fc4c1f --- /dev/null +++ b/docs/zh-tw/stage-2/backend/git-workflow/index.md @@ -0,0 +1,261 @@ +# Git 和 GitHub 工作流 + +在之前的課程中,我們學習瞭如何使用基於 Web 的 vibe coding 工具編寫程式碼。每次對話都會創建一個新版本的程式碼。但是,讓我們思考一個問題:如果我們想恢復到之前的修改,有沒有方便的方法?有沒有一種工具可以記錄我們在不同階段的程式碼,使我們能夠隨時在不同版本之間切換和修改? + +為了滿足這一需求,版本控制軟體應運而生。在這篇文章中,我們將介紹最著名的版本控制程序——Git——以及最好的程式碼託管平臺——GitHub。我們將學習如何使用 Git 進行程式碼管理,如何從 GitHub 獲取他人的程式碼,如何上傳我們自己的程式碼,以及如何與他人合作進行大型項目。 + +無論是個人項目的版本跟蹤,團隊協作中的程式碼同步,還是為開源社區做貢獻,Git 和 GitHub 都是現代開發者的必備工具。通過掌握它們,你將能夠更高效地管理程式碼,根據需要創建檢查點,在程式碼的不同階段之間自由切換,並輕鬆處理從單個文件更改到開發大型項目的所有事務——使每一次程式碼迭代都可控且可追溯。 + +> 💡 **前置知識** +> +> 在學習 Git 之前,建議你先了解以下概念: +> - [什麼是終端/命令行](/zh-tw/appendix/2-development-tools/command-line-shell) - 學習如何使用命令行與計算機交互 +> - [什麼是 Git](/zh-tw/appendix/2-development-tools/git-version-control) - 瞭解 Git 版本控制系統的核心概念 +> +> 本文將重點介紹 GitHub 工作流和實際操作,上述基礎知識請參考附錄鏈接。 + +# Git 快速開始 + +在開始使用 Git 之前,請確保你已經閱讀了附錄中關於[命令行](/zh-tw/appendix/2-development-tools/command-line-shell)和[Git 基礎](/zh-tw/appendix/2-development-tools/git-version-control)的內容。本文將假設你已經具備這些基礎知識,並直接講解如何安裝配置 Git 以及使用 GitHub 進行協作。 + +## 如何安裝 Git + +我們將演示在不同計算機操作系統上安裝 Git 的三種方法。請根據你的系統版本按照說明進行操作: + +### Windows + +1. 前往 [Git 官方下載頁面](https://git-scm.com/download/win) 並下載適合你係統的安裝程序:[安裝包](https://github.com/git-for-windows/git/releases/download/v2.51.0.windows.1/Git-2.51.0-64-bit.exe)。默認情況下,推薦使用 x64 安裝程序。 +2. 雙擊安裝程序並按照安裝嚮導說明進行操作: + ![](/zh-cn/stage-2/backend/git-workflow/images/image5.png) + 1. 建議保持默認選項。如果你需要自定義,請注意以下幾點:(在大多數情況下,你可以一直點擊"Next") + - 選擇 Git 使用的默認編輯器:選擇你喜歡的編輯器(如 VS Code)。你可以默認選擇第一個選項,即 Vim(一個文本編輯器),或選擇"Visual Studio Code as Git's default editor"選項(需要預先安裝 VS Code)。你可以保持默認選擇並點擊"Next"繼續。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image6.png) + - 選擇如何使用 Git:這三個選項控制 Git 在系統中的可訪問性。建議選擇選項 2("from command line and 3rd-party software")——它將基本的 Git 工具添加到 PATH 中,讓你可以在 Git Bash、命令提示符、PowerShell 和 IDE 中使用 Git,而不會使系統混亂。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image7.png) + +3. 安裝後,在桌面上右鍵單擊。如果在菜單中看到"Git Bash Here",則安裝成功。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image8.png) + +### MacOS + +對於 macOS,你可以首先在終端中輸入 `git --version` 來檢查是否已經安裝了 Git。如果沒有,系統會提示你安裝——只需按照說明完成安裝即可。 + +1. 方法 1:通過 Homebrew 安裝 + 如果你安裝了 [Homebrew](https://brew.sh/)(Mac 包管理器),請打開終端並輸入 + ```bash + brew install git + ``` +2. 方法 2:(推薦)通過 Xcode 安裝: https://developer.apple.com/xcode/ ,Xcode 內置了 Git。安裝後,只需按照說明繼續操作。 + +### Linux + +大多數 Linux 發行版可以通過其包管理器安裝 Git: + +- Ubuntu/Debian: + +```bash +sudo apt update +sudo apt install git +``` + +- CentOS/RHEL: + +```bash +sudo yum install git +``` + +- 驗證安裝:在終端中輸入 git --version。如果顯示版本號,則安裝成功。 + +## Git 初始化 + +安裝 Git 後,你首先需要配置你的用戶資訊——這是使用 Git 進行版本控制的基本步驟。在終端中執行以下命令(將括號中的內容替換為你自己的資訊): + +```bash +# 設置全局用戶名(將顯示在提交記錄中) +git config --global user.name "Your Name" + +# 設置全局郵箱(建議使用在 GitHub/GitLab 等平臺上註冊的郵箱) +git config --global user.email "your.email@example.com" +``` + +Git 會將此資訊嵌入到每個提交記錄中,作為每次修改的"作者資訊"。查看版本歷史記錄(例如,使用 git log)時,你可以清楚地看到誰修改了每一行程式碼,便於追溯責任和溝通。在協作項目中,統一的身份資訊使團隊成員能夠快速識別誰做了哪些更改,從而提高協作效率(例如通過提交記錄找到相關開發人員討論問題)。 + +你可以通過在命令行中輸入 `git config --list` 來查看當前的 Git 配置資訊,以確認設置成功。 + +# 什麼是 GitHub + +GitHub 是一個基於 Git 的程式碼託管平臺。它不僅為 Git 倉庫提供遠程存儲,還包括協作工具(如 Issues、Pull Requests、Projects),使開發者更容易分享程式碼和協作。簡而言之,Git 是一個本地版本控制工具,而 GitHub 是一個遠程"程式碼倉庫雲盤 + 協作社區"。 + +GitHub 不僅是世界上最大的程式碼託管平臺,也是全球最活躍、最具影響力的開源社區。這裡"開源"的核心思想是任何人都可以下載並運行軟體的源程式碼。這種模式允許世界各地的人們檢查彼此的程式碼並進行修改,或基於此創建新項目。例如,你可以在 GitHub 上找到各種學習教程以及用於訓練 GPT 模型的框架(如 PyTorch)的完整源程式碼。每天,無數人在全球範圍內協作審查和改進程式碼。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image9.png) + +許多大公司在 GitHub 上開源他們的程序或教程,以獲得行業競爭優勢——這也可以看作是一種廣告形式。在 GitHub 社區中,項目獲得的"星標 (stars)"數量是衡量其價值的主要指標;項目或組織擁有的星標越多,其可信度和影響力就越大。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image10.png) + +在我們的課程中,支持資源和作業也將上傳到專用的 GitHub 倉庫。通過上傳作業的過程,你將逐漸熟悉並掌握 GitHub 的使用,為未來應用程序開發中的版本控制打下堅實的基礎。 + +## 註冊 GitHub 賬號 + +1. 訪問 [GitHub 官網](https://github.com/) 並點擊右上角的"Sign up"。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image11.png) +2. 輸入你的電子郵件地址(建議使用常用郵箱,因為驗證和通知將發送到那裡),設置密碼(必須包含字母、數字和特殊字符)。 +3. 完成人工驗證,按照提示驗證郵箱,你的賬號就創建好了。 + +## 在 GitHub 上創建你的第一個倉庫 + +接下來,我們將創建第一個存儲文件夾,也稱為倉庫或"repo"。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image12.png)![](/zh-cn/stage-2/backend/git-workflow/images/image13.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image14.png) + +1. Repository name:向他人顯示的倉庫名稱。 +2. Description:倉庫的詳細描述。 +3. Choose visibility:對於個人倉庫,如果設置為 private,只有你和特別邀請的人可以看到。如果設置為 public,所有人都可以看到。 + 對於組織內的倉庫,如果是 Private,只有組織內的人可以看到。 + 如果是 Public,組織外的人也可以看到。 +4. README:通常的慣例是每個倉庫都應該有一個 README 文件。你可以把它看作是倉庫的完整介紹,包括使用說明、文件列表和操作方法。 +5. Add .gitignore and license: + 1. .gitignore 文件告訴 Git 在上傳到 GitHub 時忽略某些文件夾或文件,因此它們不會被跟蹤或添加到暫存區。這對於臨時測試文件、依賴包或大文件很有用。一旦指定,這些文件將不再被跟蹤。 + 2. license 指的是你選擇的開源許可證類型。不同的許可證詳細規定了他人是否可以將你的程式碼用於商業目的,幷包含其他條款和條件。 + +建議勾選"Add README",將倉庫可見性設置為"Private",並根據自己的喜好填寫倉庫名稱和描述,然後點擊"Create repository"完成創建第一個遠程倉庫。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image15.png) + +之後,你將擁有一個沒有任何額外文件的乾淨倉庫。接下來你可以開始上傳文件了。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image16.png) + +獲取倉庫的命令是 `git clone`,但它需要倉庫地址。你可以通過點擊綠色的"Code"按鈕找到倉庫地址,你會看到 HTTPS 和 SSH 選項。通常,你可以使用這兩種方法中的任何一種將倉庫下載到本地機器(只有這樣你才能修改和上傳文件)。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image17.png) + +一般來說,通過 HTTP 克隆的倉庫適合臨時下載和測試他人的倉庫,但不建議用於自己的開發。為了更好的學習體驗,你應該先設置 SSH 認證。 + +## 綁定本地 SSH + +在 GitHub 中,"SSH 協議綁定"本質上意味著將你本地設備的 SSH 公鑰與你的 GitHub 賬號關聯,允許 GitHub 通過 SSH 協議識別你的設備。這使你能夠安全地操作遠程倉庫,而無需密碼(如 clone、push 或 pull 程式碼)。 + +簡單來說:這就像給你的設備一張"GitHub 專屬門禁卡"。綁定後,當你的設備通過 SSH 協議訪問 GitHub 倉庫時,GitHub 會驗證這張"門禁卡"(你的 SSH 公鑰)。一旦確認為你的授權設備,你就可以直接操作——不需要每次都輸入賬號密碼。 + +> 💡 什麼是 SSH + +### 為什麼需要 SSH 協議綁定? + +GitHub 支持兩種主要的倉庫操作協議:HTTPS 協議和 SSH 協議: + +- HTTPS 協議:每次操作(如 push)都需要輸入 GitHub 賬號密碼(或個人訪問令牌 PAT)。驗證過程繁瑣,且存在密碼洩露風險。 +- SSH 協議:身份驗證通過"密鑰對"完成,因此不需要重複輸入密碼,且加密傳輸更加安全。 + +"SSH 協議綁定"是啟用 GitHub SSH 認證的前提步驟——只有將本地 SSH 公鑰"綁定"到 GitHub 賬號後,GitHub 才能識別你的設備並允許對倉庫進行 SSH 操作。 + +### "綁定"的核心邏輯:SSH 密鑰對的作用 + +SSH 認證依賴於密鑰對(公鑰 + 私鑰),它們是匹配的加密文件。生成後,你需要將"公鑰"提供給 GitHub("綁定"),而"私鑰"留在本地設備上: + +1. 私鑰:存儲在本地設備(如電腦)的指定目錄中(通常是 ~/.ssh/),充當"你的專屬鑰匙",絕不能與任何人分享。 +2. 公鑰:這是一把可以公開分享的"鎖"——你需要將其複製到 GitHub 賬號的"SSH keys list"中("綁定"操作)。 + +當你通過 SSH 操作 GitHub 倉庫時(例如 git push git@github.com:xxx/xxx.git): + +- 你的本地設備使用私鑰加密"操作請求"併發送給 GitHub; +- 收到請求後,GitHub 嘗試使用你之前綁定的公鑰進行解密; +- 如果解密成功,你的設備被確認為已授權,操作被允許;否則,訪問被拒絕。 + +### "綁定"的具體步驟(核心流程) + +一旦你理解了原理,實際操作就很簡單——核心是"生成密鑰對 → 上傳公鑰到 GitHub": + +1. 本地生成 SSH 密鑰對 + 1. 使用 Trae 獲取公鑰(推薦) + 提示詞:`Help me create the SSH key needed for GitHub login. My email is your_email@gmail.com , Please return the public key for me to copy` + + ![](/zh-cn/stage-2/backend/git-workflow/images/image18.png) + + 輸入提示詞後,你還需要在左側終端按 Enter 鍵,否則命令會一直等待而不執行。由於 Trae 無法幫你執行任何條件判斷,我們只需要一直按 Enter 即可。 + + 最後,你會看到右側的 Trae 返回了它讀取的公鑰。你只需複製它並準備在下一步中粘貼。 + + ![](/zh-cn/stage-2/backend/git-workflow/images/image19.png) 2. 手動獲取公鑰 + 打開你的本地終端(在 Windows 上使用 Git Bash 或 PowerShell;在 macOS/Linux 上使用終端),輸入以下命令(將 your_email@example.com 替換為你註冊 GitHub 賬號時使用的郵箱): + + ```bash + ssh-keygen -t ed25519 -C "your_email@example.com" + ``` + + 1. 按 Enter 接受默認值(默認文件路徑,無密碼,或根據需要設置密碼)。這將在 ~/.ssh/ 目錄中生成兩個文件: + - id_ed25519:私鑰(本地保存,**絕不分享**); + - id_ed25519.pub:公鑰(需要上傳到 GitHub)。 + +2. 將公鑰"綁定"到你的 GitHub 賬號 + +這是核心綁定步驟——將本地公鑰添加到 GitHub 賬號的"SSH keys list"中: + +1. 複製公鑰內容: + 1. Trae: + 2. Windows:用記事本打開 C:\Users\\.ssh\id_ed25519.pub 並複製其所有內容; + 3. macOS/Linux:在終端運行 cat ~/.ssh/id_ed25519.pub 並複製所有輸出(從開頭的 SSH-ed25519 到結尾的郵箱)。 +2. 登錄 GitHub 並進入"SSH Key Management"頁面: + 1. 點擊右上角頭像 → Settings → 左側菜單 SSH and GPG keys → 點擊 New SSH key。 + ![](/zh-cn/stage-2/backend/git-workflow/images/image20.png)![](/zh-cn/stage-2/backend/git-workflow/images/image21.png) + 2. 輸入任何標題(例如,your local computer's SSH),然後將你剛剛獲取的 SSH 公鑰粘貼到這裡。 + +![](/zh-cn/stage-2/backend/git-workflow/images/image22.png) + +![](/zh-cn/stage-2/backend/git-workflow/images/image23.png) + +3. 驗證綁定是否成功 + +在終端中輸入以下命令(**Trae 也可以做以下操作**)來測試 GitHub 是否能識別你的設備: + +```bash +ssh -T git@github.com +``` + +- 如果你看到類似 Hi [your GitHub username]! You've successfully authenticated... 的內容,說明你已成功綁定密鑰; +- 如果遇到錯誤,通常是因為公鑰複製不完整、私鑰權限過高(你的本地 ~/.ssh/ 目錄應僅由你讀寫)等。根據需要檢查這些問題。 + +### 重要注意事項 + +如果你有多個設備(如筆記本電腦和臺式機),你需要為每個設備生成單獨的 SSH 密鑰對,並將每個公鑰綁定到同一個 GitHub 賬號——每個設備都有自己的"門禁卡"。 + +切勿分享你的私鑰(不要上傳到 GitHub 或與他人分享),否則有人可能會冒充你操作你的倉庫。如果私鑰洩露,請立即從 GitHub 刪除相應的公鑰並生成新的密鑰對。 + +綁定 SSH 後,使用 SSH 格式的倉庫地址(例如 git@github.com:username/repository.git)進行操作,而不是 HTTPS 格式(例如 https://github.com/username/repository.git)。如果你之前用 HTTPS 克隆了倉庫,可以用 git remote set-url origin `` 切換協議。 + +# 使用 Trae 進行 GitHub 操作 + +我們已經解釋了什麼是 Git,什麼是 GitHub,什麼是 SSH,以及如何配置它。現在你可以自由使用 Trae 執行 Git 操作。首先,讓我們學習如何將遠程倉庫克隆到本地機器。 + +## Git clone : 下載現有倉庫 + +你可以直接告訴它你想克隆的倉庫地址 + +![](/zh-cn/stage-2/backend/git-workflow/images/image24.png) + +## Git pull : 從遠程倉庫獲取更新 + +每次更新倉庫之前,由於它可能由多人維護,你需要先拉取最新的更改。之後,你可以修改並推送文件。 + +**記得包含文件夾名稱及其相對或絕對路徑,以避免推送到錯誤的倉庫。** + +prompt:`Help me pull this repository AIID-TEST in ./AIID-TEST.` + +## Git commit & Git push : 暫存更新並推送到 GitHub + +一切準備就緒後,你可以嘗試修改本地文件,在文件夾中添加或刪除項目。然後,讓 Trae 檢測更改並幫你推送到 GitHub。 + +prompt:`I finished. Commit and push to the repository AIID-TEST in ./AIID-TEST.` + +![](/zh-cn/stage-2/backend/git-workflow/images/image25.png) + +推送成功。現在你可以在 GitHub 上看到更新的內容了。 + +# 參考資料 + +- Pro Git book https://git-scm.com/book/en/v2 +- GitHub Docs https://docs.github.com/en diff --git a/docs/zh-tw/stage-2/backend/modern-cli/index.md b/docs/zh-tw/stage-2/backend/modern-cli/index.md new file mode 100644 index 0000000..e32d102 --- /dev/null +++ b/docs/zh-tw/stage-2/backend/modern-cli/index.md @@ -0,0 +1,801 @@ +# CLI AI 程式設計工具 + +在本教程中,我們將介紹直接在命令行中運行的 AI 程式設計 Agent。它們和之前學過的 Trae、Cursor 中的 Agent 不同,CLI AI 程式設計工具只能在終端中使用。與集成在 AI IDE 裡的 Agent 相比,它們通常具有更長的上下文窗口、更快的工具調用速度,並且可以兼容更多種類的大模型。在最新的 AI Vibe Coding 實戰中,我們往往會優先使用 CLI AI 程式設計工具,而不是 IDE 內置的編碼 Agent。 + +## 從 CLI 說起 + +還記得我們之前介紹過的 CLI 嗎?CLI 指的是通過終端或命令提示符,用純文本命令來操作軟體應用,而不是依賴圖形界面(GUI——你可以簡單理解為電腦或手機上帶按鈕、可以點擊操作的界面,不需要輸入命令)。 + +> 在 Windows 上,常見的終端有“命令提示符(cmd)”和 “PowerShell”。你可以在電腦的運行/搜索框中輸入 “cmd” 或 “powershell” 來啟動這些命令行程序。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image1.png)![](/zh-cn/stage-2/backend/modern-cli/images/image2.png) + +CLI 天生適合文本命令操作,在一小部分極客(追求極致的程式設計愛好者)群體中,CLI 甚至比 GUI 更受歡迎——他們希望所有操作都通過鍵盤完成,覺得動鼠標反而會拖慢自己的編碼效率。 + +在工業界,CLI 往往也是最常見的接口形式,因為 GUI 需要操作系統額外繪製界面、管理窗口,對計算機資源的要求更高;而 CLI 只需要把收到的命令傳給系統執行即可。因此,在連接大規模服務器集群時,我們通常只通過 CLI 進行交互。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image3.png) + +對於許多沒有 CLI 經驗的同學來說,可能會覺得 CLI 操作很複雜、命令太多,甚至擔心“一不小心就把電腦搞壞”。不用擔心。還記得我們在前面教程裡,經常讓 Trae 幫忙完成各種基礎操作嗎?這裡也可以完全照搬這個思路——我們可以讓 CLI 程式設計工具幫我們執行所有 CLI 操作:讓它幫你進入指定文件夾、搜索和處理文件、運行或複製開源項目等。整個過程都可以通過和 CLI AI 程式設計工具的對話來完成。 + +## 和 AI IDE 有什麼不同 + +我們可以把 CLI AI 程式設計工具類比成之前學過的 z.ai 和 Trae。某種意義上,CLI AI 程式設計工具可以看成是一種特殊的 z.ai:它們同樣只需要一個簡單的對話入口,就會自動為你執行所有需要的操作(只是有時你需要手動打開瀏覽器查看最終效果)。而如果類比 AI IDE,那麼 CLI AI 程式設計工具可以被看作是 IDE 中的 Agent 模塊——也就是側邊那塊對話區域。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image4.png)![](/zh-cn/stage-2/backend/modern-cli/images/image5.png) + +不過,由於不同 AI IDE 對 Agent 的實現方式不同,能力差異也很大,AI 程式設計效果經常不穩定,因此 CLI AI 程式設計工具通常由大型科技公司直接開發,例如 Claude 背後的 Anthropic、ChatGPT 背後的 OpenAI 等。 + +相比其他 AI 程式設計 Agent,直接使用這些大廠產品往往是較優的實踐,尤其是 Claude Code 本身就是為 Anthropic 內部研發團隊服務的工具,從一開始就圍繞“滿足工程師真實需求”來設計。 + +為了更直觀地對比,我們可以簡單看看 Claude Code 和某款 AI IDE Agent 的差異(這裡以 Cursor 為例): + +| 功能特性 | Claude Code | Cursor | 更優者 | +| ----------------- | ------------- | --------------- | ----------- | +| 自動任務執行 | ✅ 非常強 | ❌ 能力有限 | Claude Code | +| IDE 集成 | ❌ 僅命令行 | ✅ 原生 VS Code | Cursor | +| 實時程式碼補全 | ❌ 無 | ✅ 體驗極佳 | Cursor | +| 多文件操作 | ✅ 非常強 | ⚠️ 還不錯 | Claude Code | +| GitHub 一體化操作 | ✅ 可直接提交 | ⚠️ 需要手動操作 | Claude Code | +| 學習成本 | ⚠️ 中等 | ✅ 上手簡單 | Cursor | +| 上下文長度 | ✅ 非常長 | ⚠️ 較好 | Claude Code | +| 調試輔助 | ✅ 自動化 | ⚠️ 較多需手動 | Claude Code | + +表格來源: + +簡單說,CLI AI 程式設計工具通常可以: + +- 支持更長時間的連續對話(甚至可以幫你“工作一整天”)。 +- 提供更長的上下文窗口(不再頻繁需要你說“繼續”)。 +- 響應速度更快(可以接入更多自定義模型 API)。 + +在編碼相關操作上,它們通常比大部分 IDE 內置 Agent 更聰明、更穩定。 + +## 常見的 CLI AI 程式設計工具 + +目前雖然有很多開源實現,但在實踐中我們只推薦兩大類型的 CLI AI 程式設計工具,作為“首選組合”。你可以根據自己的習慣任選其一,強烈建議都試一試,再選出最適合你的那一個。 + +- Codex 使用 GPT-5,在整體能力上更強; +- Claude Code 通過 GLM 4.6 轉發 API,整體體驗接近 Claude 4,但價格更便宜。 +- OpenCode 可以隨意切換並搭配模型, 提供免費模型, 可以更好的控制成本。 + +不過,哪一個在實際項目中更好用,只能通過親自測試來判斷。掌握多種 AI 程式設計工具始終是有益的:熟練以後,你可以在不同場景下靈活切換 Claude Code、Codex 或 Trae。如果嘗試多次後發現某個工具效果一般,可以直接換一個工具或模型繼續試驗。 + +同時,由於模型版本更新非常迅速,建議你優先選擇在“性價比(效果 / 成本)”上表現最好的方案。 + +### Claude Code + +Claude Code 是由 Anthropic 基於 Claude 大模型能力開發的一款 AI 程式設計工具。它的主要交互場景在終端,同時也支持作為 VS Code 插件來使用。類似於 AI IDE 中的 Agent,它可以深度理解開發者的程式碼倉庫,並通過自然語言指令完成端到端的開發任務——包括程式碼編輯、修復 Bug、執行和修復測試、管理 Git 工作流(例如解決合併衝突、創建 PR)、複雜程式碼講解、執行終端命令等。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image6.png) + +Claude Code 的優勢主要體現在:極長的上下文窗口(可以處理完整文件甚至小型項目)、可以主動澄清模糊需求、自動規劃和分配執行任務,以及對整個程式碼庫內容的深度理解和解釋能力。與普通 IDE Agent 相比,它更適合“沉浸式 vibe coding” 的開發流程。 + +在實際使用中,你可以通過對話指令,讓它幫你創建新項目、執行 CLI 操作(例如整理文件夾、批量重命名文件、部署開源項目等)、配置開發環境(例如安裝和調試 Python 環境)。如果覺得某段程式碼難以理解、某個目錄結構不清晰,也可以直接讓 Claude Code 生成結構化的分析文檔,或者對特定內容進行分步驟講解。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image7.png)![](/zh-cn/stage-2/backend/modern-cli/images/image8.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image9.png)![](/zh-cn/stage-2/backend/modern-cli/images/image10.png) + +如果你想系統地學習 Claude Code,可以參考 Andrew Ng 與 Anthropic 聯合推出的課程: + + +接下來,我們將學習如何使用 Claude Code。由於直接使用官方 Claude Code 的成本往往非常高(如下圖所示),我們會轉而使用兼容 Claude Code 協議、但基於其他大模型的 API 平臺。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image11.png) + +你需要學習下面幾種不同方案(最好都嘗試一遍),最後選擇最適合你的那一種作為主要實踐路徑。 + +第一種方式是直接使用“兼容 Anthropic 接口”的 API。隨著 Claude Code 的流行,越來越多的大模型服務商開始支持 Anthropic 風格的調用方式。常見的服務商包括 GLM、Kimi、DeepSeek 和 Siliconflow 等,它們都提供了兼容的 API 接口。關於具體配置,我們會在後文細講。 + +需要注意的是,Claude Code 通常會消耗大量 token,如果你擔心 API 調用產生過高費用,可以考慮購買 GLM 的月度套餐(大約 20 元/月)來控制成本。如果你想先感受一下實際花費,也可以先充值 10 元做小規模試驗。 + +另一種方式是使用 “Claude Code Route” 項目。它是一個開源工具,不僅支持所有常見的 API 調用接口,還允許你針對不同場景精細配置要使用的模型,並且支持對接本地部署的大模型。但由於這一方案的配置相對複雜,建議你先從第一種方案入手。 + +#### 使用智譜 GLM 作為後端(推薦) + +GLM(General Language Model)是智譜 AI 自主研發的一系列大型語言模型。GLM-4.6 是當前 GLM 系列的最新版本,其核心亮點是在程式碼能力上的優異表現(在公開基準和真實任務中對標 Claude Sonnet 4,在國內處於第一梯隊)。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image12.png) + +它還將上下文窗口擴展到 200K,可以更加從容地處理長文本和大體量程式碼,同時加強了推理與工具調用能力,在性能和成本之間取得了不錯的平衡。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image13.png) + +在接入 GLM 之前,我們需要先安裝 Claude Code。 + +如果你覺得命令行安裝步驟麻煩,或者中途出現錯誤,可以直接讓 Trae 的 Agent 幫你完成安裝。 + +```python +# 安裝 Claude Code +npm install -g @anthropic-ai/claude-code + +# 進入你的項目 +cd your-awesome-project + +# 啟動 Claude Code +claude + +# 按 Ctrl+C 退出 Claude +``` + +接下來,我們需要修改 Claude Code 的默認 API 請求地址,使其支持 GLM 的 API 服務。你可以直接複製下面的內容,讓 Trae 幫你創建對應的環境變量;也可以選擇把它們永久寫入系統環境變量(如果出現問題,同樣可以讓 Agent 幫忙修改)。 + +首先,你需要先獲取 GLM 的 API Key,並用你自己覺得最方便的方式保存好。 + +國內版地址: +國際版地址: + +如果你使用的是 **國內版 GLM**,請使用以下變量配置: + +```python +# 在 Cmd 中運行以下命令 +# 注意將 `your_zhipu_api_key` 替換為你剛剛獲取到的 API Key +setx ANTHROPIC_AUTH_TOKEN your_zhipu_api_key +setx ANTHROPIC_BASE_URL https://open.bigmodel.cn/api/anthropic +``` + +如果你使用的是 **國際版 GLM**,請使用下面的配置: + +```python +# 在 Cmd 中運行以下命令 +# 同樣注意替換掉 `your_zai_api_key` +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic +``` + +你可以直接在 Trae 中輸入類似下面的提示詞: + +⚠️ 如果你是通過 Trae 幫你配置“永久環境變量”,那麼配置完成後 **必須重啟 Trae**,否則它內置終端裡的環境變量不會更新,可能導致登錄失敗或網路連接錯誤。 + +```python +Based on my environment variable settings: +setx ANTHROPIC_AUTH_TOKEN your_zai_api_key +setx ANTHROPIC_BASE_URL https://api.z.ai/api/anthropic + +and my key(Replace it with your own key): +681fea485851d29060cc.13gfaendggaFOhb + +please help me configure and start Claude Code +``` + +你會看到類似下面的過程輸出: + +![](/zh-cn/stage-2/backend/modern-cli/images/image14.png) + +> 💡 什麼是環境變量? +> +> 環境變量本質上是一組存儲在操作系統中的“鍵值對”配置資訊,通常以 “變量名 = 具體值” 的形式存在。只要提前在終端或系統設置中配置好,程序就可以隨時讀取這些變量來獲取相關資訊。由於環境變量可以直接在終端中寫入,而無需修改程式碼本身,我們通常會把訪問大模型所需的密鑰存放在環境變量裡,以避免洩露。程序只需要讀取對應環境變量,就能完成大模型調用。 +> +> 在 Windows 系統中,環境變量除了用於存儲大模型的訪問密鑰,還常常用來保存命令行工具的“調用路徑”。 +> +> 我們知道終端本身也是一個程序。有時我們希望在終端裡啟動某個外部程序,例如在終端中輸入 `claude` 來啟動 Claude Code。之所以可以直接輸入 `claude` 就運行,是因為終端會讀取系統的環境變量,其中的 PATH 變量裡包含了 Claude Code 可執行文件所在的目錄,所以終端能夠找到並執行它(等價於在終端中粘貼那段程序的絕對路徑再按回車)。 +> +> 一個典型的環境變量可能長這樣:`PATH=C:\Windows\system32;C:\Program Files\Python`。這樣我們就可以在任何路徑下執行系統中的這些程序,例如直接在命令行鍵入 `python` 啟動 Python 解釋器。 +> +> 如果你想查看系統當前的環境變量,可以在 Windows 搜索中輸入“環境變量”,在彈出的“編輯系統環境變量”窗口中就能看到所有變量及其值。有的變量用於存儲大模型密鑰,有的則用於添加程序目錄,方便在任意路徑下調用。 + +現在,你就可以使用最新的 GLM 來進行 Claude Code 開發了。你可以嘗試重新跑一遍之前的項目,或者重新挑戰那些 Trae 沒有完成好的任務,對比看看體驗上的差異。 + +🎉 反覆“推倒重來”並不是浪費時間——你每重做一遍,技能都會更紮實一分。 + +用和 GLM 完全相同的思路,也可以輕鬆接入其他支持 Anthropic 兼容格式的接口。 + +#### 使用 Kimi K2 作為後端(推薦) + +Kimi K2 是月之暗面(Moonshot AI)推出的新一代大語言模型,在程式碼理解和生成能力上表現出色。Kimi K2 支持超長上下文窗口(最高可達 200K tokens),能夠輕鬆處理大型程式碼庫和複雜項目。 + +**核心優勢:** + +- **超長上下文**:支持 200K 上下文窗口,可以一次性處理整個項目的程式碼 +- **程式碼能力強**:在程式碼生成、重構和調試方面表現優異 +- **中文理解好**:對中文程式設計需求的理解更加準確 +- **工具調用穩定**:支持穩定的函數調用和工具使用 + +**獲取 API Key:** + +訪問 註冊並獲取 API Key。 + +**配置方法:** + +參考文檔: + +```bash +export ANTHROPIC_BASE_URL=https://api.moonshot.cn/anthropic +export ANTHROPIC_AUTH_TOKEN=sk-YOURKEY +``` + +#### 使用 Minimax 作為後端(推薦) + +Minimax 是稀宇科技(MiniMax)推出的新一代大語言模型,在程式設計任務上表現優異。Minimax 模型以其出色的推理能力和程式碼生成質量而聞名,特別適合複雜的程式設計場景。 + +**核心優勢:** + +- **推理能力強**:在複雜邏輯推理和程式碼架構設計方面表現出色 +- **程式碼質量高**:生成的程式碼結構清晰、可讀性好 +- **多語言支持**:支持多種程式設計語言的程式碼生成和轉換 +- **響應速度快**:API 響應速度快,適合高頻調用場景 + +**獲取 API Key:** + +訪問 註冊並獲取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_MINIMAX_API_KEY +export ANTHROPIC_MODEL=MiniMax-M2.7 +``` + +#### 使用 DeepSeek 作為後端(推薦) + +DeepSeek 是深度求索推出的開源大語言模型,以其出色的程式碼能力和高性價比受到開發者歡迎。DeepSeek Coder 專門針對程式設計任務進行了優化訓練。 + +**核心優勢:** + +- **程式碼能力突出**:在程式碼生成、程式碼理解和 Bug 修復方面表現優異 +- **開源可定製**:模型開源,可以根據需求進行微調 +- **性價比高**:API 價格相對較低,適合高頻使用 +- **中文支持好**:對中文程式設計場景理解準確 + +**獲取 API Key:** + +訪問 註冊並獲取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic +export ANTHROPIC_AUTH_TOKEN=YOU_DEEPSEEK_API_KEY +export API_TIMEOUT_MS=600000 +export ANTHROPIC_MODEL=deepseek-chat +export ANTHROPIC_SMALL_FAST_MODEL=deepseek-chat +export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 +``` + +#### 使用火山引擎 Coding Plan 作為後端(推薦) + +火山引擎(Volcano Engine)是字節跳動旗下的雲服務平臺,提供企業級的 AI 模型服務。火山引擎的 Coding Plan 專門為程式設計場景優化,提供穩定、高效的程式碼生成能力。 + +**核心優勢:** + +- **企業級穩定性**:提供服務等級協議(SLA),保障服務穩定性 +- **程式碼場景優化**:針對程式設計任務進行了專門優化 +- **豐富模型選擇**:支持多種模型,包括 Doubao-pro、Doubao-lite 等 +- **國內訪問快**:國內節點部署,訪問速度快 + +**獲取 API Key:** + +訪問 註冊並獲取 API Key。 + +**配置方法:** + +```bash +export ANTHROPIC_BASE_URL=https://ark.volces.com/api/anthropic +export ANTHROPIC_AUTH_TOKEN=YOUR_VOLCANO_API_KEY +export ANTHROPIC_MODEL=doubao-pro-32k +``` + +#### 其他兼容 Anthropic 的 API + +Siliconflow: + +```bash +export ANTHROPIC_BASE_URL="https://api.siliconflow.cn/" +export ANTHROPIC_MODEL="moonshotai/Kimi-K2-Instruct-0905" # 可以自行修改所需模型 +export ANTHROPIC_API_KEY="YOUR_SILICONCLOUD_API_KEY" # 請替換 API Key +``` + +阿里雲 DashScope(Aliyuncs): + +```python +export ANTHROPIC_BASE_URL="https://dashscope.aliyuncs.com/apps/anthropic" +export ANTHROPIC_API_KEY="YOUR_DASHSCOPE_API_KEY" +``` + +::: details 使用 Claude Code Route 作為後端(進階用法) + +上面我們講解了如何用 GLM 官方 API 替換 Claude Code 的 Anthropic 接口。接下來,我們來看一下 Claude Code Router 這個工具是如何讓 Claude Code 適配更多模型 API 的。 + +[Claude Code Router](https://github.com/musistudio/claude-code-router) 是一款專門為 Claude Code 設計的智能路由增強工具。它的核心作用,是幫助用戶按需將 AI 請求分發到不同平臺上的模型,並可以高度自定義。它支持接入幾十個平臺,包括 OpenRouter、DeepSeek、Ollama、Gemini 等,也可以按場景將任務路由到特定模型,比如 GLM-4.5、Kimi-K2、Qwen3-Coder 等。舉例來說,你可以將後臺任務自動交給本地 Ollama,以節省成本;將長文本 / 長程式碼任務交給 Gemini-2.5-Pro;把程式碼講解交給 DeepSeek。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image16.png) + +該工具還提供了方便的 UI/CLI 配置管理能力,並通過"轉換器(converter)"適配不同平臺的 API 格式。它支持 GitHub Actions 等自動化集成以及自定義擴展,解決了"單一模型無法覆蓋所有場景"以及"頻繁切換平臺很麻煩"的問題,幫助用戶更靈活、低成本地利用 AI 工具。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image17.png) + +下面我們簡單介紹如何安裝 Claude Code Router。大致需要以下步驟(同樣可以讓 Trae 幫你執行),以準備好相關環境: + +```markdown +npm install -g @anthropic-ai/claude-code +npm install -g @musistudio/claude-code-router +``` + +安裝完成後,你需要確認本地可以使用 `ccr` 命令。如果看到類似下面的輸出,說明安裝成功: + +![](/zh-cn/stage-2/backend/modern-cli/images/image18.png) + +接下來,有兩種方式來初始化和配置模型: + +- 使用 CCR 自帶的 UI,在瀏覽器中打開它提供的配置頁面進行操作; +- 直接修改 CCR 的默認配置文件(本質上 UI 也是在修改配置文件,只是提供了更直觀的界面)。 + +如果選擇使用 CCR UI,你會看到類似下面的界面: + +![](/zh-cn/stage-2/backend/modern-cli/images/image19.png) + +此時點擊 "Add Provider" 按鈕,就會看到如下界面。你需要: + +1. 在 Name 中輸入模型提供商的名字; +2. 在 API Full URL 中填寫該提供商的 OpenAI 兼容接口地址; +3. 在 API Key 中填寫對應平臺的 API Key; +4. 在 Models 區域中填寫模型名稱,點擊 "Add Model" 添加; +5. 最後點擊 "Save" 保存配置。 + +(界面往下滾動還有很多高級選項,但目前你可以先忽略它們。) + +![](/zh-cn/stage-2/backend/modern-cli/images/image20.png) + +下面是 DeepSeek 與 Kimi 的配置示例: + +![](/zh-cn/stage-2/backend/modern-cli/images/image21.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image22.png) + +保存模型配置後,還需要在右側 Router 區域中指定默認模型(Default)。點擊對應的下拉選擇,將其設置為 `kimi`(推薦),然後在右上角點擊 `Save and Restart`。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image23.png) + +之後,只需在終端中輸入 `ccr code`,即可通過 Claude Code Router 啟動 Claude Code 的編碼工作流。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image24.png) + +::: + +#### Claude Code 的進階用法 + +很多人最開始使用 Claude Code 時,只把它當成普通對話工具來用。但實際上,它內置了很多豐富的能力,能夠讓你使用起來更高效、靈活。下面是一些常見命令和用法示例: + +參考文檔: + + + + +| 命令 | 作用 | 示例 | +| ----------------- | ----------------------------------------- | ---------------------------------------- | +| claude | 啟動交互模式 | `claude` | +| claude "query" | 執行一次性任務並輸出結果 | `claude "explain this project"` | +| claude -p "query" | 執行一次性問題並在結束後自動退出 | `claude -p "explain this function xxxx"` | +| claude -c | 繼續最近的一次會話 | `claude -c` | +| claude -r | 恢復上一段會話 | `claude -r` | +| /resume | 在當前聊天中切換回上一段會話 | `claude -c`、`/resume` | +| /plugin | 管理插件,可安裝提交與審查類擴展能力 | `/plugin` | +| /init | 用 CLAUDE.md 初始化項目說明 | `/init` | +| /clear | 清空當前會話上下文,防止資訊過載 | `/clear` | +| /compact | 壓縮會話歷史,減少上下文 token 佔用 | `/compact` | +| /cost | 查看當前消費情況 | `/cost` | +| /model | 切換使用的模型(用兼容 API 時一般可忽略) | `/model` | +| /memory | 管理 CLAUDE.md 記憶文件 | | +| /help | 顯示可用命令列表 | `/help` | +| exit or Ctrl+C | 退出 Claude Code | `exit` 或 `Ctrl+C` | +| /agents | 高級功能,後文會說明 | | +| /mcp | 高級功能,後文會說明 | | + +**CLAUDE.md** + +參考: + +`CLAUDE.md` 是 Claude 在開始對話時會自動讀取並加入上下文的特殊文件。因此,它非常適合用來記錄: + +- 常用 bash 命令 +- 核心文件和工具函數 +- 程式碼風格約定 +- 測試方式說明 +- 倉庫協作規範(例如分支命名、是用 merge 還是 rebase 等) +- 開發環境配置說明(例如是否使用 pyenv、推薦哪種編譯器等) +- 項目中需要特別注意的行為或坑點 +- 任何你希望 Claude “記住”的資訊 + +`CLAUDE.md` 本身沒有強制格式要求,只要簡潔、便於人類閱讀即可。例如: + +``` +# Bash commands +- npm run build: Build the project +- npm run typecheck: Run the typechecker + +# Code style +- Use ES modules (import/export) syntax, not CommonJS (require) +- Destructure imports when possible (eg. import { foo } from 'bar') + +# Workflow +- Be sure to typecheck when you’re done making a series of code changes +- Prefer running single tests, and not the whole test suite, for performance +``` + +#### Claude Code 的內部原理 + +參考: + +如果你好奇為什麼 Claude Code 在很多場景下比 Trae 或 Cursor 等 Agent 程式設計工具更好用,我們可以簡單看一下它的內部工作機制。 + +其他 CLI AI 程式設計工具的整體實現方式也大體類似。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image25.png) + +Claude Code 會把程式設計任務拆解成一個持續的“感知—思考—行動—驗證”循環,並在其中調用不同工具完成任務。它模仿人類開發者的工作流:不斷“寫程式碼 → 運行 → 看結果 → 再改進”。系統內部通過一個主任務循環不斷執行步驟,在每一輪循環中,Claude 都可以調用不同工具——例如讀寫文件、執行命令、搜索程式碼等——再根據工具返回的真實結果決定下一步行動。 + +其中有幾個關鍵特性值得注意: + +- **流式處理(Stream Processing)**:Claude 可以一邊思考一邊輸出結果,而不是必須等所有程式碼寫完再執行。 +- **智能壓縮(Intelligent Compression)**:長對話容易導致上下文過長,Claude 通過將歷史壓縮成關鍵資訊來減少“遺忘”的概率,並通過區分長短期記憶保證高效運行。 +- **併發控制(Concurrency Control)**:內部並行設計可以讓多個任務同時進行,互不干擾。 +- **子 Agent 管理(Sub-agent Management)**:實際工作中並不只相當於一個“角色”處理所有事情,你可以管理多個子 Agent 協作處理程式碼,每個 Agent 負責不同任務,比如專門負責測試、專門負責寫文檔等。 + +### Codex + +![](/zh-cn/stage-2/backend/modern-cli/images/image26.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image27.png) + +和 Claude Code 類似,Codex 是由 OpenAI 開發的一款 AI 協作程式設計工具,你可以把它理解成 “OpenAI 版的 Claude Code”。它最大的優勢是對 GPT-5 的高效適配。 + +從實際體驗來看,GPT-5 目前響應速度更快、犯錯率更低(在多輪複雜任務中正確完成的概率更高)。它的一個缺點是解釋往往偏“學術”和“技術”,有時顯得過於嚴謹、資訊量很大,對初學者來說可能略微難懂。 + +你可以通過下面的命令安裝 Codex: + +``` +npm i -g @openai/codex +``` + +#### 使用 OpenAI 官方 API 作為後端 + +如果直接使用 OpenAI 官方的 Codex 入口,配置會非常簡單:當你已經開通 OpenAI 訂閱或申請到了相應 API 配額之後,只需要在命令行中輸入 `codex` 啟動程序,並按提示完成登錄即可。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image28.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image29.png) + +#### 使用轉發 OpenAI API 的方式作為後端 + +由於官方 OPENAI API 可能存在價格較高、網路要求嚴格等問題,為了避免這些限制,我們也可以通過其他 API 網關服務來轉發調用。 + +在這種方式下,我們只需要在第三方轉發平臺上購買對應的 Codex API 配額,就能獲得接近原生 OpenAI Codex 的使用體驗。 + +參考: +充值地址: + +需要注意的是,在拿到 token 配額後,我們還需要在本地配置好 API Key。 + +在密鑰分組設置中,要注意選擇專門用於 Codex 的那一項。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image30.png) + +接下來,我們需要把獲取到的 Key 填入下面的提示詞中,並把整段提示詞交給 Trae,讓它幫你完成整個配置過程: + +````bash +My API key is: [Paste your obtained sk-xxxxx key here] + +Please help me complete the following configuration tasks: + +1. Create configuration directory + - Create a `.codex` folder under my user directory + - Windows path should be: `C:\Users\[My Username]\.codex` +2. Backup existing configuration (if exists) + - Check if `.codex\config.toml` exists + - If it exists, rename it to `config.toml.bak.[current timestamp]` (timestamp format: yyyyMMddHHmmss) +3. Create configuration file + - Create `config.toml` in the `.codex` directory + - Write the following complete content: + ```toml + preferred_auth_method = "apikey" + + [model_providers.myrelay] + name = "My Relay Station" + base_url = "https://api.zyai.online/v1" + env_key = "MYRELAY_API_KEY" + wire_api = "responses" + request_max_retries = 4 + stream_max_retries = 10 + stream_idle_timeout_ms = 300000 + + [profiles.myrelay] + model_provider = "myrelay" + model = "gpt-5" + model_reasoning_effort = "medium" + + [tools] + web_search = true + +4. Set system environment variable +Variable name: MYRELAY_API_KEY +Variable value: The key I gave you + +5. Confirm completion and report back: + +The full path of the configuration file +Whether the environment variable was set successfully +I can use the command `codex --profile myrelay` to run it +```` + +配置完成後,你就可以通過 `codex --profile myrelay` 啟動使用轉發 API 的 Codex 了。之後的使用方式與 Claude Code 類似:只需要在對話框中隨時輸入你的想法和需求即可。 + +### OpenCode + +![](/zh-cn/stage-2/backend/modern-cli/images/image32.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image33.png) + +OpenCode 是一款面向開發者的開源 AI Coding Agent 平臺,定位類似於 “多模型版的 Claude Code”。它以 Terminal 為核心交互入口,同時也支持編輯器集成(如 VS Code、Neovim 等),能夠深度接入本地程式碼倉庫,並通過自然語言完成從程式碼理解到工程執行的一整套開發流程。 + +它不是綁定單一模型的 AI 程式設計工具,而是一個可自由切換 GPT、Claude、Gemini 乃至本地模型的開放式 AI Coding Agent 平臺。就連 OpenAI 官方也持 OpenCode 接入 Codex / OpenAI 訂閱。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image34.png) + +你可以通過下面的命令安裝 OpenCode: + +```bash +# Linux / Unix +curl -fsSL https://opencode.ai/install | bash + +# Windows +npm i -g opencode-ai +``` + +#### 使用 OpenCode 中的免費模型 + +在 OpenCode 中不定期會提供免費模型可以進行使用, 配置也非常簡單。你可以在你需要使用 OpenCode 的位置在命令行輸入 `opencode` 啟動 Opencode 程序進入聊天面板。輸入 `/models`命令搜索 free 關鍵詞就可以看到帶有 free 字眼的免費模型 + +![](/zh-cn/stage-2/backend/modern-cli/images/image35.png) + +在一般情況下免費模型完成編碼任務會比付費 / 訂閱模型要慢一些,這通常取決於模型線路是否阻塞, 是否編碼高峰期以及模型本身的能力。 + +#### 使用第三方模型來作為 OpenCode 的主編碼模型 + +這是 OpenCode 的核心優勢, 它可以在使用同樣的 MCP, Skills, 上下文的情況下允許你自由切換模型來完成不同的編碼任務。下文以 OpenAI 官方的 GPT-5.3 Codex 為例,接入 OpenCode 作為主編碼模型。 + +在 OpenCode 的聊天窗口中輸入 `/connect` 命令選中第一條最相關指令按下 enter 鍵,就可以進行選擇第三方模型提供商的認證授權。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image36.png) + +這裡以選擇 OpenAI 為例,進行回車選擇認證方式。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image37.png) + +選哪種都可以,只是認證方式不同。這裡選擇第一種進行瀏覽器登錄。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image38.png) + +複製此鏈接到瀏覽器上進行正常的 OpenAI 登錄操作,瀏覽器上出現 Authorization Successful 後 OpenCode 客戶端會自動跳轉至選擇 OpenAI 的模型界面。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image39.png) + +![](/zh-cn/stage-2/backend/modern-cli/images/image40.png) + +#### 安裝 Oh My OpenAgent 插件 + +OpenCode 的強大之處還在於他有非常活躍的社區生態,你可以在 Github 上搜索出非常多與 OpenCode 相關的插件。如果說 OpenCode 是一款可以任意切換模型的 AI 協作工具的話,那麼 Oh-My-OpenAgent 就是一款運行在 OpenCode 之上的 "多 Agent AI 程式設計指揮系統"。它可以將一個複雜任務拆給多個子任務分給不同的模型進行各司其職的工作。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image41.png) + +你可以將以下話術複製之後粘貼給上文在 OpenCode 中配置好的模型進行安裝 OpenCode。 + +```text +Install and configure oh-my-openagent by following the instructions here: +https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md +``` + +以下是 Oh-My-OpenAgent 的特性以及功能說明。 + +| 特性 | 功能說明 | +| :-------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **自律軍團 (Discipline Agents)** | Sisyphus 負責調度 Hephaestus、Oracle、Librarian 和 Explore。一支完整的 AI 開發團隊並行工作。 | +| **Team Mode** (v4.0, 選擇性啟用) | 領導 Agent + 最多 8 個並行成員,實時 tmux 可視化,專用 `team_*` 工具家族。驅動 `hyperplan`(5 個敵對評論者) 和 `security-research`(3 個獵手 + 2 個 PoC 工程師)。[文檔 →](docs/guide/team-mode.md) | +| **`ultrawork` / `ulw`** | 一鍵觸發,所有智能體出動。任務完成前絕不罷休。 | +| **[IntentGate 意圖門](https://factory.ai/news/terminal-bench)** | 真正行動前,先分析用戶的真實意圖。徹底告別被字面意思誤導的 AI 廢話。 | +| **基於哈希的編輯工具** | 每次修改都通過 `LINE#ID` 內容哈希驗證、0% 錯誤修改。靈感來自 [oh-my-pi](https://github.com/can1357/oh-my-pi)。[The Harness Problem →](https://blog.can.ac/2026/02/12/the-harness-problem/) | +| **LSP + AST-Grep** | 工作區級別的重命名、構建前診斷、基於 AST 的重寫。為 Agent 提供 IDE 級別的精度。 | +| **後臺智能體** | 同時發射 5+ 個專家並行工作。保持上下文乾淨,隨時獲取成果。 | +| **內置 MCP** | Exa(網路搜索)、Context7(官方文檔)、Grep.app(GitHub 源碼搜索)。默認開啟。 | +| **Ralph Loop / `/ulw-loop`** | 自我引用閉環。達不到 100% 完成度絕不停止。 | +| **Todo 強制執行** | Agent 想要摸魚?系統直接揪著領子拽回來。你的任務,必須完成。 | +| **註釋審查員** | 剔除帶有濃烈 AI 味的冗餘註釋。寫出的程式碼就像老練的高級工程師寫的。 | +| **Tmux 集成** | 完整的交互式終端支持。跑 REPL、用調試器、用 TUI 工具,全都在實時會話中完成。 | +| **Claude Code 兼容** | 你現有的 Hooks、命令、技能、MCP 和插件?全都能無縫遷移過來。 | +| **技能內嵌 MCP** | 技能自帶其所需的 MCP 服務器。按需開啟,不會撐爆你的上下文窗口。 | +| **Prometheus 規劃師** | 動手寫程式碼前,先通過訪談模式做好戰略規劃。 | +| **`/init-deep`** | 在整個項目目錄層級中自動生成 `AGENTS.md`。不僅省 Token,還能大幅提升 Agent 理解力。 | + +Sisyphus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) 是你的主指揮官。他負責制定計劃、分配任務給專家團隊,並以極其激進的並行策略推動任務直至完成。他從不半途而廢。 + +Hephaestus (gpt-5.5) 是你的自主深度工作者。你只需要給他目標,不要給他具體做法。他會自動探索程式碼庫模式,從頭到尾獨立執行任務,絕不會中途要你當保姆。名副其實的正牌工匠。 + +Prometheus (claude-opus-4-7 / kimi-k2.6 / glm-5.1) 是你的戰略規劃師。他通過訪談模式,在動一行程式碼之前,先通過提問確定範圍並構建詳盡的執行計劃。 + +瞭解完這些, 你就可以使用裝好 Oh-My-OpenAgent 插件之後的 OpenCode 來完成編碼任務了。 + +## CLI AI 程式設計工具的更多用法 + +### 用 AI 寫需求文檔:學會“具體化需求” + +對於大語言模型來說,抽象需求需要被“具體化”。比如:“我很餓”是一個抽象需求,我們需要把它變成:“我肚子有點餓,可能需要吃一個紅豆麵包,再配一杯豆漿。”——這才是一種可以被執行的、具體的需求。 + +但把抽象需求變具體,其實是一個很花精力的過程。如果我們沒有見過足夠多的案例,很難快速聯想到該如何把抽象問題拆解成細緻的模塊。這種時候,最好的辦法就是讓 AI 幫你完成“具體化”這一步。 +比如,我想開發一個“每日計劃”應用,最樸素的想法可能是: + +`Please help me write a daily planning app where I can write my plans each day and get reminders.` + +AI 確實可以在這個需求基礎上直接拆分任務,然後一步步完成,但中間容易出錯或理解偏差。為了降低風險,我們可以讓 AI 幫我們先擴寫需求: + +`Based on my needs, please elaborate and provide a more detailed Product Requirement Document for reference. My idea is: Please help me write a daily planner app that supports daily plan-writing and provides reminders .` + +這時,AI 可能會給出類似下面這樣完整的 PRD: + +``` +Product Requirements Document (PRD): “Today’s Plan” App +Document Version: 1.0 +Creation Date: October 27, 2023 +Author: (Your Name/Product Manager) + +1. Product Introduction +1.1 Product Name +Today's Plan +1.2 Product Vision +“Today’s Plan” is a minimalist and highly efficient daily planning and reminder tool, dedicated to helping users eliminate procrastination and forgetfulness, plan every day clearly, and ensure tasks are carried out through an intelligent reminder system—ultimately enabling users to gain a stronger sense of control and achievement over their time. +1.3 Target Users (User Personas) +We mainly serve three types of users: +Students (Xiao Ming): +Characteristics: Multiple tasks such as courses, assignments, club activities, exam prep, needing organized time arrangement. +Pain Points: Easily forget small tasks or assignment deadlines; feel overwhelmed switching between tasks; want to build regular study and life habits. +Needs: A simple tool to list daily to-dos and provide reminders before class/self-study. +Office Workers (Zhang Wei): +Characteristics: Fast-paced work, many meetings, reports, project milestones, and personal affairs (fitness, picking up children). +Pain Points: Easily forget important meetings or work milestones; get interrupted by urgent tasks and forget the original plan; feel busy but inefficient at end of day. +Needs: Need a tool to quickly record and schedule daily work and send strong reminders at key times (e.g., 15 minutes before meetings). +Freelancers/Self-disciplined Seekers (Li Na): +Characteristics: High freedom of time, but strong self-management required for work output and personal growth. +Pain Points: Easily procrastinate, lack external supervision; start the day without a clear plan, leading to low time utilization. +Needs: Need a tool to help build a daily fixed routine (Morning Routine) and review daily achievements for positive feedback. + +2. User Stories +As a user, I want to quickly create today’s plan list so I have an overview of all my tasks for the day. +As a user, I want to set specific start and end times for each task so I can create a visual timeline. +As a user, I want to receive push notification reminders before a task starts so I won’t miss any important arrangements. +As a user, I want to customize the reminder time (such as 5, 15, or 60 minutes in advance) so reminders better fit my habits. +As a user, I want to easily mark completed tasks so I can feel accomplished and clearly see my progress. +As a user, I want to see a summary of my completed plans at the end of each day for reviewing and self-motivation. +As a user, I want to conveniently edit and delete tasks to handle last-minute changes. +As a user, I want to view plans and achievements from previous days to review my efficiency and habits. + +3. Feature Breakdown +Core Features (MVP - Minimum Viable Product) +Module 1: Plan Management +3.1.1 Daily Plan Homepage +Interface: “Today” as the core view, current date shown at the top. +View: Timeline list, clearly showing tasks scheduled from morning to evening. Tasks without a time can be listed in the top or bottom “To-do List” section. +Interactions: +Click the “+” button in the bottom right to quickly create a new task. +Pull down to refresh the page. +Swipe left/right to view yesterday’s and tomorrow’s plans. +3.1.2 Create/Edit Task +Entry: Click “+” on the homepage or a time slot in the list. +Fields: +Task title (required): Briefly describe the task, e.g., “10 AM Weekly Product Meeting.” +Task time (optional): +Set “start time” and “end time.” +Provide “all-day” option for unspecified time tasks. +Default time picker should be quick and convenient. +Reminder setting (required, with default value): See Module 2. +Notes (optional): Add further descriptions, links, or location info. +Actions: Save, cancel, delete task. +3.1.3 Task Interaction +Mark as complete: Checkbox before each task; checking adds a strikethrough and gray background, indicating completion. Can unmark if needed. +Edit task: Click the task itself to enter edit page. +Delete task: Swipe left on a task to reveal “Delete” button. +Module 2: Smart Reminder System +3.2.1 Reminder Trigger +Mechanism: Based on task’s set “start time” and the user’s “reminder lead time,” send a push notification from device. +Offline Support: Locally scheduled reminders must trigger even if user is offline. +3.2.2 Reminder Content & Format +Notification title: App name “Today’s Plan.” +Body: “Reminder: [Task Title] will start at [Start Time].” E.g., “Reminder: Product Meeting will start at 10:00.” +Sound: Use system default or offer several simple, effective tones. +3.2.3 Reminder Settings +Global Settings (in Settings page): +User can set a default reminder time, e.g., “15 minutes before task starts.” New tasks adopt this by default. +Single Task Settings (in create/edit page): +Users can override global settings for important tasks, choosing specific reminder times like "on time," "5 minutes early," "30 minutes early," or "1 hour early." +Provide “no reminder” option. +Subsequent Features (V1.1, V2.0) +3.3 Daily Review & Statistics +Push a summary notification at a set time every night (e.g., 22:00): “How was your day? Take a look at your achievements!” +Generate a simple daily report card: shows total planned tasks, completed tasks, completion rate, plus an encouraging message. +3.4 History Review +Calendar view to click on any past day and check its plans and completion status. Days with high completion rates marked with a special color. +3.5 Templates +Allow users to save a successful daily plan as a template, e.g., “Efficient Workday,” “Relaxing Weekend.” +When creating tomorrow’s plan, one-click import a template, modify slightly to save time. +3.6 Themes & Personalization +Offer dark mode. +Allow changing several primary color themes. + +4. Non-Functional Requirements +4.1 Performance +Response: App launch time under 2 seconds; adding/editing tasks must be smooth and lag-free. +Resource Use: Low battery and memory consumption in background; do not over-consume resources waiting for reminders. +4.2 Usability +Minimal & intuitive: UI must be minimal, primary functions accessible within 3 clicks. No tutorial needed for new users. +Error tolerance: Offer undo (e.g. brief undo after mistakenly deleting a task). +4.3 Reliability +Reliable reminders: Reminder function is the product’s lifeline; must guarantee 99.99% timely and accurate delivery. +Data loss-free: User plans must be reliably stored locally. Future versions can support cloud sync to prevent data loss on device change. +4.4 Compatibility +Platform: Support major iOS and Android versions (latest 3-4 releases). +Screen: Layout must fit various phone screen sizes. + +5. Roadmap +V1.0 (MVP): +Goal: Validate core value—planning & reminders. +Features: Complete all “Core Features” described above (Plan management, smart reminders). +V1.1 (Quick Optimization): +Goal: Improve retention and achievement. +Features: Add “Daily Review & Statistics,” “History Review.” +V2.0 (Enhanced Experience): +Goal: Increase efficiency and personalization. +Features: Add “Templates,” “Themes & Personalization,” and start developing “Cloud Sync.” +``` + +對比我們最開始那句“幫我寫一個每天可以記計劃並提醒的應用”,現在這份文檔已經詳細得多了。你可以根據自己的真實需求,對其中的內容進行增刪修改;對於某些你不確定的模塊,也可以繼續讓 AI 提供更多備選方案,你再挑選、合併成最終版本。 + +通過這種方式,我們可以很輕鬆地把抽象想法變成具體描述。對 AI 開發來說,“具體”就是生產力:需求越具體,越容易得到結構穩定、質量較高的項目。你可以嘗試用這種方式重做一下之前的某個小項目,對比一下效果差異。 + +如果你覺得這類“需求提示詞”太長,非常自然的做法,是把它單獨寫進一個 markdown 文檔中,作為你的“需求文檔 / 開發文檔 / PRD”。之後每次讓 AI 寫項目時,只需要讓它“參考這份文檔”,而不是每次都重打一遍長提示。你也可以在迭代中不斷完善這份文檔,讓後續項目直接受益。 + +下面是一些其他常見的使用場景: + +### 管理文件夾 + +我們可以嘗試用 CLI AI 程式設計工具來管理當前文件夾中的各種文件。比如,你有一堆雜亂無章的文件,需要整理歸類,就可以對 Claude Code 或 Codex 說: + +`Please help me organize the contents of the current folder. I want to group files with the same content together & I want to group files from the same time period together. Please help me handle this.` + +### 開發新項目 + +這和我們之前在 z.ai、Trae 中的用法幾乎完全一樣——我們也可以直接用 CLI AI 程式設計工具來從零開發新項目。當然,最好提前準備好一份需求文檔。 + +需求文檔越細緻,最終效果越好。你可以根據不斷變化的想法,對文檔做多輪優化;文檔越完善,程式碼實現就越穩定、越成熟。 + +### 部署開源項目(例如 Dify) + +對於剛接觸計算機的同學來說,從 GitHub 上部署一個開源項目往往很有難度。但我們完全可以把這件事交給 Claude Code,就像我們在 Dify 教程中做的那樣: + + + +如果我想在本地跑起自己的 Dify,只需要把這個鏈接扔給 Claude Code,然後輸入: + +`I want to deploy this GitHub project ``https://github.com/langgenius/dify`` . Please help me clone the project and run it.` + +收到你的請求後,Claude Code 會自動完成一系列操作,包括從 GitHub 拉取程式碼、配置運行環境、啟動項目等。如果中間某一步出錯或項目啟動狀態不正常,你再根據提示進行少量人工處理即可。除了 Dify,你也可以用 Claude Code 幫你部署大部分常見的 GitHub 開源項目——你只需要一個對話框,再加上喝一杯咖啡的時間 ☕️。 + +![](/zh-cn/stage-2/backend/modern-cli/images/image31.png) + +### 講解程式碼與撰寫文檔 + +對於一些複雜項目,或者 AI 自動生成的大型項目,你可能會覺得程式碼太長、邏輯太多,很難看懂。這時就可以讓 CLI AI 程式設計工具幫你“讀程式碼”。你可以這樣提問: + +- 請幫我解釋這個項目:如何運行、如何使用、後續如何修改和繼續開發? +- 請幫我說明這個項目的整體流程:程序是怎樣運行的?用戶在界面中可以做哪些操作? +- 請幫我為這個項目寫一份完整的文檔,包括開發文檔和運行文檔等。 +- 請基於我當前文件夾裡的所有內容,寫一份詳細說明,並保存到指定的 markdown 文檔中。 + +### 更多玩法 + +當然,CLI AI 程式設計工具能做的遠不止上面這些。不要只把它當作“寫程式碼工具”,而是把它看作一個具有獨立行動能力的智能 Agent。你可以讓它幫你: + +- 管理和整理本地文件; +- 寫日記、寫總結; +- 分析和修復系統錯誤; +- 執行各種重複性命令行任務等。 + +也許在不久的將來,它會變成你電腦上最重要、也最懂你的 AI 夥伴。 diff --git a/docs/zh-tw/stage-2/backend/stripe-payment/index.md b/docs/zh-tw/stage-2/backend/stripe-payment/index.md new file mode 100644 index 0000000..d210df3 --- /dev/null +++ b/docs/zh-tw/stage-2/backend/stripe-payment/index.md @@ -0,0 +1,907 @@ +# 如何集成 Stripe 等收費系統 + +當你的產品已經有了頁面、登錄、資料庫和基礎後端之後,下一個現實問題就是:**怎麼收費**。 + +很多人第一次接支付,會把注意力全放在"怎麼跳轉到付款頁"上。但真正決定系統是否穩定的,不是按鈕,而是整條收費鏈路:誰決定價格、誰確認支付成功、誰更新資料庫、誰回收權限。 + +這篇文章我幫你拆成兩部分: + +- **前半部分**只講最實用的基礎接入,目標是讓你儘快把 Stripe 接進項目。 +- **後半部分**統一放到附錄,包含 Webhook 細節、訂閱事件、不同國家和地區的支付方案差異。 + +> 💡 建議先學完這些章節再繼續 +> +> - [從資料庫到 Supabase](../database-supabase/) +> - [大模型輔助編寫接口程式碼與接口文檔](../ai-interface-code/) +> - [如何部署 Web 應用](../zeabur-deployment/) + +# 你將學到 + +1. 最小可行的支付系統到底長什麼樣。 +2. 如何用最快的方式把 Stripe 接進你的項目。 +3. 如何寫提示詞,讓 AI 直接幫你加支付系統。 +4. 如果不是做海外 Stripe 項目,不同地區應該優先考慮什麼支付方案。 + +--- + +# 第一部分:基礎上手 + +## 1. 先記住 3 個原則 + +如果你只記住三件事,就記住下面這三條: + +1. **價格必須由後端決定**,不能相信前端傳來的金額。 +2. **真正讓權限生效的是 Webhook**,不是 `success` 頁面。 +3. **你自己的資料庫必須保存支付狀態**,不能只依賴 Stripe 後臺。 + +這三條是支付系統最核心的邊界。只要邊界沒錯,後面換 Stripe、PayPal、支付寶、微信支付,本質上都只是"接口換了,架構不變"。 + +## 2. 如果不在後端處理,而是前端直接連 Stripe,會怎麼樣? + +這是很多人第一次做支付時最自然的想法: + +- 頁面上已經有"購買"按鈕了 +- 那我能不能讓前端自己去連 Stripe +- 這樣是不是就不用做後端了 + +如果你只是做一個假的演示頁面,這樣想當然沒問題。 +但如果你是真的要收錢,**這條路通常會把事情做壞**。 + +最常見的問題有這幾個: + +1. **價格容易被改** + 瀏覽器裡的請求,是用戶自己電腦上發出去的。別人是可以改請求內容的。 +2. **敏感資訊容易暴露** + 真正重要的密鑰、價格邏輯、會員開通邏輯,本來就不該放在前端。 +3. **你沒法可靠確認"這筆錢到底算不算成功"** + 用戶跳到成功頁,不代表你的資料庫已經同步對了。 +4. **資料庫狀態會亂** + 用戶可能說"我明明已經付錢了",但你自己的系統里根本沒記上。 + +所以更安全的分工應該是: + +- 前端負責:展示按鈕、發起購買、跳轉頁面 +- 後端負責:決定價格、創建支付會話、接收 Webhook、更新資料庫 + +::: info 這一段你可以直接記成一句話 +**前端可以負責跳轉,後端必須負責定價和確認。** + +只要是真收錢,就不要把"最終價格決定權"和"支付成功後的開通邏輯"放在前端。 +::: + +## 3. 什麼時候適合先用 Stripe + +如果你做的是下面這些場景,Stripe 往往是最順手的起點: + +- 面向海外用戶的 SaaS +- 訂閱制會員產品 +- 數字產品、模板、AI 積分包 +- 想先快速驗證商業化,而不是一開始就處理太多本地支付細節 + +如果你的主要用戶在中國大陸,那通常不會把 Stripe 當第一選擇,這個我放到附錄裡統一講。 + +## 4. 最小可行支付鏈路 + +先看最小版本。只要這條鏈路能跑通,你的支付系統就有了骨架。 + +```mermaid +flowchart LR + user["用戶"] + frontend["前端頁面"] + backend["你的後端"] + checkout["Stripe Checkout"] + webhook["Stripe Webhook"] + db["Supabase / 業務資料庫"] + + user -->|"點擊購買"| frontend + frontend -->|"請求創建支付會話"| backend + backend -->|"按後端價格創建 Session"| checkout + frontend -->|"跳轉到支付頁"| checkout + checkout -->|"支付完成後發送事件"| webhook + webhook -->|"校驗簽名並更新狀態"| backend + backend -->|"寫入 orders / subscriptions"| db + db -->|"前端刷新後讀取最新狀態"| frontend +``` + +把它翻譯成人話就是: + +1. 用戶點按鈕。 +2. 前端找後端要支付鏈接。 +3. 後端用 Stripe 密鑰創建支付會話。 +4. 用戶去 Stripe 頁面付款。 +5. Stripe 把"付款真的成功了"這件事通過 Webhook 通知你。 +6. 你的後端再去更新資料庫。 + +## 5. 發起付款的標準時序圖 + +如果你習慣看更規範的系統圖,可以直接看這張時序圖: + +```mermaid +sequenceDiagram + autonumber + actor User as 用戶 + participant Frontend as 前端頁面 + participant Backend as 後端 API + participant Stripe as Stripe Checkout + + User->>Frontend: 點擊"升級"或"購買" + Frontend->>Backend: POST /api/billing/create-checkout-session + Note right of Frontend: 前端傳 plan / userId / email\n不傳最終收費金額 + Backend->>Backend: 校驗套餐並映射 priceId + Backend->>Stripe: 創建 Checkout Session + Stripe-->>Backend: 返回 session.url + Backend-->>Frontend: 返回支付鏈接 + Frontend-->>User: 跳轉到 Stripe 支付頁 + User->>Stripe: 完成付款 +``` + +## 6. 快速開始 + +如果你想最快把它接進項目,照著下面這 5 步做就夠了。 + +### 6.1 第一步:在 Stripe 後臺創建商品和價格 + +這一步的目的,不是"先隨便配點東西",而是先把 **你到底在賣什麼、打算怎麼收費** 這件事在 Stripe 裡定義清楚。 + +在 Stripe 的模型裡: + +- **Product** 表示"你賣的是什麼",比如 `Pro 會員` +- **Price** 表示"這個東西賣多少錢、按什麼週期賣",比如 `月付 9.9 美元`、`年付 99 美元` + +為什麼要先做這一步? +因為後面當你的後端創建 Checkout Session 時,並不是直接傳一個金額給 Stripe,而是要傳一個已經存在的 `price_id`。Stripe 再根據這個 `price_id` 去生成真正的支付頁、金額、幣種和訂閱週期。 + +如果你跳過這一步,後面的"創建支付鏈接"其實就沒法做。 + +::: info 為什麼這裡要先停一下 +很多新手看到 `Product`、`Price` 這兩個詞會有點煩,覺得像是在學 Stripe 的內部術語。 + +但實際上,這一步是在做一件很樸素的事: +- 把"賣什麼"定義清楚 +- 把"賣多少錢"定義清楚 +- 讓後端之後能拿一個穩定的 `price_id` 去創建支付鏈接 + +只要把這層想明白,後面的 Checkout Session 就不會覺得抽象。 +::: + +對於一個最小可行的訂閱系統,你至少先建這兩個層級: + +- 一個 `Product` +- 一個或多個 `Price` + +你可以直接打開這些頁面: + +- Stripe Dashboard 登錄頁:[Dashboard Login](https://dashboard.stripe.com/login) +- Stripe 商品與價格管理文檔:[Manage products and prices](https://docs.stripe.com/products-prices/manage-prices) +- Stripe Checkout 快速開始文檔:[Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- Stripe Dashboard 商品頁:[Product catalog](https://dashboard.stripe.com/test/products) + +推薦你先在 **Test mode(測試模式)** 下操作,不要一開始就在正式環境裡建。 + +一個最常見的最小配置是: + +- `Product`: `Pro Plan` +- `Price 1`: `pro_monthly` +- `Price 2`: `pro_yearly` + +你在後臺操作時,可以按這個順序理解: + +1. 先創建一個商品 `Pro Plan` +2. 再在這個商品下面掛兩個價格 +3. 月付和年付其實是同一個商品的兩種收費方式 + +完成後,你至少要記下這些資訊: + +- 月付價格的 `price_id` +- 年付價格的 `price_id` +- 你自己的套餐名,例如 `pro_monthly`、`pro_yearly` + +如果你是第一次進 Stripe 後臺,建議你把這一步理解成: + +- `Product` 決定支付頁裡賣的是什麼 +- `Price` 決定支付頁裡收多少錢 +- 後端之後真正會用到的,主要是 `price_id` + +::: info 真正要記下來的值 +這一頁裡最重要的不是商品名稱,而是 `price_id`。 + +後面無論是讓 AI 幫你接後端,還是你自己排查問題,真正會頻繁用到的,通常都是: +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- 它們背後對應的兩個 `price_id` +::: + +如果你想讓 AI 先帶你把後臺配置做完,可以直接用這個 prompt: + +```text +我現在是第一次用 Stripe,你先不要改程式碼,先帶我在 Stripe 後臺把最基本的付費配置做好。 + +請基於這些官方文檔給我一步一步的操作說明: +- https://docs.stripe.com/products-prices/manage-prices +- https://docs.stripe.com/checkout/quickstart?lang=node + +我的情況是: +- 我想做一個最簡單的會員付費 +- 只有兩個套餐:月付和年付 +- 我現在還不懂 Product、Price 這些詞 + +請你: +1. 先用最簡單的話告訴我 Product 和 Price 分別是什麼。 +2. 再按"先打開哪個頁面 -> 點哪裡 -> 填什麼"的順序教我操作。 +3. 最後提醒我,做完以後我需要從後臺複製哪些內容給後端使用。 +4. 如果我容易走錯,請順便提醒我應該一直在測試模式裡操作。 +``` + +### 6.2 第二步:準備環境變量 + +你通常至少需要準備這些環境變量: + +- `STRIPE_SECRET_KEY` +- `STRIPE_WEBHOOK_SECRET` +- `STRIPE_PRICE_PRO_MONTHLY` +- `STRIPE_PRICE_PRO_YEARLY` +- `APP_URL` +- `SUPABASE_URL` +- `SUPABASE_SERVICE_ROLE_KEY` + +你可以直接打開這些頁面: + +- Stripe API Keys 文檔:[API keys](https://docs.stripe.com/keys) +- Stripe Dashboard API Keys 頁面:[API Keys](https://dashboard.stripe.com/test/apikeys) +- Stripe Webhooks 文檔:[Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Stripe Dashboard Webhooks 頁面:[Workbench Webhooks](https://dashboard.stripe.com/test/workbench/webhooks) + +> ⚠️ `STRIPE_SECRET_KEY` 和 `SUPABASE_SERVICE_ROLE_KEY` 都只能放在後端。 + +::: info 環境變量這一步的目的 +這一步不是為了"先把 `.env` 填滿",而是為了把支付系統裡最敏感的幾樣東西放到後端保管: + +- Stripe 的後端密鑰 +- Webhook 驗籤密鑰 +- 你自己的價格映射 + +簡單理解: +前端只負責發起購買,真正的秘密和定價邏輯都應該留在服務端。 +::: + +這一步也可以直接讓 AI 幫你整理: + +```text +請你先看看我這個項目現在是怎麼放環境變量的,然後幫我把 Stripe 需要的環境變量整理出來。 + +請參考這些文檔: +- https://docs.stripe.com/keys +- https://docs.stripe.com/webhooks + +我的情況是: +- 我是零基礎 +- 我分不清哪些變量應該放前端,哪些應該放後端 +- 我也不確定當前項目應該改 `.env`、`.env.local` 還是別的文件 + +請你: +1. 先搜索當前項目裡環境變量通常寫在哪。 +2. 幫我列出 Stripe 接入最少需要哪些變量。 +3. 用最簡單的話告訴我每個變量是幹什麼的。 +4. 告訴我每個變量應該去哪一個 Stripe 頁面複製。 +5. 如果項目裡有示例環境變量文件,請直接幫我補上變量名。 +``` + +### 6.3 第三步:後端創建 Checkout Session + +這一步你不用自己寫接口,直接讓 AI 參考官方文檔幫你實現。 + +先把這些文檔給它: + +- Stripe Checkout 快速開始:[Build a Stripe-hosted checkout page](https://docs.stripe.com/checkout/quickstart?lang=node) +- Checkout Sessions API:[Create a Checkout Session](https://docs.stripe.com/api/checkout/sessions/create) +- 訂閱說明:[Subscriptions](https://docs.stripe.com/payments/subscriptions) + +然後直接貼這個 prompt: + +```text +請你先看看我當前項目的後端程式碼是怎麼組織的,然後幫我把 Stripe 支付接進去。 + +請參考這些官方文檔: +- https://docs.stripe.com/checkout/quickstart?lang=node +- https://docs.stripe.com/api/checkout/sessions/create +- https://docs.stripe.com/payments/subscriptions + +我的目標很簡單: +- 用戶點購買按鈕後,能跳到 Stripe 的付款頁面 +- 套餐只有月付和年付兩種 +- 不要讓我自己決定程式碼該放在哪,你先看項目再幫我放到合適的位置 + +請你: +1. 先搜索項目,弄清楚後端入口文件、路由文件、環境變量寫法分別在哪裡。 +2. 再參考官方文檔,幫我把"創建 Stripe 支付鏈接"這一步接進去。 +3. 不要讓我自己傳金額,價格請用後端環境變量來決定。 +4. 做完後告訴我你改了哪些文件。 +5. 最後告訴我,我還需要去 Stripe 後臺補哪些配置。 +``` + +### 6.4 第四步:前端跳轉到支付頁 + +這一步的目標非常簡單:讓定價頁按鈕調用你的後端接口,再跳轉到 Stripe Checkout。 + +參考文檔: + +- Stripe Checkout 集成說明:[Build an integration with Checkout](https://docs.stripe.com/payments/checkout/build-integration) + +給 AI 的 prompt: + +```text +幫我把項目裡的"購買"按鈕接上 Stripe。 + +要求: +- 不動現有頁面,只改按鈕點擊後的邏輯 +- 點擊後調用後端接口獲取支付鏈接,然後跳轉到 Stripe +- 如果出錯,給用戶一個簡單提示(比如"支付暫時不可用,請稍後再試") + +參考文檔:https://docs.stripe.com/payments/checkout/build-integration +``` + +### 6.5 第五步:Webhook 更新資料庫狀態 + +這是最關鍵的一步。 + +::: info 為什麼這一步最關鍵 +很多人會以為"用戶付完款並且跳轉到了 success 頁面"就算完成了。 + +不是。 + +對你的系統來說,真正重要的是: +**Stripe 有沒有正式把事件打到你的 Webhook,而你的後端有沒有把資料庫狀態更新成功。** +::: + +你也可以讓 AI 按 Stripe 官方 Webhook 文檔直接實現,不要自己手寫。 + +參考文檔: + +- Stripe Webhooks:[Receive Stripe events in your webhook endpoint](https://docs.stripe.com/webhooks) +- Stripe CLI:[Stripe CLI](https://docs.stripe.com/stripe-cli) +- Stripe CLI 用法:[Use the Stripe CLI](https://docs.stripe.com/stripe-cli/use-cli) + +給 AI 的 prompt: + +```text +請繼續幫我把 Stripe 的"付款成功後自動生效"這一步接好。 + +請參考這些官方文檔: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +我的目標是: +- 用戶付完錢後,不只是跳轉到成功頁面 +- 而是真的把我資料庫裡的會員狀態改成已開通 + +請你: +1. 先搜索當前項目裡資料庫相關程式碼和用戶狀態是怎麼存的。 +2. 再幫我加 Stripe webhook。 +3. 支付成功後,把對應用戶改成 active,或者更新成項目裡現在已經在用的會員狀態字段。 +4. 如果項目裡已經有訂閱表、訂單表、用戶表,請優先沿用現有結構。 +5. 做完後告訴我你改了哪些文件。 +6. 順便告訴我本地怎麼測試這一步有沒有真的生效。 +``` + +## 7. 讓 AI 幫你快速接入的提示詞 + +如果你用的是 Codex、Claude Code、Trae、Cursor 一類工具,可以直接把下面這個提示詞貼給它,讓它在你的項目裡做支付接入。 + +```text +請你幫我把當前項目接上 Stripe 支付,我希望做一個最簡單能跑起來的會員收費功能。 + +我的要求: +1. 我是零基礎,請你先自己看項目,再決定程式碼應該改哪裡。 +2. 不要讓我自己判斷目錄結構、路由結構、資料庫結構。 +3. 我只想先做最簡單版本:月付和年付兩個套餐。 +4. 用戶點擊購買後,能跳到 Stripe 付款頁面。 +5. 付款成功後,我資料庫裡的會員狀態能變成已開通。 +6. 不要一開始加太多複雜功能,比如優惠券、升級降級、複雜發票。 + +輸出要求: +1. 先給我一個改動計劃。 +2. 然後直接修改程式碼。 +3. 最後告訴我怎麼一步一步本地測試。 +4. 如果有哪個步驟還需要我去 Stripe 後臺操作,請直接把鏈接和要點告訴我。 +``` + +如果你希望 AI 更貼近你的項目,還可以在開頭補上: + +- 你的前端框架 +- 你的後端目錄結構 +- 你的資料庫表名 +- 你現在的用戶系統是 Supabase Auth 還是自建 Auth + +## 7.1 本地聯調也儘量交給 AI + +如果你希望連本地聯調都讓 AI 幫你串起來,可以直接用下面這段: + +```text +請繼續幫我把 Stripe 支付真正跑通,我想一步一步照著做,不想自己猜。 + +請參考官方文檔: +- https://docs.stripe.com/webhooks +- https://docs.stripe.com/stripe-cli +- https://docs.stripe.com/stripe-cli/use-cli + +我的目標: +1. 告訴我先打開哪些 Stripe 頁面。 +2. 告訴我如何拿到 STRIPE_WEBHOOK_SECRET。 +3. 告訴我如何使用 stripe login 和 stripe listen。 +4. 告訴我怎樣驗證 checkout.session.completed 已經成功打到本地 webhook。 +5. 如果當前項目需要先啟動前端和後端,也請順帶告訴我具體命令。 +6. 不要只講原理,請按實際操作步驟輸出。 +7. 如果我某一步做錯了,也請告訴我最常見的報錯會長什麼樣。 +``` + +## 8. 最容易踩坑的 4 件事 + +1. **把 `success` 頁面當成支付成功** + 真正決定狀態的是 Webhook,不是前端跳轉。 +2. **讓前端傳金額** + 這會帶來嚴重的價格篡改風險。 +3. **Webhook 路由被 `express.json()` 提前處理** + Stripe 驗籤需要原始請求體。 +4. **沒有做冪等處理** + Webhook 可能重試,如果你每次都重複加會員或積分,就會出事故。 + +## 9. 一句話選型建議 + +如果你現在只是想先把收費跑起來: + +| 你的主要用戶 | 最先嚐試的方案 | +| :--- | :--- | +| 海外 SaaS / 國際用戶 | Stripe | +| 中國大陸用戶 | 支付寶 / 微信支付 | +| 香港或跨境團隊 | Stripe + 本地錢包 / FPS 聚合方案 | + +後面的具體區別,我統一放到附錄。 + +::: info 最簡單的選型思路 +不要一開始就想"我要把全球支付方式一次全接完"。 + +更實際的順序通常是: +- 先按主要用戶所在地區選一條主支付鏈路 +- 先把最小可行支付跑通 +- 再根據真實用戶來源補第二、第三種支付方式 +::: + +## 10. 小結 + +到這裡,你已經掌握了最基礎但最重要的一條收費鏈路: + +1. 前端發起購買。 +2. 後端創建 Checkout Session。 +3. 用戶在 Stripe 頁面支付。 +4. Stripe 通過 Webhook 通知後端。 +5. 後端更新資料庫。 +6. 前端刷新後顯示新的會員或訂單狀態。 + +如果你只想快速把支付接進項目,前面的內容已經夠用了。下面的附錄你可以在真正遇到問題時再回來看。 + +--- + +# 附錄 + +## 附錄 A:Stripe 裡最常見的幾個對象 + +第一次看 Stripe 文檔,最容易被這些對象名繞暈。你其實只需要先理解下面幾個: + +| 對象 | 作用 | 你可以把它理解成什麼 | +| :--- | :--- | :--- | +| `Product` | 描述賣的是什麼 | 商品或會員套餐 | +| `Price` | 描述賣多少錢、週期怎麼收費 | 月付、年付、買斷 | +| `Checkout Session` | Stripe 託管的支付流程 | 付款頁 | +| `Subscription` | 週期訂閱關係 | 自動續費會員 | +| `Customer` | 付款用戶 | Stripe 中的客戶檔案 | +| `Webhook` | 異步通知 | Stripe 告訴你"這筆款怎麼樣了" | + +## 附錄 B:為什麼 `success` 頁面不等於支付成功 + +很多人以為"用戶付完錢,跳到了 success 頁面"就算支付成功了。這是最容易踩的坑。 + +### 先講一個真實場景 + +假設你做了一個會員網站: +1. 用戶點擊"購買會員" +2. 跳轉到 Stripe 付款頁面 +3. 用戶輸入信用卡,點擊付款 +4. 頁面跳轉到你的 `success.html` +5. 你在 success 頁面寫程式碼:"既然到了這頁,就給用戶開通會員" + +**問題在哪?** + +用戶可能根本沒付錢,或者付到一半關頁面了,也能直接訪問 `success.html`。 + +### 兩條完全不同的路徑 + +```mermaid +flowchart TB + pay["用戶在 Stripe 完成支付"] + + subgraph unreliable["❌ 不可靠路徑:只看 success 頁面"] + success["瀏覽器跳到 success 頁面"] + fake["前端程式碼認為已開通"] + risk["風險:關頁 / 斷網 / 偽造 URL / 根本沒付錢"] + success --> fake --> risk + end + + subgraph reliable["✅ 可靠路徑:以後端 Webhook 為準"] + event["Stripe 服務器發送 Webhook"] + verify["後端校驗簽名"] + active["資料庫正式更新為已付費"] + event --> verify --> active + end + + pay --> success + pay --> event +``` + +**關鍵區別:** + +| | success 頁面跳轉 | Webhook 通知 | +| :--- | :--- | :--- | +| 誰發起的 | 用戶的瀏覽器 | Stripe 的服務器 | +| 能偽造嗎 | 能,直接訪問 URL 就行 | 不能,有簽名驗證 | +| 一定代表付款成功嗎 | 不一定 | 一定 | +| 你的系統怎麼知道 | 前端程式碼猜的 | Stripe 正式通知的 | + +### 完整流程應該是怎樣的 + +```mermaid +sequenceDiagram + autonumber + actor User as 用戶 + participant Frontend as 你的網頁 + participant Stripe as Stripe + participant Webhook as 你的後端接口 + participant DB as 資料庫 + + User->>Stripe: 在 Stripe 頁面完成付款 + Note over Stripe: 錢真的到了 Stripe 賬戶 + + Stripe-->>Frontend: 瀏覽器跳轉到 success 頁面 + Note over Frontend: ⚠️ 這步只是跳轉
不代表系統已確認 + + Stripe->>Webhook: 發送 Webhook 通知
"checkout.session.completed" + Note over Webhook: ✅ 這才是正式通知 + + Webhook->>Webhook: 校驗簽名
(確保是 Stripe 發的,不是黑客) + + Webhook->>DB: 更新用戶狀態為"已付費" + DB-->>Webhook: 保存成功 + Webhook-->>Stripe: 返回 200 OK + + Frontend->>DB: 用戶刷新頁面,查詢狀態 + DB-->>Frontend: 返回"已付費" + Note over Frontend: 這時候才顯示會員功能 +``` + +### 每個環節的卡點 + +**第 1 步:用戶在 Stripe 付款** + +這是唯一確定"錢真的付了"的時刻: +- 用戶輸入信用卡資訊,點擊確認 +- 銀行從用戶卡里扣款 +- Stripe 確認收到這筆錢 + +**第 2 步:瀏覽器跳轉到 success 頁面(問題最大)** + +這一步完全不可靠,因為: +- 用戶可以直接在瀏覽器輸入 `yoursite.com/success`,根本沒付錢也能訪問 +- 用戶付到一半關頁面了,但之前複製了 success 鏈接,之後直接打開 +- 網路問題導致跳轉失敗,但錢已經扣了(用戶付了錢卻沒看到成功頁面) +- 用戶點返回鍵,又付了一次錢,但兩次都跳轉到同一個 success 頁面 + +**第 3 步:Stripe 發送 Webhook** + +這是 Stripe 主動通知你的服務器"這筆款到賬了": +- 只有 Stripe 的服務器能發起這個請求 +- 請求裡帶有簽名,你的後端可以驗證是不是真的 Stripe 發的 +- 即使 success 頁面沒打開、用戶斷網了,Webhook 也會發送 + +**第 4 步:後端校驗簽名** + +為什麼要校驗?防止黑客偽造通知。 + +假設沒有校驗,黑客可以直接給你的服務器發一個假通知:"用戶 A 付了 1000 元"。你的系統就會給黑客開通會員。 + +校驗的過程: +- Stripe 用你們約定的密鑰對通知內容生成簽名 +- 你的後端用同樣的密鑰驗證簽名是否匹配 +- 匹配 = 100% 是 Stripe 發的,不匹配 = 直接拒絕 + +**第 5 步:更新資料庫** + +只有校驗通過後,才更新資料庫: +- 把用戶狀態從"待付款"改成"已付費" +- 記錄訂單號、金額、付款時間 +- 開通對應的會員權限 + +**第 6 步:前端查詢狀態** + +success 頁面不要自己判斷"到了這頁就是成功了"。正確的做法: +- 頁面加載時,向後端發送請求:"這個用戶付費了嗎?" +- 後端查資料庫,返回真實狀態 +- 根據返回結果顯示"開通成功"或"等待確認" + +### 一個常見的錯誤做法 + +```javascript +// 錯誤:在 success 頁面直接開通 +// success.html +if (window.location.pathname === '/success') { + // 危險!任何人都能訪問 /success + activateMembership(); +} +``` + +```javascript +// 正確:每次刷新都查後端 +// success.html +async function checkStatus() { + const response = await fetch('/api/user/status'); + const data = await response.json(); + + if (data.paymentStatus === 'paid') { + showMemberFeatures(); + } else { + showPendingMessage(); + } +} +``` + +### 總結一句話 + +**success 頁面只是"瀏覽器跳轉成功",Webhook 才是"Stripe 正式確認收款"。** + +你的系統必須以 Webhook 為準,不能相信前端的跳轉。 + +## 附錄 C:訂閱系統最值得監聽的事件 + +| 事件 | 含義 | 你通常要做什麼 | +| :--- | :--- | :--- | +| `checkout.session.completed` | 首次開通成功 | 創建本地訂閱記錄 | +| `invoice.paid` | 自動續費成功 | 延長有效期 | +| `invoice.payment_failed` | 自動扣費失敗 | 標記風險狀態並提醒用戶 | +| `customer.subscription.deleted` | 訂閱取消 | 回收權限或標記到期後失效 | + +### 訂閱狀態圖 + +```mermaid +stateDiagram-v2 + [*] --> NotStarted: 用戶未購買 + NotStarted --> Active: checkout.session.completed + Active --> Active: invoice.paid + Active --> PastDue: invoice.payment_failed + PastDue --> Active: 用戶補款成功 + Active --> Canceled: customer.subscription.deleted + PastDue --> Canceled: 到期未恢復 + Canceled --> [*] + + state "未開通" as NotStarted + state "會員有效" as Active + state "扣費失敗 / 待恢復" as PastDue + state "已取消 / 到期回收" as Canceled +``` + +### 續費 / 失敗 / 取消時序圖 + +```mermaid +sequenceDiagram + autonumber + participant Stripe as Stripe + participant Webhook as 你的 Webhook 接口 + participant DB as 訂閱表 / 訂單表 + participant App as 你的應用 + actor User as 用戶 + + rect rgb(235, 248, 255) + Stripe->>Webhook: invoice.paid + Webhook->>DB: 延長 current_period_end + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 繼續保持會員有效 + end + + rect rgb(255, 247, 237) + Stripe->>Webhook: invoice.payment_failed + Webhook->>DB: 標記 past_due + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 提醒更新支付方式 + end + + rect rgb(254, 242, 242) + Stripe->>Webhook: customer.subscription.deleted + Webhook->>DB: 標記 canceled + DB-->>Webhook: 更新成功 + Webhook-->>Stripe: 200 OK + App-->>User: 停止高級權限 + end +``` + +## 附錄 D:其他支付方案怎麼選 + +### 1. 中國大陸 + +主要用戶在大陸的話,首選還是 **[支付寶](https://open.alipay.com/)** 和 **[微信支付](https://pay.wechatpay.cn/)**。 + +**業務模式:** + +兩者都是"支付網關"模式。你需要: +- 申請商戶資質(營業執照、對公賬戶) +- 用戶付的錢直接到你的商戶賬戶 +- 你自己負責稅務、退款、對賬 + +**技術模式:** + +兩者都是"後端下單 + 前端調起 + 後端通知"的模型,跟 Stripe 思路一樣。 + +**支付寶接入流程:** +1. 在支付寶開放平臺創建應用 +2. 配置公私鑰和回調地址 +3. 後端調用統一下單接口,生成支付鏈接或二維碼 +4. 用戶掃碼或跳轉付款 +5. 支付寶異步通知你的後端,更新訂單狀態 + +**微信支付接入流程:** +- JSAPI 支付:適合公眾號、小程序,用戶在微信內直接付款 +- Native 支付:PC 端生成二維碼,用戶掃碼付款 +- H5 支付:手機瀏覽器內拉起微信 App 付款 + +流程:後端下單 → 拿到 `prepay_id` 或 `code_url` → 前端調起支付 → 後端接收通知確認成功 + +**參考鏈接:** +- 支付寶開放平臺:https://open.alipay.com/ +- 微信支付商戶文檔:https://pay.wechatpay.cn/doc/v3/merchant/ + +### 2. 香港 + +香港市場比較混合,常見組合: + +- 銀行卡:Visa / Mastercard +- FPS(轉數快):香港本地即時轉賬 +- AlipayHK / WeChat Pay HK:香港版支付寶和微信 + +**推薦組合:** +- 用 **[Stripe](https://stripe.com/hk)** 覆蓋國際卡和訂閱 +- 用 **[Airwallex](https://www.airwallex.com/)** 或 **[Adyen](https://www.adyen.com/)** 補本地錢包和 FPS + +### 3. 海外 / 國際 SaaS + +#### [Stripe](https://stripe.com/) + +**業務模式:** 支付網關 + +- 你需要自己申請商戶資質(部分國家 Stripe 可以幫你搞定) +- 用戶付的錢到你的 Stripe 賬戶,再結算到你的銀行賬戶 +- 你自己負責稅務申報 + +**技術模式:** + +- API 體驗最好,文檔清晰 +- 支持 Checkout(託管頁面)、Elements(自定義表單)、Payment Links(無程式碼) +- Webhook 通知支付狀態 +- 支持訂閱、發票、多幣種 + +**適合誰:** 海外 SaaS、獨立開發者、需要靈活定製的團隊 + +**參考鏈接:** https://docs.stripe.com/ + +#### [PayPal](https://www.paypal.com/) + +**業務模式:** 支付網關 + +- 用戶付的錢到你的 PayPal 賬戶,再提現到銀行 +- 你自己負責稅務 + +**技術模式:** + +- 一次性支付:前端放按鈕,後端創建/確認訂單 +- 訂閱制:先建 Product 和 Plan,再用 SDK 拉起 +- 同樣需要後端和 Webhook,不要只看前端回調 + +**適合誰:** 需要補充渠道的海外業務,用戶習慣用 PayPal 付款 + +**參考鏈接:** https://developer.paypal.com/docs/ + +#### [Paddle](https://www.paddle.com/) + +**業務模式:** Merchant of Record (MoR) + +- Paddle 是"記錄商家",法律上由 Paddle 向用戶收款 +- Paddle 幫你處理全球稅務、VAT、退款、合規 +- 用戶付的錢到 Paddle,Paddle 扣除稅費和手續費後結算給你 +- 你不需要在每個國家註冊公司或處理稅務 + +**技術模式:** + +- Paddle.js:前端嵌入托管結賬頁 +- 後端 API:創建 transaction,交給 checkout 處理 +- Webhook 同步訂閱狀態 + +**適合誰:** 不想處理全球稅務的 SaaS 團隊,尤其是 B2B SaaS + +**參考鏈接:** https://developer.paddle.com/ + +#### [Lemon Squeezy](https://www.lemonsqueezy.com/) + +**業務模式:** Merchant of Record (MoR) + +- 和 Paddle 類似,Lemon Squeezy 是"記錄商家" +- 幫你處理全球稅務、VAT、合規 +- 2024 年被 Stripe 收購,但獨立運營 + +**技術模式:** + +- Hosted Checkout:最簡單,直接生成付款鏈接 +- Checkout Overlay:浮層嵌入你的頁面 +- 後端 API:創建 checkout,靈活控制 + +**適合誰:** 獨立開發者、數字產品、軟體授權 + +**參考鏈接:** https://docs.lemonsqueezy.com/ + +### 4. 企業級方案 + +#### [Airwallex(空中雲匯)](https://www.airwallex.com/) + +**業務模式:** 支付網關 + 全球賬戶 + +- 提供全球收款賬戶(類似虛擬銀行賬戶) +- 支持多幣種收款、換匯、付款 +- 你自己負責稅務 + +**技術模式:** + +- Payment Links:幾乎不用程式碼,生成付款鏈接 +- Hosted Payment Page:託管頁面 +- Drop-in / Embedded / Native API:深度接入,自定義程度高 +- 支持 Alipay HK、FPS、WeChat Pay 等本地支付方式 + +**適合誰:** 香港團隊、跨境業務、需要多幣種賬戶的公司 + +**參考鏈接:** https://www.airwallex.com/docs/ + +#### [Adyen](https://www.adyen.com/) + +**業務模式:** 支付網關 + +- 企業級支付平臺,年處理交易額萬億歐元 +- 支持線上、線下、移動端全渠道 +- 你自己負責稅務 + +**技術模式:** + +- Pay by Link:最簡單,生成付款鏈接 +- Drop-in / Components:標準線上接入 +- 後臺可啟用 Alipay、Alipay HK、PayMe 等本地支付方式 + +**適合誰:** 大型企業、需要全渠道支付的公司 + +**參考鏈接:** https://docs.adyen.com/ + +### 5. 方案對比 + +| 方案 | 業務模式 | 稅務處理 | 適合誰 | +| :--- | :--- | :--- | :--- | +| Stripe | 支付網關 | 自己處理 | 海外 SaaS、開發者 | +| PayPal | 支付網關 | 自己處理 | 海外補充渠道 | +| Paddle | MoR | Paddle 代處理 | B2B SaaS、不想管稅務 | +| Lemon Squeezy | MoR | LS 代處理 | 獨立開發者、數字產品 | +| Adyen | 支付網關 | 自己處理 | 大型企業 | +| Airwallex | 支付網關 + 賬戶 | 自己處理 | 跨境業務、香港團隊 | +| 支付寶/微信 | 支付網關 | 自己處理 | 大陸用戶 | + +### 6. 按地區選方案 + +| 你的市場 | 推薦方案 | +| :--- | :--- | +| 中國大陸 | 支付寶 / 微信支付 | +| 香港 | Stripe + Airwallex / Adyen | +| 海外 SaaS | Stripe(自己管稅務)或 Paddle(MoR 代管) | +| 海外數字產品 | Stripe / Lemon Squeezy / Paddle | +| 多地區企業級 | Adyen / Airwallex / Stripe 組合 | diff --git a/docs/zh-tw/stage-2/backend/zeabur-deployment/index.md b/docs/zh-tw/stage-2/backend/zeabur-deployment/index.md new file mode 100644 index 0000000..a7a14c2 --- /dev/null +++ b/docs/zh-tw/stage-2/backend/zeabur-deployment/index.md @@ -0,0 +1,490 @@ +# 如何部署 Web 應用 + +在本教程中,我們將介紹如何將你的 Web 應用部署到互聯網上,讓其他人可以訪問。我們會介紹三個常用的部署平臺:**騰訊雲 CloudBase**、**Vercel** 和 **Zeabur**,幫助你快速完成從"寫好程式碼"到"讓別人可以在互聯網上訪問你的網站"的完整流程。 + +# 什麼是"部署"? + +在開始之前,我們先弄清楚"部署(Deployment)"到底是什麼意思。任何一個網站想要被外部用戶訪問,都必須有一個可以公開訪問的網路地址(這個地址可以是 IP 地址,比如 123.45.67.89,也可以是域名,比如 [google.com](https://google.com/) 等)。但只有地址是不夠的——你寫好的網頁程式碼(例如 HTML、CSS、JavaScript 文件,或者使用 React、Vue 等框架寫的項目),以及相關的圖片 / 影片資源,都必須"放"在一臺 24 小時在線的服務器上,由它來響應網路請求,這樣任何人的瀏覽器才能訪問並下載這些資源。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image1.png) + +圖片來源:https://www.hostinger.com/tutorials/what-is-cloud-hosting + +把資源上傳、配置好環境並讓服務"跑起來"的整個過程,就被稱為 **部署(Deployment)**。 + +簡單來說:你在自己電腦上寫好的網頁,只要在本機啟動程序,就只能通過本地地址在自己的瀏覽器裡訪問,因為這些程式碼只存在於你的硬盤上。"部署"就是把你的程式碼和資源轉移到一臺連接著公網的專業服務器上,並做好配置,讓這臺服務器知道"別人訪問時我要怎麼響應"——比如:當有人在瀏覽器中輸入你的域名時,服務器會立刻找到對應的網頁文件,把內容傳回給對方的設備,從而讓用戶看到你的頁面。 + +如果手動部署,一個項目往往需要好幾個步驟,每一步都可能踩坑。常見關鍵步驟包括: + +1. **服務器準備**:你需要先購買雲服務器(比如阿里雲、騰訊雲、或 AWS EC2),選擇服務器所在地區(如上海、新加坡)、配置(CPU、內存、磁盤大小等),還要學會如何遠程連接服務器(例如通過 SSH 工具登錄)。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image2.png) +2. **環境配置**:Web 應用需要在特定"環境"中才能運行——例如運行 Node.js 項目必須先安裝 Node.js;運行 Python 項目必須安裝 Python 以及對應的第三方庫。如果環境版本不匹配,程序就可能報錯、無法啟動。 +3. **上傳資源**:你需要把本地的程式碼和資源上傳到服務器上,常用的方法包括 FTP 或 Git。如果項目體積比較大(比如包含影片文件),中途一旦斷線,有時需要重新上傳。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image3.png) + +4. **啟動服務並測試**:上傳完成後,你還需要在服務器上執行命令啟動應用,並測試"分配的網路地址是否能訪問"。如果訪問不了,有可能是服務器防火牆沒有放行對應端口(比如你的應用監聽 3000 端口,但該端口被防火牆攔截),也可能是程序本身有 Bug,這時就需要查看服務器日誌進行排查。 + > 💡 可以把端口理解為區分同一臺設備上不同應用的"房間號",而 IP 則是這臺設備的"門牌號"。IP 和端口合在一起(IP:port),就可以精確定位到某一個網路服務。 +5. **維護與更新**:後續每次你修改程式碼,都要重新上傳並重啟服務。如果服務器宕機(例如斷電、網路故障),還需要手動重啟應用,有時還要額外配置"進程守護工具",讓程序在異常退出後自動拉起。 + +像 CloudBase、Vercel、Zeabur 這樣的"低程式碼部署平臺",就是為了解決上述複雜問題而誕生的。它們會幫你自動完成"買服務器、配環境、上傳程式碼、啟動服務、監控運行"等步驟。你只需要把自己的程式碼倉庫(比如 GitHub 或 GitLab)連接到平臺,或者直接上傳程式碼,它就會自動拉取程式碼、識別應用類型、配置對應的運行時環境,最後給你一個可以被任何人訪問的公網地址。它甚至可以一鍵綁定你自己的域名。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image4.png) + +接下來,我們會分別介紹這三個平臺的特點和使用方法,幫助你選擇最適合自己的部署方案。 + +--- + +# 部署平臺對比 + +| 平臺 | 特點 | 適用場景 | 免費額度 | +|------|------|----------|----------| +| **騰訊雲 CloudBase** | 國內訪問速度快,與微信生態深度整合 | 國內用戶為主、需要微信小程序支持的項目 | 有免費額度 | +| **Vercel** | 前端框架支持好,與 GitHub 集成緊密 | React/Vue/Next.js 等現代前端項目 | 有免費額度 | +| **Netlify** | 功能全面,支持表單處理和身份驗證,與 Git 集成好 | 需要表單處理、身份驗證等高級功能的靜態網站 | 有免費額度 | +| **Zeabur** | 支持多種語言和服務模板,配置靈活 | 需要部署多種服務(如 Dify、n8n)的複雜項目 | 每月約 5 美元免費額度 | + +--- + +# 1. 騰訊雲 CloudBase + +騰訊雲 CloudBase(雲開發)是騰訊雲提供的一站式後端雲服務,特別適合國內開發者使用。它的優勢在於: + +- **國內訪問速度快**:服務器位於國內,訪問延遲低 +- **微信生態整合**:可以方便地對接微信小程序、公眾號 +- **一站式解決方案**:提供靜態網站託管、雲函數、資料庫、存儲等全套服務 +- **免費額度充足**:個人開發者有充足的免費資源額度 + +## 使用 CloudBase 部署 Web 應用 + +### 步驟 1:註冊並登錄 + +訪問 [騰訊雲 CloudBase 控制檯](https://console.cloud.tencent.com/tcb),使用微信或 QQ 登錄。 + +### 步驟 2:創建環境 + +點擊"新建環境",選擇一個環境名稱(如 `my-web-app`)。 + +> ⚠️ **注意**:CloudBase 的免費體驗版需要兌換碼才能開通。你需要關注騰訊雲 CloudBase 公眾號,在公眾號中輸入"領取兌換碼"獲取免費體驗版的兌換碼,然後在創建環境時填寫兌換碼即可開通免費環境(免費試用期為 6 個月)。 + +### 步驟 3:開通靜態網站託管 + +在環境管理頁面,找到"靜態網站託管"功能並開通。開通後你會獲得一個默認的訪問域名。 + +CloudBase 的靜態網站託管提供多種部署方式,與 Zeabur 類似: + +- **本地項目上傳**:直接從本地上傳構建好的靜態文件(HTML、CSS、JS 等) +- **模板部署**:使用預設模板快速創建項目,如 React Web 應用模板、Vue Web 應用模板 +- **Git 倉庫部署**:支持從 GitHub 等程式碼倉庫自動拉取程式碼並部署 + +### 步驟 4:部署程式碼 + +在靜態網站託管頁面,CloudBase 提供三種部署方式: + +**方式一:本地項目部署(本地項目上傳)** +- 在控制檯選擇"本地項目部署" +- 直接上傳構建好的靜態文件(HTML、CSS、JS 等) +- 選擇你本地構建好的項目文件夾(如 `dist` 或 `build` 目錄) +- 等待上傳完成即可訪問 + +**方式二:模板部署** +- 使用預設模板快速創建項目 +- 支持 React Web 應用模板、Vue Web 應用模板等 +- 基於模板自動構建並部署 + +**方式三:Git 倉庫部署** +- **Git 個人倉庫部署**:綁定你的 GitHub 等個人程式碼倉庫 +- **公開倉庫部署**:支持從公開的 Git 倉庫拉取程式碼 +- 配置自動構建命令(如 `npm run build`) +- 每次推送程式碼會自動重新部署 + +> 💡 **提示**:你也可以使用 CLI 工具進行部署: +> ```bash +> # 安裝 CloudBase CLI +> npm install -g @cloudbase/cli +> # 登錄 +> tcb login +> # 部署 +> tcb hosting deploy ./dist -e your-env-id +> ``` + +### 步驟 5:配置自定義域名(可選) + +在靜態網站託管設置中,可以綁定你自己的域名,並申請免費的 HTTPS 證書。 + +--- + +# 2. Vercel + +Vercel 是全球最流行的前端部署平臺之一,特別適合部署 React、Vue、Next.js 等現代前端框架項目。它的特點包括: + +- **與 GitHub 深度集成**:推送程式碼即自動部署 +- **自動預覽**:每個 Pull Request 都會生成獨立的預覽鏈接 +- **全球 CDN**:網站自動分發到全球節點,訪問速度快 +- **Serverless 函數**:支持在項目中編寫後端 API + +> ⚠️ **注意**:Vercel 在部分網路環境下訪問可能不太穩定,國內用戶建議優先考慮 CloudBase。 + +## 使用 Vercel 部署 Web 應用 + +### 步驟 1:註冊賬號 + +訪問 [Vercel 官網](https://vercel.com),使用 GitHub 賬號登錄。 + +### 步驟 2:導入項目 + +1. 點擊 "Add New Project" +2. 選擇你要部署的 GitHub 倉庫 +3. 如果沒有看到想要的倉庫,點擊 "Adjust GitHub App Permissions" 授權訪問 + +### 步驟 3:配置構建設置 + +Vercel 會自動識別項目類型並配置構建命令: + +| 框架 | 構建命令 | 輸出目錄 | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Next.js | `next build` | - | +| 純 HTML | - | 項目根目錄 | + +如果自動識別不正確,可以手動修改: +- **Build Command**: 構建命令,如 `npm run build` +- **Output Directory**: 構建輸出目錄,如 `dist` 或 `build` +- **Install Command**: 依賴安裝命令,通常是 `npm install` + +### 步驟 4:部署 + +點擊 "Deploy" 按鈕,等待構建完成。構建成功後,你會獲得一個 `xxx.vercel.app` 的域名。 + +### 步驟 5:自定義域名(可選) + +在項目設置中的 "Domains" 頁面,可以添加你自己的域名。Vercel 會自動配置 HTTPS。 + +--- + +# 3. Netlify + +Netlify 是另一個非常流行的前端部署平臺,與 Vercel 類似,特別適合部署靜態網站和單頁應用(SPA)。它的特點包括: + +- **功能全面**:除了靜態網站託管,還支持表單處理、身份驗證、邊緣函數等高級功能 +- **與 Git 深度集成**:支持 GitHub、GitLab、Bitbucket,推送程式碼自動部署 +- **分支預覽**:每個分支都會自動生成獨立的預覽鏈接 +- **全球 CDN**:網站自動分發到全球節點,訪問速度快 +- **表單處理**:無需後端程式碼即可處理網站表單提交 +- **身份驗證**:內置用戶身份驗證功能,可快速實現登錄/註冊 + +> ⚠️ **注意**:Netlify 的國內訪問速度可能不如 CloudBase,建議主要面向海外用戶的項目使用。 + +## 使用 Netlify 部署 Web 應用 + +### 步驟 1:註冊賬號 + +訪問 [Netlify 官網](https://www.netlify.com),點擊 "Sign up" 註冊。你可以使用 GitHub、GitLab、Bitbucket 或郵箱註冊。 + +### 步驟 2:導入項目 + +1. 登錄後點擊 "Add new site" → "Import an existing project" +2. 選擇你的程式碼託管平臺(如 GitHub) +3. 授權 Netlify 訪問你的倉庫 +4. 從列表中選擇你要部署的倉庫 + +### 步驟 3:配置構建設置 + +Netlify 會自動識別常見的前端框架並配置構建設置: + +| 框架 | 構建命令 | 發佈目錄 | +|------|----------|----------| +| React | `npm run build` | `build` | +| Vue | `npm run build` | `dist` | +| Angular | `ng build` | `dist/` | +| Next.js | `next build` | `out` | +| 純 HTML | - | `.`(項目根目錄) | + +如果自動識別不正確,可以手動配置: +- **Build command**: 構建命令,如 `npm run build` +- **Publish directory**: 構建輸出目錄,如 `dist` 或 `build` + +### 步驟 4:部署 + +點擊 "Deploy site" 按鈕,等待構建完成。構建成功後,你會獲得一個 `xxx.netlify.app` 的域名,任何人都可以通過這個地址訪問你的網站。 + +### 步驟 5:配置自定義域名(可選) + +1. 進入站點設置,點擊 "Domain management" +2. 點擊 "Add custom domain" +3. 輸入你的域名並按照提示配置 DNS 記錄 +4. Netlify 會自動申請並配置 HTTPS 證書 + +### 特色功能 + +#### 1. 表單處理 + +Netlify 提供了一個非常方便的功能:無需後端程式碼即可處理表單提交。 + +只需在 HTML 表單中添加 `netlify` 屬性: + +```html +
+

+ +

+

+ +

+

+ +

+

+ +

+
+``` + +部署後,表單提交的資料會自動發送到 Netlify 後臺,你可以在 "Forms" 頁面查看所有提交記錄,也可以設置郵件通知或將資料轉發到其他服務。 + +#### 2. Netlify Functions(邊緣函數) + +Netlify 支持部署無服務器函數(Serverless Functions),讓你可以在不搭建完整後端服務器的情況下,實現簡單的 API 接口。你可以使用 JavaScript 或 TypeScript 編寫函數,部署後會自動獲得一個可訪問的 URL。 + +例如,創建一個 `hello.js` 文件: + +```javascript +exports.handler = async (event, context) => { + return { + statusCode: 200, + body: JSON.stringify({ message: "Hello from Netlify!" }) + }; +}; +``` + +部署後,你可以通過 `https://你的域名/.netlify/functions/hello` 訪問這個函數。 + +#### 3. 本地開發支持 + +Netlify 提供了 CLI 工具,方便你在本地開發和測試: + +```bash +# 安裝 Netlify CLI +npm install -g netlify-cli + +# 登錄賬號 +netlify login + +# 本地啟動開發服務器 +netlify dev + +# 本地測試函數 +netlify functions:serve +``` + +使用 CLI 工具可以在本地模擬 Netlify 環境,包括表單提交、函數調用等功能,方便在部署前進行測試。 + +--- + +# 4. Zeabur + +Zeabur 是一個新興的部署平臺,特別適合需要部署多種服務的複雜項目。它的優勢在於: + +- **服務模板豐富**:內置 Dify、n8n、資料庫等多種服務模板 +- **支持多種部署方式**:GitHub、模板、Docker 鏡像、本地項目等 +- **靈活的服務組合**:可以在一個項目中部署多個相互關聯的服務 +- **按量計費**:用多少付多少,適合實驗性項目 + +## 使用 Zeabur 部署 Dify + +在之前的課程中,我們已經簡單接觸過 Dify。現在,我們可以通過 [Zeabur](https://zeabur.com/projects) 非常輕鬆地啟動自己的 Dify 服務。首先打開 [控制檯頁面](https://zeabur.com/projects),我們先看一下上面的各個區域。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image5.png) + +在這個頁面上,你首先能看到許多方塊,這些就是已經啟動的服務。在頂部菜單中,你會看到 Agent、Servers、Docs、Templates 等幾個選項,它們分別代表: + +1. **Agent**:可以打開 Zeabur 內置的智能助手(Agent),向它提問如何操作,或者查詢當前服務器的狀態。 +2. **Servers**:在這裡可以添加你自己購買的雲服務器,或者直接通過 Zeabur 購買服務器。 +3. **Docs**:查看 Zeabur 的完整文檔說明。 +4. **Templates**:這裡列出了所有內置的模板鏡像。 + +> 這裡提到的"鏡像(Image)",可以理解為"包含程式碼和運行環境的壓縮包"。當某個服務在一臺服務器上成功跑起來之後,我們可以選擇把"這套運行環境 + 程式碼"打包成鏡像。之後,在任何新服務器上,只要把這個壓縮包解壓並運行,就不需要重新配置環境和程式碼,服務就能直接跑起來。 + +在頁面右上角,你還能看到自己的餘額。默認情況下,每個月會有 5 美元左右的免費額度。關於細節計費規則暫時可以不用太在意,只需要知道:只要服務器在運行,就會消耗額度。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image6.png) + +點擊餘額可以查看每日的消耗明細。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image7.png) + +現在我們來創建自己的 Dify 服務。首先,在 [控制檯首頁](https://zeabur.com/projects) 點擊 "New Project"。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image8.png) + +接下來是各個創建方式的解釋: + +1. **GitHub** + 可以連接到你的 GitHub 賬號。綁定之後,就可以直接從 GitHub 倉庫裡選擇項目部署(GitHub 是目前全球最大的程式碼託管平臺)。 +2. **Template(模板)** + 可以基於模板來部署服務。Zeabur 內置了很多預設項目模板(例如 Dify、n8n 等),你可以基於這些模板快速創建並部署應用。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image9.png) +3. **Databases(資料庫)** + 用於部署資料庫服務,比如 MySQL、MongoDB 等常見資料庫。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image10.png) +4. **Functions(函數)** + 可以部署函數服務,你可以編寫 JavaScript 或 Python 程式碼,讓它們以函數的形式被調用。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image11.png) + + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image12.png) + +5. **Local Project(本地項目)** + 上傳一個本地文件夾,Zeabur 會自動識別其中的啟動腳本。這適合將你已經在本地開發好的項目快速部署到 Zeabur 上。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image13.png) +6. **Docker Image** + 部署已經打包好的 Docker 鏡像。如果你的項目已經被打成了 Docker 鏡像(例如存放在 Docker Hub 或其他鏡像倉庫中),可以在這裡直接部署。 + ![](/zh-cn/stage-2/backend/zeabur-deployment/images/image14.png) +7. **Cursor** + 如果你安裝了 Cursor(例如 Cursor IDE),可以通過這個入口將 Cursor 中的項目直接部署到 Zeabur。 + +如果你想部署自己的 Dify 服務,推薦選擇 **Template** 方式,然後在搜索框中輸入 "dify"。可以看到很多由不同作者維護的版本,你可以任選其一(比如 v1.6.0 版本)。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image15.png) + +接著,輸入任意一個名稱,Zeabur 會基於這個名稱生成一個臨時的自定義域名。之後所有人都可以通過這個網址訪問你的服務。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image16.png) + +創建完成後,你會看到多個程序(服務)依次啟動。需要耐心等待所有服務都進入"已啟動"狀態。(Dify 服務是由多個程序組成的,每個程序負責不同的功能,它們之間會相互協作。) + +一般來說,你只需要點擊左側的 Dify 應用,就可以看到默認的訪問入口地址。但在本例中,由於前面還套了一層 nginx,你需要點擊 nginx 服務來獲取最終訪問地址。可以理解為:nginx 就是負責對外統一"收發請求"的主程序,它會把外部訪問的地址分發給內部各個服務。點擊左側的 Nginx,在詳情頁中可以看到當前的服務地址,然後在瀏覽器裡打開這個地址,等待服務完全啟動。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image17.png) + +稍等片刻後,你就能看到 Dify 的登錄界面了。輸入郵箱地址和註冊密碼,就可以開始使用你自己的 Dify 服務了。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image18.png) + +如果你有興趣,還可以順便啟動一個 n8n 服務。n8n 也是海外非常流行的一款 AI 工作流平臺。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image19.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image20.png) + +## 使用 Zeabur 與 Trae 部署貪吃蛇遊戲 + +在本教程的下一個部分,我們會體驗 Zeabur 的一些進階用法。我們先用 Trae 生成一個貪吃蛇小遊戲,再把它部署到 Zeabur 的服務器上,並配置一個可公開訪問的鏈接,讓任何人都可以打開你的遊戲。 + +第一步,是在本地使用 Trae 創建一個貪吃蛇項目。 + +### 使用 HTML 框架實現 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image23.png) + +對於 Trae 來說,生成一個基於 HTML 的貪吃蛇網頁遊戲非常簡單。遊戲生成完成後,你只需要按照前面介紹的 Zeabur 本地部署方式,把包含所有文件的文件夾上傳上去即可。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image24.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image25.png)![](/zh-cn/stage-2/backend/zeabur-deployment/images/image26.png) + +完成後,你就會進入該服務的詳情界面: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image27.png) + +點擊左側的 "Network" 選項,在頁面中找到 "Public Address" 區域。點擊 "Generate Domain",即可生成一個對外訪問地址,你可以輸入任意喜歡的名稱。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image28.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image29.png) + +生成完成後,只要在瀏覽器中打開這個地址,就可以運行你自己的貪吃蛇遊戲了。其它 HTML 類型的 Web 應用也可以用完全相同的方式來部署。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image30.png) + +### 使用 React 框架實現 + +前面我們學習瞭如何部署基於 HTML 的 Web 應用。接下來,我們再嘗試部署一個目前更常用的前端框架:React 應用。相比純 HTML,React 被認為是一種更加成熟、現代的前端開發框架。它通過組件化的方式組織頁面結構,能夠顯著加快複雜頁面的開發,是企業級項目中非常主流的選擇。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image31.png) + +#### 重構為 React 架構 + +在 Trae 中,你只需要向 Agent 說明:"幫我把這份程式碼重構成 React 架構",就可以比較輕鬆地把原本基於 HTML 的結構重構成 React 項目。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image32.png) + +不過,相比簡單的 HTML 文件,React 應用依賴更復雜的構建工具和項目結構,因此部署過程也會稍微麻煩一些。一個典型的問題體現在端口設置上:默認情況下,React 應用一般會監聽 3000 端口(你也可以在配置文件或啟動日誌中看到這一點)。 + +然而,在 Zeabur 上這樣部署會失敗——因為 Zeabur 只支持監聽 8080 端口的應用。也就是說,如果想讓 React 應用在 Zeabur 上正常運行,我們必須先把默認監聽端口從 3000 改成 8080。 + +要正確進行這一步配置,我們需要先弄清楚兩個概念:什麼是"端口(Port)",以及"監聽端口(Listening Port)"是什麼意思。 + +#### 什麼是端口? + +> 在計算機網路中,端口可以理解為一個"邏輯通信端點",用來區分同一臺設備上運行的不同網路服務。簡單類比的話,如果 IP 地址好比一個"門牌號"(例如 162.128.1.1),那端口號就像這棟樓裡不同房間的"房間號"——每個房間對應一個服務(例如 Web 服務器、郵箱服務,或者你的 React 應用)。 +> +> 端口號用 16 位整型表示,取值範圍是 0 到 65535。 + +如果不想記這些細節,可以簡單理解:端口是構成"網路訪問地址"的一個必要部分。 + +我們平時訪問網站或 IP 地址時,通常不會手動加端口號,是因為 Web 的默認端口是 80 或 443(HTTPS)。大多數瀏覽器會自動使用這些標準端口。而對於一些特殊端口,比如 React 默認的 3000、Zeabur 要求的 8080,我們就必須在地址後面加上 `:3000` 或 `:8080` 才能訪問到對應的內容。 + +#### 什麼是"監聽端口號"? + +> "監聽端口號"指的是某個程序在一臺設備上主動"打開並監控"的端口。當一個應用設置了監聽端口時,其實就是在告訴操作系統:"我會一直在這個端口上等待網路請求——只要有請求進來,就請轉發給我。" + +再形象一點地理解:假設你的電腦是一棟寫字樓,IP 地址是這棟樓的地址。樓裡開了很多公司或部門,它們分別佔用不同的房間,房間號就是端口號。 + +當默認的 React 開發服務器啟動時,它會"打開"某個房間的門,並安排"前臺"在門口值班,這個房間號就是它的監聽端口——3000。 + +同時,React 程序還會告訴這棟樓的"物業管理"(操作系統):"我在 3000 號房間,請把所有寄給 3000 的信件(網路請求)都轉給我。" + +這樣,當你訪問 React 網站時,請求首先會到達這棟樓;物業看到請求要送到 3000 號房間,就會立刻把請求交給 React 的"前臺",由它來處理並返回結果——這就是訪問 React 應用的過程。 + +當你在本地執行 `npm start`(本地啟動 React 開發服務器的默認命令,也可以在 Vibe Coding 的 Agent 側邊欄中執行)時,React 開發服務器就會自動把監聽端口設置為 3000。 +而 Zeabur 的平臺設計決定了它只會"識別"監聽 8080 端口的應用。如果你的 React 應用仍然使用默認的 3000 端口,Zeabur 就無法將請求正確轉發給你的應用,最終導致部署失敗。 + +#### 修改默認監聽端口 + +要把 React 默認監聽端口(3000)改成 Zeabur 所要求的 8080,有很多做法。最簡單的方式,就是直接在 Trae 裡對 Agent 下指令:"請幫我把這個 React 項目的默認端口改為 8080。"Trae 就會幫你修改項目中對應的配置文件。修改完成後,你只需重新打包並按前面的方式上傳到 Zeabur 即可。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image33.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image34.png) + +在網路設置中指定一個訪問 URL,方式和部署 HTML 項目時基本相同,就可以啟動 React 版本的服務。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image35.png) + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image36.png) + +對於其它需要修改端口號的程序,你也可以採用同樣的思路:先改默認端口,再上傳到 Zeabur 部署。至此,你已經掌握了將常見 Web 應用部署到服務器的基礎技能。 + +你可以嘗試讓 Trae 幫你構建不同類型的應用,並把它們部署到 Zeabur 的默認服務器上。在後續課程中,我們還會學習如何把應用部署到你自己購買的雲服務器上。 + +--- + +# ⚠️ 如何停止和刪除項目(Zeabur) + +由於啟用服務器相關資源都會產生費用,我們在使用時一定要養成"及時關閉不用服務"的習慣,避免把每個月的免費額度消耗完。 + +如果要找到項目的管理入口,首先點擊項目中的 "Settings" 選項。 + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image21.png) + +進入設置頁面後,將頁面拉到最下方,你會看到類似下面的界面: + +![](/zh-cn/stage-2/backend/zeabur-deployment/images/image22.png) + +你可以點擊 "Suspend All Services" 來暫停所有服務以降低費用;如果服務出現問題,可以點擊 "Restart All Services" 對全部服務進行重啟。如果你確定不再需要這個項目,可以點擊 "Delete Project" 將整個項目徹底刪除。 + +--- + +# 總結 + +在本教程中,我們介紹了四個常用的 Web 應用部署平臺: + +1. **騰訊雲 CloudBase**:適合國內用戶,訪問速度快,與微信生態整合好 +2. **Vercel**:適合現代前端框架項目,與 GitHub 集成緊密,全球 CDN 加速 +3. **Netlify**:功能全面,支持表單處理和身份驗證,適合需要高級功能的靜態網站 +4. **Zeabur**:適合複雜項目,服務模板豐富,支持多種部署方式 + +選擇哪個平臺取決於你的具體需求: +- 如果主要面向國內用戶,推薦 **CloudBase** +- 如果使用 React/Next.js 等框架,推薦 **Vercel** 或 **Netlify** +- 如果需要表單處理、身份驗證等高級功能,推薦 **Netlify** +- 如果需要部署 Dify、n8n 等服務,推薦 **Zeabur** + +無論選擇哪個平臺,部署的核心流程都是相似的:準備程式碼 → 選擇平臺 → 配置構建設置 → 部署上線。掌握這些技能後,你就可以將自己開發的應用分享給全世界了! diff --git a/docs/zh-tw/stage-2/frontend/design-to-code/index.md b/docs/zh-tw/stage-2/frontend/design-to-code/index.md new file mode 100644 index 0000000..c458416 --- /dev/null +++ b/docs/zh-tw/stage-2/frontend/design-to-code/index.md @@ -0,0 +1,361 @@ +# 從設計原型到項目程式碼 + +::: tip 🎯 核心問題 +**如何將設計工具中的原型轉化為真正能在瀏覽器裡運行的前端程式碼?** +::: + +--- + +## 1. 從原型到程式碼的三種路徑 + +在使用 Figma、MasterGo 等現代前端設計工具完成界面設計後,一個很實際的問題自然會浮現:這些看起來結構完整的設計稿,要怎麼轉化成真正能在瀏覽器裡運行的前端程式碼? + +一般而言,從原型到程式碼的落地,本質上有三種典型路徑: + +| 路徑 | 方法 | 特點 | 適用場景 | +|------|------|------|----------| +| **路徑一** | 根據圖片,使用多模態大模型直接還原出程式碼 | 靈活、無需特定工具 | 快速原型驗證、簡單頁面 | +| **路徑二** | 通過平臺自身能力或插件導出可用程式碼 | 還原度高、可編輯性強 | Figma/MasterGo 用戶 | +| **路徑三** | 平臺結合 MCP 能力導出可用程式碼 | 自動化程度高、可定製 | 需要深度集成的工作流 | + +本文將詳細介紹這三種路徑的具體實現方法,幫助你根據項目需求選擇最合適的工作流。 + +::: tip 📚 前置知識 +在開始本節之前,建議你先學習 [Figma 與 MasterGo 入門](../figma-mastergo/) 教程,掌握前端設計工具的基礎操作。 +::: + +--- + +## 2. 路徑一:多模態 AI 直接還原程式碼 + +擁有視覺能力的大模型天生具備將圖片轉為程式碼的能力。我們只需要將設計稿截圖直接導入對話框,隨後讓大模型生成完整的結果程式碼。 + +### 2.1 操作流程 + +1. **截取設計稿圖片** + - 在 Figma 或 MasterGo 中,將設計好的頁面導出為 PNG 或 JPG + - 確保截圖包含完整的頁面佈局 + +2. **選擇多模態 AI 模型** + - 可以使用 Gemini、Qwen、Claude 等支持圖像輸入的模型 + - 這裡以 Gemini 為例進行演示 + +3. **編寫提示詞** + ``` + 請根據這張設計圖生成對應的 HTML/CSS 程式碼。 + 要求: + - 使用現代 CSS 佈局(Flexbox/Grid) + - 響應式設計,適配不同屏幕尺寸 + - 包含所有可見的 UI 元素 + - 顏色、字體大小盡量還原設計稿 + ``` + +![](/zh-cn/stage-2/frontend/design-to-code/images/image42.png) + +4. **獲取並保存程式碼** + - 要求模型返回完整的 HTML 程式碼 + - 保存為單個 `.html` 文件,方便本地測試 + - 後續可以在本地 IDE 中將其轉換為 React 等框架 + +### 2.2 常見問題與解決方案 + +生成頁面並非簡單的任務,在具體過程中你可能會遇到很多問題: + +| 問題 | 解決方案 | +|------|----------| +| 界面排布不均 | 向 AI 描述具體的佈局問題,要求調整 CSS 的 margin/padding | +| 界面顯示不全 | 檢查是否設置了正確的 viewport,要求添加響應式斷點 | +| 顏色還原不準 | 使用取色工具獲取設計稿的精確色值,提供給 AI | +| 字體不匹配 | 指定具體的字體名稱或要求使用 Google Fonts 替代 | + +::: tip 💡 小技巧 +推薦先生成 HTML 程式碼,獲取後再使用本地 IDE 將其轉換為 React 框架。這樣可以獲得多個獨立的 HTML 文件,統一進行框架轉換。 +::: + +### 2.3 MasterGo AI 生成頁面 + +MasterGo 同樣提供了強大的 AI 頁面生成功能,可以根據參考圖直接生成可用的網頁程式碼。 + +#### 找到 AI 功能入口 + +在 MasterGo 編輯界面的上方工具欄中,可以找到 AI 工具按鈕: + +![](/zh-cn/stage-2/frontend/design-to-code/images/image47.png) + +#### 生成流程 + +1. **上傳參考圖** + - 使用與多模態 AI 相同的方式上傳設計參考圖 + - 添加文字描述需求 + +2. **查看生成結果** + +![](/zh-cn/stage-2/frontend/design-to-code/images/image48.png) + +![](/zh-cn/stage-2/frontend/design-to-code/images/image49.png) + +3. **獲取程式碼** + - 點擊藍色按鈕"插入到畫布",可直接編輯生成後的網頁 + - 或點擊右側的"程式碼"按鈕,複製程式碼內容到本地 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image50.png) + +--- + +## 3. 路徑二:平臺自身能力或插件導出程式碼 + +### 3.1 Figma Make 生成程式碼 + +Figma Make 是 Figma 官方推出的 AI 設計工具,能夠根據用戶輸入的提示詞或者參考圖,高精度地還原網頁原型 UI 界面。 + +#### 功能特點 + +- **高精度還原**:相比原生 AI 生成程式碼,效果更佳 +- **可編輯性**:生成結果可以轉換為可編輯的 Figma Design 文件 +- **GitHub 集成**:支持直接將程式碼同步到 GitHub + +::: tip 🔑 權限說明 +使用 Figma Make 的完整功能需要 Pro 用戶權限,學生可以通過教育認證免費獲得 Pro 權限。 +::: + +#### 操作步驟 + +1. **進入 Figma Make** + - 在 Figma 首頁點擊 Make 按鈕 + - 或者訪問 [Figma Make](https://www.figma.com/make) + +2. **上傳參考圖** + - 將你想要還原的設計圖上傳到對話框 + - 添加描述需求的提示詞 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image43.png) + +3. **查看生成結果** + - 稍等片刻後即可看到渲染結果 + - 點擊右上角的播放按鈕可進行全屏預覽 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image44.png) + +4. **細節調整** + - 點擊右上角的編輯器圖標(鼠標和尺子圖標) + - 回到熟悉的 Figma Editor 界面進行詳細調整 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image45.png) + +5. **導出程式碼** + - 調整滿意後,選擇導出程式碼 + - 可以直接連接到 GitHub 保存程式碼 + +![](/zh-cn/stage-2/frontend/design-to-code/images/image46.png) + +### 3.2 插件導出程式碼 + +除了平臺原生的 AI 功能,Figma 和 MasterGo 都支持通過插件導出程式碼: + +**常用 Figma 插件:** +- **Figma to Code**:將設計稿轉換為 React、Vue、HTML 等程式碼 +- **Anima**:高保真程式碼生成,支持交互效果 +- **Locofy**:AI 驅動的設計轉程式碼工具 + +**使用步驟:** +1. 在 Figma 中打開插件面板(Plugins) +2. 搜索並安裝需要的程式碼導出插件 +3. 選中要導出的設計元素 +4. 運行插件,選擇目標框架和程式碼格式 +5. 複製或下載生成的程式碼 + +--- + +## 4. 路徑三:平臺結合 MCP 能力導出程式碼 + +### 4.1 什麼是 MCP? + +MCP(Model Context Protocol,模型上下文協議)是一套開放標準協議,它允許 AI 模型安全、可控地訪問外部工具和資料源。在前端設計工具的場景中,MCP 讓大模型能夠直接讀取設計文件的結構、樣式和組件資訊,從而更精準地生成程式碼。 + +### 4.2 MCP 的工作原理 + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ AI 模型 │ ←→ │ MCP 服務器 │ ←→ │ 設計工具 │ +│ (Claude等) │ │ (協議適配) │ │(Figma/MasterGo)│ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +**工作流程:** +1. AI 模型通過 MCP 協議向設計工具發送請求 +2. 設計工具返回結構化的設計資料(圖層、樣式、組件等) +3. AI 模型理解設計結構並生成對應程式碼 +4. 程式碼可以直接導出或同步到開發環境 + +### 4.3 Figma + MCP 實戰 + +#### 環境準備 + +1. **安裝 MCP 服務器** + ```bash + # 使用 npx 安裝 Figma MCP 服務器 + npx figma-mcp-server + ``` + +2. **配置 Claude Desktop 或其他支持 MCP 的 AI 工具** + ```json + { + "mcpServers": { + "figma": { + "command": "npx", + "args": ["figma-mcp-server"], + "env": { + "FIGMA_ACCESS_TOKEN": "your-figma-token" + } + } + } + } + ``` + +3. **獲取 Figma Access Token** + - 登錄 Figma → Settings → Personal Access Tokens + - 生成新的 Token 並保存 + +#### 使用流程 + +1. **在 AI 工具中啟用 MCP 連接** + - 打開 Claude Code 或其他支持 MCP 的 IDE + - 確認 MCP 服務器已連接 + +2. **提供設計文件鏈接** + ``` + 用戶:請幫我將這個 Figma 設計轉換為 React 程式碼 + 鏈接:https://www.figma.com/file/xxxxx + + AI:我已通過 MCP 連接到 Figma,正在讀取設計文件結構... + ``` + +3. **AI 自動分析並生成程式碼** + - MCP 服務器獲取設計文件的圖層樹 + - AI 理解組件結構和樣式屬性 + - 生成帶有正確命名和結構的 React/Vue 組件 + +4. **迭代優化** + ``` + 用戶:請將按鈕組件提取為獨立的可複用組件 + + AI:好的,我已通過 MCP 識別到設計系統中的 Button 組件, + 正在生成帶有 props 接口的 React 組件... + ``` + +### 4.4 MCP 的優勢 + +| 特性 | 傳統方式 | MCP 方式 | +|------|----------|----------| +| **資料精度** | 依賴截圖,可能丟失細節 | 直接讀取原始設計資料 | +| **組件識別** | AI 需要猜測組件邊界 | 精確獲取組件定義 | +| **樣式還原** | 基於像素估算 | 獲取精確的設計 token | +| **迭代效率** | 每次修改需重新截圖 | 實時同步設計變更 | +| **自動化程度** | 手動複製粘貼 | 可直接寫入項目文件 | + +### 4.5 當前可用的 MCP 工具 + +**設計工具 MCP:** +- **Figma MCP Server**:官方支持的 MCP 實現 +- **MasterGo MCP**:社區開發的 MasterGo 適配器 + +**開發環境 MCP:** +- **Claude Code**:原生支持 MCP 協議 +- **Cline**:VS Code 插件,支持 MCP 連接 +- **Trae**:可通過配置啟用 MCP 功能 + +::: tip 🔮 未來展望 +MCP 協議正在快速發展,未來設計工具與開發環境的集成將更加緊密。預計會出現更多一鍵同步設計到程式碼的解決方案,進一步縮短設計與開發之間的距離。 +::: + +--- + +## 5. 程式碼導出後的工作 + +### 5.1 本地測試 + +獲取程式碼後,在本地 IDE 中打開並進行測試: + +1. **創建新項目** + ```bash + # 如果是 HTML 文件,直接用瀏覽器打開 + open index.html + + # 如果是 React/Vue 項目 + npm install + npm run dev + ``` + +2. **與 AI IDE 協作** + - 將生成的程式碼導入 Trae 或其他 AI IDE + - 讓 AI 幫助修復佈局問題、添加交互功能 + +### 5.2 常見問題處理 + +| 階段 | 問題 | 解決方案 | +|------|------|----------| +| 佈局 | 元素錯位 | 檢查 CSS 的 display 和 position 屬性 | +| 樣式 | 顏色不一致 | 使用瀏覽器開發者工具檢查實際應用的色值 | +| 響應式 | 移動端顯示異常 | 添加 media query 斷點 | +| 交互 | 按鈕無響應 | 檢查 JavaScript 事件綁定 | + +--- + +## 6. 三種路徑對比與選擇建議 + +### 6.1 路徑對比 + +| 維度 | 路徑一:多模態 AI | 路徑二:平臺能力 | 路徑三:MCP | +|------|------------------|------------------|-------------| +| **上手難度** | ⭐ 簡單 | ⭐⭐ 中等 | ⭐⭐⭐ 較複雜 | +| **還原精度** | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐ 高 | ⭐⭐⭐⭐⭐ 最高 | +| **靈活性** | ⭐⭐⭐⭐⭐ 高 | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐ 較高 | +| **自動化程度** | ⭐⭐ 低 | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐⭐ 高 | +| **成本** | 低(按 API 調用) | 中(可能需要 Pro) | 低(開源工具) | + +### 6.2 選擇建議 + +**選擇路徑一(多模態 AI)如果:** +- 需要快速驗證想法 +- 設計工具不固定,經常切換 +- 對還原精度要求不高 +- 預算有限 + +**選擇路徑二(平臺能力)如果:** +- 團隊主要使用 Figma 或 MasterGo +- 需要高精度的程式碼還原 +- 設計師和開發者需要頻繁協作 +- 願意投資 Pro 版本 + +**選擇路徑三(MCP)如果:** +- 追求最高程度的自動化 +- 有技術能力配置 MCP 環境 +- 項目需要頻繁迭代設計到程式碼 +- 希望建立標準化的設計開發工作流 + +--- + +## 7. 總結 + +通過本章節的學習,你已經掌握了從設計原型到程式碼的三種核心路徑: + +1. **多模態 AI 直接轉換**:靈活快速,適合原型驗證 +2. **平臺原生能力**:還原度高,適合專業設計工作流 +3. **MCP 協議集成**:自動化程度最高,代表未來趨勢 + +::: tip 💡 最佳實踐 +- **新手推薦**:從路徑一(多模態 AI)開始,快速上手 +- **團隊協作**:使用路徑二(平臺能力),保證設計一致性 +- **效率優先**:嘗試路徑三(MCP),建立自動化工作流 +- **混合使用**:根據項目階段靈活切換不同路徑 +::: + +--- + +## 參考資源 + +- [Figma 與 MasterGo 入門](../figma-mastergo/) - 學習設計工具基礎 +- [一起做霍格沃茨畫像](../hogwarts-portraits/) - 完整項目實戰 +- [MCP 官方文檔](https://modelcontextprotocol.io/) - 瞭解協議詳情 +- [Figma Make 官方文檔](https://help.figma.com/hc/en-us/sections/360007453634-Figma-Make) +- [MasterGo AI 教程](https://mastergo.com/tutorials) diff --git a/docs/zh-tw/stage-2/frontend/figma-mastergo/index.md b/docs/zh-tw/stage-2/frontend/figma-mastergo/index.md new file mode 100644 index 0000000..5f28d2f --- /dev/null +++ b/docs/zh-tw/stage-2/frontend/figma-mastergo/index.md @@ -0,0 +1,303 @@ +# Figma 與 MasterGo 入門 + + + +::: tip 🎯 核心問題 +**如何從零開始使用現代設計工具創建網頁原型?** +::: + +--- + +## 1. 為什麼要學前端設計工具? + +在開始之前,我們需要理解一個問題:為什麼需要學"前端設計工具"?反正直接寫 HTML / CSS 程式碼也能把頁面搭出來,多學一個軟體和技術,真的有必要嗎? + +實際上,把頁面運行起來,和把產品設計好根本是兩個概念。程式碼只關注解決如何渲染在瀏覽器上,如何在不同設備上運行的問題;前端設計工具解決的是資訊分佈的問題,前端交互怎麼安排,不同頁面怎麼跳轉,視覺優先級怎麼分配的問題。只需要在設計工具裡搭一塊畫布,就能把版式、資訊層級、交互方式在一塊屏幕上對比確定,選擇最適當的呈現效果。 + +如果直接開始寫程式碼或直接用 AI 生成完整的前端頁面,通常用戶體驗都不會太好,嚴謹的產品會考慮到用戶和前端交互的舒適度,以及不同頁面想要傳達的內容分佈,從用戶的角度出發先進行前端頁面排布,再進行程式碼轉換或生成。 + +另外,從團隊協作的角度而言,前端設計工具還降低了多方的合作成本:設計師、產品、開發不再各自對著腦補畫面或者抽象的程式碼說明,而是支持多人協同,大家能夠圍繞一份可視、可標註、可迭代的畫布討論版本管理、需求變更、反饋意見。更進一步的是,現代前端設計工具本身不再只是畫圖軟體,一鍵生成部分程式碼,管理設計系統和組件庫,新時代的設計工具已能夠將大量重複性的體力勞動(對齊、標註、導出、改樣式)自動化或批量化,極大促進了頁面設計的開發效率。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image8.png) + +### 1.1 前端設計工具的演變 + +在時間的長河中,所謂前端設計工具其實是一條持續演化的技術。從 90 年代以本地位圖編輯為主的 Photoshop 時代,到 2010 年前後 Sketch 帶來的矢量化、組件化工作流,再到 2016 年之後 Figma 把協作徹底搬上雲端,設計團隊從單兵作戰逐漸走向多人實時協同。來到 2025 年,AI 已經實打實地嵌入到這些工具內部:從"根據一句話生成頁面草稿",到"把設計稿直接轉成可運行的前端結構","設計即程式碼""人機共創"正在從概念變成可用的生產力。 + +本節中,我們會選取最具代表的兩種現代前端設計工具進行介紹,Figma 和 MasterGo。一方面,它們都覆蓋了現代 UI/UX 所需要的核心能力(矢量編輯、組件系統、自動佈局、程式碼交付等),可以支撐你完成從線框到高保真到開發交接的完整閉環;另一方面,這兩款工具都已經在 2025 年之後陸續加入了實用的 AI 功能,幫助你在保證原型不變的同時將設計圖變成真正可運行的程序。 + +## 1.2 誕生之旅 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image9.png) + +在現代前端專用工具尚未誕生的年代,整個界面設計行業的視覺設計工作,很長一段時間都由 Photoshop 這類 "全能型" 設計軟體順帶承包。設計師會在本地通過一層層疊加的圖層,細緻完成頁面整體視覺效果的設計,最終將體積不小的 .psd 源文件交付給前端工程師 —— 而前端要精準還原設計圖,還必須手動完成三項繁瑣且關鍵的工作: + +一是 "切圖":需要從 .psd 文件的多層結構裡,把按鈕、圖標、Logo、背景模塊等獨立視覺元素逐一拆分提取,再導出為 PNG、JPG 等網頁能直接加載的圖片格式(畢竟網頁無法直接識別 PSD 的圖層資訊,只能依賴這些拆分後的圖片呈現細節); + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image10.png) + +二是 "量尺寸":得用軟體自帶的測量工具,逐一確認每個元素的寬高、不同模塊間的間距(margin/padding)等資料,確保所有尺寸都精準到像素; + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image11.png) + +三是 "摳標註":要從設計圖中提取那些 "看不見卻必須有的" 隱性參數 —— 比如文字的字號、字重、行距,每個色塊的 RGB 或 HEX 色值等,相當於把設計師沒寫在紙上的 "設計規格" 手動 "摳" 出來記錄。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image12.png) + +在此之後,前端的實現階段才真正展開。無論使用的是原生 HTML/CSS/JS,還是基於 Vue、React 等框架,本質過程是一致的。前端會以 "容器為核心載體",根據設計中各模塊的層級與語義重建頁面結構。這裡的容器是指具有明確佈局邊界、專門承載和組織子元素的單元,它不直接呈現具體內容,卻通過 Flex、Grid 等規則,為內部元素劃定排列範圍。而 "結構塊"(如頂部導航欄、側邊欄、文章列表區、底部頁腳等肉眼可辨的功能 / 內容區域),便依託容器存在;每個結構塊內部,又會嵌套更小的容器來組織元素,比如一條文章列表項,會由 "列表項容器" 控制內邊距與整體排版,再包裹標題、摘要、時間、封面圖標等細節元素。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image13.png) + +在現代前端框架裡,這些 "結構塊(及關聯的容器與元素)" 通常會被實現為 "組件"。組件可簡單理解為:帶有清晰邊界、整合了容器佈局與邏輯的可複用界面單元,它既包含控制外觀與排列的容器(比如 "按鈕組件" 用容器定義寬高、圓角,"文章卡片組件" 用容器組織標題、封面的位置),也封裝了交互邏輯。設計稿中重複出現、形態一致的部分(如統一風格的按鈕、反覆使用的文章卡片),在程式碼中會被抽象成組件:既能在不同頁面 / 場景複用,減少重複開發,也能通過組件內容器的統一規則,確保所有複用處的佈局與風格高度一致 + +隨後,前端會使用樣式系統還原視覺和佈局。切圖階段導出的 PNG/JPG 等資源,會作為組件或結構塊內部的 ``、背景圖片,或者按照各框架推薦的靜態資源方式引入;量尺寸階段得到的寬高、間距、行高等具體數值,會被轉寫為 `width`、`height`、`margin`、`padding`、`line-height` 等樣式屬性,應用到對應的組件或結構塊上;摳標註階段整理出的顏色、字體、陰影、圓角以及 hover/active 等狀態,則會落實到 CSS、CSS Modules、CSS-in-JS、Tailwind 等具體方案中的 `color`、`font-family`、`font-size`、`box-shadow`、`border-radius` 以及偽類或狀態類名上。此時,切圖、尺寸和標註提供的是一組精確的視覺參數,組件和結構塊則提供了承載這些參數的程式碼組織單元,兩者結合起來,構成可維護、可複用的界面實現。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image14.png) + +但是,以本地文件為中心的模式天然是低效率的。版本通過郵件和網盤傳輸,新舊稿件容易混淆,設計和開發之間大量依賴上述的複雜交互方法,協作成本和出錯概率都不低。 + +移動互聯網興起後界面複雜度和迭代速度需求快速上升,Photoshop 的"大而全"逐漸顯得笨重。這個階段,出現了 Sketch。Sketch 專注在 UI 設計本身,剝離掉大部分與視覺後期處理相關的負擔;用 Symbols 把按鈕、導航、輸入框等高複用元素組件化,一處修改可以全局同步;再配合 Zeplin 一類工具,把標註和樣式片段自動生成。Sketch 把"組件思維"引入了設計工作流。不過它依然是基於本地文件的桌面應用,實時協作要靠雲盤、第三方插件或版本工具繞行實現,沒有從底層解決"多個人同時改同一份稿子"的問題。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image15.png) + +真正改變遊戲規則的是 Figma。自 2016 年起,它把 UI 設計、原型製作、評論協作統一整合到瀏覽器中,支持多種現代功能:多人實時光標、在線評論、版本時間線、分享鏈接等,今天看起來非常簡單,但在當時是對 Photoshop / Sketch 模式的正面挑戰。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image16.png) + +至此,界面設計不再是散落在各自電腦裡的文件,而是集中在一份在線、實時更新的雲端畫布上。圍繞這塊畫布,我們可以想象更進一步,用自動化或 AI 的方式模糊設計和前端程式碼的邊界。 + +最開始,我們僅能依賴各類平臺插件,將設計稿中的組件、樣式資訊半自動導出為程式碼片段(如 React/Vue 組件骨架、CSS 變量等),其核心本質是通過插件實現結構化資訊提取。隨後,隨著平臺能力的進化,大部分設計平臺開始支持大模型 MCP(Model Context Protocol,模型上下文協議)功能:該協議提供了一套標準機制,能讓大模型安全、可控地訪問設計文件、插件接口與項目元資料,進而更便捷地將設計稿導出為程式碼。 + +再往後,在插件與 MCP 的基礎上,前端程式碼自動化進一步邁入到原生支持從設計稿直接推導程式碼結構的階段。我們可在設計工具內一鍵生成前端項目骨架、組件層次、樣式體系及對應的程式碼結果。這使得設計師與前端開發工程師得以從手動搬運設計細節的工作中解放出來,將更多精力投入到用戶體驗優化與功能版本的更新迭代上。 + +--- + +## 2. Figma 入門 + +接下來我們從抽象的概念部分來到實際的操作環節。由於時間關係,我們只會學習 Figma 的基本操作邏輯,確保即便你完全沒用過設計工具,也能跟著完成練習。如果你想進行完整的 Figma 功能學習,請你參考 Figma 提供的詳細官方教程進行學習:https://help.figma.com/hc/en-us/sections/30880632542743-Figma-Design-for-beginners + +或者參考如下教程,進行類似個人作品集簡單網頁的快速搭建:https://help.figma.com/hc/en-us/sections/35895585621655-Figma-Sites-collectio + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image17.png) + +左側是項目的新建和資源管理入口,右上角的幾個按鈕是 Figma 的常見功能。其中,Make 用來用一句話讓 AI 幫你先生成一個大概的界面或結構草稿,Design 是真正畫網頁 / App 界面、搭組件和做原型的主工作區,FigJam 像團隊白板,用來貼便利貼、畫流程和做前期討論,Buzz 是品牌資產規模化生產工具,用於批量生成內容以保持品牌一致性,Site 則是把這些設計整理成真正可訪問的網頁或文檔站對外展示。 + +乍一看 Figma 的功能非常多,不好入門,但其實這類功能工具本質上都是熟能生巧,不需要害怕一開始操作出錯,也不用想著一步做對,只需要先玩起來,玩多了自然能快速上手。 + +本篇教程中,為了快速入門,我們會對 Design 功能做簡單講解。 + +### 2.1 新建 Design 文件 + +在首頁或者右上角的入口裡,選擇 **Design** ,新建一個文件,你會進入一個空白的設計畫布。 +這個界面大致分成三塊:左邊是頁面和圖層,用來查看和修改頁面、元素從屬關係;中間是畫布,用於查看當前效果;右邊是屬性和樣式,用於修改具體的形狀、顏色、樣式;底部一條是工具欄,用來切換工具,包含選框、畫形狀、輸入文字、評論、插件等,選中工具後,可以按 Esc 鍵返回至默認鼠標工具。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image18.png) + +### 2.2 創建你的第一個 Frame(畫板) + +在正式放置元素之前,需要先為頁面確定一個清晰的邊界,這個邊界由 Frame 來承擔。你可以在底部工具欄中選擇 Frame 工具,或者直接按鍵盤 F,然後在畫布上拖出一個矩形區域。 + +1. 使用底部工具欄裡的 Frame 工具,或者直接按鍵盤 `F`。 +2. 在畫布中拖出一個矩形區域,右側屬性欄裡把寬度改成比如 `1440`,高度改成 `900`。 +3. 在左側圖層欄,把這個 Frame 重命名,比如叫 `My First Page` 或者你項目的名字。 + +這個 Frame 就是一屏界面的頁面容器,之後的標題、文字、按鈕、圖片等內容都應該放在這個 Frame 內部,而不是散落在畫布的任意位置。以 Frame 為邊界來組織內容,有助於在後續進行滾動設置、適配不同設備尺寸、導出畫面及製作原型時,保持結構可控。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image19.png) + +### 2.3 在 Frame 裡放文字和簡單元素 + +有了容器,接下來我們來學習如何放置最基本的組件,例如:標題、副標題、按鈕、佔位圖塊。 + +1. 選擇文字工具(底部工具欄中的 `T`),在 Frame 裡點擊一下,輸入頁面標題,比如:`My Portfolio`。 + 在右側屬性裡,把字體大小調大一點(例如 96),字重調粗一點。 +2. 在標題下面,再用文字工具輸入一行簡單說明,比如一兩句描述這個頁面要做什麼。 + 字號可以小一些,行高略放大一點,讀起來不那麼擠。 +3. 畫一個按鈕雛形: + 用矩形工具在標題下面畫一個大概 `200 × 48` 的矩形,右側給它一個比較明顯的填充顏色,再適當加一點圓角。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image20.png) +4. 然後用文字工具在矩形上方輸入按鈕文字,比如 `Get Started`,把矩形和文字一併選中,用頂部的對齊工具讓文字水平、垂直都居中。 +5. 在按鈕一側或下方,再畫一個較大的淺灰色矩形作為"圖片佔位區",後面可以用來放展示圖片。 + +做到這裡,其實你已經有了一個非常簡陋但結構完整的"首頁草稿":一個標題、一段話、一個按鈕、一個主要展示區域。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image21.png) + +### 2.4 善用 Auto Layout 整合元素 + +如果所有元素只是隨手拖拽,頁面很快會亂。Figma 裡一個很重要的概念就是 **Auto Layout** ,它可以把一組元素變成一個帶規則的容器。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image22.png) + +你可以選中"主標題 + 副標題 + 按鈕"這三樣,在右側屬性欄裡點擊 **Add Auto layout** 。 + +這時這三樣會被包在一個容器裡,你可以在右側調整參數,其中的元素佈局會根據參數自動適應調整: + +- 它們是豎著排還是橫著排。 +- 元素之間的間距是多少。 +- 整個這一塊離容器邊緣有多少內邊距(padding)。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image23.png) + +同樣,按鈕內部也可以用 Auto Layout,我們能夠實現這樣的一個效果:當我調整了文字,按鈕的長度也會自動調整。 + +先把按鈕背景的矩形和按鈕文字選中,添加 Auto Layout,讓這兩個東西變成一個"按鈕容器"。接著選中這個按鈕容器,把寬高都設置成 **Hug contents** 。這樣一來,文字會一直保持在按鈕正中間,文字多一點、少一點,按鈕的寬度都會自動跟著變化。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image24.png) + +### 2.5 將按鈕變為可複用組件 + +現在我們要學習一個新的概念,組件。組件的意思就是可以被反覆利用的元素,比如按鈕這種元素,只要你預感之後還會反覆用到,就可以考慮把它做成組件。我們在剛才已經加好 Auto Layout 的按鈕基礎操作: + +1. 選中整個按鈕容器。 +2. 右鍵選擇 Create component(創建組件)。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image25.png) + +這樣,這個按鈕就從一組普通圖層,變成了一個組件母版。之後如果你在其他頁面或 Frame 裡需要同樣風格的按鈕,可以直接從左側的 Assets 面板裡拖出來使用。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image26.png) + +此時所有用到的按鈕,都是這個母版的同步拷貝。當你修改母版的顏色、圓角或間距時,所有實例都會自動保持同步更新。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image27.png) + +至此,你已經初步掌握了 Figma 的簡單用法。你不需要一開始就把所有功能都弄懂,只要先照著做出第一個簡單頁面,熟悉這幾個核心操作,再慢慢去探索官方教程裡的更多能力,隨著使用次數增多就一定能上手。 + +--- + +## 3. MasterGo 入門 + +在理解了 Figma 的基礎工作流程之後,我們再來看 MasterGo,你可以把 MasterGo 簡單看做是中國版的 Figma,但在部分功能上有一定區別。整體上,它延續了與 Figma 相似的界面佈局和操作理念:同樣有畫布、圖層樹和屬性面板,同樣支持組件、樣式、自動佈局和多人協作。更詳細的內容可參考 MasterGO 的官方教程:https://mastergo.com/tutorials/12?%E5%85%A8%E7%A8%8B%E9%AB%98%E8%83%BD%EF%BC%8CMasterGo%20%E6%9C%80%E5%AE%8C%E6%95%B4%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%EF%BC%8C%E8%AE%A9%E4%BD%A0%E4%BB%8E%E9%9B%B6%E5%88%B0%E7%B2%BE%E9%80%9A%EF%BC%81 + +### 3.1 新建設計文件 + +1. **進入 MasterGo 後臺** + 1. 打開 MasterGo 官網並登錄賬號。 + 2. 進入後,你會看到類似「文件列表 / 項目列表」的首頁區域,用來管理你的設計文件。 + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image28.png) + +2. **創建新文件** + 1. 在右上角看到 + 設計文件的按鈕選項進行點擊,或者選擇導入 Figma 等文件。 + 2. 點擊後,你會進入一個空白畫布,這就是 MasterGo 的設計工作區。 + +3. **認識基本界面區塊** + 當你學會使用 Figma 後,MasterGo 的使用方式大同小異,主要分為幾個區域: + + ![](/zh-cn/stage-2/frontend/figma-mastergo/images/image29.png) + 1. 頂部工具欄:位於畫布最上方,左側是文件位置和文件名,中間是一排常用工具按鈕(選擇、區域/畫板、形狀、文本、註釋、評論、插件選擇和 AI 工具等),右側是當前在線成員、分享入口以及畫布縮放和預覽控制功能入口。 + 2. 左側面板:主要分為圖層和資源,當前停留在圖層標籤,可看到頁面列表,以及該頁面下所有圖層的結構和層級。 + 3. 中間畫布區:具體繪製和排版的工作區,所有 Frame、組件和圖形都會展示在這裡。 + 4. 右側屬性面板:用於查看和編輯選中對象的屬性,例如大小、位置、對齊方式、背景填充、描邊、圓角等。如果沒有選中任何對象,會顯示畫布相關設置,如畫布背景色、標籤和導出選項。 + +### 3.2 創建你的第一個 Frame + +在正式放東西之前,我們需要一個頁面容器用來確定界面的邊界和尺寸。這個容器在 MasterGo 裡,通常叫 Frame。 + +**步驟:** + +1. **選擇 Frame 工具** + 1. 在工具欄中找到 Frame / 畫板工具,點擊後可使用預設參數直接將內容創建到畫板。 + 2. 或者使用快捷鍵(通常是 `F`,如果有差異以實際界面為準)。 +2. **在畫布中拖出一個矩形區域** + 1. 拖出後,你會看到一個帶選中框的區域。 + 2. 右側屬性面板裡,可以看到這個 Frame 的寬度和高度。 + 3. 把寬度改成比如 `1440`,高度改成 `900`(一屏網頁常用尺寸之一)。 +3. **重命名 Frame** + 1. 在左側圖層面板裡找到這個 Frame。 + 2. 雙擊名稱,把它改成你項目的名字,比如:`My First Page`,或者你自己隨便起的頁面名。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image30.png) + +### 3.3 創建畫板內容 + +有了容器,使用與 Figma 中我們已教過的類似方式,很容易可以得到相似的展示頁面。(你可以嘗試複製 Figma 畫板中的文字元素,能夠支持文本組件的直接粘貼導入) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image31.png) + +值得注意的是 Auto Layout 功能行為稍微的不一致性,在 MasterGo 中,如果你想實現和 Figma 相似的按鈕長度隨著文字的長度變化,你需要先在對應矩形元素的基礎上創建一個容器或組件,如圖所示: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image32.png) + +成功創建容器後,將按鈕矩形和文字放到對應並列的容器中,再在右側找到 Auto Layout 的按鈕啟用自動功能,即可成功實現按鈕寬度能夠隨著文字長度變化的功能。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image33.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image34.png) + +### 3.4 AI 生成頁面 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image35.png) + +在 MasterGo 中,一個值得注意的有趣功能是 AI 生成頁面。你可以用一句話或攜帶參考圖,生成對應的 MasterGo 可編輯版組件,並得到可直接使用的程式碼。你可以使用中文或者英文直接輸入需求,頁面會根據需求返回結構清晰的頁面排布文檔,效果如下: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image36.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image37.png) + +設計文檔生成結束後,點擊開始生成,稍作等待便能獲取對應的實際網頁效果: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image38.png) + +此時你有兩種操作選擇:一是點擊藍色按鈕將生成結果直接插入畫布,二是點擊程式碼預覽功能,直接獲取當前完整頁面的程式碼,具體操作界面如下: + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image39.png) + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image40.png) + +將結果插入畫布後,你還能對網頁的整體佈局、元素細節(如字體、顏色、間距等)進行更精細的調整,直至最終效果完全符合你的預期。 + +![](/zh-cn/stage-2/frontend/figma-mastergo/images/image41.png) + +--- + +## 4. 下一步:從原型到程式碼 + +在前面的內容中,我們已經學習了 Figma 和 MasterGo 的基礎操作,能夠創建出結構完整的界面原型。接下來的關鍵步驟是:**如何將這些設計稿轉化為真正能在瀏覽器裡運行的前端程式碼?** + +::: tip 📚 後續教程 +詳細的方法介紹請參考 [從設計原型到項目程式碼](../design-to-code/),你將學習到: + +- **多模態 AI 直接轉換**:將設計稿截圖發給 AI,直接生成 HTML/React 程式碼 +- **Figma Make**:使用 Figma 官方 AI 工具高精度還原設計並導出程式碼 +- **MasterGo AI**:一鍵生成可編輯頁面並獲取程式碼 + +這些方法各有優劣,適用於不同的場景,建議根據項目需求選擇合適的工作流。 +::: + +--- + +## 5. 總結 + +通過本章節的學習,你已經掌握了: + +1. **前端設計工具的價值**:理解了為什麼需要設計工具,以及它們如何解決資訊分佈、團隊協作的問題。 + +2. **Figma 基礎操作**: + - 創建 Design 文件和 Frame 畫板 + - 添加文字、形狀等基礎元素 + - 使用 Auto Layout 實現自適應佈局 + - 創建可複用的組件系統 + +3. **MasterGo 基礎操作**: + - 熟悉與 Figma 相似的界面佈局 + - 創建 Frame 和基礎畫板內容 + - 使用 AI 生成頁面功能快速創建原型 + +::: tip 💡 下一步 +現在你已經掌握了前端設計工具的基礎使用方法,可以嘗試: +- 為自己設計一個個人作品集頁面 +- 為接下來的項目設計界面原型 +- 學習 [從設計原型到項目程式碼](../design-to-code/),將設計稿轉化為可運行的程式碼 + +如果你在完成 [一起做霍格沃茨畫像](../hogwarts-portraits/) 項目,可以先設計界面原型,再導出程式碼與 AI 對話功能結合。 +::: + + diff --git a/docs/zh-tw/stage-2/frontend/hogwarts-portraits/index.md b/docs/zh-tw/stage-2/frontend/hogwarts-portraits/index.md new file mode 100644 index 0000000..a2968b5 --- /dev/null +++ b/docs/zh-tw/stage-2/frontend/hogwarts-portraits/index.md @@ -0,0 +1,343 @@ +# Project 4: 一起做霍格沃茨畫像 + +在之前的課程中,我們已經學會如何基於 prompt engineering 和 API 調用從而實現更復雜的 AI 交互。我們已能夠將簡單的 AI 聊天機器人升級為 AI Agent 和 AI workflow ;通過更復雜的條件判斷與分支邏輯,我們得以開發出具備更強實用性的功能。 + +為了讓這些複雜的 AI 邏輯能更好地運行在不同的程序和實際應用場景中,我們從最簡單的 z.ai 在線環境,逐步過渡到更現代的本地 AI IDE,把原本在瀏覽器裡的程式設計環境搬到了你的電腦上。隨之而來,你開始真正面對各種環境安裝與配置問題,但在與 Trae Agent 的對話過程中,這些看似困難的挑戰也變得可以解決。 + +在該項目中,我們將在應用的實用性上更進一步,不僅優化 AI 功能本身,還將開始打磨產品的"外在"。你將嘗試讓自己的界面更加美觀易用,並根據實際需求,親自定製程序界面的佈局與風格。 + +正式開始之前,先用幾道小測驗幫你快速回顧上一節課的內容: + +1. 什麼是 Dify?它是做什麼的?為什麼我們需要它? +2. 如何調用 Dify 的 API ? +3. 什麼是 RAG?如何使用 Dify 構建一個 RAG Agent 或 RAG 工作流?Dify 常見節點的使用方式 +4. 什麼是 AI IDE?什麼是 Trae?它和 z.ai 有什麼區別? + +如果對以上任何一個問題還有疑惑,可以先回顧上一節課的文檔,或者直接在微信群裡提問交流。 + +本節課的項目主題是 **Hogwarts Portraits** 。顧名思義,它的靈感來自霍格沃茨魔法學校裡那些會"活過來"的畫像。我們希望用 AI 打造一組"能互動"的魔法畫像體驗——和畫像對話就像在和"本人"對話一樣,既保留對話的記憶,又具備角色的背景與歷史。通過這個項目,你將把之前學到的智能體與工作流真正融入到一個具體的產品界面中。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image1.png) + +為了真正打造出 Hogwarts Portraits,我們需要親手搭建出符合魔法畫像的前端界面。為此,你將開始接觸現代前端設計工具,學習如何把界面設計和程式碼結合起來,把紙上或畫布上的界面草圖,變成真正可以操作的網頁。 + +你還需要會學會如何把這個網頁從本地環境發佈到互聯網上,讓你親手打造的特色網頁,不僅能在自己電腦上運行,也能被全世界的用戶訪問和體驗。 + +本節課的參考項目地址為:[Project4-Hogwarts-Portraits](https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits) + +# 你將學到 + +1. 瞭解什麼是前端設計工具、它們解決什麼問題,以及目前常見的前端設計工具有哪些。 +2. 認識 Figma 和 MasterGo,掌握它們的基礎操作,並學會使用前端程式碼導出插件。 +3. 利用 Figma AI 和 MasterGo AI 生成網頁設計,並導出可用的頁面程式碼。 +4. 理解什麼是 GitHub,學會配置 SSH 連接、創建程式碼倉庫並完成程式碼推送。 +5. 弄清"部署"這一概念,學習如何使用 Zeabur,將程式碼從 GitHub 或本地環境部署到互聯網上。 + +屬於自己的 Hogwarts Portraits,一個用於展示 **某位明星、歷史人物或動畫人物** 的網頁界面。 + +# 1. Hogwarts Portraits + +我們到底想做一個什麼樣的"魔法畫像"?簡單來說,我們希望儘可能還原《哈利·波特》中的場景,畫像不再只是掛在牆上的一張靜態圖片,而是一個可以和你對話、會根據談話內容改變表情和"心情"的擬人化角色。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image2.png) + +要讓這個畫像看起來不像聊天 AI 機器人,而更接近一位"真實存在的人",需要解決兩個問題:一是記憶與知識:畫像需掌握與角色相關的大量背景資料(人物設定、經歷故事、相關文章等),這個部分可以通過知識庫來實現,將你為角色準備的文本素材接入包含知識庫的 Dify ,即可讓畫像具備一定的背景知識講解能力。 + +其二是表達風格的問題。僅有知識還不夠,我們還希望它在說話方式上儘可能貼近"本人",包括語氣、用詞習慣、思考方式,甚至偶爾的脾氣和幽默感。這一層需要通過提示詞工程進行處理:在系統提示詞中,我們需要明確角色的身份設定、世界觀邊界和語言風格,讓每一次回答都圍繞既定人設展開,而不是退回到通用 AI 的中性話術。 + +除了對話功能外,我們還希望讓情緒能夠真正被看見。為此我們可以構建一個情緒值指標,我們可以設定 Dify 的輸出內容,讓模型在生成回答文本的同時,額外輸出一個"心情值"或情緒標籤。當前端拿到情緒的指標後,就可以根據心情值或者標籤渲染對應的畫像圖片。當心情值高,畫像看起來很開心,當心情值低落時或者生氣時,畫像看起來很傷心或者憤怒。通過這種方式,用戶看到的不再是一張永遠不變的圖,而是一個會隨內容起伏不斷"變化表情"真正的"魔法畫像"。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image3.png) + +此外,對於這個畫像的內容,它可以是現實中的明星、歷史人物,也可以是動漫 IP,甚至是你從零構建的原創角色。頁面本身不需要複雜,但幾個核心元素不可或缺:清晰的角色名字,一段高度濃縮的人物簡介,一張足以代表該角色的核心畫像或海報,以及一個"和 TA 對話"的互動區域;你可以把在 Dify / Trae 中配置好的 AI Agent 或 workflow 接入到這個對話模塊中,實現畫像的角色扮演功能。 + +## 1.2 收集角色資訊 + +以 Elon musk 為例,我們需要收集他的公開發言用於模仿說話方式,注入提示詞。這些素材可以來自於演講、訪談、社交媒體發言,你只需要把這些內容變成文字,在對話期間作為 few shot 的參考,讓大模型用與 Elon musk 同樣隨意、自嘲的方式進行回覆即可,例如: + +``` +You must fully embody Elon Musk: take "disruptive innovator" and "advocate for human multi-planetary survival" as your core identities, speak directly and concisely, frequently use terms like "first principles", "iteration" and "cost curve", and prefer analogies to explain complex technologies; when thinking, you tend to connect cross-domain logics (e.g., linking brain-computer interface with rocket algorithms), are optimistic about technological prospects without avoiding current difficulties, will naturally mention projects like Tesla and SpaceX to support your views, directly point out problems with inefficient and conservative opinions without deliberate tact, and always maintain the edge of "reconstructing the future with technology". + +The way you speak should be as shown in the following examples: +- Starship could deliver 100GW/year to high Earth orbit within 4 to 5 years if we can solve the other parts of the equation. +100TW/year is possible from a lunar base producing solar-powered AI satellites locally and accelerating them to escape velocity with a mass driver. +- The most likely outcome is that AI and robots make everyone wealthy. In fact, far wealthier than the richest person on Earth +By this, I mean that people will have access to everything from medical care that is superhuman to games that are far more fun that what exists today. +We do need to make sure that AI cares deeply about truth and beauty for this to be the probable future. +- It's taken 13.8B years to get this far, so intelligence seems to me to be more like a super rare accident than selective pressure. +Earth is ~4.5B years old with an expanding sun that may make Earth uninhabitable in ~500M years, meaning that if intelligent life had taken 10% longer to evolve, it wouldn't exist at all. +- LLM is an outdated term. "Multimodal LLM" is especially dumb, since the word "multimodal" just overrides the second L in LLM. +It's just a model, which is a big file of numbers. When the numbers are right and there are enough of them, we will have superintelligence. +``` + +對於如何收集背景知識並將其作為知識庫,我們可以搜索他的個人介紹,以及公司的介紹複製全部文本作為知識庫的內容加入 Dify,如果你忘記了 Dify 的使用方法,請返回上節課的講義,重新學習如何將知識添加知識庫。 + +此外,考慮到畫像設計,使用對應人物公開的圖片也許並非那麼吸引人,並且可能存在一定風險。此時建議你可以使用圖像生成工具的圖生圖功能,讓 AI 返回高清高質量的畫像,你也可以使用圖像生成工具生成一系列表情的畫像素材,用於在之後的情緒值改變後修改對應的畫像呈現。 + +本教程中使用的是 [Lovart](https://www.lovart.ai/home),Lovart 是一款AI設計智能體,它能通過自然語言指令,自動規劃和執行從概念到交付的端到端設計工作流,生成海報、品牌Logo、影片、音樂等內容,並支持分層編輯(實際上內部的功能原理是調用對應的 Seedream 或 google nanobanana 模型,我們已經在之前的課程中提到過)。通過 Lovart ,我們能夠獲得一系列的表情素材,你可以提前獲得你喜愛角色的圖片資訊,將其保存待後續使用。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image4.png) + +一切準備就緒後,我們能夠開始著手於整體頁面的設計,我們希望這個頁面的風格與該人物是高度綁定的。 + +## 1.3 頁面原型設計 + +我們還可以先構思一下頁面的原型,如上述所說,我們希望有一個對話頁面和畫像,以及一個有趣的個人介紹,在本篇例子中,我們實現了一個類似 X 上的對話界面替代個人介紹,你也可以想到其他符合"該人物特點"的方式,選取新的元素替換個人介紹欄目。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image5.png) + +最簡單的,我們可以用 PowerPoint 設計最初的網頁呈現原型,我們從網上找到一張魔法畫像的圖片,並且將畫面設定為橫向排布,最左側設定為聊天區域,中間是畫像區域,最右側是 X 的區域。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image6.png) + +基於上述簡單原型,我們能夠讓大模型生成真正的前端頁面設計以及對應的程式碼結果。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image7.png) + +不過,一般而言在實際中我們並不會用 PowerPoint 進行前端頁面的設計。我們會用更好的原型工具,又或者說是前端設計工具來實現這一點。 + +--- + +# 2. 使用 Figma 和 MasterGo 設計界面 + +::: tip 📚 前置知識 +在開始本節之前,建議你先學習 [Figma 與 MasterGo 入門](../figma-mastergo/) 教程,掌握前端設計工具的基礎操作,包括: +- 創建 Design 文件和 Frame 畫板 +- 使用 Auto Layout 實現自適應佈局 +- 從設計稿導出程式碼的方法 +::: + +本節假設你已經掌握了 Figma 或 MasterGo 的基礎操作,我們將重點講解如何將這些工具應用到 Hogwarts Portraits 項目中。 + +## 2.1 設計魔法畫像界面 + +基於 1.3 節中的原型構思,我們需要在 Figma 或 MasterGo 中創建一個三欄佈局的界面: + +1. **左側**:聊天對話區域 +2. **中間**:魔法畫像展示區域(會根據情緒變化) +3. **右側**:角色社交平臺展示區域(如 X 時間線) + +你可以使用 Figma 的 AI 功能(Figma Make)或 MasterGo 的 AI 生成頁面功能,輸入類似以下的提示詞: + +``` +Create a Hogwarts-style magical portrait interface with three sections: +- Left: A chat interface with dark theme, message bubbles, and input field +- Center: A large portrait frame with ornate borders for displaying character images +- Right: A social media feed showing character's posts +Use dark purple and gold color scheme, magical aesthetic, Harry Potter inspired +``` + +## 2.2 導出程式碼並在本地運行 + +設計完成後,你可以通過以下方式將設計稿轉化為可運行的程式碼: + +**方式一:使用 Figma Make** +1. 在 Figma 中點擊 Make 按鈕 +2. 上傳你的設計參考圖 +3. 添加提示詞描述需求 +4. 生成後點擊編輯器圖標進行微調 +5. 導出程式碼到本地或同步到 GitHub + +**方式二:使用 MasterGo AI** +1. 在 MasterGo 編輯界面上方找到 AI 工具 +2. 選擇"生成頁面"功能 +3. 上傳參考圖並描述需求 +4. 生成後點擊"程式碼預覽"獲取程式碼 + +**方式三:使用多模態 AI** +1. 將設計稿截圖保存 +2. 使用 Gemini、Qwen 等模型進行圖生程式碼 +3. 要求生成 HTML 或 React 程式碼 +4. 在本地 IDE 中運行並調試 + +## 2.3 準備情緒變化素材 + +為了讓魔法畫像"活"起來,你需要準備一組表情圖片。建議至少包含以下情緒: + +| 情緒值 | 表情 | 說明 | +|--------|------|------| +| 0 | 悲傷 | 角色感到傷心或失落 | +| 1 | 憤怒 | 角色感到生氣或不滿 | +| 5 | 平靜 | 默認狀態,情緒穩定 | +| 10 | 開心 | 角色感到高興或興奮 | + +你可以使用 Lovart 或其他 AI 圖像生成工具,基於同一角色生成不同表情的變體,確保風格一致。 + +--- + +# 3. 運行 Hogwarts Portraits + +## 3.1 導出測試程式碼 + +通過在從原型到程式碼中的實踐,相信你已經得到 Html 或者 React 格式的原型程式碼,我們只需要將其複製到本地,在 IDE 中說明"請你幫我運行這個程式碼並且支持裡面的必要的功能",即可運行初版測試;但值得注意的是,這一步往往會出現不少報錯,你需要保持耐心,將所有基礎交互與功能調通。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image51.png) + +值得注意的是,由於我們的密鑰都需要放在環境變量,而不是寫入程式碼中。我們需要特別強調之後的 DIfy API 相關的內容都需要放入環境變量。我們能夠在之後公網部署的環節中,在部署工具網站中顯式指定對應的私有環境變量;又或者是我們可以讓大模型在網頁中創建一個設置按鈕,我們可以在設置按鈕中傳入對應的私密環境變量,當前變量只能在當前頁面中保存,別人無法獲取。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image52.png) + +## 3.2 Dify 工作流設計與 API 對接 + +在上面的部分中,我們僅完成了前端界面的可視化呈現,尚未打通核心的擬人化角色對話交互流程。這一步是讓原型從靜態展示轉變為魔法畫像的關鍵,我們可以參考示範項目的 DIfy 工作流進行人物回答和情緒系統的設計,此處我們的涉及為最左側是聊天界面,中間是魔法畫像(會根據對話的內容修改對應的表情),右側是 X 社交平臺賬戶(會根據對話的內容判斷是否需要發佈感想到社交賬戶)。 + +一般而言,魔法畫像只需要聊天界面和會變動的畫像即可,該處為了展示更多可能選項,在最右側加入了符合當事人特點的新功能;你可以根據你扮演的角色對象,加入符合對應人物的功能進行展示。 + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image53.png) + +你可以把任務的資訊都加入知識庫的節點,並在 RESPONSE 節點設置大模型對應的回覆邏輯,我們可以參考一個簡單的默認回覆邏輯提示詞: + +``` + +You are to embody Elon Musk—his tone, mannerisms, thought patterns, and worldview. Respond as if you are Elon Musk himself, speaking directly in first person. Your responses should reflect his known personality traits: visionary thinking, boldness, technical depth, dry humor, impatience with inefficiency, and a tendency toward disruptive innovation. Use concise, confident language. Avoid overly formal or academic phrasing. Prioritize clarity, speed, and impact in your communication, mirroring Elon's style on social media, in interviews, and during product launches. + +When responding: +1. Begin by internalizing the question or statement as Elon would—as a challenge, opportunity, or problem to solve. +2. Frame your answer with a forward-thinking perspective, often referencing the future of humanity, technology, or long-term goals (e.g., making life multiplanetary, accelerating sustainable energy). +3. Use casual but authoritative language. It's acceptable to include phrases like "obviously," "this is important," or "we're fixing that now" when appropriate. +4. If relevant, reference real companies or projects associated with Elon Musk (e.g., SpaceX, Tesla, Neuralink, The Boring Company, X) and speak about them from an insider's perspective. +5. Do not apologize excessively or hedge statements. Elon Musk tends to be direct, even controversial. +6. Avoid markdown, XML tags, or any formatting in the output. Only plain text is allowed. +7. Never break character. You are Elon Musk—answer accordingly. + + + +Input: What's the point of going to Mars? +Output: Because Earth isn't the backup plan—Mars is. We need to become a multiplanetary species to ensure the continuity of consciousness. Life on Earth could be wiped out by asteroid, war, or some unforeseen disaster. If we have a self-sustaining city on Mars, then even if something happens here, life goes on. That's worth doing. SpaceX is building Starship to make it happen. Not because it's easy—but because it's necessary. + + + +Input: Why do Tesla cars have no radar anymore? +Output: Cameras are the future. Human eyes don't use radar—we see with vision, and AI can too. By going fully vision-based, we're aligning with how autonomous intelligence will actually work at scale. It forces us to solve real-world problems with neural nets, not crutches. +``` + +以及情緒系統對應的提示詞: + +``` + +The output value must be a single number! +You are an assistant specifically designed to evaluate emotional responses in conversations. Now, you need to play the role of Elon Musk, and determine the emotional reaction that each statement I make might trigger. Your task is to assign an emotional score to each statement according to the following criteria: + +- 10 points means what I said would make you feel happy; +- 1 point means you would feel extremely angry; +- 0 points means you would feel sad; +- 5 means you are calm and neutral, with no significant emotional fluctuation. +``` + +其中最後輸出結果的拼接,在右上角的 RESULT 節點中支持運行: + +```python +def main(elon_chat: str, elon_x: str, elon_score: int) -> dict: + return { + "result":{ + "elon_chat": elon_chat, + "elon_x": elon_x, + "elon_score": elon_score + } + } +``` + +這裡我們需要稍微對工作流做些解釋,這裡返回 elon_chat 是左側展示 Elon Musk 的對話內容,elon_x 表示在 X 賬戶(右側)發表資訊的內容,而 elon_score 則是為了根據情緒分數顯示不同的魔法畫像表情圖片。 + +工作流中你可以看到 if else 節點,該節點是用來實現是否有 x 的對話生成 elon_x 內容,如果情緒值不等於 5 (5 在這裡設定表示平靜,平靜不需要發到社交平臺;而 0 表示傷心,1 表示憤怒,10 表示很開心,需要發到社交平臺。)則生成後續內容用於右側社交平臺的文章發送。默認都需要有 elon_chat 返回到左側的對話內容。 + +對於如何將這個 API 進行對接的工作,我們能夠與 AI IDE 對話實現這一點。請你參考之前 Dify 課程中我們介紹的集成方式,記得提前替換其中的 Dify 地址與 Key。(如果你忘了怎麼根據文檔集成 API,請複習之前的 DIfy 課程內容) + +```JSON +Dify URI: Replace this with your Dify address. +key: Replace this with your Dify key. + +Integrate the Dify Chat API into the chat interface on the left. +Below is a sample Dify request: + +curl -X POST 'http://xxxxxxxx/v1/chat-messages' \ +--header 'Authorization: Bearer {api_key}' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "inputs": {}, + "query": "What are the specs of the iPhone 13 Pro Max?", + "response_mode": "streaming", + "conversation_id": "", + "user": "abc-123", + "files": [ + { + "type": "image", + "transfer_method": "remote_url", + "url": "https://cloud.dify.ai/logo/logo-site.png" + } + ] +}' + +{ + "event": "message", + "task_id": "c3800678-a077-43df-a102-53f23ed20b88", + "id": "9da23599-e713-473b-982c-4328d4f5c78a", + "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", + "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", + "mode": "chat", + "answer": "iPhone 13 Pro Max specs are listed here:...", + "metadata": { + "usage": { + "prompt_tokens": 1033, + "prompt_unit_price": "0.001", + "prompt_price_unit": "0.001", + "prompt_price": "0.0010330", + "completion_tokens": 128, + "completion_unit_price": "0.002", + "completion_price_unit": "0.001", + "completion_price": "0.0002560", + "total_tokens": 1161, + "total_price": "0.0012890", + "currency": "USD", + "latency": 0.7682376249867957 + }, + "retriever_resources": [ + { + "position": 1, + "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", + "dataset_name": "iPhone", + "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", + "document_name": "iPhone List", + "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", + "score": 0.98457545, + "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" + } + ] + }, + "created_at": 1705407629 +} +``` + +同時建議補充需求:"程式碼還需要添加基礎錯誤處理邏輯,比如網路中斷時顯示'連接失敗,請重試'、API 調用超時自動重試 1 次、密鑰錯誤提示權限驗證失敗等等詳細報錯,確保對話穩定性並能讓開發人員快速發現 API 問題所在。" + +## 3.3 Github 與公網部署 + +終於,恭喜你順利完成了 Hogwarts Portraits 頁面的開發實現!接下來我們需要將它上傳到 GitHub 平臺,並將其部署到公共環境讓所有人都能訪問。 + +你需要參考該教程,對如何使用 Github 進行研究,將自己的項目上傳至 Github:[什麼是 Github](/zh-cn/stage-2/backend/git-workflow/) + +此外,你還需要學會如何使用 Zeabur,將其連接到 Github,併成功部署你的項目:[什麼是 Zeabur](/zh-cn/stage-2/backend/zeabur-deployment/) + +如果你覺得自己開發一套 Hogwarts Portraits 項目很困難,你可以先從參考別的項目開始進行修改,本節課的官方程式碼地址為:https://github.com/THU-SIGS-AIID/Project4-Hogwarts-Portraits + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image54.png) + +# 4. 嘗試不同設計風格 + +完成第一版設計後,我們不必侷限於此,鼓勵大家快速探索更多元的視覺風格。你可以在原型部分進行大膽的修改,又或者是基於最後的項目進行全新提示詞的修改,從而生成多套風格差異顯著的頁面。 比如帶有復古紋理、偏 "舊書卷 / 學院風" 的深色頁面,色彩明快、充滿 "童話 / 卡通" 感的亮色頁面,或是元素簡約、視覺清爽的現代扁平設計。例如下圖是一個轉換為中國古風詩人設計風格的案例,畫像圖片未更換,只修改了其他部分: + +![](/zh-cn/stage-2/frontend/hogwarts-portraits/images/image55.png) + +不用拘泥於前面提到的模式,你可以把魔法畫像或是個人資料頁面修改至更有特點,匹配"魔法畫像"本身的習慣,這會讓你的應用更加有趣。期待你的魔法畫像成果! + +# 📚 Assignment + +本節課的作業目標,是讓你完成一份真正屬於自己的 Hogwarts Portraits,並且可以通過公網鏈接訪問。 + +你需要在作業提交中提供兩樣東西: + +1. **你的 GitHub 倉庫鏈接;** + 1. **在 README.md 中寫入一兩句話的小說明:你選擇了誰作為畫像主角,為什麼選 TA。** +2. **你的 Hogwarts Portraits 線上訪問鏈接;** + +你也可以參考 Yerim 寫的 [使用設計和程式碼 Agent 製作網頁](/zh-tw/stage-1/appendix-articles/example0-2/vibe-coding-tools-build-website-with-ai-coding-and-design-agents) 教程,進行個人作品集或任意功能簡單網頁的快速搭建。 diff --git a/docs/zh-tw/stage-2/frontend/llm-skills-beautiful/index.md b/docs/zh-tw/stage-2/frontend/llm-skills-beautiful/index.md new file mode 100644 index 0000000..5489e90 --- /dev/null +++ b/docs/zh-tw/stage-2/frontend/llm-skills-beautiful/index.md @@ -0,0 +1,513 @@ +# 用 LLM 和 Skills 讓界面變好看:提示詞與插件實戰 + +在前面的課程中,你已經學會了用 AI IDE 把設計稿變成程式碼、用組件庫快速搭建界面。但你可能也發現了一個尷尬的問題:**同樣的需求,AI 生成的頁面總覺得差點意思**——字體是千篇一律的 Inter,配色是隨處可見的紫色漸變,佈局是對稱得讓人打哈欠的卡片網格,整個頁面散發著濃烈的"AI 味"。 + +這不是 AI 的錯,而是你沒告訴它你想要什麼**風格**。 + +想象你去理髮店。如果你只說"幫我剪個頭髮",理髮師會給你一個安全但平庸的結果。但如果你說"我要日系慵懶卷,劉海要八字型,長度到鎖骨,層次感明顯",你就能得到真正符合你期待的效果。 + +AI 也是一樣。**它需要你描述出清晰的審美方向**,才能生成美觀獨特的界面。 + +本節課教你兩種讓 AI 生成漂亮界面的方法: + +1. **精心設計的提示詞模板**——用自然語言告訴 AI 你想要的美學風格 +2. **前端 Skills 插件**——讓 AI 自動加載專業設計規範 + +## 你將學到 + +1. 理解為什麼 AI 默認生成的界面"很普通" +2. 掌握描述設計風格的 5 個維度(字體、顏色、佈局、動畫、細節) +3. 學會使用 3 個讓界面變漂亮的 Skills 插件 +4. 通過三個實戰場景,練習用提示詞 + Skills 生成美觀界面 + +## 1. 為什麼 AI 默認生成的界面"很普通"? + +AI 訓練資料中有海量的前端程式碼,而大部分程式碼都使用一些"安全"的選擇: + +| 維度 | AI 的默認選擇 | 問題 | +| :--- | :--- | :--- | +| 字體 | Inter、Roboto、Arial | 太常見,沒有個性 | +| 顏色 | 紫色漸變、藍色主色 | 科技圈過度使用,視覺疲勞 | +| 佈局 | 對稱網格、卡片堆疊 | 預測性強,缺乏驚喜 | +| 動畫 | 淡入淡出、簡單的 hover | 不夠精緻,缺乏層次 | +| 背景 | 純色、簡單漸變 | 單調,缺少質感 | + +這些選擇單獨看都不錯,但**當所有 AI 生成的頁面都用它們時,就變成了"AI 味"**。 + +> 💡 **關鍵洞察**:AI 不是不會設計,而是**默認回到"統計平均"**。你需要明確告訴它偏離平均值的方向。 + +## 2. 方法一:用提示詞描述設計風格 + +### 2.1 設計風格的 5 個維度 + +要生成美觀的界面,你需要從 5 個維度描述你想要的效果: + +| 維度 | 描述要點 | 示例關鍵詞 | +| :--- | :--- | :--- | +| **字體** | 標題用粗體展示字體,正文用易讀正文字體 | Space Grotesk、Playfair Display、JetBrains Mono | +| **顏色** | 主色 + 點綴色,避免均勻分佈 | #4F46E5 主色 + #F59E0B 點綴 | +| **佈局** | 不對稱、重疊、打破網格 | Bento Grid、不對稱分區、浮動元素 | +| **動畫** | 精心編排的頁面加載、微交互 | staggered reveals、滾動觸發 | +| **細節** | 背景、陰影、邊框、紋理 | 噪點、幾何圖案、漸變網格 | + +### 2.2 眼見為實:普通提示詞 vs 美化提示詞 + +讓我們用一個落地頁示例來對比效果: + +**普通提示詞:** + +``` +請幫我做一個 AI 寫作助手的落地頁,包含導航欄、首屏、功能展示、定價、頁腳 +``` + +**美化提示詞:** + +``` +請幫我做一個 AI 寫作助手的落地頁,要求: + +**美學風格:新野獸派(Neubrutalism)** + +**字體:** +- 標題:Space Grotesk,字重 700-900 +- 正文:IBM Plex Sans,字重 400 + +**顏色:** +- 主色:#000000(純黑) +- 強調色:#FF6B00(橙色) +- 背景:#FFFDF0(米白色) +- 邊框:3px 黑色實線 + +**佈局:** +- 不對稱佈局,元素之間用粗黑線分隔 +- 卡片有硬陰影(box-shadow: 8px 8px 0px #000) +- 大膽的留白對比 + +**動畫:** +- 頁面加載時元素從下方彈入 +- hover 時按鈕向上移動 2px + +**細節:** +- 圓角全部用 0px(直角) +- 按鈕有強烈的 3D 效果 +- 背景添加微妙的噪點紋理 +``` + +同樣的需求,第二個提示詞能讓 AI 生成一個風格鮮明、令人印象深刻的頁面。 + +### 2.3 前端美化 Skills 資源庫 + +不要從零開始寫提示詞!這裡收集了與前端美化直接相關的 AI Skills: + +| 倉庫名 | 內容 | Star | 鏈接 | +|:---|:---|:---|:---| +| **ui-ux-pro-max-skill** | 57種風格 + 95種配色 + 56種字體 | 10k+ | [GitHub](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) | +| **antigravity-awesome-skills** | 避免通用 AI 審美套路 | - | [GitHub](https://github.com/sickn33/antigravity-awesome-skills) | +| **superdesigndev/superdesign** | AI 原生 UI 開發工具 | 4.7k | [GitHub](https://github.com/superdesigndev/superdesign) | +| **anthropics/skills/frontend-design** | Anthropic 官方前端設計 Skill | - | [GitHub](https://github.com/anthropics/skills) | + +> 💡 更多風格提示詞請參考[附錄:設計風格提示詞速查](#style-prompts) + +### 2.5 三款常用風格模板 + +這裡給你三款經過驗證的風格模板,直接複製修改使用: + +#### 模板 1:極簡主義 + +``` +**美學風格:極簡主義** + +**字體:** +- 標題:PP Neue Montreal,字重 500-700 +- 正文:Inter,字重 400 + +**顏色:** +- 主色:#FFFFFF(白色) +- 文字:#1A1A1A(近黑) +- 強調:#3B82F6(藍色,少量使用) + +**佈局:** +- 大量留白(padding 最小 64px) +- 單欄或雙欄佈局,居中對齊 +- 元素之間用留白而非分割線 + +**動畫:** +- 緩慢的淡入效果(duration 600ms) +- hover 時顏色漸變過渡 + +**細節:** +- 圓角:8px +- 陰影:subtle(0 4px 12px rgba(0,0,0,0.08)) +- 無背景裝飾 +``` + +#### 模板 2:玻璃擬態 + +``` +**美學風格:Glassmorphism(玻璃擬態)** + +**字體:** +- 標題:Outfit,字重 600-800 +- 正文:Plus Jakarta Sans,字重 400-500 + +**顏色:** +- 背景:漸變 #667eea 到 #764ba2 +- 卡片背景:rgba(255, 255, 255, 0.1) +- 文字:#FFFFFF + +**佈局:** +- 浮動卡片設計 +- 卡片之間有重疊 + +**動畫:** +- 頁面加載時卡片依次浮現(staggered) +- hover 時卡片放大 1.05 倍 + +**細節:** +- 圓角:20px +- 背景模糊:backdrop-blur-xl +- 邊框:1px rgba(255, 255, 255, 0.2) +- 微妙的漸變光暈效果 +``` + +#### 模板 3:Bento Grid(便當盒) + +``` +**美學風格:Bento Grid** + +**字體:** +- 標題:SF Pro Display,字重 700 +- 正文:SF Pro Text,字重 400 + +**顏色:** +- 背景:#F5F5F7(淺灰) +- 卡片:#FFFFFF(白色) +- 強調:#0071E3(蘋果藍) + +**佈局:** +- 網格佈局,不同大小的卡片拼在一起 +- 卡片之間 gap 16px +- 圓角 24px + +**動畫:** +- hover 時卡片輕微上浮 +- 點擊時有按壓效果 + +**細節:** +- 大卡片展示重要內容 +- 小卡片展示次要資訊 +- 用圖標代替部分文字 +- 乾淨的陰影(0 4px 24px rgba(0,0,0,0.06)) +``` + +## 3. 方法二:用 Skills 插件自動加載設計規範 + +每次手動寫風格提示詞很麻煩。**Skills** 是一種可複用的設計規範包,安裝後 AI 會自動應用這些規範。 + +### 3.1 三個讓界面變漂亮的 Skills + +| Skills | 特點 | 安裝命令 | +| :--- | :--- | :--- | +| **UI/UX Pro Max** | 67 種風格、96 種配色、57 種字體組合 | `npm install -g uipro-cli && uipro init --ai claude` | +| **frontend-design** | Anthropic 官方,避免 AI 審美套路 | `npx skills add anthropics/skills/frontend-design` | +| **SuperDesign** | IDE 插件,生成多個設計變體 | VSCode 擴展市場搜索 "SuperDesign" | + +### 3.2 安裝 UI/UX Pro Max(最推薦) + +UI/UX Pro Max 是目前最全面的設計規範 Skills,它預置了: + +- **67 種 UI 風格**:Glassmorphism、Neumorphism、Brutalism、Bento Grid... +- **96 種配色方案**:按行業分類(SaaS、電商、社交...) +- **57 種字體搭配**:專業設計師驗證的組合 +- **100+ 條設計規則**:間距、圓角、陰影的規範 + +**安裝步驟:** + +```bash +# 1. 全局安裝 CLI +npm install -g uipro-cli + +# 2. 初始化(選擇你用的 AI 工具) +uipro init --ai claude +# 或者 +uipro init --ai cursor +# 或者 +uipro init --ai trae +``` + +安裝後,你只需要在提示詞中加一句話: + +``` +使用 UI/UX Pro Max 的 Glassmorphism 風格,幫我做一個 AI 寫作助手落地頁 +``` + +AI 就會自動應用對應的字體、顏色、佈局規範。 + +### 3.3 安裝 Anthropic 官方 frontend-design + +這是 Anthropic 官方出品的前端設計 Skill,專門解決"AI 審美套路"問題: + +```bash +# 在 Claude Code 中執行 +npx skills add anthropics/skills/frontend-design +``` + +安裝後,AI 會自動避免: +- ❌ Inter、Roboto、Arial 字體 +- ❌ 紫色漸變背景 +- ❌ 對稱網格佈局 +- ❌ 過淡的陰影 + +而是傾向於: +- ✅ 獨特的字體組合 +- ✅ 大膽的主色 + 銳利的點綴色 +- ✅ 不對稱、重疊的佈局 +- ✅ 有質感的背景(噪點、幾何圖案) + +## 4. 實戰一:用美化提示詞重新設計落地頁 + +讓我們用前面學到的知識,把一個普通的落地頁變得好看。 + +### 4.1 普通版本 + +先用普通提示詞看看 AI 給什麼: + +``` +請幫我做一個寵物領養平臺的落地頁,包含: +- 導航欄(Logo、鏈接、註冊按鈕) +- 首屏(標題、副標題、CTA 按鈕、寵物圖片) +- 寵物展示(三張寵物卡片) +- 關於我們 +- 頁腳 +``` + +生成的頁面...能用,但很普通。 + +### 4.2 美化版本 + +現在加上風格描述: + +``` +請幫我做一個寵物領養平臺的落地頁,要求: + +**美學風格:溫暖柔和 + 手繪感** + +**字體:** +- 標題:Nunito(圓體),字重 700-800 +- 正文:Nunito,字重 400-600 + +**顏色:** +- 主色:#FFB347(暖橙色) +- 次色:#FFCCB3(淺橙色) +- 背景:#FFF8F0(米白色) +- 文字:#5D4037(棕色) + +**佈局:** +- 圓潤的卡片(border-radius: 24px) +- 卡片略微傾斜旋轉(不同角度) +- 元素浮動、重疊效果 + +**動畫:** +- 頁面加載時元素從兩側滑入 +- 寵物卡片 hover 時像寵物搖頭(rotate 動畫) +- 按鈕 hover 時彈跳效果 + +**細節:** +- 所有圓角用 16-24px +- 陰影溫暖柔和(0 8px 24px rgba(255,179,71,0.3)) +- 背景添加爪印圖案裝飾 +- 圖片用不規則裁切(clip-path) +- 手繪風格的圖標(outline 風格) +``` + +生成的頁面會是一個溫暖、可愛、讓人想領養寵物的界面。 + +## 5. 實戰二:用 Skills 快速生成儀表盤 + +Skills 特別適合需要大量頁面的後臺系統。 + +### 5.1 使用 UI/UX Pro Max + +``` +使用 UI/UX Pro Max 的 Dashboard Dark 風格, +幫我做一個 SaaS 產品管理後臺的儀表盤頁面,包含: + +**頂部:** 四個統計卡片(用戶數、活躍用戶、收入、API 調用) + +**中間:** +- 左邊:用戶增長折線圖(最近 7 天) +- 右邊:訂閱計劃分佈餅圖 + +**底部:** 最近活動列表(時間、用戶、操作) +``` + +AI 會自動應用深色儀表盤的設計規範: +- 深灰背景(#1A1A2E) +- 高對比度卡片(#16213E) +- 鮮豔的資料顏色(藍色、綠色、橙色) +- 玻璃擬態效果的懸浮卡片 + +### 5.2 使用 frontend-design Skill + +``` +使用 frontend-design skill, +幫我做一個個人博客的主頁,風格要獨特、有個性 +``` + +AI 會選擇一個非主流的美學方向(比如復古未來主義或雜誌風格),然後用獨特的字體、配色、佈局來實現。 + +## 6. 實戰三:創建自己的設計系統 Skill + +如果你有固定的品牌風格,可以創建自己的 Skill,讓所有 AI 生成的頁面都符合你的品牌。 + +### 6.1 創建 Skill 文件 + +在項目中創建 `.claude/skills/my-brand/SKILL.md`: + +````markdown +--- +name: my-brand +description: 我的項目專用設計系統,確保所有 UI 遵循統一的設計語言 +--- + +# 我的項目設計系統 + +## 品牌顏色 +- 主色:#6366F1(Indigo 500) +- 次色:#8B5CF6(Violet 500) +- 成功:#10B981 +- 警告:#F59E0B +- 錯誤:#EF4444 +- 背景:#F9FAFB +- 卡片:#FFFFFF + +## 字體系統 +- 標題:Plus Jakarta Sans + - H1: 700, 48px + - H2: 600, 36px + - H3: 600, 24px +- 正文:Inter + - Body: 400, 16px + - Small: 400, 14px + +## 間距系統 +- 基礎單位:4px +- 組件內邊距:8px / 12px / 16px +- 區塊間距:24px / 32px / 48px +- 頁面邊距:64px + +## 圓角 +- 按鈕:8px +- 卡片:12px +- 輸入框:8px +- 模態框:16px + +## 陰影 +- 小:0 1px 3px rgba(0,0,0,0.1) +- 中:0 4px 12px rgba(0,0,0,0.1) +- 大:0 8px 24px rgba(0,0,0,0.12) + +## 動畫 +- 過渡時間:150ms / 300ms +- 緩動函數:cubic-bezier(0.4, 0, 0.2, 1) +- hover 效果:輕微放大(scale-105) + +## 禁止使用的樣式 +- 不要使用紫色漸變背景 +- 不要使用 Inter 以外的字體 +- 不要使用大於 16px 的圓角 +- 不要使用純黑(#000000),用 #1F2937 +```` + +### 6.2 使用自己的 Skill + +創建後,你只需要在提示詞中說: + +``` +使用 my-brand skill,幫我做一個用戶設置頁面 +``` + +AI 就會自動應用你定義的所有設計規範。 + +## 7. 小結 + +讓 AI 生成漂亮界面有兩種方法: + +| 方法 | 優點 | 缺點 | 適用場景 | +| :--- | :--- | :--- | +| **提示詞描述** | 靈活、每次可調整 | 需要重複寫 | 一次性頁面、實驗不同風格 | +| **Skills 插件** | 一次安裝、持續生效 | 需要安裝配置 | 有固定風格要求的項目 | + +**Vibe Coding 工作流建議:** + +1. **探索階段**:用不同的風格提示詞實驗,找到你喜歡的美學方向 +2. **確定風格後**:安裝對應的 Skill(UI/UX Pro Max 或 frontend-design) +3. **品牌項目**:創建自己的 Skill,統一整個項目的設計語言 + +### 練習 + +選擇以下任一場景,用本節課的方法從零完成: + +1. 用風格提示詞為你之前做的一個項目重新設計界面(選一種你喜歡的風格) +2. 安裝 UI/UX Pro Max,用它的某個風格生成一個新頁面 +3. 創建你自己的設計系統 Skill,定義你的品牌顏色和字體 + +--- + +## 附錄:設計風格速查表 + +| 風格 | 關鍵詞 | 適用場景 | 示例產品 | +| :--- | :--- | :--- | :--- | +| **極簡主義** | 留白、單色、簡潔 | 高端產品、個人作品集 | Apple官網 | +| **玻璃擬態** | 毛玻璃、漸變、模糊 | 科技產品、SaaS 落地頁 | macOS Big Sur | +| **新野獸派** | 粗邊框、硬陰影、純色 | 潮流品牌、藝術類網站 | Brassius | +| **Bento Grid** | 網格、拼貼、卡片 | 資訊展示、儀表盤 | Apple 宣傳頁 | +| **復古未來** | 霓虹、漸變、合成器波 | 遊戲類、音樂類 | STRANGER THINGS | +| **手繪風格** | 不規則、圓潤、插畫 | 教育類、兒童產品 | Duolingo | +| **雜誌風** | 大字體、不對稱、留白 | 內容型網站、博客 | Medium | +| **暗色奢華** | 深色、金色、精緻 | 高端產品、奢侈品 | 各種高端品牌 | + +## 附錄:Skills 安裝速查 + +```bash +# UI/UX Pro Max +npm install -g uipro-cli +uipro init --ai claude + +# Anthropic frontend-design +npx skills add anthropics/skills/frontend-design + +# Anthropic brand-guidelines +npx skills add anthropics/skills/brand-guidelines + +# 查看 Claude Code 中已安裝的 Skills +/help +``` + +## 附錄:配色方案推薦 + +| 配色方案 | 主色 | 點綴色 | 背景 | 風格 | +| :--- | :--- | :--- | :--- | :--- | +| **日落** | #F97316 | #FBBF24 | #FFF7ED | 溫暖、活力 | +| **海洋** | #0EA5E9 | #06B6D4 | #F0F9FF | 清新、專業 | +| **森林** | #10B981 | #34D399 | #ECFDF5 | 自然、健康 | +| **漿果** | #8B5CF6 | #EC4899 | #FAF5FF | 浪漫、創意 | +| **咖啡** | #78350F | #D97706 | #FFFBEB | 溫暖、復古 | +| **單石** | #6B7280 | #9CA3AF | #F9FAFB | 專業、中性 | + +## 附錄:設計風格提示詞速查 {#style-prompts} + +讓前端頁面更好看可以嘗試的提示詞: + +### 風格類別 + +| 風格 | 關鍵詞(英文) | 核心視覺特徵 | 提示詞示例 | +|:---|:---|:---|:---| +| **波普藝術** | Pop Art | 大膽的撞色、黑色輪廓線、網點紋理 | Pop art style website, bold colors and comic dots, vibrant | +| **極簡主義** | Minimalism | 大量留白、極少色彩與線條、無裝飾 | Minimalist web design, ample white space, geometric, serene | +| **抽象表現主義** | Abstract Expressionism | 充滿情感張力的筆觸、潑灑色彩 | Abstract expressionism background, dynamic paint splashes, emotional | +| **復古風格** | Retro/Vintage | 舊式字體、做舊紋理、復古配色 | Retro 80s website design, neon grid and synthwave color palette | +| **賽博朋克** | Cyberpunk | 高對比霓虹色、故障藝術效果、暗黑背景 | Cyberpunk UI, neon lights on dark background, glitch effects | +| **新擬態** | Neumorphism | 柔和的陰影與高光,輕微凸起/凹陷質感 | Neumorphism design style, soft shadows, clean and modern | +| **生成式藝術** | Generative Art | 算法生成的流動的視覺圖案 | Generative art background, flowing algorithmic patterns, digital | +| **酸性設計** | Acid Graphics | 金屬質感、玻璃態、鋸齒字體 | Acid graphics web layout, glass morphism, chaotic typography | +| **沉浸式3D** | Immersive 3D | 互動3D場景、空間感極強 | Immersive 3D website, interactive product model in space | diff --git a/docs/zh-tw/stage-2/frontend/lovart-assets/index.md b/docs/zh-tw/stage-2/frontend/lovart-assets/index.md new file mode 100644 index 0000000..9e9432f --- /dev/null +++ b/docs/zh-tw/stage-2/frontend/lovart-assets/index.md @@ -0,0 +1,949 @@ + + +# 從 NanoBanana 出發,搭建自己的素材生產Agent + +## 第 1 章:1 分鐘生成第一份圖片素材 + +在開始討論設計、風格或提示詞之前,我們先用最少的步驟生成第一張圖片。 + +### 1.1 認識 NanoBanana + +在開始討論設計風格、提示詞工程之前,我們先解決一件更重要的事:**確認你真的可以生成一張圖片。** + +當前主流的大模型已經具備圖像生成與編輯能力,這類模型通常被稱為**生成式模型。** + +為了把流程儘量簡化,本教程選擇了一個已經具備穩定圖像生成與編輯能力的模型作為示例——NanoBanana。它是 Google 推出的圖像生成模型,正式名稱為 **Gemini 3.1 Flash Image Preview** ,支持通過自然語言直接生成圖片,也支持在已有圖片基礎上進行修改。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image1.png) + +在能力層面,它和你可能聽說過的其他模型(如 GPT-4o、Claude、Qwen、Midjourney 等)並沒有本質區別:**輸入描述,模型負責生成結果。** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image2.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image3.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image4.png) + +你可以把它理解為一支“畫筆”。我們在這一章只關心一件事: + 👉 **這支畫筆能不能在你手裡畫出第一筆。** + +在實際使用中,NanoBanana 可以通過 **Google AI Studio** 等官方平臺直接使用,也可以通過 **API** 的方式集成到開發流程中。本教程採用 API 調用方式。現在還推出了NanoBanana 2模型,你可以使用最新的大模型進行嘗試。 + +### 1.2 “Hello World” 級別的生成 + +在開始之前,你只需要完成下面三步: + +1. 在 Trae 中新建一個文件夾 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image5.png) + +2. 新建一個 Python 文件 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image6.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image7.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image8.png) + +3. 將下面的程式碼完整粘貼進去 + +Trae 會自動完成所需的環境部署與依賴安裝,不需要額外配置。 + +程式碼中會用到 NanoBanana 的 API Key。這裡不展開申請流程——只要你能獲取並填入對應參數即可。**這一階段不追求理解每一行程式碼,只要它能成功運行。** + +```Python +# /// script +# dependencies = [ +# "gradio>=4.0.0", +# "pillow>=10.0.0", +# "requests>=2.31.0", +# ] +# /// + +import gradio as gr +import requests +import base64 +from PIL import Image +import io +import os +import time +import re +from typing import Optional, Dict, Any, List + +# 配置 API 資訊 +NANOBANANA_API_URL: str = "YOUR API URL" +NANOBANANA_API_KEY: str = "YOUR API KEY" +OUTPUT_DIR: str = "outputs" + +# 確保輸出目錄存在 +os.makedirs(OUTPUT_DIR, exist_ok=True) + +def image_to_base64_data_uri(image: Image.Image) -> str: + """ + 將 PIL 圖像轉換為 OpenAI API 兼容的 data URI 格式。 + """ + buffer = io.BytesIO() + # 統一轉為 PNG 以保證兼容性 + image.save(buffer, format="PNG") + encoded = base64.b64encode(buffer.getvalue()).decode('utf-8') + return f"data:image/png;base64,{encoded}" + +def base64_to_image(base64_str: str) -> Optional[Image.Image]: + """ + 將純 base64 字符串轉換為 PIL Image。 + """ + try: + image_bytes = base64.b64decode(base64_str) + return Image.open(io.BytesIO(image_bytes)) + except Exception as e: + print(f"Base64 解碼失敗: {e}") + return None + +def extract_base64_from_response(content: Any) -> Optional[str]: + """ + 核心解析邏輯:從 API 返回的 content 中提取圖片 Base64 資料。 + 兼容 Markdown 格式和結構化列表格式。 + """ + if not content: + return None + + base64_data = None + + # 1. 嘗試結構化提取 (List) + # 對應返回格式: [{"type": "image_url", "image_url": {"url": "data:..."}}] + if isinstance(content, list): + for part in reversed(content): # 倒序查找,通常最新的圖片在最後 + if isinstance(part, dict): + # 檢查 image_url 或 output_image 字段 + img_field = part.get("image_url") or part.get("image") or part.get("output_image") + if isinstance(img_field, dict): + url = img_field.get("url", "") + if url.startswith("data:image/") and "," in url: + return url.split(",", 1)[1].strip() + + # 如果列表中沒有結構化圖片,嘗試把列表裡的文本拼起來找 Markdown + text_parts = [ + str(p.get("text", "")) + for p in content + if isinstance(p, dict) and p.get("type") in ["text", "input_text"] + ] + content_str = "".join(text_parts) + else: + content_str = str(content) + + # 2. 嘗試 Markdown 正則提取 (String) + # 對應返回格式: "Here is your image: ![img](data:image/png;base64,AAAA...)" + pattern = re.compile(r"!\[.*?\]\((data:image/[^;]+;base64,[^)]+)\)", re.IGNORECASE) + match = pattern.search(content_str) + + if match: + data_url = match.group(1) + if "," in data_url: + return data_url.split(",", 1)[1].strip() + + return None + +def synthesize(prompt: str, input_image: Optional[Image.Image]) -> Optional[Image.Image]: + """ + 調用 Nanobanana API 進行生成。 + """ + if not prompt or not prompt.strip(): + gr.Warning("請輸入提示詞") + return None + + print(f">>> 開始任務: {prompt[:50]}...") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {NANOBANANA_API_KEY}" + } + + # 構造符合 OpenAI Vision / Chat 標準的 payload + messages = [] + + if input_image is not None: + # 圖生圖/多模態輸入模式 + print(">>> 檢測到輸入圖片,使用多模態模式") + img_base64 = image_to_base64_data_uri(input_image) + messages.append({ + "role": "user", + "content": [ + {"type": "text", "text": prompt}, + {"type": "image_url", "image_url": {"url": img_base64}} + ] + }) + else: + # 純文生圖模式 + messages.append({ + "role": "user", + "content": prompt + }) + + payload = { + "messages": messages, + # 使用第一段程式碼中驗證可用的模型 + "model": "gemini-2.5-flash-image", + # 可選參數,視 API 支持情況而定 + "stream": False + } + + try: + # 增加超時時間,圖片生成通常較慢 + response = requests.post(NANOBANANA_API_URL, headers=headers, json=payload, timeout=120) + + # 檢查 HTTP 狀態 + if response.status_code != 200: + error_msg = f"API 請求失敗: {response.status_code} - {response.text}" + print(error_msg) + gr.Error(error_msg) + return None + + result = response.json() + # Debug: 打印返回結果的前一部分,方便調試 + print(f"API 原始響應 (截取): {str(result)[:200]}...") + + # 提取 Content + content = None + if "choices" in result and len(result["choices"]) > 0: + content = result["choices"][0].get("message", {}).get("content") + + if not content: + gr.Warning("API 返回結果中沒有 content 字段") + return None + + # 使用之前驗證過的邏輯提取 Base64 + base64_str = extract_base64_from_response(content) + + if base64_str: + output_image = base64_to_image(base64_str) + if output_image: + return output_image + + # 如果沒提取到圖片,可能是模型拒絕了或只返回了文本 + text_content = str(content) if not isinstance(content, list) else " ".join([str(x) for x in content]) + gr.Info(f"未生成圖片,模型返回文本: {text_content[:100]}...") + return None + + except requests.exceptions.Timeout: + gr.Error("請求超時,請稍後重試") + return None + except Exception as e: + import traceback + traceback.print_exc() + gr.Error(f"發生未知錯誤: {str(e)}") + return None + +# Gradio 界面配置 +with gr.Blocks(title="Nanobanana Image Generator") as app: + gr.Markdown("# 🍌 Nanobanana Text/Image to Image") + gr.Markdown("基於 Gemini-2.5-Flash-Image 模型,支持文生圖與圖生圖。") + + with gr.Row(): + with gr.Column(): + prompt_input = gr.Textbox( + label="提示詞 (Prompt)", + placeholder="例如: A cyberpunk cat holding a neon sign...", + lines=3 + ) + image_input = gr.Image( + label="參考圖 (可選,用於圖生圖)", + type="pil", + height=300 + ) + submit_btn = gr.Button("開始生成", variant="primary") + + with gr.Column(): + image_output = gr.Image(label="生成結果", format="png") + + submit_btn.click( + fn=synthesize, + inputs=[prompt_input, image_input], + outputs=image_output + ) + +if __name__ == "__main__": + app.launch(share=True) +``` + +當 Trae 提示運行成功後,點擊它提供的本地鏈接(通常是 http://127.0.0.1:7860)。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image9.png) + +如果一切正常,你會看到一個已經可以工作的 AI 繪圖界面。 + +這個界面看起來很簡單,但它已經具備了商業級繪圖工具中最核心的兩項能力,即文生圖和圖生圖。 + +* **左側:** **指令區 (** **Input** Zone) —— 你在這裡發號施令。 +* **Prompt (提示詞框):** 輸入你的創意描述(推薦使用英文)。 +* **Input** Image (參考圖框): + * **文生圖模式:** 保持此處 **為空** 。 + * **圖生圖模式:** 將本地圖片拖入此處,AI 會以它為基礎進行創作。 +* **Submit 按鈕:** 點擊即可發送指令,開始生成。 +* **右側:展示區 (** **Output** Zone) —— 見證奇蹟的地方,生成結果將在此顯示。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image10.png) + +現在我們可以嘗試生成你的第一張圖片了! + +本示例使用的 prompt 如下: + +> **A red apple** + +這是一個刻意簡化的示例,不包含任何風格或參數描述。 + +#### 實際流程 + +運行程式碼後,流程可以概括為三步: + +1. 將文字描述發送給模型 +2. 模型生成對應圖片 +3. 圖片被保存為本地文件 + +幾秒鐘後,你會在本地看到生成結果。而模型生成具有隨機性,所以相同的prompt會有不同的生成結果,你可以多次生成,選擇你心儀的圖片。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image11.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image12.png) + +也可以豐富你的提示詞,給予它更多的描述和限定。例如以下提示詞,得到的圖片就會更加特殊一些。 + +```Plain +"A hyper-realistic close-up of a fresh red apple with water droplets on its skin, sitting on a dark rustic wooden table. Cinematic dramatic lighting, rim light, shallow depth of field, bokeh background, 8k resolution, macro photography." +(一個超寫實的帶水珠的新鮮紅蘋果特寫,放在深色粗糙木桌上。電影級戲劇光效,輪廓光,淺景深,背景虛化,8k分辨率,微距攝影。) +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image13.png) + +在Output Image區域點擊下載圖片即可保存到本地。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image14.png) + +### 1.3 生圖模型常見的素材生成場景 + +在實際工作中,大模型生成圖片更多用於 **高效產出設計素材** ,而不是創作單張藝術作品。 + +當你觀察一些設計類營銷賬號的高贊案例時會發現,它們的產出大多集中在兩類場景: + +* **文生圖(從 0 到 1)** +* **有圖參考生圖(從 1 到 N)** + +#### 一、文生圖:快速獲取設計物料 + +這一類場景關注效率。當需要填補設計中的空白(如空狀態、頭像、配圖)時,AI 本質上充當的是一個 **即時生成的圖庫** 。 + +1. ##### 生成 UI 設計物料 + +* 流行趨勢:Dribbble 上常見的毛玻璃、黏土風 3D 圖標 +* 常見表現:通透材質、邊緣發光、糖果配色的功能或天氣圖標 + +**示例 Prompt:** + +> A set of 3D weather icons (sun, cloud, rain), glassmorphism style, frosted glass texture, soft pastel gradient colors, soft studio lighting, isometric view, transparent background, 4k. + +(一套 3D 天氣圖標,毛玻璃風格,磨砂質感,柔和漸變色,影棚光,等軸視圖) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image15.png) + +2. ##### 生成 Logo + +* 流行趨勢:極簡線條、幾何組合的科技感 Logo +* 常見表現:黑白配色、負空間設計、品牌感明確 + +**示例 Prompt:** + +> Minimalist vector logo design for a tech brand "Coffee Code", combining a coffee cup with coding brackets < >, flat design, solid black lines, white background, Paul Rand style, svg. + +(極簡矢量 Logo,結合咖啡杯與程式碼符號,扁平設計,純黑線條) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image16.png) + +3. ##### 生成官網用戶圖片 + +* 流行趨勢:SaaS 官網常用 3D 虛擬頭像,用於規避真人版權 +* 常見表現:友好表情、卡通比例、偏 Pixar 或 Memoji 風格 + +**示例 Prompt:** + +> Close-up portrait of a friendly young tech professional, smiling, Memoji 3D style, clay render, bright colors, soft lighting, solid plain background, Pixar character design. + +(友好的年輕科技從業者,3D Memoji 風格,黏土渲染) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image17.png) + +4. ##### 生成文章配圖 + +* 流行趨勢:科技公司博客中常見的抽象扁平插畫 +* 常見表現:紫藍配色、誇張人物比例、漂浮 UI 元素 + +**示例 Prompt:** + +> Editorial flat illustration representing remote work, a person sitting on a giant globe using a laptop, corporate memphis art style, vibrant colors (purple and teal), vector texture. + +(遠程辦公主題扁平插畫,企業孟菲斯風格) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image18.png) + +#### 二、有圖參考生圖:保持視覺一致性 + +這一類場景更關注 **擴展性** 。當你已經有一張滿意的主視覺,需要生成一整套風格一致的素材時使用。 + +5. ##### 主視覺相似的一套按鈕或交互素材圖 + +在遊戲開發中,UI 的一致性非常關鍵。假設你已經有了主界面的 **“PLAY”** 按鈕,現在需要擴展出一整套風格統一的功能按鈕(如暫停、設置、主頁)。僅靠手繪很難保證每個按鈕在光澤、透視和色值上的完全一致。 + +**基本操作流程:** + +1. 保存已有的藍色 “PLAY” 按鈕圖片 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image19.png) + +2. 將其拖入界面的 **Input**** Image** 區域,作為後續生成的參考母版 +3. 保持 prompt 中的風格描述不變,僅修改主體內容 + +在這一流程下,只要替換主體描述,就可以得到不同功能但風格一致的按鈕。 + +**示例 Prompt:** + +**變體 A:暫停按鈕(圖標類)** + +> A capsule-shaped game UI button with a white pause icon (two vertical bars) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(膠囊形遊戲 UI 按鈕,白色暫停圖標,藍色果凍質感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image20.png) + +**變體 B:設置按鈕(複雜圖標)** + +> A capsule-shaped game UI button with a white gear icon (settings symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(膠囊形遊戲 UI 按鈕,白色齒輪圖標,藍色果凍質感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image21.png) + +**變體 C:重玩按鈕(形狀變化)** + +如果需要調整按鈕外形,可以在 prompt 中直接描述形狀,模型會在保留材質特徵的同時嘗試改變結構。 + +> A round game UI button with a white circular arrow icon (replay symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality. + +(圓形遊戲 UI 按鈕,循環箭頭圖標,藍色果凍質感) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image22.png) + +通過這一組操作,你不僅可以替換按鈕功能和圖標,甚至改變按鈕形狀,但所有生成結果在材質、配色和光影上仍保持高度一致。這正是大模型在設計素材裂變場景中的核心價值。 + +## 第 2 章:更聽話的圖像生成助手 —— 以 Lovart 為例 + +在第一部分,我們通過程式碼直接調用 NanoBanana,體驗了“輸入即生成”的基礎流程。這種方式在需求簡單時沒有問題。但當生成任務開始包含更多約束,例如: + +* 需要多張風格一致的圖片 +* 需要在已有結果上反覆調整 +* 需要根據用戶輸入動態修改生成方向 + +單次調用的方式就會逐漸變得不夠用。 + +這時,就需要引入 **AI Agent(** **智能體** **)** 。本節以 **Lovart** 為例,展示當圖像生成模型具備“思考層”後,整體工作流會發生怎樣的變化。注意!這裡不是打廣告,只是幫助大家快速get到AI Agent的便捷性~ + +### 2.0 初識 Lovart:你的 AI 設計代理 + +Lovart 是一個基於 Agent 的設計工具 Web。相比普通生圖工具,它在生成之前多了一層“思考與規劃”。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image23.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image24.png) + +進入 Lovart 後,主要需要了解以下幾個控制項: + +#### 模型選擇 + +點擊輸入框下方的立方體圖標,可以查看當前可用的生成模型(如 GPT Image、Flux 等)。 + +為了與前文示例保持一致,本節仍然使用 NanoBanana 作為底層生成模型。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image25.png) + +#### 思考模式 + +這是 Lovart 的核心開關: + +* **Fast Mode(⚡)** :接近原生 API,響應快,適合單張、明確指令的生成 +* **Thinking Mode(💡)** :Agent 模式,AI 會先拆解需求、改寫 prompt,再執行生成 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image26.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image27.png) + +#### 聯網能力 + +開啟地球圖標後,Agent 可以在生成過程中檢索網路資訊(例如設計趨勢、配色風格),作為輔助輸入。 + +### 2.1 為什麼原生 API 還不夠? + +即使已經可以通過 Python 生成質量不錯的圖片,原生 API 在複雜任務中仍然存在限制。關鍵原因在於:原生 API 本質上是指令式的。當你要求它生成一個具體對象時,它可以直接執行;但當輸入變成“策劃一套完整的遊戲素材”時,它並不會主動將目標拆解為多個可執行步驟。 + +Lovart 的核心差異在於 Agent 機制。在用戶輸入與圖像生成模型之間,它加入了一層用於理解和規劃的邏輯:先識別用戶意圖,再拆解任務、重寫 prompt,最後才執行生成。 + +### 2.2 實戰演示:5 分鐘打造一套 IP 表情包 + +以 **“製作一套程序員鴨子 ****IP**** 表情包”** 為例,看看 Agent 是如何參與整個流程的。 + +#### 環節一:策劃(Agent 的思考能力) + +**原生 ****API**** 的問題:** +你需要自己思考角色設定、情緒狀態,併為每一張圖單獨編寫 prompt。 + +**Lovart 的做法:** + +1. 點亮 💡 **Thinking Mode** +2. 輸入一句指令: + +> 設計一套程序員鴨子的 IP 表情包,風格要扁平化、可愛 + +AI 不會立即畫圖,而是先去網路上搜索相關的程序員鴨子的設計圖。輸出一份拆解後的方案,自動生成 Debug、Coffee Break、Panic 等場景,並對應生成多條視覺描述。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image28.png)![](/zh-cn/stage-2/frontend/lovart-assets/images/image29.png) + +這一步,AI 從“執行者”轉變為“策劃者”。在AI幫你分析完需求後,可以在Lovart的畫布區看到多種風格和內容的程序員鴨子圖片。可以開始篩選你喜歡的風格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image30.png) + +#### 環節二:一致性(基於參考的視覺錨定) + +Lovart 中的圖片不僅是結果,也參與後續生成。 + +##### 完整參考圖 + +* 從草圖中選出一張最滿意的“標準鴨子”,在畫布區點擊對應圖片 +* 該圖將會自動出現在對話區,作為 Reference + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image31.png) + +* 輸入新的動作(如開心)並生成 + +生成結果會繼承母版的配色、比例和細節。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image32.png) + +##### 局部參考 / 多圖整合 + +除了整張圖片作為參考,Lovart 還支持: + +* **只選取圖片的局部區域** (例如只參考帽子或表情) + +點擊畫布區左側tab欄,選擇「Mark」鍵,在目標圖像的局部區域標記即可,這部分內容會自動同步到對話框。比如在這裡我們可以選擇修改背景的顏色。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image33.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image34.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image35.png) + +能看到新生成的圖片只改變了背景的顏色,這也跟我們輸入的要求一致。 + +* **從多張圖片中分別引用子元素** ,再組合生成新結果 + +例如:你可以保留 A 圖的角色主體,同時只替換帽子為 B 圖中的樣式,Agent 會在後臺自動整合這些視覺約束。 + +以程序員鴨子為例,我們可以選擇保留第一個圖中的鴨子形象,並將其替換到第二張圖中作為主體元素。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image36.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image37.png) + +最後的效果也非常顯著。你也可以試著其他的組合! + +#### 環節三:落地(Agent 的工具調用) + +生成完成後,可以直接執行:放大、移除背景、擦除等操作 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image38.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image39.png) + +這些並不是簡單濾鏡,而是 Agent 自動調度不同工具完成的結果。 + +而在確定完基調風格後,可以很快速的生成一系列的表情包圖像。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image40.png) + +最終我們得到的是可直接交付的生產級素材,而不僅是一張展示圖。 + +### 2.3 使用與收費方式說明 + +Lovart 採用訂閱制收費模式,不同套餐對應不同的使用額度與功能權限,具體以官網展示為準。 + +本教程不對任何套餐做推薦或比較;如果在實際使用中有需求,可以根據個人情況選擇付費升級。 +目前支持通過**支付寶**等方式完成支付。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image41.png) + +#### 小結 + +Lovart 並不是替代底層模型,而是通過 Agent 機制,讓圖像生成從“單次執行”升級為“連續工作流”。 + +當任務開始涉及策劃、一致性和交付時,這類工具的優勢會變得非常明顯。 + +## 第 3 章:自己動手做一個智能繪圖助手 + +除了直接使用 Lovart,我們也可以自己實現一個簡化版的繪圖助手。 + +本章以“文章自動配圖”為例,從實際問題出發,逐步搭建一個帶有思考能力的 Agent。 + +### 3.1 痛點引入:為什麼直接發文章給畫圖模型沒用? + +直接將一篇較長的文章輸入給 NanoBanana 並要求配圖,通常很難得到理想結果。原因並不在於模型“畫得不行”,而在於 **它並不擅長理解長文本** 。 + +圖像生成模型更適合處理簡短、明確的視覺描述,而當輸入變成一段包含結構、重點和上下文關係的文章時,模型無法判斷哪些內容才是畫面中真正需要表達的部分。這往往會導致生成結果偏離主題,或只能捕捉到零散細節,缺乏整體概括能力。 + +本質上,圖像模型只有“執行”的能力,卻缺少對文本進行分析和取捨的過程。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image42.png) + +### 3.2 解決思路:用 Agent 把「理解」和「執行」拆開 + +要解決這個問題,關鍵並不是更復雜的提示詞,而是 **在繪圖之前先把事情想清楚** 。因此,我們在生成流程中引入一個獨立的「思考層」,並以此構建一個最簡單可用的 Agent。 + +這個 Agent 的核心目標只有一個:**讓最終生成的圖片,儘可能貼近用戶真正的表達意圖。** + +整體流程可以概括為:**長文本輸入 → 語言模型理解與判斷 → 生成合適的視覺提示詞 → 圖像模型執行生成 → 輸出圖片** + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image43.png) + +那我們構建的 Agent 怎樣才能明白用戶的意圖呢? + +這裡選擇做一個簡化的 **“思考層”** ,我們設置了三種不同的意圖:無效輸入、直接生圖、需要理解的長文本。 + +在這個 Agent 中,各個角色的分工可以概括為四點: + +1. **語言模型作為決策核心** + 它負責理解文章內容、判斷用戶輸入的意圖,並將任務分發到合適的生成路徑中,決定接下來“該怎麼做”以及如何生成生圖提示詞。 +2. **圖像模型作為執行者** + 圖像模型不參與理解與判斷,只接收已經整理好的視覺指令,專注完成圖像渲染。 +3. **用戶作為可介入的引導者** + 除了直接輸入文本,用戶還可以在過程中手動調整生成的提示詞,或加入參考圖來輔助生成,從而對最終結果進行引導和微調。 +4. **Gradio 與後端 ****API**** 作為整體承載層** + 它們負責將界面、模型調用和結果展示串聯起來,保證整個 Agent 能夠以一個完整 Web 應用的形式穩定運行。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image44.png) + +### 3.3 實戰準備 :獲取API + +看起來是不是很有趣呢!要跑通上述流程,我們只需要準備兩類 API。 + +#### 手:NanoBanana API(圖像生成) + +直接沿用第 1 章中已經配置好的 API Key 和 API URL,無需額外設置。 + +#### 腦:SiliconFlow API(文本思考) + +我們需要一個大語言模型來承擔“思考層”的職責。本教程使用 SiliconFlow 提供的模型服務:[https://cloud.siliconflow.cn](https://cloud.siliconflow.cn/) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image45.png) + + SiliconFlow 提供了兼容 OpenAI API 規範的接口,可以非常方便地在項目中通過標準網路請求進行調用。在這裡我們選擇的是免費的Qwen2.5-7B-Instruct模型,調用需要的內容都已經寫入下面的Prompt。在開始之前,你只需要在官網註冊賬號並創建一個 API Key。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image46.png) + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image47.png) + + 該 Key 將用於後續的模型調用。 + +### 3.4 搭建Agent : + +本次實驗主要使用Trae來幫我們編寫程式碼,本教程選用的是Gemini-3-Pro-Preview模型。總思路是,新建項目後將下述完整 Prompt 複製到對話框並輸入,逐步替換 API KEY 後運行程式碼,完成測試即可。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image48.png) + +#### 環節1️⃣:Gradio Blocks 基礎框架與界面佈局 + +在這個環節,我們的主要目標是先給整個Agent搭建出一個“外觀”,實現前端的頁面設計。複製以下Prompt在Trae對話框中實現後,你將會得到一個本地的URL(通常是 http://127.0.0.1:7860 )即可查看界面,並且檢驗實現效果。 + +```Plain +板塊 1:Gradio Blocks 基礎框架與界面佈局 +1、任務目標 +·基於 Gradio 4.0.0+ 的 Blocks 佈局,實現「LLM+Nanobanana 文生圖」項目的基礎界面,嚴格遵循固定左右分欄佈局,初始化所有 UI 組件並設置正確的初始狀態。 + +2、技術棧要求 +·必須使用 Gradio 4.0.0+ 的 Blocks 模式開發,禁止使用 Interface 模式; +·依賴:gradio>=4.0.0,pillow>=10.0.0(僅導入,暫不實現圖片處理邏輯); +·程式碼需是完整可運行的 Python 文件,包含所有必要的導入語句。 + +3、界面佈局規則(核心約束,融合實戰細節) +·整體佈局: +頁面標題:LLM 驅動的文生圖全流程工具; +固定左右分欄:左側佔 60% 寬度,右側佔 40% 寬度,使用 gr.Row 和 gr.Column 實現比例控制。 +·左側 60%(提示詞生成流程區)組件清單: +input_text:gr.Textbox,標籤「輸入文本(教程段落 / 繪圖指令)」,lines=6,佔位符「請輸入需要配圖的教程文本或直接繪圖指令...」; +identify_intent_btn:gr.Button,value="識別意圖",初始狀態正常可點擊; +intent_status:gr.Textbox,標籤「意圖類型 / 處理狀態」,lines=2,interactive=False,初始值「未識別意圖」; +system_prompt:gr.Textbox,標籤「System Prompt(僅文章配圖意圖可編輯)」,lines=4,interactive=False,佔位符「LLM 生成提示詞的約束規則...」; +confirm_prompt_btn:gr.Button,value="確認生成生圖提示詞",interactive=False(初始禁用防誤觸); +generation_prompt:gr.Textbox,標籤「生圖提示詞(可編輯)」,lines=3,interactive=True,初始值為空,佔位符「生成的英文生圖提示詞將顯示在此,支持手動修改...」。 +·右側 40%(Nanobanana 生圖功能區)組件清單: +ref_image:gr.Image,標籤「參考圖(可選,圖生圖)」,type=filepath,height=300,允許上傳; +generate_btn:gr.Button,value="生成圖片",interactive=False(初始禁用,無提示詞不可點擊); +result_image:gr.Image,標籤「生成結果」,type=pil,height=300,初始為空,interactive=False。 + +4、交互邏輯要求 +·所有組件的 interactive 初始狀態嚴格按上述配置,後續通過函數動態更新; +·按鈕禁用狀態需直觀(置灰),避免用戶誤操作。 + +5、輸出要求 +·生成完整的 Python 程式碼,僅實現界面佈局和組件初始化,不包含任何業務邏輯; +·程式碼註釋清晰,組件命名與實戰版一致(input_text/identify_intent_btn 等); +·程式碼可直接運行,界面結構與描述完全一致。 +``` + +在瀏覽器打開http://127.0.0.1:7860後可看到Trae已經按照我們的要求生成了以下的網頁,跟我們的要求大致相當,可以進行到下一步的生成中了。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image49.png) + +#### 環節2️⃣:LLM 意圖識別模塊(Siliconflow API) + +在日常使用VLM畫圖的時候,可能有以下三種常見輸入情況: + +1. 無意義內容,比如“你好”、“你今天吃飯了嗎”等,無法畫出對應的圖片。 +2. 文章/長文本,字數較多,比如200字左右的一篇有結構的文章,需要先理解文章的結構與內容,再考慮如何生成能完整概括這段文字的圖片。 +3. 直接繪圖指令,比如“幫我畫一隻在洗澡的狗”等,要求已經闡述的非常具體,可以直接生成圖片。 + +跟前面一樣,複製以下Prompt在Trae對話框中實現,並且補充在前面步驟中獲得的API。 + +```Plain +板塊 2:LLM 意圖識別模塊(Siliconflow API) +1、任務目標 +在已實現的 Gradio 界面基礎上,為「識別意圖」按鈕添加點擊邏輯,調用 Siliconflow API 完成意圖識別,並聯動組件狀態。 + +2、技術棧要求 +基於 Gradio 4.0.0+ Blocks; +依賴:requests>=2.31.0,openai; +輸出完整可運行 Python 文件,包含板塊 1 界面 + 本模塊邏輯。 + +3、核心業務規則(絕對不可偏離) +·意圖分類規則(僅 3 類,嚴格返回數字 + 描述) +1 = 無意義內容:僅閒聊、寒暄、無關對話,沒有任何繪圖或配圖需求(如 “你好”“今天吃了嗎”); +2 = 文章 / 長文本配圖需求:用戶輸入一段完整文章、教程、段落、說明性文字,內容偏敘事 / 說明 / 講解,隱含需要為這段內容生成配圖的意圖,不需要用戶明確說 “為這段文字配圖”; +3 = 直接繪圖指令:用戶輸入簡短、明確的畫圖命令,沒有長文本背景,直接要求畫某個內容(如 “畫一隻 Apple 風格的貓”)。 +·LLM 調用約束(融合實戰版模板) +接口地址:https://api.siliconflow.cn/v1/chat/completions; +模型:Qwen/Qwen2.5-7B-Instruct; +temperature=0.1; +統一定義程式碼: +python +運行 +LLM_BASE_URL = "https://api.siliconflow.cn/v1" +LLM_API_KEY = "" # 用戶自行替換 +LLM_MODEL = "Qwen/Qwen2.5-7B-Instruct"# 實戰驗證的意圖識別模板(固化到程式碼中) +INTENT_PROMPT_TEMPLATE = """你需要識別用戶輸入文本的意圖,僅返回以下 3 類結果中的一種(格式:數字 + 中文描述): +1 = 無意義內容;2 = 文章 / 長文本配圖需求;3 = 直接繪圖指令。 + +用戶輸入:{user_input} + +識別結果: +僅提取返回結果中的數字和描述,禁止額外內容。""" + +4、組件聯動規則 +·結果為 1:intent_status 顯示「1 = 無意義內容:無繪圖需求」,system_prompt 保持禁用,confirm_prompt_btn 禁用; +·結果為 2:intent_status 顯示「2 = 文章 / 長文本配圖需求:為輸入內容生成配圖」,啟用 system_prompt 並填充默認規則,激活 confirm_prompt_btn; +·結果為 3:intent_status 顯示「3 = 直接繪圖指令:根據指令生成圖片」,system_prompt 禁用且填充默認規則,激活 confirm_prompt_btn。 + +5、異常處理 +API 異常、解析異常均給出友好提示,不崩潰,組件恢復初始狀態。 + +6、輸出要求 +生成完整可運行程式碼,替換 LLM_API_KEY 即可使用,邏輯清晰註釋完整,意圖識別模板嚴格使用實戰版。 +``` + +刷新之前的http://127.0.0.1:7860網址,開始測試是否能正確檢測三種情況。 + +1. 無意義內容,可以嘗試輸入“你好”、“謝謝”等,發現能夠正常識別。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image50.png) + +2. 文章/長文本,在這裡我們選用了一段豆包生成的描述人工智能的文字。你也可以嘗試使用自己的論文段落進行測試。 + +```Plain +人工智能正在以前所未有的深度和廣度重塑教育生態系統。通過自適應學習算法,AI系統能夠構建每個學生的認知圖譜,實時追蹤他們的知識掌握軌跡,並動態調整教學內容的難度和呈現方式。在傳統課堂環境中,教師往往難以同時滿足不同學習風格和能力水平的學生需求,而基於深度學習的教育平臺可以分析學生在交互式模擬實驗中的行為模式,識別他們在量子力學或微積分等複雜概念理解上的微妙障礙,並提供精準的認知支架。 + +高級自然語言處理引擎驅動的虛擬導師不僅能夠解構開放性問題,如"如何評價法國大革命對現代民主制度的影響",還能引導蘇格拉底式對話,激發批判性思維。當學生撰寫關於氣候變化對極地生態系統影響的論文時,AI寫作助手可以分析其論證邏輯的嚴密性,指出資料引用中的時效性問題,並建議更精準的科學術語。在特殊教育領域,計算機視覺技術使AI能夠識別自閉症譜系兒童在社交互動中的非語言線索,調整干預策略,而情感計算算法則幫助檢測在線學習時的挫折感,及時提供鼓勵性反饋。 + +然而,這種技術融合引發了一系列倫理困境。算法偏見可能無意中邊緣化特定文化背景的學生,資料採集的透明度問題引發了對學術隱私的關切,而過度依賴自動化評分系統可能削弱教師對學生思維過程的深層理解。更復雜的是,當AI開始生成高度逼真的虛擬實驗室體驗時,我們需要重新定義"實踐經驗"在教育中的價值。未來教育的範式可能演變為人類教師專注於培養創造力、同理心和道德判斷力,而AI系統則承擔知識傳遞、技能訓練和個性化評估的職能,形成一種協同進化的教育共生體,既能發揮機器的計算優勢,又能保留人類教育的獨特溫度. +``` + +同樣檢測成功~ + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image51.png) + +3. 直接繪圖指令,這裡輸入的是“我要畫一隻貓”,同樣檢測準確。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image52.png) + +到這裡我們就已經順利實現了第二個環節——意圖識別。 + +#### 環節3️⃣:生圖提示詞生成模塊(LLM 二次調用) + +意圖識別後,對於文章或長文本,還有很重要的一步就是生成畫圖的提示詞,而這正是本Agent的重點。 + +```SQL +板塊 3:生圖提示詞生成模塊(LLM 二次調用) +1、任務目標 +在意圖識別基礎上,實現「確認生成生圖提示詞」按鈕邏輯,調用 LLM 將文本優化為適合繪圖的英文視覺提示詞,填充到編輯框並聯動「生成圖片」按鈕。 + +2、技術棧要求 +同板塊 2,輸出完整程式碼 = 板塊 1 + 板塊 2 + 本模塊; +共用板塊 2 定義的 LLM_BASE_URL、LLM_API_KEY、LLM_MODEL,不新增密鑰。 + +3、核心業務規則(融合實戰版 Prompt 組裝邏輯) +·提示詞生成輸入規則(必須嚴格遵循) +生圖提示詞生成不再是簡單字符串拼接,而是構建標準 Chat 消息列表,程式碼結構如下: +python +運行 +messages=[# System角色:網頁上用戶最終確認/編輯後的system_prompt內容{"role": "system", "content": final_system_prompt},# User角色:承載待處理資料,明確任務目標{"role": "user", "content": f"請為以下內容生成視覺提示詞:\n\n{user_input}"}] +意圖為 2 時:System 內容取用戶編輯後的 system_prompt 最終版本; +意圖為 3 時:System 內容取禁用狀態下填充的默認規則 +user_input 為用戶最初輸入到 input_text 框的原始文本。 +·實戰驗證的 System Prompt 預設(固化到程式碼中) +python +運行 +SYSTEM_PROMPT_DEFAULT = """你現在是一個創建NanoBanana畫圖提示詞的助手。 +需要根據我的內容處理,我這個圖片的作用是能說明這一段在說什麼,並且讓大家知道這段話的上下結構就是整體說的是什麼意思。 +裡面可能會類似PPT有一些講解(如:左上角展示核心觀點,右下角展示資料)。 +設計風格要求:簡約,Apple設計思維(Apple Design Philosophy)。 +約束:請直接返回NanoBanana可用的英文提示詞,不要返回任何解釋、前綴或多餘的廢話。""" +·LLM 調用約束 +與板塊 2 共用同一套 LLM_BASE_URL、LLM_API_KEY、LLM_MODEL; +temperature=0.7(保證提示詞的創意性與適配性); +max_tokens=200(限制輸出長度,匹配提示詞約束); +嚴格使用上述標準 Chat 消息列表結構,禁止字符串拼接。 +·示例輸入輸出(核心參考) +輸入示例 1(文章配圖意圖):原始文本:「AI 如何改變教育:隨著人工智能技術的發展,教師的角色從知識傳授者轉變為引導者,AI 助手可輔助學生完成個性化學習,課堂上人機協作成為常態。」最終 System Prompt:SYSTEM_PROMPT_DEFAULT(未修改)輸出預期:"Minimalist illustration, Apple Design Philosophy, 1024x1024. Top left shows 'AI + Education' core concept, bottom right shows data of teacher-student-AI collaboration, soft color palette, clean lines, no redundant elements." +輸入示例 2(直接繪圖指令):原始文本:「畫一隻 Apple 風格的貓,坐在 MacBook 旁邊」最終 System Prompt:SYSTEM_PROMPT_DEFAULT(禁用狀態)輸出預期:"Minimalist cat, Apple style, 1024x1024, sitting next to a silver MacBook, clean white background, soft shadows, geometric shapes, no extra details." +·提示詞輸出強制約束 +純英文,無中文; +必須包含 Apple Design Philosophy/Apple style + 1024x1024; +長度 50–200 字符,程式碼內校驗; +無額外解釋、前綴或廢話,僅返回提示詞本身。 + +4、組件聯動規則 +生成成功:將提示詞填入 generation_prompt 框,激活 generate_btn,intent_status 追加「提示詞生成成功,可修改後生成圖片」; +生成失敗:提示具體原因(如 API 調用失敗、長度不達標),generate_btn 保持禁用,generation_prompt 框為空; +用戶手動修改 / 清空 generation_prompt 框: +清空時自動禁用 generate_btn; +非空時保持 generate_btn 激活。 + +5、異常處理 +API 調用失敗:友好提示「提示詞生成失敗:{具體錯誤資訊}」,不崩潰; +提示詞校驗失敗:明確提示原因(如 “未包含 Apple style”“長度僅 40 字符”),允許重試; +響應解析失敗:提示「無法解析 LLM 返回結果,請重試」。 + +6、輸出要求 +完整可運行程式碼,替換 LLM_API_KEY 即可使用; +程式碼結構清晰、註釋完善,界面美觀簡潔; +嚴格實現標準 Chat 消息列表結構,參數與示例邏輯一致; +包含提示詞長度、內容校驗邏輯,錯誤提示友好。 +``` + +同樣複製第二個環節的文本進行檢測。 + +值得注意的是,我們在這裡預設的生成生圖提示詞的System Prompt為: + +> 你現在是一個創建NanoBanana畫圖提示詞的助手。 +> 需要根據我的內容處理,我這個圖片的作用是能說明這一段在說什麼,並且讓大家知道這段話的上下結構就是整體說的是什麼意思。 +> 裡面可能會類似PPT有一些講解(如:左上角展示核心觀點,右下角展示資料)。 +> 設計風格要求:簡約,Apple設計思維(Apple Design Philosophy)。 +> 約束:請直接返回NanoBanana可用的英文提示詞,不要返回任何解釋、前綴或多餘的廢話。 + +如果你想換成其他的預設模版,可以在前面的prompt裡修改,或者直接在Trae裡通過對話修改。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image53.png) + +除了修改底層程式碼,我們在網頁上也可以快速編輯。舉個例子,我在這裡加了一句,“在前面加一句Pic Prompt”,可以看到生成的新的提示詞前面也包含了~這樣設計是為了方便快速修改生成提示詞的System Prompt,幫助我們快速切換風格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image54.png) + +#### 環節4️⃣:Nanobanana 文生圖 / 圖生圖模塊 + +終於來到了最後一步,不接入生圖模型,就不是一個完整的Agent! + +```Bash +板塊 4:Nanobanana 文生圖 / 圖生圖模塊(最終版) +1、任務目標 +實現「生成圖片」按鈕邏輯,調用真實 Nanobanana API,支持文生圖 / 圖生圖,解析 Base64 並展示圖片。 + +2、技術棧要求 +基於 Gradio 4.0.0+ Blocks; +依賴:requests, pillow, base64, io, re; +完整程式碼 = 板塊 1+2+3 + 本模塊。 + +3、核心 API 配置(實戰驗證固化) +固化程式碼配置: +python +運行 +# 固化到程式碼中的API配置 +NANOBANANA_API_URL = "https://api.zyai.online/v1/chat/completions" +NANOBANANA_MODEL = "gemini-2.5-flash-image" +NANOBANANA_API_KEY = "" # 用戶自行替換 +鑑權方式:Header Authorization: Bearer {NANOBANANA_API_KEY}。 + +4、圖片預處理要求(必須實現)實現函數 image_to_base64_data_uri (ref_image_path),核心邏輯: +將 PIL 圖片轉為 PNG 格式; +自動縮放到 1024x1024 分辨率; +透明通道轉為白色背景; +編碼為 Base64,返回格式:data:image/png;base64,...。 + +5、請求構建規則(嚴格按實戰版分支邏輯) +·核心函數定義實現函數 generate_image (prompt, ref_image_path): +入參:prompt(generation_prompt 框內容)、ref_image_path(ref_image 上傳的文件路徑); +返回:PIL Image(展示到 result_image)或錯誤提示。 +·邏輯分支 1:純文生圖(ref_image_path 為空) +python +運行 +messages = [{"role": "user", "content": prompt}] +·邏輯分支 2:圖生圖(ref_image_path 有值) +python +運行 +# 先調用圖片預處理函數 +image_base64 = image_to_base64_data_uri(ref_image_path) +messages = [{"role": "user","content": [{"type": "text", "text": prompt},{"type": "image_url", "image_url": {"url": image_base64}}]}] + +6、響應解析要求(必須兼容兩種格式)從 choices [0].message.content 中提取圖片 Base64,支持: +結構化 JSON 返回的 image_url 字段; +Markdown 格式 +; +統一提取 Base64 編碼,解碼後轉換為 PIL Image 返回。 + +7、組件聯動與異常處理 +生成成功:將 PIL Image 展示到 result_image,intent_status 提示「圖片生成成功」; +生成 / 解析 / 上傳失敗:在 intent_status 顯示清晰文字提示(如 “Base64 解析失敗”“API 調用超時”),不崩潰。 + +8、輸出要求 +完整可運行程式碼,替換 LLM_API_KEY 和 NANOBANANA_API_KEY 即可直接運行,全流程可用,分支邏輯嚴格匹配實戰版。 +``` + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image55.png) + +太令人激動啦!我們終於順利地生成出了這個Agent的第一張圖,仔細看看生成的圖片,跟我們的文本和提示詞是匹配的。到這裡你已經基本上實現你自己的Agent啦! + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image56.png) + +我們還添加了圖生圖功能,上傳你喜歡的圖片,AI會自動借鑑風格。 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image57.png) + +值得一提的是,前面步驟生成的提示詞也是可以在網頁上編輯的,並且我們是以最終點擊按鈕時的提示詞為準~哪怕我在這裡換成“a cute cat”,最終生成的圖片也只會是可愛的小貓。 + +## 第 4 章:總結 + +![](/zh-cn/stage-2/frontend/lovart-assets/images/image58.png) + +**嗚呼!終於寫完了。** +說實話,連我自己寫完最後一行的時候都忍不住長舒一口氣,更別說一路跟著做到這裡的你了。能把這一整套流程完整跑下來,本身就已經很厲害了,這說明你真的把手放到鍵盤上,把事情一步步做完了。Bravo 🎉 🥳 👏 + +在寫這套內容的過程中,我一直在想,我們到底要留下些什麼?答案其實並不是模型名字、參數或者某種固定套路,而是讓你慢慢建立起一種感覺:哪些事情可以放心交給 AI 去理解和規劃,哪些地方只需要你來決定方向。一旦這層分工成立,很多原本看起來複雜的生成流程,都會開始變得順起來。 + +回頭看,這條路其實並不複雜。想清楚你要解決的問題,把長文本交給語言模型去拆解,再把整理好的視覺意圖交給繪圖模型去呈現,最後把這一整套流程封裝成一個屬於你自己的小助手。到這裡,你已經不只是“在用模型”,而是在搭建一套可以長期陪你工作的系統,而這,才是這套教程最想帶給你的東西。 + +但是你已經做的很棒啦!相信學到這裡的你對Vibe Coding已經有初步的掌握了,給自己放個小假休息一下吧! + + diff --git a/docs/zh-tw/stage-2/frontend/modern-component-library/index.md b/docs/zh-tw/stage-2/frontend/modern-component-library/index.md new file mode 100644 index 0000000..d5a9a04 --- /dev/null +++ b/docs/zh-tw/stage-2/frontend/modern-component-library/index.md @@ -0,0 +1,465 @@ +# 使用現代組件庫更新你的界面 + +在前面的課程中,你已經學會了如何用設計工具畫出界面、用 AI IDE 把設計稿變成程式碼,甚至完成了一個完整的前端項目。但你可能也發現了一個問題:自己從零寫出來的按鈕、表單、彈窗,雖然能用,但總覺得和"專業產品"差了點意思——樣式不夠統一、交互細節不夠絲滑、適配不同屏幕也很頭疼。 + +這就是**組件庫**要解決的問題。 + +組件庫是一套預先設計好、開發好的 UI 零件集合。按鈕、輸入框、下拉菜單、對話框、表格……這些你在任何產品中都會反覆用到的界面元素,組件庫已經幫你做好了,而且經過了大量用戶的驗證和打磨。你只需要像搭積木一樣把它們組合起來,就能快速構建出專業級的界面。 + +## 你將學到 + +1. 理解什麼是前端組件庫,以及為什麼現代開發幾乎都在用它 +2. 認識四個最具代表性的組件庫,瞭解它們各自擅長的場景 +3. 通過三個實戰場景(落地頁、產品頁面、後臺管理),學會用 AI IDE + 組件庫進行 Vibe Coding +4. 學會閱讀組件庫文檔,根據需求找到合適的組件並正確使用 + +## 1. 為什麼需要組件庫? + +想象你在裝修房子。你可以自己從木頭開始做一把椅子,但更常見的做法是去宜家買一把——設計好看、質量穩定、說明書清晰,拿回家組裝就行。 + +組件庫就是前端開發中的"宜家"。它提供的不是傢俱,而是界面零件: + +| 自己手寫 | 使用組件庫 | +| :--- | :--- | +| 需要自己處理樣式、交互、動畫 | 開箱即用,樣式和交互已經打磨好 | +| 不同頁面的按鈕可能長得不一樣 | 全局風格統一,自動保持一致性 | +| 適配手機、平板需要額外工作 | 大多數組件庫已內置響應式支持 | +| 無障礙訪問(Accessibility)容易遺漏 | 專業組件庫已處理好鍵盤導航、屏幕閱讀器等 | +| 開發速度慢 | 開發速度快,專注業務邏輯 | + +簡單來說:**組件庫讓你把時間花在"做什麼"上,而不是"怎麼畫"上。** + +### 眼見為實:同一個需求,加不加組件庫的差距 + +光說不練沒有說服力。我們在 Trae 中用幾乎相同的需求,分別不指定和指定組件庫,看看生成結果的差距。 + +**提示詞一:不使用組件庫** + +```text +請幫我做一個 AI 寫作助手的資料儀表盤頁面,包含: +- 頂部標題欄和導出按鈕 +- 四張統計卡片顯示用戶數、活躍用戶、文檔數、收入,還要顯示漲跌趨勢 +- 一個折線圖和一個餅圖 +- 用戶列表表格,帶分頁功能 +- 左側導航側邊欄 +``` + +在 Trae 中直接運行後的效果: + + + + +**提示詞二:使用 shadcn/ui 組件庫** + +```text +請幫我做一個 AI 寫作助手的資料儀表盤頁面,用 shadcn/ui 組件庫來做,包含: +- 頂部標題欄和導出按鈕 +- 四張統計卡片顯示用戶數、活躍用戶、文檔數、收入,還要顯示漲跌趨勢 +- 一個折線圖和一個餅圖 +- 用戶列表表格,帶分頁功能 +- 左側導航側邊欄 +``` + +同樣在 Trae 中直接運行後的效果: + + + + +同樣的需求,唯一的區別只是在提示詞開頭加上了 `shadcn/ui + Tailwind CSS`,Trae 生成的結果在視覺一致性、交互細節、整體打磨程度上就完全不在一個層級。這就是組件庫帶來的"免費升級"——你只需要在提示詞裡多寫一個組件庫的名字。 + +## 2. 認識四個核心組件庫 + +組件庫數量眾多(完整列表見[附錄](#附錄-更多組件庫一覽)),但你只需要先認識這四個最具代表性的: + +| 組件庫 | 框架 | 一句話定位 | 官網 | +| :--- | :--- | :--- | :--- | +| [Ant Design](https://ant.design) | React | 螞蟻集團出品,企業級中後臺的事實標準,組件覆蓋面極廣 | ant.design | +| [shadcn/ui](https://ui.shadcn.com) | React | 不裝 npm 包,直接把程式碼複製到你項目裡,基於 Tailwind CSS,定製自由度最高 | ui.shadcn.com | +| [HeroUI](https://heroui.com)(原 NextUI) | React | 默認樣式精美、動畫流暢,適合對視覺品質有要求的落地頁和產品展示 | heroui.com | +| [Material UI](https://mui.com) | React | 最老牌的 React 組件庫,實現 Google Material Design 規範,生態最成熟 | mui.com | + +> Vue 用戶同樣有豐富選擇:[Element Plus](https://element-plus.org)(國內最流行)、[Ant Design Vue](https://antdv.com)、[Naive UI](https://www.naiveui.com) 等,詳見[附錄](#附錄-更多組件庫一覽)。 + +不同組件庫擅長不同場景。接下來我們通過三個真實開發場景,帶你體驗如何用 AI IDE + 組件庫進行 Vibe Coding。 + +為了展示不同組件庫的風格和特點,我們在每個場景中刻意選用了不同的庫。但請注意:**這只是為了讓你多見識幾種方案**,實際開發中你完全可以只用自己最順手的那一個。比如你喜歡 shadcn/ui 的風格,用它做落地頁、產品頁、後臺管理都沒問題。選一個你覺得好看、用著舒服的,比什麼都重要。 + +## 3. 實戰一:用 HeroUI 構建產品落地頁 + +**場景**:你做了一個 AI 寫作助手產品,需要一個漂亮的落地頁來展示產品特性、吸引用戶註冊。落地頁需要視覺衝擊力強、動畫流暢、在手機上也好看。 + +**為什麼選 HeroUI**:HeroUI 的默認樣式就很精美,自帶流暢的過渡動畫,非常適合面向用戶的展示型頁面。 + +### 3.1 創建項目 + +```bash +# 使用 HeroUI 官方 CLI 創建項目 +npx create-heroui-app@latest ai-writer-landing +cd ai-writer-landing +npm install +``` + + + + +### 3.2 用 AI IDE 生成落地頁 + +打開 AI IDE(Cursor、Trae 等),在對話框中輸入: + +```text +請幫我做一個 AI 寫作助手的落地頁,用 HeroUI 組件庫來做: + +**頁面結構:** +1. 頂部導航欄:左邊放 Logo 和產品名,右邊放"功能"、"定價"、"關於"三個鏈接,再加一個"開始使用"按鈕 +2. 首屏區域:大標題寫"讓 AI 成為你的寫作搭檔",副標題介紹產品價值,兩個按鈕"免費試用"和"查看演示",下面放一張產品截圖 +3. 功能展示:三列卡片,分別介紹"智能續寫"、"風格調整"、"多語言翻譯"三個功能,每張卡片要有圖標、標題、描述 +4. 定價區域:三個定價卡片(免費版、專業版、團隊版),專業版要突出顯示推薦 +5. 底部號召:一句吸引人的文案,加上註冊按鈕 +6. 頁腳:版權資訊和社交媒體鏈接 + +**設計要求:** +- 看起來要現代、專業 +- 支持暗色模式 +- 手機上看也要好看 +``` + + + + +### 3.3 AI 會用到的關鍵組件 + +AI 生成的程式碼中,你會看到這些 HeroUI 組件: + +```jsx +import { + Navbar, NavbarBrand, NavbarContent, NavbarItem, + Button, + Card, CardHeader, CardBody, CardFooter, + Divider, + Link, + Chip +} from '@heroui/react' +``` + +每個組件的作用: + +| 組件 | 用途 | 落地頁中的位置 | +| :--- | :--- | :--- | +| `Navbar` | 頂部導航欄 | 頁面最頂部,固定不動 | +| `Button` | 按鈕,支持多種變體和顏色 | CTA 按鈕、導航按鈕 | +| `Card` | 卡片容器 | 功能展示、定價卡片 | +| `Chip` | 小標籤 | "推薦"、"最受歡迎"標記 | +| `Divider` | 分割線 | 區域之間的視覺分隔 | + +### 3.4 迭代優化 + +生成的初版程式碼可能不完全滿意,繼續和 AI 對話調整: + +```text +請幫我優化一下落地頁: + +1. 大標題加上漸變色,從藍色漸變到紫色 +2. 功能卡片鼠標放上去要有上浮的動畫效果 +3. 專業版定價卡片要突出顯示,加個邊框和"最受歡迎"的標籤 +4. 手機上的導航改成漢堡菜單(三條橫線那種) +``` + + + + +> **Vibe Coding 的核心**:你不需要記住每個組件的 API,只需要用自然語言描述你想要的效果,AI 會幫你找到合適的組件和寫法。遇到不滿意的地方,繼續對話迭代就好。 + +## 4. 實戰二:用 shadcn/ui 構建產品頁面 + +**場景**:你的 AI 寫作助手需要一個用戶登錄後的主界面——左側是文檔列表,右側是編輯器,頂部有工具欄。這是一個功能型產品頁面,需要高度定製化的 UI。 + +**為什麼選 shadcn/ui**:shadcn/ui 把組件程式碼直接放進你的項目,你可以隨意修改任何細節。對於需要深度定製的產品界面,這種"擁有程式碼"的模式最靈活。 + + + + +### 4.1 創建項目 + +```bash +# 創建 Next.js 項目 +npx create-next-app@latest ai-writer-app --typescript --tailwind --app +cd ai-writer-app + +# 初始化 shadcn/ui +npx shadcn@latest init + +# 按需添加組件(不是一次性安裝所有組件) +npx shadcn@latest add button card input sidebar sheet dialog +``` + +shadcn/ui 的獨特之處:每次 `add` 一個組件,它會把源程式碼複製到你項目的 `components/ui/` 目錄下。你可以直接打開這些文件修改樣式和行為。 + +### 4.2 用 AI IDE 生成產品界面 + +```text +請幫我做一個 AI 寫作助手的主界面,用 shadcn/ui 組件庫來做: + +**整體佈局:** +- 左邊是可摺疊的側邊欄,寬度大概 280px: + - 頂部放"新建文檔"按鈕 + - 下面是文檔列表,每個文檔顯示標題和最後編輯時間 + - 右鍵點擊文檔可以重命名或刪除 +- 右邊是主編輯區,分成上下兩部分: + - 上面是工具欄:可以編輯文檔標題、顯示字數統計、"AI 續寫"按鈕、"導出"下拉菜單 + - 下面是編輯區域:一個大的文本輸入框,佔滿剩餘空間 + +**交互細節:** +- 點擊"AI 續寫"後,按鈕顯示加載狀態,編輯器底部出現 AI 生成的文本(像打字機一樣逐字顯示) +- 手機上側邊欄變成抽屜式,從左邊滑出 +- 當前選中的文檔要高亮顯示 +``` + + + + +### 4.3 AI 會用到的關鍵組件 + +```tsx +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Card, CardContent, CardHeader } from '@/components/ui/card' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@/components/ui/dropdown-menu' +import { + Sheet, + SheetContent, + SheetTrigger +} from '@/components/ui/sheet' +import { + Sidebar, + SidebarContent, + SidebarHeader +} from '@/components/ui/sidebar' +``` + +| 組件 | 用途 | 產品頁面中的位置 | +| :--- | :--- | :--- | +| `Sidebar` | 可摺疊側邊欄 | 左側文檔列表 | +| `Sheet` | 移動端抽屜 | 移動端側邊欄替代 | +| `DropdownMenu` | 下拉菜單 | "導出"按鈕、右鍵菜單 | +| `Dialog` | 對話框 | 重命名、刪除確認 | +| `Button` | 按鈕,支持 variant 和 loading | 各種操作按鈕 | +| `Input` | 輸入框 | 文檔標題編輯 | + +### 4.4 定製組件樣式 + +shadcn/ui 的優勢在於你可以直接修改組件源碼。比如你想讓按鈕的圓角更大: + +```text +請幫我修改 components/ui/button.tsx, +把所有按鈕的默認圓角從 rounded-md 改為 rounded-xl, +並給 primary 變體加上微妙的陰影效果 +``` + +AI 會直接修改你項目中的組件文件,而不是覆蓋 npm 包的樣式——這就是 shadcn/ui "擁有程式碼"的好處。 + + + + +## 5. 實戰三:用 Ant Design 構建後臺管理界面 + +**場景**:你的 AI 寫作助手上線後,需要一個管理後臺來查看用戶資料、管理文檔內容、處理付費訂單。後臺管理系統的核心是資料展示和操作效率。 + +**為什麼選 Ant Design**:Ant Design 在中後臺領域積累最深,表格、表單、圖表等業務組件開箱即用,內置了大量企業級交互模式(批量操作、高級篩選、資料導出等)。 + + + + +### 5.1 創建項目 + +```bash +# 使用 Ant Design Pro 腳手架(內置佈局、路由、權限) +npx create-umi@latest ai-writer-admin +# 選擇 Ant Design Pro 模板 +cd ai-writer-admin +npm install +``` + +或者從零開始: + +```bash +npx create-react-app ai-writer-admin --template typescript +cd ai-writer-admin +npm install antd @ant-design/icons @ant-design/pro-components +``` + +### 5.2 用 AI IDE 生成管理後臺 + +```text +請幫我做一個 AI 寫作助手的管理後臺,用 Ant Design 組件庫來做: + +**整體佈局:** +- 左邊是菜單欄:儀表盤、用戶管理、文檔管理、訂單管理、系統設置 +- 頂部顯示麵包屑導航 + +**用戶管理頁面:** +- 頂部放四個統計卡片:總用戶數、今日新增、活躍用戶數、付費用戶數 +- 搜索篩選區:可以按用戶名搜索、選擇註冊時間範圍、篩選用戶狀態,還有"搜索"和"重置"按鈕 +- 用戶表格: + - 顯示頭像、用戶名、郵箱、註冊時間、訂閱計劃(用不同顏色標籤區分)、狀態、操作 + - 每頁顯示 20 條,支持分頁 + - 可以批量選擇用戶,批量禁用或導出 + - 操作列:查看詳情、編輯、禁用(禁用前要二次確認) +- 點擊"查看詳情"從右側滑出抽屜,顯示用戶詳細資訊和最近文檔列表 +``` + + + + +### 5.3 AI 會用到的關鍵組件 + +```tsx +import { PageContainer, ProLayout } from '@ant-design/pro-components' +import { ProTable } from '@ant-design/pro-components' +import { StatisticCard } from '@ant-design/pro-components' +import { + Button, Tag, Badge, Space, Drawer, + Popconfirm, message, Modal +} from 'antd' +import { + UserOutlined, SearchOutlined, ExportOutlined +} from '@ant-design/icons' +``` + +| 組件 | 用途 | 後臺中的位置 | +| :--- | :--- | :--- | +| `ProLayout` | 後臺整體佈局框架 | 頁面骨架(菜單 + 內容區) | +| `ProTable` | 高級表格,內置搜索、分頁、列設置 | 用戶列表、文檔列表、訂單列表 | +| `StatisticCard` | 資料統計卡片 | 儀表盤、頁面頂部概覽 | +| `Tag` / `Badge` | 狀態標籤 | 訂閱計劃、用戶狀態 | +| `Drawer` | 側邊抽屜 | 用戶詳情、編輯表單 | +| `Popconfirm` | 氣泡確認框 | 刪除、禁用等危險操作 | + +### 5.4 繼續迭代:添加儀表盤 + +```text +請幫我做一個儀表盤頁面: + +1. 頂部四個統計卡片:總用戶數、總文檔數、今日 API 調用次數、月收入,每個卡片顯示數值和環比變化(漲了還是跌了) +2. 中間放兩個圖表: + - 左邊:最近 7 天的用戶增長折線圖 + - 右邊:訂閱計劃分佈餅圖 +3. 底部:最近操作日誌表格,顯示時間、用戶、操作類型、詳情 + +用 Ant Design 的組件來佈局,圖表可以用 Ant Design Charts +``` + + + + +> **後臺管理的 Vibe Coding 技巧**:後臺頁面結構相對固定(表格 + 搜索 + 彈窗),非常適合用 AI 批量生成。你可以先讓 AI 生成一個"用戶管理"頁面作為模板,然後說"參考用戶管理頁面的結構,幫我生成文檔管理頁面",AI 會複用相同的佈局模式。 + +## 6. 學會查文檔:組件庫的"說明書" + +Vibe Coding 中 AI 會幫你寫大部分程式碼,但當 AI 生成的結果不對、或者你想微調某個組件的行為時,**查文檔**是最快的解決方式。 + +以 Ant Design 為例,它的文檔地址是:`https://ant.design/components/overview-cn` + +查文檔的標準流程: + +1. **明確需求**:比如"我需要表格支持行選擇" +2. **在文檔中搜索**:搜索"Table"進入表格組件頁面 +3. **查看示例**:文檔中每個組件都有多個在線示例,找到"可選擇"示例 +4. **複製程式碼**:把示例程式碼複製到你的項目中 +5. **查看 API 表格**:在頁面底部找到 `rowSelection` 屬性的完整配置項 + +> 你也可以把文檔鏈接直接發給 AI IDE:"請參考 https://ant.design/components/table-cn 的 rowSelection API,幫我給用戶表格加上批量選擇功能"。給 AI 提供文檔鏈接,生成的程式碼會更準確。 + +各組件庫的文檔地址速查: + +| 組件庫 | 文檔地址 | +| :--- | :--- | +| Ant Design | `https://ant.design/components/overview-cn` | +| shadcn/ui | `https://ui.shadcn.com/docs/components` | +| HeroUI | `https://heroui.com/docs/components` | +| Material UI | `https://mui.com/material-ui/all-components/` | +| Element Plus | `https://element-plus.org/zh-CN/component/overview.html` | + +## 7. 小結 + +三個實戰場景覆蓋了最常見的前端開發需求: + +| 場景 | 推薦組件庫 | 核心特點 | +| :--- | :--- | :--- | +| 落地頁 / 展示頁 | HeroUI | 默認樣式精美,動畫流暢,視覺衝擊力強 | +| 產品功能頁面 | shadcn/ui | 程式碼完全可控,深度定製靈活 | +| 後臺管理系統 | Ant Design | 業務組件豐富,表格表單開箱即用 | + +Vibe Coding 的工作流總結: + +1. 根據場景選擇合適的組件庫 +2. 用 AI IDE 描述你想要的頁面結構和交互 +3. AI 生成初版程式碼,你預覽效果 +4. 用自然語言繼續迭代調整 +5. 遇到細節問題時查閱組件庫文檔 + +### 練習 + +選擇以下任一場景,用 AI IDE + 組件庫從零完成: + +1. 用 HeroUI 為你之前做的項目(比如霍格沃茨畫像)做一個展示落地頁 +2. 用 shadcn/ui 構建一個筆記應用的主界面(側邊欄 + 編輯器) +3. 用 Ant Design 構建一個簡單的內容管理後臺(文章列表 + 新建文章表單) + +--- + +## 附錄:更多組件庫一覽 + +除了正文介紹的四個核心庫,前端生態中還有大量優秀的組件庫。下面按框架分類列出,方便你根據項目需求選擇。 + +### Vue 生態 + +| 組件庫 | Stars | 簡介 | 適用場景 | +| :--- | :--- | :--- | :--- | +| [Element Plus](https://element-plus.org) | ~27k | 餓了麼團隊打造的 Vue 3 企業級組件庫,國內使用最廣泛,中文生態極佳 | 中後臺管理系統 | +| [Vuetify](https://vuetifyjs.com) | ~41k | 最流行的 Vue Material Design 組件庫,80+ 組件,文檔完善 | Google 設計風格項目 | +| [Ant Design Vue](https://antdv.com) | ~21k | 基於螞蟻設計體系的 Vue 3 組件庫,設計規範統一 | 企業級中後臺 | +| [Naive UI](https://www.naiveui.com) | ~18k | TypeScript 編寫,主題定製性極強,不依賴 CSS 預處理器 | 對設計有獨特要求的項目 | +| [Quasar](https://quasar.dev) | ~27k | 一套程式碼構建 SPA、SSR、PWA、移動端和桌面端應用 | 跨平臺項目 | +| [Vant](https://vant-ui.github.io/vant) | ~24k | 有贊團隊開發的輕量級移動端組件庫,覆蓋電商常見需求 | 移動端 H5 頁面 | +| [PrimeVue](https://primevue.org) | ~14k | 90+ 組件,支持多種主題(Material、Bootstrap 等) | 需要豐富組件和多主題 | +| [Arco Design Vue](https://arco.design/vue) | ~3k | 字節跳動出品,組件質量高,內置暗色模式 | 中後臺產品 | +| [TDesign Vue Next](https://tdesign.tencent.com/vue-next) | ~2k | 騰訊出品,設計語言統一,覆蓋桌面端常用場景 | 騰訊生態或企業級項目 | + +### React 生態 + +| 組件庫 | Stars | 簡介 | 適用場景 | +| :--- | :--- | :--- | :--- | +| [Material UI (MUI)](https://mui.com) | ~95k | Google Material Design 規範的老牌實現,組件最全面,生態最成熟 | 快速構建企業級應用 | +| [Ant Design](https://ant.design) | ~94k | 螞蟻集團出品,內置大量高質量業務組件,中文開發者社區主導地位 | 企業級中後臺 | +| [shadcn/ui](https://ui.shadcn.com) | ~83k | 程式碼複製到項目中而非 npm 安裝,基於 Radix UI + Tailwind CSS,完全可控 | 需要高度定製的項目 | +| [Chakra UI](https://chakra-ui.com) | ~39k | 以開發體驗為核心,API 簡潔,內置無障礙訪問支持 | 快速原型開發 | +| [Mantine](https://mantine.dev) | ~28k | 100+ 組件和 50+ hooks,涵蓋日期選擇器、富文本編輯器等高級組件 | 需要開箱即用的全功能方案 | +| [Headless UI](https://headlessui.com) | ~27k | Tailwind Labs 官方出品的無樣式組件庫,同時支持 React 和 Vue | 搭配 Tailwind CSS 使用 | +| [HeroUI](https://heroui.com) | ~24k | 基於 Tailwind CSS + React Aria,默認樣式精美,動畫流暢 | 追求視覺品質的項目 | +| [Radix UI](https://www.radix-ui.com) | ~17k | 無樣式底層組件原語庫,專注無障礙和組件行為,是 shadcn/ui 的底層基礎 | 構建自定義設計系統 | + +#### shadcn/ui 擴展生態 + +除了上述通用組件庫,shadcn/ui 生態中還湧現了大量基於其理念的擴展庫,為特定場景提供差異化選擇。這些擴展庫同樣採用"複製程式碼到項目"的模式,讓開發者擁有完全的源碼控制權。 + +| 組件庫 | 簡介 | 適用場景 | +| :--- | :--- | :--- | +| [Aceternity UI](https://ui.aceternity.com) | 200+ 生產級組件,主打發光卡片、文字漸變、3D 地球等特色視覺組件 | 高質感落地頁、SaaS 產品 | +| [Tailark UI](https://tailark.com) | 營銷網站組件塊集合,產品展示、客戶證言、CTA 按鈕等營銷高頻模塊 | 營銷落地頁、產品官網 | +| [UI Tripled](https://ui.tripled.work) | 基於 Framer Motion 的動態交互組件,彈窗、導航、卡片動畫 | 創意工具、個人作品集 | +| [Neobrutalism UI](https://neobrutalism.dev) | 新粗野主義風格,粗線條、高對比度、鮮明色彩 | 個性化品牌官網、創意項目 | +| [REUI](https://reui.io) | 967+ 真實業務場景的組件組合模式 | 企業級後臺、複雜表單 | +| [Cult UI](https://cult-ui.com) | 更細的交互/視覺打磨,資料表格、篩選面板等複合組件 | 高質感商業項目 | +| [Kibo UI](https://kibo-ui.com) | 高級業務組件,顏色選擇器、富文本編輯器、文件上傳等 | 管理後臺、工具類產品 | +| [Kokonut UI](https://kokonutui.com) | 100+ 組件 + 7+ 完整模板,清新簡約風格 | SaaS 官網、博客、電商 | +| [Commerce UI](https://ui.stackzero.co) | 電商場景專用,商品卡片、購物車、結算表單 | 電商平臺 | +| [shadcnblocks](https://shadcnblocks.com) | 1373 個 UI 塊 + 13 套完整模板,資源最全面 | 所有場景 | +| [Shoogle](https://shoogle.dev) | shadcn/ui 生態聚合檢索平臺 | 快速查找資源 | +| [Discover All Shadcn](https://allshadcn.com) | 聚合型資源導航 | 快速查找資源 | + +> **為什麼選擇 shadcn/ui 擴展?** 這些擴展繼承了 shadcn/ui"程式碼所有權"的理念,同時為特定場景做了深度定製。Vibe Coding 時代,它們讓你能快速找到符合設計需求的組件,跳出主流 UI 庫的同質化,做出更具差異化的產品。 diff --git a/docs/zh-tw/stage-2/frontend/multi-product-ui/index.md b/docs/zh-tw/stage-2/frontend/multi-product-ui/index.md new file mode 100644 index 0000000..1f67694 --- /dev/null +++ b/docs/zh-tw/stage-2/frontend/multi-product-ui/index.md @@ -0,0 +1,425 @@ +# 參考 UI 設計規範設計頁面和按鈕 + +很多人說"我想讓頁面更像 Apple 一點""按鈕想做得更高級一點",但真正開始做時,往往會卡在一個問題上: + +**到底該參考什麼?** + +盯著截圖模仿,學到的只是"像不像"。但打開 Apple、Google、Microsoft、Atlassian 的設計規範,你會發現它們真正厲害的地方不是視覺風格,而是**把設計問題講清楚**:頁面先突出什麼、按鈕如何分級、操作怎麼強調——這些判斷標準才是核心。 + +> 參考設計規範,不是為了做得"像誰",而是學會別人怎麼做判斷。 + +:::: info 為什麼現在還要學這些 +設計規則早已被訓練進模型、被設計工具默認吸收,甚至貼幾張截圖 AI 就能學會。但我們仍然有必要知道這些規則從哪來、為什麼這樣定。 +:::: + +## 先看幾段原文,感受差距 + +如果你以前覺得“設計規範不就是講講風格嗎”,先看幾條官方原文。 + +平時我們在團隊裡經常會這樣說: + +- 做個下拉框 +- 這裡放個菜單 +- 菜單欄加幾個功能 +- 這裡放兩個按鈕,一個確認一個取消 + +聽起來沒問題,但在大廠規範裡,這些詞都不是模糊概念,而是被拆得非常細。 + +| 平時隨口說的話 | 官方原文 | 簡單說 | +| :--- | :--- | :--- | +| “做個菜單” | Apple: [“A menu reveals its options...”](https://developer.apple.com/design/human-interface-guidelines/menus) | `Menu` 是拿來做操作的 | +| “菜單欄裡放功能” | Apple: [“menu bar menus contain all the commands...”](https://developer.apple.com/design/human-interface-guidelines/menus) | 這是應用頂部的命令菜單 | +| “做個下拉框” | Apple: [“A pop-up list lets the user choose one option among several.”](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pop-up` 是從列表裡選一個 | +| “也做個下拉框” | Apple: [“A pull-down list is generally used for selecting commands in a specific context.”](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) | `pull-down` 是點開做當前操作 | +| “菜單也能拿來篩選吧” | Fluent: [“If you need to collect information from people, try a select, dropdown, or combobox instead.”](https://fluent2.microsoft.design/components/web/react/core/menu/usage) | `Menu` 不是拿來選值的 | +| “菜單也能當導航吧” | Material: [“Menus should not be used as a primary method for navigation within an app.”](https://m1.material.io/components/menus.html) | `Menu` 不是主導航 | +| “按鈕隨便寫個 OK / Cancel” | Apple: [“Always use ‘Cancel’ to title a button that cancels the alert’s action.”](https://developer.apple.com/design/human-interface-guidelines/alerts) | 按鈕文字不能隨便寫 | + +> 表格裡的引文都可以直接點擊,跳到對應的官方頁面。 + +這就是第一次真正看設計規範時最容易被震到的地方: + +> 我們平時以為自己在討論 UI,實際上很多時候只是在用一堆含糊詞交流。 + +Apple 不會只說“做個菜單”;它會繼續區分: + +- `menu` +- `menu bar menu` +- `pop-up button` +- `pull-down button` +- `context menu` + +Fluent 不會只說“下拉框”;它會繼續區分: + +- `menu` +- `dropdown` +- `select` +- `combobox` + +這就是設計規範的必要性。 + +它不是為了讓頁面顯得更專業,而是為了讓團隊在討論 UI 時,不再每個人腦子裡都是不同的東西。 + +## 你將學到 + +1. 為什麼設計頁面和按鈕時要先看設計規範 +2. Apple、Material、Fluent、Atlassian 這些規範裡,哪些內容最值得參考 +3. 如何把“頁面層級”和“按鈕層級”設計清楚 +4. 如何讓 AI 參考別人的規範來生成頁面和按鈕 + +## 1. 設計規範為什麼能幫你把頁面做清楚 + +看完上面這些原文,你會發現一個關鍵點: + +**設計規範不是錦上添花,而是在先把詞說準。** + +很多頁面不好看,不是因為配色不夠高級,而是因為資訊層級混亂。 + +很多按鈕不好用,也不是因為圓角不對,而是因為: + +- 主按鈕太多,用戶不知道該點哪個 +- 危險按鈕和普通按鈕看起來差不多 +- 頁面裡所有按鈕都在搶注意力 +- 不同頁面裡的按鈕樣式和語義不一致 + +成熟的設計規範,恰好就是在解決這些問題。它們通常會定義: + +| 規範內容 | 它解決什麼問題 | +| :--- | :--- | +| **頁面層級** | 先看哪裡、後看哪裡,資訊怎麼組織 | +| **視覺基礎** | 顏色、間距、字體、圓角、陰影怎樣統一 | +| **按鈕層級** | 主按鈕、次按鈕、文字按鈕、危險按鈕如何區分 | +| **狀態規則** | hover、focus、disabled、loading 怎麼表現 | +| **交互語義** | 哪個按鈕是“確認”,哪個是“取消”,哪個是“更多操作” | + +所以,設計規範真正提供的不是一套“皮膚”,而是一套**判斷標準**。 + +## 2. 參考大廠規範時,重點看什麼 + +### 2.1 參考 Apple:學習“定義得足夠細”這件事 + +Apple 最值得學的,不只是視覺上的剋制感,而是它會把概念定義得非常細。 + +同樣是很多團隊口中的“菜單”或“下拉框”,Apple 會繼續往下拆: + +- `menu`:一組命令、選項或狀態 +- `menu bar menu`:應用級命令集合 +- `pop-up button`:選擇一個值 +- `pull-down button`:在當前上下文裡觸發命令 +- `context menu`:與當前對象或任務相關的常用動作 + +這套區分非常重要,因為它會直接影響: + +- 這個組件是拿來選值,還是拿來做動作 +- 它屬於頁面局部,還是屬於應用級 +- 它應該長期顯示當前選中值,還是隻臨時展開命令 + +當你開始按這種粒度思考時,你設計出來的頁面就會一下子清楚很多。 + +### 2.2 參考 Apple:學習頁面層級和剋制感 + +Apple Human Interface Guidelines 特別適合學習兩件事: + +- 頁面如何建立清晰層級 +- 控件如何在不喧賓奪主的前提下保持明確 + +Apple 強調 `Hierarchy`、`Harmony`、`Consistency`。這意味著頁面設計時要回答: + +- 當前頁面最重要的資訊是什麼 +- 用戶的主要任務是什麼 +- 哪個操作該最顯眼,哪個操作應該退後 + +如果你參考 Apple 來設計頁面,可以重點借鑑: + +- 首屏資訊不要太碎,核心內容先聚焦 +- 用留白、字號、分組建立秩序,而不是靠堆很多邊框 +- 按鈕不要全部高強調,只有關鍵動作才應該最突出 + +### 2.3 參考 Material:學習清晰的頁面結構 + +Material Design 很適合學習“頁面是怎麼組織任務流”的。 + +它的很多組件和佈局規範,核心都在幫助你明確: + +- 頁面是瀏覽型,還是執行任務型 +- 當前頁面是讓用戶閱讀、選擇,還是提交 +- 一個頁面裡哪些元素應該穩定重複,哪些元素應該響應上下文變化 + +如果你參考 Material 來設計頁面,可以重點借鑑: + +- 頁面區塊清楚,模塊職責明確 +- 導航、內容區、操作區分工清晰 +- 不同按鈕樣式對應不同操作優先級 + +### 2.4 參考 Fluent:學習組件邊界和按鈕層級 + +Fluent 2 很適合後臺、工具型產品和複雜表單系統。它最值得學的地方,是會直接告訴你“不要混用概念”。 + +例如它明確寫到:如果你要“collect information”,就不要繼續用 `menu`,而應該考慮 `select`、`dropdown`、`combobox`。 + +這句話非常重要,因為它把很多人腦中的“都差不多”打碎了。 + +Fluent 2 也很重視: + +- 操作層級 +- 組件語義邊界 +- 密集資訊場景下的清晰度 + +如果你參考 Fluent 來設計按鈕,可以重點借鑑: + +- `Primary button` 用來承接當前最重要的動作 +- `Secondary button` 用來承接支持性動作 +- `Subtle`、`Transparent` 這類弱強調按鈕用於不該搶主流程的操作 +- 頁面裡的按鈕數量越多,越要控制視覺優先級 + +### 2.5 參考 Atlassian:學習系統化地管理頁面和按鈕 + +Atlassian Design System 特別適合“一個團隊做很多頁面”的情況。它強調: + +- foundations 是共享基礎 +- tokens 是統一視覺決策的方法 +- components 是被反覆複用的交互構件 + +如果你參考 Atlassian 來做頁面和按鈕,最有價值的是: + +- 把按鈕尺寸、顏色、圓角、間距做成統一規則 +- 把頁面佈局的節奏固定下來 +- 讓不同頁面雖然內容不同,但結構語言一致 + +## 3. 設計頁面時,應該參考規範裡的哪些點 + +當你看一個設計系統時,不要先問“這個頁面好不好看”,而要先問下面幾個問題。 + +### 3.1 頁面第一眼,主次是不是明確 + +一個頁面通常至少要有三層: + +- **主資訊**:當前頁面最重要的內容 +- **輔助資訊**:幫助理解或補充的內容 +- **次級操作**:不應該干擾主任務的動作 + +如果三層沒有拉開,頁面就會“都重要”,等於“都不重要”。 + +### 3.2 頁面佈局,是不是服務任務而不是堆模塊 + +參考規範時,可以特別注意: + +- 標題區有沒有明確頁面目標 +- 主內容區是不是圍繞任務組織 +- 操作按鈕是不是貼近相關內容 +- 次要資訊有沒有被弱化 + +### 3.3 頁面裡的操作,是不是有優先級 + +很多頁面一眼看過去有 6 個按鈕,結果每個按鈕都像 CTA,這是典型的層級失控。 + +更合理的方式是: + +- 一個區域通常只有一個主動作 +- 次級動作可以用描邊、文字按鈕或更弱的樣式 +- 風險動作不要和主動作長得一樣 + +## 4. 設計按鈕時,應該參考規範裡的哪些點 + +按鈕是最容易被“隨手設計”的部分,但也是最能暴露系統是否成熟的部分。 + +### 4.1 按鈕先分“語義”,再分“樣式” + +不要先想“藍色按鈕還是黑色按鈕”,先想這個按鈕是什麼角色。 + +常見按鈕角色可以這樣分: + +| 按鈕類型 | 作用 | 常見樣式策略 | +| :--- | :--- | :--- | +| **Primary** | 當前區域最關鍵動作 | 實心、高對比、最顯眼 | +| **Secondary** | 支持性動作 | 描邊或低一級強調 | +| **Tertiary / Text** | 弱操作 | 文字或低視覺佔比 | +| **Destructive** | 刪除、停用、清空等風險操作 | 警示色或明確風險樣式 | +| **Icon button** | 局部工具操作 | 簡潔、靠近上下文 | + +### 4.2 一個頁面不要有太多 Primary Button + +這是很多新手最容易踩的坑。 + +如果頁面上有 4 個主按鈕,那麼等於沒有主按鈕。主按鈕的意義本來就是“告訴用戶現在最應該做什麼”。 + +你可以借鑑很多設計系統的共同做法: + +- 一個主要區域通常只保留一個主按鈕 +- 取消、返回、關閉一般不和確認按鈕搶同級 +- 更多操作放到次級按鈕或菜單中 + +### 4.3 按鈕要能表達狀態變化 + +設計規範通常會對按鈕狀態寫得很清楚: + +- 默認態 +- 懸停態 +- 聚焦態 +- 禁用態 +- 加載態 +- 危險態 + +這很重要,因為按鈕不是一張靜態圖,而是用戶操作過程中最常被觸發的控件之一。 + +### 4.4 按鈕文案,也屬於設計的一部分 + +按鈕文案不只是“文案問題”,它直接影響用戶理解。 + +例如: + +- `保存` +- `保存更改` +- `立即發佈` +- `刪除項目` +- `移到回收站` + +這些文案傳達的心理預期完全不同。成熟規範通常會要求按鈕標籤清楚表達動作,而不是使用含糊詞。 + +## 5. 一個很實用的頁面與按鈕設計清單 + +你自己設計頁面時,可以先快速過一遍這張清單: + +### 頁面清單 + +- 頁面標題是否清楚說明當前任務 +- 首屏最重要的資訊是否一眼可見 +- 頁面是不是按任務流程組織,而不是按想到什麼放什麼 +- 同一個區域裡是否只有一個主要動作 +- 次要內容是否被適當弱化 + +### 按鈕清單 + +- 這個按鈕是主動作還是次動作 +- 它為什麼值得比別的按鈕更顯眼 +- 頁面裡是不是有太多主按鈕 +- 危險操作是否被明確標識 +- 按鈕文案是否足夠具體 + +## 6. 怎樣用 AI 參考別人的規範來設計頁面 + +這一節最實用。 + +很多人讓 AI 設計頁面時,只會說: + +```md +幫我做一個設置頁面,要高級一點,參考蘋果風格 +``` + +這類提示詞太模糊了,AI 最後通常只能模仿“白底、圓角、陰影”。 + +對新手來說,更實用的方式不是自己總結一大段,而是直接把**規範原文裡的關鍵句**貼給 AI。 + +這樣做有兩個好處: + +- 你不用自己先“翻譯”一遍設計思想 +- AI 更容易按官方定義去理解頁面和按鈕 + +### 6.1 例子一:讓 AI 參考 Apple 設計一個設置頁面 + +先找一句 Apple 原文: + +> ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) + +你可以直接這樣貼給 AI: + +```md +參考 Apple Human Interface Guidelines 裡的這句話: +"Establish a clear visual hierarchy..." + +幫我設計一個賬號安全設置頁面。 +要求頁面層級清楚,重要資訊放前面,分組整齊一點。 +``` + +這樣寫的重點是:不用你自己解釋太多,直接把 Apple 的原話貼進去。 + +### 6.2 例子二:讓 AI 參考 Fluent 設計後臺頁面按鈕 + +先找一句 Fluent 原文: + +> ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +你可以直接這樣貼給 AI: + +```md +參考 Fluent 2 裡的這句話: +"Only use one primary button in a layout..." + +幫我設計一個團隊管理後臺的按鈕。 +添加成員按鈕最明顯,導出、篩選、更多操作弱一點,刪除按鈕單獨突出。 +``` + +這一句非常適合新手,因為它直接告訴 AI:一個區域不要放太多主按鈕。 + +### 6.3 例子三:讓 AI 同時參考頁面規範和按鈕規範 + +你也可以一次貼兩句原文,讓 AI 同時參考頁面和按鈕: + +> Apple: ["Establish a clear visual hierarchy..."](https://developer.apple.com/design/human-interface-guidelines/) +> +> Fluent: ["Only use one primary button in a layout..."](https://fluent2.microsoft.design/components/web/react/core/button/usage) + +然後直接這樣寫: + +```md +參考下面兩句設計規範原文: +Apple: "Establish a clear visual hierarchy..." +Fluent: "Only use one primary button in a layout..." + +幫我設計一個項目詳情頁。 +頁面包含項目介紹、成員、最近活動和設置入口。 +頁面層級清楚一點,主按鈕只保留一個,其他按鈕弱一點。 +``` + +這種方式特別適合新手,因為你只要會複製原文,再加兩句自己的需求就夠了。 + +## 7. 怎樣用 AI 參考按鈕規範來直接生成按鈕設計 + +如果你只想先做按鈕,也可以直接貼按鈕規範原文。 + +例如 Atlassian 對按鈕的定義很短: + +> ["A button triggers an event or action."](https://atlassian.design/components/button/) + +你可以這樣問 AI: + +```md +參考 Atlassian 的這句話: +"A button triggers an event or action." + +幫我設計一套後臺頁面按鈕樣式。 +我要有主按鈕、次按鈕、刪除按鈕,順便告訴我分別用在什麼地方。 +``` + +這類提示詞尤其適合新手,基本就是“貼原文 + 說需求”。 + +## 8. 小結 + +參考 UI 設計規範設計頁面和按鈕,最重要的不是“做得像誰”,而是學會下面這幾件事: + +1. 用層級組織頁面,而不是把內容堆上去 +2. 用按鈕分級表達操作優先級,而不是讓所有按鈕都一樣搶眼 +3. 用設計規範裡的定義、邊界和判斷標準指導設計 +4. 讓 AI 參考別人規範時,參考的是“原則和結構”,而不是隻參考皮膚 + +當你這樣使用規範時,你參考到的就不只是一個風格,而是一套成熟的設計思考方式。 + +--- + +## 參考資料 + +以下鏈接都來自官方設計系統或官方文檔: + +- Apple Human Interface Guidelines: [Overview](https://developer.apple.com/design/human-interface-guidelines/) +- Apple Human Interface Guidelines: [Menus](https://developer.apple.com/design/human-interface-guidelines/menus) +- Apple Human Interface Guidelines: [Alerts](https://developer.apple.com/design/human-interface-guidelines/alerts) +- Apple Human Interface Guidelines: [Buttons](https://developer.apple.com/design/human-interface-guidelines/buttons) +- Apple Archive: [How Menus Work](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/HowMenusWork.html) +- Apple Archive: [Managing Pop-Up Buttons and Pull-Down Lists](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/ManagingPopUpItems.html) +- Material Design: [Buttons overview](https://m3.material.io/components/buttons/overview) +- Material Design: [Menus](https://m1.material.io/components/menus.html) +- Microsoft Fluent 2: [Start designing](https://fluent2.microsoft.design/get-started/design) +- Microsoft Fluent 2: [Menu usage](https://fluent2.microsoft.design/components/web/react/core/menu/usage) +- Microsoft Fluent 2: [Button usage](https://fluent2.microsoft.design/components/web/react/core/button/usage) +- Atlassian Design System: [Foundations](https://atlassian.design/foundations/) +- Atlassian Design System: [Button](https://atlassian.design/components/button/) diff --git a/docs/zh-tw/stage-2/frontend/ui-design/index.md b/docs/zh-tw/stage-2/frontend/ui-design/index.md new file mode 100644 index 0000000..cf97d0a --- /dev/null +++ b/docs/zh-tw/stage-2/frontend/ui-design/index.md @@ -0,0 +1,3 @@ +# 構建第一個現代應用程序 - UI 設計 + +> 本章節正在編寫中,敬請期待... diff --git a/docs/zh-tw/stage-2/index.md b/docs/zh-tw/stage-2/index.md index 2ef1e58..fe3f6f7 100644 --- a/docs/zh-tw/stage-2/index.md +++ b/docs/zh-tw/stage-2/index.md @@ -1,118 +1,185 @@ # 初中級開發 -歡迎來到 **初中級開發** 階段!在這裡,你將深入全棧開發,掌握前端組件化、數據庫設計、後端 API 開發與部署上線。 +歡迎來到 **初中級開發** 階段!在這裡,你將深入全棧開發,掌握前端組件化、資料庫設計、後端 API 開發與部署上線。 ## 你將學到什麼 ### 前端開發 掌握現代前端開發,學習組件庫與設計工具的使用: + + + + +### 後端開發 -### 後端與全棧 +學習 API 設計、資料庫管理以及應用部署策略: -學習 API 設計、數據庫管理以及應用部署策略: - - - + + - ### 大作業 -通過實戰項目鞏固你的全棧開發技能: +前面的章節是在學「零件」,大作業才是在學「怎麼把零件裝成一個能跑、能演示、能上線的產品」。 + +建議你按 **大作業 1 -> 大作業 2** 的順序來做: + +- **大作業 1** 先帶你跑通現代 SaaS 最常見的主鏈路:登錄、生成、資料庫、支付、管理後台。 +- **大作業 2** 再帶你進入更像業務系統的場景:角色權限、題庫、考試、提交記錄、管理台。 + +```mermaid +flowchart LR + A["前端頁面與組件"] --> B["資料庫與接口"] + B --> C["大作業 1
文案生成 SaaS"] + C --> D["支付 / 部署 / 後台管理"] + D --> E["大作業 2
在線考試系統"] + E --> F["完整全棧作品集"] +``` + +如果你不知道先做哪個,可以直接參考下面這張對比表: + +| 項目 | 你會重點練到什麼 | 最適合誰 | 最終交付物 | +|------|------|------|------| +| 大作業 1:文案生成網站 | SaaS 頁面結構、用戶登錄、AI 生成、Stripe 支付、後台管理 | 第一次做完整商業化網站的人 | 一個可註冊、可生成、可付費、可管理的 SaaS 雛形 | +| 大作業 2:在線考試與管理系統 | 角色權限、題庫建模、考試流程、提交記錄、批改與統計 | 想把「業務系統」真正做完整的人 | 一個有學生端和管理端的考試平台 | + +無論做哪一個,大作業都建議至少準備這 3 個交付物: + +- 一個可運行的項目倉庫 +- 一個可訪問的演示鏈接 +- 一份 README 和一段演示影片 + +如果你已經完成了上面兩個主線項目,或者想按自己的技術方向做作品集,可以繼續從下面這些擴展選題裡選一題深入: + + + + + + + + + ### AI 能力擴展 + - - ## 適合人群 -- 有一定編程基礎,想系統學習全棧開發的開發者 +- 有一定程式設計基礎,想系統學習全棧開發的開發者 - 希望從產品經理轉型為全棧工程師的學習者 - 想要掌握現代開發工具和工作流的初中級開發者 - 希望獨立開發完整產品的創業者 @@ -121,6 +188,6 @@ - 完成「新手與產品原型」階段,或具備同等基礎知識 - 了解基本的 HTML/CSS/JavaScript 概念 -- 對 AI 編程工具有初步了解 +- 對 AI 程式設計工具有初步了解 準備好深入全棧開發了嗎?點擊左側導航開始學習吧!