LangChainの PromptTemplate を使って Amazon Nova を実行したい 

## はじめに

LangChainの PromptTemplate クラスを使うことで、プロンプトの再利用性や管理のしやすさが向上します。
- プロンプトの一貫性が保てる
- 変数の動的な埋め込みが簡単になる

こちらも参考にして下さい。

https://qiita.com/Kahiro/items/3bb75812e5767f12b005

## 筆者のレベル

- プログラミング経験はあまりないが、実際にコードを作成して動かすことで、理解を深めていきたいと考えている。

## 記載していること

- LangChainのPromptTemplateクラスの基本的な使い方
- Amazon Novaの呼び出し

## PromptTemplate クラスの階層

**１．BasePromptTemplate**
├── **２．StringPromptTemplate**
　　　├── **３．PromptTemplate**

- **１．BasePromptTemplate**：
　　　プロンプトテンプレートの基底クラス
- **２．StringPromptTemplate**：
　　　文字列ベースのプロンプトテンプレートを定義する抽象クラス
- **３．PromptTemplate**：
　　　実際に使用するプロンプトテンプレートのクラス

PromptTemplateクラスは、文字列フォーマットを用いてプロンプトを動的に生成する機能を提供しています。


## PromptTemplateクラスのパラメータの説明
PromptTemplateクラスの代表的なパラメータについて説明します。

### template（必須）
　プロンプトのテンプレート文字列を定義します。
　{} で変数を埋め込む形式で記述します。
  
``` python
template = PromptTemplate(
    input_variables=["topic"],
    template="あなたはAWSエンジニアです。{topic} について解説してください。"
)
```
❗️ 変数 {topic} が埋め込まれる
❗️ .format() を使って変数を挿入可能


### input_variables（必須）
　template 内で使用する 動的に置き換えたい変数のリスト を指定します。
  
``` python
template = PromptTemplate(
    input_variables=["name", "topic"],
    template="こんにちは {name} さん！{topic} について詳しく教えてください。"
)

formatted_prompt = template.format(name="太郎", topic="Nova")
print(formatted_prompt)
# → "こんにちは 太郎 さん！Nova について詳しく教えてください。"
```
❗️ 指定した変数を format() で埋め込める
❗️ 変数が不足しているとエラーになる


### partial_variables
　template の一部の変数を**固定値として事前に埋め込む**ことができます。
　input_variables で指定する必要はありません。
  
``` python
template = PromptTemplate(
    input_variables=["name"],
    template="こんにちは {name} さん！{topic} について詳しく教えてください。",
    partial_variables={"topic": "Nova"}
)

formatted_prompt = template.format(name="太郎")
print(formatted_prompt)
# → "こんにちは 太郎 さん！Nova について詳しく教えてください。"
```
❗️ topic は固定値なので format() で指定不要


### metadata
　メタデータ情報（例えばバージョン情報やタグ）を格納できます。 
``` python
template = PromptTemplate(
    input_variables=["name"],
    template="こんにちは {name} さん！{topic} について詳しく教えてください。",
    partial_variables={"topic": "Nova"},
    metadata={"version": "1.0"}
)

print(template.metadata)
# → {"version": "1.0"}
```
❗️ テンプレートの管理情報を追加できる

## Amazon Novaの呼び出し

LangChainのChatBedrockクラスを利用して、Amazon Novaを呼び出します。
ChatBedrockクラスは、LangChainでAWSのBedrockを利用するためのクラスです。


Amazon Novaの呼び出しに必要なモデルIDを示します。
これらは、Amazon Bedrock の Model catalog から確認することができます。


|名称  |モデルID  |
|---|---|
|Nova Micro  |amazon.nova-micro-v1:0  |
|Nova Lite  |amazon.nova-lite-v1:0  |
|Nova Pro  |amazon.nova-pro-v1:0 |
|Nova Canvas  |amazon.nova-canvas-v1:0 |
|Nova Reel  |amazon.nova-reel-v1:0  |

## ChatBedrockクラスのパラメータの説明
ChatBedrockクラスの代表的なパラメータについて説明します。

### model_id（必須）
　使用するBedrockのモデルIDを指定します。

### region_name（必須）
　Bedrockを利用するリージョンを指定します。

### model_kwargs（任意）
　モデルの動作を調整するパラメータを指定します。
　主要なパラメータは次のとおり。

 - max_tokens
生成する最大トークン数
 - temperature
生成の多様性を調整（0.0〜1.0）
 - top_k
上位 K 個の候補から選択


## 実装例

以下は、LangChainの PromptTemplate を使って Amazon Nova を実行する例です。

``` python
from langchain.prompts import PromptTemplate
from langchain_aws import ChatBedrock

# プロンプトテンプレートの定義
template = PromptTemplate(
    input_variables=["topic"],
    template="あなたは {name}のアーキテクトです。{topic} について詳しく教えてください。",
    partial_variables={"name": "AWS"},
)

formatted_prompt = template.format(topic="Bedrock")
print(formatted_prompt)

# ChatBedrockの定義
llm = ChatBedrock(
    region_name="us-east-1",
    model_id="amazon.nova-micro-v1:0",
    model_kwargs={
        "max_tokens": 100,
        "temperature": 0
    }
)

result = llm.invoke(formatted_prompt)
```

## まとめ

このようにLangChainの PromptTemplate クラスを活用することで、プロンプトの管理が容易になり、一貫性を持たせたプロンプト設計が可能になります。また、ChatBedrockクラス を利用すれば、Amazon Bedrock上のモデル（Novaシリーズなど）を簡単に呼び出すことができます。

## 参考文献
- [LangChain APIリファレンス](https://python.langchain.com/api_reference/index.html)