ã»ãã³ãã£ãã¯æ€çŽ¢ãè£ããã€ããªããæ€çŽ¢ïŒBM25ã»RRFã®å®è£ ãšåçŸçè©äŸ¡
ã»ãã³ãã£ãã¯æ€çŽ¢ã§åçªããšã©ãŒã³ãŒããåãããŒããšãã¯ãBM25ãšãã¯ãã«æ€çŽ¢ãçµã¿åãããŸããRRFãšéã¿ä»ãã¹ã³ã¢ã®éããElasticsearchã»Weaviateã»Pineconeã§ã®å®è£ æ¹éãæ£è§£ã©ãã«ä»ãã¯ãšãªã§recall@kãæ¯èŒããæ¢åæ€çŽ¢ã®å質ãå®ããªããå°å ¥ã倿ããæé ã解説ããŸãã
å ¬éæ¥

ã»ãã³ãã£ãã¯æ€çŽ¢ã§è³ªåã®æå³ã¯æããããã®ã«ã補åã³ãŒããåãããŒããŠããŸãããããªå Žåã¯ãåã蟌ã¿ã¢ãã«ã眮ãæããåã«ãããŒã¯ãŒãã§æ€çŽ¢ããçµè·¯ã远å ããŠã¿ãŠãã ããããã€ããªããæ€çŽ¢ã¯ãããŒã¯ãŒãäžèŽãšãã¯ãã«é¡äŒŒåºŠããåŸã2ã€ã®åè£ãªã¹ããã1ã€ã®ã©ã³ãã³ã°ã«ãŸãšããä»çµã¿ã§ãããŸãã¯Reciprocal Rank FusionïŒRRFïŒãã詊ããèå¥åã®å®å šäžèŽã¯æç€ºçã«æ±ããŸããæ£è§£ã©ãã«ä»ãã®ã¯ãšãªã§åçŸçãäžããããããŸã§ããŸãæ©èœããŠããæ€çŽ¢ãæãªãããªããšç¢ºèªã§ããå Žåã«ããã®å€æŽãæ¡çšããŸãã
ããã¥ã¡ã³ãã®ç¢ºèªæ¥ïŒ2026幎10æ24æ¥ã 以äžã®å®è£ ã¬ã€ãã¯ãç¢ºèªæç¹ã®ElasticsearchãWeaviateãPineconeã®ããã¥ã¡ã³ãã«åºã¥ããŠããŸããè©äŸ¡ã®èšå®å€ã¯ãæ€èšŒãå§ããããã®ææ¡ã§ãã宿ž¬ããæ¹åå¹ ããã³ããŒã®ãã³ãããŒã¯ã§ã¯ãããŸããã
ã»ãã³ãã£ãã¯æ€çŽ¢ãè£ããã€ããªããæ€çŽ¢ãšã¯ïŒ
ãã€ããªããæ€çŽ¢ã¯ãæåã©ããã®è¡šçŸãšæå³ã®äž¡æ¹ãæ€çŽ¢çµæã«åæ ããŸãããã®èšäºã§æ±ãæ§æã§ã¯ãããŒã¯ãŒãæ€çŽ¢ãšãã¯ãã«æ€çŽ¢ãããããé äœä»ãã®ãªã¹ããè¿ããèåææ³ã§äž¡è ãçµ±åããŸããWeaviateã®è§£èª¬ã§ãããã®2ã€ã®æ€çŽ¢çµè·¯ãšçµ±åã®ä»çµã¿ã説æãããŠããŸãã
åãåãåããã2人ã®èª¿æ»æ åœè ã«èª¿ã¹ãŠãããå Žé¢ãèããŠã¿ãŠãã ãããäžæ¹ã¯çŽ¢åŒã䜿ããåç§°ããšã©ãŒæååããã®ãŸãŸäžèŽããæ å ±ãæ¢ããŸããããäžæ¹ã¯å 容ãèªã¿ãå¥ã®èšãæ¹ã§æžãããåçãå«ããŠãé¢é£ããæ å ±ãæ¢ããŸããã©ã¡ãã1人ã«äž¡æ¹ãä»»ããã®ã§ã¯ãªãããããããèŠã€ããåè£ããŸãšããããã§ãã
BM25ã¯ãã¯ãšãªã«å«ãŸããèªãææžã«ã©ã®ããã«åºçŸãããã«åºã¥ããŠã¹ã³ã¢ãä»ãããèªåœããŒã¹ã®ã©ã³ãã³ã°é¢æ°ã§ããã¹ã³ã¢ã«ã¯èªã®åºçŸé »åºŠãšææžã®é·ãã圱é¿ãããããäžèŽããåèªãåçŽã«æ°ãããããæçšã§ããElasticsearchã¯ãããã¹ãé¡äŒŒåºŠã®æ¢å®æ¹åŒã«BM25ã䜿ã£ãŠããŸãããããã®èŠçŽ ã¯Elasticã®é¡äŒŒåºŠãªãã¡ã¬ã³ã¹ã§ç¢ºèªã§ããŸãã
ãã¯ãã«æ€çŽ¢ã¯ãå å®¹ãæ°å€ã§è¡šããåã蟌ã¿ãæ¯èŒããæå³ã®è¿ãæ å ±ãèŠã€ããŸããããšãã°ãäœåºŠããã°ã¢ãŠããããããšãã質åããã衚çŸãç°ãªããã»ãã·ã§ã³ã®æå¹æéåããã®ææžãèŠã€ããããŸãããã®æ€çŽ¢çµè·¯ã¯ãã»ãã³ãã£ãã¯æ€çŽ¢ã®ã¬ã€ãã§è§£èª¬ããŠããŸãã
äŸãšããŠãERR_SESSION_EXPIRED after loginãšããã¯ãšãªãèããŸããããŒã¯ãŒãæ€çŽ¢ã®çµè·¯ã¯ããã®ãšã©ãŒæååãã®ãã®ãå«ãæ
å ±ãçµæã«å±ããŸããæå³ã«åºã¥ãæ€çŽ¢ã®çµè·¯ã¯ãèªèšŒã»ãã·ã§ã³ããã®æŽæ°ã«é¢ãã説æãåè£ã«å ããããŸããæåŸã«èååŠçãé äœã決ããŸããããã¯ç®æãåäœã®äŸã§ãããæªèšå®ã®ã¹ãã¢ãç¹å®ã®é äœãè¿ããšä¿èšŒãããã®ã§ã¯ãããŸããã

ãã€ããªããæ€çŽ¢ã§ããèå¥åã®å®å šäžèŽã«ã¯æç¢ºãªã«ãŒã«ãå¿ èŠã§ã
ããŒã¯ãŒãæ€çŽ¢ã®çµè·¯ãå ããŠããèå¥åã®å®å šäžèŽãä¿èšŒãããããã§ã¯ãããŸãããæååãæ€çŽ¢å¯èœãªããŒã¯ã³ã«å€æããããã¹ãè§£æã«ãã£ãŠãã€ã³ããã¯ã¹ã«ç»é²ããã圢ãå€ããããšããããŸããããšãã°Elasticã®æšæºã¢ãã©ã€ã¶ãŒã¯ãå ¬åŒã®äŸã§ãã€ãã³ä»ãã®èªå¥ãåå²ããŠããŸããèšå®ããã¢ãã©ã€ã¶ãŒããèªåãã¡ã®SKUããšã©ãŒã³ãŒããã©ãåŠçããã確èªããŠãã ãããæšæºã¢ãã©ã€ã¶ãŒã®ããã¥ã¡ã³ãã
èå¥åã®è¡šèšã«ãã£ãŠå¯Ÿè±¡ãäžæã«æ±ºãŸãå Žåã¯ãå®å
šäžèŽçšã®å°çšãã£ãŒã«ãã«ä¿åããŸããElasticã¯ãããããæ§é åãããå€ã®ããã«keywordãã£ãŒã«ããçšæããŠããŸããæ¶ç©ºã®SKUã§ããAX-BLUEãæ€çŽ¢ãããšãã«ã説ææã䌌ãŠãããããšãã£ãŠããã€ã®éã«ãAX-GREENã®ããããã«å€ãã£ãŠã¯ãããŸãããkeywordãã£ãŒã«ãã®ãªãã¡ã¬ã³ã¹ã
倿ã®åºæºïŒ äžæã®èå¥åãèªèããã察å¿ããé ç®ãè¿ãããšãã補å仿§ã§ããã°ãå®å šäžèŽã®æ€çŽ¢ã«æ¯ãåããŸãããã®ååã®ãã©ãã«ã·ã¥ãŒãã£ã³ã°æ å ±ãæ¢ãå Žåãªã©ãèå¥åãšããåºãç®çãçµã¿åããã£ã質åã«ã¯ããã€ããªããæ€çŽ¢ã®ã©ã³ãã³ã°ã䜿ããŸãã
RRFãšéã¿ä»ãã¹ã³ã¢ïŒæ€çŽ¢çµæãã©ãçµ±åããã
ç°ãªãã¹ã³ã¢å°ºåºŠã調æŽããã«æ¯èŒã®åºæºãäœããããªãããŸãã¯Reciprocal Rank Fusionã䜿ããŸãããã©ã³ã¹èª¿æŽã«äœ¿ããæ£è§£ã©ãã«ããããã¹ã³ã¢å士ã®å·®ãæ®ãããçç±ããããªããéã¿ä»ãã¹ã³ã¢ãæ€èšããŸãã
RRFã¯ã¹ã³ã¢ã®å€ã§ã¯ãªãé äœã䜿ããŸã
**Reciprocal Rank FusionïŒRRFïŒ**ã¯ãããææžãçŸããåãªã¹ãããã®å¯äžãåèšããŸãã
RRFïŒææžïŒ= åæ€çŽ¢çµæãªã¹ãã«ããã1 / (c + é äœ)ã®åèšã
é äœã¯1äœããæ°ããŸãããããªã¹ãã«ææžããªããã°ããã®ãªã¹ãããã®å¯äžã¯ãããŸãããGordon V. CormackãCharles L. A. ClarkeãStefan BÃŒttcherã¯ãSIGIR 2009ã®è«æã§RRFãçºè¡šããŸãããå®éšã§ã¯å®æ°ã60ã«åºå®ããŠããŸããè«æã§ã¯ãã®å®æ°ãkãšåŒãã§ããŸããããã®èšäºã§ã¯recall@kã®çµæä»¶æ°ãšæ··åããªããããcãšè¡šèšããŸãã
RRFã®å©ç¹ã¯ãBM25ã®é«ã¹ã³ã¢ãšãã¯ãã«æ€çŽ¢ã®é«ã¹ã³ã¢ããåãæå³ãæã€å¿ èŠããªãããšã§ããèŠãã®ã¯é äœã ãã§ããPineconeã®RRFå®è£ ã§ã¯ãé äœã1ããæ°ããããšãšããªã¹ãã«ãªãææžã®æ±ããæç€ºãããŠããŸãã
ãã ãããã®æ¹åŒã«ã¯ç¢ºèªããŠããããæ§è³ªããããŸãã説æçšã®äŸãšããŠãææžAã¯ããŒã¯ãŒãæ€çŽ¢ã§1äœã§ããããã¯ãã«æ€çŽ¢ã®ãªã¹ãã«ã¯ãªããšããŸããææžBã¯äž¡æ¹ã®ãªã¹ãã§2äœã§ããc = 60ãªããAã¯1/61ãBã¯2/62ãšãªããBãäžäœã«æ¥ãŸãã ããã¯åŒããèšç®ããäŸã§ãããæ€çŽ¢ãã³ãããŒã¯ã®çµæã§ã¯ãããŸããã
éã¿ä»ãã¹ã³ã¢ã¯ã¹ã³ã¢ã®å·®ãæ®ããŸã
éã¿ä»ãã¹ã³ã¢èåã§ã¯ãåæ€çŽ¢ã®é¢é£åºŠã¹ã³ã¢ãæ¯èŒå¯èœãªå°ºåºŠã«ããããŠããçµã¿åãããŸãããã䜿ãããåœ¢ã¯æ¬¡ã®ãšããã§ãã
ã¹ã³ã¢ = alpha à æ£èŠåãããã¯ãã«ã¹ã³ã¢ + (1 â alpha) à æ£èŠåããããŒã¯ãŒãã¹ã³ã¢ã
éã¿alphaã§ãã©ã³ã¹ã調æŽããŸããåæå€ã0.5ã«ããã°ä¿æ°ã¯çãããªããŸãããæçšæ§ãŸã§çãããªãããã§ããæé©ãªèšå®ã«ãªãããã§ããããŸãããæ£èŠåãšéã¿ä»ãã¯ãã©ã¡ããå€ããŠãé äœã«åœ±é¿ãããããäž¡æ¹ãèšé²ããŠãã ããã
Elasticsearchã®linear retrieverã¯ãminmaxãªã©ã®æ£èŠåæ¹åŒã䜿ã£ãå éåã«å¯Ÿå¿ããŠããŸããWeaviateã®çžå¯Ÿã¹ã³ã¢èåã¯ãåçµæéåã®äžã«ããçžå¯Ÿçãªã¹ã³ã¢å·®ãä¿æããŸããäžæ¹ãé äœã«åºã¥ãèåã§ã¯ããã®å·®ã¯äœ¿ãããŸããã
ãŸãRRFãæ¯èŒã®åºæºã«ããéã¿ä»ãèåã¯è©äŸ¡çšã«åã眮ããã¯ãšãªã§æå¹æ§ã確èªã§ããå Žåã«æ¡çšããŸãã çã®BM25ã¹ã³ã¢ãšãã¯ãã«é¡äŒŒåºŠãè¶³ããŠããã®åèšã«æå³ããããšèããŠã¯ãããŸããããŸããåè£ãäœä»¶ãŸã§ååŸããããèšé²ããŠãã ãããæ£èŠåã®å¯Ÿè±¡ãªã¹ãã«å«ããçµæãå€ãããšãã¹ã³ã¢ã®ç¯å²ãå€ããåŸãŸãã
ãã¯ãã«æ€çŽ¢ã ãã®å Žåããããã€ããªããæ€çŽ¢ãæå¹ãªã®ã¯ãã€ã
ããŒã¯ãŒãæ€çŽ¢ãããã¯ãã«æ€çŽ¢ã§ã¯èŠã€ãããªãã£ãé¢é£æ å ±ãååŸããçµ±ååŸããã®æ å ±ã圹ç«ã€é äœã«æ®ããªãããã€ããªããæ€çŽ¢ã¯æå¹ã§ããããã¯å®éã«ç¢ºèªã§ããæ¡ä»¶ã§ãããããããå Žé¢ã§ç²ŸåºŠãé«ããªããšãã䞻匵ã§ã¯ãããŸããã
ç¹ã«è©Šã䟡å€ãããã®ã¯ã次ã®ãããªçšéã§ãã
- ãµããŒãæ å ±ã®æ€çŽ¢ïŒ ãšã©ãŒæååã颿°åãã¢ã«ãŠã³ãã«é¢ããçšèªãšãçç¶ã説æããæç« ãæ··åšããŸãã
- ã«ã¿ãã°æ€çŽ¢ïŒ æ£ç¢ºãªè£œååãSKUã«ãäºææ§ã®ç¢ºèªã亀æéšåã®æ¢çŽ¢ãšãã£ãç®çãçµã¿åããããŸãã
- 瀟å ãã¬ããžæ€çŽ¢ïŒ ãããžã§ã¯ãåãç¥èªãšãèªç¶æã®è³ªåãæ··åšããŸãã
Pineconeã®ãã€ããªããæ€çŽ¢ã®æŠèŠã§ããæå³ãæããå¯ãã¯ãã«æ€çŽ¢ãšçµã¿åãããããŒã¯ãŒãåŽã®ææãããšããŠã補åã³ãŒãããšã©ãŒæååãåç§°ãæããããŠããŸãã
èå¥åã ãã§å¯Ÿè±¡ãåŒãçšéã§ã¯ããŸã確å®ã«åãå®å šäžèŽæ€çŽ¢ãçšæããŸããæ¢åã®ææžéåãšã¯ãšãªã«ãã¯ãã«æ€çŽ¢ãåå察å¿ã§ããŠãããªããæ€çŽ¢ã®åé¡ã確èªã§ããŠããçµè·¯ã远å ããŠãã ããã
å®éã®éçãæ±ºããã®ã¯ãåè£ã«å¿ èŠãªæ å ±ãå«ãŸããŠãããã§ããèååŠçãäžŠã¹æ¿ããããã®ã¯ãåçµè·¯ã§ååŸããææžã®åéåã ãã§ããã©ã¡ãã®çµè·¯ãå¿ èŠãªæç« ãèŠã€ããŠããªããã°ãçµ±åæ¹åŒãå€ããŠãåãæ»ããŸãããèååã«ã¯ãã£ãæç« ãæçµçµæããæ¶ãããªããã©ã³ãã³ã°ãšä»¶æ°ã«ããåãæšãŠã調ã¹ãŸãã
æ¢åã®ã¹ãã¢ã«ãã€ããªããæ€çŽ¢ã远å ãã
å¿ èŠãªæ€çŽ¢æ©èœãããã£ãŠãããªããä»äœ¿ã£ãŠããã¹ãã¢ãç¶æããŸããããŒã¿ããŒã¹ãšæ€çŽ¢æŠç¥ãåæã«å€ãããšãäœãæ¹åã«ã€ãªãã£ãã®ãåãåãã«ãããªããŸãã
次ã®è¡šã¯ãã©ãã§æ€çŽ¢çµæãçµã¿åãããããæŽçãããã®ã§ãããã³ããŒã®åªå£ã瀺ããã®ã§ã¯ãããŸããã
Elasticsearchã§ãã€ããªããæ€çŽ¢ãå®è£ ãã
ããã¹ãæ€çŽ¢ãšãã¯ãã«æ€çŽ¢ã«å¯Ÿå¿ããElasticsearchã§ã¯ãããã¹ãçšã®standardãªããªãŒããŒãšãã¯ãã«çšã®knnãªããªãŒããŒããrrfãªããªãŒããŒã®äžã«é
眮ã§ããŸãããã®æ§æãšåè£ãŠã£ã³ããŠã¯ãå
¬åŒã®RRFãªããªãŒããŒã®ãªãã¡ã¬ã³ã¹ã§èª¬æãããŠããŸãã
æ¢åã®ã€ã³ããã¯ã¹ã§ã¯ãæ€çŽ¢å¯Ÿè±¡ã®ããã¹ããšãã®åã蟌ã¿ããåãææžIDã«çŽä»ããŠä¿æããŸããäž¡æ¹ã®çµè·¯ã§åãæ€çŽ¢å¯Ÿè±¡ã«ã¯ãšãªãå®è¡ãããã®åŸã«èååŠçãè¡ããŸããããã³ããã¢ã¯ã»ã¹æš©éã補åããŒãžã§ã³ã®å¶éããçµè·¯éã§ããããŠãã ããã
以äžã¯ãES_URLãšES_API_KEYãèšå®ããåŸã«å®è¡ã§ãããªã¯ãšã¹ãã§ããæ¢åã®ã€ã³ããã¯ã¹åãdocsãããã¹ããã£ãŒã«ããtextãå¯ãã¯ãã«ãã£ãŒã«ããembeddingã§ãããquery-vector.jsonã«ã¯ã¯ãšãªã®å®éã®åã蟌ã¿é
åãå
¥ã£ãŠããããšãåæãšããŸãããã®é
åã¯ãã€ã³ããã¯ã¹å
ã®ææžã«äœ¿ã£ãã¢ãã«ã§çæããŠãã ãããã³ãã³ãã®å®è¡ã«ã¯jqãšcurlãå¿
èŠã§ãã
jq -n --slurpfile v query-vector.json \
--arg q 'ERR_SESSION_EXPIRED after login' \
'{
size: 10,
retriever: {
rrf: {
retrievers: [
{standard: {query: {match: {text: $q}}}},
{knn: {
field: "embedding",
query_vector: $v[0],
k: 50,
num_candidates: 100
}}
],
rank_window_size: 50,
rank_constant: 60
}
}
}' > hybrid-request.json
curl --fail-with-body "$ES_URL/docs/_search" \
-H "Authorization: ApiKey $ES_API_KEY" \
-H 'Content-Type: application/json' \
--data-binary @hybrid-request.jsonããã«ç€ºããå€ã¯ãè©äŸ¡ã®ããã®èšå®äŸã§ããsizeã¯æçµçãªçµæä»¶æ°ãrank_window_sizeã¯ååãªããªãŒããŒããèååŠçã«åå ã§ããçµæä»¶æ°ãå¶åŸ¡ããŸãããã®äŸã«ã¯ãã£ã«ã¿ãŒããªããããã¢ã¯ã»ã¹æš©éã®ããã¢ããªã±ãŒã·ã§ã³ã§äœ¿ãå Žåã¯ãæ€çŽ¢å¯Ÿè±¡ã®å¶çŽãå¿
ã远å ããŠãã ãããElasticã®ããã¥ã¡ã³ãã«ã¯ãåãªããªãŒããŒããããã®ä»æ§ã«åŸã£ãŠé©çšãããã芪åŽã®filterãèšèŒãããŠããŸãã
ã€ãŸãããããç¹ïŒ åãªããªãŒããŒã®åè£ãŠã£ã³ããŠãçããšããã€ããªããæ€çŽ¢ã§æŸãããã£ãçµæãã®ãã®ãæšãŠãŠããŸããŸããçµ±åæ¹åŒã調æŽããåã«ãåçµè·¯ã®åè£ãšæçµçµæãæ¯ã¹ãŠãã ãããlinear retrieverãžåãæ¿ããå Žåã¯ãéã¿ãšãšãã«æ£èŠåãèšå®ããŸãã
Weaviateã§ãã€ããªããæ€çŽ¢ãå®è£ ãã
ããã¹ãæ€çŽ¢ãšãã¯ãã«æ€çŽ¢ã«å¯Ÿå¿ããããŒã¿ããŒã¹Weaviateã§ã¯ãcollection.query.hybridãããã€ããªããæ€çŽ¢ãå©çšã§ããŸããããŒã¯ãŒãåŽã®æ€çŽ¢ã«ã¯ãè€æ°ãã£ãŒã«ãã«å¯Ÿå¿ããBM25ã®æŽŸçã§ããBM25Fã䜿ããŸãããã€ããªããã¯ãšãªã®ããã¥ã¡ã³ãã§ã¯ãæ€çŽ¢å¯Ÿè±¡ããããã£ãèåæ¹åŒã®éžæãã¹ã³ã¢ã®èª¬æãæ±ãããŠããŸãã
query_propertiesã«ã¯ãã¿ã€ãã«ããšã©ãŒæã補ååãªã©ãèªå¥ã®äžèŽãæå¹ãªææããã«ãªããã£ãŒã«ããæå®ããŸããã¢ããªã±ãŒã·ã§ã³åŽã§åã蟌ã¿ãçæããå Žåã¯ã¯ãšãªãã¯ãã«ãæž¡ããããã§ãªããã°ã³ã¬ã¯ã·ã§ã³ã«èšå®ãããã¯ãã«åã®çµè·¯ã䜿ããŸããèåæ¹åŒãæ¯èŒãããšãã¯fusion_typeãæç€ºããçµæã®é äœãåããçç±ã調ã¹ããšãã¯explain_scoreãååŸããŠãã ããã
alphaãæç€ºçã«èšå®ããŸãã0ã¯ããŒã¯ãŒãæ€çŽ¢ã1ã¯ãã¯ãã«æ€çŽ¢ãéžã³ãŸããç¢ºèªæç¹ã®ããã¥ã¡ã³ãã§ã¯ãçç¥æã«é©çšãããéã¿ã¯ã¯ã©ã€ã¢ã³ãã«äŸåãããšæ³šæãããŠããŸããæ¢å®ã®èåæ¹åŒã¯relativeScoreFusionã§ãrankedFusionãå©çšã§ããŸããWeaviateã®èåæ¹åŒãªãã¡ã¬ã³ã¹ã
ã€ãŸãããããç¹ïŒ éã¿ãå€ããŠããæ€çŽ¢å¯Ÿè±¡ãã£ãŒã«ãã®äžè¶³ããèå¥åã®ããŒã¯ã³åã«ãã厩ãã¯çŽããŸãããåã蟌ã¿ã¢ãã«ã眮ãæããã¹ãã ãšçµè«ä»ããåã«ãããŒã¯ãŒãåŽãäœãæ€çŽ¢ã§ããŠããã確èªããŠãã ãããéã¿ã®äž¡ç«¯ã«ããããã¯ãã«æ€çŽ¢ã®ã¿ãããŒã¯ãŒãæ€çŽ¢ã®ã¿ã®èšå®ã蚺æçšã®åºæºã«ããŠãããçµã¿åãããèšå®ãè©äŸ¡ããŸãã
Pineconeã§ãã€ããªããæ€çŽ¢ãå®è£ ãã
æ€çŽ¢çšããŒã¿ããŒã¹ã®Pineconeã¯ãç°ãªããã€ããªããæ€çŽ¢ã®ãã¿ãŒã³ãå ¬éããŠããŸãããµã³ãã«ãã³ããŒããåã«ãã©ã®æ¹åŒã䜿ããæ±ºããŠãã ããããµãŒããŒåŽã§ã®å¯ã»çãã¯ãã«ã®çµ±åãšãã¯ã©ã€ã¢ã³ãåŽã§ã®RRFã¯ãå¥ã®å®è£ ã§ããPineconeã®ãã€ããªããæ€çŽ¢ã®æŠèŠã
BM25ãšå¯ãã¯ãã«æ€çŽ¢ãçµã¿åãããå ŽåãDocuments APIã䜿ãçµè·¯ã§ã¯ãå šææ€çŽ¢ãšå¯ãã¯ãã«æ€çŽ¢ãå®è¡ããé äœä»ãã®ææžIDãã¢ããªã±ãŒã·ã§ã³åŽã§RRFã«ããçµ±åããŸããPineconeã®RRFã¬ã€ãã«ããã®ã¯ã©ã€ã¢ã³ãåŽã®å®è£ ãæ²èŒãããŠããŸãã
å¯ãã¯ãã«ãšçãã¯ãã«ããã€ãã£ãã«çµ±åããå ŽåãVectors APIã§ã¯åã¬ã³ãŒãã«äž¡æ¹ã®è¡šçŸãä¿åãã1åã®ã¯ãšãªã§çµã¿åãããããŸããåäžã€ã³ããã¯ã¹ã®ã¬ã€ãã§ã¯ãvector_type="dense"ãšmetric="dotproduct"ãå¿
é ã§ããçžå¯Ÿçãªåœ±é¿åºŠã¯ãã¯ã©ã€ã¢ã³ãåŽã§ã¯ãšãªãã¯ãã«ãã¹ã±ãŒãªã³ã°ããŠèšå®ããŸãã
çãã¯ãã«ã¯ããŒã¿ã®è¡šçŸåœ¢åŒã§ãããBM25ã§çæãããããšã瀺ããã®ã§ã¯ãããŸãããèšèšè³æã«ã¯ã䜿çšããèªåœããŒã¹ã®ã¢ãã«ãå šææ€çŽ¢ã®ã¹ã³ã¢èšç®æ¹åŒãæèšããŠãã ããã
ã€ãŸãããããç¹ïŒ ããŒã¯ãŒãã§ãã£ã«ã¿ãªã³ã°ããŠããå¯ãã¯ãã«ã§é äœãä»ããåŠçã¯ãäž¡æ¹ã®ã·ã°ãã«ãã©ã³ãã³ã°ã«åæ ããåŠçãšã¯ç°ãªããŸãããã£ã«ã¿ãŒã¯åè£ãé€å€ãããããé€å€æžã¿ã®å矩èªã®äžèŽãåŸããæŸãçŽããŸãããå¿ é æ¡ä»¶ã«ã¯ãã£ã«ã¿ãŒã䜿ããã©ã¡ãã®æ€çŽ¢çµè·¯ãããçµæãåè£ã«å ãããå Žåã«ã¯èåã䜿ããŸãã
RAGã§ãã€ããªããæ€çŽ¢ã¯ã©ããªåœ¹å²ãæããã®ã
ãã€ããªããæ€çŽ¢ãå€ããã®ã¯ã**æ€çŽ¢æ¡åŒµçæïŒRetrieval-Augmented GenerationãRAGïŒ**ã®æ€çŽ¢æ®µéã§ããRAGã§ã¯ãèšèªã¢ãã«ãåçããåã«ãã¢ããªã±ãŒã·ã§ã³ãæ€çŽ¢ããè³æãã¢ãã«ãžæž¡ããŸãããã€ããªããæ€çŽ¢ã¯çææ®µéã眮ãæãããã®ã§ããåçã®æ£ãããä¿èšŒãããã®ã§ããããŸããã
æ€çŽ¢ã®åäœã¯ããããŠãã ãããããŒã¯ãŒãæ€çŽ¢ãææžå šäœãè¿ãããã¯ãã«æ€çŽ¢ãæç« ã®äžéšåãè¿ããªããçµ±ååã«IDã®å¯Ÿå¿ä»ããæ±ºããŸããããããªããšãåãè³æããåã£ãè€æ°ã®æç« ãåè£ãå ããã»ãã®é¢é£è³æãæŒãåºãããããšããããŸããä¿åãšæ€çŽ¢ã®åºç€ã«ã€ããŠã¯ããã¯ãã«ããŒã¿ããŒã¹ã®è§£èª¬ã§æ±ã£ãŠããŸãã
Agentic RAGã§ã¯ãã©ã®æ€çŽ¢åŠçãå®è¡ããããããäžåºŠæ€çŽ¢ããããšãã£ã倿ãå ãããŸãããã€ããªããæ€çŽ¢ã¯ããã®éžæè¢ã®1ã€ã«ãªããŸãããµããŒããããããšã©ãŒã³ãŒããã®ãã®ãèŠéããŠãããªããåŠçã®å¶åŸ¡ãããã«è€éã«ããåã«ããã®æ€çŽ¢æ©æ§ãä¿®æ£ããŠè©äŸ¡ããŠãã ããã
æ€çŽ¢æ¹åŒã®æ¯èŒäžã¯ãåçãçæããã¢ãã«ãšããã³ãããåºå®ããŸããå®å šäžèŽã®èªå¥ãå«ãã¯ãšãªçŸ€ã§ã¯æ¹åããŠããèšãæããå«ãæ€çŽ¢ã匱ããŸãŸãªããåãæ£è§£ã©ãã«ä»ãã¯ãšãªã§åã蟌ã¿ã¢ãã«ãæ¯èŒããŸããåã蟌ã¿ããã£ã³ã¯åå²ãèåæ¹åŒãåæã«å€ãããšãçµæã®åå ãç¹å®ã§ããªããªããŸãã
å°å ¥ååŸã®recall@kãæ¯èŒãã
å°èŠæš¡ãªæ£è§£ã©ãã«ä»ãã¯ãšãªã»ããã䜿ããåãæ£è§£ã«å¯ŸããŠãããŒã¯ãŒãæ€çŽ¢ã®ã¿ããã¯ãã«æ€çŽ¢ã®ã¿ããã€ããªããæ€çŽ¢ãæ¯èŒããŸããçæãããåçãæµæ¢ã§ããããã¯æ€çŽ¢æ§èœã®ææšã«ã¯ãªããŸããã
Recall@k = äžäœkä»¶ã«å«ãŸããé¢é£IDã®æ° ÷ ãã®ã¯ãšãªã§é¢é£ãããšã©ãã«ä»ãããå šIDã®æ°ã ã¯ãšãªããšã®å€ãå¹³åãããšããã¯ãå¹³åã®recall@kã«ãªããŸããã©ãã«ãç¶²çŸ çã§ãªãå Žåã¯ãæ¢ç¥ã®é¢é£æ§å€å®ã«å¯ŸããåçŸçãšåŒãã§ãã ãããææžéåã«ãããã¹ãŠã®é¢é£é ç®ã«å¯ŸããåçŸçãåãã£ãããšã«ã¯ãªããŸããã
å°èŠæš¡ãªã¯ãšãªã»ãããäœã
ãŸãã¯åçå¯èœãª60ã¯ãšãªãçšæããŸããæ£ç¢ºãªèªå¥ãå«ãã¯ãšãª20ä»¶ãèšãæãã®ã¯ãšãª20ä»¶ãäž¡æ¹ãæ··åšããã¯ãšãª20ä»¶ã§ããããã¯ã¯ãŒã¯ããŒããåããããã®ææ¡ã§ããããµã³ãã«æ°ã®ååæ§ãä¿èšŒãããã®ã§ã¯ãããŸãããã§ããã ãå®éã®æ€çŽ¢ããéããçŸåšåãããŒããŠããåç§°ãSKUããšã©ãŒæååãå«ããŠãã ããã
åã¯ãšãªçŸ€ã®ååãéçºçšã«ãæ®ãååãæªäœ¿çšã®è©äŸ¡çšãšããŠåã眮ããŸããæå³çã«åçäžèœã«ãã6ã¯ãšãªãã奿 ã§è¿œå ããŠãã ãããæåã¯ç¢ºèªããŸãããé¢é£éåã空ã§åæ¯ããªããªããããåçŸçã®èšç®ããã¯é€å€ããŸãã
æ€çŽ¢åäœããšã«é¢é£æ§ãã©ãã«ä»ããã
ã¯ãšãªããšã«ãã¯ãšãªIDãã¯ãšãªçŸ€ãé¢é£ãããšç¢ºèªã§ãããã¹ãŠã®ææžIDãŸãã¯æç« IDãèšé²ããŸãã3ã€ã®æ€çŽ¢æ¹åŒããåè£ãéããã©ã®æ¹åŒã§ãååŸã§ããªãã£ãæ¢ç¥ã®æ£è§£ãå ããããã§ãã©ã®æ¹åŒãè¿ããããèŠãã«å€å®ããŸããå®å®ããIDã䜿ããææžåäœãæç« åäœããå šäœã§çµ±äžããŠãã ããã
æ¯èŒæ¡ä»¶ãåºå®ãã
ææžéåã®ã¹ãããã·ã§ãããã¢ã¯ã»ã¹æš©éãåã蟌ã¿ã¢ãã«ããã£ã³ã¯åå²ãããããŸããæçµçµæã®kã¯10ããã€ããªããæ€çŽ¢ã®åçµè·¯ããã®åè£ã¯50ä»¶ãåæèšå®ã«ããŸãããããã¯æ€èšŒã®åºçºç¹ã§ãããæé©å€ã§ã¯ãããŸãããæåã®æ¯èŒã§ã¯ãªã©ã³ãã³ã°ãç¡å¹ã«ããŸãã
åæ¹åŒã®æçµçãªé äœä»ãIDããšã¯ã¹ããŒãããŸããèååã®ããŒã¯ãŒãæ€çŽ¢ãšãã¯ãã«æ€çŽ¢ã®åè£ãªã¹ããä¿åããåè£ã«ãªãåé¡ãšãã©ã³ãã³ã°ã®åé¡ãåºå¥ã§ããããã«ããŠãã ããã
調æŽãçµããŠãããåã眮ããã¯ãšãªã§è©äŸ¡ãã
éçºçšã®ååã§èåæ¹åŒãšåè£ä»¶æ°ã調æŽããŸããèšå®ãéžã³çµããŠãããåã眮ããæ®ãååã§1åã ãè©äŸ¡ããŸããå šäœã®å¹³åã«å ããŠããã¹ãŠã®ã¯ãšãªçŸ€ã®çµæãå ±åããæªåããåã ã®ã¯ãšãªã確èªããŠãã ãããå¹³åãå°ãæ¹åããããšã¯ãããã«èª¿ã¹ãçç±ã«ã¯ãªããŸãããçµ±èšçãªèšŒæã§ã¯ãããŸããã

ããŒã«ã«ã§åçŸçãèšç®ãã
以äžãevaluate_recall.pyãšããŠä¿åããŸãã䜿ãã®ã¯Python 3ã®æšæºã©ã€ãã©ãªã ãã§ããqrels.jsonlã«ã¯ã¯ãšãªããšã«1ã€ã®JSONãªããžã§ã¯ããèšè¿°ããqidãsliceãrelevantã®åãã£ãŒã«ããå«ããŸããåçµæãã¡ã€ã«ã§ã¯ãã¯ãšãªIDããååŸããIDã®é äœä»ããªã¹ãã«å¯Ÿå¿ä»ããŸãã
ããšãã°ãã©ãã«ã®ã¬ã³ãŒãã¯{"qid":"q-exact","slice":"exact","relevant":["guide-login"]}ãçµæãã¡ã€ã«ã®å
容ã¯{"q-exact":["guide-reset","guide-login"]}ã®ããã«ãªããŸããããã¯åœ¢åŒã瀺ãäŸã§ãããæ€èšŒæžã¿ã·ã¹ãã ã®æ€çŽ¢çµæã§ã¯ãããŸããããã¹ãŠã®çµæãã¡ã€ã«ã«ãã©ãã«ä»ããããã¹ãŠã®ã¯ãšãªãå«ããŠãã ãããäœãååŸã§ããªãã£ãã¯ãšãªã«ã¯ã空ã®ãªã¹ãã䜿ããŸãã
import json
import sys
from collections import defaultdict
from statistics import mean
qrels_path, bm25_path, vector_path, hybrid_path, cutoff = sys.argv[1:]
k = int(cutoff)
if k < 1:
raise ValueError("k must be positive")
with open(qrels_path, encoding="utf-8") as f:
labels = [json.loads(line) for line in f if line.strip()]
if not labels or len({r["qid"] for r in labels}) != len(labels):
raise ValueError("Labels must be nonempty with unique query IDs")
runs = {}
for name, path in (("bm25", bm25_path), ("vector", vector_path),
("hybrid", hybrid_path)):
with open(path, encoding="utf-8") as f:
runs[name] = json.load(f)
missing = {r["qid"] for r in labels} - runs[name].keys()
if missing:
raise ValueError(f"{name} is missing query IDs: {sorted(missing)}")
groups = defaultdict(list)
skipped = 0
for row in labels:
relevant = set(row["relevant"])
if not relevant:
skipped += 1
continue
scores = {}
for name, run in runs.items():
unique_ids = list(dict.fromkeys(run[row["qid"]]))
scores[name] = len(relevant & set(unique_ids[:k])) / len(relevant)
groups["overall"].append(scores)
groups["slice:" + row["slice"]].append(scores)
if not groups:
raise ValueError("No answerable queries to score")
for group, rows in sorted(groups.items()):
values = {name: mean(r[name] for r in rows) for name in runs}
delta = values["hybrid"] - values["vector"]
report = " ".join(f"{name}={v:.3f}" for name, v in values.items())
print(f"{group} n={len(rows)} recall@{k} {report} delta={delta:+.3f}")
print(f"Excluded no-answer queries: {skipped}")åã眮ããè©äŸ¡çšã©ãã«ãšããšã¯ã¹ããŒãããçµæã«å¯ŸããŠå®è¡ããŸãã
python3 evaluate_recall.py qrels.jsonl bm25.json vector.json hybrid.json 10ãã®ã¹ã¯ãªããã¯ãIDã®éè€ãé€ããŠããäžäœä»¶æ°ã§åºåããŸããã¢ããªã±ãŒã·ã§ã³ã§ããåãéè€é€å»ã®ã«ãŒã«ã䜿ã£ãŠãã ããããã¯ãã«æ€çŽ¢ã«å¯Ÿãããã€ããªããæ€çŽ¢ã®å€åãå ±åãããšãšãã«ãããŒã¯ãŒãæ€çŽ¢ã®åºæºå€ã衚瀺ããŸããããã«ãããèªåœããŒã¹ã®æ€çŽ¢ãé«ãæ§èœãåºããŠããå Žåããæ¯èŒããèŠèœãšããã«æžã¿ãŸãã
éèŠãªã¯ãšãªçŸ€ã§æ¹åãèŠãããæªåããç¹ã補åèŠä»¶ã®ç¯å²ã§èš±å®¹ã§ãããªããå°å ¥ã«é²ã¿ãŸãã åè£ã¯æ¹åããã®ã«æçµçãªåçŸçãå€ãããªãå Žåã¯ãèåæ¹åŒãè¿åŽä»¶æ°ã調æŽããŸããæçµçãªåçŸçãäžãã£ãå Žåããçµæã®äžŠã³é ãçæåçã®æ£ããããšã³ãããŒãšã³ãã®ã¬ã€ãã³ã·ãŒã¯å¥é確èªããŠãã ãããåçŸçã ãã§ã¯ããã®ããããæž¬ããŸããã
éå€§ãªæåŸ ãé¿ããæ¬¡ã«äœãããã
ããã€ããªããæ€çŽ¢ãªãäž¡æ¹ã®ãããšãåããã§ããããšãã説æã ãã§ã¯ãèšèšäžã®å€æãèŠããªããªããŸãã圹ç«ã€æ å ±ãæŸããç¯å²ã¯åºããåŸãŸãããåæã«ããã1ã€ã®æ€çŽ¢çµè·¯ãæçµãªã¹ãã«åœ±é¿ããããšã«ãªããŸããRRFã¯å®å šäžèŽã®é äœãäžããããšããããŸããéã¿ä»ãèåã¯ãã¹ã³ã¢å°ºåºŠãæ£èŠåã®æåã®éãã«ãã£ãŠãäžæ¹ãåªéããããšããããŸãããããŠãå ã«ãªãæ å ±ãååšããªãåé¡ã¯ãã©ã¡ãã§ã解決ã§ããŸããã
éçºè ãããã«çæãã¹ããªã®ã¯ã æ£ç¢ºãªèªå¥ãå«ãé¢é£ææžããã¯ãã«æ€çŽ¢ã®åè£ããæããŠãããšç¢ºèªã§ããå Žåã§ããããŒã¯ãŒãæ€çŽ¢ã®çµè·¯ã远å ããææžã®åäžæ§ãšã¢ã¯ã»ã¹æš©éãããããæ£è§£ã©ãã«ä»ãã®æ¯èŒã宿œããŸãã
éçšæ åœè ãå±éãåŸ ã€ã¹ããªã®ã¯ã çŸåšã®åé¡ãå€ãã³ã³ãã³ããæš©éã®äžè¶³ãé¢é£æ§ã©ãã«ã®æ¬ åŠã«ããå Žåã§ããå ã«ãã®åææ¡ä»¶ãæŽããŠãããæ€çŽ¢æŠç¥ãæ¯èŒããŠãã ããã
èå¥åã«ããæ€çŽ¢ãå®å®ããŠããããŒã ã¯ã ããåºãæ å ±æ¢çŽ¢ãå¿ èŠã«ãªããŸã§ã¯ã察å¿ãå€ããå¿ èŠã¯ãããŸãããä¿¡é Œã§ããæ€çŽ¢çµè·¯ãç¶æããèªç¶æã®è³ªååãã®ãã€ããªããæ€çŽ¢ãå¥éè©äŸ¡ããŸãã
次ã®å¶æ¥æ¥ã«ãŸãè¡ãããšã¯ãããŸããããªãæ€çŽ¢ãéããæåŸ ããè³æã«ã©ãã«ãä»ããæ¢åã®ãã¯ãã«æ€çŽ¢ãšããŒã¯ãŒãæ€çŽ¢ã®åºæºå®è£ ã䞊ã¹ãŠåããããšã§ããåçµè·¯ãäœãååŸã§ãããèŠããŠããèåãå ããåã眮ããã¯ãšãªã§æå¹æ§ã瀺ããèšå®ãæ¡çšããŠãã ããã
ãããã質å
BM25ã¯ãã€ããªããæ€çŽ¢ã§ããïŒ
ããããBM25ã¯èªåœããŒã¹ã®ã©ã³ãã³ã°é¢æ°ã§ãããã®çµæããã¯ãã«æ€çŽ¢ã®çµè·¯ãšçµã¿åããããšããã€ããªããæ€çŽ¢ã®äžåœ¢æ ã«ãªããŸãã
ChatGPTã¯ã»ãã³ãã£ãã¯æ€çŽ¢ã䜿ã£ãŠããŸããïŒ
çæãããåçã ããããæ€çŽ¢ã¢ã«ãŽãªãºã ãç¹å®ããããšã¯ã§ããŸãããèšèªã¢ãã«ã䜿ã£ãŠæ§ç¯ããã·ã¹ãã ã§ã¯ãBM25ããã¯ãã«ãRRFã®ããããã䜿ãããŠãããšæ±ºãä»ãããèšå®ãããæ€çŽ¢çµè·¯ã確èªããŠãã ããã
ã»ãã³ãã£ãã¯æ€çŽ¢ãšã¯äœã§ããïŒå ·äœäŸã¯ãããŸããïŒ
ãäœåºŠããã°ã¢ãŠããããããšããã¯ãšãªããã衚çŸãç°ãªããã»ãã·ã§ã³ã®æå¹æéåããã®èª¬æãèŠã€ããããå ŽåããããŸãããããæå³ã«åºã¥ãæ€çŽ¢ã§ãããã ãããšã©ãŒæååãã®ãã®ãæ¢ãã«ã¯ãèªå¥ã®äžèŽã«ããæ€çŽ¢ãå¿ èŠã«ãªãããšããããŸãã
ãã€ããªããæ€çŽ¢ã®å ·äœäŸãæããŠãã ãã
ERR_SESSION_EXPIRED after loginã«å¯ŸããŠãããŒã¯ãŒãæ€çŽ¢ã®çµè·¯ã§ãšã©ãŒæååã«äžèŽããæ
å ±ãååŸãããã¯ãã«æ€çŽ¢ã®çµè·¯ã§é¢é£ããã»ãã·ã§ã³ã®èª¬æãååŸããŸããåè£ãçµ±åããããæåŸ
ããè³æãåŸãããããé¢é£æ§ã©ãã«ã«ç
§ãããŠç¢ºèªããŸãã
ãã€ããªããæ€çŽ¢ãšãã¯ãã«æ€çŽ¢ã®äž»ãªéãã¯äœã§ããïŒ
ãã¯ãã«æ€çŽ¢ã®ã¿ã®å Žåã¯ãåã蟌ã¿ã®é¡äŒŒåºŠã«åºã¥ããŠæ€çŽ¢ããŸããããã§èª¬æãããã€ããªããæ€çŽ¢ã§ã¯ãããŒã¯ãŒãã®çµè·¯ã§ãæ€çŽ¢ããäž¡æ¹ã®ææããã1ã€ã®çµæãªã¹ãã«ãŸãšããŸãã
ãã€ããªããæ€çŽ¢ãšã»ãã³ãã£ãã¯æ€çŽ¢ã¯åãã§ããïŒ
ããããã»ãã³ãã£ãã¯æ€çŽ¢ã¯ããã€ããªããæ€çŽ¢ãæ§æããèŠçŽ ã®1ã€ã«ãªãåŸãŸãããã€ããªãããšã¯æ€çŽ¢ã®ã·ã°ãã«ãçµã¿åãããããšãæããç¹å®ã®èåã¢ã«ãŽãªãºã ãæãããã§ã¯ãããŸããã
Googleæ€çŽ¢ã¯ã»ãã³ãã£ãã¯æ€çŽ¢ã§ããïŒ
Google Searchã¯ãã©ã³ãã³ã°ã·ã¹ãã ã®äžã§æå³ã®çè§£ãå©çšããŠããŸããGoogleã®ã©ã³ãã³ã°ã·ã¹ãã ã®ã¬ã€ãã«ã¯ãBERTãšãã¥ãŒã©ã«ãããã³ã°ã®èª¬æããããŸãããã ããããã«ãã£ãŠå šäœã®æ§æãããã®èšäºã§æ±ãBM25ãšãã¯ãã«ãçµã¿åãããèšèšã ãšåããããã§ã¯ãããŸããã
RAGãšã»ãã³ãã£ãã¯æ€çŽ¢ã¯ã©ãéããŸããïŒ
RAGã¯å ã«ãªãè³æãæ€çŽ¢ããåçã®çææã«å©çšããŸããã»ãã³ãã£ãã¯æ€çŽ¢ã¯ããã®è³æãååŸããããã«äœ¿ããæ€çŽ¢æ¹åŒã§ããRAGã¢ããªã±ãŒã·ã§ã³ã§ã¯ãããŒã¯ãŒãæ€çŽ¢ããã€ããªããæ€çŽ¢ãå©çšã§ããŸãã
ãã€ããªããæ€çŽ¢ã¯ã©ã®ããã«åãã®ã§ããïŒ
ãã®ã¬ã€ãã®æ§æã§ã¯ãæ€çŽ¢å¯Ÿè±¡ãšããŠèš±å¯ãããã³ã³ãã³ãã«å¯ŸããŠããŒã¯ãŒãæ€çŽ¢ãšãã¯ãã«æ€çŽ¢ãå®è¡ããå®å®ããIDã§åè£ããŸãšããRRFãŸãã¯æå³ãæã£ãŠèšèšããéã¿ä»ãã¹ã³ã¢æ¹åŒã§é äœãä»ããŸããå±éåã«ãæ£è§£ã©ãã«ä»ãã¯ãšãªã䜿ã£ãŠæçµçµæãè©äŸ¡ããŠãã ããã
å®è£ ã«åœ¹ç«ã€ã¬ã€ãããã¥ãŒã¹ã¬ã¿ãŒã§åãåãã
- å ¬éæ¥
- ã«ããŽãªãŒ
- Build
- èšèª










