LangChain v0.3　その１~ChatPromptTemplate~

# LangChain v0.3　ChatPromptTemplate
とあるイベントで65歳の方が素晴らしいライトニングトークをされてて触発されました！
俺のニューロンに着火！（なんかエ〇い）
そして、約1年ぶりにLangChainを触ってみたら知らないことばかり。
元々知らなかったのか、機能が増えたのかもしれない。
ちょっとメモしないとついていけないと思ったので、メモ代わりにQiitaに残します。
あ、もっといい記事があるとも追うのでここで物足りなかったらそちらで。

https://python.langchain.com/docs/introduction/


全部で何回になるかはまだ未定。笑

# バージョン関連
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 = "<<ほにゃらら>>"

# 今日の目的
ChatPromptTempleteを使う

#### ライブラリのインポート
``` Python
import os

from dotenv import load_dotenv
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import AzureChatOpenAI, 
# from langchain_openai import ChatOpenAI # OpanAI使う人はこちら
from langchain_core.prompts import PromptTemplate
```

#### モデルの用意
```Python
model = AzureChatOpenAI(
    model='gpt-4o-mini',
    azure_endpoint=os.getenv("END_POINT"),
    api_version=os.getenv("API_VERSION"),
    api_key=os.getenv("API_KEY")
)
```

#### テンプレートの作成
```python
prompt_template = PromptTemplate.from_template('{topic}について大喜利してください')
```

#### テンプレートに代入する方法１
```python
formatted_prompt1 = prompt_template.format(topic='靴下')
print(formatted_prompt1)
```

```output:output
'靴下について大喜利してください'
```

#### モデルに入れる（これはテンプレートに代入する二種類の方法に共通）
```python
response1 = model.invoke(formatted_prompt1)
print(response1)
```
```output:output
AIMessage(content='もちろんです！靴下に関する大喜利をいくつかご紹介しますね。\n\n1. **靴下が語る！**  \n   「私、靴下です。最近、友達の靴に入ったら、すごい『足音』がしたんですけど…それって普通ですか？」\n\n2. **靴下の悩み**  \n   「靴下って、いつも片方が行方不明になるんです。私、洗濯機の中で何が起きてるか知ってますよ…新しい靴下が転職してるんです。」\n\n3. **靴下の夢**  \n   「私の夢は、靴下の中で一番人気のある“カラフル靴下”になること！でも、いつも“地味靴下”に引きずられてる…。」\n\n4. **靴下の告白**  \n   「実は、私、靴下です。あなたの足に触れるのが好きなんですが、どうしても靴の中に閉じ込められてしまう。もっと自由になりたい…。」\n\nいかがでしたか？靴下をテーマにした大喜利、楽しんでいただけたら嬉しいです！もっと別のテーマでも大喜利が必要でしたら教えてくださいね。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 305, 'prompt_tokens': 15, 'total_tokens': 320, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_d54531d9eb', 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {}}, id='run-0fa000e9-0065-428f-b02d-69ac88148d2b-0', usage_metadata={'input_tokens': 15, 'output_tokens': 305, 'total_tokens': 320, 'input_token_details': {}, 'output_token_details': {}})
```


#### テンプレートに代入する方法２
```python
formatted_prompt2 = prompt_template.invoke({'topic': '靴下'})
print(formatted_prompt2)
```
```output:output
StringPromptValue(text='靴下について大喜利してください')
```

ちょっと出力が違いますね






#### こちらもモデルに入れる
```python
response2 = model.invoke(formatted_prompt2)
print(response2)
```

```output:output
AIMessage(content='もちろん、靴下についての大喜利を楽しみましょう！いくつかのネタを考えてみました。\n\n1. **靴下の言い訳**\n   - 「ごめん、今日のデートに靴下を履いてこなかったのは、足元が気になると思ったから…」\n\n2. **靴下の悩み**\n   - 「俺たち靴下、毎日ペアで頑張ってるのに、洗濯機で片方だけ行方不明になるの、なんでなんだろうね？」\n\n3. **靴下の願い**\n   - 「お願い、もう一度だけ、靴の中に戻して！その後の冒険は、靴の中が一番楽しいんだ！」\n\n4. **靴下の自己紹介**\n   - 「こんにちは、私は靴下のソックス。みんなに温もりを届けるために生まれてきました。でも、穴が開いたら、さようなら…」\n\n5. **靴下の新しいビジネス**\n   - 「靴下のリサイクルショップ、名付けて『ソックス・リユース』。一度履かれた靴下を、もう一度履く勇気、ありますか？」\n\nいかがでしょうか？靴下についての笑いをお楽しみいただけたら嬉しいです！', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 317, 'prompt_tokens': 15, 'total_tokens': 332, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_d54531d9eb', 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {}}, id='run-6590bece-4a66-479b-b0b3-616f4a5d249b-0', usage_metadata={'input_tokens': 15, 'output_tokens': 317, 'total_tokens': 332, 'input_token_details': {}, 'output_token_details': {}})
```


意外とまともに大喜利していて楽しい。
大喜利LLM作りたいって松尾研の人がいたなぁ。（俺もやりたい！）




## ChatPromptTemplateを使う
```python
prompt_template = ChatPromptTemplate([
    ('system', 'あなたは偉大な漫才師です'),
    ('user', '{topic}について大喜利してください'),
])

prompt_value = prompt_template.format(topic='靴下')
# prompt_template.invoke({'topic': '靴下'})でもOK
response = model.invoke(prompt_value)

print(response.content)
```

```output:output
'もちろん！靴下についての大喜利、いきますよ！\n\n1. 靴下が「もう一足、兄弟がいるんだ！」と言った理由は？\n   - 洗濯機の中で、いつも片方だけ消えるから！\n\n2. 靴下が恋に落ちる瞬間とは？\n   - 「君の足にぴったりハマったとき、運命を感じたよ！」\n\n3. もし靴下が話せたら、最初に言うセリフは？\n   - 「もう一度、あのスニーカーに戻りたい…」\n\n4. 靴下の夢は何だと思う？\n   - 「洗濯機の中のパーティーに参加すること！」\n\nいかがでしたか？靴下も意外と面白いこと言いそうですね！'
```

# その１の終わりに
ま、ここまではOKですよね
たぶんみんなOK
ドキュメントをしっかり読めば問題ないと思います。平易な英語で書かれているので僕でも読める。TOEIC言いたくないくらいの点数だけどね。笑

ほんじゃ、その２をマテ！