Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
LAE
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
文靖昊
LAE
Commits
031dfa1e
Commit
031dfa1e
authored
Nov 27, 2024
by
tinywell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1设备传感器数量查询接口接入;问题类型识别参数说明优化;工具返回数据结构精简
parent
a086b59c
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
164 additions
and
39 deletions
+164
-39
http_tools.py
src/agent/http_tools.py
+1
-1
tool_monitor.py
src/agent/tool_monitor.py
+111
-23
tool_rate.py
src/agent/tool_rate.py
+28
-4
api.py
src/controller/api.py
+1
-1
run_tool_picker_monitor.py
test/run_tool_picker_monitor.py
+16
-6
run_tool_picker_warn.py
test/run_tool_picker_warn.py
+7
-4
No files found.
src/agent/http_tools.py
View file @
031dfa1e
...
@@ -161,7 +161,7 @@ class MonitorClient(BaseHttpClient):
...
@@ -161,7 +161,7 @@ class MonitorClient(BaseHttpClient):
"deviceType"
:
device_type
"deviceType"
:
device_type
}
}
)
)
return
BaseResponse
[
Lis
t
](
**
data
)
return
BaseResponse
[
Dic
t
](
**
data
)
# 示例:添加新的数据接口客户端
# 示例:添加新的数据接口客户端
class
RateClient
(
BaseHttpClient
):
class
RateClient
(
BaseHttpClient
):
...
...
src/agent/tool_monitor.py
View file @
031dfa1e
...
@@ -5,7 +5,9 @@ from langchain_core.tools import BaseTool
...
@@ -5,7 +5,9 @@ from langchain_core.tools import BaseTool
from
.http_tools
import
MonitorClient
,
RateClient
from
.http_tools
import
MonitorClient
,
RateClient
from
typing
import
Type
from
typing
import
Type
from
..utils.logger
import
get_logger
from
..utils.logger
import
get_logger
from
.code
import
AreaCodeTool
code_tool
=
AreaCodeTool
()
class
MonitorPointResponse
():
class
MonitorPointResponse
():
"""监测点查询结果"""
"""监测点查询结果"""
status
:
str
=
Field
(
...
,
description
=
"状态"
)
status
:
str
=
Field
(
...
,
description
=
"状态"
)
...
@@ -15,15 +17,17 @@ class MonitorPointResponse():
...
@@ -15,15 +17,17 @@ class MonitorPointResponse():
class
MonitorPointArgs
(
BaseModel
):
class
MonitorPointArgs
(
BaseModel
):
"""监测点查询参数"""
"""监测点查询参数"""
key
:
str
=
Field
(
...
,
description
=
"行政区划名称(省/市级别均可,只需要最后一级,如长沙市,不需要湖南省)"
)
key
:
str
=
Field
(
...
,
description
=
"行政区划名称(省/市级别均可,只需要最后一级,如长沙市,不需要湖南省)"
)
year
:
str
=
Field
(
""
,
description
=
"年份,未提及则为空"
)
start_time
:
str
=
Field
(
""
,
description
=
"可选参数:仅当需要查询特定时间区间的监测点数据时才需要指定,默认为空"
)
disaster_type
:
str
=
Field
(
""
,
description
=
"灾害类型,如崩塌、滑坡、泥石流、地面塌陷、地面沉降、地裂缝等,未提及则为空"
)
end_time
:
str
=
Field
(
""
,
description
=
"可选参数:仅当需要查询特定时间区间的监测点数据时才需要指定,默认为空"
)
disaster_type
:
str
=
Field
(
""
,
description
=
"需要查询的灾害类型,如崩塌、滑坡、泥石流、地面塌陷、地面沉降、地裂缝等,默认为空"
)
three_d_model
:
str
=
Field
(
""
,
description
=
"是否需要三维模型,需要为有,不需要为无,默认为空"
)
three_d_model
:
str
=
Field
(
""
,
description
=
"是否需要三维模型,需要为有,不需要为无,默认为空"
)
ortho_image
:
str
=
Field
(
""
,
description
=
"是否需要正射影像,需要为有,不需要为无,默认为空"
)
ortho_image
:
str
=
Field
(
""
,
description
=
"是否需要正射影像,需要为有,不需要为无,默认为空"
)
disaster_threat_people_range_start
:
str
=
Field
(
""
,
description
=
"灾害威胁人数范围起始值,如100,未提及则为空"
)
disaster_threat_people_range_start
:
str
=
Field
(
""
,
description
=
"灾害威胁人数范围起始值,如100,默认为空"
)
disaster_threat_people_range_end
:
str
=
Field
(
""
,
description
=
"灾害威胁人数范围结束值,如200,未提及则为空"
)
disaster_threat_people_range_end
:
str
=
Field
(
""
,
description
=
"灾害威胁人数范围结束值,如200,默认为空"
)
disaster_scale_start
:
str
=
Field
(
""
,
description
=
"灾害规模范围起始值,灾害为崩塌、滑坡、泥石流时表示体积,灾害为地面塌陷、地面沉降时表示面积,为地裂缝时表示长度,未提及则为空"
)
disaster_scale_start
:
str
=
Field
(
""
,
description
=
"灾害规模范围起始值,灾害为崩塌、滑坡、泥石流时表示体积,灾害为地面塌陷、地面沉降时表示面积,为地裂缝时表示长度,默认为空"
)
disaster_scale_end
:
str
=
Field
(
""
,
description
=
"灾害规模范围结束值,灾害为崩塌、滑坡、泥石流时表示体积,灾害为地面塌陷、地面沉降时表示面积,为地裂缝时表示长度,未提及则为空"
)
disaster_scale_end
:
str
=
Field
(
""
,
description
=
"灾害规模范围结束值,灾害为崩塌、滑坡、泥石流时表示体积,灾害为地面塌陷、地面沉降时表示面积,为地裂缝时表示长度,默认为空"
)
device_type
:
str
=
Field
(
""
,
description
=
"设备类型(例如 加速度、位移、温度、湿度、裂缝计等),默认为空"
)
device_type
:
str
=
Field
(
""
,
description
=
"设备类型或者传感器类型,当查询设备或传感器信息时需要(例如 加速度、位移、温度、湿度、裂缝计、雨量等),默认为空"
)
class
MonitorPointTool
(
BaseTool
):
class
MonitorPointTool
(
BaseTool
):
"""查询监测点信息的工具"""
"""查询监测点信息的工具"""
...
@@ -32,7 +36,7 @@ class MonitorPointTool(BaseTool):
...
@@ -32,7 +36,7 @@ class MonitorPointTool(BaseTool):
可以查询任意省/市/区县级别的监测点数据,也可以通过灾害类型、灾害规模、灾害威胁人数范围、设备类型等条件查询。
可以查询任意省/市/区县级别的监测点数据,也可以通过灾害类型、灾害规模、灾害威胁人数范围、设备类型等条件查询。
输入参数为行政区划名称,如:湖南省、长沙市、岳麓区等。
输入参数为行政区划名称,如:湖南省、长沙市、岳麓区等。
返回该区域内的监测点列表,包含位置、经纬度等详细信息。
返回该区域内的监测点列表,包含位置、经纬度等详细信息。
还可以查询监测点下相关监测设备
信息,比如设备
数量等。
还可以查询监测点下相关监测设备
、传感器信息,比如设备数量、传感器
数量等。
"""
"""
args_schema
:
Type
[
BaseModel
]
=
MonitorPointArgs
args_schema
:
Type
[
BaseModel
]
=
MonitorPointArgs
client
:
Any
=
Field
(
None
,
exclude
=
True
)
client
:
Any
=
Field
(
None
,
exclude
=
True
)
...
@@ -50,16 +54,18 @@ class MonitorPointTool(BaseTool):
...
@@ -50,16 +54,18 @@ class MonitorPointTool(BaseTool):
self
.
client
=
MonitorClient
(
base_url
=
base_url
)
self
.
client
=
MonitorClient
(
base_url
=
base_url
)
self
.
logger
=
get_logger
(
"MonitorPointTool"
)
self
.
logger
=
get_logger
(
"MonitorPointTool"
)
def
_run
(
self
,
key
:
str
,
year
:
str
=
""
,
disaster_type
:
str
=
""
,
def
_run
(
self
,
key
:
str
,
start_time
:
str
=
""
,
end_time
:
str
=
""
,
disaster_type
:
str
=
""
,
three_d_model
:
str
=
""
,
ortho_image
:
str
=
""
,
three_d_model
:
str
=
""
,
ortho_image
:
str
=
""
,
disaster_threat_people_range_start
:
str
=
""
,
disaster_threat_people_range_end
:
str
=
""
,
disaster_threat_people_range_start
:
str
=
""
,
disaster_threat_people_range_end
:
str
=
""
,
disaster_scale_start
:
str
=
""
,
disaster_scale_end
:
str
=
""
,
device_type
:
str
=
""
)
->
Dict
[
str
,
Any
]:
disaster_scale_start
:
str
=
""
,
disaster_scale_end
:
str
=
""
,
device_type
:
str
=
""
,
query_type
:
str
=
"points"
)
->
Dict
[
str
,
Any
]:
"""
"""
执行监测点查询
执行监测点查询
Args:
Args:
key: 行政区划名称
key: 行政区划名称
year: 年份
start_time: 开始时间
end_time: 结束时间
disaster_type: 灾害类型
disaster_type: 灾害类型
three_d_model: 是否需要三维模型
three_d_model: 是否需要三维模型
ortho_image: 是否需要正射影像
ortho_image: 是否需要正射影像
...
@@ -67,23 +73,97 @@ class MonitorPointTool(BaseTool):
...
@@ -67,23 +73,97 @@ class MonitorPointTool(BaseTool):
disaster_threat_people_range_end: 灾害威胁人数范围结束值
disaster_threat_people_range_end: 灾害威胁人数范围结束值
disaster_scale_start: 灾害规模范围起始值
disaster_scale_start: 灾害规模范围起始值
disaster_scale_end: 灾害规模范围结束值
disaster_scale_end: 灾害规模范围结束值
device_required: 是否需要设备相关信息
device_type: 设备类型
device_type: 设备类型
query_type: 查询类型
Returns:
Returns:
Dict: 包含查询结果的字典
Dict: 包含查询结果的字典
"""
"""
if
len
(
device_type
)
>
0
:
query_type
=
"2"
if
query_type
==
"2"
:
return
self
.
_get_device_info
(
key
,
start_time
,
end_time
,
device_type
)
else
:
year
=
start_time
.
split
(
"-"
)[
0
]
return
self
.
_get_points_info
(
key
,
year
,
disaster_type
,
three_d_model
,
ortho_image
,
disaster_threat_people_range_start
,
disaster_threat_people_range_end
,
disaster_scale_start
,
disaster_scale_end
,
device_type
)
def
_get_device_info
(
self
,
key
:
str
,
start_time
:
str
=
""
,
end_time
:
str
=
""
,
device_type
:
str
=
""
):
self
.
logger
.
info
(
f
"开始查询设备信息,区域: {key}"
)
code
=
""
if
key
!=
""
:
self
.
logger
.
debug
(
f
"查找区域代码: {key}"
)
codes
=
code_tool
.
find_code
(
key
)
if
codes
is
None
or
len
(
codes
)
==
0
:
error_msg
=
f
'未找到匹配的区域代码: {key}'
self
.
logger
.
warning
(
error_msg
)
return
{
'code'
:
400
,
'message'
:
error_msg
}
code
=
codes
[
0
][
1
]
self
.
logger
.
debug
(
f
"找到区域代码: {code}"
)
try
:
response
=
self
.
client
.
query_device_and_sensor
(
code
,
start_time
,
end_time
,
device_type
)
self
.
logger
.
debug
(
f
"API响应: {response}"
)
if
response
.
type
!=
1
or
len
(
response
.
resultdata
)
==
0
:
error_msg
=
f
"查询失败: {response.message},请检查是否有相关数据权限"
self
.
logger
.
warning
(
error_msg
)
return
{
'code'
:
400
,
'message'
:
error_msg
}
self
.
logger
.
info
(
f
"查询设备信息成功,设备数量: {len(response.resultdata['DeviceList'])}"
)
devices_info
=
[]
for
device
in
response
.
resultdata
[
"DeviceList"
]:
devices_info
.
append
({
"设备编号"
:
device
[
"DEVICECODE"
],
"设备名称"
:
device
[
"DEVICETYPENAME"
],
# "GUID": device["GUID"]
})
self
.
logger
.
debug
(
f
"处理设备数据: {devices_info}"
)
sensors_info
=
[]
for
sensor
in
response
.
resultdata
[
"SensorList"
]:
sensors_info
.
append
({
"传感器编号"
:
sensor
[
"SENSORCODE"
],
"传感器名称"
:
sensor
[
"DEVICETYPENAME"
],
# "GUID": sensor["GUID"]
})
self
.
logger
.
debug
(
f
"处理传感器数据: {sensors_info}"
)
device_table_header
=
list
(
devices_info
[
0
]
.
keys
())
device_table_data
=
[]
for
item
in
devices_info
:
device_table_data
.
append
(
list
(
item
.
values
()))
sensor_table_header
=
list
(
sensors_info
[
0
]
.
keys
())
sensor_table_data
=
[]
for
item
in
sensors_info
:
sensor_table_data
.
append
(
list
(
item
.
values
()))
result
=
{
'code'
:
200
,
'message'
:
f
"在{key}找到{len(devices_info)}个设备信息, {len(sensors_info)}个传感器信息"
,
# 'devices': {
# 'table_header': device_table_header,
# 'table_data': device_table_data
# },
# 'sensors': {
# 'table_header': sensor_table_header,
# 'table_data': sensor_table_data
# }
}
return
result
except
Exception
as
e
:
error_msg
=
f
"查询失败: {str(e)}"
self
.
logger
.
error
(
error_msg
,
exc_info
=
True
)
return
{
'code'
:
400
,
'message'
:
error_msg
}
def
_get_points_info
(
self
,
key
:
str
,
year
:
str
=
""
,
disaster_type
:
str
=
""
,
three_d_model
:
str
=
""
,
ortho_image
:
str
=
""
,
disaster_threat_people_range_start
:
str
=
""
,
disaster_threat_people_range_end
:
str
=
""
,
disaster_scale_start
:
str
=
""
,
disaster_scale_end
:
str
=
""
,
device_type
:
str
=
""
):
try
:
try
:
self
.
logger
.
info
(
f
"开始查询监测点信息,区域: {key}"
)
self
.
logger
.
info
(
f
"开始查询监测点信息,区域: {key}"
)
# code = ""
# if key != "":
# self.logger.debug(f"查找区域代码: {key}")
# codes = code_tool.find_code(key)
# if codes is None or len(codes) == 0:
# error_msg = f'未找到匹配的区域代码: {key}'
# self.logger.warning(error_msg)
# return {'code': 400, 'message': error_msg}
# code = codes[0][1]
# self.logger.debug(f"找到区域代码: {code}")
response
=
self
.
client
.
query_points_sync
(
key
,
year
,
response
=
self
.
client
.
query_points_sync
(
key
,
year
,
disaster_type
,
three_d_model
,
ortho_image
,
disaster_type
,
three_d_model
,
ortho_image
,
...
@@ -130,10 +210,18 @@ class MonitorPointTool(BaseTool):
...
@@ -130,10 +210,18 @@ class MonitorPointTool(BaseTool):
self
.
logger
.
info
(
f
"成功获取 {len(points_info)} 个监测点数据"
)
self
.
logger
.
info
(
f
"成功获取 {len(points_info)} 个监测点数据"
)
# markdown = self.to_markdown(points_info)
# markdown = self.to_markdown(points_info)
table_header
=
list
(
points_info
[
0
]
.
keys
())
table_data
=
[]
for
item
in
points_info
:
table_data
.
append
(
list
(
item
.
values
()))
result
=
{
result
=
{
'code'
:
200
,
'code'
:
200
,
'message'
:
f
"在{key}找到{len(points_info)}个监测点信息"
,
'message'
:
f
"在{key}找到{len(points_info)}个监测点信息"
,
'points'
:
points_info
,
'points'
:
{
'table_header'
:
table_header
,
'table_data'
:
table_data
},
# 'markdown': markdown
# 'markdown': markdown
}
}
self
.
logger
.
info
(
"数据处理完成,返回结果"
)
self
.
logger
.
info
(
"数据处理完成,返回结果"
)
...
...
src/agent/tool_rate.py
View file @
031dfa1e
...
@@ -124,11 +124,25 @@ class RegionRateTool(BaseRateTool):
...
@@ -124,11 +124,25 @@ class RegionRateTool(BaseRateTool):
for
item
in
df
.
resultdata
:
for
item
in
df
.
resultdata
:
rate_date
=
self
.
_extract_rate_data
(
item
)
rate_date
=
self
.
_extract_rate_data
(
item
)
result_data
.
append
(
rate_date
)
result_data
.
append
(
rate_date
)
sorted_data
=
[
rate_date
[
0
]]
if
len
(
result_data
)
>
1
:
sorted_data
.
extend
(
sorted
(
result_data
[
1
:],
key
=
lambda
x
:
x
[
'在线率'
]))
# 将数据改成表格形式,表头提取之后,数据一行行显示
table_header
=
list
(
result_data
[
0
]
.
keys
())
table_data
=
[]
for
item
in
result_data
:
table_data
.
append
(
list
(
item
.
values
()))
result_data
=
{
'table_header'
:
table_header
,
'table_data'
:
table_data
}
data
=
{
data
=
{
'region'
:
region_name
,
'region'
:
region_name
,
'region_code'
:
code
,
'region_code'
:
code
,
'rate_data'
:
result_data
,
'rate_data'
:
result_data
,
}
}
total_time
=
time
.
time
()
-
agent_start
total_time
=
time
.
time
()
-
agent_start
...
@@ -160,6 +174,16 @@ class RegionRateTool(BaseRateTool):
...
@@ -160,6 +174,16 @@ class RegionRateTool(BaseRateTool):
self
.
logger
.
debug
(
f
"查询结果: {df.resultdata}"
)
self
.
logger
.
debug
(
f
"查询结果: {df.resultdata}"
)
# markdown = self.to_markdown(df.resultdata)
# markdown = self.to_markdown(df.resultdata)
table_header
=
list
(
result_data
[
0
]
.
keys
())
table_data
=
[]
for
item
in
result_data
:
table_data
.
append
(
list
(
item
.
values
()))
result_data
=
{
'table_header'
:
table_header
,
'table_data'
:
table_data
}
data
=
{
data
=
{
'region'
:
region_name
,
'region'
:
region_name
,
...
...
src/controller/api.py
View file @
031dfa1e
...
@@ -26,7 +26,7 @@ DEFAULT_CONFIG = {
...
@@ -26,7 +26,7 @@ DEFAULT_CONFIG = {
"API_BASE"
:
"http://192.168.10.14:8000/v1"
,
"API_BASE"
:
"http://192.168.10.14:8000/v1"
,
"TOOL_BASE_URL"
:
"http://localhost:5001"
,
"TOOL_BASE_URL"
:
"http://localhost:5001"
,
"API_KEY"
:
"xxxxxxxxxxxxx"
,
"API_KEY"
:
"xxxxxxxxxxxxx"
,
"LOG_LEVEL"
:
"
DEBUG
"
"LOG_LEVEL"
:
"
INFO
"
}
}
def
get_config
(
key
:
str
,
args
:
Optional
[
argparse
.
Namespace
]
=
None
)
->
str
:
def
get_config
(
key
:
str
,
args
:
Optional
[
argparse
.
Namespace
]
=
None
)
->
str
:
...
...
test/run_tool_picker_monitor.py
View file @
031dfa1e
...
@@ -80,10 +80,20 @@ def run_examples():
...
@@ -80,10 +80,20 @@ def run_examples():
"expected"
:
{
"expected"
:
{
"tool"
:
"monitor_points_query"
,
"tool"
:
"monitor_points_query"
,
"params"
:
{
"params"
:
{
"key"
:
"甘肃省
陇南市
"
"key"
:
"甘肃省"
}
}
}
}
},
},{
"query"
:
"贵阳市的雨量传感器有多少"
,
"expected"
:
{
"tool"
:
"monitor_points_query"
,
"params"
:
{
"key"
:
"贵阳市"
,
"device_type"
:
"雨量"
,
"query_type"
:
"2"
,
}
}
}
]
]
# 为每个测试案例创建一个表格
# 为每个测试案例创建一个表格
...
@@ -120,10 +130,10 @@ def run_examples():
...
@@ -120,10 +130,10 @@ def run_examples():
"✓"
if
expected_value
==
actual_value
else
"✗"
"✓"
if
expected_value
==
actual_value
else
"✗"
)
)
# run tool
#
#
run tool
tool
=
tools_dict
[
actual_tool
]
#
tool = tools_dict[actual_tool]
result
=
tool
.
invoke
(
result
[
"params"
])
#
result = tool.invoke(result["params"])
print
(
result
)
#
print(result)
except
Exception
as
e
:
except
Exception
as
e
:
table
.
add_row
(
"错误"
,
""
,
str
(
e
),
"✗"
)
table
.
add_row
(
"错误"
,
""
,
str
(
e
),
"✗"
)
...
...
test/run_tool_picker_warn.py
View file @
031dfa1e
...
@@ -44,6 +44,7 @@ def run_examples():
...
@@ -44,6 +44,7 @@ def run_examples():
"start_time"
:
"2024-04-01 00:00:00"
,
"start_time"
:
"2024-04-01 00:00:00"
,
"end_time"
:
"2024-05-31 23:59:59"
,
"end_time"
:
"2024-05-31 23:59:59"
,
"region_name"
:
"甘肃省"
,
"region_name"
:
"甘肃省"
,
"query_type"
:
"1"
,
}
}
}
}
},{
},{
...
@@ -64,6 +65,7 @@ def run_examples():
...
@@ -64,6 +65,7 @@ def run_examples():
"start_time"
:
"2024-01-01 00:00:00"
,
"start_time"
:
"2024-01-01 00:00:00"
,
"end_time"
:
"2024-12-31 23:59:59"
,
"end_time"
:
"2024-12-31 23:59:59"
,
"region_name"
:
"甘肃省"
,
"region_name"
:
"甘肃省"
,
"query_type"
:
"2"
,
}
}
}
}
},{
},{
...
@@ -74,6 +76,7 @@ def run_examples():
...
@@ -74,6 +76,7 @@ def run_examples():
"start_time"
:
"2024-01-01 00:00:00"
,
"start_time"
:
"2024-01-01 00:00:00"
,
"end_time"
:
"2024-06-30 23:59:59"
,
"end_time"
:
"2024-06-30 23:59:59"
,
"region_name"
:
"甘肃省"
,
"region_name"
:
"甘肃省"
,
"query_type"
:
"1"
,
}
}
}
}
}
}
...
@@ -113,11 +116,11 @@ def run_examples():
...
@@ -113,11 +116,11 @@ def run_examples():
"✓"
if
expected_value
==
actual_value
else
"✗"
"✓"
if
expected_value
==
actual_value
else
"✗"
)
)
tool
=
tool_dict
[
result
[
"tool"
]]
#
tool = tool_dict[result["tool"]]
params
=
result
[
"params"
]
#
params = result["params"]
result
=
tool
.
invoke
(
params
)
#
result = tool.invoke(params)
print
(
result
)
#
print(result)
except
Exception
as
e
:
except
Exception
as
e
:
table
.
add_row
(
"错误"
,
""
,
str
(
e
),
"✗"
)
table
.
add_row
(
"错误"
,
""
,
str
(
e
),
"✗"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment