지금은 단순히 코드를 조금 고치는 단계가 아니라, PostgreSQL과 ChromaDB를 처음으로 실제 연결하는 단계이므로 한 번에 Agent까지 바꾸지 않는 것이 좋습니다.
[요약]
# PostgreSQL의 memories 테이블과 ChromaDB연결 단계(1)
===> memory.py, vector_store.py 수정/보완하고 테스트하기
# step1. memory.py 수정
# step1.1. 7. Memory tuple → dictionary 과 8. Memory tuple 목록 → dictionary 목록 추가.
# step1.2. 기존의 7. Memory Context 생성 => 9.Memory Context 생성로 변경하고 코드 수정
# step2. vector_store.py를 보완(1)(2)(3)(4)
# step3. test_postgres_to_chroma.py를 만들어서 테스트
===> cd C:\Dev\book_agentic_ai\agent_projec폴더에서
===> python test_postgres_to_chroma.py
이번 단계의 목표를 먼저 명확하게 잡겠습니다.
이번 단계의 목표:
PostgreSQL에 이미 저장되어 있는 Memory를 가져와서 → ChromaDB에 정상적으로 저장하고 → 의미 검색까지 해본다.
Agent는 이번 단계에서는 아직 건드리지 않습니다.
전체 진행 그림
우리가 지금부터 만드는 것은 다음입니다.
PostgreSQL
장기기억 원본
│
│ get_memories()
↓
Memory tuple
│
│ 변환
↓
Memory dictionary
│
│ add_memories()
↓
ChromaDB
의미 기반 검색
│
│ query
↓
관련 Memory 반환
그리고 이번 단계를 끝내면 다음 단계에서:
사용자 질문
↓
ChromaDB 의미 검색
↓
관련 Memory
↓
LLM
↓
답변
으로 연결할 수 있습니다.
먼저 반드시 고칠 것: memory.py
현재 가장 중요한 오류는 제가 앞서 말씀드린 tuple 인덱스 문제입니다.
database.py의 get_memories()는 현재:
SELECT
memory_id,
user_id,
memory_type,
content,
importance,
created_at
순서입니다.
따라서 하나의 memory는:
[0] memory_id
[1] user_id
[2] memory_type
[3] content
[4] importance
[5] created_at
입니다.
그런데 현재 build_memory_context()는 예전 구조를 기준으로 작성되어 있습니다.
이것부터 수정하겠습니다.
① memory.py 수정
이번에는 memory.py 전체를 아래 코드로 교체하는 것을 권합니다.
①-1. 이번 수정에서 무엇이 달라졌는가?
중요한 것만 짚어보겠습니다.
첫 번째
기존:
System_prompt = """
수정:
system_prompt = """
파이썬에서는 변수명에 대문자/소문자를 자유롭게 사용할 수 있지만, 일반적으로 지역 변수는 snake_case로 쓰는 것이 좋습니다.
두 번째 — 가장 중요
기존에는:
memory_id = memory[0]
memory_type = memory[1]
content = memory[2]
importance = memory[3]
created_at = memory[4]
였습니다.
이것을:
memory_id = memory[0]
user_id = memory[1]
memory_type = memory[2]
content = memory[3]
importance = memory[4]
created_at = memory[5]
로 수정했습니다.
이것이 필수 수정사항입니다.
①-2. 그리고 memory.py에 변환 함수를 넣은 이유
이번에 추가한:
def memory_tuple_to_dict(row):
와
def memory_tuples_to_dicts(rows):
는 앞으로 상당히 중요하게 사용합니다.
PostgreSQL에서:
tuple
형태로 나오는 것을
dictionary
로 바꾸는 겁니다.
예를 들어 DB에서:
(
7,
1,
"interest",
"사용자는 Python과 AI Agent를 학습하고 있다.",
8,
datetime(...)
)
가 나오면:
{
"memory_id": 7,
"user_id": 1,
"memory_type": "interest",
"content": "사용자는 Python과 AI Agent를 학습하고 있다.",
"importance": 8,
"created_at": datetime(...)
}
가 됩니다.
이렇게 하면 이후 ChromaDB에 넣기가 훨씬 쉬워집니다.
② 이제 vector_store.py를 보완합니다
현재 vector_store.py는 기본적인 기능이 잘 되어 있습니다.
다만 이번에는 PostgreSQL에서 가져온 Memory를 ChromaDB에 넣는 역할을 명확하게 추가하겠습니다.
그리고 한 가지 원칙을 지키겠습니다.
PostgreSQL의 memory_id를 ChromaDB의 ID로 그대로 연결한다.
예를 들어:
PostgreSQL
memory_id = 17
이면 ChromaDB:
memory_17
이 됩니다.
그러면 나중에:
ChromaDB 검색 결과
↓
memory_17
↓
PostgreSQL memory_id = 17
로 원본을 찾을 수 있습니다.

vector_store.py 전체 교체
②-1. 이번에 sync_memories_to_chroma()를 만든 이유
이 함수가 이번 단계의 핵심입니다.
def sync_memories_to_chroma(memories):
사용하는 방법은:
memories = get_memories(...)
sync_memories_to_chroma(memories)
입니다.
그러면 내부적으로:
PostgreSQL
↓
get_memories()
↓
[
tuple,
tuple,
tuple
]
↓
memory_tuple_to_dict()
↓
[
dict,
dict,
dict
]
↓
add_memories()
↓
ChromaDB
가 됩니다.
②-2. created_at을 ChromaDB metadata에 넣지 않은 이유
현재 PostgreSQL에는:
created_at
이 있습니다.
그런데 이번 단계에서는 ChromaDB metadata에 넣지 않았습니다.
현재:
metadatas.append(
{
"memory_id": memory_id,
"user_id": user_id,
"memory_type": memory_type,
"importance": importance,
}
)
까지만 합니다.
이유는 간단합니다.
created_at은 PostgreSQL의 원본 데이터에서 관리하는 것이 더 좋기 때문입니다.
그리고 ChromaDB에서는 일단:
memory_id
user_id
memory_type
importance
정도만 있으면 검색과 필터링 학습에 충분합니다.
③ 이제 테스트 코드를 만듭니다
여기가 매우 중요합니다.
Agent를 실행하지 않습니다.
먼저 독립적인 테스트를 만들어서:
PostgreSQL → ChromaDB
가 정말 되는지를 확인합니다.
파일 이름은:
test_postgres_to_chroma.py
로 하겠습니다.
현재:
agent_project/
밑에 새로 만드세요.
agent_project/
│
├─ database.py
├─ memory.py
├─ vector_store.py
├─ agent_with_memory.py
├─ test_chroma.py
├─ test_postgres_to_chroma.py ← 새 파일
│
├─ chroma_db/
│
└─ .env
test_postgres_to_chroma.py
전체 코드는 다음과 같습니다.
③-1. 이 테스트에서 중요한 부분
이 테스트는 Agent가 아닙니다.
이 점을 꼭 이해하시면 좋겠습니다.
현재는:
Agent
를 테스트하는 것이 아니라
데이터 파이프라인
을 테스트하는 것입니다.
즉:
PostgreSQL
↓
Memory 가져오기
↓
Dictionary 변환
↓
ChromaDB 저장
↓
Vector Search
만 검증합니다.
④ 이제 실행합니다
프로젝트 폴더에서:
cd C:\Dev\book_agentic_ai\agent_project
그리고:
python test_postgres_to_chroma.py
를 실행하세요.
④-1. 정상적으로 나온다면
예를 들어 PostgreSQL에 다음 Memory가 있다면:
memory_id : 1
user_id : 1
memory_type : interest
content : 사용자는 Python과 AI Agent를 학습하고 있다.
importance : 8
다음과 비슷한 결과가 나와야 합니다.
======================================================================
PostgreSQL → ChromaDB 연동 테스트
======================================================================
[STEP 1] PostgreSQL 연결
☑️ PostgreSQL 연결 성공
[STEP 2] 테스트 사용자 조회
☑️ 사용자 발견
user_id : 1
user_name : 스티븐김
location : 대한민국
preferences : 저작권 안내 자동전화AI
[STEP 3] PostgreSQL Memory 조회
☑️ PostgreSQL에서 3개 Memory 발견
memory_id : 3
user_id : 1
memory_type : interest
content : 사용자는 Python과 AI Agent를 학습하고 있다.
importance : 8
created_at : ...
--------------------------------------------------
[STEP 4] PostgreSQL → ChromaDB 동기화
☑️ ChromaDB에 3개 기억 저장 완료
[STEP 5] ChromaDB 상태 확인
☑️ ChromaDB 저장된 전체 Memory 개수: 6
[STEP 6] ChromaDB 의미 검색
검색 질문:
나는 파이썬과 AI 에이전트 개발을 공부하고 있다.
[STEP 7] 검색 결과
IDs:
[['memory_3', 'memory_1', ...]]
Documents:
[['사용자는 Python과 AI Agent를 학습하고 있다.',
...]]
Metadatas:
[[{'memory_id': 3,
'user_id': 1,
'memory_type': 'interest',
'importance': 8},
...]]
Distances:
[[0.2..., 0.7..., ...]]
----------------------------------------------------------------------
🎉 PostgreSQL → ChromaDB 테스트 완료
이런 식으로 나오면 핵심 연결이 성공한 것입니다.
그런데 한 가지 주의할 점
현재 test_chroma.py에서 이미:
collection.upsert(
ids=["memory_1", "memory_2", "memory_3"],
를 실행했습니다.
따라서 현재 chroma_db에는 테스트용 Memory가 이미 있을 가능성이 높습니다.
즉:
ChromaDB count = PostgreSQL Memory 개수
가 반드시 같지는 않습니다.
예를 들어:
기존 테스트 데이터 3개
+
PostgreSQL Memory 5개
=
8개
가 될 수 있습니다.
이건 오류가 아닙니다.
오히려 여기서 아주 중요한 개념이 하나 있습니다
우리가 upsert()를 사용하는 이유가 바로 이것입니다.
예를 들어 PostgreSQL에:
memory_id = 5
가 있다면 ChromaDB ID는:
memory_5
입니다.
첫 번째 실행:
collection.upsert(
ids=["memory_5"],
...
)
→ 새로 생성
두 번째 실행:
collection.upsert(
ids=["memory_5"],
...
)
→ 같은 ID이므로 새로운 중복 Memory가 생기는 것이 아니라 기존 값을 업데이트
합니다.
따라서 테스트를 여러 번 실행해도:
memory_5
memory_5
memory_5
memory_5
처럼 계속 쌓이지 않습니다.
이것은 앞으로 Memory 시스템을 만들 때 굉장히 중요한 특징입니다.
지금 단계에서 test_chroma.py는 어떻게 할까?
현재 test_chroma.py는 버리지 마세요.
그 파일은 ChromaDB 자체가 제대로 설치되고 동작하는지 확인하는 기초 테스트입니다.
현재:
test_chroma.py
는:
"ChromaDB 자체 테스트"
이고,
이번에 만든:
test_postgres_to_chroma.py
는:
"PostgreSQL과 ChromaDB의 연결 테스트"
입니다.
둘은 역할이 다릅니다.
지금까지의 구조를 다시 정리하면
database.py
PostgreSQL 담당
사용자
Memory
저장
조회
memory.py
Memory Logic 담당
LLM
↓
Memory 추출
↓
Memory 저장
↓
Memory Context
그리고 이번에:
tuple → dictionary
변환 기능을 추가했습니다.
vector_store.py
ChromaDB 담당
Memory 저장
Memory 검색
user_id 필터
그리고 이번에:
PostgreSQL Memory
↓
sync_memories_to_chroma()
↓
ChromaDB
를 추가했습니다.
test_chroma.py
ChromaDB 자체 테스트
test_postgres_to_chroma.py
PostgreSQL
↓
ChromaDB
통합 테스트입니다.
그런데 아직 Agent는 그대로입니다
현재 agent_with_memory.py는 여전히:
memories = search_memory(
conn,
user_id=user_id,
limit=10,
)
을 사용합니다.
즉 아직은:
사용자 질문
↓
PostgreSQL에서 중요도 높은 Memory 10개
↓
LLM
입니다.
이번 단계에서는 이것을 아직 바꾸지 않습니다.
왜냐하면 먼저:
PostgreSQL
↓
ChromaDB
↓
의미 검색
이 확실히 동작하는 것을 확인해야 하기 때문입니다.
그리고 다음 단계가 진짜 재미있는 부분입니다
이번 테스트가 성공하면 다음 단계에서는 memory.py의:
def search_memory(conn, user_id, limit=10):
을 바꿉니다.
현재:
PostgreSQL
↓
중요도 순서
↓
10개
에서
사용자 질문
↓
ChromaDB
↓
의미적으로 가까운 Memory
↓
5개
로 바꾸게 됩니다.
그러면 Agent가 예를 들어:
"내가 요즘 어떤 공부를 하고 있지?"
라고 물었을 때,
단순히 최근 Memory 10개를 가져오는 것이 아니라,
질문
"내가 요즘 어떤 공부를 하고 있지?"
↓
Embedding
↓
ChromaDB
↓
┌──────────────────────────────┐
│ Python과 AI Agent 학습 │ ← 높은 관련성
│ PostgreSQL 학습 │ ← 관련성
│ HWP 자동문서 생성 │
│ 여행 │
└──────────────────────────────┘
처럼 질문과 의미가 가까운 기억을 찾아서 LLM에게 제공하게 됩니다.
이것이 이번 학습에서 중요한 분기점입니다.
따라서 지금은 여기까지 하고 실행 결과를 확인하면 됩니다
지금 해야 할 일은 딱 4가지입니다.
1. memory.py를 위 코드로 교체
2. vector_store.py를 위 코드로 교체
3. test_postgres_to_chroma.py를 새로 생성
4. 실행
[테스트 결과 예시] - 다음장에서 해설.
PostgreSQL → ChromaDB 연동 테스트
[STEP 1] PostgreSQL 연결
☑️ PostgreSQL 연결 성공
[STEP 2] 테스트 사용자 조회
☑️ 사용자 발견
user_id : 8
user_name : 스티븐김
location : 대한민국
preferences : Python과 AI Agent 학습
[STEP 3] PostgreSQL Memory 조회
☑️ PostgreSQL에서 8개 Memory 발견
memory_id : 30
user_id : 8
memory_type : goal
content : 사용자는 저작권 미구매 고객에게 자동으로 저작권 안내 전화를 걸고 구매 요청을 하는 AI를 만드는 것을 목표로 하고 있다.
importance : 9
created_at : 2026-09-05 13:21:36.822445
memory_id : 28
user_id : 8
memory_type : goal
content : 사용자의 목표는 저작권 미구매 고객에게 자동으로 저작권 안내 전화를 걸고 구매 요청을 하는 AI를 만드는 것이다.
importance : 9
created_at : 2026-09-05 13:21:16.167284
memory_id : 27
user_id : 8
memory_type : project
content : 사용자는 Python으로 AI Agent를 만들고 있으며, 저작권 미구매 고객에게 자동으로 저작권 안내 전화를 걸고 구매 요청을 하는 AI를 만들고 싶어 한다.
importance : 9
created_at : 2026-09-05 13:10:38.705845
memory_id : 23
user_id : 8
memory_type : goal
content : 사용자는 저작권 미구매 고객에게 자동으로 저작권 안내 전화를 걸고 구매 요청을 하는 AI를 만들고 싶어 한다.
importance : 9
created_at : 2026-09-05 12:54:34.591357
memory_id : 31
user_id : 8
memory_type : project
content : 사용자는 Python으로 AI Agent를 개발하여 저작권 미구매 고객에게 자동으로 전화를 걸도록 설계하고 있다.
importance : 8
created_at : 2026-09-05 13:22:11.034977
memory_id : 29
user_id : 8
memory_type : interest
content : 사용자는 Python으로 AI Agent를 만들고 있다.
importance : 8
created_at : 2026-09-05 13:21:25.354024
memory_id : 19
user_id : 8
memory_type : interest
content : 사용자는 Python으로 AI Agent를 만들고 있다.
importance : 8
created_at : 2026-09-05 12:04:07.015184
memory_id : 32
user_id : 8
memory_type : interest
content : 사용자는 Python을 활용한 AI Agent 개발에 관심이 있다.
importance : 7
created_at : 2026-09-05 13:22:11.038135
[STEP 4] PostgreSQL → ChromaDB 동기화
☑️ChromaDB에 8개 기억 저장 완료
[STEP 5] ChromaDB 상태 확인
☑️ ChromaDB 저장된 전체 Memory 개수: 15
[STEP 6] ChromaDB 의미 검색
검색 질문: 나는 파이썬과 AI 에이전트 개발을 공부하고 있다.
[STEP 7] 검색 결과
IDs:
[['memory_27', 'memory_29', 'memory_19', 'memory_32', 'memory_31']]
Documents:
[['사용자는 Python으로 AI Agent를 만들고 있으며, 저작권 미구매 고객에게 자동으로 저작권 안내 전화를 걸고 구매 요청을 하는 AI를 만들고 싶어 한다.', '사용자는 Python으로 AI Agent를 만들고 있다.', '사용자는 Python으로 AI Agent를 만들고 있다.', '사용자는 Python을 활용한 AI Agent 개발에 관심이 있다.', '사용자는 Python으로 AI Agent를 개발하여 저작권 미구매 고객에게 자동으로 전화를 걸도록 설계하고 있다.']]
Metadatas:
[[{'memory_type': 'project', 'user_id': 8, 'memory_id': 27, 'importance': 9}, {'memory_id': 29, 'importance': 8, 'memory_type': 'interest', 'user_id': 8}, {'importance': 8, 'memory_id': 19, 'memory_type': 'interest', 'user_id': 8}, {'memory_id': 32, 'user_id': 8, 'importance': 7, 'memory_type': 'interest'}, {'memory_type': 'project', 'user_id': 8, 'importance': 8, 'memory_id': 31}]]
Distances:
[[0.7492944598197937, 0.7528510689735413, 0.7528510689735413, 0.7566316723823547, 0.7820292711257935]]
🎉 PostgreSQL → ChromaDB 테스트 완료
📴 PostgreSQL 연결 종료
'Agentic AI > Memory' 카테고리의 다른 글
| 11. 장기기억(8) - PostgreSQL의 memories 테이블과 ChromaDB연결 단계(2) (0) | 2026.09.12 |
|---|---|
| 9. 장기기억(6) - 벡터스토어 만들고 테스트하기 (0) | 2026.09.06 |
| 8. 장기기억(5) - ChromaDB 추가로 의미 기반 검색 (0) | 2026.09.06 |
| 7. 장기기억(4)-Memory Layer를 Agent Loop에 연결하기 (0) | 2026.09.06 |
| 6. 장기 메모리(3)(Long-term Memory) - Memory Layer 만들기 (0) | 2026.09.05 |