
LangChain ã® HOW-TO EXAMPLES (4) - ããŒã¿æ¡åŒµçæ
ãLangChainãã®ãããŒã¿æ¡åŒµçæããæäŸããæ©èœã玹ä»ãã HOW-TO EXAMPLES ããŸãšããŸããã
åå
1. ããŒã¿æ¡åŒµçæã®æ©èœ
ãããŒã¿çææ¡åŒµãã¯ãç¹å®ã®ããŒã¿ã«åºã¥ããŠèšèªã¢ãã«ã§ããã¹ãçæããææ³ã§ãã
2. Fetching ãš Augmenting
ããŒã¿æ¡åŒµçæã¯ããFetchingããšãAugmentingãã®2ã¹ãããã§æ§æãããŸãã
2-1. Fetching
LLMã«æž¡ãé¢é£ããŒã¿ãååŸããã¹ãããã§ãã
次ã®ãããªææ³ããããŸãã
â ãŠãŒã¶ãŒãé¢é£ããŒã¿ãæäŸ
ç¹å®ã®ããã¹ãã®ãèŠçŽããªã©ãããã«ããããŸãã
â å€§èŠæš¡ããŒã¿ã³ãŒãã¹ããé¢é£ããŒã¿ãååŸ
å€§èŠæš¡ããã¹ãã³ãŒãã¹ã«å¯Ÿããã質åå¿çããªã©ãããã«ããããŸãã
â APIã¯ãšãªã§é¢é£ããŒã¿ãååŸã
Googleæ€çŽ¢ã§ååŸããããŒã¿ã«ããããã¹ãçæãªã©ãããã«ããããŸãã
2-2. Augmenting
é¢é£ããŒã¿ãã³ã³ããã¹ããšããŠLLMã«æž¡ãã¹ãããã§ãã
次ã®ãããªææ³ããããŸãã
â Stuffing
ãã¹ãŠã®é¢é£ããŒã¿ãã³ã³ããã¹ããšããŠããã³ããã«è©°ã蟌ã¿ãèšèªã¢ãã«ã«æž¡ãææ³ã§ãã
ã»é·æ : LLMãžã®åŒã³åºãã¯1åã®ã¿ãããã¹ãçææã«LLMã¯äžåºŠã«ãã¹ãŠã®ããŒã¿ã«ã¢ã¯ã»ã¹ã§ããã
ã»çæ : LLMã«ã¯ã³ã³ããã¹ãã®é·ãå¶éãããã倧ããªããŒã¿ã¯æ©èœããªãã
â Map Reduce
é¢é£ããŒã¿ããã£ã³ã¯ã«åå²ãããã£ã³ã¯ããšã«ããã³ãããçæããŠLLMãåŒã³åºããæåŸã«å
šãŠã®çµæãçµåããããã³ããã§LLMãåŒã³åºãææ³ã§ãã
ã»é·æ : Stuffingãã倧ããªããŒã¿ãæ©èœããããã£ã³ã¯ã®LLMåŒã³åºã䞊åå®è¡ã§ããã
ã»çæ : Stuffingããå€ãã®LLMåŒã³åºããå¿ èŠãæåŸã®çµåã§äžéšã®æ å ±ã倱ãããã
â Refine
é¢é£ããŒã¿ããã£ã³ã¯ã«åå²ããæåã®ãã£ã³ã¯ããšã«ããã³ãããçæããŠLLMãåŒã³åºãããã®åºåãšæ¬¡ã®ãã£ã³ã¯ã§ããã³ãããçæããŠLLMãåŒã³åºãããããç¹°ãè¿ãææ³ã§ãã
ã»é·æ : ããé¢é£æ§ã®é«ãã³ã³ããã¹ããåã蟌ãããšãã§ãããMap Reduceãããæå€±ãå°ãªãå¯èœæ§ãããã
ã»çæ : Stuffingãããå€ãã®LLMåŒã³åºããå¿ èŠããã£ã³ã¯ã®LLMåŒã³åºã䞊åå®è¡ã§ããªããããã¹ãã®é åºã«ã¯ãããã€ãã®æœåšçãªäŸåé¢ä¿ãããã
â Map-Rerank
é¢é£ããŒã¿ããã£ã³ã¯ã«åå²ãããã£ã³ã¯ããšã«ããã³ãããçæããŠLLMãåŒã³åºãããã®çããã©ãã ã確å®ãã瀺ãã¹ã³ã¢ã瀺ããŸãã
次ã«ããã®ã¹ã³ã¢ã«åŸã£ãŠå¿çãã©ã³ã¯ä»ããããæé«ã®ã¹ã³ã¢ãè¿ãããŸãã
ã»é·æ : Map Reduceãšåæ§ãMap ReduceããåŒã³åºããå°ãã
ã»çæÂ : ããã¥ã¡ã³ãéã§æ å ±ãçµåã§ããªããããã¯ã1ã€ã®ææžã«1ã€ã®åçŽãªçããããå Žåã«æãé©ããŠããããšãæå³ããã
3. 質åå¿ç
質åå¿çã®æé ã¯ã次ã®ãšããã§ãã
3-1. é¢é£ãããã£ã³ã¯ã®æºå
(1) ããã±ãŒãžã®ã€ã³ããŒãã
# ããã±ãŒãžã®ã€ã³ããŒã
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores.faiss import FAISS
from langchain.docstore.document import Document
from langchain.llms import OpenAI(2) ããã¹ããæºåããColabã«ã¢ããããŒãã
ä»åã¯ãWikipediaã®ãã©ãŽã³ããŒã«ã®ãããããèšè¿°ããããã¹ããã¡ã€ã«ãdragonball.txtããçšæããŸãã
ã»dragonball.txt (9KBã»ã©)
å«æç©ºå°å¹Žç·š
å°çã®äººéé¢ãã山奥ã«äœã尻尟ã®çããå°å¹Žã»å«æç©ºã¯ããæ¥ã西ã®éœãããã£ãŠæ¥ãå°å¥³ã»ãã«ããšåºäŒããããã§ã7ã€éãããšç¥éŸïŒã·ã§ã³ãã³ïŒãçŸããã©ããªé¡ãã§ãäžã€ã ãå¶ããŠããããšãããã©ãŽã³ããŒã«ã®ååšããããã«è²ãŠã®èŠªã§ãã嫿飝ã®åœ¢èŠãšããŠå€§åã«æã£ãŠããçããã®1ã€ãåæçïŒã¹ãŒã·ã³ãã¥ãŠïŒãã§ããããšãç¥ãããã«ããšå
±ã«æ®ãã®ãã©ãŽã³ããŒã«ãæ¢ãæ
ã«åºãã人ãããã®ãŠãŒãã³ãçè³ã®ã€ã ãã£ããå·»ã蟌ãã ããŒã«æ¢ãã®æ«ãäžçåŸæãäŒããã©ãäžå³ã«ããŒã«ã奪ããç¥éŸãåŒã³åºããããããŠãŒãã³ããšã£ãã«èšãæŸã£ãäžããªãé¡ããå¶ããŠãããããšã§äžå³ã®éæã黿¢ããã
ãã®åŸãæç©ºã¯æ
ã®éäžã«ç¥ãåã£ãæŠè¡ã®é人ã»äºä»äººã®äžã§ãåŸã«èŠªåãšãªãã¯ãªãªã³ãšå
±ã«8ãæéã«ãããä¿®è¡ãç©ã¿ããã®ææã確ãããããã«äžçäžã®æŠè¡ã®éäººãæ±ºãã倩äžäžæŠéäŒã«åºå Žããå€è£
ããŠåºå ŽããŠããäºä»äººã«æãããæºåªåãæãããæç©ºã¯åã³ä¿®è¡ã®æ
ãžãšåºçºãããã©ãŽã³ããŒã«ã®æªçšãäŒãã¬ãããªãã³è»ãšã®éããã嫿飝ãšã®åäŒãªã©ãçµãŠããã«åŒ·ããå¢ããŠãããããã«3幎åŸã®å€©äžäžæŠéäŒã§ã¯ãäºä»æµã®ã©ã€ãã«ã§ããé¶Žä»æµã®å€©æŽ¥é£¯ïŒãŠãããã¯ãïŒãšéãããããšäžæ©ã®ãšããã§æããååãšåããæºåªåã«çµããã
ããã³ã倧éçç·š
倩äžäžæŠéäŒçµäºåŸã
:(3) ããã¹ãã®èªã¿èŸŒã¿ãšåå²
# ããã¹ãã®èªã¿èŸŒã¿ãšåå²
with open("dragonball.txt") as f:
dragonball_txt = f.read()
text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=0)
texts = text_splitter.split_text(dragonball_txt)(4) é¢é£ãããã£ã³ã¯ã®æœåºã
query = "ããžãŒã¿ã®æ¯åã®ååã¯ïŒ"
# é¢é£ãããã£ã³ã¯ã®æœåº
embeddings = OpenAIEmbeddings()
docsearch = FAISS.from_texts(texts, embeddings)
docs = docsearch.similarity_search(query)2-2. Stuffing
(1) stuffã®load_qa_chainãæºåããŠè³ªåå¿çãå®è¡ã
from langchain.chains.question_answering import load_qa_chain
# stuffã®load_qa_chainãæºå
chain = load_qa_chain(OpenAI(temperature=0), chain_type="stuff")
# 質åå¿çã®å®è¡
chain({"input_documents": docs, "question": query}, return_only_outputs=True){'output_text': ' ãã©ã³ã¯ã¹'}3-3. Map Reduce
(1) map_reduceã®load_qa_chainãæºåããŠè³ªåå¿çãå®è¡ã
ä»åã®äŸã§ã¯ããŸãåçã§ããŸããã§ããã
from langchain.chains.question_answering import load_qa_chain
# stuffã®load_qa_chainãæºå
chain = load_qa_chain(OpenAI(temperature=0), chain_type="map_reduce")
# 質åå¿çã®å®è¡
chain({"input_documents": docs, "question": query}, return_only_outputs=True){'output_text': " I don't know."}3-4. Refine
(1) refineã®load_qa_chainãæºåããŠè³ªåå¿çãå®è¡ã
from langchain.chains.question_answering import load_qa_chain
# refineã®load_qa_chainãæºå
chain = load_qa_chain(OpenAI(temperature=0), chain_type="refine")
# 質åå¿çã®å®è¡
chain({"input_documents": docs, "question": query}, return_only_outputs=True){'output_text': '\n\nããžãŒã¿ã®æ¯åã®ååã¯ããã©ã³ã¯ã¹ã§ãããæªæ¥ãããã£ãŠãããã«ããšããžãŒã¿ã®æ¯åã§ããããšãæç©ºã«ã ãæãããæç©ºãå¿èç
ã«ãã£ãŠåœãèœãšãããšã3幎åŸã«çŸãã2äœã®äººé 人éãçµ¶æã®æªæ¥ãããããããšãåããããããŠ10幎åŸãæç©ºã¯å«ã®ãã³ãšå
±ã«å€©äžäžæŠéäŒã«ä¹
ãã¶ãã«åºå Žããé人ããŠã®çãŸãå€ããã§ããå°å¹Žã»ãŠãŒããšåºäŒããç©èªã¯å¹ãéãããŸã§ã«èŠæãŠã¬åŒ·ã'}4. ãœãŒã¹ä»ãã®è³ªåå¿ç
質åå¿çããéã®å ã«ãªã£ããœãŒã¹ãæç€ºããããšãã§ããŸãã
(1) ãœãŒã¹ä»ãã§é¢é£ãããã£ã³ã¯ãæœåºã
FAISS.from_texts()ã«metadatasåŒæ°ãæå®ããŸãã
query = "ããžãŒã¿ã®æ¯åã®ååã¯ïŒ"
# ãœãŒã¹ä»ãã§é¢é£ãããã£ã³ã¯ãæœåº
docsearch = FAISS.from_texts(
texts,
embeddings,
metadatas=[{"source": i} for i in range(len(texts))])
docs = docsearch.similarity_search(query)(2) load_qa_with_sources_chainãæºåããŠãœãŒã¹ä»ãã®è³ªåå¿çãå®è¡ã
load_qa_chainã§ã¯ãªããload_qa_with_sources_chainã䜿ããŸãããœãŒã¹ã¯5ãš7ã§ããããšãããããŸãã
from langchain.chains.qa_with_sources import load_qa_with_sources_chain
# load_qa_with_sources_chainã®æºå
chain = load_qa_with_sources_chain(OpenAI(temperature=0), chain_type="stuff")
# ãœãŒã¹ä»ãã®è³ªåå¿çã®å®è¡
chain({"input_documents": docs, "question": query}, return_only_outputs=True){'output_text': " The name of Vegeta's son is Trunks.\nSOURCES: 5, 7"}(3) ãœãŒã¹ã®ç¢ºèªã
# ãœãŒã¹ã®ç¢ºèª
print(texts[5])
print(texts[7])ãã¡ãã¯æã§ã®éãããçŽ1幎åŸãå¯ãã«çãå»¶ã³ãŠããããªãŒã¶ãšãã®äžå³ãå°çã襲æããããè¬ã®è¶
ãµã€ã€äººã«ãã£ãŠæéãããããã©ã³ã¯ã¹ãšåä¹ããã®é幎ã¯ã
:5. èŠçŽ
èŠçŽã®æé ã¯ã次ã®ãšããã§ãã
5-1. èŠçŽããããã¹ãã®æºå
(1) é¢é£ãããã£ã³ã¯ã®æºåã
質åå¿çãšåæ§ã§ããåã蟌ã¿ã¯äœ¿ããããã£ã³ã¯(texts)ã®ã¿å©çšããŸãã
(2) å
é 2ã€ã®ãã£ã³ã¯ã§ããã¹ãçæã
Stuffingã«ãµã€ãºå¶éããããããå°ããããŠãŸãã
# å
é 2ã€ã®ãã£ã³ã¯ã§ããã¹ãçæ
docs = [Document(page_content=t) for t in texts[:2]]5-2. Stuffing
(1) stuffã®load_summarize_chainãæºåããŠèŠçŽãå®è¡ã
from langchain.chains.summarize import load_summarize_chain
# stuffã®load_qa_chainãæºå
chain = load_summarize_chain(OpenAI(temperature=0), chain_type="stuff")
# èŠçŽã®å®è¡
print(chain.run(docs))å«æç©ºå°å¹Žç·šã§ã¯ã尻尟ã®çããå°å¹Žã»å«æç©ºã西ã®éœãããã£ãŠæ¥ãå°å¥³ã»ãã«ããšåºäŒãããã©ãŽã³ããŒã«ãæ¢ãæ
ã«åºãããã®åŸãå«æç©ºã¯æŠè¡ã®é人ã»äºä»äººã®äžã§ä¿®è¡ãç©ã¿ã倩äžäžæŠéäŒã«åºå Žãæºåªåãæãããããã³ã倧éçç·šã§ã¯ããã©ãäžå³ã«ãã£ãŠåŸ©æŽ»ããããã³ã倧éçã«ãã£ãŠãã¯ãªãªã³ãäºä»äººãªã©æç©ºã®ä»²éãã¡ã殺ããããæç©ºã¯ä»ã5-3. Map Reduce
(1) map_reduceã®load_summarize_chainãæºåããŠèŠçŽãå®è¡ã
# stuffã®load_qa_chainãæºå
chain = load_qa_chain(OpenAI(temperature=0), chain_type="map_reduce")å«æç©ºã¯å°»å°Ÿã®çããå°å¹Žã§ããã«ããšåºäŒããã©ãŽã³ããŒã«ã7ã€éããããšã§ç¥éŸãåŒã³åºãããšãç¥ããä¿®è¡ãç©ãã åŸã倩äžäžæŠéäŒã§æºåªåãæãããããã©ãäžå³ã«ãã£ãŠåŸ©æŽ»ããããã³ã倧éçã«ãã£ãŠä»²éãã¡ã殺ããããæç©ºã¯ä»ãèšã€ãããç¥ã®äžã§å€©çã§ä¿®è¡ããããšãšãªã£ãã5-4. Refine
(1) map_reduceã®load_summarize_chainãæºåããŠèŠçŽãå®è¡ã
from langchain.chains.summarize import load_summarize_chain
# refineã®load_qa_chainãæºå
chain = load_summarize_chain(llm, chain_type="refine")
# èŠçŽã®å®è¡
print(chain.run(docs))\n\nå«æç©ºã¯å°»å°Ÿã®çããå°å¹Žã§ã西ã®éœãããã£ãŠããå°å¥³ãã«ããšåºäŒãããã©ãŽã³ããŒã«ã7ã€éããããšã§ç¥éŸãåŒã³åºãããšãç¥ãããŠãŒãã³ãã€ã ãã£ããå·»ã蟌ãã ããŒã«æ¢ãã®æ
ã®æ«ããã©ãäžå³ã«ããŒã«ã奪ããç¥éŸãåŒã³åºããããããŠãŒãã³ããšã£ãã«èšãæŸã£ãäžããªãé¡ããå¶ããŠãããããšã§äžå³ã®éæã黿¢ããããã®åŸãæç©ºã¯æŠè¡ã®é人ã»äºä»äººã®äžã§8ãæéã®ä¿®è¡ãç©ã¿6. Vector DBã«ãã質åå¿ç
Vector DBã«ãã 質åå¿çã®æé ã¯ã次ã®ãšããã§ãã
(1) VectorDBQAãæºåããŠè³ªåå¿çãå®è¡ã
from langchain import OpenAI, VectorDBQA
# VectorDBQAã®æºå
qa = VectorDBQA.from_llm(llm=OpenAI(), vectorstore=docsearch)
# Vector DBã«ãã質åå¿çã®å®è¡
print(qa.run(query))ãã©ã³ã¯ã¹7. Vector DBã«ãããœãŒã¹ä»ãã®è³ªåå¿ç
Vector DBã«ãã ãœãŒã¹ä»ãã®è³ªåå¿çã®æé ã¯ã次ã®ãšããã§ãã
(1) ãœãŒã¹æ å ±ã®è¿œå ã
# ãœãŒã¹æ
å ±ã®è¿œå
for i, d in enumerate(docsearch.docstore._dict.values()):
d.metadata = {'source': f"{i}-pl"}(1) VectorDBQAWithSourcesChainãæºåããŠè³ªåå¿çãå®è¡ã
from langchain.chains import VectorDBQAWithSourcesChain
# VectorDBQAWithSourcesChainã®æºå
chain = VectorDBQAWithSourcesChain.from_llm(
OpenAI(temperature=0),
vectorstore=docsearch
)
# ãœãŒã¹ä»ãã®è³ªåå¿çã®å®è¡
chain({"question": query}, return_only_outputs=True)Token indices sequence length is longer than the specified maximum sequence length for this model (1788 > 1024). Running this sequence through the model will result in indexing errors
{'answer': " The name of Vegeta's son is Trunks.", 'sources': '2-pl, 5-pl'}