Metadata-Version: 2.4
Name: thesis-review-agent
Version: 0.0.7
Summary: AI-assisted HWPX thesis citation and reference validation
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: openai-agents>=0.22.3
Requires-Dist: langgraph>=1.2.11
Requires-Dist: python-hwpx>=6.4.0
Requires-Dist: python-dotenv>=1.0.0
Provides-Extra: dev
Requires-Dist: pytest>=9.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=1.0.0; extra == "dev"

# Thesis Review Agent

HWPX 논문에서 본문 인용과 참고문헌을 추출하고, AI 분류와 규칙 검증으로 표기 오류 후보를 반환하는 Python 패키지입니다. 문서를 수정하지는 않습니다.

검토 보조 도구이므로 결과를 원문 및 적용할 학술 작성 지침과 대조해 확인하세요. AI 분류나 자동 검증은 완전한 학술적 판단을 보장하지 않습니다.

## 설치 및 준비

- Python 3.12 이상
- OpenAI API 키
- 검토할 HWPX 파일

```bash
python -m pip install thesis-review-agent
export OPENAI_API_KEY="your-api-key"
```

Windows PowerShell에서는 API 키를 다음처럼 설정할 수 있습니다.

```powershell
$env:OPENAI_API_KEY = "your-api-key"
```

기본 모델은 `gpt-5.6-luna`입니다. AI 호출 시 문장과 참고문헌 등 문서 내용이 API로 전달되고 사용료가 발생할 수 있습니다. 민감한 문서를 처리하기 전 조직의 보안 정책과 API 사용 조건을 확인하세요.

## 바로 사용하기

아래 코드는 파일을 검토하고 CIT·REF·TYP 위반 후보를 JSON으로 출력합니다.

```python
import asyncio
import json
from pathlib import Path

from thesis_review_agent import ThesisReviewAgent


async def main() -> None:
    hwpx_bytes = Path("thesis.hwpx").read_bytes()
    agent = ThesisReviewAgent()

    result = await agent.graph.ainvoke({"hwpx_bytes": hwpx_bytes})

    report = {
        "quotation_violations": [
            item.model_dump(mode="json")
            for item in result["quotation_violations"]
        ],
        "reference_violations": [
            item.model_dump(mode="json")
            for item in result["reference_violations"]
        ],
    }
    print(json.dumps(report, ensure_ascii=False, indent=2))


asyncio.run(main())
```

`quotation_violations`에는 본문 인용 규칙 위반(CIT)이, `reference_violations`에는 참고문헌 일반 규칙(REF)과 자료유형별 규칙(TYP) 위반이 들어갑니다. 목록이 비어 있으면 해당 실행에서 위반 후보를 찾지 못했다는 뜻이지, 문서가 모든 기준을 충족한다고 보증하는 것은 아닙니다.

### 다른 모델 지정하기

LangGraph 설정의 `configurable.model`로 실행 모델을 지정할 수 있습니다.

```python
result = await agent.graph.ainvoke(
    {"hwpx_bytes": hwpx_bytes},
    config={"configurable": {"model": "gpt-5.6-luna"}},
)
```

설정을 생략하면 패키지 기본 모델을 사용합니다.

## 진행 상황 스트리밍

`ThesisReviewAgent.run()`은 최종 상태 대신 진행 이벤트를 비동기로 제공합니다. 이벤트의 `type`은 `custom` 또는 `updates`이고, 내용은 `data`에 있습니다.

```python
async def show_progress(hwpx_bytes: bytes) -> None:
    async for event in ThesisReviewAgent().run(hwpx_bytes):
        if event["type"] == "custom":
            print(event["data"].get("message", ""))
        elif event["type"] == "updates":
            print("State 변경:", event["data"].keys())
```

`updates`는 각 노드가 반환한 변경분이지 전체 최종 결과가 아닙니다. 최종 결과가 필요하면 앞의 `agent.graph.ainvoke(...)` 예제를 사용하세요.

## 결과 읽기

각 위반은 JSON으로 변환할 수 있는 Pydantic 모델입니다.

| 필드 | 의미 |
| --- | --- |
| `rule_id` | 위반 후보의 규칙 ID (`CIT-001`, `REF-021`, `TYP-009` 등) |
| `message` | 위반으로 판단한 이유와 수정 안내 |
| `quotation` | 위반된 본문 인용 문자열. 인용 위반 결과에만 포함 |
| `text` | 인용이 포함된 원문 문장 또는 참고문헌 항목 |
| `location` | 문서 위치. `section_index`, `paragraph_index`, `run_index`, `content_index`, `sentence_index`를 포함하며 각 인덱스는 0부터 시작 |

예를 들어 `result["reference_violations"][0].model_dump(mode="json")`은 첫 참고문헌 위반을 JSON 호환 딕셔너리로 변환합니다. 규칙 ID는 인용 검증의 CIT, 일반 참고문헌 검증의 REF, 자료유형별 참고문헌 검증의 TYP로 구분됩니다.

## 검증 흐름

```text
HWPX 변환 → 문장 분류
  ├─ 본문 인용 추출·분류
  └─ 참고문헌 추출
       ├─ 자료유형 분류 → 유형별 TYP 검증
       └─ 일반 REF 규칙용 특성 분류 → REF 검증
  참고문헌 검증 완료 → CIT 검증
```

분류가 필요한 적용 조건이나 자료 특성은 AI 노드에서 판별하고, 해당 분류 결과를 바탕으로 검증 노드가 규칙을 적용합니다. 그래프에는 CIT/REF/TYP 검증 결과를 하나의 최종 의견으로 요약하는 `review_node`가 포함되어 있지 않습니다. State와 노드별 상세 흐름은 [`thesis_review_agent/graph/README.md`](thesis_review_agent/graph/README.md)를 참고하세요.

## 제한 사항

- 지원 입력은 HWPX 바이트이며, DOCX/PDF 입력이나 원본 문서 자동 수정은 제공하지 않습니다.
- 추출·분류가 잘못되거나 문서 서식 정보가 충분하지 않으면 위반을 놓치거나 오탐할 수 있습니다.
- 그래프 실행 중 발생한 예외는 호출자에게 전달됩니다.
