ã¯ããã« ã¯ãããŸããŠããããã¯ãéšSearchGã®éŽæšãšç³ããŸãã 2025幎ã®ã¢ããã³ãã«ã¬ã³ããŒã¯ãåååããŸãšã圹ãããŠããæ¹ããåŒãç¶ã圢ã§ããã³ãåãåããŸããã æ¯å¹Žã®æäŸè¡äºãšãªã£ãŠããŠãããã³ãåŒãç¶ãã®ã«äžå®ã¯ãããŸããããç¡äºèµ°ãåãããšãã§ããŸããã ç¡äºå®èµ°ãã§ããã®ãå°ããã€ã§ã¯ãããŸãããæ¯å¹Žã®ãã¬ããžãæºãŸã£ãŠããŠããè³ç©ããšæããŸãã ã¹ã¿ã³ã〠Advent Calendar 2025 â» ã¢ããã³ãã«ã¬ã³ããŒãšã¯ãæ¯å¹Ž12æ1æ¥ãã25æ¥ãŸã§ã®æéã§èšäºãæçš¿ããã¯ãªã¹ãã¹ãŸã§ã®æ¥æ°ãã«ãŠã³ãããŠã³ããŠããã€ãã³ãã®ããšã§ãã ã¢ããã³ãã«ã¬ã³ããŒã®å®æœãŸã§ã®æµã ã¢ããã³ãã«ã¬ã³ããŒã®åããŸãšã圹ãšããŠã®æŽ»åã¯ãäžèšã®æµãã§å®æœããããŸããã ååã®ã¢ããã³ãã«ã¬ã³ããŒã®æ¯ãè¿ã åå è
åéã®å®æœ å·çã»ã¬ãã¥ãŒäœå¶ã®æ§ç¯ ã¢ããã³ãã«ã¬ã³ããŒã®æ¯ãè¿ã ååã®ã¢ããã³ãã«ã¬ã³ããŒã®æ¯ãè¿ã ãŸããããã³ãåŒãç¶ãã ã®ã§éçšããã¥ã¢ã«ã®ç¢ºèªãšååã®ã¢ããã³ãã«ã¬ã³ããŒã®æ¯ãè¿ãå
容ã確èªããŸããã techblog.stanby.co.jp ååã®ã¢ããã³ãã«ã¬ã³ããŒã®æ¯ãè¿ãã¯äž»ã«äžèšã®2ç¹ã§ããã ãã¢ã¬ãã¥ãŒã®å°å
¥(ã¬ãã¥ãŒè
éã§ã¬ãã¥ãŒå®æœããæçµã¬ãã¥ãŒè
ã®è² æ
ã軜æžãããã) ãªã¬ãŒåœ¢åŒã®ç޹ä»(å·çè
å士ã§èšäºã玹ä»ããŠãã¢ããã³ãã«ã¬ã³ããŒãçãäžãããã) ãã®2ã€ã®ç¹ãæèããŠãä»ååããŸãšã圹ãé²ããããšã«ããŸããã åå è
åéã®å®æœ åå è
ã®åéã¯ãäž»ã«äžèšã®2ã€ã®æ¹æ³ã§è¡ããŸããã ãŸãã¯ãå
šç€Ÿå¡ãåå ããæäŒã§åç¥ããåç¥åŸããã«Slackã§ãåç¥æãæçš¿ããŸããã é±1åã®å
šç€Ÿå¡å¯Ÿè±¡ã®æäŒã§åéã宿œ(2025幎11æ10æ¥ã«åç¥) Slackã䜿ãå
šç€Ÿå¡åãã«åéã宿œ äžèšä»¥å€ã«ãå®éã«ãªãã£ã¹ãžåºç€Ÿããéã«åå¥ã§å£°æããªã©ãè¡ãå·çè
ãéããŠãããŸããã ãŸããèšäºã®çžãã¯èšããã誰ã§ãåå OKïŒãšãããããéçºã¡ã³ããŒä»¥å€ã«ãäºæ¥éšã®ã¡ã³ããŒã2ååå ããŠãããŸããã æçµçã«23åãåå ãã25èšäºãå
¬éã§ããŸããã å·çã»ã¬ãã¥ãŒäœå¶ã®æ§ç¯ èšäºãå·çåŸã«æ¬åœã«å
¬éããŠããã®ãïŒã³ã³ãã©ã€ã¢ã³ã¹çã«å€§äžå€«ãïŒãšãã£ãäºé
ã確èªããããã«ç€Ÿå
ã¬ãã¥ãŒã¯å¿
é ãšããŠããŸããã ååã®åçç¹ãšããŠã¬ãã¥ãŒè
ã®è² æ
ãå¢ããŠããŸãããšãæããããŠããã®ã§ãå·çè
å士ã§çžäºã¬ãã¥ãŒã宿œããããšã«ããŸããã ãã®ãããå
¬éãŸã§ã®ã¹ããããšããŠäžèšã®æµãã§è¡ã£ãŠãããããã«å·çè
ã«ãé¡ããããŠãé²ããããšã«ããŸããã åå人ã§èšäºãå·çããã»ã«ãã¬ãã¥ãŒã宿œ èšäºã宿ããããå°çšã®ãã£ã³ãã«ã§ç¬¬äžè
ã¬ãã¥ãŒã宿œ 第äžè
ã¬ãã¥ãŒãå®äºããããæçµãã§ãã¯è
ã«ããã¬ãã¥ãŒã宿œ èšäºå
¬éïŒ ãªã«ãããåã¡ã³ããŒã«ãã¬ãã¥ãŒãããŠãã ããããšãé¡ãããŠããªã«ãã©ããŸã§èŠãã°ãããåãããªããªã£ãŠããŸãããã 2. ã®ç¬¬äžè
ã¬ãã¥ãŒã¯ããå€éšã«çºä¿¡ããŠãäžå©çã«ãªãæ
å ±ããªããã ãšããç¹ã«å²ãåã£ãŠã¬ãã¥ãŒããŠãããããã«ããŸããã ãŸãã瀟å
ã§ã¯Geminiãªã©æŽ»çšããŠããã®ã§ã誀åè±åã®ãã§ãã¯ãæ¥æ¬èªãšããŠããããªç¹ãèŠã€ããã®ã«AI掻çšãæšå¥šããŠã 1. ã®ç®æã®ã»ã«ãã¬ãã¥ãŒã®æŽ»çšãè¡ããŸããã ã¢ããã³ãã«ã¬ã³ããŒã®æ¯ãè¿ã ãªããšãç¡äºã«ã¢ããã³ãã«ã¬ã³ããŒãèµ°ãåãããšãã§ããŸããã 幎æ«ã®å¿ããææã ã£ãã®ã§ãã¡ã³ããŒéããªã©ããŸãè¡ããå
å¿ããªãçŠã£ãŠããã¿ã€ãã³ã°ããããŸããããå·çè
ãçå
ããŠé²ããŠãããå Žé¢ãå€ããããªããšãç¡äºã«çµããããšãã§ããŸããã ååã®åçç¹ã掻ãããæ¹åã§ããç®æã¯æ¹åããã€ããã§ãããæ¯ãè¿ã£ãŠã¿ããšããŸããããªãã£ãç®æãããã®ã§ãããã«ã€ããŠãŸãšããŸãã ååã®æ¹åç¹ã宿œããçµæ ååã®æ¯ãè¿ãã§æãã£ãããã¢ã¬ãã¥ãŒã®å°å
¥ããšããªã¬ãŒåœ¢åŒã®ç޹ä»ãã®2ç¹ãä»å宿œããŸããã ãã¢ã¬ãã¥ãŒã®å°å
¥ãšã¬ãã¥ãŒã®èгç¹ãçµã£ãã®ã¯å人çã«ã¯è¯ãã£ãããªãšæããŸããã åã¡ã³ããŒã®ã¬ãã¥ãŒã¯æ¥åã®åéã«å®æœããŠããã£ãŠããã®ã§ãã¬ãã¥ãŒèгç¹ãçµãã®ã¯è² æ
軜æžããã€ã€ãå€éšå
¬éãããåé¡ã«ãªãç®æããã¶ãåºãã®ã«æçšã ãšæããŸããã ãªã¬ãŒåœ¢åŒã®ç޹ä»ã«ã€ããŠããåã¡ã³ããŒãçå
ããŠç޹ä»ã®äžæãå
¥ããŠãããã®ã§ãã¯ãªã¹ãã¹ãŸã§æ¯æ¥èšäºãå
¬éããŠããããããæãåºãŠããã£ãã§ãã ä»åæ°ãã«èŠã€ãã£ãèª²é¡ å¹Žã®ç¬ãšããããšããããã¡ã³ããŒã®åéãäžã
ããŸããããã1人ã§2ã€èšäºãæžããŠãããããšãçºçããŠããŸããŸããã ããã¯ããå°ãåéãæ©ããŠãããã®ããªãšæããŸããã ä»åã¯ã11æ10æ¥ããåå è
åéãè¡ãæçµçã«23ååå ããŠãããããšãã§ããŸãããããã12æé ã«å
¬éããäºå®ã®æ¹ã¯ãå·çããã¬ãã¥ãŒãŸã§2é±éã¯å¿
èŠã«ãªãããã12æã®ç¬¬1é±ç®ããããããªãããããã«ãªã£ãŠããŸããŸãã ä»åŸã¯10æåŸåã«ã¡ã³ããŒåéããããã12æ1é±ç®ã¯åå¥ã«æžããŠããã人ãäºåã«éããŠããå¿
èŠããããšæããŸããã ãŸãšã ã¢ããã³ãã«ã¬ã³ããŒã®åããŸãšã圹ãšããŠå€§åœ¹ãä»»ãããŠç€Ÿå€ãžã®å€éšçºä¿¡ã®äžå©ã«ãªããã®ã¯å€§å€ããçµéšã«ãªããŸããã ãŸããå·çè
ãèªçºçã«åãäžç·ã«çãäžããŠããããããæåŸãŸã§æ¥œããã¢ããã³ãã«ã¬ã³ããŒãçãäžããããšãã§ããŸããã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ãããã¯ãéšUser Groupã®è€æŸ€ã§ãã ä»åã¯ãæã
ã®ãããã¯ãã ã¹ã¿ã³ã〠ãã§, Nuxtã¢ããããŒãããã£ããã«é¡åšåãã bfcacheïŒBack/Forward CacheïŒã«ããèšæž¬èª²é¡ãšã ããã«å¯Ÿãã察å¿ã»æ¹åã®åãçµã¿ã«ã€ããŠå
±æããŸãã ä»åã®æ¹åã«ããããããŸã§ããæ£ç¢ºãªæ°å€ãååŸã§ããããã«ãªãã瀟å
ææšã®æç¢ºåãé²ã¿ãŸããã ãã®èšäºã®ãã€ã³ã Nuxtã®ãã€ããŒã¢ããããŒãããã£ããã«ãèµ·ããã¯ãã®ãªãPVã®å€åãçºç åå ã¯ãbfcacheãã埩å
ããéã®ãã°éä¿¡ãäžå®å®ã ã£ãããš UXãç¶æãããããbfcacheã®ç¡å¹åã¯æ¡çšãããbfcacheããã®åŸ©å
æã«ããã°ãéä¿¡ããããšã§è§£æ±º UXãšæ£ç¢ºãªåæãäž¡ç«ããæ¢åã§æŸããŠããªãã£ãçŽ15%ã®ãæ¬æ¥ããã¹ãPVããåãæ»ãã 1. ã¯ããã«ïŒ Nuxtã¢ããããŒãã§é²èŠãããPVã®ãã¬ã ã ã¹ã¿ã³ã〠ãã§ã¯ãè匱æ§å¯Ÿå¿ã®ããã«Nuxt v3.12.2ããv3.12.4ãžã®ãã€ããŒã¢ããããŒããè¡ããŸããã ããããã¢ããããŒãããåŸã§ãããç°å€ãã«æ°ã¥ããŸããã Google Analytics (GA) ã® page_view ã瀟å
åæåºç€ã®ãã°ãšããŠèšæž¬ããŠãã PVïŒããŒãžãã¥ãŒïŒãããããã«æžå°ããŠãã ã®ã§ãã PVã¯æã
ã®ãããã¯ãã«ãããæéèŠããžãã¹ææšïŒKPIïŒã®1ã€ã§ããçç±ããªãå€åããŠããç¶æ
ã¯å¥œãŸãããããŸããã 調æ»ã®çµæãNuxtã¢ããããŒãã«ãã bfcacheãã埩å
ãããããŒãžã®å²åãå€åããããšããPVã®ãã¬ã®äž»å ã§ãããšå€æããŸããã ããã¯ããã©ãŠã¶åŽã®ä»æ§ã§ããbfcacheã®åããã³ãŒãåŽã§ã³ã³ãããŒã«åºæ¥ãŠããªãããšãæå³ããŸãã 2. bfcacheãšã¯ïŒ ãã©ãŠã¶ã®ãé«é埩å
æ©èœããšPVã®ãã¬ã®é¢ä¿ ããã§bfcacheã«ã€ããŠç°¡åã«è§£èª¬ããŸãã 2-1. bfcacheïŒBack/Forward CacheïŒãšã¯ bfcacheïŒBack/Forward CacheïŒã¯ããã©ãŠã¶ãããŒãžé·ç§»æã«çŽåã®ããŒãžå
šäœãã¡ã¢ãªäžã«ãŸãããšä¿æããŠããããŠãŒã¶ãŒããæ»ãããé²ããæäœããããšãã«ãã®ç¶æ
ãå³åº§ã«åŸ©å
ããä»çµã¿ã§ãã éåžžã®ãã£ãã·ã¥ïŒHTTPãã£ãã·ã¥ïŒã¯ãéçãªãœãŒã¹ïŒHTML, JS, CSS, ç»åãªã©ïŒããä¿åããã®ã«å¯Ÿããbfcache㯠JavaScriptã®å®è¡ç¶æ
ã»DOMããªãŒã»ã¹ã¯ããŒã«äœçœ®ãªã©ããŒãžã®ç¶æ
ããã®ãŸãŸã¡ã¢ãªã«æ®ããŸãã ã€ãŸãããŠãŒã¶ãŒããæ»ãããã¿ã³ãæŒããç¬éããããã¯ãŒã¯éä¿¡ãªãã»ã¬ã³ããªã³ã°ãªãã§å®å
šãªç¶æ
ãåçŸã§ããã®ã§ãã ããã«ããããŠãŒã¶ãŒã¯ãæ»ãããã¿ã³ãæŒããç¬éãèªã¿èŸŒã¿æéãŒãã§åã®ããŒãžã«æ»ããŠã ãŠãŒã¶ãŒäœéšïŒUXïŒãåçã«åäž ããŸãã bfcacheã®æ©æµãåããåç» ãã®åç»ã§ã¯ãbfcacheã䜿çšããå Žåãšæªäœ¿çšã®å Žåã®ãæ»ããæäœã®éåºŠãæ¯èŒããŠããŸãã bfcacheãæå¹ãªå ŽåãããŒãžåŸ©å
ãç¬æã«è¡ããããŠãŒã¶ãŒã¯åŸ
ã¡æéãªãåã®ããŒãžã«æ»ããŸãã äžæ¹ãbfcacheãç¡å¹ãªå Žåã¯ãéåžžã®åèªã¿èŸŒã¿ãçºçããæããã«è¡šç€ºãé
ããªããŸãã å®éã®æåãåç»ã§ç¢ºèªããããšã§ãbfcacheã®UXåäžå¹æãçŽæçã«çè§£ã§ããŸãã ããšãã°ãæ€çŽ¢çµæäžèЧããæ±äººè©³çŽ°ããŒãžãéããåã³ãæ»ããæäœãããéãbfcacheã«ãã£ãŠ æ€çŽ¢æ¡ä»¶ãã¹ã¯ããŒã«äœçœ®ãå®å
šã«ä¿æãããç¶æ
ã§å³åº§ã«åŸ©åž° ããŸãã ããã«ããããŠãŒã¶ãŒã¯ãæ€çŽ¢ãããçŽãããåæç»ãåŸ
ã€ããšãã£ãæéããè§£æŸãããŸãã ïŒâ»ãã®é«é埩å
ã¯ãã©ãŠã¶åŽã®æ©èœãšããŠå®çŸãããŠããŸãïŒ åèè³æ: bfcache - web.dev (Google) 2-2. bfcacheã®ãã©ãŠã¶äŸåæ§ bfcache㯠ãã©ãŠã¶å®è£
åŽã®æ©èœ ã§ããããã©ãŠã¶ãããŒãžã§ã³ã«ãã£ãŠæåããµããŒãç¶æ³ãç°ãªããŸãã ããšãã°ãChromeã»Firefoxã»Safariã¯ããããbfcacheããµããŒãããŠããŸããã埩å
ã®ã¿ã€ãã³ã°ãä¿ææ¡ä»¶ïŒService Workerãã€ãã³ããªã¹ããŒã®æç¡ãªã©ïŒã«ã¯åŸ®åŠãªå·®ç°ããããŸãã ã€ãŸããã åãããŒãžã§ãããã©ãŠã¶ã«ãã£ãŠbfcache埩å
ãçºçãããããªãã£ãããã ãããšãããã®ã§ãã ãããä»åèµ·ããPVã®ãã¬ãçã¿åºããŠããŸããã å€ãã®ã¢ãã³ãã©ãŠã¶ã§ã¯bfcache㯠ããã©ã«ãã§æå¹å ãããŠãããéçºè
ãç¹å¥ã«ç¡å¹åããªãéãããŠãŒã¶ãŒã®æäœã«å¿ããŠèªåçã«é©çšãããŸãã 2-3. ãªãPVãã°ã«ãã¬ãçããã®ãïŒ åé¡ã¯ã bfcacheããã®åŸ©å
ã¯ãéåžžã®ããŒãžããŒããšã¯ç°ãªã ç¹ã§ãã éåžžã®ããŒãžããŒãã§ã¯ã DOMContentLoaded ã load ãšãã£ãã€ãã³ããçºç«ããŸãã VueãNuxtã®å Žåãã³ã³ããŒãã³ããåããŠã³ããããŸãããã®éã« onMounted ããã¯ãå®è¡ãããŸãã ããããbfcacheãã埩å
ãããå Žåããããã® ã€ãã³ããã©ã€ããµã€ã¯ã«ããã¯ã¯äžåå®è¡ãããŸãã ãããŒãžã¯ã¡ã¢ãªãããè§£åããããã ãã§ãã æã
ã®ãããã¯ãã§ã¯ãGAã瀟å
åæåºç€ã®ãã°ã®PVã®å€ãã onMounted ããã¯å
ã§éä¿¡ããŠããŸããã ã€ãŸããbfcacheãã埩å
ããããšã onMounted ã¯å®è¡ãããããã°éä¿¡åŠçãäžžããšã¹ããããããŠãã ã®ã§ãã ããã¯ãGoogleã® web.dev ã§ããã¢ããªãã£ã¯ã¹å®è£
ã«ãããäžè¬çãªèœãšã穎ãšããŠèšåãããŠããŸãã bfcache ã¯ãåæã®å®è£
æ¹æ³ã«åœ±é¿ãäžããå¯èœæ§ããããŸãã ...bfcache ããã®åŸ©å
ã¯æ°ããããŒãžèªã¿èŸŒã¿ãšããŠã«ãŠã³ããããªãããã onload ã€ãã³ãã«äŸåããŠããåæã©ã€ãã©ãªã§ã¯ããããã®ã埩å
ããèšæž¬ãããŸããã åºå
ž: bfcache - ã¢ããªãã£ã¯ã¹ãšé²èŠ§ã®æž¬å® æ¹ååã®å®è£
äŸãšãã®åé¡ç¹ å®éã«ãåŸæ¥ã¯ä»¥äžã®ãããªå®è£
ã§PVãã°ãéä¿¡ããŠããŸããã // åããŒãžã® <script setup> å
import { onMounted } from 'vue' ; // æ¢åã®ãã°éä¿¡é¢æ°ïŒäŸïŒ const sendPageLog = () => { console . log ( 'PVãã°ãéä¿¡ããŸãã' ) ; } ; onMounted (() => { sendPageLog () ; }) ; ãã®å®è£
ã§ã¯ãbfcacheãã埩å
ãããå Žå㯠onMounted ãçºç«ããªããããPVãã°ãéããŠããŸããã§ããã 3. bfcacheåé¡ãžã®2ã€ã®ã¢ãããŒã ãã®åé¡ã«å¯Ÿããæã
ã¯2ã€ã®éžæè¢ããããŸããã éžæè¢A: Cache-Control: no-store ã§bfcacheãç¡å¹åãã ãµãŒããŒã®ã¬ã¹ãã³ã¹ããããŒã« Cache-Control: no-store ãèšå®ããbfcacheããããã¯ãå
šäœã§åŒ·å¶çã«ç¡å¹åãã察å¿ã§ãã ã¡ãªãã: åžžã«éåžžã®ããŒãžããŒããçºçãããã onMounted ã¯å¿
ãå®è¡ããããã°æªéä¿¡ã¯å³åº§ã«è§£æ¶ã§ãã ãã¡ãªãã: bfcacheã«ããé«éãªUXã®æ©æµããŠãŒã¶ãŒãã奪ã£ãŠããŸã ãã©ãŠã¶ããã¯ã»ãã©ã¯ãŒãæã«åžžã«ãªããŒããçºçãããããPV以å€ã®ç€Ÿå
ææšã«ãæªåœ±é¿ãåºãŠããŸã éžæè¢B: bfcacheãæå¹ã®ãŸãŸã埩å
æã®ãã°æªéä¿¡ãåå¥ã«å¯Ÿçãã bfcacheã¯æå¹ãªãŸãŸïŒUXãç¶æïŒã«ããbfcacheããã®åŸ©å
æã«ããã°ãéä¿¡ããããããæ ¹æ¬çãªæ¹ä¿®ãããã ã¡ãªãã: é«éãªUXãšãæ£ç¢ºãªãã°åæãäž¡ç«ã§ãã ãã¡ãªãã: ãã°éä¿¡ã¯ããŒãžããšã«åå¥å®è£
ãããŠããç®æãå€ãã 圱é¿ç¯å²ã®èª¿æ»ãšä¿®æ£ã®å·¥æ°ãéåžžã«å€§ãã æã
㯠é«éUXãç¶æãã€ã€ãåŸæ¥æ¬ æããŠããPVãæ£ç¢ºã«ååŸããããšãéèŠãã ãéžæè¢Bããæ¡çšããŸãã ã 4. 解決çïŒ pageshow ã€ãã³ãã§åŸ©å
ãæ€ç¥ãã ãéžæè¢Bããå®çŸããéµãã pageshow ã€ãã³ãã§ãã pageshow ã€ãã³ãã¯ãããŒãžã衚瀺ããããã³ïŒéåžžã®ããŒãæããbfcacheããã®åŸ©å
æãïŒã«çºç«ããŸãã ãããŠãã€ãã³ããªããžã§ã¯ãã® event.persisted ãããã㣠ãèŠãããšã§ãbfcacheãã埩å
ããããã©ãããå€å¥ã§ããŸãã event.persisted === true : bfcacheãã埩å
ããã event.persisted === false : éåžžã®ããŒãžããŒã ãã®ä»çµã¿ã䜿ãã以äžã®ããã«å®è£
ãä¿®æ£ããŸããã // åããŒãžã® <script setup> å
import { onMounted } from 'vue' ; // æ¢åã®ãã°éä¿¡é¢æ°ïŒäŸïŒ const sendPageLog = () => { console . log ( 'PVãã°ãéä¿¡ããŸãã' ) ; } ; onMounted (() => { // 1. éåžžã®ããŒãžé·ç§»ã»ãªããŒãæã®ãã°éä¿¡ sendPageLog () ; // 2. bfcacheããã®åŸ©å
æã«ãã°ãéä¿¡ããããã®ãªã¹ããŒãç»é² // NOTE: ãã©ãŠã¶ããã¯ã»ãã©ã¯ãŒãæã«ãã°ãéä¿¡ window . addEventListener ( "pageshow" , ( event ) => { // bfcacheãã埩å
ãããå ŽåïŒpersisted: trueïŒã®ã¿ããã°ãéä¿¡ if ( event . persisted ) { sendPageLog () ; } }) ; }) ; ãã®ä¿®æ£ã«ãããæã
ã¯bfcacheããã®åŸ©å
æã«ã確å®ã«ãã°ãéä¿¡ã§ããããã«ãªããŸããã 5. å°å
¥ããã»ã¹ãšææïŒãã¬ããã£ãPVã«æ£ç¢ºããåãæ»ã 以åããæã
ã®ãããã¯ãã§ã¯ãbfcacheã¯æå¹ã§ããã ããã埩å
æã®å¯Ÿå¿ãããŠããªãã£ãçºããã©ãŠã¶ããã¯ããã©ã¯ãŒãæäœã§PVããã¬ãããç¶æ³ã«ãªã£ãŠããŸããã ä»åã®å¯Ÿå¿ã«ãããåŸæ¥èšæž¬ã§ããªãã£ã埩å
æã®PVãæ£ç¢ºã«ååŸå¯èœã«ãªããçµæãšããŠå
šäœPVãå¢ããããã«èŠããŸãã ãã®ããã以äžã®æé ã§æ
éã«å°å
¥ãé²ããŸããã Step 1. ãã¬ã®è§£æ¶ã«ãã£ãŠå¢å ããPVã®èŠæš¡ãææ¡ïŒ no-store ãã¹ãïŒ äžåºŠãéžæè¢AïŒ Cache-Control: no-store ïŒããæ¬çªç°å¢ã§çæéãªãªãŒã¹ããŸããã ããã«ãããbfcacheãç¡å¹åããå Žåã«PVãã©ãã ããå¢ããããïŒïŒãããŸã§ãã©ãã ããã¬ã«ããPVãåãããŒããŠãããïŒãèšæž¬ããŸããã çµæã çŽ15% ã®PVãbfcacheã«ãã£ãŠåãããŒããŠããããšãææ¡ã§ããŸããã Step 2. æ¬å¯Ÿå¿ïŒ pageshow 察å¿ïŒãšé¢ä¿è
飿º 次ã«ã no-store ã®èšå®ãå
ã«æ»ããæ¬åœã®ãéžæè¢BïŒ pageshow 察å¿ïŒããè¡ããŸããã ãã®éãäºåã«PdMãããŒã¿åæããŒã ã«å¯Ÿãããä»åã®å¯Ÿå¿ã§PVãçŽ15%å¢å ããããã㯠ãã°ãä¿®æ£ãããæ£ããå€ãèšæž¬ãããããã«ãªã ããã§ããããšããåšç¥ã培åºããŸããã Step 3. ææ ãªãªãŒã¹åŸãPVã¯äºåã®è©Šç®éãçŽ15%å¢å ããå®å®ããŸããã ããã¯ãNuxtã¢ããããŒãã§é¡åšåããbfcacheã«ãããã°ã®åãããŒããè§£æ¶ãã PVããæ£ããç¶æ
ãã«åŒãçŽãã ããšãæå³ããŸãã åæé¢: ããžãã¹KPIã§ããPVããbfcacheã®æåã«å·Šå³ããããæ£ç¢ºã«èšæž¬ã§ããããã«ãªã£ãã UXé¢: bfcacheã¯æå¹ãªãŸãŸã§ãããããUXãäžåæããŠããªããããããNuxtã¢ããããŒãã«ãã£ãŠbfcacheã®åŸ©å
çãäžãã£ãããšã§ããããã¯ãå
šäœã®ãæ»ãããé²ããäœéšã¯ä»¥åããåäžããã 6. ãŸãšãïŒNuxtã¢ããããŒããæ°ã¥ãããŠãããbfcache察å¿ã®éèŠæ§ ä»åã®çµéšããæã
ãåŸãåŠã³ã¯ä»¥äžã®éãã§ãã ãã€ããŒã¢ããããŒãã§ãé ããè² åµããæŽãåºãããšããã: ãã°ã®åãããŒããšããåé¡ã¯ä»¥åããååšããŠããããNuxtã¢ããããŒããbfcacheã®æåãå€ããããšã§ããã®åœ±é¿ãç¡èŠã§ããªãã¬ãã«ã§é¡åšåããã ãæ£ããæ°åãã远ãããšã®éèŠæ§: PVã¯éèŠãªããžãã¹ææšã§ãããbfcacheã«ããæå³ããªãPVã®ãã¬ãé²ããæ£ç¢ºãªåæçµæãåãæ»ãããšãã§ããã ãŸãã宿ãªåé¿çïŒ no-store ïŒã«é Œãããæ ¹æ¬åå ã§ãã pageshow æªå¯Ÿå¿ã«æ£é¢ããåãçµãäºãåºæ¥ãŸãããããã«ããUXãšåæãäž¡ç«ã§ãããããã¯ãã®å質åäžã«å€§ããè²¢ç®ã§ãããšæããŠããŸãã ãã®ææ¡ãæ¿èªããŠããªãœãŒã¹èª¿æŽãå®è£
é¢ã§ãµããŒãããŠãããããŒã ããããã¯ããªãŒããŒã«ãæµãŸããŠãããªãšãæ¹ããŠæããŸããã æ³šæ: bfcacheã®æåã pageshow ã€ãã³ãã®ãµããŒãç¶æ³ã¯ãäž»èŠãã©ãŠã¶ïŒChrome, Firefox, SafariçïŒã§ç°ãªãå ŽåããããŸããç¹ã«Safariã¯bfcacheã®ä»æ§ã埩å
ã¿ã€ãã³ã°ãä»ãã©ãŠã¶ãšç°ãªãããšããããããå®è£
æã¯åãã©ãŠã¶ã®å
¬åŒããã¥ã¡ã³ããæåæ€èšŒãæšå¥šããŸãã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ãããã¯ãéš Appã°ã«ãŒãã§Androidã¢ããªéçºãæ
åœããŠããå±±è¶ã§ãã çŸåšãAppã°ã«ãŒãã§ã¯æ¢åã¢ããªã®UIãXMLã¬ã€ã¢ãŠãããJetpack Composeãžæ®µéçã«ç§»è¡ããŠããŸãã æ¬èšäºã§ã¯ããComposeåããé²ããèæ¯ãç®çãå®éã®é²ãæ¹ããããŠç§»è¡ã®äžã§çŽé¢ãã課é¡ã»ã¯ã©ãã·ã¥äºäŸã«ã€ããŠã玹ä»ããŸãã ãComposeåããšã¯ïŒ Jetpack Composeãšã¯ãAndroidåãã®æ°ãã宣èšçUIãã¬ãŒã ã¯ãŒã¯ã§ãã åŸæ¥ã®XMLã¬ã€ã¢ãŠãã§ã¯ãUIã®èŠãç®ãšåäœãå¥ã
ã®ãã¡ã€ã«ã§ç®¡çããå¿
èŠãããç¶æ
æŽæ°ã®ãã³ã«ViewãçŽæ¥æäœããå¿
èŠããããŸããã äžæ¹ã®Composeã§ã¯ãUIãKotlinã³ãŒãäžã§çŽæ¥å®çŸ©ããããšãšãªããã¢ããªã®ç¶æ
ïŒStateïŒã«å¿ããŠèªåçã«UIãåæç»ããããšãå¯èœãšãªããŸãã ãComposeåããšã¯ãããããComposeã®èãæ¹ãæ¢åã¢ããªã«ãåãå
¥ããŠãXMLãViewBindingã䜿ã£ãŠããç»é¢ã段éçã«Composeãžç§»è¡ããåãçµã¿ãæããŸãã ã¹ã¿ã³ãã€ã§ã¯ãUIã®ä¿å®æ§ã»åå©çšæ§ã»éçºå¹çã®åäžãç®çãšããŠãæ¢åç»é¢ã®Composeåã«çæããŸããã ç§»è¡äœæ¥ã®é²ãæ¹ ä»åã®ç§»è¡äœæ¥ã§ã¯ãå
šç»é¢ãäžæ°ã«çœ®ãæããã®ã§ã¯ãªããæ®µéçã«ç§»è¡ããæ¹éãåããŸããã æ°èŠæ©èœã¯æåããComposeã§å®è£
ããŠãæ¢åç»é¢ã¯åœ±é¿åºŠã®äœããšããããComposeåãé²ããŠããŸãã ããã«ãã圱é¿ç¯å²ãæå°éã«æããªããComposeãžã®ç¥èŠãç©ã¿éããããšãã§ããŸããã XMLã¬ã€ã¢ãŠãã®ãªãœãŒã¹ãComposeãž ç§»è¡ã®ç¬¬äžæ©ãšããŠãæ¢åã®XMLã¬ã€ã¢ãŠããComposeåããŸããã ç»é¢å
šäœãäžæ°ã«Composeåããã®ã§ã¯ãªããButtonãCardãšãã£ãæ±çšçãªUIã³ã³ããŒãã³ãåäœã§ã®çœ®ãæãããå§ããŠããŸãã Composeåããç»é¢ã¯ãFragmentäžã§ComposeViewãå©çšããŠçµã¿èŸŒãæ¹æ³ããšã£ãŠããŸãã class SampleFragment: Fragment() { // ViewModelåç
§ private val viewModel: SampleViewModel by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View = ComposeView(requireContext()).apply { setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnLifecycleDestroyed( viewLifecycleOwner ) ) setContent { // Composeåããç»é¢ SampleScreen( uiState = viewModel.uiState, onClickButton = { viewModel.onClickButton() } ) } } } ããããããšã§ãFragmentãViewModelã®æ§é ã¯æŽ»ããã€ã€éšåçã«Composeãå°å
¥ããããšã§ç§»è¡ã®ãªã¹ã¯ãæããŠããŸãã æ¢åViewãšã®å
±å Composeåã®éäžã§ã¯ãXMLãšComposeãæ··åšããæéã¯é¿ããããŸããã ãã®ããã以äžã®ãããªç¹ãæèããŠäž¡è
ãå
±åãããŸããã ããŒãããã³ã«ã©ãŒå®çŸ©ãMaterialThemeãšXMLã¹ã¿ã€ã«ã§çµ±äž ViewModelã¯å
±éã§å©çšããŠãStateFlowã collectAsState() ã§ç£èŠ ãã®çµæãæ¢åãããã¯ãã®å®å®æ§ãä¿ã¡ãªããComposeåãé²ããããšãã§ããŸããã ã€ãŸã¥ãããšãã æ±çšã³ã³ããŒãã³ãã®å¯Ÿå¿ãçµãŠç»é¢åäœã®Composeåãè¡ãªã£ãŠããŸããããã¹ã ãŒãºã«é²ãŸãªãã±ãŒã¹ãããã€ãçºçããŸããã å
±éããŠçŽé¢ãã課é¡ã«å¯ŸããŠã©ã®ãããªææ³ããšã£ãŠå¯Ÿå¿ããŠããããã玹ä»ããŸãã ããŒãèšå®ãã¬ã€ã¢ãŠã厩ã Composeåãé²ããäžã§ãæ¢åããŒããšã®æŽåæ§ã§ããã€ã課é¡ããããŸããã æ¢åã¢ããªã§ã¯ themes.xml ã styles.xml ã§å®çŸ©ããã«ã©ãŒããã©ã³ããµã€ãºãå©çšããŠããŸããã äžæ¹ãComposeåŽã§ã¯ MaterialTheme ãçµç±ããå¿
èŠããããããè²å³ãäœçœãäžèŽããªãã±ãŒã¹ããããŸããã ã¹ã¿ã³ãã€ã§ã¯ãFigmaäžã«ãã¶ã€ã³å®çŸ©ãæŽçãããŠãããã现ãã調æŽã¯äžèŠã§ããããå®è£
äžã§ã¯XMLãªãœãŒã¹ãComposeã«å¯ããéçšã§å°ããªãããå€ãçºçããŸããã ç¹ã«TextStyleã®èšå®ã¯MaterialThemeé
äžã«åå®çŸ©ããcolorResourceãæŽ»çšããŠæ¢åãªãœãŒã¹ãšã®äžæŽåãè§£æ¶ããŸããã ãŸããåå©çšå¯èœãªUIéšå㯠designsystem ããã±ãŒãžã«ãŸãšããæ§æãæ¡çšããŸããã ãã®ããã±ãŒãžã§ã¯ãã¿ã³ãããã¹ããã£ãŒã«ããªã©ã®å
±éUIã³ã³ããŒãã³ããå®çŸ©ããŠãåç»é¢ã§ã¯ããããåŒã³åºããŠUIãæ§ç¯ããŠããŸãã ãã®æ§æã«ããã¢ããªå
šäœã®ãã¶ã€ã³ãçµ±äžãã€ã€ããã¶ã€ã³ä¿®æ£ãäžç®æã§åæ ã§ããããã«ãªããŸããã ãŸããFigmaäžã®ãã¶ã€ã³å®çŸ©ãšComposeã³ãŒãã®å¯Ÿå¿é¢ä¿ãæŽçãããComposeåã«ããUIã®ã°ãã€ããé²ãããšãã§ããŠããŸãã ãã¬ãã¥ãŒãšã®ä¹é¢ Jetpack Composeã«ã¯ãã¬ãã¥ãŒæ©èœããããã³ã³ããŒãã³ãåäœã§æç»ãããUIãå³åº§ã«ç¢ºèªã§ããŸãã Composeã®ãã¬ãã¥ãŒæ©èœã¯éåžžã«äŸ¿å©ãªåé¢ãå®éã®Android端æ«äžã®æåãšç°ãªãå ŽåããããŸãã ç¹ã«ViewModelçµç±ã§ç¶æ
ãåãåãç»é¢ãã LocalContextã»MaterialTheme ã«äŸåããComposableã§ã¯ã ãã¬ãã¥ãŒäžã§ã¹ã¿ã€ã«ãåæ ãããªãã£ãããã¯ã©ãã·ã¥ãããããã±ãŒã¹ããããŸããã ãã®ãããã¬ãã¥ãŒçšã«ãããŒã®UiStateãæž¡ãã@Preview颿°ããçšæããããŒããæ¬çªãšåãAppThemeãé©çšããŠç¢ºèªããããæèããŸããã ããã§ãæçµçãªèŠãç®ãåäœã¯ãšãã¥ã¬ãŒã¿ããã³å®æ©ç¢ºèªã§å·®åãåžåããããã«ããŠããŸãã æãã¬ã¯ã©ãã·ã¥ã®çºç Composeåå®äºåŸã®ç»é¢ã宿©ãŸãã¯ãšãã¥ã¬ãŒã¿ã§åãããšãã¯ã©ãã·ã¥ããããšããããŸããã Android Studioäžã§ã¯èŠåããšã©ãŒãªã©ã®åé¡ã¯è¡šç€ºãããŠããŸããã ä»åãAppã°ã«ãŒããçŽé¢ãããã®ãã2ç¹ã®ã¯ã©ãã·ã¥ãæç²ããŠå¯ŸåŠæ¹æ³ãåãããŠã玹ä»ããŸãã Columnã®å
¥ãåæ§é ã«ããé«ãéå¶é ãšããç»é¢ã®Composeåãé²ããŠããäžã§ãColumnã®å
¥ãåæ§é ãæã€ç»é¢è¡šç€ºã®éã«ã¯ã©ãã·ã¥ãçºçããŸããã ãã®ç»é¢ã§ã¯èŠªèŠçŽ ã Column ããã®äžã« LazyVerticalGrid ãé
眮ããŠãã wrapContentHeight() ãæå®ããŠããŸããã Column { LazyVerticalGrid( columns = GridCells.Fixed( 2 ), modifier = Modifier .fillMaxWidth() .wrapContentHeight(), // ã³ã³ãã³ãã®ãµã€ãºã«å¿ããé«ãã«ããã verticalArrangement = Arrangement.spacedBy( 8 .dp), ) { items(items = targetItems, key = { it.id ?: it.hashCode() }) { item -> // åèŠçŽ ã®Composable } } } ãã®å Žåã Column ã¯çžŠæ¹åã«ç¡éã¹ã¯ããŒã«å¯èœãšã¿ãªãããŸãã ãããŠãå
éšã® LazyVerticalGrid ãé«ããèšç®ããããšããŠãç¡éãµã€ãºãèŠæ±ãã圢ãã«ãªãã æç»æã«äžèšã®äŸå€ãçºçããŸããã IllegalStateException : Vertically scrollable component was measured with an infinite height constraints ããã¯ã芪ãšåã®äž¡æ¹ãã¹ã¯ããŒã«å¯èœïŒãŸãã¯é«ãéå¶éïŒãªæ§æã«ãªã£ãŠããããšãåå ã§ãã 察å¿ãšããŠãå
éšã® LazyVerticalGrid ã« Modifier.heightIn(max = 200.dp) ãä»äžããŠé«ãã®äžéãæç€ºããããšã§ç¡éååž°çãªèšæž¬ãé²ããŸããã Column { LazyVerticalGrid( columns = GridCells.Fixed( 2 ), modifier = Modifier .fillMaxWidth() .wrapContentHeight() .heightIn(max = 200 .dp), // é«ãã®äžéæå®ã远å verticalArrangement = Arrangement.spacedBy( 8 .dp), ) { items(items = targetItems, key = { it.id ?: it.hashCode() }) { item -> // åèŠçŽ ã®Composable } } } heightIn() ã䜿ãããšã§Composeã®æž¬å®å¶çŽãæç¢ºã«ããæç»åŠçãå®å®ããããã«ãªããŸããã ããã¯ã°ã©ãŠã³ã埩垰æã®äŸå€çºç ããã²ãšã€ã®ã¯ã©ãã·ã¥ã¯ãã¢ããªã®ããã¯ã°ã©ãŠã³ã埩垰æã«çºçãããã®ã§ããã ãšããç¶æ
ãä¿æããããã«Screenå
ã§ rememberSaveable ãå©çšããŠããŸããããä¿æããŠãããªããžã§ã¯ããç»é¢åçææã«æ£ãã埩å
ã§ãã IllegalStateException: MutableState cannot be saved ãçºçããŸããã val type = rememberSaveable { mutableStateOf<SampleType?>( null )} rememberSaveable ã§ã¯ä¿åã§ããåãéãããŠãããParcelableãŸãã¯Serializableããããã¯Saverã§æç€ºçã«å€æã§ãããã®ã ãã察象ã§ãã ä»åã®ã±ãŒã¹ã§ã¯ãä¿å察象ã®ããŒã¿ã¯ã©ã¹ãParcelableãå®è£
ããŠãããã埩垰æã«åäžäžèŽãšããŠäŸå€ãã¹ããŒãããŠããŸããã 察å¿ãšããŠãSaverãå®è£
ããŠä¿å察象ãæç€ºããããšã§è§£æ±ºããŸããã // SampleTypeãä¿æããããã®Saver private val SampleTypeSaver = Saver<SampleType, Map < String , String >>( // ä¿åãããšãã¯Map<String, String>åã«å€æ save = { sampleType -> when (sampleType) { is SampleType.TypeA -> mapOf( "type" to "A" ) is SampleType.TypeB -> mapOf( "type" to "B" ) is SampleType.TypeC -> mapOf( "type" to "C" , "key" to sampleType.value ) else -> mapOf() } }, // 埩å
ãããšãã¯SampleTypeã«å€æ restore = { map -> when (map[ "type" ]) { "A" -> SampleType.TypeA "B" -> SampleType.TypeB "C" -> SampleType.TypeC(map[ "key" ].toString()) else -> null } } ) ~ // stateSaverã«äœæããSampleTypeSaverãå²ãåœãŠã val type = rememberSaveable(stateSaver = SampleTypeSaver) { mutableStateOf<SampleType?>( null )} ãã®ããã«ãComposeã¯ç¶æ
ã®ã¹ã³ãŒããæç¢ºã§ããäžæ¹ã§ã Activityåçæãããã»ã¹ãã«æã«æ°žç¶å察象ã誀ããšã¯ã©ãã·ã¥ããããããæ³šæãå¿
èŠã§ãã å®å
šãªãComposeåããŸã§ã®èª²é¡ç¹ Composeåã¯çå®ã«é²ãã§ããŸãããå®å
šãªç§»è¡ã«ã¯ãŸã ããã€ãã®èª²é¡ãæ®ã£ãŠããŸãã çŸåšã®äž»ãªèª²é¡ã¯ãDeepLinkçµç±ã§ã®ç»é¢é·ç§»åŠçããšããããç»é¢ã«ãããããã ããã²ãŒã·ã§ã³ã«ããã¿ãé·ç§»ãã§ãã çŸç¶ããããã®éšåã¯æ¢åã®FragmentãããŒã¹ã«åäœããŠãããCompose Navigation ãžã®çœ®ãæãã«ã¯ãããªãæ€èšãå¿
èŠã§ãã ç¹ã«ã«ãŒãã£ã³ã°ç®¡çãããŒã¿ã®åãæž¡ããDeepLinkèµ·åæã«ã®åæã¿ãã®å¶åŸ¡ãããã¯ã¹ã¿ãã¯ã®åæ§ç¯ãªã©ã æ¢åã®ããã²ãŒã·ã§ã³æ§é ãšComposeåŽã®é·ç§»ç®¡çãã©ãå
±åããããã課é¡ãšãªã£ãŠããŸãã ããã ããã²ãŒã·ã§ã³ã«ã€ããŠããç»é¢åçæãã¿ãåãæ¿ãæã®ç¶æ
ä¿æãComposeåŽã§ã©ããŸã§æ
ãããæŽçããå¿
èŠããããŸãã ä»åŸã¯ãããã®é·ç§»åŠçãCompose Navigationã«çµ±äžããã¢ããªå
šäœãå®å
šãªComposeããŒã¹ãžç§»è¡ããããšãç®æšãšããŠããŸãã ãŸãšã Composeåãé²ããŠããäžã§ãéçºå¹çãUIèšèšã®æè»æ§ãšãã£ãå€ãã®ã¡ãªããã宿ã§ããŸããã ç¹ã«ãUIãKotlinã³ãŒãäžã§å®çµã§ããç¹ããç¶æ
管çãViewModelãšå¯ã«é£æºã§ããç¹ã¯å€§ããªåŒ·ã¿ã§ãã ãŸããå
±éUIã designsystem ãšããããã±ãŒãžãäœæããŠãŸãšããããšã§ç»é¢ããšã®èŠãç®ã®çµ±äžãåå©çšæ§ãåäžããŸããã äžæ¹ã§ãå°å
¥åæã¯Composeç¹æã®ã¬ã€ã¢ãŠãå¶çŽãç¶æ
ä¿æã®ä»çµã¿ã«ããã¯ã©ãã·ã¥ãªã©ããããŸã§ã®XMLããŒã¹ãšã¯ç°ãªã芳ç¹ã§ã®ãã©ãã«ã·ã¥ãŒãã£ã³ã°ãå¿
èŠã§ããã ãŸããéšåçãªComposeå°å
¥ã§ã¯XMLãšã®å
±åã³ã¹ããçºçããå®å
šãªç§»è¡ã«ã¯ãŸã æéãããããšæããŠããŸãã ããã§ããUIå®è£
ã®ã·ã³ãã«ããéçºäœéšã®æ¹åã¯å€§ãããé·æçã«èŠãã°Composeåã®ã¡ãªãããæç¢ºã«äžåããšå®æããŠããŸãã æ©äŒãããã°ä»åŸã®æ¹åãå®å
šç§»è¡ã«ã€ããŠãã玹ä»ãããŠããã ããã°ãšåããŸãã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ã¯ããã« ããã«ã¡ã¯ãClientã°ã«ãŒãæå±ãšã³ãžãã¢ã®äºäžã§ãã æ¬èšäºã§ã¯ãåºåãã°ãéèšããã¢ãŒããã¯ãã£ã®äžéšãå·æ°ãããåºåãã°åºç€ãªã¢ãŒããã¯ãã£ãã«ã€ããŠä»¥äžã®å
容ãäžå¿ã«ç޹ä»ããŸãã æ°æ§åºåãã°åºç€ã®æŠèŠ åºåãã°åºç€ãªã¢ãŒããã¯ãã£ã®é²ãæ¹ã§è¯ãã£ãæ¹é ãªãã以äžã®å
容ã«ã€ããŠã¯æ¬èšäºã§ã¯ç¹çããå¥ã®æ©äŒã«è²ããŸãã è©³çŽ°ãªæè¡éžå®ããã®æ¹é ãªã¢ãŒããã¯ãã£ã®å¹æ æ¬èšäºã§ç޹ä»ããæ¹éã®èãæ¹ã¯ã©ã®ãããªã·ã¹ãã ã«å¯ŸããŠãå¿çšã§ãããšèããŠããŸãã®ã§ãæ¬èšäºãèªè
ã®çæ§ã«ãšã£ãŠå°ãã§ã圹ç«ã€ãšå¹žãã§ãã ãªã¢ãŒããã¯ãã£ã®èæ¯ æ§åºåãã°åºç€ã®æŠèŠ æ±äººæ€çŽ¢ãšã³ãžã³ãã¹ã¿ã³ãã€ãã§ã¯ãæ±äººæ
å ±ããæäŸããã ãã客æ§ãæ±äººåºåã管çã§ããŸãã æ±äººåºåãšã¯ãæ±äººæ
å ±ã®ãã¡ã客æ§ãåºåãšããŠèšå®ããæ±äººã®ããšã§ãã æ ªåŒäŒç€Ÿã¹ã¿ã³ãã€ã§ã¯ãã客æ§ãæ±äººåºåã管çããããã®ãåºå管çç»é¢ããããã®ã»ãé¢é£ããã¢ããªã±ãŒã·ã§ã³ãéçºã»éçšããŠããŸãã åºå管çç»é¢ã®æ©èœã¯ãè€æ°ã®ã¢ããªã±ãŒã·ã§ã³ã飿ºããŠå®çŸããŠããŸãã ãã®ä»£è¡šçãªæ©èœã¯ãåºåãã°ã®éèšçµæãè«æ±ããŒã¿ãæäŸããã¬ããŒãæ©èœã§ãã åºåãã°ãšã¯ãæ±äººåºåã«å¯Ÿããæ±è·è
ã®ããŸããŸãªè¡åãã°ã®ããšã§ãã ã¬ããŒãæ©èœãå®çŸããã«ã¯ãäŸãã°ä»¥äžã®ãããªã¢ããªã±ãŒã·ã§ã³ãå¿
èŠã«ãªããŸãã ã¬ããŒãæ©èœãæäŸããã¢ããªã±ãŒã·ã§ã³ ãã°ããŒã¿ãè«æ±ããŒã¿ãä¿æããDB ããŒã¿ãæŽæ°ããã¢ããªã±ãŒã·ã§ã³ å®éã«ç§ãã¡ã®åºå管çç»é¢ã®è£åŽã§ãåºåãã°ãè«æ±ããŒã¿ãéèšããä»çµã¿ãåããŠããããããã®ä»çµã¿ãç§ãã¡ã¯ãåºåãã°åºç€ããšåŒãã§ããŸãã 以äžã®å³ã¯ããªã¢ãŒããã¯ãã£åã®åºåãã°åºç€ïŒæ§åºåãã°åºç€ïŒã®ç°¡åãªã¢ãŒããã¯ãã£ã§ãã ïŒå®éã®ã¢ãŒããã¯ãã£ã¯ããè€éã§ãããæ¬èšäºã§ã¯èª¬æãç°¡åã«ãããããæå°éã®æ§æã§è¡šçŸããŠããŸããïŒ æ§ã¢ãŒããã¯ãã£ã®ç¹åŸŽãšèª²é¡ æ§åºåãã°åºç€ã¯æŽå²çãªèæ¯ã«ãããäž»ã«ä»¥äžã®ãããªç¹åŸŽããããŸããã åºåãã°ãéèšããçµè·¯ã3ã€ååšããïŒããŒã¿åºç€ããããåŠçAããããåŠçBïŒã ãããåŠçAãšBã¯ããããç°ãªãçš®é¡ã®åºåãã°ãéèšããã 3ã€ã®çµè·¯ã¯ããããç°ãªãæè¡ã§å®è£
ãããŠããã äžéšã®ã¢ããªã±ãŒã·ã§ã³ïŒããŒã¿åºç€ãªã©ïŒã¯å¥ã°ã«ãŒãã管èœããŠããã 瀟å
ããã¯ãããŒã¿åºç€ãšãããåŠçã§éèšãããããŒã¿ãå©çšã§ããã åºå管çç»é¢ã¯ããããåŠçã§éèšãããããŒã¿ãå©çšããã ããããªãããã¹ã¿ã³ãã€ã®ãµãŒãã¹ãšããŠã®æé·ãå
šç€Ÿå
±éã®æè¡éžå®ã¬ã€ãã©ã€ã³ã®æŽæ°ã人å¡ã®å¢æžãªã©ãããŸããŸãªå€åã«äŒŽã£ãŠæ§åºåãã°åºç€ã®ã¢ãŒããã¯ãã£ã®äžéšã課é¡ãšããŠèªèãããããã«ãªããŸããã ç¹ã«ãäžèšã®ãããªç¶æ
ã«èµ·å ããŠéçºã»éçšã»ä¿å®ã®ã³ã¹ããé«ãç¶æ
ã§ããã åºåãã°ãéèšããçµè·¯ãè€æ°ååšãã åºåãã°ããŒã¿ã2éã«ç®¡çããïŒããŒã¿åºç€ãåºåãã°åºç€ïŒ ãããåŠçAãšBã«å
±éã®ä»æ§ãå®è£
ãããŠãã ãããåŠçBã«å€æ©èœãã€è€éã§éèŠãªä»æ§ãå®è£
ãããŠãã 瀟å
å
±éã®æè¡éžå®ã¬ã€ãã©ã€ã³ã®æŽæ°ã人å¡ã®å¢æžã«äŒŽããã¡ã€ã³ç¥èãã¹ãã«ç¿åŸãå¿
èŠ äŸãã°ãåºåãã°éèšã®ä»æ§ãæ¹åãããèŠæãçºçããéãåºåãããããŒã¿ã®æŽåæ§ãå
šç€ŸãšããŠä¿ã€ããã«ã¯è€æ°çµè·¯ã®éçºãå¿
èŠã«ãªãããéçºã³ã¹ããé«ãç¶æ
ã§ããã ä»ã«ã¯ããããåŠçBã«ã¯è«æ±æ¥åã«äœ¿çšãããããªéèŠãªåŠçãå«ãŸããŠããããããããåŠçBã«äŸåããŠããè€æ°ã®ã¢ããªã±ãŒã·ã§ã³çŸ€ã«ç¹æ®µé
æ
®ããå¿
èŠããããéçºå¹çã»éçšæ§ã»ä¿å®æ§ãäœãç¶æ
ã§ããã æ°åºåãã°åºç€ åºåãã°åºç€ãªã¢ãŒããã¯ãã£ãšããŠã¯ãæ°æ§ã®åºåãã°åºç€ã®äžŠè¡çšŒåãåæãšãã€ã€ã2ã€ã®ãã§ãŒãºã«åããŠé²ããããšã«ããŸããã 䞊è¡çšŒåã®åœ±é¿ã2ã€ã®ãã§ãŒãºã«åããçç±ã«ã€ããŠã¯ãè¯ãã£ãæ¹éãã«ãŠåŸè¿°ããŸãããäž»ãªã³ã³ã»ãããšããŠã¯ä»¥äžãèããŸããã åºåãã°ã®éèšçµè·¯ã®çµ±äž åºåãã°ããŒã¿ã®äžå
管ç ã³ã³ã»ãããããšã«ãåãã§ãŒãºã®ãŽãŒã«ã以äžã®ããã«å®ããŸããã ãã§ãŒãº1ïŒãããžã§ã¯ãå®äºæã®çæ³ç¶æ
ïŒToBeïŒã®éªšæ Œãäœã ãããåŠçBã廿¢ããããš ãããåŠçBãéèšããŠãããã°ããŒã¿ãæŽæ°ããããããåŠçXããªãªãŒã¹ããããš ãããåŠçBãéèšããŠããè«æ±ããŒã¿ãæŽæ°ããããããåŠçYããªãªãŒã¹ããããš ãã§ãŒãº2ïŒãããžã§ã¯ãå®äºæã®çæ³ç¶æ
ïŒToBeïŒãäœã ãããåŠçAã廿¢ããããš ãããåŠçAãéèšããŠãããã°ããŒã¿ãããããåŠçXãéèšããã㚠以äžã®å³ã¯ããªã¢ãŒããã¯ãã£åŸã®åºåãã°åºç€ïŒæ°åºåãã°åºç€ïŒã®ç°¡åãªã¢ãŒããã¯ãã£ã§ãã ïŒãããŒã¿åºç€ãããæ°ããŒã¿åºç€ãã«å€ãã£ãŠããããšã«ã€ããŠã¯ãåŸè¿°ããŸããïŒ è¯ãã£ãæ¹é åœåãåºåãã°åºç€ãªã¢ãŒããã¯ãã£ãé²ããã«ããã£ãŠ Design Doc ãªã©ãäœæããŠãããã¡ã«ãäž»ã«ä»¥äžã®çç±ã§ãã®ãããžã§ã¯ãã¯é·æçãªåãçµã¿ã«ãªããšæ³å®ãããŸããã äžè¬çã«ããªã¢ãŒããã¯ãã£ã¯é·æçãªåãçµã¿ã§ãã ãªã¢ãŒããã¯ãã£ã«é¢é£ããã³ã³ããŒãã³ãïŒã¢ããªã±ãŒã·ã§ã³ãDBãªã©ïŒãå€ã ã°ã«ãŒãéãŸãã¯ãããžã§ã¯ãéã®é£æºãå¿
èŠã§ãã è«æ±ããŒã¿ãæ±ãããããªã¢ãŒãååŸã®å質管çãéèŠã§ãã ãã®ãããé·æçãªåãçµã¿ã«ãããŠãæ¹åæ§ãèŠå€±ãããçå®ãã€å®å
šã«åºåãã°åºç€ãªã¢ãŒããã¯ãã£ãå®éã§ããããã«ããªã¢ãŒããã¯ãã£ã®æ¹éãïŒçŽäœæ²æããªããïŒæ±ºããŸããã 以äžã®3ã€ã¯ãåºåãã°åºç€ãªã¢ãŒããã¯ãã£ã«ãããŠç¹ã«è¯ãã£ããšæããæ¹éã§ãã ååãšããŠä»æ§ãå€ããªãã£ãããš ã¹ã³ãŒããéå®ããŠæ®µéçã«ãªãªãŒã¹ããããš å
šäœæé©ãæèããŠã¢ãããŒãããããš åæ¹éã«ã€ããŠè©³ããã玹ä»ããŸãã ååãšããŠä»æ§ãå€ããªãã£ãããš åºåãã°åºç€ãªã¢ãŒããã¯ãã£ã®ååŸã§åå仿§ãå€ããªãããšãæ¹éãšããŠæ±ºããŸããã ãªã¢ãŒããã¯ãã£ã宿œããäžã§ããã®æ¹éããããŠåŒ·èª¿ããå¿
èŠããªããšæããæ¹ãããã£ããããããããŸããã ããããªããããã®æ¹éããããŠåŒ·èª¿ããããšã¯çµæãšããŠãšãŠãè¯ãã£ããšæããŸããã ãšã³ãžãã¢ã®æ¹ã§ããã°å
±æããã ãããšæããŸãããäœæ¥ã調æ»ãé²ãããã¡ã«ããã£ãšå¹ççã«å®è£
ã§ãããããã€ãã§ã«ä¿®æ£ãããããšãã£ã颚ã«ãæ¹åç¹ãçºèŠããããšããããŸãã åºåãã°åºç€ãªã¢ãŒããã¯ãã£ãäŸå€ã§ã¯ãªããæ¹åãå¯èœãªïŒæ¹åããããªãïŒä»æ§ãããã€ãååšããå®éã«æ¹åãææ¡ãã声ãäžãã£ãŠããŸããã ãããã£ãå§¿å¢ã¯èª²é¡è§£æ±ºã«ç©æ¥µçã§è¯ãããšã ãšæããŸãããåºåãã°åºç€ãªã¢ãŒããã¯ãã£ã«ãããŠã¯ãã®å§¿å¢ãåãããšã«ãããªã¹ã¯ãäºåã«æ³å®ã§ããŸããã å
·äœçã«ã¯ä»¥äžã®ãããªãªã¹ã¯ãèããããŸããã å察å¿ã®æææ±ºå®ãéœåºŠå®æœããããšã§ãããžã§ã¯ããé·æåãã ãªã¢ãŒããã¯ãã£ååŸã§ããŒã¿åè³ªïŒæ£ç¢ºæ§ãå®å
šæ§ãäžè²«æ§ãªã©ã®ïŒæ€èšŒãè€éåãã åºåãã°åºç€ãªã¢ãŒããã¯ãã£ãšããŠã¯ããã®ãããªãªã¹ã¯ãäºåã«çè§£ããäžã§ååãšããŠä»æ§ãå€ããªãã£ãããšã§ãæææ±ºå®ã®è³ªãšã¹ããŒããäžãããªãããã«å·¥å€«ããŸããã ãŸããæ°æ§ã®åºåãã°åºç€ã䞊è¡çšŒåããããšããããããŒã¿å質æ€èšŒã®å®æœãããããšæ€èšŒã®åçŽããç¶æããŠé²ããããšãã§ããŸããã ã¹ã³ãŒããéå®ããŠæ®µéçã«ãªãªãŒã¹ããããš ããã§ããã¹ã³ãŒããšã¯ãåºåãã°åºç€ãªã¢ãŒããã¯ãã£å¯Ÿè±¡ã®ã³ã³ããŒãã³ããæããŸãã åè¿°ã®éããæ°æ§ã®åºåãã°åºç€ã䞊è¡çšŒåããããšãåæãšããŠãåºåãã°åºç€ãªã¢ãŒããã¯ãã£å¯Ÿè±¡ã®ã³ã³ããŒãã³ããéå®ããŠæ®µéçã«ãªãªãŒã¹ããããšã«ããŸããã ãã®æ¹éã«ã¯äž»ã«ä»¥äžã®çãããããŸããã ROIãæå€§åãããå
·äœçã«ã¯ãåºåãã°åºç€ãªã¢ãŒããã¯ãã£ã®å¹æãæå€§åããã³ã³ããŒãã³ãããçæããã èªç¥è² è·ãäžãããå
·äœçã«ã¯ãå¯èœãªéãå°ãªãã³ã³ããŒãã³ãã®äœæ¥ã«éäžããŠãªã¢ãŒããã¯ãã£ã«å¿
èŠãªæ
å ±ãéå®ããã ãªãœãŒã¹ãéäžãããå
·äœçã«ã¯ãå¯èœãªéãå°ãªãã³ã³ããŒãã³ãã®äœæ¥ã«éçºãªãœãŒã¹ãéäžãããŠå¹æçã«æŽ»çšããã 圱é¿ç¯å²ãéå®ãããå
·äœçã«ã¯ããªã¢ãŒããã¯ãã£ã«ãã£ãŠåœ±é¿ãåããã³ã³ããŒãã³ããéå®ãããããšã§ãªã¹ã¯ç®¡çãã·ã³ãã«ã«ãããªãªãŒã¹æã®åœ±é¿ç¯å²ãæå°éã«ããã ç¥èŠãæ·±ãããå
·äœçã«ã¯ãè€æ°ã®ãã§ãŒãºã§æ®µéçã«é²ããããšã§ããã§ãŒãºããšã«ç¥èŠã掻çšã§ããç¶æ
ãäœãã ãã¡ãã®æ¹éãçãéãã®å¹æãåŸãããšãã§ããŸããã ç¹ã«ã段éçãªãªãªãŒã¹ãäžå
·åãªãçµããããšãã§ããã®ã¯ãã®æ¹éã倧ãã圱é¿ããŠãããšæããŸãã å
šäœæé©ãæèããŠã¢ãããŒãããããš ããã§ããå
šäœæé©ãšã¯ãåºåãã°åºç€ãªã¢ãŒããã¯ãã£ã®ã¹ã³ãŒããè¶
ããå
šç€ŸãšããŠã®åªå
床ã®è©±ã§ãã åºåãã°åºç€ãªã¢ãŒããã¯ãã£ãé²ããåããå¥ã®ãããžã§ã¯ããããŒã¿åºç€ãªã¢ãŒããã¯ãã£ããé²è¡ããŠããŸããã ããŒã¿åºç€ãªã¢ãŒããã¯ãã£ãšã¯ãã¢ãŒããã¯ãã£ã®å³ã«èšèŒããŠãããããŒã¿åºç€ãããæ°ããŒã¿åºç€ãã«ç§»è¡ãããããžã§ã¯ãã§ãã åã°ã«ãŒãã®ç«å ŽãšããŠã¯ãäºãã«ãããžã§ã¯ããã§ããã ãæ©ãé²ããããããåœåã¯ãããžã§ã¯ãéã®èª¿æŽãé£èªããããšããããŸããããã¹ããŒã¯ãã«ããŒãšååããŠå
šäœæé©ãæèããŠé²ãæ¹ãæŽçããŸããã æçµçã«ã¯ãæ°ããŒã¿åºç€ã®ããŒã¿ãã€ãã©ã€ã³ã§åºåãã°ãéèšãããã¢ãŒããã¯ãã£ã®æ¹éã«ããããŠã2ã€ã®ãªã¢ãŒããã¯ãã£ãåæã«å¹çè¯ãå®çŸããããšãæèããŠãæ°ããŒã¿åºç€ã®åæã¯åºåãã°ãåªå
çã«å®è£
ããŠãããæ¹éãšããŸããã ãããžã§ã¯ãåäœã®åªå
床ãããäžã§ã Win-Win ãšãªããããªæè¡·æ¡ã§é²ããããšã§ãã·ã¹ãã ãšéçšãšããŠããããžã§ã¯ããšããŠã ãã§ã¯ãªããæ°æã¡ã®é¢ã«å¯ŸããŠãè¯ã圱é¿ããããŸããã ãŸãšã æ¬èšäºã§ã¯ãåºåãã°åºç€ãªã¢ãŒããã¯ãã£ã®æŠèŠãšè¯ãã£ãé²ãæ¹ã®æ¹éã«ã€ããŠç޹ä»ããŸããã åºåãã°åºç€ã®ãããªå€æ°ã®ã¢ããªã±ãŒã·ã§ã³ã§æ§æãããã¢ãŒããã¯ãã£ãå€ããããšã¯é·æçãªåãçµã¿ã«ãªããŸãããçå®ã§å®å
šã«åãçµãããã®æ¹éãæç¢ºã«ããã®æ¹éãå
±éèªèãšããããšã§ããããããªã¹ã¯ã軜æžãã€ã€å¹ççã«éçºã»éçšã»ä¿å®ã®èª²é¡ãæ¹åã§ããŸããã æ¬èšäºã®å
容ãèªè
ã®çæ§ã«å°ãã§ã圹ç«ã€ãšå¹žãã§ããããããšãããããŸããã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ã¯ããã« ããã«ã¡ã¯ããããã¯ãéšSEOã°ã«ãŒãã®äŒç°ã§ãã ã¹ã¿ã³ãã€ã«å
¥ç€ŸããŠ2ã¶æãçµã¡ãåŸã
ã«æ¥åã«ãæ
£ããŠããŠããŸãïŒ æè¿ã瀟å
ã®æè¡ã«ã³ãã¡ã¬ã³ã¹ã§ç»å£ããæ©äŒãããã ããŸããããã®çºè¡šã®äžã§ç޹ä»ããåãçµã¿ã®1ã€ãã Devinã䜿ã£ãPRã¬ãã¥ãŒã®èªåå ã§ãã ä»åã¯ããã®ä»çµã¿ãå°å
¥ããèæ¯ãšå®éã®éçšæ¹æ³ã«ã€ããŠç޹ä»ããŸãã å°å
¥ããèæ¯ ç§ãã¡SEOGã§ã¯ãæ¥ã
ã®éçºã§GitHubã®Pull RequestïŒä»¥äžãPRïŒã䜿ã£ãŠã³ãŒãã¬ãã¥ãŒããŠããŸããã æ©æ¢°çã«ç¢ºèªã§ãã现ããé
ç®ãå€ããã¬ãã¥ã¢ãŒã®è² æ
ã«ãªã£ãŠãããšæããŠããŸããã ããã§èããã®ãããPRã®ã¬ãã¥ãŒã®åææ®µéãAIã«ä»»ããããªããïŒããšããããšã§ããã åºæ¬çãªã³ãŒãã£ã³ã°èŠçŽã®ãã§ã㯠æãããªãã°ãtypoã®ææ ãã¹ãã«ãã¬ããžã®ç¢ºèª ã»ãã¥ãªãã£äžã®åé¡ç¹ã®æŽãåºã ããããDevinãèªåã§è¡ã£ãŠãããã°ã人éã®ã¬ãã¥ã¢ãŒã¯ããæ¬è³ªçãªéšåïŒãã¡ã€ã³ç¥èãå¿
èŠãªéšåããèšèšã®åŠ¥åœæ§ãªã©ïŒã«éäžã§ããã¬ãã¥ã¢ãŒã®è² è·è»œæžãšã¬ãã¥ãŒæéã®ççž®ãæåŸ
ã§ãããã§ãã ããã§ã PRäœæãšåæã«Devinã«ã¬ãã¥ãŒãããä»çµã¿ ãæ§ç¯ããŸããã ä»çµã¿ã®æŠèŠ å®éã«ã¯2çš®é¡ã®èµ·åæ¹æ³ãçšæããŠããŸãã PRäœæãããªã¬ãŒã«ãããã¿ãŒã³ãšãPRã³ã¡ã³ããããªã¬ãŒã«ãããã¿ãŒã³ããããŸãã ãã¿ãŒã³1: PRäœææã®èªåã¬ãã¥ãŒ PRäœæãšåæã«èªåçã«Devinãã¬ãã¥ãŒãéå§ããŸããæ¥åžžçãªã¬ãã¥ãŒãããŒãžã®çµã¿èŸŒã¿ãç®çãšãªããŸãã ããªã¬ãŒ: pull_request.opened ã€ãã³ã ããã©ã«ãããã³ãã: /devin !prr (PRã¬ãã¥ãŒçšã®ã«ã¹ã¿ã ã³ãã³ã) ãã¿ãŒã³2: PRã³ã¡ã³ãã«ããã«ã¹ã¿ã ã¿ã¹ã¯ PRã³ã¡ã³ãã§ /devin ã®åŸã«ã«ã¹ã¿ã ããã³ãããå
¥åããããšã§ãä»»æã®ã¿ã¹ã¯ãå®è¡ã§ããŸããçšéãšããŠã¯ãã¬ãã¥ãŒä»¥å€ã®èгç¹ããç¹å®ã®çšéã§äœ¿çšããŸãã äŸïŒ /devin ãã®PRã®ãã¹ãã«ãã¬ããžãæ¹åããŠãã ãã /devin ã»ãã¥ãªãã£äžã®åé¡ããªãã確èªããŠãã ãã /devin ããã©ãŒãã³ã¹ã®æé©åæ¡ãææ¡ããŠãã ãã ããªã¬ãŒ: issue_comment.created ã€ãã³ãïŒ /devin ã§å§ãŸãã³ã¡ã³ãïŒ ãªã¯ãšã¹ãè
æ
å ±ãèšé²ãããSlackã«è¡šç€º å®è£
ã³ãŒã å®è£
ã«ã¯2ã€ã®ã¯ãŒã¯ãããŒãã¡ã€ã«ãå¿
èŠã§ãã åŒã³åºãå
ã¯ãŒã¯ãããŒïŒdevin-slack-code-actions.ymlïŒ name : Devin Slack Code Actions on : issue_comment : types : [ created ] pull_request : types : [ opened ] workflow_dispatch : inputs : pr_number : description : 'Pull Request number to review' required : false type : number jobs : parse-devin-prompt : runs-on : ubuntu-latest # Run on: PR opened, issue comments starting with /devin, or manual workflow dispatch if : | github.event_name == 'workflow_dispatch' || github.event_name == 'pull_request' || (github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/devin' )) outputs : pr_number : ${{ steps.extract.outputs.pr_number }} custom_prompt : ${{ steps.extract.outputs.custom_prompt }} comment_author : ${{ steps.extract.outputs.comment_author }} steps : - name : Extract information id : extract run : | if [ "${{ github.event_name }}" == "pull_request" ] ; then PR_NUMBER=${{ github.event.pull_request.number }} CUSTOM_PROMPT="/devin !prr " COMMENT_AUTHOR=" ${{ github.event.pull_request.user.login }} " elif [ " ${{ github.event_name }} " == " issue_comment" ]; then PR_NUMBER=${{ github.event.issue.number }} COMMENT="${{ github.event.comment.body }} " CUSTOM_PROMPT=$(echo " $COMMENT" | sed 's|^/devin[[:space:]]*||' | xargs) COMMENT_AUTHOR="${{ github.event.comment.user.login }} " else PR_NUMBER=${{ inputs.pr_number }} CUSTOM_PROMPT="" COMMENT_AUTHOR="" fi echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT echo "custom_prompt=$CUSTOM_PROMPT" >> $GITHUB_OUTPUT echo "comment_author=$COMMENT_AUTHOR" >> $GITHUB_OUTPUT call-devin-slack : needs : parse-devin-prompt uses : stanby-inc/stanby-github-actions-common/.github/workflows/devin-slack-code-action.yml@master secrets : inherit with : pr_number : ${{ fromJSON(needs.parse-devin-prompt.outputs.pr_number) }} custom_prompt : ${{ needs.parse-devin-prompt.outputs.custom_prompt }} comment_author : ${{ needs.parse-devin-prompt.outputs.comment_author }} repository : ${{ github.repository }} å
±éã¯ãŒã¯ãããŒïŒdevin-slack-code-action.ymlïŒ name : Devin Slack Code Action on : workflow_call : inputs : pr_number : description : 'Pull Request number' required : true type : string custom_prompt : description : 'Custom prompt for Devin' required : false type : string default : '' comment_author : description : 'Author of the comment that triggered this workflow' required : false type : string default : '' repository : description : 'Repository name (owner/repo)' required : true type : string jobs : slack-notification : runs-on : ubuntu-latest steps : - name : Checkout code uses : actions/checkout@v4 with : repository : ${{ inputs.repository }} fetch-depth : 0 - name : Get PR Information id : pr_info run : | PR_NUMBER=${{ inputs.pr_number }} # Extract PR info using GitHub API PR_DATA=$(gh pr view $PR_NUMBER --repo ${{ inputs.repository }} --json title,author,url 2>/dev/ null || echo '{}' ) if [ "$PR_DATA" = "{}" ] ; then echo "Error: Failed to fetch PR #$PR_NUMBER data" exit 1 fi PR_TITLE=$(echo $PR_DATA | jq -r .title) PR_AUTHOR=$(echo $PR_DATA | jq -r .author.login) PR_URL=$(echo $PR_DATA | jq -r .url) echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT echo "pr_title=$PR_TITLE" >> $GITHUB_OUTPUT echo "pr_author=$PR_AUTHOR" >> $GITHUB_OUTPUT echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT env : GH_TOKEN : ${{ secrets.GITHUB_TOKEN }} - name : Get Changed Files id : changed_files run : | # Get list of changed files using gh command CHANGED_FILES=$(gh pr diff ${{ inputs.pr_number }} --repo ${{ inputs.repository }} --name-only | head -20) # Store as plain text, not JSON escaped echo "files<<EOF" >> $GITHUB_OUTPUT echo "$CHANGED_FILES" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT env : GH_TOKEN : ${{ secrets.GITHUB_TOKEN }} - name : Send Slack Message to Devin id : slack_message env : SLACK_BOT_TOKEN : ${{ secrets.DEVIN_SLACK_BOT_TOKEN }} SLACK_CHANNEL_ID : ${{ secrets.DEVIN_SLACK_CHANNEL_ID }} DEVIN_BOT_USER_ID : ${{ secrets.DEVIN_BOT_USER_ID }} run : | # Construct the message with @Devin mention if [ -n "${{ inputs.custom_prompt }}" ] ; then # Custom prompt from /devin comment # Properly escape the custom prompt for JSON ESCAPED_PROMPT=$(echo "${{ inputs.custom_prompt }}" | jq -Rs .) REVIEW_REQUEST="<@$DEVIN_BOT_USER_ID> PR #${{ steps.pr_info.outputs.pr_number }} - $(echo $ESCAPED_PROMPT | jq -r .)" REQUESTER_INFO="_Requested by : ${{ inputs.comment_author }}_" else # Default request REVIEW_REQUEST="<@$DEVIN_BOT_USER_ID> Please check PR #${{ steps.pr_info.outputs.pr_number }} at ${{ steps.pr_info.outputs.pr_url }}" REQUESTER_INFO="" fi # Prepare changed files text for JSON CHANGED_FILES_TEXT=$(echo "${{ steps.changed_files.outputs.files }}" | jq -Rs .) # Send message using Slack API RESPONSE=$(curl -X POST https://slack.com/api/chat.postMessage \ -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ -H "Content-Type: application/json" \ -d @- <<EOF { "channel" : "$SLACK_CHANNEL_ID" , "text" : "$REVIEW_REQUEST \n\n PR: ${{ steps.pr_info.outputs.pr_url }} \n Title: ${{ steps.pr_info.outputs.pr_title }}" , "blocks" : [ { "type" : "section" , "text" : { "type" : "mrkdwn" , "text" : "$(echo " $REVIEW_REQUEST" | jq -Rs . | jq -r .)" } } , { "type" : "section" , "text" : { "type" : "mrkdwn" , "text" : "*PR #${{ steps.pr_info.outputs.pr_number }}: $(echo " $ {{ steps.pr_info.outputs.pr_title }} " | jq -Rs . | jq -r .)* \n Author: ${{ steps.pr_info.outputs.pr_author }} \n URL: ${{ steps.pr_info.outputs.pr_url }}$([ -n " $REQUESTER_INFO" ] && echo " \n $REQUESTER_INFO" || echo "" )" } } , { "type" : "section" , "text" : { "type" : "mrkdwn" , "text" : "*Changed Files:* \n \`\`\`$(echo $CHANGED_FILES_TEXT | jq -r .)\`\`\`" } } , { "type" : "divider" } , { "type" : "section" , "text" : { "type" : "mrkdwn" , "text" : "Please check the PR for full diff." } } , { "type" : "actions" , "elements" : [ { "type" : "button" , "text" : { "type" : "plain_text" , "text" : "View PR on GitHub" } , "url" : "${{ steps.pr_info.outputs.pr_url }}" } ] } ] } EOF ) # Check if message was sent successfully SUCCESS=$(echo $RESPONSE | jq -r .ok) if [ "$SUCCESS" != "true" ] ; then echo "Failed to send Slack message" echo "Response: $RESPONSE" exit 1 fi echo "Slack message sent successfully!" TIMESTAMP=$(echo $RESPONSE | jq -r .ts) echo "timestamp=$TIMESTAMP" >> $GITHUB_OUTPUT - name : Comment on PR if : success() run : | if [ -n "${{ inputs.custom_prompt }}" ] ; then COMMENT_BODY="ð€ Devin has been notified about this PR via Slack. Custom request : _${{ inputs.custom_prompt }}_ Requested by : @${{ inputs.comment_author }} Slack message sent at : $(date -u +"%Y-%m-%d %H:%M:%S UTC")" else COMMENT_BODY="ð€ Devin has been notified about this PR via Slack. Slack message sent at : $(date -u +"%Y-%m-%d %H:%M:%S UTC") Please check your Slack channel for Devin's response." fi gh pr comment ${{ inputs.pr_number }} --repo ${{ inputs.repository }} --body "$COMMENT_BODY" env : GH_TOKEN : ${{ secrets.GITHUB_TOKEN }} åŠçã®æµã ããããã®ãã¿ãŒã³ã®å
šäœã®åŠçã®æµãã«ã€ããŠè§£èª¬ããŸãã ãã¿ãŒã³1: PRäœææã®èªåã¬ãã¥ãŒ ããªã¬ãŒã€ãã³ã éçºè
ãGitHubã§PRãäœæãããšã pull_request.opened ã€ãã³ããGitHub Actionsãããªã¬ãŒããŸãã PRæ
å ±ã®ååŸ GitHub Actionsãèµ·åããGitHub CLIã䜿çšããŠPRã®è©³çްæ
å ±ãååŸããŸãïŒ # PRæ
å ±ã®è©³çްååŸ gh pr view $PR_NUMBER --json title,author,url # 倿Žãã¡ã€ã«äžèЧã®ååŸïŒæå€§20ãã¡ã€ã«ïŒ gh pr diff $PR_NUMBER --name-only | head -20 ããã©ã«ãããã³ããã®èšå® ããã©ã«ãããã³ãã /devin !prr ã䜿çšããã¬ãã¥ãŒçšPlaybookïŒã«ã¹ã¿ã ã³ãã³ãïŒãåŒã³åºããŸãã Slackãžã®ã¡ãã»ãŒãžæçš¿ ååŸããæ
å ±ã䜿ã£ãŠãSlack APIã§Devinã«ã¡ã³ã·ã§ã³ãéããŸãã Devinã«ããã¬ãã¥ãŒå®è¡ Slackã§ã¡ã³ã·ã§ã³ãåããDevinã以äžãå®è¡ããŸãïŒ PRã®URLããGitHubã«ã¢ã¯ã»ã¹ 倿Žå
容ãååŸã»åæ Playbookã«åŸã£ãŠã³ãŒãã¬ãã¥ãŒãã ã¬ãã¥ãŒçµæãSlackã¹ã¬ããã«æçš¿ PRãžã®ã³ã¡ã³ã远å GitHub Actionsãèªåçã«PRã«ã³ã¡ã³ãã远å ããŸãïŒ ð€ Devin has been notified about this PR via Slack. Slack message sent at: 2025-10-08 07:48:08 UTC Please check your Slack channel for Devin's response. PRã«Devinã®ã¬ãã¥ãŒææããã®ãŸãŸæžãæ»ããŠããŸããšãPRã®ã³ã¡ã³ããé·ããªããèŠéããæªããªããšæãããããDevinãšã®ãããšãã¯Slackäžã§ããããããã«ããŠããŸãã ãã¿ãŒã³2: PRã³ã¡ã³ãã«ããã«ã¹ã¿ã ã¿ã¹ã¯ ããªã¬ãŒã€ãã³ã éçºè
ãPRã³ã¡ã³ãã§ /devin [ã«ã¹ã¿ã ããã³ãã] ãšå
¥åãããšã issue_comment.created ã€ãã³ããGitHub Actionsãããªã¬ãŒããŸãã ã¯ãŒã¯ãããŒèµ·åãšæ
å ±æœåº GitHub Actionsãèµ·åãã以äžã®æ
å ±ãæœåºããŸãïŒ PRçªå· ã³ã¡ã³ãæ¬æããã«ã¹ã¿ã ããã³ãããæœåºïŒ /devin ã®åŸãã®æååïŒ ã³ã¡ã³ãäœæè
æ
å ± Slackãžã®ã¡ãã»ãŒãžæçš¿ ã«ã¹ã¿ã ããã³ãããå«ããŠDevinã«ã¡ã³ã·ã§ã³ãéããŸãïŒ Devinã«ããã¿ã¹ã¯å®è¡ Slackã§ã¡ã³ã·ã§ã³ãåããDevinã以äžãå®è¡ããŸãïŒ ã«ã¹ã¿ã ããã³ããã®å
容ãçè§£ PRã®ã³ãŒããååŸã»åæ æç€ºãããã¿ã¹ã¯ïŒãã¹ãã«ãã¬ããžæ¹åãã»ãã¥ãªãã£ãã§ãã¯ãªã©ïŒã宿œ å®è¡çµæãSlackã¹ã¬ããã«æçš¿ PRãžã®ã³ã¡ã³ã远å GitHub Actionsãèªåçã«PRã«ã³ã¡ã³ãã远å ããŸãïŒ ð€ Devin has been notified about this PR via Slack. Custom request: ãã®PRã®ãã¹ãã«ãã¬ããžãæ¹åããŠãã ãã Requested by: @yuto-ida Slack message sent at: 2025-09-15 10:30:00 UTC ãã¡ããåæ§ã«ãDevinãšã®ãããšãã¯Slackäžã§ããããããã«ããŠããŸãã Slackçµç±ã§åŒã³åºãã¡ãªãã ãã®ä»çµã¿ã§ã¯ãDevin APIãçŽæ¥åŒã³åºãã®ã§ã¯ãªããSlackçµç±ã§Devinã«ã¡ã³ã·ã§ã³ãéãæ¹åŒãæ¡çšããŠããŸããããã«ã¯ä»¥äžã®ãããªã¡ãªããããããŸãã ã©ã®ãã©ã³ã§ãå©çšã§ãã Devin APIã䜿çšããå ŽåãAPIã¢ã¯ã»ã¹ã¯ç¹å®ã®ãã©ã³ïŒTeamãã©ã³ãEnterpriseãã©ã³ïŒã«éå®ãããŸãã ããããSlackçµç±ã§DevinãåŒã³åºãæ¹åŒã§ã¯ãã©ã®Devinãã©ã³ã§ãåäœããããããã©ã³ã«çžãããå©çšã§ããŸãã ã³ãã¥ãã±ãŒã·ã§ã³ã®å¯èŠå Slackã®ã¹ã¬ããäžã§Devinãšããåããè¡ããããããPRã³ã¡ã³ãã®ãããšããé·ããªãããšãªãã ããŒã å
šäœã§Devinã®äœæ¥ç¶æ³ãã¬ãã¥ãŒçµæã確èªãããããªããŸãã Devinã®ã¬ãã¥ãŒããã»ã¹ Devinã«ããã¬ãã¥ãŒã®å質ãä¿ã€ãããå°çšã®PlaybookïŒã«ã¹ã¿ã ã³ãã³ãïŒãäœæããŠããŸãã Devin PRã¬ãã¥ãŒçšPlaybook # Devin PRã¬ãã¥ãŒçšPlaybook ## Procedure 1. step 1: ã³ã³ããã¹ãç¢ºèª - PRã®æŠèŠã»ç®çã»é¢é£ããIssueããã±ããã確èªãã - 倿Žç¯å²ïŒdiffïŒãšåœ±é¿ç¯å²ïŒãµãŒãã¹ã»ã¢ãžã¥ãŒã«ã»äŸåé¢ä¿ïŒãææ¡ãã 2. step 2: ã³ãŒãå質ãã§ã㯠- ã³ãŒãã£ã³ã°èŠçŽïŒåœåã»ãã©ãŒãããã»Lintã«ãŒã«ïŒã«æ²¿ã£ãŠãããç¢ºèª - è€éãããåŠçããã¹ããé¿ããèªã¿ããããä¿ã£ãŠããã - åé·ãªã³ãŒããéè€ããªãã 3. step 3: èšèšã»ã¢ãŒããã¯ãã£ç¢ºèª - 責åã®åé¢ãã§ããŠãããïŒé¢æ°ã»ã¯ã©ã¹ã®ç²åºŠïŒ - åå©çšæ§ã»æ¡åŒµæ§ã劚ããèšèšã«ãªã£ãŠããªãã - æ¢åã®èšèšååããããžã§ã¯ãæ¹éã«åŸã£ãŠããã 4. step 4: åäœç¢ºèªãã€ã³ãã®æç€º - ãŠããããã¹ããçµ±åãã¹ããé©åã«æžãããŠããã - äž»èŠãªãšããžã±ãŒã¹ïŒäŸå€åŠçã»null/undefinedã»ãšã©ãŒãªã«ããªïŒãã«ããŒãããŠããã - æå確èªãå¿
èŠãªå Žåããã®ç¯å²ãæèšãã 5. step 5: ã»ãã¥ãªãã£ã»ããã©ãŒãã³ã¹ç¢ºèª - ã»ãã¥ãªãã£ãªã¹ã¯ïŒSQLã€ã³ãžã§ã¯ã·ã§ã³ãXSSãèªèšŒèªå¯ã®æŒãïŒããªãã - äžèŠã«éãåŠçãããã«ããã¯ã«ãªããããªå®è£
ããªãã 6. step 6: ãã£ãŒãããã¯äœæ - ææã¯ããªããæ¹åãå¿
èŠãèæ¯ãæ·»ãã - ä¿®æ£æ¡ãåèãªã³ã¯ãæç€ºãã - æ¿èªã»ä¿®æ£èŠæã»ãããã«ãŒãæç¢ºã«åºåãã ## Advice & Pointers - ãGood firstãã³ã¡ã³ããæ·»ããïŒè¯ãå®è£
ã工倫ãããç¹ã¯ç©æ¥µçã«è€ãã - ãããžã§ã¯ãã®ã¬ã€ãã©ã€ã³ãã¹ã¿ã€ã«ã¬ã€ããåŒçšãããšèª¬åŸåãå¢ã - ã³ã¡ã³ãã¯ç°¡æœã«ããã€å
·äœçã«ïŒäŸïŒã倿°åãuserListã«ãããšçšéãæç¢ºã«ãªããŸããïŒ - åªå
床ãã€ããŠäŒããïŒmust / should / nice-to-haveïŒ ## Forbidden actions - äººæ Œæ¹å€ãææ
çãªã³ã¡ã³ããããªã - æœè±¡çãããææïŒäŸïŒããããªããã ãïŒã¯çŠæ¢ãå¿
ãçç±ãšä»£æ¿æ¡ãæ·»ãã - éå°ãªä¿®æ£äŸé ŒïŒãããžã§ã¯ãæ¹éãšç¡é¢ä¿ãªå人ç奜ã¿ïŒã¯ããªã - ãã¹ããç¡èŠããŠã¬ãã¥ãŒæ¿èªããªã - ã»ãã¥ãªãã£ãªã¹ã¯ã®èŠèœãšããæŸçœ®ããªã éçšããŠåãã£ãããš å®éã«éçšãå§ããŠãããDevinã®ã¬ãã¥ãŒã«ã¯ä»¥äžã®ãããªå¹æããããšæããŠããŸãã ã¬ãã¥ãŒã®è³ªã®åäž Devinã®ææã§ç¹ã«åœ¹ç«ã£ãŠããã®ã¯ä»¥äžã§ãïŒ èŠèœãšããã¡ãªåºæ¬çãªãã¹ã®æ€åº 倿°åã®typo æªäœ¿çšã®importæ ãšã©ãŒãã³ããªã³ã°ã®æŒã ãã¹ãã±ãŒã¹ã®äžè¶³ ã»ãã¥ãªãã£é¢é£ã®ææ SQL injectionã®å¯èœæ§ æ©å¯æ
å ±ã®ãã°åºå XSSè匱æ§ã®ãªã¹ã¯ ããã©ãŒãã³ã¹ã«é¢ããææ¡ äžèŠãªã«ãŒãåŠç ã¡ã¢ãªå¹çã®æ¹åæ¡ ã³ãŒãã£ã³ã°èŠçŽã®çµ±äž 人éã ãšã€ãèŠéããŠããŸã现ããèŠçŽéåããDevinã¯äžè²«ããŠææããŠãããŸããããã«ãããã³ãŒãããŒã¹å
šäœã®å質ãåäžã«ä¿ãããããã«ãªããŸããã ã¬ãã¥ã¢ãŒã®è² æ
è»œæž çŽ°ãããã§ãã¯é
ç®ãDevinãæ
åœããŠãããããã人éã®ã¬ãã¥ã¢ãŒã¯ããé«åºŠãªå€æãæ±ããããéšåã«å¯ŸããŠéäžã§ããããã«ãªããŸããã èšèšææ³ã®åŠ¥åœæ§ ããžãã¹ããžãã¯ã®æ£ç¢ºæ§ ã¢ãŒããã¯ãã£ãšã®æŽåæ§ éçãšäººéã¬ãã¥ãŒã®éèŠæ§ ãã¡ãããDevinã«ãéçããããŸãïŒ ããžãã¹èŠä»¶ãšã®æŽåæ§ ïŒãã¡ã€ã³ç¥èãå¿
èŠãªå€æã¯é£ãã ã³ã³ããã¹ãã®çè§£ ïŒPRã®èæ¯ãæå³ãå®å
šã«çè§£ããã®ã¯é£ãã ãã®ããã Devinã®ã¬ãã¥ãŒã¯ãããŸã§ãäžæ¬¡ãã§ã㯠ãšäœçœ®ã¥ããæçµçãªæ¿èªã¯å¿
ã人éã®ã¬ãã¥ã¢ãŒãè¡ã£ãŠããŸãã Devinãšäººéã®åœ¹å²åæ
ãæç¢ºã«ããããšã§ãäž¡è
ã®åŒ·ã¿ã掻ãããå¹ççãªã¬ãã¥ãŒãããŒãå®çŸã§ããŠãããšæããŠããŸãã ãŸãšã ä»åãPRäœæãšåæã«Devinãèµ·åããä»çµã¿ãå°å
¥ããããšã§ã ã¬ãã¥ã¢ãŒã®è² æ
ãè»œæž ãããéçºè
ã¯æ¬è³ªçãªéšåã«å¯ŸããŠéäžã§ããããã«ãªã£ããšæããŠããŸãã éèŠãªã®ã¯ã Devinã¯ãããŸã§ãã¬ãã¥ãŒããµããŒãããããŒã«ã§ããã人éã®ã¬ãã¥ã¢ãŒã眮ãæãããã®ã§ã¯ãªã ãšããç¹ã§ãã AIãšäººéãããããã®åŒ·ã¿ã掻ãããååããŠã¬ãã¥ãŒããäœå¶ãæ§ç¯ã§ããããšãããã®åãçµã¿ã®æåèŠå ã ãšèããŠããŸãã ä»åŸãéçšãç¶ããªããæ¹åãéããããå¹ççã§è³ªã®é«ãéçºããã»ã¹ãç®æããŠããããã§ãã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
æ ªåŒäŒç€Ÿã¹ã¿ã³ã〠QAã°ã«ãŒãïŒQuality Assurance GroupïŒã®æšœäºã§ãã ãèªåãã¹ãã¯åºç¯å²ã§å€±æããŠããããæåãã¹ãã§ã¯ã©ã®æ©èœã圱é¿ãåããŠããã®ãããããªãâŠã ãªã°ã¬ãã·ã§ã³ãã¹ãã®éããããªç¶æ³ã«é¥ã£ãããšã¯ãããŸãããïŒ ç§éã®ããŒã ã§ã¯ããã®èªåãã¹ããšæåãã¹ãã®çµæãåæãããŠããããšããåé¡çºèŠã®é
ãããäžå
·åã®èŠéããªã¹ã¯ã«ã€ãªãã£ãŠããŸããã æ¬èšäºã§ã¯ãMagicPod Web APIã䜿ã£ãŠã©ã®ããã«è§£æ±ºããã®ãããã®å
·äœçãªåãçµã¿ãã玹ä»ããŸãã MagicPodå°å
¥ã«ã€ããŠèå³ã®ããæ¹ã¯ãéå»èšäºã®ã ã¹ã¿ã³ã〠QAã®ãã¹ãèªååå°å
¥ïŒMagicPodïŒ ããã確èªäžããã techblog.stanby.co.jp ãªããã¹ãçµæãçµ±åããã®ã ã¢ãã€ã«ã¢ããªïŒä»¥éAppïŒã®ãªã°ã¬ãã·ã§ã³ãã¹ãã¯ãMagicPodã«ããèªåãã¹ããšQAæ
åœè
ã«ããæåãã¹ãã䜵çšããŠããŸãã ãªã°ã¬ãã·ã§ã³ãã¹ãã®åé
ç®ã«ã¯ãMagicPodã·ããªãªïŒä»¥éã·ããªãªïŒã®IDãçŽã¥ããããŠãããã©ã®ã·ããªãªãã©ã®é
ç®ãæ
ã£ãŠããããææ¡ããã«çãŸã£ãŠããŸããã ããã§ã®ãªã°ã¬ãã·ã§ã³ãã¹ãïŒååž°ãã¹ãã»éè¡ãã¹ãïŒã¯ããœãããŠã§ã¢ã®æ©èœè¿œå ãäžå
·åä¿®æ£ãç°å¢å€æŽãªã©ã®ããã°ã©ã 倿Žã«ãã£ãŠããããŸã§æ£åžžã«åäœããŠããæ©èœã«æ°ããªäžå
·åãçºçããŠããªãã確èªãããã¹ããæããŸãã APIå©çšä»¥åã®ãªã°ã¬ãã·ã§ã³ãã¹ã åé¡ã¯ãã·ããªãªäžæ¬å®è¡ã§è€æ°ã·ããªãªã倱æããéã圱é¿ç¯å²ã®ç¹å®ã«å€å€§ãªæéãããã£ãŠããããšã§ããã æåãã¹ãã¯äžé
ç®ãã€å®æœããããããªã°ã¬ãã·ã§ã³ãã¹ãã®é
ç®äžã§ãã©ã®æ©èœãNGã§ãã£ããããã«åãããŸããããããMagicPodã®äžæ¬å®è¡çµæã¯ãããŒã«äžã§ã©ã®ã·ããªãªã倱æãããåãããŸããããããå
·äœçã«ã©ã®æ©èœãžã®åœ±é¿ãæå³ããã®ããå³åº§ã«å€æããã®ã¯å°é£ã§ããã ç¹ã«åºç¯å²ã§å€±æããŠããå Žåããããã€ã³ãã©ã®åé¡ãªã®ããå
±éã³ã³ããŒãã³ãã®ãã°ã¬ãªã®ããã¯ããŸããã¹ãç°å¢ã®äžèª¿ãªã®ãâŠãåå ãåãåããããã«ãã²ãšã€ã²ãšã€ã®å®è¡çµæãã°ã远ããéçºè
ã«ãã¢ãªã³ã°ã⊠ãšããéå¹çãªèª¿æ»ãçºçããŠããŸããã ãã®èª¿æ»ã®é
ãã¯ãäžå
·åã®çºèŠãé
ãããªã¹ã¯ã«çŽçµããŸããèªåãã¹ããšæåãã¹ããç¬ç«ããããŠãããã®ç¶æ³ããªããšãããããšèããäž¡è
ã®ãã¹ãçµæãçµ±åããäžç®ã§æ¯èŒã§ããããã«ããããšã決ããŸããã MagicPod Web APIã®å©çš ã¹ã¿ã³ãã€ã§ã¯ããªã°ã¬ãã·ã§ã³ãã¹ããã¹ãã¬ããã·ãŒãã§ç®¡çããŠãããããMagicPodãã«ãã»ã³ã¿ãŒã®ã MagicPodãæäŸããWeb APIã®äœ¿ç𿹿³ ããåèã«ãã·ããªãªäžæ¬å®è¡çµæãã¹ãã¬ããã·ãŒããžåºåããããšã«ããŸããã MagicPod Web APIãã©ã®ããã«æŽ»çšããŠããã®ãã¯ãŸã æ€è𿮵éã®ãããæã
æ¢åã·ã¹ãã ãå©çšããæå°éã®ã³ãŒãäœæãšããŠããŸãã ã·ã¹ãã æŠèŠå³ ãªã°ã¬ãã·ã§ã³ãã¹ãã§ã¯ãã·ããªãªIDãããŒãšããŠãæåãã¹ãçµæãšçŽã¥ããè¡ããŸããã MagicPod Web APIã§ååŸããäžæ¬å®è¡çµæäžèЧ äžæ¬å®è¡çµæãšçµåãããªã°ã¬ãã·ã§ã³ãã¹ã ãã¹ãçµæã®çµ±åã§åŸããã3ã€ã®å€å ãã¹ãçµæãçµ±åããããšã§ãå¬ããå€åããããŸããã å€å1ïŒåœ±é¿ç¯å²ç¹å®ãŸã§ã®æéççž® 以åã¯æ°æéããããã·ããªãªäžæ¬å®è¡çµæããã¹ãŠç¢ºèªããããšã§åœ±é¿ç¯å²ãç¹å®ããŠããŸããããã¹ãã¬ããã·ãŒããèŠãã ãã®æ°åã§å®äºããããã«ãªããŸããããåé¡ãã©ãã§èµ·ããŠããã®ãããé
ç®åäœã§ææ¡ã§ãããããäžå
·å起祚æã®åçŸç¢ºèªã«ã圹ç«ã¡ãŸãã å€å2ïŒãã°ã¬èª¿æ»ã®é«éå éå»ã®ã·ããªãªäžæ¬å®è¡çµæãäžèЧåããŠããããããããã¯ååããèµ·ããŠããäžå
·åããããã¯ä»åã®å€æŽã«ããæ°ãããã°ã¬ããšãã£ãåé¡ã®åãåããæ©ããªããŸãããæŽã«ã¯åé¡ã解決ããåŸã圱é¿ç¯å²ãæ£ããã£ããã®çãåãããšããŠã掻çšã§ããŸãã å€å3ïŒæåãã¹ãã®åªå
ä»ã æåãã¹ãæ
åœè
ãèªåãã¹ãã®å€±æç®æããªã¢ã«ã¿ã€ã ã§ææ¡ã§ãããããããã®æ©èœã¯åé¡ããããããããªãã®ã§ãåªå
çã«ãã¹ããããããšãã£ãå
åã察å¿ãå¯èœã«ãªããããŒã å
šäœã§å¹ççã«äžå
·åãçºèŠã§ããããã«ãªããŸããã çµããã« MagicPod Web APIã®æŽ»çšã¯ãŸã å§ãŸã£ãã°ããã§ãããèªåã»æåãšãã2ã€ã®ãã¹ãçµæãç¹ãããšã§ãããã€ãã®æ¹å广ãåŸãããŸããã ãããçæ§ã®çŸå Žã§ããã¹ãçµæãç¹åšããéå¹çãªèª¿æ»ãçºçããŠããããã§ãããããã®èšäºã解決ã®ãã³ãã«ãªãã°å¹žãã§ãã 以äžããããŸã§ãä»ãåãããã ãããããšãããããŸããïŒ ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ããã«ã¡ã¯ãã¹ã¿ã³ãã€ã§ã€ã³ãã©ãæ
åœããŠããåä¿£ã§ãã ä»åã¯EKSãæ¥ã
éçšããŠããäžã§çŽé¢ããæè¡çãªèª²é¡ã®ãã¡ãã¹ã¿ã³ãã€ã®EKSã¯ã©ã¹ã¿ã«å°å
¥ããŠãããReloaderããšããã¢ããªã±ãŒã·ã§ã³ã«ã€ããŠç޹ä»ããŸãã Reloaderãšã¯ Kubernetesã®ConfigMapãSecretã®å€æŽãæ€ç¥ãã該åœããPodãèªåçã«åèµ·åããŠããã䟿å©ãªããŒã«ã§ãã ã¹ã¿ã³ãã€ã§ã¯ãAWS Parameter Store ã« æ©å¯æ
å ±ãä¿åããŠãããSecret ã«åæ ããŠãŸãã Parameter Store ã«ä¿åããŠããæ©å¯æ
å ±ã倿Žãããš Secret ã倿Žãããã®ã§ããã®ããã« Reloader ã䜿çšããŠãŸãã https://github.com/stakater/Reloader?tab=readme-ov-file#-what-is-reloader èª²é¡ ãããŸã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã¯1ã€ã®ããŒã ã¹ããŒã¹å
ã§çšŒåãããŠããŸããã Reloaderã¯ãã®ã¢ããªã±ãŒã·ã§ã³ã®ããŒã ã¹ããŒã¹ã«é
眮ããããã®ããŒã ã¹ããŒã¹ã®ã¿ç£èŠããŠããç¶æ
ã§ããã ã¹ã¿ã³ãã€ã§ã¯ãèŠæš¡æ¡å€§ã«åããæ°èŠã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ããªã¢ãŒããã¯ãã£ãè¡ãããŠãããã¢ããªã±ãŒã·ã§ã³ã®ã¯ãŒã¯ããŒããç¹æ§ããšã«è€æ°ã®ããŒã ã¹ããŒã¹ã«åããããšããèŠæãããã£ãŠããŸããã ãã®ãããä»åŸæ§ç¯ãããæ°èŠã®ããŒã ã¹ããŒã¹ãåæ§ã«Reloaderã«ç£èŠãããå¿
èŠãããã皌åäžã®EKSã¯ã©ã¹ã¿ã«å¯ŸããŠèšå®å€æŽãå¿
èŠã§ããã èšå®å€æŽæŠèŠ çŸç¶ã®Reloaderã¯ä»¥äžã®ãããªèšå®ã«ãªã£ãŠããŸããã æ¢åã¢ããªã±ãŒã·ã§ã³ãšåãããŒã ã¹ããŒã¹ã«é
眮ããããã®ããŒã ã¹ããŒã¹ã®ã¿ãç£èŠããŠãã ãã®äžã§ annotation ãèšå®ãããŠãã pod ãç£èŠå¯Ÿè±¡ 察ããŠãæ°èŠè¿œå ããããŒã ã¹ããŒã¹ãç£èŠã§ãããã以äžã®ãããªæ¹éã§èšå®å€æŽããäºã決ããŸããã Reloaderå°çšã®ããŒã ã¹ããŒã¹ã«é
眮ããå
šããŒã ã¹ããŒã¹ãç£èŠãã ãã®äžã§ annotation ãèšå®ãããŠãã pod ãç£èŠå¯Ÿè±¡ çµæçã«ã以äžã®ãããªã¹ãããã§èšå®å€æŽã宿œããŸããã Reloaderå°çšããŒã ã¹ããŒã¹ãäœæ Reloaderã®èšå®ã倿Žããå
šãŠã®ããŒã ã¹ããŒã¹ãç£èŠããããã«å€æŽ Reloaderå°çšããŒã ã¹ããŒã¹ã«Reloaderãåé
眮 ãããã解説ããŠãããŸãã 1.Reloaderå°çšããŒã ã¹ããŒã¹ãäœæ Reloaderãä»ã®ã¢ããªã±ãŒã·ã§ã³ãªãœãŒã¹ãšåé¢ããããšã§ãä»ã®ã¢ããªã±ãŒã·ã§ã³ãªãœãŒã¹ãšã®æ··åšãé²ããã¯ã©ã¹ã¿ã«å¯Ÿãããªãã¬ãŒã·ã§ã³æã®ã¡ã³ããã³ã¹æ§ãåäžãããçºãæ°ããReloaderå°çšã®ããŒã ã¹ããŒã¹ãäœæããŸãã åæãšããŠãã¹ã¿ã³ãã€ã¯EKSã¯ã©ã¹ã¿ãšå
éšã®ã³ã³ããŒãã³ããterraform+helmãã¢ããªã±ãŒã·ã§ã³ãArgoCDã§æ§æããŠããŸãã ããŒã ã¹ããŒã¹ã«é¢ããŠã¯terraformã䜿çšããŠæ§ç¯ããŠããã以äžãå®éã®ã³ãŒãã§ãã resource "kubernetes_namespace" "reloader" { metadata { name = "reloader" } } 2.Reloaderã®èšå®ã倿Žããå
šãŠã®ããŒã ã¹ããŒã¹ãç£èŠããããã«å€æŽ Reloaderèªäœã¯terraform+helmã§å®è£
ãããŠããŸãã ããã§ã¯ã reloader.watchGlobally ã®å€ã false ãã true ã«å€æŽããŸãã ããã«ãããReloaderãé
眮ãããŠããããŒã ã¹ããŒã¹ã®ã¿ãç£èŠããŠããç¶æ
ãããé
眮ãããŠããããŒã ã¹ããŒã¹ãåããå
šããŒã ã¹ããŒã¹ãç£èŠããç¶æ
ã«ãªããŸãã values.yaml ã®äžã®ä»¥äžã®èšå®ã倿ŽããŸãã reloader: reloadStrategy: annotations watchGlobally: true # ãããå€æŽ 3.Reloaderå°çšããŒã ã¹ããŒã¹ã«Reloaderãåé
眮 以äžãå®éã®ã³ãŒãã§ã 1. ã§æ§ç¯ããå°çšã®ããŒã ã¹ããŒã¹ãæå®ããŠããŸãã é
眮ããŒã ã¹ããŒã¹ã®å€æŽã«ãããhelmãã£ãŒãã®replaceãèµ°ããdeploymentã®åé€âäœæãè¡ãããŸãã locals { helm_reloader = { repository = "https://stakater.github.io/stakater-charts" version = "1.X.X" } } resource "helm_release" "reloader" { name = "reloader" chart = "reloader" repository = local.helm_reloader.repository version = local.helm_reloader.version namespace = kubernetes_namespace.reloader.id # ãããå€æŽ values = [ templatefile("_files/reloader/values.yaml", { env = var.env version = local.helm_reloader.version }) ] } ãã¹ããæ€èšŒã«ã€ã㊠èšå®èªäœã¯è³ã£ãŠã·ã³ãã«ã§ãããæ¢ã«çšŒåããŠããç°å¢ãžã®èšå®å€æŽãšãªãã®ã§ãæ€èšŒã»èª¿æ»ã«å€ãã®æéãå²ããŸããã èµ·ããåŸãã·ããªãªãåæããã©ããäœæããããŒã å
ã§ãã©ãã·ã¥ã¢ãããéãããã¹ãã±ãŒã¹ã«èœãšã蟌ã¿ãŸããã æ£åžžç³»ã®åäœç¢ºèªæ¹æ³ã®äžéšã§ããã以äžã®ãããªæ¹æ³ã宿œããŸããã Reloaderã®ãã°ã¬ãã« reloader.loglevel ãdebugã«å€æŽ reloader: logLevel: debug é©åœãªã¢ããªã±ãŒã·ã§ã³ã®ConfigMap/Secretã以äžã®ããã«æåã§å€æŽ ### ConfigMap $ kubectl patch configmap hoge-staging --type merge -p '{"data":{"HOGE":null}}' ### Secret $ kubectl label secret hoge-staging hoge/hoge=hoge --overwrite 察象ã®podsãåèµ·åãããŠããäºãç¢ºèª $ kubectl get pods | grep hoge Reloaderã®ãã°ããã倿Žãæ€ç¥ãããŠããäºãç¢ºèª $ kubectl logs reloader-6fc54b7755-b2stv | tail -n1 time="2025-06-11T09:09:12Z" level=info msg="Changes detected in 'hoge-staging' of type 'SECRET' in namespace 'A'; updated 'hoge-staging' of type 'Deployment' in namespace 'A'" Reloaderã®ç£èŠå¯Ÿè±¡ã«å€æŽããã£ãéã«ä»äžããŠããâ»Â¹hashå€ã倿ŽååŸã«å€ãã£ãŠããªãäºã確èªã äžèšã«å ããç°åžžç³»çã®æ§ã
ãªãã¿ãŒã³ã®ãã¹ãã宿œããæ¢åã®podã«åœ±é¿ãç¡ãããšã確èªã§ããã®ã§ãç¹ã«äžå®èŠçŽ ã¯ç¡ãå®å¿ããŠãªãªãŒã¹ã§ããŸããã â»Â¹ reloader.reloadStrategy ã§ãã©ãã«hashãèšé²ããããããªã¬ãŒã«ããããéžæãå¯èœã ã¹ã¿ã³ãã€ã«ãããŠã¯ annotations ã䜿çšããŠããã以äžã®ãããªhashå€ãä»äžãããŠããŸããã $ kubectl describe deployment reader-api-staging | grep -iA1 reloaded reloader.stakater.com/last-reloaded-from: {"type":"CONFIGMAP","name":"reader-api-staging","namespace":"A","hash":"stanbytechblognisanjoucbeb27969f21cd937800632c8602f737d","conta... ãŸãšã ãªãªãŒã¹ååŸã§ç¹ã«åé¡ãç¡ãå®å®çšŒåããŠãããæ°ããEKSéçšèª²é¡ã®ãã¡ã®1ã€ã解決ããäºãåºæ¥ãŸããã ããã«éããããŸã ãŸã EKSéçšã®æ¹åç¹ã¯å€ãã®ã§ãç¶ç¶çãªæ¹åãç¶ããŠãããŸãã æåŸãŸã§ã芧ãã ãããããããšãããããŸããã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ã¯ããã« ããã«ã¡ã¯ãã¯ãªãªãã£éšã®äžäžãšç³ããŸãã ããªãã¯æåŸã«ãã€ãæ±äººãæ€çŽ¢ããŸãããïŒ ãã®æãæãéãã®çµæã¯è¡šç€ºãããã§ããããã ããªããéããªããšæããããšã¯ãããŸããã§ãããïŒ ãããªããªããéãããèŠã€ããŠãæ¹åããŠããããããç§ã®ä»äºãSearch QualityïŒSQïŒã§ãã ãããããã®è·çš®ã«ã¯1ã€å€§ããªççŸããããŸãã æ€çŽ¢ãæ¹åããã®ãä»äºãªã®ã«ãç§ãã¡ã¯ã³ãŒããæžããŸããã æ€çŽ¢ãšã³ãžã³ãéçºããããã§ããUIãèšèšããããã§ããªãã®ã§ãã ä»åã¯ããã㪠æè¡ã®é£ã«ããããã©ãéçºè
ã§ã¯ãªãè·çš® ãšããŠã®SQã®ã玹ä»ãšãããã«èŸŒããŠããæã
ã®èªããèè€ã«ã€ããŠæžããŠãããŸãã SQã¯äœãããŠããã®ã SQã¯ãæè¯ã®æ€çŽ¢äœéšãéèŠããæ€çŽ¢å質ãä¿ã€ããã®è©äŸ¡ã»æ¹åã»ææ¡ãè¡ããŸãã æã
ãæ
ã£ãŠããã®ã¯ãå
·äœçã«ã¯ä»¥äžã®ãããªæ¥åã«ãªããŸãã æ€çŽ¢åè³ªææšãšå®æ§ç芳ç¹ã«åºã¥ããA/Bãã¹ãã®è©äŸ¡åæ æ€çŽ¢ã©ã³ãã³ã°ãUIçã®ããŸããŸãªæ¹åæœçãã©ã®ãããªåœ±é¿ããããããããå®éãšå®æ§ã®äž¡é¢ããæ€èšŒãæ€çŽ¢åè³ªææšããã®å®éçãªåæãšãå®éã«è¿ã£ãŠããæ€çŽ¢çµæãè©äŸ¡ã¹ã±ãŒã«ã«åŸã£ãŠ1ä»¶1件人ã®ç®ã§è©äŸ¡ãã宿§è©äŸ¡ã®äºè»žã§ç¢ºèªã æ€çŽ¢èŸæžã®äœæã»éçš æ±äººåŽã®è¡šçŸãšãŠãŒã¶ãŒã®æ€çŽ¢èªå¥ã®ãºã¬ãåããããã®èŸæžæŽåãåé³ç°çŸ©èªãå矩èªçãæå³ãè¿ããã®ãé©åã«ããããããããšã§ãæ€çŽ¢çµæã®ç¶²çŸ
æ§ãšé©åæ§ãé«ããã æ€çŽ¢å質åäžã«ãŸã€ãããªãã¬ãŒã·ã§ã³æ¥å æ©èœã®ç²ŸåºŠè©äŸ¡ãå€§èŠæš¡ãªç«¶å調æ»ãããŒã¿ã¯ã¬ã³ãžã³ã°ãªã©ãæ³¥èãèŠãããéèŠãªæ¥ã
ã®å°éãªèª¿æ»ãã¡ã³ããã³ã¹ãSQã®ç¯çãšãªãã éçºè·ã§ãäŒç»è·ã§ããªããã®ç«å Žã ããããããæ€çŽ¢äœéšããã®ãã®ã«å°å¿µã§ããââããããã®ä»äºã®äŸ¡å€ã ãšæããŠããŸãã äœããã£ãŠããŠâããæ€çŽ¢âãšèšããã®ãïŒ SQãšããè·çš®ã§ä»äºã«æºãã£ãŠãããšããã³ãã³ãããæ€çŽ¢ãšã¯ãªã«ãïŒããšããåãã«åãåããŸãã æ€çŽ¢ãšã³ãžã³ã®äžçã§ã¯ãnDCGïŒNormalized Discounted Cumulative GainïŒãMRRïŒMean Reciprocal RankïŒã®ãããªã©ã³ãã³ã°è©äŸ¡ææšããA/Bãã¹ãã®åæã§ãè¯ãæªããã倿ããã®ãäžè¬çã§ãããããã¯åœç¶ã倧äºãªå€æææã§ãã ãã ãæã
ã¯ããããææšã«å ããŠã æ€çŽ¢ãããŠãŒã¶ãŒã«ãšã£ãŠè¯ãã£ããã©ããã ãšãããããæœè±¡çã§äž»èгçãªåãã«ãåžžã«åãåã£ãŠããŸãã ãªããªãããããæ€çŽ¢ããšã¯åãªãæ°å€ã®è¯ãæªãã§ã¯ãªããã äœéšãšããŠæå³ã®ããçµæïŒæ±ããŠããä»äºïŒãè¿ã£ãŠãããã©ãã ãã«æ ¹ãããŠããããã§ãã SQã¯ã以äžã«æãããRCFPTSDãã®è»žãç·åçã«èŠãªããããããæ€çŽ¢ããå®çŸ©ããããšè©Šã¿ãŠããŸãã Relevancy â é¢é£æ§ ãŸããæ€çŽ¢äœéšã®æ ¹å¹¹ãšãªãã®ã é¢é£æ§ ã§ãã ãŠãŒã¶ãŒããäºå é±3ããšæ€çŽ¢ãããšãã«ãäžäœã«è¡šç€ºãããã®ã¯ãé±3æ¥å€åã®äºåè·ã®æ±äººãã§ããã¹ãã§ããããã®éã«ãã¢ã«ãã€ãããšã¯æã£ãŠããªãã®ã«ãéçšåœ¢æ
ãã¢ã«ãã€ãã®æ±äººãåæã«å¢ãããããªéå°ãªæšæž¬ãé¿ããã¹ãã§ãããã ãã®äººãæã£ãŠãããªãã£ããããªåºäŒããæŒåºãããã®ãã¹ã¿ã³ãã€ãšãããµãŒãã¹ã§æäŸã§ãã1ã€ã®äŸ¡å€ãšèããŸãããæ€çŽ¢ãšã³ãžã³ãæ±è·è
ã®æå³ãéå°ã«æšæž¬ããŠæ¡åŒµããŠããŸããšããå
¥åããããŒã¯ãŒããšç¡é¢ä¿ãªãã®ãåºãŠããããšããéåæã«ã€ãªãããããŸããã ã ããããã å
¥åãããã¯ãšãªã«å¿ å®ã§ããããš ãéèŠããŠããŸãã Comprehensiveness â ç¶²çŸ
æ§ äžæ¹ã§ããå¿ å®ã§ãããããšã ããåªå
ãããããšããããä»¶æ°ã極端ã«å°ãªããªãããšããããŸããããã§ç»å Žããã®ã ç¶²çŸ
æ§ ãšããèŠç¹ã§ãã ããšãã°ããªã¢ãŒãã¯ãŒã¯ããšæ€çŽ¢ãããå Žåããå®å
šåšå®
ããããã¬ã¯ãŒã¯ããªã©ã®è¡šçŸããã«å¯Ÿå¿ã§ããŠããªããšãæ±è·è
ã¯æ±ããæ±äººã«åºäŒããçµãã£ãŠããŸããŸãã åºãããŸããæ±äººç¥šãindexãããããã§ãåãããŒãããããšãªã衚瀺ãããã®ããã¹ãã§ãã Freshness â æŽæ°æ§ æ±äººæ
å ±ã¯ æŽæ°æ§ ãåœã§ãããã§ã«åéãçµäºããŠããæ±äººããæ
å ±ãå€ããŸãŸæ®ã£ãŠããæ±äººãåºãŠãããšãããã ãã§æ±è·è
ã®ãã£ãã床åãã¯é«ãŸããŸãã 宿çãªããŒã¿æŽæ°ãæéåãã®å€å®ãæ±äººæ
å ±ã®æäŸå
ãšã®åæç²ŸåºŠââããããå°éãªç©ã¿äžãã§æŽæ°æ§ãæ
ä¿ããããšãéåžžã«å€§äºãªèŠçŽ ã§ãã Presentation â é²èŠ§æ§ æ€çŽ¢å質ã¯çµæã®äžŠã³é ã ãã§ã¯ãªãã çµæã®èŠãæ¹ ã«ã圱é¿ãããŸãã ãã®æ±äººãã©ããªæ¥åå
容ã§ãã©ã®ãšãªã¢ã§ã絊äžã¯ããããªã®ããããããèŠèªæ§ã®é«ãåœ¢ã§æŽç¶ãšäžŠãã§ãããã SQã¯UIã»UXã®å°éå®¶ã§ã¯ãããŸããããæ€çŽ¢çµæã«äžŠã¶æ
å ±ã æ§é çã«è¡šç€ºãããŠããã ãšãã å¿å倿ã«å¿
èŠãªæ
å ±ã ããé©åã«é²åºãããŠããããš ãéèŠããŠããŸãã ããã«ããããŠãŒã¶ãŒãæ±äººãâèªãâã®ã§ã¯ãªããâäžç®ã§ææ¡ã§ããâç¶æ
ã«è¿ã¥ããŠãããŸãã Trust â ä¿¡é Œæ§ æ±äººæ€çŽ¢ã«ã¯ ä¿¡é Œæ§ ãæ¬ ãããŸããã æªãã坿¥å§èªãæ¶ç©ºã®æ±äººãèªå°ç®çã®ç©ºæ±äººââæ®å¿µãªãããäžã®äžã«ã¯ããããâä¿¡é Œãè£åãã³ã³ãã³ãâãååšããŠãããããããæ··ããåŸãŠããŸãããšããããŸãã æ€çŽ¢ãšã¯ã çå®ã«è¿ã¥ãããã®ææ®µ ãã§ãããã¹ãã§ãè·åäžé¢ãããé åãšããŠã¯éãããŠããŸãããSQãšããŠãå®å¿ããŠäœ¿ããæ€çŽ¢äœéšã®ç¶æã«åªããŠããŸãã Speed â 衚瀺é床 æ€çŽ¢äœéšã«ãããäœæå質ã®äžã§ãæå€ã«èŠèœãšãããã¡ãªã®ã é床 ã§ãã æ€çŽ¢ãã¿ã³ãæŒããããšãã³ã³ãæ°ç§ã§ç»é¢ãåãæ¿ããããæ±äººè©³çŽ°ããŒãžãã¯ãªãã¯ããç¬éã«è¡šç€ºãããââããããé床ã®ç©ã¿éããããŠãŒã¶ãŒã®ã¹ãã¬ã¹ãæå°åããŸãã éã«ãã¬ã¹ãã³ã¹ãé
ãã ãã§ãæ€çŽ¢äœéšå
šäœãããã£ããããŠãããã䜿ãã¥ããããšè©äŸ¡ãããŠããŸãã®ã§ãã SQã¯ äœæäžã®åŸ
ã¡æéãæå°éã«ããããš ããæ€çŽ¢å質ã®äžç°ãšããŠæããŠããŸãã Diversity â 倿§æ§ ãã®è·çš®ã§æ€çŽ¢ããŠããããã§ã¯ãªãã®ã«ãæ€çŽ¢çµæã®äžäœã«åããããªè·çš®ã®æ±äººã䞊ã³ãããŠããªããïŒ ç¹å®ã®ãã©ã³ãããšãªã¢ã ãã匷調ãããŠããªããïŒ SQã¯ãé¢é£ããéžæè¢ãéäžè¶³ãªãå±ããã ãã§ãªãããŠãŒã¶ãŒã®èŠéãçããªãããšãéèŠã ãšèããŠããŸãã ãã®ããã«ã è·çš®ã»éçšåœ¢æ
ã»å€åå°çã®å€æ§æ§ ã«ãç®ãé
ã£ãŠããŸãã âäœéšâãšããŠã®æ€çŽ¢å質ããã©ãæããã ãããŸã§ç޹ä»ããŠããåèŠçŽ ã¯ãããããçŽæ¥çãªæ°å€ã§è¡šãã«ãããããããã«è°è«ãé£ããåŽé¢ããããŸãã ãŸããŠããSQã¯ã¹ã¿ã³ãã€ã®ãããã¯ãäœéšå
šäœã代衚ããç«å Žã§ããããŸããã ã§ãããæ€çŽ¢ãšããæ©èœã«ãããŠãã ãŠãŒã¶ãŒãä»äºã«åºäŒããŸã§ã®æ©æž¡ã ããæ
ã£ãŠãããšããèªèŠããããŸãã ãã®æ©ãã厩ããŠããªããïŒ çãããŠéããªã人ãããªããïŒ èª°ãã«ãšã£ãŠæãéã«ãªã£ãŠããªããïŒ ããããåãããèªåãã¡ãªãã®âãã®ããâã§èãç¶ããââããããç§ãã¡SQã®åœ¹å²ãªã®ã ãšæã£ãŠããŸãã SQãšããè·çš®ã¯çããïŒ ããŠãããããã¯SQãšããè·çš®ã«ã€ããŠæžããŠãããŸãã æ€çŽ¢ãµãŒãã¹ã®å質管çãšãããšãGoogleãLINEã€ããŒã®ãããªå€§èŠæš¡ãã©ãããã©ãŒã ã«ããååšããªãå°è±¡ãæã€ãããããŸããã å®éãæ€çŽ¢äœéšã®è³ªã«ãã©ãŒã«ã¹ããå°ä»»è·ã¯ãå
šäžçãèŠæž¡ããŠããããµãããã®ã§ã¯ãªãããã§ããããããããã®å€ãã¯ãæ€çŽ¢ãã®ãã®ãäºæ¥ã®ã³ã¢ã§ããããã€ãªãœãŒã¹ã«äœè£ã®ããè¶
å€§äŒæ¥ã§ãã ãããªäžã§ãã¹ã¿ã³ãã€ã®ãã㪠æ¯èŒçå°èŠæš¡ãªäºæ¥äŒç€Ÿããæ€çŽ¢å質ã ãã«ç¹åããå°ä»»è·ãèšããŠãã ã®ã¯ãããæå³ãŠããŒã¯ã§ãã éçºãæ
ãããçŽæ¥ãããã¯ãæ©èœãçã¿åºãããã§ããªãè·çš®ã«å¯ŸããŠããªãœãŒã¹ãå²ãããšã¯ãçæçãªèŠç¹ã§ã¯éåçã«èŠããã§ãããã ä»®ã«çœ®ããšããŠãå°ãªããšãä»ã®ãã§ãŒãºã§ã¯ãªãã æ®éãªãã°ã1ã€ã§ãæ©èœãéçºããããã«ããšã³ãžãã¢ã®æ°ãå¢ããçµå¶å€æãããã¯ãã§ãã ãããã¹ã¿ã³ãã€ã¯ãããŠããã®è·çš®ãé
眮ããŠããŸãã ããã¯ãã æ±äººæ€çŽ¢äœéšã®è³ª ã ãããããµãŒãã¹ã®çåœç·ã§ãã ãšãã匷ãå²åŠããããããšç§ã¯æã£ãŠããŸãã ãæ€çŽ¢çµæãæ£ç¢ºã§ããã ãæå³ã«æ²¿ã£ããã®ãè¿ã£ãŠããã ââããã¯ãã©ãã ãè¯ãããªUIãæ©èœããã£ãŠãæ¬ ããŠã¯ãªããªãåå°ã§ãã ãããŠãã®åå°ããæ°åã®å€åŽã«ããâèæèŠã®éåæâãŸã§å«ããŠäžå¯§ã«ä¿ã€ããã«ãSQãšããããŒã«ãååšããŠããŸãã ããŒã«ã¢ãã«ã®äžåšãšãã£ãªã¢ã®èŠããªã SQã®æå€ãªæ©ã¿ãšããŠã¯ã æç¢ºãªããŒã«ã¢ãã«ãã»ãšãã©ããªãããš ãæããããŸãã å
è¿°ããããã«ãSQã¯äžã®äžã«ãããµããè·çš®ã§ã¯ãããŸããã è¿ãããã®ãæãããšãããªãäžéäžè¬çã«ã¯ããŒã¿ãµã€ãšã³ãã£ã¹ãããªãµãŒãã£ãŒã§ããããããšãŠSQã®çµéšããã£ãããã®ãŸãŸå€ã«æã£ãŠããã®ãé£ããã®ã§ããã ããããâŠâŠ äœããã£ãŠãåªç§ããšãããã®ãïŒ ã©ããªã¹ãã«ãæ·±ããŠããã°ããã®ãïŒ ã©ããªãã£ãªã¢ãã¹ãããããã®ãïŒ ããããææ§ã§ãèªåã§èªåã®ä»äºã®äŸ¡å€ãå®çŸ©ããªããã°ãªããªãç¬éãå€ããããŸãã SQã¯ãŸã âæªå®çŸ©ã®è·çš®âãªã®ã§ãã ããã¯å€ç¬ã§ããããŸãããåæã«ãèªåã§åœ¢ãäœããããšããèªç±ã§ããããŸãã ã奜ãåæã«èšã£ãŠããã ããã«èŠããŠããŸããšãããã äžæ¹ã§ãéçºãããªãç«å ŽãšããŠããšã³ãžãã¢ããã©ã³ããŒãšæ¥ããäžã§æããâè·é¢âã¯ãããã«ãããŸãã ããšãã°ãæ€çŽ¢äœéšãæ¹åããããã®ãææ¡ããŠãã ãå®è£
ã³ã¹ãéããªãïŒã ãå
šäœã®åªå
床çã«ä»ã§ã¯ãªãããããªãïŒã ãããã£ãŠæ¬åœã«æå³ããã®ïŒã ãšããåå¿ãè¿ã£ãŠããããšããããŸãã ãã¡ããè°è«ã¯å¥å
šãªããšã§ãã ãããã èªåãã¡ãåµãåºããŠããªãåãçºèšã軜ãåãåãããŠããŸã æèŠãæãšããŠæ±ãããšããããŸãã ãçŸå Žã®èŠåŽããããã奜ãåæã«èšã£ãŠããã ãã ãèªåã§å®è£
ããªãã®ã«ããã®ã¿ã€ãã³ã°ã§ãããèšãã®ãã ââããæããããªã¹ã¯ãåžžã«æããªãããããã§ãææ¡ãç¶ããå Žé¢ããããŸãã ãã®ç«å Žã«ã¯ã ä¿¡é Œãããªããã°ãªããªãããã©ãä¿¡é Œãç¯ãããã® ã èŠããææ ã ãåŸã«ãã ãšããççŸãåžžã«ã€ããŸãšããŸãã ããã§ããèšããªãããããªãããšããã éçºãããŠããªããŠããæ°å€ã«è¡šããªããŠããããããæ°ã«ãªãããããã¯ãŠãŒã¶ãŒäœéšãšããŠéãæ°ãããããšããçŽæã倧äºã«ãããã ãããŠããã仮説ã«å€ããæ€èšŒã§ããåœ¢ã«æã¡èŸŒã¿ã誰ããšååããŠå®éã®æ¹åã«çµã³ã€ããŠããââ ãã®ããã»ã¹ããããSQãšããè·çš®ã®æ¬è³ª ãªã®ã ãšèããŸãã æã«ã¯è³ã®çãããšãèšããªããã°ãªããªãããšãã«ã¯å«ãã圹ã«ãªãããšãããã ã§ããããããŠãŒã¶ãŒäœéšã®ããã«ãªãã®ã§ããã°ãæã
ã¯çãããŠãã®åœ¹å²ãåŒãåããããšæã£ãŠããŸãã ãããã« SQãšããè·çš®ã¯ãæè¡ãšéæè¡ã®âããã âã«ç«ã£ãŠããŸãã ãšã³ãžãã¢ã®ããã«ã³ãŒããæžãããPdMã®ããã«ããŒãããããæ¡ãããã§ããªãã ã ãããããèŠãããã®ããããŸãã ã ãããããèšããããšããããŸãã ãã®æªå®çŸ©ãªè·çš®ã§ãæ¥ã
æ©ã¿ãªããåããŠãã人éãããã«ããŸãã ãããããªãã®ããŒã ã«ããã³ãŒããæžããªãããã©ãäœéšã®è³ªãå®ã£ãŠãããŠãã人ãããããªãããã®äººã®ååšã«å°ãã ãæããå·¡ãããŠãããããå¬ããã§ãã ãããŠããããã®èšäºãèªãã§ãããããç«å Žã§æ€çŽ¢äœéšã«åãåã£ãŠã¿ããããšæããŠããã ãããªãââ ã¹ã¿ã³ãã€ã§ã¯ã SQãšããå°ãå€ãã£ãè·çš®ã«ææŠããŠã¿ãã仲éãåéããŠããŸãã æªå®çŸ©ã ããããããŸã ãŸã 圢ã«ã§ããããšããããããããŸãããã²äžç·ã«ãæ€çŽ¢ãšããäœéšãè²ãŠãŠãããŸãããã âSQãæ°ã«ãªã£ãæ¹ã¯ãã¡ããã©ãã ãµãŒãã¯ãªãªãã£/Search Quality(SQ) ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ãããã¯ãéšUserGã®çæ¬ã§ãã 2025幎3æ24æ¥ã28æ¥ã§èªå®ã¹ã¯ã©ã ãã¹ã¿ãŒïŒCSM®ïŒç ä¿®ãåè¬ããŠããŸããïŒ ãã®ç ä¿®ã¯ãšãŠãåŠã³ãå€ãææçŸ©ã§ãã£ãã®ã§ãæ¯ãè¿ããå
ŒããŠç ä¿®ã§åŠãã ããšã玹ä»ã§ããã°ãšæããŸãã èªå®ã¹ã¯ã©ã ãã¹ã¿ãŒïŒCSM®ïŒç ä¿®ãšã¯ ä»åç§ãåè¬ãã èªå®ã¹ã¯ã©ã ãã¹ã¿ãŒïŒCSM®ïŒç ä¿® ã¯æ ªåŒäŒç€ŸOdd-e Japanãäž»å¬ããŠãããã®ã§ããã ãã®ç ä¿®ã®åè¬ç¶æ³ã«å¿ããŠé©æ§ãèªããããå Žåã«èªå®è©Šéšã®åéšè³æ Œãäžãããããã®è©Šéšã«åæ Œãããš èªå®ã¹ã¯ã©ã ãã¹ã¿ãŒ ã®èªå®èšŒãçºè¡ãããŸãã ç§ã¯5æ¥éãåèš30æéã®ãªã³ã©ã€ã³éå¬ã®ç ä¿®ã«åå ããŸããã ç ä¿®ã®å
容ã¯ã忥ã«è¬åž«ã®æ¹ãããé¡ãåºããããã®ãé¡ã«å¯ŸããŠåå è
å
šå¡ã§è°è«ãããšãããã®ã§ãã ãã®è°è«ãé²ããäžã§ã¹ã¯ã©ã ãã¹ã¿ãŒãšããŠå¿
èŠãªèãæ¹ã»æ¯ãèããæ±ããããã®ã§ãããå
·äœçãªäºè±¡ãå
ã«ã¹ã¯ã©ã ã«ã€ããŠåŠã¶ããšãã§ããŸãã ç§ã¯æ®æ®µ DeveloperãšããŠã¹ã¯ã©ã ã«åå ããŠããããã®ç ä¿®ãéããŠã®ã¹ã¯ã©ã ãã¹ã¿ãŒã®èãæ¹ã¯ãã¡ãããã¹ã¯ã©ã ã¡ã³ããŒã®äžå¡ãšããŠã¹ã¯ã©ã ã®ç念ãå®è·µçã«åŠã¶ããšãã§ããã®ããšãŠã貎éãªçµéšã ã£ããªãšæããŸãã ç ä¿®ãåè¬ããããšæã£ããã£ãã ç§éã®ããŒã ã§ã¯ã¹ã¯ã©ã ãçšããŠéçºããŠããŸãããã ç§èªèº«ã¹ã¯ã©ã ãšãããã®ãæ·±ãçè§£ããªããŸãŸæ¥ã
ã®éçºãè¡ã£ãŠããŸããã ãããšãããŒã å
ã®æ¯ãè¿ãã§ãã¹ã¯ã©ã ã§è¡ã£ãŠããæŽ»åãããå°ã广çã«ã§ããã®ã§ã¯ãªããïŒãšçåã«æã£ããã®ã®ããã®ãšãã©ã®ããã«æ¹åããã®ãé©åãªã®ãããããŸããã§ããã ãã®ããç ä¿®ã®äžã§ã¹ã¯ã©ã ã®çè«ããå®è·µãŸã§äœéšããããšã§ãã¹ã¯ã©ã ãããå°ãäžæãæŽ»çšã§ããã®ã§ã¯ããšæãåè¬ããŸããã ç ä¿®ã§åŠãã ããš ä»åã®ç ä¿®ã§ç¹ã«ç§ãåŠã³ã«ãªã£ããšèããããšã¯ä»¥äžã®ãããªäºé
ã§ããã ç ä¿®ã§åŠãã ããšãªã¹ã ã¹ã¯ã©ã ã¯çŸç¶ãææ¡ããããã®ãã¬ãŒã ã¯ãŒã¯ ã¹ã¯ã©ã ã¯èšç»é§åã§ãããæŽ»åã¯åæã§ããç¶æ
ã§ãªããã°ãªããªã èšç»ã¯ç¶¿å¯ãã€è€æ°ç«ãŠãããšãå®ç³ ã¬ã³ãžãæèããèœåéçº ã¹ã¯ã©ã ã¯ååäŒããã²ãŒã ã¹ã¯ã©ã ã¯çŸç¶ãææ¡ããããã®ãã¬ãŒã ã¯ãŒã¯ ç ä¿®ãåããåã¯ã¹ã¯ã©ã ã¯ããšããããåã«é²ããªããæ¥ã
æ¹åããŠãããã¬ãŒã ã¯ãŒã¯ã ãšæã蟌ãã§ããŸããããã ã¹ã¯ã©ã ã«ãããç®çã¯ãçŸç¶ãææ¡ããããšããããšã«ãããŸãã ã¹ã¯ã©ã ã¬ã€ã ã«ã以äžã®èšèŒãããéããã¹ã¯ã©ã ã§ã¯çŸç¶ãææ¡ããããã«ïŒã€ã®ã€ãã³ããèšããããŠããŠããã®äžã§åé¡ãå¯èŠåã衚é¢åãããåé¡ã«1ã€ãã€åãåã£ãŠé©å¿ããããšããæŽ»åãéèŠã«ãªã£ãŠããŸãã ã¹ã¯ã©ã ã§ã¯ãæ€æ»ãšé©å¿ã®ããã® 4 ã€ã®æ£åŒãªã€ãã³ããçµã¿åãããŠãããããããå
å« ããã€ãã³ãã¯ãã¹ããªã³ãããšåŒã°ããããããã®ã€ãã³ããæ©èœããã®ã¯ãçµéšäž»çŸ©ã®ã¹ ã¯ã©ã ã®äžæ¬æ±ãéææ§ããæ€æ»ããé©å¿ããå®çŸããŠããããã§ããã ã¹ã¯ã©ã ãšã¯ãã¹ã¯ã©ã ã®äŸ¡å€ãçè§£ããŠçŸç¶ãææ¡ããããã«åªããããšãéèŠã§ãã¹ã¯ã©ã ãå°å
¥ãããããšèšã£ãŠèªåçã«äœçãã®åé¡ãæ¹åãããããšã¯ãªããšããããšã§ãã ã¹ã¯ã©ã ã¯èšç»é§åã§ãããæŽ»åã¯åæã§ããç¶æ
ã§ãªããã°ãªããªã ãŸãã¹ã¯ã©ã ã¯èšç»é§åã§èããå¿
èŠããããŸãã äœãããã®æŽ»åãããšãããããããäžæŠãã®ããã«å§ããŠããŸããšããã®æŽ»åãåæãã§ãããã¹ã¯ã©ã ã«ãããæ€æ»ãé©å¿ãã§ããªããªã£ãŠããŸããŸãã ãšããããè¡åã«ç§»ããšããããšã¯ã¹ã¯ã©ã ã«åããããšã§ããã®è¡åã«ç§»ãåã«äœããã®çããæã£ãŠããå¿
èŠããããŸãããã®çãã¯å¿
ãããç®çã§ããå¿
èŠã¯ãªãããã§ãã ç®çããªãããšã¯åæã§ããªãããšãšå矩ã§ã¯ãªããç®çã¯ãªããšãçããæã£ãŠããã°ãã®çãã«å¯ŸããŠåæã§ããŸãã äŸãã°ãããŒã å
ã§ã®é¢ä¿æ§ã®æ§ç¯ã»ç¶ææŽ»åãšããŠãéè«ã®æ©äŒãèšãããšããæŽ»åããããšããŸãããã®å ŽåäœçãããŒã å
ã§åæãããªã©ã®ç®çã¯ãªãã«ããŠãã芪çŠãæ·±ãããå®å¿æã»ä¿¡é Œæãéžæãããªã©ã®çããæã€ããšãã§ããŸãããã®ãããªçããæã£ãп޻åã«ç§»ãããšã§ã掻ååŸæ¬åœã«åããŒã ã¡ã³ããŒã®èŠªçŠã¯æ·±ãŸã£ãã®ãããã£ãšãã®æ©äŒãå¢ããã¹ããªã®ãããŸãããå°ãéãæŽ»åãšããŠæ¹åãã¹ããªã®ãããªã©åæããããšãã§ããŸãã ããã§ç ä¿®åã®ç§ã®ã¹ã¯ã©ã ã«ã€ããŠã®çè§£ã§ãã£ãããšããããåã«é²ããªããæ¥ã
æ¹åããŠãããã¬ãŒã ã¯ãŒã¯ãã¯æ¹ããŠééã£ãŠãããšèªèããããšãã§ããŸããã ãã åã«ããã®ã§ã¯ãªããäœãããã®æŽ»åãããåã«èšç»ãç«ãŠãŠãã®æŽ»åãåæã§ããç¶æ
ã«ããŠãããããããçŸç¶ãææ¡ãããããšã«ç¹ãããšããããšã ãšçè§£ããŸããã èšç»ã¯ç¶¿å¯ãã€è€æ°ç«ãŠãããšãå®ç³ å
ã»ã©ã¹ã¯ã©ã ã¯èšç»é§åãšããã話ãããŸããã ã¹ã¯ã©ã ã¯èšç»é§åã§ãããããäœãããã®æŽ»åãããåã«å¿
ãèšç»ãç«ãŠãŠãèšç»éãæŽ»åãé²ããå¿
èŠããããŸãã ãªãèšç»éãã«é²ããå¿
èŠãããã®ããšãããšã以äžã®2ç¹ããããããŸãã ã¹ã¯ã©ã ããŒã å
šäœã§å
±éçè§£ãæã€ããšãã§ãã => ã¹ã¯ã©ã ã®çè«ã«ãããéææ§ããå®çŸ äžç¢ºå®æ§ã®é«ãç¶æ³ã§ãçå®ã«äŸ¡å€ãçã¿åºãããšãã§ãã => å®å®çãªã€ã³ã¯ãªã¡ã³ããå®çŸ ã€ãŸãèšç»éãã«é²ããããšã¯ãå
±éçè§£ãæã€ããšã§éææ§ãäœçŸãã€ã€ãã€ã³ã¯ãªã¡ã³ããå®å®çã«åºãããšã«ç¹ãããŸãã ãããçŸå®äžçã§ã¯èšç»éãã«ç©äºãé²ããšã¯éããªããšæããŸãããã®äžã§ã¹ã¯ã©ã ã§ã¯èšç»ã倿Žããããšãªããèšç»éãã«é²ããå¿
èŠããããŸãã ããã§éèŠãªã®ã¯ã èšç»ã¯1ã€ã§ã¯ãªããè€æ°ç«ãŠãã¹ã ã ãšããããšã§ãã ãã®ããèšç»ãç«ãŠã段éã§ããããå¯èœæ§ãèŠéãè€æ°ã®ãµããã©ã³ãçšæããŠæºåããŠããããšãéèŠã«ãªã£ãŠããŸãã äºãçšæããŠããããµããã©ã³ã«å€æŽããããšã¯èšç»ã®å€æŽã§ã¯ãªããèšç»éãã§ãããšæããããšãã§ããŸãã ãªã®ã§ãã¹ã¯ã©ã ã§ã¯èšç»ã¯ç¶¿å¯ãã€è€æ°ç«ãŠããšããããšãæèããå¿
èŠããããŸãã å®éã«ã¹ã¯ã©ã ãéçšããäžã§ãã¹ããªã³ãã®éäžã§èšç»ãç«ãŠçŽãããšãNGã«ãªããŸãããã èšç»ã¯åžžã«çµ¶å¯Ÿçãªãã®ã§ã¯ãªãã®ã§ãã¹ããªã³ãã¬ãã¥ãŒãªã©ãéããŠãã®åŠ¥åœæ§ãæ€èšŒããé©å¿ã«ç¹ããŠè¡ãå¿
èŠããããŸãã ã¬ã³ãžãæèããèœåéçº ã¹ã¯ã©ã ãã¹ã¿ãŒã¯èœåéçºãæ¯æŽããäžã§ããŒã ãåã¡ã³ããŒã«ãã£ãã¬ã³ãžãæèããå¿
èŠããããŸãã ããŒã ã«å¯ŸããŠé«ãç®æšãèšå®ããŠããã®ããã®æŽ»åãè¡ã£ãŠãããŒã ãå®å®ããã¢ãŠãããããåºãããšã¯éããŸããã ãã®ããããŒã ç¶æ³ã«å¿ããŠæé©ãªã¬ã³ãžã«åãããããªæŽ»åã«å°ãå¿
èŠããããŸãã èªåèªèº«ãããŒã ã«å¯ŸããŠå®æã«ãããã§ããŠãªãã®ã¯è¯ããªãã®ã§ã¯ãªããããšçåã«æã€ããšããã£ãã®ã§ãããæ¬åœã«ãããçŸç¶ã®ããŒã ã«ãšã£ãŠå¿
èŠãªããšããæèããå¿
èŠãããã®ã ãªãšæããŸããã ãŸãèœåéçºã«ããã£ãŠã¯ãæŽ»åææšã«çç®ããããšãéèŠã ãšç¥ããŸããã æŽ»åææšãšã¯ãçŽæ¥ææã«çµã³ã€ããã®ã§ã¯ãªããã®ã®ææã«è¿ã¥ãããã«éèŠãšãªãæ¥ã
ã®åãçµã¿ã§ãã äŸãã°ãéçéžæãããŒã ã©ã³ãæã€ããã«ã¯çãã¬ãå¿
èŠã§ãããçãã¬ããããããšãã£ãŠããŒã ã©ã³ãå¿
ãæãŠãããã«ãªããšã¯éããŸããããããããŒã ã©ã³ãæãŠãããã«ãªãããã«ã¯å¿
èŠãªåãçµã¿ã§ãããããæšé²ããŠããã®ãã¹ã¯ã©ã ãã¹ã¿ãŒã®è
ã®èŠãæã§ãã å®å®ããããããšãã£ãŠçµæãåºãããã§ã¯ãªãããããã§ãããããããŠãã®æŽ»åã®åæãããšããããšã培åºããå¿
èŠããããŸãã æŽ»åã«å¯ŸããŠè©äŸ¡ã§ããææšãäºãå®ããŠãããŠã掻ååŸå¿
ãåæãããããã§ãã¹ã¯ã©ã ã¯èšç»é§åã§ããããšãåãããŸããã ã¹ã¯ã©ã ã¯ååäŒããã²ãŒã ã¹ã¯ã©ã ãè¡ãäžã§å¿
èŠãªFBåã®1ã€ã«ãç¹°ãè¿ãäŒããããšãããã®ããããŸãã ã以åã«ãèšã£ãæ°ããããã§ãããããããã«æžããŠãããŸãããããªã©1åã§çè§£ããŠãããããšããåæãªæã蟌ã¿ã§çºèšããŠããŸã£ãããšããããããããŸããã ãã 人ã¯ããããç°ãªãèæ¯ãæã¡ãæ
å ±ãåãåãã¿ã€ãã³ã°ãç¶æ³ãç°ãªãããšã¯åœããåã§ãäžåºŠèããã ãã§å
šãŠãæ£ç¢ºã«çè§£ã§ãããšã¯éããŸããã ã¹ã¯ã©ã ã§ã¯æ
å ±ãäŒããåŽã¯100åã§ã1000åã§ãç¹°ãè¿ãå¿
èŠããããŸãããã®å§¿å¢ããã Scrum Valuesã«ãããå°æ¬ããšãªããã¹ã¯ã©ã ã®äŸ¡å€ãæ ¹ä»ãã匷ãããŒã ã«è¿ã¥ãã®ããªãšæããŸããã ãŸãšã ä»ååè¬ããèªå®ã¹ã¯ã©ã ãã¹ã¿ãŒç ä¿®ã¯ãæ£çŽããªãããŒããªãã®ã§ããã ç ä¿®ã®äžã§æ¥ã
ã¹ã¯ã©ã ãã¹ã¿ãŒã®èãæ¹ã»æ¯ãèããåŠã³ãåŠãã ããšã¯å¿ å®ã«åçŸããããšãæ±ããããŸãã ãã ããªãè² è·ãé«ãç ä¿®ã§ã¯ãã£ããã®ã®ãå®è·µçã«ã¹ã¯ã©ã ã®äŸ¡å€ã«è§Šããããšã§ããè§£å床ãé«ãç¶æ
ã§åŠã¶ããšãã§ããã®ã§éåžžã«è²Žéãªçµéšã ã£ããªãšæããŸãã åŠãã ããšãšããŠã¯ä»å玹ä»ããå
容以å€ã«ãããªãå€ãã®ããšããã£ãã®ã§ãä»åŸäžæãããŒã ã«éå
ããŠãããã°ãšæããŸãã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ã¯ããã« ããã«ã¡ã¯ãã¹ã¿ã³ãã€ã§ãããã¯ãéçºãããŠããèå·»ã§ãã ã¹ã¿ã³ãã€ã®ããã¯ããã°ã§ã¯ãæ¥ã
ã®æè¡çãªææŠãåŠã³ãçºä¿¡ããŠããŸããä»åã¯å°ãè¶£åãå€ããŠãå
æ¥å
¬éããèšäºãAI Co-PilotãšäœãïŒ1200ä»¶ã®SQLæžãæããä¹ãè¶ãã瀟å
ããŒã«éçºç§è©±ããã AIã¢ã·ã¹ã¿ã³ãïŒæ¬èšäºã§ã¯äž»ã«ãã£ããã€ã³ã¿ãŒãã§ãŒã¹ã®Geminiãšããšãã£ã¿äžã®GitHub Copilotã®äž¡æ¹ãæããŸãïŒãšã©ã®ããã«ååããŠå·çããã®ã ããã®ããã»ã¹ãšåŠã³ã«ã€ããŠã玹ä»ããŸãã ãã®èšäºã®äž»ãªç®çã¯ãããã¯ããã°å·çã®ã³ã¹ããåæžããæ
å ±çºä¿¡ã®ããŒãã«ãäžããããšã§ããAIãæŽ»çšããããšã§ãããå€ãã®æ¹ãæ°è»œã«æ
å ±çºä¿¡ã§ããããã«ãªãã®ã§ã¯ããšããæåŸ
ããããŸããã ãã®èšäºã¯ã以äžã®ãããªæ¹ã«ç¹ã«ããããã§ãã AI/LLMãæŽ»çšããã³ã³ãã³ãäœæãã©ã€ãã£ã³ã°å¹çåã«é¢å¿ã®ããæ¹ ããã¯ããã°ã®éå¶ãå·çããã»ã¹æ¹åã«èå³ãããæ¹ AIã¢ã·ã¹ã¿ã³ããšã®å
·äœçãªååããã»ã¹ãããã®ã¡ãªããã»ãã¡ãªãããç¥ãããæ¹ ããã¯ããã°å·çã®äžè¬çãªèª²é¡ïŒãšAIãžã®æåŸ
ïŒ ããã¯ããã°ãæžãããšããã®ã¯æå€ãšå€§å€ãªäœæ¥ã§ãã æéã®ç¢ºä¿: éåžžæ¥åãšäžŠè¡ããŠããŸãšãŸã£ãå·çæéã確ä¿ããã®ãé£ããã æ§æå: äŒãããããšã¯ãã£ãŠããèªè
ã«ãããããããè«ççãªæµãã§æ§æããã®ãé£ããã 衚çŸå: æè¡çãªæ£ç¢ºããä¿ã¡ã€ã€ãå¹³æã§èªã¿ãããæç« ã«ããã®ãé£ããã æšæ²ã»ã¬ãã¥ãŒ: 客芳çãªèŠç¹ã§ã®æšæ²ããã¬ãã¥ãŒã«ååãªæéãå²ãã®ãé£ããã ããŒã³ïŒãããŒ: ããã°å
šäœã®é°å²æ°ãæäœãçµ±äžããã®ãé£ããã ä»åãAIã¢ã·ã¹ã¿ã³ããæŽ»çšããããšã§ããããã®èª²é¡ãç¹ã«æéçãªã³ã¹ããæ§æã»è¡šçŸã«é¢ããéšåãå¹çåã§ããã®ã§ã¯ãªãããšèããŸããã AIãšã®èšäºå·çïŒå®è·µã¯ãŒã¯ãã㌠å®éã«ç§ãšAIïŒäž»ã«ãã£ããã®Geminiãšãšãã£ã¿ã®CopilotïŒãèšäºã宿ããããŸã§ã«è¡ã£ãããã»ã¹ãããã§ãŒãºããšã«ç޹ä»ããŸããåãã§ãŒãºã§ã®å®éã®ããåãïŒããã³ããïŒã亀ããªããèŠãŠãããŸãããã ãã§ãŒãº1ïŒã³ã³ããã¹ãã®ã€ã³ããã (Geminiãž) ç®ç: AIã«èšäºã®ããŒãïŒSQL ConverteréçºïŒãèæ¯ïŒãªãäœã£ããïŒãæè¡è©³çްïŒã©ãäœã£ããïŒããããŠæã
ã®ããã¯ããã°ãæã€åºæã®ããŒã³ïŒãããŒãçè§£ããŠãããããšã§ãã å®è·µå
容: ãŸãã¯ãã£ããã€ã³ã¿ãŒãã§ãŒã¹ïŒGeminiïŒã«å¯ŸããŠãããããèšäºãæžãããããšããæå³ãäŒããé¢é£æ
å ±ãæ®µéçã«æäŸããŸããã æåã®ããã³ãã (Geminiãž): èªç€Ÿã®ããã¯ããã°ãå·çãããã ãŸãã¯èšäºãæäŸããã®ã§ããã³ããã®ã€ã³ããããããŠãã ããã [ ãã³ããåŠç¿çšã®æ¢åèšäºãã¡ã€ã«ãã¢ããããŒã ] â²Geminiã«æåã®æç€ºãšé¢é£ãã¡ã€ã«ãæäŸããŠãããã£ããç»é¢ ãã®åŸãåæ§ã«ãããžã§ã¯ãã®èæ¯è³æïŒPDFïŒãSQL ConverterããŒã«ã®READMEããœãŒã¹ã³ãŒããªã©ãé æ¬¡æäŸããAIã«å¿
èŠãªæ
å ±ãã€ã³ããããããŸããã 远å ã®ã³ã³ããã¹ãæå
¥ããã³ãã (Geminiãž): > 次ã«èšäºã管çããã¬ããžããªã®READMEãæäŸããã®ã§èªã¿èŸŒãã§ãã ããã > 次ã«ä»åäœæããã¢ããªã±ãŒã·ã§ã³ã«ã€ããŠã®èª¬æè³æãæ·»ä»ããã®ã§èªã¿èŸŒãã§ãã ããã > 次ã«ä»åäœæããã¢ããªã±ãŒã·ã§ã³ã®äž»èŠãã¡ã€ã«ãæ·»ä»ããã®ã§èªã¿èŸŒãã§ãã ããã 課é¡ãšå¯Ÿç: AIã¯ãWebäžã®URLãçŽæ¥è§£éããããšãã瀟å€ç§æ
å ±ãå«ãå¯èœæ§ã®ããããã¥ã¡ã³ããæ±ãããšãèŠæãšããå ŽåããããŸãããã®ãããå¿
èŠãªæ
å ±ã¯ãã¡ã€ã«ãšããŠã¢ããããŒãããããå Žåã«ãã£ãŠã¯æåã§æ
å ±ãæŽçããŠããã¹ãã§æž¡ããããã工倫ãå¿
èŠã§ããããã®ã³ã³ããã¹ãæå
¥ã¯å°ãæéããããéšåã§ãã ãã§ãŒãº2ïŒå¯Ÿè©±ã«ããæ
å ±æœåºãšè«ç¹æŽç (Geminiãš) ç®ç: AIããã®è³ªåãéããŠãèšäºã«å¿
èŠãªæ
å ±ããæžãæèªèº«ãåœåæèããŠããªãã£ãéèŠãªè«ç¹ãæç¢ºã«ããããšã§ãã å®è·µå
容: ååãªæ
å ±ãã€ã³ãããããããšå€æããæ®µéã§ãGeminiã«è³ªåãä¿ããŸããã 質åèŠæ±ããã³ãã (Geminiãž): ãããŸã§ã®æ
å ±ããèšäºãäœæããããã«å¿
èŠãªæ
å ±ãåŸããããç§ãžè³ªåããŠãã£ãŠãã ããã ããã«å¯ŸããGeminiã¯èšäºã®ç®çãèªè
å±€ãèæ¯ãæè¡éžæçç±ãéçºããã»ã¹ãåŠã³ãšãã£ããèšäºæ§æäžã®éèŠèŠçŽ ã«ã€ããŠå
·äœçãªè³ªåãæããããŠããããããã®è³ªåã«ãã£ããã§çããŠããããšã§ãèªç¶ãšèšäºã®éªšåãåºãŸã£ãŠããŸããã â²Geminiã質åããããã«å¯ŸããŠåçããããšã§è«ç¹ãæç¢ºåããŠãããã£ããç»é¢ 广: ã㮠察話ããã»ã¹ã¯éåžžã«æå¹ ã§ãããAIã¯å£æã¡çžæã®ããã«æ©èœããå€è§çãªèŠç¹ããã®è³ªåã«ãã£ãŠãèªåã ãã§ã¯æ°ã¥ããªãã£ãèšäºã®ãã€ã³ãããèªè
ãç¥ãããã§ãããæ
å ±ãæŽçã§ããŸãããæèãã¯ãªã¢ã«ãªããèšäºã®æ§æãèããäžã§ã®å€§ããªå©ããšãªããŸããã ãã§ãŒãº3ïŒæ§ææ¡ïŒã¢ãŠãã©ã€ã³ïŒã®äœæãšåæ (Geminiãš) ç®ç: æ¬æå·çåã«ãèšäºå
šäœã®æµãã»å«ããã¹ãã»ã¯ã·ã§ã³ã»åã»ã¯ã·ã§ã³ã®äž»èŠå
容ã«ã€ããŠAIãšèªèãåãããææ»ããé²ããŸãã å®è·µå
容: ãã§ãŒãº2ã§æŽçãããæ
å ±ãããšã«ãGeminiãžæ§ææ¡ïŒã¢ãŠãã©ã€ã³ïŒã®äœæãäŸé Œããææ¡ãããå
容ã確èªã»ä¿®æ£ããŸããã æ§ææ¡äœæäŸé Œ (GeminiãžãAIåŽææ¡ãåããŠ): (Gemini: ...次ã®ã¹ããããšããŠããããã®æ
å ±ãããšã«ããã°èšäºã®æ§ææ¡ïŒã¢ãŠãã©ã€ã³ïŒãäœæããã確èªããã ãã®ã¯ãããã§ããããïŒ) ãé¡ãããŸã [ Geminiãæ§ææ¡ãæç€º ] æ§ææ¡ãžã®ä¿®æ£æç€º (Geminiãž): è¯ãã éçºã®è©±ãããåã«ããããžã§ã¯ããé²ããäžã§ã®èª²é¡åæãããå¹çåãå®çŸããããã«å¿
èŠãªèŠæ±ãèŠä»¶ã®çå® å®éã«èããçµæãèªåã§ãäœããã®ã§ã¯ïŒãšãããšããããã·ã¹ãã éçºã®è©±ã«å
¥ã£ãŠããæµãã§äœã£ãŠãã ããã â²Geminiãææ¡ããæ§ææ¡ãšãããã«å¯Ÿããä¿®æ£æç€ºã®ãã£ããç»é¢ 广: ãããªãèšäºå
šäœãçæãããã®ã§ã¯ãªãã å
ã«æ§ææ¡ã§ããåãããè¡ãããšã§ã倧ããªæ¹åæ§ã®ãºã¬ãé²ããåŸã®ä¿®æ£ã³ã¹ããã¬ãã¥ãŒã³ã¹ãã倧å¹
ã«åæž ã§ããŸãããããã¯å¹ççãªAIãšã®ååã«ãããŠéèŠãªã¹ãããã ãšæããŸããã ãã§ãŒãº4ïŒæ¬æå·çãšå埩çãªæ¹å (GeminiãšCopilotã§) ç®ç: åæããæ§ææ¡ã«åºã¥ããAIã«èšäºæ¬æã®ãã©ãããçæããã人éãã¬ãã¥ãŒãšå
·äœçãªä¿®æ£æç€ºãç¹°ãè¿ããŠèšäºã®å質ãé«ããŸãã å®è·µå
容: ãŸãGeminiã«åæããæ§ææ¡ãããšã«æ¬æå·çãäŸé ŒããŸããçæããããã©ãããã¬ãã¥ãŒãã倧ããªä¿®æ£ãæ
å ±è¿œå ã¯Geminiãžã®æç€ºã§è¡ããŸããããã®åŸããšãã£ã¿äžã§GitHub Copilotã䜿ããªããã现ããªè¡šçŸã®èª¿æŽãèšãåãã®å€æŽãªã©ãè¡ããŸããã æ¬æå·çäŸé Œ (Geminiãž): è¯ããå
容ã«ã€ããŠè¿œå ã§ããèšäºè©³çްããããªãäœæããã®ã§ã¯ãªããæ§ææ¡ãæç€ºããŠã¢ãŠãã©ã€ã³ãããåãããããšã§ãææ»ããé²ããŠã確èªã³ã¹ããå°ãªããªã£ãããšãããã€ã³ããå
¥ã蟌ãã§ãã ããã èšäºè©³çްãå®éã«äœæããŠãã ããã [ Geminiãæ¬æãã©ãããçæ ] Geminiãžã®å
·äœçãªä¿®æ£æç€ºäŸ: ïŒhxïŒã®è¡šèšã¯åé€ããŠãã ããã ããã¡ãã£ãšèä»ãããããïŒè¿œå æ
å ±æäŸïŒ...ãæ·»ä»ããŠç޹ä»ããããäžãããimage_1.png...ãšãã圢åŒã§åŒã³åºãããã«æç« ã®markdownãäœæããŠãã ããã ã³ãŒããããã¯ã2éã«äœ¿ããšããŸã衚瀺ãããŸãããã©ããããããã§ããïŒ ïŒAIçæã³ãŒãã®æ€èšŒã«é¢ãã远èšå
容ïŒ...ãšããå
容ãçã蟌ãã§ãã ããã â²Geminiã«å¯ŸããŠãæç« ã®èä»ãããã©ãŒãããä¿®æ£ãªã©å
·äœçãªæç€ºãåºããŠãããã£ããç»é¢ â²Geminiã«å¯ŸããŠãã¿ã€ãã«æ¡ã®åè£ãæç€ºãããŠããæ§å ãã®ããã«ãGeminiã§å€§æ ãäœããCopilotã§çްéšãæŽããããšãã£ã䜿ãåããæå¹ã§ãããã¿ã€ãã«æ¡åºããªã©ãGeminiã«äŸé ŒããŸããã ãã§ãŒãº5ïŒã¬ãã¥ãŒãšLinterå¯Ÿå¿ (Gemini/Copilotã§) ç®ç: çæãããèšäºã«å¯ŸããŠã人éã®ç®ã«ããã¬ãã¥ãŒãšãããŒã«ã«ããæ©æ¢°çãªãã§ãã¯ãè¡ããæçµçãªå質ãæ
ä¿ããŸãã å®è·µå
容: ã¹ã¿ã³ãã€ã®ããã¯ããã°ã§ã¯ãèšäºã®å質ãä¿ã€ããã«ãGitHub Actionsäžã§ reviewdog ãå©çšãã textlint ã«ããæ¥æ¬èªã®ã¹ã¿ã€ã«ã衚çŸã«é¢ãããã§ãã¯ãèªåã§è¡ã£ãŠããŸãã ä»åãAIãçæãããã©ããã«å¯ŸããŠããã®ãã§ãã¯ãå®è¡ãããšãããããã€ãã®ææäºé
ãæ€åºãããŸããããããã®ææã«å¯ŸããGeminiãCopilotã«ä¿®æ£æ¡ãèããŠããããŸããã Linterææä¿®æ£äŸé Œããã³ãã (Gemini/Copilotãž): review dogãšããããã±ãŒãžã§article.mdã®æç« ã®lintãã§ãã¯ãããŸããã ã©ã®ããã«å€æŽããã¹ããææ¡ããŠãã ããã å®éã®æç« ãšæ¯èŒãããã®ã§ã該åœç®æã®æç« ã®å€æŽå
容ãdiff圢åŒã§è¡šç€ºããŠææ¡ããŠãã ããã [lintãã§ãã¯ã®çµæã貌ãä»ã] â²reviewdog/textlintã®ææãCopilotã§ä¿®æ£ããŠããæ§å 广: AI㯠Linter ã®ææå
容ãçè§£ããå
·äœçãªä¿®æ£æ¡ã diff 圢åŒãªã©ã§æç€ºããŠãããŸãããããã«ãããä¿®æ£äœæ¥ã倧å¹
ã«å¹çåãããæ©æ¢°çãªãã§ãã¯ãžã®å¯Ÿå¿ã³ã¹ããåæžã§ããŸãããAIã¯ã³ãŒãã£ã³ã°ã ãã§ãªããæç« æ ¡æ£ãã¬ãã¥ãŒæ¯æŽã«ãããŠãæå¹ãªããŒãããŒãšãªãåŸãããšã宿ããŸããã AIãšã®èšäºå·çããåŸãããåŠã³ãšå®è·µãã€ã³ã ä»åã®çµéšãéããŠãAIãšã®å
±åäœæ¥ã«ã€ããŠå€ãã®åŠã³ããããŸããã å·çå¹çãšå質åäžãžã®å¹æ æéåµåº: AIãæ§ææ¡äœæããã©ããå·çãšãã£ãæéãèŠããäœæ¥ãè©ä»£ããããŠãããããã人éã¯ãã å
å®¹ã®æšæ²ãã¬ãã¥ãŒãæçµçãªå質åäžã«æéãéäž ãããããšãã§ãããçµæçã«ãå·çå
šäœã®ãªãŒãã¿ã€ã ççž®ãšå質åäžã®äž¡ç«ã«ç¹ãã£ããšæããã åŸæåéã®æŽ»çš: ããã°ã®ããŒã³ïŒãããŒç¶æãããã£ãããŒãªã¿ã€ãã«æ¡ã®ãã¬ã€ã³ã¹ããŒãã³ã°ãããã«ã¯ Linter ææãžã®å¯Ÿå¿ãªã©ãAIãåŸæãšããéšåãããŸã掻çšã§ããã 广çãªAIãšã®ååTips â ç®çãšã³ã³ããã¹ããæç¢ºã«: æåã«ãäœã«ã€ããŠæžãããã®ããã誰ã«èªãã§ã»ããã®ãããã©ã®ãããªæ
å ±ãããã®ãããå
·äœçã«äŒããããšããåŸã®ããã»ã¹ãã¹ã ãŒãºã«é²ããéµã ⡠察話ã«ããæèæŽç: AIããã®è³ªåã¯ãèªèº«ã®èããæŽçããèšäºã®è«ç¹ãæ·±ããçµ¶å¥œã®æ©äŒã§ãããç©æ¥µçã«å¯Ÿè©±ã掻çšïŒç¹ã«Geminiã®ãããªãã£ããAIïŒã ⢠ã¢ãŠãã©ã€ã³ã§ã®äºååæ: æ¬æå·çåã«æ§ææ¡ã§èªèãåãããããšã§ã倧å¹
ãªææ»ããé²ããã¬ãã¥ãŒã³ã¹ããåæžã ⣠å埩çãªæ¹åãåæ: AIã®çæç©ã¯ãããŸã§ããã©ããããšæãã人éãã¬ãã¥ãŒããå
·äœçãªæç€ºãäžããŠæ¹åããŠããããã»ã¹ãäžå¯æ¬ ã§ãããäžçºã§ã®å®æã¯æåŸ
ããã察話ãç¹°ãè¿ãã †å
·äœçãªæç€ºãå¿ããã: ããã£ãšè¯ãããŠãã§ã¯ãªããããã®éšåã®è¡šçŸããããã®èŠç¹ãå ããŠæžãçŽããŠãããã®Linterãšã©ãŒãä¿®æ£ããææ¡ãdiff圢åŒã§åºããŠãã®ããã«ãå
·äœçãªä¿®æ£æç€ºãåºãããšã粟床åäžã«ç¹ããã ⥠AIã®éçãçè§£ãã: ææ°æ
å ±ãWebäžã®æ
å ±ã®çŽæ¥çãªè§£éãè€éãããæç€ºã®çè§£ãªã©ã¯èŠæãªå Žåãããããã¡ã€ã«æäŸã段éçãªæç€ºã§è£ãã ⊠ããŒã«ïŒGemini/CopilotïŒã®äœ¿ãåã: ãã£ããAIïŒGeminiïŒã¯æ§ææ¡äœæãé·æãã©ããã質åå¿çãªã©ã倧ããªæµããäœãã®ã«åããŠããããšãã£ã¿é£æºAIïŒCopilotïŒã¯ãã³ãŒããæç« ã®çްããªä¿®æ£ãè£å®ãªã©ã«äŸ¿å©ã§ãããç®çã«å¿ããŠäœ¿ãåãããšããå¹ççã ä»ã®èšäºå·çã«ãå¿çšã§ããããªãã€ã³ã äžèšã®Tipsãç¹ã«ãã³ã³ããã¹ãæç€ºâå¯Ÿè©±âæ§æâå·çâæ¹åâã¬ãã¥ãŒæ¯æŽããšããããã»ã¹ã¯ãæè¡èšäºã«éããæ±çšæ§ãé«ããäŒç»æžãå ±åæžãã¡ãŒã«ãªã©ãæ§ã
ãªçš®é¡ã®æç« äœæã«å¿çšã§ãããšæããŸããã åå©çšå¯èœãªããã³ãããã³ãã¬ãŒãæ¡ ä»åã®çµéšãããAIãšã®èšäºå·çããã»ã¹ã§äœ¿ããããªããã³ããã®ãã³ãã¬ãŒããèããŠã¿ãŸãããïŒäž»ã«ãã£ããAIåãïŒ ãã³ãã¬ãŒãæ¡ïŒAIã«ããè«ç¹æŽçã»è³ªåèŠæ± # ç®ç [èšäºã®äž»é¡ãéæãããããš] ã«é¢ããããã¯ããã°èšäºãäœæãããã # æ³å®èªè
[èªè
ã®ãã«ãœããæè¡ã¬ãã«ãªã©] # æäŸæžã¿æ
å ± 以äžã®è³æã»èæ¯æ
å ±ãã€ã³ãããæžã¿ã§ãã * [è³æ/æ
å ±ã®æŠèŠ1] * [è³æ/æ
å ±ã®æŠèŠ2] * [ãã®ä»ãç¹çãã¹ãã³ã³ããã¹ã] # ããŒã³ïŒãã㌠[æ¢åèšäºãã¡ã€ã«åãªã©ãåèè³æãæç€º] ãåèã«ã[äŸïŒæè¡çã課é¡è§£æ±ºå¿åãå
·äœç]ãªããŒã³ã§èšè¿°ããŠãã ããã # ã¿ã¹ã¯ äžèšã®æ
å ±ã«åºã¥ãã質ã®é«ãèšäºãäœæããããã«ãç§ã«è¿œå ã§ç¢ºèªãã¹ãç¹ãæ·±æããã¹ãè«ç¹ãæŽãåºããå
·äœçãªè³ªåãè€æ°ããŠãã ãããèšäºã®æ§ææ¡ãèããåæ®µéãšããŠãè«ç¹ã®æãæŒããé²ããå
å®¹ãæ·±ããããšãç®çãšããŸãã ãããã®ãã³ãã¬ãŒããåºçºç¹ãšããŠãå
·äœçãªç¶æ³ã«åãããŠã«ã¹ã¿ãã€ãºããŠæŽ»çšã§ããŸãã ä»åã®åãçµã¿ã®ãŸãšã ä»åã®AIïŒGeminiãšCopilotïŒãšã®å
±åå·çããã»ã¹ã¯ã以äžã®ã¹ãããã§é²ã¿ãŸããã ã³ã³ããã¹ãæå
¥ (Gemini): èšäºã®ããŒããèæ¯ãé¢é£è³æãããŒã³ïŒãããŒã®ã€ã³ãããã 察話 (Gemini): AIããã®è³ªåã«çããããšã§ãè«ç¹ã®æŽçãšæ·±æãã æ§ææ¡äœæ (Gemini): AIãææ¡ããã¢ãŠãã©ã€ã³ã人éãã¬ãã¥ãŒã»ä¿®æ£ããåæã æ¬æå·ç (Gemini): åæããæ§ææ¡ã«åºã¥ãAIããã©ãããäœæã ååŸ©ä¿®æ£ (Gemini/Copilot): 人éãã¬ãã¥ãŒããå
·äœçãªæç€ºãäžããªããAIãšå
±ã«èšäºãæ¹åããã£ããã§ã®æç€ºãšãšãã£ã¿äžã§ã®ä¿®æ£ã䜵çšã Linterå¯Ÿå¿ (Gemini/Copilot): èªåãã§ãã¯ããŒã«ã®ææç®æä¿®æ£ãAIã«æ¯æŽãäŸé Œã ãã®ããã»ã¹ãçµãŠãç¡äºã«ãAI Co-PilotãšäœãïŒ1200ä»¶ã®SQLæžãæããä¹ãè¶ãã瀟å
ããŒã«éçºç§è©±ãã®èšäºã宿ãããããšãã§ããŸãããAIãæŽ»çšããããšã§ãèšäºå·çã®ããŒãã«ãäžãããããå€ãã®æçãªæ
å ±ãã¿ã€ã ãªãŒã«çºä¿¡ã§ããå¯èœæ§ãæããŠããŸãã ãããã« AIã¢ã·ã¹ã¿ã³ããšã®ååã«ããã³ã³ãã³ãäœæã¯ãä»åŸãŸããŸãéèŠã«ãªã£ãŠãããšèãããããAIã¯åãªãããŒã«ã§ã¯ãªãã壿ã¡çžæã§ãããæèãæŽçã»å éãããŠãããããŒãããŒã«ããªãåŸãŸãã ãã¡ãããæçµçãªå
å®¹ã®æ£ç¢ºæ§ãå質ã«å¯Ÿãã責任ã¯äººéãè² ãã¹ãã§ãããAIãšã®äžæãªä»ãåãæ¹ã身ã«ã€ããããšã§ãã³ã³ãã³ãå¶äœã®å¹çãšè³ªãé£èºçã«åäžãããããå¯èœæ§ãç§ããŠããŸãã çããã¯ãAIãã©ã®ããã«æŽ»çšãããŠããŸããïŒ ããé¢çœãæŽ»çšæ³ãããã°ããã²æããŠãã ããã æåŸã«ãã¹ã¿ã³ãã€ã§ã¯ãåžžã«æ°ããã¢ã€ãã¢ãæè¡ã調æ»ãã詊ããŠããŸãããã®èšäºã§ç޹ä»ãããããªAI掻çšããéçºããã»ã¹æ¹åã«èå³ãããæ¹ãç§ãã¡ãšäžç·ã«ãµãŒãã¹ãããè¯ãããŠããããšã«ææŠãããæ¹ã¯ããã² æ¡çšããŒãž ãã芧ãã ããïŒãåŸ
ã¡ããŠããŸãïŒ ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ã¯ããã« ããã«ã¡ã¯ãã¹ã¿ã³ãã€ã§ãããã¯ãäŒç»ãããŠããèå·»ã§ãã ã¹ã¿ã³ãã€ã§ã¯ãæ¥ã
ãµãŒãã¹ãæ¹åããããã«æ§ã
ãªæè¡çææŠãããŠããŸããä»åã¯ãã®äžã§ããæ±äººããŒã¿ä¿ç®¡ã»é
ä¿¡ã·ã¹ãã ã®å·æ°ãããžã§ã¯ãã«äŒŽã£ãŠçºçãã倧ããªèª²é¡ã«å¯Ÿãã課é¡åæããèŠä»¶å®çŸ©ããããŠçæAIã®åãåããŠãèªåã§äœã£ãŠã¿ããïŒããšæãç«ã¡ã瀟å
ããŒã«éçºã«è³ã£ãçµç·¯ãšãã®ããã»ã¹ãã玹ä»ããŸãã éçºããã®ã¯ãSQL Converterããšãããæ¢åã®SQLã¯ãšãªãæ°ããããŒã¿æ§é ã«åãããŠèªå倿ããããŒã«ã§ããæå€§ã§çŽ1200ä»¶ãã®ã¯ãšãªæžãæãäœæ¥ãå¹çåããããã«ãAI Co-PilotïŒGitHub Copilot / Google GeminiïŒãšAWS Bedrock (Claude) ãæŽ»çšããŸããã ãã®èšäºã¯ã以äžã®ãããªæ¹ã«ç¹ã«ããããã§ãã AI/LLMãæŽ»çšããéçºãæ¥åå¹çåã«é¢å¿ã®ãããšã³ãžãã¢ã»éãšã³ãžãã¢ã®æ¹ SQLãããŒã¿ç§»è¡ãããŒã¿åºç€ã®å·æ°ã«é¢å¿ã®ããæ¹ 課é¡çºèŠãã解決çã®å
·äœåãããŒã«éçºãŸã§ã®ããã»ã¹ã«èå³ãããæ¹ å€§èŠæš¡ãªã·ã¹ãã æ¹ä¿®ã«ããã課é¡è§£æ±ºã®äºäŸãç¥ãããæ¹ ãã®èšäºãéããŠã身è¿ãªèª²é¡ãåæããçæAIãªã©ã®æ°ããæè¡ã掻çšããããšã§ãå°éå®¶ã§ãªããŠã解決çã圢ã«ã§ããå¯èœæ§ãæããŠããã ããã°å¹žãã§ãã ãããžã§ã¯ãã®èæ¯ãšèª²é¡åæ ã¹ã¿ã³ãã€ã§ã¯ãæ±äººããŒã¿ãä¿ç®¡ã»é
ä¿¡ããæ¢åã·ã¹ãã ïŒéç§°: job-storeïŒã®ããã©ãŒãã³ã¹ãšã³ã¹ãã«èª²é¡ããããã·ã¹ãã æ§æãå·æ°ãããããžã§ã¯ããé²è¡ããŠããŸãããã®éçšã§ãæ°ããããŒã¿æ§é ãæã€ã·ã¹ãã ïŒéç§°: jphubïŒãå°å
¥ãããããããŒã¿åºç€ãžåæ ãããããŒã¿æ§é ãæ°ãããªããŸãã ããã¯å€§ããªåé²ã§ããããåæã«æ°ããªèª²é¡ãçºçããŸãããã¹ã¿ã³ãã€ã§ã¯ãå¶æ¥ãäŒç»ããšã³ãžãã¢ãªã©ãæ§ã
ãªè·çš®ã®ã¡ã³ããŒãããŒã¿åæãã¢ãã¿ãªã³ã°ã®ããã«ãRedashçã§SQLã¯ãšãªãå©çšããŠããŸãããããŒã¿æ§é ãå€ãããšããããšã¯ããããã®æ¢åã¯ãšãªïŒãã®æ°ã çŽ1200ä»¶ïŒ ïŒãæ°ããæ§é ã«åãããŠæžãæããå¿
èŠãããããšããããšã§ãã å®éã«èª¿æ»ã»åæãé²ãããšããã®æžãæãäœæ¥ã«ã¯ããã€ãã®å€§ããªå°é£ïŒãã€ã³ãã€ã³ãïŒããããŸããã ãããã³ã°ã®è€éæ§: æ§ããŒã¿æ§é ïŒRDBã©ã€ã¯ïŒããæ°ããŒã¿æ§é ïŒNoSQLã©ã€ã¯ïŒãžã®å€æŽã§ãããåçŽãªããŒãã«åã»ã«ã©ã åã®çœ®æã ãã§ã¯å¯Ÿå¿ã§ããŸãããããŒã¿æ§é èªäœã®å€æŽãçè§£ããé©åã«SQLãæžãæããå¿
èŠããããŸãããããã¯ãç¹ã«SQLã«ç¿çããŠããªãã¡ã³ããŒã«ãšã£ãŠã¯é«ãããŒãã«ã èšå€§ãªäœæ¥é: 察象ã¯ãšãªãçŽ1200ä»¶ãšéåžžã«å€ãããã¹ãŠãæäœæ¥ã§æžãæããã«ã¯èšå€§ãªå·¥æ°ãå¿
èŠã éãããæé: ãããžã§ã¯ãã®ã¹ã±ãžã¥ãŒã«äžãæžãæãäœæ¥ã«å²ããæéã¯å幎ããªãã人çãªãœãŒã¹ã®ç¢ºä¿ãé£ããç¶æ³ã ãã®ãŸãŸæäœæ¥ã§é²ããã®ã¯éçŸå®çã§ãããäœããã®å¹çåçãæ¥åã§ããã å¹çåãžã®éçïŒèŠä»¶å®çŸ© 課é¡åæã®çµæãã人æã§è¡ãäœæ¥ã³ã¹ããäœæžããä»çµã¿ãã®å°å
¥ãäžå¯æ¬ ã§ãããšããçµè«ã«è³ããŸããããã ããå®å
šã«èªååããã®ã§ã¯ãªããæçµçãªçµæã®ç¢ºèªã¯å¿
ã人æã§è¡ãæ¹éãšããŸããã ããã§ãSQLæžãæãäœæ¥ãæ¯æŽããããŒã«ã®éçºãæ€èšãå§ããŸããããã®ããŒã«ãæºããã¹ãäž»èŠãªèŠä»¶ã以äžã®ããã«å®çŸ©ããŸããã ãããã³ã°æ
å ±ã®å©çš: æ°æ§ããŒã¿æ§é ã®ãããã³ã°æ
å ±ãèªã¿èŸŒã¿ãããã«åºã¥ããŠå€æã§ããããšã SQL倿æ©èœ: ãŠãŒã¶ãŒãå
¥åããæ§SQLãããããã³ã°æ
å ±ã«æ²¿ã£ãŠæ°SQLã«å€æããçµæãæç€ºã§ããããšã ãšã©ãŒå¯Ÿå¿: 倿åŸã®SQLãå®è¡ããŠãšã©ãŒãåºãå Žåã«ããã®ãšã©ãŒæ
å ±ãèæ
®ããŠååºŠå€æã詊ã¿ãããããšã Redash飿º: Redashããæ¢åã¯ãšãªã®æ
å ±ãååŸã§ããããšã ã·ã³ãã«ã: æ§ã
ãªè·çš®ã®ã¡ã³ããŒãå©çšãããããçŽæçã«äœ¿ããã·ã³ãã«ãªã€ã³ã¿ãŒãã§ãŒã¹ã§ããããšã ïŒéæ©èœèŠä»¶ïŒ ã»ãã¥ãªãã£ïŒVPNæ¥ç¶å¿
é ïŒãã³ã¹ãå¹çïŒäœå©çšæã¯åæ¢ïŒãªã©ãèæ
®ã ããããAIã§äœããããïŒã - éçºãžã®æ±ºæ ãããã®èŠä»¶ãå®çŸ©ããŠããäžã§ãç¹ã«ããããã³ã°æ
å ±ã«åºã¥ããŠSQLã倿ããããšããã³ã¢æ©èœã¯ãè¿å¹Žã®çæAIæè¡ãç¹ã«å€§èŠæš¡èšèªã¢ãã«ïŒLLMïŒãåŸæãšããé åã§ã¯ãªããïŒãšèãå§ããŸããã è€éãªã«ãŒã«ïŒãããã³ã°æ
å ±ïŒãšå
¥åïŒæ§SQLïŒãçè§£ããããã«åºã¥ããŠæ°ããåºåïŒæ°SQLïŒãçæããã¿ã¹ã¯ã¯ããŸãã«LLMã®èœåãæŽ»ãããå Žé¢ã§ããããã«ãGitHub Copilotã®ãããªAI Co-Pilotã䜿ãã°ãWebã¢ããªã±ãŒã·ã§ã³ã®éªšçµã¿ãå®åçãªã³ãŒããå¹ççã«çæã§ããããããããã°ã©ãã³ã°çµéšããªããŠããAIã®åãåããã°èªåã§ãã®ããŒã«ãäœããã®ã§ã¯ãªããïŒããšããæãã匷ããªããŸããã ããããŠããAIãæŽ»çšããSQL倿ããŒã«ãã®å
·äœçãªéçºãã¹ã¿ãŒãããŸããã 解決çïŒAIã«ããSQL倿ããŒã«ãSQL Converterã ãã®èª²é¡ãšèŠä»¶ããããŠãAIã§äœããããããšããçºæ³ããçãŸããã®ãã瀟å
ããŒã«ãSQL Converterãã§ããæ§ããŒã¿æ§é ã«åºã¥ããSQLãå
¥åãããšãæ°ããŒã¿æ§é ã«å¯Ÿå¿ããSQLåè£ãèªåã§çæããŠãããWebã¢ããªã±ãŒã·ã§ã³ãšããŠå®çŸããŸããã â²SQL Converterã®ã¡ã€ã³ç»é¢ â²å®éã«SQLã倿ããŠããæ§åïŒãããŒããŒã¿ã«ããåäœäŸïŒ äž»ãªæ©èœã¯ä»¥äžã®éãã§ãã SQLå
¥å: 倿ãããSQLãçŽæ¥å
¥åããŸãã¯Redashã«ä¿åãããŠããã¯ãšãªã®IDãæå®ããŠèªã¿èŸŒãããšãã§ãã AIã«ãã倿: å
¥åãããSQLãšãäºåã«å®çŸ©ãããæ°æ§ãããã³ã°æ
å ±ãããšã«ãAIïŒAWS Bedrock - ClaudeïŒãæ°ããSQLãçæã倿æã«ãšã©ãŒãçºçããå Žåã¯ããã®ãšã©ãŒæ
å ±ã远å ããŠååºŠå€æã詊ã¿ãããšãå¯èœ å·®å衚瀺: 倿ååŸã®SQLã®å·®åïŒDiffïŒã䞊ã¹ãŠè¡šç€ºãã倿Žç¹ãèŠèŠçã«ç¢ºèªã§ãã ããŒã«ã®æè¡æ§æ ããŒã«ã®æè¡ã¹ã¿ãã¯ã¯æ¯èŒçã·ã³ãã«ã«æ§æããŸããã ããã¯ãšã³ã: FastAPI (Python)ã瀟å
ã§ã®å°å
¥äºäŸãããåŠç¿ã³ã¹ããäœããšèãéžå®ããŸããã ããã³ããšã³ã: HTML, CSS (Tailwind CSS), JavaScriptãTailwind CSSã¯ã¡ãžã£ãŒãªãã¬ãŒã ã¯ãŒã¯ã§ããããæ¡çšããŸããã AIã¢ãã«: AWS Bedrock (Claude)ã瀟å
ã§ã®å©çšå®çžŸããã£ãããæ¡çšããŸããã èšå®ã»å€æããžãã¯: mapping_info.yml : æ°æ§ã®ããŒãã«ã»ã«ã©ã 察å¿é¢ä¿ãå®çŸ©ãããããã³ã°ãã¡ã€ã«ã prompt.txt : Bedrockã«æž¡ãæç€ºïŒããã³ããïŒã®ãã³ãã¬ãŒãã ç¹å¥ãªãã¬ãŒã ã¯ãŒã¯ãã©ã€ãã©ãªãžã®äŸåãæ¥µåæžãããåºæ¬çãªWebæè¡ãšAIãµãŒãã¹ãçµã¿åãããããšã§ãè¿
éãªéçºãšã¡ã³ããã³ã¹æ§ã®ç¢ºä¿ãç®æããŸããã AI Co-Pilot ãšå
±ã«æ©ãã éçºããã»ã¹ ä»åã®ããŒã«éçºã§ã¯ãGitHub CopilotãGoogle Geminiãšãã£ãAI Co-Pilotãå
šé¢çã«æŽ»çšããŸãããããã«ãããããã°ã©ãã³ã°çµéšãã»ãšãã©ãªãèªåã§ãå¹ççã«éçºãé²ããããšãã§ããŸããã éçºã®é²ãæ¹ïŒã茪éãã詳现ãžã éçºã¯ããŸãã§çµµãæãããã«ããŸã倧ãŸããªèŒªéïŒUIïŒããæãå§ããåŸã
ã«è©³çŽ°ïŒæ©èœïŒãå ããŠããã¢ãããŒããåããŸããã ããã³ããšã³ãäœæ: ãŸãHTMLãšCSSïŒTailwindïŒã§åºæ¬çãªç»é¢æ§æãäœæã ã¢ãã¯APIäœæ: ããã³ããšã³ãããã®ãªã¯ãšã¹ããåãä»ãããããŒããŒã¿ãè¿ãç°¡åãªFastAPIãµãŒããŒãäœæã ããã³ããšã³ãåäœç¢ºèª: ã¢ãã¯APIã䜿ã£ãŠããã¿ã³ã¯ãªãã¯ã衚瀺åãæ¿ããªã©ãããã³ããšã³ãïŒJavaScriptïŒã®åäœãå®è£
ã»ç¢ºèªã ããã¯ãšã³ãæ©èœå®è£
: å®éã®ããã¯ãšã³ãã«ãRedash飿ºãBedrock飿ºãªã©ã®æ©èœã 1〠ãã€è¿œå ãããã§ãã¢ãã¯APIãåç
§ããªãããæåŸ
éãã®åäœãããã確èªãã€ã€é²ããŸããã æ¬çªAPI飿º: æåŸã«ãããã¯ãšã³ããšå®éã®AWS BedrockãRedash APIã飿ºãããå
šäœã®åäœã確èªã ãã®æ®µéçãªã¢ãããŒãã«ãããææ»ããæå°éã«æãã€ã€ãçå®ã«éçºãé²ããããšãã§ããŸããã ã¢ãã¯ãµãŒããŒã®éèŠæ§ ç¹ã«éèŠã ã£ãã®ããã¹ããã2ã§äœæãã ã¢ãã¯ãµãŒããŒã®ååš ã§ããAI Co-Pilotã¯éåžžã«åŒ·åã§ãããåžžã«å®ç§ãªã³ãŒããçæããŠãããããã§ã¯ãããŸãããå®éã«AIãçæããã³ãŒãã«ã¯ãè¶ããªããã°ãªããªãã3ã€ã®ãã§ãã¯ã®ããŒãã«ãããããšæããŠããŸãã èŠãæãè¯ããããïŒ: ãã©ãŠã¶ç»é¢ã§èŠãŠæå³éãã®å€æŽã«ãªã£ãŠãããã ã¡ãããšåããããïŒ: å®éã«åãããŠã¿ãŠããšã©ãŒãªãå®è¡ã§ãããã æå³éãæ£ããåããŠãããïŒ: å®è¡ã§ããŠããæåŸ
ããéãã®çµæãå
éšç¶æ
ã«ãªã£ãŠãããã AIã¯æåã®ããŒãã«ã¯è¶
ããŠããããšãå€ãã§ããã2çªç®ãç¹ã«3çªç®ã®ããŒãã«ãäžçºã§è¶
ããããšã¯çšã§ãããã®ãããäœåºŠããçæâ詊è¡âä¿®æ£ããšããã«ãŒããåãå¿
èŠããããŸããã ããã§ã¢ãã¯ãµãŒããŒãç䟡ãçºæ®ããŸããAIãçæããã³ãŒããããã£ãšèŠãããç°å¢ããããã«è©Šããç°å¢ããæäŸããŠãããŸãã è¿
éãªåäœç¢ºèª: ããã³ããšã³ããããã¯ãšã³ãã®ããžãã¯ãæåŸ
éãã«åããããïŒããŒãã«2ïŒããå®éã®API飿ºãå€éšãµãŒãã¹ã®æ¥ç¶ç¶æ
ãæ°ã«ãããæå
ã§ããã«ç¢ºèªã§ãããããã«ããããã£ãŒãããã¯ã«ãŒããéåžžã«é«éã«ãªãã é¢å¿äºã®åé¢: äŸãã°ããã³ããšã³ãã®ãã¹ãäžã¯UIã®æåã ãã«éäžã§ããããã¯ãšã³ãAPIåŽã®åé¡ãåãåããŠèããããšãã§ãããããã«ãããåé¡ã®ç¹å®ãšä¿®æ£ã容æã«ãªãã AI Co-Pilotãšã®ãã¢ããã°ã©ãã³ã°ã«ãããŠããã®ãããã«è©ŠããŠãããã«ãã£ãŒãããã¯ãåŸãããç°å¢ãã¯ãéçºå¹çãšè©Šè¡é¯èª€ã®è³ªã倧å¹
ã«åäžãããéµãšãªããŸããã ããã³ãããšã³ãžãã¢ãªã³ã°ã®è©Šè¡é¯èª€ AIã«SQLå€æãæ£ç¢ºã«è¡ãããããã«ã¯ãBedrockã«æž¡ãæç€ºãã€ãŸãããã³ããã®è³ªãéåžžã«éèŠã§ããããã§ã詊è¡é¯èª€ãç¹°ãè¿ããŸããã æåã¯ãããã®SQLããããã³ã°æ
å ±ã«åºã¥ããŠå€æããŠããšãã£ãéåžžã«ã·ã³ãã«ãªæç€ºããå§ããŸãããããããããã ãã§ã¯ä»¥äžã®ãããªåé¡ãçºçããŸããã å
ã®SQLã«å«ãŸããæ¹è¡ãã€ã³ãã³ããã³ã¡ã³ãã¯ç¡èŠãããŠããŸãã 倿ã®ç²ŸåºŠã¯ååã§ãªãå Žåãããã ããŒã«ãåºåãã説æã¡ãã»ãŒãžã®ãã©ãŒãããã¯æ±ãã«ããã ããã§ãå®éã«ããŒã«ãåãããŠåé¡ç¹ãæŽãåºããAI Co-Pilotã«ãçžè«ããªããããã³ãããæ¹åããŠãããŸãããããã©ãŒããããã³ã¡ã³ãã¯ãã®ãŸãŸä¿æããŠã»ãããã説ææã®æ¹è¡ã¯HTMLã® <br> ã¿ã°ã«ããŠã»ããããçµæã¯JSON圢åŒã§ã'sql'ãš'message'ãšããããŒã§è¿ããŠã»ããããšãã£ãå
·äœçãªæç€ºã远å ããŠãã£ãã®ã§ãã 詊è¡é¯èª€ã®çµæãæçµçã«ä»¥äžã®ãããªããã³ãã ( prompt.txt ) ã«èœã¡çããŸããã 以äžã®SQLããæäŸããããããã³ã°æ
å ±ã«åºã¥ããŠæ°ããããŒã¿ããŒã¹ïŒããŒãã«ïŒã«å¯Ÿå¿ããããã«å€æããŠãã ããã **éèŠãªæç€º:** * å
¥åSQLå
ã® **æ¹è¡ãã€ã³ãã³ãã空çœ** ãå¯èœãªéã **å¿ å®ã«ä¿æã»åçŸ** ããŠãã ãããèªåçãªã³ãŒãæŽåœ¢ã¯è¡ããªãã§ãã ããã * å
¥åSQLã«å«ãŸããã³ã¡ã³ã (`--` ããå§ãŸãè¡ãè¡æ«ã³ã¡ã³ã) ã **ãã®ãŸãŸã®äœçœ®ã§ä¿æ** ããŠãã ããã * ãããã³ã°æ
å ±ã«åŸã£ãŠãããŒãã«åãã«ã©ã åãé©åã«çœ®æããŠãã ããã * message屿§ã®å€ã§ãã説ææäžã®æ¹è¡ã«ã¯ãæ¹è¡æå(\n)ã§ã¯ãªããå¿
ãHTMLã®<br>ã¿ã°ã䜿çšããŠãã ããã **å
¥åSQL:** ```sql {input_sql} ``` ãããã³ã°æ
å ±ã¯ãã¡ãã§ãã ```yaml {mapping_info} ``` çµæã®ã¢ãŠããããã¯ä»¥äžã®json圢åŒã«æ²¿ã£ãŠåºåããŠãã ãããåçã¯jsonã®ã¿åºåããŠãã ããã {{ "sql": "ããã«å€æããSQLãåºå", "message": "ããã«å€æã«ã€ããŠã®èª¬æãåºå" }} ãã®ããã«ãå
·äœçãªæç€ºã现ããäžããããšã§ãAIã®åºå粟床ãšäœ¿ãåæã倧ããåäžãããããšãã§ããŸããã AIã¢ã·ã¹ã¿ã³ãã®å®è·µçãªäœ¿ãæ¹ éçºå
šäœãéããŠãAI Co-Pilotã¯æ§ã
ãªå Žé¢ã§åœ¹ç«ã¡ãŸããã å®åã³ãŒãã®çæ: FastAPIã®ãšã³ããã€ã³ãã®é圢ãCSVããYAMLãžã®å€æã¹ã¯ãªãããªã©ãå®åçãªåŠçã¯AIãžä»»ããããšã§æéãç¯çŽã§ããã ã³ãŒãã®çè§£ä¿é²: AIãçæããã³ãŒããžä»äžãããã³ã¡ã³ãããåŠçå
容ã®çè§£ãå©ããã ãšã©ãŒè§£æ±ºã®ãã³ã: è¡ãè©°ãŸã£ãéããšã©ãŒã¡ãã»ãŒãžãå
¥åãããšã解決çã®åè£ã瀺ããã ããã¥ã¡ã³ãäœæã®å¹çå: å®ã¯ããã®ããŒã«ã®READMEãžèšèŒããã·ã¹ãã æ§æå³ãã·ãŒã±ã³ã¹å³ïŒMermaidèšæ³ïŒã¯ããœãŒã¹ã³ãŒããå
ãšããŠAI Co-Pilotãçæãããã®ã§ãããã³ãŒãã£ã³ã°ã ãã§ãªããããã¥ã¡ã³ãäœæäœæ¥ãå¹çåã§ããç¹ã¯å€§ããªçºèŠã§ãã£ãã â²AI Co-Pilotãçæããã·ã¹ãã æ§æå³ (Mermaid) â²AI Co-Pilotãçæããã·ãŒã±ã³ã¹å³ (Mermaid) AI Co-Pilotã䜿ãäžã§åŠãã ããšããããŸãããã㯠äžåºŠã«å€ãã®ããšãäŸé Œããªã ããšã§ããäŸãã°ããã®æ©èœå
šäœãäœã£ãŠãã®ãããªå€§ããªäŸé Œã¯é¿ããã¹ãã§ããããã®ãã¿ã³ãã¯ãªãã¯ãããããã®APIãåŒã³åºãåŠçã远å ããŠããšãã£ãå
·äœçã§å°ããªåäœã§äŸé Œããæ¹ã广çã§ãããã®æ¹ãæå³ã«è¿ãã³ãŒããåŸãããä¿®æ£ã容æã«ãªããŸããäžåºŠã«å€ãã®èŠçŽ ãçæããããšåé¡ãçããã¡ã§ããåèŠçŽ ã¯åŸ®åŠã«æ£ãããŠãçµã¿åããããšæå³ããªãåäœã«ãªãããšããããŸããã ããŒã«å°å
¥ã®çµæãšåŠã³ éçºããããSQL Converterãã¯ãjphubãžã®ããŒã¿æ§é 倿Žã«äŒŽãSQLæžãæãäœæ¥ã«ãããŠã倧ããªå©ããšãªãããã§ããå®å
šã«èªåã§å®ç§ãªSQLãåºåãããããã§ã¯ãããŸããããAIãçæããSQLåè£ãããŒã¹ã«äººéã確èªã»ä¿®æ£ããããšã§ããŒãããæžãæããå Žåã«æ¯ã¹ãР倧å¹
ãªå·¥æ°åæž ãæåŸ
ã§ããŸãã äž»ãªåŠã³ ãã®ãããžã§ã¯ããéããŠãç§ã¯å€ãã®åŠã³ãåŸãŸããã AIã«ããéçºã®æ°äž»å: çæAIãšAI Co-PilotãæŽ»çšããããšã§ãå¿
ãããããã°ã©ãã³ã°ã®å°éå®¶ã§ãªããŠããã¢ã€ãã¢ã圢ã«ããå®çšçãªããŒã«ãéçºã§ããå¯èœæ§ã宿ããã å埩çã¢ãããŒããšã¢ãã¯ã®éèŠæ§: AIæ¯æŽéçºã«ãããŠã¯ã现ãã詊è¡é¯èª€ãç¹°ãè¿ãããšãéèŠã§ããããã®ãµã€ã¯ã«ãé«éåããããã«ã¢ãã¯ãµãŒããŒã®ãããªãããã«è©Šããç°å¢ããéåžžã«æå¹ã§ãã£ããAIãçæããã³ãŒãã®ã3ã€ã®ããŒãã«ããå¹ççã«è¶ããããã«ãäžå¯æ¬ ã§ããã ããã³ãããšã³ãžãã¢ãªã³ã°ã®äŸ¡å€: AIã®èœåãæå€§éã«åŒãåºãããã«ã¯ãçç¢ºãªæç€ºïŒããã³ããïŒãäžããæè¡ãéèŠã«ãªãã詊è¡é¯èª€ãéããŠããã³ãããæ¹åããŠããããã»ã¹ã¯ãAIéçºã®æ žå¿ã®1ã€ãšèšããã ããã AIãšã®ååã®ã³ã: AIã¯äžèœã§ã¯ãªããåŸæãªããšïŒå®åã³ãŒãçæãã¢ã€ãã¢åºããããã¥ã¡ã³ãè£å©ïŒãä»»ãã人éã¯æçµçãªå€æããAIãèŠæãªè€éãªèŠæ±ã®åè§£ã»æç€ºåºããè¡ãããšãã£ã圹å²åæ
ã广çã§ãããå°ããªåäœã§äŸé Œããçµæã確èªããªããé²ããããšãæåã®éµã§ããã ãŸãšã ä»åã¯ããŒã¿æ§é 倿Žã«äŒŽãSQLæžãæã課é¡ã«å¯Ÿãã課é¡åæããèŠä»¶å®çŸ©ããããŠAIã«ãããSQL Converterãéçºããã»ã¹ãšãã®çµæãã玹ä»ããŸããã ãã®åãçµã¿ã¯ãAIãåãªãäœæ¥ã®èªååã ãã§ãªããéçºããã»ã¹ãã®ãã®ãå€é©ãããããŸã§æè¡çãªå£ã«ãã£ãŠã¢ã€ãã¢ãå®çŸã§ããªãã£ã人ã
ã«ãéçºã®éæžãéãå¯èœæ§ã瀺åããŠããŸããã³ãŒãã£ã³ã°ããããã¥ã¡ã³ãäœæãŸã§ãAIã¯éçºã®æ§ã
ãªãã§ãŒãºã§åŒ·åãªããŒãããŒãšãªãåŸãŸãã ãã¡ãããAIãçæãããã®ããã®ãŸãŸä¿¡ããã®ã§ã¯ãªãã人éãé©åã«ã¬ãã¥ãŒãããŠãæçµçãªå質ã«å¯ŸããŠè²¬ä»»ãæã€ããšã¯äŸç¶ãšããŠéèŠã§ããããããAIãšäžæã«ä»ãåãæ¹æ³ã暡玢ããã°ãç§ãã¡ã¯ããéãããããŠåµé çãªåœ¢ã§èª²é¡è§£æ±ºãžå¯Ÿå¿ã§ããããã«ãªãã§ãããã æåŸã« ã¹ã¿ã³ãã€ã§ã¯ãåžžã«æ°ããã¢ã€ãã¢ãæè¡ã調æ»ãã詊ããŠããŸãããã®èšäºã§ç޹ä»ãããããªAI掻çšããéçºããã»ã¹æ¹åã«èå³ãããæ¹ãç§ãã¡ãšäžç·ã«ãµãŒãã¹ãããè¯ãããŠããããšã«ææŠãããæ¹ã¯ããã² æ¡çšããŒãž ãã芧ãã ããïŒãåŸ
ã¡ããŠããŸãïŒ ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ã¯ãªãªãã£éšãŠãŒã¶ãŒãµããŒãã°ã«ãŒãã®å²žæ¬ã§ãã ã¹ã¿ã³ãã€ã§ã¯ãéçºæ¹éã«ãŠãŒã¶ãŒãã¡ãŒã¹ããæ²ãããŠãŒã¶ãŒèŠç¹ã«ç«ã¡ããŠãŒã¶ãŒã®ããã®æ©èœéçºã®å®çŸãç®æããŠãããFY23ããVOCã«è§Šããæ©äŒã®å¢å ãç®çãšããåãçµã¿ãéå§ããŠããŸãããŸã éåã°ã§ã¯ãããŸããããããŸã§ã®çµç·¯ãšåŸããã广ã«ã€ããŠã玹ä»ããŸãã ïŒéçºæ¹éã®èšäºç޹ä»ïŒ techblog.stanby.co.jp 1. ã¯ããã« VOCãšã¯ ãVoice of CustomerïŒé¡§å®¢ã®å£°ãã®ç¥ã§ããäŒæ¥ã®è£œåããµãŒãã¹ãå©çšããé¡§å®¢ã®æ£çŽãªæèŠã»ææ³ããæãèšèã§ããã¹ã¿ã³ãã€ã«ã¯ãä»äºãæ€çŽ¢ãããŠããæ¹ã
ãããåãåãããã©ãŒã ãªã©ãéããŠãµãŒãã¹ã«å¯Ÿããæ§ã
ãªãæèŠããèŠæãéãŸã£ãŠããŸãã VOCã®éèŠæ§ ç§ãã¡ãæäŸãããã¹ã¿ã³ãã€ããå©çšãããŠãŒã¶ãŒã®äžã«ã¯ã¢ã«ãã€ãã®ä»äºãæ¢ãããŠããæ¹ãã·ãã¢ã®æ¹ãå€ããå¿
ããã瀟å
ã®ã¡ã³ããŒãšäžèŽããããã§ã¯ãããŸãããå®éã®ãŠãŒã¶ãŒã¯ç§ãã¡ãšã¯ç°ãªãèŠç¹ã䟡å€èгãæã¡ãç°ãªãç°å¢ã§ãµãŒãã¹ãå©çšããŠããŸãããã®ããã瀟å
ã®æèŠã ãã§å€æããŠããŸããšããŠãŒã¶ãŒã®æ¬åœã®ããŒãºãšããé¢ããæ©èœãæ¹åãé²ããŠããŸããªã¹ã¯ããããŸãã ãããããºã¬ãé²ããããVOCã宿çã«åéãã誰ããæ¥åžžçã«ãŠãŒã¶ãŒã®å£°ã«è§Šããããç°å¢ãæŽããããšãç®æããŸããããŠãŒã¶ãŒã®çã®å£°ãããšã«èª²é¡ãç¹å®ãã解決çãèããããšãããã¹ã¿ã³ãã€ã®æäŸäŸ¡å€ã®åäžã«ã€ãªãããšèããŠããŸãã VOCã®åãçµã¿ãå§ããèæ¯ ã¹ã¿ã³ãã€ã§ã¯ãFY23以åãããŠãŒã¶ãŒããã®åãåãã察å¿ãè¡ãããããã¯ãéçºçµç¹ã«å¯ŸããŠå®æçã«ã¬ããŒãã£ã³ã°ã宿œããŠããŸããããããã以äžã®ãããªèª²é¡ããããVOCã®æŽ»çšã«ã¯è³ã£ãŠããŸããã§ããã ãåæã®åãåããå
容ããšãã£ãéå»ã®ãç¹ãã®æ
å ±ããæäŸãããŠããªãã£ã åãåãããããŠãŒã¶ãŒã®å±æ§ãäžæã§ããããµã³ãã«æ°ãå°ãªãã£ã ãã®èª²é¡ã解決ããããããŠãŒã¶ãŒã®å£°ãæãçŽæ¥åãåãã«ã¹ã¿ããŒãµããŒãïŒCSïŒéšéããããã¯ãéšéå
ã®ã¯ãªãªãã£éšã«çµ±åããVOCãããæ·±ããããã¯ãæ¹åã«æŽ»ãããçµç¹äœå¶ãžãšé²åãããŸããã 2. ã¢ãã¿ãªã³ã°ãšåæéçšã®éå§ â ã¢ãã¿ãªã³ã°ãšåæéçšã®éå§ VOCã®ã¢ãã¿ãªã³ã°åºç€ãæŽããããã以äžã®3ã€ã®ãã£ãã«ãæŽçããŸããã åãåããçªå£ïŒãŠãŒã¶ãŒããã®çžè«ã質åãåãä»ãã æ±äººæ
å ±ãžã®åé¡å ±åïŒåé¡ã®ããæ±äººãå ±åãã察å¿ãã ãŠãŒã¶ãŒæºè¶³åºŠã¢ã³ã±ãŒãïŒæ€çŽ¢çµæã«å¯Ÿããè©äŸ¡ãåéãã åœåããããã¯ãéšéã«å
±æãããŠããã®ã¯ãåãåããçªå£ãããã®VOCã®ã¿ã§ããã以å€ã®ããŒã¿ã¯ä»éšéãå¿
èŠã«å¿ããŠç¢ºèªããéçšã§ããããããããããã®VOCã¯ãã¹ãŠé£åããŠãããããå
šäœãå
æ¬çã«ã¢ãã¿ãªã³ã°ã§ãããããèç©ããŒã¿ãåé¡ããæããšã®VOCåŸåãå¯èŠåããããã®åæåºç€ãæ§ç¯ããŸããã â¡FAQã®ã¢ããããŒã å®éã«å£°ãšããŠéãŸã£ãŠããæ
å ±ã ãã§ãªããFAQïŒãã«ãããŒãžïŒã®ã¢ã¯ã»ã¹æ°ãVOCã®äžç°ãšããŠã¢ãã¿ãªã³ã°ãéå§ããŸãããåœåç«ã¡äžã段éã§ãã£ãFAQã®ã³ã³ãã³ããå
å®ãããªãããVOCãã£ãã«ãšããŠã®éçšãå
Œãããããããã¢ã¯ã»ã¹åæåºç€ãæŽåããŸããã FAQã®ã©ã®èšäºã«ãŠãŒã¶ãŒããã®ã¢ã¯ã»ã¹ãéãŸã£ãŠããããšããæ
å ±ãåºã«ã©ããªåé¡ãæ±ãããŠãŒã¶ãŒã墿žããŠããã®ããã¢ãã¿ãªã³ã°ããä»ã®ãã£ãã«ã®åŸåãšé£åããŠããåé¡ã®çºèŠã«æŽ»çšããŠããŸãã â¢ãŠãŒã¶ãŒæºè¶³åºŠã¢ã³ã±ãŒãã®åæ ãåãåããçªå£ããšãæ±äººæ
å ±ãžã®åé¡å ±åãã¯ããã®åŸã®ãªãã¬ãŒã·ã§ã³ãŸã§éçšãããŠããäžæ¹ã§ãããŠãŒã¶ãŒæºè¶³åºŠã¢ã³ã±ãŒããã¯å¿
èŠãªã¿ã€ãã³ã°ã§æ¹åãã¹ãåé¡ãæœåºããããã®æ
å ±æºãšããŠæŽ»çšããŠããŸããã æ¯æ5,000ä»¶çšåºŠã®æçš¿ããããã¢ã³ã±ãŒãã®åç/ã³ã¡ã³ããæ€çŽ¢æã®ãã°ãšã»ããã§èç©ãããŠããããããŸãã¯ç®ã®åã«ããããŒã¿ã®åæããçæããã¢ã³ã±ãŒããžã®åçããèªã¿åããåé¡ã«ã€ããŠã®ãã£ãŒãããã¯ãéå§ããŸããã ãâ 3. åéæ¹æ³ã®ãªãã¥ãŒã¢ã« â ãŠãŒã¶ãŒãæå³éãã®åçãéžæã§ãããã©ãŒã ã«ãªãã¥ãŒã¢ã« ãŠãŒã¶ãŒæºè¶³åºŠã¢ã³ã±ãŒãã®ãã£ãŒãããã¯ãç¶ç¶ããäžã§ããŠãŒã¶ãŒã®éžæãããé
ç®ãšã³ã¡ã³ãã«æžãããŠããå
容ã®äžèŽçã50%ãäžåã£ãŠããããšã«æ°ã¥ããŸããããã®ãããéèšã®éã«1ç¹ãã€åçãšã³ã¡ã³ããç®èŠã§ç¢ºèªããŠãéèšããäœæ¥ãçããŠããŸããããããããããã®ãŸãŸã®ããŒã¿ãåºã«ã¢ãã¿ãªã³ã°ãè¡ããšã誀ã£ãè§£éã§VOCãå
±æãããæžå¿µããããŸããã ããã§ãéå»ã®ã¢ã³ã±ãŒãçµæã«ãããã¢ã³ã±ãŒããžã®åçã®åŸåã¯ææ¡ã§ããŠããããã ããªã¥ãŒã ã®å€ãåçã现ååããŠãããå
·äœçãªåçãéžæã§ããã¢ã³ã±ãŒããã©ãŒã ãžãšãªãã¥ãŒã¢ã«ãè¡ããŸããã â¡éèšãã°ã®è¿œå ãŠãŒã¶ãŒãã©ã®ãããªã¯ãšãªã§æ€çŽ¢ããŠãã©ã®ãããªæ€çŽ¢çµæãèŠãŠãåçããŠããã®ããŸã§è¿œè·¡ãããå Žåã«åããŠãéèšãã°ã®è¿œå å®è£
ãè¡ããŸããã äŸãã°ã ã»æ€çŽ¢ã¯ãšãªã«å¯ŸããŠã衚瀺ãããæ±äººä»¶æ° ã»æµå
¥æããåçãããŸã§ã®æ€çޢ忰 ã»æ€çŽ¢æã«è¡šç€ºãããŠããæ±äººå
容 çãã©ã®ãããªç¶æ³ããåçããŠããã®ããæ·±æãããããã®ããŒã¿ãå¢ãããŸããã çŽè¿ã§ã¯ãABãã¹ãæã®ãã±ããããšã«ã¢ã³ã±ãŒãã®åçåŸåãã¢ãã¿ãªã³ã°ããŠã瀟å
ã§ãã£ãŒãããã¯ããŠããŸãã 4. 瀟å
ãžã®VOCå
±æã®åŒ·å VOCãå
šç€Ÿçã«æµžéãããããããããã¯ãéšéå
šå¡ãåå ããå
šäœäŒè°ã§VOCãå
±æããå ŽãèšããŸããã ç®ç å
šå¡ãæ¯æå¿
ãVOCã«è§Šããæ©äŒã確ä¿ãããŠãŒã¶ãŒèŠç¹ãç¶æãã çµå¶å±€ã«ãå
±æããæææ±ºå®ã«ãŠãŒã¶ãŒã®å£°ãåæ ãã éèŠãªèª²é¡ã¯ç¹°ãè¿ãäŒããèªèãæ·±ãã ãŸããSlackã«ãVOCãã£ã³ãã«ããèšç«ãããªã¢ã«ã¿ã€ã ã§ææ°ã®VOCãå
±æããéçšãéå§ãçŸåšã§ã¯ã»ãŒå
šå¡ããã£ã³ãã«ã«åå ããæçš¿ã«å¯ŸããŠãªã¢ã¯ã·ã§ã³ãéãŸã£ãŠããŸããäžæºã®å£°ã ãã§ãªãã奜æçãªè©äŸ¡ãããã ããVOCãçºä¿¡ããããšã§ãã¡ã³ããŒã®ã¢ãããŒã·ã§ã³åäžã«ãäžå®å¯äžã§ããŠããŸãã ããããåãçµã¿ã«ãã£ãŠããããã¯ãã«é¢ããå
šã¡ã³ããŒããæ¥åžžçã«ãŠãŒã¶ãŒã®å£°ãæèããç°å¢ãæ§ç¯ã§ããŸãããå®éã«ã瀟å
ããã¯ä»¥äžã®ãããªå£°ãå¯ããããŠããŸãã ãã¹ã¿ã³ãã€ã®ãŠãŒã¶ãŒãäœã«å°ã£ãŠããã®ããæ³åãããããªããŸãããã ãæèã®ãã¿ã«ãªããèŠéãåºããã®ã§å©ãããŸãïŒã ãèªåã®æ¥åããŠãŒã¶ãŒã«ã©ãçµã³ã€ããŠããã®ãã€ã¡ãŒãžãããããªã£ãïŒã 5. ä»åŸã®å±æ VOCãæŽ»çšããããŒã¿ããªãã³ãªæææ±ºå®ãž VOCã®ã¢ãã¿ãªã³ã°ãç¶ç¶çã«è¡ãããŠãŒã¶ãŒã®å£°ããèªã¿åããäž»èŠãªèª²é¡ãäžéãææ¡ããããšã¯ã§ããŸããããŸããã€ã³ã·ãã³ãçºçæãæ°æ©èœãªãªãŒã¹åŸã®ãã¬ãã£ããªåå¿ãå³åº§ã«æ€ç¥ãããããã¯ãéšéãžãã£ãŒãããã¯ããäœå¶ãæŽããŸããã ããããä»åŸã¯VOCãåãªããã£ãŒãããã¯ãšããŠã§ã¯ãªããå®éçã«è©äŸ¡ããROIïŒæè³å¯Ÿå¹æïŒã瀺ããåœ¢ã§æŽ»çšããããšãæ±ããããŸãã ã¯ãšãªåé¡ããšã®èª²é¡ãæç¢ºå ã¹ã¿ã³ãã€ã®ãŠãŒã¶ãŒå±€ã¯å€å²ã«ããããããããç°ãªã課é¡ãæã£ãŠããããšãæããããŸãããã®ãããVOCå
šäœã®åŸåã ãã§ã¯ãèŠå ã®ç¹å®ãé£ããå Žåãå€ãã§ããããå
·äœçãªèŠå ãæ¢ãããã«ããŠãŒã¶ãŒå±æ§ããšã®éããææ¡ããã©ã®èª²é¡ãæã圱é¿åã倧ããã®ããæç¢ºã«ããå¿
èŠããããŸãã VOCãšãŠãŒã¶ãŒææšãçµã³ã€ããåæ VOCãšãŠãŒã¶ãŒææšã®é¢é£æ§ã調æ»ããVOCã«çŸãã課é¡ãå®éã®å©çšããŒã¿ãKPIã«ã©ã®ãããªåœ±é¿ãäžããŠããã®ããåæããããšãäžå¯æ¬ ã§ããããã«ãããVOCã瀺ãåé¡ããããžãã¹ã«ãããŠã©ãã»ã©ã®ã€ã³ãã¯ããæã€ã®ããå
·äœçã«æ°å€ã§ç€ºããããã«ãªãã課é¡ã®å€§ãããšéèŠåºŠã枬ããŸãã ãŸããããããã¹ããŒãã£ã«åæããããã«ãã°ã«ãŒãå
ã«ããŒã¿åæãè¡ããã¡ã³ããŒãã¢ãµã€ã³ããŸãããåæäœæ¥ãä»éšçœ²ã«éœåºŠäŸé ŒããŠãããšãã¹ããŒãæã倱ãããŸããè°è«ãé²ããªãã仮説ç«ãŠããåæãã¹ããŒãã£ã«éçšã§ããäœå¶ããšã£ãŠããŸãã 6. ãããã« ãããŸã§ã®åãçµã¿ãéããŠããŠãŒã¶ãŒã®å£°ãå¯èŠåããæææ±ºå®ã«æŽ»ããåºç€ãæŽããŠããŸããã ä»åŸã¯ããã«äžæ©é²ããããããæ©èœããµãŒãã¹ã®ãªãªãŒã¹åŸã®åå¿ãVOCããçŽ æ©ãèªã¿åããäœå¶ã®æ§ç¯ãç®æããŸããããã«ããããŠãŒã¶ãŒã®ãªã¢ã«ãªåå¿ãå³åº§ã«ãã£ããããæ¹åãµã€ã¯ã«ãããè¿
éã«åãããšã§ããããã¯ãã®äŸ¡å€åäžã«ã€ãªããããšãå¯èœã«ãªããŸãã VOCã¯ãéèŠãªãŠãŒã¶ãŒãã£ãŒãããã¯ã§ããããããã¯ãæ¹åã®åååã§ãã ä»ããŠãŒã¶ãŒãäœã«å°ã£ãŠããŠãäœãæ±ããŠãããã«ã€ããŠãVOCãéããŠç¶ç¶çã«åéã»åæãããŠãŒã¶ãŒã«ãšã£ãŠæ¬åœã«äŸ¡å€ã®ãããµãŒãã¹ãæäŸããããšãç®æããŸãã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ããã«ã¡ã¯ãSearchã°ã«ãŒãã§æ€çŽ¢ãšã³ãžã³ã®éçºãéçšãæ
åœããå°éã§ãã ä»åã¯ãæ€çŽ¢ãšã³ãžã³Vespaã® Parent/Childæ©èœ ãæŽ»çšããŠåºåé
ä¿¡ãæ¹åããåãçµã¿ã«ã€ããŠç޹ä»ããŸãã ã¹ã¿ã³ãã€ã®æ€çŽ¢é£åååºå ã¹ã¿ã³ãã€ã®æ€çŽ¢çµæç»é¢ã«ã¯ä»¥äžã®2çš®é¡ã®æ ããããŸãã ç¡ææ²èŒæ : æ€çŽ¢æ¡ä»¶ãšã®äžèŽåºŠã«åºã¥ããŠæ±äººç¥šãæ²èŒ åºåæ : æ€çŽ¢æ¡ä»¶ãšã®äžèŽåºŠïŒãã£ã³ããŒã³ã®å
¥æéé¡ã«åºã¥ããŠæ±äººç¥šãæ²èŒ åºåäž»ã¯ãã£ã³ããŒã³ãèšå®ããããšã§ãåºåæ ã«èªç€Ÿã®æ±äººç¥šã衚瀺ã§ããŸãã ãã£ã³ããŒã³ã«ã¯ãã¿ãŒã²ãããšãªãæ€çŽ¢æ¡ä»¶ãå
¥æéé¡ãäºç®ãé
ä¿¡æéãªã©ãæå®ã§ããŸãã ç¡ææ ãšåæ§ã«æ€çŽ¢ãšã³ãžã³ã«ã¯Vespaãæ¡çšããŠãããæ±äººç¥šãšãã£ã³ããŒã³æ
å ±ãã€ã³ããã¯ã¹åãæ€çŽ¢åŠçãè¡ã£ãŠããŸãã é¢é£èšäº - ã¹ã¿ã³ãã€ã®åºå衚瀺ã«ãããããžãã¯ã«ã€ã㊠- æ€çŽ¢ãšã³ãžã³ãVespaãžç§»è¡ããŠããŸã ãã£ã³ããŒã³æŽæ°æã®èª²é¡ åºåé
ä¿¡çšã®Vespaã«ã¯ããŒã¿æ§é ã®åœ±é¿ã§FeedåŠçã«æéãããããšãã課é¡ããããŸããã åœåã¯æ±äººç¥šã®åäžã®ã¹ããŒãã§æ§æãããŠããããã£ã³ããŒã³æ
å ±ã¯æ±äººç¥šã«åã蟌ãŸããŠããŸããã # æ±äººç¥šã®ã¹ããŒãäŸ { "document_id": "id:default:campaign:1234", "job_title": "hoge", { "campaign_id": "1234", "start" : "2025/01/01", ... } ... } äžæ¹ãFeedåŠçã¯ä»¥äžã®ã±ãŒã¹ã§è¡ãããŸãã æ±äººç¥šã®æŽæ° ãã£ã³ããŒã³ã®èšå®æ
å ±ã®æŽæ° ãã£ã³ããŒã³ã®äºç®åãã«ããæŽæ° åé·ãªããŒã¿æ§é ã«ãããã£ã³ããŒã³æ
å ±ãæŽæ°ãããã³ã«ãé¢é£ãããã¹ãŠã®æ±äººç¥šãæŽæ°ããå¿
èŠããããŸããã äŸãã°ã1ãã£ã³ããŒã³ã«1äžä»¶ã®æ±äººç¥šãçŽã¥ããŠããå Žåã100ä»¶ã®ãã£ã³ããŒã³ãæŽæ°ãããš 100äžä»¶ã®æ±äººç¥š ãæŽæ°ããããšã«ãªããŸãã 10äžä»¶ã®æ±äººç¥šãæŽæ°ããã®ã«3åããããšãããšãå
šäœã®æŽæ°ã¯ 30å ããã£ãŠããŸããŸãã Vespaã®Parent/ChildãæŽ»çš Vespaã®Parent/Childæ©èœãå©çšãããšã芪åé¢ä¿ã®ããã¥ã¡ã³ããéå±€åã§ããŸãã åããã¥ã¡ã³ãã«èŠªããã¥ã¡ã³ãã®IDãæå®ããããšã§ãæ€çŽ¢æã«èŠªã®æ
å ±ãåç
§ã§ããŸãã ãŸãã芪ããã¥ã¡ã³ãã¯å
šã³ã³ãã³ãããŒãã«è€è£œããããããæ€çŽ¢ããã©ãŒãã³ã¹ãç¶æãã€ã€ãå¹ççãªFeedåŠçãå¯èœã«ãªããŸãã Vespa.ai Parent/Child ã¹ã¿ã³ãã€ã§ã¯ããã£ã³ããŒã³ã芪ããã¥ã¡ã³ããšããŠå®çŸ©ããæ±äººç¥šã®ã¹ããŒãã«ã¯èŠªãã£ã³ããŒã³ã®ããã¥ã¡ã³ãIDãåç
§ãã圢ã«å€æŽããŸããã # Parent-Childã䜿ã£ãããŒã¿æ§é äŸ ## ãã£ã³ããŒã³(芪) { "document_id": "id:default:campaign:1234", "campaign_id": "1234" "start" : "2025/01/01" ... } ## æ±äººç¥š(å) { "document_id": "id:default:job:abcd", "campaign_ref": "id:default:campaign:1234", import campaign_ref.start as campaign_start ... } ãã®å€æŽã«ããã ãã£ã³ããŒã³ã®æŽæ°æã¯ãã£ã³ããŒã³ã®ã¿æŽæ° æ±äººç¥šã®æŽæ°æã¯æ±äººç¥šã®ã¿æŽæ° ãšãã£ãæå°éã®æŽæ°åŠçãå¯èœã«ãªãããã£ã³ããŒã³ã®æŽæ°ã«ãããFeedåŠçæéã倧å¹
ã«ççž®ã§ããŸããã å
çšã®100ä»¶ã®ãã£ã³ããŒã³ã®æŽæ°ããäŸã§ã¯ãåŠçæéã æ°ç§ ãŸã§ççž®ãããŸãã å°å
¥æã®æ€èšŒãšèª²é¡ æ€çŽ¢æã®ã¬ã€ãã³ã·æ€èšŒ FeedåŠçã®å¹çåã¯ç¢ºèªã§ããŸããããæ€çŽ¢æã®ã¬ã€ãã³ã·ã«åœ±é¿ããªããæ€èšŒããŸããã çŽæ¥åç
§ãã鿥åç
§ã«ãªã£ãããšã§å°ãªãããæ€çŽ¢ããã©ãŒãã³ã¹ãæªåããæžå¿µãããŸããããè² è·è©Šéšã®çµæãã¬ã€ãã³ã·æªåã¯ã»ãŒçºçããŸããã§ããã Vespaå
¬åŒããã° ã§ã¯èŠªããã¥ã¡ã³ããšåããã¥ã¡ã³ãã®ä»¶æ°æ¯ãå°ããã»ã©ãããã©ãŒãã³ã¹ãžã®åœ±é¿ã倧ãããšèšåãããŠããŸãã ä»åã¯ããã£ã³ããŒã³ãšæ±äººç¥šã®ä»¶æ°æ¯ããšãŠã倧ãã(çŽ1:10,000)ãimportããé
ç®ãå°ãªãã£ããã圱é¿ã¯è»œåŸ®ã§ããã å§åçãªFeedã®å¹çåã«å¯ŸããŠãæ€çŽ¢ããã©ãŒãã³ã¹ã®æªåããªãããšã¯å€§ããªã¡ãªããã§ããã è€æ°ã¹ããŒãç§»è¡ã«ããèª²é¡ ãã£ã³ããŒã³çšã®ã¹ããŒãã远å ããããšã§ä»¥äžã®åé¡ãçºçããŸããã æ€çŽ¢ãããä»¶æ°ã®å€å ã¹ããŒãããšã®ãªãœãŒã¹æå®ãšã©ãŒ ãªãœãŒã¹äœ¿çšçã®å¢å Vespaã§ã¯ãããã©ã«ãã§å
šã¹ããŒãã«å¯ŸããŠæ€çŽ¢ãè¡ããããããè€æ°ã¹ããŒãã«ãªããšæå³ããªãæåãèµ·ããåŸãŸãã äŸãã°ãæ±äººç¥š(job)ã®æ€çŽ¢ã§RankProfileãæå®ããŠãããšãã£ã³ããŒã³(campaign)ã®ã¹ããŒãã远å ããããšã§ä»¥äžã®ãšã©ãŒãçºçããŸãã # ãšã©ãŒäŸ $ vespa query "select job_title from job where true" ranking=PiyoRankProfile â ãšã©ãŒçºç Source 'job': 4: Invalid query parameter: schema 'campaign' does not contain requested rank profile 'PiyoRankProfile' æ€çŽ¢å¯Ÿè±¡ã®ã¹ããŒããéå®ããã«ã¯ã restrict ãã©ã¡ãŒã¿ãå©çšããŸãã # ä¿®æ£ç $ vespa query "select job_title from job where true" ranking=PiyoRankProfile restrict=job â OK ç¹ã«ãšã©ãŒããªãå Žåã§ããrestrictæå®ããªããšç¡é§ãªãªãœãŒã¹ã䜿çšããŠããŸãããé©åãªæå®ãå¿
èŠã§ãã ãŸãšã Vespaã®Parent/Childæ©èœãå°å
¥ããããšã§ããã£ã³ããŒã³æŽæ°æã®FeedåŠçæéã倧å¹
ã«ççž®ã§ããŸããã ãŸããããŒã¿æ§é ãã·ã³ãã«ã«ãªã£ãããšã§éçºå¹çãåäžããŸããã ä»åŸãVespaã®æ©èœã掻çšãããããªãæ¹åãé²ããŠããããã§ãã æ€çŽ¢ãšã³ãžã³ã®éçºã«èå³ãæãããæ¹ã¯ã æ¡çšãµã€ã ãããæ°è»œã«ãåãåãããã ããã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ã¯ããã« ããã«ã¡ã¯ããããã¯ãéšSearchGã®å°éã§ãã ã¹ã¿ã³ãã€ã§ã¯æšå¹Žæ«ã¢ããã³ãã«ã¬ã³ããŒâ»ãéå¬ãåèš25æ¬ã®èšäºãæçš¿ããŸããïŒ æ¬èšäºã§ã¯ãã¢ããã³ãã«ã¬ã³ããŒãéå¶ããçµéšãããšã«ã¹ã ãŒãºã«é²ããããã®å·¥å€«ãæ¹åç¹ã玹ä»ããŸãã ããããã¢ããã³ãã«ã¬ã³ããŒãéå¶ããŠã¿ããæ¹ãã瀟å
ã§ã®æè¡çºä¿¡ã掻æ§åããããæ¹ã®åèã«ãªãã°å¹žãã§ãã ð ã¹ã¿ã³ã〠Advent Calendar 2024 â» ã¢ããã³ãã«ã¬ã³ããŒãšã¯? æ¯å¹Ž12æ1æ¥ãã25æ¥ãŸã§ã®æééå®ã§å±éãããèšäºæçš¿ã€ãã³ãã§ãã ã¯ãªã¹ãã¹ãŸã§ã®æ¥æ°ãã«ãŠã³ãããŠã³ããã¢ããã³ãã«ã¬ã³ããŒã®æ
£ç¿ã«ããšã¥ããŠãæ§ã
ãªããŒãã®ã«ã¬ã³ããŒãåããŠãã圢ã§èšäºãæçš¿ããŸãã ðåè: https://qiita.com/advent-calendar/2024 ã¢ããã³ãã«ã¬ã³ããŒã®äœçœ®ã¥ã ã¹ã¿ã³ãã€ã§ã¯ãæ®æ®µããããã¯ããã°ã§æ¥åã«é¢ããåãçµã¿ãåŠã³ã«ã€ããŠçºä¿¡ããŠããŸãã ã¢ããã³ãã«ã¬ã³ããŒããã®äžç°ã§ãããéåžžã®ããã¯ããã°ãšã¯ç°ãªãã æ¥åãšçŽæ¥é¢ä¿ããªãå人çãªåŠã³ ãªã©ã®çºä¿¡ãæšå¥šããŠããŸãã ããã«ãããå·çã®ããŒãã«ãäžããå€ãã®äººãã¢ãŠãããããéããåŠã³ã楜ãããäœéšã§ããããšãç®æããŸããã ã¢ããã³ãã«ã¬ã³ããŒéå¶ã®æµã ã¢ããã³ãã«ã¬ã³ããŒã®æºåããå
¬éãŸã§ã®æµãã¯ã以äžã®ããã«ãªããŸãã ð å
šäœã®æµã æºåïŒ11æäžæ¬ïŒ: éå¶ããŒã ã®çµæ åå è
åé: å
šäœåç¥ïŒåå¥å§èª å·çã»ã¬ãã¥ãŒ: é²æç®¡ç å
¬éïŒ12æ1æ¥ã25æ¥ïŒ: èšäºãå
±æ 1ïŒ æºå(11æäžæ¬) ã¢ããã³ãã«ã¬ã³ããŒã¯å¹Žã«äžåºŠã®ã€ãã³ãã®ãããå幎ã®ç¥èŠã倱ãããããã§ãã ãã®ããã ãã¬ããžãåŒãç¶ããããããä»çµã¿ ãæŽããããšãéèŠã§ãã ð éå¶ããŒã ã®åœ¹å² - æšå¹Žããã®åŒãç¶ã - ã¹ã±ãžã¥ãŒã«ã®ç¢ºèª - ã¢ããã³ãã«ã¬ã³ããŒã®äœæ - 管çã·ãŒãã®äœæ - ã¬ãã¥ã¢ãŒã®éžå®ã»äŸé Œ â
Tips1: éçšããã¥ã¢ã«ã®äœæ éå¶ããŒã ãã¹ã ãŒãºã«åããããã以äžã®æ
å ±ããŸãšããéçšããã¥ã¢ã«ãäœæããŸããã åå è
ã®éãæ¹ã®Tips åç¥ã®æäŸ 説ææã®ãã³ãã¬ãŒãäœæ ããã«ãããæ
åœè
ã®äº€ä»£ããã£ãå Žåã§ãåæ»ã«éå¶ãåŒãç¶ããããã«ãªããŸããã 2ïŒåå è
åé èšäºãæçš¿ããŠãããåå è
ãéããŸãã å
šäœåç¥ã«å ããŠãéå¶ããŒã ããåå¥ã«å§èªããããšããã€ã³ãã§ãã ð åéã®å·¥å€« å·çã®ããŒãã«ãäžããïŒéãé£æåºŠã¯åããªã åšå²ãå·»ã蟌ãïŒãã¿ããªã§äžç·ã«æžããïŒããšããé°å²æ°ãäœã æžãããŒãã®å¹
ãåºããïŒæè¡ã ãã§ãªãåŠã³ãçµéšè«ãæè¿ 3ïŒ å·çã»ã¬ãã¥ãŒ åå è
ãããããèšäºãäœæããå
¬éåã«ã¬ãã¥ãŒãäŸé ŒããŸãã éå¶åŽã¯å·çãã¬ãã¥ãŒãäœè£ãæã£ãã¹ã±ãžã¥ãŒã«ã§é²ãããã«é²æç®¡çãããŸãã â
Tips2: é²æç®¡çã®èªåå å
ã
ã¯ã¹ãã¬ããã·ãŒããéå¶ãç®ã§èŠãŠé²æç¢ºèªãåå¥ã«ããŠããŸããã ç· å管çãªãã€ã³ããŒãGoogle App Script(GAS)ã䜿ã£ãŠèªååããŸããã ð Googleã¹ãã¬ããã·ãŒãããé
ç® æçš¿äºå®æ¥ æ
åœè
èšäºã®äœæç¶æ³ ã¬ãã¥ãŒç¶æ³ ð GASãæŽ»çšãããªãã€ã³ãã®ä»çµã¿ èšäºå
¬éã®2é±éåã«ãé²æç¶æ³ã«å¿ãããªãã€ã³ããèªåã§Slackã«éç¥ äŸïŒ25æ¥ãå
¬éæ¥ãªã11æ¥ã«ãèšäºã®æºåç¶æ³ã¯ã©ãã§ããïŒããšãªãã€ã³ã éå¶ããããŸã ã§ããïŒããšå¬ä¿ããã®ã¯ç²Ÿç¥çã«ããã€ãã§ãããèªååã®ãããã§å¬ä¿ã¯äžèŠã«ãªããŸããã ã¹ã¿ã³ãã€ã§ã¯ãã®ä»ã«ãå€ãã®æ¥åãGASã§å¹çåããŠããŸãã é¢é£èšäº: Google Apps Script ã TypeScript ã«ç§»è¡ãã話 4. å
¬éïŒ12æ1æ¥ã25æ¥ïŒ èšäºã¯12æ1æ¥ããé çªã«èªåã§å
¬éãããŸãã ã¹ã¿ã³ãã€ã§ã¯ãSlackã® RSS Readerãå©çšããæ°ããèšäºãèªåæçš¿ãããããã«ããŸããã ð çãäžãã®å·¥å€« èªåæçš¿ã«å ããŠã(ä»åã¯ã§ããŸããã§ããã)æ¥æ¿ããã§éå¶ã¡ã³ããŒãä»ã®å·çè
ãèšäºã玹ä»ãããšãããæŽ»çºãªäº€æµãçãŸãããã§ãã æ¬¡åã«åã㊠2024幎ã®ã¢ããã³ãã«ã¬ã³ããŒã¯ãå€ãã®äººã®ååã®ãããã§ç¡äºã«å®èµ°ããŸããã ããããåããŠã®éå¶ãšããããšãããèšäºãåããããšã«ç²Ÿäžæ¯ã ã£ãé¢ããããŸãã äŸãã°ãåŸåæ¥çšã§ã¬ãã¥ã¢ãŒã®è² æ
ã倧ããã£ãããèšäºå
¬éãå§ãŸã£ãŠããã®çãäžãããè¶³ããªãã£ãããšèª²é¡ãèŠã€ãããŸããã ä»åŸã«åããŠã æç¶çã«éå¬ã§ããä»çµã¿ ã æŽã«çãäžããããã®ä»æã ãæŽããŠãããããšèããŠããŸãã ð ä»åŸåãçµã¿ããããš â
ãã¢ã¬ãã¥ãŒã®å°å
¥ïŒã¬ãã¥ã¢ãŒã®è² æ
ã軜æžïŒ â
ãªã¬ãŒåœ¢åŒã®ç޹ä»ïŒå·çè
å士ã§èšäºã玹ä»ãåãïŒ ãããã« ã¢ããã³ãã«ã¬ã³ããŒã®éå¶ãéããŠçµç¹ãšããŠã®å€éšçºä¿¡ãæšé²ãã貎éãªçµéšãã§ããŸããã 幎ã«äžåºŠã®ã€ãã³ãã§ã¯ãããŸãããéå¶ã®è² æ
ãæžããã€ã€çµç¹ãšããŠæŽã«çãäžããŠããããã§ãã ãŸãšãæ¬èšäºãã¢ããã³ãã«ã¬ã³ããŒã®éå¶ãèããŠããæ¹ã®åèã«ãªãã°å¹žãã§ãïŒ ãããããããã¯ããã°ãªã©ã®ã¹ã¿ã³ãã€ããã®çºä¿¡ããæåŸ
ãã ããð ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ãããã¯ãéšã®é«åã§ãã ä»å¹ŽåºŠã®äžåæã«ãç§ãã¡ãããã¯ãéšéã®ãããŒãžã£ãŒå
šå¡ã§ããããžã¡ã³ãããªã·ãŒããªããã®ãäœæããŠéšéå
ã«å®£èšãããšããæŽ»åãããŸããã ãã®æŽ»åã®ãèæ¯ãããããããã»ã¹ãäœæåŸã®ãããŸã§ãããããããªã©ã«ã€ããŠã話ãããããšæããŸãã ãããžã¡ã³ãããªã·ãŒãšã¯ Management Policy ãšãããšãçµå¶æ¹éããäŒç€Ÿãšç€Ÿå¡ã®çŽæäºããçµç¹ã®è¡åæéããªã©ãªã©ãããããæ¯ãå¹
ãããèšèã«ãªããŸããã»ã»ã» ç§ãã¡ãäœã£ãããããžã¡ã³ãããªã·ãŒãã®äœçœ®ã¥ãã¯ãããããŒãžã£ãŒãã¡ãã¡ã³ããŒã«å¯ŸããŠå®ãããçŽæäºããšãã衚çŸãé©åããªãšæããŸãã ä»ç€Ÿã®å
è¡äºäŸãåèã«ããŠäœæãããã®ã§ãäŸãã° amazon 瀟㮠Leadership Principles ãªã©ãåèã«ããŸããã ãããã¯ãéšéã®ãããŒãžã£ãŒããèªåã管æããŠããã°ã«ãŒãã ãã§ãªãéšéå
šäœã®çµç¹éå¶ã«åãçµãã¹ã¿ã³ã¹ã瀺ããã®ãšããŠã次ã®7é
ç®ãæ²ããŠããŸãã 1人1人ãã¹ã¿ã³ãã€ã®æªæ¥ãèªããçµç¹ãž 匷ã¿ãåŒãåºãå¯èœæ§ãæ¡ããç°å¢ã¥ãã 圹å²éè¡ã®ãµããŒã 誰ããèªåãããæèŠãåºããä»çµã¿ã¥ãã æææ±ºå®ã®éææ§åäž å
šç€Ÿã暪æãããããžã¡ã³ãæèãæã€ å
±ã«äºæ¥ãã€ãã仲éãå¢ãã 7ã€ã®çŽæäºããããã«å
·äœçãªã¢ã¯ã·ã§ã³ã瀺ããµãããã¹ããæ·»ããŠããŠãäž»èªã¯å
šãŠããããŒãžã£ãŒã¯ãã«æããŠããŸãã 以éã§ã¯ãç§ãã¡ããªããã®ãããªãããžã¡ã³ãããªã·ãŒãäœã£ãã®ãïŒããŸãããã®ãããžã¡ã³ãããªã·ãŒãã©ã䜿ãããšããŠããã®ãïŒãªã©ããäŒãã§ããã°ãšæããŸãã åæç¶æ³ ãŸããã話ã®èå°ãšãªããããã¯ãéšéã®çµç¹æ§é ã«ã€ããŠå
±æããŠãããããšæããŸãã çŸåšã®éçºçµç¹äœå¶ åœç€Ÿã®ãããã¯ãéšéã¯ãæ±ãæè¡ãã¡ã€ã³ãŸãã¯ããžãã¹ãã¡ã€ã³ã«ããç·åŒãã«ãã£ãŠéçºã°ã«ãŒããåå²ããŠããŸãã ããŒã ããããžãŒã®èãæ¹ã«è¿ããèªç¥è² è·ãèæ
®ããçµç¹äœå¶ãæ¡çšããŠããŸãã 以åã®èšäº ïŒãããã¯ãéçºäœå¶ã®ãããŸã§ãšãããã - Stanby Tech BlogïŒ ã§æžããŠãããæè¡ãã¡ã€ã³ã®æ§æã€ã¡ãŒãžããšåãæ¹éã§ç¶ç¶ããŠããŸã å³ã®æ©èœçŸ€ãããéçºã°ã«ãŒãã®ã»ãã现ååãããŠããŸã ããã«ä»å¹ŽåºŠããããããã®éçºã°ã«ãŒãã®ãããŒãžã£ãŒå
šå¡ãå
Œåæå±ãããçµç¹éå¶ã°ã«ãŒãããšããçµç¹ãèšããŠãã°ã«ãŒããéšéã®ãããžã¡ã³ããååããŠè¡ãäœå¶ããšã£ãŠããŸãã â»ã¡ã³ããŒå
šå¡ãå
Œåã§æãç«ã£ãŠããçµç¹ã®ãããéšéå
ã§ãããŒãã£ã«çµç¹ããšåŒãã§ããŸã ãã®çµç¹éå¶ã°ã«ãŒãã®ããã·ã§ã³ã«ã¯æ¬¡ã®ãããªãã®ãæ²ããŠããŸãã äºæ¥ãã§ãŒãºã®å€åã«å¯Ÿå¿ããŠææãæå€§åã§ããçµç¹ã®ä»çµã¿ã¥ãã ãããã¯ãã¡ã³ããŒã®æºè¶³åºŠåäž ãªãã仿ïŒ2024幎床ïŒã®æ³šåãã€ã³ãã¯æ¬¡ã®ããã«ãªã£ãŠããŸãã ããã§ã話ãããå
容ã¯ããããã¯ãéšéã®ãããŒãžã£ãŒå
šå¡ã®æŽ»åã®èšé²ã§ãããããã¯ããªãã¡çµç¹éå¶ã°ã«ãŒãã®æŽ»åã®èšé²ãšããããšã«ãªããŸãã ãããžã¡ã³ãããªã·ãŒãäœã£ãçµç·¯ ãªãäœã£ãã®ãïŒ äžèšã®ããã«ä»æããçµç¹éå¶ã°ã«ãŒããšããããŒãã£ã«çµç¹ã§åãåºããŸããããåœåã¯ã°ã«ãŒãéã§æ
å ±å
±æãä¿ããŠãã»ãšãã©äœãåºãŠããŸããã§ããããŸããã°ã«ãŒãéãæšªæããå
±é課é¡ã«ã€ããŠè©±ããŠããŠããèªåããšåïŒèªåãã¡ããšåïŒïŒã§ããŠããå²åãäœããã«æããŠããŸããã ãããããªçç±ãèããŸããã èªã°ã«ãŒãã®çµç¹ãšãããã¯ãéçºã®ãããžã¡ã³ãã§æäžæ¯ã ãã èªã°ã«ãŒããä»ã°ã«ãŒãã®ããšã話ãããšã§ã¡ãªããããããšæããªããã ãããŒãžã£ãŒãŸã§ç»ã£ãŠããèªè² ãããã®ã§ä»äººã«ãšãããèšãããããªããã åãããŒãžã£ãŒã®è²ã£ãŠããç°å¢ãéããã ç¹ã«ãåãããŒãžã£ãŒã®è²ã£ãŠããç°å¢ãéããããšã«ã€ããŠã¯ãã¡ãã£ãšèãããåããããšãªã®ã«ããããŸã§ããŸãæèã§ããŠããªãã£ãããšã«æ°ä»ããŠãããšããŸããã ç§ãå«ãããããŒãžã£ãŒã®ã»ãšãã©ã2020幎ã®ãžã§ã€ã³ãã»ãã³ãã£ãŒçºè¶³åŸã®å
¥ç€Ÿã§ããããŸã§ã¯åã
ãããããã®ãã£ãªã¢ãçµããªãã§ãªãŒãã£ã³ã°ããããžã¡ã³ãã®çµéšãç©ã¿éããŠããŠããŸããããã«ãããããã®ãããŒãžã£ãŒãæã£ãŠããæåïŒå€±æã®å®çŸ©ãšãçæ³åã®èªèãšãã«ãã£ããå·®ç°ããããããããªãã»ã»ãšããããšã«æãè³ããŸããã äžéå
¥ç€Ÿè
ãããã«ãããžã¡ã³ããæ
ã£ãŠããã®ã¯ã¹ã¿ãŒãã¢ãããªãã©ãã䌌ãç¶æ³ã§ãããããã¹ã€ã«ãããŒãžã£ãŒã ãã«ç¹åãã話ã§ããªããšæããŸããããªãã§ãããããžã¡ã³ããæèã§æåãèªèã®å·®ç°ãåãããããªãªã³ããŒãã£ã³ã°æœçãè¡ããŠããããšãããšé
æ
®ãèãã£ãããšã«æ°ä»ããŸããã ã€ãŸããäºæ¥ããããã¯ãã«çŽçµãããããžãã¹ãã¡ã€ã³ãããæè¡ãã¡ã€ã³ãã®ã³ã³ããã¹ããåãããç®çã§ã®ãªã³ããŒãã£ã³ã°æœçã¯æèçã«è¡ããŠãããã§ãããããã«æ¯ã¹ããšãçµç¹ãããžã¡ã³ãæèã§ã³ã³ããã¹ããåãããæŽ»åã¯ããŸãæèçã«è¡ããŠããªãã®ã§ã¯ïŒå°ãªããšãèªåã®æèã¯åŒ±ãã£ãïŒãšããããšãžã®æ°ã¥ãããããŸããã ïŒçµç¹ãããžã¡ã³ããã©çãäžã®åœ¹å²ãé ãã£ãŠãããªããã»ã»ã»ãæ¥ããããã§ããïŒ å
±æã§ããç®æšãå
±éèšèªãã»ããïŒ ããããŠãåãããŒãžã£ãŒã®è²ã£ãŠããç°å¢ãéãããã®ãéããã«æ°ã¥ããããšã§ã»ã» ããŒã äžäžžãšãªã£ãŠããã©ãŒãã³ã¹ãé«ããŠããããã«ã¯ãããŒã ã®ããã¹ãå§¿ãããããŒã ã®ç®æšããå
±æããããšãéµã«ãªã ãšããããããŸã§ã¹ã¯ã©ã ãã¹ã¿ãŒãšããŠäœåºŠãäŒããŠããŠããããšãèªåã«è·³ãè¿ã£ãŠããæããããŸããã ãããŠããããŒãžã£ãŒéã§ ToBe ãç®æšãšãã£ãå
±éèšèªã¥ãããç®æãããšã«ããŸããã ãã以å€ã®3ã€ã®çç±ã«è©²åœããŠãããšããŠããToBeãç®æšãšãã£ãå
±éèšèªãäœãããšãæ¹åã®éµã«ãªããšèããŸããã èªã°ã«ãŒãã®çµç¹ãšãããã¯ãéçºã®ãããžã¡ã³ãã§æäžæ¯ã ãã èªã°ã«ãŒããä»ã°ã«ãŒãã®ããšã話ãããšã§ã¡ãªããããããšæããªããã ãããŒãžã£ãŒãŸã§ç»ã£ãŠããèªè² ãããã®ã§ä»äººã«ãšãããèšãããããªããã ã©ããã£ãŠäœã£ãã®ã ãã®å
±éèšèªã¥ããããç®æšææç©ã«ããããžã¡ã³ãããªã·ãŒãã眮ããŠé²ãããšããçµç·¯ã§ãã ãã®éçšã端çã«è¡šçŸãããšã»ã» ãããŒãžã£å
šå¡ã§ãããã¯ãçµç¹ããžã§ã³ãèªç«åçµç¹ãã®å åãæŽãåºããŠãããããå®çŸããããã«ãæã
ãããŒãžã£ãŒã«æ±ããããè¡åãå§¿å¢ãèšèªåããã ãšããããšã«ãªããŸãã ãããããã蟿ã£ãŠããããã»ã¹ã詳ãã説æãããšæ¬¡ã®ããã«ãªããŸãã ïŒæ§æèŠçŽ ã®æŽãåºããã§ãŒãºïŒ Step1 - ToBeã§ããçµç¹ããžã§ã³ãèªç«åçµç¹ãã®èªèåãã Step2 - ToBeãå®çŸããŠããç¶æ
ã®ã€ã¡ãŒãžãå
·äœå ïŒå
±éèšèªåãã§ãŒãºïŒ Step3 - Gapã®æŽãåºã Step4 - GapãåããŠããç»ãæ¹ãæ€èš 以äžãStepããšã«è¡ã£ãäœæ¥ã€ã¡ãŒãžã®ç޹ä»ã詊ã¿ãŸãã â»æ¬æäžäœåºŠãšãªãç»å Žãããããã¯ãçµç¹ããžã§ã³ãèªç«åçµç¹ãã¯ã以åã®èšäº ïŒãããã¯ãéçºäœå¶ã®ãããŸã§ãšãããã - Stanby Tech BlogïŒ ã§ã玹ä»ããŠããŸã Step1 - ToBeã§ããçµç¹ããžã§ã³ãèªç«åçµç¹ãã®èªèåãã åã èªç«åçµç¹ã圢ã¥ããå åïŒèŠçŽ ïŒã«ã¯ã©ããªãã®ããããïŒ é²ãæ¹ é±æ¬¡ã®å®äŸããŒãã£ã³ã°ãäœé±ã䜿ã£ãŠ å人ã¯ãŒã¯âå
šäœå
±æãšããæµããäœåºŠãè¡ãæ¥ããŠé²ããŸããã åãããŒãžã£ãŒã®å人ã¯ãŒã¯ã§ãèªç«åçµç¹ãã®å®çŸ©ãèªã¿çŽããŠãããããèªç«åçµç¹ã圢ã¥ããå åããæŽãåºããŠããã£ãŠãããå
šå¡ã§æš¹åœ¢å³ã®ããã«ãããã³ã°ããããšã§ MECE ã«ãªãããæŽçã詊ã¿ãŸããã Step2 - ToBeãå®çŸããŠããç¶æ
ã®ã€ã¡ãŒãžãå
·äœå åã èªç«åçµç¹ãå®çŸãããã©ãããç¶æ
ã«ãªã£ãŠããã ãããïŒ é²ãæ¹ é±æ¬¡ã®å®äŸããŒãã£ã³ã°ãäœé±ã䜿ã£ãŠ å人ã¯ãŒã¯âå
šäœå
±æãšããæµãã§è¡ããŸããã Step1ã§æŽãåºããå åããšã«ãèªç«åçµç¹ãå®çŸããç¶æ
ããæ³åããŠèšèªåããŠãããããšã§ãããè§£å床ã®é«ã ToBe ç¶æ
ãå
±æããããšãç®æããŸããã Step3 - Gapã®æŽãåºã åã ç§ãèªç«åçµç¹ãå®çŸãããçç±ã¯ïŒ èªç«åçµç¹ã®å®çŸã«åããŠãç§ãã¡ãæ
ãã¹ã圹å²ã¯ïŒ é²ãæ¹ ãã€ãã®ãªãã£ã¹ãé¢ããŠéå¬ãããã³ã°ããŒãã£ã³ã°ïŒ1æ¥å宿ïŒã®ååã§ å人ã¯ãŒã¯ã§è¡ããŸããã å
ãããªã¹ããŒãªãŒãã¯ãŒã¯ãšããŠããããŒãžã£ãŒ1人1人ãèªç«åçµç¹ãç®æãããçç±ãåŸãããã¡ãªãããåèªã®äŸ¡å€èŠ³ã«æ²¿ã£ãŠèšèªåããŠããã£ãããã§ïŒå³ã®å·ŠåŽïŒããã®ç¶æ
ãŸã§ã® Gap ãã©ãåããŠãããšãããïŒåããŠãããããïŒãèšèªåããã¯ãŒã¯ãè¡ããŸããã è³æã§ã¯æç€ºããŠããŸããããäž»èªããå
ããç§ãã§èããããšãç§ãã¡ãã§ååããŠé²ãã§ããã€ã¡ãŒãžãžãšåºããæèã§é²ããŸããã Step4 - GapãåããŠããç»ãæ¹ãæ€èš åã ãèªç«åçµç¹ãã® Asis / Tobe ã® Gap ãã©ãåãããã®è°è«ãšèšèªå é²ãæ¹ ãã€ãã®ãªãã£ã¹ãé¢ããŠéå¬ãããã³ã°ããŒãã£ã³ã°ïŒ1æ¥å宿ïŒã®åŸå 4人ã²ãšçµãããã«çåããããŠã°ã«ãŒãã¯ãŒã¯ âå
šå¡ã§æèšã®çµ±åãšæŽç·Žãã鱿¬¡ã®å®äŸããŒãã£ã³ã°ã 2-3åãã㊠Step3ã§èšèªåãããèªç«åçµç¹ãžã® Gap ãã©ãåããŠãããšãããããæã¡å¯ã£ãŠãã°ã«ãŒãã¯ãŒã¯ã§ã¡ãã»ãŒãžã©ã€ã³ãäœæããŸããã ãããã¯ããªãã¡ãããŒãžã£ãŒããšãã¹ãè¡åã ãããšããããšã§ããããŒãžã£ãŒå
šå¡ã§éçŽããæèšããã©ãã·ã¥ã¢ããããŠãæçµåœ¢ãããããžã¡ã³ãããªã·ãŒããšããŠå®æãããŸããã ãããã®ããã»ã¹ãäžç·ã«éãæããŠããããšã§ãç®æãçæ³åã®èªèãåã£ãŠããããå
±é課é¡ã®èªåããšåãé²ãã ãããšããããã£ã广ãçã¿åºããããã«æããŸãã ãããžã¡ã³ãããªã·ãŒãã©ã䜿ãããã ããããŠäœã£ãããããžã¡ã³ãããªã·ãŒããã©ã䜿ã£ãŠãããããšèããŠããŠãå®éã©ã䜿ã£ãŠããŠãããã®ãããã®ã話ãããããŠããã ããããšæããŸãã for ãããŒãžã£ãŒ ããããŒãžã£ãŒã®çŽæäºããšããŠæç€ºããããšã§ã»ã» ãããŒãžã£ãŒãšããŠã®åãã«è¿·ã£ãéã«ãããã¹ãå§¿ãã«ç«ã¡è¿ãæéã«ã§ãã ãããŒãžã£ãŒéã§ãããžã¡ã³ãããªã·ãŒãšããå
±éèšèªãããŒã¹ã«è°è«ãã§ãã ã¡ã³ããŒããææãåããŠæããµããçŽãããšãã§ãã for ãããŒãžã£ãŒä»¥å€ã®ã¡ã³ã㌠ããããŒãžã£ãŒã®çŽæäºããšããŠæç€ºãããŠããããšã§ã»ã» ãããŒãžã£ãŒã®è¡åãæ¯ãèãã®èæ¯ãç¥ãã ãããŒãžã£ãŒã®è¡åãæ¯ãèãã«å¯ŸããŠçåãæããå Žåã«ææãããã ããªã·ãŒèªäœãèªåãæåŸ
ããŠããããšãçµç¹æ¹éã®çè§£ãšãºã¬ãŠãããšæããå Žåã¯ããããŒãžã£ãŒã«èª¬æãæ±ããã倿Žã®ææ¡ãã§ãã for ãããããããŒãžã£ãŒã«ãªã人ã远å ã 瀟å
ã§ãããããããŒãžã£ãŒã«ãªã人ã»ãããŒãžã£ãŒã®ä»äºã«é¢å¿ããã人ã«ãšã£ãŠ ãããŒãžã£ãŒã¯ã©ãããè¡åãæ±ããããããå£éèŠãã ãããŒãžã£ãŒãç®æãéã®åŠç¿ãè¡åã®å
·äœçãªã€ã¡ãŒãžãæãŠã â»ããã¯åœæãªãããŠã®ãããŒãžã£ãŒããããã£ãã³ã¡ã³ãã«æ°ã¥ããåŸãŠãåŸãã远å ããé
ç®ã§ããæ£çŽåœåã¯ãããŸã§èæ
®ã§ããŠããŸããã§ããããæãé£ãææã§ããã ãã ãã»ã»ã»ãããã¯å
šãŠãç§ãã¡äœãæåŽã®æãã§ãã 以éã§ã¯ãå®éã«ãããžã¡ã³ãããªã·ãŒãçãã©ãã䜿ã£ãŠããããšã«åãåã£ãŠãã話ããããŠããã ããŸãã ãããžã¡ã³ãããªã·ãŒãäœã£ãŠãããããŸã§ 説æäŒãéå¬ãããã£ãŒãããã¯ãåŸã çŽåã«æãããšããããããžã¡ã³ãããªã·ãŒã¯ããããŒãžã£ãŒä»¥å€ã®ã¡ã³ããŒã«ããã£ããç¥ã£ãŠãããŠã»ãããã®ã§ããããã§ããã€ãã®èªç¥æ©äŒãèšããŸããã ææ¬¡ã®ããããã¯ãå
šäœäŒãã§äœæããããšãšå
容ãšãå ±å å ããŠãä»»æåå ã®ããããžã¡ã³ãããªã·ãŒèª¬æäŒããéå¬ èª¬æäŒã§ã¯ããã®èšäºã«æžããŠãããããªãèæ¯ãäœæããã»ã¹ã䜿ãããã®æåŸ
ãªã©ã話ããŠã質çå¿çã®æéãèšããŸããã çµæçã«ã説æäŒã®æéã«çªã£èŸŒãã 質åã¯ããããªãã£ãã®ã§ããã»ã»ã»æ°æ¥åŸã説æäŒã«åå ããŠãããŠããã¡ã³ããŒãš 1on1 ããã£ãã®ã§ãããã©ãæããŸããïŒããšå°ãããšããã»ã»ã» ããããã®ã£ãŠãäœã£ãŠçµãããã«ãªãããšãå€ããšæããã§ã»ã»ã»äœ¿ããŠããããã©ããã£ãŠãµãããããã倧äºã§ãããïŒ ãšããªããªãéãããã³ããåããããšãã§ããŸããã ç§ãããããžã¡ã³ãããªã·ãŒãæèããŠäœ¿ããŠããããšããæŽæ°ããå¿
èŠããªããã®å®æçãªãã§ãã¯ãããããšã¯å€§åã ãããšæã£ãŠã¯ããã®ã§ããã»ã»ã» äœæããŠèª¬æäŒãŸã§èµ°ãæãããšããã§ãæ£çŽãããäžæ®µèœãããæãã§æ°ãç·©ã¿ããã«ãªã£ãŠããã®ã§ããã®èšèã§äžæ°ã«èº«ãåŒãç· ãŸããŸããã ãã®ããšããã£ãŠãç·åŒµæãä¿ã£ããŸãŸã¢ãã¿ãªã³ã°ã®è°è«ãç¶ããããšãã§ããããã«æããŸãã ã¢ãã¿ãªã³ã°ã®è°è« ãããžã¡ã³ãããªã·ãŒã«æ²¿ã£ãŠè¡åããææãæž¬ã芳ç¹ã§ã¯ããšã³ã²ãŒãžã¡ã³ããµãŒãã€ã®ã¹ã³ã¢ãã¢ãã¿ãªã³ã°ããããšãããã«æ³èµ·ã§ããŸããã ã©ã® Gap ãåããããã« â ã©ã®ã¹ã³ã¢ã®æ¹åãç®è«ãã§ â ã©ãã¢ã¯ã·ã§ã³ãããïŒãšããçŽä»ããã§ããã°ãã¢ã¯ã·ã§ã³ååŸã®æšç§»ãã¿ãŠã¢ãã¿ãªã³ã°ã§ãããã§ããããããããšã³ã²ãŒãžã¡ã³ããµãŒãã€ã®ã¹ã³ã¢ã«èª²é¡æãããå Žåã«ã¯ããã®ã¹ã³ã¢ãã¿ãŒã²ãããšããŠæ¹åã¢ã¯ã·ã§ã³ãæ€èšã»å®è¡ãããšããããã¡ã§ããããã§ãã éã«ã1ã€ã®ã¹ã³ã¢ã¯è€åçãªèŠå ãã圱é¿ãåããã¯ããªã®ã§ããããã¢ã¯ã·ã§ã³ããã°âãã®ã¹ã³ã¢ãäžããããšããæ¹åã§çŽä»ããã®ã¯é£ãããã§ãã ãŸãããµãŒãã€ã¹ã³ã¢ã«å¹æãåºãã«ã¯æéããããããããªãããã®å
è¡ææšãã¢ãã¿ã§ããªããïŒãšããè°è«ãå§ãŸã£ãŠããŸãã ããè¡åãã¿ãããŠãããšãè¡åãå€å®¹ãããšããæž¬ãããšãèããããŸãããäžæã«è¡åã«çŸããããšã远æ±ãããããšæ¬æ«è»¢åãããªã¹ã¯ãããããã§ãã ãã°ããæ€èšããŠãããªãã§ããŸããæã
ãããŒãžã£ãŒèªèº«ããããžã¡ã³ãããªã·ãŒã®åé
ç®ãæèããŠå®è·µã§ããŠãããïŒãšããã»ã«ããã§ãã¯ãã詊ã¿ãå§ããŠããŸãïŒè¶
å
è¡ææšãšèšãããããããªããã®ã®è¶
䞻芳çãã€å®æ§çã§ããïŒã ãããžã¡ã³ãããªã·ãŒã®æŽ»çš äœã£ãŠããçŽ6ãæããããžã¡ã³ãããªã·ãŒãå
ã«æ¬¡ã®ãããªããšãè¡ã£ãŠãããŸããã çµç¹éå¶ã°ã«ãŒãã®ç®æšèšå® ãããžã¡ã³ãã»ã¢ã¯ã·ã§ã³ã®ããã¯ãã°ãå
±æããŠå®äŸããŒãã£ã³ã°ã§æŽæ° æ°ä»»ãããŒãžã£ãŒã®ãªã³ããŒãã£ã³ã°ã»ãã·ã§ã³ãéå§ å
ã«ããããžã¡ã³ãããªã·ãŒãã©ã䜿ããããïŒãã§æããŠããããšããå°ãã¯äœçŸã§ããŠãããšãããšæããŸãã ãããŸã§ã®ãµãããããšä»åŸã«åã㊠ãµãããã ãããŒãžã£ãŒå
šå¡ã§ãããžã¡ã³ãããªã·ãŒãäœã£ãããšã§ãå
±éèšèªãåŸãããšãã§ãããã®åŸã¯æ¬¡ç¬¬ã«ãããŒãžã£ãŒéã§äžç·ã«ã¢ã¯ã·ã§ã³ã§ããŠããæ°ãããŸãã ãããŠãåœåã¯ãè²ã£ãŠããç°å¢ãéããããšããã¡ãªããã«æããŠããŸããããä»ãã倿§ãªçµéšãã倿§ãªèŠç¹ãæã¡èŸŒãã§ããããããšïŒDiversityïŒã«ã¡ãªãããæããããšãã§ãå§ããŠããŸãã å®äŸããŒãã£ã³ã°ã§ã®åã°ã«ãŒãã®æŽ»åãåé¡ç¹ã®å
±æããã ãããé »åºŠãå¢ããŠãããšæããŸãã ä»åŸã®èª²é¡ ã¢ãã¿ãªã³ã°ã«ã€ããŠã¯ãå§ããã°ããã®ãããŒãžã£ãŒã®å®è·µã»ã«ããã§ãã¯ãç¶ãã€ã€ãä»åŸã¯ããã客芳çãªã¢ãã¿ãªã³ã°ãæ€èšããŠãããããšæããŸããå
ã«æžãããè¡åå€å®¹ãšã®çŽä»ããã¢ãã¿ãªã³ã°ãç¹å®ã®é åã«ã¯ããããããããªãã®ã§ãåŒãç¶ãè°è«ããŠä»®èª¬æ€èšŒããŠãããã°ãšæã£ãŠããŸãã ãŸããçµç¹ã俯ç°çã«ã¿ãŠïŒã·ã¹ãã æèã§ïŒã¢ãããŒããã¹ããã€ã³ããæ¢ãå¿
èŠãããã®ã§ã¯ãšèããŠããŸãããããã£ãè°è«ã®éãããããžã¡ã³ãããªã·ãŒã«ç
§ããåãããªããé²ãããããšãããšèããŠããŸãã ãæŠåšãæã«å
¥ããããšèšããšæ§æ¥ã®è»äºçäžç芳ã®çµç¹è«ã«èããããããããŸããããä»åããããžã¡ã³ãããªã·ãŒããäœããããšã¯ãçµç¹ãããžã¡ã³ãã«å¯Ÿããç®ç·ãåãããããã®ããªããªã匷åãªããŒã«ãæã«å
¥ããæèŠããããŸãã ãšããããã§ãé·æã«ãªããŸããããæåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã ãã®ãããªçµç¹ã®è©±ãããŸããå ±åã§ãããšå¬ããã§ãã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ã¹ã¿ã³ãã€ã¢ããã³ãã«ã¬ã³ã㌠2024 ã® 12/24 ã®èšäºã«ãªããŸãã ãããã¯ãéšã®èŸ»ã§ãã ã¹ã¿ã³ãã€ã§ã¯äºæ¥ã®æé·ã»æ¡å€§ããã³äžé·æçãªäºæ¥ç¶ç¶ã®ãããæ©èœéçºã«å ããŠæè¡çãªæ¹å掻åãããã€ã宿œããŠãããŸãã ãã®èšäºã§ã¯2024å¹Žã®æ¯ãè¿ããå
ŒããŠãæè¿ã®ã¹ã¿ã³ãã€ã®æè¡çãªåãçµã¿ãããã€ã玹ä»ããŸãã åãçµã¿å
šäœã®æŠèŠ æšå¹ŽåºŠä»¥åããç¶ç¶ããŠãããã®ãå«ããã¹ã¿ã³ãã€å
šäœã§ã¯ ã»ã³ã¹ãæé©å ã»ã·ã¹ãã ã®ãªã¢ãŒããã¯ã㣠ã»éçºå¹çãäžããããã®ããŒã«ãªã©ã®å°å
¥ ãé²ããŠããŸããã ã³ã¹ãæé©å ã¹ã¿ã³ãã€ã¯ãµãŒãã¹ã®ã€ã³ãã©ã« AWS ãå©çšããŠããŸãã ããšããšã€ã³ãã©ã³ã¹ãã¯èª²é¡ã§ã¯ãã23幎床ã察å¿ãããã®ã§ãããæšä»ã®åŒ·ãåå®ã®åœ±é¿ãããã€ã³ãã©ã³ã¹ãã®èª²é¡ã倧ãããªã£ãŠããŠããããã24幎床ã®ååã¯ç¹ã«å
šäœã§åªå
床ãäžããŠæ¹ããŠå¯Ÿå¿ãé²ããŸããã ãã ãã³ã¹ãåæžïŒãšãã圢ã§éé²ã«é²ããŠããŸããšãã·ã¹ãã ã®é害ã«ç¹ãã£ãããéçºæŽ»åã®å¹çãå質ãäžãã£ãããSavings Plans ã®äžé©åãªè³Œå
¥ã«ããé·æéåæžã§ããªãç¡é§ãªã³ã¹ããçºçããããšãã£ãåé¡ãèµ·ãããªã¹ã¯ããããããæ
éã«èª¿æ»ãæ€èšãããŠé²ããŸããã ç¹ã«ã¯éçºæŽ»åã®å¹çãå質ãäžããïŒãšã³ãžãã¢ã®èŠåŽãéå°ã«å¢ããããå¶çŽäºé
ãå¢ããïŒãããªåæžãé²ããŠããŸããšæ¬æ«è»¢åã«ãªãã®ã§ãåãçµã¿ã®åŒã³åã "åæž" ã§ã¯ãªã "æé©å" ãšãããªã©ãè¯ããªãæ¹åã«è¡ããªãããã«æèããªããã¿ããªã§é²ããŸããã ã¹ã¿ã³ãã€ã§ã¯åé åããšã®éçºããŒã ãã¹ã¯ã©ã ãçµãã§éçºæŽ»åãããŠããŸãã ãã®ãããå
šäœã®ç®æšãšæ¹éãå
±æããäžã§ãåããŒã èªèº«ãèªç«çã«ã³ã¹ãç®æšãšæé©åæœçãç«æ¡ã宿œããŠãããŸããã å ããŠå
šéçºããŒã ã®ä»£è¡šãæãå®äŸäŒè°ã®å Žãªã©ãé©å®æŽ»ãããåçš®çžè«ãããŒã é調æŽãªã©ãã¹ã ãŒãºã«é²ããããŸããã å
·äœçãªåããŒã ã®ç®æšèšå®ãšæœç宿œææã«ã€ããŠã¯ãããããŠã³ã§ã¯ãªãããã ã¢ãããããŒã¹ãšãã圢ã§é²ãããããæçµçã«ç®æšéæã§ããã®ããšããæžå¿µã¯æåã«åºãŸããããåããŒã ãå
šäœç®æšãæèãã€ã€ããŒã éã§é£æºããªããåãçµã¿ãå
šäœã§ç®æšãè¶
ããéé¡ã®ã³ã¹ãæé©åãéæã§ããŸããïŒ äž»ãªå®æœæœçã®æŠèŠã¯ä»¥äžã«ãªããŸãã ã»æ±äººããŒã¿ãšãã®æŽæ°ã管çãã巚倧 DB åšãã®ã³ã¹ãåæž ãã»DB ã®ã¯ã©ã¹ã¿ãŒåæ§ç¯ã«ãã容éåæžããªã¶ãŒããã€ã³ã¹ã¿ã³ã¹ã®æŽ»çš ãã» Aurora MySQL ã®ã³ã¹ãã 54% åæž ã®èšäºã®ä»¶ãæã广ã倧ããã£ãæœç ã»ECS, EKS ã§åãã¢ããªã®ãªãŒãã¹ã±ãŒã«ã®èšå®ããªãœãŒã¹ãµã€ãºã®èŠçŽã ã»S3 ã®ä¿åããŒã¿ã粟æ»ããå®å
šãªç¯å²ã§äžèŠããŒã¿ã®åé€ãã©ã€ããµã€ã¯ã«ã®èšå®ïŒäžéšã¯ Intelligent-Tiering ãå©çšïŒ ã»Compute Savings Plans ã®è¿œå 賌å
¥ ãã»ä»åŸã® EC2, ECS, Lambda ãªã©ã®ãªãœãŒã¹ã®å¢æžäºæž¬ãã¢ãã¿ãªã³ã°ïŒåéçºããŒã ãžã®ãã¢ãªã³ã°ã§ç²ŸåºŠé«ãèŠç©ããã远å 賌å
¥ ãã»ã«ããŒçã 50% çšåºŠã ã£ããã®ã 80% çšåºŠãŸã§ã¢ãã ã»æ€çŽ¢ãšã³ãžã³ Vespa ã§å©çšãã EC2 ã®ã€ã³ã¹ã¿ã³ã¹ã¿ã€ãã AWS Arm ããŒã¹ã® Graviton ã«å€æŽ ãã»ãµãŒãã¹æ¹åæœçã®å®æœã«äŒŽã倧ããªã³ã¹ãå¢ãèŠèŸŒãŸããŠãããããã®å¯Ÿå¿ã«ããå¢å å¹
ãå°ããæãããã ã»EKS ã®åºç€ã Fargate ãã EC2 ã«å€æŽããããšã«ããã Datadog å«ãã EKS ã«é¢é£ããããŒã¿ã«ã³ã¹ãã®åæž ãã»æšå¹Žã«å®æœããŠããæœçã§ããã广ããã£ãæœçãªã®ã§çŽ¹ä» åæœçããšã«äžå¯§ã«èª¿æ»ãã¢ãã¿ãªã³ã°ãããªããæ®µéçã«é²ããããããããã®æœçãåå ãšããã€ã³ã·ãã³ããèµ·ãããã«åæžã§ããããšã倧ããªææã§ããã åçš®ã·ã¹ãã ã®ãªã¢ãŒããã¯ã㣠ã¹ã¿ã³ãã€ã¯2015幎ã«ããºãªãŒãã®æ°èŠäºæ¥ãšããŠå§ãŸã£ããµãŒãã¹ã§ãããµãŒãã¹ãšã·ã¹ãã ã®å¹Žéœ¢ã¯ãã10幎è¿ãã«ãªãããšãããã課é¡ãããããåºãŠããŠããŸãã æ€çŽ¢ãšã³ãžã³ã«ã€ããŠã¯ æ€çŽ¢ãšã³ãžã³ãVespaãžç§»è¡ããŠããŸã ã®èšäºã«ããããã«å·æ°ãããŠããŸããã æ€çŽ¢ãšã³ãžã³ä»¥å€ã®ã·ã¹ãã 矀ã«ãããŠããæ±ãããŒã¿éããã©ãã£ãã¯ã®å¢å ãžã®å¯Ÿå¿ãåçš®æœçã®ãã©ã€ã¢ã³ããšã©ãŒã®æŽå²ã åªå
床ã®å
Œãåãã§æ¹å掻åãé·æé宿œã§ããŠããªãã·ã¹ãã ãããã€ãååšãããªã©ãããããæè¡è² åµãšåŒã°ãããã®ãããã€ããããŸãã ãŸããå
šäœçãªã·ã¹ãã ã¢ãŒããã¯ãã£ãšæè¡éžå®ã«é¢ããŠããä»åŸã®éçºãéçšä¿å®ã®å¹çã®èгç¹ã§èŠçŽããã»ããè¯ãéšåãåºãŠããŠããŸããã ãããã®èª²é¡ã¯ããã«æ·±å»ãªåé¡ã«çŽçµãããã®ã§ã¯ãããŸãããã察å¿ãããªããã°äžé·æçã«ã¯éçºå¹çã®äœäžãã€ã³ã·ãã³ãçºççã®äžæãç¶ããäžé·æçã«ãµãŒãã¹æ¹åã®åæ»ãç¶ç¶ããå±ã¶ãŸããç¶æ³ãçã¿åºããããªãé¡ã®ãã®ã«ãªããŸãã ãã®ããã課é¡ã®åœ±é¿åºŠãç·æ¥æ§ãæ¹å广ã®èŠèŸŒã¿ãªã©ãèæ
®ããŠåªå
é äœãã€ããŠããŒãããããåŒããããã€ãã®ã·ã¹ãã ã®ãªã¢ãŒããã¯ãã£ãåéçºããŒã ã§é²ããŠããŸãã èŠæš¡ã倧ããéåã°ã®æ¡ä»¶ããããŸãã確å®ã«é²æããŠãããäžéšã¯æ¬çªãªãªãŒã¹ãè¿ãããæåŸ
ããŠããéçºå¹çãããã©ãŒãã³ã¹ã®æ¹åãå®çŸã§ããŸããã äž»ã«ã¯ä»¥äžã®ãããªåã蟌ã¿ã宿œããŠããŸãã éçºã«çšããèšèªã®å€æŽ ã¹ã¿ã³ãã€ã®ã·ã¹ãã ã®å€§å㯠Scala ã§å®è£
ãããŠããã®ã§ãããããã«ã€ããŠã¯æšä»ããã€ãã®èª²é¡ãé¡åšåããŠããŸããã äžççã«ãåœå
ã«ãããŠã Scala ã®äººæ°ãä»ã®èšèªãšæ¯èŒããŠé«ããªãç¶æ³ã«ããããšã³ãžãã¢æ¡çšãå°é£ã«ãªã£ãŠããŠããŸããã ãŸã Akka ã®ã©ã€ã»ã³ã¹å€æŽãã¯ãããšããäŸåã©ã€ãã©ãªããã¬ãŒã ã¯ãŒã¯ã«å€§ããªå€åããããScala ãç¶ç¶å©çšããŠããã«ãäžç¢ºå®æ§ãšè«žã
ã®å¯Ÿå¿å·¥æ°ã倧ãããªãèŠèŸŒã¿ããããŸããã æšå¹Žããã¹ã¿ã³ãã€å
ã§ãã®èª²é¡ã«é¢ããè°è«ãéãã ã»èšèªå©çšè
æ°ã®ç¶æ³ ã»OSS ã®éçºäœå¶ ã»ä»åŸã®ãšã³ãžãã¢æ¡çš ã»éçåä»ãèšèªã§ããããšïŒåå®å
šæ§ïŒ ã»äžŠè¡åŠçã®æ±ãããã ã»ãã€ã¯ããµãŒãã¹éã®éä¿¡ã®å®å®æ§(å£ãã«ãã)ãšé«ããã©ãŒãã³ã¹ã®å®çŸã®ãããã ã»åŠç¿ã³ã¹ãå«ããçŸç¶ããã®ç§»è¡ã³ã¹ã çã
ã®èгç¹ã§è€æ°ã®èšèªãæ¯èŒæ€èšããããã¯ãšã³ãéçºã§çšããã¡ã€ã³ã®èšèªã Go ã«å€æŽããŠããããšã決å®ããŸããã ãããŠãåŸã
ã«ããã¯ãšã³ãã®ã¢ããªã±ãŒã·ã§ã³ã Go ã§ã®å®è£
ã«åãæ¿ããããšãé²ããŠããŸãã 瀟å
ã®ãµãŒãã¹ééä¿¡ã«ã€ããŠã REST ãã gRPC ã«åŸã
ã«ç§»è¡ããŠããããšãé²ããŠããŸãã æšå¹Žã®æ±ºå®æç¹ã§ã¯ã¹ã¿ã³ãã€å
ã® Go ã®çµéšè
ã¯ããªãå°ãªãã£ãããäžå®èŠçŽ ããã倧ããªæ±ºå®ã§ããããå€éšã®è¬åž«ã®æ¹ãæããå匷äŒã瀟å
ã§ã®ããŠããŠå
±æãªã©ã宿œããªãããããã€ãã®ãµãŒãã¹ã® Go ãžã®ç§»è¡ãå®äºããŠããŸãã æ±äººåã蟌ã¿ã»ç®¡çã·ã¹ãã ã®å·æ° åè¿°ã®ã³ã¹ãæé©åã®ããŒãã§ãè§Šããã巚倧㪠DB ãçšããŠããæ±äººããŒã¿ã®åã蟌ã¿ç®¡çã·ã¹ãã ã«ã€ããŠããã¢ãŒããã¯ãã£ã®å·æ°ãé²ããŠããŸãã ãã®ã·ã¹ãã ã¯ãæ±äººããŒã¿æ¬äœã ãã§ãªãåçš®åã蟌ã¿åŠçã®ç¶æ
管çã«ã€ããŠãäž»ã«ïŒã€ã® DB ã¯ã©ã¹ã¿ãŒã§éäžç®¡çãããŠããŸãã åãæ±ãæ±äººæ°èªäœã®å¢å ã«å ããæ±äººããŒã¿åã蟌ã¿ã®åŠçæ°ãå
容ã®è€éããå¢ããŠããŠãããDB ãããã©ãŒãã³ã¹ãšã³ã¹ãã«ãããŠããã¯ã«ãªã£ãŠããŸãã ãããŠä»åŸãã¹ã¿ã³ãã€ã®ãµãŒãã¹æ¹åã®ããæ±äººããŒã¿ã®åã蟌ã¿åŠçã¯è¿œå ã倿Žããç¶ããŠããå¿
èŠããããŸãã æ±äººããŒã¿ã®åã蟌ã¿ç®¡çã¯ã¹ã¿ã³ãã€ã®ãµãŒãã¹ã®æ¹åãšç¶ç¶ã®èãšãªãéèŠãªéšåã®ããã ãããã©ãŒãã³ã¹ãããã³ã¹ããããéçºã»éçšã®ããããããæ¹åãç®æããŠãDB ãäžå¿ãšããã¢ãŒããã¯ãã£ããã¹ããªãŒã ãäžå¿ãšããã¢ãŒããã¯ãã£ãžã®å·æ°ãé²ããŠããŸãã ããŒã¿åºç€ã®å·æ° ã¹ã¿ã³ãã€ã®ãµãŒãã¹æ¹åã®ããã®åçš®æææ±ºå®ãæ€çŽ¢ãšã³ãžã³æ¹è¯ã®ææãšãªãåçš®ãã°ãæ±äººã«é¢ããããŒã¿ã管çããŠãããããŒã¿åºç€ãã«é¢ããŠããDWH ã®ãªã¢ãŒããã¯ãã£ãé²ããŠããŸãã çŸç¶ã®ã¹ã¿ã³ãã€ã®ããŒã¿åºç€ã¯ããŒã¿çµ±åãã¢ããªã³ã°ãã¡ã¿ããŒã¿ã®æŽåãªã©ã®èгç¹ã§èª²é¡ãå€ããåçš®ããŒã¿åææ¥åããšãŠãç
©éã§å質ãé«ãã§ããŠããªãç¶æ³ã«ãããŸãã DWH ã®ãªã¢ãŒããã¯ãã£ã«ãã£ãŠãããã®èª²é¡ãäžæ°ã«è§£æ¶ããããšããé¡ã®è©±ã§ã¯ãªãããŒã¿ã®ç®¡çæ¹æ³ãã¯ãããšããéçšã®èª²é¡ã倧ããã§ããããããã®èª²é¡è§£æ±ºãé²ããããããããã®åºç€æŽåã®ããã«ãªã¢ãŒããã¯ãã£ã宿œããŠããŸãã ãããæéããããåãçµã¿ã§ã¯ãããŸãããæ£ç¢ºãªããŒã¿ãšåæçµæãå
ã«ããæææ±ºå®ãããŠããããšã¯ãµãŒãã¹æ¹åã«ãããŠéåžžã«éèŠã«ãªãããšã®ãã®ã§ãåãçµã¿ãé²ããŠããŸãã éçºå¹çãå質åäžã®ããããŒã«å°å
¥ãåãçµã¿ éçºæŽ»åã®å¹çãå質ãé«ããããã«ãäžèšãã¯ãããšããããŒã«ã®å°å
¥ãåãçµã¿ã宿œããŸããã ã»GitHub Copilot ã®å°å
¥ ãã»AI ã®ãµããŒããé©å®å©çšããéçºã®å質ãšå¹çã®åäžãå³ããã ã»Renovate ã®å°å
¥æšé²ã«ããäŸåã©ã€ãã©ãªã®æŽæ°ã®å¹çå ãã»äœã³ã¹ãã§ããŸãã«ã¢ããããŒãããä»çµã¿ãæŽåããããšã«ãããå®å
šæ§ãšå®å®æ§ã®åäžãå³ããã ã»Codecov ã®å°å
¥æšé²ã«ãããã¹ãã«ãã¬ããžã®å¯èŠå ãã»æ¥ã
ã®éçºéçšã«æ¬ ãããªãèªåãã¹ãã®æ¹å掻åãé²ãããããããã GitHub Copilot ã«ã€ããŠã¯ AI ããã®ææ¡å
容ã«ã€ããŠåå³ããå¿
èŠããããªã©æ³šæã¯å¿
èŠã§ãããå©çšããŠãããšã³ãžãã¢ããã¯éçºå¹çãè¯ããªã£ããšãã声ãå€ãã£ãã§ãã ãŸãšã äžèšã§ç޹ä»ããåãçµã¿ã¯äžéšã§ãä»ã«ã倿°ãªãã¡ã¯ã¿ãªã³ã°ãåçš®æ¹å掻åãåéçºããŒã ã§é²ããŠããŸãã ã©ããªäºæ¥ã§ãåæ§ã§ãããæäŸãããµãŒãã¹ãçµç¹ãéå¶ãæé·ããç¶ããŠããããã«ã¯ãç®ã«ã¯èŠãã«ããéšåã®æ¹å掻åãå¿
èŠã«ãªããŸãã ãããã£ã掻åãšãµãŒãã¹æ¹åã«çŽçµããæœçéçºã®ãã©ã³ã¹ãã©ãåãã®ãã¯åžžã«é£ããããšã§ãããã¹ã¿ã³ãã€ã§ã¯ååæããšã«å
šäœã§ã®åçš®æ¡ä»¶ã®åªå
床調æŽã宿œã§ããŠããããšããããã©ã³ã¹è¯ãåãçµããŠãããšæããŠããŸãã ãããã£ãåãçµã¿ã§éçºæŽ»åã®å°ç€ãåºãã€ã€ãæ±äººæ€çŽ¢ãµãŒãã¹ã®ç£šã蟌ã¿ãããŠããããã§ãã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ããã«ã¡ã¯ãã¹ã¿ã³ãã€ã§æ±äººã®åã蟌ã¿ã·ã¹ãã ãéçºã»éçšãããŠããéŽæšã§ãã ä»å㯠Scala ãš Go ã«æšæºã§çµã¿èŸŒãŸããŠããæ£èŠè¡šçŸãšã³ãžã³ã®éãã«ã€ããŠã§ãã æŠèŠ ã¹ã¿ã€ãã€ã§ã¯ Scala ã§æžãããã·ã¹ãã ã Go ã«ãªãã¬ã€ã¹ããéçºãé²ãã§ããŸãã ãã®äžã§ Scala ã§å®è£
ãããŠããæ£èŠè¡šçŸã Go ã ãšåããªãäºè±¡ã«ééããŸããããã®éãã¯ã©ããªãã®ãããã®ãïŒãŸãšããŸãã æ©èœå·®åã®äžäŸ ä»åçºèŠããæ©èœå·®åã®äŸãèŠãŠã¿ãŸãããã ã¹ã¿ã³ãã€ã§æ±ã£ãŠããæ±äººæ
å ±ã管çããããã«æ£èŠè¡šçŸã䜿ã£ãŠè²ã
ãªæ
å ±ãæœåºããŠããŸãã äŸãšããŠãããªæãã®æ±äººæ
å ±ãã絊äžã®æ
å ±ãæœåºããããšããŸãã (ç°¡ååã®ããéé¡ã®ã«ã³ããåé€ããŠããŸãã) âçè·åž«ïŒæ£ã»åïŒïŒæçµŠ1400åïœ1600å+亀éè²» æåäŸ 246400åïœ281600åïŒäº€éè²»â»20æ¥å€åã1æ¥8ïœ æ¥å€åž¯ã®ã¿ã®å Žåâãã«ããŒïŒ2çŽä»¥äžïŒã»ä»è·çŠç¥å£«ïŒæçµŠ1000åïœ1200å+亀éè²» æåäŸ 176000åïœ211200åïŒäº€éè²»â»20æ¥å€åã1æ¥8ïœ æ¥å€åž¯ã®ã¿ã®å Žåâ»æ·±å€å€ïŒ22ïŒ00ïœç¿5ïŒ00ïŒã¯æçµŠ25ïŒ
ã¢ããâ»æ¥å€åž¯ã®ã¿ã§ãçžè«ã«å¿ããŸã æ°åãåºæºã«æœåºããã°è¯ãã®ã§ãããåçŽã«æ°åããããããŠããŸããš 1æ¥8ïœ ã 22æ¥å€å ãªã©ãæœåºããŠããŸãã®ã§ãããããé€å€ããŸãããã ãããããšãããªæãã®æ£èŠè¡šçŸã§å®çŸã§ããŸãã [1-9]+[0-9\.åçŸåäžå\sã]*(?!\d*[å|æ|æ¥|æ|幎|ïœ|çŽ]) ãã£ããã©ããªãããã«ãªãããšèšããŸããšãååã® [1-9]+[0-9\.åçŸåäžå\sã]* ã®éšåã¯æ°å€ãšéé¡ã®åäœããããããŠããŸãã åŸåã® (?!\d*[å|æ|æ¥|æ|幎|ïœ|çŽ]) ã¯ååã®ãããã®ãªãã§ã å|æ|æ¥|æ|幎|ïœ|çŽ ã®åãç¶ãå Žåã¯é€å€ããŠããŸãã ãã® ?! ã§è¡šãããŠãã ãããããªãããš ã®åãã Go ã®æ£èŠè¡šçŸã§ã¯å¯Ÿå¿ããŠããããšã©ãŒã«ãªã£ãŠããŸããŸãã error parsing regexp: invalid or unsupported Perl syntax: `(?!` ãã㯠Go ã®æ£èŠè¡šçŸãšã³ãžã³ãåŠå®å
èªã¿ã®æ©èœããµããŒãããŠããªãããã§ãã ãã®ããã«æ£èŠè¡šçŸã«ã¯æ£èŠè¡šçŸãè§£éããŠå®è¡ãããšã³ãžã³ãããã€ãããããµããŒãããŠããæ©èœã«å·®ããããŸãã ããã¯ãã©ããã³ã°ã«ã€ã㊠Go ã§æšæºã©ã€ãã©ãªã䜿çšããæ£èŠè¡šçŸã¯ RE2 ãšã³ãžã³ã§åããŸãã RE2 ã¯ä»ã®æ£èŠè¡šçŸãšã³ãžã³ãšæ¯èŒããŠããã¯ãã©ããã³ã°ãè¡ããªãç¹åŸŽããããŸãã åŠå®å
èªã¿ãã§ããªãã£ãã®ããããé¢é£ããŠããããã§ããã ãã®ããã¯ãã©ããã³ã°ãè¡ããªãããšã§å€åœ©ãªæ©èœã¯äœ¿ããªããã®ã®ãåŠçæéãç·åœ¢æéã§åäœãã¡ã¢ãªã®äœ¿çšéãæããããšãã§ããŸãã äžæ¹ãScala ã§ scala.util.matching.Regex ã䜿ã£ãå Žå㯠java æšæºã®æ£èŠè¡šçŸã䜿ãããŸãã ãã¡ãã¯ããã¯ãã©ããã³ã°ããµããŒãããŠãã®ã§ RE2 ãšæ¯ã¹ãŠåŠå®å
èªã¿ã®ããã«è€éãªãããã³ã°ãã§ããŸãã ããã¯ãã©ããã³ã°ã®æ§å㯠ãã¡ã ãªã©ã®ãµã€ãã§æ£èŠè¡šçŸã®ãããã°ããããšç¢ºèªããããã§ãã ãããã°ã¢ãŒã㯠PCRE ç³»ã®æ£èŠè¡šçŸãšã³ãžã³ã®ã¿å¯Ÿå¿ããŠãããããªã®ã§ PCRE2 ã§èŠãŠã¿ãŸãããã ç»é¢äžéšã® REGULAR EXPRESSION ã®å
¥åã«æ£èŠè¡šçŸãããã®äžã® TEST STRING ã«ãããããããæååãå
¥åããŸãã ãããŠãå·Šã¡ãã¥ãŒã® FLAVOR ã§ PCRE2 ãéžã³ Regex Debugger ãããããã°ãã§ããŸãã Match1 ãé²ããŠãããš âçè·åž«ïŒæ£ã»åïŒïŒæçµŠ1400å ã®ãã¡ 1400 ã®éšåã«ãããããŠ1ã€ç®ãå®äºããŠããŸãã Match2 ãã Match4 ãŸã§ãåæ§ã« 1600 , 246400 , 281600 ã«ãããããŠããŸãã Match5 ãé²ãããš 20æ¥ ã® 20 ã«ãããããŠããŸããããã®åŸã« 20 ã®åŸã« æ¥ ã ãããããªãããš ã確èªããŠããæ§åãããããŸãã ããã«é²ãããšä»åºŠã¯å
é ã®2ãé€å€ã㊠0 ãŸã§æ»ã£ãåŸãåã³ æ¥ ããããããªãããšã確èªããŠããŸãã ãã®ããã«ããã¯ãã©ããã³ã°ãå©çšãããšåãç®æã«äœåºŠããããããã詊è¡ããŠããŸããããå Žåã«ãã£ãŠã¯ææ°é¢æ°çã«åŠçéãå¢å ããããã«å¿ããŠå¿
èŠãªã¡ã¢ãªéãå¢ããŠããŸããŸãã ãã®ãã RE2 ã§ã¯åŠçéãç·åå¢å ããŠãããšããæ§è³ªã¯ããã©ãŒãã³ã¹ã«é¢ãã£ãŠããã®ãåãããŸããã ãã®ä»ã®æ©èœæ¯èŒ ããã¯ãªãã¡ã¬ã³ã¹ ããã¯ãªãã¡ã¬ã³ã¹ã¯äžåºŠãããããã°ã«ãŒããåå©çšã§ããŸãã ãããªæ£èŠè¡šçŸ (\b\w+at\b).*\1 ã§ãããªæåå The cat sat on the mat with another cat. ããããããŠã¿ããš... \1 ã®éšåãååããããã cat ãšãªãããšã§æ«å°Ÿã® cat ã«ãããããŠããããšãããããŸãã ãŒãå¹
ããã æ£èŠè¡šçŸäžã§ãç¹å¥ãªæå³ãæã€ã¡ã¿æåããããŸãã ^ ã¯æååã®å
é $ ã¯æ«å°Ÿã«ããããããªã©ã§ãããåºæ¬çã«ã¯ Go ã§ããŒãå¹
ããããå©çšã§ããŸããå©çšã§ããªããã¿ãŒã³ãããã€ããããŸãã äŸãã°ãããªæ£èŠè¡šçŸ cat(?=\s) ã§ãããªæåå The cat sat on the mat with another cat. ããããããŠã¿ããš... ãããã®æ¡ä»¶ã«ç©ºçœã¯å«ãã§ããŸãããããçµæã«ã¯å«ãŸããŠããªãããšãããããŸãã æ¡ä»¶ä»ãã®æ£èŠè¡šçŸ æ¡ä»¶ãã€ããŠæºããå Žåã®ãã¿ãŒã³ãšæºãããªãå Žåã®ãã¿ãŒã³ã®åå²ãããæ©èœã§ãã (?(test) true| false) ã®ããã« ?(æ¡ä»¶) ãš true/false ã®ãã¿ãŒã³ãšãã£ãèšè¿°ã«ãªããŸãã ãã¡ã㯠java ã®æ£èŠè¡šçŸã§ããµããŒããããŠããŸããã ãã©ã¯ãŒããªãã¡ã¬ã³ã¹ ããã¯ãªãã¡ã¬ã³ã¹ã®éã§åŸã®ãã£ããã£ã°ã«ãŒããåç
§ã§ãããããã§ãã ããããã詊è¡ããŠããªãéšåãåç
§ãããšããç¹æ®ãªæåãªã®ã§å©çšã§ããæ£èŠè¡šçŸãšã³ãžã³ã¯ããªãéãããããã§ãã ãã¡ãã java, go ãšãã«ãã®æ©èœã¯äœ¿ããŸããã ä»ã®æ£èŠè¡šçŸãšã³ãžã³ã Go ã§äœ¿ãæ¹æ³ ãã®ããã« Go ã®æšæºããã±ãŒãžãå©çšãããšãScala ã§ã¯å©çšã§ããŠããäžéšã®æ£èŠè¡šçŸã®æ©èœãå©çšã§ããªããªããŸããã Go ããæšæºã® RE2 以å€ã«ãä»ã®æ£èŠè¡šçŸãšã³ãžã³ãå©çšããæ¹æ³ãããããã§ãããæ¥æ¬èªå¯Ÿå¿ã«æªãããšãããããããã§ãã package main import ( "fmt" "github.com/GRbit/go-pcre" ) func main() { pattern := pcre.MustCompile(`[1-9]+[0-9\.åçŸåäžå\sã]*(?!\d*[æ|æ¥|æ|幎|ïŒ
|ïœ|çŽ])`, 0) subject := "âçè·åž«ïŒæ£ã»åïŒïŒæçµŠ1400åïœ1600å+亀éè²» æåäŸ 246400åïœ281600åïŒäº€éè²»â»20æ¥å€åã1æ¥8ïœ æ¥å€åž¯ã®ã¿ã®å Žåâãã«ããŒïŒ2çŽä»¥äžïŒã»ä»è·çŠç¥å£«ïŒæçµŠ1000åïœ1200å+亀éè²» æåäŸ 176000åïœ211200åïŒäº€éè²»â»20æ¥å€åã1æ¥8ïœ æ¥å€åž¯ã®ã¿ã®å Žåâ»æ·±å€å€ïŒ22ïŒ00ïœç¿5ïŒ00ïŒã¯æçµŠ25ïŒ
ã¢ããâ»æ¥å€åž¯ã®ã¿ã§ãçžè«ã«å¿ããŸã" matcher := pattern.NewMatcher([]byte(subject), 0) for matcher.Matches { fmt.Printf("GroupString: %s\n", matcher.GroupString(0)) indices := matcher.Index() end := indices[1] subject = subject[end:] matcher = pattern.NewMatcher([]byte(subject[end:]), 0) } } æ£èŠè¡šçŸã®ãã¿ãŒã³ã« å ãå«ãŸããŠããå Žåã«ãå
¥åæååã«å«ãŸããŠããªããŠããããçµæãå€ãããŸããããŸãããããããæååãæåæ°åäœã§ã¯ãªããã€ãåäœã§åãåãããŠæååãããŠããŸãäºè±¡ããããŸããã çŸåšåãçµãã§ãããªãã¬ã€ã¹ã®éçºã¯æ±äººæ
å ±ããç¹å®ã®æ
å ±ãæœåºããããžãã¯å
šäœãèŠçŽãã€ã€éçºããæ¹éã§é²ããŠãããããæ£èŠè¡šçŸãšã³ãžã³ã«é¢ããŠã¯å€éšã©ã€ãã©ãªã¯æ¡çšããŸããã§ããã çµããã« ãã®ããã«æ£èŠè¡šçŸã®ãšã³ãžã³ã¯è€æ°ããæ§ã
ãªç¹æ§ãæã£ãŠããŸãã ä»å㯠Scala(Java) ãš Go ã®æ£èŠè¡šçŸã®æ©èœã«ã€ããŠã®ã¿ã®èª¿æ»ã«ãªããŸããããåäœé床ã®ãã³ãããŒã¯ãåºæºã«æ¯èŒããã®ãé¢çœããã§ãã å¿
èŠãªèŠä»¶ã«åãããŠé©åãªæ£èŠè¡šçŸãšã³ãžã³ãéžæã§ããããã«ãªãããšããã§ããïŒ ã¹ã¿ã³ãã€ã§ã¯ãåžžã«æ°ããã¢ã€ãã¢ãæè¡ã調æ»ãã詊ããŠããŸããæ°ããããšã«ææŠãããæ¹ããçŽ æŽããããã©ãããã©ãŒã ã§çŽ æŽããã仲éãšä»äºããããæ¹ã¯ããã² æ¡çšããŒãž ãã芧ãã ãã! ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ã¯ããã« ããã«ã¡ã¯ãã¹ã¿ã³ãã€ã®ã¢ããªããŒã ã§iOSéçºãæ
åœããŠããå°æç¥èŒãšç³ããŸãã ç§ãã¡ã¹ã¿ã³ãã€ã®iOSããŒã ã§ã¯ãSwiftUIãCombineãConcurrencyãªã©ã®ã¢ãã³ãªæè¡ãçšããŠæ¥ã
éçºãé²ããŠããŸãã ãã®äžã§ãçŽè¿ã§æµ®äžãã課é¡ã®1ã€ããUIãã¹ããã§ãã ãã®èšäºã§ã¯ãç§ãã¡ã¹ã¿ã³ãã€ã®iOSããŒã ãã©ã®ããã«ããŠUIãã¹ããæ§ç¯ããéçšããŠããã®ããã玹ä»ããŸãã UIãã¹ãå°å
¥ã®èæ¯ãããã®å¿
èŠæ§ãå
·äœçãªææ³ãããŒã«ã«ã€ããŠã解説ããŠãããŸãã UIãã¹ãã®å¿
èŠæ§ãšãã°éä¿¡ãã¹ãå°å
¥ã®èæ¯ ã¹ã¿ã³ãã€ã¯ãæ±è·è
ãšäŒæ¥ãã€ãªããã©ãããã©ãŒã ãšããŠå±éããŠãããæ°å€ãã®æ±äººãµã€ããäžæ¬ããŠæ€çŽ¢ã»æ¯èŒã§ãããã¢ã°ãªã²ãŒã·ã§ã³ãµãŒãã¹ãã§ãã ã¢ããªã®ãã¶ã€ã³ã¯æ±äººã®æ€çŽ¢ããå¿åãŸã§ãç°¡åã«è¡ããããã«ãªã£ãŠãããæéã¢ã¯ãã£ããŠãŒã¶ãŒæ°ãæ¥å¢ããŠããŸãã ã§ãããã¢ããªã®èŠæš¡ã倧ãããªãã«ã€ããŠãæåãã¹ãã ãã§ã¯éçãæããå Žé¢ãå¢ããŠããã®ããŸãäºå®ã§ããã ç¹ã«ãŠãŒã¶ãŒè¡åã®åæãéèŠãªã¹ã¿ã³ãã€ã«ãããŠã¯ãéä¿¡ããããã°ãæ£ç¢ºãã€é©åãªã¿ã€ãã³ã°ã§éãããŠãããã®ç¢ºèªãå¿
é ã§ãã ããã§ããŸãã¯ãã°éä¿¡ãã¹ããéç¹çã«è¡ãUIãã¹ãã®å°å
¥ãéå§ããŸããã ãã°éä¿¡ãã¹ãã«UIãã¹ããå°å
¥ããçç± ãšã¯ããããã°éä¿¡ã®ãã¹ããšèããšäžã«ã¯ã ããŠããããã¹ãã§æ
ä¿ã§ããã®ã§ã¯ïŒã ãšæãããæ¹ãããã£ãããã®ã§ã¯ãªãã§ããããã 確ãã«ããã°ã®å
容ã ãã§ããã°ãŠããããã¹ãã§ãååã§ãã ãããããŠãŒã¶ãŒæäœã䌎ããã°éä¿¡ã¯ãå®éã®ãŠãŒã¹ã±ãŒã¹ã«åºã¥ããUIãã¹ãã®æ¹ãå
ç¢æ§ã¯é«ãŸããŸãã ç§ãã¡ã¯ããã®ç¹ãéèŠèŠããUIãã¹ããéžæããŸããã UIãã¹ãæ§ç¯ã®èª²é¡ãšViewInspectorã®æ¡çš ããããiOSããŒã ã«ã¯UIãã¹ãæ§ç¯ã®çµéšè
ãããŸããã§ããã XCUITestã¯åŠç¿ã³ã¹ããé«ããUIãã¹ããæ§ç¯ããã«ã¯å€§ããªå£ãç«ã¡ã¯ã ãã£ãããã§ãã ãããªäžã§åºäŒã£ãã®ããViewInspectorãšããã©ã€ãã©ãªã§ãã ViewInspectorãšã¯ïŒ ViewInspectorãšã¯ãSwiftUIã§æ§ç¯ãããViewã«å¯ŸããŠãããã°ã©ã ããçŽæ¥ã¢ã¯ã»ã¹ãããã®ç¶æ
ãåäœã確èªã§ããã©ã€ãã©ãªã§ãã ViewInspector SwiftUIã®Viewã¯ãã®æ§é äžãå
éšã®ç¶æ
ãçŽæ¥åç
§ããããæ€èšŒãããããããšãé£ãããªã£ãŠããŸãã XCUITestã®åŠç¿ã³ã¹ããããã§ããããããXCUITestãå°å
¥ããéã®éå£ã®1ã€ã§ããã ViewInspectorã¯ããã®åé¡ã解決ããããã«äœãããããŒã«ã§ãããéçºè
ãSwiftUIã®Viewãç°¡åã«ãã¹ãã§ããç°å¢ãæäŸããŠãããŠããŸãã å
·äœçã«ã¯ãViewã®éå±€æ§é ã«ã¢ã¯ã»ã¹ãã ç¹å®ã®Viewããã®ãããã㣠衚瀺ãããããã¹ã ãã¿ã³ã®ã¢ã¯ã·ã§ã³ ãªã©ãããã°ã©ã çã«æ€èšŒã§ããŸãã ããã«ãããæåã§ã®UIãã¹ãã«é Œãããšãªãããã°éä¿¡ã®ãããªéèŠãªæ©èœã«å¯ŸããŠããå®éã®ãŠãŒã¶ãŒæäœãæš¡å£ãããã¹ããå¹ççã«è¡ãããšãå¯èœã«ãªãããã§ãã ãŸããViewInspectorã¯çŽæçãªAPIãæäŸããŠãããããSwiftUIã䜿ã£ãŠããéçºè
ã§ããã°ãæ¯èŒç容æã«å°å
¥ã§ããç¹ã倧ããªã¡ãªããã«ä»ãªããŸããã ç§ãã¡iOSããŒã ããUIãã¹ãã®è€éããåŠç¿ã³ã¹ãã®é«ãã«æ©ãŸãããŠããäžã§ããã®ViewInspectorãæ¡çšããããšã§ããã¹ãç°å¢ã®æ§ç¯ãã¹ã ãŒãºã«é²ããããšãã§ããŸããã åºæ¬çãªäœ¿ãæ¹ãšäŸ ãã®æ¬¡ã®é
ç®ããã¹ã¿ã³ãã€ã®iOSãããžã§ã¯ãã§ã©ã®ããã«ViewInspectorãå©çšããŠããã®ãã解説ããŸãããããã«å
ç«ã£ãŠãŸãã¯ViewInspectorã®åºæ¬çãªäœ¿ãæ¹ã説æããŸãã ããã§ã¯3ã€ã®ãã¹ããã¿ãŒã³ãçšæããã®ã§ãããããå
·äœçã«æãäžããŠãããŸãã 1. ããã¹ãè¡šç€ºã®æ€èšŒ ãŸãã Text ãæ£ãã衚瀺ãããŠãããã確èªããåºæ¬çãªãã¹ããäŸã«èª¬æããŠãããŸãã import SwiftUI import ViewInspector import XCTest // ãã¹ã察象ã®View struct SimpleTextView : View { var body : some View { Text( "Hello, ViewInspector!" ) } } class SimpleTextViewTests : XCTestCase { func testTextIsDisplayedCorrectly () throws { let view = SimpleTextView() // ViewInspectorã§Textã®å
容ãååŸ let text = try view.inspect().find(text : "Hello, ViewInspector!" ).text().string() // æ€èšŒ XCTAssertEqual(text, "Hello, ViewInspector!" ) } } ViewInspectorã§ç¹å®ã®Viewã«ã¢ã¯ã»ã¹ããéããŸã㯠view.inspect() ãšå®£èšããäžã§ãViewãéå±€çã«åç
§ããŠããå¿
èŠããããŸãã view.inspect() ããã«ãããå
éšçã«åç
§å¯Ÿè±¡ã® RootView ãååŸãããããããããã«æå®ããèŠçŽ ãžã¢ã¯ã»ã¹ã§ããããã«ãªããŸãã æ¬¡ã«ãç¹å®ã®ããã¹ããæã€Viewã«ã¢ã¯ã»ã¹ããããã«ã¯ã以äžã®ããã« find(text:) ã¡ãœããã䜿ããŸãã view.inspect().find(text : "Hello, ViewInspector!" ) ããã§ã "Hello, ViewInspector!" ãšããããã¹ããæã€ViewãååŸã§ããŸãã ããã«ä»åã¯ããã®ããã¹ãã®æ£ç¢ºæ§ããã¹ããããããæååãã®ãã®ãååŸããå¿
èŠããããŸãã ãã®ããã«ã text() ã¡ãœããã䜿çšããŠæ¬¡ã®ããã«èšè¿°ããŸãã view.inspect().find(text : "Hello, ViewInspector!" ).text() ããã§ãããã¹ãèŠçŽ ã®æååããŒã¿ã«ã¢ã¯ã»ã¹ã§ããŸããã æ¬¡ã«ããã®æååã string() ã¡ãœããã§ååŸãããã¹ãã®æåŸ
å€ãšæ¯èŒããŸãã let text = try view.inspect().find(text : "Hello, ViewInspector!" ).text().string() XCTAssertEqual(text, "Hello, ViewInspector!" ) ããã§ã XCTAssertEqual ã䜿ã£ãŠãååŸããããã¹ããæåŸ
ãããå
容 "Hello, ViewInspector!" ã§ãããã©ãããæ€èšŒããŸãã 2. ãã¿ã³ã®ã¿ãããšç¶æ
倿Žã®æ€èšŒ æ¬¡ã«ããã¿ã³ãã¿ããããŠãå
éšç¶æ
ãæŽæ°ãããåäœãã¹ãã解説ããŠãããŸãã import SwiftUI import ViewInspector import XCTest // ãã¹ã察象ã®View struct CounterView : View { @State private var count = 0 var body : some View { VStack { Text( " \( count ) " ) Button( "Increment" ) { count += 1 } } } } class CounterViewTests : XCTestCase { func testButtonTapIncrementsCounter () throws { let view = CounterView() let sut = try view.inspect() // åæç¶æ
ãç¢ºèª XCTAssertEqual( try sut.find(text : "0" ).text().string(), "0" ) // ãã¿ã³ãã¿ãã try sut.find(button : "Increment" ).tap() // ã¿ããåŸãã«ãŠã³ã¿ãŒã1ã«å¢ããŠããããšãæ€èšŒ XCTAssertEqual( try sut.find(text : "1" ).text().string(), "1" ) } } ãŸãããã®ãã¹ãã§ã¯ CounterView ãšããã«ãŠã³ã¿ãŒæ©èœãæã£ãã·ã³ãã«ãªSwiftUIãã¥ãŒã®åäœãæ€èšŒããŠããŸãã ç¹å®ã®ãã¿ã³ãã¿ããããéã«ãã«ãŠã³ããæ£ããã€ã³ã¯ãªã¡ã³ããããŠãããã確èªãããã¹ãã§ãã XCTAssertEqual( try sut.find(text : "0" ).text().string(), "0" ) ããã§ã¯ã CounterView ãæã€ Text ã®åæç¶æ
ã 0 ãšããäºã確èªããŠããŸãã view.inspect() ã§RootViewã«ã¢ã¯ã»ã¹ããåŸã find(text:) ã䜿ã£ãŠ Text("0") ãæ€çŽ¢ããŠããŸãã ãã® Text ã¯ã«ãŠã³ãã衚瀺ããéšåã§ãã æ¬¡ã«ã text() ã¡ãœããã䜿ã£ãŠ Text èŠçŽ ã®äžèº«ïŒæååããŒã¿ïŒãååŸãã string() ã¡ãœããã§ãã®å
容ãæååãšããŠååŸããŸãã æçµçã«ã XCTAssertEqual ã䜿çšããŠãååŸããæååãåæç¶æ
ã§æåå "0" ã§ãããã©ããã確èªããŸãã ãã®äžã§ããã¿ã³ãã¿ããããŠã«ãŠã³ã¿ãŒã®å€ãã€ã³ã¯ãªã¡ã³ãããåŠçã以äžã§å®è¡ããŠããŸãã try sut.find(button : "Increment" ).tap() ããã§ã¯ã find(button:) ã¡ãœããã䜿çšããŠã "Increment" ãšããããã¹ããæã€ Button ãæ€çŽ¢ããŠããŸãã tap() ã¡ãœããã䜿ãããšã§ãViewInspectorã¯ãã®ãã¿ã³ãå®éã«ã¿ãããã@Stateã§ç®¡çãããŠããã«ãŠã³ã¿ãŒã®ç¶æ
ãæŽæ°ã§ããããã§ãã XCTAssertEqual( try sut.find(text : "1" ).text().string(), "1" ) ã¿ããæäœã®åŸãã«ãŠã³ãã 1 ã«å¢ããŠããããšã確èªããç®æãäžèšã§ãã å床ã find(text:) ã䜿ã£ãп޿°ããã Text("1") ãæ€çŽ¢ãããšå
±ã«ããã®å
容ã text().string() ã§ååŸããæåŸ
éãååŸããå€ã "1" ã§ããããšãæ€èšŒããŠããŸãã 3. ãã¹ãããããã¥ãŒã®æ€èšŒ æåŸã«ããã¹ããããViewã®äžã§ç¹å®ã®Viewã«ã¢ã¯ã»ã¹ãããã®ç¶æ
ãæ€èšŒããæ¹æ³ã解説ããŸãã import SwiftUI import ViewInspector import XCTest // ãã¹ã察象ã®View struct ParentView : View { var body : some View { VStack { ChildView() } } } struct ChildView : View { var body : some View { Text( "child view" ) } } class ParentViewTests : XCTestCase { func testNestedViewText () throws { let view = ParentView() let sut = try view.inspect() // ãã¹ããããChildViewã®Textãç¢ºèª let text = try sut.find(ChildView. self ).find(text : "child view" ).text().string() // æ€èšŒ XCTAssertEqual(text, "child view" ) } } ãã®ãã¹ãã±ãŒã¹ã§ã¯ã ParentView ãšãã芪ãã¥ãŒã®äžã« ChildView ãšããåãã¥ãŒãããããã®äžã§è¡šç€ºãããããã¹ããæ£ãããã©ããã確èªããŠããŸãã ParentView 㯠VStack ã®äžã« ChildView ãå«ãã§ãããChildView ã§ã¯ "child view" ãšããåºå®ã®ããã¹ãã衚瀺ãããŠããŸãã struct ParentView : View { var body : some View { VStack { ChildView() } } } ãã®äžã§ä»¥äžãã¹ãã³ãŒãã«ãããããã«ã testNestedViewText ãšããã¡ãœããã§ã¯ãæåã« ParentView ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããããã view.inspect() ã䜿ã£ãŠæ€èšŒã®å¯Ÿè±¡ïŒsutïŒãšããŠèšå®ããŸãã class ParentViewTests : XCTestCase { func testNestedViewText () throws { let view = ParentView() let sut = try view.inspect() // ãã¹ããããChildViewã®Textãç¢ºèª let text = try sut.find(ChildView. self ).find(text : "child view" ).text().string() // æ€èšŒ XCTAssertEqual(text, "child view" ) } } 次ã«ã sut ãéããŠã ParentView ã®å
éšã«ãã ChildView ãžã¢ã¯ã»ã¹ããŸãã ããã§ã¯ find(ChildView.self) ã䜿çšããŠã芪ãã¥ãŒå
ã«ãã ChildView ãèŠã€ãåºããŠããŸãã ãããŠã ChildView ã«ã¢ã¯ã»ã¹ããåŸã次ã«è¡ãã®ã¯ããã®äžã«è¡šç€ºãããŠããããã¹ãã®ç¢ºèªã§ãã ããã¯æ¢ã«èª¬æããéãã find(text: "child view") ãçšããŠã ChildView å
ã®ããã¹ããèŠã€ãåºããŸãã ãã®åŸã text() ã¡ãœããã§ Text èŠçŽ èªäœãååŸããããã« string() ã¡ãœããã䜿ã£ãŠãã®æååå
容ãååŸããŸãã ãã®äžã§ãæ¯èŒå¯Ÿè±¡ã®æ€èšŒããã ãã§ãã XCTAssertEqual(text, "child view" ) è£è¶³ïŒViewInspectorã«ããæšæºViewãžã®éå±€ã¢ã¯ã»ã¹æ¹æ³ ããã§ã¯ find() ãå©çšã㊠ChildView ã«ã¢ã¯ã»ã¹ããŸããããã·ãŒã³ã«ãã£ãŠã¯SwiftUIæšæºã®Viewã«ã¢ã¯ã»ã¹ãããå Žåãããã®ã§ã¯ãªãã§ããããã ãã®ãããªç¬èªã®åãå®çŸ©ããŠããªãå Žåã¯ãåºæ¬çã«ãããããViewInspectoråŽã§çšæããŠãã以äžã®ãããªã¡ãœãããçšããŠViewã®éå±€ãæã£ãŠããããšãå¯èœã§ãã try sut.vStack().hStack().geometryReader().zStack().group() ... ãããã®ã¡ãœãããå©çšããããšã§ãViewã®éå±€æ§é ã1ã€ãã€æãäžããªããç®çã®Viewã«å°éã§ããŸãã äžæ¹ã§ã以äžã®ããã« find() ãçšããã°ãçŽæ¥ç®çã®ChildViewã«ã¢ã¯ã»ã¹å¯èœã§ãã let text = try sut.vStack().find(ChildView. self ) find() ãå©çšãããšãéå±€ããã©ãæéãçãããããç¹å®ã®Viewã«ã¢ã¯ã»ã¹ããã±ãŒã¹ã§ã¯éåžžã«äŸ¿å©ã§ãã ã¹ã¿ã³ãã€ã«ãããViewInspectorã®å
·äœçãªæŽ»çšäŸ ViewInspectorã®åºæ¬çãªäœ¿ãæ¹ã¯åè¿°ã®éãã§ãè€éãªã±ãŒã¹ã§ãªãéããããã ãã§å€ãã®åäœãã·ãã¥ã¬ãŒãã§ããŸãã ãã®äžã§ãåé ã§è§Šããéããã¹ã¿ã³ãã€ã®iOSã¢ããªã§ã¯ããã®ViewInspectorãçšããŠãã°éä¿¡ã®ãã¹ããå®è£
ããŠããããã§ãã ããã§ã¯å®éã®ãããã¯ãã«ãããå©ç𿹿³ãå
ã«ãå
·äœçãªViewInspectorã®äœ¿ãæ¹ã解説ããŠãããŸãã ãã°ã¢ããªãã£ã¯ã¹ã®ã¢ãã¯å ãŸããå€éšãµãŒãã¹ã«äŸåããããšãªãããã°éä¿¡ããã¹ãããããã«ããã°éä¿¡ã®ä»£ããã«ã¢ãã¯ã¯ã©ã¹ãäœæããŸãã ããã«ãããå®éã®ãããã¯ãŒã¯éä¿¡ããµãŒããŒã®ç¶æ
ã«å·Šå³ãããããã°éä¿¡ãæ£ããè¡ããããã©ãããæ€èšŒã§ããŸãã class MockAnalyticsService : AnalyticsServiceProtocol { var events : [ MockAnalyticsEvent ] = [] var didFinish : (() -> Void ) ? func logEvent (_ name : String , parameters : [ String : Any ] ?) { let event = MockAnalyticsEvent(name : name , parameters : parameters ) events.append(event) didFinish?() } } ãã°éä¿¡ã®ãã¹ãã³ãŒã 次ã«ãå
·äœçãªãã¹ãã±ãŒã¹ãšããŠããã¿ã³ã¿ããã«ããéä¿¡ããããã°ãæ£ãããã©ãããæ€èšŒããã³ãŒãã®ç޹ä»ã§ãã func test_ ãµã³ãã«ç»é¢ã§ã®ãã°éä¿¡ãã¹ã() { // ã¢ãã¯ã®ViewModelã«å¿
èŠãªæ
å ±ãèšå® viewModel.isLoading = false viewModel.items = [.stub(id : "item1" , name : "itemName1" , code : "itemCode1" )] let sut = SampleView(viewModel : self.viewModel ) let exp = analyticsExp(mockAnalyticsService : mockAnalyticsService ) // ãã¿ã³ãã¿ããããŠã€ãã³ããããªã¬ãŒ do { try sut.inspect() .find(SampleCell. self ) // SampleViewã®äžã®SampleCellãèŠã€ãã .find(CellButton. self ) // SampleCellã®äžã®CellButtonãèŠã€ãã .find(button : "" ) // CellButtonã®äžã®ButtonãèŠã€ããïŒããã¹ããªãïŒ .tap() // èŠã€ãããã¿ã³ãã¿ãããã } catch { XCTFail( "failed with: \( error ) " ) } wait( for : exp , timeout : 2.0 ) // éä¿¡ãããã¹ãã€ãã³ããå®çŸ© let tapEvent = MockAnalyticsEvent( name : "tap_item" , parameters : [ "info1": "sample_screen", ..., ... ] ) // å®éã«éä¿¡ãããã€ãã³ããšæåŸ
ãããã€ãã³ããæ¯èŒ verify(actual : mockAnalyticsService.events , expected : [ tapEvent ] ) } ãã®ã³ãŒãã§ã¯ã SampleView ã§ç¹å®ã®ã¢ã€ãã ãã¿ãããããšãã«éä¿¡ããããã°ãæ£ãããã©ãããæ€èšŒããŠããŸãã ãŸããviewModelã«å¿
èŠãªã¢ã€ãã æ
å ±ãèšå®ããã¢ãã¯ã®ãã°ã¢ããªãã£ã¯ã¹ãµãŒãã¹ã䜿ã£ãŠãã°éä¿¡ã€ãã³ããææããŸãã ãã®äžã§ããŸãã¯ç»é¢æç»ã«å¿
èŠãªèšå®å€ãããããã£ã«ã¢ãµã€ã³ããŠããã®ã以äžã®ç®æã§ãã viewModel.isLoading = false viewModel.items = [.stub(id : "item1" , name : "itemName1" , code : "itemCode1" )] ãããŠã以äžã® SampleView ãã芧ã«ãªã£ãŠé ããšã isLoading ã®ç¶æ
ã«å¿ããŠViewãåãæ¿ããŠããã®ã§ãä»åItemã衚瀺ããããã«ããããã false ãã»ããããŠããŸãã import SwiftUI struct SampleView : View { @StateObject var viewModel : SampleViewModel var body : some View { Group { if viewModel.isLoading { LoadingView() } else if viewModel.jobs.isEmpty { EmptyCell() } else { List { ForEach( 0 ..< viewModel.items.count, id : \. self ) { index in let item = viewModel.items[index] JobCell(item : item , didTap : { viewModel.showDetail(item : item ) }) } } } } } } 以äžã®ã³ãŒãã§ã¯èšå®ããViewModelãçšããŠViewãåæåããå
éšçã«ã¬ã³ããªã³ã°ãå®è¡ããŠããç®æã§ãã let sut = SampleView(viewModel : self.viewModel ) äžèšã®ããã«Viewãåæåããããšã§åããŠãViewInspectorã«ããViewã®åç
§ãæ€èšŒãå¯èœã«ãªããŸãã åæåã«ããè¿ãããViewã sut ãšãããããçšããŠãããŸã§ã«è§£èª¬ããŠããæ¹æ³ã§ç®åœãŠã®ViewãŸã§æãäžããŠããã®ã以äžã®å®è£
ã§ãã do { try sut.inspect() .find(SampleCell. self ) // SampleViewã®äžã®SampleCellãèŠã€ãã .find(CellButton. self ) // SampleCellã®äžã®CellButtonãèŠã€ãã .find(button : "" ) // CellButtonã®äžã®ButtonãèŠã€ããïŒããã¹ããªãïŒ .tap() // èŠã€ãããã¿ã³ãã¿ãããã } catch { XCTFail( "failed with: \( error ) " ) } ã³ã¡ã³ãã«ãããéããç¬èªã§äœæããåãæç€ºçã«æå®ããŠå¯Ÿè±¡ãšãªã Button ãŸã§æãäžããŠãããŸãã ãã®äžã§ .tap() ãå®è¡ããããšã§ãå
éšçã«ãŠãŒã¶ãŒãç¹å®ã®Itemãã¿ããããã®ãšåãåããå®çŸããŠãããšããããšã§ãã ãããŸã§æ¥ãã°ããšã¯ç°¡åã§ã .tap() ã«ããå®è¡ããããã°éä¿¡ã€ãã³ããè£è¶³ãããããããexpectãšããŠçšæããããŒã¿ãšæ¯èŒããããšã§ç°¡åã«ãã¹ãã§ããŸãã let tapEvent = MockAnalyticsEvent( name : "tap_item" , parameters : [ "info1": "sample_screen", ... ... ] ) // å®éã«éä¿¡ãããã€ãã³ããšæåŸ
ãããã€ãã³ããæ¯èŒ verify(actual : mockAnalyticsService.events , expected : [ tapEvent ] ) ã¡ãªã¿ã«ã以äžã®ãããªã¿ã€ã ã¢ãŠãåŠçãå
¥ããŠããã®ã¯ãéåæã«å®è¡ããããã°éä¿¡åŠçãå®äºããã®ãåŸ
ã€ããã§ãã wait( for : exp , timeout : 2.0 ) ãã®ããé
å»¶æéãæå®ããŠããã®ã§ãããããã«é¢ããŠã¯ããŸãåèã«ããŠã»ããã¯ãªãããã¹ãå®è¡ç°å¢æ¬¡ç¬¬ã§ã¯æ®éã«èœã¡ãŠããŸãããšããããŸã... ããã¯è§£æ¶ããã課é¡ã§ã¯ãããŸãããã»ãšãã©ã®ç°å¢ã§ã¯ããŸãæ°ã«ããããšããªãã®ã§ãçŸåšã®ãããã¯ãã³ãŒãã§ã¯äžèšã®ãããªåœ¢ã§ãç¹æ®µåé¡ã¯ãããŸããã ãããŸã§ã§è§£èª¬ããæé ã§åœåç®çãšããŠããã ã€ãã³ãå
å®¹ã®æ£ç¢ºæ§ãã§ã㯠é©åãªã¿ã€ãã³ã°ã§ãã°ãéä¿¡ãããŠãããã®ãã§ãã¯ ãæºããããšãã§ããŸããã ããšã¯ããã¹ããå¿
èŠãªç®æã§äžèšã®ããã«å®è£
ããã ãã§ãããæ
£ãããéåžžã«ç°¡åã§ãã å®éãUIãã¹ããViewInspectorãå©çšããããšããªãã¡ã³ããŒã«æ°èŠã€ãã³ãã®ãã¹ããçæããŠããããŸããããéåžžã«çæéã§å®è£
ã§ããã®ã§ãæè»œã«UIã®ãã¹ããæ§ç¯ãããå Žåã¯éåžžã«äŸ¡å€ãããã«ãªãã¯ãã§ãã ViewInspectorã®ãã¡ãªãã ãããŸã§ViewInspectorã®ã¡ãªããã«çŠç¹ãåœãŠãŠããŸããããå®éã«å©çšããŠã¿ããšãããã€ãã®ãã¡ãªããããããŸãã äžé£ã®UIåäœãç»é¢é·ç§»ã®ãã¹ããé£ãã è€éãªã¢ãã¡ãŒã·ã§ã³ããžã§ã¹ãã£ãŒæäœã«ã¯å¯Ÿå¿ããŠããªã ãã¹ãå®è¡æã«Warningãåºãããšããããåå ãäžæç¢º ç¹ã«ãäžé£ã®UIåäœããã¹ãããå ŽåãViewInspectorã§ã¯é£ãããšæããããšããããŸãã ãªããªããViewInspectorã¯äž»ã«ãã¥ãŒã®å
éšç¶æ
ãããããã£ãçŽæ¥æ€èšŒããããã«èšèšãããŠããããŠãŒã¶ãŒã®æäœãåçŸããã¢ããªå
šäœã®æµããç»é¢é·ç§»ãã¢ãã¡ãŒã·ã§ã³ãšãã£ãåçãªåäœãå
æ¬çã«ãã¹ãããã«ã¯åããŠããªãããã§ãã å®éãViewInspectorã¯UIå
šäœã®æ¯ãèãããã¹ããããšãããããåå¥ã®ã³ã³ããŒãã³ããæ£ããåäœãããã確èªããããã®ãŠããããã¹ãåãã®ã©ã€ãã©ãªã§ãã ãã®ãããã¢ããªå
šäœã®ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãè€éãªãžã§ã¹ãã£ãŒãã¢ãã¡ãŒã·ã§ã³ã®åäœãæ€èšŒãããå Žåã¯ãæšæºã®XCUITestãªã©ä»ã®ããŒã«ã䜵çšããå¿
èŠããããŸãã ãšã¯ãããç¹å®ã®ç»é¢ãã³ã³ããŒãã³ãã«çŠç¹ãåœãŠããã¹ããçŽ æ©ãæ§ç¯ãããå ŽåãViewInspectorã¯éåžžã«æçšã§ãã å°å
¥ã³ã¹ããäœããã³ã¹ãããã©ãŒãã³ã¹ãšããé¢ã§ãåªããŠãããããäœ¿ãæ¹ã«ãã£ãŠã¯ååãªäŸ¡å€ããããšæããŠããŸãã ãŸãšã UIãã¹ãã§ã¯ãiOSã«ãããŠXCUITestãçæ³çã§ããããã¬ããžãçµéšãååã§ãªãããŒã ãå€ãã®ãçŸç¶ã§ãã ãããªããŒã ã«ãšã£ãŠãViewInspectorã¯æè»œã«å°å
¥ã§ããæåãªéžæè¢ã«ãªãã®ã§ã¯ãªãã§ããããã ãŸããç§ãã¡ã¯ä»ã«ãViewInspectorã䜿ã£ããã¹ããæžããŠããŸãã ããã«ã€ããŠã¯ãŸãå¥ã®æ©äŒã«ã玹ä»ããã€ãããªã®ã§ãåŒãç¶ããèªã¿ããã ããã°å¹žãã§ãã ãããŸã§ã粟èªããã ããããããšãããããŸããã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
ã¹ã¿ã³ãã€ã¢ããã³ãã«ã¬ã³ã㌠2024 ã® 3 æ¥ç®ã§ãïŒ ïŒã¹ã¿ã³ãã€ã§ã¯ãæ¯å¹Žã¢ããã³ãã«ã¬ã³ããŒã宿œããŠããããã¡ãã«ããã®èšäºããªã³ã¯ãããŠããŸããã¹ã¿ã³ãã€ã¢ããã³ãã«ã¬ã³ããŒã«èå³ãæã£ãŠããã ããæ¹ã¯ããã¡ããã芧ããã ãããšå¬ããã§ããïŒ æ ªåŒäŒç€Ÿã¹ã¿ã³ãã€ã§ããã³ããšã³ããšã³ãžãã¢ãããŠããå·éã§ãã ããã³ããšã³ããšã³ãžãã¢ãšãã圹å²ãæ
ã£ãŠããŸãããæè¿ã§ã¯éçºè
äœéšãéçºçç£æ§ãšãããšããã«èå³ãããããã®ãããã®æ¹åã«ãããåãçµãã§ããŸãã ã¯ããã« ããã³ããšã³ãã®æ©èœã远å ãããšããè©²åœæ©èœã®åœ±é¿ãåæããäžã§ 100% å
¬éã«é²ããããç§ãã¡ã¯ãã A/B ãã¹ãã宿œããŸãã ããã€ãã®ãã¿ãŒã³ãçšæããããããã®ãã¿ãŒã³ã«å¯ŸããŠç°ãªãå®è£
ãããŸãã ãã㊠A/B ãã¹ãã®çµæããã®äŒç»ãæ£åŽãããããšã«ãªããšããã®ã³ãŒãã¯åé€ãããŸãã äžèŠãšãªã£ããã¿ãŒã³ã®ã³ãŒããåé€ããéã«ãTypeScript ã® AST ãš JSDoc ã䜿ãããšã§ãã³ãŒãã®äžããåé€ããç®æãæ©æ¢°çã«æ€åºããå®å
šã«åé€ããããã°ã©ã ãäœãããšãã§ããã®ã§ç޹ä»ããŸãã ãã ããä»å玹ä»ããæ¹æ³ã§ã¯ãæ¡ä»¶åå²ãå«ããããªè€éãªã±ãŒã¹ã«å¯Ÿå¿ã§ããŠããªãããããã¹ãŠã®ã±ãŒã¹ã«ã¯å¯Ÿå¿ã§ããŸããã å¯èœã§ããã°ãæ¹åããŠããããä»åŸã®èª²é¡ã§ãã å°ã£ãŠããããš A/B ãã¹ãã®ã³ãŒãã¯é »ç¹ã«è¿œå ãããåé€ãããŸãã ãã®ãããåé€å¯Ÿè±¡ã®ç®æãããã«ãããããã«ãã³ã¡ã³ãã¢ãŠãã䜿ã£ãŠç®å°ãæ®ããŠããŸããã ããšãã°ããã®ãããªæãã§ãã const messages = { // âââ AB ãã¹ã (KEY-042) no001: (value: string) => { return `No 001: ${value}`; }, no003: (value: string) => { return `No 003: ${value}`; }, // âââ AB ãã¹ã (KEY-042) no002: (value: string) => { return `No 002: ${value}`; }, }; ãã®æ¹æ³ã«ã¯ããã€ãã®åé¡ããããŸããã ãã A/B ãã¹ãã®ç¯å²ã«ã誀ã£ãŠå¥ã® A/B ãã¹ãã®ã³ãŒããå«ãŸããŠããŸãããšãããã å¿
èŠãªã³ãŒããŸã§æ¶ããŠããŸããªã¹ã¯ãããã é åºéãã«ã³ãŒããæžããããŠããç¯å²ã®èšè¿°ã«ãããé åºéãã«æžããªãããšãããã ããšãã°ããªããžã§ã¯ãã®ããŒãäžèšã®ãµã³ãã«ã®ããã«é£çªãšãã«ããããé åºéãã«èšè¿°çãªãã±ãŒã¹ãããã 察å¿ããã³ã¡ã³ãã¢ãŠããèšè¿°ãå¿ããããšãããã ããšãã°ãéããŠãããéããŠããªãã³ã¡ã³ãã¢ãŠããããã 人ã®ç®ã§ç¢ºèªããŠåé€ãããããåé€ãå¿ããããšãããã æåã¯ããããã®åé¡ã解決ããããã®ç®å°ã®æ®ãæ¹ãèããŠããŸããã ããã§æãã€ããã®ããJSDoc ã䜿ãããšã§ããã ãããŠãJSDoc ã䜿ãã®ã§ããã°ãæ§æè§£æããããšã§åé€å¯Ÿè±¡ã®ã³ãŒããæ€åºãããã®ãŸãŸåé€ã§ããã®ã§ã¯ãªãããšèããŸããã TypeScript ã® AST ãš JSDoc ã䜿ã£ãŠèª²é¡ã解決ãã AST (Abstract Syntax Tree: æœè±¡æ§ææš) ã¯ããœãŒã¹ã³ãŒããããªãŒæ§é ã§è¡šçŸãããã®ã§ãã AST ã䜿ãããšã§ãåé€å¯Ÿè±¡ã®ã³ãŒããããã¯ãæ€åºã§ããŸãã å
ã»ã©äŸã«æããã³ãŒãããæ¬¡ã®ããã«ä¿®æ£ããŸãã ããã§ã¯ãJSDoc ã®ã¿ã°ã abtest ã«ããŠããŸãã const messages = { /** @abtest KEY-042 */ no001: (value: string) => { return `No 001: ${value}`; }, no002: (value: string) => { return `No 002: ${value}`; }, /** @abtest KEY-042 */ no003: (value: string) => { return `No 003: ${value}`; }, }; ãã®äžããåé€å¯Ÿè±¡ãšãªãã³ãŒããããã¯ãæ€åºããåé€ããããã°ã©ã ã¯æ¬¡ã®ããã«ãªããŸãã import path from "path"; import { Node, Project } from "ts-morph"; import ts from "typescript"; const project = new Project({ tsConfigFilePath: path.join(import.meta.dirname, "/path/to/tsconfig.json"), }); const sourceFiles = project.getSourceFiles(); sourceFiles.forEach((sourceFile) => { sourceFile.forEachDescendant((node) => { // `remove` ã¡ãœãããæã£ãŠããªã `node` ããããããåãçµã蟌ãå¿
èŠããããŸãã // å¿
èŠã«å¿ããŠãçµãèŸŒãæ¡ä»¶ã远å ããŸãã if (!Node.isPropertyAssignment(node)) return; // ts-morph ã§ä»»æã® `node` ã«å¯Ÿã㊠JSDoc ãååŸããæ¹æ³ãèŠã€ããããªãã£ããããTypeScript ã®æ©èœã䜵çšããŠããŸãã // ts-morph ã§ååŸãã `node` 㯠`node.compilerNode` ãšããããšã§ã ts ã®é¢æ°ã«æž¡ãããšãã§ããŸãã const jsDocs = ts.getJSDocTags(node.compilerNode); jsDocs.forEach((jsDoc) => { if (jsDoc.tagName.text === "abtest" && jsDoc.comment === "KEY-042") { node.remove(); } }); }); sourceFile.saveSync(); }); ts.getJSDocTags ã䜿ãããšã§ã node ãæã€ JSDoc ã®ã¿ã°ã®äžèЧãååŸã§ããŸãã ãã®ã¿ã°ã®äžã«ãåé€å¯Ÿè±¡ã®æ¡ä»¶ãšåèŽãããã®ãããã°ããã® node ãåé€ããŸãã ããã§äžèŠã«ãªã£ãã³ãŒããå®å
šã«åé€ã§ããŸãã ãŸãšã TypeScript ã® AST ãš JSDoc ã䜿ãããšã§ãã³ãŒãã®äžããåé€ããç®æãæ€åºããå®å
šã«åé€ããããã°ã©ã ãäœãããšãã§ããŸããã ãããŸã§äººéãç®èŠã§æ³šææ·±ãèªã¿ãªããã³ãŒããåé€ããŠããŸããããããã°ã©ã ã«ãã£ãŠå®å
šã«è¡ããããã«ãªããŸããã JSDoc ã«ã¿ã°ãæžããŠããã ãã§ãã³ãŒããèªãŸãªããŠãäžèŠã«ãªã£ãéšåãåé€ã§ãããããäœæ¥å¹çãè¯ããªããŸããã æåã¯ã©ã®ããã«ç®å°ãæ®ããããšèããŠããã ãã ã£ãã®ããçç£æ§ã®åäžã«ãŸã§ã€ãªããããšãã§ããã®ã¯å¬ãã誀ç®ã§ããã åãçµã¿èªäœã¯ãããŸã§æŽŸæãªãã®ã§ã¯ãªãã§ããããã®ãããªå°å³ã«å¬ããæ¹åããããããç¶ããŠãããããšèããŠããŸãã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com
æ ªåŒäŒç€Ÿã¹ã¿ã³ãã€ã§ããã³ããšã³ããšã³ãžãã¢ãããŠããå·éã§ãã ããã³ããšã³ããšã³ãžãã¢ãšãã圹å²ãæ
ã£ãŠããŸãããæè¿ã§ã¯éçºè
äœéšãéçºçç£æ§ãšãããšããã«èå³ãããããã®ãããã®æ¹åã«ãããåãçµãã§ããŸãã ã¯ããã« ç§ãã¡ã®ããŒã ã§ã¯ãGoogle Apps Script (GAS) ãå©çšããŠãéãšã³ãžãã¢ã®äººãã¡ãã·ã¹ãã ã«ã¹ãã¬ããã·ãŒãã®ããŒã¿ãã¢ããããŒãã§ããä»çµã¿ãæ§ç¯ããŠããŸãã GAS ã¯æè»œã«éçºã§ãããããžã§ã¯ãéå§åœåã®å°ããªèŠæ±ãæºããã«ã¯ååãªãã®ã§ããã ãããããããžã§ã¯ããé²ãã«ã€ã次第ã«èŠä»¶ãå¢ããŠãããGAS ã§å¯Ÿå¿ããã®ã倧å€ã«ãªãã»ã©è€éã«ãªã£ãŠããŸããã ãŸã GAS ã§ã¯ãåã®æ©æµãåããããšãé£ããã£ããããšãã£ã¿ã®ãµããŒããæºè¶³ãããã®ã§ãªãã£ããããå¢å€§ããŠããè€éãã«ç«ã¡åããã®ãé£ãããªã£ãŠããŸããã ãã®ãããªèª²é¡ã解決ããéçºè
äœéšãéçºçç£æ§ãåäžãããããã«ãGAS ãã TypeScript ãžã®ç§»è¡ã決ããŸããã ãŸããããããŠãœãããŠã§ã¢ã¢ãŒããã¯ãã£ãå·æ°ããŸããã ãã®äžã§åŸãããåŠã³ãæ°ã¥ããªã©ãããã€ã玹ä»ããŸãã GAS ãã TypeScript ãžã®ç§»è¡ TypeScript ã«ç§»è¡ããã¡ãªãã TypeScript ã«ç§»è¡ããããšã§æ¬¡ã®ãããªã¡ãªãããåŸãããŸãã åã®æ©æµãåããããšãã§ããã npm ããã±ãŒãžãå©çšã§ããã ESLint ã§éçè§£æã§ããã Prettier ã§ã³ãŒããã©ãŒãããã§ããã ãã®ä»äŸ¿å©ãªã©ã€ãã©ãªãå©çšã§ããã ãã¹ããæžãããšãã§ããã ææ
£ãããšãã£ã¿ã§éçºã§ããã ããã€ãæããŸãããããã€ãã® TypeScript ã§ã®éçºãšåæ§ã®éçºè
äœéšãåŸãããããã«ãªããŸãã GAS ã¢ããªã±ãŒã·ã§ã³ã®éçºã«ãããŠãããã¯å€§ããªã¡ãªããã ãšèããããŸãã TypeScript ã§éçºããã«ã¯ TypeScript ã§éçºãããã®ã¯ãGAS ã®ãã©ãããã©ãŒã äžã«ãããã€ããå¿
èŠããããŸãã clasp ãšãã Google ãéçºããŠãã CLI ããŒã«ãããã®ã§ããããå°å
¥ããå¿
èŠããããŸãã ãããŠåŸè¿°ã®çç±ã«ãããTypeScript ã®ã³ãŒããäžåºŠ JavaScript ã«ãã«ãããå¿
èŠããããŸãã ç§ãã¡ã®ãããžã§ã¯ãã§ã¯ã次ã®ãã㪠npm scripts ãçšæãããã«ããšãããã€ãå®è¡ã§ããããã«ããŸããã { " scripts ": { " build:<feature> ": " vite build -c src/features/<feature>/vite.config.ts ", " deploy:<feature> ": " clasp -P <output>/<feature> push " } } åŸè¿°ããŠããŸãããç§ãã¡ã®ãããžã§ã¯ãã§ã¯ Package by Feature ãæ¡çšããŠããŸãã ãã®ãããããããã®æ©èœããšã« vite.config.ts ãçšæãããŠãããããã« <output> ã®ãã¹ãèšè¿°ãããŠããŸãã clasp ã䜿ããšãã®æ³šæç¹ clasp ã¯ãTypeScript ã®ã³ãŒãã GAS ã®ã³ãŒãã«å€æããæ©èœãæã£ãŠããŸãããæ³šæãã¹ãå¶çŽããããŸãã ããã¯ãimport/export æ§æãæ±ãããšãã§ããªãããšã§ãã ãã®ããããããã€ããåã« TypeScript ã®ã³ãŒãããã«ãããå¿
èŠããããŸãã ãã«ãã«ã¯ Vite ãå©çšããŸããã ïŒå°æ¥çã«åã£ã UI ãäœããããªã£ããšãã®ããšãèŠéã«å
¥ããŠãïŒ ãã«ããããšãã®æ³šæç¹ GAS ã«ã¯ããªã¬ãŒãšåŒã°ãããçµã¿èŸŒã¿ã®äºçŽæžã¿é¢æ°ããããŸãã ããšãã°ã onOpen ã doGet ãšãã£ã颿°ã§ãã ãã®ãããªé¢æ°ã¯ãTypeScript ã®ã³ãŒãäžããã¯åç
§ãããŸããã ãã®ããããã«ãæã®ããªãŒã·ã§ã€ãã³ã°ãæå¹ã«ãªã£ãŠãããšããããã®é¢æ°ãåé€ãããŠããŸããæ£åžžã«åäœããªããªããŸãã ãã®åé¡ã«å¯ŸããŠãå°çšã® Vite ã®ãã©ã°ã€ã³ãäœãããšã§è§£æ±ºããŸããã import fs from "fs/promises"; import type { Plugin } from "vite"; interface Options { inputDir: string; outputDir: string; } export const keepGasTrigger = ({ inputDir, outputDir }: Options): Plugin => { const GAS_TRIGGER = [ "onOpen", "onInstall", "onEdit", "onSelectionChange", "doGet", "doPost", ]; // 1. ããªã¬ãŒé¢æ°ãå©çšãããããŒã³ãŒããçæããã const dummyCodes = GAS_TRIGGER.map( (trigger) => `void ${trigger}.name.toString();` ).join("\n"); return { name: "vite-plugin-keep-gas-trigger", config: (config) => { return { ...config, build: { rollupOptions: { input: `${inputDir}/main.ts`, output: { dir: outputDir, entryFileNames: "[name].js", format: "commonjs", }, }, }, }; }, transform: (code, id) => { // 2. ãããŒã³ãŒããã³ãŒãã®æ«å°Ÿã«è¿œå ããã if (id.includes("main.ts")) return [code, dummyCodes].join("\n"); return code; }, closeBundle: async () => { const filePath = `${outputDir}/main.js`; const code = await fs.readFile(filePath, "utf-8"); // 3. ãã«ãåŸã®ã³ãŒããããããŒã³ãŒããåé€ããã const transformed = code.replace(`${dummyCodes}\n`, ""); await fs.writeFile(filePath, transformed, "utf-8"); }, }; }; ãã®ããã«ããã«ãåã«ããªã¬ãŒé¢æ°ãå©çšãããããŒã³ãŒãã远å ãããã«ãåŸã«ãã®ãããŒã³ãŒããåé€ãããšããããã£ããåæãªããšãããŠããŸãã æ¬åœã«ããã§ããã®ãïŒãšããçåãæããªãã®ã§ãè¯ã解決çãèŠã€ããã°ãä¹ãæããããšæã£ãŠããŸã⊠ãœãããŠã§ã¢ã¢ãŒããã¯ãã£ã®å·æ° ã©ã®ããã«å·æ°ããã TypeScript ãžã®ç§»è¡ã«äŒŽãããœãããŠã§ã¢ã¢ãŒããã¯ãã£ã倧å¹
ã«å·æ°ããŸããã ãšããã®ãããã®ãŸãŸç§»æ€ããã®ã§ã¯è€éããå€åããŠããèŠä»¶ã«ç«ã¡åããããšãã§ããªããšæã£ãããã§ãã ãœãããŠã§ã¢ã¢ãŒããã¯ãã£ãèŠçŽãããšã§ãããä¿å®æ§ã®é«ãã³ãŒããæžãããšãã§ããããã«ãªããéçºè
äœéšãéçºçç£æ§ãåäžãããããšãã§ãããšèããŸããã ã¢ãŒããã¯ãã£ã¯ãã¯ãªãŒã³ã¢ãŒããã¯ãã£ç³»ããŒã¹ã«ãã以äžã®ãããªãã£ã¬ã¯ããªæ§æã«ããŸããã src âââ features âââ awesome_feature # ã¹ãã¬ããã·ãŒãåäœã§æ©èœãäœæãã âââ controller # å€çãšã®ããåããæ±ãã³ã³ãããŒã©ãæ ŒçŽãã âââ core # ãµãŒãã¹ãã¢ãã«ãªã©ããžãã¹ããžãã¯ãæ±ããã®ãæ ŒçŽãã âââ spreadsheet # ã¹ãã¬ããã·ãŒãã«é¢ãããã®ãæ ŒçŽãã âââ main.ts # ãšã³ããªãŒãã€ã³ãïŒããªã¬ãŒé¢æ°ã®èšè¿°çãè¡ãªã£ãŠããïŒ âââ vite.config.ts # Vite ã®èšå®ãã¡ã€ã«ïŒæ¬æ©èœã®ãã«ãçšïŒ spreadsheet 㯠controller ã core ãªã©æ··ãã£ãŠå¯çµåããªãããã«ãå€ããã³ã³ã¹ãã©ã¯ã¿ãçµç±ããŠäŸå泚å
¥ããããã«ããŸããã ãŸããPackage by Feature ãæ¡çšããæ©èœããšã«ãã£ã¬ã¯ããªãåããæ§æã«ããŸããã ããããããšã§è²¬åãæŽçãããã³ãŒãã®ä¿å®æ§ãé«ãŸããã³ãŒãã®èªã¿æžãããããããªããšèããããã§ãã ã¹ãã¬ããã·ãŒãã®æ±ã ä»åã®èŠä»¶ã§ã¯ãããŒã¿ãã¢ããããŒãããåã«ããªããŒã·ã§ã³ãè¡ãå¿
èŠããããŸãã ã¹ãã¬ããã·ãŒãã¯ããŒã¿ããŒã¹ã®ãããªãã®ã§ãä»ãŸã§ Repository ãã¿ãŒã³ã䜿ã£ãŠããŒã¿ãååŸãããã®ã ãšæã£ãŠããŸããã ãããããã®èãæ¹ã ãšãRepository ããååŸããããŒã¿ã«å¯ŸããŠããªããŒã·ã§ã³ãè¡ãå¿
èŠãåºãŠããŸãã å人çã«ãRepository ããååŸããããŒã¿ã«å¯ŸããŠããªããŒã·ã§ã³ãè¡ãã®ã¯ãéåæã®ããå®è£
ã§ããã ããŒã¿ããŒã¹ã«ã¯ããªããŒã·ã§ã³æžã¿ã®å®å
šãªããŒã¿ãæ ŒçŽãããŠããã€ã¡ãŒãžããã£ãããã§ãã ããã§èãæ¹ãå€ããã¹ãã¬ããã·ãŒãã®ããŒã¿ããã©ãŒã å
¥åã®ãããªãã®ããšã¿ãªãããšã«ããŸããã ã¹ãã¬ããã·ãŒãã®ããŒã¿ããå
¥åå€ãšããŠã³ã³ãããŒã©ã§ååŸããããªããŒã·ã§ã³ãè¡ãããã«ããããšã§ãããèªç¶ãªå®è£
ã«ã§ããŸããã åãã¹ãã¬ããã·ãŒãã§ããããŒã¿ã®æ±ãæ¹æ¬¡ç¬¬ã§ã¯è²¬åãç°ãªãããããèŠæ¥µããŠé©åãªã¬ã€ã€ãŒã«åŠçãæžãããšãéèŠã ãšæããŸããã ãŸãšã Google Apps Script ã®éçºç°å¢ãå·æ°ããTypeScript ãžç§»è¡ããŸããã ãã®éã«ããœãããŠã§ã¢ã¢ãŒããã¯ãã£ãå·æ°ãã責åãæŽçããããšã«ãã£ãŠä¿å®æ§ãé«ãŸããã³ãŒãã®èªã¿æžãããããããªããŸããã ä»åŸããéçºè
äœéšãéçºçç£æ§ãåäžãããããã«ããã®ãããªåãçµã¿ã«ç©æ¥µçã«åãçµãã§ãããããšèããŠããŸãã ã¹ã¿ã³ãã€ã®ãããã¯ããçµç¹ã«ã€ããŠè©³ããç¥ãããæ¹ã¯ãæ°è»œã«ãçžè«ãã ããã www.wantedly.com