🤖 第五章 应用实战:知乎图文创作和发布助手
📄 一句话概括

本章的流程是 7 个节点 + 一张交接台。与 4.2 相比,结构没大变,但多了一个前三章都没有的节点:补人味——它只能人做,却决定了后面所有环节的安全性。所以本节最要紧的一件事是:把这个节点【从正文里拿出来,单独立一格】,因为塞在别处的工序一定会被忘掉。

📝 本节和前面几节的关系

5.1.1 讲清了知乎难在哪(存量竞争、判定看文本特征、处置分五档),5.1.2 算清了三笔价值(时间/长尾/风险)。本节把这两件事变成一张图和一个表,交给 5.3(Agent 侧)与 5.4(RPA 侧)去填。本节是全章的地图。

一、全章结构总图

                    ┌─────────────────── Agent 侧(5.3)───────────────────┐
                    │  ① 拆对标  →  ② 出初稿                                │
                    └──────────────────────┬──────────────────────────────┘
                                           │
                                    ┌──────▼──────┐
                                    │  ③ 补人味   │  ← 人在此把关(只能人做)
                                    └──────┬──────┘
                                           │
                    ┌──────────────────────▼─────────────── RPA 侧(5.4)──┐
                    │  ④ 发起会话取稿  →  ⑤ 墨滴排版  →  ⑥ 填字段入编辑器   │
                    └──────────────────────┬───────────────────────────────┘
                                           │
                                    ┌──────▼──────┐
                                    │  ⑦ 设声明   │  ← 人在此把关(合规动作)
                                    │   → 点发布  │
                                    └─────────────┘

两条线、两个闸门。 与前三章的骨架完全一致(Agent 负责想、RPA 负责做、人在关键点把关),变的是闸门的位置和理由:

闸门 位置 为什么在这儿
闸门一:补人味 Agent 出稿之后、RPA 接手之前 因为人味必须由人补进正文里——机器一旦接手排版和填字段,正文就定型了。这个位置是流程设计里最需要想清楚的一个决定
闸门二:设声明+发布 RPA 填完之后 因为声明是责任声明(知乎那一档的原文就叫【作者对内容负责】),责任不能由机器签
⚠️ 闸门一为什么不能放在最后

一个很容易犯的设计错误:把【补人味】放到最后——排版完了、字段填好了,让作者最后读一遍顺手改两句。 为什么不行:因为最后那一步人面对的是一份【已经完整的稿子】。面对完整的稿子,人做的是校对(看错别字、看格式);而补人味需要的是往回走两步,把某个段落拆掉重写——在一份已经排好版的稿子上做这件事,心理成本高得多,所以人一定会选择【就这样吧】。 正确的位置是【初稿刚出来、还没排版的时候】。 那时候改一个字,下游全自动跟着变;等排版完了再改,你得重来一遍。

二、七个节点各做什么

# 节点 谁做 产出 归属
① 拆对标 Agent 同问题下高赞回答的结构、角度缺口 5.3.1
② 出初稿 Agent 标题(文章)+ 正文 + 配图提示词 5.3.2
③ 补人味 人 正文里多出【只有作者知道的东西】 本节
④ 发起会话取稿 RPA 从对话里把稿子拿回来(多轮) 5.4.1
⑤ 墨滴排版 RPA 剪贴板里的富文本 5.4.2
⑥ 填字段入编辑器 RPA 标题/正文/图/话题都就位 5.4.3
⑦ 设声明 → 发布 人 一篇已发布的知乎内容 5.4.3

注意 ④ 这个节点:它意味着稿子是从【一个对话窗口】里拿回来的——这一点与第三章的 3.4.2(多轮对话取稿)同形,但知乎这一侧的取稿更难,因为拿回来的往往不只是一篇(一批候选、多轮修改),5.4.1 会专门处理。

三、那张【交接台】:任务表字段设计

这是本章的中枢,也是理解整章的钥匙。 与 4.2 的任务表相比,它多了三组字段——多出来的每一组,都对应前面讲过的一件知乎特有事。

组 字段 说明
通用组 id、主题、状态、负责人、时间戳 与 4.2 相同
形态组(★知乎特有) 形态:文章 / 回答 / 想法 决定走哪套 RPA 操作——三路互不通用
问题链接(回答形态必填) 回答必须挂在具体问题下
标题(文章形态必填) 2~80 字符
话题标签(1~5 个) 三路都有
合规组(★知乎特有) 创作声明 六档选一,必填(默认那档也要确认)
AI 参与:是 / 否 与声明必须对应
补过人味:是 / 否 判 AI 的第一抓手
素材组 封面图、正文图 文章有封面,回答和想法没有

这张表最值钱的地方,是【合规组】那三格。

它们把一个模糊的道德要求(【内容要像真人写的】)变成了三个可以勾选的格子。只要这三格是流程必经的,那么【忘掉】这件事就在结构上不可能发生——这就是 5.1.2 说的那第三笔价值(风险)具体的落点。

📝 表格设计的一条通用经验

任务表的字段,不是【这条信息有用就加进去】,而是【这条信息不被记录就会出事,才加进去】。 对照一下:4.2 加了【封面】【排期】【去重】—— 因为批量时它们会出事;本章加了【形态】【问题链接】【声明】【人味】—— 因为它们是知乎这一侧会出事的地方。 所以【任务表长什么样】,本身就是【这个平台的规则说明书】。 换一个平台,这张表就该重设计一次。

四、状态机与失败三原则

状态流转(8 格,两向):

选题 → 对标 → 初稿 → 补人味 → 排版 → 待发 → 已发 → 复盘
                  ↑______↓         ↑______↓
                   允许打回          允许打回重发

注意那些反向箭头。 这是本章与 4.2 在状态机上的最大差别:

4.2(头条批量) 5.2(本章)
主方向 单向(批量的核心是往前推) 允许打回
打回的理由 少见(批量里打回一篇会拖垮节奏) 常见——【这篇对标没找到缺口】要回①,【这段还是太像 AI】要回③

为什么知乎要允许打回? 因为本章的瓶颈是质量,不是数量(5.1.2 的账算过)。一个不允许打回的质量流程,最后一定会变成【凑合过去】。

失败三原则(沿用 4.2,但改一处):

原则 4.2 的说法 本章的说法
能跳过 一篇失败不拖垮整批 同(本章批量小,但改写过程中同样会有一条卡住)
能重试 网络抖动不该丢稿 同(尤其 5.4.3 的界面自动化)
要留痕 否则不知道哪几篇没发 同,但多一样:要留【为什么打回】——打回理由是下一篇的输入

五、与 4.2 的对照:一次【同骨架、不同重点】的示范

维度 4.2 今日头条 5.2 知乎
核心矛盾 数量 质量
流程骨架 同样的两条线两个闸门 同
任务表重点 排期、去重、状态 形态路由、合规字段、人味标记
状态机 偏单向 允许打回
最怕的事 一篇拖垮整批 一篇踩了平台的判定
定盘星 批量的第一性原理是可用性 半自动的第一性原理是【别让它看出是机器写的】

一句话总结这个对照:同样的骨架,装的东西可以完全不同。 这也正是本课一门课要讲四个平台的理由——骨架可以背,但【每个平台的规则长什么样】,只能一个平台一个平台地过。

六、动手 Demo:任务表体检器

这是本节真正属于你自己的那部分代码。 它做一件事:在稿子进入 RPA 之前,把【会让这一篇发不出去、或者发出去出事】的格子挑出来。

它检查七类,注意其中第 2、4、5 三条是前三章完全没有的:

# 检查 为什么
1 形态是否合法(文章/回答/想法) 三路互不通用,形态错 → 后面全错
2 回答形态必须有【问题链接】 回答不是一个独立文档,它必须挂在问题上
3 文章标题 2~80 字符 超限会被截断或拒绝
4 声明与 AI 参与必须对应 标了 AI 却选【无声明】=声明与事实不符
5 走到【补人味】之后必须已补 判 AI 的第一抓手,且只有人能做
6 字数两档(<100 阻断 / <300 提示) 与 4.4.3 同一条纪律
7 与他篇标题高度相似 同质化,第六档风控的入口
# -*- coding: utf-8 -*-
"""5.2 Demo:知乎任务表体检器 —— 找出【会让这一篇发不出去或发出去出事】的格子(纯标准库)"""
import re

# 状态机顺序(只允许往前走,也允许打回)
FLOW = ["选题", "对标", "初稿", "补人味", "排版", "待发", "已发", "复盘"]
FORMS = ["文章", "回答", "想法"]

# 字段:id / 形态 / 标题 / 问题链接 / 字数 / ai参与 / 创作声明 / 补过人味 / 状态
TASKS = [
    {"id": "Z01", "form": "文章", "title": "玄关收纳:我只留了三件东西", "qurl": "",
     "words": 1850, "ai": True,  "declare": "包含 AI 辅助创作", "human": True,  "state": "待发"},
    {"id": "Z02", "form": "回答", "title": "", "qurl": "",
     "words": 1200, "ai": True,  "declare": "无声明", "human": False, "state": "待发"},
    {"id": "Z03", "form": "文章", "title": "一篇关于家庭收纳的完整方法论与实操指南从玄关到厨房从卧室到阳台从衣帽间到书房的十八个收纳场景的全屋收纳体系搭建思路与常见误区规避要点以及不同户型的适配方案与预算分配建议",
     "qurl": "", "words": 78, "ai": False, "declare": "无声明", "human": True, "state": "排版"},
    {"id": "Z04", "form": "想法", "title": "", "qurl": "",
     "words": 420, "ai": True,  "declare": "包含 AI 辅助创作", "human": True,  "state": "待发"},
    {"id": "Z05", "form": "文章", "title": "玄关收纳,我只留了三件东西", "qurl": "",
     "words": 1600, "ai": True,  "declare": "包含 AI 辅助创作", "human": True,  "state": "待发"},
    {"id": "Z06", "form": "回答", "title": "", "qurl": "https://www.zhihu.com/question/123456",
     "words": 260, "ai": True,  "declare": "包含 AI 辅助创作", "human": True,  "state": "待发"},
]

def bigrams(s):
    s = re.sub(r"[\s,。:、?!,.:?!]", "", s)
    return set(s[i:i + 2] for i in range(len(s) - 1)) if len(s) > 1 else set(s)

def similar(a, b):
    x, y = bigrams(a), bigrams(b)
    if not x or not y:
        return 0.0
    return len(x & y) / float(len(x | y))

def check(t, all_tasks):
    bad, warn = [], []
    # 1. 形态必须合法
    if t["form"] not in FORMS:
        bad.append("形态【%s】不存在 —— 知乎只有文章/回答/想法三路,三路互不通用" % t["form"])
    # 2. 回答形态必须挂在问题上
    if t["form"] == "回答" and not t["qurl"]:
        bad.append("形态是【回答】但没填问题链接 —— 回答必须挂在一个具体问题下面")
    # 3. 文章形态:标题长度 2~80 字符
    if t["form"] == "文章":
        n = len(t["title"])
        if n == 0:
            bad.append("形态是【文章】但没有标题 —— 文章必须有标题")
        elif n > 80:
            bad.append("标题 %d 字符,超过知乎上限 80 —— 会被截断或拒绝" % n)
    # 4. 声明与 AI 参与必须对应(这条是知乎特有)
    if t["ai"] and t["declare"] != "包含 AI 辅助创作":
        bad.append("标了【AI 参与】但创作声明是【%s】—— 声明与事实不符" % (t["declare"] or "空"))
    if not t["declare"]:
        bad.append("创作声明为空 —— 发布前必须显式设置(默认那一档也要确认)")
    # 5. 人味:状态走到【补人味】之后,必须已补
    idx = FLOW.index(t["state"]) if t["state"] in FLOW else -1
    if idx >= FLOW.index("补人味") and not t["human"]:
        bad.append("状态已到【%s】却没补过【只有你知道的东西】—— 这是判 AI 的第一抓手" % t["state"])
    # 6. 字数两档
    if t["words"] < 100:
        bad.append("正文仅 %d 字,低于底线 100 字" % t["words"])
    elif t["words"] < 300:
        warn.append("正文 %d 字,低于建议值 300 字(提示,不阻断)" % t["words"])
    # 7. 同质化:与他篇标题高度相似
    if t["title"]:
        for o in all_tasks:
            if o["id"] != t["id"] and o["title"]:
                s = similar(t["title"], o["title"])
                if s >= 0.7:
                    warn.append("标题与【%s】相似度 %.2f —— 同问题/同账号下同质化会被判低质" % (o["id"], s))
    return bad, warn

print("=" * 70)
print("一、逐篇体检(共 %d 篇)" % len(TASKS))
print("=" * 70)
total_bad = total_warn = 0
for t in TASKS:
    bad, warn = check(t, TASKS)
    total_bad += len(bad)
    total_warn += len(warn)
    tag = "OK" if not bad and not warn else "%d 阻断 / %d 提示" % (len(bad), len(warn))
    print()
    print("  [%s] %s  %s" % (t["id"], t["form"], tag))
    for b in bad:
        print("        ✗ %s" % b)
    for w in warn:
        print("        ! %s" % w)

print()
print("=" * 70)
print("二、状态机分布与【卡点】")
print("=" * 70)
for st in FLOW:
    ids = [t["id"] for t in TASKS if t["state"] == st]
    bar = "█" * len(ids)
    print("  %-8s %s %s" % (st, bar, "、".join(ids) if ids else ""))

stuck = [t["id"] for t in TASKS if t["state"] != "已发" and t["state"] != "复盘"]
print()
print("  未走完的:%s(共 %d 篇)" % ("、".join(stuck), len(stuck)))

print()
print("=" * 70)
print("三、汇总")
print("=" * 70)
print("  阻断 %d 条(不改就别发);提示 %d 条(记录了再决定)。" % (total_bad, total_warn))
print("  阻断里有 %d 条属于【声明类】—— 这是知乎特有的一组,前三章都没有。"
      % sum(1 for t in TASKS for b in check(t, TASKS)[0] if "声明" in b))
print("  放行的:%s" % "、".join(t["id"] for t in TASKS if not check(t, TASKS)[0]))

实际运行输出(真跑,不是示意):

======================================================================
一、逐篇体检(共 6 篇)
======================================================================

  [Z01] 文章  0 阻断 / 1 提示
        ! 标题与【Z05】相似度 1.00 —— 同问题/同账号下同质化会被判低质

  [Z02] 回答  3 阻断 / 0 提示
        ✗ 形态是【回答】但没填问题链接 —— 回答必须挂在一个具体问题下面
        ✗ 标了【AI 参与】但创作声明是【无声明】—— 声明与事实不符
        ✗ 状态已到【待发】却没补过【只有你知道的东西】—— 这是判 AI 的第一抓手

  [Z03] 文章  2 阻断 / 0 提示
        ✗ 标题 84 字符,超过知乎上限 80 —— 会被截断或拒绝
        ✗ 正文仅 78 字,低于底线 100 字

  [Z04] 想法  OK

  [Z05] 文章  0 阻断 / 1 提示
        ! 标题与【Z01】相似度 1.00 —— 同问题/同账号下同质化会被判低质

  [Z06] 回答  0 阻断 / 1 提示
        ! 正文 260 字,低于建议值 300 字(提示,不阻断)

======================================================================
二、状态机分布与【卡点】
======================================================================
  选题        
  对标        
  初稿        
  补人味       
  排版       █ Z03
  待发       █████ Z01、Z02、Z04、Z05、Z06
  已发        
  复盘        

  未走完的:Z01、Z02、Z03、Z04、Z05、Z06(共 6 篇)

======================================================================
三、汇总
======================================================================
  阻断 5 条(不改就别发);提示 3 条(记录了再决定)。
  阻断里有 1 条属于【声明类】—— 这是知乎特有的一组,前三章都没有。
  放行的:Z01、Z04、Z05、Z06

读结果,五个值得注意的地方:

  1. Z02 一条就报了三个错,而且三个错不在同一个环节:形态路由(缺问题链接)、合规(声明与事实不符)、质量(没补人味)。这不是巧合——一个填表不认真的人,会在三个地方同时出事。 反过来看,一道体检把三个问题一次报全的价值,是【省两次人工返工】。

  2. Z03 的标题 84 字符超限——这类问题最会骗人:标题看起来只是【写得详细了点】,而人写完一千多字正文之后,是不会回头数字符的。这条检查存在的意义就是替人做那件人不愿意做的事。

  3. Z01 与 Z05 的相似度是 1.00——注意这个数字是怎么来的:两个标题只差一个标点(: 改成 ,),而脚本在比较前把标点去掉了,所以它们在语义结构上完全一样。这正是同质化最典型的手法——【改个标点、换个词序,就想蒙过去】。 这和 4.2 里那条【只加了一个空格的重复主题】是同一类,也正好撞上第一章就讲过的那句【更换表达模板规避治理,同样从严处置】。

  4. Z04 被放行,而这恰恰是脚本最聪明的地方——想法形态不需要标题、不需要问题链接,因为三路形态的规则本来就不一样。如果检查写成【一刀切】,合法的想法就会被判死。 这与 4.3.1 那次【正则太窄、把合格卡误判】是同一类错误的镜像:前者是漏报,后者是误报,都是【没按真实规则写判据】。

  5. 所有人卡在【待发】这一格——这是本次演示数据里最值得看的一件事。 5 篇堆在同一格,说明前面几格走得快、只有最后一段没动。 这不是流程坏了,恰恰是流程对了。 因为最后那一段(设声明、点发布)正是唯一必须人做的那一步。状态机的分布图,其实是一张【机器干完了多少活】的进度表——当人看到【5 篇都堆在待发】,他的任务非常清楚:坐下来,5 分钟过一遍声明,点 5 次发布。

📝 顺手说一句这个脚本的边界

它的【未走完的:6 篇】是个粗统计(把所有非【已发/复盘】的都算进来)。真要做得细,应该按状态分档报(比如【在补人味停留超过 3 天】的单独列出来)。 这里保留粗统计是有意的——体检器不需要聪明,它只需要可靠地在每一道关上都问一遍那七个问题。 聪明的部分(判断哪一篇该放弃、哪一篇该打回)留给人。

30 秒实验

把 Demo 里 第 5 条检查(人味)整段注释掉,再跑一次。

会发生什么:

结论:本章所有检查里,这一条最虚(没法量化),却最不能省。 因为它守的不是格式,是内容能不能被当成人写的——而 5.1.1 里那五档处置(标识→减少分发→折叠→建议修改→删除)全都挂在同一个判据上。

顺着这个思路想一层:既然这条这么重要,为什么不把它做成【自动补人味】? 因为人味的内容本身就是【机器写不出来的东西】——亲历、具体的数字、明确的立场、不整齐的节奏。让机器去补【它不是机器】的证据,是一个逻辑上自相矛盾的任务。 所以这一格必须留给人,机器只能做到【提醒 + 卡住不放行】。

常见误区

  1. 【先把流程搭起来,人味那一步以后再说】——错,顺序不能反。 补人味必须在 Agent 出稿之后、RPA 接手排版之前。放到最后,人面对的是一份【已经完整的稿子】,那时候人会做校对(看错别字),而不是往回走两步拆掉重写——在一份排好版的稿子上做这件事,心理成本高得多,结果一定是【就这样吧】。
  2. 【任务表字段越多越好,信息全记上】——错。 字段的判据是 【这条信息不被记录就会出事】,不是【这条信息有用】。对照 4.2 与本节:多出来的每一格,都对应一件知乎会出事的事(形态路由、问题链接、声明、人味)。字段表其实就是这个平台的规则说明书。
  3. 【状态机应该严格单向,打回是流程设计失败】——错。 本章的瓶颈是质量(5.1.2 算过),一个不允许打回的质量流程,最后一定会退化成【凑合过去】。【这篇没找到角度缺口】要能回①,【这段太像 AI】要能回③。但要留痕——打回理由是下一篇的输入。
  4. 【体检器一次报全,所以我要一次把每条都修好】——错,不要混着修。 阻断和提示要分开处理(阻断改完才能走,提示记录后由人决定);而且不同环节的问题要回到对应环节去修——Z02 那三条里,【缺问题链接】是选题阶段的事,【声明不符】是发布前的事,混在一起改,会把流程的层次搞乱。
  5. 【六选一的创作声明,选默认的【无声明】最省事】——错,这是本节最贵的一个坑。 如果这一篇确实用了 AI 参与,选【无声明】就是【声明与事实不符】——而【包含 AI 辅助创作】那一档的完整名字是【作者对内容负责】,它不是免责声明,是责任声明。如实标注的成本是一次点击,不如实的成本是五档处置里的某一档。
自测三问(点开对答案) 1. **本章的七个节点里,哪一个是前三章没有的?它为什么必须【单独成格】,而不能塞进别处?** **③【补人味】。** 必须单独成格的原因:**塞在别处的工序一定会被忘掉**——如果把它归进【初稿】,人在看到一份完整稿子的时候就会跳过它;如果把它归进【发布前检查】,那时候正文已经排版定型,**改一句话要重来一遍下游**。 它的正确位置是 **【Agent 出稿之后、RPA 接手之前】**——因为**人味必须由人补进正文里,而机器一旦接手排版和填字段,正文就定型了。** 2. **任务表里新加的【合规组】三格是哪三个?为什么说这张表本身就是【平台的规则说明书】?** **创作声明 / AI 参与 / 补过人味。** 说它是规则说明书,因为**字段的选取判据不是【信息有用】,而是【不被记录就会出事】**:这三格分别对应——**知乎的声明是发布前必设的强制项**、**判 AI 看的是文本特征而不是使用记录**、**处置分五档且都挂在【内容质量】这个判据上**。 所以**换一个平台,这张表就要重设计一次**(4.2 的表里是排期、去重、封面;本章是形态路由、声明、人味)。 3. **为什么本章的状态机要【允许打回】,而 4.2 的可以偏单向?** 因为**两章的核心矛盾不同**:4.2 是**数量**(批量的核心是往前推,打回一篇会拖垮节奏),本章是**质量**(5.1.2 算过:知乎单篇价值高、长尾长,该加强的是单篇质量而不是产能)。 **一个不允许打回的质量流程,最后一定退化成【凑合过去】。** 所以本章允许两种回退:【对标没找到缺口】回①、【这段还是太像 AI】回③——**并且要留痕,因为打回理由是下一篇的输入。**

相关笔记