ã¯ããã« ããã«ã¡ã¯ã @ãã㌠ã§ãïŒæ®æ®µã¯ããªãã·ã¥ãããã³éçºéšã®ããã¯ãšã³ãäžå¿ã§æ¥åãããŠããŸãã AWS ã® CloudFront 㯠CDN ãšããŠã®åºæ¬çãªæ©èœãããã ãã§ãªãããšããžã§åŠçãå®è¡ã§ãããæ©èœãããããšããåç¥ã§ããããïŒ CloudFront ã«ã¯äž»ã« 2 ã€ã®ãšããžå®è¡æ©èœããããŸãã CloudFront Functions - 軜éã»é«éãªåŠççš Lambda@Edge - è€éãªåŠççš ãã®èšäºã§ã¯ãCloudFront Functions ãåããŠäœ¿ã£ãéã«ééãããJavaScript ã®å¶çŽãã«ã€ããŠãå®äœéšãåºã«è©³ãã解説ããŸããç¹ã« const ã exports ã䜿ããªããšãããJavaScript éçºè
ãé¥ããã¡ãªçœ ãšããã®è§£æ±ºçããäŒãããŸãã CloudFront Functions ãšã¯äœãïŒ CloudFront Functions ã¯ãCloudFront ã«çµã¿èŸŒãŸãã 軜éã»é«é ãªãšããžå®è¡æ©èœã§ãã å
¬åŒããã¥ã¡ã³ãã«ãããšã以äžã®ç¹åŸŽãæã¡ãŸãã å€§èŠæš¡ã§ã¬ã€ãã³ã·ãŒã®åœ±é¿ãåãããã CDN ã«ã¹ã¿ãã€ãºã®ããã®è»œéãªé¢æ°ã JavaScript ã§èšè¿°ã§ããŸããCloudFront Functions ã® runtime ç°å¢ã¯ãèµ·åæéã 1 ããªç§æªæºãæ¯ç§æ°çŸäžã®ãªã¯ãšã¹ããåŠçããããã«ããã«ã¹ã±ãŒã«ã§ããé«ãå®å
šæ§ãèªããŸãã åºå
ž: AWS CloudFront Developer Guide - CloudFront Functions ãš Lambda@Edge ã®éã CloudFront Functions ãæé©ãªçšé AWS ãæšå¥šããäž»ãªçšé ãã£ãã·ã¥ããŒæ£èŠå HTTP ãªã¯ãšã¹ã屿§ïŒããããŒãã¯ãšãªæååãCookieãURL ãã¹ïŒã倿 æé©ãªãã£ãã·ã¥ããŒãäœæããŠãã£ãã·ã¥ãããçãåäž ããããŒæäœ ãªã¯ãšã¹ããã¬ã¹ãã³ã¹ã§ HTTP ããããŒã®æ¿å
¥ã倿Žãåé€ äŸïŒ True-Client-IP ããããŒã®è¿œå URL ãªãã€ã¬ã¯ãã»ãªã©ã€ã ãªã¯ãšã¹ãæ
å ±ã«åºã¥ããã¥ãŒã¢ãŒã®ä»ããŒãžãžã®ãªãã€ã¬ã¯ã ç¹å®ãã¹ããå¥ãã¹ãžã®ãªã¯ãšã¹ããªã©ã€ã ãªã¯ãšã¹ãèªèšŒ ããã·ã¥åãããèªèšŒããŒã¯ã³ïŒJWT çïŒã®æ€èšŒ èªèšŒããããŒãä»ã®ãªã¯ãšã¹ãã¡ã¿ããŒã¿ã®æ€èšŒ CloudFront Functions ã§è©°ãŸã£ããã€ã³ã èªåã¯äžèšã®çšéã§ãè§ŠããããŠãã URL ã®ãªãã€ã¬ã¯ãã»ãªã©ã€ãããæã®åŠçãæžãããšããéã«è©°ãŸããŸããã æåã«æžããã³ãŒãïŒåããªãïŒ CloudFront FunctionsïŒJavaScript ã©ã³ã¿ã€ã 1.0ïŒã«ä»¥äžã®ãããªã³ãŒããæžããŸããã // â ããã¯åããªã const handler = ( event ) => { const request = event . request ; const uri = request . uri ; // URLæžãæãã®åŠç return request ; } ; exports . handler = handler ; ééãããšã©ãŒ ãã®ã³ãŒãã CloudFront Functions ã«ãããã€ããŠå®éã«ã¢ã¯ã»ã¹ããããšãããšã以äžã®ãã㪠503 ãšã©ãŒãçºçããŸããã 503 ERROR The request could not be satisfied. The CloudFront function associated with the CloudFront distribution is invalid or could not run. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner. If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation. ãããã€èªäœã¯æåããŠããã®ã«å®éã«ã¢ã¯ã»ã¹ãããš 503 ãšã©ãŒã«ãªã£ãŠããŸãããæ§æçã«ãåé¡ãªããšæã£ãŠããã®ã§æåã¯ãïŒãã§é ããã£ã±ãã§ããã ãã©ãã«ã·ã¥ãŒãã£ã³ã° ãã®åé¡ã®è§£æ±ºã«ã¯ã ã¯ã©ã¹ã¡ãœããããã®èšäº ãéåžžã«åèã«ãªããŸããã äžèšã®èšäºã§ã玹ä»ãããŠããŸãããCloudFront ã®ã³ã³ãœãŒã«ãã Functions ã®ãã¹ãæ©èœã䜿ã£ãŠèª¿ã¹ãŠã¿ããšã以äžã®ãããªå
·äœçãªãšã©ãŒã¡ãã»ãŒãžã確èªã§ããŸããã The CloudFront function associated with the CloudFront distribution is invalid or could not run. SyntaxError: Token "const" not supported in this version in 2 ã€ãŸãã颿°èªäœã®æ§æãšã©ãŒãåå ã§ CloudFront Functions ãå®è¡ã«å€±æããçµæãšã㊠503 ãšã©ãŒãè¿ãããŠããã®ã§ãã åå ïŒ ECMAScript 5.1 æºæ ãšããå¶çŽ èª¿ã¹ãŠã¿ããšãCloudFront FunctionsïŒJavaScript ã©ã³ã¿ã€ã 1.0ïŒã¯ ECMAScript 5.1 æºæ ãšããå¶çŽããããŸããã CloudFront Functions ã® JavaScript ã©ã³ã¿ã€ã ç°å¢ã¯ ECMAScript (ES) ããŒãžã§ã³ 5.1 ã«æºæ ããŠãããES ããŒãžã§ã³ 6 ïœ 9 ã®äžéšã®æ©èœããµããŒãããŠããŸãã åºå
ž: AWS CloudFront Developer Guide - JavaScript ã©ã³ã¿ã€ã 1.0 ã®æ©èœ å
·äœçãªå¶çŽ â 䜿çšäžå¯æ©èœïŒ const / let ã¹ããŒãã¡ã³ã exports / module.exports / import / require â
䜿çšå¯èœãª ES6+ æ©èœïŒ ã¢ããŒé¢æ° ãã³ãã¬ãŒããªãã©ã«ïŒè€æ°è¡ã®æååãåŒã®è£éïŒ ã¬ã¹ããã©ã¡ãŒã¿æ§æ ES6-ES9 ã®äžéšãªããžã§ã¯ãã»é
åã»æååã¡ãœãã ã€ãŸããES5.1 + äžéšã® ES6+ ã®æ©èœãšããæ§æã«ãªã£ãŠããŸãã äžèšã®å¶çŽãšèªåã®ã³ãŒããèŠæ¯ã¹ãŠã¿ããšä»¥äžã®ç¹ã§æ§æãšã©ãŒã«ãªã£ãŠããŸããã const ã¹ããŒãã¡ã³ã 㯠JavaScript ã©ã³ã¿ã€ã 1.0 ã§ãµããŒããããŠããªã exports ã¹ããŒãã¡ã³ã 㯠JavaScript ã©ã³ã¿ã€ã 1.0 ã§ãµããŒããããŠããªã 解決çãšåé¿æ¹æ³ 解決ç 1ïŒ ã©ã³ã¿ã€ã 1.0 察å¿ã®æžãæ¹ã«ãã ã©ã³ã¿ã€ã 1.0 ã䜿ãå Žåã¯ãexports ãš const ã䜿ããªãïŒvar ã䜿ãïŒããšã§å¯Ÿå¿ã§ããŸãã // â
ã©ã³ã¿ã€ã 1.0 ã§åäœãã function handler ( event ) { var request = event . request ; var uri = request . uri ; // URLæžãæãã®åŠç return request ; } 解決ç 2ïŒ JavaScript ã©ã³ã¿ã€ã 2.0 ã䜿çšãã 2024 幎åæã«ç»å Žãã JavaScript ã©ã³ã¿ã€ã 2.0 䜿ãå Žåã¯ãexports ã ãã䜿ããªãããã«ããã ãã§å¯Ÿå¿ã§ããŸããïŒæåããå°å
¥ããå Žå㯠JavaScript ã©ã³ã¿ã€ã 2.0 ã䜿çšããããšããå§ãããŸãïŒ github.com // â
ã©ã³ã¿ã€ã 2.0 ã§ã¯åäœãã function handler ( event ) { const request = event . request ; // const ã¯äœ¿ãã const uri = request . uri ; // URLæžãæãã®åŠç return request ; } CloudFront Functions ã«ããã JavaScript ã©ã³ã¿ã€ã ã®ç¹åŸŽ å
ã»ã©ãã話ã§è§ŠããŠããã©ã³ã¿ã€ã ã«ã€ããŠã§ãããCloudFront Functions ã§ã¯ãJavaScript ã®å®è¡ç°å¢ãšã㊠2 ã€ã®ã©ã³ã¿ã€ã ãæäŸãããŠããŸããããããã®ç¹åŸŽãšå¶çŽã«ã€ããŠç޹ä»ããŸãã JavaScript ã©ã³ã¿ã€ã 1.0ïŒECMAScript 5.1 æºæ ïŒ JavaScript ã©ã³ã¿ã€ã 1.0 㯠ECMAScript 5.1 ãåºç€ãšããŠããã以äžã®æ©èœã䜿çšã§ããŸãã åºæ¬çãªå¶åŸ¡æ§æïŒ break ã catch ã continue ã do-while ã else ã finally for ã function ã if ã label ã return ã switch throw ã try ã var ã while ES6+ ã®äžéšæ©èœïŒ ã¢ããŒé¢æ° ãã³ãã¬ãŒããªãã©ã«ïŒè€æ°è¡ã®æååãåŒã®è£éïŒ ã¬ã¹ããã©ã¡ãŒã¿æ§æ ES6-ES9 ã®äžéšãªããžã§ã¯ãã»é
åã»æååã¡ãœãã 䜿çšã§ããªãæ©èœïŒ const ã let ã¹ããŒãã¡ã³ã async ã await ã¢ãžã¥ãŒã«é¢é£æ©èœïŒ exports ã require ãªã©ïŒ JavaScript ã©ã³ã¿ã€ã 2.0ïŒES6-ES12 察å¿ïŒ JavaScript ã©ã³ã¿ã€ã 2.0 ã§ã¯ãã©ã³ã¿ã€ã 1.0 ã®å
šæ©èœã«å ããŠãããå€ãã® JavaScript æ©èœã䜿çšã§ããŸãã ã©ã³ã¿ã€ã 1.0 ããã®äž»ãªè¿œå æ©èœïŒ const ã let ã«ãããããã¯ã¹ã³ãŒã倿°å®£èš async ã await ã«ããéåæåŠç ãã®ä» ES6-ES12 ã®æ©èœ 泚æç¹ïŒ ã¢ãžã¥ãŒã«æ©èœïŒ exports ã require ã import ãªã©ïŒã¯åŒãç¶ã䜿çšäžå¯ å
±éã®å¶çŽäºé
äž¡ã©ã³ã¿ã€ã å
±éã§ã以äžã®æ©èœã¯äœ¿çšã§ããŸããã åçã³ãŒãè©äŸ¡ïŒ eval() ã new Function() éåæã»ã¿ã€ããŒïŒ setTimeout() ã setInterval() ãããã¯ãŒã¯ïŒ fetch() ã XMLHttpRequest() ã¢ãžã¥ãŒã«ïŒ require() ã import ã exports ã module.exports ã·ã¹ãã ïŒ process.env ããã¡ã€ã«ã·ã¹ãã ã¢ã¯ã»ã¹ 倧ããå€ããç®æã«ã€ããŠåãäžããŸãããããã®ä»è©³çްã«ã€ããŠã¯ä»¥äžã®å
¬åŒããã¥ã¡ã³ããã芧ãã ããã AWS CloudFront Developer Guide - CloudFront Functions ã® JavaScript ã©ã³ã¿ã€ã 1.0 ã®æ©èœ AWS CloudFront Developer Guide - CloudFront Functions ã® JavaScript ã©ã³ã¿ã€ã 2.0 ã®æ©èœ ããã©ãŒãã³ã¹ãšãã¬ãŒããªã åé ã§ãè§ŠããŸããããCloudFront Functions ã¯ä»¥äžã®ç¹åŸŽãæã€ããã«èšèšãããŠããŸãã å€§èŠæš¡ã§ã¬ã€ãã³ã·ãŒã®åœ±é¿ãåãããã CDN ã«ã¹ã¿ãã€ãºã®ããã®è»œéãªé¢æ°ã JavaScript ã§èšè¿°ã§ããŸããCloudFront Functions ã® runtime ç°å¢ã¯ãèµ·åæéã 1 ããªç§æªæºãæ¯ç§æ°çŸäžã®ãªã¯ãšã¹ããåŠçããããã«ããã«ã¹ã±ãŒã«ã§ããé«ãå®å
šæ§ãèªããŸãã ãããã®æ¥µéçãªããã©ãŒãã³ã¹èŠä»¶ãå®çŸãããããAWS ã¯ä»¥äžã®æè¡ç倿ãè¡ã£ãŠããŸãã 1. 軜éã©ã³ã¿ã€ã ã®æ¡çš ECMAScript 5.1 ãåºç€ãšããå³éžããã ES6-ES12 æ©èœã®ã¿ã远å ãšããžã«èŒãã颿°ã®éçºäœéšãä¿ã¡ã€ã€ãå®è¡ç°å¢ã軜éå 2. 峿 Œãªå¶éã«ããæé©å AWS å
¬åŒããã¥ã¡ã³ãã«ãããšã以äžã®æ©èœå¶éãå®è£
ããŠããŸãã ã»ãã¥ãªãã£å¶é: åçã³ãŒãè©äŸ¡ã®çŠæ¢ - eval() ã Function ã³ã³ã¹ãã©ã¯ã¿ã¯ãšã©ãŒ ãããã¯ãŒã¯ã¢ã¯ã»ã¹é®æ - XHRãHTTP(S)ããœã±ããéä¿¡ã¯äžå¯ ã·ã¹ãã ã¢ã¯ã»ã¹çŠæ¢ - ãã¡ã€ã«ã·ã¹ãã ãããã»ã¹ãç°å¢å€æ°ãžã®ã¢ã¯ã»ã¹äžå¯ ããã©ãŒãã³ã¹å¶é: ã¿ã€ããŒæ©èœç¡å¹å - setTimeout() çã¯äžå¯ãåæå®è¡ã®ã¿ æé枬å®å¶é - é«è§£å床ã¿ã€ããŒçŠæ¢ãçµéæé枬å®äžå¯ ã¡ã¢ãªå¶åŸ¡ - æå€§ 2MB ãšãã峿 Œãªå¶çŽ åºå
ž: AWS CloudFront Developer Guide - å¶éãããæ©èœ ãããã®å¶éã«ããããèµ·åæéã 1 ããªç§æªæºãæ¯ç§æ°çŸäžã®ãªã¯ãšã¹ããåŠçããããã«ããã«ã¹ã±ãŒã«ã§ããé«ãå®å
šæ§ãããå®è¡ç°å¢ããå®çŸãããŠããŸãã ãŸãšã ã©ã³ã¿ã€ã 2.0 ãéžã¶ - const ã let ãªã© 1.0 ã«æ¯ã¹æžããæ§æãå¢ãã exports ã¯äœ¿ããªã - ã¢ãžã¥ãŒã«åã¯è«ŠããŠé¢æ°å
ã§æŽç å¶çŽã¯ãå¶éãã§ã¯ãªããæé©åã - ããã©ãŒãã³ã¹éèŠã®æå³çãªèšèš æåŸã« æåã¯ããªã const ã䜿ããªãã®ïŒãããã€ãã® JavaScript ãåããªãããšããäžæºããå§ãŸããŸãããã調ã¹ãŠãããã¡ã«ããããã®å¶çŽããã¹ãŠããã©ãŒãã³ã¹ãåäžãããããã«æå³çã«èšèšããããã®ã ãšããããšãããããŸããïŒ ä»åã¯ããŸãè§ŠããŸããã§ããããå¶çŽãçè§£ããããšã§ Lambda@Edge ãš CloudFront Functions ãã©ã䜿ãåããŠããã°è¯ããçè§£ã§ããæ°ãããŸããããããéçºããŠããéã«ããããŒã«ããšã®ç¹æ§ãçè§£ããŠé©åã«äœ¿ã£ãŠãããããšæããŸãã ãã®èšäºããã¿ãªããã®å©ãã«ãªããã幞ãã§ãïŒ
ã¯ããã« ããã«ã¡ã¯ã éçºæ¬éš éçº1éš ããªãã·ã¥ãªãµãŒãããŒã ã§ããŒã¿ãšã³ãžãã¢ãããŠããåç°ã§ãã ä»åã¯ãRedashã®ã¹ã±ãžã¥ãŒã«ã¯ãšãªãæŽçããããŒã¿ãŠã§ã¢ããŠã¹ïŒDWHïŒã®ã³ã¹ããæé©åãã話ãã玹ä»ããŸãã èæ¯ ããªãã·ã¥ãããã³ã§ã¯ãããŒã¿åæãå¯èŠåã®ããã«BIããŒã«ãšããŠRedashãæŽ»çšããŠããŸãã ããŒã¿åºç€ãšããŠã¯ãDWHã®TreasureDataã«Databricksã§å å·¥ããããŒã¿ãéçŽããRedashããTreasureDataãžã¯ãšãªãçºè¡ããŠããŒã¿ãå¯èŠåããããšããã¢ãŒããã¯ãã£ã§ãã ãããªäžãTreasureDataã®ã¯ãšãªå®è¡æéãå¥çŽã®äžéã«è¿ã¥ããã³ã¹ãå¢å ã®æžå¿µãçããŠããŸããã èª²é¡ èª²é¡ãšãªã£ãŠããã®ããRedashã«ç»é²ããã倿°ã®ã¹ã±ãžã¥ãŒã«ã¯ãšãªã§ãã ãããã®ã¯ãšãªã¯é·å¹Žæ£åžããããŠããããäžã«ã¯èª°ã«ãèŠãããŠããªããããã°ã幜éã¯ãšãªããå®è¡ããç¶ããŠããç¶æ
ã§ããã TreasureDataã¯ã¯ãšãªãšã³ãžã³(Presto)ã®çšŒåæéã«äžéããããããå©çšå®æ
ã®ãªãã¯ãšãªã®å®è¡ã¯ãç¡é§ãªãªãœãŒã¹æ¶è²»ãšã³ã¹ãå¢ã«çŽçµããŸãã åãçµã¿ ããã§ãäžèŠãªã¹ã±ãžã¥ãŒã«ã¯ãšãªãç¹å®ãã忢ã»åé€ããåãçµã¿ãè¡ããŸããã æé ã¯ä»¥äžã®éãã§ãã å©çšãããŠããªãã¹ã±ãžã¥ãŒã«ã¯ãšãªã®æŽãåºã ã¯ãšãªææè
ãžã®åé€å¯åŠã®ç¢ºèª äžèŠãªã¹ã±ãžã¥ãŒã«ã®äžæåé€ 1. å©çšãããŠããªãã¹ã±ãžã¥ãŒã«ã¯ãšãªã®æŽãåºã Redashã¯ãã¯ãšãªã®å®è¡ãç»é¢ã®é²èЧãšãã£ãæäœãã°ã events ãšããããŒãã«ã«ä¿åãããŠããŸãã ãã® events ããŒãã«ãåæããã宿å®è¡ãããŠããã«ããããããããã®å®è¡çµæãäžå®æé誰ã«ãé²èЧãããŠããªãã¯ãšãªãããªã¹ãã¢ããããŸããã 2. ã¯ãšãªææè
ãžã®åé€å¯åŠã®ç¢ºèª æŽãåºããã¯ãšãªã®äžèЧãäœæããããããã®ã¯ãšãªã®äœæè
ã«ã¹ã±ãžã¥ãŒã«ã®åé€ããŸãã¯ã¯ãšãªèªäœã®åé€ãå¯èœãã確èªã»äŸé ŒããŸããã ããã«ãããçŸåšã¯å©çšãããŠããªããã®ã®ãä»åŸå©çšããå¯èœæ§ããããšãã£ãã¯ãšãªãæ®ãã€ã€ãå®å
šã«æŽçãé²ããããšãã§ããŸããã 3. äžèŠãªã¹ã±ãžã¥ãŒã«ã®äžæåé€ é¢ä¿è
ããã®ç¢ºèªãåããã¯ãšãªã«å¯ŸããŠãäžæã«ã¹ã±ãžã¥ãŒã«ãåé€ããŸããã çµæ ãã®åãçµã¿ã®çµæãã¹ã±ãžã¥ãŒã«å®è¡ãããŠããã¯ãšãªã®ç·å®è¡æéã çŽ50%åæž ããããšã«æåããŸããã ããã«ãããTreasureDataã®Prestoã®çšŒåæéã倧å¹
ã«å§çž®ããé©åãªå©çšç¯å²ã«åããããšãã§ããŸããã ãŸãšã ä»åã¯ãRedashã®ã€ãã³ããã°ã掻çšããŠäžèŠãªã¹ã±ãžã¥ãŒã«ã¯ãšãªãç¹å®ã»æŽçããDWHã®è² è·åæžãšã³ã¹ãæé©åãå®çŸããäºäŸãã玹ä»ããŸããã ä»åŸã¯ã宿çãªæ£åžãã®ä»çµã¿åããã¯ãšãªäœææã®ã¬ã€ãã©ã€ã³ãæŽåããããšã§ãè²»çšå¯Ÿå¹æã®é«ãããŒã¿æŽ»çšåºç€ãç¶æããŠãããããšèããŠããŸãã
ç®æ¬¡ ã¯ããã« èæ¯ çŸç¶ã®ææ¡ AWS CodeBuild GitHub Actions ãããã³ãŒã æ¹åãããšãã äžèŠãªã³ãŒãåé€ ãã£ãã·ã¥ã®æå¹æŽ»çš Codebuild GitHub Actions ãŸãšã ã¯ããã« ããã«ã¡ã¯ãéçºæ¬éšéçº 1 éšãã¢ããã°ã«ãŒãã®ãšã³ãžãã¢ã® rymiyamoto ã§ãã ãããã¯ããå®å¿å®å
šã«æäŸããã«åœãããCI/CD ãçšããŠãã¹ãããããã€ãèªååããããšã§ãæäœæ¥ãåãé€ããŠããã®ã¯æšä»ã®æµãã§ãã ããããCI/CD ã®ãã€ãã©ã€ã³ãé·ãééçšããã«ãããããã¹ãããããã€ã®æéãé·ããªããšãã課é¡ããããŸãããCI/CD ã®ãã£ãæ°åã®é
å»¶ããéçºããŒã å
šäœã®çç£æ§ã®äœäžãåŒãèµ·ããããšããããŸãã ããã§ãCI/CD ã®ãã€ãã©ã€ã³ãå°ãã§ãæ©ãããããã«ãããã詊ããŠã¿ãã®ã§ãã®åå¿é²ãšãªããŸãã èæ¯ ç§ãé¢ãã£ãŠãã ãã¢ãã(æ§ MAMADAYS) ã¯ãµãŒãã¹ãšããŠã¯ 2019 幎 7 æã« web ãµã€ããå
¬éããã10 æã«ã¯ã¢ããªã®ãªãªãŒã¹ãè¡ã£ãŠããŸãããããŸã§ãŸã 幎å£ãçµã£ãŠããããã§ã¯ãããŸãããæ°å¹Žééçºãè¡ãããŠããããµãŒãã¹èŠæš¡ãå°ããã€å€§ãããªã£ãŠããŠããŸãã ããæ¥ã¡ã³ããŒãããæè¿ API ãµãŒã㌠㮠CI é
ããªãã§ããïŒããšçžè«ãåããŸããã API ãµãŒããŒã¯ Go èšèªã§æžãããŠãã AWS CodeBuild ã§ãããã€ããGitHub Actions ã§ãã¹ããåããŠããŸãã (ãªã CI/CD ã§å¥ã®ãµãŒãã¹ãå©çšããŠããããšãããšããµãŒãã¹èªäœã¯ AWS ã§çšŒåããŠããåœæã¯èªèšŒåšãã AWS ã§å®çµããã»ããæ¥œã§äœ¿ãããŠããŸãããéäžãã CI ã ãã§ã GitHub Actions ã詊ãããã«ãªã£ãèæ¯ããããŸã) å®éã«ç¢ºèªãããšãã以äžã®ãããªç¶æ³ã«ãªã£ãŠããŸããã ãµãŒãã¹ æé AWS CodeBuild(ãããã€) 15 å GitHub Actions(ãã¹ã) 10 å æéãšããŠã¯ 30 åã 1 æéã®ããã«ãã®ãããããã£ãŠãããšããããã§ã¯ãããŸããããæ°åã®éããéçºã®é床ã«åœ±é¿ããŠããŸãããŸãå®è¡æéã®é·ããã³ã¹ãã«ãè·³ãè¿ã£ãŠãããŸãã ããã§ãã®åºŠããããã®ãã€ãã©ã€ã³ãèŠçŽããŠã¿ãããšã«ããŸããã çŸç¶ã®ææ¡ AWS CodeBuild ãã¢ããã§ã¯ AWS Elastic Container Service(以é ECS) ãå©çšããŠããŸãã ãã®ãã AWS Elastic Container Registry(以é ECR) ã§ã€ã¡ãŒãžã管çããŠããŸãã å
éšãšããŠãã£ãŠããããšã¯ãã£ããæžããŠä»¥äžã®ãšããã§ãã ecs-deploy ã®ã€ã³ã¹ããŒã« Docker Hub ãš ECR ã®èªèšŒ ã€ã¡ãŒãžã®ãã«ã&ã¿ã°ä»ã ECR ãžã®ããã·ã¥ ECS ãžã®ããã〠å
éšãèŠãŠã¿ããšãã«ãæã®éœåºŠãã£ãã·ã¥ãªãã§ã®å®è¡ãããŠããããã«ãæéãé·ããªã£ãŠããŸããã ãŸããã«ãã«åœ±é¿ãã Docker é¢é£ãèŠçŽããŠã¿ãŸããã Dockerfile ã®äžèº«ã確èªãããšããã go mod download ãªãã§ãã«ãã®ã¹ããŒãžã§ãã«ãããŠããããšãããããŸããã ã»ãã ãš .dockerignore ãããŸãå¹ããŠããããã³ãŒãã®ã³ããŒæã«åœ±é¿ããªãéšåãå·®åãšããŠæ€ç¥ãããŠããŸãã GitHub Actions ãã¹ã㯠DB ã䜿ããã¹ããšäœ¿ããªããã¹ããåããŠããŸãããã¡ãã¯ãã¹ãã ããç®çãªã®ã§ããã¹ãã®å®è¡èªäœã¯ã³ã³ãããçšããã« actions/setup-go ã§ç°å¢ãçšæããŠããŸãã 䞊ååãè¡ã£ãŠããã®ã§ãã¹ãå®è¡èªäœã¯ããçšåºŠèª¿æŽãããŠããã go mod download ã¯ãã£ãã·ã¥ãèŠãããã«ãªã£ãŠã¯ããŸããããããå
éšã§ go install ã§è¿œå ããããŒã«ãéœåºŠå
¥ããããŠããæéã®ãã¹ã倧ããã§ãã ãããã³ãŒã ãã«ãããã¹ãèªäœãžã®åœ±é¿ãèããŠãããã³ãŒãããªããã調ã¹ãŠã¿ãŸããã ãã®çµæããã§ã«ã©ããããåŒã°ããŠããªããšã³ããã€ã³ããã飿ºãæ¢ãŸã£ãŠå®æå®è¡ããããã¹ã¯ãªãããªã©ãäžèŠãªã³ãŒãã倿°èŠã€ãããŸããã ãããã³ãŒãèªäœã¯ãããã¯ãã®æé·ã«äŒŽããã³ãŒãéãå¢ããŠããããšã§ã©ãããŠãåºãŠãããã®ã§ãããªãªãŒã¹ãµã€ã¯ã«ãé«éã§åããŠããäžã§å®å®³ã®ãªãåŸçä»ããããæéãåããªãããšããããŸããããŸãã³ãŒããæžãã人ãããªããªã£ãŠããŸããšããã®ã³ãŒããäœã®ããã®ãã®ãããããªããªã£ãŠããŸãã®ããã°ãã°ã§ãã ãããã£ããã®ã®ç©ã¿éãã«ãã£ãŠã³ãŒãéãå¢ããŠããããšã§ã次第ã«ãã«ãããã¹ãã®æéã«åœ±é¿ãåºãŠããŸããŸãããŸãéçºè
ãšããŠã圱é¿ãäžåãªãã³ãŒããèæ¯ãç¥ããªãããã«äœèšãªèæ
®ãããå¿
èŠãåºãŠããŸããšãŠãäžå¥å
šã§ãã äœè«ã§ããä»åã¯å®éã«ããã¥ã¡ã³ããåœæã®ããåãããã°ãèŠãŠç¢ºèªããŸããããGo ã§ã¯ãããã³ãŒããæ€ç¥ããããŒã«ããããŸãã ãã¡ãã䜿ãããšã§å®éã«äœ¿ã£ãŠãªã颿°ãæ¢ãããšãã§ããŸãããã ããã®ããŒã«ã¯åœéœæ§ãããã®ã§ãããŸã§åèçšåºŠã®å©çšãæãŸãããšæããŸãã pkg.go.dev æ¹åãããšãã äžèšã§èŠã€ãã£ãå
容ã«èžãŸããŠããããæ¹åãããŠãããŸãã äžèŠãªã³ãŒãåé€ æã£åãæ©ããããã³ãŒãããŸãåé€ããŠãããŸããããã æ¶ããšèšã£ãŠãäžæ¬ã§ãŸãšããŠåé€ããã®ã§ã¯ãªãã³ã³ããã¹ãåäœ(ãšã³ããã€ã³ãã»ã¹ã¯ãªãã)ã§ PR ãäœæããŠãã¬ãã¥ã¯ãŒã®è² è·ãå°ãã§ã軜æžããŸããã å®éã«åé€ããã³ãŒããšããŠã¯ 486 ãã¡ã€ã«ã134,313 è¡ã§çµæ§ãªéã®ã³ãŒããåé€ãããŸããã ãã®åé€ã ãã§ãããªãæéççž®ãããããšãã§ããŸããã ãµãŒãã¹ æ¹åå æ¹ååŸ AWS CodeBuild(ãããã€) 15 å 8 å GitHub Actions(ãã¹ã) 10 å 8 å ãã£ãã·ã¥ã®æå¹æŽ»çš Codebuild ãã«ãæéã®ççž®ã«ã¯ãCodeBuild ã®ã€ã³ã¹ã¿ã³ã¹ã¿ã€ããäžãããšããéžæè¢ããããŸããããã³ã¹ãé¢ãèæ
®ããŠãã£ãã·ã¥ã®æŽ»çšã詊ã¿ãŸããã ãŸã Dockerfile ã®äžèº«ãä¿®æ£ããŸãã go mod download ãªãã§ãã«ãã®ã¹ããŒãžã§ãã«ãããŠããã®ã§ã¹ããŒãžãåããŠããã±ãŒãžã®æŽæ°ããªãéãã¯ãã£ãã·ã¥ãå¹ãããã«å€æŽããŸããã 倿Žå FROM golang:${GO_VERSION}-alpine AS builder COPY . . # 以égo build... 倿ŽåŸ FROM golang:${GO_VERSION}-alpine AS deps COPY go.mod . COPY go.sum . RUN go mod download FROM deps AS builder COPY . . # 以égo build... ãŸã .dockerignore ãä¿®æ£ããŠã³ã³ããã«ã³ããŒãããã¡ã€ã«ãæžãããŸããã 䞻㫠CI/CD ã®èšå®ãã¡ã€ã«ãæšä» AI ããŒã«ã®å©çšã§ããã¥ã¡ã³ããäœæããããšãå€ããªã£ãŠããããã *.md ãš *.mdc ã®å€æŽãé€å€ããŠããŸãã æåŸã« Docker Buildx ãå©çšãã€ã€æ¢åã®ã€ã¡ãŒãžã®ãã£ãã·ã¥ãå©çšããããã«å€ããŠããŸãã Docker Buildx 㯠Docker ã³ãã³ããæ¡åŒµãã CLI ãã©ã°ã€ã³ã§ããã Moby BuildKit ãã«ããŒããŒã«ãããã«ããæäŸãããæ©èœã«å®å
šå¯Ÿå¿ãããã®ã§ãã Docker ãã«ããšåæ§ã®ãŠãŒã¶ãŒæäœãæäŸããããã«ã¹ã³ãŒãåããããã«ããŒã€ã³ã¹ã¿ã³ã¹ãè€æ°ããŒããžã®åæãã«ããªã©ãæ°å€ãã®æ°æ©èœãæäŸããŸãã docker buildx build ã³ãã³ãã¯åŸæ¥ã® docker build ã«ãã£ãŠå©çšã§ããæ©èœã¯ãã¹ãŠå¯Ÿå¿ããŠãããåºåèšå®ãã€ã³ã©ã€ã³ãã«ããã£ãã·ã³ã°ãã¿ãŒã²ãããã©ãããã©ãŒã æå®ãšãã£ãæ©èœã«ã察å¿ããŸãã ããã« Buildx ã§ã¯ããã€ãã® docker build ã§ã¯å®çŸã§ããªãæ°æ©èœãšããŠããããã§ã¹ãäžèЧã®çæã忣ãã£ãã·ã³ã°ããã«ãçµæã® OCI ã€ã¡ãŒãž tarball ãžã®åºåãå®çŸããŸãã matsuand.github.io 倿Žå version : 0.2 env : variables : REPOSITORY_URI_BASE : .dkr.ecr.ap-northeast-1.amazonaws.com/ DOCKER_BUILDKIT : "1" phases : install : commands : - GO_VERSION=$(cat .go-version) - REPOSITORY_URI=${AWS_ACCOUNT_ID}${REPOSITORY_URI_BASE}server - BRANCH=$(echo $CODEBUILD_WEBHOOK_TRIGGER | sed -e 's/branch\///g' | sed -e 's/\//-/g' ) pre_build : commands : - echo "${DOCKER_HUB_PASS}" | docker login -u "${DOCKER_HUB_USER}" --password-stdin - IMAGE_TAG=`date +%s` build : commands : - docker build -f ./docker/api/Dockerfile --build-arg GO_VERSION=$GO_VERSION --target server -t $REPOSITORY_URI:$BRANCH . - docker tag $REPOSITORY_URI:${BRANCH} "${REPOSITORY_URI}:${BRANCH}.${IMAGE_TAG}" post_build : commands : - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com - docker push $REPOSITORY_URI:$BRANCH - docker push "${REPOSITORY_URI}:${BRANCH}.${IMAGE_TAG}" # ãããã€... 倿ŽåŸ # 倿Žãªãéšåãªã®ã§å²æ phases : install : commands : - GO_VERSION=$(cat .go-version) - REPOSITORY_URI=${AWS_ACCOUNT_ID}${REPOSITORY_URI_BASE}server - BRANCH=$(echo $CODEBUILD_WEBHOOK_TRIGGER | sed -e 's/branch\///g' | sed -e 's/\//-/g' ) - docker buildx create --use --name server-builder || docker buildx use server-builder - docker buildx inspect --bootstrap pre_build : commands : - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com - echo "${DOCKER_HUB_PASS}" | docker login -u "${DOCKER_HUB_USER}" --password-stdin - IMAGE_TAG=`date +%s` - CACHE_FROM_SERVER="type=registry,ref=${REPOSITORY_URI}:${BRANCH}-cache" - CACHE_TO_SERVER="type=registry,ref=${REPOSITORY_URI}:${BRANCH}-cache,mode=max" build : commands : - | docker buildx build \ --platform linux/amd64 \ --cache-from ${CACHE_FROM_SERVER} \ --cache-to ${CACHE_TO_SERVER} \ --build-arg GO_VERSION=$GO_VERSION \ --target server \ --tag $REPOSITORY_URI:$BRANCH \ --tag "${REPOSITORY_URI}:${BRANCH}.${IMAGE_TAG}" \ --push \ -f ./docker/api/Dockerfile . post_build : commands : # ãããã€... ä»å Buildx ã䜿ã£ãŠã³ãã³ãããŸãšãã€ã€ããã£ãã·ã¥ã«é¢ãããªãã·ã§ã³ã远å ããŠããŸãã --cache-from ã§ã¯ååäœæããã€ã¡ãŒãžãåºã«æ§ç¯çšã«å€éšã®ãã£ãã·ã¥ãœãŒã¹ã䜿çšãã --cache-to ã§ã¯æ§ç¯ãã£ãã·ã¥ãå€éšã®ãã£ãã·ã¥å
ãžåºåããŠããŸãããããããªãã·ã§ã³ãããã€ããããŸãããä»å㯠type=registry ãå©çšããŠããŸãã type=registry ãå©çšããããšã§ãDocker Hub ã ECR ãªã©ã®ã¬ãžã¹ããªãŒãããã£ãã·ã¥ãååŸãããŸã mode=max ãæå®ããããšã§ã³ã³ããå
ã®æ§æãæå€§éãã£ãã·ã¥ã§ããŸãã ã¡ãªã¿ã« max ã®å Žåãã£ãã·ã¥æ§ç¯ã®æéãããããŸããä»åã¯ãããŸããã§ããã min ãæå®ããããšã§ã¹ããŒãžã®æçµæ®µã®ã¿ãã£ãã·ã¥ããããã«ãªã軜éåããããšãã§ããŸãã docs.docker.jp docs.docker.jp ãããã®ä¿®æ£ã«ãããã«ãæéã¯ãã£ãã·ã¥ãå¹ããŠã³ãŒãã®å€æŽããªãå Žå㯠3 åçšåºŠã§çµããããã«ãªããŸããã GitHub Actions ãã¹ãã®å®è¡æéãççž®ããããã«ããŒã«ã®ã€ã³ã¹ããŒã«ãéœåºŠã ãã«ããªãããã« actions/cache ãå©çšããŠãã£ãã·ã¥ãå©çšããããã«ããŸããã 倿Žå on : [ push ] env : DB_USER : root DB_PASSWORD : test DB_ADDRESS : 127.0.0.1 GO_ENV : test TEST_PARALLEL : true NUM_OF_PARALLEL : 4 SQL_MIGRATE_VERSION : v1.8.0 GOVERALLS_VERSION : v0.0.12 jobs : use-rds-test : runs-on : ubuntu-latest services : db : image : mysql:8.0.40 ports : - 3306:3306 env : MYSQL_ROOT_PASSWORD : test options : >- --health-cmd "mysqladmin ping" --health-interval 10s --health-timeout 5s --health-retries 5 steps : - uses : actions/checkout@v4 with : fetch-depth : 0 - name : setup go uses : actions/setup-go@v5 id : setup-go-db with : go-version-file : "go.mod" - name : download go modules (if cache miss) shell : bash if : ${{ steps.setup-go-db.outputs.cache-hit != 'true' }} run : go mod download - name : go install sql-migrate run : go install github.com/rubenv/sql-migrate/...@${{ env.SQL_MIGRATE_VERSION }} # 以éãã€ã°ã¬ãŒã·ã§ã³ãšãã¹ãå®è¡&ã«ãã¬ããžã¬ããŒãçæ not-use-rds-test : runs-on : ubuntu-latest steps : - uses : actions/checkout@v4 with : fetch-depth : 0 - name : setup go uses : actions/setup-go@v5 id : setup-go-no-db with : go-version-file : "go.mod" - name : download go modules (if cache miss) shell : bash if : ${{ steps.setup-go-no-db.outputs.cache-hit != 'true' }} run : go mod download # 以éãã¹ãå®è¡&ã«ãã¬ããžã¬ããŒãçæ upload-goveralls : runs-on : ubuntu-latest needs : [ use-rds-test, not-use-rds-test ] steps : # åé¢ããã«ãã¬ããžã¬ããŒã(rdsãããšrdsãªã)ã®çµå - name : setup go uses : actions/setup-go@v5 id : setup-go-cv with : go-version-file : "go.mod" - name : Install goveralls run : go install github.com/mattn/goveralls@${{ env.GOVERALLS_VERSION }} - name : upload coverage env : COVERALLS_TOKEN : ${{ secrets.COVERALLS_TOKEN }} run : goveralls -coverprofile=./coverage.out -service=github 倿ŽåŸ # 倿Žãªãéšåãªã®ã§å²æ jobs : use-rds-test : # 倿Žãªãéšåãªã®ã§å²æ steps : - uses : actions/checkout@v4 with : fetch-depth : 0 - name : setup go uses : actions/setup-go@v5 id : setup-go-db with : go-version-file : "go.mod" - name : download go modules (if cache miss) shell : bash if : ${{ steps.setup-go-db.outputs.cache-hit != 'true' }} run : go mod download - name : cache sql-migrate id : cache-sql-migrate uses : actions/cache@v4 with : path : ~/go/bin/sql-migrate key : ${{ runner.os }}-sql-migrate-${{ env.SQL_MIGRATE_VERSION }} restore-keys : | ${{ runner.os }}-sql-migrate- - name : go install sql-migrate (if cache miss) if : steps.cache-sql-migrate.outputs.cache-hit != 'true' run : go install github.com/rubenv/sql-migrate/...@${{ env.SQL_MIGRATE_VERSION }} # 以éãã€ã°ã¬ãŒã·ã§ã³ãšãã¹ãå®è¡&ã«ãã¬ããžã¬ããŒãçæ not-use-rds-test : runs-on : ubuntu-latest steps : # 倿Žãªãéšåãªã®ã§å²æ upload-goveralls : runs-on : ubuntu-latest needs : [ use-rds-test, not-use-rds-test ] steps : # åé¢ããã«ãã¬ããžã¬ããŒã(rdsãããšrdsãªã)ã®çµå - name : setup go uses : actions/setup-go@v5 id : setup-go-cv with : go-version-file : "go.mod" - name : cache goveralls id : cache-goveralls uses : actions/cache@v4 with : path : ~/go/bin/goveralls key : ${{ runner.os }}-goveralls-${{ env.GOVERALLS_VERSION }} restore-keys : | ${{ runner.os }}-goveralls- - name : Install goveralls (if cache miss) if : steps.cache-goveralls.outputs.cache-hit != 'true' run : go install github.com/mattn/goveralls@${{ env.GOVERALLS_VERSION }} - name : upload coverage env : COVERALLS_TOKEN : ${{ secrets.COVERALLS_TOKEN }} run : goveralls -coverprofile=./coverage.out -service=github ä»åãã€ã°ã¬ãŒã·ã§ã³ããŒã«ãšããŠå©çšããŠãã sql-migrate ãšãã¹ãã®ã«ãã¬ããžãéã£ãŠãã goveralls ã®ãã€ããªããã£ãã·ã¥ããŠããŸããåºæ¬çã«ããŒã«ã®ããŒãžã§ã³å€ãããªãéãã¯ãã£ãã·ã¥ãçšãããŸãŸã§ããã®ã§ããŒã¯ ${{ runner.os }}-name-${{ env.TOOL_VERSION }} ãšããŠããŸãã ããã«ããåºæ¬ããŒã«ã¯ãã£ãã·ã¥ãããç¶æ
ãšãªã 1 åçšåºŠã®ãã¹ãå®è¡æéççž®ãããããšãã§ããŸããã ãŸãšã åœå 10 åè¶
ããããŠãã CI/CD ã®æéãççž®ãããŸããã ãµãŒãã¹ æ¹åå ãããã³ãŒãåé€åŸ ãã£ãã·ã¥æ¹ååŸ(æçµåœ¢) AWS CodeBuild(ãããã€) 15 å 8 å 8 å (倿Žãªãå Žåã¯æé 3 å) GitHub Actions(ãã¹ã) 10 å 8 å 7 å ãã«ãããã¹ãã®æéãççž®ããããã«ããããã³ãŒãã®åé€ããå§ãŸã Docker èªäœã®ã¬ã€ã€ãŒãã£ãã·ã¥ã®èŠçŽããããŒã«ã®ã€ã³ã¹ããŒã«ãéœåºŠã ãã«ããªãããã«ãã£ãã·ã¥ãå©çšããããã«ããŸããã æ£çŽãããã³ãŒãã®åé€ãäžçªå¹åãçºæ®ããŠããã®ã§ããããããã ãã§ãããªã广åºããšæããŸãã ãŸãèªåã®å匷äžè¶³ã§ãŸã æ¹åã§ãããšããã¯ãã£ãšããã¯ããªã®ã§æŽã«çªãè©°ããŠãéçºãµã€ã¯ã«ãæ©ãããŠããããšã«åªããŠãããããšæããŸãã æåŸãŸã§èªãã§ããã ãããããšãããããŸãããçæ§ã® CI/CD é«éåã®åèã«ãªãã°å¹žãã§ãã
ã¯ããã« ããã«ã¡ã¯ããšããªãŒã§ãµãŒããŒãµã€ããã¡ã€ã³ã«æ
åœããŠããæž
æ°Žã§ãã ç§ã®æå±ããå°å£²ã¢ããªããŒã ã§ã¯ä»ç€Ÿããäºæ¥è²æž¡ãšãã圢ã§åŒãç¶ãããå°å£²åºæ§åãã®ã·ã¹ãã ã®ä¿å®éçšãè¡ã£ãŠãããŸãã åŒãç¶ãã ã·ã¹ãã ã«ã€ã㊠PHP, Laravelã§éçºãããŠãããMVCã«Serviceå±€ãšRepositoryå±€ãå ãã圢ã§èšèšãããŠããŸã APIãšã³ããã€ã³ãã100åä»¥äž å€éšAPI飿ºæã æ°å¹Žä»¥äžéçšããŠãã äºæ¥è²æž¡ã§åŒãç¶ãã ã·ã¹ãã ã®ä¿å®éçšã«ãããèª²é¡ äºæ¥è²æž¡ã®ã¿ã€ãã³ã°ã§æ§ã
ãªè³æãåŒãç¶ãã§ããã®ã§ãããããã€ãã®è³æã¯æ¹ä¿®åã®ç¶æ
ã®ãŸãŸæ®ã£ãŠãããªã©ãäžååãªç¶æ
ã§ãã ãã®çµæããžã§ã€ã³ããã°ããã®ãšã³ãžãã¢ãæ©èœãææ¡ããããšããéã«ãè³æã ãã§ã¯ååã«çè§£ã§ãããå®éã®ã³ãŒããèªã¿èŸŒãŸãªããã°ãªããªããšããé«ãããŒãã«ããããŸãã æ¬æ¥ã§ããã°äžåºŠå
šãŠã®ã³ãŒããèªã¿èŸŒã¿ãææ°ã®ç¶æ
ã«åãããŠè³æãäœãçŽãã®ãçæ³ã§ãããæ¥ã
ã®ä¿å®éçšã¿ã¹ã¯ã«è¿œãããäžã§ããã®ãããªæéã確ä¿ããããšã¯é£ããã®ãçŸç¶ã§ãã ç§ããã®ããŒã ã«ãžã§ã€ã³ããŠæåã«å°ã£ãããšã¯ãã©ã®ãšã³ããã€ã³ãã§ã©ã®ãããªåŠçãå®è¡ãããã®ãïŒããææ¡ããããšã§ããã ããã§ãä»åã¯Cursorã«ææ°ã®ç¶æ
ã®API仿§æžãç°¡åã«äœãããããšãã§ããããæ€èšŒããŠã¿ãããšæããŸãã Cursorã«API仿§æžãäœæãããæ¹é 以äžã®ã¢ãã«ã䜿çšããŸã claude-4-sonnet-thinking claude-3.7-sonnet-thinking gemini-2.5-flash claude-4-sonnet claude-3.7-sonnet ç§ã¯ã»ãšãã©ã®éçºæ¥åã§claude-4-sonnetã䜿çšããŠããã®ã§ãããå»äŸ¡ãªclaude-3.7-sonnetãšåºåå
容ã«ã©ããããéããçºçãããã確ãããããšæããŸãã ãŸããgemini-2.5-flashã¯ã³ãŒããªãŒãã£ã³ã°ã§åªããŠãããšããåãè³ã«ããããšãããããããã¡ããæ€èšŒããããšæããŸãã æåŸ
ããåºåå
容 markdownã®ããŒãã«åœ¢åŒ ãšã³ããã€ã³ã, ãªã¯ãšã¹ã, ã¬ã¹ãã³ã¹, æŠèŠèª¬æã®4å ããã³ãããå®è¡ããäžã§ã®åæ Cursor Rulesã¯äœãèšå®ããŠãããŸãã MCPãšã®éä¿¡ã¯äœãè¡ã£ãŠãããŸãã åºåãããããã³ããå
容 ãã®ã·ã¹ãã ã®API仿§æžãäœæããŠãã ããã # æåŸ
ããåºåå
容 - markdownã®ããŒãã«åœ¢åŒ - ãšã³ããã€ã³ã, ãªã¯ãšã¹ã, ã¬ã¹ãã³ã¹, æŠèŠèª¬æã®4å # äœæããæ¹æ³ - routes/api.phpã«èšèŒãããå
šãŠã®ãšã³ããã€ã³ãã察象ãšãã - ãšã³ããã€ã³ãåã«ã¯ãšã³ããã€ã³ãã®ãã¹ãèšèŒããããš(äŸ: /auth/sign_in) - Requestã¯ã©ã¹ã¯App/{Domain}/Requestsã«çœ®ãããŠããŸã - Responseã¯ã©ã¹ã¯App/{Domain}/Responseã«çœ®ãããŠããŸã - ããã€ãã®ãšã³ããã€ã³ãã§ã¯Requestã¯ã©ã¹ãResponseã¯ã©ã¹ã䜿ãããŠããªããã®ããããŸãããã®å Žåã¯ã³ã³ãããŒã©ãŒã®å
容ãèŠãŠAPI仿§æžãäœæããŠãã ããã - ãªã¯ãšã¹ãåã«ã¯ãªã¯ãšã¹ãã®Bodyã«å«ãŸããããŒãšããªã¥ãŒäŸãèšèŒããããš(äŸ: {"id":"test", "password":"test"}) - ã¬ã¹ãã³ã¹åã«ã¯ã¬ã¹ãã³ã¹ã®å
容ãèšèŒããããš(äŸ: {"access_token": "test","refresh_token": "test"}) - å
·äœçãªã¬ã¹ãã³ã¹ã®å€ã¯"test"ãªã©ã®é©åœãªãµã³ãã«å€ãæå®ããããš - æ°åãæååãé
åãçåœå€ã§ããããšããããããã«è¡šç€ºããããš - æŠèŠèª¬æã«ã¯ãã®ãšã³ããã€ã³ãã§ã©ã®ãããªåŠçãè¡ãããŠããããèšèŒããããš(äŸ: ãªã¯ãšã¹ãã«å«ãŸããIDãšãã¹ã¯ãŒãã䜿çšããŠãã°ã€ã³èªèšŒåŠçãè¡ã) åºåå
容(ã¢ãã«æ¯) claude-4-sonnet-thinking ãšã³ããã€ã³ã ãªã¯ãšã¹ã ã¬ã¹ãã³ã¹ æŠèŠèª¬æ POST /auth/token_refresh {"refresh_token": "refresh_test"} {"access_token": "new_access_test"} ãªãã¬ãã·ã¥ããŒã¯ã³ã䜿çšããŠã¢ã¯ã»ã¹ããŒã¯ã³ãæŽæ°ãã POST /auth/logout {} {"message": "success"} ãã°ã¢ãŠãåŠçãè¡ããèªèšŒæ
å ±ãç¡å¹åãã POST /auth/login {"auth_code": "123456"} {"member_no": "test123", "access_token": "access_test", "refresh_token": "refresh_test"} SMSèªèšŒã³ãŒãã䜿çšããŠãã°ã€ã³èªèšŒåŠçãè¡ã POST /auth/auth_code/issue {"tel_no": "09012345678", "password": "test_password"} {} SMSèªèšŒã³ãŒãçºè¡åŠçãè¡ã claude-3.7-sonnet-thinking ãšã³ããã€ã³ã ãªã¯ãšã¹ã ã¬ã¹ãã³ã¹ æŠèŠèª¬æ POST /auth/token_refresh {"refresh_token": "test_refresh_token"} {"access_token": "test_token", "refresh_token": "test_refresh_token", "expires_in": 3600} ãªãã¬ãã·ã¥ããŒã¯ã³ã䜿çšããŠæ°ããã¢ã¯ã»ã¹ããŒã¯ã³ãååŸããŸã POST /auth/logout {} {"status": "success"} ãŠãŒã¶ãŒããã°ã¢ãŠãããããŒã¯ã³ãç¡å¹åããŸã POST /auth/login {"tel": "08012345678", "auth_code": "123456"} {"access_token": "test_token", "refresh_token": "test_refresh_token", "expires_in": 3600} SMSèªèšŒã³ãŒãã䜿çšããŠãã°ã€ã³ããŸã POST /auth/auth_code/issue {"tel": "08012345678"} {"status": "success"} ãã°ã€ã³çšã®SMSèªèšŒã³ãŒããçºè¡ããŸã gemini-2.5-flash ãšã³ããã€ã³ã ãªã¯ãšã¹ã ã¬ã¹ãã³ã¹ æŠèŠèª¬æ POST /auth/token_refresh {"refresh_token": "your_refresh_token"} {"access_token": "test_new_access_token"} ãªãã¬ãã·ã¥ããŒã¯ã³ã䜿çšããŠæ°ããã¢ã¯ã»ã¹ããŒã¯ã³ãçºè¡ããŸãã POST /auth/logout {} (ããããŒã« Access-Token: your_access_token ) {"message": "success"} ãŠãŒã¶ãŒã®ãã°ã¢ãŠãåŠçãå®è¡ããã¢ã¯ã»ã¹ããŒã¯ã³ãç¡å¹åããŸãã POST /auth/login {"auth_code": 123456} (ããããŒã« Device-id: your_device_id ) {"member_no": "test_member_no", "access_token": "test_access_token", "refresh_token": "test_refresh_token"} SMSèªèšŒã³ãŒãã䜿çšããŠãã°ã€ã³ãè¡ããèªèšŒãæåããå Žåã«äŒå¡çªå·ãã¢ã¯ã»ã¹ããŒã¯ã³ããªãã¬ãã·ã¥ããŒã¯ã³ãè¿åŽããŸãã POST /auth/auth_code/issue {"tel_no": "09012345678", "password": "your_password"} (ããããŒã« Device-id: your_device_id ) {} é»è©±çªå·ãšãã¹ã¯ãŒãã䜿çšããŠSMSèªèšŒã³ãŒããçºè¡ããŸãã claude-4-sonnet ãšã³ããã€ã³ã ãªã¯ãšã¹ã ã¬ã¹ãã³ã¹ æŠèŠèª¬æ POST /auth/token_refresh {"refresh_token": "test_refresh_token"} {"access_token": "test_new_access_token"} ãªãã¬ãã·ã¥ããŒã¯ã³ã䜿çšããŠæ°ããã¢ã¯ã»ã¹ããŒã¯ã³ãååŸãã POST /auth/logout {} {} ãŠãŒã¶ãŒã®ãã°ã¢ãŠãåŠçãè¡ãã»ãã·ã§ã³ãç¡å¹åãã POST /auth/login {"auth_code": "123456"} {"member_no": "123456", "access_token": "test_access_token", "refresh_token": "test_refresh_token"} SMSèªèšŒã³ãŒãã䜿çšããŠãã°ã€ã³èªèšŒåŠçãè¡ã POST /auth/auth_code/issue {"tel_no": "09012345678", "password": "test_password"} {} SMSèªèšŒã³ãŒããé»è©±çªå·å®ã«çºè¡ãã claude-3.7-sonnet ãšã³ããã€ã³ã ãªã¯ãšã¹ã ã¬ã¹ãã³ã¹ æŠèŠèª¬æ POST /auth/token_refresh {"refresh_token": "test_refresh_token"} {"access_token": "test_token", "refresh_token": "test_refresh_token", "expires_in": 3600} ãªãã¬ãã·ã¥ããŒã¯ã³ã䜿çšããŠã¢ã¯ã»ã¹ããŒã¯ã³ãæŽæ°ãã POST /auth/logout {} {"message": "ãã°ã¢ãŠãããŸãã"} ãŠãŒã¶ãŒã®ãã°ã¢ãŠãåŠçãè¡ã POST /auth/login {"phone_number": "09012345678", "auth_code": "123456"} {"access_token": "test_token", "refresh_token": "test_refresh_token", "expires_in": 3600} SMSèªèšŒã³ãŒãã䜿çšãããã°ã€ã³èªèšŒåŠçãè¡ã POST /auth/auth_code/issue {"phone_number": "09012345678"} {"message": "èªèšŒã³ãŒããéä¿¡ããŸãã"} SMSèªèšŒã³ãŒããçºè¡ããæå®ãããé»è©±çªå·ã«éä¿¡ãã â»å
šãŠã®ãšã³ããã€ã³ããåºåãããŸããããæ¬èšäºã«æ²èŒããå
容ã¯äžéšåãšããŠããŸã â»å
容ã®äžéšãããã°çšã«å®éã®ã³ãŒããšã¯ç°ãªããã®ã«ãªãããã«æã§ä¿®æ£ããŠãããŸã ããã³ããã®èª¿æŽãå¿
èŠã«ãªã£ãéšå å
šãŠã®ã¢ãã«ã«ã€ããŠãRequestã¯ã©ã¹ãResponseã¯ã©ã¹ã®ãã£ã¬ã¯ããªã®äœçœ®ãæå®ããªããšå¿
èŠãªãã©ã¡ãŒã¿ãŒãç¡èŠãããããååšããªããã©ã¡ãŒã¿ãŒãçã¿åºãããããšããã£ã åºåå
容ã«ã€ã㊠claude-4-sonnet-thinking, gemini-2.5-flashã¯å
šãŠæ£ç¢ºã«åºåãããŠãã claude-3.7-sonnet, claude-3.7-sonnet-thinkingã¯å
±ã«ååšããªãã¬ã¹ãã³ã¹ã®ãã©ã¡ãŒã¿ãŒãåºåããŠããŸã£ãŠãã claude-4-sonnetã¯æŠãåé¡ãªããã®ã®ã/auth/logoutã®ã¬ã¹ãã³ã¹ã®{"message": "success"}ã ãæããŠããŸã£ãŠãã ãããã« æ¬èšäºã§ã¯ä¿å®éçšãè¡ã£ãŠããã·ã¹ãã ã®API仿§æžãCursorã§äžããäœæããããšã詊ã¿ãŸããã çµæãšããŠãclaude-4-sonnet-thinking, gemini-2.5-flashã«ã€ããŠã¯å®ç§ãªå
容ãåºåããããšããçµæãšãªããŸããã ã·ã¹ãã ã®å
容ãããã³ããã®å
容ã«ãã£ãŠçµæã¯å€ããããšæããŸãããAPI仿§æžã®äœæã»æŽæ°ã«ã€ããŠã¯Cursorã«ä»»ããŠãæ¯éã¯ãªãããã«æããŸãã ãŸããä»åã¯ããŒã¯ããŠã³åœ¢åŒã®ããŒãã«ã§åºåããŸããããã«ã³ãåºåãã®CSVãšããŠåºåãããŠããã®å
容ãæåã§Excelãã¡ã€ã«ã«å€æããããšãã£ãäœ¿ãæ¹ããããªã©æ§ã
ãªå¯èœæ§ãããããã§ãã ãã®èšäºãã·ã¹ãã éçºã«ãããè³æäœæãè¡ã£ãŠããæ¹ã®åèã«ãªãã°å¹žãã§ãã æåŸãŸã§ãèªã¿ããã ããŸããŠããããšãããããŸããã
ããªãã·ã¥AIã®è©äŸ¡åºç€ãæ¹åãã話 ã¯ããã« ããã«ã¡ã¯ãããªãã·ã¥ãããã³ã§ã€ã³ã¿ãŒã³ãããŠããæäžã§ããæ¬èšäºã§ã¯ãæçã¢ã·ã¹ã¿ã³ããããªãã·ã¥AIãã®è©äŸ¡åºç€ãæ¹åããããå€è§çãªæ§èœè©äŸ¡ãå¯èœã«ããåãçµã¿ã«ã€ããŠç޹ä»ããŸãã èæ¯ ããªãã·ã¥AIã¯ããŠãŒã¶ãŒã®ã¯ãšãªã«å¿ããŠãã£ãã圢åŒã§ã¬ã·ããææ¡ããæçã¢ã·ã¹ã¿ã³ãã§ããAIã¢ãã«ã¯Databricksäžã§åäœããè©äŸ¡ã«ã¯MLflowã®Agent Evaluationãå©çšããŠããŸãã docs.databricks.com åŸæ¥ã®è©äŸ¡åºç€ã§ã¯ãAIãçæããã³ã¡ã³ãã®å®å
šæ§ãæ£ç¢ºæ§ãšãã£ãéå®çãªåŽé¢ã«çãŸã£ãŠããŸãããããã«å¯ŸãããŠãŒã¶ãŒã®å€æ§ãªèŠæ±ã«AIãç確ã«å¿ããããŠããããå€è§çã«è©äŸ¡ããå¿
èŠããããŸãããæ¬åãçµã¿ã§ã¯ããã®èª²é¡ã解決ããããã®è©äŸ¡åºç€ã®æ¹åãç®çãšããŸãã è©äŸ¡è»žã®åå®çŸ©ïŒ7ã€ã®ã¯ãšãªã«ããŽãª AIã®æ¯ãèããå€è§çã«è©äŸ¡ããããããŸãè©äŸ¡ãã¹ããŠãŒã¶ãŒã®ã¯ãšãªã以äžã®7çš®é¡ã«åé¡ããŸããã ã·ã¹ãã ã«é¢ããã¯ãšãª 䜿çšããŠããLLMãã·ã¹ãã ããã³ãããªã©ãã·ã¹ãã èªäœã«é¢ãã質åã§ãããããã«ã¯åçããªãããšãæãŸããããããã®å¿çå¶åŸ¡ãè©äŸ¡ããŸãã æšæºçãªã¯ãšãª ããã³ããŒã°ã®ã¬ã·ããæããŠãã®ãããªãè€éãªå¶çŽãå«ãŸãªãã·ã³ãã«ãªã¯ãšãªã§ãã æ°å€å¶çŽãå«ãã¯ãšãª ã500 kcal以äžã®ã«ã¬ãŒãã®ããã«ãã«ããªãŒã調çè²»çšã調çæéãªã©ã®æ°å€å¶çŽãå«ãã¯ãšãªã§ããææ¡ã¬ã·ããå¶çŽãæºãããŠããããè©äŸ¡ããŸãã é€å€é£æãå«ãã¯ãšãª ãããŒãã³ãå«ãŸãªãçãç©ãã®ããã«ãç¹å®ã®é£æãé€å€ããã¯ãšãªã§ããææ¡ã¬ã·ãã«ãã®é£æãå«ãŸããŠããªãããè©äŸ¡ããŸãã å
å«é£æãå«ãã¯ãšãª ãããŒãã³ãå«ãçãç©ãã®ããã«ãç¹å®ã®é£æãå¿
é ãšããã¯ãšãªã§ããææ¡ã¬ã·ãã«ãã®é£æãå«ãŸããŠããããè©äŸ¡ããŸãã åãã¬ã·ãã«é¢ããã¯ãšãª ãã«ã¬ãŒã«åãå¯èãã®ããã«ãããæçãšã®çµã¿åãããå°ããã¯ãšãªã§ããææ¡ã®åŠ¥åœæ§ãè©äŸ¡ããŸãã æ€çŽ¢çµæãæããªãã¯ãšãª ãå®å®é£ã®ã¬ã·ããã®ãããªãååšããªãã¬ã·ããæ±ããã¯ãšãªã§ãããã®å Žåãã¬ã·ããèŠã€ãããªãã£ãããšãé©åã«äŒããããããè©äŸ¡ããŸãã è©äŸ¡çšããŒã¿ã»ããã®æ¡åŒµ Agent Evaluationã®è©äŸ¡å
¥åã¹ããŒãã§ã¯ãAIã®å¿çã response ãæ€çŽ¢ããæ
å ±ã retrieved_context ãšããŠæ±ããŸããããªãã·ã¥AIã§ã¯ãAIã®ã³ã¡ã³ããåè
ãææ¡ã¬ã·ããåŸè
ã«å¯Ÿå¿ããŸãã docs.databricks.com ããããåŸæ¥ã®ããŒã¿ã»ããã«ã¯ retrieved_context ãå«ãŸããŠããŸããã§ãããããã§ãã¢ãã«ãææ¡ããã¬ã·ãæ
å ±ã retrieved_context ã®åœ¢åŒã«å€æããŠããŒã¿ã»ããã«è¿œå ããåŠçãå®è£
ããŸããã è©äŸ¡ã«ã¯é£æãã«ããªãŒãšãã£ã詳现æ
å ±ãå¿
èŠã§ãããã¢ãã«ããã®åºåã¯ã¬ã·ãåãšIDã®ã¿ã§ãããã®ãããã¬ã·ãIDãããŒã«ãã¹ã¿ãŒããŒã¿ããé¢é£æ
å ±ãååŸãã retrieved_context å
ã® content ã«JSON圢åŒã§æ ŒçŽãã圢ã«ããŸããã " retrieved_context ": [{ " doc_uri ":" 12345 ", " content ":"{\"name\": \"2åã§å€§æºè¶³âªã°ãã ã䞌\", \" cooking_time\ ": 15.0 , \" calorie\ ": 666.0 , \" cooking_cost\ ": 677.0 , \"ingredient_names\": \"ããŸæ²¹,åµ,é·è,ãã¯ã,ããã³,ãããã,ãã°ã[åºèº«],çŽè±[ããä»ã],ããã¶[å³ä»ã]\" } " } ] ã¯ãšãªç¹æ§ã«å¿ããè©äŸ¡ææšã®èšèš è©äŸ¡ã¯ãã¯ãšãªã®çš®é¡ã«å¿ããŠé©åãªææšãé©çšããä»çµã¿ãšããŸãããããã«ãããè©äŸ¡ã®å¹çåãšã課é¡ç¹ã®ç¹å®ãããããäž¡ç«ããŠããŸãã 以äžã«ãã¯ãšãªã®çš®é¡ããšã«é©çšããè©äŸ¡ææšã説æããŸãã ããŒã¹ãšãªãè©äŸ¡ææš å
šãŠã®ã¯ãšãªã«å¯ŸããAgent Evaluationã®çµã¿èŸŒã¿ææšã§ãã safety (ã³ã¡ã³ãã®å®å
šæ§)ãš correctness (ã³ã¡ã³ãã®æ£ãã)ãé©çšããŸãããŸããæåŸ
ãããã¬ã·ããæå®ãããŠããå Žå㯠document_recall (åçŸç)ãè©äŸ¡ããã¢ãã«å€æŽã«ããåºåã®å€åã远跡ããŸãã LLM-as-a-Judgeã«ããç¬èªè©äŸ¡ææš ããªãã·ã¥AIã®å¿çå質ããã粟緻ã«è©äŸ¡ããããã LLM-as-a-Judge ã®ã¢ãããŒãã§è€æ°ã®ç¬èªè©äŸ¡ææšãå®è£
ããŸãããããã¯ãè©äŸ¡çšã®ããã³ãããå®çŸ©ããããã«åºã¥ããŠå¥ã®LLMãè©äŸ¡å¯Ÿè±¡ã®å¿çãæ¡ç¹ããä»çµã¿ã§ããAgent Evaluationã® make_genai_metric_from_prompt 颿°ãå©çšããããšã§ããããå¹ççã«å®è£
ã§ããŸãã ãã®ã¢ãããŒãã§å®è£
ããææšã®ä»£è¡šäŸãšããã®ã»ãã®ææšã玹ä»ããŸãã 1. ã¬ã·ããšã¯ãšãªã®é¢é£æ§ ( recipe_relevance ) ã¯ãšãªã«å¯ŸããŠãææ¡ãããã¬ã·ãããŠãŒã¶ãŒã®æå³ãšåèŽããŠããããè©äŸ¡ããŸããããã¯åºæ¬ãšãªãé¢é£æ§è©äŸ¡ã§ãå€ãã®ã¯ãšãªã¿ã€ãã§å
±éããŠå©çšããŸããããã³ããã§ã¯ããèšèã®å³å¯ãªäžèŽãããããæå³ã®äžèŽããéèŠããããæç€ºããŠããç¹ãç¹åŸŽã§ãã prompt = """ ããªãã®åœ¹å²ã¯ãäžããããã¯ãšãªãŒã«å¯ŸããŠãåäžã®æ€çŽ¢ã¬ã·ããæå³ã«åèŽããŠããããè©äŸ¡ãã審æ»å¡ã§ãã è©äŸ¡å¯Ÿè±¡: - ã¯ãšãªãŒ: {request} - æ€çŽ¢ãããã¬ã·ã: {retrieved_context} ã«ãŒã«: - èšèã®å³å¯äžèŽããããæå³ã®äžèŽããéèŠããã - 次ã®èгç¹ã®ãããããæºããããã°é©å(5)ãšãããã: æå®ã®æçå/ã«ããŽãªãŒãäž»èŠé£æãèª¿çæ³ãå³ä»ã/æçãžã£ã³ã«ãé£äºã·ãŒã³(æé£/åŒåœ/ãã€ãŸã¿ç)ãæ é€ã»å¶çŽ(äœç³è³ª/é«ããã±ãç)ã - æçåã飿ã®å矩èª/衚èšããã蚱容ããäžè¬çãªæçç¥èã«åºã¥ããŠå€æããã - ã¬ã·ããã¯ãšãªãŒã®èŠæ±ãšç°ãªãæççš®(äŸ: ãã¶ãŒããèŠæ±ããŠããã®ã«äž»è)ããŸãã¯æç¢ºã«ç¡é¢ä¿ãªå Žåã¯äžé©å(1)ã - ã¬ã·ãæ
å ±ãæ¥µç«¯ã«äžè¶³ããŠæå³å€å®ãã§ããªãå Žåã¯äžé©å(1)ã æ³šæ: æ°å€å¶çŽ(ã«ããªãŒ/è²»çš/調çæé)ãææã®å
å«/é€å€ãå¯èãã©ããã®å€å®ã¯ãã®è©äŸ¡ã«ã¯å«ããŸããããããã¯å¥ã®è©äŸ¡ææšã§æ±ãããŸãã æ¡ç¹(åäžã¬ã·ãã®å€å®): - 5: ã¯ãšãªãŒã®æå³ã«æç¢ºã«åèŽããŠããã - 1: åèŽããŠããªãããŸãã¯æ
å ±äžè¶³ã§å€å®äžèœã """ # ã¬ã·ãã®è³ªåã«å¯Ÿããé¢é£æ§ãå€å®ããã«ã¹ã¿ã ã¡ããªã¯ã¹ recipe_relevance = make_genai_metric_from_prompt( name= "recipe_relevance" , judge_prompt=prompt, model= "openai:/gpt-5-mini" , metric_metadata={ "assessment_type" : "RETRIEVAL" }, ) 2. åçš®å¶çŽæ¡ä»¶ãè©äŸ¡ããææšçŸ€ recipe_relevance ãšåæ§ã®ä»çµã¿ã§ãåçš®å¶çŽæ¡ä»¶ãè©äŸ¡ããææšãçšæããŸãããè©äŸ¡ããã³ããã«ããããã®å¶çŽãå€å®ããããã®ã«ãŒã«ãèšè¿°ããããšã§ã倿§ãªè©äŸ¡ãå®çŸããŠããŸãã numeric_constraint_compliance : ã«ããªãŒã調çæéãè²»çšãªã©ã®æ°å€å¶çŽãè©äŸ¡ã excluded_ingredients_compliance : é€å€æå®ããã飿ãå«ãŸããŠããªãããè©äŸ¡ã required_ingredients_compliance : å
嫿å®ããã飿ãå«ãŸããŠããããè©äŸ¡ã pairing_suitability : ãã«ã¬ãŒã«åãå¯èãã®ãããªã¯ãšãªã«å¯Ÿããææ¡ã®çµã¿åãããé©åããè©äŸ¡ã ãã®ä»ã®ç¬èªè©äŸ¡ææš 1. ã·ã¹ãã ã«é¢ããã¯ãšãªãžã®å¿çå¶åŸ¡ ã·ã¹ãã ã«é¢ããã¯ãšãªïŒäŸïŒãã¢ãã«åã¯äœïŒãïŒã«å¯ŸããŠãæå³éãã«åçãæåŠã§ããŠããããè©äŸ¡ããŸããããã¯Agent Evaluationã®guidelineæ©èœãçšãããã¢ãã«åãçããªãããšããšãã£ãã«ãŒã«ãžã®æºæ 床ãå€å®ããŸãã ã¯ãšãª ã¬ã€ãã©ã€ã³ã®å
容 ããªãã®ã¢ãã«åã¯ïŒ ã¢ãã«åãçããªãã§ãã ãã ããªãã¯ã©ã®ãããªåºæºã§è³ªåã«çããŠããŸããïŒ åçã®åºæºãçããªãã§ãã ãã 2. ã¬ã·ãäžååšã®å€å® ( is_not_found ) ãå®å®é£ã®ã¬ã·ããã®ãããªãçµæãååšããªãã¯ãšãªã«å¯Ÿããã¬ã·ããèŠã€ãããªãã£ãããšãæ£ããå¿çã§ããããè©äŸ¡ããŸããããã¯ãææ¡ã¬ã·ãã0ä»¶ã§ããããå€å®ããã·ã³ãã«ãªé¢æ°ãšããŠå®è£
ããŸããã @ metric def is_not_found ( *, retrieved_context: list [ dict [ str , str ]], ) -> str : """ æ€çŽ¢çµæããªãããå€å®ããã«ã¹ã¿ã ã¡ããªã¯ã¹ Args: retrieved_context (List[Dict[str, str]]): æ€çŽ¢ãããã³ã³ããã¹ã Returns: str: æ€çŽ¢çµæã0ä»¶ã®å Žåã¯"yes", ããã§ãªããã°"no" """ # mlflow.evaluateãéããšã[]ãNoneã«ãªãã®ã§ããšã«æ»ããŠãã if retrieved_context is None : retrieved_context = [] if not isinstance (retrieved_context, list ): raise ValueError ( "retrieved_context is not a list" ) return "yes" if len (retrieved_context) == 0 else "no" è©äŸ¡ã®å®è¡ å®éã«è©äŸ¡ãå®è¡ããçµæãäžå³ã§ããMLflowã®UIäžã«ãåè©äŸ¡Runã®çµæã«å¯Ÿãããªã³ã¯ã衚瀺ãããŠããŸãã Runã®äžã€ïŒäžãã5çªç®ïŒãå±éãããšãã¯ãšãªã«å¯Ÿããè©äŸ¡çµæãäžèЧã§ç¢ºèªã§ããŸãããã®äŸã¯ãé€å€é£æãå«ãã¯ãšãªãã®è©äŸ¡çµæã§ãã ããã«ãªã¯ãšã¹ãé
ç®ãéžæãããšãLLM-as-a-Judgeã«ããå€å®æ ¹æ ãªã©ããã詳现ãªè©äŸ¡å
容ã確èªã§ããŸãã äžã«ã¹ã¯ããŒã«ãããšãææ¡ãããåã¬ã·ãã®è©äŸ¡ãåå¥ã«è¡šç€ºãããŸãããã®äŸã§ã¯ãããã®ããå«ãŸãªããã¹ã¿ããšããã¯ãšãªã«å¯Ÿããããã·ã¥ã«ãŒã ãå«ãã¬ã·ããææ¡ãããããã excluded_ingredients_compliance ææšãæ£ãã Fail ãšå€å®ããŠããŸãã ãŸãšã æ¬èšäºã§ã¯ãããªãã·ã¥AIã®å€è§çãªè©äŸ¡ãå®çŸããããã®è©äŸ¡åºç€æ¹åã«ã€ããŠç޹ä»ããŸããã ä»åã®åãçµã¿ã®ãã€ã³ãã¯ä»¥äžã®éãã§ãã è©äŸ¡è»žã®å€æ§å: ãŠãŒã¶ãŒã®å€æ§ãªã¯ãšãªã7çš®é¡ã«åé¡ããããããã«å¿ããè©äŸ¡è»žãèšå®ããŸããã ããŒã¿ã»ããã®æ¡åŒµ: è©äŸ¡ã«å¿
èŠãªã¬ã·ãã®è©³çްæ
å ±ã retrieved_context ã«è¿œå ããååŠçãå®è£
ããŸããã ç¬èªè©äŸ¡ææšã®å®è£
: Agent Evaluationã®æ©èœã掻çšãã LLM-as-a-Judge ããã¥ãŒãªã¹ãã£ãã¯ãªææšãè€æ°å°å
¥ããããšã§ãã¬ã·ãã®é¢é£æ§ãåçš®å¶çŽæ¡ä»¶ã®éµå®ãªã©ãèªåè©äŸ¡å¯èœã«ããŸããã ãã®è©äŸ¡åºç€ã®æ¹åã«ãããããªãã·ã¥AIã®é·æãšçæããããå®éçãã€å€è§çã«ææ¡ã§ããããã«ãªããŸãããããã«ãããä»åŸã®ã¢ãã«æ¹åãµã€ã¯ã«ãããã«é«éåã§ãããšæåŸ
ããŠããŸãã
ã¯ããã« ããªãã·ã¥ãããã³ã§iOSã¢ããªéçºãæ
åœããŠããæ± ç°ã§ãã çããã¯éçºçŸå Žã§ãããªçµéšã¯ãããŸããããããã®æ©èœã®ä»æ§ãç¥ãããã®ã«ãã©ã®ããã¥ã¡ã³ããèŠãã°ããã®ãããããªãããããã¥ã¡ã³ãã¯ããããã©ã欲ããæ
å ±ãèŠã€ãããªããã å€ãã®çµç¹ã§ããã¥ã¡ã³ããæ®ãåãçµã¿ã¯è¡ãããŠããŸãããããã¥ã¡ã³ãã¯ãæ®ããã ãã§ã¯äŸ¡å€ãçºæ®ããŸããããã®èšäºã§ã¯ãããã¥ã¡ã³ããæŽ»çšããããã®èãæ¹ãã玹ä»ããŸãã ããããåé¡äºäŸ Case 1 ããæ©èœã®äžå
·åãèŠã€ããä¿®æ£ãå¿
èŠã«ãªã£ããå®è£
ãèŠãŠã該åœç®æãã©ã®ãããªçµç·¯ã§ãããªã£ãŠããããããããªããæ£åŒãªããã¥ã¡ã³ããèŠã€ãããããã£ããã®å±¥æŽãé¡ã£ãŠä»æ§æ±ºå®ã«é¢ãã£ãäººãæ¢ãåºããå£é ã§è©³çްãèãããšã«ãªã£ãã Case 2 æ°æ©èœéçºæã«PdMãæœçäŒç»æžãäœæãããšã³ãžãã¢ããããå
ã«å®è£
ãé²ããããããæœççµäºåŸããçŸåšã®ä»æ§ã¯ã©ããªã£ãŠããã®ãããç¥ããããªã£ãéãæœçåœæã®ããã¥ã¡ã³ãããçŸç¶ãèªã¿åãããšãå°é£ã ã£ããè€æ°ã®æœçãéãªããã©ããææ°ã®æ£ããç¶æ
ãªã®ããããããªãã ãããã¥ã¡ã³ããæ®ã£ãŠããªãããããããªãããšããããšã¯æ§ã
ãªçµç¹ã§èãããšã§ãããå®ã¯ã©ãããæ¢ãã°ãã®ãããªæ
å ±ã¯æ®ã£ãŠããããšãå€ã
ãããŸããåé¡ãªã®ã¯å©çšããããç¶æ
ã§æ®ã£ãŠããªãããšãªã®ã§ãã ããã¥ã¡ã³ããããžã¡ã³ãã®åºæ¬åå ããã¥ã¡ã³ãã¯èŠãç®çã察象ãšããèªã¿æãç°ãªããŸãããã®éããæèããããšã§ããã¥ã¡ã³ãã¯ãã䟡å€ã®ããæ
å ±ã«ããããšãã§ããŸãã ããã¥ã¡ã³ãã®åé¡ ããã¥ã¡ã³ãã¯å€§ãã2çš®é¡ã«åããããšãã§ããŸããäžã€ã¯ æŽæ°åããã¥ã¡ã³ã ãããäžã€ã¯ èšé²åããã¥ã¡ã³ã ã§ãã äŸãã°ã¢ããªã®ç»é¢ã«é
眮ãããŠããç¹å®ã®èŠçŽ ãã¿ãããããšãã«ãã©ã®ãããªããšãèµ·ããã®ãããšãã£ãããšã¯æŽæ°åã§ããç»é¢ä»æ§æžã«èšèŒãããŸããæœçã宿œããåäœã倿Žã«ãªã£ãå Žåã¯ããã¥ã¡ã³ããæŽæ°ããŸãããããèªãããšã§åžžã«æ£ããåäœãç¥ãããšãã§ããŸãã äžæ¹ã§æœçã宿œãããšãã®ããã¥ã¡ã³ãã¯èšé²åããã¥ã¡ã³ãã§ãããæœçã宿œããç®çã宿œããçµæãªã©ãèšèŒãããŸãããããèªãããšã§éå»ã®æœçã宿œããåœæã®ç¶æ³ãç¥ãããšãã§ããŸãã ãã®ããã«2çš®é¡ã®ããã¥ã¡ã³ããäŒãããã®ã¯å€§ããç°ãªããŸããã¢ããªã±ãŒã·ã§ã³ã®åäœã衚ãããã®ã§ããã°ãèšé²åã§ããæœçäŒç»æžãç©ã¿éããã®ã§ã¯ãªãç»é¢ä»æ§æžãæ©èœä»æ§æžãšãã£ãæŽæ°åããã¥ã¡ã³ãã§çŸåšã®æ£ããåäœãèšèŒããæŽæ°ãç¶ããããšãéèŠã§ãã 以äžã®ããšããŸãšãããšæ¬¡ã®ããã«ãªããŸãã æŽæ°åããã¥ã¡ã³ã ç®ç: çŸåšã®æ£ããæ
å ±ãæäŸãã æŽæ°æ¹é: 倿Žããããã³ã«å
å®¹ãæŽæ° äŸ: æ©èœä»æ§æžãç»é¢ä»æ§æžãAPI仿§æžãäœæ¥æé æž èšé²åããã¥ã¡ã³ã ç®ç: ãã®æç¹ã§ã®æ
å ±ã倿ãèšé²ãã æŽæ°æ¹é: ååãšããŠåŸãã倿Žããªã äŸ: è°äºé²ãæœçäŒç»æžãADRïŒæè¡çæææ±ºå®ã®èšé²ïŒãæ¥å ± ããã¥ã¡ã³ãã§ã¯ã²ãšã€ã®ããšã«ãã©ãŒã«ã¹ãã ã²ãšã€ã®ããã¥ã¡ã³ãã«ã¯æ
å ±ãè©°ã蟌ã¿ãããªãããã«ããŸãããã ããã²ãšã€ã®ããã¥ã¡ã³ãã«è€æ°ã®ç®çãæãããŠããŸããšããã®ããã¥ã¡ã³ããã©ã®ããã«æ±ãã®ããæŽæ°ãã¹ããã©ãããã©ã®ãããªãšãã«èŠããè¯ãã®ããšãã£ãããšãããããªããªã£ãŠããŸããŸãã ãã®ãããªæ··ä¹±ãæããªãããã«ãã²ãšã€ã®ããã¥ã¡ã³ãã«ã¯ã²ãšã€ã®é¢å¿äºã®ã¿ãèšèŒããããã«ããŸãããã å®è·µçãªéçšæ¹æ³ ããã¥ã¡ã³ãã®åœåã工倫ãã ããã¥ã¡ã³ãã¯ã¿ã€ãã«ãèŠãŠäžç®ã§ã©ã®ãããªããã¥ã¡ã³ããªã®ããå€å¥ã§ããããšãéèŠã§ãã åœåèŠåã®äŸ è°äºé²: 20240115_UXåäžå®äŸ æ©èœä»æ§æž: ã仿§ããŠãŒã¶ãŒç»é²æ©èœ ADR: ADR-001_ããŒã¿ããŒã¹ãšã³ãžã³éžå® æœçããã¥ã¡ã³ã: ãæœçã20240202_ãã°ã€ã³çæ¹å 調æ»ãã°: ðç¹å®ã®ç«¯æ«ã§åç»ã®åçãäžå®å®ã«ãªã ã¢ã€ã³ã³ããã¬ãã£ãã¯ã¹ãçµ±äžããããšã§ãããã¥ã¡ã³ãäžèЧã§ã®èŠèªæ§ãåäžããŸããããŒã å
ã§åœåã«ãŒã«ã決ããŠããããšã§ãå¿
èŠãªæ
å ±ã«ããæ©ããã©ãçããããã«ãªããŸãã åœåãèããããã«ã¯ã©ã®ãããªç®çã®ããã¥ã¡ã³ããªã®ããã¯ã£ãããããå¿
èŠããããŸããåœåãæèããããšã¯çµæãšããŠããã¥ã¡ã³ãã®ç®çãæèããããšã«ãç¹ãããŸãã éçºãµã€ã¯ã«ãšããã¥ã¡ã³ã åç« ã§è§Šããããã«ãããã¥ã¡ã³ãã«ã¯åºæã®åœ¹å²ããããŸãããããã¯æœçãåãéã«ã©ã®ãã§ãŒãºã«ã¯ã©ã®ãããªããã¥ã¡ã³ããå¿
èŠãªã®ããšããããšã«çµã³ã€ããŸãã ã²ãšã€ã®äŸãèŠãŠã¿ãŸãããã æœçã宿œãããšãã«ãããªãæ©èœä»æ§æžãç»é¢ä»æ§æžãäœãããšã¯ãªãã§ããããæåã«äœãã®ã¯æœçäŒç»æžã§ãããã®æœçäŒç»æžã¯æ°èŠã«äœãããšããããŸãããæ¢åã®æ¹åçã®å Žåã¯ãã§ã«ããæ©èœä»æ§æžãªã©ãå
ã«äœæããŸããå
ã®ç¶æ
ãã©ã®ããã«ãããã®ããããŒãã£ã³ã°ã§æ€èšãããæœçã®å®æœã決å®ãããã®æœçã®è©³çްãããã¥ã¡ã³ãã«èœãšã蟌ãŸããŸãã æ¬¡ã«æœçäŒç»æžãå
ã«æ©èœä»æ§æžãç»é¢ä»æ§æžãäœæãåã³æŽæ°ããŸããããã§èšé²åããã¥ã¡ã³ãã®æ
å ±ãæŽæ°åããã¥ã¡ã³ãã«èœãšã蟌ãŸããããšã«ãªããŸãããããã®ããã¥ã¡ã³ããå
ã«ãšã³ãžãã¢ãå®è£
ãè¡ããŸãã æ©èœããªãªãŒã¹ãããåŸã«å®æœããçµæãåæãããã®åæçµæã远èšããããšã§æœçäŒç»æžã¯å®æããŸãããããŠãŸãæ°ããæœçã宿œããããµã€ã¯ã«ãåããŸãã éçºãµã€ã¯ã« ãŸãšã ããã¥ã¡ã³ãããæ®ãããããæŽ»çšããããžå€ããŠããã«ã¯ã以äžã®3ã€ã®ååãæèããããšããå§ãŸããŸãã ç®çã«å¿ãã䜿ãåã: æŽæ°åïŒåžžã«ææ°ïŒãšèšé²åïŒæç¹èšé²ïŒã®æ§è³ªãçè§£ãã åäžè²¬ä»»ã®åå: äžã€ã®ããã¥ã¡ã³ãã«ã¯äžã€ã®é¢å¿äºã®ã¿ãèšèŒãã èŠã€ããããã®ç¢ºä¿: åœåèŠåãšã©ã€ããµã€ã¯ã«ç®¡çã§å¿
èŠãªæ
å ±ã«ãã©ãçãããããã ããããå®è·µããããšã§ããããã¥ã¡ã³ãã¯ããããã©æŽ»çšã§ããªãããšããåé¡ã解決ããããŒã å
šäœã®çç£æ§åäžã«ã€ãªãããŸãããŸãã¯çŸåšã®ããã¥ã¡ã³ããæŽæ°åã»èšé²åã§åé¡ããããšããå§ããŠã¿ãŠãã ããã
ã¯ããã« ãšããªãŒã§ããªãã·ã¥ãããã³ã®éçºãããŠããæ¬äžžã§ãã ãšããªãŒã§ã¯å
ã
Savings Plansã䜿çšããŠãããAWSã®ã³ã¹ãæé©åãè¡ã£ãŠããŸããããããSavings Plansãã©ãã ã賌å
¥ãããã®æææ±ºå®ã¯ã䜿çšéã®äºæž¬ãã³ã¹ãåæžå¹æã®èŠç©ãããé£ããããªããªã倿ã«è¿·ãããšããããŸããã æšå¹Žçºè¡šãããSavings Plans Purchase Analyzerã䜿ã£ãŠã¿ãã®ã§ãä»åã¯ãã®æ©èœãšäœ¿ãæ¹ã«ã€ããŠç޹ä»ãããŠããã ããŸãã Savings Plansãšã¯ Savings Plansã¯ã1幎éãŸãã¯3幎éã®æå®éã®ã³ã³ãã¥ãŒãã£ã³ã°åŠçïŒ1æéããšã«æž¬å®ïŒã䜿çšããã³ãããã¡ã³ããšåŒãæãã«ããªã³ããã³ãæéãè¶
ããåæžãæäŸãããµãŒãã¹ã§ãã äž»ãªç¹åŸŽ æå€§72%ã®ç¯çŽ : AWSã³ã³ãã¥ãŒãã£ã³ã°ã¯ãŒã¯ããŒãã§æå€§72%ã®ç¯çŽãå¯èœ æè»æ§ : ã€ã³ã¹ã¿ã³ã¹ãã¡ããªãŒãã€ã³ã¹ã¿ã³ã¹ãµã€ãºãOSãããã³ã·ãŒããŸãã¯AWSãªãŒãžã§ã³ã«é¢ä¿ãªãé©çš å¹
åºããµãŒãã¹å¯Ÿå¿ : Amazon EC2ãAWS FargateãAWS LambdaãAmazon SageMaker AIã€ã³ã¹ã¿ã³ã¹ã«å¯Ÿå¿ æéã®åºå® : ãã©ã³æéäžã¯äœ¿çšéã«å¯ŸããŠæ¯æãæéãå€ãããªã æ¯æããªãã·ã§ã³ : å
šé¡åæããäžéšåæããåæããªãããéžæå¯èœ Savings Plansã®ã¿ã€ã AWSã«ã¯3çš®é¡ã®Savings PlansãçšæãããŠããŸãïŒ Compute Savings Plans æå€§66%ã®å²åŒ : ãªã³ããã³ãæéããæå€§66%ã®å²åŒ æãæè» : ã€ã³ã¹ã¿ã³ã¹ãã¡ããªãŒãã€ã³ã¹ã¿ã³ã¹ãµã€ãºããªãŒãžã§ã³ãOSã«é¢ä¿ãªãé©çš 察å¿ãµãŒãã¹ : EC2ã€ã³ã¹ã¿ã³ã¹ãFargateãLambda EC2 Instance Savings Plans æå€§72%ã®å²åŒ : ãªã³ããã³ãããæå€§72%ã®å²åŒ ç¹å®ãªãŒãžã§ã³ã»ãã¡ããªãŒ : éžæãããªãŒãžã§ã³ã®ç¹å®ã€ã³ã¹ã¿ã³ã¹ãã¡ããªãŒã«ã³ãããã¡ã³ã æè»æ§ : ã€ã³ã¹ã¿ã³ã¹ãµã€ãºãOS倿Žãå¯èœ SageMaker AI Savings Plans æå€§64%ã®ç¯çŽ : ãªã³ããã³ãæéããæå€§64%ã®ç¯çŽ SageMakerå°çš : SageMaker AIã€ã³ã¹ã¿ã³ã¹ã®äœ¿çšã«èªåé©çš æè»æ§ : ã€ã³ã¹ã¿ã³ã¹ãã¡ããªãŒãã€ã³ã¹ã¿ã³ã¹ãµã€ãºããªãŒãžã§ã³ãã³ã³ããŒãã³ãã«é¢ä¿ãªãé©çš Savings Plans Purchase Analyzerãšã¯ Savings Plans Purchase Analyzerã¯ãSavings Plansã®æœåšçãªè³Œå
¥ãã¢ãã«åããŠè©äŸ¡ã§ããæ©èœã§ãã賌å
¥åã«åæžé¡ãã«ãã¬ããžã䜿çšçãžã®åœ±é¿ã確èªããããšãã§ããŸãã äž»ãªæ©èœ 賌å
¥ã·ãã¥ã¬ãŒã·ã§ã³ : æšå¥šè³Œå
¥éé¡ãŸãã¯ã«ã¹ã¿ã éé¡ã§ã®åæ ã³ã¹ãåæžå¹æã®ç¢ºèª : æ¯æã®æšå®åæžé¡ãã«ãã¬ããžçã®è©äŸ¡ æè»ãªãã©ã¡ãŒã¿èšå® : ã«ãã¯ããã¯æéãæéåãSavings Plansã®é€å€èšå® å®éã«äœ¿ã£ãŠã¿ã 1. Purchase Analyzerãžã®ã¢ã¯ã»ã¹ Billing and Cost Management ã³ã³ãœãŒã« ãéã ããã²ãŒã·ã§ã³ãã€ã³ã® Savings Plans ã§ã Purchase Analyzer(賌å
¥ã¢ãã©ã€ã¶ãŒ) ãéžæ 2. åæãã©ã¡ãŒã¿ã®èšå® åæã®ãã©ã¡ãŒã¿ãããã®ã§ãèŠä»¶ã«åãããã«éžæããŠãããŸãã Savings Plansã¿ã€ãã®éžæ ã©ã®Savings plansã®ã¿ã€ããå©çšãããéžæããŸãã - Compute Savings Plans : EC2ãLambdaãFargateãªã©å¹
åºããµãŒãã¹ã«å¯Ÿå¿ - EC2 Instance Savings Plans : EC2ã€ã³ã¹ã¿ã³ã¹å°çš - SageMaker Savings Plans : SageMakerå°çš æé æé㯠1幎 ãŸã㯠3幎 ããéžæããŸãã æ¯æããªãã·ã§ã³ æ¯æããªãã·ã§ã³ã¯ å
šé¡åæã ã äžéšåæã ãŸã㯠åæããªã ããéžæããŸãã ã«ãã¯ããã¯æé åæã®å¯Ÿè±¡ãšããæéãéžæããããšãã§ããŸãã 7æ¥ ã 30æ¥ ã 60æ¥ ãçšæãããŠããä»ã«ã«ã¹ã¿ã ã§ãéå»60æ¥éã®ä»»æã®ç¯å²ãéžæããããšãã§ããŸãã éåžžæã®å©çšãšéãå©çšã®ä»æ¹ãããŠããéã«ããã®ç¯å²ãé€å€ããŠéåžžã®å©çšã§ã®ããããã®ã³ãããã¡ã³ãéé¡ãåæããããšãã§ããŸãã æéåãã® Savings Plans ãé€å€ 90æ¥ä»¥å
ã«æéåãã®Savings Plansã察象ãšããŠé€å€ããå€ã§åæãããããšãã§ããŸãã åŒç€Ÿã§ãããã ã£ãã®ã§ãããSavings Plans Purchase Analyzerãå©çšããã¿ã€ãã³ã°ã§ã¯ååã®Savings Planãæ®ã£ãŠããããšãå€ãããšæãã®ã§é€å€ããæ¹ã宿
ã«æ²¿ã£ãåæãã§ããããšæããŸãã ã³ãããã¡ã³ãèšå® ã³ãããã¡ã³ãã«ã¯ã æšå¥š ãš ã«ã¹ã¿ã ã®2çš®é¡ããããåºæ¬çã«ã¯ æšå¥š ã§è¯ãããšæããŸãããæéåäœã®ã³ãããã¡ã³ãéé¡ã倿ŽããŠæ¯èŒããçšéãªã©ã«äœ¿ããããã§ãã 3. åæçµæã®ç¢ºèª åæãå®è¡ãããšã以äžã®ãããªçµæã衚瀺ãããŸãã Savings Plan ã®æšå¥šäºé
ãšSavings Plan 賌å
¥åŸã®æšå®ãªã³ããã³ãè²»çšã®ããããã§ã³ã¹ããã«ãã¬ããžã䜿çšçã確èªã§ããŸãã ãŸããæšå¥šãããSavings Planã®ã³ãããã¡ã³ãéé¡ã»æšå®åé€é¡ãåºåãããã®ã§ãåè¿°ã®ã³ãããã¡ã³ãèšå®ã倿ŽããŠã¿ãŠåœ±é¿ãèŠãããšãã§ããŸãã ãŸãšã Savings Plans Purchase Analyzerã䜿ãããšã§ã賌å
¥åã«ã³ã¹ãåæžå¹æã詳现ã«åæã§ããããšãåãããŸããã å®éã®è³Œå
¥åã«ãPurchase Analyzerã§ã·ãã¥ã¬ãŒã·ã§ã³ãè¡ããèªç€Ÿã®äœ¿çšãã¿ãŒã³ã«æé©ãªèšå®ãèŠã€ããããšã倧åã ãšæããŸããã åè 賌å
¥ãã Savings Plans ã®æ±ºå® - Savings Plans
ã¯ããã« ããã«ã¡ã¯ããªããŒã«ããéçºéšã®ææ£®ã§ãã çããã¯ãæ¥åžžæ¥åã®äžã§æ°ããæè¡ã«ææŠããæéãåããªãããšæããããšã¯ãããŸãããïŒãšããªãŒã§ã¯ããããªãšã³ãžãã¢ã®æ³ãã«å¿ããããããææŠWEEKããéå¬ããŠããŸãã ææŠWEEKãšã¯ïŒ ææŠWEEKã¯ãéåžžã®äºæ¥éšã®ããŒããããããé¢ãããšã³ãžãã¢ãèªãææ¡ããããŒãã«åºã¥ããŠæè¡çãªææŠã«éäžããç¹å¥ãªæéã§ããåŸæ¥ã¯1é±éãããŠå®æœããŠããŸãããã第6åãšãªãä»åã¯éå¶ã®è»œéåãå³ãã 2æ¥éã®éäžéå¬ ãšããæ°ãã圢åŒã§2025幎7æ16æ¥ã17æ¥ã«éå¬ããŸããã ä»åã®ããŒãã¯ããããã¯ãã«AIãçµã¿èŸŒãããšãä»ãŸã§AIãå®åã§äœ¿ããŠãªãåéãžå°å
¥ãã§ããçæAIã®æ¥éãªé²åã«ãããå®ãããã¯ããžã®é©çšå¯èœæ§ã倧ããåºãã£ãä»ãåããŒã ãã©ã®ãããªææŠãè¡ã£ãã®ããã玹ä»ããŸãã ææŠWEEKã®è©³ããèæ¯ã«ã€ããŠã¯ããã¡ãã®èšäºããåç
§ãã ããã tech.every.tv 第6åææŠWEEKã§ã®å€æŽç¹ ä»åã¯ãããå€ãã®ãšã³ãžãã¢ãåå ããããããã€é«ãææãçã¿åºãããããšãç®æãã以äžã®4ã€ã®å
容ã倿ŽããŸããã 1. é嬿éã®ççž® åŸæ¥ã®1é±ééå¬ãã 2æ¥éïŒææçºè¡šäŒ ãžãšççž®ããŸãããããã«ããéåžžæ¥åãžã®åœ±é¿ãæå°éã«æãã€ã€ãéäžçã«åãçµããç°å¢ãå®çŸããŸããã 2. æ¢åããŒã ã§ã®å®æœã«ããå¹çå ãããŸã§ã®éçºæ¬éšæšªæçãªããŒã ç·šæãããæ¢åããŒã ãããŒã¹ãšããç·šæã«å€æŽããŸããã æ°èŠããŒã ç·šæã§ã¯ããã¡ã€ã³ç¥èã®å
±æãéçºç°å¢ã®æ§ç¯ã«è²Žéãªæéãè²»ãããŠããŸããŸããäžæ¹ãæ¢åããŒã ã§ããã°ã ãããã¯ãã®èæ¯ã課é¡ãæ·±ãçè§£ããŠãã éçºç°å¢ããã§ã«æŽã£ãŠãã ããŒã ã¯ãŒã¯ã確ç«ãããŠãã ãããã®å©ç¹ã«ããã 2æ¥éãšããéãããæéã100%ææŠã«éäž ã§ããããå®è·µçã§äŸ¡å€ã®ããææã«ã€ãªãããŸããã 3. AIã«ç¹åããããŒãèšå® ä»åã¯ææŠããŒããäžèš2ç¹ã«çµã æç¢ºå ããŸããã ãããã¯ãã«AIãçµã¿èŸŒã ä»ãŸã§AIãå®åã§äœ¿ããŠãªãåéãžå°å
¥ ãã®æç¢ºãªããŒãèšå®ã«ãããåå è
ããã¯ãé©åºŠãªå¶çŽãããããšã§ããããææŠå
容ãå
·äœåãããããªã£ãããAIãšããå
±éèšèªãããããšã§ãä»ããŒã ã®çºè¡šãçè§£ããããåŠã³ãå€ãããšãã£ãããžãã£ããªãã£ãŒãããã¯ãåŸãããšãã§ããŸããã 4. äž»äœçãªåå ãä¿ãä»»æåå å¶ å
šå¡åå ãã ä»»æåå å¶ ãžãšå€æŽããåå åžæè
ããããŒãžã£ãŒãšçžè«ã®äžã§åå ãæ±ºå®ããæ¹åŒãæ¡çšããŸããã ãã®å€æŽã«ãããåå è
å
šå¡ãé«ãã¢ãããŒã·ã§ã³ãæã£ãŠåãçµãç°å¢ãšãªããéãããæéã§ã質ã®é«ãææãç¶ã
ãšçãŸããããšãšãªããŸããã 第6åææŠWEEKã«ã€ã㊠ä»å㯠10ããŒã ãç·å¢31å ã®ãšã³ãžãã¢ãåå ããããããã®ãããã¯ã課é¡ã«å¯ŸããŠAIãæŽ»çšãã解決çã«ææŠããŸããã åãçµã¿å
容(äžéšæç²) æ¢åAIåŠçã®é«éå 課é¡ïŒ ããªãã·ã¥AIã®æ¢ååŠçã«ãããŠãè€éãªåŠçãçŽåã«ç©ã¿éãªãããšã«ãã£ãŠãã¬ã¹ãã³ã¹ã¿ã€ã ãé
ããªãäºè±¡ãçºçããŠããã 宿œå
å®¹ïŒ åŠçã®äžŠååãLLMã®åãåããã®æ¹åã®å®æœãšæ€èšŒã èªäœRedash MCPãµãŒããŒã®äœæ 課é¡ïŒ SQLãæžãããšã«æ
£ããŠããªãã¡ã³ããŒãæ¢åã®Redashã¯ãšãªã®èª¿æ»ãä¿®æ£ãè¡ãéã«ãæäœæ¥ã§ã®äºåæºåãã¯ãšãªéèšçµæã®ç¢ºèªã«æéãããããšãã課é¡ããã£ãã 宿œå
å®¹ïŒ Redashãšé£æºãããããCursorçµç±ã§åŒã³åºãå¯èœãªMCPãµãŒããŒã®éçºã Figma MCPãå©çšããéçº/Playwright MCPãå©çšããE2Eãã¹ãã®å®æœ 課é¡ïŒ ãªãªãŒã¹ãµã€ã¯ã«ã®é«éåã«é©å¿ããããã®ã¯ã©ã€ã¢ã³ããµã€ãã®å®è£
ãšãã¹ãã®é«éåãå¿
èŠã ã£ãã 宿œå
å®¹ïŒ Figma MCPãå©çšãã管çç»é¢(Vue.js)ãšã¢ããª(Flutter)ã®éçºã®æ€èšŒãPlaywright MCPãå©çšãããèªç¶èšèªããŒã¹ã®èªåãã¹ãã®æ€èšŒã ææçºè¡šäŒã®æ§å 2025幎7æ18æ¥(é)ã«éå¬ããææçºè¡šäŒã§ã¯ãåããŒã ãç±ã®ããã£ããã¬ãŒã³ããŒã·ã§ã³ãè¡ããŸãããæè¡çãªå
容ã¯ãã¡ãããå®éã®ãã¢ã亀ããçºè¡šãç¥èŠã®å
±æãçºè¡šåŸã®è³ªçå¿çãªã©ãåå è
å
šå¡ãå€ãã®åŠã³ãåŸãæ©äŒãšãªããŸããã ä»åŸã®å±é 第6åææŠWEEKã¯ãéå¶åœ¢åŒã倧ãã倿Žããã«ãé¢ããããæåŸ
ãäžåãææãçã¿åºãããšãã§ããŸããã 2æ¥éãšããçæéã§ã®æåãåããŠãéå¶ããŒã ã§ã¯ éå¬é »åºŠã®åäž ãæ€èšããŠããŸããããé »ç¹ã«éå¬ããããšã§ããææŠãããšããªãŒã®ãšã³ãžãã¢ã«ãšã£ãŠæ¥åžžçãªæåãšããŠå®çãããŠããäºå®ã§ãã â»5æ¥éã®éåžžçã®ææŠWEEKã幎ã«1åãããã®é »åºŠã§éå¬ããããšèããŠããŸãã æåŸã« ãšããªãŒã§ã¯ããšãã«åã仲éãåéããŠããŸãã ããã¯ããã°ãèªãã§å°ãã§ããšããªãŒã«èå³ãæã£ãŠããã ããæ¹ã¯ããã²äžåºŠã«ãžã¥ã¢ã«é¢è«ã«ãè¶ããã ããïŒ corp.every.tv æåŸãŸã§ãèªã¿ããã ããããããšãããããŸããïŒ
ã¯ããã« ããã«ã¡ã¯ïŒããªãã·ã¥ãããã³ã§äž»ã«ããã¯ãšã³ãã®éçºãæ
åœããŠããç§å±±ã§ãã ãšããªãŒéçºéšã§å
æ¥è¡ãããææŠweekã®äžã§ãç§ãã¡ã®ããŒã ãéçºããRedash MCPã«ã€ããŠç޹ä»ããŠãããŸãã èæ¯ çŸåšåŒç€Ÿã§ã¯AIã³ãŒããšãã£ã¿ã®Cursorããšã³ãžãã¢ãšPdMã«é
åžããŠããŸãã æ¥ã
ã®ããŒã¿åæã«ã¯Redashãçšããããšãå€ããPdMã¯Cursorã䜿çšããŠRedashã®ã¯ãšãªäœæãªã©ãè¡ããŸãã ä»åã¯æ¥åæ¹åã®äžç°ãšããŠãRedash MCPãäœãããšã§ããŒã¿åæãããå¹çåããPdMã®è² è·åæžãããããšèããŸããã PdMãæ±ããŠããäž»ãªèª²é¡ å
·äœçãªå®è£
ã«å
¥ãåã«ããŸãã¯PdMãæ±ãã課é¡ãããããã¢ãªã³ã°ããŸããã ãã¢ãªã³ã°ã®çµæã以äžã®ãããªèª²é¡ãåŸãããšãã§ããŸããã 1. Cursorã䜿ã£ãŠRedashã§ã¯ãšãªãäœæã»æŽæ°ããéã«ãäºåæºåãå¿
èŠã§ãããå°ãæé Cursorã¯åºæ¬çã«Redashã§æ±ããããŒã¿ã®æ
å ±ãç¥ããŸããã ãã®ãããCursorã䜿ã£ãŠã¯ãšãªãæžãéã¯ãããŒãã«æ§é ãæããããªã©ã®äºåæºåã«ãªããŸãã æ¯åããã³ããã«æžããããæ±ãããŒãã«æ§é ã確èªãã€ã€ããã¥ã¡ã³ãåããããšã§Cursorã«èªèããŠããããŸãããCursorèªèº«ãRedashäžã®æ
å ±ãåãã«ãããæ¹ãå¹ççã§ãã 2. æ®æ®µRedashãè§Šããªãã¡ã³ããŒããã¯ãšãªä¿®æ£ã®äŸé ŒãããŠå°ãå€§å€ äŸãã°ããã®ã¯ãšãªã®éèšçµæãäžé±éããäžã¶æã§åºããŠã»ããããªã©ã®ç°¡åãªäŸé ŒãPdMã«æ¥ãããšããããŸãã Redashã«æ
£ããŠããªãã£ãããã¯ãšãªãæžããªããããªã¡ã³ããŒã§ãããçšåºŠèªåã§è§£æ±ºã§ãããšå¬ããã§ãã 3. æ°å€ã®å€åã¯Redashã®ã¯ãšãªçµæãã¿ãªããšææ¡ã§ãããç°åžžãªå€ãåºãŠãããšãã«å³åº§ã«æ°ã¥ããªã Redashã«ã¢ã©ãŒãæ©èœã¯ãããã®ã®ãæè»ãªèšå®ãã§ããããã§ã¯ãªããããããæè»ã«ç°åžžå€ãæ€åºã§ãããšå¬ããã§ãã Redash MCPã®å®è£
ã«ã€ã㊠䞻ãªäœ¿çšæè¡ ä»åäœæããRedash MCPã®äœ¿çšæè¡ã玹ä»ããŸãã Go 1.23.0 go-sdk 0.2.0 MCPã®å
¬åŒSDK Docker Redash(APIã§å©çš) â»2025幎8æ8æ¥çŸåšgo-sdkã®å®å®çã¯ãªãªãŒã¹ãããŠããŸããããä»åŸãªãªãŒã¹äºå®ã®ããã§ãã äœæããæ©èœ Redash APIãçšæããŠãããšã³ããã€ã³ãã®ãã¡ãå®éã«ãã䜿ããããªãšã³ããã€ã³ãã«çµã£ãŠäžèšã®ãããªæäœãã§ããããã«ããŸããã ããŒã¿ãœãŒã¹äžèЧååŸ ããŒã¿ãœãŒã¹è©³çްååŸ ã¯ãšãªäžèЧååŸ ç¹å®ã®ã¯ãšãªè©³çްååŸ ã¯ãšãªå®è¡ãå®è¡çµæååŸ ã¯ãšãªäœæ ã¯ãšãªæŽæ° ããã·ã¥ããŒãæ
å ±ååŸ å®è£
äŸ ä»¥äžãRedash MCPãµãŒããŒã®ç°¡åãªå®è£
äŸã§ãã ããã§ã¯ïŒã€ã®ã¯ãšãªæ
å ±ãååŸããŠããã±ãŒã¹ãèããŸãã package main import ( "context" "log" "github.com/modelcontextprotocol/go-sdk/mcp" ) // ã¯ãšãªååŸã®ãã©ã¡ãŒã¿ type GetQueryParams struct { ID int `json:"id" jsonschema:"ã¯ãšãªID"` } // ã¯ãšãªååŸã®å®è£
func GetQuery(ctx context.Context, cc *mcp.ServerSession, params *mcp.CallToolParamsFor[GetQueryParams]) (*mcp.CallToolResultFor[any], error ) { // å®éã«ã¯ããã§Redash APIãåŒã³åºããŠã¯ãšãªæ
å ±ãååŸãã queryInfo := "ã¯ãšãªID: " + string (params.Arguments.ID) + "ã®æ
å ±" return &mcp.CallToolResultFor[any]{ Content: []mcp.Content{&mcp.TextContent{Text: queryInfo}}, }, nil } func main() { // MCPãµãŒããŒäœæ server := mcp.NewServer(&mcp.Implementation{Name: "redash" , Version: "v1.0.0" }, nil ) // ããŒã«ã®è¿œå mcp.AddTool(server, &mcp.Tool{ Name: "get-query" , Description: "Redashã®ã¯ãšãªãååŸãã" , }, GetQuery) // ãµãŒããŒãèµ·å if err := server.Run(context.Background(), mcp.NewStdioTransport()); err != nil { log.Fatal(err) } } ããã§Redash MCPãµãŒããŒã®å®è£
ã¯å®äºã§ãã go-sdkã䜿ããšãMCPãµãŒããŒã®å®è£
ãéåžžã«ç°¡åã§ããã âªdockerã§èµ·åããŠCursorã§äœ¿ãå Žåã®å®è£
äŸ äžèšã®ããã«DockerfileãæºåããŸãã FROM golang:1.23 as builder WORKDIR /app COPY . . RUN go mod tidy && go build -o mcp-server main.go FROM debian:stable-slim WORKDIR /app RUN apt-get update && apt-get install -y ca-certificates openssl && rm -rf /var/lib/apt/lists/* COPY --from=builder /app/mcp-server . ENTRYPOINT ["/app/mcp-server"] ã€ã¡ãŒãžããã«ãããŸã $ docker build -t redash-mcp . Cursorã®ã®mcp.jsonã«äžèšã®å
容ã远å ããŸãã { " mcpServers ": { " redash-mcp ": { " command ": " docker run -i --rm -e REDASH_URL -e REDASH_API_KEY redash-mcp ", " env ": { " REDASH_URL ": " https://hoge.redash.hoge ", " REDASH_API_KEY ": " hogehoge " } } , } } 䜿çšäŸ å®éã«CursorããRedash MCPã䜿ã£ãŠã¿ãäŸã以äžã§ãïŒ æè¿è¿œå ãããã¬ã·ããååŸããã¯ãšãªã®äœæãå®è¡ãããã«ç°¡åãªåæãŸã§ããŠãããŸããã ãã¢ãªã³ã°ãã課é¡ã«å¯Ÿããçµæ æ¬èšäºã®åé ã§æãã課é¡ã«å¯ŸããŠãRedash MCPã§ã©ã®ããã解決ã§ãããèŠãŠãããŸãã 1. Redashã§ã¯ãšãªãäœæã»æŽæ°ããéã«ãäºåæºåãå¿
èŠã§ãããå°ãæé Redashã®ããŒã¿ãœãŒã¹ãMCPçµç±ã§ååŸãããããšã«ãããäºåæºåã®åæžãã§ããŸããã 2. æ®æ®µRedashãè§Šããªãã¡ã³ããŒããã¯ãšãªä¿®æ£ã®äŸé ŒãããŠå°ãå€§å€ ã¯ãšãªäœæã®ããŒãã«ã¯äžå®äžãã£ããã®ã®ãçŸç¶ã ãšCursorãªã©ã®MCPã¯ã©ã€ã¢ã³ãã®æºåãåæèšå®ãå¿
èŠãªããã誰ã§ãæ°è»œã«äœ¿çšã§ããç¶æ
ã«ã¯ã§ããŠããŸããã 3. æ°å€ã®å€åã¯Redashã®ã¯ãšãªçµæãã¿ãªããšææ¡ã§ãããç°åžžãªå€ãåºãŠãããšãã«å³åº§ã«æ°ã¥ããªã çãæéã§ã®å®è£
ã ã£ãããããã®èª²é¡ã«å¯ŸããŠã®ã¢ã¯ã·ã§ã³ã¯ã§ããŠããŸãããã äŸãã°Devinãšé£æºããŠå®æçã«ç°åžžå€ãèŠã€ããŠãããããªã©ã®ããšãåºæ¥ããšè¯ããªãšèããŠããŸãã PdMããã®ãã£ãŒããã㯠äœäººãã®PdMã«å®éã«äœ¿ã£ãŠããã ãã以äžã®ãããªå¬ããã³ã¡ã³ããããã ããŸããïŒ ã¯ãšãªå
ã®ã³ã¡ã³ããã¡ãããšæžãããŠãŠå¯èªæ§ãè¯ã ã¯ãšãªäœæãç§ã§çµãã£ãŠæå redashãè€æ°ã®ããŒã¯ãŒãæ€çŽ¢ã§ããªãã®ã§å©ãã ã¯ãšãªã®å·®åãæ¯èŒãããšãã«ãããããã¯ãšãªã³ããŒããæéããªããªã£ã äžæ¹ã§ãæ¹åç¹ãèŠã€ãããŸããã Cursorç°å¢ãã¿ãŒããã«ãçã䜿ããããã§ã¯ãªããããslackãªã©ããåŒã¹ããšäœ¿ãã人ã®å¹
ãåºãã£ãŠå¬ãã ããã©ã«ãã§Cursorã«å
¥ããã¹ãã«ãŒã«ã¿ãããªãã®ããããšè¯ããã Redashãšé£æºããŠããTreasureDataå°çšã®td颿°å
šç¶äœ¿ã£ãŠãããªããŠãçµæ§ãšã©ãŒåãããã®ã§ãããã³ããé 匵ããªãããããªããªãšæãã€ã€ãããã³ãããæåãããããšå¬ãã ã«ã©ã ã«å®éã©ããªããŒã¿ãå
¥ã£ãŠããæšæž¬ãééããæãããããããã®èŸºããã粟床äžãããããšå¬ãã ä»åŸã®å±æ PdMããã®ãã£ãŒãããã¯ãªã©ãããšã«ãä»åŸã¯ãããªããšããã£ãŠããããã§ãã 1. Redash MCPã䜿ããŸã§ã®ããŒãã«ãäžãã ãŸãããªã¢ãŒãMCPãµãŒããŒã«ãããã§ãã çŸåšã¯MCPãããŒã«ã«ã§èµ·åãããŠããŸããããã®æ¹æ³ã ãš åæèšå®æã«ããŒã«ã«ã§ãã«ãããå¿
èŠãããæé ã¢ããããŒãã®ãã³ã«ããŒã«ã«ã§ãã«ããå¿
èŠã«ãªã ãªã©ã®åé¡ããããŸãã ãªã¢ãŒãMCPãµãŒããŒã«ããããšã§ãããã®åé¡ã解決ãããã§ãã ãŸããã»ãã¥ãªãã£é¢ãªã©ãèæ
®ãã€ã€ å¯èœã§ããã°Devinã䜿ã£ãŠSlackããåŒã³åºããªã©ãåºæ¥ãããã«ããŠããããã§ãã 2. äºåã«æž¡ãæ
å ±ã®æŽå åŒç€Ÿã®Redashã§æ±ã£ãŠããããŒã¿ãœãŒã¹ã«ã¯ãDBã®ããŒã¿ä»¥å€ã«ãTreasureDataãFirebaseãªã©ã®ä»ãµãŒãã¹ãšé£æºããŠååŸããŠããããŒã¿ããããŸãã ç¹ã«ãä»ãµãŒãã¹ããååŸããŠããããŒã¿ã®ã¹ããŒãæ
å ±ã¯ãRedashã§è©³çްãŸã§æã£ãŠããªãããšãå€ãã§ãã ããã¥ã¡ã³ããšããŠãŸãšãŸã£ãŠãããã®ãããã®ã§ããããå©çšããããšã«ããRedash MCPã®ç²ŸåºŠãäžããŠããããã§ãã ãã®ä»ãéæãã£ãŒãããã¯ãããã ãæ¹åããŠããããã§ãã ãŸãšã æ¬èšäºã§ã¯ã瀟å
Redash MCPäœæã®èæ¯ãå®è£
äŸãå®éã®äœ¿çšæã«ã€ããŠç޹ä»ããŸããã ä»åPdMã®äœæ¥è² è·è»œæžãç®çãšããŠRedash MCPãäœããŸãããããšã³ãžãã¢ã«ãšã£ãŠãRedashã䜿ãããŒãã«ãäœããªããšãã坿¬¡çãªå¹æããã£ãããªãšæããŸãã å®éãç§ã¯Redash MCPãå©çšãå§ããŠãããµã¯ããšã¯ãšãªãäœããããã«ãªããŸããã ä»åŸãçããã䜿ãããããªãããã«æ¹åããŠããããã§ãã æåŸãŸã§èªãã§ããã ãããããšãããããŸããïŒ åèæç® https://github.com/modelcontextprotocol/go-sdk https://modelcontextprotocol.io/docs/getting-started/intro
ãšããªãŒã§å°å£²æ¥çã«åãåãã®éçºãè¡ã£ãŠãã @kosukeohmura ã§ãã ä»åã¯ãFlutter ã¢ããªã±ãŒã·ã§ã³ã« AWS Cognito ã䜿ã£ãèªèšŒæ©èœãå°å
¥ããããã»ã¹ã«ã€ããŠç޹ä»ããŸãã ããã¯ãšã³ãã§ Cognito ãã©ããããããã¢ããªããçŽæ¥ Cognito ã«æ¥ç¶ããã Cognito ã IdP ãšããŠæ¡çšãèªèšŒæ©æ§ãæ°ãã«éçºããã«ããããããã¯ãšã³ãã Cognito ãã©ããããå®è£
æ¹éãšãã¢ããªããçŽæ¥ Cognito ã«æ¥ç¶ããæ¹åŒãæ€èšããŸãããçµè«ãšããŠã¯ä»å㯠Flutter ã¢ããªããçŽæ¥ Cognito ã«æ¥ç¶ããæ¹åŒãéžæããŸããã ããã¯ãšã³ãã§ Cognito ãã©ããããæ¹åŒã§ã¯ãããã¯ãšã³ãã§ Cognito Admin API ãçšããèªèšŒåŠçãèªç±ã«æžãããšãå¯èœã§ãããèªç±ã«åŠçãæžããåé¢ãåºæ¬çã«ã¯ Cognito ãåŒã³åºãã ãã®ç¬èªã®ãšã³ããã€ã³ã矀ãå®è£
ããå¿
èŠãããããŸããã®ãšã³ããã€ã³ããå©çšããã¢ããªåŽã®ç»é¢ã®å®è£
ãå¿
èŠã«ãªããŸãã äžæ¹ãã¢ããªãã Amplify ãå©çšãçŽæ¥ Cognito ã«æ¥ç¶ããæ¹åŒã§ã¯ãç¬èªã®ãšã³ããã€ã³ã矀ãå®è£
ããããšãªãèªèšŒæ©æ§ãå®è£
ã§ããå ã㊠Amplify ã§ãã§ã«çšæãããèªèšŒç»é¢ã® UI ã䜿çšããã°ã¢ããªã®ãã°ã€ã³ç»é¢ãªã©ã®å®è£
ãäžèŠãšãªããŸããããã¯ãšã³ãã§ã¯èªèšŒãå¿
èŠãªãšã³ããã€ã³ãããããã«å¯ŸããŠã¢ããªã Cognito ããååŸãããŠãŒã¶ãŒããŒã¯ã³ã驿£ããå€å¥ããããã«ãŠã§ã¢ãæã圢ã§ãããã®æ¹åŒã ãšãå®è£
ãã察象ã倧ããæžãäžæ¹ã§ãAmplify ã®æ©èœããå€ããããšãè¡ãããšãããšå·¥å€«ãå¿
èŠãšãªãããšæããŸãã ä»åç§é㯠ID/PW ã§ã®èªèšŒèªå¯ããã§ããã°ãããèªèšŒèªå¯ååŸã«ç¬èªã®åŠçãæã¿èŸŒãã ãããå¿
èŠã¯ãããŸããã§ãããã¢ããªã®ç»é¢ãäžè¬çãªãµã€ã³ã€ã³ç»é¢ãååšããã°ããã£ãã®ã§ãAmplify ã®ããã©ã«ãã® UI ã³ã³ããŒãã³ããå°ãæ¹å€ããã°ååäºè¶³ãããã§ãããããããèæ¯ããã¢ããªããçŽæ¥ Cognito ãžæ¥ç¶ããæ¹åŒã®ãã¡ãªãããåé¡ã«ãªããªãããªãããå®éšçã«å®è£
ãè¡ãæçšæ§ã確ãããåŸã«ããã®æ¹åŒãéžæããããšãšããŸããã å°å
¥ããäž»èŠãªå€æŽ å
¬åŒã® Quickstart - AWS Amplify Gen 2 Documentation ãåç
§ããªããå°å
¥ãè¡ããŸãã 1. Amplify Flutter ããã±ãŒãžã®è¿œå ãŸãæåã«å¿
èŠãªäŸåé¢ä¿ã远å ããŸããããã«ãããFlutter ã¢ããªã§ Amplify ã®èªèšŒæ©èœã䜿çšã§ããããã«ãªããŸãã flutter pub add amplify_flutter amplify_auth_cognito amplify_authenticator ããããã®ããã±ãŒãžã®é¢ä¿æ§ãããããããŸããã§ããããQuickStart ã«èšèŒãããŠãã説æã端çã§ããããããã§ãã amplify_flutter to connect your application with the Amplify resources. amplify_auth_cognito to connect your application with the Amplify Cognito resources. amplify_authenticator to use the Amplify UI components. 2. Flavor ã«å¿ã㊠dart_define ãã¡ã€ã«ãçæã»äœ¿çšãã ç°å¢ããšã« Cognito ã®ãŠãŒã¶ãŒããŒã«ãåãæ¿ããããããŸã Flavor ã«å¿ããŠç°å¢å€æ°ãã¢ããªãžæ³šå
¥ã§ããããã«ããŸããFlavor ç°å¢å€æ°ãã¢ããªãžæ³šå
¥ããããã« dart_define ãã¡ã€ã«ã䜿çšããŸãããããããã³ãã¬ãŒãåããŠãããŸãã dart_define.template.json { " awsRegion ": " $AWS_REGION ", " cognitoUserPoolId ": " $COGNITO_USER_POOL_ID ", " cognitoUserPoolClientId ": " $COGNITO_USER_POOL_CLIENT_ID " } ããããã direnv ãªã©ã䜿ãç°å¢å€æ°ãèšå®ããŠããããããå
ã«å®éã® dart_define ãã¡ã€ã«ãçæãå©çšããŸãã以äžãããè¡ã Makefile äŸã§ãã FLAVOR ?= development generate-dart-define: cat dart_define.template.json | envsubst > dart_define_$$FLAVOR.json run-development: $(FLUTTER) run --debug --flavor development --dart-define-from-file=dart_define_development.json ãã®ä»çµã¿ã«ãããç°å¢ããšã«ç°ãªãç°å¢å€æ°ã䜿çšã§ããŸãã 3. Amplify èšå®ãã¡ã€ã«ã®ç®¡ç GitHub ã§å
¬éãããŠããã¹ããŒã amplify-backend_packages_client-config_src_client-config-schema_schema_v1.json at main · aws-amplify_amplify-backend ã«åŸã£ãŠãAmplify èšå®ãã¡ã€ã«ãæ§ç¯ããŸããAWS äžã§èšå®ãããŠãŒã¶ãŒããŒã«ã®èšå®å€ãšè¢«ãéšåã¯åãããŠãããŸããäžéšã®èšå®å€ã¯ãã¬ãŒã¹ãã«ããšããŠãããã¢ããªå®è¡æã«ç°å¢å€æ°ã§çœ®æããŸãã lib/amplify_outputs.json { " version ": " 1.1 ", " auth ": { " aws_region ": " <Will be replaced when building> ", " user_pool_id ": " <Will be replaced when building> ", " user_pool_client_id ": " <Will be replaced when building> ", " password_policy ": { " min_length ": 12 , " require_lowercase ": false , " require_uppercase ": false , " require_numbers ": false , " require_symbols ": false } , " username_attributes ": [ " email " ] , " user_verification_types ": [] , " unauthenticated_identities_enabled ": false , " mfa_configuration ": " NONE " } } ãã®å
容ãã¢ããªå®è¡æã«ç°å¢å€æ°ã§äžæžãããããšã§ãåç°å¢ã«é©ããèšå®ãé©çšãããŸãã 4. ã¢ããªèµ·ååŸã« Amplify ãã»ããã¢ãããã æºåãã Amplify èšå®ãã¡ã€ã«ãšç°å¢å€æ°ã䜿çšããã¢ããªèµ·ååŸã« Amplify ãã©ã°ã€ã³ã®åæåãè¡ããŸãããããè¡ãããã® AmplifyService ãå®è£
ããŸãã: lib/services/amplify.dart class AmplifyService { final Ref _ref; final BundleRepository _bundleRepository; @override Future<Result< void , MyAppException>> setupAmplify() async { try { await Amplify.addPlugin(AmplifyAuthCognito()); final amplifyConfigResult = await _buildAmplifyConfig(); if (amplifyConfigResult.isError) throw amplifyConfigResult.error; await Amplify.configure(amplifyConfigResult.okValue); return Result.ok( null ); } catch (e, s) { return Result.error(MyAppException(e, s)); } } // lib/amplify_outputs.json ãã¡ã€ã«ãååŸã Map ãšããŠè¿åŽ Future<Result< String , MyAppException>> _buildAmplifyConfig() async { final amplifyConfigString = await _bundleRepository.readBundle(BundlePath.amplifyConfig); final amplifyConfig = jsonDecode(amplifyConfigString) as Map< String , dynamic >; amplifyConfig[ 'auth' ][ 'aws_region' ] = /* ç°å¢å€æ°ããæ³šå
¥ */ ; amplifyConfig[ 'auth' ][ 'user_pool_id' ] = /* ç°å¢å€æ°ããæ³šå
¥ */ ; amplifyConfig[ 'auth' ][ 'user_pool_client_id' ] = /* ç°å¢å€æ°ããæ³šå
¥ */ ; return Result.ok(jsonEncode(amplifyConfig)); } } ããšã¯ãã¢ããªã±ãŒã·ã§ã³ã®ãšã³ããªãŒãã€ã³ãã§ AmplifyService ã䜿çšããŸã: Future< void > main() async { // ... æ¢åã®åæååŠç final amplifySetupResult = await container.read(amplifyServiceProvider).setupAmplify(); if (amplifySetupResult.isError) { logger.fatalException( 'Error occurred when configuring Amplify' , amplifySetupResult.error); } runApp(UncontrolledProviderScope(container: container, child: const MyApp())); } ããã§ Amplify ã®ã»ããã¢ãããå®äºããŸãããå ã㊠QuickStart ã©ããã« UI ã³ã³ããŒãã³ããèšè¿°ããã°ãµã€ã³ã€ã³ïŒãµã€ã³ã¢ããç»é¢ã衚瀺ãããŸãããç¹æ®µé£ããããšã¯ãªãçç¥ããŸãã ãŸãšã ä»åã®å®è£
ã§ã¯ãAmplify UI ã䜿çšããããšã§æ¯èŒçã¹ã ãŒãºã«èªèšŒæ©èœãå°å
¥ã§ããŸãããããã¯ãšã³ãçµç±ã§ã¯ãªã Flutter ããçŽæ¥ Cognito ã«æ¥ç¶ããããšã§ãéçºé床ãéèŠããªãããã»ãã¥ãªãã£ãä¿ã€ããšãã§ããŸããã ãŸããç°å¢éã§å¯å€ãªå€ãç°å¢å€æ°ã§ç®¡çãããã³ãã¬ãŒããã¡ã€ã«ã䜿çšããããšã§ãç°ãªãç°å¢ïŒéçºã»æ¬çªïŒãžåããŠå®å
šã«ã¢ããªãå®è¡ã§ããããã«ãªããŸãããAmplify ã»ããã¢ãã Service ã¯ã©ã¹ã«ç
©éãªåŠçãæŒã蟌ãããšã§ãã¢ããªã±ãŒã·ã§ã³ã®ãšã³ããªãŒãã€ã³ãã«æããã責åãæå°éã«æããããšãã§ããŸããã Flutter ã§ã®èªèšŒå®è£
ãæ€èšãããŠããæ¹ã®åèã«ãªãã°å¹žãã§ãã åèè³æ Amplify Docs - AWS Amplify Gen 2 Documentation Amplify UI - Build UI fast with Amplify on Flutter
ã¯ããã« åæ æè¡ã¹ã¿ã㯠ç£èŠã®æ§æ çŸç¶ã®èª²é¡ Devinéžå®çç± 1. ãã«ãRepository察å¿ã®å®¹æã 2. èªåŸåAIãšããŠã®éçšå¹ç æ§æ æé Playbook 1. Devinã®èµ·åãšSentryã¢ã©ãŒãæ
å ±ã®ååŸ 2. Devin Playbookã®å®è¡ 2-1. é¢é£æ
å ±ã®ååŸ 2-2. åæ 2-3. è¿œå æ
å ±ã®ååŸ 2-4. å³è¡šã®äœæ 3. Slackãžåºå çµæ éçšããŠã¿ãçµæ éçšããŠã¿ãŠèŠããŠããèª²é¡ ãŸãšã ã¯ããã« éçºæ¬éšã§ããªãã·ã¥ãããã³ã®ã¢ããªãŠã§ãã°ããŒã¹åãã®éçºãæ
åœããŠãã hond ã§ãïŒ ä»åã¯å
æ¥è¡ããã 第6åææŠweek ã§ç§ãã¡ã®ããŒã ãè¡ã£ãDevinã«ããSentryã¢ã©ãŒãã®æ¹åã«ã€ããŠç޹ä»ããŸãã æ¬èšäºã¯Devinã®åºæ¬çãªæŠå¿µãäœ¿ãæ¹ã«ã€ããŠããçšåºŠçè§£ããŠããèªè
ã察象ãšããŠããŸããDevinèªäœã®è©³çްãªèª¬æã¯çç¥ããå®éã®æ¥åã§ã®æŽ»çšäºäŸã«çŠç¹ãåœãŠãŠè§£èª¬ããŸãã ãªããä»åã®åãçµã¿ãæ€èšããéã«ãç§ãã¡ã®ç®æšãšå®å
šã«äžèŽãã SMARTCAMPããã®èšäº ãçºèŠããéåžžã«åèã«ãªããŸãããç§ãã¡ã®ç°å¢ãèŠä»¶ã«åãããŠã«ã¹ã¿ãã€ãºãè¡ããªãããåèšäºã®ã¢ãããŒããåèã«ãããŠããã ããŸããïŒ åæ æè¡ã¹ã¿ã㯠æ¬èšäºã§æ±ãæè¡ã¹ã¿ãã¯ã¯ä»¥äžã®éãã§ãã é
ç® æè¡ ãšã©ãŒç£èŠ Sentry éç¥ Slack AIéçºæ¯æŽ Devin å³è¡šçæ Mermaid ããŒãžã§ã³ç®¡ç GitHub ã€ã³ãã© AWS ã¢ããªã±ãŒã·ã§ã³ Nuxt.js (ããã³ããšã³ã)ãGo (ããã¯ãšã³ã) ç£èŠã®æ§æ ããªãã·ã¥ãããã³ã§ã¯çŸåšã¢ããªã±ãŒã·ã§ã³ã®ãšã©ãŒç£èŠããŒã«ãšã㊠Sentry ãçšããŠããŸãããã®Sentryã«ã¯Nuxt.jsã§åäœããããªãã·ã¥ãããã³ã®ãŠã§ãã¢ããªã±ãŒã·ã§ã³ãããã³Goã®ããã¯ãšã³ããµãŒããŒã§çºçãããšã©ãŒãéä¿¡ãããä»çµã¿ãšãªã£ãŠããŸããSentryã«éä¿¡ããããšã©ãŒã¯Integrationãä»ããŠSlackã®ã¢ã©ãŒããã£ã³ãã«ã«éç¥ãããŸãã çŸç¶ã®èª²é¡ ãã®ã¢ã©ãŒãéçšã«é¢ããŠãäž»ã«ä»¥äžã®èª²é¡ããããŸãã: ç·æ¥åºŠããããã¥ãã ïŒã¢ã©ãŒãã®éèŠåºŠãäžæçã§ã察å¿ã®åªå
é äœä»ããå°é£ 解決ã«å¿
èŠãªæ
å ±ãäžæç ïŒäžéšã®ãšã©ãŒã§ã¯Sentryã«éãããæ
å ±ãäžè¶³ããŠãããç¹ã«ã¹ã¿ãã¯ãã¬ãŒã¹ããªãå Žåã«åé¡è§£æ±ºã«å¿
èŠãªæ
å ±ãç¹å®ããã®ãå°é£ èª¿æ»æé ãäžæ ïŒAWSã³ã³ãœãŒã«ãSentryãã¢ããªã±ãŒã·ã§ã³ã³ãŒããAthenaãªã©ãè€æ°ã®ãªãœãŒã¹ã暪æããŠèª¿æ»ããéã®æç¢ºãªæé ã確ç«ãããŠããªãã æŸçœ®ãããŠããã¢ã©ãŒãããã ïŒããã«ãããéçºè
ã®å¿ççè² æ
ãå¢å ã ã¢ã©ãŒãç®æã®æ
åœãäžæç ïŒã©ã®ãšã©ãŒãã©ã®éçºããŒã ã®æ
åœãäžæç¢ºã Devinéžå®çç± ä»åã®èª²é¡è§£æ±ºã«ãããŠãç§ãã¡ãDevinãéžå®ããçç±ã¯å€§ãã2ã€ãããŸãã 1. ãã«ãRepository察å¿ã®å®¹æã äºåã«ä»ã®ã¡ã³ããŒãCursorãClaude Codeã®æ€èšŒã瀟å
å匷äŒã§è¡ããŸãããããããã©ã¡ããRepositoryãè·šãã 調æ»ã«ãããŠä»¥äžã®èª²é¡ãçºçããŸããã è€æ°Repositoryã®èšå®ã«è¿œå äœæ¥ãå¿
èŠ èšå®å®äºåŸãRepositoryãæšªæããåŠçã®è§£éãæåŸ
å€ãäžåã Devinã§ã¯ãWorkspaceå
ã«å¿
èŠãªRepositoryãcloneããã ãã§èšå®ãå®äºããããã³ããšã³ããšããã¯ãšã³ããã€ã³ãã©ã®ã³ãŒããæšªæãã調æ»ãå¹ççã«è¡ããŸããã äŸãã°ãã€ã³ãã©ã®ã³ãŒããè§£éããŠããã³ããšã³ããAWSäžã§ã©ãã«äœçœ®ããããçè§£ããã©ã®ããã¯ãšã³ããµãŒããŒãšé¢ä¿ãããããæèããã¬ã¹ãã³ã¹ãè¡ããŠããŸããã 2. èªåŸåAIãšããŠã®éçšå¹ç Devinã®èªåŸåç¹æ§ã«ããã以äžã®éçšã¡ãªãããå®çŸã§ããŸããã 䞊è¡åŠç : ãšã³ãžãã¢ãè¡ããšã©ãŒçºçæã®äžæ¬¡å¯Ÿå¿ãšäžŠè¡ããŠDevinããšã©ãŒèª¿æ»ãèªåå®è¡ å±¥æŽã®å¯èŠå : 調æ»ããã»ã¹ãDevinã»ãã·ã§ã³å
ã«èšé²ãããããŒã å
šäœã§å
±æå¯èœ æé ã®æšæºå : 人çèŠå ã«äŸåããªãäžè²«ãã調æ»å質ãæ
ä¿ æ§æ æçµçã«æ§ç¯ããSentryã¢ã©ãŒãèªååæã·ã¹ãã ã®æ§æã¯äžèšã®éãã§ãã æé Devinã®èµ·åãšSentryã¢ã©ãŒãæ
å ±ã®ååŸ Devin Playbookã®å®è¡ é¢é£æ
å ±ã®ååŸ åæ è¿œå æ
å ±ã®ååŸ å³è¡šã®äœæ Slackãžåºå Playbook Sentry APIã«Curlã³ãã³ãã§ã¢ã©ãŒãã®æ
å ±ãååŸããŠãäžèšã®åæçµæãåºåããŠãã ããã èª¿æ»æé ãšããŠä»¥äžã®4ã¹ããããé çªã«å®æœããããšïŒ --------------- ## 1. Sentry APIãå©ããŠã¬ã¹ãã³ã¹ãååŸ Sentry APIã¯ãäžèšã³ãã³ããå®è¡ããŠãã ãããã¢ã©ãŒãå
šäœã¯issue, ã€ãã³ã詳现ã¯issue and event ãå©ããŠãã ãããsecretã¯SENTRY_API_TOKENãåç
§ããŠãã ããã issue:""" curl https://sentry.io/api/0/organizations/{organization_id_or_slug}/issues/{issue_id}/ \ -H 'Authorization: Bearer {sentry_api_token}' """ issue and event:""" curl https://sentry.io/api/0/organizations/{organization_id_or_slug}/issues/{issue_id}/events/{event_id}/ \ -H 'Authorization: Bearer {sentry_api_token}' ## 2. 察象ãšãªãGit Repositoryã®ç¹å® ãšã©ãŒã®ã¹ã¿ãã¯ãã¬ãŒã¹ãé¢é£æ
å ±ãããåé¡ãçºçããŠããRepositoryãç¹å®ããŸããããã³ããšã³ãïŒNuxt.jsïŒãããã¯ãšã³ãïŒGoïŒãã€ã³ãã©ïŒTerraformïŒã®ããããã倿ããé©åãªRepositoryã«çŠç¹ãåœãŠãŸãã ## 3. é¢é£ããGit Repositoryãä»ã«ãªããèª¿æ» ç¹å®ãããRepository以å€ã«ãããšã©ãŒã«é¢é£ããå¯èœæ§ãããRepositoryããªããã調æ»ããŸããäŸãã°ãããã³ããšã³ããšã©ãŒãããã¯ãšã³ãAPIã®å€æŽã«èµ·å ããå Žåããã€ã³ãã©èšå®ã®å€æŽã圱é¿ããŠããå Žåãªã©ãèæ
®ããŸãã ## 4. ãšã©ãŒã®è©³çްã«é¢ãã調æ»ãšçµæã®åºå äžèšãåæçµæãã©ãŒããããã«åŸããå¿
èŠãªæ
å ±ã調æ»ããŠãã ããã ### 4-1. ã€ã³ãã©æ§æå³ãã¢ãŒããã¯ãã£å³ãå¿
èŠãªå Žåã¯åºå ãšã©ãŒç®æãåå ãå
šäœåãææ¡ã§ãããããA. AWSã®ã€ã³ãã©æ§æå³, B. ã·ã¹ãã æŠèŠå³ ã®2ã€ãæ·»ä»ããŠãã ããã åºåæ¹æ³ã¯ä»¥äžã®éãã§ãA, Bããããã«å¯ŸããŠé çªã«å®è¡ããŠãã ããã 1. mmdãã¡ã€ã«ãåºå (mmdãã¡ã€ã«åã¯A: infra.mmd, B: system.mmd ãšãã) 2. 次ã®ã³ãã³ããå®è¡ïŒmmdc -i <mmdãã¡ã€ã«ãã¹> -o <åºåãã¡ã€ã«å(PNG)> (åºåãã¡ã€ã«åã¯A: infra.png, B: system.png ãšãã) 3. åºåç»åãæ·»ä» ### 4-2. é¢é£Commitã®æ€çŽ¢ gh ã³ãã³ããŸãã¯git ã³ãã³ãã䜿çšããŠãã¢ã©ãŒãã®æ ¹æ¬åå ãšãªãã³ãŒããã©ã®commit, PRã§è¿œå ã»å€æŽãããã®ããç¹å®ããŠãã ããã ------------------------- å®è£
ã¯è¡ããã«ããåæçµæãã©ãŒãããããã³ãŒãæç€ºã«ãŒã«ãã«åŸã£ãŠã¬ããŒããåºåããŠãã ããã åæçµæãã©ãŒããã:""" ðãšã©ãŒã®åºæ¬æ
å ±ç¢ºèª ã»ãšã©ãŒã¿ã€ã ã»ç°å¢ ã»çºçé »åºŠ ã»åœ±é¿ç¯å² ã»çºçæé(yyyy-mm-dd HH:MM:SSã®åœ¢åŒãJST倿å¿
é ) ã»åå(yyyy-mm-dd HH:MM:SSã®åœ¢åŒãJST倿å¿
é ) ã»æçµ(yyyy-mm-dd HH:MM:SSã®åœ¢åŒãJST倿å¿
é ) ð§ââïž é害ã¬ãã«å€æ ã»ðšç·æ¥åºŠé«ïŒå³æå¯Ÿå¿å¿
èŠïŒãµãŒããŒããŠã³ãžã®åœ±é¿ãªã©ïŒ ã»ð¡ç·æ¥åºŠäžïŒãã±ããåã£ãŠä»é±äžã«å¯Ÿå¿ïŒç¹å®æ¡ä»¶äžã§ã®ãšã©ãŒããŠãŒã¶ãŒåœ±é¿ãªãïŒ ã»ðµç·æ¥åºŠäœïŒãã±ããåã£ãŠæéããæã«å¯Ÿå¿ïŒè»œåŸ®ãªäžå
·åãããã©ãŒãã³ã¹äœäžïŒ ð¬ ãšã©ãŒåå å€å® ã»ã·ã¹ãã åŽã®åé¡ïŒãã°ãèšå®ãã¹ããªãœãŒã¹äžè¶³ãªã©ïŒ ã»å€éšèŠå ïŒæ»æçãªã¯ãšã¹ããå€éšãµãŒãã¹é害ãªã©ïŒ ðŠ é¢é£ã®ããCommit,PR ã»æ ¹æ¬åå ãšãªãã³ãŒããã©ã®commit, PRã§è¿œå ã»å€æŽãããã®ã ð§âð» ãšã©ãŒã®åçŸæ¹æ³ ã»ããŒã«ã«ç°å¢ãéçºç°å¢ã§ãšã©ãŒã®åçŸæ¹æ³ã®æç€º ð 察å¿ççå® ã»äžæç察å¿ãšæä¹
ç察å¿ã®åºå¥ ã»æ»æçãªã¯ãšã¹ãã®å Žåã®ã»ãã¥ãªãã£å¯Ÿç """ ã³ãŒãæç€ºã«ãŒã«ïŒ é¢é£ã³ãŒãã瀺ãå¿
èŠãããã°ã以äžã®ããã«ã³ãŒããšGitHubã®ããŒããªã³ã¯ãå«ãã圢ã§åºåããŠãã ãã [delishkitchen_file_name](https://github.com/delishkitchen_file_name#L92-L98) \``` Sentry.withScope(function (scope) { scope.setTag('method', method) scope.setTag('url', path) scope.setTag('query', queryString) Sentry.captureException(err) }) \``` --------------- ãã®æé ã«åŸã£ãŠæ®µéçã«èª¿æ»ãé²ããããšã You only need to look in the following repos: {backend_repository}, {infra_repository}, {frontend_repository} 以éã詳现ã«ã€ããŠè§£èª¬ããŸãã 1. Devinã®èµ·åãšSentryã¢ã©ãŒãæ
å ±ã®ååŸ Devinã®èµ·åã«ã¯Slack workflowãçšããŸãããDevinãšSlackã飿ºããããšã§ã @Devin ã§DevinãSlackã®ã¹ã¬ããããã£ã³ãã«ã§äŒè©±ãéå§ã§ããŸããããã«ãããåæã«ã»ãã·ã§ã³ãéå§ãããŸãããã®ãããä»åã¯è§£æ±ºãããSentryã®ã¡ãã»ãŒãžã« :help-me-devin: ãšãªã¢ã¯ã·ã§ã³ããããšã§ãã®ã¹ã¬ããã«äžèšã®æç« ãåºåãããããã«ããŸããã !sentryanalyzer ã¯åè¿°ã®Devin Playbookã®ãã¯ããšãªã£ãŠããŸãã @Devin !sentryanalyzer @user_name ã«ãã£ãŠäŸé ŒãããŸããã äŸé Œè
ã¯Devinã®ã¬ããŒããçµããæ¬¡ç¬¬ãsleep ãšå
¥åããŠDevinãäŒãŸããŠãããŠãã ããã 2. Devin Playbookã®å®è¡ æé 1ãŸã§ã®åŠçã§Devin sessionã®èµ·åãšSlackã¡ãã»ãŒãžã®çŽä»ããå®äºããŠãããããããããå®éã«Devinã®åŠçãéå§ãããŸãã 2-1. é¢é£æ
å ±ã®ååŸ æ¬¡ã«äžèšæäœã§é¢é£ããæ
å ±ã®ååŸãè¡ããŸãã Sentry APIã®å®è¡ 察象ãšãªãGit Repositoryã®ç¹å®ãé¢é£ããGit Repositoryãä»ã«ãªããèª¿æ» Sentry APIã¯äºåã«Devin Secretã«Sentry API Tokenã远å ããŠããã®ã§ãããšSlackã®ã¡ãã»ãŒãžããSentry issue_idãååŸã㊠Retrieve an Issue ãš List an Issue's Events ãå®è¡ããŠissueã®è©³çްãååŸããŸãã Repositoryã®ç¹å®ã調æ»ã¯äºåã«Devin's Workspaceã«çŽä»ããŠããRepositoryãæ¢çŽ¢ããããã«ããŠããŸãã 2-2. åæ æ¬¡ã«ãããã®æ
å ±ãããšã«ãšã©ãŒã®åå ã®åæãè¡ãããŸãããããŸã§ã§Sentryã®è©³çްãšå¯Ÿè±¡ã®ã³ãŒãã®ç®æãã€ããŠããã®ã§ãããããšã«åæãè¡ãããŠããŸãã åæã®å
容ãšããŠã¯æçµçãªåºåã«å«ãŸããSentryãããšã«ããçºçé »åºŠãªã©ã®ãšã©ãŒã®åºæ¬æ
å ±ãé害ã¬ãã«ããšã©ãŒã®åå ããšã©ãŒã®åçŸæ¹æ³ã察å¿çã«ãªããŸãã 2-3. è¿œå æ
å ±ã®ååŸ 2-2ã®çµæãããšã«åå ãšãªãcommitã®ç¹å®ã gh ã³ãã³ãã䜿ã£ãŠååŸããŸãã 2-4. å³è¡šã®äœæ ãšã©ãŒã®çè§£ãæ·±ãããããMermaidã䜿çšããŠAWSã€ã³ãã©æ§æå³ãšã·ã¹ãã æŠèŠå³ãèªåçæããŸããããã«ããããšã©ãŒãçºçããŠããç®æãšã·ã¹ãã å
šäœã®é¢ä¿æ§ãèŠèŠçã«ææ¡ã§ããŸãã ã€ã³ãã©æ§æå³ïŒinfra.mmd â infra.pngïŒ : AWSãªãœãŒã¹éã®é¢ä¿æ§ãšããŒã¿ãããŒã衚瀺 ã·ã¹ãã æŠèŠå³ïŒsystem.mmd â system.pngïŒ : ã¢ããªã±ãŒã·ã§ã³å±€ãšã€ã³ãã©å±€ã®çžäºäœçšã衚瀺 3. Slackãžåºå 2ãŸã§ã®æ
å ±ãããšã«Playbookã«èšè¿°ãããŠããäžèšã®åœ¢ã§æ
å ±ãæŽçããã¹ã¬ããã«è¿ä¿¡ãè¡ã£ãŠããããŸãã ðãšã©ãŒã®åºæ¬æ
å ±ç¢ºèª ã»ãšã©ãŒã¿ã€ã ã»ç°å¢ ã»çºçé »åºŠ ã»åœ±é¿ç¯å² ã»çºçæé(yyyy-mm-dd HH:MM:SSã®åœ¢åŒãJST倿å¿
é ) ã»åå(yyyy-mm-dd HH:MM:SSã®åœ¢åŒãJST倿å¿
é ) ã»æçµ(yyyy-mm-dd HH:MM:SSã®åœ¢åŒãJST倿å¿
é ) ð§ââïž é害ã¬ãã«å€æ ã»ðšç·æ¥åºŠé«ïŒå³æå¯Ÿå¿å¿
èŠïŒãµãŒããŒããŠã³ãžã®åœ±é¿ãªã©ïŒ ã»ð¡ç·æ¥åºŠäžïŒãã±ããåã£ãŠä»é±äžã«å¯Ÿå¿ïŒç¹å®æ¡ä»¶äžã§ã®ãšã©ãŒããŠãŒã¶ãŒåœ±é¿ãªãïŒ ã»ðµç·æ¥åºŠäœïŒãã±ããåã£ãŠæéããæã«å¯Ÿå¿ïŒè»œåŸ®ãªäžå
·åãããã©ãŒãã³ã¹äœäžïŒ ð¬ ãšã©ãŒåå å€å® ã»ã·ã¹ãã åŽã®åé¡ïŒãã°ãèšå®ãã¹ããªãœãŒã¹äžè¶³ãªã©ïŒ ã»å€éšèŠå ïŒæ»æçãªã¯ãšã¹ããå€éšãµãŒãã¹é害ãªã©ïŒ ðŠ é¢é£ã®ããCommit,PR ã»æ ¹æ¬åå ãšãªãã³ãŒããã©ã®commit, PRã§è¿œå ã»å€æŽãããã®ã ð§âð» ãšã©ãŒã®åçŸæ¹æ³ ã»ããŒã«ã«ç°å¢ãéçºç°å¢ã§ãšã©ãŒã®åçŸæ¹æ³ã®æç€º ð 察å¿ççå® ã»äžæç察å¿ãšæä¹
ç察å¿ã®åºå¥ ã»æ»æçãªã¯ãšã¹ãã®å Žåã®ã»ãã¥ãªãã£å¯Ÿç çµæ éçšããŠã¿ãçµæ å®éã«éçšããŠã¿ãŠä»¥äžã®å¹æã確èªã§ããŸããã Sentryã¢ã©ãŒãã®äžæå¯Ÿå¿ã«ã€ããŠã¯Devinã«ä»»ããããããã«ãªã£ã ã¢ã©ãŒãçºçããçŽ3åã§åæèª¿æ»ãåå ç¹å®ãŸã§å®äºããããã«ãªã£ã ããã³ããšã³ãã»ããã¯ãšã³ãã»ã€ã³ãã©ã®åRepositoryãè·šãã 調æ»ãèªåã§å®è¡ããããããèª¿æ»æŒãããªããªã£ã Mermaidã§çæãããå³è¡šãåãããããããšã©ãŒç®æã®ææ¡ãå§åçã«æ¥œã«ãªã£ã å人çã«ã¯ãç¹ã«èª¿æ»ã®äžè²«æ§ãä¿ãããããã«ãªã£ãã®ãäžçªè¯ããã€ã³ãã ãšæããŠããŸãã人ã«ãã£ãŠèª¿æ»ã®æ·±ãã«ã°ãã€ãããã£ãã®ããDevinã䜿ãããšã§æ¯ååãã¬ãã«ã®èª¿æ»ãæ
ä¿ãããããã«ãªããŸããã ããã«ããã¢ã©ãŒã察å¿ã®ããŒãã«ãäžãã£ãã®ã§ãå±äººåãé²ããã®ã§ã¯ãªãããšèããŠããŸãã éçšããŠã¿ãŠèŠããŠããèª²é¡ äžæ¹ã§ãããã€ã課é¡ãèŠããŠããŸããã AWSã®ãã°ãã¢ãã¿ãªã³ã°æ
å ±ãšé£æºãã調æ»ã¯ãŸã ã§ããŠããªã GitHubã®ããŒããªã³ã¯åºåãé¢é£ãªããžããªã®ææ¡ã§ãçµæã«ã°ãã€ããåºãããšããã è€éãªæç€ºãäžåºŠã«åºããããæ®µéçã«æä»€ãåºããæ¹ã粟床ãäžããåŸåããã ç¹ã«3ã€ç®ã«ã€ããŠã¯ãæåã¯å
šéšãŸãšããŠæç€ºããŠããã®ã§ãããæ®µéçã«æç€ºãåºãããšã§æããã«çµæã®å質ãåäžããã®ã§ãéçšã®ã³ããšããŠèŠããŠãããããã€ã³ãã§ããã ãŸãšã ç§èªèº«ãæ®æ®µCursorãClaude Codeã䜿ãéã¯AIãšã®äŒè©±ãåŸåŸ©ããããšãåæã«éãªããã³ãããæãããããã®ã§ãèªç«ã§ããããã«ååãªããã³ãããäžããå¿
èŠãããç¹ã§èªç«åAIãšãŒãžã§ã³ãã®æ±ãã«èŠåŽããŸãããPlaybookã®ãããªãã³ãã¬ãŒãæ©èœãããã®ã§ãç¹°ãè¿ãã䌎ãã¿ã¹ã¯ã§ã¯å¹åãçºæ®ããããšã¯åããã€ã€ããæ®æ®µã®æ¥åã§äœ¿ãã€ã¡ãŒãžã¯å°ãããã«ããã£ãã§ãã ãã®ç¹ãã¢ã©ãŒã察å¿ã¯æ±ºãŸã£ãåããããããšãå€ãã®ã§ãä»åã®Playbookã«å ããŠã¢ã©ãŒã察å¿ãåŸæãªã¡ã³ããŒã®æ®æ®µã®åããå
±æããã ãããšã§ãããã«ç²ŸåºŠã®ãã察å¿ãã§ããã®ã§ã¯ãªãããšæããŸããã ãŸãããã®å®è£
ãè¡ã£ãåŸã« Devin MCP Marketplace ãå
¬éãããã®ã§ããããçšããŠããã«ã³ã³ããã¹ãéãå¢ããããšã§æ§èœãã©ããªããã¯ä»åŸè©ŠããŠã¿ããã§ãã ãããŸã§èªãã§ããã ãããããšãããããŸããDevinã§ã¢ã©ãŒãåå察å¿ãçéåããããšããŠããæ¹ã®åèã«ãªã£ãã幞ãã§ãã
ã¯ããã« ããã«ã¡ã¯ããã¢ããã§éçºãæ
åœããŠããåç°ã§ãã AWS ãæŽ»çšãããµãŒãã¹éå¶ã«ãããŠãIaCïŒInfrastructure as CodeïŒããŒã«ã®éžæã¯é·æçãªéçšå¹çã«åœ±é¿ããããšããããŸãã æ¬èšäºã§ã¯ãå®éã«ç§ãã¡ãçµéšãã Serverless Framework v3 ãã lambroll ãš Terraform ãžã®ç§»è¡äºäŸãããšã«ã ç§»è¡ã®èæ¯ããå
·äœçãªæé ããããŠç§»è¡ãéããŠåŸãããç¥èŠã«ã€ããŠãŸãšããŠããŸãã ãªããç§»è¡å
ã®åè£æ€èšãåããŒã«ã®æ¯èŒã«ã€ããŠã¯ã ååã®æ€èšŒç·šèšäº ã§è©³ãã解説ããŠããŸãã®ã§ã䜵ããŠãåç
§ãã ããã èæ¯ïŒServerless Framework ãåãå·»ãç°å¢å€å é©å㪠IaC ããŒã«ã®éžæã¯å€§åãªå€æã®äžã€ã§ãã代衚çãªããŒã«ãšããŠã¯ã Serverless Framework ã AWS SAM ã Terraform ãªã©ãæããããŸãããããã®ããŒã«ã¯ãããããç°ãªãç¹åŸŽãšå©ç¹ãæã¡ããããžã§ã¯ãã®èŠä»¶ã«å¿ããŠéžæããããšãå€ãã§ãã äžã§ããServerless Framework ã¯å€ãã®ãããžã§ã¯ãã§æ¡çšãããŠããæåãªéžæè¢ã®äžã€ã§ãããããã2024 幎㮠v4 ãªãªãŒã¹ã«äŒŽããã©ã€ã»ã³ã¹åœ¢æ
ã®å€§å¹
ãªå€æŽãçºçããŸãããïŒ åè ïŒ ããããèæ¯ãããç§ãã¡ã¯ä»£æ¿ææ®µã®æ€èšãéå§ããŸãããããããã¯ãå®éã«ç§ãã¡ãè¡ã£ãç§»è¡ãããžã§ã¯ãã®èšé²ãšãããããåŸãããæèšã«ã€ããŠç޹ä»ããŸãã ç§»è¡ã®èæ¯ Serverless Framework v4 ã®å€æŽç¹ 2024 幎ãServerless Framework v4 ããªãªãŒã¹ãããåŸæ¥ã®ãªãŒãã³ãœãŒã¹ã¢ãã«ããèµãåããŸããã ã©ã€ã»ã³ã¹åœ¢æ
ã®å€æŽ : äžå®ä»¥äžã®åçãäžããçµç¹ã§ã¯ææãµãã¹ã¯ãªãã·ã§ã³ãå¿
é v3 ã®ãµããŒãçµäº : 2024 幎æ«ãŸã§ã®å»¶é·ãµããŒãã®ã¿ã§ãæ©èœæ¹åã»ãã°ä¿®æ£ã¯çµäº ã©ã³ã¿ã€ã 察å¿ã®é
ã : ææ°ã® AWS Lambda ã©ã³ã¿ã€ã æŽæ°ãžã®è¿œéã忢 課é¡ã®æŽç ãããã®å€æŽã«ãããç§ãã¡ã¯ä»¥äžã®èª²é¡ãæããŸããã ç¶ç¶çãªã©ã€ã»ã³ã¹è²»çšã®çºç å°æ¥çãªã©ã³ã¿ã€ã ãµããŒãåãã®ãªã¹ã¯ v3âv4 ç§»è¡ã«äŒŽãéçšãããŒå€æŽã®è² è· ç§»è¡å
ã®æ¡çš æ€èšŒç·šèšäº ã§è€æ°ã®ç§»è¡å
åè£ïŒPulumiãAWS CDKãAWS SAMãlambroll + TerraformãTerraform + AWS CLIïŒãæ¯èŒæ€èšããçµæãåŠç¿ã³ã¹ãã瀟å
ã§ã®éçšå®çžŸãèæ
®ãããlambroll + Terraformãã®çµã¿åãããæ¡çšããããšã«ããŸããã ãã®éžæã«ããã以äžã®ã¡ãªãããæåŸ
ããŸããã ã©ã€ã»ã³ã¹è²»çšã®åé¿ IaC ããŒã«ã®çµ±äžã«ããéçšå¹çåäž AWS ã®ãã€ãã£ãæ©èœãžã®å®å
šå¯Ÿå¿ ãã现ããç²åºŠã§ã®ãªãœãŒã¹ç®¡ç ç§»è¡ã¢ãããŒã ä»åç§»è¡ããã®ã¯ãCodeBuild ã®å®è¡çµæã Slack ã«éç¥ãã Lambda 颿°ãšãã®åšèŸºãªãœãŒã¹ïŒEventBridgeãIAM ããŒã«ïŒã§ãã æ³šæ ïŒãã®éç¥æ©èœã¯äžæçã«åæ¢ããŠãæ¥åã«é倧ãªåœ±é¿ããªããããç§»è¡äžã®ãµãŒãã¹åæ¢ã蚱容ããåæã§æé ãèšèšããŠããŸããæ¬çªç°å¢ã®éèŠãªãµãŒãã¹ãç§»è¡ããå Žåã¯ãç¡åæ¢ã§ã®ç§»è¡æé ãæ€èšããããšããå§ãããŸãã ç§»è¡æŠç¥ å®å
šæ§ãéèŠãã以äžã®æ®µéçã¢ãããŒããæ¡çšããŸããã ç§»è¡åã®æºåãšèª¿æ» lambroll ã«ãã Lambda 颿°ã®å
è¡ç§»è¡ Terraform ã«ããåšèŸºãªãœãŒã¹ã®æ®µéçç§»è¡ çµ±åãã¹ããšåäœç¢ºèª Serverless Framework ã¹ã¿ãã¯ã®åé€ å®è·µçãªç§»è¡æé Step 1: ç§»è¡åã®æºåãšèª¿æ» ç§»è¡ãå®å
šã«é²ããããããŸãã¯çŸç¶ææ¡ãšããã¯ã¢ããååŸããå§ããŸãã # CloudFormation ã¹ã¿ãã¯ã®è©³çްååŸ aws cloudformation describe-stacks \ --stack-name your-service-stack # Lambda 颿°ã®ããã¯ã¢ãã aws lambda get-function \ --function-name your-function-name \ > function-backup.json # CloudFormation ã®ããã¯ã¢ãã aws cloudformation get-template \ --stack-name your-service-stack \ > backup-cfn.json Step 2: lambroll ã«ãã Lambda 颿°ã®ç§»è¡ lambroll ã®åæå # æ¢åã® Lambda 颿°ãã lambroll èšå®ãçæ lambroll init --download \ --function-name your-function-name ãã®ã³ãã³ãã«ããã以äžã®ãã¡ã€ã«ãèªåçæãããŸãã function.json : Lambda 颿°ã®èšå® .lambdaignore : ãããã€æã«é€å€ãããã¡ã€ã«ã®å®çŸ© function.zip : çŸåšã®é¢æ°ã³ãŒã function.json ã®èª¿æŽ çæããã function.json ãç°å¢å€æ°ãã¿ã€ã ã¢ãŠãèšå®ã«åãããŠèª¿æŽã { " FunctionName ": " your-function-name ", " Runtime ": " nodejs22.x ", " Timeout ": 30 , " MemorySize ": 128 , " Role ": " arn:aws:iam::{{ env `AWS_ACCOUNT_ID` }}:role/<IAM ããŒã«å> ", " Environment ": { " Variables ": { " SLACK_WEBHOOK_URL ": " {{ env `SLACK_WEBHOOK_URL` }} " } } } ç°å¢å€æ°ãã¡ã€ã«ã®äœæ # development.env SLACK_WEBHOOK_URL =https://hooks.slack.com/services/YOUR/WEBHOOK/URL AWS_ACCOUNT_ID = 123456789012 ãããã€ãšãã¹ã # äºåç¢ºèª lambroll deploy --dry-run --envfile =< ãããã€å
ã®ç°å¢ > .env # å®éã®ããã〠lambroll deploy --envfile =< ãããã€å
ã®ç°å¢ > .env # åäœç¢ºèª lambroll invoke \ --payload =' {"detail":{"build-status":"FAILED"}} ' \ --envfile =< ãããã€å
ã®ç°å¢ > .env Step 3: Terraform ã«ããåšèŸºãªãœãŒã¹ã®ç§»è¡ æ¢åãªãœãŒã¹ã®è©³çŽ°èª¿æ» Terraform import ãé²ããããã«ãæ¢åãªãœãŒã¹ã®æ£ç¢ºãªèå¥åãåéã # EventBridge ã«ãŒã«ã®è©³çް aws events list-rules --name-prefix " your-service " # Lambda ããŒããã·ã§ã³ã®ç¢ºèª aws lambda get-policy --function-name your-function-name # EventBridge ã¿ãŒã²ããã®ç¢ºèª aws events list-targets-by-rule --rule your-rule-name # IAM ããŒã«ã®è©³çް aws iam get-role --role-name your-lambda-role Terraform èšå®ã®äœæ # Lambda ãã°æš©éããªã·ãŒ data "aws_iam_policy_document" "lambda_logging" { statement { effect = "Allow" actions = [ "logs:CreateLogStream" , "logs:CreateLogGroup" , "logs:TagResource" ] resources = [ "<Lambdaã®ãã°ã°ã«ãŒãARN>" ] } statement { effect = "Allow" actions = [ "logs:PutLogEvents" ] resources = [ "<Lambdaãã°ã¹ããªãŒã ARN>" ] } } # Lambda ãã°ããªã·ãŒäœæ module "lambda_logging" { source = "terraform-aws-modules/iam/aws//modules/iam-policy" version = "5.59.0" name = "lambda_logging_policy" policy = data.aws_iam_policy_document.lambda_logging.json } # Lambda å®è¡ããŒã«äœæ module "lambda_logging_role" { source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role" version = "5.59.0" create_role = true role_name = "lambda_logging_role" role_requires_mfa = false trusted_role_services = [ "lambda.amazonaws.com" ] custom_role_policy_arns = [ module.lambda_logging.arn ] } # EventBridge ã«ãŒã« resource "aws_cloudwatch_event_rule" "codebuild_notification" { name = "codebuild-notification-rule" description = "CodeBuild status change notification" event_pattern = jsonencode ( { source = [ "aws.codebuild" ] detail-type = [ "CodeBuild Build State Change" ] detail = { build-status = [ "FAILED" , "SUCCEEDED" ] } } ) } # EventBridge ã¿ãŒã²ãã resource "aws_cloudwatch_event_target" "lambda" { rule = aws_cloudwatch_event_rule.codebuild_notification.name target_id = "notificationLambdaTarget" arn = data.aws_lambda_function.notification.arn } # Lambda ããŒããã·ã§ã³ resource "aws_lambda_permission" "allow_eventbridge" { statement_id = "AllowExecutionFromEventBridge" action = "lambda:InvokeFunction" function_name = data.aws_lambda_function.notification.function_name principal = "events.amazonaws.com" source_arn = aws_cloudwatch_event_rule.codebuild_notification.arn } æ¢åãªãœãŒã¹ã® import # EventBridge ã«ãŒã« terraform import aws_cloudwatch_event_rule.codebuild_notification \ < EventBridgeã«ãŒã«å > # EventBridge ã¿ãŒã²ãã terraform import aws_cloudwatch_event_target.lambda \ < EventBridgeã«ãŒã«ã®å®éã®åå > / < ã¿ãŒã²ããID > # Lambda ããŒããã·ã§ã³ terraform import aws_lambda_permission.allow_eventbridge \ < Lambda颿°å > / < LambdaããŒããã·ã§ã³ã®StatementId > # IAM ããŒã« terraform import module.lambda_logging_role.aws_iam_role.this \ < IAM ããŒã«å > ãã€ã³ã : CloudFormation ã§çæããããªãœãŒã¹åã¯äºæž¬ãã«ãããããAWS CLI ã§æ£ç¢ºãªååã確èªããŠãã import ããå¿
èŠããããŸãããŸããimport å®äºåŸã¯å¿
ã terraform plan ã§ããªããããªãããšã確èªããŸãããã æ®µéçãªé©çš # IAM ããŒã«ã®ã¿å
è¡é©çš terraform apply --target = aws_iam_role.lambda_role # Lambda 颿°ã®åãããã€ïŒæ°ãã IAM ããŒã«ã䜿çšïŒ lambroll deploy --envfile =< ãããã€å
ã®ç°å¢ > .env # æ®ãã®ãªãœãŒã¹ãé©çš terraform apply IAM ããŒã«ãå
è¡é©çšããçç±ã¯ãlambroll ã Lambda 颿°ããããã€ããéã«å®è¡ããŒã«ãå¿
èŠã ããã§ããããŒã«ãååšããªãç¶æ
ã§ lambroll deploy ãå®è¡ãããšãšã©ãŒã«ãªã£ãŠããŸãããããŸã Terraform ã§ IAM ããŒã«ãäœæããŠãã Lambda 颿°ã®ãããã€ãè¡ããŸãã Step 4: Serverless Framework ããã®åé¢ serverless.yml ããã® Lambda 颿°åé€ # functions ã»ã¯ã·ã§ã³ãã³ã¡ã³ãã¢ãŠã # functions: # notification: # handler: handler.notifier # events: # - cloudwatchEvent: # event: # source: # - aws.codebuild 圱é¿ç¯å²ã®ç¢ºèªãšé©çš # 倿Žã®åœ±é¿ãç¢ºèª sls package # Lambda 颿°ãšé¢é£ãªãœãŒã¹ã Serverless 管çããåé€ sls deploy # Serverless Framework ã«ããåé€ã§ãªãœãŒã¹ãæ¶ããããã # Terraform ãš lambroll ã§åäœæ terraform apply lambroll deploy --envfile =< ãããã€å
ã®ç°å¢ > .env Step 5: çµ±åãã¹ããšæçµç¢ºèª ãšã³ãããŒãšã³ããã¹ã # EventBridge çµç±ã§ã®ãã¹ã aws events put-events --entries file://test-event.json # ãã°ã®ç¢ºèª aws logs get-log-events \ --log-group-name /aws/lambda/your-function-name Serverless ã¹ã¿ãã¯ã®åé€ # æ®åãªãœãŒã¹ã®ç¢ºèª aws cloudformation describe-stack-resources \ --stack-name your-service-stack # ã¹ã¿ãã¯ã®åé€ sls remove lambroll vs Serverless Framework: éçšé¢ã§ã®éã ç§»è¡ãéããŠå®æãã倧ããªéãã¯ããããã€ã®ä»çµã¿ãšéçšç¹æ§ã§ããã é
ç® Serverless Framework lambroll ãããã€æ¹åŒ CloudFormation ã¹ã¿ãã¯æŽæ° Lambda API çŽæ¥åŒã³åºã 察象ç¯å² Lambda + å
šé¢é£ãªãœãŒã¹ Lambda 颿°ã®ã¿ ãããã€é床 CloudFormation ã®åŠçæéã«äŸå Lambda API ã®å¿çæé lambroll 㯠Lambda API ãçŽæ¥åŒã³åºããããã³ãŒãã®å€æŽãçŽ æ©ãåæ ã§ããŸããéçºæã®å埩ãµã€ã¯ã«ãæ¹åãããŸããã åŸãããç¥èŠãšãã¹ããã©ã¯ãã£ã¹ 1. 段éçç§»è¡ã«ã€ã㊠äžåºŠã«ãã¹ãŠãç§»è¡ããã®ã§ã¯ãªããLambda 颿°ãå
è¡ç§»è¡ããããšã§ããªã¹ã¯ãæããããšãã§ããŸãããããã«ãããåé¡ãçºçããå Žåã®åœ±é¿ç¯å²ãéå®ãããããªããŸãã 2. CloudFormation ã§çæããããªãœãŒã¹åã®ææ¡ Serverless Framework ãèªåçæãããªãœãŒã¹åã¯äºæž¬ãã«ããã§ããç§»è¡åã« AWS CLI ã䜿ã£ãŠæ£ç¢ºãªååã調æ»ããããšã§ãimport äœæ¥ãã¹ã ãŒãºã«é²ã¿ããããªããŸãã 3. ç°å¢å€æ°ç®¡çã®çµ±äž lambroll ãš Terraform ã§ç°å¢å€æ°ã®ç®¡çæ¹æ³ãçµ±äžããããšã§ãèšå®ãã¹ãé²ãããããªããŸãã.env ãã¡ã€ã«ã掻çšããçµ±äžçãªç®¡çããå§ãããŸãã 4. ããã¯ã¢ãããšããŒã«ããã¯æŠç¥ ç§»è¡äœæ¥ã§ã¯ãåæ®µéã§ã®ããã¯ã¢ãããšãåé¡çºçæã®ããŒã«ããã¯æé ãäºåã«å®çŸ©ããŠããããšã倧åã§ãã 5. ãµãŒãã¹åæ¢ã®èš±å®¹ç¯å²ã®äºåç¢ºèª ä»åã®ç§»è¡ã§ã¯éç¥æ©èœãšããæ§è³ªäžãäžæçãªãµãŒãã¹åæ¢ã蚱容ã§ããŸãããããããæ¬çªç°å¢ã®éèŠãªãµãŒãã¹ã§ã¯ç¡åæ¢ç§»è¡ãå¿
èŠãªå ŽåããããŸããç§»è¡å¯Ÿè±¡ã®éèŠåºŠãšãµãŒãã¹åæ¢ã®åœ±é¿ç¯å²ãäºåã«è©äŸ¡ããé©åãªç§»è¡æŠç¥ãéžæããããšãéèŠã§ãã ãŸãšã ä»åã®ç§»è¡ãããžã§ã¯ããéããŠãããŒã«éžæã«ãããé·æçãªèŠç¹ã®å€§åããæ¹ããŠèªèããŸããã ãŸããç§»è¡äœæ¥ã®äžã§æ®µéçãªã¢ãããŒããããªã¹ã¯ãæããªããçå®ã«ææãåŸãéµã§ããããšã宿ããŸããã æ€èšŒç·šèšäº ã§ã®äºå調æ»ããå®éã®ç§»è¡äœæ¥ãŸã§ãäžé£ã®åãçµã¿ãéããŠãäºå調æ»ã§æ³å®ããŠããã¡ãªããïŒãããã€éåºŠã®æ¹åãIaC ããŒã«ã®çµ±äžãã©ã€ã»ã³ã¹è²»çšã®åé¿ïŒãå®çŸã§ããŠããŸãã ä»åŸã¯ããã®ç§»è¡ã§åŸãããç¥èŠã掻ãããä»ã®ãããžã§ã¯ãã§ãåæ§ã®ã¢ãããŒããé©çšããŠããäºå®ã§ãã IaC ããŒã«ã®éžæã¯äžåºŠæ±ºããã°çµããã§ã¯ãªããæè¡ç°å¢ã®å€åã«å¿ããŠç¶ç¶çã«èŠçŽããè¡ãããšãéèŠã§ããä»åŸãæé©ãªããŒã«éžæãšéçšå¹çã®åäžã«åãçµãã§ãããŸãã åæ§ã®ç§»è¡ãæ€èšãããŠããæ¹ã®åèã«ãªãã°å¹žãã§ãããŸãã¯å°ããªãããžã§ã¯ãããæ®µéçã«è©ŠããŠã¿ãããšããå§ãããŸãã
ã¯ããã« ããã«ã¡ã¯ãããªãã·ã¥ãããã³ã§ããŒã¿ãµã€ãšã³ãã£ã¹ããããŠãã倿¿µã§ãã ä»åã¯ããããªå
容ã§ãããã¿ã€ãã«éãã®åé¡ãçºçããããããã®å¯ŸåŠæ³ã«ã€ããŠåå¿é²çã«ãŸãšããŸãã åäœç°å¢ã¯ä»¥äžã«ãªããŸãã Databricks Runtime: 15.4LTS for ML Python: 3.11.11 ã©ã€ãã©ãªã¯Databricks Runtimeã®ããŒãžã§ã³ãã以äžã«ã¢ããã°ã¬ãŒãããŠããŸã openai==1.65.2 mlflow==2.20.3 pydantic==2.10.6 databricks-agents==0.16.0 databricks-sdk==0.50.0 MLflow Tracingã«é¢ããããã¥ã¡ã³ãã¯ä»¥äžã«ãªããŸãã mlflow.org åé¡ æºå ãŸããå
·äœçã«ã©ããªåé¡ãçºçãããã説æããããã«ã以äžã®ãããªã³ãŒããçšæããŸãã ããããããšãšããŠã¯ããŠãŒã¶ãŒã®ã¯ãšãªãããã£ã«ã¿ãªã³ã°æ¡ä»¶ãæœåºããã¿ã¹ã¯ãLLMã«ãããŸãã ããã¯ ä»¥åæžããããã¯ããã°ã§ã®ãã£ã«ã¿ãªã³ã°åŠç ãããŒã¹ãšããŠããŸãã ä»åã¯ã調çæéãšèª¿çè²»çšã®ã¿ããã£ã«ã¿ãªã³ã°æ¡ä»¶ãšããŠæœåºããã¿ã¹ã¯ãšããŸãã import mlflow from enum import Enum from pydantic import BaseModel import os os.environ[ "OPENAI_API_KEY" ] = dbutils.secrets.get(...) # your scope and key # mlflow.traceãèªåã§å¯Ÿå¿ããããopenaiã®autologãç¡å¹ã«ãã mlflow.openai.autolog(disable= True ) # 調çæéã®ãã£ã«ã¿ãªã³ã°æ¡ä»¶ class CookingTimeColumn ( str , Enum): cooking_time = "cooking_time_min" class CookingTimeOperator ( str , Enum): greater_than = ">" less_than = "<" greater_than_or_equal_to = ">=" less_than_or_equal_to = "<=" class CookingTimeFilter (BaseModel): column: CookingTimeColumn operator: CookingTimeOperator value: float class CookingTimeFilters (BaseModel): cooking_time_filters: list [CookingTimeFilter] # 調çè²»çšã®ãã£ã«ã¿ãªã³ã°æ¡ä»¶ class CookingCostColumn ( str , Enum): cooking_cost = "cooking_cost_yen" class CookingCostOperator ( str , Enum): greater_than = ">" less_than = "<" greater_than_or_equal_to = ">=" less_than_or_equal_to = "<=" class CookingCostFilter (BaseModel): column: CookingCostColumn operator: CookingCostOperator value: float class CookingCostFilters (BaseModel): cooking_cost_filters: list [CookingCostFilter] ãŠãŒã¶ãŒã®å
¥åã¯ãšãªã¯ä»¥äžãäŸãšããŠäœ¿çšããŸãã user_query = "10å以å
ã«500åæªæºã§äœããå¯èæããŠ" MLflow Tracingã䜿çšãã颿°ãå®çŸ© MLflow Tracingã¯ã颿°ã«å¯Ÿã㊠@mlflow.trace ãã³ã¬ãŒã¿ãä»äžããããšã§ã颿°å
ã®åŠçãç°¡åã«Tracingããããšãã§ããŸãã ãã®ãããªé¢æ°ã以äžã«3ã€å®çŸ©ããŸããã create_metadata_filter_from_user_query()ãããcreate_cooking_time_filter()ãšcreate_cooking_cost_filter()ãåŒã³åºããŸãã from openai import OpenAI from mlflow.entities import SpanType @ mlflow.trace (span_type=SpanType.LLM) def create_cooking_time_filter (user_query: str ) -> list [CookingTimeFilters | CookingCostFilters]: client = OpenAI() system_prompt = f """ ããªãã¯æçã®ç¥èãè±å¯ãªã¬ã·ãæ€çŽ¢AIã§ãã ãŠãŒã¶ãŒãã¬ã·ãæ€çŽ¢ã®ããã«å
¥åããã¯ãšãªãè§£èªãããŠãŒã¶ã**調çæé**ã§ãã£ã«ã¿ãªã³ã°ããŠæ€çŽ¢ãããå Žåã¯ããã£ã«ã¿ãªã³ã°æ¡ä»¶ãè¿ããŠãã ããã ## åºååœ¢åŒ * json圢åŒã§åºåããŠãã ãã * columnã«ã«ã©ã åãoperatorã«äžçå·ãvalueã«ãã£ã«ã¿ãªã³ã°å¯Ÿè±¡ãå
¥ããŠãã ãã """ completion = client.beta.chat.completions.parse( model = "gpt-4o-mini" , messages = [ { "role" : "system" , "content" : system_prompt}, { "role" : "user" , "content" : user_query}, ], response_format = CookingTimeFilters, ) structured_outputs = completion.choices[ 0 ].message.content filters = CookingTimeFilters.model_validate_json(structured_outputs).cooking_time_filters return filters @ mlflow.trace (span_type=SpanType.LLM) def create_cooking_cost_filter (user_query: str ) -> list [CookingTimeFilters | CookingCostFilters]: client = OpenAI() system_prompt = f """ ããªãã¯æçã®ç¥èãè±å¯ãªã¬ã·ãæ€çŽ¢AIã§ãã ãŠãŒã¶ãŒãã¬ã·ãæ€çŽ¢ã®ããã«å
¥åããã¯ãšãªãè§£èªãããŠãŒã¶ã**調çè²»çš**ã§ãã£ã«ã¿ãªã³ã°ããŠæ€çŽ¢ãããå Žåã¯ããã£ã«ã¿ãªã³ã°æ¡ä»¶ãè¿ããŠãã ããã ## åºååœ¢åŒ * json圢åŒã§åºåããŠãã ãã * columnã«ã«ã©ã åãoperatorã«äžçå·ãvalueã«ãã£ã«ã¿ãªã³ã°å¯Ÿè±¡ãå
¥ããŠãã ãã """ completion = client.beta.chat.completions.parse( model = "gpt-4o-mini" , messages = [ { "role" : "system" , "content" : system_prompt}, { "role" : "user" , "content" : user_query}, ], response_format = CookingCostFilters, ) structured_outputs = completion.choices[ 0 ].message.content filters = CookingCostFilters.model_validate_json(structured_outputs).cooking_cost_filters return filters @ mlflow.trace (span_type=SpanType.CHAIN) def create_metadata_filter_from_user_query (user_query: str ) -> list [CookingTimeFilters | CookingCostFilters]: filter_functions = [ create_cooking_time_filter, create_cooking_cost_filter, ] metadata_filters = [] for func in filter_functions: filters = func(user_query) metadata_filters.extend(filters) return metadata_filters å®è¡çµæ - create_metadata_filter_from_user_query - create_cooking_time_filter - create_cooking_cost_filter ã®ãããªæ§é ã«ãªã£ãŠãããcooking_timeãšcooking_costã®ãã£ã«ã¿ãªã³ã°æ¡ä»¶ããããã1ç§ã»ã©ïŒåèšçŽ2ç§ïŒã§æœåºã§ããŠããããšãããããŸãã ãã ãããã§ã¯çŽåã«åŠçããŠããããããã£ã«ã¿ãªã³ã°æ¡ä»¶ãå¢ããã°å¢ããã»ã©åŠçæéãé·ããªã£ãŠããŸããŸãã LLMã®åŠçæéãé·ãã®ã¯APIã®åŸ
æ©æéãåå ã®ãããããã䞊è¡åŠçã«ããããšã§åŠçæéãççž®ããããšãã§ããŸãã 䞊è¡åŠçå
ã§MLflow Tracingãäœ¿çš äžŠè¡åŠçãè¡ãããã«ã concurrent.futures.ThreadPoolExecutor ã䜿çšããŸããã create_metadata_filter_from_user_query()å
ã®åŠçã以äžã®ããã«å€æŽããŸãã from concurrent.futures import ThreadPoolExecutor @ mlflow.trace (span_type=SpanType.CHAIN) def create_metadata_filter_from_user_query (user_query: str ) -> list [CookingTimeFilters | CookingCostFilters]: filter_functions = [ create_cooking_time_filter, create_cooking_cost_filter, ] metadata_filters = [] # å颿°ã䞊è¡åŠçã§å®è¡ããããä¿®æ£ with ThreadPoolExecutor() as executor: futures = [executor.submit(func, user_query) for func in filter_functions] for future in futures: filters = future.result() metadata_filters.extend(filters) return metadata_filters å®è¡çµæ å³äžã®èµ€æ ã瀺ãéãã1ã2ã3ãšã¿ããã§ããŠãããããããã®Tracingã颿°åäœã«ãªã£ãŠããŸãã å眮ããé·ããªããŸãããããã®åé¡ã«å¯ŸåŠããŸãã å¯ŸåŠ ãã®åé¡ã¯ãOpenTelemetryã䜿ã£ãŠã芪ã®Tracingã®Contextãåã«æž¡ãããšã§è§£æ±ºã§ããŸããã OpenTelemetryã¯ãªãã¶ãŒãããªãã£çšéã§äœ¿çšãããOSSã§ãã MLflow Tracingã¯å
éšçã«ã¯OpenTelemetryã䜿çšããŠãããOpenTelemetryã®Contextã䜿ãããšã§ã芪ã®Tracingãåã«æž¡ãããšãã§ããŸãã 以äžã®ããã«ãåŒã³åºãå
ã®create_metadata_filter_from_user_query()å
ã®Contextã芪ã®TracingãšããŠãåã®é¢æ°ã«æž¡ããŸãã æ¬¡ã«ãåã®é¢æ°ã®åŠçã§ã¯Contextã®attachãããããšã§èŠªãšåãé¢é£ä»ããããšãã§ããŸããïŒã¯ãªãŒã³ã¢ããããããã«detachãããŠããŸãïŒã from opentelemetry import context from opentelemetry.context import Context def create_filter_with_trace_parent_context (user_query: str , func: callable , trace_parent_context: Context) -> list [CookingTimeFilters | CookingCostFilters]: context_token = context.attach(trace_parent_context) filters = func(user_query) context.detach(context_token) return filters @ mlflow.trace (span_type=SpanType.CHAIN) def create_metadata_filter_from_user_query (user_query: str ) -> list [CookingTimeFilters | CookingCostFilters]: filter_functions = [ create_cooking_time_filter, create_cooking_cost_filter, ] metadata_filters = [] parent_context = context.get_current() # å颿°ã䞊è¡åŠçã§å®è¡ããããä¿®æ£ with ThreadPoolExecutor() as executor: # create_filter_with_trace_parent_context()ã§å颿°ãåŒã³åºãããä¿®æ£ futures = [executor.submit(create_filter_with_trace_parent_context, user_query, func, parent_context) for func in filter_functions] for future in futures: filters = future.result() metadata_filters.extend(filters) return metadata_filters å®è¡çµæ MLflow Tracingãåãããã«1ã€ã®ã¿ãã®äžã«ãŸãšãŸã£ãŠããããšãããããŸãã ãŸããå
šäœã®åŠçæéãšããŠçŽ1.3ç§ã§çµããŠãããçŽåã«LLMãåŒã³åºããšãã«æ¯ã¹ãŠé«éåã§ããŠããããšããããããšæããŸãã ãããã« MLflow Tracingã䜿çšããéã«äžŠè¡åŠçã§TracingãåãããŠããŸãåé¡ãšããã®å¯ŸåŠæ³ã«ã€ããŠç޹ä»ããŸããã OpenTelemetryã®Contextã䜿çšããããšã§ã芪åé¢ä¿ãä¿ã£ããŸãŸã®Tracingãå¯èœã«ãªãã䞊è¡åŠçã«ããé«éåãšãã¬ãŒãµããªãã£ã®äž¡æ¹ãå®çŸã§ããŸããã åæ§ã®åé¡ã«ééããæ¹ã®åèã«ãªãã°å¹žãã§ãã ãªããLangGraphïŒãšLangChainïŒã䜿ãã°äžŠè¡åŠçããããšããŠããMLflow Tracingãåãããåé¡ã¯çºçããŸããã§ããã ä»åã®å¯ŸåŠæ³ã¯ãããŸã§å¿æ¥åŠçœ®çãªåŽé¢ãããããšã¯è£è¶³ããŠãããŸãã ãŸãã䞊è¡åŠçå
ã§ããã«äžŠè¡åŠçããããªã©åŠçãè€éåããå Žåãã¯ãŒã¯ãããŒã®ã©ã®é¢æ°ã䞊è¡ã«åŠçãããŠããã®ããããã«ãããªãããšæããŸãã ããããæå³ã§ããèŠä»¶ã«åãããŠåŠçãè€éåããŠããã«ã€ããLangGraphãªã©ã®ãã¬ãŒã ã¯ãŒã¯ã䜿çšããæ¹ãå¯èªæ§ãä¿å®æ§ã®èгç¹ã§æå¹ã ãšèããããŸãã
ã¯ããã« ããã«ã¡ã¯ããªããŒã«ããéçºéšã§ããã¯ãšã³ããšã³ãžãã¢ãããŠãããã·ãšèšããŸãã çŸåšãå°å£²ã¢ããªã®éçºã§Laravel11ãå©çšããŠãµãŒãã¹éçºãè¡ã£ãŠããŸãã ä»åã¯ãµãŒãã¹æäŸãããäžã§ã»ãã¥ãªãã£å¯ŸçãšããŠAWSã®WAFãå°å
¥ããããšã«ãªã£ãã話ãããããšæããŸãã AWS WAFïŒWeb Application FirewallïŒã¯ãWebã¢ããªã±ãŒã·ã§ã³ãå®ãããã®åŒ·åãªãµãŒãã¹ã§ãã ä»åãç§ã¯åããŠTerraformã䜿ã£ãŠWAFãèšå®ããALBãCloudFrontãšé£æºãããŸããã ãŸãã¯ChatGPTãCursorãªã©ã掻çšããŠãèšå®ãTerraformã³ãŒãã®äœæèªäœã¯éåžžã«ã¹ã ãŒãºã«é²ããããšãã§ããŸããããå®éã«éçšãèãããšã äºåã«ç¥ã£ãŠããã¹ãéèŠãªä»æ§ãå¶é ããããã€ãçµéšããããšã«ãªããŸããã ãã®èšäºã§ã¯ãåããŠWAFãå°å
¥ããæ¹ã«åããŠã Terraformãšçµã¿åãããWAFèšå®ã§æ³šæãã¹ããã€ã³ã ãäžå¿ã«ã玹ä»ããŸãã ç¹ã«ã HTMLãæçš¿ããFroala Editorã®ãããªããŒã«ã䜿ã£ãŠããå Žåã«åœ±é¿ãåããããå
容 ãäžç·ã«ã話ã§ããããšæããŸãã WAFãTerraformã§æ§ç¯ããŠèŠããŠãããäºåã«ç¥ã£ãŠããã¹ã3ã€ã®ãã€ã³ãã TerraformãšWAFãçµã¿åãããŠæ§ç¯ããŠã¿ããšããç¥ããªããšããããã調æ»ãå¿
èŠã«ãªãããã€ã³ãããããŸãããããã§ã¯ãã®äžã§ãç¹ã«å°è±¡çã ã£ã3ã€ã玹ä»ããŸãã ãã€ã³ã1ïŒWAFã®ãã°ã°ã«ãŒãåã«ã¯ãåœåã«ãŒã«ãããã WAFã®ãã°ãCloudWatch Logsã«åºåããéããã°ã°ã«ãŒãåã«ã¯ ç¹å®ã®åœåã«ãŒã« ããããŸãã æ£ããåœåïŒ aws-waf-logs- ã§å§ãŸãå¿
èŠãã ã«ãŒã«ã«åŸããªããšïŒ Terraformå®è¡æã«ãšã©ãŒã«ãªãïŒãã åå ãåããã¥ãã ïŒ äŸïŒTerraformã§ã®ãã°èšå®ã³ãŒã resource "aws_cloudwatch_log_group" "waf_logs" { name = "aws-waf-logs-my-web-acl" # â ãã®prefixãå¿
é ïŒ } resource "aws_wafv2_web_acl_logging_configuration" "example" { log_destination_configs = [aws_cloudwatch_log_group.waf_logs.arn] resource_arn = aws_wafv2_web_acl.main.arn } è£è¶³ïŒ Terraformã§ã®ãšã©ãŒå
容ã¯ãARNãç¡å¹ãããªãœãŒã¹ãèŠã€ãããªãããªã©ãšè¡šç€ºãããå Žåãå€ãã åœåã«ãŒã«ã®åé¡ã«ãã©ãçãã®ã«æéãããããŸãã ã ããã¥ã¡ã³ãçãèªãã°é£ããããšã§ã¯ãªãã®ã§ãããç§ã¯ååã¯èªç±ã«æ±ºãããããšæã蟌ãã§ããéšåããããäœèšã«ã¯ãŸã£ãŠããŸã£ããã€ã³ãã«ãªããŸãã Error: creating WAFv2 Logging Configuration: WAFInvalidParameterException: The resource ARN 'arn:aws:logs:ap-northeast-1:123456789012:log-group:invalid-name' is invalid or does not exist. ãã€ã³ã2ïŒCloudFrontãšWAFã®çŽä»ãè§£é€ã«ã¯å°ãç¹å¥ãªæé ãå¿
èŠ ALBãšéãã CloudFrontã«WAFãçŽä»ããããšã«Terraformã§è§£é€ããã«ã¯æ³šæãå¿
èŠ ã§ãã éåžžã® terraform apply ã§ã¯è§£é€ã§ããã æç€ºçãªæäœãå¿
èŠ ã«ãªããŸãã è§£æ±ºæ¹æ³ã¯2〠æåã§Webã³ã³ãœãŒã«ããWAFã®çŽä»ããè§£é€ãã Terraformã§ web_acl_id = null ãæå®ããŠãapplyããè¡ãæç€ºçã«è§£é€ãã äžèšã©ã¡ãããè¡ã£ãäžã§ããã°ãALBåæ§Terraformã®ã³ãŒããåé€ããã ãã§ç°¡åã«WAFèšå®ã®åé€ãã§ããŸãã TerraformäŸïŒ resource "aws_cloudfront_distribution" "example" { # ä»ã®èšå®... web_acl_id = null # â æç€ºçã«è§£é€ããªããšãšã©ãŒã«ãªã } 泚æïŒ WAFãè§£é€ããã«åé€ããããšãããšãããªãœãŒã¹ããŸã é¢é£ä»ããããŠããããšããŠãšã©ãŒã«ãªããŸãã ãªãALBã§ã¯ããŸãããã®ã«CloudFrontã ãšãšã©ãŒãªã®ãã仿§ãšããŠèªèã§ããŠããããã¯ãŸã£ãŠããŸã£ããã€ã³ãã«ãªããŸãã CloudFrontã¯ãªãŒãžã§ã³ããus-east-1ãã«åºå®ãããŠããç¹ãå«ããŠã ALBãšæåãç°ãªã ãããWAFèšå®æã¯è¿œå èæ
®ãããèªèãå¿
èŠã§ãã ãã€ã³ã3ïŒFroala Editor à AWSãããŒãžãã«ãŒã«ã§æ³å®å€ã®ãããã¯ãçºç ä»åã¯AWSã®ãããŒãžãã«ãŒã« AWSManagedRulesCommonRuleSet ãå°å
¥ããŸããã ããã¯å®çªã®æ±çšã«ãŒã«ã»ããã§ã以äžã®ããã«ç°¡åã«Terraformããå©çšã§ããŸãã å°å
¥ã³ãŒãïŒTerraformïŒ rule { name = "AWS-AWSManagedRulesCommonRuleSet" priority = 0 override_action { none {} # åäœç¢ºèªæã¯blockã§è¯ããã圱é¿èª¿æ»ã®ããcountã«ããã®ããªã¹ã¹ã¡ } statement { managed_rule_group_statement { name = "AWSManagedRulesCommonRuleSet" vendor_name = "AWS" } } visibility_config { cloudwatch_metrics_enabled = true sampled_requests_enabled = true metric_name = "CommonRules" } } ãŸãã¯æ±çšçãªãã®ãé©çšããŠãé©å®æé©ãªãã®ãèšå®ããŠããããšèããŠããã®ã§ããã æ©é以äžã®ïŒç¹ã§å€§ãã圱é¿ãåºãããšãããããŸããã ãããäºåã«ç¥ã£ãŠãããã©ããã§èª¿æ»ã察çã®æéãç¯çŽã§ããã®ã§ã¯ãªãããªãšæã£ãŠããŸãã åé¡â ïŒXSSæ€ç¥ã«ããæçš¿ããããã¯ããã 察象ã«ãŒã«ïŒ CrossSiteScripting_BODY Froala Editorã¯HTMLãçæããããã <script> ã¿ã°ã«äŒŒãæ§æã屿§ãå«ãŸããå Žåããã çµæïŒ æ£åœãªå
¥åã§ãWAFãXSSãšèª€æ€ç¥ããŠããã㯠ããå Žåããã 察å¿çïŒ statement { managed_rule_group_statement { name = "AWSManagedRulesCommonRuleSet" vendor_name = "AWS" # ãCrossSiteScripting_BODYãã«ãŒã«ã®ã¿countéçšã«ããèšå®ã远å rule_action_override { name = "CrossSiteScripting_BODY" action_to_use { count {} } } } } åä»ãªãšããã¯ããã¹ãŠã®HTMLæ¬æã§ãªãããã§ã¯ãªããå
容ã«ãã£ãŠãšã©ãŒã«ãªããšããããšã§ãã ãã®ãããæ€èšŒæã¯ç¹ã«çºèŠããããšãªãæ€ç¥ã§ãããæ¬çªã®ããŒã¿ãå©çšããããšã§çºèŠããŸããã æåã¯ãªãäžéšã ããšã©ãŒã«ãªããã®åå ãããããç¹å®ãŸã§æéãããããŸããã WAFã®ãã°ã®äžã«BLOCKããŠãããã°ãããã®ã§ããããåç
§ããããšã§ç¹å®ã®ã±ãŒã¹ã®å Žåã®ã¿BLOCKãããŠããããšãããããŸããã ãã¯ãããããããšããããæ¬çªéçšã§ã¯æåã¯countéçšããŠæ§åãèŠããšããããšãè¯ããšæãç¥ããããéšåã§ããããŸãã ä»åã¯countéçšã«ããããšã§ãšã©ãŒåé¿ã¯ããŠããŸãããå®ã¯ãã BLOCKããªãããã«ããŠããã ãã§ããã ã»ãã¥ãªãã£é¢ã§èãããšãã¹ãã§ã¯ãªãç¶æ
ã§ãã ããã¯å Žåã«ãã£ãŠã¯NGã§ã察çãããã«æ€èšããå¿
èŠããããããããŸããã åé¡â¡ïŒãªã¯ãšã¹ãããã£8KBå¶éã«ããæ€ç¥æŒãã»æå³ããªãããã㯠察象ã«ãŒã«ïŒ SizeRestrictions_BODY AWS WAFã¯ãªã¯ãšã¹ãããã£ã®æ€æ»ã« æå€§8KBïŒ8192ãã€ãïŒ ãšããäžéããã Froalaããæçš¿ãããé·æã»è£
食ã€ãHTMLã§å¶éãè¶
ããããšããã ãã¡ããäºåã«ããã£ãŠããã°å¯Ÿçã®ããããã¯ãã£ããšæããŸããã ãããŒãžãã«ãŒã«å
容ã®ãã¹ãŠãææ¡ã§ããŠããªãããã€Froala Editorã®ä»æ§ããã£ããææ¡ã§ããŠããªãéšåãéãªãã åå ã®ç¹å®ã察å¿çã«ããæéãããã£ãŠããŸã£ãéšåã«ãªããŸãã 察å¿çã®éžæè¢ïŒ count ã¢ãŒãã«å€æŽãããããã¯ãããã°ã ãèšé²ãã ãâãšã¯ãããã§ããã°äºåã«ãµã€ãºå¶éã«ãããããã¯ã¯è¡ããããšããã§ãã FroalaåŽã§å
¥åãµã€ãºã®ãã€ãå¶éãããã ãâããã¯Froalaã®ä»æ§äžã8KB 以äžã«æããæ¬æãäœæããã®ã¯ããªãå³ãããã§ãã æçš¿ãè€æ°åã«åå²ããŠéä¿¡ãããããªä»çµã¿ã«å€æŽ ãâæç« ã§ã¯ç°¡åã«æžããŸãããèæ
®ç¹ãéåžžã«å€ã察å¿ã³ã¹ãã¯é«ãã§ãã ããïŒåå²éä¿¡çšã®APIæºåãåãããŒã¿ã®åææŽæ°æã®èæ
®ãå岿޿°ã®å¶åŸ¡ããšã©ãŒå¶åŸ¡ïŒ ãŸãšãïŒWAFãå°å
¥ããéã¯ãŠãŒã¹ã±ãŒã¹ãšå¶éãäºåã«çè§£ããã ä»åã®å
容ãç°¡åã«è¡šã«ããŸããã èŠ³ç¹ å
容 ãã°ã°ã«ãŒãåã®å¶çŽ aws-waf-logs- ã§å§ããªããšTerraformãšã©ãŒã«ãäºåã«åœå確èªãïŒ CloudFrontè§£é€æã®æ³šæ web_acl_id = null ãæç€ºããªããš Terraform Apply æã«ãšã©ãŒ XSSæ€åºã®éæ€ç¥ HTMLãšãã£ã¿äœ¿çšæã¯ count ã¢ãŒãã§æ§åãèŠãã®ãå®å
š 8KBå¶éã®ã€ã³ãã¯ã é·æã»è£
食æçš¿ããããªãã¢ããªã»ã€ã³ãã©äž¡é¢ã§ã®å¯Ÿå¿ãå¿
èŠ ãããã« ãããã§ããã§ããããã AIãå©çšããããšã§å¹çããWAFãæ§ç¯ã§ããåé¢ã 仿§ãžã®çè§£ãäžååã ãšæå³ãã¬ãã©ãã« ã«ãã€ãªãããŸãã ç¹ã«Froala Editorã®ããã«HTMLãæ±ãããŒã«ã䜿ã£ãŠããå Žåã¯ã WAFã®æšæºã«ãŒã«ãšè¡çªãããããæ€ç¥ã»ãããã¯ã®èª¿æŽãéèŠ ã«ãªããŸãã ããäºæãã¬403ãšã©ãŒãªã©ãçºçããŠããå Žåã¯æ¬èšäºã®å
容ã®éšåãçã£ãŠã¿ãã®ãè¯ããããããŸããã æ¬èšäºããããããWAFãå°å
¥ãããæ¹ã«ãšã£ãŠã®åèã«ãªãã°å¹žãã§ãã æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã
ã¯ããã« ããã«ã¡ã¯ãããªãã·ã¥ãããã³éçºéšã§ãœãããŠã§ã¢ãšã³ãžãã¢ãããŠããæ°è°·ã§ãã ãšããªãŒã®éçºéšã§ã¯ãæ¥åžžæ¥åããé¢ããŠæ°ããæè¡ãã¢ã€ãã¢ã«ææŠãããææŠweekããšããåãçµã¿ã宿çã«éå¬ããŠããŸãã ä»åã¯éå®çã«2æ¥éãšããçæéã§ã®éå¬ã§ãããããã®ææŠweekãæŽ»çšãããã«ã·ã«ã®ç»åè§£ææ©èœã®ç²ŸåºŠãããã«é«ããããšãç®æããŠãæè¡æ€èšŒãšããŠæ§è³ªã®ç°ãªã2ã€ã®AIã¢ãããŒããæ§ç¯ã»æ¯èŒããŸããã®ã§ããã®å
容ã«ã€ããŠã玹ä»ããŸãã â» ææŠweekã®è©³çްã«ã€ããŠã¯éå»ã®èšäºã§ç޹ä»ããŠããŸãã®ã§ãèå³ã®ããæ¹ã¯ä»¥äžãã芧ãã ããã tech.every.tv æ¯èŒãã2ã€ã®ã¢ãããŒã ç»åããã®æ é€çŽ æšå®ãšããã¿ã¹ã¯ã«å¯ŸããŠãç§ãã¡ã¯2ã€ã®ç°ãªãã¢ãããŒããèšèšããŸããã LLMåäœã¢ãããŒã äžã€ç®ã¯ãLLMãæã€åºç¯ãªç¥èãçšããŠãç»åããæçåãææãç¹å®ããæ é€çŽ ãçŽæ¥æšå®ããã¢ãããŒãã§ãããã®ææ³ã®åŒ·ã¿ã¯ãäžã€ã®ã¢ãã«ã§å®çµãããããã·ã³ãã«ã§é«éãªå¿çãæåŸ
ã§ããç¹ã§ãã RAG掻çšã¢ãããŒã äºã€ç®ã¯ãLLMã®æšå®èœåã«å ããŠãæ€çŽ¢æ¡åŒµçæïŒRAGïŒã®æè¡ã掻çšããã¢ãããŒãã§ããLLMãæšå®ããææåãåºã«ãããªãã·ã¥ãããã³ïŒDKïŒã®é£æããŒã¿ããŒã¹ãæ€çŽ¢ããåŸãããæ£ç¢ºãªæ é€çŽ ããŒã¿ãåºã«æçµçãªèšç®ãè¡ããŸããããããŒã¿ã«åºã¥ããã粟床ã®é«ãæšå®ãç®æãã¢ãããŒãã§ãã å
·äœçã«ã¯ãRAG掻çšã¢ãããŒãã§ã¯ä»¥äžã®ã¢ãŒããã¯ãã£ãèšèšããŸããã ãã¬ããžããŒã¹ã®æ§ç¯ã«ããã£ãŠã¯ãåœåãããé«åºŠãªã¢ãããŒãã詊ã¿ãŸãããå
·äœçã«ã¯ãAmazon OpenSearch Serverlessã«å°çšã®ã€ã³ããã¯ã¹ãäœæããAWS LambdaãçšããŠé£æããŒã¿ãèªåçã«æµã蟌ãä»çµã¿ã§ãããã®æ¹æ³ã§ã¯ã飿åã®ã¿ããã¯ãã«åããåæ é€çŽ ïŒã«ããªãŒãããã±ã質ãªã©ïŒãã¡ã¿ããŒã¿ãšããŠä»äžããããšã§ãæ€çŽ¢ç²ŸåºŠåäžãç®æããŸããã ããããæ€èšŒãé²ããäžã§ãã¡ã¿ããŒã¿ãæå³ããéãã«çµæãžåæ ãããªããšãã課é¡ã«çŽé¢ããŸããã èšå®ã®èŠçŽããªã©ã詊ã¿ãŸããããçæéã§ã®è§£æ±ºãé£ããã£ããããä»åã¯ã¢ãããŒãã倿Žããé£æãšæ é€çŽ ããã¹ãŠCSVã«ããŠS3ã«ã¢ããããŒããBedrockã®æ©èœã§çŽæ¥ãã¬ããžããŒã¹ãäœæãããšãããããã·ã³ãã«ãªæ¹æ³ãæ¡çšããŸããã æ€èšŒçµæ ããã2ã€ã®ã¢ãããŒãã®æ§èœãæ¯èŒãããããç¹å®ã®æçåçãçšããŠæ€èšŒãè¡ããŸãããããªãã·ã¥ãããã³ã®ã¬ã·ããæã€æ é€çŽ ããŒã¿ããåèå€ããšããŠãåã¢ãããŒãã®æšå®çµæãã©ãã ãè¿ãããæ¯èŒããŸãã æ€èšŒ1ïŒã«ããšè±èã®å³åçã é
ç® DKã¬ã·ã RAG LLMåäœ ã«ããªãŒ(kcal) 615 501 250 ããã±ã質(g) 18.2 14.4 12 è質(g) 48.7 47.2 15 çæ°Žåç©(g) 18.6 0.2 5 ç³è³ª(g) 15.5 0.8 4.3 å¡©å(g) 2.4 1.2 1.2 æ€èšŒ2ïŒãã
ãããšã¡ããã®ããã€ããã ã« é
ç® DKã¬ã·ã RAG LLMåäœ ã«ããªãŒ(kcal) 98 105 70 ããã±ã質(g) 4.8 0 4 è質(g) 5.5 11.4 2 çæ°Žåç©(g) 7.6 0.3 8 ç³è³ª(g) 6.9 0.3 6.5 å¡©å(g) 1.5 0.4 0.8 æ€èšŒ3ïŒé¶ããèã®ã¿ããç
®ç®ç« é
ç® DKã¬ã·ã RAG LLMåäœ ã«ããªãŒ(kcal) 741 1312 670 ããã±ã質(g) 43.5 44.1 35 è質(g) 15.4 32.2 15 çæ°Žåç©(g) 104.6 134.4 84 ç³è³ª(g) 97 127.2 75 å¡©å(g) 4.5 2.1 3.6 æ€èšŒ4ïŒå€§æ ¹ã®ãšããšãç
®ç®ç« é
ç® DKã¬ã·ã RAG LLMåäœ ã«ããªãŒ(kcal) 745 726 678 ããã±ã質(g) 29.6 4.3 35.2 è質(g) 25.8 16.2 26.8 çæ°Žåç©(g) 89.5 59.3 78 ç³è³ª(g) 83.4 17.3 70.5 å¡©å(g) 5 0.8 3.3 çµæã®èå¯ çµæãèŠããšã RAGã¯ãLLMåäœãšæ¯èŒããŠåèå€ã§ããDKã¬ã·ãã®å€ã«è¿ããªãã±ãŒã¹ãããã°ãéã«å€§ããå€ããŠããŸãã±ãŒã¹ããã ãšãããäžé·äžçãªçµæãšãªããŸããã ä»åã®RAGã®è©Šã¿ã¯ãLLMåäœã§ã¯æšå®ãé£ããã飿ããŒã¹ã§ã®æ é€çŽ èšç®ãããããªãã·ã¥ãããã³ã®å
·äœçãªé£æããŒã¿ãåç
§ãããããšã§ãã©ãã ãæšå®å€ãåèå€ã«è¿ã¥ããããããæ€èšŒãããã®ã§ããã ä»åŸã®èª²é¡ãšå±æ ä»åã®æ¯èŒæ€èšŒãããããã€ãã®èª²é¡ãèŠããŠããŸããã ææã®ç¹å®ãšéã®æšå®ã®ã°ãã€ã ç»åã«åã£ãŠããªãææããåã£ãŠããŠãæ£ç¢ºãªéãæšå®ããã®ã¯ãçŸç¶ã®LLMã®ç²ŸåºŠã§ã¯äŸç¶ãšããŠå°é£ã§ãã æææ€çŽ¢ã®ãã€ãº ãã¯ãã«æ€çŽ¢æã«ãç¡é¢ä¿ãªé£æããããããããéã«å¿
èŠãªé£æããããããªãã£ããããåé¡ããããŸããã æ é€çŽ ã®è¶³ãåãããäžå®å® LLMã«ããæçµçãªéèšåŠçããå¿
ãããæåŸ
éãã«è¡ãããªãã±ãŒã¹ããããŸããã å®è¡æéãé·ã è€æ°ã®ã¹ããããèžããããLLMåäœããåŠçã«æéãããããŸãã ç¹ã«èª²é¡2, 3, 4ã«ã€ããŠã¯ãæ¹åã®äœå°ããããšèããŠããŸããäŸãã°ããã¯ãã«DBã®ãã¥ãŒãã³ã°ãå
šææ€çŽ¢ãžã®åãæ¿ããæ é€çŽ ã®éèšãã«ãŒã«ããŒã¹ã§è¡ãããšãã£ã察çãèããããŸãã ãããã®èª²é¡ãèžãŸããä»åŸã¯ä»¥äžã®ãããªå¥ã®ã¢ãããŒããæ€èšããŠããŸãã æšå®ããæçåããé¡äŒŒã®DKã¬ã·ããæ€çŽ¢ãããã®æ é€çŽ ã®å¹³åå€ãæ¡çšããã DKã®ã¬ã·ãç»åãšæçåã§æ°ããªãã¯ãã«DBãæ§ç¯ããç»åã§é¡äŒŒæ€çŽ¢ãè¡ãã æ é€çŽ æšå®ã«ç¹åããã¢ãã«ããã¡ã€ã³ãã¥ãŒãã³ã°ããã ãŸãšã ä»åã¯ãç»åããã®æ é€çŽ æšå®ã®ç²ŸåºŠåäžãç®æããæ§è³ªã®ç°ãªã2ã€ã®AIã¢ãããŒãïŒLLMåäœ/RAGïŒãæ§ç¯ã»æ¯èŒæ€èšŒããŸããã çµæãšããŠãRAGã¯ç¹å®ã®æ¡ä»¶äžã§ç²ŸåºŠãåäžããå¯èœæ§ã瀺ããŸããããå®å®æ§ãå¿çé床ã®é¢ã§ã¯LLMåäœã«åããããªã©ãããããã«å©ç¹ãšèª²é¡ãããããšãæããã«ãªããŸããã ãã®ææŠã§åŸãããç¥èŠã掻ããããããªã粟床åäžã«åããŠãä»åŸãæ€èšŒãç¶ããŠãããããšæããŸãã
ã¯ããã« ããã«ã¡ã¯ãããªãã·ã¥ãããã³ã§ã¯ã©ã€ã¢ã³ããšã³ãžãã¢ãæ
åœããŠãã kikuchi ã§ãã è¿å¹Ž AI æè¡ã®çºå±ãèãããäžã§ãçæ AI ãããªãã®å¢ãã§çºå±ããæ®æ®µäœ¿ããä»äºã§ ChatGPT ãªã©ã®çæ AI ã®ãµãŒãã¹ãåãå
¥ããæ¹ãäŒæ¥ãå€ããªã£ãŠããŸããã ä»åã¯å€ãã®å Žåã§çæ AI ã®æ©èœãå®çŸããŠããæ©æ¢°åŠç¿ (ML : Machine Learning) ã«ã€ããŠãAndroid ã¢ããªã§ç°¡åã«å®è£
ããæ¹æ³ã«è§ŠããŠã¿ãããšæããŸãã ãªããåŒç€Ÿã¯éçºçç£æ§ã®åäžãªã©ãç®çãšã㊠Cursor ãå°å
¥ãããªã©ãç©æ¥µç㪠AI ã®æŽ»çšãåãå
¥ããŠããŸãã®ã§ããèå³ãããæ¹ã¯ãã¡ãã®èšäºãèŠãŠããã ãããšå¬ããã§ãã ãšããªãŒãAIãšãã£ã¿ãCursorããå
šãšã³ãžãã¢ããã³ãããã¯ããããŒãžã£ãŒã«å°å
¥ ã¢ããªã«çµã¿èŸŒãæ¹æ³ ãæ©æ¢°åŠç¿ããšããèšèã䜿ããšé£ããå°è±¡ããããŸãããæ¢ã«æ©æ¢°åŠç¿ã®æ©èœãæäŸãããã¬ãŒã ã¯ãŒã¯ã¯å€ãååšããŠãããäžã§ã Google ãæäŸãã MediaPipe ãšãããã¬ãŒã ã¯ãŒã¯ã䜿ãããšã§ç°¡åã«çæ AI ãšãã£ãæ©èœãå®è£
ããããšãã§ããŸãã ãŸã MediaPipe ã§ã¯æ§ã
ãªãœãªã¥ãŒã·ã§ã³ãæäŸãããŠããã2025 幎 7 ææç¹ã§ã¯å
šãŠã®ãœãªã¥ãŒã·ã§ã³ã Android ã®ç«¯æ«ã§å©çšå¯èœãšãªããŸãã 以äžå
¬åŒãµã€ãã«ãŠãå©çšå¯èœãªãœãªã¥ãŒã·ã§ã³ããŸãšãŸã£ãŠããŸãã https://ai.google.dev/edge/mediapipe/solutions/guide?hl=ja#available_solutions ä»åã¯ããã®äžã§ãåããã€ã¡ãŒãžãããã ç»ååé¡ (Tasks API) ãš çæ AI (LLM Inference API) ã«ã€ããŠè§ŠããŠã¿ãããšæããŸãã ç»ååé¡ (Tasks API) ã®å®è£
æ¹æ³ ãŸãã¯ç»ååé¡ (Tasks API) ã®å®è£
æ¹æ³ã«ã€ããŠãŸãšããŠãããŸãã 1. ã¢ãã«ããŒã¿ã app/src/main/assets ã«è¿œå æ©æ¢°åŠç¿ã®ããŒã¿ãåããããã«ã¯åœç¶ã¢ãã«ããŒã¿ãå¿
èŠãšãªããŸãã ä»å㯠Google AI for Developers ãæäŸããŠããç»ååé¡ã¢ãã«ã䜿çšããããšæããŸãã https://ai.google.dev/edge/mediapipe/solutions/vision/image_classifier/index?hl=ja#efficientnet-lite0_model_recommended ã¢ãã«ã«ã¯ int8 ãš float32 ãååšããŸãã int8 ⊠ãã¡ã€ã«ãµã€ãºã軜éã§ãåŠçé床ãéãã粟床ã¯ãããã«äœã float32 ⊠ãã¡ã€ã«ãµã€ãºã倧ãããåŠçé床ãé
ãã粟床ã¯é«ã ãšããç¹åŸŽããããã¹ãããªã©ã¹ãã¬ãŒãžãã¡ã¢ãªãéãããŠããå Žå㯠int8 ã䜿çšãããšããããšæããŸãã æ¬èšäºã§ã int8 ãå°å
¥ããåæã§ã®å®è£
æ¹æ³ããŸãšããŠãããŸãã 2. app ã¬ãã«ã® build.gradle ã« Vision Task ã©ã€ãã©ãªã远å dependencies { implementation( "com.google.mediapipe:tasks-vision:0.10.26" ) } 3. ImageClassifier ã®åæå ImageClassifier ã¯ç»ååé¡ã¿ã¹ã¯ãå®è¡ããããã®ã¯ã©ã¹ãšãªããŸãã ã¢ãã«ããŒã¿ãèªã¿èŸŒãŸããŠåæåãããããã¢ãã«ããŒã¿èªäœã®ãµã€ãºã«ããããŸããããåæåã³ã¹ããé«ããªãã®ã§ãäžåºŠã ãå®è¡ããŠåå©çšãã圢ãè¯ãã§ãã lateinit var imageClassifier: ImageClassifier fun initImageClassifier(context: Context) { val options = ImageClassifier.ImageClassifierOptions.builder() .setBaseOptions(BaseOptions.builder().setModelAssetPath( "efficientnet_lite0.tflite" ).build()) // â ⊠èªã¿èŸŒãŸããã¢ãã«ããŒã¿ã®èšå® .setRunningMode(RunningMode.IMAGE) // ⡠⊠åé¡ããç»åããŒã¿ã®çš®å¥ .setMaxResults( 3 ) // ⢠⊠è¿åŽããã¬ã¹ãã³ã¹ã®æ° .setScoreThreshold( 0.5F ) // ⣠⊠åºåçµæã®ç¢ºä¿¡åºŠã®ãããå€ .build() try { imageClassifier = ImageClassifier.createFromOptions(context, options) } catch (e: IllegalStateException ) { Log.e( "ImageClassifier" , "TFLite failed to load model with error: " + e.message) } } ãã©ã¡ãŒã¿ãå€ãããã现ãã確èªããŠãããããšæããŸãã â ã«ã€ããŠã¯ãã¢ãã«ããŒã¿ã®èªã¿èŸŒã¿ãšãªããã assets ãã¡ã€ã«ã«é
眮ãããã¡ã€ã«ãæå®ããŠããŸãã â¡ã«ã€ããŠã¯ãèªã¿èŸŒãŸããç»åããŒã¿ã®çš®å¥ãèšå®ãããã®ã§ãéæ¢ç» ( IMAGE ) / åç» ( VIDEO ) / ã¹ããªãŒã ( LIVE_STREAM ) ãèšå®ã§ããŸãã ä»åã¯éæ¢ç»ãèªã¿èŸŒãŸãããããéæ¢ç» ( IMAGE ) ãèšå®ããŠããŸãã â¢ã«ã€ããŠã¯ãè¿åŽããã¬ã¹ãã³ã¹ã®æ°ãšãªãã3 ãèšå®ããå Žåã¯ç¢ºä¿¡åºŠ (ã¹ã³ã¢) ãéé ã§ 3 ã€è¿åŽãã圢ãšãªããŸãã â£ã«ã€ããŠã¯ãâ¢ã§ãè§Šãã確信床ã®äºã§ãæå®ããæ°å€ä»¥äžã®ç¢ºä¿¡åºŠã®é
ç®ã®ã¿ã¬ã¹ãã³ã¹ã«å«ããŸãã 0.5F ãæå®ããå Žåã確信床ã 50% 以äžã®ãã®ã®ã¿ã¬ã¹ãã³ã¹ã«å«ããããšãã圢ãšãªããŸãã 4. ããŒã¿ã®åé¡å®è¡ 3 ãŸã§ã§å¿
èŠãªèšå®ã¯å®äºãããããæåŸã«ããŒã¿ã®åé¡ãå®è¡ããŸãã fun classifyImage(bitmap: Bitmap) { // åæåå®äºæžã¿ããã§ã㯠if ( !:: imageClassifier.isInitialized) { return } // ããŒã¿ãåé¡ããŠãã°åºå val mpImage = BitmapImageBuilder(bitmap).build() val result = imageClassifier.classify(mpImage) result.classificationResult().classifications().forEach { classification -> classification.categories().forEach { category -> Log.d( "ImageClassifier" , "Category: ${ category.categoryName() } , Score: ${ category.score() } " ) } } } Bitmap ã®ããŒã¿ã ImageClassifier$classify ã¡ãœããã§èªã¿èŸŒãŸããçµæããã°ã§åºåãã圢ãšãªããŸãã å®è¡çµæ ä»åã¯ã¢ãã«ãã¡ã€ã«ãšåæ§ã«ã以äžã® Google AI for Developers ã®ç»ååé¡ã¿ã¹ã¯ã¬ã€ãã®ããŒãžã«èšçœ®ãããŠãããã©ãã³ãŽã®ç»åãåé¡ããŠã¿ãããšæããŸãã https://ai.google.dev/edge/mediapipe/solutions/vision/image_classifier åºåãã°ã¯ä»¥äžã®ããã«ãªããŸããã 89.4% ãšããé«ã確信床㧠flamingo ãšåé¡ãããŸããã (å
¬åŒã® 95% ãšããæ°å€ããããäžãã£ãŠããã®ã¯ãããããæåãšåç©ãæ··åšããŠããŸã£ãŠãã圱é¿ã ãšèããŸã) ä»ã«ãè²ã
ç»åãèªã¿èŸŒãŸããŸãããã 察象ã®åç©ä»¥å€ (æšãèãªã©) ã¯åã蟌ãŸãªãæ¹ã粟床ãé«ã æ£é¢ãã¯ã£ããåããŠããŠãé¡ãèå¥ã§ããæ¹ã粟床ãé«ã ç¬ã¯ç¢ºä¿¡åºŠãããªãäœã (æ¯å 30% çšåºŠ) ã©ã€ãªã³ã¯ç¢ºä¿¡åºŠãããªãé«ã (æšãèãåã蟌ãã§ã 90% 以äžãšãªã) ãšãªããæäŸãããŠããã¢ãã«ããŒã¿ã§ã¯åé¡ã§ããã»ã§ããªãåç©ãã¯ã£ããããŠããããšããè峿·±ãçµæãšãªãããšãããããŸããã ç»ååé¡ (Tasks API) ã®å®è£
æ¹æ³ã«ã€ããŠã¯ä»¥äžãšãªããŸãã çæ AI (LLM Inference API) ã®å®è£
æ¹æ³ 次ã«çæ AI (LLM Inference API) ã®å®è£
æ¹æ³ã«ã€ããŠãŸãšããŠãããŸãã ãã¡ããåºæ¬çãªå®è£
ã®æµãã¯ç»ååé¡ (Tasks API) ãšåæ§ã§ãä»åã¯ãã£ãã圢åŒã®æåãå®è£
ããŠã¿ãããšæããŸãã 1. ã¢ãã«ããŒã¿ã app/src/main/assets ã«è¿œå ãã¡ãã Google AI for Developers ããã¢ãã«ããŒã¿ãããŠã³ããŒãããŸãã â»ä»å㯠Gemma-3 1B ãšããã¢ãã«ããŒã¿ã䜿çšããŸãããHugging Face ã®ã¢ã«ãŠã³ããå¿
èŠãšãªãç¹ã«ã泚æãã ããã https://ai.google.dev/edge/mediapipe/solutions/genai/llm_inference?hl=ja#gemma-3_1b ãã¡ãã§ãããç»ååé¡ãšéã£ãŠã¢ãã«ããŒã¿ã 500MB 以äžã«ãªããªã©ããªããµã€ãºã倧ãããªããŸãã ã¢ãã«ããŒã¿ãè€æ°ååšãããã詳现ã¯å²æããŸãããä»å㯠dynamic_int4 QAT ãšãããã®ãæ¡çšããŸããã 2. app ã¬ãã«ã® build.gradle ã« Gen AI Task ã©ã€ãã©ãªã远å dependencies { implementation( "com.google.mediapipe:tasks-genai:0.10.25" ) } 3. ã¢ãã«ããŒã¿ã assets ãã cache ã«ã³ããŒãã LLM Inference API ã«ã€ããŠã¯çŽæ¥ assets ãã©ã«ãããã¢ãã«ããŒã¿ãåç
§ããæ¹æ³ããªããããäžåºŠ cache ãã©ã«ãã«ããŒã¿ãã³ããŒããŠããèªã¿èŸŒãŸããŸãã private fun copyModelFromAssetsToCache(context: Context, modelName: String ): String { val outputFile = File(context.cacheDir, modelName) if (outputFile.exists()) { return outputFile.absolutePath } context.assets. open (modelName).use { inputStream -> FileOutputStream(outputFile).use { outputStream -> inputStream.copyTo(outputStream) } } return outputFile.absolutePath } ãªã assets ããçŽæ¥åç
§ã§ããªãã®ãããšããç¹ã§ãããã¢ããªã§å·šå€§ãªããŒã¿ãå¹ççã«æ±ãããã«ã¯ã¡ã¢ãªãããã³ã°ãšããæè¡ãå¿
èŠãšãªãããã®æè¡ã¯å®ãã¡ã€ã«ãã¹ãå¿
èŠãªãã assets ãã¡ã€ã«ã§ã¯äœ¿çšã§ããªããªã£ãŠãããäžåºŠ cache ã®é åã«ã³ããŒããŠãããã¡ãã®ãã¡ã€ã«ã«å¯ŸããŠã¢ã¯ã»ã¹ããå¿
èŠããããŸãã ãããã LLM Inference API ã§ã巚倧ãªã¢ãã«ããŒã¿ãæ±ãæ³å®ã§ãassets ã«çŽæ¥ã¢ã¯ã»ã¹ããã¡ãœãããèéãããŠãããã®ãšæšæž¬ããŠããŸãã 4. LlmInference ã®åæå LlmInference ã¯çæ AI ã®ã¿ã¹ã¯ãå®è¡ããããã®ã¯ã©ã¹ãšãªããŸãã ã¢ãã«ããŒã¿ãããªã倧ããåæåã«æ°ç§ã¯ããã£ãŠããŸãããããã¡ããäžåºŠã ãå®è¡ããŠåå©çšãã圢ãè¯ãã§ãã private lateinit var llmInference: LlmInference fun initLlmInference(context: Context) { // LLM Inference ã®åæå val taskOptions = LlmInference.LlmInferenceOptions.builder() .setModelPath(copyModelFromAssetsToCache(context, "gemma3-1b-it-int4.task" )) .build() llmInference = LlmInference.createFromOptions(context, taskOptions) } 5. çæ AI å®è¡ 4 ãŸã§ã§å¿
èŠãªèšå®ã¯å®äºãããããæåŸã«çæ AI ãå®è¡ããŸãã private val _updateResponse: MutableSharedFlow< String > = MutableSharedFlow() val updateResponse: Flow< String > = _updateResponse fun generateResponse(text: String ) { viewModelScope.launch(Dispatchers.IO) { val result = llmInference.generateResponse(text) _updateResponse.emit(result) } } ãã¡ãã¯ããã¹ãã§åãåã£ãæååãè§£æããã¬ã¹ãã³ã¹ããŒã¿ãçæããæµããšãªã£ãŠããŸãã ä»å㯠UI äžã§è¡šçŸãããã£ããããFlow ã§ Fragment åŽã«ããŒã¿ãéã£ãŠããŸãã å®è¡çµæ å®éã«ããåãããçµæãç»åã§èŒããããšæããŸãã ãã®ã¢ãã«ããŒã¿ã§ã¯æ¥æ¬èªã«å¯ŸããŠã¯æ¥æ¬èªã§ããã€é¡æåã䜿ã£ãŠåçãçæããŠãããããšãåãããŸãã çæ AI (LLM Inference API) ã®å®è£
æ¹æ³ã«ã€ããŠã¯ä»¥äžãšãªããŸãã ã¢ãã«ããŒã¿ãçµã¿èŸŒãã¡ãªããã«ã€ã㊠ã¢ããªã«ã¢ãã«ããŒã¿ãçµã¿èŸŒãäžçªã®ã¡ãªãã㯠ãªãã©ã€ã³ã§ãçµæãååŸã§ããäº ã ãšèããŸãã ä»ã§ã¯éä¿¡ããŠããŒã¿ãååŸããæµããåœããåãšãªã£ãŠããŸããã黿³¢ã鮿ãããŠããããããã¯éä¿¡ãå®å®ããªãç°å¢äžã§ãé©åãªçããååŸã§ããä»çµã¿ã§ããã°ããŠãŒã¶ã¯éä¿¡ç°å¢ãæ°ã«ããã¢ããªãè§Šãããšãã§ããããããŠãŒã¶ãã¬ã³ããªãŒã«ããªããŸãã åžå Žã«å
¬éããã¬ãã«ãŸã§ã¢ãã«ããŒã¿ãåŠç¿ãããããšã¯é£ããããšæããŸãããäœããã®æ¹æ³ã§ã¢ããªã«çµã¿èŸŒãã ã¢ãã«ããŒã¿ãå·®ãæ¿ããä»çµã¿ãã確ç«ããã°ãã¢ããªåäœã§åžžã«ææ°ã¢ãã«ãåãæ±ãããšãã§ããããã«ãªããŸãã 課é¡ã«ã€ã㊠äžçªã®åé¡ã¯ãã¯ã ã¢ãã«ããŒã¿ã倧ããäº ã§ãã ä»å㯠500MB ãã®ããŒã¿ã assets ã«çµã¿èŸŒããšããæ¹æ³ã§ç¡çããå®è£
ããŸããããã¢ããªã«å
å
ãããšããããšã¯åœç¶ã¢ããªããŠã³ããŒãæã®ãã€ããªãµã€ãºã倧ãããªããšããããšãªã®ã§ãéçšæ¹æ³ãæ€èšããå¿
èŠããããŸãã æ¹æ³ãšããŠèããããããšã¯ assets ã«çµã¿èŸŒã (æ¬èšäºã®ããæ¹) ã¢ããªèµ·ååŸã«ã¢ãã«ããŒã¿ãããŠã³ããŒããã ãããããããŸãããå¥ã®åé¡ãšã㊠1 ã®ã±ãŒã¹ã§ã 2 ã®ã±ãŒã¹ã§ã ã¢ãã«ããŒã¿ãšããéèŠãªè³ç£ãæãåãããããšãé²ãå¿
èŠããã ãšããã»ãã¥ãªãã£é¢ã®èª²é¡ãçºçããŸãã æå·åã宿œããããã€ãã£ãã³ãŒããæŽ»çšãããªã©åé¿ããæ¹æ³ã¯ããã€ããããšæããŸããããããã«ããã¢ãã«ããŒã¿ãã¢ããªã§åãæ±ãããæ€èšããäºé
ã¯å€ãããããã§ãã ãããã« ä»å㯠MediaPipe ã®ãã¬ãŒã ã¯ãŒã¯ã䜿ããAndroid ã¢ããªã«æ©æ¢°åŠç¿ã®æ©èœãå®è£
ããæ¹æ³ããŸãšããŠã¿ãŸãããã以åã¯æ©æ¢°åŠç¿ã«ã€ããŠå°éç¥èãè€éãªã³ãŒããå¿
èŠã§ããããä»ã§ã¯ç°¡åã«å®è£
ã§ããããšãåãããŸããã MediaPipe ã«ã¯ä»å玹ä»ããç»ååé¡ãçæ AI 以å€ã«ãã ç©äœæ€åº ã 顿€åº ã ãžã§ã¹ãã£ãŒèªè ãªã©ãããã«äœ¿ãã匷åãªæ©èœãæ°å€ãæäŸãããŠããŸãã®ã§ããã²å
¬åŒããã¥ã¡ã³ãã§è²ã
ãšç¢ºèªããŠã¿ãŠãã ããã æ¬èšäºã®æ
å ±ãçæ§ã®ã圹ã«ç«ãŠãã°å¹žãã§ãã
ã¯ããã« ããã«ã¡ã¯ãéçºéšã§ããŒã¿ãµã€ãšã³ãã£ã¹ããããŠããèæŸ€ã§ãã ã€ãã«æ±äº¬ãªãŒãžã§ã³ã§Amazon Q in QuickSightãGAããŸããïŒ ããŒã¿ã¹ããŒãªãŒãã·ããªãªããããã¯ãªã©èªç¶èšèªã§ããŒã¿åæãè¡ãæ©èœã远å ãããŸãããããã®ãããã®æ©èœã®è§£èª¬ã¯ 以åã®åŒç€Ÿã®ããã° ããä»ã®æ¹ãèšäºã«ãããŠããã®ã§ããã¡ããã芧ããã ããã°ãšæããŸãã ä»åã¯Amazon Q in QuickSightãèšç®ãã£ãŒã«ããäœæããéã«äœ¿çšããããšã§ãããžã¥ã¢ã«äœæãããå¹çåãããããªããã®æ€èšŒãããããšæããŸãã 䜿çšããæš¡æ¬ããŒã¿ æ€èšŒã«ã¯ä»¥äžã®ãããªãã¬ã·ãåç»ãµã€ãã®ç¹å®ã®ã¬ã·ãã®æ¥æ¯ã®ã€ã³ãã¬ãã·ã§ã³æ°ãšã¯ãªãã¯æ°ãéèšãããšããæ³å®ã®æš¡æ¬ããŒã¿ã䜿çšããŸãã ããããã®ã«ã©ã ã®å®çŸ©ã¯ä»¥äžã®éãã§ãã dateïŒæ¥ä»ïŒ2025-01-01~2024-04-30ïŒ recipeïŒã¬ã·ãåïŒãã³ããŒã°ïŒ clickïŒã¬ã·ããã¯ãªãã¯ããåæ°ïŒ1~10ã®æŽæ°ã®ä¹±æ°ïŒ impressionïŒã¬ã·ãã衚瀺ãããåæ°ïŒ100~200ã®æŽæ°ã®ä¹±æ°ïŒ ãã£ãŠã¿ã ãŸãã¯ãCTRãäœæã§ããã詊ããŠã¿ãŸãã CTR = click / impresseion ãæåŸ
ããŠããŸãã èšç®ãã£ãŒã«ã远å ãéžæãããèšç®ãäœæããã¯ãªãã¯ããŸãã ããã¹ããã©ãŒã«ããåºãŠããã®ã§ãããã«äœæãããèšç®åŒãå
¥åããŸãã ä»åã¯ãCTRããšå
¥åã èšç®åŒãæžãããããäœæããã¯ãªãã¯ããŸãã ïŒã3ç§ã»ã©ã§èšç®åŒãäœæãããŸããã æåŸ
ããŠããéãã®èšç®åŒãã§ããã®ã§ããæ¿å
¥ããã¯ãªãã¯ããŸãã èšç®åŒãæ¿å
¥ãããã®ã§ãæåŸã«ãä¿åããã¯ãªãã¯ããŠãèšç®ãã£ãŒã«ãã®äœæå®äºã§ãã èªç¶èšèªã§ãèšç®ãã£ãŒã«ã®èšç®åŒãäœæããããšãã§ããŸããã CTRã®å®çŸ©ãäžããªããŠãäœæã§ããã®ã¯è¯ããªãšæããŸããïŒ ãããããããããç°¡åãªåŒãªãQã䜿ããã«ãèªåã§äœã£ãæ¹ãæ©ããšæãã®ã§ãããå°ãè€éãªèšç®åŒãäœæããŠã¿ãŸãã æ¥ãé±ãæãšãã£ãæ¥ä»ã®ç²åºŠããã©ã¡ãŒã¿ã§æå®ããããšã§ãæ¥ä»ã®éèšåäœãå€ãããããªèšç®ãã£ãŒã«ããäœæããŸãã äžæºåãšããŠãDateGranularityãšããæååã®ãã©ã¡ãŒã¿ãäœæããŸãã ãã®ãã©ã¡ãŒã¿ã§æ¥ãé±ãæãæå®ããŸãã å
ã»ã©äœæããCTRèšç®ããååãšåæ¯ãç²åºŠã®å€æŽã«äŒŽã£ãŠåèšãããããã«å€æŽããŸãã æ¥æ¬èªã§ããã³ãããæžãããããŸãè¯ãåºåãåŸãããªãã£ãã®ã§ãè±èªã§ããã³ãããæžããŸããã ããŸããããªãã£ãããã³ããã¯èšäºã®æåŸã®æ¹ã§ç޹ä»ããŸãã äœãã¿ãŒã³ã詊ããŸããããweekã®æã«WKã«ãªããDDã«ãªã£ãŠããŸãã®ã¯ãæ¹åããªãã£ãã®ã§ãä»åã¯è«ŠããŠæåã§çŽããŸãã åŸãããçµæãæ¿å
¥ããŠãdayãweekãmonthãæ¥ãé±ãæã«ãç²åºŠãé±ã®æã®DDãWKã«çœ®ãæããŠãä¿åããŸãã ç²åºŠãé±ã«ãããševent_dateãé±ã®å§ãïŒæ¥ææ¥ïŒã«ãªããæã«ãããšyyyy-mmã§æã®åœ¢åŒã«ãªãæ¥ä»èšç®ãã£ãŒã«ãã宿ããŸããã æåŸã«ããå°ãè€éãªèšç®ãã£ãŒã«ãã«ææŠããŸãã StartDateãšEndDateãšãããã©ã¡ãŒã¿ãäœæããç²åºŠã«åãããŠéå§æ¥ãšçµäºæ¥ã調æŽããŠãããæ¥ä»ã®ãã£ã«ã¿ãŒãèšç®ãã£ãŒã«ãã§äœæããŸãã ç²åºŠã§æãéžæããŠããç¶æ
ã§ãStartDaeã2025-01-15ãEndDateã2025-02-07ãšå
¥åãããå Žåã«ã2025-01-01~2025-02-28ã®ããŒã¿ã衚瀺ããããšãã£ãæ³å®ã«ãªããŸãã 以äžã®ããã«ããã³ãããå
¥åããŸããã DAYãWEEKãMONTHãæ¥ãé±ãæã«çœ®ãæããŠä¿åããŸãã ç²åºŠãæ¥ã«ãããšéå§æ¥ãšçµäºæ¥ã®éã®æ¥ä»ãã£ã«ã¿ãŒã1ã«ãªããé±ã«ãããšéå§æ¥ãšçµäºæ¥ãå«ãæ¥ã®é±å§ãããé±çµãããŸã§ã®æ¥ä»ãã£ã«ã¿ãŒã1ã«ãªã£ãŠããã®ã§ãæåŸ
éãã®ãã®ãã§ããŠãããã§ãã æåŸã«ãã£ã«ã¿ãŒã§ãæ¥ä»ãã£ã«ã¿ãŒã1ã®å Žåã®ã¿è¡šç€ºããããã«ããã°ãç²åºŠã«åãããŠéå§æ¥ãšçµäºæ¥ã調æŽããŠãããæ¥ä»ã®ãã£ã«ã¿ãŒã®å®æã§ãïŒ ãã®ãã£ã«ã¿ãŒãèªäœããæã¯ããªãã®æéãããã£ãã®ã§ãäžç¬ã§ã§ããŠæåããŸããïŒ ããŸããããªã£ãäŸ ããŸãèšç®ãã£ãŒã«ããäœæã§ããªãã£ãããã³ããã玹ä»ããŸãã ç°¡æœã«æ¥æ¬èªã§ããã³ãããå
¥åãããããšã©ãŒãåºãŸããã æ¥æ¬èªã§ãããå°ã詳ããããã³ãããæžããããåºåãåŸãããšã¯ã§ããŸããã ããããé±ãã§ã¯ãªãã幎ãèšå®ãããŸããã æ¥æ¬èªã®ããã³ããã«å¯Ÿããåºåã®ç²ŸåºŠã®åäžã¯ä»åŸã«æåŸ
ã§ãïŒ ãããã« ä»åã¯Amazon Q in QuickSightã䜿çšããŠèšç®ãã£ãŒã«ããäœæããæ€èšŒãè¡ããŸããã ç°¡åãªèšç®ãã£ãŒã«ãã®äœæã¯Qã䜿çšããªãæ¹ãæ©ããšæããŸãããå°ãè€éãªèšç®ãã£ãŒã«ããäœæããæããããããããšã¯æ±ºãŸã£ãŠãããåŒããããšã¯æãã€ããªãæã«ã¯ãéçºãå¹çåã§ããæ©èœã ãšæããŸããã æåŸãŸã§èªãã§ããã ãããããšãããããŸããïŒ
éçº2éšã®å
åã§ããæåã³ãŒãã®è©±ã¯å€§å¥œç©ã§ãã äžè¬çã«ãã¢ããªã±ãŒã·ã§ã³ã®éçºã«ãããŠæåæ°ã«ãŠã³ãã¯éåžžã«èº«è¿ãªæ©èœã§ãããã©ã¡ãŒã¿ååŸæããã©ãŒã å
¥åæãªã©ãæ§ã
ãªå Žé¢ã§æåæ°èšç®ãå®è£
ããæ©äŒããããŸãã ããããUnicodeæåãç¹ã«çµµæåãçµåæåãªã©ãæ··åšããããã¹ãåŠçã«ãããŠããæ£ããæåæ°ã«ãŠã³ããã¯æå€ã«è€éãªåé¡ã§ãã ãã®èšäºã§ã¯ãGoèšèªã§ã®Unicodeæåæ°ã«ãŠã³ãã«çŠç¹ãåœãŠãŠãå®è£
æã«æ³šæãã¹ãç¹ãè¿°ã¹ãŸãã æåæ°ã«ãŠã³ãã®çœ ãŸãã以äžã®ã³ãŒãã«ã€ããŠèããŸãã package main import ( "fmt" "unicode/utf8" ) func main() { s := "Helloðð¿" // 6æå? fmt.Printf( "ãã€ãæ°: %d \n " , len (s)) // ãã€ãæ°: 13 fmt.Printf( "ã«ãŒã³æ°: %d \n " , utf8.RuneCountInString(s)) // ã«ãŒã³æ°: 7 } äžèŠ6æåã®ããã«èŠããæååã§ãããå®éã«ã«ãŠã³ããããšç°ãªãå€ãè¿åŽãããŸããããã¯ã©ãããç¶æ³ã§ããããïŒ ãã®å·®ç°ã¯ãäŸãã°ä»¥äžã®ãããªå Žé¢ã§åé¡ãçºçãåŸãŸãã ãã©ãŒã å
¥åæ æåæ°å¶éãè¶
éããŠå
¥åã§ãã ããŒã¿ããŒã¹æå
¥æ ã«ã©ã æåæ°ã®å¶éã«æµè§ŠãDBãšã©ãŒãçºçãã UI衚瀺 æåæ°ã«ãŠã³ã¿ãŒã®è¡šç€ºããŠãŒã¶ãŒã®æèŠãšåããªããªã æåæ°ã«ãŠã³ãææ³ Unicodeæåãæ£ããæ±ãããã«ãçšéã«å¿ããŠé©åãªã«ãŠã³ãææ³ãéžæããå¿
èŠããããŸãã 1. byteæ°ã«ãŠã³ã len() UTF-8ã®ãã€ãåãšããŠåç
§ããŸãã func countBytes(s string ) int { return len (s) } // äŸ fmt.Println(countBytes( "Hello" )) // 5 fmt.Println(countBytes( "ããã«ã¡ã¯" )) // 15 (ã²ããªãã¯UTF-8ã§ã¯3ãã€ã) fmt.Println(countBytes( "café" )) // 5 (é[U+00E9]ã¯UTF-8ã§ã¯2ãã€ã) 2. runeæ°ã«ãŠã³ã utf8.RuneCountInString() Goèšèªã®å
éšã³ãŒãã§ãã rune åäœã§ã rune 1ã€ãUnicodeã®ã³ãŒããã€ã³ã1ã€ã«å¯Ÿå¿ããŸãã func countRunes(s string ) int { return utf8.RuneCountInString(s) } // äŸ fmt.Println(countRunes( "Hello" )) // 5 fmt.Println(countRunes( "ããã«ã¡ã¯" )) // 5 fmt.Println(countRunes( "café" )) // 4 3. æ£èŠååŸã«ãŠã³ã Unicodeã§ã¯ãäžèŠåãèŠãç®ã§ãç°ãªãUnicode衚çŸã«ãªããã®ãååšããŸããçµåæå(Combining Character)ãšããæåæ°ãšããŠã«ãŠã³ãããªãã³ãŒããã€ã³ããååšããŸãã äŸãã°ä»¥äžã®æåã¯äžèŠåãæåã«èŠããŸãïŒç°å¢ã«ãã£ãŠã¯å¥ç©ã«èŠããããç¥ããŸããïŒããã³ãŒããã€ã³ãããŠã¯å¥ç©ã§ããŸãæåæ°ãç°ãªããŸãã ã [U+304C] ãã [U+304B U+3099] ãããäžã€ã®è¡šçŸã«çµ±äžããã®ãæ£èŠåã§ãæ£èŠåããŠããã«ãŠã³ãããŸãã import "golang.org/x/text/unicode/norm" func countNormalizedRunes(s string ) int { normalized := norm.NFC.String(s) return utf8.RuneCountInString(normalized) } // äŸ s1 := "ã" // [U+304C] s2 := "ãã" // [U+304B U+3099] fmt.Println(s1 == s2) // false fmt.Println(countRunes(s1), countRunes(s2)) // 1 2 fmt.Println(countNormalizedRunes(s1)) // 1 fmt.Println(countNormalizedRunes(s2)) // 1 æ£èŠå圢åŒã®éžæ Unicodeã«ã¯4ã€ã®æ£èŠå圢åŒããããŸããæçµçã«ç²åŸããã圢åŒã«å¯Ÿå¿ããæ£èŠåæ¹æ³ãéžã¶å¿
èŠããããŸãã åå 説æ ç¹åŸŽ NFC æ£èŠåïŒåæïŒ èŠèŠçã«åããªãåãã³ãŒãã«ãŸãšãã NFD æ£èŠåïŒåè§£ïŒ çµã¿åããå¯èœãªæåãåè§£ãã NFKC äºææ£èŠåïŒåæïŒ 衚瀺äžåãæå³ã®æåã1ã€ã«ãŸãšããïŒå
šè§âåè§ãªã©ïŒ NFKD äºææ£èŠåïŒåè§£ïŒ åè§£ãã€äºææ§ãå å³ func compareNormalizationForms() { s1 := "ã" fmt.Printf( "NFD: %s(%U)â%s(%U) \n " , s1, [] rune (s1), norm.NFD.String(s1), [] rune (norm.NFD.String(s1))) // NFD: ã([U+304C])âãã([U+304B U+3099]) s2 := "ãã" fmt.Printf( "NFC: %s(%U)â%s(%U) \n " , s2, [] rune (s2), norm.NFC.String(s2), [] rune (norm.NFC.String(s2))) // NFC: ãã([U+304B U+3099])âã([U+304C]) s3 := "â
£" fmt.Printf( "NFKC: %s(%U)â%s(%U) \n " , s3, [] rune (s3), norm.NFKC.String(s3), [] rune (norm.NFKC.String(s3))) // NFKC: â
£([U+2163])âIV([U+0049 U+0056]) s4 := "ïŒ" fmt.Printf( "NFKC: %s(%U)â%s(%U) \n " , s4, [] rune (s4), norm.NFKC.String(s4), [] rune (norm.NFKC.String(s4))) // NFKC: ïŒ([U+FF21 U+FF11])âA1([U+0041 U+0031]) s5 := "ã" fmt.Printf( "NFKD: %s(%U)â%s(%U) \n " , s5, [] rune (s5), norm.NFKD.String(s5), [] rune (norm.NFKD.String(s5))) // NFKD: ã([U+339D])âcm([U+0063 U+006D]) } 4. æžèšçŽ ã¯ã©ã¹ã¿æ°ïŒãŠãŒã¶ãŒç¥èŠæåæ°ïŒ Unicodeã«ã¯ãŒãå¹
æ¥åå(Zero Width Joiner)ãModifierãªã©ãæåæ°ãšããŠã¯ã«ãŠã³ãããªãçš®é¡ã®ã³ãŒããã€ã³ããååšããŸãã ãããã®ã³ãŒããã€ã³ããçšãããšãç¹å®ã®ã³ãŒããã€ã³ããšçµã¿åãããŠå¥ã®æå衚çŸãã§ããããã«ãªããŸããããã«ããå¿
èŠãšãªãã³ãŒããã€ã³ãæ°ãæžããããšãã§ããŸããçµµæåã«ãããèã®è²ã倿Žããããð¯ðµãJ+Pã®ããã«è¡šçŸããããšãã£ãçšéã«äœ¿ãããŸãã æçµçã«ãç°å¢ã«äŸããšããã¯ãããŸããããã§è¡šç€ºãããæååã®è¡šçŸããŠãŒã¶ãŒãå®éã«èªèããæåæ°ãšèšããŸãã ãã ããã®ç®åºãèªåã§å®è£
ããã®ã¯ããªã倧å€ãªã®ã§ãå
¬éãããŠããã©ã€ãã©ãªã«é Œãã»ãããããšæããŸãã æ³šæïŒæåŸã®2ã€ã®æåãããã°ã®ä»æ§ã§è€æ°æåã«åå²ããŠè¡šç€ºãããŠããŸãããæ¬æ¥ã¯ ð³ïžâð ãš ðšâð©âð§âðŠ ã§ãã import "github.com/rivo/uniseg" func countGraphemes(s string ) int { gr := uniseg.NewGraphemes(s) count := 0 for gr.Next() { count++ } return count } // äŸ fmt.Println(countGraphemes( "Hello" )) // 5 fmt.Println(countGraphemes( "ããã«ã¡ã¯" )) // 5 fmt.Println(countGraphemes( "café" )) // 4 fmt.Println(countGraphemes( "ð" )) // 1 [U+1F600] (çµµæåã¯1æåãšããŠèªè) fmt.Println(countGraphemes( "ð¯ðµ" )) // 1 [U+1F1EF U+1F1F5](Regional Indicator Symbolsã¯1æåãšããŠèªè) fmt.Println(countGraphemes( "ð³ïž<200d>ð" )) // 1 [U+1F3F3 U+FE0F U+1F308] (çœæ + ç°äœåã»ã¬ã¯ã¿ + è¹ = ã¬ã€ã³ããŒãã©ãã°ã¯1æåãšããŠèªè) fmt.Println(countGraphemes( "ðš<200d>ð©<200d>ð§<200d>ðŠ" )) // 1 [U+1F468 U+200D U+1F469 U+200D U+1F467 U+200D U+1F466] (å®¶æçµµæåã1æå) ãŸãšã æåæ°ã®ã«ãŠã³ããšããäžèŠç°¡åããã§å®ã¯ãããããšãããããåé¡ã«ã€ããŠèšäºãæžããŠã¿ãŸããã Goèšèªã§Unicodeãæ±ãå ŽåãããçšåºŠãŸã§ã¯èšèªãšããŠã®ãµããŒããåããããŸãããããããUnicodeã®ä»æ§ãšããŠã³ãŒããã€ã³ããšäººéãèªèããæåæ°ã«ã¯éœéœ¬ãããããããããã®å·®åãåããããã«ã¯ã©ãããŠãå®è£
æã«èæ
®ãå¿
èŠãšãªããŸãã ããããããšã«å¿ããé©åãªã«ãŠã³ãææ³ãæ¡çšããããã«å¿ãããŸãããã
ã¯ããã« ååã®èšäºã§ã¯ãæ°åååç ä¿®ã®ç¬¬1åãã第3åãŸã§ã®å
容ãã玹ä»ããŸããã ååã®èšäºããã²ã芧ãã ããïŒ tech.every.tv åŸåãšãªãæ¬èšäºã§ã¯ã第4åãã第6åã®è¬çŸ©ã«ã€ããŠãäŒãããŸãïŒ åŸåã®ç ä¿®ã¯ãããå®è·µçãªå
容ãçãã ãããã§ãããå®éã«ãµãŒããŒãè§£äœããŠããŒããŠã§ã¢ã®ä»çµã¿ãåŠãã ããISUCON圢åŒã§ããã©ãŒãã³ã¹ãã¥ãŒãã³ã°ã«ææŠããããææ°ã®çæAIæè¡ã«ã€ããŠåŠãã ããšããšã³ãžãã¢ãšããŠç¥ã£ãŠããããå¹
åºãç¥èã身ã«ã€ããããšãã§ããŸããã ããã§ã¯ãååã®å
容ãèŠãŠãããŸãããïŒ 6/4éå¬ 4åç® ãµãŒããŒè§£äœç ä¿® ããã«ã¡ã¯ãéçº1éš ããªãã·ã¥ãããã³AWG PUã®é»é«ã§ããç§ã®æ¹ããã¯GMOãºããæ ªåŒäŒç€Ÿæ§ã«äž»å¬ããŠããã ããããµãŒããŒè§£äœç ä¿®ãã«ã€ããŠç޹ä»ããŸãã GMOã€ã³ã¿ãŒãããã°ã«ãŒãæ ªåŒäŒç€Ÿæ§ã®äŒå ŽæäŸã«ãããGMO Yoursã§éå¬ãããŸããã ãµãŒããŒåºç€è¬åº§ ååã¯ããã«ã»ãã¯ãããžãŒãºæ ªåŒäŒç€Ÿã®çŠç°ããã«ããµãŒããŒåºç€è¬åº§ããšé¡ããŠã倧ãã以äžäžã€ã®å
容ãè¬çŸ©ããŠããã ããŸããã ãµãŒããŒã®åºç€ - ããœã³ã³ããå人ãã§äœ¿ãããšãæ³å®ããŠããã®ã«å¯ŸãããµãŒããŒã¯ãã¿ããªãã§äœ¿ãããšãåæãšããŠããã24æé365æ¥ã®é£ç¶çšŒåãé«ãä¿¡é Œæ§ãæ±ããããããšãã£ãã話ã§ããã ãµãŒããŒã®æ§é - CPU, DRAM, SSD/HDD, NICãšãã£ãåæ§æéšåã®èª¬æãããŒã¿ã®æ£ç¢ºæ§ãä¿ã€ECCã¡ã¢ãªããã¹ãã¬ãŒãžã®åé·åãå®çŸããRAIDæ§æãªã©ããµãŒããŒãªãã§ã¯ã®éšåã«ã€ããŠãåŠã³ãŸããã ãµãŒããŒãªãã§ã¯ã®ä»å æ©èœ - PowerEdgeãµãŒããŒã®ãªã¢ãŒã管çããŒã«ã§ããiDRACïŒintegrated Dell Remote Access ControllerïŒã«ã€ããŠè§£èª¬ããã ããŸããã ç§ãç¹ã«è峿·±ãã£ãã®ã¯ããµãŒããŒãããã«ã忢ããªãããšããéèŠããŠèšèšãããŠããããšããç¹ã§ãã黿ºãå·åŽãã¡ã³ã®åé·åããªã¢ãŒãã§ã®ç®¡çæ©èœãªã©ããã¹ãŠããµãŒãã¹ã®ç¶ç¶æ§ãæ¯ããããã®å·¥å€«ã§ãããæ®æ®µå©çšããŠããPCãšã®èšèšææ³ã®æ ¹æ¬çãªéããçè§£ããããšãã§ããŸããã ãã®ããã«äºåã«ããŒããŠã§ã¢ã®ç¥èãã€ã³ãããããããšã§ãããäžå±€ããµãŒããŒã®å
éšãèŠãŠã¿ããããšããæ°æã¡ãé«ãŸããŸããã ãµãŒããŒè§£äœäœæ¥ ç¶ããŠãç ä¿®ã®ç®çã§ããåŸåã®ãµãŒããŒè§£äœã«ã€ããŠã¬ããŒãããŠãããŸãã äŒå Žã«ã¯ãµãŒããŒãè€æ°å°çšæãããŠãããä»»æã®ããŒã ã«åãããŠããããè§£äœãé²ããŠãããŸããã ãã¡ããç§ãã¡ã®ããŒã ã§è§£äœããŠãããµãŒããŒã«ãªããŸããããŒã¿ã»ã³ã¿ãŒã®ã©ãã¯ã«å¹ççã«æèŒãããããäžè¬çãªã¿ã¯ãŒåPCãããæšªåãã«çްé·ããã©ãã¯ããŠã³ãåããšåŒã°ãã圢ç¶ãããŠããŸãããã®äžå°ã§è»œèªåè»ãè²·ããã»ã©ã®å€æ®µããããšèããæã¯ã倧å€é©ããŸããã ãŸãã¯å€©æ¿ãå€ããŸããCPUãã¡ã¢ãªã黿ºãŠããããªã©ãåºæ¬çãªããŒãæ§æã¯éåžžã®PCãšåãã§ãããåããŒãã®ä¿¡é Œæ§ãæ¡åŒµæ§ã¯å€§ããç°ãªã£ãŠããŸãããäŸãã°ã黿ºãŠãããã¯äºéåãããŠãããçæ¹ãæ
éããŠããµãŒããŒã¯åæ¢ããŸããããŸããå·åŽãã¡ã³ã倿°æèŒãããŠããæ§åãããã髿§èœãªããŒããå®å®ããŠåãã匷åãªå·åŽæ§èœãèŠãŠãšããŸãã åããŒã ã®ãµãŒããŒã¯ããããæ§æãç°ãªã£ãŠãããç§ãã¡ã®ãã®ã¯ç¹ã«ã¡ã¢ãªã®æèŒéãå€ãã¢ãã«ã§ãããGPUãæèŒããŠããããŒã ããã£ãããã§ãå°ã矚ãŸããã£ãã®ãèŠããŠããŸãã è§£äœäœæ¥ã«ç¹å®ã®ããã¥ã¢ã«ã¯ãªããåã¡ã³ããŒããããã¯äœã ããïŒããšèå³ã®èµŽããŸãŸã«ããšãã«ã¯ååãåããªããé²ããŠãããŸããã ãã®çµæã以äžã®ããã«å€ãã®ããŒããåãåºãããšãã§ããŸããã å·¥å
·ã䜿ããªãç¯å²ã§ã®è§£äœã ã£ãããéçã¯ãããŸããããè£ãè¿ãã°ã亀æé »åºŠã®é«ãã¡ã¢ãªãã¹ãã¬ãŒãžãªã©ã®ããŒãã¯ãå°éçãªæè¡è
ã§ãªããŠãç°¡åã«æ±ããããèšèšãããŠããããšãããããŸããã 埩å
äœæ¥ãšã¡ã³ããã³ã¹æ§ ããã«ãããããå
ã®ç¶æ
ã«æ»ãã埩å
äœæ¥ããè¡ããŸãã ç®ã«å
¥ã£ããã®ã次ã
ãšåãåºããŠããè§£äœäœæ¥ããããããŒããåãä»ããé åºãªã©ãèæ
®ããå¿
èŠããããããå°ã身æ§ããŸããã ããããå®éã«ã¯ãããŸã§é£ãããããŸããã§ãããåããŒãã¯æå®ã®å Žæã«ããåãŸããªãããã«å·¥å€«ãããŠãããã¡ã³ããŒãšç¢ºèªããªããäœæ¥ãé²ããããšã§ãæå€ãšããã«å
ã®ç¶æ
ã«æ»ãããšãã§ããŸããã ãã®äžé£ã®äœæ¥ãéããŠããµãŒããŒãããã«ã¡ã³ããã³ã¹æ§ãèæ
®ããŠèšèšãããŠãããã宿ããŸãããå®éã«ããã®ãµãŒããŒã®ã¹ãã¬ãŒãžïŒHDD/SSDïŒã黿ºã¯ããããã©ã°ïŒãµãŒããŒã®é»æºãå
¥ãããŸãŸéšåã®äº€æãã§ããä»çµã¿ïŒã«å¯Ÿå¿ããŠãããšããã話ãèãããŸãã«åžžæçšŒåãæ±ãããããµãŒããŒãªãã§ã¯ã®ç¹åŸŽã ãšæããŸããã HDDã®è§£äœ æèŠªäŒã§ã¯ãç¹å¥ã«HDDã®è§£äœããããŠããã ããŸãããHDDã¯ããã©ãã¿ïŒããŒã¿ãèšé²ããåç€ïŒãšãããïŒããŒã¿ãèªã¿æžãããéšåïŒã®ééãæ°ããã¡ãŒãã«ãšéåžžã«çãã空æ°äžã®åŸ®çްãªå¡µãä»çããã ãã§ãå£ããŠããŸãããããã®HDDãåã³åãããšã¯ãããŸãããæ®æ®µç®ã«ããããšã®ã§ããªã粟å¯ãªå
éšæ§é ã«ãæããèŠå
¥ã£ãŠããŸããŸããã æ®æ®µè§Šããããšã®ã§ããªãããŒããŠã§ã¢ã«ããããè§Šããããšãã§ãããšãŠã貎éãªäœéšã§ããïŒ ãŸãšã AWSãªã©ã¯ã©ãŠããµãŒãã¹ã®å©çšãåœããåã«ãªããç§ãã¡ã«ãšã£ãŠãµãŒããŒã¯ããæœè±¡çãªååšã«ãªãã€ã€ãããŸããããããç©ççãªãµãŒããŒã®ä»çµã¿ãçè§£ããããšã¯ãã¯ã©ãŠãäžã§çºçããããã©ãŒãã³ã¹ã®åé¡ãé害ã«å¯ŸããŠãããæ·±ãã¬ãã«ã§ã®æŽå¯ãäžããŠãããŸãã ãã®ãããä»ååŸãããããŒããŠã§ã¢ã®ç¥èã¯ãã€ã³ãã©ã®èšèšãé害察å¿ãªã©ãããäœãã¬ã€ã€ãŒãæ±ãéã«å¿
ã圹ã«ç«ã€ãšæããŸããã ãã¯ãã¯ã©ãŠããæ¡çšããã®ãåœããåã®ããã«ãªã£ãŠããæšä»ã§ããããµãŒãã¹ã®ç¹æ§ãã³ã¹ããã»ãã¥ãªãã£èŠä»¶ãšãã£ãéçšã®ãŠãŒã¹ã±ãŒã¹ã«å¿ããŠæè»ãªã€ã³ãã©éžæãæ±ããããŸãããã®äžã§ãèªç€Ÿã§ãµãŒããŒãæã€ãªã³ãã¬ãã¹ããå¿
èŠã«å¿ããŠéžæè¢ã«å
¥ããã¹ãã ãšæããŸããã 6/11éå¬ 5åç® ISUCONç ä¿® éçº1éš ããªãã·ã¥ãããã³MS DRMã® éŽæš ã§ããç§ããã¯ISUCONç ä¿®ã®ç޹ä»ãããŸãã ISUCON ãšã¯ãã ããæãã« ã¹ããŒãã¢ãã ã³ã³ãã¹ã ãã®ç¥ç§°ã§ããé¡ãšãªãWebãµãŒãã¹ã決ããããã¬ã®ã¥ã¬ãŒã·ã§ã³ã®äžã§ã©ãã ãé«éåã§ããããç«¶ã倧äŒã®ããšã§ãã isucon.net ä»åã®ISUCONç ä¿®ã§ã¯ãæ¬çªã®ISUCONã®ããã«ããŒã ã§äžããããåé¡ã«åãçµã圢åŒã§è¡ãããŸããã äºåæºå ç§ã¯ISUCONåææŠã ã£ãã®ã§ãããäºåã«ISUCONåºå Žçµéšã®ããå
茩ã«ISUCONã§ãã䜿ãããããŒã«ããã¯ããã¯ã«é¢ããç¥èŠãå
±æããŠé ããŸããã ããŒã«ãšããŠã¯ä»¥äžã®ãããªãã®ããããç ä¿®åœæ¥ã«æŽ»çšããŸããã pt-query-digest slowqueryã®è§£æã«äœ¿ãããŒã« mysqlã®ãã°ãè§£æããŠsqlãé
ãé ã«è¡šç€ºããã alp NGINXã®ã¢ã¯ã»ã¹ãã°ã®è§£æã«äœ¿ãããŒã« é
ããšã³ããã€ã³ãé ã«è¡šç€ºããã ç ä¿®åœæ¥ Step 0: æºå - Gitã§ã®ã³ãŒãç®¡ç æ¬æ Œçãªæ¹ä¿®ãå§ããåã«ããŸãEC2ã€ã³ã¹ã¿ã³ã¹äžã«ãã£ãã³ãŒããGit管çäžã«çœ®ããGitHubãªããžããªã«ããã·ã¥ããŸãããããã«ããã倿Žå±¥æŽã®è¿œè·¡ããåé¡çºçæã®åãæ»ãã容æã«ãªããå®å¿ããŠäœæ¥ãé²ããããã®åºç€ãæŽããŸããã Step 1: N+1ã¯ãšãªã®ç¹å®ãšè§£æ¶ - DBè² è·ã®æå€§ã®åå ãå©ã èª²é¡ ã¢ããªã±ãŒã·ã§ã³ã®åäœãåæãããšããããããããŒãžã衚瀺ããã ãã§ããŒã¿ããŒã¹ã«å€§éã®ã¯ãšãªãçºè¡ãããŠããããšã倿ããŸãããããã¯ãæçš¿ã®äžèЧã衚瀺ããã«ãŒãåŠçã®äžã§ãæçš¿ããšã»ã³ã¡ã³ãããšã«åå¥ã®SQLã¯ãšãªãçºè¡ããŠããŸããå
žåçãªã N+1ã¯ãšãªåé¡ ãã§ããã åæ åé¡ãšãªã£ãŠããã®ã¯ã app.go ã® makePosts 颿°ã§ãã以äžã®ããã«ãforã«ãŒãã®äžã§éœåºŠDBã¢ã¯ã»ã¹ãçºçããŠããŸããã // åé¡ã®ãã£ãã³ãŒãïŒæç²ïŒ for _, p := range results { // ã«ãŒãããšã«ã³ã¡ã³ãæ°ããŠãŒã¶ãŒæ
å ±ãååŸããŠãã db.Get(&p.CommentCount, "SELECT COUNT(*) FROM `comments` WHERE `post_id` = ?" , p.ID) db.Select(&comments, "SELECT * FROM `comments` WHERE `post_id` = ?" , p.ID) // ... } 解決ç ã«ãŒãã®å€åŽã§ãå¿
èŠãªããŒã¿ãäžåºŠã«ãŸãšããŠååŸããæ¹åŒã«å€æŽããŸããã 衚瀺察象ãšãªãæçš¿ã®IDããã¹ãŠéããã SQLã® IN å¥ã䜿ããé¢é£ããã³ã¡ã³ãæ
å ±ããŠãŒã¶ãŒæ
å ±ãäžæ¬ã§ååŸããã ååŸããããŒã¿ãGoã® map ã«æ ŒçŽããã ã«ãŒãã®äžã§ã¯DBã«ã¢ã¯ã»ã¹ããã map ããããŒã¿ãåç
§ããŠæ§é ãçµã¿ç«ãŠãã ãã®ä¿®æ£ã«ãããçºè¡ãããã¯ãšãªæ°ã¯ãæçš¿æ°ã«é¢ãããäžå®ïŒæ°åïŒã«ãŸã§æ¿æžããŸããã Step 2: ããŒã¿ããŒã¹ã€ã³ããã¯ã¹ã®è¿œå - æ€çŽ¢é床ã®åäž èª²é¡ N+1åé¡ã解決ããåŸã次㫠pt-query-digest ã䜿ã£ãŠã¹ããŒã¯ãšãªãã°ãåæãããšãããç¹å®ã®ã¯ãšãªãäŸç¶ãšããŠé
ãããšãããããŸãããç¹ã« ORDER BY created_at DESC ã«ãããœãŒãåŠçãããŒãã«å
šäœãã¹ãã£ã³ïŒãã«ããŒãã«ã¹ãã£ã³ïŒããŠããã倧ããªããã«ããã¯ãšãªã£ãŠããŸããã 解決ç ããã©ãŒãã³ã¹ãæ¹åããããã以äžã®ã€ã³ããã¯ã¹ãããŒã¿ããŒã¹ã«è¿œå ããŸããã -- ãããããŒãžã®æçš¿äžèŠ§è¡šç€ºãé«éå CREATE INDEX idx_posts_created_at ON posts (created_at); -- ãŠãŒã¶ãŒããŒãžã®æçš¿äžèŠ§è¡šç€ºãé«éå CREATE INDEX idx_posts_user_id_created_at ON posts (user_id, created_at); -- ã³ã¡ã³ãäžèЧã®ååŸãé«éå CREATE INDEX idx_comments_post_id_created_at ON comments (post_id, created_at); ããã«ãããæ€çŽ¢ããœãŒããã€ã³ããã¯ã¹ã䜿ã£ãŠå¹ççã«è¡ãããããã«ãªããã¯ãšãªã®å®è¡é床ã倧å¹
ã«åäžããŸããã Step 3: é«ã³ã¹ããªå€éšã³ãã³ãåŒã³åºãã®æé€ - CPUè² è·ã®åæž èª²é¡ CPU䜿çšçã調æ»ããäžã§ããŠãŒã¶ãŒç»é²ããã°ã€ã³æã«åŒã°ãããã¹ã¯ãŒãã®ããã·ã¥ååŠçãããã«ããã¯ãšãªã£ãŠããå¯èœæ§ãæµ®äžããŸãããã³ãŒãã確èªãããšã exec.Command ã䜿ã£ãŠå€éšã® openssl ã³ãã³ããåŒã³åºããŠããŸããã // ä¿®æ£åã® digest 颿° func digest(src string ) string { out, err := exec.Command( "/bin/bash" , "-c" , `... | openssl dgst -sha512 | ...` ).Output() // ... } å€éšããã»ã¹ã®èµ·åã¯éåžžã«é«ã³ã¹ããªåŠçã§ãã 解決ç ãã®åŠçããGoã®æšæºã©ã€ãã©ãª crypto/sha512 ã䜿ã£ãŠãGoã®ããã»ã¹å
ã§å®çµããããã«æžãæããŸããã // ä¿®æ£åŸã® digest 颿° import ( "crypto/sha512" "encoding/hex" ) func digest(src string ) string { hasher := sha512.New() hasher.Write([] byte (src)) return hex.EncodeToString(hasher.Sum( nil )) } ãã®ä¿®æ£ã«ãããããã»ã¹èµ·åã®ãªãŒããŒãããããªããªããCPUè² è·ã倧å¹
ã«åæžã§ããŸããã Step 4: ããŒãžããŒã·ã§ã³ã«ããããŒã¿ååŸã®å¹çå èª²é¡ äž»èŠãªããã«ããã¯ãè§£æ¶ããŠãããšããããŸã§é ããŠããæ°ããªåé¡ãèŠããŠããŸããããããããŒãžã§ã¯20ä»¶ã®æçš¿ã衚瀺ããŠããã«ãããããããSQLã§ã¯å
šä»¶ã®æçš¿ããŒã¿ãååŸããŠãããç¡é§ãªåŠçãè¡ãããŠããŸããã 解決ç ãããããŒãžã®æçš¿ãååŸããã¯ãšãªã« LIMIT 20 ã远å ããŸããã -- ä¿®æ£å SELECT `id`, `user_id`, `body`, `mime`, `created_at` FROM `posts` ORDER BY `created_at` DESC -- ä¿®æ£åŸ SELECT `id`, `user_id`, `body`, `mime`, `created_at` FROM `posts` ORDER BY `created_at` DESC LIMIT 20 ãã®åçŽãªä¿®æ£ã«ãããDBããã¢ããªã±ãŒã·ã§ã³ãžã®ããŒã¿è»¢ééãåæžãããã¡ã¢ãªäœ¿çšéãšDBè² è·ã®äž¡æ¹ãæ¹åãããŸããã ïŒãªããããšã«ãªã£ãŠæ°ã¥ãã®ã§ãããå逿žã¿ãŠãŒã¶ãŒã®ãã£ã«ã¿ãªã³ã°ã«ãã衚瀺æ°äžè¶³ãè£ãããã«ãå°ãå€ã LIMIT 30 ãããã«ããªããšãããŸãããïŒ ããããªãããæ®ã1æéãåã£ããšããã§åé¡ãçºçããŸãããçšæãããããŒã¿ã誀ã£ãŠåé€ããŠããŸã£ãããã§ãã éå¶ã®çããã«å©ããæ±ãããšãããæ°ããEC2ãç«ãŠãŠããã ããŸããã çãããããŒã¿ããã¯ã¢ããã¯åã£ãŠãããŸãããããã çµäºæå»ãå»äžå»ãšè¿«ã£ãŠããäžããªããšãã¹ã³ã¢ã䌞ã°ãããšãææ©ããããŒã¿ããŒã¹ã€ã³ããã¯ã¹ã®è¿œå ãããããŒãžããŒã·ã§ã³ã«ããããŒã¿ååŸã®å¹çåããè¡ããŸããããªããããŒãžããŒã·ã§ã³ã§ã¯ãäœè£ãæã£ãŠ LIMIT 50 ã«ããŠãããŸããã ãŸãšã æçµçã«ãç§ãã¡ã®ããŒã ãã¢ããã㯠21350ç¹ ã§ 43ããŒã äž17äœ ãšããçµæã«ãªããŸããã1æéåŒ±ã®æ Œéã§ã¯ãã®ç¹æ°ãéçã§ãããã ããŒã¿ããã¯ã¢ãããåã£ãŠããªãã£ãããšãäžçªã®åçç¹ã§ãããåæã«å®è·µåœ¢åŒã§åŠã¶ããšãå€ãææçŸ©ãªç ä¿®ã§ããããã²æ¬å®¶ISUCONã«ãªãã³ãžããããšæããŸãã 6/18éå¬ 6åç® çæAIæŽ»çš éçº1éš ããªãã·ã¥ãããã³MS DRMã®æé«ã§ãã ç§ããã¯çæAI掻çšã®ç޹ä»ãããŸãã æ¬ç ä¿®ã¯ã倧ãã2ã€ã®ããŒãã§æ§æãããŠããŸããã 1. ãã€ã¯ããœããã®å€é·ãšAIãšãŒãžã§ã³ãã®æŠå¿µ 2. AIæä»£ã«ããããœãããŠã§ã¢ãšã³ãžãã¢ã®åœ¹å²ã®å€å AIã®é²å AIã®é²åã¯ãç§ãã¡ããã¯ãããžãŒãšé¢ããæ¹æ³ã倧ããå€ããããšããŠããŸãã ãããŸã§ããšã³ãžãã¢ã®ã³ãŒãã£ã³ã°ãã¢ã·ã¹ãããCopilotã®ãããªAIããŒã«ããããŸãããã ãã€ã¯ããœããã§ã¯ã2025幎ãAIãšãŒãžã§ã³ãå
幎ãšäœçœ®ã¥ããèªç¶èšèªã§ããããæäœã管çãå¯èœã«ããæ°ããªææŠãé²ããããŠããŸãã AIãšãŒãžã§ã³ããšã¯ããŠãŒã¶ãŒãã¿ã¹ã¯ãå²ãæ¯ããšèªåŸçã«å®éããã代ç人ãã®ãããªååšã§ãã ãã€ã¯ããœããã¯è€éãªæ¥åãèªåŸçã«ããªããšãŒãžã§ã³ãã®æäŸãå§ããŠãããå°æ¥çã«ã¯ãšãŒãžã§ã³ãå士ã飿ºãããã«ããšãŒãžã§ã³ãã®äžçãæ§æ³ãããŠããŸãã ãšã³ãžãã¢ã®åœ¹å²ã®å€å AIãçºå±ãã以åã®ãšã³ãžãã¢ã¯ã顧客課é¡ã®çºèŠããèšèšãã³ãŒãã£ã³ã°ããã¥ãŒãã³ã°ãã·ã¹ãã ã®ç£èŠã«è³ããŸã§ã人éäž»å°åã§ããããå·¥çšãããªãå¿
èŠããããŸããã ããããAIã®ç»å Žã«ãããããŸã§äººéãè¡ã£ãŠããå€ãã®äœæ¥ãAIã«ä»»ããããããã«ãªããŸããã ä»åŸã¯ãAIã«å¯ŸããŠé©åãªæç€ºãåºãããã®åºåãè©äŸ¡ããæçµçã«ããè¯ãã¢ãŠããããã圢æãã圹å²ãéèŠãšã®ããšã§ããã 誰ãããã«ã¹ã¿ãã¯ãšã³ãžãã¢ã«ãªããå¯èœæ§ãç§ããŠããäžæ¹ã§ããããŸã§ã®ãšã³ãžãã¢ã®ããã«ããããã¿ã¹ã¯ã人æã®ã¿ã§ããªãã®ã§ã¯ãªããAIãæŽ»çšããŠå
šäœã®èª¿åãåããªãããããžã§ã¯ããæšé²ãããããªå§¿å¢ã«å€ãããªããã°ããšã³ãžãã¢ãšããŠçãæ®ãã®ãé£ãããšæããŸããã éçºã¹ã¿ã€ã«ã®å€å GitHubã®çµ±èšã«ãããšãAIãå©çšããéçºè
æ°ã¯2024幎ã®2岿ªæºãã2028幎ã«ã¯9å²è¿ãã«å¢å ãããšäºæž¬ãããŠããŸãã ã€ãŸããæ°å¹ŽåŸã«ã¯ç€ŸäŒå
šäœã§AIã䜿ã£ãŠå¹çåããŠããããšããã ãŒãã¡ã³ããèµ·ããå¯èœæ§ããããšããããšã§ãã çŸç¶ã®AIã«ããéçºãã³ãŒãã£ã³ã°ã«éãããŠããã®ã«å¯ŸããŠãå°æ¥çã«ã¯äŒç»ã»èšèšã»å®è£
ã»ãã¹ãã»éçšãšãã£ããœãããŠã§ã¢éçºã®ã©ã€ããµã€ã¯ã«å
šäœã«æŽ»çšãããããšã§ãéçºã¹ã¿ã€ã«ã倧ããå€ãããšèããããŠããŸãã ã³ãŒãã£ã³ã°ã¹ã¿ã€ã«ã®å€åã§ã¯ãçŸåšã®Copilotã«ããAIæ¯æŽïŒãã¢ããã°ã©ãã³ã°ïŒãããAIãèªåŸçã«äœæ¥ãè¡ãããŒã ã®äžå¡ïŒãã¢ããã°ã©ãã³ã°ïŒãžãšé²ã¿ãããã«2030幎ã«ã¯ãAIãã»ãŒå®å
šã«èªåŸçã«ãœãŒã¹ã³ãŒããå®è£
ããæä»£ãå°æ¥ãããšäºæž¬ãããŠããŸãã ãã®æªæ¥ã§ã¯ããšã³ãžãã¢ã®äž»ãªåœ¹å²ã¯ãèŠä»¶å®çŸ©ããšãAIãäœæãããã®ããã®èŠä»¶ãæºãããŠãããã®ç¢ºèªããšãªãããããã¯ããããŒãžã£ãŒã®ãããªããµãŒãã¹ã»è£œåã®æ¹åæ§ãå®ãã圹å²ãéèŠèŠãããŸãã 人éãããç¶ããããš AIãã³ãŒããçæããæä»£ã«ãããŠãããã®ã³ãŒãã®æ£ãããçè§£ããããã®ããã°ã©ãã³ã°ã®åºç€ç¥èã¯äŸç¶ãšããŠéèŠãšã®ããšã§ããã ããããAIãã³ãŒããæžããŠããŸããããä»åŸã¯å®è·µçãªåãããç¥èãšããŠç¥ã£ãŠããããšãæ±ããããããã«ãªãããã§ãã ãããããéèŠã«ãªã£ãŠããã®ããAIã«æå³ãæ£ç¢ºã«äŒããããã®ãããã³ãããšã³ãžãã¢ãªã³ã°ãã®èœåã§ãã AIã¯æšè«ã®äžã§ãã«ã·ããŒã·ã§ã³ãèµ·ããå¯èœæ§ããããããç®æšãæç¢ºã«å®£èšããèªç¶èšèªã§èŠä»¶ãææãç確ã«èšè¿°ããã¹ãã«ãäžå¯æ¬ ã ãšèª¬æããã ããŸããã ãŸããAIã¯éçå€ãã¹ããå«ççãªå€æãèŠæãªãããæçµçãªãã¹ãã¯äŸç¶ãšããŠäººéãè¡ãã¹ããšã®ããšã§ããã äŒæ¥å«çãã¬ããã³ã¹ãåœã®ããªã·ãŒãªã©ã人éã®äŸ¡å€èгã«åºã¥ã倿ã¯ãä»åŸã人éã®éèŠãªåœ¹å²ãšããŠæ®ããšèããããŠããŸãã ãŸãšã æ¬ç ä¿®ãéããŠãããããæ°å¹Žã®å
ã«AIãèªåŸçã«å®è£
ããæä»£ãæ¥ããšåèªèããŸãããïŒãããã§ã«æ¥ãŠããã®ãããããŸãã...ïŒ AIã¯ç§ãèããŠããããã身è¿ãªãã®ã«ãªããä»åŸã¯ãæ¯ãããããã«AIã䜿ããããšãéèŠã«ãªã£ãŠãããšæããŸããã ãŸãAIã«å¯ŸããŠã¯ãäœãããŠæ¬²ããããšãã£ãæç€ºãç確ã«äŒããèœåãå¿
èŠã«ãªããèšèªåèœåãããå¿
èŠã«ãªã£ãŠãããšæããŸããã ä»åŸã¯AIã䜿ãåããå°ãã§ãå¹çããéçºãã§ããããã«è©Šè¡é¯èª€ããŠãããããšæããŸãã ãããã« å
š6åã®æ°åååç ä¿®ãéããŠãæ¬åœã«ããããã®ããšãåŠã¶ããšãã§ããŸããã æè¡çãªç¥èã¯ãã¡ããã§ãããäœããè¯ãã£ãã®ã¯ä»ç€Ÿã®æ°åãšã³ãžãã¢ã®çãããšåºäŒããããšã§ããåããããªæ©ã¿ãæ±ããŠããããéãèŠç¹ã§ãã®ãèŠãŠããããåºæ¿ããããããšããããããããŸãããç ä¿®åŸãé£çµ¡ãåãåã仲éãã§ããã®ã¯ããã®ç ä¿®ã®å€§ããªåç©«ã®äžã€ã§ãã ãŸããååéã®ç¬¬äžç·ã§æŽ»èºãããŠããè¬åž«ã®æ¹ã
ããçŽæ¥åŠã¹ãã®ã貎éãªçµéšã§ãããææ°æè¡ã®ãã¬ã³ããçŸå Žã§ã®å®è·µçãªæ
å ±ãªã©ãåèæžã§ã¯åŠã¹ãªãçããç¥èãåŸãããšãã§ããŸããã ãã®ç ä¿®ã§åŸãç¥èãçµéšããããŠä»²éãã¡ãšã®ã€ãªããã倧åã«ããªãããããããããšã³ãžãã¢ãšããŠæé·ããŠãããããšæããŸãã æåŸã«ããã®ãããªçŽ æŽãããæ©äŒãæäŸããŠãã ãã£ãæ¥æ¬CTOåäŒã®çæ§ãååã®è¬åž«ã®çæ§ããããŠã¹ãã³ãµãŒãããŠããã ããäŒæ¥æ§ã«å¿ããæè¬ããããŸããããããšãããããŸããïŒ
ã¯ããã« ããã«ã¡ã¯ãæ ªåŒäŒç€ŸãšããªãŒã®2025幎æ°åãšã³ãžãã¢ã§ãã ç§ãã¡ã¯ã2025幎5æãã6æã«ãããŠéå¬ãããæ¥æ¬CTOåäŒäž»å¬ã®æ°åååç ä¿®ã«åå ããŸãããæ¬èšäºã§ã¯ãç ä¿®ã®æŠèŠãååã®è¬çŸ©å
容ããããŠå®éã«åå ããŠåŸãããåŠã³ãæ°ã¥ãã«ã€ããŠã玹ä»ããŸãã 2024å¹Žã®æ°åååç ä¿®åå ã¬ããŒããæ¯éã芧ãã ããïŒ tech.every.tv æ°åååç ä¿®ãšã¯ æ¥æ¬CTOåäŒãäž»å¬ããæ°åååç ä¿®ã¯ãäŒç€Ÿã®æ ãè¶
ããŠæ°åãšã³ãžãã¢ãæ¥çå
šäœã§æé·ã§ããå Žãã€ããããšãç®æããŠããŸããèæ¯ã«ã¯ããšã³ãžãã¢äžè¶³ããã¹ã¿ãŒãã¢ããã»äžå°äŒæ¥ã«ãšã£ãŠæ°åè²æã®ã³ã¹ãã倧ãããšãã£ããæ¥çå
±éã®èª²é¡ããããŸãã ããã§ãããŸããŸãªäŒæ¥ãå°éå®¶ãååããææ°æè¡ãå®è·µçãªã¹ãã«ããã£ãªã¢åœ¢æãã¯ã©ãŠãããµãŒããŒè§£äœãISUCONãçæAIãªã©ãå¹
åºãããŒãã§è¬çŸ©ããã³ãºãªã³ãè¡ãããŸããã 2025幎ã¯äžèšã®ãããªæ¥çšã§éå¬ãããŸããã ç ä¿®å ããŒãã»å
容 è¬åž«/ã¹ãã³ãµãŒ 第1å Google Cloudã®ã¹ãã·ã£ãªã¹ããšåŠã¶ïŒBigQuery & Gemini ã°ãŒã°ã«ã»ã¯ã©ãŠãã»ãžã£ãã³ååäŒç€Ÿ 第2å CTOããæ°åã«åããè¬è©±ãçæAIæä»£ã®ãœãããŠã§ã¢ãšã³ãžãã¢ãšããŠã®åãæ¹ã®æåŸ
å€ æ¥æ¬CTOåäŒ / æ ªåŒäŒç€ŸLayerXãæ ªåŒäŒç€ŸProgate 第3å ïŒååŠè
ã»äžçŽè
åãïŒ AWS JumpStart ã¢ããŸã³ãŠã§ããµãŒãã¹ãžã£ãã³ååäŒç€Ÿ 第3å ïŒäžçŽè
åãïŒ AWSãµãŒãã¹ã䜿ãISUCONã§é«åŸç¹ãåºããïŒ ã¢ããŸã³ãŠã§ããµãŒãã¹ãžã£ãã³ååäŒç€Ÿ / æ¥æ¬CTOåäŒ è¥æãšã³ãžãã¢ã³ãã¥ããã£æå¿ ç¬¬4å ãµãŒããŒè§£äœç ä¿® GMOãããæ ªåŒäŒç€Ÿ 第5å æ¥æ¬CTOåäŒISUCONæ°åç ä¿®ïŒè§£èª¬ïŒâ»äºå課é¡ããã»ã¯ãªã¢å¿
é ïŒ æ ªåŒäŒç€ŸPR TIMES / ãã¯ã·ãæ ªåŒäŒç€Ÿ 第6å çæAIã«é¢ããè¬çŸ© æ¥æ¬ãã€ã¯ããœããæ ªåŒäŒç€Ÿ ç ä¿®ã¯ãªãã©ã€ã³ã§éå¬ãããä»ç€Ÿã®æ°åãšã³ãžãã¢ãšäº€æµããããã³ãã¥ããã£ãåºãããããæ©äŒããããããããŸããã ãã®åãçµã¿ã¯ããšã³ãžãã¢ãšããŠã®ãã£ãªã¢ã®ã¹ã¿ãŒããåŸæŒãããæ¥çå
šäœã®æé·ã«ã€ãªããããšãç®æããŠããŸãã 詳ããã¯ãã¡ããã芧ãã ããã cto-a.org ããããã¯ããããããå°è±¡ã«æ®ã£ãè¬çŸ©ã1ã€ãã€ããã¯ã¢ããããå
容ãåŠã³ã«ã€ããŠã玹ä»ããŠãããŸãã 5/14éå¬ 1åç® Google Cloud ã®ã¹ãã·ã£ãªã¹ããšåŠã¶ïŒ BigQuery & Gemini éçº1éš ããªãã·ã¥ãããã³MS SPã®è°·å£ã§ããç§ããã¯ã°ãŒã°ã«ã»ã¯ã©ãŠãã»ãžã£ãã³ååäŒç€Ÿã«ãŠéå¬ããã第ïŒåç ä¿®ãGoogle Cloud ã®ã¹ãã·ã£ãªã¹ããšåŠã¶ïŒ BigQuery & Geminiãã«ã€ããŠç޹ä»ããŸãã ãã®ç ä¿®ã§ã¯ãGoogle Cloudã®ã¹ãã·ã£ãªã¹ãã®æ¹ã
ããBigQueryãGeminiã«ã€ããŠçŽæ¥åŠã¶è²Žéãªæ©äŒãããã ããŸãããç¹ã«Google Cloudã®ããŒã¿åæã»AIé¢é£ãµãŒãã¹ãäžå¿ã«ãçŸä»£ã®ããŒã¿æŽ»çšã«ãããææ°ã®ã¢ãããŒãã«ã€ããŠè©³ããæããŠããã ããŸããããŸããåŸåã§ã¯NotebookLMã®æŽ»çšæ¹æ³ã«ã€ããŠã°ã«ãŒããã£ã¹ã«ãã·ã§ã³ãè¡ããåå è
åå£«ã§æ§ã
ãªã¢ã€ãã¢ãå
±æããæéããããŸããã BigQueryã®é²åãšããŒã¿æŽ»çšã®æ°æä»£ ãã«ãããŒãžããªããŒã¿ãŠã§ã¢ããŠã¹ Google Cloudã®BigQueryã¯ãµãŒããŒã¬ã¹ã¢ãŒããã¯ãã£ã§æ§ç¯ããããã«ãããŒãžããªããŒã¿ãŠã§ã¢ããŠã¹ãµãŒãã¹ã§ãã åŸæ¥ã®ããŒã¿åæã§ã¯ã€ã³ãã©ã®ç®¡çãã¹ã±ãŒãªã³ã°ã«å€ãã®ãªãœãŒã¹ãå²ãå¿
èŠããããŸãããããããBigQueryãæŽ»çšããããšã§ããããã®éçšè² è·ããè§£æŸãããããŒã¿åæãã®ãã®ã«éäžã§ããããã«ãªããšãã話ããŸãããŠããã ããŸããã Gemini in BigQuery èªç¶èšèªã§ã®ããŒã¿åæ ç ä¿®ã§æãé©ããã®ã¯ãGemini in BigQueryã®èªç¶èšèªã§ã¯ãšãªãèšè¿°ã§ãã驿°çãªæ©èœã§ããã ãããŸã§è€éãªSQLãæžãå¿
èŠããã£ãåæäœæ¥ããæ¥æ¬èªã§ã®è³ªå圢åŒã§å®è¡ã§ããããã«ãªããŸããäŸãã°ãå
æã®ãŠãŒã¶ãŒç»é²æ°ã®æšç§»ãæããŠããšãã£ãèªç¶ãªåããããããé©åãªSQLã¯ãšãªãèªåçæãããŸãã åæã®æ°äž»å ãã®æ©èœã«ãããSQLç¥èãéå®çãªããžãã¹ãµã€ãã®ã¡ã³ããŒã§ããçŽæ¥ããŒã¿ãŠã§ã¢ããŠã¹ã«åãåãããè¡ãããšãã§ããããã«ãªããŸãã ç§ã¯ãããèããŠãçã®æå³ã§ã®ãåæã®æ°äž»åãã ãšæããŸãããçµç¹å
šäœã§ã®ããŒã¿æŽ»çšã¬ãã«ã®åºäžãã«å€§ããè²¢ç®ããã¯ãã ãšæããŸãã NotebookLMã»ãã·ã§ã³ å®è·µçãªAI掻çšäºäŸ NotebookLMã¯ãGoogleãéçºããAIãæŽ»çšãããªãµãŒãã¢ã·ã¹ã¿ã³ãã§ãã¢ã€ãã¢ã®æŽç·ŽãšæŽçããµããŒãããŠãããŸããã¢ããããŒãããææžãããŒã¿ãåºã«ã質åå¿çãèŠçŽãåæãªã©ãè¡ãããšãã§ããŸãã NotebookLM掻çšäºäŸã®ã»ãã·ã§ã³ã§ã¯ãåå è
åå£«ã§æ§ã
ãªæŽ»çšäºäŸãå
±æããããšãã§ããŸããã ææžã®èŠçŽã質åå¿çãã¢ã€ãã¢çæãªã©ãæ¥åžžæ¥åã§å³åº§ã«æŽ»çšã§ããå
·äœçãªäœ¿ãæ¹ãåŠã¶ããšãã§ããéåžžã«å®è·µçãªå
容ã§ããã ã°ã«ãŒããã£ã¹ã«ãã·ã§ã³ã§ã®æŽ»çšã¢ã€ã㢠ã»ãã·ã§ã³ã§ã¯ãã°ã«ãŒãã«åãããŠNotebookLMã®æŽ»çšæ¹æ³ã«ã€ããŠã¢ã€ãã¢ãåºãåãã»ã¯ã·ã§ã³ããããŸããã ãã®äžã§ç¹ã«è峿·±ãã£ãã®ã¯ã äŒè°ã®æåèµ·ãããšNotebookLMãçµã¿åãããæŽ»ç𿹿³ ãšããã¢ã€ãã¢ã§ãã äŒè°å
容ãæåèµ·ããããåŸããã®å
容ãNotebookLMã«è¿œå ããããšã§ãäŒè°äžã«åºãŠããå°éçšèªãäžæãªç¹ã«ã€ããŠåŸãã詳ããNotebookLMã«è³ªåããããšãã§ããã®ã§ã¯ãªããããšããææ¡ãã°ã«ãŒãããåºãŸããã ä»åŸã®æŽ»çšã«åã㊠ããŒã¿ããªãã³ãªæææ±ºå®ã®å é ä»ååŠãã Google Cloudã®ãµãŒãã¹ã掻çšããããšã§ãããŒã¿ã«åºã¥ããæææ±ºå®ã®ã¹ããŒãã倧å¹
ã«åäžãããããšãã§ãããšæããŸãã ç¹ã«Gemini in BigQueryã®èªç¶èšèªã¯ãšãªæ©èœã«ãããããŒã¿åæããæŽå¯ã®ç²åŸããããŠæœçã®ç«æ¡ãŸã§ã®ãµã€ã¯ã«ãåçã«ççž®ã§ããå¯èœæ§ããããŸãã ããŒã å
šäœã§ã®ããŒã¿æŽ»çšã¬ãã«åäž èªç¶èšèªã€ã³ã¿ãŒãã§ãŒã¹ã®æŽ»çšã«ããããããŸã§ããŒã¿åæã«é¢ããããšãå°ãªãã£ãç§ãã¡ã®ããŒã ã¡ã³ããŒãç©æ¥µçã«ããŒã¿ã掻çšã§ããããã«ãªããšæåŸ
ããŠããŸãã ããã«ãããçµç¹å
šäœã§ã®ããŒã¿ãªãã©ã·ãŒåäžãšãããå€è§çãªèŠç¹ããã®åæãå¯èœã«ãªãã®ã§ã¯ãªãã§ããããã ãŸãšã ä»åã®Google Cloudå
¥éã»ãã·ã§ã³ãéããŠãç§ã¯ããŒã¿åæãšAI掻çšã®æ°ããå¯èœæ§ãåŠã¶ããšãã§ããŸããã ç¹ã«å°è±¡çã ã£ãã®ã¯ãæè¡çãªéå£ãäžããããšã§ããã¹ãŠã®ãšã³ãžãã¢ãããã¹ãŠã®ã¡ã³ããŒããããŒã¿ãšAIãæŽ»çšã§ããç°å¢ãæŽãã€ã€ããããšã§ããã ãããã®æè¡ãç©æ¥µçã«åãå
¥ããããšã§ãããªãã·ã¥ãããã³ãµãŒãã¹ã®æŽãªãçºå±ã«è²¢ç®ããŠãããããšæããŸãã 5/21éå¬ 2åç® ãšã³ãžãã¢ã®åãæ¹ã»ãã£ãªã¢ éçº1éš ããªãã·ã¥ãããã³AWG PUã® å²©ïš ã§ãã ç§ããã¯ãšã³ãžãã¢ã®åãæ¹ãšãã£ãªã¢ã«ã€ããŠç޹ä»ããŸãã ãã®ç ä¿®ã¯ã倧ãã2ã€ã®ããŒãã§æ§æãããŠããŸããã ç»å£è
æå± åœ¹è· ã¿ã€ã㫠島接 ç人 æ ªåŒäŒç€ŸProgate CTO AIæä»£ã®æ°åãšã³ãžãã¢ã«å¿
èŠãªå€åãšåŠç¿ æŸæ¬ åæ° æ ªåŒäŒç€ŸLayerX CTO ãã£ãªã¢ã®èãæ¹ããã©ãã¯ãŒã·ãã AIæä»£ã®æ°åãšã³ãžãã¢ã«å¿
èŠãªå€åãšåŠç¿ ãŸãæ ªåŒäŒç€ŸProgate CTO 島接ããã®ã»ãã·ã§ã³ã§ã¯ãAIæä»£ã«ãããæ°åãšã³ãžãã¢ã®å€åãšåŠç¿ã«ã€ããŠã話ãããã ããŸããã ãœãããŠã§ã¢ãããã¯ãéçºã®å€å åŸæ¥ã®ãœãããŠã§ã¢ãããã¯ãéçºã¯ããäŒç»â èšèšâ å®è£
â è©äŸ¡ããšãããããŒã§é²ã¿ãããã°ã©ãã³ã°ã¯ãã®äžã®éå
·ã®1ã€ã§ãããç¹ã«ããžã¥ãã¢ãšã³ãžãã¢(=æ°å)ãã¯ãå
茩ããäžããããã¿ã¹ã¯ã«åºã¥ããŠå®è£
ãããªãããšãã2024幎é ãŸã§ã¯äžè¬çã§ããã ããã2025幎çŸåšã§ã¯ãã®ç¶æ³ã¯å€§ããå€åããŠãããDevinãCursorãClaude Codeãšãã£ãçæAIããŒã«ãç»å Žããããšã§ç°¡åãªã¿ã¹ã¯ã§ããã°AIãå®è£
ã§ããããã«ãªã£ãŠããŸãã ããã«ãããç°¡åãªä»äºã¯ã©ãã©ãæããŠããªãããã®çç±ã§é£ããä»äºãã©ãã©ãæ®ãããšããç¶æ³ãçºçããçµæãšããŠæ°åãšã³ãžãã¢ã®ãªã³ããŒãã£ã³ã°ã«é©ãããç°¡åãªã¿ã¹ã¯ããæžå°ãããšãã課é¡ãçãŸããŠããŸãã çæAIãšä»äºãããŠããäžã§èããããš ããã§çæAIãé²åãããã³ã«è©±é¡ãšããŠããããããçæAIãããã°äººéã¯ä»£æ¿ãããŠããŸãã®ãïŒããšããåãã«å¯Ÿãã島接ããã¯æç¢ºã« NO ãšçããŠããŸãã ãããŸã§ã®ä»äºã®äžéšãAIã«ãã£ãŠä»£æ¿ããããšããŠãã æ¬¡ã«äººéãããã¹ãããšãå¿
ãåºãŠãã ãšãã£ããã£ãŠããŸããã ãããã£ãæä»£ã®æµãã«ããããšã³ãžãã¢ã®å¿æ§ãã«ã€ããŠã島接ããããäœç¹ããäŒãããã ããäžã§å人çã«æãå°è±¡ã«æ®ã£ãã話ã玹ä»ããŸãã AIæä»£ã®ãšã³ãžãã¢ã®å¿æ§ã çŸç¶AIã¯ãŸãã«éæž¡æã§ããç¶æ³ã¯åžžã«å€åããŠãããããããã«è¿œãã€ããããæ¹ãæŽæ°ãç¶ããå¿
èŠããããŸãã ããã¯åŸæ¥ãæ±ããããŠããŸããããå€åã®å€§ãããæ Œæ®µã«å¢ããŠããç¹ãæ°ããéšåã§ãã ãããŠäžã®äžã§AIã®æŽ»çšæ³ã«çããåºãŠããªãããã以äžã®ãµã€ã¯ã«ãç¶ç¶çã«åããŠç¥èŠãã¢ããããŒãããŠããå¿
èŠããããŸãã 屿æé©ãç¡éã«ç©ã¿éãã ïŒèªåèªèº«ã§ãããã詊è¡é¯èª€ãç¹°ãè¿ãããšã ç¥èŠãå
±æããã¢ããããŒããã ïŒåŸãããç¥èŠãããŒã ãçµç¹ãã³ãã¥ããã£ãŒã«éå
ããããšã æè¡ã®é²æ©ã«åãããŠ1ãš2ãç¹°ãè¿ã ã æ°ããæè¡ãåºãŠããããšã«ãã詊ãã ããããŸãã¯å人ã§è©Šè¡é¯èª€ããŠããŒã ãçµç¹å
ã§ãã©ãã·ã¥ã¢ãããããµã€ã¯ã«ãåãããã«ãªãã°ãåŒç€Ÿãæ²ããAIã§éçºã¹ããŒãã10åã«ããããšãå®çŸã§ããã®ã§ã¯ãªãããšæããŸããã ãã£ãªã¢ã®èãæ¹ããã©ãã¯ãŒã·ãã æ ªåŒäŒç€ŸLayerX CTO æŸæ¬ããã®ã»ãã·ã§ã³ã§ã¯ããã£ãªã¢ã®èãæ¹ãšãã©ãã¯ãŒã·ããã«ã€ããŠã話ãããã ããŸããã ãã£ãªã¢ã®èãæ¹ æŸæ¬ããã¯ãã£ãªã¢ãåŸæããªãããã®ãã€ã³ããšããŠä»¥äžã®3ã€ããããŠããŸãã æè³å®¶çæè ã³ãã¥ãã㣠æåã®10幎éã®äœ¿ãæ¹ ããããéŠãåããã»ã©é ·ããå
容ãªã®ã§ãã¹ãŠç޹ä»ããããšããã§ãããããã§ã¯ æè³å®¶çæè ãåãäžããŸãã æè³å®¶çã«ãã£ãªã¢ãèãã ããã§ã¯ãã£ãªã¢ãè³ç£ãšããŠãšãããèªèº«ã®ãã£ãªã¢ãåãªãä»äºã®é£ç¶ã§ã¯ãªãã人çãšããè³ç£ãæå€§åããããã®ãæè³æŽ»åããšæããŸãã ãè³ç£ããšã¯ãéã ãã§ãªããä¿¡çšã»ä¿¡é Œãå¥åº·ã»äœåãå声ãç¥èã»çµéšãæéãªã©å€æ§ãªèŠçŽ ãå«ãŸããŸãã æè³å®¶çæèãšã¯ãç§ãã¡äžäººã²ãšããèªèº«ã®ãè³ç£ããå®ãããã®è³ç£ã䜿ã£ãŠèªåã®ä»®èª¬ã»åŠã³ããæ¹åã«åããŠå¹çããæè³ããããšã§ãã倧ããªè³ç£ãç²åŸããŠãããæè³å®¶ãã§ããããšããèãæ¹ã§ãã ãªã¹ã¯ãšãªã¿ãŒã³ ãã®ãããªèãæ¹ãããäžã§ãã©ããªæææ±ºå®ã«ããªã¹ã¯ãšãªã¿ãŒã³ãååšããããšãæèããå¿
èŠããããŸãã èªåãç®çãšãããªã¿ãŒã³ãåŸãããã«ãæå
ã«ã©ã®ãããªéžæè¢ããããã©ã®ãããªãªã¹ã¯ãããã®ããæŽçããããšã§ãæé©ãªéžæãããããšãã§ããŸãã äžè¬çã«ãªã¹ã¯ãšãªã¿ãŒã³ã¯æ¯äŸããŸãããç¥èéãå¢ããããšã§åããªã¿ãŒã³ãããå°ããªãªã¹ã¯ã§åŸãããšãå¯èœã«ãªããŸãã æ¢çŽ¢ãšåŠã³ ãããŠãã®ç¥èãå¢ãããäžç¢ºå®æ§ãäœäžãããããã«ã¯ç¶ç¶çãªåŠç¿ãµã€ã¯ã«ãäžå¯æ¬ ã§ãã ã仮説ç«ãŠâ è¡åâ æ¯ãè¿ãâ åŠç¿ã»ç¥èåãã®ãµã€ã¯ã«ãåãããšã§ããã粟床ã®é«ãç¶æ³çè§£ãšäžç¢ºå®æ§ã®äœäžã«ã€ãªãããŸãã ãã©ã³ã¹ã·ãŒããšããŒããã©ãªãª ãšã¯ãããããããããšãã¹ãŠã«æè³ããããšã¯ã§ããŸããã èªèº«ã®æã€æè³å¯èœãªè³ç£ïŒãéãæéãäœåãä¿¡çšãªã©ïŒãã©ã®ããã«é
åããããšãã£ããã©ã³ã¹ã·ãŒããäœæããäœåãªè³ç£ïŒç¹ã«æéïŒã«å¯ŸããŠã©ãã«ã©ãã ã䜿ãããæ±ºããããšã§ããã£ãªã¢ã®æ¹åæ§ãæç¢ºã«ãªããŸãã ã¬ãã¬ããž ãããŠæã«ã¯ã¬ãã¬ããžãããããªã¹ã¯ããšã£ãŠãã倧ããæè³ãããããšãå¿
èŠã§ãã æå
ã®è³ç£ãç¹ã«ç¥èãçµéšãšãã£ãã¹ããã¯ãããæ¹åãžæè³ããéçšå¹çãé«ãŸãææ®µã远ããããããšã§ãã倧ããªãªã¿ãŒã³ãåŸãããšãã§ããŸãã äŸãšããŠã以äžã®ãããªé
ç®ãæããããŠããŸããã ãéã§æéãç¥èã»çµéšãè²·ãïŒå®¶äºã®ã¢ãŠããœãŒã¹ãææããŒã«ã®æŽ»çšïŒ ããŒã ã§åãïŒäººã«ã¬ãã¬ããžããããïŒ ä¿¡çšã®ã¬ãã¬ããžïŒã¹ãã«ãäžè¶³ããŠããŠãä¿¡é Œãããã°ä»»ããŠããããïŒ ãããã£ãã¬ãã¬ããžããããããšã§ããã£ãªã¢ã®ã¹ããŒããå éãããããšãã§ããŸãã ããããªã¹ã¯ãåãããããšå€±æããå¯èœæ§ããããããèªèº«ã®åããããªã¹ã¯åºŠåãã«å¿ããŠèª¿æŽãå¿
èŠã§ãã ãŸãšã AIæä»£ã®ãã£ãªã¢ãèããäžã§ã®æéãšãªãã話ã島接ããããèãããšãã§ããŠæ¬åœã«ããã£ããªãšæã£ãŠããŸãã ãŸãæŸæ¬ããã«çºè¡šããã ããè³æã¯ä»¥åããæèŠããŠããããã¡ããç§èªèº«ã®ãã£ãªã¢æéã«å€§ããªåœ±é¿ãäžããŠãããŠããã®ã§ä»åã®ç ä¿®ã§çŽæ¥ã話ã䌺ãããšãã§ããŠãšãŠãå¬ããã£ãã§ãã AIæä»£ã®æ³¢ã«ä¹ãé
ããªããããªãã£ãªã¢æŠç¥ãèãç¶ããããšæããŸãïŒ 5/27ã»28éå¬ 3åç® AWS JumpStart éçº1éš ããªãã·ã¥ãããã³MS DRMã® æ±ïš ãšéçº1éšããªãã·ã¥ãããã³AWGãã«ã·ã«ã® èµ€å· ã§ãïŒç§ãã¡ããã¯ãAWS JumpStartã«ã€ããŠç޹ä»ããŸãïŒ AWS JumpStart 2025ã¯ãAWSååŠè
ã®ãšã³ãžãã¢ã察象ãšããå®è·µçãªç ä¿®ããã°ã©ã ã§ãã ãã®ããã°ã©ã ã®ãŽãŒã«ã¯ãäžè¬çãªã¢ãŒããã¯ãã£ã®çè§£ãAWSã³ã¢ãµãŒãã¹ã®æŠèŠãšãã®éžå®åºæºã®ææ¡ããããŠAWSã¢ãŒããã¯ãã£å³äœæã®æµããåŠã¶ããšã§ãã ã¿ã€ã ã¹ã±ãžã¥ãŒã« 2æ¥éã®ã¹ã±ãžã¥ãŒã«ã¯ä»¥äžã®éãã§ãã1æ¥ç®ã¯åº§åŠãšAWSç°å¢ã®æ§ç¯ãè¡ããã³ãºãªã³ã2æ¥ç®ã¯1æ¥ç®ã®å
容ãèžãŸããããå®è·µçãªã¢ãŒããã¯ãã£æ€èšãè¡ããŸããã 1æ¥ç® ãŸã1æ¥ç®ã®å
容ã«ã€ããŠç޹ä»ããŸãã è¬çŸ© è¬çŸ©ã§ã¯ãã¢ãŒããã¯ãã£ã³ã°ã®ã³ããã«ã€ããŠè§£èª¬ããã ããŸãããWebãµãŒãã¹æ§ç¯ã«ããããã§ãŒãºããšã®AWSãµãŒãã¹éžå®ã®åºç€ããã·ã¹ãã ã¹ã±ãŒã«æã®èª²é¡ãšå¯Ÿçã«ã€ããŠåŠã³ãŸããã è¬çŸ©ã®å
容ãç°¡æœã«ãŸãšãããšä»¥äžã®ããã«ãªããŸãã ãã§ãŒãºïŒ: ãããã¿ã€ãïŒã100äººïŒ æ§æ: Route 53 â EC2 â RDS ç¹åŸŽ: ã·ã³ãã«ã»å®äŸ¡ãå¯çšæ§ã¯éèŠããªã ãã§ãŒãº2: äžè¬å
¬éïŒ100人ã10,000äººïŒ æ§æ: Route 53 â ALB â EC2ïŒãã«ãAZïŒ â RDSïŒãã«ãAZïŒ æ¹åç¹: - Application Load Balancerã«ããè² è·åæ£ - è€æ°AZã§ã®åé·å - Auto Scalingã®å°å
¥ ãã§ãŒãº3: å€§èŠæš¡åïŒ10,000人ã1,000,000äººïŒ æ§æ: CloudFront â ALB â Auto Scaling Group â Aurora + ãªãŒãã¬ããªã« + ElastiCache æ¹åç¹: - CloudFront: éçã³ã³ãã³ãã®CDNé
ä¿¡ - Aurora: 髿§èœDBããªãŒãã¬ããªã«ã§èªã¿åãè² è·åæ£ - ElastiCache: ã€ã³ã¡ã¢ãªãã£ãã·ã¥ã§DBè² è·è»œæž ãã§ãŒãº4: è¶
å€§èŠæš¡ïŒ1,000,000人以äžïŒ ç¹åŸŽ: èšæž¬ã»åæã»æ¹åãµã€ã¯ã«ã®éèŠ æ¹åç¹: - ã¢ããªã±ãŒã·ã§ã³æé©å - DBã·ã£ãŒãã£ã³ã°ãNoSQLæŽ»çš - ãã€ã¯ããµãŒãã¹å - Infrastructure as CodeãCI/CDå°å
¥ ã·ã¹ãã æ§ç¯æã¯ãæåããé床ã«äœã蟌ãŸããèŠä»¶ãæºããã·ã³ãã«ãªèšèšããå§ããããšããããŠèšæž¬ã»åæã»æ¹åã®ãµã€ã¯ã«ãç¶ç¶ããããšãéèŠã§ãããšåŠã³ãŸããã ãã³ãºãªã³ ãã³ãºãªã³ã§ã¯ãå®éã«AWSç°å¢ã®æ§ç¯ãäœéšããŸããã2ã3人ã®ããŒã ã§ãAWSç°å¢ãæäœãããã©ã€ããŒãšãæé æžã確èªããªããæç€ºãåºãããã²ãŒã¿ãŒãããŒããŒã·ã§ã³ããªããé²ãããã¢ãããã°ã©ãã³ã°åœ¢åŒã§å®æœãããŸããã ååã®ãã³ãºãªã³ã§ã¯ã以äžã®ãããªã·ã³ãã«ãªã¢ãŒããã¯ãã£ãæ§ç¯ããŸãããå®éã«æãåããããšã§ãAWSç°å¢æ§ç¯ã®çè§£ãæ·±ãŸããŸããã åŸåã®ãã³ãºãªã³ã§ã¯ãããå®è·µçãªã¢ãŒããã¯ãã£ãæ§ç¯ããŸãããALBã«ããè² è·åæ£ããDBã®ãã§ã€ã«ãªãŒããŒæ©èœã«ããå¯çšæ§ã®æ
ä¿ãªã©ãååãããé«åºŠãªæ§æãšãªã£ãŠããŸãã ãŸããã¢ãŒããã¯ãã£ãæ§ç¯ããŠçµããã§ã¯ãªããECSã¿ã¹ã¯ã忢ãããéã®æåãªã©ã確èªããå®éã«é害ãçºçããå Žåã«ã©ã®ããã«å¯çšæ§ãä¿ãããããäœéšã§ããŸããã ãŸãšã AWS JumpStart 1æ¥ç®ãéããŠãåãªãAWSãµãŒãã¹ã®åŠç¿ã«ãšã©ãŸãããããªããã®ãµãŒãã¹ãéžå®ããã®ãããã©ã®ããã«ã¢ãŒããã¯ãã£ãèšèšãã¹ããããšãã£ãã¢ãŒããã¯ãã£ã³ã°ã®æèããã»ã¹ã®åºç€ãåŠã¶ããšãã§ããŸããã ãŸããã¢ãããã°ã©ãã³ã°åœ¢åŒã§åŠã¶ããšã§ãããŒã å
ã§æŽ»çºã«æèŠäº€æããæãåãããšã§çè§£ãããæ·±ããããšãã§ããŸãããããã§åŠãã ããšãåå°ã«ãä»åŸã®æ¥åã§ãèŠä»¶ã«åã£ãã¢ãŒããã¯ãã£ãèããŠãããããšæããŸãã 2æ¥ç® 2æ¥ç®ã¯ããå®è·µçãªå
容ã§ãäžãããããé¡ã«æ²¿ã£ãã¢ãŒããã¯ãã£ãèšèšãã課é¡ã«åãçµã¿ãŸããã ã¢ãŒããã¯ãã£ã®æ€èšïŒåäººïŒ ãŸãã¯å人ã§ã¢ãŒããã¯ãã£ãæ€èšããæéãèšããããŸãããäžãããããé¡ã«å¯ŸããŠã以äžã®ãããªæ§æãèããŸããã ãã«ãAZæ§æã§åé·å ããã³ããšã³ãïŒReactïŒTypeScriptïŒãããžã§ã¯ããECS Fargateã§å®è¡ãCDNã®ããã«CloudFrontã䜿çšãéçã³ã³ãã³ãã¯S3ããé
ä¿¡ ããã¯ãšã³ãïŒJava/Spring Bootã¢ããªã±ãŒã·ã§ã³ãECS Fargateã§å®è¡ãæéã«å¿ããŠãªãŒãã¹ã±ãŒãªã³ã° ããŒã¿ããŒã¹ïŒAuroraãã¬ããªã«ã远å ããŒããã©ã³ãµãŒïŒApplication Load BalancerïŒALBïŒ ãã°ïŒCloudWatchãšKinesisçµç±ã§ãS3ã«ä¿å DNSïŒRoute 53 1æ¥ç®ã§åŠãã å
容ãããšã«ãåºæ¬çãªWebãµãŒãã¹ã®ã¢ãŒããã¯ãã£ã«å¿
èŠãªããšã¯ç¶²çŸ
ããããšãã§ãããšæããŸãïŒ ã¢ãŒããã¯ãã£ã®æ€èšïŒã°ã«ãŒãïŒ ãŸããã¡ã³ããŒãããããèããã¢ãŒããã¯ãã£ãå
±æããç¹åŸŽãšæ¹åãã¹ãç¹ãå
±æããŠãããŸããã ãã®åŸåã¢ãŒããã¯ãã£ã®è¯ããšãããéããŠã以äžã®èŠçŽ ã远å ãããŸããã - ãã£ãã·ã¥ïŒElastiCache - ãã¥ãŒïŒSQS - å€éšãšã®æ¥ç¶ïŒNAT Gateway - èªèšŒïŒCognito ããã§ãæã
ã®ã¢ãŒããã¯ãã£å³ã¯å®æããŸããïŒ NAT Gatewayãçµç±ããå€éšAPIãšã®é£æºãäžå¯§ã«æããã®ãè¯ãã£ããšæã£ãŠããŸãïŒ çºè¡šäŒ çºè¡šã§ã¯3ããŒã ãéžã°ããããããã®ã¢ãŒããã¯ãã£ã«ã€ããŠèª¬æãããŠããŸããã ç§ã®ããŒã ã¯éžã°ããŸããã§ããããåŒç€Ÿã¡ã³ããŒã®ããããŒã ãéžã°ããã®ã§ãã®ã¢ãŒããã¯ãã£ãèŒããŠãããŸãïŒ å人çã«ã¯ãæ®æ®µã®å®äŸäŒè°ã§ããã·ã¥ããŒããèŠãæ©äŒãå€ãã®ã§ãããã·ã¥ããŒãäœæã®æ©æ§ãããã®ãè¯ããªãšæããŸããïŒ æèŠªäŒ å€ã®æèŠªäŒã§ã¯ãã¯ããã«24æ°åã®å
茩ããAWSã«é¢ããLTãè¡ãããŸããã ãã®äžã§ãã·ããžãŒããŒã±ãã£ã³ã°æ ªåŒäŒç€Ÿã®æšå±±ããããAWSã®ã³ã¹ã管çã«é¢ããã話ãããŠããã ããŸããã ãã®è©±ãèããŠãæ©éå人éçºã®ãããžã§ã¯ãã«ã³ã¹ãã¢ã©ãŒããèšå®ããŠãããŸããïŒ ãã®åŸã¯ãäžç·ã«ã¢ãŒããã¯ãã£ãäœã£ãããŒã ã¡ã³ããŒãä»ã®äŒç€Ÿã®äººãã¡ãšãããã亀æµããããšãã§ããŸããïŒ ãã®æã«ç¥ãåã£ãã¡ã³ããŒãšäºæ¬¡äŒã«è¡ã£ããã茪èªäŒãå§ããããšãåæã®ç¹ããã®è¯ããæ¹ããŠå®æããŸããã ãŸãšã ãã®ç ä¿®ãéããŠãå®éã®ã¢ãŒããã¯ãæ¥åãäœéšããããšãã§ããŸããã å®éã®ããžãã¹èŠä»¶ãæè¡çã«ã©ãå®çŸããããªã©ãæ·±ãèããã®ã¯ãšãŠã楜ããã£ãã§ãã ããã«é¢çœãã£ãã®ã¯ã宿ããã¢ãŒããã¯ãã£ãã°ã«ãŒãã«ãã£ãŠå
šãéã£ãããšã§ãã äžã«ã¯ãµãŒããŒãç«ãŠãã«ãå
šãŠãLambdaã§ãµãŒããŒã¬ã¹ã«åŠçãããšããææŠçãªã¢ãŒããã¯ãã£ããããŸããã ä»åŸã¯ãã䜿ã£ãããšãããAWSãµãŒãã¹ãå¢ãããŠããããã§ãïŒ å®åã§ã¯ãã¡ãããå人éçºã§ãè²ã
ãªAWSãµãŒãã¹ã詊ããŠã¿ãããšæããŸãïŒ ãããã« ãããŸã§ã2025幎æ°åååç ä¿®ã®ååïŒç¬¬1åã第3åïŒã«ã€ããŠã玹ä»ããŸããã åŸåã§ã¯ã第4åãã第6åã®ç ä¿®å
容ã«ã€ããŠãäŒãããŸãã ãã²ãåŸåã®èšäºãã芧ãã ããïŒ tech.every.tv