YYYEJI

[MAC] LangChain 주요 컴포넌트 파해치기 본문

인공지능 챗봇

[MAC] LangChain 주요 컴포넌트 파해치기

YEJI ⍢ 2025. 8. 1. 16:56
728x90

안녕하세요! 송로지입니다 🌷

 

 

어제 LangChain 개념을 업로드하고

 

LangChain 주요 개념 알아보기

LangChain이 도대체 무엇인고하니 ,, !! LLM(Large Language Model) 기반 앱 개발을 위한 프레임워크라네요.이렇게 들었을 땐 어려운데 어떻게 쉽게 설명할 수 있을까요...? 흠.................AI 앱을 만들 때 필

yyyeji.tistory.com

오늘은 코드를 함 파해쳐보려고 합니다!! 🤩

 

 


1 모델(Models)

모델은 LLM, ChatModel 등으로 구분을 하고 

OpenAI, Anthropic, Google 등에서 다양한 모델을 지원합니다.

 

 

모델을 통해 텍스트 생성, 대화, 요약 등의 작업을 쉽게 수행할 수 있어요!!

model = AzureChatOpenAI(model='gpt-4o-mini')
response = model.invoke("안녕하세요?")

 

모델을 AzureChatOpenAI() 함수를 통해 정의해주고,

invoke(호출) 함수 안에 유저 메세지("안녕하세요?")를 보내시면 

응답을 쉽게 받아보실 수 있어요!!

 

 

print("Answer:", response.content)

response만 출력하면 모든 데이터들이 나오기 때문에 

content를 사용하면 유저 메세지의 답변만 받아보실 수 있습니다 ㅎㅎ

 

 

메타 데이터가 궁금하시다면?

response.response_metadata를 사용하시면 돼요!!

 

 


2. 메세지(Messages)

Chat model에서 사용할 수 있는 통합된 메세지 형식을 제공합니다!

각 모델 제공자의 특정 메세지 형식을 신경 쓰지 않고도 다양한 채팅 모델을 활용할 수 있어요~

 

 

* HumanMessage

휴먼메세지는 사용자 역할에 해당합니다

즉, 사용자의 입력을 처리해요!

human_message = HumanMessage(content='Glory를 한국어로 번역해 주세요.')
response = model.invoke([human_message])

유저 메세지를 생성해준 뒤 번역을 요청하게 되는 코드입니다.

여기서 주의할 점은! invoke() 함수 안에 있는 메세지가 리스트 타입임을 명시해주기 위해 []를 사용하셔야 돼요!!

 

 

print("Answer: ", response.content)

Glory의 한국어 뜻이 잘 출력되었습니다!

 

 

* AIMessage

AI 모델의 응답 즉, response에 담긴 응답들을 의미합니다.

response_1 = model.invoke("Glory를 한국어로 번역해주세요.")
response_2 = model.invoke([human_massage])

response_1, response_2가 AIMessage입니다.

 

 

여기서 아래 코드를 통해 토큰 사용량을 출력할 수 있는데 

response_1.usage_metadata
response_2.usage_metadata

이 부분은 비용과 관련된 부분이기 때문에 잘 확인하셔야 됩니다!!

 

 

 * SystemMessage

시스템 메세지는 시스템 역할에 해당하는데,

AI 모델의 동작과 제약사항을 정의하는데 사용해요!

system_message = SystemMessage(content="당신은 영어를 한국어로 번연하는 AI 어시스턴트입니다.")

위에 코드를 통해 AI에게 정체성을 부여하고

 

 

human_message = HumanMessage(content="Glory")
messages = [system_message, human_message]
response = model.invoke(messages)

휴먼 메시지에는 Glory만 content로 넣었고

system, human 메세지를 리스트로 묶어준 후 

invoke() 호출을 해주면 됩니다.

 

print("Answer: ", response.content)

AI에게 정체성을 부여하고 휴먼 메세지에 Glory만 입력했음에도 답변을 받아볼 수 있었습니다.

 


3. 프롬프트 템플릿(Prompt Template)

프롬프트 템플릿을 통해 일관된 입력 형식을 제공할 수 있습니다.

- 사용자의 입력과 파라미터를 언어 모델이 이해할 수 있는 형태로 변환하는 도구이며,

- 언어 모델에게 전달할 지시문을 만드는 틀입니다.

 

변수를 포함한 동적 프롬프트 생성이 가능합니다.

- 모든 템플릿은 딕셔너리 형태의 입력을 받아서 처리하며,

- 출력은 PromptValue 형태로 반환되며, 이는 문자열이나 메세지 리스트로 변환이 가능합니다~~

 

 

템플릿 사용의 장점은

- 결과를 예측 가능

- Cache 절약

할 수 있습니다!!

 

 

* 문자열 프롬프트 템플릿(String PromptTemplate)

가장 기본적인 형태이며, 단일 문자열을 형식화하는데 사용합니다. 

template = PromptTemplate.from_template("{주제}에 대해 이야기를 해줘")
prompt = template.invoke({"주제":"고양이"})
prompt

 

 

 

* 채팅 프롬프트 템플릿 (ChatPromptTemplate)

여러 메세지를 포함하는 대화형 템플릿을 만들 때 사용합니다!

 

 

template = ChatPromptTemplate.from_messages([
	("system", "당신은 도움이 되는 비서입니다.")
    ("user", "{subject}에 대해 설명해 주세요")
])

prompt = template.invoke({"subject" : "인공지능"})

이 AI는 도움이 되는 비서이며, 

인공지능에 대해 설명하게 됩니다!

 

 


4. 출력 파서(Output Parser)

출력 파서

1) 모델의 텍스트 출력을 구조화된 데이터로 변환

2) 채팅 모델과 LLM 출력을 정규화

3) 다운스트림 작업을 위한 데이터 형식 변환

을 합니다!

 

 

 

우선 코드를 살펴볼게요!

# 기본적인 문자열 파서 사용
parser = StrOutputParser()

# 프롬프트 템플릿 설정
prompt = PromptTemplate.from_template("도시 {city}의 특징을 알려주세요")

# 모델 정의
model = AzureChatOpenAI(model='gpt-4o-mini')

# 체인 구성 (바로 실행 X, 묶어 놓기만 함)
chain = prompt | model | parser

# 체인 실행 (invoke 명령 들어오면 실행)
result = chain.invoke({"city":"서울"})


# 결과 출력
print(result)

문자열 파서, 프롬프트 템플릿을 하나씩 생성해주고

모델을 'gpt-4o-mini'로 정의해줬습니다

 

 

chain 코드가 중요한데 !! ⭐️

prompt는 유저메세지 즉 쿼리를 의미하고

(유저가 입력하는 질문이나 메세지)

model은 어떤 모델을 사용할지

(입력을 처리할 LLM)

parser은 우리에게 돌아오는 답변을 의미합니다.

(모델이 생성한 raw한 응답을 우리가 원하는 형태로 변환해주는 역할)

 

 

여기서 chain이 !! ⭐️

Prompt → Model → Parser 흐름이 체인처럼 이어져 있는 

그 LangChain을 의미합니다!!

 

 

print(result)를 출력하면

서울의 특징을 잘 받아볼 수 있어요!!

 

 


5. 메모리(Memory)

대화 기록을 저장하고 관리합니다!

 

 


6. 에이전트(Agent)

자율적 의사결정이 가능한 실행 단위라고 합니다!

LangChain에서는 Agent 클래스를 통해 에이전트를 구현한다고 해요!

 

 

전체 코드는 아래와 같고,

# 프롬프트 템플릿 생성 - ReAct 에이전트에 필요한 변수들 포함
prompt = ChatPromptTemplate.from_messages([
    ("system", "당신은 친절한 수학 선생님입니다."),
    ("user", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad")
])

# 도구 정의
@tool
def add(a: float, b: float) -> float:
    """두 숫자를 더하는 도구"""
    return a + b

@tool
def subtract(a: float, b: float) -> float:
    """두 숫자를 빼는 도구"""
    return a - b

# 도구 목록 생성
tools = [
    add,
    subtract
]

# 에이전트 생성 (도구 호출)
agent = create_tool_calling_agent(
    llm=AzureChatOpenAI(model='gpt-4o-mini'),
    tools=tools,
    prompt=prompt
)

# 에이전트 실행 도구 정의
agent_executor = AgentExecutor(
    agent=agent,      # 도구 호출 에이전트
    tools=tools,      # 도구 목록
    verbose=True,     # 상세 로그 출력
    )

# 에이전트 실행
agent_executor.invoke({"input": "100과 200을 더하면 얼마인가요?"}) # LLM이 판단 -> @tool 호출 -> add() 실행

코드를 하나씩 살펴볼게요!

 

 

prompt = ChatPromptTemplate.from_messages([
    ("system", "당신은 친절한 수학 선생님입니다."),
    ("user", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad")
])

system: AI 역할을 정의하는데 수학 선생님으로 설정했고

user: 유저가 질문하는 쿼리이고

agent_scratchpad: 에이전트가 도구를 사용하면서 생긴 내부 기록을 넣는 자리에요!

 

 

@tool
def add(a: float, b: float) -> float:
    return a + b

@tool
def subtract(a: float, b: float) -> float:
    return a - b

@tool 데코레이터를 사용하면서 LangChain에 등록 가능한 도구가 되고,

이 함수들은 LLM이 직접 호출할 수 있는 계산기 도구에요!

 

 

tools = [add, subtract]

사용할 도구들을 리스트로 정리해서 에이전트에 넘겨주고

 

 

도구 호출을 하는 에이전트를 생성합니다.

agent = create_tool_calling_agent(
    llm=AzureChatOpenAI(model='gpt-4o-mini'),
    tools=tools,
    prompt=prompt
)

create_tool_calling_agent() 함수를 통해 Agent를 생성합니다!!

이 Agent는 질문을 이해하고, 어떤 도구를 쓸지 스스로 판단하게 돼요

 

 

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
)

agent_executor가 실제로 LLM 에이전트를 실행시키는 역할을 합니다

(verbose=True를 사용하면 실행 과정을 상세히 출력해줘서 디버깅에 도움이 돼요!)

 

 

에이전트가 사용자의 질문을 해석해서 

add(100, 200)을 호출하고

결과로 300을 반환합니다!!

 

 

이 코드들의 핵심 포인트는! ⭐️

Prompt → Agent에게 역할과 입력을 알려주고

Tool(@tool) → LLM이 직접 호출할 수 있는 함수 정의

Agent → LLM + Prompt + Tools 조합으로, 스스로 판단하고 도구 호출

AgentExecutor → Agent를 실행시키는 컨트롤러 역할을 하게 됩니다.

 

 

 

주요 컴포넌트를 파헤쳐봤는데 어떠신가요 🤣

모두들 이해가 잘 되었길 바랍니다 🙏🏻

728x90