blog.dopana

Back

Code Storage 是由 Pierre Computer Company 构建的为 AI 代理提供的托管 Git 基础设施。它通过 SDK、HTTP API 或 Git over HTTPS 启用创建仓库、编写提交、合并分支和获取 Git 远程 URL。

问题#

在构建 AI 驱动的系统,特别是 AI 代理时,传统存储解决方案面临重大限制:

  • 拼凑的 S3/R2 解决方案:缓慢且脆弱,并非为协作工作负载而设计
  • 传统存储 API:并非为协作工作而构建
  • Git 原语复杂性:团队在 Postgres 和其他数据存储中重复 Git 原语,同时试图管理 S3 中分歧的快照
  • 性能差:当前解决方案无法处理每天数百万个新仓库
  • 速率限制和复杂身份验证:公共 API 有速率限制和复杂的身份验证流程

对于 AI 代理,Git 提供确定性、可重现的状态,具有可以在提示、评估和回滚中固定的内容寻址快照,以及用于人机协作的熟悉的多玩家策略(如分支)。

解决方案#

Code Storage 是一个建立在 Git 上的高规模分布式存储系统,用于存储和协作仓库,API 人体工程学针对机器进行了优化。

核心架构#

Code Storage 利用 Git 的三阶段提交协议和基于”轮辐”的仲裁架构来保证大规模所有读写操作的持久性和一致性。

graph TD
    A[AI 代理/应用程序] --> B[Code Storage SDK]
    B --> C[HTTP API]
    C --> D[基于仲裁的存储层]
    D --> E[Git 仓库存储]
    D --> F[Git LFS 存储]
    D --> G[元数据存储]
    
    H[JWT 身份验证] --> C
    I[Ref 策略] --> C
    J[提交签名] --> C
    
    K[Webhooks] --> L[构建系统]
    K --> M[Bots]
    K --> N[AI 代理]
    
    C --> K

主要功能#

Git 操作#

  • 通过 HTTPS 使用 JWT 认证的远程进行克隆、获取、推送和拉取
  • 没有速率限制、复杂的身份验证流程或其他限制

Git LFS#

  • 在同一远程上跟踪大文件,无需单独的 LFS 服务器

Git Notes#

  • 将元数据附加到提交并按引用隔离笔记流

Ref 策略#

  • 限制 JWT 可以更新的引用并拒绝强制推送

提交签名#

  • 注册密钥并要求在选定引用上签名提交

导入命名空间#

  • 批量推送大型仓库,Code Storage 将其移动到冷存储

临时命名空间#

  • 为预览和实验创建隔离的引用,然后提升它们

仓库分支#

  • 复制仓库以用作模板、快照或隔离工作

GitHub 同步#

  • 在 Code Storage 和 GitHub 之间镜像仓库

通用同步#

  • 镜像 GitLab、Bitbucket 或其他 HTTPS Git 仓库

Webhooks#

  • 接收推送和同步事件,使用 HMAC 签名验证

AI 代理工作流程#

Code Storage 为代理提供专门的工作流程:

连接沙盒#

使用经过身份验证的 URL 克隆到 Modal、E2B、Daytona 和其他沙盒。

sequenceDiagram
    participant Agent as AI 代理
    participant CodeStorage as Code Storage
    participant Sandbox as Modal/E2B/Daytona
    
    Agent->>CodeStorage: 请求经过身份验证的 URL
    CodeStorage-->>Agent: JWT 认证的 Git URL
    Agent->>Sandbox: 使用经过身份验证的 URL 克隆
    Sandbox->>CodeStorage: 通过 HTTPS 进行 Git 克隆
    CodeStorage-->>Sandbox: 仓库数据
    Sandbox-->>Agent: 克隆完成

存储会话状态#

将代理会话状态存储为临时提交,正常分支保持不变。

恢复沙盒工作#

在新沙盒中恢复最后的会话状态。

运行并行尝试#

从一个提交开始多个尝试并提升最佳结果。

graph TD
    A[基础提交] --> B[尝试 1]
    A --> C[尝试 2]
    A --> D[尝试 3]
    
    B --> E{结果质量?}
    C --> F{结果质量?}
    D --> G{结果质量?}
    
    E -->|最佳| H[提升到主分支]
    F -->|最佳| H
    G -->|最佳| H
    
    H --> I[最终结果]

显示实时差异#

将代理分支渲染为在每个新状态刷新的实时差异。

快速开始#

安装#

# TypeScript
pnpm i @pierre/storage

# Python(使用 uv - 推荐)
uv add pierre-storage

# 或使用 pip
pip install pierre-storage

# Go
go get github.com/pierrecomputer/sdk/packages/code-storage-go@latest
bash

初始化客户端#

TypeScript#

import { GitStorage } from '@pierre/storage';

const storage = new GitStorage({
  name: 'your-org',
  key: process.env.PIERRE_PRIVATE_KEY!,
});
typescript

Python#

from pierre_storage import GitStorage

storage = GitStorage({
    "name": "your-org",
    "key": os.environ["PIERRE_PRIVATE_KEY"],
})
python

Go#

client, err := storage.NewClient(storage.Options{
	Name: "your-org",
	Key:  os.Getenv("PIERRE_PRIVATE_KEY"),
})
go

创建仓库和首次提交#

TypeScript#

const repo = await storage.createRepo({ id: 'new-workspace' });

const result = await repo
  .createCommit({
    targetBranch: 'main',
    commitMessage: 'Get started with Code Storage',
    author: { name: 'Pierre', email: 'pierre@pierre.co' },
  })
  .addFileFromString('README.md', '# Getting started\n')
  .addFileFromString('main.ts', 'console.log("Hello from Code Storage");')
  .send();

console.log(result.commitSha);
typescript

Python#

repo = await storage.create_repo(id="new-workspace")

result = await (
    repo.create_commit(
        target_branch="main",
        commit_message="Get started with Code Storage",
        author={"name": "Pierre", "email": "pierre@pierre.co"},
    )
    .add_file_from_string("README.md", "# Getting started\n")
    .add_file_from_string("main.py", "print('Hello from Code Storage')")
    .send()
)

print(result["commit_sha"])
python

Go#

ctx := context.Background()
repo, err := client.CreateRepo(ctx, storage.CreateRepoOptions{ID: "new-workspace"})

builder, err := repo.CreateCommit(storage.CommitOptions{
	TargetBranch:  "main",
	CommitMessage: "Get started with Code Storage",
	Author:        storage.CommitSignature{Name: "Pierre", Email: "pierre@pierre.co"},
})

result, err := builder.
	AddFileFromString("README.md", "# Getting started\n", nil).
	AddFileFromString("main.go", "package main\n\nfunc main() {}\n", nil).
	Send(ctx)

fmt.Println(result.CommitSHA)
go

身份验证和安全#

Code Storage 使用 JSON Web Tokens (JWT) 进行身份验证。每个 Code Storage 请求使用您的组织签名的 JWT。您控制每个 JWT 中的仓库访问、范围、过期和引用策略,因此每个客户端、代理或任务都能获得所需的精确访问权限。

flowchart TD
    A[组织] --> B[签名 JWT]
    B --> C[带范围的 JWT]
    C --> D[Ref 策略]
    C --> E[过期]
    C --> F[仓库访问]
    
    D --> G[限制引用更新]
    E --> H[令牌过期]
    F --> I[仓库权限]
    
    G --> J[代理请求]
    H --> J
    I --> J
    
    J --> K[Code Storage API]
    K --> L[验证 JWT]
    L --> M[应用策略]
    M --> N[执行操作]

性能和规模#

Code Storage 旨在处理大规模工作负载:

  • 每天数百万个仓库:可以处理每天数百万个新仓库
  • 快 60 倍:读写操作比类似的基于 S3/R2 的解决方案快约 60 倍
  • 99.99% 正常运行时间:关键仓库基础设施的高可用性
  • 峰值时 90,000+ 操作:可以在峰值时维持 90,000+ 操作

案例研究:Lovable#

Lovable 是一个 AI 驱动的软件开发平台,选择 Code Storage 来处理每周 800 万+ 新仓库,具有前所未有的速度、规模和可靠性要求。

取得的结果#

  • 99.99% 正常运行时间 用于关键仓库基础设施
  • 峰值时 90,000+ 操作
  • p50 获取延迟改善 230%
  • 推送延迟改善 160%

“Pierre 已成为我们在规模上运营 AI 原生软件生成的基础设施。他们的团队深刻理解代理驱动开发工作负载的运营现实。”

— Will Rudenmalm,Lovable 技术人员

最佳实践#

  1. 使用临时分支 用于实验和预览
  2. 实施引用策略 以限制强制推送并保护重要分支
  3. 利用 webhooks 与构建系统和机器人集成
  4. 使用会话状态工作流程 用于代理状态管理
  5. 实施并行尝试 用于探索和优化

重要说明#

[!NOTE] Code Storage 不提供拉取请求、问题或代码审查。它专注于 Git 基础设施和存储,而不是 GitHub 的协作功能。

参考资料#