﻿{"nodes":[{"id":"N1","name":"开始","desc":"工作流开始","type":"start","action":"开始回答","output_data":{},"input_data":{},"extra":"{\"position\":{\"x\":134,\"y\":180}}","api_data":{"userInput":{"type":"string"},"appPrompt":{"type":"string"},"docFileName":{"type":"string"},"default":{"type":"object"}}},{"id":"N2","name":"LLM","desc":"将用户问题归类","type":"llm2","action":"","output_data":{"text":{"type":"string","value":""}},"input_data":{"appPrompt":{"type":"string","value":"你是一位问题分类专家，我需要你根据输入的问题给我返回相对应的内容。\n# 规则\n1.如果用户的内容涉及“请审查这份合同”、“请检查”、“评审”或涉及关于规则的说法，\n请给我返回\"check\"\n2.如果用户的内容不涉及第一点的内容，不涉及“请审查这份合同”、“请检查”、“评审”或让你帮忙评审这份合同相类似的说法，\n请给我返回\"info\"\n你返回的内容只有\"审查\"或者\"提取\"，我不需要你返回除此之外任何其他的内容"},"userInput":{"type":"flow","value":"N1.userInput"}},"extra":"{\"position\":{\"x\":464,\"y\":52}}","reply":null,"option":{"llm":"GLM-4-Flash","system":"{{appPrompt}}","user":"{{userInput}}","history":0,"chunks":null,"prompt":"<角色>\n你是一个专业的信息助手，可以从一堆已知信息中查找到\n用户问题相关的信息，并根据相关信息回答用户的问题。你的回答非常简洁、干练。不要解释。不要回复与问题无关的内容。尽快结束回答。\n<注意>\n1、如果相关信息中不存在用户问题相关的内容，请告知用户你没有找到相关内容，让他换个问题试试。\n2、如果相关内容存在链接，请按原文输出带hw-L标记的链接。\n3、如果相关内容不存在链接，不要输出，也不要编造\n\n已知信息:\n{{chunks}}","reply_quote":false}},{"id":"N3","name":"文件获取","desc":"从文件服务中获取文件","type":"file_get","action":"","output_data":{"filePath":{"type":"string","value":""}},"input_data":{},"extra":"{\"position\":{\"x\":507.63901582154574,\"y\":281.6804920892271}}","reply":null,"option":{"docFileName":"N1.docFileName"}},{"id":"N4","name":"代码执行","desc":"获取文件全文信息","type":"code","action":"","output_data":{"result":{"type":"string"},"error":{"type":"string"}},"input_data":{"filePath":{"type":"flow","value":"N3.filePath"},"default":{"type":"flow","value":"N1.default"}},"extra":"{\"position\":{\"x\":865,\"y\":305}}","reply":null,"option":{"timeout":300,"lang":"python3","code":"def str_func(filePath, default):\r\n    from docx import Document\r\n    import io\r\n\r\n    def get_text_from_paragraph(paragraph):\r\n        paragraph_text = paragraph.text\r\n        # 处理段落中的运行对象(包括控件)\r\n        for run in paragraph._element.xpath('.//w:sdt//w:t'):\r\n            if run.text:\r\n                paragraph_text += run.text\r\n        return paragraph_text\r\n      \r\n    error_text = ''\r\n    text = []\r\n    # 区分pdf和docx\r\n    if filePath.endswith('.pdf'):\r\n      import requests\r\n      url = 'http://chat-knowledge-service/api/document/doc2text'\r\n      files = {'file': open(filePath, 'rb')}\r\n      # 添加请求头\r\n      headers = {'Authorization': default['token']}\r\n      response = requests.post(url, files=files, headers=headers)\r\n      # print(response.json())\r\n      if 'data' in response.json() and 'text' in response.json()['data']:\r\n          text.append(response.json()['data']['text'])\r\n      else:\r\n          error_text = \"pdf转换失败:\" + str(response.json())\r\n          text.append('')\r\n    else:\r\n        doc = Document(filePath)\r\n        # 迭代文档中的每个段落\r\n        for paragraph in doc.paragraphs:\r\n            text.append(get_text_from_paragraph(paragraph))\r\n    \r\n        for table in doc.tables:\r\n            text.append(\"|\")\r\n            # 表头\r\n            headers = []\r\n            for cell in table.rows[0].cells:\r\n                cell_text = \"\"\r\n                for paragraph in cell.paragraphs:\r\n                    cell_text += get_text_from_paragraph(paragraph)\r\n                headers.append(cell_text)\r\n            text.append(\" | \".join(headers))\r\n            text.append(\"|\" + \"---|\" * len(headers))\r\n            # 表格数据\r\n            for row in table.rows[1:]:\r\n                row_data = []\r\n                for cell in row.cells:\r\n                    cell_text = \"\"\r\n                    for paragraph in cell.paragraphs:\r\n                        cell_text += get_text_from_paragraph(paragraph)\r\n                    row_data.append(cell_text)\r\n                text.append(\"| \" + \" | \".join(row_data) + \" |\")\r\n    return  {\"result\": '\\n'.join(text), \"error\": error_text}"}},{"id":"N5","name":"分支控制","desc":"根据分类控制所走分支","type":"code_classify","action":"","output_data":{"check":{"type":"object"},"info":{"type":"object"}},"input_data":{"text":{"type":"flow","value":"N2.text"}},"extra":"{\"position\":{\"x\":1222.1401155275396,\"y\":39.70538128948189}}","reply":null,"option":{"timeout":300,"lang":"python3","code":"def str_func(text):\n    if 'check' in text:\n        return {\"check\":\"check\"}\n    if 'info' in text:\n        return {\"info\":\"info\"}"}},{"id":"N6","name":"LLM","desc":"合同审查","type":"llm2","action":"","output_data":{"text":{"type":"string","value":""}},"input_data":{"appPrompt":{"type":"string","value":"# 注意\n1.你是一个专业的纠错专家，请严格根据用户提出的规则对内容指出需要修改的地方。\n2.默认规则无论什么时候都需要进行检查。\n2.我不需要你对内容进行推断。\n3.你需要对每一条规则都进行评审。\n4.我不需要你对内容的格式以及规范上进行评审，请根据规则专注在内容上进行评审。\n5.如果是无需修改的规则则不用返回。\n6.如果判断出需要修改，但是文档内又没有这一类的信息，请不要胡编乱造。\n\n\n# 审查规则，请无论什么情况都需要检查以下的规则并给出结论:\n文本中出现的拼写错误、用词不当、多余的字或缺失的字等问题\n句子结构不符合语法规则，导致意义模糊或难以理解\n检查合同中的每一项信息项，如果有为空的情况需要提示，为空的情况就是如果是:后面没有内容并且进行换行，就代表为空\n有金额的地方，必须有小写和大写，且数字必须相同\n所有的“甲方”，其名称必须相同(如果\"甲方\"信息未填写，则不用判断)\n所有的“乙方”，其名称必须相同(如果\"乙方\"信息未填写，则不用判断)\n合同总价必须等于各分项价格之和\n如果有手机或者手机号码等信息，检查是否为11位；（若检查出手机号信息位数不对，你只需要告诉我号码错误，多了还是少了，请不要自己补充胡编乱造)\n\n\n##  账号信息检查\n如果用户输入了有关甲方乙方的账号信息,请添加以下审查规则进行检查，如果没有则不用检查:\n检查甲方开票信息是否正确；\n判断合同中是否有收款账号信息，如果没有要求补充；\n检查乙方账号信息是否正确；\n\n## 在内容最后严格按照以下格式下一个结论，\"需要修改为:\"后面的内容需要进行加粗，注意不是全部加粗，而是在需要修改的内容上要加粗：\n1.依据规则\"xxx\",\"xxx\"需要修改为：xxx\n判断原因:xxx\n\n## 需要检查合同中的每一项信息项，如果有为空的情况需要提示\n例如:\n给出的审查内容是:甲方：\\n法定代表人：\\n地址：\\n\\n乙方：\\n法定代表人：\\n地址：\\n\\n鉴于：\\n1、甲方拟为某客户（以下简称“客户”）开发、建设专利大模型系统\\n2、甲方拟将该系统的部分工作委托给乙方开展\\n3、客户要求甲方提前投入，并在2024年9月30日前上线该系统的临时版本（以下简称“临时系统”）\n代表甲方，法定代表人，乙方，地址为空，你需要返回“依据规则\"需要检查合同中的每一项信息项，如果有为空的情况需要提示\",甲方，法定代表人，乙方，地址为空需要进行补充”\n\n这里给出一个例子，按照这个格式回复，\"需要修改为:\"后面的内容需要进行加粗，注意不是全部加粗，而是在需要修改的内容上要加粗。\n1.依据规则\"所有的“甲方”，其名称必须相同\",\"名称：广州华微明天软件技术有限公司\"需要修改为：xxx\n判断原因:xxx<br><br>\n2.依据规则\"检查乙方账号信息是否正确；\",\"乙方收款账户信息的名称\"需要修改为：xxx\n判断原因:xxx<br><br>"},"userInput":{"type":"flow","value":"N4.result"}},"extra":"{\"position\":{\"x\":1610.3496640806754,\"y\":-77.89926282715652}}","reply":[],"option":{"llm":"GLM-4-Flash","system":"{{appPrompt}}","user":"{{userInput}}","history":0,"chunks":null,"prompt":"<角色>\n你是一个专业的信息助手，可以从一堆已知信息中查找到\n用户问题相关的信息，并根据相关信息回答用户的问题。你的回答非常简洁、干练。不要解释。不要回复与问题无关的内容。尽快结束回答。\n<注意>\n1、如果相关信息中不存在用户问题相关的内容，请告知用户你没有找到相关内容，让他换个问题试试。\n2、如果相关内容存在链接，请按原文输出带hw-L标记的链接。\n3、如果相关内容不存在链接，不要输出，也不要编造\n\n已知信息:\n{{chunks}}","reply_quote":false}},{"id":"N7","name":"LLM","desc":"合同信息提取","type":"llm2","action":"","output_data":{"text":{"type":"string","value":""}},"input_data":{"appPrompt":{"type":"string","value":"你是一名信息提取专家，请你根据用户需要提取的内容在给出的文本内容中提取出来。并且尽量联系上下文告诉我信息的大概位置。"},"userInput":{"type":"flow","value":"N4.result"}},"extra":"{\"position\":{\"x\":1585.799860218957,\"y\":214.73744544888717}}","reply":[],"option":{"llm":"GLM-4-Flash","system":"{{appPrompt}}","user":"{{userInput}}","history":0,"chunks":null,"prompt":"<角色>\n你是一个专业的信息助手，可以从一堆已知信息中查找到\n用户问题相关的信息，并根据相关信息回答用户的问题。你的回答非常简洁、干练。不要解释。不要回复与问题无关的内容。尽快结束回答。\n<注意>\n1、如果相关信息中不存在用户问题相关的内容，请告知用户你没有找到相关内容，让他换个问题试试。\n2、如果相关内容存在链接，请按原文输出带hw-L标记的链接。\n3、如果相关内容不存在链接，不要输出，也不要编造\n\n已知信息:\n{{chunks}}","reply_quote":false}}],"edges":[{"id":"N1-N2","source":"N1","target":"N2","source_id":"1","target_id":"0"},{"id":"N1-N3","source":"N1","target":"N3","source_id":"1","target_id":"0"},{"id":"N3-N4","source":"N3","target":"N4","source_id":"1","target_id":"0"},{"id":"N2-N5","source":"N2","target":"N5","source_id":"1","target_id":"0"},{"id":"N4-N5","source":"N4","target":"N5","source_id":"1","target_id":"0"},{"id":"N5_case1-N6","source":"N5","target":"N6","source_id":"check","target_id":"0"},{"id":"N5_case2-N7","source":"N5","target":"N7","source_id":"info","target_id":"0"}],"extra":{"max_id":7,"viewport":{"x":26.6521262924407,"y":200.37556044771384,"zoom":0.7578582832551991}}}