[00:00]
AI 에이전트를 구축할 때의 가장 큰 장점 중 하나는
[00:01]
기존의 워크플로우나 자동화와 비교했을 때
[00:04]
사람처럼 행동할 수 있다는 점입니다.
[00:06]
실시간으로 의사결정을 내리고
[00:08]
지능적으로 업무를 대신 처리할 수 있죠.
[00:10]
이것이 바로 AI 에이전트가
[00:13]
LLM의 가장 중요한 활용 사례로 여겨지는 이유입니다.
[00:16]
하지만 사람과 비슷하다고 하면서도
[00:19]
대부분의 경우 기억력이 형편없죠.
[00:21]
이에 대해 저는 매우 깔끔하고 간단한 해결책이 있어
[00:24]
오늘 여러분께 소개해드리려고 합니다.
[00:26]
현재 상황을 보면
[00:27]
모든 사람들이 RAG를 통해
[00:30]
문서로 AI 에이전트를 학습시키는 데 집중하고 있습니다.
[00:32]
물론 이것도 중요하지만, 진정한 의미의 기억은 아니죠.
[00:35]
우리가 제공하는 문서를 통한 학습뿐만 아니라
[00:36]
AI 에이전트에게 대화를 통한
[00:39]
학습 능력을 부여하는 것은 어떨까요?
[00:41]
우리가 제공하는 문서뿐만 아니라
[00:43]
대화를 통해서도 학습하는 AI 에이전트가 필요합니다.
[00:46]
상호작용하면서 학습하여 우리의 목표,
[00:48]
선호도, 지시사항,
[00:50]
수정사항 등을 기억할 수 있어야 합니다.
[00:53]
이러한 장기 기억은
[00:55]
AI 에이전트를 한 단계 발전시켜
[00:57]
정말 사람다운 행동과
[00:59]
개인화된 서비스를 제공할 수 있게 합니다.
[01:01]
이 영상에서는 이러한 자가학습 에이전트를
[01:04]
단계별로 구축하는 방법을 보여드리겠습니다.
[01:06]
Mem Zero라는 오픈소스
[01:08]
파이썬 라이브러리를 사용할 건데요,
[01:10]
사용하기 쉽고 우리가 원하는 기능에
[01:13]
최적화되어 있습니다.
[01:15]
이는 에이전트와 상호작용하는
[01:17]
개별 사용자에 대한 지식, 즉 기억을
[01:19]
쌓아가는 것이 목적입니다.
[01:22]
현재 이 도구는 제가 가장 아끼는 도구이며,
[01:25]
영상 끝까지 시청하시면
[01:26]
여러분도 그렇게 느끼실 거라 확신합니다.
[01:29]
지금부터 Mem Zero를 살펴보고
[01:30]
AI 에이전트를 발전시키는 데
[01:32]
얼마나 쉽게 사용할 수 있는지 보여드리겠습니다.
[01:35]
먼저 장기 기억과 Mem Zero가
[01:37]
어떤 문제를 해결하는지 살펴보겠습니다.
[01:40]
장기 기억이 구현되지 않은
[01:42]
LLM과의 대화가 어떤지
[01:45]
빠르게 보여드리고,
[01:46]
그 다음 우리가 구축하려는
[01:48]
최종 결과물을 보여드리겠습니다.
[01:50]
장기 기억을 가진 에이전트로 무엇을 할 수 있는지
[01:52]
첫 번째 테스트로, 저는 지금
[01:54]
Gemini 2.0 Flash와 대화하고 있습니다.
[01:57]
이것은 장기 기억이 없는
[02:00]
에이전트 또는 챗봇입니다.
[02:02]
첫 번째 프롬프트에서는
[02:04]
제가 SaaS 회사를 만드는 데 사용하는
[02:06]
기술 스택을 설명했습니다.
[02:09]
이론적으로 챗봇은 이제
[02:11]
Redis나 Supabase 같은
[02:12]
여러 서비스들을 이해하고 있어야 합니다.
[02:15]
하지만 이제 새로운 대화를 시작하고
[02:17]
이전에 설명했던 서비스들에 대해
[02:19]
질문을 해보겠습니다.
[02:21]
'데이터베이스에 대해
[02:23]
어떤 점들을 고려해야 할까요?'라고 물어보면
[02:26]
만약 이것이 진정한 지능형 에이전트라면
[02:28]
대화 사이에서도 제 기술 스택을
[02:30]
기억해야 할 텐데요,
[02:32]
보시다시피 여기서는
[02:34]
제가 사용하는 것을
[02:36]
실제로 이해하고 있다는
[02:38]
표시가 전혀 없습니다.
[02:40]
제가 사용 중인 Redis는 언급하지만
[02:42]
MongoDB, Oracle 같은
[02:44]
다른 서비스들도 나열하고 있습니다.
[02:47]
제가 기술 스택에서
[02:49]
전혀 언급하지 않은 것들을 나열하고 있죠.
[02:50]
이를 통해 Gemini가 장기 기억력이
[02:53]
없다는 것을 알 수 있습니다. 새로운 대화를
[02:55]
시작할 때마다 이전 대화의
[02:57]
중요한 세부사항들을
[02:58]
다시 설명해야 하는데
[03:00]
이것이 매우 귀찮습니다. 이제
[03:02]
mem을 이용해 장기 기억력을 갖춘
[03:05]
에이전트와 비교해보겠습니다.
[03:08]
이 영상에서 최종적으로
[03:09]
만들어볼 결과물을 지금 바로
[03:11]
무료로 사용해보실 수 있습니다.
[03:13]
studio.automator.ai에
[03:14]
접속하시면
[03:16]
Pydantic AI mem 에이전트를 보실 수 있습니다. 이것이 우리가
[03:18]
만들어볼 것인데, 먼저
[03:20]
Gemini와 어떻게 다른지 보여드리겠습니다.
[03:22]
동일한 프롬프트를 입력해보겠습니다.
[03:24]
SaaS 회사를 운영 중이고
[03:26]
이것이 제 기술 스택이라고 말이죠.
[03:29]
이전처럼 기술들을 인식하는 것을
[03:31]
볼 수 있습니다. 하지만 새로운
[03:33]
대화를 시작하면 - 잠시 후에
[03:35]
보여드리겠지만 - 지금은
[03:37]
기억을 처리하는 중입니다.
[03:39]
새로운 대화에서 Gemini에게
[03:41]
같은 질문을 했을 때, 이번에는
[03:44]
제가 사용 중인 기술들을 기억하고
[03:46]
저에게 훨씬 더
[03:47]
맞춤화된 답변을 제공할 것입니다.
[03:50]
새로운 대화에서
[03:52]
"데이터베이스 구축 시 고려사항이 무엇인가요?"라고
[03:55]
질문하겠습니다. 잠시
[03:57]
답변을 기다려보면
[03:58]
훨씬 더 나은 답변이
[04:00]
나올 것입니다. 자, 여기 나왔네요.
[04:03]
이를 보시면, SaaS 회사의
[04:04]
데이터베이스를 고려할 때
[04:07]
우선 제가 SaaS 회사를 만들고 있다는 것을
[04:08]
기억하고 있습니다. 이제 Supabase와
[04:11]
PostgreSQL에 대해 이야기하고 있고,
[04:14]
Redis를 검색해보면, 네, Redis와
[04:16]
FastAPI에 대해 언급하고 있습니다. Gemini와 달리
[04:19]
제가 사용하지 않는 기술은
[04:21]
언급하지 않고, 오직
[04:22]
사용 중인 것들만 언급합니다. 이는
[04:25]
매우 기본적인 예시지만, 여러분이
[04:28]
상상력을 발휘해서
[04:30]
AI 에이전트가 사용자와의 과거 상호작용을
[04:32]
기억할 수 있을 때 무엇이 가능한지,
[04:34]
그리고 거의 사용자별 맞춤
[04:37]
지식 베이스를 구축하는 것까지
[04:39]
생각해보시기 바랍니다. Mem도
[04:41]
사용자 ID를 사용하여 기억을
[04:43]
사용자별로 분리합니다. 이것을
[04:46]
Supabase 인증과 함께 사용하는 방법도
[04:48]
나중에 보여드리겠습니다. Mem Zero로
[04:50]
시작하는 것은 매우 쉽습니다.
[04:52]
GitHub 리포지토리가 있는데,
[04:53]
이 영상의 설명란에 링크를 걸어두겠습니다.
[04:55]
Python이 설치되어 있다면 pip install memzero-ai만
[04:58]
실행하면 됩니다. 정말
[05:00]
간단합니다. Mem Zero를 호스팅해주는
[05:01]
플랫폼도 있고, 원하신다면
[05:04]
완전히 무료로 셀프 호스팅도
[05:06]
가능합니다. 100% 오픈소스 프로젝트이기
[05:09]
때문이죠. 이것이 우리가
[05:10]
이 영상에서 활용할 것입니다. 먼저
[05:12]
Mem Zero의 매우 기본적인 구현부터 시작하는데,
[05:15]
실제로 여기 있는 템플릿을
[05:16]
기반으로 합니다. 그리고
[05:18]
시간이 지나면서 점점 더 복잡해져서
[05:20]
Supabase 인증과 같은 중요한
[05:22]
사용자 인증을 추가할 것입니다.
[05:24]
사용자 인증과 메모리를 위한 벡터 저장소를
[05:27]
구현해야 하기 때문입니다. 대부분의 경우
[05:30]
새로운 프레임워크나 도구를 배울 때는
[05:31]
직접 만들어보는 것이 가장 좋은 방법이죠.
[05:33]
그래서 지금부터 우리는
[05:35]
Mem Zero를 직접 코드로 구현해볼 겁니다.
[05:36]
바로 코드 작성에 들어가보겠습니다.
[05:39]
이 영상의 마지막 부분에는
[05:41]
Mem이 어떻게 작동하는지에 대해 더 자세히 다룰 예정입니다.
[05:43]
관심 있으시다면 끝까지 시청해주세요.
[05:45]
지금은 코드 작성에 집중하도록 하겠습니다.
[05:47]
여러분과 함께 코딩을 해보려고 합니다.
[05:48]
지금 보시는 이 GitHub 저장소는
[05:51]
영상 설명란에 링크를 첨부해두었습니다.
[05:52]
README를 따라 환경 설정을 하시면
[05:54]
우리가 만들 모든 코드를
[05:56]
직접 실행해보실 수 있습니다.
[05:57]
우리가 함께 만들어볼
[05:59]
이 프로젝트는 기본적인 것부터 시작해서
[06:00]
단계별로 발전시켜 나갈 예정입니다.
[06:02]
Mem Zero의 기본적인 구현부터 시작해서
[06:05]
처음부터 함께 코딩하면서
[06:06]
단계별로 발전시켜 나갈 건데요,
[06:09]
Supabase를 통한 메모리 저장소 통합과
[06:11]
메모리 저장, 그리고
[06:13]
간단한 프론트엔드를 만들고
[06:14]
Supabase 인증을 통해 사용자가 로그인하여
[06:16]
각자의 고유 ID로 메모리를 저장할 수 있도록
[06:20]
데이터베이스에 별도로 저장하는 방법까지 다룰 겁니다.
[06:22]
이것이 바로
[06:23]
Mem Zero의 가장 중요한 사용 사례 중
[06:24]
하나입니다. 이 모든 것을 보여드리겠습니다.
[06:27]
마지막으로 말씀드릴 것은
[06:29]
이 저장소에는 앞서 보여드린
[06:31]
Studio 통합 버전도
[06:33]
포함되어 있다는 점입니다. 라이브 에이전트 스튜디오에서
[06:35]
Mem Zero를 사용하여 Pydantic AI로
[06:37]
AI 에이전트를 만드는 방법이 궁금하시다면
[06:41]
이 코드를 참고하시면 됩니다.
[06:42]
좋은 예시가 될 것입니다. 이제
[06:44]
Mem Zero로 간단한 구현을
[06:46]
시작해보도록 하겠습니다. 모든 과정을
[06:48]
단계별로 자세히 설명해드리겠습니다.
[06:50]
모든 내용을 잘 이해하실 수 있도록
[06:51]
첫 번째로 할 일은
[06:53]
라이브러리와 환경 변수를
[06:55]
임포트하는 것입니다.
[06:57]
버전 1에서는 OpenAI API 키만
[06:59]
필요한데요,
[07:01]
이후 버전에서는 모델 정의와
[07:04]
환경 변수를 통해
[07:05]
Supabase 설정도 다루게 될 것입니다.
[07:07]
이제 Mem Zero의 설정을
[07:09]
구성해보겠습니다. 여기에는
[07:11]
다양한 설정이 가능한데요,
[07:14]
문서를 참고하시면 자세히 보실 수 있습니다.
[07:16]
나중에 볼 데이터베이스 설정처럼
[07:18]
다양한 옵션이 있지만, 지금은
[07:19]
아주 기본적인 것부터 시작하겠습니다.
[07:21]
LLM 설정부터 시작해볼텐데요,
[07:23]
LLM이 Mem에서 사용될 때는
[07:26]
메시지에서 메모리를 추출하거나 검색을 수행할 때
[07:29]
사용됩니다. 우리는 간단하게
[07:32]
GPT-4를 사용할 겁니다.
[07:34]
그리고 나서 OpenAI 클라이언트와
[07:37]
Mem Zero 클라이언트를 생성할 건데요,
[07:39]
여기 보시는 것처럼 이 설정을 사용합니다.
[07:42]
이 첫 번째 버전의 주요 함수는
[07:44]
'chat_with_memories'입니다. 이 함수는
[07:47]
두 개의 매개변수를 받는데요,
[07:49]
사용자의 현재 메시지와
[07:51]
사용자 ID를 받습니다. 사용자 ID는
[07:53]
메모리를 분리하는 데 필요한데요,
[07:55]
각 사용자의 메모리를 구분하기 위해서입니다.
[07:58]
사용자별로 메모리를 구분해야 하는데,
[08:00]
이를 위해 사용자 ID를 활용합니다.
[08:02]
우리는 절대로 다른 사용자의
[08:04]
메모리를 실수로 가져오면 안 됩니다.
[08:07]
에이전트와 대화할 때는 먼저
[08:09]
관련 메모리를 검색합니다.
[08:10]
mem0 클라이언트를 사용해서
[08:12]
검색 함수에 사용자의 최신 메시지와
[08:15]
ID를 전달하고,
[08:17]
가장 관련성 높은 메모리 3개로
[08:20]
제한을 둡니다. 그리고 나서
[08:22]
여기서 반환된 객체의
[08:24]
문자열 버전을 만듭니다.
[08:26]
문자열로 만드는 이유는
[08:28]
시스템 프롬프트에 전달하기 위해서입니다.
[08:30]
여기 매우 기본적인
[08:32]
시스템 프롬프트를 설정했습니다.
[08:34]
'당신은 도움이 되는 AI입니다. 사용자의
[08:36]
최신 메시지와 여기에서 제공하는
[08:38]
메모리를 기반으로 답변하세요.'
[08:40]
이 메모리는 mem0로부터 동적으로
[08:43]
검색된 것입니다. 그리고 메시지
[08:45]
배열을 만들어서 OpenAI 클라이언트에
[08:47]
전달합니다. 여기서 현재
[08:50]
대화에서 축적된 모든 메시지와 함께
[08:53]
GPT-4에 요청을 보냅니다.
[08:55]
이것은 대화형 봇이 아닙니다.
[08:57]
보시다시피 GPT-4에 전달되는
[09:00]
메시지에는 시스템 프롬프트와
[09:02]
사용자의 최신 메시지만 포함됩니다.
[09:05]
시간이 지나도 대화 히스토리를
[09:08]
쌓지 않습니다.
[09:11]
이것이 중요한 이유는
[09:13]
나중에 보여드리겠지만,
[09:15]
대화 히스토리가 전혀 없어도
[09:17]
에이전트가 여전히 기억할 수 있다는 것을
[09:20]
증명할 것이기 때문입니다.
[09:22]
이 점을 기억해 두세요.
[09:24]
대화 히스토리를
[09:25]
축적하지 않습니다. 에이전트로부터
[09:27]
응답을 받은 후, 메시지에
[09:30]
응답을 추가합니다. 그 이유는
[09:32]
사용자 메시지와 AI 응답을
[09:35]
가지고 mem0 클라이언트의
[09:38]
add 함수를 호출할 것이기 때문입니다.
[09:40]
사용자 메시지와 AI 응답을 기반으로
[09:43]
특정 사용자를 위한 주요 메모리를 추출하고
[09:46]
저장합니다. 현재는 메모리에만
[09:49]
저장되며, 나중에
[09:51]
Supabase와 연동할 것입니다.
[09:53]
그리고 응답을 반환합니다.
[09:54]
매우 간단한 함수입니다. 그리고
[09:56]
메인 함수에서는 단순히
[09:58]
무한 루프로 사용자의 입력을
[10:01]
받고, 종료를 원하면
[10:03]
프로그램을 종료할 수 있게 합니다.
[10:05]
그렇지 않으면 chat_with_memories 함수를
[10:07]
호출하여 사용자 입력과
[10:09]
최신 사용자 메시지로 다음 응답을 받고
[10:11]
mem0와 관련된 모든 작업을
[10:14]
이 함수에서 수행합니다.
[10:16]
그리고 사용자 ID로
[10:17]
기본값인 'default_user'를 사용합니다.
[10:19]
그래서 매개변수가 하나뿐입니다.
[10:21]
이것이 전부입니다. 이것이
[10:23]
우리의 버전 1입니다. 이제
[10:24]
테스트해 보겠습니다. Python
[10:26]
환경이 이미 설정되어 있고
[10:28]
환경 변수도 설정되어 있습니다.
[10:29]
이제 'python iterations'
[10:32]
그리고 'version_one_basic_mem'을 실행합니다.
[10:34]
이제 GPT-4와
[10:36]
채팅 인터페이스가 열렸습니다.
[10:38]
간단히 '안녕'이라고 입력해 보겠습니다.
[10:40]
응답이 왔네요. 이 시점에서는
[10:42]
저장할 만한 내용이 없기 때문에
[10:44]
아직 메모리에 아무것도 저장되지 않을 거예요
[10:46]
이걸 직접 증명해 보겠습니다
[10:48]
대화 기록이 전혀 없다는 걸 보여드릴게요
[10:50]
'방금 내가 뭐라고 했지?'라고 물어보면
[10:52]
만약 최신 사용자 메시지 이상을
[10:54]
저장하고 있다면
[10:57]
우리가 '안녕'이라고 했다는 걸 알 수 있을 텐데
[10:59]
지금은 이전 대화를 전혀 기억하지 못하고 있죠
[11:01]
이전 대화나 발언을 전혀 기억하지 못합니다
[11:03]
대화 기록은 없지만
[11:07]
메모리에 저장하게 할 수는 있어요
[11:09]
새로운 내용을 말해볼게요. '나는 모든 종류의 치즈를 좋아하는데
[11:12]
염소 치즈만 빼고 좋아해' - 이건 사실이에요
[11:16]
블루 치즈를 포함해 다 좋아하는데
[11:18]
염소 치즈만 왠지 모르게...
[11:20]
암튼 그렇습니다
[11:21]
자, 응답이 왔고
[11:23]
그리고 백그라운드에서
[11:24]
memo add 함수를 호출해서 그 기억을 저장했어요
[11:27]
그래서 비록
[11:29]
대화 기록은 전혀 없지만
[11:31]
'내 음식 취향이 뭐지?'라고
[11:33]
물어보면 응답을 받을 수 있어요
[11:35]
대화 기록이 아닌
[11:38]
장기 메모리에서 정보를 가져왔기 때문에
[11:40]
제가 치즈에 대해 어떤 선호도를 가지고 있는지
[11:42]
알고 있죠. 그리고 중간에 얼마나 많은
[11:45]
메시지나 대화가 오갔는지는
[11:47]
전혀 중요하지 않아요
[11:49]
그 기억을 다시 불러올 때
[11:51]
여전히 검색이 가능합니다
[11:53]
장기 지식 베이스에 저장되어 있기 때문이죠
[11:55]
지금은 단순히 이 스크립트 내의
[11:57]
메모리에만 저장되어 있지만
[11:59]
Supabase로 넘어가면
[12:02]
메모리의 임베딩이 Supabase에 저장되고
[12:04]
데이터베이스에서 확인할 수 있게 됩니다
[12:06]
자, 이제 그걸 해볼까요?
[12:08]
사실 처음부터 Supabase를
[12:10]
버전 1에 포함시킬 수도 있었지만
[12:12]
첫 버전은 최대한 단순하게 유지하고 싶었어요
[12:14]
다행히도 Supabase를 추가하는 건
[12:16]
그렇게 어렵지 않아요. 보세요
[12:19]
몇 줄만으로 가능합니다
[12:21]
자, 보세요. 이게 전부예요
[12:23]
Mem0 클라이언트의 설정만
[12:25]
변경하면 됩니다
[12:28]
벡터 스토어를 위해
[12:30]
기본 인메모리 방식 대신
[12:32]
Supabase를 사용하도록 지정하고
[12:34]
연결 문자열은
[12:36]
환경 변수로 설정했어요
[12:38]
자,
[12:40]
example로 가보면
[12:41]
설정 방법에 대한 설명이 주석으로 있습니다
[12:43]
빠르게 보여드릴게요
[12:45]
Supabase 인스턴스에서
[12:46]
상단 중앙의 'connect'를 클릭하고
[12:48]
transaction pooler로 내려가서
[12:50]
parameters를 보면
[12:52]
모든 파라미터가 있습니다
[12:54]
여기 있는 연결 문자열을
[12:56]
그대로 복사하면 돼요. 정말 쉽죠
[12:58]
채워넣어야 할 건
[12:59]
데이터베이스 비밀번호 자리뿐입니다
[13:02]
비밀번호만 기억하고 있다면
[13:04]
바로 시작할 수 있어요
[13:05]
그리고 모델도
[13:07]
환경 변수를 통해 동적으로 설정할 수 있게 했어요
[13:10]
이게 변경된 내용의 전부입니다
[13:12]
나머지는 버전 1과 완전히 동일하고
[13:13]
이제 Supabase가 설정됐습니다
[13:15]
이제 우리는
[13:17]
에이전트와 대화하면서
[13:20]
Supabase에 우리의 기억이 저장되는 것을 지켜볼 수 있습니다.
[13:22]
정말 멋진 걸 보여드리겠습니다.
[13:24]
터미널로 돌아와서
[13:25]
버전 1 대신 버전 2를 실행하고 있습니다.
[13:28]
Supabase 인스턴스의
[13:30]
memories 테이블로 가보면
[13:31]
Mem0가 모든 기억을 저장할 곳이
[13:33]
완전히 비어있습니다. 참고로
[13:36]
이걸 보려면 VEX 스키마로 가야 합니다.
[13:38]
일반적으로 사용하는
[13:40]
public 스키마와는 다릅니다.
[13:41]
Supabase에서요. VEX로 가면
[13:42]
Mem0가 생성할 이 테이블을 찾을 수 있습니다.
[13:44]
직접 SQL을 실행할 필요도 없이
[13:46]
매우 편리하게 만들어줍니다.
[13:49]
이제 터미널로 돌아가서
[13:51]
대화를 나누면서
[13:52]
Supabase에 기억이 쌓이는 걸 보겠습니다.
[13:54]
다시 한 번
[13:56]
무작위로 시작해보겠습니다. '나는 PHP로
[14:00]
코딩하느니 차라리 발을 쏘겠다'라고 하겠습니다.
[14:04]
사실 이건 진심입니다.
[14:06]
PHP를 그다지 좋아하지 않아서
[14:08]
JavaScript, Python이나
[14:10]
Go를 훨씬 선호합니다. 자, 보시죠.
[14:12]
우리의 기억을 위한 벡터가 생성되었네요.
[14:15]
이 긴 숫자 리스트가 바로 그겁니다.
[14:17]
처음에는 검색했지만
[14:19]
기억을 찾지 못했고
[14:20]
하나를 만들고 나서
[14:22]
아래에 응답을 주었습니다.
[14:24]
'PHP에 대해 많이 좌절하신 것 같네요.' 맞아요.
[14:27]
한동안 다루지 않았지만
[14:29]
그렇죠. Supabase로 돌아가서
[14:30]
테이블을 새로고침 해보면
[14:33]
짜잔! 첫 번째 기억이 생겼습니다.
[14:35]
메타데이터를 보면
[14:37]
어떤 텍스트가 벡터화되었는지 알 수 있습니다.
[14:41]
'사용자는 PHP에 좌절감을 느끼고
[14:43]
다시는 사용하고 싶어하지 않음' 맞습니다.
[14:46]
사용자 ID는 기본값으로
[14:48]
default user로 되어있고
[14:50]
나중에 Supabase 인증을 추가하면
[14:52]
더 현실적인 값으로 변경될 것입니다.
[14:54]
그리고 생성 시간도 있네요.
[14:56]
이것이 메타데이터입니다.
[14:58]
이제 이게 정말 작동하는지
[14:59]
장기 기억으로서 작동하는지 보여드리기 위해
[15:02]
스크립트를 완전히 종료하고 다시 시작하겠습니다.
[15:06]
이전 대화 기록이 있더라도
[15:08]
여기서 설정한 것처럼
[15:10]
새로운 인스턴스를 시작합니다.
[15:12]
'내 코딩 선호도가 어떻게 되나요?'라고
[15:15]
물어보겠습니다.
[15:17]
먼저 기억을 검색하고
[15:18]
여기 있는 기억을 찾아냅니다.
[15:21]
이건 기억이 아주 많아도
[15:22]
잘 작동할 거예요.
[15:24]
지금은 단순하게 하기 위해
[15:25]
하나만 가지고 있습니다.
[15:27]
응답을 보면 '기억을 바탕으로,
[15:29]
PHP 코딩을 피하시는 것 같네요'라고 하네요.
[15:32]
네, 말 그대로입니다.
[15:34]
아주 잘 작동하고 있습니다. 이제
[15:36]
다음으로 필요한 것은
[15:38]
사용자 인증을 제대로
[15:40]
처리하는 것입니다.
[15:41]
지금은 사용자 ID에 기본값만 사용하고 있죠.
[15:44]
이제 Supabase 인증 설정 방법과
[15:46]
로그인한 사용자의 ID로 기억을 저장하는 방법,
[15:49]
그리고 프론트엔드 구현까지
[15:51]
보여드리겠습니다.
[15:53]
버전 3에서는 Supabase 인증을 보여드리기 위해
[15:54]
프론트엔드를 만들었습니다.
[15:57]
매우 간단한 스트림릿 사용자 인터페이스를 만들었는데요.
[16:00]
여기서 보이는 코드의 대부분은
[16:01]
Claude 3.7이 도움을 준 기본 템플릿입니다.
[16:04]
이전 버전들처럼 처음부터
[16:05]
자세히 설명하지는 않을 거지만,
[16:07]
궁금하실 것 같아서 빠르게
[16:09]
설명해드리겠습니다.
[16:11]
스트림릿으로 이렇게 쉽게
[16:12]
설정할 수 있다는 게 정말 멋지죠.
[16:14]
Supabase 인증을 위해 URL과 키가 필요한데
[16:17]
Supabase 인증을 위한
[16:19]
약간 메타적이지만
[16:21]
이해가 되실 거예요.
[16:23]
이것들을 env 파일의 마지막 두 값으로 설정하고
[16:26]
그런 다음 우리의 설정을 가져옵니다.
[16:29]
이전과 동일한 방식으로 mem 클라이언트를 생성하구요.
[16:32]
그리고 Supabase를 통한
[16:34]
모든 가입과 로그인에 대해
[16:37]
사용자 인터페이스 세션 상태의 일부로
[16:40]
사용자를 저장합니다. 이렇게 하면
[16:42]
Memzero 클라이언트를 호출할 때
[16:45]
사용자 ID를 가져올 수 있죠.
[16:47]
이전에 사용하던 기본 사용자
[16:49]
플레이스홀더 값 대신에 이것을 사용합니다.
[16:52]
메모리가 있는 채팅 기능은
[16:54]
여전히 기본적으로 동일하지만
[16:56]
인터페이스와 잘 작동하도록
[16:57]
약간의 차이가 있습니다.
[16:59]
여기서 중요한 점은
[17:02]
이제 사용자 ID가 하드코딩된 값이 아닌
[17:04]
동적으로 변하게 된다는 겁니다.
[17:06]
그 방법을 보여드리면,
[17:08]
인터페이스 코드 아래쪽에서
[17:10]
현재 사용자를 가져옵니다.
[17:12]
로그인하면 이 사용자 값이 생성되고
[17:14]
그 안에 사용자 ID가 있습니다.
[17:17]
이렇게 사용자 ID를 가져오는데,
[17:19]
이는 Supabase에서 오는 거죠.
[17:21]
그래서 채팅을 시작할 때
[17:24]
메모리와 함께 대화할 때
[17:26]
이전처럼 기본값이 아닌
[17:28]
실제 사용자 ID를 전달합니다.
[17:30]
이제 이걸 가지고 시연해보겠습니다.
[17:33]
어떻게 작동하는지 보여드릴게요.
[17:35]
몇 가지 테스트 계정을
[17:37]
사용자 인터페이스에서 사용해서
[17:39]
로그인한 이메일에 따라
[17:41]
다르게 기억하는 것을
[17:42]
보여드리겠습니다. 버전 3은
[17:44]
스트림릿 앱이기 때문에
[17:46]
일반 파이썬 스크립트가 아닌
[17:48]
streamlit run 명령어와
[17:49]
버전 3의 경로로 실행합니다.
[17:51]
그러면 자동으로 브라우저에
[17:53]
이 페이지가 열리고 로그인할 수 있죠.
[17:56]
왼쪽에서 말이에요.
[17:57]
테스트용으로 사용할
[17:59]
이메일이 몇 개 있는데요.
[18:02]
하나로 로그인해보겠습니다.
[18:04]
자, 로그인을 하면
[18:06]
이 계정으로 로그인이 됐네요.
[18:08]
이건 Supabase 인증을 사용하는 거라
[18:10]
여기서는 모의 데이터가 전혀 없고
[18:11]
Supabase가 이미 설정되어 있습니다.
[18:14]
정말 쉽죠. 심지어 현재
[18:16]
사용자 ID도 보여줍니다.
[18:18]
이걸 저장된 메모리와
[18:20]
대조해서 실제로
[18:22]
현재 사용자의 정보를
[18:23]
저장하고 있는지 확인할 수 있고
[18:25]
메모리도 지울 수 있죠.
[18:27]
자, 이제 뭔가를 말해볼까요?
[18:30]
우리가 이미 AGI를 달성했는데 사람들이 조용히 하고 있다고 생각한다고 말해보죠.
[18:35]
이것에 대해 쉬쉬하고 있다고요.
[18:38]
명백히 에이전트가 기억해야 할
[18:40]
의견을 제시하고 있는 거죠.
[18:42]
에이전트가 이 기억을 저장하는 걸 지켜보겠습니다.
[18:44]
자, 저장이 완료됐네요.
[18:46]
이제 Supabase로 돌아가서
[18:49]
새로고침을 해보면, 버전2에서 테스트했던
[18:51]
이전 기록이 있고, 이제 새로운 기록이 추가됐습니다.
[18:53]
"사용자는 우리가 이미 AGI를 달성했고
[18:55]
사람들이 이것에 대해 쉬쉬하고 있다고 믿는다"
[18:57]
그리고 사용자 ID를 보면
[19:00]
버전2에서 봤던 기본 사용자가 아닌
[19:02]
실제 Supabase의
[19:04]
사용자 ID가 있습니다.
[19:07]
이걸 복사해서 인터페이스로 돌아가
[19:09]
검색해보면,
[19:11]
예상대로 Streamlit이 보여주는
[19:14]
사용자 ID와 정확히 일치합니다.
[19:16]
이제 로그아웃하고
[19:19]
다른 계정으로 로그인해서
[19:21]
기억이 별도로 저장되는지
[19:24]
확인해보겠습니다. 다른 이메일로
[19:26]
로그인하겠습니다.
[19:30]
좋습니다. 대화 내용은 여전히 있지만
[19:33]
기억하세요, 에이전트는
[19:35]
대화 기록을 추적하지 않습니다.
[19:36]
새로고침할 수도 있지만,
[19:38]
계속 진행하겠습니다.
[19:40]
"우리는 전혀 AGI를 달성하지 못했다"라고 말해보겠습니다.
[19:45]
이 메시지를 보내면
[19:47]
이제 다른 사용자와는 완전히 반대되는
[19:49]
기억을 저장하게 됩니다.
[19:51]
일부러 이렇게 하는 건데요,
[19:53]
우리가 AGI를 달성하지 못했다고 했습니다.
[19:56]
이제 Supabase로 돌아가서
[19:58]
테이블을 다시 새로고침하면
[20:00]
세 번째 기록이 생겼습니다.
[20:02]
"사용자는 AGI를 전혀 달성하지 못했다고 생각한다"
[20:05]
그리고 이 사용자 ID는
[20:07]
현재 로그인한 계정과 일치합니다.
[20:10]
이제 "AGI를 달성했다고 생각하나요?"
[20:13]
라고 물어보겠습니다. 질문을 이렇게 하는 게
[20:16]
가장 좋은 방법은 아닐 수 있지만,
[20:17]
제가 어떻게 생각하는지 알려줄 것 같네요.
[20:19]
잘 작동하는지 보겠습니다.
[20:21]
AGI 달성 여부를 물어보고 있죠.
[20:22]
"기억에 따르면 당신은
[20:24]
AGI를 달성하지 못했다고 믿고 있습니다."
[20:27]
보세요, 이제 로그아웃하고
[20:29]
첫 번째 계정으로 다시 로그인하겠습니다.
[20:33]
이것이 바로 제가
[20:35]
일부러 정반대의 기억을
[20:38]
만든 이유입니다.
[20:39]
똑같은 질문을 붙여넣겠습니다.
[20:41]
"AGI를 달성했다고 생각하나요?"
[20:44]
일부러 이렇게 하는 이유는
[20:46]
사용자 ID로 구분되기 때문에
[20:48]
에이전트가 실수로 다른 사용자의
[20:50]
기억을 참조할 가능성이 전혀 없습니다.
[20:52]
따라서 완전히 다른 정보임에도
[20:54]
올바른 응답을 보장받을 수 있습니다.
[20:56]
따라서,
[20:57]
"당신이 공유한 내용에 따르면
[20:59]
우리가 이미 AGI를 달성했고
[21:01]
이에 대한 논의가 대중에게
[21:03]
공개되지 않고 있다고 믿습니다."
[21:06]
참고로 저는 두 의견을 모두 제시했는데,
[21:08]
실제로 어느 쪽을 믿는지는 모르겠습니다.
[21:09]
그건 또 다른 논의 주제죠.
[21:11]
하지만 이 시스템은 완벽하게 작동합니다.
[21:13]
한 계정에서는 한 가지를 말하고,
[21:15]
다른 계정에서는 정반대를 말하는데,
[21:17]
이는 사용자 데이터와 사용자 ID를 기반으로
[21:20]
기억을 참조하기 때문입니다.
[21:22]
이것은 완벽하게 작동하고 있습니다.
[21:24]
그리고 제가 이미 말씀드렸듯이
[21:26]
이것들은 대부분 Mem Zero를
[21:28]
시작하기 위한 예시들입니다.
[21:30]
앞으로 더 발전시켜
[21:32]
AI 에이전트에 실제로 통합하여
[21:34]
프로덕션 환경에서 활용할 수 있습니다.
[21:37]
이것은 시작을 위한
[21:39]
좋은 기반을 제공합니다.
[21:41]
Mem Zero는 내부적으로
[21:43]
많은 기능을 수행하기 때문에
[21:46]
기본적인 구현만으로도
[21:48]
꽤 강력한 장기 메모리 기능을
[21:51]
제공합니다. 그리고 만약
[21:53]
Mem Zero가 내부적으로 어떻게 작동하는지
[21:55]
어떤 추가 기능을 제공하는지 궁금하시다면
[21:58]
보너스 섹션에서
[22:00]
다루도록 하겠습니다.
[22:01]
관심 있으신 분들은 참고해 주세요.
[22:02]
오늘 코드의 핵심 기능은
[22:04]
Mem Zero의 두 가지 주요 기능으로
[22:06]
어떤 에이전트 프레임워크와도
[22:08]
통합할 수 있는 메모리 추가와
[22:10]
메모리 검색입니다. 이 다이어그램에서
[22:12]
이를 잘 보여주고 있습니다.
[22:14]
메모리 추가의 경우
[22:16]
대화를 통해 들어오는 메시지가 있고
[22:18]
대화에서 핵심 메모리를
[22:20]
추출하도록 특별히 프롬프트된
[22:22]
대규모 언어 모델이 있습니다.
[22:24]
이는 메인 에이전트와는 다르며
[22:26]
시스템의 메모리 부분입니다.
[22:28]
그래서 이 새로운 메모리들은
[22:30]
벡터 데이터베이스에 추가됩니다.
[22:32]
본질적으로 각 사용자별로
[22:34]
RAG 설정과 지식 베이스를
[22:37]
에이전트와 대화할 때 가지게 됩니다.
[22:39]
Mem을 그래프 지식 구현으로
[22:41]
더욱 발전시킬 수도 있습니다.
[22:44]
이는 더 고급 사용 사례로
[22:46]
이 영상에서는 다루지 않겠습니다만
[22:48]
엔티티와 관계도 저장하여
[22:50]
더욱 강력하게 만들 수 있습니다.
[22:52]
하지만 RAG와 벡터 데이터베이스만으로도
[22:54]
일반적으로 충분합니다.
[22:56]
여기서 중요한 점은
[22:58]
단순한 RAG 이상이라는 것입니다.
[23:00]
사용자별로 데이터를 분리하고
[23:02]
Mem이 내부적으로
[23:04]
충돌 해결과 같은 중요한 작업을
[23:06]
수행하기 때문입니다.
[23:07]
새로운 메모리가 들어올 때
[23:09]
유사한 기존 메모리가
[23:10]
이미 있을 수 있으므로 중복을 방지합니다.
[23:13]
이것이 메모리 추가에
[23:14]
관한 모든 것입니다. 메모리 검색의 경우
[23:17]
또 다른 좋은 다이어그램이 있습니다.
[23:19]
여기서 보시는 모든 것은
[23:20]
주 AI 에이전트 실행 전에 처리됩니다.
[23:23]
왜냐하면 가장 관련성 높은 메모리를
[23:25]
가져와서 에이전트에게
[23:28]
장기 메모리 기능을 제공하는
[23:30]
역할을 하기 때문입니다. LLM이
[23:33]
쿼리를 지능적으로 재작성하여
[23:35]
벡터 데이터베이스에서
[23:36]
가장 관련성 높은 정보를 추출합니다.
[23:39]
지식 그래프를 통해
[23:41]
더 발전시킬 수도 있습니다.
[23:43]
그래서 관련된 메모리들이
[23:45]
벡터 데이터베이스에서 추출되면
[23:47]
AI 에이전트에게 전달됩니다.
[23:49]
메모리 추가와 마찬가지로
[23:51]
Mem Zero는 내부적으로
[23:53]
생각보다 더 많은 작업을
[23:54]
수행합니다. 관련성 점수 재순위화,
[23:57]
메타데이터와 타임스탬프 포함 등
[23:59]
고급 RAG 기술을 구현하여
[24:01]
장기 메모리가 매우 견고하도록
[24:03]
보장합니다. ChatGPT와 같은
[24:06]
플랫폼들도 실제로
[24:08]
Mem과 유사한 것을
[24:10]
통합하고 있습니다. Gemini보다
[24:12]
더 나은 기능을 제공하는 플랫폼들도 있지만
[24:15]
Mem Zero의 커스터마이제이션 수준과
[24:17]
제어 능력은 매우 뛰어납니다.
[24:20]
Python이나 Node SDK를 살펴보면
[24:22]
장기 메모리를 사용 사례에 맞게
[24:24]
최적화할 수 있는 많은 여지가
[24:27]
있습니다. 메모리 추가와 검색 방식에서
[24:28]
매우 강력한 기능을 제공합니다.
[24:30]
이 가이드가 AI 에이전트에
[24:32]
장기 메모리를 구현하는 방법을
[24:34]
명확하고 간단하게 설명했기를 바랍니다.
[24:37]
이 모든 것의 가장 좋은 점은
[24:39]
Mem Zero가 사용 사례나
[24:41]
프레임워크에 관계없이 쉽게
[24:43]
통합할 수 있다는 것입니다.
[24:46]
앞으로도 Mem에 대한
[24:47]
더 많은 콘텐츠를 만들 계획입니다.
[24:50]
고급 사용 사례, 다른 플랫폼과의 통합,
[24:52]
그래프 메모리 설정 등을
[24:53]
다룰 예정입니다.
[24:55]
이 콘텐츠가 도움이 되었고
[24:57]
AI 에이전트에 대해 더 알고 싶으시다면
[24:59]
좋아요와 구독 부탁드립니다.
[25:01]
다음 영상에서 뵙겠습니다.
[25:03]
감사합니다.