├── output ├── docx_folder │ ├── test │ ├── demo.docx │ ├── output.docx │ ├── legal_document.docx │ └── legal_document02.docx ├── demo.pcm ├── output.wav └── json_folder │ ├── person_wkw.json │ ├── output.json │ ├── person.json │ └── person_tmp.json ├── demo.pcm ├── env.txt ├── poster.png ├── assert ├── end.jpg ├── robot.gif └── sine_wave.gif ├── documents ├── 1_技术文档.pdf ├── 2_部署文档.docx ├── 技术文档V1.0.2.docx ├── 4_1_机动车诉状-模型生成.docx └── 4_2_离婚诉状-模型生成.docx ├── __pycache__ ├── tools.cpython-38.pyc ├── json2docx.cpython-38.pyc ├── json2text.cpython-38.pyc ├── prompt_config.cpython-38.pyc ├── prompt_config_l.cpython-38.pyc └── prompt_config_l_copy.cpython-38.pyc ├── utils ├── __pycache__ │ ├── tools.cpython-38.pyc │ ├── prompt_config.cpython-38.pyc │ └── prompt_config_l.cpython-38.pyc ├── iflytek │ ├── __pycache__ │ │ ├── Spark.cpython-38.pyc │ │ ├── SparkApi.cpython-37.pyc │ │ ├── SparkApi.cpython-38.pyc │ │ ├── SparkApi.cpython-39.pyc │ │ └── SparkApi.cpython-311.pyc │ ├── 接口文档.txt │ ├── ifly_spark.py │ ├── prompt.md │ ├── app.py │ ├── main.py │ ├── test.py │ ├── SparkApi.py │ └── Spark.py ├── audio_gen │ ├── __pycache__ │ │ ├── input_audio.cpython-38.pyc │ │ └── play_audio.cpython-38.pyc │ ├── input_audio.py │ ├── gen_audio.py │ └── play_audio.py ├── prompt_config.py ├── tools.py └── prompt_config_l.py ├── scripts ├── __pycache__ │ ├── json2docx.cpython-38.pyc │ └── json2text.cpython-38.pyc ├── check_json.py ├── json2text.py └── json2docx.py ├── pages ├── 4_使用意见反馈.py ├── 3_查看历史输入.py ├── 2_法律知识汇总.py └── 1_预览诉讼文书.py ├── Readme.md ├── requirements.txt ├── .gitignore ├── law.yaml └── 0_用户聊天界面.py /output/docx_folder/test: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/demo.pcm -------------------------------------------------------------------------------- /env.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/env.txt -------------------------------------------------------------------------------- /poster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/poster.png -------------------------------------------------------------------------------- /assert/end.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/assert/end.jpg -------------------------------------------------------------------------------- /assert/robot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/assert/robot.gif -------------------------------------------------------------------------------- /output/demo.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/output/demo.pcm -------------------------------------------------------------------------------- /output/output.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/output/output.wav -------------------------------------------------------------------------------- /assert/sine_wave.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/assert/sine_wave.gif -------------------------------------------------------------------------------- /documents/1_技术文档.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/documents/1_技术文档.pdf -------------------------------------------------------------------------------- /documents/2_部署文档.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/documents/2_部署文档.docx -------------------------------------------------------------------------------- /documents/技术文档V1.0.2.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/documents/技术文档V1.0.2.docx -------------------------------------------------------------------------------- /documents/4_1_机动车诉状-模型生成.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/documents/4_1_机动车诉状-模型生成.docx -------------------------------------------------------------------------------- /documents/4_2_离婚诉状-模型生成.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/documents/4_2_离婚诉状-模型生成.docx -------------------------------------------------------------------------------- /output/docx_folder/demo.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/output/docx_folder/demo.docx -------------------------------------------------------------------------------- /output/docx_folder/output.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/output/docx_folder/output.docx -------------------------------------------------------------------------------- /__pycache__/tools.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/__pycache__/tools.cpython-38.pyc -------------------------------------------------------------------------------- /__pycache__/json2docx.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/__pycache__/json2docx.cpython-38.pyc -------------------------------------------------------------------------------- /__pycache__/json2text.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/__pycache__/json2text.cpython-38.pyc -------------------------------------------------------------------------------- /output/docx_folder/legal_document.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/output/docx_folder/legal_document.docx -------------------------------------------------------------------------------- /utils/__pycache__/tools.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/utils/__pycache__/tools.cpython-38.pyc -------------------------------------------------------------------------------- /__pycache__/prompt_config.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/__pycache__/prompt_config.cpython-38.pyc -------------------------------------------------------------------------------- /output/docx_folder/legal_document02.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/output/docx_folder/legal_document02.docx -------------------------------------------------------------------------------- /__pycache__/prompt_config_l.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/__pycache__/prompt_config_l.cpython-38.pyc -------------------------------------------------------------------------------- /scripts/__pycache__/json2docx.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/scripts/__pycache__/json2docx.cpython-38.pyc -------------------------------------------------------------------------------- /scripts/__pycache__/json2text.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/scripts/__pycache__/json2text.cpython-38.pyc -------------------------------------------------------------------------------- /utils/__pycache__/prompt_config.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/utils/__pycache__/prompt_config.cpython-38.pyc -------------------------------------------------------------------------------- /utils/iflytek/__pycache__/Spark.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/utils/iflytek/__pycache__/Spark.cpython-38.pyc -------------------------------------------------------------------------------- /__pycache__/prompt_config_l_copy.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/__pycache__/prompt_config_l_copy.cpython-38.pyc -------------------------------------------------------------------------------- /utils/__pycache__/prompt_config_l.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/utils/__pycache__/prompt_config_l.cpython-38.pyc -------------------------------------------------------------------------------- /utils/iflytek/__pycache__/SparkApi.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/utils/iflytek/__pycache__/SparkApi.cpython-37.pyc -------------------------------------------------------------------------------- /utils/iflytek/__pycache__/SparkApi.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/utils/iflytek/__pycache__/SparkApi.cpython-38.pyc -------------------------------------------------------------------------------- /utils/iflytek/__pycache__/SparkApi.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/utils/iflytek/__pycache__/SparkApi.cpython-39.pyc -------------------------------------------------------------------------------- /utils/iflytek/__pycache__/SparkApi.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/utils/iflytek/__pycache__/SparkApi.cpython-311.pyc -------------------------------------------------------------------------------- /utils/audio_gen/__pycache__/input_audio.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/utils/audio_gen/__pycache__/input_audio.cpython-38.pyc -------------------------------------------------------------------------------- /utils/audio_gen/__pycache__/play_audio.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phil329/lawgpt/HEAD/utils/audio_gen/__pycache__/play_audio.cpython-38.pyc -------------------------------------------------------------------------------- /utils/iflytek/接口文档.txt: -------------------------------------------------------------------------------- 1 | 星火认知大模型API调用参考文档:https://www.xfyun.cn/doc/spark/Web.html 2 | 3 | 4 | 5 | python -m pip install websocket 6 | python -m pip install websocket_client -------------------------------------------------------------------------------- /output/json_folder/person_wkw.json: -------------------------------------------------------------------------------- 1 | { 2 | "原告": [], 3 | "被告": [], 4 | "案由": null, 5 | "诉讼请求": null, 6 | "事实理由": null, 7 | "证据": null, 8 | "法院": null, 9 | "日期": "2023 08 24" 10 | } -------------------------------------------------------------------------------- /output/json_folder/output.json: -------------------------------------------------------------------------------- 1 | { 2 | "公司名称": None, 3 | "公司所在地": None, 4 | "法人": { 5 | "姓名": None, 6 | "职务": None, 7 | "联系方式": None 8 | }, 9 | "委托诉讼代理人": { 10 | "姓名": None, 11 | "事务所": None 12 | } 13 | } -------------------------------------------------------------------------------- /pages/4_使用意见反馈.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | 3 | st.title("📝 用户反馈") 4 | 5 | user_prompt = '我们非常重视您的反馈意见,请在以下输入框中提供您的宝贵意见。您的反馈将帮助我们改进产品和服务质量。谢谢!' 6 | 7 | # 反馈意见输入框 8 | feedback = st.text_area(user_prompt, height=150) 9 | 10 | # 联系方式输入框 11 | contact_info = st.text_input("请输入您的联系方式") 12 | 13 | # 提交按钮 14 | if st.button("提交"): 15 | # 在这里添加提交反馈逻辑 16 | st.write("反馈已提交!") 17 | 18 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # 法律生成文书项目 2 | 该项目是一个法律文书自动生成工具,旨在帮助律师、法律机构或个人快速生成标准化的法律文书。 3 | 4 | # 功能特点 5 | - 自动生成法律文书:根据用户提供的输入信息,自动生成标准格式的法律文书,如合同、授权书、诉讼状等。 6 | - 自定义模板:支持用户自定义法律文书模板,按照特定格式编写模板,并通过填充关键字段生成具体文书。 7 | - 智能编辑器:提供一个智能化的编辑器界面,方便用户输入信息、选择模板、编辑文书内容等。 8 | - 敏感词过滤:集成敏感词过滤功能,确保生成的文书不包含任何敏感信息。 9 | 10 | # 快速开始 11 | ## 环境要求 12 | Python 3.8+ 13 | 安装依赖:pip install -r requirements.txt 14 | 15 | ## 运行项目 16 | 克隆本项目:git clone https://github.com/phil329/lawgpt.git 17 | 18 | 进入项目目录:cd lawgpt 19 | 20 | 启动应用:streamlit run 0_用户聊天界面.py 21 | 22 | 在浏览器中访问:http://localhost:8501 23 | 24 | # 使用说明 25 | - 在网页中根据提示信息输入相关信息,如当事人姓名、案由,原告被告信息等。 26 | - 选择需要生成的文书类型。 27 | - 根据提示填写其他必要信息。 28 | - 预览法律文书的相关细节,修改不正确的信息。 29 | - 点击生成文书按钮,即可生成标准的法律文书,可以下载到本地文件夹。 30 | 31 | # 注意事项 32 | 本工具仅作为法律文书生成的辅助工具,生成的文书可能不符合特定法律要求,请在使用前核对并适当调整。 33 | 用户需自行承担使用该工具生成的文书的法律责任。 34 | 如遇到问题或有改进建议,请联系开发者。 -------------------------------------------------------------------------------- /utils/iflytek/ifly_spark.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import openai 4 | import json 5 | 6 | 7 | def Spark(query, model='gpt-3.5-turbo'): 8 | try: 9 | openai.api_key = 'your api key' 10 | openai.proxy = {'http': '127.0.0.1:7890', 'https': '127.0.0.1:7890'} 11 | # openai.proxy = {'http': '124.70.203.196:20171', 'https': '124.70.203.196:20171'} 12 | messages = [ 13 | {"role": "user", "content": query}, 14 | ] 15 | print(model) 16 | print(messages) 17 | 18 | response = openai.ChatCompletion.create(model=model, messages=messages,temperature=0) 19 | answer = response.choices[0].message.content 20 | answer = json.dumps(answer, ensure_ascii=False) 21 | return answer 22 | except Exception as e: 23 | print('报错:',str(e)) 24 | 25 | 26 | if __name__ == '__main__': 27 | query = '你是谁' 28 | res = Spark(query) 29 | print(res) -------------------------------------------------------------------------------- /pages/3_查看历史输入.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | from streamlit_chat import message 3 | import sys 4 | 5 | sys.path.append('/root/lawgpt') 6 | from utils.prompt_config import start_chat,summary_chat_prompt 7 | from utils.iflytek.Spark import Spark 8 | 9 | api = Spark() 10 | 11 | 12 | st.title("🦜 查看历史输入") 13 | if 'current_chat' not in st.session_state: 14 | st.session_state['current_chat'] = [{"role": "assistant", "content": start_chat}] 15 | 16 | if 'history_chat' not in st.session_state: 17 | st.session_state['history_chat'] = {} 18 | 19 | temp = st.session_state['current_chat'] 20 | content = api._get_all_content(st.session_state['current_chat']) 21 | abstract = api.main([{'role':'user','content':summary_chat_prompt+content}]) 22 | 23 | index = len(st.session_state['history_chat']) 24 | 25 | title = str(index)+'.'+abstract 26 | st.session_state['history_chat'][title] = temp 27 | 28 | 29 | options = [] 30 | for chat in st.session_state['history_chat']: 31 | options.append(chat) 32 | # 创建侧边栏 33 | selection = st.sidebar.selectbox('Select an option', options) 34 | 35 | print(selection) 36 | 37 | 38 | for msg in st.session_state['history_chat'][selection]: 39 | # st.chat_message(msg["role"]).write(msg["content"]) 40 | message(msg["content"],is_user=(msg["role"]=='user')) 41 | 42 | -------------------------------------------------------------------------------- /utils/prompt_config.py: -------------------------------------------------------------------------------- 1 | start_chat="您好,我是星火起诉书生成助手,很高兴为您服务。如果您需要生成星火起诉书,请告诉我你的姓名、性别、出生日期、民族、住址、联系方式、委托诉讼代理人的姓名和事务所" 2 | json_template="""{ "姓名": null, "性别": null, "出生日期": null, "民族": null, "住址": { "省份": null, "城市": null, "区域": null }, "联系方式": null, "委托诉讼代理人": { "姓名": null, "事务所": null } }""" 3 | gudie_json="""你是一名精通民事起诉的律师。客户将给你一段文字,需要你提取全部关键信息,不丢失信息,填充到下面的json文件中,并符合json语法,记住只需把这个json文件输出给我。"""+json_template+"""客户描述如下: """ 4 | gudie_question="""你是一名精通民事起诉的律师。已经有的诉讼书内容的json文件如下。"""+json_template+"""请输出一句话,继续引导用户补全信息""" 5 | guide_agent="""""" 6 | # 为一段对话生成标题 7 | summary_chat_prompt = '我给你提供一段对话,请你帮我生成20字以内的标题,请体现文字具体信息和特点。' 8 | 9 | # 总结相关法律知识的知识卡片 10 | knowledge_comment_prompt = '你是知识提示卡片,请回答涉及到的相关法律以及具体条款,分条简单阐述,大概的结构:“涉及的法律和具体条款:1.某个法律的某一条规定了什么什么什么 2.某个法律的某一条规定了什么什么什么”。请注意无需体现与案件有关信息。' 11 | 12 | 13 | # 寻找相关案例的判罚情况 14 | related_result_prompt = '请找出与下面诉讼请求相似内容的某案件的判罚情况' 15 | 16 | 17 | 18 | second_guide="你是一名精通民事起诉的律师。客户将给你一段文字,仅需提取案由、诉讼请求、事实和理由。如有证据,请说明证据和证据来源;请注意,用户说明中,若无证据请勿编纂留空。" 19 | 20 | #引导星火根据json填写文本 21 | json_to_text =""" 22 | 请你根据下面样式的文本模板生成我上面提供的json文件中的信息,然后返回给我,你只需要返回给我文本本身,不需要返回给我其他的任何东西。此外,json中没有提到的信息保持为空,不要胡编乱造,json中为null的值换成”无“。注意,原告和被告可能有一个或多个,有可能是人也有可能是公司,但他们的信息格式一致,具体可以参考json。json中的原告被告各有几个人,你生成的时候就生成几个人的信息,如原告有3人,就是原告1,原告2,原告3,以此类推,被告同理: 23 | 原告1:×××,男/女,××××年××月××日生,×族,住......。联系方式:......。 24 | 法定代理人/指定代理人:×××,......。 25 | 委托诉讼代理人:×××,......。 26 | 原告2:...... 27 | 被告1:×××,男/女,××××年××月××日生,×族,住......。联系方式:...... 28 | 法定代理人/指定代理人:×××,...... 29 | 委托诉讼代理人:×××,...... 30 | """ 31 | 32 | -------------------------------------------------------------------------------- /utils/iflytek/prompt.md: -------------------------------------------------------------------------------- 1 | # 概念 2 | 3 | - 文本片段。 4 | - 引导模型的行为。 5 | - 上下文约束。 要涉及上下文历史信息。 6 | - 设计、优化。 怎么设计,如何优化? 7 | 8 | 9 | # 应用方向 任务类型 10 | 11 | prompt的设计要和你模型的定位相关。你是通用的模型还是专用与某一领域的模型。 12 | 13 | - 14 | 15 | 16 | # 设计和调优的方法 17 | 18 | - 明确prompt 的目的 19 | 20 | ## 标准 21 | 1. 要求清晰。 22 | 2. 语言具体。 23 | 3. 目标要聚焦。 24 | 4. 简洁,不包含冗余多余的信息。 25 | 5. 和你的主题相关。看你大模型的定位是啥,你是教育相关还是金融相关。 26 | 27 | ## 例子 28 | 29 | 写一篇关于狗的文章。 30 | 31 | 写一篇关于哈士奇的文章,介绍它的外貌,饲养条件等 32 | 33 | 34 | 第二个例子更好。任务更具体,目标更明确,能让模型更好的理解人的指令。 35 | 36 | 37 | 38 | # prompt 设计技巧 39 | 40 | ## prompt公式 41 | 42 | 任务: 43 | 指令: 44 | 角色: 45 | 46 | ## 标准prompt 47 | 48 | 引导模型完成特殊的任务 49 | 50 | 文本信息 + prompt 51 | 52 | prompt + 文本信息 53 | 54 | ## 指令prompt 55 | 该技术确保输出的相关性和高质量很重要。 56 | 57 | 会在大任务的基础上做的更多要求。 58 | 59 | ## 角色prompt 60 | 61 | 让大模型扮演一个角色,引导大模型进行回答问题。 62 | 63 | 比如,让他充当一个律师。给他一个案件,让他写一个起诉状。 64 | 65 | ## few shot 输出 66 | 67 | 给模型几个例子。让模型按照你想要的格式进行输出。 68 | 69 | 70 | ## 让我们思考一下 prompt 71 | 72 | 鼓励模型进行思考,反思,沉淀。比较适合创作型的任务,写作,绘画,诗歌创作等 73 | 74 | 有时需要联系一下上下文。 75 | 76 | 77 | ## 自一致性 prompt 78 | 79 | 确保模型的输出与所提供的输入要一致。训练的比较好的大模型,不用考虑这样的问题。 80 | 81 | ## 种子词 prompt 82 | 83 | 使用 短语 调控大模型的输出。 84 | 85 | 86 | 根据任务的目标综合使用上面的方法。 87 | 88 | 89 | 90 | # 调优技巧 91 | 92 | ## 迭代法 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /output/json_folder/person.json: -------------------------------------------------------------------------------- 1 | { 2 | "原告": [ 3 | { 4 | "姓名": "李大勇", 5 | "性别": "男", 6 | "出生日期": "2006年12月22日", 7 | "民族": "回族", 8 | "住址": "甘肃省平凉市静宁县", 9 | "联系方式": { 10 | "手机号": "13712345678" 11 | }, 12 | "身份证号": "320404200405032134", 13 | "法定代理人": "贾振扬", 14 | "委托诉讼代理人": { 15 | "姓名": "郑建国", 16 | "事务所": "山东东方律师事务所" 17 | } 18 | } 19 | ], 20 | "被告": [ 21 | { 22 | "公司名称": "海翼人寿保险股份有限公司的江苏分公司常州中心支公司", 23 | "公司所在地": "江苏省常州市武进区延政大道13号", 24 | "统一社会信用代码": "52719384621", 25 | "法人": { 26 | "姓名": "王立伟", 27 | "职务": "老板", 28 | "联系方式": "电话:12345678901" 29 | }, 30 | "委托诉讼代理人": { 31 | "姓名": "贾建国", 32 | "事务所": "江苏西方律师事务所" 33 | } 34 | } 35 | ], 36 | "案由": "机动车交通事故责任纠纷", 37 | "诉讼请求": "原告请求:\n\n1. 被告应赔偿原告因车辆损坏而产生的修理费用,金额为人民币20,000元。原告要求被告承担该笔费用的赔偿责任。\n\n2. 原告在车辆损坏事故中遭受了医疗费用的损失,金额为人民币10,000元。此外,原告还因此事故而无法正常工作,导致收入减少。因此,原告要求被告赔偿其医疗费和误工费共计人民币10,000元。", 38 | "事实理由": "事实与理由:\n\n1. 事件发生时间:2019年11月12日下午5:30。在这一天,我正在驾驶车辆通过一个十字路口。\n\n2. 被告行为:被告的车突然从侧路冲出来,直接撞到了我的车,造成了严重的伤害。\n\n3. 交通规则遵守情况:我在绿灯下行驶,符合交通规则,而被告却违反了交通规则,导致事故发生。\n\n4. 被告态度:被告承认了他的过错,但是在事故发生后并未进行赔偿。\n\n5. 协商结果:尽管我多次尝试与被告协商赔偿事宜,但均未达成一致。\n\n6. 提起诉讼:由于协商无果,我只好选择起诉,希望能够通过法律途径维护自己的权益。", 39 | "证据": "现场监控录像、通话记录、短信记录、医院诊断报告和修车单据。", 40 | "法院": "江苏省常州市武进区人民法院", 41 | "日期": "2023年08月24日" 42 | } -------------------------------------------------------------------------------- /utils/audio_gen/input_audio.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | import streamlit as st 5 | from bokeh.models.widgets import Button 6 | from bokeh.models import CustomJS 7 | 8 | from streamlit_bokeh_events import streamlit_bokeh_events 9 | 10 | js_code = """ 11 | var value = ""; 12 | var rand = 0; 13 | var recognition = new webkitSpeechRecognition(); 14 | recognition.continuous = false; 15 | recognition.interimResults = true; 16 | recognition.lang = 'zh'; 17 | 18 | document.dispatchEvent(new CustomEvent("GET_ONREC", {detail: 'start'})); 19 | 20 | recognition.onspeechstart = function () { 21 | document.dispatchEvent(new CustomEvent("GET_ONREC", {detail: 'running'})); 22 | } 23 | recognition.onsoundend = function () { 24 | document.dispatchEvent(new CustomEvent("GET_ONREC", {detail: 'stop'})); 25 | } 26 | recognition.onresult = function (e) { 27 | var value2 = ""; 28 | for (var i = e.resultIndex; i < e.results.length; ++i) { 29 | if (e.results[i].isFinal) { 30 | value += e.results[i][0].transcript; 31 | rand = Math.random(); 32 | 33 | } else { 34 | value2 += e.results[i][0].transcript; 35 | } 36 | } 37 | document.dispatchEvent(new CustomEvent("GET_TEXT", {detail: {t:value, s:rand}})); 38 | document.dispatchEvent(new CustomEvent("GET_INTRM", {detail: value2})); 39 | 40 | } 41 | recognition.onerror = function(e) { 42 | document.dispatchEvent(new CustomEvent("GET_ONREC", {detail: 'stop'})); 43 | } 44 | recognition.start(); 45 | """ 46 | -------------------------------------------------------------------------------- /utils/iflytek/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request, jsonify, make_response 2 | import hashlib 3 | import hmac 4 | import base64 5 | import json 6 | import time 7 | 8 | import SparkApi 9 | 10 | app = Flask(__name__) 11 | 12 | appid = "e97d3136" 13 | api_key = "b25338415789cf13a0091d64a1b3381e" 14 | api_secret = "MDExMGZmZjFjMzRhOTkzNzczMGEyMzgw" 15 | 16 | domain = "plugin" 17 | Spark_url = "ws://spark-api-knowledge.xf-yun.com/v2.1/multimodal" 18 | 19 | def getlength(text): 20 | length = 0 21 | for content in text: 22 | temp = content["content"] 23 | leng = len(temp) 24 | length += leng 25 | return length 26 | 27 | def checklen(text): 28 | while (getlength(text) > 8000): 29 | del text[0] 30 | return text 31 | 32 | @app.route('/') 33 | def index(): 34 | return 'Hello, World!' 35 | 36 | 37 | @app.route('/chat', methods=['POST']) 38 | def chat(): 39 | text = request.json.get("text",[]) 40 | if text.length == 0: 41 | response_data = { 42 | 'code': -1, 43 | 'text': [] 44 | } 45 | response = make_response(jsonify(response_data)) 46 | return response 47 | question = checklen(text) 48 | SparkApi.answer = "" 49 | SparkApi.main(appid, api_key, api_secret, Spark_url, domain, question) 50 | jsoncon = {} 51 | jsoncon["role"] = "assistant" 52 | jsoncon["content"] = SparkApi.answer 53 | text.append(jsoncon) 54 | # 返回结果 55 | response_data = { 56 | 'code': 20000, 57 | 'text': text 58 | } 59 | response = make_response(jsonify(response_data)) 60 | return response 61 | 62 | if __name__ == '__main__': 63 | app.run(host='172.30.12.252', port=5001,debug=True) 64 | -------------------------------------------------------------------------------- /pages/2_法律知识汇总.py: -------------------------------------------------------------------------------- 1 | 2 | import json 3 | import os 4 | import sys 5 | 6 | import streamlit as st 7 | 8 | from utils.iflytek.Spark import Spark 9 | from utils.prompt_config import knowledge_comment_prompt, related_result_prompt 10 | from utils.tools import get_project_path 11 | 12 | api = Spark() 13 | 14 | st.title("🔎 相关法律知识") 15 | 16 | # description = ' { "案由": "民间借贷纠纷", "诉讼请求": [ { "被告归还原告借款41,040元" }, { "被告支付原告违约金12,222元" }, { "被告承担本案诉讼费用" } ], "事实和理由": "原告冯雯与被告为朋友关系。被告在2018年1月19日向原告借款2万元,原告当天通过现金方式支付给被告。同日,被告再次向原告借款55,500元,并承诺在2018年4月29日前归还。原告分两次通过银行转账共计4万5千元以及500元现金给被告。此后,被告于2019年1月15日再次向原告借款1万元,原告当天通过现金方式支付给被告。自2018年至今,被告未按约定归还原告借款。原告多次催促被告还款,但被告仍未履行还款义务。因此,原告决定起诉被告,要求归还借款本金及支付违约金,并承担本案诉讼费用。", "证据": { "证据和证据来源": [ { "原告提供的银行转账记录、现金收据等证明被告借款的事实" }, { "原告与被告的聊天记录、通话录音等证明双方关于借款事宜的约定" } ] } }' 17 | 18 | project_path = get_project_path() 19 | json_file = os.path.join(project_path,'output','json_folder','person_tmp.json') 20 | 21 | 22 | with open(json_file,'r',encoding='utf8') as f: 23 | description = f.read() 24 | 25 | 26 | # # st.subheader('相关法律条款') 27 | # chat_list = [{'role':'user','content':knowledge_comment_prompt+description}] 28 | # res = api.main(chat_list) 29 | # st.write(res) 30 | 31 | 32 | 33 | # st.write(description) 34 | 35 | # 创建两个列 36 | left_column, right_column = st.columns(2) 37 | 38 | with left_column: 39 | st.subheader('相关法律条款') 40 | chat_list = [{'role':'user','content':knowledge_comment_prompt+description}] 41 | res = api.main(chat_list) 42 | st.write(res) 43 | 44 | 45 | with right_column: 46 | st.subheader('相关案例') 47 | chat_list = [{'role':'user','content':related_result_prompt+description}] 48 | # chat_list = [{'role':'user','content':'请给出与下面内容相似的某案件的判罚情况'+description}] 49 | res = api.main(chat_list) 50 | st.write(res) 51 | -------------------------------------------------------------------------------- /scripts/check_json.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | def filter_null_values(json_text): 4 | # 解析输入的 JSON 文本 5 | data = json.loads(json_text) 6 | 7 | # 递归遍历 JSON 数据,将值为 null 的键值对的值设置为"无",但不包含有内容的键值对 8 | def recursive_filter(data): 9 | filtered_data = {} 10 | for key, value in data.items(): 11 | if isinstance(value, dict): 12 | nested_filtered_data = recursive_filter(value) 13 | if nested_filtered_data: 14 | filtered_data[key] = nested_filtered_data 15 | elif isinstance(value, list): 16 | nested_filtered_data = [] 17 | for item in value: 18 | if isinstance(item, dict): 19 | nested_item = recursive_filter(item) 20 | if nested_item: 21 | nested_filtered_data.append(nested_item) 22 | if nested_filtered_data: 23 | filtered_data[key] = nested_filtered_data 24 | elif value is None: 25 | filtered_data[key] = "无" 26 | return filtered_data 27 | 28 | # 将值为 null 的键值对的值设置为"无",但不包含有内容的键值对 29 | filtered_data = recursive_filter(data) 30 | 31 | # 将筛选后的数据转换回 JSON 文本 32 | filtered_json = json.dumps(filtered_data, ensure_ascii=False) 33 | 34 | return filtered_json 35 | 36 | 37 | # 示例输入 38 | json_text = ''' 39 | { 40 | "案由": null, 41 | "原告": { 42 | "姓名": "王仁淞", 43 | "性别": "男", 44 | "出生日期": null, 45 | "民族": null, 46 | "其他信息": null, 47 | "住址": null, 48 | "联系方式": null 49 | }, 50 | "法定代理人/指定代理人": { 51 | "姓名": null, 52 | "其他信息": null 53 | }, 54 | "委托诉讼代理人": { 55 | "姓名": null, 56 | "其他信息": null 57 | }, 58 | "被告": { 59 | "姓名": null, 60 | "其他信息": null 61 | }, 62 | "结尾": { 63 | "法院名称": null, 64 | "附件": null, 65 | "签名": null, 66 | "日期": null 67 | } 68 | } 69 | ''' 70 | 71 | # 调用函数进行筛选并将值为 null 的键值对的值设置为"无",但不包含有内容的键值对 72 | filtered_json = filter_null_values(json_text) 73 | 74 | # 输出结果 75 | print(filtered_json) -------------------------------------------------------------------------------- /output/json_folder/person_tmp.json: -------------------------------------------------------------------------------- 1 | { 2 | "原告": [ 3 | { 4 | "姓名": "", 5 | "性别": "女", 6 | "出生日期": "1922年10月10日", 7 | "民族": "汉族", 8 | "住址": "江西省赣州市赣县", 9 | "联系方式": "12345678911", 10 | "委托诉讼代理人": { 11 | "姓名": "张三", 12 | "事务所": "湖南锦泽律师事务所" 13 | } 14 | }, 15 | { 16 | "姓名": "刘小小", 17 | "性别": "女", 18 | "出生日期": "1922年10月10日", 19 | "民族": "汉族", 20 | "住址": "江西省赣州市赣县", 21 | "联系方式": "12345678911", 22 | "委托诉讼代理人": { 23 | "姓名": "张三", 24 | "事务所": "湖南锦泽律师事务所" 25 | } 26 | } 27 | ], 28 | "被告": [ 29 | { 30 | "公司名称": "华安财产保险股份有限公司河北分公司保定中心支公司", 31 | "公司所在地": "河北省保定市阳光大街与东风路交叉口仁和公寓底商第12号", 32 | "法定代表人/法定代理人/法人": { 33 | "姓名": "贾洪杰", 34 | "职务": "该公司经理", 35 | "联系方式": "联系电话98765432100" 36 | }, 37 | "委托诉讼代理人": { 38 | "姓名": "吕志伟", 39 | "事务所": "河北锦泽律师事务所" 40 | } 41 | }, 42 | { 43 | "姓名": "刘小小", 44 | "性别": "女", 45 | "出生日期": "1922年10月10日", 46 | "民族": "汉族", 47 | "住址": "江西省赣州市赣县", 48 | "联系方式": "12345678911", 49 | "委托诉讼代理人": { 50 | "姓名": "张三", 51 | "事务所": "湖南锦泽律师事务所" 52 | } 53 | } 54 | ], 55 | "案由": "机动车交通事故责任纠纷", 56 | "诉讼请求": "事实:\n1. 2018年1月19日,被告向原告借款2万元,原告当天交付现金。\n2. 2018年1月29日,被告再次向原告借款55,500元,并承诺在2018年4月29日前归还。原告分两次通过银行转账给被告共计4万5千元,另支付现金500元。\n3. 2019年1月15日,被告再次向原告借款1万元,原告当天交付现金。\n4. 被告至今未按约定还款,仅还了部分款项。\n\n理由:\n根据《中华人民共和国合同法》第196条规定:“借款人应当按照约定的期限返还借款。”被告未按照约定的期限返还借款,构成违约。原告多次催告被告还款,但被告仍未履行还款义务。因此,原告要求被告立即偿还剩余借款本金及违约金。", 57 | "事实理由": "诉讼请求:\n1. 要求被告归还原告41,040元借款;\n2. 要求被告支付原告12,222元的违约金;\n3. 要求被告承担本次诉讼的全部费用。", 58 | "证据": "根据客户输入的信息,他们拥有借条和转账记录作为证据。在民事起诉中,这些证据可以帮助证明借款关系的存在以及款项的支付。", 59 | "法院": "客户提到的法院信息为:好日子法院。", 60 | "日期": null 61 | } -------------------------------------------------------------------------------- /scripts/json2text.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from docx import Document 4 | from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_PARAGRAPH_ALIGNMENT 5 | from docx.oxml.ns import qn 6 | from docx.shared import Pt, RGBColor 7 | 8 | from utils.iflytek import SparkApi 9 | from utils.prompt_config import * 10 | 11 | 12 | def generate_docx(data,doc_file): 13 | # 以下密钥信息从控制台获取 14 | appid = "f54bca1a" # 填写控制台中获取的 APPID 信息 15 | api_secret = "ZGJmMjY3YWFmNGY5N2Q1YWMwOGZlMjFh" # 填写控制台中获取的 APISecret 信息 16 | api_key = "2e7516edf376713eb5d99fc812a87ed5" # 填写控制台中获取的 APIKey 信息 17 | 18 | text = [] 19 | 20 | def getText(role, content): 21 | jsoncon = {} 22 | jsoncon["role"] = role 23 | jsoncon["content"] = content 24 | text.append(jsoncon) 25 | return text 26 | 27 | def getlength(text): 28 | length = 0 29 | for content in text: 30 | temp = content["content"] 31 | leng = len(temp) 32 | length += leng 33 | return length 34 | 35 | def checklen(text): 36 | while (getlength(text) > 8000): 37 | del text[0] 38 | return text 39 | 40 | # 用于配置大模型版本,默认“generalv2” 41 | domain = "generalv2" # v2.0版本 42 | 43 | # 云端环境的服务地址 44 | Spark_url = "ws://spark-api.xf-yun.com/v2.1/chat" # v2.0环境的地址 45 | 46 | # 提取原告和被告部分 47 | result = { 48 | "原告": data["原告"], 49 | "被告": data["被告"] 50 | } 51 | 52 | # 转换为JSON格式字符串 53 | result_json = json.dumps(result, ensure_ascii=False, indent=4) 54 | prompt = result_json + json_to_text 55 | question = checklen(getText("user", prompt)) 56 | SparkApi.answer = "" 57 | SparkApi.main(appid, api_key, api_secret, Spark_url, domain, question) 58 | answer = SparkApi.answer 59 | 60 | document = Document() 61 | 62 | document.styles['Normal'].font.name = u'宋体' 63 | document.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体') 64 | document.styles['Normal'].font.size = Pt(10.5) 65 | document.styles['Normal'].font.color.rgb = RGBColor(0,0,0) 66 | 67 | 68 | # 标题 69 | document.add_heading('民事起诉状', level=0).alignment = WD_PARAGRAPH_ALIGNMENT.CENTER 70 | document.add_paragraph(answer) 71 | 72 | # 添加诉讼请求 73 | document.add_paragraph('诉讼请求:\n' + data['诉讼请求']) 74 | 75 | # 添加事实和理由 76 | document.add_paragraph('事实和理由:\n' + data['事实理由']) 77 | 78 | # 添加证据和证据来源,证人姓名和住所 79 | document.add_paragraph('证据和证据来源,证人姓名和住所:\n' + data['证据']) 80 | 81 | # 结尾部分 82 | document.add_paragraph('此致\n\n' + data['法院'] + '人民法院\n\n附:本起诉状副本×份') 83 | 84 | # 起诉人(签名) 85 | paragraph = document.add_paragraph('起诉人(签名)\n') 86 | paragraph.alignment = WD_ALIGN_PARAGRAPH.RIGHT 87 | 88 | # 日期 89 | date_paragraph = document.add_paragraph(data['日期']) 90 | date_paragraph.alignment = WD_ALIGN_PARAGRAPH.RIGHT 91 | 92 | # 保存文档为docx文件 93 | document.save(doc_file) 94 | 95 | if __name__ == "__main__": 96 | # 从JSON文件中读取数据 97 | doc_file = './legal_document02.docx' 98 | 99 | with open('./person.json', 'r', encoding='utf-8') as f: 100 | data = json.load(f) 101 | docx_file = generate_docx(data,doc_file) -------------------------------------------------------------------------------- /utils/iflytek/main.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | 4 | sys.path.append('/root/lawgpt') 5 | from Spark import Spark 6 | 7 | from prompt_config import gudie_json,start_chat 8 | from tools import transverse_on_json,extract_json_from_string 9 | 10 | 11 | text = [ 12 | {'role': "user", 'content': '你好,你能够帮我生成一份起诉状吗?'}, 13 | {'role': "assistant", 'content': '您好,我是星火,我可以帮您生成一份起诉状,请先给我几份模板。'}, 14 | {'role': "user", 'content': '’‘好的,这是一份模板:' 15 | '民事起诉状' 16 | '原告:姓名,性别: , 年 月 日 出生, 族,住址: 省 市 区 镇 村 组 号' 17 | '联系电话: 。' 18 | '被告一: 姓名 ,性别: , 年 月 日 出生, 族,住址: 省 市 区 路 小区 号楼 单元 室。' 19 | '联系电话: 。' 20 | '被告二: 保险股份有限公司 分公司,住所地: 省 市 区 路 号 座 层 。' 21 | '负责人: 。职务: 。' 22 | '联系电话: 。' 23 | '案由:机动车交通事故责任纠纷' 24 | '诉讼请求:' 25 | '一、依法判决被告一赔偿原告各项损失共计 元(其中:医疗费 元、后续医疗费 元、误工费 元、伙食费 元、护理费 元、交通费 元、住宿费 元、营养费 元、残疾赔偿金 元、残疾辅助器具费 元、被抚养人生活费 元、精神损害抚慰金 元);' 26 | '二、依法判决被告一赔偿原告车辆损失共计 元;' 27 | '三、依法判决被告二在责任保险赔偿限额范围内对被告一的上述赔偿义务承担连带赔偿责任;' 28 | '四、本案诉讼费由被告承担。' 29 | '事实及理由:' 30 | '一、事故概况' 31 | ' 年 月 日,原告驾驶车牌号为 的小轿车与被告一驾驶的 汽车发生交通事故,造成原告人身与财产损害。事故地点为: ;事故原因为: 。该事故已由 市 区交通警察支队做出编号为 的道路交通事故认定书,认定被告承担事故全部责任,原告不承担事故责任。' 32 | '二、保险情况' 33 | '事故发生前,被告车辆已在被告二购买了交通事故责任强制保险和商业险。 ' 34 | '原告认为:被告一应就交通事故造成原告的损失予以赔偿,被告二应当在保险责任范围内承担连带责任。为维护原告合法权益,特向贵院具状起诉,请求支持原告请求。' 35 | '' 36 | '此致' 37 | '人民法院' 38 | '具状人(签名或盖章): ' 39 | ' 年 月 日'''}, 40 | {'role': 'assistant', 'content': '好的我都了解了,我会按照你的模板来生成起诉状'}, 41 | {'role': 'user', 'content': '让我们开始吧,请一步步引导我填写起诉状模板上所需要的信息,最后生成一份起诉状'}, 42 | {'role': 'assistant', 'content': '好的,我会一步步地引导你,分别从原告和被告的个人信息,案由,诉讼请求,所掌握的事实和理由。'}, 43 | # {'role': "user", 'content': '帮我把我写的地址填入下面的住址中,你需要先确定我给的是哪个省哪个城市哪个区或者县,如果城市或者省份是{“上海”、“北京”、“天津”、“重庆”}中的任一城市,则“省份”和“城市”都填入该城市,如果不是这四个,请把刚刚确认的那个省哪个市哪个区或者县和具体的地址填入:"住址": { "省份": null, "城市": null, "区/县": null, "其他": null } 比如一个输入是"甘肃静安县",输出为"住址": { "省份": 甘肃省, "城市": 平凉市, "区/县": 静安县, "其他": null },我的输入是:栖霞区仙林大道163号'}, 44 | # {'role': "assistant", 'content': '"住址": { "省份": "江苏省", "城市": "南京市", "区/县": "栖霞区", "其他": 仙林大道163号 }'}, 45 | ] 46 | 47 | api = Spark() 48 | 49 | 50 | prompt = ['请你提供原告的姓名、性别、出生日期、民族、身份证号码、住址以及联系电话,如果有多个人的情况下,请分开来写', 51 | '现在开始提供被告的姓名'] 52 | 53 | text = [] 54 | 55 | print('\n'+'星火:',start_chat) 56 | 57 | while (1): 58 | 59 | Input = input("\n\n" + "我:") 60 | text.append({'role':'user','content':Input}) 61 | 62 | res = api.main(text) 63 | 64 | text.append({'role':'assistant','content':res}) 65 | 66 | new_prompt_json={'role': 'user', 'content': gudie_json+Input} 67 | res_json = api.main([new_prompt_json]) 68 | 69 | data=extract_json_from_string(res_json) 70 | 71 | print(data) 72 | 73 | 74 | print('\n\n'+'星火:',res) 75 | 76 | # print(str(text)) 77 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | aiofiles==23.2.1 2 | aiohttp==3.8.5 3 | aiosignal==1.3.1 4 | altair==5.0.1 5 | annotated-types==0.5.0 6 | anthropic==0.3.10 7 | anyio==3.7.1 8 | async-timeout==4.0.3 9 | attrs==23.1.0 10 | av==10.0.0 11 | backports.zoneinfo==0.2.1 12 | beautifulsoup4==4.12.2 13 | blinker==1.6.2 14 | bokeh==2.4.1 15 | Brotli==1.0.9 16 | cachetools==5.3.1 17 | certifi==2023.7.22 18 | cffi==1.15.1 19 | charset-normalizer==3.2.0 20 | click==8.1.7 21 | contourpy==1.1.0 22 | cycler==0.11.0 23 | dataclasses-json==0.5.14 24 | distro==1.8.0 25 | docopt==0.6.2 26 | duckduckgo-search==3.8.5 27 | exceptiongroup==1.1.3 28 | Faker==19.3.0 29 | fastapi==0.101.1 30 | favicon==0.7.0 31 | ffmpeg==1.4 32 | ffmpy==0.3.1 33 | filelock==3.12.2 34 | Flask==2.3.2 35 | fonttools==4.42.0 36 | frozenlist==1.4.0 37 | fsspec==2023.6.0 38 | gevent==1.4.0 39 | gitdb==4.0.10 40 | GitPython==3.1.32 41 | gradio==3.40.1 42 | gradio_client==0.4.0 43 | greenlet==0.4.15 44 | gTTS==2.3.2 45 | h11==0.14.0 46 | h2==4.1.0 47 | hpack==4.0.0 48 | htbuilder==0.6.1 49 | httpcore==0.17.3 50 | httpx==0.24.1 51 | huggingface-hub==0.16.4 52 | hyperframe==6.0.1 53 | idna==3.4 54 | importlib-metadata==6.8.0 55 | importlib-resources==6.0.1 56 | itsdangerous==2.1.2 57 | Jinja2==3.1.2 58 | Js2Py==0.74 59 | jsonschema==4.19.0 60 | jsonschema-specifications==2023.7.1 61 | kiwisolver==1.4.4 62 | langchain==0.0.268 63 | langsmith==0.0.25 64 | linkify-it-py==2.0.2 65 | loguru==0.7.0 66 | lxml==4.9.3 67 | Markdown==3.4.4 68 | markdown-it-py==2.2.0 69 | markdownlit==0.0.7 70 | MarkupSafe==2.1.3 71 | marshmallow==3.20.1 72 | matplotlib==3.7.2 73 | mdit-py-plugins==0.3.3 74 | mdurl==0.1.2 75 | more-itertools==10.1.0 76 | multidict==6.0.4 77 | mypy-extensions==1.0.0 78 | numexpr==2.8.5 79 | numpy==1.24.4 80 | openai==0.27.8 81 | orjson==3.9.5 82 | packaging==23.1 83 | pandas==2.0.3 84 | Pillow==9.5.0 85 | pipwin==0.5.2 86 | pkgutil_resolve_name==1.3.10 87 | protobuf==4.24.1 88 | pyarrow==12.0.1 89 | PyAudio==0.2.11 90 | pycparser==2.19 91 | pydantic==1.10.12 92 | pydantic_core==2.6.1 93 | pydeck==0.8.0 94 | pydub==0.25.1 95 | Pygments==2.16.1 96 | pyjsparser==2.7.1 97 | pymdown-extensions==10.1 98 | Pympler==1.0.1 99 | pyparsing==3.0.9 100 | PyPrind==2.11.3 101 | pyproject==1.3.1 102 | pySmartDL==1.3.4 103 | python-dateutil==2.8.2 104 | python-docx==0.8.11 105 | python-multipart==0.0.6 106 | pytz==2023.3 107 | pytz-deprecation-shim==0.1.0.post0 108 | PyYAML==6.0.1 109 | referencing==0.30.2 110 | requests==2.31.0 111 | rich==13.5.2 112 | rpds-py==0.9.2 113 | semantic-version==2.10.0 114 | six==1.12.0 115 | smmap==5.0.0 116 | sniffio==1.3.0 117 | socksio==1.0.0 118 | sounddevice==0.4.6 119 | soupsieve==2.4.1 120 | SpeechRecognition==3.10.0 121 | SQLAlchemy==2.0.20 122 | st-annotated-text==4.0.0 123 | starlette==0.27.0 124 | streamlit==1.25.0 125 | streamlit-bokeh-events==0.1.2 126 | streamlit-camera-input-live==0.2.0 127 | streamlit-card==0.0.61 128 | streamlit-chat==0.1.1 129 | streamlit-embedcode==0.1.2 130 | streamlit-extras==0.3.0 131 | streamlit-faker==0.0.2 132 | streamlit-feedback==0.0.9 133 | streamlit-image-coordinates==0.1.6 134 | streamlit-keyup==0.2.0 135 | streamlit-toggle-switch==1.0.2 136 | streamlit-vertical-slider==1.0.2 137 | tenacity==8.2.3 138 | tokenizers==0.13.3 139 | toml==0.10.2 140 | toolz==0.12.0 141 | tornado==6.3.3 142 | tqdm==4.66.1 143 | trubrics==1.4.5 144 | typeguard==2.13.3 145 | typer==0.9.0 146 | typing-inspect==0.9.0 147 | typing_extensions==4.7.1 148 | tzdata==2023.3 149 | tzlocal==4.3.1 150 | uc-micro-py==1.0.2 151 | urllib3==2.0.4 152 | uvicorn==0.23.2 153 | validators==0.21.2 154 | watchdog==3.0.0 155 | Wave==0.0.2 156 | websocket==0.2.1 157 | websocket-client==0.58.0 158 | websockets==11.0.3 159 | Werkzeug==2.3.7 160 | xyzservices==2023.7.0 161 | yarl==1.9.2 162 | zipp==3.16.2 163 | zope.event==5.0 164 | zope.interface==6.0 165 | -------------------------------------------------------------------------------- /pages/1_预览诉讼文书.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import sys 4 | 5 | import pandas as pd 6 | import streamlit as st 7 | 8 | from scripts.json2docx import json2docx 9 | from scripts.json2text import generate_docx 10 | from utils.tools import (flatten_dictionary, generate_json_file, 11 | unflatten_dataframe,get_project_path) 12 | 13 | # with st.sidebar: 14 | # anthropic_api_key = st.text_input("Anthropic API Key", key="file_qa_api_key", type="password") 15 | # "[View the source code](https://github.com/streamlit/llm-examples/blob/main/pages/1_File_Q%26A.py)" 16 | # "[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/streamlit/llm-examples?quickstart=1)" 17 | 18 | 19 | 20 | 21 | st.title("📝 预览诉讼文书") 22 | 23 | project_path = get_project_path() 24 | json_file = os.path.join(project_path,'output','json_folder','person.json') 25 | file_path = os.path.join(project_path,'output','docx_folder','legal_document.docx') 26 | 27 | 28 | # 保存数据的函数,你可以根据需求进行自定义 29 | def save_data(case_title, lawsuit_demands, factual_reasons, evidence): 30 | # 在这里执行保存逻辑,例如将数据保存到文件或数据库中 31 | pass 32 | 33 | with open(json_file,'r',encoding='utf8') as f: 34 | json_data = json.load(f) 35 | 36 | # 案由 37 | 38 | st.subheader("案由") 39 | case = st.text_input('当前的案由是', json_data["案由"]) 40 | 41 | 42 | # 原告 43 | st.subheader("原告") 44 | 45 | plaintiff = json_data["原告"] 46 | plaintiff_df_list = [] 47 | 48 | for i in range(len(plaintiff)): 49 | st.markdown("###### 原告" + str(i+1)) 50 | 51 | # 将嵌套的字典展开为新的键值对 52 | flattened_data = flatten_dictionary(plaintiff[i]) 53 | 54 | # 将展开的键值对转换为 DataFrame 55 | df = pd.DataFrame([flattened_data]) 56 | # df = df.transpose() 57 | plaintiff_df = st.data_editor(df, num_rows="fixed", key=str(i)) 58 | plaintiff_df_list.append(plaintiff_df) 59 | 60 | 61 | # 被告 62 | st.subheader("被告") 63 | 64 | defendant = json_data["被告"] 65 | defendant_df_list = [] 66 | 67 | for i in range(len(defendant)): 68 | st.markdown("###### 被告" + str(i+1)) 69 | 70 | # 将嵌套的字典展开为新的键值对 71 | flattened_data = flatten_dictionary(defendant[i]) 72 | 73 | # 将展开的键值对转换为 DataFrame 74 | df = pd.DataFrame([flattened_data]) 75 | # df = df.transpose() 76 | defendant_df = st.data_editor(df, num_rows="fixed", key=str(i+100)) 77 | defendant_df_list.append(defendant_df) 78 | 79 | 80 | 81 | # 诉讼请求文本编辑框 82 | st.subheader("诉讼请求") 83 | lawsuit_demands = st.text_area("请确认或修改诉讼文书的诉讼请求",value=json_data['诉讼请求'], height=500) 84 | 85 | # 事实理由文本编辑框 86 | st.subheader("事实理由") 87 | factual_reasons = st.text_area("请确认或修改诉讼文书的事实理由",value=json_data['事实理由'], height=500) 88 | 89 | # 证据文本编辑框 90 | st.subheader("证据") 91 | evidence = st.text_area("请确认或修改证据(如有)",value=json_data['证据'], height=300) 92 | 93 | # 保存按钮 94 | if st.button("保存"): 95 | # 在这里执行保存操作 96 | 97 | # 原告保存 98 | json_data['原告'] = [] 99 | for i in range(len(plaintiff_df_list)): 100 | plaintiff_data = unflatten_dataframe(plaintiff_df_list[i]) 101 | json_data['原告'].append(plaintiff_data) 102 | 103 | # 被告保存 104 | json_data['被告'] = [] 105 | for i in range(len(defendant_df_list)): 106 | defendant_data = unflatten_dataframe(defendant_df_list[i]) 107 | json_data['被告'].append(defendant_data) 108 | 109 | json_data['案由'] = case 110 | json_data['诉讼请求'] = lawsuit_demands 111 | json_data['事实理由'] = factual_reasons 112 | json_data['证据'] = evidence 113 | 114 | # 保存相关的json文件 115 | generate_json_file(json_data, json_file) 116 | 117 | # 保存对应的docx文件 118 | json2docx(json_data,file_path) 119 | st.success("保存成功!") 120 | 121 | # 点击按钮进行下载 122 | filename = os.path.basename(file_path) 123 | with open(file_path, 'rb') as f: 124 | st.download_button('下载诉讼文书', f, file_name=filename) 125 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | led / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | 162 | -------------------------------------------------------------------------------- /utils/iflytek/test.py: -------------------------------------------------------------------------------- 1 | import SparkApi 2 | 3 | # 以下密钥信息从控制台获取 4 | appid = "api" # 填写控制台中获取的 APPID 信息 5 | api_secret = "api_secret" # 填写控制台中获取的 APISecret 信息 6 | api_key = "api_key" # 填写控制台中获取的 APIKey 信息 7 | 8 | # 用于配置大模型版本,默认“generalv2” 9 | domain = "generalv2" # v2.0版本 10 | 11 | # 云端环境的服务地址 12 | Spark_url = "ws://spark-api.xf-yun.com/v2.1/chat" # v2.0环境的地址 13 | 14 | text = [ 15 | # {'role': "user", 'content': '你好,你能够帮我生成一份起诉状吗?'}, 16 | # {'role': "assistant", 'content': '您好,我是星火,我可以帮您生成一份起诉状,请先给我几份模板。'}, 17 | # {'role': "user", 'content': '’‘好的,这是一份模板:' 18 | # '民事起诉状' 19 | # '原告:姓名,性别: , 年 月 日 出生, 族,住址: 省 市 区 镇 村 组 号' 20 | # '联系电话: 。' 21 | # '被告一: 姓名 ,性别: , 年 月 日 出生, 族,住址: 省 市 区 路 小区 号楼 单元 室。' 22 | # '联系电话: 。' 23 | # '被告二: 保险股份有限公司 分公司,住所地: 省 市 区 路 号 座 层 。' 24 | # '负责人: 。职务: 。' 25 | # '联系电话: 。' 26 | # '案由:机动车交通事故责任纠纷' 27 | # '诉讼请求:' 28 | # '一、依法判决被告一赔偿原告各项损失共计 元(其中:医疗费 元、后续医疗费 元、误工费 元、伙食费 元、护理费 元、交通费 元、住宿费 元、营养费 元、残疾赔偿金 元、残疾辅助器具费 元、被抚养人生活费 元、精神损害抚慰金 元);' 29 | # '二、依法判决被告一赔偿原告车辆损失共计 元;' 30 | # '三、依法判决被告二在责任保险赔偿限额范围内对被告一的上述赔偿义务承担连带赔偿责任;' 31 | # '四、本案诉讼费由被告承担。' 32 | # '事实及理由:' 33 | # '一、事故概况' 34 | # ' 年 月 日,原告驾驶车牌号为 的小轿车与被告一驾驶的 汽车发生交通事故,造成原告人身与财产损害。事故地点为: ;事故原因为: 。该事故已由 市 区交通警察支队做出编号为 的道路交通事故认定书,认定被告承担事故全部责任,原告不承担事故责任。' 35 | # '二、保险情况' 36 | # '事故发生前,被告车辆已在被告二购买了交通事故责任强制保险和商业险。 ' 37 | # '原告认为:被告一应就交通事故造成原告的损失予以赔偿,被告二应当在保险责任范围内承担连带责任。为维护原告合法权益,特向贵院具状起诉,请求支持原告请求。' 38 | # '' 39 | # '此致' 40 | # '人民法院' 41 | # '具状人(签名或盖章): ' 42 | # ' 年 月 日'''}, 43 | # {'role': 'assistant', 'content': '好的我都了解了,我会按照你的模板来生成起诉状'}, 44 | # {'role': 'user', 'content': '让我们开始吧,请一步步引导我填写起诉状模板上所需要的信息,最后生成一份起诉状'}, 45 | # {'role': "user", 'content': '帮我把我写的地址填入下面的住址中,你需要先确定我给的是哪个省哪个城市哪个区或者县,如果城市或者省份是{“上海”、“北京”、“天津”、“重庆”}中的任一城市,则“省份”和“城市”都填入该城市,如果不是这四个,请把刚刚确认的那个省哪个市哪个区或者县和具体的地址填入:"住址": { "省份": null, "城市": null, "区/县": null, "其他": null } 比如一个输入是"甘肃静安县",输出为"住址": { "省份": 甘肃省, "城市": 平凉市, "区/县": 静安县, "其他": null },我的输入是:栖霞区仙林大道163号'}, 46 | # {'role': "assistant", 'content': '"住址": { "省份": "江苏省", "城市": "南京市", "区/县": "栖霞区", "其他": 仙林大道163号 }'}, 47 | ] 48 | 49 | 50 | def getText(role, content): 51 | jsoncon = {} 52 | jsoncon["role"] = role 53 | jsoncon["content"] = content 54 | text.append(jsoncon) 55 | return text 56 | 57 | 58 | def getlength(text): 59 | length = 0 60 | for content in text: 61 | temp = content["content"] 62 | leng = len(temp) 63 | length += leng 64 | return length 65 | 66 | 67 | def checklen(text): 68 | while (getlength(text) > 8000): 69 | del text[0] 70 | return text 71 | 72 | 73 | 74 | if __name__ == '__main__': 75 | text.clear 76 | # text_start_assistant = '您好,我是星火,我可以帮您生成一份起诉状,请先告诉我您的姓名、年龄、民族、联系方式和住址' 77 | text_start_assistant = '您好,我是星火,有什么可以帮你的吗' 78 | print("星火:" + text_start_assistant, end="") 79 | getText("assistant", text_start_assistant) 80 | while (1): 81 | Input = input("\n" + "我:") 82 | question = checklen(getText("user", Input)) 83 | SparkApi.answer = "" 84 | print("星火:", end="") 85 | SparkApi.main(appid, api_key, api_secret, Spark_url, domain, question) 86 | getText("assistant", SparkApi.answer) 87 | # print(str(text)) 88 | 89 | 90 | -------------------------------------------------------------------------------- /utils/iflytek/SparkApi.py: -------------------------------------------------------------------------------- 1 | import _thread as thread 2 | import base64 3 | import datetime 4 | import hashlib 5 | import hmac 6 | import json 7 | import ssl 8 | from datetime import datetime 9 | from time import mktime 10 | from urllib.parse import urlencode, urlparse 11 | from wsgiref.handlers import format_date_time 12 | 13 | import websocket # 使用websocket_client 14 | 15 | answer = "" 16 | 17 | class Ws_Param(object): 18 | # 初始化 19 | def __init__(self, APPID, APIKey, APISecret, Spark_url): 20 | self.APPID = APPID 21 | self.APIKey = APIKey 22 | self.APISecret = APISecret 23 | self.host = urlparse(Spark_url).netloc 24 | self.path = urlparse(Spark_url).path 25 | self.Spark_url = Spark_url 26 | 27 | # 生成url 28 | def create_url(self): 29 | # 生成RFC1123格式的时间戳 30 | now = datetime.now() 31 | date = format_date_time(mktime(now.timetuple())) 32 | 33 | # 拼接字符串 34 | signature_origin = "host: " + self.host + "\n" 35 | signature_origin += "date: " + date + "\n" 36 | signature_origin += "GET " + self.path + " HTTP/1.1" 37 | 38 | # 进行hmac-sha256进行加密 39 | signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'), 40 | digestmod=hashlib.sha256).digest() 41 | 42 | signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8') 43 | 44 | authorization_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"' 45 | 46 | authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8') 47 | 48 | # 将请求的鉴权参数组合为字典 49 | v = { 50 | "authorization": authorization, 51 | "date": date, 52 | "host": self.host 53 | } 54 | # 拼接鉴权参数,生成url 55 | url = self.Spark_url + '?' + urlencode(v) 56 | # 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致 57 | return url 58 | 59 | 60 | # 收到websocket错误的处理 61 | def on_error(ws, error): 62 | print("### error:", error) 63 | 64 | 65 | # 收到websocket关闭的处理 66 | def on_close(ws,one,two): 67 | print(" ") 68 | 69 | 70 | # 收到websocket连接建立的处理 71 | def on_open(ws): 72 | thread.start_new_thread(run, (ws,)) 73 | 74 | 75 | def run(ws, *args): 76 | data = json.dumps(gen_params(appid=ws.appid, domain= ws.domain,question=ws.question)) 77 | ws.send(data) 78 | 79 | 80 | # 收到websocket消息的处理 81 | def on_message(ws, message): 82 | # print(message) 83 | data = json.loads(message) 84 | code = data['header']['code'] 85 | if code != 0: 86 | print(f'请求错误: {code}, {data}') 87 | ws.close() 88 | else: 89 | choices = data["payload"]["choices"] 90 | status = choices["status"] 91 | content = choices["text"][0]["content"] 92 | print(content,end ="") 93 | global answer 94 | answer += content 95 | # print(1) 96 | if status == 2: 97 | ws.close() 98 | 99 | 100 | def gen_params(appid, domain,question): 101 | """ 102 | 通过appid和用户的提问来生成请参数 103 | """ 104 | data = { 105 | "header": { 106 | "app_id": appid, 107 | "uid": "1234" 108 | }, 109 | "parameter": { 110 | "chat": { 111 | "domain": domain, 112 | "random_threshold": 0.5, 113 | "max_tokens": 2048, 114 | "auditing": "default" 115 | } 116 | }, 117 | "payload": { 118 | "message": { 119 | "text": question 120 | } 121 | } 122 | } 123 | return data 124 | 125 | 126 | def main(appid, api_key, api_secret, Spark_url,domain, question): 127 | 128 | # print("星火:") 129 | wsParam = Ws_Param(appid, api_key, api_secret, Spark_url) 130 | websocket.enableTrace(False) 131 | wsUrl = wsParam.create_url() 132 | ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open) 133 | ws.appid = appid 134 | ws.question = question 135 | ws.domain = domain 136 | ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}) 137 | 138 | 139 | -------------------------------------------------------------------------------- /utils/tools.py: -------------------------------------------------------------------------------- 1 | import re 2 | import os 3 | import json 4 | import pandas as pd 5 | 6 | law_claim = '免责声明:本文档是由人工智能语言模型生成的文本,我们无法保证生成的文本完全准确、完整或适用于特定目的。任何使用本文档的个人或组织应该自行判断并承担使用本文档所产生的风险。' 7 | 8 | def json2md(json_data): 9 | json_data = extract_json_from_string(json_data) 10 | 11 | if isinstance(json_data,str): 12 | # if type(json_data) == "str": 13 | print(json_data) 14 | return "Invalid Str" 15 | 16 | json_data = flatten_dictionary(json_data) 17 | md_table = "\n|描述| 内容 |\n|-----|-----------------|\n" 18 | 19 | for key, value in json_data.items(): 20 | if isinstance(value, dict): 21 | value_str = ', '.join([f"{sub_key}: {sub_value}" for sub_key, sub_value in value.items()]) 22 | else: 23 | value_str = value 24 | 25 | md_table += f"| {key} | {value_str} |\n" 26 | 27 | print(md_table) 28 | return md_table 29 | 30 | def get_project_path(project_name='lawgpt_win'): 31 | # 获取当前文件的绝对路径 32 | p_path = os.path.abspath(os.path.dirname(__file__)) 33 | # 通过字符串截取方式获取 34 | return p_path[:p_path.index(project_name) + len(project_name)] 35 | 36 | 37 | def flatten_dictionary(d, parent_key='', sep='_'): 38 | items = [] 39 | for k, v in d.items(): 40 | new_key = parent_key + sep + k if parent_key else k 41 | if isinstance(v, dict): 42 | items.extend(flatten_dictionary(v, new_key, sep=sep).items()) 43 | else: 44 | items.append((new_key, v)) 45 | return dict(items) 46 | 47 | # 将展平的 DataFrame 转换回带字典的 JSON 格式 48 | def unflatten_dataframe(df, sep='_'): 49 | result = {} 50 | for col in df.columns: 51 | parts = col.split(sep) 52 | d = result 53 | for part in parts[:-1]: 54 | if part not in d: 55 | d[part] = {} 56 | d = d[part] 57 | d[parts[-1]] = df[col][0] 58 | return result 59 | 60 | def json2file(yuangao,beigao,second_state): 61 | json_data = { 62 | "原告": yuangao, 63 | "被告": beigao 64 | } 65 | json_data.update(second_state) 66 | 67 | project_path = get_project_path() 68 | generate_json_file(json_data, os.path.join(project_path,'output','json_folder','person.json')) 69 | 70 | def generate_json_file(data, filename): 71 | with open(filename, 'w',encoding='utf8') as f: 72 | json.dump(data, f, indent=4, ensure_ascii=False) 73 | 74 | 75 | 76 | def extract_json_from_string(text,outfile=None): 77 | ''' 78 | 请注意,上述示例假定只有一个有效的JSON文本。如果存在多个JSON文本,将只提取第一个匹配项。 79 | 80 | ''' 81 | text = text.replace("None", "null").replace("none", "null") 82 | 83 | patterns = [r'```json([\s\S]*)```',r'({[\s\S]*})',] 84 | 85 | for pa in patterns: 86 | match = re.search(pa, text) 87 | if match: 88 | break 89 | 90 | if match: 91 | json_text = match.group(1).strip() 92 | # print(json_text) 93 | try: 94 | data = json.loads(json_text) 95 | if outfile: 96 | generate_json_file(data,outfile) 97 | return data 98 | 99 | except json.JSONDecodeError as e: 100 | # print(f"Invalid JSON format: {e}") 101 | res = f"Invalid JSON format: {e} \n {json_text}" 102 | return res 103 | 104 | 105 | 106 | # 递归遍历 JSON 数据,将值为 null 的键值对的值设置为"无",但不包含有内容的键值对 107 | def transverse_on_json(json_data): 108 | """遍历json dict,寻找缺失值为空 109 | 110 | Args: 111 | json_data (_type_): _description_ 112 | 113 | Returns: 114 | _type_: _description_ 115 | """ 116 | keys_get = [] 117 | keys_miss = [] 118 | 119 | for key, value in json_data.items(): 120 | if isinstance(value, dict): 121 | keys_get_tmp,keys_miss_tmp = transverse_on_json(value) 122 | if keys_miss_tmp: 123 | keys_miss.append(key) 124 | else: 125 | keys_get.append(key) 126 | elif value: 127 | keys_get.append(key) 128 | elif value is None: 129 | keys_miss.append(key) 130 | return keys_get,keys_miss 131 | 132 | 133 | 134 | if __name__ == '__main__': 135 | text = ''' hel{"text":"school","name":"lily"}''' 136 | text = person_json_template="""{ "姓名": null, "性别": null, "出生日期": null, "民族": null, "住址": null, "联系方式": null, "身份证号": null, "法定代理人": {"姓名": null, "性别": null, "出生日期": null, "民族": null, "住址": null, "联系方式": null, "身份证号": null}, 委托诉讼代理人": { "姓名": null, "事务所": null } }""" 137 | # 138 | 139 | # status = extract_json_from_string(text,'output.json') 140 | # with open('output.json','r') as f: 141 | # data = json.load(f) 142 | # print(type(data),data) 143 | # print() 144 | 145 | # get,miss = transverse_on_json(data) 146 | # print(get) 147 | 148 | # print(miss) 149 | data = '{"住址": "河北省保定市阳光大街与东风路交叉口仁和公寓底商第12号"}' 150 | 151 | a = extract_json_from_string(text) 152 | print(a) 153 | -------------------------------------------------------------------------------- /law.yaml: -------------------------------------------------------------------------------- 1 | name: law 2 | channels: 3 | - defaults 4 | dependencies: 5 | - _libgcc_mutex=0.1=main 6 | - _openmp_mutex=5.1=1_gnu 7 | - ca-certificates=2023.05.30=h06a4308_0 8 | - ld_impl_linux-64=2.38=h1181459_1 9 | - libffi=3.4.4=h6a678d5_0 10 | - libgcc-ng=11.2.0=h1234567_1 11 | - libgomp=11.2.0=h1234567_1 12 | - libstdcxx-ng=11.2.0=h1234567_1 13 | - ncurses=6.4=h6a678d5_0 14 | - openssl=3.0.10=h7f8727e_0 15 | - pip=23.2.1=py38h06a4308_0 16 | - portaudio=19.6.0=h7b6447c_4 17 | - pyaudio=0.2.11=py38h7b6447c_2 18 | - python=3.8.17=h955ad1f_0 19 | - readline=8.2=h5eee18b_0 20 | - setuptools=68.0.0=py38h06a4308_0 21 | - sqlite=3.41.2=h5eee18b_0 22 | - tk=8.6.12=h1ccaba5_0 23 | - wheel=0.38.4=py38h06a4308_0 24 | - xz=5.4.2=h5eee18b_0 25 | - zlib=1.2.13=h5eee18b_0 26 | - pip: 27 | - aiofiles==23.2.1 28 | - aiohttp==3.8.5 29 | - aiosignal==1.3.1 30 | - altair==5.0.1 31 | - annotated-types==0.5.0 32 | - anthropic==0.3.10 33 | - anyio==3.7.1 34 | - async-timeout==4.0.3 35 | - attrs==23.1.0 36 | - av==10.0.0 37 | - backports-zoneinfo==0.2.1 38 | - beautifulsoup4==4.12.2 39 | - blinker==1.6.2 40 | - bokeh==2.4.1 41 | - brotli==1.0.9 42 | - cachetools==5.3.1 43 | - certifi==2023.7.22 44 | - cffi==1.15.1 45 | - charset-normalizer==3.2.0 46 | - click==8.1.7 47 | - contourpy==1.1.0 48 | - cycler==0.11.0 49 | - dataclasses-json==0.5.14 50 | - distro==1.8.0 51 | - docopt==0.6.2 52 | - duckduckgo-search==3.8.5 53 | - exceptiongroup==1.1.3 54 | - faker==19.3.0 55 | - fastapi==0.101.1 56 | - favicon==0.7.0 57 | - ffmpeg==1.4 58 | - ffmpy==0.3.1 59 | - filelock==3.12.2 60 | - flask==2.3.2 61 | - fonttools==4.42.0 62 | - frozenlist==1.4.0 63 | - fsspec==2023.6.0 64 | - gevent==1.4.0 65 | - gitdb==4.0.10 66 | - gitpython==3.1.32 67 | - gradio==3.40.1 68 | - gradio-client==0.4.0 69 | - greenlet==0.4.15 70 | - gtts==2.3.2 71 | - h11==0.14.0 72 | - h2==4.1.0 73 | - hpack==4.0.0 74 | - htbuilder==0.6.1 75 | - httpcore==0.17.3 76 | - httpx==0.24.1 77 | - huggingface-hub==0.16.4 78 | - hyperframe==6.0.1 79 | - idna==3.4 80 | - importlib-metadata==6.8.0 81 | - importlib-resources==6.0.1 82 | - itsdangerous==2.1.2 83 | - jinja2==3.1.2 84 | - js2py==0.74 85 | - jsonschema==4.19.0 86 | - jsonschema-specifications==2023.7.1 87 | - kiwisolver==1.4.4 88 | - langchain==0.0.268 89 | - langsmith==0.0.25 90 | - linkify-it-py==2.0.2 91 | - loguru==0.7.0 92 | - lxml==4.9.3 93 | - markdown==3.4.4 94 | - markdown-it-py==2.2.0 95 | - markdownlit==0.0.7 96 | - markupsafe==2.1.3 97 | - marshmallow==3.20.1 98 | - matplotlib==3.7.2 99 | - mdit-py-plugins==0.3.3 100 | - mdurl==0.1.2 101 | - more-itertools==10.1.0 102 | - multidict==6.0.4 103 | - mypy-extensions==1.0.0 104 | - numexpr==2.8.5 105 | - numpy==1.24.4 106 | - openai==0.27.8 107 | - orjson==3.9.5 108 | - packaging==23.1 109 | - pandas==2.0.3 110 | - pillow==9.5.0 111 | - pipwin==0.5.2 112 | - pkgutil-resolve-name==1.3.10 113 | - protobuf==4.24.1 114 | - pyarrow==12.0.1 115 | - pycparser==2.19 116 | - pydantic==1.10.12 117 | - pydantic-core==2.6.1 118 | - pydeck==0.8.0 119 | - pydub==0.25.1 120 | - pygments==2.16.1 121 | - pyjsparser==2.7.1 122 | - pymdown-extensions==10.1 123 | - pympler==1.0.1 124 | - pyparsing==3.0.9 125 | - pyprind==2.11.3 126 | - pyproject==1.3.1 127 | - pysmartdl==1.3.4 128 | - python-dateutil==2.8.2 129 | - python-docx==0.8.11 130 | - python-multipart==0.0.6 131 | - pytz==2023.3 132 | - pytz-deprecation-shim==0.1.0.post0 133 | - pyyaml==6.0.1 134 | - referencing==0.30.2 135 | - requests==2.31.0 136 | - rich==13.5.2 137 | - rpds-py==0.9.2 138 | - semantic-version==2.10.0 139 | - six==1.12.0 140 | - smmap==5.0.0 141 | - sniffio==1.3.0 142 | - socksio==1.0.0 143 | - sounddevice==0.4.6 144 | - soupsieve==2.4.1 145 | - speechrecognition==3.10.0 146 | - sqlalchemy==2.0.20 147 | - st-annotated-text==4.0.0 148 | - starlette==0.27.0 149 | - streamlit==1.25.0 150 | - streamlit-bokeh-events==0.1.2 151 | - streamlit-camera-input-live==0.2.0 152 | - streamlit-card==0.0.61 153 | - streamlit-chat==0.1.1 154 | - streamlit-embedcode==0.1.2 155 | - streamlit-extras==0.3.0 156 | - streamlit-faker==0.0.2 157 | - streamlit-feedback==0.0.9 158 | - streamlit-image-coordinates==0.1.6 159 | - streamlit-keyup==0.2.0 160 | - streamlit-toggle-switch==1.0.2 161 | - streamlit-vertical-slider==1.0.2 162 | - tenacity==8.2.3 163 | - tokenizers==0.13.3 164 | - toml==0.10.2 165 | - toolz==0.12.0 166 | - tornado==6.3.3 167 | - tqdm==4.66.1 168 | - trubrics==1.4.5 169 | - typeguard==2.13.3 170 | - typer==0.9.0 171 | - typing-extensions==4.7.1 172 | - typing-inspect==0.9.0 173 | - tzdata==2023.3 174 | - tzlocal==4.3.1 175 | - uc-micro-py==1.0.2 176 | - urllib3==2.0.4 177 | - uvicorn==0.23.2 178 | - validators==0.21.2 179 | - watchdog==3.0.0 180 | - wave==0.0.2 181 | - websocket==0.2.1 182 | - websocket-client==0.58.0 183 | - websockets==11.0.3 184 | - werkzeug==2.3.7 185 | - xyzservices==2023.7.0 186 | - yarl==1.9.2 187 | - zipp==3.16.2 188 | - zope-event==5.0 189 | - zope-interface==6.0 190 | prefix: /root/anaconda3/envs/law 191 | -------------------------------------------------------------------------------- /utils/audio_gen/gen_audio.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # 3 | # author: iflytek 4 | # 5 | # 本demo测试时运行的环境为:Windows + Python3.7 6 | # 本demo测试成功运行时所安装的第三方库及其版本如下: 7 | # cffi==1.12.3 8 | # gevent==1.4.0 9 | # greenlet==0.4.15 10 | # pycparser==2.19 11 | # six==1.12.0 12 | # websocket==0.2.1 13 | # websocket-client==0.56.0 14 | # 合成小语种需要传输小语种文本、使用小语种发音人vcn、tte=unicode以及修改文本编码方式 15 | # 错误码链接:https://www.xfyun.cn/document/error-code (code返回错误码时必看) 16 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 17 | import websocket 18 | import datetime 19 | import hashlib 20 | import base64 21 | import hmac 22 | import json 23 | from urllib.parse import urlencode 24 | import time 25 | import ssl 26 | from wsgiref.handlers import format_date_time 27 | from datetime import datetime 28 | from time import mktime 29 | import _thread as thread 30 | import os 31 | 32 | 33 | STATUS_FIRST_FRAME = 0 # 第一帧的标识 34 | STATUS_CONTINUE_FRAME = 1 # 中间帧标识 35 | STATUS_LAST_FRAME = 2 # 最后一帧的标识 36 | 37 | 38 | class Ws_Param(object): 39 | # 初始化 40 | def __init__(self, APPID, APIKey, APISecret, Text): 41 | self.APPID = APPID 42 | self.APIKey = APIKey 43 | self.APISecret = APISecret 44 | self.Text = Text 45 | 46 | # 公共参数(common) 47 | self.CommonArgs = {"app_id": self.APPID} 48 | # 业务参数(business),更多个性化参数可在官网查看 49 | self.BusinessArgs = {"aue": "raw", "auf": "audio/L16;rate=16000","vcn": "xiaoyan", "tte": "utf8"}# "sfl":1, 50 | self.Data = {"status": 2, "text": str(base64.b64encode(self.Text.encode('utf-8')), "UTF8")} 51 | #使用小语种须使用以下方式,此处的unicode指的是 utf16小端的编码方式,即"UTF-16LE"” 52 | #self.Data = {"status": 2, "text": str(base64.b64encode(self.Text.encode('utf-16')), "UTF8")} 53 | 54 | # 生成url 55 | def create_url(self): 56 | url = 'wss://tts-api.xfyun.cn/v2/tts' 57 | # 生成RFC1123格式的时间戳 58 | now = datetime.now() 59 | date = format_date_time(mktime(now.timetuple())) 60 | 61 | # 拼接字符串 62 | signature_origin = "host: " + "ws-api.xfyun.cn" + "\n" 63 | signature_origin += "date: " + date + "\n" 64 | signature_origin += "GET " + "/v2/tts " + "HTTP/1.1" 65 | # 进行hmac-sha256进行加密 66 | signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'), 67 | digestmod=hashlib.sha256).digest() 68 | signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8') 69 | 70 | authorization_origin = "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"" % ( 71 | self.APIKey, "hmac-sha256", "host date request-line", signature_sha) 72 | authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8') 73 | # 将请求的鉴权参数组合为字典 74 | v = { 75 | "authorization": authorization, 76 | "date": date, 77 | "host": "ws-api.xfyun.cn" 78 | 79 | } 80 | # 拼接鉴权参数,生成url 81 | url = url + '?' + urlencode(v) 82 | # print("date: ",date) 83 | # print("v: ",v) 84 | # 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致 85 | # print('websocket url :', url) 86 | return url 87 | 88 | def on_message(ws, message): 89 | try: 90 | message =json.loads(message) 91 | code = message["code"] 92 | sid = message["sid"] 93 | audio = message["data"]["audio"] 94 | audio = base64.b64decode(audio) 95 | status = message["data"]["status"] 96 | #print(message) 97 | if status == 2: 98 | print("ws is closed") 99 | ws.close() 100 | if code != 0: 101 | errMsg = message["message"] 102 | print("sid:%s call error:%s code is:%s" % (sid, errMsg, code)) 103 | else: 104 | print("write to demo") 105 | with open('./demo.pcm', 'ab') as f: 106 | f.write(audio) 107 | print("ok") 108 | except Exception as e: 109 | print("receive msg,but parse exception:", e) 110 | 111 | 112 | 113 | # 收到websocket错误的处理 114 | def on_error(ws, error): 115 | print("### error:", error) 116 | 117 | 118 | # 收到websocket关闭的处理 119 | def on_close(ws): 120 | print("### closed ###") 121 | 122 | 123 | # 收到websocket连接建立的处理 124 | def on_open(ws): 125 | def run(*args): 126 | d = {"common": wsParam.CommonArgs, 127 | "business": wsParam.BusinessArgs, 128 | "data": wsParam.Data, 129 | } 130 | d = json.dumps(d) 131 | print("------>开始发送文本数据") 132 | ws.send(d) 133 | if os.path.exists('./demo.pcm'): 134 | os.remove('./demo.pcm') 135 | 136 | thread.start_new_thread(run, ()) 137 | 138 | 139 | def gen_audio(content): 140 | # 测试时候在此处正确填写相关信息即可运行 141 | wsParam = Ws_Param(APPID='ac0d049c', APISecret='MTIyMzY2ZGEwMjJlNDkyNzU3N2JhYjU3', 142 | APIKey='f3893454045f4e3dea21444b2b505df8', 143 | Text=content) 144 | websocket.enableTrace(False) 145 | wsUrl = wsParam.create_url() 146 | ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close,) 147 | ws.on_open = on_open 148 | ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}) 149 | # if __name__ == "__main__": 150 | 151 | 152 | # # -*- coding: utf-8 -*- 153 | # """ 154 | # Created on Sat Aug 19 21:53:41 2023 155 | 156 | # @author: spark2023-30 157 | # """ 158 | 159 | # from pydub import AudioSegment 160 | # from pydub.playback import play 161 | 162 | # # 读取PCM音频文件 163 | # pcm_audio = AudioSegment.from_file("demo.pcm", format="raw", frame_rate=16000, channels=1, sample_width=2) 164 | 165 | # # 播放音频 166 | # play(pcm_audio) 167 | 168 | -------------------------------------------------------------------------------- /utils/iflytek/Spark.py: -------------------------------------------------------------------------------- 1 | 2 | import _thread as thread 3 | import base64 4 | import datetime 5 | import hashlib 6 | import hmac 7 | import json 8 | import ssl 9 | from datetime import datetime 10 | from time import mktime 11 | from urllib.parse import urlencode, urlparse 12 | from wsgiref.handlers import format_date_time 13 | 14 | import websocket # 使用websocket_client 15 | 16 | 17 | class Ws_Param(object): 18 | # 初始化 19 | def __init__(self, APPID, APIKey, APISecret, Spark_url): 20 | self.APPID = APPID 21 | self.APIKey = APIKey 22 | self.APISecret = APISecret 23 | self.host = urlparse(Spark_url).netloc 24 | self.path = urlparse(Spark_url).path 25 | self.Spark_url = Spark_url 26 | 27 | # 生成url 28 | def create_url(self): 29 | # 生成RFC1123格式的时间戳 30 | now = datetime.now() 31 | date = format_date_time(mktime(now.timetuple())) 32 | 33 | # 拼接字符串 34 | signature_origin = "host: " + self.host + "\n" 35 | signature_origin += "date: " + date + "\n" 36 | signature_origin += "GET " + self.path + " HTTP/1.1" 37 | 38 | # 进行hmac-sha256进行加密 39 | signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'), 40 | digestmod=hashlib.sha256).digest() 41 | 42 | signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8') 43 | 44 | authorization_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"' 45 | 46 | authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8') 47 | 48 | # 将请求的鉴权参数组合为字典 49 | v = { 50 | "authorization": authorization, 51 | "date": date, 52 | "host": self.host 53 | } 54 | # 拼接鉴权参数,生成url 55 | url = self.Spark_url + '?' + urlencode(v) 56 | # 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致 57 | return url 58 | 59 | 60 | # 收到websocket错误的处理 61 | def on_error(ws, error): 62 | print("### error:", error) 63 | 64 | 65 | # 收到websocket关闭的处理 66 | def on_close(ws,one,two): 67 | print(" ") 68 | 69 | 70 | # 收到websocket连接建立的处理 71 | def on_open(ws): 72 | thread.start_new_thread(run, (ws,)) 73 | 74 | 75 | def run(ws, *args): 76 | data = json.dumps(gen_params(appid=ws.appid, domain= ws.domain,question=ws.question)) 77 | ws.send(data) 78 | 79 | 80 | # 收到websocket消息的处理 81 | def on_message(ws, message): 82 | # print(message) 83 | data = json.loads(message) 84 | code = data['header']['code'] 85 | if code != 0: 86 | print(f'请求错误: {code}, {data}') 87 | ws.close() 88 | else: 89 | choices = data["payload"]["choices"] 90 | status = choices["status"] 91 | content = choices["text"][0]["content"] 92 | # print(content,end ="") 93 | global answer 94 | answer += content 95 | # print(1) 96 | if status == 2: 97 | ws.close() 98 | 99 | 100 | def gen_params(appid, domain,question): 101 | """ 102 | 通过appid和用户的提问来生成请参数 103 | """ 104 | data = { 105 | "header": { 106 | "app_id": appid, 107 | "uid": "1234" 108 | }, 109 | "parameter": { 110 | "chat": { 111 | "domain": domain, 112 | "random_threshold": 0.5, 113 | "max_tokens": 2048, 114 | "auditing": "default" 115 | } 116 | }, 117 | "payload": { 118 | "message": { 119 | "text": question 120 | } 121 | } 122 | } 123 | return data 124 | 125 | 126 | class Spark(object): 127 | def __init__(self): 128 | self.appid = "f54bca1a" 129 | self.api_key = "2e7516edf376713eb5d99fc812a87ed5" 130 | self.api_secret = "ZGJmMjY3YWFmNGY5N2Q1YWMwOGZlMjFh" 131 | 132 | # 用于配置大模型版本,默认“generalv2” 云端环境的服务地址 133 | self.domain = "generalv2" 134 | self.Spark_url = "ws://spark-api.xf-yun.com/v2.1/chat" # v2.0环境的地址 135 | 136 | 137 | def _checklen(self,chat_list,length=8000): 138 | while (self._get_length(chat_list) > length): 139 | del chat_list[0] 140 | return chat_list 141 | 142 | def _get_all_content(self,chat_list): 143 | chat_list = self._checklen(chat_list,length=4000) 144 | res = '' 145 | for content in chat_list: 146 | res = content["content"] 147 | return res 148 | 149 | 150 | def _get_length(self,chat_list): 151 | length = 0 152 | for content in chat_list: 153 | temp = content["content"] 154 | leng = len(temp) 155 | length += leng 156 | return length 157 | 158 | def main(self,chat_list): 159 | global answer 160 | answer = '' 161 | 162 | chat_list = self._checklen(chat_list) 163 | wsParam = Ws_Param(self.appid, self.api_key, self.api_secret, self.Spark_url) 164 | websocket.enableTrace(False) 165 | wsUrl = wsParam.create_url() 166 | ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open) 167 | ws.appid = self.appid 168 | ws.question = chat_list 169 | ws.domain = self.domain 170 | ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}) 171 | 172 | return answer 173 | 174 | if __name__ == '__main__': 175 | api = Spark() 176 | 177 | prompt1 = [{'role':'asistant','content':'how can i help you?'},{'role':'user','content':'write me a bubble sort algorithm.'}] 178 | 179 | res = api.main(prompt1) 180 | print(res) 181 | 182 | prompt1.append({'role':'asistant','content':res}) 183 | 184 | prompt2 = [{'role':'user','content':'what is the meaning of code above'}] 185 | 186 | res = api.main(prompt1+prompt2) 187 | print('--'*40) 188 | print(res) 189 | -------------------------------------------------------------------------------- /utils/prompt_config_l.py: -------------------------------------------------------------------------------- 1 | # 对话开始 2 | start_chat="您好,我是星火起诉书生成助手,很高兴为您服务!\n\n 我现在需要**原告**的信息。\n\n请问原告是 *自然人(个人)* 还是 *非自然人(公司)* 呢?" 3 | 4 | # {"姓名": null, "性别": null json Template#ull, "住址": null, "联系方式": null, "身份证号": null} 5 | person_json_template="""{'姓名': null, '性别': null, '出生日期': null, '民族': null, '住址': null, '联系方式': null, '身份证号': null, "法定代理人": null, '委托诉讼代理人': {'姓名': null, '事务所': null}}""" 6 | company_json_template="""{ "公司名称": null, "公司所在地": null, '统一社会信用代码': null, "法人": { "姓名": null, "职务": null, "联系方式": null},"委托诉讼代理人": {"姓名": null,"事务所": null}}""" 7 | 8 | # Prompt 9 | gudie_1_2="下面有段客户的文字,请判断客户是需要以个人的名义还是公司的名义起诉,如果是个人请输出1,否则输出2。记住只需1或2。提问和回答如下:" 10 | # person_json_template="""{ "姓名": null, "性别": null, "出生日期": null, "民族": null, "住址": { "省份": null, "城市": null, "区/县": null }, "联系方式": null, "委托诉讼代理人": { "姓名": null, "事务所": null } }""" 11 | guide_agent="""客户将告诉你是否需要委托代理人。若用户没有或者不需要委托代理人,则不变;如有请填入下面的json模板中"""+person_json_template+"""提问和回答如下: """ 12 | address_complete_json=""",请帮我补全以上住址使其包含省市区信息,并以如下json格式输出:{"住址":""}""" 13 | # gudie_json="""你是一名精通民事起诉的律师。客户将给你一段文字,需要你提取全部关键信息,不丢失信息,填充到下面的json文件中,并符合json语法,记住只需把这个json文件输出给我。"""+json_template+"""提问和回答如下: """ 14 | gudie_yuangao_person_json="""你是一名精通民事起诉的律师。客户将给你一段文字,需要你提取全部关键信息,不丢失信息,填充到下面的json文件中,并符合json语法,记住只需把这个json文件输出给我。"""+person_json_template+"""提问和回答如下: """ 15 | gudie_beigao_person_json="""你是一名精通民事起诉的律师。客户将给你一段文字,需要你提取被告人的全部关键信息,不丢失信息,填充到下面的json文件中,并符合json语法,记住只需把这个json文件输出给我。"""+person_json_template+"""提问和回答如下: """ 16 | 17 | gudie_yuangao_company_json="""你是一名精通民事起诉的律师。客户将给你一段文字,需要你提取全部关键信息,不丢失信息,填充到下面的json文件中,并符合json语法,记住只需把这个json文件输出给我。"""+company_json_template+"""提问和回答如下: """ 18 | gudie_beigao_company_json="""你是一名精通民事起诉的律师。客户将给你一段文字,需要你提取被告公司的全部关键信息,不丢失信息,填充到下面的json文件中,并符合json语法,记住只需把这个json文件输出给我。"""+company_json_template+"""提问和回答如下: """ 19 | 20 | gudie_again="你是一名精通民事起诉的律师。客户将给你一段文字,需要你判断是否客户需要继续加入原告信息,如果需要请输出1,否则输出2。记住只需1或2。提问和回答如下:" 21 | gudie_again_2="你是一名精通民事起诉的律师。客户将给你一段文字,需要你判断是否客户需要继续加入被告信息,如果需要请输出1,否则输出2。记住只需1或2。提问和回答如下:" 22 | gudie_question="""你是一名精通民事起诉的律师。已经有的诉讼书内容的json文件如下。"""+person_json_template+"""请输出一句话,继续引导用户补全信息""" 23 | 24 | gudie_second_json1="""你是一名精通民事起诉的律师。客户将给你一段文字,仅需提取案由、诉讼请求、事实和理由。如有证据,请说明证据和证据来源;请注意,用户说明中,若无证据请勿编纂留空。 25 | 提问和回答如下:""" 26 | 27 | gudie_second_json2="""把这段话填入这份json文件中。不要修改原句,也不要生成新的键。 28 | { "案由": null, 诉讼请求": null, "事实和理由": null, "证据": { "证据和证据来源": null, "证人姓名和住所": null } }""" 29 | second_guide="好的,我已经知道您的原告的基本信息了。请问您可以继续提供被告人的信息吗?包括姓名、性别、出生日期、民族、住址、联系方式" 30 | third_guide="好的,我已经知道您的所有基本信息了。能进一步给出您的诉讼请求吗?" 31 | 32 | gudie_second_step0="""请根据用户输入判断案由类型,案由类型一般有机动车交通事故责任纠纷、民间借贷纠纷、离婚纠纷、合同纠纷、买卖合同纠纷、金融借款合同纠纷、借款合同纠纷、劳动争议、房屋买卖合同纠纷、建设工程施工合同纠纷、土地经营权纠纷等,如果不是以上案由类型,请自行判断,请注意一定要以以下json格式输出案由类别:{"案由":""},用户的输入是:""" 33 | guide_second_step1="""以上是可以参考的诉讼请求模板,请根据以下原告描述内容生成诉讼请求部分,注意严格按照原告意思,不要随意篡改,不要出现第一第二第三人称。请注意分点阐述,原告:""" 34 | # 事实和请求 35 | guide_second_step2="""以上是可以参考的事实与理由模板,请根据以下原告描述内容生成事实与理由部分,注意严格按照原告意思,不要随意篡改,不要出现第一第二第三人称。请注意分点阐述,原告:""" 36 | # 证据 37 | gudie_second_step3="""你是一名精通民事起诉的律师。请从下面客户输入的文字中提取客户说的证据内容,注意只需要输出证据""" 38 | gudie_second_step4="""你是一名律师,我会告诉你被告人的住址,请列举他们住所地的人民法院,并只输出法院名称。例如福建省福州是仓山区人民法院这样的管辖法院。住址是""" 39 | gudie_second_step5="""你是一名精通民事起诉的律师。请从下面客户输入的文字中提取客户说的法院信息""" 40 | 41 | # 为一段对话生成标题 42 | summary_chat_prompt = '我给你提供一段对话,请你帮我生成20字以内的标题,请体现文字具体信息和特点。' 43 | 44 | # 总结相关法律知识的知识卡片 45 | knowledge_comment_prompt = '你是知识提示卡片,请回答涉及到的相关法律以及具体条款,分条简单阐述,大概的结构:“涉及的法律和具体条款:1.某个法律的某一条规定了什么什么什么\n2. 某个法律的某一条规定了什么什么什么\n”。请注意无需体现与案件有关信息。' 46 | 47 | 48 | # 寻找相关案例的判罚情况 49 | related_result_prompt = '假如你是一个法官,请找出与下面诉讼请求相似内容的某一个案件的判罚情况,要给出案件、判罚情况、事实和理由以及证据。请注意不要给出下面案件的判罚及相关信息。' 50 | 51 | 52 | #判断是个人还是公司 53 | res_judge_p_1=["个人","1","我自己","自然人"] 54 | res_judge_c_2=["公司","企业","2","非自然人","不是自然人"] 55 | 56 | 57 | #判断是否继续添加信息 58 | res_judge_go_1=["继续","再加一个","是","需要","要的","行呀","添加","可以"] 59 | res_judge_no_2=["不继续","不用","没有了","否","是我自己","不需要","不要","不添加了","不"] 60 | res_judge_jj_3=["手机号码是","代理人是","汉族","性别"] 61 | 62 | # 民间借贷—事实和理由提示 63 | debt_usr_reason_example = "\n事实与理由:原告经人介绍认识被告,后被告以店铺经营周转为由多次找原告借钱。2023年8月24日,被告为还银行贷款向原告处借款50000元,借款期限为3个月,双方约定按年利率3%支付利息,承诺承担连带保证责任。基于对被告的信任,原告以现金的方式向被告交付了借款。后原告因自己急于用钱多次向被告催要借款,但被告以各种理由拖延,拒不归还借款。为了维护原告的合法权利,特向贵院提起诉讼。" 64 | 65 | # 民间借贷—诉讼请求提示 66 | debt_usr_request_example = "\n诉讼请求:\n1. 请求被告归还借款50000元及利息;\n2. 请求判令保证人请在此输入保证人姓名对借款本息承担连带保证责任;\n3、请求判令本案诉讼费用由被告承担。" 67 | 68 | debt_usr_reason_prompt = "1. 双方认识过程\n2. 被告借款的原因:(还银行贷款/投资需要/买房/买车/资金周转/其他原因)\n 3. 被告借款金额(元)\n 4. 借款的交付方式:现金/银行转账/网络电子汇款/票据支付\n 4. 被告借款的时间\n 5. 您与被告约定的借款期限?(月)\n 6. 是否约定了利息。如有,请说明约定的利息(年利率%)\n 7. 合同是书面还是口头订立(书面合同/口头约定)\n 8. 是否向被告催要过\n 9. 合同法中是否约定了保证人?如有,保证的方式(一般保证/连带责任保持),是否起诉保证人" 69 | 70 | debt_usr_request_prompt = "1. 本金和利息\n 2. 是否起诉保证人\n 3. 诉讼费律师费等" 71 | 72 | traffic_usr_reason_prompt ="1. **当事人类型:** 机动车驾驶员 / 非机动车驾驶员(类型:电动自行车 / 自行车 / 三轮车) / 乘车人 / 行人\n2. **交警部门责任认定:**\n\t1) 交警部门是否做出责任认定?\n\t\ta) 被告方当事人在事故中的责任(无责任,次要责任,同等责任,主要责任,全部责任,双方无责任) \n\t\t\ti. 是否接受交警部门的认定? \n\t\tb) 交警部门未作认定\n3. **事故发生时间:** xx年xx月xx日\n4. **是否协商过赔偿事宜:**\n5. **对方车辆是否购买汽车强制保险:**\n\t1) 已购买:保险公司是否已赔偿相关损失(已赔偿 / 未赔偿)\n\t2) 未购买\n\t3) 不清楚" 73 | 74 | traffic_usr_request_prompt ="**当事人损失包括:**\n\t1) 财产损失(车辆损失,其他财产损失):\n\t\ta) 财产损失(施救花费,维修花费,车辆停运导致的损失,使用替代交通工具产生的费用,车辆彻底损坏的损失,其他财产的损失)\n\t\tb) 财产损失金额(元)\n\t2) 人身损失:\n\t\ta) 人身损失(医疗费,交通费,住宿费,住宿伙食补助费,营养费,护理费,误工费,鉴定费,后续治疗费,残疾赔偿金,被扶养人生活费,精神损失抚慰金,其他)\n\t\tb) 人身损害金额(元)\n\t\tc) 是否住院: \n\t\t\ti. 住过(住院时间、出院时间) \n\t\tii. 没住过 \n\t\td) 有无做过伤残等级鉴定" 75 | 76 | # 机动车—事实和理由提示 77 | traffic_usr_reason_example = "\n事实与理由:\n2008年5月5日 时许,被告一驾驶轿车沿横滨之路行驶至凤城五路口处时,因速度过快、未注意观察,将原告撞伤,发生交通事故(写事故发生的时间、地点、经过)。后经认定被告一对事故发生负全部责任(写责任认定)。事发后,原告被送 医院接受治疗(写治疗经过)。经查证,被告一驾驶的车辆在被告二处投保了保险,事故发生在保险期内(写车辆投保情况)。事故发生后,各方就赔偿事宜协商未果,为维护原告的合法权益,特提起诉讼,请贵院依法支持诉请。" 78 | 79 | # 机动车—上述请求提示 80 | traffic_usr_request_example = "\n诉讼请求:\n1、请求判决两被告赔偿原告的医疗费5000元,交通费500元,住宿费2678元,财产损失2456元,残疾辅助工具费678元,伙食补助费56元,合计4567876元。残疾赔偿金、被抚养人生活费、精神损害抚慰金、误工费、护理费、营养费、鉴定费等具体赔偿数额,待司法鉴定后再行主张。\n2、请求法院判决被告二优先赔偿原告的损失;超出部分由被告一承担。\n3、请求法院依法判决本案诉讼费用、鉴定费用由被告承担。" 81 | 82 | # 离婚—事实和理由提示 83 | divorce_usr_reason_prompt = "事实和理由:\n原告与被告 年 月份相识,后于 年 月 日登记结婚, 年生育一子 (婚恋及家庭情况),由于婚前双方实际相处时间不多,对彼此的了解不深,在婚后长达 年的生活中,被告时常因家庭琐事频繁殴打、辱骂原告,婚内还与多名异性保持不正当关系,给原告及家庭带来诸多的伤害。(写感情破裂的表现)\n原告认为,由于原被告在婚后没有建立稳固的夫妻感情,被告时常有家庭暴力行为,还与异性发生不正当关系,导致双方感情已经完全破裂、毫无和好可能,正常的家庭生活中原告的个人安全也得不到保障,理当结束这段婚姻。(离婚原因)\n综上所述,为维护原告的合法权益,为保护原告的婚姻自由权利,特向法院提起诉讼,请求法院依法支持原告的全部诉讼请求。" 84 | 85 | # 离婚-诉讼请求提示 86 | divorce_usr_request_prompt = "诉讼请求:\n1、请求法院依法判决原被告离婚;(离婚)\n2、请求判决儿女 归被告抚养,原告不承担抚养费;(子女抚养问题)\n3、请求法院依法分割位于 号 幢 单元 室的房屋;(财产分割,可以逐个列出)\n4、请求判决被告赔偿原告精神损害抚慰金 万元;(无过错方可以主张家暴精神赔偿)\n5、请求判决本案诉讼费用由被告承担。(诉讼费)" -------------------------------------------------------------------------------- /utils/audio_gen/play_audio.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # 3 | # author: iflytek 4 | # 5 | # 本demo测试时运行的环境为:Windows + Python3.7 6 | # 本demo测试成功运行时所安装的第三方库及其版本如下: 7 | # cffi==1.12.3 8 | # gevent==1.4.0 9 | # greenlet==0.4.15 10 | # pycparser==2.19 11 | # six==1.12.0 12 | # websocket==0.2.1 13 | # websocket-client==0.56.0 14 | # 合成小语种需要传输小语种文本、使用小语种发音人vcn、tte=unicode以及修改文本编码方式 15 | # 错误码链接:https://www.xfyun.cn/document/error-code (code返回错误码时必看) 16 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 17 | import websocket 18 | import datetime 19 | import hashlib 20 | import base64 21 | import hmac 22 | import json 23 | from urllib.parse import urlencode 24 | import time 25 | import ssl 26 | from wsgiref.handlers import format_date_time 27 | from datetime import datetime 28 | from time import mktime 29 | import _thread as thread 30 | import os 31 | import numpy as np 32 | from pydub import AudioSegment 33 | from utils.tools import get_project_path 34 | 35 | demo_pcm_file = os.path.join(get_project_path(),'output','demo.pcm') 36 | print(demo_pcm_file) 37 | 38 | 39 | STATUS_FIRST_FRAME = 0 # 第一帧的标识 40 | STATUS_CONTINUE_FRAME = 1 # 中间帧标识 41 | STATUS_LAST_FRAME = 2 # 最后一帧的标识 42 | 43 | 44 | def on_message(ws, message): 45 | 46 | try: 47 | message = json.loads(message) 48 | code = message["code"] 49 | sid = message["sid"] 50 | audio = message["data"]["audio"] 51 | audio = base64.b64decode(audio) # Convert the base64 audio data to bytes 52 | status = message["data"]["status"] 53 | 54 | if status == 2: 55 | # print("ws is closed") 56 | ws.close() 57 | if code != 0: 58 | errMsg = message["message"] 59 | print("sid:%s call error:%s code is:%s" % (sid, errMsg, code)) 60 | else: 61 | # print("pcm写入成功") 62 | with open(demo_pcm_file, 'ab') as f: 63 | f.write(audio) 64 | 65 | 66 | except Exception as e: 67 | print("receive msg, but parse exception:", e) 68 | 69 | 70 | # 收到websocket错误的处理 71 | def on_error(ws, error): 72 | print("### error:", error) 73 | 74 | 75 | # 收到websocket关闭的处理 76 | def on_close(ws): 77 | print("### closed ###") 78 | 79 | 80 | # 收到websocket连接建立的处理 81 | def on_open(ws): 82 | def run(*args): 83 | APPID='ac0d049c' 84 | APISecret='MTIyMzY2ZGEwMjJlNDkyNzU3N2JhYjU3' 85 | APIKey='f3893454045f4e3dea21444b2b505df8' 86 | global content_user 87 | Text=content_user 88 | # 公共参数(common) 89 | CommonArgs = {"app_id": APPID} 90 | # 业务参数(business),更多个性化参数可在官网查看 91 | BusinessArgs = {"aue": "raw", "auf": "audio/L16;rate=16000","vcn": "xiaoyan", "tte": "utf8"}# "sfl":1, 92 | Data = {"status": 2, "text": str(base64.b64encode(Text.encode('utf-8')), "UTF8")} 93 | d = {"common": CommonArgs, 94 | "business": BusinessArgs, 95 | "data": Data, 96 | } 97 | d = json.dumps(d) 98 | # print("------>开始发送文本数据") 99 | ws.send(d) 100 | if os.path.exists(demo_pcm_file): 101 | os.remove(demo_pcm_file) 102 | 103 | thread.start_new_thread(run, ()) 104 | 105 | def create_url(APPID,APISecret,APIKey,CommonArgs,BusinessArgs,Data): 106 | url = 'wss://tts-api.xfyun.cn/v2/tts' 107 | # 生成RFC1123格式的时间戳 108 | now = datetime.now() 109 | date = format_date_time(mktime(now.timetuple())) 110 | 111 | # 拼接字符串 112 | signature_origin = "host: " + "ws-api.xfyun.cn" + "\n" 113 | signature_origin += "date: " + date + "\n" 114 | signature_origin += "GET " + "/v2/tts " + "HTTP/1.1" 115 | # 进行hmac-sha256进行加密 116 | signature_sha = hmac.new(APISecret.encode('utf-8'), signature_origin.encode('utf-8'), 117 | digestmod=hashlib.sha256).digest() 118 | signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8') 119 | 120 | authorization_origin = "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"" % ( 121 | APIKey, "hmac-sha256", "host date request-line", signature_sha) 122 | authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8') 123 | # 将请求的鉴权参数组合为字典 124 | v = { 125 | "authorization": authorization, 126 | "date": date, 127 | "host": "ws-api.xfyun.cn" 128 | 129 | } 130 | # 拼接鉴权参数,生成url 131 | url = url + '?' + urlencode(v) 132 | # print("date: ",date) 133 | # print("v: ",v) 134 | # 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致 135 | # print('websocket url :', url) 136 | return url 137 | 138 | def gen_audio(Text): 139 | # 测试时候在此处正确填写相关信息即可运行 140 | APPID='ac0d049c' 141 | APISecret='MTIyMzY2ZGEwMjJlNDkyNzU3N2JhYjU3' 142 | APIKey='f3893454045f4e3dea21444b2b505df8' 143 | # APPID='b280520e' 144 | # APISecret='ZGE4NmYxYTRkM2EyMzRiNGUyNWZiMzg4' 145 | # APIKey='2d7ea59e8fe2c6a462354e544a67fc0d' 146 | 147 | 148 | global content_user 149 | content_user=Text 150 | # 公共参数(common) 151 | CommonArgs = {"app_id": APPID} 152 | # 业务参数(business),更多个性化参数可在官网查看 153 | BusinessArgs = {"aue": "raw", "auf": "audio/L16;rate=16000","vcn": "xiaoyan", "tte": "utf8"}# "sfl":1, 154 | Data = {"status": 2, "text": str(base64.b64encode(Text.encode('utf-8')), "UTF8")} 155 | #使用小语种须使用以下方式,此处的unicode指的是 utf16小端的编码方式,即"UTF-16LE"” 156 | #self.Data = {"status": 2, "text": str(base64.b64encode(self.Text.encode('utf-16')), "UTF8")} 157 | 158 | wsUrl = create_url(APPID,APISecret,APIKey,CommonArgs,BusinessArgs,Data) 159 | 160 | 161 | websocket.enableTrace(False) 162 | 163 | ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close) 164 | ws.on_open = on_open 165 | ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}) 166 | 167 | 168 | 169 | def text2audio(text,audio_file="output.wav"): 170 | """_summary_ 171 | 172 | Args: 173 | text (_type_): _description_ 174 | audio_file (str, optional): _description_. Defaults to "output.wav". 175 | 176 | Returns: 177 | _type_: 返回streamlit直接可以播放的wav byte文件 178 | """ 179 | # print(text) 180 | # print("**********************") 181 | gen_audio(text) 182 | 183 | # 读取PCM音频文件 184 | pcm_audio = AudioSegment.from_file(demo_pcm_file, format="raw", frame_rate=16000, channels=1, sample_width=2) 185 | 186 | # 将PCM音频转换为WAV格式 187 | wav_audio = pcm_audio.set_frame_rate(44100).set_channels(2) # 设置适当的采样率和声道数 188 | wav_audio.export(audio_file, format="wav") 189 | 190 | # 读取转换后的WAV文件 191 | wav_bytes = open(audio_file, "rb").read() 192 | 193 | return wav_bytes -------------------------------------------------------------------------------- /scripts/json2docx.py: -------------------------------------------------------------------------------- 1 | import json 2 | from docx import Document 3 | from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING 4 | from docx import Document 5 | from docx.oxml.ns import qn 6 | from docx.shared import Pt,RGBColor 7 | 8 | 9 | 10 | def json2docx(json_data, doc_file): 11 | 12 | document = Document() 13 | 14 | document.styles['Normal'].font.name = u'仿宋' 15 | document.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋') 16 | document.styles['Normal'].font.size = Pt(14) 17 | document.styles['Normal'].font.color.rgb = RGBColor(0,0,0) 18 | 19 | 20 | # 标题 21 | # 标题等级如1,2,3这些数字,一级标题二级标题这样 22 | Head = document.add_heading("",level=1)# 这里不填标题内容 23 | run = Head.add_run("民事起诉状") 24 | Head.alignment = WD_ALIGN_PARAGRAPH.CENTER 25 | run.font.name=u'宋体' 26 | run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体') 27 | run.font.size = Pt(22) 28 | run.font.color.rgb = RGBColor(0,0,0) 29 | paragraph = document.add_paragraph() 30 | 31 | 32 | # 添加原告信息 33 | for plaintiff in json_data['原告']: 34 | 35 | ### 公司 36 | if '公司名称' in plaintiff: 37 | 38 | doc = document.add_paragraph() 39 | doc.paragraph_format.first_line_indent = Pt(14) * 2 40 | doc.add_run('原告:').bold = True 41 | doc.add_run(f"公司名称:{plaintiff['公司名称'] or '__________'}," 42 | f"地址:{plaintiff['公司所在地'] or '________________'}。" 43 | f"统一社会信用代码:{plaintiff['统一社会信用代码'] or '________________'}") 44 | if '无' in plaintiff['法人']: 45 | doc.add_run('无法人') 46 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 47 | else: 48 | doc.add_run(f"法人:{plaintiff['法人']['姓名'] or '_______'},职务:{plaintiff['法人']['职务'] or '______'},联系方式:{plaintiff['法人']['联系方式'] or '___________'}。") 49 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 50 | if '无' in plaintiff['委托诉讼代理人']: 51 | doc = document.add_paragraph(f"无委托诉讼代理人。") 52 | doc.paragraph_format.first_line_indent = Pt(14) * 2 53 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 54 | else : 55 | doc = document.add_paragraph(f"委托诉讼代理人:{plaintiff['委托诉讼代理人']['姓名']},{plaintiff['委托诉讼代理人']['事务所']}。") 56 | doc.paragraph_format.first_line_indent = Pt(14) * 2 57 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 58 | ### 个人 59 | else: 60 | doc = document.add_paragraph() 61 | doc.paragraph_format.first_line_indent = Pt(14) * 2 62 | doc.add_run('原告:').bold = True 63 | doc.add_run(f"{plaintiff['姓名'] or '姓名:_______'},{plaintiff['性别'] or '性别:__'},{plaintiff['出生日期'] or '__________'}生," 64 | f"{plaintiff['民族'] or '____' + '族'},现住{plaintiff['住址']or '_________________'}。" 65 | f"联系方式:{plaintiff['联系方式'] or '_________'}" 66 | f"身份证号:{plaintiff['身份证号'] or '________________'}" 67 | f"法定代理人:{plaintiff['法定代理人'] or '__________'}") 68 | doc.paragraph_format.line_spacing = Pt(30) # 固定值18磅 69 | if '无' in plaintiff['委托诉讼代理人']: 70 | doc = document.add_paragraph(f"无委托诉讼代理人。") 71 | doc.paragraph_format.first_line_indent = Pt(14) * 2 72 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 73 | else : 74 | doc = document.add_paragraph(f"委托诉讼代理人:{plaintiff['委托诉讼代理人']['姓名']},{plaintiff['委托诉讼代理人']['事务所']}。") 75 | doc.paragraph_format.first_line_indent = Pt(14) * 2 76 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 77 | # document.add_paragraph() 78 | 79 | 80 | # 添加被告信息 81 | for defendant in json_data['被告']: 82 | 83 | ### 公司 84 | if '公司名称' in defendant: 85 | doc = document.add_paragraph() 86 | doc.paragraph_format.first_line_indent = Pt(14) * 2 87 | doc.add_run('被告:').bold = True 88 | doc.add_run(f"公司名称:{defendant['公司名称'] or '__________'}," 89 | f"地址:{defendant['公司所在地'] or '________________'}。" 90 | f"统一社会信用代码:{defendant['统一社会信用代码'] or '________________'}") 91 | if '无' in defendant['法人']: 92 | doc.add_run('无法人。') 93 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 94 | else: 95 | doc.add_run(f"法人:{defendant['法人']['姓名'] or '_______'},职务:{defendant['法人']['职务'] or '______'},联系方式:{defendant['法人']['联系方式'] or '___________'}。") 96 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 97 | if '无' in defendant['委托诉讼代理人']: 98 | doc = document.add_paragraph(f"无委托诉讼代理人。") 99 | doc.paragraph_format.first_line_indent = Pt(14) * 2 100 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 101 | else: 102 | doc = document.add_paragraph(f"委托诉讼代理人:{defendant['委托诉讼代理人']['姓名']},{defendant['委托诉讼代理人']['事务所']}。") 103 | doc.paragraph_format.first_line_indent = Pt(14) * 2 104 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 105 | ## 个人 106 | else: 107 | doc = document.add_paragraph() 108 | doc.paragraph_format.first_line_indent = Pt(14) * 2 109 | doc.add_run('被告:').bold = True 110 | doc.add_run(f"{defendant['姓名'] or '姓名:_______'},{defendant['性别'] or '性别:__'},{defendant['出生日期'] or '__________'}生," 111 | f"{defendant['民族'] or '____' + '族'},现住{defendant['住址']or '_________________'}。" 112 | f"联系方式:{defendant['联系方式'] or '_________'}" 113 | f"身份证号:{defendant['身份证号'] or '________________'}" 114 | f"法定代理人:{defendant['法定代理人'] or '__________'}") 115 | doc.paragraph_format.line_spacing = Pt(30) # 固定值18磅 116 | if '无' in defendant['委托诉讼代理人']: 117 | doc = document.add_paragraph(f"无委托诉讼代理人。") 118 | doc.paragraph_format.first_line_indent = Pt(14) * 2 119 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 120 | else: 121 | doc = document.add_paragraph(f"委托诉讼代理人:{defendant['委托诉讼代理人']['姓名']},{defendant['委托诉讼代理人']['事务所']}。") 122 | doc.paragraph_format.first_line_indent = Pt(14) * 2 123 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 124 | 125 | document.add_paragraph() 126 | 127 | 128 | # 添加诉讼请求 129 | paragraph = document.add_paragraph() 130 | paragraph.paragraph_format.first_line_indent = Pt(14) * 2 131 | paragraph.add_run('诉讼请求:').bold = True 132 | paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 133 | if json_data['诉讼请求'] == "null": 134 | doc = document.add_paragraph('无诉讼请求!\n') 135 | doc.paragraph_format.first_line_indent = Pt(14) * 2 136 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 137 | else: 138 | request_text = json_data['诉讼请求'] 139 | # 根据"\n"拆分为多行 140 | lines = request_text.split('\n') 141 | # 对每一行进行处理 142 | for line in lines: 143 | paragraph = document.add_paragraph(line) 144 | paragraph.paragraph_format.first_line_indent = Pt(14) * 2 145 | paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 146 | document.add_paragraph() 147 | 148 | # 添加事实和理由 149 | paragraph = document.add_paragraph() 150 | paragraph.paragraph_format.first_line_indent = Pt(14) * 2 151 | paragraph.add_run('事实和理由:').bold = True 152 | paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 153 | if json_data['事实理由'] == "null": 154 | doc = document.add_paragraph('无事实和理由!\n') 155 | doc.paragraph_format.first_line_indent = Pt(14) * 2 156 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 157 | else: 158 | request_text = json_data['事实理由'] 159 | # 根据"\n"拆分为多行 160 | lines = request_text.split('\n') 161 | # 对每一行进行处理 162 | for line in lines: 163 | paragraph = document.add_paragraph(line) 164 | paragraph.paragraph_format.first_line_indent = Pt(14) * 2 165 | paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 166 | document.add_paragraph() 167 | 168 | # 添加证据和证据来源,证人姓名和住所 169 | paragraph = document.add_paragraph() 170 | paragraph.paragraph_format.first_line_indent = Pt(14) * 2 171 | paragraph.add_run('证据和证据来源,证人姓名和住所:').bold = True 172 | paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 173 | if json_data['证据'] == "null": 174 | doc = document.add_paragraph('无证据和证据来源,证人姓名和住所!\n') 175 | doc.paragraph_format.first_line_indent = Pt(14) * 2 176 | doc.paragraph_format.line_spacing = Pt(30) # 固定值30磅 177 | else: 178 | request_text = json_data['证据'] 179 | # 根据"\n"拆分为多行 180 | lines = request_text.split('\n') 181 | # 对每一行进行处理 182 | for line in lines: 183 | paragraph = document.add_paragraph(line) 184 | paragraph.paragraph_format.first_line_indent = Pt(14) * 2 185 | paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 186 | 187 | # 结尾部分 188 | paragraph = document.add_paragraph() 189 | paragraph.add_run('此致').bold = True 190 | paragraph.paragraph_format.first_line_indent = Pt(14) * 2 191 | paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 192 | 193 | paragraph = document.add_paragraph() 194 | paragraph.add_run(json_data['法院']).bold = True 195 | paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 196 | paragraph = document.add_paragraph('\n附:本起诉状副本2份') 197 | paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 198 | 199 | # 起诉人(签名) 200 | paragraph = document.add_paragraph() 201 | paragraph.add_run('起诉人(签名)\n').bold = True 202 | paragraph.alignment = WD_ALIGN_PARAGRAPH.RIGHT 203 | paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 204 | 205 | # 日期 206 | if json_data['日期'] is None: 207 | date_paragraph = document.add_paragraph() 208 | date_paragraph.add_run('日期:____________').bold = True 209 | date_paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 210 | else: 211 | date_paragraph = document.add_paragraph() 212 | date_paragraph.add_run(json_data['日期']).bold = True 213 | date_paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 214 | date_paragraph.alignment = WD_ALIGN_PARAGRAPH.RIGHT 215 | 216 | 217 | from utils.tools import law_claim 218 | claim_paragraph = document.add_paragraph(law_claim) 219 | claim_paragraph.paragraph_format.first_line_indent = Pt(14) * 2 220 | claim_paragraph.paragraph_format.line_spacing = Pt(30) # 固定值30磅 221 | 222 | # 保存文档 223 | document.save(doc_file) 224 | 225 | 226 | if __name__ == '__main__': 227 | json_1 = 'person.json' 228 | 229 | with open(json_1, 'r',encoding='utf8') as f: 230 | json_data = json.loads(f.read()) 231 | 232 | json2docx(json_data, 'demo.docx') -------------------------------------------------------------------------------- /0_用户聊天界面.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import json 4 | 5 | from utils.iflytek.Spark import Spark 6 | import streamlit as st 7 | from streamlit_chat import message 8 | 9 | from bokeh.models.widgets import Button 10 | from bokeh.models import CustomJS 11 | 12 | from streamlit_bokeh_events import streamlit_bokeh_events 13 | 14 | from gtts import gTTS 15 | from io import BytesIO 16 | from utils.audio_gen.play_audio import text2audio 17 | 18 | from utils.prompt_config_l import * 19 | from utils.tools import transverse_on_json,extract_json_from_string,json2file,get_project_path,json2md 20 | from utils.prompt_config import summary_chat_prompt 21 | from utils.audio_gen.input_audio import js_code 22 | 23 | import pytz 24 | from datetime import datetime 25 | 26 | systime=pytz.timezone('Asia/shanghai') 27 | cur_time=datetime.utcnow() 28 | cur_beijing=cur_time.replace(tzinfo=pytz.utc).astimezone(systime) 29 | formattime=cur_beijing.strftime('%Y年%m月%d日') 30 | 31 | project_path = get_project_path() 32 | 33 | api = Spark() 34 | 35 | # ⛋ ✍ 36 | # st.title("✍ Legal Document Chatbot") 37 | 38 | 39 | if 'is_audio' not in st.session_state: 40 | st.session_state['is_audio'] = True 41 | 42 | if 'message_keys' not in st.session_state: 43 | st.session_state['message_keys'] = 0 44 | 45 | 46 | if 'current_chat' not in st.session_state: 47 | st.session_state['current_chat'] = [{"role": "assistant", "content": start_chat}] 48 | st.session_state['message_keys'] = 0 49 | 50 | if 'gen_keyget' not in st.session_state: 51 | st.session_state['gen_keyget'] =[] 52 | 53 | if 'gen_keymiss' not in st.session_state: 54 | st.session_state['gen_keymiss'] =[] 55 | 56 | if 'yuangao_data' not in st.session_state: 57 | st.session_state['yuangao_data'] ={'姓名': None, '性别': None, '出生日期': None, '民族': None, '住址': None, '联系方式': None, '身份证号': None, '法定代理人':None, '委托诉讼代理人': {'姓名': None, '事务所': None}} 58 | 59 | if 'beigao_data' not in st.session_state: 60 | st.session_state['beigao_data'] ={'姓名': None, '性别': None, '出生日期': None, '民族': None, '住址': None, '联系方式': None, '身份证号': None, '法定代理人':None, '委托诉讼代理人': {'姓名': None, '事务所': None}} 61 | 62 | if 'yuangao_company_data' not in st.session_state: 63 | st.session_state['yuangao_company_data'] ={ "公司名称": None, "公司所在地": None, '统一社会信用代码': None, "法人": { "姓名": None, "职务": None, "联系方式": None},"委托诉讼代理人": {"姓名": None,"事务所": None}} 64 | 65 | if 'beigao_company_data' not in st.session_state: 66 | st.session_state['beigao_company_data'] ={ "公司名称": None, "公司所在地": None, '统一社会信用代码': None, "法人": { "姓名": None, "职务": None, "联系方式": None},"委托诉讼代理人": {"姓名": None,"事务所": None}} 67 | 68 | if 'second_state' not in st.session_state: 69 | st.session_state['second_state'] = False 70 | 71 | if 'third_state' not in st.session_state: 72 | st.session_state['third_state'] = False 73 | 74 | if 'third_state_data' not in st.session_state: 75 | st.session_state['third_state_data'] = {"案由": None, "诉讼请求": None, "事实理由": None, "证据": None, "法院":None, "日期": formattime} 76 | 77 | if 'third_state_step' not in st.session_state: 78 | st.session_state['third_state_step'] = 1 79 | 80 | if 'fourth_state' not in st.session_state: 81 | st.session_state['fourth_state'] = False 82 | 83 | if 'yuangao_list' not in st.session_state: 84 | st.session_state['yuangao_list'] = [] 85 | 86 | if 'beigao_list' not in st.session_state: 87 | st.session_state['beigao_list'] = [] 88 | 89 | if "is_person"not in st.session_state: 90 | st.session_state['is_person'] = False 91 | 92 | if "is_company"not in st.session_state: 93 | st.session_state['is_company'] = False 94 | 95 | if 'agent_flag_1' not in st.session_state: 96 | st.session_state['agent_flag_1'] = False 97 | 98 | if 'agent_flag_2' not in st.session_state: 99 | st.session_state['agent_flag_2'] = False 100 | 101 | 102 | if 'prompt2usr' not in st.session_state: 103 | st.session_state['prompt2usr'] = "" 104 | 105 | if "cause_of_action" not in st.session_state: 106 | st.session_state['cause_of_action'] = ['机动车交通事故责任纠纷', '民间借贷纠纷', '离婚纠纷'] 107 | 108 | if "input_count" not in st.session_state: 109 | st.session_state['input_count'] = 0 110 | 111 | if "last_gen_keymiss" not in st.session_state: 112 | st.session_state['last_gen_keymiss'] = 0 113 | 114 | def clear_chat_history(): 115 | temp = st.session_state['current_chat'] 116 | 117 | if 'history_chat' not in st.session_state: 118 | st.session_state['history_chat'] = {} 119 | 120 | st.session_state['second_state'] = False 121 | st.session_state['third_state'] = False 122 | st.session_state['fourth_state'] = False 123 | st.session_state['third_state_step'] = 1 124 | st.session_state['yuangao_data'] ={'姓名': None, '性别': None, '出生日期': None, '民族': None, '住址': None, '联系方式': None, '身份证号': None, "法定代理人": None, '委托诉讼代理人': {'姓名': None, '事务所': None}} 125 | st.session_state['beigao_data'] ={'姓名': None, '性别': None, '出生日期': None, '民族': None, '住址': None, '联系方式': None, '身份证号': None, "法定代理人": None, '委托诉讼代理人': {'姓名': None, '事务所': None}} 126 | st.session_state['yuangao_company_data'] ={ "公司名称": None, "公司所在地": None, '统一社会信用代码': None, "法人": { "姓名": None, "职务": None, "联系方式": None},"委托诉讼代理人": {"姓名": None,"事务所": None}} 127 | st.session_state['beigao_company_data'] ={ "公司名称": None, "公司所在地": None, '统一社会信用代码': None, "法人": { "姓名": None, "职务": None, "联系方式": None},"委托诉讼代理人": {"姓名": None,"事务所": None}} 128 | st.session_state['third_state_data'] = {"案由": None, "诉讼请求": None, "事实理由": None, "证据": None, "法院":None, "日期": formattime} 129 | st.session_state['yuangao_list'] = [] 130 | st.session_state['beigao_list'] = [] 131 | st.session_state['is_person'] = False 132 | st.session_state['is_company'] = False 133 | st.session_state['agent_flag_1'] = False 134 | st.session_state['agent_flag_2'] = False 135 | st.session_state['prompt2usr'] = "" 136 | st.session_state['gen_keyget'] =[] 137 | 138 | temp = st.session_state['current_chat'] 139 | content = api._get_all_content(st.session_state['current_chat']) 140 | abstract = api.main([{'role':'user','content':summary_chat_prompt+content}]) 141 | 142 | index = len(st.session_state['history_chat']) 143 | 144 | title = str(index)+'.'+abstract 145 | st.session_state['history_chat'][title] = temp 146 | st.session_state['current_chat'] = [{"role": "assistant", "content": start_chat}] 147 | 148 | if 'category' in st.session_state: 149 | del st.session_state['category'] 150 | 151 | if 'message_keys' in st.session_state: 152 | st.session_state['message_keys'] = 0 153 | 154 | 155 | st.sidebar.subheader("全局设置") 156 | 157 | st.sidebar.button('开启新对话', on_click=clear_chat_history,use_container_width=True) 158 | # is_anonymous = st.sidebar.selectbox('匿名设置,是否允许我们收集您的信息',('yes','no')) 159 | # is_anonymous = st.sidebar.radio("匿名设置,是否允许我们收集您的信息", ('yes', 'no')) 160 | # st.session_state["is_anonymous"] = is_anonymous 161 | 162 | # is_audio = st.sidebar.selectbox('是否语音输出',('no','yes')) 163 | is_audio = st.sidebar.radio('是否语音输出',('Yes','No')) 164 | st.session_state["is_audio"] = (is_audio == 'Yes') 165 | 166 | 167 | 168 | # if 'category' not in st.session_state: 169 | options = ('我不太清楚诶','机动车交通事故责任纠纷', '民间借贷纠纷', '离婚纠纷','合同纠纷','买卖合同纠纷','金融借款合同纠纷','借款合同纠纷','房屋买卖合同纠纷') 170 | 171 | option = st.sidebar.selectbox( 172 | '🙋如果确定,请选择要生成诉讼文书的案由', 173 | options) 174 | st.session_state['category'] = option 175 | st.sidebar.write('🖊️ 当前任务:'+st.session_state['category']) 176 | 177 | def judge_p_c(res_judge): 178 | for x in res_judge: 179 | if x in st.session_state.prompt: 180 | return True 181 | return False 182 | 183 | 184 | def check_miss(data): 185 | keyget = [] 186 | if st.session_state['agent_flag_1']: 187 | if "委托诉讼代理人" in data and "姓名" in data["委托诉讼代理人"]: 188 | if data["委托诉讼代理人"]["姓名"] is None: 189 | data["委托诉讼代理人"] = "无" 190 | st.session_state['agent_flag_1'] = False 191 | 192 | if st.session_state['agent_flag_2']: 193 | if "法定代理人" in data: 194 | # print(data) 195 | if data["法定代理人"] is None: 196 | data["法定代理人"] = "无" 197 | st.session_state['agent_flag_2'] = False 198 | 199 | if isinstance(data,dict): 200 | keyget,keymiss=transverse_on_json(data) 201 | 202 | for x in keyget: 203 | if x == "住址" or x == "公司所在地": 204 | new_prompt_json={'role': 'user', 'content': data[x]+address_complete_json} 205 | res_json = api.main([new_prompt_json]) 206 | try: 207 | data[x]=extract_json_from_string(res_json)["住址"] 208 | except: 209 | data[x]=data[x] 210 | 211 | 212 | if st.session_state['is_person']==True: 213 | if st.session_state['second_state']: 214 | st.session_state['beigao_data'][x]=data[x] 215 | else: 216 | st.session_state['yuangao_data'][x]=data[x] 217 | if st.session_state['is_company']==True: 218 | if st.session_state['second_state']: 219 | st.session_state['beigao_company_data'][x]=data[x] 220 | else: 221 | st.session_state['yuangao_company_data'][x]=data[x] 222 | st.session_state['gen_keyget']+=keyget 223 | 224 | new_miss=[] 225 | 226 | for x in st.session_state['gen_keymiss']: 227 | if x not in st.session_state['gen_keyget']: 228 | new_miss.append(x) 229 | st.session_state['gen_keymiss']=new_miss 230 | 231 | def excute_fourth(): 232 | new_prompt_json={'role': 'user', 'content': st.session_state.prompt} 233 | res_answer=api.main([new_prompt_json]) 234 | return res_answer 235 | 236 | def excute_third(): 237 | # 输入诉讼请求 238 | 239 | if st.session_state['third_state_step'] == 1: 240 | if st.session_state['third_state_data']["案由"] == "民间借贷纠纷": 241 | prompt = debt_usr_request_prompt + debt_usr_request_example 242 | if st.session_state['third_state_data']["案由"] == "机动车交通事故责任纠纷": 243 | prompt = traffic_usr_request_prompt + traffic_usr_request_example 244 | if st.session_state['third_state_data']["案由"] == "离婚纠纷": 245 | prompt = divorce_usr_request_prompt 246 | else: 247 | prompt = "" 248 | 249 | 250 | new_prompt_json={'role': 'user', 'content': prompt+guide_second_step1+st.session_state.prompt} 251 | st.session_state['third_state_data']["诉讼请求"]=api.main([new_prompt_json]) 252 | st.session_state['third_state_step'] = 2 253 | 254 | res_answer="好的,我已经知道您的诉讼请求了,根据您的案由,我为您生成了一份事实与理由模板:\n\n" 255 | if st.session_state['category'] == "民间借贷纠纷": 256 | res_answer += debt_usr_reason_prompt + "\n\n**样本如下:**\n" + debt_usr_reason_example +"\n\n **请参考以上模板输入您的事实和理由。**" 257 | elif st.session_state['category'] == "机动车交通事故责任纠纷": 258 | res_answer += traffic_usr_reason_prompt + "\n\n**样本如下:**\n" + traffic_usr_reason_example + "\n\n **请参考以上模板输入您的事实和理由。**" 259 | elif st.session_state['category'] == "离婚纠纷": 260 | res_answer += divorce_usr_reason_prompt + "\n\n **请参考以上模板输入您的事实和理由。**" 261 | else: 262 | res_prompt={'role': 'user', 'content': "案件类型是"+st.session_state['third_state_data']['案由']+",请给出在起诉书中典型的该类别案件的事实与理由,并分点陈述"} 263 | res_ans=api.main([res_prompt]) 264 | res_answer += "**,提示如下:\n\n" + res_ans + "\n\n **请根据上述提示输入您的事实与理由。**" 265 | 266 | # 输入事实和理由 267 | elif st.session_state['third_state_step'] == 2: 268 | if st.session_state['third_state_data']["案由"] == "民间借贷纠纷": 269 | prompt = debt_usr_reason_prompt + debt_usr_reason_example 270 | if st.session_state['third_state_data']["案由"] == "机动车交通事故责任纠纷": 271 | prompt = traffic_usr_reason_prompt + traffic_usr_reason_example 272 | if st.session_state['third_state_data']["案由"] == "离婚纠纷": 273 | prompt = divorce_usr_reason_prompt 274 | else: 275 | prompt = "" 276 | new_prompt_json={'role': 'user', 'content': prompt+guide_second_step2+st.session_state.prompt} 277 | st.session_state['third_state_data']["事实理由"]=api.main([new_prompt_json]) 278 | st.session_state['third_state_step']=3 279 | res_answer="好的,我已经知道你的事实和理由了。请进一步告诉我您诉讼的**相关证据**。" 280 | 281 | elif st.session_state['third_state_step'] == 3: 282 | new_prompt_json={'role': 'user', 'content': gudie_second_step3+st.session_state.prompt} 283 | st.session_state['third_state_data']["证据"]=api.main([new_prompt_json]) 284 | st.session_state['third_state_step']=4 285 | res_answer="好的,我已经知道你的相关证据了。" 286 | 287 | # 根据被告信息推荐法院 288 | company_addresses = [] 289 | for info in st.session_state['beigao_list']: 290 | if "住址" in info: 291 | company_address = info["住址"] 292 | company_addresses.append(company_address) 293 | if "公司所在地" in info: 294 | company_address = info["公司所在地"] 295 | company_addresses.append(company_address) 296 | all_addresses = ", ".join(company_addresses) 297 | 298 | new_prompt_json={'role': 'user', 'content': gudie_second_step4+all_addresses} 299 | recommend=api.main([new_prompt_json]) 300 | 301 | res_answer = "如下是为您推荐的法院:" + recommend + "。请选择法院。" 302 | st.session_state['third_state_step'] = 5 303 | 304 | elif st.session_state['third_state_step'] == 5: 305 | # 填写法院名称 306 | new_prompt_json={'role': 'user', 'content': gudie_second_step5+st.session_state.prompt} 307 | st.session_state['third_state_data']["法院"]=api.main([new_prompt_json]) 308 | st.session_state['third_state_step']=5 309 | st.session_state['fourth_state']=True 310 | # st.session_state['yuangao_list'].append(st.session_state['yuangao_data']) 311 | # st.session_state['beigao_list'].append(st.session_state['beigao_data']) 312 | res_answer="好的,已为你生成了诉讼书。案由、诉讼请求、事实和理由的相关信息如下"+json2md(json.dumps(st.session_state['third_state_data'],ensure_ascii=False)) 313 | res_answer="好的,已为你生成了诉讼书,您可以前往预览界面进行预览,如果您想继续生成一份诉状书,可以点击左边开启新对话。或者你可以和我继续聊天,我很乐意和你讨论法律相关知识。" 314 | else: 315 | res_answer="好的,已为你生成了诉讼书。案由、诉讼请求、事实和理由的相关信息如下"+json2md(json.dumps(st.session_state['third_state_data'],ensure_ascii=False)) 316 | return res_answer 317 | 318 | def excute_second(): 319 | if st.session_state['is_person']==False and st.session_state['is_company']==False: 320 | #大模型判断是个人还是公司 321 | if "个人" in st.session_state.prompt and "公司" in st.session_state.prompt: 322 | res_1_2=3 323 | elif judge_p_c(res_judge_jj_3): 324 | res_1_2=3 325 | elif judge_p_c(res_judge_c_2): 326 | res_1_2=2 327 | elif judge_p_c(res_judge_p_1): 328 | res_1_2=1 329 | else: 330 | res_1_2=3 331 | # prompt_1_2={'role': 'user', 'content': gudie_1_2+prompt} 332 | # res_1_2 = api.main([prompt_1_2]) 333 | 334 | if res_1_2==1: 335 | st.session_state['is_person']=True 336 | res_answer="谢谢您提供的信息!\n\n请告诉我 **自然人(个人)** 的如下信息\n* 姓名\n* 身份证号\n* 性别\n* 出生日期\n* 民族\n* 住址\n* 联系方式\n * 委托代理人(如有)\n * 法定代理人(如有)" 337 | st.session_state['gen_keymiss'] =["姓名", "性别", "出生日期", "民族", "住址","联系方式","委托诉讼代理人","身份证号","法定代理人"] 338 | st.session_state['last_gen_keymiss']=st.session_state['gen_keymiss'] 339 | st.session_state['gen_keyget'] =[] 340 | elif res_1_2==2: 341 | st.session_state['is_company']=True 342 | res_answer="谢谢您提供的信息!\n\n请先告诉我 **非自然人(公司)** 的如下信息:\n* 公司名称\n* 统一社会信用代码\n * 公司所在地\n* 法人的姓名、职务、联系方式\n * 委托诉讼代理人(如有)" 343 | st.session_state['gen_keymiss'] =["公司名称", "公司所在地","法人","委托诉讼代理人","统一社会信用代码"] 344 | st.session_state['last_gen_keymiss']=st.session_state['gen_keymiss'] 345 | st.session_state['gen_keyget'] =[] 346 | else: 347 | st.session_state['is_person']=False 348 | st.session_state['is_company']=False 349 | res_answer="不好意思,我不太清楚您的意思,请问该被告是个人还是公司呢" 350 | 351 | elif st.session_state['is_person']==True and st.session_state['is_company']==False: 352 | 353 | new_prompt_json={'role': 'user', 'content': gudie_beigao_person_json+st.session_state["prompt2usr"]+st.session_state.prompt} 354 | res_json = api.main([new_prompt_json]) 355 | data=extract_json_from_string(res_json) 356 | check_miss(data) 357 | if st.session_state['last_gen_keymiss']==st.session_state['gen_keymiss']: 358 | st.session_state['input_count']+=1 359 | else: 360 | st.session_state['input_count']=0 361 | if st.session_state['input_count']==3: 362 | st.session_state['input_count']=0 363 | for x in st.session_state['gen_keymiss']: 364 | st.session_state['beigao_data'][x]="无" 365 | st.session_state['beigao_list'].append(st.session_state['beigao_data']) 366 | st.session_state['is_person']=True 367 | st.session_state['is_company']=True 368 | res_answer="亲,发现您多次没有提供有效的"+','.join(st.session_state['gen_keymiss'])+"信息,先帮你跳过吧!我已经知道第"+str(len(st.session_state['beigao_list']))+"个被告的信息了\n 请问你是否继续添加**被告**信息呢" 369 | return res_answer 370 | st.session_state['last_gen_keymiss']=st.session_state['gen_keymiss'] 371 | if len(st.session_state['gen_keymiss'])!=0: 372 | # res_answer="现在还不知道您的被告人的"+','.join(st.session_state['gen_keymiss'])+"信息,您能告诉我吗?" 373 | if "委托诉讼代理人" in st.session_state['gen_keymiss']: 374 | st.session_state['agent_flag_1'] = True 375 | res_answer="请问自然人是否有**委托代理人**?有的话请告诉我其**姓名**和**事务所。**" 376 | elif "法定代理人" in st.session_state['gen_keymiss']: 377 | st.session_state['agent_flag_2'] = True 378 | res_answer="请问自然人是否有**法定代理人**?" 379 | else: 380 | res_answer="现在还不知道该被告的"+','.join(st.session_state['gen_keymiss'])+"信息,您能告诉我吗?" 381 | 382 | else: 383 | st.session_state['beigao_list'].append(st.session_state['beigao_data']) 384 | duo_yuangao="好的,我已经知道第"+str(len(st.session_state['beigao_list']))+"个被告的信息了,信息如下。\n请问你是否需要继续添加被告信息?" 385 | res_answer= duo_yuangao+json2md(json.dumps(st.session_state['beigao_data'],ensure_ascii=False)) 386 | st.session_state['is_person']=True 387 | st.session_state['is_company']=True 388 | 389 | elif st.session_state['is_person']==False and st.session_state['is_company']==True: 390 | new_prompt_json={'role': 'user', 'content': gudie_beigao_company_json+st.session_state["prompt2usr"]+st.session_state.prompt} 391 | res_json = api.main([new_prompt_json]) 392 | data=extract_json_from_string(res_json) 393 | check_miss(data) 394 | if st.session_state['last_gen_keymiss']==st.session_state['gen_keymiss']: 395 | st.session_state['input_count']+=1 396 | else: 397 | st.session_state['input_count']=0 398 | if st.session_state['input_count']==3: 399 | st.session_state['input_count']=0 400 | for x in st.session_state['gen_keymiss']: 401 | st.session_state['beigao_company_data'][x]="无" 402 | st.session_state['beigao_list'].append(st.session_state['beigao_company_data']) 403 | st.session_state['is_person']=True 404 | st.session_state['is_company']=True 405 | res_answer="亲,发现您多次没有提供有效的"+','.join(st.session_state['gen_keymiss'])+"信息,先帮你跳过吧!我已经知道第"+str(len(st.session_state['beigao_list']))+"个被告的信息了\n 请问你是否继续添加**被告**信息呢" 406 | return res_answer 407 | st.session_state['last_gen_keymiss']=st.session_state['gen_keymiss'] 408 | if len(st.session_state['gen_keymiss'])!=0: 409 | if "委托诉讼代理人" in st.session_state['gen_keymiss']: 410 | st.session_state['agent_flag_1'] = True 411 | res_answer="请问被告公司是否有委托代理人?有的话请告诉我其姓名和事务所" 412 | else: 413 | res_answer="现在还不知道被告公司的"+','.join(st.session_state['gen_keymiss'])+"信息,您能告诉我吗?" 414 | else: 415 | st.session_state['beigao_list'].append(st.session_state['beigao_company_data']) 416 | duo_yuangao="好的,我已经知道第"+str(len(st.session_state['beigao_list']))+"个被告的信息了,请问你是否需要继续添加被告信息" 417 | res_answer= duo_yuangao+json2md(json.dumps(st.session_state['beigao_company_data'],ensure_ascii=False)) 418 | st.session_state['is_person']=True 419 | st.session_state['is_company']=True 420 | elif st.session_state['is_person']==True and st.session_state['is_company']==True: 421 | if judge_p_c(res_judge_jj_3) and st.session_state['third_state_data']["案由"]==None: 422 | return "不好意思,没有听懂您的意思,请问你是否继续添加**被告**信息呢" 423 | elif judge_p_c(res_judge_no_2) or st.session_state['third_state_data']["案由"]=="不清楚": 424 | res_json=2 425 | elif judge_p_c(res_judge_go_1): 426 | res_json=1 427 | else: 428 | return "不好意思,没有听懂您的意思,请问你是否继续添加**被告**信息呢" 429 | if res_json==1: 430 | res_answer="好的,我会继续添加**被告**信息,请问你还想添加**个人**还是**公司**呢?" 431 | st.session_state['is_person']=False 432 | st.session_state['is_company']=False 433 | else: 434 | # 判断案由 435 | if st.session_state['category']=="我不太清楚诶" and st.session_state['third_state_data']["案由"]==None: 436 | res_answer="好的,我已经收集好了你的被告信息了。这边检测到您还没有选择**案由**,您若不清楚案件类型,请简单描述一下案件情况,我会帮你**智能识别**案由" 437 | st.session_state['third_state_data']["案由"]="不清楚" 438 | elif st.session_state['category']=="我不太清楚诶" and st.session_state['third_state_data']["案由"]=="不清楚": 439 | new_prompt_json={'role': 'user', 'content': gudie_second_step0+st.session_state.prompt} 440 | anyou_str=api.main([new_prompt_json]) 441 | # print("**********") 442 | # print(anyou_str) 443 | try: 444 | anyou=extract_json_from_string(anyou_str)["案由"] 445 | except: 446 | res_answer="不好意思,我没识别成功,麻烦您再输入一次,再给我个机会!" 447 | return res_answer 448 | # print(anyou) 449 | st.session_state['third_state_data']["案由"]=anyou 450 | res_answer="好的,已帮您识别案由为**"+anyou 451 | st.session_state['category']=anyou 452 | if st.session_state['third_state_data']["案由"] in st.session_state['cause_of_action']: 453 | if st.session_state['third_state_data']["案由"] == "民间借贷纠纷": 454 | res_answer += "**,根据您的案由,我为您生成了一份诉讼请求模板:\n\n" + debt_usr_request_prompt + "\n\n **请根据上述提示输入您的诉讼请求。**" 455 | if st.session_state['third_state_data']["案由"] == "机动车交通事故责任纠纷": 456 | res_answer += "**,根据您的案由,我为您生成了一份诉讼请求模板:\n\n" + traffic_usr_request_prompt + "\n\n **请根据上述提示输入您的诉讼请求。**" 457 | if st.session_state['third_state_data']["案由"] == "离婚纠纷": 458 | res_answer += "**,根据您的案由,我为您生成了一份诉讼请求模板:\n\n" + divorce_usr_request_prompt + "\n\n **请根据上述提示输入您的诉讼请求。**" 459 | else: 460 | anyou_prompt={'role': 'user', 'content': "案件类型是"+anyou+",请给出在起诉书中典型的该类别案件的诉讼请求,并分点陈述"} 461 | anyou_res=api.main([anyou_prompt]) 462 | res_answer += "**,根据您的案由,我为您生成了一份诉讼请求模板:\n\n" + anyou_res + "\n\n **请参考上述提示输入您的诉讼请求。**" 463 | # res_answer="好的,已帮您识别案由为"+anyou+",请继续输入您的诉讼请求。" 464 | # st.session_state['third_state_step'] = 1 465 | # res_answer="好的,已帮您识别案由为"+anyou+",能进一步给出您的**事实和理由**吗?" 466 | st.session_state['third_state']=True 467 | st.session_state['second_state']=False 468 | st.session_state['gen_keymiss']=["案由", "诉讼请求", "事实理由", "证据", "法院", "日期"] 469 | st.session_state['gen_keyget'] =[] 470 | elif st.session_state['category']!="我不太清楚诶":#and st.session_state['third_state_data']["案由"]!="不清楚" 471 | st.session_state['third_state_data']["案由"]=st.session_state['category'] 472 | st.session_state['third_state']=True 473 | st.session_state['second_state']=False 474 | st.session_state['gen_keymiss']=["案由", "诉讼请求", "事实理由", "证据", "法院", "日期"] 475 | st.session_state['gen_keyget'] =[] 476 | # res_answer="能进一步给出您的**事实和理由**吗?" 477 | st.sidebar.write('🖊️ 当前任务:'+st.session_state['category']) 478 | res_answer = "目前您的案由是**" + st.session_state['category'] 479 | # 获取案由的提示信息 480 | if st.session_state['third_state_data']["案由"] in st.session_state['cause_of_action']: 481 | if st.session_state['category'] == "民间借贷纠纷": 482 | res_answer += "**,提示如下:\n\n" + debt_usr_request_prompt + "\n\n**样本如下:**\n" + debt_usr_reason_example + "\n\n **请根据上述提示输入您的诉讼请求。**" 483 | if st.session_state['category'] == "机动车交通事故责任纠纷": 484 | res_answer += "**,提示如下:\n\n" + traffic_usr_request_prompt + "\n\n**样本如下:**\n" + traffic_usr_request_example + "\n\n **请根据上述提示输入您的诉讼请求。**" 485 | if st.session_state['category'] == "离婚纠纷": 486 | res_answer += "**,提示如下:\n\n" + divorce_usr_request_prompt + "\n\n **请根据上述提示输入您的诉讼请求。**" 487 | else: 488 | anyou_prompt={'role': 'user', 'content': "案件类型是"+anyou+",请给出在起诉书中典型的该类别案件的诉讼请求,并分点陈述"} 489 | anyou_res=api.main([anyou_prompt]) 490 | res_answer += "**,根据您的案由,我为您生成了一份诉讼请求模板:\n\n" + anyou_res + "\n\n **请参考上述提示输入您的诉讼请求。**" 491 | 492 | 493 | return res_answer 494 | 495 | def excute_first(): 496 | if st.session_state['is_person']==False and st.session_state['is_company']==False: 497 | #大模型判断是个人还是公司 498 | if "个人" in st.session_state.prompt and "公司" in st.session_state.prompt: 499 | res_1_2=3 500 | elif judge_p_c(res_judge_jj_3): 501 | res_1_2=3 502 | elif judge_p_c(res_judge_c_2): 503 | res_1_2=2 504 | elif judge_p_c(res_judge_p_1): 505 | res_1_2=1 506 | else: 507 | res_1_2=3 508 | if res_1_2==1: 509 | st.session_state['is_person']=True 510 | res_answer="谢谢您提供的信息!\n\n请告诉我 **自然人(个人)** 的如下信息\n* 姓名\n* 身份证号\n* 性别\n* 出生日期\n* 民族\n* 住址\n* 联系方式\n * 委托代理人(如有)\n * 法定代理人(如有)" 511 | st.session_state['gen_keymiss'] =["姓名", "性别", "出生日期", "民族", "住址","联系方式","委托诉讼代理人","身份证号", "法定代理人" ] 512 | st.session_state['last_gen_keymiss']=st.session_state['gen_keymiss'] 513 | st.session_state['gen_keyget'] =[] 514 | elif res_1_2==2: 515 | st.session_state['is_company']=True 516 | res_answer="谢谢您提供的信息!\n\n请先告诉我 **非自然人(公司)** 的如下信息:\n* 公司名称\n* 统一社会信用代码\n* 公司所在地\n* 法人的姓名、职务、联系方式\n * 委托代理人(如有)" 517 | st.session_state['gen_keymiss'] =["公司名称", "公司所在地","法人","委托诉讼代理人", "统一社会信用代码"] 518 | st.session_state['last_gen_keymiss']=st.session_state['gen_keymiss'] 519 | st.session_state['gen_keyget'] =[] 520 | else: 521 | st.session_state['is_person']=False 522 | st.session_state['is_company']=False 523 | res_answer="不好意思,我不太清楚您的意思,请再告诉一次我**原告**的信息。\n\n请问原告是 *自然人(个人)* 还是 *非自然人(公司)* 呢?" 524 | elif st.session_state['is_person']==True and st.session_state['is_company']==False: 525 | new_prompt_json={'role': 'user', 'content': gudie_yuangao_person_json+st.session_state['prompt2usr']+st.session_state.prompt} 526 | res_json = api.main([new_prompt_json]) 527 | data=extract_json_from_string(res_json) 528 | check_miss(data) 529 | if st.session_state['last_gen_keymiss']==st.session_state['gen_keymiss']: 530 | st.session_state['input_count']+=1 531 | else: 532 | st.session_state['input_count']=0 533 | if st.session_state['input_count']==3: 534 | st.session_state['input_count']=0 535 | for x in st.session_state['gen_keymiss']: 536 | st.session_state['yuangao_data'][x]="无" 537 | st.session_state['yuangao_list'].append(st.session_state['yuangao_data']) 538 | st.session_state['is_person']=True 539 | st.session_state['is_company']=True 540 | res_answer="亲,发现您多次没有提供有效的"+','.join(st.session_state['gen_keymiss'])+"信息,先帮你跳过吧!我已经知道第"+str(len(st.session_state['yuangao_list']))+"个被告的信息了\n 请问你是否继续添加**原告**信息呢" 541 | return res_answer 542 | st.session_state['last_gen_keymiss']=st.session_state['gen_keymiss'] 543 | if len(st.session_state['gen_keymiss'])!=0: 544 | if "委托诉讼代理人" in st.session_state['gen_keymiss']: 545 | st.session_state['agent_flag_1'] = True 546 | res_answer="请问该人是否有**委托代理人**?有的话请告诉我其姓名和事务所" 547 | elif "法定代理人" in st.session_state['gen_keymiss']: 548 | st.session_state['agent_flag_2'] = True 549 | res_answer="请问该人是否有**法定代理人**?" 550 | else: 551 | res_answer="现在还不知道该人的"+','.join(st.session_state['gen_keymiss'])+"信息,您能告诉我吗?" 552 | 553 | else: 554 | st.session_state['yuangao_list'].append(st.session_state['yuangao_data']) 555 | duo_yuangao="好的,我已经知道**第"+str(len(st.session_state['yuangao_list']))+"个原告**的信息了,请问你是否需要继续添加**原告**信息?" 556 | res_answer= duo_yuangao + json2md(json.dumps(st.session_state['yuangao_data'],ensure_ascii=False)) 557 | st.session_state['is_person']=True 558 | st.session_state['is_company']=True 559 | 560 | elif st.session_state['is_person']==False and st.session_state['is_company']==True: 561 | new_prompt_json={'role': 'user', 'content': gudie_yuangao_company_json+st.session_state["prompt2usr"]+st.session_state.prompt} 562 | res_json = api.main([new_prompt_json]) 563 | # print("-----------") 564 | # print(res_json) 565 | # print("-----------") 566 | data=extract_json_from_string(res_json) 567 | check_miss(data) 568 | if st.session_state['last_gen_keymiss']==st.session_state['gen_keymiss']: 569 | st.session_state['input_count']+=1 570 | else: 571 | st.session_state['input_count']=0 572 | if st.session_state['input_count']==3: 573 | st.session_state['input_count']=0 574 | for x in st.session_state['gen_keymiss']: 575 | st.session_state['yuangao_company_data'][x]="无" 576 | st.session_state['yuangao_list'].append(st.session_state['yuangao_company_data']) 577 | st.session_state['is_person']=True 578 | st.session_state['is_company']=True 579 | res_answer="亲,发现您多次没有提供有效的"+','.join(st.session_state['gen_keymiss'])+"信息,先帮你跳过吧!我已经知道第"+str(len(st.session_state['yuangao_list']))+"个被告的信息了\n 请问你是否继续添加**原告**信息呢" 580 | return res_answer 581 | st.session_state['last_gen_keymiss']=st.session_state['gen_keymiss'] 582 | if len(st.session_state['gen_keymiss'])!=0: 583 | if "委托诉讼代理人" in st.session_state['gen_keymiss']: 584 | st.session_state['agent_flag_1'] = True 585 | res_answer="请问该公司是否有**委托代理人**?有的话请告诉我其姓名和事务所" 586 | else: 587 | res_answer="现在还不知道该公司的"+','.join(st.session_state['gen_keymiss'])+"信息,您能告诉我吗?" 588 | else: 589 | st.session_state['yuangao_list'].append(st.session_state['yuangao_company_data']) 590 | duo_yuangao="好的,我已经知道第"+str(len(st.session_state['yuangao_list']))+"个原告的信息了,请问你是否需要继续添加原告信息" 591 | res_answer= duo_yuangao+json2md(json.dumps(st.session_state['yuangao_company_data'],ensure_ascii=False)) 592 | st.session_state['is_person']=True 593 | st.session_state['is_company']=True 594 | elif st.session_state['is_person']==True and st.session_state['is_company']==True: 595 | if judge_p_c(res_judge_jj_3): 596 | return "不好意思,没有听懂您的意思,请问你是否继续添加**原告**信息呢" 597 | elif judge_p_c(res_judge_no_2): 598 | res_json=2 599 | elif judge_p_c(res_judge_go_1): 600 | res_json=1 601 | else: 602 | return "不好意思,没有听懂您的意思,请问你是否继续添加**原告**信息呢" 603 | # print("res_json",res_json) 604 | if res_json==1: 605 | res_answer="好的,我会继续为你添加**原告**信息,请问你还想添加**个人**还是**公司**呢?" 606 | else: 607 | st.session_state['second_state']=True 608 | res_answer="好的,我已经收集好了你的原告信息,麻烦您提供**被告人信息**,请问您的被告人是**个人**还是**公司**呢?" 609 | st.session_state['is_person']=False 610 | st.session_state['is_company']=False 611 | return res_answer 612 | 613 | def on_input_change(): 614 | 615 | if len(st.session_state.user_input)==0: 616 | # 这种对应的情况是无端的空白输入变化,将空白信息输出了 617 | #下面这个没问题!!! 618 | return 619 | 620 | st.session_state['prompt'] = st.session_state['user_input'] 621 | st.session_state['user_input'] = '' 622 | 623 | st.session_state['current_chat'].append({"role": "user", "content": st.session_state.prompt}) 624 | 625 | if st.session_state['fourth_state']: 626 | res_answer=excute_fourth() 627 | elif st.session_state['third_state']:#第3步:"案由", "诉讼请求", "事实理由", "证据", "日期" 628 | res_answer=excute_third() 629 | elif st.session_state['second_state']:#第2步:被告人信息 630 | res_answer=excute_second() 631 | else: #第1步:原告人信息 632 | res_answer=excute_first() 633 | 634 | json2file(st.session_state['yuangao_list'],st.session_state['beigao_list'],st.session_state['third_state_data']) 635 | 636 | st.session_state['prompt2usr'] = res_answer 637 | msg = {'role':"assistant","content":res_answer} 638 | st.session_state['current_chat'].append(msg) 639 | 640 | 641 | # ----------------------------- audio input ------------------------------------- 642 | st.session_state['user_input'] = '' 643 | st.session_state['is_audio_input'] = False 644 | 645 | if 'last_audio' not in st.session_state: 646 | st.session_state['last_audio'] = '' 647 | 648 | placeholder = st.container() 649 | with placeholder: 650 | start_button = Button(label='SPEAK', button_type='success', margin = (1, 1, 1, 1), width=200) 651 | 652 | start_button.js_on_event("button_click", CustomJS(code=js_code)) 653 | 654 | audio_result = streamlit_bokeh_events( 655 | bokeh_plot = start_button, 656 | events="GET_TEXT,GET_ONREC,GET_INTRM", 657 | key="listen", 658 | refresh_on_update=False, 659 | override_height=30, 660 | debounce_time=500) 661 | 662 | 663 | if audio_result: 664 | if "GET_ONREC" in audio_result and "GET_INTRM" in audio_result: 665 | if audio_result["GET_ONREC"] == 'stop' and audio_result["GET_INTRM"] =='': 666 | # print(st.session_state['last_audio']) 667 | # print(audio_result['GET_TEXT']['t']) 668 | if st.session_state['last_audio'] == audio_result['GET_TEXT']['t']: 669 | audio_result = None 670 | 671 | # st.write(audio_result) 672 | if audio_result: 673 | if 'GET_INTRM' in audio_result: 674 | st.write(audio_result['GET_INTRM']) 675 | 676 | if "GET_ONREC" in audio_result: 677 | if audio_result.get("GET_ONREC") == 'start': 678 | st.session_state['is_audio_input'] = True 679 | 680 | elif audio_result.get("GET_ONREC") == 'running': 681 | # placeholder.image(os.path.join(project_path,'assert','sine_wave.gif')) 682 | st.session_state['is_audio_input'] = True 683 | 684 | elif audio_result.get("GET_ONREC") == 'stop': 685 | # placeholder.image(os.path.join(project_path,'assert','end.jpg')) 686 | if 'GET_TEXT' in audio_result: 687 | st.session_state['user_input'] = audio_result['GET_TEXT']['t'] 688 | st.session_state['last_audio'] = audio_result['GET_TEXT']['t'] 689 | st.session_state['is_audio_input'] = False 690 | audio_result = None 691 | # print('here02 : ',audio_result) 692 | else: 693 | st.session_state['user_input'] = '' 694 | # ------------------------------------------------------------------------------- 695 | 696 | 697 | st.text_area(label='输入区域,发送信息: ctl + enter, 语音输入自动识别停止',on_change=on_input_change,key='user_input') 698 | 699 | if not st.session_state.is_audio_input: 700 | for i in range(len(st.session_state['current_chat'])-1,-1,-1): 701 | msg = st.session_state['current_chat'][i] 702 | message(msg['content'],is_user=(msg["role"]=='user'),key=st.session_state['message_keys']) 703 | if st.session_state["is_audio"] and msg["role"]!='user': 704 | # if msg["role"]!='user': 705 | wav_bytes = text2audio(msg['content'],os.path.join(project_path,'output','output.wav') ) 706 | st.audio(wav_bytes, format="audio/wav", start_time=0) 707 | st.session_state['message_keys'] += 1 708 | 709 | 710 | --------------------------------------------------------------------------------