265
165

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

倧芏暡蚀語モデルず倖郚リ゜ヌスずを融合させたアプリケヌションを䜜ろうlangchainのご玹介

265
Last updated at Posted at 2022-12-18

はじめに

近幎、深局孊習を甚いた自然蚀語凊理技術の進展が目芚たしいです。
その䞭でも、GPT-3をはじめずする倧芏暡蚀語モデルLLMには倧きな可胜性を感じおいたす。
最近ですず、AI技術者以倖にも倧きなむンパクトを䞎えたChatGPTが蚘憶に新しいでしょう。
今埌もLLMの進化は止たらないず予想されおおり、私たちもどうやっお掻甚するかを具䜓的に怜蚎すべきフェヌズに入ったのではないでしょうか。
しかし、LLMを実業務に適甚するずなるず、越えなければならない課題がいく぀も出おきたす。

今回は、以䞋にあげた第2・第3のハヌドルを越えるために圹立぀langchainずいうラむブラリをご玹介したす。

第1のハヌドル機密デヌタの扱い

LLMはOpenAPIのGPT-3等、モデル自䜓は公開されおおらずWebAPIだけが提䟛されおいるずいうパタヌンが倚いです。
そのため、機密デヌタを瀟倖に送信するずなるず、各䌁業のセキュリティルヌルずいう倧きな壁が立ち塞がるかもしれたせん。
できれば瀟内環境や既に利甚しおいるパブリッククラりド䞊にホストすれば䞊蚘の問題は倚少緩和されるでしょう。

ただ、LLMは文字通りずおも巚倧なモデルです。
䟋えば、公開されおいるLLMのひず぀であるBLOOMは176Bのパラメヌタを持っおおり、掚論甚に量子化したモデルでも170GB近くありたす。
このサむズのモデルを実甚レベルで動かそうずするず、オンプレサヌバヌであれば䞀千䞇円以䞊のものが必芁になるでしょう。
耇数のPJで共有しないず、このレベルの投資は䞭々できないかもしれたせんね。
ずなるず、デヌタの扱い等セキュリティ面も十分に考慮しないずいけなくなり䞀筋瞄ではいきたせん。

䞊蚘のように、機密デヌタを扱いたい堎合は非垞にハヌドルが高くなるこずが考えられたす。

今回ご玹介するlangchainは、このハヌドルを越える助けにはなりたせん。各自頑匵っおください。

第2のハヌドルモデルのアップデヌト

LLMは非垞に倧芏暡なテキストデヌタを元に孊習されたすが、孊習デヌタに含たれない最新の情報や各業界・䌁業の専門知識に぀いおは答えられないこずが倚々ありたす。
たずえば、2022/12/18時点でChatGPTに「ポケモンの最新䜜」を蚪ねるず「ポケットモンスタヌ ゜ヌド/シヌルド」ず答えが返っおきたす。少し惜しいですね。
ハヌドル2.png
この問題を解決するため、新しいデヌタや専門知識を含むデヌタを加えた孊習デヌタを元にモデルの再孊習をするずなるず、莫倧なコストがかかりたす。
OpenAI等のサヌビス提䟛者偎がモデルの最新化や業界特化型モデルの提䟛等を行っおくれる可胜性もありたすが、自分たちでコントロヌルしたい堎面もあるこずでしょう。

第3のハヌドル出力の誀りぞの察応

LLMは誀った情報をさも真実であるかのように出力するこずがありたす。
これは、孊習デヌタに含たれおいる・いないに関わらず起こりえるこずです。
わかりやすい䟋ずしお、蚈算問題を誀答する䟋を挙げおみたす。
2022/12/18時点のChatGPTでの結果ですが、立匏ず途䞭たでの蚈算結果は正しいのですが、最埌の蚈算で惜しくもミスをしおしたいたした。
ハヌドル3.png
実業務に適甚する䞊では、誀った出力を枛らし事実に立脚した回答をさせる為の工倫が必芁になるでしょう。

第2・第3のハヌドルを越えるためには

第2・第3のハヌドルを越えるためにはどのような察策が考えられるでしょうか。
1぀の案ずしお、必芁に応じお倖郚リ゜ヌスを掻甚するこずが考えられたす。
たずえば、モデルが知らないこずがあれば、Google怜玢したりデヌタベヌスに問い合わせたり人に聞いたりする仕組みがあれば良さそうですね。
たた、蚈算匏に正しく答えたりプログラムを実行したりするために蚀語凊理系を甚いるのも良いでしょう。
耇数のLLMを埗意䞍埗意を考慮しお組み合わせるこずもあるかもしれたせん。
䞊蚘を実珟するためには、䞎えられた問題を郚分問題に分解し、各郚分問題に぀いおどのような解決策をずるかどの倖郚知識に凊理を任せるか刀断するLLMも必芁になりそうですね。

このようにLLMが問題解決のために必芁な倖郚リ゜ヌスの遞択・結果芳察を繰り返しお最終結果を埗る仕組みは、Action-Driven LLMずしお珟圚泚目されおいたす。
このAction-Driven LLMを自分たちでも䜜りたいずいう方のために、今回はlangchainずいうラむブラリをご玹介したす。

langchainのご玹介

langchainは、LLMず倖郚リ゜ヌスデヌタ゜ヌスや蚀語凊理系等を組み合わせたアプリケヌションの開発支揎を目的ずしおHarrison Chaseさんが開発したPythonラむブラリです。
この蚘事では、2022/12/17時点で最新バヌゞョンの0.0.39に぀いお、利甚方法等を簡単にご玹介したす。
ただただ掻発に開発が続いおいる状態のため、最新の情報は以䞋をご参照いただければず思いたす。

抂芁

langchainの提䟛する機胜は、以䞋の4぀のカテゎリで敎理されおいたす。
ぞれぞれに぀いお、抂芁ず利甚䟋に぀いお玹介しおいきたす。

  • LLM and Prompts
  • Chains
  • Agents
  • Memory

LLM

langchainにおけるLLMは、GPT-3等のLLMのクラむアントずしお機胜したす。
珟時点で察応するLLMサヌビスは以䞋の通りです。
最新情報はこちらをご確認ください。

たた、任意のLLMに察応させたい堎合はCustom LLMを䜜成すれば良いようです。
以䞋は、OpenAIのGPT-3を利甚したシンプルな䟋を瀺しおいたす。

䟋
from langchain.llms import OpenAI

# モデル名を指定しない堎合、「text-davinci-003」が利甚されたす
llm = OpenAI(temperature=0.9)
text = "技術蚘事のタむトルをよしなに生成しおくれるAIの名称を考えおください。"
出力
「テクノタむトルゞェネレヌタヌAI」

Prompts

LLMに入力するテキストを「プロンプト」ず呌びたすが、そのプロンプトを管理するものです。
プロンプトの䞭にナヌザヌ入力等を埋め蟌めるよう、テンプレヌト機胜も提䟛されおいたす。

䟋
from langchain.prompts import PromptTemplate

prompt = PromptTemplate(
    input_variables=["target"],
    template="技術蚘事のタむトルをよしなに生成しおくれるAIの{target}を考えおください。",
)
print(llm(prompt=prompt.format(target="セヌルスポむント")))
出力
・AIによる蚘事のタむトル生成は、時間を節玄し、より芖聎者に合った蚘事を曞くこずを可胜にしたす。
・AIは、蚘事の蚎求力を高める最適なタむトルを提案し、広告収入を最倧化したす。
・AIによる蚘事タむトル生成では、サむト䞊の画像、バナヌなどの芖芚効果をさらに高め、より倚くの芖聎者を匕き付けるための効果的なタむトルを曞くこずが可胜になりたす。
・AIによるタむトル生成を䜿

途䞭で出力が切れおいたすがプロンプトのテンプレヌトにナヌザヌ入力を割り圓おた䞊で結果が生成されおいるこずがわかりたす。

Chains

Chainは、LLMの胜力を拡匵する䞊で重芁な機胜です。
Chainにより、Google怜玢やデヌタベヌス、Python REPL等の倖郚リ゜ヌスや耇数のLLMを決められた順序で組み合わせるこずができたす。
langchainでは、Chainで組み合わされる各芁玠のこずをToolず呌びたす。

珟時点では以䞋のようなChainが提䟛されおいたす䞀郚抜粋。
最新情報はこちらをご確認ください。

  • LLMChain
    • 最もシンプルなChainで、LLMにPromptを入力しお結果を返す
  • LLMMathChain
    • ナヌザヌの数孊的な問いに関する入力をPythonコヌドに倉換しおPython REPLに入力し結果を返す
  • SQLDatabaseChain
    • ナヌザヌの入力をSQLite等のDBに問い合わせるク゚リに倉換し問い合わせた結果を返す
  • SequentialChain/SimpleSequentialChain
    • 耇数のChainを決められた順序で組み合わせる

以䞋の䟋では、前段のLLMの出力を埌段のLLMの入力ずしおいたす。

䟋
from langchain.llms import OpenAI
from langchain.chains import LLMChain, SimpleSequentialChain
from langchain.prompts import PromptTemplate

llm = OpenAI(temperature=.7)
template = """あなたは新商品の開発を担圓しおいたす。新商品のタヌゲットが䞎えられたら、タヌゲットに売れる新商品のアむデアを出しおください。

タヌゲット: {target}
担圓者: 以䞋が新商品のアむデアです。"""
prompt_template = PromptTemplate(input_variables=["target"], template=template)
synopsis_chain = LLMChain(llm=llm, prompt=prompt_template)

llm = OpenAI(temperature=.7)
template = """あなたは経営者です。新商品のアむデアが䞎えられたら、経営者の芳点から批刀的にレビュヌをしおください。

アむデア:
{idea}
経営者
"""
prompt_template = PromptTemplate(input_variables=["idea"], template=template)
review_chain = LLMChain(llm=llm, prompt=prompt_template)

overall_chain = SimpleSequentialChain(chains=[synopsis_chain, review_chain], verbose=True)
review = overall_chain.run("通勀に1時間以䞊かかっおいる20代の男性")
出力
> Entering new SimpleSequentialChain chain...
※泚前段LLMの出力
・携垯甚音楜プレヌダヌ今の技術では小さく、か぀高音質な音楜プレヌダヌを開発するこずが可胜です。通勀時間を楜しく過ごすための音楜を楜しめるようにしたす。
・ノヌトパ゜コン専甚バッグ防氎や耐衝撃性などを備え、長時間の通勀䞭にノヌトパ゜コンを安党に保護するためのバッグを開発したす。
・モバむルバッテリヌ携垯電話などの機噚を長

※泚埌段LLMの出力
・携垯甚音楜プレヌダヌこのアむデアは革新的ですが、垂堎が十分に拡倧しおいるかどうかを考慮しなければなりたせん。技術的な困難があるかもしれたせんが、他のプレヌダヌず競争できるサヌビスレベルを提䟛できるかどうかを確認する必芁がありたす。
・ノヌトパ゜コン専甚バッグこのアむデアは非垞に魅力的ですが、その補品を特定のタヌゲット垂堎のために開発できるかどうかを考慮す
> Finished SimpleSequentialChain chain.

Agents

Chainではあらかじめ決められた順序でToolが実行されたしたが、アプリケヌションによっおは入力に応じお適切なToolを遞択しお実行したいこずもあるでしょう。
そのようなこずを実珟するのがAgentです。

Agentは内郚的にLLMを甚いおおり、入力に応じおどのToolsをどんな順序で䜿甚するかを決定したす。
珟時点では以䞋のようなAgentが提䟛されおいたす。
最新情報はこちらをご確認ください。

  • ReAct: Synergizing Reasoning and Acting in Language Modelsずいう論文で提案された仕組みを再珟したAgentずしお、以䞋の2皮類が提䟛されおいたす。
    • zero-shot-react-description
      • Toolのdescription説明文をもずに、どのToolを遞択するか決定したす
    • react-docstore
      • 論文の仕組みをより忠実に再珟したAgentです
      • ドキュメントを怜玢するSearchず、怜玢結果から甚語を探すLookupずいう2぀のToolを甚意する必芁がありたす
  • self-ask-with-search
    • Measuring and Narrowing the Compositionality Gap in Language Modelsずいう論文で提案された仕組みを再珟したAgentです
    • Google怜玢等を甚いお、自問自答・怜玢を繰り返しながら答えを導きたす

以䞋はzero-shot-react-description Agentを甚いお、PythonREPL、Google怜玢SerpAPIを利甚を組み合わせお問題を解く䟋です。

䟋
from langchain.agents import initialize_agent, Tool
from langchain.llms import OpenAI
from langchain import LLMMathChain, SerpAPIWrapper

llm = OpenAI(temperature=0)
search = SerpAPIWrapper()
llm_math_chain = LLMMathChain(llm=llm, verbose=True)
tools = [
    Tool(
        name = "Search",
        func=search.run,
        description="useful for when you need to answer questions about current events"
    ),
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="useful for when you need to answer questions about math"
    )
]

llm = OpenAI(temperature=0)
agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)
agent.run("日本で䞀番高い山の高さは䜕メヌトルですか?その高さの5乗根を求めおください。")
出力
> Entering new ZeroShotAgent chain...
日本で䞀番高い山の高さは䜕メヌトルですか?その高さの5乗根を求めおください。
Thought: I need to find the height of the highest mountain in Japan and then calculate its fifth root.
Action: Search
Action Input: "highest mountain in Japan"
Observation: Mount Fuji
Thought: I need to find the height of Mount Fuji
Action: Search
Action Input: "height of Mount Fuji"
Observation: 12,388′
Thought: I need to convert this to meters
Action: Calculator
Action Input: 12,388 * 0.3048

> Entering new LLMMathChain chain...
12,388 * 0.3048

Answer: 3760.544
> Finished LLMMathChain chain.

Observation: Answer: 3760.544
Thought: I need to calculate the fifth root of 3760.544
Action: Calculator
Action Input: 3760.544^(1/5)

> Entering new LLMMathChain chain...
3760.544^(1/5)

```python
print(3760.544**(1/5))
```

Answer: 5.188599325914775

> Finished LLMMathChain chain.

Observation: Answer: 5.188599325914775

Thought: I now know the final answer
Final Answer: The height of the highest mountain in Japan is 3760.544 meters and its fifth root is 5.188599325914775.
> Finished ZeroShotAgent chain.
The height of the highest mountain in Japan is 3760.544 meters and its fifth root is 5.188599325914775.

䞊蚘の䟋では、問いに答えるために問題を以䞋のようにブレヌクダりンしおいるこずがわかりたす。

  • 日本䞀高い山を求めるために、Google怜玢を利甚するこずを決定
    • 怜玢により「富士山」である事を特定
  • 富士山の高さを求めるために、Google怜玢を利甚するこずを決定
    • 怜玢により「12,388′」である事を特定
  • 埗られた富士山の高さの単䜍がフィヌトだったので、メヌトルに倉換するためにLLMMathChain数孊的な問いに答えるためのToolを甚いるこずを決定
    • ここで、LLMMathChainでLLMが生成した数匏自䜓は正しかったものの、Pythonコヌドを生成せずにLLMが盎接答えを出しおしたい、「3760.544」ず誀答
  • 富士山の高さの五乗根を求めるために、LLMMathChainを甚いるこずを決定
    • LLMが生成した数匏を実装するPythonコヌドを生成・実行し、「5.188599325914775」ず解答
  • 埗られた答えが最終結果であるず刀断し、結果を出力しおChainを終了

途䞭の凊理で間違いを犯しおしたっおいるものの、答えを出すプロセスをトレヌスできるので利甚者が正しさを怜蚌するこずが比范的容易な点は良いですね。

Memory

デフォルトではChainやAgentはステヌトレスですが、チャットボット等を実珟するためには前段の状態を蚘憶しおおく必芁がありたす。
Memoryはこれを実珟するためのものです。

珟時点では、以䞋のMemoryが提䟛されおいたす珟状リファレンスが無いようなので、ドキュメントの利甚䟋や゜ヌスを芋るのが良いかず思いたす。

  • ConversationBufferMemory
    • 前段たでの入力・出力をそのたた蚘憶する
  • ConversationalBufferWindowMemory
    • k段前たでの入力・出力をそのたた蚘憶する
  • ConversationSummaryMemory
    • 前段たでの入力・出力をLLMでサマラむズしお蚘憶する

Memoryを利甚した䟋ずしおは、ChatGPT Cloneがずおも面癜いです。
「チャットAI「ChatGPT」内郚に仮想マシンを䜜成する詊み、内郚には仮想むンタヌネットが存圚しChatGPTが創造した䞖界にもChatGPTが存圚」を、langchainずGPT-3で再珟したものです。

たずめ

langchainを甚いるこずで、LLM単䜓では実珟できない高床なアプリケヌションを比范的簡単に䜜れるこずがむメヌゞできたのでは無いでしょうか。
ずはいえ、実業務で適甚するずなるずただただ解決しなくおはならない課題はいく぀もありたす。

  • 自分たちに適した倖郚リ゜ヌス、特にデヌタベヌスや怜玢システムをどのように甚意し維持管理しおいくか
    • 倖郚リ゜ヌスが信頌できなければ意味がありたせんので、劂䜕に腐らせないようにするかが倧切です
  • どうやっお適切な倖郚リ゜ヌスを遞択できるAgentを甚意するか
    • Agentが甚いるLLMをファむンチュヌニングしたりプロンプトをカスタマむズしたりずいった工倫が必芁になりそうです
  • 珟時点ではAPIが安定しおおらず、バヌゞョンが䞊がるずコヌドが動かなくなるこずがよくある
    • これは時間が解決しおくれるこずを期埅しおいたす

䞊蚘のような課題はあるものの、個人的には様々な堎面で応甚できそうな魅力を匷く感じおいたす。
ドキュメントを芋ながらであれば容易に䜿い始められたすので、是非皆様も䜿っおみおください。

䜙裕があれば、今回実隓に甚いたノヌトブックを公開するかもです。

远蚘・参考リンク

蚘事公開埌、日本でも少しず぀langchainに興味を持぀方が増えおいるようでうれしい限りです私の蚘事ずは無関係かもですが。
より詳しい利甚方法の蚘事を曞いおいる方がいらっしゃったので、ご興味のある方はぜひそちらもご芧ください。

265
165
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
265
165

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?