
第1节 六条变现路全景:跳槽、接单、咨询、内容、产品、生态
一句话总结:循环工程的变现矩阵——技能溢价(跳槽/调薪)、项目制(接单)、咨询(审计+落地)、内容(课程/专栏)、SaaS(工具产品化)、生态(MCP/技能包);各路径的门槛×天花板×启动成本对照表,外加一个路径评分器和一份12个月现金流模拟。
本文导航
- 一、为什么变现需要一张地图:技能不等于收入
- 二、六条路径全景图
- 三、变现矩阵对照表
- 四、逐条路径的赚钱逻辑与锚点数据
- 五、路径选择决策:从现状到组合
- 六、代码实战:路径评分器与现金流模拟器
- 七、踩坑实录:我第一年犯的三个错
一、为什么变现需要一张地图:技能不等于收入
前面十三章,我们从一个 bash while 循环讲到票据库、验证器、Maker/Checker、子智能体编排,手上的技能已经足够搭一条生产级的 Agentic Loop 了。但从"会做"到"赚到"中间隔着一段没人替你规划的路,这一章就干这件事。
先泼一盆冷水。我在第2章引用过一组数据:84% 的人已经在用 AI,但只有 29% 的人敢信 AI 的输出。这中间 55 个百分点的信任缺口,才是付费意愿的来源——客户不是为"你会用 AI"付钱,是为"你敢对结果负责"付钱。循环工程的价值恰恰在这里:验证器、票据库、人审门禁,这一整套东西本质上都是在把信任变成工程问题。谁能兜住责任,谁就能收高风险溢价。
我自己吃过没有地图的亏。2026 年上半年 Loop Engineering 刚爆火那阵,我手里攥着一套现成的循环工具,看什么都像机会:朋友介绍的企业单想接,公众号想日更,GitHub 上的 MCP 想法列了一页纸,还顺手投了两份简历。两个月后复盘,四条线全在半空悬着——接单的单子没时间交付,公众号更了 9 篇断更,MCP 仓库写了 300 行躺在那,面试也因为没时间准备挂了。问题不是不努力,是没有按"门槛×天花板×现金流特征"给路径做排序,把精力当成了均摊的免费资源。
后来我强制自己做了一件很工程化的事:把所有变现可能列成六条路径,每条路径量化成五个参数(门槛、启动成本、风险、见效月数、每周投入),再把自己的现状也量化(经验、表达力、风险承受、可投入时间、现金储备),然后用代码算匹配分。这就是本节第六节那个评分器的由来。先看地图,再上路。
还有一个认知要先摆正:六条路径不是六选一,而是组合问题。课程里反复讲 Agentic Loop 的核心是"决策-执行-观察-再决策",变现这件事也一样——选组合、跑三个月、观察数据、再平衡。把它当成一个持续运行的循环,而不是一次性决定。
二、六条路径全景图
六条路径围绕同一个技能内核——循环工程——展开,但变现的"收费单位"完全不同:跳槽卖的是履历,接单卖的是交付物,咨询卖的是判断,内容卖的是注意力,SaaS 卖的是订阅,生态卖的是分发。
#mermaid-svg-it3olZnm2IrGS4KU{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-it3olZnm2IrGS4KU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-it3olZnm2IrGS4KU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-it3olZnm2IrGS4KU .error-icon{fill:#552222;}#mermaid-svg-it3olZnm2IrGS4KU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-it3olZnm2IrGS4KU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-it3olZnm2IrGS4KU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-it3olZnm2IrGS4KU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-it3olZnm2IrGS4KU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-it3olZnm2IrGS4KU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-it3olZnm2IrGS4KU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-it3olZnm2IrGS4KU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-it3olZnm2IrGS4KU .marker.cross{stroke:#333333;}#mermaid-svg-it3olZnm2IrGS4KU svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-it3olZnm2IrGS4KU p{margin:0;}#mermaid-svg-it3olZnm2IrGS4KU .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-it3olZnm2IrGS4KU .cluster-label text{fill:#333;}#mermaid-svg-it3olZnm2IrGS4KU .cluster-label span{color:#333;}#mermaid-svg-it3olZnm2IrGS4KU .cluster-label span p{background-color:transparent;}#mermaid-svg-it3olZnm2IrGS4KU .label text,#mermaid-svg-it3olZnm2IrGS4KU span{fill:#333;color:#333;}#mermaid-svg-it3olZnm2IrGS4KU .node rect,#mermaid-svg-it3olZnm2IrGS4KU .node circle,#mermaid-svg-it3olZnm2IrGS4KU .node ellipse,#mermaid-svg-it3olZnm2IrGS4KU .node polygon,#mermaid-svg-it3olZnm2IrGS4KU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-it3olZnm2IrGS4KU .rough-node .label text,#mermaid-svg-it3olZnm2IrGS4KU .node .label text,#mermaid-svg-it3olZnm2IrGS4KU .image-shape .label,#mermaid-svg-it3olZnm2IrGS4KU .icon-shape .label{text-anchor:middle;}#mermaid-svg-it3olZnm2IrGS4KU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-it3olZnm2IrGS4KU .rough-node .label,#mermaid-svg-it3olZnm2IrGS4KU .node .label,#mermaid-svg-it3olZnm2IrGS4KU .image-shape .label,#mermaid-svg-it3olZnm2IrGS4KU .icon-shape .label{text-align:center;}#mermaid-svg-it3olZnm2IrGS4KU .node.clickable{cursor:pointer;}#mermaid-svg-it3olZnm2IrGS4KU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-it3olZnm2IrGS4KU .arrowheadPath{fill:#333333;}#mermaid-svg-it3olZnm2IrGS4KU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-it3olZnm2IrGS4KU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-it3olZnm2IrGS4KU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-it3olZnm2IrGS4KU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-it3olZnm2IrGS4KU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-it3olZnm2IrGS4KU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-it3olZnm2IrGS4KU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-it3olZnm2IrGS4KU .cluster text{fill:#333;}#mermaid-svg-it3olZnm2IrGS4KU .cluster span{color:#333;}#mermaid-svg-it3olZnm2IrGS4KU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-it3olZnm2IrGS4KU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-it3olZnm2IrGS4KU rect.text{fill:none;stroke-width:0;}#mermaid-svg-it3olZnm2IrGS4KU .icon-shape,#mermaid-svg-it3olZnm2IrGS4KU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-it3olZnm2IrGS4KU .icon-shape p,#mermaid-svg-it3olZnm2IrGS4KU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-it3olZnm2IrGS4KU .icon-shape .label rect,#mermaid-svg-it3olZnm2IrGS4KU .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-it3olZnm2IrGS4KU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-it3olZnm2IrGS4KU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-it3olZnm2IrGS4KU :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
循环工程技能Agentic Loop + 验证器 + 票据库
1.跳槽/调薪技能溢价
2.项目接单按交付物收费
3.企业咨询审计+落地
4.内容课程/专栏/广告
5.SaaS产品工具产品化订阅
6.生态MCP/技能包/插件
现金流特征:稳定天花板:高
现金流特征:项目制波动天花板:中高
现金流特征:高单价低频天花板:高
现金流特征:复利累积天花板:中
现金流特征:先投入后回收天花板:极高
现金流特征:长尾被动天花板:中
注意这张图的关键信息不是六个盒子,而是下面那行"现金流特征"。选路径时人最容易只盯天花板看(SaaS 天花板极高!),而忽略现金流形状(SaaS 是先烧 6-12 个月才见收入的类型)。天花板决定你三年后在哪,现金流形状决定你能不能活到三年后。
三、变现矩阵对照表
把六条路径放进同一张表里对比。这张表建议你存下来,选路之前先扫一遍:
| 跳槽/调薪 | 中 | 高(年薪百万) | 低 | 1-3月 | 在职者 |
| 项目接单 | 中 | 中高(月入3-8万) | 低 | 1-2月 | 独立开发者 |
| 咨询 | 高 | 高(日薪5000-2万) | 中 | 2-4月 | 资深者 |
| 内容 | 低 | 中(月入1-5万) | 低 | 3-6月 | 任何人 |
| SaaS产品 | 高 | 极高 | 高 | 6-12月 | 创业者 |
| 生态 | 中 | 中 | 中 | 3-6月 | 开发者 |
光看这张表还不够,我再补三个隐藏维度,都是实际跑过之后才发现重要的:
| 跳槽/调薪 | 主动收入 | 低(换公司清零重谈) | 低 | 面试表达+作品集 |
| 项目接单 | 主动收入 | 中(口碑滚动) | 中(平台/客户集中) | 报价+合同+交付管理 |
| 咨询 | 主动收入 | 中高(案例背书滚动) | 低 | 审计方法论+向上沟通 |
| 内容 | 被动+主动混合 | 高(长尾流量持续) | 中(平台规则变化) | 选题+持续输出 |
| SaaS产品 | 被动收入 | 极高(MRR累积) | 高(九死一生) | 产品+销售+运维全栈 |
| 生态 | 被动收入 | 高(一次写作反复分发) | 中(生态平台政策) | 开源运营+英文文档 |
两表合起来看,有两条结论值得单独说:
四、逐条路径的赚钱逻辑与锚点数据
每条路径给一段"赚钱逻辑+国内锚点",细节在后面六节各自展开,这里先建立全局体感。
1. 跳槽/调薪:把课程项目变成议价筹码。 第2章引用过的数据在这里直接用:Agent 工程师岗位一年暴增 789%,平均月薪 63160 元;全球岗位薪资中位数 $217K,且 98% 的岗位只要中级以上。供需失衡意味着"能证明自己搭过生产级循环"的人在谈判桌上是稀缺方。关键动作是把第13章的综合项目整理成作品集:一条 PR 审查全自动流水线、真实成功率数据、成本曲线。面谈时能掏出"我的循环把审查成功率从 71% 调到 91.6%,这是调优日志"的人,和只会说"我了解 LangChain"的人,报价差一倍很正常。
2. 项目接单:卖交付物,不卖工时。 国内中小商家自动内容工厂月费 ¥3000-8000,品牌方 ¥8000-20000;海外 Upwork 月费 $500-2000。三条接单线(内容工厂/屎山改造/企业咨询落地)分别在后面三节展开,这里先记一个总原则:循环工程接单的本质是你用自动化把"脏活累活"的成本打下来,报价按"客户原来的痛"定价,而不是按"你花了多少机器时间"定价。机器跑一夜成本可能就几十块,但对客户值几万。
3. 咨询:卖判断,收的是责任费。 国内日薪 ¥3000-8000,项目制 ¥5-20 万。咨询的高单价来自两件事:一是审计方法论(第4节那套工具/流程/数据三维度打分),二是你敢在 ROI 上签字。企业客户买咨询买的其实是"有人替我把技术翻译成钱,并且错了能追责"。
4. 内容:把学习过程变成资产。 CSDN 付费专栏、公众号流量主+知识星球、B站充电、视频号带货课程,组合下来月入 1-5 万是可达到的区间(第5节展开)。内容路径还有一个隐藏福利:它是其他五条路径的获客漏斗——我现在的接单客户,一半以上是先看了我的踩坑文章找过来的。
5. SaaS产品:从自用工具到订阅收入。 把自己接单用的内部循环工具抽象成垂直场景产品。参考锚点:Cursor 用 $20/月的个人订阅做到 $2B ARR;Devin 走 $500/月起的企业座席。国内做 SaaS 还要额外过合规关(第6节讲)。这条路径门槛最高,但天花板也最高。
6. 生态:一次写作,反复分发。 MCP 服务器生态已经过万,但企业内部系统集成、垂直行业工具仍有品类空缺;技能包(SKILL.md 格式)$5-30/个,托管版 MCP $10-50/月。生态位的妙处在于边际成本趋近于零:一个 MCP 服务器写完,100 个客户用和 1000 个客户用,你的维护成本差别不大。
六条路径的收入量级和成熟速度,用一张表粗略锚定(数值为国内市场 2026 年观察值,具体因城市和行业浮动):
| 跳槽/调薪 | 涨薪30%-80% | 年薪40-100万 | 岗位窗口期 |
| 项目接单 | 月入1-3万 | 月入3-8万 | 交付产能 |
| 咨询 | 单量零星 | 日薪5000-2万 | 信任背书 |
| 内容 | 月入0-5000 | 月入1-5万 | 持续输出 |
| SaaS产品 | 收入≈0(投入期) | MRR数万-数十万 | 产品市场匹配 |
| 生态 | 月入0-2000 | 月入0.5-3万 | 分发量 |
五、路径选择决策:从现状到组合
选路径的决策树不长这样——"你擅长什么就选什么"是错的。正确的问法是先问现状:现金储备能撑几个月?每周有多少小时是真正可支配的?风险承受力是心理问题更是数学问题。
#mermaid-svg-AaUCrSX8ttO9itaH{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AaUCrSX8ttO9itaH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AaUCrSX8ttO9itaH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AaUCrSX8ttO9itaH .error-icon{fill:#552222;}#mermaid-svg-AaUCrSX8ttO9itaH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AaUCrSX8ttO9itaH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AaUCrSX8ttO9itaH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AaUCrSX8ttO9itaH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AaUCrSX8ttO9itaH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AaUCrSX8ttO9itaH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AaUCrSX8ttO9itaH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AaUCrSX8ttO9itaH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AaUCrSX8ttO9itaH .marker.cross{stroke:#333333;}#mermaid-svg-AaUCrSX8ttO9itaH svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AaUCrSX8ttO9itaH p{margin:0;}#mermaid-svg-AaUCrSX8ttO9itaH .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-AaUCrSX8ttO9itaH .cluster-label text{fill:#333;}#mermaid-svg-AaUCrSX8ttO9itaH .cluster-label span{color:#333;}#mermaid-svg-AaUCrSX8ttO9itaH .cluster-label span p{background-color:transparent;}#mermaid-svg-AaUCrSX8ttO9itaH .label text,#mermaid-svg-AaUCrSX8ttO9itaH span{fill:#333;color:#333;}#mermaid-svg-AaUCrSX8ttO9itaH .node rect,#mermaid-svg-AaUCrSX8ttO9itaH .node circle,#mermaid-svg-AaUCrSX8ttO9itaH .node ellipse,#mermaid-svg-AaUCrSX8ttO9itaH .node polygon,#mermaid-svg-AaUCrSX8ttO9itaH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AaUCrSX8ttO9itaH .rough-node .label text,#mermaid-svg-AaUCrSX8ttO9itaH .node .label text,#mermaid-svg-AaUCrSX8ttO9itaH .image-shape .label,#mermaid-svg-AaUCrSX8ttO9itaH .icon-shape .label{text-anchor:middle;}#mermaid-svg-AaUCrSX8ttO9itaH .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-AaUCrSX8ttO9itaH .rough-node .label,#mermaid-svg-AaUCrSX8ttO9itaH .node .label,#mermaid-svg-AaUCrSX8ttO9itaH .image-shape .label,#mermaid-svg-AaUCrSX8ttO9itaH .icon-shape .label{text-align:center;}#mermaid-svg-AaUCrSX8ttO9itaH .node.clickable{cursor:pointer;}#mermaid-svg-AaUCrSX8ttO9itaH .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-AaUCrSX8ttO9itaH .arrowheadPath{fill:#333333;}#mermaid-svg-AaUCrSX8ttO9itaH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AaUCrSX8ttO9itaH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AaUCrSX8ttO9itaH .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AaUCrSX8ttO9itaH .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-AaUCrSX8ttO9itaH .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AaUCrSX8ttO9itaH .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-AaUCrSX8ttO9itaH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AaUCrSX8ttO9itaH .cluster text{fill:#333;}#mermaid-svg-AaUCrSX8ttO9itaH .cluster span{color:#333;}#mermaid-svg-AaUCrSX8ttO9itaH div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-AaUCrSX8ttO9itaH .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-AaUCrSX8ttO9itaH rect.text{fill:none;stroke-width:0;}#mermaid-svg-AaUCrSX8ttO9itaH .icon-shape,#mermaid-svg-AaUCrSX8ttO9itaH .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AaUCrSX8ttO9itaH .icon-shape p,#mermaid-svg-AaUCrSX8ttO9itaH .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-AaUCrSX8ttO9itaH .icon-shape .label rect,#mermaid-svg-AaUCrSX8ttO9itaH .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AaUCrSX8ttO9itaH .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-AaUCrSX8ttO9itaH .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-AaUCrSX8ttO9itaH :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
在职且只想涨薪
有10小时以上空余想先赚到第一笔
8年以上经验有行业人脉
能稳定周更表达欲强
有12个月现金储备有明确场景
英文文档能力强喜欢开源
是
暂不
你的现状?
跳槽/调薪1-3个月准备作品集
项目接单从熟人单起步
咨询先做免费审计换案例
内容专栏+公众号双开
SaaS先做内部工具验证
生态MCP/技能包
是否组合?
推荐:接单+内容现金流+复利资产双轨
单路径跑通再加线
我的判断标准浓缩成一句话:一条现金流路径(接单或在职)+ 一条复利资产路径(内容或生态),是绝大多数人的最优起点。咨询等有了 2-3 个成功案例再开价,SaaS 等你从接单里发现重复出现的需求再动手——需求是从交付里长出来的,不是想出来的。
六、代码实战:路径评分器与现金流模拟器
这一节上两个工具:一个解决"选哪些线"(路径评分器),一个解决"组合起来现金流长什么样"(12个月现金流模拟器)。两个都是 pydantic 校验+日志双输出的工程化写法,参数直接可改复用。
实战一:变现路径评分器
光有决策树还是偏感性,我把六条路径和个人现状都量化,写了个评分器。技能画像用 pydantic 校验,跑起来是这个项目里的第一个"商业工具"代码。先看数据模型和评分逻辑:
# path_scorer.py
"""六条变现路径评分器:按个人现状算匹配分,输出排序与推荐组合。
架构:
UserProfile(个人现状) ──┐
PATHS(六条路径画像) ────┴─> score() 加权评分 ─> 排序输出 + 推荐组合
工程规范:pydantic校验 / logging双输出按月分割保留12个月
"""
import logging
import sys
from datetime import datetime
from pathlib import Path
from pydantic import BaseModel, Field
sys.stdout.reconfigure(encoding="utf-8")
sys.stderr.reconfigure(encoding="utf-8")
# ———- 日志基建(精简版:控制台+文件双输出,按月分割,保留12个月) ———-
class MonthlyFileHandler(logging.FileHandler):
"""按月滚动日志文件:跨月自动切换到 app-YYYY-MM.log"""
def __init__(self, log_dir: Path):
self.log_dir = Path(log_dir)
self.month = datetime.now().strftime("%Y-%m")
super().__init__(self._path(), mode="a", encoding="utf-8")
def _path(self) –> str:
return str(self.log_dir / f"app-{self.month}.log")
def emit(self, record: logging.LogRecord) –> None:
now = datetime.now().strftime("%Y-%m")
if now != self.month: # 跨月:关旧句柄、开新文件
self.month = now
self.close()
self.baseFilename = self._path()
self.stream = self._open()
super().emit(record)
def setup_logging(name: str = "ch14") –> logging.Logger:
"""初始化双输出日志,并清理超过12个月的历史文件"""
log_dir = Path("logs"); log_dir.mkdir(exist_ok=True)
logger = logging.getLogger(name)
logger.setLevel(logging.INFO)
logger.handlers.clear() # 幂等:防重复输出
ch = logging.StreamHandler()
ch.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s", "%H:%M:%S"))
fh = MonthlyFileHandler(log_dir)
fh.setFormatter(logging.Formatter("%(asctime)s | %(levelname)-8s | %(message)s"))
logger.addHandler(ch); logger.addHandler(fh)
now = datetime.now()
for f in log_dir.glob("app-*.log"): # 保留12个月
try:
m = datetime.strptime(f.stem.removeprefix("app-"), "%Y-%m")
except ValueError:
continue
if (now.year – m.year) * 12 + now.month – m.month > 12:
f.unlink()
return logger
log = setup_logging()
# ———- 数据模型:pydantic 校验 ———-
class PathProfile(BaseModel):
"""一条变现路径的画像(1-5分制,5为最高)"""
name: str
threshold: int = Field(ge=1, le=5, description="门槛:技能/经验/资历要求")
cost: int = Field(ge=1, le=5, description="启动成本:资金+时间投入")
risk: int = Field(ge=1, le=5, description="收入波动风险")
months_to_revenue: int = Field(ge=0, le=12, description="见效月数")
hours_per_week: int = Field(ge=0, description="每周需投入小时")
class UserProfile(BaseModel):
"""个人现状快照"""
employed: bool = True # 是否在职
years: int = Field(ge=0, le=20, description="开发经验年数")
express: int = Field(ge=1, le=5, description="表达/写作能力")
risk: int = Field(ge=1, le=5, description="风险承受力")
hours_per_week: int = Field(ge=0, description="每周可投入小时")
savings_months: int = Field(ge=0, description="现金储备可撑月数")
# 六条路径画像(与正文对照表一致)
PATHS = [
PathProfile(name="跳槽/调薪", threshold=3, cost=1, risk=1, months_to_revenue=2, hours_per_week=8),
PathProfile(name="项目接单", threshold=3, cost=2, risk=3, months_to_revenue=1, hours_per_week=20),
PathProfile(name="企业咨询", threshold=5, cost=3, risk=3, months_to_revenue=3, hours_per_week=12),
PathProfile(name="内容变现", threshold=2, cost=1, risk=3, months_to_revenue=4, hours_per_week=10),
PathProfile(name="SaaS产品", threshold=5, cost=5, risk=5, months_to_revenue=9, hours_per_week=30),
PathProfile(name="MCP生态", threshold=3, cost=3, risk=3, months_to_revenue=4, hours_per_week=10),
]
def skill_level(u: UserProfile) –> int:
"""由经验+表达力折算综合能力等级(1-5)"""
return max(1, min(5, round(u.years / 4 + 0.6) + (1 if u.express >= 4 else 0)))
def resource_level(u: UserProfile) –> int:
"""由现金储备+可投入时间折算资源等级(1-5)"""
return max(1, min(5, u.savings_months // 3 + u.hours_per_week // 15))
def score(p: PathProfile, u: UserProfile) –> float:
"""加权评分:能力/资源/风险/见效/时间 四维加权,输出0-100"""
ability = 5 – max(0, p.threshold – skill_level(u)) # 能力匹配
resource = 5 – max(0, p.cost – resource_level(u)) # 资源匹配
safety = 5 – max(0, p.risk – u.risk) + (1 if u.employed else 0) # 风险匹配(在职可加分)
speed = 6 – min(6, p.months_to_revenue) # 见效越快分越高
fit_hours = 5 if u.hours_per_week >= p.hours_per_week else round(5 * u.hours_per_week / p.hours_per_week)
return round((0.35 * ability + 0.2 * resource + 0.2 * safety + 0.15 * speed + 0.1 * fit_hours) * 20, 1)
def main() –> None:
me = UserProfile(employed=True, years=5, express=4, risk=3, hours_per_week=18, savings_months=6)
log.info(f"个人画像: {me.model_dump()}")
ranked = sorted(((score(p, me), p) for p in PATHS), key=lambda x: –x[0])
log.info("=" * 56)
log.info(f"{'路径':<8}{'匹配分':>8} 门槛 成本 风险 见效(月) 周小时")
for s, p in ranked:
bar = "█" * int(s // 10)
log.info(f"{p.name:<8}{s:>8} {bar:<10} {p.threshold:>4} {p.cost:>4} {p.risk:>4} {p.months_to_revenue:>6} {p.hours_per_week:>6}")
top3 = [p.name for _, p in ranked[:3]]
combo = [n for n in ["内容变现", "项目接单", "MCP生态"] if n in top3] or top3[:2]
log.info("=" * 56)
log.info(f"推荐组合(2-3条并行): {' + '.join(combo)}")
log.info("原则:一条现金流(接单/在职)+ 一条复利资产(内容/生态)+ 视情况一条高天花板(咨询/SaaS)")
if __name__ == "__main__":
main()
以我自己当时的画像(在职、5年经验、表达力4、风险承受3、每周18小时、储备6个月)跑出来的真实输出:
12:07:32 INFO 个人画像: {'employed': True, 'years': 5, 'express': 4, 'risk': 3, 'hours_per_week': 18, 'savings_months': 6}
12:07:32 INFO ========================================================
12:07:32 INFO 路径 匹配分 门槛 成本 风险 见效(月) 周小时
12:07:32 INFO 项目接单 102.0 ██████████ 3 2 3 1 20
12:07:32 INFO 跳槽/调薪 101.0 ██████████ 3 1 1 2 8
12:07:32 INFO 内容变现 95.0 █████████ 2 1 3 4 10
12:07:32 INFO MCP生态 95.0 █████████ 3 3 3 4 10
12:07:32 INFO 企业咨询 84.0 ████████ 5 3 3 3 12
12:07:32 INFO SaaS产品 55.0 █████ 5 5 5 9 30
12:07:32 INFO ========================================================
12:07:32 INFO 推荐组合(2-3条并行): 内容变现 + 项目接单
12:07:32 INFO 原则:一条现金流(接单/在职)+ 一条复利资产(内容/生态)+ 视情况一条高天花板(咨询/SaaS)
几个实现细节值得说。第一,匹配分超过 100 不是 bug——safety 里在职者加了 1 分裸分再乘权重放大,说明这个模型的输出是相对排序而不是绝对分,看名次别看绝对值。第二,SaaS 拿 55 分不是因为它不好,而是它对这个画像(每周只有 18 小时)严重不匹配:SaaS 需要每周 30 小时,fit_hours 项直接砍半。换个失业但有 18 个月储备的画像,排序会完全变样——你可以自己改参数跑。第三,日志走了控制台+文件双输出,月度文件 logs/app-2026-09.log 里字段用 | 分隔,三个月后回看"我当时为什么这么选",证据都在。
踩坑提示:评分器最大的坑是参数自欺。风险承受力填 5 的人,往往没经历过连续三个月零收入。我的校准方法是拿真实历史问自己:上一次收入砍半时我是什么反应?如果答案是"焦虑到失眠",风险承受力就是 2,不是 5。参数诚实,排序才有用。
实战二:组合策略的12个月现金流模拟
评分器解决"选哪些线",第二个工具解决"组合起来现金流长什么样"。模型很简单:每条路径有起始月、爬坡期、天花板、成交概率期望和月成本,净收入 = 天花板 × 爬坡系数 × 概率期望 – 成本。
# portfolio_sim.py
"""组合策略现金流模拟器:单路径 vs 组合路径的12个月收入推演。
模型:每月净收入 = 天花板 × 爬坡系数 × 成交概率期望 – 月成本
爬坡系数 = min(1, max(0, (月份 – 起始月 + 1) / 爬坡期))
"""
import logging
import sys
from pathlib import Path
from pydantic import BaseModel, Field
sys.stdout.reconfigure(encoding="utf-8"); sys.stderr.reconfigure(encoding="utf-8")
Path("logs").mkdir(exist_ok=True) # 日志目录先建好,FileHandler 才能打开
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s", datefmt="%H:%M:%S",
handlers=[logging.StreamHandler(), logging.FileHandler("logs/sim-2026-09.log", encoding="utf-8")])
log = logging.getLogger("sim")
class PathSim(BaseModel):
"""单条路径的现金流参数"""
name: str
start_month: int = Field(ge=1, le=12, description="第几个月开始有收入")
ramp_months: int = Field(ge=1, description="爬坡到天花板所需月数")
ceiling: float = Field(gt=0, description="成熟期月收入(元)")
win_rate: float = Field(gt=0, le=1, description="成交/成功概率期望")
monthly_cost: float = Field(ge=0, description="月成本(API/工具/外包)")
def revenue(self, m: int) –> float:
"""第m个月的净收入(爬坡×概率期望 – 成本)"""
ramp = min(1.0, max(0.0, (m – self.start_month + 1) / self.ramp_months))
return self.ceiling * ramp * self.win_rate – self.monthly_cost
# 三种策略的路径组合(与正文组合策略对应)
PLANS = {
"单干接单": [PathSim(name="接单", start_month=2, ramp_months=3, ceiling=30000, win_rate=0.8, monthly_cost=1500)],
"内容+接单": [PathSim(name="内容", start_month=3, ramp_months=6, ceiling=12000, win_rate=0.7, monthly_cost=400),
PathSim(name="接单", start_month=2, ramp_months=3, ceiling=26000, win_rate=0.75, monthly_cost=1500)],
"内容+接单+咨询": [PathSim(name="内容", start_month=3, ramp_months=6, ceiling=12000, win_rate=0.7, monthly_cost=400),
PathSim(name="接单", start_month=2, ramp_months=3, ceiling=22000, win_rate=0.7, monthly_cost=1300),
PathSim(name="咨询", start_month=5, ramp_months=4, ceiling=30000, win_rate=0.5, monthly_cost=800)],
}
def simulate(plan_name: str, paths: list[PathSim]) –> None:
"""推演12个月并打印月度现金流表"""
log.info(f"== 策略: {plan_name} ==")
log.info("月份 " + "".join(f"{p.name:>10}" for p in paths) + f"{'合计':>12}{'累计':>12}")
cum = 0.0
for m in range(1, 13):
rows = [p.revenue(m) for p in paths]
total, cum = sum(rows), cum + sum(rows)
log.info(f"{m:>3}月 " + "".join(f"{v:>10,.0f}" for v in rows) + f"{total:>12,.0f}{cum:>12,.0f}")
log.info(f"第12个月单月: {sum(p.revenue(12) for p in paths):,.0f}元 | "
f"12个月累计: {cum:,.0f}元 | 月均: {cum/12:,.0f}元\\n")
def main() –> None:
for name, paths in PLANS.items():
simulate(name, paths)
log.info("结论:组合策略前期更累,但第8-10个月后曲线明显上扬,且单点失效不会归零。")
if __name__ == "__main__":
main()
真实运行输出(三种策略横向对比):
12:07:33 INFO == 策略: 单干接单 ==
12:07:33 INFO 月份 接单 合计 累计
12:07:33 INFO 1月 -1,500 -1,500 -1,500
12:07:33 INFO 2月 6,500 6,500 5,000
12:07:33 INFO 3月 14,500 14,500 19,500
12:07:33 INFO 4月 22,500 22,500 42,000
12:07:33 INFO 5月 22,500 22,500 64,500
12:07:33 INFO 6月 22,500 22,500 87,000
12:07:33 INFO 7月 22,500 22,500 109,500
12:07:33 INFO 8月 22,500 22,500 132,000
12:07:33 INFO 9月 22,500 22,500 154,500
12:07:33 INFO 10月 22,500 22,500 177,000
12:07:33 INFO 11月 22,500 22,500 199,500
12:07:33 INFO 12月 22,500 22,500 222,000
12:07:33 INFO 第12个月单月: 22,500元 | 12个月累计: 222,000元 | 月均: 18,500元
12:07:33 INFO == 策略: 内容+接单 ==
12:07:33 INFO 月份 内容 接单 合计 累计
12:07:33 INFO 1月 -400 -1,500 -1,900 -1,900
12:07:33 INFO 2月 -400 5,000 4,600 2,700
12:07:33 INFO 3月 1,000 11,500 12,500 15,200
12:07:33 INFO 4月 2,400 18,000 20,400 35,600
12:07:33 INFO 5月 3,800 18,000 21,800 57,400
12:07:33 INFO 6月 5,200 18,000 23,200 80,600
12:07:33 INFO 7月 6,600 18,000 24,600 105,200
12:07:33 INFO 8月 8,000 18,000 26,000 131,200
12:07:33 INFO 9月 8,000 18,000 26,000 157,200
12:07:33 INFO 10月 8,000 18,000 26,000 183,200
12:07:33 INFO 11月 8,000 18,000 26,000 209,200
12:07:33 INFO 12月 8,000 18,000 26,000 235,200
12:07:33 INFO 第12个月单月: 26,000元 | 12个月累计: 235,200元 | 月均: 19,600元
12:07:33 INFO == 策略: 内容+接单+咨询 ==
12:07:33 INFO 月份 内容 接单 咨询 合计 累计
12:07:33 INFO 1月 -400 -1,300 -800 -2,500 -2,500
12:07:33 INFO 2月 -400 3,833 -800 2,633 133
12:07:33 INFO 3月 1,000 8,967 -800 9,167 9,300
12:07:33 INFO 4月 2,400 14,100 -800 15,700 25,000
12:07:33 INFO 5月 3,800 14,100 2,950 20,850 45,850
12:07:33 INFO 6月 5,200 14,100 6,700 26,000 71,850
12:07:33 INFO 7月 6,600 14,100 10,450 31,150 103,000
12:07:33 INFO 8月 8,000 14,100 14,200 36,300 139,300
12:07:33 INFO 9月 8,000 14,100 14,200 36,300 175,600
12:07:33 INFO 10月 8,000 14,100 14,200 36,300 211,900
12:07:33 INFO 11月 8,000 14,100 14,200 36,300 248,200
12:07:33 INFO 12月 8,000 14,100 14,200 36,300 284,500
12:07:33 INFO 第12个月单月: 36,300元 | 12个月累计: 284,500元 | 月均: 23,708元
12:07:33 INFO 结论:组合策略前期更累,但第8-10个月后曲线明显上扬,且单点失效不会归零。
读这份输出时注意三个数字背后的含义。第2个月:三线组合是 133 元,几乎打平——组合策略前四个月是真金白银地比单线少赚,因为接单天花板被压缩(从 30000 降到 22000,腾时间给内容和咨询),而新线还在爬坡。第8个月:三线组合月收入 36300 元反超单线的 22500 元约 61%。12个月累计:284500 vs 222000,多出 62500 元,而且这个差距在第二年会继续拉大,因为内容和咨询还在复利曲线上。
模型里我特意保留了 win_rate(成交概率期望)这个参数,而不是按满血收入算。接单 0.7-0.8 是"报价十单成七八单"的现实值,咨询只有 0.5——咨询单量少但单价高,半年成一单也够。用期望值而不是最好情况做规划,是所有商业模拟的底线。
七、踩坑实录:我第一年犯的三个错
地图画完了,最后交三个学费买来的教训。
错一:六线全开,精力均摊。 开头讲过,两个月四条线全悬空。修复动作是砍到两条:接单+内容。砍的时候肉疼——MCP 那个仓库真的写了一半。但后来想通了:未完成的路径不只是不赚钱,它还在持续消耗你的心理账户。砍线不是放弃,是把想法记进 backlog,等现金流稳定后再启动。
错二:把跳槽当保底,低估了它的机会成本。 有段时间我把"大不了跳槽"挂在嘴边,结果面试准备断断续续耗了一个多月,简历改了八版。跳槽看似门槛低,实际是一次性重仓决策:入职后你的时间就整体卖给岗位了,其他路径的时间预算瞬间归零。正确姿势是给跳槽一个明确的启动条件(比如"接单收入连续三个月低于 X")和截止时间(三周内完成所有面试),当成项目去打,而不是当退路供着。
错三:内容当兴趣做,没当资产管。 前九篇公众号文章我随手写随手发,没有选题矩阵、没有数据复盘,阅读量全凭运气。直到把第5节那套选题打分和一稿多发流水线搭起来,同样的写作时间,单篇平均阅读翻了三倍。内容是六条路径里唯一"边际成本递减"的,值得用工程方法管理——毕竟这套课程本身就是这么被管理出来的。
一句话收束本章开局:技能决定你能做什么,组合决定你能赚多少,纪律决定你能赚多久。 接下来三节进入实战:内容工厂、屎山改造、企业咨询,三单生意从获客到回款全程拆解。
小结
- 六条路径:跳槽(卖履历)、接单(卖交付物)、咨询(卖判断)、内容(卖注意力)、SaaS(卖订阅)、生态(卖分发),收费单位完全不同,不能只比数字。
- 对照表是双维的:门槛×天花板×启动成本之外,还要看现金流形态和复利性——天花板决定三年后在哪,现金流形态决定能不能活到三年后。
- 组合优于单线:一条现金流路径+一条复利资产路径是大多数人的最优起点;模拟显示组合策略第8个月起反超单线 61%,且抗单点失效。
- 两个工具:路径评分器(量化选路)和现金流模拟器(期望值规划),都是 pydantic 校验+日志双输出的工程化写法,直接可改参数复用。
- 用期望值做规划:成交概率 0.5-0.8 的现实参数比满血假设有用得多。
下节预告
第14章第2节《接单实战一:中小商家"自动内容工厂"》——第一单生意从哪来、方案怎么设计、¥3000 到 ¥20000 的报价怎么谈,附完整内容工厂脚本和成本核算表。
如果觉得本文对你有帮助,欢迎点赞、收藏、关注三连! 本系列持续更新中,关注不迷路~
文章编号:第14章第1节 | 总进度:98/120 | 预计阅读时间:18分钟(含完整代码)
网硕互联帮助中心



评论前必须登录!
注册