langchain-ai/langchain
Development workflow
The branch–code–test–PR cycle for this monorepo.
1. Pick a package
Almost every change touches exactly one package under libs/. The typical choices:
| Change | Package |
|---|---|
| New base abstraction or interface | libs/core/ |
| New built-in middleware | libs/langchain_v1/ |
| Provider integration | libs/partners/<provider>/ |
| New text splitter | libs/text-splitters/ |
| Shared test improvements | libs/standard-tests/ |
| Model profile data | partner's data/ directory, refreshed via libs/model-profiles/langchain_model_profiles/cli.py |
| Legacy chain bug fix | libs/langchain/langchain_classic/ |
Cross-cutting changes (e.g. a new content-block type) usually start in langchain-core and propagate outward via PRs against partner packages.
2. Set up the dev environment
cd libs/<package>
uv sync --all-groups[tool.uv.sources] in each pyproject.toml wires sibling packages with editable = true, so your in-tree changes are visible across packages without reinstalling. For example, libs/langchain_v1/pyproject.toml includes:
[tool.uv.sources]
langchain-core = { path = "../core", editable = true }
langchain-tests = { path = "../standard-tests", editable = true }
langchain-text-splitters = { path = "../text-splitters", editable = true }
langchain-openai = { path = "../partners/openai", editable = true }
langchain-anthropic = { path = "../partners/anthropic", editable = true }3. Write the change
Conventions enforced by lint:
- All Python code must include type hints and return types.
- All public functions need Google-style docstrings with an
Args:section. - Imports are absolute (
ban-relative-imports = "all"in everyruff.toml). - Lines wrap at 100 chars (
line-length = 100). - New keyword arguments to public APIs should be keyword-only (
*, new_param: ...) so callers' positional usage doesn't break. - Don't change the default value of
model=parameters in shipped code without flagging it as breaking.
Mark experimental APIs with the MkDocs Material !!! warning admonition in their docstring.
4. Run lint, type check, and tests locally
make format # apply ruff format and ruff check --fix
make lint # ruff check + ruff format --check + mypy (varies per package)
make test # unit tests, no networkFor type-checks specifically:
uv run --group lint mypy .Both langchain-core and langchain use mypy in strict = true mode with enable_error_code = "deprecated".
5. Commit and PR
The repo follows Conventional Commits. PR titles are linted by .github/workflows/pr_lint.yml. Every title needs a scope:
feat(langchain): add new chat completion feature
fix(core): resolve type hinting issue in vector store
chore(anthropic): update infrastructure dependencies
fix(openai): infer Azure chat profiles from model name- Lowercase first letter after the colon, except for proper nouns (Azure, OpenAI, GitHub) and named entities (which should be wrapped in backticks).
- The
core,langchain,langchain-classic,text-splitters,standard-tests,model-profiles,tests,partners, and each partner name (openai,anthropic, …) are valid scopes — see.github/workflows/pr_lint.ymlfor the canonical list.
PR descriptions:
- The description is the summary; don't add a
# Summaryheader. - Lead with
Closes #N(orFixes/Resolves) on its own line, followed by a horizontal rule, when applicable. - Explain the why of the change, not just the what.
- Wrap class/function/parameter names in backticks.
- Add a brief disclaimer if AI agents helped.
6. CI
.github/workflows/check_diffs.yml inspects the changed paths and dispatches the right reusable workflows:
_lint.yml— ruff + mypy_test.yml— pytest unit tests across Python 3.10–3.14_compile_integration_test.yml— verify integration tests still import (without API calls)_test_pydantic.yml— runs the test matrix against Pydantic versions_test_vcr.yml— replays recorded HTTP cassettesintegration_tests.yml— full integration tests, gated on secrets
.github/workflows/pr_labeler.yml automatically applies size, file, title, external-vs-internal, and contributor-tier labels.
7. Review and merge
- Only repository maintainers can merge.
- Reviews focus on: API stability, test coverage, type-correctness, and whether the change belongs in
langchain-core(broad surface) vs a higher-level package. - For partner packages, the relevant integration's domain expert is usually the reviewer.
8. Release
Releases are manual. The .github/workflows/_release.yml workflow takes working-directory (e.g. libs/partners/openai) and release-version (e.g. 1.2.3) inputs, builds the wheel via hatchling, and publishes to PyPI. Tags follow the format <package>==<version> (for example langchain-openai==1.2.1).
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.