Amazon Bedrock と Stripe Agent Toolkit を LangChain と LangGraph で動かしてみた

:::note info
この記事は [Stripe / JP_Stripes Advent Calendar 2024](https://qiita.com/advent-calendar/2024/stripe) の12月23日分の記事です。
:::

:::note warn
開発者プレビュー状態の機能を扱っています。
:::

なかなかうまく動かすことができず、遅くなってしまいました。

Stripe から 面白そうな機能が発表されていたので、とりあえず触ってみました。

https://prtimes.jp/main/html/rd/p/000000082.000077879.html

エージェントワークフローに決済の機能を追加することができる「Stripe Agent Toolkit」というものが発表されました。LINEなどで「これください」って言ったら支払い画面が出てきて実際に決済できちゃう。みたいなのが作れてしまいそうです。スモールビジネスとかに効きそうじゃないですか。

機能としては開発社プレビューの状態です。

AWS 大好きなので、 Amazon Bedrock を使って、Payment Links を使用して、決済できるURLをもらうところまでをゴールとしています。すぐ終わる予定だったのですが、LangChain/LangGraph まわりの理解がまだまだでして、時間がかかってしまいました。

## 手探りでいろいろさわってみる

公式のドキュメントを参考に最初はやってみたのですが、うまく動かず。

https://docs.stripe.com/agents?locale=ja-JP&framework=langchain

クイックスタートもTypeScriptでフロントエンドまで付いてくるみたいで、今回の目的からだとやりすぎ

https://docs.stripe.com/agents/quickstart

## GitHub のリポジトリから

https://github.com/stripe/agent-toolkit/tree/main/python/examples/langchain

ツールのリポジトリにすぐ動きそうなサンプルが入っているのを紆余曲折あってやっと見つけました。

これなら動きを試すことができそうです。

動かしている環境について、macOS 15.1.1 (24B91) のローカルでPythonを実行して動きを確認します。

```shell
$ python --version
Python 3.13.0

$ pip --version
pip 24.3.1

$ aws --version
aws-cli/2.22.2
```
Stripe のAPI バージョンは ```2024-12-18.acacia``` を使用しています。

サンプルコードを一部修正して、
Amazon Bedrock から Claude 3.5 Sonnet を叩くように変更します。

```diff_python:main.py
import os
from dotenv import load_dotenv

from langchain import hub
- from langchain_openai import ChatOpenAI
+ from langchain_aws import ChatBedrock

from langgraph.prebuilt import create_react_agent

from stripe_agent_toolkit.langchain.toolkit import StripeAgentToolkit

load_dotenv()

- llm = ChatOpenAI(
-     model="gpt-4o",
+ llm = ChatBedrock(
+     region_name="ap-northeast-1",
+     model_id="anthropic.claude-3-5-sonnet-20240620-v1:0",
+     model_kwargs={
+         "max_tokens": 1000,
+         "temperature": 0.1
+     },
)

stripe_agent_toolkit = StripeAgentToolkit(
    secret_key=os.getenv("STRIPE_SECRET_KEY"),
    configuration={
        "actions": {
            "payment_links": {
                "create": True,
            },
            "products": {
                "create": True,
            },
            "prices": {
                "create": True,
            },
        }
    },
)

tools = []
tools.extend(stripe_agent_toolkit.get_tools())

langgraph_agent_executor = create_react_agent(llm, tools)

input_state = {
    "messages": """
+         来月の授業料５万円分の支払いを行いたいです。
    """,
}

+ try:
    output_state = langgraph_agent_executor.invoke(input_state)
    print(output_state["messages"][-1].content)
+ except Exception as e:
+     print(f"Error: {e}")
    
```
README.md にも記載がありますが、`.env.template` を元に `.env` を作成してください。`.env`ファイルの中にStripe のシークレットキーを記載しましょう。

Stripeでサンドボックス環境を作成し、シークレットキーを使うと良いです。`sk_test`から始まるものを環境変数に設定しましょう。

```.env
STRIPE_SECRET_KEY="sk_test_......"
```

ここまで来れば、`main.py` を実行するだけです

```shell
$ python main.py
はい、来月の授業料5万円分の支払いのための準備ができました。以下の手順で支払いを行うことができます：

1. 授業料という名前で商品を作成しました。
2. その商品に対して、5万円（50,000円）の価格を設定しました。
3. 支払いリンクを作成しました。

支払いを行うには、以下のURLにアクセスしてください：
https://buy.stripe.com/test_3csfZfbZP37n3dufZ0

このリンクから、安全に授業料の支払いを行うことができます。支払い手続きの際は、クレジットカードなどの必要な情報を入力してください。

何か質問や追加の要望がありましたら、お気軽にお聞かせください。
```

**来月の授業料５万円分の支払いを行いたいです。**
というプロンプトから支払いのリンクが生成されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927755/562c2e5b-8dc4-9f91-d734-40b6caaa0872.png)

Stripe Workbench を開いてログを確認してみると、

1. /v1/products で商品を作成
1. /v1/prices で作成した商品に価格を設定
1. /v1/paymentlinks で数量１個で支払いリンクを作成

という手順をとっていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927755/4f56e01a-d0b5-775a-cd29-5faa71fa91a4.png)

以下のプロンプトの出力部分と一致していますね

```shell
1. 授業料という名前で商品を作成しました。
2. その商品に対して、5万円（50,000円）の価格を設定しました。
3. 支払いリンクを作成しました。
```

## 🦀

カニを依頼してみましょう

```python
input_state = {
    "messages": """
        カニを買いたいです。
        適当にカニの画像を設定してください。
        価格は１つ１万円のものを５セットください。
        商品の説明は美味しそうなシズル感のあるものを設定してください。
    """,
}
```
画像は無理っぽいですが、どうなるでしょう

```shell
python main.py  
カニの商品を作成し、価格を設定し、支払いリンクを生成しました。以下が詳細です：

1. 商品名：極上ズワイガニ
2. 商品説明：厳選された極上のズワイガニをお届けします。身がぎっしり詰まった大ぶりの脚は、口の中でとろけるような甘みと旨味が広がります。蒸したてのカニから立ち上る香りと、ほぐした身の艶やかな赤色が食欲をそそります。カニ本来の味を存分に楽しめる、贅沢な一品です。
3. 価格：1セット10,000円
4. 数量：5セット

支払いリンクが生成されました。以下のURLから購入することができます：
https://buy.stripe.com/test_14k4gxe7XbDT4hy9AD

このリンクから、5セットの極上ズワイガニ（合計50,000円）を購入することができます。なお、画像については、Stripeの商品作成機能では直接設定できないため、別途管理画面から追加する必要があります。

ご要望通り、美味しそうなシズル感のある商品説明を設定しました。カニの魅力が伝わるよう、視覚的・味覚的な表現を使用しています。

何か他にご要望やご質問がありましたら、お気軽にお聞かせください。

```


*厳選された極上のズワイガニをお届けします。身がぎっしり詰まった大ぶりの脚は、口の中でとろけるような甘みと旨味が広がります。蒸したてのカニから立ち上る香りと、ほぐした身の艶やかな赤色が食欲をそそります。カニ本来の味を存分に楽しめる、贅沢な一品です。*

なかなか良さそうな説明文も生成しつつ、APIになげて登録してくれています。

残念ながら、画像の設定はできないと、断られてしまったので、生成された説明文を Amazon Nova Canvas に渡して出力された画像を商品画像としてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927755/ca5ad492-a5f5-fe94-18ff-ca6c20f56cff.png)

この画像の解釈をするにはもう眠いので、一旦ここまでとしたいと思います。

## まとめ

エージェントの機能のひとつとして、Stripe API を叩くことができるようです。個人的にはチャットのインターフェースとPayment Linksと相性良い気がするので、実際のユースケースに落とし込んで考えてみたいと思います。