更新到2024年9月25日,采用Llama 3.2
通过函数调用让大型语言模型 (LLM) 连接到世界,就像是赋予你的AI联通世界的本领。通过将你的LLM与外部工具(如自定义函数或API)集成,你可以构建解决实际问题的应用。
在这篇文章中,我们将展示如何将Llama 3.2与诸如Milvus(https://zilliz.com/what-is-milvus)和APIs等集成,以构建强大且具备上下文感知能力的应用。
函数调用入门像GPT-4、Mistral Nemo和Llama 3.2这样的大型语言模型现在可以判断何时需要调用函数,并输出带有参数的JSON,以便调用该函数。这使得您的AI应用更加灵活和强大。
通过功能调用,开发人员可以创建:
- 基于大规模语言模型的数据提取和标记解决方案(例如,从维基百科文章中提取人名等数据)
- 将自然语言转换成API调用或者有效数据库查询的应用程序
- 可以与知识库进行对话的知识检索引擎
这些工具
- Ollama:将大语言模型的强大功能带到您的笔记本电脑上,简化本地运行。
- Milvus:我们常用的高效数据存储和检索向量数据库。
- Llama 3.2–3B:3.1模型的升级版本,支持多语言,并且上下文长度大幅提升至128K,支持工具使用。
Llama 3.2 在函数调用上进行了微调。它支持单个、嵌套和并行的函数调用,以及多轮函数调用。这意味着你的 AI 可以处理包含多个步骤或并行流程的复杂任务。
在我们这个例子中,我们将实现不同的函数来模拟 API 调用来获取航班时间,以及在 Milvus 中执行搜索。Llama 3.2 将根据用户的查询来决定调用哪个函数。
安装依赖首先,我们用Ollama下载Llama 3.2。
ollama run llama3.2
这会将模型下载到你的电脑上,使其可以与Ollama一起使用。然后,安装所需的依赖项。
! pip install ollama openai "pymilvus[model]"
我们在安装带有模型扩展功能的Milvus Lite,这样您就可以将数据嵌入到Milvus中可用的嵌入模型中。
将数据插入Milvus现在,我们来将一些数据插入到Milvus中。这是Llama 3.2以后可能会决定搜索的数据,如果它觉得这些数据有用。
创建和插入数据(例如,插入一些示例数据) 从pymilvus导入MilvusClient, model模块
embedding_fn = model.DefaultEmbeddingFunction()
docs = [
"人工智能作为一门学科是在1956年成立的。",
"阿兰·图灵是第一位进行大量人工智能研究的人。",
"图灵出生在伦敦的迈德威尔区,并在英格兰南部长大。",
]
vectors = embedding_fn.encode_documents(docs)
# 输出的向量有768个维度,与我们刚刚创建的集合相匹配。
print("维度:", embedding_fn.dim, vectors[0].shape) # 维度: 768 (768,)
# 每个实体都有id、向量表示、原始文本和主题标签。
data = [
{"id": i, "vector": vectors[i], "text": docs[i], "subject": "历史"}
for i in range(len(vectors))
]
print("数据包含", len(data), "个实体,每个实体包含以下字段:", data[0].keys())
print("向量维度:", len(data[0]["vector"]))
# 创建集合并插入数据
client = MilvusClient('./milvus_local.db')
client.create_collection(
collection_name="demo_collection",
dimension=768, # 此示例中使用的向量有768个维度
)
client.insert(collection_name="demo_collection", data=data)
你的新集合里应该有3个元素。
定义一下我们需要用到的函数在这个例子中,如下所示,我们定义了两个函数。第一个函数模拟了一个获取航班时间的API请求。第二个函数在Milvus中执行了一次搜索查询。
from pymilvus import model
import json
import ollama
embedding_fn = model.DefaultEmbeddingFunction()
# 模拟获取航班时间的API请求
# 在实际应用中,这将从实时数据库或API获取数据
def get_flight_times(departure: str, arrival: str) -> str:
flights = {
'NYC-LAX': {'departure': '08:00 AM', 'arrival': '11:30 AM', 'duration': '5h 30m'},
'LAX-NYC': {'departure': '02:00 PM', 'arrival': '10:30 PM', 'duration': '5h 30m'},
'LHR-JFK': {'departure': '10:00 AM', 'arrival': '01:00 PM', 'duration': '8h 00m'},
'JFK-LHR': {'departure': '09:00 PM', 'arrival': '09:00 AM', 'duration': '7h 00m'},
'CDG-DXB': {'departure': '11:00 AM', 'arrival': '08:00 PM', 'duration': '6h 00m'},
'DXB-CDG': {'departure': '03:00 AM', 'arrival': '07:30 AM', 'duration': '7h 30m'},
}
key = f'{departure}-{arrival}'.upper()
return json.dumps(flights.get(key, {'error': '没有找到该航班'}))
# 在向量数据库中搜索与人工智能相关的内容
def search_data_in_vector_db(query: str) -> str:
query_vectors = embedding_fn.encode_queries([query])
res = client.search(
collection_name="demo_collection",
data=query_vectors,
limit=2,
output_fields=["text", "subject"], # 指定需要返回的字段
)
# 打印搜索结果
print(res)
return json.dumps(res)
给LLM提供使用这些功能的方法的指示
现在,让我们给LLM提供使用我们定义的功能的指示。
def run(model: str, question: str):
client = ollama.Client()
# 初始化对话,包含用户查询
messages = [{"role": "user", "content": question}]
# 第一次API请求:发送查询以及函数描述给模型
response = client.chat(
model=model,
messages=messages,
tools=[
{
"type": "function",
"function": {
"name": "get_flight_times",
"description": "获取两个地点之间的航班时间",
"parameters": {
"type": "object",
"properties": {
"departure": {
"type": "string",
"description": "出发地点(机场代码)",
},
"arrival": {
"type": "string",
"description": "到达地点(机场代码)",
},
},
"required": ["departure", "arrival"],
},
},
},
{
"type": "function",
"function": {
"name": "search_data_in_vector_db",
"description": "搜索人工智能相关数据",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词",
},
},
"required": ["query"],
},
},
},
],
)
# 将模型的响应添加到对话历史中
messages.append(response["message"])
# 检查模型是否调用任何函数
if not response["message"].get("tool_calls"):
print("模型未调用任何函数,其响应内容如下:")
print(response["message"]["content"])
return
# 处理模型调用的工具
if response["message"].get("tool_calls"):
available_functions = {
"get_flight_times": get_flight_times,
"search_data_in_vector_db": search_data_in_vector_db,
}
for tool in response["message"]["tool_calls"]:
function_to_call = available_functions[ tool["function"]["name"] ]
function_args = tool["function"]["arguments"]
function_response = function_to_call(**function_args)
# 将函数响应添加至对话
messages.append(
{
"role": "tool",
"content": function_response,
}
)
# 发起第二次API请求:获得模型的最终响应
final_response = client.chat(model=model, messages=messages)
print(final_response["message"]["content"])
使用示例
我们来看看能不能查到某个航班的具体时间:
question = "从纽约(NYC)到洛杉矶(LAX)的飞行时间是多久?"
run('llama3.2', question)
这就产生了这样的结果:
从纽约(JFK/LGA/EWR)飞洛杉矶(LAX)大约需要5小时30分钟。但是请注意,具体时间可能因航空公司、航班时刻表,以及是否会有经停或延误等因素而有所变化。最好还是直接向您的航空公司确认最准确和最新的航班信息。
现在我们来看看Llama 3.2能否使用Milvus进行向量检索。
question = "人工智能是从什么时候开始发展的呢?"
run("llama3.2", question)
这返回Milvus搜索的结果:
data: ["[{'id': 0, 'distance': 0.5738513469696045, 'entity': {'text': '人工智能作为一门学科是在1956年创立的。', 'subject': '历史学'}}, {'id': 1, 'distance': 0.4090226888656616, 'entity': {'text': '阿兰·图灵是第一位在人工智能领域进行大量研究的人。', 'subject': '历史学'}}]"]
人工智能作为一门学科是在1956年创立的。
总结
通过调用大语言模型(LLMs)的函数,打开了一个充满可能性的世界。通过将Llama 3.2与外部工具如Milvus和APIs集成,你可以构建理解上下文的应用程序,以解决特定场景中的实际问题。
共同学习,写下你的评论
评论加载中...
作者其他优质文章