Closed3

AIエージェント

cygkichicygkichi

LangChainと検索ツールエージェントとstreamlitとAnthropic

概要

langchainのgithubに、streamlitとlangchainを使用した会話履歴を持つ検索ツール付きエージェントのデモアプリが公開されていた。こちらをAnthropic用に書き換えながら読んでみたため、理解した点や詰まった点をメモしておく。
https://github.com/langchain-ai/streamlit-agent/blob/main/streamlit_agent/search_and_chat.py

作ったもの

メモ

msg,memory

msgs = StreamlitChatMessageHistory()
memory = ConversationBufferMemory(chat_memory=msgs, return_messages=True, memory_key="chat_history", output_key="output")

msgはuserとaiの会話履歴で、中間処理は含めない。
memoryはよくわからんが、msgをmemoryにいれて、memoryをAgentExecutorに入れとくことで、AgentExecutorを実行したとき、会話履歴がmsgに追加される。

userメッセージから始める

if len(msgs.messages) == 0 or st.sidebar.button("Reset chat history"):
    msgs.clear()
    msgs.add_user_message("こんにちは。これから質問しますので日本語で答えてください。")
    msgs.add_ai_message("承知しました。何を調べますか?")
    st.session_state.intermediate_steps = {}

会話履歴をaiメッセージを先頭に入れるとエラーになるので、無理やりuserメッセージを挟んだ。

StreamlitCallbackHandler, RunnableConfig

st_cb = StreamlitCallbackHandler(st.container(), expand_new_thoughts=False)
cfg = RunnableConfig()
cfg["callbacks"] = [st_cb]
response = executor.invoke(prompt, cfg)

この辺もよくわからん。最終回答の直前に「Complete!」と記載されたステータスコンテナが表示されるのも、ここの処理のためだと思うが、よくわからん。

cygkichicygkichi

langchainのメモリについて

概要

メモリクラスが全然理解できていないので、以下を見ながら色々試したメモ。
https://python.langchain.com/docs/modules/memory/adding_memory/

メモ

とりあえず動かしてみる

from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory
from langchain_core.prompts import PromptTemplate
from langchain_anthropic import ChatAnthropic

template = """You are a chatbot having a conversation with a human.

{chat_history}
Human: {human_input}
Chatbot:"""

prompt = PromptTemplate(
    input_variables=["chat_history", "human_input"], template=template
)
memory = ConversationBufferMemory(memory_key="chat_history")

llm = ChatAnthropic(model='claude-3-haiku-20240307')
llm_chain = LLMChain(
    llm=llm,
    prompt=prompt,
    verbose=True,
    memory=memory,
)

llm_chain.predict(human_input="よろしくね〜")

動いた

> Entering new LLMChain chain...
Prompt after formatting:
You are a chatbot having a conversation with a human.


Human: よろしくね〜
Chatbot:

> Finished chain.
'こんにちは。はい、私はチャットボットです。人間の方と会話させていただくのを楽しみにしています。どのようなお話ができますでしょうか?何か質問やご相談があれば私なりに答えさせていただきますので、気

llm_chain.predictを使用するだけで、会話履歴とかも保存しておいてくれてるようだ。

llm_chain.predict(human_input="例えば?")
> Entering new LLMChain chain...
Prompt after formatting:
You are a chatbot having a conversation with a human.

Human: よろしくね〜
AI: こんにちは。はい、私はチャットボットです。人間の方と会話させていただくのを楽しみにしています。どのようなお話ができますでしょうか?何か質問やご相談があれば私なりに答えさせていただきますので、気軽に話しかけてください。
Human: 例えば?
Chatbot:

> Finished chain.
'では、例えば以下のようなお話題が考えられます:\n\n- 趣味や日常生活について - 読書、映画、料理、旅行など、あなたの好きなことについて教えてください。楽しい会話ができると思います。\n\n- 最近のニュースや世の中の出来事 - 気になるニュースや話題について一緒に意見を交換できます。社会問題など、建設的な議論ができるかもしれません。\n\n- 将来の夢や目標 - あなたの将来の抱負や目標について教えていただけますか?励ましのアドバイスができるかもしれません。\n\n- 好きな有名人について - 俳優、アーティスト、スポーツ選手など、あなたの尊敬する有名人についてお聞かせください。\n\n- 旅行の思い出 - 印象に残る旅行の思い出を共有していただけると楽しいですね。\n\nこれらをはじめ、さまざまな話題で楽しく会話を重ねていきましょう。どのようなお話をしたいですか?'

LLMChainとは?

グラフみてもよくわからん。

print(llm_chain.get_graph().draw_ascii())
# +------------+   
# | ChainInput |   
# +------------+   
#         *        
#         *        
#         *        
#   +----------+   
#   | LLMChain |   
#   +----------+   
#         *        
#         *        
#         *        
# +-------------+  
# | ChainOutput |  
# +-------------+  

https://api.python.langchain.com/en/latest/chains/langchain.chains.llm.LLMChain.html

[Deprecated] Chain to run queries against LLMs.

非推奨になっていた。今は、LCEL(※prompt | llmみたいなやつ)を使うほうが良いのだろう

LCELで書き直す

LCELで書きたいけど、memoryをpromptにどう入れればいいかわからないので調べてみます。

同じような事を考えている方がいた。
https://twitter.com/hmdev3/status/1760079042605433046

ここ(RunnableWithMessageHistory)を見ると良いらしい。
https://python.langchain.com/docs/expression_language/how_to/message_history/

会話履歴を構造化(ツリー構造とか)して、保存しておくような場合はどうしたらよいだろう?

cygkichicygkichi

langchainのメモリについて(その2)

RunnableWithMessageHistoryについてnpakaさんの記事にいいのがあった。
https://note.com/npaka/n/nbd04bdc041cb

メモ

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory

prompt_template = ChatPromptTemplate.from_messages(
    [
        MessagesPlaceholder(variable_name="history"), 
        ("human", "{input}"),
    ]
)

llm = ChatAnthropic(model='claude-3-haiku-20240307')

runnable = prompt_template | llm


store = {}

def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]

runnable_with_history = RunnableWithMessageHistory(
    runnable,
    get_session_history,
    input_messages_key="input",
    history_messages_key="history",
)

res = runnable_with_history.invoke({'input':'よろしく!'}, config={"configurable": {"session_id": "123"}})

ポイント

  • プロンプトテンプレートにMessagesPlaceholderを入れる。
  • キーがセッションID、値が会話履歴(ChatMessageHistory)の辞書型変数を用意する。
print(runnable_with_history.get_graph().draw_ascii())
#                   +------------------------+              
#                   | Parallel<history>Input |              
#                   +------------------------+              
#                      ***               ***                
#                   ***                     ***             
#                 **                           **           
# +------------------------+               +-------------+  
# | Lambda(_enter_history) |               | Passthrough |  
# +------------------------+               +-------------+  
#                      ***               ***                
#                         ***         ***                   
#                            **     **                      
#                  +-------------------------+              
#                  | Parallel<history>Output |              
#                  +-------------------------+              
#                                *                          
#                                *                          
#                                *                          
#                     +--------------------+                
#                     | ChatPromptTemplate |                
#                     +--------------------+                
#                                *                          
#                                *                          
#                                *                          
#                       +---------------+                   
#                       | ChatAnthropic |                   
#                       +---------------+                   
#                                *                          
#                                *                          
#                                *                          
#                    +---------------------+                
#                    | ChatAnthropicOutput |                
#                    +---------------------+
このスクラップは2025/01/04にクローズされました