本节约处在第五章第二站,把上一节的设计原则落到"提示词怎么写"。CrewAI 的提示不是一处,而是分散在 Agent 的 role/goal/backstory 和 Task 的 description/expected_output 多处。约束写错地方,模型就吃错药。我们先画清提示词的层级与各自职责。

第一条规则:风格与能力边界放 Agent 层,具体验收放 Task 层。role/goal/backstory 决定"这是个什么样的人",description/expected_output 决定"这次具体做成啥样"。把本该写进 Task 的约束塞进 backstory,会让该角色接的所有任务都被同一段陈词带偏。
# 5.2 Prompt Engineering for CrewAI analyst = Agent( role="分析师", goal="给出有依据的结论", backstory="金融背景,习惯先列证据再判断,语气克制", verbose=True, ) # 验收进 Task,且越具体越好 t = Task( description="分析 {data} 的月度变化", expected_output="三条结论,每条含:现象、证据、建议;用编号列,不用段落", agent=analyst, )
第二条规则:expected_output 用"结构 + 禁止项"双保险。光说要什么还不够,明确不要什么能挡掉模型常见跑偏。比如"不要寒暄、不要复述问题、直接给结论"。
t = Task( description="为 {topic} 写一句定位语", expected_output=( "一句不超过二十字的中文定位语。" "约束:不含标点以外的符号、不出现'全球领先'等空话、直接给文案不要解释" ), agent=writer, )
第三条规则:占位符只承载"运行时才知的值",不承载"固定指令"。把固定的事写死在 description,把变化的主题用 {topic} 注入。这样同一段提示可复用,且不会因占位符缺失崩。
# 固定指令写死,变量用占位符 t = Task( description="用克制语气写 {topic} 的新闻稿,先结论后论据,不超过三百字", expected_output="新闻稿全文", agent=writer, ) # crew.kickoff(inputs={"topic": "新品发布"})
第四条规则:层级模式下的提示要更"自包含"。因为经理可能动态派活,Task 的 description 不能假设上游一定给了某上下文,要能在缺省时自洽。我们给层级模式下的 Task 都写一句"若未提供 X,则自行检索",降低对上游的依赖。
第五条规则:把提示当代码管理。版本化、做 A/B、记录哪版提示产出更稳定。多智能体系统的回归测试很大程度是"提示回归"——提示一改,产出分布就变。我们建议把关键提示抽成配置,改一处、测全队。
一个收尾提醒:写给多智能体的提示,目标是"让每个角色的输出可被下游稳定消费",而不是"让单个角色显得聪明"。所以衡量提示好坏的标准不是模型答得漂亮,而是下游 Task 拿到的东西恰好是它要的格式。带着"下游视角"写提示,比堆修辞有用得多。下一站讲测试,你会发现提示稳不稳,最终要靠测试来验证。
把验收写进人设、把风格写进 Task,是常见的左右颠倒。后果是:风格约束被每次任务的指令覆盖,验收又因混在人设里而模糊。我们见过把"必须带来源"写进 backstory,结果换了个不带该人设的 Task 就丢了约束。
# 错:约束在 backstory,换任务就失效 wrong = Agent(backstory="回答必须带来源", verbose=True) # 对:约束在 Task.expected_output,跟着任务走 right_task = Task(description="回答 {q}", expected_output="答案,且每条带来源链接", agent=wrong)
提示归位后,下游消费稳定,测试也好写。这也是为什么第五章把"验收写 Task 层"当成原则。
Agent 的 role/goal/backstory 是"人设提示",强调稳定风格;Task 的 description/expected_output 是"当次指令",强调具体动作与产出格式。两者语气不同,混用会乱。
| 对象 | 提示词重点 | 写法倾向 |
|---|---|---|
| Agent | 你是谁、风格、禁忌 | 名词化、稳定 |
| Task | 这次做什么、产出啥样 | 动词开头、具体 |
⚠️ 常见坑:把验收标准写进 Agent 的 backstory,导致所有任务都被同一套标准绑架。验收标准属于 Task 的 expected_output,写那里才对。另一个坑是 description 用疑问句,模型容易答非所问——用祈使句。
from crewai import Agent, Task analyst = Agent( role="数据分析师", goal="产出可复核的分析", backstory="只用数据说话,拒绝臆测", # 人设:稳定风格+禁忌 verbose=True, ) t = Task( description="基于销售表计算各区域环比增长率,列出前三名", # 祈使句、具体 expected_output="表格:区域、本月、上月、环比%、排名", # 钉死格式 agent=analyst, ) print(analyst.backstory) print(t.expected_output)
💡 关键直觉:提示词工程在 CrewAI 里是"两层写作"——给人设写传记,给任务写工单。传记写得越像"这个人",行为越一致;工单写得越像"验收单",产出越可用。把传记当工单写,系统就乱了。
# 用模板统一 Task 描述,减少手写漂移 TEMPLATE = "基于 {data} 完成 {action},产出 {fmt}" desc = TEMPLATE.format(data="销售表", action="区域排名", fmt="表格") assert "基于" in desc and "产出" in desc
写完后问自己三句:人设里有没有写"验收标准"?(不该有,那属于 Task);Task 描述是不是祈使句、有没有动词?(含糊就改);expected_output 能不能让一个外人照着它验收?(不能就钉死格式)。三句都过,提示词质量基本在线。
💡 关键直觉:好的 CrewAI 提示词不是"写得多",而是"写得各司其职"——人设稳、工单清,系统就稳。