고갱

[인공지능] 졸업 작품 #9, ChromaDB 구축 본문

인공지능/졸업작품

[인공지능] 졸업 작품 #9, ChromaDB 구축

주인장 고갱 2025. 10. 17. 17:32

이제 거의 최종 단계에 들어섰다.

거의 모든 법률을 벡터 데이터베이스에 옮기는 작업을 진행하고 있다.

정말 이 작업이 너무 오래걸려서 사이에 짬을 내서 게시물을 쓰고있다.

데이터베이스에 문서 삽입을 어제 오후 2시부터 했으니, 대략 12시간이 지나가고 있다.

(너무 오래걸려서 잘 때 까지 다 안 되면 disown 으로 돌려놓고 자던가 해야지...)

 

🤔 그래서 무엇을 하고 있나?

바로 위에서 말한 바와 같이 법률을 벡터 데이터베이스로 옮기고 있다.

문서 수만 2,539,763개로 어마무시하게 많다.

아마 그래서 아직도 데이터베이스에 다 삽입되지 못한 것 같긴 하다. 

 

 

 

사실 원래는 이렇게까지 조문이 많지 않은데, 왜 이렇게 많냐면,

오른쪽 그림처럼 법의 과거 이력까지 모두 저장해주고 있기 때문이다.

 

민간인 입장에서는 "어? 최신 법을 적용하는 거 아니야?" 라는 의문을 가질 수 있지만,

사실 그렇지 않다.

 

 

 

행위시법주의

 

우리나라는 "행위시법주의" 를 채택하고 있다.

즉, 2025년에 재판을 받더라도 2021년에 범죄를 저지른 사건이라면 2021년의 법을 적용한다는 말이다.

 

하지만 이것도 2항을 보면 알 수 있듯이 법률이 변경되어 형이 더 가벼워지는 경우에는 신법을 적용한다.

되게 까다로운 상황이다.

그래서 내가 하고있는 것은 각 법 조항에 변경 이력을 메타데이터로 기록해두어 변경 이력을 추적할 수 있도록 하였다.

 

예를 들어, 형법 제2조가 그대로 형이 가벼워지는 경우면 문제가 되지 않지만 만약 2021년 당시 형법 제2조가 2025년에는 형법 제5조로 이동되었다면 이동 이력을 조회해서 제대로 가져와야 하기 때문이다.

 

문서 메타데이터 구조

그래서 문서 메타데이터 구조는 위와 같다.

일단 임시로 reference_list 를 넣어두었는데, 이건 reference 필드의 값을 ,로 split 하여 배열로 보기 쉽게 해둔 것이다.

(어차피 reference_list 는 사용하지 못한다. 이는 뒤에서 후술하겠다.)

 

아무튼 메타데이터 구조는 기본적으로 아래와 같다.

  • 띄어쓰기를 제거한 법령 이름,
  • 조문 번호 (ex: 제72조 > 72)
  • 조문 부번호 (ex: 제72조의2 > 2, 제72조의3 > 3) (기본값: 1)
  • 참조하는 다른 조문들 (법이름_조문번호_조문부번호)
  • 시행일
  • 법 순서 (과거부터 1번 부여, 최신으로 갈수록 1씩 증가)

여기서 디버그를 용이하게 하기 위해서 임시로 reference_list 를 넣어두었을 뿐이니 이는 무시하자.

아무튼 법 조항에서 다른 조항을 필요로 하는 경우가 있을 수 있으니 이렇게 참조 조항을 저장해두도록 하였다.

친구법 제1조 ...
친구법 제2조 (친구성립비용지불) : 친구 관계를 유지하면 매 달 100만원을 줘야한다.
친구법 제3조 ...
~~~
친구법 제71조 ...
친구법 제72조 (처벌) : 제2조를 어긴 자는 1년 이하의 징역형에 처한다.

 

예를 들어 위와 같은 법이 있다고 하면 제72조는 제2조의 내용이 있어야 LLM이 해석이 가능하다.

따라서 제72조의 reference에는 제2조가 들어있게 된다.

 

 

근데 왜 reference_list를 사용할 수 없을까?

 

이건 ChromaDB에서 메타데이터에 포함할 수 있는 타입은 오로지 문자형, 정수형, 실수형, 논리형이기 때문이다.

즉 reference_list는 배열형이기 때문에 저장할 수 없고, 이를 저장하려고 하면 오류가 나타나게 된다.

ValueError: Expected metadata value to be a str, int, float or bool, got 내용 which is a <class ‘list’>

Try filtering complex metadata from the document using langchain_community.vectorstores.utils.filter_complex_metadata.

 

대강 위 오류가 나타나게 되는데 대충 직역하면 위에서 말한바와 같다.

filter_complex_metadata 를 쓰라고 하는데,

이걸 쓰면 자동으로 저장해주는 게 아니라 말 그대로 지원 안되는 메타데이터 타입을 "삭제" 해버린다.

그렇게 되면 어떤 조문을 필요로 하는지 알 수 없게 되기 때문에 저렇게 reference 필드에 문자형으로 넣어주었다.

 

 

 

🤔 근데 뭔가 걸리는 게 있다며?

사실 내 경우에는 RAG를 수행할 때 벡터 데이터베이스를 채택할 필요성이 그렇게 높지 않다.

물론 아주 없는건 아니지만 확실히 높지는 않다.

 

왜냐하면 기존에 벡터 데이터베이스를 채택하려고 했던 이유가 범죄 사실에 맞는 법을 도출해내기 위해서였지만,

지금은 파인튜닝이 되어있어서 어떤 법이 범죄 사실에 해당하는지 이미 구하고 있기 때문이다.

즉, 간단히 법을 MySQL같이 비교적 단순한 데이터베이스에 넣어두고 해당하는 법 조문을 뽑아와서 이를 토대로 LLM에 넘겨주면 충분하기 때문이다.

 

그래서 만약 이게 하루 이틀로 끝나지 않는다면 그냥 다른 데이터베이스를 선택할까 하고있다.

(에휴 데이터베이스 용량만 12시간 지났는데 12기가 쓰고있다.. 1시간에 1기가씩은 더 잡아먹는 듯..)

 

 

어차피 RAG는 말 그대로 "검색 증강 생성" 이고 외부 데이터베이스에서 데이터를 얻어오는 것이고

'무조건 벡터 데이터베이스를 사용해야 한다!' 라는 것이 아니기 때문에 괜찮을 것 같다.

 

 

❓ 이제 무엇을 할까?

이제 양형 기준안을 처리해야 한다.

양형 기준안을 텍스트로 바꾸는 것이 아니더라도 어떤 법 조항이 양형 기준안을 적용할 수 있는지 확인하고 해당되는 양형 기준안 파일이라도 제공토록 하고자 한다.

 

텍스트로 바꾸려면 일일히 사람이 수기로 바꿔야 하기 때문에..

OpenAI의 ChatGPT, Google의 Gemini, Claude, Qwen 등 다양한 이미지 처리 가능한 모델을 사용하여 처리해보았지만 비교적 단순한 표는 처리를 할 수 있지만 복잡한 표는 처리하지 못하였다.



 

일단 비교적 단순한 표를 통해 ChatGPT 5.0 에 분석을 요청한 그림인데 일단 오타가 많고 표를 텍스트로 알기 쉽게 풀이하였다고 보기도 힘들다.

워낙 글자가 빽빽하게 기술되어 있기도 하고 축소해서 보면 글자가 깨져보일 정도라 어쩔 수 없는 한계점 같다.

 

그래서 PDF 파일을 통째로 넘겨서 분석을 요청해보면 오타도 잘 안 나타나고 대체적으로 좋게 결과가 나온다.

 

근데 문제는 이제 모든 PDF 파일이 저렇게 좋게 나온다는 보장도 없을 뿐 더러 간혹 오타나 자기가 스스로 내용을 추가해버리는 등의 현상이 나타나기 때문에 그냥 파일을 제공하는 것이 좋을 것이라는 결론을 도출하였다.

 

 

🚀 향후 계획

 

  • 법령 데이터베이스 완성
    • 과거 이력 포함 전체 법령 벡터화
    • 메타데이터 기반 참조 관계 구축
  • 🧩 양형기준안 파일 매칭
    • 관련 법 조항별 PDF 링크 제공
  • 🌐 웹 인터페이스 구축
    • 검색 → 조회 → 관련 기준안 다운로드까지 가능한 플랫폼 형태

 

 

 

✍️ 마무리하며

법률 데이터는 단순한 텍스트 데이터가 아니다.
그 속에는 시대의 변화, 사회적 합의, 그리고 인간의 판단이 담겨 있다.
그렇기에 단순히 “검색 가능한 법령 데이터”를 만드는 것이 아니라,
시간과 법의 변화를 이해하는 인공지능 시스템을 구축하는 것이 이 프로젝트의 진정한 목표다.

데이터는 많고, 시간은 오래 걸리지만
결국 이 모든 과정이 미래를 위한 발판이 되길 바란다.