見出し画像

OpenAI Codex の使い方

OpenAI APIの「Codex」の使い方をまとめました。

前回

1. Codex

Codex」は、自然言語と数十億行のコードの両方で学習したGPT-3ベースのモデルです。Pythonの能力が最も高く、JavaScript、Go、Perl、PHP、Ruby、Swift、TypeScript、SQL、Shell を含む10を超える言語を熟知しています。

「Codex」は、次のような様々なタスクに利用できます。

・コメントをコードに変換。
・コンテキスト内で次の行または関数を記述。
・アプリケーションの有用なライブラリや API 呼び出しなどの知識の提供。
・コメントの追加。
・効率化のためのコードの書き直し。

2. Codexの使用例

Playground」でModelに「code-davinci-002」を指定して試しています。

2-1. 「Hello」と言う (Python)

"""
Ask the user for their name and say "Hello"
"""
name = input("What is your name? ")
print("Hello " + name)

2-2. ランダムな名前の生成 (Python)

"""
1. Create a list of first names
2. Create a list of last names
3. Combine them randomly into a list of 100 full names
"""
import random

first_names = ['John', 'Jane', 'Corey', 'Travis', 'Dave', 'Kurt', 'Neil', 'Sam', 'Steve', 'Tom', 'James', 'Robert', 'Michael', 'Charles', 'Joe', 'Mary', 'Maggie', 'Nicole', 'Patricia', 'Linda', 'Barbara', 'Elizabeth', 'Laura', 'Jennifer', 'Maria']

last_names = ['Smith', 'Doe', 'Jenkins', 'Robinson', 'Davis', 'Stuart', 'Jefferson', 'Jacobs', 'Wright', 'Patterson', 'Wilks', 'Arnold', 'Johnson', 'Williams', 'Jones', 'Brown', 'Davis', 'Miller', 'Wilson', 'Moore', 'Taylor', 'Anderson', 'Thomas', 'Jackson', 'White', 'Harris', 'Martin']

full_names = []

for i in range(100):
    first = random.choice(first_names)
    last = random.choice(last_names)
    full_names.append(f"{first} {last}")

print(full_names

2-3. MySQLクエリの作成 (Python)

"""
Table customers, columns = [CustomerId, FirstName, LastName, Company, Address, City, State, Country, PostalCode, Phone, Fax, Email, SupportRepId]
Create a MySQL query for all customers in Texas named Jane
"""
query =
query = """
SELECT * FROM customers
WHERE State = 'TX' AND FirstName = 'Jane'
"""

run_query(query)

2-4. コードの説明 (JavaScript)

// Function 1
var fullNames = [];
for (var i = 0; i < 50; i++) {
  fullNames.push(names[Math.floor(Math.random() * names.length)]
    + " " + lastNames[Math.floor(Math.random() * lastNames.length)]);
}

// What does Function 1 do?
// Function 1 creates an array of 50 random full names.

2-5. その他の使用例

その他の使用例は、以下の「Example」で参照できます。

3. ベストプラクティス

ベストプラクティスは、次のとおりです。

3-1. コメント・データ・コードから始める

Codexに有用な補完コードを作成させるには、プログラマがタスクを実行するためにどのような情報が必要であるか考えることが役立ちます。例えば、明確なコメントや、変数名や関数が扱うクラス名など、これらは補完コードを作成するために必要なデータです。

# Create a function called 'nameImporter' to add a first and last name to the database

3-2. 言語の指定

Codex は、数十の異なるプログラミング言語を理解します。多くは、コメント、関数、およびその他のプログラミング構文について同様の規則を共有しています。コメントで言語とバージョンを指定することにより、Codex は必要なものをより適切に補完できます。

# R language
# Calculate the mean distance between an array of points
# Python 3
# Calculate the mean distance between an array of points

Codex に何をさせたいかを指示します。CodexにWeb ページを作成させたい場合は、コメントの後にHTMLドキュメント (<!DOCTYPE html>) を配置します。

<!-- Create a web page with the title 'Kat Katman attorney at paw' -->
<!DOCTYPE html>

同じ方法で、コメントの後に func または def で始まる行を追加することで、関数を作成できます。

# Create a function to count to 100

def counter

関数を書き始めると、Codexは次に何をする必要があるかを理解します。

3-3. ライブラリの指定

コメントまたはインポートで使用するのライブラリを指定すると、Codexが必要なものを理解するのに役立ちます。

<!-- Use A-Frame version 1.2.0 to create a 3D website -->
<!-- https://aframe.io/releases/1.2.0/aframe.min.js -->

バージョンを指定することで、Codexが最新のライブラリを使用していることを確認できます。

3-4. コメントのスタイル

一部の言語では、コメントのスタイルによって出力品質が向上します。たとえば、Python を使用する場合、ドキュメント文字列 (三重引用符で囲まれたコメント) を使用すると、シャープ (#) 記号を使用するよりも出力品質が向上します。

"""
Create an array of users and email addresses
"""

3-5. 関数内にコメントを記述

関数内にコメントを記述した方が、Codexが明確に理解するのに役立ちます。推奨されるコーディングでは、通常、関数の記述を関数内に配置することを提案しています。

def getUserBalance(id):
    """
    Look up the user in the database ‘UserData' and return their current account balance.
    """

3-6. 例の指定

Codexで使用する必要がある特定のスタイルまたは形式がある場合は、要求の最初の部分で例を指定すると、Codexが明確に理解するのに役立ちます。

"""
Create a list of random animals and species
"""
animals  = [ {"name": "Chomper", "species": "Hamster"}, {"name":

3-7. temperaturesは低くする

ほとんどの場合、temperatures を0または0に近い値 (0.1 や 0.2 など) に設定した方が、より良い結果を得られます。GPT-3では temperatures が高いほどクリエイティブな結果が得られますが、Codexにとってはランダムで不規則な結果になります。

3-8. 関数が何をすべきかを指定

コメントで関数が何をすべきかをできるだけ正確に指定することで、関数の補完コードを生成できます。

// Create a timer that creates an alert in 10 seconds

3-9. サンプルデータの作成

Codexに、テスト用のサンプルデータを作成してもらうことができます。

/* Create an array of weather temperatures for San Francisco */

Codexにこのタスクの実行を依頼すると、次のサンプルデータが生成されます。

var weather = [
  { month: 'January', high: 58, low: 48 },
  { month: 'February', high: 61, low: 50 },
  { month: 'March', high: 64, low: 53 },
  { month: 'April', high: 67, low: 55 },
  { month: 'May', high: 70, low: 58 },
  { month: 'June', high: 73, low: 61 },
  { month: 'July', high: 76, low: 63 },
  { month: 'August', high: 77, low: 64 },
  { month: 'September', high: 76, low: 63 },
  { month: 'October', high: 73, low: 61 },
  { month: 'November', high: 68, low: 57 },
  { month: 'December', high: 64, low: 54 }
];

3-10. タスクのリストアップ

Codexは、複雑な要求であってもタスクをリストアップすることで、補完コードを生成できます。

/*
Create a list of animals
Create a list of cities
Use the lists to generate stories about what I saw at the zoo in each city
*/

3-11. 結果サイズの制限

maximum length を減らし、stop sequence を設定して、結果サイズを制限することは、より正確な結果を得る、または待ち時間を短縮することに繋がります。

3-12. ストリーミングで待ち時間を短縮

オートコンプリートなど、低レイテンシを必要とする機能には、ストリーミングの使用を検討してください。モデルが全ての結果生成を完了する前に、応答が返されます。

3-13. コードについて説明

Codexに、コードが何を行っているかを説明してもらうことができます。これを実現する方法の1つは、関数の後に"This function" または "This application is." で始まるコメントを入れることです。Codexは通常、これを説明の開始と解釈し、残りのテキストを完成させます。

/* Explain what the previous function is doing: It

3-14. SQLクエリについて説明

Codexに、SQLクエリが何を行っているかを説明してもらうことができます。

SELECT DISTINCT department.name
FROM department
JOIN employee ON department.id = employee.department_id
JOIN salary_payments ON employee.id = salary_payments.employee_id
WHERE salary_payments.date BETWEEN '2020-06-01' AND '2020-06-30'
GROUP BY department.name
HAVING COUNT(employee.id) > 10;
-- Explanation of the above query in human readable format
--

3-15. 単体テストの作成

コメント「Unit test」を追加して関数を開始するだけで、単体テストを作成できます。

# Python 3
def sum_numbers(a, b):
  return a + b

# Unit test
def

3-16. エラー原因について説明

Codexに、コードのエラー原因を説明してもらうことができます。

/* Explain why the previous function doesn't work. */

3-17. データベース構造と列名の情報を指定

データベース構造と列名の情報を指定することで、Codexが正確なクエリを作成するのに役立ちます。

# Table albums, columns = [AlbumId, Title, ArtistId]
# Table artists, columns = [ArtistId, Name]
# Table media_types, columns = [MediaTypeId, Name]
# Table playlists, columns = [PlaylistId, Name]
# Table playlist_track, columns = [PlaylistId, TrackId]
# Table tracks, columns = [TrackId, Name, AlbumId, MediaTypeId, GenreId, Composer, Milliseconds, Bytes, UnitPrice]

# Create a query for all albums by Adele

3-18. 言語の変換

ある言語から別の言語に変換したい場合は、変換したいコードの言語をコメントにリストし、その後にコードと翻訳したい言語のコメントを記述します。

# Convert this from Python to R
# Python version

[ Python code ]

# End

# R version

3-19. コードを書き直す

関数を書き直したい場合は、書き換えるコードを提供し、その後に使用する形式についての指示を記述します。

// Rewrite this as a React component
var input = document.createElement('input');
input.setAttribute('type', 'text');
document.body.appendChild(input);
var button = document.createElement('button');
button.innerHTML = 'Say Hello';
document.body.appendChild(button);
button.onclick = function() {
  var name = input.value;
  var hello = document.createElement('div');
  hello.innerHTML = 'Hello ' + name;
  document.body.appendChild(hello);
};

// React version:

4. コードの挿入

completionsエンドポイントは、prefix に加えて suffix を指定することで、コード内へのコードの挿入をサポートします。

4-1. ベストプラクティス

ベストプラクティスは、次のとおりです。

◎ max_tokens > 256 を使用
このモデルは、より長い補完コードを挿入するのに適しています。max_tokens が小さすぎると、suffixに接続する前にモデルが切断される可能性があります。

◎ finish_reason == "stop" を優先
モデルが自然な停止点、またはユーザーが指定した stop sequence に到達すると、finish_reason == "stop" が設定されます。これは、モデルが suffix にうまく接続できたことを示しており、完成度の良いシグナルです。

◎ 3~5回リサンプリングする
補完コードは prefix に接続しますが、suffix の接続に苦労する場合があります。その場合は、3〜5回のリサンプリング (または k=3,5 で best_of を使用) して、finish_reason == "stop" でサンプルを選択する手法が効果的です。リサンプリング時は、多様性を高めるために temperatures を高くする必要があります。

【注】 返されたすべてのサンプルが finish_reason == "length" の場合は、max_tokens が小さすぎである可能性が高いです。

5. コードの編集

editsエンドポイント は、コードを完成させるだけでなく、コードを編集するために使用できます。いくつかのコードとその変更方法の指示を指定すると、code-davinci-edit-001モデルがそれに応じて編集を試みます。

5-1. 例

例は、次のとおりです。

◎ 関数を書く
・INPUT

(なし)

・INSTRUCTIONS

Write a function in python that calculates fibonacci

・OUTPUT

def fibonacci(num):
    a = 0
    b = 1
    if num ==1:
       print(a)
    else:
        print(a)
        print(b)
        #the  sequence starts with 0,1
        for i in range(2,num):
            c = a+b
            a = b
            b = c
            print(c)

fibonacci(10)

◎ リファクタリング
・INPUT

    if num ==1:
        print(a)
    else:
        print(a)
        print(b)
        #the  sequence starts with 0,1
        for i in range(2,num):
            c = a+b
            a = b
            b = c
            print(c)

fibonacci(10)

・INSTRUCTIONS

Refactor this function to be recursive

・OUTPUT

def fibonacci(num):
    if num <= 1:
        return num
    else:
        return fib(num-1) + fib(num-2)
print(fibonacci(10))

◎ 関数のリネーム
・INPUT

def fibonacci(num):
    if num <= 1:
        return num
    else:
        return fib(num-1) + fib(num-2)
print(fibonacci(10))

・INSTRUCTIONS

Rename the function to fib

・OUTPUT

def fib(num):
    if num <= 1:
          return num
      else:
        return fib(num-1) + fib(num-2)
print(fib(10))

5-2. ベストプラクティス

ベストプラクティスは、次のとおりです。

(1) 空のプロンプトの使用を検討してください。この場合、編集は補完と同様になります。
(2) 指示はできるだけ具体的に指定してください。
(3) モデルが解を見つけられずエラーになることがあります。その場合は、指示を言い換える必要があります。

次回



この記事が気に入ったらサポートをしてみませんか?