6. 직접 만들기: 회의록 정리 Agent

무엇을 기억할 것인가

이 차시를 마치면

무엇을 기억해야 하는지 State 로 정리합니다.

무엇을 기억해야 하는지 정합니다. 4번 트랙의 4분류를 그대로 씁니다.

코드

"""회의록 정리 Agent 의 State.

트랙 4 의 4분류를 그대로 따른다.
Input / Working / Control / Output 과 감사 로그.
"""
from typing import Annotated, Literal, Optional
import operator

from typing_extensions import TypedDict


class NotesState(TypedDict):
    # 1) Input — 사용자에게 받은 값
    meeting_dir: str          # 회의록이 있는 폴더 (workspace 기준 상대경로)
    target_path: str          # 쓸 파일 (workspace 기준 상대경로)
    requester_id: str

    # 2) Working — 중간 처리 결과
    note_names: list          # 읽은 회의록 파일 이름
    note_texts: list          # 회의록 본문
    actions: list             # 추출한 실행항목

    # 3) Control — 분기와 승인에 필요한 값
    pending_content: str      # 쓸 내용을 확정한 값. 승인 화면과 실행이 이 값을 쓴다
    diff: str                 # 기존 파일과의 차이. 승인 화면에 보여 준다
    target_exists: bool
    risk_level: Literal["low", "high"]
    approved: bool
    executed_action_id: Optional[str]

    # 4) Output — 최종 반환값
    backup_name: Optional[str]
    result: str

    audit_log: Annotated[list[str], operator.add]

State 정의 자체를 겨누는 테스트는 없습니다. 값을 담는 그릇이라 따로 시험할 것이 없기 때문입니다. 대신 이 State 를 쓰는 그래프 테스트 8개가 키 이름과 Reducer 동작을 간접적으로 확인합니다. 키 이름을 바꾸면 그 테스트가 깨집니다.

pending_content 가 Control 인가

내용을 담고 있으니 Working 처럼 보입니다. 그런데 Control 에 둡니다.

이 값이 승인의 대상이기 때문입니다. 사람이 보는 것도 이 값이고 실제로 쓰이는 것도 이 값입니다. 승인 여부(approved)와 짝을 이루므로 같은 자리에 둡니다. 분석

4번 트랙 감사에서 나온 결함이 바로 이 지점이었습니다. 승인 화면에 보인 것과 실제로 실행되는 것이 코드상 이어져 있지 않았습니다. 값을 하나로 확정해 두면 그 문제가 생기지 않습니다.

diff 를 State 에 두는 이유와 주의

차이는 승인 화면에 보여 주기 위해 만듭니다. interrupt 전달값에 실어야 하므로 State 를 거칩니다.

확인 필요 주의할 점이 있습니다. State 에 넣은 값은 Checkpoint 에 남습니다. 회의록이 크면 차이도 커지고, 그만큼 저장소를 씁니다. 이 교재의 예제는 작지만 실제 업무에서는 크기를 재 봐야 합니다.

회의록 본문도 State 에 있습니다

note_texts 에 회의록 원문이 통째로 들어갑니다. 3번 트랙과 4번 트랙에서 배운 원칙을 떠올려 봅니다.

원칙과 현실

State 영역의 설계 질문 3번은 "대용량 원문 대신 ID 나 reference 만 저장할 수 있는가" 였습니다.

여기서는 원문을 담았습니다. 모델에 넘겨야 하고 멱등성 키를 만드는 재료이기 때문입니다. 대신 그 대가를 알고 있어야 합니다 — 회의록 내용이 Checkpoint 에 남습니다. 회의록에 개인정보가 있다면 Checkpoint 저장소를 그 수준으로 관리해야 합니다. 분석

원칙을 어긴 것이 아니라 알고 선택한 것입니다. 그 차이를 기록해 두는 것이 중요합니다.

감사 로그

    audit_log: Annotated[list[str], operator.add]

Reducer 가 붙어 있어 각 Node 의 기록이 덮어써지지 않고 쌓입니다. 4번 트랙에서 배운 그대로입니다.

다음 차시에서 읽기 도구를 붙입니다.

이해도 확인

문항을 불러오는 중입니다.