Skip to content

LangChain Integration

Anvil provides seamless integration with LangChain through the to_langchain() adapter.

Terminal window
pip install "anvil-agent[langchain]"
from anvil import Anvil
from langchain_anthropic import ChatAnthropic
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
# Create Anvil tools
anvil = Anvil()
search = anvil.use_tool(
name="web_search",
intent="Search the web for current information"
)
weather = anvil.use_tool(
name="get_weather",
intent="Get current weather for a location"
)
# Convert to LangChain tools
lc_tools = [
search.to_langchain(),
weather.to_langchain(),
]
# Create LangChain agent
llm = ChatAnthropic(model="claude-sonnet-4-20250514")
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
agent = create_tool_calling_agent(llm, lc_tools, prompt)
executor = AgentExecutor(agent=agent, tools=lc_tools)
# Run
result = executor.invoke({"input": "What's the weather in Tokyo?"})
print(result["output"])

The to_langchain() method:

  1. Creates a BaseTool subclass
  2. Sets name from your tool name
  3. Sets description from your intent
  4. Generates a Pydantic args_schema from your inputs
  5. Wraps the run() method for execution
# Anvil tool
tool = anvil.use_tool(
name="search_docs",
intent="Search documentation for answers",
inputs=[
InputParam(name="query", param_type="str", required=True),
InputParam(name="limit", param_type="int", default=10),
]
)
# Converts to approximately:
class SearchDocsInput(BaseModel):
query: str
limit: int = 10
class SearchDocsTool(BaseTool):
name = "search_docs"
description = "Search documentation for answers"
args_schema = SearchDocsInput
def _run(self, query: str, limit: int = 10) -> Any:
return anvil_tool.run(query=query, limit=limit)
async def _arun(self, query: str, limit: int = 10) -> Any:
return await anvil_tool.run_async(query=query, limit=limit)

Define explicit inputs for better type safety:

from anvil import Anvil, InputParam
anvil = Anvil()
calculator = anvil.use_tool(
name="calculator",
intent="Perform mathematical calculations",
inputs=[
InputParam(
name="expression",
param_type="str",
required=True,
description="Mathematical expression to evaluate"
),
InputParam(
name="precision",
param_type="int",
required=False,
default=2,
description="Decimal places for the result"
),
]
)
lc_tool = calculator.to_langchain()
# LangChain will validate inputs against the schema

For more control, use the structured tool variant:

from anvil.adapters.langchain import to_langchain_structured_tool
structured_tool = to_langchain_structured_tool(calculator)

This creates a StructuredTool instead of a BaseTool subclass.

Use Anvil tools in LangChain Expression Language chains:

from langchain_core.runnables import RunnablePassthrough
# Create tools
research = anvil.use_tool(name="research", intent="Research a topic")
summarize = anvil.use_tool(name="summarize", intent="Summarize text")
# Build chain
chain = (
{"topic": RunnablePassthrough()}
| research.to_langchain()
| summarize.to_langchain()
)
result = chain.invoke("quantum computing")

LangChain tools support async execution:

import asyncio
async def main():
lc_tool = search.to_langchain()
# Async invocation
result = await lc_tool.ainvoke({"query": "AI news"})
print(result)
asyncio.run(main())

Errors from Anvil tools propagate to LangChain:

try:
result = executor.invoke({"input": "Search for something"})
except Exception as e:
print(f"Tool failed: {e}")

With self-healing enabled, Anvil will attempt to fix the tool before the error reaches LangChain.

Create multiple tools efficiently:

tools_config = [
("web_search", "Search the web"),
("calculator", "Perform calculations"),
("file_reader", "Read file contents"),
]
lc_tools = []
for name, intent in tools_config:
tool = anvil.use_tool(name=name, intent=intent)
lc_tools.append(tool.to_langchain())
# Use all tools with an agent
executor = AgentExecutor(agent=agent, tools=lc_tools)

Anvil types map to Python types in the Pydantic schema:

Anvil TypePython Type
strstr
intint
floatfloat
boolbool
listlist