403 lines
14 KiB
Plaintext
403 lines
14 KiB
Plaintext
---
|
|
title: 'CrewAI Example'
|
|
description: 'Build a job posting generator with CrewAI agents and AgentOps tracking'
|
|
---
|
|
{/* SOURCE_FILE: examples/crewai/job_posting.ipynb */}
|
|
|
|
_View Notebook on <a href={'https://github.com/AgentOps-AI/agentops/blob/main/examples/crewai/job_posting.ipynb'} target={'_blank'}>Github</a>_
|
|
|
|
# CrewAI Job Posting Generator with AgentOps
|
|
|
|
This example shows you how to build a complete job posting generator using CrewAI's official project structure with comprehensive tracking via AgentOps.
|
|
|
|
## What We're Building
|
|
|
|
A **3-agent system** that collaborates to create job postings:
|
|
- 🔍 **Research Agent**: Analyzes company culture and industry trends
|
|
- ✍️ **Writer Agent**: Drafts compelling job descriptions
|
|
- 📝 **Editor Agent**: Reviews and polishes the final posting
|
|
|
|
**With AgentOps**, you'll get complete visibility into agent conversations, tool usage, costs, and performance.
|
|
|
|
## Step-by-Step Implementation
|
|
|
|
### Step 1: Install Dependencies
|
|
|
|
Install CrewAI with tools support and AgentOps for tracking:
|
|
|
|
<CodeGroup>
|
|
```bash pip
|
|
pip install -U 'crewai[tools]' agentops
|
|
```
|
|
```bash poetry
|
|
poetry add 'crewai[tools]' agentops
|
|
```
|
|
```bash uv
|
|
uv pip install 'crewai[tools]' agentops
|
|
```
|
|
</CodeGroup>
|
|
|
|
**What AgentOps adds:**
|
|
- 🔍 **Automatic tracking** of all LLM calls and agent interactions
|
|
- 💰 **Cost monitoring** with token usage breakdown
|
|
- 🛠️ **Tool usage analytics** for web searches and file operations
|
|
- 📊 **Performance metrics** and execution timelines
|
|
- 🐛 **Session replay** for debugging and optimization
|
|
|
|
### Step 2: Create CrewAI Project
|
|
|
|
Use CrewAI's CLI to create the proper project structure:
|
|
|
|
```bash
|
|
crewai create crew job_posting_agent
|
|
```
|
|
|
|
**Select your provider and model:**
|
|
- Choose **1. openai**
|
|
- Choose **1. gpt-4** (or your preferred model)
|
|
- Enter your OpenAI API key when prompted
|
|
|
|
**This creates the complete project structure:**
|
|
```
|
|
job_posting_agent/
|
|
├── .env # API keys
|
|
├── .gitignore
|
|
├── pyproject.toml # Dependencies
|
|
├── README.md
|
|
├── knowledge/
|
|
│ └── user_preference.txt
|
|
└── src/job_posting_agent/
|
|
├── __init__.py
|
|
├── main.py # Main execution
|
|
├── crew.py # Crew definition
|
|
├── config/
|
|
│ ├── agents.yaml # Agent configurations
|
|
│ └── tasks.yaml # Task definitions
|
|
└── tools/
|
|
├── __init__.py
|
|
└── custom_tool.py # Custom tools
|
|
```
|
|
|
|
### Step 3: Add Additional API Keys
|
|
|
|
Edit the generated `.env` file to add AgentOps and Serper keys:
|
|
|
|
```bash
|
|
# .env (already has OPENAI_API_KEY from crewai create)
|
|
OPENAI_API_KEY=your_openai_key_here
|
|
AGENTOPS_API_KEY=your_agentops_key_here
|
|
SERPER_API_KEY=your_serper_key_here
|
|
```
|
|
|
|
**Get your additional API keys:**
|
|
- **AgentOps**: [Get one here](https://agentops.ai/settings/projects)
|
|
- **Serper**: [Serper Dev](https://serper.dev/api-key) (for web search)
|
|
|
|
### Step 4: Configure Agents
|
|
|
|
Edit `src/job_posting_agent/config/agents.yaml` to define your 3 agents:
|
|
|
|
```yaml
|
|
researcher:
|
|
role: "Research Analyst"
|
|
goal: "Analyze the company website and provided description to extract insights on culture, values, and specific needs."
|
|
backstory: "Expert in analyzing company cultures and identifying key values and needs from various sources, including websites and brief descriptions."
|
|
verbose: true
|
|
|
|
writer:
|
|
role: "Job Description Writer"
|
|
goal: "Use insights from the Research Analyst to create a detailed, engaging, and enticing job posting."
|
|
backstory: "Skilled in crafting compelling job descriptions that resonate with the company's values and attract the right candidates."
|
|
verbose: true
|
|
|
|
editor:
|
|
role: "Review and Editing Specialist"
|
|
goal: "Review the job posting for clarity, engagement, grammatical accuracy, and alignment with company values and refine it to ensure perfection."
|
|
backstory: "A meticulous editor with an eye for detail, ensuring every piece of content is clear, engaging, and grammatically perfect."
|
|
verbose: true
|
|
```
|
|
|
|
### Step 5: Configure Tasks
|
|
|
|
Edit `src/job_posting_agent/config/tasks.yaml` to define the workflow:
|
|
|
|
```yaml
|
|
research_company_culture:
|
|
description: >
|
|
Analyze the provided company website and description: "{company_description}"
|
|
at domain {company_domain}. Focus on understanding the company's culture,
|
|
values, and mission. Identify unique selling points and specific projects
|
|
or achievements highlighted on the site. Compile a report summarizing these
|
|
insights, specifically how they can be leveraged in a job posting to attract
|
|
the right candidates.
|
|
expected_output: >
|
|
A comprehensive report detailing the company's culture, values, and mission,
|
|
along with specific selling points relevant to the job role. Suggestions on
|
|
incorporating these insights into the job posting should be included.
|
|
agent: researcher
|
|
|
|
research_role_requirements:
|
|
description: >
|
|
Based on the hiring manager's needs: "{hiring_needs}", identify the key skills,
|
|
experiences, and qualities the ideal candidate should possess for the role.
|
|
Consider the company's current projects, its competitive landscape, and industry
|
|
trends. Prepare a list of recommended job requirements and qualifications that
|
|
align with the company's needs and values.
|
|
expected_output: >
|
|
A list of recommended skills, experiences, and qualities for the ideal candidate,
|
|
aligned with the company's culture, ongoing projects, and the specific role's requirements.
|
|
agent: researcher
|
|
|
|
draft_job_posting:
|
|
description: >
|
|
Draft a job posting for the role described by the hiring manager: "{hiring_needs}".
|
|
Use the insights on "{company_description}" to start with a compelling introduction,
|
|
followed by a detailed role description, responsibilities, and required skills and
|
|
qualifications. Ensure the tone aligns with the company's culture and incorporate
|
|
any unique benefits or opportunities offered by the company.
|
|
Specific benefits: "{specific_benefits}"
|
|
expected_output: >
|
|
A detailed, engaging job posting that includes an introduction, role description,
|
|
responsibilities, requirements, and unique company benefits. The tone should
|
|
resonate with the company's culture and values, aimed at attracting the right candidates.
|
|
agent: writer
|
|
context:
|
|
- research_company_culture
|
|
- research_role_requirements
|
|
|
|
review_and_edit_job_posting:
|
|
description: >
|
|
Review the draft job posting for the role: "{hiring_needs}". Check for clarity,
|
|
engagement, grammatical accuracy, and alignment with the company's culture and
|
|
values. Edit and refine the content, ensuring it speaks directly to the desired
|
|
candidates and accurately reflects the role's unique benefits and opportunities.
|
|
Provide feedback for any necessary revisions.
|
|
expected_output: >
|
|
A polished, error-free job posting that is clear, engaging, and perfectly
|
|
aligned with the company's culture and values. Feedback on potential improvements
|
|
and final approval for publishing. Formatted in markdown.
|
|
agent: editor
|
|
context:
|
|
- draft_job_posting
|
|
output_file: "job_posting.md"
|
|
```
|
|
|
|
### Step 6: Update the Crew Definition
|
|
|
|
Edit `src/job_posting_agent/crew.py` to add tools and AgentOps:
|
|
|
|
```python
|
|
from crewai import Agent, Crew, Process, Task
|
|
from crewai.project import CrewBase, agent, crew, task
|
|
from crewai_tools import SerperDevTool, WebsiteSearchTool
|
|
import agentops
|
|
|
|
# Initialize AgentOps
|
|
agentops.init()
|
|
|
|
@CrewBase
|
|
class JobPostingAgentCrew():
|
|
"""JobPostingAgent crew"""
|
|
|
|
def __init__(self) -> None:
|
|
# Initialize tools
|
|
self.serper_tool = SerperDevTool()
|
|
self.website_tool = WebsiteSearchTool()
|
|
|
|
@agent
|
|
def researcher(self) -> Agent:
|
|
return Agent(
|
|
config=self.agents_config['researcher'],
|
|
tools=[self.serper_tool, self.website_tool]
|
|
)
|
|
|
|
@agent
|
|
def writer(self) -> Agent:
|
|
return Agent(
|
|
config=self.agents_config['writer'],
|
|
tools=[self.serper_tool, self.website_tool]
|
|
)
|
|
|
|
@agent
|
|
def editor(self) -> Agent:
|
|
return Agent(
|
|
config=self.agents_config['editor']
|
|
)
|
|
|
|
@task
|
|
def research_company_culture(self) -> Task:
|
|
return Task(
|
|
config=self.tasks_config['research_company_culture']
|
|
)
|
|
|
|
@task
|
|
def research_role_requirements(self) -> Task:
|
|
return Task(
|
|
config=self.tasks_config['research_role_requirements']
|
|
)
|
|
|
|
@task
|
|
def draft_job_posting(self) -> Task:
|
|
return Task(
|
|
config=self.tasks_config['draft_job_posting']
|
|
)
|
|
|
|
@task
|
|
def review_and_edit_job_posting(self) -> Task:
|
|
return Task(
|
|
config=self.tasks_config['review_and_edit_job_posting']
|
|
)
|
|
|
|
@crew
|
|
def crew(self) -> Crew:
|
|
"""Creates the JobPostingAgent crew"""
|
|
return Crew(
|
|
agents=self.agents,
|
|
tasks=self.tasks,
|
|
process=Process.sequential,
|
|
verbose=True
|
|
)
|
|
```
|
|
|
|
### Step 7: Update the Main Execution File
|
|
|
|
Edit `src/job_posting_agent/main.py` to add AgentOps session management:
|
|
|
|
```python
|
|
#!/usr/bin/env python
|
|
import sys
|
|
import warnings
|
|
from job_posting_agent.crew import JobPostingAgentCrew
|
|
import agentops
|
|
|
|
warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")
|
|
|
|
def run():
|
|
"""
|
|
Run the crew with AgentOps tracking.
|
|
"""
|
|
# Start AgentOps session
|
|
session = agentops.start_session(tags=["crewai", "job-posting"])
|
|
|
|
try:
|
|
# Define the inputs for the crew
|
|
inputs = {
|
|
'company_description': 'A fast-paced tech startup focused on AI-driven solutions for e-commerce.',
|
|
'company_domain': 'https://agentops.ai',
|
|
'hiring_needs': 'Senior Software Engineer with experience in Python, AI, and cloud platforms.',
|
|
'specific_benefits': 'Competitive salary, stock options, remote work flexibility, and great team culture.'
|
|
}
|
|
|
|
# Initialize and run the crew
|
|
crew = JobPostingAgentCrew().crew()
|
|
result = crew.kickoff(inputs=inputs)
|
|
|
|
print("\n" + "="*50)
|
|
print("Job Posting Creation Completed!")
|
|
print("Result:")
|
|
print(result)
|
|
print("\nCheck 'job_posting.md' for the generated job posting.")
|
|
|
|
# End session successfully
|
|
agentops.end_session("Success")
|
|
return result
|
|
|
|
except Exception as e:
|
|
print(f"An error occurred: {e}")
|
|
agentops.end_session("Failed", end_state_reason=str(e))
|
|
raise
|
|
|
|
def train():
|
|
"""
|
|
Train the crew for a given number of iterations.
|
|
"""
|
|
inputs = {
|
|
'company_description': 'A fast-paced tech startup focused on AI-driven solutions for e-commerce.',
|
|
'company_domain': 'https://agentops.ai',
|
|
'hiring_needs': 'Senior Software Engineer with experience in Python, AI, and cloud platforms.',
|
|
'specific_benefits': 'Competitive salary, stock options, remote work flexibility, and great team culture.'
|
|
}
|
|
try:
|
|
JobPostingAgentCrew().crew().train(n_iterations=int(sys.argv[1]), filename=sys.argv[2], inputs=inputs)
|
|
except Exception as e:
|
|
raise Exception(f"An error occurred while training the crew: {e}")
|
|
|
|
def replay():
|
|
"""
|
|
Replay the crew execution from a specific task.
|
|
"""
|
|
try:
|
|
JobPostingAgentCrew().crew().replay(task_id=sys.argv[1])
|
|
except Exception as e:
|
|
raise Exception(f"An error occurred while replaying the crew: {e}")
|
|
|
|
def test():
|
|
"""
|
|
Test the crew execution and returns the results.
|
|
"""
|
|
inputs = {
|
|
'company_description': 'A fast-paced tech startup focused on AI-driven solutions for e-commerce.',
|
|
'company_domain': 'https://agentops.ai',
|
|
'hiring_needs': 'Senior Software Engineer with experience in Python, AI, and cloud platforms.',
|
|
'specific_benefits': 'Competitive salary, stock options, remote work flexibility, and great team culture.'
|
|
}
|
|
try:
|
|
JobPostingAgentCrew().crew().test(n_iterations=int(sys.argv[1]), openai_model_name=sys.argv[2], inputs=inputs)
|
|
except Exception as e:
|
|
raise Exception(f"An error occurred while testing the crew: {e}")
|
|
```
|
|
|
|
### Step 8: Run Your Job Posting Generator
|
|
|
|
Navigate to your project and run:
|
|
|
|
```bash
|
|
cd job_posting_agent
|
|
crewai run
|
|
```
|
|
|
|
**What happens:**
|
|
1. AgentOps session starts automatically
|
|
2. Research agent analyzes the company and industry trends
|
|
3. Writer agent drafts the job posting using research insights
|
|
4. Editor agent reviews and polishes the final version
|
|
5. A `job_posting.md` file is created with the result
|
|
6. AgentOps captures all agent interactions, tool usage, and costs
|
|
7. Session ends with success/failure status
|
|
|
|
## View Results in AgentOps Dashboard
|
|
|
|
After running your job posting generator, visit your [AgentOps Dashboard](https://app.agentops.ai) to see:
|
|
|
|
1. **Session Overview**: Complete timeline of the 3-agent workflow
|
|
2. **Agent Conversations**: Every LLM call with prompts and responses
|
|
3. **Tool Execution**: Web searches and their results
|
|
4. **Cost Breakdown**: Token usage and costs per agent and task
|
|
5. **Performance Analytics**: Execution times and success rates
|
|
6. **Session Replay**: Step-by-step playback for debugging
|
|
|
|
## Key Files Modified
|
|
|
|
**Configuration files you edited:**
|
|
- `config/agents.yaml` - Agent definitions with roles and backstories
|
|
- `config/tasks.yaml` - Task workflow with context dependencies
|
|
- `crew.py` - Added tools and AgentOps initialization
|
|
- `main.py` - Added session management
|
|
- `.env` - Added AgentOps and Serper API keys
|
|
|
|
**Generated output:**
|
|
- `job_posting.md` - Final job posting created by the crew
|
|
|
|
**AgentOps Integration Points:**
|
|
- `agentops.init()` in `crew.py` - Enables automatic instrumentation
|
|
- `agentops.start_session()` in `main.py` - Begins tracking
|
|
- `agentops.end_session()` in `main.py` - Completes the session
|
|
|
|
## Next Steps
|
|
|
|
- Customize the input parameters in `main.py`
|
|
- Modify agent configurations in `agents.yaml`
|
|
- Add more tasks or change the workflow in `tasks.yaml`
|
|
- Add custom tools in the `tools/` directory
|
|
- Use AgentOps analytics to optimize agent performance
|