Skip to main content

langchain-clm

Route a LangGraph graph with a CLM (Contrastive Language Model).

router = create_router(
    state_selector=lambda s: s["last_message"],
    routes=[Route(Intent.REFUND, "Refund the duplicate charge", "refund_node")],
)
graph.add_conditional_edges("classify", router)

Checkpoint

checkpoint_path (or $CLM_CHECKPOINT) if given; otherwise ~/.cache/clm/CLM_v0.1-8B.pt, downloaded from Hugging Face on first use.

Device

The CLM projection heads (the small networks on top of the encoder) run on the CPU by default. Pass device="cuda" (or "cuda:1", "mps", a torch.device, ...) to create_router to use a GPU:

create_router(..., device="cuda")

This only affects the projection heads. The heavy part, the Qwen3-8B encoder that produces the embeddings, runs in the embedding server, so GPU use there is configured on the server itself (e.g. llama serve ... -ngl 99 to offload layers to the GPU), not through this library.

Embeddings

By default embeddings come from a llama server running Qwen3-8B (llama serve -m Qwen3-8B-Q4_K_M.gguf --embedding --pooling last --port 8090). Configure it, or replace it, with embedding_provider:

# Different server / address
create_router(..., embedding_provider=LlamaEmbeddingProvider(base_url="http://host:8090"))

# Any LangChain Embeddings object
create_router(..., embedding_provider=LangChainEmbeddingProvider(my_embeddings))

# Fully custom: any object with embed(list[str]) -> list[list[float]]
class MyProvider:
    def embed(self, texts: list[str]) -> list[list[float]]: ...

The CLM heads were trained on Qwen3-8B embeddings (4096 dims, last-token pooling), so a custom provider must serve the same encoder; a dimension mismatch raises a ValueError.

Example: Wumpus World

examples/wumpus.py solves the Wumpus World with a LangGraph graph in which CLM takes the decisions. It needs the llama embedding server running (see above).

uv run python examples/wumpus.py              # the classic 4x4 world
uv run python examples/wumpus.py --random     # a random world
uv run python examples/wumpus.py --seed 7     # a reproducible random world (implies --random)
uv run python examples/wumpus.py --gui        # a window instead of the terminal (needs tkinter)

--gui shows the board (pits, wumpus, gold, agent), a Start button, and a side panel with what CLM answered at each step (the probability of every intent), how long each decision took (embedding server vs. CLM heads) and a log. --delay SECONDS sets the pause between steps (default 1).

The map is printed first (S start, P pit, W wumpus, G gold), then the agent's observations and actions, and finally the outcome and score.

How it works:

  • An observe node updates what the agent knows from the percepts (breeze, stench, glitter) and describes the situation in plain English.
  • create_router gives that text to CLM, which chooses between three intents: explore, grab the gold or leave. The router returns the node that carries the intent out.
  • Those nodes do the path-finding over the cells the agent has proven safe, so it never steps on a pit or on the wumpus.

Two things to know:

  • CLM is a semantic matcher and does not tell "turn left" from "turn right" (nor north from east). That is why it picks high-level intents and the nodes handle navigation.
  • The agent never takes risks and never shoots. Random worlds are filtered so that the gold can be reached through cells proven safe.

The wording of the situation text and of the route descriptions affects which route CLM picks; the ones in the example were tuned against the model, so re-check them if you change them.

Metadata

Release files for langchain-clm 0.1.0

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

Source distribution (sdist)

Source distribution for langchain-clm 0.1.0
File Size Uploaded
langchain_clm-0.1.0.tar.gz 11.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for langchain-clm 0.1.0
File Interpreter ABI Platform
langchain_clm-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 19.7 kB

Release files / langchain_clm-0.1.0.tar.gz

Download URL langchain_clm-0.1.0.tar.gz
Size 11.1 kB
Tags Source
SHA-256 checksum
How to use checksums
15bf0d16f2924096f6f828d7ae244a94ce0ddd9156d2954ace248462938663e2
BLAKE2b-256 checksum
How to use checksums
daeae10cf8bb34bef0f18ca6797628eb3507fbb206666c9792ab67cea6a67f98
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.22

Release files / langchain_clm-0.1.0-py3-none-any.whl

Download URL langchain_clm-0.1.0-py3-none-any.whl
Size 8.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
624bb537e316afd5fe1852bcf33eb265462378a08ea1b4e78656e08335c1efc8
BLAKE2b-256 checksum
How to use checksums
28a9444924a1f5c7913ec5138b797c7b3fe0070897c99a335174e957e8c2bda3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.22

Release history Release notifications | RSS feed

This release

0.1.0 This release

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