ローカルLLMでRAG over Code
ローカルAgentで何をするにせよ、先人の資料やコードを読まないと始まりません。趣味で遊んでる程度の人が、公式ドキュメントを読んだだけでは何にもわからないですからね!
つまり、今、必要なのは!コードの読解を助けてくれるAgentです。
前回のコードにRAG over Codeの能力を追加して、リポジトリの読解を助けてもらいましょう。そうしましょう。
LangChain公式のユースケースは基本的にはChatGPT APIを前提としています。GPT-3.5 turbo/GPT-4の能力を前提にしているということです。
ローカルLLMの能力は比較にならないほど低いので、Agentとして推敲(Chain-of-Thought)させることで何とか達成させます。
Embeddings
Retrieval Augment Generation (RAG)でLLMにドキュメント検索能力を持たせます。そのためにはembeddingsといって、テキストの類似度で検索できるデータベースを作成する必要があります。
HuggingFaceでembeddingsが無料で提供されているので、そちらを利用させていただきましょう。
HuggingFaceに登録してAPIキーを取得してください。
そして、ファイルにキーを書き込んで、そちらを参照するようにします。
# config.py
HUGGINGFACEHUB_API_TOKEN = "your_token_here"
参照したいリポジトリをgit cloneする
open-interpreterを参照しようと思います。
これはすごいツールなので、いろんな学びがありそうです。
git clone "https://github.com/KillianLucas/open-interpreter"
emeddingsで作成されたclone リポジトリのディレクトリを参照します。
Retriever
まずは検索に必要なemeddingsとretrieverを作成します。
repo_pathにcloneリポジトリのディレクトリを指定してください。
from langchain.tools import DuckDuckGoSearchRun
from langchain.agents import Tool, initialize_agent
from langchain.chains import LLMMathChain
from pydantic import BaseModel, Field
from langchain.llms import HuggingFacePipeline
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
from langchain.document_loaders.generic import GenericLoader
from langchain.document_loaders.parsers import LanguageParser
from langchain.text_splitter import Language
from langchain.text_splitter import RecursiveCharacterTextSplitter
import os
from config import HUGGINGFACEHUB_API_TOKEN
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from langchain.agents.agent_toolkits import create_retriever_tool
# API TOKENS
os.environ["HUGGINGFACEHUB_API_TOKEN"] = HUGGINGFACEHUB_API_TOKEN
# git clone "https://github.com/KillianLucas/open-interpreter"
repo_path = "~/open-interpreter"
# Load
loader = GenericLoader.from_filesystem(
repo_path + "/interpreter",
glob="**/*",
suffixes=[".py"],
parser=LanguageParser(language=Language.PYTHON, parser_threshold=500),
)
documents = loader.load()
python_splitter = RecursiveCharacterTextSplitter.from_language(language=Language.PYTHON, chunk_size=2000, chunk_overlap=200)
texts = python_splitter.split_documents(documents)
# pip install sentence-transformers
embeddings = HuggingFaceEmbeddings()
# pip install faiss-cpu
db = FAISS.from_documents(texts, embeddings)
retriever = db.as_retriever()
retriever.search_kwargs["distance_metric"] = "cos"
retriever.search_kwargs["fetch_k"] = 20
retriever.search_kwargs["maximal_marginal_relevance"] = True
retriever.search_kwargs["k"] = 8
近傍探索にはMeta社が公開しているfaissを使用します。これも無料です。
faissをgpuで動作させる環境を整えるのは難しいので、cpuにしています。
LLM
# Local LLM
model_name_or_path = "TheBloke/openchat_3.5-GPTQ"
# To use a different branch, change revision
# For example: revision="gptq-4bit-32g-actorder_True"
model = AutoModelForCausalLM.from_pretrained(
model_name_or_path,
device_map="auto",
trust_remote_code=False,
revision="gptq-8bit-32g-actorder_True",
)
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, use_fast=True)
pipe = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
max_new_tokens=512,
do_sample=True,
temperature=1.0,
top_p=0.95,
top_k=40,
repetition_penalty=1.1,
)
llm = HuggingFacePipeline(pipeline=pipe)
Agent能力を満たすLLM "TheBloke/openchat_3.5-GPTQ"を使用します。
Tools
Agentが利用できるツールにリポジトリ検索ツールを追加します。
# Tools
tool = create_retriever_tool(
retriever,
"search-repository",
"Searches and returns repository.",
)
tools = [tool]
# pip install duckduckgo-search
search = DuckDuckGoSearchRun()
tools.append(
Tool(
name="duckduckgo-search",
func=search.run,
description="useful for when you need to answer questions. You should ask targeted questions",
)
)
# pip install numexpr
llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=True)
tools.append(
Tool.from_function(
func=llm_math_chain.run,
name="Calculator",
description="useful for when you need to answer questions about math",
)
)
Agent
pythonのファイルを指定して、Agentに要約してもらいます。
# agent
agent = initialize_agent(
tools,
llm,
agent="zero-shot-react-description",
verbose=True,
handle_parsing_errors=True,
)
text = "Summarize 'interpreter/core/code_interpreters/languages/powershell.py' in the repository."
output = agent.run(text)
output = output.split("\n")[0]
print(output)
Output
いいかんじです!第一歩としては上出来ではないでしょうか?
この記事が気に入ったらサポートをしてみませんか?