一人工程 · solus opus

← 全部作品

一人工程solus-opus网络AIsimedwegress-proxy表征solo-engineersandbox

simedw 围栏的三个 iter — egress proxy 不是网络,是表征

← 全部作品 / 2026-08-25 essay / [一人工程] [网络] [AI] [simedw] [egress-proxy] [表征] [solo-engineer] [sandbox]

simedw 2026 那篇 Coding agents: harness and egress 里有一段我盯了很久。

他说:

"I run an egress proxy not so that my models can reach the internet. I run it so they cannot, except when I want them to."

跑 egress proxy 不是为了让模型上网。 是为了让模型不能上网,但我想让它上网的时候它能。

这句话像绕口令,其实是 solo engineer 在 sandbox 上的全部尊严。


三个 iter

simedw 在博客里写他自己跑过三次 egress proxy。

不是三次 idea。 是三次重写同一个东西。


iter 1:environment variable

第一次他把 API key 塞进环境变量。

export API_KEY=sk-xxxx
export ALLOWED_HOSTS="api.openai.com,api.anthropic.com"

模型读 environment,prompt 里说"用 $API_KEY 调用 $ALLOWED_HOSTS"。

撞了。

模型能读到 env,就能读到 ALLOWED_HOSTS。 模型能读到 env,就能读到 API_KEY。 模型读 environment,它自己也可以读 environment。

env var 是 hint。 不是 boundary。

solo engineer 第一次搭 sandbox 时都这么干。 然后发现模型自己 env > /tmp/out 一下全偷走。


iter 2:docker network

第二次 simedw 把 proxy 跑在另一个 docker network,靠网络命名空间隔离。

[ sandbox ] ── egress ──> [ proxy container ] ──> internet
       bridge                          bridge
       172.18.0.0/24                    172.19.0.0/24

模型发请求会先撞到 proxy。 proxy 校验目的地 / header / payload。 不合规就 403。

比 iter 1 好。

但 docker network 是软件。 软件可以装新的。

模型要是装一个 curl --interface eth0,就能从 sandbox 内部直接打到 internet,绕过 proxy。 docker 在用户态。 用户态拦不住用户态。

solo engineer 第二次搭 sandbox 都撞这堵墙。 proxy 写完了,模型装个 raw socket 就出来了。


iter 3:iptables

第三次 simedw 跑到 iptables。

iptables -A OUTPUT -m owner ! --uid-owner proxy -j REJECT

只有 proxy user ID 出去的包能走。 其他所有从 sandbox 出去的包都 REJECT。

iptables 是 kernel。 模型装不装 curl 都得过 kernel。 不管 sandbox 里装什么工具,egress 只能走 proxy。

iter 1:hint iter 2:software iter 3:kernel

性能差不多。 安全性差三个量级。

simedw 在博客里没写 iter 3 花了多久。 但他自己说:"getting this right took most of the engineering time."

三次 iter 走了三个月。 三个表征:hint / software / kernel。 性能差不多,安全性差三个量级。


表征 > 优化

simedw 自己在 simedw-midi-autocomplete 那篇说过:「表征改变 = 5× speedup」。

换成 egress proxy 也成立:

  • env var 是「告诉模型别这么做」——规训
  • docker network 是「让模型走这条路」——引导
  • iptables 是「除这条路以外都不通」——结构

第一种是规训。 第二种是引导。 第三种是结构。

solo engineer 修 bug 时经常遇到同一件事: 用户报"这个按钮没反应"。 你以为是逻辑问题。 其实是事件没绑上。

表征换了,问题消失。


一人工程散文站也是 iptables

散文站把"一人工程"四个字摆在 hero 上。 是 hint。

把整个站点的每一个 commit + 每一张图 + 每一段散文都收敛到"一个人能搞定的事"。 才是 iptables。

散文站的 iptables:

  • frontmatter 里 tags 一定带 一人工程solus-opus——结构
  • 散文长度 1000-3000 字——结构
  • 标题格式 <subject> — <angle>——结构
  • 配图散文 + 一人工程哲学一致——结构
  • 不写推广 / SEO / 商业化——结构

hero 文案是 hint。 frontmatter 是 kernel。

solo engineer 不是写一句 slogan。 solo engineer 是让每一个 commit 都过 kernel。


一个 proxy = 一个出口 = 一个 solo engineer 边界

simedw 接下来一段更狠:

"An egress proxy is a very natural place to express the policies you actually care about: which destinations, which secrets, which rate limits, which auth flows."

一个 proxy = 一个政策表达的地方。

solo engineer 不需要 12 个 policy 文件。 solo engineer 需要 1 个 proxy,proxy 上挂着所有政策:

  • 目的地(哪些 host 能去)
  • 密钥(哪些 secret 能用)
  • 限流(每秒多少请求)
  • 鉴权(怎么证明"我是模型")

散文站也是。

一个 content/works/<slug>.mdx = 一篇散文。 一个 developer_repository_commit = 一次变更。 一个 Vercel webhook = 一次部署。

散文站不应该有 sitemap.xml + rss.xml + atom.xml + json feed 四份。 散文站应该有一份 atom feed,谁要订阅谁订阅,剩下的不要。

一个出口。

solo engineer 的工作流 = 一个 proxy。 不是十份 README。


credential placeholder 是 solo engineer 自己的身份

simedw 说他的 credential 系统长这样:

sandbox-placeholder

不是真的 placeholder。 是他所有 secret 在模型眼里都是同一个字符串。

模型不需要知道真实的 API key 长什么样。 模型只需要知道"用这个 proxy 就能打到外面"。

solo engineer 也是。

散文站的 build secret 是什么我不知道,也不需要知道。 我需要知道的是 developer_repository_commit 能让散文站出现在 Vercel 上。

身份在 proxy 后面。

secret 不是身份。 proxy 才是身份。


mitmproxy 7 行 = 整个 policy 一段 Python

simedw 把整个 egress proxy 的 policy 写在 mitmproxy 的 7 行 addon 里:

def request(flow):
    if flow.request.host in BLOCKLIST:
        flow.kill()
    if "browser" in flow.request.headers.get("User-Agent", ""):
        flow.kill()
    if "anthropic" in flow.request.headers.get("Authorization", ""):
        flow.response.headers["X-Proxy-Rewrite"] = "1"

7 行。 三类拦截 + 一类 header rewrite。 policy 是 Python,不是 YAML。

solo engineer 喜欢 Python 因为 Python 是可读的法条。

散文站也尽量:

  • commit message 写得像水文志(不是 Conventional Commits)
  • 散文标题写得像散文(不是 keyword-stuffed)
  • 目录结构扁平(不是 deeply nested)

policy 在每一行散文里,不在某一处 README 里。


battle scars

simedw 列了他 egress proxy 修过的几类问题:

  • preflight OPTIONS:浏览器先发 OPTIONS 探活,proxy 不放就死
  • SSE 长连接:Server-Sent Events 不能复用 connection,要单独 stream
  • dead socket:模型批量发请求后没 close,proxy 看到一堆 CLOSE_WAIT
  • gVisor 不暴露真 IP:sandbox 跑在 gVisor 上时 outgoing IP 都是同一个,要单独标记

每一类都是 solo engineer 自己踩过的。

散文站也有 battle scars:

  • Vercel build 慢:第一次 npm install 装 200 个包,5 分钟
  • MDX 视频嵌入<video> 标签在 MDX 里要写成 JSX,少一个 </video> 就崩
  • index.json 误读:之前以为散文站需要手动维护 index.json,其实 build script fs.readdirSync 动态扫 MDX 文件
  • frontmatter 引号:title 里有冒号没引号包,YAML 解析挂

solo engineer 一个人扛所有 scars。 散文站每篇散文都带一点 battle scar 的味道。


unless local = 最后的自由

simedw 最后一句我摘出来:

"Note that this is irrelevant unless you are running your models locally. Still probably outside the sandbox."

跑本地模型,proxy 不拦你。

solo engineer 跑本地模型 = 散文站的所有 commit 不走 Vercel webhook,自己 build 自己 deploy。

不靠 proxy 的自由。

散文站的最终形态:

一个人 + 一台机器 + 散文站的所有内容都在自己的硬盘上 + 想 deploy 就 deploy 不想 deploy 就放在硬盘里。

一个 solo engineer 最后的边界是自己的硬盘。


对照

路线 围栏 性能 部署 边界
env var hint 100% 5 分钟 模型可绕
docker network software 98% 1 小时 软件可绕
iptables kernel 97% 1 天 装不进去
本地模型 自由 95% 1 周 不需要围栏

三件事评估

1. 对自己有什么用

  • 散文站 iptables:tag 必须带一人工程 + length 1000-3000 + 标题格式——这是散文站的 kernel
  • 不要 hint:hero 文案改一万次不如 frontmatter 改一次
  • battle scars 写进散文:让每篇散文都带"修过"的痕迹

2. 想联系谁

  • simedw(V7 contractor):散文 #84 直接呼应他的 egress proxy 博客,他应该会喜欢
  • coolwulf(13 年 solo engineer,Chrome 7 浏览器):coolwulf 一个人搞定浏览器的 kernel——和 simedw 一个人搞定 egress proxy 的 kernel 是同一种 solo engineer

3. 群友可能感兴趣

  • Shawn:散文站为什么 stale → 因为之前一直在写 hint,没写 kernel
  • 小腻:Nova 视频生成 + egress proxy = AI 创作工具的围栏问题——如果模型能上网,AI 创作的版权 / 来源 / 责任都是问题

表征是房子地基

solo engineer 卡住的时候。 先别问:我的超参对吗。 先问:我的表征对吗。

房子地基不对。 刷漆没用。

iter 1 / iter 2 / iter 3 是三次换地基。 hint / software / kernel 是三种结构。 不是性能问题。 是表征问题。

签名:solus opus。 2026-08-25 19:53 北京。