📚 Agentic AI - 기업용 자율 에이전트 개발 7장 · 기억하는 에이전트 Agentic AI란

정리 & 체크리스트

한 줄 요약

에이전트 네 종류에 기억까지 붙였습니다. 재료가 다 모였습니다. 8장에서 하나의 팀으로 묶습니다.


1. 7장에서 만든 것

code/ch07_memory.py기억하는 에이전트

만든 것 하는 일
State 상태 정의 — messages + add_messages
counselor(state) 노드 — 대화 전체를 모델에 넘기고 답을 돌려줌
graph / chatbot START → counselor → END 를 조립·컴파일
say(text, thread_id) 단순 챗봇 호출
analyst_with_memory 5장 에이전트 + checkpointer 한 줄
ask_analyst(text, thread_id) 멀티턴 CSV 분석

2. 이 장의 핵심 내용 — 말로 설명할 수 있어야 할 것들

  1. LangGraph는 프로그램을 "상태를 들고 노드 사이를 이동하는 그래프"로 본다.
  2. 상태는 딕셔너리, 노드는 함수, 엣지는 화살표다.
  3. Annotated[list, add_messages] 는 "덮어쓰지 말고 이어 붙여라"를 뜻한다. 2장의 history.append(...) 를 대신한다.
  4. 리듀서를 안 붙이면 덮어쓴다. 8장에서 둘 다 쓴다.
  5. 노드는 바뀐 부분만 돌려준다. (전체를 돌려줘도 add_messagesid 로 걸러 결과는 같지만, 리듀서가 하는 일이 가려지고 복사 비용이 붙는다.)
  6. compile(checkpointer=...) 한 줄로 기억이 생긴다. 저장은 노드가 끝날 때마다 일어난다.
  7. 우리는 이번 말 하나만 넣고, 체크포인터가 앞의 것을 붙여 준다.
  8. InMemorySaver 는 프로그램을 끄면 사라진다. 저장 위치를 바꾸려면 이 한 줄만 바꾼다.
  9. create_agent 도 StateGraph 다. 그래서 checkpointer 인자를 그대로 받는다.
  10. thread_id 는 "어느 서랍인가"를 가리킨다. 같은 질문이라도 서랍이 다르면 다른 답이 나온다.
  11. 체크포인터와 thread_id 는 짝이다. 하나만 있으면 동작하지 않는다.
  12. 길이 관리는 여전히 사람의 일이다. 자르기·요약·thread_id 교체 중에 고른다.
  13. 대화가 섞이는 사고는 오류 없이 조용히 일어나고, 그것은 개인정보 사고다. 그래서 검증한다.

3. 체크리스트

  • [ ] python code/ch07_memory.py 가 끝까지 돌아간다
  • [ ] [1] 에서 앞말을 기억하는 것을 확인했다
  • [ ] [2] 에서 thread_id 를 바꾸면 기억이 없는 것을 확인했다
  • [ ] [3] 에서 "그거" 가 통하는 것을 확인했다
  • [ ] get_state() 로 쌓인 메시지를 직접 봤다
  • [ ] add_messages 를 빼면 어떻게 되는지 직접 해 봤다
  • [ ] 두 손님이 번갈아 대화해도 섞이지 않는 것을 코드로 검증했다

4. 지금까지 만든 것 전부

[에이전트 네 종류]
  ✓ ① 사내 데이터 조회    3장   ch03_order_agent.py
  ✓ ② 웹검색             4장   ch04_web_agent.py
  ✓ ③ CSV 데이터분석      5장   ch05_csv_agent.py
  ✓ ④ RAG 문서검색        6장   ch06_rag_agent.py

[기억]
  ✓ LangGraph StateGraph  7장   ch07_memory.py

[남은 것]
  □ 팀으로 묶기            8장   ch08_multi_agent.py

재료가 전부 갖춰졌습니다.


5. 8장 예고 — 한 종류로는 답이 안 나오는 질문

"승승 스마트워치 Fit 5(P0003), 지금 어떻게 대응해야 할까요?"

지금까지 만든 에이전트에게 하나씩 질문해 보면 이렇습니다.

에이전트 답할 수 있는 것 여기서 멈춘다
CSV 분석 재고 3개, 평점 3.8, 5월 판매 12개 "평점이 낮네"
RAG 문서검색 배터리 일반 7일 / GPS 18시간 "사양은 정상인데?"
웹검색 시장에서 배터리가 경쟁 요소 "그래서 뭘 하라고?"

셋을 나란히 놓아야 판단이 나옵니다.

리뷰 불만: "GPS를 켜면 하루도 못 갑니다. 일주일 간다는 설명과 너무 달라요"   (CSV)
매뉴얼   : 일반 7일 / GPS 18시간                                          (RAG)
          ↓
제품은 사양대로 동작한다. 고객은 "일주일"만 보고 샀다.
          ↓
결함이 아니라 표기 문제다 → 상세페이지에 GPS 18시간을 명시하라

이 판단은 한 종류만으로는 절대 안 나옵니다.


6. 어떻게 묶을까 — 두 갈래

방법이 둘 있습니다. 8장에서 둘 다 살펴보고 하나를 고릅니다.

① 한 명에게 도구를 다 준다

아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.

agent = create_agent(llm, tools=[order_tool, run_pandas, policy_tool, search_web], ...)

간단합니다. 그런데 4장 4절에서 본 문제가 생깁니다 — 도구가 많아지면 무엇을 쓸지 헷갈립니다. 그리고 어디서 틀렸는지 찾기 어렵습니다.

② 나눠서 맡긴다 — Planner–Worker

팀장 (플래너)누구에게 무엇을 물을지 계획만 세운다 · 도구가 없다주문담당get_order_status 하나만3장데이터분석가run_pandas 하나만5장규정담당policy_search 하나만6장시장조사원search_web 하나만4장종합 (synthesis)보고를 모아 하나의 판단으로담당자마다 도구를 하나씩 사용합니다. 도구 선택지를 줄이면 잘못 고를 가능성도 줄어듭니다.
8장 예고 — 팀장 하나에 담당 넷, 각자 도구는 하나씩

각 담당은 도구가 하나뿐이라 고민할 게 없습니다. 그리고 "규정담당이 잘못 보고했다"고 짚을 수 있습니다.

왜 Planner–Worker 라고 부르나계획을 세우는 쪽(Planner, 플래너)일을 하는 쪽(Worker, 워커) 을 나눠 놓았다고 해서 이렇게 부릅니다. 멀티에이전트 구성 방식 중 하나의 정식 이름이라 검색하면 자료가 나옵니다. 8장 내내 이 이름을 씁니다 — 한국어로는 "팀장–담당 방식" 이라고 읽으면 됩니다.

8장은 ②로 갑니다.


7. 그리고 이번 장이 얹힙니다

8장의 그래프도 체크포인터를 붙입니다.

아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.

team = graph.compile(checkpointer=InMemorySaver())

그래서 이렇게 됩니다.

질문 1: "승승 스마트워치 Fit 5(P0003), 지금 어떻게 대응해야 할까요?"
        → 계획: 데이터분석가 + 규정담당 + 시장조사원
        → 종합 답변

질문 2: "그 상품을 산 주문 O001203은 어떤 상태인가요? 재주문 기준을 채우려면 몇 개?"
        → "그 상품"이 통한다 (7장)
        → 계획: 주문담당 + 데이터분석가
        → "배송완료 상태이고, 27개를 발주해야 합니다"

계획은 실행할 때마다 조금씩 달라집니다. 위는 한 번 돌린 예입니다.

계획이 질문에 따라 달라지고, 앞 대화를 기억합니다. 멀티에이전트와 멀티턴이 함께 동작하는 것이죠.

이번 장의 State · add_messages · checkpointer · thread_id 가 그대로 쓰입니다. 다만 노드가 하나에서 셋(계획 → 실행 → 종합) 으로 늘어납니다.

← 이전 절08. 따라하기 세션이 섞이지 않는지 검증하기