mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-07-01 05:08:12 +00:00
* feat: adopt directory-based docs versioning with Edge channel Switch docs.crewai.com from navigation-only versioning (every version selector entry rendered the same docs/<lang>/* source files) to Mintlify's directory-based versioning so each version selector entry renders its own snapshot. Add an "Edge" channel under docs/edge/<lang>/* that always reflects main HEAD for unreleased work, eliminating pre-release leakage onto frozen release labels. External links to canonical /<lang>/* URLs are preserved via wildcard redirects that always land on the current default version. Layout: - docs/edge/<lang>/* rolling source (you edit here) - docs/edge/enterprise-api.*.yaml - docs/v<X.Y.Z>/<lang>/* frozen, immutable snapshots - docs/v<X.Y.Z>/enterprise-api.*.yaml - docs/images/ shared, append-only - docs/docs.json nav + redirects URLs follow the Mintlify-idiomatic shape: /edge/<lang>/<page> for Edge, /v<X.Y.Z>/<lang>/<page> for every frozen snapshot. The wildcard redirects /<lang>/:slug* -> /<default>/<lang>/:slug* keep stale links working, and every freeze rewrites them (plus all per-section/per-page redirects) so destinations always resolve to the current default without depending on a second redirect hop. Release flow integration (devtools release): - New module crewai_devtools.docs_versioning.freeze() materialises docs/v<X.Y.Z>/ from docs/edge/, rewrites openapi: refs inside the snapshot, inserts the version into every language block in docs.json, and refreshes all redirect destinations. - _update_docs_and_create_pr() in cli.py now calls that freeze during Phase 2 of devtools release. Edge changelogs are updated first (so the snapshot freeze picks them up), then the snapshot is staged alongside docs.json, branched as docs/freeze-v<X.Y.Z>, and the PR is titled [docs-freeze] docs: snapshot and changelog for v<X.Y.Z> — the title prefix the new CI guard reads. - The PR still gates tag, GitHub release, PyPI publish, and the enterprise release as before; no new PRs are added. - Pre-releases (1.X.YaN, 1.X.YbN, ...) skip the snapshot — they ride Edge — and the docs PR title omits the [docs-freeze] prefix. - docs_check (AI-generated docs scaffolding) writes to docs/edge/<lang>/* so newly-generated unreleased docs land in Edge and never accidentally touch a frozen snapshot. Migration scripts (one-shot): - scripts/docs/freeze_historical_versions.py reconstructs all 16 historical snapshots (v1.10.0 .. v1.14.7) from git tags via git archive | tar, rewriting openapi: MDX refs so each snapshot reads its own enterprise-api YAML rather than the live one. - scripts/docs/prefix_version_paths.py one-shot-migrates docs.json: rewrites every page path in 16 versioned blocks to point under docs/v<X.Y.Z>/, inserts a new Edge entry per language, tags v1.14.7 as Latest (default), prunes pages whose target file doesn't exist in the snapshot (e.g. docs/ar/ didn't exist before v1.12.0), and writes the wildcard + per-section redirects. - scripts/docs/freeze_current_edge.py is now a thin CLI wrapper around docs_versioning.freeze for manual one-off freezes (e.g. retroactively snapshotting a forgotten release). CI guards (.github/workflows/docs-snapshots.yml): - Frozen snapshots under docs/v[0-9]*/ are immutable; only PRs whose title contains [docs-freeze] (i.e. release-cut PRs generated by devtools release or the manual wrapper) may modify them. - Images under docs/images/ are append-only since snapshots share a single image directory. Deleting or renaming an image breaks every historical snapshot that still references it. Restored docs/images/crewai-otel-export.png from PR #3673; it was deleted in PR #4908 but v1.10.0 / v1.10.1 snapshots still reference it. Restoring instead of editing the snapshots preserves historical rendering fidelity and validates the new append-only rule retroactively. Tests: - lib/devtools/tests/test_docs_versioning.py covers the freeze: file copy, openapi rewrite, version insertion, default demotion, redirect upserts, per-section redirect rewriting, idempotency, and invalid inputs. Verified locally with mintlify broken-links: 0 broken links across the full site (Edge + 16 frozen versions, 4 locales). AGENTS.md (repo root) is the contributor guide for the new model; RELEASING.md is the release-cut runbook; README's Contribution section links to both. Co-authored-by: Cursor <cursoragent@cursor.com> * style: resolve linter issues --------- Co-authored-by: Cursor <cursoragent@cursor.com>
156 lines
6.6 KiB
Plaintext
156 lines
6.6 KiB
Plaintext
---
|
|
title: "Using Annotations in crew.py"
|
|
description: "Learn how to use classic Python annotations to structure agents, tasks, and components in CrewAI"
|
|
icon: "at"
|
|
mode: "wide"
|
|
---
|
|
|
|
This guide explains how to use annotations to properly reference **agents**, **tasks**, and other components in a classic `crew.py` file.
|
|
|
|
<Note>
|
|
New crew projects created with `crewai create crew <name>` are JSON-first and use `crew.jsonc` plus `agents/*.jsonc`. Use this annotations guide when you are working in a classic project created with `crewai create crew <name> --classic`, migrating an existing Python/YAML project, or need decorator-based Python control.
|
|
</Note>
|
|
|
|
## Introduction
|
|
|
|
Annotations in the CrewAI framework are used to decorate classes and methods, providing metadata and functionality to various components of your crew. In classic Python/YAML projects, these annotations help organize the code that loads `config/agents.yaml`, `config/tasks.yaml`, and returns the `Crew` object.
|
|
|
|
## Available Annotations
|
|
|
|
The CrewAI framework provides the following annotations:
|
|
|
|
- `@CrewBase`: Used to decorate the main crew class.
|
|
- `@agent`: Decorates methods that define and return Agent objects.
|
|
- `@task`: Decorates methods that define and return Task objects.
|
|
- `@crew`: Decorates the method that creates and returns the Crew object.
|
|
- `@llm`: Decorates methods that initialize and return Language Model objects.
|
|
- `@tool`: Decorates methods that initialize and return Tool objects.
|
|
- `@callback`: Used for defining callback methods.
|
|
- `@output_json`: Used for methods that output JSON data.
|
|
- `@output_pydantic`: Used for methods that output Pydantic models.
|
|
- `@cache_handler`: Used for defining cache handling methods.
|
|
|
|
## Usage Examples
|
|
|
|
Let's go through examples of how to use these annotations:
|
|
|
|
### 1. Crew Base Class
|
|
|
|
```python
|
|
@CrewBase
|
|
class LinkedinProfileCrew():
|
|
"""LinkedinProfile crew"""
|
|
agents_config = 'config/agents.yaml'
|
|
tasks_config = 'config/tasks.yaml'
|
|
```
|
|
|
|
The `@CrewBase` annotation is used to decorate the main crew class. This class typically contains configurations and methods for creating agents, tasks, and the crew itself.
|
|
|
|
<Tip>
|
|
`@CrewBase` does more than register the class:
|
|
|
|
- **Configuration bootstrapping:** looks for `agents_config` and `tasks_config` (defaulting to `config/agents.yaml` and `config/tasks.yaml`) beside the class file, loads them at instantiation, and safely falls back to empty dicts if files are missing.
|
|
- **Decorator orchestration:** keeps memoized references to every method marked with `@agent`, `@task`, `@before_kickoff`, or `@after_kickoff` so they are instantiated once per crew and executed in declaration order.
|
|
- **Hook wiring:** automatically attaches the preserved kickoff hooks to the `Crew` object returned by the `@crew` method, making them run before and after `.kickoff()`.
|
|
- **MCP integration:** when the class defines `mcp_server_params`, `get_mcp_tools()` lazily starts an MCP server adapter, hydrates the declared tools, and an internal after-kickoff hook stops the adapter. See [MCP overview](/en/mcp/overview) for adapter configuration details.
|
|
</Tip>
|
|
|
|
### 2. Tool Definition
|
|
|
|
```python
|
|
@tool
|
|
def myLinkedInProfileTool(self):
|
|
return LinkedInProfileTool()
|
|
```
|
|
|
|
The `@tool` annotation is used to decorate methods that return tool objects. These tools can be used by agents to perform specific tasks.
|
|
|
|
### 3. LLM Definition
|
|
|
|
```python
|
|
@llm
|
|
def groq_llm(self):
|
|
api_key = os.getenv('api_key')
|
|
return ChatGroq(api_key=api_key, temperature=0, model_name="mixtral-8x7b-32768")
|
|
```
|
|
|
|
The `@llm` annotation is used to decorate methods that initialize and return Language Model objects. These LLMs are used by agents for natural language processing tasks.
|
|
|
|
### 4. Agent Definition
|
|
|
|
```python
|
|
@agent
|
|
def researcher(self) -> Agent:
|
|
return Agent(
|
|
config=self.agents_config['researcher']
|
|
)
|
|
```
|
|
|
|
The `@agent` annotation is used to decorate methods that define and return Agent objects.
|
|
|
|
### 5. Task Definition
|
|
|
|
```python
|
|
@task
|
|
def research_task(self) -> Task:
|
|
return Task(
|
|
config=self.tasks_config['research_linkedin_task'],
|
|
agent=self.researcher()
|
|
)
|
|
```
|
|
|
|
The `@task` annotation is used to decorate methods that define and return Task objects. These methods specify the task configuration and the agent responsible for the task.
|
|
|
|
### 6. Crew Creation
|
|
|
|
```python
|
|
@crew
|
|
def crew(self) -> Crew:
|
|
"""Creates the LinkedinProfile crew"""
|
|
return Crew(
|
|
agents=self.agents,
|
|
tasks=self.tasks,
|
|
process=Process.sequential,
|
|
verbose=True
|
|
)
|
|
```
|
|
|
|
The `@crew` annotation is used to decorate the method that creates and returns the `Crew` object. This method assembles all the components (agents and tasks) into a functional crew.
|
|
|
|
## Classic YAML Configuration
|
|
|
|
In classic projects, agent configurations are typically stored in a YAML file. Here's an example of how the `agents.yaml` file might look for the researcher agent:
|
|
|
|
```yaml
|
|
researcher:
|
|
role: >
|
|
LinkedIn Profile Senior Data Researcher
|
|
goal: >
|
|
Uncover detailed LinkedIn profiles based on provided name {name} and domain {domain}
|
|
Generate a Dall-E image based on domain {domain}
|
|
backstory: >
|
|
You're a seasoned researcher with a knack for uncovering the most relevant LinkedIn profiles.
|
|
Known for your ability to navigate LinkedIn efficiently, you excel at gathering and presenting
|
|
professional information clearly and concisely.
|
|
allow_delegation: False
|
|
verbose: True
|
|
llm: groq_llm
|
|
tools:
|
|
- myLinkedInProfileTool
|
|
- mySerperDevTool
|
|
- myDallETool
|
|
```
|
|
|
|
This YAML configuration corresponds to the researcher agent defined in the `LinkedinProfileCrew` class. The configuration specifies the agent's role, goal, backstory, and other properties such as the LLM and tools it uses.
|
|
|
|
Note how the `llm` and `tools` in the YAML file correspond to the methods decorated with `@llm` and `@tool` in the Python class.
|
|
|
|
## Best Practices
|
|
|
|
- **Consistent Naming**: Use clear and consistent naming conventions for your methods. For example, agent methods could be named after their roles (e.g., researcher, reporting_analyst).
|
|
- **Environment Variables**: Use environment variables for sensitive information like API keys.
|
|
- **Flexibility**: Design your crew to be flexible by allowing easy addition or removal of agents and tasks.
|
|
- **YAML-Code Correspondence**: In classic projects, ensure that the names and structures in your YAML files correspond correctly to the decorated methods in your Python code.
|
|
|
|
By following these guidelines and properly using annotations, you can maintain classic Python/YAML crews cleanly. For new crews, prefer the JSON-first structure covered in [Crews](/en/concepts/crews).
|