Skip to main content

langchaint

Provider-neutral async LLM client over the official anthropic and openai SDKs. Alpha: the API is unstable and may change without notice.

The point

langchaint is the layer between an application's own agent loop and the provider SDKs. Across providers it gives one message tree, one error taxonomy, one priced Usage, and one RateLimiter that owns retrying and pacing. The application keeps the agent loop and states every billing-relevant choice itself, starting with prompt caching; langchaint defaults none of them.

Install

Requires Python >= 3.13. The hard dependencies are pydantic and jsonschema; the provider SDKs are optional dependencies the application pins directly, and langchaint declares no extras.

pip install langchaint openai        # or anthropic, or both

import langchaint needs neither SDK; importing langchaint.openai without the openai package raises a ModuleNotFoundError naming the package to install.

Example

import asyncio

from pydantic import BaseModel

from langchaint.openai import openai_model


class Sentiment(BaseModel):
    label: str
    confidence: float


async def main() -> None:
    llm = openai_model("gpt-5.6-terra")
    classifier = llm.bind(
        system_prompt="Classify the sentiment of the user's message.",
        response_format=Sentiment,
        automatic_prompt_caching=False,
    )
    response = await classifier.generate_one("This is the best day I have had in months.")
    print(response.output.label, response.usage.cost_in_usd)


asyncio.run(main())

bind(response_format=Sentiment) returns a BoundLLM[Sentiment], so response.output is a validated Sentiment instance; without response_format, output is the assistant text. A bare str generation_input is shorthand for [UserMessage(content=generation_input)]. examples/ holds one snippet file per subject and MIGRATING_FROM_LANGCHAIN.md, the LangChain call-for-call map.

What it has

Generation only via binding. LLM.bind(...) freezes everything that determines the cacheable prompt prefix into a BoundLLM[OutputT], and changing parameters is rebind(...). BoundLLM has generate_one, generate_many, and stream_one.

A constructor per backend returning a ready LLM. openai_model(...), anthropic_model(...), anthropic_bedrock_model(...), and openai_bedrock_model(...).

One accounting contract for success and failure. Success is a Response[OutputT] and a terminal failure is a GenerationError. Both carry usage, the paid total across every attempt.

Priced usage. Usage partitions input tokens by cache outcome and carries one cost per priced category; cost_in_usd is their sum.

One RateLimiter owning retrying and pacing. One instance shared by several LLMs is one budget for the account they hit.

User-stated prompt caching. automatic_prompt_caching is a required keyword of bind with no default, because caching changes billing. cache_breakpoint=True on a content part places a prompt-cache boundary at exactly that part.

Streaming as a handle. stream_one returns a StreamHandle: an async context manager that iterates str | ReasoningDelta | ToolCall items, with await handle.final() returning the assembled Response.

Tools under one protocol. PydanticTool, JSONSchemaTool (for tools discovered at run time, such as MCP tools), and CaptureTool share the Tool protocol. One ToolManager holds a mix, and an application adds its own form by implementing Tool.

Reasoning preserved across turns. Every provider reasoning element is re-sent verbatim on later requests, so tool-use continuations satisfy each provider's replay rules without application code.

OTel tracing as a wrapper. langchaint.tracing wraps LLM, BoundLLM, StreamHandle, and ToolManager in Traced counterparts; capture_message_content is a required keyword with no default, because recording prompts is a privacy choice.

What it does not have

  • No agent class and no agent loop: the loop is ~15 lines of application code, shown in examples/02_tool_loop.py, and a tool returns data, never a control-flow signal.
  • No client-side guessing at provider rules.
  • No document or PDF part: convert before sending, rasterizing pages to ImagePart or extracting the text layer to TextPart.

No Chat Completions adapter is built yet; OpenAI support is the Responses API.

Layout

src/langchaint/           the neutral core; imports no SDK
src/langchaint/anthropic/ the anthropic backend
src/langchaint/openai/    the openai backend
src/langchaint/tracing/   the OTel tracing subpackage
examples/                 one snippet file per subject and MIGRATING_FROM_LANGCHAIN.md

Verification

Run scripts/CI.sh. The tests are offline and need no API keys.

Release files for langchaint 0.11.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for langchaint 0.11.2
File Size Uploaded
langchaint-0.11.2.tar.gz 147.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for langchaint 0.11.2
File Interpreter ABI Platform
langchaint-0.11.2-py3-none-any.whl Python 3 none any Details

Total release size: 305.5 kB

Release files / langchaint-0.11.2.tar.gz

Download URL langchaint-0.11.2.tar.gz
Size 147.6 kB
Tags Source
SHA-256 checksum
How to use checksums
1ba3e4a32ae72fbc5dd98ecb9c6f265e7110b2867a2670e58744deb4f9cffb25
BLAKE2b-256 checksum
How to use checksums
5d7575ab937a54e8967473932ccd2d99b2225618789c492e597a5caa9b7b5f98
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / langchaint-0.11.2-py3-none-any.whl

Download URL langchaint-0.11.2-py3-none-any.whl
Size 157.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fb3784c731522ce5b23e11bfba19c8b3d062ace592b5434e1089ecd213b2ac3e
BLAKE2b-256 checksum
How to use checksums
f43ac680774b4462810f764c076c679ea7028c6cbb253cc44047045b28f2b5f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.23.3

2 release files

0.23.2

2 release files

0.23.1

2 release files

0.23.0

2 release files

0.22.0

2 release files

0.21.2

2 release files

0.19.4

2 release files

0.19.3

2 release files

0.19.1

2 release files

0.19.0

2 release files

0.18.1

2 release files

0.18.0

2 release files

0.17.1

2 release files

0.17.0

2 release files

0.16.0

2 release files

0.15.3

2 release files

0.15.2

2 release files

0.15.1

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

This release

0.11.2 This release

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page