在当今竞争激烈的就业市场中,求职者往往面临海量岗位筛选效率低、重复投递耗时耗力、HR回复率不高等核心痛点。传统的手动投递方式不仅耗时耗力,还容易错失优质机会。本文将详细介绍如何利用AI智能体技术,构建一个能够自动浏览招聘网站、筛选岗位、投递简历的智能助手,彻底改变传统求职方式。

一、系统架构设计

1.1 核心架构理念

AI求职智能体采用视觉识别+行为模拟的双引擎架构,通过模拟人类操作实现真正的"人机协作"求职。与传统的爬虫技术不同,AI模拟操作智能体能够像真人一样"看"屏幕、"理解"内容、"思考"决策并"动手"操作,从而避免被招聘平台的反爬机制识别。

三层架构设计

  • 视觉感知层:负责获取手机/电脑屏幕的实时图像,并深度理解图像内容

  • 决策推理层:基于屏幕内容、用户指令和记忆,规划下一步操作

  • 行为执行层:将决策转化为精准的模拟操作,执行点击、滑动、输入等动作

1.2 技术栈选择

核心框架

  • Mineru:移动设备远程操作接口,提供实时屏幕流

  • VLA多模态大模型:视觉语言动作模型,进行像素级理解和决策推理

  • Playwright:现代浏览器自动化工具,比Selenium更高效稳定

  • Python:核心开发语言,生态丰富且易于扩展

辅助工具

  • OpenCV:图像处理和视觉识别

  • Tesseract:OCR文字识别

  • PyTorch/TensorFlow:构建和微调NLP模型

  • SQLite/Chroma:记忆存储和向量数据库

二、核心模块实现

2.1 视觉感知层实现

视觉感知层是智能体的"眼睛",负责理解屏幕内容。以下是基于OpenCV和Tesseract的核心实现:



import cv2
import pytesseract
import numpy as np
from PIL import Image
import pyautogui

class VisionProcessor:
    def __init__(self):
        # 预定义UI元素模板
        self.templates = {
            'login_button': cv2.imread('templates/login_button.png', 0),
            'search_box': cv2.imread('templates/search_box.png', 0),
            'apply_button': cv2.imread('templates/apply_button.png', 0)
        }
    
    def capture_screen(self, region=None):
        """捕获屏幕截图"""
        screenshot = pyautogui.screenshot(region=region)
        return cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
    
    def extract_text(self, image, lang='chi_sim+eng'):
        """从图像中提取文字"""
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        text = pytesseract.image_to_string(gray, lang=lang)
        return text.strip()
    
    def find_element(self, image, template_name, threshold=0.8):
        """模板匹配查找UI元素"""
        template = self.templates[template_name]
        result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
        
        if max_val >= threshold:
            h, w = template.shape[:2]
            center_x = max_loc[0] + w // 2
            center_y = max_loc[1] + h // 2
            return (center_x, center_y)
        return None
    
    def detect_job_list(self, image):
        """检测岗位列表区域"""
        # 使用边缘检测和轮廓分析定位列表区域
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        edges = cv2.Canny(gray, 50, 150)
        contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        
        job_rects = []
        for contour in contours:
            x, y, w, h = cv2.boundingRect(contour)
            if 200 < w < 800 and 50 < h < 200:  # 岗位卡片尺寸范围
                job_rects.append((x, y, w, h))
        
        return job_rects

2.2 决策推理层实现

决策推理层基于大语言模型,能够理解页面内容并制定操作策略:



from langchain.schema import SystemMessage, HumanMessage
from langchain.chat_models import ChatOpenAI
import json

class DecisionMaker:
    def __init__(self, api_key):
        self.llm = ChatOpenAI(
            model="gpt-4o",
            temperature=0.1,
            openai_api_key=api_key
        )
    
    def analyze_page(self, screenshot_text, current_state):
        """分析当前页面并制定操作策略"""
        prompt = f"""
        你是一个自动求职助手,正在浏览招聘网站。当前页面内容如下:
        
        {screenshot_text}
        
        当前状态:{current_state}
        
        请分析当前页面类型,并制定下一步操作策略。输出格式为JSON:
        {{
            "page_type": "login_page|job_list|job_detail|apply_page|unknown",
            "actions": [
                {{
                    "type": "click|type|scroll|wait",
                    "target": "元素描述或坐标",
                    "value": "输入内容(如为type操作)",
                    "delay": "操作后等待时间(秒)"
                }}
            ],
            "next_state": "新的状态描述"
        }}
        """
        
        messages = [
            SystemMessage(content="你是一个专业的求职助手,能够准确识别招聘网站页面并制定操作策略。"),
            HumanMessage(content=prompt)
        ]
        
        response = self.llm(messages)
        return json.loads(response.content)
    
    def match_job(self, job_description, resume_data):
        """匹配岗位与简历"""
        prompt = f"""
        请分析以下岗位描述与简历的匹配度:
        
        岗位描述:
        {job_description}
        
        简历信息:
        {json.dumps(resume_data, ensure_ascii=False)}
        
        请输出匹配度评分(0-100分)和匹配理由。输出格式:
        {{
            "score": 85,
            "reason": "匹配理由...",
            "recommend": true|false
        }}
        """
        
        messages = [
            SystemMessage(content="你是一个专业的HR,能够准确评估简历与岗位的匹配度。"),
            HumanMessage(content=prompt)
        ]
        
        response = self.llm(messages)
        return json.loads(response.content)

2.3 行为执行层实现

行为执行层负责将决策转化为实际动作,模拟人类操作:



import pyautogui
import time
import random
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class ActionExecutor:
    def __init__(self):
        self.driver = None
        self.pyautogui = pyautogui
        self.pyautogui.PAUSE = 0.5  # 默认操作间隔
    
    def start_browser(self, url):
        """启动浏览器并打开指定URL"""
        options = webdriver.ChromeOptions()
        options.add_argument('--disable-blink-features=AutomationControlled')
        options.add_experimental_option("excludeSwitches", ["enable-automation"])
        options.add_experimental_option('useAutomationExtension', False)
        
        self.driver = webdriver.Chrome(options=options)
        self.driver.get(url)
        time.sleep(2)
    
    def execute_action(self, action):
        """执行单个操作"""
        action_type = action['type']
        target = action.get('target')
        value = action.get('value')
        delay = action.get('delay', random.uniform(0.5, 1.5))
        
        if action_type == 'click':
            if isinstance(target, tuple):  # 坐标点击
                self.pyautogui.click(target[0], target[1])
            else:  # 元素点击
                element = self.driver.find_element(By.XPATH, target)
                element.click()
        
        elif action_type == 'type':
            if isinstance(target, tuple):  # 坐标输入
                self.pyautogui.click(target[0], target[1])
                self.pyautogui.typewrite(value)
            else:  # 元素输入
                element = self.driver.find_element(By.XPATH, target)
                element.clear()
                element.send_keys(value)
        
        elif action_type == 'scroll':
            if target == 'down':
                self.driver.execute_script("window.scrollBy(0, 500);")
            elif target == 'up':
                self.driver.execute_script("window.scrollBy(0, -500);")
        
        elif action_type == 'wait':
            time.sleep(delay)
        
        time.sleep(random.uniform(0.3, 0.8))  # 随机延迟,模拟人类操作
    
    def handle_captcha(self):
        """处理验证码(需要人工干预)"""
        print("检测到验证码,请手动处理...")
        input("处理完成后按回车继续...")
    
    def close(self):
        """关闭浏览器"""
        if self.driver:
            self.driver.quit()

三、智能体工作流实现

3.1 主工作流控制器

基于LangGraph构建智能体工作流,实现状态管理和异常处理:



from langgraph.graph import StateGraph, END
from typing import TypedDict, List, Optional
import json

class AgentState(TypedDict):
    current_url: str
    screenshot_text: str
    current_state: str
    actions: List[dict]
    job_list: List[dict]
    applied_jobs: List[str]
    error_count: int

class JobAgent:
    def __init__(self, vision_processor, decision_maker, action_executor):
        self.vision = vision_processor
        self.decision = decision_maker
        self.executor = action_executor
        self.workflow = self._create_workflow()
    
    def _create_workflow(self):
        """创建智能体工作流"""
        workflow = StateGraph(AgentState)
        
        # 添加节点
        workflow.add_node('capture_screen', self.capture_screen)
        workflow.add_node('analyze_page', self.analyze_page)
        workflow.add_node('execute_actions', self.execute_actions)
        workflow.add_node('handle_error', self.handle_error)
        
        # 定义流程
        workflow.set_entry_point('capture_screen')
        workflow.add_edge('capture_screen', 'analyze_page')
        workflow.add_edge('analyze_page', 'execute_actions')
        workflow.add_edge('execute_actions', 'capture_screen')  # 循环处理
        
        # 异常处理
        workflow.add_conditional_edges(
            'execute_actions',
            self.check_error,
            {
                'error': 'handle_error',
                'continue': 'capture_screen'
            }
        )
        
        workflow.add_edge('handle_error', 'capture_screen')
        
        return workflow.compile()
    
    def capture_screen(self, state: AgentState):
        """捕获屏幕并提取文字"""
        screenshot = self.vision.capture_screen()
        text = self.vision.extract_text(screenshot)
        return {'screenshot_text': text}
    
    def analyze_page(self, state: AgentState):
        """分析页面并制定操作策略"""
        result = self.decision.analyze_page(
            state['screenshot_text'], 
            state['current_state']
        )
        return {'actions': result['actions'], 'current_state': result['next_state']}
    
    def execute_actions(self, state: AgentState):
        """执行操作序列"""
        for action in state['actions']:
            try:
                self.executor.execute_action(action)
            except Exception as e:
                print(f"操作执行失败: {e}")
                return {'error_count': state.get('error_count', 0) + 1}
        return {'error_count': 0}
    
    def check_error(self, state: AgentState):
        """检查是否需要处理错误"""
        if state.get('error_count', 0) >= 3:
            return 'error'
        return 'continue'
    
    def handle_error(self, state: AgentState):
        """处理错误状态"""
        print("连续多次操作失败,请检查网络或页面状态")
        # 尝试刷新页面或重新登录
        self.executor.driver.refresh()
        time.sleep(3)
        return {'error_count': 0}
    
    def run(self, start_url):
        """启动智能体"""
        self.executor.start_browser(start_url)
        initial_state = AgentState(
            current_url=start_url,
            screenshot_text="",
            current_state="initial",
            actions=[],
            job_list=[],
            applied_jobs=[],
            error_count=0
        )
        
        try:
            for step in self.workflow.stream(initial_state):
                print(f"Step: {step}")
        except KeyboardInterrupt:
            print("程序被用户中断")
        finally:
            self.executor.close()

3.2 实战配置与使用

环境准备



# 安装依赖
pip install opencv-python pytesseract pyautogui selenium langchain langgraph

# 安装浏览器驱动
playwright install chromium

配置文件(config.yaml):



resume:
  name: "张三"
  email: "zhangsan@example.com"
  phone: "123-456-7890"
  skills: ["Python", "机器学习", "数据分析"]
  experience: 3
  education: "本科"

preferences:
  target_cities: ["北京", "上海", "深圳"]
  min_salary: 25000
  max_salary: 40000
  job_types: ["全职", "远程"]
  keywords: ["Python开发", "数据分析", "机器学习"]

platforms:
  boss: true
  lagou: true
  zhilian: true

ai:
  api_key: "your_openai_api_key"
  model: "gpt-4o"
  temperature: 0.1

启动智能体



from job_agent import JobAgent, VisionProcessor, DecisionMaker, ActionExecutor

# 初始化组件
vision = VisionProcessor()
decision = DecisionMaker(api_key="your_api_key")
executor = ActionExecutor()

# 创建智能体
agent = JobAgent(vision, decision, executor)

# 启动求职流程
agent.run("https://www.zhipin.com")

四、优化策略与进阶功能

4.1 反检测优化

为避免被招聘平台识别为自动化程序,需实施以下策略:

  • 人性化操作间隔:在操作之间添加随机延迟(1-3秒),模拟人类操作节奏

  • 浏览器指纹伪装:随机化User-Agent和视窗大小,使用无头浏览器模式

  • 行为模式多样化:模拟人类鼠标移动轨迹,添加随机滚动操作

  • 验证码处理:遇到验证码时暂停并通知用户手动处理

4.2 性能优化

随着投递规模增大,系统性能优化至关重要:

  • 异步处理:使用asyncio实现并发投递,大幅提升效率

  • 缓存机制:对频繁访问的页面元素和匹配结果进行缓存

  • 分布式架构:当需要大规模投递时,可采用Celery实现分布式任务队列

4.3 进阶功能

智能匹配优化

  • 基于岗位描述动态调整简历内容

  • 根据HR回复率动态调整投递策略

  • 学习用户偏好,自动优化搜索条件

数据可视化

  • 实时展示投递进度和成功率

  • 分析各平台投递效果,优化平台选择

  • 生成求职报告,帮助用户调整求职策略

五、总结

通过Python和现代AI技术构建自动求职智能体,不仅能大幅提升求职效率,还能实现更精准的人岗匹配。本文介绍的架构结合了视觉感知、智能处理和自动执行三大模块,形成了一个完整的解决方案。

关键成功因素

  • 精准的简历-JD匹配算法确保投递质量

  • 自适应页面解析能力应对不同招聘平台

  • 人性化操作模式避免被检测

  • 完善的异常处理机制保证系统稳定运行

这种智能体不仅是求职工具,更体现了AI技术在改善人类工作生活方面的巨大潜力。随着技术发展,未来的求职过程将更加智能化、个性化。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐