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

การจัดอันดับชิ้นส่วนข้อมูลที่ดึงมาใหม่

การจัดอันดับใหม่ด้วยตัวเข้ารหัสไขว้

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

เหตุใดจึงต้องจัดอันดับใหม่

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

รูปแบบการค้นคืนให้กว้างก่อนแล้วจึงจัดอันดับใหม่อย่างแม่นยำนี้เป็นแกนหลักของ RAG ขั้นสูง

def two_stage(query, k_retrieve=50, k_final=5):
    candidates = first_stage_retrieve(query, k_retrieve)  # high recall
    reranked = rerank(query, candidates)                  # high precision
    return reranked[:k_final]

ตัวเข้ารหัสแบบคู่เทียบกับตัวเข้ารหัสแบบข้าม

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

ตัวเข้ารหัสแบบข้ามมีความแม่นยำสูงกว่ามาก แต่ไม่สามารถคำนวณล่วงหน้าได้ จึงทำงานเฉพาะกับรายการคัดสั้นเท่านั้น

# Bi-encoder: score = cos(enc(q), enc(d))     -> precomputable
# Cross-encoder: score = model(q, d) -> 0..1   -> per-pair, no index
def cross_encode(query, doc):
    return cross_encoder.predict([(query, doc)])[0]  # joint attention

การจัดอันดับใหม่ด้วยตัวเข้ารหัสแบบข้าม

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

โดยทั่วไปขั้นตอนนี้เพิ่มความแม่นยำของคำตอบได้มากกว่าการปรับปรุง RAG รายการเดียวอื่น ๆ

def rerank(query, candidates):
    pairs = [(query, c.text) for c in candidates]
    scores = cross_encoder.predict(pairs)        # batched
    for c, s in zip(candidates, scores):
        c.rerank_score = s
    return sorted(candidates, key=lambda c: c.rerank_score, reverse=True)

LLM ในบทบาทตัวจัดอันดับใหม่

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

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

def llm_listwise(query, candidates):
    passages = '\n'.join(
        '[' + str(i) + '] ' + c.text for i, c in enumerate(candidates)
    )
    prompt = (
        'Rank the passages by relevance to the query. '
        'Return only IDs, most relevant first.\nQuery: ' + query +
        '\n' + passages
    )
    order = parse_ids(llm(prompt, temperature=0))
    return [candidates[i] for i in order]

เวลาแฝงกับขนาดรายการคัดสั้น

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

โปรดจัดกลุ่มการให้คะแนนเป็นคู่และเรียกใช้บนฮาร์ดแวร์เร่งความเร็ว เนื่องจากตัวเข้ารหัสไขว้สามารถประมวลผลคู่ต่าง ๆ แบบขนานได้ดี

def tune_shortlist(eval_set, ks=(20, 50, 100, 200)):
    # find smallest k where recall@k saturates -> rerank fewer pairs
    return {k: (recall_at_k(eval_set, k), rerank_latency(k)) for k in ks}

ขั้นแรกแบบไฮบริดร่วมกับการจัดอันดับใหม่

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

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

def hybrid_then_rerank(query, k_final=6):
    dense = dense_retrieve(query, 50)
    sparse = bm25_retrieve(query, 50)
    fused = dedup(rrf(dense, sparse))     # reciprocal rank fusion
    return rerank(query, fused)[:k_final]

เกณฑ์คะแนนและจุดตัด

คะแนนของตัวจัดอันดับใหม่สามารถปรับเทียบได้ แทนที่จะเลือก n อันดับแรกเสมอ ให้ใช้ เกณฑ์ความเกี่ยวข้อง: เก็บชิ้นส่วนที่มีคะแนนสูงกว่าเกณฑ์ และหากไม่มีชิ้นส่วนใดผ่านเกณฑ์ ให้ส่งคืนคำตอบอย่างตรงไปตรงมาว่าไม่มีคำตอบ วิธีนี้ป้องกันการยัดข้อมูลเติมที่มีความเกี่ยวข้องต่ำลงในพรอมต์

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

def threshold_select(reranked, tau=0.3, max_n=8):
    kept = [c for c in reranked if c.rerank_score >= tau][:max_n]
    if not kept:
        return None        # signal: no sufficiently relevant context
    return kept

ความหลากหลายหลังการจัดอันดับใหม่

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

เรื่องนี้สำคัญสำหรับคำถามแบบหลายขั้น ซึ่งคำตอบครอบคลุมเอกสารหลายฉบับ

def diversify(reranked, max_per_doc=2, k=6):
    out, per_doc = [], {}
    for c in reranked:
        d = c.meta['doc_id']
        if per_doc.get(d, 0) < max_per_doc:
            out.append(c)
            per_doc[d] = per_doc.get(d, 0) + 1
        if len(out) == k:
            break
    return out

การจัดลำดับสำหรับตัวสร้างผลลัพธ์

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

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

def order_for_llm(chunks):
    chunks = sorted(chunks, key=lambda c: c.rerank_score)  # ascending
    return chunks                 # most relevant chunk ends up last,
                                  # nearest the trailing question

การประเมินตัวจัดอันดับใหม่

วัดผลตัวจัดอันดับใหม่ด้วยเมตริกการจัดอันดับ โดยใช้ NDCG และ MRR เป็นหลัก กับความเกี่ยวข้องระหว่างคำค้นกับชิ้นส่วนที่มีป้ายกำกับ จากนั้นวัด ความถูกต้องของ answer ในขั้นตอนปลายทางด้วย ตัวจัดอันดับใหม่ที่ทำให้ NDCG ดีขึ้นแต่ไม่ทำให้คำตอบดีขึ้น อาจเพียงจัดลำดับชิ้นส่วนใหม่ในแบบที่ตัวสร้างผลลัพธ์จัดการไว้แล้ว

ตรวจสอบคุณภาพของงานปลายทางให้ครบวงจรเสมอ ไม่ใช่ดูแค่เมตริกการจัดอันดับ

import math

def ndcg_at_k(relevances, k):
    dcg = sum(r / math.log2(i + 2) for i, r in enumerate(relevances[:k]))
    ideal = sorted(relevances, reverse=True)
    idcg = sum(r / math.log2(i + 2) for i, r in enumerate(ideal[:k]))
    return dcg / idcg if idcg else 0.0

pipeline การจัดอันดับใหม่สำหรับใช้งานจริง

ตั้งแต่ต้นจนจบ: ค้นหาแบบไฮบริดเพื่อสร้างรายการสั้นที่มีผู้สมัคร 50 รายการ ตัดรายการซ้ำ จัดอันดับใหม่ด้วยตัวเข้ารหัสไขว้ ใช้เกณฑ์คะแนน สร้างความหลากหลายตามเอกสาร จัดลำดับเพื่อกลไกความสนใจ และสร้างผลลัพธ์พร้อมการอ้างอิง ใช้เกณฑ์เป็นเงื่อนไขเพื่อส่งคืนคำตอบอย่างตรงไปตรงมาว่าไม่มีคำตอบ

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

def pipeline(query):
    shortlist = hybrid_then_rerank(query, k_final=20)
    kept = threshold_select(shortlist, tau=0.3, max_n=8)
    if kept is None:
        return 'No relevant information found.'
    ctx = order_for_llm(diversify(kept))
    return generate_with_citations(query, ctx)

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

เลือกสถาปัตยกรรมการจัดอันดับใหม่ที่เหมาะสม

สรุปทบทวน

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

  • เรียกคืนข้อมูลให้ครอบคลุมเพื่อให้ได้ความครอบคลุมสูง แล้วจัดอันดับรายการสั้นใหม่เพื่อเพิ่มความแม่นยำ
  • ตัวเข้ารหัสไขว้ให้คะแนนคู่คำค้นกับเอกสารร่วมกัน (แม่นยำแต่จัดทำดัชนีไม่ได้) ส่วนตัวเข้ารหัสแบบสองทางทำงานเร็วแต่หยาบกว่า
  • การจัดอันดับใหม่แบบรายการหรือแบบรายรายการด้วย LLM เป็นทางเลือกสำรอง ควรระวังอคติจากตำแหน่งและการแยกวิเคราะห์
  • ปรับขนาดรายการสั้นให้ความครอบคลุมอิ่มตัวภายในงบประมาณเวลาแฝง และผสานกับการเรียกคืนแบบไฮบริดในขั้นแรก
  • ใช้เกณฑ์คะแนน สร้างความหลากหลายตามเอกสาร จัดลำดับชิ้นส่วนเพื่อกลไกความสนใจ และประเมินด้วย NDCG ร่วมกับความถูกต้องของ answer ในขั้นตอนปลายทาง

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

บทเรียน “การจัดอันดับชิ้นส่วนข้อมูลที่ดึงมาใหม่” ฟรีหรือไม่

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

บทเรียน “การจัดอันดับชิ้นส่วนข้อมูลที่ดึงมาใหม่” ใช้เวลานานแค่ไหน

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

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

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

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

  1. ก้าวข้าม RAG แบบพื้นฐาน
  2. การจัดอันดับชิ้นส่วนข้อมูลที่ดึงมาใหม่
  3. การบีบอัดบริบท
  4. การเขียนคำสืบค้นใหม่และ HyDE
← กลับไปที่ AI Prompt Engineering