Skip to main content
Open In Colab MariTalk 是由巴西公司 Maritaca AI 开发的智能助手。 MariTalk 基于经过专门训练、能够出色理解葡萄牙语的语言模型。 本 notebook 通过两个示例演示如何在 LangChain 中使用 MariTalk:
  1. 一个简单示例,展示如何使用 MariTalk 执行任务。
  2. LLM + RAG:第二个示例展示如何回答一个答案存在于长文档中的问题,而该文档超出了 MariTalk 的 token 限制。为此,我们将使用一个简单的搜索器(BM25)首先在文档中检索最相关的段落,然后将其提供给 MariTalk 进行回答。

安装

首先,使用以下命令安装 LangChain 库(及其所有依赖项):
!pip install langchain langchain-core langchain-community httpx

API 密钥

您需要一个 API 密钥,可以从 chat.maritaca.ai(“Chaves da API” 部分)获取。

示例 1 - 宠物名称建议

让我们定义语言模型 ChatMaritalk,并使用您的 API 密钥进行配置。
from langchain_community.chat_models import ChatMaritalk
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts.chat import ChatPromptTemplate

llm = ChatMaritalk(
    model="sabia-2-medium",  # Available models: sabia-2-small and sabia-2-medium
    api_key="",  # Insert your API key here
    temperature=0.7,
    max_tokens=100,
)

output_parser = StrOutputParser()

chat_prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "You are an assistant specialized in suggesting pet names. Given the animal, you must suggest 4 names.",
        ),
        ("human", "I have a {animal}"),
    ]
)

chain = chat_prompt | llm | output_parser

response = chain.invoke({"animal": "dog"})
print(response)  # should answer something like "1. Max\n2. Bella\n3. Charlie\n4. Rocky"

流式生成

对于生成长文本的任务,例如创作长篇文章或翻译大型文档,边生成边接收响应(而非等待完整文本)可能更有优势。这使应用程序响应更快、效率更高,尤其是在生成文本较长时。我们提供两种方法来满足这一需求:一种是同步方式,另一种是异步方式。

同步

from langchain.messages import HumanMessage

messages = [HumanMessage(content="Suggest 3 names for my dog")]

for chunk in llm.stream(messages):
    print(chunk.content, end="", flush=True)

异步

from langchain.messages import HumanMessage


async def async_invoke_chain(animal: str):
    messages = [HumanMessage(content=f"Suggest 3 names for my {animal}")]
    async for chunk in llm._astream(messages):
        print(chunk.message.content, end="", flush=True)


await async_invoke_chain("dog")

示例 2 - RAG + LLM:UNICAMP 2024 入学考试问答系统

在这个示例中,我们需要安装一些额外的库:
!pip install unstructured rank_bm25 pdf2image pdfminer-six pikepdf pypdf unstructured_inference fastapi kaleido uvicorn "pillow<10.1.0" pillow_heif -q

加载数据库

第一步是创建一个包含招生简章信息的数据库。为此,我们将从 COMVEST 官网下载招生简章,并将提取的文本分割为 500 字符的窗口。
from langchain_community.document_loaders import OnlinePDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter

# Loading the COMVEST 2024 notice
loader = OnlinePDFLoader(
    "https://www.comvest.unicamp.br/wp-content/uploads/2023/10/31-2023-Dispoe-sobre-o-Vestibular-Unicamp-2024_com-retificacao.pdf"
)
data = loader.load()

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500, chunk_overlap=100, separators=["\n", " ", ""]
)
texts = text_splitter.split_documents(data)

创建搜索器

现在我们有了数据库,需要一个搜索器。在本示例中,我们将使用简单的 BM25 作为搜索系统,但这可以替换为任何其他搜索器(例如通过嵌入进行搜索)。
from langchain_community.retrievers import BM25Retriever

retriever = BM25Retriever.from_documents(texts)

组合搜索系统 + LLM

现在我们有了搜索器,只需实现一个指定任务的提示词并调用链即可。
from langchain_classic.chains.question_answering import load_qa_chain

prompt = """Baseado nos seguintes documentos, responda a pergunta abaixo.

{context}

Pergunta: {query}
"""

qa_prompt = ChatPromptTemplate.from_messages([("human", prompt)])

chain = load_qa_chain(llm, chain_type="stuff", verbose=True, prompt=qa_prompt)

query = "Qual o tempo máximo para realização da prova?"

docs = retriever.invoke(query)

chain.invoke(
    {"input_documents": docs, "query": query}
)  # Should output something like: "O tempo máximo para realização da prova é de 5 horas."