AI专栏 | Prompt Engineering实战 [新闻助手实战,这样写Prompt,你的程序能用?]
难度系数:★★★☆☆
本章知识:
- 复习清单
- 新闻助手Prompt
- Prompt分析 [重点 ★★★★★]
- 改造验证 [重点 ★★★★★]
- 继续改进思路
- 下一章预告: PromptEngineering进阶技巧
复习清单
上一章我们提到了关于PromptEngineering的8条高能建议,本章基于新闻助手的场景,带你来观察一下Prompt这样写你的程序能用么。
先来回顾一下PromptEngineering的8条高能建议有哪些?
- 把AI当人来看
- 提供单一的任务
- 任务描述清晰且准确
- 给出适量参考样例
- 正向描述任务信息
- 不要提供过长的prompt
- 根据任务类型切换任务角色
- A/B测试迭代找到最佳的prompt
接下来我们会用这份清单,逐条对照分析一个真实 Prompt 在程序中的表现。
注意 本章内容实际已涉及Agent开发,此时我们主要关注Prompt的编写问题。
新闻助手Prompt示例工程
需求描述
现在某公司要开发一个新闻助手,这个新闻助手会根据用户输入的关键词,从互联网上抓取相关的新闻,并返回给用户。
Code示例
下面是一个简单的新闻助手,基于LLM的搜索能力,实现新闻查询及格式化输出,来我们分析一下代码中所犯的问题有哪些?
# 非完整代码,主要包括关键代码,完整见gitcode仓库
# https://gitcode.com/miasdz/ai-column-code.git
sys_prompt = """
你是一个新闻助手,负责进行新闻信息查询并格式化输出。
# 输出要求
## 输出格式
以JSON格式仅输出查询结果,确保输出结果可以被python中json.loads加载不报错。
## JSON内容要求
0. json总体结构为list嵌套dict结构
1. 每个dict结构表示一个企业的新闻信息查询结果
2. 每个dict结构存在两个key,name和news
3. name key对应value为企业名称,value值类型为string
4. news key对应value值为新闻列表,value值类型为list,list的每一项值类型为dict
5. 企业新闻信息查询结果的list的每一个dict类型的值包括三个要素:date(日期)、new_type(新闻类型)、news(新闻信息)
6. new_type类型包括:
- 重大事件/战略动态类
- 产品/技术创新类
- 企业成就/荣誉认可类
- 人事与组织变动类
- 合规、风险与监管类
- 社会责任/ESG/公益类
- 日常运营与业务动态类
- 招标、采购公告类
## 示例
[
{
"name":"xx企业",
"news":[
{
"date":"2026年1月12日",
"new_type":"合规、风险与监管类",
"news": "xxx公司因xxx业务违规开展被处罚1000万元。"
},
{
"date":"2026年1月5日",
"new_type":"重大事件/战略动态类",
"news": "xxx公司与yyy公司达成战略合作。"
},
]
},
{
"name":"zz企业",
"news":[
{
"date":"2026年1月18日",
"new_type":"合规、风险与监管类",
"news": "zz企业因xxx业务违规开展被行政处罚85万元。"
},
{
"date":"2026年1月19日",
"new_type":"人事与组织变动类",
"news": "zz企业新任命总经理uu。"
},
]
}
]
"""
user_prompt = """
查询山西银行和晋商银行近期的5条新闻
"""
# 对话消息
messages = [
{
"role": "system",
"content": sys_prompt
},
{
"role": "user",
"content": user_prompt
}
]
# 调用llm接口
chat_completion = client.chat.completions.create(
model=model,
messages=messages,
extra_body={
"enable_search": True,
"search_options": {
"search_strategy": "max", # 配置搜索策略为高性能模式
"forced_search": True
}
}
)
...... 此处思考3分钟 ......
Prompt分析
运行结果
先看一下运行结果,看看程序是否能正常返回结果。
注意 下述运行结果代码实测结果截取,再次执行无法保证完全一致。
[
{
"name": "山西银行",
"news": [
{
"date": "2026年1月7日",
"new_type": "日常运营与业务动态类",
"news": "山西银行发布‘晋晟理财’理财产品净值公告。"
},
{
"date": "2025年12月31日",
"new_type": "日常运营与业务动态类",
"news": "山西银行发布‘晋晟理财’理财产品净值公告。"
},
{
"date": "2025年12月24日",
"new_type": "日常运营与业务动态类",
"news": "山西银行发布‘晋晟理财’理财产品净值公告。"
},
{
"date": "2025年12月18日",
"new_type": "重大事件/战略动态类",
"news": "任凯与临汾市长王延峰座谈。"
},
{
"date": "2025年12月12日",
"new_type": "重大事件/战略动态类",
"news": "邢毅赴省内金融同业拜访交流。"
}
]
},
{
"name": "晋商银行",
"news": [
{
"date": "2025年12月15日",
"new_type": "合规、风险与监管类",
"news": "晋商消费金融成被执行人第一大股东为晋商银行。"
},
{
"date": "2025年12月10日",
"new_type": "合规、风险与监管类",
"news": "山西最新批复!多家金融机构高管任职获批。"
},
{
"date": "2025年11月30日",
"new_type": "人事与组织变动类",
"news": "山西银行党委副书记、行长(代)邢毅带队赴太重集团开展专项调研。"
},
{
"date": "2025年11月30日",
"new_type": "人事与组织变动类",
"news": "山西银行党委副书记、副董事长、行长李颖耀拟进一步使用。"
},
{
"date": "2025年11月28日",
"new_type": "重大事件/战略动态类",
"news": "山西银行新增高管人事变动引关注。"
}
]
}
]
观察上述结果,prompt要求的json格式是正确的。但是从内容上分析会发现明显的错误:
- 同一个人的名字出现在了两家企业内,稍微了解一下是错误新闻
- 我要求的是近期新闻,截至我写作时间2026年1月19日,返回的新闻几乎全都是25年末的,近期目标效果差
- 新闻与公司关联错误,A公司新闻归类到B公司
- 从news字段中看不出来企业与这条新闻的关系
- 新闻类型错误,如“重大事件/战略动态类”
问题分析
基于前面的建议,我们逐条分析一下这段乍一看还不错的prompt,存在什么问题?
1. 提供单一的任务
问题指数: ★★★★★
基于上一章节对单一任务的理解,我们再看Prompt:
SystemPrompt逻辑点:
- 新闻信息查询
- 新闻归类
- 数据格式化
根据单一任务理解,system prompt已经违反单一任务的限制,不做认知的切换,新闻信息查询和归类属于两类任务 信息提取 和 分类决策任务,不满足单一任务定义。
UserPrompt逻辑点:
- 查询山西银行近期新闻
- 查询晋商银行近期新闻
- 近期是什么时候[隐性任务]
- 新闻筛选
对于UserPrompt,要求同时查询两个企业的信息,涉及了两个信息聚合主题,也不符合单一任务定义。
根据执行结果,综合SystemPrompt和UserPrompt,经过A/B测试,主要问题体现在UserPrompt中存在两个信息实体,具体见新Prompt运行效果。
2. 任务描述清晰且准确
从程序运行结果看,主要的prompt用于描述数据格式,返回符合预期要求,从描述层面足够清晰,满足该项。
3. 给出适量参考样例
JSON格式正确,demo中给了明确的示例,满足该项。
4. 正向描述任务信息
问题指数: ★☆☆☆☆☆
确保输出结果可以被python中json.loads加载不报错。非正面描述,不过问题不大,大模型实测是没问题的,也可以改为更合理的描述如"符合标准 RFC 8259 规范的 JSON 字符串"。
5. 不要提供过长的prompt
使用openai的tokenizer计算约在gpt4模型下约600,从模型容量角度看不多,该条满足。
可参考OpenAI官方tokenizer计算结果(不同模型结算结果不同,仅供参考)
6. 根据任务类型切换任务角色
Systmem Prompt首行定义了任务角色,该条满足。
7. A/B测试迭代找到最佳的prompt
A/B测试迭代属于持续优化的过程,接下来我们继续修改prompt测试的过程满足此条。
改造验证
新版Prompt
sys_prompt = """
你是一个新闻助手,负责进行新闻信息查询并格式化输出。
# 输出要求
## 输出格式
以JSON格式仅输出查询结果,确保输出结果符合标准 RFC 8259 规范的 JSON 字符串。
## JSON内容要求
1. JSON结构存在两个key,name和news
2. name key对应value为企业名称,value值类型为string
3. news key对应value值为新闻列表,value值类型为list,list的每一项值类型为dict
4. 企业新闻信息查询结果的list的每一个dict类型的值包括三个要素:date(日期)、new_type(新闻类型)、new_info(新闻信息)
5. new_type类型包括:
- 重大事件/战略动态类
- 产品/技术创新类
- 企业成就/荣誉认可类
- 人事与组织变动类
- 合规、风险与监管类
- 社会责任/ESG/公益类
- 日常运营与业务动态类
- 招标、采购公告类
## 示例
{
"name":"xx企业",
"news":[
{
"date":"2026年1月12日",
"new_type":"合规、风险与监管类",
"news": "xxx公司因xxx业务违规开展被处罚1000万元。"
},
{
"date":"2026年1月5日",
"new_type":"重大事件/战略动态类",
"news": "xxx公司与yyy公司达成战略合作。"
},
]
}
# 约束
当未检索到可验证的有效新闻时,news 字段应返回一个空数组 []
"""
user_prompt = """
查询晋商银行近期的5条新闻
"""
实测结果
再看新prompt测试结果,在单一信息主体下,结果可用。
{
"name": "晋商银行",
"news": [
{
"date": "2026年1月16日",
"new_type": "日常运营与业务动态类",
"news": "晋商银行股份有限公司2026年第006期同业存单发行情况公告。"
},
{
"date": "2026年1月14日",
"new_type": "日常运营与业务动态类",
"news": "晋商银行股份有限公司2026年第004期同业存单即日起开始在银行间债券市场交易流通。"
},
{
"date": "2026年1月6日",
"new_type": "合规、风险与监管类",
"news": "晋商银行发布《关于加强个人银行账户安全管理的公告》。"
},
{
"date": "2025年11月28日",
"new_type": "日常运营与业务动态类",
"news": "晋商银行召开2025年四季度经营工作会。"
},
{
"date": "2025年10月29日",
"new_type": "人事与组织变动类",
"news": "晋商银行启动2026年度校园招聘,计划招聘11人。"
}
]
}
继续改进思路
初始需求如何满足?
再翻回来看user_prompt,要求查询两个信息主体的新闻,上述优化后的prompt仅查询一个主体好用,那多个怎么办?
这就涉及工作流的开发:
- 用户意图识别:通过用户prompt摘取在新闻查询场景下的查询主体有几个
- 根据获取出的查询主体,多次调用新闻查询服务
- 聚合结果
查询质量不满足、新闻总结不满足怎么办
现在使用的是大模型提供的查询服务,如果需要相对稳定的查询数据源,那就需要依赖外部服务了,比如秘塔搜索API、百度搜索API甚至是外部稳定数据源的数据采购等方式来提升数据质量。
此时做法就变成了:
- 用户意图识别获取查询主体
- FuncationCalling获取外部数据
- 通过LLM进行新闻总结及归类
- 基于新闻总结及归类结果进行信息提取为JSON结构
- 多轮查询的信息聚合
这些流程的窜连完成一个完整的新闻领域查询服务,详情查看gitcode源码。
针对LLM单一任务,靠人识别可能因经验不足或者思维定式无法准确分析,后续将开发Prompt单一分析器Agent,用于优化Agent的Prompt准备。
下一章预告
下一章节将通过介绍PromptEngineering中思维链、思维树、自洽性等进阶技巧。
关注本专栏,让我们一起掌握方法、实践落地、共同发展。