Năm 2010, nếu một công ty dược phẩm muốn xây knowledge graph từ toàn bộ tài liệu nghiên cứu nội bộ, câu trả lời thực tế là: cần đội người. Một nhóm ontologist thiết kế schema, phân loại entity°, định nghĩa từng loại relationship. Một nhóm data steward đọc từng tài liệu, annotate mention, đánh dấu từng claim. Một nhóm domain° expert kiểm tra mọi edge quan trọng trước khi vào graph. Vài triệu đô. Vài năm. Kết quả: một graph mà mỗi edge đều có người nhìn qua. Scope hẹp, nhưng những gì có thì tin được.
Năm 2024, cùng tác vụ đó cần một buổi chiều. Một bộ tài liệu, một API call, một prompt hỏi LLM rút ra entities và relationships, và kết quả đổ thẳng vào database. Rẻ hơn hàng chục lần, nhanh hơn hàng trăm lần.
Câu hỏi của chương này không phải "điều đó có tốt không". Câu hỏi là điều đó thay đổi gì, theo hướng nào, và chi phí mà không ai tính đến đặt ở chỗ nào.
Để trả lời, cần nhìn lại ba thế hệ knowledge graph, vì mỗi thế hệ không chỉ thay đổi chi phí mà thay đổi loại lỗi mà người dùng phải sống cùng.
Thế hệ đầu tiên là curation hoàn toàn thủ công. Google Knowledge Graph, ra mắt năm 2012, xây trên nền Freebase và đội ngũ editorial curate từ Wikipedia infoboxes và semantic web triples đã được verify. Chi phí cao, quy trình chậm, scope bị giới hạn bởi những gì đội ngũ người có thể xử lý. Loại lỗi đặc trưng của thế hệ này rất rõ ràng: entity chưa có trong cơ sở dữ liệu thì không có trong graph. Người dùng biết chính xác graph đang thiếu gì, vì "chưa có" là trạng thái quan sát được, không phải trạng thái ẩn.
Thế hệ thứ hai là extraction pipeline truyền thống: Named Entity Recognition kết hợp Relation Extraction, dùng rule-based hoặc model° được train trên annotated corpus. Chi phí giảm so với thế hệ đầu, nhưng vẫn đắt: cần domain expert viết rule, cần annotated data per domain, giòn với văn phong mới hoặc domain chưa từng thấy trong training. Loại lỗi của thế hệ này khác ở chỗ người dùng vẫn có thể debug bằng cách nhìn vào câu nguồn: recall thấp ở entity ít phổ biến, relation extraction sai ở cấu trúc câu phức, và khi sai thì sai theo cách có thể truy về rule hoặc pattern cụ thể.
Thế hệ thứ ba là LLM extraction, và đây là nơi kinh tế học đảo ngược. Một prompt có thể extract entity và relationship từ văn bản bất kỳ, không cần training data per domain, không cần viết rule, không cần domain expert trong vòng lặp. Chi phí giảm hai bậc so với thế hệ đầu. Và cùng với đó xuất hiện một loại lỗi mà hai thế hệ trước không có: entity trùng không gộp, quan hệ bịa ra từ câu điều kiện trông hoàn toàn hợp lý, độ chính xác không đồng đều giữa vùng tài liệu phổ biến và vùng ít phổ biến trong training data của model. Tất cả những điều đó, trong graph đã được render, trông hoàn chỉnh.
Đây là điểm mấu chốt của thế hệ thứ ba: loại lỗi mới không phải "không biết gì về domain này" như thế hệ đầu, không phải "câu này quá phức tạp" như thế hệ hai. Loại lỗi mới không hiển thị. Graph đầy edge, edge có tên nghe hợp lý, entity có property. Người dùng cuối không có cách phân biệt edge nào đáng tin và edge nào được sinh ra từ cách model hiểu một câu điều kiện. Và hệ thống downstream trích dẫn graph đó như sự thật có cấu trúc.
Graph trông hoàn chỉnh nguy hiểm hơn graph rõ ràng chưa xong, vì cái trông hoàn chỉnh không ai nghi ngờ.
Buổi demo diễn ra vào thứ Tư. Đội sản phẩm trình bày knowledge graph vừa xây từ hàng nghìn tài liệu pháp lý nội bộ: công ty nào liên quan đến công ty nào, ai là founder, đâu là hợp đồng giữa các bên. Visualization đẹp, query trả về nhanh, lãnh đạo gật đầu.
Ba tuần sau, đội bắt đầu dùng thật để trả lời câu hỏi của analyst. Ba tuần sau đó là buổi meeting debug đầu tiên.
"John Smith", "J. Smith", và "Smith, John" là ba node khác nhau trong graph. Mọi query về ông này trả về kết quả rời rạc, mỗi query bắt được một phần và bỏ sót hai phần còn lại. Không ai trong đội biết node nào là canonical, không ai biết bắt đầu merge từ đâu, và không có ghi chép nào trong pipeline về việc ba string đó đến từ tài liệu nào.
Một edge "ACQUIRED" nối Company A vào Company B, với confidence mặc định là cao vì pipeline không có cơ chế confidence riêng. Nguồn của edge đó là câu sau trong một hợp đồng: "In the event that Company A were to acquire Company B, the following indemnification clauses shall apply." LLM đọc "Company A acquire Company B" và extract thành sự kiện. Acquisition chưa bao giờ xảy ra.
Một giám đốc xuất hiện cùng lúc là CEO và CTO của cùng một công ty trong graph, không phải vì ông giữ hai vai, mà vì hai tài liệu từ hai thời điểm khác nhau mô tả ông theo hai cách khác nhau và pipeline không có cơ chế tracking temporal context.
Đây là ba tuần điển hình sau một pipeline extraction đơn giản. Không phải vì đội làm sai, mà vì approach mặc định thiếu một khái niệm căn bản: pipeline không có concept "claim". Mọi edge được tạo ra với cùng trọng lượng, cùng địa vị. Không edge nào biết mình đến từ đâu. Không edge nào biết mình được tạo ra từ câu thật hay câu điều kiện. Không entity nào biết có mention khác đang chỉ về cùng thực thể trong thế giới thật.
Naive fix phổ biến nhất là làm prompt tốt hơn. Thêm instruction: "Chỉ extract relationship đã thực sự xảy ra, không extract câu điều kiện hay giả định." Chạy lại trên một sample nhỏ, đo precision, thấy cải thiện, report cho lãnh đạo. Đây là fix đúng hướng và giải được một triệu chứng cụ thể. Nhưng không phải fix đúng tầng.
Prompt tốt hơn không giải entity resolution°. "John Smith" và "J. Smith" vẫn là hai node vì pipeline không có bước so sánh mention qua tài liệu. Nó không tạo provenance: ba tháng sau khi graph trả lời sai một câu hỏi, đội không có đường truy về edge nào gây ra lỗi, tài liệu nào là nguồn, prompt version nào tạo ra nó. Nó không calibrate confidence theo loại relationship: mọi edge vẫn bình đẳng, dù "founded_by" với "might_be_affiliated_with" có yêu cầu độ chính xác hoàn toàn khác nhau.
Sample nhỏ đo precision trên những gì có thể nhìn thấy. Recall thấp ở entity hiếm không nhìn thấy được từ sample. Entity split không phát hiện được nếu không có ground truth về entity canonical là gì.
Cái thiếu không phải prompt tốt hơn. Cái thiếu là một khái niệm khác về pipeline: extraction không phải transform từ text sang graph, mà là sinh ra tập claim, mỗi claim có provenance, có confidence, có ngưỡng chấp nhận riêng theo loại. Từ khái niệm đó, pipeline có cấu trúc hoàn toàn khác.
Bốn tầng sau không phải checklist để tick xong rồi thôi. Chúng là bốn câu hỏi mà một pipeline extraction phải trả lời được trước khi edge đầu tiên vào graph, và mỗi câu phải được thiết kế để trả lời từ ngày đầu, không phải thêm vào sau khi pipeline đã chạy.
Hai cách hỏi LLM trông gần giống nhau nhưng không giống nhau. Cách một: "Hãy rút ra entities và relationships từ đoạn văn này." Cách hai: "Trong schema sau, gồm bốn loại entity và sáu loại relationship được định nghĩa dưới đây, những cái nào xuất hiện trong đoạn văn này?"
Với cách hỏi thứ nhất, LLM có thể trả về loại relationship "might_be_involved_in_the_same_sector" hay "was_mentioned_alongside" hay bất kỳ relationship nào model thấy phù hợp với văn bản. Không ai hứa nó sẽ không làm vậy. Với cách hỏi thứ hai, model không thể bịa ra loại edge ngoài schema, vì schema là tập câu trả lời hợp lệ duy nhất.
Đây là điều ontology làm trong pipeline extraction: không phải giúp LLM hiểu domain tốt hơn, mà là giới hạn không gian output về đúng tập mà người thiết kế đã định nghĩa và chịu trách nhiệm. Ở chương trước khi nói về mô hình hoá, ontology phục vụ người đọc là con người; ở đây nó phục vụ máy thực thi, và hợp đồng với máy đòi độ rõ ràng cao hơn: tên relationship phải phân biệt được, không chỉ đọc hiểu được, và example positive và negative phải được cung cấp để model calibrate đúng ranh giới.
Trade-off của schema-guided extraction là recall. Relationship nằm ngoài schema sẽ không được extract dù có trong tài liệu. Đây không phải bug mà là feature: scope kiểm soát được quan trọng hơn recall cao mà không kiểm soát được, vì đội không có cách xử lý edge với loại relationship không ai định nghĩa là gì.
"John Smith", "J. Smith", và "Smith, John" là ba mention của cùng một thực thể trong thế giới thật. Quyết định chúng có phải cùng entity hay không là bài toán entity resolution, và nó không thể giải trong một prompt extraction vì extraction nhìn từng tài liệu một, không nhìn toàn bộ corpus cùng lúc.
Entity resolution là bài toán clustering: thu thập tất cả mention, tính similarity giữa từng cặp dựa trên tên và context đồng xuất hiện và loại entity, rồi cluster những mention đủ tương đồng về cùng một entity canonical. Cấu trúc của bài toán là clustering các node trên similarity graph, trong đó mỗi pair mention có similarity weight và có ngưỡng quyết định merge hay giữ riêng.
Tại sao phải tách thành bài toán riêng: nếu entity resolution bị bỏ qua, mọi metric trên graph tính trên entity bị fragment. Người thật có 80 connections nhưng bị split thành ba node, mỗi node thấy 25 đến 30 connections. Centrality của ông không xuất hiện đúng trong graph. Community detection° tìm community sai vì entity split tạo boundary giả. Và không có cách phát hiện điều này từ bên ngoài graph nếu không có ground truth về entity nào là canonical.
Entity resolution phải chạy sau extraction và trước mọi thao tác phân tích. Không phải một bước nâng cao cho version 2.0 của pipeline, mà là điều kiện cần để bất kỳ metric nào trên graph có nghĩa.
Mỗi edge phải biết mình đến từ đâu: tài liệu nào, đoạn văn nào, chunk ID nào, lần extraction nào, version model và prompt nào. Không phải vì audit trail là tốt theo nguyên lý, mà vì không có provenance thì không có đường debug.
Khi graph downstream trả lời sai một câu hỏi multi-hop ba tháng sau, có hai cách debug: cách đầu là re-extract toàn bộ graph và so sánh, tốn nhiều ngày và không chắc tìm ra nguyên nhân. Cách hai là theo provenance từ câu trả lời sai về node sai về edge sai về tài liệu nguồn và đoạn văn cụ thể, mất vài giờ và có kết quả. Cách hai chỉ tồn tại nếu provenance được gắn vào từng edge từ đầu.
Chi phí lưu trữ provenance thật không nhỏ ở hàng triệu edge. Quyết định thiết kế là lưu metadata inline trong graph hay trong separate store với edge ID tham chiếu. Cả hai có trade-off về query speed và storage cost, không có câu trả lời đúng tuyệt đối. Điều không có lựa chọn là không lưu.
Không phải một threshold chung cho mọi loại edge. "FOUNDED_BY" giữa người và công ty là high-stakes claim: nếu sai, câu trả lời về lịch sử công ty sai theo. Ngưỡng phải cao. "INFLUENCED_BY" giữa hai sản phẩm hay hai tư tưởng là claim inherently ambiguous: tài liệu ít khi nói thẳng, context quyết định, và mức độ sai có thể chấp nhận hơn. Ngưỡng thấp hơn, hoặc dùng weighted edge thay vì binary.
Câu hỏi calibrate ngưỡng không phải "accuracy đạt bao nhiêu phần trăm là đủ". Câu hỏi là: nếu edge này sai, downstream bị ảnh hưởng gì? Edge dùng để trả lời câu hỏi factual cần precision cao. Edge dùng để cluster sản phẩm tương tự có thể chấp nhận noise vì cluster đủ lớn để một edge sai không phá kết quả tổng. Mức độ ảnh hưởng của lỗi calibrate ngưỡng, không phải accuracy đo trên sample nhỏ.
“Graph dựng tay sai ở chỗ bạn biết là chưa làm, graph máy dựng sai ở chỗ bạn tin là đã xong.”
Amazon có vấn đề mà quy mô làm nó không thể giải thủ công: hàng trăm triệu seller listing, mỗi listing là mô tả tự do của seller, không schema, không chuẩn hoá, không nhất quán giữa các seller. Cùng một chiếc pin, mỗi người bán mô tả theo cách khác nhau với tên sản phẩm khác nhau và attribute được ghi theo format khác nhau. Câu hỏi từ phía khách hàng, chẳng hạn "pin nào tương thích với máy ảnh này", đòi structured relationship không có trong raw text: product-to-compatible-accessory, product-to-attribute, product-to-category. Không thể curate thủ công ở quy mô đó.
AutoKnow, được Amazon Research công bố tại KDD 2020, là hệ thống extraction tự động từ ba nguồn: product description từ seller, customer Q&A, và customer review. Ba nguồn này bổ sung cho nhau theo cách có thể đoán trước. Description của seller có thể sai hoặc thiếu vì seller có động cơ marketing. Q&A phản ánh câu hỏi thật của khách, thường hỏi đúng thứ người mua cần biết. Review phản ánh trải nghiệm thực tế sau khi dùng. Product taxonomy của Amazon đóng vai trò schema ràng buộc extraction, tức là schema-guided theo đúng tầng đầu tiên của pipeline.
Entity resolution ở đây là bài toán sản phẩm: cùng một chiếc tai nghe, seller A ghi "Sony WH-1000XM5", seller B ghi "Sony Noise Cancelling Headphones XM5 Series", seller C ghi "WH1000XM5 Headphone Sony". Ba string khác nhau, cùng product. Nếu không resolve, mọi attribute và review gắn vào ba entity riêng, không phải một. Query về sản phẩm đó trả về ba phần kết quả không liên kết và analyst không thể tổng hợp được gì.
Điều đáng chú ý nhất của AutoKnow không phải kỹ thuật extraction hay thuật toán entity resolution cụ thể, mà là cách xử lý câu hỏi human-in-the-loop.
Ở quy mô hàng trăm triệu sản phẩm, human review toàn bộ extraction là không thể. Nhưng không review gì cả cũng không được vì accuracy sẽ không đủ cho các claim quan trọng. AutoKnow giải bài toán này bằng cách phân loại extraction theo hai trục: confidence của model và tác động nếu extraction sai.
Vùng confidence cao và tác động thấp, ví dụ attribute-value phổ biến như màu sắc hay trọng lượng, không cần human review. Model đúng ở đây với xác suất cao và nếu sai thì sai ở thứ ít ảnh hưởng đến quyết định mua. Vùng confidence thấp, bất kể loại claim nào, cần human review trước khi vào graph vì model không chắc. Vùng confidence cao nhưng tác động cao, ví dụ compatibility claim vì sai ở đây dẫn đến khách mua nhầm phụ kiện, vẫn cần human spot-check thường xuyên.
Đây là áp dụng tầng bốn của pipeline, confidence per relationship type, với thêm một chiều: không chỉ confidence của model, mà confidence nhân với tác động theo loại claim trong domain cụ thể. Kết quả là đội chỉ review một phần nhỏ của extraction nhưng review đúng phần quan trọng nhất.
Bài học từ AutoKnow không phải kiến trúc cụ thể của hệ thống, mà là cách đặt câu hỏi. Câu hỏi không phải "tự động hay thủ công", vì ở quy mô đủ lớn không pipeline nào hoàn toàn tự động mà đủ tin, và không đội nào review toàn bộ mà đủ nhanh. Câu hỏi là: với ngân sách người cố định, đặt nó vào đâu để mỗi giờ review loại bỏ nhiều lỗi có tác động nhất? Confidence kết hợp impact là framework để trả lời câu hỏi đó, không phải để quyết định tự động hay không theo nghĩa tuyệt đối.
Nếu graph có một triệu edge và đội có thể annotate thủ công một nghìn edge trong một tuần, precision và recall toàn graph không đo được trực tiếp. Đây không phải vấn đề của tool cụ thể hay methodology cụ thể. Đây là giới hạn của bài toán.
Phần lớn đội giải quyết bằng cách bỏ qua: dùng "trông có vẻ đúng" khi nhìn vào một subset nhỏ, hoặc dùng "demo tốt" như proxy cho quality. Điều này không phải vì đội không cẩn thận mà vì không có tool tốt và benchmark chuẩn cho bài toán này. Ngành này còn non ở bài toán eval, và đây là thông tin, không phải lời xin lỗi.
Ba cách đo có thể làm ngay, không cần chờ benchmark chuẩn:
Cách đầu là sampling theo tầng. Thay vì sample ngẫu nhiên toàn graph, sample theo relationship type, vì accuracy không đồng đều giữa các loại. "FOUNDED_BY" có thể đạt precision cao vì claim này phổ biến và thường được phát biểu rõ ràng trong tài liệu. "INFLUENCED_BY" có thể thấp hơn nhiều vì claim inherently subjective và tài liệu ít khi nói thẳng. Sampling theo tầng cho số liệu có thể action được: biết loại nào cần tăng threshold hoặc thêm few-shot example trong prompt.
Cách hai là đo entity resolution riêng khỏi relation extraction. Đây là hai bài toán với loại lỗi và cách đo hoàn toàn khác nhau. Entity resolution có ground truth rõ ràng hơn: hai mention này có phải cùng entity không là câu hỏi có câu trả lời binary. Đo được precision và recall trên tập mention pairs đã annotate với sample nhỏ hơn nhiều so với toàn graph. Quan trọng hơn, nếu entity resolution quality thấp, mọi metric trên relation extraction trở nên vô nghĩa vì entity làm nền đã sai. Đo ER trước, fix ER trước, rồi mới đo RE.
Cách ba là downstream task proxy. Nếu hệ thống retrieval dùng graph này trả lời câu hỏi multi-hop tốt hơn sau khi entity resolution được cải thiện, đó là signal graph quality đi đúng hướng. Proxy này không đo graph trực tiếp, nhưng đo thứ mà graph cần phục vụ. Một graph đo tốt trên proxy là graph phục vụ được mục đích, dù quality tuyệt đối của từng edge không đo được hết.
Implication thiết kế của thực trạng eval còn non này là: provenance không phải audit trail về sau, mà là eval infrastructure ngay từ đầu. Khi không có benchmark chuẩn để đo quality toàn graph, khả năng trace từng edge về tài liệu nguồn là cách duy nhất để debug có mục tiêu khi downstream trả lời sai. Provenance không được gắn vào sau khi đã xây graph và nhận ra cần debug; nó phải có từ ngày pipeline đầu tiên chạy.
Entity bị split thành nhiều node, mỗi node chỉ thấy một phần connections thật. Người thật có degree 80 nhưng bị split thành ba node: một node có 32 connections, một node có 28, một node có 20. Không node nào trong số đó được xếp là hub trong graph. Community detection tìm community sai vì boundary giả do entity split tạo ra. Centrality tính sai vì flow° qua graph đi qua ba node phantom thay vì một.
Nguy hiểm đặc trưng của failure mode này là kết quả trông hợp lý. Graph đầy edge, câu trả lời có cấu trúc, visualization đẹp. Không có gì rõ ràng sai khi nhìn vào từ bên ngoài. Chỉ có người biết ground truth entity canonical mới phát hiện được, và người đó thường không phải người đang query graph hàng ngày.
Tài liệu sống. Press release mới, filing mới, product launch mới, nhân sự thay đổi. Graph không được re-extract thì sau sáu tháng là bản đồ của công ty sáu tháng trước, nhưng hệ thống vẫn trích dẫn nó như sự thật có cấu trúc.
Đây là vấn đề freshness và vòng đời, và cơ chế giải đặt ở chỗ khác, nhưng quyết định thiết kế pipeline phải dự phòng cho nó từ đầu: provenance bao gồm timestamp extraction để biết edge nào đến từ tài liệu thuộc giai đoạn nào, entity ID ổn định qua các lần re-extract để lần sau không tạo duplicate, schema version control để biết lần re-extract sau đang dùng ontology version nào. Không thiết kế cho freshness từ đầu thì khi cần update là phải rebuild từ đầu toàn bộ graph.
Downstream retrieval không có cơ chế phòng thủ nếu graph không phân biệt edge confidence 95% và edge confidence 55%. Câu hỏi multi-hop theo ba bước: nếu mỗi bước đi qua một edge với confidence độc lập là 80%, confidence tổng sau ba hop chỉ còn khoảng 51%. Với edge confidence 55% mỗi bước, sau ba hop còn khoảng 17%.
Không phải về con số cụ thể, vì confidence của LLM extraction không thể diễn giải như xác suất thuần tuý theo nghĩa xác suất thống kê. Về nguyên lý: hệ thống trả lời câu hỏi multi-hop mà không biết nó đang tin vào gì với mức độ nào, và người dùng cũng không biết. Câu trả lời cuối có thể đúng, có thể sai, và không có cách phân biệt từ bên ngoài mà không có confidence kèm theo từng bước.
Confidence phải là phần của schema từ đầu, không phải metadata add-on khi đội nhận ra cần nó.
Pipeline bốn tầng không phải giải pháp đúng cho mọi bài toán extraction.
Domain hẹp, tài liệu chuẩn hoá, cấu trúc rõ thì rule-based extraction vẫn thắng về độ tin và chi phí debug. Extract tên, địa chỉ, và số hợp đồng từ hoá đơn có template cố định: regex cộng schema validation đủ, rẻ hơn, và khi sai thì biết ngay sai ở rule nào. LLM extraction trả công ở quy mô và độ hỗn loạn, ở nhiều loại tài liệu với nhiều cách diễn đạt khác nhau. Tài liệu ít và chuẩn hoá thì cost-benefit nghiêng về phía đơn giản mà không mất gì.
Không phải lúc nào cũng cần full pipeline bốn tầng. Entity resolution không cần nếu entities đã unique trong nguồn: product ID, user ID, account number là những định danh không cần resolve. Provenance metadata không cần nếu graph nhỏ và đội có thể audit thủ công toàn bộ edge, biết chính xác từng edge đến từ tài liệu nào. Confidence threshold không cần nếu chỉ có một loại relationship đơn giản và đội đã validate thủ công đủ để tin vào toàn bộ corpus đó.
Điểm chung của ba điều kiện trên là khả năng kiểm soát. Pipeline đơn giản đủ khi đội hiểu rõ toàn bộ graph và có thể trace lỗi bằng tay, không phải khi graph nhỏ theo nghĩa số lượng edge. Một graph mười nghìn edge mà mỗi edge đến từ tài liệu đã xác định, bởi đội đã review, là graph đơn giản đủ để không cần provenance automation. Một graph mười nghìn edge từ LLM extraction mà không ai biết từng edge sinh ra khi nào, từ câu nào, là graph cần đủ bốn tầng.
Câu hỏi phân biệt khi nào cần full pipeline: nếu graph này trả lời sai một câu hỏi sáu tháng sau, bạn bắt đầu debug từ đâu? Nếu câu trả lời là "mình biết ngay vì graph nhỏ và rõ, mình biết từng edge từ đâu", pipeline đơn giản đủ. Nếu câu trả lời là "mình phải re-extract lại toàn bộ và so sánh", provenance và confidence phải có từ đầu.
Pipeline này, với đủ bốn tầng, giải được bài toán extraction một lần với corpus ổn định. Nhưng tài liệu không đứng im. Model mới ra, ontology cần tiến hoá theo domain hiểu biết mới, confidence threshold cần recalibrate khi phân phối tài liệu thay đổi. Câu hỏi mà chương này chưa trả lời: ai trả lời khi graph này trả lời sai sáu tháng sau, và cơ chế nào kéo graph theo tài liệu mới mà không phải rebuild từ đầu mỗi lần có gì thay đổi?