当前位置: 代码网 > 服务器>软件设计>开源 > 无需邀请码!Manus复刻开源版OpenManus下载安装与体验

无需邀请码!Manus复刻开源版OpenManus下载安装与体验

2025年03月10日 开源 我要评论
manus是什么?manus 是 monica 团队推出的全球首款通用型 ai agent。manus能独立思考、规划和执行复杂任务,直接交付完整成果。与传统 ai 不同,manus 拥有强大的工具调

manus是什么?

manus 是 monica 团队推出的全球首款通用型 ai agent。manus能独立思考、规划和执行复杂任务,直接交付完整成果。与传统 ai 不同,manus 拥有强大的工具调用能力,能自主完成从任务规划到执行的全流程,如文件处理、数据分析、代码编写、内容创作等。manus在 gaia 基准测试中表现优异,远超openai的deep research。manus 的设计理念是“知行合一”,基于智能化手段扩展人类能力,成为人类的智能伙伴。目前,manus 仍处于内测阶段,需要使用邀请码登录使用。

说人话就是,你告诉他任务的目标或方案,他给你干活,并自动给你一个最终结果比如帮你处理文件、分析数据、写代码、创作内容等,而这些都是一气呵成的,不需要人工干预

openmanus又是什么?

openmanus 是 metagpt 团队推出的开源复刻版 manus,提供无需邀请码的 ai agent 。openmanus基于模块化设计,支持多种语言模型和工具链,能执行代码、处理文件、搜索网络信息等复杂任务。openmanus 的核心优势在于实时反馈机制,用户能直观看到 ai 的思考过程和任务执行进度。openmanus具备强大的工具链和灵活的配置选项,方便开发者根据需求进行定制。 

简单来说 openmanus是的开源版,manus能做的事情,openmanus也可以实现,并且openmanus还可以安装在本地,无需服务器,无需多高性能的电脑配置,只需要一个像deepseek,或chatgpt的api账号即可使用

openmanus环境配置与安装

使用openmanus官方推荐uv安装方法:python3.11+uv

uv是由astral公司(rust工具ruff的开发者)推出的高性能python包管理工具,基于rust编写,旨在替代传统的pippip-tools。其核心优势在于极快的速度(比pip快10-100倍)、轻量级设计(仅几十mb)以及现代化的依赖管理(支持pyproject.tomluv.lock文件)。uv集成了虚拟环境管理、python版本控制、依赖解析等功能,目标是成为类似rust cargo的全能工具,简化python开发流程。

在windows上安装uv的2种方法

通过pip安装(推荐)直接使用python自带的pip安装,兼容性最佳:

pip install uv

安装后,uv会被添加到系统环境变量,即使切换虚拟环境也能使用。

powershell脚本安装打开powershell,执行:

irm https://astral.sh/uv/install.ps1 | iex

克隆openmanus存储库:

git clone https://github.com/mannaandpoem/openmanus.git
cd openmanus

如果你没有安装git或者无法通过git克隆openmanus源码时出错,可以扫码下面的二维码关注公众号【python客栈】并回复【openmanus】下载openmanus源码

关注公众号【python客栈】并回复【openmanus】下载openmanus源码

克隆或下载完成后,进入openmanus项目的根目录。在路径栏输入cmd,回车,进入openmanus根目录路径下的控制台。 

输入uv venv创建一个新的虚拟环境并激活它:

uv venv
#unix/macos返回
source .venv/bin/activate

#windows返回:
.venv\scripts\activate

安装openmanus依赖项:

uv pip install -r requirements.txt

 执行命令后返回下面内容

c:\openmanus\openmanus-main>uv pip install -r requirements.txt
resolved 133 packages in 2m 36s
      built english-words==2.0.1
      built html2text==2024.2.26
prepared 132 packages in 2m 50s
installed 133 packages in 10.19s
 + aiofiles==24.1.0
 + aiohappyeyeballs==2.5.0
 + aiohttp==3.11.13
 + aiolimiter==1.2.1
 + aiosignal==1.3.2
 + annotated-types==0.7.0
 + anthropic==0.49.0
 + anyio==4.8.0
 + attrs==25.1.0
 + backoff==2.2.1
 + beartype==0.12.0
 + beautifulsoup4==4.13.3
 + blinker==1.9.0
 + browser-use==0.1.40
 + browsergym==0.13.3
 + browsergym-assistantbench==0.13.3
 + browsergym-core==0.13.3
 + browsergym-experiments==0.13.3
 + browsergym-miniwob==0.13.3
 + browsergym-visualwebarena==0.13.3
 + browsergym-webarena==0.13.3
 + browsergym-workarena==0.4.1
 + certifi==2025.1.31
 + charset-normalizer==3.4.1
 + click==8.1.8
 + cloudpickle==3.1.1
 + colorama==0.4.6
 + dataclasses-json==0.6.7
 + datasets==3.2.0
 + defusedxml==0.7.1
 + dill==0.3.8
 + distro==1.9.0
 + english-words==2.0.1
 + evaluate==0.4.3
 + faker==37.0.0
 + farama-notifications==0.0.4
 + filelock==3.17.0
 + flask==3.1.0
 + frozenlist==1.5.0
 + fsspec==2024.9.0
 + googlesearch-python==1.3.0
 + greenlet==3.1.1
 + gymnasium==1.0.0
 + h11==0.14.0
 + html2text==2024.2.26
 + httpcore==1.0.7
 + httpx==0.28.1
 + huggingface-hub==0.29.2
 + idna==3.10
 + imageio==2.37.0
 + itsdangerous==2.2.0
 + jinja2==3.1.6
 + jiter==0.8.2
 + joblib==1.4.2
 + jsonpatch==1.33
 + jsonpointer==3.0.0
 + langchain-anthropic==0.3.3
 + langchain-core==0.3.43
 + langchain-ollama==0.2.2
 + langchain-openai==0.3.1
 + langsmith==0.3.13
 + lazy-loader==0.4
 + libvisualwebarena==0.0.15
 + libwebarena==0.0.4
 + loguru==0.7.3
 + lxml==5.3.1
 + markdownify==0.14.1
 + markupsafe==3.0.2
 + marshmallow==3.26.1
 + monotonic==1.6
 + mpmath==1.3.0
 + multidict==6.1.0
 + multiprocess==0.70.16
 + mypy-extensions==1.0.0
 + networkx==3.4.2
 + nltk==3.9.1
 + numpy==2.2.3
 + ollama==0.4.7
 + openai==1.58.1
 + orjson==3.10.15
 + packaging==24.2
 + pandas==2.2.3
 + pillow==10.4.0
 + playwright==1.49.1
 + portalocker==3.1.1
 + posthog==3.19.0
 + propcache==0.3.0
 + pyarrow==19.0.1
 + pydantic==2.10.6
 + pydantic-core==2.27.2
 + pyee==12.0.0
 + pyparsing==3.2.1
 + python-dateutil==2.9.0.post0
 + python-dotenv==1.0.1
 + pytz==2025.1
 + pywin32==309
 + pyyaml==6.0.2
 + regex==2024.11.6
 + requests==2.32.3
 + requests-toolbelt==1.0.0
 + sacrebleu==2.5.1
 + safetensors==0.5.3
 + scikit-image==0.25.2
 + scipy==1.15.2
 + setuptools==76.0.0
 + six==1.17.0
 + sniffio==1.3.1
 + soupsieve==2.6
 + sympy==1.13.1
 + tabulate==0.9.0
 + tenacity==9.0.0
 + text-generation==0.7.0
 + tifffile==2025.2.18
 + tiktoken==0.9.0
 + tokenizers==0.21.0
 + torch==2.6.0
 + tqdm==4.67.1
 + transformers==4.49.0
 + types-requests==2.32.0.20250306
 + types-tqdm==4.67.0.20250301
 + typing-extensions==4.12.2
 + typing-inspect==0.9.0
 + tzdata==2025.1
 + unidiff==0.7.5
 + urllib3==2.3.0
 + uvicorn==0.34.0
 + weblinx==0.3.2
 + weblinx-browsergym==0.0.1.dev14
 + werkzeug==3.1.3
 + win32-setctime==1.2.0
 + xxhash==3.5.0
 + yarl==1.18.3
 + zstandard==0.23.0

配置openmanus

在openmanus根目录下找到并进入config目录

编辑config.toml文件,配置api地址和api key。

大语言模型api配置问题

在尝试了多个模型后,总结出以下配置是效果最好的:

# deepseek v3配置(国内最佳选择)
[llm]
model = "deepseek-v3"
base_url = "https://api.deepseek.com/v1"
api_key = "你的api密钥"  # 替换为你的实际密钥
max_tokens = 8192
temperature = 0.0

# 通义千问配置(国产模型备选)
[llm]
model = "qwen-turbo"
base_url = "https://dashscope.aliyuncs.com/api/v1"
api_key = "你的阿里云api密钥"
max_tokens = 4096
temperature = 0.0

# claude配置(国外用户推荐)
[llm]
model = "claude-3-5-sonnet"
base_url = "https://api.anthropic.com"
api_key = "你的anthropic api密钥"
max_tokens = 4096
temperature = 0.0

使用openmanus的实际体验与建议

经过两天的深度使用,结合github issues中的反馈,总结了以下经验:

不同模型的实际表现

通过系统测试,发现不同模型在openmanus中的表现有明显差异:

模型工具调用能力中文理解执行效率我的评分
deepseek-v3优秀,支持完整函数调用极佳快速★★★★★
claude-3.5良好,少量格式问题很好中等★★★★☆
qwen-turbo中等,需要特殊处理极佳快速★★★★☆
gpt-4o优秀,工具调用稳定良好较慢★★★★☆
gpt-4o-mini不稳定,经常需要重试中等快速★★★☆☆

实战演示:从seo审核到自动化报告

karpathy个人网站seo优化任务为例,openmanus的运作流程展现其强大能力:

  • 任务解析阶段智能体将用户指令拆解为:
  • 网站元数据抓取
  • 技术seo检测(站点地图、响应速度等)
  • 内容优化建议生成
  • 工具调用过程
  • 通过browserusetool抓取https://karpathy.ai/的html结构
  • 使用pythonexecute运行seo分析脚本
  • 调用googlesearch验证关键词竞争度
  • 结果输出最终生成包含优先级排序的优化报告,例如:
  • 高优先级:为图片添加alt文本(当前缺失率78%)
  • 中优先级:实施schema标记增强搜索引擎理解
  • 基础优化:压缩css/js文件提升加载速度

国内使用的时候会出现多次报错,因为程序设计的原因使用的搜索等功能都是基于google做的,所以会出现部分浏览器抓取等失败的问题,不过下面的搜索功能与模块替换已经给出解决方法,这里就需要自己解决了,你们懂得!

技术对比:openmanus与manus的异同

维度manusopenmanus
架构设计闭源商业系统开源react框架
规划能力线性任务链支持dag有向无环图扩展
模型支持仅限claude系列兼容qwen/gpt-4等主流模型
执行反馈可视化进度条终端日志实时输出

值得注意的是,openmanus当前版本在任务规划的细腻度上略逊于manus,但其开源特性允许社区开发者持续优化工具链与提示工程

安装与环境配置问题

依赖安装错误

问题表现
playwright安装失败。

解决方案

# 分步安装能解决大部分依赖问题
pip install --no-deps -r requirements.txt

# 对于playwright,使用这个方法成功解决了问题
pip install playwright==1.40.0 --no-build-isolation
playwright install chromium

# 如果仍然遇到问题,尝试手动安装核心依赖
pip install pydantic==2.5.2 langchain==0.1.6 beautifulsoup4==4.12.3

windows特有问题解决

问题表现
在windows环境下,遇到了一些linux环境中没有的问题,特别是路径和编码相关的错误。

解决方案

# 在windows中处理路径时使用了这种方式统一处理
import os
def normalize_path(path):
    """统一处理windows和linux路径"""
    return os.path.normpath(path).replace('\\', '/')

api调用错误的故障排除

遇到的几个常见api错误及解决方法:

问题表现1
经常遇到"api error: error code: 400"错误。

解决方案

# 修改了app/llm.py,增加了更详细的错误处理
def call_api_with_detailed_error(self, *args, **kwargs):
    try:
        return self._call_api(*args, **kwargs)
    except exception as e:
        error_msg = str(e)
        if "400" in error_msg:
            # 检查请求参数
            print("api 400错误排查清单:")
            print("1. 检查api密钥格式是否正确")
            print("2. 检查模型名称是否正确")
            print("3. 检查请求参数格式")
            print("4. 原始错误信息:", error_msg)
        elif "401" in error_msg:
            print("认证失败,请检查api密钥")
        elif "429" in error_msg:
            print("请求频率过高,请降低请求速度或升级api配额")
        raise e

问题表现2
"not support function calling"问题

解决方案
deepseek最新版本已支持函数调用。

token限制问题的实际解决方法

问题表现
“max_token最大允许8192,太小了”,导致复杂任务无法完成。

解决方案

# 实现了一个上下文管理器,大大提高了长任务的完成率
def manage_context_length(context, max_length=6000, summarize_threshold=7500):
    """智能管理上下文长度"""
    if len(context) < summarize_threshold:
        return context
    
    # 将上下文分为三部分处理
    intro = context[:1500]  # 保留初始指令
    recent = context[-3000:]  # 保留最近交互
    middle = context[1500:-3000]  # 中间部分需要压缩
    
    # 对中间部分进行摘要
    from app.llm import llm
    llm = llm()
    summary_prompt = f"请将以下对话历史压缩为简短摘要,保留关键信息:\n\n{middle}"
    summary = llm.generate(summary_prompt, max_tokens=1500)
    
    # 组合处理后的上下文
    new_context = intro + "\n\n[历史摘要]: " + summary + "\n\n" + recent
    return new_context

搜索功能与模块替换

由于google搜索在国内无法使用,这个问题在github issues中被多次提到。

bing搜索实现

进一步优化了bing搜索实现:

# app/tool/bing_search.py
from typing import dict, list, optional
import os
import requests
from pydantic import field
from app.logger import logger
from app.tool.base import basetool

class bingsearch(basetool):
    """使用必应搜索引擎进行网络搜索"""
    
    name: str = "bing_search"
    description: str = "使用必应搜索查询信息,对于需要最新信息的查询特别有用"
    
    def __init__(self):
        super().__init__()
        # 从环境变量或配置文件获取api密钥
        self.subscription_key = os.environ.get("bing_api_key", "你的bing搜索api密钥")
        self.search_url = "https://api.bing.microsoft.com/v7.0/search"
    
    def _call(self, query: str, num_results: int = 10) -> dict:
        """执行必应搜索"""
        headers = {"ocp-apim-subscription-key": self.subscription_key}
        params = {
            "q": query, 
            "count": num_results, 
            "textdecorations": true, 
            "textformat": "html",
            "mkt": "zh-cn"  # 设置为中文市场,结果更符合国内用户习惯
        }
        
        try:
            response = requests.get(self.search_url, headers=headers, params=params)
            response.raise_for_status()
            search_results = response.json()
            
            # 提取有用的搜索结果
            results = []
            if "webpages" in search_results and "value" in search_results["webpages"]:
                for result in search_results["webpages"]["value"]:
                    results.append({
                        "title": result["name"],
                        "link": result["url"],
                        "snippet": result["snippet"],
                        "datelastcrawled": result.get("datelastcrawled", "")
                    })
            
            # 添加新闻结果
            if "news" in search_results and "value" in search_results["news"]:
                for news in search_results["news"]["value"][:3]:  # 取前3条新闻
                    results.append({
                        "title": "[新闻] " + news["name"],
                        "link": news["url"],
                        "snippet": news["description"],
                        "datepublished": news.get("datepublished", "")
                    })
            
            return {
                "query": query,
                "results": results,
                "total_results": len(results)
            }
            
        except exception as e:
            logger.error(f"必应搜索出错: {str(e)}")
            return {
                "query": query,
                "results": [],
                "total_results": 0,
                "error": str(e)
            }

百度搜索替代实现

将google搜索替换成百度搜索"

# app/tool/baidu_search.py
import requests
from bs4 import beautifulsoup
from pydantic import field
from app.tool.base import basetool
from app.logger import logger

class baidusearch(basetool):
    """使用百度搜索引擎进行网络搜索"""
    
    name: str = "baidu_search"
    description: str = "使用百度搜索获取信息,适合中文搜索"
    
    def _call(self, query: str, num_results: int = 10) -> dict:
        """执行百度搜索并解析结果"""
        headers = {
            "user-agent": "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/91.0.4472.124 safari/537.36",
            "accept-language": "zh-cn,zh;q=0.9,en;q=0.8"
        }
        
        search_url = f"https://www.baidu.com/s?wd={query}&rn={num_results}"
        
        try:
            response = requests.get(search_url, headers=headers, timeout=10)
            response.raise_for_status()
            response.encoding = 'utf-8'
            
            soup = beautifulsoup(response.text, 'html.parser')
            search_results = soup.select('.result.c-container')
            
            results = []
            for result in search_results[:num_results]:
                title_elem = result.select_one('.t')
                link_elem = title_elem.select_one('a') if title_elem else none
                abstract_elem = result.select_one('.c-abstract')
                
                if title_elem and link_elem:
                    title = title_elem.get_text(strip=true)
                    link = link_elem.get('href', '')
                    abstract = abstract_elem.get_text(strip=true) if abstract_elem else "无描述"
                    
                    results.append({
                        "title": title,
                        "link": link,
                        "snippet": abstract
                    })
            
            return {
                "query": query,
                "results": results,
                "total_results": len(results)
            }
            
        except exception as e:
            logger.error(f"百度搜索出错: {str(e)}")
            return {
                "query": query,
                "results": [],
                "total_results": 0,
                "error": str(e)
            }

搜索功能的注册方法

按照以下步骤将新的搜索工具集成到openmanus中:

# 修改app/agent/manus.py文件
from app.tool.bing_search import bingsearch
from app.tool.baidu_search import baidusearch

# 找到available_tools部分并替换
available_tools: toolcollection = field(
    default_factory=lambda: toolcollection(
        pythonexecute(), 
        baidusearch(),  # 国内用户首选
        bingsearch(),   # 备选搜索工具
        browserusetool(), 
        filesaver(), 
        terminate()
    )
)

执行控制与错误处理

循环检测与自动中断

解决了"loop error"、"任务完成后的重复思考"问题:

# 在app/agent/base.py中添加了循环检测功能
def is_in_loop(self, actions_history, threshold=3, similarity_threshold=0.85):
    """检测是否陷入执行循环"""
    if len(actions_history) < threshold * 2:
        return false
    
    recent_actions = actions_history[-threshold:]
    previous_actions = actions_history[-(threshold*2):-threshold]
    
    # 计算最近动作与前一批动作的相似度
    similarity_count = 0
    for i in range(threshold):
        # 使用简单字符串相似度
        current = recent_actions[i]
        previous = previous_actions[i]
        
        # 如果动作类型、参数等关键信息相似
        if current['tool'] == previous['tool'] and \
           self._params_similarity(current['params'], previous['params']) > similarity_threshold:
            similarity_count += 1
    
    # 如果超过一定比例的动作重复,判定为循环
    return similarity_count / threshold > 0.7

def _params_similarity(self, params1, params2):
    """计算两组参数的相似度"""
    # 简化实现,实际使用中可以采用更复杂的相似度算法
    if params1 == params2:
        return 1.0
    
    common_keys = set(params1.keys()) & set(params2.keys())
    if not common_keys:
        return 0.0
    
    similarity = 0
    for key in common_keys:
        if params1[key] == params2[key]:
            similarity += 1
    
    return similarity / len(common_keys)

在执行流程中添加循环检测:

# 在执行流程中使用循环检测
def run(self, prompt):
    actions_history = []
    
    for step in range(self.max_steps):
        action = self.plan_next_action(prompt)
        actions_history.append(action)
        
        # 检测是否陷入循环
        if len(actions_history) > 6 and self.is_in_loop(actions_history):
            logger.warning("检测到执行循环,尝试重新规划...")
            # 添加特殊提示,帮助模型跳出循环
            prompt += "\n\n[系统提示]: 检测到可能的执行循环,请尝试不同的解决方案或工具。"
            continue
        
        result = self.execute_action(action)
        
        if self.is_task_complete():
            return result
    
    return "达到最大步骤数,任务未完成"

文件保存问题的实际解决

针对"更改了file_path控制台输出文件已保存,但实际上并没有保存"的问题,修改filesaver工具:

# 改进的filesaver工具实现
def save_file_with_verification(self, content, file_path, overwrite=false):
    """保存文件并验证成功与否"""
    # 规范化路径
    file_path = os.path.abspath(file_path)
    
    # 检查目录是否存在,不存在则创建
    dir_path = os.path.dirname(file_path)
    if not os.path.exists(dir_path):
        try:
            os.makedirs(dir_path, exist_ok=true)
        except exception as e:
            return f"创建目录失败: {dir_path}, 错误: {str(e)}"
    
    # 检查文件是否已存在
    if os.path.exists(file_path) and not overwrite:
        return f"文件已存在且未设置覆盖: {file_path}"
    
    # 保存文件
    try:
        if isinstance(content, str):
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(content)
        else:
            with open(file_path, 'wb') as f:
                f.write(content)
        
        # 验证文件是否成功保存
        if os.path.exists(file_path) and os.path.getsize(file_path) > 0:
            return f"文件成功保存到: {file_path}"
        else:
            return f"文件保存失败,虽然没有报错但文件为空: {file_path}"
    except exception as e:
        return f"保存文件出错: {str(e)}"

manus出现短短几小时开源社区就有了复刻开源版本openmanus,说明manus确实具备较强的创新性和吸引力,有了开源项目,让我们这些没钱没设备的普通开发者也可以体验尝试ai的创造力让人十分激活

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com