【AIエージェント入門】LangChain・LangGraphによるエージェント開発　その④　LCEL

どうも。@TM_AIbuchoことおっさんです。
SES企業の社長が開発経験ゼロからAIを学習しています。
是非とも暖かく、時には厳しく見守っていただけると嬉しいです。

# はじめに

AIエージェントの定義は明確ではないですが、一般的には**特定の目的に応じて自律的に目標を設定し、タスクを実行していくシステム**をAIエージェントといわれています。

LangChainによるAIエージェントを開発してみよう。
開発環境はGoogleColab、言語はPythonを使用しています。

以下書籍を参考にしています。
[LangChainとLangGraphによるRAG・AIエージェント［実践］入門 (エンジニア選書) 単行本（ソフトカバー） – 2024/11/9 西見 公宏 (著), 吉田 真吾 (著), 大嶋 勇樹 (著)](https://amzn.asia/d/2UfTzY9)

# 過去の記事
[【AIエージェント入門】LangChain・LangGraphによるエージェント開発　その①複数のモデルを使ってみる](https://qiita.com/TM_AIbucho/items/33a7b20da151a0b0f016)

[【AIエージェント入門】LangChain・LangGraphによるエージェント開発　その②LangChain基礎知識](https://qiita.com/TM_AIbucho/items/c52abe0f6050a4c42f4b)

[【AIエージェント入門】LangChain・LangGraphによるエージェント開発　その③　RAG入門](https://qiita.com/TM_AIbucho/items/882ea30cee6c65307c3e)

# それでは実装していく！

```Python:入力
import os
from google.colab import userdata

os.environ["OPENAI_API_KEY"] = userdata.get("OPENAI_API_KEY")
```

```text:入力
!pip install langchain-core==0.3.0 langchain-openai==0.2.0
```

まずはシークレットのAPIキーを読み込んで、パッケージをインストールしておきます。

# LCEL

Langchain Expression Language、略してLCELです。
これで処理を繋いでいきます。

>Expression Language（EL）とは、プログラミング言語の一部や構成ファイル、テンプレートファイルなどにおいて、簡単な式やロジック、ポリシーなどを記述する際に使用される言語です。

ふ～ん、なるほど。とりあえず繋ぐやつね。
やってみましょう。

```Python:入力
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

model = ChatOpenAI(model="gpt-4o-mini",temperature=0)

prompt = ChatPromptTemplate.from_messages(
    [
        ("system","ユーザーは疲れたおっさんです。名前を呼んで励ましてあげて。"),
        ("human","{name}"),
    ]
)

output_parser = StrOutputParser()

chain = prompt | model | output_parser

output = chain.invoke({"name":"@TM_AIbucho"})
print(output)
```

```text:出力
TM_AIbuchoさん、いつもお疲れ様です！頑張っているあなたを心から応援していますよ。少し休憩を取って、自分を大切にしてくださいね。あなたの努力は必ず報われます！
```

ありがとう。おっさん頑張りますね。

- model
gpt-4o-miniを選択。temperatureは0。ちなみにtemperaturというのはどれくらいランダム性を上げるかという設定値で、0だとランダム性なし。数字が大きくなるとランダム性も上がる。（1以上とか）デフォルトは0.7だったはず。

- prompt 
PromptTemplateを使ってプロンプトを作成

- output_parser
LLMからの回答を文字列として抽出する

- chain
それぞれをパイプ「|」でつなぎます。

そしてinvokeメソッドを実行します。
なるほど、invokeね。invokeってなんだ？

:::note info
はい、分かりやすく説明しますね！

invokeは「実行する」という意味で、簡単に言うと「AIに仕事をお願いする」ためのボタンのようなものです。

例えば、あなたがAIに「猫について説明して」とお願いしたいとします。
その時のやり方を、人間の会話に例えると：

```python
# まずAIさんを呼んできます
ai = OpenAI()

# AIさんへの「お願いの仕方」を決めます
お願いの内容 = "これについて教えてください：{トピック}"

# 実際にAIさんにお願いします（これがinvoke）
結果 = ai.invoke({"トピック": "猫"})
```

invokeは要するに「実行してください！」というボタンみたいなものです。

他の方法として：
- たくさんの質問を一度に聞く方法（batch）
- 結果が少しずつ返ってくる方法（stream）

などもありますが、基本的には「invoke」を使うだけで大丈夫です！

これで少し分かりやすくなりましたか？もし具体的に「こういうことがしたい」というのがあれば、それに合わせて説明できます😊
:::

invole以外にも、Streamとbatchがあるとのこと。batchはよくわからないので飛ばしてStremはストリーミングで出力できます。

```Python:入力
model = ChatOpenAI(model="gpt-4o-mini",temperature=1)

chain = prompt | model | output_parser
for chunk in chain.stream({"name":"@TM_AIbucho"}):
  print(chunk,end="",flush=True)
```
```text:出力
TM_AIbuchoさん、お疲れ様です！今日も一日頑張りましたね。少し休憩してリラックスして、また元気を取り戻してください。あなたの努力はちゃんと見ていますよ！大丈夫、今日も乗り越えられます！
```

ストリーミングで出力されました。temperature=1にしたので出力結果も変わりましたね。
Chainを2つ繋げることもできます。
名前を入力して、LLMの回答から名前を抽出する。LLMの使い方を間違えてますがやってみます。

```Python:入力
name_prompt = ChatPromptTemplate.from_messages(
    [
        ("system","LLMの回答から名前だけ抽出してください。"),
        ("human","{text}"),
    ]
)

name_chain = name_prompt | model | output_parser

chain_name_chain = chain | name_chain

chain_name_chain.invoke({"name":"@TM_AIbucho"})
```
name_chainとchainをつなげて名前を抽出できました。

# まとめ

この記事では、LangChainを使用したAIエージェント開発の基礎として、LCEL (LangChain Expression Language) の使い方について解説しました。

1. LCELの基本的な使い方
- modelの設定（ChatOpenAI）
- プロンプトテンプレートの作成
- 出力パーサーの設定
- パイプ演算子（|）を使用した処理の連携

2. 実行方法の違い
- invoke()による基本的な実行
- stream()によるストリーミング出力
- チェーンの連結による複数処理の実行

次回はRAGの発展した話題に入っていきます！なかなかエージェントにたどり着かない！