VINO/WANG返回博客 ←

BLOG / POST

文件系统上下文与托管代理

文件系统作为上下文工程载体的六种模式,以及托管代理的沙盒基础设施、API 层与多端客户端实现。

  • context-engineering
  • agent

来源:Agent-Skills-for-Context-Engineering

模块一:基于文件系统的上下文工程

核心概念

文件系统提供了单一接口,代理可以通过它灵活地存储、检索和更新几乎无限量的上下文。这种模式解决了基本的约束:上下文窗口是有限的,而任务通常需要的信息量超过了单个窗口的容量。

核心洞察:文件系统支持动态上下文发现——代理按需拉取相关上下文,而不是在上下文窗口中携带所有内容。这与静态上下文形成对比,静态上下文无论是否相关都会被包含。

上下文工程的四种失败方式

  1. 上下文缺失:代理需要的上下文不在可用上下文中
  2. 检索不完整:检索到的上下文未能封装所需上下文
  3. 上下文过载:检索到的上下文远远超过所需上下文,浪费 token 并降低性能
  4. 发现困难:代理无法发现埋藏在许多文件中的小众信息

文件系统通过提供一个持久层来解决这些失败,代理可以在其中写入一次并选择性读取,卸载大量内容,同时保留通过搜索工具检索特定信息的能力。

静态 vs 动态上下文权衡

静态上下文

静态上下文始终包含在提示中:

  • 系统指令
  • 工具定义
  • 关键规则

无论任务相关性如何,静态上下文都会消耗 token。随着代理积累更多能力(工具、技能、指令),静态上下文会增长并挤占动态信息的空间。

问题

  • 消耗 token 而不考虑任务相关性
  • 可能包含令人困惑或矛盾的信息
  • 限制了动态信息的可用空间

动态上下文发现

动态上下文在与当前任务相关时按需加载。代理接收最小的静态指针(名称、描述、文件路径),并使用搜索工具在需要时加载完整内容。

优势

  • token 效率更高,只有必要的数据进入上下文窗口
  • 通过减少潜在困惑或矛盾的信息提高响应质量
  • 支持近乎无限的扩展知识库

权衡:动态发现需要模型正确识别何时加载额外的上下文。这对于当前的前沿模型很有效,但对于无法识别何时需要更多信息的能力较弱的模型可能会失败。

六种文件系统模式

模式 1:文件系统作为草稿板 (Scratch Pad)

问题 工具调用可能返回大量输出:

  • 网络搜索可能返回 10k token 的原始内容
  • 数据库查询可能返回数百行
  • 代码分析可能生成大量报告

如果这些内容进入消息历史,它们将在整个对话中保留,导致:

  • token 成本膨胀
  • 降低对更相关信息的注意力
  • 可能导致上下文退化

解决方案 将大型工具输出写入文件,而不是直接返回到上下文。代理然后使用定向检索(grep、特定行读取)仅提取相关部分。

实现示例

def handle_tool_output(output: str, threshold: int = 2000) -> str:
    """
    处理工具输出,将大输出卸载到文件系统
    """
    if len(output) < threshold:
        return output

    # 写入草稿板
    file_path = f"scratch/{tool_name}_{timestamp}.txt"
    write_file(file_path, output)

    # 返回引用而不是内容
    key_summary = extract_summary(output, max_tokens=200)
    return f"[Output written to {file_path}. Summary: {key_summary}]"

使用示例

输入: Web 搜索返回 8000 tokens
之前: 8000 tokens 添加到消息历史
之后:
  - 写入到 scratch/search_results_001.txt
  - 返回: "[Results in scratch/search_results_001.txt. Key finding: API rate limit is 1000 req/min]"
  - 代理在需要具体细节时 grep 文件
结果: 上下文中约 100 tokens,8000 tokens 按需访问

好处

  • 减少长对话中的 token 累积
  • 保留完整输出供以后参考
  • 支持定向检索而不是携带所有内容
  • 防止上下文窗口被不相关的信息填充

模式 2:计划持久化

问题 长视野任务要求代理制定计划并遵循它们。但随着对话的延伸,计划可能:

  • 脱离注意力
  • 因总结而丢失
  • 被新信息混淆

代理失去了它应该做什么的跟踪。

解决方案 将计划写入文件系统。代理可以在任何时候重新读取其计划,提醒自己当前的目标和进度。这有时被称为“通过背诵操纵注意力”(manipulating attention through recitation)。

实现示例

# scratch/current_plan.yaml
objective: "Refactor authentication module"
status: in_progress
steps:
  - id: 1
    description: "Audit current auth endpoints"
    status: completed
  - id: 2
    description: "Design new token validation flow"
    status: in_progress
  - id: 3
    description: "Implement and test changes"
    status: pending

代理在每个回合开始时或需要重新定位时读取此文件。

好处

  • 保持对长期目标的关注
  • 防止计划在上下文压缩中丢失
  • 允许代理在复杂任务中保持一致性
  • 支持计划的可视化和跟踪

模式 3:通过文件系统进行子代理通信

问题 在多代理系统中,子代理通常通过消息传递向协调代理报告发现。这会产生“电话游戏”(game of telephone):

  • 信息在每次跳跃时通过总结而降级
  • 协调器的上下文累积来自所有子代理的报告
  • 详细信息在多层总结中丢失

解决方案 子代理将其发现直接写入文件系统。协调器直接读取这些文件,绕过中间消息传递。

实现结构

workspace/
  agents/
    research_agent/
      findings.md        # 研究代理在这里写入
      sources.jsonl      # 源跟踪
    code_agent/
      changes.md         # 代码代理在这里写入
      test_results.txt   # 测试输出
    analyzer_agent/
      metrics.json       # 分析结果
      recommendations.md # 建议
  coordinator/
    synthesis.md         # 协调器读取代理输出,写入综合

每个代理在相对隔离中操作,但通过文件系统共享状态。

好处

  • 保留信息保真度,无总结损失
  • 减少协调器中的上下文累积
  • 允许代理并行工作而无协调开销
  • 支持异步通信模式

模式 4:动态技能加载

问题 代理可能有许多技能或指令集,但大多数与任何给定任务无关。将所有指令填充到系统提示中会导致:

  • 浪费 token
  • 可能用矛盾或无关的指导混淆模型
  • 增加静态上下文开销

解决方案 将技能存储为文件。仅在静态上下文中包含技能名称和简短描述。代理在任务需要时使用搜索工具加载相关技能内容。

静态上下文示例

Available skills (load with read_file when relevant):
- database-optimization: Query tuning and indexing strategies
- api-design: REST/GraphQL best practices
- testing-strategies: Unit, integration, and e2e testing patterns
- security-audit: Common vulnerabilities and mitigation strategies
- performance-profiling: Bottleneck identification and optimization

使用示例

输入: 用户询问数据库索引
静态上下文: "database-optimization: Query tuning and indexing"
代理操作: read_file("skills/database-optimization/SKILL.md")
结果: 仅在相关时加载完整技能

好处

  • 保持系统提示精简
  • 只在需要时加载相关技能
  • 避免指令之间的矛盾
  • 支持技能库的无限扩展

模式 5:终端和日志持久化

问题 长时间运行进程的终端输出迅速累积。将输出复制粘贴到代理输入是:

  • 手动且低效的
  • 容易出错
  • 难以搜索特定模式

解决方案 自动将终端输出同步到文件。代理可以 grep 相关部分(错误消息、特定命令),而无需加载整个终端历史。

实现结构

terminals/
  1.txt    # 终端会话 1 输出
  2.txt    # 终端会话 2 输出

代理使用定向 grep 查询:

grep -A 5 "error" terminals/1.txt
grep -B 3 "fatal" terminals/*.txt

好处

  • 自动捕获所有终端输出
  • 支持模式搜索而非完整加载
  • 保留完整历史用于调试
  • 跨会话持久化日志

模式 6:通过自我修改学习

问题 代理通常缺乏用户在交互期间隐式或显式提供的上下文。传统上,这需要在会话之间手动更新系统提示。

解决方案 代理将学习的信息写入自己的指令文件。后续会话加载这些文件,自动合并学习的上下文。

实现示例

def remember_preference(key: str, value: str):
    """
    记住用户偏好到持久存储
    """
    preferences_file = "agent/user_preferences.yaml"
    prefs = load_yaml(preferences_file)
    prefs[key] = value
    write_yaml(preferences_file, prefs)

# 用户说:"我总是使用 TypeScript"
# 代理调用: remember_preference("preferred_language", "typescript")

后续会话包括一个步骤来加载用户偏好(如果文件存在)。

警告 这种模式仍在出现中。自我修改需要仔细的保护措施:

  • 防止代理积累错误或矛盾的指令
  • 验证学习的上下文与已知最佳实践
  • 实施指令的过期机制
  • 提供审查和撤销学习内容的机制

好处

  • 自动适应用户偏好
  • 跨会话持久化学习
  • 无需手动系统提示更新
  • 个性化代理体验

文件系统搜索技术

模型经过专门训练以理解文件系统遍历。lsglobgrepread_file 与行范围的组合为上下文发现提供了强大的功能:

基本工具

  • ls / list_dir:发现目录结构

    ls src/components/
  • glob:查找匹配模式的文件

    glob("**/*.py")      # 所有 Python 文件
    glob("src/**/*.ts")  # src 下所有 TypeScript 文件
    glob("test_*.py")    # 所有测试文件
  • grep:搜索文件内容中的模式

    grep "def authenticate" src/**/*.py
    grep -A 10 "class User" models.py
    grep -B 5 "TODO" **/*.md
  • read_file 与范围:读取特定行范围而不加载整个文件

    read_file("config.yaml", offset=1, limit=50)

为什么这适用于技术内容

对于语义含义稀薄但结构模式清晰的技术内容(代码、API 文档),这种组合通常优于语义搜索:

优势

  • 精确匹配,无语义歧义
  • 快速且确定性
  • 模型理解代码结构和命名约定
  • 可以组合多个搜索条件

组合策略 语义搜索和文件系统搜索可以很好地配合:

  • 语义搜索:概念查询(“如何处理身份验证?”)
  • 文件系统搜索:结构和精确匹配查询(“查找所有使用 bcrypt 的文件”)

实践指导

何时使用文件系统上下文

使用文件系统模式当

  • 工具输出超过 2000 tokens
  • 任务跨越多个对话回合
  • 多个代理需要共享状态
  • 技能或指令超过系统提示舒适容纳的范围
  • 日志或终端输出需要选择性查询

避免文件系统模式当

  • 任务在单个回合中完成
  • 上下文舒适地适合窗口
  • 延迟至关重要(文件 I/O 增加开销)
  • 简单模型无法进行文件系统工具使用

文件组织

为可发现性构建文件结构:

project/
  scratch/           # 临时工作文件
    tool_outputs/    # 大型工具结果
    plans/           # 活跃计划和检查清单
  memory/            # 持久学习信息
    preferences.yaml # 用户偏好
    patterns.md      # 学习的模式
  skills/            # 可加载技能定义
  agents/            # 子代理工作空间

使用一致的命名约定:

  • 在草稿文件中包含时间戳或 ID 以消除歧义
  • 使用描述性文件名
  • 按功能和日期组织目录

Token 会计

跟踪 token 来源:

  • 测量静态与动态上下文比率
  • 监控卸载前后的工具输出大小
  • 跟踪动态上下文的实际加载频率

基于测量进行优化,而非假设。

关键指标

  • 静态上下文 token 计数
  • 平均动态上下文加载频率
  • 卸载到文件系统的 token 数量
  • 文件系统搜索操作的频率

模块二:托管代理基础设施

核心概念

托管代理在远程沙盒环境中运行,而不是在本地机器上。设计良好时,它们提供:

  • 无限并发
  • 一致的执行环境
  • 多人协作

关键洞察:会话速度应仅受模型提供商 time-to-first-token 限制,所有基础设施设置应在用户开始会话之前完成。

架构三层

  1. 沙盒基础设施:隔离执行
  2. API 层:状态管理和客户端协调
  3. 客户端界面:跨平台的用户交互

沙盒基础设施

核心挑战

快速启动完整的开发环境是主要的技术挑战。用户期望近乎即时的会话启动,但开发环境需要:

  • 克隆存储库
  • 安装依赖项
  • 运行构建步骤

镜像注册表模式

定期(每 30 分钟一次)预构建环境镜像。每个镜像包含:

  1. 克隆的存储库:在已知提交处
  2. 所有运行时依赖项:已安装
  3. 初始设置和构建命令:已完成
  4. 缓存文件:从运行应用程序和测试套件一次生成

工作流程

1. 每 30 分钟构建新镜像
2. 当启动会话时,从最新镜像生成沙盒
3. 存储库最多落后 30 分钟
4. 与最新代码的同步快得多

好处

  • 快速会话启动(秒级而非分钟级)
  • 一致的环境
  • 减少同步时间
  • 预热缓存

快照和恢复

在关键点获取文件系统快照:

  • 初始镜像构建后:基础快照
  • 代理完成更改后:会话快照
  • 沙盒退出前:用于潜在的后续操作

这实现了即时恢复,而无需重新运行设置。

好处

  • 即时会话恢复
  • 无需重新运行昂贵设置
  • 支持会话分支和比较
  • 快速回滚到已知良好状态

Git 配置

由于 git 操作在镜像构建期间不绑定到特定用户:

  • 为存储库访问生成 GitHub 应用安装令牌
  • 在提交和推送更改时更新 git config 的 user.nameuser.email
  • 使用提示用户的身份进行提交,而非应用身份

实现示例

def setup_git_identity(user):
    """
    为后台代理设置 git 身份
    """
    # 使用提示用户的身份
    run_git(["config", "user.name", user.name])
    run_git(["config", "user.email", user.email])

    # 存储库访问使用应用令牌
    run_git(["config", "credential.helper", "store"])
    with open(".git-credentials", "w") as f:
        f.write(f"https://x-access-token:{app_token}@github.com\n")

温池策略

为高容量存储库维护预加热的沙盒池:

策略

  • 沙盒在用户开始会话之前就准备就绪
  • 当新镜像构建完成时过期并重新创建池条目
  • 预测性预热:用户开始输入时就开始加热沙盒

容量规划

  • 基于使用模式预测需求
  • 保持最小池大小以处理突发需求
  • 自动扩展池以处理负载峰值

好处

  • 消除启动延迟
  • 改善用户体验
  • 更好的资源利用率
  • 处理流量峰值

代理框架选择

服务器优先架构

选择结构为服务器的代理框架,TUI 和桌面应用程序作为客户端

优势

  • 多个自定义客户端而不重复代理逻辑
  • 所有交互表面的一致行为
  • 用于扩展功能的插件系统
  • 实时更新的事件驱动架构

示例架构

┌─────────────────────────────────────┐
│         Agent Server                │
│  - 核心代理逻辑                      │
│  - 状态管理                          │
│  - 工具执行                          │
│  - 插件系统                          │
└─────────────────────────────────────┘
           ↑              ↑              ↑
           │              │              │
┌──────────┴─┐   ┌───────┴──────┐   ┌──┴─────────┐
│   TUI      │   │  Desktop App │   │ Web Client │
│  Client    │   │   Client     │   │   Client   │
└────────────┘   └──────────────┘   └────────────┘

代码作为真实来源

选择代理可以读取自己的源代码以理解行为的框架。

为什么这很重要: 这在 AI 开发中被低估:拥有代码作为真实来源可以防止:

  • 对代理自身能力的幻觉
  • 不一致的行为
  • 文档漂移

实现

  • 代理可以访问其自己的源代码
  • 代理可以解释为什么它做出某些决定
  • 代理可以根据代码改进自身

插件系统要求

框架应支持以下功能的插件:

事件监听

  • 工具执行事件(例如 tool.execute.before
  • 状态变化事件
  • 错误事件

条件操作

  • 阻止或修改工具调用
  • 在运行时注入上下文或状态
  • 覆盖默认行为

示例

class ToolAuditPlugin:
    def on_before_tool_execute(self, tool_name, args):
        """
        在工具执行前记录所有工具调用
        """
        log.info(f"Executing {tool_name} with {args}")

        # 可以阻止或修改调用
        if tool_name == "rm" and "-rf" in args:
            raise Exception("Destructive operation blocked")

    def on_after_tool_execute(self, tool_name, result):
        """
        记录工具结果
        """
        log.info(f"{tool_name} completed: {len(result)} chars")

速度优化

预测性预热

核心思想:用户开始输入提示时就开始加热沙盒

实现

async def on_user_typing(user_id, repo_id):
    """
    当用户开始输入时触发
    """
    # 并行克隆最新更改
    await async_clone_repo(repo_id)

    # 在用户按下回车之前运行初始设置
    await async_run_setup(repo_id)

好处

  • 对于快速启动,沙盒可以在用户完成输入之前准备就绪
  • 用户感觉不到延迟
  • 更好的用户体验

并行文件读取

允许代理立即开始读取文件,即使与最新基础分支的同步尚未完成:

假设

  • 在大型存储库中,传入提示很少修改最近更改的文件
  • 代理可以立即研究而无需等待 git 同步

实现

def handle_file_read(file_path, sync_status):
    """
    处理文件读取
    """
    if not sync_status.is_complete:
        if file_path in sync_status.pending_changes:
            raise Exception("File not available until sync completes")

    # 允许读取未更改的文件
    return read_file(file_path)

def handle_file_write(file_path, sync_status):
    """
    处理文件写入
    """
    if not sync_status.is_complete:
        raise Exception("Must wait for sync before writing")

    return write_file(file_path)

好处

  • 代理可以立即开始工作
  • 不会阻止大多数读取操作
  • 仅在必要时阻止写入

最大化构建时工作

将所有可能的内容移动到镜像构建步骤:

  • 完整依赖安装
  • 数据库模式设置
  • 初始应用程序和测试套件运行(填充缓存)
  • 代码生成和编译

关键原则:构建时持续时间对用户不可见。

示例

# 在镜像构建期间
RUN npm install
RUN npm run build
RUN npm run test          # 填充缓存
RUN python setup.py       # 生成代码

# 在会话启动时(快速)
# 仅 git pull 和小增量更新

自生成代理

代理生成的会话

创建允许代理生成新会话的工具:

用例

  • 跨不同存储库的研究任务
  • 大型更改的并行子任务执行
  • 从一个主要任务生成多个较小的 PR

工具设计

def spawn_agent_session(
    task: str,
    repository: str,
    priority: str = "normal"
) -> str:
    """
    生成一个新的代理会话

    返回会话 ID
    """
    session_id = create_session(repository)
    submit_prompt(session_id, task, priority)
    return session_id

def get_session_status(session_id: str) -> dict:
    """
    检查会话状态

    返回状态信息
    """
    return query_session(session_id)

def wait_for_session(session_id: str, timeout: int = 300):
    """
    等待会话完成
    """
    return await_session_completion(session_id, timeout)

使用示例

# 主代理
def refactor_authentication():
    """
    大型重构任务,分解为多个 PR
    """
    # 生成研究子任务
    research_session = spawn_agent_session(
        task="Research best practices for JWT implementation",
        repository="docs/auth-research"
    )

    # 生成代码子任务(与研究并行)
    backend_session = spawn_agent_session(
        task="Implement JWT authentication in backend",
        repository="backend"
    )

    frontend_session = spawn_agent_session(
        task="Implement JWT token management in frontend",
        repository="frontend"
    )

    # 继续其他工作...

    # 等待子任务完成
    research_results = wait_for_session(research_session)
    backend_results = wait_for_session(backend_session)
    frontend_results = wait_for_session(frontend_session)

    # 综合结果
    return synthesize_results([
        research_results,
        backend_results,
        frontend_results
    ])

自生成的提示工程

设计提示以指导代理何时生成子会话:

触发条件

  • 需要跨存储库探索的研究任务
  • 将单一更改分解为多个 PR
  • 并行探索不同方法
  • 独立的子任务可以从并行化中受益

提示示例

When facing tasks that can be executed in parallel,
consider spawning sub-sessions:

1. Research tasks across different repositories:
   - If you need information from multiple codebases
   - Spawn a research session for each repository

2. Breaking monolithic changes into smaller PRs:
   - Large changes should be split into focused PRs
   - Spawn a session for each PR

3. Parallel exploration of approaches:
   - When multiple viable approaches exist
   - Spawn sessions to explore each in parallel

Always:
- Use spawn_agent_session() for parallel work
- Use get_session_status() to check progress
- Continue your own work while sub-sessions run
- Synthesize results when all sessions complete

API 层

每会话状态隔离

每个会话需要自己隔离的状态存储:

实现选项

  • 每会话 SQLite:简单,有效
  • 每会话 Redis:更快,更复杂
  • 每会话 PostgreSQL schema:强大,资源密集

SQLite 方法

class SessionState:
    def __init__(self, session_id: str):
        self.db_path = f"sessions/{session_id}.db"
        self.conn = sqlite3.connect(self.db_path)

    def get_state(self, key: str) -> Any:
        cursor = self.conn.execute(
            "SELECT value FROM state WHERE key = ?",
            (key,)
        )
        return cursor.fetchone()[0]

    def set_state(self, key: str, value: Any):
        self.conn.execute(
            "INSERT OR REPLACE INTO state (key, value) VALUES (?, ?)",
            (key, json.dumps(value))
        )
        self.conn.commit()

好处

  • 没有任何会话会影响另一个会话的性能
  • 处理数百个并发会话
  • 简单的资源管理
  • 易于调试和监控

实时流

代理工作涉及高频更新:

  • 来自模型提供商的 token 流
  • 工具执行状态更新
  • 文件更改通知

WebSocket 连接

async def stream_session_updates(session_id: str, websocket):
    """
    将会话更新流式传输到客户端
    """
    async for update in session_updates(session_id):
        await websocket.send_json({
            "type": update.type,
            "data": update.data
        })

        # 休眠 API 在空闲期间降低成本
        if update.type == "idle":
            await hibernate_connection(session_id)

休眠 API

  • 在空闲期间降低计算成本
  • 保持打开连接
  • 快速恢复

跨客户端同步

构建跨所有接口同步的单一状态系统:

支持平台

  • 聊天界面(TUI)
  • Slack 机器人
  • Chrome 扩展
  • Web 界面
  • VS Code 实例

实现

class SessionManager:
    def __init__(self):
        self.sessions = {}
        self.clients = {}  # session_id -> [websockets]

    def broadcast_update(self, session_id: str, update: dict):
        """
        广播更新到会话的所有客户端
        """
        clients = self.clients.get(session_id, [])
        for client in clients:
            await client.send_json(update)

    def add_client(self, session_id: str, client):
        """
        添加客户端到会话
        """
        if session_id not in self.clients:
            self.clients[session_id] = []
        self.clients[session_id].append(client)

        # 发送当前状态
        yield self.sessions[session_id].get_state()

好处

  • 所有更改同步到会话状态
  • 无缝客户端切换
  • 多设备访问
  • 实时协作

多人支持

为什么多人很重要

多人支持实现:

教学场景

  • 教非工程师有效使用 AI
  • 导师指导学习会话
  • 团队培训

协作场景

  • 多个团队成员的实时 QA 会话
  • 具有即时更改的实时 PR 审查
  • 协作调试会话
  • 配对编程

商业价值

  • 更快的团队入职
  • 知识共享
  • 集体问题解决
  • 透明度

实现要求

数据模型

  • 不得将会话绑定到单个作者
  • 支持多个参与者
  • 跟踪每个操作作者

作者身份传递

def handle_prompt(session_id: str, prompt: str, user: User):
    """
    处理用户提示
    """
    # 将作者信息传递给每个提示
    agent_prompt = f"""
    User: {user.name} ({user.email})
    Prompt: {prompt}

    Previous context:
    {get_session_context(session_id)}
    """

    # 代码更改归因于提示用户
    result = agent.execute(agent_prompt)
    result.author = user

共享会话链接

def create_shared_session_link(session_id: str) -> str:
    """
    创建共享会话链接
    """
    return f"https://agent.app/sessions/{session_id}?share=true"

# 任何有链接的人可以查看和交互
# 所有操作都归因于实际用户

好处

  • 具有适当同步架构的多人支持几乎是免费的
  • 增加产品价值
  • 促进采用
  • 支持新用例

认证和授权

基于用户的提交

使用 GitHub 身份验证来:

  • 获取用户令牌以创建 PR
  • 代表用户(而非应用)打开 PR
  • 防止用户批准自己的更改

工作流程

def create_pull_request(session_id: str, user: User):
    """
    使用用户的 GitHub 身份创建 PR
    """
    # 1. 沙盒推送更改(更新 git user config)
    # 2. 沙盒发送事件到 API,包含分支名称和会话 ID
    # 3. API 使用用户的 GitHub 令牌创建 PR
    # 4. GitHub webhooks 通知 API 的 PR 事件

    # 使用用户的令牌
    github = GitHubClient(user.access_token)

    pr = github.create_pull_request(
        repo=user.repository,
        head=session_branch,
        base="main",
        title=f"Agent changes from {session_id}",
        body="Generated by hosted agent"
    )

    # 存储用户身份用于审查
    pr.author = user

    return pr

安全考虑

  • 不要将用户令牌存储在沙盒中
  • 使用短期令牌
  • 实施适当的范围限制
  • 记录所有操作

沙盒到 API 流

1. 沙盒推送更改
   └─ 更新 git user config 为实际用户

2. 沙盒发送事件到 API
   └─ 包含分支名称和会话 ID

3. API 创建 PR
   └─ 使用用户的 GitHub 令牌
   └─ 将操作归因于用户

4. GitHub webhooks 通知 API
   └─ PR 事件(审查、评论、合并)

客户端实现

Slack 集成

为什么 Slack 有效

  • 内部采用最有效的分发渠道
  • 当团队成员看到其他人使用它时,创造病毒循环
  • 无需语法,自然聊天界面
  • 低摩擦,高可见性

存储库分类器

def classify_repository(message: str, context: dict) -> str:
    """
    从消息、线程上下文和频道名称分类存储库
    """
    prompt = f"""
    Available repositories:
    - monorepo: Main application code
    - backend: API and services
    - frontend: Web client
    - docs: Documentation

    Context:
    - Channel: {context['channel_name']}
    - Thread topic: {context.get('thread_topic', 'None')}
    - User message: {message}

    Determine which repository to work in.
    If unclear, return "unknown"
    """

    return fast_model.generate(prompt)

最佳实践

  • 包含常见存储库的提示
  • 允许“未知”选项以处理模糊情况
  • 从频道名称和线程上下文学习
  • 在工作空间中提供明确的存储库切换命令

Web 界面

核心功能

  • 在桌面和移动设备上工作
  • 代理工作的实时流
  • 在沙盒内运行的托管 VS Code 实例
  • 用于视觉验证的流式桌面视图
  • PR 的前后屏幕截图

统计页面

def get_statistics(repo: str, time_range: DateRange) -> dict:
    """
    获取仓库统计信息
    """
    return {
        # 主要成功指标
        "sessions_resulting_in_merged_prs": count_merged_prs(repo, time_range),

        # 使用情况
        "usage_over_time": get_usage_timeline(repo, time_range),
        "total_sessions": count_sessions(repo, time_range),

        # 实时指标
        "live_humans_prompting": count_active_users(window_minutes=5),

        # 质量指标
        "pr_approval_rate": calculate_approval_rate(repo, time_range),
        "avg_revision_count": avg_revisions_per_pr(repo, time_range),

        # 代理贡献
        "agent_written_code_percentage": calculate_agent_contribution(repo)
    }

关键指标

  • 主要成功指标:导致合并 PR 的会话
  • 时间到第一个响应:从会话开始到第一个模型响应的时间
  • PR 批准率:合并的 PR 百分比
  • 修订计数:每个 PR 的平均修订数

Chrome 扩展

目标用户:非工程师

功能

  • 侧边栏聊天界面
  • 截图工具
  • DOM 和 React 内部提取而非原始图像

优势

  • 减少 token 使用,同时保持精度
  • 更适合非工程师
  • 无上下文切换
  • 直接交互

分发

  • 通过托管设备策略分发(绕过 Chrome Web Store)
  • 企业分发
  • 私有扩展

实践指导

后续消息处理

决定如何处理执行期间发送的消息:

队列方法

  • 消息等待当前提示完成
  • 更简单的管理
  • 让用户在代理工作时发送下一步的想法
  • 需要停止代理的机制

插入方法

  • 消息立即处理
  • 更复杂的协调
  • 可能打断当前工作
  • 对紧急中断更有响应

推荐:队列方法更简单且通常足够。

指标重要

跟踪指示真实价值的指标:

成功指标

  • 导致合并 PR 的会话(主要成功指标)
  • 会话到 PR 的转换率
  • PR 批准率和修订计数

性能指标

  • 从会话开始到第一个模型响应的时间
  • 会话完成时间
  • 代理并行工作利用率

使用指标

  • 随时间推移的使用情况
  • 活跃用户计数
  • 每用户会话频率

质量指标

  • 代理编写代码的百分比
  • 代码审查反馈
  • 用户满意度

采用策略

内部采用有效模式

  • 在公共空间(Slack 频道)工作以获得可见性
  • 让产品创造病毒循环
  • 不要强制使用超过现有工具
  • 根据人的需求构建,而非假设需求

采用阶段

  1. 试点:与小团队一起工作
  2. 可见性:在公共频道工作
  3. 病毒式传播:让团队成员看到价值
  4. 扩展:根据反馈扩大到更多团队

总结

文件系统上下文关键要点

  1. 动态上下文发现:按需加载相关上下文,而非携带所有内容
  2. 六种文件系统模式:草稿板、计划持久化、子代理通信、动态技能加载、终端持久化、自我修改
  3. 文件系统搜索技术:ls、glob、grep、read_file 组合提供强大的上下文发现
  4. Token 会计:基于测量而非假设进行优化

托管代理关键要点

  1. 镜像注册表模式:定期(30 分钟)预构建环境镜像
  2. 预测性预热:用户开始输入时就开始加热沙盒
  3. 服务器优先架构:框架结构为服务器,客户端作为薄包装器
  4. 每会话状态隔离:隔离状态以防止跨会话干扰
  5. 多人支持:从一开始就为多人构建,使用适当的同步架构几乎是免费的

与其他技能的关系

文件系统上下文连接到

  • context-optimization:文件系统卸载是一种观察掩蔽形式
  • memory-systems:文件系统即内存是一种简单的内存层
  • multi-agent-patterns:子代理文件工作空间实现隔离
  • context-compression:文件引用实现无损“压缩”
  • tool-design:工具应为大输出返回文件引用

托管代理连接到

  • multi-agent-patterns:自生成代理遵循监督者模式
  • tool-design:构建用于代理生成和状态检查的工具
  • context-optimization:管理跨分布式会话的上下文
  • filesystem-context:使用文件系统进行会话状态和工件

(完)