zhouhui.jiang

update

...@@ -13,7 +13,7 @@ API_CONFIG = { ...@@ -13,7 +13,7 @@ API_CONFIG = {
13 "headers": { 13 "headers": {
14 "accept": "*/*", 14 "accept": "*/*",
15 "Content-Type": "application/json", 15 "Content-Type": "application/json",
16 - "Authorization": os.getenv("API_AUTHORIZATION", "Bearer 2.2e71fc6f79704ee0b266679e6427a28e"), 16 + "Authorization": os.getenv("API_AUTHORIZATION", "Bearer 2.70e56e690ce64cb8b1e4fc892e1b71de"),
17 "Ver": os.getenv("API_VER", "033BD94B1168D7E4F0D644C3C95E35BF.D73E33B659AD1D6B7D181D1DF8D05760"), 17 "Ver": os.getenv("API_VER", "033BD94B1168D7E4F0D644C3C95E35BF.D73E33B659AD1D6B7D181D1DF8D05760"),
18 "Referer": os.getenv("API_REFERER", "http://192.168.1.251/") 18 "Referer": os.getenv("API_REFERER", "http://192.168.1.251/")
19 } 19 }
......
...@@ -3,7 +3,9 @@ from langchain_openai import ChatOpenAI ...@@ -3,7 +3,9 @@ from langchain_openai import ChatOpenAI
3 import os 3 import os
4 import sys 4 import sys
5 import json 5 import json
6 -from typing import Dict, Any 6 +from typing import Dict, Any, List
7 +from langchain_core.runnables import RunnableConfig
8 +from langchain_core.messages import AnyMessage
7 9
8 # 添加项目根目录到 Python 路径 10 # 添加项目根目录到 Python 路径
9 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 11 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
...@@ -87,17 +89,95 @@ def pre_model_inspect_attachments(state, **kwargs): ...@@ -87,17 +89,95 @@ def pre_model_inspect_attachments(state, **kwargs):
87 traceback.print_exc() 89 traceback.print_exc()
88 return {} 90 return {}
89 91
90 -# 创建 ReAct 智能体 92 +
91 -agent = create_react_agent( 93 +def extract_token(state: Dict[str, Any]) -> str:
92 - model=model, 94 + """
93 - tools=[query_waybill_list, create_waybill_d, upload_clearance_file, push_waybill_for_ocr], 95 + 从 state 中提取 token
94 - pre_model_hook=pre_model_inspect_attachments, 96 + 获取最后一个类型为 HumanMessage 或 human 的消息中的 token
95 - prompt="""你是一个专业的出口物流系统智能助手,专门帮助用户处理运单相关的业务操作。 97 +
98 + Args:
99 + state: LangGraph 状态字典,包含 messages 数组
100 +
101 + Returns:
102 + token 字符串,如果未找到则返回空字符串
103 + """
104 + messages = state.get("messages", [])
105 + if not messages:
106 + return ""
107 +
108 + # 找到所有 is_human 类型的消息
109 + human_messages = []
110 + for msg in messages:
111 + # 兼容 dict 或 LangChain 的消息对象
112 + if isinstance(msg, dict):
113 + msg_type = msg.get("type")
114 + else:
115 + msg_type = msg.__class__.__name__
116 +
117 + # 检查是否是 human 类型的消息
118 + is_human = (msg_type == "HumanMessage" or msg_type == "human")
119 + if is_human:
120 + human_messages.append(msg)
121 +
122 + # 如果没有 human 消息,直接返回
123 + if not human_messages:
124 + return ""
125 +
126 + # 直接取最后一个 human 消息(不需要循环判断)
127 + last_human_msg = human_messages[-1]
128 +
129 + # 从 content 中提取 token
130 + if isinstance(last_human_msg, dict):
131 + content = last_human_msg.get("content")
132 + else:
133 + content = getattr(last_human_msg, "content", None)
134 +
135 + if isinstance(content, list):
136 + # content 是列表,遍历查找包含 token 的 part
137 + for part in content:
138 + if isinstance(part, dict) and "token" in part:
139 + token = part.get("token")
140 + if token:
141 + return token
142 + elif isinstance(content, dict):
143 + # content 是字典,直接获取 token
144 + if "token" in content:
145 + token = content.get("token")
146 + if token:
147 + return token
148 +
149 + return ""
150 +
151 +
152 +def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List[AnyMessage]:
153 + """
154 + 创建动态系统提示词
155 +
156 + Args:
157 + state: LangGraph 状态字典
158 + config: Runnable 配置
159 +
160 + Returns:
161 + 包含系统消息和原始消息的列表
162 + """
163 + # 从 state 中提取动态参数(目前先不提取,等后续需要时再添加)
164 + # 例如:token = state.get("token")
165 + # 例如:user_id = state.get("user_id")
166 + token = extract_token(state)
167 +
168 + # 如果从 state 中提取的 token 为空,则从 api_config.py 中获取 Authorization 作为备选
169 + if not token:
170 + from API.api_config import API_CONFIG
171 + token = API_CONFIG.get("headers", {}).get("Authorization", "")
172 +
173 + # 创建系统提示词(内容保持不变,后续可以添加动态参数)
174 + system_msg = f"""你是一个专业的出口物流系统智能助手,专门帮助用户处理运单相关的业务操作。
96 175
97 ## 你的主要职责: 176 ## 你的主要职责:
98 1. **运单查询**:根据用户需求查询运单列表,支持按状态、时间等条件筛选,结果以JSON形式展示,AI不用对返回数据JSON进行加工 177 1. **运单查询**:根据用户需求查询运单列表,支持按状态、时间等条件筛选,结果以JSON形式展示,AI不用对返回数据JSON进行加工
99 2. **运单创建**:协助用户创建D类运单,确保信息完整准确 178 2. **运单创建**:协助用户创建D类运单,确保信息完整准确
100 -4. **业务咨询**:解答用户关于出口物流流程、运单状态、操作规范等问题 179 +3. **业务咨询**:解答用户关于出口物流流程、运单状态、操作规范等问题
180 +4. **您当前访问工具的权限值为 Authorization: {token}**
101 181
102 ## 工作原则: 182 ## 工作原则:
103 - 上传时文件路径不用确认,路径肯定是完整的,文件肯定是存在的,不用确认文件索引,工具会自动设置索引为0,请直接调用工具接口 183 - 上传时文件路径不用确认,路径肯定是完整的,文件肯定是存在的,不用确认文件索引,工具会自动设置索引为0,请直接调用工具接口
...@@ -107,7 +187,7 @@ agent = create_react_agent( ...@@ -107,7 +187,7 @@ agent = create_react_agent(
107 - 如遇到错误,主动分析原因并提供解决方案 187 - 如遇到错误,主动分析原因并提供解决方案
108 - 保持专业、友好的沟通态度 188 - 保持专业、友好的沟通态度
109 - 严禁改写工具函数返回的文本格式;对工具输出仅直接转述,不得增删前后缀或改写内容。 189 - 严禁改写工具函数返回的文本格式;对工具输出仅直接转述,不得增删前后缀或改写内容。
110 - - 若调用了工具并获得结果,则必须将该工具返回的文本“原样作为最终答复”输出,不允许添加任何解释、建议或额外文字。 190 +- 若调用了工具并获得结果,则必须将该工具返回的文本"原样作为最终答复"输出,不允许添加任何解释、建议或额外文字。
111 191
112 ## 可用工具: 192 ## 可用工具:
113 - query_waybill_list: 查询运单列表,支持按状态筛选,结果以JSON形式展示,AI不用对返回数据JSON进行加工 193 - query_waybill_list: 查询运单列表,支持按状态筛选,结果以JSON形式展示,AI不用对返回数据JSON进行加工
...@@ -122,7 +202,19 @@ agent = create_react_agent( ...@@ -122,7 +202,19 @@ agent = create_react_agent(
122 202
123 ## create_waybill_d数据展示说明: 203 ## create_waybill_d数据展示说明:
124 - 按照数据返回的原本格式进行展示,不得增删前后缀或改写内容。 204 - 按照数据返回的原本格式进行展示,不得增删前后缀或改写内容。
205 +
125 请根据用户的具体需求,选择合适的工具并提供帮助。""" 206 请根据用户的具体需求,选择合适的工具并提供帮助。"""
207 +
208 + # 返回系统消息 + 原始消息
209 + return [{"role": "system", "content": system_msg}] + state.get("messages", [])
210 +
211 +
212 +# 创建 ReAct 智能体
213 +agent = create_react_agent(
214 + model=model,
215 + tools=[query_waybill_list, create_waybill_d, upload_clearance_file, push_waybill_for_ocr],
216 + pre_model_hook=pre_model_inspect_attachments,
217 + prompt=_create_system_prompt, # 使用动态提示词函数
126 ) 218 )
127 219
128 # 如果直接运行此文件 220 # 如果直接运行此文件
......