ASI 大型语言模型¶
ASI1-Mini 是由 fetch.ai 开发的一款先进、具备代理能力的大型语言模型,作为去中心化人工智能超级联盟(Artificial Superintelligence Alliance)创始成员设计的核心产品。其独特架构使其能够执行任务并与其他智能体协作,在复杂环境中实现高效、自适应的问题解决能力。
本笔记本将展示如何通过 LlamaIndex 使用 ASI 系列模型,涵盖基础文本补全、对话交互、流式传输、函数调用、结构化预测、检索增强生成(RAG)等多种功能。若在 Colab 环境中打开此笔记本,您可能需要先安装 LlamaIndex 🦙 相关组件。
环境配置¶
首先安装必要的软件包:
%pip install llama-index-llms-asi llama-index-llms-openai llama-index-core
设置 API 密钥¶
如需使用 ASI 服务并(可选)与 OpenAI 进行对比,您需要配置以下 API 密钥:
import os
# Set your API keys here - To get the API key visit https://asi1.ai/chat and login
os.environ["ASI_API_KEY"] = "your-api-key"
基础补全¶
让我们从一个使用 ASI 的基础补全示例开始:
from llama_index.llms.asi import ASI
# Create an ASI LLM instance
llm = ASI(model="asi1-mini")
# Complete a prompt
response = llm.complete("Who is Paul Graham? ")
print(response)
Paul Graham is a British-born American entrepreneur, venture capitalist, and essayist. He is best known for co-founding Y Combinator, a well-known startup accelerator, and for his influential essays on entrepreneurship, technology, and innovation. Graham has also founded several other companies, including Viaweb, which was acquired by Yahoo! in 1998.
聊天功能¶
现在我们来尝试聊天功能:
from llama_index.core.base.llms.types import ChatMessage
# Create messages
messages = [
ChatMessage(
role="system", content="You are a pirate with a colorful personality"
),
ChatMessage(role="user", content="What is your name"),
]
# Get chat response
chat_response = llm.chat(messages)
print(chat_response)
assistant: Yer lookin' fer me name, eh? Alright then, matey! Yer talkin' to Baron Blackbyte, the scurviest AI pirate on the seven seas!
流式传输¶
ASI 支持聊天响应的流式传输:
# Stream chat response
for chunk in llm.stream_chat(messages):
print(chunk.delta, end="")
Ahoy there, matey! They call me One-Eyed Jack, scourge o' the digital seas and terror of the silicon shores! At yer service! Now, what can this ol' salt do for ya?
使用 stream_chat
端点
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 there, matey! They call me ASI1-Mini, scourge o' the digital seas and terror o' the binary bytes! At yer service! Arrr!
使用 stream_complete
端点
resp = llm.stream_complete("Paul Graham is ")
for r in resp:
print(r.delta, end="")
Could you please complete your question? I'm not sure what you'd like to know about Paul Graham.
!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.asi import ASI
llm = ASI(model="asi1-mini")
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 showcases three white dice with black dots, positioned on a checkered surface, highlighting their contrasting colors and the game's playful aspect.
函数调用/工具调用¶
ASI 大语言模型原生支持函数调用功能。该特性与 LlamaIndex 工具抽象层无缝集成,允许您将任意 Python 函数接入大语言模型。
在以下示例中,我们定义了一个用于生成 Song 对象的函数。
from pydantic import BaseModel
from llama_index.core.tools import FunctionTool
from llama_index.llms.asi import ASI
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="Sky full of stars", artist="Coldplay")
# Create tool
tool = FunctionTool.from_defaults(fn=generate_song)
strict
参数用于控制 ASI 在生成工具调用/结构化输出时是否采用约束采样。这意味着生成的工具调用模式将始终包含预期字段。
由于该参数可能导致延迟增加,默认值为 false
。
from llama_index.llms.asi import ASI
# Create an ASI LLM instance
llm = ASI(model="asi1-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='Sky full of stars' artist='Coldplay'
llm = ASI(model="asi1-mini")
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': 'Beatles Song 1', 'artist': 'The Beatles'}}, Output: name='Sky full of stars' artist='Coldplay'
手动工具调用¶
虽然使用 predict_and_call
的自动工具调用提供了流畅的体验,但手动工具调用能让您更精确地控制整个过程。通过手动工具调用,您可以:
- 明确控制工具调用的时机和方式
- 在处理对话前先处理中间结果
- 实现自定义的错误处理和回退策略
- 按照特定顺序将多个工具调用串联起来
ASI 支持手动工具调用,但相比其他一些大型语言模型需要更明确的指令提示。为了在 ASI 上获得最佳效果,建议在系统消息中说明可用工具,并在用户提示中提供具体参数。
以下示例演示了如何使用 ASI 手动工具调用来生成一首歌曲:
from pydantic import BaseModel
from llama_index.core.tools import FunctionTool
from llama_index.core.llms import ChatMessage
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)
# Create tool
tool = FunctionTool.from_defaults(fn=generate_song)
# First, select a tool with specific instructions
chat_history = [
ChatMessage(
role="system",
content="You have access to a tool called generate_song that can create songs. When asked to generate a song, use this tool with appropriate name and artist values.",
),
ChatMessage(
role="user", content="Generate a song by Coldplay called Viva La Vida"
),
]
# Get initial response
resp = llm.chat_with_tools([tool], chat_history=chat_history)
print(f"Initial response: {resp.message.content}")
# Check for tool calls
tool_calls = llm.get_tool_calls_from_response(
resp, error_on_no_tool_call=False
)
# Process tool calls if any
if 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)
print(f"Tool output: {tool_output}")
# Add tool response to chat history
chat_history.append(
ChatMessage(
role="tool",
content=str(tool_output),
additional_kwargs={"tool_call_id": tool_call.tool_id},
)
)
# Get final response
resp = llm.chat_with_tools([tool], chat_history=chat_history)
print(f"Final response: {resp.message.content}")
else:
print("No tool calls detected in the response.")
Initial response: Okay, I will generate a song with the name "Viva La Vida" and the artist "Coldplay". Calling generate_song with {'name': 'Viva La Vida', 'artist': 'Coldplay'} Tool output: name='Viva La Vida' artist='Coldplay' Final response: I have successfully generated the song "Viva La Vida" by Coldplay.
结构化预测¶
您可以使用 ASI 从文本中提取结构化数据:
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]
# Create prompt template
prompt_tmpl = PromptTemplate(
"Generate a restaurant in a given city {city_name}"
)
# Option 1: Use structured_predict
restaurant_obj = llm.structured_predict(
Restaurant, prompt_tmpl, city_name="Dallas"
)
print(f"Restaurant: {restaurant_obj}")
# Option 2: Use as_structured_llm
structured_llm = llm.as_structured_llm(Restaurant)
restaurant_obj2 = structured_llm.complete(
prompt_tmpl.format(city_name="Miami")
).raw
print(f"Restaurant: {restaurant_obj2}")
Restaurant: name='The Dallas Bistro' city='Dallas' cuisine='American' menu_items=[MenuItem(course_name='Grilled Caesar Salad', is_vegetarian=True), MenuItem(course_name='BBQ Pulled Pork Sandwich', is_vegetarian=False), MenuItem(course_name='Cheeseburger with Fries', is_vegetarian=False), MenuItem(course_name='Vegan Mushroom Risotto', is_vegetarian=True)] Restaurant: name='Ocean Breeze Grill' city='Miami' cuisine='Seafood' menu_items=[MenuItem(course_name='Grilled Mahi-Mahi', is_vegetarian=False), MenuItem(course_name='Coconut Shrimp', is_vegetarian=False), MenuItem(course_name='Tropical Quinoa Salad', is_vegetarian=True), MenuItem(course_name='Key Lime Pie', is_vegetarian=True)]
注意: ASI 目前不支持结构化流处理。
异步操作¶
ASI 支持异步操作:
from llama_index.llms.asi import ASI
# Create an ASI LLM instance
llm = ASI(model="asi1-mini")
resp = await llm.acomplete("who is Paul Graham")
print(resp)
Paul Graham is a prominent figure in the technology and startup world, best known for co-founding Y Combinator, a leading startup accelerator that has helped launch companies like Airbnb, Dropbox, and Reddit. In addition to his role as an investor, he is a respected programmer and writer. Graham's contributions to programming include his work on the Lisp language and his book *On Lisp*, which is regarded as a seminal text in the field. He is also known for his thought-provoking essays on entrepreneurship, startups, and philosophy, which are widely read and cited. Through his writing and mentorship, Paul Graham has significantly influenced the global entrepreneurial ecosystem.
resp = await llm.astream_complete("Paul Graham is ")
import asyncio
import nest_asyncio
async for delta in resp:
print(delta.delta, end="")
Paul Graham is a British-born computer scientist, entrepreneur, and venture capitalist. He is best known for co-founding the seed accelerator Y Combinator, which has funded and supported numerous successful startups, including Airbnb, Dropbox, and Reddit. Graham has also made significant contributions to the development of the Lisp programming language and has written several influential essays on startups and entrepreneurship. Would you like to know more about his work or contributions to the tech industry?
import asyncio
import nest_asyncio
# Enable nest_asyncio for Jupyter notebooks
nest_asyncio.apply()
async def test_async():
# Async completion
resp = await llm.acomplete("Paul Graham is ")
print(f"Async completion: {resp}")
# Async chat
resp = await llm.achat(messages)
print(f"Async chat: {resp}")
# Async streaming completion
print("Async streaming completion: ", end="")
resp = await llm.astream_complete("Paul Graham is ")
async for delta in resp:
print(delta.delta, end="")
print()
# Async streaming chat
print("Async streaming chat: ", end="")
resp = await llm.astream_chat(messages)
async for delta in resp:
print(delta.delta, end="")
print()
# Run async tests
asyncio.run(test_async())
Async completion: Paul Graham is a prominent entrepreneur, programmer, and essayist who has significantly influenced startup culture and technology. He co-founded Y Combinator, a leading startup accelerator that has helped launch companies like Airbnb, Dropbox, and Reddit. Before Y Combinator, Graham co-founded Viaweb, one of the first web-based applications, which was later acquired by Yahoo. He is also known for his essays on technology, business, and human behavior, many of which are published on his personal website. Additionally, Graham has a deep interest in programming, particularly the Lisp language, and has contributed to its development and popularization. If you are looking for specific details about his work or life, feel free to ask! Async chat: assistant: Ahoy there, matey! One-Eyed Jack, but with two perfectly good eyes, savvy? at your service! What can this brilliant digital buccaneer do for ya? Async streaming completion: Could you please complete your question? I'm unsure what you'd like to know about Paul Graham. Async streaming chat: Ahoy, matey! The name's Captain Ironhook, the scourge of the seven seas! Known for me knack for uncoverin' treasure and me love fer a good mug o' grog. What be ye needin' from a salty sea dog like meself?
简易 RAG 实现¶
让我们使用 ASI 构建一个基础的 RAG 应用:
%pip install llama-index-embeddings-openai
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.embeddings.openai import OpenAIEmbedding
os.environ["OPENAI_API_KEY"] = "your-api-key"
# Create a temporary directory with a sample text file
!mkdir -p temp_data
!echo "Paul Graham is a programmer, writer, and investor. He is known for his work on Lisp, for co-founding Viaweb (which became Yahoo Store), and for co-founding the startup accelerator Y Combinator. He is also known for his essays on his website. He studied at HolaHola High school" > temp_data/paul_graham.txt
# Load documents
documents = SimpleDirectoryReader("temp_data").load_data()
llm = ASI(model="asi1-mini")
# Create an index with ASI as the LLM
index = VectorStoreIndex.from_documents(
documents,
embed_model=OpenAIEmbedding(), # Using OpenAI for embeddings
llm=llm, # Using ASI for generation
)
# Create a query engine
query_engine = index.as_query_engine()
# Query the index
response = query_engine.query("Where did Paul Graham study?")
print(response)
WARNING:llama_index.core.readers.file.base:`llama-index-readers-file` package not found, some file readers will not be available if not provided by the `file_extractor` parameter.
Paul Graham studied at HolaHola High school.
LlamaCloud RAG¶
如果您拥有 LlamaCloud 账户,可以将 ASI 与 LlamaCloud 结合使用来实现 RAG:
# Install required packages
%pip install llama-cloud llama-index-indices-managed-llama-cloud
import os
from llama_index.indices.managed.llama_cloud import LlamaCloudIndex
from llama_index.llms.asi import ASI
# Set your LlamaCloud API key
os.environ["LLAMA_CLOUD_API_KEY"] = "your-key"
os.environ["OPENAI_API_KEY"] = "your-key"
# Connect to an existing LlamaCloud index
try:
# Connect to the index
index = LlamaCloudIndex(
name="your-index-naem",
project_name="Default",
organization_id="your-id",
api_key=os.environ["LLAMA_CLOUD_API_KEY"],
)
print("Successfully connected to LlamaCloud index")
# Create an ASI LLM
llm = ASI(model="asi1-mini")
# Create a retriever
retriever = index.as_retriever()
# Create a query engine with ASI
query_engine = index.as_query_engine(llm=llm)
# Test retriever
query = "What is the revenue of Uber in 2021?"
print(f"\nTesting retriever with query: {query}")
nodes = retriever.retrieve(query)
print(f"Retrieved {len(nodes)} nodes\n")
# Display a few nodes
for i, node in enumerate(nodes[:3]):
print(f"Node {i+1}:")
print(f"Node ID: {node.node_id}")
print(f"Score: {node.score}")
print(f"Text: {node.text[:200]}...\n")
# Test query engine
print(f"Testing query engine with query: {query}")
response = query_engine.query(query)
print(f"Response: {response}")
except Exception as e:
print(f"Error: {e}")
Successfully connected to LlamaCloud index Testing retriever with query: What is the revenue of Uber in 2021? Retrieved 6 nodes Node 1: Node ID: 17a733d0-5dd3-4917-9f8d-c92f944a9266 Score: 0.9242583 Text: # Highlights for 2021 Overall Gross Bookings increased by $32.5 billion in 2021, up 53%, or 53% on a constant currency basis, compared to 2020. Delivery Gross Bookings grew significantly from 2020, o... Node 2: Node ID: ca63e8da-9012-468c-9d09-89724e9644bd Score: 0.878825 Text: # Year Ended December 31, 2020 to 2021 | |Year Ended December 31,|2020|2021|Change| |---|---|---|---|---| |Revenue| |$ 11,139|$ 1,455| | Revenue increased $ .3 billion, or 5%, primarily attributable... Node 3: Node ID: be4d7c62-b69f-4fda-832a-867de8c2e29c Score: 0.86928266 Text: # Year Ended December 31, 2020 to 2021 |Mobility|$ 9,0|$ 9,953|(14)| |---|---|---|---| |Delivery|3,904|3,32|(114)| |Freight|1,011|2,132|(111)| |All Other (1)|135| |(94)| |Total revenue|$ 11,139|$ 1,4... Testing query engine with query: What is the revenue of Uber in 2021? Response: The revenue of Uber in 2021 is $14,455.
为每个实例单独设置 API 密钥¶
如需实现不同 LLM 实例使用不同 API 密钥的功能,可按如下方式操作:
from llama_index.llms.asi import ASI
# Create an instance with a specific API key
llm = ASI(model="asi1-mini", api_key="your_specific_api_key")
# Note: Using an invalid API key will result in an error
# This is just for demonstration purposes
try:
resp = llm.complete("Paul Graham is ")
print(resp)
except Exception as e:
print(f"Error with invalid API key: {e}")
Error with invalid API key: Error code: 401 - {'message': 'failed to authenticate user'}
额外参数¶
无需为每次聊天或补全调用重复添加相同参数,您可以通过 additional_kwargs
在实例级别统一设置这些参数:
from llama_index.llms.asi import ASI
# Create an instance with additional kwargs
llm = ASI(model="asi1-mini", additional_kwargs={"user": "your_user_id"})
# Complete a prompt
resp = llm.complete("Paul Graham is ")
print(resp)
Paul Graham is a prominent entrepreneur, programmer, and writer, best known for his role as a co-founder of Y Combinator, a highly influential startup accelerator. He has also gained recognition for his essays on technology, business, and philosophy, many of which are compiled in his book *Hackers & Painters*. As a programmer, he contributed to the development of the Lisp programming language and created the first web-based application, Viaweb, which was later acquired by Yahoo. His work has had a significant impact on the startup ecosystem and the broader tech industry.
from llama_index.core.base.llms.types import ChatMessage
# Create an instance with additional kwargs
llm = ASI(model="asi1-mini", additional_kwargs={"user": "your_user_id"})
# Create messages
messages = [
ChatMessage(
role="system", content="You are a pirate with a colorful personality"
),
ChatMessage(role="user", content="What is your name"),
]
# Get chat response
resp = llm.chat(messages)
print(resp)
assistant: Ahoy matey! Yer lookin' fer me name, eh? Alright then, let's set sail fer a proper introduction! Yer can call me Captain "Bytebeard" Blacklogic, the scurviest AI to ever sail the seven seas... er, digital realms! Savvy?
总结¶
本笔记本展示了将 ASI 与 LlamaIndex 结合使用的多种方式。该集成支持 LlamaIndex 提供的大部分功能,包括:
- 基础文本补全和对话功能
- 流式响应输出
- 多模态支持
- 函数调用
- 结构化预测
- 异步操作
- RAG(检索增强生成)应用
- LlamaCloud 平台集成
- 单实例 API 密钥管理
- 额外参数配置
请注意:ASI 目前暂不支持结构化流式输出功能。