ข้ามไปที่เนื้อหา
cd /blog

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

[สถาปัตยกรรม][เวิร์กโฟลว์]

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

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

ทุกทีมวิศวกรรมเผชิญความท้าทายเดียวกัน: การเปลี่ยนแปลงเกิดขึ้นตลอดเวลา แต่ เหตุผล เบื้องหลังการเปลี่ยนแปลงเหล่านั้นหายไป หกเดือนต่อมา มีคนถามว่า “ทำไมเราถึงเลือกใช้ 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: ซิงค์ดัชนี

uv run orkestra mine sync

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

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

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

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: รับตัวเลือกเพื่อรีวิว

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

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

on
{
  "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

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

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

uv run orkestra mine classify abc123 --changelog added

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

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

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

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

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

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

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

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

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

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

on
l
{"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: เรนเดอร์ผลลัพธ์

uv run orkestra changelog render --package <pkg>

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

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

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

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 ได้:

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

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

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

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

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

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

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

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

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

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

uv run orkestra 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 พร้อมกันได้โดยไม่มีความขัดแย้งจากการผสาน แต่ละบรรทัดเป็นอิสระจากกัน

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

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

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 ทั้งวันนี้และหกเดือนจากนี้ เมื่อการเปลี่ยนแปลงกลายเป็นความทรงจำองค์กร ทีมจะต่อยอดจากรูปแบบที่วางไว้แล้ว แทนที่จะคิดค้นมันขึ้นมาใหม่


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

อ่านเพิ่มเติมที่เกี่ยวข้อง

เนื้อหาอื่นๆ จากบันทึกการพัฒนา Maguyva

เหตุใดเราจึงอัปเกรดการค้นหาโค้ดเป็น voyage-4-large_

เราย้ายเอ็มเบดดิ้งโค้ดของเราไปที่ voyage-4-large — ปัจจุบันอยู่อันดับหนึ่งของตารางอันดับการค้นคืนโค้ด RTEB สาธารณะ ฉบับตรงไปตรงมา: การแลกเปลี่ยนที่เรายอมรับ สิ่งที่เราทำดัชนีจริง และเหตุผลที่เราจ่ายเงินเพื่อเอ็มเบดดิ้งระดับพรีเมียม

[เอ็มเบดดิ้ง][การค้นหา][สถาปัตยกรรม]

การพัฒนาตนเองเชิงเวียนซ้ำของภาษา: กรินด์ Code Intelligence ครอบคลุมเกือบ 280 ภาษา_

เรารองรับ code intelligence สำหรับเกือบ 280 ภาษา ไม่มีมนุษย์คนไหนตรวจสอบด้วยมือได้ทั้งหมดนั้น เราจึงสร้างลูปการพัฒนาตนเองเชิงเวียนซ้ำของภาษา — สุ่มตรวจ ใช้ LLM เป็นผู้ตัดสิน แก้ไขทีละจุด ตรวจสอบซ้ำ — และรันมันด้วยทีม agent ที่แยกจากกันจนกว่าการแตกโครงสร้างจะถูกต้องจริง ไม่ใช่แค่เขียวผ่าน

[สถาปัตยกรรม][ภาษา][เอเจนต์]

ค้นหาแบบผสานหลายโหมด: เลือกตัวค้นคืนที่ใช่สำหรับทุกคำค้น_

คำค้นอย่าง 'parseConfig ถูกนิยามที่ไหน' ต้องการการค้นหาที่ต่างจาก 'auth ทำงานอย่างไร' Maguyva จำแนกเจตนา ให้น้ำหนักทั้งสี่รูปแบบการค้นคืนตามนั้น แล้วรวมผลลัพธ์ด้วย weighted Reciprocal Rank Fusion

[การค้นหา][สถาปัตยกรรม]