LangChain 코드 기여하기
LangChain 코드 기여하기 (Contributing to code)
LangChain 오픈소스 생태계에 코드 기여를 하고 싶다면 이 문서를 따라가면 돼요. 버그 수정부터 신규 기능, 성능 개선까지 여러분의 기여가 수천 명의 개발자에게 더 나은 경험을 제공하거든요. 물론 처음부터 거대한 기능을 던지기보다는 프로젝트의 규칙과 워크플로우를 먼저 익히는 게 훨씬 수월해요. 아래에서 단계별로 같이 살펴볼게요.
출처: 공식문서
시작하기 (Getting started)
무엇을 작업할지 찾고 있다면 각 저장소의 "help wanted" 라벨이 붙은 이슈를 확인해 보세요.
- LangChain 라벨
- LangGraph 라벨
- Deep Agents 라벨
특히 큰 신규 기능이나 리팩터링을 제출하기 전에는 반드시 먼저 이슈를 열거나 포럼에 글을 올려 논의해야 해요. 그래야 프로젝트의 방향과 맞는지 확인되고, 중복 작업도 막을 수 있거든요.
빠른 버그 수정 제출하기
단순한 버그 수정은 바로 시작할 수 있어요. 다음과 같은 흐름으로 진행해 주세요.
- 이슈 재현: 저장소를 클론하기 전에 먼저 버그를 확실하게 재현할 수 있는지 확인해요. 유지보수자나 다른 기여자가 설명만으로 쉽게 재현할 수 있어야 해요.
- 저장소 포크: LangChain, LangGraph, Deep Agents 중 하나를 개인 GitHub 계정으로 포크해요.
- 클론 및 환경 설정:
git clone https://github.com/your-username/name-of-forked-repo.git
# 예를 들어 LangChain이라면:
git clone https://github.com/parrot123/langchain.git
LangChain Python 저장소는 모노레포예요. 저장소 루트에는 pyproject.toml이 없고, 각 패키지는 각자 libs/ 아래에 있어요 (예: libs/core/, libs/langchain/, libs/partners/openai/). uv 명령을 실행하기 전에 반드시 해당 패키지 디렉터리로 cd해야 해요.
# 작업할 패키지로 이동한 뒤 의존성을 설치합니다
cd libs/core # 또는 libs/langchain, libs/partners/openai 등
uv sync --all-groups
# 특정 그룹만 설치하려면:
uv sync --group test
uv가 아직 없다면 설치해야 해요. 전체 패키지 목록과 위치는 저장소 구조 섹션을 참고해요.
- 브랜치 생성: 수정 작업을 위한 새 브랜치를 만들어요.
git checkout -b your-username/short-bugfix-name
- 실패하는 테스트 작성: 수정 없이는 실패할 유닛 테스트를 추가해요. 그래야 버그가 실제로 해결됐는지, 회귀가 생기지 않는지 검증할 수 있어요.
- 수정 진행: 코드 품질 기준을 따르며 문제를 해결하기 위한 최소한의 변경을 만들고, 코딩 전에 이슈에 코멘트를 남기는 걸 권장해요. 예를 들면 "이 문제 작업하고 싶어요. 제 접근 방식은 [...짧은 설명...] 인데, 유지보수자 기대와 맞을까요?" 같은 코멘트 30초면 접근이 틀렸을 때 낭비를 막아줘요.
- 수정 검증: 모든 테스트가 통과하고 회귀가 없는지 확인해요.
make format
make lint
make test
# 통합(integration)과 관련된 버그 수정이라면:
make integration_tests
# (API 테스트 자격증명 설정이 필요할 수 있어요)
- 변경 문서화: 동작이 바뀌었다면 docstring이나 인라인 코멘트를 갱신해요.
- PR 제출: 제공된 PR 템플릿을 따르고, 관련 이슈가 있다면 closing keyword (예:
Fixes #ISSUE_NUMBER)를 사용해 PR 병합 시 이슈가 자동으로 닫히게 해요.
전체 개발 환경 설정
지속적인 개발이나 더 큰 기여를 위해서는 다음을 검토해요.
기여 가이드라인
LangChain 프로젝트에 기여하기 전에 '왜 기여하고 싶은지' 먼저 생각해 보는 게 좋아요. 이력서에 "first contribution" 한 줄만 추가하려는 목적이라면 부트캠프나 온라인 튜토리얼이 더 적합할 수도 있어요. 오픈소스 기여는 시간과 노력이 들지만 더 좋은 개발자가 되는 데도 도움이 돼요. 다만 교육 과정보다는 더디고 어려울 수 있다는 점은 알아두는 게 좋아요.
하위 호환성 (Backwards compatibility)
공개 API의 호환성을 깨는 변경은 보안 수정 같은 긴급한 경우를 제외하고 허용되지 않아요. 메이저 버전 릴리즈 정책은 버저닝 정책을 참고해요.
유지해야 하는 것 (Stable interfaces) — 항상 보존할 것:
- 함수 시그니처와 파라미터 이름
- 클래스 인터페이스와 메서드 이름
- 반환 값 구조와 타입
- 공개 API의 import 경로
안전한 변경 (Safe changes) — 허용되는 수정:
- 새 선택적 파라미터 추가
- 클래스에 새 메서드 추가
- 동작을 바꾸지 않는 성능 개선
- 새 모듈 또는 함수 추가
변경 전에 스스로 물어봐야 할 질문: 기존 사용자 코드를 깨뜨리지 않을까? 대상이 public인가? 필요하다면 __init__.py에 export되어 있나? 테스트에 기존 사용 패턴이 있는가?
신규 기능 (New features)
신규 기능에는 기준을 높게 유지하고 있어요. 외부 기여자가 제안한 new core abstraction은 명확한 필요성을 보여주는 기존 이슈 없이는 일반적으로 받지 않아요. 인프라나 의존성 변경에도 동일하게 적용돼요.
기능 기여 요구사항은 대략 다음과 같아요:
- 설계 논의: 문제, 제안하는 API 설계, 예상 사용 패턴을 담은 이슈를 열어요.
- 구현: 기존 코드 패턴을 따르고, 포괄적인 테스트와 문서를 포함하며, 보안 영향을 고려해요.
- 통합 고려사항: 기존 기능과 어떻게 상호작용하는지, 성능 영향, 새 의존성 도입 여부를 검토해요.
보안 취약점이나 안전하지 않은 패턴을 유발할 가능성이 있는 기능은 거절할 거예요.
보안 가이드라인 (Security guidelines)
보안이 최우선이에요. 취약점이나 안전하지 않은 패턴을 절대 도입하면 안 돼요. 체크리스트는 다음과 같아요.
- 입력 검증: 모든 사용자 입력을 검증하고 살균(sanitize)해요. 템플릿과 쿼리에서 데이터를 제대로 이스케이프해요. 사용자 데이터에
eval(),exec(),pickle을 절대 사용하지 마세요 — 임의 코드 실행 취약점으로 이어질 수 있어요. - 오류 처리: 구체적인 예외 타입을 쓰고, 오류 메시지에 민감한 정보를 노출하지 말며, 리소스 정리를 제대로 해요.
- 의존성: 하드 의존성을 추가하지 말고, 선택적 의존성을 최소화하며, 서드파티 패키지의 보안 이슈를 검토해요.
개발 환경 (Development environment)
AI 코딩 에이전트를 쓰고 있다면 LangChain Docs MCP servers를 설치해서 최신 문서와 예제에 접근할 수 있게 해요. LangChain Skills를 설치하면 LangChain 생태계 작업에서 에이전트 성능이 좋아져요.
Python 프로젝트는 의존성 관리를 위해 uv를 사용해요. 최신 버전이 설치돼 있는지 확인하고, 패키지 디렉터리에서 다음을 실행해요.
uv sync --all-groups
make test # 개발을 시작하기 전에 유닛 테스트가 통과하는지 먼저 확인
저장소 구조 (Repository structure)
LangChain은 여러 패키지를 가진 모노레포로 구성돼 있어요.
핵심 패키지 (Core packages)
langchain(libs/langchain/): 체인, 에이전트, 검색 로직을 담은 메인 패키지langchain-core(libs/core/): 기본 인터페이스와 핵심 추상화
파트너 패키지 (Partner packages) — libs/partners/ 아래에 있으며 통합별로 독립 버전 관리됩니다. 예:
langchain-openai: OpenAI 통합langchain-anthropic: Anthropic 통합langchain-google-genai: Google Generative AI 통합
많은 파트너 패키지는 외부 저장소에 있어요. 자세한 내용은 통합 목록을 확인해요.
지원 패키지 (Supporting packages)
langchain-text-splitters: 텍스트 분할 유틸리티langchain-standard-tests: 통합용 표준 테스트 스위트
LangGraph도 여러 Python 패키지로 구성된 모노레포예요.
langgraph(libs/langgraph/): 상태 기반(stateful) 멀티 에이전트를 만드는 핵심 프레임워크langgraph-prebuilt(libs/prebuilt/): 에이전트와 도구를 만들고 실행하는 고수준 APIlanggraph-checkpoint(libs/checkpoint/): 체크포인트 세이버의 기본 인터페이스langgraph-checkpoint-postgres(libs/checkpoint-postgres/): Postgres 구현langgraph-checkpoint-sqlite(libs/checkpoint-sqlite/): SQLite 구현langgraph-sdk(libs/sdk-py/): 에이전트 서버 API용 Python SDKlanggraph-cli(libs/cli/): 공식 커맨드라인 인터페이스
Deep Agents 역시 여러 Python 패키지로 구성된 모노레포예요.
deepagents(libs/deepagents/): 계획(planning), 파일시스템, 서브에이전트 기능을 갖춘 딥 에이전트를 만드는 핵심 프레임워크deepagents-code(libs/code/): Deep Agents Code — 대화 이어가기, 웹 검색, 샌드박스를 갖춘 인터랙티브 터미널 인터페이스deepagents-cli(libs/cli/): LangSmith 배포로 에이전트를 릴리즈하는 배포 툴링 (deepagents deploy,deepagents init,deepagents dev)deepagents-evals(libs/evals/): LangSmith 추적과 연동된 평가 스위트 및 Harbor 통합deepagents-acp(libs/acp/): Agent Client Protocol 통합
개발 워크플로우 (Development workflow)
Pre-commit 훅: LangChain과 Deep Agents 저장소에는 커밋 전에 포맷·린트·검증을 자동 실행하는 pre-commit 훅이 있어요. 저장소 루트에서 설치해요.
pip install pre-commit # 또는: uv tool install pre-commit
pre-commit install
훅이 강제하는 것: 보호 브랜치로의 직접 커밋 금지, YAML/TOML 문법 검증, 트레일링 공백과 EOF 수정, 스마트 따옴표/비표준 공백 정규화, 패키지별 make format/make lint 등이에요.
테스트 실행 (Running tests)
디렉터리는 작업 중인 패키지 기준으로 상대 경로예요. 가능하면 통합 테스트보다 유닛 테스트를 선호해요. 유닛 테스트는 모든 PR에서 실행되므로 빠르고 안정적이어야 하고, 통합 테스트는 스케줄에 따라 실행되며 더 많은 설정이 필요해서 외부 서비스와의 접점 확인에만 사용해요.
유닛 테스트 — 위치: tests/unit_tests/. 외부 API 호출이 필요 없는 모듈 로직을 다뤄요. 새 로직을 추가하면 유닛 테스트도 추가해야 해요. 요구사항: 네트워크 호출 금지, 엣지 케이스를 포함한 모든 코드 경로 테스트, 외부 의존성은 mock 사용.
make test
# 또는 직접:
uv run --group test pytest tests/unit_tests
# 특정 테스트만:
TEST_FILE=tests/unit_tests/test_imports.py make test
통합 테스트 — 위치: tests/integration_tests/. 외부 API를 호출하는 로직(종종 다른 서비스와의 통합)을 다뤄요. 외부 서비스/프로바이더 API 접근이 필요하고 비용이 들 수 있어 기본적으로 실행되지 않아요. 모든 코드 변경에 통합 테스트가 필요한 건 아니지만, 리뷰 과정에서 별도로 요구/실행할 수 있다는 점을 기억해요. 요구사항: 외부 서비스와 실제 통합 테스트, API 키는 환경변수 사용, 자격증명 없으면 우아하게 스킵.
make integration_tests
# 또는 직접:
uv run --group test --group test_integration pytest --retries 3 --retry-delay 1 tests/integration_tests
# 특정 테스트만:
TEST_FILE=tests/integration_tests/test_openai.py make integration_tests
코드 품질 기준 (Code quality standards)
타입 힌트 (Required): 모든 함수에 완전한 타입 어노테이션이 필요해요.
def process_documents(
docs: list[Document],
processor: DocumentProcessor,
*,
batch_size: int = 100
) -> ProcessingResult:
"""Process documents in batches.
Args:
docs: List of documents to process.
processor: Document processing instance.
batch_size: Number of documents per batch.
Returns:
Processing results with success/failure counts.
"""
문서화 (Required): 모든 공개 함수에 Google 스타일 docstring이 필요해요. 지침: docstring은 "무엇(what)"을 설명하고, 이 사이트의 문서는 "어떻게/왜(how & why)"를 설명해요.
| 내용 | 위치 | 목적 |
|---|---|---|
| 파라미터 타입 | 시그니처 | API 레퍼런스로 자동 생성 |
| 파라미터 설명 | Docstrings | API 레퍼런스로 자동 생성 |
| 반환 타입과 예외 | Docstrings | API 레퍼런스 |
| 최소 사용 예제 | Docstrings | 기본 인스턴스화 패턴 제시 |
| 기능 튜토리얼 | 이 사이트 | 심층 워크스루 |
| 엔드투엔드 예제 | 이 사이트 | 실제 사용 패턴 |
| 개념 설명 | 이 사이트 | 이해와 맥락 |
좋은 docstring 예시:
class ChatAnthropic(BaseChatModel):
"""Interface to Claude chat models.
See the [usage guide](https://docs.langchain.com/oss/python/integrations/chat/anthropic)
for tutorials, feature walkthroughs, and examples.
Args:
model: Model identifier (e.g., `'claude-sonnet-4-6'`).
temperature: Sampling temperature between `0` and `1`.
max_tokens: Maximum number of tokens to generate.
api_key: Anthropic API key.
If not provided, reads from the `ANTHROPIC_API_KEY`
environment variable.
timeout: Request timeout in seconds.
max_retries: Maximum number of retries for failed requests.
Returns:
A chat model instance that can be invoked with messages.
Raises:
ValueError: If the model identifier is not recognized.
AuthenticationError: If the API key is invalid.
Example:
```python
from langchain_anthropic import ChatAnthropic
model = ChatAnthropic(model="claude-sonnet-4-6")
response = model.invoke("Hello!")
```
"""
docstring에 넣으면 안 되는 것: 파라미터 타입(시그니처에 있고 API 레퍼런스로 자동 생성됨), 기능 튜토리얼(확장 워크스루 대신 이 사이트로 링크), 여러 예제 변형(최소 예제 하나 넣고 종합 가이드로 링크), 개념 설명(사실적 파라미터 설명만), MkDocs 전용 문법(???+, 아코디언, 탭 — IDE에서 렌더링 안 됨).
코드 스타일 (Automated): ruff로 포맷과 린트를 자동화해요.
make format # 포맷 적용
make lint # 스타일과 타입 검사
기준: 설명적인 변수 이름, 복잡한 함수는 잘게 쪼개기(20줄 미만 목표), 코드베이스의 기존 패턴 따르기.
의존성 (Dependencies)
LangChain 패키지는 패키지를 가볍게 유지하고 설치 부담을 최소화하기 위해 **하드 의존성(hard)**과 **선택적 의존성(optional)**을 구분해요.
선택적 의존성 — 거의 모든 새 의존성은 선택적이어야 해요. 특정 통합/기능에만 필요한 경우, 의존성 없이도 패키지를 의미 있게 쓸 수 있는 경우, 크거나 전이 의존성이 많은 경우에 선택적 의존성을 사용해요. 요구사항: 의존성이 없는 사용자도 부작용 없이(경고·오류·예외 없이) 코드를 import할 수 있어야 하고, pyproject.toml과 uv.lock은 수정하지 않아요. 추가하려면: 적절한 테스트 의존성 파일(예: extended_testing_deps.txt)에 추가하고, 최소한 새 코드를 import하는 유닛 테스트를 추가하며, 의존성이 필요하면 @pytest.mark.requires("package_name") 데코레이터를 사용해요.
하드 의존성 — 사용자가 패키지를 설치할 때 자동으로 설치돼요. 패키지가 근본적으로 이 의존성 없이는 동작할 수 없는 경우, 의존성이 작고 전이 의존성이 최소인 경우, 선택적으로 만들 방법이 없는 경우에만 사용해요. 하드 의존성을 추가하면 모든 사용자의 설치 시간과 버전 충돌 가능성이 늘어나므로 유지보수자가 꼼꼼히 검토해요. 추가하려면: 왜 hard여야만 하는지 설명하는 이슈/토론을 열고, pyproject.toml의 적절한 섹션에 추가하고, uv lock으로 lockfile을 갱신하고, 새 기능을 다루는 포괄적인 테스트를 포함해요.
테스트 작성 가이드라인 (Test writing guidelines)
효과적인 테스트를 위한 좋은 관행:
- docstring에 테스트를 자연어로 설명
- 설명적인 변수 이름 사용
- 단언(assertion)을 철저하게
유닛 테스트 예시:
def test_document_processor_handles_empty_input():
"""Test processor gracefully handles empty document list."""
processor = DocumentProcessor()
result = processor.process([])
assert result.success
assert result.processed_count == 0
assert len(result.errors) == 0
통합 테스트 예시:
@pytest.mark.requires("openai")
def test_openai_chat_integration():
"""Test OpenAI chat integration with real API."""
chat = ChatOpenAI()
response = chat.invoke("Hello")
assert isinstance(response.content, str)
assert len(response.content) > 0
Mock 사용 예시:
def test_retry_mechanism(mocker):
"""Test retry mechanism handles transient failures."""
mock_client = mocker.Mock()
mock_client.call.side_effect = [
ConnectionError("Temporary failure"),
{"result": "success"}
]
service = APIService(client=mock_client)
result = service.call_with_retry()
assert result["result"] == "success"
assert mock_client.call.call_count == 2
PR 제출하기 (Submitting your PR)
테스트가 통과하고 코드 품질 기준을 충족했다면:
- 브랜치를 푸시하고 풀 리퀘스트를 열어요
- 제공된 PR 템플릿을 따라요
- closing keyword (예:
Fixes #123)로 관련 이슈를 참조해요 - CI 체크가 끝날 때까지 기다려요
PR에 AI 생성 콘텐츠가 포함됐다면 LLM 허용 사용 정책을 따라야 해요. 노력이 들지 않은 AI 생성 스팸처럼 보이는 PR은 코멘트 없이 닫힐 수 있어요. CI 실패는 빨리 처리해 주세요 — 합리적 기간 내에 CI를 통과하지 못한 PR은 유지보수자가 닫을 수 있어요.
도움 받기 (Getting help)
가장 접근성 좋은 개발 환경을 만드는 게 목표예요. 설정에 어려움이 있다면 커뮤니티 슬랙에서 묻거나 포럼에 글을 올려요. 이제 LangChain에 고품질 코드를 기여할 준비가 됐어요.
더 알아보기 (Learn more)
- LangChain MCP 서버 — Claude, VSCode 등에서 실시간 문서를 MCP로 연결
- LangChain Skills — 에이전트 성능 개선용 스킬
- LangChain 커뮤니티 — 포럼과 슬랙