# Knowledge Agent 분석 및 기능명세 분석 대상: `C:\Users\lasta\MyProject\AI\참고\knowledge_agent-main` 작성 목적: 오픈 프로젝트 `knowledge_agent-main`을 범용 온톨로지 구축 플랫폼의 기본 소스로 활용하기 위해, 아키텍처와 기능을 상세히 분석하고 재사용 가능 범위와 보완 필요 사항을 명세한다. ## 1. 프로젝트 개요 `Knowledge Agent`는 LightRAG 지식베이스를 자동으로 분석, 확장, 정제, 감사, 개선 제안하는 멀티 에이전트형 지식 관리 시스템이다. 핵심 목표는 정적인 RAG/지식그래프 저장소를 다음과 같은 “살아있는 지식 관리 루프”로 전환하는 것이다. 1. 기존 지식베이스를 분석하여 지식 공백을 찾는다. 2. 지식 공백별 연구 주제를 생성한다. 3. 검색 계획을 세우고 외부 웹/PDF 자료를 수집한다. 4. 수집한 원문을 마크다운과 요약으로 정제하여 DB에 저장한다. 5. 적합한 URL을 선별하여 LightRAG에 적재한다. 6. 그래프 품질 문제를 감사한다. 7. 중복, 명칭 불일치, 관계 오류 등을 수정한다. 8. 반복되는 문제를 분석하여 시스템 개선안을 제시한다. 범용 온톨로지 구축 플랫폼 관점에서는 “도메인 문서 수집 → 문서 정제 → 엔티티/관계 추출 기반 지식그래프 구축 → 품질 감사 → 정제 → 운영 개선”의 기본 골격으로 활용할 수 있다. ## 2. 기술 스택 및 실행 환경 ### 2.1 주요 의존성 `pyproject.toml` 기준 의존성은 다음과 같다. | 분류 | 패키지 | 용도 | |---|---|---| | 에이전트 프레임워크 | `langchain`, `langgraph` | 에이전트 실행 및 상태 그래프 구성 | | LLM 연동 | `langchain-openai` | OpenAI 호환 Chat 모델 호출 | | MCP 연동 | `langchain-mcp-adapters` | MCP 서버의 도구를 LangChain 도구로 연결 | | DB | `psycopg2-binary` | PostgreSQL 연결 | | 설정 | `python-dotenv`, `pydantic` | 환경 변수 및 데이터 검증 | | JSON 복구 | `json-repair` | LLM 출력 JSON 파싱 안정화 | | 웹 수집 | `requests`, `trafilatura`, `playwright`, `beautifulsoup4`, `html2text` | HTML/PDF 수집 및 본문 추출 | | PDF 처리 | `pdfplumber` | PDF 텍스트 추출 | | 토큰 제어 | `tiktoken` | 요약 전 입력 토큰 제한 | ### 2.2 환경 변수 `.env.example`과 코드 기준으로 다음 환경 변수가 필요하다. | 변수 | 설명 | |---|---| | `DATABASE_URL` | PostgreSQL 연결 문자열. `db_utils.py`에서 필수로 사용 | | `OPENAI_MODEL_NAME` | 사용할 OpenAI 호환 모델명. 기본값은 `chat` | | `OPENAI_BASE_URL` | OpenAI 호환 API 서버 URL. 기본값은 `http://localhost:8001/v1` | ### 2.3 MCP 서버 설정 `mcp.json`은 다음 MCP 서버를 전제로 한다. | 서버 | 역할 | |---|---| | `google_search` | 외부 검색 | | `lightrag` | LightRAG 질의, 그래프 조회, 문서 적재, 엔티티/관계 수정 | | `fetch` | URL fetch 보조 도구 | | `file_tools` | 파일 시스템 접근 | | `deepwiki` | 외부 지식 검색 보조 | 이 프로젝트는 MCP 도구 이름에 강하게 의존한다. 예를 들어 `analyst`는 `query`, `graphs_get`, `graph_labels`, `google_search`, `fetch` 도구를 찾고, `fixer`는 `graph_update_entity`, `documents_delete_entity`, `graph_update_relation`, `documents_delete_relation`, `graph_entity_exists` 도구를 기대한다. ## 3. 전체 아키텍처 ### 3.1 구조 ```text run.py └─ knowledge_agent.py └─ LangGraph StateGraph ├─ Analyst ├─ Researcher ├─ Curator ├─ Auditor ├─ Fixer └─ Advisor db_utils.py ├─ 보고서 저장 테이블 관리 └─ 수집 문서 저장/조회 tools.py ├─ URL 다운로드 ├─ HTML/PDF 본문 추출 ├─ 마크다운 생성 └─ 사람 승인 도구 prompts/ ├─ analyst_prompt.txt ├─ planner_prompt.txt ├─ refiner_prompt.txt ├─ summarizer_prompt.txt ├─ search_ranker_prompt.txt └─ ingester_prompt.txt ``` ### 3.2 상태 모델 `state.py`의 `AgentState`는 LangGraph 전체 상태를 정의한다. 주요 상태 필드: | 필드 | 설명 | |---|---| | `messages` | LangChain 메시지 목록 | | `task` | 실행 워크플로우명 | | `status` | 현재 상태 메시지 | | `timestamp` | 실행 시각 | | `mcp_tools` | MCP 서버에서 로드한 도구 목록 | | `model` | ChatOpenAI 모델 객체 | | `logger` | 실행 로거 | | `analyst_report_id`, `analyst_report` | Analyst 산출물 | | `researcher_report_id`, `researcher_gaps_todo`, `researcher_gaps_complete`, `researcher_report` | Researcher 진행 상태 | | `curator_report_id`, `curator_urls_for_ingestion`, `curator_url_ingestion_status`, `curator_report` | Curator 진행 상태 | | `auditor_report_id`, `auditor_report` | Auditor 산출물 | | `fixer_report_id`, `fixer_report` | Fixer 산출물 | | `advisor_report_id`, `advisor_report` | Advisor 산출물 | ## 4. 실행 흐름 ### 4.1 진입점 `run.py`가 실행 진입점이다. 처리 순서: 1. `.env`를 로드한다. 2. `create_tables()`로 PostgreSQL 테이블을 생성한다. 3. CLI 인자를 파싱하여 실행 태스크를 결정한다. 4. `get_mcp_tools()`로 MCP 도구를 로드한다. 5. `ChatOpenAI` 모델 객체를 생성한다. 6. `create_knowledge_agent_graph(task, mcp_tools)`로 LangGraph 워크플로우를 만든다. 7. 초기 상태를 넣고 `app.ainvoke(initial_state)`로 실행한다. 지원 CLI: | 옵션 | 실행 태스크 | |---|---| | `--maintenance` | 전체 유지보수 루프 | | `--analyze` | 지식 공백 분석 | | `--research` | 외부 조사 및 문서 수집 | | `--curate` | URL 선별 및 LightRAG 적재 | | `--audit` | 그래프 품질 감사 | | `--fix` | 품질 문제 수정 | | `--advise` | 시스템 개선 제안 | ### 4.2 LangGraph 워크플로우 `knowledge_agent.py`가 태스크별 그래프를 구성한다. 전체 유지보수 흐름: ```text analyst → save_analyst_report → researcher → curator → auditor → save_auditor_report → fixer → save_fixer_report → advisor → save_advisor_report → END ``` 개별 태스크는 해당 노드와 저장 노드만 실행한다. ## 5. 데이터베이스 명세 `db_utils.py`는 PostgreSQL을 사용하며, 실행 시 다음 테이블을 생성한다. ### 5.1 보고서 테이블 공통 구조: ```sql id SERIAL PRIMARY KEY report_id VARCHAR(255) UNIQUE NOT NULL report JSONB created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ``` 테이블: | 테이블 | 저장 대상 | |---|---| | `analyst_reports` | 지식베이스 요약 및 지식 공백 | | `researcher_reports` | 지식 공백별 검색 계획 및 검색 결과 | | `curator_reports` | 선별 URL 및 적재 상태 | | `auditor_reports` | 그래프 품질 문제 | | `fixer_reports` | 수정 실행 결과 | | `advisor_reports` | 시스템 개선 제안 | ### 5.2 문서 테이블 `documents` 테이블: ```sql id SERIAL PRIMARY KEY url TEXT UNIQUE NOT NULL raw_document BYTEA markdown_content TEXT summary TEXT created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ``` 역할: | 컬럼 | 설명 | |---|---| | `url` | 원본 URL. 중복 방지 기준 | | `raw_document` | HTML/PDF 원문 바이너리 | | `markdown_content` | 본문 추출 결과 | | `summary` | LLM 요약 | 범용 온톨로지 플랫폼에서는 이 테이블을 `source_documents` 또는 `collected_documents`로 확장하고, `domain`, `source_type`, `crawl_status`, `content_hash`, `license`, `language`, `published_at`, `ontology_project_id` 같은 컬럼을 추가하는 것이 좋다. ## 6. 에이전트별 기능명세 ### 6.1 Analyst 파일: `sub_agents/analyst.py` 프롬프트: `prompts/analyst_prompt.txt` 목적: LightRAG 지식베이스의 현재 상태를 분석하고, 지식 공백을 구조화된 연구 주제로 변환한다. 입력: | 입력 | 설명 | |---|---| | `state.messages[0].content` | 분석 지시문 | | `mcp_tools` | `query`, `graphs_get`, `graph_labels`, `google_search`, `fetch` | | `analyst_report_id` | 실행 시각 기반 ID | 처리: 1. LightRAG 질의 및 그래프 조회 도구로 기존 지식베이스를 탐색한다. 2. 5-10개 수준의 주제 테마를 만든다. 3. 외부 검색으로 주제 지형을 보완한다. 4. 시간적/논리적 지식 공백을 식별한다. 5. 각 공백을 Researcher가 사용할 수 있는 `research_topic` 객체로 만든다. 6. JSON 보고서를 반환한다. 7. `save_analyst_report_node`가 JSON을 복구/파싱한 후 DB에 저장한다. 출력 JSON 핵심 스키마: ```json { "report_id": "ana_...", "knowledge_base_summary": { "summary": "...", "themes": [ { "theme_id": "T1", "description": "..." } ] }, "identified_gaps": [ { "gap_id": "G1", "description": "...", "research_topic": { "title": "...", "summary": "...", "key_questions": [], "keywords": [], "sources_to_consult": [], "sources_to avoid": [] } } ] } ``` 재사용 판단: | 항목 | 판단 | |---|---| | 지식 공백 탐지 패턴 | 거의 그대로 재사용 가능 | | 출력 스키마 | 온톨로지 구축용으로 확장 필요 | | 도구 의존성 | LightRAG 도구명에 의존하므로 어댑터 필요 | 온톨로지 플랫폼 확장안: `research_topic`에 다음 필드를 추가하는 것이 좋다. | 필드 | 설명 | |---|---| | `target_ontology_scope` | 구축 대상 온톨로지 범위 | | `candidate_entity_types` | 예상 엔티티 유형 | | `candidate_relation_types` | 예상 관계 유형 | | `competency_questions` | 온톨로지가 답해야 하는 역량 질문 | | `source_priority_policy` | 공식 문서, 논문, 웹문서 등 우선순위 | ### 6.2 Researcher 파일: `sub_agents/researcher.py` 프롬프트: `planner_prompt.txt`, `refiner_prompt.txt`, `summarizer_prompt.txt` 목적: Analyst가 만든 지식 공백별 연구 주제를 바탕으로 검색 계획을 세우고, URL을 검색하고, 원문을 수집/정제/요약하여 DB에 저장한다. 입력: | 입력 | 설명 | |---|---| | 최신 `analyst_reports` | `initialize_researcher()`가 DB에서 로드 | | `google_search` MCP 도구 | 검색 실행 | | `process_url()` | URL 수집 및 문서화 | | `summarizer_executor` | 문서 요약 | 처리 단계: 1. `initialize_researcher()`가 최신 Analyst 보고서를 읽는다. 2. `identified_gaps`를 `researcher_gaps_todo`로 변환한다. 3. Planner가 각 `research_topic`에 대해 5개 검색 계획을 만든다. 4. 각 검색 계획을 `google_search`로 실행한다. 5. 검색 결과 URL마다 `process_url()`을 호출한다. 6. `process_url()`은 `documents` 테이블에 URL을 추가하고 원문/마크다운을 저장한다. 7. Refiner가 검색 결과의 충분성을 평가한다. 8. 부족하면 최대 2개의 추가 검색을 수행한다. 9. 저장된 마크다운 문서를 요약한다. 10. `researcher_reports`에 공백별 검색 결과를 업데이트한다. 검색 계획 스키마: ```json { "searches": [ { "search_id": "S_P1", "query": "...", "rationale": "...", "parameters": { "dateRestrict": "y1", "sort": "date", "num": 10 } } ] } ``` Refiner 출력 스키마: ```json { "status": "sufficient", "rationale": "..." } ``` 또는: ```json { "status": "insufficient", "rationale": "...", "searches": [ { "search_id": "S_R1", "query": "...", "rationale": "...", "parameters": {} } ] } ``` 요약 출력 스키마: ```json { "summary": "2-4 sentence summary" } ``` 재사용 판단: | 항목 | 판단 | |---|---| | Planner/Refiner/Summarizer 구조 | 거의 그대로 재사용 가능 | | URL 중복 저장 | 그대로 재사용 가능 | | HTML/PDF 수집 | 보완 후 재사용 권장 | | 도메인별 검색 전략 | 프롬프트만 교체/확장 | 범용 온톨로지 플랫폼에서 가장 가치가 높은 모듈이다. 특히 “지식 공백 → 검색 계획 → 검색 결과 → 문서 저장 → 요약” 흐름은 도메인별 온톨로지 구축의 자료 수집 레이어로 그대로 사용할 수 있다. ### 6.3 Content Processor 파일: `tools.py` 목적: URL을 원문 문서와 마크다운 콘텐츠로 변환한다. 함수: | 함수 | 설명 | |---|---| | `fetch_and_generate_markdown(url, logger)` | URL의 Content-Type을 확인하고 HTML/PDF를 처리 | | `process_url(url, logger)` | URL 중복 확인, 신규 URL이면 수집 후 DB 업데이트 | | `human_approval(plan)` | 파괴적 작업 전 터미널 승인 요청 | HTML 처리: 1. `requests.head()`로 Content-Type 확인 2. `text/html`이면 `trafilatura.fetch_url()`로 HTML 다운로드 3. `trafilatura.extract()`로 본문 추출 4. 추출 결과가 없거나 200자 미만이면 Playwright로 브라우저 렌더링 5. `main`, `#main`, `#content`, `[role="main"]`, `body` 순으로 텍스트 추출 PDF 처리: 1. `requests.get()`으로 PDF 다운로드 2. `pdfplumber`로 페이지별 텍스트 추출 3. 줄 단위로 연결하여 `markdown_content`에 저장 실패 처리: 지원하지 않는 Content-Type 또는 예외 발생 시: ```text [MARKDOWN_GENERATION_FAILED: ...] ``` 재사용 판단: | 항목 | 판단 | |---|---| | URL 중복 등록 | 그대로 사용 가능 | | Trafilatura 우선 + Playwright fallback | 그대로 사용 가능 | | PDF 텍스트 추출 | 그대로 사용 가능 | | 403/SSL/JS 복잡 사이트 대응 | 개선 필요 | | Content-Type이 부정확한 서버 대응 | 개선 필요 | | robots.txt/저작권/라이선스 정책 | 추가 필요 | ### 6.4 Curator 파일: `sub_agents/curator.py` 프롬프트: `search_ranker_prompt.txt`, `ingester_prompt.txt` 목적: Researcher의 검색 결과를 평가해 실제 LightRAG에 넣을 URL을 선별하고 적재한다. 처리: 1. `initialize_curator()`가 최신 Researcher 보고서를 읽는다. 2. 검색 결과별로 Search Ranker 에이전트를 실행한다. 3. 각 URL을 `approved` 또는 `denied`로 분류한다. 4. 승인 URL 목록을 `curator_reports.urls_for_ingestion`에 저장한다. 5. Ingester 에이전트가 LightRAG 문서 적재 도구를 호출한다. 6. URL별 적재 상태를 저장한다. Search Ranker 출력 스키마: ```json { "ranked_urls": [ { "url": "https://example.com", "status": "approved", "rationale": "..." } ] } ``` Ingester 출력 스키마: ```json { "url_ingestion_status": [ { "url": "https://example.com", "status": "ingested" } ] } ``` 현재 코드상 주의점: `curator.py`에서는 다음 형태로 호출한다. ```python update_curator_report(tool_input) ``` 하지만 `db_utils.py`의 실제 함수 시그니처는 다음과 같다. ```python update_curator_report(report_id: str, job: str, results: list) ``` 따라서 현재 상태로는 Curator 실행 중 타입 오류가 발생할 가능성이 높다. 다음처럼 수정해야 한다. ```python update_curator_report(report_id, "urls_for_ingestion", approved_urls) update_curator_report(report_id, "url_ingestion_status", curator_url_ingestion_status) ``` 재사용 판단: | 항목 | 판단 | |---|---| | URL 평가 기준 | 거의 그대로 재사용 가능 | | URL 승인/거부 JSON 계약 | 그대로 사용 가능 | | LightRAG 적재 흐름 | MCP 도구명 확인 후 사용 | | 현재 구현 안정성 | 수정 후 사용 필요 | ### 6.5 Auditor 파일: `sub_agents/auditor.py` 프롬프트 파일: `prompts/auditor_prompt.txt`는 비어 있음 실제 프롬프트: 코드 내 문자열 목적: LightRAG 그래프를 조회하여 중복 엔티티, 정규화 오류, 관계 품질 문제를 찾는다. 사용 도구: | 도구 | 설명 | |---|---| | `graphs_get` | 그래프 조회 | | `query` | 지식베이스 질의 | 현재 구현상 문제: 1. `save_auditor_report_node()`에서 `save_auditor_report()`를 호출하지만 import하지 않았다. 2. `create_openai_tools_agent()` 결과를 `AgentExecutor`로 감싸지 않고 직접 `ainvoke()`한다. 3. 저장 시 `save_auditor_report({"auditor_report": json.dumps(report_json)})` 형태로 넘기는데, `_save_report()`는 최상위 `report_id`를 요구한다. 이 형태는 `report_id` 누락 오류를 만들 수 있다. 4. `auditor_prompt.txt`가 비어 있어 프롬프트 관리 체계와 코드가 불일치한다. 재사용 판단: | 항목 | 판단 | |---|---| | 감사 에이전트 개념 | 그대로 재사용 가능 | | 현재 코드 | 수정 필요 | | 프롬프트 파일화 | 필요 | | 감사 결과 스키마 | 새로 명확화 필요 | 온톨로지 플랫폼용 Auditor 권장 스키마: ```json { "report_id": "aud_...", "ontology_project_id": "...", "issues": [ { "issue_id": "Q1", "issue_type": "duplicate_entity | relation_conflict | weak_evidence | naming_inconsistency | schema_violation", "severity": "low | medium | high | critical", "entities": [], "relations": [], "evidence": [], "recommended_action": "..." } ] } ``` ### 6.6 Fixer 파일: `sub_agents/fixer.py` 프롬프트 파일: `prompts/fixer_prompt.txt`는 비어 있음 실제 프롬프트: 코드 내 문자열 목적: Auditor가 찾은 그래프 품질 문제를 수정한다. 사용 도구: | 도구 | 설명 | |---|---| | `graph_update_entity` | 엔티티 수정 | | `documents_delete_entity` | 엔티티 삭제 | | `graph_update_relation` | 관계 수정 | | `documents_delete_relation` | 관계 삭제 | | `graph_entity_exists` | 엔티티 존재 확인 | | `human_approval` | 수정 계획 승인 | | `load_latest_report` | 최신 보고서 로드 | 현재 구현상 문제: 1. `save_fixer_report()`를 import하지 않았다. 2. `load_latest_report`는 LangChain `@tool`로 감싸져 있지 않은 일반 함수다. 도구 목록에 직접 넣으면 LangChain 도구로 인식되지 않을 수 있다. 3. `create_openai_tools_agent()` 결과를 `AgentExecutor`로 감싸지 않는다. 4. 저장 보고서 구조가 `_save_report()`의 요구 조건과 맞지 않을 수 있다. 5. CLI/자동 실행 환경에서 `input()` 기반 `human_approval`은 중단 위험이 있다. 재사용 판단: | 항목 | 판단 | |---|---| | 사람 승인 후 수정 패턴 | 매우 중요, 재사용 권장 | | 현재 코드 | 수정 필요 | | 파괴적 작업 정책 | 플랫폼 핵심 기능으로 확장 필요 | 온톨로지 플랫폼에서는 수정 작업을 다음 세 단계로 분리하는 것이 좋다. 1. `FixPlanGenerator`: 수정 계획 생성 2. `ApprovalGate`: 사람 승인 또는 정책 기반 자동 승인 3. `FixExecutor`: 승인된 작업만 실행 ### 6.7 Advisor 파일: `sub_agents/advisor.py` 프롬프트 파일: `prompts/advisor_prompt.txt`는 비어 있음 실제 프롬프트: 코드 내 문자열 목적: 감사/수정 보고서를 분석하여 반복 문제와 시스템 개선안을 제시한다. 사용 도구: | 도구 | 설명 | |---|---| | `list_allowed_directories` | 접근 가능한 디렉터리 조회 | | `list_directory` | 디렉터리 조회 | | `search_files` | 파일 검색 | | `read_text_file` | 파일 읽기 | | `load_latest_report` | 최신 보고서 로드 | 현재 구현상 문제: 1. `save_advisor_report()`를 import하지 않았다. 2. `load_latest_report` 도구화 문제가 있다. 3. `create_openai_tools_agent()` 직접 호출 문제가 있다. 4. 프롬프트 파일이 비어 있다. 재사용 판단: | 항목 | 판단 | |---|---| | 운영 개선 에이전트 개념 | 그대로 재사용 가능 | | 코드 안정성 | 수정 필요 | | 플랫폼 확장 가치 | 높음 | 온톨로지 플랫폼에서는 Advisor가 다음 개선안을 만들도록 확장할 수 있다. | 개선 대상 | 예시 | |---|---| | 엔티티 타입 체계 | 특정 타입 누락, 과도한 `concept/idea` 사용 | | 관계 타입 체계 | 관계명이 너무 일반적이거나 중복됨 | | 수집 정책 | 특정 도메인 실패율, 저품질 출처 비율 | | 프롬프트 | 추출 누락, 명칭 정규화 실패 | | 스키마 | 필수 속성 누락, 식별자 정책 부족 | ## 7. LightRAG 프롬프트 분석 파일: `lightrag/prompt.py` 이 파일은 LightRAG의 엔티티/관계 추출 프롬프트를 JSON 기반으로 재정의한다. 범용 온톨로지 구축 플랫폼에서 매우 중요한 자산이다. ### 7.1 엔티티 타입 정의된 엔티티 타입: | 타입 | 설명 | |---|---| | `organization/institution` | 기관, 기업, 정부, 비영리 조직 | | `person` | 인물 | | `location/geo` | 지리적 장소 | | `event` | 사건 | | `policy/proposal` | 정책, 제안, 공식 계획 | | `law/regulation` | 법률, 규정 | | `tax/fiscal_instrument` | 조세, 수수료, 재정 메커니즘 | | `narrative` | 사회적 서사 | | `misinformation/disinformation` | 허위정보, 조작정보 | | `digital_asset` | 디지털 자산 또는 플랫폼 | | `concept/idea` | 추상 개념 | | `metric/score` | 수치 지표 | | `publication/article` | 보고서, 책, 기사 | | `political_group` | 정치적 집단 | | `scenario/situation` | 상황/맥락 | | `demographic/population` | 인구 집단 | | `publisher/outlet` | 출판사/매체 | | `time_period/era` | 시기/기간 | ### 7.2 관계 타입 정의된 관계 타입: ```text TARGETS, EVALUATES, PRODUCES, CAUSES, IS_A, IS_PART_OF, IS_LOCATED_IN, INFLUENCES, PUBLISHED_BY, LED_BY, CRITICIZES, SUPPORTS, USES, INVOLVES, ESTIMATES, AFFIRMED_BY, PAYS_INTO, REIMBURSES ``` ### 7.3 출력 스키마 ```json { "entities": [ { "name": "...", "type": "...", "description": "..." } ], "relationships": [ { "source": "...", "target": "...", "description": "...", "type": "...", "strength": 8 } ] } ``` ### 7.4 재사용 가치 이 파일은 범용 온톨로지 구축 플랫폼의 “기본 온톨로지 추출 프롬프트”로 활용 가치가 높다. 특히 다음 원칙이 좋다. 1. 엔티티 타입을 JSON 사전으로 명시한다. 2. 관계 타입을 고정 리스트로 제한한다. 3. `UNKNOWN` 타입을 금지하고 애매한 경우 `concept/idea`로 보낸다. 4. 관계 강도 `strength`를 함께 출력한다. 5. 결과를 반드시 JSON으로 강제한다. 다만 현재 타입 체계는 정치/사회정책 도메인에 치우쳐 있다. 범용 온톨로지 플랫폼에서는 프로젝트별 타입 팩을 주입할 수 있어야 한다. ## 8. 재사용 가능 모듈 평가 | 모듈 | 재사용 등급 | 사유 | |---|---:|---| | `knowledge_agent.py` LangGraph 구성 | 높음 | 워크플로우 분기와 노드 연결 구조가 명확 | | `run.py` 실행 진입점 | 중간 | 기본 실행 구조는 좋지만 설정/모델 기본값 정리 필요 | | `state.py` | 높음 | 멀티 에이전트 상태 전달 모델로 활용 가능 | | `db_utils.py` 보고서 저장 | 중간 | 기본 구조는 좋지만 스키마 확장과 일부 저장 구조 수정 필요 | | `db_utils.py` 문서 저장 | 높음 | URL 중복 방지와 원문/마크다운/요약 저장이 유용 | | `tools.py` URL 처리 | 높음 | HTML/PDF 수집 파이프라인이 실용적 | | `researcher.py` | 높음 | 자료 수집 자동화 핵심 모듈 | | `analyst.py` | 높음 | 지식 공백 기반 조사 설계에 적합 | | `curator.py` | 중간 | 개념은 좋지만 코드 수정 필요 | | `auditor.py` | 낮음-중간 | 개념은 좋지만 구현 완성도가 낮음 | | `fixer.py` | 낮음-중간 | 사람 승인 패턴은 좋지만 코드 수정 필요 | | `advisor.py` | 중간 | 운영 개선 아이디어는 좋지만 구현 정리 필요 | | `prompts/*.txt` | 높음 | JSON 계약과 역할 분리가 명확 | | `lightrag/prompt.py` | 매우 높음 | 온톨로지 추출 프롬프트 기반으로 직접 활용 가능 | ## 9. 현재 코드의 주요 결함 및 수정 필요 사항 ### 9.1 실행 오류 가능성이 높은 부분 | 위치 | 문제 | 영향 | 수정 방향 | |---|---|---|---| | `curator.py` | `update_curator_report()` 호출 인자 불일치 | Curator 실행 실패 | `update_curator_report(report_id, job, results)`로 수정 | | `auditor.py` | `save_auditor_report` import 누락 | 저장 실패 | `from db_utils import save_auditor_report` 추가 | | `fixer.py` | `save_fixer_report` import 누락 | 저장 실패 | import 추가 | | `advisor.py` | `save_advisor_report` import 누락 | 저장 실패 | import 추가 | | `auditor.py`, `fixer.py`, `advisor.py` | `create_openai_tools_agent()`를 `AgentExecutor`로 감싸지 않음 | 정상 실행 불확실 | Researcher/Analyst 방식으로 통일 | | `auditor.py`, `fixer.py`, `advisor.py` | 저장 데이터에 최상위 `report_id`가 없을 수 있음 | `_save_report()` 오류 | 보고서 스키마 통일 | | `prompts/auditor_prompt.txt` 등 | 파일은 있으나 비어 있고 코드에 프롬프트 하드코딩 | 유지보수성 저하 | 프롬프트 파일로 이동 | | `load_latest_report` | 일반 함수를 도구 목록에 직접 삽입 | LangChain 도구 인식 실패 가능 | `@tool` 래핑 또는 에이전트 외부에서 로드 | ### 9.2 설계상 보완점 | 영역 | 보완 필요 | |---|---| | 도메인 독립성 | LightRAG 도구명, 정치/정책형 엔티티 타입에 의존 | | 수집 정책 | robots.txt, 라이선스, 출처 신뢰도, 차단 도메인 정책 부족 | | 실패 복구 | 403, SSL 오류, JS 렌더링 실패, 빈 본문 처리 강화 필요 | | 중복 문서 | URL 기준 중복만 처리. `content_hash` 기반 중복 제거 필요 | | 보고서 버전 | 프로젝트/도메인/실행 단위 식별자 부족 | | 승인 흐름 | CLI `input()` 기반 승인만 제공. 웹 UI/API 승인 필요 | | 감사 스키마 | 품질 이슈 타입, 심각도, 수정안 스키마가 불명확 | | 테스트 | 단위 테스트/통합 테스트 부재 | ## 10. 범용 온톨로지 구축 플랫폼 적용 설계 ### 10.1 추천 플랫폼 아키텍처 ```text Ontology Project ├─ Source Discovery │ ├─ Analyst │ └─ Research Planner ├─ Source Collection │ ├─ Search Executor │ ├─ URL Processor │ └─ Document Store ├─ Ontology Extraction │ ├─ Entity Extractor │ ├─ Relation Extractor │ └─ Schema Mapper ├─ Curation │ ├─ Source Ranker │ ├─ Evidence Scorer │ └─ Ingestion Manager ├─ Quality Control │ ├─ Auditor │ ├─ Fix Planner │ └─ Approval Gate └─ Continuous Improvement └─ Advisor ``` ### 10.2 기존 소스와 매핑 | 플랫폼 기능 | 기존 소스 | |---|---| | 프로젝트 실행 워크플로우 | `knowledge_agent.py`, `run.py` | | 상태 전달 | `state.py` | | 지식 공백 탐지 | `sub_agents/analyst.py`, `analyst_prompt.txt` | | 검색 전략 생성 | `sub_agents/researcher.py`, `planner_prompt.txt` | | 검색 결과 보완 판단 | `refiner_prompt.txt` | | 문서 수집/정제 | `tools.py` | | 문서 저장 | `db_utils.py`의 `documents` | | 요약 | `summarizer_prompt.txt` | | URL 선별 | `curator.py`, `search_ranker_prompt.txt` | | LightRAG 적재 | `curator.py`, `ingester_prompt.txt` | | 그래프 감사 | `auditor.py` | | 수정 승인/실행 | `fixer.py`, `human_approval()` | | 시스템 개선 | `advisor.py` | | 엔티티/관계 추출 프롬프트 | `lightrag/prompt.py` | ### 10.3 거의 변형 없이 가져갈 수 있는 기능 1. LangGraph 기반 워크플로우 분기 구조 2. `AgentState` 중심 상태 전달 방식 3. Analyst의 지식 공백 탐지 프롬프트 구조 4. Researcher의 Planner/Refiner/Summarizer 단계 구조 5. URL 중복 저장 후 원문/마크다운/요약을 관리하는 문서 저장소 구조 6. Trafilatura 우선, Playwright fallback 수집 전략 7. JSON 출력 강제 프롬프트 패턴 8. LightRAG 엔티티/관계 추출 프롬프트의 JSON 스키마 방식 9. Human approval을 거친 그래프 수정 개념 ### 10.4 반드시 수정 후 가져갈 기능 1. Curator의 DB 업데이트 호출 오류 2. Auditor/Fixer/Advisor의 누락 import 3. Auditor/Fixer/Advisor의 AgentExecutor 사용 방식 4. 보고서 저장 스키마 불일치 5. 빈 프롬프트 파일과 하드코딩 프롬프트 분리 6. `load_latest_report` 도구화 방식 7. 수집 실패 및 차단 도메인 처리 8. 프로젝트/도메인 단위 멀티테넌시 스키마 ## 11. 기능명세서 ### 11.1 프로젝트 관리 | 기능 ID | 기능명 | 설명 | 입력 | 출력 | |---|---|---|---|---| | ONT-PROJ-001 | 온톨로지 프로젝트 생성 | 도메인, 목표, 기본 타입 체계를 가진 프로젝트 생성 | 프로젝트명, 도메인, 설명 | `ontology_project_id` | | ONT-PROJ-002 | 프로젝트별 실행 설정 | 모델, MCP 도구, 수집 정책, 승인 정책 설정 | 설정 JSON | 저장된 설정 | | ONT-PROJ-003 | 프로젝트별 실행 이력 조회 | 분석/수집/적재/감사 이력 확인 | 프로젝트 ID | 실행 목록 | ### 11.2 지식베이스 분석 | 기능 ID | 기능명 | 설명 | 입력 | 출력 | |---|---|---|---|---| | ONT-ANA-001 | 기존 지식베이스 요약 | 그래프와 문서를 조회하여 현재 지식 범위 요약 | 프로젝트 ID | 주제 요약 | | ONT-ANA-002 | 지식 공백 탐지 | 시간적/논리적/출처상 공백 식별 | 지식베이스 요약 | 공백 목록 | | ONT-ANA-003 | 연구 주제 생성 | 공백을 검색 가능한 조사 브리프로 변환 | 공백 목록 | `research_topic` 목록 | | ONT-ANA-004 | 역량 질문 생성 | 온톨로지가 답해야 할 질문 생성 | 도메인 설명 | `competency_questions` | ### 11.3 자료 검색 및 수집 | 기능 ID | 기능명 | 설명 | 입력 | 출력 | |---|---|---|---|---| | ONT-RES-001 | 검색 계획 생성 | 연구 주제별 검색 쿼리와 파라미터 생성 | `research_topic` | 검색 계획 | | ONT-RES-002 | 검색 실행 | MCP 검색 도구로 검색 수행 | 검색 계획 | 검색 결과 | | ONT-RES-003 | URL 중복 확인 | URL이 이미 저장되어 있는지 확인 | URL | 문서 ID, 신규/기존 상태 | | ONT-RES-004 | HTML 본문 추출 | Trafilatura/Playwright로 본문 추출 | URL | 원문, 마크다운 | | ONT-RES-005 | PDF 텍스트 추출 | PDF를 다운로드하고 텍스트 추출 | URL | 원문, 텍스트 | | ONT-RES-006 | 문서 요약 | 마크다운을 16k 토큰 이하로 제한 후 요약 | 문서 ID | 요약 | | ONT-RES-007 | 검색 결과 충분성 평가 | 초기 검색 결과가 연구 질문을 충족하는지 판단 | 검색 결과 | 충분/부족, 보완 검색 | ### 11.4 출처 큐레이션 | 기능 ID | 기능명 | 설명 | 입력 | 출력 | |---|---|---|---|---| | ONT-CUR-001 | URL 품질 평가 | 관련성, 권위성, 품질, 신규성 기준 평가 | 검색 결과 | 승인/거부 URL | | ONT-CUR-002 | 적재 대상 선정 | 승인 URL을 적재 목록에 추가 | 승인 URL | 적재 대기 목록 | | ONT-CUR-003 | 지식베이스 적재 | LightRAG 또는 내부 그래프 저장소에 문서 적재 | URL/문서 ID | 적재 상태 | | ONT-CUR-004 | 적재 상태 추적 | URL별 적재 성공/실패 기록 | 적재 작업 ID | 상태 목록 | ### 11.5 온톨로지 추출 | 기능 ID | 기능명 | 설명 | 입력 | 출력 | |---|---|---|---|---| | ONT-EXT-001 | 엔티티 타입 사전 관리 | 프로젝트별 엔티티 타입 정의 | 타입 정의 JSON | 타입 사전 | | ONT-EXT-002 | 관계 타입 사전 관리 | 프로젝트별 관계 타입 정의 | 관계 정의 JSON | 관계 사전 | | ONT-EXT-003 | 엔티티/관계 추출 | 문서 청크에서 엔티티와 관계 추출 | 문서 청크, 타입 사전 | 엔티티/관계 JSON | | ONT-EXT-004 | 명칭 정규화 | 약어/별칭을 표준명으로 통합 | 엔티티 후보 | 표준 엔티티 | | ONT-EXT-005 | 증거 연결 | 엔티티/관계에 원문 근거 연결 | 추출 결과 | evidence 링크 | | ONT-EXT-006 | 관계 강도 산정 | 관계의 명시성/확실성 점수 산정 | 관계 후보 | `strength` | ### 11.6 품질 감사 | 기능 ID | 기능명 | 설명 | 입력 | 출력 | |---|---|---|---|---| | ONT-AUD-001 | 중복 엔티티 탐지 | 이름/별칭/설명 기반 중복 탐지 | 그래프 | 중복 후보 | | ONT-AUD-002 | 명칭 불일치 탐지 | 동일 개념의 표기 차이 탐지 | 그래프 | 정규화 이슈 | | ONT-AUD-003 | 관계 충돌 탐지 | 상충 관계나 잘못된 방향 탐지 | 그래프 | 관계 이슈 | | ONT-AUD-004 | 스키마 위반 탐지 | 허용되지 않은 타입/관계 탐지 | 그래프, 스키마 | 위반 목록 | | ONT-AUD-005 | 약한 근거 탐지 | evidence가 부족한 엔티티/관계 탐지 | 그래프 | 저신뢰 항목 | ### 11.7 수정 및 승인 | 기능 ID | 기능명 | 설명 | 입력 | 출력 | |---|---|---|---|---| | ONT-FIX-001 | 수정 계획 생성 | 감사 이슈를 실행 가능한 수정 계획으로 변환 | 감사 보고서 | 수정 계획 | | ONT-FIX-002 | 사람 승인 요청 | 삭제/병합/관계 변경 전 승인 요청 | 수정 계획 | 승인/거부 | | ONT-FIX-003 | 엔티티 수정 | 이름, 타입, 설명 수정 | 승인된 계획 | 수정 결과 | | ONT-FIX-004 | 관계 수정 | 관계 타입, 방향, 설명, 강도 수정 | 승인된 계획 | 수정 결과 | | ONT-FIX-005 | 엔티티/관계 삭제 | 승인된 파괴적 변경 실행 | 승인된 계획 | 삭제 결과 | | ONT-FIX-006 | 수정 이력 저장 | 누가/언제/무엇을 변경했는지 저장 | 수정 결과 | 이력 레코드 | ### 11.8 운영 개선 | 기능 ID | 기능명 | 설명 | 입력 | 출력 | |---|---|---|---|---| | ONT-ADV-001 | 실패 패턴 분석 | 수집/적재/추출/감사 실패 로그 분석 | 실행 로그 | 실패 패턴 | | ONT-ADV-002 | 프롬프트 개선 제안 | 반복 오류를 줄이기 위한 프롬프트 수정안 제시 | 감사/수정 보고서 | 개선안 | | ONT-ADV-003 | 타입/관계 체계 개선 제안 | 누락/중복 타입 및 관계 개선 | 추출 결과 | 스키마 제안 | | ONT-ADV-004 | 수집 정책 개선 제안 | 차단 도메인, 신뢰 출처, 우선순위 개선 | 수집 로그 | 정책 제안 | | ONT-ADV-005 | Top N 개선 리포트 | 가장 영향도 높은 개선안을 정리 | 전체 보고서 | 개선 보고서 | ## 12. 권장 리팩터링 순서 1. Curator/Auditor/Fixer/Advisor 실행 오류를 먼저 수정한다. 2. 보고서 저장 스키마를 모든 에이전트에서 통일한다. 3. 하드코딩 프롬프트를 `prompts/*.txt`로 이동한다. 4. `load_latest_report`를 에이전트 도구로 쓸지, 노드 내부 로직으로 쓸지 분리한다. 5. DB 스키마에 `ontology_project_id`와 실행 ID를 추가한다. 6. 문서 테이블에 `content_hash`, `source_status`, `source_type`, `language`, `license`, `last_checked_at`을 추가한다. 7. LightRAG 프롬프트의 엔티티/관계 타입을 프로젝트별 설정으로 분리한다. 8. Auditor/Fixer 스키마를 명확히 정의하고 승인 UI/API를 설계한다. 9. 수집 실패 도메인 blocklist를 DB화한다. 10. 주요 기능별 테스트를 추가한다. ## 13. 결론 `knowledge_agent-main`은 범용 온톨로지 구축 플랫폼의 초기 골격으로 활용 가치가 높다. 특히 Analyst-Researcher-Curator로 이어지는 “지식 공백 기반 자료 수집 루프”와 `lightrag/prompt.py`의 JSON 기반 엔티티/관계 추출 프롬프트는 거의 그대로 가져와도 된다. 다만 현재 프로젝트는 연구/프로토타입 성격이 강하며, 전체 유지보수 워크플로우를 바로 운영 환경에 넣기에는 Curator 이후 단계의 코드 안정성이 부족하다. 따라서 기본 소스로 채택하되, 먼저 실행 오류와 보고서 스키마를 정리하고, 이후 범용 온톨로지 플랫폼에 맞게 프로젝트 단위 설정, 도메인별 타입 체계, 품질 감사/승인 체계를 확장하는 방식이 적합하다.