(with Go as our trusty sidekick)


| ปัญหา | ผลที่ตามมา |
|---|---|
| Toolless | ดึงข้อมูลจาก DB ไม่ได้ ยิง API ไม่ได้ |
| Stateless | คุยจบ ลืมทันที |
| Passive | ไม่ถาม ไม่เคยตอบ ไม่เคยลงมือทำเอง |
Agent = Model + HarnessHarness คือ "สายรัด" หรือโครงที่เราเขียนครอบ LLM เอาไว้ ให้มันมีมือ มีความจำ มีลูป คิด-ทำ-เช็คผล ซ้ำได้เอง
| Concept | LLM | AI Agent |
|---|---|---|
| Role | Oracle (ผู้พยากรณ์) | Worker / Actor |
| State | Stateless | Stateful (มีความจำ) |
| Action | ทายคำตอบ | เรียก Tool จริง |
| Flow | ตอบครั้งเดียวจบ | Loop คิด-ทำ-ทวน |


LLM ทำได้แค่ "คิด" แล้วบอกว่าอยากเรียก tool อะไร คนที่ "ลงมือทำจริง" คือโค้ดฝั่งเรา ไม่ใช่ตัว LLM เอง






$ claude
> เขียน python script สแกน open port บน localhost
| Claude Code มี... | ...คือชั้นไหนใน Part 3 |
|---|---|
| ตอบเป็นคนไม่ใช่หุ่นยนต์ | System Instruction |
| อ่าน/เขียนไฟล์, รันคำสั่ง | Tools |
| จำบทสนทนา, จำ context โปรเจกต์ | Sessions & State |
| ขอ permission ก่อนทำอะไรเสี่ยง | Callbacks & Safety |
| โหลดความรู้เฉพาะทางตามจังหวะ | Skills |
| แตกงานให้ subagent | Multi-Agent |
ไม่ใช่ "ปลั๊กอิน" ไม่ใช่ "โมเดลใหม่"
Skill = ไฟล์คำสั่ง (instructions) ที่ถูกเขียนแยกไว้เป็นชุดๆ แล้วให้ตัว harness ตัดสินใจว่า "ตอนนี้ควรโหลดชุดไหนเข้ามา"
ทุก skill คือไฟล์ SKILL.md หนึ่งไฟล์
เริ่มด้วย frontmatter สั้นๆ 2 บรรทัด:
name — ชื่อ skilldescription — สรุป 1 บรรทัดว่า "ใช้ตอนไหน"ส่วนเนื้อหาด้านล่าง คือคำสั่งแบบละเอียดยิบ
---
name: brainstorming
description: >
Use before any creative work -
creating features, building
components, designing systems.
---
# Brainstorming Ideas into Designs
... (คำสั่งเต็มยาวๆ ต่อจากนี้) ...
ชั้น 1: name + description <- โหลดเสมอ ทุก skill ทุกครั้ง (เบามาก)
ชั้น 2: เนื้อหาคำสั่งเต็ม <- โหลดเมื่อ "ตรง" กับสิ่งที่กำลังทำ
ชั้น 3: ไฟล์แนบ (scripts, docs) <- โหลดเมื่อ skill นั้นเรียกใช้เอง

Agent = Model + Harness
Model = LLM (ไม่ได้เขียนด้วย Go — เป็น service ที่เราเรียกใช้) Harness = โค้ด Go ทั้งหมดที่ประกอบมาใน Part 3
agent.NewTool(
"run_command",
"Run shell command",
func(ctx context.Context, cmd string) (string, error) {
out, err := exec.Command("sh", "-c", cmd).CombinedOutput()
return string(out), err
},
)
agent.WithBeforeModel(func(ctx context.Context, req *llm.Request) error {
// โหลด skill ตาม trigger (progressive disclosure ชั้น 2)
if isTranslationCommand(req) {
skillData, _ := os.ReadFile("skills/translate.md")
req.System = string(skillData) + "\n" + req.System
}
// กรอง PII ก่อนออกจาก server เสมอ
return redactPII(req)
})

func TestAgentWorkflow(t *testing.T) {
mockLLM := mock.NewLLM(
mock.WithToolCall("run_command", `{"cmd":"echo hi"}`),
)
ag := agent.New(mockLLM, tools)
res, _ := ag.Run(ctx, "say hi")
assert.Contains(t, res, "hi")
}
เราไม่ได้เทส AI — เราเทส Harness ของเรา
Minimum bar เมื่อเวลาไม่พอ:
LLM → เจอกำแพง → ใส่ Harness ทีละชั้น → กลายเป็น Agent → ส่อง Claude Code → เจาะ Skill → ใช้ Go ทำ AI Agent ด้วย ADK → Checklist ใช้ AI เขียนโค้ด
(ลองเริ่มสร้าง Agent ตัวแรกของคุณเองได้เลยวันนี้)