สถาปัตยกรรมทะเบียนพรอมต์
จัดเก็บพรอมต์เป็นทรัพยากรที่มีเวอร์ชัน พร้อมข้อมูลกำกับและแท็ก
สถาปัตยกรรมทะเบียนพรอมต์ เป็นบทเรียน AI Prompt Engineering ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Prompt Engineering และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Prompt Engineering มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องมีคลัง PromptRegistry
หากไม่มีคลัง พรอมต์จะกระจัดกระจายอยู่ในโค้ด ไฟล์การกำหนดค่า และความทรงจำของนักพัฒนา คลังพรอมต์ คือแหล่งจัดเก็บส่วนกลางที่จัดการพรอมต์แต่ละรายการให้เป็นสิ่งประดิษฐ์ที่มีเวอร์ชันและติดตามได้ — เช่นเดียวกับโค้ดซอฟต์แวร์
ประโยชน์ประกอบด้วยการสร้างผลลัพธ์ซ้ำได้ การตรวจสอบย้อนหลังได้ ความสามารถในการย้อนกลับ และการทำงานร่วมกันเป็นทีม
ฟิลด์หลักของสิ่งประดิษฐ์พรอมต์
สิ่งประดิษฐ์พรอมต์แต่ละรายการควรมีฟิลด์ต่อไปนี้:
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 หรือไฟล์รูปแบบเจสันภายในโฟลเดอร์นั้น
# 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}คลาส PromptRegistry ในไพธอน
คลาสไพธอนแบบง่ายจะห่อหุ้มการเข้าถึงฐานข้อมูลและเปิดเผยเมธอดที่ใช้งานได้ชัดเจน ได้แก่ 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
}การสร้างผลลัพธ์จากแม่แบบด้วยตัวแปร
แม่แบบพรอมต์ใช้รูปแบบตัวแทนค่า คลังจะแทนที่ตัวแปรขณะทำงานลงในแม่แบบเพื่อสร้างพรอมต์สุดท้าย การใช้ 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'])จุดปลายทางส่วนติดต่อของคลัง
เปิดเผยคลังเป็นส่วนติดต่อโปรแกรมประยุกต์แบบเรสต์ เพื่อให้บริการทั้งหมด (บริการส่วนหลัง กระบวนการเรียนรู้ของเครื่องมือประเมิน) ใช้แหล่งข้อมูลหลักเดียวกัน จุดปลายทางหลักมีดังนี้:
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();ตรวจสอบอย่างรวดเร็ว
ในโครงสร้างฐานข้อมูลของคลังพรอมต์ ฟิลด์ใดทำให้มั่นใจได้ว่าจะมีการให้บริการพรอมต์เพียงเวอร์ชันเดียวในระบบจริง ณ เวลาใดเวลาหนึ่ง
สรุปสถาปัตยกรรมคลัง
คลังพรอมต์รวมศูนย์การจัดการพรอมต์โดยจัดการพรอมต์ให้เป็นสิ่งประดิษฐ์ที่มีเวอร์ชัน การตัดสินใจด้านการออกแบบที่สำคัญมีดังนี้:
- แยก ตารางข้อมูลประจำตัว (prompt_id) ออกจาก ตารางเวอร์ชัน (version, template, metadata)
- ใช้แฟล็ก
is_activeเดียวพร้อมการสลับแบบอะตอมิก เพื่อป้องกันข้อผิดพลาดที่มีหลายเวอร์ชันใช้งานอยู่พร้อมกัน - เมทาดาทาที่มีรายละเอียด (ผู้เขียน แท็ก โมเดล บันทึกการเปลี่ยนแปลง) ช่วยให้ค้นหาและตรวจสอบได้
- ชั้นส่วนติดต่อโปรแกรมประยุกต์แบบเรสต์ทำให้บริการทั้งหมดเข้าถึงคลังได้
- บันทึกการตรวจสอบช่วยสนับสนุนการปฏิบัติตามข้อกำหนดและการแก้ไขเหตุขัดข้อง
คลังแบบใช้ไฟล์เหมาะกับทีมขนาดเล็ก ส่วนคลังที่ใช้ฐานข้อมูลเหมาะกว่าสำหรับระบบจริงที่มีหลายทีมและต้องพร้อมใช้งานสูง
คำถามที่พบบ่อย
บทเรียน “สถาปัตยกรรมทะเบียนพรอมต์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “สถาปัตยกรรมทะเบียนพรอมต์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Prompt Engineering ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Prompt Engineering มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “สถาปัตยกรรมทะเบียนพรอมต์”
จัดเก็บพรอมต์เป็นทรัพยากรที่มีเวอร์ชัน พร้อมข้อมูลกำกับและแท็ก คุณปฏิบัติ AI Prompt Engineering ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Prompt Engineering หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Prompt Engineering บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “สถาปัตยกรรมทะเบียนพรอมต์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Prompt Engineering นี้ได้ไหม
ได้ บทเรียน AI Prompt Engineering ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- สถาปัตยกรรมทะเบียนพรอมต์
- การควบคุมเวอร์ชันสำหรับพรอมต์
- กลยุทธ์การนำไปใช้งานและย้อนกลับ
- การตรวจติดตามประสิทธิภาพพรอมต์ในระบบจริง