[{"data":1,"prerenderedAt":1429},["ShallowReactive",2],{"post:\u002Fposts\u002Fone-person-delivery-experiment-01-multi-agent-saas":3,"published-posts-ordered":495,"post-series:one-person-delivery-experiment":1412},{"id":4,"title":5,"body":6,"date":475,"description":476,"draft":477,"extension":478,"featured":479,"lang":480,"launch":479,"license":481,"meta":482,"navigation":479,"order":461,"path":483,"seo":484,"series":485,"stem":486,"tags":487,"translationOf":493,"updated":493,"__hash__":494},"posts\u002Fposts\u002Fone-person-delivery-experiment-01-multi-agent-saas.md","一人交付实验",{"type":7,"value":8,"toc":459},"minimark",[9,13,16,76,80,83,86,102,109,112,116,125,133,136,139,145,148,151,154,158,173,176,179,182,186,192,195,232,235,238,244,248,254,260,266,272,275,279,282,312,315,318,321,324,350,353,356,359,385,388,391,394,421,424,427,430,451],[10,11,12],"p",{},"先把结论放在前面：这是一套面向民办幼儿园的家园共育与园务管理 SaaS。产品方案、后端、两个微信小程序和一个管理后台，由我一个人完成；开发过程由一条自建的多 agent 流水线驱动。周期约 2.5 个月，代码合计约 14 万行。",[10,14,15],{},"这不是「AI 全自动写完」的故事。代码由 agent 生成、由人工评审与测试兜底；真正决定交付质量的，是切片方式、契约、评审隔离和证据留存。下面把过程完整拆开。",[17,18,19,32],"table",{},[20,21,22],"thead",{},[23,24,25,29],"tr",{},[26,27,28],"th",{},"维度",[26,30,31],{},"结果",[33,34,35,44,52,60,68],"tbody",{},[23,36,37,41],{},[38,39,40],"td",{},"周期",[38,42,43],{},"约 2.5 个月",[23,45,46,49],{},[38,47,48],{},"后端",[38,50,51],{},"Go，约 7 万行（含约 2.2 万行测试），约 300 个接口、70 张表",[23,53,54,57],{},[38,55,56],{},"前端",[38,58,59],{},"约 130 个 Vue 组件，约 7 万行",[23,61,62,65],{},[38,63,64],{},"端",[38,66,67],{},"老师端小程序、家长端小程序、Nuxt 3 管理后台",[23,69,70,73],{},[38,71,72],{},"合计",[38,74,75],{},"约 14 万行（AI 生成 + 人工评审）",[77,78,79],"h2",{"id":79},"问题与约束",[10,81,82],{},"民办幼儿园的家园沟通，长期依赖微信群和纸质记录：通知发了不知道谁看，请假靠口头汇总，接送靠人工辨认，成长记录散落在各个老师的手机里，出了纠纷很难追溯。",[10,84,85],{},"这类需求并不「高精尖」，但它有几个很现实的约束：",[87,88,89,93,96,99],"ul",{},[90,91,92],"li",{},"幼儿园预算有限，不可能为一个内部系统养一支研发团队；",[90,94,95],{},"老师和管理员不是专业软件用户，界面必须足够简单；",[90,97,98],{},"儿童照片、接送人、健康信息都属于敏感数据，权限必须清楚；",[90,100,101],{},"需求会持续变化，系统必须能迭代，而不是一次性交付后锁死。",[10,103,104,105],{},"传统外包的问题不是做不出来，而是沟通成本和迭代成本太高；一个小团队的问题也不是技术，而是「为这个预算养团队」不成立。于是我想验证一件事：",[106,107,108],"strong",{},"如果一个人把交付流水线设计好，能不能独立完成一套企业级 SaaS？",[10,110,111],{},"我给自己定了三条边界：不接支付、不做开放注册、不碰与儿童隐私无关的扩张功能。范围越小，切片越清楚，评审越容易做。对一人项目来说，克制不是保守，而是交付的一部分。",[77,113,115],{"id":114},"架构先把边界画清楚","架构：先把边界画清楚",[10,117,118],{},[119,120],"img",{"alt":121,"src":122,"loading":123,"decoding":124},"养成星球的三端与后端架构","\u002Fimages\u002Fnurture-planet-architecture.svg","lazy","async",[10,126,127,128,132],{},"后端使用 Go 1.25 + Gin + GORM + MySQL + Redis，权限用 Casbin，依赖注入用 Wire，分层是 ",[129,130,131],"code",{},"handler → service → repository → domain","。这套分层不新，但它适合 agent 协作：每一层的职责固定，切片可以沿着层边界切，评审也更容易判断「有没有越层」。",[10,134,135],{},"为什么是 Go？不是因为性能神话，而是因为一人项目需要「部署简单、并发模型清楚、错误处理显式」。一个二进制、一套标准库、一个能看懂的错误链，比一堆框架魔法更适合长期维护。Gin 和 GORM 也不是唯一选择，但它们的生态足够成熟，agent 生成的代码更容易被评审。",[10,137,138],{},"多租户是这套系统的第一约束。所有业务表都带租户列，查询必须带租户条件，跨园所数据强制隔离；儿童照片只对授权家长可见。这个约束不是事后补的，而是从第一张表开始就写进 schema 和 repository 的。",[10,140,141],{},[119,142],{"alt":143,"src":144,"loading":123,"decoding":124},"多租户隔离：所有查询都必须带租户条件","\u002Fimages\u002Fmulti-tenant-isolation.svg",[10,146,147],{},"多租户有两种常见做法：每个租户一个 schema，或者共享表 + 租户列。前者隔离更彻底，但迁移、备份、跨租户统计都更复杂；后者实现简单，但要求每一层都记得带条件。对这套系统，我选了共享表 + 租户列，并把「忘记租户条件」当成最高级别的代码缺陷：repository 层强制注入，code review 里看到跨园所查询直接拒绝，测试里专门覆盖跨租户读取。",[10,149,150],{},"多租户的测试不能只测「正常查询」：要构造两个园所的数据，用 A 园所的账号去读 B 园所的学生、通知、照片、接送记录，确认全部返回空或 404；还要测管理员跨园所的统计接口，确认它只返回授权范围内的聚合。这类测试很枯燥，但它是多租户系统最值得投入的地方。",[10,152,153],{},"人脸识别抽象了一个 Provider 接口，接入腾讯云 IAI 做 1:N 检索：照片自动匹配学生，按人脸数量区分单人、小组和合影。后来供应商方案调整，我只替换了实现层，调用方零改动。对一个一人项目来说，这种「可替换边界」比「选对某个供应商」更重要：你没有团队去追每一个供应商的变化，只能把变化关在一个小盒子里。",[77,155,157],{"id":156},"三端把复杂度留在后端","三端：把复杂度留在后端",[87,159,160,163,166],{},[90,161,162],{},"老师端和家长端用 uni-app + Vue 3 + Vite，共用一套组件与设计 Token；",[90,164,165],{},"管理后台用 Nuxt 3 + Element Plus + Pinia + ECharts；",[90,167,168,169,172],{},"三端共享 ",[129,170,171],{},"tokens.json","，构建时生成产物，再用 lint 阻断硬编码色值和间距。",[10,174,175],{},"老师端的核心是「少点几下」：发通知、记成长、看待办、处理请假、接送核验。家长端的核心是「看得懂」：通知、成长档案、请假、接送授权、相册。管理后台的核心是「可管理」：园所、班级、学生、老师、权限、统计。",[10,177,178],{},"共享设计 Token 看起来是「设计系统」的事，实际上它是 agent 协作的护栏：当三个端由不同切片实现时，颜色、间距、圆角很容易各自发挥；Token + lint 把「审美」变成了可验证的约束。",[10,180,181],{},"另一个容易被忽略的点是错误提示。三端面向的是非技术用户，错误信息不能是「internal server error」。我在契约层定义了错误码和用户可读文案，前端只负责展示；这样 agent 在实现不同端时，不会各自发明一套错误语言。",[77,183,185],{"id":184},"多-agent-流水线主会话不读源码","多 agent 流水线：主会话不读源码",[10,187,188],{},[119,189],{"alt":190,"src":191,"loading":123,"decoding":124},"多 agent 交付流水线","\u002Fimages\u002Fmulti-agent-pipeline.svg",[10,193,194],{},"这是整个项目里最值得复盘的部分。流水线不是「开一个聊天窗口，让 AI 一直写」，而是把交付拆成几个角色：",[196,197,198,204,213,222],"ol",{},[90,199,200,203],{},[106,201,202],{},"主会话只做编排","。它不读源码，只读计划、切片状态和评审结论。这样可以避免主上下文被几十万行代码淹没，也能让「决策」和「实现」分开。",[90,205,206,212],{},[106,207,208,211],{},[129,209,210],{},"slice-worker"," 负责实现","。每个切片足够小，有明确的输入、输出和验收标准；worker 只在自己的切片里工作，失败可以回滚。",[90,214,215,221],{},[106,216,217,220],{},[129,218,219],{},"slice-supervisor"," 负责对抗式评审","。它是一个全新上下文的实例，不继承 worker 的自我判断；它读代码、跑测试、在微信开发者工具里做真机验证，然后给出 verdict。",[90,223,224,227,228,231],{},[106,225,226],{},"检查点与证据","。四个检查点、validator、密钥扫描，状态全部落在 ",[129,229,230],{},"PROGRESS.md","。主会话靠这些证据判断「能不能进入下一阶段」，而不是靠 agent 说「我完成了」。",[10,233,234],{},"四个检查点分别看四件事：规格是否写清楚、契约是否稳定、实现是否越层、真机行为是否符合验收。validator 负责机械检查：编译、测试、lint、密钥扫描、禁止的依赖。检查点不通过，worker 不进入下一个切片；supervisor 不通过，主会话不合并。",[10,236,237],{},"为什么 supervisor 要用全新实例？因为同一个上下文里，模型很容易为自己的实现找理由。换一个没有「沉没成本」的实例，评审会更接近一个真正的外部 reviewer。这一点在跨文件重构和权限边界上尤其明显。",[10,239,240,241],{},"这套流水线并不能让 agent 变成资深工程师。它做的是另一件事：",[106,242,243],{},"把「实现」变成可并行、可回滚、可复核的工作单元，把人的注意力留给架构、边界和取舍。",[245,246,247],"h3",{"id":247},"四个检查点具体看什么",[10,249,250,253],{},[106,251,252],{},"规格检查点","：需求有没有写成可验收的行为？边界条件、权限、失败路径有没有写清楚？如果规格里只有「实现通知已读」，没有「家长只能标记自己的记录」，这个切片就不该开始。",[10,255,256,259],{},[106,257,258],{},"契约检查点","：接口形状、错误码、字段类型有没有定下来？前端和后端是不是照着同一份契约写？契约没定就开工，最后一定会在联调时返工。",[10,261,262,265],{},[106,263,264],{},"实现检查点","：有没有越层？repository 里有没有业务逻辑？handler 里有没有直接拼 SQL？租户条件有没有漏？这些是机械检查能发现的部分，也是 supervisor 最先看的地方。",[10,267,268,271],{},[106,269,270],{},"真机检查点","：在微信开发者工具里跑一遍真实路径，不只看单元测试。登录、切换身份、打开通知、标记已读、返回列表，每一步都要在真机上确认。很多问题只在真机上出现，测试环境看不出来。",[10,273,274],{},"四个检查点都通过，切片才算完成；任何一个不通过，worker 回到实现，而不是把问题留给下一个人。",[77,276,278],{"id":277},"工程规范让-agent-有东西可以遵守","工程规范：让 agent 有东西可以遵守",[10,280,281],{},"agent 不会自动遵守你脑子里的规范，除非规范被写成可执行的约束。这个项目里，真正起作用的是四件事：",[87,283,284,294,300,306],{},[90,285,286,289,290,293],{},[106,287,288],{},"API 契约优先","：",[129,291,292],{},"backend\u002Fapi\u002F"," 是接口形状的唯一真相源。改接口先改契约，三端照着契约写；契约不一致，测试会先失败。",[90,295,296,299],{},[106,297,298],{},"OpenSpec 规格驱动","：跨三层的改动先写 proposal 和带 SHALL + Scenario 的验收标准，验收通过才归档。我试过不写规格直接改，结果就是三个月后没人记得当初为什么这么写。",[90,301,302,305],{},[106,303,304],{},"测试","：Go 端用 testify 做单元测试，前端用 Vitest。测试不是给 agent 看的，是给「未来的我」看的。",[90,307,308,311],{},[106,309,310],{},"检查点","：每个阶段结束必须留下可验证的产物；没有产物，不算完成。",[10,313,314],{},"这些规范听起来像「大团队才需要的东西」，但在一个人 + agent 的场景里反而更重要：agent 的速度越快，没有约束的返工就越贵。",[10,316,317],{},"我后来发现，规范的价值不在于「写得漂亮」，而在于「让 agent 可以被问责」。当验收标准是 SHALL + Scenario 时，supervisor 可以逐条对照；当接口有契约时，前端不需要猜后端；当测试覆盖真实行为时，agent 说「完成了」才有意义。",[77,319,320],{"id":320},"失败与取舍",[10,322,323],{},"这套流水线不是没有代价。几个真实的失败点：",[87,325,326,332,338,344],{},[90,327,328,331],{},[106,329,330],{},"跨文件重构仍然最容易失控","。切片一旦跨过太多文件，worker 很容易改出「局部正确、整体不一致」的结果；后来我把这类任务拆成「先改契约，再改实现，再改调用方」。",[90,333,334,337],{},[106,335,336],{},"UI 细节和真机兼容需要人盯着","。小程序的样式、键盘、滚动、真机表现，agent 可以写，但很难自己判断「看起来对不对」；supervisor 的真机验证是必要的，但仍然需要人做最终取舍。",[90,339,340,343],{},[106,341,342],{},"评审开销是真实成本","。全新上下文的 supervisor 会增加时间，但它减少的是更贵的返工；如果切片太大，评审开销会迅速失控。",[90,345,346,349],{},[106,347,348],{},"上下文管理比模型能力更关键","。主会话不读源码、切片足够小、状态落到文件，这些做法比换一个更强的模型更能提升稳定性。",[10,351,352],{},"如果重来一次，我会改三件事：切片再小一点；真机验证再早一点；契约测试再多一点。",[77,354,355],{"id":355},"时间花在哪里",[10,357,358],{},"2.5 个月里，真正写代码的时间没有想象中多。大致可以分成四块：",[87,360,361,367,373,379],{},[90,362,363,366],{},[106,364,365],{},"产品与范围","：把「什么都想要」压到「这一版必须有什么」，这部分只能人做；",[90,368,369,372],{},[106,370,371],{},"架构与契约","：定分层、租户模型、接口形状、设计 Token，这部分决定后面返工多少；",[90,374,375,378],{},[106,376,377],{},"实现与评审","：agent 写、supervisor 审、我处理冲突和边界；",[90,380,381,384],{},[106,382,383],{},"真机与收尾","：小程序兼容、权限边界、异常路径、部署与文档。",[10,386,387],{},"AI 明显加速的是第三块；第一、二、四块反而更需要人。这个分布也解释了为什么「一人 + agent」不是简单地把人替换掉：它把人的工作从「写」推向了「定义」和「判断」。",[77,389,390],{"id":390},"可复用清单",[10,392,393],{},"如果你也想尝试「一个人 + agent」交付，下面几条可以直接抄走：",[196,395,396,403,406,409,412,415,418],{},[90,397,398,399,402],{},"按",[106,400,401],{},"可交付行为","切片，不要按文件切片。",[90,404,405],{},"每个切片先写验收标准，再让 agent 实现。",[90,407,408],{},"评审必须用没有参与实现的上下文。",[90,410,411],{},"主会话不要读全部源码，只读计划和 verdict。",[90,413,414],{},"契约优先，测试放在契约和真实行为的交界处。",[90,416,417],{},"每个阶段留下证据：测试、日志、检查点、回滚路径。",[90,419,420],{},"对外复盘前先脱敏：客户名称、儿童信息、内部域名、密钥，一个都不能留。",[10,422,423],{},"这套方法不适合所有项目。需求极不稳定、界面极重、强实时协作的场景，仍然需要更多人。但如果你在做一人公司、独立产品，或者想验证「一个人到底能交付到什么程度」，它值得一试。",[77,425,426],{"id":426},"下一篇",[10,428,429],{},"这篇讲的是「怎么把一套 SaaS 交付出来」；下一篇回到 AI 工程本身，拆解模型服务、LLM 工具编排、数据与算法三层怎么一起落地：",[87,431,432,439,445],{},[90,433,434],{},[435,436,438],"a",{"href":437},"\u002Fposts\u002Fone-person-delivery-experiment-02-ai-engineering-stack","一人交付实验 #2：AI 工程落地的三层栈",[90,440,441],{},[435,442,444],{"href":443},"\u002Fposts\u002Fwhy-i-started-one-person-delivery-notes","我为什么开始「一人交付笔记」",[90,446,447],{},[435,448,450],{"href":449},"\u002Fseries\u002Fone-person-delivery-experiment","一人交付实验专题",[10,452,453,454,458],{},"如果你对某个环节想看得更细——切片怎么切、supervisor 怎么评审、契约怎么落地——欢迎通过 ",[435,455,457],{"href":456},"\u002Ffeed.xml","RSS","、知乎或公众号告诉我。",{"title":460,"searchDepth":461,"depth":461,"links":462},"",2,[463,464,465,466,470,471,472,473,474],{"id":79,"depth":461,"text":79},{"id":114,"depth":461,"text":115},{"id":156,"depth":461,"text":157},{"id":184,"depth":461,"text":185,"children":467},[468],{"id":247,"depth":469,"text":247},3,{"id":277,"depth":461,"text":278},{"id":320,"depth":461,"text":320},{"id":355,"depth":461,"text":355},{"id":390,"depth":461,"text":390},{"id":426,"depth":461,"text":426},"2026-11-17","一套多租户幼儿园家园共育 SaaS 的完整复盘：架构、三端、多 agent 流水线、工程规范、失败路径与可复用清单。",false,"md",true,"zh","CC BY 4.0",{},"\u002Fposts\u002Fone-person-delivery-experiment-01-multi-agent-saas",{"title":5,"description":476},"one-person-delivery-experiment","posts\u002Fone-person-delivery-experiment-01-multi-agent-saas",[488,489,490,491,492],"一人交付","AI Agent","多租户 SaaS","Go","工程管理",null,"d_npBYOCuvpBaAhqXmpANfEyUkRlE87GkMyqhqcdiUQ",[496,803,1114],{"id":497,"title":444,"body":498,"date":793,"description":794,"draft":477,"extension":478,"featured":479,"lang":480,"launch":479,"license":481,"meta":795,"navigation":479,"order":796,"path":443,"seo":797,"series":485,"stem":798,"tags":799,"translationOf":493,"updated":493,"__hash__":802},"posts\u002Fposts\u002Fwhy-i-started-one-person-delivery-notes.md",{"type":7,"value":499,"toc":781},[500,503,506,512,515,521,525,531,534,537,543,547,550,553,571,577,580,583,586,589,592,596,599,613,616,619,622,625,628,631,634,637,651,654,657,660,674,677,681,684,695,698,709,712,715,718,744,747,750,753,756,767,775],[10,501,502],{},"在最近这个项目里，有一个瞬间让我意识到，自己对「一个人能交付多少软件」的判断已经过时了。",[10,504,505],{},"那天晚上，我在微信开发者工具里点下预览：老师端、家长端、管理后台同时亮起来，接口、权限、通知、接送记录都按预期工作。就在几个小时前，这些切片还只是计划文件里的几行任务。它们由一个主会话拆解，被不同的 agent 实现，再由一个全新上下文的 agent 逐项评审、在真机上验证，最后回到我这里做取舍。",[10,507,508,509],{},"那一刻我没有觉得「AI 替我写完了代码」。我想到的是另一件事：",[106,510,511],{},"一个人也可以设计一条交付流水线，让 agent 在里面干活，而人只负责判断、边界和证据。",[10,513,514],{},"这就是「一人交付笔记」的起点。",[10,516,517],{},[119,518],{"alt":519,"src":520,"loading":123,"decoding":124},"一人 + agent 的交付流水线","\u002Fimages\u002Fone-person-delivery-pipeline.svg",[77,522,524],{"id":523},"十一年三个转折","十一年，三个转折",[10,526,527,528],{},"过去十一年，我主要做后端与分布式系统。那段时间里，我关心的东西很具体：接口契约、数据一致性、并发、可观测性、故障恢复。今天回头看，那几年真正留下来的不是某个框架的用法，而是一种习惯：",[106,529,530],{},"先把边界画清楚，再谈实现。",[10,532,533],{},"后来有四年半时间，我带着一个小团队做数据分析。工作从「把代码写对」变成了「对交付结果负责」：需求是否值得做、模型是否真的有用、上线之后谁来维护。带团队和写代码最大的区别，是你不能再用「我本地跑通了」作为完成标准；你要面对的是别人的时间、客户的环境和长期的维护成本。",[10,535,536],{},"再往后，我把重心放到 AI 模型服务与 LLM 应用上：把 YOLOv5、PaddleOCR 这类模型导出成 ONNX，部署到 Triton Inference Server；用 LLM 做意图识别和工具编排；在客户环境里做私有化部署，让数据不出门。这一段经历让我第一次认真面对「模型不是全部」：前后处理、批处理、CPU\u002FGPU 降级、权限、审计、回滚，任何一项没做好，demo 都变不成产品。",[10,538,539,540],{},"这三个阶段看起来跨度很大，但有一条线一直没变：",[106,541,542],{},"我关心的不是某个技术名词，而是一个东西能不能被稳定地交付出去。",[77,544,546],{"id":545},"真正的转折点把-agent-放进流水线","真正的转折点：把 agent 放进流水线",[10,548,549],{},"很多人对 AI 编程的想象是「补全更快」：写一行，AI 接下半行；写一个函数，AI 补一个测试。那当然有用，但它改变的是手感，不是交付方式。",[10,551,552],{},"真正改变交付方式的，是把 agent 放进一条完整的流水线里：",[87,554,555,558,561,568],{},[90,556,557],{},"主会话只做编排，不读源码，只读计划和评审结论；",[90,559,560],{},"每个切片交给一个 worker 实现，切片足够小，失败可以回滚；",[90,562,563,564,567],{},"再由一个",[106,565,566],{},"全新上下文","的 supervisor 做对抗式评审，并在真实环境里验证；",[90,569,570],{},"检查点、validator、密钥扫描和进度文件把过程留下来，而不是只留下「我觉得写完了」。",[10,572,573,574],{},"这套流程并不神秘，也不轻松。它要求你把「怎么做」拆成「怎么验收」，要求你接受 agent 会在某些任务上反复失败，也要求你承认：",[106,575,576],{},"人最有价值的部分，不是敲代码的速度，而是定义边界和判断取舍。",[77,578,579],{"id":579},"一个切片长什么样",[10,581,582],{},"「切片」听起来抽象，其实可以很具体。",[10,584,585],{},"比如「通知已读状态」这个需求。它不是一个「把通知模块写出来」的大任务，而是一个可以被单独验收的切片：数据库里增加已读记录；接口返回当前用户的已读状态；老师端显示已读人数；家长端在打开通知后标记已读；管理员能看到未读名单；权限上，家长只能标记自己的记录。",[10,587,588],{},"这个切片有明确的输入、输出和验收标准。worker 拿到的是契约、相关文件范围和验收条件，而不是「你看着办」。supervisor 评审时也不需要理解整个系统，只需要确认：契约有没有被遵守、权限有没有越界、已读状态在并发下会不会重复、真机上打开通知后状态有没有变化。",[10,590,591],{},"切片足够小，失败就可以回滚；切片足够完整，评审就能在真实行为上做判断。这两件事同时成立，agent 才不会变成「写得很快、返工更多」的工具。",[77,593,595],{"id":594},"一人交付不是ai-取代团队","一人交付，不是「AI 取代团队」",[10,597,598],{},"我不想把这件事写成「一个人干掉一个团队」的故事。真实情况更朴素：",[87,600,601,604,607,610],{},[90,602,603],{},"agent 可以承担大量实现、测试补齐、重复修改和文档整理；",[90,605,606],{},"但需求是否成立、架构是否过度、风险是否可接受，仍然要人判断；",[90,608,609],{},"评审必须独立，最好由没有参与实现的上下文来做；",[90,611,612],{},"交付的证据要能复核：测试、日志、检查点、回滚路径。",[10,614,615],{},"所以「一人交付」不是把人去掉，而是把人的位置往前移：从执行者变成流水线的设计者。一个人能不能交付一套企业级软件，取决于这条流水线设计得好不好，而不是模型参数有多大。",[77,617,618],{"id":618},"为什么公开写",[10,620,621],{},"私人笔记也可以记录这些过程，但公开写有三个不同的作用。",[10,623,624],{},"第一，它逼我把「我觉得」变成「可复核」。当你知道读者会追问数字、环境和失败路径时，你会不自觉地写得更具体，也更愿意承认哪些地方没做好。",[10,626,627],{},"第二，它是个人品牌的一部分。我希望当有人问「袁海粟是谁」「一个人能不能用 AI 交付企业级软件」时，AI 和读者能找到一个稳定的、可验证的来源，而不是只看到一份简历或几个零散的项目名。",[10,629,630],{},"第三，它让同类经验可以被复用。一人公司、独立开发者、小团队的技术负责人，面对的问题往往不是「要不要用 AI」，而是「怎么把 AI 放进交付流程里」。如果这些记录能帮你少走一点弯路，公开就是值得的。",[77,632,633],{"id":633},"这个博客写什么",[10,635,636],{},"我会把「一人交付实验」拆成可复核的记录，而不是只展示结果：",[87,638,639,642,645,648],{},[90,640,641],{},"一人公司的软件交付方法：范围控制、架构取舍、质量门槛；",[90,643,644],{},"AI agent 流水线的实际用法：任务编排、上下文管理、验证与回滚；",[90,646,647],{},"真实项目的复盘：指标、失败、成本与时间线；",[90,649,650],{},"可复用清单：哪些做法能直接被读者拿走。",[10,652,653],{},"这个专题的第一篇正式复盘，是我用约 2.5 个月、一个人加一条多 agent 流水线交付的一套多租户 SaaS。它不是一个玩具项目：后端约 300 个接口、70 张表，前端约 130 个组件，包含老师端、家长端两个微信小程序和一个管理后台。下一篇会完整拆开它的架构、流水线和失败路径。",[10,655,656],{},"第三篇会回到 AI 工程本身：模型服务、LLM 工具编排、数据与算法三层怎么一起落地。如果你在做 AI 应用，或者正在判断「私有化部署到底该从哪里开始」，那一篇会更接近你的日常。",[77,658,659],{"id":659},"这个博客不写什么",[87,661,662,665,668,671],{},[90,663,664],{},"不写无法验证的成功学；",[90,666,667],{},"不写「AI 全自动交付」的神话；",[90,669,670],{},"不暴露客户名称、儿童信息、手机号、内部域名或任何密钥；",[90,672,673],{},"不把 AI 生成的内容当作未经审查的事实。",[10,675,676],{},"每一篇都尽量给出可复核的过程与证据。你可以不同意我的结论，但应该能看清我是怎么走到那里的。",[77,678,680],{"id":679},"适合谁不适合谁","适合谁，不适合谁",[10,682,683],{},"这套记录适合：",[87,685,686,689,692],{},[90,687,688],{},"独立开发者、一人公司，想验证「一个人 + AI 能交付到什么程度」；",[90,690,691],{},"小团队的技术负责人，想把 agent 放进现有工程流程；",[90,693,694],{},"对 AI 工程落地感兴趣，但不想只看 demo 的工程师。",[10,696,697],{},"它不适合：",[87,699,700,703,706],{},[90,701,702],{},"需要强实时协作、多人并行修改同一模块的团队；",[90,704,705],{},"界面极重、视觉判断占主导的项目；",[90,707,708],{},"希望「把需求丢给 AI，明天上线」的人。",[10,710,711],{},"一人交付不是万能方法。它只是把「一个人能做的事」往前推了一点，同时把「人必须判断的事」暴露得更清楚。",[77,713,714],{"id":714},"我怎么判断一篇复盘是否可信",[10,716,717],{},"我自己读别人的复盘时，会看四件事：",[196,719,720,726,732,738],{},[90,721,722,725],{},[106,723,724],{},"数字有没有条件","：吞吐、周期、代码量，是在什么环境、什么规模下得到的？",[90,727,728,731],{},[106,729,730],{},"失败有没有写","：只写成功路径的复盘，通常省略了最贵的部分。",[90,733,734,737],{},[106,735,736],{},"过程能不能复现","：切片怎么切、评审怎么做、证据怎么留，读者能不能照着做？",[90,739,740,743],{},[106,741,742],{},"脱敏是否认真","：客户名称、儿童信息、内部域名、密钥，有没有被处理干净？",[10,745,746],{},"这个博客会尽量按这四条来写。如果哪一篇没做到，欢迎直接指出来。",[77,748,749],{"id":749},"接下来",[10,751,752],{},"这个博客本身也是一次实验：Markdown 写作为内容源，Git 管理版本，静态生成后部署到 Cloudflare Pages；正文以服务端生成的 HTML 呈现，不依赖 JavaScript 也能完整阅读，方便读者、搜索引擎与 AI agent 获取内容。",[10,754,755],{},"如果你也在独立开发、经营一人公司，或者只是想搞清楚「一个人 + AI 到底能交付到什么程度」，欢迎从下面两篇继续：",[87,757,758,763],{},[90,759,760],{},[435,761,762],{"href":483},"一人交付实验 #1：一个人 + 多 agent，2.5 个月交付 14 万行 SaaS",[90,764,765],{},[435,766,438],{"href":437},[10,768,769,770,774],{},"也可以先看看",[435,771,773],{"href":772},"\u002Fabout","关于我","，了解我过去十一年在做什么。",[10,776,777,778,780],{},"订阅可以通过 ",[435,779,457],{"href":456}," 或微信公众号；国内读者也欢迎在知乎\u002F公众号讨论。下一篇见。",{"title":460,"searchDepth":461,"depth":461,"links":782},[783,784,785,786,787,788,789,790,791,792],{"id":523,"depth":461,"text":524},{"id":545,"depth":461,"text":546},{"id":579,"depth":461,"text":579},{"id":594,"depth":461,"text":595},{"id":618,"depth":461,"text":618},{"id":633,"depth":461,"text":633},{"id":659,"depth":461,"text":659},{"id":679,"depth":461,"text":680},{"id":714,"depth":461,"text":714},{"id":749,"depth":461,"text":749},"2026-11-10","从十一年后端与数据分析经验出发，说明我为什么要公开记录「一个人 + AI agent」的软件交付过程，以及这个博客会写什么、不写什么。",{},1,{"title":444,"description":794},"posts\u002Fwhy-i-started-one-person-delivery-notes",[488,800,489,801],"个人品牌","独立开发","Ukta0bfifd38M6nFekc9el4-4miU99TKGx3ao_ylgCg",{"id":4,"title":5,"body":804,"date":475,"description":476,"draft":477,"extension":478,"featured":479,"lang":480,"launch":479,"license":481,"meta":1111,"navigation":479,"order":461,"path":483,"seo":1112,"series":485,"stem":486,"tags":1113,"translationOf":493,"updated":493,"__hash__":494},{"type":7,"value":805,"toc":1098},[806,808,810,852,854,856,858,868,872,874,876,880,884,886,888,892,894,896,898,900,910,912,914,916,918,922,924,948,950,952,956,958,962,966,970,974,976,978,980,1000,1002,1004,1006,1008,1026,1028,1030,1032,1050,1052,1054,1056,1074,1076,1078,1080,1094],[10,807,12],{},[10,809,15],{},[17,811,812,820],{},[20,813,814],{},[23,815,816,818],{},[26,817,28],{},[26,819,31],{},[33,821,822,828,834,840,846],{},[23,823,824,826],{},[38,825,40],{},[38,827,43],{},[23,829,830,832],{},[38,831,48],{},[38,833,51],{},[23,835,836,838],{},[38,837,56],{},[38,839,59],{},[23,841,842,844],{},[38,843,64],{},[38,845,67],{},[23,847,848,850],{},[38,849,72],{},[38,851,75],{},[77,853,79],{"id":79},[10,855,82],{},[10,857,85],{},[87,859,860,862,864,866],{},[90,861,92],{},[90,863,95],{},[90,865,98],{},[90,867,101],{},[10,869,104,870],{},[106,871,108],{},[10,873,111],{},[77,875,115],{"id":114},[10,877,878],{},[119,879],{"alt":121,"src":122,"loading":123,"decoding":124},[10,881,127,882,132],{},[129,883,131],{},[10,885,135],{},[10,887,138],{},[10,889,890],{},[119,891],{"alt":143,"src":144,"loading":123,"decoding":124},[10,893,147],{},[10,895,150],{},[10,897,153],{},[77,899,157],{"id":156},[87,901,902,904,906],{},[90,903,162],{},[90,905,165],{},[90,907,168,908,172],{},[129,909,171],{},[10,911,175],{},[10,913,178],{},[10,915,181],{},[77,917,185],{"id":184},[10,919,920],{},[119,921],{"alt":190,"src":191,"loading":123,"decoding":124},[10,923,194],{},[196,925,926,930,936,942],{},[90,927,928,203],{},[106,929,202],{},[90,931,932,212],{},[106,933,934,211],{},[129,935,210],{},[90,937,938,221],{},[106,939,940,220],{},[129,941,219],{},[90,943,944,227,946,231],{},[106,945,226],{},[129,947,230],{},[10,949,234],{},[10,951,237],{},[10,953,240,954],{},[106,955,243],{},[245,957,247],{"id":247},[10,959,960,253],{},[106,961,252],{},[10,963,964,259],{},[106,965,258],{},[10,967,968,265],{},[106,969,264],{},[10,971,972,271],{},[106,973,270],{},[10,975,274],{},[77,977,278],{"id":277},[10,979,281],{},[87,981,982,988,992,996],{},[90,983,984,289,986,293],{},[106,985,288],{},[129,987,292],{},[90,989,990,299],{},[106,991,298],{},[90,993,994,305],{},[106,995,304],{},[90,997,998,311],{},[106,999,310],{},[10,1001,314],{},[10,1003,317],{},[77,1005,320],{"id":320},[10,1007,323],{},[87,1009,1010,1014,1018,1022],{},[90,1011,1012,331],{},[106,1013,330],{},[90,1015,1016,337],{},[106,1017,336],{},[90,1019,1020,343],{},[106,1021,342],{},[90,1023,1024,349],{},[106,1025,348],{},[10,1027,352],{},[77,1029,355],{"id":355},[10,1031,358],{},[87,1033,1034,1038,1042,1046],{},[90,1035,1036,366],{},[106,1037,365],{},[90,1039,1040,372],{},[106,1041,371],{},[90,1043,1044,378],{},[106,1045,377],{},[90,1047,1048,384],{},[106,1049,383],{},[10,1051,387],{},[77,1053,390],{"id":390},[10,1055,393],{},[196,1057,1058,1062,1064,1066,1068,1070,1072],{},[90,1059,398,1060,402],{},[106,1061,401],{},[90,1063,405],{},[90,1065,408],{},[90,1067,411],{},[90,1069,414],{},[90,1071,417],{},[90,1073,420],{},[10,1075,423],{},[77,1077,426],{"id":426},[10,1079,429],{},[87,1081,1082,1086,1090],{},[90,1083,1084],{},[435,1085,438],{"href":437},[90,1087,1088],{},[435,1089,444],{"href":443},[90,1091,1092],{},[435,1093,450],{"href":449},[10,1095,453,1096,458],{},[435,1097,457],{"href":456},{"title":460,"searchDepth":461,"depth":461,"links":1099},[1100,1101,1102,1103,1106,1107,1108,1109,1110],{"id":79,"depth":461,"text":79},{"id":114,"depth":461,"text":115},{"id":156,"depth":461,"text":157},{"id":184,"depth":461,"text":185,"children":1104},[1105],{"id":247,"depth":469,"text":247},{"id":277,"depth":461,"text":278},{"id":320,"depth":461,"text":320},{"id":355,"depth":461,"text":355},{"id":390,"depth":461,"text":390},{"id":426,"depth":461,"text":426},{},{"title":5,"description":476},[488,489,490,491,492],{"id":1115,"title":5,"body":1116,"date":1400,"description":1401,"draft":477,"extension":478,"featured":477,"lang":480,"launch":479,"license":481,"meta":1402,"navigation":479,"order":469,"path":437,"seo":1403,"series":485,"stem":1404,"tags":1405,"translationOf":493,"updated":493,"__hash__":1411},"posts\u002Fposts\u002Fone-person-delivery-experiment-02-ai-engineering-stack.md",{"type":7,"value":1117,"toc":1389},[1118,1121,1124,1130,1134,1137,1144,1147,1153,1156,1159,1162,1165,1168,1171,1175,1178,1181,1187,1193,1200,1203,1206,1210,1213,1216,1219,1222,1251,1257,1260,1267,1271,1274,1288,1291,1294,1297,1300,1332,1335,1337,1360,1364,1367,1380],[10,1119,1120],{},"很多 AI 项目的失败，不是模型选错了，而是只做了「模型」这一层。",[10,1122,1123],{},"一个能交付的 AI 应用，通常要同时解决三件事：模型怎么稳定地跑起来、LLM 怎么和业务工具接上、数据与算法怎么形成闭环。我把它们叫做 AI 工程落地的三层栈。这篇用我做过的金融级私有化项目拆开讲。",[10,1125,1126],{},[119,1127],{"alt":1128,"src":1129,"loading":123,"decoding":124},"AI 工程落地的三层栈","\u002Fimages\u002Fai-engineering-stack.svg",[77,1131,1133],{"id":1132},"第一层模型服务不是写个-flask-调模型","第一层：模型服务，不是「写个 Flask 调模型」",[10,1135,1136],{},"模型服务层要回答的问题很具体：模型怎么加载、怎么批处理、怎么在 CPU\u002FGPU 之间切换、怎么预热、怎么观测、怎么升级。",[10,1138,1139,1140,1143],{},"在内容识别场景里，我用 YOLOv5 做检测、PaddleOCR 做文字识别（det + rec），模型导出 ONNX 后部署到 Triton Inference Server。Triton 里维护了 5 个模型仓库：检测和识别走 ONNX Runtime backend，前后处理用 Python backend 自己实现；",[129,1141,1142],{},"max_batch_size"," 最高到 1000，其中 2 个模型配置了 model warmup。",[10,1145,1146],{},"为什么用 Triton，而不是直接在 Flask 里加载模型？因为交付环境要考虑的不只是「推理一次」：多个模型要共存、请求要批处理、CPU\u002FGPU 要有不同配置、模型升级要能回滚、进程重启后要能自动预热。Triton 提供的模型仓库和 backend 机制，把这些事收敛到了配置层；业务代码只负责调用，不负责管理模型生命周期。",[10,1148,1149],{},[119,1150],{"alt":1151,"src":1152,"loading":123,"decoding":124},"Triton 模型仓库与 CPU\u002FGPU 双版本","\u002Fimages\u002Ftriton-model-repos.svg",[10,1154,1155],{},"对外接口是 Flask + waitress，部署在 Kubernetes 的 Deployment \u002F Service 上。客户环境不一定有 GPU，所以同一套服务提供 CPU \u002F GPU 双版本；在没有 GPU 的银行客户环境里，CPU 版本稳定吞吐大约 7–10 req\u002Fs，具体会随请求内容大小浮动。",[10,1157,1158],{},"这一层最容易被低估的是「前后处理」。检测框怎么裁、OCR 的 det\u002Frec 怎么串、图片怎么归一化、批量请求怎么拼，这些都不在模型文件里，却直接决定吞吐和准确率。把它们放进 Python backend，而不是散落在业务代码里，是我认为最值得的一个取舍。",[10,1160,1161],{},"模型服务还有几个必须提前想清楚的失败模式：图片超大导致显存\u002F内存暴涨；批量请求里混入损坏文件导致整批失败；模型版本升级后输出格式变化；CPU 环境下超时。这些不是「模型准不准」的问题，而是「服务能不能稳定交付」的问题。",[245,1163,1164],{"id":1164},"模型服务的观测与回滚",[10,1166,1167],{},"模型服务的日志不能只记「成功\u002F失败」。我至少会记录：输入尺寸、批大小、推理耗时、CPU\u002FGPU、模型版本、错误类型。这样线上变慢时，才能判断是流量、模型还是环境的问题。",[10,1169,1170],{},"回滚也要提前设计：模型仓库按版本命名，配置里锁定版本；新版本先在一小部分请求上验证，再全量切换；切换失败时能回到上一版，而不是重新导出模型。对私有化客户来说，「能不能回滚」往往比「新模型准不准」更重要，因为客户环境里没有人能帮你现场调试。",[77,1172,1174],{"id":1173},"第二层llm-应用重点是工具编排","第二层：LLM 应用，重点是工具编排",[10,1176,1177],{},"LLM 应用层不是「接一个聊天接口」就结束了。真正的价值在于：把自然语言变成对内部系统的可靠调用。",[10,1179,1180],{},"我做过两个方向：",[10,1182,1183,1186],{},[106,1184,1185],{},"AI 智询","：用户用自然语言描述需求，系统做意图识别，然后路由到最合适的内部接口或工具，完成多步调用。它把过去需要在菜单里点很多次的流程，收敛成一次对话。难点不在 prompt，而在工具边界的定义：哪些工具可以暴露、参数怎么校验、失败怎么回滚、权限怎么继承。",[10,1188,1189,1192],{},[106,1190,1191],{},"AI 鉴敏","：用语义分析识别用户行为与内容中的敏感信息，相比关键词匹配降低误判。它同样私有化部署在客户环境里，数据不出门。",[10,1194,1195,1196,1199],{},"这两个应用有一个共同约束：",[106,1197,1198],{},"私有化部署","。模型、向量、日志、工具调用都不能离开客户环境。这个约束会反过来影响架构：你不能依赖一个云端 LLM API 做所有事，要在本地做模型服务、缓存、降级和审计；你也不能把业务数据随便塞进第三方工具。",[10,1201,1202],{},"工具编排最容易犯的错误，是把「模型能调用」当成「模型可以随便调用」。我的做法是：每个工具都有明确的输入 schema、权限要求和失败语义；模型只负责选择工具和填参数，真正的执行、鉴权和审计由后端完成。这样即使模型选错工具，也不会越权。",[10,1204,1205],{},"权限模型也要按「用户身份」而不是「模型身份」设计。模型只是发起调用的一个环节，最终执行时仍然要带当前用户的身份、租户和角色；不能因为「是 AI 发起的」就绕过 RBAC。否则一次 prompt 注入，就可能变成一次越权操作。",[77,1207,1209],{"id":1208},"第三层数据与算法决定系统是不是越用越准","第三层：数据与算法，决定系统是不是「越用越准」",[10,1211,1212],{},"第三层最容易被忽略，但它决定 AI 应用是不是只有 demo 价值。",[10,1214,1215],{},"在用户行为分析场景里，系统每天采集千万级的桌面操作元事件。我们用 Python + Pandas \u002F NumPy 按业务配置的异常规则做清洗、转换与特征工程，归纳到约 30 万条样本、4–10 维特征（分类 + 数值），在模型效率与检出效果之间取平衡；日均百万级预测。",[10,1217,1218],{},"这一层的关键不是「用哪个模型」，而是「数据怎么变成可解释的特征」。异常规则来自业务，特征工程要能回答「为什么这个用户被判定为异常」；如果模型只给一个分数，客户环境里没人敢用。",[10,1220,1221],{},"另一块是事件序列关联分析。我独立设计并实现了一个轻量的事件序列正则引擎：",[87,1223,1224,1227,1238,1245,1248],{},[90,1225,1226],{},"词法 \u002F 语法分析 → AST → 后缀 IR → Thompson ε-NFA 构造与匹配；",[90,1228,1229,1230,1233,1234,1237],{},"支持并、连接、分组、有界重复 ",[129,1231,1232],{},"{n}"," 与无序组 ",[129,1235,1236],{},"\u003C...>","；",[90,1239,1240,1241,1244],{},"带 ",[129,1242,1243],{},"mustMatchPos"," 位置约束的反向匹配，保证刚到达的事件必须参与；",[90,1246,1247],{},"用字符集、长度 100、编译规模 3000、无序单元 5 四层约束规避灾难性回溯；",[90,1249,1250],{},"核心 pass 都有单元测试。",[10,1252,1253],{},[119,1254],{"alt":1255,"src":1256,"loading":123,"decoding":124},"事件序列正则引擎","\u002Fimages\u002Fevent-sequence-regex.svg",[10,1258,1259],{},"为什么不用现成的规则引擎？因为需求要的是「事件之间的顺序关系」：先打开某个页面，再复制，再外发，才算一条风险序列；中间允许无关事件，但关键事件必须按顺序出现。现成引擎要么表达不了无序组，要么在长序列上回溯失控。自己实现一个小而可控的引擎，反而更容易测试和解释。",[10,1261,1262,1263,1266],{},"这段经历给我的最大提醒是：",[106,1264,1265],{},"AI 工程不是只有模型。"," 数据怎么采、特征怎么造、规则怎么表达、失败怎么解释，往往比换一个更大的模型更能决定系统能不能上线。",[77,1268,1270],{"id":1269},"工程取舍为什么没有做-rag-和微调","工程取舍：为什么没有做 RAG 和微调",[10,1272,1273],{},"这套系统没有做 RAG，也没有做微调。不是这些技术不好，而是场景不匹配：",[87,1275,1276,1279,1282,1285],{},[90,1277,1278],{},"客户环境要求私有化，数据不能出门；",[90,1280,1281],{},"业务问题更多是「识别 + 路由 + 规则」，不是开放域问答；",[90,1283,1284],{},"微调需要稳定的标注数据和持续评估，项目周期内不成立；",[90,1286,1287],{},"先把模型服务、工具编排、数据闭环做稳，收益比追新更大。",[10,1289,1290],{},"同理，Triton 也不是唯一选择。如果只是低频调用，一个 Flask 服务就够了；但当你要批处理、要多模型仓库、要在 CPU\u002FGPU 之间切换、要做 warmup 和观测，Triton 的价值才会显现。技术选型应该由交付约束驱动，而不是由技术名词驱动。",[10,1292,1293],{},"这也是为什么我先把模型服务做稳，再做 LLM 应用。模型服务是底座：它不稳定，上面的工具编排再优雅也没有意义。反过来，底座稳定之后，LLM 层可以快速试错，因为每次失败都能定位到是工具、提示词还是模型服务。对一人项目来说，顺序比速度重要：先做能复用的底座，再做能讲故事的场景。",[10,1295,1296],{},"还有一个取舍是观测。模型服务的日志不能只记「请求成功\u002F失败」，还要记输入尺寸、批大小、推理耗时、CPU\u002FGPU、模型版本。否则线上变慢时，你无法判断是流量、模型还是环境的问题。",[77,1298,1299],{"id":1299},"常见失败模式",[87,1301,1302,1308,1314,1320,1326],{},[90,1303,1304,1307],{},[106,1305,1306],{},"OCR 质量不稳定","：图片模糊、倾斜、遮挡会显著影响识别；需要在前后处理里加入质量判断和降级策略。",[90,1309,1310,1313],{},[106,1311,1312],{},"CPU 吞吐不够","：没有 GPU 的客户环境，批处理和超时策略要重新设计，不能照搬 GPU 参数。",[90,1315,1316,1319],{},[106,1317,1318],{},"工具越权","：模型选错工具或填错参数，必须在后端做权限校验和参数校验。",[90,1321,1322,1325],{},[106,1323,1324],{},"数据漂移","：业务规则变化后，特征分布会变；需要定期回看样本和误判。",[90,1327,1328,1331],{},[106,1329,1330],{},"模型升级破坏契约","：输出格式、类别、阈值变化要有版本和回滚。",[10,1333,1334],{},"这些失败模式有一个共同点：它们都不是模型能力问题，而是工程问题。模型服务层要把它们当成一等公民，提前设计检测、降级和回滚，而不是等上线后再补。",[77,1336,390],{"id":390},[196,1338,1339,1342,1345,1348,1351,1354,1357],{},[90,1340,1341],{},"先把模型服务做成独立层，不要让业务代码直接加载模型。",[90,1343,1344],{},"前后处理也属于模型服务，不要散落在业务里。",[90,1346,1347],{},"私有化场景先设计降级路径：没有 GPU、没有外网、模型升级失败时怎么办。",[90,1349,1350],{},"LLM 应用先定义工具边界和权限，再谈 prompt。",[90,1352,1353],{},"数据与算法层要能解释「为什么命中」，否则无法在客户环境里维护。",[90,1355,1356],{},"不要为了追新引入 RAG\u002F微调；先确认场景真的需要。",[90,1358,1359],{},"吞吐数字要写清测试条件，不要把实验室数字当成生产承诺。",[77,1361,1363],{"id":1362},"回到一人交付","回到「一人交付」",[10,1365,1366],{},"这三层栈看起来是技术问题，其实也是交付问题：一个人要同时扮演模型工程师、后端工程师、数据工程师和运维，唯一的办法是把边界切清楚，让每一层都能独立验证。",[10,1368,1369,1370,1372,1373,1376,1377,1379],{},"这也是",[435,1371,5],{"href":449},"的核心：不是让一个人变成四个人，而是让一个人用流水线把四类工作组织起来。上一篇讲的是",[435,1374,1375],{"href":483},"一个人如何交付一套多租户 SaaS","，这一篇讲的是 AI 应用的三层栈；如果你还没看开篇，可以从",[435,1378,444],{"href":443},"开始。",[10,1381,1382,1383,1385,1386,1388],{},"想继续聊模型服务、工具编排或事件序列引擎，欢迎通过 ",[435,1384,457],{"href":456},"、知乎或公众号找到我；也可以先看看",[435,1387,773],{"href":772},"。",{"title":460,"searchDepth":461,"depth":461,"links":1390},[1391,1394,1395,1396,1397,1398,1399],{"id":1132,"depth":461,"text":1133,"children":1392},[1393],{"id":1164,"depth":469,"text":1164},{"id":1173,"depth":461,"text":1174},{"id":1208,"depth":461,"text":1209},{"id":1269,"depth":461,"text":1270},{"id":1299,"depth":461,"text":1299},{"id":390,"depth":461,"text":390},{"id":1362,"depth":461,"text":1363},"2026-11-24","从模型服务、LLM 工具编排到数据与算法，拆解一套私有化 AI 应用真正落地时需要一起设计的三层栈。",{},{"title":5,"description":1401},"posts\u002Fone-person-delivery-experiment-02-ai-engineering-stack",[1406,1407,1408,1409,1410,1198,491],"AI 工程","Triton","YOLOv5","PaddleOCR","LLM","rNCMl3flRYGj61oYWnsfKq-GAzuM871gRhG9mfiFDjY",{"id":1413,"title":5,"body":1414,"description":1424,"extension":478,"meta":1425,"navigation":479,"path":449,"seo":1426,"stem":1427,"__hash__":1428},"series\u002Fseries\u002Fone-person-delivery-experiment.md",{"type":7,"value":1415,"toc":1422},[1416,1419],[10,1417,1418],{},"「一人交付实验」不是一个「AI 取代团队」的口号，而是一组可复核的交付记录：一个人如何设计流水线、把任务切给 agent、用评审与测试守住质量，最后把软件真正交付出去。",[10,1420,1421],{},"这个专题会按项目阶段拆解：问题与约束、架构取舍、agent 编排、工程规范、失败路径与可复用清单。涉及客户与儿童信息时统一脱敏。",{"title":460,"searchDepth":461,"depth":461,"links":1423},[],"记录一个人借助 AI agent 流水线交付真实软件的过程：架构、工程规范、失败与可复用清单。",{},{"title":5,"description":1424},"series\u002Fone-person-delivery-experiment","bfRSrJJf1WaIA_RzLxzojaTAoNolLQz22jTVu87XQ0k",1794018033739]