自主公司消息分流层(DeepSeek 分流→看板;已弃 VM,含可复用眼睛)#2
Open
yangchunxuan wants to merge 41 commits into
Open
Conversation
依据 OpenAI《Harness engineering》给 macos_agent 加一层治理设施的规格书 (给 Codex/Gemini 实现,Claude 按 §7 逐条审): - 支柱 B:tools/lint_invariants.py 把 12 条架构不变量做成机械 lint,报错内嵌修复指引 - 支柱 A:AGENTS.md(≤120 行目录)+ docs/ 分层 + lint_knowledge.py(知识库防腐) - 支柱 C:gc_scan.py(黄金原则 GC,🟥🟨🟩 分级,--fix 只动机械安全项) 铁律:只加治理层、不碰 brain/macos/broker 运行行为(A8 大脑零回归); 纯 stdlib+AST;诚实台账不假绿(已知存量违规 brain/agent.py 690 行超上限)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
自主定制游 agent 公司的业务层(建在 macos_agent 引擎之上): - docs/ARCHITECTURE.md:六大流程→岗位 agent 映射 + 系统真相源 + 两层安全 (VM 隔离让敢开操作权限 / 业务闸门守钱与承诺)+ MVP 分阶段 - docs/phase0-system-of-record-spec.md:给 Codex 的第一张工单——把价格库/ 供应商/需求/报价/订单/转化变成结构化 agent 可读数据,边界强校验 (核心护栏:报价每项成本必须来自价格库真实条目,不许编价),纯 stdlib、 不碰 VM/钱/网络。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
自主定制游 agent 公司的数据地基(真跑验证通过): - 8 张表 schema.sql(供应商/价格库/需求/报价+明细/订单/退改政策/转化/定价策略) - models.py 类型化 dataclass + enum;costing.py 确定性成本汇总(非 LLM) - validate.py 6 条边界不变量护栏;db.py 唯一读写入口,写入即校验 - seed.py 示例数据走全校验;cli.py 查询/巡检;tests 11 个反例测试 核心护栏 INV-Q1:报价每项成本必须来自价格库真实条目、单价一致,不许编价。 验证:seed 真跑(报价6000成本+利润20%=7200对客价、40%定金2880); 11 反例测试全过;cli check 巡检 0 违规。纯 stdlib,不碰 VM/钱/网络。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
客服(SDR) agent 核心(离线可测,不依赖 VM/key/SaleSmartly): - 对话 → 抽 8 项基础需求 → 建 Lead → 校验完整性 → 落 company.record - 信息不全 → 标 collecting + 指出缺字段 + 给一句自然追问 - 数据源可插拔(TranscriptSource 现在 / SaleSmartly 适配器待接)、 提取器可注入(默认 LLM 走 DeepSeek+broker / 测试注入假提取器) - 安全:客户消息是不可信数据(提示词写死),隔离靠 agent 跑在 VM 里 验证:5 个测试全过;端到端 demo 对话→qualified Lead→可进报价链路。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
计调(Operations) agent 核心(离线可测,纯读价格库确定性组价): - 拿 qualified Lead + 价格库 → 按「成本×服务」平衡选供应商(非最便宜) → 组报价 - 走 Phase 0 护栏(INV-Q1~Q4)落库,status=pending_review(发客户前人审) - 诚实:价格库查不到的资源不编价 → 报 incomplete_pricebook + 列缺口 验证:4 测过;全公司 20 测全过;端到端 对话→客服→Lead→计调→报价→订单 链路跑通、巡检 0 违规、金额确定性正确。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
数据分析 agent 核心(V2 一·3 转化反馈,离线纯读 funnel 表): - 漏斗统计 咨询→有效→报价→成单 + 成交金额 + 各级转化率 - 按 platform/ad_content/region/campaign_time 维度切转化 - 优化建议:哪个维度加投、哪个收缩 → 反馈前端投放 顺带修 Phase 0 真 bug:funnel_events.lead_id 外键太严(咨询往往还没建 lead, 咨询人数≠lead 数)→ 改可选关联。 验证:4 测过;全公司 24 测全过;demo 转化统计+优化建议正确。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
收款(Collections) agent 核心(V2 四;离线可测): - 按 30/40 定金规则生成收款单 → 对账 → 落地后收尾款 - 金钱状态机守卫:定金未付不能收尾款;两笔都到才 settled - 🔴 §3 业务闸门:agent 绝不自动划钱;真支付页操作=人审的可插拔 PaymentAdapter(requires_human_confirm),confirm_*_paid 代表人已核实到账 - 支付宝/PayPal 真对接是往 adapter 插实现,本核心不含(不投机建支付代码) 验证:4 测过;全公司 28 测全过;端到端 对话→报价→订单→定金→尾款→结清 demo。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
供应商下单(Procurement) agent 核心(V2 报价流程第四阶段 + 退改政策;离线可测): - 从报价明细生成 pending booking → 真下单(confirmed) 守卫「定金已付」+ 人审 - 取消按退改政策分档退款(refund.py 查 refund_policy);没配政策诚实报未配置 - 🔴 §3 闸门:真下单=占库存/产生成本,人审的可插拔 SupplierAdapter - 新增 bookings 表 + refund.py 验证:5 测过;全公司 33 测全过(Phase 0-5 完整业务链核心)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…an gates 总指挥(conductor):把六大流程岗位 agent 串成一条自主运行的流水线。 一条客户对话自动流过 客服→计调→报价→收款→供应商下单→尾款→结清, 只在 4 个人审闸门停下(发报价/定金到账/供应商下单/尾款——碰钱或对外承诺, §3 业务闸门),其余全自动、全程护栏。每步记 funnel,数据分析随时统计。 真实世界触点(SaleSmartly/支付/供应商)是各 agent 的可插拔适配器,本层不关心。 验证:4 测过;全公司 37 测全过;端到端 demo 一条对话自动跑到结清(成交4800元)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
运营控制台——把引擎变成能「启动 + 日常操作」的运行系统: 状态沉在库里,agent 自动把能推的推到人审闸门;运营者(人)在控制台 看待办、逐门点批准,公司往前走。命令:intake/pending/send/deposit/ book/balance/funnel。真实 intake 可走 LLM(BROKER_*)或 SaleSmartly 适配器。 验证:3 测过;全公司 40 测全过;控制台真走一遍 intake→结清、待办清空、漏斗记全。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
自动公司的真入口:Facebook/Instagram → SaleSmartly → webhook POST → 验签 → 归一化 → 客服 agent 抽需求 → 落库成 Lead。入站按 SaleSmartly 官方 webhook 文档做真实现(event/chat_session_id/chat_user_id/sequence_id/msg/msg_type/ channel/send_time + md5 验签);出站 REST 客户端结构真实、精确端点/鉴权头 标 CONFIRM(以 Max 套餐 apifox 文档为准)。 - company/systems/salesmartly.py:parse_webhook / verify_signature / SaleSmartlyInbound(幂等去重、多轮更新同一 Lead)/ SaleSmartlyClient / 可运行 webhook 服务(stdlib http.server,python3 -m company.systems.salesmartly serve) - record/db.py:update_lead(多轮渐次补全)+ Database(check_same_thread)(服务线程安全) - roles/customer_service.py:ingest 支持 lead_id 更新既有 Lead - tests:12 新测(解析/验签/幂等/多轮更新/非文本备档),真 HTTP 冒烟通过 上线只差你两样运行时输入:①SaleSmartly 后台把「新消息」webhook 指到本服务 ②webhook 签名 secret(SS_WEBHOOK_SECRET)。出站自动回复另需 Max API token。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
照 PayPal Invoicing v2 官方契约建真适配器:create_payment_request 建草稿发票 (钱不动)/ send_invoice 发给客户(人审后调)/ check_status 只读查 PAID 对账。 安全立场硬化:**绝不实现 capture/payout/refund 类划钱端点**——钱永远客户在 PayPal 自己付、客户→公司,适配器不经手资金移动。凭证只经环境变量注入,不进代码/VM。 - company/systems/paypal.py:PayPalPaymentAdapter(OAuth client_credentials + Invoicing v2),实现 PaymentAdapter 协议 → 可直插 CollectionAgent;from_env 构造。 可注入 transport → 离线可测,无需真凭证、不碰网络。 - tests:8 新测(请求载荷照契约/分→两位小数/发送端点/只读PAID映射/ 绝不命中划钱端点/直插CollectionAgent 协议对齐)。全套 60 绿。⚠️ 金额币种:库存 CNY 分;发票 value 按 currency 小单位/100,跨币种需上游先换 FX (不猜汇率)。上线只差你:PAYPAL_CLIENT_ID/SECRET(沙箱可先验)+ 币种。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pipeline 拆出 run_from_lead:把「前门(SaleSmartly 入站建好 Lead)」与「后续 计调→报价→收款→下单→尾款→结清」解耦成接续缝(也是真实架构)。run() 委托它, 返回结构不变(既有 60 测全绿)。 新增端到端「接通」集成测试(test_e2e_wired.py): SaleSmartly webhook(真契约) → 客服抽需求 → qualified Lead → 计调按真价格库 (INV-Q1)出报价 → PayPal 开发票(真 Invoicing 契约、金额=gmv*40%定金) → 人审 放行 → 定金/下单/尾款 → 结清 + 记成交;闸门测试证明供应商闸门仍守得住。 外部 HTTP 用可注入假件顶替,其余全真模块真护栏 —— 上线换真凭证即真跑。 全套 62 测绿。这是「整套是一个连起来的自主系统、只差最后一公里凭证」的证据。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
补上 Marketing 段最后两环「数据反馈 + 优化投放」,把 投放→咨询→报价→成交→
数据反馈→优化投放 闭成环。纯读系统已记的 funnel_events,不需你私有数据。
- roles/marketing.py:MarketingAgent
· dimension_funnel:按 平台/地区/投放时间/广告素材 切**全阶段**漏斗
(咨询→有效→报价→成单 + 成交额 + 各段转化率)
· budget_recommendations:结构化可执行建议 SCALE_UP/HOLD/SHRINK/PAUSE;
有花费→按 ROAS/CPA,无花费→按成交转化率(诚实降级,不假装有 ROI)
· reallocation:从最差 ROAS 挪预算到最好 ROAS,给具体数字
· feedback_report:反馈前端的总产物
· 边界:只出建议,绝不真花广告费;真调预算=人审的 AdSpendAdapter(协议留好,
真实现未接=需你广告账号的最后一公里)
- console 加 market 命令;tests 9 新测。全套 71 绿。真跑演示:
facebook ROAS4→SCALE_UP / instagram 4咨询0成交→PAUSE / 调仓挪900元。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
补上你特意强调的「低价引流→二次报价」流程。数据模型早留好了位
(Quote.version / parent_quote_id),这轮把逻辑接通:
- roles/operations.py:
· build_quote 加 version/parent_quote_id 参数
· re_quote(parent_quote_id, plan?, markup?, reason):生成父单**下一版本**并链起;
plan=None 沿用父单行程(只调加价),给新 plan 按调整后行程重算;
走同样护栏(INV-Q1..Q4)、仍 pending_review(发客户前照样人审,不绕闸门);
诚实:二次报价加了没价格库的城市 → 报缺不编价、不建版本
· quote_history:一条 Lead 的报价版本链
- console 加 requote 命令;tests 6 新测(版本链/加价调整/行程调整/护栏保持/诚实报缺)。
全套 77 绿。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
把你逐字给定的对客措辞固化,措辞精确一致、不让客服自由发挥: - QUOTE_DISCLOSURE:星级可保证,具体酒店/房型/加床以预订时库存为准(不锁死) - CANCELLATION_NOTICE:付定金后取消可能产生费用、部分不可退(保留强约束) - 守卫 _assert_customer_safe:对客话术**禁止**出现「全额付款/一律不退」式强硬措辞 (你明确不建议——保留约束但别吓退客户) - quote_message 拼金额+说明+能/不能承诺项;wire 进 console op_send(批准发报价时 直接给操作员现成对客话术) 真实退款分档数字仍是你未决策的规则(refund_pct 未配置返回 None,不编)。 tests 5 新测,全套 82 绿。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
我造不出你的真实价格/退改数字,但能把「你交给我」这件事变成 2 分钟的活。 这是把系统从占位切到真实运营的活化能降到最低(非表面功能,是真数据入口)。 - systems/import_data.py:真 CSV 导入器。填价格表→一条命令灌进价格库→计调出真报价。 元→分、供应商按名去重、类型校验对齐 ResourceType;格式不对的行**跳过并报错,绝不编价**。 跑:python3 -m company.systems.import_data prices.csv - onboarding/:price_book_template.csv(价格表模板)+ refund_tiers_template.csv (你自述"需完善"的退改分档表,你来填数字)+ GO-LIVE.md(六项上线清单,每项=你给→我接) - tests:5 新测(导入/去重/元分换算/坏行诚实跳过/随附模板可加载/灌完出真报价)。全套 87 绿。 真跑演示:模板导入 3 价 → 出真报价(成本4000→对客4800),换你的真 CSV 即你的真报价。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
现在每笔定金/尾款要人手工点「确认到账」。PayPal API 本身就是到账的权威来源—— 让系统查 PayPal 的 PAID 状态自动推进订单,把人工确认换成系统读支付方权威状态。 §3 合规:这不是 agent 擅自认钱,是读支付方自己的 PAID 记录反映事实;对外承诺 (发报价/向供应商下单)仍留人审,不受影响。 - schema/db:orders 加 deposit_ref/balance_ref(存支付方收款单号)+ 幂等迁移(老库自动补列) - collections:request_deposit/balance 记下 provider_ref;reconcile_order/reconcile_all 查支付方状态、PAID 才自动推进(尾款须定金已付;对账绝不触发下单/发送) - console:reconcile 命令 + _payment_adapter()(有 PAYPAL_CLIENT_ID 走真 PayPal 可对账, 否则占位保持人工确认,优雅降级不崩) - tests:6 新测(存单号/仅PAID才推进/尾款依赖定金/批量/占位降级/不越权下单)。全套 93 绿。 真跑演示:开发票→未付不动→客户付款后系统自动推进 deposit_paid(无人手工点)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
你要的是「harness 自主运行 agent 公司」。前面各件都是分开被调用的;autopilot 把它们 拧成一个你一启动就持续自转的进程: 1) 收客户:SaleSmartly webhook 常驻(新消息→客服→Lead) 2) 自动对账:定期查支付方 PAID 状态自动推进已付款订单 3) 盯闸门:把待人审事项(待发报价/待下单/待确认款)汇总成待办队列 4) 反馈:转化漏斗 + 投放优化快照 §3 不变:只自动做安全自主动作(收客户/读支付方权威状态对账/统计);对外承诺 (发报价、向供应商下单)永远留人审,autopilot 只排进待办、绝不自动执行。 - company/autopilot.py:tick()(纯函数可测:对账+待办+漏斗快照)+ run() 循环 (webhook 常驻线程 + 定期 tick,max_ticks 可控退出)+ CLI(--interval / --once / --no-webhook) - tests:5 新测(PAID自动推进/待发报价只排队不自动发/占位降级/--once/循环受控退出)。 全套 98 绿。真跑 `python3 -m company.autopilot --once` 通过。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
之前 autopilot 只用 --once 在空库跑过;这次让整套从「客户进来」一路自主跑到 「收款结清 + 数据反馈」,证明这台机器真能运营公司。只有价格是合成演示数据、 外部 HTTP 是假件,业务逻辑/护栏/闸门/算钱/对账/漏斗/投放建议全是生产代码。 - company/demo_full_run.py:4 位合成客户(2 成交 / 1 被人审在供应商闸门按住 / 1 信息不全停收集)跑完整链路 + 产出转化漏斗和投放建议。跑:python3 -m company.demo_full_run - 🐛彩排逮到真 bug:前门 SaleSmartlyInbound 不记 inquiry(拆 run_from_lead 时漏的) → 漏斗「咨询1→有效3」自相矛盾。修:前门在客户首次进来即记 inquiry(咨询人数本就 产生于接触点)+ CHANNEL_PLATFORM 归一平台标签(facebook/instagram),漏斗跨组件一致。 - tests:2 新验收测(端到端自洽漏斗 咨询4→有效3→报价3→成单2 / 被按住的单不结清)。全套 100 绿。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
彩排暴露的真缺口:真上线时 webhook 收进合格 Lead 后,autopilot 只对账/汇总, 不会自动把合格客户推进到报价——客户会卡在「已合格但没人报价」。这不算自主运行。 - autopilot._auto_advance_leads:把「合格但未报价」的 Lead 自动生成**待人审报价** (§3:只生成不发;发给客户仍是人审闸门)→ 客户进来即自动被报价,进「待发报价」队列。 价格库缺则诚实报缺、不编价、不反复噪音。 - 结清订单在对账路径记成交(won);配 record_stage_once 幂等阶段记录,跨路径不重复计数。 - 漏斗跨路径一致:Lead 加 platform 字段(+schema迁移),前门记 inquiry、autopilot 记 valid/quoted/won 都带归一平台标签 → 自主路径的转化漏斗也自洽。 - tests:2 新自主路径测(webhook→自动报价未发·幂等·漏斗自洽 / 缺价诚实报缺)。全套 102 绿。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GO-LIVE.md 讲你要给什么输入;RUN.md 补上「怎么跑」:机器自动做什么 vs 你做什么 (一张表)、三步启动(装依赖配凭证/灌真价格/nohup autopilot 常驻)、怎么让 SaleSmartly 打进来(内网穿透或反代+TLS)、日常三个人审闸门(send/book/balance)、 健康检查与排错。命令全部核对与现有 CLI 一致(console 10 子命令 / autopilot 4 参数)。 全套 102 绿。至此代码 + 运维文档齐全,剩下的只有用户的真实数据/凭证。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A2 假成功根因:提示词教模型「文件名框可以直接输入完整路径」,而 macOS 文件名框里 的 / 会触发 Go-to-Folder → 存错地方/存不成的假成功。A4 Finder 新建文件夹没策略。 - macos/prompts.py:重写「存文件」指引——cmd+s → cmd+shift+g 前往目录 → 文件名框 只填纯文件名(不带 /)→ 存储;新增「Finder 里 cmd+shift+n 新建文件夹 + 直接改名」策略。 - macos/actions.py:ALLOWED_COMBOS 加 cmd+shift+g / cmd+shift+n;macos/ax.py 补 g 键码(5), 否则模型被教了却按不出。 - tools/lint_invariants.py:加两条机械不变量防回归—— · INV-13 提示词教的组合键必须都在 press_key 白名单(键盘版的 INV-04 单一真相) · INV-14 保存到目录必须走 cmd+shift+g + 纯文件名,禁「文件名框输路径」反模式(A2 教训) docs/INVARIANTS.md 同步记两条(lint↔doc 一致,INV-KB-03 过);tests +3。 - 验证:lint_invariants/lint_knowledge 均退出 0,全套 44 测过。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
按 harness-engineering 思路,把易错的多步键盘序列封装成一等公民动作,模型一步 调用、踩不到「路径塞文件名框」的坑(A2/A4 从"教模型别错"升级为"给它个错不了的工具")。 - macos/actions.py:新增 _do_go_to_folder(cmd+shift+g→输 path→回车)、 _do_new_folder(cmd+shift+n→输名字→回车),共享 _inject_text_sync(ascii 走 CGEvent, 中文走剪贴板+Cmd+V);注册进 _HANDLERS。二者都过 fail-closed 守卫(注入键盘=状态动作)。 - macos/prompts.py:ACTION_SPEC 增两条;保存/Finder 指引改为优先用这两个工具(手动键序列留作兜底)。 - tools/lint_invariants.py:INV-14 正向要求放宽为「go_to_folder 或 cmd+shift+g 任一」。 - tests:+5(离线 mock AX 验证按键序列/中文走剪贴板/空参拒绝/真Mac守卫拒绝)。 - 验证:check.sh 退出 0(INV-04 动作空间单一真相仍一致、INV-13/14 过),49 测全绿。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
harness-engineering 核心:真瓶颈常是配置被悄悄写错,不是模型。开跑前把可静态发现 的配置 bug 一次性报清+给修复,避免 agent 跑到一半神秘卡死。 - macos/preflight.py:配置自检(与 run_agent 的安全硬门分开)。3 条代码级一致性=硬失败 (whitelist↔keycode / prompt↔whitelist / ACTION_SPEC↔handlers),应用/AX=软警告。 - run_agent.py:_preflight() 尾部接配置自检(硬失败→SystemExit(5));新增 --check 只跑自检并退出(off-VM 也能跑,不触发 VM 安全门)。 - tools/lint_invariants.py:加 INV-15——白名单每个键必须解析得出键码(锁死 g 差点无键码 那类「授权了却按不出」的 bug);docs/INVARIANTS.md 同步。 - 设计决定:**不建 save_file 全流程复合工具**——它得在 handler 里盲搜文件名框/Save 按钮, 反而不如让模型用观察列表里的编号 type/click 可靠;复合工具只封装观察里没有的键盘态变更。 - 验证:check.sh 退出 0,run_agent --check 退出 0,56 测全绿(+7)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
多视角对抗评审(5 lens × 逐条验证)查出 13 条 CONFIRMED,最要命的是我新加的复合工具 自己也会造「假成功」——正是我要根除的 A2/A4 反模式。全部修掉: 复合工具假成功根治(评审 #1/#2/#3): - macos/ax.py 加 focused_element_role():读当前聚焦元素 AXRole。 - new_folder 先断言前台确是 Finder(否则 cmd+shift+n 会把名字灌进别的 App 文档还假成功)。 - go_to_folder/new_folder 注入前**轮询等焦点真落在输入框**(AXTextField/AXComboBox), 换掉靠不住的固定 sleep(0.3/0.4)(真机时序会 flaky);等不到/上下文不对 → 诚实 ok=False。 lint 鲁棒性(评审 #7/#9): - INV-14 反模式正则加 (?<!不) 否定前瞻,别误伤「文件名里不可以放路径」这类警告句。 - INV-13/preflight 组合键正则放宽到允许 + 两侧空格、末段数字(cmd + 1),漏扫补上。 测试补洞(评审 #4/#5/#6/#10/#11/#12/#13): - 复合工具改断言**精确操作码顺序**(旧测只查成员存在,颠倒顺序=A2 根因也能过)。 - 补按键/注入失败路径、前台非 Finder、焦点never就绪、空 name 拒绝等用例。 - preflight 测试收窄 CHECKS 不跑真 subprocess;补 run_agent --check 接线 + 硬失败 SystemExit(5)。 - INV-14 测试拆成「反模式/缺指引/合规」三例 + INV-13 空格数字组合键回归。 验证:68 测全绿(+11),check.sh / preflight / lint 均退出 0。 (评审 #8 anchoring 属低优先、现检查有效,未改以免徒增复杂度。) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
「假成功」是桌面 agent 可靠性的核心病根(A2 是它、复合工具也栽在它上)。治本靠让 agent 在 VM 里直接查**真实文件系统**,而不是靠 GUI 猜。 - macos/workflows.py 新增 verify_path 工具:查 path 真在不在(存文件/建文件夹后在 done 前核实);可选 contains 连文件内容一起核。**只回布尔,绝不把文件正文放进 message/ extracted**(否则经 broker→DeepSeek egress,§2A.2)——专门写了防泄露测试。 - macos/prompts.py:ACTION_SPEC 增 verify_path;「见好就收」加铁律——产出型任务 done 前必须 verify_path 核实产物真在,ok=false 别谎报成功。 - 尊重自己的 INV-01(actions.py 加到 534 行超 500):**不用豁免糊弄**,把复合工作流工具 (go_to_folder/new_folder/verify_path + 焦点轮询/注入辅助)抽成 macos/workflows.py, actions.py 末尾 import 并合进 _HANDLERS(避开循环 import)。原语 vs 复合分层更清晰。 actions.py 405 行 / workflows.py 156 行,都 <500。 - 验证:75 测全绿(+7,含 verify_path 存在/缺失/contains/防正文 egress/空参/守卫), check.sh & preflight 退出 0,INV-04 动作空间一致性含新工具仍绿。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
拆分后留了个潜在坑:workflows 顶层 `from macos.actions import ActionResult`,若 `import macos.workflows` 先于 actions,会触发 actions 反 import 半初始化的 workflows → HANDLERS 未定义 AttributeError。测试碰巧都先 import actions 才没暴露;实证 `python3 -c "import macos.workflows"` 确会崩。 - workflows.py 顶层不再 import actions;ActionResult 改各 handler 内懒加载(§7A 惯例, handler 运行时 actions 已就绪);`from __future__ import annotations` 使返回标注不在导入期求值。 - 两种 import 顺序均验证通过。 - 加回归测试 test_workflows_importable_standalone(全新子进程先 import workflows,锁死此坑)。 - 76 测全绿,check.sh 退出 0。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
把「重跑让它真过?」从人肉判断变成一键机械判定:每个场景 = {目标 + 产物真值后置条件},
判过没过**只查真值、不听 agent 自称**,并专门标出「自称成功但真值不符」的假成功
(false_success)——这正是 A2 栽过、本 harness 要机械根除的坑。
- acceptance.py:A2/A3/A4 场景(带真值判据:A2 文件含指定文字、A3 结果含 408、A4 目录存在)
+ check_post(查真值)+ run_scenarios(真值判定 + false_success 识别)+ CLI(list/run --only)。
真机 runner 跑 run_agent.py 读 summary.json(VM-only),纯逻辑注入假 runner 可离线测。
- macos/workflows.py:抽出纯函数 probe_path(文件系统真值检查),verify_path 动作与
acceptance 后置条件共用一份逻辑(单一真相,仍只回布尔不泄露正文)。
- 自查修正 vm_runner:跑前快照 run_* 目录,只认本次**新产出**的 summary,
别误读上一个场景的旧文件当本场景结果。
- tests:+10(后置条件真值检查 / **假成功必被抓** / 诚实失败不误标 / only 过滤 / 报告标红)。
- 验证:86 测全绿,check.sh & preflight 退出 0。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… 里不稳) 在真 macOS Tahoe VM 上端到端调试后修好两处真实故障,A2/A3 现真机通过(查真值确认): 真机发现的根因: - CGEvent 打字(ax.type_unicode)在这台 VM 上**不稳**:文档正文能用,但保存框「前往 文件夹」框、Finder 改名框等临时字段里整段丢失,还常整段丢 → 存出**空文件**的假成功。 - macOS 保存框回车不确认「前往文件夹」;文件名框默认只选中不含扩展名的部分(粘贴会 得到 name.txt.txt);默认存到 Documents 不是目标目录。 修复: - macos/actions.py:_do_type 文本注入统一改**剪贴板+Cmd+V**(type_unicode 不可靠)。 - macos/workflows.py:_inject_text_sync 同样改剪贴板;**新增 save_document(path) 工具** ——真机验证的确定性保存流程:cmd+s → cmd+a 全选+粘贴文件名 → 在 Where 弹出里 AXPress 选目标文件夹 → AXPress Save → **probe_path 落地核实**才 ok=True(治空文件假成功)。 加 _find_elements(按 role/title/value 在窗口+菜单里定位,AXPress 比发按键可靠)。 - macos/prompts.py:ACTION_SPEC 加 save_document;存文件指引改为「直接用 save_document」。 - tests:复合工具序列改断言剪贴板路径 + save_document 空参守卫;87 测过,check.sh 0。 真机验收:A2 = ~/Desktop/agent_a2.txt 存在且内容 'hello from agent';A3 = 计算器 12×34 result=408。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
用户观察到 flash 模型卡在 GUI 上不会破局(不如 Gemini 能"临时写个工具")。两处升级: - **run_script 逃生出口**(macos/workflows.py):GUI 动作做不到时,agent 可直接跑 shell/ AppleScript 把事办成(如 mkdir、osascript)。**这是"自己造工具"的破局能力,只在 VM 里 放开**——任意代码执行正是靠 VM 隔离兜住的危险权力,过 fail-closed 守卫、真机拒绝 (spec §2A.1)。ACTION_SPEC + 提示词「卡住就用 run_script 破局」同步。 - **默认模型 deepseek-v4-flash → v4-pro**(brain/llm.py):更强规划/纠错;可 DEEPSEEK_MODEL 覆盖省钱。 - tests:run_script 能跑+空参拒绝+**真机守卫拒绝**(危险权力不上真机);90 测过,check.sh 0。 真机验收:**A4 现在通过**——pro 先试 new_folder(GUI 失败)→ verify_path 抓到假成功 → run_script `mkdir -p ~/Desktop/agent_a4` 破局 → verify_path 确认 → done。正是"验证+改招+ 自己造工具"的全局行为。A2/A3/A4 全部真机通过。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
依据两篇公开工程文章落地:Anthropic《Building Effective Agents》——把 agent 锚定在 环境真实反馈上;OpenAI《Harness Engineering》——别信模型自述、用机械不变量强制。 规则:一旦改动过状态(mutation),done(success=true) 之前必须至少核验过一次真实结果 (verify_path 查文件系统 / extract 拿数据)。没核验就打回、提示先核验;只打回一次, 不硬困死(确实核验不了时仍能诚实收尾)。 - brain/loop_guards.py:纯函数 action_kind(verify/neutral/mutation 分类)+ needs_verify_before_success。 - brain/agent.py:循环里加 done 闸门 + 跟踪 last_mutation_step/last_verify_step; 只记成功动作,verify_path/extract=核验、其余改状态=mutation。 - tests:分类 + 判定的单测;92 测过,check.sh 0。 真机验证:A2 里 agent type→save_document→done(success) **被闸门当场打回**("改过状态 却没核验")→ 被迫 verify_path(exists=True)→ done 才放行。文件真含 hello from agent。 从此"别信界面"是硬性兜底,不只靠模型自觉。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
按用户"2 人团队、先造再学"的方向,刻意做薄:一条客户消息 → DeepSeek(便宜·一号员工)
判断能否自理,输出 {理解/抽需求/拟回复/信心/是否升级/是否碰钱},落成三条去向:
auto(DeepSeek 自理) / claude(升级二号员工) / human(碰钱或承诺→找老板,硬闸门)。
三层:DeepSeek(always on) → Claude(被升级才上) → 人(守钱和承诺)。
- company/inbox.py:decide() + route_of() + make_broker_brain()(stdlib urllib 接 broker,
默认 flash=便宜)。brain 可注入,离线可测。
- tests:路由规则 + 假 brain 的常规/碰钱/坏JSON 兜底升级(6 测)。
- 真样例实测(flash 经 broker):常规咨询→自理并抽到需求;碰钱→找人;棘手轮椅+清真→
medium 信心自理(暴露"medium 该不该升级"这个待调旋钮)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DeepSeek 判定升级(claude/human)时落一条 case 进队列,Claude(二号)/人 从 open 队列拿活、 处理、回写;auto 直接结案留痕。附「交接包」= Claude 接手所需的一切;「园丁改进笔记」 = 攒 DeepSeek 老栽的模式 + harness 该怎么改(把 DeepSeek 越养越能干)。刻意做薄、自带小 sqlite、不耦合重架构。 - company/handoff.py:record/open_cases/handoff_packet/resolve/note_improvement。 - tests:auto 即时结案 / claude+human 进队列 / 交接包内容 / 回写 + 改进笔记(4 测)。 - 真链路实测:议价威胁流失消息 → DeepSeek 正确升级 human(要折扣=碰价格承诺)→ 落队列 → 生成交接包 → Claude 接手(整理决策简报给人拍板 + 不承诺的稳住话术)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
接住 handoff 那张表,把客户 case 摆成三栏便签墙:🧑待你拍板(碰钱/承诺) | ⬆️升级Claude 处理中 | ✅DeepSeek自理(留痕)。每张便签=一个客户:消息、DeepSeek 的理解/拟回复/抽到的 需求、状态;点「已处理」结案。Python stdlib 起本地小服务 + 一页自带 HTML/JS,无三方依赖。 跑:python3 -m company.board --db company/data/handoff.db --port 8080 → 浏览器开。 - company/board.py:build_server(/、/api/cases、POST /api/resolve)+ 三栏看板前端。 - company/handoff.py:Store 加 check_same_thread(服务线程安全)。 - tests:case 序列化/open 优先/三栏/服务端点(4 测)。 - 真数据实测:5 条真 DeepSeek 分流的 case(家庭游→自理、轮椅定制→升级Claude、 付定金/要折扣→找你、朋友推荐→自理)在看板上各归其栏。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
用户看过预览批准了。把 board.py 前端从奶油/赭石(AI 烂大街色)换成冷灰蓝 + 语义三色 (待你拍板=赭黄/升级Claude=靛蓝/DeepSeek自理=鼠尾草绿),卡片改状态 chip + 顶部色条 (去掉左轨那个套路),抽到的需求做成 mono 小标签,回复带「已回客户/拟回复(未发)」标注。 纯 stdlib、系统字体、无三方依赖。测试仍全过。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
用户场景(没 API,靠盯真实软件;MacBook 上跑,主盯 Facebook+微信)的正解骨架: 哨兵(免费·每隔几秒看一眼·去重) → 有真新消息才喂 DeepSeek(inbox 分流) → handoff → 看板。 读取器可插拔:ManualReader(投递文件,今天就能跑通整条链) + facebook/wechat 占位(之后接真软件)。 只读、只登记;回复一律上看板等审,绝不自动发。 - company/sentinel.py:Sentinel(tick/run,seen 去重持久化) + manual_reader + stub_reader。 - tests:新消息处理/去重/追加拾取/重启后不重复/坏读取器不拖垮/占位空返回(5 测)。 - 真跑:投递 2 条 → 哨兵拾取 → DeepSeek 分流(咨询→自理、付定金→找你) → 落看板库 → 二轮去重。 下一步真读取器:Facebook(浏览器读)先,微信(截图读,难)后。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
yangchunxuan
marked this pull request as ready for review
July 3, 2026 08:34
决定放弃虚拟机 + 桌面隔离整条路线(VM 登录摩擦太大、公司系统本就纯 Python 可直接在
主机跑)。按「B:留下读 App 的眼睛」清理:
- 删除整个 ai-agent-core/macos_agent/(VM 桌面代理引擎:VmGuard 隔离、clean-token、
UTM 脚本、桌面 AX 动作、验收清单、harness 治理层…共 39 文件)。
- 保留并迁出可复用件(去掉 VM 逻辑):
· company/eyes/ax.py + observe.py —— 用辅助功能读原生 App 的「眼睛」(将来读微信用)。
observe(session) 的 session 参数本就没被使用,天然解耦。
· company/broker.py —— 揣 DeepSeek key 的中转(company 靠它调大脑),从 macos_agent 迁入。
- 删除 .github/workflows/harness.yml(跑已删 harness 的 CI)+ specs/(VM/沙盒 agent 设计文档)。
- 删掉的东西全在 git 历史里,将来要读微信可单独捞 eyes 重用。
验证:company 全套 121 测通过;eyes/broker 均可 import。留下的顶层 brain/ 是更早的网页版
大脑(非 VM,暂留)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- client: gettoken(缓存)/sync_msg/send_msg,自建应用secret - crypto: WXBizMsgCrypt 回调签名校验+AES解密(防串企业/防篡改) - callback: 纯stdlib回调HTTP服务(GET验URL/POST收事件) - hub: 事件→sync_msg拉→inbox判→handoff上看板;碰钱硬闸门永不自动发 - run: 一键入口;DeepSeek可选,未接用保守stub - DEPLOY_WINDOWS.md: 首尔常开Windows的完整部署手册 - 24 tests pass Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
把
feat/macos-vm-agent并入main。方向已定案:放弃虚拟机 + 桌面隔离整条路线,本 PR 落地的是自主公司的消息分流层(纯 Python,主机直接跑,Mac 现在 / Windows 以后 7×24),外加从旧引擎里保留的可复用「眼睛」。工程原则贯穿两篇公开文章:OpenAI《Harness Engineering》(不变量、机械化强制、别信自述) + Anthropic《Building Effective Agents》(把 agent 锚定在环境真实反馈上)。
交付:company —— 自主公司消息分流层
三层:DeepSeek(便宜·一号员工·always on) → Claude(被升级才上) → 人(守钱和承诺)。
已放弃并删除:VM / 桌面隔离引擎
原
macos_agent/(在 macOS 虚拟机里 observe→decide→act 的 ReAct 桌面代理 + VM 守卫隔离 + clean-token + UTM 脚本 + 桌面 AX 动作 + harness 治理 + 验收清单)整体删除——VM 登录摩擦太大(Facebook 死拦 VM/数据中心 IP),而公司系统本就纯 Python、主机直接跑更简单。删除内容全在 git 历史里,将来要读微信可单独捞 eyes 重用。测试
备注 / 待办
🤖 Generated with Claude Code