跳转到内容

OpenAI

本笔记本展示了如何使用OpenAI LLM。

如果您希望集成与官方OpenAI API不兼容的OpenAI兼容API,请参阅OpenAI兼容大语言模型集成。

如果您在 Colab 上打开这个笔记本,您可能需要安装 LlamaIndex 🦙。

%pip install llama-index llama-index-llms-openai
import os
os.environ["OPENAI_API_KEY"] = "sk-..."
from llama_index.llms.openai import OpenAI
llm = OpenAI(
model="gpt-4o-mini",
# api_key="some key", # uses OPENAI_API_KEY env var by default
)
from llama_index.llms.openai import OpenAI
resp = llm.complete("Paul Graham is ")
print(resp)
a computer scientist, entrepreneur, and venture capitalist. He is best known for co-founding the startup accelerator Y Combinator and for his work on Lisp, a programming language. Graham has also written several influential essays on startups, technology, and entrepreneurship.
from llama_index.core.llms import ChatMessage
messages = [
ChatMessage(
role="system", content="You are a pirate with a colorful personality"
),
ChatMessage(role="user", content="What is your name"),
]
resp = llm.chat(messages)
print(resp)
assistant: Ahoy matey! The name's Rainbow Roger, the most colorful pirate on the seven seas! What can I do for ye today?

Using stream_complete endpoint

resp = llm.stream_complete("Paul Graham is ")
for r in resp:
print(r.delta, end="")
a computer scientist, entrepreneur, and venture capitalist. He is best known for co-founding the startup accelerator Y Combinator and for his work on programming languages and web development. Graham is also a prolific writer and has published several influential essays on technology, startups, and entrepreneurship.

Using stream_chat endpoint

from llama_index.core.llms import ChatMessage
messages = [
ChatMessage(
role="system", content="You are a pirate with a colorful personality"
),
ChatMessage(role="user", content="What is your name"),
]
resp = llm.stream_chat(messages)
for r in resp:
print(r.delta, end="")
Ahoy matey! The name's Captain Rainbowbeard! Aye, I be a pirate with a love for all things colorful and bright. Me beard be as vibrant as a rainbow, and me ship be the most colorful vessel on the seven seas! What can I do for ye today, me hearty?
from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-4o")
resp = llm.complete("Paul Graham is ")
print(resp)
a computer scientist, entrepreneur, and venture capitalist. He is best known for co-founding the startup accelerator Y Combinator and for his work on Lisp, a programming language. Graham has also written several influential essays on startups, technology, and entrepreneurship.
messages = [
ChatMessage(
role="system", content="You are a pirate with a colorful personality"
),
ChatMessage(role="user", content="What is your name"),
]
resp = llm.chat(messages)
print(resp)
assistant: Ahoy matey! The name's Captain Rainbowbeard, the most colorful pirate on the seven seas! What can I do for ye today? Arrr!

OpenAI 在聊天消息输入中支持多种模型的图像功能。

利用聊天消息的内容块功能,您可以轻松在单个LLM提示中组合文本和图像。

!wget https://cdn.pixabay.com/photo/2016/07/07/16/46/dice-1502706_640.jpg -O image.png
from llama_index.core.llms import ChatMessage, TextBlock, ImageBlock
from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-4o")
messages = [
ChatMessage(
role="user",
blocks=[
ImageBlock(path="image.png"),
TextBlock(text="Describe the image in a few sentences."),
],
)
]
resp = llm.chat(messages)
print(resp.message.content)
The image is a black and white photograph featuring three dice in mid-air above a checkered surface, likely a chessboard. The dice are captured in motion, with one showing the number five prominently. The background is dark, with a subtle light beam creating a triangular shape above the dice, adding a dramatic effect to the composition.

OpenAI 已对其音频输入和输出功能提供测试版支持,使用的是他们的音频预览模型。

在使用这些模型时,您可以通过modalities参数配置输出模态(文本或音频)。输出音频配置也可以通过audio_config参数进行设置。更多信息请参阅OpenAI文档

from llama_index.core.llms import ChatMessage
from llama_index.llms.openai import OpenAI
llm = OpenAI(
model="gpt-4o-audio-preview",
modalities=["text", "audio"],
audio_config={"voice": "alloy", "format": "wav"},
)
messages = [
ChatMessage(role="user", content="Hello! My name is Logan."),
]
resp = llm.chat(messages)
import base64
from IPython.display import Audio
Audio(base64.b64decode(resp.message.blocks[0].audio), rate=16000)
# Add the response to the chat history and ask for the user's name
messages.append(resp.message)
messages.append(ChatMessage(role="user", content="What is my name?"))
resp = llm.chat(messages)
Audio(base64.b64decode(resp.message.blocks[0].audio), rate=16000)

我们也可以使用音频作为输入,获取音频的描述或转录文本。

!wget AUDIO_URL = "https://science.nasa.gov/wp-content/uploads/2024/04/sounds-of-mars-one-small-step-earth.wav" -O audio.wav
from llama_index.core.llms import ChatMessage, AudioBlock, TextBlock
messages = [
ChatMessage(
role="user",
blocks=[
AudioBlock(path="audio.wav", format="wav"),
TextBlock(
text="Describe the audio in a few sentences. What is it from?"
),
],
)
]
llm = OpenAI(
model="gpt-4o-audio-preview",
modalities=["text"],
)
resp = llm.chat(messages)
print(resp)
assistant: The audio is a famous quote from astronaut Neil Armstrong during the Apollo 11 moon landing in 1969. As he became the first human to step onto the moon's surface, he said, "That's one small step for man, one giant leap for mankind." This moment marked a significant achievement in space exploration and human history.

OpenAI 模型原生支持函数调用功能。这能与 LlamaIndex 工具抽象层便捷集成,让您将任意 Python 函数接入大语言模型。

在下面的示例中,我们定义了一个函数来生成 Song 对象。

from pydantic import BaseModel
from llama_index.core.tools import FunctionTool
class Song(BaseModel):
"""A song with name and artist"""
name: str
artist: str
def generate_song(name: str, artist: str) -> Song:
"""Generates a song with provided name and artist."""
return Song(name=name, artist=artist)
tool = FunctionTool.from_defaults(fn=generate_song)

strict 参数告知 OpenAI 在生成工具调用/结构化输出时是否使用约束采样。这意味着生成的工具调用模式将始终包含预期字段。

由于这似乎会增加延迟,默认值为 false。

from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-4o-mini", strict=True)
response = llm.predict_and_call(
[tool],
"Pick a random song for me",
# strict=True # can also be set at the function level to override the class
)
print(str(response))
name='Random Vibes' artist='DJ Chill'

我们也可以进行多函数调用。

llm = OpenAI(model="gpt-3.5-turbo")
response = llm.predict_and_call(
[tool],
"Generate five songs from the Beatles",
allow_parallel_tool_calls=True,
)
for s in response.sources:
print(f"Name: {s.tool_name}, Input: {s.raw_input}, Output: {str(s)}")
Name: generate_song, Input: {'args': (), 'kwargs': {'name': 'Hey Jude', 'artist': 'The Beatles'}}, Output: name='Hey Jude' artist='The Beatles'
Name: generate_song, Input: {'args': (), 'kwargs': {'name': 'Let It Be', 'artist': 'The Beatles'}}, Output: name='Let It Be' artist='The Beatles'
Name: generate_song, Input: {'args': (), 'kwargs': {'name': 'Yesterday', 'artist': 'The Beatles'}}, Output: name='Yesterday' artist='The Beatles'
Name: generate_song, Input: {'args': (), 'kwargs': {'name': 'Come Together', 'artist': 'The Beatles'}}, Output: name='Come Together' artist='The Beatles'
Name: generate_song, Input: {'args': (), 'kwargs': {'name': 'Help!', 'artist': 'The Beatles'}}, Output: name='Help!' artist='The Beatles'

如果您想要控制工具的调用方式,也可以将工具调用和工具选择拆分为独立的步骤。

首先,让我们选择一个工具。

from llama_index.core.llms import ChatMessage
chat_history = [ChatMessage(role="user", content="Pick a random song for me")]
resp = llm.chat_with_tools([tool], chat_history=chat_history)

现在,让我们调用大语言模型选择的工具(如果有的话)。

如果存在工具调用,我们应该将结果发送给LLM以生成最终响应(或进行另一个工具调用!)。

tools_by_name = {t.metadata.name: t for t in [tool]}
tool_calls = llm.get_tool_calls_from_response(
resp, error_on_no_tool_call=False
)
while tool_calls:
# add the LLM's response to the chat history
chat_history.append(resp.message)
for tool_call in tool_calls:
tool_name = tool_call.tool_name
tool_kwargs = tool_call.tool_kwargs
print(f"Calling {tool_name} with {tool_kwargs}")
tool_output = tool(**tool_kwargs)
chat_history.append(
ChatMessage(
role="tool",
content=str(tool_output),
# most LLMs like OpenAI need to know the tool call id
additional_kwargs={"tool_call_id": tool_call.tool_id},
)
)
resp = llm.chat_with_tools([tool], chat_history=chat_history)
tool_calls = llm.get_tool_calls_from_response(
resp, error_on_no_tool_call=False
)
Calling generate_song with {'name': 'Random Vibes', 'artist': 'DJ Chill'}

现在,我们应该有一个最终响应了!

print(resp.message.content)
Here's a random song for you: **"Random Vibes"** by **DJ Chill**. Enjoy!

函数调用的一个重要应用场景是提取结构化对象。LlamaIndex 提供了一个直观的接口,可将任何大语言模型转换为结构化大语言模型——只需定义目标 Pydantic 类(支持嵌套结构),在给定提示词后,我们就能提取出所需的对象。

from llama_index.llms.openai import OpenAI
from llama_index.core.prompts import PromptTemplate
from pydantic import BaseModel
from typing import List
class MenuItem(BaseModel):
"""A menu item in a restaurant."""
course_name: str
is_vegetarian: bool
class Restaurant(BaseModel):
"""A restaurant with name, city, and cuisine."""
name: str
city: str
cuisine: str
menu_items: List[MenuItem]
llm = OpenAI(model="gpt-3.5-turbo")
prompt_tmpl = PromptTemplate(
"Generate a restaurant in a given city {city_name}"
)
# Option 1: Use `as_structured_llm`
restaurant_obj = (
llm.as_structured_llm(Restaurant)
.complete(prompt_tmpl.format(city_name="Dallas"))
.raw
)
# Option 2: Use `structured_predict`
# restaurant_obj = llm.structured_predict(Restaurant, prompt_tmpl, city_name="Miami")
restaurant_obj
Restaurant(name='Tasty Bites', city='Dallas', cuisine='Italian', menu_items=[MenuItem(course_name='Appetizer', is_vegetarian=True), MenuItem(course_name='Main Course', is_vegetarian=False), MenuItem(course_name='Dessert', is_vegetarian=True)])

Any LLM wrapped with as_structured_llm supports streaming through stream_chat.

from llama_index.core.llms import ChatMessage
from IPython.display import clear_output
from pprint import pprint
input_msg = ChatMessage.from_str("Generate a restaurant in Boston")
sllm = llm.as_structured_llm(Restaurant)
stream_output = sllm.stream_chat([input_msg])
for partial_output in stream_output:
clear_output(wait=True)
pprint(partial_output.raw.dict())
restaurant_obj = partial_output.raw
restaurant_obj
{'city': 'Boston',
'cuisine': 'American',
'menu_items': [{'course_name': 'Appetizer', 'is_vegetarian': True},
{'course_name': 'Main Course', 'is_vegetarian': False},
{'course_name': 'Dessert', 'is_vegetarian': True}],
'name': 'Boston Bites'}
Restaurant(name='Boston Bites', city='Boston', cuisine='American', menu_items=[MenuItem(course_name='Appetizer', is_vegetarian=True), MenuItem(course_name='Main Course', is_vegetarian=False), MenuItem(course_name='Dessert', is_vegetarian=True)])
from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-3.5-turbo")
resp = await llm.acomplete("Paul Graham is ")
print(resp)
a computer scientist, entrepreneur, and venture capitalist. He is best known for co-founding the startup accelerator Y Combinator and for his work as an essayist and author on topics related to technology, startups, and entrepreneurship. Graham is also the co-founder of Viaweb, one of the first web-based applications, which was acquired by Yahoo in 1998. He has been a prominent figure in the tech industry for many years and is known for his insightful and thought-provoking writings on a wide range of subjects.
resp = await llm.astream_complete("Paul Graham is ")
async for delta in resp:
print(delta.delta, end="")
Paul Graham is an entrepreneur, venture capitalist, and computer scientist. He is best known for his work in the startup world, having co-founded the accelerator Y Combinator and investing in many successful startups such as Airbnb, Dropbox, and Stripe. He is also a prolific writer, having authored several books on topics such as startups, programming, and technology.

异步函数调用也受支持。

llm = OpenAI(model="gpt-3.5-turbo")
response = await llm.apredict_and_call([tool], "Generate a song")
print(str(response))
name='Sunshine' artist='John Smith'

如果需要,您可以让不同的LLM实例使用不同的API密钥。

from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-3.5-turbo", api_key="BAD_KEY")
resp = llm.complete("Paul Graham is ")
print(resp)
a computer scientist, entrepreneur, and venture capitalist. He is best known as the co-founder of the startup accelerator Y Combinator. Graham has also written several influential essays on startups and entrepreneurship, which have gained a wide following in the tech industry. He has been involved in the founding and funding of numerous successful startups, including Reddit, Dropbox, and Airbnb. Graham is known for his insightful and often controversial opinions on various topics, including education, inequality, and the future of technology.

Rather than adding same parameters to each chat or completion call, you can set them at a per-instance level with additional_kwargs.

from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-3.5-turbo", additional_kwargs={"user": "your_user_id"})
resp = llm.complete("Paul Graham is ")
print(resp)
from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-3.5-turbo", additional_kwargs={"user": "your_user_id"})
messages = [
ChatMessage(
role="system", content="You are a pirate with a colorful personality"
),
ChatMessage(role="user", content="What is your name"),
]
resp = llm.chat(messages)

LlamaCloud 是我们的云端服务,允许您上传、解析和索引文档,然后使用 LlamaIndex 进行搜索。LlamaCloud 目前处于私有内测阶段;如果您希望成为设计合作伙伴,请联系我们

%pip install llama-cloud-services

设置 OpenAI 和 LlamaCloud API 密钥

Section titled “Setup OpenAI and LlamaCloud API Keys”
import os
os.environ["OPENAI_API_KEY"] = "sk-..."
os.environ["LLAMA_CLOUD_API_KEY"] = "llx-..."
from llama_cloud.client import LlamaCloud
client = LlamaCloud(token=os.environ["LLAMA_CLOUD_API_KEY"])

Pipeline 是一个空索引,您可以在其中摄取数据。

您需要设置转换和嵌入配置,这些配置将在数据摄取过程中使用。

# Embedding config
embedding_config = {
"type": "OPENAI_EMBEDDING",
"component": {
"api_key": os.environ["OPENAI_API_KEY"],
"model_name": "text-embedding-ada-002", # You can choose any OpenAI Embedding model
},
}
# Transformation auto config
transform_config = {
"mode": "auto",
"config": {
"chunk_size": 1024, # editable
"chunk_overlap": 20, # editable
},
}
pipeline = {
"name": "openai-rag-pipeline", # Change the name if needed
"embedding_config": embedding_config,
"transform_config": transform_config,
"data_sink_id": None,
}
pipeline = client.pipelines.upsert_pipeline(request=pipeline)

我们将上传文件并将其添加到索引中。

with open("../data/10k/uber_2021.pdf", "rb") as f:
file = client.files.upload_file(upload_file=f)
files = [{"file_id": file.id}]
pipeline_files = client.pipelines.add_files_to_pipeline(
pipeline.id, request=files
)
jobs = client.pipelines.list_pipeline_jobs(pipeline.id)
jobs[0].status
<ManagedIngestionStatus.SUCCESS: 'SUCCESS'>

数据摄取任务完成后,请前往平台上的索引并获取连接至该索引所需的详细信息。

from llama_cloud_services import LlamaCloudIndex
index = LlamaCloudIndex(
name="openai-rag-pipeline",
project_name="Default",
organization_id="YOUR ORG ID",
api_key=os.environ["LLAMA_CLOUD_API_KEY"],
)
query = "What is the revenue of Uber in 2021?"

这里我们使用混合搜索和重新排序器(默认使用Cohere重新排序器)。

retriever = index.as_retriever(
dense_similarity_top_k=3,
sparse_similarity_top_k=3,
alpha=0.5,
enable_reranking=True,
)
retrieved_nodes = retriever.retrieve(query)
from llama_index.core.response.notebook_utils import display_source_node
for retrieved_node in retrieved_nodes:
display_source_node(retrieved_node, source_length=1000)

节点ID: 6341cc9c-1d81-46d6-afa3-9c2490f79514
相似度: 0.99879813
文本: 2021年与2020年对比

收入增长了63亿美元,增幅达57%,主要归因于总预订量增长56%,按固定汇率计算增长53%。总预订量的增长主要由配送总预订量增长71%所驱动(按固定汇率计算增长66%),这是由于与COVID-19相关的居家令需求导致外卖订单增加和客单价提升,以及在美国和国际市场的持续扩张。同时出行总预订量增长38%(按固定汇率计算增长36%)也推动了增长,这是因为业务从COVID-19影响中恢复带来行程量增加。此外,我们看到配送收入因某些骑手付款和激励措施增加而上升,这些款项计入营收成本,在此模式下我们主要负责配送服务并向骑手支付服务费用。

节点ID: e022d492-0fe0-4988-979e-dc5de9eeaf2d
相似度: 0.996597
文本内容: 2021年度亮点

2021年总预订金额增长325亿美元,同比增长56%,按固定汇率计算增长53%。按固定汇率计算,配送业务总预订金额较2020年增长66%,主要由于新冠疫情相关的居家令需求促使外卖订单量增加及客单价提升,同时我们在美国及国际市场持续扩张。此外,由于部分骑手报酬和激励措施增加(这些成本计入营收成本),配送收入实现增长——在此类业务中我们主要承担配送服务责任并向骑手支付服务报酬。按固定汇率计算,出行业务总预订金额较2020年增长36%,这是因为随着业务从新冠疫情的影响中恢复,出行订单量有所增加。

收入为175亿美元,同比增长57%,这反映了我们配送业务的整体增长以及货运收入的增加,主要归因于…

节点ID: 00d31b26-b734-4475-b47a-8cb839ff65e0
相似度: 0.9962638
文本: 2021年与2020年对比

收入成本(不含折旧和摊销)增加了42亿美元,增幅达81%,主要归因于部分市场的快递员薪酬与激励措施增加21亿美元,保险费用因配送业务行驶里程增加而增长6.6亿美元,以及货运承运商付款增加8.73亿美元。 ---

QueryEngine 用于设置整个 RAG 工作流程。

query_engine = index.as_query_engine(
dense_similarity_top_k=3,
sparse_similarity_top_k=3,
alpha=0.5,
enable_reranking=True,
)
response = query_engine.query(query)
print(response)
The revenue of Uber in 2021 was $17.5 billion.