mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-03-31 16:18:14 +00:00
Compare commits
2 Commits
gl/refacto
...
docs/agent
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d6b4c47b6 | ||
|
|
3283a00e31 |
@@ -150,6 +150,7 @@
|
||||
"group": "Core Concepts",
|
||||
"pages": [
|
||||
"en/concepts/agents",
|
||||
"en/concepts/agent-capabilities",
|
||||
"en/concepts/tasks",
|
||||
"en/concepts/crews",
|
||||
"en/concepts/flows",
|
||||
|
||||
147
docs/en/concepts/agent-capabilities.mdx
Normal file
147
docs/en/concepts/agent-capabilities.mdx
Normal file
@@ -0,0 +1,147 @@
|
||||
---
|
||||
title: "Agent Capabilities"
|
||||
description: "Understand the five ways to extend CrewAI agents: Tools, MCPs, Apps, Skills, and Knowledge."
|
||||
icon: puzzle-piece
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
CrewAI agents can be extended with **five distinct capability types**, each serving a different purpose. Understanding when to use each one — and how they work together — is key to building effective agents.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Tools" icon="wrench" href="/en/concepts/tools" color="#3B82F6">
|
||||
**Callable functions** — give agents the ability to take action. Web searches, file operations, API calls, code execution.
|
||||
</Card>
|
||||
<Card title="MCP Servers" icon="plug" href="/en/mcp/overview" color="#8B5CF6">
|
||||
**Remote tool servers** — connect agents to external tool servers via the Model Context Protocol. Same effect as tools, but hosted externally.
|
||||
</Card>
|
||||
<Card title="Apps" icon="grid-2" color="#EC4899">
|
||||
**Platform integrations** — connect agents to SaaS apps (Gmail, Slack, Jira, Salesforce) via CrewAI's managed OAuth layer.
|
||||
</Card>
|
||||
<Card title="Skills" icon="bolt" href="/en/concepts/skills" color="#F59E0B">
|
||||
**Domain expertise** — inject instructions, guidelines, and reference material into agent prompts. Skills tell agents *how to think*.
|
||||
</Card>
|
||||
<Card title="Knowledge" icon="book" href="/en/concepts/knowledge" color="#10B981">
|
||||
**Retrieved facts** — provide agents with data from documents, files, and URLs via semantic search (RAG). Knowledge gives agents *what to know*.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
---
|
||||
|
||||
## The Key Distinction
|
||||
|
||||
The most important thing to understand: **these capabilities fall into two categories**.
|
||||
|
||||
### Action Capabilities (Tools, MCPs, Apps)
|
||||
|
||||
These give agents the ability to **do things** — call APIs, read files, search the web, send emails. At execution time, all three resolve into the same internal format (`BaseTool` instances) and appear in a unified tool list the agent can call.
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from crewai_tools import SerperDevTool, FileReadTool
|
||||
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Find and compile market data",
|
||||
backstory="Expert market analyst",
|
||||
tools=[SerperDevTool(), FileReadTool()], # Local tools
|
||||
mcps=["https://mcp.example.com/sse"], # Remote MCP server tools
|
||||
apps=["gmail", "google_sheets"], # Platform integrations
|
||||
)
|
||||
```
|
||||
|
||||
### Context Capabilities (Skills, Knowledge)
|
||||
|
||||
These modify the agent's **prompt** — injecting expertise, instructions, or retrieved data before the agent starts reasoning. They don't give agents new actions; they shape how agents think and what information they have access to.
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
|
||||
agent = Agent(
|
||||
role="Security Auditor",
|
||||
goal="Audit cloud infrastructure for vulnerabilities",
|
||||
backstory="Expert in cloud security with 10 years of experience",
|
||||
skills=["./skills/security-audit"], # Domain instructions
|
||||
knowledge_sources=[pdf_source, url_source], # Retrieved facts
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## When to Use What
|
||||
|
||||
| You need... | Use | Example |
|
||||
| :------------------------------------------------ | :---------------- | :--------------------------------------- |
|
||||
| Agent to search the web | **Tools** | `tools=[SerperDevTool()]` |
|
||||
| Agent to call a remote API via MCP | **MCPs** | `mcps=["https://api.example.com/sse"]` |
|
||||
| Agent to send emails via Gmail | **Apps** | `apps=["gmail"]` |
|
||||
| Agent to follow specific procedures | **Skills** | `skills=["./skills/code-review"]` |
|
||||
| Agent to reference company docs | **Knowledge** | `knowledge_sources=[pdf_source]` |
|
||||
| Agent to search the web AND follow review guidelines | **Tools + Skills** | Use both together |
|
||||
|
||||
---
|
||||
|
||||
## Combining Capabilities
|
||||
|
||||
In practice, agents often use **multiple capability types together**. Here's a realistic example:
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from crewai_tools import SerperDevTool, FileReadTool, CodeInterpreterTool
|
||||
|
||||
# A fully-equipped research agent
|
||||
researcher = Agent(
|
||||
role="Senior Research Analyst",
|
||||
goal="Produce comprehensive market analysis reports",
|
||||
backstory="Expert analyst with deep industry knowledge",
|
||||
|
||||
# ACTION: What the agent can DO
|
||||
tools=[
|
||||
SerperDevTool(), # Search the web
|
||||
FileReadTool(), # Read local files
|
||||
CodeInterpreterTool(), # Run Python code for analysis
|
||||
],
|
||||
mcps=["https://data-api.example.com/sse"], # Access remote data API
|
||||
apps=["google_sheets"], # Write to Google Sheets
|
||||
|
||||
# CONTEXT: What the agent KNOWS
|
||||
skills=["./skills/research-methodology"], # How to conduct research
|
||||
knowledge_sources=[company_docs], # Company-specific data
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Comparison Table
|
||||
|
||||
| Feature | Tools | MCPs | Apps | Skills | Knowledge |
|
||||
| :--- | :---: | :---: | :---: | :---: | :---: |
|
||||
| **Gives agent actions** | ✅ | ✅ | ✅ | ❌ | ❌ |
|
||||
| **Modifies prompt** | ❌ | ❌ | ❌ | ✅ | ✅ |
|
||||
| **Requires code** | Yes | Config only | Config only | Markdown only | Config only |
|
||||
| **Runs locally** | Yes | Depends | No (AMP API) | N/A | Yes |
|
||||
| **Needs API keys** | Per tool | Per server | OAuth via AMP | No | Embedder only |
|
||||
| **Set on Agent** | `tools=[]` | `mcps=[]` | `apps=[]` | `skills=[]` | `knowledge_sources=[]` |
|
||||
| **Set on Crew** | ❌ | ❌ | ❌ | `skills=[]` | `knowledge_sources=[]` |
|
||||
|
||||
---
|
||||
|
||||
## Deep Dives
|
||||
|
||||
Ready to learn more about each capability type?
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Tools" icon="wrench" href="/en/concepts/tools">
|
||||
Create custom tools, use the 75+ OSS catalog, configure caching and async execution.
|
||||
</Card>
|
||||
<Card title="MCP Integration" icon="plug" href="/en/mcp/overview">
|
||||
Connect to MCP servers via stdio, SSE, or HTTP. Filter tools, configure auth.
|
||||
</Card>
|
||||
<Card title="Skills" icon="bolt" href="/en/concepts/skills">
|
||||
Build skill packages with SKILL.md, inject domain expertise, use progressive disclosure.
|
||||
</Card>
|
||||
<Card title="Knowledge" icon="book" href="/en/concepts/knowledge">
|
||||
Add knowledge from PDFs, CSVs, URLs, and more. Configure embedders and retrieval.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -1,27 +1,186 @@
|
||||
---
|
||||
title: Skills
|
||||
description: Filesystem-based skill packages that inject context into agent prompts.
|
||||
description: Filesystem-based skill packages that inject domain expertise and instructions into agent prompts.
|
||||
icon: bolt
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Skills are self-contained directories that provide agents with domain-specific instructions, references, and assets. Each skill is defined by a `SKILL.md` file with YAML frontmatter and a markdown body.
|
||||
Skills are self-contained directories that provide agents with **domain-specific instructions, guidelines, and reference material**. Each skill is defined by a `SKILL.md` file with YAML frontmatter and a markdown body.
|
||||
|
||||
Skills use **progressive disclosure** — metadata is loaded first, full instructions only when activated, and resource catalogs only when needed.
|
||||
When activated, a skill's instructions are injected directly into the agent's task prompt — giving the agent expertise without requiring any code changes.
|
||||
|
||||
## Directory Structure
|
||||
<Note type="info" title="Skills vs Tools — The Key Distinction">
|
||||
**Skills are NOT tools.** This is the most common point of confusion.
|
||||
|
||||
- **Skills** inject *instructions and context* into the agent's prompt. They tell the agent *how to think* about a problem.
|
||||
- **Tools** give the agent *callable functions* to take action (search, read files, call APIs).
|
||||
|
||||
You often need **both**: skills for expertise, tools for action. They are configured independently and complement each other.
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Create a Skill Directory
|
||||
|
||||
```
|
||||
my-skill/
|
||||
├── SKILL.md # Required — frontmatter + instructions
|
||||
├── scripts/ # Optional — executable scripts
|
||||
├── references/ # Optional — reference documents
|
||||
└── assets/ # Optional — static files (configs, data)
|
||||
skills/
|
||||
└── code-review/
|
||||
├── SKILL.md # Required — instructions
|
||||
├── references/ # Optional — reference docs
|
||||
│ └── style-guide.md
|
||||
└── scripts/ # Optional — executable scripts
|
||||
```
|
||||
|
||||
The directory name must match the `name` field in `SKILL.md`.
|
||||
### 2. Write Your SKILL.md
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: code-review
|
||||
description: Guidelines for conducting thorough code reviews with focus on security and performance.
|
||||
metadata:
|
||||
author: your-team
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
## Code Review Guidelines
|
||||
|
||||
When reviewing code, follow this checklist:
|
||||
|
||||
1. **Security**: Check for injection vulnerabilities, auth bypasses, and data exposure
|
||||
2. **Performance**: Look for N+1 queries, unnecessary allocations, and blocking calls
|
||||
3. **Readability**: Ensure clear naming, appropriate comments, and consistent style
|
||||
4. **Testing**: Verify adequate test coverage for new functionality
|
||||
|
||||
### Severity Levels
|
||||
- **Critical**: Security vulnerabilities, data loss risks → block merge
|
||||
- **Major**: Performance issues, logic errors → request changes
|
||||
- **Minor**: Style issues, naming suggestions → approve with comments
|
||||
```
|
||||
|
||||
### 3. Attach to an Agent
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from crewai_tools import GithubSearchTool, FileReadTool
|
||||
|
||||
reviewer = Agent(
|
||||
role="Senior Code Reviewer",
|
||||
goal="Review pull requests for quality and security issues",
|
||||
backstory="Staff engineer with expertise in secure coding practices.",
|
||||
skills=["./skills"], # Injects review guidelines
|
||||
tools=[GithubSearchTool(), FileReadTool()], # Lets agent read code
|
||||
)
|
||||
```
|
||||
|
||||
The agent now has both **expertise** (from the skill) and **capabilities** (from the tools).
|
||||
|
||||
---
|
||||
|
||||
## Skills + Tools: Working Together
|
||||
|
||||
Here are common patterns showing how skills and tools complement each other:
|
||||
|
||||
### Pattern 1: Skills Only (Domain Expertise, No Actions Needed)
|
||||
|
||||
Use when the agent needs specific instructions but doesn't need to call external services:
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Technical Writer",
|
||||
goal="Write clear API documentation",
|
||||
backstory="Expert technical writer",
|
||||
skills=["./skills/api-docs-style"], # Writing guidelines and templates
|
||||
# No tools needed — agent writes based on provided context
|
||||
)
|
||||
```
|
||||
|
||||
### Pattern 2: Tools Only (Actions, No Special Expertise)
|
||||
|
||||
Use when the agent needs to take action but doesn't need domain-specific instructions:
|
||||
|
||||
```python
|
||||
from crewai_tools import SerperDevTool, ScrapeWebsiteTool
|
||||
|
||||
agent = Agent(
|
||||
role="Web Researcher",
|
||||
goal="Find information about a topic",
|
||||
backstory="Skilled at finding information online",
|
||||
tools=[SerperDevTool(), ScrapeWebsiteTool()], # Can search and scrape
|
||||
# No skills needed — general research doesn't need special guidelines
|
||||
)
|
||||
```
|
||||
|
||||
### Pattern 3: Skills + Tools (Expertise AND Actions)
|
||||
|
||||
The most common real-world pattern. The skill provides *how* to approach the work; tools provide *what* the agent can do:
|
||||
|
||||
```python
|
||||
from crewai_tools import SerperDevTool, FileReadTool, CodeInterpreterTool
|
||||
|
||||
analyst = Agent(
|
||||
role="Security Analyst",
|
||||
goal="Audit infrastructure for vulnerabilities",
|
||||
backstory="Expert in cloud security and compliance",
|
||||
skills=["./skills/security-audit"], # Audit methodology and checklists
|
||||
tools=[
|
||||
SerperDevTool(), # Research known vulnerabilities
|
||||
FileReadTool(), # Read config files
|
||||
CodeInterpreterTool(), # Run analysis scripts
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
### Pattern 4: Skills + MCPs
|
||||
|
||||
Skills work alongside MCP servers the same way they work with tools:
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Data Analyst",
|
||||
goal="Analyze customer data and generate reports",
|
||||
backstory="Expert data analyst with strong statistical background",
|
||||
skills=["./skills/data-analysis"], # Analysis methodology
|
||||
mcps=["https://data-warehouse.example.com/sse"], # Remote data access
|
||||
)
|
||||
```
|
||||
|
||||
### Pattern 5: Skills + Apps
|
||||
|
||||
Skills can guide how an agent uses platform integrations:
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Customer Support Agent",
|
||||
goal="Respond to customer inquiries professionally",
|
||||
backstory="Experienced support representative",
|
||||
skills=["./skills/support-playbook"], # Response templates and escalation rules
|
||||
apps=["gmail", "zendesk"], # Can send emails and update tickets
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Crew-Level Skills
|
||||
|
||||
Skills can be set on a crew to apply to **all agents**:
|
||||
|
||||
```python
|
||||
from crewai import Crew
|
||||
|
||||
crew = Crew(
|
||||
agents=[researcher, writer, reviewer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
skills=["./skills"], # All agents get these skills
|
||||
)
|
||||
```
|
||||
|
||||
Agent-level skills take priority — if the same skill is discovered at both levels, the agent's version is used.
|
||||
|
||||
---
|
||||
|
||||
## SKILL.md Format
|
||||
|
||||
@@ -34,7 +193,7 @@ compatibility: crewai>=0.1.0 # optional
|
||||
metadata: # optional
|
||||
author: your-name
|
||||
version: "1.0"
|
||||
allowed-tools: web-search file-read # optional, space-delimited
|
||||
allowed-tools: web-search file-read # optional, experimental
|
||||
---
|
||||
|
||||
Instructions for the agent go here. This markdown body is injected
|
||||
@@ -43,57 +202,46 @@ into the agent's prompt when the skill is activated.
|
||||
|
||||
### Frontmatter Fields
|
||||
|
||||
| Field | Required | Constraints |
|
||||
| Field | Required | Description |
|
||||
| :-------------- | :------- | :----------------------------------------------------------------------- |
|
||||
| `name` | Yes | 1–64 chars. Lowercase alphanumeric and hyphens. No leading/trailing/consecutive hyphens. Must match directory name. |
|
||||
| `name` | Yes | 1–64 chars. Lowercase alphanumeric and hyphens. Must match directory name. |
|
||||
| `description` | Yes | 1–1024 chars. Describes what the skill does and when to use it. |
|
||||
| `license` | No | License name or reference to a bundled license file. |
|
||||
| `compatibility` | No | Max 500 chars. Environment requirements (products, packages, network). |
|
||||
| `metadata` | No | Arbitrary string key-value mapping. |
|
||||
| `allowed-tools` | No | Space-delimited list of pre-approved tools. Experimental. |
|
||||
|
||||
## Usage
|
||||
---
|
||||
|
||||
### Agent-level Skills
|
||||
## Directory Structure
|
||||
|
||||
Pass skill directory paths to an agent:
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Find relevant information",
|
||||
backstory="An expert researcher.",
|
||||
skills=["./skills"], # discovers all skills in this directory
|
||||
)
|
||||
```
|
||||
my-skill/
|
||||
├── SKILL.md # Required — frontmatter + instructions
|
||||
├── scripts/ # Optional — executable scripts
|
||||
├── references/ # Optional — reference documents
|
||||
└── assets/ # Optional — static files (configs, data)
|
||||
```
|
||||
|
||||
### Crew-level Skills
|
||||
The directory name must match the `name` field in `SKILL.md`. The `scripts/`, `references/`, and `assets/` directories are available on the skill's `path` for agents that need to reference files directly.
|
||||
|
||||
Skill paths on a crew are merged into every agent:
|
||||
---
|
||||
|
||||
```python
|
||||
from crewai import Crew
|
||||
## Pre-loading Skills
|
||||
|
||||
crew = Crew(
|
||||
agents=[agent],
|
||||
tasks=[task],
|
||||
skills=["./skills"],
|
||||
)
|
||||
```
|
||||
|
||||
### Pre-loaded Skills
|
||||
|
||||
You can also pass `Skill` objects directly:
|
||||
For more control, you can discover and activate skills programmatically:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
from crewai.skills import discover_skills, activate_skill
|
||||
|
||||
# Discover all skills in a directory
|
||||
skills = discover_skills(Path("./skills"))
|
||||
|
||||
# Activate them (loads full SKILL.md body)
|
||||
activated = [activate_skill(s) for s in skills]
|
||||
|
||||
# Pass to an agent
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Find relevant information",
|
||||
@@ -102,14 +250,57 @@ agent = Agent(
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## How Skills Are Loaded
|
||||
|
||||
Skills load progressively — only the data needed at each stage is read:
|
||||
Skills use **progressive disclosure** — only loading what's needed at each stage:
|
||||
|
||||
| Stage | What's loaded | When |
|
||||
| :--------------- | :------------------------------------------------ | :----------------- |
|
||||
| Discovery | Name, description, frontmatter fields | `discover_skills()` |
|
||||
| Activation | Full SKILL.md body text | `activate_skill()` |
|
||||
| Stage | What's loaded | When |
|
||||
| :--------- | :------------------------------------ | :------------------ |
|
||||
| Discovery | Name, description, frontmatter fields | `discover_skills()` |
|
||||
| Activation | Full SKILL.md body text | `activate_skill()` |
|
||||
|
||||
During normal agent execution, skills are automatically discovered and activated. The `scripts/`, `references/`, and `assets/` directories are available on the skill's `path` for agents that need to reference files directly.
|
||||
During normal agent execution (passing directory paths via `skills=["./skills"]`), skills are automatically discovered and activated. The progressive loading only matters when using the programmatic API.
|
||||
|
||||
---
|
||||
|
||||
## Skills vs Knowledge
|
||||
|
||||
Both skills and knowledge modify the agent's prompt, but they serve different purposes:
|
||||
|
||||
| Aspect | Skills | Knowledge |
|
||||
| :--- | :--- | :--- |
|
||||
| **What it provides** | Instructions, procedures, guidelines | Facts, data, information |
|
||||
| **How it's stored** | Markdown files (SKILL.md) | Embedded in vector store (ChromaDB) |
|
||||
| **How it's retrieved** | Entire body injected into prompt | Semantic search finds relevant chunks |
|
||||
| **Best for** | Methodology, checklists, style guides | Company docs, product info, reference data |
|
||||
| **Set via** | `skills=["./skills"]` | `knowledge_sources=[source]` |
|
||||
|
||||
**Rule of thumb:** If the agent needs to follow a *process*, use a skill. If the agent needs to reference *data*, use knowledge.
|
||||
|
||||
---
|
||||
|
||||
## Common Questions
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Do I need to set skills AND tools?">
|
||||
It depends on your use case. Skills and tools are **independent** — you can use either, both, or neither.
|
||||
|
||||
- **Skills alone**: When the agent needs expertise but no external actions (e.g., writing with style guidelines)
|
||||
- **Tools alone**: When the agent needs actions but no special methodology (e.g., simple web search)
|
||||
- **Both**: When the agent needs expertise AND actions (e.g., security audit with specific checklists AND ability to scan code)
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Do skills automatically provide tools?">
|
||||
**No.** The `allowed-tools` field in SKILL.md is experimental metadata only — it does not provision or inject any tools. You must always set tools separately via `tools=[]`, `mcps=[]`, or `apps=[]`.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="What happens if I set the same skill on both an agent and its crew?">
|
||||
The agent-level skill takes priority. Skills are deduplicated by name — the agent's skills are processed first, so if the same skill name appears at both levels, the agent's version is used.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="How large can a SKILL.md body be?">
|
||||
There's a soft warning at 50,000 characters, but no hard limit. Keep skills focused and concise for best results — large prompt injections can dilute the agent's attention.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@@ -10,6 +10,10 @@ mode: "wide"
|
||||
CrewAI tools empower agents with capabilities ranging from web searching and data analysis to collaboration and delegating tasks among coworkers.
|
||||
This documentation outlines how to create, integrate, and leverage these tools within the CrewAI framework, including a new focus on collaboration tools.
|
||||
|
||||
<Note type="info" title="Tools are one of five agent capability types">
|
||||
Tools give agents **callable functions** to take action. They work alongside [MCPs](/en/mcp/overview) (remote tool servers), [Apps](/en/concepts/agent-capabilities) (platform integrations), [Skills](/en/concepts/skills) (domain expertise), and [Knowledge](/en/concepts/knowledge) (retrieved facts). See the [Agent Capabilities](/en/concepts/agent-capabilities) overview to understand when to use each.
|
||||
</Note>
|
||||
|
||||
## What is a Tool?
|
||||
|
||||
A tool in CrewAI is a skill or function that agents can utilize to perform various actions.
|
||||
|
||||
@@ -43,7 +43,7 @@ dependencies = [
|
||||
"uv~=0.9.13",
|
||||
"aiosqlite~=0.21.0",
|
||||
"pyyaml~=6.0",
|
||||
"lancedb>=0.29.2",
|
||||
"lancedb>=0.29.2,<0.30.1",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
||||
@@ -6,7 +6,6 @@ import warnings
|
||||
|
||||
from crewai.agent.core import Agent
|
||||
from crewai.agent.planning_config import PlanningConfig
|
||||
from crewai.agents.crew_agent_executor import CrewAgentExecutor
|
||||
from crewai.crew import Crew
|
||||
from crewai.crews.crew_output import CrewOutput
|
||||
from crewai.flow.flow import Flow
|
||||
@@ -20,9 +19,6 @@ from crewai.tasks.task_output import TaskOutput
|
||||
from crewai.telemetry.telemetry import Telemetry
|
||||
|
||||
|
||||
CrewAgentExecutor.model_rebuild()
|
||||
|
||||
|
||||
def _suppress_pydantic_deprecation_warnings() -> None:
|
||||
"""Suppress Pydantic deprecation warnings using targeted monkey patch."""
|
||||
original_warn = warnings.warn
|
||||
|
||||
@@ -14,15 +14,8 @@ import inspect
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any, Literal, cast
|
||||
|
||||
from pydantic import (
|
||||
BaseModel,
|
||||
ConfigDict,
|
||||
Field,
|
||||
PrivateAttr,
|
||||
ValidationError,
|
||||
model_validator,
|
||||
)
|
||||
from typing_extensions import Self
|
||||
from pydantic import BaseModel, GetCoreSchemaHandler, ValidationError
|
||||
from pydantic_core import CoreSchema, core_schema
|
||||
|
||||
from crewai.agents.agent_builder.base_agent_executor_mixin import CrewAgentExecutorMixin
|
||||
from crewai.agents.parser import (
|
||||
@@ -30,7 +23,6 @@ from crewai.agents.parser import (
|
||||
AgentFinish,
|
||||
OutputParserError,
|
||||
)
|
||||
from crewai.agents.tools_handler import ToolsHandler
|
||||
from crewai.core.providers.human_input import ExecutorContext, get_provider
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.logging_events import (
|
||||
@@ -46,9 +38,6 @@ from crewai.hooks.tool_hooks import (
|
||||
get_after_tool_call_hooks,
|
||||
get_before_tool_call_hooks,
|
||||
)
|
||||
from crewai.llms.base_llm import BaseLLM
|
||||
from crewai.tools.base_tool import BaseTool
|
||||
from crewai.tools.structured_tool import CrewStructuredTool
|
||||
from crewai.utilities.agent_utils import (
|
||||
aget_llm_response,
|
||||
convert_tools_to_openai_schema,
|
||||
@@ -70,65 +59,106 @@ from crewai.utilities.constants import TRAINING_DATA_FILE
|
||||
from crewai.utilities.file_store import aget_all_files, get_all_files
|
||||
from crewai.utilities.i18n import I18N, get_i18n
|
||||
from crewai.utilities.printer import Printer
|
||||
from crewai.utilities.prompts import StandardPromptResult, SystemPromptResult
|
||||
from crewai.utilities.string_utils import sanitize_tool_name
|
||||
from crewai.utilities.tool_utils import (
|
||||
aexecute_tool_and_check_finality,
|
||||
execute_tool_and_check_finality,
|
||||
)
|
||||
from crewai.utilities.training_handler import CrewTrainingHandler
|
||||
from crewai.utilities.types import LLMMessage
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.agent import Agent
|
||||
from crewai.agents.tools_handler import ToolsHandler
|
||||
from crewai.crew import Crew
|
||||
from crewai.llms.base_llm import BaseLLM
|
||||
from crewai.task import Task
|
||||
from crewai.tools.base_tool import BaseTool
|
||||
from crewai.tools.structured_tool import CrewStructuredTool
|
||||
from crewai.tools.tool_types import ToolResult
|
||||
from crewai.utilities.prompts import StandardPromptResult, SystemPromptResult
|
||||
from crewai.utilities.types import LLMMessage
|
||||
|
||||
|
||||
class CrewAgentExecutor(BaseModel, CrewAgentExecutorMixin):
|
||||
class CrewAgentExecutor(CrewAgentExecutorMixin):
|
||||
"""Executor for crew agents.
|
||||
|
||||
Manages the execution lifecycle of an agent including prompt formatting,
|
||||
LLM interactions, tool execution, and feedback handling.
|
||||
"""
|
||||
|
||||
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
|
||||
def __init__(
|
||||
self,
|
||||
llm: BaseLLM,
|
||||
task: Task,
|
||||
crew: Crew,
|
||||
agent: Agent,
|
||||
prompt: SystemPromptResult | StandardPromptResult,
|
||||
max_iter: int,
|
||||
tools: list[CrewStructuredTool],
|
||||
tools_names: str,
|
||||
stop_words: list[str],
|
||||
tools_description: str,
|
||||
tools_handler: ToolsHandler,
|
||||
step_callback: Any = None,
|
||||
original_tools: list[BaseTool] | None = None,
|
||||
function_calling_llm: BaseLLM | Any | None = None,
|
||||
respect_context_window: bool = False,
|
||||
request_within_rpm_limit: Callable[[], bool] | None = None,
|
||||
callbacks: list[Any] | None = None,
|
||||
response_model: type[BaseModel] | None = None,
|
||||
i18n: I18N | None = None,
|
||||
) -> None:
|
||||
"""Initialize executor.
|
||||
|
||||
llm: BaseLLM
|
||||
task: Task | None = None
|
||||
crew: Crew | None = None
|
||||
agent: Agent
|
||||
prompt: SystemPromptResult | StandardPromptResult
|
||||
max_iter: int
|
||||
tools: list[CrewStructuredTool]
|
||||
tools_names: str
|
||||
stop: list[str] = Field(alias="stop_words")
|
||||
tools_description: str
|
||||
tools_handler: ToolsHandler
|
||||
step_callback: Any = None
|
||||
original_tools: list[BaseTool] = Field(default_factory=list)
|
||||
function_calling_llm: BaseLLM | Any | None = None
|
||||
respect_context_window: bool = False
|
||||
request_within_rpm_limit: Callable[[], bool] | None = None
|
||||
callbacks: list[Any] = Field(default_factory=list)
|
||||
response_model: type[BaseModel] | None = None
|
||||
i18n: I18N | None = Field(default=None, exclude=True)
|
||||
ask_for_human_input: bool = False
|
||||
messages: list[LLMMessage] = Field(default_factory=list)
|
||||
iterations: int = 0
|
||||
log_error_after: int = 3
|
||||
before_llm_call_hooks: list[Callable[..., Any]] = Field(default_factory=list)
|
||||
after_llm_call_hooks: list[Callable[..., Any]] = Field(default_factory=list)
|
||||
_i18n: I18N = PrivateAttr()
|
||||
_printer: Printer = PrivateAttr(default_factory=Printer)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def _init_executor(self) -> Self:
|
||||
self._i18n = self.i18n or get_i18n()
|
||||
Args:
|
||||
llm: Language model instance.
|
||||
task: Task to execute.
|
||||
crew: Crew instance.
|
||||
agent: Agent to execute.
|
||||
prompt: Prompt templates.
|
||||
max_iter: Maximum iterations.
|
||||
tools: Available tools.
|
||||
tools_names: Tool names string.
|
||||
stop_words: Stop word list.
|
||||
tools_description: Tool descriptions.
|
||||
tools_handler: Tool handler instance.
|
||||
step_callback: Optional step callback.
|
||||
original_tools: Original tool list.
|
||||
function_calling_llm: Optional function calling LLM.
|
||||
respect_context_window: Respect context limits.
|
||||
request_within_rpm_limit: RPM limit check function.
|
||||
callbacks: Optional callbacks list.
|
||||
response_model: Optional Pydantic model for structured outputs.
|
||||
"""
|
||||
self._i18n: I18N = i18n or get_i18n()
|
||||
self.llm = llm
|
||||
self.task = task
|
||||
self.agent = agent
|
||||
self.crew = crew
|
||||
self.prompt = prompt
|
||||
self.tools = tools
|
||||
self.tools_names = tools_names
|
||||
self.stop = stop_words
|
||||
self.max_iter = max_iter
|
||||
self.callbacks = callbacks or []
|
||||
self._printer: Printer = Printer()
|
||||
self.tools_handler = tools_handler
|
||||
self.original_tools = original_tools or []
|
||||
self.step_callback = step_callback
|
||||
self.tools_description = tools_description
|
||||
self.function_calling_llm = function_calling_llm
|
||||
self.respect_context_window = respect_context_window
|
||||
self.request_within_rpm_limit = request_within_rpm_limit
|
||||
self.response_model = response_model
|
||||
self.ask_for_human_input = False
|
||||
self.messages: list[LLMMessage] = []
|
||||
self.iterations = 0
|
||||
self.log_error_after = 3
|
||||
self.before_llm_call_hooks: list[Callable[..., Any]] = []
|
||||
self.after_llm_call_hooks: list[Callable[..., Any]] = []
|
||||
self.before_llm_call_hooks.extend(get_before_llm_call_hooks())
|
||||
self.after_llm_call_hooks.extend(get_after_llm_call_hooks())
|
||||
if self.llm:
|
||||
@@ -141,7 +171,6 @@ class CrewAgentExecutor(BaseModel, CrewAgentExecutorMixin):
|
||||
else self.stop
|
||||
)
|
||||
)
|
||||
return self
|
||||
|
||||
@property
|
||||
def use_stop_words(self) -> bool:
|
||||
@@ -1658,3 +1687,14 @@ class CrewAgentExecutor(BaseModel, CrewAgentExecutorMixin):
|
||||
return format_message_for_llm(
|
||||
self._i18n.slice("feedback_instructions").format(feedback=feedback)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def __get_pydantic_core_schema__(
|
||||
cls, _source_type: Any, _handler: GetCoreSchemaHandler
|
||||
) -> CoreSchema:
|
||||
"""Generate Pydantic core schema for BaseClient Protocol.
|
||||
|
||||
This allows the Protocol to be used in Pydantic models without
|
||||
requiring arbitrary_types_allowed=True.
|
||||
"""
|
||||
return core_schema.any_schema()
|
||||
|
||||
2
uv.lock
generated
2
uv.lock
generated
@@ -1243,7 +1243,7 @@ requires-dist = [
|
||||
{ name = "json-repair", specifier = "~=0.25.2" },
|
||||
{ name = "json5", specifier = "~=0.10.0" },
|
||||
{ name = "jsonref", specifier = "~=1.1.0" },
|
||||
{ name = "lancedb", specifier = ">=0.29.2" },
|
||||
{ name = "lancedb", specifier = ">=0.29.2,<0.30.1" },
|
||||
{ name = "litellm", marker = "extra == 'litellm'", specifier = ">=1.74.9,<=1.82.6" },
|
||||
{ name = "mcp", specifier = "~=1.26.0" },
|
||||
{ name = "mem0ai", marker = "extra == 'mem0'", specifier = "~=0.1.94" },
|
||||
|
||||
Reference in New Issue
Block a user