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

การเขียนคำสืบค้นใหม่และ HyDE

ปรับปรุงความครอบคลุมของการดึงข้อมูล

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

คำค้นคือจุดอ่อนที่สุด

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

นี่เป็นหนึ่งในการปรับปรุงที่มีต้นทุนต่ำแต่ให้ผลคุ้มค่าสูงที่สุดเมื่อเทียบกับ RAG แบบพื้นฐาน เพียงแก้คำค้น ทุกขั้นตอนถัดไปก็ได้รับประโยชน์

def transform_query(raw, history):
    # Resolve references, expand, decompose, or hypothesize
    # BEFORE embedding and retrieving.
    return rewrite(raw, history)

การเขียนคำค้นใหม่

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

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

def rewrite_query(raw):
    prompt = (
        'Rewrite the user question into a clear, standalone search '
        'query optimized for document retrieval. Keep key entities.\n'
        'Question: ' + raw
    )
    return llm(prompt, temperature=0).strip()

การย่อบทสนทนา

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

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

def condense(history, follow_up):
    prompt = (
        'Given the conversation, rewrite the follow-up as a standalone '
        'question with all references resolved.\nConversation:\n' +
        render(history) + '\nFollow-up: ' + follow_up
    )
    return llm(prompt, temperature=0).strip()

การขยายคำค้น

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

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

def expand(query, n=3):
    prompt = (
        'List ' + str(n) + ' alternative phrasings of this query using '
        'synonyms and domain terms, one per line.\n' + query
    )
    variants = parse_lines(llm(prompt, temperature=0.5))
    return [query] + variants

การเรียกคืนด้วยหลายคำค้น

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

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

def multi_query(raw, n=4):
    queries = expand(raw, n)
    rankings = [dense_retrieve(q, 30) for q in queries]
    fused = rrf(*rankings)
    return dedup(fused)

การแยกคำถาม

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

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

def decompose_and_retrieve(question):
    subs = parse_lines(llm(
        'Break this into independent sub-questions, one per line.\n' +
        question, temperature=0))
    evidence = {s: rerank(s, dense_retrieve(s, 30))[:3] for s in subs}
    return evidence  # generator synthesizes the final answer

HyDE: แนวคิดหลัก

HyDE (เวกเตอร์ฝังเอกสารสมมติ, Gao และคณะ, 2022) พลิกวิธีคิดของปัญหานี้ แทนที่จะสร้างเวกเตอร์ฝังจากคำค้นสั้น ๆ ระบบจะให้ LLM สร้างเอกสารคำตอบสมมติ จากนั้นสร้างเวกเตอร์ฝังจากเอกสารนั้นและใช้เอกสารนั้นในการเรียกคืน

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

def hyde(query):
    hypo = llm(
        'Write a short passage that would answer this question, as if '
        'from a reference document.\nQuestion: ' + query,
        temperature=0.3)
    return dense_retrieve_by_vector(embed(hypo), k=30)  # embed the answer

เหตุใด HyDE จึงเพิ่มความครอบคลุม

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

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

# Robustness: average several hypothetical docs to reduce variance
def hyde_avg(query, n=3):
    vecs = [embed(llm(HYDE_PROMPT + query, temperature=0.5))
            for _ in range(n)]
    centroid = sum(vecs) / n
    return dense_retrieve_by_vector(centroid, 30)

ข้อแลกเปลี่ยนและรูปแบบความล้มเหลวของ HyDE

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

ลดผลกระทบด้วยการผสานการเรียกคืนจากเวกเตอร์ HyDE กับการเรียกคืนจากคำค้นดิบผ่านการผสานผลลัพธ์ เพื่อไม่ให้เอกสารสมมติที่ไม่ดีเพียงฉบับเดียวทำลายความครอบคลุมทั้งหมด

def hyde_hybrid(query):
    a = dense_retrieve_by_vector(embed(hyde_doc(query)), 30)
    b = dense_retrieve(query, 30)          # raw-query fallback
    return dedup(rrf(a, b))                 # robust to bad hypotheticals

การเลือกและผสานเทคนิค

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

การแปลงแต่ละขั้นที่เพิ่มเข้ามาต้องใช้การเรียก LLM เพิ่มหนึ่งครั้ง จึงควรเลือกใช้ตามประเภทคำค้น แทนที่จะทำทุกขั้นตอนเสมอ

def route_transform(query, history, qtype):
    q = condense(history, query) if history else query
    if qtype == 'multi_hop': return decompose_and_retrieve(q)
    if qtype == 'mismatch':  return hyde_hybrid(q)
    if qtype == 'vocab_gap': return multi_query(q)
    return dense_retrieve(q, 30)

การประเมินการแปลง

ประเมินการแปลงแต่ละรายการจากการเพิ่มขึ้นของ อัตราการเรียกคืน@k ในการค้นคืน และความแม่นยำของคำตอบเมื่อเทียบกับคำค้นดิบ โดยใช้ชุดข้อมูลที่ไม่มีการรั่วไหล ติดตามเวลาแฝงที่เพิ่มขึ้นและค่าใช้จ่ายของ LLM เพื่อเก็บไว้เฉพาะการแปลงที่ให้ผลคุ้มค่า

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

def eval_transform(name, fn, eval_set):
    return {
        'recall@10': recall_at_k(eval_set, retriever=fn, k=10),
        'answer_acc': answer_accuracy(eval_set, retriever=fn),
        'extra_latency_ms': transform_latency(fn),
    }

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

พิจารณาเหตุผลว่าเหตุใด HyDE จึงทำงานได้ แม้สมมติฐานจะไม่สมบูรณ์

ทบทวน

ประเด็นสำคัญที่ได้เรียนรู้:

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

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

บทเรียน “การเขียนคำสืบค้นใหม่และ HyDE” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเขียนคำสืบค้นใหม่และ HyDE” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Prompt Engineering ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Prompt Engineering มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเขียนคำสืบค้นใหม่และ HyDE”

ปรับปรุงความครอบคลุมของการดึงข้อมูล คุณปฏิบัติ AI Prompt Engineering ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Prompt Engineering หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Prompt Engineering บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การเขียนคำสืบค้นใหม่และ HyDE” ใช้เวลานานแค่ไหน

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

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

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

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

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