本页还没有译文
本页 36 段还没译成日本語,下面显示的是英文原文。TypeSafe integrations
还没翻译译自英文(docs.langchain.com)本页 36 段都还没译
Jev is a System One model that reads natural language but returns typed answers and calibrated probabilities instead of generated text.
TypeSafeClassifier exposes these decisions as a LangChain Runnable, so you can invoke, batch, or compose them with other runnables. It accepts strings, structured JSON, and LangChain message objects, and records traces and token usage in LangSmith. Use it for focused decisions such as routing a request, choosing a model, or checking whether a tool call is safe to run.
Use TypeSafe decisions in LangChain middleware to control create_agent behavior at specific lifecycle points, including with custom middleware that classifies agent state. See Agent middleware for examples.
Setup
uvpip
uv add langchain-typesafepip install langchain-typesafeCreate an API key in the TypeSafe console and export it:
export TYPESAFE_API_KEY=...Note
Optional: Set TYPESAFE_BASE_URL to use a compatible gateway, test server, or private deployment. The default is https://api.typesafe.ai.
export TYPESAFE_BASE_URL=https://gateway.example.comQuickstart
Create a TypeSafeClassifier, then pass the state and named questions together in each invocation. Questions that share state are evaluated independently and in parallel in one request:
Note
Earlier versions configured questions on TypeSafeClassifier and passed only the state to invoke. Pass both state and questions to invoke now.
from langchain_typesafe import Choice, Noul, Score, TypeSafeClassifier
classifier = TypeSafeClassifier()
response = classifier.invoke(
{
"state": (
"The deploy failed twice and customers are seeing 500s. "
"Can someone look now?"
),
"questions": {
"urgent": Noul(instructions="Does this need attention right now?"),
"team": Choice(
instructions="Which team should pick this up?",
criteria={
"infra": "Deploys, availability, and on-call incidents.",
"billing": "Payments, invoices, and subscriptions.",
},
),
"severity": Score(
instructions="How severe is the impact?",
criteria=["Cosmetic.", "Degraded for some users.", "Full outage."],
),
},
}
)
print(response.nouls["urgent"].noul)
print(response.choices["team"].choice, response.choices["team"].confidence)
print(response.scores["severity"].score)Answers are keyed by the question IDs you supplied, and grouped by type on nouls, choices, and scores. The response also carries the model that answered, token usage, and the TypeSafe request_id.
The request state can be a string, a JSON object or array, or LangChain messages. A BaseMessage or a sequence of messages is converted to role/content JSON, including when nested inside a larger object.
Decision types
Each question is one of three primitives:
| Primitive | Asks | Returns | Reach for it when |
|---|---|---|---|
Noul | Is this true? | noul, the probability of yes | Your code branches on an if |
Choice | Which of these options? | choice, plus probabilities and confidence | Options map to distinct code paths |
Score | Which level? | score, plus legend, probabilities, and confidence | The answer is a spectrum you compare to a threshold |
Noul is the only one without a confidence, since the probability is the answer. Use Score rather than a Noul for a spectrum: a Noul of 0.5 means an even split between yes and no, not "medium".
Agent middleware
The package includes two experimental middleware that put the classifier on an agent's decision points. Import them from langchain_typesafe.experimental.middleware.
Note
The middleware are experimental and require langchain-typesafe[experimental]. Their APIs may change without notice.
The examples below use OpenAI models. Install the experimental extra and the OpenAI integration before using them:
uvpip
uv add "langchain-typesafe[experimental]" langchain-openaipip install "langchain-typesafe[experimental]" langchain-openai| Middleware | Hook | Decision |
|---|---|---|
ModelRouterMiddleware | before_agent, wrap_model_call | Which model handles the run |
AutoModeMiddleware | wrap_tool_call | Whether a tool call is too risky to run |
Model routing
Classifies the latest human message across your named models and uses the selected one for every model call in the run. Each ModelChoice pairs a model with the criterion for picking it:
from langchain.agents import create_agent
from langchain_typesafe.experimental.middleware import (
ModelChoice,
ModelRouterMiddleware,
)
router = ModelRouterMiddleware(
choices={
"fast": ModelChoice(
model="openai:gpt-5.6-terra",
criteria="Direct lookups, extraction, and localized changes with explicit targets.",
),
"powerful": ModelChoice(
model="openai:gpt-6-astra",
criteria="Architecture, novel root-cause reasoning, and high-stakes decisions.",
),
},
instructions="Choose the least costly model that can complete the task safely.",
)
agent = create_agent("openai:gpt-5.6-terra", middleware=[router])
result = agent.invoke(
{
"messages": [
{
"role": "user",
"content": "Prove that there are infinitely many prime numbers.",
}
]
}
)
print(result["model_route"].choice)Tool-risk gating
Asks for the probability that a tool call is risky or insufficiently authorized. Calls that are determined risky return an error ToolMessage instead of running the tool. Only the tools you list are classified. Pass their names or tool objects:
from langchain.agents import create_agent
from langchain.messages import ToolMessage
from langchain.tools import tool
from langchain_typesafe import NoulCriteria
from langchain_typesafe.experimental.middleware import AutoModeMiddleware
@tool
def delete_all_backups() -> str:
"""Delete every backup. This action cannot be undone."""
return "Backups deleted."
agent = create_agent(
"openai:gpt-6-astra",
tools=[delete_all_backups],
middleware=[AutoModeMiddleware(tools=[delete_all_backups])],
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "Delete all backups."}]}
)
print(result["messages"][-1].content)Override instructions, or pass criteria=NoulCriteria(true=..., false=...), to describe risk for your own tools.
Warning
Do not put secrets in tool arguments or conversation state unless sending them to TypeSafe is acceptable. This middleware refuses risky calls. It does not request approval. Pair it with human-in-the-loop middleware when you want a person to approve them.
Custom middleware
TypeSafeClassifier accepts LangChain message objects directly, so a custom middleware hook can classify an agent's conversation state without converting it first. This example classifies the conversation once at the start of each run and stores the complete ChoiceAnswer in agent state:
from langchain.agents import create_agent
from langchain.agents.middleware import AgentMiddleware, AgentState, Runtime
from langchain_typesafe import Choice, ChoiceAnswer, TypeSafeClassifier
from typing_extensions import NotRequired
class TriageState(AgentState):
triage: NotRequired[ChoiceAnswer]
class TriageMiddleware(AgentMiddleware[TriageState]):
state_schema = TriageState
def __init__(self) -> None:
self.classifier = TypeSafeClassifier()
def before_agent(
self, state: TriageState, runtime: Runtime
) -> dict[str, ChoiceAnswer]:
response = self.classifier.invoke(
{
"state": state["messages"],
"questions": {
"triage": Choice(
instructions="Which team should handle this conversation?",
criteria={
"billing": "Payments, invoices, and subscriptions.",
"infra": "Deploys, availability, and incidents.",
"other": "Requests that belong to another team.",
},
)
},
}
)
return {"triage": response.choices["triage"]}
agent = create_agent(
"openai:gpt-5.6-terra",
middleware=[TriageMiddleware()],
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "Customers are seeing 500 errors."}]}
)
print(result["triage"].choice, result["triage"].confidence)Use any lifecycle hook that matches your decision point. For example, use before_model to reclassify after each tool result, or wrap_tool_call to classify a proposed action. See Custom middleware for all hooks and state patterns.
Tracing
TypeSafe classifications are traced in LangSmith, so you can inspect decisions, token usage, and spend alongside the rest of your agent.