一段新闻摘要为何让模型“失忆”?

看一眼下面这段原文片段(来自某财经新闻聚合页):

  • /TABLE-Matsumoto -2025/26 parent results. Sign in or create a free account to read this news. Reuters Refinitiv TABLE-Kyowakogyosyo -2025/26 group results. … * Image 12 Dow Jones Newswires Sign in to read exclusive news. * Image 10 … Dec 22, 2025 Reuters Australia's FlexiRoam surge on Generali deal …

如果你把这段文字直接丢给LLM,指望它给你一个清晰的财务摘要——十有八九你会得到。要么是“无法理解,请提供更完整的信息”,要么是直接生成一段混乱的复制粘贴。

这不是模型笨,而是上下文结构没设计好。模型同时面对多条新闻标题、日期、图片占位符、登录提示,还有重复的“Sign in”文本。它不知道自己要提取什么、输出的格式是什么、哪些信息是噪音。于是它“失忆”了——注意力被分散,最终输出也随波逐流。

LLM confused by cluttered text with multiple headlines and login prompts

上下文结构分析:为什么模型会“跑偏”?

我们可以把这段文本拆解成模型眼中的“上下文块”:

  • 实体块:TABLE-Matsumoto, TABLE-Kyowakogyosyo, FlexiRoam, 1MDB saga 等
  • 动作块:“Sign in to read”、“returns parent results”、“accepts bids for bonds”
  • 噪音块:图片标签 * Image 12、重复的登录提示、无关联的日期序列

如果不用清晰的指令告诉模型“忽略噪音,只关注财务相关实体和数字”,模型就会默认所有内容都是相关的——这是它语言建模的本能。结果就是:输出中可能混入图片占位符,或者把不同公司的数据揉在一起。

优化方案:一个可复用的Prompt模板

核心思路是:用角色+任务+格式约束+示例,为模型划定一个明确的“上下文边界”。下面这个模板可以直接复制到任何支持Chat Completion的API中使用。

text
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
## 角色定义
你是一名金融数据提取专家。你的任务是从给定的杂乱新闻文本中,提取所有与上市公司财务业绩相关的关键信息,并以标准JSON数组格式输出。

## 输入文本
{INSERT_YOUR_TEXT_HERE}

## 提取规则
1. 只提取包含“parent results”、“group results”、“bonds”、“earnings”、“revenue”、“profit”等关键词的公司条目。
2. 忽略图片标签(* Image 数字)、登录提示(Sign in)和付费墙文本。
3. 每条记录包含以下字段(如果缺失则填null):
   - company_name: 公司全称
   - period: 财报覆盖期间(提取“-2025/26”这类信息)
   - metric_type: parent_results / group_results / bond_issuance 等
   - details: 直接引用的数字或具体描述(如“$500 million”或“surge on deal”)
4. 输出严格为JSON数组,不要任何Markdown包装。

## 示例
输入:"TABLE-Matsumoto -2025/26 parent results. Sign in. * Image 5"
输出:[{"company_name": "Matsumoto", "period": "2025/26", "metric_type": "parent_results", "details": "No numeric data available"}]

原理说明:为什么这样写有效?

  1. 角色注入(“你是一名金融数据提取专家”)给模型一个身份锚点,让其主动调用相关领域的知识,避免自由闲聊。
  2. 任务边界(“从杂乱新闻文本中提取”)让模型知道输入是噪音,需要过滤。
  3. 格式约束(JSON数组+字段定义)限死了输出空间,模型无法“发散”出其他格式。
  4. 示例(“输入…输出…”)进一步降低了自由度,模型会模仿示例的行为。

实验对比:差Prompt vs 好Prompt

差Prompt

text
1 2
请提取下面新闻中关于财务结果的信息:
(输入文本同上)

实际输出(典型)

我看到新闻中提到MATSUMOTO、Kyowakogyosyo以及一些债券信息。但是有许多链接和图片,我不确定要提取什么。如果您能提供更干净的数据,我才能帮助您。

分析:模型没有看到明确的“提取格式”,于是反馈了一个反问。它试图理解用户意图,但因为意图模糊,它选择了“保守拒绝”。

好Prompt(上面的模板)

实际输出(模拟)

json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
[
  {
    "company_name": "Matsumoto",
    "period": "2025/26",
    "metric_type": "parent_results",
    "details": "No numeric data available"
  },
  {
    "company_name": "Kyowakogyosyo",
    "period": "2025/26",
    "metric_type": "group_results",
    "details": "No numeric data available"
  },
  {
    "company_name": "L&T Finance",
    "period": null,
    "metric_type": "bond_issuance",
    "details": "accepts bids for 3-year bonds"
  }
]

对比效果:好Prompt成功过滤了图片、登录提示、无关日期(Dec 22, 2025)和重复新闻标题。它只输出了金融实体,且格式完全符合JSON约定。数据缺失时用null填充,而不是自行虚构数字。

Side-by-side comparison of bad prompt output (text refusal) vs good prompt output (clean JSON)

适用场景和边界

这个方法的本质是用结构化指令对抗上下文噪音。它适用于以下场景:

  • 从大量新闻摘要中提取财报关键数据
  • 从会议记录中提取关键决议和责任人
  • 从多封邮件中提取截止日期和任务分配

边界条件

  1. 如果输入文本中完全没有匹配关键词(例如全是八卦新闻),模型会返回空数组 []。这是预期行为。
  2. 如果数字信息被隐藏在图片中(如图表),模型无法提取。需要额外调用OCR工具。
  3. 对于同一个公司的重复条目,模型可能提取多次。可以通过后续去重或prompt中加入“只保留最新一条”来缓解。

变体与扩展用法

变体1:多轮增量提取

当你先提取一批数据,然后又给模型追加新新闻时,可以这样改:

text
1 2
你已有之前的提取结果:{previous_json}
现在输入新文本,请只提取新增的条目,不要重复已有数据。

这样就能在不丢失上下文的情况下更新表格。

变体2:带置信度评分

让模型对每个提取结果加一个“confidence”字段(high/medium/low),用于警示可能错误的数字。

text
1
- confidence: 如果文本明确提到数字(如“$100 million”),则为high;如果只有间接描述,则为medium;如果没有数字,则为low。

变体3:输出Markdown表格(适合非技术读者)

text
1
请输出如下Markdown表格:| 公司 | 期间 | 指标类型 | 详情 |

这样方便直接嵌入文档。

写在最后

不要责怪模型“不听话”——它只是在按照自己的理解尽力回应。问题是我们的上下文结构没有给它清晰的“任务边界”。通过一个精心设计的prompt模板,你可以把一段混乱的新闻摘要变成干净的结构化数据,直接用于下游分析。这个能力在金融数据处理、信息抽取、自动化报表生成等领域极其实用。

现在就去你的API里试一下这个模板,你会看到模型变“聪明”了。