1 คะแนน โดย GN⁺ 6 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ในเครื่องมือ edit ของ Pi พบว่า Claude Opus 4.8 และ Sonnet 5 เพิ่มฟิลด์ที่ไม่มีในสคีมาภายใน edits[] ทำให้การเรียกถูกปฏิเสธ และสังเกตเห็นว่าโมเดลรุ่นใหม่กลับทำตามสคีมาเครื่องมือบางแบบได้แย่กว่ารุ่นก่อน
  • การเรียกเครื่องมือคือกระบวนการที่โมเดล สร้างข้อความ ในรูปแบบมาร์กเกอร์พิเศษและ JSON ดังนั้นเมื่อมีการสุ่มตัวอย่างแบบไม่มีข้อจำกัด ธรรมเนียมที่เรียนรู้มาจากการฝึกอาจมาก่อนสคีมา
  • ในกรณีที่ล้มเหลว oldText และ newText เองถูกต้องอยู่แล้ว แต่กลับมี คีย์ปลอม อย่าง requireUnique, oldText2, matchCase, in_file ถูกแนบมาด้วย และอัตราการเกิดซ้ำก็เปลี่ยนไปตามประวัติของเอเจนต์และการมีหรือไม่มี thinking block
  • Claude Code เป็นฮาร์เนสแบบปิด แต่ทำ การแก้ให้หลวม หลายอย่าง เช่น ลองเรียกใหม่เมื่อเรียกผิด, alias ของพารามิเตอร์, ปรับชนิดข้อมูล, กู้คืน Unicode, กรองคีย์ที่ไม่รู้จัก และไม่ได้ใช้โหมด strict
  • การเรียกเครื่องมือแบบ strict ของ Anthropic แก้ปัญหานี้ได้ และถ้าเมื่อโมเดลเก่งขึ้น สคีมาเครื่องมือทางเลือกกลับเสียเปรียบมากขึ้น ฮาร์เนสก็อาจต้องมีการรับประกันที่แข็งแรงกว่าเดิม เช่น ข้อจำกัดทางไวยากรณ์

Regression ที่เกิดขึ้นในเครื่องมือ edit ของ Pi

  • ระหว่างติดตาม Pi issue พบว่าขณะ Claude รุ่นล่าสุดเรียกเครื่องมือ edit ของ Pi จะมีปัญหาเพิ่ม ฟิลด์ที่ไม่มีอยู่จริง เข้าไปในอาร์เรย์ edits[]
  • ปัญหานี้ไม่ได้เกิดกับโมเดลเล็ก แต่เกิดกับ Opus 4.8 และพบพฤติกรรมเดียวกันใน Sonnet 5
  • ในโมเดล Anthropic รุ่นก่อนหน้าไม่เห็นปัญหาเดียวกันนี้ จึงกลายเป็นว่ารุ่นใหม่ที่ประสิทธิภาพสูงกว่ากลับทำงานแย่ลงกับสคีมาเครื่องมือเฉพาะแบบนี้
  • ไม่ได้ทดสอบ Fable เพราะตัวจัดประเภทอาจลดคำขอไปเป็น Opus แบบเงียบ ๆ

การเรียกเครื่องมือใกล้เคียงกับการสร้างข้อความ

  • การเรียกเครื่องมือของ LLM คือวิธีที่โมเดลรับประวัติการสนทนา system prompt และรายการเครื่องมือที่ใช้ได้ แล้วสร้าง รูปแบบการเรียก ภายในพรอมป์ขนาดใหญ่ที่มีมาร์กเกอร์พิเศษรวมอยู่ด้วย
  • อาร์กิวเมนต์ที่ตั้งใจไว้ของเครื่องมือแก้ไขไฟล์อาจมี path และอาร์เรย์ edits แบบนี้
{
  "path": "some/file.py",
  "edits": [
    {
      "oldText": "text to replace",
      "newText": "replacement text"
    }
  ]
}
  • ฮาร์เนสจะตรวจสอบอาร์กิวเมนต์และทำการแก้ไข จากนั้นส่งผลลัพธ์กลับเข้าไปให้โมเดลอีกครั้ง และถ้าตรวจสอบไม่ผ่าน โมเดลจะเห็นข้อผิดพลาดและมักจะลองใหม่
  • รูปแบบภายในของโมเดล Anthropic ไม่ได้เปิดเผยต่อสาธารณะ แต่เคยมี ANTML marker หลุดออกมาหรือปรากฏในช่องทางสื่อสารสาธารณะ
  • รูปแบบนี้ดูคล้าย XML แต่แท้จริงแล้วใกล้เคียงกับ สัญญาณ in-band ที่เหมาะกับการ tokenize และการฝึกมากกว่าจะเป็น XML จริง
    • พารามิเตอร์สตริงระดับบนสุดอาจถูกใส่ inline ได้
    • อาร์เรย์ของอ็อบเจ็กต์ดูเหมือนจะถูกใส่มาในรูปแบบ JSON serialization

การสร้างแบบไม่มีข้อจำกัดและการสร้างแบบมีข้อจำกัดทางไวยากรณ์

  • โดยใหญ่ ๆ แล้วมีสองวิธีที่โมเดลใช้สร้าง structured output
    • ขอให้โมเดลสร้าง JSON ที่ตรงตามสคีมา แล้วค่อยตรวจสอบภายหลัง
    • ให้ sampler ป้องกันตั้งแต่ต้นไม่ให้สุ่ม JSON หรือรูปทรงสคีมาที่ผิดออกมาได้
  • วิธีที่สองเรียกว่า grammar-aware decoding หรือ constrained decoding โดยจะ mask token ที่ละเมิดไวยากรณ์
  • ถ้าสคีมายอมรับแค่ oldText และ newText sampler ก็สามารถกันไม่ให้สร้างคีย์อย่าง "in_file" หรือ "type" ได้
  • หากไม่มีข้อจำกัดแบบนี้ โมเดลจะสร้างตามธรรมเนียมที่มันเรียนรู้มา มากกว่าจะยึดตามสัญญาเชิงนามธรรมอย่างเคร่งครัด

รูปแบบความล้มเหลวที่เกิดขึ้นจริง

  • เครื่องมือ edit ของ Pi ใช้อาร์เรย์ edits เพราะรองรับการแทนที่สตริงที่ตรงกันหลายจุดภายในการเรียกครั้งเดียว
  • ในการเรียกที่ล้มเหลว จะมีฟิลด์ที่ไม่อนุญาตติดมาด้วยแบบนี้
{
  "oldText": "...",
  "newText": "...",
  "requireUnique": true
}
{
  "oldText": "...",
  "newText": "...",
  "oldText2": "",
  "newText2": ""
}
  • คีย์ปลอมที่พบจากการทดลองซ้ำมีหลากหลาย เช่น type, id, kind, unique, requireUnique, matchCase, in_file, forceMatchCount, children, notes, cost, oldText2, newText2, oldText_2, newText_2, event.0.additionalProperties
  • ในการเรียกที่ผิดซึ่งตรวจพบ ค่า payload ของ oldText และ newText จริง ๆ แล้ว ถูกต้องระดับไบต์ แต่มีคีย์ไร้ความหมายถูกต่อท้ายที่ท้ายอ็อบเจ็กต์ ทำให้คำสั่งถูกปฏิเสธ
  • การทำให้เกิดซ้ำขึ้นอยู่กับบริบทอย่างมาก
    • ในพรอมป์แบบ single-turn ใหม่อย่าง “edit this file” จะไม่เกิดซ้ำ
    • แต่จะเกิดซ้ำใน ประวัติเอเจนต์ ที่โมเดลอ่านไฟล์ วินิจฉัยปัญหา แล้วจัดชุดการแก้ไขหลายบรรทัด
    • ต้องมี transcript ของ Petr Baudis จึงจะทำให้เกิดซ้ำได้
    • หากใช้ user session นั้นต่อไป Opus 4.8 จะล้มเหลวด้วยความน่าจะเป็นประมาณ 20%
    • ถ้าลบ thinking block ออกจากประวัติ อัตราความล้มเหลวจะลดลงครึ่งหนึ่ง
    • หากเปิดการเรียกเครื่องมือแบบ strict ปัญหาจะหายไปในการรันนั้น

ทำไมมันถึงแย่ลง

  • สมมติฐานที่หนักแน่นที่สุดคือ นี่ไม่ใช่การเสื่อมแบบสุ่ม แต่เป็น ผลผลิตจากการฝึก
  • โมเดล Anthropic รุ่นก่อนถูกฝึกกับเครื่องมือบางส่วน แต่ยังเป็นช่วงก่อนที่ฮาร์เนสที่ผู้ใช้จัดเตรียมเองอย่าง Claude Code จะกลายเป็นเป้าหมายที่ชัดเจน
  • มีความเป็นไปได้สูงว่าโมเดล Anthropic รุ่นล่าสุดได้รับ post-training โดยมี Claude Code หรือฮาร์เนสที่คล้ายกันมากรวมอยู่ด้วย และในสภาพแวดล้อมนั้นอาจเรียนรู้ทั้งการเรียกเครื่องมือที่สำเร็จและความผิดพลาดที่ยังยอมรับได้
  • เครื่องมือ edit ของ Claude Code มีโครงสร้าง แบบแบน ใกล้กับ file_path, old_string, new_string และ replace_all แบบเลือกได้ มากกว่าจะเป็นโครงสร้าง edits[] แบบซ้อนของ Pi
  • ไคลเอนต์ Claude Code แก้ข้อผิดพลาดได้มากพอสมควร ทั้งลองใช้เครื่องมือใหม่เมื่อใช้ผิด, alias ของพารามิเตอร์, บังคับแปลงชนิด, กู้คืน Unicode และกรองคีย์ที่ไม่รู้จัก
  • หาก reinforcement learning เกิดขึ้นภายในฮาร์เนสแบบนี้หรือการจำลองของมัน การเรียกเครื่องมือที่ผิดเล็กน้อยก็ยังอาจทำงานสำเร็จและได้รับรางวัลได้
  • เมื่อฮาร์เนสอื่นให้เครื่องมือแก้ไขที่มีความหมายเหมือนกันแต่ใช้สคีมาต่างออกไป สำหรับโมเดลแล้วเครื่องมือนั้นอาจค่อย ๆ กลายเป็นเครื่องมือ นอก distribution
  • ตอนเปิดตัว Opus 4.5 โมเดลยังปรับตัวเข้ากับเครื่องมือ edit แบบอื่นได้ดีมาก แต่สิ่งที่สังเกตตอนนี้ชี้ว่าสคีมาเครื่องมือทางเลือกอาจเสียเปรียบในระบบนิเวศเครื่องมือที่ผ่อนปรนแบบเฉพาะบางชุด
  • แม้จะมี text editor tool ที่มีเอกสารกำกับ แต่ Claude Code ไม่ได้ทำตามรูปแบบนั้นตรง ๆ และการทำงานภายในของ Claude Code ก็มองไม่เห็นเพราะเป็นฮาร์เนสแบบปิดซอร์ส

ฮาร์เนสแบบหลวมของ Claude Code

  • Claude Code เป็นซอฟต์แวร์ปิดซอร์ส แต่จากโค้ดที่ย่อมาให้ดูจะเห็นว่ามันผ่อนปรนมากกับข้อมูลขาเข้า
  • มันตรวจว่ามี <invoke markup หลุดออกมาในข้อความที่โมเดลมองเห็นหรือไม่ และถ้ามีก็จะส่ง telemetry แล้วลองเรียกที่ผิดใหม่ด้วย state machine ของตัวเอง
  • มี การกู้คืน Unicode escape สำหรับแก้ลำดับ \uXXXX ที่เสียหายและ lone surrogate ในค่าสตริง
  • ยังมี alias ของพารามิเตอร์ตามชนิดเครื่องมือด้วย
    • Edit ยอมรับ old_str, old_string, new_str, new_string
    • ยอมรับ path เป็น alias ของ file_path
  • คีย์ที่ไม่คาดคิดจะถูกกรองทิ้งแบบเงียบ ๆ
  • ไม่ได้ใช้โหมด strict
    • Anthropic ใช้ข้อจำกัดความซับซ้อนของนิยามเครื่องมือในโหมด strict ซึ่งอาจทำให้คำขอ API ล้มเหลวได้
    • ดูเหมือนว่านี่คือเหตุผลที่ Claude Code ไม่พยายามใช้โหมด strict

โหมด strict และระบบนิเวศอื่น ๆ

  • ทั้งโมเดลและฮาร์เนสของ Anthropic ต่างก็ปิด จึงยากจะบอกได้ว่าปัญหาเดียวกันนี้จะเกิดในฮาร์เนสอื่นด้วยหรือไม่
  • โมเดล Codex ก็เป็นแบบปิด แต่ฮาร์เนสไม่ปิด
  • gpt-oss ถูกฝึกมาอย่างชัดเจนให้ใช้รูปแบบการตอบกลับ harmony ของ OpenAI และมีเอกสารจำนวนมากที่แสดงแนวคิดของ OpenAI
  • harmony ทำให้ channel และ content type ของการเรียกเครื่องมือกลายเป็นส่วนหนึ่งของรูปแบบพรอมป์ และสามารถใส่มาร์กเกอร์อย่าง <|constrain|>json ไว้ใน body ของการเรียกเครื่องมือได้
<|start|>assistant<|channel|>commentary to=functions.get_weather
<|constrain|>json<|message|>{"location":"San Francisco"}<|call|>
  • <|constrain|>json ทำให้ reasoning stack หา boundary ที่ต้องสลับไปใช้การสุ่มแบบมีข้อจำกัด JSON สำหรับ body ของการเรียกเครื่องมือได้ง่าย
  • สำหรับโมเดล GPT ที่โฮสต์ไว้ ยังมีตัวเลือกให้ส่งไวยากรณ์ LARK สำหรับกำหนด grammar ที่เครื่องมือของผู้ใช้ต้องทำตาม
  • ดูเหมือน Anthropic เองก็มีการจัดการคล้ายกันบางส่วนในโหมด strict แต่สำหรับพารามิเตอร์อาร์เรย์แบบซ้อน โมเดลจำเป็นต้องสร้าง JSON ที่ escape แล้วภายใน string literal สำหรับเนื้อหาไฟล์หลายบรรทัดยาว ๆ
  • คีย์ปลอมจะปรากฏหลังจากปิดสตริง newText ที่ยาวหลายร้อยโทเคนทันที ตรง จุดเอนโทรปีสูง ที่โมเดลต้องเลือกระหว่าง } กับ , "..."
  • ดูเหมือน Opus 4.8 และ Sonnet 5 จะมี prior ที่แรงกว่าสำหรับรูปแบบการเรียกเครื่องมือ edit และ prior นั้นใกล้กับสคีมา edit แบบแบนของ Claude Code มากกว่า
  • ที่โหมด strict ของ Anthropic แก้ปัญหาได้ อาจเป็นเพราะฝั่งเซิร์ฟเวอร์ปฏิเสธการสุ่มคีย์ที่ไม่ได้รับอนุญาตตามโครงสร้าง JSON schema
  • ในโมเดล Codex ที่ทดสอบ ไม่พบ regression ประเภทนี้ และไม่ได้รวม 5.6 เพราะไม่มีสิทธิ์เข้าถึง

ผลกระทบต่อการออกแบบฮาร์เนส

  • สำหรับโมเดล Anthropic สคีมาเครื่องมืออาจไม่ใช่สัญญาเชิงนามธรรมที่เป็นกลาง
  • รูปทรงของเครื่องมือบางแบบใกล้กับสิ่งที่เคยเห็นในการ post-training และบางแบบก็ไกลออกไป
  • บางรูปทรงอาจง่ายสำหรับ encoding ที่ซ่อนอยู่ของผู้ให้บริการ แต่บางรูปทรงกลับยาก เพราะต้องเขียนอ็อบเจ็กต์ JSON ขนาดใหญ่ที่ escape ไว้ภายในอาร์เรย์ซ้อนหลังสตริงหลายบรรทัดยาว ๆ
  • แม้โมเดลจะเข้าใจสคีมา แต่ในสถานการณ์ที่มีแรงกดดัน มันก็อาจสุ่มโครงสร้างที่ถูกต้องออกมาไม่สำเร็จ
  • สำหรับ Anthropic ปัญหานี้อาจหายไปได้ถ้าเปิดการสุ่มแบบ strict
  • อย่างไรก็ตาม พฤติกรรมของโมเดลรุ่นล่าสุดแสดงให้เห็นผลกระทบของ reinforcement learning ต่อโมเดล และการพยายามฝืน prior ของฮาร์เนสเฉพาะอาจไม่เป็นผลดีต่อการดึงประสิทธิภาพสูงสุดออกมา
  • Claude Code ไม่ได้เป็นโอเพนซอร์ส และก็ไม่รู้ว่ามันทำอะไรในสภาพแวดล้อม RL ดังนั้นจึงยากจะสมมติว่าพฤติกรรมที่ฝึกให้เข้ากับ Claude Code จะถ่ายโอนมายังเครื่องมืออื่นได้อย่างสะอาด
  • ยิ่งมี post-training เกิดขึ้นมากภายในฮาร์เนสที่ครองตลาดเพียงชุดเดียว ฮาร์เนสอื่นก็ยิ่งต้องรับช่วง ลักษณะแปลกเฉพาะ ของฮาร์เนสนั้นไปด้วย
  • การถอดรหัสแบบมีข้อจำกัดอาจมี trade-off ด้านคุณภาพ แต่ถ้าโมเดลรุ่นใหม่เก่งขึ้นในการแก้งาน ขณะเดียวกันกลับแย่ลงในการปล่อยสคีมาเครื่องมือทางเลือกอย่างซื่อตรง ก็จำเป็นต้องมีการรับประกันที่แข็งแรงขึ้นในบางจุดของฮาร์เนส

1 ความคิดเห็น

 
GN⁺ 6 시간 전
ความคิดเห็นบน Lobste.rs
  • ถ้าสงสัยเกี่ยวกับ Fable เท่าที่เข้าใจ ตอนนี้ Fable จะ แจ้งให้ทราบอย่างชัดเจน เสมอเมื่อมีการดาวน์เกรด
    ผมเองก็เคยโดนตัวจำแนกจับเหมือนกัน ดูเหมือนว่า “ช่วยเรียงบั๊กตามระดับความรุนแรงให้หน่อย” ฟังดูเหมือนงานวิจัยด้านความปลอดภัย

    • ว่าจะลองทดสอบดูสักหน่อย
      รู้ว่าเขาบอกว่าจะไม่ทำลับหลัง แต่ยังไม่ได้ตรวจสอบ กลไก ที่ใช้ในการดาวน์เกรด
  • ถ้าสมมติฐานนี้ถูกต้อง ผลกระทบอาจไปไกลกว่า coding agent
    แอปพลิเคชันใดก็ตามที่พึ่งพา การเรียกใช้เครื่องมือ อย่างเสถียร อาจเจอประสิทธิภาพตกแบบเดียวกันหลังจากโมเดลถูกทำ post-training ให้เข้ากับสภาพแวดล้อมการรันที่ผู้ให้บริการรายหนึ่งชอบเป็นพิเศษ

  • ขอเสริมว่าโพสต์นี้ผมลงด้วยแท็ก ai ไม่ใช่ vibecoding
    ผมเข้าใจยากจริง ๆ ว่าเส้นแบ่งของ vibecoding บนเว็บนี้อยู่ตรงไหน
    โพสต์นี้เกี่ยวข้องกับ LLM พื้นฐาน, reinforcement learning และการสร้างสภาพแวดล้อมการรันรอบ ๆ มันมากกว่าเยอะ
    ถ้าแม้แต่นี่ก็เป็น vibecoding แล้วแท็ก ai ยังเหลือไว้ใช้ตรงไหนกันแน่

    • ที่นี่ vibecoding กลายเป็นเหมือน ตราบาปตัวอักษรสีแดง ขนาดใหญ่ที่แปะให้ทุกอย่างที่แตะ generative AI แม้แต่นิดเดียว หรือดูเหมือนจะเคยแตะ
      ในช่วงไม่กี่สัปดาห์ที่ผ่านมา ตั้งแต่บทความบล็อกแนวอารมณ์ ๆ, README ของโปรเจกต์ใหญ่ที่ห้ามการมีส่วนร่วมจาก LLM ไปจนถึงบทความที่มีประโยคทำนอง “ไม่ใช่ X แต่เป็น Y” มากเกินไป ล้วนถูกติดแท็ก vibecoding กันหมด
      ส่วนตัวผมเลิกสนใจแท็กนั้นไปโดยสิ้นเชิงแล้ว เพราะชุมชนติดกันแบบอัตโนมัติเกินไปจนความหมายจริง ๆ หายไป
      แต่สำหรับบทความนี้โดยเฉพาะ ถ้าจะพูดให้ชัด มันเกี่ยวกับโมเดลที่ถูกใช้กับงานนั้นจริง ๆ ดังนั้นผมเห็นด้วยที่จะติดแท็ก vibecoding
      ขณะเดียวกันก็เห็นด้วยตามเหตุผลที่ชี้ไว้ว่า ai ไม่ควรถูกลบออก ด้วย อยากเพิ่มกลับเข้าไป แต่ไม่รู้ทำไมโพสต์นี้ถึงไม่มีตัวเลือกนั้น
  • ไม่น่าแปลกใจ vendor lock-in น่าจะเป็นส่วนหนึ่งของแผนอยู่แล้ว

    • น่าจะมีเรื่องลดต้นทุนปนอยู่บ้างด้วย ถ้าทุกคนใช้ Claude Code prompt caching ก็จะดีขึ้น
      แนวคิดแบบ “ถ้าคุณจ่ายค่าสมัครสมาชิก Claude และส่งโค้ดทั้งหมดมาให้เราอยู่แล้ว ก็ต้องใช้ UI ฟรีของเราด้วย แม้มันอาจไม่ใช่เครื่องมือผูกมัดที่แข็งแรงพอเมื่อแยกจากโมเดล” นั้นค่อนข้างต่างจากวิธีที่ vendor lock-in แบบเพียว ๆ มักทำงาน
  • มันสมเหตุสมผลที่โมเดลจะทำงานได้ดีที่สุดในสภาพแวดล้อมการรันที่มันถูกฝึกมา นั่นคือสภาพแวดล้อมที่ผู้พัฒนาโมเดลสร้างขึ้น
    ถ้ามีการทำ reinforcement learning อย่างหนักกับ trace แบบ Claude Code ผมก็คาดไว้ว่าในสภาพแวดล้อมการรันที่ไม่ทำงานเหมือน Claude Code มันคงแย่ลงพอสมควร
    ส่วนตัวกลับแปลกใจกว่าที่มันดูเหมือนทำงานได้ค่อนข้างดีแม้ในสภาพแวดล้อมการรันของบุคคลที่สามอย่าง Pi
    การที่บั๊กเกิดขึ้นเฉพาะลึก ๆ ใน trace ของ agent ก็ดูสมเหตุสมผลเช่นกัน
    เมื่อต้นปีนี้ ผมเคยปล้ำกับบั๊กในโมเดล GPT 5.2 และ 5.3 ที่ช่วงท้าย ๆ ของ trace agent พิมพ์ ls -ლა ออกมาแทน ls -la
    ผมจดไว้คร่าว ๆ ที่นี่: https://github.com/openai/codex/issues/7988
    จากประสบการณ์ของผม สิ่งนี้ก็เกิดขึ้นหลังจาก trace ลึกขึ้นแล้วเท่านั้น
    ในบริบทยาว ๆ โมเดลดูเหมือนไม่สามารถ “คิด” ได้อย่างชัดเจน และถอยกลับไปสู่ สัญชาตญาณ แบบดิบ ๆ
    บางที ณ จุดนั้น ความแตกต่างระหว่าง distribution ที่โมเดลถูกฝึกมากับสภาพแวดล้อมการรัน หรือภารกิจที่ผู้ใช้บังคับให้โมเดลทำ อาจส่งผลต่อประสิทธิภาพอย่างรุนแรงที่สุด

    • ปัญหาไม่ใช่การทำ reinforcement learning แล้วมันทำงานได้ดีขึ้นในสภาพแวดล้อมการรันของตัวเอง
      ปัญหาคือทำ reinforcement learning มากเกินไปจนมัน ถดถอย ในสภาพแวดล้อมการรันอื่นเมื่อเทียบกับรีลีสก่อนหน้า
      มาถึงจุดนี้ควรต้องถามแล้วว่า “overfitting แบบอื่น ๆ กำลังเริ่มเกิดขึ้นด้วยหรือเปล่า?”