Google開源框架LangExtract初體驗(yàn)
從AI技術(shù)維度分類,大約可以將LangExtract歸為RAG框架,但從細(xì)處分辨,二者實(shí)有比較明顯的區(qū)別。RAG的關(guān)注重點(diǎn)是檢索,LangExtract的重點(diǎn)則如其名,是對數(shù)據(jù)的提取,且主要針對非結(jié)構(gòu)化文本數(shù)據(jù)進(jìn)行結(jié)構(gòu)化提取。
LangExtract官網(wǎng)對它的介紹為:“一個(gè)使用大語言模型從非結(jié)構(gòu)化文本中提取結(jié)構(gòu)化信息的 Python 庫,具備精確的源定位和交互式可視化功能。”提取結(jié)構(gòu)化信息是其核心功能,而其亮點(diǎn)則是能夠提供精確的源定位,并完成交互式的可視化呈現(xiàn)。
之所以能提供精確的源定位,在于LangChain并沒有使用embedding的機(jī)制通過向量進(jìn)行相似度計(jì)算和檢索,而是采用了一套精巧的確定性文本對齊算法:“首先通過指令讓LLM返回原文片段,然后利用WordAligner進(jìn)行多層次匹配——從精確字符串匹配到模糊相似度計(jì)算,但始終避免了基于向量embedding的模糊對齊?!?/span>
例如,運(yùn)行官方提供的醫(yī)療文本的提取代碼,可得到如下結(jié)果:
Extracted entities:
? Dosage: 400 mg (pos: 13-19)
? Route: PO (pos: 20-22)
? Medication: Ibuprofen (pos: 23-32)
? Frequency: q4h (pos: 33-36)
? Duration: for two days (pos: 37-49)結(jié)果清晰給出了提取的實(shí)體在文本所處的位置。在生成的jsonl文件中,以Dosage為例,輸出的結(jié)構(gòu)化數(shù)據(jù)為:
{"extraction_class":"dosage","extraction_text":"400 mg","char_interval":{"start_pos":13,"end_pos":19},"alignment_status":"match_exact","extraction_index":1,"group_index":0,"description":null,"attributes":{}}其中的char_interval屬性值就是提取結(jié)果在原文中的位置,很好地體現(xiàn)了它的溯源能力。
完成提取后,LangExtract會自動生成一個(gè)HTML文件,打開網(wǎng)頁能夠看到提取結(jié)構(gòu)的一種交互式可視化呈現(xiàn):
圖片
雖說LangExtract官網(wǎng)將其定位為“Gemini 驅(qū)動的信息提取庫”,這大概是為了配合Google大模型的宣傳手段,但它顯然不會愚蠢得僅支持Gemini模型。事實(shí)上,它可以支持任何LLM,即便官方?jīng)]有提供支持,也可以自定義模型的Provider。事實(shí)上,前面輸出的結(jié)果使用的模型是我通過Ollama在本地部署的lamma3:7b模型:
result = lx.extract(
text_or_documents=input_text,
prompt_description=prompt_description,
examples=examples,
model_id="llama3:latest",# Automatically selects Ollama provider
model_url="http://localhost:11434",
fence_output=False,
use_schema_constraints=False)為了確保提取的結(jié)構(gòu)化結(jié)果更加可靠,LangExtract用到了需要大模型支持的“受控生成(Controlled Generation)”技術(shù),這確實(shí)是Gemini的一大優(yōu)勢。除了受控生成技術(shù),LangExtract還通過運(yùn)用“少樣本”示例盡可能確保結(jié)果的穩(wěn)定性:
examples = [
lx.data.ExampleData(
text="Patient was given 250 mg IV Cefazolin TID for one week.",
extractinotallow=[
lx.data.Extraction(extraction_class="dosage", extraction_text="250 mg"),
lx.data.Extraction(extraction_class="route", extraction_text="IV"),
lx.data.Extraction(extraction_class="medication", extraction_text="Cefazolin"),
lx.data.Extraction(extraction_class="frequency", extraction_text="TID"), # TID = three times a day
lx.data.Extraction(extraction_class="duration", extraction_text="for one week")
]
)
]我看現(xiàn)在很多AI框架都在API上做文章,于不知不覺中引入提示詞工程,從而提升LLM生成結(jié)果的準(zhǔn)確性。例如使用CrewAI創(chuàng)建Agent時(shí),就要求給定Agent的Role、Goal和Backstory。LangExtract通過
ExampleData雖然LangExtract完全可以精確提取超長文本的高價(jià)值信息,卻是以消耗極高的token數(shù)量為代價(jià),因此在生產(chǎn)使用時(shí),必須考慮時(shí)間成本、基礎(chǔ)設(shè)置的資源成本以及算力成本。就以官方使用的《羅密歐與朱麗葉》為例,整個(gè)提取操作會消耗約44000 tokens。而這個(gè)所謂的長文本,其實(shí)還不到3萬個(gè)單詞。
我在本機(jī)嘗試使用lamma:7b的LLM對《羅密歐與朱麗葉》的文本進(jìn)行提取,運(yùn)行沒有多久,CPU就開始瘋狂運(yùn)轉(zhuǎn),不斷散發(fā)熱量,風(fēng)扇開始賣力的工作,結(jié)果沒等執(zhí)行完畢,就拋出了ResolverParsingError錯(cuò)誤。我將LLM切換為更匹配LangExtract的gemma2:9b大模型,仍然出現(xiàn)同樣錯(cuò)誤。顯然,真要讓LangChain為大量非結(jié)構(gòu)性文本提供精確的提取服務(wù),背后需要更好的LLM和更強(qiáng)大的算力支持。
另一個(gè)不足之處在于LangExtract目前僅支持文本字符串作為文本源,一些常見的文本文檔文件,如PDF、DOCX,暫時(shí)都不支持。當(dāng)然,社區(qū)已經(jīng)看到了這一問題,目前作為Proposal的Issue提交到了LangExtract的Issue列表中。
無論如何,LangExtract為我們處理非結(jié)構(gòu)化文本提供一個(gè)不錯(cuò)的選擇。
























