原文:Reimagining the Recommendation Engine
AI助手的崛起
人工智能正在改变我们与在线应用程序互动的方式。目前,我们使用搜索引擎、新闻源和精心设计的菜单来导航,这些菜单引导我们找到所需的信息或服务。然而,我相信目前人工智能的创新使一种新型的推荐引擎成为可能:人工智能助手。随着Chat-GPT和Bard的出现,我们已经看到了这方面的证据。但是,让我们考虑一个示例来进一步说明这一点。想象一下,你正在伦敦度假,你想和一些朋友在格林威治公园野餐。在你决定日期之前,你可能会通过谷歌搜索或直接找到你喜欢的天气预报服务。接下来,您将浏览他们的站点并检查所选日期范围内的天气预报,根据最有利的天气选择一天和时间。

格林威治公园
如果你直接问不是更简单吗?“哪天去格林威治公园野餐最好?”
不需要搜索谷歌,不需要选择你的日子。如果它与语音助手相连,你可能甚至不需要输入任何东西,你只需要从你信任的人工智能天气助手那里得到一个建议,告诉你安排旅行的最佳日期。
在本文中,我将演示如何使用从Open AI、Langchain ‘s SQL Database Chain和Open Weather Map API调用的函数来实现这一点。
请注意下面的动图,展示了我在实际中开发的原型
The first shows the response to “What’s the best day to have a picnic in Greenwich park?”(第一个是对“在格林威治公园野餐最好的一天是哪天?”)

这是一个温和的例子,说明了什么是可能的。让我们尝试一些更复杂的方法。如果我们去冰岛旅游,想看北极光呢?我们可能会问:“When am I most likely to see the Northern Lights in Reykjavik?(我什么时候最有可能在雷克雅未克看到北极光?)”
如果您对此印象深刻,请继续阅读,我将解释它是如何工作的。
(简化的)应用架构

首先,我想通过提供我认为将为这些人工智能助手提供动力的架构类型的广泛而直接的概述来建立背景。
他们将使用大型语言模型 (LLM)函数调用、API请求和对结构化数据集的自动查询来向用户提供个性化的响应。
随着生态系统的成熟,这个也会成熟,但我相信一般的方法将保持不变——只是增加一些额外的功能。
这是我用来构建AI天气助手原型的通用架构,所以让我们深入了解一些技术细节,以获得更好的理解。
函数调用
在llm出现之前,解析文本需要使用Regex——它非常严格,限制了我们使用自然语言所能做的事情。
现在有了llm和函数调用,我们可以更灵活地操作自然语言。让我们检查一下函数调用本身,以理解为什么它如此强大。
在我们的AI天气助手示例中,应用程序的用户希望确定访问特定地点的最佳日期,可能是为了参加活动。
因此,我们需要三个关键的信息:地标/目的地、它的坐标(纬度、经度)和未来一段时间的天气预报。
一旦知道了地标/目的地,后两者就很简单了。但是,前者是从用户提供的自由格式文本输入派生出来的。
由于拼写错误、大小写不一致和语法错误,或者目的地可能只能通过上下文推断,因此从自由文本中确定目的地是具有挑战性的。
然而,这正是函数调用被证明是无价的地方。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | from geopy.geocoders import Nominatim
import pandas as pd
import requests
import uuid
# gets latitude and longitude
def get_lat_long(location):
    geolocator = Nominatim(user_agent="my_application_" + str(uuid.uuid4()))
    location = geolocator.geocode(location)
    return (location.latitude, location.longitude)
# gets weather data for the enxt five days - returns a dataframe
def get_weather(location_response, location):
    api_key = YOUR_OPEN_WEATHER_MAP_API_KEY   # Replace with your API key from Open Weather Map
    base_url = "https://api.openweathermap.org/data/2.5/forecast"
    params = {
        'lat': location_response[0],  # latitude
        'lon': location_response[1],  # longitude
        'appid': api_key,
        'units': 'metric'   # change 'metric' to 'imperial' for Fahrenheit
    }
    response = requests.get(base_url, params=params)
    weather_data = response.json()
    df = pd.json_normalize(weather_data['list']).drop(columns='weather')
    df['location'] = location
        
    return df
 | 
我们首先定义检索天气数据的函数。我们有两个独立的函数。
第一个方法接受位置作为非特定输入,并返回纬度和经度。
第二个方法接受纬度、经度和位置,并通过调用Open weather Map API返回一个包含该位置未来五天天气数据的数据框。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import openai
import pandas as pd
import json
def parse_location(query):
    
    # OpenAI function calling
    
    function_call = [
    {
      "name": "get_lat_long",
      "description": "Takes the location as an argument. Returns a tuple (latiude, longitude)",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": '''Do not answer the question. Only respond with the location, or the location of the landmark/tourist attraction mentioned.
      Location must be in the form City name, state code (only for the US) and country code divided by comma.
      Please use ISO 3166 country codes.'''
          }
        },
        "required": ["location"]
      }
    }
    ]
    
    # Open AI API Call
    openai.api_key = YOUR_OPEN_AI_API_KEY  # Replace this with your openAI API key
    message = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[{"role": "system", "content": query}],
        functions = function_call,
        function_call = 'auto',
        temperature=0
    )
    
    arguments = message["choices"][0]["message"]["function_call"]["arguments"]
    arguments_dict = json.loads(arguments)
    location = arguments_dict['location'] 
    
    print(f"LOCATION!: {location}")
    return location
 | 
接下来,我们设计函数调用。这里我们感兴趣的函数是我们之前定义的get_lat_long函数,它以location作为参数。我们在函数调用字典中的name键中建立它。
真正的“神奇”发生在parameters键下,我们通过其属性定义参数。
该描述尤其重要,因为它使我们能够利用大型语言模型的预测属性来帮助从查询中识别位置。
例如,如果用户询问:“参观埃菲尔铁塔的最佳日期是哪天?”,我们将收到以下回复:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <OpenAIObject chat.completion id=chatcmpl-7byJmyUNMNeYIIQhrBQ295u4JqM4C at 0x1f654544680> JSON: {
  "id": "chatcmpl-7byJmyUNMNeYIIQhrBQ295u4JqM4C",
  "object": "chat.completion",
  "created": 1689284354,
  "model": "gpt-4-0613",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "{\n  \"location\": \"Paris, FR\"\n}"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 124,
    "completion_tokens": 12,
    "total_tokens": 136
  }
}
    }
  ],
  "usage": {
    "prompt_tokens": 132,
    "completion_tokens": 19,
    "total_tokens": 151
  }
}
 | 
我们可以看到函数调用返回了Paris, Fr作为我们的位置。这里的诀窍是,我们利用模型的强大功能,直接从查询中推断出埃菲尔铁塔的位置。
在这个关键时刻,我应该提出一个警告:虽然这个技巧到目前为止表现良好,但llm不是数据库查找,它们可能会产生幻觉并推断出错误的位置。
为了提高健壮性,可以加入一个步骤,将位置与数据库交叉引用。虽然我没有对错误率做过任何数学计算,但大多数时候,这个模型都是正确的,特别是如果你使用GPT-4以后的版本。
一旦确定了位置,我们就可以继续获取纬度和经度,最终从Open weather Map返回用户指定位置的结构化天气数据。
Langchain SQL数据库链
创新的第二部分是朗链的SQL数据库链。调用API之后,我们就有了一些结构化的天气数据。
我们可以利用Langchain的SQL数据库链来自动查询。下面是相应的代码片段。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | from sqlalchemy import create_engine
import openai
import pandas as pd
from langchain import OpenAI, SQLDatabase, SQLDatabaseChain
# load data in memeory to sql lite database
def load_data(df):
  engine = create_engine('sqlite:///:memory:')
  # Write the data to the SQLite database
  df.to_sql('weather', engine, if_exists='replace', index=False)
  # Check if the data was loaded correctly
  df_loaded = pd.read_sql('SELECT * FROM weather', engine)
  db = SQLDatabase(engine)
  return db
# run langchain sql database chain 
def run_query(query, db):
  openai_token = YOUR_OPENAI_KEY
  llm = OpenAI(temperature=0, verbose=True, openai_api_key=openai_token)
  db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True, use_query_checker=True)
  response = db_chain.run(query)
  return response
 | 
Note: 我对SQL数据库链使用的一个小提示工程技巧是要求模型解释它的选择,我发现这样做会产生更好的响应。这只需使用f字符串即可完成。
| 1 2 3 | query = "What's the best day to visit the Eiffel Tower for the best view of the city?"
query_1 = f"{query} Return an explanation alongside your response, and a description of the relevant weather conditions"
 | 
SQL数据库链将自然语言请求转换为SQL查询,并在结构化天气数据上执行该查询。
让我们回想一下雷克雅未克的例子。SQL数据库链生成的SQL查询是这样的:

SQL数据库链能够进行一些分析推理。它可以接受用户提交的请求并基于它生成SQL查询。
通过检查SQL查询,我们可以辨别模型用来生成响应的逻辑。看看你是否相信它与反应一致。
人工智能天气助手原型可供你自己玩。你需要一个OpenAI API密钥来让它工作并批准使用GPT-4,不幸的是,该模型不能与GPT-3.5一起工作。
总结
我相信专业的人工智能助手将在众多服务行业中变得越来越普遍。
采用这些更无缝的人工智能替代方案的公司可能会从一些采用传统菜单或基于搜索的选项的公司那里抢夺市场份额。
我可以想象这样一个未来,我们与人工智能助手互动,帮助我们预订机票、安排住宿、计划约会、组织我们的财务生活——这个清单是无止境的。然而,仍有许多问题需要解决。
-  延迟相当高,特别是考虑到我们已经习惯了即时请求和接收信息。 
-  用户体验设计是另一个将被证明是关键区别的领域。目前,许多人工智能应用程序感觉很麻烦,但用户体验将得到改善,并将成为用户采用背后的关键驱动力之一。 
-  一致性很难实现。大多数情况下,模型会返回相同的结果,但偶尔也会给出不同的建议。对于期望一定程度的确定性的用户来说,这可能是一个问题。 
-  调用多个api的成本限制了高价值用例的商业可行性。 


![Mybatis-Plus自动填充功能配置和使用 [MyBatis-Plus系列] - 第494篇](https://img-blog.csdnimg.cn/img_convert/d67a3557c4f4feda413c175f4d46ab4f.png)















