LangChain custom chat model
Project description
ChatBaml
Custom LangChain Chat Model tích hợp BAML — bridge giữa LangChain orchestration và BAML structured extraction/function calling.
Demo: React Agent với ChatBaml chạy trên Qwen3-VL-8B-Instruct
Mục lục
Cài đặt
git clone https://github.com/thanhhuynhk17/ChatBaml.git
cd ChatBaml
uv venv
source .venv/bin/activate # Linux/macOS
# source .venv/Scripts/activate # Windows
uv pip install -e .
# Generate baml_client/ từ baml_src/
uv run baml-cli generate
Cấu hình môi trường
Tạo file .env (xem .env.sample):
# Model config
OPENAI_MODEL_NAME="qwen3-vl"
OPENAI_BASE_URL="http://localhost:8000/v1"
OPENAI_API_KEY="sk-your-key"
# Bắt buộc khi dùng vLLM
DEFAULT_ROLE="user"
# Tắt BAML verbose logging (optional)
BAML_LOG=off
# Bắt buộc cho LangChain content blocks v1
LC_OUTPUT_VERSION="v1"
Kiến trúc
custom_langchain_model/
├── core/
│ ├── registry.py ← build_client_registry(), get_baml_client()
│ └── logging.py
├── llms/
│ ├── chat_baml.py ← ChatBaml (BaseChatModel)
│ └── types.py
├── helpers/
│ ├── parse_json_schema.py ← convert_to_baml_tool()
│ ├── messages.py
│ └── render_agent_wants_to.py
└── extractors/
└── structured.py ← extract_structured(), extract_with_pydantic()
baml_src/
├── chat_baml.baml ← Chat, ChooseTool, ExtractStructure
├── clients.baml
└── generators.baml
react_agent/
├── agent.py
└── tools.py
Nguyên tắc thiết kế:
core/registry.pylà single source of truth cho BAML authentication — cảChatBamllẫn standalone client đều dùng chung.- Không cần tạo
ChatBamlinstance nếu chỉ cần gọi BAML functions trực tiếp.
Sử dụng
1. Standalone BAML Client
Dùng khi muốn gọi BAML functions trực tiếp mà không cần tạo LangChain model instance. Giải quyết vấn đề 401 auth error khi dùng baml_client.b mặc định.
from custom_langchain_model import get_baml_client
# Đọc config từ env vars (OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_MODEL_NAME)
b = get_baml_client()
# Override bất kỳ param nào
b = get_baml_client(
model="gpt-4o",
api_key="sk-...",
base_url="http://localhost:8000/v1",
)
# Gọi BAML functions như bình thường
from custom_langchain_model.baml_client.types import BamlState, BaseMessage, ContentBlock
state = BamlState(messages=[
BaseMessage(role="user", content_block=ContentBlock(text="Hello!"))
])
result = b.Chat(state)
print(result) # str
2. Pydantic Extraction — extract_with_pydantic()
Trích xuất dữ liệu sử dụng Pydantic Model. Hỗ trợ nested models và truyền description trong Field để điều hướng LLM.
from pydantic import BaseModel, Field
from custom_langchain_model import extract_with_pydantic
class Invoice(BaseModel):
invoice_number: str = Field(description="Số hóa đơn")
total_amount: float = Field(description="Tổng tiền")
customer_name: str = Field(description="Tên khách hàng, hãy viết HOA")
result = extract_with_pydantic(
input_text="Hóa đơn #INV-2024-001 cho khách Nguyễn Văn A, tổng 5.500.000đ",
model_class=Invoice,
client_kwargs={
"base_url": "http://localhost:8000/v1",
"api_key": "sk-...",
"model": "qwen3-vl"
}
)
print(result.extracted["customer_name"]) # "NGUYỄN VĂN A"
Lưu ý: Sử dụng client_kwargs để override cấu hình client (base_url, api_key, model) thay vì dùng file .env.
3. ChatBaml với LangChain
import os
from dotenv import load_dotenv
from custom_langchain_model import ChatBaml
load_dotenv()
chat = ChatBaml(
base_url=os.getenv("OPENAI_BASE_URL"),
api_key=os.getenv("OPENAI_API_KEY"),
model=os.getenv("OPENAI_MODEL_NAME"),
temperature=0.7,
streaming=True,
)
# Basic invoke
from langchain_core.messages import HumanMessage, SystemMessage
response = chat.invoke([
SystemMessage(content="Bạn là trợ lý hữu ích."),
HumanMessage(content="2 + 2 bằng mấy?"),
])
print(response.content)
# Streaming
for chunk in chat.stream([HumanMessage(content="Kể tên 3 thủ đô châu Á.")]):
print(chunk.content, end="", flush=True)
Bind tools
from pydantic import BaseModel, Field
from custom_langchain_model import ChatBaml
class SearchWeb(BaseModel):
"""Tìm kiếm thông tin trên internet."""
query: str = Field(description="Từ khóa tìm kiếm")
class Calculator(BaseModel):
"""Tính toán biểu thức số học."""
expression: str = Field(description="Biểu thức cần tính, ví dụ: '2 + 3 * 4'")
chat = ChatBaml(model="qwen3-vl", streaming=True)
chat_with_tools = chat.bind_tools([SearchWeb, Calculator])
response = chat_with_tools.invoke([
HumanMessage(content="Tìm kiếm về LangChain trên internet")
])
if response.tool_calls:
tool_call = response.tool_calls[0]
print(f"Tool: {tool_call['name']}")
print(f"Args: {tool_call['args']}")
4. React Agent
# Chạy LangGraph dev server
langgraph dev
# Hoặc F5 trong VSCode (cần .vscode/launch.json)
# react_agent/agent.py
from langchain.agents import create_agent
from custom_langchain_model import ChatBaml
from react_agent.tools import add, multiply
from langchain_community.tools import DuckDuckGoSearchRun
chat_baml = ChatBaml(
base_url=os.getenv("OPENAI_BASE_URL"),
api_key=os.getenv("OPENAI_API_KEY"),
model=os.getenv("OPENAI_MODEL_NAME"),
streaming=True,
temperature=0.7,
)
agent = create_agent(
chat_baml,
tools=[add, multiply, DuckDuckGoSearchRun()],
system_prompt="You are a helpful assistant with math and search tools.",
)
5. Tool Definition
Pydantic BaseModel (recommended)
from pydantic import BaseModel, Field
class AddTool(BaseModel):
"""Cộng hai số nguyên."""
a: int = Field(..., description="Số thứ nhất")
b: int = Field(..., description="Số thứ hai")
class SearchTool(BaseModel):
"""Tìm kiếm thông tin."""
query: str = Field(..., description="Từ khóa tìm kiếm")
max_results: int = Field(default=5, description="Số kết quả tối đa")
LangChain @tool (cần parse_docstring=True)
from langchain.tools import tool
@tool(parse_docstring=True)
def get_weather(city: str, unit: str = "celsius") -> str:
"""Lấy thông tin thời tiết hiện tại của một thành phố.
Args:
city (str): Tên thành phố.
unit (str): Đơn vị nhiệt độ, "celsius" hoặc "fahrenheit".
Returns:
str: Thông tin thời tiết dạng text.
"""
return f"Thời tiết tại {city}: 28°C, nhiều mây"
Lưu ý:
@toolphải có docstring đầy đủArgs:vàReturns:sections. Thiếu sẽ gây lỗi khi convert sang BAML schema.
BAML Functions
| Function | Input | Output | Dùng khi |
|---|---|---|---|
Chat |
BamlState |
string |
Chat thông thường, không có tools |
ChooseTool |
BamlState + TypeBuilder |
string | DynamicSchema |
Agent cần chọn và gọi tools |
ExtractStructure |
system_instruction?, prefix?, input |
DynamicSchema |
Trích xuất structured data từ text |
ExtractStructure chi tiết
function ExtractStructure(
system_instruction: string?, // null → dùng default instruction
prefix: string?, // null → không có prefix trong output format
input: string // text cần extract (bắt buộc)
) -> DynamicSchema
Cách BAML render prompt:
system_instruction | default(...)→ fallback về default nếu null{% if prefix %}→ chỉ thêm prefix vàoctx.output_formatkhi có giá trịDynamicSchemađược define lúc runtime quaTypeBuilder(truyền vàobaml_options={"tb": tb})
API Reference
get_baml_client(*, model, api_key, base_url, **kwargs)
Trả về BAML client đã authenticated. Không cần tạo ChatBaml.
from custom_langchain_model import get_baml_client
b = get_baml_client()
extract_with_pydantic(input_text, model_class, client_kwargs=None, ...)
Extraction với Pydantic model làm schema. Hỗ trợ client_kwargs để cấu hình client.
from custom_langchain_model import extract_with_pydantic
result = extract_with_pydantic("text...", MyModel, client_kwargs={"model": "gpt-4o"})
ChatBaml
LangChain BaseChatModel backed by BAML. Hỗ trợ .invoke(), .stream(), .bind_tools().
from custom_langchain_model import ChatBaml
chat = ChatBaml(model="qwen3-vl", streaming=True)
References
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 custom_langchain_model-0.2.0.tar.gz.
File metadata
- Download URL: custom_langchain_model-0.2.0.tar.gz
- Upload date:
- Size: 40.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b53028d5a0ef2ba27b9b45353f30111027ef9f55dc8abe9df75c5f2f4e43d85
|
|
| MD5 |
ba813e44d801a693ab8bdf3936e6530f
|
|
| BLAKE2b-256 |
50726711a475f8552ebd5c099f8f3f75de7b2de56d48182b7d853613c71256a3
|
File details
Details for the file custom_langchain_model-0.2.0-py3-none-any.whl.
File metadata
- Download URL: custom_langchain_model-0.2.0-py3-none-any.whl
- Upload date:
- Size: 42.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11747f71606c8320b9774c05b4f70b65114be4b758cf4b6370505fbdd59b512a
|
|
| MD5 |
1f59dcec978837260e7e556f25487dbd
|
|
| BLAKE2b-256 |
d9387cbed5deffcf637db73d1a82006c966af1809c9ced9a3a9ce82d4f520a04
|