Ansible Lightspeed with IBM Watson Code Assistant で自動コード生成

## 概要

2023年に入り、生成 AI の勢いがさらに凄みを増して行っているのをひしひしと感じる日々で、「生成 AI」や「ChatGPT」の言葉を聞かない日はないほどだ。
この動きは一般的な会社や官公庁の業務にも影響を及ぼしており、AI の技術で業務効率化、自動化などを考えているところも増えている印象をうける。

AI による自動コード生成もすでに現実化してきている。[GitHub Copilot](https://github.com/features/copilot) や [Amaxon CodeWhisperer](https://aws.amazon.com/jp/codewhisperer/) といったサービスも利用可能であり、ソフトウェアエンジニアリングが大きなパラダイムシフトを迎えようとしている。
そんな中、Redhat 社より先月5月、Ansible Lightspeed が発表された。
これは、生成 AI により、Ansible の自動コード生成を行なってくれるというものだ。
上記二つのサービスが、今のところプログラミング言語をコード生成の対象としているのに対して、Ansible Lightspeed　では、現在のところ **Ansible のコード(Ansible task が対象)を生成対象としている**。
では、Ansible のコード生成のための準備手順と実際使ってみるところまでさらっと見てみたい。
**※執筆時点(2023/6/27)では、このサービスは Tech Preview 版となり、今後色々と変更が入る可能性はある。**

## 前提

- 自動コード生成に使用した環境: Mac(Apple M1 Pro), macOS 12.6.5

## アーキテクチャ

![archi2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/0c12a575-29a2-369a-6068-871399e47e50.png)


独断と偏見が混じったアーキテクチャはこのような形になる。
VSCode で自然言語[^1]で記述した task の `name` セクションが入力値となり、Ansible Lightspeed の extension を通してバックエンドである Watson Code Assistant に渡され、モデルに基づいて、コードが生成される。その結果を最終的にどういう形で提案されるべきかが Ansible Lightspeed により決定され、VSCode に最適と判断されたものが表示される。
この時、その提案を受け入れたか拒否したかなどの情報がフィードバックとして再度 Watson Code Assistant に伝えられ、モデルのトレーニングに利用される。このほかにも、[これら](#提案されるコードは何をもとにして生成されるか)の情報がバックエンドに送信されることになっている。
また、[後述](#将来的には個人的主観)しているように、将来的には IBM watsonx というモデルのトレーニング・チューニングプラットフォームとの連携も考えられる。


[^1]:執筆時点(2023/7月)では英語のみ対応。

## 設定

基本的には、[このあたりのページ](https://github.com/ansible/ansible-lightspeed/blob/main/docs/vscode_guide/installing_vs.md)に書いていることをやっていく。

### VSCode

#### extension のインストール

VSCode に Ansible の extension をインストールする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/39981950-79de-d9c4-760d-11223a50fd1e.png)

該当 extension ページの Configuration にある、`ansible.lightspeed.*` の設定項目が、今回の目的の機能となる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/1183a6b8-d7a7-de6f-ab23-d9c1b3302597.png)


#### extension の設定

`settings.json` を開き、下記の設定を追加する。

```settings.json
{
  "ansible.lightspeed.enabled": true,
  "ansible.lightspeed.suggestions.enabled": true
}
```

#### サンプルコードの用意

`playbooks` というフォルダと、その下に `test.yaml` を作成する。

```sh
mkdir playbooks

touch playbooks/test.yaml
```

エディタで test.yaml を開くと、「Python の環境を選択してください」と言われる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/70298bb1-1373-cee1-ad0c-81c5f4f5c42a.png)

黄色くなっているところをクリックすると、Python 環境の選択候補がいくつか表示されるので、Recommended のものをクリックして選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/252da860-2999-7736-6d91-9e52c5747c76.png)

すると、設定ファイルに自動的に phthon　環境へのパスが追加される。

```diff_json
{
  "ansible.lightspeed.enabled": true,
  "ansible.lightspeed.suggestions.enabled": true,
+  "ansible.python.interpreterPath": "/opt/homebrew/bin/python3"
}
```

#### Ansible/Python 関係のエラー解決

VSCode 画面の右下に、依然として二つほどエラーがでている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/904fd2c4-6fe5-a396-cdef-9082a42b3374.png)

##### 1. `Ansible-lint is not available. Kindly check the path or disable validation using ansible-lint`

ansible-lint が有効になっていない、というエラーであり、解決には以下の二つ
- 別でライブラリをインストールする
- Ansible extension の設定で lint を無効にする

ansible-lint インストール場合は以下コマンドでインストールする。

```sh
brew install ansible-lint
```

ansible-lint を無効化する場合は、`settings.json` に追記する。

```diff_json
{
  "ansible.lightspeed.enabled": true,
  "ansible.lightspeed.suggestions.enabled": true,
  "ansible.python.interpreterPath": "/usr/local/bin/python",
+  "ansible.validation.lint.enabled": false
}
```

##### 2. `Command failed: ansible-config dump /bin/sh: ansible-config: command not found`

そもそも Ansible がインストールされていない場合、このようなエラーが出る。
そのため、Ansible を以下コマンドにてインストールする。

```sh
python3 -m pip install --user ansible
```

これだけだと ansible コマンドが見つからない可能性があり、その場合は、ansible のコマンドへのパスを追加する。

```sh
python3 -m site --user-base
# /Users/xxx/Library/Python/3.11
# → /Users/xxx/Library/Python/3.11/bin を PATH に追加する

vi ~/.zshrc

export PATH="$HOME/Library/Python/3.11/bin:$PATH"
```

ここまでで下準備は整ったので、ここから実際にコードの自動生成を見ていく。


## 自動コード生成

### 簡単な yaml を書いてみる

```yaml
- name: AWS EC2 Cloud Operation
  tasks:
    - name: create ec2 instance
```

`create ec2 instance` の行末で Enter を押すと、画面右下にこのような表示がされる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/fa6be216-139a-b615-7e9a-970af763f3a6.png)

`Login` をクリックし、指示に従って進めていく。
ブラウザが立ち上がり、`Log in to Ansible Lightspeed with Watson Code Assistant` の表示がされたところで、GitHub でのログインを促される。
無事ログインが成功すると、VSCode の先ほどのエディタ上で再度 Enter を押すと、数秒待ったのち**画像のようなコードが提案された。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/4205b19c-bbfe-b64a-2c94-a0a5cbcd12f6.png)

この状態で Tab を押すと、提案されたコードが確定となり、入力された状態になる。
また、Esc を押すことで、キャンセルもできる。

### 少し注文を増やした yaml を書いてみる

```yaml
- name: AWS EC2 Cloud Operation
  tasks:
    - name: create smallest ec2 instance
```

結果はこのようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/aff025de-69a8-5922-d30d-f824bd741dca.png)

`instance_type: t2.micro` の部分に smallest のニュアンスが入っていることが受け取れる。(t2.micro が _smallest_ かどうかは議論があるが(というか t2.nano の方が小さい)、AI が頑張って提案してくれた感はある)
しかし、今のままではまるで商用としてはなかなか使いづらいかもしれない。


## 裏側のこと

### モデル

コード生成に使用されるモデルは、**Foundation Model** と呼ばれる技術を用い IBM によってトレーニングされる。Foundation Model(基盤モデル)は、ざっくりいうと、最終的にさまざまな用途に使用できるモデルを作る前段階として汎用的なモデルをまずは作成し、そこから各用途に応じたファインチューニングを行なっていく、というコンセプトのもとに成り立っている。今流行りの大規模言語モデル(LLM)と呼ばれるものもこれの一種である。Foundation Model では、汎用的なモデルの作成には多くのデータを必要とするが、ラベルなしのデータによる自己教師あり学習を行わせるため、現実的なコスト内でこれを行うことができる。

### モデルのトレーニング

Ansible Lightspeed with Watson Code Assistant では、コード生成対象となる playbook の内容やファイル名、また [Ansible Galaxy](https://galaxy.ansible.com/) や GitHub で利用可能な roles や collections その他データが利用される。
モデルのトレーニングには、ユーザーからのフィードバックが重要な役割を果たすが、これは提案されたコードを受け入れる/破棄される/変更される などのアクションがフィードバックとして利用される。

#### 提案されるコードは何をもとにして生成されるか？

現状以下のような項目が提案に寄与するようになっている。

| 項目 | 説明 |
|:-:|:-:|
| 提案に対するリアクション  | 提案が受け入れられたか or 拒否されたか |
| task の name の記述内容 | コード提案をしてもらいたい内容を自然言語で記述したもの |
| playbook/role コンテキスト  |  task の name 記述以前に存在していた playbook の内容 |
| playbook の内容  | コード提案時に、その中のどの部分が重要だったか、またはそうではなかったか  |
| ドキュメント URI(匿名化) | Ansible のどのドキュメントかを区別(playbook/role など) |
|  リクエスト/レスポンスタイムスタンプ | UTC フォーマット  |
| ユーザー ID(匿名化)  | `~/.redhat/anonymousid` の内容  |
| 提案 ID(匿名化) | リクエスト時に自動生成されるセッション ID |


#### モデルのトレーニングに自分のコードを参加させたくない時

以下の手順を行う。

1. [Ansible Galaxy NG](https://beta-galaxy-dev.ansible.com/ui/) にいく。
1. 表示されるページでログインする。（初回は、GitHub アカウントとの連携を求められる）
1. 画面左メニューより、**コレクション** > **名前空間** をクリックする。  

    <img width="200" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/cda6ecc1-9762-05e8-bef7-cec228fe0677.png">

1. 更新された画面右側で **自分の名前空間** をクリックし、下部に表示される名前空間からモデルトレーニングに参加させたくないものを選ぶ。

    <img width="200" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/8f5a49d7-53bd-ae2c-f32a-9f33cd1dc6cf.png">

1. 選択した名前空間の画面が表示されたら、画面右上の **...** > **Ansible Lightspeed の設定** をクリックし、表示されるポップアップ上で **Ansible Lightspeed をオプトアウトする** をクリックする。

    <img width="200" title="1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/bd3741f4-75c9-5ae0-2979-e2e23cdb85d1.png">

    <img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/22ed8cd7-2b18-3abc-198e-6437fd76bb8c.png">


### ロードマップ(2023/7/20 時点)

Red Hat 社からアナウンスされているロードマップのうち、個人的に興味があるものをいくつかピックアップして記載する。


#### Short Term

- 自然言語からの完全な Ansible playbook の生成
- REST API による CI/CD パイプラインや開発ツール、その他の自動化エコシステムとの統合
- モデルのチューニング機能

#### Middle-Long Term
- ドキュメントの自動作成
- Web や CLI ベースの UI 提供と他のエディタへの対応
- ユーザーが所属する組織のポリシーに基づいた推奨内容のチューニング
- 非構造データの構造化と解析


### 将来的には(個人的主観)

現時点では Tech Preview 版ということで、基本的にはパブリックデータをベースにしたモデルのトレーニングおよびそれに基づくコード提案となるが、正式なサービスイン後は、企業が固有のデータでトレーニング/ファインチューニングしたモデルが自動コード生成に利用されることが想定される。これは、**watsonx** という、Ansible Lightspeed と同時期に発表されたプラットフォームと併せて利用することにより実現されると考えられる。


### 参考

- https://www.youtube.com/live/ukxE_4O0Woc?feature=share&t=7961 (Ansible Automates 2023 Japan)
- https://www.imagazine.co.jp/ibm-watsonx/
- https://pc.watch.impress.co.jp/docs/news/1499191.html