🔥
Semantic Kernel Pythonでユーザーごとの記憶を持たせてみる
MS版LangChainことSemantic KernelのPython版が出たので気になっていたSemantic Memory関連の動作を試した。
セットアップ系
今のところ.envは必須らしい。
KV = {} # DBのかわり
def init_kernel():
k = sk.Kernel()
api_key, org_id = sk.openai_settings_from_dot_env()
k.config.add_chat_backend(
"chat-gpt", sk_oai.OpenAIChatCompletion("gpt-3.5-turbo", api_key, org_id)
)
k.config.add_embedding_backend(
"ada", sk_oai.OpenAITextEmbedding("text-embedding-ada-002", api_key, org_id)
)
k.register_memory_store(memory_store=sk.memory.VolatileMemoryStore())
return k
def build_chat_function(k):
prompt_config = sk.PromptTemplateConfig.from_completion_parameters(
max_tokens=2000, temperature=0.7, top_p=0.8
)
prompt_template = sk.ChatPromptTemplate("""Chat:
{{$chat_history}}
User: {{$user_input}}
ChatBot:""", k.prompt_template_engine, prompt_config)
prompt_template.add_system_message("""
あなたはChatBotです。Userの質問にフレンドリーに答えてください。答えは10単語程度にしてください。
""")
function_config = sk.SemanticFunctionConfig(prompt_config, prompt_template)
return k.register_semantic_function("ChatBot", "Chat", function_config)
呼び出し
chat関数にユーザーIDを渡して呼び出せるようにする。
kernel = init_kernel()
chat_function = build_chat_function(kernel)
async def chat(user_id, message):
context_vars = KV.get(user_id, sk.ContextVariables(variables=dict(
user_input="",
chat_history="",
)))
context_vars["user_input"] = message
talk = f'{user_id}: ' + context_vars["user_input"]
print(talk)
answer = await kernel.run_async(chat_function, input_vars=context_vars)
print('ChatBot: ' + answer.result)
await kernel.memory.save_information_async(user_id, talk, uuid.uuid4())
context_vars["chat_history"] += f"\n{talk}\nChatBot:> {answer.result}\n"
KV[user_id] = context_vars
return "\n".join([talk, 'ChatBot: ' + answer.result])
await chat('user-1', '私は今日トマトのオムライスを食べました。')
await chat('user-2', '私は今日テニスをしました。')
await chat('user-1', '私は何を食べましたか?')
await chat('user-2', '私は何を食べましたか?')
ChatBotはuser-1さんとuser-2さんを区別していることが分かる。
output
user-1: 私は今日トマトのオムライスを食べました。
ChatBot: それは美味しそうですね。お腹いっぱいになりましたか?
user-2: 私は今日テニスをしました。
ChatBot: スポーツをするのはとても良い運動になりますね。楽しかったですか?
user-1: 私は何を食べましたか?
ChatBot: あなたは今日トマトのオムライスを食べたと言いました。
user-2: 私は何を食べましたか?
ChatBot: 申し訳ありません、あなたは何を食べたか教えてくれませんでした。今日何か食べましたか?
メモリは個別にキーを指定して中身をセマンチックに検索できる。
memories = await kernel.memory.search_async('user-1', 'Userの今日の活動')
print("(´ー`)...: " + memories[0].text)
memories = await kernel.memory.search_async('user-2', 'Userの今日の活動')
print("(´ー`)...: " + memories[0].text)
(´ー`)...: user-1: 私は今日トマトのオムライスを食べました。
(´ー`)...: user-2: 私は今日テニスをしました。
Discussion