watsonx.aiのAPIの使い方とサンプルコード

watsonx.aiでは、metaのLlama3も使えるようになったということで、
watsonx.aiのAPIからの利用方法についてまとめます。

::: note info

この記事はIBMクラウドのアカウントがあることを前提にしています。
ない場合は、[こちらの記事](https://qiita.com/Topfield/items/d3bdd7f696268a562340)を参考にIBMクラウドのアカウントを作成をお願いします。

また、ブラウザ上ではwatsonx.aiでLLMが実行できている、という状態からスタートします。もしまだLLMをブラウザ上で実行できていない場合は、[こちらの記事](https://qiita.com/ironikot/items/a1ff1423c5c2e7c44876)を参考に使える準備をお願いします。
:::

# API利用までのおおまかな流れ
利用までは、下記のフローを実行していきます。
1. APIキーを取得する
1. Project IDを取得する
1. プログラムの実行
    1. APIキーを利用して、アクセストークンの取得
    1. Project IDとアクセストークンを取得して、LLMのAPIを実行する

以降で上記フローの詳細を説明していきます。

## 1. APIキーを取得する 

まずwatsonx.aiのトップページにアクセスし、左上のハンバーガーアイコンを押下し、アクセス(IAM)を押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076333/b9ae8a77-7496-420b-c498-7d191104dd49.png)

次に、APIキーという左のバーを押し、作成ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076333/a16c5fa8-ce4d-18cb-6a79-dc6dc26c1d4a.png)

適当に名前をつけ、作成を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076333/14eedd30-895d-c317-8931-0b832f1bce49.png)

APIキーが表示されるので、メモしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076333/5f6a5bc2-768a-974b-0da7-bc5c975dfe8a.png)

これでAPIキーが取得できました。

## 2. Project IDを取得する

再びwatsonx.aiのトップページに戻り、下部のプロジェクト、を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076333/4256b929-2376-bba6-5deb-4a4166fa77df.png)


管理タブを押すと中段にプロジェクトIDという文字が表示されます。
この中の値をコピーして、メモしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076333/a9d630eb-5588-fa78-e9c3-ec85b065f8d8.png)


## 3. プログラムの実行

Pythonで下記のコードで実行できます。

1番でコピーしたAPIキーを、`api_key = "<your_api_key>"`の部分に貼り付け、
2番でコピーしたプロジェクトIDを`project_id = "<your_project_id>"`の
部分に貼り付けてください。

```python

import requests


def get_ibm_access_token(api_key: str) -> str:
    url = "https://iam.cloud.ibm.com/identity/token"
    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
        "Accept": "application/json"
    }
    data = {
        "grant_type": "urn:ibm:params:oauth:grant-type:apikey",
        "apikey": api_key
    }
    try:
        response = requests.post(url, headers=headers, data=data)
        response.raise_for_status()
        return response.json().get("access_token")
    except requests.exceptions.RequestException as e:
        print(f"Request failed: {e}")
        print(f"Response content: {response.json()}")
        raise

def invoke_prompt(api_endpoint: str, access_token: str, prompt: str, project_id: str, model_id: str="meta-llama/llama-3-70b-instruct") -> str:
    url = f"{api_endpoint}/ml/v1/text/generation?version=2023-05-29"

    body = {
        "input": prompt,
        "parameters": {
            "decoding_method": "greedy",
            "max_new_tokens": 200,
            "repetition_penalty": 1
        },
        "model_id": model_id,
        "project_id": project_id
    }

    headers = {
        "Accept": "application/json",
        "Content-Type": "application/json",
        "Authorization": f"Bearer {access_token}"
    }
    response = requests.post(url, headers=headers, json=body)
    response.raise_for_status()

    try:
        return response.json()["results"][0]["generated_text"]
    except (KeyError, IndexError) as e:
        print(response.json())
        raise ValueError("Error in generating text or parsing response") from e

def main():
    api_key = "<your_api_key>"
    project_id = "<your_project_id>"
    api_endpoint = "https://us-south.ml.cloud.ibm.com"

    access_token = get_ibm_access_token(api_key)
    judge_target_text = "IBMは何の会社？一単語で表してください。"
    results = invoke_prompt(api_endpoint, access_token, judge_target_text, project_id)
    print(results)

if __name__ == "__main__":
    main()

```

注意点
watsonx.aiのリージョンがダラス以外の方は下記の部分も変えてください。
`api_endpoint = "https://us-south.ml.cloud.ibm.com"`


## まとめ

APIキーを利用して、アクセストークンを取得してから、LLMを実行できる、という流れになります。

ちなみに上記の実行結果は、

`IBMは、"Innovation"（イノベーション）という一単語で表すことができます。IBMは、100年以上の歴史を持つ企業であり、コンピューター、ソフトウェア、サービスなど、多くの分野でイノベーションを推進してきました。IBMは、世界中の企業や組織に対して、技術的なソリューションを提供し、ビジネスを推進するためのパートナーとしての役割を果たしています`

だそうです🐝