让数据库读懂 NBA 新闻:用 LLM 提取中文实体

发布于:2025-09-11 ⋅ 阅读:(25) ⋅ 点赞:(0)

在这里插入图片描述

想象一下,你打开一篇中文 NBA 新闻,读到:

「LeBron James 砍下 42 分,帮助洛杉矶湖人险胜金州勇士。Draymond Green
因与对手发生冲突,被判技术犯规。Anthony Davis
因髋部受伤被列为每日观察。」

作为球迷的你,很快就明白了:谁得分、谁冲突、谁受伤。

但如果你希望 数据库也能理解这些信息,并能回答:

  • 「最近有哪些球员受伤?」
  • 「列出湖人最近险胜的比赛。」
  • 「这周有哪些球员领到技术犯规?」

这就是 利用大型语言模型(LLM)的命名实体识别(NER) 的用途。


第一步:我们要提取哪些实体?

NBA 中文新闻中的「实体」不只是球队和球员,还包括:

  • 球队:洛杉矶湖人、金州勇士、波士顿凯尔特人。
  • 球员:LeBron James、Stephen Curry。
  • 比赛事件:湖人对勇士、总决赛第三场。
  • 伤病:脚踝扭伤、每日观察、手术。
  • 冲突:打架、推搡、禁赛。
  • 数据:42 分、12 篮板、三双。
  • 犯规与处罚:技术犯规、恶意犯规、驱逐出场。
  • 交易与合同:交易传闻、续约。
  • 奖项与里程碑:MVP 候选人、破纪录。
  • 地点:球馆、城市。
  • 时间:比赛日期、伤病恢复期。

第二步:让 LLM 抽取实体

我们给 LLM 一个 清晰的提示词(Prompt),让它输出 JSON:

你是一个信息抽取系统。  
请阅读以下 NBA 中文新闻,并抽取结构化的实体。  
请只输出有效 JSON,格式如下:  

{
  "entities": [
    {"type":"球员","name":"", "details":{}},
    {"type":"球队","name":"", "details":{}},
    {"type":"伤病","name":"", "details":{}},
    {"type":"犯规","name":"", "details":{}},
    {"type":"数据","name":"", "details":{}}
  ],
  "game": {
    "date":"",
    "arena":"",
    "winner":"",
    "score":{"TEAM1":0,"TEAM2":0}
  }
}

details 示例:
- 球员: {"得分":42, "篮板":12}
- 伤病: {"部位":"脚踝", "状态":"每日观察"}
- 犯规: {"类型":"技术犯规"}
- 数据: {"类别":"助攻", "数值":10}

新闻内容:
"LeBron James 砍下 42 分,湖人险胜勇士。Draymond Green 因冲突被判技术犯规。Anthony Davis 因髋部受伤被列为每日观察。"

LLM 输出示例:

{
  "entities": [
    {"type":"球员","name":"LeBron James","details":{"得分":42}},
    {"type":"球队","name":"洛杉矶湖人"},
    {"type":"球队","name":"金州勇士"},
    {"type":"球员","name":"Draymond Green","details":{"犯规":"技术犯规"}},
    {"type":"球员","name":"Anthony Davis","details":{"伤病":"髋部","状态":"每日观察"}}
  ],
  "game": {
    "date":"2025-03-20",
    "arena":"Crypto.com Arena",
    "winner":"洛杉矶湖人",
    "score":{"湖人":112,"勇士":108}
  }
}

第三步:存进 PostgreSQL

我们需要三张核心表:

-- 新闻
CREATE TABLE 新闻 (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  标题 TEXT,
  内容 TEXT,
  来源链接 TEXT,
  发布时间 TIMESTAMPTZ,
  来源 TEXT
);

-- 实体(球员、球队、比赛、伤病等)
CREATE TYPE 实体类型 AS ENUM (
  '球员','球队','比赛','伤病','冲突',
  '数据','犯规','交易','奖项','地点','日期'
);

CREATE TABLE 实体 (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  类型 实体类型 NOT NULL,
  名称 TEXT NOT NULL,
  属性 JSONB DEFAULT '{}'::jsonb
);

-- 实体提及(LLM 输出结果)
CREATE TABLE 实体提及 (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  新闻_id UUID REFERENCES 新闻(id),
  实体_id UUID REFERENCES 实体(id),
  细节 JSONB DEFAULT '{}'::jsonb,   -- 伤病、得分、犯规
  来源 TEXT NOT NULL,                -- 'llm'
  创建时间 TIMESTAMPTZ DEFAULT now()
);

第四步:查询知识

当新闻被结构化之后,就可以像分析师一样发问了。

查询最新伤病:

SELECT e.名称 AS 球员,
       em.细节->>'伤病' AS 伤病,
       em.细节->>'状态' AS 状态,
       n.标题, n.发布时间
FROM 实体 e
JOIN 实体提及 em ON em.实体_id = e.id
JOIN 新闻 n ON n.id = em.新闻_id
WHERE e.类型 = '球员' AND em.细节 ? '伤病'
ORDER BY n.发布时间 DESC;

查询技术犯规:

SELECT e.名称 AS 球员, em.细节->>'犯规' AS 犯规, n.标题
FROM 实体 e
JOIN 实体提及 em ON em.实体_id = e.id
JOIN 新闻 n ON n.id = em.新闻_id
WHERE em.细节->>'犯规' = '技术犯规'
ORDER BY n.发布时间 DESC;

查询湖人比赛结果:

SELECT em.细节->>'score' AS 比分, n.标题, n.发布时间
FROM 实体 e
JOIN 实体提及 em ON em.实体_id = e.id
JOIN 新闻 n ON n.id = em.新闻_id
WHERE e.类型 = '球队' AND e.名称 = '洛杉矶湖人'
ORDER BY n.发布时间 DESC;

为什么 LLM 特别适合中文体育新闻?

中文体育新闻的表达非常灵活,常带有绰号或隐喻:

  • 「小皇帝爆发」 → LeBron James 表现火热
  • 「AD 每日观察」 → Anthony Davis 受伤,短期缺阵
  • 「库里投进 12 记三分球」 → Stephen Curry 命中率惊人

规则方法很容易漏掉,而 LLM 可以理解语境并生成结构化结果


结论

只需要 PostgreSQLLLM,就能把杂乱的中文 NBA
新闻转化为结构化数据,涵盖球员、球队、伤病、犯规和比赛结果。

流程非常简单:

  1. 收集新闻
  2. 调用 LLM,用 JSON 提示词抽取实体
  3. 存进 Postgres
  4. 查询并得到洞察

这样一来,你的数据库就不只是存文章,而是一个可以回答问题的「篮球专家」:
谁受伤?谁状态火热?谁惹上麻烦?

这就是 LLM + 数据设计的力量。


网站公告

今日签到

点亮在社区的每一天
去签到