Open7
langchan を使用して複数の PDF を入力してチャットを行う機能ツールを作成する/
openAI の API をそのまま使用して要約ツールを作成していたので, 要約作成が楽になるLangchain を導入したうえで, いい感じに要約文を作成してもらえるようにする.
更に一つのファイルだけではなく複数のファイルを使用できるようにしていく.
参考サイト
Sequential Chain
出力したデータをもとにして新たに出力させるやつ.
サンプルコードが一部動かなかったため少し修正している.
openai APIの仕様が一部変わってるみたい.
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain, SimpleSequentialChain
llm = ChatOpenAI(model_name="gpt-3.5-turbo")
prompt_1 = PromptTemplate(
input_variables=["job"],
template="{job}に一番オススメのプログラミング言語は?\nプログラミング言語:",
)
chain_1 = LLMChain(llm=llm, prompt=prompt_1)
prompt_2 = PromptTemplate(
input_variables=["programming_language"],
template="{programming_language}を学ぶためにやるべきことを3ステップで100文字で教えて。",
)
chain_2 = LLMChain(llm=llm, prompt=prompt_2)
overall_chain = SimpleSequentialChain(chains=[chain_1, chain_2], verbose=True)
print(overall_chain("消防士"))
参考 : https://zenn.dev/umi_mori/books/prompt-engineer/viewer/langchain_chains
sonyの2023年度第三四半期の有価証券報告書をまとめさせる.
これだけでかけるのは便利だけど, どのモデル使ってるのかわからない.
from langchain.indexes import VectorstoreIndexCreator
from langchain_community.document_loaders.pdf import PyPDFLoader
from langchain_community.vectorstores.chroma import Chroma
from langchain_openai import OpenAIEmbeddings
loader = PyPDFLoader("sony.pdf")
index = VectorstoreIndexCreator(
vectorstore_cls=Chroma, # Default
embedding=OpenAIEmbeddings(), # Default
).from_loaders([loader])
query = "有価証券報告書の内容をまとめてください. 最後に今後の発展性について述べてください."
answer = index.query(query)
print(answer)
複数のPDFを入力として与える.
2社の売上を比較すると下記のような返答を得られた.
Toyotaの売上は、2022年に27,464,033百万円、2023年に34,022,720百万円であり、営業利益はそれぞれ1,588億円となっています。一方、Sonyの売上は、2022年に25,383,850百万円、2023年に31,511,767百万円であり、営業利益はそれぞれ1,475億円となっています。
from langchain.indexes import VectorstoreIndexCreator
from langchain_community.document_loaders.pdf import PyPDFLoader
from langchain_community.vectorstores.chroma import Chroma
from langchain_openai import OpenAIEmbeddings
loader_sony = PyPDFLoader("sony.pdf")
loader_toyota = PyPDFLoader("toyota.pdf")
index = VectorstoreIndexCreator(
vectorstore_cls=Chroma, # Default
embedding=OpenAIEmbeddings(), # Default
).from_loaders([loader_sony, loader_toyota])
query = "Toyota と Sony それぞれの売上と利益を教えて下さい"
answer = index.query(query)
print(answer)
コマンドライン上での簡単なチャット
from langchain.chains.conversation.base import ConversationChain
from langchain.memory import ConversationBufferMemory
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model_name="gpt-3.5-turbo")
template = '''
あなたは優秀なAIです. ユーザーからの質問に対して, あなたは適切な回答を返すことができます.
会話内容:
{history}
人間: {input}
AI:'''
prompt = PromptTemplate(
input_variables=['history', 'input'],
template=template
)
conversation = ConversationChain(
llm=llm,
prompt=prompt,
memory=ConversationBufferMemory(
human_prefix='人間'
),
verbose=False)
def chat(message, history):
history = history or []
response = conversation.predict(input=message)
history.append((message, response))
return history, history
if __name__ == '__main__':
history = []
while True:
message = input('人間:')
history, response = chat(message, history)
# 最新のレスポンスを表示
ai_text = response[-1][1]
print('AI:', ai_text)
``` python
## 参考
https://qiita.com/hideki/items/b26154ab503fd3394a0b
大きなPDFファイルの要約
PDFによっては改行や句読点で区切ることが難しいことがあるので単純に
import PyPDF2
from langchain.chains.combine_documents.base import BaseCombineDocumentsChain
from langchain.chains.summarize import load_summarize_chain
from langchain.docstore.document import Document
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain_text_splitters import RecursiveCharacterTextSplitter
refine_first_template = """
これからPDFファイルの要約を行います
テーマごとに文章をまとめてください.
# 要約する文章
{text}
"""
refine_template = """
これからPDFファイルの要約を行います
テーマごとに文章をまとめてください.
# 生成する文章の例
1章: ****
- 内容1
- 内容2
2章: ****
- 内容1
- 内容2
3章: ***
<同上>
# 要約する文章
{existing_answer}
{text}
"""
refine_first_prompt = PromptTemplate(input_variables=["text"], template=refine_first_template)
refine_prompt = PromptTemplate(input_variables=["existing_answer", "text"],
template=refine_template)
refine_chain: BaseCombineDocumentsChain = load_summarize_chain(
ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo-16k"),
chain_type="refine",
question_prompt=refine_first_prompt,
refine_prompt=refine_prompt)
pdf_path = "sony.pdf"
# PDFローダーの定義
read_text = ''
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f, strict=False)
for i in range(len(reader.pages)):
page = reader.pages[i]
read_text += page.extract_text()
# 指定したサイズでテキストを分割する
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=10000, chunk_overlap=1000
)
texts = text_splitter.split_text(read_text)
docs = [Document(page_content=t) for t in texts]
result = refine_chain.invoke({"input_documents": docs}, return_only_outputs=True)
print(result["output_text"])
参考