見出し画像

ChatGPT→LangChainをもくもく学習した話

先日のChatGPT選手権で知り合ったエンジニアさんたちとLangChainのもくもく会でキャッキャウフフしながらもくもく勉強したので雑レポです。

ChatGPT PluginのWaitlistで待ってるアナタ。いろいろ面白くて新しいLLMを使ったアプリ開発技術「LangChain」のまとめになります。
めちゃめちゃ広大ですがだいたい2時間の勉強、初手でわかる魅力の数々を現場からお送りします。

もくもく会とは!?

「もくもく会」はITエンジニア用語。集まって黙々と勉強する会です。
今回は「ChatGPTによるデータ変換がもたらすインパクト」をLTで発表した野生のまーくんさんが主催で「フラットなAIコミュニティ(AIDD)」のDiscordを会場としてお借りしました。

冒頭の説明より。
筆者は雑談と相談の「ザッソウスタイル」→ひとり朝までモクモクスタイルで参加です!

LangChainとは!?

公式のタグラインによると
https://github.com/hwchase17/langchain

⚡ Building applications with LLMs through composability⚡
「コンポーザビリティによるLLMを使ったアプリケーションの構築」とあります。

大規模言語モデルを使ったアプリ開発…はわかりますが、コンポーザビリティとは?

Composabilityとは!?

コンポーザビリティとは、システムの要素を再結合してより大きなものにする能力のことで、一つの要素の出力を別の要素の入力として見なすことができる。この仕組みを理解するには、全てのブロックが他のブロックと結合することができる、レゴブロックが良い例である。コンポーザビリティとは、暗号の中の効果的に分岐して再結合する能力のことであり、分散型アプリケーション(dApps)やDAOである。例えば、Ethereumネットワーク上で一度作られたスマートコントラクトは、元のソフトウェアロジックを使用して、その上に構築された後続のコントラクトに組み替えることができる。形態的コンポーザビリティは、トークンやメッセージなどのソフトウェアコンポーネントが、互いに、あるいはdAppsやスマートコントラクトの間で操作できるようにするものである。

https://meta-bank.jp/glossary/composability/

そういえばWeb3界隈でよく耳にするワードでもありました(若干実装レイヤーが違いますが)。

もくもく会で、まーくんさんから聞いて納得した感覚ですが「LangChainをアプリ開発に例えると、LLMはそのOSのようなもの」と例える事ができそうです。
LangChainを使用することで、LLM単独ではできないような他の計算や知識のソースと組み合わせた「より高度なアプリケーション」を開発することができます。複数のアプリを連携させてつないでいく事ができますが、疎結合ともいえます。マッシュアップではあるけれど、コード自身もChatGPTでのプロンプトエンジニアリングや自然言語を使ってPythonコードでつながっていくアプリを作ることができます。
⭐︎別言語Wrapperも存在し、JS/Typescript版は同一作者が統合しています。

Chat GPTプラグインで良いのでは?説に対して

ChatGPT Pluginが近いように思う人もいらっしゃるかもしれません(そもそもまだこの原稿を書いている時点で正式リリースされていません!)。
企業のウェブサイトやデータベースをChatGPTのインタフェースで利用するならChatGPT Pluginでいいと思いますが、LangChainはLaamaなどOpenAI以外のLLMも横断して使うことができるということになります。独自のアプリや、データ基盤、最新のニュースやWikipedia、そしてそもそもOpenAIのAPIコストを負担できないような用途だったらどうしましょう?そしてChatGPTP Plugin自身のセキュリティ問題などもあります。

逆瀬川さんの解説
https://qiita.com/sakasegawa/items/5a5bb4beca0a435d8535

https://qiita.com/sakasegawa/items/d01dafdf0c77da133f24

▼ChatGPTのAPIをハッキングしたら80以上の「秘密のプラグイン」を発見したという報告 - GIGAZINE


この記事ではGoogle Colabを使って「LangChainの初手」を実際に触ってみることで、その可能性をニワカに語れるぐらいまでを目指しておきます。

先行者たちの日本語資料

今回のもくもく会の主催者、まーくん/西見さんの完成形です。
行政のPDFからデータを抽出します。神エクセルならぬ神PDFからのデータ取得が見どころです。

https://note.com/mahlab/n/n998d8601cfab

LangChainをデプロイする事例は多くないのですが、FastAPIでサクッとリリースしている例。

ほかに試してみた系記事

ChatGPTの機能を拡張するLangChainを試してみた - NRIネットコムBlog 本記事は 2022年度 新人卒業記念Week 2日目の記事です。 🌸 1日目 ▶▶ 本記事 ▶▶ 3日目 📚 はじめに L tech.nri-net.com

npakaさんの足跡をたどる

私は前々からLangChainには目をつけていたのですが以上の記事を読んでも「なんだかわからん…」となってしまいました。やはりガッツリ公式ドキュメントを追いたい、しかし成長速い上にどんどん更新される上にドキュメント量も機能もめちゃ多い!
気の長い方はnpakaさんが昨年末ぐらいから一通りのAPIを試した記事を書いていらっしゃいますので、たどっていくといいかもしれません(当時v.0.0.58~v.0.0.102ぐらい、すごい速くて細かい刻みです…)。時系列でインデックスされた記事はなさそうなのでこれはこれで価値あるかもしれない(npakaさんありがとうございます!)。玄人の方はExamplesからがいいかも。

ずんだもん と 祥龍院隆子の会話が見れます

本当はマーケットプレイス的な役割を担うはずだったというlangchain-hubはあまり流行っていないので、ここから始めないこと。「(Hubが本来もっと盛り上がるべきかもだけど)本体の熱量がすごい」と話題になっておりました。


毎日のように有益なnoteを書いているnpakaさんに尊敬の念を込めて感謝…!
みんな、いいね!…いいねをするんだ…!

LangChain公式の「🤔 What is this?」より

ここから先は私のひとりモクモク勉強メモになります。公式のドキュメントを中心に翻訳しながらGoogle Colabでのコードとともに紹介していきます。

大規模言語モデル(LLM)は、開発者がこれまでできなかったようなアプリケーションを構築できるようにする、変革的なテクノロジーとして登場してきています。しかし、LLMを単独で使用するだけでは、真にパワフルなアプリケーションを作るには不十分な場合が多く、LLMを他の計算ソースや知識と組み合わせることで、真のパワーを発揮します。

このライブラリは、このようなタイプのアプリケーションの開発を支援することを目的としています。このようなタイプのアプリケーションの一般的な例としては、以下のようなものがあります:

❓ 特定の文書に対する質問応答(資料)
エンドツーエンドの例: Notionデータベースを使った質問応答

💬 チャットボット(資料)
エンドツーエンドの例: チャットLangChain

🤖 エージェント(資料)
エンドツーエンドの例: GPT+WolframAlpha

ドキュメンテーション(資料)
けっこう資料が充実しています。
・はじめに(インストール、環境設定、簡単な例)
・ハウツー例(デモ、統合、ヘルパー機能など)
・リファレンス(全APIドキュメント)
・リソース(コアコンセプトのハイレベルな説明)

📃 LLMs and Prompts:
大規模言語モデル(LLM)とプロンプト:プロンプトの管理、プロンプトの最適化、すべてのLLMのための汎用インターフェース、LLMを扱うための共通ユーティリティが含まれます。

🔗 チェーン:
チェーンとは、単一のLLM呼び出しを超えたもので、(LLMであれ、別のユーティリティであれ)一連の呼び出しを指します。LangChainは、チェーン用の標準インターフェース、他のツールとの多くの統合、一般的なアプリケーションのためのエンドツーエンドチェーンを提供します。

📚 データ拡張生成:
データ拡張生成(Data Augmented Generation)は、生成ステップで使用するデータを取得するために、最初に外部データソースと対話する特定のタイプのチェーンを含みます。この例として、長いテキストの要約や、特定のデータソースに対する質問/回答などがあります。

🤖 エージェント:
エージェントとは、LLMがどのActionを取るか決定し、そのActionを取り、Observationを見て、それを完了するまで繰り返すことです。LangChainはエージェントの標準インターフェース、エージェントの選択、そしてエンド・トゥ・エンドのエージェントの例を提供します。

🧠 メモリー:
メモリーとは、チェーン/エージェントの呼び出しの間に状態を持続させる概念です。LangChainは、メモリの標準インターフェース、メモリ実装のコレクション、メモリを使用するチェーン/エージェントの例を提供します。

🧐 評価:
[BETA] 生成モデルは、従来のメトリクスで評価することが難しいことで有名です。新しい評価方法の一つは、言語モデルそのものを使って評価することです。LangChainは、これを支援するためのいくつかのプロンプト/チェーンを提供します。
これらのコンセプトの詳細については、完全なドキュメントを参照してください。
💁 貢献する
急速に発展している分野のオープンソースプロジェクトとして、私たちは、新機能、改良されたインフラ、より良いドキュメントの形であれ、貢献を非常に歓迎しています。
貢献の方法についての詳しい情報は、こちらをご覧ください。

Twitter @langchainai
※本稿現時点での最新版は v0.0.125

作者のHarrison Chaseさん。

@LangChainAI で最高のエージェントとツールを使用して AGI を作成する (やや) 面白い試み。現在、検索の使用、複雑な計算の実行、天気の検索、現在のニュースの検索などを行うことができます

2022/12/24@hwchase17 (Translated)

ノートブックはこちら

初手 - Getting Started

LLMsを呼び出して問い合わせてみる

Google Colabを使って実際に出力結果を確認しながらもくもくしてみます。

from langchain.llms import OpenAI
gpt3 = OpenAI(model_name="text-davinci-003", openai_api_key=openai_key,temperature=0.9)
print("[text-davinci-003]"+gpt3("Sam Altmanについて教えて下さい"))

turbo = OpenAI(model_name="gpt-3.5-turbo", openai_api_key=openai_key)
print("[gpt-3.5-turbo]"+turbo("Sam Altmanについて教えて下さい"))

出力結果
[text-davinci-003]Sam Altmanは、米国のソフトウェアエンジニア、投資家、オープンソースソフトウェアの発祥者です。2005年からY Combinator(YC)の共同創設者として活躍しており、2014年からYCの会長も務めています。Altmanはまた、TachyusのCEOであり、自動車テクノロジーのOpenAIの統括責任者でもあります。Altmanは多数の著書を出版し、インタビューで技術の専門家、社会の投資家、新興企業家や天才について話します。彼の信

[gpt-3.5-turbo]Sam Altmanは、アメリカの起業家、投資家、そして技術者です。彼は、Y Combinatorの元社長であり、同社の初期のインキュベーターの成功に大きく貢献しました。彼は、Reddit、Airbnb、Stripe、Weeblyなど多くの有名なスタートアップ企業の投資家としても知られています。彼はまた、AIの研究への取り組みも行っており、人工知能開発者のコミュニティであるOpenAIの共同設立者でもあります。彼はアメリカの技術界の重要人物の一人と評価されています。

PromptTemplate

プロンプトテンプレートは問い合わせの形式に変数を渡すことができます。

# 前に引き続きOpenAIのAPIを使って turbo を生成しておく
from langchain import PromptTemplate
template = """
新しい会社のネーミングコンサルタントとして活躍してほしい。
良い会社名の例をいくつか紹介しよう:
・サーチエンジン「グーグル」
・ソーシャルメディア「 フェイスブック」
・動画サイト「YouTube」
名前は、短く、キャッチーで、覚えやすいものでなければなりません。
{product}を作る会社の名前として良いものは何でしょうか?
"""
prompt = PromptTemplate(
input_variables=["product"],
template=template,
)

# LLMChainを使ってプロンプトテンプレートを渡し「チャットボット」を製品名にして問い合わせ
from langchain.chains import LLMChain
chain = LLMChain(llm=turbo, prompt=prompt)
print(chain.run("チャットボット"))

出力:例えば「チャットメイト」、「チャットブレイク」、「チャットコア」、「チャットワン」といった名前が良いでしょう。それぞれ短く、かつ覚えやすい名前であり、チャットボットを作る会社としてのイメージを伝えることができます。また、キャッチーなワードを組み合わせることで、名前に特徴を持たせることもできます。

ここから先はnpakaさんの記事へ…


エージェント

エージェントはユーザの入力に基づいて、チェーンを動的に呼び出します。
ここでは公式のサンプルを改造して、
「昨日の東京の最高気温は華氏で何度だったでしょう?その数字、華氏から摂氏を引いた値は何ですか?」という謎の演算を複合問い合わせを使って解いてもらいます。

内部での問い合わせには serpapiを使いますので、APIキーを取得しておきましょう(100 searches / month までは無料です)

from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.llms import OpenAI

# まず、エージェントを制御するために使う言語モデルをロードしましょう。
# turbo = OpenAI(model_name="gpt-3.5-turbo", openai_api_key=openai_key)
# llm = OpenAI(temperature=0)
llm = turbo

# 次に、使用するツールをいくつか読み込みましょう。なお、`llm-math`ツールはLLMを使用するので、それを渡す必要がある。
tools = load_tools(["serpapi", "llm-math"], llm=llm)


#  最後に、ツール、言語モデル、エージェントの種類を指定して、エージェントを初期化しましょう。
agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)

# では、テストしてみましょう!
# agent.run("What was the high temperature in SF yesterday in Fahrenheit? What is that number raised to the .023 power? lang:ja")
agent.run("昨日の東京の最高気温は華氏で何度だったでしょう?その数字、華氏から摂氏を引いた値は何ですか?")
> Entering new AgentExecutor chain...
I don't know Japanese, so I'll need to use a search engine to translate the question and figure out what it's asking for
Action: Search
Action Input: "Translate '昨日の東京の最高気温は華氏で何度だったでしょう?その数字、華氏から摂氏を引いた値は何ですか?' to English"
Observation: Translations in context of "華氏温度" in Japanese-English from Reverso Context: 遅い料理は、重要な要素です温度はめったに場合は、275の華氏温度を超えることに ...
Thought:That search didn't help, let me try using a different search query
Action: Search
Action Input: "What was yesterday's highest temperature in Tokyo in Fahrenheit and the Celsius equivalent?"
Observation: High & Low Weather Summary for the Past Weeks ; 75 °F (Mar 24, 12:00 pm), 100% (Mar 23, 11:00 am), 30.33 "Hg (Mar 23, 11:00 am) ; 46 °F (Mar 18, 8:30 am), 31% ( ...
Thought:I need to convert Fahrenheit to Celsius to answer the second part of the question
Action: Calculator
Action Input: 75-32*5/9
Observation: Answer: 57.22222222222222

Thought:I now know the final answer
Final Answer: Yesterday's highest temperature in Tokyo was 75°F, which is equivalent to 57.22°Celsius after subtracting 32 and multiplying by 5/9.

> Finished chain.
Yesterday's highest temperature in Tokyo was 75°F, which is equivalent to 57.22°Celsius after subtracting 32 and multiplying by 5/9.

新しいAgentExecutorチェーンを入力...
私は日本語がわからないので、検索エンジンを使って質問を翻訳し、何を求めているのか把握する必要があります
[アクション 検索]
アクションインプット "翻訳 '昨日の東京の最高気温は華氏で何度だったでしょう?その数字、華氏から摂氏を引いた値は何ですか?"英語への翻訳"
[観察]: 日本語-英語の "華氏温度 "の文脈での翻訳
[Reverso Context]: 遅い料理は、重要な要素です温度はめったに、275の華氏温度を超えることに...。
[Thought]:その検索は役に立ちませんでした、別の検索クエリで試してみます。
[アクション 検索]
アクションの入力です: "東京の昨日の最高気温は華氏で何度、摂氏で何度相当でしたか?"
[観測]: 過去1週間の最高・最低気温のまとめ ; 75 °F (Mar 24, 12:00 pm), 100% (Mar 23, 11:00 am), 30.33 "Hg (Mar 23, 11:00 am) ; 46°F (Mar 18, 8:30 am), 31%( ...
[思考]:問題の後半に答えるために、華氏を摂氏に変換する必要があります。
[アクション] 電卓
アクションインプット 75-32*5/9
[観察]:回答 57.22222222222222
[感想] : 最終的な答えがわかった
[最終回答]: 東京の昨日の最高気温は75°Fで、32を引いて5/9をかけると57.22℃に相当します。
[チェーンを完成] 昨日の東京の最高気温は75°Fで、32を引いて5/9を掛けた後の57.22℃セルシオに相当する。

出力のDeeplによる翻訳

ここから先に興味がある人はnpakaさんのnoteへ…Googleカスタム検索も。


メモリー

これまでに調べたすべてのチェーンとエージェントはステートレスでした。しかし、以前のやり取りに関する情報を記憶できるように、チェーンまたはエージェントに「記憶」の概念を持たせたい場合がよくあります。これの最も明確で単純な例は、チャットボットを設計するときです。以前のメッセージを記憶して、そのコンテキストを使用して会話を改善できるようにする必要があります。これは一種の「短期記憶」です。より複雑な側面では、チェーン/エージェントが時間の経過とともに重要な情報を記憶していると想像できます。これは「長期記憶」の一種です。後者に関するより具体的なアイデアについては、このすばらしい論文を参照してください。

from langchain.chat_models import ChatOpenAI
from langchain import ConversationChain
llm = OpenAI(model_name="gpt-3.5-turbo", openai_api_key=openai_key,temperature=0)
conversation = ConversationChain(llm=llm, verbose=True)
conversation.predict(input="こんにちわ!")
conversation.predict(input="AIとお話しするのは初めてなんだけど、何から話したらいいかな?")
conversation.predict(input="東京から来ました")
conversation.predict(input="来たことある?")

LangChain は、この目的のために特別に作成されたチェーンをいくつか提供しています。ConversationChainのデフォルトでは、ConversationChain以前のすべての入力/出力を記憶し、渡されたコンテキストに追加する単純なタイプのメモリがあります。このチェーンの使用を見てみましょう (verbose=Trueプロンプトが表示されるように設定されています)。

チャットの入力が、これまでの会話内容を引き継いでいることがわかります。

もくもく会では、この内部のソースが単純なhistoryに基づいていることなどがディスカッションされていました。ほかの実装も結構、雑なプロンプト芸の集大成で出来上がっていたりして、非常に発見が多かったです:

メモリについてのさらなる実験はnpakaさんの記事へ…

https://note.com/npaka/n/nb0abfd88b752?magazine_key=mdf3ce11e35b9

ChatGPTで鍛えたプロンプト芸がPythonでの生成に置き換えられるだけでなく、PDFやWebページの読み込み、そしてコードそのものを生成するようなコードもあります。

また自家Python環境だけでなく、サービスとしてデプロイするための良いサービスなどもディスカッションされていました。

これは別記事にまとめておきます。

ここから先にもくもくしたい人は、公式Twitter @LangChainAI と次回のもくもく会&野生のまーくん @mah_lab さんをフォローです。
解説と次回の告知が発表されています。

おまけ

会場となったDiscordをご提供いただいたAIDD改め「AIAD (AI Adoption/Adaption)」主宰のサガワフミヤさんに、ChatGPTをギャル化するプロンプトを教えたらさっそく遊んでくれたので紹介しますね。これもLangChainで使えるはず!

開催後にいただいたギャル化したChatGPTスクショ

★後編に補足情報が続きます!


この記事が気に入ったらサポートをしてみませんか?