AI を活用したスマート コントラクトは、AI を使用してリアルタイムの Web データにアクセスし、自然言語の指示を解釈して、従来のスマート コントラクトを強化します。
このチュートリアルでは、次の内容を取り上げます。
注:このチュートリアルでは、Python に関するある程度の知識が前提とされており、必要です。
スマート コントラクトは間違いなくゲームチェンジャーです。スマート コントラクトは本質的に自動実行され、契約条件がコードに直接書き込まれます。事前に設定された条件が満たされると、スマート コントラクトはブロックチェーン上に展開され、第三者を必要とせずにトランザクションが安全かつ透過的に処理されることを保証します。
ただし、スマート コントラクトは特定の指示に従うだけであり、予期しない状況やプログラミングに含まれていない複雑な要件には対応できません。時間の経過とともに発生する状況に基づいて学習したり適応したりすることはありません。また、外部データに独立してアクセスすることもできません。外部データをスマート コントラクトに提供して、現実世界のイベントに対応できるようにするには、Oracle などのサードパーティ サービスが必要です。
GenLayer は、従来のスマート コントラクトの機能をすべて保持しながらも、次の機能も備えたインテリジェント コントラクトを作成することで、スマート コントラクトのこの制限を解決しようとしています。
GPT-4 や LLaMA などの LLM モデルを使用して、自然言語の指示を理解して処理します。
サードパーティのツールを必要とせずに、インターネットからリアルタイム データにアクセスして使用します。
GenLayer は、オプティミスティック デモクラシー コンセンサス メソッドを使用して、インテリジェント コントラクトのトランザクションと操作を検証します。このコンセンサス メソッドの重要な部分は、等価性原則です。等価性原則は、オプティミスティック デモクラシー フレームワーク内で使用される特定のルールまたは基準のセットであり、LLM やリアルタイム Web データによって生成される出力などの非決定論的な出力を処理する際の精度と一貫性を確保します。この先では、等価性原則について、またインテリジェント コントラクトを実行するときにそれがどのように機能するかについて、さらに詳しく説明します。
このブログでは、Web からリアルタイム データを取得し、LLM を使用して処理して試合結果を予測できる、サッカー予測インテリジェント コントラクトの構築方法について説明します。面白そうですよね?
早速始めましょう:)。
契約の構築を始める前に、それを実行する環境を設定する必要があります。GenLayer のシミュレーターは、インテリジェント コントラクトの構築とテストに使用できるインタラクティブなサンドボックスです。設定してみましょう。
ターミナルに移動し、以下をコピーして貼り付け、コンピューターに GenLayer をインストールします。
npm install -g genlayer
インストールが完了したら、init コマンドを実行して開発環境のセットアップ プロセスを開始します。
genlayer init
このコマンドを実行すると、5 つのバリデーターでセットアップが初期化され、優先する LLM プロバイダーを選択するように求められます。
選択できるオプションは 3 つあります。
OpenAI: バリデータを実行するための最速かつ最も信頼性の高いオプション)
Ollama: 無料のオープンソースオプションですが、他のオプションよりもパフォーマンスが遅くなる可能性があります
Heurist: オープンソース AI モデル向け推論プロバイダー
選択すると、GenLayer シミュレーター環境に必要な Docker コンテナーが自動的にダウンロードされ、構成されます。セットアップが完了すると、 http://localhost:8080/で GenLayer シミュレーターにアクセスできるようになります。
それでは、契約書の作成を始めましょう。
シミュレータには、コードを記述するためのコード エディターがあります。
インテリジェント コントラクトは Python で記述されており、Web のやり取りや自然言語処理に必要なデータや文字列操作の処理に最適です。
この予測契約では、 BBCスポーツのウェブサイトからウェブデータを取得し、取得したデータをLLMで処理してどのチームが勝利するかを決定します。これを行うための手順を見てみましょう。
ウォークスルーをスキップしたい場合は、 GitHubのコードを確認し、以下の「コントラクトのデプロイ」セクションに進んでください。
まず、インテリジェント コントラクトに使用するライブラリとモジュールをインポートします。
import json from genvm.base.equivalence_principle import EquivalencePrinciple from genvm.base.icontract import IContract
json
: このモジュールは、データ交換の一般的な形式である JSON データの解析と処理に使用されます。EquivalencePrinciple
: これにより、異なるバリデータ間で結果が一貫して正確であることが保証されます。複数のバリデータからの結果を比較することで、非決定論的な出力の整合性を維持する上で重要な役割を果たします。IContract
: GenLayer 上でインテリジェント コントラクトを作成するための基本クラスで、重要なプロパティと動作を提供します。これにより、コントラクトが GenLayer (GenVM) 環境内でスムーズに統合されることが保証されます。ここで、Intelligent Contract クラス (この場合は Prediction Market IContract
を定義する必要があります。Intelligent Contract コントラクト クラスはIContract
から継承します。IContract からの継承は、コントラクトが GenLayer フレームワーク内で適切に実行されるようにするために必要です。
class PredictionMarket(IContract):
次に、コントラクトの状態を初期化し、必要なパラメータを設定します。このステップは、コントラクトの実行全体で使用される初期条件とプロパティを定義するため、非常に重要です。
class PredictionMarket(IContract): def __init__(self, game_date: str, team1: str, team2: str): self.has_resolved = False self.game_date = game_date self.resolution_url = 'https://www.bbc.com/sport/football/scores-fixtures/' + game_date self.team1 = team1 self.team2 = team2
このコンストラクターでは、次のパラメーターを定義します。
game_date
: ゲームの日付。形式は「YYYY-MM-DD」です。team1
: 試合に参加する最初のチームの名前。team2
: 試合に参加する2番目のチームの名前。has_resolved
: ゲームの結果がすでに解決されているかどうかを示し、冗長な処理を防ぎます。resolution_url
: ゲーム結果を取得できる BBC Sport の Web サイトの URL。
これらのパラメータは契約の初期状態を定義し、ゲームの結果を処理する準備を整えます。
ここで、ゲームの結果を決定するメソッドを追加しましょう。このメソッドは、ゲームの結果がまだ解決されていない場合にのみ、そのゲームの結果を処理することを保証します。
async def resolve(self) -> None: if self.has_resolved: return "Already resolved" final_result = {}
このメソッドは、まずself.has_resolved
を調べて結果がすでに決定されているかどうかを確認します。これにより、冗長な処理が防止され、効率性が確保されます。ゲームがまだ解決されていない場合は、結果を格納するためにfinal_result
を初期化します。この辞書には、ゲームの最終的な検証済み結果が保持されます。
等価性原則は、インテリジェント コントラクトを作成するときに非常に重要です。Web にアクセスしたり、LLM を呼び出したりすると、不整合が発生する可能性があります。前述したように、等価性原則は、非決定論的操作 (Web または LLM 呼び出し) の最終出力を検証するために使用される特定のルールまたは基準のセットです。この原則では、複数の検証者が使用され、1 つの検証者がリーダーとして結果を提案し、他の検証者が定義された基準またはルールに基づいてその結果を検証します。
したがって、契約では、Web からの出力や LLM を使用したプロセスでの不一致を防ぐために、等価性原則を定義する必要があります。
async with EquivalencePrinciple( result=final_result, principle="The score and the winner have to be exactly the same", comparative=True, ) as eq:
私たちの予測コントラクトでは、等価性原則は「スコアと勝者は完全に同じでなければならない」と述べています。バリデーターはこの原則を使用して、自分の結果をリーダーの結果と比較します。結果が等価性原則に従って一致する場合、最終結果が受け入れられます。comparative comparative=True
フラグは、リーダーとバリデーターの両方が同一のタスクを実行し、一貫性を確保するために結果を比較することを示します。
この等価性原理の範囲内で、ゲームに関するWeb データを取得し、 LLM を使用して処理します。
次に、等価性原理ブロック内で、BBC スポーツ ニュース Web サイトの URL から Web ページ コンテンツを取得します。
web_data = await eq.get_webpage(self.resolution_url) print(web_data)
データが取得されたら、LLM で処理して結果を確認し、取得した Web ページから勝利チームを決定します。
取得した Web ページからの情報を処理するために、LLM に送信するプロンプトを作成し、LLM に必要な操作を正確に伝えます。LLM とやり取りする場合、モデルが正確で適切な応答を提供できるように、明確で具体的なプロンプトを作成することが重要です。以下は、作成したプロンプトです。
task = f"""In the following web page, find the winning team in a matchup between the following teams: Team 1: {self.team1} Team 2: {self.team2} Web page content: {web_data} End of web page data. If it says "Kick off [time]" between the names of the two teams, it means the game hasn't started yet. If you fail to extract the score, assume the game is not resolved yet. Respond with the following JSON format: {{ "score": str, // The score with numbers only, eg, "1:2", or "-" if the game is not resolved yet "winner": int, // The number of the winning team, 0 for draw, or -1 if the game is not yet finished }} """ result = await eq.call_llm(task) print(result)
私たちが作成したプロンプトは、LLM に次のことを指示します。
取得したウェブページから優勝チームとスコアを特定する
また、LLM が試合がまだ開始されていないかどうかを確認するための条件も追加しました。2つのチーム名の間に「キックオフ [時間]」というフレーズが表示された場合、試合はまだ開始されていないことを示します。LLM はこのシナリオを認識し、まだ結果を抽出できないことを理解するように指示されます。
また、スコアを抽出できない場合にゲームが解決されていないと LLM が想定するための別の条件も追加しました。これにより、未完了または進行中のゲームが適切に処理されるようになります。
最後に、LLMにJSON形式を使用して応答するよう依頼します。
この詳細なプロンプトはさまざまなシナリオを処理し、LLM が必要な情報を正確かつ一貫して抽出して処理することを保証します。プロンプトが作成されると、 call_llm
メソッドを使用して LLM に送信します。
LLM から結果が取得されると、上で定義された等価性原則に従って確認および検証されます。 「スコアと勝者は完全に同じである必要があります。」等価性原則に従って結果が一致した場合、最終結果が受け入れられます。
eq.set(result)
注:バリデータは、等価性原則ブロックのすべてのステップを検証するのではなく、複雑な検証の必要性を減らし、リソースを節約し、契約の操作を簡素化するために最終結果のみに焦点を当てます。
結果が検証され確定したら、 json.loads()
を使用して結果を解析できます。これにより、結果が簡単に操作および評価できる形式に変換されます。解析された結果から、勝者とスコアを抽出します。
result_json = json.loads(final_result['output']) if result_json['winner'] > -1: self.has_resolved = True self.winner = result_json['winner'] self.score = result_json['score'] return result_json
ゲームの結果が決まると (勝者 > -1)、それに応じてコントラクトの状態が更新されます。これにより、最終結果が正確に記録されます。
これで、契約をデプロイする準備が整いました。
契約が実際にどのように機能するかを見てみましょう。
GenLayer シミュレーターで、再生ボタンをクリックして契約を実行します。
コンストラクター パラメーター セクションで、ゲームの日付と確認する 2 つのチームの名前を指定します。たとえば、 game_date
を「2024-06-05」、 team1
を「Brazil」、 team2
を「Jamaica」に設定します。
ゲームの詳細が設定されたら、「デプロイ」をクリックします。
デプロイされたコントラクトとやり取りするには、 「トランザクションの実行」セクションに移動します。ここで、resolve メソッドを呼び出してゲームの結果を処理できます。
解決メソッドが実行されると、次のようになります。
このプロセスにより、ネットワーク全体の一貫性と正確性が確保されます。バリデーターがジャマイカ (チーム 2) の勝者として「1:3」を返し、リーダーがジャマイカ (チーム 2) の「1:2」を返した場合、バリデーターは結果を拒否します。
ログを表示して、契約のやり取りに関する詳細情報を確認します。
🙌 最後まで読んでくださった方、おめでとうございます!!!
AI を活用したスマート コントラクトの将来は明るいようです。サッカー予測コントラクト以外にも、GenLayer シミュレーターで構築してテストできるインテリジェント コントラクトのアイデアは他にもあります。
GenLayer ドキュメントには、上記のいくつかを実現する方法についてのさらに多くの例のアイデアも記載されています。