ENDEAVOR LOCAL AGENT TH ทำงานอย่างไร — เจาะลึกสถาปัตยกรรม

ภาพประกอบ: ENDEAVOR LOCAL AGENT TH ทำงานอย่างไร — เจาะลึกสถาปัตยกรรม

บทความ เริ่มต้นใช้งาน บอกวิธีติดตั้งและใช้งาน ส่วนบทความนี้อธิบายสถาปัตยกรรมของ ENDEAVOR LOCAL AGENT TH รุ่นปัจจุบัน ว่าทำไมระบบยังเป็น ReAct loop ที่เรียบง่าย แต่มี deterministic guard หลายชั้นคอยบังคับ invariant ที่สำคัญแทนการฝากทุกอย่างไว้กับโมเดล

แกนหลัก: LangGraph single-node ReAct

กราฟหลักมี node เดียว:

START → react → END

ไม่มี planner_node, execute_node, synthesize_node แยกเป็นหลาย node ตัว main agent จึงเห็น full message history + tool results อยู่ใน loop เดียว แล้วตัดสินใจต่อเองว่า:

  1. ต้องวางแผนหรือไม่
  2. ต้องเรียก tool ไหน
  3. ผลลัพธ์พอหรือยัง
  4. ต้องวนต่อหรือสรุปคำตอบ

โครงสร้างนี้ลดจุดที่ state/context หลุดระหว่าง node และทำให้ behavior ใกล้กับ ReAct ตรง ๆ มากที่สุด

Planner ยังมี แต่ไม่ใช่ planner node

planner.py ใช้ LLM call แยกเพื่อจัด query เป็น:

  • simple
  • complex พร้อม step list

จากนั้น graph.py มี deterministic intercept สำหรับคำสั่งค้นคว้า/research ที่ชัดเจน

ถ้า planner บอกว่า complex ระบบสามารถ seed create_plan เป็น tool call ใน code ได้โดยตรง แทนที่จะหวังให้โมเดล “นึกได้เอง” ว่าควรวางแผนก่อน จุดนี้ทำให้ขั้นตอนสำคัญถูกบังคับด้วย runtime logic แต่ execution หลังจากนั้นยังอยู่ใน ReAct node เดิม

เครื่องมือปกติ 28 ตัว

ปัจจุบัน Agent TH bind 28 tools ในโหมดปกติ:

หมวด จำนวน Tools / ตัวอย่าง
Web & Research 7 web_search, browse_url, browser_use, recall_web, fetch_sitemap, batch_browse, scrape_table
File & Code 5 read_file, write_file, edit, grep, workspace_ls
Execution & Data 4 bash, bash_bg, python_exec, plot
Vision 1 read_image
Knowledge Base 1 rag_search
Memory 1 remember
Audio 1 speak
Automation 1 awake
Computer Use 1 computer
MCP 4 mcp_list_tools, mcp_call_tool, mcp_add_server, mcp_remove_server
Planning & Loops 2 create_plan, tool_loop

รวม 28 tools

MCP surface นี้เป็น generic client ไม่ใช่ backend เฉพาะตัว: public repo เริ่มด้วย config.MCP_SERVERS = {} และไม่ bundle default MCP server ใด ๆ ผู้ใช้สามารถเพิ่ม Streamable HTTP หรือ guarded local stdio server ระหว่างใช้งานได้ผ่าน registry ใต้ workspace/tool_mcp/

research_orchestrator เป็น skill-only tool และจะถูก bind เฉพาะเมื่อเข้า Research Skill ไม่ได้โผล่ให้โมเดลเห็นทุก turn

Parallel tools: ลดจำนวนรอบโดยไม่ทำให้ผลลัพธ์สลับลำดับ

Agent TH รุ่นปัจจุบันย้ายงานอ่านที่เป็นอิสระต่อกันให้ทำพร้อมกันใน tool call เดียว สองจุดหลัก:

  • read_file — path เป็น list ได้สูงสุด 4 ไฟล์ หรือใช้ requests 1–4 รายการเมื่อแต่ละไฟล์ต้องใช้ filter/range คนละแบบ ตัว worker ทำงานขนาน แต่ผลลัพธ์ถูกประกอบกลับตาม input order และ error ของไฟล์หนึ่งไม่ล้มทั้ง batch
  • read_image — source เป็น list ได้สูงสุด 10 ภาพ พร้อม ocr=true หรือ selector เช่น ocr=[1,3]; การ resolve/prepare/OCR ที่ทำได้จะรันขนาน แต่ progressive vision ยังคงบังคับ original-before-OCR สำหรับภาพใหม่

แนวทางนี้ลดจำนวน ReAct round-trip จาก “เรียก tool ทีละไฟล์/ภาพ” เป็น “หนึ่ง call ครอบคลุมชุดที่ independent” โดยไม่ย้าย reasoning เข้า worker thread และไม่ทำให้ main agent สูญเสียลำดับของ input

Repeated tool-call guard: hint รอบสอง, stop รอบสาม

นอกจาก recursion limit แล้ว ToolNode มี deterministic guard กลางที่ตรวจ tool name + arguments ของ call ที่ติดกันภายใน user turn เดียว

  1. ครั้งแรก — รัน tool ตามปกติ
  2. ครั้งที่สองด้วย fingerprint เดิม — ไม่รัน tool ซ้ำ แต่คืน [tool_loop_hint] ให้ model เปลี่ยน query/arguments หรือเปลี่ยนเครื่องมือ
  3. ถ้ายังเรียกเดิมเป็นครั้งที่สาม — raise ToolLoopDetected และหยุด turn ที่ stream boundary พร้อมข้อความที่ผู้ใช้มองเห็น

สำหรับ web_search ระบบ normalize ตัวพิมพ์และ whitespace ของ query ก่อนสร้าง fingerprint จึงใช้ "Same Query", "same query" หรือ spacing ต่างกันเพื่อหลบ guard ไม่ได้ จุดประสงค์คือหยุด loop ที่ไม่มีข้อมูลใหม่ โดยไม่ลดสิทธิ์ของ model ในการเรียก tool เดิมซ้ำเมื่อ arguments เปลี่ยนจริง

MCP: capability เพิ่มได้ แต่ไม่ขยาย sandbox ตามไปด้วย

MCP client แยก transport ออกเป็นสองแบบ:

  • Streamable HTTP — ใช้ URL + optional headers แล้วคุยผ่าน official MCP SDK
  • local stdio — command ต้องเป็น absolute executable, cwd ต้องอยู่ใน Agent workspace และ child process ถูกครอบด้วย macOS sandbox profile เดียวกับ bash

self-service registry เขียนแบบ atomic พร้อม cross-process lock และตั้ง permission 0600 เพื่อไม่ให้ config/HTTP headers เปิดกว้างในเครื่อง การเพิ่ม stdio server ไม่ได้ให้ write path พิเศษนอก workspace/ และ /tmp; public fork จงใจไม่เปิด write-capability พิเศษนอก sandbox และไม่ bundle default MCP server มาให้

mcp_list_tools ยัง inspect schema ของ tool เดียวได้ก่อน call ส่วน mcp_call_tool รับ arguments เป็น JSON object และ cap text result ก่อนคืนเข้า ReAct loop อ่านรายละเอียดที่ Tools: MCP client

Runtime model: 9B / 14B / 35B ใช้ config กลางเดียวกัน

fresh install และ fresh runtime config ยังเริ่มที่ Qwen3-14B-MLX-4bit แต่ model list เพิ่ม mlx-community/Qwen3.5-9B-4bit เป็น compact VLM สำหรับ Mac unified memory 16GB. Electron Settings และ CLI menu → Model / Think Budget ใช้ config กลางเดียวกัน จึงเห็น model/budget ชุดเดียวกันข้ามสอง frontend

Qwen3.5-9B และ Qwen3.6-35B ไม่ถูกดาวน์โหลดบังคับพร้อม 14B แต่โหลดเมื่อผู้ใช้เลือกจริง. 9B เหมาะกับเครื่อง RAM จำกัดและรองรับ direct vision; 35B เป็นตัวเลือกคุณภาพสูงสำหรับ reasoning/tool calling ที่ซับซ้อนกว่า. เฉพาะ 35B บน RAM ต่ำกว่า 24GB ที่ระบบจะแสดง low-RAM confirmation ก่อน download/load

Vision architecture: behavior ขึ้นกับ capability ของ model

Qwen3.5-9B บน Mac 16GB: compact direct vision

9B option เป็น vision-language model ดังนั้น read_image สามารถส่ง original pixels ให้ main model และ computer ใช้ screenshot direct vision ได้เหมือน vision-capable path อื่น โดยแลกกับ reasoning/tool-calling headroom ที่ต่ำกว่า 35B

Qwen3-14B default แบบ text-only

runtime probe capability ก่อนใช้งานภาพ:

  • read_image → fallback เป็น full OCR ของภาพต้นฉบับใน turn เดียว
  • computer → คืน [unsupported] ก่อน screenshot หรือ desktop action

จึงไม่เกิดกรณี model text-only พยายามเดา pixel ที่มองไม่เห็น และผู้ใช้ Mac 24GB ยังใช้ file/code/web/RAG/MCP/tool-calling หลักได้ตามปกติ

เมื่อเลือก vision-capable model เช่น Qwen3.5-9B หรือ Qwen3.6-35B

read_image ทำงานแบบ progressive direct vision กับทั้ง 9B VLM และ 35B:

  1. ครั้งแรกส่งภาพต้นฉบับทั้งภาพให้ main VLM
  2. Agent มอง pixels และตอบ/ตัดสินใจเอง
  3. ถ้าต้องการอ่านข้อความ ตาราง QR กราฟ หรือจุดเฉพาะ ค่อยเรียก sensor/detail เพิ่ม

ไม่มี semantic image prompt หรือ inner LLM ซ่อนอยู่ใน read_image — tool ทำหน้าที่เตรียมภาพ/sensor output แล้ว main agent เป็นคน reasoning

computer ใช้หลักเดียวกัน: screenshot ล่าสุดถูกส่งให้ main VLM พร้อม observation จาก Accessibility/OCR เพื่อช่วยยึดตำแหน่งและตรวจผลหลัง action

read_image เป็น progressive sensor ไม่ใช่ image chatbot ซ้อนอีกชั้น

จุดสำคัญของ design ปัจจุบันคือ original first

Agent ต้องเห็นภาพ overview ก่อน แล้วจึงขอรายละเอียด เช่น:

  • detail="text" — OCR/table/QR assist
  • detail="chart" / "slide"
  • find=...
  • region + zoom

การ crop/zoom ก่อน overview ถูก guard เพื่อไม่ให้ agent เริ่มจากชิ้นส่วนเล็ก ๆ แล้วตีความภาพรวมผิด

อ่านรายละเอียดเพิ่มที่ Tool: read_image

computer: screenshot → aim → action → re-observe

computer ไม่ได้ใช้ OCR เป็น “สายตาหลัก” อีกต่อไป และไม่มี vision model ตัวเล็กแยกอยู่ข้างใน

flow หลักคือ:

screenshot
   ↓
main VLM มองภาพ + [OBS] จาก AX/OCR
   ↓
เลือก target/action
   ↓
click/type/key/scroll/open...
   ↓
capture + observe ใหม่
   ↓
ตรวจ visible effect ก่อนทำต่อ

Accessibility และ OCR ยังสำคัญ แต่ทำหน้าที่เป็น structured assist เพื่อให้ model อ้าง element/text ได้แม่นขึ้น ไม่ใช่การแทน vision ทั้งหมด

อ่านรายละเอียดเพิ่มที่ Tool: computer

Context, history และ web cache

Agent TH แยก state หลายชนิดออกจากกัน:

  • Conversation history — LangGraph SqliteSaver ใน logs/history.db
  • Persistent memory — remember เขียนข้อมูลสำคัญลง memory store
  • Web cache — raw web results เก็บแยกใน process memory แล้วให้ Agent เรียก recall_web เมื่อจำเป็น
  • Context trimming — ตัด/สรุป history เมื่อ session ยาวเกิน threshold เพื่อกัน context overflow

จุดนี้ช่วยลดการยัด raw tool output จำนวนมากกลับเข้า prompt ทุก turn

Generation profile: จำกัด thinking + reuse prefix

ค่าหลักปัจจุบัน:

Parameter Default
Temperature 0.1
Thinking budget 1536
Repetition penalty 1.05
Recursion limit 60
APC enabled 1
APC exact cache entries 2
APC exact prefix guard 64 tokens

ทำไม APC exact cache ใช้ 2 slots

สำหรับ conversation เส้นตรง runtime exact APC เก็บ 2 state ต่อ request:

  1. guarded reusable checkpoint ก่อน variable tail
  2. full prompt snapshot

ถ้ามี slot เดียว full snapshot จะไล่ reusable checkpoint ออกเอง ทำให้ turn ถัดไปไม่ hit prefix

ดังนั้น Agent TH ใช้ 2 slots เป็นค่าต่ำสุดที่เหมาะกับ linear conversation และช่วยลด prefill/TTFT ของ system prompt + tool schema + history ก้อนเดิมได้มาก โดยไม่ต้องเก็บหลาย conversation branches ไว้พร้อมกัน

Security: capability ไม่ได้แปลว่าให้สิทธิ์ไม่จำกัด

Agent TH มี tools ที่แตะไฟล์ process และ desktop จริง จึงมี guard ระดับ code แยกจาก system prompt

File/process sandbox

  • write จำกัดใน workspace ตาม policy
  • path สำคัญ/credential ถูก block
  • resolve real path เพื่อกัน ../ และ symlink escape
  • bash, bash_bg, python_exec ถูกครอบด้วย macOS sandbox-exec ตาม policy ของโปรเจกต์

computer guard

สำหรับ desktop action:

  • capability probe ต้องยืนยัน vision ก่อน
  • destructive-looking action ถูกจำกัดตาม user intent
  • turn จาก awake เข้มกว่าปกติและจำกัด action สูงสุด
  • observation/screenshot state reset ตาม turn
  • หลัง mutation ต้อง re-observe และตรวจ visible effect แทนการสมมติว่าคลิกสำเร็จ

แนวคิดเหมือนกันทั้งระบบ: model ตัดสินใจงาน แต่ code เป็นเจ้าของ safety invariant

Standing trigger: awake

awake ให้ Agent ตั้ง trigger แล้วกลับมาทำงานเองภายใน process เดิม เช่น:

  • file — ไฟล์เปลี่ยน
  • every — ทุก N นาที
  • times / run_at — ตามเวลา
  • once — ครั้งเดียวหลัง delay
  • screen — ตรวจการเปลี่ยนแปลงบนหน้าจอ

turn ที่เกิดจาก standing trigger ใช้ agent loop เดิม แต่มี computer guard ที่เข้มกว่า interactive turn

Skill modes

/research และ /pdf_to_text เปลี่ยน prompt/toolset ให้เหมาะกับงานเฉพาะ แทนการให้ model เห็นเครื่องมือทุกตัวตลอดเวลา

Research Skill สามารถ bind research_orchestrator เพิ่มเฉพาะโหมด เพื่อย้าย loop research หลาย batch เข้า deterministic Python orchestration แทนการหวังให้ LLM วนเองยาว ๆ

สรุป

Agent TH รุ่นปัจจุบันไม่ได้พยายามเพิ่ม node หรือ agent ซ้อนหลายชั้น แต่เน้น:

  • main ReAct loop เดียว
  • deterministic planning/safety intercept เฉพาะจุดสำคัญ
  • repeated-tool guard ที่เตือนรอบสองและหยุดรอบสามเมื่อ call เดิมซ้ำติดกัน
  • read_file parallel สูงสุด 4 ไฟล์ และ read_image batch สูงสุด 10 ภาพ
  • 28 tools ที่มีหน้าที่ชัด รวม generic MCP client 4 tools
  • main-model direct vision แทน inner VLM
  • text-only fallback ที่ fail closed
  • bounded thinking
  • APC สำหรับ reuse prefix
  • local-first runtime บน MLX

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

อ่านเพิ่มเติม

ความคิดเห็น

กำลังโหลดความคิดเห็น...