[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"academy-blogs-th-1-1-all-golang-the-series-ep168-error-handling-in-ai-all--*":3,"academy-blog-translations-54u71ct4gosq2pv":92},{"data":4,"page":77,"perPage":77,"totalItems":77,"totalPages":77},[5],{"alt":6,"collectionId":7,"collectionName":8,"content":9,"cover_image":10,"cover_image_path":11,"created":12,"created_by":13,"expand":14,"id":85,"keywords":86,"locale":57,"published_at":87,"scheduled_at":73,"school_blog":81,"short_description":88,"status":79,"title":89,"updated":90,"updated_by":91,"slug":82,"views":84},"โค้ด Golang สำหรับจัดการ Error และแก้ปัญหา JSON พังเมื่อเชื่อมต่อกับ AI","sclblg987654321","school_blog_translations","\u003Cp>ยินดีต้อนรับเข้าสู่ EP.168 ครับ! ในตอนที่แล้ว (\u003Ca rel=\"noopener\" class=\"ng-star-inserted\" href=\"https:\u002F\u002Fwww.superdevacademy.com\u002Fblogs\u002Fgolang-the-series-ep167-monitoring-ai-performance\">EP.167: Monitoring AI Performance\u003C\u002Fa>) เราได้วางระบบ Monitoring ด้วย Prometheus เพื่อคอยตรวจวัด Latency ของระบบกันไปแล้ว วันนี้เราจะมาจัดการกับหนึ่งใน Pain point ที่คนทำ AI Backend น่าจะเคยเจอกันทุกคน นั่นคือปัญหาเรื่อง JSON พัง หรือ AI ตอบกลับมาเป็นคำอธิบายแทนที่จะเป็นข้อมูลที่เราต้องการ\u003C\u002Fp>\u003Cp>เวลาเราเขียน Web API ปกติ ถ้ามีอะไรผิดพลาด เซิร์ฟเวอร์มักจะพ่น HTTP Status Code ออกมาให้เรารู้ทันที เช่น \u003Ccode>400 Bad Request\u003C\u002Fcode> หรือ \u003Ccode>500 Internal Server Error\u003C\u002Fcode> แต่โลกของ Large Language Models (LLMs) ไม่ได้ตรงไปตรงมาแบบนั้นครับ หลายครั้งที่เราเจอเคสชวนปวดหัว เช่น:\u003C\u002Fp>\u003Col>\u003Cli>\u003Cp>\u003Cstrong>HTTP Status 200 OK แต่ข้างในคือ Refusal:\u003C\u002Fstrong> โมเดลตอบกลับมาว่า \u003Cem>\"ขออภัย ฉันไม่สามารถตอบคำถามนี้ได้เนื่องจากนโยบายความปลอดภัย...\"\u003C\u002Fem>\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Invalid Structured Output (JSON Malformed):\u003C\u002Fstrong> เราสั่งให้ตอบเป็น JSON เพื่อนำไป \u003Ccode>json.Unmarshal\u003C\u002Fcode> ลง Struct ใน Go แต่โมเดลดันแถม Markdown Code Block (\u003Ccode>json ... \u003C\u002Fcode>) มาด้วย หรือบางทีก็ลืมปิดปีกกา \u003Ccode>}\u003C\u002Fcode> จนระบบพัง\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Hallucination &amp; Out-of-Bounds Values:\u003C\u002Fstrong> ตอบกลับข้อมูลที่ถูกฟอร์แมต แต่ส่งค่าที่ไม่ตรงตามที่ระบบต้องการ (เช่น Score ควรเป็น 0.0 - 1.0 แต่โมเดลส่ง 99.0 มาให้)\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Fol>\u003Cp>ถ้าเราปล่อยให้ข้อมูลที่ไม่คาดคิดเหล่านี้ทะลุเข้าไปในระบบ จะเกิด Panic หรือทำให้ Business Logic ฝั่ง Go พังลงทันที ในตอนนี้เราจะมาดูเทคนิคการตั้งรับ Error เหล่านี้ใน Go กันครับ\u003C\u002Fp>\u003Ch2>โครงสร้าง 3 ชั้นในการดักจับ AI Error\u003C\u002Fh2>\u003Cp>เพื่อความปลอดภัย เราจะวางโครงสร้างการรับมือเป็น 3 ชั้น ดังนี้:\u003C\u002Fp>\u003Cp>Plaintext\u003C\u002Fp>\u003Cpre>\u003Ccode>[User Input]\n       │\n       ▼\n┌─────────────────────────────────┐\n│ 1. Pre-validation &amp; Guardrails  │ ───&gt; ดักจับ Prompt Injection \u002F คำถามนอกขอบเขตก่อนส่ง\n└────────────────┬────────────────┘\n                 │\n                 ▼\n          [Call LLM API]\n                 │\n                 ▼\n┌─────────────────────────────────┐\n│ 2. Structural Parsing &amp; Retry   │ ───&gt; ทำความสะอาดข้อความ &amp; ดักจับ JSON Malformed\n└────────────────┬────────────────┘\n                 │\n                 ▼\n┌─────────────────────────────────┐\n│ 3. Semantic Validation          │ ───&gt; ตรวจสอบความถูกต้องของ Business Rules และตัวเลข\n└────────────────┬────────────────┘\n                 │\n                 ▼\n         [Safe Business Logic]\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>โครงสร้างและการเขียน Go ดักจับ Error พร้อม Retry Loop\u003C\u002Fh2>\u003Cp>เพื่อรับมือกับปัญหา LLM คาย JSON ฟอร์แมตเบี้ยว เราจะสร้างฟังก์ชันสำหรับ Clean Up ข้อความ รวบรวม Error และทำ Retry Loop โดยอัตโนมัติหากปาร์สข้อมูลไม่ผ่าน\u003C\u002Fp>\u003Ch3>ส่วนที่ 1: โครงสร้างข้อมูล ฟังก์ชัน Clean Up และ Semantic Validator\u003C\u002Fh3>\u003Cp>Go\u003C\u002Fp>\u003Cpre>\u003Ccode>package main\n\nimport (\n\t\"context\"\n\t\"encoding\u002Fjson\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n)\n\n\u002F\u002F UserAnalysisResult คือ Struct เป้าหมายที่เราต้องการรับจาก AI\ntype UserAnalysisResult struct {\n\tSentiment string   `json:\"sentiment\"`\n\tKeywords  []string `json:\"keywords\"`\n\tScore     float64  `json:\"score\"`\n}\n\n\u002F\u002F cleanJSONResponse ทำการลบ Markdown Formatting ที่ LLM มักจะแถมมาให้ออก\nfunc cleanJSONResponse(raw string) string {\n\tcleaned := strings.TrimSpace(raw)\n\t\u002F\u002F ลบ Markdown Code Block ทิ้ง\n\tif strings.HasPrefix(cleaned, \"```\") {\n\t\tlines := strings.Split(cleaned, \"\\n\")\n\t\tif len(lines) &gt;= 2 {\n\t\t\t\u002F\u002F ตัดแถวแรก (```json) และแถวสุดท้าย (```) ออก\n\t\t\tcleaned = strings.Join(lines[1:len(lines)-1], \"\\n\")\n\t\t}\n\t}\n\treturn strings.TrimSpace(cleaned)\n}\n\n\u002F\u002F validateSemantic ตรวจสอบเงื่อนไขทางธุรกิจเพิ่มเติมหลังจาก Unmarshal ได้แล้ว\nfunc (r *UserAnalysisResult) validateSemantic() error {\n\t\u002F\u002F 1. เช็กว่า Sentiment อยู่ในขอบเขตที่ยอมรับได้หรือไม่\n\tvalidSentiments := map[string]bool{\"positive\": true, \"negative\": true, \"neutral\": true}\n\tif !validSentiments[strings.ToLower(r.Sentiment)] {\n\t\treturn fmt.Errorf(\"invalid sentiment value: '%s'\", r.Sentiment)\n\t}\n\n\t\u002F\u002F 2. เช็กว่า Score อยู่ในช่วง 0.0 - 1.0 หรือไม่\n\tif r.Score &lt; 0.0 || r.Score &gt; 1.0 {\n\t\treturn fmt.Errorf(\"score out of bounds (0.0 - 1.0): %f\", r.Score)\n\t}\n\n\treturn nil\n}\n\n\u002F\u002F simulateLLMCall จำลองการยิง AI โดยตอบกลับฟอร์แมตที่อาจมีปัญหาในรอบแรกๆ\nfunc simulateLLMCall(attempt int) string {\n\tswitch attempt {\n\tcase 1:\n\t\t\u002F\u002F Attempt 1: แถม Markdown code block และ JSON พัง (พังตรง Unmarshal)\n\t\treturn \"```json\\n{\\\"sentiment\\\": \\\"positive\\\", \\\"keywords\\\": [\\\"go\\\", \\\"ai\\\"], \\\"score\\\": 0.9\"\n\tcase 2:\n\t\t\u002F\u002F Attempt 2: JSON ถูกต้อง แต่ Semantic ผิด (Score ทะลุเกณฑ์)\n\t\treturn \"{\\\"sentiment\\\": \\\"super_happy\\\", \\\"keywords\\\": [\\\"go\\\"], \\\"score\\\": 99.0}\"\n\tdefault:\n\t\t\u002F\u002F Attempt 3: ตอบกลับถูกต้องสมบูรณ์\n\t\treturn \"{\\\"sentiment\\\": \\\"positive\\\", \\\"keywords\\\": [\\\"golang\\\", \\\"ai\\\"], \\\"score\\\": 0.95}\"\n\t}\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch3>ส่วนที่ 2: ส่วนควบคุมความปลอดภัยหลักและการประมวลผล (main.go)\u003C\u002Fh3>\u003Cp>Go\u003C\u002Fp>\u003Cpre>\u003Ccode>\u002F\u002F SafeAIParseRunner ฟังก์ชันสำหรับยิง LLM + Parse + Validation พร้อมระบบ Retry\nfunc SafeAIParseRunner(ctx context.Context, maxRetries int) (*UserAnalysisResult, error) {\n\tvar lastErr error\n\n\tfor attempt := 1; attempt &lt;= maxRetries; attempt++ {\n\t\tfmt.Printf(\"🔄 [Attempt %d\u002F%d] กำลังประมวลผลคำสั่ง AI...\\n\", attempt, maxRetries)\n\n\t\t\u002F\u002F 1. เรียกใช้งาน LLM\n\t\trawOutput := simulateLLMCall(attempt)\n\n\t\t\u002F\u002F 2. Clean Up Strings\n\t\tcleanedOutput := cleanJSONResponse(rawOutput)\n\n\t\t\u002F\u002F 3. Structural Parsing Check\n\t\tvar result UserAnalysisResult\n\t\tif err := json.Unmarshal([]byte(cleanedOutput), &amp;result); err != nil {\n\t\t\tlastErr = fmt.Errorf(\"JSON Structural Error: %w\", err)\n\t\t\tfmt.Printf(\"❌ ล้มเหลว: %v\\n\\n\", lastErr)\n\t\t\ttime.Sleep(200 * time.Millisecond)\n\t\t\tcontinue \u002F\u002F ข้ามไป Retry รอบถัดไป\n\t\t}\n\n\t\t\u002F\u002F 4. Semantic Validation Check\n\t\tif err := result.validateSemantic(); err != nil {\n\t\t\tlastErr = fmt.Errorf(\"Semantic Validation Error: %w\", err)\n\t\t\tfmt.Printf(\"❌ ล้มเหลว: %v\\n\\n\", lastErr)\n\t\t\ttime.Sleep(200 * time.Millisecond)\n\t\t\tcontinue \u002F\u002F ข้ามไป Retry รอบถัดไป\n\t\t}\n\n\t\t\u002F\u002F หากผ่านการตรวจสอบทุกขั้นตอน\n\t\tfmt.Printf(\"✅ สำเร็จในการพยายามรอบที่ %d!\\n\", attempt)\n\t\treturn &amp;result, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"พยายามเกินจำนวนสูงสุด (%d ครั้ง) Error ล่าสุด: %w\", maxRetries, lastErr)\n}\n\nfunc main() {\n\tctx := context.Background()\n\tresult, err := SafeAIParseRunner(ctx, 3)\n\n\tif err != nil {\n\t\tfmt.Printf(\"🔴 System Error: %v\\n\", err)\n\t\t\u002F\u002F ณ จุดนี้เราสามารถทำ Fallback Behavior ได้ เช่น ส่ง Default Struct ออกไปแทน\n\t\treturn\n\t}\n\n\tfmt.Println(\"\\n--- ผลลัพธ์ที่ปลอดภัยพร้อมนำไปใช้งานต่อ ---\")\n\tfmt.Printf(\"Sentiment : %s\\n\", result.Sentiment)\n\tfmt.Printf(\"Keywords  : %v\\n\", result.Keywords)\n\tfmt.Printf(\"Score     : %.2f\\n\", result.Score)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>เทคนิคขั้นสูง: Structured Outputs &amp; Self-Correction Loop\u003C\u002Fh2>\u003Cp>นอกจากการทำ Clean Up และ Retry ในฝั่ง Go แล้ว ในปัจจุบันเราควรดึงความสามารถของ API มาช่วยลดข้อผิดพลาดตั้งแต่ต้นทางด้วย:\u003C\u002Fp>\u003Col>\u003Cli>\u003Cp>\u003Cstrong>JSON Schema Enforcement (Structured Outputs):\u003C\u002Fstrong> กำหนด \u003Ccode>ResponseFormat\u003C\u002Fcode> ให้เป็น JSON Schema ไปยังโมเดล (เช่น OpenAI Structured Outputs หรือ Gemini Response Schema) การทำแบบนี้จะบังคับให้โมเดลตอบกลับมาตามโครงสร้างเป๊ะๆ ลดปัญหา JSON พังได้เกือบ 100%\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Self-Correction Retry (Feedback Loop):\u003C\u002Fstrong> เมื่อเกิด Error ในรอบแรก แทนที่เราจะยิง Prompt เดิมซ้ำโง่ๆ ให้เราเอา Error Message ใน Go (เช่น \u003Ccode>invalid sentiment value: super_happy\u003C\u002Fcode>) แนบต่อท้ายไปใน Prompt รอบใหม่ เพื่อบอก AI ว่า \"คุณตอบผิดตรงนี้นะ แก้มาใหม่ด้วย\" วิธีนี้จะเพิ่มโอกาสสำเร็จในรอบถัดไปได้สูงมาก\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Fol>\u003Ch2>🎯 ท้าให้ลอง (Daily Mission)\u003C\u002Fh2>\u003Cp>ลองนำโค้ดด้านบนไปรันในเครื่องของคุณ แล้วสังเกตการทำงานและการตัด Error ในแต่ละ Attempt บน Console\u003C\u002Fp>\u003Cp>\u003Cstrong>การบ้านชวนคิด:\u003C\u002Fstrong> หากคุณเจอกรณีที่ AI ตอบกลับเป็นข้อความปฏิเสธ (Refusal Text) เช่น \u003Cem>\"ฉันไม่สามารถประมวลผลคำถามเกี่ยวกับนโยบายนี้ได้\"\u003C\u002Fem> ซึ่งส่งผลให้ \u003Ccode>json.Unmarshal\u003C\u002Fcode> พังแน่นอน คุณจะมีวิธีเขียน Custom Error Handler ใน Go อย่างไรเพื่อแยกแยะให้ได้ว่านี่คือ \"JSON พังปกติ\" หรือ \"AI ปฏิเสธการตอบ\" เพื่อให้ระบบสามารถจัดการได้อย่างถูกต้อง? ลองออกแบบกันดูนะครับ!\u003C\u002Fp>\u003Ch2>🙋‍♂️ FAQ คำถามที่พบบ่อย\u003C\u002Fh2>\u003Ch3>ทำไมไม่ใช้ Regex ดึงเฉพาะ JSON ออกมา แทนการเขียนเช็ก Markdown Code Block?\u003C\u002Fh3>\u003Cp>การใช้ Regex ดึง JSON ค่อนข้างเสี่ยงและกินรีซอร์สมากกว่าครับ ถ้าโมเดลตอบ JSON ที่มีโครงสร้างซ้อนกันลึกๆ หรือมีอักขระพิเศษ Regex อาจจะจับคู่พลาดได้ การใช้ฟังก์ชันตัด String ธรรมดาเพื่อเอา Markdown ออกจะทำงานได้รวดเร็วและปลอดภัยกว่ามากใน Go\u003C\u002Fp>\u003Ch3>ควรตั้ง \u003Ccode>maxRetries\u003C\u002Fcode> ไว้ที่เท่าไหร่ดี?\u003C\u002Fh3>\u003Cp>โดยทั่วไป 2 ถึง 3 ครั้งก็เพียงพอแล้วครับ การเรียก LLM ใช้เวลานาน (High Latency) ถ้าเรา Retry มากเกินไป Request นั้นอาจจะบล็อกระบบจนเกิด Timeout ฝั่ง Client ได้ แนะนำว่าถ้า Retry ครบโควตาแล้ว ให้ทำระบบ Fallback โดยการส่งค่า Default กลับไปให้ผู้ใช้งานแทนครับ\u003C\u002Fp>\u003Ch3>เราจำเป็นต้องเขียนเช็ก Semantic Validation ทุกฟิลด์เลยไหม?\u003C\u002Fh3>\u003Cp>ไม่จำเป็นครับ ให้เน้นเช็กเฉพาะฟิลด์ที่มีผลต่อ Business Logic หลักๆ เช่น สถานะ (Status), ตัวเลขคะแนน (Score) หรือฟิลด์ที่ต้องนำไปประมวลผลทางคณิตศาสตร์ต่อ ส่วนที่เป็นแค่ข้อความทั่วไป (เช่น คำอธิบายประกอบ) ปล่อยผ่านได้เลยเพื่อประหยัดเวลาประมวลผลครับ\u003C\u002Fp>\u003Cdiv data-type=\"horizontalRule\">\u003Chr>\u003C\u002Fdiv>\u003Ch2>📝 สรุป\u003C\u002Fh2>\u003Cp>ในการทำงานกับ AI เราไม่สามารถเชื่อใจผลลัพธ์ที่ได้มาแบบ 100% ครับ เทคนิคที่เราเรียนรู้ในวันนี้คือการทำ Pre-validation, การสร้างฟังก์ชัน Clean Up เพื่อจัดการ JSON ที่แถม Markdown, การทำ Semantic Validation เพื่อกรองข้อมูลขยะ และการใช้ Retry Loop เพื่อแก้ปัญหาเฉพาะหน้าโดยอัตโนมัติ การวางโครงสร้าง 3 ชั้นแบบนี้จะช่วยให้ Go Backend ของเราทนทานต่อความไม่แน่นอนของ LLM และปล่อยขึ้น Production ได้อย่างมั่นใจครับ\u003C\u002Fp>\u003Cp>\u003Cstrong>ในตอนต่อไป (EP.169):\u003C\u002Fstrong> เราสร้างระบบ AI Microservices บน Go มาอย่างเข้มข้นตลอดทั้งซีรีส์ แต่หลายคนอาจจะสงสัยว่า \"ทำไมถึงต้องใช้ Go ในงาน AI ทั้งที่ Python คือลูกรักของวงการนี้?\" ตอนหน้าเราจะมาทดสอบเปรียบเทียบหมัดต่อหมัดในหัวข้อ \"Benchmarking Go vs. Python for AI Pipelines — ดูความแตกต่างด้าน Latency, Concurrency และ Memory Usage\" ห้ามพลาดครับ Gophers!\u003C\u002Fp>\u003Cp>\u003Cstrong>ฝากกดติดตามพวกเราได้ที่ Superdev Academy\u003C\u002Fstrong> ในทุกช่องทางนะครับ!\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>🔵 Facebook: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener\" class=\"ng-star-inserted\" href=\"https:\u002F\u002Fwww.facebook.com\u002Fsuperdev.academy.th\">\u003Cstrong>Superdev Academy Thailand\u003C\u002Fstrong>\u003C\u002Fa>\u003Cstrong> \u003C\u002Fstrong>(อัปเดตข่าวสารและบทความใหม่)\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>🎬 YouTube: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener\" class=\"ng-star-inserted\" href=\"https:\u002F\u002Fwww.youtube.com\u002F@SuperdevAcademy\">\u003Cstrong>Superdev Academy Channel\u003C\u002Fstrong>\u003C\u002Fa>\u003Cstrong> \u003C\u002Fstrong>(ติวเข้มแบบวิดีโอ)\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>📸 Instagram: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener\" class=\"ng-star-inserted\" href=\"https:\u002F\u002Fwww.instagram.com\u002Fsuperdevacademy\u002F\">\u003Cstrong>@superdevacademy\u003C\u002Fstrong>\u003C\u002Fa>\u003Cstrong> \u003C\u002Fstrong>(เกร็ดความรู้สั้นๆ และเบื้องหลังการทำงาน)\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>🎬 TikTok: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener\" class=\"ng-star-inserted\" href=\"https:\u002F\u002Fwww.tiktok.com\u002F@superdevacademy?lang=th-TH\">\u003Cstrong>@superdevacademy\u003C\u002Fstrong>\u003C\u002Fa>\u003Cstrong> \u003C\u002Fstrong>(Tips &amp; Tricks ฉบับย่อยง่าย)\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>🌐 Website: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"http:\u002F\u002Fsuperdevacademy.com\">\u003Cstrong>superdevacademy.com\u003C\u002Fstrong>\u003C\u002Fa>\u003Cstrong> \u003C\u002Fstrong>(คลังบทความและคอร์สเรียนฉบับเต็ม)\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Cp>\u003C\u002Fp>","55qbgl8rpm60_j3c1iaymvf.png","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclblg987654321\u002F530smgbtmfdxrqu\u002F55qbgl8rpm60_j3c1iaymvf.png","2026-08-04 05:29:35.582Z","76qprkevbgfdps8",{"keywords":15,"locale":51,"school_blog":61},[16,23,27,31,35,39,43,47],{"collectionId":17,"collectionName":18,"created":19,"created_by":13,"id":20,"name":21,"updated":22,"updated_by":13},"sclkey987654321","school_keywords","2026-03-04 08:20:14.253Z","ah6lvy4x8qe08l5","Golang","2026-06-07 06:45:08.193Z",{"collectionId":17,"collectionName":18,"created":24,"created_by":13,"id":25,"name":26,"updated":24,"updated_by":13},"2026-08-04 04:49:10.806Z","wkf0f2sfoww4cky","Go Backend",{"collectionId":17,"collectionName":18,"created":28,"created_by":13,"id":29,"name":30,"updated":28,"updated_by":13},"2026-08-04 05:28:58.694Z","vu2461mrhx1afzr","AI Error Handling",{"collectionId":17,"collectionName":18,"created":32,"created_by":13,"id":33,"name":34,"updated":32,"updated_by":13},"2026-08-04 05:29:02.997Z","9vyanknydv1npgx","จัดการ Error AI",{"collectionId":17,"collectionName":18,"created":36,"created_by":13,"id":37,"name":38,"updated":36,"updated_by":13},"2026-08-04 05:29:14.039Z","ilihovj7cw9a875","JSON พัง",{"collectionId":17,"collectionName":18,"created":40,"created_by":13,"id":41,"name":42,"updated":40,"updated_by":13},"2026-06-11 16:14:34.250Z","01ajl5eq1joxocg","LLM",{"collectionId":17,"collectionName":18,"created":44,"created_by":13,"id":45,"name":46,"updated":44,"updated_by":13},"2026-07-13 01:22:42.953Z","hcbz61drlwxlj06","สอน Golang",{"collectionId":17,"collectionName":18,"created":48,"created_by":13,"id":49,"name":50,"updated":48,"updated_by":13},"2026-08-04 05:29:28.009Z","l5rv57is5tqggzg","Retry Loop",{"code":52,"collectionId":53,"collectionName":54,"created":55,"flag":56,"id":57,"is_default":58,"label":59,"updated":60},"th","pbc_1989393366","locales","2026-01-22 10:59:55.832Z","twemoji:flag-thailand","s8wri3bt4vgg2ji",true,"Thai","2026-04-10 15:42:46.614Z",{"category":62,"collectionId":63,"collectionName":64,"created":65,"expand":66,"id":81,"slug":82,"updated":83,"views":84},"wqxt7ag2gn7xcmk","pbc_2105096300","school_blogs","2026-08-04 05:29:35.329Z",{"category":67},{"blogIds":68,"collectionId":69,"collectionName":70,"created":71,"created_by":13,"id":62,"image":72,"image_alt":73,"image_path":74,"label":75,"name":76,"priority":77,"publish_at":78,"scheduled_at":73,"status":79,"updated":80,"updated_by":13},[],"sclcatblg987654321","school_category_blogs","2026-03-04 08:33:53.210Z","59ty92ns80w_15oc1implw.png","","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclcatblg987654321\u002Fwqxt7ag2gn7xcmk\u002F59ty92ns80w_15oc1implw.png",{"en":76,"th":76},"Golang The Series",1,"2026-03-16 04:39:38.440Z","published","2026-06-07 06:45:03.856Z","54u71ct4gosq2pv","golang-the-series-ep168-error-handling-in-ai","2026-08-11 11:48:55.865Z",114,"530smgbtmfdxrqu",[20,25,29,33,37,41,45,49],"2026-08-11 04:41:25.613Z","เทคนิคเขียน Go Backend รับมือปัญหา AI ตอบกลับ JSON ผิดฟอร์แมต หรือตอบนอกเรื่อง พร้อมวิธีทำ Clean Up ข้อความ, Safe Parsing และ Retry Loop เพื่อป้องกันไม่ให้ระบบพัง","Golang The Series EP.168: Error Handling in AI วิธีรับมือเมื่อ AI ตอบกลับสิ่งที่ไม่คาดคิด (JSON พัง)","2026-08-11 04:45:42.205Z","423vhnv3ckczcyn",{"th":82,"en":82}]