规划模块:Agent的大脑 — 决定"做什么"和"以什么顺序做"

先说结论

感知让 Agent 看见世界,记忆让 Agent 记住过去,规划让 Agent 决定下一步做什么。

没有规划的 Agent,就像没有大脑的机器人 --- 感知到信息也不知道怎么用,记住了偏好也不知道什么时候该用。

在 self-media-agent 项目里,规划体现在三个层面:

规划层面 决定什么 对应代码 当前状态
选题规划 写什么主题 topic/generator.py LLM 生成,但与热点脱节
流水线编排 以什么顺序执行 pipeline/runner.py 固定 7 步,静态
风格进化策略 用什么风格写 persona/style_learner.py 被动触发,用户修改后才学习

当前项目是静态规划 --- 步骤固定、顺序固定、策略固定。 这够用但不够聪明。真正的 Agent 应该能动态规划:根据热点自动选题、根据质检分数决定是否重写、根据发布数据主动调整风格。

一句话:规划是 Agent 智能的核心体现,当前项目迈出了第一步(静态规划),离动态规划还有距离。

一、选题规划:从赛道到选题

当前实现:LLM 根据赛道生成选题

topic/generator.pyTopicGenerator --- 给 LLM 赛道信息,让它生成结构化选题:

ini 复制代码
class TopicGenerator:
    async def generate_topics(self, persona: PersonaConfig, count: int = 10) -> list[Topic]:
        niche_name = NICHE_NAMES.get(persona.niche, persona.niche)
​
        system_prompt = self.prompt_mgr.get_template("topic_generation")
        user_prompt = (
            f"赛道:{niche_name}\n"
            f"人设类型:{persona.persona_type}\n"
            f"文案风格:{persona.writing_style}\n"
            f"内容形式:{persona.content_format}\n"
            f"请生成 {count} 个高潜力选题。"
        )
​
        result = await self.llm.generate_json(
            system_prompt=system_prompt,
            user_prompt=user_prompt,
            schema=TopicList,  # ← 结构化输出
            temperature=0.8,
        )
        topics = [
            Topic(persona_id=persona.id, title=item.title, category=item.category, ...)
            for item in result.topics
        ]
        return topics

选题规划的输入输出

css 复制代码
输入:PersonaConfig(赛道、人设类型、风格、内容形式)
      ↓ LLM 规划
输出:list[Topic](10 个结构化选题,含分类和预估流量)

选题池管理:规划结果的存储

生成的选题不直接用,先存入选题池topic/pool.py),按状态管理:

ruby 复制代码
class TopicPool:
    def add(self, topic: Topic) -> Topic:           # 添加到池
    def list_pending(self, persona_id: str) -> list: # 列出待使用
    def mark_used(self, topic_id: str) -> Topic:     # 标记已使用
    def mark_skipped(self, topic_id: str) -> Topic:  # 标记已跳过

选题状态流转

objectivec 复制代码
生成 → PENDING(待使用)→ USED(已使用)/ SKIPPED(已跳过)

选题池的作用:规划结果不一次性消费完,可以攒一批选题,按需取用。避免每次生成都要调 LLM。

踩坑:选题与热点脱节

项目在 api/schemas.py 里定义了 use_hotspot 参数:

ini 复制代码
class TopicGenerateRequest(BaseModel):
    persona_id: str
    count: int = Field(default=10, ge=1, le=50)
    use_hotspot: bool = False  # 是否使用热点数据

但这个参数在选题生成的实现里并没有被使用。 热点抓取(hotspot/)和选题生成(topic/generator.py)是两个独立模块,没有自动串联。

当前流程(手动):

arduino 复制代码
用户手动执行 sma hotspot → 看到热点列表 → 手动挑选 → 手动传入 sma run --topics "xxx"

理想流程(自动):

复制代码
Agent 自动抓热点 → 自动分析筛选 → 自动结合人设生成选题 → 自动生产内容

差距就是规划模块的进化方向 --- 从"人规划"到"Agent 规划"。

二、流水线编排:固定顺序的执行规划

第4篇详细讲过 pipeline/runner.py 的 7 步流水线。从规划的角度看,流水线就是一种静态规划 --- 步骤和顺序在代码里写死:

python 复制代码
async def _generate_single(self, persona, topic, output_dir):
    # 2a: 生成标题     ← 第1步:规划好了,先写标题
    # 2b: 生成正文     ← 第2步:规划好了,再写正文
    # 2c: 排版         ← 第3步:规划好了,然后排版
    # 2d: 四维质检     ← 第4步:规划好了,然后质检
    # 2e: 构建对象     ← 第5步:规划好了,打包成对象
    # 2f: 存储         ← 第6步:规划好了,存起来
    # 2g: 导出文件     ← 第7步:规划好了,导出

静态规划的特点

特点 当前项目 动态规划的未来
步骤顺序 固定写死在代码里 根据内容类型动态调整
步骤数量 固定 7 步 某些步骤可跳过或重复
分支决策 只有 short_video vs text 一个分支 根据质检分数决定是否重写
错误处理 失败跳过,不重试 失败后根据原因决定重试策略

静态规划够用但不够聪明

够用的地方:步骤固定 → 可预测、可测试、可维护。对于"生成文章"这种标准化流程,静态规划完全够用。

不够聪明的地方

ini 复制代码
# 当前:质检不过也照常输出
quality_result = await self.quality_orchestrator.check_and_fix(persona, formatted)
formatted = quality_result.final_content
quality_score = quality_result.total_score
# ← 如果 quality_score < 0.5,应该重写,但当前直接输出了

动态规划应该做的

python 复制代码
# 未来:质检不过 → 自动重写
for attempt in range(max_retries):
    quality_result = await self.quality_orchestrator.check_and_fix(persona, formatted)
    if quality_result.total_score >= 0.8:
        break  # 通过,跳出循环
    # 没通过 → 把质检反馈注入 Prompt,重新生成
    user_prompt += f"\n\n# 上次质检问题\n{quality_result.violations}\n请改进。"
    formatted = await self.body_gen.generate_text(persona, topic, title)

这就是静态规划和动态规划的核心区别:静态规划不根据中间结果调整后续步骤,动态规划会。

三、风格进化策略:从被动学习到主动进化

第6篇讲过 style_learner.py 的三层风格进化。从规划的角度看,风格进化是一种"策略规划" --- 决定用什么风格写。

当前的风格进化策略:被动触发

复制代码
用户修改文章
    ↓(被动触发)
提取偏好 → 合并到 style_preferences
    ↓(手动触发)
汇总偏好 → 生成 style_profile
    ↓(自动注入)
下次生成时 build_style_hint 注入 Prompt

"被动"体现在:Agent 不会主动发现问题、不会主动建议修改、不会主动调整风格。所有进化都由用户的行为触发。

风格进化的完整流程

style_learner.py 实现了从提取到注入的完整链路:

python 复制代码
class StyleLearner:
    # 1. 从单次修改提取偏好
    async def extract_preference_from_revision(self, revision) -> list[dict]:
        """LLM 从修改前后 diff + 修改建议中提取结构化偏好"""
        # 输入:revision(原文 + 修改后文 + 建议)
        # 输出:[{"category": "语气", "value": "活泼", "confidence": 0.8}]
​
    # 2. 合并去重偏好
    @staticmethod
    def _merge_preferences(preferences: list[dict]) -> list[dict]:
        """相同 category+value 合并,confidence 取最高,count 累加"""
​
    # 3. 汇总生成画像
    async def build_profile(self, persona) -> tuple[str, list[dict]]:
        """收集所有修改记录 → 逐条提取偏好 → 合并 → LLM 生成画像"""
​
    # 4. 写入人设
    def apply_to_persona(self, persona, profile, preferences) -> PersonaConfig:
        """model_copy 更新 style_profile + style_preferences"""
​
    # 5. 构建注入 Prompt 的风格提示
    @staticmethod
    def build_style_hint(persona) -> str:
        """画像 + 偏好提醒 → 注入生成 Prompt"""

5 个方法,构成风格进化的完整规划链

sql 复制代码
extract(提取)→ merge(合并)→ build_profile(汇总画像)→ apply(写入)→ inject(注入)

被动 vs 主动

被动进化(当前) 主动进化(未来)
触发 用户修改后提取 Agent 生成后自评
发现 用户说"太正式" Agent 对比历史偏好发现偏差
建议 不建议 主动建议"这段可以更活泼"
调整 下次生成注入 当前生成实时调整

主动进化示例(未来):

ini 复制代码
# 生成后自评:对比当前输出和历史偏好
current_style = analyze_style(generated_body)
if current_style.tone != persona.preferred_tone:
    # 发现偏差 → 自动调整
    user_prompt += f"\n注意:你的风格偏好是{persona.preferred_tone},请调整。"
    generated_body = await regenerate(user_prompt)

当前项目做不到这一点 --- 因为没有"风格自评"的规划步骤。 这是规划模块的进化方向。

四、静态规划 vs 动态规划:差距在哪

把三个层面综合起来看:

当前:静态规划

复制代码
                    ┌─────────────┐
                    │  静态规划    │
                    └──────┬──────┘
                           │
    ┌──────────────────────┼──────────────────────┐
    │                      │                      │
    ▼                      ▼                      ▼
┌─────────┐          ┌──────────┐          ┌──────────┐
│ 选题规划  │          │ 流水线编排 │          │ 风格进化  │
│ LLM生成  │          │ 固定7步   │          │ 被动触发  │
│ 不结合热点│          │ 不根据结果 │          │ 不主动自评 │
│         │          │  调整后续  │          │          │
└─────────┘          └──────────┘          └──────────┘

三个"不"

  1. 不结合热点 --- 选题和热点是两个独立模块,没有自动串联
  2. 不根据结果调整 --- 质检不过也照常输出,不重写
  3. 不主动自评 --- 风格进化全靠用户触发,Agent 不主动发现问题

未来:动态规划

复制代码
                    ┌─────────────┐
                    │  动态规划    │
                    └──────┬──────┘
                           │
    ┌──────────────────────┼──────────────────────┐
    │                      │                      │
    ▼                      ▼                      ▼
┌─────────┐          ┌──────────┐          ┌──────────┐
│ 选题规划  │          │ 流水线编排 │          │ 风格进化  │
│ 热点→选题 │          │ 质检不过  │          │ 生成后自评 │
│ 自动串联  │          │  →自动重写 │          │ 主动调整   │
│ 相关度排序 │          │ 根据分数  │          │ 对比历史   │
│         │          │  调整策略  │          │  偏好      │
└─────────┘          └──────────┘          └──────────┘

三个"变"

  1. 热点→选题自动串联 --- use_hotspot=True 时,先抓热点再生成选题,按相关度排序
  2. 质检不过自动重写 --- quality_score < 0.8 时,把违规项注入 Prompt 重新生成
  3. 生成后主动自评 --- 对比当前输出和历史偏好,发现偏差主动调整

为什么当前是静态的?

不是不能做,是权衡后的选择

动态规划的代价 当前项目的权衡
每次质检不过要重写 → LLM 调用翻倍 成本 ×2,当前选择不重写
主动自评需要额外 LLM 调用 成本 +1,当前选择不自评
热点自动串联增加复杂度 先做简单的,热点手动触发够用

静态规划是 V1 的合理选择 --- 先跑通,再优化。 动态规划是 V2/V3 的方向。

五、规划模块在项目中的位置

把规划放在 Agent 四大模块的框架里看:

复制代码
感知(第5篇)→ 获取热点
                ↓
记忆(第6篇)→ 提供人设 + 风格偏好
                ↓
规划(本篇)  → 决定选题 + 执行顺序 + 风格策略
                ↓
行动(第8篇)→ 生成标题 + 正文 + 质检 + 排版

规划是感知和行动之间的桥梁 --- 感知提供信息,记忆提供偏好,规划决定怎么用这些信息和偏好来指导行动。

当前项目的规划链路:

ini 复制代码
# pipeline/runner.py --- 规划的入口
async def run(self, persona_id, topics=None, topic_count=10):
    # ━━━ 感知 + 记忆 → 规划输入 ━━━
    persona = self.persona_mgr.get(persona_id)  # 记忆:人设 + 风格偏好
​
    # ━━━ 规划:决定写什么 ━━━
    if topics:
        topic_list = [Topic(...) for t in topics]  # 用户规划:手动选题
    else:
        topic_list = await self.topic_gen.generate_topics(persona, topic_count)  # AI 规划:自动选题
​
    # ━━━ 规划:决定怎么写 ━━━
    for topic in topic_list:
        content = await self._generate_single(persona, topic, output_dir)
        # _generate_single 内部:标题→正文→排版→质检→存储→导出
        # 风格偏好通过 build_style_hint 自动注入正文生成

两处规划决策

  1. 写什么 --- topics 有值则用户规划,无值则 AI 规划
  2. 怎么写 --- _generate_single 的 7 步顺序 + 风格偏好注入

当前都是静态的 --- 决策逻辑写死在代码里,不根据运行时信息动态调整。

踩坑总结

根因 修复方向
选题与热点脱节 use_hotspot 参数定义了但没实现 实现热点→选题自动串联
质检不过照常输出 流水线不根据中间结果调整 质检不过时自动重写
风格进化全靠手动 没有主动自评的规划步骤 生成后对比历史偏好自评
选题生成不结合热点 两个模块独立,无串联 规划层串联:热点→分析→选题
流水线步骤固定 静态规划,不动态调整 根据内容类型/质检结果动态调整步骤
风格画像手动触发 build_profile 需要手动调用 定期自动汇总,或每次修改后增量更新

经验总结

  1. 规划决定"做什么"和"以什么顺序做" --- 选题规划决定主题,流水线编排决定执行顺序,风格策略决定写作风格
  2. 当前项目是静态规划 --- 步骤固定、顺序固定、策略固定,够用但不够聪明
  3. 静态规划的三 个"不" --- 不结合热点、不根据结果调整、不主动自评,这是动态规划的进化方向
  4. 静态规划是 V1 的合理选择 --- 先跑通再优化,动态规划的代价是 LLM 调用翻倍,当前权衡后选择不做
  5. 规划是感知和行动的桥梁 --- 感知提供信息,记忆提供偏好,规划决定怎么用这些来指导行动

下篇预告

下一篇讲 行动模块:Agent的手 --- 行动是 Agent 的产出,多策略行动(图文/脚本/笔记)+ 质检作为行动的一部分 + 修改再生成的行动闭环。

相关推荐
canber2 小时前
DeepSeek Harness (DSH) 实战:架构、模式与插件化开发
ai编程
OpenTiny社区2 小时前
GenUI SDK v1.3.0 开发者深度解读:当生成式 UI 开始"长出"工程化骨架
前端·ai编程
全栈弄潮儿2 小时前
4 个新手就能直接套用的 AI 编程提示词模板
chatgpt·openai·ai编程
晚安code2 小时前
Agent Harness 从原理到实战:大模型不干活,全靠智能体运行框架在撑
ai编程
刘立军2 小时前
依赖注入:禁止 AI 硬编码实例化,提升可测试性与扩展性
架构·ai编程
Behavior2 小时前
Claude Code 扩展点:Hooks
aigc·claude
晚安code3 小时前
上下文工程是什么?从提示词工程到上下文,一文讲透 AI 不跑偏
ai编程
晓得迷路了3 小时前
栗子前端技术周刊第 142 期 - DeepSeek Harness、pnpm 12 RC、crypto‑js...
前端·javascript·ai编程
必须会一定会4 小时前
Node.js Agent Handoff 仓库扫描 MVP:忽略规则、include 通配与稳定输出实现
人工智能·node.js·ai编程