Phase 05 - Lesson 26
Extração de Relações e Construção de Grafos de Conhecimento
O NER encontrou as entidades. A vinculação de entidades as ancorou. A extração de relações encontra as arestas entre elas. Um grafo de conhecimento é a soma de nós, arestas e sua proveniência.
Tipo: Build Linguagens: Python Pré-requisitos: Fase 5 · 06 (NER), Fase 5 · 25 (Vinculação de Entidades) Tempo: ~60 minutos
O Problema
Um analista lê: "Tim Cook tornou-se CEO da Apple em 2011." Quatro fatos:
(Tim Cook, role, CEO)(Tim Cook, employer, Apple)(Tim Cook, start_date, 2011)(Apple, type, Organization)
A Extração de Relações (RE) transforma texto livre em triplas estruturadas (subject, relation, object). Agregue ao longo de um corpus e você tem um grafo de conhecimento. Agregue e consulte e você tem um substrato de raciocínio para RAG, analytics ou auditorias de conformidade.
O problema de 2026: os LLMs extraem relações com entusiasmo. Entusiasmo demais. Eles alucinam triplas que o texto-fonte não sustenta. Sem proveniência, você não consegue distinguir triplas reais de ficção plausível. A resposta de 2026 são os pipelines de ancorar-e-verificar no estilo AEVS.
O Conceito
Forma de tripla. (subject_entity, relation_type, object_entity). As relações vêm de uma ontologia fechada (propriedades do Wikidata, FIBO, UMLS) ou de um conjunto aberto (estilo OpenIE, vale tudo).
Três abordagens de extração.
- Baseada em regras / padrões. Padrões de Hearst: "X such as Y" →
(Y, isA, X). Mais regex feitas à mão. Frágil, precisa, explicável. - Classificador supervisionado. Dadas duas menções de entidades em uma frase, prediz a relação a partir de um conjunto fixo. Treinado em TACRED, ACE, KBP. Padrão de 2015–2022.
- LLM generativo. Faça um prompt para o modelo emitir triplas. Funciona de imediato. Precisa de proveniência, ou alucina lixo de aparência plausível.
AEVS (Anchor-Extraction-Verification-Supplement, 2026). O framework atual de mitigação de alucinações:
- Anchor (Ancorar). Identifique cada span de entidade e cada span de frase-relação com posições exatas.
- Extract (Extrair). Gere triplas vinculadas aos spans-âncora.
- Verify (Verificar). Confronte cada elemento da tripla com o texto-fonte; rejeite qualquer coisa não sustentada.
- Supplement (Complementar). Uma passagem de cobertura garante que nenhum span ancorado seja descartado.
As alucinações caem drasticamente. Exige mais computação, mas é auditável.
O tradeoff aberto-versus-fechado.
- Ontologia fechada. Lista fixa de propriedades (por exemplo, as mais de 11.000 propriedades do Wikidata). Previsível. Consultável. Difícil de inventar.
- IE aberta. Qualquer frase verbal vira uma relação. Alta cobertura. Baixa precisão. Bagunçada de consultar.
KGs de produção geralmente misturam: IE aberta para descoberta, depois canonicalizam as relações em uma ontologia fechada antes de mesclar no grafo principal.
Construa
Passo 1: extração baseada em padrões
PATTERNS = [
(r"(?P<s>[A-Z]\w+) (?:is|was) (?:a|an|the) (?P<o>[A-Z]?\w+)", "isA"),
(r"(?P<s>[A-Z]\w+) (?:is|was) born in (?P<o>\w+)", "bornIn"),
(r"(?P<s>[A-Z]\w+) works? (?:at|for) (?P<o>[A-Z]\w+)", "worksAt"),
(r"(?P<s>[A-Z]\w+) founded (?P<o>[A-Z]\w+)", "founded"),
]
Veja code/main.py para o extrator de brinquedo completo. Padrões de Hearst ainda estão presentes em pipelines específicos de domínio porque são depuráveis.
Passo 2: classificação supervisionada de relações
from transformers import AutoTokenizer, AutoModelForSequenceClassification
tok = AutoTokenizer.from_pretrained("Babelscape/rebel-large")
model = AutoModelForSequenceClassification.from_pretrained("Babelscape/rebel-large")
text = "Tim Cook was born in Alabama. He later became CEO of Apple."
encoded = tok(text, return_tensors="pt", truncation=True)
output = model.generate(**encoded, max_length=200)
triples = tok.batch_decode(output, skip_special_tokens=False)
O REBEL é um extrator de relações seq2seq: texto na entrada, triplas na saída, já em ids de propriedade do Wikidata. Ajustado com dados de supervisão distante. Baseline padrão de pesos abertos.
Passo 3: extração via prompt de LLM com ancoragem
prompt = f"""Extract (subject, relation, object) triples from the text.
For each triple, include the exact character span in the source text.
Text: {text}
Output JSON:
[{{"subject": {{"text": "...", "span": [start, end]}},
"relation": "...",
"object": {{"text": "...", "span": [start, end]}}}}, ...]
Only include triples fully supported by the text. No inference beyond what is stated.
"""
Verifique cada span retornado contra a fonte. Rejeite qualquer coisa em que text[start:end] != triple_entity. Este é o passo "verify" do AEVS em sua forma mínima.
Passo 4: canonicalize em uma ontologia fechada
RELATION_MAP = {
"is the CEO of": "P169", # "chief executive officer"
"was born in": "P19", # "place of birth"
"founded": "P112", # "founded by" (inverted subject/object)
"works at": "P108", # "employer"
}
def canonicalize(relation):
rel_low = relation.lower().strip()
if rel_low in RELATION_MAP:
return RELATION_MAP[rel_low]
return None # drop unmapped open relations or route to manual review
A canonicalização costuma ser 60-80% do trabalho de engenharia. Reserve orçamento para ela.
Passo 5: construa um pequeno grafo e consulte
triples = extract(text)
graph = {}
for s, r, o in triples:
graph.setdefault(s, []).append((r, o))
def neighbors(node, relation=None):
return [(r, o) for r, o in graph.get(node, []) if relation is None or r == relation]
print(neighbors("Tim Cook", relation="P108")) # -> [(P108, Apple)]
Este é o átomo de todo sistema de RAG-sobre-KG. Escale com triple stores RDF (Blazegraph, Virtuoso), grafos de propriedades (Neo4j) ou stores de grafo aumentados por vetores.
Armadilhas
- Correferência antes da RE. "He founded Apple" — a RE precisa saber quem é "he". Execute a correferência primeiro (lição 24).
- Canonicalização de entidades. "Apple Inc" e "Apple" precisam resolver para o mesmo nó. Vinculação de entidades primeiro (lição 25).
- Triplas alucinadas. Os LLMs emitem triplas que o texto não sustenta. Imponha a verificação de spans.
- Deriva na canonicalização de relações. As relações de IE aberta são inconsistentes ("was born in", "came from", "is a native of"). Reduza a ids canônicos ou o grafo fica não consultável.
- Erros temporais. "Tim Cook is CEO of Apple" — verdade agora, falso em 2005. Muitas relações são limitadas no tempo. Use qualificadores (
P580tempo de início,P582tempo de fim no Wikidata). - Incompatibilidade de domínio. O REBEL foi treinado na Wikipédia. Textos jurídicos, médicos e científicos frequentemente precisam de modelos de RE ajustados ao domínio.
Use
A stack de 2026:
| Situação | Escolha |
|---|---|
| Produção rápida, domínio geral | REBEL ou LlamaPred com canonicalização do Wikidata |
| Específico de domínio (biomédico, jurídico) | Ajuste de domínio estilo SciREX + ontologia customizada |
| Saída via prompt de LLM, auditada | Pipeline AEVS: ancorar → extrair → verificar → complementar |
| IE de notícias em alto volume | Híbrido baseado em padrões + supervisionado |
| Construir um KG do zero | IE aberta + passagem de canonicalização manual |
| KG temporal | Extrair com qualificadores (tempo de início/fim, ponto no tempo) |
O padrão de integração: NER → correferência → vinculação de entidades → extração de relações → mapeamento de ontologia → carga no grafo. Cada estágio é um potencial portão de qualidade.
Entregue
Salve como outputs/skill-re-designer.md:
---
name: re-designer
description: Design a relation extraction pipeline with provenance and canonicalization.
version: 1.0.0
phase: 5
lesson: 26
tags: [nlp, relation-extraction, knowledge-graph]
---
Given a corpus (domain, language, volume) and downstream use (KG-RAG, analytics, compliance), output:
1. Extractor. Pattern-based / supervised / LLM / AEVS hybrid. Reason tied to precision vs recall target.
2. Ontology. Closed property list (Wikidata / domain) or open IE with canonicalization pass.
3. Provenance. Every triple carries source char-span + doc id. Non-negotiable for audit.
4. Merge strategy. Canonical entity id + relation id + temporal qualifiers; dedup policy.
5. Evaluation. Precision / recall on 200 hand-labelled triples + hallucination-rate on LLM-extracted sample.
Refuse any LLM-based RE pipeline without span verification (source provenance). Refuse open-IE output flowing into a production graph without canonicalization. Flag pipelines with no temporal qualifier on time-bounded relations (employer, spouse, position).
Exercícios
- Fácil. Execute o extrator de padrões em
code/main.pyem 5 frases de artigos de notícias. Confira a precisão à mão. - Médio. Use o REBEL (ou um LLM pequeno) nas mesmas frases. Compare as triplas. Qual extrator tem maior precisão? Maior cobertura?
- Difícil. Construa o pipeline AEVS: extraia com LLM + verifique os spans contra a fonte. Meça a taxa de alucinação antes versus depois do passo de verificação em 50 frases ao estilo da Wikipédia.
Termos-Chave
| Termo | O que as pessoas dizem | O que realmente significa |
|---|---|---|
| Tripla | Sujeito-relação-objeto | Tupla (s, r, o) que é a unidade atômica de um KG. |
| IE aberta | Extrai qualquer coisa | Frases-relação de vocabulário aberto; alta cobertura, baixa precisão. |
| Ontologia fechada | Esquema fixo | Conjunto limitado de tipos de relação (Wikidata, UMLS, FIBO). |
| Canonicalização | Normaliza tudo | Mapeia nomes/relações de superfície para ids canônicos. |
| AEVS | Extração ancorada | Pipeline Anchor-Extraction-Verification-Supplement (2026). |
| Proveniência | Link de fonte-da-verdade | Cada tripla carrega um doc id + char-span até sua fonte. |
| Supervisão distante | Rótulos baratos | Alinha texto com um KG existente para criar dados de treino. |
Leitura Adicional
- Mintz et al. (2009). Distant supervision for relation extraction without labeled data — o artigo de supervisão distante.
- Huguet Cabot, Navigli (2021). REBEL: Relation Extraction By End-to-end Language generation — o cavalo de batalha seq2seq de RE.
- Wadden et al. (2019). Entity, Relation, and Event Extraction with Contextualized Span Representations (DyGIE++) — IE conjunta.
- AEVS — Anchor-Extraction-Verification-Supplement framework — design de mitigação de alucinações de 2026.
- Wikidata SPARQL tutorial — consultas canônicas a grafos.