GPT飿ºã¢ããªéçºæã®å¿ é ç¥èãRAGããŒããã解説ãããæŠèŠïŒPythonã³ãŒãäŸ
ããã«ã¡ã¯ãããããã§ãã
ä»åã®èšäºã§ã¯ãçæAIçéã§ã¯ããªã浞éããŠãã RAG ã«ã€ããŠæ¹ããŠè§£èª¬ããŠãããŸãã
ãäœäºç®ã§èšèªã¢ãã«ã䜿ã£ãã¢ããªãéçºãããããšãããšãã«çã£å ã«éžæè¢ã«äžããRAGã§ãããç§èªèº«ãRAGã䜿ã£ãã¢ããªã±ãŒã·ã§ã³ã®å®è£ ãæ¥åã®äžã§äœåºŠãè¡ã£ãŠããŸããã
ä»åã¯ãã®ç¥èŠãã·ã§ã¢åºæ¥ãã°å¹žãã§ãã
RAGïŒRetrieval-Augmented Generation)ãšã¯
ãŸãã ããããRAGãšã¯äœããïŒ ãšãããšããããèŠãŠãããŸãããã
RAGïŒRetrieval-Augmented Generation) ã¯èªç¶èšèªåŠçïŒNLPïŒãšç¹ã«èšèªã¢ãã«ã®éçºã«ãããŠäœ¿çšãããæè¡ã§ãã
ãã®æè¡ã¯ãå€§èŠæš¡ãªèšèªã¢ãã«ãçæããããã¹ãã®å質ãšé¢é£æ§ãåäžãããããã«ãå€éšã®æ å ±æºããã®æ å ±ãååŸïŒretrievalïŒããŠå©çšããŸãã
èŠã¯ãChatGPTãªã©ã®èšèªã¢ãã«ã«ç¹æ®ãªç¥èã«é¢é£ããæ å ±ãåãããæè¡ã ãšèšããŸããã
çãããåç¥ã®éããChatGPTãªã©ã®å€§èŠæš¡èšèªã¢ãã«ïŒLLMïŒã¯ã人éãšéè²ãªãã¬ãã«ã§èªç¶èšèªã話ãããšãåºæ¥ãŸãã
ããããäŸãã°
ããããããšãã人ç©ã®å¥œããªé£ã¹ç©ã¯ïŒã
ãšè³ªåããŠãChatGPTã¯ïŒåœç¶ã®ããšãªããïŒçããããšãåºæ¥ãŸããã
ããã¯ãChatGPTã®åŠç¿ããŒã¿ã«å«ãŸããªãæ å ±ã«ã€ããŠè³ªåããŠããããã§ãã
ããããæ¢åã®ããŒã¿ããŒã¹ãªã©ããäœããã®æ¹æ³ã§
ãããããã®å¥œããªé£ã¹ç©ã¯ã«ã¬ãŒã§ããã
ãšããæ
å ±ãäºåã«ååŸã§ããŠããã°è©±ã¯éã£ãŠããŸãã
ãã®å Žåã以äžã®ããã«ä»ã®DBãããšã£ãŠããæ
å ±ãçµã¿èŸŒãã ããã³ãããChatGPTã«æããããšã§æ£ããçããåŸãããšãæ¥ãŸãã
以äžã®è³ªåã«çããŠãã ããã
ãã ããåŸè¿°ããåèæ
å ±ã®éšåãèžãŸããŠåçããŠãã ããã
ã»è³ªå
ãããããšãã人ç©ã®å¥œããªé£ã¹ç©ã¯ïŒ
[åèæ
å ±]
ã»ããããã®å¥œããªé£ã¹ç©ã¯ã«ã¬ãŒã§ãã
åºåã¯é£ã¹ç©åã®ã¿ãç°¡æœã«çããŠãã ããã
Output(é£ã¹ç©åã®ã¿):
ãã®ããã«è³ªåããããšã§GPTã¯ãã«ã¬ãŒããšããåçãããããšãåºæ¥ãŸãã

RAGãæå¹ãªã¢ããªã±ãŒã·ã§ã³
以äžã®æŠèŠãããåãããšãããRAGã¯å€§å ã®èšèªã¢ãã«ã«å«ãŸããªããããªç¬èªã®ç¥èãèªç¶èšèªãšããŠãŠãŒã¶ãŒã«è¿ãããšãæ±ããããã¢ããªã±ãŒã·ã§ã³éçºã«æŽ»çšã§ããŸãã
äŸãã°ã以äžã®ãããªäŸãæããããŸãã
- 瀟å è³æã«é¢ããæ å ±ãçãããã£ããããã
- ç¹æ®ãªæ¥ççšèªã«å¯Ÿå¿ãããã£ããããã
- ã«ã¹ã¿ããŒå¯Ÿå¿çšã®ãã£ããããã
ä»ã«ããŸã ãŸã ããã§ãããã
ããããçŸå®ã«ã¢ããªã±ãŒã·ã§ã³ãéçºããéã«ã¯ãïŒç¿»èš³ã¢ããªãªã©ãé€ããŠïŒäžè¬çãªç¥èã ããLLMã«åãããŠããã°OKãšããã±ãŒã¹ã¯ããŸããããŸããã
ãããããŠãŒã¶ãŒããŒã¿ã瀟å
ããŒã¿ãªã©ã®ã¯ããŒãºããªããŒã¿ã«é¢ããããšãåããããå Žåãå€ãã¯ãã§ãã
RAGã®æ³šç®åºŠãé«ãã®ã«ã¯ããããã£ãèæ¯ããããŸãã
RAGã®ã¡ãªãã
次ã«RAGã®ã¡ãªãããšãã¡ãªãããèŠãŠãããŸãããã
ãŸããã¡ãªãããšããŠæããããã®ãã
- äœã³ã¹ãã§å®è¡ã§ãã
- æ¢åã®èšèªã¢ãã«ã掻çšããŠããã®ã§åºç€æ§èœãé«ã
ãšããç¹ã§ãã
åæãšããŠãRAGã§ã¯ãªãç¬èªã®åŠç¿ããŒã¿ãæ··ã蟌ãã§æ°ãã«ã€ãããå€§èŠæš¡èšèªã¢ãã«ãç ç©¶ã»èšèšã»èšç·ŽããããšãããšãGPUãµãŒããŒã®è³Œå
¥ãå°éç¥èãæã£ããšã³ãžãã¢ã®éçšãªã©ã§äœãèŠç©ãã£ãŠãååäœã®æè³ãå¿
èŠã«ãªããŸãã
ïŒç§ãå€åããäŒç€Ÿã®äŸã§ããµãŒããŒã®è³Œå
¥è²»çšã¯ååäœã§ãããïŒ
æ¢åã¢ãã«ã®fine-tuningãè¡ãã«çããããšãã£ãéžæè¢ãåã£ããšããŠããããã¯ã·ã§ã³ã¬ãã«ã®ã¯ãªãªãã£ã«éããã«ã¯æéçã«ãééçã«ã倧ããªã³ã¹ããèŠæ±ãããããšã«ãªããŸãã
ããã«ãããã ãã®æè³ããããšããŠãæ¢åã®GPT3.5, GPT4ãGemini proã«å¹æµãã粟床ã®LLMãåŠç¿ãããã®ã¯éåžžã«é£æåºŠãé«ãã§ãã
以äžã®èæ¯ãããå人ã®å Žåã¯2024幎2æçŸåšã ãšãŸãç¬èªLLMãåŠç¿ãããã®ã¯ã³ã¹ãçã«ããããç¡çãªè©±ã§ãå€ããå°ãªããRAGã«é ŒããããåŸãªãç¶æ³ã§ãã
ãŸããæ³äººã§ãã£ãŠããããã«ãããªãæ°ååãæ°çŸååã®ã¬ãã«ã§ã®æè³ã«ã¯èžã¿åããªãããšããäŒæ¥ãå€ãã§ãããã
ããã§ãåãæ¢ããRAGã䜿ã£ãŠPOCãããŠã¿ããããšãããã¿ãŒã³ãå€ãã§ãã
äŸãã°OpenAIã® gpt-3.5-turbo-0125 ã¢ãã«ã§ã¯1000ããŒã¯ã³ã®äœ¿çšã§
Inputã 0.0005ãã« ãoutputã 0.0015ãã« ãšãªã£ãŠããŸãïŒ2024/02ïŒã
ä»®ã«æ¥æ¬èª1æåã1.5ããŒã¯ã³ã ãšãããšãå ¥åã»åºåã§ãããã1äžæåãã€äœ¿ã£ãå Žåã§ã課éé¡ã¯0.03ãã«ã§ãã
ãã«åã150å/USDã ãšãããšããã¯4.5åã«çžåœããŸãã
ãã®ããã«RAGã¯äŸ¡æ Œé¢ã§éåžžã«å§ããããããšãã¡ãªããã§ãã
ãŸããå€ãã®å ŽåRAGã«çµã¿èŸŒãã®ã¯GPTãªã©ã®æ¢åLLMã«ãªããšæããŸããã ãããã¯äœäŸ¡æ Œã§äœ¿çšã§ããã®ã«ãé¢ãããæ§èœã¯æ¡éãã«é«ã ã§ãã
ã²ãšæ¡ãã®çµç¹ä»¥å€ã¯ãããããæ®éã«èšèªã¢ãã«ã«èšèãåããããšããéšåã«ãããŠOpenAIãGoogleãéçºããŠããã¢ãã«ãè¶ ããæ§èœãåºãããšã¯é£ããã§ãããã
RGAã®ãã¡ãªãã
äžæ¹ã§RAGã«ã¯ãã¡ãªããããããŸãã
- æ¢åããŒã¿ãæ€çŽ¢ããä»çµã¿ã¥ãããå¿ èŠ
- åŠçã«æéããããããšããã
- ããã³ããã«å·¥å€«ãæ±ãããã
- ã»ãã¥ãªãã£èŠä»¶ã«åŒã£ãããå¯èœæ§ããã
ãŸããRAGã䜿ãå Žåã¯LLMã«äžããåç
§ããŒã¿ãæ€çŽ¢ããã·ã¹ãã ãååšããŠããå¿
èŠããããŸãã
åé ã®äŸã§ããã°ããŠãŒã¶ãŒãã
ãããããšãã人ç©ã®å¥œããªé£ã¹ç©ã¯ïŒ
ãšãã質åãæ¥ããšãã«ã
ããããã®å¥œããªé£ã¹ç©ã¯ã«ã¬ãŒã§ãã
ãšããæ å ±ãæ€çŽ¢ããŠæã£ãŠããããããªä»çµã¿ãå¿ èŠã§ãã
äžè¬çã«LLMã«å
¥åã§ããããã³ããã®é·ãïŒããŒã¯ã³é·ïŒã«ã¯å¶éãããã®ã§ãçãèŠç©ãã£ãŠãæ€çŽ¢çµæäžäœ10ä»¶ãããã«æ£ããæ
å ±ãå
¥ã£ãŠããªããšããã€å Žåãå€ãã§ãããã
ãŸããäŸãã°ç€Ÿå
質åããããªã©ãäœãããå Žåãæ€çŽ¢å¯Ÿè±¡ã«ãããããŒã¿ã瀟å
ã«æ£è²¡ããŠããŠæ€çŽ¢çšããŒã¿ããŒã¹ãããã®ãããããé£ããããšããã±ãŒã¹ããããŸãã
ãããã£ãå Žåãã©ãããŠãæ³¥èãæ€çŽ¢ãšã³ãžã³äœãã®å·¥çšãçºçããŠããŸããŸãã
ãããŠãå®åã§ã¯ãã®æ€çŽ¢ã·ã¹ãã ã®ç²ŸåºŠãåºãã®ãäžã
é£ãããã®ã§ãã
äŸãã°ç§ã以ååãçµãã äŸã§ã¯RAGå
šäœãšããŠããŸãæ©èœããªãã£ãã±ãŒã¹ã®å
ã®7å²çšåºŠã§é©åãªããŒã¿æ€çŽ¢ã«å€±æããŠããŸããã
忥è
ã®è©±ãèããŠãç¶æ³ã¯äŒŒãããã£ããã§ããã±ãŒã¹ãå€ããRAGã§ã¯æ€çŽ¢ç²ŸåºŠãæ
ä¿ããããšãäžã€ã®ããŒãã€ã³ãã«ãªããšæãããŸãã
ãŸããLLMããã åãããã ãã§ãªããã®å段ã«é¢é£ããŒã¿ã®æ€çŽ¢åŠçãå
¥ãã®ã§ã·ã¹ãã å
šäœãšããŠã®å®å®æ§ãé床ãäœäžããŸãã
ç¹ã«ãçŸç¶ãŠãŒã¶ãŒããã®ã¯ãšãªïŒåãããå
容ïŒã«å¯ŸããŠæå³çã«è¿ãããŒã¿ãåŒã£åŒµã£ãŠããããã«OpenAIEmbeddingsãªã©ã®æ©æ¢°åŠç¿ãããã¢ãã«ã§ãŠãŒã¶ãŒã¯ãšãªããã¯ãã«åããã±ãŒã¹ãå€ãã®ã§ããããã®èŸºãã®åŠçãè¡ãéã³ã³ãäœç§ãã®æéçãã¹ãèæ
®ããå¿
èŠããããŸãã
æéçèŠä»¶ãå³ããã¯ãŒã¯ããŒãã®å Žåã¯æ³šæãå¿
èŠã§ãã
ããã«ãããã³ããã«å·¥å€«ãæ±ããããããšãå€ãã®ããã¡ãªãããšèšãããããããŸããã
äŸãã°æ€çŽ¢çšã®æ å ±ãwebã¹ã¯ã¬ã€ãã³ã°ãªã©ã§éã«äœã£ãŠããå ŽåãRAGã§æ€çŽ¢ããŠããããŒã¿ãå®å šãªèªç¶æã«ãªã£ãŠããªãããšãå€ãã§ãã
äŸãã°ã
ããããããšãã人ç©ã¯ããªããã³ãšããAIç§æžã®LINEå ¬åŒã¢ã«ãŠã³ããéå¶ããŠããã
ãšããå®å šãªæã§ã¯ãªã
ãããªããã³ éçšã®è©±ïŒããããããããã
ãšãã埮åŠãªæç« ïŒãã£ã³ã¯ïŒãæ€çŽ¢ããŠããŠGPTã«æž¡ããçµæãåºåã厩å£ãããšãããã¿ãŒã³ãªã©ãæããããŸãã
ã¡ãªã¿ã«ãããã£ãå Žåãããã³ããã«
以äžã®åç
§æ
å ±ã¯webããã¹ã¯ã¬ã€ãã³ã°ããŠæ¥ããã®ã§ãã
ãã®ããæ¥æ¬èªãšããŠäžå®å
šãªåœ¢åŒã«ãªã£ãŠããå¯èœæ§ããããŸããããã®å Žåã§ãæ£ç¢ºãªæ¥æ¬èªãåºåããããæ³šæããŠãã ããã
åç
§æ
å ±ãšããŠæå³ãåããªããã®ã¯ç¡èŠããŠæ§ããŸãã
ãªã©ãšãã£ãæèšãçµã¿èŸŒããšåºåãæ¹åããããšãå€ãã§ãã
æåŸã«ãRAGã䜿ãé(ãšãããæ£ç¢ºã«ãããšæ¢åã®èšèªã¢ãã«ã䜿ã£ãŠã¢ããªäœæããæå šè¬)ã¯ã»ãã¥ãªãã£çãªèŠä»¶ã«åŒã£ãããããšãå€ãã§ãã
RAGã§æ¢åã®LLMã䜿çšããå Žåãæµ·å€ãµãŒããŒïŒOpenAI, Azure, Googleãªã©ã®ãµãŒããŒïŒãžããã³ãããæããªããã°ãããªãããšãå€ã ãããŸãã
ãã®éãäŒæ¥ã«ãã£ãŠã¯
- ãã¯ã€ããªã¹ãã«æ²èŒãããŠããäŒæ¥ã«ããããŒã¿ãæµããŠã¯ãªããªã
- æµ·å€ãµãŒããŒãšã®éä¿¡ã¯äžåŸçŠæ¢
ãªã©ã®å¶éãããããšãå€ãã§ãã
ãäœã³ã¹ãã§RAGãåºæ¥ãããšã¯ããã£ãŠãããã ãã©ã瀟å
èŠçŽçã«é£ãããã ããªãã
ãšãã声ã¯å®åã§ã¯ããèããšããã§ãã
ãŸããããã¡ã®äŒç€Ÿã¯ç€Ÿå èŠçŽäžOpenAIã¯NGã ãã©Azure OpenAIã¯OKã ãïŒãã¿ãããªã±ãŒã¹ãæå€ãšå€ããå¥¥ãæ·±ãïŒïŒïŒãšããã§ããããŸãã
æ€çŽ¢ã³ã³ããŒãã³ãïŒRetrieverïŒã®äŸ
ããŠãããã§ã¯RAGã®ä»çµã¿ã®å ãRetrieverïŒæ å ±ãæ¢åããŒã¿ããŒã¹ããæ€çŽ¢ããŠããéšåïŒã§äœ¿çšå¯èœãªéžæè¢ãæŽçããŠã¿ãããšæããŸãã
RAGã§ã¯å€§åæãšããŠãRetrieverã§ã¯ãŠãŒã¶ãŒã¯ãšãªãäŸãã°
ããããããšãã人ç©ã®å¥œããªé£ã¹ç©ã¯ïŒã
ããæå³çã«è¿ãããŒã¿ãæ€çŽ¢ããããšãèŠæ±ãããŸãã
ãæå³çã«è¿ãããšããèšèãã©ã®ããã«è§£éãããã¯èŠä»¶ã«ããç°ãªããŸãã
äŸãã°ãæ¥ççšèªã瀟å
å°éçšèªã®æå³ãGPTã«æãããå Žåã§ããã°ããã«ã¬ãŒã©ã€ã¹ãã«å¯ŸããŠãã«ã¬ãŒã»ã©ã€ã¹ããæ€çŽ¢ããŠãããããªãããŸãæ€çŽ¢ã§ååãªã±ãŒã¹ãæ³å®ãããŸãã
ãšã¯ãããäžè¬çã«ã¯å
ã«ãå°ãè§Šãããã¯ãã«æ€çŽ¢ãçšããã±ãŒã¹ãå€ãããšæããŸãã
- ãŠãŒã¶ãŒãçºããã¯ãšãªãOpenAIEmbeddingsãªã©ã§ãã¯ãã«åãã
- ãã¯ãã«åããã¯ãšãªãšæ¢åã®ããŒã¿ããŒã¹ã«ä¿åãããŠããããŒã¿ïŒãã¡ãã¯ããããããã¯ãã«åãããŠããïŒãšã®ã³ãµã€ã³é¡äŒŒåºŠãªã©ããè¿åããŒã¿ãæœåº
- æœåºããããŒã¿ãpromptã«åã蟌ã¿LLMã«æãã
ãšãããããŒã§ããã
2ã§çšãããã¯ãã«ããŒã¿ãä¿åããŠããDBãšããŠã¯ãäŸãã°äžèšã®ãããªãã®ãæããããŸãã
| ãã³ã㌠| ãµãŒãã¹å |
|---|---|
| Azure | AI Search |
| AWS | OpenSearch, Kendra |
| GCP | Vertex AI Matching Engine |
| ãã®ä» | Pinecone, FAISSïŒã©ã€ãã©ãªïŒ |
ã¡ãªã¿ã«ããã®å
ç§ãå®åã§äœ¿ã£ãããšãããã®ã¯Azure AI SearchãšOpensearch, Pineconeã§ãã
ã©ãã«å¯ŸããŠãæ©èœçã«äžè¶³ãæããããšã¯ããŸããããŸããã§ããã
ä»ã®äœ¿çšãµãŒãã¹ãšã®å Œãåãã§çŸåšã¯AI Searchããã䜿ã£ãŠããŸãããåèªã®èŠä»¶ãç¶æ³ã«åãããŠå¥œããªãã®ãéžã¶ãšè¯ããšæããŸãã
ä»ã«ãæ¡åŒµçãªæ©èœã䜿ãã°ãPostgresQLãªã©ã®RDBã«ãã¯ãã«åãããã®ãä¿åããããRDBããè¿åæ€çŽ¢ããããšãå¯èœã§ãã
åèïŒ Amazon RDS for PostgreSQL with pgvector
ã¡ãªã¿ã«ããã®èšäºã®åŸåã§ç޹ä»ããäºå®ã®RAGã®pythonã³ãŒããµã³ãã«ã§ã¯ãããã®DBãµãŒãã¹ã®ä»£æ¿ãšããŠãããŒã«ã«ãã¡ã€ã«ã«ãã¯ãã«æ å ±ããã®ãŸãŸæžã蟌ãããšã§ç䌌DBãšããŠäœ¿ããŸãã
äœããã£ãŠããã®ãã誰ã®ç®ã«ãæçœã«ãªãããšãšãäžèšã«æããDBãæ¬æ Œçã«äœ¿ããšãªããšèª²éãå¿ èŠã«ãªã£ãããDBæäŸãµãŒãã¹åŽã®ã»ããã¢ãããå¿ èŠã«ãªãã®ã§ãã®æ¹éãšããŸããã
çæã³ã³ããŒãã³ãïŒGenerator)ã®äŸ
RAGã«ãããçæã³ã³ããŒãã³ããšã¯åºæ¬çã«ã¯å€§èŠæš¡èšèªã¢ãã«ïŒLLMïŒãæããŸãã
äŸãã°ä»¥äžã®ãããªãã®ã§ããã
| æäŸå | åç§° | ç¹åŸŽ |
|---|---|---|
| OpenAI | GPT | GPT-3.5ãšGPT-4ã¯ããããé床ãšç²ŸåºŠã«åŒ·ã¿ããã |
| Gemini | Gemini proã¯GPT-3.5ã«å¯ŸããŠå šãèŠå£ãããªãæ§èœ | |
| Meta | Llama2 | ãªãŒãã³ãœãŒã¹ |
| åèª | ç¬èªã¢ãã«ãéçº | å人ãå°èŠæš¡æ³äººã ãšèŠä»¶ã«ãã£ãŠã¯çŸå®çã§ã¯ãªã |
Llamaã®å Žåã¯ããŒã«ã«ã«ã¢ãã«ãèœãšããŠããŠåããããšãã£ãããšãå¯èœã§ãããæè»œã«RAGã詊ãããå Žåã¯ãŸãOpenAIã®GPT3.5-turboãªã©ã®APIã詊ããŠã¿ãã®ã楜ã ãšæããŸãã
äžå¿èª²éããããšã¯ããå°ã詊ããããã§ããã°ããããæ°ååçšåºŠã®ç¯å²ã«åãŸãã¯ãã§ãã
OpenAI APIã§GPTã䜿ã£ãŠRAGãå®è·µããŠã¿ã
ããŠãããããã¯å®éã«ã³ãŒããåãããŠRAGã®æŠèŠãæŽãã§ãããŸãããã
æçµçã«äœããã®ã¯ä»¥äžã®ãããªãããŒã蟿ãããšãšããŸãã
[äžæºå]
- OpenAI APIkeyã®çºè¡ïŒopenAIã®å ¬åŒããŒãžããååŸããŠãããŠãã ãããèšäºäžã§ã¯æãäžããŸãããïŒ
- å¿ èŠã©ã€ãã©ãªãªã©ã®ã€ã³ã¹ããŒã«
[å®è£ ]
- ãã¹ãçšããŒã¿ããã¯ãã«åããå ããã¹ããšå ±ã«jsonãã¡ã€ã«ãšããŠä¿å(ç䌌DB)
- ãŠãŒã¶ãŒã¯ãšãªãåãåã£ãããããããã¯ãã«å
- ç䌌DBããããŒã¿ãèªã¿åãããã¯ãã«è¿åæ€çŽ¢ãè¡ã
- æ€çŽ¢çµæãããã³ããã«åã蟌ã¿GPTã«æãã
- åŸãåçã衚瀺ãã
ãªããã³ãŒãã¯ç§ã®githubãªããžããªã§å ¬éããŠããŸãã
æºåç·š
ãŸããå¿ èŠã©ã€ãã©ãªãã€ã³ã¹ããŒã«ããŠãããŸãããã
å¿ èŠã«å¿ããŠä»®æ³ç°å¢ãªã©ãäœããŸãã
python3 -m venv venv
source venv/bin/activate
äžèšã®requirements.txtãã¡ã€ã«ãäœæããŸãã
openai==1.10.0
numpy==1.26.4
pipã§ã€ã³ã¹ããŒã«ããŸãã
pip install -r requirements.txt
ããã§å¿ èŠã©ã€ãã©ãªãã€ã³ã¹ããŒã«åºæ¥ãŸããã
å®è£ ç·š
ããŠããŸãã¯æ¬¡ã®ãã¡ã€ã«ãäœæãå®è¡ããŸãããã
泚ïŒä»¥äžã®ã³ãŒããå®è¡ããããšã§è»œåŸ®ã§ãã課éãçºçããããšã«æ³šæããŠãã ããã
from abc import ABC, abstractmethod
import json
import openai
# ããŒã¿ããã¯ãã«åããã¢ãžã¥ãŒã«ã®ã€ã³ã¿ãŒãã§ãŒã¹
class Embedder(ABC):
@abstractmethod
def embed(self, texts: list[str]) -> list[list[float]]:
raise NotImplementedError
@abstractmethod
def save(self, texts: list[str], filename: str) -> bool:
raise NotImplementedError
# Embedderã€ã³ã¿ãŒãã§ãŒã¹ã®å®è£
class OpenAIEmbedder(Embedder):
def __init__(self, api_key: str):
openai.api_key = api_key
def embed(self, texts: list[str]) -> list[list[float]]:
# openai 1.10.0 ã§åäœç¢ºèª
response = openai.embeddings.create(input=texts, model="text-embedding-3-small")
# ã¬ã¹ãã³ã¹ãããã¯ãã«ãæœåº
return [data.embedding for data in response.data]
def save(self, texts: list[str], filename: str) -> bool:
vectors = self.embed(texts)
data_to_save = [
{"id": idx, "text": text, "vector": vector}
for idx, (text, vector) in enumerate(zip(texts, vectors))
]
with open(filename, "w", encoding="utf-8") as f:
json.dump(data_to_save, f, ensure_ascii=False, indent=4)
print(f"{filename} ã«ä¿åãããŸããã")
return True
if __name__ == "__main__":
import os
texts = [
"äœè€äžéã¯ãæ±äº¬çãŸãã®35æ³ã®ããã°ã©ããŒã§ããè¶£å³ã¯åçæ®åœ±ãšãã€ãã³ã°ãæ°ããæè¡ãåŠã¶ããšã«æ
ç±ã泚ãã§ããŸãã",
"éŽæšè±åã¯ãåæµ·éåºèº«ã®28æ³ã®ã€ã©ã¹ãã¬ãŒã¿ãŒã§ããç«ãäºå¹é£Œã£ãŠãããèªç¶ãšåç©ãæããå¿åªãã人ç©ã§ãã",
"ç°äžå¥äºã¯ã倧éªã§å°ããªã«ãã§ãçµå¶ãã45æ³ã®èµ·æ¥å®¶ã§ããã³ãŒããŒã«å¯Ÿããæ·±ãç¥èãšæ
ç±ãæã¡ãå°å瀟äŒã«è²¢ç®ããŠããŸãã",
"å±±æ¬çŸå²ã¯ãçŠå²¡çåºèº«ã®22æ³ã®å€§åŠçã§ããæ³åŸãå°æ»ããŠãããå°æ¥ã¯äººæš©ã«é¢ããä»äºã«å°±ããããšèããŠããŸãã",
"äŒè€é«å¿ã¯ãé·éçã®å±±ã®äžã§è²ã£ã30æ³ã®åçå®¶ã§ããèªç¶ã®çŸãããæããããšã«ç¹åããåœå
å€ã§å±ç€ºäŒãéå¬ããŠããŸãã",
"å°æç±çŽåã¯ãæ²çžçåºèº«ã®40æ³ã®å°åŠæ ¡æåž«ã§ããåã©ããã¡ã«èžè¡ãšæåã®å€§åããæããããšã«çããããæããŠããŸãã",
]
# OpenAI APIããŒãäºåã«ç°å¢å€æ°ã«ã»ããããŠãã ããã
api_key = os.getenv("OPENAI_API_KEY")
if api_key is None:
raise ValueError("APIããŒãã»ãããããŠããŸããã")
embedder = OpenAIEmbedder(api_key)
embedder.save(texts, "sample_data.json")
èŠãŠã®éãããµã³ãã«ãšããŠæ¶ç©ºã®äººç©ãã¡ã«é¢ããæç« ããã¯ãã«åããŠããŒã«ã«ã®jsonãã¡ã€ã«ã«ç䌌DBãšããŠä¿åãããã®ã§ãã
ãŸããç°å¢å€æ°ã«openaiã®APIããŒãèšå®ããŠå®è¡ãããšãããŒã«ã«ã«ãã¯ãã«ããŒã¿ãšå
±ã«ãã¡ã€ã«ãä¿åãããŠããã®ã確èªã§ããã§ãããã
export OPENAI_API_KEY=sk-**************************
python3 embedder.py
次ã¯ä¿åããããŒã¿ããè¿åæ€çŽ¢ãè¡ãã³ãŒããäœæããŸãããã
åãã£ã¬ã¯ããªã«äžèšã®ãã¡ã€ã«ãäœæããŠãã ããã
from abc import ABC, abstractmethod
import json
import numpy as np
class NearestNeighborsFinder(ABC):
@abstractmethod
def find_nearest(self, vector: list[float], topk: int = 3) -> list[dict]:
pass
class CosineNearestNeighborsFinder(NearestNeighborsFinder):
def __init__(self, data_file: str):
self.data = self._load_data(data_file)
def _load_data(self, data_file: str) -> list[dict]:
with open(data_file, "r", encoding="utf-8") as f:
return json.load(f)
def _cosine_similarity(self, vec1: list[float], vec2: list[float]) -> float:
vec1 = np.array(vec1)
vec2 = np.array(vec2)
# openAI embeddingã®ãã¯ãã«ã察象ã«ããå Žåã¯æ£èŠåãããŠãããããnp.dot(vec1, vec2) ã ãã§ãè¯ã
return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
def find_nearest(self, vector: list[float], topk: int = 1) -> list[dict]:
similarities = [
(idx, self._cosine_similarity(vector, item["vector"]))
for idx, item in enumerate(self.data)
]
# é¡äŒŒåºŠãé«ãé ã«ãœãŒã
sorted_similarities = sorted(similarities, key=lambda x: x[1], reverse=True)
# Top-Kã®çµæãè¿ã
return [self.data[idx] for idx, _ in sorted_similarities[:topk]]
èŠãŠã®éããæ€çŽ¢æã¯å
šããŒã¿ã«å¯ŸããŠãŠãŒã¶ãŒã¯ãšãªãembeddingãããã®ãšã®cosé¡äŒŒåºŠãäžã€äžã€èšç®ããã®ã§å¹çã¯æªãã§ãã
ãŸããèšç®çµæããœãŒããããšããã§ãO(nlogn)ã®èšç®éãçºçããŠããŸãã
ãšã¯ããããµã³ãã«ãšããŠã¯ããã§ååã§ãããã
æåŸã«gptãšã®é£æºãè¡ãããã®ã¢ãžã¥ãŒã«chatBot.pyãäœæããŸãã
from abc import ABC, abstractmethod
from openai import OpenAI
class ChatBot(ABC):
@abstractmethod
def generate_response(self, user_query: str, refs: list[str]) -> str:
pass
class GPTBasedChatBot(ChatBot):
def __init__(self):
self.client = OpenAI()
def generate_response(self, user_query: str, refs: list[str]) -> str:
# GPTã«ããå¿çãçæ
context = "\n".join(refs) + "\n"
prompt = f"以äžã®æ
å ±ã«åºã¥ããŠãŠãŒã¶ãŒã®è³ªåã«çããŠãã ãã:\n\n{context}\n\n質å: {user_query}\nçã:"
print("#" * 30)
print("#" * 30)
print(f"\nprompt:\n {prompt}\n")
print("#" * 30)
print("#" * 30)
completion = self.client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{
"role": "user",
"content": prompt,
},
],
)
return completion.choices[0].message.content
ãããã®ã¢ãžã¥ãŒã«ã以äžã®ããã«çµ±åããŸããã
import os
from embedder import OpenAIEmbedder
from searcher import CosineNearestNeighborsFinder
from chatBot import GPTBasedChatBot
# OpenAI APIããŒãäºåã«ç°å¢å€æ°ã«ã»ããããŠãã ããã
api_key = os.getenv("OPENAI_API_KEY")
if api_key is None:
raise ValueError("APIããŒãã»ãããããŠããŸããã")
def main():
embedder = OpenAIEmbedder(api_key)
searcher = CosineNearestNeighborsFinder("sample_data.json")
user_query: str = "ã¢ãŒããæããããå
çãæ¢ããŠããŸã"
user_query_vector: list[float] = embedder.embed([user_query])[0]
search_results: list[dict] = searcher.find_nearest(user_query_vector, topk=2)
chat_bot = GPTBasedChatBot()
response: str = chat_bot.generate_response(
user_query, [search_result["text"] for search_result in search_results]
)
print("*" * 30)
print("*" * 30)
print("ãAIã®è¿çã")
print(response)
if __name__ == "__main__":
main()
å
šäœã®ã¹ããŒãªãŒãšããŠã¯ãããŒã«ã«ã«ä¿åããæ¶ç©ºã®äººç©æ
å ±ãåç
§ããªããããŠãŒã¶ãŒããã®"ã¢ãŒããæããããå
çãæ¢ããŠããŸã"ãšããã¯ãšãªã«å¿çããããšããç«ãŠä»ãã§ããã
æ©éå®è¡ããŠã¿ãŸãã
python3 main.py
ç§ã®ç°å¢ã§ã¯ãAIã®åçã¯ä»¥äžã®ããã«ãªããŸããã
å°æç±çŽåå
çã¯ãèžè¡ãšæåã®å€§åããåã©ããã¡ã«æããããšã«çããããæããŠããŸãã®ã§ãããªããæ¢ããŠããã¢ãŒããæããå
çãšããŠãŽã£ããã§ãããäœãã®å°åãåŠæ ¡ã«ãããŠãå°æç±çŽåå
çãšã®é¢è«ãæ¡çšã®çžè«ãããããããŸãã
ç¡äºãç䌌DBã®å 容ãèžãŸããåçãåºæ¥ãŸããã

printãããããã³ãããèŠããšããããã¯ãã«è¿åæ€çŽ¢ã§å°æãããšäŒè€ãããéžã°ããŠããããšãããããŸãã
RAGã®åé¡ç¹ãšãã®å ææ¡
以äžãRAGã®æŠèŠãšãªããŸãã
ããããã¯çµã³ãšããŠãå®åã§RAGã䜿ãäžã§æãã課é¡ç¹ãšãã®å
ææ¡ãªã©ãèããŠãããããšæããŸãã
RAGã®éç
ä»åæ±ã£ããããªç°¡åãªäŸã ãšæ±ããåçãåŸãããŸããããå®åã§ã¯å¿
ãããããã§ã¯ãããŸããã
ç§ã®ãããŸã§ã®çµéšã ãšç¹ã«ãã¯ãã«æ€çŽ¢ã«å€±æããŠåŸæ®µã®GPTåŠçãããŸãè¡ããªãã±ãŒã¹ãç®ç«ã¡ãŸããã
äŸãã°
- ãã¯ãã«æ€çŽ¢æã®topkãå¢ãã
ãªã©ã®æ¹æ³ã§ãã®åé¡ãç·©åã§ããã¯ãã§ãããã®åããã³ããã«æž¡ãããŒã¯ã³ãå¢ããã®ã§ã³ã¹ãã¯äžãããŸãã
RAGãããŸãåäœãããããã«
RAGãããŸãåäœãããããã«ã¯
- ããŒã¿ä¿åæã®å·¥å€«
- ããŒã¿æ€çŽ¢æã®å·¥å€«
ãããããå¿ èŠãšãªããŸãã
åè ã«ã€ããŠã¯ä»¥äžã®ãããªæœçãæå¹ã«ãªãã±ãŒã¹ãå€ãã£ãã§ãã
- webããŒãžããã¡ã€ã«ã®ã³ã³ãã³ããæ©æ¢°çã«åè§£ããŠæ€çŽ¢å¯Ÿè±¡ã®ããŒã¿ã«äœ¿ã£ãŠããå Žåã¯ãæŽåœ¢ããŠããããŒã¿æå ¥ããããã«ããã
- ç¹ã«ããŒã¿ãçŽæ¥äººã®ç®ã§èŠãŠãååŸã®æèãåãèœã¡ããããªçްåãã®åœ¢åŒã§ä¿åãããŠããªãããã§ãã¯ããã
- äžèšã«åé¡ãããå Žåã¯ååŸã®æèãæã£ãç¶æ ã§ããŒã¿ä¿åãããããã«å·¥å€«ããã
ãŸããä¿åæã«ããŒã¿ãå å·¥ããŠããã®ãè¯ããããããŸããã
ãæ¥æ¬ã§äžçªé«ãå±±ã¯å¯å£«å±±ã§ãã â ãæ¥æ¬ã§äžçªé«ãå±±ã¯ãªãã§ããïŒã
ãšãã倿ãããŠãããŠããæ¥æ¬ã§äžçªé«ãå±±ã¯ãªãã§ããïŒããšããããŒã¿ãæ€çŽ¢ããããããã·ã¹ãã çã«ãã®åçïŒã€ãŸããå¯å£«å±±ã§ããïŒãã»ããã§LLMã«æž¡ãããšãã£ãæ¹æ³ã§ããã
ãã¯ãã«æ€çŽ¢ã¯ãããŸã§æå³çã«äŒŒããããªæåå£«ãæ€çŽ¢ããã®ã§ãŠãŒã¶ãŒã¯ãšãªãšæ€çŽ¢å¯Ÿè±¡æãäž¡æ¹ãšã質åæã§ãã£ãã»ãã粟床ãåäžããããšãäºæ³ãããŸãã
åŸè ã«ã€ããŠã¯ãäŸãã°
- DBãã«ããŽãªæ¯ã«åå²ããŠãããŠããŠãŒã¶ãŒã¯ãšãªã«å¯ŸããŠã©ã®ã«ããŽãªã®DBã«å¯ŸããŠæ€çŽ¢ãããããå°ãã
ãšãã£ãææ³ãªã©ãèããããŸãã
ãã®ãããªå€æ®µééžå¥ãGPT-4ã䜿ã£ãŠè¡ãã°æçµçã«ãã¯ãã«æ€çŽ¢ãè¡ã察象ããŒã¿æ°ãããªãæžããããšæåŸ ã§ããŸãïŒãã ãããã®ååŠçæéãšã³ã¹ããäžããããšã«æ³šæïŒã
ãããã«ããéã®åŒŸäžžã¯ç¡ãã®ã§ãèŠä»¶ã«ç §ãããŠæé©ãªãœãªã¥ãŒã·ã§ã³ãåžžã«èããŠããå¿ èŠããããŸãã
æåŸã¡ãã£ãšéããŠããŸããŸããããä»åŸãªã«ãã¢ããããŒããããã°ç§ã®Xã¢ã«ãŠã³ããªã©ã§ãçºä¿¡ããŠããäºå®ãªã®ã§è¯ããã°ãã©ããŒããŠããã ãããšå¹žãã§ãã
远èšïŒãã°å¯Ÿå¿
ãã®èšäºãèªãã æ¹ãããembedder.pyã®å®è¡æã«ä»¥äžã®ãšã©ãŒãçºçããŠãããšã®å ±åããããŸããã
TypeError: Client.__init__() got an unexpected keyword argument 'proxies'
ãã®å Žåã¯openaiã©ã€ãã©ãªã®ããŒãžã§ã³ãäžæŽåã§ããå¯èœæ§ãããã®ã§ã
äžèšãå®è¡ããŠäŸãã° 1.55.3ãã€ã³ã¹ããŒã«ããŠã¿ãŠãã ããã
pip install --force-reinstall -v "openai==1.55.3"
Discussion
è¯èšäºããããšãããããŸãã
æåŸã®ãã ãã§ããã ãããã®ååŠçæéãšã³ã¹ããäžããããšã«æ³šæããšããã®ã§ãããã³ã¹ãã¯ã©ããã£ãã³ã¹ããäžããããšãèããããã§ããããïŒ
倿®µééžå¥ãGPT-4ã§è¡ãå Žåããã®éžå¥èªäœã«GPTã®ããŒã¯ã³èª²éãçºçãããšãããã¥ã¢ã³ã¹ã§ããã
ãããã¯ãDBã®èšèšãè€éåããããšã§ã€ã³ãã©ã³ã¹ããå¢å€§ãããšããããšãïŒå Žåã«ãã£ãŠã¯ïŒèµ·ãããããªãšæããŸãã
ãåçããããšãããããŸããïŒ