| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- 我设计了一个系统,内部有如下实体:
- 1. **文章**:以文本为主体,可能包含少量表格、代码、文头文尾等内容,包含大量需提取的关键信息。一个典型的示例:
- ```
- 2026年6月1日晚8点,好友们决定为王若飞(男)组织一场生日派对。这次小范围聚会共有5人参加,刘阳(女)作为总策划,除寿星和总策划外,还有李四(女)、王五(男)和赵六(男)参加。活动总预算为3000元,且已完成备案,现场安排了掷骰子、扔飞镖和打桌球等破冰游戏,确保大家玩得尽兴。
- ```
- 2. **关键信息定义**:使用Json定义的树状结构,每个节点以`node_label`为key,包含`metadata`字段和`subnodes`字段,`metadata`字段中包含`node_label`(取关键信息名称的拼音首字母、`node_name`(关键信息名称)、`node_type`(取值为`concept`时表示分类节点,`property`时表示属性节点)、`value_type`(仅当`node_type`为`property`时生效,取值为`integer`、`float`、`string`、`boolean`、`date_time`、`class`,其中`class`表示关键信息为复合结构,包含子属性)、`is_list`(仅当`node_type`为`property`时生效,标识关键信息是否为列表类型,即是否可以有多个实例)字段。一个典型的示例:
- ```json
- {
- "metadata": {
- "node_label": "PDJH",
- "node_name": "派对计划",
- "node_type": "concept"
- },
- "subnodes": {
- "JBXX": {
- "metadata": {
- "node_label": "JBXX",
- "node_name": "基本信息",
- "node_type": "concept"
- },
- "subnodes": {
- "PDMC": {
- "metadata": {
- "node_label": "PDMC",
- "node_name": "派对名称",
- "node_type": "property",
- "value_type": "string",
- "is_list": false
- }
- },
- "PDKSSJ": {
- "metadata": {
- "node_label": "PDKSSJ",
- "node_name": "派对开始时间",
- "node_type": "property",
- "value_type": "date_time",
- "is_list": false
- }
- },
- "PDZRS": {
- "metadata": {
- "node_label": "PDZRS",
- "node_name": "派对总人数",
- "node_type": "property",
- "value_type": "integer",
- "is_list": false
- }
- },
- "SFBA": {
- "metadata": {
- "node_label": "SFBA",
- "node_name": "是否备案",
- "node_type": "property",
- "value_type": "boolean",
- "is_list": false
- }
- }
- }
- },
- "RYXX": {
- "metadata": {
- "node_label": "RYXX",
- "node_name": "人员信息",
- "node_type": "concept"
- },
- "subnodes": {
- "ZCH": {
- "metadata": {
- "node_label": "ZCH",
- "node_name": "总策划",
- "node_type": "property",
- "value_type": "class",
- "is_list": false
- },
- "subnodes": {
- "XM": {
- "metadata": {
- "node_label": "XM",
- "node_name": "姓名",
- "node_type": "property",
- "value_type": "string",
- "is_list": false
- }
- },
- "SFZH": {
- "metadata": {
- "node_label": "SFZH",
- "node_name": "身份证号",
- "node_type": "property",
- "value_type": "string",
- "is_list": false
- }
- }
- }
- },
- "RYQD": {
- "metadata": {
- "node_label": "RYQD",
- "node_name": "人员清单",
- "node_type": "property",
- "value_type": "class",
- "is_list": true
- },
- "subnodes": {
- "XM": {
- "metadata": {
- "node_label": "XM",
- "node_name": "姓名",
- "node_type": "property",
- "value_type": "string",
- "is_list": false
- }
- },
- "SFZH": {
- "metadata": {
- "node_label": "SFZH",
- "node_name": "身份证号",
- "node_type": "property",
- "value_type": "string",
- "is_list": false
- }
- }
- }
- }
- }
- },
- "HDXX": {
- "metadata": {
- "node_label": "HDXX",
- "node_name": "活动信息",
- "node_type": "concept"
- },
- "subnodes": {
- "PBYXLB": {
- "metadata": {
- "node_label": "PBYXLB",
- "node_name": "破冰游戏清单",
- "node_type": "property",
- "value_type": "string",
- "is_list": true
- }
- }
- }
- }
- }
- }
- ```
- 3. **关键信息实例**:根据**关键信息定义**,对其中的节点进行赋值而得到的实例,以Json形式表示。其中,有如下注意事项:
- 1. 节点以`node_label`为key;
-
- 2. 在**关键信息定义**中,`node_type`为`concept`的,value为Json对象,包含其子节点或子属性的值;
- 3. 在**关键信息定义**中,`value_type`为`integer`、`float`、`string`、`boolean`、`date_time`时,如果`is_list`为`false`,value为对应类型;如果`is_list`为`true`,value为对应类型列表。特别地,`date_time`类型的值设置为字符串,但格式固定为`XXXX-XX-XXTXX:XX:XX.XXX`;
- 4. 在**关键信息定义**中,`value_type`为`class`的,如果`is_list`为`false`,value为Json对象,包含其子属性的值;如果`is_list`为`true`,value为Json对象列表,每个元素包含其子属性的值。
- 针对**文章**示例,根据上述**关键信息定义**,生成对应的**关键信息实例**为:
- ```json
- {
- "PDJH": {
- "JBXX": {
- "PDMC": "王若飞生日派对",
- "PDKSSJ": "2026-06-01T20:00:00.000",
- "PDZRS": 5,
- "PDZYS": 3000.0,
- "SFBA": true
- },
- "RYXX": {
- "ZCH": {
- "XM": "刘阳",
- "XB": "女"
- },
- "RYQD": [
- {
- "XM": "刘阳",
- "XB": "女"
- },
- {
- "XM": "王若飞",
- "XB": "男"
- },
- {
- "XM": "李四",
- "XB": "女"
- },
- {
- "XM": "王五",
- "XB": "男"
- },
- {
- "XM": "赵六",
- "XB": "男"
- }
- ]
- },
- "HDXX": {
- "PBYXQD": [
- "掷骰子",
- "扔飞镖",
- "打桌球"
- ]
- }
- }
- }
- ```
- 现在,我需要依托大模型,根据输入的**文章**和**关键信息定义**,从文章中将所有关键信息提取出来;请帮我设计一个prompt,使得大模型能够准确、高效、稳定地完成这个task。如果有必要,请使用langchain等框架,分步骤进行,以达到最好的效果。
- --------
- OK,现在,我需要将原始文本中相关的关键信息区域也标识出来。例如,针对“2026年6月1日晚8点,好友们决定为王若飞(男)组织一场生日派对,活动已完成备案。”这个文本,我希望生成类似于“{[PDJH.JBXX.PDKSSJ],2026-06-01T20:00:00.000,2026年6月1日晚8点,2026年1月1日~2026年12月31日,YYYY年M月D日(上午/下午/晚)H点[m分[s秒]]},好友们决定为{[PDJH.RYXX.RYQD[0].XM],王若飞,王若飞,2~4个汉字,不作转换}({[PDJH.RYXX.RYQD[0].XB],男,男,男/女,不作转换})组织一场生日派对,活动{[PDJH.JBXX.SFBA],true,已完成备案,已完成备案/未完成备案,true->已完成备案/false->未完成备案}”。每块关键信息区域包括{节点路径,提取值,原始文本,提取值的约束(以自然语言表示,供大模型理解),提取值到原始文本的转换规则(以自然语言表示,供大模型理解)}。请先帮我思考这个标识相关的符号体系是否合理,是否会与原文符号产生歧义,如果会,则不一定使用这套符号体系,改进该体系。
- --------
- 1. 值约束来源是关键信息定义Json,部分关键信息会带一个constraints属性,里面会带{"raw_constraints":{"min_value":[0],"max_value":[100]}}、{"raw_constraints":{"enum_string":[["男", "女"]]}}这样的约束,确保将其精准地转换为自然语言,也可以在值约束里将原始的Json约束附带上。如果关键信息没有自带该属性,那么对于显而易见的关键信息约束,如“身份证号(18位数字,最后一位可以是X)”、“性别(男/女)”、“年龄(0-110)”等,你要进行推断,给出约束;对于你无法确定的约束,不要随意给出。 转换规则由你自行给出。
- 2. 标注以一个独立字段输出。
- --------
- 有几个提取的原则需要微调一下:
- 1. 如果原文中某处同时对应关键信息定义中的多个关键信息,如“刘阳”即对应“总策划”,又对应“人员清单”中的一员,那么标注时,将多处同时标注,并在中间使用“||”分隔开,如:`{{PDJH.RYXX.ZCH.XM||刘阳||刘阳|| ||不作转换}}||{{PDJH.RYXX.RYQD[1].XM||刘阳||刘阳|| ||不作转换}}`;
- 2. 如果原文中不存在关键信息实例中的某处关键信息原文,例如原文为“为王若飞(男)组织一场生日派对”,而关键信息实例中为“王若飞生日派对”,那么在原文中找到最相关的部分,如“生日派对”进行标注,并将转换规则写为“根据原文进行微调”,结果为`{{PDJH.JBXX.PDMC||王若飞生日派对||生日派对|| ||根据原文进行微调}}`;
- 3. 对于时间、布尔等类型的值,你原来的做法是在代码里写死,我需要你根据原文内容,利用大模型(为确保快速处理,可不使用reasoning推理)给出明确的转换规则,例如`ISO 8601 → YYYY年M月D日(上午/下午/晚)H点[m分[s秒]],根据是否为整点,可视情省略[]中的内容`;
- 4. 你现在预置了一些关键信息的约束,我同样要求你不要写死,根据不同关键信息定义中的内容,利用大模型(为确保快速处理,可不使用reasoning推理)给出相应的约束。
- --------
- 针对某个提取值在原文中拥有多个对应文本的情况(如“王五”这个人在文中出现了多次),我新增了一条提取规则:“10. **同一提取值可多次标注**:如果某个提取值在原文中拥有多个对应文本,对这些文本分别进行标注,各标注的“节点路径”、“提取值”、“值约束”需保持一致,“原始文本”、“转换规则”可以不同,视原文决定”。但是经过测试,该规则未生效,多个对应文本只有一个被标注。请帮我检查并使之生效。
- --------
- 请为我增加调试日志,在每一次与LLM交互前,打印本次交互是整个处理流程中的哪个分步骤,同时打印给LLM发送的prompt,以便我了解发送的内容。同时,在最外层函数调用处增加debug变量,只有当它为True时才打印上述日志。
- --------
- 目前,在转换规则生成过程中,由于直接把整篇文章给了LLM,导致LLM识别提取值对应的原文不清晰(例如提取值“3000.0”对应文中的“3000”,但LLM认为是“3000元”)。所以,我想将“Step 2: LLM辅助生成约束和转换规则”拆分成两步,第一步将提取值对应的原文提取出来,第二步仅根据对应的原文进行约束和转换规则的生成。为了速度快,两步均采用大模型的轻量级调用,不调用reasoning推理。
- --------
- 现在,我希望做一个界面,左侧为菜单栏,目前包含两个菜单:文档解析和信息管理。
- 1. 文档解析:分为两栏,左栏为文档展示区域,如未选择文档,显示“请选择文档”;上传文档后,左侧可浏览文档(支持pdf和word),右侧区域分为上下两栏,比例约为3:1,上方显示从文档中提取的正文内容(不含页眉页脚等,可转为markdown格式),右上方有一个按钮,“开始解析”,点击后,下栏开始输出正文内容关键信息提取的思考过程(即原python文件输出的内容);思考完成后,上方内容区域变为提取后的文本(带{{||}})。
- 2. 信息管理:针对关键信息树状结构的管理维护模块,以折叠树形式展示,每个节点均可编辑其元数据和子节点(参考之前的设计:**关键信息定义**:使用Json定义的树状结构,每个节点以`node_label`为key,包含`metadata`字段和`subnodes`字段,`metadata`字段中包含`node_label`(取关键信息名称的拼音首字母、`node_name`(关键信息名称)、`node_type`(取值为`concept`时表示分类节点,`property`时表示属性节点)、`value_type`(仅当`node_type`为`property`时生效,取值为`integer`、`float`、`string`、`boolean`、`date_time`、`class`,其中`class`表示关键信息为复合结构,包含子属性)、`is_list`(仅当`node_type`为`property`时生效,标识关键信息是否为列表类型,即是否可以有多个实例)字段。)
- 前端请使用vue实现,后端引入flask框架。请实现。
- ---
- 后端配置里有API Key,前端不用输入,请求发给后端,后端使用配置的API key即可。
- ---
- 将后端端口改为8754,前端端口改为8774,然后重启服务。
- ---
- 我要求左侧是文档预览,word打开什么样子就是什么样子,pdf打开什么样子就是什么样子;右侧md文字行距过大,减小一些
- ---
- 1. 上传pdf,报错:上传失败:文档解析失败: PyMuPDF 未安装,无法解析 PDF
- 2. 上传word,不报错,右侧也能解析出来,但左侧为空白页面,无word文档显示。
- ---
- 点击上传,报错:上传失败:Promise.withResolvers is not a function
- ---
- 页面缩放大小为125%时,显示没有问题;100%时,右侧有一大块区域是空白的,鼠标也无法交互。请修复。
- ---
- 信息管理中,我希望不止可以管理这一条关键信息,而是整理一个列表,每一条关键信息有名称、描述等元数据,点开后是这个树状结构,可以进行管理。支持json格式的导入,导入时填入名称和描述,导入格式参考@data/samples/info_definition.json。
- ---
- 我希望在@extractor.py中写一个函数,输入一段文本,从中提取**关键信息定义**Json,格式参考@data/samples/info_definition.json,具体含义:使用Json定义的树状结构,每个节点以`node_label`为key,包含`metadata`字段和`subnodes`字段,`metadata`字段中包含`node_label`(取关键信息名称的拼音首字母、`node_name`(关键信息名称)、`node_type`(取值为`concept`时表示分类节点,`property`时表示属性节点)、`value_type`(仅当`node_type`为`property`时生效,取值为`integer`、`float`、`string`、`boolean`、`date_time`、`class`,其中`class`表示关键信息为复合结构,包含子属性)、`is_list`(仅当`node_type`为`property`时生效,标识关键信息是否为列表类型,即是否可以有多个实例)字段。使用大模型来实现,生成后校验Json结构是否正确,如不正确,给出错误信息让大模型重试。
- ---
- 创建一个 test_definition.py 示例脚本,但复用test.py 中已有的 API 配置调用模型
- ---
- 右下方的文本框里完全没有思考过程输出,之前annotator.py、extractor.py等文件的思考过程输出呢?请将它们返回给前端,并实时流式输出至右下方文本框中。
- ---
- 写个启动脚本吧,里面设置INFO_EXTRACTOR_API_KEY变量,我稍后填入key。
- ---
- 1. 界面右下方,我希望将当前Step也输出出来,当前阶段的思考过程和输出前方统一加4个空格缩进(原有n个空格缩进的话,变为n+4个),阶段之间用“====================================”隔开,例如:
- ```
- 阶段一:XXXXX
- XXXX(思考过程)
- XXXX(思考过程)
- 输出:
- {
- XXXXX
- }
- ====================================
- 阶段2a:XXXX
- ……
- ====================================
- 2. 增加功能:右侧上方区域,不再以markdown形式展示,直接将文字排版显示出来,类似于新闻页面,默认使用仿宋_GB2312字体。解析完成后,对于{{COL1||COL2||COL3||COL4||COL5}}中间的内容进行渲染,文字为原文(COL3),但使用灰色背景将对应文字框选。点击框选区域任意位置,弹出对话框,对话框内表单包含字段:
- ①关键信息名称,值为COL1对应中文字段名,不可编辑;②关键信息值,值为COL2,可编辑;这里你需要根据COL1对应的数据类型和COL4生成组件,如COL1为数字,这里就是数字输入框;COL1为时间,这里就是时间选择框;COL1为字符串,这里就是文本框;COL1为字符串,且COL4约束为枚举型,这里就是下拉选择框;等等。③文中展示值,值为COL3,可编辑,文本框。修改并确认后,后台更新{{}}中的COL2和COL3值,原文中灰色背景框选的部分更新为新的COL3值。
- ---
- 提取报错:提取失败:maximum recursion depth exceeded in comparison
- ---
- 基本实现了,但存在两个问题:
- 1. 灰色选中的区域,不要换行显示,嵌入原文中即可。我以[]表示灰色区域,示例:
- ```
- [小明]是个[医生]。
- ```
- 而非
- ```
- [小明]
- 是个
- [医生]
- 。
- ```
- 2. 文本区域,段落与段落之间空行太多,去掉,一个空行都不要。
- ---
- 另外,右下方思考过程输出时,区域内滚动条自动不断滚到最底部吧
- ---
- 你个垃圾,灰色框选区域不要换行展示,而是嵌入文中,你一点没改;段落与段落之间一个空行都不要,但不是不要换行,还是要一个换行的。你行不行?你不行有的是大模型能干。
- ---
- 有没有一种可能,你用<span>,它灰色区域就一定会换行?我需要它在原文中的原位置,不能换行显示。
- ---
- 基本实现了,但段落之间的换行还要留着啊,怎么没了?从前后端都找找问题。
- 另外,每个段落前要缩进2字符。
- ---
- 当关键信息在段首时,你的处理方式会导致它前面的换行丢失,与上一段接在一起。请解决。
- 另外,为了测试方便,在文本区域增加按钮:导入文本,让我粘贴带{{}}的文本进去,你直接展示,省去标注流程。
- ---
- 段落间的换行又没了,你仔细看看怎么回事,我的要求:段落间的换行要留着,尤其注意段首有关键信息的情况;关键信息两侧的换行不要(除非它在段落首尾)
- ---
- .replace(/(\{\{[^{}]*\}\})/g, (m) => m.replace(/\n+/g, '')),这个语句是干什么用的?逻辑不对吧,执行完以后,文中就没有段落间的换行了
- ---
- function confirmImport() {
- const text = importText.value || ''
- if (!text.trim()) {
- ElMessage.warning('请粘贴要导入的文本')
- return
- }
- annotatedContent.value = normalizeNewsText(text)
- hasResult.value = true
- importDialogVisible.value = false
- ElMessage.success('已导入文本')
- persistAnnotation()
- }
- 这个方法中,normalizeNewsText(text)的结果含\n,为什么最终渲染出来的丢失了换行符?
- ---
- 导入时输入:
- 1
- 2
- 3
- 解析完后,也显示 1 2 3,换行到底怎么回事???
- ---
- 我希望启动前端,但页面上不显示vue调试工具
- ---
- 取消所有TODO。现在,信息管理中,条目无法删除,请实现。写完后,不要启动playwright验证。
- ---
- 把模型的model_name、base_url都做到start_backend的两个脚本里。
- ---
- 现在,我的test.py可以正常使用大模型推理,但使用start_backend.bat调用app.py中的推理,报错: {'error': {'code': '1113', 'message': '余额不足或无可用资源包,请充值。'}},请帮我检查配置。
- ---
- test.py 日志:POST https://open.bigmodel.cn/api/coding/paas/v4/chat/completions "HTTP/1.1 200 OK"
- app.py 日志:POST https://open.bigmodel.cn/api/coding/paas/v4/chat/completions "HTTP/1.1 429 Too Many Requests"
- 你发个请求验证吧
- ---
- 三个问题:
- 1. 最终输出结果,前后容易带上<article>和</article>,过滤掉;
- 2. 对照我的原始需求:“右侧上方区域,不再以markdown形式展示,直接将文字排版显示出来,类似于新闻页面,默认使用仿宋_GB2312字体。解析完成后,对于{{COL1||COL2||COL3||COL4||COL5}}中间的内容进行渲染,文字为原文(COL3),但使用灰色背景将对应文字框选。点击框选区域任意位置,弹出对话框,对话框内表单包含字段:①关键信息名称,值为COL1对应中文字段名,不可编辑;②关键信息值,值为COL2,可编辑;这里你需要根据COL1对应的数据类型和COL4生成组件,如COL1为数字,这里就是数字输入框;COL1为时间,这里就是时间选择框;COL1为字符串,这里就是文本框;COL1为字符串,且COL4约束为枚举型,这里就是下拉选择框;等等。③文中展示值,值为COL3,可编辑,文本框。修改并确认后,后台更新{{}}中的COL2和COL3值,原文中灰色背景框选的部分更新为新的COL3值。” 你现在在灰色背景框选区域中,显示的是COL2的值,而非COL3的值;另外,弹出对话框中,“关键信息值”应为COL2的值,目前为空值;“文中展示值”应为COL3的值,目前为COL2的值。请修改;
- 3. 思考过程容易输出英文思考,请强调输出中文思考过程。
- ---
- 你说“LLM 有时输出 {{path||raw_text||...}}(第 2 段空、第 3 段填了原文),看起来像"COL2 显示成了 COL3"。” 根据我观察,不是的,就算{{}}中内容正确,前端处理也有问题。
- 另外,我不希望完全依赖大模型,请写一个方法,校验LLM输出的结果,{{}}外的内容+{{}}内的原文字段,能否完全匹配原文,若不能,进行相应修改后再输出。
- ---
- 这个新的修复步骤,是否在日志和前端思考过程输出中打印了?如果没有,请补充
- ---
- 重建报错: [修复] text-anchored 重建不可行:text segment 在原文中找不到(从位置 230 起):'指挥员仍然感觉意犹未尽:"每次训练,都是一次全新挑战!"\n\n'
- 就是因为LLM容易出现幻觉,比如,就算让LLM原样输出,它也容易把“”符号输出为""符号,或者出现一些小的问题。所以重建并不是只重建{{}}内的部分,还需要针对{{}}外的部分进行校验和修复,且保持最小的编辑距离。
- ---
- “导入文本”和“提取完成”后,在渲染文本中的组件时,请把每个组件对应的关键信息值、文中展示值打印出来,我查看一下,现在还有问题。
- ---
- @DocumentParse.vue文件中,第341行左右,
- if (ch === '|') {
- fields.push(buf)
- buf = ''
- continue
- }
- 这里有问题,分隔符为“||”而非“|”,修复它。这么明显的问题,为什么会出现???
- ---
|