2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LangChain v0.3 その3 ~LCELの発展1(RunnableSequenceとRunnableParallel)~

Posted at

LCEL

LangChainのLCEL。ま、コアな部分の一つだよね。
きっとこれらを使うと便利なものが作れるんだろうね。
ということでもう少し踏み込んでみました。
実は「ドキュメントを読む練習」というのは内緒である。
ということで直線的な処理と並行させる処理をやらせてみました

バージョン関連

Python 3.10.8
langchain==0.3.7
python-dotenv
langchain-openai==0.2.5
langgraph>0.2.27
langchain-core

※LLMのAPIはAzureOpenAIのgpt-4o-miniを使いました

準備

.envファイルに以下を用意しましょうね
END_POINT="https://<<ほにゃらら>>.openai.azure.com/"
API_KEY="<<ほにゃらら>>"
API_VERSION="2023-05-15"
LANG_SMITH = "<<ほにゃらら>>"

やらせてみたこと

大喜利。それも英語で

復習

前回のもみてね

シーケンシャルな処理の場合

langchain_corerunnablesからRunnableSequenceをインポートして使います。

from langchain_core.runnables import RunnableSequence

プロンプトを準備

prompt_template0 = ChatPromptTemplate([
    ('system', 'あなたは偉大な漫才師です。'),
    ('user', '{topic}について大喜利してください。')
])

topic2english = ChatPromptTemplate([
    ('system', 'あなたは優秀な英語への翻訳者です。翻訳した内容だけを回答してください。'),
    ('user', '{topic}を翻訳してください')
])

oogiri_prompt = ChatPromptTemplate([
    ('system', 'You are a great comedian'),
    ('user', 'Please create OOGIRI about {topic} in English')
])

シーケンシャルに組む

chain_oogiri_english = RunnableSequence(
    topic2english, 
    model, 
    oogiri_prompt, 
    model, 
    output_parser
    )

実はこれ、以下と同じ

chain_oogiri_english = topic2english | model | oogiri_prompt | model | output_parser

なんやねんて。
ま、直線的に組むだけですからそうなりますわな。

実行してプリント

result = chain_oogiri_english.invoke('靴下')
print(result)
output
Sure! Here’s an OOGIRI (a form of Japanese comedy) themed around socks:

---

**Q:** Why did the sock break up with the shoe?  
**A:** Because it found someone more supportive!

---

**Q:** What do you call a sock that can do magic?  
**A:** A sock-cerer!

---

**Q:** Why did the sock refuse to play hide and seek?  
**A:** Because it always got lost in the wash!

---

Hope that brings you a chuckle!

並列処理の場合

from langchain_core.runnables import RunnableParallel

今度はRunnalbleParallelを使います。

parallel_chain = RunnableParallel({
    'Japanese': prompt_template0 | model | output_parser,
    'English': topic2english | model | oogiri_prompt | model | output_parser
})

こんな風に辞書形式でそれぞれぶっ込みます。
今回は辞書の中はパイプ「|」で繋いでます

実行!

result_parallel = parallel_chain.invoke('靴下')

結果を表示。まず日本語から。

print(result_parallel['Japanese'])
もちろん、靴下についての大喜利いきますよ!

1. 靴下が出会い系アプリを始めた理由は?
   - 「足元から恋を育てたい!」

2. 短い靴下と長い靴下、どっちが人気?
   - 「短い靴下、いつも『あたしも見て!』ってアピールしてるから!」

3. 靴下が自分の存在意義を考えた結果?
   - 「やっぱり、足元を支えるのが私の使命だと気づいた!」

4. 靴下が言う「これが私のスタイル!」とは?
   - 「色んな柄で、足元から個性を主張!」

5. 靴下が選ぶ理想のデートコースは?
   - 「靴屋巡り。だって、いい靴にはいい靴下が必要でしょ!」

どうでしょう?靴下の魅力を引き出しつつ、笑いを誘う感じになりましたか?

まぁまぁ大喜利しやがる!さすがGPT-4o-mini

今度は英語

print(result_parallel['English'])
output
Sure! Here’s an OOGIRI (a Japanese form of comedic wordplay) about socks:

**Q:** Why did the sock break up with the shoe?  
**A:** Because it found someone who really "fits" its sole! 

Feel free to ask for more jokes or a different topic!

えっと、英語は苦手なんでぇ・・・よくわからん。w
日本語は5個も作ってくれたけど、英語はひとつなのね。笑

大事だと思うこと

これらのライブラリ、継承しているクラスを遡っていくとRunnableクラスにたどり着きます。
ここで、RunnableクラスのDocStringsを和訳してもらいました。(GPT-4o)
以下の108行目

和訳
LangChainのRunnableクラスは、データを処理するための作業単位を表す概念で、さまざまな方法での呼び出しや構成が可能です。このクラスには以下の主要なメソッドや特徴が備わっています。

主なメソッド

	•	invoke/ainvoke:1つの入力を1つの出力に変換します。ainvokeは非同期対応。
	•	batch/abatch:複数の入力を効率的に処理し、出力を得ます。
	•	stream/astream:1つの入力に対し出力をストリーミングとして返します。
	•	astream_log:出力と中間結果をリアルタイムでストリーミングします。

組み込みの最適化

	•	バッチ処理:デフォルトではスレッドプールを使って並列実行し、効率化を図ります。
	•	非同期処理:メソッド名に「a」がついているものは非同期処理で、標準的には同期版を非同期化していますが、オーバーライドしてネイティブな非同期対応も可能です。

各メソッドにはオプションのconfig引数があり、実行設定やデバッグのためのメタデータ追加に利用されます。また、input_schemaやoutput_schemaを使って入出力形式の情報を提供します。

LangChain Expression Language(LCEL)と構成

LCELは、Runnableをチェーン状に構成するための宣言的な方法です。これにより、同期・非同期・バッチ・ストリーミングの全機能を持つチェーンを簡単に構築できます。主な構成方法には以下があります。

	•	RunnableSequence:複数のRunnableを順に呼び出し、一つの出力を次の入力として利用します。|演算子やリストで構成できます。
	•	RunnableParallel:複数のRunnableを並列に呼び出し、同じ入力を渡して異なる出力を取得します。辞書リテラルを使って構成可能です。

つまり、Runnableの機能としてinvoke/ainvokebatch/abatchstream/astreamastream_logこれらの機能がとても重要なんですね。
あとで少しコードを読んでみようかな。

まとめ

ということでパラレルに動かすってことをやってみたかったので、RunnableSequenceRunnableParallelを比較してみました。
使ってみると挙動がよくわかります。
sosite,
LCELの発展2に続きます。

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?