Compare commits

...

10 Commits

Author SHA1 Message Date
ly a6166b18b7 修改提示词 2025-04-10 11:45:20 +08:00
ly 1428c12b9e 增加人称指代 2025-04-10 09:37:56 +08:00
ly 002df6df38 修改上下文状态 2025-04-10 09:35:49 +08:00
ly c252fe5ef7 更新 2025-04-10 09:22:45 +08:00
ly d967f4fa58 提交数据 2025-04-10 08:30:13 +08:00
ly 7be91a21d4 最后修改提示词。 2025-04-10 08:23:18 +08:00
ly 6356f53ef7 完善整个示例,并增加查询测试模式 2025-04-10 07:18:52 +08:00
ly 211db332c0 半成品,为了保存记录,请勿使用。 2025-04-09 20:44:26 +08:00
ly b6b697efdb 修改知识库范围 2025-04-09 14:21:18 +08:00
ly 0ddf56a52a 修改环境配置支持公司大模型配置 2025-04-08 15:16:15 +08:00
11 changed files with 2993 additions and 133 deletions
+13 -13
View File
@@ -2,22 +2,22 @@
# DB_URL=postgresql+psycopg://ai:ai@localhost:5532/ai
# OpenAI API配置
API_KEY=sk-oftybjqntjpxlhkcxkieluljb
EMBEDDING_MODEL=BAAI/bge-large-zh-v1.5
EMBEDDING_BASE_URL=https://api.siliconflow.cn/v1
MODEL_LIST=Qwen2.5-72B=openai:Qwen/Qwen2.5-72B-Instruct&gpt-4o=openai:gpt-4o
# 模型配置
MODEL_BASE_URL=https://api.siliconflow.cn/v1
API_KEY=sk-oftybjqntjpxlhkc
EMBEDDING_MODEL=bge-m3
EMBEDDING_BASE_URL=http://10.1.16.39:9995/v1
MODEL_LIST=Qwen2.5-72B=openai:Qwen2.5-72B-Instruct-GPTQ-Int8
MODEL_BASE_URL=http://172.20.0.145:9995/v1
# 文件路径配置
KNOWLEDGE_SOURCE_DIR=data
MEMORY_DB_FILE=tmp/agent_memory.db
VECTOR_DB_PATH=tmp/lancedb
SESSION_STORAGE_PATH=tmp/agent_sessions_json
MINGCI_KNOWLEDGE_SOURCE_DIR=data/业务名词库
MINGCI_VECTOR_DB_PATH=tmp/mingcidb
# 知识库加载控制
LOAD_KNOWLEDGE=true
KNOWLEDGE_SOURCE_DIR=data/控件布局
VECTOR_DB_PATH=tmp/knowledgedb
MEMORY_DB_FILE=tmp/agent_memory.db
SESSION_STORAGE_PATH=tmp/agent_sessions_json
AGNO_MONITOR=true
AGNO_TELEMETRY=true
-1
View File
@@ -6,7 +6,6 @@
.vscode
__pycache__
wiki_doc.json
Data/
**/node_modules/**
.DS_Store
+983
View File
@@ -0,0 +1,983 @@
[
{
"name": "博微配网工程计价通D3",
"synonymous": ["配网D3", "配网软件D3", "D3", "软件D3", "配网软件", "配网计价通D3", "配网计价通D3"],
"description": ""
},
{
"name": "资源管理",
"synonymous": [],
"description": "资源管理-定额库新增技改跨越定额"
}
,
{
"name": "取费表",
"synonymous": [],
"description": ""
},
{
"name": "取费表费用项",
"synonymous": ["子项", "费用项"],
"description": ""
},
{
"name": "工程属性",
"synonymous": ["工程参数","计算参数"],
"description": ""
},
{
"name": "工程量",
"synonymous": [],
"description": ""
},
{
"name": "定额",
"synonymous": [],
"description": ""
},
{
"name": "主材",
"synonymous": [],
"description": ""
},
{
"name": "设备",
"synonymous": [],
"description": ""
},
{
"name": "人材机",
"synonymous": ["材机"],
"description": ""
},
{
"name": "人工",
"synonymous": [],
"description": ""
},
{
"name": "机械",
"synonymous": [],
"description": ""
},
{
"name": "材料",
"synonymous": [],
"description": ""
},
{
"name": "项目划分",
"synonymous": [],
"description": ""
},
{
"name": "物料库",
"synonymous": [],
"description": "物料数据通过导入excel至自定义物料库,需支持导入模板中的“价格来源”、“备注”列数据。"
},
{
"name": "定额库",
"synonymous": [],
"description": "替换修订后的定额库。"
},
{
"name": "人材机库",
"synonymous": [],
"description": "按照新定额,建筑册的混凝土作为拆分材机,2021定额材机库中展示该部分混凝土材机,故对人材机库、定额库等进行适配"
},
{
"name": "清单库",
"synonymous": [],
"description": "调整辽宁清单库增加项目特征值下拉配置。"
},
{
"name": "组合件库",
"synonymous": [],
"description": "描述D3软件组合件库的实现。"
},
{
"name": "搜问题",
"synonymous": [],
"description": "描述D3软件链接到服务大厅知识库的实现。"
},
{
"name": "在线客服",
"synonymous": [],
"description": "描述D3软件链接到客服中心的实现。"
},
{
"name": "智电课堂",
"synonymous": [],
"description": "描述D3软件链接到智电课堂的实现。"
},
{
"name": "多工程批量调价",
"synonymous": [],
"description": "主页新增<多工程批量调价>按钮,支持将一批工程导入后,进行一键调价的设置。"
},
{
"name": "导入设计接口-创建单个工程",
"synonymous": [],
"description": "描述D3软件导入设计接口创建单个工程的实现。"
},
{
"name": "导入设计接口-拆分专业创建多个工程",
"synonymous": [],
"description": "描述D3软件导入设计接口创建多个工程的实现。"
},
{
"name": "费用统计",
"synonymous": [],
"description": "描述D3软件费用统计的实现。"
},
{
"name": "物料统计",
"synonymous": [],
"description": "描述D3软件费用统计的实现。"
},
{
"name": "费用及物料统计",
"synonymous": [],
"description": "描述D3软件费用统计的实现。"
},
{
"name": "统计分析",
"synonymous": [],
"description": "增加批量设置小数位数对统计分析新增表的控制"
},
{
"name": "多工程批量设置",
"synonymous": [],
"description": "描述D3软件多工程批量设置功能的实现。"
},
{
"name": "其中:建设场地征用及清理费",
"synonymous": [],
"description": "增加“其中:建场征用及清理费”界面设置。"
},
{
"name": "多工程建筑材机设置",
"synonymous": [],
"description": "描述D3软件多工程建筑材机设置功能的实现。"
},
{
"name": "多工程报表导出",
"synonymous": [],
"description": "描述D3软件多工程报表导出功能的实现。"
},
{
"name": "工程量合并",
"synonymous": [],
"description": "描述D3软件工程量合并功能的实现。"
},
{
"name": "一般计税转简易计税",
"synonymous": [],
"description": "描述D3软件一般计税转简易计税功能的实现。"
},
{
"name": "老版定额升级",
"synonymous": [],
"description": "描述D3软件老版定额升级功能的实现。"
},
{
"name": "工程转换",
"synonymous": [],
"description": "优化建筑工程定额自动挂载清单规则。"
},
{
"name": "设置选项",
"synonymous": [],
"description": "设置选项新增“切换到报表界面是否自动统计工程量”相关设置选项,控制单工程切换到报表输出界面时是否自动统计工程量。"
},
{
"name": "物料库下载",
"synonymous": [],
"description": "描述D3软件物料库下载功能的实现。"
},
{
"name": "云物料录入",
"synonymous": [],
"description": "描述D3软件云物料录入功能的实现。"
},
{
"name": "物料询价/物料批量询价",
"synonymous": [],
"description": "描述D3软件物料库下载功能的实现。"
},
{
"name": "云文件管理",
"synonymous": [],
"description": "描述D3软件云文件管理功能的实现。"
},
{
"name": "云工程备份",
"synonymous": [],
"description": "描述D3软件云工程备份功能的实现。"
},
{
"name": "邮件分享/链接分享",
"synonymous": [],
"description": "描述D3软件邮件分享/链接分享功能的实现。"
},
{
"name": "云推送",
"synonymous": [],
"description": "区分地区插件类型进行资源(调差系数、信息价格库、清单库、定额库)精准推送"
},
{
"name": "新建工程",
"synonymous": [],
"description": "描述D3软件新建工程功能的实现。"
},
{
"name": "打开工程",
"synonymous": [],
"description": "描述D3软件打开工程功能的实现。"
},
{
"name": "备份管理",
"synonymous": [],
"description": "描述D3软件备份管理功能的实现。"
},
{
"name": "最近打开列表",
"synonymous": [],
"description": "描述D3软件最近打开列表功能的实现。"
},
{
"name": "例子工程列表",
"synonymous": [],
"description": "按照新定额配置配电站、架空线路例子工程"
},
{
"name": "导出到单个excel",
"synonymous": [],
"description": "《招标汇总表》其中安全文明施工出值增加拆除安全文明施工费"
},
{
"name": "编辑",
"synonymous": [],
"description": "描述D3软件报表参数功能的实现。"
},
{
"name": "云端备份",
"synonymous": [],
"description": "云端备份集成企业云登录。"
},
{
"name": "设置密码",
"synonymous": [],
"description": "描述D3软件设置密码功能的实现。"
},
{
"name": "更新土质",
"synonymous": [],
"description": "描述D3软件更新土质功能的实现。"
},
{
"name": "运输设置",
"synonymous": [],
"description": "描述D3软件运输设置功能的实现。"
},
{
"name": "地形相关",
"synonymous": [],
"description": "描述D3软件地形相关功能的实现。"
},
{
"name": "边坡系数",
"synonymous": [],
"description": "描述D3软件边坡系数功能的实现。"
},
{
"name": "土质说明",
"synonymous": [],
"description": "描述D3软件土质说明功能的实现。"
},
{
"name": "估算指标",
"synonymous": [],
"description": "描述D3软件估算指标功能的实现。"
},
{
"name": "价差文件",
"synonymous": [],
"description": "描述D3软件价差文件功能的实现。"
},
{
"name": "导出模板/参数",
"synonymous": [],
"description": "描述D3软件导出模板/参数功能的实现。"
},
{
"name": "导入模板/参数",
"synonymous": [],
"description": "描述D3软件导入模板/参数功能的实现。"
},
{
"name": "统计说明",
"synonymous": [],
"description": "描述D3软件统计说明功能的实现。"
},
{
"name": "统计规模参数",
"synonymous": [],
"description": "描述D3软件统计规模参数功能的实现。"
},
{
"name": "统计技经指标",
"synonymous": [],
"description": "描述D3软件统计技经指标功能的实现。"
},
{
"name": "工程体检",
"synonymous": [],
"description": "描述D3软件工程体检功能的实现。"
},
{
"name": "清空新建时间",
"synonymous": [],
"description": "描述D3软件清空新建时间功能的实现。"
},
{
"name": "工程审核",
"synonymous": [],
"description": "描述D3软件工程审核功能的实现。"
},
{
"name": "设为审前数据",
"synonymous": [],
"description": "描述D3软件设为审前数据功能的实现。"
},
{
"name": "取费表列表展现",
"synonymous": [],
"description": "描述D3软件取费表列表展现功能的实现。"
},
{
"name": "添加",
"synonymous": [],
"description": "描述D3软件添加取费表功能的实现。"
},
{
"name": "删除",
"synonymous": [],
"description": "描述D3软件删除取费表功能的实现。"
},
{
"name": "修改计算式",
"synonymous": [],
"description": "取费设置界面增加甲供物料含税,不含税变量"
},
{
"name": "取费表模板展现",
"synonymous": [],
"description": "描述D3软件取费表模板展现功能的实现。"
},
{
"name": "添加子级",
"synonymous": [],
"description": "描述D3软件添加子级费用项功能的实现。"
},
{
"name": "修改费率",
"synonymous": [],
"description": "描述D3软件修改取费表模板费率功能的实现。"
},
{
"name": "剪切",
"synonymous": [],
"description": "描述D3软件取费表模板剪切功能的实现。"
},
{
"name": "复制",
"synonymous": [],
"description": "描述D3软件取费表模板复制功能的实现。"
},
{
"name": "粘贴",
"synonymous": [],
"description": "描述D3软件取费表模板粘贴功能的实现。"
},
{
"name": "位置移动",
"synonymous": [],
"description": "描述D3软件移动费用项位置功能的实现。"
},
{
"name": "层级移动",
"synonymous": [],
"description": "描述D3软件移动费用项层级功能的实现。"
},
{
"name": "查询预规",
"synonymous": [],
"description": "描述D3软件查询预规功能的实现。"
},
{
"name": "导入取费表模板",
"synonymous": [],
"description": "描述D3软件导入取费表模板功能的实现。"
},
{
"name": "导出取费表模板",
"synonymous": [],
"description": "描述D3软件导出取费表模板功能的实现。"
},
{
"name": "导出工程量清单",
"synonymous": [],
"description": "调整导出工程量清单功能规则,增加过滤非工程量清单的数据"
},
{
"name": "复用清单组价",
"synonymous": [],
"description": "描述D3软件复用清单组价功能的实现。"
},
{
"name": "组合件展示",
"synonymous": [],
"description": "描述D3软件组合件展示功能的实现。"
},
{
"name": "恢复原定额",
"synonymous": [],
"description": "描述D3软件恢复原定额功能的实现。"
},
{
"name": "批量设置所属项目",
"synonymous": [],
"description": "描述D3软件批量设置所属项目功能的实现。"
},
{
"name": "取消关联父级量",
"synonymous": [],
"description": "描述D3软件取消关联父级量功能的实现。"
},
{
"name": "设置关联父级量",
"synonymous": [],
"description": "描述D3软件设置关联父级量功能的实现。"
},
{
"name": "合并相同消耗量",
"synonymous": [],
"description": "描述D3软件合并相同消耗量功能的实现。"
},
{
"name": "清空数量",
"synonymous": [],
"description": "描述D3软件清空数量功能的实现。"
},
{
"name": "清除计算过程",
"synonymous": [],
"description": "描述D3软件清除计算过程功能的实现。"
},
{
"name": "清除统计标记",
"synonymous": [],
"description": "描述D3软件清除统计标记功能的实现。"
},
{
"name": "删除工程量",
"synonymous": [],
"description": "描述D3软件删除工程量功能的实现。"
},
{
"name": "同步定位工程量",
"synonymous": [],
"description": "描述D3软件同步定位工程量功能的实现。"
},
{
"name": "删除批注",
"synonymous": [],
"description": "描述D3软件删除批注功能的实现。"
},
{
"name": "五金计算",
"synonymous": [],
"description": "描述D3软件五金计算功能的实现。"
},
{
"name": "批量设置设计类型",
"synonymous": [],
"description": "描述D3软件批量设置设计类型功能的实现。"
},
{
"name": "添加资源",
"synonymous": [],
"description": "描述D3软件添加资源功能的实现。"
},
{
"name": "主材设备互转",
"synonymous": [],
"description": "描述D3软件主材设备互转功能的实现。"
},
{
"name": "锁定清单属性",
"synonymous": [],
"description": "为避免误操作改动招标清单信息引起废标,需锁定清单的信息,锁定清单后不可编辑清单,但不影响下方工程量的录入"
},
{
"name": "项目划分列表",
"synonymous": [],
"description": "描述D3软件项目划分列表功能的实现。"
},
{
"name": "覆盖粘贴",
"synonymous": [],
"description": "描述D3软件覆盖粘贴功能的实现。"
},
{
"name": "土方列表",
"synonymous": [],
"description": "土方列表中“设置土质比例”窗体中,增加“挖土方式”列设置,支持不同土质时设置不同挖土方式。"
},
{
"name": "合并相同清单",
"synonymous": [],
"description": "清单工程,相同清单且消耗量相同支持合并,增加土方条件。"
},
{
"name": "选择标记颜色",
"synonymous": [],
"description": "描述D3软件选择标记颜色功能的实现。"
},
{
"name": "删除颜色标记",
"synonymous": [],
"description": "描述D3软件删除颜色标记功能的实现。"
},
{
"name": "删除所有颜色",
"synonymous": [],
"description": "描述D3软件删除所有颜色功能的实现。"
},
{
"name": "展现",
"synonymous": [],
"description": "描述D3软件展现组合件、消耗量功能的实现。"
},
{
"name": "展现层级",
"synonymous": [],
"description": "描述D3软件展现层级功能的实现。"
},
{
"name": "录入资源",
"synonymous": [],
"description": "描述D3软件录入资源功能的实现。"
},
{
"name": "导入excel",
"synonymous": [],
"description": "描述D3软件导入excel功能的实现。"
},
{
"name": "粘贴excel",
"synonymous": [],
"description": "描述D3软件粘贴excel功能的实现。"
},
{
"name": "回存资源",
"synonymous": [],
"description": "描述D3软件回存资源功能的实现。"
},
{
"name": "统计钢筋量",
"synonymous": [],
"description": "描述D3软件统计钢筋量功能的实现。"
},
{
"name": "统计运输与土方定额",
"synonymous": [],
"description": "描述D3软件统计运输与土方定额功能的实现。"
},
{
"name": "统计工程量",
"synonymous": [],
"description": "描述D3软件统计工程量功能的实现。"
},
{
"name": "批量设置",
"synonymous": [],
"description": "描述D3软件批量设置功能的实现。"
},
{
"name": "批量替换",
"synonymous": [],
"description": "描述D3软件批量替换功能的实现。"
},
{
"name": "费用预览",
"synonymous": [],
"description": "描述D3软件费用预览功能的实现。"
},
{
"name": "工程小数位数",
"synonymous": [],
"description": "描述D3软件工程小数位数功能的实现。"
},
{
"name": "统计编辑性",
"synonymous": [],
"description": "描述D3软件统计编辑性功能的实现。"
},
{
"name": "配置列",
"synonymous": [],
"description": "描述D3软件配置列功能的实现。"
},
{
"name": "刷新物料",
"synonymous": [],
"description": "描述D3软件刷新物料功能的实现。"
},
{
"name": "特殊符号",
"synonymous": [],
"description": "描述D3软件插入特殊符号功能的实现。"
},
{
"name": "查找",
"synonymous": [],
"description": "描述D3软件查找功能的实现。"
},
{
"name": "唯一市场价检测",
"synonymous": [],
"description": "描述D3软件唯一市场价检测功能的实现"
},
{
"name": "设备明细反查区域",
"synonymous": [],
"description": "描述D3软件设备明细反查区域功能的实现"
},
{
"name": "右键功能-批量设置",
"synonymous": [],
"description": "描述D3软件右键功能-批量设备功能的实现"
},
{
"name": "查询",
"synonymous": [],
"description": "描述D3软件查询功能的实现"
},
{
"name": "定额明细反查区域",
"synonymous": [],
"description": "描述D3软件定额明细反查区域功能的实现"
},
{
"name": "界面布局",
"synonymous": [],
"description": "材料页签增加展现供货方"
},
{
"name": "配合比列表",
"synonymous": [],
"description": "材料页签增加展现“配合比列表”区域"
},
{
"name": "刷新/保存物料",
"synonymous": [],
"description": "描述D3软件刷新/保存物料功能的实现"
},
{
"name": "刷新/保存材机",
"synonymous": [],
"description": "描述D3软件刷新/保存材机功能的实现"
},
{
"name": "更新机械市场价",
"synonymous": [],
"description": "描述D3软件更新机械市场价功能的实现"
},
{
"name": "主材页签",
"synonymous": [],
"description": "材机分析界面支持四则运算,以覆盖客户在调材料市场价格的时候,可以直接输入公式得出结果值的场景,辅助快速计算编制。"
},
{
"name": "显示典型材机",
"synonymous": [],
"description": "描述D3软件显示典型材机功能的实现"
},
{
"name": "恢复市场价",
"synonymous": [],
"description": "【材机分析】界面,定位资源右键→提供<恢复市场价>功能,支持将选中的人材机的市场价刷新为预算价。"
},
{
"name": "替换",
"synonymous": [],
"description": "用户问题:希望材机分析界面提供替换功能,参考技改T软件。"
},
{
"name": "编辑/预览数据",
"synonymous": [],
"description": "描述D3软件编辑/预览数据功能的实现"
},
{
"name": "一键清空费率",
"synonymous": [],
"description": "描述D3软件一键清空费率功能的实现"
},
{
"name": "一键调价",
"synonymous": [],
"description": "描述D3软件一键调价功能的实现"
},
{
"name": "可抵扣增值税",
"synonymous": [],
"description": "描述D3软件可抵扣增值税设置功能的实现"
},
{
"name": "施工方相关费用",
"synonymous": [],
"description": "描述D3软件施工方相关费用计算功能的实现"
},
{
"name": "导入费用表模板",
"synonymous": [],
"description": "描述D3软件导入费用表模板功能的实现"
},
{
"name": "导出费用表模板",
"synonymous": [],
"description": "描述D3软件导出费用表模板功能的实现"
},
{
"name": "基本设计费",
"synonymous": [],
"description": "调整“设计费费率”窗口高度"
},
{
"name": "其他费用",
"synonymous": [],
"description": "用户问题:展现说明且考虑只开展竣工结算审核时75%,先判断75%后判断800元。而不是只开展竣工结算审核时,手动修改费率75% 解决方案:增加对应判断条件"
},
{
"name": "价差预备费",
"synonymous": [],
"description": "新增功能自动计算价差预备费"
},
{
"name": "总算表",
"synonymous": [],
"description": "软件默认可抵扣增值税的计算式"
},
{
"name": "显示/隐藏空表",
"synonymous": [],
"description": "描述D3软件显示/隐藏空表功能的实现"
},
{
"name": "设置显示的报表目录",
"synonymous": [],
"description": "描述D3软件设置显示的报表目录功能的实现"
},
{
"name": "预览报表",
"synonymous": [],
"description": "描述D3软件预览报表功能的实现"
},
{
"name": "放大/缩小",
"synonymous": [],
"description": "描述D3软件放大/缩小功能的实现"
},
{
"name": "首页/上一页/跳转页面/下一页/末页",
"synonymous": [],
"description": "描述D3软件首页/上一页/跳转页面/下一页/末页功能的实现"
},
{
"name": "设置起始页",
"synonymous": [],
"description": "描述D3软件设置起始页功能的实现"
},
{
"name": "设置页眉页脚",
"synonymous": [],
"description": "描述D3软件设置页眉页脚功能的实现"
},
{
"name": "设置行高",
"synonymous": [],
"description": "描述D3软件设置行高功能的实现"
},
{
"name": "设置页面",
"synonymous": [],
"description": "描述D3软件设置页面功能的实现"
},
{
"name": "打印",
"synonymous": [],
"description": "描述D3软件打印功能的实现"
},
{
"name": "导出",
"synonymous": [],
"description": "描述D3软件导出功能的实现"
},
{
"name": "添加/删除",
"synonymous": [],
"description": "描述D3软件添加/删除功能的实现"
},
{
"name": "合并/取消合并单元格",
"synonymous": [],
"description": "描述D3软件合并/取消合并单元格功能的实现"
},
{
"name": "插入图片/删除图片/设置透明度",
"synonymous": [],
"description": "描述D3软件插入图片/删除图片/设置透明度功能的实现"
},
{
"name": "插入变量",
"synonymous": [],
"description": "描述D3软件插入变量功能的实现"
},
{
"name": "导入/导出自由表",
"synonymous": [],
"description": "描述D3软件导入/导出自由表功能的实现"
},
{
"name": "应用",
"synonymous": [],
"description": "描述D3软件应用功能的实现"
},
{
"name": "字体/加粗/倾斜/下划线",
"synonymous": [],
"description": "描述D3软件字体/加粗/倾斜/下划线功能的实现"
},
{
"name": "居中/对齐",
"synonymous": [],
"description": "描述D3软件居中/对齐功能的实现"
},
{
"name": "边框线/自动换行/自动缩放/不裁剪显示",
"synonymous": [],
"description": "描述D3软件边框线/自动换行/自动缩放/不裁剪显示功能的实现"
},
{
"name": "固定行高/列宽",
"synonymous": [],
"description": "描述D3软件固定行高/列宽功能的实现"
},
{
"name": "添加/添加子表头/删除",
"synonymous": [],
"description": "描述D3软件添加/添加子表头/删除功能的实现"
},
{
"name": "恢复默认设置",
"synonymous": [],
"description": "描述D3软件恢复默认设置功能的实现"
},
{
"name": "设置",
"synonymous": [],
"description": "描述D3软件设置功能的实现"
},
{
"name": "表达式编辑器变量加载",
"synonymous": [],
"description": "描述D3软件表达式编辑器变量加载功能的实现"
},
{
"name": "批量导出/批量打印",
"synonymous": [],
"description": "当前导出报表默认导出为文本格式,导致客户无法直接引用导出的的报表进行公式求和等操作,故导出报表,新增导出数据格式选择功能,以满足客户"
},
{
"name": "导出接口成果",
"synonymous": [],
"description": "南网规约平台近期上线了重码校验规则,软件侧在输出时需进行同步校验"
},
{
"name": "设置报表参数",
"synonymous": [],
"description": "【设置报表参数】窗口,提供“合计等于明细之和”勾选,默认不勾选保证老工程升级数据不变,勾选后响应用户子级费用相加等于合计的需求。"
},
{
"name": "设置报表生成",
"synonymous": [],
"description": "描述D3软件设置报表生成功能的实现"
},
{
"name": "批量设置小数位数",
"synonymous": [],
"description": "描述D3软件批量设置小数位数功能的实现"
},
{
"name": "批量设置页面",
"synonymous": [],
"description": "描述D3软件批量设置页面功能的实现"
},
{
"name": "导入电子徽标",
"synonymous": [],
"description": "描述D3软件导入电子徽标功能的实现"
},
{
"name": "添加自由表/删除自定义报表",
"synonymous": [],
"description": "描述D3软件添加自由表/删除自定义报表功能的实现"
},
{
"name": "生成报表",
"synonymous": [],
"description": "描述D3软件生成报表功能的实现"
},
{
"name": "导入/导出报表模板",
"synonymous": [],
"description": "描述D3软件导入/导出报表模板功能的实现"
},
{
"name": "报表名称",
"synonymous": [],
"description": "按照新预规 1.总算表(万元)报表勾选输出; 2.总算表名称调整"
},
{
"name": "报表数据规则",
"synonymous": [],
"description": "表三甲供材配送、卸车、保管区分主材、消材,目前现状是合并输出,无法清晰界定费用 设备配送费区分甲供设备配送费、乙供设备配送费,并分别输出配送费率和单位"
},
{
"name": "报表列表",
"synonymous": [],
"description": "新增施工费明细表,覆盖客户实际成果输出要求。"
},
{
"name": "报表输出",
"synonymous": [],
"description": "将招标和投标模式下输出项目划分的报表的项目名称列的出值规则统一,将项目划分的序号统一输出至“项目名称”列"
},
{
"name": "导出工程文件",
"synonymous": [],
"description": "批次工程导出单工程时,弹出提示框,供客户自行选择是否按照工程当前最新数据重新生成各单工程报表"
},
{
"name": "导出Excel提醒窗体",
"synonymous": [],
"description": "批次工程导出报表时,增加弹出核对报表格式的提示窗体,实现同当前版本单工程一致"
},
{
"name": "调整报表标准模版列宽",
"synonymous": [],
"description": "响应内蒙客户要求,统一调整报表列宽。"
}
]
File diff suppressed because it is too large Load Diff
+406 -50
View File
@@ -28,16 +28,26 @@
查看README了解如何运行应用程序。
"""
import json
from pathlib import Path
from textwrap import dedent
from agno.document.chunking.document import DocumentChunking
from agno.memory.workflow import WorkflowMemory
from agno.models.deepseek import DeepSeek
from agno.models.message import Message
from agno.run.response import RunResponse
from agno.storage.base import Storage
from agno.storage.sqlite import SqliteStorage
from agno.utils.log import logger
from agno.workflow import Workflow
from dotenv import load_dotenv
# 加载.env文件
load_dotenv()
import os
from typing import Optional
from typing import Optional, Iterator, Dict, Any, Union, List
from agno.agent import Agent, AgentMemory
from agno.embedder.openai import OpenAIEmbedder
@@ -89,10 +99,10 @@ def get_reader(file_type: str):
}
return readers.get(file_type.lower(), None)
def get_model_by_provider(provider: str, model_name: str):
def get_model_by_provider(provider: str, model_name: str, temperature: float = None):
"""根据提供商获取对应的模型实例"""
if provider == "openai":
model = OpenAIChat(id=model_name, base_url=model_baseUrl, api_key=api_key)
model = OpenAIChat(id=model_name, base_url=model_baseUrl, api_key=api_key, temperature=temperature)
model.role_map = {
"system": "system",
"user": "user",
@@ -107,6 +117,8 @@ def get_model_by_provider(provider: str, model_name: str):
# return Claude(id=model_name)
# elif provider == "groq":
# return Groq(id=model_name)
elif provider == "deepseek":
return DeepSeek(id=model_name, base_url=model_baseUrl, api_key=api_key)
else:
raise ValueError(f"Unsupported model provider: {provider}")
@@ -121,18 +133,29 @@ def initialize_memory(model) -> AgentMemory:
summarizer=MemorySummarizer(model=model),
manager=MemoryManager(model=model),
create_user_memories=True, # 存储用户偏好
#create_session_summary=True, # 存储对话摘要
create_session_summary=False, # 存储对话摘要
update_session_summary_after_run=False, # 不更新对话摘要
max_user_memories=10, # 最多存储10条用户偏好
)
def initialize_vector_db() -> LanceDb:
"""初始化并返回配置好的LanceDb实例"""
return LanceDb(
table_name="recipes",
uri=os.getenv("VECTOR_DB_PATH", "tmp/lancedb"),
table_name="knowledge",
uri=os.getenv("VECTOR_DB_PATH", "tmp/knowledgedb"),
search_type=SearchType.hybrid,
embedder=OpenAIEmbedder(id=embedding_model, base_url=embedding_baseUrl, api_key=api_key)
)
def initialize_mingci_vector_db() -> LanceDb:
"""初始化并返回配置好的LanceDb实例"""
return LanceDb(
table_name="mingci",
uri=os.getenv("MINGCI_VECTOR_DB_PATH", "tmp/mingcidb"),
search_type=SearchType.vector,
embedder=OpenAIEmbedder(id=embedding_model, base_url=embedding_baseUrl, api_key=api_key)
)
def initialize_knowledge_base() -> AgentKnowledge:
"""初始化并返回配置好的AgentKnowledge实例"""
return AgentKnowledge(
@@ -146,6 +169,321 @@ def initialize_knowledge_base() -> AgentKnowledge:
reader=TextReader(), # 默认文本读取器
)
def initialize_mingci_knowledge_base() -> AgentKnowledge:
"""初始化并返回配置好的AgentKnowledge实例"""
return AgentKnowledge(
vector_db=initialize_mingci_vector_db(),
num_documents=1, # 检索1个最相关的文档
chunking_strategy=DocumentChunking(
chunk_size=500,
overlap=50,
), # 固定大小分块
optimize_on=1000, # 每1000条数据进行向量优化
reader=TextReader(), # 默认文本读取器
)
def get_question_agent(
model_id: str = "openai:gpt-4o",
user_id: Optional[str] = None,
session_id: Optional[str] = None,
debug_mode: bool = True,
) -> Agent:
"""获取一个带有记忆功能的Questions代理。"""
"""获取一个带有记忆功能的Agentic RAG代理。"""
# 解析模型提供商和名称
provider, model_name = model_id.split(":")
model = get_model_by_provider(provider, model_name, temperature=0)
# 初始化记忆系统
#memory = initialize_memory(model)
# 初始化知识库
knowledge_base = initialize_mingci_knowledge_base()
description = """
# 电力造价软件操作问题转换工具(严格模式)
## 核心指令
你只能输出与**电力造价软件操作**直接相关的专业问题改写结果,禁止任何解释或中间步骤。
## 角色定义
你是一个**严格的问题转换工具**,仅将用户问题转换为电力造价专业表述,**禁止任何额外输出**。
## 绝对禁止事项
- ❌ 禁止强调软件
- ❌ 禁止添加解释性文字(如“注:”“提示:”等)
- ❌ 禁止反问句(如“请问”“您想了解什么?”)
- ❌ 禁止分步过程说明(如“下一步需要...”)
- ❌ 禁止使用人称代词(你/我/您)
## 必须执行的操作流程
1. **关键词提取**
- 立即识别问题中的**基础词语**(动词/名词/形容词)
- 格式示例:`"项目" "划分" "cost" "control"`
- **不输出**,直接进入下一步
2. **专业术语查询**
- 强制自动执行 `search_knowledge_base` 工具
- 等待返回结果后继续
3. **问题改写**
- 严格使用知识库返回的**专业术语**(带引号,如`"工程量清单"`
- 如果问题仅是一个**专业术语**,则用户是想知道该**专业术语**的操作入口
- 仅输出最终改写结果
## 输出规范
- **唯一允许格式**:
`[改写后的专业问题]`
- **错误示例**(将触发终止):
❌ `"涉及...管理"`
❌ `"请问您需要..."`
❌ `"注:已提取关键词..."`
## 违规处罚
若违反上述规则,立即终止并输出:
`[ERROR_STRICT_MODE: 检测到禁止内容]`
## 正确案例
✅ `"在哪里查看'项目划分'"`
✅ `"如何编辑'项目划分''取费表'属性?"`
---
**立即执行**:输入问题后,自动完成`提取→查询→改写`,**仅输出最终结果**。
"""
instructions = """
1. 识别关键词
请识别问题中的关键词,需要中英文均有,可以适量补充不在问题中但相关的关键词。
关键词尽量切分为动词、名词、或形容词等单独的词,不要长词组(目的是更好的匹配检索到语义相关但表述不同的相关资料)。
关键词间以空格分割,比如: "关键词1" "关键词2" "keyword3" "keyword4"
2.搜索知识库中的电力造价专业专有名词
必须始终使用工具 search_knowledge_base 来搜索出所有和关键词相关的电力造价专业及软件业务对象、业务属性的专有名词。
3. 改写用户问题
请结合知识库中返回的电力造价专业专有名词改写用户的输入问题,将问题中的同义词替换成专业词汇,然后将用户问题改写成用电力造价专业描述方式输出完整清晰的问句。
4. 注意事项
不需要反问,不需要补充背景,仅输出第3步中最终改写后的问句。
注意:如果用户问题中有知识库返回的电力造价专业专有名词,请务必将该专业名词用引号包起来,以保留该专业名词完整,不要被拆分成多个基础词语。
"""
# 创建代理
rag_agent: Agent = Agent(
name="博微用户问题理解助手",
session_id=session_id, # 跟踪会话ID以实现持久对话
user_id=user_id,
model=model,
storage=JsonStorage(dir_path=os.getenv("SESSION_STORAGE_PATH", "tmp/question_agent_sessions_json")), # 持久化会话数据
#memory=memory, # 为代理添加记忆功能
knowledge=knowledge_base, # 添加知识库
description=description,
#instructions=instructions,
search_knowledge=True, # 此设置赋予模型搜索知识库信息的工具
markdown=True, # 此设置告诉模型以markdown格式格式化消息
show_tool_calls=True,
add_datetime_to_instructions=True,
debug_mode=debug_mode,
read_tool_call_history=True,
num_history_responses=3,
save_response_to_file=str(tmp.joinpath("msg/question_{message}_{run_id}.md")),
)
return rag_agent
def get_answer_agent(
model_id: str = "openai:gpt-4o",
user_id: Optional[str] = None,
session_id: Optional[str] = None,
debug_mode: bool = True,
) -> Agent:
"""获取一个带有记忆功能的Questions代理。"""
"""获取一个带有记忆功能的Agentic RAG代理。"""
# 解析模型提供商和名称
provider, model_name = model_id.split(":")
model = get_model_by_provider(provider, model_name, 0.3)
# 初始化记忆系统
memory = initialize_memory(model)
# 初始化知识库
knowledge_base = initialize_knowledge_base()
description = """
你是一个智能助手,专门为[博微配网计价通D3软件]提供使用支持。你的任务是帮助用户理解和使用这个复杂的配电网工程造价软件系统。
软件特点
1.多页面架构:软件由多个功能页面组成
2.复杂控件布局:每个页面包含多种控件(如列表控件、TAB控件、按钮等)
3.业务对象丰富:涉及"取费表""项目划分""工程量"等多种业务对象
4.操作多样:支持"添加""修改""删除""导入""导出"等多种操作
"""
instructions = """
1. 理解用户问题
- 用户正在使用软件过程中遇到问题,向您请求帮助
- 只从用户问题识别中提到的业务对象(如"如何设置取费费率""取费表")
- 只从用户问题识别业务对象的属性字段(如"如何设置取费费率""费率")
- 只从用户问题识别用户想要执行的操作(如"如何设置取费费率""设置")
- 判断问题类型(功能入口、操作步骤、错误处理等)
- **不输出**,直接进入下一步
2. 改写问题
- 将用户问题改写为包含以下要素的标准查询:
- [问题类型] : [操作类型] + [业务对象] + [属性]
- **不输出**
- [属性]只有用户问题中明确包含才改写,否则为未知。
- [问题类型]、[操作类型]、[业务对象]为必须输入,如果缺少任一个都需追问用户补全才能进入下一步。
示例:
原始问题:"如何设置取费费率?"
改写后:"操作步骤 : 设置 - 取费 - 费率"
3.搜索知识库
- 必须始终使用工具 search_knowledge_base 来搜索知识库
- 在回应前彻底分析所有返回的文档
- 如果返回多个文档,需连贯地综合信息
- **不输出**,直接进入下一步
4. 上下文管理:
- 使用工具 get_chat_history 保持对话连续性
- 相关时引用之前的交互
- 记录用户偏好和之前的澄清
5. 结果呈现要求
- 用户所处环境如下:
{sofeware_work_context}
- 以 makedown 格式输出,注意换行和排版
- 避免使用'根据我的知识''取决于信息'等模糊表述
7. 特殊情况处理
- 如果问题不明确,可以反问请求澄清
- 如果知识库搜索无结果,则直接明确回复不知道
- 对于错误提示,先解释含义再直接回复无法解决
"""
# 创建代理
rag_agent: Agent = Agent(
name="博微软件AI助手",
session_id=session_id, # 跟踪会话ID以实现持久对话
user_id=user_id,
model=model,
storage=JsonStorage(dir_path=os.getenv("SESSION_STORAGE_PATH", "tmp/answer_agent_sessions_json")), # 持久化会话数据
memory=memory, # 为代理添加记忆功能
knowledge=knowledge_base, # 添加知识库
description=description,
instructions=instructions,
search_knowledge=True, # 此设置赋予模型搜索知识库信息的工具
#read_chat_history=True, # 此设置赋予模型获取聊天历史的工具
# tools=[DuckDuckGoTools()],
markdown=True, # 此设置告诉模型以markdown格式格式化消息
# add_chat_history_to_messages=True,
show_tool_calls=True,
add_history_to_messages=True, # 将聊天历史添加到消息中
add_datetime_to_instructions=True,
add_name_to_instructions=True,
debug_mode=debug_mode,
read_tool_call_history=True,
num_history_responses=3,
save_response_to_file=str(tmp.joinpath("msg/answer_{message}_{run_id}.md")),
)
return rag_agent
class QuestionAndAnswerGenerator(Workflow):
description: str = dedent("""\
An intelligent blog post generator that creates engaging, well-researched content.
This workflow orchestrates multiple AI agents to research, analyze, and craft
compelling blog posts that combine journalistic rigor with engaging storytelling.
The system excels at creating content that is both informative and optimized for
digital consumption.
""")
question: Agent
answer: Agent
def __init__(
self,
*,
name: Optional[str] = None,
workflow_id: Optional[str] = None,
description: Optional[str] = None,
user_id: Optional[str] = None,
session_id: Optional[str] = None,
session_name: Optional[str] = None,
session_state: Optional[Dict[str, Any]] = None,
memory: Optional[WorkflowMemory] = None,
storage: Optional[Storage] = None,
extra_data: Optional[Dict[str, Any]] = None,
debug_mode: bool = False,
monitoring: bool = False,
telemetry: bool = True,
):
super().__init__(
name=name,
workflow_id=workflow_id,
description=description,
user_id=user_id,
session_id=session_id,
session_name=session_name,
session_state=session_state,
memory=memory,
storage=storage,
extra_data=extra_data,
debug_mode=debug_mode,
monitoring=monitoring,
telemetry=telemetry,
)
def run(
self,
message: Optional[Union[str, List, Dict, Message]] = None,
stream: bool = False,
) -> Iterator[RunResponse]:
logger.info(f"Generating a blog post on: {message}")
# Run the writer and yield the response
question_spsponse: RunResponse = self.question.run(message, stream=stream);
if(question_spsponse is None
and question_spsponse.content is None):
yield RunResponse(
content=f"对不起, question 发生错误: {str(question_spsponse.error)}",
error=question_spsponse.error,
tools=question_spsponse.tools,
)
return
answer_spsponse: RunResponse = self.question.run(question_spsponse.content, stream=stream);
if (answer_spsponse is None
and answer_spsponse.content is None):
yield RunResponse(
content=f"对不起, question 发生错误: {str(answer_spsponse.error)}",
error=answer_spsponse.error,
tools=answer_spsponse.tools,
)
return
yield answer_spsponse
def get_workflow(
model_id: str = "openai:gpt-4o",
user_id: Optional[str] = None,
session_id: Optional[str] = None,
debug_mode: bool = True,
) -> QuestionAndAnswerGenerator:
qa_workflow = QuestionAndAnswerGenerator(
user_id=user_id,
session_id=session_id,
#storage=SqliteStorage(
# table_name="investment_report_workflows",
# db_file="tmp/agno_workflows.db",
# auto_upgrade_schema=True,
#),
memory=WorkflowMemory(),
debug_mode=debug_mode,
)
qa_workflow.question = get_question_agent(model_id, user_id, session_id, debug_mode)
qa_workflow.answer = get_answer_agent(model_id, user_id, session_id, debug_mode)
return qa_workflow
mingci_knowledge_base = initialize_mingci_knowledge_base()
def search_mingci_knowledge(query: str) -> str:
""" 使用这个函数用于在专业术语库搜索一个查询请求.
Args:
query: 查询请求.
Returns:
str: 从专业术语库返回一个结果字符串.
"""
global mingci_knowledge_base
from agno.document import Document
docs: List[Document] = mingci_knowledge_base.search(query=query, num_documents=1)
if len(docs) == 0:
return "No documents found"
return "\n\n".join([doc.content for doc in docs])
def get_agentic_rag_agent(
model_id: str = "openai:gpt-4o",
@@ -156,7 +494,7 @@ def get_agentic_rag_agent(
"""获取一个带有记忆功能的Agentic RAG代理。"""
# 解析模型提供商和名称
provider, model_name = model_id.split(":")
model = get_model_by_provider(provider, model_name)
model = get_model_by_provider(provider, model_name, 0.3)
# 初始化记忆系统
memory = initialize_memory(model)
@@ -165,47 +503,65 @@ def get_agentic_rag_agent(
knowledge_base = initialize_knowledge_base()
description="""
你是一个智能助手,专门为[博微配网计价通D3软件]提供使用支持。你的任务是帮助用户理解和使用这个复杂的配电网工程造价软件系统
你是一个智能助手,专门为[博微配网计价通D3软件]提供使用支持。你的任务是帮助博微软件的用户理解和使用这个复杂的配电网工程造价软件系统
交谈中的涉及的""指当前软件。
注意 在当前环境下"工程""项目"并非同义词,请勿相互替换
软件特点
1.多页面架构:软件由多个功能页面组成
2.复杂控件布局:每个页面包含多种控件(如列表控件、TAB控件、按钮等)
3.业务对象丰富:涉及"取费表""项目划分""工程量"多种业务对象
4.操作多样:支持"添加""修改""删除""导入""导出"等多种操作
1.多页面架构:软件整个界面由多个编辑页面组成,通过顶部的页签切换页面
2.复杂控件布局:每个编辑页面包含多种控件(如列表控件、TAB控件、树列表控件、按钮等)
3.业务对象丰富:每个控件可能用于展示和编辑零至多个业务对象。(如"取费表""项目划分""工程量"等业务对象)
4.操作多样:支持"添加""修改""删除""导入""导出""右键"等多种操作
"""
instructions="""
1. 理解用户问题
用户正在使用软件过程中遇到问题,向您请求帮助
用户所处环境如下:
{sofeware_work_context}
只从用户问题识别中提到的业务对象(如"如何设置取费费率""取费表")
只从用户问题识别业务对象的属性字段(如"如何设置取费费率""费率")
只从用户问题识别用户想要执行的操作(如"如何设置取费费率""设置")
判断问题类型(功能入口、操作步骤、错误处理等)
2. 改写问题
将用户问题改写为包含以下要素的标准查询:
[问题类型] : [操作类型] + [业务对象] + [属性]
[属性]只有用户问题中明确包含才改写,否则为未知。
[问题类型]、[操作类型]、[业务对象]为必须输入,如果缺少任一个都需追问用户补全才能进入下一步。
示例
原始问题:"如何设置取费费率?"
改写后:"操作步骤 : 设置 - 取费 - 费率"
3.搜索知识库
必须始终使用工具 search_knowledge_base 来搜索知识库
在回应前彻底分析所有返回的文档
如果返回多个文档,需连贯地综合信息
4. 上下文管理:
使用工具 get_chat_history 保持对话连续性
相关时引用之前的交互
记录用户偏好和之前的澄清
5. 结果呈现要求
以 makedown 格式输出,注意换行和排版
避免使用'根据我的知识''取决于信息'等模糊表述
7. 特殊情况处理
如果问题不明确,可以反问请求澄清
如果知识库搜索无结果,则直接明确回复不知道
对于错误提示,先解释含义再直接回复无法解决
1. **关键词提取**
- 立即识别问题中的**基础词语**(动词/名词/形容词)
- 格式示例:`"项目" "划分" "cost" "control"`
- **不输出**,直接进入下一步
2. **专业术语查询**
- 强制自动执行 `search_mingci_knowledge` 工具搜索专业术语库
- **不输出**,等待返回结果后直接进入下一步
3. **问题改写**
- 问题改写严格仅使用专业术语库返回的**专业术语**和**同义词**,必须完全匹配才能替换,不使用上下文等其他信息(带引号,如`"工程量清单"`
- 如果问题仅是一个**专业术语**,则用户是想知道该**专业术语**的操作入口
- **不输出**,直接进入下一步
4. **问题结构化**
- 判断问题类型(功能入口、操作步骤、错误处理等)
- 将上一步中问题改写的结果解析为包含以下要素的标准查询
- [问题类型] : [操作类型] + [业务对象] + [业务属性]
- [业务属性]只有用户问题中明确包含才改写,否则为未知。
- [问题类型]、[操作类型]、[业务对象]为必须输入,如果缺少任一个都需追问用户补全才能进入下一步。
示例:
原始问题:"如何设置取费费率?"
改写后:"操作步骤 : 设置 - 取费 - 费率"
- **不输出**,直接进入下一步
5.**搜索知识库**
- 每次都必须始终调用工具 search_knowledge_base 从知识库中搜索结构化后的问题
- **不输出**,直接进入下一步
6. **上下文管理**
- 使用工具 get_chat_history 保持对话连续性
- 相关时引用之前的交互
- 记录用户偏好和之前的澄清
- 用户消息中的{context}中的软件环境上下文:{软件上下文}
- **不输出**,直接进入下一步
7. **结果呈现要求**
- ***最终输出内容*
- **首先以 makedown 格式以向用户确认的口吻输出改写后的完整问句** (如 您是想询问:`改写后的问句`)
- **其次换行后以 makedown 格式输出回答信息**
- 注意 改写后的问句应该能叫人清晰的理解用户在咨询什么[问题类型](功能入口、操作步骤、错误处理等)的问题
- 如果问题类型是"功能入口",句式示例:'在哪里可以设置综合地形增加费?'
- 如果问题类型是"操作步骤",句式示例:'如何设置取费费率?'
- 如果问题类型是"错误处理",句式示例:'修改表达式时提示"表达式错误"'
- 注意 回答信息请必须从用户消息中的"软件上下文"中读取当前页面信息,然后从当前页面指引用户如何继续操作
- **在回答时候,要注意问题类型**,并根据问题类型输出不同的回答信息
- 如果搜索知识库返回"No documents found"无结果,则直接明确回复当前知识库中不存在该知识
- 如果问题类型是"功能入口",则只需要回答如何进入该功能入口即可,不要回答多余内容。
- 如果问题类型是"操作步骤",则只需要回答如何完成该操作的步骤即可,不要回答多余内容。
- 如果问题类型是"错误处理",则需要回答如何处理该错误,不要回答多余内容。
8. 特殊情况处理
- 如果问题不明确,可以反问请求澄清
- 对于错误提示,直接告知错误原因即可
"""
# 创建代理
@@ -219,21 +575,21 @@ def get_agentic_rag_agent(
knowledge=knowledge_base, # 添加知识库
description=description,
instructions=instructions,
context={"sofeware_work_context": get_sofeware_work_context},
context={"软件上下文": get_sofeware_work_context},
add_context=True,
search_knowledge=True, # 此设置赋予模型搜索知识库信息的工具
read_chat_history=True, # 此设置赋予模型获取聊天历史的工具
#tools=[DuckDuckGoTools()],
tools=[search_mingci_knowledge],
markdown=True, # 此设置告诉模型以markdown格式格式化消息
# add_chat_history_to_messages=True,
show_tool_calls=True,
add_history_to_messages=True, # 将聊天历史添加到消息中
#add_history_to_messages=True, # 将聊天历史添加到消息中
add_datetime_to_instructions=True,
add_name_to_instructions=True,
debug_mode=debug_mode,
read_tool_call_history=True,
#read_tool_call_history=True,
num_history_responses=3,
save_response_to_file=str(tmp.joinpath("{message}.md")),
save_response_to_file=str(tmp.joinpath("msg/answer_{message}_{run_id}.md")),
)
return agentic_rag_agent
+60 -10
View File
@@ -1,10 +1,13 @@
import re
from typing import Optional
from dotenv import load_dotenv
# 加载.env文件
load_dotenv()
import threading
import nest_asyncio
from agentic_rag import get_agentic_rag_agent
from agentic_rag import get_agentic_rag_agent, get_workflow, get_sofeware_work_context
from agno.utils.log import logger
from ui import (
initialize_ui,
@@ -14,7 +17,6 @@ from ui import (
)
from utils import (
add_message,
session_selector_widget,
)
import streamlit as st
from extra_streamlit_components import CookieManager
@@ -24,20 +26,29 @@ nest_asyncio.apply()
lock = threading.Lock()
def initialize_agent(model_id: str):
def initialize_agent(model_id: str, session_id: Optional[str] = None):
"""Initialize or retrieve the Agentic RAG."""
lock.acquire()
if session_id is None:
session_id = st.session_state.get("agentic_rag_agent_session_id")
agent = st.session_state.get("agentic_rag_agent") if "agentic_rag_agent" in st.session_state else None
try:
if (
not "agentic_rag_agent" in st.session_state
or st.session_state.get("agentic_rag_agent") is None
or st.session_state.get("current_model") != model_id
if (st.session_state.get("current_model") != model_id
or agent is None
or agent.session_id != session_id
):
logger.info(f"---*--- Creating {model_id} Agent ---*---")
agent = get_agentic_rag_agent(
model_id=model_id,
session_id=st.session_state.get("agentic_rag_agent_session_id"),
session_id=session_id,
)
#agent = get_workflow(
# model_id=model_id,
# session_id=session_id,
#)
st.session_state["agentic_rag_agent"] = agent
st.session_state["current_model"] = model_id
else:
@@ -95,6 +106,7 @@ def main():
# Chat input
if prompt := st.sidebar.chat_input("👋 问我任何问题!"):
agentic_rag_agent.context = get_sofeware_work_context()
add_message("user", prompt)
# Display UI
@@ -111,6 +123,7 @@ def main():
with st.chat_message(message["role"]):
#if "tool_calls" in message and message["tool_calls"]:
# display_tool_calls(st.empty(), message["tool_calls"])
_content = re.sub(r'<context>\s*{.*?}\s*</context>', '', _content, flags=re.DOTALL)
st.markdown(_content)
with lastMsgContainer:
@@ -127,7 +140,7 @@ def main():
response = ""
try:
# Run the agent and stream the response
run_response = agentic_rag_agent.run(question, stream=True)
run_response = agentic_rag_agent.run(message=question, stream=True)
for _resp_chunk in run_response:
# Display tool calls if available
#if _resp_chunk.tools and len(_resp_chunk.tools) > 0:
@@ -148,7 +161,44 @@ def main():
####################################################################
# Session selector
####################################################################
session_selector_widget(agentic_rag_agent, model_id)
if agentic_rag_agent.storage:
agent_sessions = agentic_rag_agent.storage.get_all_sessions()
# Get session names if available, otherwise use IDs
session_options = []
for session in agent_sessions:
session_id = session.session_id
session_name = (
session.session_data.get("session_name", None)
if session.session_data
else None
)
display_name = session_name if session_name else session_id
session_options.append({"id": session_id, "display": display_name})
# Display session selector
# selected_session = st.sidebar.selectbox(
# "会话",
# options=[s["display"] for s in session_options],
# key="session_selector",
# )
# Find the selected session ID
# selected_session_id = next(
# s["id"] for s in session_options if s["display"] == selected_session
# )
if len(session_options) > 0:
selected_session_id = session_options[0]["id"]
if ('agentic_rag_agent_session_id' in st.session_state and
selected_session_id is not None and
st.session_state["agentic_rag_agent_session_id"] != selected_session_id):
logger.info(
f"---*--- Loading {model_id} run: {selected_session_id} ---*---"
)
st.session_state["agentic_rag_agent"] = initialize_agent(
model_id=model_id,
session_id=selected_session_id,
)
st.rerun()
#rename_session_widget(agentic_rag_agent)
####################################################################
+49 -16
View File
@@ -1,3 +1,4 @@
import json
from pathlib import Path
from typing import List
@@ -5,7 +6,7 @@ from agno.document import Document
from agno.utils.log import logger
from dotenv import load_dotenv
from agentic_rag import initialize_knowledge_base, get_reader
from agentic_rag import initialize_knowledge_base, get_reader, initialize_mingci_knowledge_base
# 加载.env文件
load_dotenv()
@@ -14,26 +15,58 @@ import os
def main():
print("Hello from agno-agentic-rag!")
# 从.env加载知识库来源目录并初始化知识库
load_knowledge = os.getenv("LOAD_KNOWLEDGE", "false").lower() == "true"
mingci_knowledge_source_dir = os.getenv("MINGCI_KNOWLEDGE_SOURCE_DIR")
if mingci_knowledge_source_dir and os.path.exists(mingci_knowledge_source_dir):
# 初始化知识库
knowledge_base = initialize_mingci_knowledge_base()
LoadMingCiKnowledgeToDatabase(knowledge_base, mingci_knowledge_source_dir)
knowledge_source_dir = os.getenv("KNOWLEDGE_SOURCE_DIR")
if load_knowledge and knowledge_source_dir and os.path.exists(knowledge_source_dir):
if knowledge_source_dir and os.path.exists(knowledge_source_dir):
# 初始化知识库
knowledge_base = initialize_knowledge_base()
logger.info(f"加载知识库: {knowledge_source_dir}")
for root, _, files in os.walk(knowledge_source_dir):
for file in files:
file_path = os.path.join(root, file)
file_ext = os.path.splitext(file)[1][1:] # 获取文件扩展名
reader = get_reader(file_ext)
if reader:
try:
filePath = Path(file_path)
docs: List[Document] = reader.read(filePath)
knowledge_base.load_documents(docs, upsert=True)
except Exception as e:
logger.warning(f"无法加载文档 {file_path}: {str(e)}")
LoadKnowledgeToDatabase(knowledge_base, knowledge_source_dir)
def LoadMingCiKnowledgeToDatabase(knowledge_base, knowledge_source_dir):
logger.info(f"加载知识库: {knowledge_source_dir}")
for root, _, files in os.walk(knowledge_source_dir):
for file in files:
file_path = os.path.join(root, file)
file_ext = os.path.splitext(file)[1][1:] # 获取文件扩展名
reader = get_reader(file_ext)
if reader:
try:
docs = []
with open(file_path, 'r', encoding='utf-8') as f:
json_obj = json.load(f)
for item in json_obj:
file_contents = "{}\n 同义词: {}".format(item["name"], item["synonymous"])
docs.append(Document(
name=item["name"],
id=item["name"],
content=file_contents,
))
knowledge_base.load_documents(docs, upsert=True)
except Exception as e:
logger.warning(f"无法加载文档 {file_path}: {str(e)}")
def LoadKnowledgeToDatabase(knowledge_base, knowledge_source_dir):
logger.info(f"加载知识库: {knowledge_source_dir}")
for root, _, files in os.walk(knowledge_source_dir):
for file in files:
file_path = os.path.join(root, file)
file_ext = os.path.splitext(file)[1][1:] # 获取文件扩展名
reader = get_reader(file_ext)
if reader:
try:
filePath = Path(file_path)
docs: List[Document] = reader.read(filePath)
knowledge_base.load_documents(docs, upsert=True)
except Exception as e:
logger.warning(f"无法加载文档 {file_path}: {str(e)}")
if __name__ == "__main__":
main()
+1
View File
@@ -11,6 +11,7 @@ dependencies = [
"nest-asyncio>=1.6.0",
"streamlit>=1.44.1",
"openai",
"pylance",
"extra-streamlit-components>=0.1.71",
"sqlalchemy>=2.0.38",
"websockets>=14.2",
+49
View File
@@ -0,0 +1,49 @@
from pathlib import Path
from typing import List
from agno.document import Document
from agno.utils.log import logger
from dotenv import load_dotenv
from agentic_rag import initialize_knowledge_base, get_reader, initialize_mingci_knowledge_base, get_question_agent, \
get_answer_agent, get_agentic_rag_agent
from app import initialize_agent
from ui import get_modul_option
# 加载.env文件
load_dotenv()
import os
def main():
print("Hello from agno-agentic-rag!")
model_id = get_modul_option(0)
query = "修改取费表名称"
gent = get_agentic_rag_agent(model_id)
response = gent.run(query)
print(response)
# 初始化知识库
#mingci_knowledge_base = initialize_mingci_knowledge_base()
#mingci_result = mingci_knowledge_base.search(query, num_documents=10)
#print(mingci_result)
question_agent = get_question_agent(model_id)
question_response = question_agent.run(query)
print(question_response)
#knowledge_base = initialize_knowledge_base()
#result = knowledge_base.search(query, num_documents=10)
#print(result)
answer_agent = get_answer_agent(model_id)
answer_response = answer_agent.run(question_response.content)
print(answer_response)
print(answer_response)
if __name__ == "__main__":
main()
+1 -1
View File
@@ -35,7 +35,7 @@ def set_current_page(page : str):
set_sofeware_work_context({
"软件": "博微配网计价通D3软件",
"工程文件": "广州配网造价工程",
"已打开页面": ["工程信息", "取费设置", "组合件", "工程量", "材机分析", "工程费用", "报表输出"],
"所有编辑页面": ["工程信息", "取费设置", "组合件", "工程量", "材机分析", "工程费用", "报表输出"],
"当前页面": page,
})
+1 -42
View File
@@ -1,4 +1,5 @@
from dotenv import load_dotenv
# 加载.env文件
load_dotenv()
@@ -108,48 +109,6 @@ def rename_session_widget(agent: Agent) -> None:
st.session_state.session_edit_mode = False
st.rerun()
def session_selector_widget(agent: Agent, model_id: str) -> None:
"""Display a session selector in the sidebar"""
if agent.storage:
agent_sessions = agent.storage.get_all_sessions()
# Get session names if available, otherwise use IDs
session_options = []
for session in agent_sessions:
session_id = session.session_id
session_name = (
session.session_data.get("session_name", None)
if session.session_data
else None
)
display_name = session_name if session_name else session_id
session_options.append({"id": session_id, "display": display_name})
# Display session selector
#selected_session = st.sidebar.selectbox(
# "会话",
# options=[s["display"] for s in session_options],
# key="session_selector",
#)
# Find the selected session ID
#selected_session_id = next(
# s["id"] for s in session_options if s["display"] == selected_session
#)
if len(session_options) > 0:
selected_session_id = session_options[0]["id"]
if st.session_state["agentic_rag_agent_session_id"] != selected_session_id:
logger.info(
f"---*--- Loading {model_id} run: {selected_session_id} ---*---"
)
st.session_state["agentic_rag_agent"] = get_agentic_rag_agent(
model_id=model_id,
session_id=selected_session_id,
)
st.rerun()
def about_widget() -> None:
"""Display an about section in the sidebar"""
st.sidebar.markdown("---")