使用大型语言模型(LLM)进行函数调用就像是给你的AI赋予了与世界连接的能力。通过将你的LLM与外部工具(如用户自定义的函数或API)集成,你可以构建解决实际问题的应用。
在这篇博客文章中,我们将讲解如何将Llama 3.1与外部工具如Milvus和API集成,以构建功能强大且具备上下文感知能力的应用。
函数调用入门比如GPT-4、Mistral Nemo和Llama 3.1这类大型语言模型现在能够判断何时需要调用一个函数,并输出调用该函数所需参数的JSON。这让您的AI应用变得更灵活和强大。
功能呼叫让开发者能够:
- 利用LLM技术的数据提取和标注解决方案(例如,从维基百科文章中提取人名等信息)
- 能够将自然语言转换为API调用或有效数据库查询的应用程序
- 与知识库互动的对话式知识检索系统
这些工具
- Ollama:将大规模语言模型的强大功能带到您的笔记本上,简化本地操作。
- Milvus:我们的首选向量数据库,用于高效的数据存储和检索。
- Llama 3.1–8B:这个8B模型的升级版本是多语言的,并且上下文长度增加到了128K,能够使用工具。
当使用 Llama 3.1 和 Ollama 时,请注意它们是专有名词,应保留其原有首字母大写。
Llama 3.1 在功能调用上进行了优化。它支持单一、嵌套及并行调用,以及多轮调用。这意味着您的AI可以应对涉及多个步骤或并行处理的复杂任务。
在我们的示例中,我们将实现一些不同的函数来模拟API调用来获取航班时间和在Milvus中进行搜索。Llama 3.1将根据用户的查询决定调用哪个函数。
安装依赖项首先,让我们使用Ollama下载Llama 3.1,并做好所有准备工作。
ollama run llama3.1
这会将模型下载到您的笔记本电脑上,使其可以立即用于Ollama。下载完成后,只需安装必要的依赖项即可。
! pip install ollama openai "pymilvus[model]" # 安装ollama、openai和pymilvus[model]库
咱们正在安装带有模型扩展功能的Milvus Lite,这使得你可以利用Milvus中提供的模型来嵌入数据。
在Milvus中插入数据现在,让我们向Milvus里添加一些数据。如果Llama 3.1觉得这些数据相关的话,稍后可能会用来搜索。
创建并添加数据 从 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提供使用这些功能的指示
现在,让我们给大模型下达指令,让它能使用我们定义的功能。
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.1', question) # 运行模型 'llama3.1' 并提问
这就造成了:
从纽约(JFK/LGA/EWR)飞往洛杉矶(LAX)的飞行时间大约为5小时30分钟。不过,请注意,具体时间可能会有所不同,视航空公司、航班时刻表以及是否有中转或延误而定。建议您向您的航空公司查询最准确和最新的航班信息。
现在我们来看看Llama 3.1能不能用Milvus做向量搜索。
question = “什么是人工智能?”
run('llama3.1', question) # 运行llama3.1模型来回答问题
这会返回一个 Milvus 的搜索结果:
data: ["[{'id': 0, 'distance': 0.4702666699886322, 'entity': {'text': '人工智能作为一门学科在1956年成立。', 'subject': '历史学'}}, {'id': 1, 'distance': 0.2702862620353699, 'entity': {'text': '阿兰·图灵是第一位在人工智能领域进行重要研究的人。', 'subject': '历史学'}}]"] , extra_info: {'费用': 0}
结论部分
使用大语言模型进行函数调用开启了无限的可能性。通过将Llama 3.1和外部工具如Milvus和APIs集成,你可以构建出智能上下文理解的应用程序,以解决特定用例和实际问题的需求。
共同学习,写下你的评论
评论加载中...
作者其他优质文章