From 187b8c8756b468126f5f9c1847824c3a3b13236c Mon Sep 17 00:00:00 2001 From: HengZhang Date: Sun, 1 Mar 2026 11:09:18 +0800 Subject: [PATCH] react_agent/ agent_tools/middleware --- .gitignore | 2 + .idea/agent_proj.iml | 2 +- .idea/misc.xml | 2 +- agent/chroma_db/chroma.sqlite3 | Bin 0 -> 167936 bytes agent/react_agent.py | 39 +++++++ .../__pycache__/agent_tools.cpython-312.pyc | Bin 0 -> 5071 bytes .../__pycache__/middleware.cpython-312.pyc | Bin 0 -> 3076 bytes agent/tools/agent_tools.py | 99 ++++++++++++++++++ agent/tools/chroma_db/chroma.sqlite3 | Bin 0 -> 167936 bytes agent/tools/middleware.py | 51 +++++++++ config/agent.yaml | 1 + logs/Agent_20260301.log | 28 +++++ middleware.py | 0 rag/__pycache__/rag_service.cpython-312.pyc | Bin 0 -> 2901 bytes rag/__pycache__/vector_store.cpython-312.pyc | Bin 0 -> 5311 bytes .../__pycache__/file_handler.cpython-312.pyc | Bin 3127 -> 3152 bytes .../logger_handler.cpython-312.pyc | Bin 2169 -> 2169 bytes .../__pycache__/prompt_loader.cpython-312.pyc | Bin 0 -> 2742 bytes 18 files changed, 222 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 agent/chroma_db/chroma.sqlite3 create mode 100644 agent/react_agent.py create mode 100644 agent/tools/__pycache__/agent_tools.cpython-312.pyc create mode 100644 agent/tools/__pycache__/middleware.cpython-312.pyc create mode 100644 agent/tools/agent_tools.py create mode 100644 agent/tools/chroma_db/chroma.sqlite3 create mode 100644 agent/tools/middleware.py create mode 100644 logs/Agent_20260301.log delete mode 100644 middleware.py create mode 100644 rag/__pycache__/rag_service.cpython-312.pyc create mode 100644 rag/__pycache__/vector_store.cpython-312.pyc create mode 100644 utils/__pycache__/prompt_loader.cpython-312.pyc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..63ac784 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.git +.idea diff --git a/.idea/agent_proj.iml b/.idea/agent_proj.iml index b9ed519..5e376b1 100644 --- a/.idea/agent_proj.iml +++ b/.idea/agent_proj.iml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 1511473..f86cb7f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/agent/chroma_db/chroma.sqlite3 b/agent/chroma_db/chroma.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..88acd6f7e29aad7aa6b2fc0f4c63f251b0d195f8 GIT binary patch literal 167936 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 MPDo3|3@zsVA9k#(P5=M^ literal 0 HcmV?d00001 diff --git a/agent/react_agent.py b/agent/react_agent.py new file mode 100644 index 0000000..4bb2f86 --- /dev/null +++ b/agent/react_agent.py @@ -0,0 +1,39 @@ +from langchain.agents import create_agent +from model.factory import chat_model +from utils.prompt_loader import load_system_prompts +from agent.tools.agent_tools import (rag_summarize, get_weather, get_user_id, + get_user_location, get_current_month, + fill_context_for_report, fetch_external_data) +from agent.tools.middleware import monitor_tool, log_before_model, repoet_prompt_switch + + +class ReactAgent: + def __init__(self): + self.agent = create_agent( + model=chat_model, + system_prompt=load_system_prompts(), + tools=[rag_summarize, get_weather, get_user_location, get_user_id, + get_current_month, fetch_external_data, fill_context_for_report], + middleware=[monitor_tool, log_before_model, repoet_prompt_switch], + ) + + def excute_stream(self, query: str): + input_dict = { + "messages": [ + {"role": "user", "content": query} + ] + } + + # 上下文runtime信息,做提示词切换标记 + response = self.agent.stream(input_dict, stream_mode="values", context={"report": False}) + for chunk in response: + latest_message = chunk["messages"][-1] + if latest_message.content: + yield latest_message.content.strip() + "\n" + + +if __name__ == '__main__': + agent = ReactAgent(); + stream = agent.excute_stream("扫地机器人在我所在地的气温下如何保养") + for chunk in stream: + print(chunk, end="", flush=True) diff --git a/agent/tools/__pycache__/agent_tools.cpython-312.pyc b/agent/tools/__pycache__/agent_tools.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97c39eefc339330feaeac594ef315f8dd266d94a GIT binary patch literal 5071 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 literal 0 HcmV?d00001 diff --git a/agent/tools/__pycache__/middleware.cpython-312.pyc b/agent/tools/__pycache__/middleware.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37b237cc8cd63804b15b27a7f73379ab295d71c7 GIT binary patch literal 3076 zcmai0Z){W76~FJF|2@Zkc0xl!iwq6~lM+X2E6^4dLJ9+tLX`kr&5-Bh-8jzPv$Ol2 z7ZQaEy3r+FH>lJJG{y>ASu-JRnKrFV;{)sVq0+v*H%BvlB5I`JjDD&Y`eEumZ09~d z+et^^%D(r!bI&>V-gD3Iocq^?1|Nd<#~VM-oOC1f5BgDU9*20a48%nwBbiZ<$|M+- zO|UAL;8Z@rGnCINg6c}RY?@Qtswd&GX; zvT2VJQp1U`O?#C_wJFi0u1l$gBHl=2Ulj9_(j_a2HMamw)-_B!Ak1Y_G$JpyA-~}wzEswb%m?iV$h>x zW%swXAw*ha4@kM{=dDs>RghE}Fv{L;=%?916h*oXFFM(V$gb1es(t$@cWsk>kJ`&+ zB#U~msxe(V0r-kvbsFw9MnndXD4wA498q)GjGiMWmuKI* zf9=iE``1h7-v9L0Pb?ln8b3tt-mR;pbJt7fUt9k1ye*d^X)WJWx0k8dt60j@bKRf+ z?myq2Tb{X4dgC3dc_gC%igH;UpVE_nqGTmbkJ50Y0h_0eb+nsn+NF1YbN_eOKfU#4 z=|}IBE?@mhB<3L^%vyXVJCd`!b!@sx1ss;!S;X@0J2i~Q^-L~n37C)^u{cd9F`h_Z zfP|j(QS5g-#l)1ykKnKcl#Sg z)4+mfa7hdo#V1Yi$xFvgvCY`l^Ea{QPS>+DUps$f_DInmHT}`62TcEtrQo`mhJW7` zn^q7jNYt)>)_>tUm(sPsI0*Kjd8cGjcwi^9_5NAtCTc_a;weZcuqhn0SD^za z_-att{TJ@`z7MyXFB~iEId1HJ*?9SzhLl?1hbS2O&-NRQTi%uDo||u_;XPn>>?v&R zDQ-PvZarjd=_@0qpNZayZkua0qtDI{n9*Iu=pHk=rx@LDM)wz@2aL@J%N!H#V?INS z(9bN1!3VGdG+e82@WI31u6|QMT%@%C#xJ&qRl>1a6xO9>MrLm~Rr546%@ChXW7}@k z+aE;rsH^j0++jjf-~O0DT45v`ptHC%)(MRy5`Yd|PScm=&1g;rUE}yBnoM!E`X{xC zj6OU{o&gOSTpA_Lpe3pKV(_hCQEE4(_M+5bN*!|t=5aylK6CIRw{$nSxe#nKJZ<;H zjRi4c@DUORy~D8(NmC7mZu zr9?;)s&j%c0C0n`tG-3l~*3C$F mf-PkZ#--5u6#+&nQ<*6@+0p{D>FU!f2nJjIUo24eLH-A3#S~Zo literal 0 HcmV?d00001 diff --git a/agent/tools/agent_tools.py b/agent/tools/agent_tools.py new file mode 100644 index 0000000..603f9ed --- /dev/null +++ b/agent/tools/agent_tools.py @@ -0,0 +1,99 @@ +import pandas +from langchain_core.tools import tool +from rag.rag_service import RagSummarizeService +import random +from utils.config_handler import agent_conf +from utils.path_tool import get_abs_path +from utils.logger_handler import logger +import os + +rag = RagSummarizeService() + +user_ids = [str(i) for i in range(1001, 1011, 1)] +month_arr = [f"2025-{str(i).zfill(2)}" for i in range(1, 13, 1)] +external_data = {} + + +@tool(description="向量存储中检索参考资料") +def rag_summarize(query: str) -> str: + return rag.rag_summarize(query) + + +@tool(description="获取指定城市天气,消息以字符串方式返回") +def get_weather(city: str) -> str: + return f"城市{city}天气为晴天,温度为26摄氏度,湿度50%,南风1级,AQI21,最近6小时降雨概率极低" + + +@tool(description="获取用户所在城市名称,以纯字符串形式返回") +def get_user_location() -> str: + return random.choice(["深圳", "合肥", "杭州"]) + + +@tool(description="获取用户ID,以纯字符串形式返回") +def get_user_id() -> str: + return random.choice(user_ids) + + +@tool(description="获取当前月份,以纯字符串形式返回") +def get_current_month() -> str: + return random.choice(month_arr) + + +def generate_external_data(): + """得到用户字典, + { + "user_id": { + "month": {"特征: ..., "效率:} + } + }""" + + if not external_data: + external_data_path = agent_conf['external_data_path'] + external_data_path = get_abs_path(external_data_path) + + if not os.path.exists(external_data_path): + raise FileExistsError(f"外部文件{external_data_path}不存在") + + with open(external_data_path, 'r', encoding='utf-8') as f: + for line in f.readlines(): + arr = line.strip().split(',') + user_id = arr[0].replace('"', "") + feature = arr[1].replace('"', "") + efficiency = arr[2].replace('"', "") + consumables = arr[3].replace('"', "") + comparison = arr[4].replace('"', "") + time = arr[5].replace('"', "") + + if user_id not in external_data: + external_data[user_id] = {} + + external_data[user_id][time] = { + "特征": feature, + "效率": efficiency, + "耗材": consumables, + "对比": comparison, + } + return external_data + + +@tool(description="从外部系统获取用户使用记录,以春字符串形式返回,如果未检索到,返回空字符串") +def fetch_external_data(user_id: str, month: str) -> str: + generate_external_data() + + try: + return external_data[user_id][month] + except KeyError: + logger.warning(f"[fetch_external_data]未检索到用户:{user_id}在{month}的使用数据") + return "" + + +@tool(description="无入参,无返回值,调用后自动触发中间件,自动为报告生成动态场景上下文" + "+") +def fill_context_for_report(): + return "fill_context_for_report已调用" + +# if __name__ == '__main__': +# user_id = "1005" +# month = "2025-06" +# res = fetch_external_data(user_id, month) +# print(res) diff --git a/agent/tools/chroma_db/chroma.sqlite3 b/agent/tools/chroma_db/chroma.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..3b39f563dc2fa7c34b06340a13ca12dd9d91d594 GIT binary patch literal 167936 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 literal 0 HcmV?d00001 diff --git a/agent/tools/middleware.py b/agent/tools/middleware.py new file mode 100644 index 0000000..d60abfe --- /dev/null +++ b/agent/tools/middleware.py @@ -0,0 +1,51 @@ +from langchain.agents.middleware import wrap_tool_call, before_model, dynamic_prompt, ModelRequest +from langchain.tools.tool_node import ToolCallRequest +from typing import Callable +from langchain_core.messages import ToolMessage +from langgraph.types import Command +from utils.logger_handler import logger +from langchain.agents import AgentState +from langgraph.runtime import Runtime +from utils.prompt_loader import load_system_prompts, load_report_prompts + +@wrap_tool_call +def monitor_tool( + # 函数 + request: ToolCallRequest, + # 入参 + handler: Callable[[ToolCallRequest], ToolMessage | Command], +) -> ToolMessage | Command: + logger.info(f"[tool monitor]执行工具:{request.tool_call['name']}") + logger.info(f"[tool monitor]传入参数:{request.tool_call['args']}") + + try: + result = handler(request) + logger.info(f"[tool minitor]工具{request.tool_call['name']}调用成功") + + if request.tool_call['name'] == 'fill_context_for_report': + request.runtime.context["report"] = True + + return result + except Exception as e: + logger.error(f"工具{request.tool_call['name']}调用失败,原因: {str(e)}") + raise e + + +@before_model +def log_before_model( + state: AgentState, # 状态记录 + runtine: Runtime, # 执行过程 上下文信息 +): + logger.info(f"[log_before_model]即将调用模型,带有{len(state["messages"])}条消息") + logger.debug(f"[log_before_model]{type(state["messages"][-1]).__name__} | " + f"消息内容:{state["messages"][-1].content.strip()}") + return None + + +@dynamic_prompt # 每一次提示词生成前,调用 +def repoet_prompt_switch(request: ModelRequest): + is_report = request.runtime.context.get("report", False) + if is_report: + return load_report_prompts() + + return load_system_prompts() diff --git a/config/agent.yaml b/config/agent.yaml index e69de29..eb994ba 100644 --- a/config/agent.yaml +++ b/config/agent.yaml @@ -0,0 +1 @@ +external_data_path: data/external/records.csv diff --git a/logs/Agent_20260301.log b/logs/Agent_20260301.log new file mode 100644 index 0000000..600704c --- /dev/null +++ b/logs/Agent_20260301.log @@ -0,0 +1,28 @@ +2026-03-01 00:10:11,186 - Agent - WARNING - agent_tools.py:86 - [fetch_external_data]未检索到用户:1004在2月的使用数据 +2026-03-01 00:10:15,880 - Agent - WARNING - agent_tools.py:86 - [fetch_external_data]未检索到用户:1008在8月的使用数据 +2026-03-01 11:06:16,324 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 11:06:16,324 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:扫地机器人在我所在地的气温下如何保养 +2026-03-01 11:06:50,251 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 11:06:50,251 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:扫地机器人在我所在地的气温下如何保养 +2026-03-01 11:08:04,788 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 11:08:04,789 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:扫地机器人在我所在地的气温下如何保养 +2026-03-01 11:08:09,924 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_user_location +2026-03-01 11:08:09,925 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 11:08:09,926 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_user_location调用成功 +2026-03-01 11:08:09,927 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有3条消息 +2026-03-01 11:08:09,927 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:杭州 +2026-03-01 11:08:13,076 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_weather +2026-03-01 11:08:13,076 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'city': '杭州'} +2026-03-01 11:08:13,078 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_weather调用成功 +2026-03-01 11:08:13,079 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有5条消息 +2026-03-01 11:08:13,079 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:城市杭州天气为晴天,温度为26摄氏度,湿度50%,南风1级,AQI21,最近6小时降雨概率极低 +2026-03-01 11:08:16,346 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:rag_summarize +2026-03-01 11:08:16,346 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'query': '扫地机器人在26摄氏度温度和50%湿度环境下的保养方法'} +2026-03-01 11:08:19,183 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 +2026-03-01 11:08:19,185 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有7条消息 +2026-03-01 11:08:19,185 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:参考资料中未提及扫地机器人在26摄氏度温度和50%湿度环境下的具体保养方法。 +2026-03-01 11:08:21,538 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:rag_summarize +2026-03-01 11:08:21,539 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'query': '扫地机器人日常保养方法'} +2026-03-01 11:08:25,493 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 +2026-03-01 11:08:25,494 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有9条消息 +2026-03-01 11:08:25,494 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:定期清理滚刷和边刷上的缠绕物,清空尘盒,擦拭传感器和充电触点,检查并清理滤网,避免在潮湿或有水区域使用,及时更换磨损配件。 diff --git a/middleware.py b/middleware.py deleted file mode 100644 index e69de29..0000000 diff --git a/rag/__pycache__/rag_service.cpython-312.pyc b/rag/__pycache__/rag_service.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..674b1208d26c0a6e5fe4b40e7579a7758e921e02 GIT binary patch literal 2901 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 literal 0 HcmV?d00001 diff --git a/utils/__pycache__/file_handler.cpython-312.pyc b/utils/__pycache__/file_handler.cpython-312.pyc index 6f644945833f809b57fed75db65bd590b4b42d3c..5a064dfa8e455479b7e9e8ef6fbe42882d732983 100644 GIT binary patch delta 203 zcmdlkaY2IjG%qg~0}w1dzbLb5Bd;!(JPVM=48)%;fW&l$5=I~e1~m*RjBA)CPvunC zU@qkc3O(&w@M7=Ykcg0H)7qcx-d4q0T9T$~p~-lQBQ-BMKP59Seey&uZB-MXQZpbf zmH-kB3{SX4CuFWrzrt;Fo!k5(xA|pm%L^=)lkamKkpZb($xx&Vq>2=Q#4Qe+-29Z% ioK(9ao5}mR6C|u=D1TsJVzgSIvY=w2-WL!PtQr74t2uc9 delta 145 zcmca0v0Z}qG%qg~0}!};SeRL`kyn>XmKn$c;m;;OVmdMG%qg~0}w1dzi1MG%qg~0}wbqS-6oqj{^Wh!v+Na diff --git a/utils/__pycache__/prompt_loader.cpython-312.pyc b/utils/__pycache__/prompt_loader.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..267e2678b8bcdd3e95211cbd932d426b43eb67f3 GIT binary patch literal 2742 zcmeHJTWs4@7(OSq6X()8vR8LmggOu{ue>-UXkgJN+HQS|+99Ftg>#&EZF(6Tad9(=RYWwX<;1RyALoO^OyJ2@ll2pe&) z5)%<<`qD^ErFD&usmcIZ%aYCu{TiPZ^f+ESld3FBC|2IudblyA@V(xI9hn4fpqCv2 zKzG=JBCNyEc6E$Md2L=6h?GcQW2T7}d<|BWo?EHy_$lxV(CvVNX8~#)gSyL>9As^@ z`4k;lco}@*u=j=_3(r9jjKTNdFdPPFsdvFJ#8#_q9c=Z$zgl%>!DS%2^v7(iEVOsP zyU{k@eYXgE-1Mh}gu<8NZG|@z#io*~AoALXrc0?ZPiqUWe)P%hAFi)lJim1F#?p7+ z-2Q%UdG@o_iR*1)6QT_!qYoTBG6hXmQevu@P~=SOUY736++4nJv1Dmw^2YM{xz&kF zZQ;NCSfMqH@tv8Or5~@Zd@$1%o^m4+Xhi;s$@WMi-3X}&F=WX|1e>&)mK2jlk|3Jy z?z1r|ttV8)q%<8x9A-_$cUa$OLP;Yz5e{!0iN38#NQ=fsN8^Gb$0bFMN@6A|$daOy zZy$_i^h8pNmP14$BcVg-5wmueAfbKODsfG_g30@!=%5+@9}SUft;XRua{G_v8+r^j zRP>OyT&)pk`kI=R3*6CLTvv|k%5&WY+x_=lFYpD{fCJ00)fapp`;2|B&Yzi&8Np)( zw&%BMZrpXR$YA!pyFTCxR!Vjmue@V)oiOy%Q>A*)6(U0}~_QQcTSfE_$n z^E~+c$&PyPt-GU+nhSLVsD%K7;X=K;(@!lt*VO5ye)2LHKdLqHp=+%U2{Nx`QYir? zMx~0PyI(3qq}=@;RB?#37({v=A{{>y!NkhP3jICm4Ecy2X>YhZxJ?bKHc$}1FINY8 z9AneJ-7u=huWO0eB~0ur4>f(2HC{ZCYd)C|^^S9Pl7D*Q%Tu$53*1Y$xb_^^p65CZ zwsW@}@0#zJf58a8R$yP>lBm1oc>8>#(cWwH3Wa{j7?AV*aYINL!NCGMv_*3RJ%PP@ zl(!F`w>3ygtH|nxcq(t35*54$PKoU~yP5M_&0`b)A#Kr9_}}hK)lyHcbO|+L(Wmjf zOHb~}?SC`h@YesNCtC??vOI6iWd3->YX+?0bBLUS5;Bh`l$gXb&zgl?iA9b?ysoNA zYfRb-r32D^1u~MX*<_Wj6%n$JBBUgqH<>g_DEbsw$5NnF^X$thRm>!%qX-}N069r% zCow5f5W+=pa1pdDg61{a3;k>LHYtVx?HeEcg{u3VcIP||c~4`34)4IByr=$Gx}oR- KbO<$LqyGR^yty?1 literal 0 HcmV?d00001