0Pricing
AI Prompt Engineering · บทเรียน

การเลือกตัวอย่างแบบไม่กี่ตัวอย่างแบบไดนามิก

การดึงตัวอย่างตามแต่ละคำสืบค้น

การเลือกตัวอย่างแบบไม่กี่ตัวอย่างแบบไดนามิก เป็นบทเรียน AI Prompt Engineering ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Prompt Engineering และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Prompt Engineering มีบทเรียนทั้งหมด 4 บทเรียน

จากตัวอย่างสาธิตแบบคงที่สู่แบบไดนามิก

การเรียนรู้แบบใช้ตัวอย่างน้อยที่มีตัวอย่างคงที่จะใช้ตัวอย่างเดิมกับทุกคำค้น ส่วน การเรียนรู้แบบใช้ตัวอย่างน้อยแบบไดนามิกจะค้นคืนตัวอย่างสาธิตที่เกี่ยวข้องที่สุดสำหรับแต่ละคำค้นจากกลุ่มตัวอย่าง แล้วทำให้โมเดลใช้ตัวอย่างที่คล้ายกับข้อมูลนำเข้าปัจจุบัน

นี่คือการเรียนรู้ในบริบทที่เสริมด้วยการค้นคืน ซึ่งเพิ่มความเกี่ยวข้องของตัวอย่างสาธิต อันเป็นปัจจัยสำคัญอย่างหนึ่งต่อคุณภาพของ ICL โดยเฉพาะกับข้อมูลคำขอที่มีความหลากหลาย

class DynamicSelector:
    def __init__(self, pool, embedder, index):
        self.pool = pool          # candidate demonstrations
        self.embed = embedder
        self.index = index        # ANN index over pool embeddings
    def select(self, query, k):
        q = self.embed(query)
        ids = self.index.search(q, k)
        return [self.pool[i] for i in ids]

การสร้างเวกเตอร์ฝังสำหรับกลุ่มตัวอย่างสาธิต

คำนวณเวกเตอร์ฝังล่วงหน้าสำหรับตัวอย่างสาธิตที่เป็นไปได้ทุกตัวอย่าง แล้วจัดเก็บไว้ในดัชนี เพื่อนบ้านใกล้เคียงโดยประมาณ (FAISS, HNSW หรือฐานข้อมูลเวกเตอร์) เมื่อมีคำค้น ให้ใช้ embed กับข้อมูลนำเข้าเพียงครั้งเดียว แล้วค้นคืนรายการที่ตรงกันมากที่สุด

เลือกโมเดลสร้างเวกเตอร์ฝังที่สอดคล้องกับความหมายของงาน โมเดลสร้างเวกเตอร์ฝังทั่วไปอาจจัดกลุ่มตามลักษณะภายนอก แทนที่จะจัดกลุ่มตามมิติที่ใช้ทำนายป้ายกำกับที่ถูกต้อง

import numpy as np

def build_index(pool, embed):
    vecs = np.stack([embed(d.input) for d in pool]).astype('float32')
    vecs /= np.linalg.norm(vecs, axis=1, keepdims=True)  # cosine via dot
    index = HNSW(dim=vecs.shape[1])
    index.add(vecs)
    return index

การป้อนพรอมต์ด้วย kNN

วิธีมาตรฐาน (Liu et al., 2022) จะค้นคืน เพื่อนบ้านที่ใกล้ที่สุดจำนวน k รายการของคำค้นจากกลุ่มข้อมูลที่ติดป้ายกำกับ แล้วใช้เป็นตัวอย่างสาธิต การเลือกโดยอาศัยการค้นคืนมีประสิทธิภาพเหนือกว่าการเลือกแบบสุ่มอย่างสม่ำเสมอ เพราะตัวอย่างสาธิตที่เกี่ยวข้องช่วยระบุตำแหน่งของงานและจัดเตรียมขอบเขตป้ายกำกับที่เหมาะสม

ป้ายกำกับที่ค้นคืนมายังทำหน้าที่เป็นค่าก่อนหน้าของตัวจำแนกแบบ kNN อย่างไม่ตายตัว ซึ่งชักนำโมเดลไปสู่คำตอบของเพื่อนบ้าน

def knn_prompt(query, selector, k, build):
    demos = selector.select(query, k)
    demos = order_by_similarity(embed(query), demos)  # most similar last
    return build(demos, query)

การค้นคืนที่คำนึงถึงความหลากหลาย

การเลือกอันดับต้น ๆ เพียงอย่างเดียวอาจคืนตัวอย่างที่เกือบซ้ำกัน ทำให้ใช้พื้นที่บริบทอย่างสูญเปล่า ให้ใช้ MMR หรือการจัดกลุ่มกับตัวเลือกที่ค้นคืนมา เพื่อรักษาความเกี่ยวข้องและทำให้ตัวอย่างสาธิตที่เลือกครอบคลุมแง่มุมต่าง ๆ ของคำค้น

เรื่องนี้สำคัญที่สุดสำหรับข้อมูลนำเข้าแบบประกอบ ซึ่งแต่ละแง่มุมย่อยที่แตกต่างกันจำเป็นต้องมีตัวอย่างสาธิตที่เป็นตัวแทน

def diverse_retrieve(query, selector, k, pool_n=30, lam=0.7):
    cand = selector.select(query, pool_n)
    q = embed(query)
    return mmr_against_query(cand, q, k, lam)  # relevance + diversity

เวลาแฝงและงบประมาณการค้นคืน

การเลือกแบบไดนามิกเพิ่มการเรียกสร้างเวกเตอร์ฝังและการค้นคืนจากดัชนี ANN ให้กับทุกคำขอ จึงต้องจัดสรรงบประมาณให้เหมาะสม โดยแคชเวกเตอร์ฝังของคำค้นที่เกิดซ้ำ ค้นคืนเป็นชุด และเก็บดัชนีไว้ในหน่วยความจำ

สำหรับระบบที่มี QPS สูง ขั้นตอนการค้นคืนต้องใช้เวลาต่ำกว่าหนึ่งมิลลิวินาที มิฉะนั้นประโยชน์ด้านความเกี่ยวข้องจะถูกหักล้างด้วยเวลาแฝงส่วนท้ายที่เพิ่มขึ้น

from functools import lru_cache

@lru_cache(maxsize=50_000)
def cached_embed(text):
    return embed(text)
# Plus: warm in-RAM HNSW, batched search, async prefetch

ความขัดแย้งระหว่างการแคชกับตัวอย่างสาธิตแบบไดนามิก

ตัวอย่างสาธิตแบบไดนามิกทำลายการแคชคำนำหน้าพรอมต์ เพราะบล็อกตัวอย่างเปลี่ยนไปตามคำค้นแต่ละรายการ วิธีลดผลกระทบคือเก็บ คำนำหน้าที่แคชไว้อย่างคงที่ (คำสั่งและตัวอย่างต้นแบบทั่วไปบางส่วน) แล้วเติมต่อเฉพาะตัวอย่างสาธิตที่ค้นคืนตามคำค้นไว้หลังคำนำหน้านั้น

วิธีนี้ช่วยให้ได้ประโยชน์ด้านการประหยัดจากแคชกลับคืนมาเกือบทั้งหมด พร้อมรักษาความเกี่ยวข้องของส่วนท้ายให้เหมาะกับแต่ละคำค้น

prompt = (
    STATIC_PREAMBLE          # cached: instructions + anchor demos
    + render(diverse_retrieve(query, selector, k))  # dynamic tail
    + format_query(query)
)

การหลีกเลี่ยงการรั่วไหลระหว่างการฝึกและการทดสอบ

หากคำค้นเองอยู่ในกลุ่มตัวอย่าง (ซึ่งพบได้บ่อยระหว่างการประเมิน) การค้นคืนอาจส่งคืนคำตอบที่ตรงกันทุกประการ ทำให้ตัวชี้วัดสูงเกินจริง ระหว่างการประเมินควร ตัดคำค้นออกและตัดเพื่อนบ้านที่เกือบเหมือนกันซึ่งมีค่าความคล้ายคลึงเกินเกณฑ์ออกเสมอ

ในระบบใช้งานจริง ควรกำจัดข้อมูลซ้ำในกลุ่มตัวอย่าง และป้องกันไม่ให้นำข้อมูลนำเข้าก่อนหน้าของผู้ใช้เองกลับมาเป็นตัวอย่างสาธิต

def leak_safe_select(query, selector, k, sim_cap=0.97):
    cand = selector.select(query, k + 5)
    q = embed(query)
    cand = [d for d in cand if cos(q, d.emb) < sim_cap]
    return cand[:k]

การเริ่มต้นแบบเย็นและการขยายกลุ่มตัวอย่าง

ในช่วงแรก กลุ่มตัวอย่างมีขนาดเล็กและการค้นคืนอาจได้รายการที่ตรงกันไม่ดี ให้เริ่มต้นด้วยชุดคงที่ที่คัดสรรแล้ว จากนั้น ขยายกลุ่มตัวอย่างจากร่องรอยในระบบใช้งานจริงที่ผ่านการตรวจสอบ โดยคำนวณเวกเตอร์ฝังและสร้างดัชนีใหม่ตามกำหนดเวลา

ติดตามการใช้งานและผลลัพธ์ของตัวอย่างสาธิตแต่ละรายการ เพื่อให้สามารถตัดตัวอย่างที่มีคุณค่าต่ำหรือล้าสมัยออก และรักษาดัชนีให้มีขนาดกระชับ

def maybe_add_to_pool(trace, verified):
    if verified and novelty(trace, index) > THRESH:
        emb = embed(trace.input)
        index.add(emb)
        pool.append(Demo(trace.input, trace.output, trace.meta))

การเลือกที่ก้าวข้ามความคล้ายคลึง

ความเกี่ยวข้องจากเพื่อนบ้านใกล้เคียงเป็นค่าเริ่มต้นที่ดี แต่ไม่ใช่ทางเลือกที่เหมาะสมที่สุดเสมอไป ตัวเลือกขั้นสูงจะพิจารณา ความสามารถในการให้ข้อมูล (ตัวอย่างสาธิตช่วยคลี่คลายความกำกวมของคำค้นหรือไม่) ความหลากหลาย และ ความครอบคลุมของป้ายกำกับ วิธีการบางอย่างเรียนรู้นโยบายการเลือกที่เพิ่มความแม่นยำในขั้นปลายให้สูงสุด แทนที่จะเพิ่มความคล้ายคลึงดิบให้สูงสุด

ให้มองการเลือกเป็นการเลือกชุดตัวอย่างสาธิตที่ลดความไม่แน่นอนของโมเดลต่อคำค้นนี้ได้มากที่สุด

def select_by_uncertainty_reduction(query, pool, k):
    base = entropy(model_probs(build([], query)))
    gains = []
    for d in pool:
        h = entropy(model_probs(build([d], query)))
        gains.append((d, base - h))   # info gain per demo
    return [d for d, _ in sorted(gains, key=lambda x: -x[1])[:k]]

การประเมินกระบวนการทำงานแบบไดนามิก

เปรียบเทียบระบบแบบไดนามิกกับระบบฐานแบบคงที่และแบบสุ่มบนข้อมูลกันไว้ทดสอบที่ควบคุมการรั่วไหล รายงานความแม่นยำ การกระจายของค่าความคล้ายคลึงจากการค้นคืน เวลาแฝงตั้งแต่ต้นจนจบ และอัตราการพบแคช

ระบบแบบไดนามิกที่ชนะด้านความแม่นยำแต่ทำให้การใช้แคชซ้ำลดลงอย่างมากอาจทำให้ต้นทุนโดยรวมแย่ลง จึงควรประเมินเป้าหมายทั้งหมด ไม่ใช่เฉพาะคุณภาพ

def eval_pipeline(eval_set):
    return {
        'acc_dynamic': run(dynamic, eval_set),
        'acc_static':  run(static, eval_set),
        'acc_random':  run(random_sel, eval_set),
        'p95_latency': latency_p95(),
        'cache_hit':   cache_hit_rate(),
    }

สถาปัตยกรรมอ้างอิง

ตั้งแต่ต้นจนจบ ประกอบด้วยกลุ่มตัวอย่างสาธิตที่ผ่านการตรวจสอบแล้ว โมเดลสร้างเวกเตอร์ฝัง ดัชนี ANN ในหน่วยความจำ ตัวเลือกที่ใช้การป้องกันการรั่วไหล ความหลากหลาย และการจัดลำดับตามความคล้ายคลึง คำนำหน้าที่แคชไว้อย่างคงที่ และวงจรป้อนกลับที่ใช้ขยายและตัดกลุ่มตัวอย่าง

สถาปัตยกรรมนี้เปลี่ยนการป้อนพรอมต์แบบใช้ตัวอย่างน้อยให้เป็นระบบค้นคืนที่มีวินัยด้านการปฏิบัติงานตามที่ระบบลักษณะนี้ต้องการ

def answer(query):
    demos = leak_safe_select(query, selector, k=4)
    demos = mmr_against_query(demos, embed(query), 4)
    demos = order_by_similarity(embed(query), demos)
    prompt = STATIC_PREAMBLE + render(demos) + format_query(query)
    out = llm(prompt)
    log_for_pool_growth(query, out)
    return out

ตรวจสอบอย่างรวดเร็ว

วินิจฉัยผลการประเมินที่ดูแข็งแกร่งเกินจริง

สรุปทบทวน

ประเด็นสำคัญ:

  • การเรียนรู้แบบใช้ตัวอย่างน้อยแบบไดนามิกจะค้นคืนตัวอย่างสาธิตสำหรับแต่ละคำค้น จึงเหนือกว่าวิธีสุ่มและวิธีคงที่ด้วยการเพิ่มความเกี่ยวข้อง
  • สร้างเวกเตอร์ฝังของกลุ่มตัวอย่างลงในดัชนี ANN การป้อนพรอมต์ด้วย kNN เป็นค่าเริ่มต้นที่ดี โดยเรียงตามความคล้ายคลึงจากน้อยไปมาก
  • เพิ่มความหลากหลายด้วย MMR และพิจารณาตัวเลือกที่คำนึงถึงความสามารถในการให้ข้อมูลหรือการลดความไม่แน่นอน
  • ป้องกันการรั่วไหลจากการค้นคืน จัดการเวลาแฝง และเก็บคำนำหน้าคงที่ที่แคชไว้ร่วมกับส่วนท้ายแบบไดนามิก
  • ขยายและตัดกลุ่มตัวอย่างจากร่องรอยที่ผ่านการตรวจสอบแล้ว และประเมินความแม่นยำ เวลาแฝง และอัตราการพบแคชร่วมกัน

คำถามที่พบบ่อย

บทเรียน “การเลือกตัวอย่างแบบไม่กี่ตัวอย่างแบบไดนามิก” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเลือกตัวอย่างแบบไม่กี่ตัวอย่างแบบไดนามิก” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ 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 ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การเลือกตัวอย่างแบบไม่กี่ตัวอย่างแบบไดนามิก” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน AI Prompt Engineering นี้ได้ไหม

ได้ บทเรียน AI Prompt Engineering ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. แบบไม่มีตัวอย่าง ตัวอย่างเดียว และไม่กี่ตัวอย่าง
  2. การออกแบบตัวอย่างที่มีประสิทธิภาพ
  3. ลำดับและความใหม่ของตัวอย่าง
  4. การเลือกตัวอย่างแบบไม่กี่ตัวอย่างแบบไดนามิก
← กลับไปที่ AI Prompt Engineering