A newer version of the Gradio SDK is available:
5.45.0
AI API éçºã¬ã€ã
ãã®ããã¥ã¡ã³ãã¯ãHugging Face SpacesãšGradioãå©çšããAI APIã®éçºç°å¢æ§ç¯ãšããã®åŸã®éçºããã»ã¹ã«é¢ããèŠç¹ããŸãšãããã®ã§ãã
1. æŠèŠ
1.1. ç®çãšæ©èœæŠèŠ
æ¬ãããžã§ã¯ãã®ç®çã¯ãã芪åã§éãŒããããã«AIãæŽ»çšããå£ã³ãã®èªåèŠçŽæ©èœãå®è£ ããããšã§ãã
- ç®ç: ãŠãŒã¶ãŒã倿°ã®å£ã³ããå šãŠèªãã§ããæœèšã®å šäœçãªè©å€ãçŽ æ©ãããã€å®¢èгçã«ææ¡ã§ããããã«ããã
- ãŠãŒã¶ãŒäœéš:
- ãŠãŒã¶ãŒã¯æœèšã®è©³çްããŒãžã§ãå£ã³ããAIèŠçŽããã¿ã³ãã¯ãªãã¯ããŸãã
- AIããã®æœèšã®å šå£ã³ããåæãããããžãã£ããªç¹ããšã泚æãå¿ èŠãªç¹ããªã©ããŸãšããäžç«çãªèŠçŽæãçæããŸãã
- çæãããèŠçŽãã¢ãŒãã«ãŠã£ã³ããŠçã§è¡šç€ºããããŠãŒã¶ãŒã¯çæéã§æœèšã®é·æãšçæãçè§£ã§ããŸãã
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. ã¢ãŒããã¯ãã£å³
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
ãæå®ããŠèµ·åããããšãå¯èœã§ãã
# -d ãã©ã°ã§ããã¯ã°ã©ãŠã³ãã§èµ·å
docker-compose up --build -d
ããã«ãããåãµãŒãã¹ãã³ã³ãããšããŠèµ·åããŸãã
- Djangoã¢ããªã±ãŒã·ã§ã³:
http://localhost:8000
- AI API (Gradio):
http://localhost:7860
2.4. ãããã°æ¹æ³
ã³ã³ããå ã§åé¡ãçºçããå Žåã以äžã®ã³ãã³ãã§ã³ã³ããã®å éšã«å ¥ãããããã°äœæ¥ãè¡ãããšãã§ããŸãã
# <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. æšå¥šã¯ãŒã¯ãããŒ
- CI (GitHub Actions): ãã«ãªã¯ãšã¹ãäœææã
main
ãã©ã³ããžã®ããã·ã¥æã«ãGitHub Actionsãèµ·åããpytest
ã«ããèªåãã¹ãïŒãŠããããã¹ããšã€ã³ãã°ã¬ãŒã·ã§ã³ãã¹ãïŒãå®è¡ããŸãã - 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:
- Hugging Faceã®å人èšå®ã§ã
write
æš©éãæã€ã¢ã¯ã»ã¹ããŒã¯ã³ãçºè¡ããŸãã - çºè¡ããããŒã¯ã³ããGitHubãªããžããªã®
Settings > Secrets and variables > Actions
ã«HF_TOKEN
ãšããŠç»é²ããŸãã ci.yml
å ã®ãããã€ãžã§ãã¯ããã®HF_TOKEN
ãå®å šã«å©çšããŠHugging Faceãžã®èªèšŒãè¡ããŸãã
- Hugging Faceã®å人èšå®ã§ã
7. ã»ãã¥ãªãã£ãšå©çšå¶é
7.1. APIèªèšŒ
課é¡: Hugging Face Spacesã§å ¬éãããAPIã¯ãããã©ã«ãã§ã¯èª°ã§ãã¢ã¯ã»ã¹å¯èœãªç¶æ ã«ãªããŸããæå³ããªãå©çšãæ»æãé²ããããèªèšŒãå°å ¥ããå¿ èŠããããŸãã
察ç: Gradioãæšæºã§æäŸãããã¹ã¯ãŒãèªèšŒæ©èœãå©çšããŸãã
- èªèšŒæ
å ±ã®èšå®:
GRADIO_PASSWORD
: APIãä¿è·ããããã®ãã¹ã¯ãŒããç°å¢å€æ°ã§èšå®ããŸãã
- Secretsãžã®ç»é²:
- APIãµãŒããŒåŽ (Hugging Face):
GRADIO_PASSWORD
ã®å€ããHugging Face Spacesã®Secretsã«ç»é²ããŸãã - ã¯ã©ã€ã¢ã³ãåŽ (Renderãªã©): åããã¹ã¯ãŒãããã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã®ç°å¢å€æ°
AI_SUMMARY_API_KEY
ãšããŠç»é²ããŸãã
- APIãµãŒããŒåŽ (Hugging Face):
- èªèšŒã®å®è£
:
- GradioåŽ:
iface.launch(auth=(username, password))
ã®åœ¢åŒã§èªèšŒãæå¹ã«ããŸãããŠãŒã¶ãŒåã¯çŸåšgemini
ã§åºå®ãããŠããããã¹ã¯ãŒãã¯ç°å¢å€æ°ããèªã¿èŸŒãŸããŸãã - ã¯ã©ã€ã¢ã³ãåŽ:
gradio_client
ãå©çšããéãauth=("gemini", api_key)
ã®ããã«èªèšŒæ å ±ãæž¡ããŠAPIãåŒã³åºããŸãã
- GradioåŽ:
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):
{ "data": [ "å£ã³ãå šæãçµåããæåå..." ] }
9.1.3. ã¬ã¹ãã³ã¹ä»æ§ (Gradio API â Django)
æåæ (HTTP 200 OK):
- ãã㣠(JSON):
{ "data": [ "AIã«ãã£ãŠçæãããèŠçŽæ..." ], "duration": 3.5 }
å€±ææ (HTTP 500 Internal Server Error):
- ãã㣠(JSON):
{ "error": "GradioåŽã§èšå®ãããšã©ãŒã¡ãã»ãŒãž" }
9.2. UI/UXèšèš (å£ã³ãèŠçŽæ©èœ v1)
ãŠãŒã¶ãŒãæ©èœãçŽæçã«å©çšã§ããã·ã¹ãã ã®å¿çãå¿«é©ã«åŸ ãŠãããã«ã以äžã®éãUI/UXãèšèšããŸãã
9.2.1. æäœãããŒ
- ããªã¬ãŒ: ãŠãŒã¶ãŒãæœèšè©³çްããŒãžã®ãå£ã³ããAIèŠçŽããã¿ã³ãã¯ãªãã¯ããŸãã
- ããŒãã£ã³ã°: ãã¿ã³ãç¡å¹åããããçæäžã§ã...ããšããããã¹ããšã¹ãããŒïŒå転ããã¢ã€ã³ã³ïŒã衚瀺ãããŸããããã«ãããåŠçäžã§ããããšããŠãŒã¶ãŒã«æç¢ºã«äŒãããŸãã
- çµæè¡šç€º: èŠçŽãå®äºãããšãBootstrapã®ã¢ãŒãã«ãŠã£ã³ããŠãç»é¢äžå€®ã«è¡šç€ºããããã®äžã«çæãããèŠçŽæãæç€ºãããŸãã
- å®äº: ãŠãŒã¶ãŒã¯ã¢ãŒãã«ãéããŠãå ã®ããŒãžé²èЧãç¶ããŸããããŒãã£ã³ã°è¡šç€ºã¯å ã®ãã¿ã³è¡šç€ºã«æ»ããŸãã
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ãµãŒããŒã§åé¡ãçºçããŸãããã®ãããªæœè±¡çã§åãããããã¡ãã»ãŒãžãè¿ããŸãã
- Djangoã®ãã¥ãŒã¯ãGradio APIãšã®éä¿¡éšåãå¿
ã
Gradio API (å°éå®¶) ã®åœ¹å²:
- AIã®æšè«åŠçãªã©ã倱æããå¯èœæ§ã®ããã³ãŒãã¯
try...except
ãããã¯ã§å²ã¿ãŸãã - ãšã©ãŒçºçæã¯ã
raise gr.Error("å ·äœçãªãšã©ãŒåå ")
ãåŒã³åºããAPIã®å¥çŽéãã«ãšã©ãŒæ å ±ãè¿åŽããŸãã
- AIã®æšè«åŠçãªã©ã倱æããå¯èœæ§ã®ããã³ãŒãã¯
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
ãäœæããå€ãèšå®ããŸãã# AI APIã®ã¢ãã«åãæå® AI_MODEL_NAME="llm-jp/t5-small-japanese-finetuned-sum"
docker-compose.yml
ã§ã®èªã¿èŸŒã¿:docker-compose.yml
ãã¡ã€ã«ã§env_file
ãæå®ããããšã§ãã³ã³ããèµ·åæã«.env
ãã¡ã€ã«ã®å 容ãç°å¢å€æ°ãšããŠèªã¿èŸŒãŸããŸãã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ãªã¯ãšã¹ããåŠçããã¡ã€ã³ã¡ãœããã
- 以äžã®åŠçãããŒãå¶åŸ¡ããã
_get_reviews
ãåŒã³åºããå£ã³ãããŒã¿ãååŸã_validate_reviews
ãåŒã³åºããããžãã¹ã«ãŒã«ïŒä»¶æ°ãæåæ°ïŒãæ€èšŒã- å£ã³ãããã¹ããååŠçïŒçµåããã€ãºé€å»ïŒã
_call_summary_api
ãåŒã³åºããå€éšAPIãšéä¿¡ã- æåã¬ã¹ãã³ã¹ãŸãã¯ãšã©ãŒã¬ã¹ãã³ã¹ã
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
ïŒãè¿ãããšã確èªããã
- æ£åžžç³»: APIã«æå¹ãªãªã¯ãšã¹ããéä¿¡ããHTTPã¹ããŒã¿ã¹ã³ãŒã
9.8.3. ãã¹ãã®å¹çå
- ãã£ã¯ã¹ãã£ã®æŽ»çš (
@pytest.fixture
): AIã¢ãã«ã®ããŒãã¯æéãããããããSummarizer
ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹çæããã£ã¯ã¹ãã£ãšããŠå®çŸ©ããŸããscope="session"
ãæå®ããããšã§ãå šãã¹ãå®è¡äžã«ã¢ãã«ã®ããŒããäžåºŠã ãã§æžã¿ããã¹ãæéãå€§å¹ ã«ççž®ããŸãã - ãã©ã¡ãŒã¿åã®æŽ»çš (
@pytest.mark.parametrize
): è€æ°ã®ç°ãªãå ¥åå€ãšæåŸ ãããçµæã®çµã¿åããããäžã€ã®ãã¹ã颿°ã§å¹ççã«æ€èšŒããããã«äœ¿çšããŸãã
9.9. 詳现èšèš: Django-AI飿º (v1)
Djangoã¢ããªã±ãŒã·ã§ã³ãšAIã¢ããªã±ãŒã·ã§ã³ïŒGradioïŒãã©ã®ããã«é£æºããŠæ©èœãå®çŸãããã®å ·äœçãªèšèšã以äžã«ç€ºããŸãã
9.9.1. 飿ºã·ãŒã±ã³ã¹
æ£åžžç³»ã®ã·ãŒã±ã³ã¹
å šäœã®åŠçã®æµãã¯ä»¥äžã®éãã§ãã
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åŽã§ãšã©ãŒãçºçããå Žåã®åŠçã®æµãã§ãã
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ãšã®éä¿¡ãå¶åŸ¡ããåžä»€å¡ã
- åŠçãããŒ:
- DBããå£ã³ããååŸããä»¶æ°ãæåæ°ãæ€èšŒããã
_call_summary_api
ã¡ãœãããåŒã³åºããAI APIã«ãªã¯ãšã¹ããéä¿¡ããã- è¿ã£ãŠããçµæïŒæåãŸãã¯ãšã©ãŒïŒãæŽåœ¢ãã
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ãªã¯ãšã¹ããåãä»ããçªå£ã
- å®è£
詳现:
- èµ·åæã«äžåºŠã ãã
core.inference.Summarizer
ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãçæããã functools.partial
ã䜿ããAPIåŠç颿°ã«Summarizer
ã®ã€ã³ã¹ã¿ã³ã¹ãæ³šå ¥ïŒãã€ã³ãïŒããã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_summary_api
ã¡ãœãããã¢ãã¯ïŒåœã®ãªããžã§ã¯ãã«å·®ãæ¿ãïŒããŸãã- ããã«ãããAI APIãžå®éã«ãããã¯ãŒã¯éä¿¡ãçºçãããããšãªãããAPIãæåãè¿ããå Žåããã¿ã€ã ã¢ãŠãããå Žåãããšã©ãŒãè¿ããå Žåããªã©ãããããç¶æ³ãæ³å®ãããã¥ãŒã®ããžãã¯ãé«éã«ãã¹ãã§ããŸãã
- AIã¢ããªã±ãŒã·ã§ã³:
ãã®èšèšã«ãããäž¡ã¢ããªã±ãŒã·ã§ã³ã¯äºãã«äŸåããããšãªããç¬ç«ããŠéçº,ãã¹ã,ãããã€ãé²ããããšãå¯èœã«ãªããŸãã
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ãªã©ïŒã調æ»ããã
- Pythonã®evaluate
ã©ã€ãã©ãªçã䜿ãããµã³ãã«ããŒã¿ã§å®éã«ã¹ã³ã¢ãç®åºããPoCïŒæŠå¿µå®èšŒïŒãè¡ãã
- ã¹ã³ã¢ã®èšç®æ¹æ³ãšããã®çµæã®è§£éã«ã€ããŠç¥èŠããŸãšããã | - è©äŸ¡ææšã®éžå®çç±ãšäœ¿ãæ¹ããŸãšããããã¥ã¡ã³ãã
- ã¹ã³ã¢ç®åºçšã®ãµã³ãã«ã¹ã¯ãªããã |
| 2. ããã³ãããšã³ãžãã¢ãªã³ã° | - ãããžãã£ã/ãã¬ãã£ãåæããç®æ¡æžãããªã©ãè€æ°ã®æç€ºïŒããã³ããïŒåœ¢åŒãèæ¡ããã
- åãå
¥åããŒã¿ã«å¯Ÿããåããã³ããã§çæçµæãã©ãå€ããããæ¯èŒã»åæããã
- æãèŠçŽã®è³ªãåäžããããã³ããã®ãã³ãã¬ãŒããæ±ºå®ããã | - ããã³ããã®æ¯èŒå®éšã®çµæã¬ããŒãã
- æ¡çšããããã³ãããã³ãã¬ãŒãã |
| 3. ã¢ãã«ã®A/Bãã¹ã | - ç°ãªãã¢ãã«ãããã³ããã®æ§èœãå®ç°å¢ã§æ¯èŒããããã®A/Bãã¹ãåºç€ãæ€èšããã
- ãªã¯ãšã¹ãã«å¿ããŠãããã¯ãšã³ãã§ã¢ãã«ãåçã«åãæ¿ããä»çµã¿ãèšèšããã
- ãŠãŒã¶ãŒãã£ãŒãããã¯ãããžãã¹ææšïŒäŸ: æ»åšæéïŒãžã®åœ±é¿ãèšæž¬ããæé©ãªã¢ãã«ãéžå®ããã | - A/Bãã¹ãã®èšèšæžã
- ã¢ãã«åãæ¿ãããžãã¯ã®å®è£
æ¡ã |
| 4. ã¢ãã«æŽæ°æ¹éã®çå® | - æ°ããæ¥æ¬èªèŠçŽã¢ãã«ãç»å Žããéã«ãã©ã®ã¿ã€ãã³ã°ã§è©äŸ¡ã»å°å
¥ãè¡ããã®åºæºãèšããã
- ãå幎ã«äžåºŠãææ°ã¢ãã«ã調æ»ããããç¹å®ã®è©äŸ¡ææšã10%ä»¥äžæ¹åããå Žåã«æŽæ°ãæ€èšããããªã©ãå
·äœçãªã«ãŒã«ãå®çŸ©ããã | - ã¢ãã«ã®ã©ã€ããµã€ã¯ã«ç®¡çæ¹éæžã |
10.2. å ç¢æ§ãšã¹ã±ãŒã©ããªãã£ã®åäž
ç®ç: 倧éã¢ã¯ã»ã¹ãäºæãã¬å ¥åã«å¯ŸããŠããå®å®ããŠé«éãªã¬ã¹ãã³ã¹ãè¿ããã³ã¹ããæé©åããã
| é
ç® | 調æ»èšç» | ææç© |
| : | : | : |
| 1. é«åºŠãªå
¥åå岿Šç¥ | - é·å€§ãªå£ã³ã矀ã«å¯Ÿå¿ãããããããã¹ããæå³ã®ããåäœïŒãã£ã³ã¯ïŒã§åå²ãããããããèŠçŽããŠããæçµçã«çµ±åãããMap-Reduceãçãªã¢ãããŒãã調æ»ã»å®è£
ããã
- LangChainãªã©ã®ã©ã€ãã©ãªãæäŸããèŠçŽãã§ãŒã³ã®æŽ»çšãæ€èšããã | - ãã£ã³ã¯èŠçŽã®å®è£
PoCã
- é·æå
¥åã«å¯Ÿãããšã©ãŒçãåè³ªã®æ¹åã¬ããŒãã |
| 2. éåæAPIåŒã³åºã | - DjangoããAI APIãåŒã³åºãåŠçãéåæåããWebãµãŒããŒã®ã¯ãŒã«ãŒã¹ã¬ãããé·æéãããã¯ããã®ãé²ãã
- CeleryãDramatiqãšãã£ãéåæã¿ã¹ã¯ãã¥ãŒãå°å
¥ããèŠçŽåŠçãããã¯ã°ã©ãŠã³ããžã§ããšããŠå®è¡ããã¢ãŒããã¯ãã£ãèšèšããã
- ããã³ããšã³ãåŽã¯ãããŒãªã³ã°ãWebSocketãå©çšããŠããžã§ãã®å®äºãæ€ç¥ãçµæã衚瀺ããæ¹åŒã«å€æŽããã | - éåæåŠçã¢ãŒããã¯ãã£ã®èšèšå³ã
- Celeryå°å
¥ã®PoCãšãå¿çæ§èœã®æ¹åå¹ææž¬å®ã¬ããŒãã |
| 3. ãã£ãã·ã¥æŠç¥ã®å°å
¥ | - Djangoã®ãã£ãã·ã¥ãã¬ãŒã ã¯ãŒã¯ïŒRedis, Memcachedãªã©ïŒã®å©ç𿹿³ã調æ»ããã
- ãæœèšIDããããŒãšããŠèŠçŽçµæããã£ãã·ã¥ããã¢ãŒããã¯ãã£ãèšèšããã
- ãã£ãã·ã¥ã®æå¹æéïŒTTLïŒãã©ã®çšåºŠã«èšå®ãã¹ãããæ¹éãæ±ºå®ããã | - ãã£ãã·ã¥ã·ã¹ãã ã®ã¢ãŒããã¯ãã£å³ã
- settings.py
ãžã®èšå®äŸãšããã¥ãŒã§ã®å©çšã³ãŒãäŸã |
| 4. ã³ã¹ãã»ããã©ãŒãã³ã¹è©Šç® | - Hugging Face Spacesã®ç¡ææ ã»ææãã©ã³ïŒããŒããŠã§ã¢æ§èœïŒãšæéäœç³»ã調æ»ããã
- 1ãªã¯ãšã¹ããããã®å¹³ååŠçæéãšã¡ã¢ãªäœ¿çšéãèšæž¬ããç¡ææ ã®ç¯å²å
ã§äœãªã¯ãšã¹ããŸã§åŠçå¯èœã詊ç®ããã
- æ³å®ãããã¢ã¯ã»ã¹æ°ã«åºã¥ããæéã®éçšã³ã¹ããšãã¹ã±ãŒã«ã¢ãããå¿
èŠã«ãªãæ¡ä»¶ãå®çŸ©ããã | - ã³ã¹ããšããã©ãŒãã³ã¹ã®è©Šç®ã¬ããŒãã
- ã¹ã±ãŒã«ã¢ããèšç»ã |
10.3. éçšãšç£èŠ
ç®ç: æ¬çªç°å¢ã«ãããAPIã®çšŒåç¶æ³ãå¯èŠåããåé¡çºçæã«è¿ éãªæ€ç¥ãšå¯Ÿå¿ãå¯èœã«ããã
| é
ç® | 調æ»èšç» | ææç© |
| : | : | : |
| 1. ãã°ã®çµ±å管ç | - DjangoãšGradio APIã®äž¡æ¹ã§ããªã¯ãšã¹ãIDãå
±æããä»çµã¿ãå°å
¥ããã
- æ§é åãã°ïŒJSON圢åŒïŒã«ãªã¯ãšã¹ãIDãå«ããããšã§ãDatadogãªã©ã®å€éšãµãŒãã¹ã§ããŠãŒã¶ãŒãªã¯ãšã¹ãããAI APIåŒã³åºããŸã§ã®äžé£ã®ãã°ã暪æçã«è¿œè·¡ã§ããããã«ããã | - ãã°ãã©ãŒãããã®çµ±äžä»æ§ã
- æ§é åãã®ã³ã°ã®å®è£
äŸã |
| 2. ããã©ãŒãã³ã¹ç£èŠãšãšã©ãŒã¬ããŒã | - Hugging Face Spacesãæšæºã§æäŸããåææ©èœïŒAnalyticsïŒã§ååŸã§ããã¡ããªã¯ã¹ã確èªããã
- Sentryãªã©ã®ãšã©ãŒã¬ããŒãããŒã«ãå°å
¥ããã¢ããªã±ãŒã·ã§ã³äŸå€ãèªåã§åéã»éç¥ããä»çµã¿ãæ§ç¯ããã
- ç¹ã«ç£èŠãã¹ãéèŠææšïŒKPIïŒãå®çŸ©ããïŒäŸ: ãšã©ãŒçã95ããŒã»ã³ã¿ã€ã«å¿çæéãèŠçŽå質ã¹ã³ã¢ïŒã | - ç£èŠããŒã«ã®éžå®ãšæ¯èŒã
- ç£èŠKPIãªã¹ããšãã®éŸå€ã®å®çŸ©ã
- Sentryå°å
¥æé æžã |
10.4. ãŠãŒã¶ãŒäœéšã®åŒ·å
ç®ç: AIã®æ©èœããããŠãŒã¶ãŒãã¬ã³ããªãŒã§ãå€ãã®äººãå©çšããããåœ¢ã§æäŸããã
| é
ç® | 調æ»èšç» | ææç© |
| : | : | : |
| 1. ãŠãŒã¶ãŒãã£ãŒãããã¯æ©æ§ | - èŠçŽçµæã«ã圹ã«ç«ã£ãã (ð/ð)ããæç¥šã§ããUIãèšèšããã
- ãã£ãŒãããã¯çµæãDjangoã®DBã«ä¿åããããã®ããŒã¿ã¢ãã«ãèšèšããã
- åéããããŒã¿ãå°æ¥ã®ã¢ãã«ååŠç¿ãããã³ããæ¹åã«ã©ã掻ããããæ¹éãæ€èšããã | - UIãã¶ã€ã³æ¡ã
- models.py
ã«è¿œå ãããã£ãŒãããã¯ã¢ãã«ã®å®çŸ©ã
- ããŒã¿æŽ»çšæ¹éã®æŠèŠã |
| 2. åèŠçŽæ©èœ | - ãŠãŒã¶ãŒãçæãããèŠçŽã«æºè¶³ããªãã£ãå Žåã«ãç°ãªããã©ã¡ãŒã¿ïŒäŸ: ããçãããã詳ããïŒã§åçæã詊ããUIãèšèšããã
- ãèŠçŽã®ããŒã³ãå€ããïŒäŸ: ä¿è·è
åããåäŸåãïŒããšãã£ãä»å æ©èœã®å®çŸå¯èœæ§ã調æ»ããã | - åèŠçŽæ©èœã®UIãã¶ã€ã³æ¡ã
- ãã©ã¡ãŒã¿å€æŽæ©èœã®å®è£
æ¹éã |
| 3. ã¢ã¯ã»ã·ããªã㣠(a11y) å¯Ÿå¿ | - ã¢ãŒãã«è¡šç€ºããã¿ã³æäœããã¹ã¯ãªãŒã³ãªãŒããŒïŒèŠèŠé害è
åãèªã¿äžããœããïŒã§æ£ããèªèã»æäœã§ãããæ€èšŒããã
- WCAG (Web Content Accessibility Guidelines) ã®äž»èŠãªé
ç®ã«åºã¥ããããŒããŒãã®ã¿ã§ã®æäœãå¯èœããååãªã³ã³ãã©ã¹ãæ¯ã確ä¿ãããŠããããªã©ã確èªããã | - ã¢ã¯ã»ã·ããªãã£ã®ãã§ãã¯ãªã¹ãã
- 察å¿ãå¿
èŠãªç®æã®ä¿®æ£æ¡ã |
11. å®è£ ã¿ã¹ã¯ãªã¹ãïŒè©³çްçïŒ
ãã®ã»ã¯ã·ã§ã³ã§ã¯ãTDDïŒãã¹ãé§åéçºïŒã®ãµã€ã¯ã«ã«åºã¥ããå®è£ ã®è©³çŽ°ãªæé ãéå±€çã«å®çŸ©ããŸãã
- æ åœ: AI - ãã®ã¢ã€ã³ã³ãä»ããŠããã¿ã¹ã¯ã¯ãAIïŒGeminiïŒãã³ãŒãçæããã¡ã€ã«äœæãçŽæ¥å®è¡ã§ããŸãã
- æ åœ: 人é - ãã®ã¢ã€ã³ã³ãä»ããŠããã¿ã¹ã¯ã¯ãéçºè ã«ããæåã§ã®å®è¡ã倿ããŸãã¯æ¿èªãå¿ èŠã§ãã
ãã§ãŒãº0: ãããžã§ã¯ãã®åæå
ç®ç: æ°ãããããžã§ã¯ãã®äœæ¥ãéå§ããããã®æºåãè¡ãã
- äžã¿ã¹ã¯0.1: ãããžã§ã¯ãã«ãŒããã£ã¬ã¯ããªã®äœæ
- æ åœ: 人é
- å
容: äœæ¥ãéå§ãããã£ã¬ã¯ããªã«ããããžã§ã¯ãã®ã«ãŒããšãªã
kids-playground-ai-api
ãã£ã¬ã¯ããªãäœæãããã®äžã«ç§»åããŠãã ããã - æç€º: 以äžã®ã³ãã³ããå®è¡ããŠãã ããã
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"
- äžã¿ã¹ã¯0.3: GitHubãªããžããªã®äœæãšé£æº
- æ åœ: 人é
- å 容: GitHubäžã«æ°ãããªããžããªãäœæããããŒã«ã«ãªããžããªãšé£æºãããŸãã
- æç€º:
- GitHubã«ãã°ã€ã³ããæ°ãããªããžããªãäœæããŸãïŒãªããžããªåã¯
kids-playground-ai-api
ãªã©ïŒãREADMEã.gitignoreãã©ã€ã»ã³ã¹ã®è¿œå ã¯ã¹ãããããŠãã ããã - äœæããããªããžããªããŒãžã«è¡šç€ºãããæç€ºã«åŸããããŒã«ã«ãªããžããªããªã¢ãŒãã«ããã·ã¥ããŸãã
- GitHubã«ãã°ã€ã³ããæ°ãããªããžããªãäœæããŸãïŒãªããžããªåã¯
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` ã¯ããã®ããã¥ã¡ã³ããçŸåšçœ®ãããŠãã絶察ãã¹ã«çœ®ãæããå¿
èŠããããŸãã*
- äžã¿ã¹ã¯1.1: ãããžã§ã¯ãæ§é ã®åæã»ããã¢ãã
- æ åœ: AI
- å
容: 以äžã®ãã£ã¬ã¯ããªãšãã¡ã€ã«ããããžã§ã¯ãã«ãŒãã«äœæããŸãã
- ãã£ã¬ã¯ããª:
src/ai_api/core
,tests/core
,docs
,.github/workflows
- ãã¡ã€ã«:
.gitignore
,Dockerfile
,pyproject.toml
,requirements.txt
,README.md
,.github/workflows/ci.yml
(空ãã¡ã€ã«ãšããŠ)
- ãã£ã¬ã¯ããª:
- æç€º: 以äžã®ã³ãã³ããå®è¡ããŠããããžã§ã¯ãã®åæãã£ã¬ã¯ããªãšãã¡ã€ã«ãæºåããŠãã ããã
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`ãã¡ã€ã«ãäœæããŠãã ããã
- [x] **äžã¿ã¹ã¯1.5: VSCodeãšDockerã³ã³ããã®é£æº (Dev Containers)**
- [x] **å°ã¿ã¹ã¯1.5.1: ãDev Containersãæ¡åŒµæ©èœã®ã€ã³ã¹ããŒã« (人é):** VSCodeã«`ms-vscode-remote.remote-containers`æ¡åŒµæ©èœãã€ã³ã¹ããŒã«ããã
- [x] **å°ã¿ã¹ã¯1.5.2: `devcontainer.json`èšå®ãã¡ã€ã«ã®äœæ (AI):** ãããžã§ã¯ãã«ãŒãã«`.devcontainer`ãã£ã¬ã¯ããªãšã`docker-compose.yml`ã®`api`ãµãŒãã¹ã«æ¥ç¶ããããã®`devcontainer.json`ãã¡ã€ã«ãäœæããã
- [x] **å°ã¿ã¹ã¯1.5.3: ã³ã³ããå
ã§ã®åãªãŒãã³ (人é):** VSCodeã®ã³ãã³ããã¬ãããããReopen in Containerããå®è¡ããVSCodeãã³ã³ããã«æ¥ç¶ãããç¶æ
ã§åèµ·åããããšã確èªããã
### ãã§ãŒãº2: CI/CDæ€èšŒçšãµã³ãã«ã¢ããªã±ãŒã·ã§ã³ã®äœæ
**ç®ç:** CI/CDãã€ãã©ã€ã³ãå
šäœãšããŠæ©èœããããšãæ€èšŒããããã®ãæãã·ã³ãã«ãªãHello WorldãçãªGradioã¢ããªã±ãŒã·ã§ã³ãäœæããã
- [x] **äžã¿ã¹ã¯2.1: Gradioãµã³ãã«ã³ãŒãã®å®è£
**
- [x] **å°ã¿ã¹ã¯2.1.1 (RED):** `main.py`ã®ãã¹ããäœæ
- **æ
åœ:** AI
- **å
容:** `tests/test_main.py`ãäœæãã`main.py`ã®`greet`颿°ãç¹å®ã®æååãè¿ãããšãæåŸ
ãããã¹ããèšè¿°ããŸãããã®æç¹ã§ã¯`main.py`ã`greet`颿°ãååšããªãããããã¹ãã¯å€±æããŸãã
- [x] **å°ã¿ã¹ã¯2.1.2 (GREEN):** `main.py`ã«ãµã³ãã«ãå®è£
- **æ
åœ:** AI
- **å
容:** `src/ai_api/main.py`ã«ãç°¡åãª`greet`颿°ãšããããåŒã³åºãGradioã€ã³ã¿ãŒãã§ãŒã¹ãå®è£
ãããã¹ãããã¹ãããŸãã
- [x] **å°ã¿ã¹ã¯2.1.3 (REFACTOR):** ãªãã¡ã¯ã¿ãªã³ã°
- **æ
åœ:** AI
- **å
容:** ã³ãŒããæŽçããå¯èªæ§ãé«ããŸãã
### ãã§ãŒãº3: CI/CDã®æ§ç¯ãšãããã€
**ç®ç:** ã³ãŒãã®å質ãèªåçã«æ€èšŒããHugging Face Spacesãžèªåçã«ãããã€ããä»çµã¿ãæ§ç¯ããã
- [x] **äžã¿ã¹ã¯3.1: CIã¯ãŒã¯ãããŒã®æ§ç¯ (GitHub Actions)**
- [x] **å°ã¿ã¹ã¯3.1.1 (RED):** CIèšå®ãã¡ã€ã«ã®éªšæ Œäœæ
- **æ
åœ:** AI
- **å
容:** `.github/workflows/ci.yml` ãäœæããŸããæåã¯ããªã¬ãŒã ããèšè¿°ããå
·äœçãªãžã§ãã¯ç©ºã«ããŠãããŸãããã®æç¹ã§ã¯äœãå®è¡ãããŸããã
- [x] **å°ã¿ã¹ã¯3.1.2 (GREEN):** CIãžã§ãã®å®è£
- **æ
åœ:** AI
- **å
容:** `ci.yml` ã«ãPythonã®ã»ããã¢ãããäŸåé¢ä¿ã®ã€ã³ã¹ããŒã«ã`ruff`ã«ããlintãã§ãã¯ã`mypy`ã«ããåãã§ãã¯ã`pytest`ã«ãããã¹ãå®è¡ã®ã¹ãããã远å ããŸãã
- **æç€º:** `/home/jam/kids-playground-ai-api/.github/workflows/ci.yml` ãæŽæ°ããŠãã ããã
- [x] **å°ã¿ã¹ã¯3.1.3 (REFACTOR):** ã¯ãŒã¯ãããŒã®æé©å
- **æ
åœ:** AI
- **å
容:** ãã£ãã·ã¥æ©æ§ãªã©ãå°å
¥ããCIã®å®è¡æéãççž®ããŸãã
- [x] **å°ã¿ã¹ã¯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 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
- **å
容:** ã³ãŒããæŽçããŸãã
- [x] **äžã¿ã¹ã¯5.3: çµ±åãã¹ã**
- [x] **å°ã¿ã¹ã¯5.3.1: æåã§ã®æçµç¢ºèª**
- **æ
åœ:** 人é
- **å
容:** DjangoãµãŒããŒãšAIã¢ããªïŒGradioïŒãäž¡æ¹ããŒã«ã«ã§èµ·åãããã©ãŠã¶ããæåã®èŠçŽãã¿ã³ãã¯ãªãã¯ããŠãå
šäœã®æµããæ£ããåäœãããã確èªããŸãã