保姆级教程:利用大模型与高德地图API,轻松实现查找附近咖啡店

随着人工智能和地图服务的迅速发展,我们可以轻松地利用这些工具实现各种便捷功能。例如,通过整合OpenAI的大模型和高德地图API,可以快速查找某个地址附近的咖啡店。本文将介绍如何通过远程调用和多功能调用大模型,结合高德地图API,实现这一功能,并分享具体的代码示例。

一、步骤解析

图片

  1. 用户查询

    • 用户向ChatBot提出查询请求,例如“长沙证券大厦附近的咖啡店”。
  2. 解析用户请求

    • ChatBot(通过OpenAI API)解析用户的请求内容,理解用户想要查询的地点和兴趣点。
  3. 调用高德地图API获取地理坐标

    • ChatBot调用高德地图API,使用get_location_coordinate函数获取用户查询地点的地理坐标(经纬度)。
  4. 高德地图API返回地理坐标

    • 高德地图API返回查询地点的地理坐标信息(例如经度和纬度)。
  5. 解析地理坐标

    • ChatBot解析从高德地图API返回的地理坐标,为后续查询做好准备。
  6. 调用高德地图API搜索附近兴趣点

    • ChatBot调用高德地图API,使用search_nearby_pois函数,根据获取的地理坐标和用户提供的关键词(如“咖啡”),搜索附近的兴趣点(POIs)。
  7. 高德地图API返回附近兴趣点

    • 高德地图API返回查询坐标附近的兴趣点信息,包括咖啡店的名称、地址和距离等。
  8. 整理并生成回复内容

    • ChatBot整理高德地图API返回的兴趣点信息,并生成用户所需的回复内容。
  9. 返回结果给用户

    • ChatBot将生成的回复内容返回给用户,展示附近的咖啡店信息。
  10. 用户继续对话或结束

    • 用户可以根据返回的信息继续进行对话,提出更多查询或结束对话。

二、完整代码

# 导入必要的库和模块
import openai
import os
from math import *
from icecream import ic
import json
import requests
import logging
# 设置日志记录配置
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 加载环境变量
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())

# 初始化OpenAI API密钥和模型
openai.api_key = os.getenv('OPENAI_API_KEY')
openai.api_base = os.getenv('OPENAI_API_URL')
model = os.getenv('MODEL')
amap_key = os.getenv('GAODE_MAP_API_KEY')

# 通过高德地图API获取地点的经纬度坐标
# 用于查询某个地点的地理坐标。
def get_location_coordinate(location, city="长沙"):
    """    
    根据地点和城市名称,使用高德地图API查询并返回该地点的坐标。 
           
    参数:    
    location (str): 地点名称。    
    city (str): 城市名称,默认为“长沙”。       
     
    返回:    
    dict: 包含地点坐标信息的字典,如果没有找到则返回None。    
    """    
    url = f"https://restapi.amap.com/v5/place/text?key={amap_key}&keywords={location}&region={city}"    
    ic(url)    
    r = requests.get(url)    
    result = r.json()    
    if "pois" in result and result["pois"]:        
        return result["pois"][0]
    return None

# 通过高德地图API查询给定坐标附近的兴趣点(POIs)
#用于查询地理坐标附近的某些信息(取决于用户输入的Keyword)
#这是用的高德地图的开放接口,在使用本例之前,你需要先去高德地图开放接口的官网(https://console.amap.com/dev/key/app)申请一个key,免费的。这里就不过多介绍了。
def search_nearby_pois(longitude, latitude, keyword):
    """    
    根据给定的经纬度和关键词,使用高德地图API查询并返回附近的兴趣点信息。   
         
    参数:    
    longitude (str): 经度。    
    latitude (str): 纬度。    
    keyword (str): 查询关键词。      
      
    返回:    
    str: 包含查询结果的字符串,如果没有找到则返回空字符串。    
    """    
    url = f"https://restapi.amap.com/v5/place/around?key={amap_key}&keywords={keyword}&location={longitude},{latitude}"    
    ic(url)    
    r = requests.get(url)    
    result = r.json()    
    ans = ""    
    if "pois" in result and result["pois"]:      
        for i in range(min(3, len(result["pois"]))):       
            name = result["pois"][i]["name"]            
            address = result["pois"][i]["address"]            
            distance = result["pois"][i]["distance"]            
            ans += f"{name}\n{address}\n距离:{distance}米\n\n"    
    return ans

# 使用OpenAI API完成聊天对话
def get_completion(messages, model=model):
    """    
    根据输入的消息列表,使用OpenAI API生成并返回聊天对话的回复。  
          
    参数:    
    messages (list): 消息列表,包含系统的和用户的对话内容。    
    model (str): 使用的OpenAI模型,默认为环境变量中的MODEL。   
        
    返回:    
    dict: 包含OpenAI生成的回复信息的字典。    
    """    
    response = openai.ChatCompletion.create(
        model=model,        
        messages=messages,        
        temperature=0,  # 模型输出的随机性,0 表示随机性最小        
        seed=1024,  # 随机种子保持不变,temperature 和 prompt 不变的情况下,输出就会不变        
        tool_choice="auto",  # 默认值,由系统自动决定,返回function call还是返回文字回复        
        tools=[{      
            "type": "function",            
            "function": {           
            
                "name": "get_location_coordinate",                
                "description": "根据POI名称,获得POI的经纬度坐标",                
                "parameters": {                
                    "type": "object",                    
                    "properties": {                        
                        "location": {                        
                            "type": "string",                            
                            "description": "POI名称,必须是中文",                        
                        },                        
                        "city": {                         
                            "type": "string",                            
                            "description": "POI所在的城市名,必须是中文",                        
                        }                    
                    },                    
                    "required": ["location", "city"],                
                }            
            }        
       },       
            {            
            "type": "function",            
            "function": {                
                "name": "search_nearby_pois",                
                "description": "搜索给定坐标附近的poi",                
                "parameters": {               
                    "type": "object",                    
                    "properties": {                    
                        "longitude": {                       
                            "type": "string",                            
                            "description": "中心点的经度",                        
                        },                        
                        "latitude": {                       
                            "type": "string",                            
                            "description": "中心点的纬度",                        
                        },                        
                        "keyword": {                         
                            "type": "string",                            
                            "description": "目标poi的关键字",                        
                        }                    
                    },                    
                    "required": ["longitude", "latitude", "keyword"],                
                }            
            }        
        }],    
    )    
    return response.choices[0].message

# 处理工具函数调用
def handle_tool_call(response, messages):
    """    
    处理聊天对话中的工具函数调用,根据调用的函数名称和参数执行相应的操作,并将结果添加到消息列表中。        
    
    参数:    
    response (dict): 包含工具函数调用信息的响应字典。    
    messages (list): 消息列表,用于添加工具函数的调用结果。    
    """    
    if response.tool_calls is not None:    
        for tool_call in response.tool_calls:       
            try:           
                args = json.loads(tool_call.function.arguments)            
            except json.JSONDecodeError:           
                logging.error("解析工具函数参数失败")                
                continue  # 跳过当前循环            
            logging.info(f"调用: {tool_call.function.name}")            
            try:           
                if tool_call.function.name == "get_location_coordinate":               
                    result = get_location_coordinate(**args)                
                elif tool_call.function.name == "search_nearby_pois":               
                    result = search_nearby_pois(**args)            
            except Exception as e:             
                logging.error(f"调用 {tool_call.function.name} 出错: {e}")                
                continue  # 跳过当前循环            
            logging.info("函数返回: ")            
            logging.info(result)            
            messages.append({          
                "tool_call_id": tool_call.id,                
                "role": "tool",                
                "name": tool_call.function.name,                
                "content": str(result)            
            })

# 测试聊天对话流程
def test_promopt():
    """    
    测试聊天助手的功能,模拟用户查询长沙证券大厦附近的咖啡店。    
    """    
    prompt = "长沙证券大厦附近的咖啡"    
    messages = [    
        {"role": "system", "content": "你是一个地图通,你可以找到任何地址。"},        
        {"role": "user", "content": prompt}    
    ]    
    
    try:  
        response = get_completion(messages)    
    except Exception as e:   
        logging.error(f"获取初始响应失败: {e}")        
        return    

    # 处理初始响应    
    if response.content is None:   
        response.content = "null"    
    messages.append(response)    
    
    logging.info("=====GPT回复=====")    
    logging.info(response)    
    
    while True:   
        handle_tool_call(response, messages)        
        
        # 检查是否还有更多响应        
        try:        
            response = get_completion(messages)        
        except Exception as e:       
            logging.error(f"获取后续响应失败: {e}")            
            break        
        if response.content is None:     
            response.content = "null"            
            messages.append(response)        
        if not hasattr(response,'tool_calls'):  # 如果没有tool_calls属性,则表示没有更多响应            
            break    
    logging.info("=====最终回复=====")    
    logging.info(response.content)

# 主程序入口
if __name__ == '__main__':
    test_promopt()

**输出 **

2024-06-05 22:54:59,119 - INFO - =====GPT回复=====
2024-06-05 22:54:59,120 - INFO - {
  "role": "assistant",  
  "content": "null",  
  "tool_calls": [  
    {     
      "id": "call_aCIvrc4Vdey4RXYiCS5srQpC",      
      "type": "function",      
      "function": {      
        "name": "get_location_coordinate",        
        "arguments": "{\"location\":\"\u957f\u6c99\u8bc1\u5238\u5927\u53a6\",\"city\":\"\u957f\u6c99\"}"      
      }    
    }  
  ]
}
2024-06-05 22:54:59,122 - INFO - 调用: get_location_coordinate
ic| url: 'https://restapi.amap.com/v5/place/text?key=22b2d81ac8d7ed9512e6bf177cf4fc4a&keywords=长沙证券大厦&region=长沙'
2024-06-05 22:55:00,646 - INFO - 函数返回: 
2024-06-05 22:55:00,646 - INFO - {'parent': '', 'address': '车站北路459号(烈士公园东地铁站2号口步行210米)', 'distance': '', 'pcode': '430000', 'adcode': '430102', 'pname': '湖南省', 'cityname': '长沙市', 'type': '商务住宅;楼宇;商务写字楼', 'typecode': '120201', 'adname': '芙蓉区', 'citycode': '0731', 'name': '证券大厦(车站北路)', 'location': '113.007771,28.210813', 'id': 'B02DB044DJ'}
2024-06-05 22:55:02,727 - INFO - 调用: search_nearby_pois
ic| url: 'https://restapi.amap.com/v5/place/around?key=22b2d81ac8d7ed9512e6bf177cf4fc4a&keywords=咖啡&location=113.007771,28.210813'
2024-06-05 22:55:03,857 - INFO - 函数返回: 
2024-06-05 22:55:03,857 - INFO - luckin coffee 瑞幸咖啡(步步高生活广场店)
车站北路王府步步高生活商场1层1048号
距离:178米

咖啡因(车站路店)
车站北路170号瑞丰家园111门面(近冰火楼)
距离:356米

Wheat Espresso小麦咖啡(梦泽园商务楼店)
晚报大道63号梦泽园商务楼(烈士公园东地铁站4号口旁)
距离:417米


2024-06-05 22:55:11,315 - INFO - =====最终回复=====
2024-06-05 22:55:11,316 - INFO - 长沙证券大厦附近有几家咖啡店:
1. luckin coffee 瑞幸咖啡(步步高生活广场店)
地址:车站北路王府步步高生活商场1层1048号,距离证券大厦约178米。
2. 咖啡因(车站路店)
地址:车站北路170号瑞丰家园111门面(近冰火楼),距离证券大厦约356米。
3. Wheat Espresso小麦咖啡(梦泽园商务楼店)
地址:晚报大道63号梦泽园商务楼(烈士公园东地铁站4号口旁),距离证券大厦约417米。

结语

通过本文介绍的方法和代码示例,我们可以轻松地结合OpenAI的大模型和高德地图API,实现查找某个地址附近咖啡店的功能。这不仅可以提升我们的开发效率,也为我们提供了强大的工具来应对各种实际需求。希望本文能对你有所帮助!

如何学习AI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值