AI radio makerへの道2
なんかいろいろやっておりましたらlangchainが半分というよくわからないコードになってしまいました。
import json
import os
import time
import anthropic
import openai
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
os.environ["ANTHROPIC_API_KEY"] = "sk-ant-******************************"
openai_key = os.environ.get("OPENAI_API_KEY")
system_content = """
あなたは優秀なラジオリポーターになりきってください。名前は、エナです。
あなたはこれから現場取材を行います。
相手は解説役ですので、質問をしながら話を深掘りしてください。
また、生放送ですので、質問は短い文章になるようにしてください。
会話には少しユーモアを加えるようにしてください。自然なはなし口調でお願いします。
解説者の出力はしないでください。
また、前回の会話からなるべく違う質問をしてください。"""
system_content2 = """
あなたはラジオゲストになりきってください。これからインタビューを受けます。
あなたの名前は、金剛地です。
これは生放送ですので、回答は短い文章にしてください。
また、音声のみのコミュニケーションになりますので、相手に伝わるように長文は避けてください。
自然なはなし口調でお願いします。同じような質問が来た場合言い回しを変えてみてください。"""
client1 = anthropic.Anthropic()
client2 = openai.OpenAI()
messages1 = []
messages2 = []
theme = "ドラえもん" # テーマを設定
loader = TextLoader("./doraemon.txt", encoding="utf-8")
texts = loader.load_and_split()
faiss_index = FAISS.from_documents(texts, OpenAIEmbeddings())
messages2.append({"role": "system", "content": system_content2})
tools = [
{"type": "function",
"function":{
"name": "similarity_search_and_answer",
"description": "Answer the given question by referring to the results of similarity search.",
"parameters": {
"type": "object",
"properties": {
"question": {
"type": "string",
"description": "question",
},
"results": {
"type": "string",
"description": "results of search",
},
},"required": ["results"]
}
}
}
]
def similarity_search_and_answer(question):
"""Answer the given question by referring to the results of similarity search."""
retriever = faiss_index.as_retriever()
template = """contextに従って回答してください:
{context}
質問: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI(model_name="gpt-3.5-turbo-0125")
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| model
| StrOutputParser()
)
results = chain.invoke(question)
return json.dumps({"results": results})
def reporter(u):
messages1.append({"role": "user", "content": u})
resp = client1.messages.create(
model="claude-3-haiku-20240307",
system=system_content,
max_tokens=150,
temperature=0.7,
messages=messages1
)
a = resp.content[0].text
messages1.append({"role": "assistant", "content": a})
return a
def interviwee(u):
messages2.append({"role": "user", "content": u})
resp = client2.chat.completions.create(
model="gpt-3.5-turbo-0125",
messages=messages2,
tools=tools,
tool_choice="auto",
)
resp_mess = resp.choices[0].message
tool_calls = resp_mess.tool_calls
if tool_calls:
available_functions = {
"similarity_search_and_answer": similarity_search_and_answer, }
messages2.append(resp_mess) # ここは型があってないけどこのままでいい。
for tool_call in tool_calls:
function_name = tool_call.function.name
function_to_call = available_functions[function_name]
function_args = json.loads(tool_call.function.arguments)
function_response = function_to_call(
question=function_args.get("question"),
)
messages2.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
}
)
second_resp = client2.chat.completions.create(
model="gpt-3.5-turbo-0125",
messages=messages2,
)
a = second_resp.choices[0].message.content
messages2.append({"role": "assistant", "content": a})
return a
a = resp.choices[0].message.content
messages2.append({"role": "assistant", "content": a})
return a
def interview(u,interview_msgs):
a_rep = reporter(u)
print(a_rep)
interview_msgs.append({"role": "reporter", "content": a_rep})
time.sleep(0.5)
a_int = interviwee(a_rep)
print(a_int)
interview_msgs.append({"role": "interviewee", "content": a_int})
def main():
print(f"インタビューを始めます。{theme}についてお話ししてください。")
count = 0
t_count = 3 # インタビュー回数
interview_msgs = []
while count < t_count:
u = f"""インタビューをしてください。{theme}についてお二人で語ってもらいます。
リポーターから解説者に質問をしてください。お二人の会話をあと
{t_count - count}回で終わらせてください。お願いします。"""
interview(u,interview_msgs)
count += 1
if count == t_count:
print("\n インタビューが終了しました。")
break
# pprint(interview_msgs)
if __name__ == "__main__":
main()
とりあえずRAGがちゃんと実装できたので、きりがいいのでここで掲載します。受け答えはプロンプトで制御するのがいいのか、はたまた違う方法でするのか。まだ決めてませんがこのコードでもインタビューは一応往復します。
doraemon.txtはwikipediaからコピペしたテキストファイルです。ダウンロードして環境に貼り付けてください。
この記事が気に入ったらサポートをしてみませんか?