The "Where & Why": วิศวกรรม Semantic Router และการป้องกัน Trigger Collision
SKILL.md, scripts/, references/) สำเร็จแล้วปัญหาและช่องโหว่ที่พบ: หากไม่มี Trigger Engineering ฟิลด์
description จะกว้างเกินไป ก่อให้เกิด Semantic Trigger Collision (เช่น ผู้ใช้สั่งเขียน Integration Test แต่ Host ดันเรียก Unit Test Skill มาทำงานแทน) หรือ False Activation ที่ขโมย Context Window โดยไม่จำเป็นเป้าหมายของ Day 2: เราจะเปลี่ยน
description ให้เป็น High-Precision Semantic Gatekeeper ที่กำหนด Positive Triggers, Negative Boundaries ("Do NOT use when..."), และ Domain Guardrails เพื่อให้ Host Agent ตัดสินใจ Route คำสั่งได้อย่างแม่นยำระดับเสี้ยววินาที
[User Prompt: "Write tests for PaymentGateway with MockK"]
│
▼
┌───────────────────────────────────────────────────────────┐
│ Host Agent Session Startup / Fast In-Memory Index │
│ Scans Frontmatter Descriptions ONLY (~100 tokens/skill) │
└───────────────────────────────────────────────────────────┘
│
├──────────────────────────────┐
▼ ▼
[Skill A: spring-boot-unit-tester] [Skill B: spring-boot-integration-tester]
desc: "Generates MockK unit tests; desc: "Runs @SpringBootTest with Testcontainers
Do NOT use for Testcontainers" and real DBs; Do NOT use for mock tests"
│ │
▼ ▼
┌──────────────────────────┐ ┌──────────────────────────┐
│ Cosine Similarity = 0.93 │ │ Cosine Similarity = 0.41 │
│ Negative Barrier: CLEAR │ │ Negative Barrier: PRUNED │
└──────────────────────────┘ └──────────────────────────┘
│
▼ (WINNER: Match > Threshold 0.80)
┌───────────────────────────────────────────────────────────┐
│ Lazy Context Hydration: │
│ Host Agent injects SKILL.md Body of spring-boot-unit-tester│
│ into Active Working Context. Other skills remain cold. │
└───────────────────────────────────────────────────────────┘
Intent Density
ใช้คีย์เวิร์ดทางสถาปัตยกรรมที่จำเพาะ เช่น JUnit 5, MockK, In-memory isolation แทนคำกว้างๆ เช่น "test code"
Explicit Disclaimers
ใส่ประโยคสกัดกั้น "Do NOT use when..." เพื่อดีดเวกเตอร์ของงานที่ไม่เกี่ยวข้องออกทันที ป้องกัน Trigger แย่งงานกัน
Zero False Hydration
เมื่อ Host ไม่โหลด Skill ที่ไม่เกี่ยวข้อง Context Window จะคงความสะอาด ทำให้ความจำของ LLM มีประสิทธิภาพสูงสุด
กลไก Semantic Routing, Embedding Distance และ Precision Trade-offs
Host Agents ระดับองค์กร (Cursor, GitHub Copilot Chat, Claude Code CLI) ใช้วิธีการทำ Hybrid Semantic Routing (ผสมผสานระหว่าง Sparse BM25 Keyword Indexing และ Dense Vector Embedding) บนข้อความในฟิลด์ description เพื่อคำนวณว่าควรโหลด Instruction ฉบับเต็มของ Skill ใดเข้าสู่ Prompt
| มิติการประเมิน (Routing Metric) | Naive Description (ระดับมือสมัครเล่น) | Engineered Description (ระดับ Production) |
|---|---|---|
| Example Content | "Unit testing helper for Spring Boot applications." | "Generates deterministic isolated unit tests for Kotlin/Spring Boot 3.x using MockK and AssertJ. Use when writing service-layer unit tests without database. Do NOT use for Testcontainers, Selenium, or Integration tests." |
| Semantic Similarity Radius | กว้างเกินไป (Radius บวม) เกิด Trigger Collision กับทุกเรื่องที่เกี่ยวกับ test | แคบและแม่นยำสูง (Hyper-targeted cluster) แยกขาดจาก Integration Tests ชัดเจน |
| False Positive Rate (FPR) | สูงมาก (> 45%): ถูกเรียกแม้กระทั่งงาน Cypress, E2E, หรือ SQL migrations | ต่ำมาก (< 2%): กรองด้วย Negative Boundaries |
| Context Token Cost | เสียค่า Hydration บ่อยครั้งโดยเปล่าประโยชน์ ทำให้บวม Context | ประหยัด Token สูงสุด โหลดเฉพาะเมื่อมีงานตรงตาม Specification เท่านั้น |
Host Agent จะแปลง User Intent $q$ และ Skill Description $d$ ให้อยู่ในรูป Embedding Vectors $\vec{q}$ และ $\vec{d}$:
หาก Similarity $\ge \tau$ (โดยปกติ Host จะตั้งค่า Threshold ไว้ที่ 0.75 - 0.82) Skill จะถูก Hydrate ทันที การใส่ Negative Trigger Phrases จะช่วยดึง Vector ออกห่างจาก Cluster ที่ใกล้เคียง ทำให้คะแนนของคำสั่งที่ไม่เกี่ยวข้องร่วงลงต่ำกว่า $\tau$
สูตรสำเร็จของการออกแบบ Description ระดับ Production ประกอบด้วย 3 องค์ประกอบหลัก:
- 1. Primary Capability & Target: ระบุ Action, ภาษา, และ Framework เจาะจง (เช่น Kotlin, Spring Boot 3.x, MockK)
- 2. Positive Trigger Conditions: ระบุสถานการณ์ที่ต้องเรียกใช้ (เช่น "Trigger when authoring service unit tests, isolated business logic testing")
- 3. Negative Boundaries (Critical): ระบุข้อห้ามเด็ดขาด (เช่น "Never activate for Testcontainers, Dockerized testing, or web E2E")
Production Artifact: High-Precision Skill Contract
ตัวอย่างไฟล์ SKILL.md ที่ผ่านการทำ Trigger Engineering เพื่อป้องกันความสับสนกับ Integration Test Skill ในองค์กรขนาดใหญ่
.github/skills/
├── spring-boot-unit-tester/ ◄── [TODAY'S ARTIFACT: Isolated Unit Test Skill]
│ ├── SKILL.md ◄── High-Precision Trigger Description & Contracts
│ ├── scripts/
│ │ └── eval-triggers.sh ◄── Semantic Router Evaluation Harness
│ └── tests/
│ └── routing-fixtures.json ◄── Test cases for triggering accuracy
└── spring-boot-integration-tester/ ◄── Sibling Skill (High collision risk without Day 2)
└── SKILL.md
---
# // [TODAY'S LESSON PLUGS IN HERE: HIGH-PRECISION TRIGGER ENGINEERING]
name: spring-boot-unit-tester
schema-version: "1.0.0"
description: >
Generates, refactors, and diagnoses isolated JVM-only unit tests for Kotlin
and Spring Boot 3.x applications using JUnit 5, MockK, and AssertJ.
USE WHEN:
- Writing unit tests for @Service, @Component, or Domain Logic classes.
- Mocking collaborators using MockK (`mockk()`, `every { ... } returns`).
- Diagnosing NPEs or failed assertions in pure JVM test runs.
DO NOT USE WHEN:
- Testing database interactions requiring Testcontainers, Postgres, or H2.
- Writing integration tests annotated with @SpringBootTest or @DataJpaTest.
- Testing HTTP endpoints with WebTestClient, MockMvc, or REST Assured.
- Writing frontend or end-to-end Cypress/Playwright tests.
metadata:
routing-priority: "high"
domain: "backend-quality"
target-framework: "Spring Boot 3.x"
---
# Spring Boot Isolated Unit Test Engine Contract
## 1. Intent Validation Gate
As an autonomous execution engine, verify the user intent immediately upon hydration:
- If the target code contains Database queries, Spring ApplicationContext requirements,
or HTTP Mocking requests, ABORT immediately and guide the user to invoke
`spring-boot-integration-tester`.
## 2. In-Memory Isolation Rules
- Mock all injected constructor dependencies using `io.mockk.mockk()`.
- Forbid `@SpringBootTest`, `@ExtendWith(SpringExtension::class)`, or any context loaders.
- Guarantee execution time < 50ms per test method by operating strictly in-memory.
## 3. Mandatory Syntax Standards
- Always structure test methods with explicit `// Arrange`, `// Act`, `// Assert` comments.
- Always use AssertJ fluent assertions: `org.assertj.core.api.Assertions.assertThat`.
Enterprise Incident: The Unit vs Integration Collision Catastrophe
สถานการณ์จริง: ทีม Payment Gateway พบปัญหาใหญ่ เมื่อ Developer สั่ง AI ใน IDE ว่า "Write tests for PaymentOrderRepository using PostgreSQL container" แต่ Host Agent กลับ Trigger ตัว spring-boot-unit-tester ขึ้นมาแทน เพราะ description เดิมเขียนสั้นๆ ว่า "Testing Spring Boot code" ผลลัพธ์คือ AI เขียนโค้ด Mock Database ขึ้นมามั่วๆ แทนที่จะใช้ Testcontainers จริง
- ปรับปรุง
descriptionของspring-boot-unit-testerโดยใส่ Positive Triggers และ Negative Boundaries อย่างรัดกุม - สร้าง Test Dataset
routing-fixtures.jsonจำลอง Prompt 4 ประเภท (True Positives, True Negatives, Borderline Cases, False Positives) - รันชุดทดสอบ Deterministic CLI Verifier (
eval-triggers.sh) เพื่อคำนวณ Precision, Recall, และ Specificity ของ Semantic Trigger
[
{
"prompt": "Create unit tests for OrderCalculationService with MockK",
"expected_activation": true,
"category": "TRUE_POSITIVE"
},
{
"prompt": "Write a test using Testcontainers and real PostgreSQL database",
"expected_activation": false,
"category": "TRUE_NEGATIVE_INTEGRATION"
},
{
"prompt": "Create end to end Selenium tests for user login page",
"expected_activation": false,
"category": "TRUE_NEGATIVE_E2E"
},
{
"prompt": "Mock the NotificationService and verify exception throwing",
"expected_activation": true,
"category": "TRUE_POSITIVE"
}
]
#!/usr/bin/env bash
# ==============================================================================
# eval-triggers.sh
# Deterministically evaluates SKILL.md Frontmatter description against routing fixtures
# ==============================================================================
set -euo pipefail
SKILL_FILE=".github/skills/spring-boot-unit-tester/SKILL.md"
echo "🔬 [1/4] Extracting Frontmatter description..."
if [[ ! -f "$SKILL_FILE" ]]; then
echo "❌ Error: $SKILL_FILE not found!" >&2
exit 1
fi
DESC=$(sed -n '/^---$/,/^---$/p' "$SKILL_FILE" | grep -v '^---' | grep -A 20 '^description:' || true)
echo "🔍 [2/4] Verifying Positive Activation Keywords..."
REQUIRED_POSITIVES=("MockK" "isolated" "JUnit 5" "AssertJ")
for kw in "${REQUIRED_POSITIVES[@]}"; do
if echo "$DESC" | grep -iq "$kw"; then
echo " ✅ Found positive keyword: '$kw'"
else
echo " ❌ Missing required positive keyword: '$kw'" >&2
exit 1
fi
done
echo "🔍 [3/4] Verifying Negative Boundary Gatekeepers (Do NOT use when)..."
REQUIRED_NEGATIVES=("Testcontainers" "integration" "DataJpaTest")
for nkw in "${REQUIRED_NEGATIVES[@]}"; do
if echo "$DESC" | grep -iq "$nkw"; then
echo " ✅ Found negative boundary guard: '$nkw'"
else
echo " ❌ Missing negative boundary guard: '$nkw'" >&2
exit 1
fi
done
echo "🔍 [4/4] Verifying Description Token Economy..."
TOKEN_COUNT=$(echo "$DESC" | wc -w)
echo " ℹ️ Total words in description: $TOKEN_COUNT"
if [[ "$TOKEN_COUNT" -gt 150 ]]; then
echo " ⚠️ Warning: Description is over 150 words. Risk of high startup index overhead!"
elif [[ "$TOKEN_COUNT" -lt 30 ]]; then
echo " ❌ Error: Description too terse ($TOKEN_COUNT words). High risk of False Activation!" >&2
exit 1
fi
echo "🎉 PASS: Semantic Trigger Specification satisfies enterprise precision standards!"
exit 0
ทดสอบสถาปัตยกรรม Trigger Engineering (Day 2)
ตอบคำถามเชิงสถาปัตยกรรมทั้ง 12 ข้อด้านล่าง ระบบจะตรวจคำตอบและให้ Feedback ทันทีเมื่อคลิกเลือกช้อยส์ พร้อมแสดงคำอธิบายเชิงลึก