대화에서 워크플로까지 - 우리가 온톨로지를 쓰는 방법
AI 에이전트에게 업무를 시켜본 사람은 비슷한 벽을 만납니다.
처음 한 번은 놀랍도록 잘합니다. 두 번째도 대체로 됩니다. 그런데 열 번째에도 여전히 같은 설명을 하다보면, 답답함이 자라납니다.
상품 표의 어느 칸이 무엇인지, 중복은 무엇을 기준으로 판정하는지, 자료 조사 시 꼭 채워야하는 항목을 매번 설명하기 피곤해집니다.
에이전트가 멍청해서가 아닙니다. 그 업무에 대해 합의한 내용이 어디에도 남지 않기 때문입니다. 매번 대화에 실려 왔다가 대화와 함께 사라집니다.
우리는 이 문제를 "에이전트를 더 똑똑하게"로 풀지 않기로 했습니다. 대신 업무에 등장하는 명사와 관계를 제품의 핵심으로 만들었습니다. 온톨로지 층입니다.
흩어진 개념
작년부터 우리는 실제 고객사의 업무를 에이전트에 얹어 왔습니다. 상품 데이터베이스를 관리하고, 거래처에 보낼 제안서를 만들고, 광고 성과를 관리하고 새 전략을 실행하는 일들입니다. 잘 돌아갔습니다. 다만 잘 돌아가는 방식을 뜯어보니 이랬습니다.
"상품"이라는 하나의 개념이 최소 다섯 군데에 흩어져 있었습니다. 기능마다 따로 적힌 프롬프트 산문에, 그리고 에이전트가 그때그때 만들어낸 데이터베이스 테이블에.
결과는 실행 시점에 나타납니다. 에이전트가 데이터베이스를 더듬다가, 실패하고, 재시도를 소진하고, 그제서야 사람에게 "확인이 필요합니다"라고 넘어옵니다. 사람이 받아 보면 판단이 필요한 일이 아니라 그냥 값 하나가 빠져 있는 건이었습니다.
에이전트 기술 자체에는 문제가 없었습니다. 없던 것은 명사와 관계였습니다.
기능은 객체에 가하는 동작이다
온톨로지라고 하면 거창하게 들리지만, 우리가 도입한 것은 세 가지 중 두 가지입니다.
- 객체: 이 업무에 등장하는 것들. 상품, 제안서, 상세페이지.
- 링크: 그것들 사이의 관계. 이 상품의 상세페이지, 이 상품으로 나간 제안서들.
- 액션: 객체에 가하는 동작.
세 번째인 액션은 이미 성숙해 있었습니다. 도구, 위험도 판정, 사람 승인, 감사 기록이 모두 그 축에 붙어 있었습니다. 그래서 액션 엔티티를 새로 만들지 않았습니다. 기존 기능 정의에 "무엇에 가하는가" 한 칸을 더했을 뿐입니다.
기능은 객체에 가하는 동작이다.
이 한 문장이 설계의 출발점입니다. 새 개념을 세우는 대신 있던 개념에 목적어를 붙였습니다.
코드에는 '상품'이 없다
고객사의 객체 정의는 이렇게 생겼습니다.

상품
속성: 상품명*, 브랜드, 카테고리, 공급가, 판매가, 원산지, 규격, 조사상태
중복 판정: (브랜드, 상품명)
제약: 판매가 >= 공급가, 공급가 > 0
상품 → 상세페이지 (하나. 재생성하면 치환)
상품 → 제안서 (여럿. 거래처마다 따로 쌓임)
중요한 것은 이 이름들이 전부 데이터라는 점입니다. 우리 코드베이스를 아무리 뒤져도 product도 proposal도 나오지 않습니다. 나와서는 안 됩니다. 나오는 순간 그 고객사가 코드에 눌어붙고, 두 번째 고객은 코드 수정 없이 온보딩할 수 없게 됩니다.
이 정의 하나를 세우자 여러 개가 동시에 따라왔습니다. 단건 상품 등록 폼이 정의에서 파생되고, 중복 판정이 결정적으로 내려오고, 제약 위반이 실행 전에 걸리고, 산출물이 대상에 귀속됩니다. "이 상품의 현재 상세페이지"가 비로소 물어볼 수 있는 질문이 됩니다.
반려의 위치도 바뀌었습니다.
전: 실행 → 에이전트가 헤맴 → 실패 → 재시도 소진 → 반려 → 사람이 확인
후: 접수 시점에 검증 → 안 되면 도구 에러로 에이전트가 자기교정 → 그래도 안 되면 반려
사람 화면에는 정말 사람 판단이 필요한 건만 남습니다.
승격 계단
여기서 제품의 진짜 논점이 나옵니다. 온톨로지 자체는 차별점이 아닙니다. 개념 정의를 잘 해두면 좋다는 건 새로운 주장이 아니고, 누가 그 정의를 쓰느냐도 본질이 아닙니다.
우리가 보는 축은 속도입니다. 에이전트와의 업무는 아래 네 칸을 오릅니다.

| 단계 | 상태 | 이 칸의 성질 |
|---|---|---|
| 1 | 대화 | 탐색적이고 비결정적. 매번 다르게 흘러갑니다 |
| 2 | 승인된 스키마 | 무엇이 무엇인지 합의됨. 변경은 기록으로 남습니다 |
| 3 | 계약된 액션 | 접수 시점 검증, 중복 실행 안전, 감사 가능 |
| 4 | 컴파일드 워크플로 | LLM 호출 없이 도는 경로. 예측 가능하고 값이 쌉니다 |
모든 업무가 1단계에서 시작합니다. 어떤 업무는 영원히 1단계에 있어도 됩니다. 매번 다른 조사, 매번 다른 판단은 그 자리가 맞습니다. 그러나 반복되는 업무가 1단계에 머무르면, 사용자는 매달 같은 설명을 하고 우리는 매번 LLM 값을 냅니다.
차별점은 "누가 온톨로지를 만드는가"가 아니라 "고정된 워크플로로 승격되는 속도"입니다. 고객이 구매하는 것은 결과(예측 가능하고 되돌릴 수 있는 자동화)이고, 승격 속도는 그 결과를 만드는 우리 쪽의 원가에 해당합니다.
솔직히 적어두면, 아직 모든 사례에 완벽히 대응되지 않으며 우리는 여전히 개선 중입니다. 지금 우리가 가진 것은 완성된 3단계까지와, ④의 성질을 부분적으로 보여주는 좁은 경로 하나입니다. 계단를 다 올라간 사례를 보여드릴 수 있게 되면 그때 수치와 함께 다시 쓰겠습니다.
개인 사용자에게도 같은 계단
이 층을 처음 만든 자리는 기업 고객용 포털이었습니다. 그러나 처음부터 특정 고객의 업무가 아니라 일반 기술로 지었습니다. 개인 사용자의 에이전트도 같은 저장소, 같은 도구, 같은 중복 판정 규칙을 씁니다.
다만 계단를 오르는 부품이 다릅니다. 기업 트랙에서 ②칸의 승인자는 우리 쪽 엔지니어지만, 개인 사용자 트랙에서는 사용자 자신입니다. 그래서 세 가지를 원칙으로 뒀습니다.
첫 실행이 곧 발견입니다. "같은 일을 세 번 하면 며칠 뒤에 제안한다"는 모델은 폐기했습니다. 트리거는 빈도가 아니라 형태입니다. 구조화할 수 있는 데이터와 반복 가능한 동작이 한 턴 안에 보이면, 그 턴에 제안합니다. 사용자가 말로 "이거 매번 하게 만들어줘"라고 요청하는 경로도 함께 열려 있습니다.
굳히기는 한 장의 카드입니다. 스키마 승인과 액션 승인을 두 번 묻지 않습니다. 두 번 물으면 두 번 다 거절당합니다.
중복 판정 기준은 처음엔 무릅니다. 첫 대화에서 "이 표의 고유 키가 무엇입니까"를 정확히 답할 수 있는 사용자는 없습니다. 그래서 데이터가 적은 동안에는 기준을 바꿀 수 있게 두고, 쌓인 뒤에 잠급니다. 짧은 시간 안에 완벽한 정의를 받아낼 수 없다는 사실을 설계로 받아들였습니다.
그리고 그 밑에 하나가 더 깔려 있습니다. 되돌릴 수 있어야 승인이 가볍습니다. 승인 마찰의 대부분은 "이거 눌렀다가 잘못되면 어쩌지"에서 오니까요.
강력한 확신
우리가 확신하는 것은 단 하나입니다. 흩어진 개념을 묶어 고정된 워크플로를 만들 때, AI는 비로소 '신기한 장난감'을 넘어 '신뢰할 수 있는 실무자'가 됩니다.
우리는 계속해서 이 승격 계단을 끝까지 오를 것입니다.

