You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在LlamaIndex中调用LlamaCPP获得与纯LlamaCPP一致的结果?

问题:如何调整LlamaIndex实现,使其调用LlamaCPP后输出与纯LlamaCPP一致?

我尝试将纯LlamaCPP Python中针对葡萄牙语法律PDF文件的查询逻辑迁移到LlamaIndex中,但二者输出结果不一致。

纯LlamaCPP实现代码

from llama_cpp import Llama
import os, re, sys
from pypdf import PdfReader

reader = PdfReader('inicial_pg10_teste.pdf')
total_pages = len(reader.pages)

texto_inicial = ''
for page_num in range(total_pages):
    page = reader.pages[page_num]
    texto_inicial += page.extract_text()

model_name = 'mistral-br-pt-q4_k_m.gguf'  
llm = Llama(
      model_path=f"llms/{model_name}",
      n_gpu_layers=20,
      n_ctx=7000,
)
response = llm.create_chat_completion(
      messages = [
          {
              "role": "user",
              "content": f"""Quem são os réus desta ação? {texto_inicial}"""
          }
      ]
)
print(response['choices'][0]['message']['content'])

正确输出结果

Os réus neste processo trabalhista são:

Degustare e Servir Alimentação e Serviços Técnicos Ltda. (empresa de
direito privado, inscrita no CNPJ nº: 17.104.821/0001 -70, com sede na
Avenida do Rio Branco, nº 869, Centro, Niterói, Rio de Janeiro, CEP:
24020 -006) Secretaria de Estado de Educação do Rio de Janeiro (SEERJ)
(pessoa jurídica de direito público interno, inscrita no CNPJ sob o nº
42.498.600/0001 -71, com sede na Rua Pinheiro Machado, s/n°, Palácio da Guanaba, Laranjeiras, Rio de Janeiro/RJ, CEP 22.231 -901)

LlamaIndex实现代码

import os, re, sys
from pathlib import Path
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex, download_loader, ServiceContext, PromptTemplate
from llama_index.llms.llama_cpp import LlamaCPP
from llama_index.readers.file import PDFReader

loader = PDFReader()
documents = loader.load_data(file=Path('inicial_pg10_teste.pdf'))

model_name = 'mistral-br-pt-q4_k_m.gguf'

llm = LlamaCPP(
      model_path=f"llms/{model_name}",
      model_kwargs={"n_gpu_layers": 20},
      context_window=7000,
)
service_context = ServiceContext.from_defaults(
    llm=llm, 
    embed_model="local",
    chunk_size=6235
)
index = VectorStoreIndex.from_documents(documents, service_context=service_context)

template = (
    "<s> [INST] {query_str} {context_str} [/INST]"
)

custom_prompt = PromptTemplate(template)
query_engine = index.as_query_engine(text_qa_template=custom_prompt)
question = "Quem são os réus desta ação?"
response = query_engine.query(question)
print(response)

错误输出结果

Os réus neste processo são a Reclamada e a 2ª Reclamada.


解决方法

1. 完全对齐纯LlamaCPP的输入逻辑

纯LlamaCPP是将完整PDF文本直接拼接在问题后作为单条输入,LlamaIndex默认的分块检索逻辑会改变输入结构。要得到一致结果,可绕过向量检索,直接将完整文档传入LLM:

# 替换LlamaIndex代码中索引及查询引擎部分
# 合并所有文档内容为完整文本
full_text = "\n".join([doc.text for doc in documents])

# 构造与纯LlamaCPP一致的输入prompt
prompt = f"""Quem são os réus desta ação? {full_text}"""

# 直接调用LLM生成结果
response = llm.complete(prompt)
print(response.text)

2. 保留检索能力的前提下调整策略

若不想放弃分块检索,需确保能召回包含完整被告信息的片段:

  • 调整分块参数:增大chunk_size(比如设为7000,匹配模型上下文窗口),同时设置chunk_overlap=200,避免关键信息被拆分到不同片段中。
  • 优化检索范围:使用RetrieverQueryEngine并设置similarity_top_k=10,确保召回所有相关片段后再拼接传入LLM。
  • 强化Prompt指令:补充明确要求,避免模型返回泛称:
    template = (
        "<s> [INST] Você é um assistente jurídico especializado em processos brasileiros. "
        "Com base no contexto fornecido, responda a pergunta com os nomes completos das partes réus, incluindo dados como CNPJ e sede. "
        "Pergunta: {query_str} "
        "Contexto: {context_str} [/INST]"
    )
    

3. 统一PDF文本提取方式

纯LlamaCPP用pypdf提取文本,LlamaIndex的PDFReader可能使用不同底层库,导致文本内容差异。可强制LlamaIndex使用pypdf:

# 替换PDF加载部分
from pypdf import PdfReader
from llama_index.core import Document

def load_pdf_with_pypdf(file_path):
    reader = PdfReader(file_path)
    text = "\n".join([page.extract_text() for page in reader.pages])
    return [Document(text=text)]

documents = load_pdf_with_pypdf('inicial_pg10_teste.pdf')

内容的提问来源于stack exchange,提问作者celsowm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 00:35:02