Framework Adapters
Adapters map a framework-specific agent to an EntroPy-instrumentable
callable returning an AgentRun. They import their target
framework lazily, so
import entropy works even when none are installed.
Every adapter exposes a from_* helper and is also reachable
through automatic routing with find_adapter:
from entropy import (from_langchain, from_langgraph, from_openai,
from_crewai, from_pydanticai, from_autogen,
from_google_adk, from_mcp, from_custom, find_adapter)
runnable = from_langchain(my_langchain_agent) # now a callable -> AgentRun
runnable = find_adapter(my_langchain_agent)() # auto-detect the framework
| Helper | Framework | Extra |
|---|---|---|
from_langchain | LangChain | langchain |
from_langgraph | LangGraph | langgraph |
from_openai | OpenAI Agents | openai |
from_crewai | CrewAI | crewai |
from_pydanticai | PydanticAI | pydanticai |
from_autogen | AutoGen | autogen |
from_google_adk | Google ADK | google-adk |
from_mcp | MCP | mcp |
from_custom | Your own wrapper | — |
Code per framework
Each snippet below builds a minimal agent, wraps it with the matching adapter, and runs a Monte Carlo evaluation. Wrap the call in a small retry helper if your model is flaky (local GPU models sometimes 500).
LangChain
from langchain_core.runnables import RunnableLambda
from entropy import from_langchain, Suite, Dataset, Case
agent = RunnableLambda(lambda x: {"output": x["input"] + "!"})
wrapped = from_langchain(agent)
results = Suite(seed=42).run(
wrapped, Dataset([Case(input="hi", expected="hi!")]), trials=100,
)
print(results["success_rate"], results["behavioral_entropy"])
LangGraph / create_agent
from langchain.agents import create_agent
from langchain_core.tools import tool
from langchain_ollama import ChatOllama
from entropy import from_langgraph, Suite, Dataset, Case
@tool
def get_weather(city: str) -> str:
"""Return a canned weather report for a city."""
return f"It is sunny in {city}."
agent = create_agent(ChatOllama(model="minimax-m3:cloud", temperature=0.0),
tools=[get_weather],
system_prompt="You are a helpful assistant. Answer concisely.")
wrapped = from_langgraph(agent) # create_agent -> CompiledStateGraph
results = Suite(seed=42).run(
wrapped,
Dataset([Case(input="weather in Paris?",
check=lambda o: "sunny" in (o or "").lower())]),
trials=10,
)
create_agent returns a CompiledStateGraph
whose result is {"messages": [...]} (no "output" key)
and expects {"messages": [HumanMessage(...)]} as input. The
adapter handles both shapes automatically.
OpenAI Agents SDK
from agents import Agent
from entropy import from_openai, Suite, Dataset, Case
agent = Agent(name="assistant", instructions="You are helpful.")
wrapped = from_openai(agent)
results = Suite(seed=42).run(
wrapped, Dataset([Case(input="hi", expected="hi")]), trials=10,
)
CrewAI
from crewai import Agent, Task, Crew
from entropy import from_crewai, Suite, Dataset, Case
researcher = Agent(role="researcher", goal="answer questions", backstory="expert")
task = Task(description="Answer the user: {input}", agent=researcher)
crew = Crew(agents=[researcher], tasks=[task])
wrapped = from_crewai(crew)
results = Suite(seed=42).run(
wrapped, Dataset([Case(input="What is 2+2?")]), trials=10,
)
PydanticAI
from pydantic_ai import Agent
from entropy import from_pydanticai, Suite, Dataset, Case
agent = Agent("openai:gpt-4o", instructions="Be helpful.")
wrapped = from_pydanticai(agent)
results = Suite(seed=42).run(
wrapped, Dataset([Case(input="hi")]), trials=10,
)
AutoGen
from autogen import ConversableAgent
from entropy import from_autogen, Suite, Dataset, Case
agent = ConversableAgent("bot", llm_config={"config_list": [...]})
wrapped = from_autogen(agent)
results = Suite(seed=42).run(
wrapped, Dataset([Case(input="hi")]), trials=10,
)
Google ADK
from google.adk.agents import LlmAgent
from entropy import from_google_adk, Suite, Dataset, Case
agent = LlmAgent(model="gemini-2.0-flash", name="assistant",
instruction="Be helpful.")
wrapped = from_google_adk(agent)
results = Suite(seed=42).run(
wrapped, Dataset([Case(input="hi")]), trials=10,
)
MCP
from mcp import ClientSession
from entropy import from_mcp, Suite, Dataset, Case
# `session` is an already-connected MCP ClientSession
wrapped = from_mcp(session, tool="run")
results = Suite(seed=42).run(
wrapped, Dataset([Case(input="hi")]), trials=10,
)
Your own agent (custom)
from entropy import from_custom, Suite, Dataset, Case
def my_agent(inp):
return "echo: " + inp
wrapped = from_custom(my_agent)
results = Suite(seed=42).run(
wrapped, Dataset([Case(input="hi", expected="echo: hi")]), trials=100,
)
Discovery & custom adapters
List registered adapters, or build your own with the
@adapter decorator (see Plugins):
from entropy import list_adapters, find_adapter, adapter, Adapter
print(list_adapters())
@adapter("myfw")
class MyAdapter(Adapter):
def match(self, agent): return hasattr(agent, "run_myfw")
def wrap(self, agent):
def call(inp):
res = agent.run_myfw(inp)
from entropy import AgentRun
return AgentRun(run_id="", input=inp, output=res)
return call