wiki: Topic_Blog 신규 문서 일괄 추가 + ASTRA 성장 자산 동기화
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
---
|
||||
id: adr-0001-event-sourcing
|
||||
title: "ADR-0001 이벤트 소싱 채택"
|
||||
category: "Architecture_Decision"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["ADR event sourcing", "왜 이벤트 소싱", "append-only 결정", "JSONL 결정"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["adr", "event-sourcing", "decision", "persistence", "astraai"]
|
||||
raw_sources: ["AstraAI/src/features/_shared/eventSourcedStore.ts", "AstraAI/src/memory/types.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[ADR-0001 이벤트 소싱 채택]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
도메인 데이터(고객·채용·런웨이·피드백)를 "상태 덮어쓰기" 대신 **append-only JSONL 이벤트**로 저장하기로 결정했다 — 이력 보존·내결함·중복 제거(제네릭 팩토리)를 한 번에 얻기 위해 [S1].
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- **결정:** `createEventStore<E>` 제네릭 팩토리로 모든 도메인 스토어를 append-only JSONL 위에 구현.
|
||||
- **상태:** 현재 상태는 이벤트 재생(`computeStates`)으로 도출, 저장은 이벤트만.
|
||||
- 자세한 구현은 [[이벤트 소싱 스토어 패턴]] 참조.
|
||||
|
||||
## 📖 세부 내용 (Details · ADR)
|
||||
### Problem (문제)
|
||||
customers/hire/runway/feedback 4개 도메인이 각자 `getXFilePath/readX/appendX/countX` 를 복붙해 ~240줄 byte-for-byte 중복. 동시에 "언제 무엇이 바뀌었나" 이력이 필요한 도메인인데 마지막 상태만 저장하면 그 정보를 잃는다 [S1].
|
||||
|
||||
### Context (맥락)
|
||||
- 단일 사용자 로컬 VS Code 확장 — 무거운 DB 운영 비용을 감당할 이유가 적다.
|
||||
- 데이터 규모가 작고(수백~수천 행), 사람이 직접 파일을 열어보는 투명성이 가치.
|
||||
- 부분 손상(파일 1줄 깨짐)에도 나머지를 살려야 한다.
|
||||
|
||||
### Options Considered (고려한 대안)
|
||||
1. **상태 JSON 1개 덮어쓰기** — 단순하지만 이력 손실·동시쓰기 시 전체 덮어쓰기 위험.
|
||||
2. **SQLite** — 쿼리/인덱스 강력하지만 의존성·마이그레이션·운영 복잡도 추가.
|
||||
3. **append-only JSONL 이벤트 + 제네릭 팩토리** — 이력 보존 + 한 줄 추가의 단순함 + 내결함.
|
||||
|
||||
### Chosen Solution (선택)
|
||||
3번. `createEventStore<E>({ relPath, validate })` 가 read/append/count/getFilePath 를 제공하고, 도메인은 이벤트 타입 `E` 와 `computeStates` 만 정의 [S1].
|
||||
|
||||
### Why It Was Chosen (선택 이유)
|
||||
- 이력이 그 자체로 가치 있는 도메인에 자연스럽다.
|
||||
- 제네릭으로 4벌 중복을 1벌로 — BOM/인코딩 fix 도 한 곳에서 전파.
|
||||
- 한 줄 손상이 전체를 무력화하지 않는 내결함(파싱 실패 줄 skip).
|
||||
- 외부 의존 0 (Node fs 만) — 번들 가벼움 유지.
|
||||
|
||||
### Benefits (장점)
|
||||
이력 감사·재현·디버깅 용이, 단순한 append I/O, 사람이 읽고 고칠 수 있는 투명성, 타입 안전한 재사용.
|
||||
|
||||
### Drawbacks (단점)
|
||||
파일이 단조 증가(compaction 없음), 현재 상태를 매번 재생하는 비용, 멀티프로세스 동시 append 는 별도 잠금 필요.
|
||||
|
||||
### Future Risks (미래 위험)
|
||||
- 이벤트 수가 수만을 넘으면 재생 비용/메모리 증가 → 스냅샷+증분 compaction 필요.
|
||||
- 이벤트 스키마 진화 시 구버전 이벤트 호환(버전 필드/업캐스팅) 관리 부담.
|
||||
|
||||
### Alternative Approaches (대안 접근)
|
||||
규모가 커지면 SQLite(+WAL)로 이전하거나, 이벤트는 유지하되 주기적 스냅샷을 도입. 읽기 빈도가 매우 높으면 메모리 캐시 + 파일 watch.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"이력 보존" 이 목표가 아니라면(마지막 값만 중요) 이 결정은 과설계다. 그 경우 상태 1개 파일이 더 단순하다.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
`AstraAI/src/features/_shared/eventSourcedStore.ts` — 결정의 구현체 [S1].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[이벤트 소싱 스토어 패턴]], [[Event Bus Pattern]], [[ADR-0005 파일 기반 저장 채택]], [[엔지니어링 트레이드오프 분석]]
|
||||
- **참조 맥락:** 로컬 LLM 이 "이력 저장 vs 상태 저장" 을 결정할 때 판단 근거로 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/features/_shared/eventSourcedStore.ts — 제네릭 이벤트 스토어, 중복 통합 배경 주석
|
||||
- [S2] AstraAI/src/memory/types.ts — 버전 필드 직렬화 스토어
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 코드 분석 기반 ADR 작성.
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: adr-0002-memory-layer-separation
|
||||
title: "ADR-0002 5계층 메모리 분리"
|
||||
category: "Architecture_Decision"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["ADR memory layers", "왜 메모리를 분리", "메모리 계층 결정"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["adr", "memory", "decision", "ai", "astraai"]
|
||||
raw_sources: ["AstraAI/src/memory/index.ts", "AstraAI/src/memory/types.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[ADR-0002 5계층 메모리 분리]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
에이전트의 "기억"을 단일 저장소가 아니라 **시간 범위·용도가 다른 5계층(단기·장기·프로젝트·절차·일화)**으로 분리하기로 결정했다 — 계층마다 검색·만료·승급 정책이 달라야 하기 때문 [S1].
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- **결정:** MemoryManager 가 5개 독립 계층을 보유, 각 계층이 query 에 대해 관련도를 매겨 컨텍스트에 합침.
|
||||
- 구현 상세는 [[5계층 메모리 시스템]] 참조.
|
||||
|
||||
## 📖 세부 내용 (Details · ADR)
|
||||
### Problem
|
||||
모든 기억을 한 통에 넣으면 "현재 대화"·"사용자 영구 취향"·"프로젝트 결정"·"반복 절차"·"과거 세션 요약"이 같은 정책으로 다뤄진다. 그러나 이들은 수명·만료·우선순위·검색 방식이 전부 다르다 [S1].
|
||||
|
||||
### Context
|
||||
- 로컬 작은 모델은 컨텍스트 한도가 작아, 무엇을 넣을지 *정교한 선별* 이 필수.
|
||||
- 시한부 지식(분기 계획)과 영구 지식(사용자 선호)이 공존.
|
||||
- 과거 세션을 "지난번에 한 일"로 떠올릴 수 있어야 한다.
|
||||
|
||||
### Options Considered
|
||||
1. **단일 메모리 버퍼(최근 N 메시지)** — 단순하나 장기·프로젝트·절차 기억 불가.
|
||||
2. **벡터 DB 단일 저장** — 의미 검색은 좋지만 만료·승급·계층별 정책 표현이 어렵고 인프라 부담.
|
||||
3. **역할별 5계층 분리 + 통합 매니저** — 계층별 정책 + 단일 진입점.
|
||||
|
||||
### Chosen Solution
|
||||
3번. 단기(FIFO)·장기(category/confidence/expiresAt)·프로젝트(workspace별 ADR/버그)·절차(trigger→steps)·일화(세션 요약, distillation 승급) [S1][S2].
|
||||
|
||||
### Why It Was Chosen
|
||||
계층마다 다른 정책을 자연스럽게 표현(만료, 승급, lazy 생성). 컨텍스트 예산이 빠듯한 작은 모델에 "관련도 높은 계층부터" 선별 주입 가능. 인간 인지 메타포로 이해·확장 용이.
|
||||
|
||||
### Benefits
|
||||
정밀한 컨텍스트 선별, 시한부/영구 지식 공존, 일화→장기 증류로 자동 정리, RAG 소스로 통합 가능.
|
||||
|
||||
### Drawbacks
|
||||
계층 경계의 모호성(장기 decision vs 프로젝트 ADR), 매니저 조립 복잡도, 계층별 저장 파일 증가.
|
||||
|
||||
### Future Risks
|
||||
계층이 더 늘면(예: 감정/사회적 기억) 관리 폭증. 관련도 점수가 휴리스틱이라 잘못 선별 시 핵심 기억 누락 가능.
|
||||
|
||||
### Alternative Approaches
|
||||
의미 검색이 핵심이면 각 계층 *내부* 에 임베딩을 도입(하이브리드)하거나, 계층 수를 3개(작업·세션·영구)로 단순화. 대규모면 벡터 DB + 메타데이터 필드로 계층을 표현.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
계층이 많을수록 표현력은 커지나 "어디에 저장할지" 결정 비용도 커진다 — 명확한 분류 규칙([[아키텍처 휴리스틱]])이 없으면 오히려 혼란.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
`AstraAI/src/memory/index.ts`, `types.ts` [S1][S2].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[5계층 메모리 시스템]], [[Memory Pattern]], [[아키텍처 휴리스틱]], [[엔지니어링 트레이드오프 분석]]
|
||||
- **참조 맥락:** 로컬 LLM 이 에이전트 메모리 구조를 설계할 때 "한 통 vs 계층 분리" 판단에 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/memory/index.ts — MemoryManager 5계층 통합
|
||||
- [S2] AstraAI/src/memory/types.ts — 계층별 타입·만료·승급 필드
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 코드 분석 기반 ADR 작성.
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
id: adr-0003-single-writer-multi-role
|
||||
title: "ADR-0003 단일작성자 다중역할 멀티에이전트"
|
||||
category: "Architecture_Decision"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["ADR multi-agent", "왜 병렬 persona 를 버렸나", "ChunkedWriter 결정", "멀티에이전트 결정"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["adr", "multi-agent", "decision", "ai", "astraai"]
|
||||
raw_sources: ["AstraAI/src/agents/AgentWorkflowManager.ts", "AstraAI/src/features/company/dispatcher.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[ADR-0003 단일작성자 다중역할 멀티에이전트]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
"여러 persona 를 병렬/직렬로 줄세우는 멀티에이전트" 대신, 일반 작성 작업은 **단일 작성자가 outline→section→polish 역할을 번갈아 수행**하고, 진짜 다중 전문가가 필요한 회사 모드는 **순차 디스패치(한 번에 한 모델 상주)**로 가기로 결정했다 [S1][S2].
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- **결정 1:** 5-persona 파이프라인 폐기 → 단일 `ChunkedWriter` 다중 역할.
|
||||
- **결정 2:** 다중 전문가는 병렬이 아니라 순차 + peer-context 전달.
|
||||
- 구현은 [[Agent 오케스트레이터 분해]] 참조.
|
||||
|
||||
## 📖 세부 내용 (Details · ADR)
|
||||
### Problem
|
||||
초기 planner/researcher/reflector/writer/synthesizer 5-persona 파이프라인은 (1) hop 마다 컨텍스트가 누적되고 (2) 원본 본문이 추상화로 손실돼, 사용자가 본문 분석을 요청해도 "분석 방법론" 만 만들어내는 사고가 났다 [S1]. 또 병렬 에이전트는 단일 GPU/제한 RAM 에서 여러 모델을 동시 상주시켜야 한다 [S2].
|
||||
|
||||
### Context
|
||||
- 타깃 환경: 단일 GPU/CPU, 제한된 RAM, 로컬 작은 모델(gemma 등).
|
||||
- LM Studio lifecycle 매니저가 모델 load/unload 를 관리 — "한 번에 하나" 가 자연스럽다.
|
||||
- 작업 종류: 대부분 단일 문서 작성, 일부만 진짜 다중 전문가 협업(회사 모드).
|
||||
|
||||
### Options Considered
|
||||
1. **병렬 멀티에이전트(persona N개 동시)** — 빠르지만 모델 다중 상주·자원 폭주, 컨텍스트/본문 손실.
|
||||
2. **직렬 5-persona 파이프라인** — 자원은 낫지만 hop 누적·본문 추상화 손실(실제 발생한 사고).
|
||||
3. **단일 작성자 다중 역할(+필요 시 순차 전문가)** — 컨텍스트 작고 본문 직접 전달, 한 모델만 상주.
|
||||
|
||||
### Chosen Solution
|
||||
3번. 일반 작성은 `ChunkedWriter`(outline/section/polish 한 모델 번갈아). 다중 전문가는 company `dispatcher` 가 CEO 플래너→전문가 순차(peer-context 잘라 전달)→CEO 리포터 [S1][S2].
|
||||
|
||||
### Why It Was Chosen
|
||||
- 본문이 매 호출에 직접 전달돼 손실 없음(초기 사고의 직접 해결).
|
||||
- 각 호출이 작아 작은 모델의 컨텍스트 한도를 지킴.
|
||||
- "정확히 한 모델만 상주" 로 VRAM 안전 + lifecycle 단순.
|
||||
|
||||
### Benefits
|
||||
자원 안전, 본문 보존, 컨텍스트 폭증 방지, 디버깅 단순(한 번에 한 단계).
|
||||
|
||||
### Drawbacks
|
||||
총 응답 시간이 길다(순차). 단일 모델 품질에 결과가 좌우된다. 병렬로 얻는 다양성·속도를 포기.
|
||||
|
||||
### Future Risks
|
||||
작업이 진짜 병렬성을 요구하거나(대규모 리서치), 멀티 GPU 환경이 표준이 되면 이 결정이 병목이 된다.
|
||||
|
||||
### Alternative Approaches
|
||||
자원이 충분하면 병렬 persona + 합의(judge panel). 또는 역할별로 작은 특화 모델을 동시에. 속도가 critical 하면 outline/section 을 병렬화하고 polish 만 직렬.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"멀티에이전트가 항상 낫다" 는 통념과 반대다 — *자원 제약 하에서는* 잘 구성된 단일 작성자가 어설픈 병렬 파이프라인보다 낫다는 실측 교훈. 환경이 바뀌면 재평가 대상.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
`AgentWorkflowManager.ts`(ChunkedWriter), `company/dispatcher.ts`(순차) [S1][S2].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[Agent 오케스트레이터 분해]], [[Agent Orchestration Pattern]], [[ADR-0004 순차 디스패치 채택]], [[엔지니어링 트레이드오프 분석]]
|
||||
- **참조 맥락:** 로컬 LLM 이 멀티에이전트를 도입할지/어떻게 구성할지 자원 제약 하에 판단할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/agents/AgentWorkflowManager.ts — 5-persona 폐기 post-mortem, ChunkedWriter
|
||||
- [S2] AstraAI/src/features/company/dispatcher.ts — 순차 디스패치 근거
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 코드 분석 기반 ADR 작성.
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: adr-0004-sequential-dispatch
|
||||
title: "ADR-0004 순차 디스패치 채택"
|
||||
category: "Architecture_Decision"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["ADR sequential dispatch", "왜 순차 실행", "한 번에 한 모델"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["adr", "concurrency", "decision", "resource", "astraai"]
|
||||
raw_sources: ["AstraAI/src/features/company/dispatcher.ts", "AstraAI/src/lmstudio/lifecycleManager.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[ADR-0004 순차 디스패치 채택]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
다중 에이전트/모델 작업을 **순차로 실행하고 한 번에 정확히 하나의 모델만 메모리에 상주**시키기로 결정했다 — 단일 GPU/제한 RAM 에서 병렬은 여러 모델 동시 로드를 강요해 OOM·스왑을 부르기 때문 [S1].
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- **결정:** company 턴은 전문가를 순차 실행, LM Studio lifecycle 가 이전 모델 unload → 다음 load.
|
||||
- 무거운 LLM 작업은 `missionId` 락으로도 직렬화.
|
||||
|
||||
## 📖 세부 내용 (Details · ADR)
|
||||
### Problem
|
||||
병렬 에이전트는 동시에 여러 모델을 상주시켜야 하는데, 타깃 사용자는 단일 GPU/제한 RAM 으로 Astra 를 돌린다 → 동시 로드 시 메모리 초과/스왑/로드 실패 [S1].
|
||||
|
||||
### Context
|
||||
로컬 우선 설계, 작은 모델, LM Studio SDK 의 load/unload 수명관리. 응답 지연보다 *동작 보장* 이 우선.
|
||||
|
||||
### Options Considered
|
||||
1. **병렬 실행** — 빠르지만 다중 모델 상주 필요(자원 초과).
|
||||
2. **순차 + 매번 같은 모델** — 단순하나 역할별 특화 모델 사용 불가.
|
||||
3. **순차 + 에이전트별 모델 override(lifecycle unload/load)** — 한 번에 하나, 역할별 모델 가능.
|
||||
|
||||
### Chosen Solution
|
||||
3번. 전문가마다 모델 override 가능, 디스패처가 순차로 돌며 lifecycle 가 교체. peer-context 를 잘라 다음 에이전트에 전달 [S1].
|
||||
|
||||
### Why It Was Chosen
|
||||
"한 모델만 상주" 불변식이 자원 안전을 보장하고, 그러면서도 단계별 최적 모델을 쓸 수 있다.
|
||||
|
||||
### Benefits
|
||||
OOM 회피, 예측 가능한 메모리, 역할별 모델 유연성, 진행 단계 가시화 용이.
|
||||
|
||||
### Drawbacks
|
||||
총 시간이 길다(모델 교체 오버헤드 포함). 병렬 처리량 포기.
|
||||
|
||||
### Future Risks
|
||||
멀티 GPU/대용량 RAM 이 표준이 되면 과도한 제약. 작업 수가 많으면 누적 지연이 사용자 인내를 초과.
|
||||
|
||||
### Alternative Approaches
|
||||
자원 충분 시 워커 풀 + 모델 핀닝으로 병렬. 또는 빠른 단계는 작은 모델로 병렬, 합성만 큰 모델로 직렬(하이브리드).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
처리량 최적화와 정면 충돌하는 결정 — 환경(자원)이 전제이므로, 서버 배포 시엔 [[엔지니어링 트레이드오프 분석]] 기준으로 재검토.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
`company/dispatcher.ts` 의 순차 루프 + lifecycle [S1].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[ADR-0003 단일작성자 다중역할 멀티에이전트]], [[동시성 제어 Lock Queue Transaction]], [[Background Worker Pattern]]
|
||||
- **참조 맥락:** 로컬 LLM 이 자원 제약 환경에서 병렬 vs 순차를 결정할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/features/company/dispatcher.ts — "Why sequential?" 근거 주석
|
||||
- [S2] AstraAI/src/lmstudio/lifecycleManager.ts — 모델 load/unload 수명관리
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 코드 분석 기반 ADR 작성.
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
id: adr-0005-file-based-storage
|
||||
title: "ADR-0005 파일 기반 저장 채택"
|
||||
category: "Architecture_Decision"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["ADR storage", "왜 DB 안 쓰나", "Markdown JSONL 저장", "파일 저장 결정"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.89
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["adr", "storage", "decision", "filesystem", "astraai"]
|
||||
raw_sources: ["AstraAI/src/core/services.ts", "AstraAI/src/features/_shared/eventSourcedStore.ts", "AstraAI/src/intelligence/correctionLoop.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[ADR-0005 파일 기반 저장 채택]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
지식·메모리·로그를 DB 가 아니라 **Markdown(.md) + JSON/JSONL 파일**로 저장하기로 결정했다 — 사람이 직접 열어 읽고/고치는 투명성(Permission Based Learning)과 무의존성이 단일 사용자 로컬 도구에 최적이기 때문 [S1][S3].
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- **결정:** brain 지식=Markdown(frontmatter), 이벤트/케이스=JSONL, 설정/프로필=JSON.
|
||||
- 검색은 파일 위 TF-IDF/임베딩 인덱스([[RAG 검색 파이프라인]]).
|
||||
|
||||
## 📖 세부 내용 (Details · ADR)
|
||||
### Problem
|
||||
지식/메모리/학습 데이터를 어디에 저장할 것인가. DB 는 강력하지만 단일 사용자 로컬 확장에 운영·마이그레이션·불투명성 비용을 더한다.
|
||||
|
||||
### Context
|
||||
- 사용자가 두뇌 내용을 직접 보고 수정/삭제할 수 있어야 한다(투명성·신뢰).
|
||||
- VS Code/에디터로 그대로 열람 가능해야(Markdown).
|
||||
- 번들 의존성 최소화(런타임 deps 2개).
|
||||
|
||||
### Options Considered
|
||||
1. **SQLite/임베디드 DB** — 쿼리·트랜잭션 강력, 그러나 불투명·의존성·스키마 관리.
|
||||
2. **벡터 DB** — 의미 검색 최적, 그러나 인프라·운영 부담, 사람이 못 읽음.
|
||||
3. **파일 기반(Markdown + JSONL + JSON)** — 투명·무의존·버전관리(git) 친화.
|
||||
|
||||
### Chosen Solution
|
||||
3번. 지식은 frontmatter 달린 Markdown, 이벤트/정정 케이스는 append-only JSONL, 프로필/설정은 JSON. 검색은 파일 위 인덱스로 보강 [S1][S2][S3].
|
||||
|
||||
### Why It Was Chosen
|
||||
사람이 읽고 고치는 투명성이 신뢰의 핵심(특히 자기학습 시스템). git diff 로 변경 추적. 의존성 0 으로 배포 단순.
|
||||
|
||||
### Benefits
|
||||
투명성, 무의존, git 친화, 에디터 직접 열람, 백업/이동 단순(폴더 복사).
|
||||
|
||||
### Drawbacks
|
||||
복잡한 쿼리/조인 불가, 대량 데이터에서 스캔 비용, 동시쓰기 잠금 직접 관리, 인덱스를 직접 구축해야 함.
|
||||
|
||||
### Future Risks
|
||||
brain 이 수만 파일로 커지면 파일 스캔/인덱싱 비용 급증. 트랜잭션이 약해 다중 파일 일관성은 보상 트랜잭션에 의존.
|
||||
|
||||
### Alternative Approaches
|
||||
규모 확대 시 SQLite(메타데이터) + 파일(본문) 하이브리드, 또는 임베딩만 벡터 DB 로 외부화하고 본문은 파일 유지.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"검색·쿼리 성능" 만 보면 DB 가 우위다. 이 결정은 *투명성·무의존* 을 성능보다 우선한 가치 판단 — 멀티유저/대규모면 뒤집힌다.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
brain Markdown(BrainService.inject), JSONL 이벤트 스토어, corrections.jsonl / weakness-profile.json [S1][S2][S3].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[ADR-0001 이벤트 소싱 채택]], [[이벤트 소싱 스토어 패턴]], [[Local Storage Pattern]], [[Caching Pattern]]
|
||||
- **참조 맥락:** 로컬 LLM 이 "DB vs 파일" 저장 방식을 결정할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/core/services.ts — BrainService Markdown 저장
|
||||
- [S2] AstraAI/src/features/_shared/eventSourcedStore.ts — JSONL 이벤트
|
||||
- [S3] AstraAI/src/intelligence/correctionLoop.ts — JSONL/JSON 케이스·프로필(투명성)
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 코드 분석 기반 ADR 작성.
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
id: adr-0006-manual-di-interface-services
|
||||
title: "ADR-0006 수동 의존성주입과 인터페이스 서비스"
|
||||
category: "Architecture_Decision"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["ADR DI", "왜 DI 컨테이너 안 쓰나", "수동 주입 결정", "인터페이스 서비스 결정"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.89
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["adr", "dependency-injection", "decision", "architecture", "astraai"]
|
||||
raw_sources: ["AstraAI/src/extension.ts", "AstraAI/src/core/services.ts", "AstraAI/src/intelligence/criticAgent.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[ADR-0006 수동 의존성주입과 인터페이스 서비스]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
의존성 주입을 **DI 프레임워크 없이 entry point(`activate`)에서 손으로 조립**하고, 외부 효과를 가진 협력자는 **인터페이스/함수 타입으로 추상화**해 주입하기로 결정했다 — 조립 지점이 하나뿐이라 컨테이너의 비용이 불필요하기 때문 [S1][S2].
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- **결정:** 수동 생성자/함수/getter 주입 + IAIService/IBrainService/CritiqueLlmCall 추상화.
|
||||
- 구현 상세는 [[의존성 주입과 서비스 인터페이스]] 참조.
|
||||
|
||||
## 📖 세부 내용 (Details · ADR)
|
||||
### Problem
|
||||
협력자(AI 서비스, 스트리머, 큐, LLM 호출)를 객체가 직접 생성하면 결합이 강해지고 테스트가 어렵다. 그러나 DI 컨테이너는 학습·설정·런타임 마법 비용이 있다.
|
||||
|
||||
### Context
|
||||
조립 지점이 사실상 `activate` 한 곳. 모듈 수는 많지만 의존 그래프는 명시적. 테스트는 순수 함수 + 가짜 주입으로 충분.
|
||||
|
||||
### Options Considered
|
||||
1. **DI 컨테이너(tsyringe 등)** — 자동 해석/수명관리, 그러나 의존성·매직·디버깅 비용.
|
||||
2. **싱글톤 남발** — 간단하나 테스트 격리 불가, 숨은 결합.
|
||||
3. **수동 주입 + 인터페이스/함수 추상화** — 명시적, 무의존, 테스트 용이.
|
||||
|
||||
### Chosen Solution
|
||||
3번. 생성자 옵션 객체(`new AgentExecutor(ctx, {...})`), 함수 타입 주입(`CritiqueLlmCall`), getter 주입(`getProvider`). 전역이 본질인 자원만 싱글톤(lock/queue) [S1][S2].
|
||||
|
||||
### Why It Was Chosen
|
||||
조립이 한 곳이라 컨테이너의 이득이 작고, 수동 주입이 흐름을 가장 투명하게 만든다. 함수 주입으로 검증 모듈을 순수하게 유지(테스트 시 가짜 LLM).
|
||||
|
||||
### Benefits
|
||||
무의존·투명한 조립, 뛰어난 테스트성, 명시적 의존 그래프, 교체 용이.
|
||||
|
||||
### Drawbacks
|
||||
조립 코드가 장황(activate 가 큼), 의존이 늘면 수동 배선 부담, 수명관리 직접.
|
||||
|
||||
### Future Risks
|
||||
모듈/조립 지점이 폭증하면 수동 배선이 한계 → 부분적 컨테이너 도입 필요. 싱글톤은 테스트 격리를 점점 어렵게.
|
||||
|
||||
### Alternative Approaches
|
||||
규모 확대 시 경량 컨테이너 또는 팩토리 레이어. 또는 기능별 "composition root" 를 여러 개로 분리.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"엔터프라이즈엔 DI 컨테이너" 통념과 다르다 — 단일 composition root 소규모에선 수동 주입이 더 단순·명확. 규모가 결정 인자.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
`extension.ts`(수동 조립), `services.ts`(인터페이스), `criticAgent.ts`(함수 주입) [S1][S2][S3].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[의존성 주입과 서비스 인터페이스]], [[Repository Pattern]], [[엔지니어링 트레이드오프 분석]]
|
||||
- **참조 맥락:** 로컬 LLM 이 "DI 컨테이너 vs 수동 주입" 을 규모 기준으로 결정할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/extension.ts — activate 수동 조립, getter/옵션 주입
|
||||
- [S2] AstraAI/src/core/services.ts — IAIService/IBrainService
|
||||
- [S3] AstraAI/src/intelligence/criticAgent.ts — CritiqueLlmCall 함수 주입
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 코드 분석 기반 ADR 작성.
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: adr-0007-hybrid-retrieval-deterministic-first
|
||||
title: "ADR-0007 하이브리드 검색과 결정론 우선"
|
||||
category: "Architecture_Decision"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["ADR retrieval", "왜 TF-IDF 먼저", "하이브리드 검색 결정", "결정론 우선"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["adr", "rag", "retrieval", "decision", "astraai"]
|
||||
raw_sources: ["AstraAI/src/retrieval/index.ts", "AstraAI/src/retrieval/scoring.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[ADR-0007 하이브리드 검색과 결정론 우선]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
검색의 기본은 **TF-IDF(sparse)로 항상 동작**하게 하고, 임베딩(dense)은 *가용할 때만 가산 혼합* 하기로 결정했다 — 임베딩 엔진이 없거나 미색인이어도 검색이 절대 망가지지 않게 하기 위해 [S1].
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- **결정:** TF-IDF 기본 + 임베딩 blend(α). 벡터 없는 문서는 순수 sparse 유지.
|
||||
- 구현은 [[RAG 검색 파이프라인]], [[TF-IDF 이중언어 스코어링]] 참조.
|
||||
|
||||
## 📖 세부 내용 (Details · ADR)
|
||||
### Problem
|
||||
의미 검색(임베딩)은 강력하지만 임베딩 모델 가용성·색인 상태에 의존한다. 그것에만 의존하면 모델이 없을 때 검색이 죽는다. 반대로 키워드만 쓰면 환언/동의를 놓친다.
|
||||
|
||||
### Context
|
||||
로컬 환경에서 임베딩 모델이 있을 수도/없을 수도. brain 은 한/영 혼용. "검색은 언제나 동작" 이 신뢰의 기본.
|
||||
|
||||
### Options Considered
|
||||
1. **임베딩 단독(dense only)** — 의미 강하나 가용성·비용 의존, 무관 문서도 높은 cos.
|
||||
2. **키워드 단독(sparse only)** — 항상 동작·설명가능하나 환언 놓침.
|
||||
3. **하이브리드(결정론 우선 + 임베딩 가산)** — 기본 보장 + 의미 보강.
|
||||
|
||||
### Chosen Solution
|
||||
3번. TF-IDF 로 점수, 임베딩이 있으면 `(1-α)·sparse + α·dense`. 모든 후보를 maxTfidf 로 정규화(벡터 있는 것만 줄이면 안 됨), cosine 은 후보군 min-max 정규화 [S1].
|
||||
|
||||
### Why It Was Chosen
|
||||
가용성 보장(임베딩 없어도 동작), 설명가능(왜 매치됐는지), 그러면서 의미 검색의 이득을 더한다. 실측 버그(스케일 불일치)를 정규화로 해결.
|
||||
|
||||
### Benefits
|
||||
무중단 검색, 점진 도입(임베딩 색인이 늘수록 좋아짐), 설명가능, 한/영 교차 매칭(동의어 확장).
|
||||
|
||||
### Drawbacks
|
||||
스케일 정규화가 까다로움(2건의 실측 버그), 수작업 동의어 사전 유지, 형태소 분석 부재.
|
||||
|
||||
### Future Risks
|
||||
brain 규모↑ 시 sparse 인덱스 메모리·시간 증가. 동의어 사전 누락이 recall 을 갉아먹음.
|
||||
|
||||
### Alternative Approaches
|
||||
대규모면 BM25 + 벡터 DB 하이브리드, 또는 reranker 모델 도입. 한국어 정밀도가 critical 하면 형태소 분석기.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"임베딩이 최신이고 우월" 통념과 달리, *가용성·설명가능성* 을 위해 결정론을 1순위로 둔다 — 단, 의미 검색을 버리지 않고 가산.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
`retrieval/index.ts`(하이브리드 blend), `scoring.ts`(TF-IDF/토크나이저) [S1].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[RAG 검색 파이프라인]], [[TF-IDF 이중언어 스코어링]], [[RAG Pattern]], [[Caching Pattern]]
|
||||
- **참조 맥락:** 로컬 LLM 이 검색을 설계할 때 "dense only vs 하이브리드" 와 가용성 보장을 판단할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/retrieval/index.ts — 하이브리드 blend, 스케일 정규화 버그 기록
|
||||
- [S2] AstraAI/src/retrieval/scoring.ts — TF-IDF, 이중언어 토크나이저, 동의어
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 코드 분석 기반 ADR 작성.
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: adr-0008-local-first-llm-cloud-fallback
|
||||
title: "ADR-0008 로컬 우선 LLM과 클라우드 폴백"
|
||||
category: "Architecture_Decision"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["ADR local-first", "엔진 폴백 결정", "로컬 LLM 우선", "프로바이더 라우팅 결정"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["adr", "llm", "provider", "decision", "fallback", "astraai"]
|
||||
raw_sources: ["AstraAI/src/core/services.ts", "AstraAI/src/features/providers/types.ts", "AstraAI/src/features/providers/index.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[ADR-0008 로컬 우선 LLM과 클라우드 폴백]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
기본은 **로컬 엔진(LM Studio/Ollama)을 우선**하고 로컬끼리 폴백하며, 클라우드(OpenRouter/Anthropic/Gemini)는 **model id prefix 로 옵션 선택**하기로 결정했다 — 프라이버시·비용·오프라인을 기본값으로, 필요 시 클라우드 품질을 끌어쓰기 위해 [S1][S2].
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- **결정:** prefix 없으면 로컬, 있으면 클라우드 어댑터. 로컬은 LM Studio↔Ollama 자동 폴백.
|
||||
- 구현은 [[LLM 프로바이더 추상화]] 참조.
|
||||
|
||||
## 📖 세부 내용 (Details · ADR)
|
||||
### Problem
|
||||
어떤 LLM 을 어떻게 선택/실패 처리할 것인가. 로컬은 무료·프라이버시·오프라인이지만 품질·가용성이 들쭉날쭉. 클라우드는 품질↑ 비용·프라이버시 우려.
|
||||
|
||||
### Context
|
||||
제2뇌는 개인 지식을 다룸 → 프라이버시 중요. 로컬 엔진은 가끔 빈 응답/전송 오류. 사용자가 작업별로 품질을 올리고 싶을 때가 있음.
|
||||
|
||||
### Options Considered
|
||||
1. **클라우드 전용** — 품질·간편, 그러나 비용·프라이버시·오프라인 불가.
|
||||
2. **로컬 전용** — 프라이버시·무료, 그러나 실패 시 대안 없음.
|
||||
3. **로컬 우선 + 로컬 폴백 + 클라우드 옵션(prefix)** — 기본 안전 + 선택적 품질.
|
||||
|
||||
### Chosen Solution
|
||||
3번. `AIService.chat` 이 설정 엔진→다른 로컬 엔진 폴백(빈 응답=soft failure). 클라우드는 `parseModelPrefix` 로 라우팅, 어댑터가 SSE 정규화 [S1][S2].
|
||||
|
||||
### Why It Was Chosen
|
||||
프라이버시·비용·오프라인을 기본으로 보장하면서, 로컬 불안정을 폴백으로 메우고, 필요 시 클라우드 품질을 prefix 하나로 선택.
|
||||
|
||||
### Benefits
|
||||
프라이버시 기본, 가용성↑(폴백), 유연성(작업별 클라우드), 호출부 공급자 무관.
|
||||
|
||||
### Drawbacks
|
||||
폴백이 지연을 더함, 로컬/클라우드 응답 형식 차이를 어댑터가 흡수해야 함, 클라우드 키 관리.
|
||||
|
||||
### Future Risks
|
||||
클라우드 모델 id/형식 변경 시 어댑터 유지보수, 로컬 모델 품질이 작업을 못 받치면 사용자 불만.
|
||||
|
||||
### Alternative Approaches
|
||||
품질이 절대 우선이면 클라우드 기본 + 로컬 폴백(역순). 또는 작업 난이도 자동 분류로 라우팅(쉬운 건 로컬, 어려운 건 클라우드).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"좋은 클라우드 모델을 쓰면 되지" 라는 입장과 충돌 — 이 결정은 *프라이버시·비용·오프라인* 을 품질보다 우선한 가치 판단. 사용은 prefix 로 자유.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
`services.ts`(폴백), `providers/types.ts`+`index.ts`(prefix 라우팅) [S1][S2].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[LLM 프로바이더 추상화]], [[API Client Pattern]], [[Tool Calling Pattern]]
|
||||
- **참조 맥락:** 로컬 LLM 이 다중 추론 백엔드 전략(로컬/클라우드/폴백)을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/core/services.ts — 로컬 엔진 폴백, soft failure
|
||||
- [S2] AstraAI/src/features/providers/types.ts, index.ts — prefix 라우팅, 어댑터 dispatch
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 코드 분석 기반 ADR 작성.
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
id: adr-0009-deterministic-always-llm-conditional
|
||||
title: "ADR-0009 결정론 항상, LLM 검증 조건부"
|
||||
category: "Architecture_Decision"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["ADR verification", "왜 조건부 critic", "결정론 우선 검증", "확신도 결정론"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["adr", "verification", "intelligence", "decision", "astraai"]
|
||||
raw_sources: ["AstraAI/src/intelligence/confidenceEngine.ts", "AstraAI/src/intelligence/criticAgent.ts", "AstraAI/src/intelligence/epistemicGuardBlock.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[ADR-0009 결정론 항상, LLM 검증 조건부]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
답변 검증에서 **저렴한 결정론적 검사(정규식/카운트/그라운딩 신호)는 매 턴 실행**하고, **비싼 LLM 검수(Critic)는 결정론 검사가 문제를 신호할 때만** 돌리기로 결정했다 — 로컬 모델의 latency 비용 안에서 신뢰를 확보하기 위해 [S1][S2].
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- **결정:** Epistemic Guard(사전, 무비용) + Confidence Engine(결정론, 무LLM) 항상 / Critic(LLM) 조건부 1-pass.
|
||||
- 구현은 [[Intelligence 검증 레이어]] 참조.
|
||||
|
||||
## 📖 세부 내용 (Details · ADR)
|
||||
### Problem
|
||||
작은 로컬 모델은 환각이 잦다. 매 답변을 LLM 으로 재검수하면 정확하지만 latency·비용이 2배 이상으로 사용성이 무너진다.
|
||||
|
||||
### Context
|
||||
로컬 Gemma 류, 단일 GPU. 매 턴 추가 LLM 호출은 체감 지연이 큼. 그러나 사실오류/근거누락은 잡아야 함.
|
||||
|
||||
### Options Considered
|
||||
1. **항상 LLM 재검수(full debate)** — 가장 정확, 그러나 latency·비용 폭증.
|
||||
2. **검증 없음** — 빠르나 환각 방치.
|
||||
3. **결정론 항상 + LLM 조건부** — 비용 통제 + 위험 신호 시 정밀 검수.
|
||||
|
||||
### Chosen Solution
|
||||
3번. 매 턴 Epistemic Guard 주입 + 결정론 Confidence(0~100) 산출. "커버리지 누락 또는 확신도 <70" 일 때만 Critic LLM 1회 호출, 보완 카드 표시. 다회전 debate 는 knob 만 준비 [S1][S2].
|
||||
|
||||
### Why It Was Chosen
|
||||
대부분의 답변은 결정론 신호로 충분히 걸러지고, 진짜 위험할 때만 비싼 검수를 써 비용 대비 신뢰를 극대화. "모름 인정이 오답보다 낫다" 를 사전 가드로 구조화.
|
||||
|
||||
### Benefits
|
||||
낮은 평균 latency, 위험 시 정밀 검수, 설명가능한 확신도, 사용자 검토 유도(에스컬레이션).
|
||||
|
||||
### Drawbacks
|
||||
조건 임계가 잘못되면 위험 답변을 놓치거나 불필요 검수. 확신도 가중치가 휴리스틱(보정 필요). 1-pass 는 다회전보다 약함.
|
||||
|
||||
### Future Risks
|
||||
임계/가중치가 데이터 없이 고정되면 오탐/미탐. 모델 교체 시 신호 분포가 바뀌어 재보정 필요.
|
||||
|
||||
### Alternative Approaches
|
||||
골든셋으로 가중치 학습, 위험 도메인만 다회전 debate, 또는 작은 전용 검증 모델 상시 가동.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"항상 검증해야 안전" 과 "검증은 비싸다" 의 균형점 — 환경(로컬 latency)이 임계를 정한다. 서버/대형 모델이면 더 자주 LLM 검수가 합리적.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
`confidenceEngine.ts`(결정론), `criticAgent.ts`(조건부), `epistemicGuardBlock.ts`(사전) [S1][S2][S3].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[Intelligence 검증 레이어]], [[Critic Pattern]], [[Reflection Pattern]], [[엔지니어링 트레이드오프 분석]]
|
||||
- **참조 맥락:** 로컬 LLM 이 자기검증 비용/정확도 균형을 설계할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/intelligence/confidenceEngine.ts — 결정론 확신도(매 턴)
|
||||
- [S2] AstraAI/src/intelligence/criticAgent.ts — 조건부 1-pass 검수
|
||||
- [S3] AstraAI/src/intelligence/epistemicGuardBlock.ts — 사전 가드
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 코드 분석 기반 ADR 작성.
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: adr-0010-orchestrator-skeleton-module-extraction
|
||||
title: "ADR-0010 오케스트레이터 골격과 모듈 추출"
|
||||
category: "Architecture_Decision"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["ADR orchestrator", "god class 분해 결정", "흐름 골격 유지", "모듈 추출"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.87
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["adr", "architecture", "refactoring", "decision", "astraai"]
|
||||
raw_sources: ["AstraAI/src/agent.ts", "AstraAI/src/extension.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[ADR-0010 오케스트레이터 골격과 모듈 추출]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
거대해지는 `agent.ts` 를 완전히 잘게 쪼개 흩어버리는 대신, **한 턴의 흐름 골격은 orchestrator 에 남기고 세부 구현만 모듈로 추출**하기로 결정했다 — "흐름을 한 곳에서 읽을 수 있음" 의 가치를 위해 [S1].
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- **결정:** handlePrompt/·llm/·actions/·sessions/·multiAgent/·contextBuilders/ 로 구현 추출, 흐름은 agent.ts 가 호출 순서로 표현.
|
||||
- 구현은 [[Agent 오케스트레이터 분해]] 참조.
|
||||
|
||||
## 📖 세부 내용 (Details · ADR)
|
||||
### Problem
|
||||
한 턴 처리(컨텍스트 조립·라우팅·스트리밍·후처리·학습)가 한 파일에 쌓이면 수천 줄 god-class 가 된다. 반대로 전부 잘게 쪼개면 흐름이 파일 사이를 떠돌아 추적이 어렵다.
|
||||
|
||||
### Context
|
||||
복잡한 단일 흐름(분기 많음), 다수 협력 모듈, 디버깅 시 "이 턴이 무슨 순서로 처리되나" 를 빨리 파악해야 함.
|
||||
|
||||
### Options Considered
|
||||
1. **단일 god-class** — 흐름은 한눈, 그러나 거대·테스트 불가·병합 충돌.
|
||||
2. **완전 분해(흐름도 분산)** — 모듈은 작으나 흐름 추적이 산만.
|
||||
3. **골격 유지 + 세부 추출** — 흐름은 orchestrator, 구현은 순수/작은 모듈.
|
||||
|
||||
### Chosen Solution
|
||||
3번. orchestrator 는 buildTurnContextBlocks→system prompt 빌드→budget→stream→processFinalAnswer→postAnswerHooks 순서를 *호출* 만 하고, 각 단계 구현은 추출된 함수/모듈 [S1].
|
||||
|
||||
### Why It Was Chosen
|
||||
디버깅·온보딩 시 한 턴의 흐름을 orchestrator 한 곳에서 읽고, 세부가 궁금하면 해당 모듈로 내려간다. 추출된 함수는 순수해 테스트 가능.
|
||||
|
||||
### Benefits
|
||||
흐름 가독성 + 모듈 테스트성, 병합 충돌 감소, 점진적 추출 가능.
|
||||
|
||||
### Drawbacks
|
||||
orchestrator 가 여전히 큼(import 100+줄), 추출 경계 설정에 판단 필요, 과도하면 "얇은 래퍼 지옥".
|
||||
|
||||
### Future Risks
|
||||
흐름 분기가 더 늘면 orchestrator 가 다시 비대 → 모드별 서브-오케스트레이터로 분할 필요.
|
||||
|
||||
### Alternative Approaches
|
||||
파이프라인/미들웨어 체인으로 단계를 데이터로 표현, 또는 모드(chat/agent/company)별 orchestrator 분리.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"god-class 는 무조건 나쁘다" 는 단순 규칙과 다르다 — *흐름 가독성* 이라는 명확한 이득이 있으면 골격을 남기는 것이 합리적. 단, 크기 상한을 정하지 않으면 다시 비대해진다.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
`agent.ts` 의 import/호출 구조, `extension.ts` 의 얇은 조립 [S1][S2].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[Agent 오케스트레이터 분해]], [[리팩토링 플레이북]], [[안티패턴 카탈로그]]
|
||||
- **참조 맥락:** 로컬 LLM 이 거대 함수/클래스를 리팩터링할 때 "어디까지 추출할지" 판단에 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/agent.ts — 골격 + 추출 모듈 import
|
||||
- [S2] AstraAI/src/extension.ts — 얇은 조립 entry point
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 코드 분석 기반 ADR 작성.
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
id: aitrain-rag-retrieval
|
||||
title: "AITRAIN RAG 검색"
|
||||
category: "AI_Training"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["AI training RAG", "검색 학습 추출", "RAG 원리"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["ai-training", "rag", "retrieval", "transferable", "astraai"]
|
||||
raw_sources: ["AstraAI/src/retrieval/index.ts", "AstraAI/src/retrieval/scoring.ts", "AstraAI/src/retrieval/chunker.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[AITRAIN RAG 검색]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
RAG 의 전이 원리는 "여러 소스를 같은 스케일로 융합하고, 결정론을 기본으로 의미검색을 가산하며, 토큰 예산 안에서 선별한다" 이다 — 구현은 [[RAG 검색 파이프라인]]·[[TF-IDF 이중언어 스코어링]], 결정 근거는 [[ADR-0007 하이브리드 검색 결정론 우선]].
|
||||
|
||||
## 📖 세부 내용 (Details · 8-field 추출)
|
||||
- **Concept:** 답하기 전에 근거를 찾아 컨텍스트에 주입. 검색 = 후보 생성 → 점수 → 융합 → 예산 선택.
|
||||
- **Implementation:** tokenize(이중언어)→expandQuery(동의어)→TF-IDF→임베딩 blend→소스 정규화+가중→actionability/hierarchical rerank→토큰 예산. 섹션 청킹으로 정밀도↑. mtime 인덱스로 재계산 회피.
|
||||
- **Design Reasoning:** 임베딩 가용성에 의존하지 않으려 결정론(TF-IDF)을 기본; 설명가능성·무중단을 우선. 긴 문서는 청크해야 매치 정밀.
|
||||
- **Tradeoffs:** 가용성·설명가능 ↔ 스케일 정규화 복잡·동의어 수작업.
|
||||
- **Failure Modes:** 부분 정규화 편향(L-02), 동의어 누락 recall↓, 운영 로그 오염, stale 인덱스.
|
||||
- **Debugging Strategy:** fusionLog 단계 카운트, rankBrainForEval recall@k, 점수 분포, 토큰 예산.
|
||||
- **Improvement Ideas:** reranker 모델, BM25, 형태소 분석, 동의어 자동 학습, 청크별 임베딩.
|
||||
- **Reusable Principles:** ① 신호를 합칠 땐 *동일 스케일* 정규화. ② 외부 의존(임베딩) 없이도 동작하는 *바닥선* 을 둬라. ③ 긴 문서는 *의미 단위(섹션)* 로 잘라라. ④ 평가와 프로덕션은 *같은 코드 경로* 로(측정 무결성). ⑤ 변하지 않은 입력은 *재계산하지 말라*(mtime 캐시).
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[RAG 검색 파이프라인]], [[RAG Pattern]], [[Caching Pattern]], [[프로젝트 독립 설계 원칙]]
|
||||
- **참조 맥락:** 작은 모델이 다른 프로젝트에서 검색/RAG 를 설계할 때 원리로 전이.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/retrieval/index.ts, scoring.ts, chunker.ts
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AI 학습용 지식 추출 초안.
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
id: aitrain-verification-layer
|
||||
title: "AITRAIN 검증 레이어"
|
||||
category: "AI_Training"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["AI training verification", "검증 학습 추출", "환각 방지 원리", "critic 원리"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["ai-training", "verification", "hallucination", "transferable", "astraai"]
|
||||
raw_sources: ["AstraAI/src/intelligence/confidenceEngine.ts", "AstraAI/src/intelligence/criticAgent.ts", "AstraAI/src/intelligence/epistemicGuardBlock.ts", "AstraAI/src/intelligence/correctionLoop.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[AITRAIN 검증 레이어]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
LLM 검증의 전이 원리는 "저렴한 결정론 검사는 항상, 비싼 LLM 검수는 조건부; 모름 인정을 보상; 사용자 정정을 학습으로 환원" 이다 — 구현은 [[Intelligence 검증 레이어]], 결정 근거는 [[ADR-0009 결정론 항상 LLM검증 조건부]].
|
||||
|
||||
## 📖 세부 내용 (Details · 8-field 추출)
|
||||
- **Concept:** 답변의 신뢰도를 측정/억제/검수/학습하는 다단 안전망.
|
||||
- **Implementation:** Epistemic Guard(사전 프롬프트 억제)+Confidence Engine(결정론 0~100)+Critic(조건부 1-pass LLM)+Correction Loop(정정→레슨→약점프로필→프롬프트).
|
||||
- **Design Reasoning:** 작은 모델은 환각이 잦고 매 턴 LLM 검수는 비싸다 → 결정론으로 거르고 위험 시만 LLM. "모름>그럴듯한 오답".
|
||||
- **Tradeoffs:** 낮은 latency ↔ 임계 오설정 위험·휴리스틱 가중치.
|
||||
- **Failure Modes:** 임계 미탐/오탐, JSON 파싱 실패, 정정 오탐 노이즈, 모델 교체 후 신호 분포 변화.
|
||||
- **Debugging Strategy:** 확신도 factor 분해, 검색 청크 수, Critic 발동 여부, raw 응답.
|
||||
- **Improvement Ideas:** 골든셋 가중치 학습, 다회전 debate, 전용 검증 모델, 정정 감지 정교화.
|
||||
- **Reusable Principles:** ① 검증은 *계층화* 하라(사전/측정/사후/학습). ② 비용은 위험에 비례 배분(조건부). ③ 불확실성을 *드러내는* 답을 보상. ④ 사용자 피드백 1회를 *시스템 변화* 로 자동 환원. ⑤ LLM 출력은 *파서로 방어*(형식만 믿지 마라).
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[Critic Pattern]], [[Reflection Pattern]], [[프롬프트 엔지니어링 패턴]], [[프로젝트 독립 설계 원칙]]
|
||||
- **참조 맥락:** 작은 모델이 자기검증/피드백 학습을 다른 프로젝트에 적용할 때 원리로 전이.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/intelligence/confidenceEngine.ts, criticAgent.ts, epistemicGuardBlock.ts, correctionLoop.ts
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AI 학습용 지식 추출 초안.
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
id: aitrain-concurrency-control
|
||||
title: "AITRAIN 동시성 제어"
|
||||
category: "AI_Training"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["AI training concurrency", "동시성 학습 추출", "락 큐 트랜잭션 원리"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["ai-training", "concurrency", "transferable", "astraai"]
|
||||
raw_sources: ["AstraAI/src/core/lock.ts", "AstraAI/src/core/queue.ts", "AstraAI/src/core/transaction.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[AITRAIN 동시성 제어]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
동시성의 전이 원리는 "단일 스레드라도 await 사이에 race 가 생긴다; 자원은 락으로 직렬화, 폭주는 큐로 제한, 다중 변경은 보상 트랜잭션으로 원자화" 이다 — 구현은 [[동시성 제어 Lock Queue Transaction]].
|
||||
|
||||
## 📖 세부 내용 (Details · 8-field 추출)
|
||||
- **Concept:** 공유 자원 동시 접근/자원 폭주/부분 실패를 제어하는 세 도구(락·큐·트랜잭션).
|
||||
- **Implementation:** 토큰 기반 AsyncLock(race 타임아웃, try/finally release), 동시성 제한 큐(max(2,cpus-1)), 보상 트랜잭션(begin/record/commit/rollback).
|
||||
- **Design Reasoning:** JS 비동기에도 갱신 손실이 발생; 무한 병렬은 자원 고갈; FS 엔 트랜잭션이 없어 백업/복원으로 원자성 흉내.
|
||||
- **Tradeoffs:** 안전 ↔ 지연(직렬화)·복잡도. 메모리 트랜잭션은 프로세스 사망 시 롤백 불가.
|
||||
- **Failure Modes:** 데드락, 락 누수(release 누락), 동일성 비교 실수, 메모리 백업 유실.
|
||||
- **Debugging Strategy:** active lock 수 추세, 타임아웃 위치, 경합 resourceId 로그.
|
||||
- **Improvement Ideas:** 동적 동시성, WAL/DB 내구 트랜잭션, 분산 락(멀티프로세스).
|
||||
- **Reusable Principles:** ① `await` 가 있으면 race 를 의심하라. ② 락은 *반드시 try/finally*. ③ 식별은 객체 동일성 아닌 *명시 토큰*. ④ 대량 작업엔 *동시성 상한*. ⑤ 다중 쓰기는 *전부 또는 무*(보상 트랜잭션). ⑥ 동시성 수준은 *하드웨어* 가 정한다.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[Background Worker Pattern]], [[Background Task Pattern]], [[프로젝트 독립 설계 원칙]]
|
||||
- **참조 맥락:** 작은 모델이 공유 자원/대량 작업/다중 변경 코드를 다른 프로젝트에서 작성할 때 전이.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/core/lock.ts, queue.ts, transaction.ts
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AI 학습용 지식 추출 초안.
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
id: aitrain-memory-system
|
||||
title: "AITRAIN 메모리 시스템"
|
||||
category: "AI_Training"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["AI training memory", "메모리 학습 추출", "에이전트 메모리 원리"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["ai-training", "memory", "transferable", "astraai"]
|
||||
raw_sources: ["AstraAI/src/memory/index.ts", "AstraAI/src/memory/types.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[AITRAIN 메모리 시스템]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
에이전트 메모리는 "수명·용도가 다른 기억을 분리하고, 관련도로 선별해, 만료/승급으로 자정한다" 는 전이 가능한 원리로 추출된다 — 구현 세부는 [[5계층 메모리 시스템]], 결정 근거는 [[ADR-0002 5계층 메모리 분리]].
|
||||
|
||||
## 📖 세부 내용 (Details · 8-field 추출)
|
||||
- **Concept (개념):** 단일 버퍼가 아닌 다계층 인지 메모리. 각 계층 = (수명 × 용도 × 검색정책).
|
||||
- **Implementation (구현):** MemoryManager 가 5계층(단기 FIFO / 장기 entry / 프로젝트 ADR·버그 / 절차 trigger→steps / 일화 요약)을 보유, `buildContext` 가 관련도순으로 합치고 `onSessionEnd` 가 추출·증류.
|
||||
- **Design Reasoning (설계 이유):** 작은 모델은 컨텍스트 한도가 좁다 → "무엇을 넣을지" 의 선별이 품질을 좌우. 계층마다 만료/우선순위가 달라 분리가 자연스럽다.
|
||||
- **Tradeoffs:** 정밀 선별 ↔ 분류 결정 비용·복잡도. ([[엔지니어링 트레이드오프 분석]])
|
||||
- **Failure Modes:** 만료 미설정으로 옛 사실 재현, 관련도 휴리스틱 오선별, 계층 경계 모호.
|
||||
- **Debugging Strategy:** 계층별 buildContext 출력 확인, expiresAt 점검, distillation 로그 ([[디버깅 플레이북]]).
|
||||
- **Improvement Ideas:** 관련도 학습화, 계층별 임베딩, 분류 규칙 명문화/자동화.
|
||||
- **Reusable Principles:** ① 컨텍스트는 *선별* 의 문제다. ② 시한부 지식엔 만료를. ③ 오래된 기억은 *버리지 말고 압축(증류)*. ④ 기억의 수명이 다르면 저장소도 달라야 한다.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[5계층 메모리 시스템]], [[Memory Pattern]], [[ADR-0002 5계층 메모리 분리]], [[프로젝트 독립 설계 원칙]]
|
||||
- **참조 맥락:** 작은 모델이 *다른 프로젝트* 에서 에이전트 메모리를 설계할 때 원리로 전이.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/memory/index.ts, types.ts
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AI 학습용 지식 추출 초안.
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
---
|
||||
id: aitrain-agent-orchestration
|
||||
title: "AITRAIN 에이전트 오케스트레이션"
|
||||
category: "AI_Training"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["AI training agent", "에이전트 학습 추출", "오케스트레이션 원리"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["ai-training", "agent", "orchestration", "transferable", "astraai"]
|
||||
raw_sources: ["AstraAI/src/agent.ts", "AstraAI/src/agents/AgentWorkflowManager.ts", "AstraAI/src/features/company/dispatcher.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[AITRAIN 에이전트 오케스트레이션]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
에이전트 오케스트레이션의 전이 원리는 "에이전트 수를 늘리기 전에 정보 손실과 자원을 점검하고, 흐름 골격은 한 곳에 남긴다" 이다 — 구현은 [[Agent 오케스트레이터 분해]], 결정 근거는 [[ADR-0003 단일작성자 다중역할 멀티에이전트]]·[[ADR-0010 오케스트레이터 골격 모듈추출]].
|
||||
|
||||
## 📖 세부 내용 (Details · 8-field 추출)
|
||||
- **Concept:** 복잡한 작업을 단계/역할로 나눠 LLM 을 여러 번 호출하되, 흐름을 한 곳에서 조율.
|
||||
- **Implementation:** orchestrator(agent.ts)가 흐름 골격, 세부는 추출 모듈. 일반 작성은 단일 ChunkedWriter(outline→section→polish). 다중 전문가는 순차 디스패치(peer-context 전달).
|
||||
- **Design Reasoning:** 병렬 persona 는 hop 컨텍스트 누적·본문 손실·자원 폭주를 부른다(실측). 자원 제약(단일 GPU)이 순차를 강제. 흐름 가독성을 위해 골격은 분해하지 않음.
|
||||
- **Tradeoffs:** 자원 안전·본문 보존 ↔ 속도(순차)·단일 모델 의존.
|
||||
- **Failure Modes:** 에이전트 남발로 "방법론만 생성", OOM(병렬 다중 상주), orchestrator 재비대.
|
||||
- **Debugging Strategy:** 단계 인디케이터 추적, peer-context 길이, 모델 lifecycle, 한 단계씩 격리.
|
||||
- **Improvement Ideas:** 자원 감지 후 조건부 병렬, judge panel, 모드별 서브-오케스트레이터.
|
||||
- **Reusable Principles:** ① 에이전트 추가 전 "원본이 hop 에서 손실되는가" 점검. ② 동시성은 *배포 환경* 이 결정. ③ 흐름은 한 곳에서 읽히게, 구현만 추출. ④ 진행을 사용자에게 *가시화* 해 순차 지연 체감을 완화. ⑤ 단계별로 같은 모델이 역할만 바꾸는 것이 종종 N-에이전트보다 낫다.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[Agent Orchestration Pattern]], [[Reflection Pattern]], [[Critic Pattern]], [[프로젝트 독립 설계 원칙]]
|
||||
- **참조 맥락:** 작은 모델이 멀티에이전트/파이프라인을 설계할 때 과설계 회피 원리로 전이.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/agent.ts, agents/AgentWorkflowManager.ts, features/company/dispatcher.ts
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AI 학습용 지식 추출 초안.
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
id: aitrain-event-sourcing-storage
|
||||
title: "AITRAIN 이벤트소싱 저장"
|
||||
category: "AI_Training"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["AI training storage", "이벤트소싱 학습 추출", "저장 원리"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.89
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["ai-training", "event-sourcing", "storage", "transferable", "astraai"]
|
||||
raw_sources: ["AstraAI/src/features/_shared/eventSourcedStore.ts", "AstraAI/src/core/services.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[AITRAIN 이벤트소싱 저장]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
저장 설계의 전이 원리는 "이력이 가치면 append-only, 단순함·투명성을 위해 파일 우선, 반복 I/O 는 제네릭으로, 손상은 부분 격리" 이다 — 구현은 [[이벤트 소싱 스토어 패턴]], 결정 근거는 [[ADR-0001 이벤트 소싱 채택]]·[[ADR-0005 파일 기반 저장 채택]].
|
||||
|
||||
## 📖 세부 내용 (Details · 8-field 추출)
|
||||
- **Concept:** 상태를 덮어쓰지 않고 이벤트를 추가; 현재 상태는 재생으로 도출. 저장 매체는 사람이 읽는 파일.
|
||||
- **Implementation:** `createEventStore<E>({relPath, validate})` 제네릭 팩토리(JSONL append + 내결함 read + 판별 유니온 결과). 지식은 frontmatter Markdown.
|
||||
- **Design Reasoning:** 단일 사용자 로컬 → DB 운영 비용 회피, 투명성(직접 열람/편집), 무의존. 4벌 중복을 제네릭으로 흡수.
|
||||
- **Tradeoffs:** 이력·투명·무의존 ↔ 쿼리 성능·파일 증가·동시쓰기 잠금 직접.
|
||||
- **Failure Modes:** 파일 단조 증가(compaction 없음), 멀티프로세스 동시 append, 손상 줄.
|
||||
- **Debugging Strategy:** JSONL 줄 단위 파싱 검사, 워크스페이스 경로 해석, 검증 함수 통과율.
|
||||
- **Improvement Ideas:** 스냅샷+증분 compaction, SQLite 메타+파일 본문 하이브리드, 스키마 버전 업캐스팅.
|
||||
- **Reusable Principles:** ① 이력이 가치면 *추가만* 하라. ② 손상 1줄이 전체를 죽이지 않게 *부분 격리*. ③ 반복 I/O 패턴은 *제네릭 1벌* 로. ④ 가능하면 *사람이 읽는* 포맷(신뢰·디버깅). ⑤ 흔한 실패는 예외 대신 *결과 유니온* 으로 호출부에 강제.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[Event Bus Pattern]], [[Local Storage Pattern]], [[Repository Pattern]], [[프로젝트 독립 설계 원칙]]
|
||||
- **참조 맥락:** 작은 모델이 영속화/스토어를 설계할 때 원리로 전이.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/features/_shared/eventSourcedStore.ts, core/services.ts
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AI 학습용 지식 추출 초안.
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
id: aitrain-provider-abstraction
|
||||
title: "AITRAIN 프로바이더 추상화"
|
||||
category: "AI_Training"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["AI training provider", "어댑터 학습 추출", "외부 API 통합 원리"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.89
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["ai-training", "provider", "adapter", "transferable", "astraai"]
|
||||
raw_sources: ["AstraAI/src/features/providers/index.ts", "AstraAI/src/features/providers/anthropic.ts", "AstraAI/src/features/providers/types.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[AITRAIN 프로바이더 추상화]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
외부 API 통합의 전이 원리는 "차이는 가장자리(어댑터)에서 흡수하고 중심은 단일 포맷으로 정규화하며, 라우팅은 명시적 키로" 이다 — 구현은 [[LLM 프로바이더 추상화]], 결정 근거는 [[ADR-0008 로컬우선 LLM 클라우드 폴백]].
|
||||
|
||||
## 📖 세부 내용 (Details · 8-field 추출)
|
||||
- **Concept:** 다수의 이질적 외부 서비스를 호출부 입장에선 하나처럼 보이게 하는 어댑터 계층.
|
||||
- **Implementation:** model id prefix 라우팅(parseModelPrefix), 공급자별 streamX 어댑터, 응답을 공통 OpenAI-SSE 로 변환, 에러는 passthrough, 활성 공급자만 병렬 조회.
|
||||
- **Design Reasoning:** 같은 모델명이 여러 경로에 존재 → 출처 명시 필요; 호출부를 공급자 무관하게 유지하려 정규화; 프라이버시·비용 위해 로컬 우선.
|
||||
- **Tradeoffs:** 호출부 단순·교체 용이 ↔ 어댑터별 구현·정규화 비용·키 관리.
|
||||
- **Failure Modes:** 인증 실패, 응답 형식 차이, 모델 목록 노후화, role 교대/system 위치 같은 공급자 제약.
|
||||
- **Debugging Strategy:** 에러 Response.text(), 어댑터별 입력 정규화 점검, prefix 매칭 확인.
|
||||
- **Improvement Ideas:** prompt caching/tool use, 자동 모델 목록, 난이도 기반 라우팅.
|
||||
- **Reusable Principles:** ① *차이는 가장자리에서* 흡수, 중심은 단일 모델. ② 라우팅은 *명시 키(prefix)* 로 모호성 제거. ③ 입력/출력을 *정규화* 해 상위 코드를 공급자 무관하게. ④ 외부 실패는 삼키지 말고 *그대로 전달*해 호출부가 안내. ⑤ 기본은 *프라이버시·비용 안전*, 품질은 옵션.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[API Client Pattern]], [[Tool Calling Pattern]], [[프로젝트 독립 설계 원칙]]
|
||||
- **참조 맥락:** 작은 모델이 다중 외부 API/SDK 통합을 다른 프로젝트에서 설계할 때 전이.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/features/providers/index.ts, anthropic.ts, types.ts
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AI 학습용 지식 추출 초안.
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
id: lessons-learned-library
|
||||
title: "교훈 라이브러리 Lessons Learned"
|
||||
category: "Software_Engineering"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["lessons learned", "교훈", "버그 사후기록", "post-mortem", "재사용 가능한 교훈"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.91
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["lessons", "post-mortem", "engineering", "bugs", "astraai"]
|
||||
raw_sources: ["AstraAI/src/core/lock.ts", "AstraAI/src/retrieval/index.ts", "AstraAI/src/agents/AgentWorkflowManager.ts", "AstraAI/src/features/company/dispatcher.ts", "AstraAI/src/core/services.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[교훈 라이브러리 Lessons Learned]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
AstraAI 의 주석에는 실제 겪은 버그·오설계의 사후기록이 박혀 있다 — 각 교훈을 (문제→근본원인→해결→교훈→향후 권고)로 정리하면, 작은 모델이 *같은 실수를 코드 작성 단계에서 회피* 하는 재사용 지식이 된다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- 교훈 형식: **Problem → Root Cause → Solution → Lesson → Future Recommendation**.
|
||||
- 코드 설명이 아니라 *전이 가능한 엔지니어링 지식* 을 추출하는 것이 목적.
|
||||
|
||||
## 📖 세부 내용 (Details · 교훈 모음)
|
||||
|
||||
### L-01. Promise 동일성 비교는 항상 실패한다
|
||||
- **Problem:** 비동기 락 cleanup 이 동작하지 않아 락이 새거나 다른 작업 entry 를 지움.
|
||||
- **Root Cause:** `map.get(id) === prev.then(()=>next)` 로 비교했는데 `.then()` 은 *매번 새 Promise* 를 반환 → 동일성 비교가 항상 false. 또 release 시 무조건 delete → race.
|
||||
- **Solution:** 각 entry 에 고유 `Symbol` 토큰을 부여, "내 토큰이 Map 의 최신일 때만" 정리.
|
||||
- **Lesson:** Promise·객체 동일성(`===`)에 로직을 걸지 말 것. 식별이 필요하면 명시적 토큰/ID 를 써라.
|
||||
- **Future Recommendation:** 공유 자원 정리는 "내가 최신 소유자인가" 를 토큰으로 확인 후 수행 [S1].
|
||||
|
||||
### L-02. 하이브리드 점수는 같은 스케일로 정규화해야 한다
|
||||
- **Problem:** 임베딩을 섞었더니 검색 품질이 *나빠짐*.
|
||||
- **Root Cause:** ① 벡터 있는 후보만 0..1 로 줄이면 벡터 없는 후보의 raw 점수(≫1)가 상위 독식 → blend 무효. ② cosine 절대값 가산은 무관 문서도 0.5~0.7 이라 균일 노이즈로 sparse 정밀도 훼손.
|
||||
- **Solution:** *모든* 후보를 maxTfidf 로 정규화, cosine 은 후보군 내 min-max 정규화 후 혼합.
|
||||
- **Lesson:** 서로 다른 점수를 합칠 땐 *동일 스케일* 로 정규화하라. 부분 정규화는 편향을 만든다.
|
||||
- **Future Recommendation:** 점수 융합 전 각 신호의 분포를 측정하고 정규화 방식을 명시 [S2].
|
||||
|
||||
### L-03. 멀티에이전트 hop 은 컨텍스트를 누적하고 본문을 잃는다
|
||||
- **Problem:** 본문 분석 요청에 "분석 방법론" 만 생성.
|
||||
- **Root Cause:** 5-persona 파이프라인이 hop 마다 컨텍스트를 쌓고 원본 본문을 추상화로 손실.
|
||||
- **Solution:** 단일 작성자가 역할을 번갈아 수행, 본문을 매 호출에 직접 전달.
|
||||
- **Lesson:** 에이전트를 늘리기 전에 "원본 데이터가 hop 을 거치며 손실되는가" 를 점검하라. 에이전트 수 ≠ 품질.
|
||||
- **Future Recommendation:** 정보 손실 위험이 있으면 hop 을 줄이고 원자료를 끝까지 보존 [S3].
|
||||
|
||||
### L-04. 자원 제약은 동시성 모델을 결정한다
|
||||
- **Problem:** 병렬 에이전트가 단일 GPU 에서 OOM/로드 실패.
|
||||
- **Root Cause:** 병렬은 여러 모델 동시 상주를 강요 — 제한 RAM 초과.
|
||||
- **Solution:** 순차 디스패치 + "한 번에 한 모델 상주" 불변식(lifecycle unload/load).
|
||||
- **Lesson:** 동시성은 알고리즘이 아니라 *배포 환경* 이 결정한다. 자원을 모르면 동시성을 정할 수 없다.
|
||||
- **Future Recommendation:** 설계 전 타깃 하드웨어(RAM/GPU)를 먼저 못박아라 [S4].
|
||||
|
||||
### L-05. 작은 모델은 system 없으면 환각 거절한다
|
||||
- **Problem:** 짧고 모호한 입력에 "시는 못 써드려요" 류 거절.
|
||||
- **Root Cause:** system 프롬프트 없이 user 만 주면 작은 모델이 의도를 못 잡고 방어적 거절.
|
||||
- **Solution:** grounding 경로는 system 을 반드시 채운다(역할·규칙 명시).
|
||||
- **Lesson:** 모델이 작을수록 *명시적 지시* 의존도가 크다. "알아서 하겠지" 가 안 통한다.
|
||||
- **Future Recommendation:** 모든 LLM 호출에 최소한의 역할 system 을 기본 제공 [S5].
|
||||
|
||||
### L-06. 빈 catch 는 "이유 주석" 과 함께만 안전하다
|
||||
- **Problem:** 부가 작업(메모리 추출/증류) 실패가 대화 전체를 깨뜨릴 위험.
|
||||
- **Root Cause:** 핵심 흐름에 부가 작업을 직렬로 엮으면 부가 실패가 본류를 막는다.
|
||||
- **Solution:** 부가 작업을 `try { } catch { /* should never break main flow */ }` 로 격리, *반드시 이유 주석*.
|
||||
- **Lesson:** 실패를 삼키는 것은 *부가 작업에 한해, 의도를 명시* 할 때만 정당하다.
|
||||
- **Future Recommendation:** 빈 catch 마다 "왜 안전한가" 를 1줄로 남겨 리뷰어/모델이 구분하게 [S6].
|
||||
|
||||
### L-07. 동적 require 는 이유가 사라지면 정적 import 로
|
||||
- **Problem:** 매 stage 마다 `await import(...)` 8회 — 흐름 불명확.
|
||||
- **Root Cause:** 과거 cyclic import 회피로 짐작됐으나, 실제로는 해당 모듈들이 dispatcher 를 import 하지 않아 순환이 없었음.
|
||||
- **Solution:** 정적 import 로 promote — 코드 명료 + require 8회→0회(모듈 캐시).
|
||||
- **Lesson:** "왜 이렇게 했는지" 가 불명한 우회 코드는 가정을 검증하고 단순화하라.
|
||||
- **Future Recommendation:** 우회(workaround)에는 이유를 적고, 주기적으로 "아직 필요한가" 재검토 [S4].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
교훈은 *그 맥락에서* 참이다. 예: L-04(순차)는 단일 GPU 전제 — 서버에선 반대가 교훈이 된다. 교훈을 적용하기 전 전제가 같은지 확인하라.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
각 교훈은 실제 AstraAI 주석/리팩터링에서 추출. AstraAI 의 lessons/ 폴더와 correctionLoop 이 이런 교훈을 자동 적립하는 시스템이기도 하다 → [[Intelligence 검증 레이어]].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[안티패턴 카탈로그]], [[디버깅 플레이북]], [[엔지니어링 트레이드오프 분석]], [[코딩 컨벤션과 주석 철학]]
|
||||
- **참조 맥락:** 로컬 LLM 이 코드를 작성하기 전 "이 상황에서 알려진 함정" 을 회피하는 체크리스트로 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/core/lock.ts — Promise 동일성/토큰 정리 post-mortem
|
||||
- [S2] AstraAI/src/retrieval/index.ts — 하이브리드 스케일 정규화 버그
|
||||
- [S3] AstraAI/src/agents/AgentWorkflowManager.ts — 멀티에이전트 hop 손실
|
||||
- [S4] AstraAI/src/features/company/dispatcher.ts — 자원 제약, 동적 require 통합
|
||||
- [S5] AstraAI/src/core/services.ts — 작은 모델 system grounding
|
||||
- [S6] AstraAI/src/memory/index.ts — 의도적 빈 catch
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 코드 사후기록 기반 교훈 추출.
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
id: debugging-playbook
|
||||
title: "디버깅 플레이북"
|
||||
category: "Software_Engineering"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["debugging playbook", "디버깅", "장애 모드", "failure mode", "복구 절차", "진단 단계"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.88
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["debugging", "failure-modes", "diagnostics", "recovery", "astraai"]
|
||||
raw_sources: ["AstraAI/src/core/errorHandler.ts", "AstraAI/src/core/services.ts", "AstraAI/src/retrieval/index.ts", "AstraAI/src/core/lock.ts", "AstraAI/src/lmstudio/lifecycleManager.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[디버깅 플레이북]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
디버깅은 "증상에서 근본 원인으로 좁혀 들어가는" 체계적 절차이며, 서브시스템별로 *흔한 장애 모드·진단 순서·복구·예방* 을 미리 정리하면 사람과 AI 에이전트 모두 빠르게 고친다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
각 서브시스템: **흔한 장애 모드 / 근본 원인 / 진단 단계 / 복구 절차 / 예방**. 공통 원칙: 증상→가설→*측정으로 검증*→최소 변경.
|
||||
|
||||
## 📖 세부 내용 (Details · 서브시스템별)
|
||||
|
||||
### LLM 호출 / 엔진 ([[LLM 프로바이더 추상화]])
|
||||
- **장애:** 빈 응답, timeout, 연결 거부(ECONNREFUSED), 404 모델 없음.
|
||||
- **근본 원인:** 엔진 미실행, 모델 미로드, URL 오설정, 작은 모델의 빈 출력.
|
||||
- **진단:** ErrorTranslator 카테고리 확인 → 엔진 상태(health) → 모델 목록 → fusionLog/로그.
|
||||
- **복구:** 다른 로컬 엔진 폴백(자동), 모델 재선택(lifecycle 재로드), timeout 상향.
|
||||
- **예방:** system 프롬프트 항상 채움(빈 응답↓), 폴백 경로 유지, 빈 응답을 soft failure 로 명시.
|
||||
|
||||
### 동시성 / 락 ([[동시성 제어 Lock Queue Transaction]])
|
||||
- **장애:** 데드락, 락 누수, 갱신 손실, 락 타임아웃.
|
||||
- **근본 원인:** release 누락(try/finally 없음), 동일성 비교 실수(L-02 토큰), 자원 직렬화 누락.
|
||||
- **진단:** `getActiveLockCount()` 추세, 타임아웃 에러 위치, 같은 resourceId 경합 로그.
|
||||
- **복구:** 타임아웃으로 깨운 뒤 재시도/안내, 프로세스 재시작(메모리 락 해제).
|
||||
- **예방:** 락은 반드시 try/finally, 토큰 기반 정리, 무거운 작업은 missionId 직렬화.
|
||||
|
||||
### 검색 / RAG ([[RAG 검색 파이프라인]])
|
||||
- **장애:** 관련 문서 누락(낮은 recall), 무관 문서 상위, 빈 결과.
|
||||
- **근본 원인:** 토큰화/동의어 누락, 하이브리드 스케일 편향, 운영 로그 미제외, 인덱스 stale.
|
||||
- **진단:** `fusionLog` 단계별 카운트, `rankBrainForEval`(recall@k), 토큰/예산 사용량, 청크 점수 분포.
|
||||
- **복구:** 동의어 추가, blend α 조정, 인덱스 clear/재빌드, scopeFolders 점검.
|
||||
- **예방:** 평가 하니스 정기 실행(프로덕션과 동일 경로), 정규화 일관, mtime 인덱스 무결성.
|
||||
|
||||
### 메모리 ([[5계층 메모리 시스템]])
|
||||
- **장애:** 오래된 사실을 현재처럼 답함, 기억 미반영, 잘못된 계층 선택.
|
||||
- **근본 원인:** `expiresAt` 미설정, 추출 실패(빈 catch 삼킴), 관련도 휴리스틱 오선별.
|
||||
- **진단:** 계층별 buildContext 출력 확인, 만료 필드 점검, distillation 로그.
|
||||
- **복구:** 만료 부여/엔트리 삭제(파일 직접 편집 가능 — 투명성), 재추출.
|
||||
- **예방:** 시한부 지식에 expiresAt, 분류 규칙 명문화([[아키텍처 휴리스틱]]).
|
||||
|
||||
### 검증 / 환각 ([[Intelligence 검증 레이어]])
|
||||
- **장애:** 환각(근거 없는 단정), 과도한 헤지, 위험 답변 미검수.
|
||||
- **근본 원인:** 검색 근거 0인데 단정, 확신도 임계 오설정, JSON 파싱 실패.
|
||||
- **진단:** 확신도 factor 분해(footer), 검색 청크 수, Critic 발동 여부, raw 응답 검사.
|
||||
- **복구:** Epistemic Guard 강도↑(근거 없을 때), 임계 조정, 균형 괄호 파서 fallback.
|
||||
- **예방:** "근거 없으면 확인 필요" 강제, 결정론 신호 항상, 파서 방어.
|
||||
|
||||
### 모델 수명 / 메모리(VRAM) ([[ADR-0004 순차 디스패치 채택]])
|
||||
- **장애:** OOM, 모델 로드 실패, VRAM 미해제.
|
||||
- **근본 원인:** 병렬 다중 모델 상주, 이전 모델 미언로드.
|
||||
- **진단:** lifecycle 상태, 시스템 메모리, 모델 전환 로그.
|
||||
- **복구:** 이전 모델 unload 후 재로드, idle timeout 단축, 순차 강제.
|
||||
- **예방:** "한 번에 한 모델" 불변식, gpuOffloadRatio 등 로드 설정 조정.
|
||||
|
||||
### VS Code 확장 ([[VSCode 확장 구조와 생명주기]])
|
||||
- **장애:** 활성화 실패, 명령 미등록, 자원 누수, 패널 안 열림.
|
||||
- **근본 원인:** activate 예외, disposable 미등록, 웹뷰 타이밍.
|
||||
- **진단:** activate console/OutputChannel 로그, subscriptions 등록 여부.
|
||||
- **복구:** 확장 reload, deactivate 정리 확인.
|
||||
- **예방:** 모든 자원 subscriptions 등록, best-effort 옵셔널 체이닝, 부트스트랩 비차단.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
"로그를 보면 답이 있다" 는 빈 catch 가 로그를 삼키면 깨진다 — 그래서 빈 catch 는 이유 주석 + 가능하면 logError 동반이 원칙. 진단은 *측정* 으로 검증하라(추측으로 재시작 금지).
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
ErrorTranslator(증상 분류), fusionLog/rankBrainForEval(검색 진단), 확신도 footer(검증 진단), lifecycle(VRAM) [S1~S5].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[교훈 라이브러리 Lessons Learned]], [[안티패턴 카탈로그]], [[소프트웨어 실패 라이브러리]], [[리팩토링 플레이북]]
|
||||
- **참조 맥락:** 로컬 LLM/개발자가 장애를 만났을 때 서브시스템별 진단 순서로 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/core/errorHandler.ts — 증상 분류
|
||||
- [S2] AstraAI/src/core/services.ts — 엔진 폴백/빈 응답
|
||||
- [S3] AstraAI/src/retrieval/index.ts — fusionLog/평가 경로
|
||||
- [S4] AstraAI/src/core/lock.ts — 락 진단
|
||||
- [S5] AstraAI/src/lmstudio/lifecycleManager.ts — 모델 수명/VRAM
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 서브시스템별 디버깅 절차 초안.
|
||||
@@ -0,0 +1,87 @@
|
||||
---
|
||||
id: refactoring-playbook
|
||||
title: "리팩토링 플레이북"
|
||||
category: "Software_Engineering"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["refactoring playbook", "리팩토링", "기술 부채", "technical debt", "마이그레이션 경로", "확장 우려"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.87
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["refactoring", "technical-debt", "scaling", "migration", "astraai"]
|
||||
raw_sources: ["AstraAI/src/agent.ts", "AstraAI/src/features/_shared/eventSourcedStore.ts", "AstraAI/src/retrieval/index.ts", "AstraAI/src/features/company/dispatcher.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[리팩토링 플레이북]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
리팩토링은 "동작을 바꾸지 않고 구조를 개선" 하는 것이며, AstraAI 의 실제 리팩터링(중복 통합·동적→정적·persona 단순화·god-class 추출)에서 *언제·어떻게 안전하게 진화시키는가* 의 절차를 뽑을 수 있다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- 현재 한계 → 기술 부채 → 리팩토링 기회 → 확장 우려 → 마이그레이션 경로.
|
||||
- 안전 리팩토링 = 테스트로 동작 고정 → 작은 단계 → 회귀 격리.
|
||||
|
||||
## 📖 세부 내용 (Details)
|
||||
|
||||
### 현재 한계 (Current limitations)
|
||||
- `agent.ts` orchestrator 가 여전히 큼(import 100+줄) — 모드 분기가 늘면 재비대.
|
||||
- 파일 기반 저장은 brain 이 수만 파일로 커지면 스캔/인덱싱 비용 급증.
|
||||
- 이벤트 JSONL 은 compaction 없어 단조 증가.
|
||||
- 검색 동의어 사전이 수작업이라 도메인 확장 시 누락.
|
||||
- 확신도/검증 가중치가 휴리스틱(데이터 보정 전).
|
||||
- 순차 디스패치는 누적 지연 — 멀티 GPU 미활용.
|
||||
|
||||
### 기술 부채 (Technical debt)
|
||||
- 일부 `as any` 캐스팅(외부 JSON 경계).
|
||||
- 하드코딩 모델 목록(클라우드 어댑터) 노후화.
|
||||
- 메모리 계층 경계 모호(장기 decision vs 프로젝트 ADR).
|
||||
|
||||
### 리팩토링 기회 (Refactoring opportunities)
|
||||
1. **중복 → 제네릭/공통 모듈:** eventSourcedStore 처럼 반복 패턴을 팩토리로 흡수(이미 적용). 다음 후보: contextBuilders 의 유사 블록.
|
||||
2. **동적 → 정적:** 이유가 사라진 `await import` 를 정적 import 로(이미 dispatcher 적용).
|
||||
3. **god-class → 골격+추출:** 모드별 서브-오케스트레이터 분리(chat/agent/company).
|
||||
4. **휴리스틱 → 학습:** 확신도/검색 가중치를 골든셋으로 보정.
|
||||
|
||||
### 확장 우려 (Scaling concerns)
|
||||
- brain 파일 수 ↑ → 인덱싱 시간/메모리. → 파일 watch + 증분 인덱스, 또는 메타데이터 DB.
|
||||
- 이벤트 수 ↑ → 재생 비용. → 스냅샷 + 증분.
|
||||
- 사용자 수 ↑(멀티유저) → 파일 잠금/일관성 한계. → DB 이전.
|
||||
|
||||
### 마이그레이션 경로 (Suggested migration paths)
|
||||
- **저장:** 파일 → (SQLite 메타 + 파일 본문 하이브리드) → 필요 시 벡터 DB 외부화. *본문 투명성은 유지.*
|
||||
- **검색:** TF-IDF → +임베딩(이미) → +reranker 모델 → BM25/벡터 DB.
|
||||
- **에이전트:** 순차 → (자원 감지) → 조건부 병렬(워커 풀). 환경을 런타임 감지해 전략 전환.
|
||||
- **오케스트레이터:** 단일 → 모드별 분리 → 파이프라인/미들웨어 체인.
|
||||
|
||||
### 안전 절차 (How to refactor safely)
|
||||
1. 동작을 테스트로 고정(특히 순수 함수 — chunker/scoring 처럼).
|
||||
2. 회귀 위험을 *플래그로 격리*(예: `chunkLevelRetrieval` 처럼 새 경로를 분리).
|
||||
3. 작은 단계로 커밋, 각 단계 후 평가 하니스(recall@k/회귀 리포트) 재실행.
|
||||
4. 동일 scoring 경로 재사용으로 *측정 무결성* 유지(평가와 프로덕션이 같은 코드).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
리팩토링은 가치지만 *동작 변경 없는* 범위를 지켜야 한다. 기능 추가와 섞으면 회귀 원인 추적이 어렵다 — 분리된 커밋이 원칙.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
중복 통합(eventSourcedStore), 동적→정적(dispatcher), persona 단순화(ChunkedWriter), 플래그 격리(chunkLevelRetrieval) [S1~S4].
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[디버깅 플레이북]], [[안티패턴 카탈로그]], [[엔지니어링 트레이드오프 분석]], [[아키텍처 휴리스틱]]
|
||||
- **참조 맥락:** 로컬 LLM 이 기존 코드를 개선/확장할 때 안전 절차와 마이그레이션 경로로 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/features/_shared/eventSourcedStore.ts — 중복 통합
|
||||
- [S2] AstraAI/src/features/company/dispatcher.ts — 동적→정적
|
||||
- [S3] AstraAI/src/agents/AgentWorkflowManager.ts — persona 단순화
|
||||
- [S4] AstraAI/src/retrieval/index.ts — 플래그 격리, 평가 무결성
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 리팩터링 사례 기반 플레이북 초안.
|
||||
@@ -0,0 +1,91 @@
|
||||
---
|
||||
id: architecture-heuristics
|
||||
title: "아키텍처 휴리스틱"
|
||||
category: "Software_Engineering"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["architecture heuristics", "결정 규칙", "언제 무엇을 쓰나", "design heuristics", "의사결정 규칙"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.89
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["heuristics", "decision-rules", "architecture", "engineering", "astraai"]
|
||||
raw_sources: ["AstraAI 전체 분석", "본 위키 ADR/트레이드오프 모음"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[아키텍처 휴리스틱]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
좋은 설계자는 매번 0부터 고민하지 않고 *결정 규칙(휴리스틱)* 을 적용한다 — "언제 X 를 만들고, 언제 만들지 않는가" 를 명시한 규칙 모음은 작은 모델에게 가장 실용적인 설계 지능이다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- 휴리스틱 = "조건 → 권장 선택" 의 빠른 판단 규칙. 절대 법칙이 아니라 *기본값*.
|
||||
- AstraAI 의 실제 결정에서 역추출.
|
||||
|
||||
## 📖 세부 내용 (Details · 결정 규칙)
|
||||
|
||||
### 새 서비스(클래스/모듈)를 언제 만드나
|
||||
- **만든다:** 명확한 단일 책임 + 다른 곳에서 재사용 + 교체/테스트 필요 + 외부 효과(I/O·API) 캡슐화. → 인터페이스로 추상화([[의존성 주입과 서비스 인터페이스]]).
|
||||
- **안 만든다:** 한 곳에서만 쓰는 3줄 로직, 상태 없는 순수 변환(그냥 함수), "미래에 필요할지도" (YAGNI).
|
||||
|
||||
### 언제 이벤트(append-only)를 쓰나
|
||||
- **쓴다:** 변경 *이력 자체가 가치*, 감사/재현 필요, 추가만 하고 수정 드뭄, 여러 소비자가 같은 사실을 다르게 투영.
|
||||
- **안 쓴다:** 마지막 값만 중요, 빈번한 in-place 수정, 복잡 조인 쿼리 중심 → 상태 저장/DB.
|
||||
|
||||
### 언제 큐(동시성 제한)를 쓰나
|
||||
- **쓴다:** 대량 작업이 자원(메모리/IO/소켓)을 폭주시킬 수 있을 때, 처리량을 일정하게.
|
||||
- **안 쓴다:** 작업이 소수거나 이미 락으로 직렬화될 때(중복 제어 불필요).
|
||||
|
||||
### 언제 락을 쓰나
|
||||
- **쓴다:** 같은 공유 자원(파일/세션)에 read-modify-write 가 동시에 일어날 수 있을 때.
|
||||
- **안 쓴다:** 불변 데이터, 단일 소유자, append-only 단일 프로세스.
|
||||
|
||||
### 언제 메모리 타입을 나누나
|
||||
- **나눈다:** 수명/만료/우선순위/검색 방식이 다른 기억이 섞일 때([[5계층 메모리 시스템]]).
|
||||
- **안 나눈다:** 단발성 도구(기억 불필요), 또는 전부 같은 정책이면 단일 버퍼.
|
||||
|
||||
### 언제 에이전트를 만드나 / 만들지 않나
|
||||
- **만든다:** 진짜 독립적 전문성 + 산출물이 명확히 분리 + 자원이 여러 모델/순차를 감당.
|
||||
- **만들지 않는다:** 단일 작성자가 역할만 바꿔도 되는 작업, hop 에서 원본 손실 위험, 자원이 빠듯할 때([[ADR-0003 단일작성자 다중역할 멀티에이전트]]). **기본값은 "에이전트를 늘리지 말 것".**
|
||||
|
||||
### 언제 상태를 영속화하나 / 휘발로 두나
|
||||
- **영속:** 세션을 넘어 필요(사용자 선호, 프로젝트 결정, 학습 케이스), 투명성 필요.
|
||||
- **휘발:** 현재 턴/세션 한정(단기 버퍼), 재계산이 싼 파생값, 민감해서 남기면 안 되는 것.
|
||||
|
||||
### 언제 추상화(인터페이스)를 도입하나
|
||||
- **도입:** 구현이 2개 이상이거나 곧 생김(로컬/클라우드 엔진), 테스트에 가짜가 필요(LLM 호출).
|
||||
- **안 함:** 구현이 하나뿐이고 변할 조짐 없음(과추상화 = 비용).
|
||||
|
||||
### 언제 결정론 vs LLM 을 쓰나
|
||||
- **결정론:** 매 턴 돌릴 저비용 신호(정규식·카운트·점수). latency 0 이 중요할 때.
|
||||
- **LLM:** 의미 판단이 필요하고, 결정론 신호가 위험을 표시했을 때만(조건부)([[ADR-0009 결정론 항상 LLM검증 조건부]]).
|
||||
|
||||
### 언제 동기 vs 비동기/병렬을 쓰나
|
||||
- **병렬:** 독립 작업 + 자원 여유. 의존 없으면 `Promise.all`.
|
||||
- **순차:** 자원 제약(모델 상주), 출력이 다음 입력(peer-context), 데드락 위험.
|
||||
|
||||
### 파일 분리/추출 기준
|
||||
- 한 파일이 한 화면을 크게 넘고 *여러 책임* 을 가지면 추출. 단, *흐름 골격* 은 한 곳에 남긴다([[ADR-0010 오케스트레이터 골격 모듈추출]]).
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
휴리스틱은 *기본값* 이지 법칙이 아니다. 충돌하면 [[엔지니어링 트레이드오프 분석]] 으로 내려가 맥락(자원·규모·팀)에 맞춰 판단하라. 가장 강한 메타 규칙: **YAGNI(필요해질 때 만들어라) + 단순함 우선 + 환경이 동시성·저장·검증을 결정한다.**
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
각 규칙은 AstraAI 의 실제 ADR 결정과 1:1 대응. 신규 기능 설계 시 이 목록을 먼저 훑는다.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[엔지니어링 트레이드오프 분석]], [[안티패턴 카탈로그]], [[리팩토링 플레이북]], [[프로젝트 독립 설계 원칙]]
|
||||
- **참조 맥락:** 로컬 LLM 이 "새 것을 만들지 말지" 를 빠르게 판단할 때 1차 규칙으로 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI 전체 ADR/서브시스템 결정의 역추출(본 위키 Engineering_Intelligence 모음)
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 결정 규칙 추출 초안.
|
||||
@@ -0,0 +1,117 @@
|
||||
---
|
||||
id: anti-patterns-catalog
|
||||
title: "안티패턴 카탈로그"
|
||||
category: "Software_Engineering"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["anti-patterns", "안티패턴", "피해야 할 것", "코드 냄새", "code smell"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["anti-pattern", "engineering", "pitfalls", "code-smell", "astraai"]
|
||||
raw_sources: ["AstraAI/src/core/lock.ts", "AstraAI/src/memory/index.ts", "AstraAI/src/retrieval/index.ts", "AstraAI/src/features/company/dispatcher.ts"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[안티패턴 카탈로그]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
안티패턴은 "처음엔 그럴듯하지만 시간이 지나면 버그·복잡도를 부르는 습관" 이며, AstraAI 가 *실제로 겪고 고친* 사례에서 추출한 것이라 작은 모델이 회피해야 할 1순위 목록이다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
각 안티패턴: **설명 / 왜 위험한가 / 증상 / 더 나은 대안 / 이 프로젝트의 사례(있으면)**.
|
||||
|
||||
## 📖 세부 내용 (Details · 안티패턴 모음)
|
||||
|
||||
### A-01. 무음 빈 catch (Silent swallow)
|
||||
- **설명:** `try { ... } catch {}` 로 에러를 이유 없이 삼킴.
|
||||
- **왜 위험:** 실패가 숨겨져 디버깅 불가, 잘못된 상태로 진행.
|
||||
- **증상:** "왜 아무 일도 안 일어나지?", 로그 없는 실패.
|
||||
- **더 나은 대안:** 본류 에러는 throw/처리. 부가 작업만 삼키되 *이유 주석* 필수.
|
||||
- **사례:** AstraAI 는 부가 작업에 한해 `catch { /* should never break main flow */ }` 로 정당화 [S2].
|
||||
|
||||
### A-02. Promise/객체 동일성에 로직 걸기
|
||||
- **설명:** `===` 로 Promise·새 객체를 비교해 분기.
|
||||
- **왜 위험:** `.then()`/`.map()` 등은 매번 새 인스턴스 → 비교 항상 false.
|
||||
- **증상:** cleanup 안 됨, 메모리 누수, 간헐 race.
|
||||
- **더 나은 대안:** 명시적 토큰/ID 비교.
|
||||
- **사례:** lock.ts 의 옛 버그 → Symbol 토큰으로 수정 [S1].
|
||||
|
||||
### A-03. `||` 로 기본값 — 의미 있는 0/''/false 삼킴
|
||||
- **설명:** `limit || 8` 처럼 falsy 전체를 대체.
|
||||
- **왜 위험:** 0/''/false 가 유효값인데 기본값으로 둔갑.
|
||||
- **증상:** "검색 끄기(0)" 가 무시되는 류의 미묘한 버그.
|
||||
- **더 나은 대안:** `??`(nullish) 사용.
|
||||
- **사례:** `brainFileLimit ?? 8` [S3].
|
||||
|
||||
### A-04. 에이전트 남발 (Multi-agent over-engineering)
|
||||
- **설명:** 문제마다 새 persona/에이전트를 추가.
|
||||
- **왜 위험:** hop 마다 컨텍스트 누적·원본 손실, 자원 폭증, 디버깅 난해.
|
||||
- **증상:** "분석 방법론" 만 나오고 실제 결과 없음, OOM.
|
||||
- **더 나은 대안:** 단일 작성자 다중 역할, 정말 필요한 협업만 순차.
|
||||
- **사례:** 5-persona → ChunkedWriter 전환 [S4].
|
||||
|
||||
### A-05. 거대 god-class (흐름·구현 한 덩어리)
|
||||
- **설명:** 모든 로직을 한 클래스/파일에.
|
||||
- **왜 위험:** 테스트 불가, 병합 충돌, 변경 두려움.
|
||||
- **증상:** 수천 줄 파일, "여길 고치면 저기가 깨짐".
|
||||
- **더 나은 대안:** 흐름 골격만 남기고 구현을 순수 모듈로 추출([[ADR-0010 오케스트레이터 골격 모듈추출]]).
|
||||
|
||||
### A-06. 이유 없는 동적 require/import
|
||||
- **설명:** 습관적으로 `await import()` 를 핫패스에서 반복.
|
||||
- **왜 위험:** 흐름 불명확, 불필요 오버헤드, 진짜 이유가 사라져도 잔존.
|
||||
- **증상:** 같은 모듈을 매 호출 동적 로드.
|
||||
- **더 나은 대안:** 순환이 없으면 정적 import. 동적은 *진짜 무거운/드문* 기능에만 + 이유 주석.
|
||||
- **사례:** dispatcher 의 require 8회 → 정적 promote [S4].
|
||||
|
||||
### A-07. 형식만 믿는 LLM 출력 파싱
|
||||
- **설명:** "JSON 만 출력" 을 믿고 `JSON.parse(raw)` 직접.
|
||||
- **왜 위험:** 작은 모델은 코드펜스·잡설을 섞어 파싱 실패.
|
||||
- **증상:** 간헐 파싱 예외, 빈 결과.
|
||||
- **더 나은 대안:** 균형 괄호 스캔 추출 + fallback. "프롬프트와 파서를 함께 설계".
|
||||
- **사례:** criticAgent 의 균형 `{}` 파서 [참조: [[Intelligence 검증 레이어]]].
|
||||
|
||||
### A-08. 점수 부분 정규화 (편향 융합)
|
||||
- **설명:** 여러 신호를 합치며 일부만 정규화.
|
||||
- **왜 위험:** 정규화 안 된 신호가 스케일로 상위 독식.
|
||||
- **증상:** 새 신호를 더했는데 품질이 *나빠짐*.
|
||||
- **더 나은 대안:** 모든 신호를 동일 스케일로 정규화 후 가중 합.
|
||||
- **사례:** 하이브리드 검색 [S3].
|
||||
|
||||
### A-09. 환경 무시한 동시성 가정
|
||||
- **설명:** "병렬이 빠르니 무조건 병렬".
|
||||
- **왜 위험:** 자원(RAM/GPU)을 넘으면 OOM·스왑으로 *더 느려지거나 죽음*.
|
||||
- **증상:** 로컬에서 멀티모델 로드 실패.
|
||||
- **더 나은 대안:** 타깃 하드웨어 기준으로 동시성 결정([[ADR-0004 순차 디스패치 채택]]).
|
||||
|
||||
### A-10. 만료 없는 영구 메모리
|
||||
- **설명:** 모든 기억을 영구 저장.
|
||||
- **왜 위험:** 시한부 사실(분기 계획)이 만료 후에도 검색돼 오답 유발.
|
||||
- **증상:** "지난 분기 계획" 을 현재처럼 답함.
|
||||
- **더 나은 대안:** temporal marker(`expiresAt`)로 자동 제외 + 증류 보존 [참조: [[5계층 메모리 시스템]]].
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
일부 "안티패턴" 은 맥락에 따라 정당하다 — god-class(흐름 가독성), 빈 catch(부가 작업), 동적 import(무거운 기능). 핵심은 *이유를 명시하고 의식적으로* 쓰는가다. 무의식적 습관일 때만 안티패턴.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
모두 AstraAI 가 실제로 마주쳐 고치거나 의식적으로 관리하는 사례. [[교훈 라이브러리 Lessons Learned]] 와 짝을 이룬다.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[교훈 라이브러리 Lessons Learned]], [[아키텍처 휴리스틱]], [[디버깅 플레이북]], [[코딩 컨벤션과 주석 철학]]
|
||||
- **참조 맥락:** 로컬 LLM 이 코드 작성/리뷰 시 회피 목록으로 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI/src/core/lock.ts — 동일성 비교 안티패턴
|
||||
- [S2] AstraAI/src/memory/index.ts — 빈 catch(정당화된 형태)
|
||||
- [S3] AstraAI/src/retrieval/index.ts — ?? vs ||, 부분 정규화
|
||||
- [S4] AstraAI/src/features/company/dispatcher.ts, AgentWorkflowManager.ts — 에이전트 남발, 동적 require
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 사례 기반 안티패턴 카탈로그 초안.
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
id: engineering-tradeoff-analysis
|
||||
title: "엔지니어링 트레이드오프 분석"
|
||||
category: "Software_Engineering"
|
||||
status: "draft"
|
||||
verification_status: "applied"
|
||||
canonical_id: ""
|
||||
aliases: ["tradeoff analysis", "트레이드오프", "무엇을 최적화 무엇을 희생", "설계 절충", "언제 실패하나"]
|
||||
duplicate_of: ""
|
||||
source_trust_level: "A"
|
||||
confidence_score: 0.9
|
||||
created_at: 2026-06-13
|
||||
updated_at: 2026-06-13
|
||||
review_reason: ""
|
||||
merge_history: []
|
||||
tags: ["tradeoff", "engineering", "decision", "architecture", "astraai"]
|
||||
raw_sources: ["AstraAI 전체 서브시스템 분석", "AstraAI/src/core/*", "AstraAI/src/retrieval/*", "AstraAI/src/intelligence/*"]
|
||||
applied_in: ["AstraAI"]
|
||||
github_commit: ""
|
||||
---
|
||||
|
||||
# [[엔지니어링 트레이드오프 분석]]
|
||||
|
||||
## 🎯 한 줄 통찰 (One-line insight)
|
||||
모든 설계는 "무언가를 최적화하기 위해 무언가를 희생"한 결과다 — AstraAI 의 각 서브시스템이 *무엇을 얻고 무엇을 포기했으며, 언제 그 선택이 깨지는지* 를 명시하면, 작은 모델이 맥락에 맞는 설계를 고를 수 있다.
|
||||
|
||||
## 🧠 핵심 개념 (Core concepts)
|
||||
- 트레이드오프 분석 = (최적화한 것 / 희생한 것 / 더 단순한 대안 / 더 확장적인 대안 / 이 설계가 실패하는 조건 / 다른 설계가 나은 조건).
|
||||
- 정답은 *맥락 의존* — 같은 결정도 환경이 바뀌면 오답이 된다.
|
||||
|
||||
## 📖 세부 내용 (Details · 서브시스템별 트레이드오프)
|
||||
|
||||
### 1. 이벤트 소싱 JSONL 저장 ([[이벤트 소싱 스토어 패턴]])
|
||||
- **최적화:** 이력 보존, 내결함, 코드 중복 제거, 무의존.
|
||||
- **희생:** 저장 공간(단조 증가), 상태 재생 비용, 복잡 쿼리.
|
||||
- **더 단순한 대안:** 상태 JSON 1개 덮어쓰기(이력 불필요 시).
|
||||
- **더 확장적인 대안:** SQLite/이벤트 스토어 DB + 스냅샷 compaction.
|
||||
- **실패 조건:** 이벤트가 수만 건↑, 멀티프로세스 동시 쓰기, 복잡 조인 필요.
|
||||
- **다른 설계가 나을 때:** 마지막 값만 중요하거나, 분석 쿼리가 핵심일 때.
|
||||
|
||||
### 2. 5계층 메모리 ([[5계층 메모리 시스템]])
|
||||
- **최적화:** 컨텍스트 정밀 선별, 계층별 정책(만료/승급).
|
||||
- **희생:** 분류 결정 비용, 매니저 복잡도, 다중 저장 파일.
|
||||
- **더 단순한 대안:** 최근 N 메시지 버퍼 + 단일 노트 저장.
|
||||
- **더 확장적인 대안:** 계층별 임베딩 + 벡터 DB 메타 필터.
|
||||
- **실패 조건:** 분류 규칙이 모호해 "어디 저장?" 이 매번 논쟁, 관련도 휴리스틱 오선별.
|
||||
- **다른 설계가 나을 때:** 단발성 도구(기억 불필요), 또는 순수 의미검색이 전부일 때.
|
||||
|
||||
### 3. 멀티에이전트(단일 작성자/순차) ([[Agent 오케스트레이터 분해]])
|
||||
- **최적화:** 자원 안전(한 모델 상주), 본문 보존, 컨텍스트 절약.
|
||||
- **희생:** 처리량/속도(순차), 단일 모델 품질 의존, 병렬 다양성.
|
||||
- **더 단순한 대안:** 단일 프롬프트 1회 호출(짧은 작업).
|
||||
- **더 확장적인 대안:** 워커 풀 병렬 + judge panel 합의(자원 충분 시).
|
||||
- **실패 조건:** 멀티 GPU 표준화, 대규모 병렬 리서치 요구, 누적 지연이 인내 초과.
|
||||
- **다른 설계가 나을 때:** 서버 배포·속도 critical.
|
||||
|
||||
### 4. 하이브리드 검색(결정론 우선) ([[RAG 검색 파이프라인]])
|
||||
- **최적화:** 가용성(임베딩 없어도 동작), 설명가능성.
|
||||
- **희생:** 스케일 정규화 복잡, 수작업 동의어 유지, 형태소 미분석.
|
||||
- **더 단순한 대안:** 키워드 includes 매칭.
|
||||
- **더 확장적인 대안:** BM25 + 벡터 DB + reranker 모델.
|
||||
- **실패 조건:** brain 규모 폭증(sparse 인덱스 부담), 동의어 사전 누락 누적.
|
||||
- **다른 설계가 나을 때:** 대규모·고품질 임베딩 상시 가용.
|
||||
|
||||
### 5. 검증(결정론 항상/LLM 조건부) ([[Intelligence 검증 레이어]])
|
||||
- **최적화:** 낮은 평균 latency, 위험 시 정밀 검수.
|
||||
- **희생:** 임계 오설정 시 미탐/오탐, 휴리스틱 가중치, 1-pass 약함.
|
||||
- **더 단순한 대안:** 검증 없음(빠르나 환각 방치).
|
||||
- **더 확장적인 대안:** 골든셋 학습 가중치 + 다회전 debate.
|
||||
- **실패 조건:** 모델 교체로 신호 분포 변화, 위험 도메인에서 1-pass 부족.
|
||||
- **다른 설계가 나을 때:** 대형 모델/서버에서 상시 LLM 검수 감당 가능.
|
||||
|
||||
### 6. 파일 저장(투명성 우선) ([[ADR-0005 파일 기반 저장 채택]])
|
||||
- **최적화:** 투명성, 무의존, git 친화.
|
||||
- **희생:** 쿼리 성능, 동시쓰기 잠금 직접, 인덱스 자가구축.
|
||||
- **실패 조건:** 멀티유저, 수만 파일, 복잡 분석.
|
||||
- **다른 설계가 나을 때:** 다중 사용자 SaaS, 대규모 분석.
|
||||
|
||||
### 7. 수동 DI(단일 composition root) ([[ADR-0006 수동 의존성주입 인터페이스 서비스]])
|
||||
- **최적화:** 투명한 조립, 테스트성, 무의존.
|
||||
- **희생:** 조립 코드 장황, 배선 수작업.
|
||||
- **실패 조건:** 모듈/조립 지점 폭증.
|
||||
- **다른 설계가 나을 때:** 대규모 팀/모듈, 동적 수명관리 필요 시 컨테이너.
|
||||
|
||||
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
|
||||
이 표의 모든 "희생" 은 *현재 환경(로컬·단일 사용자·작은 모델)* 전제다. 환경이 바뀌면 같은 표의 우열이 뒤집힌다 — 트레이드오프는 절대값이 아니라 *맥락 함수*.
|
||||
|
||||
## 🛠️ 적용 사례 (Applied in summary)
|
||||
각 행은 대응 ADR/서브시스템 문서의 결정 요약. 신규 설계 시 "내 환경에서 이 희생을 감당할 수 있나?" 를 먼저 묻는다.
|
||||
|
||||
## 🔗 지식 그래프 (Knowledge Graph)
|
||||
- **상위/루트:** [[AstraAI 아키텍처 개요]]
|
||||
- **관련 개념:** [[아키텍처 휴리스틱]], [[안티패턴 카탈로그]], [[ADR-0001 이벤트 소싱 채택]], [[리팩토링 플레이북]]
|
||||
- **참조 맥락:** 로컬 LLM 이 설계 선택 시 "무엇을 희생하는지" 와 "언제 깨지는지" 를 평가할 때 참조.
|
||||
|
||||
## 📚 출처 (Sources)
|
||||
- [S1] AstraAI 서브시스템 분석(core/retrieval/intelligence/memory) 및 본 위키의 ADR 모음
|
||||
|
||||
## 📝 변경 이력 (Change history)
|
||||
- 2026-06-13: AstraAI 트레이드오프 종합 분석 초안 생성.
|
||||
Reference in New Issue
Block a user