はじめに
みなさん、こんにちは。もう5月も終わりですね・・・。4月からあっという間の2ヶ月が終わろうとしています。
前回はローカルLLMを使って、ゴミ出しの情報を答えるゴミ出LMを製作してみました。まだご覧になられてない方がいらっしゃいましたら、ぜひご覧ください!
今回は、これに応用編ということで、OPENAI_API_KEYを使って、より性能の高いゴミ出しLMへ進化させていきいたいと思います!
ちょっと寄り道。RAGについて。
前回、用語の整理としてLMやLLMなどについて語りました。今回も少し用語を紹介です。
今作っているシステムは、RAG(Retrieval Augmented Generation)といい、検索拡張生成というシステムになります。
普段使用しているLLM(chatGPTなどのツール)に、新しい知識を与えて常に最新の回答や、正確な回答ができるようにしておく技術になります。
さらに詳しく知りたい人は、以下の記事を参考にしてみてください!

作ってみる
前回との変更点
それでは早速作っていくのですが、前回と何が違うのかだけ、先に紹介しておきます。
今回大きく変わってくるのは、LLMのモデルとEmbedding生成の部分です。
前回作ったゴミ出しLMは、LLMのモデルがOllama、Embedding生成がSentence-transformersというのを使ってきました。今回は、この二つの役割を、OPENAI_API_KEYを使うことで、OpenAIのGPTやopenai.Embedding.createでこなすことができます。
ただ、前回の記事でも書いたように、これらには課金が発生するので、注意が必要です!
プログラムをつくる
今回は、札幌市の情報でゴミ出しLMを作っていきます。
全体的なプログラムの処理は、webページのテキスト抽出をしてから、テキストをチャンク分割します。その分割したテキストを、EmbeddingとFAISSで保存し、質問に対して回答を生成するというものです。
# ① Webページのテキスト抽出
def scrape_text(url):
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
return soup.get_text()
# ② テキストをチャンク分割
def chunk_text(text, chunk_size=500, chunk_overlap=50):
splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
return splitter.split_text(text)
# ③ EmbeddingとFAISSで保存
def create_vector_store(chunks):
embeddings = OpenAIEmbeddings()
return FAISS.from_texts(chunks, embeddings)
# ④ 質問を処理して回答を生成
def ask_question(vectorstore, query):
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
qa = RetrievalQA.from_chain_type(
llm=ChatOpenAI(temperature=0, model="gpt-4"),
chain_type="stuff",
retriever=retriever
)
return qa.run(query)
しかし、壁・・・。
しかし、このプログラムでいざ質問をしようとすると、なぜかうまく回答をしてくれません。質問に対して、答えるために情報が少ないと言ってきたり、誤った情報を提供してきたりします。これはなぜでしょうか・・・?


調べ進めてみると、どうやらwebから情報を抽出するときに、正しく情報が抽出できていないことがわかりました。それは、抽出した情報が文字化けや、HTMLの構造が複雑で正しく情報を抽出できていないことが原因でした。

また、最近弊社に導入されたAIエージェントのDevinにも、原因究明を手伝ってもらいました。すると、スクレイピング機能の問題点や、RAGパイプラインの最適化不足などを提案してくれました。また、その問題点について修正もしてくれました。天才!
(今後、Devinに関する記事も増やしていきますので、ぜひご覧ください!!)

再度実行してみる
修正してくれたコードを実行してみると、今度は問題なく回答をしてくれました!
また、ただゴミの名前だけでなく、備考欄の項目についても回答することができています。素晴らしいですね!
.png?resize=510%2C287&ssl=1)
まとめ
さて、今回はゴミ出しLMの第二弾ということで、OPENAI_API_KEYを使用してLLMのモデルとEmbedding生成の部分をそれぞれ代用させてみました。こうすることで、オンラインでも操作することができるようになり、ますます実用性が増したと思います。
今回作ったコードも、GitHubに共有していますので、ぜひご覧ください。
今回もご覧いただき、ありがとうございました!