Skip to main content
我们始终欢迎代码贡献!无论是修复 Bug、添加功能还是提升性能,您的贡献都有助于为成千上万的开发者提供更好的开发体验。

快速开始

在提交大型新功能或重构之前,请先提交 Issue 或在论坛发帖讨论。这有助于确保与项目目标保持一致,并避免重复工作。

快速修复:提交 Bug 修复

对于简单的 Bug 修复,您可以立即开始:
1

复现问题

在克隆仓库之前,先确保您能可靠地复现该 Bug。这有助于确认问题并为修复提供起点。维护者和其他贡献者应该能够根据您的描述复现问题,无需额外设置或修改。
2

Fork 仓库

LangChainLangGraphDeep Agents 仓库 Fork 到您的
3

克隆并设置

git clone https://github.com/your-username/name-of-forked-repo.git

# For instance, for LangChain:
git clone https://github.com/parrot123/langchain.git
# Inside your repo, initialize environment and install dependencies
uv venv && source .venv/bin/activate
uv sync --all-groups

# or, to install a specific group only:
uv sync --group test
如果您之前未安装过 uv,需要先进行安装
4

创建分支

为您的修复创建一个新分支。这有助于保持更改的组织性,并使后续提交 Pull Request 更加容易。
git checkout -b your-username/short-bugfix-name
5

编写失败测试

添加单元测试,这些测试在没有您的修复时会失败。这让我们可以验证 Bug 已被解决,并防止回归。
6

进行更改

在遵循我们的代码质量标准的同时修复 Bug。进行最小必要的更改来解决问题。我们强烈鼓励贡献者在开始编码之前在 Issue 上评论。例如:
“我想处理这个问题。我的预期方法是 […简要描述…]。这与维护者的期望一致吗?”
如果您的初始方法有误,30 秒的评论通常可以避免浪费精力。
7

验证修复

确保测试通过且没有引入回归。在提交 PR 之前确保所有测试在本地通过
make format
make lint
make test

# For bugfixes involving integrations, also run:
make integration_tests
# (You may need to set up API testing credentials)
8

记录更改

如果行为发生变化,请更新文档字符串和/或内联注释
9

提交 Pull Request

遵循提供的 PR 模板。如果适用,使用关闭关键字引用您正在修复的 Issue(例如 Fixes #ISSUE_NUMBER),以便 PR 合并时 Issue 自动关闭。

完整开发设置

对于持续开发或较大贡献:
  1. 查看我们关于功能、Bug 修复和集成的贡献准则
  2. 按照下方的设置指南设置您的环境
  3. 了解仓库结构和包组织
  4. 学习我们的开发工作流,包括测试和代码检查

贡献准则

在开始为 LangChain 项目做贡献之前,花点时间思考一下您的动机。如果您唯一的目标是在简历上添加”第一次贡献”(或者只是在寻找一次快速成功),您可能最好去参加训练营或在线教程。 为开源项目做贡献需要时间和精力,但它也可以帮助您成为更好的开发者并学习新技能。但是,重要的是要知道,它可能比参加培训课程更难、更慢。话虽如此,如果您愿意花时间把事情做好,为开源项目做贡献是值得的!

向后兼容性

不允许对公共 API 进行破坏性更改,除非是关键安全修复。有关主版本发布的详细信息,请参阅我们的版本政策
通过以下方式维护兼容性:
始终保留
  • 函数签名和参数名称
  • 类接口和方法名称
  • 返回值结构和类型
  • 公共 API 的导入路径
可接受的修改
  • 添加新的可选参数
  • 向类添加新方法
  • 在不改变行为的情况下提升性能
  • 添加新模块或函数
  • 这会破坏现有用户代码吗?
  • 检查您的目标是否是公共的
  • 如果需要,是否在 __init__.py 中导出?
  • 测试中是否有现有的使用模式?

新功能

我们的目标是对新功能保持较高的标准。通常,我们不接受来自外部贡献者的新核心抽象,除非有现有的 Issue 展示了对其的迫切需求。这也适用于对基础设施和依赖项的更改。 一般来说,功能贡献的要求包括:
1

设计讨论

提交 Issue,描述:
  • 您正在解决的问题
  • 建议的 API 设计
  • 预期的使用模式
2

实现

  • 遵循现有的代码模式
  • 包含全面的测试和文档
  • 考虑安全影响
3

集成考虑

  • 这与现有功能如何交互?
  • 是否有性能影响?
  • 这是否引入了新的依赖项?
我们将拒绝可能导致安全漏洞或报告的功能。

安全准则

安全至关重要。切勿引入漏洞或不安全的模式。
安全检查清单:
  • 验证并清理所有用户输入
  • 在模板和查询中正确转义数据
  • 切勿对用户数据使用 eval()exec()pickle,因为这可能导致任意代码执行漏洞
  • 使用特定的异常类型
  • 不要在错误消息中暴露敏感信息
  • 实现适当的资源清理
  • 避免添加硬性依赖项
  • 保持可选依赖项最小化
  • 检查第三方包的安全问题

开发环境

我们的 Python 项目使用 uv 进行依赖管理。请确保您已安装最新版本。
我们致力于在所有 Python 包中保持一致的设置。在包目录中运行:
uv sync --all-groups
make test  # Verify unit tests pass before starting development
查看贡献准则后,在下方的仓库结构部分找到您正在处理的组件的包目录。

仓库结构

LangChain 以 Monorepo 形式组织,包含多个包:

核心包

  • langchain(位于 libs/langchain/):包含链、智能体和检索逻辑的主包
  • langchain-core(位于 libs/core/):基础接口和核心抽象
位于 libs/partners/,这些是特定集成的独立版本包。例如:许多合作伙伴包位于外部仓库中。请查看集成列表了解详情。

开发工作流

运行测试

目录路径相对于您正在处理的包。
我们尽可能优先使用单元测试而非集成测试。单元测试在每个 Pull Request 上运行,因此应该快速且可靠。集成测试按计划运行且需要更多设置,因此应保留用于确认与外部服务的接口点。

单元测试

位置tests/unit_tests/ 单元测试涵盖不需要调用外部 API 的模块化逻辑。如果您添加了新逻辑,应该添加一个单元测试。在单元测试中,检查前/后处理并模拟外部依赖项。 要求
  • 不允许网络调用
  • 测试所有代码路径,包括边界情况
  • 对外部依赖项使用模拟
运行单元测试:
make test

# Or directly:
uv run --group test pytest tests/unit_tests

# To run a specific test:
TEST_FILE=tests/unit_tests/test_imports.py make test

集成测试

位置tests/integration_tests/ 集成测试涵盖需要调用外部 API(通常是与其他服务的集成)的逻辑。 集成测试需要访问外部服务/提供商 API(可能需要付费),因此默认不运行。 不是每个代码更改都需要集成测试,但请记住,我们将在审查过程中单独要求/运行集成测试。 要求
  • 测试与外部服务的真实集成
  • 使用环境变量存储 API 密钥
  • 如果凭证不可用,优雅跳过
运行集成测试:
make integration_tests

# Or directly:
uv run --group test --group test_integration pytest --retries 3 --retry-delay 1 tests/integration_tests

# To run a specific test:
TEST_FILE=tests/integration_tests/test_openai.py make integration_tests

代码质量标准

贡献必须遵守以下质量要求:
必需:所有函数的完整类型注解
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.
    """

依赖项

LangChain 包区分硬性依赖项可选依赖项,以保持包的轻量化并最小化用户的安装开销。
几乎所有新依赖项都应该是可选的。在以下情况下使用可选依赖项:
  • 依赖项仅对特定集成或功能是必需的
  • 用户可以在没有此依赖项的情况下有效地使用该包
  • 依赖项体积较大或有许多传递依赖项
要求:
  • 未安装依赖项的用户必须能够导入您的代码而没有任何副作用(无警告、无错误、无异常)
  • pyproject.tomluv.lock 不会被修改
添加可选依赖项:
  1. 将依赖项添加到适当的测试依赖项文件(例如 extended_testing_deps.txt
  2. 添加单元测试,至少尝试导入新代码。理想情况下,单元测试使用轻量级固件来测试代码逻辑。
  3. 对于需要依赖项的任何单元测试,使用 @pytest.mark.requires("package_name") 装饰器。

测试编写准则

为了编写有效的测试,有几个好的实践需要遵循:
  • 在文档字符串中使用自然语言描述测试
  • 使用描述性变量名
  • 断言要详尽
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

提交 PR

测试通过且代码符合质量标准后:
  1. 推送您的分支并提交 Pull Request
  2. 遵循提供的 PR 模板
  3. 使用关闭关键字引用相关 Issue(例如 Fixes #123
  4. 等待 CI 检查完成
请及时处理 CI 失败。维护者可能会关闭在合理时间内未通过 CI 的 PR。

获取帮助

我们的目标是拥有尽可能易于访问的开发者设置。如果您在设置过程中遇到任何困难,请在社区 Slack 中提问或发布论坛帖子
您现在已准备好向 LangChain 贡献高质量代码!