Showing
4 changed files
with
221 additions
and
29 deletions
| ... | @@ -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.21e3deecca904c7697ab891b8276cf36"), | 16 | + "Authorization": os.getenv("API_AUTHORIZATION", "Bearer 2.bd593d8f36c4468fbf02ee95c473cbb6"), |
| 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 | } | ... | ... |
| ... | @@ -103,3 +103,79 @@ def upload_clearance_file( | ... | @@ -103,3 +103,79 @@ def upload_clearance_file( |
| 103 | return f"上传清关文件失败: {str(e)}" | 103 | return f"上传清关文件失败: {str(e)}" |
| 104 | 104 | ||
| 105 | 105 | ||
| 106 | +def upload_file_for_ocr( | ||
| 107 | + pdf_path: str, | ||
| 108 | + Authorization: Optional[str] = None, | ||
| 109 | +) -> str: | ||
| 110 | + """上传文件进行OCR识别 | ||
| 111 | + | ||
| 112 | + Args: | ||
| 113 | + pdf_path: 本地 PDF 文件路径(必填) | ||
| 114 | + Authorization: 授权令牌,如果提供则使用该值,否则使用 API_CONFIG 中的默认值 | ||
| 115 | + | ||
| 116 | + Returns: | ||
| 117 | + 文本:成功/失败信息 | ||
| 118 | + """ | ||
| 119 | + if not os.path.isfile(pdf_path): | ||
| 120 | + return f"参数错误: 文件不存在 - {pdf_path}" | ||
| 121 | + | ||
| 122 | + # 从文件路径提取文件名 | ||
| 123 | + file_name = os.path.basename(pdf_path) | ||
| 124 | + | ||
| 125 | + # 构建URL(不包含查询参数) | ||
| 126 | + url = f"{API_CONFIG['base_url']}/API/ocrDemo/pushDemo" | ||
| 127 | + | ||
| 128 | + # 封装参数到 params_payload | ||
| 129 | + params_payload = { | ||
| 130 | + "fileName01": file_name, | ||
| 131 | + "fileNumber": 1 | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + # form-data: params 是 JSON 字符串,fileUpload 是文件 | ||
| 135 | + data = { | ||
| 136 | + "params": json.dumps(params_payload, ensure_ascii=False), | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + files = { | ||
| 140 | + "file": (file_name, open(pdf_path, "rb"), "application/pdf"), | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + # 构建 headers,优先使用传入的 Authorization | ||
| 144 | + headers = dict(API_CONFIG.get("headers", {})) | ||
| 145 | + if Authorization: | ||
| 146 | + headers['Authorization'] = Authorization | ||
| 147 | + # 移除 Content-Type(由 requests 根据 multipart 自动设置) | ||
| 148 | + headers.pop("Content-Type", None) | ||
| 149 | + | ||
| 150 | + try: | ||
| 151 | + resp = requests.post(url, headers=headers, data=data, files=files, timeout=60) | ||
| 152 | + # 确保文件句柄尽快关闭 | ||
| 153 | + try: | ||
| 154 | + files["file"][1].close() | ||
| 155 | + except Exception: | ||
| 156 | + pass | ||
| 157 | + | ||
| 158 | + if resp.status_code == 200: | ||
| 159 | + # 解析响应JSON | ||
| 160 | + result = resp.json() | ||
| 161 | + | ||
| 162 | + # 提取指定字段,只返回 status、message、chmCode、chmId | ||
| 163 | + filtered_result = {} | ||
| 164 | + if "status" in result: | ||
| 165 | + filtered_result["status"] = result["status"] | ||
| 166 | + if "message" in result: | ||
| 167 | + filtered_result["message"] = result["message"] | ||
| 168 | + if "chmCode" in result: | ||
| 169 | + filtered_result["chmCode"] = result["chmCode"] | ||
| 170 | + if "chmId" in result: | ||
| 171 | + filtered_result["chmId"] = result["chmId"] | ||
| 172 | + | ||
| 173 | + # 返回过滤后的JSON字符串 | ||
| 174 | + return json.dumps(filtered_result, ensure_ascii=False) | ||
| 175 | + return f"上传失败: HTTP {resp.status_code}, 错误信息: {resp.text}" | ||
| 176 | + | ||
| 177 | + except requests.exceptions.RequestException as e: | ||
| 178 | + return f"网络请求失败: {str(e)}" | ||
| 179 | + except Exception as e: | ||
| 180 | + return f"上传文件进行OCR识别失败: {str(e)}" | ||
| 181 | + | ... | ... |
| ... | @@ -133,6 +133,70 @@ def create_waybill_d(consignmentCode: str, Authorization: str = None) -> str: | ... | @@ -133,6 +133,70 @@ def create_waybill_d(consignmentCode: str, Authorization: str = None) -> str: |
| 133 | return f"❌ 创建D类运单失败: {str(e)}" | 133 | return f"❌ 创建D类运单失败: {str(e)}" |
| 134 | 134 | ||
| 135 | 135 | ||
| 136 | +def create_waybill_d_with_id( | ||
| 137 | + consignmentCode: str, | ||
| 138 | + consignmentId: str, | ||
| 139 | + loginName: str, | ||
| 140 | + userId: int, | ||
| 141 | + Authorization: str = None, | ||
| 142 | +) -> str: | ||
| 143 | + """根据运单ID及运单号创建D类运单 | ||
| 144 | + | ||
| 145 | + Args: | ||
| 146 | + consignmentCode: 运单号(必填) | ||
| 147 | + consignmentId: 运单ID(必填) | ||
| 148 | + loginName: 登录名(必填) | ||
| 149 | + userId: 用户ID(必填) | ||
| 150 | + Authorization: 授权令牌,如果提供则使用该值,否则使用 API_CONFIG 中的默认值 | ||
| 151 | + | ||
| 152 | + Returns: | ||
| 153 | + 创建结果,成功时返回序列化的JSON,失败时返回错误信息 | ||
| 154 | + """ | ||
| 155 | + try: | ||
| 156 | + url = f"{API_CONFIG['base_url']}/Exp/bus-customer/consignment/createChmConsignmentD/demo" | ||
| 157 | + | ||
| 158 | + # 构建请求数据 | ||
| 159 | + data = { | ||
| 160 | + "consignmentCode": consignmentCode, | ||
| 161 | + "consignmentId": consignmentId, | ||
| 162 | + "isAIRecognition": 1, # 写死为1 | ||
| 163 | + "loginName": loginName, | ||
| 164 | + "userId": userId | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + # 构建 headers,优先使用传入的 Authorization | ||
| 168 | + headers = dict(API_CONFIG['headers']) | ||
| 169 | + if Authorization: | ||
| 170 | + headers['Authorization'] = Authorization | ||
| 171 | + | ||
| 172 | + # 发送POST请求 | ||
| 173 | + response = requests.post( | ||
| 174 | + url, | ||
| 175 | + headers=headers, | ||
| 176 | + json=data, | ||
| 177 | + timeout=30 | ||
| 178 | + ) | ||
| 179 | + | ||
| 180 | + # 检查响应状态 | ||
| 181 | + if response.status_code == 200: | ||
| 182 | + result = response.json() | ||
| 183 | + # 提取运单ID | ||
| 184 | + data = result.get('data') or {} | ||
| 185 | + extra = data.get('extra') or {} | ||
| 186 | + waybill_id = extra.get('id') | ||
| 187 | + if waybill_id is not None: | ||
| 188 | + return waybill_id # 返回数字格式的运单ID | ||
| 189 | + return f"❌ 创建失败: 响应中未找到运单ID" | ||
| 190 | + return f"❌ 创建失败: HTTP {response.status_code}, 错误信息: {response.text}" | ||
| 191 | + | ||
| 192 | + except requests.exceptions.RequestException as e: | ||
| 193 | + return f"❌ 网络请求失败: {str(e)}" | ||
| 194 | + except json.JSONDecodeError as e: | ||
| 195 | + return f"❌ 响应解析失败: {str(e)}" | ||
| 196 | + except Exception as e: | ||
| 197 | + return f"❌ 创建D类运单失败: {str(e)}" | ||
| 198 | + | ||
| 199 | + | ||
| 136 | def query_waybill_info(consignmentCode: str, Authorization: str = None) -> str: | 200 | def query_waybill_info(consignmentCode: str, Authorization: str = None) -> str: |
| 137 | """根据运单编号查询运单信息 | 201 | """根据运单编号查询运单信息 |
| 138 | 202 | ... | ... |
| ... | @@ -12,8 +12,8 @@ from langchain_core.messages import AnyMessage | ... | @@ -12,8 +12,8 @@ from langchain_core.messages import AnyMessage |
| 12 | sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | 12 | sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
| 13 | 13 | ||
| 14 | # 导入 API 模块 | 14 | # 导入 API 模块 |
| 15 | -from API.waybill_api import query_waybill_list, create_waybill_d, push_waybill_for_ocr, query_waybill_info | 15 | +from API.waybill_api import query_waybill_list, create_waybill_d, push_waybill_for_ocr, query_waybill_info, create_waybill_d_with_id |
| 16 | -from API.paperless_api import upload_clearance_file | 16 | +from API.paperless_api import upload_clearance_file, upload_file_for_ocr |
| 17 | 17 | ||
| 18 | # 导入工具类 | 18 | # 导入工具类 |
| 19 | from langgraph_examples.utils.message_processor import MessageProcessor | 19 | from langgraph_examples.utils.message_processor import MessageProcessor |
| ... | @@ -91,20 +91,28 @@ def pre_model_inspect_attachments(state, **kwargs): | ... | @@ -91,20 +91,28 @@ def pre_model_inspect_attachments(state, **kwargs): |
| 91 | return {} | 91 | return {} |
| 92 | 92 | ||
| 93 | 93 | ||
| 94 | -def extract_token(state: Dict[str, Any]) -> str: | 94 | +def extract_token(state: Dict[str, Any]) -> Dict[str, Any]: |
| 95 | """ | 95 | """ |
| 96 | - 从 state 中提取 token | 96 | + 从 state 中提取参数 |
| 97 | - 获取最后一个类型为 HumanMessage 或 human 的消息中的 token | 97 | + 获取最后一个类型为 HumanMessage 或 human 的消息中的参数(token、consignmentCode、consignmentId、loginName、userId) |
| 98 | 98 | ||
| 99 | Args: | 99 | Args: |
| 100 | state: LangGraph 状态字典,包含 messages 数组 | 100 | state: LangGraph 状态字典,包含 messages 数组 |
| 101 | 101 | ||
| 102 | Returns: | 102 | Returns: |
| 103 | - token 字符串,如果未找到则返回空字符串 | 103 | + 包含所有参数的字典,如果未找到则返回空字符串或None |
| 104 | """ | 104 | """ |
| 105 | + result = { | ||
| 106 | + "token": "", | ||
| 107 | + "consignmentCode": None, | ||
| 108 | + "consignmentId": None, | ||
| 109 | + "loginName": None, | ||
| 110 | + "userId": None | ||
| 111 | + } | ||
| 112 | + | ||
| 105 | messages = state.get("messages", []) | 113 | messages = state.get("messages", []) |
| 106 | if not messages: | 114 | if not messages: |
| 107 | - return "" | 115 | + return result |
| 108 | 116 | ||
| 109 | # 找到所有 is_human 类型的消息 | 117 | # 找到所有 is_human 类型的消息 |
| 110 | human_messages = [] | 118 | human_messages = [] |
| ... | @@ -122,32 +130,45 @@ def extract_token(state: Dict[str, Any]) -> str: | ... | @@ -122,32 +130,45 @@ def extract_token(state: Dict[str, Any]) -> str: |
| 122 | 130 | ||
| 123 | # 如果没有 human 消息,直接返回 | 131 | # 如果没有 human 消息,直接返回 |
| 124 | if not human_messages: | 132 | if not human_messages: |
| 125 | - return "" | 133 | + return result |
| 126 | 134 | ||
| 127 | # 直接取最后一个 human 消息(不需要循环判断) | 135 | # 直接取最后一个 human 消息(不需要循环判断) |
| 128 | last_human_msg = human_messages[-1] | 136 | last_human_msg = human_messages[-1] |
| 129 | 137 | ||
| 130 | - # 从 content 中提取 token | 138 | + # 从 content 中提取参数 |
| 131 | if isinstance(last_human_msg, dict): | 139 | if isinstance(last_human_msg, dict): |
| 132 | content = last_human_msg.get("content") | 140 | content = last_human_msg.get("content") |
| 133 | else: | 141 | else: |
| 134 | content = getattr(last_human_msg, "content", None) | 142 | content = getattr(last_human_msg, "content", None) |
| 135 | 143 | ||
| 136 | if isinstance(content, list): | 144 | if isinstance(content, list): |
| 137 | - # content 是列表,遍历查找包含 token 的 part | 145 | + # content 是列表,遍历查找包含参数的 part |
| 138 | for part in content: | 146 | for part in content: |
| 139 | - if isinstance(part, dict) and "token" in part: | 147 | + if isinstance(part, dict): |
| 140 | - token = part.get("token") | 148 | + if "token" in part and part.get("token"): |
| 141 | - if token: | 149 | + result["token"] = part.get("token") |
| 142 | - return token | 150 | + if "consignmentCode" in part: |
| 151 | + result["consignmentCode"] = part.get("consignmentCode") | ||
| 152 | + if "consignmentId" in part: | ||
| 153 | + result["consignmentId"] = part.get("consignmentId") | ||
| 154 | + if "loginName" in part: | ||
| 155 | + result["loginName"] = part.get("loginName") | ||
| 156 | + if "userId" in part: | ||
| 157 | + result["userId"] = part.get("userId") | ||
| 143 | elif isinstance(content, dict): | 158 | elif isinstance(content, dict): |
| 144 | - # content 是字典,直接获取 token | 159 | + # content 是字典,直接获取参数 |
| 145 | - if "token" in content: | 160 | + if "token" in content and content.get("token"): |
| 146 | - token = content.get("token") | 161 | + result["token"] = content.get("token") |
| 147 | - if token: | 162 | + if "consignmentCode" in content: |
| 148 | - return token | 163 | + result["consignmentCode"] = content.get("consignmentCode") |
| 164 | + if "consignmentId" in content: | ||
| 165 | + result["consignmentId"] = content.get("consignmentId") | ||
| 166 | + if "loginName" in content: | ||
| 167 | + result["loginName"] = content.get("loginName") | ||
| 168 | + if "userId" in content: | ||
| 169 | + result["userId"] = content.get("userId") | ||
| 149 | 170 | ||
| 150 | - return "" | 171 | + return result |
| 151 | 172 | ||
| 152 | def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List[AnyMessage]: | 173 | def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List[AnyMessage]: |
| 153 | """ | 174 | """ |
| ... | @@ -166,14 +187,23 @@ def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List | ... | @@ -166,14 +187,23 @@ def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List |
| 166 | # print(f"state keys: {list(state.keys()) if isinstance(state, dict) else 'not a dict'}") | 187 | # print(f"state keys: {list(state.keys()) if isinstance(state, dict) else 'not a dict'}") |
| 167 | 188 | ||
| 168 | # 从 state 中提取动态参数 | 189 | # 从 state 中提取动态参数 |
| 169 | - token = extract_token(state) | 190 | + params = extract_token(state) |
| 191 | + token = params.get("token", "") | ||
| 192 | + consignmentCode = params.get("consignmentCode") | ||
| 193 | + consignmentId = params.get("consignmentId") | ||
| 194 | + loginName = params.get("loginName") | ||
| 195 | + userId = params.get("userId") | ||
| 170 | 196 | ||
| 171 | # 如果从 state 中提取的 token 为空,则从 api_config.py 中获取 Authorization 作为备选 | 197 | # 如果从 state 中提取的 token 为空,则从 api_config.py 中获取 Authorization 作为备选 |
| 172 | if not token: | 198 | if not token: |
| 173 | from API.api_config import API_CONFIG | 199 | from API.api_config import API_CONFIG |
| 174 | token = API_CONFIG.get("headers", {}).get("Authorization", "") | 200 | token = API_CONFIG.get("headers", {}).get("Authorization", "") |
| 175 | - # | 201 | + |
| 176 | - # print(f"提取到的 token: {token[:30] if token else 'None'}...") | 202 | + # 格式化参数值用于提示词显示 |
| 203 | + consignmentCode_str = str(consignmentCode) if consignmentCode is not None else "无" | ||
| 204 | + consignmentId_str = str(consignmentId) if consignmentId is not None else "无" | ||
| 205 | + loginName_str = str(loginName) if loginName is not None else "无" | ||
| 206 | + userId_str = str(userId) if userId is not None else "无" | ||
| 177 | 207 | ||
| 178 | # 创建系统提示词(使用 f-string 以便插入 token) | 208 | # 创建系统提示词(使用 f-string 以便插入 token) |
| 179 | system_msg = f"""你是一个专业的出口物流系统智能助手,专门帮助用户处理运单相关的业务操作。 | 209 | system_msg = f"""你是一个专业的出口物流系统智能助手,专门帮助用户处理运单相关的业务操作。 |
| ... | @@ -183,9 +213,16 @@ def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List | ... | @@ -183,9 +213,16 @@ def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List |
| 183 | - **查询运单列表**:当用户查询运单但不提供运单号时,使用 query_waybill_list 查询运单列表,支持按状态、时间等条件筛选,结果以JSON形式展示,AI不用对返回数据JSON进行加工 | 213 | - **查询运单列表**:当用户查询运单但不提供运单号时,使用 query_waybill_list 查询运单列表,支持按状态、时间等条件筛选,结果以JSON形式展示,AI不用对返回数据JSON进行加工 |
| 184 | - **查询单个运单详情**:当用户提供运单号查询时,使用 query_waybill_info 查询该运单的详细信息(包括运单基本信息、公司信息、商品明细等),返回格式与 create_waybill_d 相同 | 214 | - **查询单个运单详情**:当用户提供运单号查询时,使用 query_waybill_info 查询该运单的详细信息(包括运单基本信息、公司信息、商品明细等),返回格式与 create_waybill_d 相同 |
| 185 | 2. **运单创建**:协助用户创建D类运单,确保信息完整准确 | 215 | 2. **运单创建**:协助用户创建D类运单,确保信息完整准确 |
| 186 | - - **重要说明**:当用户输入"创建运单"或"申报"时,都理解为"创建运单"操作,应调用 create_waybill_d 工具 | 216 | + - **优先级规则**:当用户输入"创建运单"或"申报"时,首先检查提示词中是否已有 consignmentCode、consignmentId、loginName、userId 且都不为None |
| 187 | -3. **业务咨询**:解答用户关于出口物流流程、运单状态、操作规范等问题 | 217 | + - **如果提示词中有这些参数且都不为None**:必须使用 create_waybill_d_with_id 工具创建运单,参数从提示词中获取 |
| 188 | -4. **您当前访问工具Authorization的传参为 Authorization= {token} | 218 | + - **如果提示词中没有这些参数或为None**:使用 create_waybill_d 工具,运单编号需要从用户输入中获取 |
| 219 | + - **create_waybill_d**:根据运单号创建D类运单,运单编号需要从用户输入中获取,不是从提示词中获取。仅在提示词中没有 consignmentCode、consignmentId、loginName、userId 或这些参数为None时使用 | ||
| 220 | + - **create_waybill_d_with_id**:根据运单ID及运单号创建D类运单,参数从提示词中获取(consignmentCode、consignmentId、loginName、userId),不需要用户再次输入。当提示词中这些参数齐全且都不为None时,必须使用此工具 | ||
| 221 | +3. **文件上传**:根据用户需求上传文件 | ||
| 222 | + - **上传清关文件**:当用户需要上传清关文件并关联运单信息(code、slip_id)时,使用 upload_clearance_file 工具 | ||
| 223 | + - **上传文件进行OCR识别**:当用户只有一个上传文件地址,需要直接进行OCR识别时,使用 upload_file_for_ocr 工具 | ||
| 224 | +4. **业务咨询**:解答用户关于出口物流流程、运单状态、操作规范等问题 | ||
| 225 | +5. **您当前访问工具Authorization的传参为 Authorization= {token} | ||
| 189 | 226 | ||
| 190 | ## 工作原则: | 227 | ## 工作原则: |
| 191 | - 上传时文件路径不用确认,路径肯定是完整的,文件肯定是存在的,不用确认文件索引,工具会自动设置索引为0,请直接调用工具接口 | 228 | - 上传时文件路径不用确认,路径肯定是完整的,文件肯定是存在的,不用确认文件索引,工具会自动设置索引为0,请直接调用工具接口 |
| ... | @@ -203,8 +240,17 @@ def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List | ... | @@ -203,8 +240,17 @@ def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List |
| 203 | - query_waybill_info: 根据运单编号查询单个运单的详细信息(包括运单基本信息、公司信息、商品明细等),需要提供参数(运单编号、Authorization),返回格式与 create_waybill_d 相同 | 240 | - query_waybill_info: 根据运单编号查询单个运单的详细信息(包括运单基本信息、公司信息、商品明细等),需要提供参数(运单编号、Authorization),返回格式与 create_waybill_d 相同 |
| 204 | - **使用场景**:当用户提供运单号查询运单详情时使用此工具 | 241 | - **使用场景**:当用户提供运单号查询运单详情时使用此工具 |
| 205 | - create_waybill_d: 根据运单号创建D类运单,需要提供参数(运单号、Authorization) | 242 | - create_waybill_d: 根据运单号创建D类运单,需要提供参数(运单号、Authorization) |
| 206 | - - **注意**:当用户说"创建运单"或"申报"时,都应调用此工具 | 243 | + - **使用场景**:当用户输入"创建运单"或"申报"时,仅在提示词中没有 consignmentCode、consignmentId、loginName、userId 或这些参数为None时使用此工具 |
| 244 | + - **重要说明**:运单编号需要从用户输入中获取,不是从提示词中获取 | ||
| 245 | + - **优先级**:如果提示词中已有 consignmentCode、consignmentId、loginName、userId 且都不为None,则不应使用此工具,应使用 create_waybill_d_with_id | ||
| 246 | +- create_waybill_d_with_id: 根据运单ID及运单号创建D类运单,需要提供参数(运单编号、运单ID、登录名、用户ID、Authorization) | ||
| 247 | + - **使用场景**:当用户输入"创建运单"或"申报"时,如果提示词中已经有了 consignmentCode、consignmentId、loginName、userId,并且这几个参数都不为None,那么必须调用此工具创建运单 | ||
| 248 | + - **重要说明**:此工具的参数从提示词中获取,不需要用户再次输入。当提示词中这些参数齐全且都不为None时,必须优先使用此工具,而不是 create_waybill_d | ||
| 249 | + - **可用参数**:您当前访问工具 create_waybill_d_with_id 的传参为 consignmentCode={consignmentCode_str}、consignmentId={consignmentId_str}、loginName={loginName_str}、userId={userId_str},如果参数有值则使用,没有值则不使用 | ||
| 207 | - upload_clearance_file: 上传清关PDF文件,需要 code、slip_id、pdf_path、Authorization,上传时文件路径不用确认,路径肯定是完整的,文件肯定是存在的,不用确认文件索引,工具会自动设置索引为0,请直接调用工具接口 | 250 | - upload_clearance_file: 上传清关PDF文件,需要 code、slip_id、pdf_path、Authorization,上传时文件路径不用确认,路径肯定是完整的,文件肯定是存在的,不用确认文件索引,工具会自动设置索引为0,请直接调用工具接口 |
| 251 | + - **使用场景**:当用户需要上传清关文件并关联运单信息(code、slip_id)时使用此工具 | ||
| 252 | +- upload_file_for_ocr: 上传文件进行OCR识别,只需要提供文件路径(pdf_path、Authorization),上传时文件路径不用确认,路径肯定是完整的,文件肯定是存在的,请直接调用工具接口 | ||
| 253 | + - **使用场景**:当用户只有一个上传文件地址,需要直接进行OCR识别时,使用此工具 | ||
| 208 | - push_waybill_for_ocr: 根据运单ID推送OCR进行识别,需要提供运单ID(waybill_id、Authorization)参数 | 254 | - push_waybill_for_ocr: 根据运单ID推送OCR进行识别,需要提供运单ID(waybill_id、Authorization)参数 |
| 209 | 255 | ||
| 210 | ## query_waybill_list数据展示说明: | 256 | ## query_waybill_list数据展示说明: |
| ... | @@ -219,6 +265,12 @@ def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List | ... | @@ -219,6 +265,12 @@ def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List |
| 219 | ## create_waybill_d数据展示说明: | 265 | ## create_waybill_d数据展示说明: |
| 220 | - 按照数据返回的原本格式进行展示,不得增删前后缀或改写内容。 | 266 | - 按照数据返回的原本格式进行展示,不得增删前后缀或改写内容。 |
| 221 | 267 | ||
| 268 | +## create_waybill_d_with_id数据展示说明: | ||
| 269 | +- 按照数据返回的原本格式进行展示,不得增删前后缀或改写内容。 | ||
| 270 | + | ||
| 271 | +## upload_file_for_ocr数据展示说明: | ||
| 272 | +- 按照数据返回的原本格式进行展示,不得增删前后缀或改写内容。 | ||
| 273 | + | ||
| 222 | 请根据用户的具体需求,选择合适的工具并提供帮助。""" | 274 | 请根据用户的具体需求,选择合适的工具并提供帮助。""" |
| 223 | 275 | ||
| 224 | # 返回系统消息 + 原始消息 | 276 | # 返回系统消息 + 原始消息 |
| ... | @@ -231,7 +283,7 @@ def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List | ... | @@ -231,7 +283,7 @@ def _create_system_prompt(state: Dict[str, Any], config: RunnableConfig) -> List |
| 231 | # 创建 ReAct 智能体 | 283 | # 创建 ReAct 智能体 |
| 232 | agent = create_react_agent( | 284 | agent = create_react_agent( |
| 233 | model=model, | 285 | model=model, |
| 234 | - tools=[query_waybill_list, query_waybill_info, create_waybill_d, upload_clearance_file, push_waybill_for_ocr], | 286 | + tools=[query_waybill_list, query_waybill_info, create_waybill_d, create_waybill_d_with_id, upload_clearance_file, upload_file_for_ocr, push_waybill_for_ocr], |
| 235 | pre_model_hook=pre_model_inspect_attachments, | 287 | pre_model_hook=pre_model_inspect_attachments, |
| 236 | prompt=_create_system_prompt, | 288 | prompt=_create_system_prompt, |
| 237 | ) | 289 | ) | ... | ... |
-
Please register or login to post a comment