Research reportai-agents
Using LangChain tools inside CrewAI agents: a working guide
CrewAI and LangChain are usually pitched as rivals. Their own docs disagree — the verified, working pattern for wrapping a LangChain tool for a CrewAI agent.
Most “CrewAI vs LangChain” content treats the two as an either/or choice. CrewAI’s own documentation disagrees: it ships a built-in wrapper, LangChainTool, specifically so a CrewAI agent can call any tool from LangChain’s tool ecosystem. You don’t have to pick one framework’s orchestration model and give up the other’s integrations — you can run CrewAI’s role-based crews on top of LangChain’s tool library. Below is the pattern straight from CrewAI’s own docs, verified live on 21 July 2026, plus the gotcha that trips people up.
Why anyone would combine them
CrewAI and LangChain solve different halves of the same problem. CrewAI’s pitch is orchestration: define agents with roles, goals and tools, and let them collaborate as a “crew,” with Flows for tighter event-driven control when you need it. LangChain’s pitch is breadth: its own listing describes “unmatched integration ecosystem and community” — connectors for search APIs, vector stores, SQL databases and hundreds of other services, built up over several years as the default place new integrations land first.
That split is exactly why CrewAI’s docs treat LangChain as a tool source rather than a competing runtime: “CrewAI seamlessly integrates with LangChain’s comprehensive list of tools, all of which can be used with CrewAI.” If you like CrewAI’s crew model but need a LangChain-only integration — a specific vector store client, a niche search API wrapper — you don’t have to rewrite it from scratch or switch frameworks. Our own CrewAI vs LangChain comparison covers the head-to-head choice; this guide is for the case where the honest answer is “both.”
The pattern, from CrewAI’s own docs
CrewAI agents don’t accept a raw LangChain tool object directly — they expect a BaseTool subclass with a name, a description, and a typed input (CrewAI’s own custom-tool docs use an args_schema: Type[BaseModel] for this). The documented fix is to wrap the LangChain tool or utility inside a small BaseTool subclass rather than pass it straight into an agent’s tools list. Here is CrewAI’s own worked example, wrapping LangChain’s GoogleSerperAPIWrapper:
import os
from dotenv import load_dotenv
from crewai import Agent, Task, Crew
from crewai.tools import BaseTool
from pydantic import Field
from langchain_community.utilities import GoogleSerperAPIWrapper
# Set up your SERPER_API_KEY key in an .env file, eg:
# SERPER_API_KEY=<your api key>
load_dotenv()
search = GoogleSerperAPIWrapper()
class SearchTool(BaseTool):
name: str = "Search"
description: str = "Useful for search-based queries. Use this to find current information about markets, companies, and trends."
search: GoogleSerperAPIWrapper = Field(default_factory=GoogleSerperAPIWrapper)
def _run(self, query: str) -> str:
"""Execute the search query and return results"""
try:
return self.search.run(query)
except Exception as e:
return f"Error performing search: {str(e)}"
# Create Agents
researcher = Agent(
role='Research Analyst',
goal='Gather current market data and trends',
backstory="""You are an expert research analyst with years of experience in
gathering market intelligence. You're known for your ability to find
relevant and up-to-date market information and present it in a clear,
actionable format.""",
tools=[SearchTool()],
verbose=True
)
The shape generalizes past search: take whatever LangChain utility or tool you want (a retriever, a database wrapper, a third-party API client), store it as a field on a BaseTool subclass, and call it from inside _run. CrewAI’s own tools reference also documents an LlamaIndexTool wrapper built on the identical idea, so the same pattern carries over if you’re pulling a tool from LlamaIndex instead.
What you actually need installed
Two package families, not one:
crewaiandcrewai-toolsfor the agent/crew runtime and CrewAI’s own tool base classes.- The specific LangChain package that owns the utility you want — in the example above,
langchain-community(home toGoogleSerperAPIWrapperand most third-party integrations) pluspython-dotenvfor the.envkey. LangChain split most integrations into per-provider packages, so pulling in the wholelangchainmetapackage for one wrapper is usually more than you need.
The gotcha: schemas, not compatibility
The integration doesn’t fail because CrewAI and LangChain are incompatible — it fails, or silently misbehaves, when a raw LangChain tool’s input schema doesn’t match what a CrewAI agent expects to send it. LangChain tools were designed for LangChain’s own internal chains and agents, which don’t always pass arguments the same way CrewAI does. Wrapping the tool in your own BaseTool subclass — as the example above does — sidesteps this: you control the _run signature and can normalize whatever CrewAI’s agent passes in before handing it to the LangChain object. Skipping the wrapper and passing a LangChain tool straight into an agent’s tools=[] list is the shortcut that looks like it works in a five-line demo and then breaks the first time the agent sends an argument the LangChain tool wasn’t expecting.
When this is the wrong move
If your actual need is orchestration-only — you’re not reaching for any LangChain-specific integration — adding LangChain as a dependency just to get one tool it wraps around a public API is often not worth it; CrewAI’s own toolkit and the plain BaseTool pattern cover a lot of ground without the extra dependency surface. This pattern earns its keep specifically when the tool you need already has a mature LangChain integration and no CrewAI-native equivalent exists yet.
Sources
CrewAI’s LangChainTool documentation and tool-creation docs (both fetched live 21 July 2026) are the primary sources for the code and the schema behavior described above. Background on each framework’s own scope and pricing comes from our CrewAI and LangChain listings, re-verified the same day.