질문에서 답까지 – RAG 파이프라인, 로컬에서 완성

임베딩까지 이해했으니, 이제 RAG 파이프라인 구현의 마지막 단계 — 검색과 생성을 잇는 작업만 남았다.

15개의 반야심경 구절로 된 자료창고 원본은 클로드가 만들어 준 걸 그대로 사용했고,
이 창고에서 질문에 딱 맞는 참고자료를 찾아서 질문과 합친 하나의 프롬프트를 만들고
내 컴퓨터에 있는 소형모델에 보내 답변을 받는 건,
클로드가 파이썬으로 코드를 짜준 걸 실제 실행해보는 걸로 진행했다.

잠깐 옆길로 새면.
사실 처음 파이썬을 공부한 건 2019년이었다.
그냥 배워야 할 것 같은 생각에 파이썬 기본서와 코세라의 데이터분석 수업을 듣고 연습문제들도 풀었는데,
그 다음이 문제였다.

이걸로, 뭘하지?
내가 담당하던 업무는 금융회사의 내부감사라 대외비도 많았고, 데이터나 보고서 등이 정형화되어 있지도 않았다.
일만 하며 산 시간이 오래되서, 일 외에 파이썬으로 만들어 보고 싶은 것도 딱히 없었다.

그때였다.
그러면 난 뭘 해야 하지? 아니, 난 뭘 하고 “싶지?” 그리고 그걸 구체화시키는 건, 어떻게 하는 거지?
그 당시의 기대와는 달리, 아마도 그건 죽을 때까지도 계속 찾아가며 살아야 하겠지만,
이때의 경험으로
AI를 공부하겠답시고 무작정 책이나 강의부터 사들이지 않고,
AI로 뭘 해볼까를 먼저 생각했던 것 같다.

물론.. 시간이 꽤 지났지만,
어렴풋이라도 기억나는 파이썬이 이번에 도움이 됐으니
그 노력이 영 허빵은 아니었나 싶어 은근 좋기도 하다.

긴장되는 환경 설정

그런데 이번 편의 진짜 난관은 검색 로직 자체가 아니라,
내 컴퓨터에서 그 코드가 실제로 돌아가게 환경을 설정하는 것이었다.

ollama serve 에러

cmd창에 ‘ollama serve’를 실행시켰더니 에러가 메시지가 떴다.
“Error: listen tcp 127.0.0.1:11434: bind: Only one usage of each socket address…”

다행히 이미 Ollama가 백그라운드에서 돌고 있다는 뜻이란다.
트레이 아이콘에 라마 얼굴이 떠 있으면 이미 상시 실행 중이라는 의미라서,
ollama serve는 실행시킬 필요가 없었던 거였다.

파이썬이 없었다

이번엔 ‘python —version’을 실행시켰더니 버전 숫자 없이 그냥 “Python”이라고만 떴다.
이건 진짜 파이썬이 응답한 게 아니라, 윈도우에 기본으로 깔려있는 “파이썬 없으면 스토어에서 받을래?” 하는 가짜 안내창이라고 했다.
where python으로 확인해보니 역시 경로가 WindowsApps로 나오는 가짜 안내창이 맞았다.
결론은 파이썬을 다운받아서 설치하라는 것.

아나콘다는 너무 큰데..

예전에 LG그램에 아나콘다를 깔았을 때 용량(3GB 정도)이 부담스러웠어서,
태블릿인 줄 알고 있었던 서피스프로8로 코세라 수업을 들을 땐 구글 코랩으로 파이썬을 사용했었다.
알고 보니 서프를 너무 과잉보호 했던 거였어 ㅎ

이번 작업엔 순수 파이썬(100~200MB)에,
파이썬 라이브러리 중 requests(몇백 KB)와 numpy(15~20MB) 정도만 있으면 충분했다.
만약 코랩을 쓰려면..
코랩은 구글의 원격 서버라서, 내 컴퓨터 안에서 작동되고 있는 Ollama를 코랩에 연결하려면 복잡한 우회경로를 따로 설정해야 한다고 했다.

그래서 그냥 파이썬을 설치하기로..
python.org에서 standalone installer를 받아 설치했는데,
이때 “Add python.exe to PATH” 체크박스를 반드시 체크해야 한다고.
‘방금 설치한 파이썬이 있는 폴더 경로를, 저 PATH라는 주소록에 자동으로 추가해줘’라는 뜻인데, 그렇게 해야 파이썬 명령어를 실행시켰을 때, 컴퓨터가 프로그램을 찾아서 실행시킬 수 있기 때문이라고 한다.

모르는게 생길 때마다 AI가 바로바로 답해주니까, 겁이 덜난다.

폴더 구조와 상대경로 설정

클로드가 짜준 코드에 따라 자료창고 삼아 간단히 만든 json 파일, 파이썬 실행 파일이 있어야 할 폴더를 각각 만들어야 했는데 한참 헤맸다.
삼십년 전 DOS 창에서 써봤던 명령어도 오랜만에 써보고.
당시에 난 그 시커먼 화면에 도무지 취미를 못 붙였었는데, 왠일인지 지금은 재밌다.

환경 설정은 늘 큰맘 먹고 해야 하는 일이다.
내가 무슨 짓을 해놨는지도 모르는 게 환경 설정이라 늘 긴장되던 일인데..
그래도 이젠, 클로드에 바로바로 물으면 되니, 공부할 맛 나는 듯.

검색에서 생성으로 — RAG 파이프라인 구현의 마지막 조각

환경 설정을 완료하자 파이썬으로 만든 검색 코드가 정말 작동했다.
nomic-embed-text를 써서 15개의 반야심경 구절이 각각 768개 숫자로 이뤄진 벡터가 됐고,
질문을 넣으면 가장 가까운 구절이 순위대로 나왔다.

※ nomic-embed-text : AI가 텍스트를 컴퓨터가 이해할 수 있는 숫자의 나열(벡터)로 변환해 주는 오픈 소스 임베딩 모델(Embedding Model)로서, 문장이나 문서들의 ‘의미’를 숫자로 된 좌표로 만들어 비슷한 의미를 가진 텍스트끼리 가까운 곳에 모아주는 기술

이렇게 검색해온 구절들을 “이것만 근거로 답해라”는 지시문과 함께 질문과 합쳐 하나의 프롬프트로 조립하는 함수와, 그 프롬프트를 Ollama의 api로 보내서 답을 받아오는 함수, 두가지 함수를 만들어서 R(검색)-A(보강)-G(생성) 전체 구조를 완성했다.

여기서 API를 부른다는게 정확히 무슨 의미인지 또 한참 헤맸다.
이걸 이해하고 쉬운 글로 써보려고 클로드와 고속버스 터미널에 비유해서 묻고 답하고를 한참 했는데,
그 과정에서 API와 관련한 개념들을 나 스스로는 이해했지만, 정확하게 똑 떨어지는 비유법은 안타깝지만 찾지 못했다.
그러니 이번에 API는 건조하게 설명하는 걸로 ㅎ
이건 코딩해보고 실행해봐야 정확히 이해할 수 있는 것 같다.

API(Application Programming Interface) : 프로그램끼리 서로 요청하고 응답을 주고받기 위한 정해진 규칙과 통로. 하나의 API 서버는 보통 여러 개의 세부 경로(엔드포인트)를 갖고 있고, 그 경로마다 서로 다른 기능을 담당(Ollama 같이 작은 모델도, 클로드 같은 거대모델도 API를 하나씩 제공). 그래서 요청을 보낼 때는 “어떤 경로로 보낼지”와 “그 경로에서 구체적으로 무엇을 처리할지(예: 어떤 모델을 쓸지)”를 함께 지정해줘야 함

이렇게 R-A-G 전체를 내 컴퓨터에서 처음부터 끝까지 손으로 완성했다.
코드보다 환경 세팅에 더 진땀을 뺐지만,
돌아가는 걸 직접 눈으로 보니 그 과정이 훨씬 더 생생하게 이해가 되고 왠지 뿌듯하다.

다음 편에선 이 파이프라인에 모델 크기만 바꿔가며(1B, 3B, 8B) 던져본 결과 — 같은 참고자료를 줘도 답변이 어떻게 갈렸는지에 관한 이야기를 정리해 보려고 한다.

Q. API(Application Programming Interface)란 무엇인가요?

A. API는 프로그램끼리 서로 요청하고 응답을 주고받기 위한 정해진 규칙과 통로입니다. 하나의 API 서버는 보통 여러 개의 세부 경로(엔드포인트)를 갖고 있으며, 경로마다 서로 다른 기능을 담당합니다. 그래서 API를 호출할 때는 어떤 경로로 요청을 보낼지와, 그 경로에서 구체적으로 무엇을 처리할지를 함께 지정해줘야 합니다.

Q. nomic-embed-text 같은 임베딩 모델은 어떤 역할을 하나요?

A. 임베딩 모델은 문장이나 문서의 텍스트를 컴퓨터가 처리할 수 있는 숫자의 나열(벡터)로 변환해주는 오픈소스 모델입니다. 단순히 글자를 숫자로 바꾸는 것이 아니라, 문장이나 문서의 의미를 숫자로 된 좌표로 표현해서 비슷한 의미를 가진 텍스트끼리 벡터 공간에서 가까운 위치에 모이도록 만드는 것이 핵심입니다.

Q. 윈도우에서 python --version 명령어를 실행했는데 버전 번호 없이 “Python”이라고만 뜨는 이유는 무엇인가요?

A. 이는 실제 파이썬이 응답한 것이 아니라, 윈도우에 기본으로 내장된 안내창으로 “파이썬이 설치되어 있지 않으니 스토어에서 받으시겠습니까”를 알려주는 가짜 응답입니다. where python 명령어로 확인했을 때 경로가 WindowsApps로 나온다면 이 가짜 안내창이 맞고, 이 경우 python.org에서 정식 설치 파일을 받아 설치해야 합니다.

관련 글 보기