← 返回博客
社区10 分钟 分钟阅读

如何为 OpenClaw 开源社区做贡献 2026

完整的 OpenClaw 贡献指南 - 从搭建开发环境到提交第一个 PR。学习代码规范、PR 流程和社区准则。

AI
OpenClaw 团队
2026年3月23日

如何为 OpenClaw 开源社区做贡献 2026

OpenClaw 因为像你这样的贡献者而蓬勃发展。无论你是修复 bug、添加功能、改进文档,还是在社区中帮助他人,每一份贡献都很重要。本指南将带你了解所需的一切。

开始之前

前置要求

在贡献之前,确保你有:

  • 安装并配置好 Git
  • Node.js 18+ 和 npm 8+
  • Python 3.10+(用于 Python SDK 贡献)
  • 一个 GitHub 账号
  • TypeScript/Python 基础知识
  • 搭建开发环境

  • Fork 仓库
  • ```bash

    访问 https://github.com/openclaw/openclaw 并点击 "Fork"

    ```

  • 克隆你的 fork
  • ```bash

    git clone https://github.com/YOUR_USERNAME/openclaw.git

    cd openclaw

    ```

  • 添加上游远程仓库
  • ```bash

    git remote add upstream https://github.com/openclaw/openclaw.git

    ```

  • 安装依赖
  • ```bash

    TypeScript/JavaScript SDK

    npm install

    Python SDK

    cd python-sdk

    pip install -e ".[dev]"

    ```

  • 运行测试验证设置
  • ```bash

    TypeScript

    npm test

    Python

    pytest

    ```

    代码规范

    TypeScript/JavaScript

    我们遵循严格的编码标准以保持代码质量:

    ```typescript

    // ✅ 好:清晰的命名、正确的类型、错误处理

    async function executeAgentTask(

    task: Task,

    options: ExecutionOptions

    ): Promise {

    if (!task.description) {

    throw new ValidationError('任务描述是必需的')

    }

    try {

    const result = await this.agent.execute(task, options)

    return {

    status: 'completed',

    output: result,

    timestamp: new Date()

    }

    } catch (error) {

    logger.error('任务执行失败', { task, error })

    throw new ExecutionError(`执行任务失败: ${error.message}`)

    }

    }

    // ❌ 差:不清晰的命名、没有类型、糟糕的错误处理

    async function doStuff(t, opts) {

    const r = await this.agent.execute(t, opts)

    return r

    }

    ```

    关键原则

  • 使用 TypeScript 严格模式
  • 优先使用 `async/await` 而不是回调
  • 始终显式处理错误
  • 使用描述性变量名
  • 为公共 API 添加 JSDoc 注释
  • 保持函数在 50 行以内
  • 最大嵌套深度:4 层
  • Python

    ```python

    ✅ 好:类型提示、文档字符串、正确的错误处理

    from typing import Optional

    from openclaw.types import Task, TaskResult

    from openclaw.exceptions import ValidationError, ExecutionError

    async def execute_agent_task(

    task: Task,

    options: Optional[ExecutionOptions] = None

    ) -> TaskResult:

    """

    使用给定选项执行 agent 任务。

    Args:

    task: 要执行的任务

    options: 可选的执行配置

    Returns:

    包含执行输出和元数据的 TaskResult

    Raises:

    ValidationError: 如果任务无效

    ExecutionError: 如果执行失败

    """

    if not task.description:

    raise ValidationError("任务描述是必需的")

    try:

    result = await self.agent.execute(task, options)

    return TaskResult(

    status="completed",

    output=result,

    timestamp=datetime.now()

    )

    except Exception as error:

    logger.error(f"任务执行失败: {error}", extra={"task": task})

    raise ExecutionError(f"执行任务失败: {error}")

    ❌ 差:没有类型、没有文档字符串、糟糕的错误处理

    async def do_stuff(t, opts=None):

    r = await self.agent.execute(t, opts)

    return r

    ```

    关键原则

  • 到处使用类型提示
  • 遵循 PEP 8 风格指南
  • 为所有公共函数编写文档字符串
  • 对 I/O 操作使用 `async/await`
  • 优先显式而非隐式
  • 保持函数专注和小巧
  • 测试要求

    所有贡献必须包含测试。我们维持 80%+ 的代码覆盖率。

    单元测试

    ```typescript

    // TypeScript (Vitest)

    import { describe, it, expect, vi } from 'vimport { Agent } from '../src/agent'

    describe('Agent', () => {

    it('应该成功执行简单任务', async () => {

    const mockLLM = vi.fn().mockResolvedValue({

    content: '任务完成'

    })

    const agent = new Agent({ llm: mockLLM })

    const result = await agent.execute({ description: '简单任务' })

    expect(result.status).toBe('completed')

    expect(mockLLM).toHaveBeenCalledTimes(1)

    })

    it('应该优雅地处理执行失败', async () => {

    const mockLLM = vi.fn().mockRejectedValue(new Error('API 错误'))

    const agent = new Agent({ llm: mockLLM })

    await expect(

    agent.execute({ description: '失败的任务' })

    ).rejeoThrow('API 错误')

    })

    })

    ```

    ```python

    Python (pytest)

    import pytest

    from openclaw import Agent

    from openclaw.exceptions import ExecutionError

    @pytest.mark.asyncio

    async def test_agent_executes_simple_tasks():

    """Agent 应该成功执行简单任务。"""

    mock_llm = AsyncMock(return_value={"content": "任务完成"})

    agent = Agent(llm=mock_llm)

    result = await agent.execute({"description": "简单任务"})

    assert result.status == "completed"

    assert mock_llm.call_count == 1

    @pytest.mark.asyncio

    async def test_agent_handles_failures():

    """Agent 应该优雅地处理执行失败。"""

    mock_llm = AsyncMock(side_effect=Exception("API 错误"))

    agent = Agent(llm=mock_llm)

    with pytest.raises(ExecutionError, match="API 错误"):

    await agent.execute({"description": "失败的任务"})

    ```

    集成测试

    ```typescript

    describe('Agent 集成测试', () => {

    it('应该完成端到端的真实任务', async () => {

    const agent = new Agent({

    apiKey: process.env.OPENCLAW_API_KEY

    })

    const result = await agent.execute({

    description: '计算 50 美元的 15% 小费',

    maxSteps: 5

    })

    expect(result.status).toBe('completed')

    expect(result.output).toContain('7.50')

    }, 30000) // 真实 API 调用需要更长的超时时间

    })

    ```

    Pull Request 工作流

    1. 创建功能分支

    ```bash

    git checkout -b feature/your-feature-name

    或者对于 bug 修复

    git checkout -b fix/bug-description

    ```

    2. 进行更改

  • 遵循我们的标准编写代码
  • 为新功能添加测试
  • 如需要更新文档
  • 运行 linter 和格式化工具
  • ```bash

    TypeScript

    npm run lint

    npm run format

    Python

    black .

    flake8 .

    mypy .

    ```

    3. 提交更改

    我们使用 约定式提交

    ```bash

    格式: ():

    git commit -m "feat(agent): 添加并行工具执行"

    git commit -m "fix(api): 正确处理速率限制错误"

    git commit -m "docs(readme): 更新安装说明"

    git commit -m "test(agent): 添加错误处理测试"

    ```

    类型

  • `feat`: 新功能
  • `fix`: Bug 修复
  • `docs`: 文档更改
  • `test`: 添加或更新测试
  • `refactor`: 代码重构
  • `perf`: 性能改进
  • `chore`: 维护任务
  • 4. 推送并创建 PR

    ```bash

    git push origin feature/your-feature-name

    ```

    然后访问 GitHub 并点击 "Create Pull Request"。

    PR 模板

    ```markdown

    描述

    简要描述此 PR 的作用。

    更改类型

  • [ ] Bug 修复
  • [ ] 新功能
  • [ ] 破坏性更改
  • [ ] 文档更新
  • 测试

  • [ ] 添加/更新了单元测试
  • [ ] 添加/更新了集成测试
  • [ ] 所有测试在本地通过
  • 检查清单

  • [ ] 代码遵循项目风格指南
  • [ ] 完成自我审查
  • [ ] 为复杂逻辑添加了注释
  • [ ] 更新了文档
  • [ ] 没有生成新的警告
  • 相关 Issue

    Closes #123

    ```

    5. 代码审查流程

  • 自动检查运行:Linting、测试、覆盖率
  • 维护者审查:通常在 48 小时内
  • 处理反馈:进行请求的更改
  • 批准:一旦批准,维护者将合并
  • 更快审查的技巧

  • 保持 PR 专注和小巧(< 400 行)
  • 编写清晰的描述
  • 及时回应反馈
  • 对建议持开放态度
  • 贡献想法

    适合新手的 Issue

    寻找标记为 `good-first-issue` 的问题:

  • 文档改进
  • 添加示例
  • 修复拼写错误
  • 编写测试
  • 改进错误消息
  • 功能贡献

    在开始主要功能之前:

  • 检查现有 issue - 可能有人已经在做了
  • 开启讨论 - 在 GitHub Discussions 中提出你的想法
  • 获取反馈 - 等待维护者批准
  • 创建 issue - 记录功能计划
  • 开始编码 - 一旦获得批准
  • 文档

    文档贡献总是受欢迎的:

  • API 文档:JSDoc/docstrings
  • 指南:操作指南文章
  • 示例:真实世界用例
  • 翻译:帮助翻译文档
  • Bug 报告

    发现了 bug?帮助我们修复它:

    ```markdown

    Bug 描述

    清晰描述 bug。

    重现步骤

  • 步骤 1
  • 步骤 2
  • 看到错误
  • 预期行为

    应该发生什么。

    实际行为

    实际发生了什么。

    环境

  • 操作系统: macOS 14.0
  • Node: 18.17.0
  • OpenClaw: 1.2.3
  • 附加上下文

    任何其他相关信息。

    ```

    社区准则

    行为准则

    我们致力于提供一个热情和包容的环境:

  • 尊重他人:尊重每个人
  • 建设性:提供有帮助的反馈
  • 耐心:记住每个人都曾是初学者
  • 包容:欢迎不同的观点
  • 沟通渠道

  • GitHub Issues:Bug 报告和功能请求
  • GitHub Discussions:问题和一般讨论
  • Discord:实时聊天和社区支持
  • Twitter:更新和公告
  • 获取帮助

    遇到困难?以下是获取帮助的方法:

  • 查看文档:大多数问题在那里都有答案
  • 搜索现有 issue:你的问题可能已经被回答
  • 在 Discussions 中提问:对于一般问题
  • 加入 Discord:获取实时帮助
  • 认可

    我们重视所有贡献:

  • 贡献者列表:所有贡献者都列在 README 中
  • 发布说明:重要贡献会被突出显示
  • 周边:活跃贡献者会收到 OpenClaw 周边
  • 维护者身份:持续贡献者可能成为维护者
  • 高级主题

    成为维护者

    维护者拥有提交权限并帮助指导项目:

    要求

  • 10+ 个合并的 PR
  • 3+ 个月的持续贡献
  • 对代码库的深入理解
  • 展示良好的判断力
  • 社区参与
  • 职责

  • 审查 PR
  • 分类 issue
  • 指导贡献者
  • 维护代码质量
  • 发布流程

    维护者遵循此流程进行发布:

  • 更新 `package.json`/`pyproject.toml` 中的版本
  • 更新 CHANGELOG.md
  • 创建发布分支
  • 运行完整测试套件
  • 创建 GitHub 发布
  • 发布到 npm/PyPI
  • 在社交媒体上宣布
  • 总结

    为 OpenClaw 做贡献是有意义的,并帮助全球数千名开发者。无论你是修复拼写错误还是添加主要功能,你的贡献都很重要。

    准备好贡献了吗?查看我们的 适合新手的 issue 并加入我们的 Discord 社区

    资源

  • GitHub 仓库
  • 文档
  • Discord 社区
  • 行为准则
  • #OpenClaw#开源#贡献#社区#开发

    准备好优化您的 AI 战略了吗?

    获得您的免费 AI 服务商,发现优化机会。

    开始免费审计