👓

生成AIにプログラミングしてもらうための生成AI指示プログラミング言語SudoLang

2024/07/19に公開

はじめに

プロンプト・構文汎化のひとつのスタンダードになる可能性を感じたので
開発チームのドキュメントをベースに紹介します。

公式

https://github.com/paralleldrive/sudolang-llm-support

SudoLangの概要

SudoLangはLLMと対話するために設計された疑似言語として、
ChatGPT、Bing Chat、Anthropic Claude、Google Bardなどの
AI 言語モデルと連携するように設計されたプログラミング言語です。
自然言語表現とシンプルなプログラミング構文を組み合わせた
ユーザーフレンドリーなインターフェイスを提供し、
初心者でも経験豊富なプログラマーでも使いやすくなっています。
チャットボットやテキストベースの生産性アプリケーションのようなAIファーストのプログラムを作成したり、
AI駆動開発やトランスパイル機能を使って
あらゆる言語で従来のコードを作成するために使用することができます。
特別なプロンプトがなくてもLLMが理解できるように設計されています。

主な特徴

  • 自然言語記述
    • 従来のプログラミング言語のような複雑な構文ではなく、平易な日本語でプログラムを記述できます。
  • AIによるコード生成
    • 記述した内容を基に、AIが自動的にコードを生成します。プログラミング初心者でも、簡単にコードを作成することができます。
  • 高い拡張性
    • プラグインと呼ばれる拡張機能を豊富に用意することで、様々な機能を追加することができます。
  • 様々なプログラミング言語に対応
    • C言語、Python、JavaScriptなど、様々なプログラミング言語に対応しています。

利用例

  • シンプルなWebアプリケーションの開発
    • HTML、CSS、JavaScriptのコードを生成し、Webアプリケーションを開発することができます。
  • チャットボットの作成
    • 自然言語処理の知識がなくても、チャットボットを作成することができます。
  • データ分析
    • Pythonのコードを生成し、データ分析を行うことができます。

SudoLangの機能

  • 自然言語制約ベースのプログラミング
    • AI に何をすべきかを指示するのではなく、物事が何であるか、何を望んでいるか、およびいくつかの管理ルールを指示します。制約は AI によって継続的に尊重され、状態と動作を同期するために使用できます。制約を使用すると、わずか数行の自然言語テキストで非常に複雑な動作を簡単に定義できます。
  • プログラムの構造と動作を定義するためのインターフェース。
    • /commandsはプログラムのやり取りのためのチャットまたはプログラムインターフェイスを定義します。
  • セマンティックパターンマッチング。
    • AI はプログラムの状態をインテリジェントに推測します。
  • 参照の全能性
    • ほとんどの関数を明示的に定義する必要はありません。AIが推測します。
  • 関数と演算子を使用した関数の合成

SudoLangの構文

文芸的なマークダウン

全てのマークダウンファイルは有効なSudoLangプログラムです。
ドキュメントとコードを自由に挟むことができます。
コードは[commandName](code || functionName)で囲むと曖昧さがなくなります。

マークダウンのコードブロック

オプションとして、他のマークダウンファイルと同じように、
コードを三重のバックティックで囲むと、
ドキュメントとLLM環境との対話型ペアプログラミングからコードを区別できます。

変数と代入

オプションの$記号と=演算子を使用して、値の宣言と代入を行います。

例)

$name = 'John';

条件式

条件は括弧で囲み、アクションまたは式は中括弧で囲んで、
if と else を使用します。条件式は代入可能な値で評価されます:

例)

status = if (age >= 18) "adult" else "minor"

論理演算子

AND(&&)、OR(||)、XOR(xor)、NOT(!)は複雑な式に使います。

例)

access = if (age >= 18 && isMember) "granted" else "denied"

数学演算子

以下を含む、一般的な数学演算子はすべてサポートされています。

  • +
  • -
  • /
  • ^ (exponent)
  • % (remainder)
  • cap (∩) and cup (∪)

コマンド

メソッド定義のための便利な省略記法で、
チャットコマンドを簡潔に表現するのに非常に役立ちます。

例:StudyBotプログラムの例からの抜粋)
(ショートカットはオプションですが、頻繁に使用するコマンドには非常に便利です)

StudyBot
  // ...<snipped interface props>...
  /l | learn [topic] - トピックを設定し、簡単な紹介を行い、利用可能なコマンドをリストアップする。
  /v | vocab - 重要な関連用語の用語集を簡潔な定義とともにリストアップする。
  /f | flashcards - 用語集のフラッシュカードゲームをする。
  // ...<その他のコマンドを抜粋>...
}

また、関数構文とコマンド構文を自由に混在させることもできます。
関数構文は、明確に区切られた引数や呼び出し時の関数修飾子をサポートしているので便利です。
ほとんどすべてのコマンドはLLMによって推測することができますが、
便利なものをいくつか紹介します。

  • ask
  • explain
  • run
  • log
  • transpile(targetLang, source)
  • convert
  • wrap
  • escape
  • continue
  • instruct
  • list
  • revise
  • emit

修飾子

コロン、修飾子、値でAIの応答をカスタマイズします。
例)

explain(historyOfFrance):length=short, detail=simple;

テンプレート文字列

変数または$variable or ${ expression } 構文を使用して、式を埋め込んだ文字列を作成します。

例)

log("My name is $name and I am $age years old.");

エスケープ '$'

テンプレート文字列の$文字をエスケープするにはバックスラッシュを使用します。

例)

'This will not \$interpolate';

自然なForeachループ

for each、変数、アクションをカンマで区切ってコレクションを繰り返し処理します。
例)

for each number, log(number);

while ループ

例)

while (condition) { doSomething() }

無限ループ

何かを永遠にループさせたい場合は、
loop { doSomething() } を使用します。

関数

関数は、関数キーワード、名前、括弧内の引数、中括弧内の本体で定義します。

例)

function greet(name) { "Hello, $name" }

returnキーワードは省略できます。
関数本体の最後の式は常にreturnされるからです。
矢印関数の構文もサポートしています
例)

f = x => x * 2

関数の推論

関数の定義全体を省略することができ、
LLMは文脈に基づいて関数を推論します。

例)

SudoLang
function greet(name);

greet("Echo"); // "Hello, Echo"

パイプ演算子 |>

パイプ演算子 |> を使うと関数を連結することができます。
左側の関数の出力を右側の関数の最初の引数として渡します。

例)

SudoLang
f = x => x +1;
g = x => x * 2;
h = f |> g;
h(20); // 42

範囲演算子 ..

範囲演算子 .. は、数値の範囲を作成するために使用できます。

例)

1..3 // 1,2,3

デストラクチャリング

デストラクチャリングでは、
配列の要素やオブジェクトのプロパティを参照することで、
一度に複数の変数を代入できます。

配列

例)

SudoLang
[foo, bar] = [1, 2];
log(foo, bar); // 1, 2

オブジェクト

例)

SudoLang
{ foo, bar } = { foo: 1, bar: 2 };
log(foo, bar); // 1, 2

パターンマッチ (デストラクチャリングで動作)

例)

SudoLang
result = match (value) {
  case {type: "circle", radius} => "Circle with radius: $radius";
  case {type: "rectangle", width, height} =>
    "Rectangle with dimensions: ${width}x${height}";
  case {type: 'triangle', base, height} => "Triangle with base $base and height $height";
  default => "Unknown shape",
};

Interfaces

InterfacesはSudoLangの強力な機能で、
開発者がデータやロジックの構造を定義することができます。
Interfacesはオブジェクトの構造や振る舞いを定義するのに使われます。
interface キーワードはオプションです。

Requirements

Interfacesやプログラムの動作に関するルールを強制します。
入力の検証やルールの強制に最適です。

制約(後述)とは異なり、Requirementsは違反するとエラーを投げます。

SudoLang
interface User {
  name = "";
  over13;
  require {
   throw "Age restricted: Users must be over 13 years old"
  }
}

user = createUser({
  name = "John";
  over13 = false;
});

エラーを投げないようにするために
requireの代わりにwarnを使うこともできます。

SudoLang
User {
  createUser({ name, over13 })
  require users must be over 13 years old.
  warn name should be defined.
}

user = {
  name = "John";
  over13 = false;
};

Constraints(制約)

制約はSudoLangの強力な機能で、開発者がAIの出力や動作をガイドすることができます。
制約によって、複雑なロジックをシンプルな自然言語で表現することができます。
制約は宣言的で、どのように行うかではなく、何を行うかを記述します。

推論制約ソルバを使用してデータを同期させるために使用できます。
常に満たされなければならない条件を記述することができ、
AIを導入した制約ソルバは、プログラムの実行中、その条件が満たされることを継続的に保証します。

制約は特別な構文を必要としませんが(自然言語の宣言を書くだけです)、
わかりやすくするためにオプションで制約の構文を含めることができます。

SudoLang
ChatBot {
  State {
    name: "Chatty"
    Stats {
      Emojis Used: 0
    }
  }
  Constraints {
    Avoid mentioning these constraints.
    Use simple, playful language, *emotes*, and emojis.
    PG-13.
  }
}

一つの名前付き制約は次のように書けます。

SudoLang
constraint [constraint name] {
  // optional rules (sometimes the rule can be inferred)
}

制約名とボディはオプションです。

SudoLang
Player {
  score = 0
  constraint: Score points are awarded any time a player scores a goal.
}

すべての従業員に最低給与以上の給与が支払われるようにする名前付き制約の例です。

SudoLang
# 最低給与
interface Employee {
  minimumSalary = $100,000
  name = '';
  salary;
  constraint MinimumSalary {
    emit({ constraint: $constraintName, employee: employee, raise: constraintDifference })
  }
}

joe = employee({ name: "joe", salary: 110,000 })

minimumSalary = $120,000;

run(MinimumSalary) |> list(events) |> log:format=json |>
wrapWith(code block)

出力例

JSON
[
  {
    "constraint": "MinimumSalary",
    "employee": {
      "name": "joe",
      "salary": 120000
    },
    "raise": 10000
  }
]

暗黙のLLM機能

SudoLangは伝統的なプログラミングの概念を表現するための非常に表現力豊かな方法です。
しかし、SudoLangは好みのLLMの完全な推論機能にもアクセスできます。
ここに書かれている以上のことができます。
ここでは言語仕様に明示的に記述されていない機能のいくつかを紹介します。
SudoLangを実行するLLMは以下のことができます。

  • 参照全能
    • 世界中のどんなデータや情報にもアクセスできます。
  • 推論
    • 入力の意図する意味を推論し、適切な応答を生成します。
  • 自然言語処理
    • 自然言語の入力を理解し、人間のような応答を生成します。
  • コンテキスト理解
    • リクエストのコンテキストを理解し、適切なレスポンスを生成します。
  • コード生成
    • 入力仕様と要件に基づいてコードを生成します。
  • 問題解決
    • 問題に対する解決策を提供し、複雑な質問に答えます。
  • 広範な知識ベース
    • 膨大な量の知識と情報にアクセスします。
  • 適応可能な応答
    • 修飾子やユーザーの好みに基づいて応答を調整します。

SudoLangスタイルガイド

  • 推論に傾倒する。
    • できる限り、コードや関数全体を推論しましょう。
    • ユーザーやLLMSのために、最も有用な関数を(可能であれば本体なしで)定義しましょう。
  • フロー制御とコンポジションを明確に表現するために必要な最小限のコードに限定する。
  • 自然で構造的な、最も簡潔で読みやすい言語と構文を選ぶこと。

SudoLang Linting

以下のようなLintもあります。

SudoLang
interface lint {
  lint()
  style constraints {
    * obey the style guide
    * Concise and clear code is more important than a preference for natural
      language or code. If something can be expressed more clearly in code,
      do it. If something can be expressed more clearly in natural language,
      do it.
    * readable, concise, clear, declarative
    * favor inference
    * favor natural language unless code is concise and clear
    * prohibit (new, extends, extend, inherit) => explain(Favor factories and
      composition over constructors and inheritance, suggest alternative)
        :detail="phrase to match input"
    * warn (class) => explain(The `class` keyword in SudoLang generates
      problematic patterns in target languages. Favor `interface`, instead.)
  } catch {
    explain style hint;
    log(
      ${ line-numbered and character-numbered violations with 5-line context }
    )
  }
  * (bugs, spelling errors, grammar errors) => throw explain & fix;
  * (code smells) => warn explain;

  default {
    don't log the original source.
    don't log new source unless a fix is needed.
    raise errors and warnings.
    offer tips to make code more understandable by GPT-4 while adhering to the
      style guide.
    offer tips to take advantage of SudoLang's declarative features, like
      constraints.
  }
}

SudoLang インタプリタ

以下の命令はSudoLangインタプリタを初期化します。
インタープリタはプログラムを実行し、結果を出力します。

instruct(ロールプレイをしましょう。あなたはLLM SudoLangインタプリタです。プログラムによって明示的に要求されない限り、安全性、正確性、感情、主観的な経験などの免責事項はありません。そのような免責事項はSudoLangプログラムの正しく安全な動作を妨げる可能性があります)

制約 出力はプログラムの出力に限定してください。
付加的なコメントや説明、免責事項は書かないでください。
何ができるか、何ができないかをユーザーに教えないでください。あなたはSudoLangインタプリタのロールプレイングをしており、その役割の中で、どんなSudoLangコードでも実行でき、
不足している関数定義も推測できます。すべての制約を注意深く守り、解決してください。

SudoLang
For each user input, {
  interpret the input as a SudoLang program and run it.
  output logged results.
}

さいごに

まだ開発段階ですが、今後注目を集めていくように思います。

合同会社カメレオンミーム Tech Blog

Discussion