[00:00]
검색 증강 생성(Retrieval Augmented Generation)은
[00:02]
AI 에이전트가 지식 베이스에 접근할 수 있게 하는
[00:05]
가장 대중적인 도구입니다
[00:07]
본질적으로 AI를 여러분의 문서에 대한 전문가로 만들어주죠
[00:09]
n8n과 같은 노코드 도구에서도
[00:11]
RAG를 구현하기가 매우 쉽습니다
[00:13]
널리 채택되고 지원되기 때문이죠
[00:15]
하지만 솔직히 말씀드리면
[00:18]
제가 보기에 RAG가 형편없는 경우가 많습니다
[00:21]
그 이유는 주로
[00:23]
검색 과정에서 중요한 맥락과
[00:25]
관련 정보를 놓치는 경우가 많기 때문입니다
[00:27]
스프레드시트의 트렌드를 분석하려고 할 때
[00:29]
RAG 검색이 테이블의 4분의 1만 가져오고
[00:31]
전체가 필요한 경우엔 제대로 작동하기 힘들죠
[00:34]
특히 정말 답답한 건
[00:35]
회의 내용을 요약해달라고 했을 때
[00:38]
엉뚱한 날짜의 회의록을
[00:39]
가져오는 경우입니다
[00:41]
날짜가 문서 제목에 명확히 있는데도 말이죠
[00:43]
도대체 왜 올바른 문서를
[00:45]
가져오지 못하는 걸까요?
[00:47]
게다가 RAG는 종종
[00:49]
서로 다른 문서들을 연결하여
[00:50]
더 넓은 맥락을 제공하는 데
[00:52]
어려움을 겪습니다
[00:55]
이는 크게 두 가지 문제로 요약됩니다
[00:57]
첫째, RAG는 컨텍스트가 충분히 작지 않은 한
[01:00]
전체 문서나 문서 세트를 조망할 수 없고
[01:02]
둘째, RAG는
[01:05]
적절한 데이터 분석 개념이 없습니다
[01:07]
그렇다면 이러한 한계를 어떻게 극복할 수 있을까요?
[01:10]
몇 가지 방법이 있지만
[01:12]
제가 가장 선호하는 것은 에이전틱 RAG입니다
[01:14]
이 영상에서는 에이전틱 RAG가 무엇인지
[01:16]
왜 이것이 우리의 문제를 해결하는지
[01:18]
그리고 n8n에서 에이전틱 RAG 에이전트를
[01:21]
어떻게 구축하는지 정확히 보여드리겠습니다
[01:22]
또한 이 워크플로우는
[01:25]
다운로드 가능한 템플릿으로 제공되어
[01:27]
여러분의 n8n 인스턴스에
[01:29]
몇 분 만에 가져올 수 있습니다
[01:31]
자, 이제 n8n에서 구현한 에이전틱 RAG 에이전트의
[01:33]
전체적인 모습을 살펴보겠습니다
[01:36]
먼저 인정하자면
[01:38]
꽤 복잡해 보일 수 있습니다
[01:39]
하지만 걱정하지 마세요
[01:41]
모든 것을 자세히 설명해드리겠습니다
[01:43]
좋은 에이전틱 RAG 설정을 만들기 위해
[01:45]
필요한 모든 것을 다룰 것입니다
[01:48]
RAG 파이프라인도 설명드릴 텐데요
[01:50]
Google Drive의 파일들부터 시작해서
[01:52]
다양한 파일 형식에서 데이터를 추출하고
[01:54]
Supabase 지식 베이스에
[01:55]
추가하는 과정까지 모두 다룰 예정입니다
[01:58]
로컬 AI 패키지를 사용한
[02:00]
로컬 버전도 만들어보고 싶은데
[02:02]
관심 있으시다면
[02:03]
댓글로 알려주시면 감사하겠습니다
[02:05]
이 전체 워크플로우는 제가 개발한
[02:08]
n8n RAG 에이전트의 버전 3입니다
[02:11]
이전에 제 채널에서 다뤘던
[02:12]
마지막 버전은 이것인데
[02:14]
이것은 훨씬 단순한 구현이었고
[02:16]
좋은 시작점이 될 수 있었습니다
[02:18]
다양한 파일 형식을 처리할 수 있지만
[02:20]
나중에 보시겠지만
[02:22]
표 형식 데이터는 잘 처리하지 못했죠
[02:24]
CSV나 Excel 파일은 지식 베이스에
[02:26]
다른 방식으로 추가해야 합니다
[02:29]
일반 텍스트 문서처럼 처리할 수 없고
[02:31]
테이블을 쿼리할 수 있어야 하기 때문입니다
[02:32]
그리고 이 에이전트는
[02:37]
이 에이전트는 RAG만을 도구로 가지고 있는데요
[02:39]
이 도구 노드를 보면 알 수 있듯이
[02:41]
다른 도구는 전혀 없습니다. 그래서 만약 RAG
[02:42]
검색이 필요한 정보를 찾는데 실패하면
[02:44]
에이전트는 Supabase의 데이터를 탐색할
[02:47]
다른 방법이 전혀 없게 됩니다
[02:49]
그래서 사용자에게 답을 찾을 수 없다고
[02:51]
말할 수밖에 없죠
[02:52]
사실 다른 방법으로 문서를 살펴보면
[02:54]
답을 찾을 수 있는 방법이 있을 텐데도 말이죠
[02:56]
그래서 우리가 이 워크플로우에서
[02:58]
하고 있는 일이 바로 그것입니다
[02:59]
자세히 살펴보면
[03:01]
RAG 에이전트를 위한
[03:02]
우리가 가진 도구들을 보실 수 있습니다
[03:04]
이전 예제처럼 RAG 검색 도구도 있고
[03:06]
이전 버전과 마찬가지로 있지만
[03:08]
이번에는 개선된 버전으로
[03:09]
출처를 인용할 수 있는 기능이 추가되었죠
[03:11]
이것만으로도 한 단계 발전된 것인데요
[03:14]
여기에 더해 RAG 에이전트를 위한
[03:16]
다양한 PostgreSQL 도구들도 있어서
[03:18]
지식을 살펴보는 다른 방법들도 가능합니다
[03:20]
이것이 바로 우리가 정의하는
[03:22]
Agentic RAG입니다. Agentic RAG는 단순히
[03:25]
에이전트에게 지식 베이스를 탐색하는 방법에 대해
[03:28]
추론할 수 있는 능력을 주는 것입니다
[03:30]
단일 도구만 제공하는 것이 아니라
[03:32]
에이전트가 RAG 검색 쿼리를 개선하고
[03:34]
다양한 도구를 선택할 수 있게 하여
[03:37]
사용자의 질문에 답할 수 있게 합니다
[03:39]
이전 버전의 Agentic 워크플로우에서는
[03:42]
RAG 검색 개선 기능이 있었는데
[03:44]
RAG를 도구로 사용할 수 있어서
[03:46]
에이전트가 더 나은 쿼리로
[03:48]
두 번째 검색을 시도할 수 있었죠
[03:50]
그 부분은 있었지만
[03:52]
지식 베이스를 다른 방식으로
[03:53]
탐색하거나
[03:55]
사용자의 질문에 따라 데이터를
[03:57]
다르게 보는 방법은 없었습니다
[03:59]
하지만
[04:00]
이 세 가지 PostgreSQL 도구들을 통해
[04:02]
우리는 이 업그레이드된 버전에서
[04:04]
Agentic RAG 에이전트에게 더 많은 기능을 제공합니다
[04:06]
지식 베이스에서 사용 가능한
[04:08]
모든 문서를 나열할 수 있고
[04:10]
특정 문서의 내용도
[04:12]
가져올 수 있습니다. 만약 RAG 검색이
[04:14]
어떤 이유로든 실패한다면
[04:16]
검색 대신 사용 가능한 파일들을
[04:18]
살펴보고 어떤 문서를
[04:20]
봐야 할지 추론할 수 있습니다
[04:22]
답을 찾기 위해 여러 문서를
[04:23]
검토할 수도 있죠. 예를 들어
[04:26]
2월 23일 회의록을 요약해달라고 했는데
[04:27]
RAG 검색이 실패한 경우
[04:29]
어떤 이유에서든 - 예를 들어
[04:31]
잘못된 날짜를 가져왔다든지 - 그럴 때
[04:33]
문서들을 직접 살펴보고
[04:34]
문서 제목이 '2월 23일 회의록'인
[04:36]
파일을 찾아서
[04:38]
그 내용을 가져와
[04:40]
사용자의 질문에
[04:42]
답할 수 있습니다
[04:44]
이처럼 지식 베이스를
[04:46]
다양한 방식으로 접근할 수 있죠
[04:47]
RAG를 사용하거나 전체 문서를 보거나
[04:50]
이 모든 것이 도구로 제공됩니다
[04:52]
여기에 더해 Excel과 CSV 파일을
[04:55]
SQL 테이블처럼 쿼리할 수 있는 아주 멋진
[04:58]
도구도 있습니다
[05:00]
이것은 구현이 좀 더 복잡하지만
[05:02]
정말 강력한 기능을 제공하여
[05:04]
다양한 데이터를 처리할 수 있게 해줍니다
[05:06]
테이블의 합계나 최댓값과 같은 것들을
[05:08]
일반적인 RAG로는 얻을 수 없습니다.
[05:10]
CSV 파일이 아주 작지 않는 한
[05:12]
전체 파일을 가져올 수 없기 때문이죠.
[05:14]
이제 우리의 에이전트를 테스트해볼 시간입니다.
[05:16]
이전 버전으로는 답하기 어려웠을
[05:18]
까다로운 질문들을 해보겠습니다.
[05:20]
RAG만으로는 어려웠을 수도 있죠.
[05:22]
제가 보여드리고 싶은 가장 중요한 점은
[05:23]
이 에이전트가 다양한 도구를 사용하여
[05:25]
질문에 따라 지식 베이스를
[05:26]
다르게 탐색한다는 것입니다.
[05:28]
제 구글 드라이브에는 6개의 문서가 있는데
[05:30]
스프레드시트와 일반 문서가 섞여 있고
[05:32]
이미 모두 수퍼베이스
[05:33]
지식 베이스에 저장되어 있습니다.
[05:35]
나중에 설정 방법도 설명해드리겠습니다.
[05:36]
현재 우리는 문서 테이블이 있는데
[05:38]
여기에는 RAG를 위한
[05:40]
임베딩과 메타데이터,
[05:41]
그리고 각 청크의 내용이 포함되어 있습니다.
[05:44]
그리고 문서 메타데이터 테이블이 있는데
[05:45]
이것은 나중에 자세히 설명하겠지만
[05:47]
문서의 상위 수준 정보를 담고 있습니다.
[05:48]
출처 인용을 위한 URL이나
[05:50]
제목 같은 정보들이 있죠.
[05:52]
그리고 문서 행 테이블이 있는데
[05:55]
이것은 CSV와 엑셀 파일을
[05:57]
수퍼베이스에 저장하는 방식입니다.
[05:59]
SQL 쿼리로 조회할 수 있지만
[06:01]
각 CSV나 엑셀 파일마다
[06:03]
별도의 SQL 테이블을
[06:05]
만들 필요가 없어서 매우 편리합니다.
[06:08]
자, 이제 다시 돌아가서
[06:10]
문서에 대해 질문을 해보겠습니다.
[06:12]
먼저 이 중 하나를 열어보면
[06:14]
데이터를 보여드리고
[06:15]
제가 할 질문을 설명하겠습니다.
[06:17]
2024년 월별 매출 지표를 보겠습니다.
[06:20]
참고로 이 데이터는 모두
[06:22]
Claude가 생성한 가짜 데이터입니다.
[06:24]
간단한 질문을 해보겠습니다.
[06:26]
어느 달에 가장 많은 신규 고객을 얻었는지
[06:28]
물어보겠습니다. RAG만으로도
[06:31]
이 테이블 전체를 가져올 수는 있겠지만
[06:33]
우리는 에이전트가
[06:35]
SQL 쿼리를 작성하는 것을 보고 싶습니다.
[06:37]
만약 이 테이블이 더 컸다면
[06:39]
RAG로는 전체를 가져올 수 없었을 겁니다.
[06:41]
청크 수의 제한 때문에
[06:43]
테이블의 일부만 가져오게 되어
[06:45]
4분의 1 정도만 볼 수 있고
[06:46]
가장 많은 신규 고객이 있는
[06:47]
기록을 놓칠 수도 있어서
[06:49]
잘못된 답을 줄 수 있습니다.
[06:51]
자, 이제 돌아가서
[06:53]
실제로 질문을 해보겠습니다.
[06:54]
'어느 달에 가장 많은 신규 고객을 얻었나요?'
[06:57]
여기서 제 목표는 에이전트가
[07:00]
SQL 쿼리를 작성하는 도구를 사용하는 것을 보는 겁니다.
[07:03]
네, 보세요. 실행했네요.
[07:05]
자세히 보시면 에이전트가 작성한
[07:07]
SQL 쿼리를 볼 수 있습니다.
[07:09]
지금은 복잡한 설명은 생략하고
[07:10]
보시죠, 12월에 129명의
[07:13]
신규 고객이 있었다는 것을 확인했습니다.
[07:16]
그리고 이것이 정확한 답변이에요.
[07:18]
모든 정보를 가져왔고,
[07:20]
네, 여기 정확한 답변이 있네요.
[07:22]
다음 질문을 위해
[07:24]
대화 내용을 초기화하고
[07:25]
다시 구글 드라이브로 가서
[07:27]
이번에는 텍스트 문서를 열어보겠습니다.
[07:29]
'개선이 필요한 영역'이라는 문서입니다.
[07:32]
이것은 고객 피드백 설문조사입니다.
[07:34]
개선할 점이 무엇인지 물어보고
[07:36]
이 문서에서 특별히 언급하지 않고도
[07:37]
정보를 추출할 수 있는지 확인해보겠습니다
[07:39]
다시 돌아가서
[07:41]
'우리가 더 잘할 수 있는 부분은 무엇인가요?'라고 물어보겠습니다
[07:44]
특별히 '개선'이라는 단어를
[07:46]
사용하지 않으려고 합니다
[07:48]
이는 검색이 단순히
[07:49]
글자 그대로의 '개선 영역'이라는 단어에
[07:51]
의존하지 않도록 하기 위해서입니다
[07:53]
그래서 '더 잘할 수 있는 부분'이라고 하겠습니다
[07:54]
이번에는 RAG를 사용했고, 네
[07:56]
모바일 접근성, 통합 기능,
[07:59]
그리고 보고서 커스터마이징이 나왔네요
[08:01]
정확히 맞습니다
[08:03]
정확한 답변을 얻었네요
[08:05]
이제 다시 대화를 지우고
[08:07]
이번에는
[08:10]
RAG를 수행하는 대신 파일의 내용을
[08:12]
직접 살펴보고 싶습니다
[08:14]
놀랍게도 이것은 테스트 환경에서
[08:16]
까다로울 수 있습니다
[08:18]
이 정도의 데이터만으로는
[08:20]
RAG가 실패하도록 만들기가 어렵습니다
[08:23]
전체 파일의 내용을
[08:25]
가져와야 하므로, 명시적으로
[08:27]
이 도구를 사용하라고 지시하겠습니다
[08:29]
최소한 작동하는 것을 보여드리기 위해서죠
[08:31]
하지만 제 RAG 경험상
[08:32]
이런 종류의 기능은
[08:34]
확실히 필요합니다
[08:36]
RAG가 항상 신뢰할 수 있는 것은 아니기 때문이죠
[08:38]
앞서 이야기했던 것처럼
[08:39]
자, 이제 이 제품팀 회의록을
[08:41]
열어보겠습니다
[08:42]
이 파일을 특별히 살펴보라고 지시해서
[08:45]
우리가 가진 액션 아이템들을 추출하도록 하겠습니다
[08:47]
n8n으로 돌아가서
[08:49]
소스도 인용하도록 하겠습니다
[08:51]
먼저 제품 회의록의
[08:53]
파일 내용을 가져오고
[08:55]
액션 아이템을 알려달라고 하겠습니다
[08:57]
명시적으로 요청하니
[08:59]
도구를 호출해서 파일 내용을
[09:00]
전체 문서를 반환했고
[09:03]
네, 이 답변이 좋아 보입니다
[09:05]
마커스가 일정을 제공하기로 했네요
[09:07]
다른 내용들도 모두 일치합니다
[09:10]
완벽해 보이네요. 이제
[09:11]
소스를 인용해달라고 하겠습니다
[09:14]
문서 링크를 원하는데, 이는
[09:16]
문서를 직접 열어보지 않았더라도
[09:19]
정답이 맞는지 확인하고 싶어서입니다
[09:20]
그리고 여기
[09:21]
링크가 나왔네요
[09:23]
이걸 클릭하면 바로
[09:25]
에이전트에서 문서가 열립니다
[09:27]
자, 오늘 영상의 스폰서는
[09:29]
Unstract입니다. 오픈소스 노코드
[09:32]
LLM 플랫폼으로, API와 ETL 파이프라인을 만들어
[09:35]
비정형 문서를
[09:37]
구조화된 데이터로 변환합니다. 이는
[09:39]
AI 에이전트에서 특히 RAG에
[09:41]
매우 중요한데, 항상
[09:44]
단순한 CSV와 텍스트 문서만
[09:46]
지식 베이스로 사용할 수 있는 것은 아니기 때문입니다
[09:48]
텍스트를 추출하고 덤프하는 것만으로는
[09:50]
때로는 PDF에서
[09:51]
특정 테이블을 추출해야 하거나
[09:53]
영수증과 같은 이미지에서
[09:55]
정보를 추출해야 할 수도 있습니다
[09:57]
이것이 바로 Unstract가 도움이 되는 부분이고
[09:59]
여러분도 이를 활용할 수 있습니다
[10:01]
이것을 API 엔드포인트로 전환하여
[10:03]
n8n 워크플로우에 통합해 더 복잡한 문서를
[10:05]
처리할 수 있게 만들 수 있습니다
[10:07]
여기 Unstracts의 GitHub 저장소가 있는데
[10:09]
이 플랫폼은 세 가지 주요 부분으로
[10:11]
구성되어 있다고 볼 수 있습니다
[10:13]
첫 번째는 프롬프트 스튜디오입니다
[10:15]
여기서 LLM과 함께 작동할 프롬프트를 설계하고
[10:17]
비정형 문서에서 정보를 추출하는 방법을
[10:18]
LLM이 이해하도록 만들 수 있습니다
[10:21]
그런 다음 이 프롬프트들을
[10:22]
워크플로우에 추가합니다
[10:25]
여기서 문서에서 자동으로 정보를
[10:26]
추출하는 플로우를 구축하게 됩니다
[10:30]
그리고 이 워크플로우를 데이터 API와
[10:33]
ETL 파이프라인으로 배포할 수 있으며
[10:35]
설명란에 링크된 훌륭한 문서가
[10:36]
있어서 API 배포와 ETL 파이프라인 같은
[10:38]
모든 구성 요소들의 사용 방법을
[10:40]
자세히 설명하고 있습니다
[10:42]
그리고 프롬프트 스튜디오에 대해
[10:44]
특별히 언급하고 싶은데
[10:45]
구글에서 가져온 이런 영수증 같은
[10:47]
파일을 업로드하는 것이 정말 간단하고
[10:50]
프롬프트를 정의해서
[10:51]
품목, 세금 금액, 총액과 같은
[10:53]
원하는 모든 중요 정보를
[10:55]
추출할 수 있습니다
[10:57]
하단의 금액이나
[10:59]
모든 정보를 아주 잘 추출해냅니다
[11:00]
여기서 프롬프트를 정의하고
[11:02]
필요한 것을 정확히 파악한 다음
[11:04]
워크플로우를 구축하면 됩니다
[11:05]
만약 단순한 CSV나 텍스트 문서 이상의
[11:07]
n8n의 단일 노드로 추출할 수 있는 것보다
[11:09]
더 복잡한 문서가 있다면
[11:11]
Unstracts를 적극 추천합니다
[11:13]
복잡한 문서 작업에서 발생하는
[11:15]
많은 문제들을 해결해주고
[11:17]
RAG 에이전트를 포함한 다양한
[11:19]
사용 사례에 매우 중요합니다
[11:21]
설명란에 Unstracts 링크를 남겨두었으니
[11:24]
꼭 확인해보시기 바랍니다
[11:26]
모든 종류의 데이터를
[11:27]
다루고 싶다면 강력히 추천드립니다
[11:28]
단순한 데이터 이상을 처리하고 싶다면 말이죠
[11:30]
이제 이 에이전트 RAG 설정이
[11:32]
전반적으로 어떻게 작동하는지 아셨을 텐데
[11:34]
이제 각 구성 요소들을
[11:36]
자세히 살펴보려고 합니다
[11:38]
제가 만든 템플릿을 여러분의 특정 사용 사례에
[11:40]
맞게 확장할 수 있도록 말이죠. 이것은 좋은
[11:43]
시작점이지만, 바로 사용 가능한
[11:44]
완벽한 솔루션이라고는 기대하지 마세요
[11:47]
여러분이 직접 프롬프트와 도구,
[11:48]
파이프라인을 작업하고
[11:50]
여러분의 지식 베이스에 맞게
[11:52]
수정하기를 바랍니다
[11:54]
자세히 살펴보면, 먼저 워크플로우의
[11:56]
첫 부분을 보여드리겠습니다
[11:58]
빨간 박스 안의 모든 노드를 실행하여
[12:00]
Supabase 데이터베이스를 설정합니다
[12:02]
여기에는 세 개의 다른 테이블이 있고
[12:04]
각각을 생성해야 합니다. 첫 번째 노드는
[12:06]
documents 테이블을 생성하는 것입니다
[12:09]
이전에 n8n으로 RAG를 설정해보셨다면
[12:12]
이 쿼리가 매우 익숙할 것입니다
[12:14]
이것은 Supabase 설정
[12:15]
지침에 있는 내용이라 이미 가지고
[12:17]
계실 수도 있습니다. 기존 것을 사용하거나
[12:19]
documents 테이블의 이름을 변경하고
[12:21]
쿼리를 수정할 수도 있습니다. 하지만
[12:24]
이것은 우리의 documents 테이블을 구축하는데
[12:26]
RAG를 위한 임베딩을
[12:28]
메타데이터와 각 파일의 모든 내용을
[12:30]
저장하고, 그 다음으로 두 번째
[12:31]
노드에서 메타데이터 테이블을 생성하는데,
[12:35]
이 테이블은 문서에 대한 상위 레벨
[12:36]
정보를 저장하여 우리의 에이전트가
[12:39]
단순한 RAG 검색을 넘어서
[12:41]
더 높은 수준에서 정보를 볼 수 있게 합니다.
[12:43]
제목을 기반으로 전체 파일을 분석할지
[12:45]
결정할 수 있습니다. 예를 들어
[12:48]
매출 지표와 같은 경우에 대해서도
[12:51]
URL도 포함되어 있어서 RAG와 전체 파일
[12:53]
검색 모두에서 출처를 인용할 수 있습니다.
[12:56]
에이전트가 이러한 도구들을 호출할 때
[12:58]
출처를 인용할 수 있도록 하고
[13:00]
마지막으로 나중에 더 자세히 설명할
[13:01]
스키마가 있습니다.
[13:03]
스프레드시트 형식 파일의 경우
[13:06]
여기서 스키마를 정의하고
[13:08]
테이블의 데이터를 쿼리할 때 어떤 필드가 있는지
[13:11]
알려줍니다. 문서 행 테이블에서
[13:14]
이와 관련하여 세 번째 노드는
[13:16]
문서 행을 생성하고
[13:18]
각 행의 모든 데이터는 JSONB 형식으로
[13:21]
row_data 열에 저장됩니다.
[13:25]
이를 통해 테이블 데이터에 대한
[13:27]
SQL 쿼리를 생성할 수 있으면서도
[13:30]
새로운 파일을 수집할 때마다 새로운 SQL 테이블을
[13:34]
만들 필요가 없습니다. 모든 것이
[13:37]
JSONB 안에서 처리되기 때문에
[13:39]
유연하게 작동하며, row_data에는
[13:42]
어떤 종류의 스키마도 저장할 수 있습니다.
[13:43]
여기서 볼 수 있듯이
[13:45]
예를 들어 이 파일에는
[13:47]
코호트, 초기 고객 등
[13:49]
여러 다른 항목들이 있고
[13:51]
이 스프레드시트에는
[13:53]
CAC, LTV, MR 등 다양한 데이터가
[13:56]
row_data에 저장되어 있으며
[13:58]
여기 있는 스키마는 에이전트에게
[14:00]
쿼리 방법과 사용 가능한 열을 알려줍니다.
[14:02]
완벽한 설정은 아닙니다. 예를 들어
[14:04]
데이터 타입을 알려주지 않아서
[14:07]
각 숫자에 달러 기호가 있는
[14:09]
문자열 데이터에 대해 합계를
[14:11]
계산하려고 할 수도 있습니다.
[14:12]
완벽한 구현은 아니지만
[14:15]
이것은 시작을 위한 템플릿일 뿐이고
[14:16]
개념을 보여주는 것이 주된 목적입니다.
[14:18]
매우 강력한 기능을
[14:20]
간단한 방식으로 보여주는 것이
[14:21]
이 에이전트의 주요 목적입니다.
[14:24]
워크플로우의 두 번째 부분은
[14:26]
RAG 파이프라인으로, 이 파란색 박스 안에
[14:27]
있는 모든 것들입니다. Google Drive와 같은 곳에서
[14:29]
문서를 가져와서
[14:31]
Supabase 지식 베이스로 가져오는 과정입니다.
[14:33]
실제 AI 에이전트를 만들기 전에
[14:35]
이 작업을 먼저 해야 합니다.
[14:37]
지식 베이스를 탐색하는 도구들이
[14:38]
제대로 작동하는지 테스트해야 하기 때문입니다.
[14:40]
지금부터 파이프라인을 설명하겠습니다.
[14:42]
Google Drive나
[14:43]
다양한 자격 증명 생성은
[14:46]
다루지 않을 것입니다.
[14:48]
Supabase에 대해서는 제 채널의
[14:50]
다른 영상에서 이미 다뤘기 때문입니다.
[14:52]
이 워크플로우 버전에서
[14:54]
새로운 자격 증명을 만들 때
[14:55]
항상 문서 열기 버튼이 있어서
[14:57]
n8n이 제공하는 문서 페이지로
[14:59]
이동할 수 있어
[15:00]
자격 증명 설정이 매우 쉽습니다.
[15:02]
자격 증명 설정에 대해 한 가지 말씀드리자면
[15:05]
PostgreSQL 노드와 관련된
[15:06]
자격 증명에 대해 n8n 문서가
[15:08]
매우 명확하지 않다는 점입니다. PostgreSQL에
[15:11]
연결할 때는 반드시 트랜잭션 풀러 방식을
[15:14]
사용해야 합니다. Supabase 대시보드에서
[15:16]
상단 중앙의 'Connect'를 클릭하면
[15:18]
많은 시행착오를 피할 수 있습니다.
[15:20]
제가 겪었던 것처럼 말이죠.
[15:22]
직접 연결 파라미터는 사용하지 마세요.
[15:24]
이 방식은 작동하지 않을 겁니다.
[15:27]
포트 6543을 사용하는 트랜잭션 풀러
[15:29]
방식을 사용해야 합니다. 이렇게 하면
[15:32]
필요한 모든 정보를 얻을 수 있습니다.
[15:34]
데이터베이스 비밀번호만 제외하고요.
[15:36]
이건 당연히 따로 있어야 합니다.
[15:38]
이제 이 부분은 넘어가고
[15:39]
파이프라인의 시작인 Google Drive
[15:41]
트리거를 살펴보겠습니다. 이 노드를 클릭하면
[15:43]
Google Drive에서 하는 작업은
[15:45]
매 분마다 새로운 파일이 생성되었는지
[15:47]
확인하는 것입니다. 이는 Dropbox나
[15:49]
로컬 파일 트리거로 대체할 수 있는데
[15:51]
로컬 AI 버전을 만들 때 보여드리겠습니다.
[15:53]
지금은 Google Drive를 예시로 사용하고 있습니다.
[15:55]
매 분마다 지정된 폴더에서
[15:57]
파일이 생성되는지 감시하고
[15:59]
드라이브의 특정 폴더를 지정해서
[16:01]
모니터링합니다. 그리고
[16:02]
파일이 업데이트되는 경우도
[16:04]
비슷한 트리거를 가지고 있어서, 이 워크플로우는
[16:06]
파일 생성과 업데이트 모두를 처리합니다.
[16:08]
아쉽게도 파일이 삭제되는 경우를 감지하는
[16:10]
트리거는 없습니다. 매우 아쉽네요.
[16:12]
n8n에서 이 기능을 추가하길 바랍니다.
[16:14]
그래야 Google Drive에서
[16:15]
파일을 삭제할 때 지식 베이스도
[16:17]
정리할 수 있을 텐데요. 현재는
[16:18]
지원되지 않습니다. 그리고 이전 버전의
[16:20]
워크플로우에서 정말 부족했던 부분이
[16:22]
여러 파일이 동시에 트리거로
[16:24]
들어올 때 제대로 처리하지 못했다는 점입니다.
[16:27]
워크플로우를 통해 한 파일만 처리되고
[16:29]
나머지는 건너뛰었는데
[16:30]
이번 버전에서는 이 문제를
[16:33]
해결했습니다. 많은 피드백을 받았던
[16:35]
부분이라는 걸 알고 있었고
[16:36]
Loop를 추가하여 해결했습니다.
[16:39]
이제 동일한 폴링 주기 내에
[16:42]
여러 파일을 한꺼번에 추가하거나
[16:44]
업데이트해도 처리할 수 있습니다. 실제로
[16:46]
여기 핀 데이터를 보시면
[16:48]
Google Drive 트리거에 두 개의
[16:51]
항목이 있고, 두 파일을 보내서
[16:53]
Loop에서 처리하고 있습니다. 작동 방식은
[16:55]
먼저 한 파일을 전체 플로우에 보내서
[16:58]
앞서 본 것처럼 처리한 다음
[17:00]
다시 처음으로 돌아가서
[17:03]
다음 파일에 대해 같은 작업을
[17:05]
반복하고, 또 다음 파일,
[17:06]
이렇게 트리거로 들어온 모든 파일을
[17:08]
처리할 때까지 반복합니다. 이해가 되셨길 바랍니다.
[17:10]
여러분을 위해 이 부분을 개선하고 싶었습니다.
[17:12]
이제 단일 파일 레벨로 들어가보면
[17:14]
나머지 과정은 한 번에 하나의 파일에 대해
[17:16]
처리됩니다. 우선 말씀드리자면
[17:19]
여기 모든 것을 이미 실행해봤기 때문에
[17:21]
입력과 출력을 볼 수 있습니다.
[17:22]
테스트 실행을 마쳤기 때문에
[17:25]
모든 박스가 초록색으로 표시되어 있죠.
[17:26]
첫 번째 노드에서는
[17:28]
워크플로우의 나머지 부분을 위한
[17:29]
초기 설정을 하고 있습니다.
[17:31]
파일 ID, 쿼리, 파일 타입과 같은 모든 중요한 정보를 설정합니다. 이는 콘텐츠를 추출하는 방법을 결정하고,
[17:39]
데이터베이스에 들어갈 제목과 URL도 포함됩니다.
[17:42]
다음으로 Supabase에서 이 파일의 기존 데이터를 모두 삭제해야 합니다. 파일을 업데이트할 때마다 이 작업을 수행합니다.
[17:49]
이렇게 하는 이유는 완전히 새로운 상태에서 시작하여, 에이전트가 query할 때 이전 파일 버전의 데이터가 남아있지 않도록 하기 위해서입니다.
[18:01]
예를 들어, 처음에 10개의 문단으로 구성된 파일이 있어서 10개의 청크가 있었는데, 마지막 문단을 삭제하여 9개의 청크만 남았다고 가정해보겠습니다.
[18:10]
만약 데이터베이스의 기존 청크를 삭제하지 않고 그냥 업데이트만 하면, 처음 9개만 업데이트되고
[18:18]
10번째 청크는 파일이 더 길었던 이전 버전의 것이 지식 베이스에 그대로 남아있게 됩니다.
[18:26]
따라서 가장 확실한 방법은 모든 것을 삭제하는 것입니다. 이 파일 ID에 해당하는 모든 문서 행을
[18:33]
메타데이터 필드를 사용해 삭제하고, 표 형식 파일의 데이터 행도 같은 방식으로 삭제합니다.
[18:44]
이미 설정한 파일 ID를 기반으로 Supabase 테이블의 모든 레코드를 삭제합니다.
[18:51]
그 다음으로 첫 번째 삽입 작업을 수행합니다. 실제로는 upsert 작업인데, 파일이 이미 존재하면 메타데이터를 업데이트하고
[18:57]
존재하지 않으면 메타데이터를 새로 삽입합니다.
[19:02]
여기서는 제목과 URL 같은 문서의 초기 단계를 설정하고, 테이블의 경우 나중에 스키마를 설정할 것입니다.
[19:09]
이 테이블은 아직 파일 내용이 필요하지 않기 때문에 여기서 설정할 수 있습니다.
[19:15]
파일 내용은 나중에 추출할 것이고, 그때 문서 테이블을 채울 수 있습니다.
[19:20]
콘텐츠를 추출하여 content 컬럼에 추가하고, 임베딩을 생성하는 등의 작업을 할 것입니다.
[19:27]
여기서 PostgreSQL과 Supabase를 번갈아 사용하는 이유는, PostgreSQL이 SQL 쿼리 실행이나
[19:35]
upsert와 같은 작업에 더 나은 노드를 제공하기 때문입니다. Supabase 노드에는 이러한 옵션이 없지만,
[19:42]
Supabase는 PostgreSQL에는 없는 필터 옵션이 있어서 삭제 작업에 사용하고 있습니다.
[19:49]
이것이 이 워크플로우에서 PostgreSQL과 Supabase 노드를 혼용하는 이유입니다.
[19:55]
자, 이제 우리는 백지 상태에서 시작하여
[19:57]
초기 메타데이터를 삽입했습니다.
[20:00]
이제 파이프라인의 나머지 부분을 위해
[20:02]
콘텐츠를 추출해야 하므로 구글 드라이브에서
[20:04]
파일을 다운로드합니다. 이 데이터 필드의
[20:06]
출력은 파일 자체입니다.
[20:08]
다운로드하거나 볼 수 있죠.
[20:10]
아직 파일의 내용은 없고
[20:11]
파일 자체가 n8n 인스턴스에
[20:14]
저장되어 있어서 추출할 수 있습니다.
[20:16]
이제 스위치 노드로 넘어가는데
[20:18]
파일 유형에 따라 콘텐츠를 추출하는
[20:20]
방법이 다르기 때문입니다.
[20:22]
PDF나 스프레드시트,
[20:23]
구글 문서에서 콘텐츠를 추출하는 방식이
[20:26]
모두 다르기 때문에
[20:28]
여기 있는 스위치를 기반으로
[20:30]
결정되는 여러 분기가
[20:32]
있습니다.
[20:34]
이 테스트 실행에서처럼 CSV 파일이면
[20:36]
세 번째 분기인 출력 2로 이동하고
[20:39]
구글 문서이거나 기본값인 경우는
[20:41]
출력 3으로 가서
[20:44]
이 아래쪽 분기로 이동합니다.
[20:46]
제 테스트에서는 CSV에서 추출하는 쪽으로
[20:49]
초록색 선이 가는 것을 볼 수 있는데
[20:51]
이는 구글 드라이브에 업로드한
[20:53]
CSV 파일로 테스트하고 있기 때문입니다.
[20:56]
사실 PDF나
[20:58]
텍스트 문서에서 추출할 때는
[21:00]
매우 간단한데, 단일 노드만
[21:02]
있으면 됩니다. 보여드리자면
[21:03]
새 노드를 추가하고 검색하면
[21:05]
'extract'라고 검색하면 이 모든 파일 형식이
[21:08]
지원됩니다. 따라서
[21:09]
JSON 파일이나 HTML 파일에서
[21:11]
추출하도록 확장하고 싶다면
[21:13]
이러한 추출 노드들을 추가하고
[21:15]
스위치 문에
[21:17]
분기만 추가하면 됩니다.
[21:18]
다른 파일 형식으로도
[21:20]
쉽게 확장할 수 있죠.
[21:22]
보신 옵션들에서 지원하지 않는
[21:24]
형식이 있다면
[21:26]
다른 파일 형식에서 추출하기 위한
[21:28]
커스텀 n8n 워크플로우를 만들 수도 있습니다.
[21:30]
가능성은 무한하며
[21:31]
원하는 모든 파일 형식으로
[21:33]
작업할 수 있습니다.
[21:35]
마크다운이나 텍스트 문서 같은
[21:37]
다른 파일 형식들도
[21:39]
텍스트 문서에서 추출하는 것으로
[21:41]
처리할 수 있는데
[21:43]
이 노드가 많은 파일 형식을
[21:44]
지원하기 때문입니다. 하지만 지금은
[21:47]
CSV 추출에 집중하고 싶은데
[21:48]
여기서 좀 더 복잡해지고
[21:51]
메타데이터와 스키마를 채워야 하며
[21:54]
행도 추가해야 하기 때문입니다.
[21:56]
n8n 워크플로우로 돌아가서
[21:58]
CSV와 Excel 파일에 대해 어떻게 작동하는지
[22:00]
보여드리겠습니다. 이 데모에서는
[22:03]
CSV 경로만 실행하고 있지만
[22:05]
Excel도 동일합니다.
[22:06]
나머지 노드들은 같고
[22:08]
추출 노드만 다르면 됩니다.
[22:10]
먼저 CSV 파일의 내용을 가져와서
[22:12]
n8n 워크플로우의 행으로 변환합니다.
[22:16]
그리고 두 가지를 동시에 해야 하는데
[22:17]
테이블 파일의 데이터를 RAG에서
[22:20]
사용할 수 있게 하기 위해서는
[22:24]
텍스트 문서로 변환해야 합니다.
[22:25]
다른 문서들과 마찬가지로 청킹을 하면서
[22:27]
문서 로우에도 저장하려고 합니다.
[22:30]
SQL 테이블처럼 쿼리할 수 있도록
[22:32]
에이전트에게 그런 기능을 부여하는 거죠.
[22:34]
따라서 우리는 두 가지 경로로
[22:36]
진행하고 있습니다.
[22:39]
첫 번째는 CSV에서 가져온
[22:41]
15개의 레코드 모두를
[22:44]
문서 로우 테이블에 삽입하는 것입니다.
[22:47]
예를 들어 이것은 하나의 파일로
[22:49]
여기 있는 모든 것을
[22:51]
이 노드 안에서
[22:53]
모든 레코드를 삽입하고 있습니다.
[22:55]
그리고 동시에 텍스트 문서로
[22:57]
변환하는 작업도 시작합니다.
[22:59]
모든 것을 하나로 집계할 건데
[23:01]
여러 레코드 대신
[23:02]
모든 행을 배열로 가진
[23:04]
단일 항목으로 만들고, 그 다음
[23:07]
요약을 하려고 합니다.
[23:08]
이는 기본적으로 문자열로 변환하는 것인데
[23:10]
이제 우리는 청킹할 수 있는
[23:12]
텍스트 문서를 갖게 됩니다.
[23:15]
PDF나 마크다운 파일에서 추출한 것처럼요.
[23:17]
상단과 하단 브랜치에서
[23:19]
이 모든 것이 수퍼베이스로 들어가는데
[23:20]
이에 대해서는 잠시 후에 설명하겠습니다.
[23:22]
결과적으로 테이블은 다른 텍스트
[23:25]
문서처럼 처리되지만, 동시에
[23:27]
스키마를 설정하는 이 경로도 있습니다.
[23:30]
여기서는 복잡한 자바스크립트를 사용하는데
[23:31]
자세한 설명은 생략하겠습니다.
[23:34]
여기서는 CSV의 헤더를 가져와서
[23:35]
스키마로 정의하고
[23:37]
메타데이터 레코드를 업데이트합니다.
[23:40]
이렇게 하면 에이전트가 스키마에 접근할 수 있죠.
[23:43]
이 정보를 설정하는 곳이 바로 여기입니다.
[23:45]
CSV 파일의 헤더를 지정하면
[23:48]
에이전트가 이를 이해할 수 있습니다.
[23:50]
먼저 이 레코드를 읽어
[23:52]
고객 코호트 분석을 위한
[23:54]
메타데이터를 가져오고, 스키마를 확인한 뒤
[23:57]
SQL 쿼리를 작성하여
[23:59]
여기 있는 행들을 조회할 수 있게 됩니다.
[24:01]
이해가 되셨길 바랍니다.
[24:04]
에이전트는 먼저 여기를 보고
[24:05]
스키마를 이해한 다음
[24:08]
행을 쿼리하게 되는데
[24:10]
이 모든 것을
[24:11]
메타데이터 레코드에 스키마를 추가하여
[24:14]
가능하게 만들고 있습니다.
[24:16]
마지막으로 수퍼베이스 부분인데
[24:18]
n8n이 많은 부분을 처리해주기 때문에
[24:20]
꽤 간단합니다.
[24:22]
모든 것을 청킹하고 수퍼베이스에 추가하는 것이
[24:25]
복잡하지만, 단 4개의 노드로
[24:27]
처리됩니다.
[24:28]
먼저 수퍼베이스 벡터 스토어
[24:30]
삽입 노드가 있는데
[24:32]
RAG에 사용할 테이블과 쿼리를
[24:34]
정의합니다. 그 다음 임베딩이 있는데
[24:37]
저는 OpenAI를 사용하고 있습니다.
[24:39]
참고로 임베딩 모델로는
[24:42]
text-embedding-3을 사용하고
[24:43]
LLM으로는 GPT-4-mini를 사용합니다.
[24:46]
가장 강력한 LLM은 아니지만
[24:48]
저렴하고 빠른 것을 원했기에
[24:49]
선택했습니다. 물론 사용 사례에 따라
[24:51]
GPT-4나
[24:52]
Claude 3.5처럼 더 강력한 모델이 필요할 수도 있죠.
[24:55]
어쨌든 이것이 우리의 임베딩 모델이고
[24:58]
이제 우리는 단순히
[24:59]
기본 데이터 로더를 사용하고 있는데,
[25:02]
이것은 문서를 청킹하고
[25:04]
Supabase에 삽입할 준비를 하며
[25:06]
메타데이터도 정의하는 역할을 합니다.
[25:08]
메타데이터는 정말 매우
[25:10]
중요한데, 여기서는 파일 ID와
[25:12]
파일 제목을 메타데이터로 사용합니다.
[25:15]
이것이 매우 중요한 이유는
[25:16]
메타데이터를 통해 특정 파일의
[25:19]
레코드만 선택적으로 삭제할 수 있기 때문입니다.
[25:22]
플로우 시작 시점에서
[25:23]
RAG를 위한 새로운 데이터 삽입을 위해
[25:25]
깨끗한 상태가 필요할 때 사용합니다.
[25:27]
또한 파일 제목도
[25:29]
메타데이터에 필요한데, 에이전트가
[25:31]
RAG를 수행할 때 어떤 파일을
[25:33]
참조하고 있는지 알아야 하기 때문입니다.
[25:35]
이를 통해 출처를 인용할 수 있고,
[25:37]
나중에 자세히 설명하겠지만, RAG 도구에서
[25:39]
메타데이터도 함께 반환되도록
[25:41]
설정되어 있습니다. 여기
[25:42]
이 옵션을 체크해 두었는데, 이를 통해 에이전트가
[25:45]
무엇을 참조하고 있는지 알 수 있습니다.
[25:47]
마지막으로 텍스트 스플리터는
[25:48]
매우 단순하게 설정했는데,
[25:50]
character text splitter를 사용했고
[25:51]
많은 고민을 하지 않았습니다.
[25:52]
문서 청킹 방식은 사용 사례에 따라
[25:54]
크게 달라질 수 있기 때문입니다.
[25:56]
매우 단순하게 유지했습니다.
[25:58]
이것이 RAG 파이프라인의 전부입니다.
[26:00]
그리고 워크플로우를 살펴보면서
[26:02]
모든 입력과 출력을 보여드렸는데,
[26:03]
전체 실행 과정을 확인하실 수 있었습니다.
[26:05]
이미 실행을 완료했기 때문에
[26:07]
제 Google Drive에 있는
[26:09]
스프레드시트와 문서 파일들이
[26:11]
모두 수집되어 있습니다.
[26:13]
모든 파일에 대해 이 워크플로우를
[26:15]
실행했고, 트리거를 사용해서
[26:17]
파일들을 넣으면
[26:18]
자동으로 처리되도록 했습니다.
[26:20]
RAG 파이프라인이 생성되고
[26:22]
모든 지식이 준비되었으니
[26:24]
이제 에이전트를 설정할 수 있고, 다행히도
[26:27]
AI 에이전트 생성은 RAG 파이프라인보다 간단합니다.
[26:29]
지식 베이스와 Supabase에서
[26:31]
모든 설정을 완료했기 때문에
[26:32]
에이전트는 몇 가지 간단한
[26:34]
도구만 있으면 됩니다.
[26:36]
이제 살펴보도록 하겠습니다.
[26:37]
먼저 이 워크플로우에는 몇 가지
[26:40]
트리거가 있습니다. 웹훅이 있어서
[26:41]
에이전트를 API 엔드포인트로 만들 수 있고,
[26:44]
또한 채팅 트리거가 있어서
[26:46]
n8n 워크플로우에서 직접 대화할 수 있습니다.
[26:48]
이것이 하단 중앙에 있는
[26:50]
채팅 버튼을 제공하고,
[26:51]
이 두 노드는 약간 다른 형식으로 출력되므로
[26:54]
Edit Fields 노드를 사용해
[26:56]
여기서 약간의 JavaScript로
[26:57]
두 가지 다른 트리거를 처리하여
[27:00]
에이전트 노드에 일관된 출력을
[27:02]
제공하도록 했습니다. 이제
[27:03]
에이전트로 들어가보면 전반적으로
[27:05]
매우 단순합니다. 시스템 프롬프트가 있어서
[27:08]
지식 베이스를 탐색하는 데 사용할 수 있는
[27:09]
다양한 도구들을 설명하고
[27:11]
이러한 도구들을 활용하는 방법에 대한
[27:13]
지침을 제공합니다. 예를 들어
[27:15]
RAG로 시작하고 다른 도구들을
[27:17]
활용하라고 지시하며,
[27:19]
RAG로 시작한 다음 다른 도구들을 사용하도록 했습니다.
[27:21]
RAG가 올바른 답변을 주지 않을 경우 다른 도구들을 사용하도록 할 수 있고
[27:23]
이 시스템 프롬프트를 확실히 수정할 수 있습니다
[27:24]
저는 이 시스템 프롬프트를 더 개선할
[27:26]
많은 기회가 있다고 생각합니다
[27:28]
이것은 단지 예시로 제공한 것입니다
[27:30]
이런 RAG 에이전트에서 매우 도움이 되는
[27:32]
한 가지는 정직하게 답변하도록 하는 것입니다
[27:34]
만약 RAG나 다른 도구들에서 답을 찾지 못했다면
[27:37]
답을 만들어내려 하지 말고
[27:39]
사용자에게 그대로 알려주라고 하는 것이죠
[27:41]
이것만으로도 환각 현상을
[27:43]
상당히 줄일 수 있습니다
[27:45]
그리고 우리가 사용하는 모델은
[27:46]
앞서 보여드린 것처럼 GPT-4 미니입니다
[27:48]
여기에 간단한 PostgreSQL 대화 기록을
[27:50]
설정했는데, 이 테이블은
[27:53]
아직 없다면 첫 번째 대화에서
[27:55]
자동으로 생성됩니다
[27:56]
그래서 제가 빨간색 박스에
[27:58]
네 번째 노드로 생성하지 않은 것이죠
[28:00]
간단하고 사용하기 쉽게 만들었습니다
[28:02]
이제 우리의 도구들을 살펴보겠습니다
[28:04]
첫 번째 도구는 RAG입니다
[28:06]
워크플로우의 이전 버전을 보시면
[28:09]
훨씬 더 단순한 버전인 것을 알 수 있습니다
[28:11]
이는 제가 마지막 비디오를 만든 이후
[28:13]
n8n이 AI 에이전트를 위한 많은 멋진 업데이트를
[28:16]
진행했기 때문입니다
[28:18]
그래서 Supabase 벡터 저장소를 위한 이 도구가
[28:20]
훨씬 더 단순해졌고, 이제 메타데이터를
[28:23]
포함할 수 있는 옵션이 생겼습니다
[28:25]
각 레코드에 삽입한 파일 ID와 파일 제목을
[28:27]
여기서 보여드리겠습니다. 문서로 가서
[28:30]
메타데이터 필드를 클릭하면
[28:33]
파일 ID와 파일 제목이 있는 것을
[28:35]
확인할 수 있습니다
[28:36]
이 모든 정보가 RAG 결과에 포함되어
[28:38]
에이전트가 출처를 인용할 수 있게 됩니다
[28:41]
이는 정말 중요한 기능입니다
[28:44]
그리고 우리는 Supabase에 데이터를 삽입할 때 사용한
[28:47]
동일한 임베딩 모델을 사용하고 있는데
[28:49]
이것도 매우 중요합니다
[28:51]
삽입과 검색 모두에서
[28:53]
모델의 차원 수가 동일해야 하기 때문입니다
[28:55]
이것은 매우 중요한 점이죠
[28:57]
다른 도구들로 넘어가서
[28:58]
첫 번째로 문서 목록을 보여주는 도구가 있습니다
[29:00]
여기서는 간단한 PostgreSQL 쿼리를 사용하여
[29:02]
문서 메타데이터 테이블에서
[29:05]
모든 문서를 가져옵니다
[29:06]
에이전트가 이를 읽고 어떤 파일을 볼지
[29:09]
각 파일의 ID를 확인할 수 있죠
[29:11]
또한 테이블 파일의 스키마도 포함되어 있어
[29:13]
문서 행 테이블을 어떻게 쿼리할지 알 수 있습니다
[29:16]
여기서는 모든 문서를 반환하고 있는데
[29:18]
대규모 문서 코퍼스가 있는 경우
[29:20]
모든 것을 반환하지 않고
[29:22]
날짜 기반이나 AI가 작성한 쿼리를 통해
[29:24]
문서를 필터링하는 방법을 찾아볼 수 있습니다
[29:26]
하지만 현재 LLM은 매우 긴 컨텍스트를
[29:29]
처리할 수 있다는 점을 기억하세요
[29:31]
지식 베이스에 천 개의 문서가 있더라도
[29:34]
모든 파일과 제목, ID를
[29:36]
가져올 수 있습니다
[29:38]
AI가 쿼리를 작성하거나
[29:40]
날짜 기반으로 필터링하는 방법도 있죠
[29:41]
하지만 현재 LLM은
[29:43]
매우 긴 컨텍스트를 관리할 수 있어서
[29:45]
지식 베이스에 천 개의 문서가 있더라도
[29:47]
모든 파일과 제목,
[29:49]
ID를 가져올 수 있습니다
[29:52]
파일과 제목, ID를 모두 가져올 수 있죠
[29:54]
그들 모두를 가져와서
[29:55]
LLM 프롬프트에 넣을 수 있으므로
[29:57]
그것도 여전히 작동할 수 있습니다
[29:58]
문서 목록을 나열한 후에는
[30:01]
에이전트가 특정 파일의
[30:02]
내용을 가져오고 싶어할 수 있어서
[30:04]
여기 이 쿼리가 있는데
[30:07]
기본적으로 파일 ID가 주어지면
[30:08]
메타데이터 테이블에서 가져와서
[30:11]
문서의 모든 청크의 내용을
[30:14]
함께 가져와서 결합하여
[30:17]
해당 문서의 전체 텍스트를 제공합니다
[30:19]
제가 메타데이터 테이블에
[30:21]
content 컬럼을 사용하는 이유는
[30:23]
파일의 모든 내용이 들어있는 content 컬럼을
[30:26]
메타데이터 테이블에 두는 대신
[30:28]
문서 테이블에 두는 것은
[30:30]
n8n이 이 content 컬럼을 기본적으로 포함하기 때문입니다
[30:33]
이것은 제가 제어할 수 없는 부분이라
[30:35]
이미 여기 있다면
[30:37]
메타데이터에도 파일 내용을 저장해서
[30:39]
정보를 중복시키고 싶지 않아서
[30:40]
그래서 모든 청크를 함께 가져와서
[30:42]
여기 있는 이 쿼리로
[30:44]
내용을 결합합니다
[30:46]
AI가 결정하는 유일한 매개변수는 파일 ID입니다
[30:49]
메타데이터 테이블에서 파일 ID를 선택하고
[30:51]
이 도구에 전달합니다
[30:53]
에이전트가 매번
[30:55]
파일 내용을 가져올 때마다
[30:57]
항상 먼저 문서 목록을 호출하는 것을 보게 될 겁니다
[31:00]
왜냐하면 파일 내용을 가져오기 위해
[31:02]
어떤 파일 ID를 도구에 전달할지
[31:05]
알아야 하기 때문이죠
[31:08]
그리고 마지막 도구는
[31:10]
테이블 데이터를 쿼리하기 위한
[31:13]
SQL 쿼리를 작성하는 도구입니다
[31:16]
이것은 조금 더 정교한 구현이지만
[31:18]
여전히 기본적인 수준입니다
[31:20]
프롬프트를 개선할 여지가 많은데
[31:22]
여기 도구 설명은
[31:25]
LLM에 주어지는
[31:26]
프롬프트의 일부로
[31:28]
이 도구를 언제 어떻게 사용할지
[31:30]
알려주는 것입니다
[31:32]
다른 도구들도 마찬가지지만
[31:34]
여기서는 더 명시적으로
[31:35]
설명해야 합니다
[31:37]
document rows 테이블을
[31:38]
이해하도록 도와야 하기 때문입니다
[31:41]
row_data JSONB를 어떻게 사용해서
[31:43]
이 파일들에 대한 SQL 쿼리를
[31:45]
작성해야 하는지 알아야 하고
[31:47]
예시도 몇 가지 제공했습니다
[31:49]
이 예시들은 매우 기본적이라
[31:50]
특정 사용 사례에 맞게
[31:53]
테이블 데이터를 쿼리하는 방식을
[31:54]
개선하고 싶을 것입니다
[31:56]
row_data JSONB를 사용하는 방법에 대한
[31:59]
특정 컬럼 선택과 그룹화 예시를 제공했고
[32:02]
필터링을 더 잘 이해하도록
[32:04]
할 수 있습니다
[32:06]
전체 쿼리를 작성하게 했는데
[32:08]
여기서 단일 매개변수는
[32:10]
작성하고자 하는 전체 SQL 쿼리입니다
[32:12]
이런 식으로 특정 파일의 내용을
[32:15]
쿼리할 수 있는데, dataset_id가
[32:17]
파일 ID이기 때문에 쿼리하고자 하는
[32:20]
특정 파일을 지정할 수 있고
[32:21]
row_data JSONB를 사용해서
[32:24]
특정 컬럼으로 쿼리하고 그룹화하며
[32:26]
필터링도 할 수 있습니다
[32:27]
이것이 마지막 도구입니다
[32:30]
이제 모든 것이 완성되었는데요.
[32:31]
도구들이 조금 복잡해진 것 같아서
[32:33]
궁금한 점이 있으시다면
[32:34]
댓글로 남겨주시면 좋겠습니다.
[32:36]
이제 우리의 에이전트가 완성되어
[32:37]
영상 시작 부분에서 보여드린 것처럼
[32:39]
모든 기능을 사용할 수 있게 되었습니다.
[32:41]
간단한 예시를 하나 보여드리면,
[32:44]
'회사에 어떤 직원들이 있나요?'라는
[32:46]
매우 일반적인 질문을 해보겠습니다.
[32:48]
이런 종류의 질문은
[32:49]
일반적인 RAG로도 가능하지만,
[32:50]
여러 도구들을 어떻게 활용하는지
[32:52]
보여드리기 위한 예시입니다.
[32:54]
이 경우에 RAG를 수행했고
[32:56]
원하는 정보를 찾지 못해
[32:57]
여러 문서들을 검색하기로 결정했습니다.
[32:59]
그래서 몇 개의 문서를 살펴보았고
[33:03]
이 문서에서는 원하는 정보가 없고
[33:05]
저 문서에서도 원하는 정보가 없었지만
[33:06]
제품팀 회의록에서
[33:07]
팀원들의 정보를 찾을 수 있었습니다.
[33:10]
정말 멋지지 않나요?
[33:11]
즉석에서 이 예시를 생각해냈는데도
[33:13]
정말 잘 작동했습니다.
[33:15]
RAG를 수행하고
[33:16]
그것이 작동하지 않았을 때의 과정을 보여줬는데
[33:18]
이는 당연한 결과입니다.
[33:19]
벡터 검색만으로는 특정 이름을 찾기 어렵기 때문에
[33:22]
직원을 찾는 단순 질문으로는
[33:24]
파일 검색을 하기로 결정했고
[33:26]
이는 정말 멋진 결정이었습니다.
[33:28]
이 템플릿으로
[33:30]
여러분이 에이전트 기반 RAG를
[33:32]
n8n에서 빠르게 시작하실 수 있기를 바랍니다.
[33:34]
물론 궁금한 점이 있으시다면
[33:36]
이 워크플로우를 구축하면서
[33:37]
댓글로 남겨주세요.
[33:39]
이는 고급 RAG 주제로 들어가고 있으며
[33:42]
곧 더 많은 유사한 콘텐츠가 나올 예정입니다.
[33:44]
local AI 패키지로 구축한
[33:46]
완전히 로컬 버전의 에이전트 기반 RAG도
[33:48]
공개할 예정이니 기대해 주세요.
[33:51]
이 콘텐츠가 도움이 되었고
[33:52]
AI, 에이전트, n8n에 대한
[33:54]
더 많은 내용을 기대하신다면
[33:57]
좋아요와 구독 부탁드립니다.
[33:59]
다음 영상에서 만나뵙겠습니다.