Metadata-Version: 2.4
Name: hair-platform
Version: 0.1.3
Summary: HAIR(Human-AI Resource Management) 협업 플랫폼 — 사람과 AI Agent를 하나의 조직도에서 배치·배분·승인·성과리뷰하는 도구. AgentForge의 자매 프로젝트.
License-Expression: MIT
Project-URL: Homepage, https://github.com/bullpeng72/HAIR-Platform
Project-URL: Repository, https://github.com/bullpeng72/HAIR-Platform
Project-URL: Issues, https://github.com/bullpeng72/HAIR-Platform/issues
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Framework :: FastAPI
Classifier: Operating System :: OS Independent
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic<3.0,>=2.0
Requires-Dist: fastapi>=0.110.0
Requires-Dist: starlette>=0.37.0
Requires-Dist: uvicorn>=0.29.0
Requires-Dist: bcrypt>=4.0.0
Requires-Dist: itsdangerous>=2.1.0
Requires-Dist: agent-evaluator[sdk]>=1.1.1
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: httpx>=0.27.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: ruff>=0.5.0; extra == "dev"
Provides-Extra: llm
Requires-Dist: anthropic>=0.34.0; extra == "llm"
Requires-Dist: openai>=1.40.0; extra == "llm"
Provides-Extra: crewai
Requires-Dist: crewai>=1.0.0; extra == "crewai"
Requires-Dist: litellm>=1.0.0; extra == "crewai"
Provides-Extra: mcp
Requires-Dist: crewai-tools[mcp]>=1.0.0; extra == "mcp"
Requires-Dist: mcp<2.0,>=1.10.1; extra == "mcp"
Provides-Extra: documents
Requires-Dist: pypdf>=4.0.0; extra == "documents"
Requires-Dist: beautifulsoup4>=4.12.0; extra == "documents"
Provides-Extra: all
Requires-Dist: crewai>=1.0.0; extra == "all"
Requires-Dist: litellm>=1.0.0; extra == "all"
Requires-Dist: crewai-tools[mcp]>=1.0.0; extra == "all"
Requires-Dist: mcp<2.0,>=1.10.1; extra == "all"
Requires-Dist: anthropic>=0.34.0; extra == "all"
Requires-Dist: openai>=1.40.0; extra == "all"
Requires-Dist: pypdf>=4.0.0; extra == "all"
Requires-Dist: beautifulsoup4>=4.12.0; extra == "all"
Dynamic: license-file

# HAIR-Platform

사람과 AI Agent를 하나의 조직도 위에서 함께 배치하고, 업무를 배분하고,
결재를 거쳐 확정하고, 성과를 리뷰하는 협업 플랫폼. AgentForge(Agent 생성
아키텍처를 검증하는 실습서 저장소)의 자매 프로젝트로, 그 아키텍처를
"Agent 생성"에서 "사람-Agent 협업/배분"으로 확장한다.

**현재 상태**: 조직도 기반 배치·배분·승인, Agent 생성·실행(Gate A-G
자동 채점), CrewAI 다중 Agent 협업, 로그인 직후 바로 쓰는 **대화 중심
작업공간**(기본 AI 자동응답 / 특정 Agent·Team 멘션 / 업무 요청 승격),
기본 제공 **단계형 업무 파이프라인 4종**(소프트웨어 개발·사업/기획·
제안서 작성·실적 보고 — Gate 기준 자동 재시도 + 반복 실패 시에만 사람
개입), Agent별 LLM 모델/설정 최적화 추천(admin), **통합 CLI**
(`hair serve`/`bootstrap-admin`/`reset-data`/`eval`)까지 전부 구현돼
실제로 쓸 수 있다. 테스트 917건 통과, API 엔드포인트 175개, Web UI
26개 탭. 개념·아키텍처 전체 설명은 `docs/OVERVIEW.md`, 설계 결정의
배경·과거 버그 수정 이력은 `git log`(커밋 메시지에 날짜·사용자 요청
원문이 그대로 남아 있다)를 참고.

## 무엇을 할 수 있나

### 1. 사람과 AI Agent를 함께 운용
- 조직도 위에 사람·Agent를 같이 배치하고 업무에 배분한다. 매칭은
  자동(완전일치 우선, 그 외엔 가용성·적합도·비용으로 점수화)이고,
  확정은 조직도 상사 체인을 따르는 다단계 결재를 거친다(자기 승인은
  막힘) — 다만 **본인을 배정하는 "셀프배정"은 결재 없이 즉시
  확정**된다.
- 한 업무에 여러 사람·여러 Agent·여러 팀이 동시에(confirmed 상태로)
  배정될 수 있다 — 교체하려면 어떤 배정을 대체하는지 명시해야 한다.
- **팀**: 사람 N명 + Agent M명을 역할과 함께 묶어 등록해두고 여러
  업무에 재사용한다. 협업 워크스페이스의 "팀 Agent 실행"으로 팀의
  Agent 멤버 전원을 실제 CrewAI Crew로 한 번에 실행하면, 결과가
  Agent별 결과물+결재 체인으로 그 업무에 그대로 연결된다.
- **협업 워크스페이스**: 결과물(deliverable) 타임라인 + 댓글. 사람이
  작성한 결과물도 "검토 요청"을 누르면 Agent 결과물과 같은 결재를
  거친다. 결과물은 일반 텍스트/마크다운/HTML/코드 중 형식을 지정할
  수 있고, 화면에서 그 형식대로 렌더링된다(마크다운 서식·코드 구문
  강조·HTML 미리보기 전부 포함, 복사/다운로드/소스 보기 지원).

### 2. 대화창에서 바로 일 시키기
- 로그인하면 바로 대화창부터 시작한다. 아무것도 지정하지 않으면 기본
  AI가 답하고, `@에이전트명`/`@팀명`으로 특정 Agent나 팀을 멘션해
  실행시킬 수 있다.
- 대화에서 쓸 스킬을 직접 고를 수 있는데, **"개발업무" 스킬은
  일반 사용자에게 불필요하므로 기본적으로 목록에서 숨겨진다** —
  "개발업무 스킬도 보기"를 켜야 보이고, 평소엔 일반 업무용 스킬
  (51개 중 다수)·도구(12개)만 노출된다. (Agent/Task에 미리 등록해둔
  스킬 태그나 CrewAI 실행 자체는 이 필터와 무관하게 전부 동작한다.)
- 특정 업무(Task)에 종속된 대화는 그 업무로 자동 흡수되고, 대화가
  커지면 업무 요청(Brief)으로 승격할 수 있다.

### 3. Agent 만들고 실제로 실행하기
- Anthropic/OpenAI/Ollama 중 하나로 실제 LLM Agent를 돌릴 수 있다
  (설정하지 않으면 비용 없는 무료 스텁으로 동작). provider/model은
  "모델 레지스트리"에 등록해두면 전 화면에서 드롭다운으로 공유된다.
- 실행마다 **Gate A-G**(목표달성·행동무결성·신뢰성·성능계약·보안
  경계·멀티에이전트조율·관찰가능성)가 자동으로 채점돼 기록에 남는다.
- **Crew 빌더**: 여러 Agent를 즉석으로 묶어 실제 CrewAI로 같이
  실행한다(sequential/hierarchical), 위임 관계를 다이어그램으로
  보여주고, 실행 이력에서 이전 결과와 차이(diff)를 바로 비교할 수
  있다. Agent가 스스로 초안을 원 요구사항과 대조해 검토·수정하는
  "자가검토" 옵션도 있다. 성공한 조합은 팀이나 파이프라인 단계로
  저장(승격)할 수 있다.
- 과거 산출물 검색(지식검색)·조직 관계 질의(관계조회)·실시간 웹
  검색(Tavily)이 Agent가 필요하면 스스로 판단해 호출하는 도구로
  이미 연결돼 있고, MCP로 외부 도구를 추가 연결할 수도 있다.

### 4. 복잡한 업무는 파이프라인으로
- 기본 제공 파이프라인 **4종**: 소프트웨어 개발, 사업/기획 업무
  처리, 제안서 작성, 실적 보고. 각 단계는 Gate 기준으로 자동
  채점·재시도되고, 반복 실패해야만 사람에게 에스컬레이션된다
  (계획 승인은 1회, 이후는 최소 개입 — BMAD-METHOD 방식).
- 화면에서 직접 단계를 구성하는 빌더도 제공되므로, 개발 외 업무에도
  같은 엔진을 그대로 재사용할 수 있다.
- 업무를 등록할 때 LLM에게 하위 업무 분해(역할·필요 스킬·선행 업무
  의존관계)를 제안받아 한 번에 배치로 생성할 수도 있다.

### 5. 지식 쌓아서 Agent가 찾아보게 하기
- "지식 베이스" 탭(admin/manager)에서 로컬 파일(.md/.pdf/.html)을
  올리거나 텍스트를 직접 입력하면 영구적으로 색인된다 — 색인되면
  "지식검색" 스킬을 가진 모든 Agent가 대화창·CrewAI 실행 양쪽에서
  찾아낸다.
- 대화창·협업 워크스페이스에서 올리는 참고자료는 **그 1회만 쓰는
  휘발성 첨부**다 — 영구 보관하려면 지식 베이스에 올려야 한다.
- 같은 탭에서 색인된 조각 조회/삭제+통계, 조직 관계 조회+통계까지
  관리한다.

### 6. 운영 관리
- 통합 인박스(결재 대기+Agent 실행 실패+낮은 Gate 점수 경고),
  매니저 대시보드(팀 Gate 평균·대기 승인 건수·비용 추이), 검색·
  필터·활동 기록(감사로그).
- `hair reset-data`로 운영 데이터(사용자·업무·대화·실행 이력·팀 등)
  만 공장 초기화할 수 있다 — Agent/Tool/Skill Pool·파이프라인
  템플릿은 그대로 둔다(배포 전 깨끗한 상태로 준비할 때 사용).

### 7. 권한(RBAC)
4개 역할(`admin`/`manager`/`member`/`viewer`) — 조회·생성은
admin+manager 공용이 많고, 삭제·사용자 생성·Agent 온보딩 승인처럼
조직 구조에 직접 영향을 주는 동작은 admin 전용.

## 처음 써보기 — 실전 시나리오

설치·설정을 시작하기 전에, 실제로 쓰면 어떤 모습인지부터 감을 잡고
싶다면 아래 4가지 중 자기 상황과 가까운 걸 골라 읽어보면 된다(용어는
전부 위 "무엇을 할 수 있나"에서 설명한 것들이다).

- **그냥 질문 하나만 던지고 싶다** — 로그인 직후 뜨는 "대화" 탭에서
  바로 입력. 아무도 멘션하지 않으면 기본 AI가 답한다. 결재도 없고
  가장 빠르다 — 단, 멘션 없이 보낼 때마다 실제 LLM이 호출돼
  **비용이 발생**한다는 점만 알아두면 된다.
- **특정 전문가(Agent)에게 시키고 싶다** — 대화에서 `@역할명`으로
  멘션(예: `@코드 검증가 이 함수 리뷰해줘`). 아직 그 Agent가 없으면
  먼저 만들어야 한다("AI 에이전트 생성" → 역할 지정 → 온보딩 승인,
  admin/manager만 가능).
- **여러 역할이 협업해야 하는 복잡한 업무다** — 업무 요청 제출 →
  할 일로 나누기 → 기본 제공 "소프트웨어 개발 파이프라인"(또는
  사업/기획·제안서·실적 보고 파이프라인) 실행. 사람은 계획 단계에서
  한 번만 승인하면, 그 뒤로는 Gate 기준을 통과할 때까지 자동으로
  반복되고 — 반복해도 안 되는 단계만 다시 사람에게 올라온다.
- **팀 전체(사람+Agent) 작업 흐름을 조직처럼 운영하고 싶다** — "팀
  관리"에서 역할별로 사람·Agent를 묶어 등록해두고, 업무마다 그 팀을
  배정. 결재·성과 리뷰·비용 집계가 팀 단위로도 쌓인다.

어느 경로로 시작해도 같은 Agent/팀 등록을 공유하므로, 가벼운 대화로
시작했다가 나중에 정식 업무로 넘기거나 그 반대로 가는 것도 자유롭다.
화면 안에는 이보다 훨씬 자세한 "이용 가이드"(로그인 후 "이용 가이드"
탭)가 있다 — 메뉴 이름·버튼 문구까지 그대로 따라 할 수 있게 단계별로
적어뒀다.

## 빠른 시작

```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,all]"
# `[dev]`만 설치하면 `tests/unit`의 CrewAI 연동 테스트 일부가 테스트
# 실행 시점에 `ModuleNotFoundError`로 깨진다. `all`(= crewai+mcp+llm+
# documents 묶음, pyproject.toml 참고)까지 같이 설치해야 아래 골든셋이
# 전부 오프라인으로 깨끗하게 통과한다.
pytest tests/ -q        # 골든셋 917건 통과(오프라인, 실제 LLM 호출 없음 — 전부 mock)
```

### 설치 옵션(extras) 한눈에 보기

아직 PyPI에 배포되지 않아 지금은 GitHub 클론 후 `pip install -e ".[...]"`
형태로만 설치할 수 있다(PyPI 배포 후에는 `pip install "hair-platform[...]"`
로 동일하게 쓸 수 있다). 필요한 조합만 골라 쉼표로 묶어 한 번에 설치
가능(예: `pip install -e ".[llm,documents]"`) — 아래 "빠른 시작"
각 절이 extra별 상세 설정(환경변수·API 키 등)을 안내한다.

| extra | 설치 명령 | 필요할 때 | 추가 설치되는 패키지 |
|-------|-----------|-----------|----------------------|
| *(기본)* | `pip install -e .` | 무료 스텁으로만 쓸 때 — LLM/CrewAI/MCP/문서 업로드 전부 불필요 | pydantic·fastapi·uvicorn 등 핵심 의존성만 |
| `llm` | `pip install -e ".[llm]"` | 실제 Anthropic/OpenAI API로 Agent를 실행할 때(Ollama는 API 키 없이 기본 의존성만으로 동작) | anthropic, openai |
| `crewai` | `pip install -e ".[crewai]"` | 여러 Agent를 실제 CrewAI Crew로 협업시킬 때("Crew 빌더"/파이프라인) | crewai, litellm |
| `mcp` | `pip install -e ".[mcp]"` | Agent에 외부 MCP 도구 서버를 연결할 때 | crewai-tools[mcp], mcp(`<2.0` 고정 — 아래 참고) |
| `documents` | `pip install -e ".[documents]"` | 대화창/지식 베이스에서 `.pdf`/`.html` 파일을 업로드할 때(`.md`/`.txt`는 추가 설치 불필요) | pypdf, beautifulsoup4 |
| `dev` | `pip install -e ".[dev]"` | 테스트/린트/포맷터를 돌릴 때 | pytest, black, ruff |
| `all` | `pip install -e ".[dev,all]"` | 전체 골든셋을 오프라인으로 깨끗하게 통과시킬 때(= `llm`+`crewai`+`mcp`+`documents` 전부) | 위 extras 전부 |

> `mcp`는 `mcp>=1.10.1,<2.0`으로 상한을 고정해둔다 — `crewai-tools`가
> 쓰는 `mcpadapt==0.1.19`가 `mcp 2.x`의 API 이름 변경을 아직 못
> 따라잡아서다(따라잡으면 상한을 올릴 것). `pip install -e ".[mcp]"`만
> 따로 설치하면 이 상한이 자동으로 지켜지지만, `mcp`를 다른 이유로
> 이미 더 최신 버전을 설치해둔 환경에 나중에 이 extra를 추가하면
> pip가 `mcp`를 1.x로 다운그레이드한다는 점에 유의.

실행 명령은 전부 `hair <subcommand>` 하나로 모여 있다 — 각 서브커맨드의
옵션/예시는 `hair <subcommand> --help`로 확인(`src/hair_platform/cli.py`):

```bash
hair --help
```

콜드스타트(신규 배포 시 최초 ADMIN 계정 생성 — 유일한 진입 경로,
`users` 테이블이 완전히 비어 있을 때만 동작):

```bash
hair bootstrap-admin -u admin -p '...'       # --db-path 생략 시 기본 hair.db
```

운영 중 쌓인 데이터만 초기화하고(사용자·업무·대화·실행 이력·모델
레지스트리·팀·활동 기록 등) Agent(26종)/Tool·Skill Pool/파이프라인
템플릿은 그대로 둘 때(예: 배포 전 깨끗한 상태로 준비):

```bash
hair reset-data                              # 확인 프롬프트 뜸(되돌릴 수 없음)
hair reset-data --yes                        # 확인 없이 바로 실행
# 보통 바로 이어서: hair bootstrap-admin -u admin -p '...'
```

실제 CrewAI 연동을 쓰려면(무거운 의존성 — opt-in):

```bash
pip install -e ".[crewai]"
# GenerateRequest.framework="crewai" 또는 Web UI "AI 에이전트 생성" 탭에서
# framework를 crewai로 선택 — 실제 LLM API를 호출하므로 비용이 발생한다.
# "Crew 빌더" 탭에서 여러 Agent를 실제 CrewAI Crew로 묶어 협업시킬 수 있다
# (업무에 바로 실행/즉석 테스트/실행 이력 3개 모드).

# MCP(외부 검색 등 도구) 연동을 쓰려면 추가로:
pip install -e ".[mcp]"
# Web UI "AI 에이전트" 탭의 "MCP 서버(JSON)" 칸에
# [{"url": "http://localhost:8000/mcp", "transport": "streamable-http"}]
# 형태로 넣고 "모델 설정" 저장 — 이후 "Crew 빌더"에서 그 Agent에 실제
# MCP 도구가 붙는다. MCPServerAdapter는 생성 시점에 실제로 접속을
# 시도한다(접속 가능한 MCP 서버가 준비돼 있어야 한다).
```

실제 LLM 연동을 쓰려면(Anthropic·OpenAI·Ollama 중 선택):

```bash
pip install -e ".[llm]"                    # anthropic·openai SDK 설치(httpx는 기본 의존성에 포함)

# 방법 A — 프로젝트 루트에 .env 파일(git에 커밋되지 않음, .gitignore 처리됨):
#   ANTHROPIC_API_KEY=...
#   OPENAI_API_KEY=...
# create_app()이 기동 시 자동으로 읽는다(python-dotenv, 이미 설정된 환경변수는
# 덮어쓰지 않음).

# 방법 B — 환경변수로 직접:
export ANTHROPIC_API_KEY=...               # 또는 OPENAI_API_KEY

# Ollama는 API 키가 없다 — 로컬 서버(기본 http://localhost:11434, OLLAMA_BASE_URL로
# 변경 가능)를 미리 띄워두고 provider="ollama"를 직접 지정해야 한다(자동판별 대상 아님).

# API 요청에 "use_llm": true 를 넣거나, Web UI "AI 에이전트 생성" 탭의
# 체크박스를 켜면 실제 API가 호출된다(비용 발생) — 안 켜면 무료 스텁 그대로.
# "AI 에이전트" 탭의 "모델 설정"으로 Agent별 기본 provider/model을 저장해두면
# (비용 없음), 이후 "실행"이 매번 지정 안 해도 그 설정을 따른다. provider/model
# 목록은 "모델 레지스트리" 탭에 등록해두면 전 화면에서 드롭다운으로 공유된다.
```

### 권장 모델 & API 토큰(키) 발급

**토큰(API 키) 발급처** — Ollama는 로컬 실행이라 키가 필요 없다.
클라우드 provider는 먼저 가입해 키를 받아야 한다(가입 시 결제 수단
등록 필요, 사용한 만큼 과금):

| provider | 발급 위치 | 비용 |
|----------|-----------|------|
| Anthropic | https://console.anthropic.com/ (API Keys 메뉴) | 사용량 과금 |
| OpenAI | https://platform.openai.com/api-keys | 사용량 과금 |
| Ollama | https://ollama.com 에서 설치 후 로컬 실행 | 무료(로컬 컴퓨팅 자원만 소비) |
| Tavily(실시간 웹검색) | https://tavily.com | 무료 티어 있음 |

받은 키는 `.env`(`ANTHROPIC_API_KEY`/`OPENAI_API_KEY`/`TAVILY_API_KEY`)
에 넣거나 환경변수로 export — 위 "실제 LLM 연동을 쓰려면" 참고.

**Agent별 LLM 설정 최적화**(admin, "LLM 설정 최적화" 탭)는 역할을
**심층추론**(기획/분석/설계)/**정밀·신속**(구현/리뷰/QA)/**표준** 3단계
tier로 분류해 모델을 추천한다(Web UI "모델 레지스트리"/"⚡ 최적화 추천"
화면에 뜨는 표기와 동일). provider별 권장 기준:

| tier | 클라우드 권장 | 로컬(Ollama) 권장 | 비고 |
|------|---------------|---------------------|------|
| **표준**(일반 응답) | Haiku/GPT-4o-mini급(코드 기본값: `gpt-4o-mini`) | `llama3.1`(코드 기본값) 등 7B~8B급 경량 모델 | 가장 빠른 응답이 필요한 티어 |
| **정밀·신속**(구현/리뷰/QA) | Sonnet/GPT-4o급(코드 기본값: `claude-sonnet-5`) | 20B+ 급 코드 역량 모델(예: `qwen3.8:27b-mlx` — 이 플랫폼의 "개발자" 계열 Agent가 실제로 쓰고 있는 모델, 라이브 DB로 직접 확인) | 이름에 `code`/`coder`가 들어간 모델은 추천 랭킹에서 자동 우대되지만, 그렇지 않은 모델(`qwen3.8:27b-mlx` 포함)도 "모델 레지스트리"에서 admin이 이 tier로 직접 매핑해두면 패턴 추정보다 항상 먼저 추천된다 |
| **심층추론**(기획/분석/설계) | Opus급 | 30B+ 대형 로컬 모델도 가능하지만 **느리다**(아래 실측 참고) | 응답을 실시간으로 봐야 하면 클라우드 권장 |

**로컬(Ollama) 모델 쓸 때 실측으로 확인된 점**:
- 모델은 미리 받아둬야 한다(`ollama pull <모델명>`) — 받지 않은 모델을
  지정하면 그 자리에서 404로 실패한다(실제 사고 사례: 코드 기본값
  `llama3.1`이 로컬에 없어서 발생).
- **대형 모델일수록 느리다** — 실측 사례로 35B급 모델이 **단일 호출에
  337.7초**(약 5.6분) 걸렸고, "자율 개발 크루"처럼 매니저가 여러 차례
  위임까지 하는 멀티 Agent 실행은 **12분을 넘긴** 사례가 있다. 그래서
  백엔드 타임아웃도 그에 맞춰 넉넉히 잡혀 있다(단일 호출 기본
  600초, **심층추론** tier Agent 최대 1800초, CrewAI 멀티 Agent
  경로는 최대 5400초). 대화창에서 실시간 응답을 기다리는 용도라면
  7B~14B급으로, 그보다 큰 모델은 파이프라인처럼 비동기로 도는
  배치성 작업에 쓰는 걸 권장한다.
- **임베딩(지식검색/VectorDB) 모델**: 코드 기본값은 `mxbai-embed-large:latest`
  인데, 이는 "이미 받아져 있던 모델"이라서 고른 값일 뿐 성능상 최선은
  아니다 — 컨텍스트 한도가 **512토큰뿐**이라 조금만 긴 문서도 많이
  잘려나간다. `nomic-embed-text`(8192토큰, 16배 더 넓음)를 대신 받아서
  (`ollama pull nomic-embed-text`) "모델 레지스트리"에서 임베딩 모델로
  바꿔주면 장문 산출물 검색 품질이 더 좋다.

대화창·협업 워크스페이스(업무 실행)·지식 베이스 세 곳 중 어디서든
`.pdf`/`.html` 파일을 업로드하려면(`.md`/`.txt`는 추가 설치 없이 바로
동작 — 셋 다 같은 `documents.extract_text()`를 공유한다):

```bash
pip install -e ".[documents]"              # pypdf·beautifulsoup4 설치
```

"실시간웹검색" 스킬(Tavily, 대화창·Crew 실행 양쪽에서 동작하는 실시간
웹 검색)을 쓰려면 `.env`에 키를 추가:

```bash
#   TAVILY_API_KEY=...                       # https://tavily.com 무료 발급
```

Web UI 실행(부트스트랩으로 만든 ADMIN 계정으로 로그인):

```bash
hair serve                # http://127.0.0.1:8000/, hair.db(기본)에 저장 — 브라우저 자동으로 열림
hair serve --reload       # 개발 중 — 코드 변경 시 자동 재시작
hair serve --no-browser   # 브라우저 자동 열기 끄기(서버만 실행)
```

### 사내망에서 여러 명이 함께 쓰기

같은 네트워크(사내망)의 팀원 여러 명이 한 서버에 각자 PC 브라우저로
접속해 쓰려면 아래 순서를 따른다. 서버를 띄우는 PC(관리자 PC) 1대만
있으면 되고, 나머지는 브라우저만 열면 된다 — 팀원 PC에 따로 설치할
필요 없음.

1. **(관리자 PC) 랜덤 세션 서명 키를 먼저 지정한다** — `--host
   0.0.0.0`처럼 루프백이 아닌 주소로 띄우면서 이 키를 안 주면, 세션이
   소스에 공개된 고정값으로 서명돼 같은 네트워크의 누구나 다른
   사용자(admin 포함)의 로그인 세션을 위조할 수 있다(`hair serve`가
   기동 시점에 이걸 감지하면 경고를 띄운다):

   ```bash
   export HAIR_PLATFORM_SECRET_KEY="$(python3 -c 'import secrets; print(secrets.token_hex(32))')"
   hair serve --host 0.0.0.0 --no-browser
   ```

   `.env` 파일에 넣어두면(`HAIR_PLATFORM_SECRET_KEY=...`) 재기동할 때마다
   새로 export할 필요가 없다. **`--reload`는 여기서 절대 쓰지 않는다** —
   개발 전용 옵션이라 파일이 바뀔 때마다 서버가 재시작되며 접속 중인
   팀원 전체가 끊긴다.

2. **방화벽에서 포트를 연다** — 기본 포트는 `8000`(`--port`로 변경
   가능). macOS는 "시스템 설정 → 네트워크 → 방화벽"에서, Windows는
   "Windows Defender 방화벽 → 고급 설정"에서 해당 포트의 인바운드 연결을
   허용해야 다른 PC에서 접속된다.

3. **관리자 PC의 사내망 IP를 확인한다** — macOS/Linux는
   `ifconfig`(또는 `ip addr`), Windows는 `ipconfig`로 확인(보통
   `192.168.x.x`/`10.x.x.x` 형태).

4. **(관리자) 팀원 계정을 만들어준다** — 로그인 후 "사용자 관리" 탭
   (admin 전용)의 "사용자 생성" 폼에서 아이디/비밀번호/역할
   (`admin`/`manager`/`member`/`viewer`)을 지정해 계정을 만든다(API를
   직접 호출할 필요 없음). 생성 직후엔 조직도 상사가 지정돼 있지 않아
   그 사용자가 배정을 요청하면 결재가 단일 단계(승인자 미지정)로
   처리된다 — 필요하면 "조직도" 탭에서 상사를 지정해준다.

5. **(각 팀원 PC) 브라우저로 접속해 로그인한다** — 주소창에
   `http://<관리자 PC의 사내망 IP>:8000/`을 입력하고, 발급받은
   아이디/비밀번호로 로그인한다. 로그인 세션은 브라우저별 쿠키 기반이라
   팀원마다 독립적으로 유지된다(한 명이 로그아웃해도 다른 팀원 세션에
   영향 없음).

**동시 사용 시 알아둘 점**:
- `hair serve`는 단일 프로세스로 뜬다(멀티 워커 미지원) — 동시 접속
  자체는 문제없지만, 여러 명이 동시에 LLM 호출(Agent 실행/CrewAI/파이프라인)
  을 겹쳐서 돌리면 응답이 순서대로 밀려서 늦게 나올 수 있다. 실시간
  응답이 중요한 조직이면 인원 규모에 맞춰 여러 인스턴스(다른 포트·다른
  `--db-path`)로 분산하는 것도 방법이다(단, 데이터가 분리된다는 점
  유의).
- SQLite(WAL 모드)라 읽기는 동시에 여러 건 처리되지만, 쓰기(결재 승인,
  배정 확정 등)는 짧게 직렬화된다 — 일반적인 팀 사용 규모(수 명~수십 명)
  에서는 체감되지 않는다.
- 로그인 비밀번호는 평문 HTTP로 오간다 — 민감도가 높은 조직이라면
  앞단에 리버스 프록시로 TLS(HTTPS)를 추가하는 걸 권장한다.

Gate A–G 수동 실측(선택, 서비스 경로는 이미 상시 연결돼 있음 —
`agent_evaluation.py`):

```bash
agent-eval check          # API 키 등 설정 먼저 확인
hair eval                 # Gate A/B/D/E/G 측정 실행(results/에 저장)
agent-eval gate results/*.json       # 채점
```

## 구조

```
src/hair_platform/
  auth.py            # 세션 인증 + RBAC(4종 역할: admin/manager/member/viewer)
  models.py          # Pydantic v2 요청 모델
  db.py              # SQLite 스키마(WAL, audit_log append-only 트리거)
  app.py             # FastAPI 라우트(175개 엔드포인트, GET / 포함)
  pool.py            # Human/Agent Pool → ResourceCandidate 어댑터
  assignment.py      # 매칭 알고리즘(결정론적)
  match_llm_judge.py # 매칭 결과 LLM judge 폴백(역할명 부분일치로도 못 찾을 때)
  approvals.py       # 다단계 결재라인(조직도 매니저 체인)
  assignments.py     # 배정 요청·확정(팀 배정 + 다중 confirmed + 셀프배정 즉시확정 지원)
  teams.py           # 팀(사람+Agent 그룹) CRUD — "등록→재사용" 패턴
  jobs.py            # Job Queue(+ idempotency)
  sandbox.py         # Docker 샌드박스 명령 구성
  audit.py           # 감사로그
  performance.py     # 성과리뷰(동의 기반)
  cost.py            # 비용 조회(전역 + Task 단위)
  fairness.py        # 배정 공정성 지표
  retention.py       # 데이터 보관기간 정책(assignment_history 1년)
  eval_wiring.py      # Gate A/B/D/E/G 평가 배선 수동 실행 probe(agent-evaluator SDK, python -m으로 직접 실행)
  agent_evaluation.py # Gate A-G 평가를 Agent 실행 경로에 상시 연결(agent_evaluations 테이블) + 구문검사
  content_validators.py # content_type별(html 등) pluggable 구문 검증기 디스패치
  requirements_traceability_llm.py # "코드 검증" 단계 요구사항 추적성 LLM judge 채점(정보성 지표)
  brief_decompose_llm.py # 업무 분해 LLM 제안(역할·필요 스킬·선행 업무 의존관계)
  bootstrap.py       # 콜드스타트 — 최초 ADMIN 계정 생성(`hair bootstrap-admin`이 호출)
  cli.py             # 통합 CLI(`hair` 콘솔 스크립트) — serve/bootstrap-admin/reset-data/eval
  webui.py           # Web UI 셸(단일 페이지 바닐라 JS, GET / 에서 서빙, 26개 탭)
  llm.py             # 실제 Anthropic/OpenAI/Ollama 연동(provider/model 선택 가능)
  model_registry.py  # provider별 사용 가능 모델 등록·관리("등록→재사용") + 모델별 LLM 설정 최적화 tier(deep_reasoning/precision_fast/standard) 직접 매핑
  agent_runtime.py   # 온보딩된 Agent에게 온디맨드로 업무를 맡기는 실행 경로(RAG 증강 포함)
  crew_runtime.py    # 실제 CrewAI 연동(단일 생성 + 다중 Agent 협업/위임 + 다이어그램 + 자가검토)
  crew_history.py    # Crew 실행 이력(crew_runs) — 팀/즉석 실행의 진행상태·협업다이어그램·토큰사용량 영구 저장
  vectorstore.py     # 지식검색 Agent(VectorDB) — OpenAI 임베딩+SQLite 코사인 유사도
  graphquery.py      # 관계조회 Agent(GraphDB) — 기존 관계형 데이터 그래프 질의
  websearch.py       # 외부 검색 — 실시간 웹 검색(Tavily native 도구, 대화창·Crew 양쪽 동작, TAVILY_API_KEY 필요) + Parallel AI MCP(Crew 전용). Wikipedia 검색 코드는 남아있으나 이 배포 환경 IP가 지속 차단돼 기본 시드에서 뺐다(db.py 참고)
  documents.py       # 외부 자료(.md/.pdf/.html) 업로드·텍스트 직접 입력 → 청크 분할 → VectorDB 색인
  pool_registry.py   # Skill Pool·Tool Pool — 스킬→도구 매핑 데이터화 + 개발업무/일반업무 category 분류, CrewAI Tool 조립
  data_admin.py      # brief/task/human/agent 하드 삭제(FK 연쇄 삭제 + confirmed 배정 보호) + 운영 데이터 공장 초기화(Agent/Tool/Skill/파이프라인은 유지, 팀은 초기화, `hair reset-data`)
  deliverables.py    # 협업 워크스페이스 — 결과물/댓글, "내 업무", 사람 LLM 보조, Agent 비동기 실행+평가(agent_execution_jobs)
  inbox.py           # 통합 인박스(결재 대기+Agent 실행 실패+낮은 Gate 점수 경고)
  dashboard.py       # 매니저 대시보드(팀 Gate 평균+대기 승인 건수+비용 추이) + Task 재시도 합산
  conversations.py   # 대화 중심 작업공간 — Task 독립 대화, 기본 AI/Agent/Team 멘션 3경로, skill 그라운딩, Brief 승격
  pipeline_runtime.py # 단계형 업무 파이프라인 엔진(단독/순차 릴레이/병행 위임 단계, Gate A-G 기준 자동 재시도·에스컬레이션, Task 재시도 예산)
  reference_pipeline_seeds.py # 레퍼런스 Agent 26종 + Skill/Tool Pool + 파이프라인 템플릿 4종(소프트웨어 개발/사업·기획/제안서 작성/실적 보고) 기본 시드
  agent_optimizer.py # Agent별 LLM provider/model/tuning_config 최적화 추천(규칙 기반 + 선택적 LLM 보정, admin)
  id_scheme.py       # Agent/Tool/Skill 표시용 코드 체계(`AGT-REF-001` 등, 종류 구분용) — 정수 PK는 그대로, `code`만 별도 배정
docs/
  OVERVIEW.md        # 지향점·핵심 개념·아키텍처·주요 기능 개요(과거 설계 논의·벤치마크는 git log 참고)
.claude/skills/rbac-permission-audit/  # 신규 발굴 스킬(3회+ 반복 확인)
.github/workflows/ci.yml               # pytest+ruff+black CI
tests/unit/                            # 골든셋 917건 통과
```

## 로드맵

핵심 기능은 전부 구현 완료됐고, 그 이후 반복적으로 들어온 사용자 요청에
맞춰 계속 확장돼왔다 — 다음에 뭘 할지는 `docs/OVERVIEW.md`의 "알려진
한계" 절을 참고해서 정한다.

## 변경 이력

버전별 핵심 변경만 한 줄로 요약한다 — 자세한 배경·버그 재현 과정은
커밋 메시지(`git log --oneline --all`)에 날짜·사용자 요청 원문과 함께
남아 있다.

| 버전 | 날짜 | 핵심 변경 |
|------|------|-----------|
| v0.1.3 | 2026-11-11 | Skill/Tool "개발업무/일반업무" 분류(대화창 기본 숨김+필요시 노출) · HAIR 자체 Skill 이름 30개 한글화 · 제안서 작성/실적 보고 파이프라인 추가(템플릿 4종) |
| v0.1.2 | 2026-11-09 | 파이프라인 Ollama 실제 적용 + "구현" 단계 합성 버그 수정(위임 계획만 남던 문제) · 사업/기획 파이프라인 추가 · 자동 단계적 에스컬레이션·셀프배정 즉시확정·Task 재시도 예산 등 로드맵 9건 |
| v0.1.1 | 2026-11-03 | 리소스 매칭/RAG 검색 품질 향상 · 결재·GraphDB 화면 가독성 개선 · Crew 빌더 신설 · 사내망 다중 사용자 접속 준비(`hair reset-data` 포함) |
| v0.1.0 | 2026-10-26 | 외부 자료 업로드(RAG) 지원 + Admin "지식 베이스" 탭 신설 · Agent 응답 형식(`content_type`) 일관성 수정 |
| v0.0.4 | 2026-10-20 | Crew 빌더 전신(멀티 Agent 즉석 실행 통합) · 배정 취소 기능 · Agent 역할/인격 상세조정 |

## 라이선스

MIT
