13. 중간 점검
현재 단계는 성공입니다. 특히 이번 결과는 단순히 "검색이 됐다"가 아니라, 지금까지 만든 장기기억 구조가 실제 Agent 안에서 연결되어 작동했다는 것이 중요합니다.
그리고 질문하신 "이제 마지막 단계인가?"에 대해서는 이렇게 보는 것이 가장 정확합니다.
지금까지의 진행 상황
① PostgreSQL에 장기기억 저장
↓
② Memory 추출 기능 구현
↓
③ ChromaDB 구축
↓
④ PostgreSQL → ChromaDB 동기화
↓
⑤ ChromaDB semantic search 구현
↓
⑥ Agent가 ChromaDB 기억을 검색하여 답변에 활용 ← 지금 성공
↓
⑦ 새 Memory를 PostgreSQL + ChromaDB에 동시에 저장 ← 다음 단계
↓
⑧ 전체 구조 통합 테스트
↓
⑨ 중복/오류/검색품질 개선 ← 선택적 고도화
따라서 핵심 기능 구현 기준으로는 2~3단계 정도 남았습니다.
다만 ⑦까지 끝나면 사실상 "PostgreSQL + ChromaDB 기반 장기기억 AI Agent의 기본 버전"은 완성이라고 볼 수 있습니다.
1. 우선 이번 테스트 결과를 정확하게 해석해 봅시다
이번 결과에서 가장 중요한 부분은 이것입니다.
🧠 관련 장기기억 검색 중...
☑️ 관련 Memory 5개 검색 완료
🤖 AI가 답변을 생성하는 중...
그리고 AI가:
당신은 Python을 활용하여 AI Agent를 개발하고 있으며...
라고 답했습니다.
즉,
사용자 질문
↓
ChromaDB semantic search
↓
관련 Memory 5개
↓
Memory Context 생성
↓
LLM에 전달
↓
AI가 Memory를 참고하여 답변
이 흐름이 실제로 작동했습니다.
2. 더 중요한 것은 Memory Extraction도 정상 작동했다는 것입니다
이번에는 질문을 보고 다시:
🧠 새로운 Memory 추출 중...
그리고:
[
{
"memory_type": "interest",
"content": "사용자는 Python을 활용하여 AI Agent를 개발하는 데 관심이 있다.",
"importance": 8
},
{
"memory_type": "goal",
"content": "사용자는 저작권 미구매 고객에게 자동으로 전화를 걸고 구매 요청을 하는 AI Agent를 만들고 싶어 한다.",
"importance": 9
}
]
를 추출했습니다.
그리고:
🧠기억 저장 완료 (memory_id=35)
🧠기억 저장 완료 (memory_id=36)
이것은 PostgreSQL 저장까지 정상적으로 됐다는 뜻입니다.

3. 그런데 현재 딱 하나의 문제가 남아 있습니다
여기가 다음 단계의 핵심입니다.
현재 구조는:
┌───────────────┐
│ 사용자 질문 │
└───────┬───────┘
↓
ChromaDB 검색
↓
LLM 답변
↓
Memory Extraction
↓
PostgreSQL 저장
입니다.
즉 새로 추출된 Memory가 현재는:
PostgreSQL ← 저장됨
ChromaDB ← 저장되지 않음
상태입니다.
4. 왜 이것이 문제일까요?
예를 들어 이번에 새로 저장된:
memory_id=35
Python을 활용하여 AI Agent를 개발하는 데 관심
memory_id=36
저작권 미구매 고객에게 자동으로 전화를 걸고 구매 요청하는 AI Agent를 만들고 싶음
이 두 개는 PostgreSQL에는 있습니다.
그런데 다음 질문을 했다고 생각해 보겠습니다.
내가 만들려고 하는 AI Agent의 구체적인 목표가 뭐였지?
현재 search_memory()는 ChromaDB를 검색합니다.
그런데 ChromaDB에는 아직 memory_id=35, 36이 없습니다.
그러면:
PostgreSQL
├─ 35 ✅
├─ 36 ✅
└─ ...
ChromaDB
├─ 35 ❌
├─ 36 ❌
└─ 기존 Memory만 존재
가 됩니다.
즉 기억은 저장됐는데 검색할 수 없는 상태가 됩니다.
이것이 현재 남아 있는 가장 중요한 연결 부분입니다.
5. 그래서 다음 단계는 "Dual Write"입니다
다음 단계의 목표는 아주 명확합니다.
새로운 Memory가 생성되면 PostgreSQL과 ChromaDB에 함께 저장한다.
구조를 이렇게 만드는 것입니다.
┌───────────────┐
│ 사용자 대화 │
└───────┬───────┘
↓
LLM 답변 생성
↓
Memory Extraction
↓
새로운 Memory
│
┌─────────┴─────────┐
↓ ↓
PostgreSQL 저장 ChromaDB 저장
Source of Truth 검색 Index
│ │
└─────────┬─────────┘
↓
다음 질문에서
ChromaDB 검색
이렇게 되면 구조가 완성됩니다.
6. 여기서 아주 중요한 설계 원칙
저는 다음 단계에서 PostgreSQL을 먼저 저장하고 ChromaDB를 나중에 저장하는 방식으로 가는 것을 권합니다.
즉:
① PostgreSQL 저장
↓
② memory_id 확보
↓
③ 해당 memory_id로 ChromaDB 저장
입니다.
왜냐하면 PostgreSQL이 원본(Source of Truth) 이기 때문입니다.
예를 들어:
PostgreSQL
memory_id = 37
user_id = 8
memory_type = goal
content = "..."
importance = 9
가 만들어졌다면 ChromaDB에는 정확히:
memory_37
이라는 ID로 넣습니다.
7. 현재 코드에서 가장 먼저 바꿀 곳
현재 database.py의 save_memory()가 아마 이런 형태일 것입니다.
def save_memory(conn, user_id, memory_type, content, importance=5):
...
여기서 중요한 것은 INSERT 후 생성된 memory_id를 반환하도록 만드는 것입니다.
예를 들어:
INSERT INTO memories (...)
VALUES (...)
RETURNING memory_id;
를 사용합니다.
그러면:
PostgreSQL INSERT
↓
memory_id = 37
↓
37을 Python으로 반환
할 수 있습니다.
이게 중요한 이유는 ChromaDB의 ID를 정확하게:
memory_37
로 만들 수 있기 때문입니다.
8. 그러면 Memory 저장 함수도 바뀝니다
현재는 아마:
save_memories()
↓
PostgreSQL에 저장
이었다면 다음에는:
save_memories()
↓
PostgreSQL 저장
↓
저장된 memory_id 확보
↓
저장된 Memory dictionary 생성
↓
ChromaDB upsert
가 됩니다.
예를 들어 최종적으로 내부적으로 이런 데이터가 만들어지는 것입니다.
{
"memory_id": 37,
"user_id": 8,
"memory_type": "goal",
"content": "사용자는 ... AI Agent를 만들고 싶어 한다.",
"importance": 9
}
그리고 이것을:
add_memories(...)
로 ChromaDB에 넣습니다.
9. 그러면 지금 만든 vector_store.py가 그대로 활용됩니다
이 부분이 아주 좋습니다.
우리가 이미 만들어 놓은:
add_memory()
add_memories()
가 있기 때문에 ChromaDB 쪽을 처음부터 다시 만들 필요가 없습니다.
현재 구조를 최대한 유지하면서:
database.py
│
│ memory_id 반환
↓
memory.py
│
│ 저장된 Memory dictionary 생성
↓
vector_store.py
│
│ add_memories()
↓
ChromaDB
로 연결하면 됩니다.
10. 그리고 여기서 한 가지 아주 중요한 것을 배우게 됩니다
이번 단계는 단순한 코딩 문제가 아닙니다.
실제 AI 시스템에서 "Database와 Vector DB를 어떻게 함께 관리할 것인가?"라는 매우 중요한 아키텍처 문제입니다.
우리가 지금 만들고 있는 구조는 사실상:
PostgreSQL
원본 데이터베이스
정확한 Memory 데이터
사용자 ID
Memory ID
Memory Type
Importance
생성일
ChromaDB
검색용 Index
Memory 내용
Embedding
검색용 metadata
distance
입니다.
따라서:
PostgreSQL이 원본이고 ChromaDB는 검색을 빠르고 의미적으로 하기 위한 인덱스다.
라고 기억하시면 됩니다.
이 개념은 앞으로 RAG나 Vector DB를 공부하실 때 상당히 중요합니다.
11. 다음 단계에서 우리가 만들 최종 구조
다음 단계가 끝나면 Agent는 이렇게 움직입니다.
사용자 질문
│
↓
┌───────────────┐
│ ChromaDB │
│ Semantic Search│
└───────┬───────┘
│
관련 Memory
│
↓
┌───────────────┐
│ LLM │
│ 답변 생성 │
└───────┬───────┘
│
답변
│
↓
Memory Extraction
│
↓
새로운 Memory
│
┌──────┴──────┐
↓ ↓
PostgreSQL ChromaDB
Source of Truth Vector Index
이제 읽기(Read)와 쓰기(Write)가 모두 연결됩니다.
12. 그 다음에는 통합 테스트를 합니다
Dual Write가 끝나면 바로 한 번 더 테스트합니다.
예를 들어:
1차 질문
나는 앞으로 어떤 AI Agent를 만들고 싶어?
그러면:
PostgreSQL
memory_id=37 저장
그리고 동시에:
ChromaDB
memory_37 저장
되는지 확인합니다.
2차 질문
완전히 다른 질문을 합니다.
내가 만들려고 하는 AI Agent의 목적이 뭐였지?
그러면 ChromaDB가 방금 추가된 memory_37을 찾아내야 합니다.
즉:
새 Memory 생성
↓
PostgreSQL 저장
↓
ChromaDB 저장
↓
새로운 질문
↓
ChromaDB semantic search
↓
방금 저장한 Memory 발견
↓
LLM 답변
까지 확인하면 기본 장기기억 Agent가 완성됩니다.
13. 그 다음은 "선택적인 고도화"입니다
기본 기능이 완성된 뒤에는 이런 것들을 할 수 있습니다.
A. 중복 Memory 방지
현재 테스트 결과를 보면 이미:
같은 내용의 Memory가 여러 개
생길 가능성이 있습니다.
예를 들어 같은 질문을 반복하면:
Python과 AI Agent에 관심
이라는 Memory가 계속 생성될 수 있습니다.
이것은 다음 단계에서:
새 Memory
↓
기존 Memory와 유사한가?
↓
YES → 기존 Memory 업데이트/무시
NO → 새 Memory 저장
방식으로 개선할 수 있습니다.
B. Memory 중요도와 검색 결과 결합
현재는 ChromaDB의 semantic similarity 중심입니다.
나중에는:
semantic similarity
+
importance
+
최신성
을 함께 고려할 수 있습니다.
예:
최종 점수 =
semantic similarity
× importance
× recency
같은 방식입니다.
이것은 꽤 재미있는 다음 단계입니다.
C. Memory 삭제/수정
실제 서비스에서는 사용자가:
내가 예전에 저장된 그 기억을 삭제해줘.
라고 할 수도 있습니다.
그러면:
PostgreSQL 삭제
+
ChromaDB 삭제
를 동시에 처리해야 합니다.
D. Memory 충돌 해결
예를 들어 과거에는:
사용자는 Python을 공부하고 있다.
였다가 나중에는:
사용자는 Python 공부를 중단했다.
가 될 수 있습니다.
그렇다면 단순히 두 개를 저장하면:
Memory A: Python 공부 중
Memory B: Python 공부 중단
이라는 충돌이 발생합니다.
이것도 실제 장기기억 시스템에서는 상당히 중요한 문제입니다.
14. 그런데 지금은 여기까지 가지 않는 것이 좋습니다
지금 사용자님이 배우는 과정에서는 한 번에 너무 많은 것을 넣지 않는 것이 좋습니다.
지금까지 우리가 한 것을 보면:
PostgreSQL
↓
Memory Extraction
↓
ChromaDB
↓
Semantic Search
↓
Agent Retrieval
까지 차근차근 하나씩 만들었습니다.
이제 딱 하나:
새로운 Memory를 PostgreSQL과 ChromaDB에 동시에 저장
하는 것만 연결하는 것이 좋습니다.
그것이 끝나면 기본 아키텍처가 완성됩니다.
15. 그래서 다음 단계는 이렇게 진행합시다
제가 권하는 순서는 다음과 같습니다.
STEP 7-1
database.py
save_memory()가 PostgreSQL에 저장한 후:
memory_id
를 반환하도록 수정
↓
STEP 7-2
memory.py
save_memories()가 실제 저장된 Memory들을:
[
{
"memory_id": 37,
"user_id": 8,
"memory_type": "...",
"content": "...",
"importance": 9
}
]
형태로 만들어 반환
↓
STEP 7-3
vector_store.py
이미 만들어놓은:
add_memories()
를 이용해서 ChromaDB에 저장
↓
STEP 7-4
agent_with_memory.py
기존:
Memory 추출
↓
PostgreSQL 저장
을:
Memory 추출
↓
PostgreSQL 저장
↓
ChromaDB 저장
으로 변경
↓
STEP 7-5
통합 테스트
새로운 기억 생성
↓
PostgreSQL 확인
↓
ChromaDB 확인
↓
새 질문
↓
ChromaDB에서 방금 기억 검색
↓
AI가 그 기억을 활용
까지 확인
그리고 지금 결과에서 한 가지 더 칭찬할 부분
이번 테스트에서:
memory_id=35
memory_id=36
가 생성됐다는 것은 아주 좋습니다.
특히 importance=9인:
사용자는 저작권 미구매 고객에게 자동으로 전화를 걸고 구매 요청을 하는 AI Agent를 만들고 싶어 한다.
라는 구체적인 목표가 장기기억으로 구조화되어 저장되었습니다.
즉 우리가 처음에 만들었던 단순한 "대화형 Agent"에서 한 단계 더 나아가서,
사용자와 대화하면서 사용자의 관심사·목표·사실 등을 스스로 추출하고, 그것을 장기기억으로 축적하는 Agent
로 발전하고 있는 것입니다.
다음 단계에서는 바로 database.py → memory.py → vector_store.py → agent_with_memory.py 순서로 하나씩 수정하겠습니다.
특히 이번에는 한꺼번에 전체 코드를 바꾸기보다, 먼저 database.py의 save_memory()를 수정하고 테스트 → 성공하면 다음 파일로 이동하는 방식이 지금까지의 학습 방식에도 가장 잘 맞습니다.