Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.devin.ai/llms.txt

Use this file to discover all available pages before exploring further.

在蓝图中,monorepo 和多软件包工作区需要额外处理,因为不同子目录可能使用不同的语言、软件包管理器或依赖项。Devin 支持两种方案:

原生工作区(推荐)

为每个子目录创建单独的蓝图。每个工作区都有各自的 initialize、maintenance 和 Knowledge 部分,工作目录也会自动设置为对应的子目录。

Subshells

在单个蓝图中使用 (cd dir && command) 在子目录内运行命令。对于只包含少量软件包的小型 monorepo,这种方式更简单。

原生工作区

推荐用于大多数 monorepo。 原生工作区会为每个子目录分别提供独立的蓝图,并隔离各自的设置、Knowledge 和工作目录。随着软件包数量增加,相比 subshell,这种方式更清晰,也更易于维护。
使用原生工作区时,每个子目录都会有一个专用蓝图。该蓝图中的命令会直接在对应子目录下运行——无需再使用 cd 或 subshell。

根蓝图

使用原生工作区的每个代码仓库都应有一个根蓝图。根蓝图从代码仓库根目录运行,并在任何工作区作用域的蓝图之前执行。可将其用于整个代码仓库共用的设置——安装运行时环境、全局工具,或在根级别安装依赖。
# 根蓝图 — 最先运行,从 repo 根目录开始
initialize: |
  npm install -g pnpm

maintenance: |
  pnpm install
工作区蓝图随后会处理软件包级别的设置,并在根蓝图完成后执行。

创建工作区

  1. 前往 Settings > Environment > Blueprints
  2. 点击相应的代码仓库
  3. 点击 Add workspace
  4. 输入子目录路径 (例如 packages/frontend)
  5. 为该工作区编写蓝图
工作区路径必须对应代码仓库中的实际目录。如果构建运行时该路径不存在,构建将失败。请务必再次确认该路径与你的代码仓库结构完全一致 (例如 packages/frontend,而不是 pkg/frontend) 。

示例

一个 monorepo,包含 React 前端和 Python 后端。根蓝图负责安装共享工具,然后各个工作区分别处理自己的依赖:
# 根蓝图——整个仓库的共享设置
initialize: |
  npm install -g pnpm
  curl -LsSf https://astral.sh/uv/install.sh | sh

knowledge:
  - name: structure
    contents: |
      包含两个软件包的 monorepo:
      - packages/frontend — React 应用(TypeScript、pnpm)
      - packages/backend — Python API(FastAPI、uv)
每个工作区的 knowledge 条目都限定在对应的子目录内。当 Devin 在 packages/frontend 中工作时,它看到的是前端的 lint/test/dev 命令,而不是后端的命令。

何时使用原生工作区

  • 子目录使用不同的语言或软件包管理器
  • 每个软件包都需要各自的知识条目 (lint、测试、构建命令)
  • 你希望采用隔离的配置——某个工作区的蓝图出问题时,不会阻塞其他工作区
  • 软件包数量不断增加,单个蓝图变得难以管理

subshell

对于较简单的 monorepo,你可以在单个蓝图中使用 subshell 管理所有内容。将命令放在括号中,即可在子目录中运行,而不会影响后续步骤:
maintenance:
  - name: Frontend deps
    run: (cd packages/frontend && pnpm install)
  - name: Backend deps
    run: (cd packages/backend && uv sync)
圆括号 (cd ... && ...) 会创建一个 subshell。subshell 退出后,工作目录会重置为仓库根目录,以便执行下一步。
如果没有圆括号,cd 会更改后续所有步骤的工作目录。在蓝图步骤中切换目录时,务必使用 subshell。

为什么 subshell 很重要

比较以下两种做法:
maintenance:
  - name: Frontend deps
    run: (cd packages/frontend && pnpm install)
  - name: Backend deps
    run: (cd packages/backend && uv sync)
每个步骤都从仓库根目录开始运行。这两个命令都能找到正确的 packages/ 子目录。

何时使用 subshells

  • monorepo 中只有少量软件包,且设置较为简单
  • 所有软件包都使用相同的语言和包管理器
  • 你不需要为每个软件包单独创建 知识条目

适用于 monorepo 的 知识条目

无论你使用原生工作区还是 subshells,结构清晰的 知识条目都能帮助 Devin 更好地在代码库中定位和理解内容:
knowledge:
  - name: structure
    contents: |
      This is a monorepo with three packages:
      - `packages/frontend` — React app (TypeScript, pnpm)
      - `packages/backend` — Python API (FastAPI, uv)
      - `packages/shared` — Shared TypeScript utilities
  - name: frontend
    contents: |
      cd packages/frontend
      Dev server: pnpm dev
      Lint: pnpm lint
      Test: pnpm test
  - name: backend
    contents: |
      cd packages/backend
      Dev server: uv run uvicorn app.main:app --reload
      Lint: uv run ruff check .
      Test: uv run pytest
将每个目录对应到其编程语言和工具链的 structure 知识条目,可以帮助 Devin 快速了解 repo。使用原生工作区时,每个工作区都有各自的知识条目,因此 structure 条目在根蓝图中或基于 subshell 的设置中最为实用。

示例

Turborepo / Nx 工作区

对于由 Turborepo 或 Nx 等 monorepo 构建工具管理的工作区,请在根目录安装依赖,并让工具负责协调各个包:
initialize: |
  npm install -g pnpm turbo

maintenance: |
  pnpm install

knowledge:
  - name: structure
    contents: |
      Turborepo monorepo. Use `turbo` for building and testing:
      - `apps/web` — Next.js app
      - `apps/api` — Express API
      - `packages/ui` — Shared component library
      - `packages/config` — Shared configuration
  - name: build
    contents: turbo run build
  - name: test
    contents: turbo run test
  - name: lint
    contents: turbo run lint
  - name: dev
    contents: turbo run dev

多个 JDK 版本

在一个 Java monorepo 中,不同服务需要不同的 JDK 版本:
initialize:
  - name: Install JDK 17 (primary)
    run: |
      sudo apt-get update -qq
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openjdk-17-jdk-headless
      echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' \
        | sudo tee /etc/profile.d/java.sh > /dev/null

  - name: Install JDK 11 (legacy service)
    run: |
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openjdk-11-jdk-headless

maintenance:
  - name: Warm dependency caches
    run: |
      export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
      (cd services/api && ./gradlew dependencies --refresh-dependencies)

      export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
      (cd services/legacy && ./gradlew dependencies --refresh-dependencies)

knowledge:
  - name: build_api
    contents: |
      Build the API service (JDK 17):
        JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
        cd services/api && ./gradlew clean build
  - name: build_legacy
    contents: |
      Build the legacy service (JDK 11):
        JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \
        cd services/legacy && ./gradlew clean build
  - name: test_all
    contents: |
      Run tests for all services:
        JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
        (cd services/api && ./gradlew test)

        JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \
        (cd services/legacy && ./gradlew test)

共享工具的组织级蓝图

当多个 monorepo 软件包共用同一套工具时,请在组织级蓝图中统一安装一次:
# 组织级蓝图 (Settings > Environment > Blueprints > Org-wide setup)
initialize:
  - name: Install pnpm
    run: npm install -g pnpm
  - name: Install uv
    run: curl -LsSf https://astral.sh/uv/install.sh | sh
  - name: Install shared build tools
    run: npm install -g turbo typescript
这样,每个仓库蓝图只需要项目专用的命令:
# 仓库蓝图(使用来自组织蓝图的 pnpm 和 uv)
maintenance:
  - name: Install all workspace deps
    run: pnpm install
  - name: Install Python service deps
    run: (cd services/ml-pipeline && uv sync)

最佳实践

当每个子目录都有自己的语言、软件包管理器或构建流程时,原生工作区可以让每个蓝图保持聚焦和独立。subshells 仅适用于只有少量软件包的简单场景。
使用 subshell 方法时,请将 cd 命令放在括号中:(cd dir && command)。这样可防止某一步的目录切换影响后续步骤。
跨多个代码仓库使用的语言运行时和软件包管理器应放在组织级蓝图中。这样可以避免重复,并让代码仓库蓝图专注于项目特定的设置。
如果软件包 A 依赖先构建软件包 B,请在 maintenance 中先列出 B 的构建步骤,再列出 A 的安装步骤。蓝图步骤会按列出顺序依次运行。
创建一个名为 structure 的知识条目,将目录映射到其对应的语言和工具,这有助于 Devin 理解代码库结构。请注明每个子目录使用的软件包管理器,以及任何跨软件包依赖。
不要只创建一个很大的知识条目,而应为每个软件包分别创建独立条目 (例如 frontendbackendml-pipeline) 。使用原生工作区时,每个工作区都会内置自己的知识部分。
使用 pnpm install (而不是 pnpm install --force) 以及 uv sync (而不是 rm -rf .venv && uv sync) 。在定期重建期间,增量命令执行得更快。