命名实体提取提示
从非结构化文本中提取姓名、日期、地点和自定义实体
命名实体提取提示 是 CoddyKit 上的免费 AI Prompt Engineering 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Prompt Engineering 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Prompt Engineering 课程共包含 4 节课。
什么是命名实体抽取
命名实体抽取(NER)是识别并分类文本中提及的特定现实世界实体的任务。传统自然语言处理使用统计模型执行 NER;LLM 则可以借助设计良好的提示词完成这项任务。
常见实体类型:
- PERSON:人物姓名(埃隆·马斯克、简·史密斯博士)
- ORG:公司和组织(苹果、WHO)
- DATE:日期和时间表达(1 月 15 日、上周二、2024 年第三季度)
- LOCATION:地点(纽约、亚马逊河)
- MONEY:金额(42 亿美元)
基本 NER 提示词
最简单的 NER 提示词会要求以特定格式返回所有实体:
import anthropic, json
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
text = 'Apple CEO Tim Cook met with European Commission President Ursula von der Leyen in Brussels on March 15, 2025 to discuss the Digital Markets Act.'
prompt = f'''
Extract all named entities from the text below.
Return ONLY a JSON object with no other text:
{{
"people": ["string"],
"organizations": ["string"],
"locations": ["string"],
"dates": ["string"]
}}
Text: {text}
'''
r = client.messages.create(
model='claude-opus-4-5', max_tokens=300,
messages=[{'role': 'user', 'content': prompt}]
)
print(json.loads(r.content[0].text))为抽取添加类型约束
基本抽取会返回实体字符串。类型约束会增加验证步骤——确保日期采用特定格式,并确保组织名称不包含常见词语:
prompt_typed = '''
Extract named entities from the text below with type constraints.
Return JSON:
{
"people": ["Full name as written in text"],
"organizations": ["Official organization name only, no articles (the, a)"],
"dates": ["ISO 8601 format if possible: YYYY-MM-DD, else exact text as written"],
"money": ["Include currency symbol and amount: $4.2B, EUR 500K"],
"locations": ["City, Country format if applicable"]
}
If a category has no entities, use an empty array [].
Text: {text}
'''
print(prompt_typed[:200])
print('\nConstraints enforce consistent output format per entity type.')模式驱动的抽取
在生产环境中,请预先定义实体模式,并在提示词中引用该模式。这样可以明确输出契约:
ENTITY_SCHEMA = '''
{
"entities": [
{
"text": "exact text as it appears in the document",
"type": "PERSON | ORG | DATE | LOCATION | MONEY | PRODUCT | EVENT",
"normalized": "canonical form (e.g., full name, ISO date)",
"start_char": "integer, character offset in source text",
"confidence": "high | medium | low"
}
]
}
'''
def extract_entities(text):
prompt = f'Extract all named entities. Return JSON matching this schema exactly:\n{ENTITY_SCHEMA}\n\nText: {text}'
r = client.messages.create(
model='claude-opus-4-5', max_tokens=500,
messages=[{'role': 'user', 'content': prompt}]
)
return json.loads(r.content[0].text)
result = extract_entities('Tesla stock rose 5% after Elon Musk announced the Cybertruck delivery on December 1.')
print(result['entities'][0])处理含糊实体
有些实体字符串含义不明确——苹果可能指公司或水果,乔丹可能指人物,也可能指国家。请引导模型利用上下文消除歧义:
prompt_disambiguation = '''
Extract named entities from the text. For ambiguous entities, use the surrounding
context to determine the correct type. Include your reasoning in an "evidence" field.
Return JSON:
{
"entities": [
{
"text": "string",
"type": "PERSON | ORG | LOCATION | OTHER",
"evidence": "brief reason for type assignment"
}
]
}
Text: Jordan and Apple signed a distribution deal for the new Air Jordan shoes.
'''
# Expected output: Jordan = PERSON (context: Air Jordan), Apple = ORG (context: signed a deal)
print(prompt_disambiguation)使用字段定义进行抽取
对于特定于您所在领域的自定义实体类型,请在提示词中提供字段定义,让模型准确了解哪些内容应被视为实体:
prompt_custom = '''
Extract entities from the medical text below using these custom entity types:
Entity Types:
- MEDICATION: Any drug name, trade name, or generic name
- DOSAGE: Amounts and frequencies (mg, mcg, units/day)
- CONDITION: Diagnoses, symptoms, or medical conditions
- PROCEDURE: Medical tests, surgeries, or treatments
- PROVIDER: Doctor names and medical professionals
Return JSON: {"entities": [{"text": str, "type": str}]}
Text: Dr. Patel prescribed Metformin 500mg twice daily for Type 2 Diabetes.
A follow-up HbA1c test is scheduled for next month.
'''
print(prompt_custom)批量实体抽取
处理多个文档时,批量抽取更加高效。请设计提示词来处理多个输入,并为每个文档返回结构化结果:
def batch_extract(documents):
docs_formatted = '\n'.join(
f'<document id="{i+1}">\n{doc}\n</document>'
for i, doc in enumerate(documents)
)
prompt = f'''
Extract named entities from each document below.
Return JSON: {{
"results": [
{{"doc_id": int, "entities": {{"people": [], "organizations": [], "dates": []}}}}
]
}}
{docs_formatted}
'''
r = client.messages.create(
model='claude-opus-4-5', max_tokens=1000,
messages=[{'role': 'user', 'content': prompt}]
)
return json.loads(r.content[0].text)
docs = [
'Satya Nadella presented at Microsoft Build 2025.',
'The WHO released guidelines on May 10.'
]
print(batch_extract(docs))对抽取的实体进行后处理
抽取出的实体在使用前通常需要后处理:
from datetime import datetime
def normalize_entities(raw_entities):
normalized = {'people': [], 'organizations': [], 'dates': [], 'money': []}
for person in raw_entities.get('people', []):
normalized['people'].append(person.strip().title())
for org in raw_entities.get('organizations', []):
normalized['organizations'].append(org.strip())
for date_str in raw_entities.get('dates', []):
# Try to parse to ISO format
for fmt in ['%B %d, %Y', '%Y-%m-%d', '%b %d, %Y']:
try:
parsed = datetime.strptime(date_str.strip(), fmt)
normalized['dates'].append(parsed.strftime('%Y-%m-%d'))
break
except ValueError:
pass
else:
normalized['dates'].append(date_str.strip())
return normalized
raw = {'people': ['tim cook', 'URSULA VON DER LEYEN'], 'dates': ['March 15, 2025']}
print(normalize_entities(raw))评估抽取质量
NER 质量通过带标签的测试集上的精确率、召回率和 F1 分数进行衡量:
- 精确率:在所有抽取出的实体中,有多大比例是正确的?
- 召回率:在所有真实实体中,有多大比例被抽取出来?
- F1:精确率和召回率的调和平均数
def evaluate_extraction(predicted, ground_truth):
pred_set = set(predicted)
true_set = set(ground_truth)
true_positives = len(pred_set & true_set)
false_positives = len(pred_set - true_set)
false_negatives = len(true_set - pred_set)
precision = true_positives / (true_positives + false_positives) if pred_set else 0
recall = true_positives / (true_positives + false_negatives) if true_set else 0
f1 = 2 * precision * recall / (precision + recall) if (precision + recall) else 0
return {'precision': round(precision, 3), 'recall': round(recall, 3), 'f1': round(f1, 3)}
predicted = ['Tim Cook', 'Apple', 'Brussels', 'March 15 2025']
ground_truth = ['Tim Cook', 'Apple', 'Ursula von der Leyen', 'Brussels', 'March 15, 2025', 'European Commission']
print(evaluate_extraction(predicted, ground_truth))减少幻觉实体
模型有时会抽取源文本中不存在的实体,这些实体属于幻觉现象。缓解策略包括:
- 指示:仅抽取文本中明确提及的实体。不要推断或添加不存在的实体。
- 指示:对于每个实体,都要包含其在文本中出现位置的准确引文。
- 后处理:验证每个抽取出的实体字符串确实出现在原始文本中
def anti_hallucination_extract(text):
prompt = f'''
Extract ONLY entities that are explicitly present in the text below.
Do NOT infer, add, or supplement with external knowledge.
For each entity, include the exact quote from the text.
Return JSON: {{"entities": [{{"text": str, "type": str, "quote": str}}]}}
Text: {text}
'''
r = client.messages.create(model='claude-opus-4-5', max_tokens=400, messages=[{'role': 'user', 'content': prompt}])
extracted = json.loads(r.content[0].text)
# Post-process: verify each entity appears in original text
verified = [e for e in extracted['entities'] if e['text'].lower() in text.lower()]
return {'entities': verified}
result = anti_hallucination_extract('Google announced a $5B investment in AI infrastructure.')
print(result)共指与实体链接
抽取原始实体字符串后,还有两个额外任务可以提升下游使用效果:
- 共指消解:将他、该公司和它关联回它们所指的命名实体
- 实体链接:将抽取出的名称映射到规范标识符(例如,将“苹果”映射为知识库中的规范标识符)
这两个任务都可以在初始抽取后通过额外的提示词步骤完成。
coref_prompt = '''
Resolve coreferences in the text below.
For each pronoun or definite reference (he, she, it, the company, the CEO),
identify which named entity it refers to.
Return JSON: {"coreferences": [{"text": str, "refers_to": str, "position": int}]}
Text: Apple released its new chip. The company said it would ship in Q4.
Tim Cook announced that he would present it at the fall event.
'''
print(coref_prompt)快速检查
防止模型抽取源文本中不存在的实体,最有效的方法是什么?
命名实体抽取——要点
当提示词设计得当时,基于 LLM 的命名实体抽取灵活而强大:
- 明确规定实体类型——PERSON、ORG、DATE、LOCATION、MONEY 以及特定领域的类型
- 在提示词中使用 JSON 模式,强制输出结构保持一致
- 为自定义实体类型添加字段定义,让模型准确了解哪些内容符合要求
- 要求提供原文引文,以防止实体幻觉
- 进行后处理以规范化实体格式(日期转换为 ISO,名称转换为标题格式)
- 在带标签的测试集上使用精确率、召回率和 F1 评估质量
- 处理批次时,在一次调用中处理多个文档,并为每个文档输出结构化结果
常见问题解答
「命名实体提取提示」课时是免费的吗?
是的 — 「命名实体提取提示」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Prompt Engineering 课程的其余内容,请升级到 CoddyKit PRO。 AI Prompt Engineering 课程共包含 4 节课。
「命名实体提取提示」这节课中我会学到什么?
从非结构化文本中提取姓名、日期、地点和自定义实体 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 AI Prompt Engineering 需要有经验吗?
无需任何先前经验。CoddyKit 上的 AI Prompt Engineering 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「命名实体提取提示」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 AI Prompt Engineering 课中编写并运行代码吗?
能。每节 AI Prompt Engineering 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。