GPT-3デモとプロンプト・プログラミング

## はじめに
話題のGPT-3について知人を通じて触れる好機を得ました。
日本語の記事は少ないということで、多少思うところもあり、使ってみての使用感や印象をまとまりなく書いていきたいと思います。


## プロンプト
GPT-2はすでに学習モデルが公開されており、PyTorchなどを利用して巨大データセットをもとにして転移学習をすることができます。
一方そのGPTシリーズ最新作たる3は現在、なんからの巨大学習モデルとして訓練は不可能です。今できることは、ほんの少しだけ文章(など)を渡して、それに続く文章を出力する補完(completion)というタスクです。

この「GPT-3に予測させたい呼び水のような文や文字や数字の羅列」を**プロンプト**(促すもの)と言います。
コンソール画面でいうプロンプトと言えば $とか # ですが、GPTシリーズの場合はテキストによってAIを促します。

自然言語からReactコードの生成する[Sharif Shameemのデモンストレーション](https://twitter.com/sharifshameem/status/1282692481608331265/)も、その前に以下のようなプロンプトが背後で挿入されています。


```
description: a red button that says stop
code: <button style={{color: 'white', backgroundColor: 'red'}}>Stop</button>

description: a blue box that contains 3 yellow circles with red borders
code: <div style={{backgroundColor: 'blue', padding: 20}}><div style={{backgroundColor: 'yellow', border: '5px solid red', borderRadius: '50%', padding: 20, width: 100, height: 100}}></div><div style={{backgroundColor: 'yellow', borderWidth: 1, border: '5px solid red', borderRadius: '50%', padding: 20, width: 100, height: 100}}></div><div style={{backgroundColor: 'yellow', border: '5px solid red', borderRadius: '50%', padding: 20, width: 100, height: 100}}></div></div>
```

そしてこの文章に続けて、予測してほしいものの「流れ」を作ります

```
description: a button looks like a watermelon
code: 
```

`description`に予測してほしい「a button looks like a watermelon(スイカみたいなボタン)」と説明を入れて、APIに投げます。
すると`code`以降の文章をGPT-3が生成してくれるという仕組みになっています。

今の所全てのGPT-3APIを利用したアプリケーションは、このようなプロンプトを活用して作られています。
GPT-3に与えるパラメータはこれ以外にもtemperatureなど複数あるのですが、このプロンプトこそが高い汎用性と、高い実用性を促す要因となっています。

### Prompts As Programming
> これは従来の深層学習モデルとは異なる使い方で、新しいプログラミングです。プロンプトはいまやGPT-3を使って新しいことをする「プログラム」になったと考えたほうが良いでしょう。
>
> **[GPT-3 Creative Fiction](https://www.gwern.net/GPT-3#prompts-as-programming)**


独立系研究者[Gwern](https://www.gwern.net/)はこれをPrompts As Programming(プラグラミングとしてのプロンプト)と呼んでいます。プロンプト**そのものもまたプログラミング**と言えます。

どんなプロンプトを与えるか？ というのがこれからのプログラミングの鍵の一つになっていくかもしれません。

今日エンジニアは、IDEやエディタの力を借りて、次にどんな変数、関数、記号が現れるか素早く予測し、タブキーでその予測を選択できる時代にいます。
この補完プログラミングの時代においては、組み込み関数、型情報、メソッド、すでに打ち込まれた変数を呼び出したりと、補完機能に強く依存していることでしょう。
それをより拡張されたプログラミングが、プロンプト・プログラミングだと言えます。「そこまで勝手に書くの？」と言えるほどエディタが書いてくれてしまう。それがありがた迷惑なこともありますが、上手く使いこなせば十数行勝手にAIが書いてくれるでしょう。なんと便利ではないでしょうか！


## ちょっとした実験
### CSSでのプロンプト例
上記したSharif ShameemのJSXコードですが、よく見てもらえれば分かりますが、基本的にはHTML/CSSのコードです。複雑なDescriptionを与えるのは、正直難しいです。
内容的にはCSSで書き換えられるので、これから使用する実験では、プロンプトとして以下のようなものを使用しました。

```
description: a red button that says stop
code: <button style="color: white; background: red;>Stop</button>

description: a blue box that contains 3 yellow circles with red borders
code: <div style="background: blue; padding: 20px;"><div style="background: yellow; border: 5px solid red; border-radius: 50%; padding: 20px; width: 100px; height: 100px;"></div><div style="background: yellow; border: 5px solid red; border-radius: 50%; padding: 20px; width: 100px; height: 100px;"></div><div style="background: yellow; border: 5px solid red; border-radius: 50%; padding: 20px; width: 100px; height: 100px;"></div></div>
```


## 実験1  自然言語からCSSへ
Shameemのコードが再現できるか実験してみます。
プロンプトを与えた後、「スイカみたいなボタン」と書き込んで、そのとおりのコードになるか？

**入力** :  a button looks like a watermelon
(スイカみたいなボタン)

**出力**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294146/bcd6ab4c-2f79-ac3e-a75c-42eba0dee832.png)

スイカみたいなボタンはできています。ただ`code:`というプロンプトの一部が残っているうえ、閉じタグがないのでおかしなことになっていますね。

## 実験2 自然言語からCSSへ

**入力**  : large text in red that says "WELCOME TO MY NEWSLETTER" and a blue button that says subscribe
(WELCOME TO MY NEWSLETTERと書かれた大きな赤い文字と、subscribeと書かれたボタン)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294146/e17c5727-faff-0be9-6cfc-fe4fcc434394.png)

求めていた出力は **「大きな赤い文字でWELCOME TO MY NEWSLETTERと、subscribeと書かれたボタン」** だけでしたが、何か余計なものまで出力されています。


## 実験3 Reactコードの出力

これは[Harley TuranのReactコード生成のデモンストレーション](https://twitter.com/hturan/status/1282261783147958272)を参考にしています。

promptは「３つのボタンのコンポーネント」と命名された「関数式」だけです。コンポーネントと命名はされていますし、Reactもimportされていますが、それがReact関数コンポーネントとは書いていません。これを以降のコードを補完してもらいます。

```react
import React from 'react';

const ThreeButtonComponent=()=>(
```

GPT-3による予測出力は以下の通りです(プロンプトも一緒に書いています)

```react
import React from 'react';

const ThreeButtonComponent=()=>(

<div>

<button onClick={()=>alert('Hello')}>Click Me</button>

<button onClick={()=>alert('Hello')}>Click Me</button>

<button onClick={()=>alert('Hello')}>Click Me</button>

</div>

);

export default ThreeButtonComponent;

```
素晴らしい！
ThreeButtonComponentという名前の通り、ボタンが３つあるコードを返してくれます！

ちなみに、temperatureなどパラメータに変化を加えると出力も変化します。

```react
import React from 'react';

const ThreeButtonComponent=()=>(

<div className="three-button">

<button>Cancel</button><button>OK</button><button></button>

</div>

);







export default function cancel(e) { // do something here }
```


## 実験4 Todoリストコンポーネントを作ってもらう

今度は単にコンポーネントの名前を`TodoListComponent`に変更しました。

```react

import React from 'react';

const TodoListComponent=()=>(
```

↑これが、↓こう出力されます(プロンプト含む)

```react

import React from 'react';

const TodoListComponent=()=>(

<div className="todo-list">

{this.props.todos.map(todo => (

<div key={todo.id}>

<input type="checkbox" value={todo.completed} onChange={()=> this.toggleTodo(todo) } /> { todo.text }</div>

))}</div>);

















export default TodoListComponent;

```
おお、なんかそれっぽいのができてる……`this.props.todos`が勝手に作られているという問題はありますが。
(やたらと改行が多くインデントがないのはGPT-3のレスポンス通りです)

私は仕事でVue/Nuxtを2年書いていますが、Vueで似たようなことをしようとしましたが上手く出力できなかったので、今回は省略しました。
どういうプロンプトが適切かも経験に頼ることになりますが、もともとプロンプトをしやすい or しづらい言語/フレームワークなどはあるのかもしれません。
そうなると、もしも未来のフレームワークがあるとすれば、それはプロンプト・プログラミングのしやすいフレームワークではないでしょうか？

## 実験5 英語→日本語翻訳

もののついでに、翻訳もしてみましょう。
はじめに、プロンプトとして以下のような文章を与えます。

```
English: I do not speak French.
Japanese: 私はフランス語を話しません。

English: See you later!
Japanese: またね！

English: Where is a good restaurant?
Japanese: いいレストランはどこ？

English: {example}
Japanese: 
```
簡単なプロンプトを与えて、{example}に、訳したい文章をいれます。

今回はEric Evans著、*Domain-Driven-Design Reference*から、冒頭のドメイン駆動設計関連の用語集を訳してもらいます。
この文章自体から抽象的で分かりにくいもので、日本語に訳すのも骨というものでしょう。
ではGPT-3や機械であれば、どう訳すか？という疑問が浮かびます。

以下の`Japanese: `以降の文字が、GPT-3による翻訳です。プロンプトが一般的すぎでしょうが、これだけでも日本語として翻訳してくれています。
また参考までに、同じ英文についてのDeepLによる翻訳も付け足しています。
サンプルとして少ないですが、どちらの翻訳が優れているかご自分の目でご判断してください


### ドメインとは

> English: A sphere of knowledge, influence, or activity. The subject area to which the user applies a program is the domain of the software.

> Japanese: 一定の圏内に存在する知識、影響力、活動のこと。ソフトウェアを適用する対象となる分野は、そのソフトウェアのドメインである。

> DeepL: 知識、影響力、または活動の領域。ユーザがプログラムを適用する対象領域がソフトウェアの領域となる。

### モデルとは


> English: A system of abstractions that describes selected aspects of a domain and can be used to solve problems related to that domain.

> Japanese: いくつかの要素を抽象化して、それらの要素を使って、その特定のドメインに関する問題を解決できるようにしたもの。

> DeepL: あるドメインの選択された側面を記述し、そのドメインに関連する問題を解決するために使用できる抽象化システム。

### ユビキタス言語とは


> English: A language structured around the domain model and used by all team members within a bounded context to connect all the activities of the team with the software.

> Japanese: ドメインモデルを中心にした言語で、チームメンバー全員がその範囲内で行うすべての活動とソフトウェアとを結びつける。

> DeepL: ドメインモデルを中心に構造化された言語で、限られたコンテキストの中でチームメンバー全員が使用し、チームのすべての活動をソフトウェアに接続します。

### コンテキストとは


> English: The setting in which a word or statement appears that determines its meaning. Statements about a model can only be understood in a context.
> Japanese: 一定の状況下で言葉や文が意味を持つ状況。モデルに関する文章は、その文脈によってその意味を理解することができない。
> DeepL: 意味を決定する単語や文が現れる設定。モデルに関する記述は、文脈の中でしか理解できません。


### 境界づけられたコンテキストとは

> English: A description of a boundary (typically a subsystem, or the work of a particular team) within which a particular model is defined and applicable.

> Japanese: 仕様領域（概念化されたサブシステム、あるいは特定のチームにより定義された仕事の領域）内で、特定のモデルが定義されている。

> DeepL: 特定のモデルが定義され、適用可能な境界（通常はサブシステム、または特定のチームの作業）の記述。

似たような結果にもなっていれば、そうでないものもあります。原文がそもそも難しいためか、日本語訳も難しいのでしょうか……？



## 終わりに
取り急ぎGPT-3の描く未来と、簡単なデモンストレーションを行ってみました。
GPT-3は明らかに**理想的な**汎用人工知能ではありません。いかにも機械的な融通の効かなさが結構あります。
しかしまったく役に立たないということもなく、様々な分野で応用が進んでいくのではないかと思います。
今後OpenAIはAPIを有料で提供していく予定と発表しています。これからどんどんGPT-3、ゆくゆくは4、5と進化していき、エンジニアたちもこれをいかすプロダクトを作っていくことでしょう。大変楽しみです。