LangChain-compatible LLM agent framework with Chain-of-Thought and structured output support
Project description
LLM Client Integration for LangChain with Chain-of-Thought Support
This package provides a seamless integration between custom LLM clients (e.g., DeepSeek, GLM, Qwen) and LangChain’s BaseChatModel, with built-in support for chain-of-thought (CoT) reasoning, structured output parsing, and both synchronous/asynchronous streaming.
Designed for developers who want fine-grained control over LLM interactions while leveraging LangChain’s ecosystem (e.g., callbacks, astream_events, tools, agents), this implementation wraps any OpenAI-compatible API into a fully compliant LangChain chat model.
📦 Features
- ✅ LangChain-Compatible Chat Model: Implements
BaseChatModelwith full support for sync/async, streaming/non-streaming. - 🔗 Chain-of-Thought (Thinking) Mode: Enable or disable CoT reasoning per model (GLM, Qwen, DeepSeek).
- 🧠 Custom Message Types:
ChatMessageandChatMessageChunkpreserve raw LLM responses (ChatCompletion/ChatCompletionChunk). - 📐 Structured Output Parsing:
SchemaParsergenerates schema-aware prompts and robustly parses LLM responses into Pydantic models. - ⚙️ Flexible LLM Client: Configurable base URL, API key fallbacks, and dynamic reconfiguration.
- 🌐 Streaming Support: Full compatibility with LangChain’s event streaming (
astream_events, callbacks).
🗂️ Project Structure
lingua-agent/
├── pyproject.toml # ← MUST contain project metadata & deps
├── README.md
├── LICENSE
└── src/
└── lingua_agent/ # ← top-level package name
├── __init__.py
├── llm_api/ # ← core LLM integration
│ ├── __init__.py
│ ├── llm_client.py
│ ├── llm_client_chat_model.py
│ ├── message_chunk.py
│ └── thinking_config.py
└── utils/ # ← helpers
├── __init__.py
└── schema_parse.py
🚀 Quick Start
1. Install Dependencies
pip install langchain-core openai pydantic
2. Initialize the LLM Client
from llm_client import LLMClient
llm_client = LLMClient(
model="deepseek-chat",
api_key="your-api-key",
enable_thinking=True # Enable chain-of-thought if supported
)
3. Wrap as LangChain Chat Model
from llm_client_chat_model import LLMClientChatModel
chat_model = LLMClientChatModel(llm_client=llm_client)
4. Use with LangChain
from langchain_core.messages import HumanMessage
# Non-streaming
response = chat_model.invoke([HumanMessage(content="Explain quantum computing.")])
print(response.content)
# Streaming
for chunk in chat_model.stream([HumanMessage(content="Write a haiku.")]):
print(chunk.content, end="", flush=True)
5. Parse Structured Output
from pydantic import BaseModel
from schema_parser import SchemaParser
class Answer(BaseModel):
summary: str
keywords: list[str]
parser = SchemaParser(Answer)
prompt = parser.schema_generation_prompt + "\n\nUser: Summarize climate change."
response = chat_model.invoke([HumanMessage(content=prompt)])
answer: Answer = parser.parse_response_to_base_model(response.content)
🔧 Configuration
Supported Models & CoT Parameters
| Model Prefix | Enable Thinking | Disable Thinking |
|---|---|---|
glm |
{"thinking": {"type": "enabled"}} |
{"thinking": {"type": "disabled"}} |
qwen |
{"enable_thinking": True} |
{"enable_thinking": False} |
deepseek |
{} (no extra params) |
{} |
The
LLMClientauto-detects model type and injects parameters viaextra_body.
API Key Resolution
The client checks environment variables in order:
DEEPSEEK_API_KEYOPENAI_API_KEYZHIPU_API_KEYAPI_KEY
📝 Notes
- Streaming Merge:
merge_chunks_to_completion()reconstructs fullChatCompletionfrom chunks, including usage stats and custom fields likereasoning_content. - Error Resilience:
SchemaParseruses fallback strategies to extract JSON from LLM responses (code blocks, raw JSON). - Callbacks: Fully supports LangChain’s callback system (
on_llm_new_token,astream_events, etc.).
📜 License
MIT License — feel free to use, modify, and distribute.
Built for researchers and developers who need reliable, structured, and introspectable LLM interactions within the LangChain framework.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file langllm-0.1.0.tar.gz.
File metadata
- Download URL: langllm-0.1.0.tar.gz
- Upload date:
- Size: 10.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9222dc3a548f0c0f98503d55da7864038f58ed1222cf11290daacc6ef5f412fb
|
|
| MD5 |
6d28f181a95904519bb89bafea728662
|
|
| BLAKE2b-256 |
84632f96a53b282316323a506171b999f25ac49a2a0fcee21e121313c1ac9220
|
File details
Details for the file langllm-0.1.0-py3-none-any.whl.
File metadata
- Download URL: langllm-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1ca91a8d296dca67aebfcc1bfb3460a665e6c772f3633ac65120d59756a5d78
|
|
| MD5 |
282ce612e3a13006ca288161182f24b5
|
|
| BLAKE2b-256 |
d1e36e6819c6b057f5c2b7af6bca9635f3de794444a3dca8e96eb47b4d0fd4b3
|