LangChainで引き続き遊ぶ
前回の修行でLangChainの「チェーン」「エージェント」のサンプルを実行したので、今回は残りの「メモリ」「チャットとの組み合わせ」を試してみる。
LangChainのMemoryサンプル
教科書は引き続きLangChainのスターターガイドだ。全部英語だけど、ブラウザの自動翻訳をONすればちゃんと読めるレベルの訳文になってくれるので問題なく勉強できる。スバラシイ。ときどき「は?」みたいな翻訳結果になるときもあるけど、そのときは原文を別の翻訳サイトに突っ込めばいいのだ…。
とりあえずサンプルコードを書く。サンプルからLLMモデルだけGPT-3.5に変えておく。これは料金モデルの都合であり、gpt-3.5-turboのほうがtext-davinci-003より安いのだ(まじで謎)。とはいえ個人で遊ぶレベルなので、無料枠の18ドルのうちまだ1ドルも使っていないのでそこまで気にしなくてもいいはず…
import os
from langchain import OpenAI, ConversationChain
from langchain.chat_models import ChatOpenAI
os.environ["OPENAI_API_KEY"] = "XXX"
llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo")
conversation = ConversationChain(llm=llm, verbose=True)
output = conversation.predict(input="Hi there!")
print(output)
output = conversation.predict(input="I'm doing well! Just having a conversation with an AI.")
print(output)
会話の履歴を全部覚えるモードになっているらしい。最初のこちらからの呼びかけ「Hi there!」に対して、AIが何かしらお返事してくるので、それに対してさらに「I’m doing well! Just having a conversation with an AI.」みたいに答えているサンプルだ。本来はAIからの会話に対してこちらで次の返事を考えるのだが、サンプルなので相手が何を返してこようがお構いなしに「調子イイで~す。おしゃべりしよっ☆」とか返事するヤバいヤツになっています。
> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.
Current conversation:
Human: Hi there!
AI:
> Finished chain.
Hello! How can I assist you today?
> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.
Current conversation:
Human: Hi there!
AI: Hello! How can I assist you today?
Human: I'm doing well! Just having a conversation with an AI.
AI:
> Finished chain.
That's great to hear! I'm always happy to chat with humans. Is there anything specific you'd like to talk about?
…「That’s great to hear! I’m always happy to chat with humans. Is there anything specific you’d like to talk about?」だそうです。「すばらしいですゥ~、私は人間とお話するのダイチュキなんですゥ。さ、何についておしゃべりしますかぁ?」っていう…いつものケナゲなChatGPTって感じですね(悪意のある意訳)。出力を見ると、①身に覚えのない性格付け部分が足されている②最初の会話の履歴が残っている というふうになっている。自分は「Human」部分しか入れていないけど、LangChainの仕組みでほかの部分を付け足して、いかにもそれっぽい会話というか、履歴管理機能を実現しているみたい。
これはなかなか便利な話で、普通のOpenAIライブラリを使ってモデルgpt-3.5-turboを使う場合、履歴機能は配列に自分でデータを突っ込まないといけないのですが、LangChainはそこの実装の手間をはぶいているということなんですね。ただ、本当に配列に突っ込んでいるのか、最初の会話文に履歴めいた情報を1プロンプトに押し込んでいるのかまではちょっとまだわからない。ログ出せばわかるのかな?(やらない宣言…いや、違うんですよ、ちょっと調べたらTraceという機能があるらしいのですが導入のための環境作るのが自分のPCスペック的に面倒くさい予感がして避けているだけなんです…)
LangChainのChatサンプル
ようやくチャットのところまで来ました。とはいえ課金や精度の都合ですでにgpt-3.5-turbo置き換えはやっていたのであまりコード変えることもないのかな? とりあえずサンプルだ。
import os
from langchain.chat_models import ChatOpenAI
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
os.environ["OPENAI_API_KEY"] = "XXX"
chat = ChatOpenAI(temperature=0)
batch_messages = [
[
SystemMessage(content="You are a helpful assistant that translates English to Japanese."),
HumanMessage(content="Translate this sentence from English to Japanese. I love programming.")
],
[
SystemMessage(content="You are a helpful assistant that translates English to Japanese."),
HumanMessage(content="Translate this sentence from English to Japanese. I love artificial intelligence.")
],
]
result = chat.generate(batch_messages)
print(result.generations[0][0].text)
print(result.generations[1][0].text)
print(result.llm_output['token_usage'])
私はプログラミングが大好きです。
私は人工知能が大好きです。
{'prompt_tokens': 73, 'completion_tokens': 26, 'total_tokens': 99}
もとはto Frenchになっていたけどto Japaneseに変えた。当然かもだが普通に動いた(^^)/
今日のまとめ
一通りさわってみて、やっぱりAgent強すぎる~~~っていうのと、履歴機能をMemoryで実装できるの楽~~~っていうのが印象的だった。
あとは毎回書こう書こうと思って忘れているLangChainの地味にありがたい機能として、OpenAIのAPI実行に失敗したとき、自動でリトライの機能が入っているというのがある。APIはフリープランだと1分に3要求と決められているので、連続でバンバン会話するようなことをすると即NGになる。そうなったときにも、リトライ処理が勝手に動くようになっている。便利だ。
次はちょっと実際にAIくんに小説らしきものを書いてもらおうかな。試行回数が結構なことになりそうなので、ブラウザで実行できる小さいアプリを作るところからやってみよう。イメージとしてはPlayGroundみたいな感じで…。まあ一日あればできるッショ!(‘_’)
旅は終わらないッ!