使用大模型,通过自然语言的查询语句,从数据库获取结果,是目前大模型和结构化数据交互的一种主流形式。
举个例子,存储朝阳区高中学校招生信息的数据库,现在问它 陈经纶招多少人?
,生成回答的大致步骤是:
- 数据库的 DDL 加入对话上下文,主要是建表语句,让大模型感知表结构
- 大模型将提示词
陈经纶招多少人?
转化为 SQL 查询语句,比如select * from school_info where school_name like '%陈经纶%'
- 大模型根据 SQL 查询结果,生成自然语言的回答,比如
北京市陈经纶中学招收的学生人数为279名。
以下使用 Jupyter 笔记实现了一个示例:
- 笔记代码见 [通过 LlamaIndex 使用自然语言查询数据库]
- 搭建 JupyterLab 笔记环境见 在 4GB 显存下运行 LLM 基础开发环境
- 笔记中使用的技术
- sqlalchemy,ORM 工具,建表和表记录
- 数据库使用 sqlite,也可以改为其他sql标准数据库
- 使用 LlamaIndex 简化检索查询方面的开发
- 使用本地模型(通过ollama)和云端模型(通过one-api)执行
下面介绍下主要过程和初步结论。
准备数据
使用 sqlalchemy 在 sqlite 建内存数据库和相关记录:
# 建立连接和表
from sqlalchemy import (
create_engine,
MetaData,
Table,
Column,
String,
Integer,
select,
)
engine = create_engine("sqlite:///:memory:")
metadata_obj = MetaData()
# 创建学校信息表结构
table_name = "school_info"
school_info_table = Table(
table_name,
metadata_obj,
Column("school_name", String(200), primary_key=True),
Column("students_enrolled", Integer,nullable=False),
)
metadata_obj.create_all(engine)
# 插入学校信息记录
rows = [
{"school_name": "北京市第八十中学", "students_enrolled": 260},
{"school_name": "北京市陈经纶中学", "students_enrolled": 279},
{"school_name": "北京市日坛中学", "students_enrolled": 403},
{"school_name": "中国人民大学附属中学朝阳学校", "students_enrolled": 247},
{"school_name": "北京工业大学附属中学", "students_enrolled": 418},
{"school_name": "北京中学", "students_enrolled": 121},
]
for row in rows:
stmt = insert(school_info_table).values(**row)
with engine.begin() as connection:
cursor = connection.execute(stmt)
数据可以通过 pandas
查询显示:
最基本的使用
需要 LLM 和嵌入模型,设置到 LlamaIndex 全局 Settings
中,这样后续不必在方法参数中设置:
Settings.llm=OpenAILike(
model="qwen2",
api_base="http://monkey:11434/v1",
api_key="ollama",
is_chat_model=True,
temperature=0.1,
request_timeout=60.0
)
Settings.embed_model =OllamaEmbedding(
model_name="quentinz/bge-large-zh-v1.5",
base_url="http://monkey:11434",
ollama_additional_kwargs={"mirostat": 0}, # -mirostat N 使用 Mirostat 采样。
)
执行查询:
query_engine = NLSQLTableQueryEngine(
sql_database=sql_database,
tables=["school_info"],
)
query_str = "招生最多的是哪个学校?"
response = query_engine.query(query_str)
# '招生最多的是北京工业大学附属中学,共有418名学生。'
这种方式的不足:
- 不支持对话流式输出
- 当表很多的时候,可能受到对话上下文长度限制
支持流式输出回答
需要使用 LlamaIndex 底层的检索 API:
nl_sql_retriever = NLSQLRetriever(
sql_database, tables=["school_info"], return_raw=True
)
query_engine = RetrieverQueryEngine.from_args(
nl_sql_retriever,
streaming=True
)
response = query_engine.query(
"招生最多的前三个学校?"
)
response.print_response_stream()
运行效果:
支持模糊查询
默认情况下查询是不支持模糊查询的:
response = query_engine.query("陈经纶招多少?")
response.print_response_stream()
# 无法回答这个问题,因为提供的上下文信息是一个空列表,没有包含任何与“陈经纶招多少”相关的内容。需要具体的数字、单位或者上下文来提供一个准确的答案。
需要增加提示词,另外需要高级 LLM 模型,本地模型(qwen 7b,14b/qwen2 7b/yi 6b)都不行,云端模型目前只有 qwen-turbo
生成的 sql 符合要求:
nl_sql_retriever = NLSQLRetriever(
sql_database, tables=["school_info"],
return_raw=False,
llm=OpenAILike(
model='qwen-turbo',
api_base="http://ape:3000/v1",
api_key="sk-bJP6QSnUfjAYeYeE505d3eBf63A643BeB0B8E350Df9b7750",
is_chat_model=True,
temperature=0.1,
request_timeout=60.0
)
)
old_prompt_str=nl_sql_retriever.get_prompts()['text_to_sql_prompt'].template
new_prompt = PromptTemplate(
f"{old_prompt_str}"
"查询关键字使用模糊查询, 并且查询结果应包含关键字所属的列"
)
nl_sql_retriever.update_prompts({"text_to_sql_prompt": new_prompt})
query_engine = RetrieverQueryEngine.from_args(
nl_sql_retriever,
streaming=True,
)
response = query_engine.query(
"陈经纶招多少?"
)
response.print_response_stream()
# 陈经纶招收279名学生。
可以查看到检索数据详情:
[NodeWithScore(node=TextNode(id_=‘5baee8fa-73df-4133-952a-9a0e3b1b31ae’, embedding=None, metadata={‘sql_query’: “SELECT school_name, students_enrolled FROM school_info WHERE school_name LIKE ‘%陈经纶%’ ORDER BY students_enrolled DESC LIMIT 1;”, ‘result’: [(‘北京市陈经纶中学’, 279)], ‘col_keys’: [‘school_name’, ‘students_enrolled’]}, excluded_embed_metadata_keys=[‘sql_query’, ‘result’, ‘col_keys’], excluded_llm_metadata_keys=[‘sql_query’, ‘result’, ‘col_keys’], relationships={}, text=“[(‘北京市陈经纶中学’, 279)]”, mimetype=‘text/plain’, start_char_idx=None, end_char_idx=None, text_template=‘{metadata_str}\n\n{content}’, metadata_template=‘{key}: {value}’, metadata_seperator=‘\n’), score=None)]
如果需要更多要求,比如显示学校名称应该用全名,那么还得定制提示词,并且有与之匹配的模型,这里需要再上述检索基础上对回答内容增加提示词要求:
my_qa_prompt_template = (
"回答中要求使用学校的完整名称(school_name)"
"不用再计算,给出的就是答案"
"Context information is below.\n"
"---------------------\n"
"{context_str}\n"
"---------------------\n"
"Given the context information and not prior knowledge, "
"answer the query.\n"
"Query: {query_str}\n"
"Answer: "
)
my_qa_prompt = PromptTemplate(
my_qa_prompt_template, prompt_type=PromptType.QUESTION_ANSWER
)
query_engine = RetrieverQueryEngine.from_args(
nl_sql_retriever,
streaming=True,
text_qa_template=my_qa_prompt,
)
response = query_engine.query(
"陈经纶招多少?"
)
response.print_response_stream()
运行效果:
总结
- 演示了如何使用大模型,将自然语言生成sql,并将sql查询结果,以自然语言形式回答
- 想得到预期结果,十分依赖大模型能力和相关的提示词
- 目前测试,gpt4效果最好,国内云端模型qwen高级模型较好,其他云端模型问题较多
- 本文主要使用qwen2:7b, 在检索阶段(自然语言生成sql)可能需要依赖更强的云端模型
- 初步结论,如果采用 nl2sql 方式,需要能力更高的云端或者自己微调的本地模型
那么,如何系统的去学习大模型LLM?
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。
但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
所有资料 ⚡️ ,朋友们如果有需要全套 《LLM大模型入门+进阶学习资源包》,扫码获取~
篇幅有限,部分资料如下:
👉LLM大模型学习指南+路线汇总👈
💥大模型入门要点,扫盲必看!
💥既然要系统的学习大模型,那么学习路线是必不可少的,这份路线能帮助你快速梳理知识,形成自己的体系。
👉大模型入门实战训练👈
💥光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
👉国内企业大模型落地应用案例👈
💥《中国大模型落地应用案例集》 收录了52个优秀的大模型落地应用案例,这些案例覆盖了金融、医疗、教育、交通、制造等众多领域,无论是对于大模型技术的研究者,还是对于希望了解大模型技术在实际业务中如何应用的业内人士,都具有很高的参考价值。 (文末领取)
💥《2024大模型行业应用十大典范案例集》 汇集了文化、医药、IT、钢铁、航空、企业服务等行业在大模型应用领域的典范案例。
👉LLM大模型学习视频👈
💥观看零基础学习书籍和视频,看书籍和视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。 (文末领取)
👉640份大模型行业报告👈
💥包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
👉获取方式:
这份完整版的大模型 LLM 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
】
😝有需要的小伙伴,可以Vx扫描下方二维码免费领取🆓