OpenAI, Anthropic 등 LLM을 도구, 외부 지식, 기억과 결합해 실제 서비스를 만들기 쉽게 해주는 프레임워크
단계별 워크플로우를 제공한다!
대표 기능:
- 문서 기반 질문응답 (RAG)
- 에이전트 기반 도구 사용
- 체인 구성 및 기억 저장
LangChain의 핵심 구성 요소:
| LLMs | OpenAI 등에서 텍스트 생성 |
| PromptTemplates | 입력 프롬프트 구성 |
| Chains | 여러 처리 단계를 연결 |
| Tools | 외부 함수나 API 연결 |
| Agents | 상황에 따라 툴을 사용하는 지능형 LLM |
| Memory | 대화 기록 저장 |
| VectorStore | 문서 검색을 위한 임베딩 저장소 (예: Chroma) |
LangChain 프롬프트 엔지니어링
1. LLM 모델로드
2. 프롬프트 템플릿 생성
3. LLM 모델과 템플릿을 연결(Chains)
4. 사용자 입력을 받아 모델에 입력
5. 모델의 결과를 후처리
요걸 하나의 프로세스로 합쳐주는 것
1. LLM 모델 로드
가장 성능 좋게 활용할 수 있는 건 OpenAI의 GPT 모델
langchain_openai 모듈은 ChatOpenAI 객체를 통해 OpenAI GPT 모델을 쉽게 불러와 Langchain에 연동해 준다.
먼저 OpenAI 모델을 사용하기 위해선 API 키를 사전 등록해주어야 한다.
OpenAI API 활성화 :
OpenAI 사이트에서 회원 가입 및 로그인 절차 진행
계정 설정의 Billing 페이지에서 결제 수단 등록
Dashboard 메뉴의 API Keys 페이지에서 API-Key 생성
생성된 API-Key는 복사하여 보안에 주의하여 보관
from langchain_openai import ChatOpenAI
import os
# API 키 입력
os.environ["OPENAI_API_KEY"] = 'API-KEY'
# 모델 로드
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.0)
2. 프롬프트 템플릿 생성
langchain.prompts 모듈은 PromptTemplate 객체를 제공하여 사용자가 입력한 프롬프트에 적절한 템플릿을 덮어 씌워 모델에 입력할 수 있게 도와준다.
이때 PromptTemplate에 입력되는 문자열 안에 {변수이름}형식으로 수정 가능한 변수를 할당할 수 있다.
from langchain.prompts import PromptTemplate
# 텍스트 요약 템플릿
summary_template = """
당신은 전문 요약가입니다.
아래 주어진 텍스트를 50단어 이내로 간결하게 요약해 주세요.
텍스트:
{text_to_summarize}
요약:
"""
# PromptTemplates 템플릿 구성
summary_prompt = PromptTemplate.from_template(summary_template)
3. LLM 모델과 템플릿을 연결 (Chains)
langchain.chains 모듈의 LLMChain 객체는 사용자 입력을 PromptTemplate로 만들어진 템플릿으로 변환하고 LLM 모델에 입력되는 과정까지 순차적인 연결을 만들어 낸다.
생성된 LLMChain 인스턴스에서 run() 함수 안에 사용자 프롬프트를 인자로 입력하면 체인의 결과로 나온 생성된 텍스트를 반환한다.
from langchain.chains import LLMChain
# LLMChain - PromptTemplate + LLM 결합하여 기본 체인 생성
summary_chain = LLMChain(
llm=llm,
prompt=summary_prompt,
verbose=True
)
# 사용자 프롬프트
text_to_summarize = """\
[데일리안 = 조인영 기자] 우리나라 앱 개발자가 앱 마켓사업자에게서 경험하는 주요 불공정 사례는 심사 지연과 등록 거부이며, 앱 내 결제(인앱결제)의 가장 큰 문제점은 ‘과도한 수수료’라고 인식하고 있는 것으로 나타났다.
방송통신위원회와 한국인터넷진흥원은 11일 '전기통신사업법' 제22조의9(앱 마켓사업자의 의무 및 실태조사)에 따른 ‘2024년도 앱 마켓 실태조사 결과’를 발표했다.
2023년도 국내 ‘앱 마켓’ 규모는 거래액 기준으로 8조1952억원으로 2022년 8조 7598억원 대비 6.4% 감소했다
각 사업자별로 보면, 애플 앱스토어(10.1%)와 삼성전자 갤럭시스토어(6.3%)는 전년 대비 매출이 증가했으며, 구글 플레이(△10.1%)와 원스토어(△21.6%)는 감소했다.
4개 앱 마켓사업자의 거래액 대비 수수료 비중은 약 14~26% 수준이며, 앱 등록 매출의 경우 애플 앱스토어는 약 9.4% 증가했고 구글 플레이는 약 12.9% 감소했다.
또한 국내 앱 마켓에 등록된 전체 앱 수는 전년 대비 0.1% 증가한 531만8182개(각 앱 마켓별 중복 포함), 앱 개발자 수는 전년 대비 0.65% 적은 163만6655명(각 앱 마켓별 중복 포함)으로 나타났다.
분야별 앱 등록 비중은 사진‧도구(26.1%), 라이프스타일(15.6%), 미디어‧출판(14.5%) 관련 앱이 전체의 56.2%를 차지했다.
국내 앱 개발자가 이용하는 앱 마켓은 구글 플레이(96.4%), 애플 앱스토어(71.3%) 순(중복포함)이며, 매출액 비중도 구글 플레이가 67.5%로 가장 높았다. 그 를 애플 앱스토어(28.2%), 원스토어(2.9%), 갤럭시스토어(1.5%)가 따랐다.
앱 개발자가 느끼는 주요 불공정 사례로는 앱 심사지연 경험(애플 앱스토어 6.8%, 구글 플레이 26.2%)이 가장 높았으며, 앱 등록 거부 경험(애플 20%, 구글 3%)과 앱 삭제 경험(구글 8.2%, 애플 3.2%)이 그 뒤를 이었다.
앱 내 결제의 가장 큰 문제점은 ‘과도한 수수료’라고 답한 앱 개발자가 0.4%로 가장 높게 나타났으며, 다음으로 ‘환불 등 수익 정산의 불명확함’(11.6%), ‘결제 수단 선택 제한’(8.9%) 순으로 조사됐다.
앱 개발자가 느낀 앱 최초 등록 과정상의 어려움으로는 ‘심사 기준이 확하지 않음’(구글 플레이 29.8%, 애플 앱스토어 29.6%), ‘질의에 대한 드백 지연’(각각 26.1%, 25.3%) 등이 꼽혔다.
앱을 최초로 등록하기 위해 소요되는 심사기간은 구글 플레이는 등록 시 일 이내(25.6%)에 처리되는 경우가 많았으나, 애플 앱스토어는 6∼7일 이내(42.5%)로 나타났다.
우리나라 국민이 가장 자주 이용하는 앱 마켓은 구글 플레이(67.2%), 애플 스토어(29.7%) 순이었으며, 해당 앱 마켓을 자주 이용하는 이유로는 ‘사용이 편리해서’(67.7%), ‘설치되어 있어서’(61.3%), ‘상품 수가 많아서’(33,5%) 등 으로 나타났다.
"""
# 사용자 프롬프트를 체인에 입력
summary_result = summary_chain.run(text_to_summarize)
print("[요약 결과]")
summary_result
국내 앱 개발자들은 앱 마켓에서 심사 지연과 등록 거부를 주요 불공정 사례로 경험하며, 인앱 결제의 과도한 수수료를 문제로 인식하고 있다. 2023년 앱 마켓 규모는 감소했으며, 구글 플레이와 애플 앱스토어가 가장 많이 사용된다.
요약 결과는 다음과 같이 나온다.
이 외에도 롤 토큰 Chat 템플릿, 메모리 활용, Few-Shot 템플릿 등이 존재한다.
툴 활용과 에이전트
LangChain은 직접 구현한 함수나 외부 기능을 LLM이 적절하게 활용할 수 있게 Tool과 Agent를 제공한다.
툴(Tool)
- 특정 작업(예: 웹 검색, 계산, 외부 API 호출 등)을 수행하기 위한 기능을 캡슐화
- 입력된 파라미터를 받아 정해진 로직대로 처리하고, 그 결과를 반환함으로써 LLM이 직접 할 수 없는 외부 작업을 대신 수행
에이전트(Agent)
- LLM과 여러 툴을 조합해 복잡한 워크플로우를 자동화하고, “언제·어떤 툴을 쓸지” 결정
- 에이전트의 기본 로직(ReAct)
- 사용자 질문을 이해
- 내부적으로 적절한 툴 호출(Action) 계획 수립
- 툴을 실행해 얻은 Observation(결과)을 순차적으로 통합
- 최종 답변(Final Answer)을 생성
툴 함수와 에이전트
랭체인에서 툴 에이전트 활용 위해 다음과 같은 워크플로우를 따름
1. LLM 모델 로드
2. 데코레이터를 활용한 툴 함수 정의 (@tool)
3. 툴 목록을 활용하는 템플릿 작성
4. LLM, 툴 목록, 템플릿을 결합하여 에이전트 생성
5. AgentExecutor 객체로 에이전트 생성자를 만들고 프롬프트 입력
* @tool 데코레이터 함수는 타입을 지정해주는것이 좋습니다
* 템플릿은 에이전트의 형식에 따라 다릅니다
* 에이전트 생성시 에이전트 형식에 맞는 함수 (`create_..._agent`)를 활용해 줍니다
간단한 날짜 연산 함수를 Tool로 만들고 단순 함수 적용 에이전트 create_tool_calling_agent()를 통해 에이전트를 만드는 과정
create_tool_calling_agent() 함수를 통해 에이전트를 만들 때 반드시 템플릿에 agent_scratchpad 변수가 포함되어야 하며, ChatPromptTemplate 객체로 생성된 템플릿이어야 함
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.agents import AgentExecutor, create_tool_calling_agent, tool
from datetime import datetime, timedelta
# LLM 모델 정의
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.0)
# 에이전트용 챗 프롬프트 (input, agent_scratchpad 키 포함)
prompt = ChatPromptTemplate.from_messages(
[
("system", "당신은 다양한 도구를 활용하여 질문에 답변할 수 있습니다."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
]
)
# 툴 함수 정의
@tool
def get_tomorrow_date() -> str:
"""내일의 날짜를 'YYYY-MM-DD' 형식으로 반환합니다.""" # 함수에 설명 문자열 반드시 포함
return (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
# 툴 목록
tools = [get_tomorrow_date]
# 단순 함수 적용 에이전트 생성
agent = create_tool_calling_agent(
llm =llm,
tools=tools,
prompt=prompt,
)
# 에이전트 생성자
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
)
# 실행
result = agent_executor.invoke({"input":"어제의 날짜를 알려줘."})
print(result)
> Entering new AgentExecutor chain...
Invoking: `get_tomorrow_date` with `{}`
2025-05-03어제의 날짜는 2025년 5월 2일입니다.
> Finished chain.
{'input': '어제의 날짜를 알려줘.', 'output': '어제의 날짜는 2025년 5월 2일입니다.'}
ReAct 에이전트
create_react_agent() 함수를 통해 ReAct 에이전트를 만들 수 있다.
이때 템플릿(PromptTemplate)에는 반드시 tools, tool_names, agent_scratchpad 변수가 포함되어야 하며, 템플릿의 형식이 ReAct 형식에 맞게 작성되어야 한다.
항목툴 에이전트 (Tool Agent)ReAct 에이전트 (ReAct Agent)
| 행동 방식 | 한 번에 툴 선택 후 실행 | Reasoning + Acting 반복 |
| LLM 역할 | "어떤 툴을 사용할까?" → 실행 | "생각(thought) → 행동(action) → 관찰(observation)" 반복 |
| 추론능력 | 단순한 프롬프트로 툴 호출 | 중간 사고 단계를 통해 복잡한 문제 해결 |
| 적합한 경우 | 간단한 툴 실행, 검색 | 여러 툴을 조합하거나 복잡한 추론 필요할 때 |
| 사용 프롬프트 구조 | 도구 설명 기반 프롬프트 | "Thought → Action → Observation → Thought ..." 흐름 |
| Agent Type | openai-functions, chat-conversational-react-description 등 다양 | 대표적으로 zero-shot-react-description 사용 |
참 신기한 거 많네잉
생각 -> 행동 -> 피드백 -> 생각 루프를 계속 돈다고 한다.
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.agents import AgentExecutor, create_react_agent, tool
from datetime import datetime, timedelta
# LLM모델 정의
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.0)
# 에이전트용 ReAct 프롬프트 (input, tools, tool_names, agent_scratchpad 키 포함)
template = """다음 질문들에 최선을 다해 답하세요. 다음 도구들을 사용할 수 있습니다:
{tools}
다음 형식을 사용하세요:
Question: 답해야 할 입력 질문
Thought: 무엇을 해야 할지 항상 고민하세요
Action: 수행할 작업, [{tool_names}] 중 하나여야 합니다
Action Input: 작업에 대한 입력
Observation: 작업의 결과
... (위의 Thought/Action/Action Input/Observation 단계는 N번 반복될 수 있습니다)
Thought: 이제 최종 답을 알고 있습니다
Final Answer: 원래 질문에 대한 최종 답변
시작!
Question: {input}
Thought:{agent_scratchpad}"""
prompt = PromptTemplate.from_template(template)
@tool
def get_tomorrow_date() -> str:
"""내일의 날짜를 'YYYY-MM-DD' 형식으로 반환합니다."""
return (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
@tool # 실제 날짜 API를 적용
def get_w(date: str) -> str:
"""입력된 날짜의 날씨를 반환합니다."""
return '맑음'
tools = [get_tomorrow_date, get_w]
# react 형식 에이전트 생성
agent = create_react_agent(
llm =llm,
tools=tools,
prompt=prompt,
)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
)
# 실행
result = agent_executor.invoke({"input":"내일의 날씨를 알려줘."})
print(result)
> Entering new AgentExecutor chain...
내일의 날짜를 알아야 내일의 날씨를 확인할 수 있습니다.
Action: get_tomorrow_date
Action Input: 없음 2025-05-03이제 내일의 날짜인 2025-05-03을 알았으니, 이 날짜의 날씨를 확인해야 합니다.
Action: get_w
Action Input: "2025-05-03" 맑음이제 최종 답을 알고 있습니다.
Final Answer: 내일의 날씨는 맑음입니다.
> Finished chain.
{'input': '내일의 날씨를 알려줘.', 'output': '내일의 날씨는 맑음입니다.'}
웹 서치 툴 활용
Langchain에는 사전 구현된 많은 Tool 객체가 있다. 그 중 검색엔진에 따라 다양한 서치 툴이 존재한다. Bing, Google, SearchAPI 등등 ..
다음 예시는 무료로 사용가능한 DuckDuckgoSearch 툴을 활용하여 웹서치를 기반으로 답변을 제시하는 예시이다.
DuckDuckgoSearch 툴 사용을 위해 모듈을 설치하고 langchain_community.tools의 DuckDuckGoSearchResults를 툴 목록에 넣어 간단한 에이전트를 만들어준다.
!pip install duckduckgo-search
from langchain_community.tools import DuckDuckGoSearchResults
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.agents import AgentExecutor, create_tool_calling_agent, tool
# LLMChain 정의
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.0)
# 에이전트용 챗 프롬프트
prompt = ChatPromptTemplate.from_messages(
[
("system", "당신은 웹검색 도구를 활용하여 질문에 답변할 수 있습니다."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
]
)
# DuckDuckGo 검색 툴 생성
search = DuckDuckGoSearchResults()
# 툴 목록에 입력
tools = [search]
# 에이전트
agent = create_tool_calling_agent(
llm =llm,
tools=tools,
prompt=prompt,
)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
)
# 실행
result = agent_executor.invoke({"input":"최근 멀티헤드 어텐션을 변형한 아키텍처를 찾아줘"})
print(result)
> Entering new AgentExecutor chain...
Invoking: `duckduckgo_results_json` with `{'query': 'recent architectures modified multi-head attention'}`
snippet: In this work, we upgrade the multi-head attention mechanism, the core of the Transformer model, to improve efficiency while maintaining or surpassing the previous accuracy level. We show that multi-head attention can be expressed in the summation form. Drawing on the insight that not all attention heads hold equal significance, we propose Mixture-of-Head attention (MoH), a new architecture ..., title: Title: MoH: Multi-Head Attention as Mixture-of-Head Attention - arXiv.org, link: https://arxiv.org/abs/2410.11842, snippet: Modern large language models (LLMs) often encounter communication bottlenecks on current hardware, rather than purely computational constraints. Multi-head Latent Attention (MLA) tackles this challenge by using low-rank matrices in the key-value (KV) layers, thereby allowing compressed latent KV states to be cached. This approach significantly reduces the KV cache size relative to traditional ..., title: Title: TransMLA: Multi-Head Latent Attention Is All You Need - arXiv.org, link: https://arxiv.org/abs/2502.07864, snippet: Transformers are widely used in various fields such as natural language processing and computer vision. However, the training time for large Transformer models can be challenging due to the Multi-Head Attention (MHA) mechanism. Especially as models become larger, training becomes more costly. So it is crucial to utilize various resources for efficient model training. Currently, NVIDIA Volta ..., title: SparkAttention: high-performance multi-head attention for ... - Springer, link: https://link.springer.com/article/10.1007/s42514-024-00211-0, snippet: Transformer are widely used in various fields such as natural language processing and computer vision. However, the training time for large Transformer models can be challenging due to the Multi-Head Attention (MHA) mechanism. Especially as models become larger, training becomes more costly. So it is crucial to utilize various resources for efficient model training. Currently, NVIDIA Volta GPU ..., title: [2502.12784] SparkAttention: High-Performance Multi-Head Attention for ..., link: https://arxiv.org/abs/2502.12784최근 멀티헤드 어텐션을 변형한 아키텍처에 대한 몇 가지 연구 결과는 다음과 같습니다:
1. **Mixture-of-Head Attention (MoH)**:
- 이 연구에서는 멀티헤드 어텐션 메커니즘을 개선하여 효율성을 높이고 이전의 정확도 수준을 유지하거나 초과하는 방법을 제안합니다. MoH는 모든 어텐션 헤드가 동일한 중요성을 가지지 않는다는 통찰력을 바탕으로 새로운 아키텍처를 제안합니다.
- [논문 링크](https://arxiv.org/abs/2410.11842)
2. **Multi-Head Latent Attention (MLA)**:
- 이 아키텍처는 현재 하드웨어에서의 통신 병목 현상을 해결하기 위해 저랭크 행렬을 키-값(KV) 레이어에 사용하여 압축된 잠재 KV 상태를 캐시할 수 있도록 합니다. 이 접근 방식은 전통적인 방법에 비해 KV 캐시 크기를 크게 줄입니다.
- [논문 링크](https://arxiv.org/abs/2502.07864)
3. **SparkAttention**:
- 이 연구는 대형 Transformer 모델의 훈련 시간을 줄이기 위한 고성능 멀티헤드 어텐션을 제안합니다. 특히 모델이 커질수록 훈련 비용이 증가하는 문제를 해결하기 위해 다양한 자원을 효율적으로 활용하는 방법을 모색합니다.
- [논문 링크](https://arxiv.org/abs/2502.12784)
이 연구들은 멀티헤드 어텐션의 효율성을 높이고 훈련 시간을 단축시키기 위한 다양한 접근 방식을 제안하고 있습니다.
> Finished chain.
{'input': '최근 멀티헤드 어텐션을 변형한 아키텍처를 찾아줘', 'output': '최근 멀티헤드 어텐션을 변형한 아키텍처에 대한 몇 가지 연구 결과는 다음과 같습니다:\n\n1. **Mixture-of-Head Attention (MoH)**:\n - 이 연구에서는 멀티헤드 어텐션 메커니즘을 개선하여 효율성을 높이고 이전의 정확도 수준을 유지하거나 초과하는 방법을 제안합니다. MoH는 모든 어텐션 헤드가 동일한 중요성을 가지지 않는다는 통찰력을 바탕으로 새로운 아키텍처를 제안합니다.\n - [논문 링크](https://arxiv.org/abs/2410.11842)\n\n2. **Multi-Head Latent Attention (MLA)**:\n - 이 아키텍처는 현재 하드웨어에서의 통신 병목 현상을 해결하기 위해 저랭크 행렬을 키-값(KV) 레이어에 사용하여 압축된 잠재 KV 상태를 캐시할 수 있도록 합니다. 이 접근 방식은 전통적인 방법에 비해 KV 캐시 크기를 크게 줄입니다.\n - [논문 링크](https://arxiv.org/abs/2502.07864)\n\n3. **SparkAttention**:\n - 이 연구는 대형 Transformer 모델의 훈련 시간을 줄이기 위한 고성능 멀티헤드 어텐션을 제안합니다. 특히 모델이 커질수록 훈련 비용이 증가하는 문제를 해결하기 위해 다양한 자원을 효율적으로 활용하는 방법을 모색합니다.\n - [논문 링크](https://arxiv.org/abs/2502.12784)\n\n이 연구들은 멀티헤드 어텐션의 효율성을 높이고 훈련 시간을 단축시키기 위한 다양한 접근 방식을 제안하고 있습니다.'}
이 외에도 ArXiv (논문 서치) 등의 툴을 활용할 수 있다.
'자연어 공부' 카테고리의 다른 글
| RAG 개념과 실전 예제 (0) | 2025.05.07 |
|---|---|
| BERT 간단한 개념 정리 - 동작, 구조 (1) | 2025.04.16 |