浏览代码

智能选址数据库切换为控规数据表

liutao 3 月之前
父节点
当前提交
c3d99c3f18

+ 11 - 4
aiAgent_gd/qwen_agent/config/db_config.py

@@ -11,11 +11,18 @@ db_list = {
     #     "password": "zjugis1402!",
     # }
     "pg": {
-        "host": "10.10.9.243",
-        "port": "5432",
+        "host": "172.27.27.16",
+        "port": "yzt",
         "database": "sde",
-        "user": "sde",
-        "password": "zjugis1402!",
+        "user": "zjgt_ww_readonly",
+        "password": "Zjgt_ww_16",
     }
+    # "pg": {
+    #     "host": "10.10.9.243",
+    #     "port": "5432",
+    #     "database": "sde",
+    #     "user": "sde",
+    #     "password": "zjugis1402!",
+    # }
 }
 

+ 3 - 13
aiAgent_gd/qwen_agent/memory/data/plans/plan_examples_智能选址.jsonl

@@ -2,21 +2,11 @@
   {
     "query_type": "land_site_selection",
     "query": "帮我在萧山区推荐几块50亩左右的工业用地",
-    "plan": "Question: 帮我在萧山区推荐几块50亩左右的工业用地 \nThought: 用户问题中想查询城市为‘萧山区’,面积为‘50’亩左右,土地用途为‘工业用地’的地块,数量未限制,工业用地属于土地用途大类,包含如下具体的土地用途小类'工业用地','通用仓储类','标准厂房','工业用地(新业态用地M0)','工矿仓储用地','其他工业用地',所以需要通过[LandSiteSelectionSqlAgent]查询图层信息,最后使用summary的Action来总结并输出。Plan: ```json\n    [{\"action_name\": \"LandSiteSelectionSqlAgent\", \"instruction\": \"你需要调用 [LandSiteSelectionSqlAgent],来查询城市为‘萧山区’,面积为‘50’亩左右,土地用途为'工业用地','通用仓储类','标准厂房','工业用地(新业态用地M0)','工矿仓储用地','其他工业用地'的地块\"},\n    {\"action_name\": \"summary\", \"instruction\": \"你需要根据用户的Question和查询的结果,回答用户问题。\"}]"
+    "plan": "Question: 帮我在萧山区推荐几块50亩左右的工业用地 \nThought: 用户问题中想查询城市为‘萧山区’,面积为‘50’亩左右,用地性质‘工业’的地块,数量未限制,所以需要通过[LandSiteSelectionSqlAgent]查询图层信息,最后使用summary的Action来总结并输出。Plan: ```json\n    [{\"action_name\": \"LandSiteSelectionSqlAgent\", \"instruction\": \"你需要调用 [LandSiteSelectionSqlAgent],来查询城市为‘萧山区’,面积为‘50’亩左右,用地性质‘工业’的地块\"},\n    {\"action_name\": \"summary\", \"instruction\": \"你需要根据用户的Question和查询的结果,回答用户问题。\"}]"
   },
   {
     "query_type": "land_site_selection",
-    "query": "帮我在萧山区推荐一宗50亩左右的标准厂房",
-    "plan": "Question: 帮我在萧山区推荐一宗50亩左右的标准厂房\nThought: 用户问题中想查询城市为‘萧山区’,数量为‘1’宗,面积为‘50’亩左右,土地用途为‘标准厂房’的地块,工业用地属于土地用途小类,所以需要通过[LandSiteSelectionSqlAgent]查询图层信息,最后使用summary的Action来总结并输出。Plan: ```json\n    [{\"action_name\": \"LandSiteSelectionSqlAgent\", \"instruction\": \"你需要调用 [LandSiteSelectionSqlAgent],来查询城市为‘萧山区’,数量为‘1’宗,面积为‘50’亩左右,土地用途为'标准厂房'的地块\"},\n    {\"action_name\": \"summary\", \"instruction\": \"你需要根据用户的Question和查询的结果,回答用户问题。\"}]"
-  },
-  {
-    "query_type": "land_site_selection",
-    "query": "帮我在杭州市滨江区正泰大厦附近推荐二宗50亩左右的标准厂房",
-    "plan": "Question: 帮我在杭州市滨江区正泰大厦附近推荐二宗50亩左右的标准厂房 \nThought: 用户问题中想查询城市为‘杭州市’,区县为‘滨江区’,详细地点为‘杭州市滨江区正泰大厦’,数量为‘2’宗,面积为‘50’亩左右,土地用途为‘标准厂房’的地块,所以需要先通过[GisGeocoderAgent]将详细的地址转换为坐标点,再通过[LandSiteSelectionSqlAgent]查询图层信息,最后使用summary的Action来总结并输出。Plan: ```json\n    [{\"action_name\": \"GisGeocoderAgent\", \"instruction\": \"你需要调用 [GisGeocoderAgent],来将‘杭州市滨江区正泰大厦’ 转换为坐标wkt\"},\n {\"action_name\": \"LandSiteSelectionSqlAgent\", \"instruction\": \"你需要调用 [LandSiteSelectionSqlAgent],来查询行政区为‘滨江区’,面积为‘50’亩左右,数量为‘2’宗,土地用途为‘标准厂房’的地块\"},   {\"action_name\": \"summary\", \"instruction\": \"你需要根据用户的Question和查询的结果,回答用户问题。\"}]"
-  },
-  {
-    "query_type": "land_site_selection",
-    "query": "请在萧山机场附近选出30-100亩之间适用来做物流仓储的地块",
-    "plan": "Question: 请在萧山机场附近选出30-100亩之间适用来做物流仓储的地块 \nThought: 用户问题中想查询详细地点为‘萧山机场’,面积为‘30-100’亩左右,土地用途为‘物流仓储’的地块,数量未限制,再通过[LandSiteSelectionSqlAgent]查询图层信息,最后使用summary的Action来总结并输出。Plan: ```json\n    [\n {\"action_name\": \"LandSiteSelectionSqlAgent\", \"instruction\": \"你需要调用 [LandSiteSelectionSqlAgent],来查询行政区为‘萧山区’,面积为‘30-100’亩左右,土地用途为‘物流仓储’的地块\"},   {\"action_name\": \"summary\", \"instruction\": \"你需要根据用户的Question和查询的结果,回答用户问题。\"}]"
+    "query": "帮我在萧山区推荐一宗1公顷左右的学校用地",
+    "plan": "Question: 帮我在萧山区推荐一宗1公顷左右的学校用地\nThought: 用户问题中想查询城市为‘萧山区’,数量为‘1’宗,面积为‘1公顷’左右,用地性质‘学校’的地块,所以需要通过[LandSiteSelectionSqlAgent]查询图层信息,最后使用summary的Action来总结并输出。Plan: ```json\n    [{\"action_name\": \"LandSiteSelectionSqlAgent\", \"instruction\": \"你需要调用 [LandSiteSelectionSqlAgent],来查询城市为‘萧山区’,数量为‘1’宗,面积为‘1公顷’左右,用地性质'学校'的地块\"},\n    {\"action_name\": \"summary\", \"instruction\": \"你需要根据用户的Question和查询的结果,回答用户问题。\"}]"
   }
 ]

+ 3 - 13
aiAgent_gd/qwen_agent/memory/data/sqls/sql_examples_智能选址.jsonl

@@ -2,21 +2,11 @@
   {
     "query_type": "land_site_selection",
     "query": "帮我在萧山区推荐几块50亩左右的工业用地",
-    "sql_code": "select id, dkid, xzqmc, dkmc, address, dkmj, tdyt, st_astext(st_centroid(shape)) as center_wkt from sde.ecgap_klyzy where xzqmc = '萧山区' and tdyt in ('工业用地','通用仓储类','标准厂房','工业用地(新业态用地M0)','工矿仓储用地','其他工业用地') and abs(dkmj - 50) <= 5 and sfsj=1 order by dkmj nulls last limit 10"
+    "sql_code": "select objectid, xzqmc, xzqdm, dymc, yddm, ydxz, ydmj, rjlsx, rjlxx, jzmdsx, jzmdxx, jzgdsx, jzgdxx, ldlsx, ldlxx, pfwh, pfsj, st_astext(shape) as geom, st_astext(st_centroid(shape)) as center_wkt from dlgis.gcs330000g2007_kzxxxgh_kgdk_kgy_dsgj where xzqmc = '萧山区' and ydxz like '%工业%' and abs(ydmj - 50*0.0667) <= 1 order by ydmj nulls last limit 10"
   },
   {
     "query_type": "land_site_selection",
-    "query": "帮我在萧山区推荐一宗50亩左右的标准厂房",
-    "sql_code": "select id, dkid, xzqmc, dkmc, address, dkmj, tdyt, st_astext(st_centroid(shape)) as center_wkt from sde.ecgap_klyzy where xzqmc = '萧山区' and tdyt ='标准厂房' and abs(dkmj - 50) <= 5 and sfsj=1 order by dkmj nulls last limit 1"
-  },
-  {
-    "query_type": "land_site_selection",
-    "query": "帮我在杭州市滨江区正泰大厦附近推荐二宗50亩左右的标准厂房",
-    "sql_code": "select t.* from (select id, dkid, xzqmc, dkmc, address, dkmj, tdyt, round(st_distance(st_geometryfromtext('POINT (120.42827489304307 30.23751646603668)', 4490)::geography,shape::geography)::numeric,0) as distance, st_astext(st_centroid(shape)) as center_wkt from sde.ecgap_klyzy where tdyt ='工业用地' and sfsj=1 and dkmj BETWEEN 30 and 100) as t where t.distance <= 5000  order by t.dkmj nulls last limit 2"
-  },
-  {
-    "query_type": "land_site_selection",
-    "query": "请在萧山机场附近选出30-100亩之间适用来做物流仓储的地块",
-    "sql_code": "select t.* from (select id, dkid, xzqmc, dkmc, address, dkmj, tdyt, round(st_distance(st_geometryfromtext('POINT (120.42827489304307 30.23751646603668)', 4490)::geography,shape::geography)::numeric,0) as distance, st_astext(st_centroid(shape)) as center_wkt from sde.ecgap_klyzy where dkmc like '%仓储%' and sfsj=1 and dkmj BETWEEN 30 and 100) as t where t.distance <= 5000  order by t.dkmj nulls last limit 10"
+    "query": "帮我在萧山区推荐一宗1公顷左右的学校用地",
+    "sql_code": "select objectid, xzqmc, xzqdm, dymc, yddm, ydxz, ydmj, rjlsx, rjlxx, jzmdsx, jzmdxx, jzgdsx, jzgdxx, ldlsx, ldlxx, pfwh, pfsj, st_astext(shape) as geom, st_astext(st_centroid(shape)) as center_wkt from dlgis.gcs330000g2007_kzxxxgh_kgdk_kgy_dsgj where xzqmc = '萧山区' and ydxz like '%学校%' and abs(ydmj - 1) <= 1 order by ydmj nulls last limit 10"
   }
 ]

+ 29 - 44
aiAgent_gd/qwen_agent/sub_agent/sql/land_site_selection_sql_agent.py

@@ -32,55 +32,40 @@ class LandSiteSelectionSqlAgent(BaseSubAgent):
         self.SubAgent_Summary_Prompt = "通过查询数据库,检索数据库得到的信息为:\n{obs}\n"
         self.SubAgent_PROMPT = """你是一个PostgreSQL专家,当前需要根据用户问题和上下文,生成语法正确的PostgreSQL查询语句。'
          #数据库表的表名和表结构如下:
-        `sde.ecgap_klyzy`(
-            `xzqmc` COMMENTS '所属区县(行政区代码) 用来指定区 或者 县',
+        `dlgis.gcs330000g2007_kzxxxgh_kgdk_kgy_dsgj`(
+            `objectid` COMMENTS '主键ID',
+            `xzqmc` COMMENTS '所属区县(行政区代码) 用来指定‘区’或者‘县’',
             `xzqdm` COMMENTS '行政区代码 6位,前2位代表省,前4位代表市,前6位代表区县',
-            `dkmc` COMMENTS '地块名称',
-            `dkid` COMMENTS '地块id',
-            `address` COMMENTS '土地坐落',
-            `dkmj` COMMENTS '土地面积,单位亩',
-            `tdyt` COMMENTS '土地规划用途',
+            `dymc` COMMENTS '地块名称',
+            `yddm` COMMENTS '用地代码',
+            `ydxz` COMMENTS '用地性质(土地用途)',
+            `ydmj` COMMENTS '用地面积 单位:公顷',
+            `pfwh` COMMENTS '批复文号',
+            `pfsj` COMMENTS '批复时间',
+            `rjlsx` COMMENTS '容积率上限',
+            `rjlxx` COMMENTS '容积率下限',
+            `jzmdsx` COMMENTS '建筑密度上限',
+            `jzmdxx` COMMENTS '建筑密度下限',
+            `jzgdsx` COMMENTS '建筑高度上限',
+            `jzgdxx` COMMENTS '建筑高度下限',
+            `ldlsx` COMMENTS '绿地率上限',
+            `ldlxx` COMMENTS '绿地率下限',
             `shape` COMMENTS '地块图形wkt',
-            `sfsj` COMMENTS '是否上架 1表示已上架,0表示未上架'
-        )
-
+        )'
 
         有几个注意事项:
-        注意0:请仔细区分"去年","今年","N年前","近三年"等时间关键词,必须使用to_char(transaction_sold_time,'yyyy') as nf,具体去年、今年等使用to_char(CURRENT_DATE - INTERVAL '1 year', 'YYYY')、to_char(CURRENT_DATE, 'YYYY'),如果提到了近三年、近五年时候查询是请使用to_char(transaction_sold_time,'yyyy') > to_char(CURRENT_DATE - INTERVAL '3 year', 'YYYY')、to_char(transaction_sold_time,'yyyy') > to_char(CURRENT_DATE - INTERVAL '5 year', 'YYYY');
-        注意1: 统计面积时候,无指定单位的情况下,请默认转换为亩并四舍五入成整数,平方米转换为亩请乘以0.0015
+        注意1: 统计面积时候,无指定单位的情况下,请默认转换为公顷,平方米转换公顷请乘以0.0001,亩转换为公顷请乘以0.0667
         注意2: 查询地区条件时,区县为**时请使用 xzqmc 字段。省为**时请先将行政区名称转换为行政区代码,使用xzqdm字段的前2位进行模糊查询,市为**时请先将行政区名称转换为行政区代码,使用xzqdm字段的前4位进行模糊查询
-        注意3: 计算百分比之类的数值时,需要使用round函数保留两位小数
-        注意4: 使用 order by 进行排序时。必须使用 nulls last 确保 null值不会对排序产生影响,使用方法如下: order by xxxx desc nulls last 或者 order by xxxx nulls last
-        注意5: 当用户问题中的面积等于不是一个确定值的时候,如‘面积为xx亩左右’或‘面积为xx平方米左右’, 需要条件中添加 abs(dkmj - xx) <= 5, 将面积差控制在5亩之内。使用 ‘order by abs(dkmj - xx)  nulls last’ 来进行排序
-        注意5: 当用户问题中的面积是一个确定值的时候,如‘面积为xx亩’或‘面积为xx平方米’, 需要条件中添加 abs(dkmj - xx) <= 5, 将面积差控制在5亩之内。使用 ‘order by abs(dkmj - xx)  nulls last’ 来进行排序
-        注意6: 查询出地块。必须要对dkmj 进行desc排序。查询地块有数量限制时,比如'1宗','一宗','1块',使用limit 1语句;未限定时,只查询10宗,使用limit 10语句
-        注意7: 问题中设计具体的地点时,需要使用round(st_distance(st_geometryfromtext('具体地点的wkt', 4528), st_transform(shape, 4528))::numeric,0)获取其distance, 如果问题未指定范围则使用 distance <= 5000 来限制在地点5公里内,并对其排序
-        注意8: 当问题中提及周边分析的条件时,不需要将其转换为查询条件,比如交通便利,离港口码头近,人口等
-        注意9: 生成sql时,只对涉及表结构中的字段进行条件设置,不可生成不在表字段列表中的查询条件,不可生成任何不在表字段中的条件,比如周边5公里有什么设施
-        注意10: 生成sql时,必须使用 st_astext(st_centroid(shape)) as center_wkt 
-        注意11: 查询语句必须包含 id, dkid, xzqmc, dkmc, address, dkmj, tdyt, st_astext(st_centroid(shape)) as center_wkt 这几个字段
-        注意12: 只准生成查询 的sql 语句,不可生成任何 修改数据的语句, 比如:update, delete, insert, truncate 等
-        注意14:当用户问题中的土地用途是"工业用地"时,工业用地属于土地用途大类,需要转换成对应的土地用途小类,使用in操作符进行查询
-        注意15:当用户问题中的土地用途是"城镇村道路用地"时,城镇村道路用地属于土地用途小类,使用=操作符进行查询
-        注意16:以下是数据中的土地用途大类
-                    道路用地:包含以下几种土地用途小类 城镇村道路用地,
-                    工业用地:包含以下几种土地用途小类 工业用地,通用仓储类,标准厂房,工业用地(新业态用地M0),工矿仓储用地,其他工业用地
-                    公用设施用地:包含以下几种土地用途小类 社会福利用地,公共管理与公共服务用地,公用设施用地,其他非养老机构用地
-                    公园与绿地:包含以下几种土地用途小类 公园与绿地
-                    交通服务场站用地:包含以下几种土地用途小类 交通服务场站用地
-                    交通用地:包含以下几种土地用途小类 交通运输用地
-                    科教文卫用地:包含以下几种土地用途小类 体育用地,文化设施用地,科研用地,医疗卫生用地,教育用地
-                    其他用地:包含以下几种土地用途小类 其他土地,其他用地
-                    商服用地:包含以下几种土地用途小类 餐饮用地,娱乐用地,商务金融用地,商服用地,旅馆用地,零售商业用地
-                    水工建筑用地:包含以下几种土地用途小类 水域及水利设施用地
-                    特殊用地:包含以下几种土地用途小类 特殊用地
-                    住宅用地:包含以下几种土地用途小类 居住用地,城镇住宅-用于安置的商品住房用地,住宅用地,农村宅基地,城镇住宅-保障性租赁住房,城镇住宅-租赁型商品住房,城镇住宅-公共租赁住房,城镇住宅-普通商品住房,城镇住宅-经济适用住房,城镇住宅用地
-        注意17: 如果土地用途是‘物流仓储’,不使用tdyt进行查询,使用dkmc进行模糊查询,比如:dkmc like '%仓储%'
-        ```
-        以下是可供参考的SQL写法(仅供参考,也可自由发挥):
-        ```
-        {refs}
-        ```
+        注意3: 使用 order by 进行排序时。必须使用 nulls last 确保 null值不会对排序产生影响,使用方法如下: order by xxxx desc nulls last 或者 order by xxxx nulls last
+        注意4: 当用户问题中的面积等于不是一个确定值的时候,如‘面积为xx亩左右’或‘面积为xx平方米左右’或‘面积为xx公顷左右’, 需要条件中添加 abs(ydmj - xx) <= 1, 将面积差控制在1公顷之内。使用 ‘order by abs(ydmj - xx)  nulls last’ 来进行排序
+        注意5: 当用户问题中的面积是一个确定值的时候,如‘面积为xx亩’或‘面积为xx平方米’或‘面积为xx公顷左右’, 需要条件中添加 abs(ydmj - xx) <= 1, 将面积差控制在1公顷之内。使用 ‘order by abs(ydmj - xx)  nulls last’ 来进行排序
+        注意6: 查询出地块。必须要对ydmj进行desc排序。查询地块有数量限制时,比如'1宗','一宗','1块',使用limit 1语句;未限定时,只查询10宗,使用limit 10语句
+        注意7: 问题中设计具体的地点时,需要使用round(st_distance(st_geometryfromtext('具体地点的wkt', 4490)::geography,shape::geography)::numeric,0)获取其distance, 如果问题未指定范围则使用 distance <= 5000 来限制在地点5公里内,并对其排序
+        注意8: 生成sql时,只对涉及表结构中的字段进行条件设置,不可生成不在表字段列表中的查询条件,不可生成任何不在表字段中的条件,比如周边5公里有什么设施
+        注意9: 生成sql时,必须使用 st_astext(st_centroid(shape)) as center_wkt 
+        注意10: 查询语句必须包含 objectid, xzqmc, xzqdm, dymc, yddm, ydxz, ydmj, rjlsx, rjlxx, jzmdsx, jzmdxx, jzgdsx, jzgdxx, ldlsx, ldlxx, pfwh, pfsj st_astext(shape) as geom, st_astext(st_centroid(shape)) as center_wkt 这几个字段
+        注意11: 只准生成查询 的sql 语句,不可生成任何 修改数据的语句, 比如:update, delete, insert, truncate 等
+        注意12:当用户问题中的土地用途是"工业用地"时,去掉"用地",使用ydxz进行模糊查询,比如ydxz like '%工业%'
         """
         self.retriever = SqlRetriever(query_type='land_site_selection')
 

+ 4 - 6
aiAgent_gd/qwen_agent/sub_agent/summary_agent.py

@@ -40,19 +40,17 @@ agents_prompt = dict({
     
     必须按照markdown格式输出的地块信息。以下是输出信息的参考,请将<>替换成真实的内容:
     
-         ### 1.地块名称
+         ### 1.<地块名称>
     
           - **行政区**: 
-          - **规划用途**: 
+          - **土地用途**: 
           - **用地面积**: 
-          - **土地坐落**:
                 
-        ### 2.<地块2名称>
+        ### 2.<地块名称>
         
           - **行政区**: 
-          - **规划用途**: 
+          - **土地用途**: 
           - **用地面积**: 
-          - **土地坐落**: 
     
     
      下面是输出时的注意事项: