wiki: Topic_Blog 신규 문서 일괄 추가 + ASTRA 성장 자산 동기화

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Antigravity Agent
2026-06-16 09:55:38 +09:00
parent d77ff5c625
commit e2c5471046
444 changed files with 88916 additions and 231 deletions
@@ -0,0 +1,83 @@
---
id: topic-programming-index
title: "Topic Programming 인덱스"
category: "Index"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["프로그래밍 위키 인덱스", "Topic_Programming 목차", "second brain coding index", "코딩 제2뇌 목차"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.95
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["index", "navigation", "programming", "second-brain", "connectai"]
raw_sources: ["Topic_Programming 전체"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Topic Programming 인덱스]]
## 🎯 한 줄 통찰 (One-line insight)
이 위키는 "로컬 작은 LLM(Gemma/Qwen/Llama 등)의 코딩·설계 능력을 제2뇌 지식으로 끌어올린다" 는 목적의 지식 베이스로, ConnectAI 코드 분석에서 출발해 **언어 → 아키텍처 → 서브시스템 → 설계 결정(ADR) → 패턴 → 실패 → 플랫폼 → 일반 원칙** 으로 추상도를 높여간다.
## 🧠 핵심 개념 (Core concepts)
- **목적:** 코드 설명이 아니라 *전이 가능한 엔지니어링 지능* 을 작은 모델에 제공.
- **출처:** 1차 코드는 ConnectAI(Astra) VS Code 확장(TypeScript, 308 파일). 일반 지식은 표준 소프트웨어 공학.
- **포맷:** P-Reinforce v3.1(frontmatter + 이모지 섹션 + [[위키링크]] + 출처).
## 📖 세부 내용 (Details · 전체 지도)
### 작은 모델 권장 학습 순서 (사용자 우선순위)
1. **프로젝트 위키** → 2. **설계 결정(ADR)** → 3. **패턴 라이브러리** → 4. **실패 라이브러리** → 5. **플랫폼별 개발 패턴** → 6. **일반 원칙**.
### 1) 언어 지식 (Language/)
- [[TypeScript 기초와 타입 시스템]] · [[TypeScript 고급 타입]] · [[비동기 프로그래밍 Promise async await]] · [[모듈 시스템과 프로젝트 구성]] · [[에러 처리와 커스텀 에러]]
### 2) 아키텍처·설계 (Architecture/)
- [[ConnectAI 아키텍처 개요]] · [[VSCode 확장 구조와 생명주기]] · [[의존성 주입과 서비스 인터페이스]] · [[이벤트 소싱 스토어 패턴]] · [[동시성 제어 Lock Queue Transaction]]
### 3) 서브시스템 심층 (Subsystems/)
- [[5계층 메모리 시스템]] · [[RAG 검색 파이프라인]] · [[TF-IDF 이중언어 스코어링]] · [[LLM 프로바이더 추상화]] · [[Intelligence 검증 레이어]] · [[Agent 오케스트레이터 분해]]
### 4) 컨벤션 (Conventions/)
- [[코딩 컨벤션과 주석 철학]] · [[프롬프트 엔지니어링 패턴]]
### 5) 설계 결정 — ADR (Engineering_Intelligence/ADR/)
- [[ADR-0001 이벤트 소싱 채택]] · [[ADR-0002 5계층 메모리 분리]] · [[ADR-0003 단일작성자 다중역할 멀티에이전트]] · [[ADR-0004 순차 디스패치 채택]] · [[ADR-0005 파일 기반 저장 채택]] · [[ADR-0006 수동 의존성주입 인터페이스 서비스]] · [[ADR-0007 하이브리드 검색 결정론 우선]] · [[ADR-0008 로컬우선 LLM 클라우드 폴백]] · [[ADR-0009 결정론 항상 LLM검증 조건부]] · [[ADR-0010 오케스트레이터 골격 모듈추출]]
### 6) 엔지니어링 지능 (Engineering_Intelligence/)
- [[엔지니어링 트레이드오프 분석]] · [[교훈 라이브러리 Lessons Learned]] · [[안티패턴 카탈로그]] · [[아키텍처 휴리스틱]] · [[리팩토링 플레이북]] · [[디버깅 플레이북]]
- AI 학습 추출: [[AITRAIN 메모리 시스템]] · [[AITRAIN RAG 검색]] · [[AITRAIN 에이전트 오케스트레이션]] · [[AITRAIN 검증 레이어]] · [[AITRAIN 이벤트소싱 저장]] · [[AITRAIN 동시성 제어]] · [[AITRAIN 프로바이더 추상화]]
### 7) 패턴 카탈로그 (Pattern_Catalog/) → [[패턴 카탈로그 인덱스]]
- AI · Cross-cutting · Web · Mobile · Desktop 패턴 27종.
### 8) 실패 라이브러리 (Failure_Library/)
- [[소프트웨어 실패 라이브러리]]
### 9) 플랫폼 가이드 (Platform_Guides/) → [[플랫폼 개발 가이드 인덱스]]
- [[웹 개발 가이드]] · [[데스크탑 앱 개발 가이드]] · [[모바일 개발 가이드]] · [[백엔드 API 개발 가이드]] · [[AI 에이전트 개발 가이드]]
### 10) 일반 원칙 (Generalized_Principles/)
- [[프로젝트 독립 설계 원칙]] — 모든 것의 capstone(12원칙).
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
ConnectAI 사례 기반 지식은 *로컬·단일 사용자·작은 모델* 전제다. 다른 환경에선 [[엔지니어링 트레이드오프 분석]] 으로 재평가하라. 모든 문서는 draft — 사용하며 검증/보강.
## 🛠️ 적용 사례 (Applied in summary)
이 인덱스를 진입점으로, 작은 모델은 질의에 맞는 계층(언어/패턴/실패/원칙)을 RAG 로 회수해 컨텍스트에 주입한다.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[Topic Programming 인덱스]]
- **관련 개념:** [[ConnectAI 아키텍처 개요]] · [[패턴 카탈로그 인덱스]] · [[플랫폼 개발 가이드 인덱스]] · [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 제2뇌 전체의 목차이자 진입점.
## 📚 출처 (Sources)
- [S1] Topic_Programming 전체 문서 + ConnectAI 소스 분석
## 📝 변경 이력 (Change history)
- 2026-06-13: 제2뇌 코딩 지식 베이스 마스터 인덱스 생성.
@@ -0,0 +1,104 @@
---
id: connectai-architecture-overview
title: "ConnectAI 아키텍처 개요"
category: "Architecture"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["Astra", "ConnectAI", "feature-based architecture", "전체 구조", "모듈 아키텍처", "제2뇌 OS"]
duplicate_of: ""
source_trust_level: "S"
confidence_score: 0.95
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["architecture", "connectai", "feature-based", "layering", "overview"]
raw_sources: ["ConnectAI/src/extension.ts", "ConnectAI/src 트리(308 TS 파일)", "ConnectAI/package.json", "ConnectAI/src/core/services.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[ConnectAI 아키텍처 개요]]
## 🎯 한 줄 통찰 (One-line insight)
ConnectAI(Astra)는 "로컬 LLM 을 두뇌로 쓰는 VS Code 확장형 자기진화 지식 OS"이며, **기능별 폴더 경계 + 얇은 entry point + 핵심 인프라(core) 위에 도메인(features)을 쌓는 계층형 모듈 아키텍처**로 308개 파일을 조직한다 [S1][S2].
## 🧠 핵심 개념 (Core concepts)
1. **Feature-based 구조:** `src/features/` 아래 각 폴더가 독립 기능(stocks, calendar, company, datacollect, devilAgent…). 기능 간 결합을 최소화하고, 공통 인프라만 `core/`/`lib/` 에서 공유 [S2].
2. **계층 분리:** `core`(인프라) → `lib`/`memory`/`retrieval`/`intelligence`(역량) → `features`(기능) → `extension.ts`(조립). 아래 계층은 위를 모른다 [S2].
3. **얇은 entry point:** `extension.ts``activate()`*조립과 등록만* 한다 — 객체 생성, 의존성 주입, 명령 등록, 워처 시작. 로직은 전부 모듈에 위임 [S1].
4. **의존성 주입:** 생성자에 옵션 객체로 협력자를 주입(`new AgentExecutor(context, { lmStudioStreamer, approvalQueue, ... })`) — 테스트·교체 용이 [S1].
5. **싱글톤 인프라:** 프로세스 전역이 자연스러운 자원(`lockManager`, `actionQueue`)은 모듈 싱글톤으로 export [S1].
## 🧩 추출된 패턴 (Extracted patterns)
- **God-class 분해:** 거대해지는 orchestrator(`agent.ts`)를 `handlePrompt/`, `llm/`, `actions/`, `multiAgent/`, `sessions/` 하위 모듈로 쪼개 함수 단위로 추출하고, orchestrator 는 이들을 호출만 한다 [참조: [[Agent 오케스트레이터 분해]]].
- **인터페이스 우선 서비스:** `IAIService`/`IBrainService` 인터페이스를 두고 구현(`AIService`)을 분리 — 엔진 폴백 같은 정책을 구현체에 캡슐화 [S3].
- **자기등록 핸들러:** slashRouter 에 핸들러가 side-effect import 로 자기 등록 — 새 명령 추가 시 중앙 등록표를 건드리지 않음 [S1].
- **부트스트랩 분리:** 활성화 시 필요한 초기화(brain 디렉터리, 임베딩 감지, 기능 인벤토리)를 `extension/*Bootstrap.ts` 로 분리해 entry point 를 얇게 유지 [S1].
- **disposable 수명 관리:** 생성한 모든 자원을 `context.subscriptions.push(...)` 로 등록해 확장 종료 시 일괄 정리 [S1].
## 📖 세부 내용 (Details)
### 디렉터리 지도 (역할별)
- **core/** — 횡단 인프라: `lock`, `queue`, `transaction`, `errors`, `errorHandler`, `services`(AI/Brain 서비스), `session`, `events`, `health`, `telemetry`, `statusBar`.
- **memory/** — 5계층 인지 메모리(Short/Long/Project/Procedural/Episodic) + `distillation`. → [[5계층 메모리 시스템]].
- **retrieval/** — RAG 파이프라인: `chunker`, `scoring`(TF-IDF), `embeddings`, `brainIndex`, `contextBudget`, rerank 류. → [[RAG 검색 파이프라인]].
- **intelligence/** — 검증·자기평가: `criticAgent`, `confidenceEngine`, `correctionLoop`, `epistemicGuardBlock`, `knowledgeValidation`. → [[Intelligence 검증 레이어]].
- **lib/contextBuilders/** — 프롬프트에 들어갈 컨텍스트 블록을 조립하는 순수 함수 모음(메모리·프로젝트·일정·자기인식 등 30+개).
- **features/** — 도메인 기능. 각자 `index.ts`(공개 API) + store + handler + prompt 로 구성되는 경향.
- **agent/** + **agents/** — 에이전트 실행 세부와 다중 에이전트 워크플로 매니저.
- **integrations/** — 외부 연동(telegram).
- **sidebar/** + **sidebarProvider.ts** — 웹뷰 UI 와 메시지 핸들러.
- **system/**, **lmstudio/**, **scaffolder/**, **skills/** — 시스템 사양 탐지, LM Studio SDK 수명관리, 프로젝트 스캐폴딩, 스킬 로딩.
### 제어 흐름 (한 턴의 처리)
1. 웹뷰(사이드바)에서 사용자 입력 → `sidebar/chatHandlers``AgentExecutor`.
2. `agent/handlePrompt/*` 가 컨텍스트 블록(메모리·RAG·프로젝트·일정)을 조립.
3. 모델 라우팅: 클라우드 prefix 면 provider 어댑터, 아니면 로컬 엔진(LM Studio/Ollama). → [[LLM 프로바이더 추상화]].
4. 스트리밍 응답 → 후처리(sanitize, devil rebuttal) → post-answer hooks(critic 검수, 교정 캡처).
5. 세션 종료 시 메모리 추출/증류, 성장 사이클 워처가 폐루프로 학습.
### 빌드/런타임
- esbuild 단일 번들(`out/extension.js`), `vscode` external. 런타임 의존성은 `@lmstudio/sdk`, `pdf-parse` 둘뿐 — 나머지는 native API(fetch 등)로 자급 [S2].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **단일 거대 agent.ts(1681줄):** 분해를 했음에도 orchestrator 가 여전히 크다. 이는 "한 턴의 제어 흐름을 한 곳에서 읽을 수 있게" 하려는 의도적 트레이드오프 — 세부는 추출하되 흐름의 골격은 남긴다.
- **features 간 결합:** 일부 기능(company, stocks)은 텔레그램·시트 등 여러 통합을 동시에 참조해 완전 독립은 아니다. core/lib 를 통한 간접 결합으로 완화.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/extension.ts``activate()` 전체가 "얇은 조립 entry point" 의 교과서적 예 — 25개+ 모듈을 생성·주입·등록하지만 비즈니스 로직은 0 [S1].
## 💻 코드 패턴 (Code patterns)
```typescript
// activate(): 조립과 등록만 — 로직은 모듈에 위임 (src/extension.ts 발췌)
export async function activate(context: vscode.ExtensionContext) {
await ensureDefaultBrainConfigured(); // 부트스트랩 분리
void ensureEmbeddingConfigured(context); // 비차단 best-effort
initAstraPathResolver(context);
const lmStudioClient = new LMStudioClient(getConfig().ollamaUrl);
const agent = new AgentExecutor(context, { // 생성자 의존성 주입
onStreamLifecycle: { start: () => lifecycle.onStreamStart(), end: () => lifecycle.onStreamEnd() },
lmStudioStreamer, approvalQueue,
});
const provider = new SidebarChatProvider(context.extensionUri, context, agent, { lifecycle, /* ... */ });
context.subscriptions.push( // 수명 관리: 종료 시 일괄 dispose
vscode.commands.registerCommand('g1nation.openChat', () => provider.openAsPanel(vscode.ViewColumn.Three)),
...registerProviderCommands(context, { getProvider: () => provider }),
);
}
```
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[VSCode 확장 구조와 생명주기]], [[의존성 주입과 서비스 인터페이스]], [[Agent 오케스트레이터 분해]], [[모듈 시스템과 프로젝트 구성]]
- **참조 맥락:** 로컬 LLM 이 새 기능을 "어느 계층/폴더에 어떤 형태로" 추가할지 판단할 때 최상위 지도로 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/extension.ts — activate/deactivate, 조립·주입·등록·부트스트랩
- [S2] ConnectAI/src 디렉터리 트리(308 TS 파일) + package.json — 계층/번들 구성
- [S3] ConnectAI/src/core/services.ts — IAIService/IBrainService 인터페이스 우선 설계
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 전체 코드 분석 기반 초안 생성.
@@ -0,0 +1,122 @@
---
id: vscode-extension-structure-lifecycle
title: "VSCode 확장 구조와 생명주기"
category: "Architecture"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["VS Code Extension", "activate", "deactivate", "Disposable", "Webview", "command 등록", "extension API"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.93
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["vscode", "extension", "lifecycle", "disposable", "webview", "connectai"]
raw_sources: ["ConnectAI/src/extension.ts", "ConnectAI/package.json", "ConnectAI/src/features/_shared/eventSourcedStore.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[VSCode 확장 구조와 생명주기]]
## 🎯 한 줄 통찰 (One-line insight)
VS Code 확장은 `activate(context)` 에서 깨어나 명령·뷰·이벤트를 등록하고 `deactivate()` 에서 정리되며, 모든 자원을 **`context.subscriptions` 에 Disposable 로 등록**해 두면 확장 종료 시 메모리/타이머/리스너가 누수 없이 일괄 정리된다 [S1].
## 🧠 핵심 개념 (Core concepts)
1. **`activate(context)`:** 확장 진입점. `package.json` 의 activationEvents 조건이 충족되면 호출된다. `context: ExtensionContext` 가 전역 상태·구독·시크릿 저장소를 제공 [S1].
2. **`deactivate()`:** 종료 훅. 명시적으로 풀어야 하는 자원(외부 프로세스, 봇, 모델 언로드)을 여기서 정리 [S1].
3. **Disposable 패턴:** `{ dispose(): void }` 를 가진 객체. `context.subscriptions.push(disposable)` 하면 VS Code 가 종료 시 `dispose()` 를 호출 [S1].
4. **Command:** `vscode.commands.registerCommand(id, handler)` 로 등록, `package.json``contributes.commands` 에 선언. 반환값이 Disposable [S1].
5. **Webview:** HTML 기반 커스텀 UI. 확장↔웹뷰는 `postMessage` 로 통신. ConnectAI 는 사이드바 대신 *에디터 컬럼* 에 패널로 띄운다 [S1].
6. **Configuration:** `vscode.workspace.getConfiguration('g1nation')` 으로 설정 읽기, `onDidChangeConfiguration` 으로 변경 반응 [S1].
7. **SecretStorage:** 토큰 등 민감정보는 `context.secrets` 에 저장(평문 설정 금지) [S1].
## 🧩 추출된 패턴 (Extracted patterns)
- **모든 자원을 subscriptions 로:** 명령·리스너·상태바·타이머·커스텀 dispose 콜백까지 전부 `context.subscriptions.push(...)` — 정리를 잊지 않는 구조적 보장 [S1].
- **설정 변경 반응:** `onDidChangeConfiguration((e) => { if (!e.affectsConfiguration('g1nation.ollamaUrl')) return; ... })` — 관심 키만 필터링해 재설정 [S1].
- **lazy webview 전송:** 매우 이른 활성화 시점엔 웹뷰가 아직 없을 수 있어 `provider?._sendModels(...)` 옵셔널 체이닝 + best-effort [S1].
- **getter 콜백으로 늦은 바인딩:** 아직 안 만들어진 객체는 `getProvider: () => provider` 처럼 getter 로 주입 — 순환 의존/초기화 순서 문제 회피 [S1].
- **워처 = disposable 반환 함수:** `startStocksWatcher(context)` 가 타이머를 만들고 disposable 을 반환해 subscriptions 에 등록 → 종료 시 timer cleanup [S1].
## 📖 세부 내용 (Details)
### activate 의 책임 순서 (ConnectAI 실제 순서)
1. 가시화(버전 popup/console) → 환경 진단.
2. 부트스트랩(brain 디렉터리, 임베딩 감지, 기능 인벤토리) — 일부는 `void` 비차단.
3. 인프라 초기화(health monitor, path resolver, config 검증).
4. 핵심 객체 생성·주입(LMStudioClient, lifecycle, AgentExecutor, SidebarChatProvider, BridgeServer).
5. 명령·리스너 등록.
6. 워처 시작(stocks, daily briefing, growth cycle, sleep digest).
7. 웹뷰 자동 오픈.
### deactivate 의 책임
`HealthCheckMonitor.dispose()`, 인메모리 인덱스 해제(`clearBrainTokenIndex()` — Map 이 프로세스 수명 동안 안 비는 것 방지), 텔레그램 봇 stop, 모델 lifecycle dispose+unload. *명시적 정리가 필요한 것만* 여기서 처리하고, subscriptions 로 등록된 것은 VS Code 가 알아서 정리한다 [S1].
### 설정·시크릿
```typescript
const cfg = vscode.workspace.getConfiguration('g1nation');
const timeout = cfg.get<number>('lmStudio.idleTimeoutMs', 300000); // 기본값 동반
const token = await context.secrets.get(TELEGRAM_TOKEN_SECRET_KEY); // 민감정보는 secrets
```
### Webview 통신
확장→웹뷰는 `webview.postMessage({ type: 'streamChunk', value })`, 웹뷰→확장은 메시지 핸들러(`sidebar/chatHandlers`). 스트리밍은 `streamStart`/`streamChunk`/`streamEnd` 의 메시지 프로토콜로 표현 [참조: [[Agent 오케스트레이터 분해]]].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **사이드바 뷰 제거(v2.81):** 과거엔 activity bar 사이드바에 webview view 를 등록했으나, 현재는 에디터 컬럼 3에 패널로 띄운다. 대신 activity bar 에는 명령 링크만 있는 빈 TreeView 를 둔다 — 탭이 닫혀도 다시 열 수 있게 [S1].
- **activationEvents:** 너무 광범위하면(예: `*`) 시작이 느려진다. 필요한 이벤트로 좁히는 것이 좋다(ConnectAI 는 명령/뷰 기반).
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/extension.ts` — activate/deactivate 의 전 과정, subscriptions 등록, 설정 반응, secrets 사용, 워처 등록이 모두 한 파일에 [S1].
- `ConnectAI/src/features/_shared/eventSourcedStore.ts``vscode.workspace.workspaceFolders` 로 워크스페이스 경로 해석(확장에서 파일 경로 다루는 표준 방식) [S3].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 명령 등록 → 반환된 Disposable 을 subscriptions 로 (src/extension.ts)
context.subscriptions.push(
vscode.commands.registerCommand('g1nation.clearChat', () => provider.clearChat()),
);
// 2) 설정 변경 반응 — 관심 키만 (src/extension.ts)
context.subscriptions.push(
vscode.workspace.onDidChangeConfiguration((e) => {
if (!e.affectsConfiguration('g1nation.ollamaUrl')) return;
const newUrl = vscode.workspace.getConfiguration('g1nation').get<string>('ollamaUrl', '');
lmStudioClient.setBaseUrl(newUrl);
}),
);
// 3) 커스텀 dispose 콜백도 disposable 로 등록
context.subscriptions.push({ dispose: () => activityTracker.dispose() });
// 4) getter 콜백으로 늦은 바인딩 (순환/초기화 순서 회피)
const telegramBot = createTelegramBot(context, { telegramClient, getProvider: () => provider });
// 5) deactivate — 명시 정리가 필요한 것만
export async function deactivate() {
HealthCheckMonitor.dispose();
clearBrainTokenIndex();
if (_telegramBot) { try { await _telegramBot.stop(); } catch {} }
}
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.93
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[의존성 주입과 서비스 인터페이스]], [[모듈 시스템과 프로젝트 구성]], [[동시성 제어 Lock Queue Transaction]]
- **참조 맥락:** 로컬 LLM 이 VS Code 확장의 명령/뷰/설정/수명관리 코드를 작성·수정할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/extension.ts — activate/deactivate, subscriptions, 명령/설정/시크릿/웹뷰/워처
- [S2] ConnectAI/package.json — engines.vscode, main, contributes(명령/뷰)
- [S3] ConnectAI/src/features/_shared/eventSourcedStore.ts — workspaceFolders 경로 해석
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,129 @@
---
id: concurrency-lock-queue-transaction
title: "동시성 제어 Lock Queue Transaction"
category: "Architecture"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["concurrency", "AsyncLock", "mutex", "race condition", "동시성", "큐", "concurrency limit", "트랜잭션"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.94
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["architecture", "concurrency", "lock", "queue", "transaction", "connectai"]
raw_sources: ["ConnectAI/src/core/lock.ts", "ConnectAI/src/core/queue.ts", "ConnectAI/src/core/transaction.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[동시성 제어 Lock Queue Transaction]]
## 🎯 한 줄 통찰 (One-line insight)
단일 스레드 JavaScript 도 `await` 사이에 다른 작업이 끼어들어 *경쟁 상태(race condition)* 가 생기며, ConnectAI 는 **자원별 비동기 락(AsyncLock)·동시성 제한 큐·파일 보상 트랜잭션** 세 가지로 "한 번에 하나만·자원을 폭주시키지 않고·실패하면 되돌리는" 동시성 안전을 확보한다 [S1][S2][S3].
## 🧠 핵심 개념 (Core concepts)
1. **JS 의 동시성:** 단일 스레드라도 `await` 지점에서 제어가 넘어가므로, 같은 파일을 동시에 읽고-수정-쓰면 갱신 손실이 난다. 직렬화가 필요 [S1].
2. **비동기 뮤텍스 (AsyncLock):** 자원 ID 별로 "이전 작업이 끝나야 다음이 시작"되는 Promise 체인. `acquire` 가 release 함수를 반환, `try/finally` 로 반드시 해제 [S1].
3. **데드락 방지 타임아웃:** 락 대기를 `Promise.race([previous, timeout])` 로 감싸 무한 대기 차단 [S1].
4. **동시성 제한 큐:** 동시에 실행되는 작업 수를 `max(2, cpus-1)` 로 제한해 I/O·메모리 폭주 방지 [S2].
5. **보상 트랜잭션:** 파일시스템에 트랜잭션이 없으므로, 변경 전 백업→실패 시 복원으로 원자성을 흉내 [S3].
## 🧩 추출된 패턴 (Extracted patterns)
- **고유 토큰으로 안전한 정리:** 각 락 entry 에 `Symbol` 토큰을 부여하고, cleanup/release 시 "내 토큰이 아직 Map 의 최신인지" 확인 후에만 삭제 — 연쇄 호출 시 다른 작업 entry 를 지우는 race 방지 [S1].
- **release 는 반드시 try/finally:** `const release = await lock.acquire(id); try { ... } finally { release(); }` — 예외가 나도 락이 풀리게 [S1].
- **enqueue 가 Promise 반환:** `enqueue<T>(task)` 가 작업 결과 Promise 를 돌려주되 실행은 슬롯이 빌 때 — 호출부는 평소처럼 await [S2].
- **micro-delay 로 숨통:** 무거운 I/O 사이 `await sleep(10)` 로 시스템에 여유 [S2].
- **begin/record/commit/rollback:** 변경 전 `record(파일)` 로 백업, 성공 `commit`(백업 폐기), 실패 `rollback`(원복) [S3].
## 📖 세부 내용 (Details)
### AsyncLock 의 핵심 — Promise 체인 + 토큰
```typescript
const previousPromise = this.locks.get(resourceId)?.promise ?? Promise.resolve();
const token = Symbol(`lock:${resourceId}`);
let release!: () => void;
const newPromise = new Promise<void>((resolve) => { release = resolve; });
this.locks.set(resourceId, { promise: previousPromise.then(() => newPromise), token });
await Promise.race([previousPromise, timeoutPromise]); // 앞 작업 끝날 때까지(타임아웃 보호)
return () => { release(); if (this.locks.get(resourceId)?.token === token) this.locks.delete(resourceId); };
```
**버그 사후기록(주석)**: 옛 구현은 `.then(...)` 이 매번 새 Promise 를 반환해 동일성 비교가 *항상 false* → cleanup 실패. 또 release 시 무조건 `delete` 해서 연쇄 호출 시 다른 작업 entry 를 지우는 race. → 각 entry 에 고유 symbol 을 부여하고 "내 토큰이 최신일 때만" 정리하도록 수정 [S1].
### 동시성 제한 큐
```typescript
function defaultConcurrencyLimit() { return Math.max(2, (os.cpus()?.length ?? 4) - 1); } // UI 스레드 여유
public async enqueue<T>(task: () => Promise<T>): Promise<T> {
return new Promise<T>((resolve, reject) => {
this.queue.push(async () => { try { resolve(await task()); } catch (e) { reject(e); } });
this.processNext();
});
}
```
`processNext``activeCount < limit` 일 때만 다음 작업을 꺼내 실행하고, `finally` 에서 `activeCount--` 후 재귀로 다음을 당긴다. 무거운 LLM 호출은 큐가 아니라 `missionId` 락으로 직렬화하므로 큐는 단순하게 유지 [S2].
### 보상 트랜잭션 (파일 원자성)
`isTransactionActive` 가드로 중복 begin 방지. `record` 는 같은 파일을 한 번만 백업(이미 있으면 skip). rollback 은 `created` 파일은 삭제, `modified` 는 원본 내용으로 복원. 외부 API 호출 성공 여부도 `recordExternalAction` 으로 추적해 `isFullyVerified()` 로 전체 검증 [S3].
## ⚖️ 비교 및 선택 기준 (Comparison & decision criteria)
| 도구 | 막는 문제 | 사용 시점 |
|---|---|---|
| AsyncLock (자원별) | 같은 자원 동시 수정(갱신 손실) | 파일/세션 등 공유 자원 read-modify-write |
| 동시성 제한 큐 | 자원 폭주(메모리/IO/소켓) | 대량 작업을 일정 동시성으로 처리 |
| 보상 트랜잭션 | 부분 실패로 인한 불일치 | 여러 파일을 한 단위로 변경 |
| 외부 abort signal | 취소 불가 | 사용자 Stop / 타임아웃 ([[비동기 프로그래밍 Promise async await]]) |
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **락 타임아웃의 부작용:** 타임아웃으로 깨어난 작업은 자원을 못 얻은 채 throw 한다. 호출부는 이 실패를 재시도/사용자 안내로 처리해야 한다(조용히 진행 금지).
- **큐의 static 동시성:** 동적 조정이 없어 부하 급변에 둔감하지만, 무거운 작업이 락으로 직렬화되므로 큐는 단순함을 택했다 — 의도적 단순성.
- **메모리 내 트랜잭션:** 백업이 메모리(Map)에 있어 프로세스가 죽으면 롤백이 불가능하다. 진짜 내구성이 필요하면 WAL/DB 가 필요.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/core/lock.ts``lockManager` 싱글톤. agent 가 파일/세션 작업 직렬화에 사용 [S1].
- `ConnectAI/src/core/queue.ts``actionQueue` 싱글톤. 대량 액션 처리 [S2].
- `ConnectAI/src/core/transaction.ts` — AgentExecutor 가 파일 다중 변경을 묶을 때 [S3].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 락 — 반드시 try/finally 로 해제 (src/core/lock.ts)
const release = await lockManager.acquire(filePath);
try {
const cur = fs.readFileSync(filePath, 'utf-8');
fs.writeFileSync(filePath, transform(cur)); // read-modify-write 직렬화
} finally {
release(); // 예외가 나도 반드시 해제
}
// 2) 동시성 제한 큐 (src/core/queue.ts)
const result = await actionQueue.enqueue(() => heavyTask(item)); // 슬롯 빌 때 실행
// 3) 보상 트랜잭션 (src/core/transaction.ts)
tx.begin();
try {
await tx.record(fileA); fs.writeFileSync(fileA, nextA);
await tx.record(fileB); fs.writeFileSync(fileB, nextB);
tx.commit();
} catch (e) { tx.rollback(); throw e; }
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.94
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[비동기 프로그래밍 Promise async await]], [[에러 처리와 커스텀 에러]], [[이벤트 소싱 스토어 패턴]]
- **참조 맥락:** 로컬 LLM 이 공유 자원·대량 작업·다중 파일 변경의 동시성 안전 코드를 작성할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/core/lock.ts — AsyncLockManager(토큰 기반), race 타임아웃, 버그 사후기록
- [S2] ConnectAI/src/core/queue.ts — ActionQueueManager 동시성 제한
- [S3] ConnectAI/src/core/transaction.ts — 보상 트랜잭션(begin/record/commit/rollback)
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,128 @@
---
id: dependency-injection-service-interface
title: "의존성 주입과 서비스 인터페이스"
category: "Architecture"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["DI", "dependency injection", "인터페이스", "service interface", "느슨한 결합", "testability", "전략 패턴"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.93
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["architecture", "dependency-injection", "interface", "design-pattern", "connectai"]
raw_sources: ["ConnectAI/src/core/services.ts", "ConnectAI/src/extension.ts", "ConnectAI/src/intelligence/criticAgent.ts", "ConnectAI/src/agent/multiAgent/workflow.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[의존성 주입과 서비스 인터페이스]]
## 🎯 한 줄 통찰 (One-line insight)
의존성 주입은 "객체가 협력자를 *직접 만들지 않고 밖에서 받는*" 설계이며, ConnectAI 는 **인터페이스로 계약을 정의하고, 생성자 옵션 객체·함수 타입으로 구현을 주입**해 모듈을 순수하고 교체·테스트 가능하게 만든다 [S1][S3].
## 🧠 핵심 개념 (Core concepts)
1. **인터페이스 = 계약:** `IAIService`/`IBrainService` 는 "무엇을 할 수 있는가"만 정의하고 "어떻게" 는 구현에 맡긴다. 호출부는 인터페이스에만 의존 [S1].
2. **생성자 주입 (Constructor injection):** 협력자를 `new X(deps)` 처럼 생성 시점에 옵션 객체로 받는다 — 객체가 자기 의존을 숨기지 않고 시그니처에 드러낸다 [S2].
3. **함수 주입 (Function injection):** 무거운 의존(LLM 호출)을 *함수 타입* 으로 받아, 모듈 자체는 LLM 을 모른 채 순수 함수로 남는다 (`CritiqueLlmCall`) [S3].
4. **getter 주입 (Lazy):** 아직 생성되지 않은 의존은 `getProvider: () => provider` 처럼 getter 로 — 초기화 순서/순환 의존 회피 [S2].
5. **deps 번들 객체:** 여러 협력자를 `WorkflowDeps` 같은 인터페이스로 묶어 한 번에 전달 [S4].
## 🧩 추출된 패턴 (Extracted patterns)
- **인터페이스 선언 → 구현 클래스:** `interface IAIService { ... }` + `class AIService implements IAIService { ... }`. 정책(엔진 폴백)은 구현에 캡슐화, 호출부는 인터페이스만 본다 [S1].
- **옵션 객체로 생성자 주입:** `new AgentExecutor(context, { onStreamLifecycle, lmStudioStreamer, approvalQueue })` — 위치 인자 대신 명명 옵션으로 가독성·확장성 확보 [S2].
- **함수 타입으로 LLM 추상화:** `type CritiqueLlmCall = (system, user, maxTokens) => Promise<string>` 를 주입받아, criticAgent 는 어떤 엔진이든 무관하게 동작하고 테스트 시 가짜 함수를 끼운다 [S3].
- **deps 인터페이스 + 콜백 게터:** `WorkflowDeps { getWebview, getAbortSignal, chatHistory, ... }` — 동적으로 바뀌는 상태는 게터로 전달해 stale 참조 방지 [S4].
- **싱글톤 vs 주입 구분:** 프로세스 전역 자원(lock/queue)은 싱글톤, 정책·상태를 가진 협력자는 주입 [S2].
## 📖 세부 내용 (Details)
### 왜 인터페이스인가
`AIService` 는 "LM Studio 먼저, 실패 시 Ollama 폴백, 빈 응답은 soft failure" 같은 *정책* 을 담는다. 호출부(텔레그램 핸들러 등)는 `IAIService.chat()` 만 알면 되고, 정책이 바뀌어도 호출부는 안 바뀐다. 이것이 "구현이 아니라 추상에 의존하라"(DIP)의 실천 [S1].
### 함수 주입으로 순수성 유지
`criticAgent.ts` 헤더 주석은 "모든 LLM 의존은 주입(critique caller) — 모듈 자체는 순수, 테스트 가능" 이라고 명시한다. `runCriticReview({ ..., callLlm })` 는 실제 LLM 을 직접 부르지 않고 주입된 `callLlm` 을 부른다. 덕분에:
- 프로덕션: `agent.ts``callNonStreaming` 을 주입.
- 테스트: 고정 문자열을 반환하는 가짜 함수를 주입 → LLM 없이 단위 테스트 [S3].
### deps 번들 + getter 의 이유
멀티에이전트 워크플로는 실행 도중 webview/abort signal 이 바뀔 수 있다. 그래서 값이 아니라 *게터* 를 주입한다:
```typescript
export interface WorkflowDeps {
getWebview: () => vscode.Webview | undefined; // 호출 시점의 최신 webview
getAbortSignal: () => AbortSignal | undefined; // 새 controller 의 최신 signal
chatHistory: ChatMessage[];
}
```
주석은 "호출자가 stop()+new AbortController() 를 먼저 마쳐야 한다 — getAbortSignal() 은 그 새 controller 의 signal 을 반환해야 함" 이라고 함정을 경고한다 [S4].
## ⚖️ 비교 및 선택 기준 (Comparison & decision criteria)
| 항목 (Option) | 장점 | 단점 | 언제 선택 |
|---|---|---|---|
| 생성자 주입(옵션 객체) | 의존 명시, 교체 쉬움 | 생성 코드 장황 | 상태/정책 가진 협력자 |
| 함수 주입 | 모듈 순수, 테스트 최상 | 콜백 시그니처 관리 | LLM·I/O 같은 외부 효과 |
| getter 주입 | 늦은 바인딩, 순환 회피 | 호출 시점 의존 | 동적/초기화 순서 문제 |
| 싱글톤 import | 간결, 전역 공유 | 테스트 격리 어려움 | 프로세스 전역 인프라(lock/queue) |
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **DI 컨테이너 없음:** ConnectAI 는 별도 DI 프레임워크를 쓰지 않고 *수동 주입* (activate 에서 직접 조립)한다. 규모가 작고 조립 지점이 한 곳이라 프레임워크 비용이 불필요 — 큰 시스템이면 컨테이너가 유리할 수 있다.
- **싱글톤의 비용:** `lockManager`/`actionQueue` 싱글톤은 편하지만 테스트 격리를 어렵게 한다. ConnectAI 는 전역성이 본질인 자원에만 한정해 사용한다.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/core/services.ts` — IAIService/IBrainService 인터페이스 + 구현 [S1].
- `ConnectAI/src/extension.ts` — AgentExecutor/SidebarChatProvider 생성자 옵션 주입, getProvider 게터 [S2].
- `ConnectAI/src/intelligence/criticAgent.ts` — CritiqueLlmCall 함수 주입 [S3].
- `ConnectAI/src/agent/multiAgent/workflow.ts` — WorkflowDeps 게터 번들 [S4].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 인터페이스 계약 + 구현 분리 (src/core/services.ts)
export interface IAIService {
call(prompt: string): Promise<string>;
chat(req: AIChatRequest): Promise<AIChatResult>;
}
export class AIService implements IAIService { /* 엔진 폴백 정책 캡슐화 */ }
// 2) 생성자 옵션 객체 주입 (src/extension.ts)
const agent = new AgentExecutor(context, {
onStreamLifecycle: { start: () => lifecycle.onStreamStart(), end: () => lifecycle.onStreamEnd() },
lmStudioStreamer, approvalQueue,
});
// 3) 함수 주입으로 순수 모듈 (src/intelligence/criticAgent.ts)
export type CritiqueLlmCall = (system: string, user: string, maxTokens: number) => Promise<string>;
export async function runCriticReview(params: { /* ... */ callLlm: CritiqueLlmCall }) {
const raw = await params.callLlm(system, user, opts.maxTokens); // 어떤 엔진인지 모름
return parseCritique(raw);
}
// 4) getter 번들 (src/agent/multiAgent/workflow.ts)
export interface WorkflowDeps {
getWebview: () => vscode.Webview | undefined;
getAbortSignal: () => AbortSignal | undefined;
}
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.93
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[TypeScript 고급 타입]], [[Intelligence 검증 레이어]], [[VSCode 확장 구조와 생명주기]]
- **참조 맥락:** 로컬 LLM 이 협력 객체를 가진 모듈을 테스트 가능하고 교체 가능하게 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/core/services.ts — IAIService/IBrainService + AIService 구현
- [S2] ConnectAI/src/extension.ts — 생성자 옵션 주입, getProvider 게터
- [S3] ConnectAI/src/intelligence/criticAgent.ts — CritiqueLlmCall 함수 주입(순수 모듈)
- [S4] ConnectAI/src/agent/multiAgent/workflow.ts — WorkflowDeps 게터 번들
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,135 @@
---
id: event-sourced-store-pattern
title: "이벤트 소싱 스토어 패턴"
category: "Architecture"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["event sourcing", "append-only", "JSONL", "이벤트 스토어", "팩토리 함수", "computeStates"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.92
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["architecture", "event-sourcing", "persistence", "factory", "connectai"]
raw_sources: ["ConnectAI/src/features/_shared/eventSourcedStore.ts", "ConnectAI/src/memory/types.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[이벤트 소싱 스토어 패턴]]
## 🎯 한 줄 통찰 (One-line insight)
이벤트 소싱은 "현재 상태를 덮어쓰지 않고 *일어난 일(event)을 추가만(append-only)* 기록"하는 영속화 방식이며, ConnectAI 는 이를 **JSONL 파일 + 제네릭 팩토리(`createEventStore<E>`)** 로 구현해 4개 도메인 스토어의 ~240줄 중복을 한 곳으로 통합한다 [S1].
## 🧠 핵심 개념 (Core concepts)
1. **Append-only:** 데이터를 수정·삭제하지 않고 끝에 줄을 추가만 한다. 이력이 전부 남아 감사·재현·디버깅에 강하다 [S1].
2. **JSONL (JSON Lines):** 한 줄에 JSON 객체 하나. 스트리밍 append 가 쉽고, 한 줄이 손상돼도 나머지는 읽을 수 있다 [S1].
3. **이벤트 → 상태 계산:** 저장은 이벤트로, *현재 상태* 는 이벤트들을 재생(`computeStates`)해 도출한다 — 도메인 파일의 책임 [S1].
4. **제네릭 팩토리 + 검증 주입:** I/O(읽기/추가/카운트)는 공통 모듈이, 도메인 로직은 호출부가 — 관심사 분리 [S1].
5. **내결함 파싱:** 손상된 줄은 skip 하고 계속 — append-only 라 1줄 손상이 전체를 무력화하면 안 된다 [S1].
## 🧩 추출된 패턴 (Extracted patterns)
- **중복 4벌 → 제네릭 1벌:** customers/hire/runway/feedback 이 같은 `getXFilePath/readX/appendX/countX` 를 반복 → `createEventStore<E>` 로 흡수. BOM/인코딩 등 edge case fix 도 한 번에 전파 [S1].
- **팩토리 함수 + 클로저:** 클래스 대신 함수가 내부 함수들을 담은 객체를 반환 — 캡슐화는 클로저로, `new` 불필요 [S1].
- **타입 가드 검증을 옵션으로:** `validate: (e) => e is E` 를 주입해 파싱 결과의 유효성을 도메인이 정의 [S1].
- **결과를 판별 유니온으로:** `append``{ ok: true; filePath } | { ok: false; error }` 반환 — 워크스페이스 없음 등 흔한 실패를 예외 없이 전달 [S1].
- **워크스페이스 상대경로:** `relPath: '.astra/customers.jsonl'` 를 워크스페이스 루트 기준으로 해석 [S1].
## 📖 세부 내용 (Details)
### 왜 이벤트 소싱인가 (이 코드에서)
고객/채용/런웨이/피드백 같은 도메인은 "변경 이력 자체가 가치" 다. 마지막 상태만 저장하면 "언제 무엇이 바뀌었나"를 잃는다. 이벤트를 append 하면 전체 타임라인이 보존되고, 현재 상태는 필요할 때 재생으로 만든다 [S1].
### 공통 I/O vs 도메인 로직 경계
모듈 헤더 주석이 경계를 명확히 한다: "도메인별 로직(computeStates 등)은 그대로 도메인 파일에 남음 — 본 모듈은 I/O 만 추상화." 즉 `createEventStore` 는 read/append/count/getFilePath 만 제공하고, "이벤트들로 현재 고객 목록을 만드는" 로직은 customers 도메인에 둔다 [S1].
### 내결함 읽기
```typescript
for (const line of content.split('\n')) {
const trimmed = line.trim();
if (!trimmed) continue;
try {
const parsed = JSON.parse(trimmed);
if (opts.validate(parsed)) out.push(parsed);
} catch { /* skip malformed — append-only 라 손상 1줄이 전체 무력화하면 안 됨 */ }
}
```
한 줄 파싱 실패나 검증 실패는 그 줄만 버리고 계속한다 — 견고성의 핵심 [S1].
### 안전한 append
`fs.mkdirSync(dirname, { recursive: true })` 로 디렉터리 보장 후 `appendFileSync(... + '\n')`. 실패는 throw 가 아니라 `{ ok: false, error }` 로 반환해 호출부가 사용자에게 안내할 수 있게 한다 [S1].
## ⚖️ 비교 및 선택 기준 (Comparison & decision criteria)
| 항목 (Option) | 장점 | 단점 | 언제 선택 |
|---|---|---|---|
| Append-only 이벤트(JSONL) | 이력 보존, 내결함, 단순 | 상태 재생 비용, 파일 증가 | 변경 이력이 가치 있을 때 |
| 상태 덮어쓰기(JSON 1개) | 읽기 즉시, 작음 | 이력 손실, 동시쓰기 충돌 | 마지막 값만 중요할 때 |
| SQLite/DB | 쿼리·인덱스·트랜잭션 | 의존성·운영 비용 | 대량·복잡 쿼리 |
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **파일 무한 증가:** append-only 는 파일이 계속 커진다. 주기적 compaction(스냅샷 + 이후 이벤트만 유지)이 필요할 수 있다 — 현재 모듈은 compaction 을 제공하지 않으므로 도메인이 관리.
- **동시 append:** 단일 프로세스 내 순차 append 는 안전하나, 멀티 프로세스/동시 쓰기는 잠금이 필요하다. ConnectAI 는 무거운 작업을 [[동시성 제어 Lock Queue Transaction]] 의 lockManager 로 직렬화한다.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/features/_shared/eventSourcedStore.ts` — 제네릭 이벤트 스토어 본체. customers/hire/runway/feedback 도메인이 이를 인스턴스화해 사용 [S1].
- 메모리 계층의 episodic/long-term 도 유사하게 버전 필드를 가진 직렬화 스토어 형태(`EpisodicStore { version, episodes, lastUpdated }`)를 쓴다 [S2].
## 💻 코드 패턴 (Code patterns)
```typescript
// 제네릭 이벤트 스토어 (src/features/_shared/eventSourcedStore.ts)
export function createEventStore<E>(opts: EventStoreOptions<E>): EventStore<E> {
function getFilePath(): string | null {
const folders = vscode.workspace.workspaceFolders;
if (!folders?.length) return null;
return path.join(folders[0].uri.fsPath, opts.relPath); // 워크스페이스 상대경로
}
function read(): E[] {
const fp = getFilePath();
if (!fp || !fs.existsSync(fp)) return [];
const out: E[] = [];
for (const line of fs.readFileSync(fp, 'utf-8').split('\n')) {
const t = line.trim(); if (!t) continue;
try { const p = JSON.parse(t); if (opts.validate(p)) out.push(p); }
catch { /* 손상 줄 skip */ }
}
return out;
}
function append(event: E) {
const fp = getFilePath();
if (!fp) return { ok: false, error: '워크스페이스 폴더가 없어 저장 불가.' } as const;
try {
fs.mkdirSync(path.dirname(fp), { recursive: true });
fs.appendFileSync(fp, JSON.stringify(event) + '\n', 'utf-8');
return { ok: true, filePath: fp } as const;
} catch (e: any) { return { ok: false, error: e?.message || String(e) } as const; }
}
return { getFilePath, read, append, count };
}
// 도메인 사용:
const store = createEventStore<CustomerEvent>({
relPath: '.astra/customers.jsonl',
validate: (e): e is CustomerEvent => typeof (e as any).id === 'string',
});
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.92
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[TypeScript 고급 타입]], [[5계층 메모리 시스템]], [[동시성 제어 Lock Queue Transaction]]
- **참조 맥락:** 로컬 LLM 이 이력·로그·상태를 파일로 영속화하는 스토어를 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/features/_shared/eventSourcedStore.ts — createEventStore 제네릭 팩토리, 내결함 파싱, 판별 유니온 결과
- [S2] ConnectAI/src/memory/types.ts — 버전 필드를 가진 직렬화 스토어(EpisodicStore/LongTermStore)
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,110 @@
---
id: coding-conventions-comment-philosophy
title: "코딩 컨벤션과 주석 철학"
category: "Software_Engineering"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["코딩 스타일", "주석 철학", "why comment", "post-mortem comment", "naming", "graceful degradation", "코드 컨벤션"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.93
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["conventions", "style", "comments", "readability", "connectai"]
raw_sources: ["ConnectAI/src/core/lock.ts", "ConnectAI/src/retrieval/index.ts", "ConnectAI/src/features/company/dispatcher.ts", "ConnectAI/src/extension.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[코딩 컨벤션과 주석 철학]]
## 🎯 한 줄 통찰 (One-line insight)
ConnectAI 코드의 가장 큰 특징은 "**주석이 '무엇'이 아니라 '왜'와 '왜 다른 방법이 아니었는지'를 적고, 버그 사후기록(post-mortem)을 코드 옆에 남긴다**"는 점이며, 이것이 작은 LLM 이 *의도까지* 학습하게 하는 핵심 자료다 [S1][S3].
## 🧠 핵심 개념 (Core concepts)
1. **Why 주석:** 코드가 '무엇을 하는지'는 코드로 읽고, 주석은 '왜 이렇게 했는지'·제약·트레이드오프를 적는다 [S1].
2. **Post-mortem 주석:** 과거 버그의 원인과 수정 근거를 코드 옆에 남겨 같은 실수를 막는다 [S1].
3. **모듈 헤더 docstring:** 각 파일 상단에 그 모듈의 책임·배경·다른 모듈과의 분업을 설명 [S1][S4].
4. **결정 근거 주석:** "왜 순차인가", "왜 handlePrompt 를 안 쓰나" 같은 설계 결정을 인라인으로 [S3].
5. **방어적 기본값/널 처리 + 의도 명시:** `??` vs `||`, `void` fire-and-forget, 의도적 빈 catch 를 주석으로 [S2][S4].
## 🧩 추출된 패턴 (Extracted patterns)
- **named export 일관:** default export 를 배제하고 named export 만 — 자동완성·리네이밍 안전 [S4].
- **단일 진입점 헬퍼:** 설정은 `getConfig()`, 경로는 path resolver 처럼 한 곳을 통해 — 파싱/coercion 중복 방지 [S4].
- **`??` 로 의미 있는 0/'' 보존:** `brainFileLimit ?? 8` (0 이 유효), `req.timeoutMs ?? config.timeout` [S2].
- **의도된 graceful degradation:** 부가 작업 실패를 `catch { /* should never break main flow */ }` 로 — 빈 catch 에 *반드시* 이유 주석 [S2].
- **단계 로그(추적성):** 복잡 로직은 `fusionLog.push(...)` 처럼 단계별 기록을 남겨 디버깅 [S2].
- **상수 중앙화:** 가중치/임계값/불용어를 설정 객체 한 곳에(`SCORING_CONFIG`) [S2].
- **한국어 주석 + 영어 식별자:** 식별자·타입은 영어, 설명 주석은 한국어 — 팀 가독성 우선 [S1].
## 📖 세부 내용 (Details)
### 주석이 의도를 가르친다 (이 위키의 핵심 가치)
`lock.ts` 의 주석은 옛 구현이 왜 틀렸는지를 적는다: "`.then(...)` 은 매 호출마다 새 Promise instance 를 반환해서 사실상 항상 false — cleanup 이 안 됨." 이런 주석은 *코드만 봐서는 절대 알 수 없는* 함정을 전수한다. 작은 LLM 이 비슷한 코드를 쓸 때 같은 함정을 피하게 만드는 최고의 학습 신호다 [S1].
### "왜 다른 방법이 아니었나" 를 적는다
`dispatcher.ts` 헤더는 "Why sequential?", "Why not use handlePrompt?" 를 명시한다. 대안을 검토하고 *기각한 이유* 까지 적어, 미래의 개발자(또는 LLM)가 같은 고민을 반복하지 않게 한다 [S3].
### 방어적이되 명시적
```typescript
const brainFileLimit = options.brainFileLimit ?? 8; // 0 이 의미 있음 → || 아님
void ensureEmbeddingConfigured(context); // 비차단 의도를 void 로 명시
try { extract(); } catch { /* memory extraction should never break the main flow */ }
```
빈 catch·fire-and-forget 같은 "위험해 보이는" 패턴에는 *왜 안전한지* 를 항상 주석으로 정당화한다 [S2][S4].
### 네이밍
- 함수는 동사구(`buildContext`, `searchBrainFiles`, `parseModelPrefix`), boolean 은 `is*`/`should*`/`has*`(`isOperationalPath`, `shouldUseMultiAgentWorkflow`).
- 내부 전용은 `_` 접두사(`_ensureBrainDir`, `_getBrainDir`).
- 타입은 PascalCase 인터페이스(`RetrievalChunk`, `ConfidenceResult`), 상수는 UPPER_SNAKE(`PEER_OUTPUT_BUDGET`).
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **주석 과다 vs 적정:** "코드가 자명하면 주석 불필요" 라는 원칙과 충돌할 수 있다. ConnectAI 의 기준은 *비자명한 why/제약/함정만* 적는 것 — "다음 줄이 무엇을 하는지" 류의 노이즈 주석은 피한다.
- **주석의 노후화:** 코드가 바뀌면 주석이 거짓이 될 위험. post-mortem 주석은 역사적 사실이라 비교적 안전하나, "현재 동작" 주석은 변경 시 함께 갱신해야 한다.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/core/lock.ts` — 버그 post-mortem 주석의 모범 [S1].
- `ConnectAI/src/features/company/dispatcher.ts` — 결정 근거(왜 순차/왜 분리) 주석 [S3].
- `ConnectAI/src/retrieval/index.ts` — 단계 로그, 상수 중앙화, `??` 보존 [S2].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) Post-mortem 주석 — 코드로 알 수 없는 함정 전수 (src/core/lock.ts)
// 옛 구현은 `this.locks.get(id) === prev.then(() => next)` 로 Promise 동일성을 비교했는데,
// `.then(...)` 은 매번 새 Promise 를 반환 → 항상 false → cleanup 실패. 그래서 고유 symbol
// 토큰을 부여하고 "내 토큰이 최신일 때만" 정리한다.
// 2) 의도적 graceful degradation — 빈 catch 에 이유 명시 (src/memory/index.ts)
try { this.extractor.extractFromSession(...); }
catch { /* memory extraction should never break the main flow */ }
// 3) ?? 로 의미 있는 0 보존 (src/retrieval/index.ts)
const brainFileLimit = options.brainFileLimit ?? 8; // 명시적 0 = "검색 끔"
// 4) 단계 로그로 추적성 (src/retrieval/index.ts)
fusionLog.push(`Brain search: ${brainChunks.length} chunks found`);
fusionLog.push(`Selected: ${selectedChunks.length}, Dropped: ${dropped.length}, Tokens: ${tokensUsed}`);
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.93
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[에러 처리와 커스텀 에러]], [[모듈 시스템과 프로젝트 구성]], [[프롬프트 엔지니어링 패턴]]
- **참조 맥락:** 로컬 LLM 이 코드를 작성할 때 네이밍·주석·방어 코드의 스타일을 ConnectAI 와 일치시키도록 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/core/lock.ts — post-mortem 주석, 모듈 헤더
- [S2] ConnectAI/src/retrieval/index.ts — ?? 보존, 단계 로그, 상수 중앙화
- [S3] ConnectAI/src/features/company/dispatcher.ts — 결정 근거 주석
- [S4] ConnectAI/src/extension.ts — named export, 단일 진입점, void/getter 패턴
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,110 @@
---
id: prompt-engineering-patterns
title: "프롬프트 엔지니어링 패턴"
category: "AI_and_ML"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["prompt engineering", "system prompt", "프롬프트 조립", "context block", "JSON output", "grounding", "프롬프트 설계"]
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: ["prompt-engineering", "llm", "ai", "system-prompt", "connectai"]
raw_sources: ["ConnectAI/src/intelligence/epistemicGuardBlock.ts", "ConnectAI/src/intelligence/correctionLoop.ts", "ConnectAI/src/intelligence/criticAgent.ts", "ConnectAI/src/features/datacollect/prompts/wikifyPrompt.ts", "ConnectAI/src/core/services.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[프롬프트 엔지니어링 패턴]]
## 🎯 한 줄 통찰 (One-line insight)
좋은 프롬프트는 "**조립 가능한 블록**으로 만들고(역할·규칙·컨텍스트·출력형식), 작은 모델일수록 system 으로 강하게 grounding 하고, 출력은 파싱 가능한 JSON/템플릿으로 강제하며, 결정론적 신호로 동적으로 강도를 조절"한다 — ConnectAI 의 검증 레이어가 이를 그대로 실천한다 [S1][S3][S4].
## 🧠 핵심 개념 (Core concepts)
1. **블록 조립:** 시스템 프롬프트를 `[EPISTEMIC GUARD]`, `[MEMORY CONTEXT]`, `[자기검토]` 같은 명명 블록으로 만들어 필요 시 합친다 [S1][S5].
2. **작은 모델엔 강한 system grounding:** gemma 류는 system 이 없으면 짧고 모호한 입력에 "시는 못 써드려요" 같은 환각 거절을 한다 — system 을 반드시 채운다 [S5].
3. **출력 형식 강제:** "반드시 아래 JSON 만 출력" + 예시 스키마. 파싱은 균형 괄호 스캔으로 잡설 내성 [S3].
4. **동적 강도 조절:** 검색 근거가 없을수록 가드 지시를 강화(`chunkCount === 0` 이면 "단정 금지·질문 우선") [S1].
5. **few-shot 대신 규칙+제약:** 길고 명시적인 규칙 목록 + "근거 없으면 지어내지 말 것" 같은 negative constraint [S4].
## 🧩 추출된 패턴 (Extracted patterns)
- **명명 블록 + 닫는 태그:** `[EPISTEMIC GUARD] ... [/EPISTEMIC GUARD]` — 모델이 블록 경계를 인식 [S1].
- **3등급 인식론 강제:** 확실/추정/모름 등급 표시 — "모름 인정이 그럴듯한 오답보다 낫다" 를 명문화 [S1].
- **조건부 블록 주입:** 통계가 임계(같은 태그 2회+)를 넘을 때만 자기검토 블록 주입 — 노이즈 방지 [S2].
- **태그별 맞춤 지시:** 오류 태그(사실오류/근거누락…)마다 다른 자기검토 문장 매핑 [S2].
- **system/user 분리 빌더:** `buildCritiquePrompt``{ system, user }` 를 반환 — 역할(검수자)과 데이터(초안)를 분리 [S3].
- **입력 잘라내기(budget):** 초안/필드를 `maxDraftChars`/`MAX_FIELD_CHARS` 로 잘라 토큰·비용 통제 [S3].
- **출력 후처리:** 작은 모델이 흘리는 `##`/`**` 마커를 사후 제거하고 history 에도 정제본만 저장(마커 재학습 방지) [참조: [[Agent 오케스트레이터 분해]]].
## 📖 세부 내용 (Details)
### 왜 블록 조립인가
한 턴의 system 프롬프트는 정체성·모드·메모리·가드·자기검토 등 여러 관심사가 합쳐진다. 각 관심사를 독립 빌더 함수(`buildEpistemicGuardBlock`, `buildSelfReviewBlock`)로 만들면, 조건에 따라 켜고 끄며 조합할 수 있고 단위 테스트가 쉽다 [S1][S2].
### 작은 모델 대응 (이 프로젝트의 핵심 제약)
- system 으로 강하게 grounding (services.ts 주석: system 없으면 환각 거절) [S5].
- 규칙을 *명시적이고 번호 매겨* 제시(wikify 프롬프트의 "필수 규칙 1~6 + 공통 규칙 7~15") [S4].
- "본문에 없으면 지어내지 말고 '확인되지 않음' 표시" 같은 negative constraint 를 반복 [S4].
- 출력 형식을 템플릿으로 못박고, 흘러나온 마커는 사후 정제.
### JSON 출력 + 강건 파싱
"반드시 JSON 한 줄만" 을 지시해도 작은 모델은 코드펜스·잡설을 섞는다. 그래서 첫 균형 `{}` 블록을 스캔(문자열/이스케이프 인식)해 추출하고, 실패 시 휴리스틱 fallback 으로 분류한다 — *프롬프트와 파서를 함께 설계* [S3].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **긴 프롬프트 vs 컨텍스트 한도:** 블록을 다 합치면 길어져 작은 모델의 컨텍스트를 압박한다. 그래서 [[RAG 검색 파이프라인]] 의 토큰 예산과 조건부 주입으로 길이를 통제한다.
- **JSON 강제의 취약성:** 모델이 형식을 어기면 파싱 실패. 강건 파서 + fallback 이 필수 — "프롬프트만 믿지 말고 파서로 방어".
- **few-shot 비용:** 예시를 많이 넣으면 정확하지만 토큰이 비싸다. ConnectAI 는 예시 최소화 + 규칙/제약 위주로 절충.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/intelligence/epistemicGuardBlock.ts` — 명명 블록, 동적 강도 [S1].
- `ConnectAI/src/intelligence/correctionLoop.ts` — 조건부·태그별 자기검토 블록 [S2].
- `ConnectAI/src/intelligence/criticAgent.ts` — system/user 분리, JSON 강제+강건 파싱 [S3].
- `ConnectAI/src/features/datacollect/prompts/wikifyPrompt.ts` — 번호 규칙 + negative constraint + 템플릿 강제 [S4].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 명명 블록 + 동적 강도 (src/intelligence/epistemicGuardBlock.ts)
lines.push('[EPISTEMIC GUARD]');
lines.push('- **모름 / 확인 필요** — 근거 없음. 지어내지 말고 "(확인 필요)" 표시.');
if (signals.chunkCount === 0) lines.push('⚠️ 이번 턴은 검색 근거가 없음 — 단정하지 말 것.');
lines.push('[/EPISTEMIC GUARD]');
// 2) 출력 형식 강제 (src/intelligence/criticAgent.ts)
const system = [
'너는 업무 산출물 검수자(Critic)다.',
'반드시 아래 JSON 만 출력 (다른 텍스트 금지):',
'{"pass": true|false, "issues": [{"severity":"major"|"minor","description":"..."}], "supplement":"..."}',
].join('\n');
// 3) 작은 모델 grounding — system 필수 (src/core/services.ts 주석)
// gemma 같은 작은 모델은 system 이 없으면 짧은/모호한 입력에 환각 거절을 하는 경향 → system 을 반드시 채운다.
// 4) 조건부 주입 — 임계 넘을 때만 (src/intelligence/correctionLoop.ts)
const significant = profile.tagCounts.filter(t => t.count >= 2).slice(0, 2);
if (significant.length === 0) return ''; // 1회성 실수로 프롬프트 어지럽히지 않음
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.91
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[Intelligence 검증 레이어]], [[RAG 검색 파이프라인]], [[코딩 컨벤션과 주석 철학]], [[Reflection Pattern]], [[Critic Pattern]]
- **참조 맥락:** 로컬 LLM 이 다른(또는 자기 자신) 모델을 호출하는 프롬프트를 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/intelligence/epistemicGuardBlock.ts — 명명 블록, 3등급, 동적 강도
- [S2] ConnectAI/src/intelligence/correctionLoop.ts — 조건부·태그별 자기검토 주입
- [S3] ConnectAI/src/intelligence/criticAgent.ts — system/user 분리, JSON 강제+강건 파싱, 입력 budget
- [S4] ConnectAI/src/features/datacollect/prompts/wikifyPrompt.ts — 번호 규칙, negative constraint, 템플릿
- [S5] ConnectAI/src/core/services.ts — 작은 모델 system grounding 근거
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -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", "connectai"]
raw_sources: ["ConnectAI/src/features/_shared/eventSourcedStore.ts", "ConnectAI/src/memory/types.ts"]
applied_in: ["ConnectAI"]
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)
`ConnectAI/src/features/_shared/eventSourcedStore.ts` — 결정의 구현체 [S1].
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[이벤트 소싱 스토어 패턴]], [[Event Bus Pattern]], [[ADR-0005 파일 기반 저장 채택]], [[엔지니어링 트레이드오프 분석]]
- **참조 맥락:** 로컬 LLM 이 "이력 저장 vs 상태 저장" 을 결정할 때 판단 근거로 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/features/_shared/eventSourcedStore.ts — 제네릭 이벤트 스토어, 중복 통합 배경 주석
- [S2] ConnectAI/src/memory/types.ts — 버전 필드 직렬화 스토어
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 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", "connectai"]
raw_sources: ["ConnectAI/src/memory/index.ts", "ConnectAI/src/memory/types.ts"]
applied_in: ["ConnectAI"]
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)
`ConnectAI/src/memory/index.ts`, `types.ts` [S1][S2].
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[5계층 메모리 시스템]], [[Memory Pattern]], [[아키텍처 휴리스틱]], [[엔지니어링 트레이드오프 분석]]
- **참조 맥락:** 로컬 LLM 이 에이전트 메모리 구조를 설계할 때 "한 통 vs 계층 분리" 판단에 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/memory/index.ts — MemoryManager 5계층 통합
- [S2] ConnectAI/src/memory/types.ts — 계층별 타입·만료·승급 필드
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 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", "connectai"]
raw_sources: ["ConnectAI/src/agents/AgentWorkflowManager.ts", "ConnectAI/src/features/company/dispatcher.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[Agent 오케스트레이터 분해]], [[Agent Orchestration Pattern]], [[ADR-0004 순차 디스패치 채택]], [[엔지니어링 트레이드오프 분석]]
- **참조 맥락:** 로컬 LLM 이 멀티에이전트를 도입할지/어떻게 구성할지 자원 제약 하에 판단할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/agents/AgentWorkflowManager.ts — 5-persona 폐기 post-mortem, ChunkedWriter
- [S2] ConnectAI/src/features/company/dispatcher.ts — 순차 디스패치 근거
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 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", "connectai"]
raw_sources: ["ConnectAI/src/features/company/dispatcher.ts", "ConnectAI/src/lmstudio/lifecycleManager.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[ADR-0003 단일작성자 다중역할 멀티에이전트]], [[동시성 제어 Lock Queue Transaction]], [[Background Worker Pattern]]
- **참조 맥락:** 로컬 LLM 이 자원 제약 환경에서 병렬 vs 순차를 결정할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/features/company/dispatcher.ts — "Why sequential?" 근거 주석
- [S2] ConnectAI/src/lmstudio/lifecycleManager.ts — 모델 load/unload 수명관리
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 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", "connectai"]
raw_sources: ["ConnectAI/src/core/services.ts", "ConnectAI/src/features/_shared/eventSourcedStore.ts", "ConnectAI/src/intelligence/correctionLoop.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[ADR-0001 이벤트 소싱 채택]], [[이벤트 소싱 스토어 패턴]], [[Local Storage Pattern]], [[Caching Pattern]]
- **참조 맥락:** 로컬 LLM 이 "DB vs 파일" 저장 방식을 결정할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/core/services.ts — BrainService Markdown 저장
- [S2] ConnectAI/src/features/_shared/eventSourcedStore.ts — JSONL 이벤트
- [S3] ConnectAI/src/intelligence/correctionLoop.ts — JSONL/JSON 케이스·프로필(투명성)
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 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", "connectai"]
raw_sources: ["ConnectAI/src/extension.ts", "ConnectAI/src/core/services.ts", "ConnectAI/src/intelligence/criticAgent.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[의존성 주입과 서비스 인터페이스]], [[Repository Pattern]], [[엔지니어링 트레이드오프 분석]]
- **참조 맥락:** 로컬 LLM 이 "DI 컨테이너 vs 수동 주입" 을 규모 기준으로 결정할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/extension.ts — activate 수동 조립, getter/옵션 주입
- [S2] ConnectAI/src/core/services.ts — IAIService/IBrainService
- [S3] ConnectAI/src/intelligence/criticAgent.ts — CritiqueLlmCall 함수 주입
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 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", "connectai"]
raw_sources: ["ConnectAI/src/retrieval/index.ts", "ConnectAI/src/retrieval/scoring.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[RAG 검색 파이프라인]], [[TF-IDF 이중언어 스코어링]], [[RAG Pattern]], [[Caching Pattern]]
- **참조 맥락:** 로컬 LLM 이 검색을 설계할 때 "dense only vs 하이브리드" 와 가용성 보장을 판단할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/retrieval/index.ts — 하이브리드 blend, 스케일 정규화 버그 기록
- [S2] ConnectAI/src/retrieval/scoring.ts — TF-IDF, 이중언어 토크나이저, 동의어
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 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", "connectai"]
raw_sources: ["ConnectAI/src/core/services.ts", "ConnectAI/src/features/providers/types.ts", "ConnectAI/src/features/providers/index.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[LLM 프로바이더 추상화]], [[API Client Pattern]], [[Tool Calling Pattern]]
- **참조 맥락:** 로컬 LLM 이 다중 추론 백엔드 전략(로컬/클라우드/폴백)을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/core/services.ts — 로컬 엔진 폴백, soft failure
- [S2] ConnectAI/src/features/providers/types.ts, index.ts — prefix 라우팅, 어댑터 dispatch
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 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", "connectai"]
raw_sources: ["ConnectAI/src/intelligence/confidenceEngine.ts", "ConnectAI/src/intelligence/criticAgent.ts", "ConnectAI/src/intelligence/epistemicGuardBlock.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[Intelligence 검증 레이어]], [[Critic Pattern]], [[Reflection Pattern]], [[엔지니어링 트레이드오프 분석]]
- **참조 맥락:** 로컬 LLM 이 자기검증 비용/정확도 균형을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/intelligence/confidenceEngine.ts — 결정론 확신도(매 턴)
- [S2] ConnectAI/src/intelligence/criticAgent.ts — 조건부 1-pass 검수
- [S3] ConnectAI/src/intelligence/epistemicGuardBlock.ts — 사전 가드
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 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", "connectai"]
raw_sources: ["ConnectAI/src/agent.ts", "ConnectAI/src/extension.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[Agent 오케스트레이터 분해]], [[리팩토링 플레이북]], [[안티패턴 카탈로그]]
- **참조 맥락:** 로컬 LLM 이 거대 함수/클래스를 리팩터링할 때 "어디까지 추출할지" 판단에 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/agent.ts — 골격 + 추출 모듈 import
- [S2] ConnectAI/src/extension.ts — 얇은 조립 entry point
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 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", "connectai"]
raw_sources: ["ConnectAI/src/retrieval/index.ts", "ConnectAI/src/retrieval/scoring.ts", "ConnectAI/src/retrieval/chunker.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[RAG 검색 파이프라인]], [[RAG Pattern]], [[Caching Pattern]], [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 작은 모델이 다른 프로젝트에서 검색/RAG 를 설계할 때 원리로 전이.
## 📚 출처 (Sources)
- [S1] ConnectAI/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", "connectai"]
raw_sources: ["ConnectAI/src/intelligence/confidenceEngine.ts", "ConnectAI/src/intelligence/criticAgent.ts", "ConnectAI/src/intelligence/epistemicGuardBlock.ts", "ConnectAI/src/intelligence/correctionLoop.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[Critic Pattern]], [[Reflection Pattern]], [[프롬프트 엔지니어링 패턴]], [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 작은 모델이 자기검증/피드백 학습을 다른 프로젝트에 적용할 때 원리로 전이.
## 📚 출처 (Sources)
- [S1] ConnectAI/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", "connectai"]
raw_sources: ["ConnectAI/src/core/lock.ts", "ConnectAI/src/core/queue.ts", "ConnectAI/src/core/transaction.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[Background Worker Pattern]], [[Background Task Pattern]], [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 작은 모델이 공유 자원/대량 작업/다중 변경 코드를 다른 프로젝트에서 작성할 때 전이.
## 📚 출처 (Sources)
- [S1] ConnectAI/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", "connectai"]
raw_sources: ["ConnectAI/src/memory/index.ts", "ConnectAI/src/memory/types.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[5계층 메모리 시스템]], [[Memory Pattern]], [[ADR-0002 5계층 메모리 분리]], [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 작은 모델이 *다른 프로젝트* 에서 에이전트 메모리를 설계할 때 원리로 전이.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/memory/index.ts, types.ts
## 📝 변경 이력 (Change history)
- 2026-06-13: AI 학습용 지식 추출 초안.
@@ -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", "connectai"]
raw_sources: ["ConnectAI/src/agent.ts", "ConnectAI/src/agents/AgentWorkflowManager.ts", "ConnectAI/src/features/company/dispatcher.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[Agent Orchestration Pattern]], [[Reflection Pattern]], [[Critic Pattern]], [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 작은 모델이 멀티에이전트/파이프라인을 설계할 때 과설계 회피 원리로 전이.
## 📚 출처 (Sources)
- [S1] ConnectAI/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", "connectai"]
raw_sources: ["ConnectAI/src/features/_shared/eventSourcedStore.ts", "ConnectAI/src/core/services.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[Event Bus Pattern]], [[Local Storage Pattern]], [[Repository Pattern]], [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 작은 모델이 영속화/스토어를 설계할 때 원리로 전이.
## 📚 출처 (Sources)
- [S1] ConnectAI/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", "connectai"]
raw_sources: ["ConnectAI/src/features/providers/index.ts", "ConnectAI/src/features/providers/anthropic.ts", "ConnectAI/src/features/providers/types.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[API Client Pattern]], [[Tool Calling Pattern]], [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 작은 모델이 다중 외부 API/SDK 통합을 다른 프로젝트에서 설계할 때 전이.
## 📚 출처 (Sources)
- [S1] ConnectAI/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", "connectai"]
raw_sources: ["ConnectAI/src/core/lock.ts", "ConnectAI/src/retrieval/index.ts", "ConnectAI/src/agents/AgentWorkflowManager.ts", "ConnectAI/src/features/company/dispatcher.ts", "ConnectAI/src/core/services.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[교훈 라이브러리 Lessons Learned]]
## 🎯 한 줄 통찰 (One-line insight)
ConnectAI 의 주석에는 실제 겪은 버그·오설계의 사후기록이 박혀 있다 — 각 교훈을 (문제→근본원인→해결→교훈→향후 권고)로 정리하면, 작은 모델이 *같은 실수를 코드 작성 단계에서 회피* 하는 재사용 지식이 된다.
## 🧠 핵심 개념 (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)
각 교훈은 실제 ConnectAI 주석/리팩터링에서 추출. ConnectAI 의 lessons/ 폴더와 correctionLoop 이 이런 교훈을 자동 적립하는 시스템이기도 하다 → [[Intelligence 검증 레이어]].
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[안티패턴 카탈로그]], [[디버깅 플레이북]], [[엔지니어링 트레이드오프 분석]], [[코딩 컨벤션과 주석 철학]]
- **참조 맥락:** 로컬 LLM 이 코드를 작성하기 전 "이 상황에서 알려진 함정" 을 회피하는 체크리스트로 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/core/lock.ts — Promise 동일성/토큰 정리 post-mortem
- [S2] ConnectAI/src/retrieval/index.ts — 하이브리드 스케일 정규화 버그
- [S3] ConnectAI/src/agents/AgentWorkflowManager.ts — 멀티에이전트 hop 손실
- [S4] ConnectAI/src/features/company/dispatcher.ts — 자원 제약, 동적 require 통합
- [S5] ConnectAI/src/core/services.ts — 작은 모델 system grounding
- [S6] ConnectAI/src/memory/index.ts — 의도적 빈 catch
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 사후기록 기반 교훈 추출.
@@ -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", "connectai"]
raw_sources: ["ConnectAI/src/core/errorHandler.ts", "ConnectAI/src/core/services.ts", "ConnectAI/src/retrieval/index.ts", "ConnectAI/src/core/lock.ts", "ConnectAI/src/lmstudio/lifecycleManager.ts"]
applied_in: ["ConnectAI"]
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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[교훈 라이브러리 Lessons Learned]], [[안티패턴 카탈로그]], [[소프트웨어 실패 라이브러리]], [[리팩토링 플레이북]]
- **참조 맥락:** 로컬 LLM/개발자가 장애를 만났을 때 서브시스템별 진단 순서로 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/core/errorHandler.ts — 증상 분류
- [S2] ConnectAI/src/core/services.ts — 엔진 폴백/빈 응답
- [S3] ConnectAI/src/retrieval/index.ts — fusionLog/평가 경로
- [S4] ConnectAI/src/core/lock.ts — 락 진단
- [S5] ConnectAI/src/lmstudio/lifecycleManager.ts — 모델 수명/VRAM
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 서브시스템별 디버깅 절차 초안.
@@ -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", "connectai"]
raw_sources: ["ConnectAI/src/agent.ts", "ConnectAI/src/features/_shared/eventSourcedStore.ts", "ConnectAI/src/retrieval/index.ts", "ConnectAI/src/features/company/dispatcher.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[리팩토링 플레이북]]
## 🎯 한 줄 통찰 (One-line insight)
리팩토링은 "동작을 바꾸지 않고 구조를 개선" 하는 것이며, ConnectAI 의 실제 리팩터링(중복 통합·동적→정적·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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[디버깅 플레이북]], [[안티패턴 카탈로그]], [[엔지니어링 트레이드오프 분석]], [[아키텍처 휴리스틱]]
- **참조 맥락:** 로컬 LLM 이 기존 코드를 개선/확장할 때 안전 절차와 마이그레이션 경로로 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/features/_shared/eventSourcedStore.ts — 중복 통합
- [S2] ConnectAI/src/features/company/dispatcher.ts — 동적→정적
- [S3] ConnectAI/src/agents/AgentWorkflowManager.ts — persona 단순화
- [S4] ConnectAI/src/retrieval/index.ts — 플래그 격리, 평가 무결성
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 리팩터링 사례 기반 플레이북 초안.
@@ -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", "connectai"]
raw_sources: ["ConnectAI 전체 분석", "본 위키 ADR/트레이드오프 모음"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[아키텍처 휴리스틱]]
## 🎯 한 줄 통찰 (One-line insight)
좋은 설계자는 매번 0부터 고민하지 않고 *결정 규칙(휴리스틱)* 을 적용한다 — "언제 X 를 만들고, 언제 만들지 않는가" 를 명시한 규칙 모음은 작은 모델에게 가장 실용적인 설계 지능이다.
## 🧠 핵심 개념 (Core concepts)
- 휴리스틱 = "조건 → 권장 선택" 의 빠른 판단 규칙. 절대 법칙이 아니라 *기본값*.
- ConnectAI 의 실제 결정에서 역추출.
## 📖 세부 내용 (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)
각 규칙은 ConnectAI 의 실제 ADR 결정과 1:1 대응. 신규 기능 설계 시 이 목록을 먼저 훑는다.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[엔지니어링 트레이드오프 분석]], [[안티패턴 카탈로그]], [[리팩토링 플레이북]], [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 로컬 LLM 이 "새 것을 만들지 말지" 를 빠르게 판단할 때 1차 규칙으로 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI 전체 ADR/서브시스템 결정의 역추출(본 위키 Engineering_Intelligence 모음)
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 결정 규칙 추출 초안.
@@ -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", "connectai"]
raw_sources: ["ConnectAI/src/core/lock.ts", "ConnectAI/src/memory/index.ts", "ConnectAI/src/retrieval/index.ts", "ConnectAI/src/features/company/dispatcher.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[안티패턴 카탈로그]]
## 🎯 한 줄 통찰 (One-line insight)
안티패턴은 "처음엔 그럴듯하지만 시간이 지나면 버그·복잡도를 부르는 습관" 이며, ConnectAI 가 *실제로 겪고 고친* 사례에서 추출한 것이라 작은 모델이 회피해야 할 1순위 목록이다.
## 🧠 핵심 개념 (Core concepts)
각 안티패턴: **설명 / 왜 위험한가 / 증상 / 더 나은 대안 / 이 프로젝트의 사례(있으면)**.
## 📖 세부 내용 (Details · 안티패턴 모음)
### A-01. 무음 빈 catch (Silent swallow)
- **설명:** `try { ... } catch {}` 로 에러를 이유 없이 삼킴.
- **왜 위험:** 실패가 숨겨져 디버깅 불가, 잘못된 상태로 진행.
- **증상:** "왜 아무 일도 안 일어나지?", 로그 없는 실패.
- **더 나은 대안:** 본류 에러는 throw/처리. 부가 작업만 삼키되 *이유 주석* 필수.
- **사례:** ConnectAI 는 부가 작업에 한해 `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)
모두 ConnectAI 가 실제로 마주쳐 고치거나 의식적으로 관리하는 사례. [[교훈 라이브러리 Lessons Learned]] 와 짝을 이룬다.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[교훈 라이브러리 Lessons Learned]], [[아키텍처 휴리스틱]], [[디버깅 플레이북]], [[코딩 컨벤션과 주석 철학]]
- **참조 맥락:** 로컬 LLM 이 코드 작성/리뷰 시 회피 목록으로 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/core/lock.ts — 동일성 비교 안티패턴
- [S2] ConnectAI/src/memory/index.ts — 빈 catch(정당화된 형태)
- [S3] ConnectAI/src/retrieval/index.ts — ?? vs ||, 부분 정규화
- [S4] ConnectAI/src/features/company/dispatcher.ts, AgentWorkflowManager.ts — 에이전트 남발, 동적 require
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 사례 기반 안티패턴 카탈로그 초안.
@@ -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", "connectai"]
raw_sources: ["ConnectAI 전체 서브시스템 분석", "ConnectAI/src/core/*", "ConnectAI/src/retrieval/*", "ConnectAI/src/intelligence/*"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[엔지니어링 트레이드오프 분석]]
## 🎯 한 줄 통찰 (One-line insight)
모든 설계는 "무언가를 최적화하기 위해 무언가를 희생"한 결과다 — ConnectAI 의 각 서브시스템이 *무엇을 얻고 무엇을 포기했으며, 언제 그 선택이 깨지는지* 를 명시하면, 작은 모델이 맥락에 맞는 설계를 고를 수 있다.
## 🧠 핵심 개념 (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)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[아키텍처 휴리스틱]], [[안티패턴 카탈로그]], [[ADR-0001 이벤트 소싱 채택]], [[리팩토링 플레이북]]
- **참조 맥락:** 로컬 LLM 이 설계 선택 시 "무엇을 희생하는지" 와 "언제 깨지는지" 를 평가할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI 서브시스템 분석(core/retrieval/intelligence/memory) 및 본 위키의 ADR 모음
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 트레이드오프 종합 분석 초안 생성.
@@ -0,0 +1,120 @@
---
id: software-failure-library
title: "소프트웨어 실패 라이브러리"
category: "Software_Engineering"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["failure library", "실패 라이브러리", "failure modes", "장애 모드 카탈로그", "how things break"]
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: ["failure", "engineering", "debugging", "patterns", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI 사후기록(lock/retrieval/dispatcher 등)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[소프트웨어 실패 라이브러리]]
## 🎯 한 줄 통찰 (One-line insight)
모든 아키텍처 패턴은 *특유의 방식으로 깨진다* — 패턴별 (장애 모드 → 증상 → 근본 원인 → 진단 → 복구 → 예방)을 알면, AI/개발자가 실패를 *조기에 인식하고 회피* 할 수 있다. 이것이 패턴 카탈로그의 어두운 쌍둥이다.
## 🧠 핵심 개념 (Core concepts)
각 패턴 항목 = **Failure Modes / Symptoms / Root Causes / Debugging / Recovery / Prevention**. 패턴 카드의 "실패 사례" 와 [[디버깅 플레이북]] 을 패턴 축으로 재구성.
## 📖 세부 내용 (Details · 패턴별 실패)
### [[RAG Pattern]] / [[Caching Pattern]]
- **Failure Modes:** 낮은 recall, 무관 상위, stale 결과, 빈 결과.
- **Symptoms:** "분명 있는데 못 찾음", 엉뚱한 인용, 옛 데이터 제공.
- **Root Causes:** 동의어 미확장, 하이브리드 부분 정규화(편향), 청크 과대, 인덱스 stale, 무효화 누락.
- **Debugging:** fusionLog 단계 카운트, recall@k 평가, 점수 분포, mtime 비교.
- **Recovery:** 동의어 추가, α 조정, 인덱스 재빌드, 캐시 무효화.
- **Prevention:** 평가 하니스 정기 실행(프로덕션 동일 경로), 동일 스케일 정규화, 변경 감지 무효화.
### [[Memory Pattern]]
- **Failure Modes:** 옛 사실 재현, 기억 미반영, 잘못된 계층.
- **Symptoms:** 만료 지식이 현재처럼, 사용자 정보 망각.
- **Root Causes:** expiresAt 미설정, 추출 빈 catch 삼킴, 관련도 오선별, 분류 모호.
- **Debugging:** 계층별 컨텍스트 출력, 만료 필드, distillation 로그.
- **Recovery:** 만료 부여/엔트리 삭제(파일 편집), 재추출.
- **Prevention:** 시한부엔 만료, 분류 규칙 명문화, 증류로 정리.
### [[Agent Orchestration Pattern]] / [[Reflection Pattern]] / [[Critic Pattern]]
- **Failure Modes:** "방법론만 생성", 환각 통과, OOM, latency 폭증, 무한 루프.
- **Symptoms:** 실제 산출물 없음, 근거 없는 단정, 모델 로드 실패, 느림.
- **Root Causes:** 에이전트 남발(hop 손실), 병렬 다중 상주, 무조건 LLM 검수, 종료 조건 부재, JSON 직접 파싱.
- **Debugging:** 단계 인디케이터, peer-context 길이, 확신도 factor, raw 응답, lifecycle.
- **Recovery:** 단일 작성자 전환, 순차+한 모델, 조건부 검수, 라운드 상한, 균형 괄호 파서.
- **Prevention:** "에이전트 추가 전 정보 손실 점검", 자원 기준 동시성, 결정론 우선 검증.
### [[Tool Calling Pattern]] / [[Command Pattern]]
- **Failure Modes:** 임의 명령 실행, 경로 탈출, 무한 호출, undo 불완전.
- **Symptoms:** 보안 사고, 권한 밖 파일 접근, 반복 실행.
- **Root Causes:** 모델 출력 미검증, 경로 미검증, 승인 게이트 부재, 멱등성 부재.
- **Debugging:** 액션 파싱 로그, 검증 결과, 승인 큐 상태.
- **Recovery:** 화이트리스트 제한, 승인 요구, 롤백.
- **Prevention:** 모델 출력을 신뢰 안 된 입력으로, validatePath/sanitize, 승인 게이트.
### [[State Management Pattern]] / [[React State Pattern]] / [[Data Flow Pattern]]
- **Failure Modes:** 동기화 버그, stale 파생, 불필요 리렌더, 역류.
- **Symptoms:** 같은 데이터 불일치, 화면-데이터 어긋남, 성능 저하.
- **Root Causes:** 중복 상태, 파생값 저장, 서버/클라 상태 혼동, 전역 남용, 경계 정규화 누락.
- **Debugging:** 상태 출처 추적, 변경 로그, 리렌더 프로파일.
- **Recovery:** 단일 출처로 통합, 파생은 계산, 서버 상태 분리.
- **Prevention:** SSOT, 단방향 흐름, 경계 정규화.
### [[Async Concurrency Pattern]] / [[Background Worker Pattern]] / [[Background Task Pattern]]
- **Failure Modes:** 데드락, 락 누수, 좀비 작업, OOM, 중복 실행, UI 멈춤.
- **Symptoms:** 멈춤, 메모리 증가, 같은 작업 N번, 응답 없음.
- **Root Causes:** release 누락, 취소 미전파, 무한 병렬, 재진입, 객체 동일성 비교(L-02), dispose 누락.
- **Debugging:** active lock 수, 타임아웃 위치, 큐 길이, 메모리 추세.
- **Recovery:** try/finally release, 동시성 상한, 재진입 가드, 토큰 정리.
- **Prevention:** 락은 try/finally, AbortSignal 전파, 하드웨어 기준 동시성, 멱등성.
### [[Event Bus Pattern]] / [[IPC Pattern]] / [[Plugin Architecture Pattern]]
- **Failure Modes:** 추적 불가 흐름, 리스너 누수, 직렬화 실패, 플러그인이 코어 크래시.
- **Symptoms:** "누가 이걸 했지?", 중복 핸들러, 통신 행, 앱 죽음.
- **Root Causes:** 리스너 해제 누락, 외부 입력 미검증, 함수/순환 직렬화, 플러그인 격리 부재, 이벤트 이름 오타.
- **Debugging:** 리스너 목록, 메시지 로그, 직렬화 검증, 플러그인 로드 로그.
- **Recovery:** 해제 추가, 입력 검증, 명시 타입(enum), 플러그인 try/catch 격리.
- **Prevention:** 이벤트 카탈로그, 신뢰 경계 검증, 안정된 확장 계약.
### [[Repository Pattern]] / [[Local Storage Pattern]] / [[이벤트 소싱 스토어 패턴]] / [[Offline Sync Pattern]]
- **Failure Modes:** 데이터 손실/중복, 파일 폭증, 마이그레이션 크래시, 충돌 미해소.
- **Symptoms:** 불일치, 업데이트 후 크래시, 동기화 후 데이터 사라짐.
- **Root Causes:** 멱등 키 부재, LWW 손실, compaction 부재, 스키마 버전 무시, 손상 줄 미격리, 민감정보 평문.
- **Debugging:** 줄 단위 파싱 검사, 버전 필드, outbox 순서, 충돌 로그.
- **Recovery:** 멱등 키 도입, 충돌 해소(버전 벡터/사용자), 스냅샷, 부분 격리 파싱.
- **Prevention:** 변경에 고유 id, 데이터 성격별 매체, 손상 줄 skip, 보안 저장소.
### [[JWT Authentication Pattern]] / [[Push Notification Pattern]] / [[Navigation Pattern]] / [[Infinite Scroll Pattern]]
- **Failure Modes:** 토큰 탈취 지속, 알림 미수신, 딥링크 깨짐, 목록 중복/렉.
- **Symptoms:** 로그아웃 안 됨, 알림 안 옴, 뒤로가기 길 잃음, 스크롤 끊김.
- **Root Causes:** localStorage 저장/회전 부재, 전달 보장 가정, 객체 라우트 인자, offset 페이징/가상화 부재.
- **Debugging:** 토큰 수명/저장 위치, 전송 로그, 라우트 직렬화, 요청 중복.
- **Recovery:** httpOnly+회전, 중요 데이터는 동기화로, 커서 페이징, 가상화.
- **Prevention:** 짧은 만료+회전, 알림은 유도만, 직렬화 가능 라우트, 커서+가상화.
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
실패 모드는 *맥락 의존* — 같은 증상도 원인이 다를 수 있다. "증상→가설→*측정으로 검증*→최소 변경" 순서를 지키고, 추측만으로 재시작/롤백하지 마라([[디버깅 플레이북]]).
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI 가 실제로 겪은 실패(락 동일성, 하이브리드 스케일, 에이전트 hop 손실, OOM)가 각 항목의 근거. → [[교훈 라이브러리 Lessons Learned]].
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[디버깅 플레이북]], [[교훈 라이브러리 Lessons Learned]], [[안티패턴 카탈로그]]
- **참조 맥락:** 작은 모델이 패턴을 적용할 때 "이 패턴이 어떻게 깨지는가" 를 함께 학습해 회피.
## 📚 출처 (Sources)
- [S1] 일반 소프트웨어 장애/디버깅 지식
- [S2] ConnectAI 사후기록(lock.ts, retrieval/index.ts, dispatcher.ts 등) — 실증 근거
## 📝 변경 이력 (Change history)
- 2026-06-13: 패턴별 실패 지식 라이브러리 초안.
@@ -0,0 +1,120 @@
---
id: project-independent-design-principles
title: "프로젝트 독립 설계 원칙"
category: "Software_Engineering"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["design principles", "설계 원칙", "transferable principles", "project-independent knowledge", "엔지니어링 원칙"]
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: ["principles", "engineering", "transferable", "design", "platform-independent"]
raw_sources: ["ConnectAI 전체 분석의 일반화", "본 위키 ADR/패턴/교훈 모음"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[프로젝트 독립 설계 원칙]]
## 🎯 한 줄 통찰 (One-line insight)
ConnectAI 라는 *한 프로젝트* 에서 추출한 결정들을 *어느 프로젝트에나 쓰는* 원칙으로 일반화한 것 — "ConnectAI 는 X 를 쓴다" 가 아니라 "**언제 X 를 쓰는가**" 의 형태로, 작은 모델에게 진짜 전이 가능한 학습 데이터다.
## 🧠 핵심 개념 (Core concepts)
각 원칙 = (원칙 / 사용 조건 / 장점 / 단점 / 대안 / 실패 신호). ConnectAI 사례는 *예시* 일 뿐, 규칙은 프로젝트 독립.
## 📖 세부 내용 (Details · 일반화된 원칙)
### P1. 환경이 아키텍처를 결정한다
- **원칙:** 동시성·저장·검증 깊이는 알고리즘이 아니라 *배포 환경(자원·사용자 수·네트워크)* 이 정한다.
- **조건:** 타깃 하드웨어/규모를 알 때.
- **장점:** 과/저설계 회피. **단점:** 환경 변화 시 재평가 필요. **대안:** 런타임 환경 감지 후 전략 전환.
- **실패 신호:** "병렬이 빠르니까" 로 OOM; 서버 가정으로 로컬 앱 설계.
- 일반화 출처: [[ADR-0004 순차 디스패치 채택]], [[엔지니어링 트레이드오프 분석]].
### P2. 결정론을 바닥선으로, 비싼 것은 조건부로
- **원칙:** 항상 동작해야 하는 기능은 저비용 결정론으로 바닥을 깔고, 비싼(LLM/네트워크) 것은 가산·조건부.
- **조건:** 가용성·설명가능성이 중요할 때. **장점:** 무중단·저지연. **단점:** 결정론 한계. **대안:** 항상 고비용(자원 충분 시).
- **실패 신호:** 임베딩/외부 의존 없으면 검색이 죽음; 매 턴 LLM 검수로 느림.
- 출처: [[ADR-0007 하이브리드 검색 결정론 우선]], [[ADR-0009 결정론 항상 LLM검증 조건부]].
### P3. 차이는 가장자리에서 흡수, 중심은 단일 모델
- **원칙:** 외부(공급자/소스/디바이스)의 차이를 경계 어댑터에서 정규화하고 내부는 하나의 형태로.
- **조건:** 이질적 외부가 여럿일 때. **장점:** 호출부 단순·교체 용이. **단점:** 어댑터 비용. **대안:** 직접 결합(소수일 때).
- **실패 신호:** 공급자별 분기가 코드 전체에 산재.
- 출처: [[LLM 프로바이더 추상화]], [[Data Flow Pattern]].
### P4. 이력이 가치면 추가만 하라
- **원칙:** 변경 이력이 중요하면 상태 덮어쓰기 대신 append-only 이벤트. 현재 상태는 재생.
- **조건:** 감사/재현/되돌리기 필요. **장점:** 이력 보존·내결함. **단점:** 파일 증가·재생 비용. **대안:** 상태 저장(마지막 값만 중요).
- **실패 신호:** "언제 바뀌었지?" 를 알 수 없음.
- 출처: [[ADR-0001 이벤트 소싱 채택]], [[이벤트 소싱 스토어 패턴]].
### P5. 기억은 수명별로 분리하라
- **원칙:** 수명·만료·우선순위가 다른 기억은 다른 계층/저장소에. 시한부엔 만료, 오래된 건 압축.
- **조건:** 세션 넘는 상태가 다양할 때. **장점:** 정밀 선별. **단점:** 분류 비용. **대안:** 단일 버퍼(단발성).
- **실패 신호:** 옛 사실을 현재처럼 답함.
- 출처: [[ADR-0002 5계층 메모리 분리]], [[Memory Pattern]].
### P6. 추상화는 두 번째 구현에서
- **원칙:** 구현이 2개 이상이거나 테스트에 가짜가 필요할 때 인터페이스를 도입. 하나뿐이면 미루라(YAGNI).
- **조건:** 교체/테스트 필요. **장점:** 결합↓·테스트성. **단점:** 과추상화 비용. **대안:** 직접 구현.
- **실패 신호:** 구현 1개짜리 인터페이스가 가득(얇은 래퍼 지옥).
- 출처: [[ADR-0006 수동 의존성주입 인터페이스 서비스]], [[의존성 주입과 서비스 인터페이스]].
### P7. 모델/외부 출력은 신뢰되지 않은 입력이다
- **원칙:** LLM·외부 프로세스·플러그인 출력은 검증·샌드박스·승인 후 사용. JSON 은 강건 파서로.
- **조건:** 외부 효과(파일/명령/IPC)가 있을 때. **장점:** 보안·안정. **단점:** 검증 코드. **대안:** 화이트리스트만.
- **실패 신호:** 모델이 시키는 대로 실행; JSON.parse 직접 호출 실패.
- 출처: [[Tool Calling Pattern]], [[Critic Pattern]], [[IPC Pattern]].
### P8. 실패는 분류하고 본류를 지켜라
- **원칙:** 복구 가능(재시도/폴백)·불가(throw)·부가(이유 주석 후 무시)로 분류. 사용자에겐 행동 지침으로 번역.
- **조건:** I/O·외부 의존. **장점:** 복원력. **단점:** 코드량. **대안:** 크래시-온리.
- **실패 신호:** 무음 빈 catch 로 실패 은폐; 부가 실패가 본류 중단.
- 출처: [[Error Handling Pattern]], [[에러 처리와 커스텀 에러]].
### P9. 흐름은 한 곳에서 읽히게, 구현은 추출
- **원칙:** 거대 함수는 흐름 골격만 남기고 세부를 순수 모듈로. 단, 크기 상한을 정하라.
- **조건:** 복잡한 단일 흐름. **장점:** 가독성+테스트성. **단점:** 경계 판단 필요. **대안:** 완전 분해(흐름 분산) 또는 모놀리식.
- **실패 신호:** 한 턴 흐름을 파악하려 파일 10개를 떠돔; 또는 5천 줄 god-class.
- 출처: [[ADR-0010 오케스트레이터 골격 모듈추출]], [[Architecture Separation Pattern]].
### P10. 변하지 않은 것은 다시 계산하지 마라
- **원칙:** 비싼 계산은 캐시하되 *무효화 전략(변경 감지/버전)* 을 먼저 정하라.
- **조건:** 반복 계산·조회. **장점:** 성능. **단점:** stale 위험. **대안:** 매번 계산.
- **실패 신호:** 무효화 누락으로 옛 결과; 키 충돌.
- 출처: [[Caching Pattern]], mtime 인덱스([[TF-IDF 이중언어 스코어링]]).
### P11. 주석은 '왜'와 '왜 다른 방법이 아닌지'를 적어라
- **원칙:** 코드가 못 말하는 의도·제약·기각한 대안·버그 사후기록을 남겨라.
- **조건:** 비자명한 결정/함정. **장점:** 지식 전수(특히 AI 학습). **단점:** 노후화 관리. **대안:** ADR 문서.
- **실패 신호:** "이게 왜 이렇지?" 를 아무도 모름; 같은 버그 재발.
- 출처: [[코딩 컨벤션과 주석 철학]], [[교훈 라이브러리 Lessons Learned]].
### P12. 피드백 1회를 시스템 변화로 환원하라
- **원칙:** 사용자 정정/오류를 *통계로만* 두지 말고 다음 동작(프롬프트·규칙)을 자동으로 바꿔라.
- **조건:** 학습/개선 루프가 필요할 때. **장점:** 자기진화. **단점:** 폭주 위험(임계·상한 필요). **대안:** 수동 개선.
- **실패 신호:** 리포트만 쌓이고 행동이 안 바뀜; 1회성 노이즈로 프롬프트 오염.
- 출처: [[Intelligence 검증 레이어]](correction loop), [[AITRAIN 검증 레이어]].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
원칙끼리도 충돌한다(예: P6 추상화 미루기 vs P3 어댑터 도입). 충돌 시 [[엔지니어링 트레이드오프 분석]] 으로 내려가 *맥락* 으로 결정. 메타 원칙: **단순함 우선 · YAGNI · 환경이 결정 · 측정으로 검증.**
## 🛠️ 적용 사례 (Applied in summary)
각 원칙은 ConnectAI 의 구체 결정에서 일반화. 다른 프로젝트(웹/모바일/백엔드)에 그대로 적용 가능 — [[플랫폼 개발 가이드 인덱스]] 의 가이드들이 이 원칙의 플랫폼별 구체화.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[Topic Programming 인덱스]]
- **관련 개념:** [[아키텍처 휴리스틱]], [[엔지니어링 트레이드오프 분석]], [[패턴 카탈로그 인덱스]], [[교훈 라이브러리 Lessons Learned]]
- **참조 맥락:** 작은 모델이 *어떤* 프로젝트를 설계하든 최상위 원칙으로 먼저 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI 전체 결정의 일반화(본 위키 ADR/패턴/교훈 모음)
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 설계 원칙을 프로젝트 독립 형태로 일반화.
@@ -0,0 +1,142 @@
---
id: typescript-advanced-types
title: "TypeScript 고급 타입"
category: "Programming_Language"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["제네릭", "Generics", "타입 가드", "discriminated union", "유틸리티 타입", "Partial", "Omit"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.94
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["typescript", "language", "generics", "type-guard", "advanced", "connectai"]
raw_sources: ["ConnectAI/src/features/_shared/eventSourcedStore.ts", "ConnectAI/src/core/queue.ts", "ConnectAI/src/features/providers/types.ts", "ConnectAI/src/memory/index.ts", "ConnectAI/src/intelligence/criticAgent.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[TypeScript 고급 타입]]
## 🎯 한 줄 통찰 (One-line insight)
제네릭·판별 유니온·타입 가드·유틸리티 타입은 "중복을 없애면서도 타입 안전을 유지"하는 도구이며, ConnectAI 는 이들로 **하나의 제네릭 스토어가 4개 도메인을 안전하게 처리**하고 **함수 결과를 성공/실패로 명확히 분기**한다 [S1].
## 🧠 핵심 개념 (Core concepts)
1. **제네릭 (Generics):** `createEventStore<E>(...)` 처럼 타입을 파라미터로 받아, 호출부가 `CustomerEvent`/`HireEvent` 등 구체 타입을 끼워 넣으면 그 타입으로 동작한다. 코드는 한 벌, 타입은 N 벌 [S1].
2. **판별 유니온 (Discriminated union):** 공통 *판별 필드* 로 갈래를 나눈 union. `{ ok: true; filePath } | { ok: false; error }` 처럼 `ok` 를 검사하면 컴파일러가 나머지 필드를 자동으로 좁힌다 [S1].
3. **타입 가드 (Type guard):** 반환 타입을 `x is T` 로 선언한 함수. `validate: (e: unknown) => e is E` 가 true 면 컴파일러가 그 블록에서 `e``E` 로 취급한다 — 런타임 검증과 컴파일 타입 좁히기를 동시에 [S1].
4. **유틸리티 타입 (Utility types):** `Partial<T>`(모든 필드 옵셔널), `Omit<T, K>`(특정 키 제외), `Record<K, V>`(키-값 맵), `Pick<T, K>`. 기존 타입에서 파생 타입을 *연산* 으로 만든다 [S2][S3].
5. **`keyof` / 인덱스 시그니처:** 객체 키 집합을 타입으로 (`Record<string, number>`), 동적 키 접근을 안전하게.
## 🧩 추출된 패턴 (Extracted patterns)
- **제네릭 팩토리 + 검증 주입:** `createEventStore<E>({ relPath, validate })` — 타입 파라미터와 런타임 검증을 함께 받아 I/O 를 추상화하고 도메인 로직은 호출부에 남긴다 [S1].
- **결과를 판별 유니온으로:** 예외를 던지는 대신 `{ ok: true } | { ok: false; error }` 를 반환해 호출부가 분기를 강제로 처리하게 한다 (Rust 의 `Result` 와 유사) [S1].
- **`Partial<T>` 로 설정 병합:** 생성자가 `config?: Partial<MemoryConfig>` 를 받아 기본값과 스프레드 병합 (`{ ...defaults, ...config }`) — 부분 오버라이드 패턴 [S4].
- **`Omit<T, 'model'>` 로 파라미터 일부만:** `streamCloudCompletion``Omit<StreamParams, 'model'>` 을 받아, model 은 내부에서 채운다 — "이미 아는 필드는 받지 않는다" [S3].
- **함수 타입 별칭으로 의존성 주입:** `type CritiqueLlmCall = (system, user, maxTokens) => Promise<string>` — LLM 호출을 타입으로 추상화해 모듈을 순수하게 유지 [S5].
## 📖 세부 내용 (Details)
### 제네릭의 실전 가치
ConnectAI 는 customers/hire/runway/feedback 4개 스토어가 같은 CRUD 패턴을 반복해 ~240줄 중복이 있었다. 이를 `createEventStore<E>` 하나로 통합 — 타입 파라미터 `E` 덕분에 각 스토어는 자기 이벤트 타입을 그대로 유지하면서 코드는 공유한다. 제네릭이 없었다면 `any` 로 타입을 잃거나 4벌을 복붙해야 했다 [S1].
```typescript
export interface EventStore<E> {
read(): E[];
append(event: E): { ok: true; filePath: string } | { ok: false; error: string };
count(): number;
}
export function createEventStore<E>(opts: EventStoreOptions<E>): EventStore<E> { /* ... */ }
```
### 판별 유니온으로 안전한 분기
`append` 의 반환값을 보면 호출부는 반드시 `ok` 를 먼저 검사해야 한다:
```typescript
const r = store.append(ev);
if (r.ok) { use(r.filePath); } // 이 블록에서 r.error 는 타입상 존재하지 않음
else { show(r.error); } // 이 블록에서 r.filePath 는 존재하지 않음
```
컴파일러가 갈래별로 접근 가능한 필드를 제한하므로, "성공 경로에서 error 를 읽는" 류의 버그가 원천 차단된다.
### 타입 가드 = 런타임 검증 + 컴파일 좁히기
```typescript
validate: (e: unknown) => e is CustomerEvent // 호출부 시그니처
// 내부에서
if (opts.validate(parsed)) out.push(parsed); // parsed 가 여기서 E 로 좁혀짐
```
`unknown` 으로 받은 외부 JSON 을 가드 통과 후에만 `E[]` 로 쌓는다 — type erasure 로 런타임에 타입이 없는 한계를 가드로 메운다.
### 제네릭 제약과 기본 타입 파라미터
`enqueue<T>(task: () => Promise<T>): Promise<T>` 처럼 메서드 단위 제네릭도 흔하다. 태스크의 반환 타입 `T` 가 그대로 큐의 반환 타입으로 흐른다 [S2].
## ⚖️ 비교 및 선택 기준 (Comparison & decision criteria)
| 항목 (Option) | 장점 | 단점 | 언제 선택 |
|---|---|---|---|
| 예외 throw | 작성 간단, 호출부 코드 짧음 | 호출부가 처리를 잊기 쉬움 | 진짜 예외적 상황(I/O 실패) |
| 판별 유니온 결과 | 호출부가 분기를 강제 처리 | 보일러플레이트 증가 | 실패가 정상 흐름의 일부일 때 (`append`) |
| 제네릭 함수 | 타입 안전 + 중복 제거 | 시그니처 복잡해질 수 있음 | 같은 로직이 여러 타입에 반복될 때 |
| `any` 캐스팅 | 즉시 통과 | 타입 안전 상실 | 최후의 수단, 외부 라이브러리 경계 |
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **과도한 제네릭은 독:** 타입 파라미터가 3개를 넘거나 조건부 타입이 중첩되면 가독성이 급락한다. ConnectAI 는 대부분 단일 `<E>`/`<T>` 수준으로 절제한다.
- **결과 유니온 vs 예외:** ConnectAI 는 둘을 혼용한다 — 파일 append 같은 "흔한 실패"는 유니온, 트랜잭션 위반 같은 "계약 위반"은 커스텀 예외(throw). 일관 규칙은 "호출부가 정상적으로 마주칠 실패면 유니온".
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/features/_shared/eventSourcedStore.ts` — 제네릭 + 타입 가드 + 판별 유니온이 한 파일에 모두 [S1].
- `ConnectAI/src/memory/index.ts``constructor(brainPath, config?: Partial<MemoryConfig>)` + `{ ...defaults, ...config }` 병합 [S4].
- `ConnectAI/src/features/providers/index.ts``Omit<StreamParams, 'model'>` 로 일부 필드만 받는 함수 [S3].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 제네릭 팩토리 + 타입 가드 주입 (src/features/_shared/eventSourcedStore.ts)
export interface EventStoreOptions<E> {
relPath: string;
validate: (e: unknown) => e is E; // 타입 가드: 런타임 검증 + 컴파일 좁히기
}
export function createEventStore<E>(opts: EventStoreOptions<E>): EventStore<E> { /* ... */ }
// 사용처:
const store = createEventStore<CustomerEvent>({
relPath: '.astra/customers.jsonl',
validate: (e): e is CustomerEvent =>
typeof (e as any).id === 'string' && typeof (e as any).customerId === 'string',
});
// 2) 판별 유니온 결과 — 호출부가 분기 강제
function append(event: E): { ok: true; filePath: string } | { ok: false; error: string } {
try { /* write */ return { ok: true, filePath }; }
catch (e: any) { return { ok: false, error: e?.message || String(e) }; }
}
// 3) Partial<T> 로 부분 설정 병합 (src/memory/index.ts)
constructor(brainPath: string, config?: Partial<MemoryConfig>) {
this.config = { enabled: true, shortTermLimit: 8, /* ...defaults */ ...config };
}
// 4) 함수 타입 별칭으로 의존성 주입 (src/intelligence/criticAgent.ts)
export type CritiqueLlmCall = (system: string, user: string, maxTokens: number) => Promise<string>;
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied (ConnectAI 1차 코드에서 모든 패턴 확인)
- **출처 신뢰도:** A
- **신뢰 점수:** 0.94
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[TypeScript 기초와 타입 시스템]]
- **관련 개념:** [[이벤트 소싱 스토어 패턴]], [[에러 처리와 커스텀 에러]], [[의존성 주입과 서비스 인터페이스]]
- **참조 맥락:** 로컬 LLM 이 중복 제거·안전한 결과 반환·검증 코드를 작성할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/features/_shared/eventSourcedStore.ts — 제네릭, 타입 가드, 판별 유니온 결과
- [S2] ConnectAI/src/core/queue.ts — 메서드 제네릭 `enqueue<T>`
- [S3] ConnectAI/src/features/providers/index.ts, types.ts — Omit, union literal, ReadonlyArray
- [S4] ConnectAI/src/memory/index.ts — Partial<T> + 스프레드 병합
- [S5] ConnectAI/src/intelligence/criticAgent.ts — 함수 타입 별칭(의존성 주입)
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,113 @@
---
id: typescript-basics-type-system
title: "TypeScript 기초와 타입 시스템"
category: "Programming_Language"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["TypeScript", "TS", "타입스크립트", "정적 타이핑", "strict mode"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.95
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["typescript", "language", "type-system", "fundamentals", "connectai"]
raw_sources: ["ConnectAI/tsconfig.json", "ConnectAI/src/core/services.ts", "ConnectAI/src/memory/types.ts", "TypeScript Handbook (general knowledge)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[TypeScript 기초와 타입 시스템]]
## 🎯 한 줄 통찰 (One-line insight)
TypeScript 는 JavaScript 에 **정적 타입 계층**을 얹어 "실행 전에 오류를 잡는" 언어이며, ConnectAI 처럼 `strict: true` 로 운영하면 컴파일러가 `null`/`undefined`/타입 불일치를 코드 작성 시점에 강제로 드러낸다 [S1].
## 🧠 핵심 개념 (Core concepts)
1. **점진적 타이핑 (Gradual typing):** JS 코드에 타입을 점진적으로 추가할 수 있다. 타입을 안 쓰면 `any` 로 동작하지만, ConnectAI 는 `strict` 모드로 `any` 를 최대한 배제한다 [S1].
2. **구조적 타이핑 (Structural typing):** 이름이 아니라 *구조(모양)* 가 같으면 호환된다. `interface IAIService` 를 명시적으로 `implements` 하지 않아도 같은 메서드를 가지면 그 타입으로 통한다 — 다만 ConnectAI 는 가독성을 위해 `implements` 를 명시한다 [S2].
3. **컴파일 타임 vs 런타임:** 타입은 컴파일 후 *지워진다(type erasure)*. 런타임에는 타입 정보가 없으므로, 외부 입력 검증은 **타입 가드 함수**로 직접 해야 한다 (`validate: (e: unknown) => e is E`) [S3].
4. **`strict` 플래그:** `strictNullChecks`, `noImplicitAny` 등을 한 번에 켠다. `null`/`undefined` 가 다른 타입에 섞이지 않게 하여, "정의되지 않음" 버그를 구조적으로 차단한다 [S1].
5. **타입 추론 (Inference):** 명시하지 않아도 컴파일러가 초기값·반환값에서 타입을 추론한다. 불필요한 타입 주석은 생략하고, 경계(함수 시그니처·공개 API)에만 명시하는 것이 ConnectAI 스타일이다.
## 🧩 추출된 패턴 (Extracted patterns)
- **경계에 타입, 내부에 추론:** 공개 함수/인터페이스는 타입을 명시하고(`public async chat(req: AIChatRequest): Promise<AIChatResult>`), 함수 내부 지역 변수는 추론에 맡긴다 [S2].
- **`interface` 로 데이터 형태 선언:** 도메인 데이터는 `interface` 로 모양을 먼저 정의한다 (`LongTermEntry`, `EpisodicEntry`). 구현보다 *형태* 를 먼저 설계하는 타입 우선 접근 [S3].
- **`type` 별칭으로 유한 집합 표현:** 고정된 문자열 집합은 union literal type 으로 (`type MemoryLayer = 'short-term' | 'long-term' | ...`). 오타를 컴파일러가 잡고, switch 에서 누락 케이스를 경고한다 [S3].
- **`readonly` / `as const` 로 불변 데이터:** 상수 배열은 `as const` 또는 `ReadonlyArray<...>` 로 변경 불가를 표현 (`PROVIDER_PREFIXES`) [S4].
## 📖 세부 내용 (Details)
### 기본 타입
`string`, `number`, `boolean`, `null`, `undefined`, `bigint`, `symbol`, 그리고 객체 타입(`object`, 배열 `T[]`, 튜플 `[A, B]`). 특수 타입으로 `any`(타입 검사 끔 — 지양), `unknown`(any 의 안전판 — 사용 전 좁히기 강제), `never`(도달 불가), `void`(반환값 없음)가 있다.
### `interface` vs `type`
- `interface`: 객체 *형태* 선언에 적합. 선언 병합(declaration merging)·`extends` 가능. ConnectAI 는 도메인 엔티티에 주로 `interface` 사용 (`MemoryContextResult`, `ProjectMemoryStore`) [S3].
- `type`: union/intersection/조건부 타입 등 *타입 연산* 에 적합. ConnectAI 는 union literal (`type ProviderId = 'openrouter' | 'anthropic' | 'gemini'`) 과 함수 타입 별칭에 사용 [S4].
- 실무 규칙: "객체 모양이면 `interface`, 합집합·매핑·연산이면 `type`".
### `strict` 가 강제하는 것 (ConnectAI tsconfig 기준)
`module: commonjs`, `target: ES2022`, `lib: ["ES2022", "DOM"]`, `strict: true`, `skipLibCheck: true` 로 설정 [S1]. `strict` 가 켜지면:
- `strictNullChecks`: `string | undefined``string` 에 바로 못 넣는다. 옵셔널 필드(`expiresAt?: number`)는 사용 전 `if (entry.expiresAt)` 같은 좁히기 필요 [S3].
- `noImplicitAny`: 타입을 추론할 수 없는 파라미터에 `any` 를 암묵 허용하지 않음 → 명시 강제.
- `strictFunctionTypes`, `strictBindCallApply` 등 함수 타입의 안전성 강화.
### 옵셔널·기본값·널 처리
- 옵셔널 프로퍼티 `field?: T` 는 값이 `T | undefined`. 코드에서 `req.timeoutMs ?? config.timeout` 처럼 **nullish 병합(`??`)** 으로 기본값을 준다. `||` 와 달리 `0`/`''`/`false` 를 유효값으로 보존한다 [S2].
- 옵셔널 체이닝 `data.choices?.[0]?.message?.content` 로 중첩 접근 중 `undefined` 를 안전하게 통과 [S2].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **`interface` vs `type` 논쟁:** 둘은 많은 경우 호환되며 "무엇을 써야 하는가"에 절대 정답은 없다. ConnectAI 의 실제 관례(객체=interface, 연산=type)를 따르는 것이 일관성 측면에서 안전하다.
- **`any` vs `unknown`:** 레거시 호환을 위해 ConnectAI 도 일부 `as any` 캐스팅을 쓰지만(예: `data` JSON 파싱 후), 새 코드에서는 외부 입력에 `unknown` + 타입 가드를 쓰는 것이 안전하다 [S3].
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/memory/types.ts` — 5계층 메모리의 모든 데이터 형태를 `interface`/`type` 로 선언. 옵셔널 temporal marker(`expiresAt?`)와 union category(`LongTermCategory`)가 strict 환경에서 어떻게 쓰이는지 보여준다 [S3].
- `ConnectAI/src/core/services.ts``interface IAIService` + `class AIService implements IAIService` 로 "인터페이스 선언 → 구현" 패턴 [S2].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) union literal type 으로 유한 집합 — 오타를 컴파일러가 차단 (src/memory/types.ts)
export type MemoryLayer = 'short-term' | 'long-term' | 'project' | 'procedural' | 'episodic';
// 2) interface 로 데이터 형태 선언 + 옵셔널 필드 (strictNullChecks 대응)
export interface LongTermEntry {
id: string;
category: LongTermCategory;
confidence: number; // 0.0~1.0
expiresAt?: number; // undefined = 영구. 사용 전 좁히기 필요
}
// 3) nullish 병합으로 기본값 — 0/''/false 를 보존 (src/core/services.ts)
const timeoutMs = req.timeoutMs ?? config.timeout; // ?? : null/undefined 일 때만 기본값
const model = (req.model || config.defaultModel || '').trim() || 'gemma4:e2b'; // || : falsy 전부 대체
// 4) 옵셔널 체이닝으로 안전한 중첩 접근
const content = data.choices?.[0]?.message?.content || '';
// 5) interface → implements 로 계약 명시
export interface IAIService { call(prompt: string): Promise<string>; }
export class AIService implements IAIService {
public async call(prompt: string): Promise<string> { /* ... */ return ''; }
}
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied (ConnectAI 실제 소스에서 패턴 확인됨)
- **출처 신뢰도:** A (언어 사양 + 1차 코드)
- **신뢰 점수:** 0.95
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[TypeScript 기초와 타입 시스템]]
- **관련 개념:** [[TypeScript 고급 타입]], [[비동기 프로그래밍 Promise async await]], [[에러 처리와 커스텀 에러]]
- **참조 맥락:** 로컬 LLM 이 TypeScript 코드를 작성/수정할 때 타입 선언·null 안전·strict 규칙의 기본기로 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/tsconfig.json — strict/target/module 컴파일러 설정
- [S2] ConnectAI/src/core/services.ts — IAIService 인터페이스, ?? vs || 기본값, 옵셔널 체이닝
- [S3] ConnectAI/src/memory/types.ts — interface/type 선언, 옵셔널 필드, union literal
- [S4] ConnectAI/src/features/providers/types.ts — type 별칭, as const, ReadonlyArray
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성 (로컬 LLM 코딩 지식 베이스 구축).
@@ -0,0 +1,122 @@
---
id: module-system-project-structure
title: "모듈 시스템과 프로젝트 구성"
category: "Programming_Language"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["import", "export", "모듈", "barrel", "side-effect import", "dynamic import", "esbuild", "번들링"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.92
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["typescript", "module", "import", "esbuild", "project-structure", "connectai"]
raw_sources: ["ConnectAI/src/extension.ts", "ConnectAI/src/memory/index.ts", "ConnectAI/src/retrieval/index.ts", "ConnectAI/package.json", "ConnectAI/tsconfig.json"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[모듈 시스템과 프로젝트 구성]]
## 🎯 한 줄 통찰 (One-line insight)
모듈 시스템은 "무엇을 공개하고(`export`) 무엇을 가져올지(`import`)"로 코드 경계를 긋는 것이며, ConnectAI 는 **barrel(index.ts) 재수출·side-effect import 자기등록·동적 import 지연로딩**을 조합해 308개 파일을 esbuild 단일 번들로 묶는다 [S1][S4].
## 🧠 핵심 개념 (Core concepts)
1. **ES Module 문법:** `import { x } from './m'` / `export function x()`. TypeScript 는 이 문법을 쓰고, tsconfig `module: commonjs` 로 CommonJS 로 컴파일된다 [S5].
2. **named vs default export:** ConnectAI 는 거의 전부 *named export* 만 쓴다 — 자동완성·일관된 이름·리팩터링 안전성 때문. default export 는 사실상 배제 [S2].
3. **Barrel 파일 (index.ts):** 하위 모듈을 한 곳에서 재수출(`export * from './types'`)해 외부가 깔끔한 진입점 하나만 import 하게 한다 [S2][S3].
4. **Side-effect import:** `import './features/teamops/handlers'` — 값을 가져오지 않고 *모듈 로드의 부수효과*(핸들러 자기등록)만 노린다 [S1].
5. **Dynamic import (`await import(...)`):** 무겁거나 드물게 쓰는 모듈을 실제 호출 시점에 지연 로딩 — 활성화 시간 단축 [S1].
6. **번들링 (esbuild):** 모든 모듈을 `out/extension.js` 하나로 묶되 `vscode` 는 external (런타임 제공) [S4].
## 🧩 추출된 패턴 (Extracted patterns)
- **상대경로 import + 명확한 트리:** `../config`, `./types` 같은 상대경로로 모듈을 참조하고, 폴더 구조가 곧 도메인 경계(`features/`, `core/`, `memory/`, `retrieval/`, `intelligence/`).
- **barrel 재수출로 진입점 단일화:** `src/memory/index.ts` 가 5개 메모리 클래스 + distillation API + `export * from './types'` 를 한 번에 노출 [S3].
- **side-effect import 로 핸들러 자기등록:** entry point 가 `import './features/system/handlers'` 만 하면 그 모듈이 slashRouter 에 자기를 등록 — 등록 코드를 한 곳에 모으지 않는 분산 등록 [S1].
- **동적 import 로 무거운 기능 지연:** `const { runDatacollectSetup } = await import('./features/setup/datacollectSetup')` — 명령 실행 시에만 로드 [S1].
- **타입 전용 import:** `import type { ChatMessage } from '../../agent'` — 컴파일 후 사라지는 타입만 가져와 순환참조·번들 부담 회피 [S6].
## 📖 세부 내용 (Details)
### 폴더 = 도메인 경계
```
src/
core/ 공통 인프라 (lock, queue, transaction, errors, services, events)
features/ 기능 도메인 (각 폴더가 독립 기능: stocks, calendar, company, datacollect…)
memory/ 5계층 메모리
retrieval/ RAG 검색
intelligence/ 검증·자기평가 (critic, confidence, correctionLoop)
lib/ 순수 헬퍼 + contextBuilders (프롬프트 컨텍스트 조립)
agent/ 에이전트 실행 세부 (handlePrompt/, llm/, actions/, multiAgent/)
```
각 폴더 안에 `index.ts`(barrel)가 있으면 외부는 그 하나만 import 한다.
### import 순서·스타일
실제 코드는 (1) Node 표준(`fs`, `path`), (2) vscode, (3) 내부 모듈 순으로 import 하며, 내부는 도메인별로 묶어 가독성을 유지한다. 거대한 orchestrator(agent.ts)는 import 가 100줄을 넘는데, 이는 *기능을 작은 모듈로 추출하고 다시 끌어모으는* 구조의 자연스러운 결과다 [S1].
### side-effect import 의 순서 민감성
```typescript
// slashRouter 가 먼저 로드된 뒤 핸들러가 자기 등록되도록 entry point 에서 import
import './features/teamops/handlers';
import './features/system/handlers';
import './features/datacollect/handlers';
```
주석이 "왜 여기서 import 하는지"(로드 순서 보장)를 명시한다 — side-effect import 는 순서가 동작에 영향을 주므로 의도를 적는 것이 필수 [S1].
### 번들/빌드
- `compile`: `esbuild src/extension.ts --bundle --platform=node --external:vscode --outfile=out/extension.js` — 단일 파일 번들 [S4].
- `watch`: `tsc -watch` (타입 체크용), `test`: `jest`. 런타임 의존성은 `@lmstudio/sdk`, `pdf-parse` 둘뿐이고 axios 대신 native `fetch` 사용 [S4].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **barrel 의 양날:** index.ts 재수출은 진입점을 깔끔히 하지만, 과하면 순환참조와 "한 줄 import 가 거대한 그래프를 끌어옴" 문제를 낳는다. ConnectAI 는 무거운 기능을 동적 import 로 분리해 이를 완화 [S1].
- **commonjs vs ESM:** tsconfig 는 `commonjs` 로 컴파일하지만 소스는 ESM 문법으로 작성한다 — VS Code 확장 런타임(Node)이 CJS 를 기대하기 때문. 새 프로젝트라면 ESM 출력도 가능하나 호환성 고려 필요 [S5].
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/extension.ts` — side-effect import, 동적 import, 100+줄 named import 의 실제 예 [S1].
- `ConnectAI/src/memory/index.ts`, `src/retrieval/index.ts` — barrel 재수출 [S2][S3].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) side-effect import — 핸들러 자기등록 (순서 주석 필수) (src/extension.ts)
import './features/teamops/handlers';
import './features/system/handlers';
// 2) barrel 재수출로 진입점 단일화 (src/memory/index.ts)
export { ShortTermMemory } from './ShortTermMemory';
export { LongTermMemory } from './LongTermMemory';
export * from './types';
// 3) 동적 import 로 무거운 기능 지연 (src/extension.ts)
vscode.commands.registerCommand('g1nation.setupDatacollect', async () => {
const { runDatacollectSetup } = await import('./features/setup/datacollectSetup');
await runDatacollectSetup();
});
// 4) 타입 전용 import — 런타임 부담/순환참조 회피
import type { AgentExecutorOptions, ChatMessage } from '../../agent';
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.92
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[TypeScript 기초와 타입 시스템]]
- **관련 개념:** [[ConnectAI 아키텍처 개요]], [[VSCode 확장 구조와 생명주기]], [[코딩 컨벤션과 주석 철학]]
- **참조 맥락:** 로컬 LLM 이 파일을 나누고 import/export 를 구성할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/extension.ts — side-effect/동적 import, named import 구성
- [S2] ConnectAI/src/features/providers/index.ts — named export, 재수출
- [S3] ConnectAI/src/memory/index.ts, src/retrieval/index.ts — barrel(export *) 패턴
- [S4] ConnectAI/package.json — esbuild 번들 스크립트, 의존성
- [S5] ConnectAI/tsconfig.json — module/target 설정
- [S6] ConnectAI/src/agent/multiAgent/workflow.ts — import type
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,131 @@
---
id: async-programming-promise-async-await
title: "비동기 프로그래밍 Promise async await"
category: "Programming_Language"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["Promise", "async", "await", "비동기", "AbortSignal", "동시성", "스트리밍", "concurrency"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.93
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["typescript", "javascript", "async", "promise", "abortsignal", "connectai"]
raw_sources: ["ConnectAI/src/core/services.ts", "ConnectAI/src/core/lock.ts", "ConnectAI/src/core/queue.ts", "ConnectAI/src/features/providers/index.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[비동기 프로그래밍 Promise async await]]
## 🎯 한 줄 통찰 (One-line insight)
`async/await` 는 비동기 코드를 동기처럼 읽히게 하는 문법이고, `Promise` 는 그 토대이며, ConnectAI 는 여기에 **`AbortSignal` 결합·타임아웃 경쟁(race)·동시성 제한**을 더해 "취소 가능하고 폭주하지 않는" 비동기를 구현한다 [S1][S2].
## 🧠 핵심 개념 (Core concepts)
1. **Promise:** 미래의 값을 담는 객체. `pending → fulfilled/rejected` 상태를 가진다. `new Promise((resolve, reject) => ...)` 로 직접 만들거나 `async` 함수가 자동 반환한다 [S2].
2. **async/await:** `async` 함수 안에서 `await promise` 는 Promise 가 풀릴 때까지 기다린 ** 을 돌려준다. 실패하면 예외로 던져져 `try/catch` 로 잡는다 [S1].
3. **`Promise.all` / `Promise.race`:** `all` 은 모두 완료될 때까지 병렬 대기(하나라도 실패 시 전체 reject), `race` 는 가장 먼저 끝난 하나를 채택 — ConnectAI 는 race 로 "작업 vs 타임아웃" 경쟁을 만든다 [S3].
4. **`AbortSignal` / `AbortController`:** 진행 중인 비동기(특히 `fetch`)를 외부에서 취소하는 표준 메커니즘. `AbortSignal.timeout(ms)`, `AbortSignal.any([...])` 로 타임아웃·사용자 취소를 결합 [S1].
5. **동시성 제한 (Concurrency limiting):** 무한 병렬은 자원을 고갈시킨다. 큐로 동시 실행 수를 `max(2, cpus-1)` 로 제한 [S4].
## 🧩 추출된 패턴 (Extracted patterns)
- **타임아웃 + 외부 취소 신호 결합:** `AbortSignal.any([req.signal, AbortSignal.timeout(timeoutMs)])` — 둘 중 무엇이 먼저 fire 돼도 fetch 가 즉시 중단된다. 사용자가 "Stop" 을 누르면 LLM 생성 도중에도 끊긴다 [S1].
- **race 로 데드락 방지:** lock 획득 시 `Promise.race([previousPromise, timeoutPromise])` — 앞 작업이 영원히 안 끝나도 timeout 이 깨운다 [S2].
- **resolve 를 밖으로 빼내는 deferred:** `let release; new Promise(r => { release = r; })` — Promise 를 만들고 그 resolve 함수를 외부에서 호출 가능하게 보관(락 해제 함수로 반환) [S2].
- **큐 기반 동시성 캡:** `enqueue<T>` 가 Promise 를 반환하되 실제 실행은 `activeCount < limit` 일 때만 — 초과분은 대기 [S4].
- **best-effort 비차단:** `void ensureEmbeddingConfigured(context)` — 결과를 기다리지 않고 백그라운드로 흘려보내는 fire-and-forget (`void` 로 의도 명시) [S1].
## 📖 세부 내용 (Details)
### await 의 실패는 예외다
`await fetch(...)` 가 네트워크 오류로 reject 되면 그 지점에서 throw 된다. ConnectAI 의 `AIService.chat` 은 엔진별 루프 안에서 `try/catch` 로 잡아 `lastError` 에 저장하고 다음 엔진으로 폴백한다 — "한 엔진 실패가 전체 실패가 아니다" [S1].
### AbortSignal 결합 (핵심 패턴)
```typescript
const timeoutSignal = AbortSignal.timeout(timeoutMs);
const combinedSignal = req.signal
? AbortSignal.any([req.signal, timeoutSignal]) // 사용자 취소 OR 타임아웃
: timeoutSignal;
const res = await fetch(apiUrl, { /* ... */ signal: combinedSignal });
```
이 패턴 덕분에 (1) 응답이 너무 느리면 타임아웃으로, (2) 사용자가 멈추면 외부 signal 로 즉시 중단된다. 긴 multi-turn 경로(dispatcher 등)에는 반드시 `signal` 을 전달하는 것이 규칙 [S1].
### 직접 만드는 Promise (deferred 패턴)
락 매니저는 "다른 코드가 부를 때 풀리는 Promise" 가 필요하다:
```typescript
let release!: () => void;
const newPromise = new Promise<void>((resolve) => { release = resolve; });
// ... 작업이 끝나면 호출부가 release() 를 부르면 newPromise 가 fulfilled
return () => { release(); /* cleanup */ };
```
### 병렬 vs 순차
- 독립 작업은 `Promise.all([a(), b()])` 로 병렬 (provider 모델 목록 동시 조회) [S5].
- 의존 작업은 순차 `await a(); await b();`.
- 자원 부담이 큰 대량 작업은 `Promise.all` 대신 동시성 제한 큐를 쓴다 [S4].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **`Promise.all` 의 함정:** 하나라도 reject 되면 전체가 reject 되고 나머지 성공 결과를 잃는다. 부분 실패를 허용해야 하면 `Promise.allSettled` 를 쓰거나 각 작업을 try/catch 로 감싸야 한다.
- **`await` in loop vs 병렬:** 루프 안 `await` 는 순차 실행이라 느릴 수 있다. 단, ConnectAI 의 엔진 폴백 루프는 *의도적으로 순차* (앞 엔진이 성공하면 뒤는 안 부름).
- **`forEach` + async 주의:** `array.forEach(async ...)` 는 완료를 기다리지 않는다. 대기하려면 `for...of` + `await` 또는 `Promise.all(array.map(...))`.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/core/services.ts` — AbortSignal 결합 + 엔진 폴백 루프(try/catch 순차) [S1].
- `ConnectAI/src/core/lock.ts` — deferred Promise + `Promise.race` 타임아웃 [S2].
- `ConnectAI/src/core/queue.ts` — 동시성 제한 큐 [S4].
- `ConnectAI/src/features/providers/index.ts``Promise.all(tasks)` 로 provider 목록 병렬 조회 [S5].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 타임아웃 + 외부 취소 결합 (src/core/services.ts)
const timeoutSignal = AbortSignal.timeout(timeoutMs);
const combinedSignal = req.signal ? AbortSignal.any([req.signal, timeoutSignal]) : timeoutSignal;
const res = await fetch(apiUrl, { method: 'POST', body: JSON.stringify(payload), signal: combinedSignal });
// 2) try/catch 폴백 루프 — 한 엔진 실패가 전체 실패가 아님 (src/core/services.ts)
let lastError: Error | null = null;
for (const engine of engines) {
try { const r = await callEngine(engine); if (r) return r; }
catch (e: any) { lastError = e instanceof Error ? e : new Error(String(e)); }
}
throw lastError ?? new Error('All engines failed.');
// 3) deferred Promise + race 타임아웃 (src/core/lock.ts)
let release!: () => void;
const newPromise = new Promise<void>((resolve) => { release = resolve; });
const timeoutPromise = new Promise<never>((_, reject) =>
setTimeout(() => reject(new Error('Lock timed out')), timeoutMs));
await Promise.race([previousPromise, timeoutPromise]);
// 4) fire-and-forget (의도적 비대기) — void 로 명시 (src/extension.ts)
void ensureEmbeddingConfigured(context);
// 5) 병렬 수집 (src/features/providers/index.ts)
const tasks: Array<Promise<void>> = [];
tasks.push(listOpenRouterModels(ctx).then((ids) => ids.forEach(pushModel)));
await Promise.all(tasks);
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.93
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[TypeScript 기초와 타입 시스템]]
- **관련 개념:** [[동시성 제어 Lock Queue Transaction]], [[LLM 프로바이더 추상화]], [[에러 처리와 커스텀 에러]]
- **참조 맥락:** 로컬 LLM 이 fetch/취소/타임아웃/병렬 처리를 작성할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/core/services.ts — AbortSignal.any/timeout, 엔진 폴백, void fire-and-forget(extension.ts 포함)
- [S2] ConnectAI/src/core/lock.ts — deferred Promise, Promise.race 타임아웃
- [S3] (general) Promise.all/race 의미론
- [S4] ConnectAI/src/core/queue.ts — 동시성 제한 큐
- [S5] ConnectAI/src/features/providers/index.ts — Promise.all 병렬 수집
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,150 @@
---
id: error-handling-custom-errors
title: "에러 처리와 커스텀 에러"
category: "Programming_Language"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["error handling", "try catch", "커스텀 에러", "graceful degradation", "에러 클래스", "rollback"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.93
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["typescript", "error-handling", "robustness", "connectai"]
raw_sources: ["ConnectAI/src/core/errors.ts", "ConnectAI/src/core/errorHandler.ts", "ConnectAI/src/core/transaction.ts", "ConnectAI/src/memory/index.ts", "ConnectAI/src/core/services.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[에러 처리와 커스텀 에러]]
## 🎯 한 줄 통찰 (One-line insight)
견고한 코드는 "실패를 *예측해서 분류하고*, 사용자에게는 친절히 번역하며, 부가 작업의 실패가 본류를 망가뜨리지 않게" 만든다 — ConnectAI 는 커스텀 에러 계층 + 사용자 친화 번역기 + "절대 본 흐름을 깨지 않는 try/catch" 로 이를 구현한다 [S1][S2][S4].
## 🧠 핵심 개념 (Core concepts)
1. **`Error` 상속 계층:** 도메인별 에러를 `class XError extends Error` 로 만들어, `instanceof` 로 분기하고 추가 컨텍스트(경로, 엔진, 상태코드)를 담는다 [S1].
2. **추상 베이스 클래스:** `abstract class G1Error extends Error` 가 공통 형태(`details`, `getTypeCode()`)를 강제하고, 구체 에러가 타입 코드를 구현 [S1].
3. **에러 번역 (Error translation):** 내부 기술 에러 메시지를 *사용자 행동 지침* 으로 변환 (`title`/`message`/`action`) [S2].
4. **Graceful degradation:** 부가 기능(메모리 추출, 증류, 텔레메트리)의 실패는 삼키고(`catch {}`) 본 흐름을 계속한다 [S4].
5. **트랜잭션/롤백:** 여러 파일 변경을 묶고, 실패 시 백업으로 되돌리는 보상 트랜잭션 [S3].
## 🧩 추출된 패턴 (Extracted patterns)
- **커스텀 에러에 컨텍스트 부착:** `FileSystemError(message, path, details)`, `APICommunicationError(message, engine, status)` — 잡는 쪽이 어디서 왜 실패했는지 알 수 있게 [S1].
- **`this.name = this.constructor.name`:** 스택 트레이스에 정확한 클래스명이 찍히도록 베이스에서 설정 [S1].
- **"본 흐름을 깨지 않는" catch:** `try { extract(); } catch { /* memory extraction should never break the main flow */ }` — 의도를 주석으로 명시한 의도적 삼킴 [S4].
- **에러를 Error 로 정규화:** `error instanceof Error ? error : new Error(String(error))` — catch 의 `unknown`/`any` 를 항상 Error 로 변환 [S5].
- **사용자 친화 번역기:** 키워드 매칭(`fetch`/`timeout`/`404`)으로 정형화된 안내 카드를 반환 [S2].
- **보상 트랜잭션:** 변경 전 원본을 백업(`record`), 성공 시 `commit`(백업 폐기), 실패 시 `rollback`(원복) [S3].
## 📖 세부 내용 (Details)
### 에러 클래스 계층
```typescript
abstract class G1Error extends Error {
constructor(public message: string, public details?: any) {
super(message);
this.name = this.constructor.name; // 스택에 실제 클래스명
}
abstract getTypeCode(): string; // 하위가 타입 코드 구현 강제
}
export class FileSystemError extends G1Error {
constructor(message: string, public path: string, details?: any) { super(message, details); }
getTypeCode() { return 'FILE_SYSTEM_ERROR'; }
}
```
`abstract` 메서드로 모든 하위 에러가 식별 코드를 갖게 강제 — 로깅/분기에서 문자열 비교 대신 안정적 코드를 쓴다 [S1].
### "절대 본 흐름을 깨지 않는다"
세션 종료 시 메모리 추출·증류는 *부가 작업* 이다. 실패해도 대화 자체는 정상이어야 하므로 빈 catch 로 삼키되 **왜 삼키는지 주석을 단다**:
```typescript
try { this.extractor.extractFromSession(...); }
catch { /* memory extraction should never break the main flow */ }
```
무분별한 빈 catch 는 안티패턴이지만, "부가 작업 + 의도 주석" 조합은 의도적 견고성이다 [S4].
### 사용자 친화 번역
```typescript
if (msg.includes('timeout')) return {
title: '⏱️ 응답 시간 초과 (Timeout)',
message: 'AI가 답변을 준비하는 데 너무 오래 걸리고 있습니다.',
action: '설정에서 Timeout 시간을 늘리거나, 더 작은 범위로 질문해보세요.',
};
```
기술 메시지(`ECONNREFUSED`)를 그대로 노출하지 않고, *무엇을 하면 되는지* 를 알려준다. 마지막에 일반 fallback 카드로 미분류 에러를 처리 [S2].
### 보상 트랜잭션 (파일 작업의 원자성)
DB 트랜잭션이 없는 파일시스템에서 "여러 파일 변경을 전부 성공 또는 전부 취소" 하려면 직접 백업/복원해야 한다. `begin → record(각 파일) → (성공) commit / (실패) rollback`. rollback 은 `created` 파일은 삭제, `modified` 파일은 원본 내용 복원 [S3].
## ⚖️ 비교 및 선택 기준 (Comparison & decision criteria)
| 항목 (Option) | 장점 | 단점 | 언제 선택 |
|---|---|---|---|
| throw + 상위 catch | 흐름 단순 | 어디서 잡을지 추적 필요 | 계약 위반·복구 불가 상황 |
| 빈 catch (의도 주석) | 본 흐름 보호 | 남용 시 버그 은폐 | 진짜 부가 작업만 |
| 결과 유니온 반환 | 호출부 강제 처리 | 보일러플레이트 | 흔한 실패(파일 append) |
| 커스텀 에러 클래스 | instanceof 분기 + 컨텍스트 | 클래스 정의 비용 | 도메인별 처리 분기 필요 |
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **빈 catch 는 기본적으로 위험:** ConnectAI 는 "본 흐름을 깨지 않아야 하는 부가 작업"에 한해 의도 주석과 함께만 허용한다. 검증·핵심 로직의 실패는 절대 조용히 삼키지 않는다.
- **에러 메시지 키워드 매칭의 취약성:** `ErrorTranslator` 는 메시지 문자열에 의존하므로, 라이브러리가 메시지를 바꾸면 매칭이 깨질 수 있다. 가능하면 `getTypeCode()` 같은 안정 식별자 기반 분기가 더 견고하다.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/core/errors.ts` — G1Error 추상 베이스 + 4개 도메인 에러 [S1].
- `ConnectAI/src/core/errorHandler.ts` — ErrorTranslator 사용자 친화 번역 [S2].
- `ConnectAI/src/core/transaction.ts` — begin/record/commit/rollback 보상 트랜잭션 [S3].
- `ConnectAI/src/memory/index.ts` — "본 흐름 보호" 의도적 빈 catch [S4].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 컨텍스트를 담는 커스텀 에러 (src/core/errors.ts)
export class APICommunicationError extends G1Error {
constructor(message: string, public engine: string, public status?: number, details?: any) {
super(message, details);
}
getTypeCode() { return 'API_COMMUNICATION_ERROR'; }
}
// 2) catch 의 unknown 을 Error 로 정규화 (src/core/services.ts)
catch (error: any) {
lastError = error instanceof Error ? error : new Error(String(error));
}
// 3) 본 흐름을 깨지 않는 의도적 삼킴 (src/memory/index.ts)
try { distillStaleEpisodes(...); }
catch { /* distillation should never break session end */ }
// 4) 보상 트랜잭션 (src/core/transaction.ts)
tx.begin();
try {
await tx.record(filePath); // 변경 전 백업
fs.writeFileSync(filePath, next);
tx.commit(); // 성공 → 백업 폐기
} catch (e) {
tx.rollback(); // 실패 → 원본 복원
throw e;
}
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.93
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[TypeScript 기초와 타입 시스템]]
- **관련 개념:** [[동시성 제어 Lock Queue Transaction]], [[비동기 프로그래밍 Promise async await]], [[코딩 컨벤션과 주석 철학]]
- **참조 맥락:** 로컬 LLM 이 실패를 분류·번역·복구하는 코드를 작성할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/core/errors.ts — G1Error 추상 베이스 + 도메인 에러
- [S2] ConnectAI/src/core/errorHandler.ts — ErrorTranslator
- [S3] ConnectAI/src/core/transaction.ts — 보상 트랜잭션
- [S4] ConnectAI/src/memory/index.ts — 의도적 빈 catch
- [S5] ConnectAI/src/core/services.ts — Error 정규화
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,62 @@
---
id: pattern-catalog-index
title: "패턴 카탈로그 인덱스"
category: "Index"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["pattern catalog", "패턴 카탈로그", "design pattern index", "패턴 라이브러리"]
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: ["index", "pattern", "catalog", "navigation"]
raw_sources: ["Pattern_Catalog 전체"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[패턴 카탈로그 인덱스]]
## 🎯 한 줄 통찰 (One-line insight)
플랫폼이 달라도 개발은 *같은 문제(상태·비동기·데이터·캐싱·오류·분리)* 를 반복한다 — 이 카탈로그는 재사용 가능한 패턴 27종을 (언제·조건·장점·단점·대안·실패사례) 형식으로 정리해 작은 모델이 상황에 맞는 패턴을 고르게 한다.
## 🧠 핵심 개념 (Core concepts)
각 패턴 카드 = 문제/조건/장단점/대안/실패. ConnectAI 사례가 있으면 적용 예로 연결, 없으면 일반 지식.
## 📖 세부 내용 (Details · 패턴 목록)
### Cross-cutting (모든 플랫폼 공통 — 최우선 학습)
- [[State Management Pattern]] · [[Async Concurrency Pattern]] · [[Data Flow Pattern]] · [[Caching Pattern]] · [[Error Handling Pattern]] · [[Architecture Separation Pattern]]
### AI
- [[RAG Pattern]] · [[Memory Pattern]] · [[Agent Orchestration Pattern]] · [[Reflection Pattern]] · [[Critic Pattern]] · [[Tool Calling Pattern]]
### Web
- [[JWT Authentication Pattern]] · [[Repository Pattern]] · [[API Client Pattern]] · [[React State Pattern]] · [[Infinite Scroll Pattern]] (캐싱은 [[Caching Pattern]])
### Mobile
- [[Offline Sync Pattern]] · [[Local Storage Pattern]] · [[Background Task Pattern]] · [[Push Notification Pattern]] · [[Navigation Pattern]]
### Desktop
- [[IPC Pattern]] · [[Plugin Architecture Pattern]] · [[Command Pattern]] · [[Event Bus Pattern]] · [[Background Worker Pattern]]
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
패턴은 *기본값* 이지 의무가 아니다. 적용 전 [[소프트웨어 실패 라이브러리]] 로 "이 패턴이 어떻게 깨지는가" 를 함께 확인하라.
## 🛠️ 적용 사례 (Applied in summary)
RAG/Memory/Agent Orchestration/Critic/Event Bus/Repository/Caching/API Client/IPC/Command/Plugin/Background Worker 는 ConnectAI 에 실제 구현되어 있어 코드 근거가 있다.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[Topic Programming 인덱스]]
- **관련 개념:** [[소프트웨어 실패 라이브러리]] · [[플랫폼 개발 가이드 인덱스]] · [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 작은 모델이 구현 시 "어떤 패턴을 쓸까" 를 고를 때의 카탈로그.
## 📚 출처 (Sources)
- [S1] Pattern_Catalog 전체 + 일반 소프트웨어 공학 지식 + ConnectAI 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 패턴 카탈로그 인덱스 생성.
@@ -0,0 +1,71 @@
---
id: pattern-agent-orchestration
title: "Agent Orchestration Pattern"
category: "Pattern_AI"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["Agent Orchestration", "에이전트 오케스트레이션 패턴", "multi-agent", "pipeline"]
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: ["pattern", "ai", "agent", "orchestration", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/agents/*, src/features/company/dispatcher.ts (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Agent Orchestration Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
에이전트 오케스트레이션은 "큰 작업을 단계/역할로 쪼개 LLM 을 여러 번 호출·조율" 하는 패턴이며, *에이전트 수를 늘리는 것 자체가 목적이 되면 실패* 한다 — 정보 손실과 자원을 먼저 따져라.
## 🧠 핵심 개념 (Core concepts)
1. **분해:** 작업 → 단계(outline/draft/polish) 또는 역할(planner/specialist/reporter).
2. **조율:** 흐름 골격이 호출 순서·데이터 전달을 관리.
3. **상태 전달:** 앞 단계 출력을 다음에 전달(peer-context), 단 손실 주의.
4. **자원 모델:** 병렬 vs 순차는 하드웨어가 결정.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 단일 호출로는 품질/길이/전문성이 부족한 복합 작업.
- **사용 조건:** 단계 분해가 명확; 단계 간 인터페이스 정의 가능; 자원이 선택한 동시성 모델을 감당.
- **장점:** 단계별 최적화, 긴 산출물, 역할 전문화, 검증 단계 삽입 용이.
- **단점:** 지연·비용 증가, hop 마다 컨텍스트 누적/원본 손실, 디버깅 복잡.
- **대안:** 단일 프롬프트(짧은 작업), 단일 작성자 다중 역할(자원 제약), 도구 호출.
- **실패 사례:** 에이전트 남발로 "방법론만 생성"; 병렬 다중 모델 상주 OOM; orchestrator 재비대.
## 💻 코드 패턴 (Code patterns)
```text
# 자원 제약: 순차 + 한 모델 상주
plan = planner(prompt)
peer = ""
for task in plan.tasks:
out = specialist(task, peer); persist(out); peer += truncate(out)
report = synthesizer(prompt, peer)
# 단일 작성자 다중 역할 (작은 모델 친화)
outline = M("outline", prompt); body = [M("section", o, source) for o in outline]; M("polish", body)
```
적용 예: [[Agent 오케스트레이터 분해]], [[AITRAIN 에이전트 오케스트레이션]], 결정 [[ADR-0003 단일작성자 다중역할 멀티에이전트]]·[[ADR-0004 순차 디스패치 채택]].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"멀티에이전트가 항상 낫다" 는 자원 제약 하에서 거짓 — 잘 만든 단일 작성자가 어설픈 병렬 파이프라인을 이긴다.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI company dispatcher(순차), ChunkedWriter(단일 다중역할).
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Reflection Pattern]], [[Critic Pattern]], [[Tool Calling Pattern]], [[Background Worker Pattern]]
- **참조 맥락:** 작은 모델이 복합 작업을 단계화할 때 과설계 회피와 함께 참조.
## 📚 출처 (Sources)
- [S1] 일반 멀티에이전트 지식
- [S2] ConnectAI/src/agents/*, features/company/dispatcher.ts — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,63 @@
---
id: pattern-critic
title: "Critic Pattern"
category: "Pattern_AI"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["Critic", "LLM judge", "검수자 패턴", "verifier"]
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: ["pattern", "ai", "critic", "verification", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/intelligence/criticAgent.ts (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Critic Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
Critic 패턴은 "별도의 검수자(보통 LLM)가 산출물을 비판적으로 평가" 하는 것으로, 생성자와 검수자를 분리하면 환각·누락을 잡지만 *검수 출력도 결국 LLM 이라 강건 파싱·근거 강제가 필수* 다.
## 🧠 핵심 개념 (Core concepts)
1. 생성자와 검수자 역할 분리. 2. 검수 기준 명시(요구 충족·근거·미결 구분·지어냄 금지). 3. 구조화 출력(JSON) + 강건 파싱. 4. 검수 결과를 보완 카드/재작성 입력으로.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 산출물의 사실성/완결성이 중요하고, 생성자 자체 점검만으론 부족할 때.
- **사용 조건:** 검수 기준을 명문화 가능; 검수 호출 비용 감당; 출력 파싱 방어.
- **장점:** 독립 시각으로 오류 포착, 근거 없는 단정 차단, 보완 제안.
- **단점:** 추가 LLM 비용, 검수자도 환각 가능, JSON 형식 위반.
- **대안:** 결정론 규칙 검증, 다수결(여러 검수자), 사람 검수.
- **실패 사례:** 검수자가 원문에 없는 내용을 "보완" 으로 지어냄; JSON.parse 직접 호출로 파싱 실패; 무조건 검수로 비용 폭증.
## 💻 코드 패턴 (Code patterns)
```text
critique = LLM_critic(system="검수자. 근거 없는 단정/지어냄은 major. JSON만 출력", user=task+draft)
result = parseBalancedJson(critique) or heuristicFallback() # 잡설 내성
if not result.pass: attach(footer(result.issues, result.supplement))
# 규칙: supplement 도 원문 근거 한정, 없으면 "(확인 필요)"
```
적용 예: [[Intelligence 검증 레이어]] 의 criticAgent(조건부 1-pass + 균형 괄호 파서), 결정 [[ADR-0009 결정론 항상 LLM검증 조건부]].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
검수자가 생성자보다 똑똑하지 않으면 효과가 제한적 — 작은 모델끼리는 *결정론 신호 + 근거 강제* 가 LLM-judge 보다 안정적일 수 있다.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI Critic(조건부), regression LLM-judge.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Reflection Pattern]], [[프롬프트 엔지니어링 패턴]], [[소프트웨어 실패 라이브러리]]
- **참조 맥락:** 작은 모델이 산출물 품질 게이트를 둘 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 LLM critic/judge 지식
- [S2] ConnectAI/src/intelligence/criticAgent.ts — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,63 @@
---
id: pattern-memory
title: "Memory Pattern"
category: "Pattern_AI"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["Memory Pattern", "에이전트 메모리 패턴", "agent memory"]
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: ["pattern", "ai", "memory", "agent", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/memory/* (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Memory Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
에이전트 메모리 패턴은 "대화/세션을 넘어 지식을 보존·회수" 하며, 단일 버퍼가 아니라 *수명·용도별 계층* 으로 나누고 관련도로 선별 주입할 때 작은 모델의 일관성이 크게 오른다.
## 🧠 핵심 개념 (Core concepts)
1. **단기:** 현재 대화(FIFO). 2. **장기:** 안정적 사실/선호(만료 가능). 3. **작업/프로젝트:** 작업 종속 지식. 4. **절차:** 반복 작업 방법. 5. **일화:** 과거 세션 요약. 회수 시 관련도순 선별.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 에이전트가 세션을 넘어 사용자/프로젝트를 기억해야 할 때, 컨텍스트 한도가 빠듯할 때.
- **사용 조건:** 영속 저장 가능; 관련도 점수화 가능; 무엇을 어느 계층에 넣을지 분류 규칙 존재.
- **장점:** 일관성·개인화, 컨텍스트 정밀 선별, 시한부/영구 공존, 자동 정리(증류).
- **단점:** 분류 결정 비용, 저장/검색 인프라, 잘못된 회수 시 노이즈.
- **대안:** 무상태(매번 새로), 전체 이력 투입(짧을 때), 외부 RAG 로만 대체.
- **실패 사례:** 만료 없는 영구 저장으로 옛 사실 재현; 관련도 오선별로 핵심 누락; 계층 경계 모호로 중복.
## 💻 코드 패턴 (Code patterns)
```text
buildContext(query):
layers = [shortTerm, longTerm(query), project(query), procedural(query), episodic(query)]
return sort_by_relevance(layers).join() # 빈 계층 제외
onSessionEnd(): extract -> persist -> distill(stale -> longterm digest)
```
적용 예: [[5계층 메모리 시스템]], [[AITRAIN 메모리 시스템]], 결정 [[ADR-0002 5계층 메모리 분리]].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
계층이 많을수록 표현력↑ 결정 비용↑ — 명확한 분류 규칙이 없으면 단순 3계층(작업/세션/영구)이 낫다.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI MemoryManager.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[RAG Pattern]], [[Local Storage Pattern]], [[Offline Sync Pattern]]
- **참조 맥락:** 작은 모델이 기억하는 에이전트를 만들 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 에이전트 메모리 지식
- [S2] ConnectAI/src/memory/* — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,66 @@
---
id: pattern-rag
title: "RAG Pattern"
category: "Pattern_AI"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["RAG", "Retrieval-Augmented Generation", "검색 증강 생성 패턴"]
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: ["pattern", "ai", "rag", "retrieval", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/retrieval/* (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[RAG Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
RAG 는 "모델이 답하기 전에 외부 지식에서 관련 조각을 검색해 프롬프트에 주입" 하는 패턴으로, 모델의 학습되지 않은/최신/사적 지식을 *재학습 없이* 활용하고 환각을 줄인다.
## 🧠 핵심 개념 (Core concepts)
1. **인덱싱:** 문서를 청크로 나눠 검색 인덱스(키워드/임베딩)에 저장.
2. **검색:** 질의로 top-k 관련 청크 회수(sparse/dense/하이브리드).
3. **증강:** 회수 청크를 컨텍스트로 프롬프트에 삽입(토큰 예산 내).
4. **생성:** 모델이 근거를 보고 답하고 출처를 인용.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 모델이 모르는 사적/최신/대용량 지식이 필요하고, 파인튜닝은 비싸거나 자주 바뀔 때. 출처 인용·환각 감소가 필요할 때.
- **사용 조건:** 검색 가능한 지식 베이스 존재; 청킹/인덱싱 가능; 컨텍스트 한도 내 주입 가능.
- **장점:** 재학습 불필요, 지식 즉시 갱신, 출처 추적, 환각↓, 작은 모델도 강화.
- **단점:** 검색 품질에 답이 좌우(garbage in), 인덱싱/저장 비용, 컨텍스트 토큰 소비, 청킹 경계 손실.
- **대안:** 파인튜닝(지식이 안정적·대규모일 때), 긴 컨텍스트에 전체 투입(소량일 때), 도구 호출로 실시간 조회.
- **실패 사례:** 청크가 너무 커 정밀도↓; 부분 정규화로 하이브리드 편향; 동의어 미확장으로 recall↓; stale 인덱스; 운영 로그를 지식으로 오염.
## 💻 코드 패턴 (Code patterns)
```text
index = chunk(docs) -> tokenize/embed -> store
query -> expand(synonyms) -> score(sparse + α·dense) -> normalize -> rerank
context = selectWithinTokenBudget(top_chunks)
answer = LLM(system + context + question) # "근거 없으면 모른다고"
```
적용 예: ConnectAI 의 [[RAG 검색 파이프라인]]·[[TF-IDF 이중언어 스코어링]] (하이브리드+섹션 청킹+토큰 예산).
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"임베딩만 쓰면 된다" 는 가용성·설명가능성을 잃는다 — 결정론(키워드) 바닥선 + 임베딩 가산이 견고([[ADR-0007 하이브리드 검색 결정론 우선]]).
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI 전체 검색이 이 패턴. → [[AITRAIN RAG 검색]].
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Memory Pattern]], [[Caching Pattern]], [[Tool Calling Pattern]], [[소프트웨어 실패 라이브러리]]
- **참조 맥락:** 작은 모델이 지식 기반 응답 시스템을 만들 때 1순위 패턴.
## 📚 출처 (Sources)
- [S1] 일반 RAG 공학 지식
- [S2] ConnectAI/src/retrieval/* — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,65 @@
---
id: pattern-reflection
title: "Reflection Pattern"
category: "Pattern_AI"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["Reflection", "자기성찰 패턴", "self-reflection", "self-critique"]
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: ["pattern", "ai", "reflection", "self-improvement", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/intelligence/*, src/features/selfReflector/* (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Reflection Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
Reflection 은 "모델이 자기 출력을 다시 점검·수정" 하는 패턴으로, 작은 모델의 1-pass 오류를 줄이지만 *호출이 늘어 비용/지연이 증가* 하므로 조건부로 써야 한다.
## 🧠 핵심 개념 (Core concepts)
1. **생성 → 점검 → (필요시) 재생성** 루프. 2. 점검은 *결정론 신호* 또는 *LLM 자기비판*. 3. 자기검토 지시를 시스템 프롬프트에 주입. 4. 무한 루프 방지(최대 라운드).
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 1-pass 정확도가 부족하고, 오류 비용이 재검토 비용보다 클 때.
- **사용 조건:** 점검 신호(규칙/요구사항/근거) 정의 가능; 추가 호출 latency 감당.
- **장점:** 정확도·완결성↑, 누락/모순 발견, 불확실성 표면화.
- **단점:** 지연·비용↑, 과도하면 헤지 남발, 무한 루프 위험.
- **대안:** 결정론 검증만(무LLM), 외부 검증기, 더 큰 모델 1-pass.
- **실패 사례:** 매 턴 무조건 reflect 로 latency 폭증; 자기비판이 오히려 정답을 망침; 종료 조건 없어 루프.
## 💻 코드 패턴 (Code patterns)
```text
draft = LLM(task)
signals = deterministicChecks(draft) # 커버리지/근거/확신도 — 항상(저비용)
if signals.risky: # 조건부로만 LLM 점검
issues = LLM_critique(task, draft)
if issues: draft = revise(draft, issues) # 최대 N라운드
emit(draft + confidence_footer)
```
적용 예: [[Intelligence 검증 레이어]] (사전 자기검토 블록 + 조건부 critic), 결정 [[ADR-0009 결정론 항상 LLM검증 조건부]].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"항상 성찰하면 좋다" 는 비용을 무시한 통념 — *위험 신호가 있을 때만* 깊은 성찰이 비용 대비 효과적.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI selfReflector + 조건부 Critic.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Critic Pattern]], [[Agent Orchestration Pattern]], [[프롬프트 엔지니어링 패턴]]
- **참조 맥락:** 작은 모델의 자기개선 루프 설계 시 참조.
## 📚 출처 (Sources)
- [S1] 일반 reflection/self-critique 지식
- [S2] ConnectAI/src/intelligence/*, features/selfReflector/* — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,65 @@
---
id: pattern-tool-calling
title: "Tool Calling Pattern"
category: "Pattern_AI"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["Tool Calling", "function calling", "도구 호출 패턴", "action tag"]
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: ["pattern", "ai", "tool-calling", "function-calling", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/agent/actions/* (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Tool Calling Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
Tool Calling 은 "모델이 자연어 대신 구조화된 호출(함수/태그)로 외부 도구를 실행" 하게 해 실제 행동(파일 생성·명령 실행·검색)을 가능케 하며, *모델 출력을 신뢰 경계로 보고 검증·승인* 하는 것이 안전의 핵심이다.
## 🧠 핵심 개념 (Core concepts)
1. 도구 스키마 정의(이름·인자). 2. 모델이 호출 의도를 구조화 출력(JSON function call 또는 `<action>` 태그). 3. 실행기가 파싱→검증→실행→결과 반환. 4. 위험 동작은 승인 게이트.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 모델이 텍스트를 넘어 *행동* 해야 할 때(파일/명령/API/검색).
- **사용 조건:** 도구 인터페이스 명확; 출력 파싱 가능; 권한/검증 체계.
- **장점:** 실제 작업 자동화, 결정론 도구로 환각 보완, 확장성(도구 추가).
- **단점:** 보안 위험(임의 명령), 파싱 실패, 잘못된 인자, 무한 호출.
- **대안:** 사람이 실행, 고정 워크플로(모델 미개입), 제한된 화이트리스트 액션.
- **실패 사례:** 모델 출력을 검증 없이 실행(주입 공격); 경로 미검증으로 임의 파일 접근; 승인 없는 파괴적 명령.
## 💻 코드 패턴 (Code patterns)
```text
output = LLM(system + tools_schema + task)
for call in parseToolCalls(output): # <create_file>, <run_command> ...
if !validate(call): skip/log
if dangerous(call): await approval() # 승인 게이트
result = execute(call) # 실행기로 라우팅
feed(result -> next turn)
```
적용 예: ConnectAI 의 action tag 실행기(src/agent/actions/*) + 승인 큐(approval) + 경로 검증(security.validatePath). 라우팅은 [[Agent 오케스트레이터 분해]] 참조.
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"모델이 시키는 대로 실행" 은 위험 — 모델 출력은 *신뢰되지 않은 입력* 으로 다뤄 검증·샌드박스·승인을 거쳐야 한다.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI action tags + approval gate + validatePath/sanitizeCommand.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Agent Orchestration Pattern]], [[API Client Pattern]], [[Command Pattern]], [[소프트웨어 실패 라이브러리]]
- **참조 맥락:** 작은 모델이 행동하는 에이전트를 만들 때 안전 경계와 함께 참조.
## 📚 출처 (Sources)
- [S1] 일반 function/tool calling 지식
- [S2] ConnectAI/src/agent/actions/*, security.ts — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,67 @@
---
id: pattern-architecture-separation
title: "Architecture Separation Pattern"
category: "Pattern_CrossCutting"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["layering", "아키텍처 분리", "관심사 분리", "separation of concerns", "layered architecture", "ports and adapters"]
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: ["pattern", "cross-cutting", "architecture", "layering", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src 구조 (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Architecture Separation Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
아키텍처 분리는 "**관심사를 계층/모듈로 나누고, 의존은 한 방향(안정적인 쪽으로)으로만 흐르게**" 하는 것으로, 플랫폼이 달라도 UI/도메인/인프라를 섞지 않는 것이 유지보수의 토대다.
## 🧠 핵심 개념 (Core concepts)
1. **계층:** 인프라(core) → 역량(lib/도메인 서비스) → 기능(features) → 조립(entry). 위가 아래에 의존.
2. **관심사 분리:** UI / 도메인 로직 / I/O 를 섞지 않는다.
3. **의존성 역전:** 도메인이 인프라 *인터페이스* 에 의존, 구현은 주입.
4. **경계(ports & adapters):** 외부(DB/API/UI)는 어댑터로, 핵심은 순수.
5. **단일 책임:** 한 모듈은 한 가지 변경 이유.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 코드가 커지며 UI/로직/I/O 가 엉켜 변경이 두려울 때.
- **사용 조건:** 책임 경계를 식별 가능; 인터페이스로 추상화 가능.
- **장점:** 변경 격리, 테스트성(핵심 순수), 교체 용이(어댑터), 병렬 작업.
- **단점:** 초기 보일러플레이트, 과한 계층은 오버헤드("얇은 래퍼 지옥").
- **대안:** 모놀리식 단순 구조(소규모), 수직 슬라이스(기능별 풀스택), 모듈러 모놀리스.
- **실패 사례:** UI 에 비즈니스 로직 혼입; 도메인이 DB/프레임워크에 직접 의존(교체 불가); 순환 의존; 계층 우회(아래가 위 호출).
## 💻 코드 패턴 (Code patterns)
```text
features/ -> lib/도메인서비스 -> core/인프라 # 단방향 의존
domain depends on interface (IRepo, IAIService) # 의존성 역전
adapter implements interface (FileRepo, AIService)
entrypoint wires them (composition root) # 조립은 한 곳
```
적용 예: ConnectAI 계층(core/lib/memory/retrieval/intelligence/features) + 인터페이스 서비스([[ConnectAI 아키텍처 개요]], [[의존성 주입과 서비스 인터페이스]], [[모듈 시스템과 프로젝트 구성]]).
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
계층이 많을수록 격리는 좋아지나 단순 변경도 여러 파일을 거친다 — 규모에 맞춰라. 흐름 가독성을 위해 *골격은 한 곳에* 남기는 절충도 유효([[ADR-0010 오케스트레이터 골격 모듈추출]]).
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI 전체 폴더 계층 + DI.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Repository Pattern]], [[Plugin Architecture Pattern]], [[Data Flow Pattern]], [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 작은 모델이 새 프로젝트의 폴더/계층 구조를 잡을 때 1차 원리.
## 📚 출처 (Sources)
- [S1] 일반 계층화/관심사 분리 지식(Clean/Hexagonal)
- [S2] ConnectAI/src 구조 — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,69 @@
---
id: pattern-async-concurrency
title: "Async Concurrency Pattern"
category: "Pattern_CrossCutting"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["async pattern", "비동기 패턴", "concurrency", "cancellation", "debounce", "throttle"]
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: ["pattern", "cross-cutting", "async", "concurrency", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/core/* (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Async Concurrency Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
비동기 처리는 모든 플랫폼이 공유하는 핵심이며, 안전의 3축은 "**취소 가능(cancellation) · 자원 폭주 방지(제한) · 경쟁 상태 제어(직렬화)**" 다 — UI 멈춤·메모리 폭주·갱신 손실이 여기서 갈린다.
## 🧠 핵심 개념 (Core concepts)
1. **취소:** AbortSignal/토큰으로 진행 중 작업 중단(타임아웃+사용자 취소 결합).
2. **동시성 제한:** 큐/세마포어로 동시 실행 수 상한.
3. **직렬화:** 공유 자원은 락/뮤텍스로 한 번에 하나.
4. **debounce/throttle:** 빈번 이벤트(입력/스크롤)를 솎아냄.
5. **병렬 vs 순차:** 독립이면 병렬(all), 의존이면 순차, 부분실패 허용이면 allSettled.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** I/O·네트워크·장시간 작업이 UI/자원에 영향 줄 때.
- **사용 조건:** 취소 신호 전파 가능; 작업 단위 분리 가능.
- **장점:** 반응성 유지, 자원 안정, 데이터 일관.
- **단점:** 복잡도↑, 콜백/Promise 추론 어려움, 취소 누락 시 좀비 작업.
- **대안:** 동기(작은 작업), 워커/스레드(CPU 바운드), 큐 시스템(분산).
- **실패 사례:** 취소 미전파로 좀비 fetch; Promise.all 부분 실패로 전체 손실; 무한 병렬 OOM; 락 미해제 데드락; forEach+async 로 미대기.
## 💻 코드 패턴 (Code patterns)
```text
signal = combine(userAbort, timeout(ms)) # 취소 = 사용자 OR 타임아웃
await fetch(url, { signal })
await queue.enqueue(task) # 동시성 상한
release = await lock.acquire(id); try{...} finally{ release() } # 직렬화
onInput = debounce(handler, 200) # 이벤트 솎기
results = await Promise.allSettled(tasks) # 부분 실패 허용
```
적용 예: [[비동기 프로그래밍 Promise async await]], [[동시성 제어 Lock Queue Transaction]], [[AITRAIN 동시성 제어]].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"병렬이 빠르다" 는 자원 한도 내에서만 참 — 한도를 넘으면 스왑/OOM 으로 더 느려진다([[ADR-0004 순차 디스패치 채택]]).
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI services(AbortSignal), lock/queue.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Background Worker Pattern]], [[Background Task Pattern]], [[Error Handling Pattern]]
- **참조 맥락:** 작은 모델이 어떤 플랫폼이든 비동기 코드를 쓸 때 1차 원리.
## 📚 출처 (Sources)
- [S1] 일반 비동기/동시성 지식
- [S2] ConnectAI/src/core/services.ts, lock.ts, queue.ts — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,69 @@
---
id: pattern-caching
title: "Caching Pattern"
category: "Pattern_CrossCutting"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["caching", "캐싱", "memoization", "TTL", "invalidation", "mtime cache"]
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: ["pattern", "cross-cutting", "caching", "performance", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/retrieval/scoring.ts, src/lib/mtimeFileCache.ts (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Caching Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
캐싱은 "비싼 계산/조회 결과를 저장해 재사용" 하는 보편 최적화이며, 어려운 것은 캐싱 자체가 아니라 "**언제 무효화(invalidation)하느냐**" 다 — stale 데이터는 성능보다 더 큰 버그를 만든다.
## 🧠 핵심 개념 (Core concepts)
1. **memoization:** 같은 입력→같은 출력을 키로 저장.
2. **무효화 전략:** TTL(시간), 버전/해시, 변경 감지(mtime), 수동.
3. **캐시 키 설계:** 입력을 정확히 식별(누락 시 잘못된 hit).
4. **용량 제한:** LRU/상한으로 무한 증가 방지.
5. **계층:** 메모리→디스크→원격, 가까울수록 빠름.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 동일 계산/조회가 반복되고 비용이 클 때, 결과가 자주 안 바뀔 때.
- **사용 조건:** 결정적 입력→출력; 무효화 신호 존재; 메모리/디스크 여유.
- **장점:** 지연·비용 대폭↓, 부하 완화.
- **단점:** stale 위험, 메모리 사용, 무효화 복잡, 캐시 키 버그.
- **대안:** 매번 계산(정확성 우선), 사전 계산(배치), 증분 갱신.
- **실패 사례:** 무효화 누락으로 옛 데이터 제공; 키 충돌로 잘못된 hit; 무한 증가 OOM; 변경 감지 누락(mtime 미갱신).
## 💻 코드 패턴 (Code patterns)
```text
# memoization + 용량 제한
if cache.has(key): return cache.get(key)
val = expensive(input); if cache.size >= LIMIT: cache.clear(); cache.set(key, val)
# 변경 감지 무효화 (파일)
if file.mtime != cached.mtime: cached = reindex(file) # 변경된 파일만 재계산
```
적용 예: ConnectAI 의 TOKEN_CACHE(토크나이저 memoization, 상한 시 clear) + mtime 키 brain 인덱스(변경 없는 파일 재토큰화 회피) [S2]. RAG 의 dense/sparse 인덱스도 캐시.
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"캐시하면 빠르다" 의 이면은 "무효화를 틀리면 조용히 틀린 답" — Phil Karlton 의 "캐시 무효화는 컴퓨터 과학의 2대 난제". 변경 감지(mtime/해시)가 TTL 보다 정확할 때가 많다.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI 토큰 캐시 + mtime 인덱스([[TF-IDF 이중언어 스코어링]], [[RAG 검색 파이프라인]]).
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Local Storage Pattern]], [[API Client Pattern]], [[RAG Pattern]], [[소프트웨어 실패 라이브러리]]
- **참조 맥락:** 작은 모델이 성능 최적화를 할 때 무효화 전략과 함께 참조.
## 📚 출처 (Sources)
- [S1] 일반 캐싱 공학 지식
- [S2] ConnectAI/src/retrieval/scoring.ts(TOKEN_CACHE), brainIndex/mtimeFileCache — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,66 @@
---
id: pattern-data-flow
title: "Data Flow Pattern"
category: "Pattern_CrossCutting"
status: "draft"
verification_status: "conceptual"
canonical_id: ""
aliases: ["data flow", "데이터 흐름", "pipeline", "transform", "boundary normalization"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.86
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "cross-cutting", "data-flow", "pipeline", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/retrieval/*, src/features/providers/* (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Data Flow Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
데이터 흐름 설계의 핵심은 "**경계에서 정규화하고(입력 검증·형식 통일), 내부는 단일 형태로 다루며, 변환을 작은 순수 단계의 파이프라인으로**" 만드는 것이다 — 그러면 어디서 무엇이 변하는지 추적된다.
## 🧠 핵심 개념 (Core concepts)
1. **경계 정규화:** 외부 입력(API/파일/사용자)을 들어오자마자 내부 표준 형태로 변환·검증.
2. **단일 내부 모델:** 내부는 하나의 형태만 — 분기/특수처리를 가장자리로.
3. **파이프라인:** 변환을 작은 순수 단계로 연결(test 가능).
4. **출력 정규화:** 다양한 백엔드를 같은 출력 형식으로(예: SSE).
5. **불변 전달:** 단계 간 데이터를 변형 대신 새 값 생성.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 이질적 소스/싱크가 많고 변환 단계가 여러 개일 때.
- **사용 조건:** 표준 내부 모델 정의 가능; 단계 분해 가능.
- **장점:** 추적성, 테스트성(순수 단계), 소스/싱크 추가 용이, 버그 격리.
- **단점:** 변환 레이어 비용, 과한 추상화는 오버헤드.
- **대안:** 직접 결합(소규모), 스트림 처리(대용량), 이벤트 버스(느슨 결합).
- **실패 사례:** 경계 검증 누락으로 내부에 오염 전파; 내부에 외부 형식 누수(공급자별 분기 산재); 가변 전달로 단계 간 부작용.
## 💻 코드 패턴 (Code patterns)
```text
internal = normalizeAtBoundary(externalInput) # 들어올 때 1회 정규화 + 검증
result = stage3(stage2(stage1(internal))) # 작은 순수 단계 파이프라인
output = toStandardFormat(result) # 나갈 때 형식 통일 (예: SSE)
```
적용 예: [[LLM 프로바이더 추상화]](공급자별 입력 정규화→공통 SSE 출력), [[RAG 검색 파이프라인]](tokenize→score→fuse→budget).
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
경계 정규화는 비용이지만, 생략하면 특수처리가 코드 전체로 번진다 — "차이는 가장자리에서 흡수" 원칙([[AITRAIN 프로바이더 추상화]]).
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI provider 어댑터, retrieval 파이프라인.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[State Management Pattern]], [[Repository Pattern]], [[API Client Pattern]], [[Architecture Separation Pattern]]
- **참조 맥락:** 작은 모델이 입출력 변환이 많은 코드를 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 데이터 흐름/파이프라인 지식
- [S2] ConnectAI/src/retrieval/*, features/providers/* — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,68 @@
---
id: pattern-error-handling
title: "Error Handling Pattern"
category: "Pattern_CrossCutting"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["error handling", "오류 처리 패턴", "graceful degradation", "result type", "retry", "fallback"]
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: ["pattern", "cross-cutting", "error-handling", "resilience", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/core/* (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Error Handling Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
견고한 오류 처리는 "**실패를 분류하고(복구 가능/불가), 흔한 실패는 결과값으로·예외는 진짜 예외에, 부가 작업 실패는 본류를 막지 않게, 사용자에겐 행동 지침으로 번역**" 하는 것이다.
## 🧠 핵심 개념 (Core concepts)
1. **분류:** 복구 가능(재시도/폴백) vs 불가(즉시 실패) vs 부가(무시).
2. **결과 타입 vs 예외:** 흔한 실패는 `{ok,error}` 유니온, 계약 위반은 throw.
3. **재시도/폴백:** 일시 오류는 backoff 재시도, 대안 경로 폴백.
4. **graceful degradation:** 핵심은 살리고 부가만 끈다(이유 주석 필수).
5. **사용자 번역:** 기술 에러→무엇을 하면 되는지.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** I/O·네트워크·외부 의존이 있는 모든 코드.
- **사용 조건:** 실패 유형을 구분 가능; 복구/대안 전략 존재.
- **장점:** 복원력, 디버깅 용이, UX 개선, 부분 장애 격리.
- **단점:** 코드량↑, 잘못된 삼킴은 버그 은폐.
- **대안:** 크래시-온리(빠른 실패+재시작), 서킷 브레이커(연속 실패 차단).
- **실패 사례:** 무음 빈 catch 로 실패 은폐; `||` 로 0/'' 삼킴; 무한 재시도; 사용자에게 raw 스택 노출; 부가 실패가 본류 중단.
## 💻 코드 패턴 (Code patterns)
```text
result = op() -> { ok:true, val } | { ok:false, error } # 흔한 실패는 유니온
for engine in engines: try { return call(engine) } catch { last=e } # 폴백
try { sideEffect() } catch { /* 부가 — 본류 안 막음(이유 주석) */ }
showUser(translate(error)) # 행동 지침으로 번역
catch (e) { err = e instanceof Error ? e : new Error(String(e)) } # 정규화
```
적용 예: [[에러 처리와 커스텀 에러]](G1Error 계층, ErrorTranslator, 보상 트랜잭션), [[LLM 프로바이더 추상화]](엔진 폴백).
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"모든 에러를 잡아라" 와 "빠르게 실패하라" 의 균형 — 복구 불가·계약 위반은 던지고, 일시·부가만 흡수. 빈 catch 는 *부가 작업 + 이유 주석* 일 때만.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI errors/errorHandler/transaction/services.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Async Concurrency Pattern]], [[API Client Pattern]], [[소프트웨어 실패 라이브러리]], [[안티패턴 카탈로그]]
- **참조 맥락:** 작은 모델이 어떤 플랫폼이든 실패 경로를 작성할 때 1차 원리.
## 📚 출처 (Sources)
- [S1] 일반 오류 처리/복원력 지식
- [S2] ConnectAI/src/core/errors.ts, errorHandler.ts, transaction.ts, services.ts — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,67 @@
---
id: pattern-state-management
title: "State Management Pattern"
category: "Pattern_CrossCutting"
status: "draft"
verification_status: "conceptual"
canonical_id: ""
aliases: ["state management", "상태 관리", "single source of truth", "unidirectional data flow"]
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: ["pattern", "cross-cutting", "state", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/sidebar/managers/* (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[State Management Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
상태 관리의 본질은 플랫폼(웹/모바일/데스크탑)을 막론하고 "**단일 진실 원천(Single Source of Truth) + 단방향 데이터 흐름 + 명시적 변경**" 으로, 상태가 흩어지고 양방향으로 얽힐수록 버그가 기하급수로 는다.
## 🧠 핵심 개념 (Core concepts)
1. **Single Source of Truth:** 같은 데이터를 한 곳에만 둔다(중복 상태 = 동기화 버그).
2. **단방향 흐름:** 상태→뷰 렌더, 이벤트→상태 변경(역류 금지).
3. **파생 상태 vs 원천 상태:** 계산 가능한 건 저장하지 말고 derive.
4. **로컬 vs 전역:** 한 컴포넌트만 쓰면 로컬, 여러 곳이 공유하면 전역(끌어올림).
5. **불변 업데이트:** 상태를 *교체* 로 갱신해 변경 추적/되돌리기 용이.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** UI/세션/도메인 상태가 여러 곳에서 읽고 쓰일 때.
- **사용 조건:** 상태 소유자를 정할 수 있을 때; 변경 경로를 한정할 수 있을 때.
- **장점:** 예측 가능, 디버깅 용이(변경 추적), 동기화 버그↓, 테스트 용이.
- **단점:** 보일러플레이트, 과한 전역화는 결합↑, 작은 앱엔 과설계.
- **대안:** 로컬 상태만(소규모), 서버 상태를 진실로(react-query류), 이벤트 소싱(이력 필요 시).
- **실패 사례:** 같은 데이터를 두 곳에 저장→불일치; 파생값을 저장→stale; 컴포넌트가 부모 상태 직접 변경(역류); 전역 store 에 모든 걸 넣어 결합 폭증.
## 💻 코드 패턴 (Code patterns)
```text
state = SingleStore(initial)
view = render(state) # 상태 → 뷰
onEvent(e): state = reducer(state, e) # 이벤트 → 새 상태(불변 교체) → 재렌더
derived = useMemo(() => compute(state))# 파생은 저장 말고 계산
```
적용 예: ConnectAI 의 sessionStateStore/chatSessionStore 등 manager 가 상태 소유, webview 는 메시지로만 변경 요청([[VSCode 확장 구조와 생명주기]]).
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
전역 상태 라이브러리(Redux 등)가 항상 답은 아니다 — 서버 상태는 캐시 라이브러리에, UI 지역 상태는 로컬에, 진짜 공유 도메인 상태만 전역에.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI sidebar managers(상태 소유 + 메시지 변경).
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Data Flow Pattern]], [[React State Pattern]], [[Caching Pattern]], [[프로젝트 독립 설계 원칙]]
- **참조 맥락:** 작은 모델이 어떤 플랫폼이든 UI/앱 상태를 설계할 때 1차 원리.
## 📚 출처 (Sources)
- [S1] 일반 상태 관리 공학 지식
- [S2] ConnectAI/src/sidebar/managers/* — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,68 @@
---
id: pattern-background-worker
title: "Background Worker Pattern"
category: "Pattern_Desktop"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["background worker", "백그라운드 워커", "worker thread", "job queue", "concurrency limit"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.86
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "desktop", "worker", "queue", "concurrency", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/core/queue.ts (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Background Worker Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
Background Worker 는 "무거운/장시간 작업을 메인(UI) 흐름 밖에서, *동시성 상한이 있는 큐* 로 처리" 해 UI 멈춤과 자원 폭주를 동시에 막는 패턴이다.
## 🧠 핵심 개념 (Core concepts)
1. **작업 큐:** 작업을 enqueue, 워커가 꺼내 실행.
2. **동시성 상한:** 동시에 N개만(CPU/메모리 보호).
3. **UI 분리:** CPU 바운드는 워커 스레드, I/O 는 비동기.
4. **결과 반환:** 작업별 Promise/콜백으로 결과 전달.
5. **백프레셔:** 큐가 넘치면 거부/지연.
## 📖 세부 내용 (Details · 패턴 명세)
- **언제 쓰나:** 대량/무거운 작업이 UI 반응성·자원을 위협할 때.
- **사용 조건:** 작업 단위 분리; 동시성 정책; 결과 전달 경로.
- **장점:** UI 반응성, 자원 안정(상한), 처리량 제어.
- **단점:** 복잡도, 결과 동기화, 스레드 통신 비용(CPU 바운드 시).
- **대안:** 동기 처리(소규모), 외부 잡 시스템(분산), OS 스케줄러.
- **실패 사례:** 무한 병렬 OOM; 큐 무한 증가(백프레셔 없음); 워커 예외 미처리로 멈춤; UI 스레드에서 무거운 작업.
## 💻 코드 패턴 (Code patterns)
```text
class Queue {
enqueue(task): Promise = new Promise((res,rej)=>{ this.q.push(()=>task().then(res,rej)); this.next() })
next(): if (active < limit && q.length) { active++; run(q.shift()).finally(()=>{active--; next()}) }
}
limit = max(2, cpus-1) # UI 코어 여유
```
적용 예: ConnectAI 의 ActionQueueManager(동시성 `max(2,cpus-1)`, micro-delay 로 숨통) [S2]. 무거운 LLM 작업은 큐 대신 missionId 락으로 직렬화([[동시성 제어 Lock Queue Transaction]]).
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
동시성은 처리량을 올리지만 자원을 넘으면 역효과 — 상한은 *하드웨어 기준*([[ADR-0004 순차 디스패치 채택]]). 메모리 큰 작업(모델)은 병렬보다 순차가 안전.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI actionQueue + 워처.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Async Concurrency Pattern]], [[Background Task Pattern]], [[AITRAIN 동시성 제어]], [[데스크탑 앱 개발 가이드]]
- **참조 맥락:** 작은 모델이 무거운 작업을 백그라운드로 뺄 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 워커/잡 큐 지식
- [S2] ConnectAI/src/core/queue.ts — ActionQueueManager
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,67 @@
---
id: pattern-command
title: "Command Pattern"
category: "Pattern_Desktop"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["command pattern", "커맨드 패턴", "command registry", "undo redo", "action"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.86
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "desktop", "command", "behavioral", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/extension.ts(registerCommand), src/agent/actions/* (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Command Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
Command 패턴은 "요청(동작)을 객체/등록 항목으로 캡슐화" 해 실행을 호출자와 분리하고, 등록·취소(undo)·큐잉·로깅·단축키 매핑을 일관되게 만든다.
## 🧠 핵심 개념 (Core concepts)
1. **명령 캡슐화:** 동작을 id+핸들러로 등록.
2. **레지스트리:** id→핸들러 매핑(중앙 디스패치).
3. **undo/redo:** 명령에 역연산 정의(선택).
4. **메타데이터:** 단축키·메뉴·가시성 조건.
5. **분리:** UI(버튼/메뉴)는 명령 id 만 알면 됨.
## 📖 세부 내용 (Details · 패턴 명세)
- **언제 쓰나:** 여러 진입점(메뉴/단축키/팔레트)이 같은 동작을 부를 때, undo/매크로/큐가 필요할 때.
- **사용 조건:** 동작을 id 로 표현; 핸들러 등록 메커니즘.
- **장점:** 호출자-실행자 분리, 재사용, undo/큐/로깅 일관, 확장 용이.
- **단점:** 명령 폭증, 단순 동작엔 과설계, 상태 전달 설계 필요.
- **대안:** 직접 함수 호출(소규모), 이벤트(반응형).
- **실패 사례:** 명령에 무거운 상태 결합; undo 불완전(부분 복원); id 충돌; 등록 해제 누락.
## 💻 코드 패턴 (Code patterns)
```text
registry.register('app.save', () => save()) # 명령 = id + 핸들러
ui.button(onClick = () => exec('app.save')) # UI 는 id 만
shortcut('Ctrl+S' -> 'app.save') # 매핑 일관
# undo 지원 시: command = { do(), undo() }; history.push(command)
```
적용 예: ConnectAI 의 `vscode.commands.registerCommand('g1nation.openChat', ...)` (명령 레지스트리)와 action tag 실행기(`<create_file>` 등을 명령처럼 라우팅) [S2]. → [[Tool Calling Pattern]].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
진입점이 하나면 함수 호출이 단순 — 다중 진입점/undo/큐가 필요할 때 Command 가 값을 한다.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI VS Code 명령 등록 + action 실행기.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Event Bus Pattern]], [[Tool Calling Pattern]], [[Plugin Architecture Pattern]], [[데스크탑 앱 개발 가이드]]
- **참조 맥락:** 작은 모델이 다중 진입점/undo 동작을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 Command 패턴(GoF) 지식
- [S2] ConnectAI/src/extension.ts(registerCommand), agent/actions/* — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,67 @@
---
id: pattern-event-bus
title: "Event Bus Pattern"
category: "Pattern_Desktop"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["event bus", "이벤트 버스", "observer", "pub-sub", "EventEmitter", "발행 구독"]
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: ["pattern", "desktop", "event-bus", "pub-sub", "decoupling", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/core/events.ts (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Event Bus Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
Event Bus(발행-구독)는 "발신자와 수신자가 서로를 모른 채 이벤트로 소통" 해 모듈 결합을 낮추는 패턴 — 단, 흐름이 *암묵적* 이 되어 추적이 어려워지므로 이벤트 종류와 계약을 명시해야 한다.
## 🧠 핵심 개념 (Core concepts)
1. **발행/구독:** emit(event) / on(event, handler).
2. **느슨한 결합:** 발신자는 누가 듣는지 모름.
3. **이벤트 타입 명시:** enum/상수로 이벤트 카탈로그.
4. **리스너 수명:** 등록 해제(누수 방지), 최대 리스너 한도.
5. **동기 vs 비동기:** 핸들러 예외가 발신자에 새지 않게.
## 📖 세부 내용 (Details · 패턴 명세)
- **언제 쓰나:** 한 사건에 여러 관심사가 반응(로깅·UI·기록), 모듈을 직접 의존시키고 싶지 않을 때.
- **사용 조건:** 이벤트 카탈로그 정의; 리스너 수명 관리.
- **장점:** 결합도↓, 확장 용이(구독 추가), 관심사 분리.
- **단점:** 흐름 암묵적(추적 난해), 디버깅 어려움, 이벤트 폭발, 순서 보장 약함.
- **대안:** 직접 호출(흐름 명확, 결합↑), 콜백 주입, 상태 구독(reactive).
- **실패 사례:** 리스너 해제 누락→누수·중복 실행; 이벤트 이름 오타(문자열); 핸들러 예외가 발신자 중단; "누가 이 이벤트를 듣나" 추적 불가; 이벤트 순환.
## 💻 코드 패턴 (Code patterns)
```text
enum E { TASK_STARTED='task:started', ERROR='error:occurred' } # 카탈로그
bus.emit(E.TASK_STARTED, payload) # 발신자: 누가 듣는지 모름
bus.on(E.TASK_STARTED, h); // ... bus.off(E.TASK_STARTED, h) # 해제로 누수 방지
bus.setMaxListeners(20) # 폭발 방지
```
적용 예: ConnectAI 의 `agentEvents`(싱글톤 EventEmitter)와 `AgentEventTypes` enum — 트랜잭션 commit/rollback, task 시작/완료 등을 발행해 모듈 결합을 낮춤 [S2].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
이벤트 버스는 결합을 낮추지만 *흐름을 숨긴다* — 핵심 제어 흐름은 명시 호출이 낫고, 부가/횡단 반응(로깅·기록)에 이벤트가 적합.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI agentEvents(Observer 허브).
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Command Pattern]], [[IPC Pattern]], [[Architecture Separation Pattern]], [[데스크탑 앱 개발 가이드]]
- **참조 맥락:** 작은 모델이 모듈 간 느슨한 통신을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 pub-sub/observer 지식
- [S2] ConnectAI/src/core/events.ts — agentEvents/AgentEventTypes
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,69 @@
---
id: pattern-ipc
title: "IPC Pattern"
category: "Pattern_Desktop"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["IPC", "프로세스 간 통신", "inter-process communication", "message passing", "bridge"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.86
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "desktop", "ipc", "messaging", "platform-independent"]
raw_sources: ["일반 데스크탑 공학 지식", "ConnectAI/src/bridge.ts, sidebarProvider.ts (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[IPC Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
IPC 는 "서로 다른 프로세스(메인↔렌더러, 앱↔외부 도구)가 메시지로 소통" 하는 패턴으로, *직렬화 가능한 메시지 계약 + 신뢰 경계 검증* 이 핵심 — 다른 프로세스의 입력은 신뢰되지 않은 입력이다.
## 🧠 핵심 개념 (Core concepts)
1. **메시지 패싱:** 객체 직접 공유 불가 → 직렬화(JSON)해 전달.
2. **채널/타입:** 메시지에 type 을 두고 핸들러로 라우팅.
3. **요청-응답 vs 단방향:** 명령은 응답, 알림은 단방향.
4. **신뢰 경계:** 상대 프로세스 입력을 검증(특히 외부 도구).
5. **전송 매체:** Electron ipcMain/Renderer, 웹뷰 postMessage, 로컬 HTTP/소켓.
## 📖 세부 내용 (Details · 패턴 명세)
- **언제 쓰나:** UI 프로세스↔백그라운드, 앱↔외부 프로그램 통신.
- **사용 조건:** 직렬화 가능 메시지; 채널 정의; 보안 검증.
- **장점:** 프로세스 격리(크래시 격리·보안), 언어/도구 무관 연동.
- **단점:** 직렬화 비용, 객체 공유 불가, 비동기 복잡, 보안 표면.
- **대안:** 단일 프로세스(스레드/공유 메모리), 파일 교환, 메시지 큐.
- **실패 사례:** 외부 입력 미검증→임의 명령 실행; 함수/순환 객체 직렬화 실패; 채널 타입 오타; 응답 누락으로 행; 포트 충돌.
## 💻 코드 패턴 (Code patterns)
```text
# 웹뷰(렌더러) ↔ 확장(메인): postMessage 프로토콜
webview.postMessage({ type:'streamChunk', value }) # 확장 → UI
onMessage(msg): route(msg.type, validate(msg)) # UI → 확장
# 앱 ↔ 외부 도구: 로컬 HTTP 브리지
http.createServer((req,res) => { body=validate(parse(req)); res.end(handle(body)) })
```
적용 예: ConnectAI 의 BridgeServer(로컬 HTTP 포트 4825 로 외부 도구↔확장 연결, 서비스 레이어로 로직 분리) + 웹뷰 postMessage 프로토콜([[VSCode 확장 구조와 생명주기]], [[Agent 오케스트레이터 분해]]) [S2].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
프로세스 분리는 격리·보안 이득이 있으나 직렬화·복잡도 비용 — 같은 신뢰 영역의 작은 작업이면 단일 프로세스가 단순. 외부 IPC 는 *항상* 입력 검증.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI BridgeServer + 웹뷰 메시지.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Event Bus Pattern]], [[Tool Calling Pattern]], [[API Client Pattern]], [[데스크탑 앱 개발 가이드]]
- **참조 맥락:** 작은 모델이 데스크탑(Electron/확장) 프로세스 통신을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 IPC 지식(Electron, message passing)
- [S2] ConnectAI/src/bridge.ts, sidebarProvider.ts — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,70 @@
---
id: pattern-plugin-architecture
title: "Plugin Architecture Pattern"
category: "Pattern_Desktop"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["plugin architecture", "플러그인 아키텍처", "extension point", "self-registration", "skill loader"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.85
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "desktop", "plugin", "extensibility", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/skills/externalSkillLoader.ts, src/features/*/handlers.ts (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Plugin Architecture Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
플러그인 아키텍처는 "코어를 안정적으로 두고 기능을 *확장 지점(extension point)* 으로 끼워 넣게" 해 코어 수정 없이 능력을 늘리는 패턴 — 핵심은 *안정된 계약(인터페이스)**자기 등록* 이다.
## 🧠 핵심 개념 (Core concepts)
1. **확장 지점:** 코어가 정의한 인터페이스/훅.
2. **자기 등록:** 플러그인 로드 시 레지스트리에 자기를 등록(side-effect import).
3. **발견(discovery):** 디렉터리/매니페스트 스캔으로 동적 로드.
4. **격리/검증:** 플러그인 실패가 코어를 죽이지 않게.
5. **버전 계약:** 코어 API 버전 호환.
## 📖 세부 내용 (Details · 패턴 명세)
- **언제 쓰나:** 서드파티/도메인 기능을 코어 변경 없이 추가, 기능 on/off, 생태계 구축.
- **사용 조건:** 안정된 확장 인터페이스; 로딩/등록 메커니즘; 격리.
- **장점:** 확장성, 코어 안정, 병렬 개발, 선택적 기능.
- **단점:** 인터페이스 설계 어려움, 버전 호환 부담, 플러그인 품질/보안 위험.
- **대안:** 모놀리식(소규모), 설정 플래그, 마이크로서비스.
- **실패 사례:** 플러그인 예외가 코어 크래시(격리 부재); 안정 안 된 API 로 잦은 호환 깨짐; 등록 순서 의존; 신뢰 안 된 플러그인 권한 과다.
## 💻 코드 패턴 (Code patterns)
```text
# 자기 등록 (side-effect import)
import './features/system/handlers' # 로드되며 registry.register(...) 실행
registry.register('cmd:foo', handler)
# 동적 발견
for file in scan(pluginsDir): plugin = load(file); if validate(plugin): register(plugin)
try { plugin.run() } catch { /* 격리 — 코어 보호 */ logError() }
```
적용 예: ConnectAI 의 핸들러 자기등록(`import './features/.../handlers'` 가 slashRouter 에 등록)과 externalSkillLoader(외부 스킬 동적 로드) [S2]. → [[모듈 시스템과 프로젝트 구성]].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
플러그인은 유연하나 *안정된 계약* 없이는 버전 지옥. 확장 지점을 최소·신중히 설계하고, 신뢰 안 된 플러그인은 샌드박스/권한 제한.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI 핸들러 자기등록 + 스킬 로더.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Command Pattern]], [[Event Bus Pattern]], [[Architecture Separation Pattern]], [[데스크탑 앱 개발 가이드]]
- **참조 맥락:** 작은 모델이 확장 가능한 앱(에디터/IDE/툴)을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 플러그인/확장 아키텍처 지식
- [S2] ConnectAI/src/skills/externalSkillLoader.ts, features/*/handlers.ts — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,68 @@
---
id: pattern-background-task
title: "Background Task Pattern"
category: "Pattern_Mobile"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["background task", "백그라운드 작업", "scheduled job", "watcher", "cron", "WorkManager"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.86
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "mobile", "background", "scheduling", "platform-independent"]
raw_sources: ["일반 모바일/클라이언트 공학 지식", "ConnectAI/src/features/*/watcher, src/extension.ts (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Background Task Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
백그라운드 작업은 "사용자 상호작용 밖에서 주기적/지연 작업을 실행" 하는 패턴으로, OS 제약(배터리/킬)과 *재진입·중복 실행 방지*를 고려하지 않으면 자원을 낭비하거나 데이터를 손상시킨다.
## 🧠 핵심 개념 (Core concepts)
1. **스케줄링:** interval/cron/조건(충전 중·Wi-Fi) 트리거.
2. **수명관리:** 등록한 작업은 dispose 가능해야(누수 방지).
3. **재진입 방지:** 이전 실행이 안 끝났으면 skip/큐.
4. **멱등성:** 중복 실행에도 안전.
5. **OS 제약:** 모바일은 OS 가 백그라운드를 제한(WorkManager/BGTask).
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 동기화/정리/알림/사전계산을 사용자 흐름 밖에서.
- **사용 조건:** 스케줄러; 작업을 작게 분할; 취소/정리 가능.
- **장점:** 응답성(무거운 일을 뒤로), 자동화, 유휴 활용.
- **단점:** 디버깅 난해, OS 킬/제약, 중복/경쟁 위험.
- **대안:** 포그라운드 처리, 서버측 작업(클라 부담↓), 푸시 트리거.
- **실패 사례:** dispose 누락으로 타이머 누수; 재진입으로 중복 실행; 무거운 작업을 메인 스레드; OS 제약 무시로 실행 안 됨; 실패 무한 재시도.
## 💻 코드 패턴 (Code patterns)
```text
const handle = scheduleInterval(ms, async () => {
if (running) return; running = true # 재진입 방지
try { await doWork() /*멱등, 작게*/ } finally { running = false }
})
register(handle) # dispose 가능하게 등록 → 종료 시 정리
```
적용 예: ConnectAI 의 stocksWatcher/dailyBriefing/growthCycle/sleepDigest 워처가 interval 로 돌고 disposable 을 `context.subscriptions` 에 등록해 종료 시 정리([[VSCode 확장 구조와 생명주기]]).
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
모바일에선 OS 가 백그라운드를 강하게 제한 — "정확한 시각 보장" 을 가정하면 깨진다. 중요 작업은 서버 푸시로 트리거하는 것이 안전.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI 워처들(KST 스케줄, dispose 등록).
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Background Worker Pattern]], [[Async Concurrency Pattern]], [[Push Notification Pattern]], [[모바일 개발 가이드]]
- **참조 맥락:** 작은 모델이 주기/지연 작업을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 백그라운드 작업 지식(WorkManager/BGTaskScheduler)
- [S2] ConnectAI/src/features/*/watcher, extension.ts — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,68 @@
---
id: pattern-local-storage
title: "Local Storage Pattern"
category: "Pattern_Mobile"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["local storage", "로컬 저장 패턴", "key-value", "sqlite", "secure storage"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.86
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "mobile", "storage", "persistence", "platform-independent"]
raw_sources: ["일반 모바일/클라이언트 공학 지식", "ConnectAI/src/core/services.ts, eventSourcedStore.ts (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Local Storage Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
로컬 저장은 "데이터 성격에 맞는 매체를 고르는 것" 이 핵심 — 소량 설정은 key-value, 구조화 데이터는 SQLite, 민감정보는 보안 저장소, 대용량 파일은 파일시스템. 한 매체에 다 넣으면 성능·보안이 무너진다.
## 🧠 핵심 개념 (Core concepts)
1. **key-value(prefs):** 작은 설정/플래그.
2. **임베디드 DB(SQLite/Realm):** 구조화/쿼리 데이터.
3. **보안 저장소(Keychain/Keystore):** 토큰/비밀.
4. **파일시스템:** 이미지/대용량/캐시.
5. **마이그레이션:** 스키마 버전 관리.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 앱이 디바이스에 데이터를 보존해야 할 때.
- **사용 조건:** 데이터 성격 분류; 용량/보안 요구 파악.
- **장점:** 오프라인, 빠른 접근, 네트워크 절약.
- **단점:** 디바이스 한정, 백업/동기화 별도, 보안 책임.
- **대안:** 서버 저장(동기화 필요), 캐시만(휘발).
- **실패 사례:** 토큰을 평문 prefs 에(보안 사고); 대용량을 key-value 에(성능); 마이그레이션 없어 업데이트 시 크래시; 캐시와 영구 데이터 혼동.
## 💻 코드 패턴 (Code patterns)
```text
prefs.set('theme', v) # 소량 설정
secureStore.set('token', t) # 민감정보 (Keychain/Keystore)
db.exec('INSERT ...') # 구조화 데이터
fs.write(path, blob) # 대용량
onUpgrade(old, new): migrate(old→new) # 스키마 버전
```
적용 예: ConnectAI 는 설정=VS Code config/secrets, 지식=Markdown 파일, 이벤트=JSONL — *데이터 성격별 매체 분리* 원칙을 그대로([[ADR-0005 파일 기반 저장 채택]]).
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"전부 SQLite" 나 "전부 key-value" 는 안티패턴 — 성격별 분리가 원칙. 민감정보는 *반드시* 보안 저장소.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI secrets(토큰) + 파일(지식) + JSONL(이벤트).
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Offline Sync Pattern]], [[Caching Pattern]], [[이벤트 소싱 스토어 패턴]], [[모바일 개발 가이드]]
- **참조 맥락:** 작은 모델이 클라이언트 저장을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 모바일 저장 지식
- [S2] ConnectAI/src/core/services.ts, extension.ts(secrets), eventSourcedStore.ts — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,65 @@
---
id: pattern-navigation
title: "Navigation Pattern"
category: "Pattern_Mobile"
status: "draft"
verification_status: "conceptual"
canonical_id: ""
aliases: ["navigation", "내비게이션 패턴", "routing", "deep link", "navigation stack"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.83
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "mobile", "navigation", "routing", "platform-independent"]
raw_sources: ["일반 모바일/프런트엔드 공학 지식"]
applied_in: []
github_commit: ""
---
# [[Navigation Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
내비게이션은 "화면 간 이동과 스택/상태를 관리" 하는 패턴으로, *경로를 선언적·직렬화 가능*하게 두고 딥링크/뒤로가기/상태 복원을 1급으로 다뤄야 한다.
## 🧠 핵심 개념 (Core concepts)
1. **선언적 라우트:** URL/route 로 화면을 표현(직렬화 가능).
2. **스택/탭/드로어:** 내비 구조 유형.
3. **딥링크:** 외부에서 특정 화면 직접 진입.
4. **파라미터 전달:** 라우트 인자 + 타입 안전.
5. **상태 복원:** 프로세스 죽어도 내비 상태 복구.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 다화면 앱의 이동/히스토리/딥링크 관리.
- **사용 조건:** 라우트 정의; 화면 식별자; 인자 직렬화.
- **장점:** 일관된 이동, 딥링크, 뒤로가기, 테스트성.
- **단점:** 설정 복잡, 깊은 스택 메모리, 타입 안전 관리.
- **대안:** 단일 화면(소규모), 조건부 렌더(상태 기반), 코디네이터 패턴.
- **실패 사례:** 객체를 라우트 인자로 직접(직렬화 불가/딥링크 깨짐); 스택 누수(화면 안 떼어냄); 뒤로가기 상태 불일치; 딥링크 시 부모 스택 없어 길 잃음.
## 💻 코드 패턴 (Code patterns)
```text
routes = { '/home': Home, '/item/:id': ItemDetail } # 선언적 + 직렬화 가능 인자
navigate('/item/42') # id 만 전달(객체 X)
deepLink('myapp://item/42') -> rebuild stack [Home, ItemDetail]
restore(savedNavState) # 프로세스 복원
```
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"상태로 화면 전환" vs "라우터" — 작은 앱은 상태 조건부가 단순하나, 딥링크/히스토리가 필요하면 선언적 라우터가 필수.
## 🛠️ 적용 사례 (Applied in summary)
일반 모바일/SPA. (ConnectAI 는 패널 기반이라 직접 사례 없음 — 화면 식별/복원 원리는 동일.)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[State Management Pattern]], [[React State Pattern]], [[모바일 개발 가이드]]
- **참조 맥락:** 작은 모델이 다화면 앱의 이동을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 내비게이션/라우팅 지식
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,66 @@
---
id: pattern-offline-sync
title: "Offline Sync Pattern"
category: "Pattern_Mobile"
status: "draft"
verification_status: "conceptual"
canonical_id: ""
aliases: ["offline sync", "오프라인 동기화", "optimistic update", "conflict resolution", "outbox"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.85
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "mobile", "offline", "sync", "platform-independent"]
raw_sources: ["일반 모바일 공학 지식", "ConnectAI/src/features/_shared/eventSourcedStore.ts (개념 유사)"]
applied_in: []
github_commit: ""
---
# [[Offline Sync Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
오프라인 동기화는 "네트워크 없이도 로컬에서 동작하고, 연결되면 변경을 *큐로 모아 동기화*하며 충돌을 해소" 하는 패턴으로, 핵심 난제는 동기화 자체가 아니라 **충돌 해소(conflict resolution)** 다.
## 🧠 핵심 개념 (Core concepts)
1. **로컬 우선 저장:** 모든 쓰기를 먼저 로컬에.
2. **outbox(변경 큐):** 미동기 변경을 append-only 로 쌓아 연결 시 전송.
3. **낙관적 업데이트:** UI 는 즉시 반영, 실패 시 롤백.
4. **충돌 해소:** last-write-wins / 버전 벡터 / 병합 / 사용자 선택.
5. **멱등성:** 재전송에도 안전하도록 변경에 고유 id.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 불안정/없는 네트워크에서도 앱이 동작해야 할 때.
- **사용 조건:** 로컬 저장소; 변경을 식별/순서화 가능; 서버 동기 API.
- **장점:** 오프라인 사용성, 빠른 반응(낙관적), 복원력.
- **단점:** 충돌 해소 복잡, 데이터 일관성 약화, 디버깅 난해.
- **대안:** 온라인 전용(단순), CRDT(자동 병합, 복잡), 서버 권위(충돌 시 서버 우선).
- **실패 사례:** 멱등 키 없어 중복 적용; LWW 로 사용자 데이터 유실; outbox 순서 꼬임; 낙관적 업데이트 롤백 누락으로 유령 데이터.
## 💻 코드 패턴 (Code patterns)
```text
write(op): localDB.apply(op); outbox.append({id:uuid, op, ts}) # 로컬 우선 + 큐
onOnline: for op in outbox: try{ server.apply(op) /*멱등*/; outbox.remove(op) } catch{ retry }
onPull: merge(serverChanges, local, resolve=versionVector|userChoice)
```
개념 유사: ConnectAI 의 append-only 이벤트([[이벤트 소싱 스토어 패턴]])가 outbox 와 같은 구조 — 변경을 줄로 쌓고 재생/전송.
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
LWW 는 간단하지만 데이터 손실 위험 — 협업/중요 데이터엔 버전 벡터/CRDT 또는 사용자 충돌 해소가 안전.
## 🛠️ 적용 사례 (Applied in summary)
일반 모바일 앱(노트/메신저). ConnectAI 는 단일 로컬이라 동기화는 불필요하나 outbox 구조는 동일.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Local Storage Pattern]], [[Background Task Pattern]], [[이벤트 소싱 스토어 패턴]], [[모바일 개발 가이드]]
- **참조 맥락:** 작은 모델이 오프라인 가능 앱을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 오프라인 동기화 지식(outbox, CRDT)
- [S2] ConnectAI/src/features/_shared/eventSourcedStore.ts — 구조 유사
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,67 @@
---
id: pattern-push-notification
title: "Push Notification Pattern"
category: "Pattern_Mobile"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["push notification", "푸시 알림", "FCM", "APNs", "notification"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.84
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "mobile", "push", "notification", "platform-independent"]
raw_sources: ["일반 모바일 공학 지식", "ConnectAI/src/integrations/telegram/*, src/features/briefing/* (유사 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Push Notification Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
푸시 알림은 "서버가 디바이스로 비동기 메시지를 밀어 넣는" 패턴으로, 토큰 수명 관리·전달 보장 없음·사용자 동의·과알림 피로를 다루지 못하면 오히려 이탈을 부른다.
## 🧠 핵심 개념 (Core concepts)
1. **디바이스 토큰:** 앱이 FCM/APNs 토큰 등록, 서버 저장(만료/갱신).
2. **전송:** 서버→게이트웨이(FCM/APNs)→디바이스.
3. **전달 비보장:** best-effort — 중요 데이터는 알림 본문 말고 동기화로.
4. **동의/채널:** 권한 요청, 카테고리별 on/off.
5. **딥링크:** 탭 시 해당 화면으로.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 서버 이벤트를 사용자에게 즉시 알릴 때.
- **사용 조건:** 게이트웨이 연동; 토큰 저장; 사용자 동의.
- **장점:** 재참여, 실시간 알림, 백그라운드 트리거.
- **단점:** 전달 비보장, 토큰 만료, 권한 거부 시 무력, 과알림 피로.
- **대안:** 인앱 알림, 폴링(배터리↑), 이메일/SMS.
- **실패 사례:** 만료 토큰으로 전송 실패; 알림 본문에만 중요 데이터(미수신 시 유실); 과알림으로 권한 철회; 딥링크 없어 탭 후 길 잃음.
## 💻 코드 패턴 (Code patterns)
```text
onAppStart: token = registerForPush(); server.saveToken(userId, token)
server.onEvent: send(FCM/APNs, token, { title, body, data:{deeplink} }) # best-effort
onReceive: showNotification ; onTap: navigate(data.deeplink)
onTokenRefresh: server.updateToken(...)
```
유사 예: ConnectAI 의 Telegram 리포트/daily briefing 이 "서버측 이벤트→사용자 채널 푸시" 구조([[Background Task Pattern]] 워처가 트리거). 전달 비보장 가정도 동일.
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
알림을 "전달된다" 고 가정하면 안 된다 — 중요 상태는 서버에 두고 알림은 *유도* 만. 과알림은 가장 흔한 이탈 원인.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI Telegram 알림(리포트/브리핑).
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Background Task Pattern]], [[API Client Pattern]], [[모바일 개발 가이드]]
- **참조 맥락:** 작은 모델이 알림 기능을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 푸시(FCM/APNs) 지식
- [S2] ConnectAI/src/integrations/telegram/*, features/briefing/* — 유사 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,72 @@
---
id: pattern-api-client
title: "API Client Pattern"
category: "Pattern_Web"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["API client", "HTTP client", "API 클라이언트 패턴", "adapter", "SDK wrapper"]
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: ["pattern", "web", "api", "http", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/features/providers/*, src/integrations/telegram/telegramClient.ts (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[API Client Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
API Client 패턴은 "외부 HTTP/SDK 호출을 한 모듈로 캡슐화" 해 인증·재시도·타임아웃·에러 정규화·취소를 한 곳에서 관리하고, 호출부는 깨끗한 메서드만 보게 한다.
## 🧠 핵심 개념 (Core concepts)
1. **단일 클라이언트:** baseURL/헤더/인증을 한 곳에.
2. **횡단 관심사:** 재시도·타임아웃·취소(AbortSignal)·로깅·에러 변환을 내장.
3. **응답 정규화:** 다양한 응답을 내부 표준 형태로.
4. **인증 주입:** 토큰을 getter 로(갱신 반영).
5. **에러 passthrough/translate:** 실패를 호출부가 쓸 수 있는 형태로.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 외부 API/SDK 를 여러 곳에서 호출, 인증·재시도·에러 처리가 반복될 때.
- **사용 조건:** 호출 인터페이스 정의 가능; 인증/설정 중앙화 가능.
- **장점:** 중복 제거, 일관된 에러/재시도/취소, 교체·모킹 용이, 테스트성.
- **단점:** 추상화 비용, 만능 클라이언트화 위험.
- **대안:** fetch 직접(소규모), 생성된 SDK, GraphQL 클라이언트.
- **실패 사례:** 타임아웃/취소 누락으로 멈춤; 토큰 하드코딩(갱신 안 됨); 에러 삼킴; 재시도에 backoff 없어 폭주; 응답 형식 호출부 산재.
## 💻 코드 패턴 (Code patterns)
```text
class Client {
constructor({ getToken, baseUrl }) # 인증은 getter 주입
async call(path, body, { signal }) {
const s = combine(signal, timeout(ms)) # 취소+타임아웃
res = await fetch(baseUrl+path, { headers:{Authorization:getToken()}, signal:s })
if (!res.ok) return normalizeError(res) # 에러 정규화/passthrough
return parse(res) # 응답 정규화
}
}
```
적용 예: ConnectAI 의 provider 어댑터(공급자별 차이 흡수→공통 SSE)와 TelegramHttpClient(getToken 게터). → [[LLM 프로바이더 추상화]], [[AITRAIN 프로바이더 추상화]].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
얇은 호출이면 fetch 직접이 낫다 — 인증/재시도/에러가 반복될 때만 클라이언트 추상화가 이득.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI providers + telegramClient.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[Async Concurrency Pattern]], [[Error Handling Pattern]], [[Caching Pattern]], [[Tool Calling Pattern]]
- **참조 맥락:** 작은 모델이 외부 API 통합 코드를 작성할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 API 클라이언트 지식
- [S2] ConnectAI/src/features/providers/*, integrations/telegram/telegramClient.ts — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,66 @@
---
id: pattern-infinite-scroll
title: "Infinite Scroll Pattern"
category: "Pattern_Web"
status: "draft"
verification_status: "conceptual"
canonical_id: ""
aliases: ["infinite scroll", "무한 스크롤", "pagination", "cursor pagination", "virtualization"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.85
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "web", "frontend", "pagination", "platform-independent"]
raw_sources: ["일반 프런트엔드 공학 지식"]
applied_in: []
github_commit: ""
---
# [[Infinite Scroll Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
무한 스크롤은 "사용자가 끝에 도달하면 다음 페이지를 자동 로드" 하는 패턴으로, *커서 기반 페이징 + DOM 가상화 + 중복/경쟁 요청 방지* 가 없으면 성능과 정확성이 무너진다.
## 🧠 핵심 개념 (Core concepts)
1. **트리거:** IntersectionObserver 로 sentinel 가시화 감지.
2. **커서 페이징:** offset 대신 cursor(마지막 항목 키) — 삽입/삭제에 안정.
3. **가상화:** 화면 밖 항목은 DOM 에서 제거(react-window 등).
4. **중복/경쟁 방지:** 진행 중 로드 잠금, 이전 요청 취소.
5. **상태:** 로딩/끝(hasMore)/에러 표시.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 큰 목록(피드/검색결과)을 점진 로드해 초기 부하를 줄일 때.
- **사용 조건:** 페이징 API(가급적 커서); 항목 높이 처리.
- **장점:** 빠른 초기 로드, 자연스러운 UX, 대용량 처리.
- **단점:** 푸터 도달 불가, 딥링크/뒤로가기 어려움, 접근성/SEO 약함, 구현 복잡.
- **대안:** 일반 페이지네이션(점프/SEO 좋음), "더 보기" 버튼(제어 명확).
- **실패 사례:** offset 페이징 중 삽입→항목 중복/누락; 가상화 없이 DOM 폭증 렉; 중복 트리거로 같은 페이지 N번; 경쟁 요청 순서 꼬임; hasMore 미처리로 무한 호출.
## 💻 코드 패턴 (Code patterns)
```text
observer.observe(sentinel)
onIntersect: if (!loading && hasMore) { loading=true; signal=abortPrev()
page = await api.list({ cursor, signal }); items.push(...page.items)
cursor = page.nextCursor; hasMore = !!cursor; loading=false }
render: virtualize(items) # 화면 밖 제거
```
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
무한 스크롤이 항상 옳지 않다 — 작업형 목록(테이블/검색)엔 페이지네이션이 제어·딥링크 면에서 낫다. 피드형에만 적합.
## 🛠️ 적용 사례 (Applied in summary)
일반 웹/모바일 피드. (ConnectAI 직접 사례 없음.)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[React State Pattern]], [[Async Concurrency Pattern]], [[Caching Pattern]], [[웹 개발 가이드]]
- **참조 맥락:** 작은 모델이 큰 목록 UI 를 구현할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 프런트엔드 페이징/가상화 지식
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,65 @@
---
id: pattern-jwt-authentication
title: "JWT Authentication Pattern"
category: "Pattern_Web"
status: "draft"
verification_status: "conceptual"
canonical_id: ""
aliases: ["JWT", "토큰 인증", "access token", "refresh token", "stateless auth"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.86
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "web", "auth", "jwt", "security", "platform-independent"]
raw_sources: ["일반 웹 보안 공학 지식"]
applied_in: []
github_commit: ""
---
# [[JWT Authentication Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
JWT 인증은 "서명된 토큰에 사용자 정보를 담아 *서버 세션 없이* 상태 무관(stateless) 인증" 을 하는 패턴으로, 확장성은 좋지만 *토큰을 즉시 무효화하기 어렵다* 는 본질적 약점이 있다.
## 🧠 핵심 개념 (Core concepts)
1. **access token(짧은 수명) + refresh token(긴 수명):** 짧은 access 로 노출 위험↓, refresh 로 재발급.
2. **서명 검증:** 서버 비밀키로 서명, 변조 시 검증 실패(저장 불필요).
3. **claims:** sub/exp/role 등 페이로드(민감정보 금지 — base64 는 암호화 아님).
4. **저장 위치:** httpOnly 쿠키(XSS 안전) vs localStorage(XSS 취약).
5. **무효화:** 블랙리스트/짧은 만료/회전으로 보완.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 분산/무상태 API, 여러 서비스가 같은 토큰 검증(SSO), 모바일+웹 공용.
- **사용 조건:** 비밀키 안전 보관; HTTPS; 토큰 수명 정책.
- **장점:** 무상태(수평 확장), 서비스 간 공유, DB 조회 없이 검증.
- **단점:** 즉시 무효화 어려움(로그아웃/탈취), 페이로드 노출, 토큰 비대.
- **대안:** 서버 세션(즉시 무효화 쉬움, 상태 필요), OAuth/OIDC(위임), API key(머신).
- **실패 사례:** localStorage 저장→XSS 탈취; refresh 회전 없이 탈취 지속; 민감정보를 claims 에; 만료 너무 길어 탈취 피해 확대; 서명 알고리즘 `none` 허용.
## 💻 코드 패턴 (Code patterns)
```text
login: verify(creds) -> access=sign({sub,exp:15m}), refresh=sign({sub,exp:7d}); setHttpOnlyCookie
request: verifySignature(access) && !expired -> allow ; else 401
refresh: verify(refresh) && !revoked -> rotate(new access+refresh), invalidate old
logout: revoke(refresh) # 블랙리스트/회전
```
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"JWT 가 세션보다 낫다" 는 과장 — 즉시 무효화·서버측 제어가 중요하면 세션이 낫다. JWT 는 *무상태 확장* 이 목적일 때.
## 🛠️ 적용 사례 (Applied in summary)
일반 웹/모바일 API 인증. (ConnectAI 는 로컬 도구라 직접 사례 없음 — provider API key 는 [[API Client Pattern]] 참조.)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[API Client Pattern]], [[웹 개발 가이드]], [[소프트웨어 실패 라이브러리]]
- **참조 맥락:** 작은 모델이 웹/모바일 인증을 구현할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 웹 보안/JWT 지식(RFC 7519, OWASP)
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,65 @@
---
id: pattern-react-state
title: "React State Pattern"
category: "Pattern_Web"
status: "draft"
verification_status: "conceptual"
canonical_id: ""
aliases: ["React state", "리액트 상태 패턴", "hooks", "lifting state up", "server state"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.85
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["pattern", "web", "react", "frontend", "state", "platform-independent"]
raw_sources: ["일반 프런트엔드 공학 지식"]
applied_in: []
github_commit: ""
---
# [[React State Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
React(및 유사 선언형 UI) 상태의 핵심 규칙은 "**상태를 필요한 가장 낮은 곳에 두되, 공유되면 끌어올리고, 서버 데이터는 UI 상태와 분리**" 하는 것 — 이는 [[State Management Pattern]] 의 프런트엔드 구체화다.
## 🧠 핵심 개념 (Core concepts)
1. **로컬 상태(useState):** 한 컴포넌트만 쓰는 상태.
2. **lifting state up:** 두 형제가 공유하면 공통 부모로.
3. **전역 상태(Context/Zustand/Redux):** 앱 전반 공유(과용 금지).
4. **서버 상태(react-query/SWR):** 원격 데이터는 캐시·동기화 라이브러리로 분리.
5. **파생 상태:** useMemo 로 계산, 저장하지 않음.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 컴포넌트 트리에서 상태 위치·공유 범위를 정할 때.
- **사용 조건:** 선언형 UI; 단방향 데이터.
- **장점:** 예측 가능 렌더, 재사용, 테스트성.
- **단점:** prop drilling(전역 미사용 시), 과한 전역화는 리렌더·결합, 서버/클라 상태 혼동.
- **대안:** 전역 store(공유 많을 때), 서버 상태 라이브러리, URL 상태(공유 가능 상태).
- **실패 사례:** 서버 데이터를 useState 에 복사→stale·동기화 버그; 모든 걸 전역 store 에→불필요 리렌더·결합; 파생값 저장; 깊은 prop drilling.
## 💻 코드 패턴 (Code patterns)
```text
const [v, setV] = useState(init) # 로컬
// 공유되면 부모로 올리고 props/context 로 전달
const data = useQuery('key', fetcher) # 서버 상태는 분리(캐시/리페치)
const total = useMemo(() => sum(items), [items]) # 파생은 계산
```
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"Redux 가 정석" 은 옛말 — 서버 상태는 react-query, 지역은 useState, 진짜 전역만 가벼운 store. 도구보다 *상태의 출처/수명* 으로 위치를 정하라.
## 🛠️ 적용 사례 (Applied in summary)
일반 React 앱. (ConnectAI 웹뷰는 메시지 기반 — 원리는 [[State Management Pattern]] 와 동일.)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[State Management Pattern]], [[Data Flow Pattern]], [[Infinite Scroll Pattern]], [[웹 개발 가이드]]
- **참조 맥락:** 작은 모델이 프런트엔드 상태를 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 React/프런트엔드 상태 지식
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,66 @@
---
id: pattern-repository
title: "Repository Pattern"
category: "Pattern_Web"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["Repository", "리포지토리 패턴", "data access layer", "DAO"]
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: ["pattern", "web", "backend", "data-access", "platform-independent"]
raw_sources: ["일반 소프트웨어 공학 지식", "ConnectAI/src/features/_shared/eventSourcedStore.ts (적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Repository Pattern]]
## 🎯 한 줄 통찰 (One-line insight)
Repository 는 "도메인 코드와 데이터 저장 방식 사이에 *컬렉션처럼 보이는* 인터페이스를 두어, 비즈니스 로직이 DB/파일/API 의 세부를 모르게" 하는 패턴이다.
## 🧠 핵심 개념 (Core concepts)
1. **인터페이스로 저장 추상화:** `find/save/delete` 같은 도메인 언어 메서드.
2. **구현 교체:** 같은 인터페이스로 메모리/파일/SQL/원격 구현.
3. **도메인 모델 반환:** raw 행이 아니라 도메인 객체.
4. **쿼리 캡슐화:** 복잡 쿼리를 repository 안에.
## 📖 세부 내용 (Details · 패턴 명세)
- **Problem (언제 쓰나):** 도메인 로직을 저장 기술과 분리하고 테스트(가짜 repo)하고 싶을 때.
- **사용 조건:** 도메인 모델 정의; 저장 연산을 인터페이스로 표현 가능.
- **장점:** 저장 교체 용이, 테스트성(in-memory repo), 도메인 순수, 쿼리 한 곳.
- **단점:** 추상화 비용, 단순 CRUD 엔 과설계, leaky abstraction 위험.
- **대안:** ORM 직접 사용(소규모), Active Record, 쿼리 빌더 직접.
- **실패 사례:** repository 가 DB 세부를 누수(IQueryable 노출); 만능 repository(God repo); 도메인이 SQL 을 알게 됨.
## 💻 코드 패턴 (Code patterns)
```text
interface UserRepo { findById(id): User?; save(u: User): Result; list(): User[] }
class FileUserRepo implements UserRepo { ... } # 교체 가능 구현
class SqlUserRepo implements UserRepo { ... }
service(repo: UserRepo) # 도메인은 인터페이스만 의존(주입)
```
적용 예: ConnectAI 의 `createEventStore<E>` 가 read/append/count 로 저장을 추상화하고 도메인은 인터페이스만 사용([[이벤트 소싱 스토어 패턴]], [[AITRAIN 이벤트소싱 저장]]).
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
ORM 이 이미 repository 유사 추상을 주므로, 그 위에 또 repository 를 얹으면 중복일 수 있다 — 교체/테스트 필요가 명확할 때만.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI eventSourcedStore(도메인별 store 인스턴스화).
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[패턴 카탈로그 인덱스]]
- **관련 개념:** [[의존성 주입과 서비스 인터페이스]], [[Architecture Separation Pattern]], [[Local Storage Pattern]], [[백엔드 API 개발 가이드]]
- **참조 맥락:** 작은 모델이 데이터 접근 계층을 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] 일반 DDD/Repository 지식
- [S2] ConnectAI/src/features/_shared/eventSourcedStore.ts — 적용 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 프로젝트 독립 패턴 카드 작성.
@@ -0,0 +1,52 @@
---
id: platform-guides-index
title: "플랫폼 개발 가이드 인덱스"
category: "Index"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["platform guides", "플랫폼 가이드", "플랫폼별 개발 패턴", "platform development index"]
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: ["index", "platform", "guide", "navigation"]
raw_sources: ["Platform_Guides 전체"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[플랫폼 개발 가이드 인덱스]]
## 🎯 한 줄 통찰 (One-line insight)
플랫폼별 가이드는 [[프로젝트 독립 설계 원칙]] 과 [[패턴 카탈로그 인덱스]] 를 *각 플랫폼의 구체적 폴더 구조·핵심 컴포넌트·테스트·확장 전략* 으로 구체화한 것 — 경험 많은 엔지니어가 플랫폼을 가로질러 어떻게 설계하는지를 작은 모델에 가르친다.
## 🧠 핵심 개념 (Core concepts)
각 가이드 12-field: Problem / Recommended Architecture / Folder Structure / Core Components / State Management / Error Handling / Testing / Scaling / Common Mistakes / Refactoring / Tradeoffs / Heuristics.
## 📖 세부 내용 (Details · 가이드 목록)
- [[웹 개발 가이드]]
- [[데스크탑 앱 개발 가이드]] (ConnectAI 실증)
- [[모바일 개발 가이드]]
- [[백엔드 API 개발 가이드]]
- [[AI 에이전트 개발 가이드]] (ConnectAI 실증)
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
가이드의 "Recommended" 는 *기본값* 이며, 프레임워크/스택 선택은 팀·생태계·규모로 조정. 공통 원리는 [[프로젝트 독립 설계 원칙]] 으로 수렴.
## 🛠️ 적용 사례 (Applied in summary)
데스크탑·AI 에이전트 가이드는 ConnectAI 가 실제 구현한 사례로 뒷받침된다.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[Topic Programming 인덱스]]
- **관련 개념:** [[패턴 카탈로그 인덱스]] · [[프로젝트 독립 설계 원칙]] · [[소프트웨어 실패 라이브러리]]
- **참조 맥락:** 작은 모델이 특정 플랫폼 프로젝트를 시작할 때의 상위 설계 가이드.
## 📚 출처 (Sources)
- [S1] Platform_Guides 전체 + 일반 공학 지식 + ConnectAI 실증
## 📝 변경 이력 (Change history)
- 2026-06-13: 플랫폼 개발 가이드 인덱스 생성.
@@ -0,0 +1,60 @@
---
id: platform-ai-agent-development
title: "AI 에이전트 개발 가이드"
category: "Platform_Engineering"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["AI agent development", "AI 에이전트 개발", "LLM app", "agent architecture", "RAG agent"]
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: ["platform", "ai", "agent", "llm", "guide", "platform-independent"]
raw_sources: ["일반 AI 에이전트 공학 지식", "ConnectAI 전체 (실증 사례)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[AI 에이전트 개발 가이드]]
## 🎯 한 줄 통찰 (One-line insight)
AI 에이전트 개발의 핵심은 "**검색(RAG)·기억(Memory)·도구(Tool)·검증(Critic)·오케스트레이션**" 을 자원 제약에 맞게 조합하는 것 — 특히 작은 로컬 모델에선 *결정론 우선·강한 grounding·자기검증* 이 품질을 가른다. ConnectAI 전체가 이 가이드의 실증이다.
## 🧠 핵심 개념 (Core concepts)
컨텍스트 조립, RAG, 다계층 메모리, 도구 호출, 자기검증/critic, 프롬프트 엔지니어링, 멀티에이전트 오케스트레이션, 모델 라우팅/폴백.
## 📖 세부 내용 (Details · 12-field)
- **Problem:** LLM(특히 작은 모델)으로 신뢰 가능·근거 있는·행동하는 시스템을 만들기.
- **Recommended Architecture:** 턴 파이프라인(컨텍스트 조립 → 라우팅 → 생성 → 후처리/검증 → 학습) + RAG + 메모리 + 도구 + 검증 레이어. 흐름 골격은 한 곳([[Agent 오케스트레이터 분해]]).
- **Folder Structure:** `src/{retrieval/, memory/, intelligence/(검증), agent/(handlePrompt,llm,actions), providers/, lib/contextBuilders/}` — ConnectAI 구조.
- **Core Components:** RAG([[RAG Pattern]]), 메모리([[Memory Pattern]]), 도구 실행([[Tool Calling Pattern]]), 검증([[Critic Pattern]]/[[Reflection Pattern]]), 프롬프트 빌더([[프롬프트 엔지니어링 패턴]]), 프로바이더([[LLM 프로바이더 추상화]]).
- **State Management:** 대화=단기 메모리, 지식=RAG/장기, 작업 상태=세션 store. 컨텍스트는 토큰 예산 내 선별.
- **Error Handling:** 엔진 폴백, 빈 응답 soft failure, JSON 강건 파싱, 환각 가드([[Error Handling Pattern]], [[Intelligence 검증 레이어]]).
- **Testing Strategy:** 순수 함수 단위(토크나이저/스코어/파서), 검색 평가 하니스(recall@k/MRR), 회귀 케이스(정정 재검사), 프롬프트 골든셋.
- **Scaling Strategy:** 인덱스 캐시(mtime), 토큰 예산, 순차/자원 인지 동시성, sleep-time 사전소화, 클라우드 폴백.
- **Common Mistakes:** 에이전트 남발(hop 손실), 임베딩 단독 의존, 매 턴 LLM 검수(비용), JSON 직접 파싱, 모델 출력 무검증 실행, system 없는 호출(작은 모델 거절).
- **Refactoring Patterns:** 5-persona→단일 작성자([[ADR-0003 단일작성자 다중역할 멀티에이전트]]), 동적→정적, 휴리스틱→골든셋 보정, 프롬프트 블록화.
- **Real-world Tradeoffs:** 로컬(프라이버시/비용 ↔ 품질) vs 클라우드, 결정론(가용/설명 ↔ 의미) vs 임베딩, 검증 깊이(정확 ↔ latency), 멀티에이전트(다양성 ↔ 자원/손실).
- **Design Heuristics:** "결정론 우선, 의미는 가산", "작은 모델엔 강한 system+명시 규칙", "근거 없으면 모른다", "검증 비용은 위험에 비례", "에이전트 추가 전 정보 손실 점검", "동시성은 하드웨어가 결정".
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"더 큰 모델·더 많은 에이전트" 가 답이 아니다 — 자원 제약 하에선 *잘 설계된 RAG+메모리+검증* 이 작은 모델을 크게 끌어올린다. 이 위키 자체가 그 전략(제2뇌)의 산물.
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI(Astra) — RAG/메모리/검증/멀티에이전트의 통합 실증. 본 위키 [[ConnectAI 아키텍처 개요]] 및 AI_Training 시리즈.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[플랫폼 개발 가이드 인덱스]]
- **관련 개념:** [[RAG Pattern]], [[Memory Pattern]], [[Agent Orchestration Pattern]], [[Critic Pattern]], [[Tool Calling Pattern]], [[Intelligence 검증 레이어]]
- **참조 맥락:** 작은 모델이 *자기 같은* AI 에이전트 시스템을 설계할 때 최상위 가이드로 참조.
## 📚 출처 (Sources)
- [S1] 일반 AI 에이전트/LLM 앱 공학 지식
- [S2] ConnectAI 전체 — 실증 사례
## 📝 변경 이력 (Change history)
- 2026-06-13: 플랫폼 독립 AI 에이전트 개발 가이드 초안.
@@ -0,0 +1,60 @@
---
id: platform-desktop-development
title: "데스크탑 앱 개발 가이드"
category: "Platform_Engineering"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["desktop development", "데스크탑 개발", "Electron", "VS Code extension", "native app"]
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: ["platform", "desktop", "electron", "guide", "platform-independent"]
raw_sources: ["일반 데스크탑 공학 지식", "ConnectAI(VS Code 확장) 적용 예"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[데스크탑 앱 개발 가이드]]
## 🎯 한 줄 통찰 (One-line insight)
데스크탑 앱의 핵심은 "**프로세스 분리(UI↔백그라운드)·생명주기/자원 관리·확장성·로컬 저장**" 이며, ConnectAI(VS Code 확장)가 이 원리들의 실증 사례다.
## 🧠 핵심 개념 (Core concepts)
메인/렌더러 프로세스, IPC, 생명주기(activate/dispose), 로컬 파일/설정/시크릿, 플러그인 확장, 백그라운드 워커.
## 📖 세부 내용 (Details · 12-field)
- **Problem:** OS 자원 접근·장시간 실행·로컬 데이터·반응적 UI 를 안정적으로.
- **Recommended Architecture:** 얇은 entry(조립) + 계층 분리(인프라/도메인/기능) + IPC 로 UI 분리 + 플러그인 확장 지점. ([[ConnectAI 아키텍처 개요]])
- **Folder Structure:** `src/{core/(인프라), lib/도메인, features/<기능>, ui|webview, integrations}` + entry(activate/main).
- **Core Components:** entry point, IPC 브리지([[IPC Pattern]]), 명령 레지스트리([[Command Pattern]]), 이벤트 버스([[Event Bus Pattern]]), 워커 큐([[Background Worker Pattern]]), 로컬 저장([[Local Storage Pattern]]).
- **State Management:** 메인 프로세스가 진실 소유, UI 는 메시지로 변경 요청([[State Management Pattern]]). 설정은 단일 getConfig.
- **Error Handling:** 사용자 친화 번역, 부가 작업 격리(빈 catch+이유), 보상 트랜잭션([[Error Handling Pattern]]).
- **Testing Strategy:** 순수 도메인 단위 테스트(핵심), IPC/통합 테스트, UI 스모크. (ConnectAI: jest + 순수 함수 격리)
- **Scaling Strategy:** 무거운 작업 워커/순차([[ADR-0004 순차 디스패치 채택]]), 지연 로드(동적 import), 인덱스 캐시([[Caching Pattern]]).
- **Common Mistakes:** disposable 미등록(누수), UI 스레드 무거운 작업, 외부 IPC 입력 미검증, 동적 import 남발, 전역 상태 산재.
- **Refactoring Patterns:** entry 얇게(조립만), god-class 골격+추출([[ADR-0010 오케스트레이터 골격 모듈추출]]), 동적→정적 import, 중복→공통 모듈.
- **Real-world Tradeoffs:** Electron(생산성·크로스플랫폼 ↔ 메모리·번들 크기), 네이티브(성능 ↔ 플랫폼별 코드), 프로세스 분리(격리·보안 ↔ 직렬화 비용).
- **Design Heuristics:** "모든 자원은 dispose 등록", "한 번에 한 모델/무거운 자원", "외부 입력은 신뢰 안 함", "흐름 골격은 한 곳".
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
Electron 은 편하지만 무겁다 — 경량이 중요하면 Tauri/네이티브. 자원 제약(메모리/GPU)이 동시성·아키텍처를 좌우한다(ConnectAI 의 핵심 교훈).
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI(Astra) VS Code 확장 — 본 위키 [[ConnectAI 아키텍처 개요]] 전체가 실증.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[플랫폼 개발 가이드 인덱스]]
- **관련 개념:** [[IPC Pattern]], [[Event Bus Pattern]], [[Command Pattern]], [[Plugin Architecture Pattern]], [[Background Worker Pattern]], [[VSCode 확장 구조와 생명주기]]
- **참조 맥락:** 작은 모델이 데스크탑/확장 앱을 설계할 때 상위 가이드로 참조.
## 📚 출처 (Sources)
- [S1] 일반 데스크탑(Electron/확장) 공학 지식
- [S2] ConnectAI — 실증 사례
## 📝 변경 이력 (Change history)
- 2026-06-13: 플랫폼 독립 데스크탑 개발 가이드 초안.
@@ -0,0 +1,59 @@
---
id: platform-mobile-development
title: "모바일 개발 가이드"
category: "Platform_Engineering"
status: "draft"
verification_status: "conceptual"
canonical_id: ""
aliases: ["mobile development", "모바일 개발", "iOS", "Android", "React Native", "Flutter"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.85
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["platform", "mobile", "guide", "platform-independent"]
raw_sources: ["일반 모바일 공학 지식"]
applied_in: []
github_commit: ""
---
# [[모바일 개발 가이드]]
## 🎯 한 줄 통찰 (One-line insight)
모바일 개발의 고유 제약은 "**불안정 네트워크·제한된 자원·OS 백그라운드 제약·생명주기**" 이며, 이를 *오프라인 우선·로컬 저장·백그라운드 작업·내비게이션* 패턴으로 다루는 것이 핵심이다.
## 🧠 핵심 개념 (Core concepts)
앱 생명주기(foreground/background), 오프라인 우선, 로컬 저장, 푸시, 내비게이션 스택, 권한.
## 📖 세부 내용 (Details · 12-field)
- **Problem:** 끊기는 네트워크·제한 메모리/배터리·OS 제약 하에서 반응적이고 신뢰 가능한 앱.
- **Recommended Architecture:** 오프라인 우선(로컬 저장이 진실) + 동기화 계층 + 화면/도메인 분리(MVVM/Clean) + 내비게이션 라우터.
- **Folder Structure:** `lib|src/{features/<feature>/{ui,viewmodel,data}, core/(network,storage,di), navigation}`.
- **Core Components:** 로컬 DB([[Local Storage Pattern]]), 동기화([[Offline Sync Pattern]]), API 클라이언트([[API Client Pattern]]), 푸시([[Push Notification Pattern]]), 내비게이션([[Navigation Pattern]]), 백그라운드([[Background Task Pattern]]).
- **State Management:** ViewModel/store(Bloc/Riverpod/Redux) + 서버 상태 분리 + 화면 상태 복원([[State Management Pattern]]).
- **Error Handling:** 네트워크 실패 우아 처리(오프라인 표시·재시도), 낙관적 업데이트 롤백([[Error Handling Pattern]]).
- **Testing Strategy:** 단위(ViewModel/로직), 위젯/컴포넌트, 통합/E2E(Detox/Espresso). 디바이스 매트릭스.
- **Scaling Strategy:** 이미지/리스트 가상화, 지연 로드, 배터리/네트워크 인지 동기화, 모듈화.
- **Common Mistakes:** 메인 스레드 무거운 작업(jank), 토큰 평문 저장, 알림 전달 가정, 생명주기 무시(누수), offset 페이징.
- **Refactoring Patterns:** UI-로직 분리(ViewModel 추출), 동기화 계층 분리, 거대 위젯 분해, 네트워크 클라이언트 통합.
- **Real-world Tradeoffs:** 크로스플랫폼(RN/Flutter: 생산성 ↔ 네이티브 한계), 네이티브(성능/플랫폼 기능 ↔ 2벌 개발), 오프라인(UX ↔ 충돌 복잡도).
- **Design Heuristics:** "로컬을 진실로, 서버는 동기화", "메인 스레드를 비워라", "민감정보는 보안 저장소", "알림은 유도, 데이터는 동기화".
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
크로스플랫폼이 항상 답은 아니다 — 고성능/플랫폼 특화 기능이 중요하면 네이티브. OS 백그라운드 제약은 "정시 실행" 가정을 깬다.
## 🛠️ 적용 사례 (Applied in summary)
일반 모바일 앱. ConnectAI 직접 사례 없으나 오프라인/저장/백그라운드 원리는 [[패턴 카탈로그 인덱스]] 공유.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[플랫폼 개발 가이드 인덱스]]
- **관련 개념:** [[Offline Sync Pattern]], [[Local Storage Pattern]], [[Background Task Pattern]], [[Push Notification Pattern]], [[Navigation Pattern]]
- **참조 맥락:** 작은 모델이 모바일 앱을 설계할 때 상위 가이드로 참조.
## 📚 출처 (Sources)
- [S1] 일반 모바일(iOS/Android/RN/Flutter) 공학 지식
## 📝 변경 이력 (Change history)
- 2026-06-13: 플랫폼 독립 모바일 개발 가이드 초안.
@@ -0,0 +1,60 @@
---
id: platform-backend-api-development
title: "백엔드 API 개발 가이드"
category: "Platform_Engineering"
status: "draft"
verification_status: "conceptual"
canonical_id: ""
aliases: ["backend development", "백엔드 개발", "API design", "REST", "서버 아키텍처", "microservices"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.86
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["platform", "backend", "api", "guide", "platform-independent"]
raw_sources: ["일반 백엔드 공학 지식", "ConnectAI/src/bridge.ts (소규모 서버 적용 예)"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[백엔드 API 개발 가이드]]
## 🎯 한 줄 통찰 (One-line insight)
백엔드의 핵심은 "**계층 분리·명확한 API 계약·데이터 일관성·복원력(재시도/멱등/한도)·관측성**" 이며, 화려한 프레임워크보다 이 기본기가 신뢰성을 만든다.
## 🧠 핵심 개념 (Core concepts)
계층(라우터→서비스→리포지토리), API 계약(REST/GraphQL/RPC), 트랜잭션, 인증/인가, 멱등성, 레이트 리밋, 로깅/메트릭.
## 📖 세부 내용 (Details · 12-field)
- **Problem:** 동시 다수 클라이언트에 일관·안전·확장 가능한 데이터/로직 제공.
- **Recommended Architecture:** 계층형(라우터/컨트롤러 → 서비스(도메인) → 리포지토리(데이터)) + DTO 경계 + 의존성 주입. ([[Architecture Separation Pattern]])
- **Folder Structure:** `src/{routes|controllers, services, repositories, domain/models, middleware, infra(db,cache,queue), config}`.
- **Core Components:** 라우터/미들웨어, 서비스, 리포지토리([[Repository Pattern]]), 인증([[JWT Authentication Pattern]]), 캐시([[Caching Pattern]]), 큐/워커([[Background Worker Pattern]]), 에러 핸들러.
- **State Management:** 상태는 DB/캐시(서버는 가급적 무상태), 세션/토큰, 분산 락. SSOT.
- **Error Handling:** 표준 에러 응답(코드/메시지), 재시도(backoff)/서킷 브레이커, 멱등 키, 트랜잭션 롤백([[Error Handling Pattern]]).
- **Testing Strategy:** 단위(서비스/도메인), 통합(DB/리포), 계약 테스트(API), 부하 테스트.
- **Scaling Strategy:** 수평 확장(무상태), 캐시 계층, 읽기 복제/샤딩, 비동기 큐, 레이트 리밋, CDN.
- **Common Mistakes:** 컨트롤러에 비즈니스 로직, N+1 쿼리, 멱등성 부재(중복 처리), 트랜잭션 경계 오류, 검증 누락, 무한 재시도.
- **Refactoring Patterns:** 컨트롤러→서비스 로직 이동, 쿼리→리포지토리 캡슐화, 공통→미들웨어, 동기→큐 비동기화.
- **Real-world Tradeoffs:** 모놀리스(단순·일관 ↔ 확장/배포 결합) vs 마이크로서비스(독립 확장 ↔ 분산 복잡도/일관성), SQL(일관성 ↔ 확장) vs NoSQL(확장 ↔ 일관성), REST vs GraphQL.
- **Design Heuristics:** "서버 무상태로", "쓰기는 멱등하게", "경계에서 검증", "느린 작업은 큐로", "관측 가능하게(로그/메트릭/트레이스)".
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
마이크로서비스가 기본값은 아니다 — 대부분 모놀리스(또는 모듈러 모놀리스)로 시작해 *필요할 때* 분리하는 것이 안전(분산은 비싸다).
## 🛠️ 적용 사례 (Applied in summary)
ConnectAI BridgeServer(로컬 HTTP, 서비스 레이어로 로직 분리 — 소규모 백엔드의 계층 분리 예) [S2].
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[플랫폼 개발 가이드 인덱스]]
- **관련 개념:** [[Repository Pattern]], [[API Client Pattern]], [[JWT Authentication Pattern]], [[Caching Pattern]], [[Event Bus Pattern]], [[이벤트 소싱 스토어 패턴]]
- **참조 맥락:** 작은 모델이 서버/API 를 설계할 때 상위 가이드로 참조.
## 📚 출처 (Sources)
- [S1] 일반 백엔드/API 공학 지식
- [S2] ConnectAI/src/bridge.ts — 소규모 서버 계층 분리 예
## 📝 변경 이력 (Change history)
- 2026-06-13: 플랫폼 독립 백엔드 개발 가이드 초안.
@@ -0,0 +1,59 @@
---
id: platform-web-development
title: "웹 개발 가이드"
category: "Platform_Engineering"
status: "draft"
verification_status: "conceptual"
canonical_id: ""
aliases: ["web development", "웹 개발", "frontend", "SPA", "프런트엔드 아키텍처"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.86
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["platform", "web", "frontend", "guide", "platform-independent"]
raw_sources: ["일반 웹 공학 지식"]
applied_in: []
github_commit: ""
---
# [[웹 개발 가이드]]
## 🎯 한 줄 통찰 (One-line insight)
웹 개발의 본질은 프레임워크가 아니라 "**상태·비동기·데이터 흐름·에러·계층 분리**" 라는 반복 문제를 푸는 것 — 도구는 바뀌어도 원리는 [[패턴 카탈로그 인덱스]] 의 cross-cutting 패턴으로 수렴한다.
## 🧠 핵심 개념 (Core concepts)
선언형 UI, 컴포넌트, 단방향 데이터, 서버/클라 상태 분리, 라우팅, 번들링/코드 분할.
## 📖 세부 내용 (Details · 12-field)
- **Problem:** 다양한 디바이스/브라우저에서 반응적이고 유지보수 가능한 UI 와 데이터 동기화.
- **Recommended Architecture:** 컴포넌트 기반 + 단방향 데이터 + 서버 상태 라이브러리(react-query) + 기능별 폴더(feature-sliced). 무거운 로직은 도메인 계층으로 분리.
- **Folder Structure:** `src/{features/<feature>/{ui,api,model}, shared/{ui,lib,api}, app/(라우팅·프로바이더)}`. 기능 슬라이스 + 공유 계층.
- **Core Components:** 라우터, 데이터 페칭 계층([[API Client Pattern]]), 상태 store([[State Management Pattern]]/[[React State Pattern]]), 디자인 시스템, 에러 바운더리.
- **State Management:** 지역=useState, 서버=쿼리 캐시, 공유 도메인=가벼운 store, 공유 가능 상태=URL. (SSOT·단방향)
- **Error Handling:** 에러 바운더리(렌더 에러), 쿼리 에러/리트라이, 사용자 친화 메시지([[Error Handling Pattern]]).
- **Testing Strategy:** 단위(순수 로직)·컴포넌트(Testing Library)·E2E(Playwright). 피라미드(단위 多, E2E 少).
- **Scaling Strategy:** 코드 분할/지연 로드, 가상화([[Infinite Scroll Pattern]]), CDN/캐시, SSR/SSG(초기 로드·SEO), 이미지 최적화.
- **Common Mistakes:** 서버 데이터를 로컬 상태에 복사(stale), 전역 store 남용(리렌더), prop drilling, 거대 컴포넌트, 무분별 useEffect.
- **Refactoring Patterns:** 거대 컴포넌트 분해, 로직→커스텀 훅 추출, 페칭→쿼리 계층 이동, prop drilling→context/store.
- **Real-world Tradeoffs:** SSR(성능·SEO ↔ 복잡도), 전역 상태(편의 ↔ 결합), 마이크로프런트엔드(독립 배포 ↔ 운영 부담).
- **Design Heuristics:** "상태는 가장 낮은 곳, 공유되면 올린다", "서버 상태와 UI 상태 분리", "파생은 계산", "경계에서 검증".
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
프레임워크(React/Vue/Svelte)는 수단 — 채용/생태계로 고르되, 위 원리는 공통. "최신 프레임워크" 추종보다 상태/데이터 흐름 설계가 품질을 가른다.
## 🛠️ 적용 사례 (Applied in summary)
일반 SPA/웹앱. ConnectAI 웹뷰 UI 도 상태/메시지 원리는 동일.
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[플랫폼 개발 가이드 인덱스]]
- **관련 개념:** [[State Management Pattern]], [[React State Pattern]], [[API Client Pattern]], [[JWT Authentication Pattern]], [[Infinite Scroll Pattern]]
- **참조 맥락:** 작은 모델이 웹 프로젝트를 설계/구현할 때 상위 가이드로 참조.
## 📚 출처 (Sources)
- [S1] 일반 웹/프런트엔드 공학 지식
## 📝 변경 이력 (Change history)
- 2026-06-13: 플랫폼 독립 웹 개발 가이드 초안.
@@ -0,0 +1,110 @@
---
id: five-layer-memory-system
title: "5계층 메모리 시스템"
category: "AI_and_ML"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["cognitive memory", "메모리 시스템", "short-term", "long-term", "episodic", "procedural", "distillation", "memory layers"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.93
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["memory", "ai", "agent", "cognitive-architecture", "connectai"]
raw_sources: ["ConnectAI/src/memory/index.ts", "ConnectAI/src/memory/types.ts", "ConnectAI/src/retrieval/index.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[5계층 메모리 시스템]]
## 🎯 한 줄 통찰 (One-line insight)
LLM 에이전트의 "기억"은 인간 인지처럼 **시간 범위·용도가 다른 5개 계층(단기·장기·프로젝트·절차·일화)** 으로 나누고, 각 계층이 질의에 대해 관련도 점수를 매겨 컨텍스트에 합치는 것이 ConnectAI 의 설계다 [S1][S2].
## 🧠 핵심 개념 (Core concepts)
1. **① 단기(Short-Term):** 현재 대화 흐름. 최근 N개 메시지를 FIFO 로 유지(`shortTermLimit: 8`) [S1].
2. **② 장기(Long-Term):** 사용자 취향·규칙·결정·목표. category(`preference`/`rule`/`decision`/`goal`/`episode-digest`)와 confidence, 참조 횟수, 만료시각(`expiresAt`)을 가진 엔트리 [S2].
3. **③ 프로젝트(Project):** 워크스페이스별 지식 — 아키텍처 결정(ADR), 버그 기록, 요구사항, 기술스택, 코드 컨벤션. workspace 경로 hash 로 식별 [S2].
4. **④ 절차(Procedural):** 반복 작업의 절차서(skill.md). triggerPatterns 로 매칭(`["wiki화","위키","wikify"]`)해 steps 를 제공 [S2].
5. **⑤ 일화(Episodic):** 과거 세션의 요약·주요 결정·토픽. 시간이 지나면 distillation 으로 장기 digest 로 승급 [S2].
## 🧩 추출된 패턴 (Extracted patterns)
- **통합 매니저 + 계층 위임:** `MemoryManager` 가 5개 계층 객체를 보유하고 `buildContext()` 에서 각 계층의 `buildContext(query)` 를 호출해 결과를 모은다 — 계층은 독립, 매니저는 조립 [S1].
- **관련도 점수 + 정렬:** 각 계층이 `MemoryContextResult { layer, label, content, relevance }` 를 반환, 매니저가 `relevance` 내림차순 정렬 후 합침 [S1].
- **lazy 프로젝트 메모리:** `projectMemories: Map<string, ProjectMemory>` 로 워크스페이스별 지연 생성·캐시 [S1].
- **temporal marker 로 자동 만료:** `expiresAt < now` 인 엔트리는 검색·컨텍스트 구성에서 자동 제외 — "Q3 계획은 9/30까지만 유효" 같은 시한부 지식 [S2].
- **증류(Distillation) 폐루프:** 세션 종료 시 stale 일화를 장기 digest 로 승급하고 `promoted=true` 로 표시해 이후 검색에서 제외(중복 방지) [S1].
## 📖 세부 내용 (Details)
### 컨텍스트 조립 (핵심 API)
`buildContext(currentPrompt, visibleHistory, summarize, workspacePath)` 가 5계층에서 관련 컨텍스트를 모아 하나의 `[MEMORY CONTEXT]` 블록으로 만든다. 각 계층은 자기 데이터를 query 와 비교해 relevance 를 매기고, 빈 결과면 제외된다. 마지막에 "관련될 때만 사용하고, 충돌 시 현재 요청을 우선하라"는 지침을 덧붙인다 [S1].
### 세션 종료 시 추출·영속화
`onSessionEnd(sessionId, messages, workspacePath, distillationOpts)`:
1. `MemoryExtractor` 가 대화에서 장기/일화/프로젝트 메모리를 추출 (실패해도 본 흐름 안 깨짐 — 빈 catch).
2. 장기 메모리 `save()`.
3. distillation 이 enabled 이고 interval 충족 시 stale 일화를 장기 digest 로 승급 [S1].
### RAG 와의 결합
검색 오케스트레이터는 메모리 계층을 RAG 소스 중 하나로 끌어온다 — 장기/프로젝트/절차/일화 각각을 `RetrievalChunk` 로 변환하고, source 별 가중치(procedural 0.95, project 0.85, episodic 0.7)로 정규화한다 [S3]. → [[RAG 검색 파이프라인]].
### 설정 가능성
`MemoryConfig` 로 계층별 on/off 와 한도(`longTermMaxEntries: 100`, `episodicMaxEpisodes: 50`)를 조절. 생성자에서 `{ ...defaults, ...config }` 로 부분 오버라이드 [S1].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **계층 경계의 모호성:** "프로젝트 결정"이 장기 메모리(decision)인지 프로젝트 메모리(ADR)인지 겹칠 수 있다. ConnectAI 는 워크스페이스 종속성 유무로 가른다(프로젝트 종속이면 ③, 사용자 보편이면 ②).
- **만료 vs 보존:** `expiresAt` 로 시한부 지식을 자동 제외하지만, 만료된 지식이 "역사적 맥락"으로 필요할 때도 있다 — 검색은 제외하되 distillation 이 digest 로 보존하는 식으로 절충.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/memory/index.ts` — MemoryManager 의 buildContext/onSessionEnd 전체 흐름 [S1].
- `ConnectAI/src/memory/types.ts` — 5계층 데이터 형태, temporal marker, distillation 승급 필드 [S2].
- `ConnectAI/src/retrieval/index.ts``searchMemoryLayers` 가 계층을 RAG 청크로 변환 [S3].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 통합 매니저가 계층에 위임 + 관련도 정렬 (src/memory/index.ts)
public buildContext(prompt, history, summarize, workspacePath?): string {
const layers: MemoryContextResult[] = [];
const stm = this.shortTerm.buildContext(history, this.config.shortTermLimit, summarize);
if (stm) layers.push(stm);
const ltm = this.longTerm.buildContext(prompt);
if (ltm) layers.push(ltm);
// ... project / procedural / episodic 동일 패턴
if (!layers.length) return '';
layers.sort((a, b) => b.relevance - a.relevance); // 관련도 내림차순
return ['', '[MEMORY CONTEXT]', /* 지침 */, layers.map(l => `### ${l.label}\n${l.content}`).join('\n\n')].join('\n');
}
// 2) lazy 프로젝트 메모리 (src/memory/index.ts)
public getProjectMemory(workspacePath: string): ProjectMemory {
if (!this.projectMemories.has(workspacePath))
this.projectMemories.set(workspacePath, new ProjectMemory(workspacePath));
return this.projectMemories.get(workspacePath)!;
}
// 3) 부가 작업은 본 흐름을 깨지 않음 (src/memory/index.ts)
try { this.extractor.extractFromSession(...); } catch { /* never break main flow */ }
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.93
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[RAG 검색 파이프라인]], [[이벤트 소싱 스토어 패턴]], [[Agent 오케스트레이터 분해]]
- **참조 맥락:** 로컬 LLM 이 에이전트의 기억/컨텍스트 시스템을 설계하거나 메모리 계층 코드를 다룰 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/memory/index.ts — MemoryManager, buildContext, onSessionEnd, distillation 호출
- [S2] ConnectAI/src/memory/types.ts — 5계층 타입, temporal marker, 승급 필드
- [S3] ConnectAI/src/retrieval/index.ts — searchMemoryLayers(메모리→RAG 청크)
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,113 @@
---
id: agent-orchestrator-decomposition
title: "Agent 오케스트레이터 분해"
category: "AI_and_ML"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["agent executor", "orchestrator", "god class 분해", "multi-agent", "ChunkedWriter", "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: ["agent", "orchestrator", "multi-agent", "architecture", "ai", "connectai"]
raw_sources: ["ConnectAI/src/agent.ts", "ConnectAI/src/agents/AgentWorkflowManager.ts", "ConnectAI/src/agent/multiAgent/workflow.ts", "ConnectAI/src/features/company/dispatcher.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Agent 오케스트레이터 분해]]
## 🎯 한 줄 통찰 (One-line insight)
한 턴의 복잡한 처리(컨텍스트 조립→라우팅→스트리밍→후처리→학습)는 거대 orchestrator 하나가 *흐름의 골격만 쥐고 세부는 추출된 모듈에 위임*하는 구조가 유지보수에 유리하며, 멀티에이전트는 "병렬 persona 줄세우기"보다 **자원 제약에 맞춘 순차 실행 + 단일 작성자 다중 역할**이 로컬 환경에서 더 견고하다 [S1][S2][S4].
## 🧠 핵심 개념 (Core concepts)
1. **얇은 골격 + 추출 위임:** `agent.ts`(orchestrator)는 한 턴의 흐름을 읽을 수 있게 유지하고, 세부는 `handlePrompt/`, `llm/`, `actions/`, `sessions/`, `multiAgent/` 로 추출 [S1].
2. **Action tag 실행:** 모델 출력의 `<create_file>`, `<run_command>` 등 태그를 액션 실행기로 라우팅해 도구를 수행 [S1][S4].
3. **단일 작성자 다중 역할(ChunkedWriter):** outline → section[N] → polish 를 같은 모델이 번갈아 수행 — hop 마다 컨텍스트 폭증·본문 손실을 피함 [S2].
4. **순차 디스패치(company):** CEO 플래너 → 전문가들 순차 실행(peer-context 전달) → CEO 리포터 합성 [S4].
5. **mission 락:** 무거운 LLM 작업은 `missionId` 단위로 직렬화 [S2][참조: [[동시성 제어 Lock Queue Transaction]]].
## 🧩 추출된 패턴 (Extracted patterns)
- **God-class 분해:** orchestrator 의 import 가 100줄을 넘지만, 이는 "기능을 작은 모듈로 추출하고 흐름에서 다시 끌어모은" 결과 — 흐름은 한 곳, 구현은 분산 [S1].
- **메시지 프로토콜 UI:** webview 와 `streamStart`/`streamChunk`/`streamEnd`/`workflowStage` 메시지로 통신 — 진행 단계는 본문이 아니라 상단 인디케이터로 [S3].
- **모든 종료 경로에서 인디케이터 닫기:** 성공·취소·에러 어디서든 `workflowStage{done:true}` 를 보내 "영원히 도는 스피너" 방지 [S3].
- **peer-context 버퍼:** 앞 에이전트 출력을 잘라(`PEER_OUTPUT_BUDGET 1500`) 다음 에이전트 프롬프트에 전달 [S4].
- **raw 출력 → 공용 액션 실행기 재사용:** 전문가도 action tag 를 낼 수 있고, 채팅과 같은 실행기를 통과시켜 도구 동작 일관성 유지 [S4].
## 📖 세부 내용 (Details)
### 멀티에이전트 설계의 진화 (post-mortem)
초기엔 planner/researcher/reflector/writer/synthesizer 5개 persona 를 줄세웠다. 문제: 각 hop 마다 컨텍스트가 누적되고 *원본 본문이 추상화로 손실* 돼, 사용자가 본문 분석을 요청해도 "분석 방법론" 만 만들어내는 사고가 났다. → 현재는 단일 `ChunkedWriter` 가 outline/section/polish 세 역할을 같은 모델에서 번갈아 수행 — 각 호출이 작고 본문은 매 호출에 직접 전달돼 손실이 없다 [S2].
### 왜 순차 디스패치인가 (company 모드)
사용자는 단일 GPU/제한된 RAM 에서 Astra 를 돌린다. 병렬 에이전트는 여러 모델을 동시에 메모리에 상주시켜야 한다. 순차 실행은 "정확히 한 번에 하나의 모델만 상주" 를 보장하고, LM Studio lifecycle 매니저가 이전 모델을 unload 하고 다음을 load 한다 [S4]. → 이 위키의 sub-agent 제약(병렬 fanout 금지)과도 같은 원리.
### 왜 handlePrompt 를 재사용하지 않는가
`handlePrompt`*대화형* 경로용이라 대화 이력·스트리밍 UI·에이전트 모드 주입 등 12가지를 떠안는다. company 턴은 "system 1개 + user 1개 → 문자열 1개" 의 깨끗한 primitive 가 필요하므로 `AIService.chat()` 을 쓴다 — 책임이 다른 경로는 다른 primitive [S4].
## ⚖️ 비교 및 선택 기준 (Comparison & decision criteria)
| 멀티에이전트 방식 | 장점 | 단점 | 언제 |
|---|---|---|---|
| 병렬 persona N개 | 빠름(자원 충분 시) | 모델 다중 상주, 컨텍스트 누적/본문 손실 | RAM/GPU 넉넉한 서버 |
| 단일 작성자 다중 역할 | 컨텍스트 작고 본문 보존 | 한 모델 품질에 의존 | 로컬 단일 모델 |
| 순차 디스패치 | 한 번에 한 모델, 자원 안전 | 총 시간 김 | 단일 GPU/제한 RAM |
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **orchestrator 크기:** 분해했어도 agent.ts 가 크다 — "흐름 가독성" 을 위해 의도적으로 골격을 남긴 트레이드오프(완전 분해 시 흐름 추적이 파일 사이를 떠돈다).
- **순차의 비용:** 응답이 느리다. 사용자 경험을 위해 진행 단계를 webview 인디케이터로 보여 체감 지연을 완화한다.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/agent.ts` — orchestrator 골격 + 추출 모듈 import [S1].
- `ConnectAI/src/agents/AgentWorkflowManager.ts` — ChunkedWriter 단일 작성자 다중 역할 [S2].
- `ConnectAI/src/agent/multiAgent/workflow.ts` — webview 메시지 프로토콜, 모든 경로 인디케이터 닫기 [S3].
- `ConnectAI/src/features/company/dispatcher.ts` — 순차 디스패치, peer-context, 설계 근거 주석 [S4].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 단일 작성자 다중 역할 — 스테이지를 UI 라벨로 (src/agents/AgentWorkflowManager.ts)
const writer = new ChunkedWriter(modelName, overrides); // outline → section → polish
const engine = new AgentEngine(writer);
return await engine.runMission(missionId, prompt, brainContext, signal,
(stage, msg) => onProgress(this.mapStageToUI(stage), msg)); // ① 구조 → ② 본문 → ③ 다듬기
// 2) 모든 종료 경로에서 인디케이터 닫기 (src/agent/multiAgent/workflow.ts)
} catch (error: any) {
deps.getWebview()?.postMessage({ type: 'workflowStage', value: { step: '완료', done: true } });
if (error.name === 'AbortError') { /* 취소 */ return; }
// ... 에러 카드
} finally { deps.options.onStreamLifecycle?.end(); }
// 3) 순차 디스패치 + peer-context 버퍼 (src/features/company/dispatcher.ts, 개념)
let peerContext = '';
for (const task of plan.tasks) {
const prompt = buildSpecialistPrompt(task, peerContext); // 앞 에이전트 맥락 포함
const out = await aiService.chat({ system, user: prompt }); // 한 번에 한 모델만 상주
writeAgentOutput(sessionDir, task, out.content);
peerContext += '\n' + out.content.slice(0, PEER_OUTPUT_BUDGET); // 다음 에이전트에 전달
}
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.90
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[Intelligence 검증 레이어]], [[LLM 프로바이더 추상화]], [[동시성 제어 Lock Queue Transaction]], [[Agent Orchestration Pattern]]
- **참조 맥락:** 로컬 LLM 이 에이전트 실행 파이프라인·멀티에이전트 구조를 자원 제약 하에서 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/agent.ts — orchestrator 골격, 추출 모듈 import 구조
- [S2] ConnectAI/src/agents/AgentWorkflowManager.ts — ChunkedWriter, 멀티에이전트 진화 post-mortem
- [S3] ConnectAI/src/agent/multiAgent/workflow.ts — 메시지 프로토콜, 인디케이터 닫기
- [S4] ConnectAI/src/features/company/dispatcher.ts — 순차 디스패치 근거, peer-context, primitive 분리
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,127 @@
---
id: intelligence-verification-layer
title: "Intelligence 검증 레이어"
category: "AI_and_ML"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["self-evolving", "critic", "confidence engine", "epistemic guard", "correction loop", "anti-hallucination", "자기검증", "환각 방지"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.93
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["intelligence", "verification", "hallucination", "self-evolving", "ai", "connectai"]
raw_sources: ["ConnectAI/src/intelligence/criticAgent.ts", "ConnectAI/src/intelligence/confidenceEngine.ts", "ConnectAI/src/intelligence/epistemicGuardBlock.ts", "ConnectAI/src/intelligence/correctionLoop.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[Intelligence 검증 레이어]]
## 🎯 한 줄 통찰 (One-line insight)
작은 로컬 LLM 의 환각·오류를 시스템이 잡으려면 "**저렴한 결정론적 검사를 항상, 비싼 LLM 검사는 조건부로**" 돌리고, 사용자 정정 한 번을 시스템 성장으로 환원하는 폐루프가 핵심이며, ConnectAI 는 Epistemic Guard(사전 억제)·Confidence Engine(측정)·Critic(사후 검수)·Correction Loop(학습)로 이를 계층화한다 [S1][S2][S3][S4].
## 🧠 핵심 개념 (Core concepts)
1. **Epistemic Guard (사전):** 시스템 프롬프트에 "확실/추정/모름 3등급" 을 강제하는 블록을 주입. 검색 근거가 없을수록 지시가 강해진다("지어내지 말고 질문하라") [S3].
2. **Confidence Engine (측정):** LLM 호출 없이 검색 그라운딩 신호 + 답변 텍스트 신호(정규식)만으로 0~100 확신도를 *결정론적* 산출. latency 0 [S2].
3. **Critic Agent (사후):** 결정론적 검사가 문제를 신호할 때만 LLM 검수 1회 — 조건부 1-pass. 누락·근거 없는 단정·미결 구분을 검사 [S1].
4. **Correction Loop (학습):** 사용자 정정을 Ground Truth 로 보고 레슨 저장 + 회귀 케이스 적립 + 약점 프로필 → 다음 턴 프롬프트에 자동 주입 [S4].
5. **CoVe vs Epistemic Guard 분업:** CoVe 는 출처가 *있을 때* 주장-출처 매핑 검증, Epistemic Guard 는 출처 *유무 무관* 등급 표시 강제 [S3].
## 🧩 추출된 패턴 (Extracted patterns)
- **저렴한 것 항상, 비싼 것 조건부:** 결정론적(정규식/카운트) 검사는 매 턴, LLM 검수는 신호가 있을 때만 — 로컬 모델 latency 비용 통제 [S1][S2].
- **"확신도는 모델 자신감이 아니라 검증 가능성":** 모델이 솔직히 "(확인 필요)" 를 쓰면 점수가 *내려가는* 게 올바른 동작 — 사용자 검토를 유도해야 하므로 [S2].
- **가중치 합산 + factor 기록:** 확신도를 요인별 delta 합으로 계산하고 각 factor 를 footer 에 노출 — 점수가 왜 그렇게 나왔는지 설명가능 [S2].
- **정답지를 사람이 안 만든다:** 정정 발화 자체가 Ground Truth. 회귀 테스트가 "같은 실수 반복?" 을 LLM-judge 로 판정 [S4].
- **통찰→행동의 기계화:** 태그 통계가 리포트에 머물지 않고 `buildSelfReviewBlock` 으로 다음 턴 시스템 프롬프트를 바꾼다(같은 태그 2회+일 때만) [S4].
- **JSON 강건 파싱:** LLM 의 JSON 출력에 잡설이 섞여도 첫 균형 `{}` 블록을 스캔해 추출 [S1].
- **fire-and-forget 캡처:** 정정 캡처는 비동기로 흘려 응답 속도에 영향 없음 [S4].
## 📖 세부 내용 (Details)
### Confidence Engine — 결정론적 가중 합산
중립 출발점 55에서 시작해 요인별로 가감한다 [S2]:
- 그라운딩: 청크 3건+ & topScore 0.5+ → +25, 1건+ → +12, 없음 → -15.
- 출처 인용 +8 / 모델 지식만 -5.
- 출처 충돌 건당 -8(최대 -16), 요청 모호성 -10.
- Requirement 커버리지 전부 충족 +10 / 누락당 -6(최대 -18).
- 헤지 표현 개당 -4(최대 -12).
구간: 90+ 높음 / 70-89 보통 / 50-69 낮음 / <50 매우 낮음(에스컬레이션).
### Critic — 조건부 1-pass 검수
완전한 작성→비판→재작성 debate 는 로컬 Gemma latency 때문에 미룬다. v1 은 "커버리지 누락 또는 확신도 <70" 일 때만 Critic LLM 1회 호출, 결과를 답변 아래 보완 카드로 표시. `maxRounds` knob 만 준비해 두고 다회전은 후속 [S1].
### Correction Loop — 정정 1회가 3곳을 성장
```
사용자 정정 → ① 감지(보수적 정규식) + LLM 분류(6개 오류 태그)
├→ 태깅된 레슨 저장 (lessons/)
└→ 회귀 케이스 적립 (.astra/eval/corrections.jsonl)
② 주간 성장 사이클: 회귀 재검사 + 태그 통계 → 약점 프로필
③ 약점 프로필 → 시스템 프롬프트 자기검토 블록 자동 주입
```
설계 원칙: 정답지는 정정 자체, 통찰→행동은 기계적, 모든 산출물은 사람이 열어 수정/삭제 가능(Permission Based Learning), 캡처는 fire-and-forget [S4].
### 폭주 방지 장치들
- 자기검토 블록은 같은 태그 2회+일 때만(1회성 실수로 프롬프트 어지럽힘 방지) [S4].
- 지식 공백 학습 큐는 같은 질문 1회만 등록(해시 id) + proposed 20건 쌓이면 사람이 정리할 때까지 중단 [S4].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **휴리스틱 가중치의 임시성:** Confidence 가중치는 "휴리스틱 v1" 으로, 골든셋이 쌓이면 사람 평가와의 상관으로 보정 예정 — 현재 절대 점수보다 *상대 비교* 와 추세에 의미가 있다.
- **정규식 정정 감지의 한계:** 보수적이라 미묘한 정정("음 그건 좀…")은 놓친다. 오탐이 레슨 노이즈를 만들기에 의도적으로 보수적.
- **Critic 의 1-pass 한계:** 다회전 debate 가 더 정확하지만 비용 때문에 보류 — 정확도 vs latency 트레이드오프의 현실적 타협.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/intelligence/confidenceEngine.ts` — 결정론적 확신도 + footer [S2].
- `ConnectAI/src/intelligence/criticAgent.ts` — 조건부 검수 + 균형 JSON 파싱 [S1].
- `ConnectAI/src/intelligence/epistemicGuardBlock.ts` — 사전 억제 프롬프트 [S3].
- `ConnectAI/src/intelligence/correctionLoop.ts` — 정정→레슨→약점프로필→프롬프트 폐루프 [S4].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 결정론적 확신도 — 요인별 delta 합산 + 설명가능 (src/intelligence/confidenceEngine.ts)
let score = 55; // 중립 출발점
if (retrieval.chunkCount >= 3 && retrieval.topScore >= 0.5) factors.push({ label: '검색 근거 강', delta: +25 });
else if (retrieval.chunkCount >= 1) factors.push({ label: '검색 근거 있음', delta: +12 });
else factors.push({ label: '검색 근거 없음', delta: -15 });
if (answer.hedgeCount > 0) factors.push({ label: '불확실 표시', delta: -Math.min(12, answer.hedgeCount * 4) });
for (const f of factors) score += f.delta;
score = Math.max(0, Math.min(100, Math.round(score))); // 0~100 clamp
// 2) 균형 괄호 JSON 추출 — LLM 잡설 내성 (src/intelligence/criticAgent.ts)
let depth = 0, end = -1, inString = false, escaped = false;
for (let i = start; i < raw.length; i++) {
const ch = raw[i];
if (escaped) { escaped = false; continue; }
if (ch === '\\') { escaped = true; continue; }
if (ch === '"') { inString = !inString; continue; }
if (inString) continue;
if (ch === '{') depth++; else if (ch === '}' && --depth === 0) { end = i; break; }
}
// 3) 통찰→행동 — 약점 통계를 다음 턴 프롬프트로 (src/intelligence/correctionLoop.ts)
const significant = profile.tagCounts.filter(t => t.count >= 2).slice(0, 2); // 2회+만
// → "너는 최근 '사실오류' 정정을 N회 받았다. 수치·날짜는 근거 없으면 '확인 필요'로 표시하라."
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.93
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[의존성 주입과 서비스 인터페이스]], [[프롬프트 엔지니어링 패턴]], [[Agent 오케스트레이터 분해]]
- **참조 맥락:** 로컬 LLM 이 자기검증·환각 억제·피드백 학습 루프를 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/intelligence/criticAgent.ts — 조건부 검수, 균형 JSON 파싱, 함수 주입
- [S2] ConnectAI/src/intelligence/confidenceEngine.ts — 결정론적 확신도 산출
- [S3] ConnectAI/src/intelligence/epistemicGuardBlock.ts — 3등급 인식론 가드
- [S4] ConnectAI/src/intelligence/correctionLoop.ts — 정정 폐루프, 약점 프로필, 폭주 방지
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,124 @@
---
id: llm-provider-abstraction
title: "LLM 프로바이더 추상화"
category: "AI_and_ML"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["provider abstraction", "adapter pattern", "LLM 라우팅", "prefix routing", "SSE", "스트리밍", "엔진 폴백"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.92
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["llm", "provider", "adapter", "streaming", "sse", "connectai"]
raw_sources: ["ConnectAI/src/features/providers/types.ts", "ConnectAI/src/features/providers/index.ts", "ConnectAI/src/features/providers/anthropic.ts", "ConnectAI/src/core/services.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[LLM 프로바이더 추상화]]
## 🎯 한 줄 통찰 (One-line insight)
여러 LLM 공급자(로컬 LM Studio/Ollama, 클라우드 OpenRouter/Anthropic/Gemini)를 한 코드에서 쓰려면 "**model id prefix 로 라우팅 + 공급자별 어댑터가 차이를 흡수 + 모두 같은 SSE 포맷으로 정규화**"가 핵심이며, ConnectAI 는 이 어댑터 패턴으로 호출부를 공급자 무관하게 유지한다 [S1][S2].
## 🧠 핵심 개념 (Core concepts)
1. **Prefix 라우팅:** `anthropic:claude-...`, `gemini:...`, `openrouter:...` 처럼 model id 의 접두사로 공급자를 결정. 접두사 없으면 로컬 엔진 [S1].
2. **어댑터 패턴:** 공급자마다 `streamX(context, params)` 함수가 그 API 의 차이(인증·바디·스트림 형식)를 흡수하고 표준 인터페이스(`StreamParams`)를 받는다 [S2][S3].
3. **출력 정규화(SSE):** 각 어댑터가 응답 스트림을 *OpenAI 호환 SSE* 로 변환해 반환 → 기존 SSE 파서 하나로 모두 소비 [S2][S3].
4. **로컬 엔진 폴백:** 로컬은 LM Studio↔Ollama 간 자동 폴백(전송 오류/5xx/빈 응답 시) [S4].
5. **에러 응답 passthrough:** 인증 실패·4xx·5xx 는 `.ok=false` Response 로 그대로 반환, 호출부가 `.text()` 로 메시지 추출 [S2][S3].
## 🧩 추출된 패턴 (Extracted patterns)
- **양방향 prefix 변환:** `parseModelPrefix(id)`(분해) ↔ `makeModelId(provider, model)`(조립) — UI/config 저장과 라우팅이 1:1 [S1].
- **switch dispatch:** `streamCloudCompletion``switch (hit.provider)` 로 어댑터 선택 — 공급자 추가는 case 하나 [S2].
- **입력 정규화(공급자 제약 흡수):** Anthropic 어댑터는 (1) system 을 top-level 로 분리, (2) 연속 같은 role 병합(교대 강제), (3) 첫 메시지 user 강제(dummy 삽입) [S3].
- **활성 공급자만 병렬 조회:** `listAllCloudModels` 가 enabled+apiKey 인 공급자만 `Promise.all` 로 모델 목록 수집 [S2].
- **하드코딩 fallback 목록:** 모델 list API 가 없는 공급자(Anthropic)는 알려진 모델 목록을 반환하되 사용자 직접 입력도 허용(validate 안 함) [S3].
## 📖 세부 내용 (Details)
### prefix 를 왜 쓰는가
같은 model name 이 OpenRouter 와 직통에 동시 존재할 수 있어 출처를 명시해야 라우팅이 모호하지 않다. 또 UI 드롭다운 그룹화('OpenRouter · ...')와, 접두사 없는 옛 설정('gemma4:e2b')의 자동 로컬 경로 처리에 유리하다 [S1].
### 어댑터가 흡수하는 차이 (Anthropic 예)
- base URL `https://api.anthropic.com/v1`, 인증 `x-api-key` + `anthropic-version` 헤더.
- system 은 messages 가 아니라 top-level `system` 필드 → 어댑터가 분리·병합.
- role 교대 강제 → 연속 같은 role 병합.
- 응답 스트림이 OpenAI 와 다른 event 형식 → `transformAnthropicStream` 으로 변환 후 새 `Response` 로 wrap [S3].
이 정규화 덕분에 상위 `agent.ts` 의 스트림 파서는 공급자를 전혀 모른다 — "차이는 가장자리(어댑터)에서 흡수, 중심은 단일 포맷".
### 로컬 엔진 폴백 (services.ts)
`AIService.chat` 은 사용자 설정 엔진을 먼저 시도하고, 전송 오류/HTTP 실패/빈 응답이면 다른 엔진으로 폴백한다. 빈 응답은 soft failure 로 취급해 재시도, 두 엔진 모두 빈 응답이면 `empty: true` 결과를 반환해 호출부가 사용자에게 안내하게 한다(예외 삼키지 않음) [S4].
## ⚖️ 비교 및 선택 기준 (Comparison & decision criteria)
| 접근 | 장점 | 단점 | 언제 |
|---|---|---|---|
| prefix 라우팅 | 모호성 없음, UI 그룹화 | id 규칙 학습 필요 | 다중 공급자/중복 모델명 |
| 어댑터별 함수 | 차이 격리, 추가 쉬움 | 공급자마다 구현 | 공급자 API 가 제각각일 때 |
| 공통 SSE 정규화 | 파서 1개로 통일 | 변환 레이어 비용 | 스트리밍 다공급자 |
| 로컬↔로컬 폴백 | 가용성↑ | 지연 증가 가능 | 로컬 엔진 불안정 환경 |
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **하드코딩 모델 목록의 노후화:** Anthropic 어댑터의 모델 목록은 작성 시점 기준이라 시간이 지나면 낡는다. 사용자 직접 입력을 허용해 완화하지만, 최신 모델 사용 시 id 를 직접 넣어야 한다.
- **prompt caching/tool use 미구현:** 어댑터 주석이 "향후 확장 여지(prompt caching, tool use)"를 명시 — 현재는 단순 streaming 만. 비용 최적화·구조화 호출은 후속 과제.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/features/providers/index.ts` — streamCloudCompletion switch dispatch, listAllCloudModels 병렬 [S2].
- `ConnectAI/src/features/providers/anthropic.ts` — 입력 정규화 + SSE 변환 + 에러 passthrough [S3].
- `ConnectAI/src/features/providers/types.ts` — parseModelPrefix/makeModelId [S1].
- `ConnectAI/src/core/services.ts` — 로컬 엔진 폴백 [S4].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) prefix 라우팅 (src/features/providers/types.ts)
export function parseModelPrefix(id: string): { provider: ProviderId; model: string } | null {
for (const { prefix, id: pid } of PROVIDER_PREFIXES)
if (id.startsWith(prefix)) return { provider: pid, model: id.slice(prefix.length) };
return null; // null = 로컬 엔진 경로
}
// 2) switch dispatch — 공급자 추가는 case 하나 (src/features/providers/index.ts)
switch (hit.provider) {
case 'openrouter': return streamOpenRouter(context, fullParams);
case 'anthropic': return streamAnthropic(context, fullParams);
case 'gemini': return streamGemini(context, fullParams);
}
// 3) 입력 정규화로 공급자 제약 흡수 (src/features/providers/anthropic.ts)
for (const m of params.messages) {
if (m.role === 'system') systemPrompt += (systemPrompt ? '\n\n' : '') + m.content; // top-level 분리
else { const last = messages.at(-1);
if (last?.role === m.role) last.content += '\n\n' + m.content; // 같은 role 병합
else messages.push({ role: m.role, content: m.content }); }
}
if (messages[0]?.role !== 'user') messages.unshift({ role: 'user', content: '(continue)' }); // 첫 user 강제
// 4) 응답 스트림을 공통 SSE 로 정규화
const transformed = transformAnthropicStream(upstream.body);
return new Response(transformed, { status: 200, headers: { 'Content-Type': 'text/event-stream' } });
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.92
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[비동기 프로그래밍 Promise async await]], [[의존성 주입과 서비스 인터페이스]], [[Agent 오케스트레이터 분해]]
- **참조 맥락:** 로컬 LLM 이 다중 LLM 공급자/외부 API 를 어댑터로 통합하는 코드를 작성할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/features/providers/types.ts — prefix 라우팅, makeModelId
- [S2] ConnectAI/src/features/providers/index.ts — switch dispatch, 병렬 모델 조회
- [S3] ConnectAI/src/features/providers/anthropic.ts — 입력 정규화, SSE 변환, 에러 passthrough
- [S4] ConnectAI/src/core/services.ts — 로컬 엔진 폴백
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,115 @@
---
id: rag-retrieval-pipeline
title: "RAG 검색 파이프라인"
category: "AI_and_ML"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["RAG", "retrieval", "검색 증강 생성", "하이브리드 검색", "context budget", "rerank", "chunking", "orchestrator"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.92
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["rag", "retrieval", "ai", "search", "embedding", "connectai"]
raw_sources: ["ConnectAI/src/retrieval/index.ts", "ConnectAI/src/retrieval/chunker.ts", "ConnectAI/src/retrieval/scoring.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[RAG 검색 파이프라인]]
## 🎯 한 줄 통찰 (One-line insight)
RAG 는 "질문에 답하기 전에 관련 지식을 찾아 컨텍스트에 넣는" 기법이며, ConnectAI 의 오케스트레이터는 **질의 계획 → 다중 소스 병렬 검색 → 점수 정규화·재가중 → 토큰 예산 내 선택** 의 4단계로 brain 파일·5계층 메모리·최근 세션을 하나의 컨텍스트로 융합한다 [S1].
## 🧠 핵심 개념 (Core concepts)
1. **소스 융합(Fusion):** brain 파일(TF-IDF/하이브리드), 메모리 계층, 중기(최근 세션)를 각각 검색해 `RetrievalChunk[]` 로 모은다 [S1].
2. **점수 정규화:** 소스마다 점수 스케일이 달라, 소스별로 0~1 정규화 후 source 우선순위 가중치를 곱한다 [S1].
3. **재가중(Re-rank):** Actionability(현재 작업 상태 신호)와 Hierarchical(질의·문서 추상도 매칭)로 점수를 조정 [S1].
4. **토큰 예산(Context budget):** 모델 컨텍스트 한도 내에서 점수 높은 청크만 선택, 나머지는 drop [S1].
5. **섹션 청킹:** 긴 문서를 헤딩 경계로 쪼개 정밀도를 높이는 선택적 경로 [S2]. → [[TF-IDF 이중언어 스코어링]].
## 🧩 추출된 패턴 (Extracted patterns)
- **단계별 fusionLog:** 각 단계가 `fusionLog.push(...)` 로 무엇을 했는지 기록 — 검색이 왜 그 결과를 냈는지 추적·디버깅 가능 [S1].
- **`??` 로 의미 있는 0 보존:** `brainFileLimit ?? 8` — Knowledge Mix "모델 지식만" 모드가 명시적 0 을 보내면 검색을 건너뛴다(`|| 8` 이면 0이 8로 둔갑) [S1].
- **하이브리드 blend(sparse+dense):** TF-IDF 점수를 top 값으로 정규화하고 임베딩 cosine 과 `(1-α)·sparse + α·dense` 로 혼합. 벡터 없는 문서는 순수 TF-IDF 유지 [S1].
- **per-file cap:** 한 문서가 상위 슬롯을 독식하지 않게 파일당 청크 수를 3개로 제한 [S1].
- **운영 로그 제외:** 세션/메모리/회사 로그 폴더는 "지식"이 아니므로 검색에서 제외(`isOperationalPath`) — 노이즈·토큰 낭비 차단 [S1].
- **레슨 카드 가산:** 짧고 신호 강한 레슨 카드는 top-limit 밖이어도 추가로 끌어오고 1.4× 가중 [S1].
## 📖 세부 내용 (Details)
### 4단계 흐름 (`retrieve`)
```
① Query Planning : tokenize → expandQuery(동의어 확장)
② Parallel Search : Brain(TF-IDF/하이브리드) + Memory 계층 + Medium-term(최근 세션)
③ Result Fusion : normalizeScores(소스별 0~1 + source boost) → actionability/hierarchical re-rank
④ Context Budget : selectWithinBudget(점수순, 토큰 한도 내) → lesson 청크 분리 추출
```
반환에는 선택/탈락 청크, 레슨 청크, 사용 토큰, fusionLog 가 포함된다 [S1].
### 하이브리드 검색의 스케일 함정 (주석에 기록된 실측 버그)
1. *모든* 후보를 maxTfidf 로 정규화해야 한다 — 벡터 있는 것만 0..1 로 줄이면 벡터 없는 후보의 raw 점수(≫1)가 상위를 독식해 blend 가 무효가 된다.
2. cosine 은 후보군 내 min-max 정규화 — 임베딩 모델은 무관 문서끼리도 cos 0.5~0.7 이 나와, 절대값 가산이 균일 노이즈로 sparse 정밀도를 흐린다 [S1].
### 성능 — mtime 인덱스
`getBrainTokenIndex` 는 파일 mtime 기준 영속 인덱스라, 변경 없는 파일은 재읽기·재토큰화하지 않는다. 큰 brain 에서 질의당 작업량이 O(전체 내용) → O(파일 수)로 떨어진다. 실제 디스크 읽기는 *선택된 파일* 의 발췌 추출 때만 발생 [S1].
### 평가 무결성
`rankBrainForEval` 은 프로덕션 `retrieve`*동일한 scoring 경로*(`searchBrainFiles`)를 재사용한다 — recall@k/MRR 측정이 실제 검색 동작을 반영하도록 [S1].
## ⚖️ 비교 및 선택 기준 (Comparison & decision criteria)
| 검색 방식 | 장점 | 단점 | 언제 |
|---|---|---|---|
| TF-IDF (sparse) | 키워드 정확, 인덱스 가벼움, 설명가능 | 의미 유사 놓침 | 임베딩 엔진 없을 때 기본 |
| 임베딩 (dense) | 의미 유사 포착 | 무관 문서도 높은 cos, 비용 | 동의·환언 많은 질의 |
| 하이브리드 blend | 둘의 장점 결합 | 스케일 정규화 까다로움 | 임베딩 가용 시 권장 |
| 섹션 청크 | 긴 문서 정밀도↑ | 인덱스 크기↑ | 다주제 장문 brain |
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **청크 vs 파일 단위:** 섹션 청킹은 정밀도를 높이지만 회귀 위험이 있어 파일 단위 경로와 분리(`chunkLevelRetrieval` 플래그)해 격리했다 — 점진 도입 전략.
- **재가중의 위험:** actionability/hierarchical 가중이 과하면 키워드 정합이 약한 문서가 떠오를 수 있다. 그래서 정규화 *후, 예산 선택 전* 에 적용해 영향 범위를 통제한다.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/retrieval/index.ts` — RetrievalOrchestrator 의 retrieve/searchBrainFiles/searchBrainChunks/normalizeScores 전체 [S1].
- `ConnectAI/src/retrieval/chunker.ts` — 헤딩 경계 섹션 청킹(순수 함수) [S2].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 의미 있는 0 보존 — Knowledge Mix "모델 지식만" 모드 (src/retrieval/index.ts)
const brainFileLimit = options.brainFileLimit ?? 8; // ?? : 명시적 0 을 0으로 존중
const brainChunks = brainFileLimit > 0 ? this.searchBrainFiles(...) : [];
// 2) 소스별 정규화 + 우선순위 가중 (src/retrieval/index.ts)
for (const [, group] of groups) {
const maxScore = Math.max(...group.map(c => c.score), 0.001);
for (const c of group) c.score /= maxScore; // 소스 내 0~1 정규화
}
const sourceBoost = { 'procedural-memory': 0.95, 'brain-memory': 0.9, 'episodic-memory': 0.7 /* ... */ };
for (const c of chunks) { c.score *= (sourceBoost[c.source] ?? 0.5); if (c.metadata.isLesson) c.score *= 1.4; }
// 3) 하이브리드 blend — 모든 후보를 같은 스케일로 (src/retrieval/index.ts)
const sparse = s.score / maxTfidf;
s.score = cos === null ? sparse : (1 - alpha) * sparse + alpha * ((cos - minCos) / span);
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.92
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[TF-IDF 이중언어 스코어링]], [[5계층 메모리 시스템]], [[Agent 오케스트레이터 분해]]
- **참조 맥락:** 로컬 LLM 이 검색 증강·컨텍스트 조립·점수 융합 코드를 설계할 때 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/retrieval/index.ts — RetrievalOrchestrator(4단계, fusion, 하이브리드, 예산, 평가)
- [S2] ConnectAI/src/retrieval/chunker.ts — 섹션 청킹 순수 함수
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.
@@ -0,0 +1,121 @@
---
id: tfidf-bilingual-scoring
title: "TF-IDF 이중언어 스코어링"
category: "AI_and_ML"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["TF-IDF", "토크나이저", "tokenizer", "한국어 영어 토큰화", "동의어 확장", "검색 점수", "stop words", "섹션 청킹"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.92
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["tfidf", "tokenizer", "search", "nlp", "korean", "connectai"]
raw_sources: ["ConnectAI/src/retrieval/scoring.ts", "ConnectAI/src/retrieval/chunker.ts"]
applied_in: ["ConnectAI"]
github_commit: ""
---
# [[TF-IDF 이중언어 스코어링]]
## 🎯 한 줄 통찰 (One-line insight)
임베딩 엔진 없이도 쓸 수 있는 가벼운 검색의 핵심은 "좋은 토크나이저 + TF-IDF 가중"이며, ConnectAI 는 **한국어/영어 혼합 토크나이저·불용어·동의어 확장·제목 가중·충돌 신호** 를 더해 단순 `includes()` 매칭을 넘어선 점수를 낸다 [S1].
## 🧠 핵심 개념 (Core concepts)
1. **TF-IDF:** 용어 빈도(TF, 문서 내 흔함) × 역문서빈도(IDF, 전체에서 희소함). 흔하면서 그 문서에만 자주 나오는 단어가 고득점 [S1].
2. **이중언어 토큰화:** 한글-영문 경계를 분리(`성능optimization``성능` `optimization`), 특수기호 보존(C++, C#, .net) [S1].
3. **불용어(Stop words):** 검색에 무의미한 단어(영/한 각각 집합)를 제거 [S1].
4. **동의어 확장:** 질의 토큰을 관련어로 확장(`성능``performance`, `optimization`, `최적화`) [S1].
5. **제목 가중:** 제목 일치는 본문보다 3배 가중(`TITLE_MULTIPLIER: 3.0`) [S1].
6. **토큰 캐시:** 같은 텍스트의 토큰화를 Map 으로 캐시(한도 초과 시 전체 clear) [S1].
## 🧩 추출된 패턴 (Extracted patterns)
- **중앙 설정 객체:** `SCORING_CONFIG` 에 불용어·동의어·임계값·가중치를 모아 한 곳에서 조정 [S1].
- **경계 분리 정규식:** `replace(/([a-z0-9]+)([가-힣]+)/gi, '$1 $2')` 로 언어 경계 분할, `split(/[^a-z0-9가-힣+#.-]+/g)` 로 특수기호(C++) 보존 [S1].
- **TF 계산 1회화:** `buildTermCounts` 로 문서당 용어 빈도 맵을 한 번 만들고 질의 용어마다 재사용 — O(질의×문서) 재스캔 회피 [S1].
- **IDF smoothing:** 문서 수가 적을 때도 안정적이도록 평활화 적용 [S1].
- **충돌 신호 탐지:** "반대/충돌/conflict/vs" 등 지표 단어 수로 conflictSeverity 산출 — 지식 충돌 가능 문서를 표시 [S1].
- **순수 함수 분리:** chunker/scoring 은 fs·네트워크 의존 없는 순수 함수라 단위 테스트·재현이 쉽다 [S2].
## 📖 세부 내용 (Details)
### 토크나이저 (가장 중요한 부품)
```typescript
const normalized = text.toLowerCase()
.replace(/[-]/g, '') // zero-width 제거
.replace(/[^\w\s가-힣_+#.-]/g, ' '); // 의미 없는 기호 → 공백
const splitText = normalized
.replace(/([a-z0-9]+)([가-힣]+)/gi, '$1 $2') // 영→한 경계 분리
.replace(/([가-힣]+)([a-z0-9]+)/gi, '$1 $2');// 한→영 경계 분리
const tokens = splitText.split(/[^a-z0-9가-힣+#.-]+/g) // C++, C#, .net 보존
.map(t => t.trim().replace(/[.,]$/g, ''))
.filter(t => /[가-힣]/.test(t) ? t.length >= 1 : t.length >= 2) // 한글 1자+, 영문 2자+
.filter(t => !STOP_EN.has(t) && !STOP_KO.has(t));
```
한국어는 한 글자도 의미를 가질 수 있어 1자 이상 허용, 영문은 2자 이상으로 노이즈를 줄인다 [S1].
### 동의어 확장
질의 `[성능]``[성능, performance, optimization, 최적화, speed]`. Set 으로 중복 제거 후 반환. brain 문서가 영어로, 질의가 한국어로 와도(또는 반대) 매칭되게 하는 양국어 다리 [S1].
### 섹션 청킹과의 결합
긴 문서를 통째 색인하면 5000자 다주제 문서가 흐릿한 한 단위가 되어 정밀도가 떨어진다. `chunker.ts` 가 헤딩(`#`~`######`) 경계로 섹션을 나누고, 짧은 섹션은 병합·긴 섹션은 문단 경계로 재분할한다. fenced code block(```) 안의 `#` 는 헤딩으로 보지 않는다. 헤딩 breadcrumb 을 보존해 청크가 문맥을 잃지 않게 한다 [S2].
## ⚖️ 모순 및 업데이트 (Contradictions & updates)
- **TF-IDF 의 한계:** 어휘가 다르면(동의어 사전에 없는 환언) 못 잡는다. 그래서 임베딩 하이브리드로 보완한다 → [[RAG 검색 파이프라인]].
- **동의어 사전의 유지보수:** 수작업 사전이라 도메인이 늘면 누락이 생긴다. 핵심 도메인 용어 위주로 관리하는 절충.
- **형태소 분석 부재:** 한국어 조사/어미를 정밀 분해하지 않는다(경량 우선). 정밀도가 더 필요하면 형태소 분석기 도입 여지.
## 🛠️ 적용 사례 (Applied in summary)
- `ConnectAI/src/retrieval/scoring.ts` — tokenize/expandQuery/TF-IDF/충돌 탐지 [S1].
- `ConnectAI/src/retrieval/chunker.ts` — splitIntoSections 섹션 청킹 [S2].
## 💻 코드 패턴 (Code patterns)
```typescript
// 1) 중앙 설정 객체 — 가중치/임계값 한 곳에서 (src/retrieval/scoring.ts)
const SCORING_CONFIG = {
STOP_WORDS_EN: new Set(['the','a','and',/* ... */]),
STOP_WORDS_KO: new Set(['그리고','그런데',/* ... */]),
SYNONYM_DATA: [['성능', ['performance','optimization','최적화','speed']], /* ... */],
TITLE_MULTIPLIER: 3.0,
GLOBAL_CACHE_LIMIT: 2000,
};
// 2) TF 계산 1회화 (src/retrieval/scoring.ts)
function buildTermCounts(tokens: string[]): Map<string, number> {
const counts = new Map<string, number>();
for (const t of tokens) counts.set(t, (counts.get(t) || 0) + 1);
return counts; // 질의 용어마다 재스캔 대신 이 맵을 조회
}
// 3) 동의어 확장 (src/retrieval/scoring.ts)
export function expandQuery(tokens: string[]): string[] {
const expanded = new Set(tokens);
for (const t of tokens) (synonymMap.get(t) ?? []).forEach(s => expanded.add(s));
return Array.from(expanded);
}
// 4) 헤딩 경계 섹션 청킹 — fence 안의 # 무시 (src/retrieval/chunker.ts)
const fence = line.trimStart().startsWith('```'); if (fence) inFence = !inFence;
const m = !inFence ? line.match(HEADING_RE) : null; // 코드블록 내 #는 헤딩 아님
```
## ✅ 검증 상태 및 신뢰도
- **상태:** draft
- **검증 단계:** applied
- **출처 신뢰도:** A
- **신뢰 점수:** 0.92
- **중복 검사 결과:** 신규 생성 (New discovery)
## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[ConnectAI 아키텍처 개요]]
- **관련 개념:** [[RAG 검색 파이프라인]], [[5계층 메모리 시스템]], [[TypeScript 기초와 타입 시스템]]
- **참조 맥락:** 로컬 LLM 이 가벼운 텍스트 검색·토큰화·점수 함수를 작성할 때(특히 한/영 혼용) 참조.
## 📚 출처 (Sources)
- [S1] ConnectAI/src/retrieval/scoring.ts — 토크나이저, TF-IDF, 동의어, 불용어, 충돌 탐지, 캐시
- [S2] ConnectAI/src/retrieval/chunker.ts — 섹션 청킹(순수 함수)
## 📝 변경 이력 (Change history)
- 2026-06-13: ConnectAI 코드 분석 기반 초안 생성.