プロンプトレジストリのアーキテクチャ
メタデータとタグを付けたプロンプトを、バージョン管理された成果物として保存します。
「プロンプトレジストリのアーキテクチャ」はCoddyKit上の無料AI Prompt Engineeringレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Prompt Engineering学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Prompt Engineeringコースには全4レッスンが含まれています。
なぜプロンプトレジストリなのか
レジストリがなければ、プロンプトはコードや設定ファイル、開発者の記憶に散在してしまいます。プロンプトレジストリは、すべてのプロンプトをソフトウェアコードと同じように、バージョン管理され追跡可能なアーティファクトとして扱う集中管理ストアです。
メリットには、再現性、監査可能性、ロールバック機能、チームでの共同作業などがあります。
プロンプトアーティファクトの主要フィールド
各プロンプトアーティファクトには、次のフィールドを持たせる必要があります。
prompt_id— 一意で安定した識別子(例:summarize-article)version— セマンティックバージョン文字列(例:2.1.0)template—{variable}プレースホルダーを含む実際のプロンプトテキストmetadata— 作成者、タグ、対象モデル、created_at、説明
データベーススキーマ設計
プロンプトレジストリのリレーショナルスキーマでは、プロンプトとそのバージョン履歴を別々のテーブルに保存することで、効率的な検索と監査を可能にします。
-- prompts table: one row per unique prompt identity
CREATE TABLE prompts (
prompt_id VARCHAR(100) PRIMARY KEY,
description TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- prompt_versions table: one row per versioned artifact
CREATE TABLE prompt_versions (
id SERIAL PRIMARY KEY,
prompt_id VARCHAR(100) REFERENCES prompts(prompt_id),
version VARCHAR(20) NOT NULL,
template TEXT NOT NULL,
author VARCHAR(100),
tags TEXT[],
model VARCHAR(50),
is_active BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(prompt_id, version)
);ファイルベースのレジストリ設計
小規模なチームでは、ファイルベースのレジストリが構造化されたディレクトリ構成を使用します。各プロンプトにフォルダーを割り当て、その中に各バージョンのYAMLまたはJSONファイルを配置します。
# Directory structure
prompts/
summarize-article/
1.0.0.yaml
1.1.0.yaml
latest -> 1.1.0.yaml # symlink
classify-sentiment/
1.0.0.yaml
# Example: summarize-article/1.1.0.yaml
prompt_id: summarize-article
version: '1.1.0'
model: gpt-4o-mini
author: alice@company.com
tags: [summarization, articles, english]
created_at: '2024-06-01T10:00:00Z'
template: |
Summarize the following article in {num_sentences} sentences.
Focus on: {focus_area}.
Article:
{article_text}Python PromptRegistryクラス
シンプルなPythonクラスでデータベースアクセスをラップし、使いやすいメソッドとしてregister()、get_active()、list_versions()を提供します。
import psycopg2
import json
from datetime import datetime
class PromptRegistry:
def __init__(self, dsn):
self.conn = psycopg2.connect(dsn)
def register(self, prompt_id, version, template, author, tags, model):
with self.conn.cursor() as cur:
# Ensure prompt identity exists
cur.execute(
'INSERT INTO prompts (prompt_id) VALUES (%s) ON CONFLICT DO NOTHING',
(prompt_id,)
)
cur.execute(
'''INSERT INTO prompt_versions
(prompt_id, version, template, author, tags, model)
VALUES (%s, %s, %s, %s, %s, %s)''',
(prompt_id, version, template, author, tags, model)
)
self.conn.commit()
print(f'Registered {prompt_id}@{version}')
def get_active(self, prompt_id):
with self.conn.cursor() as cur:
cur.execute(
'SELECT template, version FROM prompt_versions '
'WHERE prompt_id=%s AND is_active=TRUE LIMIT 1',
(prompt_id,)
)
row = cur.fetchone()
if not row:
raise ValueError(f'No active version for {prompt_id}')
return {'template': row[0], 'version': row[1]}メタデータスキーマ詳説
豊富なメタデータがあると、レジストリは単なる保存先にとどまらず役立つものになります。主要なメタデータフィールドは次のとおりです。
- author — 説明責任と連絡先
- tags —
['production', 'summarization', 'v2']のような検索可能なラベル - model — 対象モデル(プロンプトはモデル非依存とは限りません)
- changelog — 何が変更されたかを説明する人間向けの記述
- test_suite — このプロンプトの評価データセットへのリンク
# Extended metadata example
prompt_metadata = {
'prompt_id': 'extract-key-dates',
'version': '2.0.0',
'author': 'bob@company.com',
'tags': ['extraction', 'dates', 'contracts', 'production'],
'model': 'gpt-4o',
'changelog': 'Added support for relative dates (next quarter, end of year)',
'test_suite': 's3://company-evals/extract-key-dates/v2-testset.jsonl',
'created_at': '2024-07-15T09:30:00Z',
'is_active': True
}変数を使ったテンプレートのレンダリング
プロンプトテンプレートではプレースホルダー構文を使用します。レジストリは、実行時の変数をテンプレートに置き換えて最終的なプロンプトを生成します。Pythonのstr.format_map()を使うと、安全かつ簡単に実装できます。
class PromptRegistry:
# ... (previous methods)
def render(self, prompt_id, variables: dict) -> str:
artifact = self.get_active(prompt_id)
template = artifact['template']
try:
rendered = template.format_map(variables)
except KeyError as e:
raise ValueError(f'Missing variable {e} for prompt {prompt_id}')
return rendered
# Usage
registry = PromptRegistry(dsn='postgresql://...')
prompt = registry.render(
'summarize-article',
{
'num_sentences': 3,
'focus_area': 'financial impact',
'article_text': 'Apple reported record revenue of $119B...'
}
)
print(prompt)
# Output: Summarize the following article in 3 sentences.
# Focus on: financial impact. ...バージョンの有効化
本番環境で有効にするプロンプトのバージョンは、一度に1つだけにする必要があります。有効化はアトミックに行い、現在のバージョンを無効化して新しいバージョンを有効化する処理を、空白期間が生じないよう1つのトランザクション内で実行します。
def activate_version(self, prompt_id, version):
with self.conn.cursor() as cur:
# Deactivate all current versions
cur.execute(
'UPDATE prompt_versions SET is_active=FALSE '
'WHERE prompt_id=%s AND is_active=TRUE',
(prompt_id,)
)
# Activate target version
cur.execute(
'UPDATE prompt_versions SET is_active=TRUE '
'WHERE prompt_id=%s AND version=%s',
(prompt_id, version)
)
if cur.rowcount == 0:
self.conn.rollback()
raise ValueError(f'Version {version} not found for {prompt_id}')
self.conn.commit()
print(f'Activated {prompt_id}@{version}')プロンプトの一覧表示と検索
内容を見つけられなければ、レジストリは役に立ちません。タグベースの検索をサポートし、指定したプロンプトのすべてのバージョンを一覧表示できるようにします。
def list_versions(self, prompt_id):
with self.conn.cursor() as cur:
cur.execute(
'SELECT version, author, is_active, created_at '
'FROM prompt_versions WHERE prompt_id=%s '
'ORDER BY created_at DESC',
(prompt_id,)
)
return cur.fetchall()
def search_by_tag(self, tag):
with self.conn.cursor() as cur:
cur.execute(
'SELECT prompt_id, version, tags FROM prompt_versions '
'WHERE %s = ANY(tags)',
(tag,)
)
return cur.fetchall()
# Usage
for v in registry.list_versions('summarize-article'):
print(v) # ('1.1.0', 'alice', True, datetime(...))
for p in registry.search_by_tag('production'):
print(p) # ('summarize-article', '1.1.0', ['production', 'summarization'])レジストリAPIエンドポイント
レジストリをREST APIとして公開し、すべてのサービス(バックエンド、MLパイプライン、評価ツール)が同じ信頼できる情報源を共有できるようにします。主要なエンドポイントは次のとおりです。
POST /prompts/{id}/versions— 新しいバージョンを登録GET /prompts/{id}/active— 有効なテンプレートを取得PUT /prompts/{id}/activate/{version}— バージョンを有効化GET /prompts— メタデータ付きですべてのプロンプトを一覧表示
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
registry = PromptRegistry(dsn='postgresql://user:pass@localhost/prompts')
class VersionPayload(BaseModel):
version: str
template: str
author: str
tags: list
model: str
@app.post('/prompts/{prompt_id}/versions')
def register_version(prompt_id: str, payload: VersionPayload):
registry.register(
prompt_id, payload.version, payload.template,
payload.author, payload.tags, payload.model
)
return {'status': 'registered'}
@app.get('/prompts/{prompt_id}/active')
def get_active(prompt_id: str):
try:
return registry.get_active(prompt_id)
except ValueError as e:
raise HTTPException(404, str(e))
@app.put('/prompts/{prompt_id}/activate/{version}')
def activate(prompt_id: str, version: str):
registry.activate_version(prompt_id, version)
return {'status': 'activated'}監査ログと変更履歴
有効化、無効化、登録の各イベントは、タイムスタンプと実行者とともにすべて記録する必要があります。この監査証跡は、本番インシデントのデバッグやコンプライアンス要件への対応に不可欠です。
CREATE TABLE prompt_audit_log (
id SERIAL PRIMARY KEY,
prompt_id VARCHAR(100),
version VARCHAR(20),
action VARCHAR(50), -- 'registered', 'activated', 'deactivated'
actor VARCHAR(100), -- user or service that performed the action
reason TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- Trigger to auto-log activations
CREATE OR REPLACE FUNCTION log_activation()
RETURNS TRIGGER AS $func$
BEGIN
IF NEW.is_active != OLD.is_active THEN
INSERT INTO prompt_audit_log (prompt_id, version, action)
VALUES (NEW.prompt_id, NEW.version,
CASE WHEN NEW.is_active THEN 'activated' ELSE 'deactivated' END);
END IF;
RETURN NEW;
END;
$func$ LANGUAGE plpgsql;
CREATE TRIGGER trg_activation
AFTER UPDATE ON prompt_versions
FOR EACH ROW EXECUTE FUNCTION log_activation();クイックチェック
プロンプトレジストリのデータベーススキーマで、常に1つのバージョンだけが本番環境で提供されることを保証するフィールドはどれですか?
レジストリアーキテクチャのまとめ
プロンプトレジストリは、プロンプトをバージョン管理されたアーティファクトとして扱うことで、プロンプト管理を一元化します。主な設計上の決定事項は次のとおりです。
- 識別情報テーブル(prompt_id)とバージョンテーブル(version、template、metadata)を分離する
- 単一の
is_activeフラグをアトミックに切り替えることで、複数のバージョンが同時に有効になるバグを防ぐ - 豊富なメタデータ(author、tags、model、changelog)によって、検索と監査をサポートする
- REST API層によって、すべてのサービスからレジストリを利用可能にする
- 監査ログによって、コンプライアンス対応とインシデントのデバッグをサポートする
ファイルベースのレジストリは小規模なチームに適しています。複数チームで利用する高可用性の本番システムでは、DBベースのレジストリが推奨されます。
よくある質問
「プロンプトレジストリのアーキテクチャ」レッスンは無料ですか?
はい。「プロンプトレジストリのアーキテクチャ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Prompt Engineeringコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Prompt Engineeringコースには全4レッスンが含まれています。
「プロンプトレジストリのアーキテクチャ」で何を学びますか?
メタデータとタグを付けたプロンプトを、バージョン管理された成果物として保存します。 ブラウザで直接実行するハンズオンコードでAI Prompt Engineeringを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AI Prompt Engineeringを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAI Prompt Engineeringは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「プロンプトレジストリのアーキテクチャ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAI Prompt Engineeringレッスンでコードを書いて実行できますか?
はい。すべてのAI Prompt Engineeringレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- プロンプトレジストリのアーキテクチャ
- プロンプトのバージョン管理
- デプロイとロールバックの戦略
- 本番環境でのプロンプト性能監視