ผมนำ LangGraph มาใช้ด้วยความคาดหวังว่า “การจัดการสถานะและการควบคุมโฟลว์น่าจะเป็นระเบียบขึ้น” แต่กลับทำให้โค้ดซับซ้อนกว่าเดิม
นี่คือบันทึกและการแชร์ประสบการณ์ที่ได้เจอกับตัวว่า แม้จะนำเฟรมเวิร์กมาใช้แล้ว โครงสร้างก็ยังแย่ลงได้
เมื่อลองวิเคราะห์ดู สถานะเป็นแบบนี้
- ในกราฟมีเพียงโหนดเดียว โครงสร้างเป็น current_step → END จึงไม่มี conditional edge หรือการแตกกิ่ง และ
graph.invoke()ก็ไม่ต่างจากการเรียกฟังก์ชันโดยตรง การเปลี่ยน Step เป็นรูปแบบที่โค้ดบริการนอกกราฟเป็นผู้ตัดสินใจ - เก็บสถานะเดียวกันไว้สองที่ LangGraph MemorySaver (in-memory) กับ PostgreSQL Checkpointer ที่ทำเองเก็บและกู้คืนเซสชันเดียวกันซ้ำซ้อน ทำให้เกิดความไม่สอดคล้องกัน
- โค้ดรัน LangGraph (Executor) 3 ชุด รวมราว 8,700 บรรทัดมีโค้ดซ้ำกัน แก่นหลักจริง ๆ มีเพียงประมาณ “เรียก LLM + ประกอบพรอมป์ต์” ส่วนที่เหลือส่วนใหญ่คือการจัดการสถานะ การแตกเงื่อนไข และแพตช์ edge case
ในระดับผิวเผิน ปัญหาคือการนำเฟรมเวิร์กเข้ามาใช้แค่เป็นเปลือก โดยไม่ได้ใช้ฟีเจอร์จริงของมัน (conditional edge, built-in checkpointer, Human-in-the-Loop) แต่เมื่อขุดลึกลงไป สาเหตุที่แท้จริงอยู่คนละจุด
- ส่วนใหญ่ถูกสร้างด้วย vibe coding แต่ระหว่างกระบวนการสร้างไม่ได้ลงลึกไปดูโค้ดภายในหรือหลักการออกแบบ เพียงสรุปข้อกำหนดและเจตนาในแต่ละครั้งแล้วให้พัฒนาต่อไป
- ปัญหาไม่ใช่ตัว vibe coding เอง แต่คือการเดินหน้าต่อโดยไม่มีการตรวจสอบ มันช่วยเพิ่มประสิทธิภาพเฉพาะฟีเจอร์ตรงหน้า แต่ไม่ได้รักษาขอบเขตความรับผิดชอบของโครงสร้างโดยรวม ไม่ว่าจะเป็นการ checkpoint ซ้ำซ้อน สถานะที่กระจัดกระจาย หรือโลจิกที่ซ้ำกัน ล้วนเป็นผลสะสมของการ optimize เฉพาะส่วน
- ไม่ใช่ว่าไม่มีผู้ออกแบบ แต่สาเหตุที่แท้จริงคือสั่งงานอยู่บนเฟรมเวิร์กโดยยังไม่เข้าใจเพียงพอว่าเฟรมเวิร์กถูกออกแบบมาให้รับผิดชอบอะไร
ดังนั้นผมจึงทบทวนและปรับกลับมาแบบนี้
- แยกเซสชันด้วย topology อิสระ + การกั้นด้วย thread_id
- ให้ State มีเฉพาะ metadata และย้ายเนื้อหาหลักไปไว้ที่ Store
- ใช้
tool_useแบบ native แทนการ parse ด้วย regex - แยกโหนดเพื่อให้ทดสอบได้
- ตัวผมเองจำเป็นต้องมีความเข้าใจที่ถูกต้องเกี่ยวกับเฟรมเวิร์ก และโครงสร้างในการนำไปใช้
นี่คือบันทึก/การแชร์ ไม่ใช่เรื่อง “ใช้อย่างไร” แต่เป็นเรื่อง “ใช้ผิดอย่างไร”
2 ความคิดเห็น
ดูเหมือนว่าทุกกรณีที่ใช้ langchain และ langgraph จะสามารถแทนที่ด้วย AI SDK ได้
ใช่ครับ เห็นด้วยครับ แม้จะมี dependency กับ SDK เพิ่มขึ้นมา แต่เพราะ learning curve สูง เลยคิดว่าแบบนั้นน่าจะดีกว่าเสียอีกครับ