# ขุดค้นและปิดวงจร: การเปลี่ยนแปลงกลายเป็นความทรงจำองค์กรได้อย่างไร

Canonical source: https://maguyva.ai/th/blog/mining-workflow-closing-the-loop

License: text under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/); code samples under [MIT-0](https://opensource.org/license/mit-0); the Maguyva name, logos, brand assets and other code are not covered. Details: [maguyva.ai/license](https://maguyva.ai/license).

Date: 2026-02-03 · Author: Maguyva Team

> Git commit กลายเป็นรายการบันทึกการเปลี่ยนแปลงที่มีโครงสร้างและบันทึกการตัดสินใจเชิงสถาปัตยกรรม แล้วป้อนกลับเข้าสู่เอเจนต์ AI ในรูปแบบความทรงจำองค์กรที่ค้นหาได้

> *ตัวเลขในบทความนี้สะท้อนระบบ ณ วันที่เผยแพร่ (กุมภาพันธ์ 2026) ดู[หน้าทีม](/th/team)ของเราสำหรับตัวเลขปัจจุบัน*

ทุกทีมวิศวกรรมเผชิญความท้าทายเดียวกัน: การเปลี่ยนแปลงเกิดขึ้นตลอดเวลา แต่ *เหตุผล* เบื้องหลังการเปลี่ยนแปลงเหล่านั้นหายไป หกเดือนต่อมา มีคนถามว่า "ทำไมเราถึงเลือกใช้ DuckDB สำหรับสเตจของไปป์ไลน์" และคำตอบอยู่ในหัวของคนที่ตัดสินใจนั้นเท่านั้น — ถ้าเขายังอยู่

เราสร้างเวิร์กโฟลว์การขุดค้นที่ปิดวงจรนี้ การเปลี่ยนแปลงไหลผ่าน git commit ถูกประมวลผลโดย pipeline การขุดค้นของเรา กลายเป็นรายการบันทึกการเปลี่ยนแปลงที่มีโครงสร้างและบันทึกการตัดสินใจเชิงสถาปัตยกรรม แล้วป้อนกลับเข้าสู่ AI agent ของเราผ่านคำสั่ง CLI ผลลัพธ์คือ: ความทรงจำองค์กรที่ทั้งมนุษย์และ AI เข้าถึงได้

## ปัญหา: การตัดสินใจระเหยหายไป

พิจารณาสถานการณ์ทั่วไป นักพัฒนา commit ว่า:

```
feat(canonical): add DuckDB runtime for pipeline stages
```

commit นี้แทนการเลือกเชิงสถาปัตยกรรมที่สำคัญ ทีมประเมินตัวเลือก พิจารณาข้อแลกเปลี่ยน และลงเอยที่ DuckDB ด้วยเหตุผลเฉพาะ แต่บริบททั้งหมดนั้นอยู่ใน:

- เธรด Slack (น่าจะถูกลบไปแล้ว)
- ความทรงจำของใครบางคน (ที่กำลังจางหายแน่นอน)
- คอมเมนต์ในโค้ด (บางทีถ้าคุณโชคดี)

สามเดือนต่อมา สมาชิกทีมใหม่ถามว่า "ฉันควรใช้ DuckDB หรือ SQLite สำหรับสเตจใหม่นี้" หากไม่มีความทรงจำองค์กร พวกเขาจะต้องเริ่มคิดวิธีแก้ปัญหาเดิมตั้งแต่ต้น หรือเลือกอย่างไม่สอดคล้องกัน

## วงจร: จาก Commit สู่บริบท

เวิร์กโฟลว์การขุดค้นของเราแปลงประวัติ git ให้เป็นความรู้ที่ค้นหาได้:

```
Git Commits
    │
    ▼
┌─────────────────────┐
│  mine sync          │  ← Build index from git history
└─────────────────────┘
    │
    ▼
┌─────────────────────┐
│  mine candidates    │  ← Surface commits for review
└─────────────────────┘
    │
    ▼
┌─────────────────────┐
│  Classification     │  ← Human or LLM assessment
│  (changelog or ADR) │
└─────────────────────┘
    │
    ├──────────────────────┐
    ▼                      ▼
┌─────────────┐    ┌───────────────┐
│ Changelog   │    │ Decisions     │
│ Ledger      │    │ Registry      │
│ (JSONL)     │    │ (YAML files)  │
└─────────────┘    └───────────────┘
    │                      │
    ▼                      ▼
┌─────────────┐    ┌───────────────┐
│ CHANGELOG.md│    │ orkestra CLI  │
│ per package │    │ queries       │
└─────────────┘    └───────────────┘
    │                      │
    └──────────────────────┘
              │
              ▼
      ┌───────────────┐
      │ AI Agents     │
      │ (via CLI)     │
      └───────────────┘
```

ข้อมูลเชิงลึกที่สำคัญ: ทั้งบันทึกการเปลี่ยนแปลงและการตัดสินใจเชิงสถาปัตยกรรมไหลมาจากประวัติ git เดียวกัน ประมวลผลผ่าน pipeline เดียวกัน สิ่งนี้ทำให้แน่ใจว่าไม่มีอะไรหลุดรอดไป

## การขุดค้นทำงานอย่างไร

### ขั้นที่ 1: ซิงค์ดัชนี

```bash
uv run orkestra mine sync
```

คำสั่งนี้สแกนประวัติ git และสร้างดัชนีของ commit ทั้งหมด มันดึงสัญญาณเชิงโครงสร้างจากแต่ละ commit:

- ประเภท conventional commit (`feat`, `fix`, `chore`, `docs`)
- ขอบเขต (แพ็กเกจหรือพื้นที่ไหน)
- เครื่องหมาย breaking change
- ไฟล์ที่ถูกแตะและเมตริกความซับซ้อน

### ขั้นที่ 2: ตรวจสอบสถานะความครอบคลุม

```bash
uv run orkestra mine status
```

นี่คือสถานะปัจจุบันของเรา:

```
Mining Status
=============

Decisions
---------
  Coverage:        100.0%
    Processed:     15637  (of 15637)
    Extracted:       476
    Skipped:       15161

Changelog
---------
  Coverage:        100.0%
    Processed:     15637  (of 15637)
    Released:       6799
    Skipped:        8838
```

commit 15,637 รายการได้รับการประมวลผลแล้ว 476 รายการกลายเป็นการตัดสินใจเชิงสถาปัตยกรรม 6,799 รายการกลายเป็นรายการบันทึกการเปลี่ยนแปลง ทุก commit ถูกจำแนกแล้ว

### ขั้นที่ 3: รับตัวเลือกเพื่อรีวิว

```bash
uv run orkestra mine candidates --limit 50 --full
```

สิ่งนี้แสดง commit ที่ยังไม่ถูกประมวลผล พร้อมบริบทเต็มสำหรับการจำแนก:

```json
{
  "sha": "90571786d99166c0039ca2e80e4d9cd96184bd85",
  "date": "2026-01-26",
  "subject": "feat(canonical): add DuckDB runtime for pipeline stages",
  "signals": {
    "commit_type": "feat",
    "scope": "canonical",
    "breaking": false,
    "is_releasable_type": true,
    "domains_affected": ["pipeline", "data-architecture"]
  },
  "body": "Establishes DuckDB as canonical in-process analytical database...",
  "files_changed": ["packages/canonical/pipelines/stages/duckdb_runtime.py", "..."],
  "stats": {"files": 8, "insertions": 450, "deletions": 120}
}
```

สัญญาณช่วยชี้แนวทางการจำแนก: `is_releasable_type: true` บ่งบอกว่านี่ควรปรากฏในบันทึกการเปลี่ยนแปลง จำนวนบรรทัดที่เพิ่มขึ้นมากและไฟล์โครงสร้างพื้นฐานบ่งบอกว่ามันอาจเป็นการตัดสินใจเชิงสถาปัตยกรรมด้วย

### ขั้นที่ 4: จำแนก Commit

สองเส้นทางแยกจากกันที่นี่: รายการบันทึกการเปลี่ยนแปลงและการตัดสินใจเชิงสถาปัตยกรรม

**สำหรับรายการบันทึกการเปลี่ยนแปลง:**

```bash
uv run orkestra mine classify abc123 --changelog added
```

สิ่งนี้บันทึกว่า commit `abc123` ควรปรากฏในบันทึกการเปลี่ยนแปลงภายใต้หมวด "Added"

**สำหรับการตัดสินใจเชิงสถาปัตยกรรม:**

ก่อนอื่น รับ ID การตัดสินใจจริง:

```bash
uv run orkestra registry decisions new --domain pipeline --dry-run
# Returns: DEC-PL-143
```

จากนั้นจำแนกด้วย ID การตัดสินใจ:

```bash
uv run orkestra mine classify abc123 --decision DEC-PL-143
```

สิ่งนี้เชื่อมโยง commit เข้ากับบันทึกการตัดสินใจที่จะถูกสร้างหรืออัปเดต

**สำหรับการประมวลผลเป็นชุด (สิ่งที่เราทำจริงๆ):**

```bash
# Generate classifications file with LLM assistance
uv run orkestra mine commit --input classifications.jsonl
```

รูปแบบ JSONL รองรับทั้งสองโดเมนในรอบเดียว:

```jsonl
{"sha":"abc123","domain":"changelog","action":"release","category":"added","summary":"Add DuckDB runtime for pipeline stages"}
{"sha":"abc123","domain":"decisions","action":"extract","decision_id":"DEC-PL-142"}
{"sha":"def456","domain":"changelog","action":"skip","reason":"Chore: dependency update"}
```

### ขั้นที่ 5: เรนเดอร์ผลลัพธ์

```bash
uv run orkestra registry changelog render --package <pkg>
```

สิ่งนี้สร้างไฟล์ `CHANGELOG.md` ต่อแพ็กเกจ จาก ledger บันทึกการเปลี่ยนแปลง เป็นไฟล์ที่สร้างจากข้อมูลต้นทาง — ลบมันแล้วมันจะสร้างขึ้นใหม่ได้อย่างสมบูรณ์จาก ledger ต้นทาง

## โครงสร้างบันทึกการตัดสินใจ

การตัดสินใจที่ดึงออกมากลายเป็นไฟล์ YAML ที่มี metadata อันหลากหลาย:

```yaml
id: DEC-PL-142
title: Adopt DuckDB as Canonical Processing Runtime for Pipeline Stages
domain: pipeline
status: active
created: '2026-01-26'
summary: |
  Establishes DuckDB as the canonical in-process analytical database for pipeline
  stage transformations. Provides a shared runtime module that resolves settings
  from pipeline defaults with stage-level overrides.

context: |
  Pipeline stages performing data transformations each independently configured
  DuckDB connections. This led to inconsistent settings, duplicated configuration
  code, and no way to tune DuckDB globally for a pipeline run.

rationale:
  - DuckDB provides efficient in-process OLAP with zero configuration deployment
  - Centralized runtime module eliminates duplicated DuckDB setup across stages
  - Hierarchical settings enable global tuning with stage-level overrides
  - Memory limits and thread counts can be adjusted per-pipeline

impact:
  positive:
    - Consistent DuckDB configuration across all pipeline stages
    - Single point of control for memory/thread tuning
    - Reduced code duplication in conversion and export stages
  negative:
    - Adds dependency on shared runtime module
    - Stages must adopt new configuration pattern

source_commits:
  - sha: 90571786d99166c0039ca2e80e4d9cd96184bd85
    message: 'feat(canonical): add DuckDB runtime for pipeline stages'
    date: '2026-01-26'
    role: primary

files:
  - packages/canonical/pipelines/stages/duckdb_runtime.py
  - packages/canonical/pipelines/runner.py
  - packages/canonical/pipelines/stages/convert_hdx_admin_boundaries_to_geoparquet.py

related:
  - DEC-DA-014  # Data architecture decisions that influenced this
```

ทุกการตัดสินใจเชื่อมโยงกลับไปยัง commit ต้นทาง ทุกการตัดสินใจระบุว่าไฟล์ไหนได้รับผลกระทบ ความสัมพันธ์ระหว่างการตัดสินใจถูกทำให้ชัดเจน

## การผสานรวมกับ CLI: การคิวรีความทรงจำองค์กร

นี่คือจุดที่วงจรปิดลง agent สามารถคิวรีการตัดสินใจผ่าน CLI ได้:

```bash
# Search by topic
uv run orkestra registry decisions search --query "retry"
```

คืนการตัดสินใจเกี่ยวกับตรรกะการลองซ้ำ, การจัดการข้อผิดพลาด, รูปแบบการกู้คืน

```bash
# Get full details on a specific decision
uv run orkestra registry decisions info DEC-PL-142
```

คืนบันทึกการตัดสินใจฉบับสมบูรณ์พร้อมบริบท เหตุผล และผลกระทบ

```bash
# List recent decisions for context
uv run orkestra registry decisions list --limit 15
```

แสดงว่าการเลือกเชิงสถาปัตยกรรมใดถูกทำล่าสุด

### Agent ใช้สิ่งนี้อย่างไร

คำสั่งพื้นฐานของออร์เคสเตรเตอร์ของเรารวมถึง:

```markdown
**Essential CLI commands:**
- `orkestra registry decisions search "X"` — Find architectural decisions
```

เมื่อ agent ถูกขอให้นำสิ่งที่เกี่ยวข้องกับ DuckDB ไปใช้งานจริง มันสามารถตรวจสอบก่อนได้ว่า:

```bash
uv run orkestra registry decisions search --query "DuckDB"
```

และค้นพบ DEC-PL-142 เรียนรู้ว่า:
- ทำไมเราถึงเลือก DuckDB (บริบท)
- ใช้มันอย่างถูกต้องอย่างไร (agent_guidance)
- ไฟล์ไหนที่ต้องดู (files)
- การตัดสินใจที่เกี่ยวข้องมีอะไรบ้าง (related)

agent ไม่ต้องเริ่มคิดวิธีแก้ปัญหาเดิมตั้งแต่ต้น มันต่อยอดจากรูปแบบที่วางไว้แล้ว

## แบบทดสอบสามคำถาม

ไม่ใช่ทุก commit ที่สมควรมีบันทึกการตัดสินใจ เราใช้แบบทดสอบสามคำถามเพื่อคัดกรอง:

1. **สิ่งนี้ตัดสินใจยากไหม?** มันต้องการการวิเคราะห์อย่างมีนัยสำคัญ การประเมินข้อแลกเปลี่ยน หรือการถกเถียงหรือไม่?
2. **การเปลี่ยนการตัดสินใจนี้มีต้นทุนสูงไหม?** การกลับคำตัดสินใจนี้จะต้องทำงานใหม่อย่างมีนัยสำคัญหรือไม่?
3. **มันมีผลกระทบระดับระบบไหม?** มันส่งผลต่อหลายแพ็กเกจหรือสร้างรูปแบบที่คนอื่นจะทำตามหรือไม่?

หาก commit ตอบว่า "ใช่" อย่างน้อยหนึ่งในคำถามเหล่านี้ มันคือตัวเลือกสำหรับการดึงการตัดสินใจ อัตราทั่วไปของเรา: 1-4 การตัดสินใจต่อ 100 commit (ประมาณ 1-4%)

สำหรับรายการบันทึกการเปลี่ยนแปลง เกณฑ์ต่ำกว่า: การเปลี่ยนแปลงที่ผู้ใช้เห็น (ฟีเจอร์, การแก้ไข, การปรับปรุง) จะถูกบันทึกไว้ งานภายใน, การอัปเดตเอกสาร และการรีแฟกเตอร์มักถูกข้ามไป อัตราทั่วไปของเรา: 30-50 รายการบันทึกการเปลี่ยนแปลง ต่อ 100 commit

## การจัดเก็บข้อมูล: Ledger แบบเพิ่มได้อย่างเดียว

ระบบการขุดค้นใช้ ledger แบบ JSONL ที่เพิ่มได้อย่างเดียวเพื่อการทำงานหลาย agent โดยไม่มีความขัดแย้ง:

```
packages/orchestration/ai_assets/reference/changelog/
├── commits_processed.jsonl  # Classification ledger (both domains)
├── release_notes.jsonl      # Changelog entries
└── commits_index.yaml       # Derived index (gitignored)

packages/orchestration/ai_assets/reference/decisions/
├── registry.yaml            # Decision index
└── records/
    ├── DEC-AD-001.yaml
    ├── DEC-AD-002.yaml
    └── ...
```

รูปแบบ JSONL พร้อม `merge=union` ใน `.gitattributes` หมายความว่า agent หลายตัวสามารถจำแนก commit พร้อมกันได้โดยไม่มีความขัดแย้งจากการผสาน แต่ละบรรทัดเป็นอิสระจากกัน

## เกณฑ์การตรวจสอบ

ก่อนทุกเซสชันการขุดค้น เรารันการตรวจสอบ:

```bash
uv run orkestra mine validate --quick
```

สิ่งนี้ตรวจสอบ:
- ความถูกต้องของรูปแบบ SHA
- การปฏิบัติตามรูปแบบ ID การตัดสินใจ
- ไม่มีรายการซ้ำสำหรับ SHA เดียวกัน
- การตัดสินใจที่ถูกอ้างอิงมีอยู่จริง

หลังจากการจำแนก เราตรวจสอบอีกครั้งก่อน commit การเปลี่ยนแปลง

## เหตุใดสิ่งนี้จึงสำคัญ

ลูปป้อนกลับที่เราสร้างขึ้นแก้ปัญหาหลายอย่าง:

**สำหรับสมาชิกทีมใหม่:** แทนที่จะถามว่า "ทำไมเราถึงทำ X" พวกเขาสามารถค้นหารีจิสทรีการตัดสินใจได้ บริบทถูกเก็บรักษาไว้

**สำหรับ AI agent:** พวกมันไม่ได้ทำงานในสุญญากาศ พวกมันสามารถคิวรีความรู้องค์กรก่อนให้คำแนะนำได้ เมื่อถูกขอให้เพิ่ม pipeline stage ใหม่ พวกมันสามารถค้นพบรูปแบบ DuckDB และทำตามได้

**สำหรับความสอดคล้องเชิงสถาปัตยกรรม:** การตัดสินใจชัดเจนและค้นหาได้ เมื่อมีคนเสนอวิธีที่ขัดแย้งกับการตัดสินใจที่มีอยู่ ระบบสามารถแสดงความขัดแย้งนั้นได้

**สำหรับการสร้างบันทึกการเปลี่ยนแปลง:** บันทึกการปล่อยใช้งานไม่ใช่การรีบทำนาทีสุดท้าย มันคือผลพลอยได้จากการจำแนกอย่างต่อเนื่องระหว่างการพัฒนา

**สำหรับการออนบอร์ด:** agent ใหม่รับช่วงบริบททั้งหมดของโค้ดเบส พวกมันไม่ได้แค่เห็นโค้ด — พวกมันเห็นการตัดสินใจที่หล่อหลอมมันด้วย

## สถานะปัจจุบัน

ณ วันนี้:
- **15,637 commit** ผ่านการประมวลผลใน pipeline
- **476 การตัดสินใจเชิงสถาปัตยกรรม** ถูกดึงและบันทึกแล้ว
- **6,799 รายการบันทึกการเปลี่ยนแปลง** ถูกบันทึกแล้ว
- **ความครอบคลุม 100%** ข้ามทั้งสองโดเมน

ทุก commit ตั้งแต่เราเริ่มต้นถูกจำแนกแล้ว ความทรงจำองค์กรสมบูรณ์และค้นหาได้

## เริ่มต้นใช้งาน

หากคุณต้องการนำสิ่งที่คล้ายกันไปใช้จริง:

1. **เริ่มด้วย conventional commit** pipeline การขุดค้นทำงานได้ดีที่สุดเมื่อ commit มีคำนำหน้าที่มีโครงสร้าง (`feat:`, `fix:`, `chore:`)

2. **นิยามโดเมนของคุณ** เราใช้โดเมนอย่าง `pipeline`, `agent-design`, `observability`, `data-modeling` สิ่งเหล่านี้จัดระเบียบการตัดสินใจตามพื้นที่

3. **สร้างนิสัยการจำแนก** การขุดค้นทำงานได้เมื่อทีมจำแนก commit อย่างสม่ำเสมอ การประมวลผลเป็นชุดด้วยความช่วยเหลือของ LLM ช่วยให้ขยายสเกลได้

4. **ทำให้คิวรีการตัดสินใจได้** คุณค่าจะทวีคูณเมื่อ agent สามารถค้นหาการตัดสินใจผ่าน CLI ได้ จัดโครงสร้างผลลัพธ์ของคุณให้เครื่องอ่านได้

5. **ปิดวงจร** การตัดสินใจควรมีอิทธิพลต่องานในอนาคต รวมการอ้างอิงการตัดสินใจไว้ในคำสั่งของ agent และรายการตรวจสอบการรีวิวโค้ด

เป้าหมายไม่ใช่เอกสารที่สมบูรณ์แบบ แต่คือการทำให้ *เหตุผล* เบื้องหลังการเปลี่ยนแปลงเข้าถึงได้ทั้งมนุษย์และ AI ทั้งวันนี้และหกเดือนจากนี้ เมื่อการเปลี่ยนแปลงกลายเป็นความทรงจำองค์กร ทีมจะต่อยอดจากรูปแบบที่วางไว้แล้ว แทนที่จะคิดค้นมันขึ้นมาใหม่

---

*เวิร์กโฟลว์การขุดค้นเป็นส่วนหนึ่งของเอนจินออร์เคสเตรชันของเรา โดยเฉพาะโมดูลเอนจินบริบทในแพ็กเกจออร์เคสเตรชันของเรา*
