使用结构化LLM
在LlamaIndex中提取结构化数据的最高层级方法是实例化一个结构化LLM。首先,让我们像之前那样实例化我们的Pydantic类:
from datetime import datetimefrom pydantic import BaseModel, Field
class LineItem(BaseModel): """A line item in an invoice."""
item_name: str = Field(description="The name of this item") price: float = Field(description="The price of this item")
class Invoice(BaseModel): """A representation of information from an invoice."""
invoice_id: str = Field( description="A unique identifier for this invoice, often a number" ) date: datetime = Field(description="The date this invoice was created") line_items: list[LineItem] = Field( description="A list of all the items in this invoice" )如果您是首次使用LlamaIndex,让我们先安装所需依赖:
pip install llama-index-core llama-index-llms-openai用于获取大语言模型(为简化起见我们将使用OpenAI,但你始终可以使用其他模型)- 获取一个OpenAI API密钥,并将其设置为名为
OPENAI_API_KEY的环境变量 pip install llama-index-readers-fileto get the PDFReader- 注意:为了更好地解析PDF文件,我们推荐使用 LlamaParse
现在让我们加载一份实际发票的文本:
from llama_index.readers.file import PDFReaderfrom pathlib import Path
pdf_reader = PDFReader()documents = pdf_reader.load_data(file=Path("./uber_receipt.pdf"))text = documents[0].text然后让我们实例化一个大型语言模型,给它我们的Pydantic类,接着要求它使用发票的纯文本complete:
from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-4o")sllm = llm.as_structured_llm(Invoice)
response = sllm.complete(text)response 是一个具有两个属性的 LlamaIndex CompletionResponse:text 和 raw。text 包含经过 Pydantic 处理后的 JSON 序列化响应:
json_response = json.loads(response.text)print(json.dumps(json_response, indent=2)){ "invoice_id": "Visa \u2022\u2022\u2022\u20224469", "date": "2024-10-10T19:49:00", "line_items": [ {"item_name": "Trip fare", "price": 12.18}, {"item_name": "Access for All Fee", "price": 0.1}, {"item_name": "CA Driver Benefits", "price": 0.32}, {"item_name": "Booking Fee", "price": 2.0}, {"item_name": "San Francisco City Tax", "price": 0.21}, ],}请注意,此发票没有ID,因此大型语言模型已尽力尝试并使用信用卡号码。Pydantic验证并非绝对保证!
响应的 raw 属性(有些令人困惑地)包含了 Pydantic 对象本身:
from pprint import pprint
pprint(response.raw)Invoice( invoice_id="Visa ••••4469", date=datetime.datetime(2024, 10, 10, 19, 49), line_items=[ LineItem(item_name="Trip fare", price=12.18), LineItem(item_name="Access for All Fee", price=0.1), LineItem(item_name="CA Driver Benefits", price=0.32), LineItem(item_name="Booking Fee", price=2.0), LineItem(item_name="San Francisco City Tax", price=0.21), ],)请注意,Pydantic 正在创建一个完整的 datetime 对象,而不仅仅是转换字符串。
结构化LLM的工作方式与常规LLM类完全相同:您可以调用chat、stream、achat、astream等,它将在所有情况下返回Pydantic对象。您还可以将结构化LLM作为参数传递给VectorStoreIndex.as_query_engine(llm=sllm),它将自动以结构化对象响应您的RAG查询。
结构化LLM为您处理所有提示生成。如果您希望对提示有更多控制权,请继续学习结构化预测。