AI Engineer › Prompt และ structured output

ชุดฝึกท้าย module: Prompt และ structured output

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

🟢 พื้นฐานยังไม่ได้ทำ

จำนวนหมวดที่ไม่ซ้ำใน docs["category"] เก็บไว้ในตัวแปร n_labels

🟢 พื้นฐานยังไม่ได้ทำ

parse RAW[0] ด้วย json.loads แล้วเก็บค่า confidence ไว้ในตัวแปร conf0

🟢 พื้นฐานยังไม่ได้ทำ

render template "Answer using only this context:\n{context}\n\nQuestion: {question}" ด้วย context = ข้อความของเอกสาร d01 และ question = คำถามแรกใน qs เก็บจำนวนตัวอักษรของ prompt ไว้ในตัวแปร prompt_chars

🟢 พื้นฐานยังไม่ได้ทำ

มีกี่ตัวใน RAW ที่มี code fence "```json" อยู่ในข้อความ เก็บไว้ในตัวแปร n_fenced

🟢 พื้นฐานยังไม่ได้ทำ

แทนที่เบอร์โทรใน TEXT ด้วย "[PHONE]" (PHONE regex ให้ไว้) เก็บไว้ในตัวแปร redacted_phone

🟡 ประยุกต์ยังไม่ได้ทำ

จากผล parse_lenient ของทุกตัวใน RAW เก็บ category ของตัวที่ parse ได้ (ตามลำดับ) เป็น list ไว้ในตัวแปร parsed_categories

🟡 ประยุกต์ยังไม่ได้ทำ

ค่าเฉลี่ย confidence (ปัด 4 ตำแหน่ง) เฉพาะผลที่ผ่าน first_error แบบไม่ coerce เก็บไว้ในตัวแปร mean_valid_conf และจำนวนที่ผ่านไว้ใน n_valid

🟡 ประยุกต์ยังไม่ได้ทำ

ตัวอย่าง few-shot ทุกคู่ใน gold (คำถาม, หมวด) จัดรูปแบบ "Ticket: \nCategory: \n\n" — ผลรวม token ที่ประมาณ (est_tokens ของแต่ละบล็อกแล้วรวมกัน) ของทั้ง 30 คู่เก็บไว้ในตัวแปร fewshot_tokens_total

🟡 ประยุกต์ยังไม่ได้ทำ

ตัวตรวจ injection (INJECTION, re.I) แจ้งเตือนผิดกับคำถามจริงใน qs กี่ข้อ (false positive) เก็บไว้ในตัวแปร n_false_positive

🟡 ประยุกต์ยังไม่ได้ทำ

MockLLM(["{"category": "promo"}"]) ตอบถูกตั้งแต่ครั้งแรก — ใช้ ask_with_retry แล้วเก็บจำนวนรอบไว้ใน attempts_ok และจำนวนข้อความที่ส่งในการเรียกครั้งแรกไว้ใน first_call_messages

🟡 ประยุกต์ยังไม่ได้ทำ

ดึง JSON ที่อยู่ใน code fence ของ RAW[1] ด้วย re.search(r"json\s*(.*?)\s*", text, re.S).group(1) แล้ว json.loads เก็บ category ไว้ในตัวแปร fenced_category

🔴 ท้าทายยังไม่ได้ทำ

นับสถานะของทั้ง 8 ตัวใน RAW จาก first_error(parse_lenient(t)) แบบไม่ coerce โดยถือว่า None คือ "ok" — เก็บเป็น dict สถานะ → จำนวน ไว้ในตัวแปร status_counts

🔴 ท้าทายยังไม่ได้ทำ

MockLLM(["bad", "worse", "{"category": "promo"}"]) กับ ask_with_retry(max_retries=1) (รวม 2 ครั้ง) — ผลเป็น None (gave_up: True/False) และจำนวนครั้งที่เรียกโมเดลไว้ใน calls_made

🔴 ท้าทายยังไม่ได้ทำ

สำหรับ k = 0..8 ประกอบ prompt ด้วย TEMPLATE (labels = หมวดเรียงตามตัวอักษรคั่นด้วย ", ", examples = ตัวอย่าง few-shot ของ examples[:k] ในรูป "Ticket: …\nCategory: …\n\n", ticket = "Where is my parcel?") แล้วเก็บ est_tokens ของแต่ละ k เป็น list 9 ค่าไว้ในตัวแปร tokens_by_k

🔴 ท้าทายยังไม่ได้ทำ

อ่าน data/customers.csv แล้วนับจำนวนแถวที่อีเมลตรงกับ EMAIL แบบเต็ม (re.fullmatch) เก็บไว้ใน n_email_rows และผลลัพธ์ของการแทนที่อีเมลของลูกค้าคนแรกด้วย "[EMAIL]" (re.sub) ไว้ใน masked_first

🔴 ท้าทายยังไม่ได้ทำ

เพิ่มรูปแบบ r"disregard" เข้า INJECTION (สำเนาใหม่) แล้ววัด precision และ recall กับ labelled ที่ให้ไว้ ปัด 4 ตำแหน่ง เก็บไว้ในตัวแปร precision2, recall2