Mirage:把 S3、Slack、GitHub 挂成同一棵虚拟文件树

热点手记 · GitHub 新项目速递 · hot.snaplinediary.cn · 估读约 8 分钟 · 2026-05-20

GitHub 新项目速递 · 估读约 8 分钟 · 2026-05-20

碎片化是 Agent 集成的真成本

Agent 同时要 S3、Slack、GitHub、Notion 时,传统做法是多个 SDK + 多套 OAuth + 多套错误处理。Mirage(github.com/strukto-ai/mirage)把各类后端挂到同一虚拟文件系统,让 Agent 用 ls、cat、cp、grep、find 组合管道,利用 LLM 对 shell 的强项,而不是为每个 SaaS 写专用 tool schema。

这个思路的底层假设是:LLM 在训练数据中见过大量 shell 命令,对文件语义的理解比特定 REST API 更稳定。Mirage 不是让 Agent 学新 SDK,而是把世界翻译成 Agent 已经懂的语言。

架构亮点

Workspace 与虚拟文件树

配置一棵树,例如 /s3 指向桶,/slack 指向频道 JSON。支持 snapshot 与版本,便于复现 Agent 环境。Workspace 配置是声明式的,用 Python dict 或 YAML 描述,启动时一次性挂载。

文件语义做了合理映射:S3 对象变成文件路径,Slack 消息变成 JSON 行文件,GitHub issue 变成 markdown 文件。不是完美的 one-to-one,但足以支撑 grep、wc、head 这类日常操作。

一个典型配置如下:

from mirage import Workspace
    from mirage.resource.s3 import S3Resource, S3Config
    from mirage.resource.slack import SlackResource, SlackConfig
    from mirage.resource.github import GitHubResource, GitHubConfig
    
    ws = Workspace({
        "/ro-s3/logs": S3Resource(S3Config(bucket="prod-logs", prefix="2026/")),
        "/ro-s3/assets": S3Resource(S3Config(bucket="static-assets")),
        "/ro-slack/general": SlackResource(SlackConfig(channel="C123456")),
        "/ro-github/issues": GitHubResource(GitHubConfig(repo="strukto-ai/mirage")),
        "/rw-scratch": S3Resource(S3Config(bucket="agent-scratch", allow_write=True)),
    })
    

注意前缀 /ro- 表示只读,/rw- 表示可写。这种命名约定让人类和 Agent 都能一眼识别权限边界。

双语言 SDK

Python 包 mirage-ai 与 TypeScript 包 @struktoai/mirage-node 同时维护。CLI 和 daemon 模式也有。Python SDK 适合 Jupyter 或后端服务嵌入,TypeScript SDK 适合 Next.js 或边缘函数。

两个 SDK 的核心语义一致:创建 Workspace、挂载 Resource、执行命令。但版本发布节奏可能不同步,生产环境建议锁死一种语言。Node SDK 的异步接口用 Promise,Python SDK 用 async/await,迁移时需注意错误处理风格差异。

缓存层

索引缓存与对象字节缓存可走 RAM 或 Redis。第一次 ls /s3 可能慢,因为要走 ListObjects API;第二次命中缓存就快得多。缓存 TTL 可配置,对变化不频繁的数据可以设长一些。

缓存对限流敏感的后端特别重要。Slack API 有 tier 限制,未经缓存的 grep 可能几秒就把配额打光。Redis 配置示例:

ws = Workspace(
        mounts={...},
        cache_backend="redis://localhost:6379/0",
        cache_ttl_seconds=300,
    )
    

框架嵌入

文档列举与 OpenHands、LangChain、Pydantic AI 等组合。定位是工具层与 sandbox,不是替代 LLM。在 LangChain 里可以作为 Tool 接入,在 OpenHands 里可以作为文件操作后端。

Pydantic AI 集成示例:

from pydantic_ai import Agent
    from mirage.langchain import MirageTool
    
    tool = MirageTool(ws)
    agent = Agent("openai:gpt-4o", tools=[tool])
    

上手示例

安装:

curl -fsSL https://strukto.ai/mirage/install.sh | sh
    uv add mirage-ai
    

基础用法:

result = await ws.execute("grep alert /slack/general/*.json | wc -l")
    print(result.stdout)
    

实测顺序:只读挂载 -> 单条 cat -> 再试 cp 到隔离目录,避免一上来跨服务写生产。

典型收益与代价

收益:少维护十几个 MCP Server;prompt 里工具说明更短;Agent 出错时人类可以用同样命令手动复现;审计日志天然统一,因为所有操作都走 Workspace.execute。

代价:所有能力包装成文件语义,某些 API 细粒度操作会别扭。比如 Slack 的线程回复、 reaction 表情,在文件系统里很难找到自然映射。错误信息也要习惯 vfs 层的翻译,原始 API 报错可能被包装成 “No such file or directory”。

安全:vfs 上的 rm

把 Slack 当文件系统后,一条错误 cp 可能把敏感消息导出到公开桶。建议生产 Workspace 只读,写操作仅在 scratch/ 前缀,定期审计 OAuth scope。

Agent prompt 约束示例:

你只能使用 /ro-* 路径。输出必须引用路径。禁止 cp 到 /ro- 以外。
    

把约束写进系统提示,比事后追责有效。生产环境中,写权限的开通应该走单独的审批流程,而不是默认开放。

性能与限流

跨服务 grep 可能触发上游 API 限流。利用 Mirage 缓存层,并对大目录分页。批处理任务放夜间 cron,而不是交互式 Agent 会话里硬跑。

分页示例:

await ws.execute("ls /s3/logs/2026/05 | head -n 100")
    

不要不加限制地遍历全量对象。S3 ListObjectsV2 在百万对象桶上可能耗时数十秒。

Workspace 命名规范

建议固定前缀:/ro-s3/ 只读桶、/rw-scratch/ 可写临时、/slack-ro/ 只读频道。Agent prompt 里写死「禁止写 /ro-」。人类审计时一眼看懂权限。

多人协作时,每个人独立 Workspace 配置,禁止共享写 Token。审计日志记录谁在何时执行了跨服务 cp。

跨服务管道实战

统计本周 alert 关键词出现次数:

await ws.execute("grep -i outage /slack-ro/general/*.json | wc -l")
    

先在小样本目录跑通,再扩到全量,避免一次 grep 打满 Slack tier 限流。

与 OpenHands 组合时,OpenHands 负责改代码,Mirage 负责读 Slack/S3 上下文。不要让 OpenHands 直接持 Slack 写 Token;用 Mirage 只读挂载把证据喂给 Agent。

缓存命中率观察

若重复 grep 同一目录,Redis 缓存应提高命中率。命中率低说明 Workspace 路径配置不稳或数据变动过快,需要缩小 snapshot 范围。

监控命令:

redis-cli info stats | grep keyspace
    

看 hits 与 misses 比例。miss 过高时检查 TTL 设置是否合理。

SDK 版本锁定

Python 与 Node SDK 主版本不同步时,行为可能不一致。选定一种语言写生产集成,另一种仅做实验。锁 uv.lock 或 package-lock.json 再部署。

升级前先读 Release Notes,关注 vfs 语义变更。某次升级如果改了路径分隔符或默认编码,可能导致现有 Agent 脚本静默失败。

故障排查速查

现象 可能原因 排查命令
空结果 OAuth 过期或 scope 不足 检查 Token 有效期
极慢 未开 Redis 缓存或目录过大 ls 加 head 限制
乱码 二进制被当文本 cat 用 file 命令确认类型
权限拒绝 Agent 越界写 /ro- 检查 prompt 约束

遇到空结果时不要先怀疑 Agent,先用手动 curl 确认 API 权限。很多问题是 Slack OAuth scope 被管理员收紧,而不是代码 bug。

另外,建议在生产环境前做一次压力测试:用真实代码库触发 50 次查询,记录平均响应时间和错误率,作为上线基线。

局限与不适合谁

Mirage 不能消除 OAuth 合规审查,Slack、GitHub、Gmail 仍要企业管理员批准。Agent 若误解 rm 类命令,破坏面可能跨服务,必须沙箱加备份。新项目 API 变动快,生产要用锁定版本。若你只有单一 GitHub 集成需求,直接官方 CLI 可能更简单。文件语义对某些 API 是过度简化,比如需要细粒度审批流或实时推送的场景,Mirage 的 vfs 抽象会成为阻碍。跨服务管道的延迟是各后端延迟之和,不适合对实时性要求高的交互场景。初期部署建议只读挂载运行至少一周,确认无异常后再评估写权限。Mirage 是工具层抽象,不能替代后端自身的 SLA 保障。多租户场景下,Workspace 隔离要自己做,项目本身不提供企业级权限体系。不要在生产环境直接暴露 daemon 端口到公网。具体安装步骤以 README 为准。仓库:https://github.com/strukto-ai/mirage