# Using crewai, ollama, and pandantic

**URL:** https://community.crewai.com/t/using-crewai-ollama-and-pandantic/4084
**Category:** CrewAI Community Support
**Tags:** crewai
**Created:** [February 22, 2025, 12:46pm UTC](https://community.crewai.com/t/using-crewai-ollama-and-pandantic/4084 "2025-02-22T12:46:47Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Saeed\_Kasmani](https://sea1.discourse-cdn.com/flex025/user_avatar/community.crewai.com/saeed_kasmani/32/2396_2.png) [@Saeed\_Kasmani](https://community.crewai.com/u/Saeed_Kasmani)
#### Post date: [February 22, 2025, 12:46pm UTC](https://community.crewai.com/t/using-crewai-ollama-and-pandantic/4084/1 "2025-02-22T12:46:47Z")

</div>

I am using crewai, ollama, pandantic. But I am getting these error and it is frusttating.  
here is my codes:  
main.py  
#!/usr/bin/env python  
import sys  
import warnings  
from dotenv import load\_dotenv

load\_dotenv(‘creds.env’) # Adjust path if needed  
from resume\_crew.crew import ResumeCrew

warnings.filterwarnings(“ignore”, category=SyntaxWarning, module=“pysbd”)

def run():  
“”"  
Run the resume optimization crew.  
“”"  
inputs = {  
‘job\_url’: ‘[Jobs | Careers | McKinsey & Company](https://www.mckinsey.com/careers/search-jobs/jobs/associate-15178)’,  
‘company\_name’: ‘Mckinsey & Co.’  
}  
ResumeCrew().crew().kickoff(inputs=inputs)

if **name** == “ **main** ”:  
run()

##resume\_crew.py

```
import os 
os.environ["OPENAI_API_KEY"] = "sk-proj-oo86brBMfkJOgDC4E"
from crewai import Agent, Crew, Process, Task, LLM
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool, ScrapeWebsiteTool, PDFSearchTool
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
from .models import (
    JobRequirements,
    ResumeOptimization,
    CompanyResearch
)

from langchain_openai import ChatOpenAI

llm_local = ChatOpenAI(
model="ollama/phi4:latest",
base_url="http://localhost:11434"
)
# llm_local = LLM(
# model="ollama/phi4:latest",
# base_url="http://localhost:11434",
# api_key="ollama", # Adjust if needed by your local Ollama
# max_tokens=32000,
# temperature=0.1
# )

@CrewBase
class ResumeCrew():
    """ResumeCrew for resume optimization and interview preparation"""

    agents_config = 'config/agents.yaml'
    tasks_config = 'config/tasks.yaml'

    def __init__ (self) -> None:
        """Sample resume PDF for testing from https://www.hbs.edu/doctoral/Documents/job-market/CV_Mohan.pdf"""

        self.resume_pdf = PDFKnowledgeSource(
            file_paths=["CV_Mohan.pdf"],
            config=dict(
                llm=dict(
                    provider="ollama",
                    config=dict(
                        model="phi4:latest",
                        base_url="http://localhost:11434",
                    ),
                ),
                embedder=dict(
                    provider="ollama",
                    config=dict(
                        model="nomic-embed-text:latest",
                        base_url="http://localhost:11434", # Added base_url parameter
                    ),
                ),
            )
        )
        
        print(self.resume_pdf)

    @agent
    def resume_analyzer(self) -> Agent:
        return Agent(
            config=self.agents_config['resume_analyzer'],
            verbose=True,
            llm=llm_local,
            knowledge_sources=[self.resume_pdf]
        )
    
    @agent
    def job_analyzer(self) -> Agent:
        return Agent(
            config=self.agents_config['job_analyzer'],
            verbose=True,
            tools=[ScrapeWebsiteTool()],
            llm=llm_local
        )

    @agent
    def company_researcher(self) -> Agent:
        return Agent(
            config=self.agents_config['company_researcher'],
            verbose=True,
            tools=[SerperDevTool()],
            llm=llm_local,
            knowledge_sources=[self.resume_pdf]
        )

    @agent
    def resume_writer(self) -> Agent:
        return Agent(
            config=self.agents_config['resume_writer'],
            verbose=True,
            llm=llm_local
        )

    @agent
    def report_generator(self) -> Agent:
        return Agent(
            config=self.agents_config['report_generator'],
            verbose=True,
            llm=llm_local
        )

    @task
    def analyze_job_task(self) -> Task:
        return Task(
            config=self.tasks_config['analyze_job_task'],
            output_file='output/job_analysis.json',
            output_pydantic=JobRequirements
        )

    @task
    def optimize_resume_task(self) -> Task:
        return Task(
            config=self.tasks_config['optimize_resume_task'],
            output_file='output/resume_optimization.json',
            output_pydantic=ResumeOptimization
        )

    @task
    def research_company_task(self) -> Task:
        return Task(
            config=self.tasks_config['research_company_task'],
            output_file='output/company_research.json',  
            output_pydantic=CompanyResearch
        )

    @task
    def generate_resume_task(self) -> Task:
        return Task(
            config=self.tasks_config['generate_resume_task'],
            output_file='output/optimized_resume.md'
        )

    @task
    def generate_report_task(self) -> Task:
        return Task(
            config=self.tasks_config['generate_report_task'],
            output_file='output/final_report.md'
        )

    @crew
    def crew(self) -> Crew:
        return Crew(
            agents=self.agents,
            tasks=self.tasks,
            verbose=True,
            process=Process.sequential,
            knowledge_sources=[self.resume_pdf],
            embedder={
                "provider": "ollama",
                "config": {
                    "model": "nomic-embed-text:latest"
                }
            }
            # embedder={
            # "provider": "ollama",
            # "config": {
            # "model": "nomic-embed-text:latest",
            # # "api_key": "ollama",
            # # "base_url": "http://localhost:11434"
            # }
            # }
        )

```

#models.py  
from typing import List, Dict, Optional  
from pydantic import BaseModel, Field, confloat

class SkillScore(BaseModel):  
skill\_name: str = Field(description=“Name of the skill being scored”)  
required: bool = Field(description=“Whether this skill is required or nice-to-have”)  
match\_level: confloat(ge=0, le=1) = Field(description=“How well the candidate’s experience matches (0-1)”)  
years\_experience: Optional[float] = Field(description=“Years of experience with this skill”, default=None)  
context\_score: confloat(ge=0, le=1) = Field(  
description=“How relevant the skill usage context is to the job requirements”,  
default=0.5  
)

class JobMatchScore(BaseModel):  
overall\_match: confloat(ge=0, le=100) = Field(  
description=“Overall match percentage (0-100)”  
)  
technical\_skills\_match: confloat(ge=0, le=100) = Field(  
description=“Technical skills match percentage”  
)  
soft\_skills\_match: confloat(ge=0, le=100) = Field(  
description=“Soft skills match percentage”  
)  
experience\_match: confloat(ge=0, le=100) = Field(  
description=“Experience level match percentage”  
)  
education\_match: confloat(ge=0, le=100) = Field(  
description=“Education requirements match percentage”  
)  
industry\_match: confloat(ge=0, le=100) = Field(  
description=“Industry experience match percentage”  
)  
skill\_details: List[SkillScore] = Field(  
description=“Detailed scoring for each skill”,  
default\_factory=list  
)  
strengths: List[str] = Field(  
description=“List of areas where candidate exceeds requirements”,  
default\_factory=list  
)  
gaps: List[str] = Field(  
description=“List of areas needing improvement”,  
default\_factory=list  
)  
scoring\_factors: Dict[str, float] = Field(  
description=“Weights used for different scoring components”,  
default\_factory=lambda: {  
“technical\_skills”: 0.35,  
“soft\_skills”: 0.20,  
“experience”: 0.25,  
“education”: 0.10,  
“industry”: 0.10  
}  
)

class JobRequirements(BaseModel):  
technical\_skills: List[str] = Field(  
description=“List of required technical skills”,  
default\_factory=list  
)  
soft\_skills: List[str] = Field(  
description=“List of required soft skills”,  
default\_factory=list  
)  
experience\_requirements: List[str] = Field(  
description=“List of experience requirements”,  
default\_factory=list  
)  
key\_responsibilities: List[str] = Field(  
description=“List of key job responsibilities”,  
default\_factory=list  
)  
education\_requirements: List[str] = Field(  
description=“List of education requirements”,  
default\_factory=list  
)  
nice\_to\_have: List[str] = Field(  
description=“List of preferred but not required skills”,  
default\_factory=list  
)  
job\_title: str = Field(  
description=“Official job title”,  
default=“”  
)  
department: Optional[str] = Field(  
description=“Department or team within the company”,  
default=None  
)  
reporting\_structure: Optional[str] = Field(  
description=“Who this role reports to and any direct reports”,  
default=None  
)  
job\_level: Optional[str] = Field(  
description=“Level of the position (e.g., Entry, Senior, Lead)”,  
default=None  
)  
location\_requirements: Dict[str, str] = Field(  
description=“Location details including remote/hybrid options”,  
default\_factory=dict  
)  
work\_schedule: Optional[str] = Field(  
description=“Expected work hours and schedule flexibility”,  
default=None  
)  
travel\_requirements: Optional[str] = Field(  
description=“Expected travel frequency and scope”,  
default=None  
)  
compensation: Dict[str, str] = Field(  
description=“Salary range and compensation details if provided”,  
default\_factory=dict  
)  
benefits: List[str] = Field(  
description=“List of benefits and perks”,  
default\_factory=list  
)  
tools\_and\_technologies: List[str] = Field(  
description=“Specific tools, software, or technologies used”,  
default\_factory=list  
)  
industry\_knowledge: List[str] = Field(  
description=“Required industry-specific knowledge”,  
default\_factory=list  
)  
certifications\_required: List[str] = Field(  
description=“Required certifications or licenses”,  
default\_factory=list  
)  
security\_clearance: Optional[str] = Field(  
description=“Required security clearance level if any”,  
default=None  
)  
team\_size: Optional[str] = Field(  
description=“Size of the immediate team”,  
default=None  
)  
key\_projects: List[str] = Field(  
description=“Major projects or initiatives mentioned”,  
default\_factory=list  
)  
cross\_functional\_interactions: List[str] = Field(  
description=“Teams or departments this role interacts with”,  
default\_factory=list  
)  
career\_growth: List[str] = Field(  
description=“Career development and growth opportunities”,  
default\_factory=list  
)  
training\_provided: List[str] = Field(  
description=“Training or development programs offered”,  
default\_factory=list  
)  
diversity\_inclusion: Optional[str] = Field(  
description=“D&I statements or requirements”,  
default=None  
)  
company\_values: List[str] = Field(  
description=“Company values mentioned in the job posting”,  
default\_factory=list  
)  
job\_url: str = Field(  
description=“URL of the job posting”,  
default=“”  
)  
posting\_date: Optional[str] = Field(  
description=“When the job was posted”,  
default=None  
)  
application\_deadline: Optional[str] = Field(  
description=“Application deadline if specified”,  
default=None  
)  
special\_instructions: List[str] = Field(  
description=“Any special application instructions or requirements”,  
default\_factory=list  
)  
match\_score: JobMatchScore = Field(  
description=“Detailed scoring of how well the candidate matches the job requirements”,  
default\_factory=JobMatchScore  
)  
score\_explanation: List[str] = Field(  
description=“Detailed explanation of how scores were calculated”,  
default\_factory=list  
)

class ResumeOptimization(BaseModel):  
content\_suggestions: List[Dict[str, str]] = Field(  
description=“List of content optimization suggestions with ‘before’ and ‘after’ examples”  
)  
skills\_to\_highlight: List[str] = Field(  
description=“List of skills that should be emphasized based on job requirements”  
)  
achievements\_to\_add: List[str] = Field(  
description=“List of achievements that should be added or modified”  
)  
keywords\_for\_ats: List[str] = Field(  
description=“List of important keywords for ATS optimization”  
)  
formatting\_suggestions: List[str] = Field(  
description=“List of formatting improvements”  
)

class CompanyResearch(BaseModel):  
recent\_developments: List[str] = Field(  
description=“List of recent company news and developments”  
)  
culture\_and\_values: List[str] = Field(  
description=“Key points about company culture and values”  
)  
market\_position: Dict[str, List[str]] = Field(  
description=“Information about market position, including competitors and industry standing”  
)  
growth\_trajectory: List[str] = Field(  
description=“Information about company’s growth and future plans”  
)  
interview\_questions: List[str] = Field(  
description=“Strategic questions to ask during the interview”  
)

here is the error:  
(.venv) (base) skasmani@Saeeds-MacBook-Pro resume-optimization-crew % crewai run  
Running the Crew  
LLM value is an unknown object

[2025-02-22 23:46:17][ERROR]: Failed to upsert documents: APIStatusError. **init** () missing 2 required keyword-only arguments: ‘response’ and ‘body’  
Traceback (most recent call last):  
File “/Users/skasmani/Downloads/IBM/CSM/Experiments/csm/agentic\_ai/AgenticAI\_app/cv\_optimize/resume-optimization-crew/.venv/bin/run\_crew”, line 12, in   
sys.exit(run())  
^^^^^  
File “/Users/skasmani/Downloads/IBM/CSM/Experiments/csm/agentic\_ai/AgenticAI\_app/cv\_optimize/resume-optimization-crew/src/resume\_crew/main.py”, line 19, in run  
ResumeCrew().crew().kickoff(inputs=inputs)  
^^^^^^^^^^^^  
File “/Users/skasmani/Downloads/IBM/CSM/Experiments/csm/agentic\_ai/AgenticAI\_app/cv\_optimize/resume-optimization-crew/.venv/lib/python3.12/site-packages/crewai/project/crew\_base.py”, line 36, in **init**  
self.map\_all\_task\_variables()  
File “/Users/skasmani/Downloads/IBM/CSM/Experiments/csm/agentic\_ai/AgenticAI\_app/cv\_optimize/resume-optimization-crew/.venv/lib/python3.12/site-packages/crewai/project/crew\_base.py”, line 203, in map\_all\_task\_variables  
self.\_map\_task\_variables(  
File “/Users/skasmani/Downloads/IBM/CSM/Experiments/csm/agentic\_ai/AgenticAI\_app/cv\_optimize/resume-optimization-crew/.venv/lib/python3.12/site-packages/crewai/project/crew\_base.py”, line 236, in \_map\_task\_variables  
self.tasks\_config[task\_name][“agent”] = agentsagent\_name  
^^^^^^^^^^^^^^^^^^^^  
File “/Users/skasmani/Downloads/IBM/CSM/Experiments/csm/agentic\_ai/AgenticAI\_app/cv\_optimize/resume-optimization-crew/.venv/lib/python3.12/site-packages/crewai/project/utils.py”, line 11, in memoized\_func  
cache[key] = func(\*args, \*\*kwargs)  
^^^^^^^^^^^^^^^^^^^^^  
File “/Users/skasmani/Downloads/IBM/CSM/Experiments/csm/agentic\_ai/AgenticAI\_app/cv\_optimize/resume-optimization-crew/src/resume\_crew/crew.py”, line 62, in resume\_analyzer  
return Agent(  
^^^^^^  
File “/Users/skasmani/Downloads/IBM/CSM/Experiments/csm/agentic\_ai/AgenticAI\_app/cv\_optimize/resume-optimization-crew/.venv/lib/python3.12/site-packages/pydantic/main.py”, line 214, in **init**  
validated\_self = self. **pydantic\_validator**.validate\_python(data, self\_instance=self)  
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  
pydantic\_core.\_pydantic\_core.ValidationError: 1 validation error for Agent  
Value error, Invalid Knowledge Configuration: APIStatusError. **init** () missing 2 required keyword-only arguments: ‘response’ and ‘body’ [type=value\_error, input\_value={‘verbose’: True, ‘llm’: …d ATS compatibility.\n’}, input\_type=dict]  
For further information visit [Redirecting...](https://errors.pydantic.dev/2.10/v/value_error)  
sys:1: ResourceWarning: unclosed \<ssl.SSLSocket fd=7, family=2, type=1, proto=0, laddr=(‘192.168.0.52’, 63451), raddr=(‘162.159.140.245’, 443)\>  
An error occurred while running the crew: Command ‘[‘uv’, ‘run’, ‘run\_crew’]’ returned non-zero exit status 1.

(.venv) (base) skasmani@Saeeds-MacBook-Pro resume-optimization-crew %
