LangChain (Python)
The langchain-ferrolabsai package is the first-party LangChain Python integration for Ferro Labs AI Gateway. It ships three classes โ FerroChatModel, FerroEmbeddings, FerroLLM โ that talk to any of the gateway's 30+ providers by model name, with every response surfacing the Ferro trace_id, provider, cost_usd, and latency_ms on response_metadata.
Installโ
pip install langchain-ferrolabsai
This pulls in ferrolabsai>=0.1.0 and langchain-core>=0.3.0 transitively.
Chatโ
from langchain_ferrolabsai import FerroChatModel
from langchain_core.messages import HumanMessage
chat = FerroChatModel(
model="gpt-4o",
base_url="http://localhost:8080", # any Ferro gateway endpoint
api_key="sk-ferro-...",
)
response = chat.invoke([HumanMessage(content="Hello, world")])
print(response.content)
print(response.response_metadata["provider"]) # which provider handled it
print(response.response_metadata["cost_usd"]) # cost of this request
print(response.response_metadata["trace_id"]) # x-trace-id header value
Swap providers without changing the class โ the gateway auto-routes by model name:
claude = FerroChatModel(model="claude-3-5-sonnet-20241022", base_url="...", api_key="...")
gemini = FerroChatModel(model="gemini-1.5-flash", base_url="...", api_key="...")
Streamingโ
for chunk in chat.stream([HumanMessage(content="Tell me a story")]):
print(chunk.content, end="", flush=True)
Tool callingโ
bind_tools() accepts LangChain tools, Pydantic models, raw OpenAI schemas, or @tool-decorated functions:
from langchain_core.tools import tool
@tool
def add(a: int, b: int) -> int:
"""Add two integers."""
return a + b
agent_chat = chat.bind_tools([add])
result = agent_chat.invoke([HumanMessage(content="what is 4 + 7?")])
print(result.tool_calls)
# [{'id': 'call_1', 'name': 'add', 'args': {'a': 4, 'b': 7}, 'type': 'tool_call'}]
Embeddingsโ
from langchain_ferrolabsai import FerroEmbeddings
embed = FerroEmbeddings(model="text-embedding-3-small", base_url="...", api_key="...")
vectors = embed.embed_documents(["hello", "world"])
query_vec = embed.embed_query("hello")
Swap embedding providers the same way you swap chat models โ model="voyage-3", model="cohere.embed-english-v3", model="text-embedding-3-large" all just work.
Legacy LLM interfaceโ
For chains still built on the old completion-style LLM:
from langchain_ferrolabsai import FerroLLM
llm = FerroLLM(model="gpt-4o", base_url="...", api_key="...")
print(llm.invoke("Write a haiku about gateways"))
Why use this instead of ChatOpenAI(base_url=...)?โ
ChatOpenAI pointed at a Ferro gateway works as a drop-in for chat. langchain-ferrolabsai adds:
- First-class metadata.
provider,cost_usd,latency_ms,trace_id,cache_hitarrive on everyresponse_metadataโ no header parsing required. - Ferro extras as fields.
route_tag,template_id,template_variables, anduserare typed constructor arguments, not magic strings. - One join key. The
trace_idis the link to whichever observability backend you bridge the gateway to โ LangSmith, Langfuse, Phoenix, Datadog. See LangSmith for the full story.
Verify the gateway is reachableโ
curl http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer sk-ferro-..." \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o","messages":[{"role":"user","content":"hi"}]}' | jq '.choices[0].message.content'
Runnable exampleโ
ai-gateway-cookbook/python/02-langgraph-multi-provider-agent โ a LangGraph agent that routes its planner / coder / summarizer nodes to three different best-in-class providers (GPT-4o, Claude 3.5 Sonnet, Gemini 1.5 Flash) through one gateway, with trace_id printed at each step.
git clone https://github.com/ferro-labs/ai-gateway-cookbook
cd ai-gateway-cookbook/python/02-langgraph-multi-provider-agent
cp .env.example .env
make run
What's nextโ
- Async surfaces (
_agenerate,_astream,aembed_documents) โ planned forlangchain-ferrolabsai 0.2.0. with_structured_output()โ planned for0.2.0.- Streaming tool-call reassembly โ planned for
0.2.0.
Track progress in the CHANGELOG.
See alsoโ
- LangGraph โ agentic state machines that span multiple providers
- LangSmith โ turn the Ferro
trace_idinto LangSmith runs - Python SDK quickstart โ the underlying
ferrolabsaiclient