Skip to main content
Summary

먼저 작은 성공을 만든다

랭체인을 처음 배울 때 가장 중요한 일은 거창한 챗봇을 바로 만드는 것이 아니다. 먼저 "내 컴퓨터에서 모델을 호출하고 응답을 받는 것"을 성공시켜야 한다. 이 작은 성공이 있어야 이후 프롬프트, 체인, RAG, 도구 호출을 안정적으로 쌓아 올릴 수 있다.

이번 장에서는 다음 흐름을 만든다.

  1. Python 가상환경을 만든다.

  2. LangChain과 모델 제공자 패키지를 설치한다.

  3. API 키를 코드 밖에서 관리한다.

  4. 채팅 모델에 메시지를 보내 응답을 받는다.

  5. 간단한 터미널 대화 앱을 만든다.

LangChain Python은 Python 3.10 이상을 요구한다. 또한 최근 LangChain은 핵심 패키지와 모델 제공자별 통합 패키지를 나누어 설치하는 방식을 사용한다. 예를 들어 OpenAI 모델을 쓰려면 langchain과 함께 langchain-openai를 설치한다.1

개발 환경 준비와 첫 번째 랭체인 앱AI 생성 이미지

프로젝트 폴더와 가상환경 만들기

먼저 작업 폴더를 만든다.

mkdir langchain-first-app
cd langchain-first-app

가상환경을 만든다. 가상환경은 이 프로젝트에서만 사용할 Python 패키지를 분리해 두는 공간이다. 프로젝트마다 필요한 패키지 버전이 다를 수 있으므로, 초보자라도 가상환경을 기본 습관으로 두는 편이 좋다.

macOS 또는 Linux에서는 다음과 같이 실행한다.

python3 -m venv .venv
source .venv/bin/activate

Windows PowerShell에서는 다음과 같이 실행한다.

python -m venv .venv
..venvScriptsActivate.ps1

터미널 앞에 (.venv)가 보이면 가상환경이 활성화된 것이다. Windows에서 스크립트 실행 정책 때문에 활성화 명령이 막히는 경우가 있다. 그럴 때는 PowerShell을 관리자 권한으로 열기보다, 먼저 현재 사용자 범위에서 실행 정책을 조정할 수 있는지 확인하는 편이 안전하다.

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

이제 필요한 패키지를 설치한다.

pip install -U langchain langchain-openai python-dotenv

각 패키지의 역할은 다음과 같다.

  • langchain: LangChain의 기본 기능을 제공한다.

  • langchain-openai: OpenAI 모델을 LangChain 방식으로 호출하게 해 주는 통합 패키지다.

  • python-dotenv: .env 파일에 저장한 환경변수를 Python 코드에서 읽게 해 준다.

설치가 끝나면 다음 명령으로 확인할 수 있다.

python -c "import langchain; from langchain_openai import ChatOpenAI; print('ok')"

ok가 출력되면 준비가 된 것이다.

API 키는 코드에 쓰지 않는다

LLM API를 호출하려면 보통 API 키가 필요하다. 여기서는 OpenAI 키를 예로 든다. LangChain의 OpenAI 통합은 OPENAI_API_KEY 환경변수를 사용한다.2

프로젝트 루트에 .env 파일을 만든다.

touch .env

Windows에서는 파일 탐색기나 편집기에서 .env 파일을 직접 만들어도 된다.

.env 파일에 다음처럼 API 키를 저장한다.

OPENAI_API_KEY=여기에_본인의_API_키를_입력

주의할 점이 있다. API 키를 Python 파일 안에 직접 쓰지 말아야 한다. 예를 들어 다음 방식은 피한다.

# 나쁜 예: 코드에 키를 직접 쓰지 않는다.
api_key = "sk-..."

코드는 GitHub 같은 저장소에 올라갈 수 있다. 실수로 API 키가 공개되면 비용이 발생하거나 계정이 악용될 수 있다. 따라서 키는 .env 파일이나 운영 환경의 비밀값 관리 기능에 둔다. 실습 프로젝트에서도 .gitignore 파일을 만들고 .env를 제외하는 습관을 들이자.

.venv/
.env
__pycache__/

.env에 키를 저장하고 python-dotenv로 불러오는 방식은 실습 단계에서 간단하면서도 안전한 출발점이다.3

첫 번째 모델 호출

이제 가장 작은 LangChain 앱을 만든다. first_call.py 파일을 생성한다.

from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage

load_dotenv()

model = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
)

response = model.invoke([
    HumanMessage(content="랭체인을 한 문장으로 설명해 줘.")
])

print(response.content)

실행한다.

python first_call.py

정상적으로 설정되었다면 모델의 답변이 출력된다.

여기서 핵심은 model.invoke(...)다. invoke는 입력 하나를 넣고 결과 하나를 받는 가장 기본적인 실행 방식이다. 지금은 사람의 메시지 하나만 전달했지만, 뒤에서는 시스템 지시문, 대화 기록, 검색 결과, 도구 실행 결과도 함께 전달하게 된다.

temperature=0은 출력을 비교적 일관되게 만들기 위한 설정이다. 실습과 테스트에서는 낮은 값을 쓰는 편이 좋다. 창의적인 문구 생성이 필요할 때는 값을 올릴 수 있지만, 업무 자동화나 문서 기반 답변에서는 예측 가능성이 더 중요할 때가 많다.

모델 이름은 계정과 제공자의 정책에 따라 달라질 수 있다. 예제의 gpt-4o-mini를 사용할 수 없다면, 본인 계정에서 사용 가능한 채팅 모델 이름으로 바꾸면 된다.

메시지 종류 이해하기

채팅 모델은 단순 문자열만 받는 것이 아니라 "역할이 있는 메시지"를 받는다. 대표적으로 세 가지를 자주 사용한다.

  • SystemMessage: 모델의 역할, 규칙, 답변 스타일을 정한다.

  • HumanMessage: 사용자가 입력한 메시지다.

  • AIMessage: 이전에 모델이 답한 메시지다.

이 차이는 대화형 앱에서 중요하다. 같은 문장이라도 시스템 메시지에 넣는지, 사용자 메시지에 넣는지에 따라 모델이 다르게 해석할 수 있다.

messages_demo.py 파일을 만들어 보자.

from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage

load_dotenv()

model = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
)

messages = [
    SystemMessage(content="너는 초보 개발자를 돕는 친절한 Python 튜터다. 답변은 짧고 예제로 설명한다."),
    HumanMessage(content="가상환경이 왜 필요한지 알려 줘."),
]

response = model.invoke(messages)
print(response.content)

여기서는 시스템 메시지로 모델의 역할을 먼저 정했다. 사용자의 질문은 HumanMessage에 넣었다. 이 구조가 챗봇의 기본 뼈대다.

AIMessage는 보통 대화 기록을 유지할 때 사용한다. 예를 들어 첫 번째 질문과 답변을 저장한 뒤, 두 번째 질문을 이어서 보낼 수 있다.

messages = [
    SystemMessage(content="너는 초보 개발자를 돕는 Python 튜터다."),
    HumanMessage(content="가상환경이 뭐야?"),
    AIMessage(content="프로젝트별로 Python 패키지를 분리해 관리하는 공간이야."),
    HumanMessage(content="그럼 왜 프로젝트마다 따로 만들어야 해?"),
]

response = model.invoke(messages)
print(response.content)

일반적인 LangChain 호출에서는 모델이 이전 실행을 자동으로 기억한다고 생각하면 안 된다. 필요한 대화 기록은 매번 함께 보내야 한다. 이 점은 뒤에서 대화 기록과 상태 관리를 다룰 때 다시 중요해진다.

터미널 대화 앱 만들기

이제 사용자가 직접 입력하고, 모델이 답하는 간단한 앱을 만든다. chat.py 파일을 작성한다.

from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage

load_dotenv()

model = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0.2,
)

messages = [
    SystemMessage(
        content=(
            "너는 초보 개발자를 돕는 LangChain 학습 도우미다. "
            "답변은 한국어로 하고, 핵심을 먼저 말한 뒤 짧은 예를 들어라."
        )
    )
]

print("LangChain 대화 앱입니다. 종료하려면 exit 또는 quit를 입력하세요.n")

while True:
    user_input = input("나: ").strip()

    if user_input.lower() in {"exit", "quit"}:
        print("종료합니다.")
        break

    if not user_input:
        continue

    messages.append(HumanMessage(content=user_input))

    response = model.invoke(messages)

    print(f"AI: {response.content}n")

    messages.append(AIMessage(content=response.content))

실행한다.

python chat.py

이 앱은 작지만 중요한 구조를 모두 갖고 있다.

첫째, 시스템 메시지로 앱의 성격을 정한다. 이 예제에서는 "LangChain 학습 도우미"라는 역할과 한국어 답변 규칙을 지정했다.

둘째, 사용자의 입력을 HumanMessage로 추가한다.

셋째, 모델의 응답을 출력한 뒤 AIMessage로 다시 저장한다. 이렇게 해야 다음 질문에서 이전 대화를 참고할 수 있다.

다만 이 방식에는 한계가 있다. 대화가 길어질수록 messages 목록이 계속 커진다. 모델에 보내는 토큰도 늘어나므로 비용과 지연 시간이 증가한다. 실제 서비스에서는 오래된 대화를 요약하거나, 필요한 일부만 유지하거나, 외부 저장소에 상태를 관리한다. 지금은 구조를 이해하는 것이 목표이므로 메모리 안의 리스트로 충분하다.

모델 제공자를 바꾸면 무엇이 달라질까

LangChain을 쓰는 이유 중 하나는 모델 호출 방식의 차이를 어느 정도 감춰 준다는 점이다. 예를 들어 OpenAI 대신 Anthropic 모델을 쓰고 싶다면 설치 패키지와 모델 객체 생성 부분이 바뀐다. LangChain 공식 설치 안내도 OpenAI, Anthropic 같은 제공자별 통합 패키지를 별도로 설치하는 방식을 보여 준다.1

OpenAI를 사용할 때는 다음과 같았다.

from langchain_openai import ChatOpenAI

model = ChatOpenAI(model="gpt-4o-mini")

Anthropic을 사용한다면 대략 다음처럼 바뀐다.

pip install -U langchain-anthropic
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(model="claude-3-5-haiku-latest")

물론 실제 모델 이름과 환경변수 이름은 제공자 문서를 확인해야 한다. 그러나 중요한 점은 나머지 코드의 상당 부분이 유지된다는 것이다.

from langchain_core.messages import HumanMessage

response = model.invoke([
    HumanMessage(content="랭체인을 한 문장으로 설명해 줘.")
])

print(response.content)

즉, 바뀌는 부분은 주로 "어떤 모델 객체를 만들 것인가"다. 메시지를 만들고, invoke로 호출하고, 응답의 content를 읽는 흐름은 거의 그대로 유지된다. 이것이 LangChain의 추상화가 주는 실용적인 장점이다.

하지만 모든 제공자가 완전히 같지는 않다. 지원하는 모델 이름, 토큰 한도, 이미지 입력 여부, 도구 호출 방식, 가격, 응답 속도는 다를 수 있다. LangChain은 공통 인터페이스를 제공하지만, 제공자별 차이까지 없애 주지는 않는다. 운영 환경에서는 반드시 선택한 모델의 비용, 성능, 제한 사항을 확인해야 한다.

자주 만나는 오류

처음 실행할 때는 대부분 설정 오류를 만난다. 아래 항목을 차례로 확인하자.

API 키 오류가 나면 .env 파일의 위치와 변수명을 확인한다. 파일은 실행하는 Python 파일과 같은 프로젝트 루트에 두는 것이 가장 쉽다. 변수명은 OpenAI 기준으로 OPENAI_API_KEY다.

패키지 import 오류가 나면 가상환경이 활성화되어 있는지 확인한다. pip install을 전역 Python에 해 놓고, 실행은 가상환경 Python으로 하는 경우가 흔하다.

모델 이름 오류가 나면 현재 계정에서 사용할 수 있는 모델인지 확인한다. 예제의 모델 이름은 언제든 바뀔 수 있으므로, 제공자 콘솔이나 문서를 확인해야 한다.

응답이 너무 느리거나 비용이 걱정된다면 짧은 입력으로 테스트하고, 낮은 비용의 모델을 선택한다. 대화 기록을 계속 붙이는 앱에서는 새 입력과 누적된 기록이 모두 비용에 영향을 준다.

이번 장에서 만든 기본 흐름

이번 장에서 만든 앱은 단순하다. 그러나 앞으로의 모든 예제는 이 구조 위에서 확장된다.

  • 가상환경으로 프로젝트 의존성을 분리했다.

  • langchain과 제공자 통합 패키지를 설치했다.

  • API 키를 .env로 관리했다.

  • ChatOpenAI로 채팅 모델을 만들었다.

  • SystemMessage, HumanMessage, AIMessage의 역할을 확인했다.

  • 터미널에서 동작하는 작은 대화 앱을 만들었다.

  • 모델 제공자를 바꿀 때 어느 부분이 유지되고 어느 부분이 바뀌는지 살펴봤다.

다음에는 같은 모델 호출이라도 결과 품질을 크게 바꾸는 요소인 프롬프트와 메시지 설계를 다룬다. 이제 모델을 부르는 방법을 알았으니, 다음 질문은 "무엇을 어떻게 말해야 원하는 답을 얻을 수 있는가"다.

참고

1Install LangChain - Docs by LangChain

2ChatOpenAI integration - Docs by LangChain

3How to Use OpenAI's API with LangChain: Setup, Environment Variables, and First Model Call

책 목록

랭체인 활용법: LLM 애플리케이션 개발부터 RAG·에이전트·운영까지

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기