# GUARDiA ITSM — Priority 3: AI 에이전트 확장 **문서 버전**: 1.0 | **작성일**: 2026-05-25 --- ## 1. 장애 RCA 자동 초안 생성 ### 목적 INCIDENT_TRIAGE 에이전트 확장. RESOLVED 상태 장애에 대해 Ollama로 RCA 문서 초안을 자동 생성한다. ### 동작 흐름 ``` 1. tb_incident WHERE status='RESOLVED' AND rca_draft IS NULL 조회 2. LLM 프롬프트 구성: - 장애 제목, 설명, 등급, 발생~해소 시각, 조치 이력 3. Ollama json_generate() 호출 4. 결과 구조: { "root_cause": "근본 원인", "timeline": "사건 타임라인", "impact": "영향 범위", "resolution": "해결 과정", "preventive_measures": "재발 방지 조치", "lessons_learned": "교훈" } 5. tb_incident.rca_draft 컬럼에 저장 (JSON) 6. AgentApproval(PENDING) 생성 — 담당자 검토 후 최종 확정 ``` ### 구현 위치 `core/agents.py` → `_incident_triage()` 핸들러 하단 추가 ```python # RESOLVED 장애 RCA 초안 생성 resolved_incidents = await db.execute( select(Incident).where( Incident.status == "RESOLVED", Incident.rca_draft == None ).limit(5) ) for inc in resolved_incidents.scalars(): rca = await llm.json_generate(rca_prompt(inc), agent.llm_model) inc.rca_draft = rca await db.commit() ``` --- ## 2. 에이전트 간 메시지 전달 ### 목적 CEO 에이전트가 CTO/PM_AGENT에게 태스크를 위임할 수 있도록 에이전트 간 메시지 전달 체계를 구현한다. ### 신규 DB 테이블: tb_agent_message ```sql CREATE TABLE tb_agent_message ( id INTEGER PRIMARY KEY, from_agent_id INTEGER REFERENCES tb_agent_config(id), to_agent_id INTEGER REFERENCES tb_agent_config(id), message_type VARCHAR(30), -- TASK_DELEGATION / STATUS_UPDATE / ESCALATION subject VARCHAR(200), body TEXT, metadata JSON, is_read BOOLEAN DEFAULT FALSE, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, read_at DATETIME ); ``` ### 메시지 타입 | 타입 | 설명 | 트리거 | |------|------|--------| | TASK_DELEGATION | 태스크 위임 | CEO → CTO: 개발 태스크 | | STATUS_UPDATE | 상태 보고 | CTO/Dev → CEO: 완료 보고 | | ESCALATION | 에스컬레이션 | 하위 에이전트 → 상위 에이전트 | ### API 엔드포인트 추가 ``` GET /api/agents/{id}/messages 수신 메시지 목록 POST /api/agents/{id}/messages 메시지 전송 PATCH /api/agents/messages/{msg_id}/read 읽음 처리 ``` --- ## 3. KB 품질 검토 자동화 ### 목적 KB_CURATOR가 생성한 초안에 자동으로 품질 점수를 부여하고, 기준 이상이면 자동 발행한다. ### 품질 평가 기준 | 항목 | 가중치 | 설명 | |------|--------|------| | completeness | 40% | 증상/원인/해결책 3섹션 완성도 | | clarity | 30% | 문장 명확성 및 가독성 | | actionability | 30% | 실제 조치 가능한 구체적 내용 여부 | ### 동작 흐름 ```python # kb_curator 핸들러 확장 quality = await llm.json_generate( quality_prompt(kb_doc), agent.llm_model ) # quality = {"completeness": 85, "clarity": 78, "actionability": 82, "overall": 82} kb_doc.quality_score = quality.get("overall", 0) if kb_doc.quality_score >= 80: kb_doc.published = True # 자동 발행 approval.status = "AUTO_APPROVED" else: approval.status = "PENDING" # 수동 검토 필요 ``` ### 모델 변경 (models.py) `KBDocument`에 `quality_score: int` 컬럼 추가 --- ## 4. WBS 지연 완료 예측 ### 목적 WBS_MONITOR 핸들러 확장. 완료율 추이를 분석하여 프로젝트 완료 예상일을 계산한다. ### 예측 알고리즘 ```python # 최근 7일간 완료율 기울기 계산 prev_rate = wbs_snapshot_7days_ago.completion_rate # 예: 45% curr_rate = current_completion_rate # 예: 52% daily_delta = (curr_rate - prev_rate) / 7 # 1%/일 remaining = 100 - curr_rate # 48% est_days = remaining / daily_delta if daily_delta > 0 else 999 est_completion = date.today() + timedelta(days=est_days) # planned_end_date와 비교 → 초과 시 리스크 등록 if est_completion > project.planned_end_date: delay_days = (est_completion - project.planned_end_date).days # WBS 리스크 자동 등록 ``` ### 저장 위치 `si_project.estimated_completion` 컬럼 업데이트 (또는 AgentTask에 기록) --- ## 5. 에이전트 파인튜닝 파이프라인 ### 목적 누적된 `tb_agent_task(COMPLETED)` 데이터를 기반으로 Ollama 커스텀 모델을 파인튜닝한다. ### 파이프라인 단계 ``` 1. 데이터 수집 SELECT input_data, output_data FROM tb_agent_task WHERE status='COMPLETED' AND tokens_used > 0 LIMIT 1000 2. JSONL 파일 생성 (Ollama fine-tune 포맷) {"prompt": "...", "response": "..."} → /opt/guardia/finetune/guardia-agent-v2.jsonl 3. Modelfile 생성 FROM guardia-agent TRAIN /opt/guardia/finetune/guardia-agent-v2.jsonl 4. ollama create 실행 ollama create guardia-agent-v2 -f Modelfile.guardia-v2 5. 헬스체크 후 active model 전환 AgentConfig.llm_model = "guardia-agent-v2" ``` ### API 엔드포인트 ``` POST /api/agents/finetune/start 파인튜닝 시작 (ADMIN only) GET /api/agents/finetune/status 진행 상태 조회 ``` ### 구현 위치 `core/llm_client.py`에 `fine_tune()` 메서드 추가 ```python async def fine_tune(self, dataset_path: str, model_name: str) -> bool: """Ollama 모델 파인튜닝 실행""" proc = await asyncio.create_subprocess_exec( "ollama", "create", model_name, "-f", f"Modelfile.{model_name}", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) stdout, stderr = await proc.communicate() return proc.returncode == 0 ```