0Pricing
AI Prompt Engineering · 课时

提示词注册表架构

将提示词作为带有元数据和标签的版本化制品存储。

提示词注册表架构 是 CoddyKit 上的免费 AI Prompt Engineering 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Prompt Engineering 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Prompt Engineering 课程共包含 4 节课。

为什么需要提示词注册表?

没有注册表时,提示词会分散在代码、配置文件和开发者的记忆中。提示词注册表是一个集中式存储,它将每个提示词视为可版本控制、可追踪的制品——就像软件代码一样。

它的优势包括可复现性、可审计性、rollback 能力以及团队协作。

提示词制品的核心字段

每个提示词制品都应包含以下字段:

  • prompt_id — 唯一且稳定的标识符(例如 summarize-article)
  • version — 语义版本字符串(例如 2.1.0)
  • template — 包含 {variable} 占位符的实际提示词文本
  • metadata — 作者、标签、目标模型、创建时间、描述

数据库模式设计

提示词注册表的关系模式将提示词及其版本历史存储在不同的表中,从而支持高效查询和审计。

-- 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]}

元数据深入解析

丰富的元数据让注册表的用途超越简单存储。关键的元数据字段包括:

  • 作者 — 责任归属和联系对象
  • 标签 — 可搜索的标签,例如 ['production', 'summarization', 'v2']
  • 模型 — 目标模型(提示词可能并不适用于所有模型)
  • 变更日志 — 对变更内容的可读描述
  • 测试套件 — 指向此提示词评估数据集的链接
# 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. ...

激活版本

在生产环境中,同一个提示词同时只能有一个版本处于激活状态。激活操作必须是原子的:停用当前版本、激活新版本——全部在同一个事务中完成,以避免出现空档。

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,以便所有服务(后端、机器学习流程、评估工具)共享同一个事实来源。核心端点包括:

  • 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();

快速检查

在提示词注册表的数据库模式中,哪个字段能确保任意时刻生产环境只提供某个提示词的一个版本?

注册表架构总结

提示词注册表将提示词视为有版本的制品,从而集中管理提示词。关键设计决策包括:

  • 将身份表(提示词 ID)与版本表(版本、模板、元数据)分开
  • 使用单一的 is_active 标志进行原子切换,防止双重激活错误
  • 丰富的元数据(作者、标签、模型、变更日志)支持发现和审计
  • REST API 层让所有服务都能访问注册表
  • 审计日志支持合规和事故调试

基于文件的注册表适合小型团队;对于多团队、高可用的生产系统,建议使用数据库支持的注册表。

常见问题解答

「提示词注册表架构」课时是免费的吗?

是的 — 「提示词注册表架构」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Prompt Engineering 课程的其余内容,请升级到 CoddyKit PRO。 AI Prompt Engineering 课程共包含 4 节课。

「提示词注册表架构」这节课中我会学到什么?

将提示词作为带有元数据和标签的版本化制品存储。 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Prompt Engineering 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Prompt Engineering 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「提示词注册表架构」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Prompt Engineering 课中编写并运行代码吗?

能。每节 AI Prompt Engineering 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 提示词注册表架构
  2. 提示词的版本控制
  3. 部署与回滚策略
  4. 监控生产环境中的提示词表现
← 返回 AI Prompt Engineering