LangChain Integration¶
Use Jobko tools in your LangChain agents.
Installation¶
Quick Setup¶
from langchain.tools import StructuredTool
import requests
import os
JOBKO_API_KEY = os.environ.get("JOBKO_API_KEY")
JOBKO_URL = "https://jobko.ai/api/mcp/tools/call"
def jobko_request(name: str, arguments: dict = None):
"""Make a request to the Jobko API."""
response = requests.post(
JOBKO_URL,
headers={"Authorization": f"Bearer {JOBKO_API_KEY}"},
json={"name": name, "arguments": arguments or {}}
)
return response.json()
Creating Tools¶
Get Profile Tool¶
get_profile = StructuredTool.from_function(
func=lambda: jobko_request("get_profile"),
name="jobko_get_profile",
description="Get the user's job profile including skills, experience, and preferences"
)
Analyze Job Tool¶
from pydantic import BaseModel, Field
class AnalyzeJobInput(BaseModel):
job_url: str = Field(description="URL of the job posting to analyze")
def analyze_job(job_url: str) -> dict:
return jobko_request("analyze_job", {"job_url": job_url})
analyze_job_tool = StructuredTool.from_function(
func=analyze_job,
name="jobko_analyze_job",
description="Analyze a job posting URL against the user's profile. Returns match score, matching/missing skills, and recommendations. Costs $0.02.",
args_schema=AnalyzeJobInput
)
Generate CV Tool¶
class GenerateCVInput(BaseModel):
job_id: int = Field(description="ID of the analyzed job")
format: str = Field(default="pdf", description="Output format: pdf, docx, or markdown")
def generate_cv(job_id: int, format: str = "pdf") -> dict:
return jobko_request("generate_cv", {"job_id": job_id, "format": format})
generate_cv_tool = StructuredTool.from_function(
func=generate_cv,
name="jobko_generate_cv",
description="Generate a tailored CV for a specific job. Costs $0.20.",
args_schema=GenerateCVInput
)
Full Example Agent¶
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
# Create tools
tools = [
StructuredTool.from_function(
func=lambda: jobko_request("get_profile"),
name="jobko_get_profile",
description="Get user's job profile"
),
StructuredTool.from_function(
func=lambda: jobko_request("get_credits"),
name="jobko_get_credits",
description="Check Jobko credit balance"
),
StructuredTool.from_function(
func=lambda job_url: jobko_request("analyze_job", {"job_url": job_url}),
name="jobko_analyze_job",
description="Analyze a job posting URL. Costs $0.02."
),
]
# Create agent
llm = ChatOpenAI(model="gpt-4")
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful job search assistant with access to Jobko tools."),
MessagesPlaceholder(variable_name="chat_history", optional=True),
("human", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
agent = create_openai_tools_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# Run
result = agent_executor.invoke({
"input": "Analyze this job for me: https://linkedin.com/jobs/view/123456"
})
print(result["output"])
Using with LangGraph¶
from langgraph.prebuilt import create_react_agent
agent = create_react_agent(
model=ChatOpenAI(model="gpt-4"),
tools=tools,
state_modifier="You are a job search assistant with access to Jobko tools."
)
response = agent.invoke({
"messages": [("user", "What's my skill profile?")]
})
Error Handling¶
def jobko_request_safe(name: str, arguments: dict = None):
"""Make a request to Jobko API with error handling."""
try:
response = requests.post(
JOBKO_URL,
headers={"Authorization": f"Bearer {JOBKO_API_KEY}"},
json={"name": name, "arguments": arguments or {}},
timeout=30
)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 402:
return {"error": "Insufficient credits. Please add credits at jobko.ai/dashboard"}
elif e.response.status_code == 429:
return {"error": "Rate limit exceeded. Please wait and try again."}
raise