LlamaIndex 结构化数据库交互指南增强(text2sql)

打印 上一主题 下一主题

主题 883|帖子 883|积分 2649

结构化数据指南

很多现代数据系统都依赖于结构化数据,例如 Postgres DB 或 Snowflake 数据仓库。 LlamaIndex 提供了很多由 LLM 提供支持的高级功能,可以从中创建结构化数据 非结构化数据,以及通过增强的文本到 SQL 功能分析这些结构化数据。
注意:任何 Text-to-SQL 应用步伐都应该意识到,执行 恣意 SQL 查询可能存在安全风险。建议 根据需要采取预防步伐,例如使用受限角色、只读 数据库、沙箱等。
本指南资助介绍这些功能中的每一项。具体而言,我们涵盖以下主题:


  • 设置:定义我们的示例 SQL 表。
  • 构建我们的表索引:怎样从sql数据库转到表架构索引
  • 使用天然语言 SQL 查询:怎样使用天然语言查询我们的 SQL 数据库。
    我们将演练一个包含城市/人口/国家/地区信息的玩具示例表。 此处提供了本教程的笔记本。
设置

起首,我们使用 SQLAlchemy 设置一个简单的 sqlite 数据库:
  1. from sqlalchemy import (
  2.     create_engine,
  3.     MetaData,
  4.     Table,
  5.     Column,
  6.     String,
  7.     Integer,
  8.     select,
  9.     column,
  10. )
  11. engine = create_engine("sqlite:///:memory:")
  12. metadata_obj = MetaData()
复制代码
然后我们创建一个测试表:city_stats
  1. # create city SQL table
  2. table_name = "city_stats"
  3. city_stats_table = Table(
  4.     table_name,
  5.     metadata_obj,
  6.     Column("city_name", String(16), primary_key=True),
  7.     Column("population", Integer),
  8.     Column("country", String(16), nullable=False),
  9. )
  10. metadata_obj.create_all(engine)
复制代码
现在是时候插入一些数据点了!
如果您想通过推断结构化数据点来查看怎样填充此表 从非结构化数据中,请查看以下部门。否则,您可以选择 要直接填充此表,请执行以下操作:
  1. from sqlalchemy import insert
  2. rows = [
  3.     {"city_name": "Toronto", "population": 2731571, "country": "Canada"},
  4.     {"city_name": "Tokyo", "population": 13929286, "country": "Japan"},
  5.     {"city_name": "Berlin", "population": 600000, "country": "Germany"},
  6. ]
  7. for row in rows:
  8.     stmt = insert(city_stats_table).values(**row)
  9.     with engine.begin() as connection:
  10.         cursor = connection.execute(stmt)
复制代码
最后,我们可以用 SQLDatabase 包装器包装 SQLAlchemy 引擎; 这允许在LlamaIndex中使用 db:
  1. from llama_index.core import SQLDatabase
  2. sql_database = SQLDatabase(engine, include_tables=["city_stats"])
复制代码
天然语言 SQL

构建 SQL 数据库后,我们可以使用 NLSQLTableQueryEngine 来 构造合成为 SQL 查询的天然语言查询。
请注意,我们需要指定要用于此查询引擎的表。 如果我们不如许做,查询引擎将拉取所有 schema 上下文,这可能会 overflow 的上下文窗口。
  1. from llama_index.core.query_engine import NLSQLTableQueryEngine
  2. query_engine = NLSQLTableQueryEngine(
  3.     sql_database=sql_database,
  4.     tables=["city_stats"],
  5. )
  6. query_str = "Which city has the highest population?"
  7. response = query_engine.query(query_str)
复制代码
此查询引擎应在您可以指定所需表的任何情况下使用 以提前查询,或者所有表架构的总巨细加上 提示符适合您的上下文窗口。
构建我们的表索引

如果我们事先不知道我们想使用哪个表,以及 Table Schema 溢出了您的上下文窗口巨细,我们应该存储 Table Schema 在索引中,以便在查询时我们可以检索正确的 schema。
我们可以做到这一点的方法是使用 SQLTableNodeMapping 对象,它接收一个SQLDatabase 并为传递的每个 SQLTableSchema 对象生成一个 Node 对象 放入 ObjectIndex 构造函数中。
  1. from llama_index.core.objects import (
  2.     SQLTableNodeMapping,
  3.     ObjectIndex,
  4.     SQLTableSchema,
  5. )
  6. table_node_mapping = SQLTableNodeMapping(sql_database)
  7. table_schema_objs = [
  8.     (SQLTableSchema(table_name="city_stats")),
  9.     ...,
  10. ]  # one SQLTableSchema for each table
  11. obj_index = ObjectIndex.from_objects(
  12.     table_schema_objs,
  13.     table_node_mapping,
  14.     VectorStoreIndex,
  15. )
复制代码
在这里,你可以看到我们定义了我们的 table_node_mapping,以及一个带有 “city_stats” 表名。我们将这些函数与 VectorStoreIndex 类定义。这将得到一个 VectorStoreIndex,此中 每个节点都包含表架构和其他上下文信息。您还可以添加任何其他 上下文信息。
  1. # manually set extra context text
  2. city_stats_text = (
  3.     "This table gives information regarding the population and country of a given city.\n"
  4.     "The user will query with codewords, where 'foo' corresponds to population and 'bar'"
  5.     "corresponds to city."
  6. )
  7. table_node_mapping = SQLTableNodeMapping(sql_database)
  8. table_schema_objs = [
  9.     (SQLTableSchema(table_name="city_stats", context_str=city_stats_text))
  10. ]
复制代码
使用天然语言 SQL 查询

定义表架构索引obj_index后,我们可以构造一个 SQLTableRetrieverQueryEngine 通过传入我们的 SQLDatabase 和从我们的对象索引构造的检索器。
  1. from llama_index.core.indices.struct_store import SQLTableRetrieverQueryEngine
  2. query_engine = SQLTableRetrieverQueryEngine(
  3.     sql_database, obj_index.as_retriever(similarity_top_k=1)
  4. )
  5. response = query_engine.query("Which city has the highest population?")
  6. print(response)
复制代码
现在,当我们查询 retriever 查询引擎时,它将检索相关的表 schema 并合成 SQL 查询和来自该查询结果的相应。
结束语

之前写了一篇文章 《Chainlit集成LlamaIndex并使用通义千问实现和数据库交互的网页对话应用(text2sql)》,是直接使用llama index中的NLSQLTableQueryEngine的知识点扩展补充,使用SQLTableRetrieverQueryEngine,它将检索相关的表 schema 并合成 SQL 查询和来自该查询结果的相应。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

民工心事

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表