Spaces:
Sleeping
Sleeping
| # AI API éçºã¬ã€ã | |
| ãã®ããã¥ã¡ã³ãã¯ãHugging Face SpacesãšGradioãå©çšããAI APIã®éçºç°å¢æ§ç¯ãšããã®åŸã®éçºããã»ã¹ã«é¢ããèŠç¹ããŸãšãããã®ã§ãã | |
| ## 1. æŠèŠ | |
| ### 1.1. ç®çãšæ©èœæŠèŠ | |
| æ¬ãããžã§ã¯ãã®ç®çã¯ãã芪åã§éãŒããããã«AIãæŽ»çšãã**å£ã³ãã®èªåèŠçŽæ©èœ**ãå®è£ ããããšã§ãã | |
| - **ç®ç:** ãŠãŒã¶ãŒã倿°ã®å£ã³ããå šãŠèªãã§ããæœèšã®å šäœçãªè©å€ãçŽ æ©ãããã€å®¢èгçã«ææ¡ã§ããããã«ããã | |
| - **ãŠãŒã¶ãŒäœéš:** | |
| 1. ãŠãŒã¶ãŒã¯æœèšã®è©³çްããŒãžã§ãå£ã³ããAIèŠçŽããã¿ã³ãã¯ãªãã¯ããŸãã | |
| 2. AIããã®æœèšã®å šå£ã³ããåæãããããžãã£ããªç¹ããšã泚æãå¿ èŠãªç¹ããªã©ããŸãšããäžç«çãªèŠçŽæãçæããŸãã | |
| 3. çæãããèŠçŽãã¢ãŒãã«ãŠã£ã³ããŠçã§è¡šç€ºããããŠãŒã¶ãŒã¯çæéã§æœèšã®é·æãšçæãçè§£ã§ããŸãã | |
| ### 1.2. ã¢ãŒããã¯ãã£æŠèŠ | |
| ãã®æ©èœã¯ãDjangoã¢ããªã±ãŒã·ã§ã³ãšãHugging Face Spacesäžã§åäœããGradio APIãšã®é£æºã«ãã£ãŠå®çŸããŸãã | |
| - **éçºç°å¢:** Dockerã³ã³ããå ã§éçºã»ãã¹ããè¡ãã | |
| - **ããŒãžã§ã³ç®¡ç:** Gitã§ã³ãŒãã管çããã | |
| - **CI/CD:** GitHub Actionsã§ãã¹ããšãããã€ãèªååããã | |
| - **æ¬çªç°å¢:** Hugging Face Spacesã«ãããã€ããAPIãå ¬éããã | |
| ### 1.3. æè¡éžå®çç± | |
| - **Hugging Face Spaces:** | |
| - **éžå®çç±:** ç¡ææ ãå©çšå¯èœã§ãè¿ éãªãããã¿ã€ãã³ã°ã«é©ããŠããŸãããŸããGitHubãªããžããªãšé£æºããèªåãããã€æ©èœïŒCI/CDïŒãæšæºã§æäŸãããŠãããéçºäœéšãéåžžã«ã¹ã ãŒãºã§ãã | |
| - **ä»£æ¿æ¡ãšã®æ¯èŒ:** AWS LambdaãGoogle Cloud Functionsã®ãããªãµãŒããŒã¬ã¹ç°å¢ãèããããŸããããããã¯ã³ã³ããã€ã¡ãŒãžã®ãµã€ãºå¶éãå³ãããå€§èŠæš¡ãªAIã¢ãã«ã®ãããã€ã«ã¯è¿œå ã®å·¥å€«ãå¿ èŠã§ããHugging Face Inference APIã¯æãæè»œã§ãããã«ã¹ã¿ã ããžãã¯ã®è¿œå ãUIã®æäŸãã§ããªããããä»åã¯Gradioãšçµã¿åãããããSpacesãéžæããŸããã | |
| - **Gradio:** | |
| - **éžå®çç±:** æ°è¡ã®ã³ãŒãã§AIã¢ãã«ã®ãã¢UIãšAPIãšã³ããã€ã³ããåæã«äœæã§ãããããéçºé床ãå€§å¹ ã«åäžãããŸããç¹ã«ãåäœç¢ºèªçšã®UIãèªåã§çæãããç¹ã¯ãéçºåææ®µéã§ã®å®éšããããã°ã«ãããŠå€§ããªå©ç¹ãšãªããŸãã | |
| ### 1.4. ã¢ãŒããã¯ãã£å³ | |
| ```mermaid | |
| graph TD | |
| subgraph "ãŠãŒã¶ãŒç°å¢" | |
| Browser[ãŠãŒã¶ãŒã®ãã©ãŠã¶] | |
| end | |
| subgraph "WebãµãŒã㌠(Django)" | |
| A[Django View] -- DBããå£ã³ãååŸ --> DB[(PostgreSQL)] | |
| A -- èŠçŽãªã¯ãšã¹ã --> B{API Client} | |
| B -- HTTP POST --> C[AI API Gateway] | |
| end | |
| subgraph "AIæšè«ç°å¢ (Hugging Face Spaces)" | |
| C -- èªèšŒã»ã«ãŒãã£ã³ã° --> D[Gradio App] | |
| D -- æšè«å®è¡ --> E[Summarization Model] | |
| end | |
| Browser -- "1. èŠçŽãã¿ã³ã¯ãªãã¯" --> A | |
| C -- "3. èŠçŽçµæ (JSON)" --> B | |
| A -- "4. èŠçŽçµæ (JSON)" --> Browser | |
| style DB fill:#f9f,stroke:#333,stroke-width:2px | |
| style E fill:#ccf,stroke:#333,stroke-width:2px | |
| ``` | |
| --- | |
| ## 2. ãããžã§ã¯ãæ§é ãšéçºç°å¢ | |
| ä¿å®æ§ã»æ¡åŒµæ§ãé«ããããã圹å²ããšã«ãã¡ã€ã«ãåå²ãããã£ã¬ã¯ããªæ§é ãæ¡çšããDockerã§éçºç°å¢ãæ§ç¯ããŸãã | |
| ### 2.1. æšå¥šãã£ã¬ã¯ããªæ§é | |
| ``` | |
| kids-playground-ai-api/ | |
| â | |
| âââ .github/ | |
| â âââ workflows/ | |
| â âââ ci.yml | |
| â | |
| âââ .gitignore | |
| âââ Dockerfile | |
| âââ pyproject.toml | |
| âââ requirements.txt | |
| âââ README.md | |
| â | |
| âââ docs/ | |
| â âââ ai_api_development_guide.md # â ãã®éçºã¬ã€ã | |
| â | |
| âââ src/ | |
| â âââ ai_api/ | |
| â âââ __init__.py | |
| â âââ main.py # APIãšã³ããªãŒãã€ã³ã (Gradio UI) | |
| â âââ core/ | |
| â â âââ __init__.py | |
| â â âââ inference.py # AIæšè«ããžã㯠| |
| â âââ config.py # èšå®ãã¡ã€ã« | |
| â | |
| âââ tests/ | |
| âââ core/ | |
| âââ test_inference.py | |
| ``` | |
| ### 2.2. å質管çããŒã«ã®èšå® | |
| - **`pyproject.toml`:** ãããžã§ã¯ãã«ãŒãã«äœæããRuff (ãã©ãŒããã¿ãŒ/ãªã³ã¿ãŒ), Mypy (åãã§ãã«ãŒ), Pytest (ãã¹ããã¬ãŒã ã¯ãŒã¯) ã®èšå®ãèšè¿°ããŸãã | |
| - **`.pre-commit-config.yaml`:** `pre-commit`ãå°å ¥ããGitã³ãããæã«èªåã§ã³ãŒããã§ãã¯ãèµ°ãããã«èšå®ããŸãã | |
| ### 2.3. éçºç°å¢ (Docker) | |
| - **`requirements.txt`:** å¿ èŠãªã©ã€ãã©ãªãèšè¿°ããŸãã | |
| - **`Dockerfile`:** ããŒã«ã«éçºç°å¢ã®çµ±äžãšå¹çåã®ããã«äœ¿çšããŸãã | |
| - **泚èš:** ãã®`Dockerfile`ã¯ããããŸã§ããŒã«ã«éçºçšã§ãããããã€å ã®Hugging Face Spacesã§ã¯ã`Dockerfile`ã¯çŽæ¥äœ¿ãããã`requirements.txt`ã«åºã¥ããŠç°å¢ãèªåæ§ç¯ãããŸãã | |
| - **`docker-compose.yml`:** DjangoãµãŒããŒãšAI APIãµãŒããŒãªã©ãè€æ°ã®ãµãŒãã¹ãå®çŸ©ããäžæ¬ã§èµ·åã»ç®¡çããããã«äœ¿çšããŸãã | |
| - **Docker Desktopã®æŽ»çš:** WindowsãMacã®ãŠãŒã¶ãŒã¯ãDocker Desktopãå©çšããããšã§ãã³ã³ããã®ç¶æ ãGUIã§èŠèŠçã«ç¢ºèªããããèµ·åã»åæ¢ã容æã«è¡ãããšãã§ããŸããLinuxãŠãŒã¶ãŒãå©çšå¯èœã§ããã³ãã³ãã©ã€ã³æäœã«æ £ããŠããªãéçºè ã«ã¯ãDocker Desktopã®å©çšãæšå¥šããŸãã | |
| #### 2.3.1. ããŒã«ã«ç°å¢ã®èµ·åãšã¢ã¯ã»ã¹ | |
| éçºãéå§ããã«ã¯ããããžã§ã¯ãã®ã«ãŒããã£ã¬ã¯ããªã§ä»¥äžã®ã³ãã³ããå®è¡ããŸããDocker Desktopãå©çšããŠããå Žåã¯ãGUIäžãã `docker-compose.yml` ãæå®ããŠèµ·åããããšãå¯èœã§ãã | |
| ```bash | |
| # -d ãã©ã°ã§ããã¯ã°ã©ãŠã³ãã§èµ·å | |
| docker-compose up --build -d | |
| ``` | |
| ããã«ãããåãµãŒãã¹ãã³ã³ãããšããŠèµ·åããŸãã | |
| - **Djangoã¢ããªã±ãŒã·ã§ã³:** `http://localhost:8000` | |
| - **AI API (Gradio):** `http://localhost:7860` | |
| ### 2.4. ãããã°æ¹æ³ | |
| ã³ã³ããå ã§åé¡ãçºçããå Žåã以äžã®ã³ãã³ãã§ã³ã³ããã®å éšã«å ¥ãããããã°äœæ¥ãè¡ãããšãã§ããŸãã | |
| ```bash | |
| # <service_name> 㯠docker-compose.yml ã§å®çŸ©ãããµãŒãã¹å (äŸ: web, api) | |
| docker-compose exec <service_name> bash | |
| ``` | |
| ã³ã³ããå ã§ã¯ããã°ãã¡ã€ã«ã®ç¢ºèªãPythonã®ã€ã³ã¿ã©ã¯ãã£ãã·ã§ã«ãèµ·åããŠã®ã³ãŒãå®è¡ãªã©ãå¯èœã§ãã | |
| --- | |
| ## 3. ã¢ãã«ç®¡ç | |
| - **ã¢ãã«éžå®:** ãŸãã¯é床ãšãªãœãŒã¹ã®ãã©ã³ã¹ãè¯ã軜éãªã¢ãã«ïŒäŸ: `llm-jp/t5-small-japanese-finetuned-sum`ïŒã§éçºãéå§ããå¿ èŠã«å¿ããŠãããé«å質ãªã¢ãã«ïŒäŸ: `izumi-lab/t5-base-japanese-summary`ïŒãžã®å·®ãæ¿ããæ€èšããŸãã | |
| - **æ å ±èšé²:** `config.py`ã«ã¯ãã¢ãã«åã ãã§ãªããã¢ãã«ãµã€ãºãã©ã€ã»ã³ã¹ãæšè«é床ã®ç®å®ãªã©ã®æ å ±ãã³ã¡ã³ããšããŠèšé²ãã管çããŸãã | |
| --- | |
| ## 4. å®è£ ã®åœ¹å²åæ | |
| - **`src/ai_api/config.py` (èšå®æ åœ):** ã¢ãã«ããã©ã¡ãŒã¿ã®æ å ±ã管çããŸãã | |
| - **`src/ai_api/core/inference.py` (AIæšè«æ åœ):** AIã¢ãã«ã®ããŒããšæšè«ã®ã³ã¢ããžãã¯ãå®è£ ããŸãã | |
| - **`src/ai_api/main.py` (APIå仿 åœ):** Gradioã®UIãå®çŸ©ãããµãŒããŒãèµ·åããŸããDockerã³ã³ããå ã§å€éšã«APIãå ¬éããããã`iface.launch(server_name="0.0.0.0")`ã®ããã«èµ·åãªãã·ã§ã³ãæå®ããŸãã | |
| ### AIæ°æ©èœéçºã«ãããã³ãŒãã£ã³ã°èŠçŽ | |
| AIæ°æ©èœã®éçºã«ãããŠã¯ã以äžã®ã³ãŒãã£ã³ã°èŠçŽãšéçºååãéµå®ããé«å質ã§ä¿å®æ§ã®é«ãã³ãŒãããŒã¹ãç®æããŸãã | |
| #### 1. Pythonã³ãŒãã£ã³ã°èŠçŽ | |
| * **PEP 8æºæ **: Pythonã³ãŒãã¯PEP 8ã¹ã¿ã€ã«ã¬ã€ãã«å³å¯ã«æºæ ããŸãã`flake8` ããã³ `black` ã«ããèªåãã©ãŒããããšãªã³ãã培åºããã³ãŒãã®äžè²«æ§ãä¿ã¡ãŸãã | |
| * **åãã³ãã®æŽ»çš**: `mypy` ãçšããåãã§ãã¯ã培åºããã³ãŒãã®å ç¢æ§ãå¯èªæ§ãããã³IDEã«ããè£å®ã®æ©æµãæå€§åããŸãã | |
| * **Djangoãšã®é£æº**: AIæ©èœãDjangoã¢ããªã±ãŒã·ã§ã³ãšé£æºããå ŽåãDjangoã®ã¢ãã«ããã¥ãŒããã©ãŒã ãURLãã¿ãŒã³ãªã©ã®æ¢åã®åœåèŠåãšæ§é ã«æºæ ããã·ãŒã ã¬ã¹ãªçµ±åãå³ããŸãã | |
| * **AI/MLã³ãŒãã®æ§é **: | |
| - ããŒã¿åŠçïŒååŠçãç¹åŸŽéãšã³ãžãã¢ãªã³ã°ïŒãã¢ãã«å®çŸ©ãåŠç¿ããžãã¯ãæšè«ããžãã¯ã¯æç¢ºã«åé¢ãããããããåäžã®è²¬åãæã€ã¢ãžã¥ãŒã«ãšããŠèšèšããŸãã | |
| - èšå®å€ããã€ããŒãã©ã¡ãŒã¿ã¯ã³ãŒãããåé¢ããDjangoã®`settings.py`ããŸãã¯å°çšã®YAML/JSONãã¡ã€ã«ãªã©ã§äžå çã«ç®¡çããŸãã | |
| * **ããã¥ã¡ã³ããŒã·ã§ã³**: 颿°ãã¯ã©ã¹ãè€éãªã¢ã«ãŽãªãºã ãããã³AIã¢ãã«ã®èšèšæå³ã«ã¯ãé©åãªDocstringãèšè¿°ããã³ãŒãã®æå³ãšæ¯ãèããæç¢ºã«ããŸãã | |
| * **ãšã©ãŒãã³ããªã³ã°**: äºæãã¬ãšã©ãŒãäŸå€åŠçã¯ãDjangoã®æšæºçãªãšã©ãŒãã³ããªã³ã°ãPythonã®äŸå€åŠçã¡ã«ããºã ã«åŸããé©åã«ãã°ãåºåããã·ã¹ãã ã®å®å®æ§ã確ä¿ããŸãã | |
| * **ä¿å®æ§ãšå¯èªæ§**: ã³ãŒãã¯åžžã«ä¿å®æ§ãšå¯èªæ§ãæåªå ã«èšèšã»å®è£ ããŸããè€éãªããžãã¯ã¯å°ããªé¢æ°ã«åå²ãã倿°åã颿°åã¯æå³ãæç¢ºã«äŒããããã«åœåããŸãã | |
| * **åäžè²¬åã®åå (SRP)**: ã¯ã©ã¹ã颿°ã¯ã倿Žã®çç±ãäžã€ã§ããããã«èšèšããŸããããã«ãããã³ãŒãã®åé床ãé«ãããã¹ãå®¹ææ§ãšåå©çšæ§ãåäžãããŸãã | |
| #### 2. ãã¹ãé§åéçº (TDD) ãšãã¹ãã®èãæ¹ | |
| * **t_wadaæ°ã®TDDã¹ã¿ã€ã«**: éçºã¯ãRed â Green â Refactorãã®TDDãµã€ã¯ã«ãå³å®ããŠé²ããŸãã | |
| - **Red**: æåã«å€±æãããã¹ããèšè¿°ããå¿ èŠãªæ©èœã®æ¯ãèããå®çŸ©ããŸãã | |
| - **Green**: ãã¹ããæåããæå°éã®ã³ãŒããå®è£ ããŸãã | |
| - **Refactor**: ã³ãŒãã®å質ãåäžãããéè€ãæé€ããèšèšãæ¹åããŸãã | |
| * **ãåã仿§æžããšããŠã®ãã¹ã**: ãã¹ãã³ãŒãã¯ãåãªãå質ä¿èšŒã®ææ®µã§ã¯ãªããæ©èœã®æ¯ãèããæç¢ºã«èšè¿°ãããåã仿§æžããšããŠæ©èœããããã«èšèšããŸãã | |
| - ãã¹ãã±ãŒã¹åïŒ`pytest`ã®ãã¹ã颿°åãªã©ïŒã¯ã**æ¥æ¬èªã§**ãããšããç¶æ³ã§ãããšããæ¯ãèãããã¹ãããšããããã«ãå ·äœçãªã·ããªãªãšæåŸ ãããçµæãèšè¿°ããŸãã | |
| - ãã¹ãã¯å®è£ ã®è©³çްã§ã¯ãªããæ©èœã®**æ¯ãèãïŒBehaviorïŒ**ã«çŠç¹ãåœãŠãŸãã | |
| --- | |
| ## 5. ãã¹ãæŠç¥ | |
| - **ãŠããããã¹ã:** `pytest`ã䜿ãã`inference.py`å ã®çŽç²ãªé¢æ°ïŒAIã®ã³ã¢ããžãã¯ïŒããã¹ãããŸãã | |
| - **ã€ã³ãã°ã¬ãŒã·ã§ã³ãã¹ã:** ããŒã«ã«ã§èµ·åããGradioãµãŒããŒã«å¯Ÿãã`requests`ã©ã€ãã©ãªã§å®éã«APIãªã¯ãšã¹ããéããHTTPã¹ããŒã¿ã¹ã³ãŒããã¬ã¹ãã³ã¹ã®åœ¢åŒãæåŸ éãã§ããããšã確èªãããã¹ãã远å ããŸããããã«ãããAPIãšããŠã®æ£åžžæ§ãä¿èšŒããŸãã | |
| --- | |
| ## 6. CI/CDãšãããã€æŠç¥ | |
| ### 6.1. æšå¥šã¯ãŒã¯ãã㌠| |
| 1. **CI (GitHub Actions):** ãã«ãªã¯ãšã¹ãäœææã`main`ãã©ã³ããžã®ããã·ã¥æã«ãGitHub Actionsãèµ·åãã`pytest`ã«ããèªåãã¹ãïŒãŠããããã¹ããšã€ã³ãã°ã¬ãŒã·ã§ã³ãã¹ãïŒãå®è¡ããŸãã | |
| 2. **CD (GitHub Actionsã«ãããããã€):** ãã¹ããæåããã³ãŒãã`main`ãã©ã³ãã«ããŒãžãããããGitHub Actionsã®ã¯ãŒã¯ãããŒãHugging Faceã®ã¢ã¯ã»ã¹ããŒã¯ã³ã䜿ã£ãŠãHugging Face Spacesã®ãªããžããªã«çŽæ¥`git push`ããŸããããã«ããããããã€ãèªåçã«å®è¡ãããŸãã | |
| ### 6.2. èšå® | |
| - **GitHub Actions:** `.github/workflows/ci.yml`ã«ãã¹ããšãããã€ã®ã¯ãŒã¯ãããŒãå®çŸ©ããŸãã | |
| - **Hugging Face Hub & GitHub Secrets:** | |
| 1. Hugging Faceã®å人èšå®ã§ã`write`æš©éãæã€ã¢ã¯ã»ã¹ããŒã¯ã³ãçºè¡ããŸãã | |
| 2. çºè¡ããããŒã¯ã³ããGitHubãªããžããªã®`Settings > Secrets and variables > Actions`ã«`HF_TOKEN`ãšããŠç»é²ããŸãã | |
| 3. `ci.yml`å ã®ãããã€ãžã§ãã¯ããã®`HF_TOKEN`ãå®å šã«å©çšããŠHugging Faceãžã®èªèšŒãè¡ããŸãã | |
| --- | |
| ## 7. ã»ãã¥ãªãã£ãšå©çšå¶é | |
| ### 7.1. APIèªèšŒ | |
| **課é¡:** Hugging Face Spacesã§å ¬éãããAPIã¯ãããã©ã«ãã§ã¯èª°ã§ãã¢ã¯ã»ã¹å¯èœãªç¶æ ã«ãªããŸããæå³ããªãå©çšãæ»æãé²ããããDjangoã¢ããªã±ãŒã·ã§ã³ããã®ã¿ãªã¯ãšã¹ããåãä»ããããã«å¶åŸ¡ããå¿ èŠããããŸãã | |
| **察ç:** APIããŒã«ããèªèšŒãå°å ¥ããŸãã | |
| 1. **APIããŒã®çæ:** UUIDãªã©ã§æšæž¬å°é£ãªæååãAPIããŒãšããŠçæããŸãã | |
| 2. **Secretsãžã®ç»é²:** çæããããŒããDjangoãšGradio APIã®äž¡æ¹ã®ç°å¢å€æ°ïŒHugging Face Spacesã®SecretsïŒãšããŠç»é²ããŸãã | |
| - `AI_API_KEY`: GradioåŽã§ãªã¯ãšã¹ããæ€èšŒããããã®ã㌠| |
| - `DJANGO_AI_API_KEY`: Djangoããªã¯ãšã¹ãæã«éä¿¡ããã㌠| |
| 3. **èªèšŒã®å®è£ :** | |
| - **DjangoåŽ:** APIãåŒã³åºãéãHTTPããããŒïŒäŸ: `Authorization: Bearer <APIããŒ>`ïŒã«APIããŒãå«ããŠéä¿¡ããŸãã | |
| - **GradioåŽ:** FastAPIã®äŸåæ§æ³šå ¥ïŒ`Depends`ïŒãªã©ãå©çšããŠããªã¯ãšã¹ãããããŒããã§ãã¯ããèªèšŒé¢æ°ãå®çŸ©ããŸããAPIããŒãäžèŽããªãå Žåã¯ãHTTP 401ãŸãã¯403ãšã©ãŒãè¿åŽããŸãã | |
| ### 7.2. ãã®ä»ã®å¯Ÿç | |
| - **Abuse察ç:** å ¬éAPIãæªçšãããã®ãé²ããããGradioã®`queue()`ã¡ãœãããå©çšããŠãªã¯ãšã¹ããåŸ ã¡è¡åã«å ¥ããåæã¢ã¯ã»ã¹æ°ãå¶éããããšãæ€èšããŸãã | |
| - **å 責äºé :** `README.md`ã«ãAPIã®å©çšã¯èªå·±è²¬ä»»ã§ããããšãçæãããå å®¹ã®æ£ç¢ºæ§ãä¿èšŒããªãããšãåçšå©çšã«é¢ããå¶éãªã©ãæèšããŠãããŸãã | |
| --- | |
| ## 8. ä»åŸã®éçºããã»ã¹ | |
| ãã®ããã¥ã¡ã³ãã¯ãä»åŸã®èª¿æ»ãéçºã®é²æã«å¿ããŠãç¶ç¶çã«æŽæ°ã»ã¡ã³ããã³ã¹ãããŸãã | |
| --- | |
| ## 9. èšèš | |
| ãã®ã»ã¯ã·ã§ã³ã§ã¯ãæ©èœå®è£ ã®åã«å®çŸ©ããã¹ãããã詳现ãªèšèšã«ã€ããŠèšé²ããŸãã | |
| ### 9.1. APIã€ã³ã¿ãŒãã§ãŒã¹èšèš (å£ã³ãèŠçŽæ©èœ v1) | |
| DjangoãšGradio APIãããåãããããŒã¿åœ¢åŒãšã«ãŒã«ã以äžã®ããã«å®ããŸãã | |
| #### 9.1.1. åºæ¬æ¹é | |
| - **éä¿¡ãããã³ã«:** HTTP/HTTPS | |
| - **ããŒã¿åœ¢åŒ:** JSON | |
| - **åºæ¬æ§é :** Gradioã®æšæºAPI圢åŒã«æºæ ããŸãã | |
| #### 9.1.2. ãªã¯ãšã¹ã仿§ (Django â Gradio API) | |
| - **ãšã³ããã€ã³ã:** `(Spaceã®URL)/api/predict/` | |
| - **HTTPã¡ãœãã:** `POST` | |
| - **ãã㣠(JSON):** | |
| ```json | |
| { | |
| "data": [ | |
| "å£ã³ãå šæãçµåããæåå..." | |
| ] | |
| } | |
| ``` | |
| #### 9.1.3. ã¬ã¹ãã³ã¹ä»æ§ (Gradio API â Django) | |
| **æåæ (HTTP 200 OK):** | |
| - **ãã㣠(JSON):** | |
| ```json | |
| { | |
| "data": [ | |
| "AIã«ãã£ãŠçæãããèŠçŽæ..." | |
| ], | |
| "duration": 3.5 | |
| } | |
| ``` | |
| **å€±ææ (HTTP 500 Internal Server Error):** | |
| - **ãã㣠(JSON):** | |
| ```json | |
| { | |
| "error": "GradioåŽã§èšå®ãããšã©ãŒã¡ãã»ãŒãž" | |
| } | |
| ``` | |
| ### 9.2. UI/UXèšèš (å£ã³ãèŠçŽæ©èœ v1) | |
| ãŠãŒã¶ãŒãæ©èœãçŽæçã«å©çšã§ããã·ã¹ãã ã®å¿çãå¿«é©ã«åŸ ãŠãããã«ã以äžã®éãUI/UXãèšèšããŸãã | |
| #### 9.2.1. æäœãã㌠| |
| 1. **ããªã¬ãŒ:** ãŠãŒã¶ãŒãæœèšè©³çްããŒãžã®ãå£ã³ããAIèŠçŽããã¿ã³ãã¯ãªãã¯ããŸãã | |
| 2. **ããŒãã£ã³ã°:** ãã¿ã³ãç¡å¹åããããçæäžã§ã...ããšããããã¹ããšã¹ãããŒïŒå転ããã¢ã€ã³ã³ïŒã衚瀺ãããŸããããã«ãããåŠçäžã§ããããšããŠãŒã¶ãŒã«æç¢ºã«äŒãããŸãã | |
| 3. **çµæè¡šç€º:** èŠçŽãå®äºãããšã**Bootstrapã®ã¢ãŒãã«ãŠã£ã³ããŠ**ãç»é¢äžå€®ã«è¡šç€ºããããã®äžã«çæãããèŠçŽæãæç€ºãããŸãã | |
| 4. **å®äº:** ãŠãŒã¶ãŒã¯ã¢ãŒãã«ãéããŠãå ã®ããŒãžé²èЧãç¶ããŸããããŒãã£ã³ã°è¡šç€ºã¯å ã®ãã¿ã³è¡šç€ºã«æ»ããŸãã | |
| #### 9.2.2. ãšããžã±ãŒã¹ã®å¯Ÿå¿ | |
| - **å£ã³ããå°ãªãå Žå:** | |
| - **æ¡ä»¶:** DjangoåŽã§ã察象æœèšã®å£ã³ãã3ä»¶æªæºã®å Žåã | |
| - **åŠç:** AIã®APIã¯åŒã³åºãããå³åº§ã«ãå£ã³ãã3ä»¶æªæºã®ãããèŠçŽã§ããŸãããããšããã¢ã©ãŒãã¡ãã»ãŒãžã衚瀺ããŸããããã«ãããäžèŠãªAPIã³ãŒã«ãé²ãããŠãŒã¶ãŒã«ç¶æ³ãç確ã«äŒããŸãã | |
| - **APIãšã©ãŒçºçæ:** | |
| - **æ¡ä»¶:** APIã®ã¿ã€ã ã¢ãŠãããµãŒããŒãšã©ãŒãçºçããå Žåã | |
| - **åŠç:** ãAIãµãŒããŒã§åé¡ãçºçããŸãããæéããããŠå床ã詊ããã ãããããšãã£ãå 容ãã¢ã©ãŒããŸãã¯ã¢ãŒãã«ã§è¡šç€ºããŸãã | |
| ### 9.3. ããŒã¿åŠçã»ããžãã¹ããžãã¯èšèš (v1) | |
| AIã®æ§èœãæå€§éã«åŒãåºããå®å®ããéçšãè¡ãããã®å éšã«ãŒã«ã以äžã®ããã«èšèšããŸãã | |
| #### 9.3.1. å ¥åããŒã¿ã®ååŠç (DjangoåŽ) | |
| - **å£ã³ãã®çµå:** è€æ°ã®å£ã³ãã¯ããããããç¬ç«ããæ®µèœãšããŠAIã«èªèãããããã2ã€ã®æ¹è¡æå (`\n\n`) ã§åºåã£ãŠ1ã€ã®ããã¹ãã«çµåããŸãã | |
| - **ãã€ãºé€å»:** çµµæåãURLãªã©ãèŠçŽã®ãã€ãºãšãªãããäžèŠãªæååã¯ãæ£èŠè¡šçŸãçšããŠäºåã«é€å»ããŸãã | |
| #### 9.3.2. èŠçŽå®è¡ã®å€æããžã㯠(DjangoåŽ) | |
| 以äžã®æ¡ä»¶ãæºãããªãå Žåã¯ãAPIãåŒã³åºããã«ãšã©ãŒãšããŠåŠçããŸãã | |
| - **æå°å£ã³ãä»¶æ°:** 3ä»¶ä»¥äž | |
| - **æå°ç·æåæ°:** å šäœã®æåæ°ã300æåä»¥äž | |
| #### 9.3.3. AIã¢ãã«ã®æšè«ãã©ã¡ãŒã¿ (Gradio APIåŽ) | |
| çæãããèŠçŽæã®å質ãå¶åŸ¡ããããã以äžã®åæãã©ã¡ãŒã¿ãèšå®ããŸãããããã®å€ã¯ `config.py` ã§ç®¡çãã調æŽå¯èœã«ããŸãã | |
| - **èŠçŽæã®æå°é· (`min_length`):** 50 | |
| - **èŠçŽæã®æå€§é· (`max_length`):** 250 | |
| - **é·ãããã«ã㣠(`length_penalty`):** 2.0 (åé·ãªè¡šçŸãæå¶) | |
| #### 9.3.4. 倧éããŒã¿ãžã®å¯Ÿå¿æ¹é | |
| - **åæå®è£ :** ãŸãã¯å šãŠã®å£ã³ããçµåããŠAPIã«éä¿¡ããŸããã¢ãã«ã®æå€§å ¥åé·ãè¶ ããå Žåã¯ã`truncation=True` ãªãã·ã§ã³ã«ããèªåçã«æ«å°ŸãåãæšãŠãããŸãã | |
| - **å°æ¥çãªæ¹å:** æ§èœãã³ã¹ãã«åé¡ãèŠãããå ŽåããçŽè¿1幎éã®å£ã³ãã®ã¿ã察象ãšããããªã©ã®å¶éãåŸãã远å ããããšãæ€èšããŸãã | |
| ### 9.4. ãšã©ãŒãã³ããªã³ã°èšèš (v1) | |
| äºæãã¬äºæ ãçºçããå Žåã§ãã·ã¹ãã ãå®å®ããŠåäœãããŠãŒã¶ãŒã«é©åãªãã£ãŒãããã¯ãè¿ããããã以äžã®éããšã©ãŒãã³ããªã³ã°ãèšèšããŸãã | |
| #### 9.4.1. ãšã©ãŒçºçæºãšå¯Ÿå¿æ¹é | |
| | çºçå Žæ | ãšã©ãŒäŸ | å¯Ÿå¿æ¹é | ãŠãŒã¶ãŒãžã®éç¥äŸ | | |
| | :--- | :--- | :--- | :--- | | |
| | **Gradio API** | ã¢ãã«ã®ããŒã倱æãæšè«äžã®ãšã©ãŒ | `try...except`ã§ææããHTTP 500ãšãšã©ãŒå 容ãJSONã§è¿ãã | (Djangoçµç±ã§)ãAIãµãŒããŒã§åé¡ãçºçã | | |
| | **Django â Gradio APIé** | ãããã¯ãŒã¯é害ãã¿ã€ã ã¢ãŠã | Djangoã®`requests`éšåã§`try...except`ã§ææãããšã©ãŒããã°èšé²ã | ãAIãµãŒããŒã«å¿çããããŸããã | | |
| | **Django** | DBæ¥ç¶ãšã©ãŒãå£ã³ãä»¶æ°äžè¶³ | `try...except`ãæ¡ä»¶åå²ã§å¯Ÿå¿ãå£ã³ãäžè¶³ã¯HTTP 400ãè¿ãã | ããµãŒããŒã§ãšã©ãŒãçºçãããŸãã¯ãå£ã³ããäžè¶³ã | | |
| | **ãã©ãŠã¶ â Djangoé** | ãŠãŒã¶ãŒã®ãªãã©ã€ã³ | jQuery Ajaxã®`.fail()`ã³ãŒã«ããã¯ã§ææã | ãéä¿¡ã«å€±æããŸããã | | |
| #### 9.4.2. å®è£ ã®ãã€ã³ã | |
| - **Django (åžä»€å¡) ã®åœ¹å²:** | |
| - Djangoã®ãã¥ãŒã¯ãGradio APIãšã®éä¿¡éšåãå¿ ã`try...except`ãããã¯ã§å²ã¿ãã¿ã€ã ã¢ãŠãïŒäŸ: 30ç§ïŒãèšå®ããŸãã | |
| - APIããè¿ãããHTTPã¹ããŒã¿ã¹ã³ãŒããåžžã«ãã§ãã¯ãã200çªå°ä»¥å€ã¯ãšã©ãŒãšããŠåŠçããŸãã | |
| - çºçãããšã©ãŒã¯ã**å¿ ããµãŒããŒãã°ã«èšé²**ããåå 調æ»ã«åœ¹ç«ãŠãŸãã | |
| - ãŠãŒã¶ãŒã«ã¯ãæè¡çãªãšã©ãŒè©³çްïŒã¹ã¿ãã¯ãã¬ãŒã¹çïŒãçŽæ¥èŠããããAIãµãŒããŒã§åé¡ãçºçããŸãããã®ãããªæœè±¡çã§åãããããã¡ãã»ãŒãžãè¿ããŸãã | |
| - **Gradio API (å°éå®¶) ã®åœ¹å²:** | |
| - AIã®æšè«åŠçãªã©ã倱æããå¯èœæ§ã®ããã³ãŒãã¯`try...except`ãããã¯ã§å²ã¿ãŸãã | |
| - ãšã©ãŒçºçæã¯ã`raise gr.Error("å ·äœçãªãšã©ãŒåå ")`ãåŒã³åºããAPIã®å¥çŽéãã«ãšã©ãŒæ å ±ãè¿åŽããŸãã | |
| ### 9.5. 詳现èšèš: AIæšè«ã³ã¢ (`core/inference.py`) (v1) | |
| AIæšè«ã®ã³ã¢ããžãã¯ã¯ãä¿å®æ§ãšãã¹ãå®¹ææ§ãé«ããããã«ãããã€ãã®èšèšååãšãã¶ã€ã³ãã¿ãŒã³ãé©çšããŠæ§é åããŸãã | |
| #### 9.5.1. ã¯ã©ã¹èšèšãšè²¬å | |
| - **`Summarizer` ã¯ã©ã¹ã®å°å ¥:** AIã®æšè«ã«é¢é£ããå šãŠã®ããžãã¯ããåäžã®`Summarizer`ã¯ã©ã¹ã«éçŽããŸãããã®ã¯ã©ã¹ã¯**ãAIã¢ãã«ã管çããããã¹ãèŠçŽãå®è¡ããã**ãšããæç¢ºãªè²¬åãæã¡ãŸãã | |
| #### 9.5.2. é©çšãããã¶ã€ã³ãã¿ãŒã³ | |
| - **ãã¡ãµãŒã (Facade) ãã¿ãŒã³:** `Summarizer`ã¯ã©ã¹ã¯ã`transformers`ã©ã€ãã©ãªã®è€éãªå éšåŠçïŒã¢ãã«ã®ããŒããããŒã¯ãã€ãºãæšè«ããã³ãŒãçïŒãã«ãã»ã«åïŒé èœïŒããŸãããããŠã`summarize(text)`ãšããéåžžã«ã·ã³ãã«ãªã¡ãœããã®ã¿ãå€éšã«å ¬éããŸããããã«ãããå©çšåŽïŒ`main.py`ïŒã¯AIã®è€éãªè©³çްãæèããããšãªããç°¡åãã€å®å šã«èŠçŽæ©èœãå©çšã§ããŸãã | |
| - **äŸåæ§ã®æ³šå ¥ (Dependency Injection) ã«ããã€ã³ã¹ã¿ã³ã¹ç®¡ç:** AIã¢ãã«ã®ãããªãªãœãŒã¹ã倧éã«æ¶è²»ãããªããžã§ã¯ãã¯ããªã¯ãšã¹ãããšã«çæããã¹ãã§ã¯ãããŸããã代ããã«ãã¢ããªã±ãŒã·ã§ã³ã®èµ·åæã«äžåºŠã ã`Summarizer`ã®ã€ã³ã¹ã¿ã³ã¹ãçæãããããå¿ èŠãšããåã³ã³ããŒãã³ãïŒAPIã®ãšã³ããã€ã³ã颿°ãªã©ïŒã«**æ³šå ¥ïŒåŒæ°ãšããŠæž¡ãïŒ**ããŸãã | |
| - **ãªãã·ã³ã°ã«ãã³ãé¿ããã:** ãææã®éããã°ããŒãã«ãªåäžã€ã³ã¹ã¿ã³ã¹ïŒã·ã³ã°ã«ãã³ïŒã«äŸåããèšèšã¯ãã³ã³ããŒãã³ãéã®çµåã匷ãããã¹ããå°é£ã«ããããã¢ã³ããã¿ãŒã³ãšèŠãªãããŸãããã®ã¢ãããŒãã¯é¿ããã¹ãã§ãã | |
| - **å ·äœçãªå®çŸæ¹æ³:** ã¢ããªã±ãŒã·ã§ã³ã®ãšã³ããªãŒãã€ã³ãïŒ`main.py`ïŒã§`Summarizer`ã€ã³ã¹ã¿ã³ã¹ãçæãã`functools.partial`ãªã©ãçšããŠãAPIãåŠçãã颿°ã«ãã®ã€ã³ã¹ã¿ã³ã¹ããããããæž¡ããŠããããšã§ãã°ããŒãã«ãªç¶æ ãæã€ããšãªãã€ã³ã¹ã¿ã³ã¹ã®å ±æãå®çŸããŸããããã«ããããã¹ãå®¹ææ§ãšèšèšã®æè»æ§ãå€§å¹ ã«åäžããŸãã | |
| - **èšå®å€ã®æ³šå ¥:** ãã®DIãã¿ãŒã³ã¯ã`Summarizer`ã¯ã©ã¹ã䜿çšããã¢ãã«åãèŠçŽã®é·ããšãã£ãèšå®å€ãã³ã³ã¹ãã©ã¯ã¿ãéããŠå€éšã®`config`ã¢ãžã¥ãŒã«ããåãåããšãããå ã ã®äŸåæ§æ³šå ¥ã®èãæ¹ãšãäžèŽããŠããŸãã | |
| #### 9.5.3. ãšã©ãŒãã³ããªã³ã°æ¹é | |
| - `Summarizer`ã¯ã©ã¹å ã§çºçãããšã©ãŒïŒã¢ãã«ã®ããŒã倱æãæšè«å€±æãªã©ïŒã¯ãã¯ã©ã¹å éšã§é©åã«ææãããåŒã³åºãå ããã³ããªã³ã°ããããããã«ãå°çšã®äŸå€ïŒäŸ: `InferenceError`ïŒãšããŠåéåºããèšèšãšããŸãã | |
| ### 9.6. 詳现èšèš: èšå®ç®¡ç (`config.py`) (v1) | |
| èšå®å€ãã³ãŒãããåé¢ããå®å šãã€æ§é çã«ç®¡çããããã以äžã®éãèšèšããŸãã | |
| #### 9.6.1. èšèšæ¹é | |
| - **ããŒã¿ã¯ã©ã¹ã®æŽ»çš:** Pythonæšæºã®`dataclasses`ãçšããé¢é£ããèšå®é ç®ãã°ã«ãŒãåããèšå®ã¯ã©ã¹ïŒäŸ: `ModelConfig`ïŒãå®çŸ©ããŸããããã«ãããåå®å šæ§ãä¿èšŒãããã³ãŒãè£å®ãå¹ãããéçºå¹çãåäžããŸãã | |
| - **äžå€æ§ã®ç¢ºä¿:** äœæããããŒã¿ã¯ã©ã¹ã¯ `@dataclass(frozen=True)` ãæå®ããã€ãã¥ãŒã¿ãã«ïŒå€æŽäžå¯èœïŒã«ããŸããããã«ãããã¢ããªã±ãŒã·ã§ã³å®è¡äžã«æå³ããèšå®ã倿ŽãããŠããŸãå±éºãªç¶æ ãé²ããŸãã | |
| - **ç°å¢å€æ°ã«ããèšå®ã®äžæžã:** å°æ¥çãªæ¡åŒµæ§ïŒäŸ: APIããŒã®ç®¡çïŒãèŠæ®ããèšå®å€ã¯ç°å¢å€æ°ããååŸããããšãåºæ¬ãšããŸããéçºç°å¢ã§ã¯`.env`ãã¡ã€ã«ãå©çšããæ¬çªç°å¢ã§ã¯å®è¡ç°å¢ïŒHugging Face Spacesãªã©ïŒã®Secretsæ©èœã§èšå®ãæ³šå ¥ããéçšãæ³å®ããŸãã | |
| - **`.env.example` ã®æäŸ:** éçºè ãç°å¢å€æ°ã容æã«èšå®ã§ããããããªããžããªã«ã¯ `.env.example` ãã¡ã€ã«ãå«ããŸããå®éã®éçºã§ã¯ããã®ãã¡ã€ã«ãã³ããŒã㊠`.env` ãäœæããå€ãèšå®ããŸãã | |
| ```.env.example | |
| # AI APIã®ã¢ãã«åãæå® | |
| AI_MODEL_NAME="llm-jp/t5-small-japanese-finetuned-sum" | |
| ``` | |
| - **`docker-compose.yml` ã§ã®èªã¿èŸŒã¿:** `docker-compose.yml` ãã¡ã€ã«ã§ `env_file` ãæå®ããããšã§ãã³ã³ããèµ·åæã« `.env` ãã¡ã€ã«ã®å 容ãç°å¢å€æ°ãšããŠèªã¿èŸŒãŸããŸãã | |
| ```yaml | |
| services: | |
| api: | |
| build: . | |
| env_file: | |
| - .env | |
| ``` | |
| #### 9.6.2. æ§é æ¡ | |
| - **`ModelConfig` ã¯ã©ã¹:** | |
| - **責å:** 䜿çšããAIã¢ãã«ã«é¢ããæ å ±ãäžå 管çããŸãã | |
| - **屿§æ¡:** `NAME` (ã¢ãã«å), `REVISION` (ããŒãžã§ã³) | |
| - **`InferenceConfig` ã¯ã©ã¹:** | |
| - **責å:** AIã®æšè«ïŒèŠçŽçæïŒæã®ãã©ã¡ãŒã¿ãäžå 管çããŸãã | |
| - **屿§æ¡:** `MIN_LENGTH`, `MAX_LENGTH`, `LENGTH_PENALTY`, `NUM_BEAMS` | |
| ### 9.7. 詳现èšèš: DjangoåŽãã¥ãŒ (`summary_views.py`) (v1) | |
| DjangoåŽã§AI APIãåŒã³åºããã¥ãŒã¯ã責åãæç¢ºã«åé¢ããå ç¢ãªãšã©ãŒãã³ããªã³ã°ãšãã®ã³ã°ãçµã¿èŸŒãã ã¯ã©ã¹ãšããŠèšèšããŸãã | |
| #### 9.7.1. èšèšæ¹é | |
| - **ã¯ã©ã¹ããŒã¹ãã¥ãŒ (CBV) ã®æ¡çš:** Djangoæšæºã®`django.views.View`ãç¶æ¿ããã¯ã©ã¹ãšããŠå®è£ ããŸããããã«ãããå°æ¥çãªæ©èœæ¡åŒµïŒäŸ: POSTã¡ãœããã®è¿œå ïŒã«ãæè»ã«å¯Ÿå¿ã§ããŸãã | |
| - **責åã®åé¢:** 1ã€ã®ã¡ãœããã«å šãŠã®ããžãã¯ãèšè¿°ããã®ã§ã¯ãªãããå£ã³ãã®ååŸããããªããŒã·ã§ã³ããAPIåŒã³åºãããšãã£ãé¢å¿äºããšã«ãã©ã€ããŒãã¡ãœããïŒäŸ: `_call_api`ïŒãžåŠçãåå²ããã¡ã€ã³ã®`get`ã¡ãœããã®èŠéããè¯ãããŸãã | |
| - **éäžçãªãšã©ãŒãã³ããªã³ã°:** ã¡ã€ã³ã®`get`ã¡ãœããã«`try...except`ãããã¯ãèšããååŠçã§çºçãããäŸå€ïŒDBé¢é£ãéä¿¡é¢é£ãªã©ïŒãéäžçã«ææããé©åãª`JsonResponse`ãè¿ãããã«ããŸãã | |
| - **詳现ãªãã®ã³ã°:** Pythonã®`logging`ã¢ãžã¥ãŒã«ã掻çšããAPIåŒã³åºãã®æåŠãçºçãããšã©ãŒãããžãã¹ããžãã¯ã®å€æãªã©ããã°ã«åºåããŸããç¹ã«ãšã©ãŒçºçæã«ã¯ãã¹ã¿ãã¯ãã¬ãŒã¹ãå«ããŠèšé²ããããšã§ãè¿ éãªåå ç©¶æãå¯èœã«ããŸãã | |
| #### 9.7.2. ã¯ã©ã¹ã»ã¡ãœããæ§ææ¡ | |
| - **`SummarizeReviewsView(View)`** | |
| - **`get(self, request, playground_id)`:** | |
| - HTTP GETãªã¯ãšã¹ããåŠçããã¡ã€ã³ã¡ãœããã | |
| - 以äžã®åŠçãããŒãå¶åŸ¡ããã | |
| 1. `_get_reviews`ãåŒã³åºããå£ã³ãããŒã¿ãååŸã | |
| 2. `_validate_reviews`ãåŒã³åºããããžãã¹ã«ãŒã«ïŒä»¶æ°ãæåæ°ïŒãæ€èšŒã | |
| 3. å£ã³ãããã¹ããååŠçïŒçµåããã€ãºé€å»ïŒã | |
| 4. `_call_summary_api`ãåŒã³åºããå€éšAPIãšéä¿¡ã | |
| 5. æåã¬ã¹ãã³ã¹ãŸãã¯ãšã©ãŒã¬ã¹ãã³ã¹ã`JsonResponse`ãšããŠè¿ãã | |
| - **`_get_reviews(self, playground_id)`:** | |
| - `playground_id`ã«å¯Ÿå¿ããå£ã³ããããŒã¿ããŒã¹ããååŸãã責åãæã€ã | |
| - **`_validate_reviews(self, reviews)`:** | |
| - ååŸããå£ã³ããèŠçŽå®è¡ã®æ¡ä»¶ãæºãããæ€èšŒãã責åãæã€ã | |
| - **`_call_summary_api(self, text)`:** | |
| - `requests`ã©ã€ãã©ãªã䜿ããGradio APIãšã®éä¿¡ãè¡ã責åãæã€ãã¿ã€ã ã¢ãŠãèšå®ãããã§è¡ãã | |
| #### 9.7.3. èšå®å€ã®ç®¡ç | |
| - Gradio APIã®ãšã³ããã€ã³ãURLãã¿ã€ã ã¢ãŠãç§æ°ãšãã£ãèšå®å€ã¯ã`settings.py`ã«èšè¿°ãããã¥ãŒããã¯`django.conf.settings`ãéããŠåç §ããŸããããã«ãããèšå®ã®äžå 管çãå®çŸããŸãã | |
| ### 9.8. 詳现èšèš: ãã¹ãæŠç¥ã®å ·äœå (v1) | |
| ã¢ããªã±ãŒã·ã§ã³ã®å質ãšä¿¡é Œæ§ãä¿èšŒããããã以äžã®éãå€å±€çãªãã¹ãæŠç¥ãèšèšããŸãã | |
| #### 9.8.1. ãã¹ãã®çš®é¡ãšç®ç | |
| - **ãŠããããã¹ã (Unit Tests):** | |
| - **ç®ç:** åã ã®éšåïŒã¯ã©ã¹ãã¡ãœããïŒãåäœã§æ£ããåäœããããšãæ€èšŒããŸããé«éã«å®è¡ã§ãããããéçºäžã®é »ç¹ãªç¢ºèªã«é©ããŠããŸãã | |
| - **察象:** `core/inference.py` ã® `Summarizer` ã¯ã©ã¹ãªã©ãããžãã¹ããžãã¯ã®äžæ žãæ ãéšåã | |
| - **ã€ã³ãã°ã¬ãŒã·ã§ã³ãã¹ã (Integration Tests):** | |
| - **ç®ç:** Gradio APIã®ãšã³ããã€ã³ãããAPIã®å¥çŽéãã«æ£ãããªã¯ãšã¹ããåŠçããã¬ã¹ãã³ã¹ãè¿ãããšãæ€èšŒããŸããã³ã³ããŒãã³ãéã®é£æºã確èªããŸãã | |
| - **察象:** ããŒã«ã«ã§èµ·åããGradioã¢ããªã±ãŒã·ã§ã³ã® `/api/predict/` ãšã³ããã€ã³ãã | |
| #### 9.8.2. ãã¹ãã±ãŒã¹ã®èšç» | |
| - **ãŠããããã¹ã (`tests/core/test_inference.py`):** | |
| - **æ£åžžç³»:** éåžžã®ããã¹ããå ¥åãããå Žåã«ãæåŸ ããã圢åŒïŒæååïŒã®èŠçŽãè¿ãããšã確èªããã | |
| - **ç°åžžç³»:** 空æååãäžæ£ãªããŒã¿åãå ¥åãããå Žåã«ãèšèšéã`ValueError`çã®äŸå€ãçºçããããšã確èªããã | |
| - **ã€ã³ãã°ã¬ãŒã·ã§ã³ãã¹ã (`tests/test_api.py`):** | |
| - **æ£åžžç³»:** APIã«æå¹ãªãªã¯ãšã¹ããéä¿¡ããHTTPã¹ããŒã¿ã¹ã³ãŒã`200`ãšãèšèšéãã®JSONã¬ã¹ãã³ã¹ãè¿ãããšã確èªããã | |
| - **ç°åžžç³»:** äžæ£ãªãªã¯ãšã¹ããéä¿¡ããå Žåã«ãé©åãªHTTPãšã©ãŒã¹ããŒã¿ã¹ã³ãŒãïŒäŸ: `4xx`ïŒãè¿ãããšã確èªããã | |
| #### 9.8.3. ãã¹ãã®å¹çå | |
| - **ãã£ã¯ã¹ãã£ã®æŽ»çš (`@pytest.fixture`):** AIã¢ãã«ã®ããŒãã¯æéããããããã`Summarizer`ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹çæããã£ã¯ã¹ãã£ãšããŠå®çŸ©ããŸãã`scope="session"`ãæå®ããããšã§ãå šãã¹ãå®è¡äžã«ã¢ãã«ã®ããŒããäžåºŠã ãã§æžã¿ããã¹ãæéãå€§å¹ ã«ççž®ããŸãã | |
| - **ãã©ã¡ãŒã¿åã®æŽ»çš (`@pytest.mark.parametrize`):** è€æ°ã®ç°ãªãå ¥åå€ãšæåŸ ãããçµæã®çµã¿åããããäžã€ã®ãã¹ã颿°ã§å¹ççã«æ€èšŒããããã«äœ¿çšããŸãã | |
| ### 9.9. 詳现èšèš: Django-AI飿º (v1) | |
| Djangoã¢ããªã±ãŒã·ã§ã³ãšAIã¢ããªã±ãŒã·ã§ã³ïŒGradioïŒãã©ã®ããã«é£æºããŠæ©èœãå®çŸãããã®å ·äœçãªèšèšã以äžã«ç€ºããŸãã | |
| #### 9.9.1. 飿ºã·ãŒã±ã³ã¹ | |
| ##### æ£åžžç³»ã®ã·ãŒã±ã³ã¹ | |
| å šäœã®åŠçã®æµãã¯ä»¥äžã®éãã§ãã | |
| ```mermaid | |
| sequenceDiagram | |
| participant Browser as ãŠãŒã¶ãŒ(ãã©ãŠã¶) | |
| participant Django as DjangoãµãŒã㌠| |
| participant Gradio as AI API (Gradio) | |
| Browser->>+Django: GET /summarize/playground/{id}/ | |
| Django->>Django: 1. å£ã³ãååŸã»æ€èšŒ | |
| alt å£ã³ãã3ä»¶æªæºãªã©æ¡ä»¶ãæºãããªã | |
| Django-->>-Browser: JSON (ãšã©ãŒ) | |
| end | |
| Django->>+Gradio: POST /api/predict/ (å£ã³ãããã¹ã) | |
| Gradio->>Gradio: 2. AIã¢ãã«ã§èŠçŽå®è¡ | |
| Gradio-->>-Django: JSON (èŠçŽçµæ) | |
| Django-->>-Browser: JSON (èŠçŽçµæ) | |
| ``` | |
| ##### ç°åžžç³»ïŒAI APIãšã©ãŒïŒã®ã·ãŒã±ã³ã¹ | |
| AI APIåŽã§ãšã©ãŒãçºçããå Žåã®åŠçã®æµãã§ãã | |
| ```mermaid | |
| sequenceDiagram | |
| participant Browser as ãŠãŒã¶ãŒ(ãã©ãŠã¶) | |
| participant Django as DjangoãµãŒã㌠| |
| participant Gradio as AI API (Gradio) | |
| Browser->>+Django: GET /summarize/playground/{id}/ | |
| Django->>+Gradio: POST /api/predict/ (å£ã³ãããã¹ã) | |
| Gradio->>Gradio: AIã¢ãã«ã®åŠçã§ãšã©ãŒçºç | |
| Gradio-->>-Django: HTTP 500 (ãšã©ãŒæ å ±) | |
| Django->>Django: ãšã©ãŒããã°ã«èšé² | |
| Django-->>-Browser: JSON (ãŠãŒã¶ãŒåããšã©ãŒã¡ãã»ãŒãž) | |
| ``` | |
| #### 9.9.2. åã³ã³ããŒãã³ãã®è²¬åãšå®è£ | |
| **1. DjangoåŽ (`myapp/views/summary_views.py`)** | |
| - **ã¯ã©ã¹:** `SummarizeReviewsView(View)` | |
| - **ã¡ãœãã:** `get(self, request, playground_id)` | |
| - **責å:** ãªã¯ãšã¹ããåãä»ããAI APIãšã®éä¿¡ãå¶åŸ¡ããåžä»€å¡ã | |
| - **åŠçãããŒ:** | |
| 1. DBããå£ã³ããååŸããä»¶æ°ãæåæ°ãæ€èšŒããã | |
| 2. `_call_summary_api` ã¡ãœãããåŒã³åºããAI APIã«ãªã¯ãšã¹ããéä¿¡ããã | |
| 3. è¿ã£ãŠããçµæïŒæåãŸãã¯ãšã©ãŒïŒãæŽåœ¢ãã`JsonResponse`ãšããŠããã³ããšã³ãã«è¿ãã | |
| - **ã¡ãœãã:** `_call_summary_api(self, text)` | |
| - **責å:** `requests`ã©ã€ãã©ãªãçšããŠãAI APIãšã®HTTPéä¿¡ãå®éã«æ åœããã | |
| - **å®è£ 詳现:** | |
| - `settings.AI_SUMMARY_API_URL` ããAPIã®ãšã³ããã€ã³ãURLãååŸããã | |
| - `requests.post()` ã䜿ããã¿ã€ã ã¢ãŠããèšå®ããŠPOSTãªã¯ãšã¹ããéä¿¡ããã | |
| - éä¿¡ãšã©ãŒããAPIãè¿ããšã©ãŒã¹ããŒã¿ã¹ã³ãŒãã`try...except`ã§ææããé©åã«åŠçããã | |
| - æåæã¯ã¬ã¹ãã³ã¹ã®JSONãããŒã¹ããèŠçŽããã¹ããè¿ãã | |
| **2. AIã¢ããªã±ãŒã·ã§ã³åŽ (`src/ai_api/`)** | |
| - **ãã¡ã€ã«:** `main.py` (ãšã³ããªãŒãã€ã³ã) | |
| - **責å:** Gradioã¢ããªã±ãŒã·ã§ã³ãèµ·åããHTTPãªã¯ãšã¹ããåãä»ããçªå£ã | |
| - **å®è£ 詳现:** | |
| 1. èµ·åæã«äžåºŠã ãã`core.inference.Summarizer` ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãçæããã | |
| 2. `functools.partial` ã䜿ããAPIåŠç颿°ã« `Summarizer` ã®ã€ã³ã¹ã¿ã³ã¹ãæ³šå ¥ïŒãã€ã³ãïŒããã | |
| 3. `gradio.Interface` ãå®çŸ©ãããªã¯ãšã¹ããåŠçãã颿°ãšããŠäžèšã§ãã€ã³ããã颿°ãæž¡ããããã«ãããGradio㯠`/api/predict/` ãšãããšã³ããã€ã³ããèªåçã«äœæããã | |
| - **ãã¡ã€ã«:** `core/inference.py` | |
| - **ã¯ã©ã¹:** `Summarizer` | |
| - **ã¡ãœãã:** `summarize(self, text)` | |
| - **責å:** AIã¢ãã«ã®ç®¡çãšãå®éã®èŠçŽåŠçãšããã³ã¢ããžãã¯ã«è²¬ä»»ãæã€ã | |
| - **å®è£ 詳现:** `transformers`ã©ã€ãã©ãªã䜿ããããã¹ãã®ããŒã¯ãã€ãºãã¢ãã«ã«ããæšè«ãçµæã®ãã³ãŒããè¡ãã | |
| #### 9.9.3. ççµåã®æ ä¿ïŒç¬ç«ããéçºã»ãã¹ãïŒ | |
| ãã®èšèšããããã«ããŠççµåïŒLoose CouplingïŒãæ ä¿ããŠãããã以äžã«ç€ºããŸãã | |
| - **éä¿¡ã®æœè±¡å:** | |
| - DjangoãšAIã¢ããªã¯ã**HTTPãšJSON**ãšããæšæºåãããæè¡ã§ã®ã¿éä¿¡ããŸãã | |
| - Djangoã¯AIã¢ããªãGradioã§å®è£ ãããŠããããšãç¥ãå¿ èŠã¯ãªããéããŸãç¶ãã§ããç¥ã£ãŠããã®ã¯ãã©ã®URLã«ãã©ããªJSONãéãã°ãã©ããªJSONãè¿ã£ãŠãããããšããAPIå¥çŽã ãã§ãã | |
| - **ç¬ç«ããå®è¡ãšãã¹ã:** | |
| - **AIã¢ããªã±ãŒã·ã§ã³:** | |
| - `src/ai_api/` ãã£ã¬ã¯ããªã¯ãããèªäœãå®çµããPythonãããžã§ã¯ãã§ãã | |
| - `python src/ai_api/main.py` ãå®è¡ããã°ãDjangoãšã¯ç¡é¢ä¿ã«åäœã§èµ·åã§ããŸãã | |
| - èµ·åããAIã¢ããªã«å¯Ÿãããã©ãŠã¶ã§UIãæäœãããã`curl`ã³ãã³ãã§APIãçŽæ¥å©ãããããããšã§ãåäœã§ã®åäœãã¹ããå¯èœã§ãã | |
| - **Djangoã¢ããªã±ãŒã·ã§ã³:** | |
| - `SummarizeReviewsView` ã®ãã¹ããæžãéã`unittest.mock.patch` ã䜿ã£ãŠ `_call_api` ã¡ãœãããã¢ãã¯ïŒåœã®ãªããžã§ã¯ãã«å·®ãæ¿ãïŒããŸãã | |
| - ããã«ãããAI APIãžå®éã«ãããã¯ãŒã¯éä¿¡ãçºçãããããšãªãããAPIãæåãè¿ããå Žåããã¿ã€ã ã¢ãŠãããå Žåãããšã©ãŒãè¿ããå Žåããªã©ãããããç¶æ³ãæ³å®ãããã¥ãŒã®ããžãã¯ãé«éã«ãã¹ãã§ããŸãã | |
| ãã®èšèšã«ãããäž¡ã¢ããªã±ãŒã·ã§ã³ã¯äºãã«äŸåããããšãªããç¬ç«ããŠéçº,ãã¹ã,ãããã€ãé²ããããšãå¯èœã«ãªããŸãã | |
| ### 9.10. pyproject.toml ã®è©³çްèšèš | |
| ããã§ã®ãŽãŒã«ã¯ããããžã§ã¯ãã§å©çšããå質管çããŒã«ïŒRuff, Mypy, PytestïŒã®å ·äœçãªåäœã«ãŒã«ã`pyproject.toml`ãã¡ã€ã«ã«å®çŸ©ãã誰ãéçºããŠãããŸãCI/CDã§å®è¡ãããŠããåžžã«äžè²«ããåºæºã§ã³ãŒãã®å質ããã§ãã¯ãããããã«ããããšã§ãã | |
| #### 1. Ruff (ãªã³ã¿ãŒ & ãã©ãŒããã¿ãŒ) | |
| é«éãªãªã³ã¿ãŒå Œãã©ãŒããã¿ãŒã§ããRuffã®èšå®ãå®çŸ©ããŸãã | |
| ##### èšèšæ¹é | |
| - Pythonã®æšæºçãªãã©ãŒããã¿ãŒã§ãã`black`ã®èŠçŽã«æºæ ãããŸãã | |
| - å¿ é ã®ã«ãŒã«ã«å ããæœåšçãªãã°ãçºèŠããã«ãŒã«ããã³ãŒããããã¢ãã³ãªèšæ³ã«èªåä¿®æ£ããã«ãŒã«ãç©æ¥µçã«æå¹åããã³ãŒãå質ãé«ãä¿ã¡ãŸãã | |
| ##### èšå®æ¡ (`[tool.ruff]`ã»ã¯ã·ã§ã³) | |
| - `line-length = 88`: 1è¡ã®æå€§é·ã`black`ã«åãããŠ88æåã«èšå®ã | |
| - `select = ["E", "W", "F", "I", "B", "UP"]`: | |
| - `E`, `W`, `F`: `pycodestyle`ãš`Pyflakes`ã®åºæ¬çãªãšã©ãŒã»èŠåïŒå¿ é ïŒã | |
| - `I`: `isort`äºæã®importæã®èªåãœãŒãïŒå¿ é ïŒã | |
| - `B`: `flake8-bugbear`ã®ããã°ã®æž©åºãšãªããããã³ãŒããã¿ãŒã³ãæ€åºããã«ãŒã«ã | |
| - `UP`: `pyupgrade`ã®ãå€ãPythonèšæ³ãæ°ããèšæ³ãžèªåçã«ã¢ããã°ã¬ãŒãããã«ãŒã«ã | |
| - `target-version = "py312"`: Python 3.12ã®ææ³ãæ£ããè§£éããããã«æå®ã | |
| ##### èšå®æ¡ (`[tool.ruff.format]`ã»ã¯ã·ã§ã³) | |
| - `quote-style = "double"`: ã³ãŒãå ã§ã®åŒçšç¬Šãããã«ã¯ã©ãŒãïŒ`"`ïŒã«çµ±äžã | |
| #### 2. Mypy (éçåãã§ãã«ãŒ) | |
| åãã³ãã®æ£ãããä¿èšŒããMypyã®èšå®ãã峿 Œãã€å®çšçã«å®çŸ©ããŸãã | |
| ##### èšèšæ¹é | |
| - åãã³ãã®èšè¿°ããããžã§ã¯ãå ã§åŸ¹åºãããåã®å®å šæ§ãé«ããŸãã | |
| - äžæ¹ã§ãåæ å ±ãæããªãå€éšã©ã€ãã©ãªã«èµ·å ãããšã©ãŒã¯ç¡èŠããå®çšæ§ãæãªããªãããã«ããŸãã | |
| ##### èšå®æ¡ (`[tool.mypy]`ã»ã¯ã·ã§ã³) | |
| - `python_version = "3.12"`: åãã§ãã¯ã®å¯Ÿè±¡ãšãªãPythonããŒãžã§ã³ãæå®ã | |
| - `ignore_missing_imports = true`: åæ å ±ïŒã¹ã¿ãïŒãæäŸãããŠããªãã©ã€ãã©ãªãã€ã³ããŒãããéã®ãšã©ãŒãç¡èŠããŸããããã¯å€ãã®ãããžã§ã¯ãã§å¿ é ã®èšå®ã§ãã | |
| - `disallow_untyped_defs = true`: åãã³ããæžãããŠããªã颿°å®çŸ©ããšã©ãŒãšããŸããããã«ããããããžã§ã¯ãå šäœã§åãã³ãã®èšè¿°ã匷å¶ããã³ãŒãã®å¯èªæ§ãšä¿¡é Œæ§ãé£èºçã«åäžãããŸãã | |
| - `warn_return_any = true`: 颿°ã®è¿ãå€ã®åããææ§ãª`Any`åã«ãªã£ãŠããå Žåã«èŠåãåºããŸããããå ·äœçãªåå®çŸ©ãä¿ãããã°ãæªç¶ã«é²ããŸãã | |
| #### 3. Pytest (ãã¹ããã¬ãŒã ã¯ãŒã¯) | |
| ãã¹ãã®å®è¡æ¹æ³ã«é¢ããèšå®ãå®çŸ©ããŸãã | |
| ##### èšèšæ¹é | |
| - ãã¹ãã®å®è¡ã«é¢ããåºæ¬çãªã«ãŒã«ãå®ãã誰ãå®è¡ããŠãåãçµæãåŸãããããã«ããŸãã | |
| ##### èšå®æ¡ (`[tool.pytest.ini_options]`ã»ã¯ã·ã§ã³) | |
| - `testpaths = ["tests"]`: ãã¹ããã¡ã€ã«ãæ ŒçŽãããŠãããã£ã¬ã¯ããªã`tests`ã«éå®ããŸãã | |
| - `addopts = "-ra --strict-markers"`: ãã¹ãå®è¡æã«ã詳现ãªãµããªãŒã衚瀺ã(`-ra`)ãæªå®çŸ©ã®ãã¹ãããŒã«ãŒã®äœ¿çšãçŠæ¢ãã(`--strict-markers`)ããšã§ããã¹ãã®ç®¡çã峿 Œã«ããŸãã | |
| - `minversion = "7.0"`: ãããžã§ã¯ããèŠæ±ããPytestã®æäœããŒãžã§ã³ã7.0ãšå®ããå€ãããŒãžã§ã³ã§ã®æå³ããªãåäœãé²ããŸãã | |
| ## 10. ãããªãæ€èšäºé (Further Considerations) | |
| ãã®ã»ã¯ã·ã§ã³ã§ã¯ãv1éçºã®ã¹ã³ãŒãå€ãšãã€ã€ããæ¬æ©èœã®å質ãšäŸ¡å€ãç¶ç¶çã«åäžãããããã«ãå°æ¥çã«èª¿æ»ã»å®è£ ãã¹ãé ç®ãèšç»ãšããŠãŸãšããã | |
| ### 10.1. AIã¢ãã«ã®è©äŸ¡ãšæ¹åãµã€ã¯ã« (MLOps) | |
| **ç®ç:** æèŠçãªå€æãæããããŒã¿ã«åºã¥ããŠAIã®å質ã客芳çã«è©äŸ¡ã»æ¹åããä»çµã¿ãæ§ç¯ããã | |
| | é ç® | 調æ»èšç» | ææç© | | |
| | : | : | : | | |
| | **1. 客芳çè©äŸ¡ææšã®å°å ¥** | - èŠçŽã¿ã¹ã¯ã§äžè¬çã«å©çšãããè©äŸ¡ææšïŒROUGE, BERTScoreãªã©ïŒã調æ»ããã<br>- Pythonã®`evaluate`ã©ã€ãã©ãªçã䜿ãããµã³ãã«ããŒã¿ã§å®éã«ã¹ã³ã¢ãç®åºããPoCïŒæŠå¿µå®èšŒïŒãè¡ãã<br>- ã¹ã³ã¢ã®èšç®æ¹æ³ãšããã®çµæã®è§£éã«ã€ããŠç¥èŠããŸãšããã | - è©äŸ¡ææšã®éžå®çç±ãšäœ¿ãæ¹ããŸãšããããã¥ã¡ã³ãã<br>- ã¹ã³ã¢ç®åºçšã®ãµã³ãã«ã¹ã¯ãªããã | | |
| | **2. ããã³ãããšã³ãžãã¢ãªã³ã°** | - ãããžãã£ã/ãã¬ãã£ãåæããç®æ¡æžãããªã©ãè€æ°ã®æç€ºïŒããã³ããïŒåœ¢åŒãèæ¡ããã<br>- åãå ¥åããŒã¿ã«å¯Ÿããåããã³ããã§çæçµæãã©ãå€ããããæ¯èŒã»åæããã<br>- æãèŠçŽã®è³ªãåäžããããã³ããã®ãã³ãã¬ãŒããæ±ºå®ããã | - ããã³ããã®æ¯èŒå®éšã®çµæã¬ããŒãã<br>- æ¡çšããããã³ãããã³ãã¬ãŒãã | | |
| | **3. ã¢ãã«ã®A/Bãã¹ã** | - ç°ãªãã¢ãã«ãããã³ããã®æ§èœãå®ç°å¢ã§æ¯èŒããããã®A/Bãã¹ãåºç€ãæ€èšããã<br>- ãªã¯ãšã¹ãã«å¿ããŠãããã¯ãšã³ãã§ã¢ãã«ãåçã«åãæ¿ããä»çµã¿ãèšèšããã<br>- ãŠãŒã¶ãŒãã£ãŒãããã¯ãããžãã¹ææšïŒäŸ: æ»åšæéïŒãžã®åœ±é¿ãèšæž¬ããæé©ãªã¢ãã«ãéžå®ããã | - A/Bãã¹ãã®èšèšæžã<br>- ã¢ãã«åãæ¿ãããžãã¯ã®å®è£ æ¡ã | | |
| | **4. ã¢ãã«æŽæ°æ¹éã®çå®** | - æ°ããæ¥æ¬èªèŠçŽã¢ãã«ãç»å Žããéã«ãã©ã®ã¿ã€ãã³ã°ã§è©äŸ¡ã»å°å ¥ãè¡ããã®åºæºãèšããã<br>- ãå幎ã«äžåºŠãææ°ã¢ãã«ã調æ»ããããç¹å®ã®è©äŸ¡ææšã10%ä»¥äžæ¹åããå Žåã«æŽæ°ãæ€èšããããªã©ãå ·äœçãªã«ãŒã«ãå®çŸ©ããã | - ã¢ãã«ã®ã©ã€ããµã€ã¯ã«ç®¡çæ¹éæžã | | |
| ### 10.2. å ç¢æ§ãšã¹ã±ãŒã©ããªãã£ã®åäž | |
| **ç®ç:** 倧éã¢ã¯ã»ã¹ãäºæãã¬å ¥åã«å¯ŸããŠããå®å®ããŠé«éãªã¬ã¹ãã³ã¹ãè¿ããã³ã¹ããæé©åããã | |
| | é ç® | 調æ»èšç» | ææç© | | |
| | : | : | : | | |
| | **1. é«åºŠãªå ¥åå岿Šç¥** | - é·å€§ãªå£ã³ã矀ã«å¯Ÿå¿ãããããããã¹ããæå³ã®ããåäœïŒãã£ã³ã¯ïŒã§åå²ãããããããèŠçŽããŠããæçµçã«çµ±åãããMap-Reduceãçãªã¢ãããŒãã調æ»ã»å®è£ ããã<br>- LangChainãªã©ã®ã©ã€ãã©ãªãæäŸããèŠçŽãã§ãŒã³ã®æŽ»çšãæ€èšããã | - ãã£ã³ã¯èŠçŽã®å®è£ PoCã<br>- é·æå ¥åã«å¯Ÿãããšã©ãŒçãåè³ªã®æ¹åã¬ããŒãã | | |
| | **2. éåæAPIåŒã³åºã** | - DjangoããAI APIãåŒã³åºãåŠçãéåæåããWebãµãŒããŒã®ã¯ãŒã«ãŒã¹ã¬ãããé·æéãããã¯ããã®ãé²ãã<br>- CeleryãDramatiqãšãã£ãéåæã¿ã¹ã¯ãã¥ãŒãå°å ¥ããèŠçŽåŠçãããã¯ã°ã©ãŠã³ããžã§ããšããŠå®è¡ããã¢ãŒããã¯ãã£ãèšèšããã<br>- ããã³ããšã³ãåŽã¯ãããŒãªã³ã°ãWebSocketãå©çšããŠããžã§ãã®å®äºãæ€ç¥ãçµæã衚瀺ããæ¹åŒã«å€æŽããã | - éåæåŠçã¢ãŒããã¯ãã£ã®èšèšå³ã<br>- Celeryå°å ¥ã®PoCãšãå¿çæ§èœã®æ¹åå¹ææž¬å®ã¬ããŒãã | | |
| | **3. ãã£ãã·ã¥æŠç¥ã®å°å ¥** | - Djangoã®ãã£ãã·ã¥ãã¬ãŒã ã¯ãŒã¯ïŒRedis, Memcachedãªã©ïŒã®å©ç𿹿³ã調æ»ããã<br>- ãæœèšIDããããŒãšããŠèŠçŽçµæããã£ãã·ã¥ããã¢ãŒããã¯ãã£ãèšèšããã<br>- ãã£ãã·ã¥ã®æå¹æéïŒTTLïŒãã©ã®çšåºŠã«èšå®ãã¹ãããæ¹éãæ±ºå®ããã | - ãã£ãã·ã¥ã·ã¹ãã ã®ã¢ãŒããã¯ãã£å³ã<br>- `settings.py`ãžã®èšå®äŸãšããã¥ãŒã§ã®å©çšã³ãŒãäŸã | | |
| | **4. ã³ã¹ãã»ããã©ãŒãã³ã¹è©Šç®** | - Hugging Face Spacesã®ç¡ææ ã»ææãã©ã³ïŒããŒããŠã§ã¢æ§èœïŒãšæéäœç³»ã調æ»ããã<br>- 1ãªã¯ãšã¹ããããã®å¹³ååŠçæéãšã¡ã¢ãªäœ¿çšéãèšæž¬ããç¡ææ ã®ç¯å²å ã§äœãªã¯ãšã¹ããŸã§åŠçå¯èœã詊ç®ããã<br>- æ³å®ãããã¢ã¯ã»ã¹æ°ã«åºã¥ããæéã®éçšã³ã¹ããšãã¹ã±ãŒã«ã¢ãããå¿ èŠã«ãªãæ¡ä»¶ãå®çŸ©ããã | - ã³ã¹ããšããã©ãŒãã³ã¹ã®è©Šç®ã¬ããŒãã<br>- ã¹ã±ãŒã«ã¢ããèšç»ã | | |
| ### 10.3. éçšãšç£èŠ | |
| **ç®ç:** æ¬çªç°å¢ã«ãããAPIã®çšŒåç¶æ³ãå¯èŠåããåé¡çºçæã«è¿ éãªæ€ç¥ãšå¯Ÿå¿ãå¯èœã«ããã | |
| | é ç® | 調æ»èšç» | ææç© | | |
| | : | : | : | | |
| | **1. ãã°ã®çµ±å管ç** | - DjangoãšGradio APIã®äž¡æ¹ã§ããªã¯ãšã¹ãIDãå ±æããä»çµã¿ãå°å ¥ããã<br>- æ§é åãã°ïŒJSON圢åŒïŒã«ãªã¯ãšã¹ãIDãå«ããããšã§ãDatadogãªã©ã®å€éšãµãŒãã¹ã§ããŠãŒã¶ãŒãªã¯ãšã¹ãããAI APIåŒã³åºããŸã§ã®äžé£ã®ãã°ã暪æçã«è¿œè·¡ã§ããããã«ããã | - ãã°ãã©ãŒãããã®çµ±äžä»æ§ã<br>- æ§é åãã®ã³ã°ã®å®è£ äŸã | | |
| | **2. ããã©ãŒãã³ã¹ç£èŠãšãšã©ãŒã¬ããŒã** | - Hugging Face Spacesãæšæºã§æäŸããåææ©èœïŒAnalyticsïŒã§ååŸã§ããã¡ããªã¯ã¹ã確èªããã<br>- Sentryãªã©ã®ãšã©ãŒã¬ããŒãããŒã«ãå°å ¥ããã¢ããªã±ãŒã·ã§ã³äŸå€ãèªåã§åéã»éç¥ããä»çµã¿ãæ§ç¯ããã<br>- ç¹ã«ç£èŠãã¹ãéèŠææšïŒKPIïŒãå®çŸ©ããïŒäŸ: ãšã©ãŒçã95ããŒã»ã³ã¿ã€ã«å¿çæéãèŠçŽå質ã¹ã³ã¢ïŒã | - ç£èŠããŒã«ã®éžå®ãšæ¯èŒã<br>- ç£èŠKPIãªã¹ããšãã®éŸå€ã®å®çŸ©ã<br>- Sentryå°å ¥æé æžã | | |
| ### 10.4. ãŠãŒã¶ãŒäœéšã®åŒ·å | |
| **ç®ç:** AIã®æ©èœããããŠãŒã¶ãŒãã¬ã³ããªãŒã§ãå€ãã®äººãå©çšããããåœ¢ã§æäŸããã | |
| | é ç® | 調æ»èšç» | ææç© | | |
| | : | : | : | | |
| | **1. ãŠãŒã¶ãŒãã£ãŒãããã¯æ©æ§** | - èŠçŽçµæã«ã圹ã«ç«ã£ãã (ð/ð)ããæç¥šã§ããUIãèšèšããã<br>- ãã£ãŒãããã¯çµæãDjangoã®DBã«ä¿åããããã®ããŒã¿ã¢ãã«ãèšèšããã<br>- åéããããŒã¿ãå°æ¥ã®ã¢ãã«ååŠç¿ãããã³ããæ¹åã«ã©ã掻ããããæ¹éãæ€èšããã | - UIãã¶ã€ã³æ¡ã<br>- `models.py`ã«è¿œå ãããã£ãŒãããã¯ã¢ãã«ã®å®çŸ©ã<br>- ããŒã¿æŽ»çšæ¹éã®æŠèŠã | | |
| | **2. åèŠçŽæ©èœ** | - ãŠãŒã¶ãŒãçæãããèŠçŽã«æºè¶³ããªãã£ãå Žåã«ãç°ãªããã©ã¡ãŒã¿ïŒäŸ: ããçãããã詳ããïŒã§åçæã詊ããUIãèšèšããã<br>- ãèŠçŽã®ããŒã³ãå€ããïŒäŸ: ä¿è·è åããåäŸåãïŒããšãã£ãä»å æ©èœã®å®çŸå¯èœæ§ã調æ»ããã | - åèŠçŽæ©èœã®UIãã¶ã€ã³æ¡ã<br>- ãã©ã¡ãŒã¿å€æŽæ©èœã®å®è£ æ¹éã | | |
| | **3. ã¢ã¯ã»ã·ããªã㣠(a11y) 察å¿** | - ã¢ãŒãã«è¡šç€ºããã¿ã³æäœããã¹ã¯ãªãŒã³ãªãŒããŒïŒèŠèŠé害è åãèªã¿äžããœããïŒã§æ£ããèªèã»æäœã§ãããæ€èšŒããã<br>- WCAG (Web Content Accessibility Guidelines) ã®äž»èŠãªé ç®ã«åºã¥ããããŒããŒãã®ã¿ã§ã®æäœãå¯èœããååãªã³ã³ãã©ã¹ãæ¯ã確ä¿ãããŠããããªã©ã確èªããã | - ã¢ã¯ã»ã·ããªãã£ã®ãã§ãã¯ãªã¹ãã<br>- 察å¿ãå¿ èŠãªç®æã®ä¿®æ£æ¡ã | | |
| ## 11. å®è£ ã¿ã¹ã¯ãªã¹ãïŒè©³çްçïŒ | |
| ãã®ã»ã¯ã·ã§ã³ã§ã¯ãTDDïŒãã¹ãé§åéçºïŒã®ãµã€ã¯ã«ã«åºã¥ããå®è£ ã®è©³çŽ°ãªæé ãéå±€çã«å®çŸ©ããŸãã | |
| - **æ åœ: AI** - ãã®ã¢ã€ã³ã³ãä»ããŠããã¿ã¹ã¯ã¯ãAIïŒGeminiïŒãã³ãŒãçæããã¡ã€ã«äœæãçŽæ¥å®è¡ã§ããŸãã | |
| - **æ åœ: 人é** - ãã®ã¢ã€ã³ã³ãä»ããŠããã¿ã¹ã¯ã¯ãéçºè ã«ããæåã§ã®å®è¡ã倿ããŸãã¯æ¿èªãå¿ èŠã§ãã | |
| ### ãã§ãŒãº0: ãããžã§ã¯ãã®åæå | |
| **ç®ç:** æ°ãããããžã§ã¯ãã®äœæ¥ãéå§ããããã®æºåãè¡ãã | |
| - [x] **äžã¿ã¹ã¯0.1: ãããžã§ã¯ãã«ãŒããã£ã¬ã¯ããªã®äœæ** | |
| - **æ åœ:** 人é | |
| - **å 容:** äœæ¥ãéå§ãããã£ã¬ã¯ããªã«ããããžã§ã¯ãã®ã«ãŒããšãªã `kids-playground-ai-api` ãã£ã¬ã¯ããªãäœæãããã®äžã«ç§»åããŠãã ããã | |
| - **æç€º:** 以äžã®ã³ãã³ããå®è¡ããŠãã ããã | |
| ```bash | |
| mkdir kids-playground-ai-api | |
| cd kids-playground-ai-api | |
| ``` | |
| - [x] **äžã¿ã¹ã¯0.2: Git管çã®éå§ãšåæã³ããã** | |
| - **æ åœ:** 人é | |
| - **å 容:** ãããžã§ã¯ãã®Git管çãéå§ãã`.gitignore`ãèšå®ããŠäžèŠãªãã¡ã€ã«ã管ç察象ããé€å€ããåæã³ããããè¡ããŸãã | |
| - **æç€º:** ãããžã§ã¯ãã«ãŒããã£ã¬ã¯ããªã§ä»¥äžã®ã³ãã³ããå®è¡ããŠãã ããã | |
| ```bash | |
| git init | |
| # .gitignore ãã¡ã€ã«ãäœæãŸãã¯ç·šéããé©åãªå 容ãèšè¿° | |
| # äŸ: | |
| # echo "__pycache__\nvirtualenv/\.env" > .gitignore | |
| git add . | |
| git commit -m "Initial commit" | |
| ``` | |
| - [x] **äžã¿ã¹ã¯0.3: GitHubãªããžããªã®äœæãšé£æº** | |
| - **æ åœ:** 人é | |
| - **å 容:** GitHubäžã«æ°ãããªããžããªãäœæããããŒã«ã«ãªããžããªãšé£æºãããŸãã | |
| - **æç€º:** | |
| 1. GitHubã«ãã°ã€ã³ããæ°ãããªããžããªãäœæããŸãïŒãªããžããªå㯠`kids-playground-ai-api` ãªã©ïŒãREADMEã.gitignoreãã©ã€ã»ã³ã¹ã®è¿œå ã¯ã¹ãããããŠãã ããã | |
| 2. äœæããããªããžããªããŒãžã«è¡šç€ºãããæç€ºã«åŸããããŒã«ã«ãªããžããªããªã¢ãŒãã«ããã·ã¥ããŸãã | |
| ```bash | |
| git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPOSITORY_NAME.git | |
| git branch -M main | |
| git push -u origin main | |
| ``` | |
| - [x] **äžã¿ã¹ã¯0.4: Hugging Faceã¢ã«ãŠã³ãã®ç»é²ãšSpacesã®æºå** | |
| - **æ åœ:** 人é | |
| - **å 容:** Hugging Faceã¢ã«ãŠã³ããç»é²ããAIã¢ãã«ããããã€ããããã®Hugging Face SpaceãæºåããŸãã | |
| - **æç€º:** | |
| 1. Hugging Faceã®ãŠã§ããµã€ã (huggingface.co) ã«ã¢ã¯ã»ã¹ããã¢ã«ãŠã³ããç»é²ããŸãã | |
| 2. ãã°ã€ã³åŸããSpacesãã»ã¯ã·ã§ã³ã«ç§»åãããCreate new Spaceããã¯ãªãã¯ããŸãã | |
| 3. Spaceåãã©ã€ã»ã³ã¹ãSDKïŒGradioãéžæïŒãå ¬é/éå ¬éèšå®ãªã©ãé©åã«èšå®ããSpaceãäœæããŸãã | |
| - [x] **äžã¿ã¹ã¯0.5: ã©ã€ã»ã³ã¹ãã¡ã€ã«ã®äœæ** | |
| - **æ åœ:** AI | |
| - **å 容:** ãããžã§ã¯ãã®ã©ã€ã»ã³ã¹ãã¡ã€ã«ã`LICENSE`ãšããååã§äœæããŸãã | |
| - **æç€º:** ãããžã§ã¯ãã®ã«ãŒããã£ã¬ã¯ããªã«`LICENSE`ãã¡ã€ã«ãäœæããé©åãªã©ã€ã»ã³ã¹ïŒäŸ: MIT LicenseïŒã®å 容ãèšè¿°ããŠãã ããã | |
| ### ãã§ãŒãº1: éçºç°å¢ã®ã»ããã¢ãã | |
| **ç®ç:** ã³ãŒãã£ã³ã°ãéå§ããåã«ãåè³ªãæ ä¿ããéçºãå¹çåããããã®åºç€ãæ§ç¯ããã | |
| - [x] **äžã¿ã¹ã¯1.0: ããã¥ã¡ã³ãã®é 眮** | |
| - **æ åœ:** AI | |
| - **å 容:** ãã®éçºã¬ã€ã (`ai_api_development_guide.md`) ã `docs/` ãã£ã¬ã¯ããªã«é 眮ããŸãã | |
| - **æç€º:** 以äžã®ã³ãã³ããå®è¡ããŠãã ããã | |
| ```bash | |
| cp /path/to/current/ai_api_development_guide.md docs/ai_api_development_guide.md | |
| ``` | |
| * *泚: `/path/to/current/ai_api_development_guide.md` ã¯ããã®ããã¥ã¡ã³ããçŸåšçœ®ãããŠãã絶察ãã¹ã«çœ®ãæããå¿ èŠããããŸãã* | |
| - [x] **äžã¿ã¹ã¯1.1: ãããžã§ã¯ãæ§é ã®åæã»ããã¢ãã** | |
| - **æ åœ:** AI | |
| - **å 容:** 以äžã®ãã£ã¬ã¯ããªãšãã¡ã€ã«ããããžã§ã¯ãã«ãŒãã«äœæããŸãã | |
| - ãã£ã¬ã¯ããª: `src/ai_api/core`, `tests/core`, `docs`, `.github/workflows` | |
| - ãã¡ã€ã«: `.gitignore`, `Dockerfile`, `pyproject.toml`, `requirements.txt`, `README.md`, `.github/workflows/ci.yml` (空ãã¡ã€ã«ãšããŠ) | |
| - **æç€º:** 以äžã®ã³ãã³ããå®è¡ããŠããããžã§ã¯ãã®åæãã£ã¬ã¯ããªãšãã¡ã€ã«ãæºåããŠãã ããã | |
| ```bash | |
| mkdir -p src/ai_api/core tests/core docs .github/workflows | |
| touch .gitignore Dockerfile pyproject.toml requirements.txt README.md .github/workflows/ci.yml | |
| ``` | |
| - [x] **äžã¿ã¹ã¯1.2: å質管çããŒã«ã®èšå®** | |
| - [x] **å°ã¿ã¹ã¯1.2.1: `pyproject.toml` ã®èšå®** | |
| - **æ åœ:** AI | |
| - **å 容:** ã»ã¯ã·ã§ã³ `9.10` ã®èšèšã«åºã¥ããRuff, Mypy, Pytestã®èšå®ãèšè¿°ãã `pyproject.toml` ãã¡ã€ã«ãæŽæ°ããŸãã | |
| - **æç€º:** `/home/jam/kids-playground-ai-api/pyproject.toml` ãæŽæ°ããŠãã ããã | |
| - [x] **å°ã¿ã¹ã¯1.2.2: `pre-commit`ããã¯ã®èšå®ãšã€ã³ã¹ããŒã«** | |
| - **æ åœ:** AI | |
| - **å 容:** `pre-commit`ããã¯ãèšå®ããGitã³ãããæã«èªåã§ã³ãŒããã§ãã¯ãèµ°ãããã«ããŸãã | |
| - **æç€º:** `.pre-commit-config.yaml`ãäœæããã³ã³ããå ã§`pre-commit install`ãå®è¡ããŠãã ããã | |
| - [x] **äžã¿ã¹ã¯1.3: äŸåé¢ä¿ã®ç®¡ç** | |
| - [x] **å°ã¿ã¹ã¯1.3.1: `requirements.txt` ã®èšå®** | |
| - **æ åœ:** AI | |
| - **å 容:** ã©ã€ãã©ãªãèšè¿°ãã `requirements.txt` ãæŽæ°ããŸãã | |
| - **æç€º:** `/home/jam/kidsPlayGround/requirements.txt` ãæŽæ°ããŠãã ããã | |
| ``` | |
| # AI App | |
| gradio | |
| transformers | |
| torch | |
| # Testing | |
| pytest | |
| requests | |
| # Linting & Formatting | |
| ruff | |
| mypy | |
| ``` | |
| - [x] **å°ã¿ã¹ã¯1.3.2: Dockeréçºç°å¢ã®æ§ç¯ãšèµ·å** | |
| - **æ åœ:** 人é | |
| - **å 容:** Docker Desktopãå©çšããŠããããžã§ã¯ãã®Dockeréçºç°å¢ãæ§ç¯ããèµ·åããŸããããã«ãããå¿ èŠãªäŸåé¢ä¿ãã³ã³ããå ã«èªåçã«ã€ã³ã¹ããŒã«ãããŸãã | |
| - **æç€º:** | |
| 1. Docker Desktopãã€ã³ã¹ããŒã«ãããèµ·åããŠããããšã確èªããŠãã ããã | |
| 2. ãããžã§ã¯ãã®ã«ãŒããã£ã¬ã¯ããªã§ã以äžã®ã³ãã³ããå®è¡ããŠDockerã³ã³ããããã«ãããããã¯ã°ã©ãŠã³ãã§èµ·åããŸãã | |
| ```bash | |
| docker-compose up --build -d | |
| ``` | |
| 3. ã³ã³ãããæ£åžžã«èµ·åããããDjangoã¢ããªã±ãŒã·ã§ã³ã¯ `http://localhost:8000`ãAI API (Gradio) 㯠`http://localhost:7860` ã§ã¢ã¯ã»ã¹å¯èœã«ãªããŸãã | |
| - [x] **äžã¿ã¹ã¯1.4: ç°å¢å€æ°èšå®ãã¡ã€ã«ã®æºå (`.env`, `.env.example`)** | |
| - **æ åœ:** AI | |
| - **å 容:** ç°å¢å€æ°èšå®ãã¡ã€ã«ïŒ`.env`ïŒãšãã®ãã³ãã¬ãŒãïŒ`.env.example`ïŒãäœæããŸãã | |
| - **æç€º:** ãããžã§ã¯ãã®ã«ãŒããã£ã¬ã¯ããªã«`.env`ãã¡ã€ã«ãš`.env.example`ãã¡ã€ã«ãäœæããŠãã ããã | |
| ### ãã§ãŒãº2: CI/CDæ€èšŒçšãµã³ãã«ã¢ããªã±ãŒã·ã§ã³ã®äœæ | |
| **ç®ç:** CI/CDãã€ãã©ã€ã³ãå šäœãšããŠæ©èœããããšãæ€èšŒããããã®ãæãã·ã³ãã«ãªãHello WorldãçãªGradioã¢ããªã±ãŒã·ã§ã³ãäœæããã | |
| - [ ] **äžã¿ã¹ã¯2.1: Gradioãµã³ãã«ã³ãŒãã®å®è£ ** | |
| - [ ] **å°ã¿ã¹ã¯2.1.1 (RED):** `main.py`ã®ãã¹ããäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `tests/test_main.py`ãäœæãã`main.py`ã®`greet`颿°ãç¹å®ã®æååãè¿ãããšãæåŸ ãããã¹ããèšè¿°ããŸãããã®æç¹ã§ã¯`main.py`ã`greet`颿°ãååšããªãããããã¹ãã¯å€±æããŸãã | |
| - [ ] **å°ã¿ã¹ã¯2.1.2 (GREEN):** `main.py`ã«ãµã³ãã«ãå®è£ | |
| - **æ åœ:** AI | |
| - **å 容:** `src/ai_api/main.py`ã«ãç°¡åãª`greet`颿°ãšããããåŒã³åºãGradioã€ã³ã¿ãŒãã§ãŒã¹ãå®è£ ãããã¹ãããã¹ãããŸãã | |
| - [ ] **å°ã¿ã¹ã¯2.1.3 (REFACTOR):** ãªãã¡ã¯ã¿ãªã³ã° | |
| - **æ åœ:** AI | |
| - **å 容:** ã³ãŒããæŽçããå¯èªæ§ãé«ããŸãã | |
| ### ãã§ãŒãº3: CI/CDã®æ§ç¯ãšããã〠| |
| **ç®ç:** ã³ãŒãã®å質ãèªåçã«æ€èšŒããHugging Face Spacesãžèªåçã«ãããã€ããä»çµã¿ãæ§ç¯ããã | |
| - [ ] **äžã¿ã¹ã¯3.1: CIã¯ãŒã¯ãããŒã®æ§ç¯ (GitHub Actions)** | |
| - [ ] **å°ã¿ã¹ã¯3.1.1 (RED):** CIèšå®ãã¡ã€ã«ã®éªšæ Œäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `.github/workflows/ci.yml` ãäœæããŸããæåã¯ããªã¬ãŒã ããèšè¿°ããå ·äœçãªãžã§ãã¯ç©ºã«ããŠãããŸãããã®æç¹ã§ã¯äœãå®è¡ãããŸããã | |
| - [ ] **å°ã¿ã¹ã¯3.1.2 (GREEN):** CIãžã§ãã®å®è£ | |
| - **æ åœ:** AI | |
| - **å 容:** `ci.yml` ã«ãPythonã®ã»ããã¢ãããäŸåé¢ä¿ã®ã€ã³ã¹ããŒã«ã`ruff`ã«ããlintãã§ãã¯ã`mypy`ã«ããåãã§ãã¯ã`pytest`ã«ãããã¹ãå®è¡ã®ã¹ãããã远å ããŸãã | |
| - **æç€º:** `/home/jam/kids-playground-ai-api/.github/workflows/ci.yml` ãæŽæ°ããŠãã ããã | |
| - [ ] **å°ã¿ã¹ã¯3.1.3 (REFACTOR):** ã¯ãŒã¯ãããŒã®æé©å | |
| - **æ åœ:** AI | |
| - **å 容:** ãã£ãã·ã¥æ©æ§ãªã©ãå°å ¥ããCIã®å®è¡æéãççž®ããŸãã | |
| - [ ] **å°ã¿ã¹ã¯3.1.4: CIã®åäœç¢ºèª** | |
| - **æ åœ:** 人é | |
| - **å 容:** ãã®å€æŽãGitHubã«ããã·ã¥ããGitHubã®ãActionsãã¿ãã§ã¯ãŒã¯ãããŒãæ£ããå®è¡ãããå šãŠã®ãã§ãã¯ãæåããããšã確èªããŸãã | |
| - [ ] **äžã¿ã¹ã¯3.2: CDã¯ãŒã¯ãããŒã®æ§ç¯ (GitHub Actions)** | |
| - [ ] **å°ã¿ã¹ã¯3.2.1: Hugging Faceã¢ã¯ã»ã¹ããŒã¯ã³ã®æºå** | |
| - **æ åœ:** 人é | |
| - **å 容:** Hugging Faceã®èšå®ããŒãžã§`write`æš©éãæã€ã¢ã¯ã»ã¹ããŒã¯ã³ãçºè¡ãããããGitHubãªããžããªã®Secretsã«`HF_TOKEN`ãšããŠç»é²ããŸãã | |
| - [ ] **å°ã¿ã¹ã¯3.2.2 (RED):** ãããã€ãžã§ãã®éªšæ Œäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `ci.yml`ã«ã`test`ãžã§ãã®æååŸã«`main`ãã©ã³ãã§ã®ã¿å®è¡ããã`deploy-to-hf-space`ãžã§ãã远å ããŸããæåã¯ç°¡åãª`echo`ã³ãã³ãã®ã¿ãèšè¿°ãããããã€ãå®è¡ãããªãç¶æ ã«ããŸãã | |
| - [ ] **å°ã¿ã¹ã¯3.2.3 (GREEN):** ãããã€ãžã§ãã®å®è£ | |
| - **æ åœ:** AI | |
| - **å 容:** `deploy-to-hf-space`ãžã§ãã«ã`hugging-face/push-to-hub`ã¢ã¯ã·ã§ã³ã远å ããSecretsã«ç»é²ãã`HF_TOKEN`ã䜿ã£ãŠHugging Face Spacesã«ã³ãŒããããã·ã¥ããããã«å®è£ ããŸãã | |
| - [ ] **å°ã¿ã¹ã¯3.2.4: CDã®åäœç¢ºèª** | |
| - **æ åœ:** 人é | |
| - **å 容:** CI/CDãæåããã³ãããã`main`ãã©ã³ãã«ããŒãžããGitHubã®ãActionsãã¿ãã§ãããã€ãžã§ããæåããããšã確èªããŸãããã®åŸãHugging Face Spaceã®å ¬éURLã«ã¢ã¯ã»ã¹ããã¢ããªã±ãŒã·ã§ã³ãæ£ãããããã€ãããŠããããšã確èªããŸãã | |
| ### ãã§ãŒãº4: AIã¢ããªã±ãŒã·ã§ã³ã®TDD (ã³ã¢ããžã㯠â API) | |
| **ç®ç:** ã¯ãªãŒã³ã¢ãŒããã¯ãã£ã®ååã«åŸããå åŽã®ããžãã¹ããžãã¯ããå€åŽã®APIãžãšå®è£ ãé²ããã | |
| - [ ] **äžã¿ã¹ã¯4.1: AIã³ã¢ããžã㯠`Summarizer` ã®å®è£ ** | |
| - [ ] **å°ã¿ã¹ã¯4.1.1 (RED):** `Summarizer`ã¯ã©ã¹ã®ãã¹ãäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `tests/core/test_inference.py` ãäœæããã`from src.ai_api.core.inference import Summarizer` ãæåããããšãããã¹ãããŸãããã®ãã¹ãã¯ããã¡ã€ã«ãã¯ã©ã¹ãååšããªããã倱æããŸãã | |
| - [ ] **å°ã¿ã¹ã¯4.1.2 (GREEN):** `Summarizer`ã¯ã©ã¹ã®éªšæ Œäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `src/ai_api/core/inference.py` ãšã空ã®`Summarizer`ã¯ã©ã¹ãäœæãããã¹ãããã¹ãããŸãã | |
| - [ ] **å°ã¿ã¹ã¯4.1.3 (REFACTOR):** ãªãã¡ã¯ã¿ãªã³ã° | |
| - **æ åœ:** AI | |
| - **å 容:** ãã®æç¹ã§ã¯ç¹ã«ãªããã³ãããã®åºåããšããŸãã | |
| - [ ] **äžã¿ã¹ã¯4.2: AIèšå®ã¯ã©ã¹ `Config` ã®å®è£ ãšæ³šå ¥** | |
| - [ ] **å°ã¿ã¹ã¯4.2.1 (RED):** `Summarizer`ãèšå®ãªããžã§ã¯ããåãåããã¹ãäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `tests/core/test_inference.py`ã«è¿œèšããŸãã | |
| - **å 容:** `Summarizer`ãã³ã³ã¹ãã©ã¯ã¿ã§èšå®ãªããžã§ã¯ãïŒã¢ãã«åãªã©ïŒãåãåãããšãæåŸ ãããã¹ãã`tests/core/test_inference.py`ã«è¿œèšããŸãã | |
| - [ ] **å°ã¿ã¹ã¯4.2.2 (GREEN):** èšå®ã¯ã©ã¹ã®äœæãšã³ã³ã¹ãã©ã¯ã¿ä¿®æ£ | |
| - **æ åœ:** AI | |
| - **å 容:** `src/ai_api/config.py`ã«èšèšéãã®èšå®ã¯ã©ã¹ïŒ`ModelConfig`ãªã©ïŒãäœæããŸãã`Summarizer`ã®`__init__`ãä¿®æ£ããèšå®ãªããžã§ã¯ããåãåãããã«ããŸãã | |
| - [ ] **å°ã¿ã¹ã¯4.2.3 (REFACTOR):** ãªãã¡ã¯ã¿ãªã³ã° | |
| - **æ åœ:** AI | |
| - **å 容:** ã³ãŒãã®å¯èªæ§ãåäžãããŸãã **ãã®æç¹ã§ãAIã¢ãã«ãåãæ¿ããããã®åºæ¬çãªä»çµã¿ïŒèšå®å€ãå€éšããäžããïŒã宿ããŸãã** | |
| - [ ] **äžã¿ã¹ã¯4.3: èŠçŽæ©èœ `summarize` ã¡ãœããã®å®è£ ** | |
| - [ ] **å°ã¿ã¹ã¯4.3.1 (RED):** `summarize`ã¡ãœããã®ãŠããããã¹ãäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `unittest.mock.patch`ã䜿ãã`transformers.pipeline`ãã¢ãã¯ïŒåœç©ã«å·®ãæ¿ãïŒããŸããã`summarize`ã¡ãœãããåŒã¶ãšãå éšã§`pipeline`ãç¹å®ã®åŒæ°ã§åŒã°ããã¢ãã¯ã®è¿ãå€ããã®ãŸãŸè¿ãããããšãããã¹ãããŸããããã«ãããéãã¢ãã«ãããŒãããã«ããžãã¯ã ããé«éã«ãã¹ãã§ããŸãã | |
| - [ ] **å°ã¿ã¹ã¯4.3.2 (GREEN):** `summarize`ã¡ãœããã®å®è£ | |
| - **æ åœ:** AI | |
| - **å 容:** `Summarizer`ã¯ã©ã¹ã«`summarize`ã¡ãœãããå®è£ ããå éšã§`transformers.pipeline`ãåŒã³åºããŠèŠçŽãå®è¡ããããã«ããŸãã | |
| - [ ] **å°ã¿ã¹ã¯4.3.3 (REFACTOR):** ãªãã¡ã¯ã¿ãªã³ã° | |
| - **æ åœ:** AI | |
| - **å 容:** ãšã©ãŒãã³ããªã³ã°ãªã©ã远å ããã³ãŒããæŽçããŸãã | |
| - [ ] **äžã¿ã¹ã¯4.4: APIãšã³ããªãŒãã€ã³ã `main.py` ã®å®è£ ** | |
| - [ ] **å°ã¿ã¹ã¯4.4.1 (RED):** APIã®ã€ã³ãã°ã¬ãŒã·ã§ã³ãã¹ãäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `tests/test_api.py`ãäœæããŸãããã¹ãå ã§Gradioã¢ããªãå¥ã¹ã¬ããã§èµ·åãã`requests.post`ã§`/api/predict/`ã«ãªã¯ãšã¹ããéä¿¡ããŠãæåŸ ããå¿çãåŸãããªãïŒãµãŒããŒããªãããïŒããšã確èªããŸãã | |
| - [ ] **å°ã¿ã¹ã¯4.4.2 (GREEN):** `main.py`ã®å®è£ | |
| - **æ åœ:** AI | |
| - **å 容:** `src/ai_api/main.py`ãäœæããŸãã`Summarizer`ãšèšå®ã¯ã©ã¹ãã€ã³ã¹ã¿ã³ã¹åããDIïŒäŸåæ§ã®æ³šå ¥ïŒããŠGradioã®`Interface`ãå®çŸ©ã»èµ·åããŸãã | |
| - [ ] **å°ã¿ã¹ã¯4.4.3 (REFACTOR):** ãªãã¡ã¯ã¿ãªã³ã° | |
| - **æ åœ:** AI | |
| - **å 容:** ã³ãŒããæŽçããŸãã | |
| - [ ] **å°ã¿ã¹ã¯4.4.4: æåã§ã®åäœç¢ºèª** | |
| - **æ åœ:** 人é | |
| - **å 容:** `python src/ai_api/main.py` ãå®è¡ãããã©ãŠã¶ã§è¡šç€ºãããGradioã®UIã«ããã¹ããå ¥åããŠãèŠçŽæ©èœãåäœã§æ£ããåäœããããšã確èªããŸãã | |
| ### ãã§ãŒãº5: Djangoãžã®çµã¿èŸŒã¿ | |
| **ç®ç:** ç¬ç«ããŠåäœããAIã¢ããªã±ãŒã·ã§ã³ããDjangoããAPIçµç±ã§å®å šã«åŒã³åºãã | |
| - [ ] **äžã¿ã¹ã¯5.1: DjangoåŽã®APIã¯ã©ã€ã¢ã³ãå®è£ ** | |
| - [ ] **å°ã¿ã¹ã¯5.1.1 (RED):** APIã¯ã©ã€ã¢ã³ãã®ãã¹ãäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `myapp/tests/test_clients.py`ãäœæããŸãã`requests.post`ãã¢ãã¯åãããŠããç¶æ ã§APIã¯ã©ã€ã¢ã³ã颿°ãåŒã³åºããæåæã»ã¿ã€ã ã¢ãŠãæã»ãµãŒããŒãšã©ãŒæã®æåããã¹ãããŸãã | |
| - [ ] **å°ã¿ã¹ã¯5.1.2 (GREEN):** APIã¯ã©ã€ã¢ã³ãã®å®è£ | |
| - **æ åœ:** AI | |
| - **å 容:** `myapp/clients/ai_summary_client.py`ãäœæãã`requests`ã䜿ã£ãŠå€éšAPIãåŒã³åºã颿°ãå®è£ ããŸãã | |
| - [ ] **å°ã¿ã¹ã¯5.1.3 (REFACTOR):** ãªãã¡ã¯ã¿ãªã³ã° | |
| - **æ åœ:** AI | |
| - **å 容:** èšå®ã`settings.py`ããèªã¿èŸŒãããã«ãããªã©ãã³ãŒããæŽçããŸãã | |
| - [ ] **äžã¿ã¹ã¯5.2: Django Viewã®å®è£ ** | |
| - [ ] **å°ã¿ã¹ã¯5.2.1 (RED):** Viewã®URLãã¹ãäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `myapp/tests/test_views.py`ã«ã`/summarize/playground/{id}/`ãžã®GETãªã¯ãšã¹ãã404ãè¿ããã¹ããæžããŸãã | |
| - [ ] **å°ã¿ã¹ã¯5.2.2 (GREEN):** URLãšViewã®éªšæ Œäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `myapp/urls.py`ãš`myapp/views/summary_views.py`ãäœæã»ç·šéãããã¹ãããã¹ãããŸãã | |
| - [ ] **å°ã¿ã¹ã¯5.2.3 (RED):** Viewãšã¯ã©ã€ã¢ã³ãã®é£æºãã¹ãäœæ | |
| - **æ åœ:** AI | |
| - **å 容:** `unittest.mock.patch`ã§APIã¯ã©ã€ã¢ã³ããã¢ãã¯åãããViewãåŒã³åºããšãå éšã§APIã¯ã©ã€ã¢ã³ããç¹å®ã®åŒæ°ã§åŒã°ããããšãããã¹ãããŸãã | |
| - [ ] **å°ã¿ã¹ã¯5.2.4 (GREEN):** Viewããžãã¯ã®å®è£ | |
| - **æ åœ:** AI | |
| - **å 容:** Viewå ã§å£ã³ãã®ååŸã»æ€èšŒããžãã¯ãããã³APIã¯ã©ã€ã¢ã³ãã®åŒã³åºããå®è£ ããŸãã | |
| - [ ] **å°ã¿ã¹ã¯5.2.5 (REFACTOR):** ãªãã¡ã¯ã¿ãªã³ã° | |
| - **æ åœ:** AI | |
| - **å 容:** ã³ãŒããæŽçããŸãã | |
| - [ ] **äžã¿ã¹ã¯5.3: çµ±åãã¹ã** | |
| - [ ] **å°ã¿ã¹ã¯5.3.1: æåã§ã®æçµç¢ºèª** | |
| - **æ åœ:** 人é | |
| - **å 容:** DjangoãµãŒããŒãšAIã¢ããªïŒGradioïŒãäž¡æ¹ããŒã«ã«ã§èµ·åãããã©ãŠã¶ããæåã®èŠçŽãã¿ã³ãã¯ãªãã¯ããŠãå šäœã®æµããæ£ããåäœãããã確èªããŸãã | |
| ``` |