LangChain ã§ç€Ÿå ãã£ãããããäœã£ãŠã¿ã
ããã«ã¡ã¯ãã¯ã©ãŠããšãŒã¹ SRE ãã£ããžã§ã³æå±ã®èã§ãã
ä»åã¯ãçŸåšæãæ®åããŠãã察話å AI ãµãŒãã¹ã§ãã ChatGPT ã§äœ¿çšãããŠããã¢ãã«ãšãLLM ã䜿ã£ãã¢ããªã±ãŒã·ã§ã³éçºã«ç¹åããã©ã€ãã©ãªã§ãã LangChain ãçšããŠç€Ÿå åãã®ãã£ããããããäœæããŸãã
ã¿ãŒã²ãã
- ä»»æã®ããŒã¿ãå ã«åçãè¡ããã£ããããããäœæãããæ¹
- ä»»æã®ããŒã¿ãå ã«åçãããä»çµã¿ãç¥ãããæ¹
ChatGPT ãšã¯

ChatGPT ãšã¯ããŠãŒã¶ãŒãå
¥åãã質åã«å¯ŸããŠããŸãã§äººéã®ããã«èªç¶ãªå¯Ÿè©±åœ¢åŒã§AIãçãããã£ãããµãŒãã¹ã§ãã2022 幎 11 æã«å
¬éãããŠä»¥æ¥ãåç粟床ã®é«ãã話é¡ãšãªããå©çšè
ãæ¥å¢ããŠããŸãã
人工ç¥èœã®ç ç©¶éçºæ©é¢ãOpenAIãã«ããéçºãããŸããã
å·çæç¹ã§ã¯ãGPT-3.5ãGPT-4 ãšããå€§èŠæš¡èšèªã¢ãã« (LLM) ã䜿çšãããŠããŸãã
LangChain ãšã¯

LangChain ãšã¯ãLLM ãæŽ»çšããŠãµãŒãã¹ãéçºããéã«åœ¹ç«ã€ã©ã€ãã©ãªã§ãã
LangChainã«ã¯å€§ããåã㊠2 ã€ã®åŽé¢ããããŸãã1 ã€ã¯ãLLM ãçšããã¢ããªã±ãŒã·ã§ã³éçºã«å¿ èŠãªã³ã³ããŒãã³ãããæœè±¡åãããã¢ãžã¥ãŒã«ãšããŠæäŸããŠããããšã§ãããã 1 ã€ã¯ãç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã«ç¹åããæ©èœãåããã¢ãžã¥ãŒã«ãæäŸããŠããããšã§ãã
ãããã®ã¢ãžã¥ãŒã«ã䜿çšããããšã§ãå°ãªãå®è£ éã§ã®ãããã¿ã€ãã®äœæãå¯èœãšãªããŸãããŸããç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã«ç¹åããæ©èœãæã€ã¢ãžã¥ãŒã«ã掻çšããããšã«ãããç¬èªæ§ã®é«ãã¢ããªã±ãŒã·ã§ã³ã®å®è£ ãå®çŸã§ããŸãã
äž»èŠã¢ãžã¥ãŒã«
å·çæç¹ã§ã¯ãã¢ãžã¥ãŒã«ã¯å€§ãã以äžã® 6 ã€ã«åé¡ãããŠããŸãã
ãããã®ã«ããŽãªã«å¯ŸããŠãæ©èœã«å¿ããŠããã«çްããåé¡ãããŠããŸãã
-
Model I/O
- Prompts
- LLMs
- Chat Models
- Output Parsers
-
Retrieval
- Document loaders
- Text Splitting
- Text embedding models
- Vector stores
- Retrievers
- Indexing
-
Agents
- Agent
- AgentExecutor
- Tools
- Toolkits
- Chains
- Memory
- Callbacks
RAG ã«ã€ããŠ
瀟å
ãã£ãããããã§ã¯ãäŒæ¥ãæã€ç€Ÿå
ããŒã¿ãåèã«åçãçæããå¿
èŠããããŸãã
ãããå®çŸããããã«äœ¿çšãããã®ããRAG (Retrieval Augmented Generation) ãšåŒã°ããä»çµã¿ã§ãã
RAG ã§ã¯ã以äžã®æµãã§ä»»æã®ããŒã¿ãå ã«ããåçãè¡ãããŸãã
- ãŠãŒã¶ãŒã®è³ªåãå ã«é¢é£æ§ã®ããããŒã¿ããã¯ã¿ãŒã¹ãã¢ããæ€çŽ¢ãååŸ
- 質åãšååŸããããŒã¿ãåã蟌ãã ããã³ãããäœæ
- LLM ã«åãåãã

RAG ã®æµã
Retrieval ã§ RAG ãå®è£
RAG ãå®è£
ããããã«äœ¿çšããã¢ãžã¥ãŒã«ããRetrieval ã§ãã
以äžã®æ©èœã䜿çšããŸãã
- Document loadersïŒããŒã¿ãœãŒã¹ããããã¥ã¡ã³ããèªã¿èŸŒã
- Text SplittingïŒããã¥ã¡ã³ãããã£ã³ã¯ãšããåäœã«åå²
- Text embedding modelsïŒããã¹ãããã¯ãã«å
- Vector storesïŒãã¯ãã«åããããã¹ãã®ä¿åå
- RetrieversïŒãŠãŒã¶ãŒå ¥åãšé¢é£ããããã¥ã¡ã³ããæ€çŽ¢ãååŸ

Retrieval ã®æµã (LangChain å
¬åŒããåŒçš)
ãã£ãããããäœæ
䜿çšã¢ãžã¥ãŒã«
ä»åã®ãã£ãããããã§ã¯ã以äžã®ã¢ãžã¥ãŒã«ã䜿çšããŸãã
Model I/O
ãLLMsããŸãã¯ãChat Modelsããšããã¢ãžã¥ãŒã«ã䜿çšããããšã«ãããããŸããŸãªèšèªã¢ãã«ãå ±éã®ã€ã³ã¿ãŒãã§ãŒã¹ã§äœ¿çšããããšãã§ããŸãã
OpenAI ã®æç« çæ API ã«ã¯ããCompletions APIããšãChat Completions APIãã®2ã€ããããåè ã LangChain ã§äœ¿çšããã«ã¯ LLMs ã¢ãžã¥ãŒã«ãåŸè ã䜿çšããã«ã¯ Chat Models ã¢ãžã¥ãŒã«ã䜿çšããŸãã
ä»åã¯ã以äžã®çç±ãã Chat Models ã¢ãžã¥ãŒã« (Chat Completions API) ã䜿çšããŸãã
- ææ°ã¢ãã« (gpt-4ãgpt-3.5-turbo) ã¯ãChat Completions API ã®ã¿ã§äœ¿çšå¯èœ
- Completions API ã¯ã¬ã¬ã·ãŒãªæ©èœãšãªã£ãŠããã2023 幎 7 æä»¥éã¢ããããŒããè¡ãããŠããªã
Retrieval
åè¿°ã®ããã«ããDocument loadersããText SplittingããText embedding modelsããVector storesããRetrieversãã䜿çšã RAG ãå®è£ ããŸãã
Chains
LLM ã䜿çšããã¢ããªã±ãŒã·ã§ã³ã§ã¯ãåã« LLM ã«å
¥åããŠåºåãåŸãŠçµããã§ã¯ãªããåŠçãé£éçã«ã€ãªãããããšãå€ãã§ãã
ä»åã®å Žåã ãšã以äžã®é£éçåŠçãçºçããŸãã
- ãŠãŒã¶ãŒå ¥åã Embedding
- é¢é£æ§ã®é«ãããã¹ããæ€çŽ¢ãååŸ
- ååŸããæ å ±ãããã³ããã«åã蟌ã
- æç« çæ API ãåŒã³åºããåçãååŸ
ãã®ãããªé£éããåŠçãå®çŸããã®ããChains ã¢ãžã¥ãŒã«ã§ãããäžèšã®äžé£ã®åŠçã®ããã« ãRetrievalQAã ãšãã Chain (åŠçã®ãŸãšãŸã) ãæäŸãããŠããŸãã

RetrievalQA ã®åºæ¬åäœ
Callbacks
Callbacksãšã¯ãã¢ããªã±ãŒã·ã§ã³ã®ãã®ã³ã°ãã¢ãã¿ãªã³ã°ãã¹ããªãŒãã³ã°ãªã©ãå¹ççã«ç®¡çããæ©èœã§ãã
ããã«ãããããã€ãã³ããçºçãããšããç¹å®ã®æ¡ä»¶ãæç«ããå Žåã«ãèªåçã«é¢æ°ãã¡ãœãããåŒã³åºãããšãã§ããŸãã
ä»åã¯ãStreamlitCallbackHandlerããšããã¢ãžã¥ãŒã«ã䜿çšããã¹ããªãŒãã³ã°ã§å¿çãååŸããŸãã
äºåæºå
Open AI API ããŒã®ååŸ
Chat Completion API ã䜿çšããããã«ãOpen AI ã® API ããŒãæºåããŸãã
-
Open AI ã® Web ãµã€ãã«ã¢ã¯ã»ã¹ãããã°ã€ã³ããŸãã
-
API ãã¯ãªãã¯ããéçºè åãã®ç»é¢ã«é·ç§»ããŸãã

-
API ããŒã®äžèЧç»é¢ã«é·ç§»ãããCreate new secret keyããã¯ãªãã¯ããŸãã

-
ä»»æã®ååãã€ããAPI ããŒãçºè¡ããŸãã

ãã¯ã¿ãŒããŒã¿ããŒã¹ã®ã»ããã¢ãã
瀟å ããã¥ã¡ã³ãããååŸãããã¯ãã«ããŒã¿ãæ ŒçŽãããã¯ã¿ãŒããŒã¿ããŒã¹ãšããŠãPinecone ã䜿çšããŸãã
-
Pinecone ã® Web ãµã€ãã«ã¢ã¯ã»ã¹ãããã°ã€ã³ããŸãã
-
ãCreate Indexããã¯ãªãã¯ããIndex ãäœæããŸããIndex ãšã¯ããã¯ãã«ããŒã¿ããŸãšããŠæ±ãåäœã®ããšã§ãã
ä»»æã®ååãå ¥åãããDimensionsãã®é ç®ã«ã¯ãOpen AI Embeddings API ã®æ¬¡å æ°ã§ããã1536ããå ¥åããŸãã

-
ãCreate Indexããã¯ãªãã¯ãããš Index ãäœæãããIndex ã®è©³çްç»é¢ã«é·ç§»ããŸãã

-
API ããŒäžèЧç»é¢ãããçºè¡ãããããŒã確èªã§ããŸãã

ããã±ãŒãžãšã©ã€ãã©ãªã®ã€ã³ã¹ããŒã«
ä»åã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãWeb ãã¬ãŒã ã¯ãŒã¯ãšã㊠streamlit ã䜿çšããŸãã
pip install streamlit
LangChain ã¢ãžã¥ãŒã«ãš Open AI ã® API ã䜿çšãããããlangchainããlangchain-communityããlangchain-openaiãããã±ãŒãžãã€ã³ã¹ããŒã«ããŸãã
ãŸãã.env ãã¡ã€ã«ã®å
容ãç°å¢å€æ°ã«èšå®ãããããpython-dotenvãããã±ãŒãžãã€ã³ã¹ããŒã«ããŸãã
pip install langchain langchain-community langchain-openai python-dotenv
Pinecone ã䜿çšãããããã¯ã©ã€ã¢ã³ãã©ã€ãã©ãªãpinecone-clientããã€ã³ã¹ããŒã«ããŸãã
ãŸããOpenAIEmbeddings ãå¿
èŠãšãããtiktokenããã€ã³ã¹ããŒã«ããŸãã
pip install pinecone-client tiktoken
PDF ãªã©ã®çã®ããã¥ã¡ã³ããããã¹ããšããŠèªã¿èŸŒããããunstructuredãããã±ãŒãžãã€ã³ã¹ããŒã«ããŸãã
pip install "unstructured[all-docs]"
ä»å䜿çšããããŒãžã§ã³ã¯ä»¥äžã®éãã§ãã
| ããã±ãŒãž(ã©ã€ãã©ãª)å | ããŒãžã§ã³ |
|---|---|
| streamlit | 1.30.0 |
| langchain | 0.1.4 |
| langchain-community | 0.0.16 |
| langchain-openai | 0.0.5 |
| python-dotenv | 1.0.1 |
| pinecone-client | 2.2.4 |
| tiktoken | 0.5.2 |
| unstructured | 0.12.2 |
ããŒã¿ã®ä¿å
ããã¥ã¡ã³ãããã¯ãã«åããPinecone ã«ä¿åããåŠçãå®è£
ããŠãããŸãã
ä»åã¯ç€Ÿå
ããã¥ã¡ã³ããšããŠãæ¥æ¬ãã£ãŒãã©ãŒãã³ã°åäŒãæäŸããŠããçæAIã®å©çšã¬ã€ãã©ã€ã³ã PDF ã«å€æã䜿çšããŸãã
Python ããã°ã©ã ãã Pinecone ã«æ¥ç¶ãããããç°å¢å€æ°ãšã㊠.env ãã¡ã€ã«ã« Pinecone ã® API ããŒãš Index åãç°å¢åãèšèŒããŸãã
ãŸããOpen AI ã¢ãžã¥ãŒã«ã䜿çšãããããOpen AI API ããŒãèšèŒããŸãã䜿çšããã¢ãã«ãtemperature ãèšèŒããŸãã
PINECONE_API_KEY=<API ããŒ>
PINECONE_INDEX=company-data
PINECONE_ENV=gcp-starter
OPENAI_API_KEY=<API ããŒ>
OPENAI_API_MODEL=gpt-3.5-turbo
OPENAI_API_TEMPERATURE=0.5
add_document.py ãã¡ã€ã«ã«åŠçãèšè¿°ããŠãããŸãã
import ãèšè¿°ããload_dotenv ã§ç°å¢å€æ°ãèšå®ããŸãã
import os
import sys
import pinecone
from dotenv import load_dotenv
from langchain_community.document_loaders import UnstructuredFileLoader
from langchain_openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain_community.vectorstores import Pinecone
load_dotenv()
Pinecone ã LangChain ã®ãã¯ã¿ãŒã¹ãã¢ãšããŠäœ¿çšããããã®é¢æ°ãå®çŸ©ããŸãã
def initialize_vectorstore():
pinecone.init(
api_key=os.environ["PINECONE_API_KEY"],
environment=os.environ["PINECONE_ENV"],
)
index_name = os.environ["PINECONE_INDEX"]
embeddings = OpenAIEmbeddings()
return Pinecone.from_existing_index(index_name, embeddings)
ã¡ã€ã³ã®åŠçãå®è£
ããŸãã
åŒæ°ã§äžãããããã¡ã€ã«ã UnstructuredFileLoader ã§èªã¿èŸŒã¿ãCharacterTextSplitter ã§åå²ã Pinecone ã«ä¿åããŸãã
ããã¥ã¡ã³ãã®ãã¯ãã«ååŠçã¯ããã¯ã¿ãŒã¹ãã¢ã«ããŒã¿ãä¿åããéã«å
éšçã«å®è¡ãããŸãã
if __name__ == "__main__":
file_path = sys.argv[1]
loader = UnstructuredFileLoader(file_path)
raw_docs = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=300, chunk_overlap=30)
docs = text_splitter.split_documents(raw_docs)
vectorstore = initialize_vectorstore()
vectorstore.add_documents(docs)
add_document.py ãå®è¡ããŸãã
python add_document.py <ããã¥ã¡ã³ããã¹>
Pinecone ã確èªãããšã16 åã®ãã¯ãã«ããŒã¿ãä¿åãããŠããŸãã

é¢é£æ å ±ãå ã«ããåç
質åã«é¢é£ããææžã Pinecone ããæ€çŽ¢ããåçããåŠçãå®è£ ããŠãããŸãã
internal_qa.py ãã¡ã€ã«ã«åŠçãèšè¿°ããŠãããŸãã
import ãèšè¿°ããload_dotenv ã§ç°å¢å€æ°ãèšå®ããŸãã
import os
import streamlit as st
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_community.callbacks import StreamlitCallbackHandler
from add_document import initialize_vectorstore
from langchain.chains import RetrievalQA
load_dotenv()
st.title("瀟å
ãã£ããããã")
ãã¯ã¿ãŒã¹ãã¢ããããŒã¿ãåç
§ãåçãè¡ãåŠçãå®çŸ©ããŸãã
ChatOpenAI ã¯ã©ã¹ãã OpenAI ã®èšèªã¢ãã«ã䜿çšããã€ã³ã¹ã¿ã³ã¹ãäœæããRetrievalQA ãçšããŠè³ªåã«é¢ããããŒã¿ãæ€çŽ¢ãåçãçæãã chain ãæ§ç¯ããŸãã
Retriever (質åã«é¢ããããŒã¿ãååŸããã€ã³ã¿ãŒãã§ãŒã¹) ã¯ããã¯ã¿ãŒã¹ãã¢ã®ã€ã³ã¹ã¿ã³ã¹ããäœæã§ããŸãã
def create_qa_chain():
vectorstore = initialize_vectorstore()
callback = StreamlitCallbackHandler(st.container())
llm = ChatOpenAI(
model_name=os.environ["OPENAI_API_MODEL"],
temperature=os.environ["OPENAI_API_TEMPERATURE"],
streaming=True,
callbacks=[callback],
)
qa_chain = RetrievalQA.from_llm(llm=llm, retriever=vectorstore.as_retriever())
return qa_chain
æåŸã« UI éšåãå®è£
ããŠãããŸãã
ãŠãŒã¶ãŒå
¥åãåãåããããã«å¯Ÿããå¿çãçæããŠãã£ãã圢åŒã§è¡šç€ºããã€ã³ã¿ãŒãã§ãŒã¹ãäœæããŸãã
st.session_state ã䜿çšããããšã§ãäŒè©±å±¥æŽãäžæçã«ä¿æãããŸãã
if "messages" not in st.session_state:
st.session_state.messages = []
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
prompt = st.chat_input("What's up?")
if prompt:
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
qa_chain = create_qa_chain()
response = qa_chain.invoke(prompt)
st.session_state.messages.append({"role": "assistant", "content": response["result"]})
streamlit ã³ãã³ãã䜿çšããã¢ããªã±ãŒã·ã§ã³ãèµ·åããŸãã
streamlit run internal_qa.py --server.port 8080
以äžã®ç»é¢ã衚瀺ãããŸããã

質åãããŸãã
ãã¯ã¿ãŒã¹ãã¢ã«ä¿åããæ
å ±ãå
ã«åçãçæãããŸããã

ãŸãšã
ä»åã¯ãLangChain ã䜿çšããä»»æã®ããŒã¿ãå ã«åçãè¡ããã£ããããããäœæããŸããã
LangChain ã䜿çšããããšã§ãããŸããŸãªã¢ãã«ãçµ±äžã®ã€ã³ã¿ãŒãã§ãŒã¹ã§æ±ãããšãã§ããŸããããŸããLLM ãçšããã¢ããªã±ãŒã·ã§ã³ã«å¿ èŠãªæ©èœãç°¡åã«å®è£ ããããšãã§ããŸããã
äžæ¹ã以äžã®ç¹ã«ã¯æ³šæãå¿ èŠã§ãã
- å
¬åŒããã¥ã¡ã³ããåããã«ãã
- æžç± (ChatGPT / LangChain ã«ãããã£ããã·ã¹ãã æ§ç¯ïŒ»å®è·µïŒœå ¥é) ã GitHub ãªããžããªãåèã«ããŠå®è£ ããã
- ã¢ããããŒããé »ç¹ã«è¡ããã
- ä»å䜿çšãã RetrievalQA ã¯æ¢ã«ã¬ã¬ã·ãŒãšãªã£ãŠããã
LangChain ã䜿çšããŠãLLM ãæŽ»ãããã¢ããªã±ãŒã·ã§ã³ãäœã£ãŠã¿ãŠã¯ãããã§ããããã
Discussion