Agentic AI- 一小时魔改Cursor变身Devin

搏一搏,$20变$500:一小时魔改Cursor变身Devin

📚 更多LLM文章 | 🧰 开源代码 | 🎯 应用案例 | ❓ 常见问题

Cursor Windsurf Devin 功能覆盖

1- Agentic AI: 一小时魔改 Cursor 变身 Devin

" 工欲善其事,必先利其器。" — 在 AI 时代,我们不仅需要好的工具,更需要能够按照自己需求定制工具的能力。

1.1- 🧭 阅读指引

  • 初学者:建议按顺序阅读,特别关注背景介绍和魔改方案详解部分
  • Cursor/Windsurf 用户:可直接跳到魔改方案详解和开源资源部分
  • 仅了解概念:可重点阅读背景介绍、小结与成果展示以及后续展望部分
  • 准备动手实践:建议详细阅读魔改方案详解和开源资源部分,并参考 FAQ 解决可能遇到的问题
  • 开发者:可关注更多工具的使用部分,了解如何扩展 AI 能力

1.2- 背景介绍

在上一篇文章中,我们提到了 Devin 这种可以全自动进行编程的 Agentic AI。相比于其他 Agentic AI 工具,比如 Cursor 和 Windsurf,它有几个核心优势,尤其是流程规划自我进化更多的工具使用全自动的工作方式。这让 Devin 显得是一个下一代的工具,和现有的 Agentic AI 工具拉开了一个身位。

但是在用了它一段时间之后,我的 Builder’s Mindset 又开始蠢蠢欲动,驱使我魔改了 Windsurf 和 Cursor,让它们也能实现 Devin 90% 的功能。我也把魔改的方式开源了,让你也可以在一分钟之内就把 Cursor 或者 Windsurf 变成 Devin。而这篇文章主要是介绍魔改的具体思路,用这个例子来演示,Agentic AI 时代,不论是构建还是拓展,是一件多么有效率的事情。为了讨论简便起见,我们下面都先用 Cursor 来指代这一类工具,而到最后讨论一下,如果想要用 Windsurf 的话,需要做哪些微小的改动。

1.2.1- 工具对比表

工具 流程规划 自我进化 工具拓展 全自动执行 价格
Devin 有(自动、完善) 有(自我学习) 支持 $500/月
Cursor(魔改前) 有限 工具集不全 手动确认 $20/月
Cursor(魔改后) 接近 Devin 接近 Devin,可扩展 仍需确认或绕过 $20/月
Windsurf(魔改后) 接近Devin 有,但需间接实现 接近Devin,可扩展 支持Docker容器全自动执行 $15/月

1.3- 魔改方案详解

1.3.1- 流程规划和自我进化

在上一篇文章中也提到,Devin 的一个非常有意思的变化是,它更像一个有章法的实习生。它知道先做一个计划出来,然后在执行的过程中不断地更新计划的进度。这一方面,让我们作为 AI Manager 能够更轻松地掌握 AI 当前的进度;另一方面,也让它不至于偏离原有的计划,实现更高的思维深度和任务完成质量。

这个功能看起来很厉害,其实用 Cursor 是很容易实现的。

1.3.1.1- Cursor 的魔改方法

对于 Cursor 来说,它有一个特殊的文件,叫做 .cursorrules,放在打开文件夹的根目录上面。它的特殊之处在于,它让你可以改变 Cursor 对于后台 LLM 的 prompt。换言之,这个文件里的所有内容都会作为 prompt 的一部分,发给后端的 AI,比如 GPT 或者 Claude。这给我们的定制化带来了非常大的灵活性。

下面是一个实现计划与自我进化的 .cursorrules 文件示例:

# Cursor Agent 增强配置

## 1. 项目计划与进展追踪

### 当前计划
<!-- 
这里会记录当前的项目计划,由 AI 自动更新
初始状态为空,AI 会在第一次交互时创建计划
-->

### 进度追踪
<!-- 
这里会记录项目进展,由 AI 自动更新
-->

## 2. 学习与经验积累

### 项目特定知识
<!-- 
这里记录在项目过程中学到的特定知识
-->

### 错误与修正
<!-- 
这里记录曾经犯过的错误和解决方案
-->

## 3. 工作方式

每次新任务开始时:
1. 首先分析需求并制定详细计划
2. 将计划更新到"当前计划"部分
3. 计划应包含明确的步骤、预期结果和可能的挑战

每次完成一个任务步骤后:
1. 更新"进度追踪"部分
2. 反思这一步骤的执行情况
3. 必要时调整剩余计划

每次遇到错误或新知识时:
1. 记录在对应部分
2. 在后续工作中主动应用这些经验教训

每次与用户交互时:
1. 参考计划和进度,提供清晰的当前状态概述
2. 主动提出下一步行动建议

比如我们可以把计划的内容放在这个文件里,这样每次我们跟 Cursor 对话的时候,它都会得到一份最新版的计划。同时在这个文件里,我们也可以给它更详细的指令,比如让它任务开始的时候先思考和制定一个计划,每次做完一步之后都要更新这个计划。由于 Cursor 可以利用更改文件的 agent,而 .cursorrules 本身就是一个文件,因此这就实现了一个闭环:

它每次都会自动地读取这个文件的内容,了解最新动态,在经过思考之后,把更新后的进度和下一步的计划写到这个文件里,让我们始终能够得到最新的更新。

而自我进化的功能也可以使用类似的思路来实现。在 .cursorrules 这个文件里,我们加入 prompt,让 Cursor 在被用户更正它的行为之后思考刚才犯的错误,有没有什么可以复用的经验教训记录下来。如果有的话,就更新 .cursorrules 这个文件相关的章节。通过这种方式,也可以让它积累出针对每一个 project 的特定知识。

1.3.1.2- 实际案例

一个典型的例子就是,现在的 LLM,由于 knowledge cutoff date 相对较早,很多都不知道有 GPT-4o 这个模型。如果你让它调用 GPT-4o 的话,它会自己把 o 去掉,认为这里是打错了。那如果你更正它:" 其实已经有了这个模型,只是你不知道而已 ",它就会把这个教训记在 .cursorrules 相关的章节里面,以后就不会再犯这样的错误了,通过这种方式就实现了学习和提升。

但是这一点仍然取决于 prompt 到底有没有效,有些时候它确实也会漏掉这一点,不一定会把我们觉得有必要记成笔记的知识记下来。这种情况下,我们也可以用自然语言去 nudge 它一把,直接跟它说,你要把这点记下来。用这种更直接的方式也可以实现 AI 的经验积累和成长。

1.3.1.3- Windsurf 的差异

如果使用 Windsurf 的话,有一个不同的地方在于,可能是为了安全考虑,它是不允许 AI 直接更改 .windsurfrules 这个文件的。因此我们需要把它拆成两个部分,一个部分比如叫 scratchpad.md,总之使用另外一个文件名。而在 .windsurfrules 这个文件里提及:当你每次进行思考前,你要先看一眼 Scratchpad,并且在里面更新计划。这种间接的方式可能效果没有直接放在 .cursorrules 里面那么好,因为它毕竟还是需要 AI 去调一个 Agent,再根据反馈的结果进行思考,但试下来也是可以工作的。

1.3.2- 更多工具的使用

相比于 Cursor,Devin 的一个很大的优势是它可以使用更多的工具。比如可以调用浏览器进行搜索,可以浏览网页,甚至可以调用它自己的大脑,用 LLM 的智能对内容进行分析。这些在 Cursor 里都是不支持的,但好消息是,因为我们可以通过 .cursorrules 直接控制给 Cursor 的 prompt,而且它又有运行命令的能力,因此这又构成了一个闭环。

1.3.2.1- 实现方案

我们可以事先准备好一些写好的程序,比如 Python 库或者命令行,然后在 .cursorrules 里面向它介绍这些工具的用法,这样它就可以 learning on the fly,自然而然的学会如何使用这些工具来完成它的任务。

以下是一个简单的网页浏览工具的 Python 实现:

# web_browser.py
from playwright.sync_api import sync_playwright
import argparse
import html2text
import re

def browse_url(url, selector=None):
    """
    访问指定URL并返回页面内容,支持选择特定元素
    
    Args:
        url: 要访问的网页URL
        selector: 可选,CSS选择器,用于选择页面的特定部分
        
    Returns:
        返回页面内容的Markdown格式
    """
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()
        
        try:
            page.goto(url, wait_until="networkidle", timeout=60000)
            
            if selector:
                element = page.query_selector(selector)
                if element:
                    content = element.inner_html()
                else:
                    content = page.content()
            else:
                content = page.content()
                
            # 将HTML转换为Markdown以便AI更好地理解
            h = html2text.HTML2Text()
            h.ignore_links = False
            h.ignore_images = False
            h.ignore_tables = False
            
            markdown = h.handle(content)
            
            # 保留一些结构信息
            markdown = re.sub(r'<([a-z0-9]+)[^>]*class=["\']([^"\']*)["\'][^>]*>', 
                             r'<!-- \1 class: \2 -->', 
                             content) + "\n\n" + markdown
            
            return markdown
            
        except Exception as e:
            return f"Error browsing {url}: {str(e)}"
        finally:
            browser.close()

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Browse a URL and return content")
    parser.add_argument("url", help="URL to browse")
    parser.add_argument("--selector", help="Optional CSS selector to extract specific content")
    
    args = parser.parse_args()
    result = browse_url(args.url, args.selector)
    print(result)

.cursorrules 文件中介绍这个工具:

## 4. 可用工具

### 网页浏览工具
使用方法: `python web_browser.py <URL> [--selector "CSS选择器"]`
功能: 访问指定网页并返回Markdown格式的内容
示例: `python web_browser.py https://example.com --selector "div.main-content"`

而事实上,这些工具本身也可以使用 Cursor 在一两分钟内写出来。比如对于网页浏览这个工具,我在开源的项目里就用 Cursor 做了一个参考实现。其中有一些需要注意的技术决策:

  1. 网页抓取:为了实现对含有 JavaScript 内容的网页的抓取,我们在这里不使用 Python 自己的 request 库,而是使用 playwright 之类的浏览器。

  2. 内容处理:为了更好地跟 LLM 沟通,方便它对后续内容的理解和抓取,我们并没有单纯地使用 beautiful soup 来提取这个网页的文本内容,而是将它按照一定规则转化成了 markdown 格式,因而保留了它的 class name 和超链接等等更细节的基础信息,通过这样的方式,在更底层的方面支持 LLM 撰写后续的爬虫。

1.3.2.2- 搜索工具的选择

类似的,对于搜索的工具,有一个小坑是,不论是 Bing 还是 Google,它们的 API 的搜索质量都远远不如客户端,这主要是历史原因造成的,API 和网页端分别是不同的组来负责,但是 DuckDuckGo 则没有这样的问题,因此我们使用的参考实现用的是 DuckDuckGo 的免费 API。

下面是 DuckDuckGo 搜索工具的实现示例:

# web_search.py
import requests
import argparse
import json
from urllib.parse import quote_plus
import sys

def search_duckduckgo(query, num_results=5):
    """
    使用DuckDuckGo搜索API进行搜索
    
    Args:
        query: 搜索查询
        num_results: 返回结果数量
        
    Returns:
        搜索结果列表,每项包含标题、链接和摘要
    """
    # 对查询进行URL编码
    encoded_query = quote_plus(query)
    
    # DuckDuckGo搜索API
    url = f"https://api.duckduckgo.com/?q={encoded_query}&format=json&pretty=1"
    
    try:
        response = requests.get(url, headers={
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        })
        
        if response.status_code != 200:
            return f"Error: Received status code {response.status_code}"
        
        data = response.json()
        
        # 提取搜索结果
        results = []
        
        # 添加即时回答(如果有)
        if data.get('Abstract'):
            results.append({
                'title': 'Instant Answer',
                'link': data.get('AbstractURL', ''),
                'snippet': data.get('Abstract', '')
            })
        
        # 添加相关主题
        for topic in data.get('RelatedTopics', [])[:num_results]:
            if 'Text' in topic and 'FirstURL' in topic:
                results.append({
                    'title': topic.get('Text', '').split(' - ')[0] if ' - ' in topic.get('Text', '') else topic.get('Text', ''),
                    'link': topic.get('FirstURL', ''),
                    'snippet': topic.get('Text', '')
                })
        
        # 格式化输出为易读格式
        output = f"搜索结果: {query}\n\n"
        for i, result in enumerate(results, 1):
            output += f"{i}. {result['title']}\n"
            output += f"   链接: {result['link']}\n"
            output += f"   摘要: {result['snippet']}\n\n"
        
        return output
        
    except Exception as e:
        return f"搜索出错: {str(e)}"

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="搜索网络信息")
    parser.add_argument("query", help="搜索查询")
    parser.add_argument("--results", type=int, default=5, help="返回结果数量")
    
    args = parser.parse_args()
    print(search_duckduckgo(args.query, args.results))

.cursorrules 文件中添加这个工具的介绍:

### 网络搜索工具
使用方法: `python web_search.py "搜索查询" [--results 结果数量]`
功能: 从DuckDuckGo搜索信息并返回结果
示例: `python web_search.py "最新AI发展动态" --results 3`

1.3.2.3- LLM 分析能力

对于 Cursor 使用自己的脑力进行深入分析,这件事情相对复杂一些。一方面,Cursor 确实有一定程度的这样的能力,比如在上面的两个工具里,当我们把网页的内容打印在 stdout 上面的时候,它会作为 Cursor prompt 的一部分交给 LLM,因此它就可以对这些文本内容做出智能的分析。

但从另一个角度来说,Devin 有一个独特的能力,它可以用 LLM 对相对大量的文本做批量处理,这个 Cursor 是做不到的,所以为了让它有这样的能力,我们额外实现了一个工具,非常简单,就是把我们的 API key 事先在系统里设置好,然后让这个工具去调用 GPT 或者 Claude 或者我们本地的 LLM 的 API,通过这样的方式来让 Cursor 拥有用 LLM 批量处理文本的能力。在我的参考实现中,我使用的是我自己本地的一个 vllm cluster,但改动起来也非常简单,只需要把 base_url 那行去掉就可以了。

下面是一个简单的 LLM 分析工具实现:

# llm_analyze.py
import os
import sys
import argparse
import json
import requests
from openai import OpenAI

def analyze_with_llm(content, prompt, model="gpt-4o"):
    """
    使用LLM分析内容
    
    Args:
        content: 要分析的内容文本
        prompt: 给LLM的指令
        model: 使用的模型名称
        
    Returns:
        LLM的分析结果
    """
    # 从环境变量获取API密钥
    api_key = os.getenv("OPENAI_API_KEY")
    if not api_key:
        return "错误: 未设置OPENAI_API_KEY环境变量"
    
    try:
        client = OpenAI(api_key=api_key)
        # 如果需要使用本地LLM服务,取消下面这行的注释
        # client.base_url = "http://localhost:8000/v1"
        
        full_prompt = f"{prompt}\n\n以下是要分析的内容:\n\n{content}"
        
        response = client.chat.completions.create(
            model=model,
            messages=[
                {"role": "system", "content": "你是一个专业的数据分析助手,擅长从文本中提取有价值的信息。"},
                {"role": "user", "content": full_prompt}
            ],
            temperature=0.3,
            max_tokens=2000
        )
        
        return response.choices[0].message.content
        
    except Exception as e:
        return f"分析出错: {str(e)}"

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="使用LLM分析文本内容")
    parser.add_argument("--file", help="要分析的文件路径")
    parser.add_argument("--text", help="要分析的文本内容")
    parser.add_argument("--prompt", required=True, help="给LLM的分析指令")
    parser.add_argument("--model", default="gpt-4o", help="使用的模型名称")
    
    args = parser.parse_args()
    
    # 获取要分析的内容
    content = ""
    if args.file:
        try:
            with open(args.file, 'r', encoding='utf-8') as f:
                content = f.read()
        except Exception as e:
            print(f"读取文件出错: {str(e)}")
            sys.exit(1)
    elif args.text:
        content = args.text
    else:
        content = sys.stdin.read()
    
    result = analyze_with_llm(content, args.prompt, args.model)
    print(result)

.cursorrules 文件中添加这个工具的介绍:

### LLM分析工具
使用方法: 
- 文件分析: `python llm_analyze.py --file 文件路径 --prompt "分析指令"`
- 文本分析: `python llm_analyze.py --text "文本内容" --prompt "分析指令"`
- 管道输入: `cat 文件.txt | python llm_analyze.py --prompt "分析指令"`
功能: 使用LLM对大量文本进行深度分析和处理
示例: `python llm_analyze.py --file data.json --prompt "提取并总结这些数据中的主要趋势"`
环境变量: 需要设置OPENAI_API_KEY环境变量

1.3.2.4- 仍存在的局限

但是即使经过了这样的改动,我们仍然有两个工具,由于 Cursor 本身的限制没有办法实现:

  1. 图像理解:Devin 看起来是有理解图像的能力的,这是为什么它可以进行前端交互和测试的原因,但是由于 Cursor 的限制,我们没办法把一个图像作为输入传给后端的 AI,这个需要它在自己的实现上进行改动才可以。

  2. 反爬虫绕过:Devin 在数据抓取方面,非常神奇的不会被反爬虫算法判定成机器人,但是我们的网页获取工具在抓取数据的时候经常就要 captcha,或者直接就被封了。这个也许是可以解决的,我也还在探索,但是确实是 Devin 的一个独特的优势。

1.3.3- 全自动执行

最后一个非常有意思的特性是全自动执行。Devin 因为是在一个完全虚拟化的云端环境中执行,因此我们可以放心地让它执行各种命令,而不用担心它被 LLM 攻击或者抽风运行什么危险的命令。就算你把整个系统都删了,只要开一个新的 container,又是一条好汉。

但 Cursor 则由于在本机宿主系统上运行,则有很强的安全顾虑。这是为什么在 Cursor 的 agent mode 里面,我们每执行一个命令之前,都需要手工去确认。对于相对简单的任务,这样是可以接受的,但由于我们现在有了复杂的流程规划和自我进化的能力,Cursor 也可以有能力去完成长时间的复杂的任务,因而这种交互方式就显得不适应 Cursor 的能力了。

1.3.3.1- Cursor 的解决方案

为了解决这个问题,我目前还没找到基于 Cursor 的解决方法(更新:2024 年 12 月 17 日 Cursor 也加入了这个功能,叫Yolo Mode,但还不支持在 Docker 里开发)。

1.3.3.2- Windsurf 的优势方案

Windsurf 对这个是有所考量的,甚至我觉得从它的设计里面可以看出,它从一开始就是想奔着 Devin 这种产品形态走,而现有的代码编辑器只是它的一个中间形态而已。

更具体的说,Windsurf 有一个功能是直接和一个 Docker container 连起来,在那里面跑,或者如果我们有一个配置文件的话,它可以直接帮你新起一个 Docker container,做一些初始化,然后把你本地的一个文件夹映射过去。因此它执行的所有命令除了对本地文件夹的更改以外,全都是在 Docker container 里面进行的,对宿主系统没有任何影响,因而安全性得到了极大的提高。

下面是一个 Windsurf 的 Docker 配置示例:

// .windsurf/docker-config.json
{
  "image": "python:3.10-slim",
  "workdir": "/app",
  "volumes": [
    {
      "host": ".",
      "container": "/app"
    }
  ],
  "ports": [
    {
      "host": 8000,
      "container": 8000
    }
  ],
  "env": [
    {
      "name": "OPENAI_API_KEY",
      "value": "${OPENAI_API_KEY}"
    },
    {
      "name": "PATH",
      "value": "/usr/local/bin:${PATH}"
    }
  ],
  "init_commands": [
    "apt-get update && apt-get install -y curl git",
    "pip install --no-cache-dir --upgrade pip",
    "pip install -r requirements.txt || echo 'No requirements.txt found'"
  ]
}

这个配置文件会告诉 Windsurf 如何创建一个安全的 Docker 容器环境。当你使用此配置打开一个项目时,Windsurf 会:

  1. 拉取 Python 3.10 slim 镜像
  2. 将当前目录映射到容器中的 /app 目录
  3. 映射端口 8000(可用于 Web 应用程序开发)
  4. 传递环境变量(如 OpenAI API 密钥)
  5. 执行初始化命令安装必要依赖

在这个基础上,它又引入了黑白名单机制:

  • 对于黑名单上的命令一概自动拒绝执行
  • 对于白名单上的命令一概予以放行
  • 对于二者都不在的命令,则由 LLM 智能判断,对宿主系统是否有风险

下面是一个 Windsurf 命令白名单和黑名单配置示例:

// .windsurf/command-config.json
{
  "auto_approve": true,
  "whitelist": [
    "pip install",
    "npm install",
    "pytest",
    "python",
    "node",
    "git status",
    "git add",
    "git commit",
    "git pull",
    "git push",
    "ls",
    "cat",
    "cd",
    "mkdir",
    "touch"
  ],
  "blacklist": [
    "rm -rf /",
    "sudo",
    "chmod 777",
    "ssh-keygen",
    "curl -s | bash",
    "wget -O- | bash"
  ]
}

.windsurfrules 文件中,你可以这样引导 AI 使用 Docker 环境:

## 工作环境

你正在一个安全的Docker容器中运行,具有以下特点:
1. 基于Python 3.10镜像
2. 已预装git、curl等基本工具
3. 项目文件位于/app目录
4. 端口8000已映射到主机

请注意以下事项:
1. 你可以自由执行大多数命令,系统已配置了安全防护
2. 命令会在容器内执行,不会影响用户主机系统
3. 容器状态不会永久保存,因此需要确保重要数据写入到项目文件夹中
4. 如需安装依赖,请更新requirements.txt文件

当你遇到需要长时间运行的命令(如Web服务器)时,应该在后台运行或使用新终端会话。

比如如果它要删除文件夹中的某个文件的话,它会让用户确认,但是一般的 pip install 之类的命令,它会直接放过。但注意这个特性似乎只有在 Docker container 里面运行的时候,才会被启用。如果我们是在宿主系统中运行命令的话,体验仍然和 Cursor 很像,还是需要频繁地按确认。同时,自动的命令执行也需要在配置中进行开启。

1.4- 小结与成果展示

因此我们可以看出,虽然 Devin 的产品形态和设计理念确实非常先进,但是从技术壁垒上来说,它和现有的 Agentic AI 的工具之间的沟壑并没有我们想象的那么大。使用基于 15 到 20 美元每个月的流行工具,比如 Cursor 和 Windsurf,我们完全可以在一小时内实现 Devin 90% 的功能,并且用它来完成以魔改前做不到的复杂任务。

1.4.1- 实际应用案例

  1. 金融数据分析:我给 Cursor 布置了一个任务,是分析一下近 5 年来热门科技股票的收益率,做一个深度的数据分析,它给了一个非常详尽完善的报告。

    具体实现流程

    • 首先让 Cursor 使用搜索工具获取苹果、谷歌、微软、亚马逊和特斯拉等科技巨头的股票数据
    • Cursor 自动使用 Python 编写了爬虫脚本,抓取 Yahoo Finance 的历史数据
    • 使用 Pandas 进行数据清洗和预处理
    • 自动计算年化收益率、波动率、夏普比率等指标
    • 生成可视化图表(使用 Matplotlib 和 Seaborn)
    • 最后撰写完整分析报告,包括各公司业绩比较和投资建议
  2. 内容数据可视化:我让 Windsurf 抓取我的博客前 100 篇文章的发贴时间,并且把它用 github 贡献图这样的方式可视化出来,它也可以全自动的完成。

    具体实现流程

    • Windsurf 首先分析了博客的结构和分页机制
    • 编写专门的爬虫代码提取文章发布时间
    • 设计了类似 GitHub 贡献图的热力图可视化
    • 自动分析发文规律,找出高产期和低产期
    • 生成互动式网页展示结果

    代码示例(部分):

    # 生成GitHub风格的贡献热力图
    def create_contribution_heatmap(post_dates):
        # 按日期计数
        date_counts = {}
        for date in post_dates:
            date_str = date.strftime('%Y-%m-%d')
            date_counts[date_str] = date_counts.get(date_str, 0) + 1
        
        # 创建日历热力图
        all_dates = pd.date_range(start=min(post_dates), end=max(post_dates))
        data = []
        for date in all_dates:
            date_str = date.strftime('%Y-%m-%d')
            count = date_counts.get(date_str, 0)
            data.append({
                'date': date_str,
                'count': count,
                'intensity': min(count, 4)  # 0-4 表示强度级别
            })
        
        return data
    

    博客活跃度可视化

  3. 全栈开发:作为一个完全不懂前端的开发者,我花了一个半小时做出来了一个有前端后端五脏俱全的招聘网站。这个效率和 Devin 相当接近甚至更高了。

    具体实现流程

    • Cursor 先规划了整个项目架构:
      • 前端:React + Tailwind CSS
      • 后端:FastAPI
      • 数据库:SQLite(简化开发)
    • 一步步实现了关键功能:
      • 用户注册/登录(求职者和招聘方)
      • 职位发布、搜索和筛选
      • 简历上传和管理
      • 在线申请和跟踪
    • 自动编写了单元测试和部署脚本

    项目结构截图

    recruitment-platform/
    ├── backend/
    │   ├── app/
    │   │   ├── api/
    │   │   ├── core/
    │   │   ├── models/
    │   │   └── services/
    │   ├── tests/
    │   └── main.py
    ├── frontend/
    │   ├── public/
    │   ├── src/
    │   │   ├── components/
    │   │   ├── pages/
    │   │   ├── services/
    │   │   └── App.js
    │   └── package.json
    ├── docker-compose.yml
    └── README.md
    

效率与质量对比
在上述案例中,我用魔改后的 Cursor/Windsurf 完成任务的时间与使用 Devin 相当,有时甚至更快。核心原因是通过自定义工具和流程规划,我们创造了一个更加适合特定任务的工作流,减少了不必要的交互和等待。

像这两种任务用传统的 cursor 和 Windsurf 都是没办法做出来的,只有用 Devin 才可以,但是在做了这个简单的更改之后,我们用一个月只要 $20美元的工具,也可以实现一个月$500 美元的工具的效果。

1.5- 开源资源

所有在文中提到的魔改配置文件和工具代码都已开源,你可以在我的 GitHub仓库 下载。只需要把里面的内容拷贝到你当前工程的文件夹下面就可以立即使用。

1.5.1- 仓库结构

agentic-ai-tools/
├── cursor/
│   ├── .cursorrules           # Cursor 增强配置文件
│   ├── tools/                 # 工具集合
│   │   ├── web_browser.py     # 网页浏览工具
│   │   ├── web_search.py      # 网络搜索工具
│   │   └── llm_analyze.py     # LLM 分析工具
│   └── README.md              # 使用说明
├── windsurf/
│   ├── .windsurfrules         # Windsurf 增强配置文件
│   ├── .windsurf/             # Windsurf 配置目录
│   │   ├── docker-config.json # Docker 容器配置
│   │   └── command-config.json# 命令白名单/黑名单配置
│   ├── tools/                 # 工具集合(与 Cursor 相同)
│   └── README.md              # 使用说明
└── examples/                  # 示例项目
    ├── stock-analysis/        # 股票分析项目示例
    ├── blog-visualization/    # 博客可视化项目示例
    └── recruitment-site/      # 招聘网站项目示例

1.5.2- 快速开始

只需三步即可将 Cursor 或 Windsurf 魔改成类似 Devin 的体验:

  1. 克隆仓库:git clone https://github.com/username/agentic-ai-tools.git
  2. 复制需要的配置文件到你的项目根目录:
    • Cursor 用户:cp -r agentic-ai-tools/cursor/.cursorrules agentic-ai-tools/cursor/tools/ your-project/
    • Windsurf 用户:cp -r agentic-ai-tools/windsurf/.windsurfrules agentic-ai-tools/windsurf/.windsurf agentic-ai-tools/windsurf/tools/ your-project/
  3. 确保安装了必要的依赖:pip install -r agentic-ai-tools/requirements.txt

1.6- 后续展望

随着 Agentic AI 技术的快速发展,我们可以预见未来会有更多类似 Devin 的工具出现,它们将进一步降低编程的门槛,提高开发效率。而通过这种魔改和自定义的方式,我们也可以不断扩展现有工具的能力边界,创造出更适合自己需求的 AI 助手。

1.6.1- 未来改进方向

  1. 增强图像理解能力

    • 虽然目前的魔改方案无法实现图像理解,但随着 Cursor 和 Windsurf 的升级,这一功能可能会被原生支持
    • 临时解决方案可以是通过图像描述服务将图像转换为文本描述,再传递给 AI
  2. 改进反爬虫策略

    • 探索使用更先进的浏览器指纹模拟技术
    • 实现自动化的验证码识别和绕过
    • 使用代理轮换和请求速率限制
  3. 知识库建设

    • 为 AI 助手构建领域特定的知识库
    • 实现更持久化的学习机制,不仅限于单个项目
    • 开发跨项目的经验和最佳实践共享机制
  4. 工具生态系统扩展

    • 创建更多专业领域的工具集
    • 建立工具市场,允许社区贡献和分享工具
    • 提供工具推荐机制,根据项目类型自动建议适用的工具

1.6.2- 行业趋势与影响

随着像 Devin、Cursor 和 Windsurf 这样的 Agentic AI 工具的普及,我们看到了几个明显的趋势:

  1. 编程民主化

    • 编程门槛将持续降低,使更多非专业开发者能够构建软件
    • " 公民开发者 " 将成为主流,他们通过 AI 辅助工具来实现想法
  2. 开发者角色转变

    • 专业开发者将从编写具体代码转向更高层次的架构设计和业务逻辑定义
    • AI 协作将成为开发者必备的技能
    • 更多精力将放在创意和解决方案设计上,而非实现细节
  3. 生产力提升

    • 项目交付时间将大幅缩短
    • 更多资源将投入到创新而非维护
    • 软件更新和迭代周期将加速
  4. 自定义工具的兴起

    • 类似本文介绍的魔改方案将变得常见
    • 开发者会构建适合自己特定工作流的 AI 工具
    • 大型通用工具与小型专用工具将共存

1.7- 常见问题解答(FAQ)

1.7.1- 配置与安装相关

Q1: 如何判断魔改是否生效?
A1: 当你第一次输入一个较复杂的任务时,如果 Cursor/Windsurf 开始主动规划任务步骤,并且在完成一步后自动更新计划,那就说明魔改已经生效。你也可以查看工作目录中的 .cursorrules.windsurfrules 文件,如果其中的计划部分被更新,也表明魔改成功。

Q2: 安装过程中遇到依赖问题怎么办?
A2: 首先确保你已经安装了主要依赖:pip install playwright html2text requests openai。如果仍有问题,检查 Python 版本(推荐 3.8+)。对于 playwright,可能需要额外运行 playwright install 来安装浏览器。

Q3: 我的配置文件没有被 Cursor/Windsurf 读取怎么办?
A3: 确保配置文件位于项目根目录,文件名正确(包括前面的点)。有时候需要重启 Cursor/Windsurf 来使配置生效。如果使用 Windows,确保没有隐藏文件扩展名,防止文件实际被保存为 .cursorrules.txt

1.7.2- 功能与限制相关

Q4: 魔改后的工具会记住跨项目的知识吗?
A4: 默认情况下不会。每个项目的 .cursorrules 文件只在当前项目中有效。但你可以维护一个个人知识库文件,在新项目开始时复制进去,这样可以实现一定程度的知识积累。

Q5: 魔改后的工具是否可以完全取代 Devin?
A5: 虽然功能相似,但仍有差距。Devin 在图像理解、反爬虫和全自动执行方面仍有优势。但对于大多数开发任务,魔改工具已经足够强大,尤其考虑到价格差异。

Q6: 为什么有时候它忘记更新计划和进度?
A6: 这与底层 LLM 的不确定性有关。有时候它可能忽略 prompt 的某些部分。当发现它没有更新计划时,可以直接提醒它:" 请记得更新当前计划和进度 ",通常就会恢复正常工作。

1.7.3- 安全与性能相关

Q7: 在 Docker 中运行命令是否完全安全?
A7: 虽然比直接在宿主机上运行更安全,但仍需谨慎。Docker 容器如果配置不当(如挂载敏感目录),理论上仍可能对宿主系统造成影响。建议使用黑名单屏蔽高风险命令。

Q8: 网页浏览和搜索工具会对 API 密钥造成安全风险吗?
A8: 工具本身不会造成风险,但要注意不要将 API 密钥硬编码在脚本中。最佳做法是使用环境变量或专门的密钥管理工具来存储和调用这些敏感信息。

Q9: 如何优化 LLM 分析工具的性能?
A9: 对于大型文本,可以先使用简单的文本处理(如关键词提取、摘要生成)减少文本量,然后再传给 LLM。此外,选择正确的模型也很重要:对于不需要高推理能力的任务,可以使用更快的模型如 GPT-3.5。

1.7.4- 扩展与开发相关

Q10: 如何添加自定义工具?
A10: 创建新的 Python 脚本,遵循现有工具的模式(接受命令行参数,返回结果到标准输出),然后在 .cursorrules 文件中添加对应的工具说明。示例:

# my_custom_tool.py
import argparse

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("input", help="Input data")
    args = parser.parse_args()
    
    # 工具逻辑...
    result = process_data(args.input)
    
    print(result)  # 输出结果供AI读取

if __name__ == "__main__":
    main()

然后在 .cursorrules 中添加:

### 我的自定义工具
使用方法: `python my_custom_tool.py "输入数据"`
功能: 描述工具的功能...
示例: `python my_custom_tool.py "示例输入"`

Q11: 可以让 Cursor/Windsurf 使用第三方 API 吗?
A11: 可以。创建封装该 API 的 Python 脚本,处理认证和数据格式化,然后在 .cursorrules 中介绍这个工具。这样 AI 就能学会调用这个脚本来间接使用第三方 API。

Q12: 如何让多人协作时共享同一套魔改配置?
A12: 将魔改配置文件和工具脚本加入版本控制,并在项目的 README 中说明使用方法。还可以创建一个安装脚本,自动设置必要的环境变量和依赖项。对于团队协作,可以考虑使用 Docker Compose 配置一个标准开发环境。



然后在 `.cursorrules` 中添加:

```markdown
### 我的自定义工具
使用方法: `python my_custom_tool.py "输入数据"`
功能: 描述工具的功能...
示例: `python my_custom_tool.py "示例输入"`

Q11: 可以让 Cursor/Windsurf 使用第三方 API 吗?
A11: 可以。创建封装该 API 的 Python 脚本,处理认证和数据格式化,然后在 .cursorrules 中介绍这个工具。这样 AI 就能学会调用这个脚本来间接使用第三方 API。

Q12: 如何让多人协作时共享同一套魔改配置?
A12: 将魔改配置文件和工具脚本加入版本控制,并在项目的 README 中说明使用方法。还可以创建一个安装脚本,自动设置必要的环境变量和依赖项。对于团队协作,可以考虑使用 Docker Compose 配置一个标准开发环境。