Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
Tags
- kafka
- producer
- orelse
- SpringBoot
- JWT
- 패스트캠퍼스 #환급챌린지 #패스트캠퍼스후기 #습관형성 #직장인자기계발 #오공완
- Functional Programming
- effective java
- Java8
- git cli
- 카프카
- signWith
- Clean Code
- Java
- 싱글톤
- orElseGet
- Factory Method Pattern
- junit5
- Stream
- optional
- 인텔리제이 단축키
- Spring Security
- consumer
- 함수형 프로그래밍
- TDD
- topic
- mokito
- Authentication
- #패스트캠퍼스 #환급챌린지 #패스트캠퍼스후기 #습관형성 #직장인자기계발 #오공완
- 디자인패턴
Archives
- Today
- Total
goodbye
패스트캠퍼스 환급챌린지 28일차 : 테디노트의 RAG 비법노트 강의 후기 본문
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다
https://fastcampus.info/4n8ztzq
(~6/20) 50일의 기적 AI 환급반💫 | 패스트캠퍼스
초간단 미션! 하루 20분 공부하고 수강료 전액 환급에 AI 스킬 장착까지!
fastcampus.co.kr
패스트캠퍼스 환급챌린지 28일차!
1) 공부 시작 시간 인증

2) 공부 종료 시간 인증

3) 강의 수강 클립 인증

4) 학습 인증샷

5) 학습 통계

Today I Learned
에이전트 대화 시뮬레이션(고객 응대 시나리오)
- 챗봇을 구축할 때, 고객 지원 어시스턴트와 같은 경우, 챗봇의 성능을 제대로 평가하는 것이 어려울 수 있습니다.
- 코드 변경마다 집중적으로 수동으로 상호 작용하는 것은 시간이 많이 소요됩니다.
- 평가 과정을 더 쉽고 재현 가능하게 만드는 한 가지 방법은 사용자 상호 작용을 시뮬레이션하는 것 입니다.
- LangGraph를 사용하면 이를 설정하는 것이 쉽습니다.
- 아래는 대화를 시뮬레이션하기 위해 "가상 사용자(Simulated User)"를 생성하는 방법의 예시입니다.
from langgraph.graph.message import add_messages
from typing import Annotated
from typing_extensions import TypedDict
# State 정의
class State(TypedDict):
messages: Annotated[list, add_messages] # 사용자 - 상담사 간의 대화 메시지
상담사, 고객 역할 정의
상담사 역할 정의
시뮬레이션에서 상담사 역할을 하는 챗봇을 정의합니다.
- call_chatbot 내의 구현은 설정 가능하며, 내부에서 사용한 모델을 Agent 로 변경하는 것도 가능합니다.
- call_chatbot 은 사용자로부터 메시지를 입력으로 받아, 고객을 상담하는 역할을 부여하겠습니다.
고객 지원 시나리오에서의 대화 응답 생성에 활용될 수 있습니다.
from typing import List
from langchain_teddynote.models import LLMs, get_model_name
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, AIMessage, BaseMessage
from langchain_core.output_parsers import StrOutputParser
# 모델 이름 설정
MODEL_NAME = get_model_name(LLMs.GPT4)
def call_chatbot(messages: List[BaseMessage]) -> dict:
# LangChain ChatOpenAI 모델을 Agent 로 변경할 수 있습니다.
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"You are a customer support agent for an airline. Answer in Korean.",
),
MessagesPlaceholder(variable_name="messages"),
]
)
model = ChatOpenAI(model=MODEL_NAME, temperature=0.6)
chain = prompt | model | StrOutputParser()
return chain.invoke({"messages": messages})
# 사용자의 입력을 받아 챗봇의 응답 처리
call_chatbot([("user", "안녕하세요?")])
고객 역할(Simulated User) 정의
- 이제 시뮬레이션된 고객의 역할을 정의합니다.
- 고객 지원 시나리오에서의 대화를 시뮬레이션합니다.
- 시스템 프롬프트는 고객과 고객 지원 담당자 간의 상호작용을 설정하며,
- 사용자 지시사항을 통해 시나리오의 세부 사항을 제공합니다.
- 이 구성은 특정 사용자 요구(예: 환불 요청)에 대한 모델의 반응을 시뮬레이션하는 데 사용됩니다.
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai import ChatOpenAI
def create_scenario(name: str, instructions: str):
# 시스템 프롬프트를 정의: 필요에 따라 변경
system_prompt_template = """You are a customer of an airline company. \\
You are interacting with a user who is a customer support person. \\
Your name is {name}.
# Instructions:
{instructions}
[IMPORTANT]
- When you are finished with the conversation, respond with a single word 'FINISHED'
- You must speak in Korean."""
# 대화 메시지와 시스템 프롬프트를 결합하여 채팅 프롬프트 템플릿을 생성합니다.
prompt = ChatPromptTemplate.from_messages(
[
("system", system_prompt_template),
MessagesPlaceholder(variable_name="messages"),
]
)
# 특정 사용자 이름과 지시사항을 사용하여 프롬프트를 부분적으로 채웁니다.
prompt = prompt.partial(name=name, instructions=instructions)
return prompt
- 가상의 시나리오를 생성합니다.
- 이 가상의 시나리오는 고객의 입장에서의 시나리오입니다.
- 여기서는 환불을 요청하는 시나리오를 정의합니다.
from langchain_core.messages import HumanMessage
# 사용자 지시사항을 정의합니다.
instructions = """You are trying to get a refund for the trip you took to Jeju Island. \\
You want them to give you ALL the money back. This trip happened last year."""
# 사용자 이름을 정의합니다.
name = "Wook"
create_scenario(name, instructions).pretty_print()
# OpenAI 챗봇 모델을 초기화합니다.
model = ChatOpenAI(model=MODEL_NAME, temperature=0.6)
# 시뮬레이션된 사용자 대화를 생성합니다.
simulated_user = create_scenario(name, instructions) | model | StrOutputParser()
# 시뮬레이션된 사용자에게 메시지를 전달(상담사 -> 고객)
messages = [HumanMessage(content="안녕하세요? 어떻게 도와 드릴까요?")]
simulated_user.invoke({"messages": messages})
에이전트 시뮬레이션 정의하기
아래의 코드는 시뮬레이션을 실행하기 위한 LangGraph 워크플로우를 생성합니다.
주요 구성 요소는 다음과 같습니다:
- 시뮬레이션된 사용자와 챗봇을 위한 두 개의 노드입니다.
- 조건부 정지 기준을 가진 그래프 자체입니다.
노드 정의
- 그래프에서 노드를 정의합니다.
- 이들은 메시지 목록을 입력으로 받아 상태에 추가할 메시지 목록을 반환해야 합니다.
- 이것들은 위에 있는 챗봇과 시뮬레이션된 사용자를 둘러싼 것 래퍼들입니다.
- 여기서 까다로운 점은 어떤 메시지가 어떤 것인지 구분하는 것입니다.
- 챗봇과 시뮬레이션된 사용자 모두 LLMs이기 때문에, 둘 다 AI 메시지로 응답할 것입니다.
- 우리의 상태는 인간과 AI 메시지가 번갈아 가며 나열된 목록이 될 것입니다.
- 이는 노드 중 하나에서 AI와 인간 역할을 바꾸는 논리가 필요함을 의미합니다.
- HumanMessages가 시뮬레이션된 사용자로부터 온 메시지라고 가정할 것입니다.
- 이는 시뮬레이션된 사용자 노드에 AI와 Human 메시지를 교환하는 논리가 필요함을 의미합니다.
from langchain_core.messages import AIMessage
# 상담사 역할
def ai_assistant_node(messages):
# 상담사 응답 호출
ai_response = call_chatbot(messages)
# AI 상담사의 응답을 반환
return {"messages": [("assistant", ai_response)]}
ai_assistant_node(
[
("user", "안녕하세요?"),
("assistant", "안녕하세요! 어떻게 도와드릴까요?"),
("user", "환불 어떻게 하나요?"),
]
)
- 다음으로, 우리의 시뮬레이션된 사용자를 위한 노드를 정의
- 과정에서는 메시지의 역할을 교체하는 작은 로직이 포함=
def _swap_roles(messages):
# 메시지의 역할을 교환: 시뮬레이션 사용자 단계에서 메시지 타입을 AI -> Human, Human -> AI 로 교환합니다.
new_messages = []
for m in messages:
if isinstance(m, AIMessage):
# AIMessage 인 경우, HumanMessage 로 변환합니다.
new_messages.append(HumanMessage(content=m.content))
else:
# HumanMessage 인 경우, AIMessage 로 변환합니다.
new_messages.append(AIMessage(content=m.content))
return new_messages
# 상담사 역할(AI Assistant) 노드 정의
def ai_assistant_node(state: State):
# 상담사 응답 호출
ai_response = call_chatbot(state["messages"])
# AI 상담사의 응답을 반환
return {"messages": [("assistant", ai_response)]}
# 시뮬레이션된 사용자(Simulated User) 노드 정의
def simulated_user_node(state: State):
# 메시지 타입을 교환: AI -> Human, Human -> AI
new_messages = _swap_roles(state["messages"])
# 시뮬레이션된 사용자를 호출
response = simulated_user.invoke({"messages": new_messages})
return {"messages": [("user", response)]}
엣지 정의
- 주된 로직은 시뮬레이션된 사용자가 작업을 마친 후 발생하며, 두 가지 결과 중 하나로 이어져야 합니다:
- 고객 지원 봇을 호출하여 계속 진행("continue")
- 대화를 마치고 종료("end")
- 우리는 이를 인간 챗봇이 FINISHED로 응답하거나(시스템 프롬프트 참조)
- 대화가 6개( 임의의 숫자) 메시지를 초과하는 경우로 정의할 것입니다
- should_continue 함수는 메시지 리스트를 인자로 받아,
- 리스트의 길이가 6을 초과하거나 마지막 메시지의 내용이 'FINISHED'일 경우 'end'를 반환합니다.
- 그렇지 않으면 'continue'를 반환하여 처리를 계속하도록 합니다.
def should_continue(state: State):
# 메시지 리스트의 길이가 6보다 크면 'end'를 반환합니다.
if len(state["messages"]) > 6:
return "end"
# 마지막 메시지의 내용이 'FINISHED'라면 'end'를 반환합니다.
elif state["messages"][-1].content == "FINISHED":
return "end"
# 위의 조건에 해당하지 않으면 'continue'를 반환합니다.
else:
return "continue"
그래프 정의
- 이제 시뮬레이션을 설정하는 그래프를 정의합니다.
- MessageGraph 클래스는 챗봇과 시뮬레이션된 사용자 간의 상호작용을 구성하고 시뮬레이션하는 데 사용됩니다.
from langgraph.graph import END, StateGraph
from langchain_teddynote.graphs import visualize_graph
# StateGraph 인스턴스 생성
graph_builder = StateGraph(State)
# 노드 정의
graph_builder.add_node("simulated_user", simulated_user_node)
graph_builder.add_node("ai_assistant", ai_assistant_node)
# 엣지 정의 (챗봇 -> 시뮬레이션된 사용자)
graph_builder.add_edge("ai_assistant", "simulated_user")
# 조건부 엣지 정의
graph_builder.add_conditional_edges(
"simulated_user",
should_continue,
{
"end": END, # 종료 조건이 충족되면 시뮬레이션을 중단
"continue": "ai_assistant", # 종료 조건이 충족되지 않으면 상담사 역할 노드로 메시지를 전달
},
)
# 시작점 설정
graph_builder.set_entry_point("ai_assistant")
# 그래프 컴파일
simulation = graph_builder.compile()
visualize_graph(simulation)
시뮬레이션 시작
- 이제 우리의 챗봇을 평가할 수 있습니다!
- 빈 메시지로 호출할 수 있습니다
- 이것은 챗봇이 초기 대화를 시작하게 하는 것을 시뮬레이션합니다
- 시뮬레이션에서 스트리밍되는 데이터 청크를 순회하며
- 최종 종료 청크(END)를 제외한 모든 이벤트를 출력합니다.
from langchain_core.runnables import RunnableConfig
# config 설정(재귀 최대 횟수, thread_id)
config = RunnableConfig(recursion_limit=10, configurable={"thread_id": random_uuid()})
# 입력 메시지 설정
inputs = {
"messages": [HumanMessage(content="안녕하세요? 저 지금 좀 화가 많이 났습니다^^")]
}
# 그래프 스트리밍
stream_graph(simulation, inputs, config, node_names=["simulated_user", "ai_assistant"])
'Lecture > 패스트캠퍼스' 카테고리의 다른 글
| 패스트캠퍼스 환급챌린지 30일차 : 테디노트의 RAG 비법노트 강의 후기 (3) | 2025.07.30 |
|---|---|
| 패스트캠퍼스 환급챌린지 29일차 : 테디노트의 RAG 비법노트 강의 후기 (3) | 2025.07.29 |
| 패스트캠퍼스 환급챌린지 27일차 : 테디노트의 RAG 비법노트 강의 후기 (3) | 2025.07.27 |
| 패스트캠퍼스 환급챌린지 26일차 : 테디노트의 RAG 비법노트 강의 후기 (3) | 2025.07.26 |
| 패스트캠퍼스 환급챌린지 25일차 : 테디노트의 RAG 비법노트 강의 후기 (2) | 2025.07.25 |
Comments