跳到内容

使用结构化LLM#

在LlamaIndex中提取结构化数据的最高级方法是实例化一个结构化LLM。首先,像之前一样实例化我们的Pydantic类

from datetime import datetime


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 以获取LLM(为简单起见,我们将使用OpenAI,但您也可以随时使用其他LLM)
  • 获取OpenAI API密钥并将其设置为名为 OPENAI_API_KEY 的环境变量
  • pip install llama-index-readers-file 以获取PDF读取器
    • 注意:为了更好地解析PDF,我们推荐使用 LlamaParse

现在,让我们加载实际发票的文本

from llama_index.readers.file import PDFReader
from pathlib import Path

pdf_reader = PDFReader()
documents = pdf_reader.load_data(file=Path("./uber_receipt.pdf"))
text = documents[0].text

然后实例化一个LLM,将我们的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 对象,它有两个属性: textrawtext 包含通过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,因此LLM尽力使用了信用卡号。Pydantic验证不是保证!

responseraw 属性(有点令人困惑)包含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类完全相同:您可以调用 chatstreamachatastream 等,并且在所有情况下,它都会以Pydantic对象响应。您还可以将结构化LLM作为参数传递给 VectorStoreIndex.as_query_engine(llm=sllm),它将自动以结构化对象响应您的RAG查询。

结构化LLM会为您处理所有提示词工程。如果您想对提示词有更多控制权,请继续阅读 结构化预测