RAG与LLM原理及实践(2)--- RAG结合LLM function调用的原理及落地实践

花一点时间继续写下,RAG结合LLM。通过上一篇文章你应该知道为什么RAG要结合LLM,或者说为什么LLM要结合RAG使得LLM更强大,特别是当LLM 应用在人机对话等方面的时候。只要涉及一问一答,并通过上下文继续丰富对话,就会涉及到他。这个是看事情的两个维度。就像是买钟送电池还是买电池送闹钟。一方面,RAG的专家知识库上因为加入了LLM,而使得RAG对应更自然,不再是生硬的回答,借助LLM,可以帮助RAG的回答润色。另一方面,LLM因为专业知识的相对缺乏,毕竟是AIGC,不是垂直领域的AI,所以需要RAG帮忙加持,二者相互完善,彼此成就。好了,不太喜欢写虚的,直接开始干货分享。

在这两者结合的过程中,你要知道一件事,那就是LLM大模型必须知道你所提出的问题,在什么时候需要 LLM来回答, 什么时候需要 RAG 来回答,才是比较好的结果,prompt 起着至关重要的作用。他本质上会告诉LLM,这个问题由RAG来回答是比较好的,因为‘我’是这方面的领域专家。LLM怎么知道他是这方面领域的专家呢?就可以透过一些关键字来描述。当然prompt 的用处很多,很多书上会写他实际上会指导在客户描述的受限条件下,这里的受限条件,可以由prompt 来描述。比如 ‘如果你发现这类问题是医学相关的问题,请尝试使用我的RAG_Medcine 知识库做回答 ’。但在每个模型实现时,又有所差别。

我下面用通义千问 model 来进行举例说明,通过function式的调用如何实现RAG与LLM结合,并解释他是如何工作的,先附上完整代码:

from datetime import datetime
import random
import json
import dashscope
from dashscope import Generation

dashscope.api_key = '需要自己去申请一个key'

# 定义工具列表,模型在选择使用哪个工具时会参考工具的name和description
tools = [
    # 工具1 获取当前时刻的时间
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "当你想知道现在的时间时非常有用。",
            "parameters": {}  # 因为获取当前时间无需输入参数,因此parameters为空字典
        }
    },
    # 工具2 获取指定城市的天气
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "当你想查询指定城市的天气时非常有用。",
            "parameters": {  # 查询天气时需要提供位置,因此参数设置为location
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市或县区,比如北京市、杭州市、余杭区等。"
                    }
                }
            },
            "required": [
                "location"
            ]
        }
    }
]


# 模拟天气查询工具。返回结果示例:“北京今天是晴天。”
def get_current_weather(location):
    return f"{location}今天是晴天。 "


# 查询当前时间的工具。返回结果示例:“当前时间:2024-04-15 17:15:18。“
def get_current_time():
    # 获取当前日期和时间
    current_datetime = datetime.now()
    # 格式化当前日期和时间
    formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')
    # 返回格式化后的当前时间
    return f"当前时间:{formatted_time}。"


# 封装模型响应函数
def get_response(messages):
    response = Generation.call(
        model='qwen-max',
        messages=messages,
        tools=tools,
        seed=random.randint(1, 10000),  # 设置随机数种子seed,如果没有设置,则随机数种子默认为1234
        result_format='message'  # 将输出设置为message形式
    )
    return response


def call_with_messages():
    print('\n')
    messages = [
        {
            "content": input('请输入:'),  # 提问示例:"现在几点了?" "一个小时后几点" "北京天气如何?"
            "role": "user"
        }
    ]

    # 模型的第一轮调用
    first_response = get_response(messages)
    assistant_output = first_response.output.choices[0].message
    print(f"\n大模型第一轮输出信息:{first_response}\n")
    messages.append(assistant_output)
    # 如果模型判断无需调用工具,则将assistant的回复直接打印出来,无需进行模型的第二轮调用
    if 'tool_calls' not in assistant_output:
        print(f"最终答案:{assistant_output.content}")
        return
    # 如果模型选择的工具是get_current_weather
    elif assistant_output.tool_calls[0]['function']['name'] == 'get_current_weather':
        tool_info = {"name": "get_current_weather", "role": "tool"}
        location = json.loads(assistant_output.tool_calls[0]['function']['arguments'])['properties']['location']
        tool_info['content'] = get_current_weather(location)
    # 如果模型选择的工具是get_current_time
    elif assistant_output.tool_calls[0]['function']['name'] == 'get_current_time':
        tool_info = {"name": "get_current_time", "role": "tool"}
        tool_info['content'] = get_current_time()
    print(f"工具输出信息:{tool_info['content']}\n")
    messages.append(tool_info)

    # 模型的第二轮调用,对工具的输出进行总结
    second_response = get_response(messages)
    print(f"大模型第二轮输出信息:{second_response}\n")
    print(f"最终答案:{second_response.output.choices[0].message['content']}")


if __name__ == '__main__':
    call_with_messages()

我们看看他的输出:

我们可以看到我们自己定义了专业的函数,这就相当于是 RAG,他的 "description": "当你想知道现在的时间时非常有用。" 为LLM指明了什么情况下 LLM 应该调用‘我’。当大模型发现需要调用‘我’RAG时,就会调用。同时我们将RAG生成的答案再经过一次LLM,他会在已有答案上进行之前我说的润色,得到最终答案。附上一个解释说明,你会更加明白:

时间有限,今天先写到这里,后面继续补充

  • 30
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值