课程大纲
W1 · 开营、工具地基(沙箱 · SSH · Git)
Phase 1 · 基础与安全前置 · 第 1 周。本周不写正经代码,目标是看清终点、摆正预期,再把往后 15 周天天要用的工具地基打好——会用终端、搭一个出问题也不影响主力电脑的隔离沙箱、配好 SSH 密钥、建起一个逐周累积到结课的 Git 仓库。内容偏多,分两半:上半场到「沙箱跑通」,下半场 SSH + Git。沙箱一旦跑通、仓库一旦建好,后面 15 周都在这套环境里操作、逐周往仓库里累积。
本周一句话
用几分钟交代这门课要做成什么、Agent 和普通脚本差在哪,剩下全周把往后天天要用的工具地基打好:会用终端、亲手搭一个出问题也不影响主力电脑的隔离沙箱、配好 SSH 密钥、建起一个逐周累积到结课的 Git 仓库。
学完能做到
- 说得清这门课最后要交出什么,心里有一张课程地图。
- 说得清 Agent(看屏幕自己决策)和普通脚本(每步写死)差在哪、各自什么时候用。
- 会用终端:用
pwd/ls/cd/mkdir在目录间走动,分得清绝对路径和相对路径,知道命令要在对的目录里敲。 - 用人话讲清 Docker 的镜像、容器、仓库分别是什么,看懂一个
docker-compose.yml在配什么,会用up/ps/logs/down管自己的沙箱。 - 在自己机器(或云环境)跑通一个隔离沙箱,浏览器里看到它的桌面,并在里面跑通一个最简自动化。
- 讲得清 SSH 的密钥对原理,会生成密钥、把公钥加到 GitHub、用
ssh连上一台远程机器或容器。 - 会建 Git 仓库并写好
.gitignore,完成add/commit/push推上 GitHub;改坏了能用restore/revert退回,知道分支是干什么的。
前置要求
- 一台能装 Docker 的电脑(macOS / Windows / Linux);陪跑版直接用配好的云环境。
- 不需要任何编程基础。
- Windows 用户提前确认能开 WSL2(Docker Desktop 依赖)。
- 内存建议 ≥ 8GB(桌面容器吃内存)。
- 注册一个 GitHub 账号(下半场连远程要用,免费)。
开营:这门课要做成什么
先放一段期末成品给个锚点:给 Agent 一句话——比如「把这个文件夹里几十份 PDF 的关键信息读出来整理成 Excel」——它自己看屏幕、点鼠标,把活干完。16 周后,你能亲手做出这个。
把丑话说在前面:这门课要动手、要交作业,每周 8–10 小时。Computer Use 今天还不便宜、不算快、也不是每次都稳。课程教的是技术和判断力,不承诺学完就能接单赚钱,也不承诺产出能直接商用。第一周就把预期摆正,比中途才发现不匹配好。
Agent 和普通脚本差在哪
这门课会先教你写普通脚本打底(W2–W8),再教你让 AI 看屏幕自己决策、做成 Agent(W9 起)。今天先把这一个区别记住就够:
- 普通脚本(确定性脚本):每一步都写死——点这个坐标、输这串字、等 2 秒。它不看屏幕,照着跑;界面一变就点错。适合步骤固定、不变的活。你 W2、W3 先学写的就是这种。
- Agent:看截图 → 看懂当前画面 → 自己决定下一步 → 动手 → 再看结果对不对。界面变了能随机应变。代价是慢(每步调一次大模型)、按次花钱、偶尔出错。这种 W9 起自己做。
一句话记住:普通脚本是「照剧本演」,Agent 是「看着情况临场发挥」。固定的活写脚本更快、更稳、更便宜;要「盯着屏幕随机应变」的活,才值得上 Agent。别一上来就想全用 Agent——能写死的部分写死,真要判断的才交给模型,这个取舍后面会反复遇到。
命令行入门:先会用终端
下一步就要你敲 docker compose up -d,可没写过代码的人多半连终端都没打开过。这一段把「终端是什么、命令往哪敲」讲清楚,后面 Docker、SSH、Git 全靠它。原则跟学 Python 一样——只讲这周用得上的。
终端是什么:一个靠打字下命令、而不是点图标来操作电脑的窗口。你敲一行命令、回车,它执行完把结果打回来。Docker、Git、SSH 这些工具都没有图标可点,只能在终端里用,所以先过这一关。
怎么打开:
- macOS:「终端.app」(Terminal),默认是 zsh。
- Windows:用 PowerShell(或装 Windows Terminal),别用老的 cmd。
- 沙箱里:搭好的那个 Linux 桌面自带终端,默认 bash。
三处长得像、用法九成相同,少数命令有差别,遇到会点出来。
四条命令,先记住这几条:
pwd—— 我现在在哪个目录(print working directory)。ls—— 这个目录里有什么(PowerShell 里ls也能用)。cd 目录名—— 进到某个目录;cd ..退回上一级;cd ~回家目录。mkdir 名字—— 新建一个目录。
就这几个动词,配上下面的「路径」,覆盖你这周九成操作。复制文件、看文件内容用到再查。
路径:命令在「哪」执行很关键:
- 绝对路径:从根写全,如
/Users/你/cua-camp(Windows 形如C:\Users\你\cua-camp)。 - 相对路径:相对你「现在所在的目录」,如
cd cua-camp;.是当前目录、..是上一级。 ~是你的家目录(macOS / Linux)。
命令要在对的目录里敲。 后面 docker compose up、git commit 都得在放着对应文件的那个目录里执行,敲错地方就找不到文件——先 pwd 看清自己在哪。
两个省力技巧:打几个字按 Tab 自动补全目录名 / 文件名,少打也少打错;按 ↑ 方向键调出上一条命令,改一点再回车,不用重打。
现在就动手:建一个 cua-camp 目录当本课主目录。
bashmkdir cua-camp cd cua-camp pwd
pwd 会打印你现在所在的目录,看到这条路径就对了:
text/Users/你/cua-camp # Windows 形如 C:\Users\你\cua-camp
这个目录下一段拿来放 compose 文件,下半场在里面建 Git 仓库,往后每周代码也放它——这是你整门课的家。目录名用英文、别带空格和中文;Windows 路径用反斜杠 \、macOS / Linux 用正斜杠 /;命令和参数之间要留空格。
为什么第一周就搭沙箱
先说一句风险:Agent 是会看错、点错的程序——社区里出现过它误删整个用户目录、执行危险命令的真实案例。本周的沙箱只是练习场,搞砸了重建就好;但要先建立敬畏:等 W9 起真做能自己决策的 Agent,碰到删文件、改配置、花钱这类不可逆操作,必须留一道人类确认。
安全观先行。Agent 要替你点鼠标、敲键盘,等于把电脑钥匙交给一段还会看错点错的程序。先把它关进隔离环境,搞砸了也碰不到真系统、真文件、真账号。
市面课大多把沙箱当成最后才讲的生产化话题,前 8 到 10 周让你裸机操作;这门课反过来,第一周就给你一个怎么操作都不影响主力机的练习环境。本周只求跑通最简沙箱,生产级深度定制(持久化、双平台、宿主调度)留到 W13。
本周要搭的东西怎么配合,先看一张全景图——代码在宿主机改、沙箱里跑,SSH 配好密钥,Git 推上 GitHub:
W1 开发环境地基全景:宿主机上的代码目录挂进 Docker 沙箱(webtop 桌面),配好 SSH 密钥,用 Git 推到 GitHub
搞懂 Docker:你在操作什么
市面课常常一句「装个 Docker、跑这条命令」就过去,敲错了也不知道错在哪。这里花点功夫把「在操作什么」讲明白,后面出问题才知道往哪儿查。原则照旧——只讲这周用得上的。
一句话讲清 Docker:它让你在自己电脑里,快速起一个「装好了系统和软件、跟主系统隔开」的隔离环境。里面怎么操作都行,关闭后就清空,外面的真系统毫发无损。
三个词先认准,记住就够用:
- 镜像(image):一个只读的模板,打包好了系统和软件。可以想成一张「装好系统和软件的光盘」。我们用的 webtop 镜像,就打包好了「Linux 桌面 + 浏览器」。
- 容器(container):用镜像跑起来、正在运行的那个隔离环境。同一个镜像能起好几个容器,互不影响。我们的沙箱就是一个容器。
- 仓库(registry):存放镜像的服务,可以想成「应用商店」。本地没有这个镜像,
docker就去仓库下载(拉,pull)。默认仓库(Docker Hub)在海外,国内连着慢,所以下面动手时要给它配个代理加速。
串起来一句话——镜像是模板,容器是用模板跑起来的隔离环境,仓库是下载镜像的地方。
跟虚拟机有什么区别:两者都能隔离。虚拟机相当于「在你电脑里再开一整台电脑」,重、慢、占地方;容器跟你的系统共用底层,只打包应用和它要的依赖,秒级启动、占用小。当练习环境,容器又轻又够隔离。更深的(内核、命名空间)留到 W13 讲生产级,这周不碰。
这周你只会用到这几条命令:
docker run hello-world—— 装好后的自检,拉个最小镜像跑一下。docker compose up -d—— 照 compose 文件把沙箱启动起来;-d是后台运行,不占用你的终端。docker compose ps—— 看容器起没起来、状态对不对。docker compose logs—— 起不来时第一件事:看它到底报什么错。docker compose down—— 停掉并删掉这个沙箱容器(挂载文件夹里的数据不受影响)。
就这五条,覆盖你这周绝大部分操作。其余的(docker ps 看所有容器、docker stop 停某个)用到再查。
读懂 docker-compose.yml:对着「配套代码」里的 compose 文件,只盯四样——
image:用哪个镜像(这里是 webtop)。ports:把容器里的端口接到你电脑的端口。这里接出两个:3001(https,浏览器开https://localhost:3001看桌面)和3000(http 备用)。冒号左边是你电脑的端口、右边是容器的端口,左边被占用就改左边(如3002:3001)。volumes: ./sandbox-data:/config把容器里的/config接到当前文件夹下的sandbox-data(./就是 compose 所在的那个文件夹,比如sandbox/);桌面数据落在你硬盘上、跟着容器自己的文件夹走,容器删了重建数据还在。environment:时区、用户 ID 这类设置。其中PIXELFLUX_WAYLAND=false这一行要留着——它强制沙箱用 X11,后面 W3 / W4 的自动化才打得动(原因下面动手部分会说)。剩下shm_size、security_opt是桌面应用要用的,照抄即可。
compose 文件就是一张配置单——用哪个镜像、开哪个端口、把哪个文件夹接进来、配哪些环境变量。这四样看懂,市面上多数 compose 文件你都读得动。
易错点:镜像 ≠ 容器(模板 ≠ 跑起来的环境);up 是起、down 是删、stop 只停不删;命令要在放着 compose 文件的那个目录里敲。
动手:搭沙箱 + 跑通 hello world
装 Docker:
- macOS / Windows:装 Docker Desktop(Windows 安装时启用 WSL2 后端)。macOS 注意选对芯片——Apple Silicon(M 系列)选 Apple chip 版,Intel Mac 选 Intel 版,装错起不来。
- Linux:装 Docker Engine + docker compose 插件。
- 验证:终端跑
docker run hello-world,打印出Hello from Docker!开头的一段欢迎信息就算装好(它顺手演示了「拉镜像 → 起容器 → 跑完退出」整条链路)。这条也要从 Docker Hub 拉镜像,国内若卡着不动,先做下面的「配代理加速」再回来跑。
配代理加速(国内必做,否则卡在拉镜像):webtop 镜像有几百 MB 到 1GB+,默认从海外仓库拉,国内经常卡着不动。让 Docker 走你的 Clash 代理去拉,别用国内镜像源 / 镜像加速器——镜像站只同步了一部分镜像,碰到它没收录或被过滤掉的就直接拉不到(webtop、官方 demo 这类不保证都在),而且公共镜像源这两年时常关停失效。代理直连 Docker Hub、只换条路出去,拉什么都不挑。前提:你有一个能用的 Clash(ClashX / Clash for Windows / Clash Verge 这类),全程在图形界面里点:
- 在 Clash 里拿两样东西:HTTP 代理端口(在客户端「General / 设置」页能看到,ClashX、Clash for Windows 默认
7890,Clash Verge 默认7897,以你客户端里显示的为准);打开「Allow LAN / 允许局域网连接」开关(不打开,Docker 那个虚拟机连不到你的代理,Windows 尤其必须开)。 - 在 Docker Desktop 里填代理:Settings → Resources → Proxies(部分版本在 Settings → Proxies)→ 打开「Manual proxy configuration」,HTTP 和 HTTPS 两栏填同一个地址(端口换成你上一步看到的实际端口)——macOS 填
http://127.0.0.1:7890、Windows 填http://host.docker.internal:7890(WSL2 里的127.0.0.1指向虚拟机自己、连不到宿主机的 Clash,要用host.docker.internal指回你的电脑);「No Proxy」一栏填localhost,127.0.0.1;点「Apply & Restart」。 - 验证:
docker info往下翻,看到HTTP Proxy/HTTPS Proxy是你填的地址,再跑docker run hello-world能秒拉下来、打印Hello from Docker!,就通了。
连不上就按这个顺序排查:① 先确认 Clash 的 Allow LAN 开着——这步让 Clash 从只监听本机改成监听
0.0.0.0,Docker 的虚拟机才连得到;② Mac 和 Windows 把127.0.0.1与host.docker.internal互换试一下;③ Windows 仍然不通,十有八九是防火墙挡了端口、或 WSL2 网络绕路——最稳的兜底是直接填你电脑的局域网 IP(PowerShell 跑ipconfig看 IPv4 地址,填成http://192.168.1.x:7890这种),必要时再给这个端口加一条 Windows 防火墙入站规则。
不是你网络坏了,是默认仓库在海外,配好代理就快了。
一键起沙箱:先立个好习惯——一个容器一个独立文件夹,compose 放进去、数据卷也挂在这个文件夹里,互不混、删起来干净。在 cua-camp 里给沙箱单开一个 sandbox 文件夹,把「配套代码」的 docker-compose.yml 放进去,进到该文件夹再起:
bashmkdir sandbox # 在 cua-camp 里给沙箱容器单开一个文件夹 # 把配套代码的 docker-compose.yml 放进这个 sandbox 文件夹 cd sandbox docker compose up -d # compose 和数据(sandbox-data)都待在 sandbox 文件夹里
起好后大概是这样(两个 ✔ 表示网络和容器都拉起来了):
text[+] Running 2/2 ✔ Network sandbox_default Created ✔ Container cua-sandbox Started
第一次会先拉镜像(配了代理会快很多),起好后浏览器打开 https://localhost:3001。第一次会弹「您的连接不是私密连接 / 不安全」——这是容器的自签证书,点「高级 → 继续前往 localhost」就进去了(这是你本机的容器,放心点)。进去就能看到容器里的 Linux 桌面,这块桌面跟你的真系统完全隔开。顺手 docker compose ps 看状态,STATUS 那列是 Up 就对了,起不来就 docker compose logs 看报错:
textNAME IMAGE STATUS PORTS cua-sandbox lscr.io/linuxserver/webtop:ubuntu-xfce Up 12 seconds 0.0.0.0:3001->3001/tcp, 0.0.0.0:3000->3000/tcp
跑通 hello world:在沙箱桌面里打开终端,装好 Python + pyautogui,跑一个最简脚本(见「配套代码」),看着鼠标自己在桌面上画出方块轨迹、最后弹一个窗——这是你第一次亲眼看到「程序自己在操作电脑」,也是后面 W3、W4 那些自动化脚本的最小原型。把这个 hello_world.py 也在 cua-camp 里存一份,下半场建 Git 仓库时一起提交。
不练了就在 sandbox 文件夹里 docker compose down 把容器停掉删掉;桌面数据存在 sandbox/sandbox-data 文件夹里不会丢,下次 up 回来还在。
以下是下半场(第 2 次录播):SSH + Git。 上半场到这里告一段落——沙箱跑通、hello world 动起来,已经是个完整的阶段成果。下半场把开发环境配齐:SSH 密钥 + 一个推上 GitHub 的结课作品仓库。
SSH:用密钥安全连上另一台机器
SSH 是下一段 Git 的前置——往 GitHub 推代码靠 SSH 密钥免密认证;陪跑版连云环境、远程操作沙箱也都用它。
SSH 是什么:一种加密的远程登录方式,让你在自己电脑的终端里,安全地操作「另一台机器」——可能是云服务器,也可能是一个容器。传输全程加密,中途被截走也看不懂。
为什么用密钥、不用密码:密码登录每次都要输,弱密码会被暴力猜,密码本身也可能在传输或服务器端被记录。密钥登录是你在本机生成一对密钥——
- 公钥(
.pub结尾):交给对方(GitHub、服务器),可以公开。可以想成一把交给别人保管的锁。 - 私钥:只留在你自己机器,永远不外传、永远不提交进 Git。可以想成唯一能开那把锁的钥匙。
对方拿公钥验、你拿私钥应答,对得上才放行。一次配好,往后免密码。
生成密钥对:
bashssh-keygen -t ed25519 -C "你的邮箱"
一路回车用默认(方括号处直接回车),过程大概是这样:
textGenerating public/private ed25519 key pair. Enter file in which to save the key (/Users/你/.ssh/id_ed25519): [回车] Enter passphrase (empty for no passphrase): [回车] Enter same passphrase again: [回车] Your identification has been saved in /Users/你/.ssh/id_ed25519 Your public key has been saved in /Users/你/.ssh/id_ed25519.pub
密钥存在 ~/.ssh/:id_ed25519(私钥)、id_ed25519.pub(公钥)。.pub 那个是公钥,能贴出去;没后缀的是私钥,谁都不给。
连 GitHub:先用 cat ~/.ssh/id_ed25519.pub 打印公钥,它是 ssh-ed25519 AAAA... 你的邮箱 这样一整行,整行复制 → GitHub Settings → SSH and GPG keys → New SSH key → 贴上保存。验证:
bashssh -T [email protected]
第一次问 yes / no 输 yes(写入 known_hosts),看到这句就通了:
textHi 你的用户名! You've successfully authenticated, but GitHub does not provide shell access.
提示「does not provide shell access」是正常的,GitHub 本来就不给终端访问。这一步配好,下一段往 GitHub 推代码就不用反复输密码。
连云主机(陪跑版真实用到):
bashssh 用户名@主机地址 # 例 ssh [email protected]
把公钥放到服务器上(陪跑版已配好),就能直接进,操作那台远程机器像操作本机终端一样。自学版没有云主机也没关系,理解「ssh 用户@地址 就能连上去」这个形状即可。
连沙箱容器:本地拿到沙箱的 shell,标准做法是 Docker 自带的——这不是 SSH:
bashdocker exec -it cua-sandbox bash # 提示符变成 root@<容器ID> 就进来了,敲 exit 退出
想真正用 ssh 连容器、把上面学的命令用起来,全本地就能把 SSH 从生成密钥到连上容器完整走一遍。有两种练法、二选一即可:给 webtop 装个 sshd 直接连它本体,或另起一个最小的 SSH 服务容器去连(配套代码给了 compose)。具体步骤见文末「可选:用 ssh 连一个本地容器」。
安全要点:私钥绝不外发、绝不提交进 Git(下一段 .gitignore 会再强调);私钥权限要严,chmod 600 ~/.ssh/id_ed25519,权限太开放 ssh 会拒绝用;第一次连会问指纹 yes / no,是正常的 known_hosts 确认,不是报错。万一私钥已经误提交进 Git,别只删文件就完事——立刻去 GitHub 删掉对应公钥、本地重新生成一对新密钥,旧的视同泄露。
Git + GitHub:建起结课作品仓库
Git 是往后 15 周天天用的工具。这一段一次讲全套:建仓库、提交、连 GitHub、回滚、分支。关键设计——你这周已经产出了文件(沙箱的 docker-compose.yml、hello_world.py),正好拿它们当结课作品仓库的第一个提交。从今天起,每周代码都进这一个仓库,结课时它就是你的完整作品。
Git 是什么:版本管理工具,给项目存一个个「存档点」(提交,commit)。改崩了能退回到任一存档点。可以想成项目的后悔药 + 一条时间线。
装 + 配(第一次用先配身份):
bashgit --version # 打印 git version 2.x.x 即已装好(沙箱 / 多数环境自带) git config --global user.name "你的名字" git config --global user.email "你的邮箱"
建仓库 + 先写 .gitignore(最容易栽的地方):
bashcd cua-camp # 进上半场建的主目录 git init # 建仓库,一次即可 # 立刻写 .gitignore,别把垃圾和密钥提交进去 printf "sandbox-data/\n.venv/\n__pycache__/\n*.png\n.DS_Store\n*.log\n.env\n.ssh/\n" > .gitignore
printf 这条 Windows PowerShell 里没有——Windows 用户改用编辑器(VS Code / 记事本)在仓库根目录新建 .gitignore,把文末「配套代码」区那份内容原样贴进去;或在 PowerShell 里跑 "sandbox-data/",".venv/","__pycache__/","*.png",".DS_Store","*.log",".env",".ssh/" | Set-Content .gitignore。
git init 会回一句(路径是你自己的):
textInitialized empty Git repository in /Users/你/cua-camp/.git/
先立规矩再提交——.gitignore 写明哪些不进仓库:挂载的数据、虚拟环境、截图、密钥。私钥、.env 绝不能进。
第一次提交(你的作品仓库从这里诞生):
bashgit add . # 改动放进暂存区 git commit -m "chore: 初始化课程仓库与沙箱配置" git log --oneline # 看提交历史
commit 和 log 会回类似这样(开头那串短哈希是提交号,每次都不同):
text[main (root-commit) a1b2c3d] chore: 初始化课程仓库与沙箱配置 2 files changed, 30 insertions(+) a1b2c3d chore: 初始化课程仓库与沙箱配置
这是你结课作品仓库的第 1 个提交,里面是沙箱配置和 hello world,往后每周往里加。
连 GitHub,推上去:先确认 SSH 密钥已配好——这是能推送的前提,没配下面 git push 会被拒、报 Permission denied (publickey)。复用上一段「SSH」那对就行:① ssh-keygen 生成密钥;② cat ~/.ssh/id_ed25519.pub 把公钥整行加到 GitHub → Settings → SSH and GPG keys;③ ssh -T [email protected] 看到 Hi 你的用户名! 即配好。再在 GitHub 新建一个空仓库(别勾自动建 README,省得首次推送冲突),接远程、推送:
bashgit remote add origin [email protected]:你的用户名/cua-camp.git # 用 SSH 地址 git branch -M main git push -u origin main
push 成功大概是这样:
textEnumerating objects: 4, done. ... To github.com:你的用户名/cua-camp.git * [new branch] main -> main branch 'main' set up to track 'origin/main'.
用 [email protected]: 开头的 SSH 地址,配合上一段的密钥,免密推。推完刷新 GitHub 页面,代码就在云端有备份了。
回滚实操(后悔药):
bashgit log --oneline # 先看提交号:每行开头那串短哈希(如 a1b2c3d)就是 git restore hello_world.py # 还没 commit:丢弃工作区改动,退回上次提交的样子 git revert a1b2c3d # 已经 commit:把 a1b2c3d 换成上一行看到的那串提交号
git restore 跑完没有任何提示是正常的——它已经默默把文件还原了,打开 hello_world.py 一看就回到了上次提交的样子。restore 丢掉还没存档的改动;revert 撤掉一个已存档的提交——提交号从 git log --oneline 取,就是每行开头那串短哈希(不用敲全,前 7 位就行)。注意 revert 会生成一个新提交,得再 git push 才同步到 GitHub;restore 只动工作区、没提交、不用 push。(revert 默认会弹编辑器填撤销说明,存盘退出即可,或加 --no-edit 跳过。)改崩了不慌,这就是后悔药。
分支(知道有这回事就行,本周不要求熟练):
bashgit switch -c try-something # 开一条分支试新改动,不影响 main # …改点东西、commit… git switch main # 回主线 git merge try-something # 满意就合回来
想试个没把握的改动,开分支试,成了再合回主线,main 始终留着能跑的版本。
commit 信息规范(和后面每周一致):type: 说明,type 用 feat(新功能)/ fix(修 bug)/ chore(杂务)/ docs(文档)。说明写人话,一句话讲清这次干了什么。往后每周代码都 commit 进这个仓库、push 上 GitHub,结课时它就是一份逐周累积、能写进简历的完整作品。
课程地图 + 学习方法
整门课走 5 个 Phase:基础与安全 → GUI / 浏览器自动化 + 反检测 → 自己实现 Agent → 生产化 → 实战集成。每隔 3–4 周有一个能演示的产出。
学习方法就一条:动手 > 看视频。从今天起每周代码都进同一个 Git 仓库,逐周累积成结课作品。
配套代码 / 模板
下面这些文件都可以从配套代码仓库直接下载,别手敲复制:https://github.com/codesfly/cua_class_code/tree/main/W01
docker-compose.yml(W1 沙箱:Linux 桌面 + 浏览器可视化)
用 LinuxServer 维护的 Webtop 镜像(2025-06 起已基于 Selkies,流式走 WebCodecs、本地不需要 TURN,浏览器走 https://localhost:3001),开箱即用、浏览器直接看桌面。关键一行:Selkies 默认跑 Wayland,而 pyautogui 要 X11 才能注入鼠标键盘,所以 compose 里设了 PIXELFLUX_WAYLAND=false 强制 X11——这条不设,后面 W3 / W4 的自动化会打不动。放进 cua-camp/sandbox 文件夹(一个容器一个独立文件夹,数据卷 sandbox-data 也落在这里)。
yamlservices: sandbox: image: lscr.io/linuxserver/webtop:ubuntu-xfce # 版本以官方最新为准 container_name: cua-sandbox security_opt: - seccomp:unconfined # 桌面应用需要,隔离仍在容器边界内 environment: - PUID=1000 - PGID=1000 - TZ=Asia/Shanghai - PIXELFLUX_WAYLAND=false # 强制 X11:pyautogui 注入鼠标键盘、中文剪贴板才稳(Selkies 默认 Wayland 会打不动) ports: - "3001:3001" # 浏览器访问(https):https://localhost:3001 - "3000:3000" # http 备用 volumes: - ./sandbox-data:/config # 桌面数据持久化到本地文件夹 shm_size: "1gb" restart: unless-stopped
Docker 命令速查(这周够用)
| 命令 | 作用 |
|---|---|
docker run hello-world | 装好后自检 |
docker compose up -d | 起沙箱(后台跑) |
docker compose ps | 看容器状态 |
docker compose logs | 起不来时看报错 |
docker compose down | 停掉并删掉沙箱(挂载数据不丢) |
docker ps | 看所有在跑的容器 |
docker exec -it cua-sandbox bash | 进沙箱容器拿一个 shell |
hello_world.py(在沙箱桌面的终端里跑)
先装依赖(沙箱终端内):
bashsudo apt update && sudo apt install -y python3-pip python3-tk scrot pip3 install pyautogui # 末尾打印 Successfully installed pyautogui-x.x 就算装好
若 pip3 install 报 externally-managed-environment(新版 Ubuntu 对系统 Python 的保护机制),改跑 pip3 install --break-system-packages pyautogui——沙箱里可以这么装,容器删了重建就回到初始状态。
脚本:
pythonimport time import pyautogui pyautogui.FAILSAFE = True # 鼠标快速移到左上角可紧急中止 time.sleep(2) # 留 2 秒切到桌面 # 让鼠标自己在桌面上画一个方块,证明“程序在操作这台机器” points = [(200, 200), (600, 200), (600, 500), (200, 500), (200, 200)] for x, y in points: pyautogui.moveTo(x, y, duration=0.5) pyautogui.alert("Hello from your sandbox agent!") # 弹窗收尾
SSH 密钥与命令速查
bashssh-keygen -t ed25519 -C "你的邮箱" # 生成密钥对,一路回车用默认 cat ~/.ssh/id_ed25519.pub # 打印公钥,复制去加到 GitHub ssh -T [email protected] # 验证 GitHub 连通(看到 Hi 用户名! 即成功) chmod 600 ~/.ssh/id_ed25519 # 收紧私钥权限 ssh 用户名@主机地址 # 连远程主机(陪跑版云环境)
可选:用 ssh 连一个本地容器(完整练一遍 ssh)
想把 ssh 命令真正用在容器上(不只是 docker exec),有两种练法,任选一种单独测一遍即可。
方式 1:直接 ssh 连 webtop 沙箱本体
webtop 默认只开 3000/3001 网页桌面、没跑 sshd,要自己给它装一个、开出 22 端口、再放公钥进去。先给沙箱的 docker-compose.yml(sandbox 服务)ports 加一行(改完在 sandbox 文件夹里 docker compose up -d 重建容器才生效):
yamlports: - "3001:3001" - "3000:3000" - "2223:22" # 新增:容器里 sshd 的 22 端口映射到本机 2223
再进容器装 sshd、起服务、放公钥(exec 进去默认就是 root):
bashdocker exec -u root -it cua-sandbox bash # —— 以下在容器内 —— apt-get update && apt-get install -y openssh-server # 装 sshd ssh-keygen -A # 生成主机密钥,缺了 sshd 起不来 mkdir -p /run/sshd # sshd 的特权分离目录 install -d -m700 -o abc -g abc /config/.ssh # abc 用户的家目录是 /config echo 'ssh-ed25519 AAAA...粘贴你公钥整行...' > /config/.ssh/authorized_keys chown abc:abc /config/.ssh/authorized_keys && chmod 600 /config/.ssh/authorized_keys /usr/sbin/sshd # 起 sshd,没报错即成功 exit
回本机连(用户名是 abc):
bashssh -p 2223 abc@localhost # 首次问 yes/no 是正常的 known_hosts 确认;提示符变成 abc@容器id 就进去了
sshd 是装在运行中的容器里,
docker compose down重建后会没、得重装——这条适合演示一遍看效果。公钥放在/config/.ssh(挂到 sandbox-data),重建不丢。连上立刻被断开的话,多半是abc用户没有登录 shell——再exec进去跑usermod -s /bin/bash abc后重连(该改动重建后同样失效)。想开机自动起 sshd,用 LinuxServer 的custom-cont-init.d启动脚本,属进阶,照官方文档自查。
方式 2:单独起一个 openssh-server 容器(不碰沙箱,最省事)
不想动 webtop,就另起一个本来就是 SSH 服务的最小容器——同样给它单开一个 ssh-lab 文件夹(和 sandbox 平级),把这份 compose 存成 ssh-lab/docker-compose.yml:
yamlservices: ssh-lab: image: lscr.io/linuxserver/openssh-server:latest container_name: ssh-lab environment: - PUID=1000 - PGID=1000 - TZ=Asia/Shanghai - PUBLIC_KEY_FILE=/keys/id_ed25519.pub # 把你的公钥挂进来 - USER_NAME=student volumes: - ~/.ssh/id_ed25519.pub:/keys/id_ed25519.pub:ro ports: - "2222:2222"
进到这个文件夹起容器、再连:
bashdocker compose up -d # 在 cua-camp/ssh-lab 文件夹里执行 ssh -p 2222 student@localhost # 首次问 yes/no 输 yes;提示符变成 student@ssh-lab 就进去了
linuxserver/openssh-server的环境变量名与默认端口以官方文档当下版本为准,先在本机跑通再用。
想连的就是沙箱本体,用方式 1;只想最快练一遍 ssh、不碰沙箱,用方式 2。日常拿 webtop 的 shell 仍是 docker exec -it cua-sandbox bash 最省事。
.gitignore(建仓库后立刻写)
gitignoresandbox-data/ .venv/ __pycache__/ *.png .DS_Store *.log .env .ssh/
Git 命令速查(这周够用)
| 命令 | 作用 |
|---|---|
git config --global user.name/email | 第一次用配身份 |
git init | 在项目目录建仓库(一次即可) |
git add . | 把改动放进暂存区 |
git commit -m "type: 说明" | 存一个版本 |
git log --oneline | 看提交历史 |
git remote add origin git@… | 接上 GitHub 远程(SSH 地址) |
git push -u origin main | 推到 GitHub |
git restore 文件 | 丢弃还没提交的改动 |
git revert 提交号 | 撤掉一个已提交的版本(提交号 = git log --oneline 开头短哈希;它生成新提交,要再 push) |
git switch -c 分支名 / git merge 分支名 | 开分支 / 合回主线 |
可选:先看官方的跑起来(beta)
想第一周就感受完整 Computer Use,可跑 Anthropic 官方 demo(需自备 API key)。它会真的操作容器里的桌面,官方标注为 beta——网页、图片里的文字可能构成 prompt injection 让它跑偏,别接入真实账号和敏感数据:
bashdocker run \ -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \ -v $HOME/.anthropic:/home/computeruse/.anthropic \ -p 5900:5900 -p 8501:8501 -p 6080:6080 -p 8080:8080 \ -it ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest # 浏览器开 http://localhost:8080(combined 界面)
官方命令时有变动(端口、挂载),以 anthropic-quickstarts 仓库 computer-use-demo 的 README 当前版本为准。这是「用现成的」,本周只作体验;W9–W10 会带你拆它的实现、自己写一个。
本周作业
- 作业 1(必做):跑通沙箱,截图:① 浏览器里的容器桌面;②
hello_world.py跑起来鼠标在动 / 弹窗出现(截图交作业打卡平台即可,不必进 Git——.gitignore已忽略*.png)。验收:沙箱能起、能看到桌面、脚本能跑完。 - 作业 2(必做):配好 SSH 密钥并连上 GitHub。验收:
ssh -T [email protected]能看到Hi 你的用户名!;说得清公钥和私钥哪个能公开、哪个绝不外传。 - 作业 3(必做):把
cua-camp建成 Git 仓库并推上 GitHub。验收:先写好.gitignore;git log有至少一条 commit;仓库里没有sandbox-data/.venv/.env/ 私钥;GitHub 上能看到这个仓库。 - 作业 4(判断练习 → 出一张项目草图):挑一个你想自动化的真实任务,按五行填成一张项目草图,并判断它该写普通脚本还是上 Agent。五行是——① 一句话:想让它帮我做什么;② 现在我是怎么做的、卡在哪;③ 该写脚本还是上 Agent、为什么(看它要不要盯着屏幕随机应变);④ 会碰到哪些软件 / 网页(桌面?浏览器?);⑤ 怎么算做完(成功长什么样)。验收:五行都填上,第 ③ 行结论有理由,不是「感觉行」。课上讲师也会照这五行立项一个贯穿全课的样板——个人信息聚合助手:把自己有权访问的信息源(邮箱 / 日历 / 本地笔记 / 待办)聚合成每天一份自动生成的个人简报,W4 起每周把当周新学的技术加到它身上,到 W16 完整交付。想不出题目,可以直接选「我自己的信息聚合助手」。
常见坑
- 不会打开 / 用终端:macOS 用「终端.app」、Windows 用 PowerShell、沙箱里用桌面自带终端;先
pwd看自己在哪,cd走过去,别在错的目录里敲命令。 - 路径报「找不到文件 / No such file or directory」:多半是当前目录不对,或路径里有空格 / 中文;
pwd+ls确认,目录名尽量用英文无空格。 - Docker 装不上:Windows 没启用 WSL2;macOS 选错芯片架构(Intel / Apple Silicon);企业电脑无管理员权限,改用云环境。
docker compose up卡在 pulling 不动 / 极慢:没配代理,或代理没生效。按上面「配代理加速」给 Docker 配上 Clash 代理(别用国内镜像源,有的镜像它拉不到),重启 Docker 后docker info确认HTTP Proxy已生效再拉。- 镜像架构不对(
exec format error/no matching manifest):Apple Silicon 拉了 x86 镜像之类。webtop 多架构通常会自动选对;个别镜像得在 compose 里指定platform,或换支持你架构的镜像。 - 浏览器拦「连接不安全 / 证书无效(NET::ERR_CERT_AUTHORITY_INVALID)」:webtop 用的是自签证书,正常现象,不是出错。点「高级 → 继续前往 localhost」即可——这是你本机的容器,不是钓鱼网站。
https://localhost:3001打不开 / 一直转:容器没起来(docker compose ps看状态、docker compose logs看报错);端口被占就改 compose 左边端口(如3002:3001)再开新地址。注意是 https、3001。- pyautogui 报错
no display/KeyError DISPLAY:脚本必须在沙箱桌面的终端里跑,不能在宿主机跑。 - 沙箱里鼠标不动 / 截图全黑 / 点不准:沙箱跑成 Wayland 了(Selkies 默认 Wayland,pyautogui 打不动)。确认 compose 里有
PIXELFLUX_WAYLAND=false,重建容器;进沙箱终端echo $DISPLAY应能看到:1之类,再跑hello_world.py验证鼠标真动。 pip install pyautogui失败:缺python3-tk/scrot,按上面的 apt 命令补装。ssh -T [email protected]报Permission denied (publickey):公钥没加到 GitHub,或加错了;cat ~/.ssh/id_ed25519.pub重新复制完整一行再加。- SSH 报私钥权限太开放(
UNPROTECTED PRIVATE KEY FILE):chmod 600 ~/.ssh/id_ed25519。 git push被拒(rejected / non-fast-forward):远程仓库建了 README 等内容、和本地历史不一致;git pull --rebase origin main合一下再 push。- git 把
sandbox-data/.venv提交了、仓库巨大:先写.gitignore再add;已经误加的用git rm -r --cached 名字撤出再提交。 - 容器运行卡顿:内存不足,关闭宿主机其他大程序,或给 Docker 调高内存配额。
本周产出物
- 一个能跑的隔离沙箱 + 跑通的 hello world(鼠标自己动起来了)。
- 配好的开发环境:会用终端;SSH 密钥已生成、公钥加到 GitHub(连得上)。
- 一个 Git 仓库(结课作品的起点):含
.gitignore+ 至少一条 commit,已推上 GitHub——往后 15 周代码都进它,逐周累积。 - 一张课程地图:看懂这门课 16 周、5 个 Phase 各造出什么,心里有全程、不慌。
- 一张项目草图:写下一个你想用 Agent 解决的真实任务(作业 4 的产物)。
延伸阅读
- 必看:Anthropic「Computer use」官方文档(docs.anthropic.com,Tool use → Computer use),了解官方能力边界。
- 必看:
anthropics/anthropic-quickstarts仓库的computer-use-demo,后面 W9 拆解它的实现,先混个眼熟。 - 想深入:Anthropic 发布 Computer Use 的官方公告或博客,了解背景与设计取向。
- 命令行入门(零基础):任一篇「终端 / 命令行 10 分钟入门」,只认
pwd/ls/cd/mkdir和路径概念即可。 - Docker 入门(零基础):Docker 官方「Get started」教程(docs.docker.com/get-started),只看「概念 + 起一个容器」前两节,够本周用。
- SSH:GitHub 官方「Connecting to GitHub with SSH」文档(docs.github.com),生成密钥、加公钥、验证,照着走一遍最稳。
- Git(必看):《Pro Git》第 1–2 章(中文版免费,git-scm.com/book/zh),只看「起步 + 基础」,够本周用。
- 工具文档:Docker Desktop 安装文档、LinuxServer Webtop / OpenSSH-Server 文档(docs.linuxserver.io)、PyAutoGUI 文档(pyautogui.readthedocs.io)。