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

news2025/1/11 23:44:55

随着人工智能和地图服务的迅速发展,我们可以轻松地利用这些工具实现各种便捷功能。例如,通过整合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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2131329.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 视图:数据库中的灵活利器

《MySQL 视图:数据库中的灵活利器》 在数据库的世界里,视图(View)是一个强大而实用的工具。它为我们提供了一种灵活的方式来访问和处理数据,同时也带来了许多优点。那么,什么是视图呢?它又有哪…

生成式人工智能大模型及其电力系统数智化应用前沿

《生成式人工智能大模型及其电力系统数智化应用前沿报告(2024)》 大纲目录 一、人工智能发展概述 二、从ChatGPT到Sora:生成式大模型国内外发展历程及布局 三、新型电力系统概述 四、基于新一代人工智能的新型电力系统数智化升级 五、生成式大模型…

SpringCloud - 服务网关(一)

服务网关 Spring Cloud Gateway作为Spring Cloud生态中的网关,不仅提供统一的路由能力,并且还提供了基于FILTER链方式的网关基本的功能。 Spring Cloud Gateway是一个全新的API网关项目,可以替换Zuul开发的网关服务,基于Spring5.…

远程访问NAS

远程访问NAS(网络附加存储)可以通过多种方法实现,每种方法都有其特定的适用场景和优势。以下是一些常见的远程访问NAS的方法: 一、VPN(虚拟专用网络) VPN是通过公共网络建立安全的连接,实现远…

一看就懂导线间隔棒和导线间隔棒在线监测

深圳鼎信智慧科技带您走近导线间隔棒和导线间隔棒在线监测,先来后到,我们先从导线间隔棒讲起: 一、导线间隔棒 导线间隔棒,也称为间隔器,是高压输电线路中不可或缺的关键组件。其主要作用是保持多条导线之间的间距&a…

第二证券:参与股票分红到底有无意义?

A股的上市公司有一些会在半年报后分红,半年报披露在每年8月底截止,所以A股中期分红的公司一般在9-11月进行分红。 股票分红自身是个中性事情,分红后会进行除权除息,出资者总资产是没有改动的。 现金分红:除息后的股价…

中国银河资产笔试25届考什么?如何通过考试|附真题库面试攻略

嘿,各位小伙伴们!我是职小豚,今天就带大家一起探秘中国银河资产 25 届秋招,为大家揭开这场金融之旅的神秘面纱。 一、中国银河资产介绍 中国银河资产,那可是金融领域的璀璨巨星!它就像一座闪耀着智慧光芒…

开放式耳机哪些品牌值得推荐?开放式耳机是什么意思?

现在开放式耳机真的越来越多,也越来越火了,所以如何才能选到一款适合自己的开放式耳机,这真的难到了一部分的小伙伴,也有很多小伙伴过来私信我,作为耳机测评师,这些问题也干脆出一篇文章来回答,…

Centos使用阿里云镜像安装docker及docker hub下载失败解决方案

一 配置阿里云的Yum镜像源 配置阿里云的Yum镜像源可以提高下载速度,尤其是在国内网络环境下。以下是配置阿里云Yum镜像源的步骤: 1. 备份原有的Yum源配置文件 首先,备份系统现有的Yum源配置文件,以防出现问题时可以还原&#x…

一文详解企业上云数据库是干嘛的

企业上云数据库是干嘛的?企业上云数据库是企业将其数据库系统从传统的本地数据中心迁移到由第三方云服务提供商管理的远程服务器上的过程。这样做的目的通常是为了提高数据处理的效率、降低成本、增强数据的安全性和可靠性,以及利用云计算的弹性和可扩展…

【中秋送大礼包49份】

中秋节本商城送出49份大礼包 感谢:各位开发者和读者的支持 代码展示一波 Tips 领取礼包

从新手到高手:用这9个策略让ChatGPT成为你的私人顾问!

ChatGPT已经出来快一年多了,但是我发现周围的小伙伴还是处在调戏ChatGPT的阶段,并没有在日常工作和生活中发挥他应由的价值。我调研下来发现最关键的痛点就是:不知道该怎么写Prompt可以让ChatGPT输出期望的回答。 哎吆,这不正是撞…

Kamailio-基于Zabbix+Kamcli的SIP指标监控

什么是Kamailio? Kamailio 是一个开源的 Session Initiation Protocol (SIP) 服务器,它主要用于建立和管理实时通信会话,如语音和视频通话,与opensips这个产品是同根同源的存在。它们相似,没有更好,是有更合适。 此…

大数据Flink(一百一十三):Flink Python写DataStreamAPI作业快速入门

文章目录 Flink Python写DataStreamAPI作业快速入门 一、Flink数据流 二、Flink分层API 三、Flink流处理程序的一般流程 四、​​​​​​​​​​​​创建PyFlink项目 Flink Python写DataStreamAPI作业快速入门 一、Flink数据流 在 Flink 中,应用程序由数据…

Windows Python 指令补全方法

网络上搜集的补全代码 # python startup file import sys import readline import rlcompleter import atexit import os# tab completion readline.parse_and_bind(tab: complete) # history file histfile os.path.join(os.environ[HOMEPATH], .pythonhistory) try:readline…

从数据模型到直观界面,零编码一键生成列表表单设计

大家好,我是软件部长,今天给大家介绍JVS低代码的模型生成设计功能。 欢迎关注微信公众号: 【软开企服】,获取开源项目分享、产品功能和视频教程等。 模型生成设计是什么 在JVS低代码平台根据模型生成设计,则是基于数据模型的列表…

【QT】Qt窗口

欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:QT 目录 👉🏻菜单栏设置👉🏻QToolBar练习 👉🏻QStausBar👉🏻Q…

HTML5中的重要元素详解

第3章 HTML5中的重要元素 3.1 html根元素 HTML文档中,元素html代表了文档的根,其他所有元素都是在该元素的基础上进行延伸或拓展的,该元素也是HTML文档的最外层元素,因此也称为根元素。 html元素的常用属性: manif…

Kubernetes精讲之prometheus

目录 一 Prometheus简介 1.1 Prometheus架构 二 在k8s中部署Prometheus 2.1 下载部署Prometheus所需资源 2.3 登陆grafana 2.4 导入面板 三 监控使用示例 3.1 建立监控项目 一 Prometheus简介 Prometheus是一个开源的服务监控系统和时序数据库 其提供了通用的数据模型…

【专题】2024跨境出海供应链洞察-更先进供应链报告合集PDF分享(附原数据表)

原文链接:https://tecdat.cn/?p37665 当前,全球化商业浪潮促使跨境电商行业飞速发展,产业带与跨境电商接轨、平台半托管模式涌现、社交电商带来红利机会以及海外仓不断扩张,这使得产业带外贸工厂、内贸工厂、传统进出口企业和品…