Skip to main content

langchaint

langchaint is an opinionated, provider-neutral Python client for LLM applications. It provides fully typed, asynchronous APIs for generation, streaming, embeddings, tools, retries, and billing. The application owns the agent loop.

Alpha: the API may change without notice.

Why langchaint

  • Consistent API. Bind request fields once with LLM.bind(), then call generate_one(), generate_many(), or stream_one() on the resulting BoundLLM.
  • Output types determined by binding. Binding response_format=Answer gives generate_one() the return type Response[Answer]. Binding tools as well adds ToolCallTurn[Answer] to that return type.
  • Result variants with autocomplete. Match on .kind with editor autocomplete and no class imports.
  • Coordinated retries. Share concurrency limits, request-start pacing, and provider-directed pauses across models using one rate-limit quota.
  • Complete billing. Successful results and GenerationError values retain provider-reported usage from every recorded attempt, including billed retries.
  • Streaming. stream_one() returns an async context manager and async iterator. final() returns the typed result with its usage.
  • Agent loops in Python. Provider-neutral messages, typed tools with argument validation, concurrent dispatch, and explicit result variants support async control flow.

Install

langchaint requires Python 3.13 or newer.

Install the extra for each backend you use:

pip install "langchaint[openai]"
Backend Class Install
Anthropic Anthropic langchaint[anthropic]
Anthropic on Amazon Bedrock AnthropicBedrock langchaint[anthropic-bedrock]
Cohere embeddings on Amazon Bedrock CohereBedrock langchaint[cohere-bedrock]
DeepSeek DeepSeek langchaint[deepseek]
Gemini Gemini langchaint[gemini]
OpenAI OpenAI langchaint[openai]
OpenAI embeddings OpenAI langchaint[openai-embedding]
OpenAI on Amazon Bedrock OpenAIBedrock langchaint[openai-bedrock]

Install langchaint[tracing] for OpenTelemetry tracing.

Generate a typed response

import asyncio

from pydantic import BaseModel

from langchaint.openai import OpenAI


class Answer(BaseModel):
    answer: str
    confidence: float


async def main() -> None:
    assistant = (
        OpenAI()
        .model("gpt-5.6-terra")
        .bind(
            system_prompt="Answer clearly and concisely.",
            response_format=Answer,
        )
    )
    response = await assistant.generate_one("Why is the sky blue?")

    print(response.output.answer)
    print(response.usage.cost_in_usd)


asyncio.run(main())

The Pydantic model validates the provider response.

generate_many() returns one result per input in input order. A terminal failure becomes that input's GenerationError, so sibling results remain available.

Coordinate retries across a rate-limit quota

Create one OpenAI for each rate-limit quota:

openai = OpenAI(
    max_concurrent_requests=8,
    max_request_starts_per_second=50.0,
)

fast_model = openai.model("gpt-5.6-luna")
strong_model = openai.model("gpt-5.6-sol")

A rate-limit response pauses request starts across the shared quota. After a transient failure local to one request, langchaint waits and retries that request.

Stream with an explicit lifetime

text_assistant = OpenAI().model("gpt-5.6-terra").bind()

async with text_assistant.stream_one("Explain photosynthesis.") as stream:
    async for item in stream:
        if isinstance(item, str):
            print(item, end="", flush=True)

    response = await stream.final()

final() consumes the remaining stream and returns the assembled result.

Build agent loops

The application controls turn limits, state, approvals, model changes, and persistence.

messages: list[Message] = [UserMessage(content=prompt)]

for _ in range(max_turns):
    result = await bound.generate_one(messages)

    match result.kind:
        case "tool_call_turn":
            messages.append(result.assistant_message)
            outcomes = await bound.tool_manager.dispatch_many(result.tool_calls)
            messages.extend(outcome.tool_message for outcome in outcomes)
        case "response":
            return result.output

raise RuntimeError("model did not finish within max_turns")

ToolManager.dispatch_many() runs tool calls concurrently and preserves their order.

See examples/02_tool_loop.py for a complete typed tool loop.

Account for the complete call

response.usage.cost_in_usd includes every billed retry recorded for the call. GenerationError.usage preserves the recorded cost of failed calls.

More examples

See examples/README.md for complete examples.

License

MIT License

Release files for langchaint 0.23.3

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.23.3
File Size Uploaded
langchaint-0.23.3.tar.gz 179.2 kB Details

Built distribution (wheel)

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

Total release size: 380.3 kB

Release files / langchaint-0.23.3.tar.gz

Download URL langchaint-0.23.3.tar.gz
Size 179.2 kB
Tags Source
SHA-256 checksum
How to use checksums
de8bb5dfd7e85f3546e0cd44559db6dda1f37131d8825afa81f042b9ed4a9aa7
BLAKE2b-256 checksum
How to use checksums
e0e3ea8e6d080b02f3515b771f2ea9931fcbe1b3fd47e12f833f465c3ebeeea7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","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.23.3-py3-none-any.whl

Download URL langchaint-0.23.3-py3-none-any.whl
Size 201.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0f9de2c6a7e0ae88c744ddb248f7d1895ee18d663a95ad5643a1f313852a3f06
BLAKE2b-256 checksum
How to use checksums
13202513ce5e4e071e36022afc2181ee1c56eca92b3b5aeef4dfca915569423d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","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

This release

0.23.3 This release

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

0.11.2

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