From f5a057ddc555cf0e7e33cfe1f22cd98ec048ec0c Mon Sep 17 00:00:00 2001 From: lixinyue <2569494688@qq.com> Date: Wed, 31 Dec 2025 11:39:30 +0800 Subject: [PATCH 1/4] =?UTF-8?q?data=5Fconfig=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/models/data_config_model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/app/models/data_config_model.py b/api/app/models/data_config_model.py index 870d46b2..2914432e 100644 --- a/api/app/models/data_config_model.py +++ b/api/app/models/data_config_model.py @@ -51,8 +51,8 @@ class DataConfig(Base): # 自我反思配置 enable_self_reflexion = Column(Boolean, default=False, comment="是否启用自我反思") iteration_period = Column(String, default="3", comment="反思迭代周期") - reflexion_range = Column(String, default="retrieval", comment="反思范围:部分/全部") - baseline = Column(String, default="time", comment="基线:时间/事实/时间和事实") + reflexion_range = Column(String, default="partial", comment="反思范围:部分/全部") + baseline = Column(String, default="TIME", comment="基线:时间/事实/时间和事实") reflection_model_id = Column(String, nullable=True, comment="反思模型ID") memory_verify = Column(Boolean, default=True, comment="记忆验证") quality_assessment = Column(Boolean, default=True, comment="质量评估") From e08e761319d69aa62d0de897da7d0eb823c8b652 Mon Sep 17 00:00:00 2001 From: mengyonghao <1533512157@qq.com> Date: Wed, 31 Dec 2025 12:06:50 +0800 Subject: [PATCH 2/4] fix(workflow): adapt node ID regex to support symbols --- api/app/core/workflow/nodes/end/node.py | 2 +- api/app/templates/workflows/simple_qa/template.yml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/api/app/core/workflow/nodes/end/node.py b/api/app/core/workflow/nodes/end/node.py index efc62dc5..65bb6cb5 100644 --- a/api/app/core/workflow/nodes/end/node.py +++ b/api/app/core/workflow/nodes/end/node.py @@ -61,7 +61,7 @@ class EndNode(BaseNode): 引用的节点 ID 列表 """ # 匹配 {{node_id.xxx}} 格式 - pattern = r'\{\{([a-zA-Z0-9_]+)\.[a-zA-Z0-9_]+\}\}' + pattern = r'\{\{([a-zA-Z0-9_-]+)\.[a-zA-Z0-9_]+\}\}' matches = re.findall(pattern, template) return list(set(matches)) # 去重 diff --git a/api/app/templates/workflows/simple_qa/template.yml b/api/app/templates/workflows/simple_qa/template.yml index dc3a7c70..0843744d 100644 --- a/api/app/templates/workflows/simple_qa/template.yml +++ b/api/app/templates/workflows/simple_qa/template.yml @@ -41,8 +41,6 @@ nodes: - 使用友好、礼貌的语气 - 适当使用格式化(如列表、段落)提高可读性 - - role: user - content: "{{sys.message}}" model_id: null temperature: 0.7 From 742d54342b03ceffcf2f5e10a594511b110caf63 Mon Sep 17 00:00:00 2001 From: lixiangcheng1 Date: Wed, 31 Dec 2025 12:58:30 +0800 Subject: [PATCH 3/4] [fix]parsed excel document error:float division by zero --- .../core/rag/deepdoc/parser/excel_parser.py | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/api/app/core/rag/deepdoc/parser/excel_parser.py b/api/app/core/rag/deepdoc/parser/excel_parser.py index a161f4ca..d66a21a8 100644 --- a/api/app/core/rag/deepdoc/parser/excel_parser.py +++ b/api/app/core/rag/deepdoc/parser/excel_parser.py @@ -48,7 +48,6 @@ class RAGExcelParser: logging.info(f"pandas with default engine load error: {ex}, try calamine instead") file_like_object.seek(0) df = pd.read_excel(file_like_object, engine="calamine") - print("lxc1") return RAGExcelParser._dataframe_to_workbook(df) except Exception as e_pandas: raise Exception(f"pandas.read_excel error: {e_pandas}, original openpyxl error: {e}") @@ -215,19 +214,35 @@ class RAGExcelParser: continue if not rows: continue + # 获取表头 ti = list(rows[0]) - for r in list(rows[1:]): - fields = [] - for i, c in enumerate(r): - if not c.value: - continue - t = str(ti[i].value) if i < len(ti) else "" - t += (":" if t else "") + str(c.value) - fields.append(t) - line = "; ".join(fields) - if sheetname.lower().find("sheet") < 0: - line += " ——" + sheetname - res.append(line) + header_fields = [] + for cell in ti: + if cell.value: # 只添加有值的表头 + header_fields.append(str(cell.value)) + + # 如果有数据行,处理数据行;否则只处理表头 + data_rows = rows[1:] + if data_rows: + for r in data_rows: + fields = [] + for i, c in enumerate(r): + if not c.value: + continue + t = str(ti[i].value) if i < len(ti) else "" + t += (":" if t else "") + str(c.value) + fields.append(t) + line = "; ".join(fields) + if sheetname.lower().find("sheet") < 0: + line += " ——" + sheetname + res.append(line) + else: + # 只有表头的情况 + if header_fields: + line = "; ".join(header_fields) + if sheetname.lower().find("sheet") < 0: + line += " ——" + sheetname + res.append(line) return res @staticmethod From c6cd2e583962aeb2d6ceeac5b456bb31d8ebc7b1 Mon Sep 17 00:00:00 2001 From: lixiangcheng1 Date: Sun, 4 Jan 2026 15:18:44 +0800 Subject: [PATCH 4/4] [fix]get knowledge graph entity types --- api/app/controllers/knowledge_controller.py | 100 ++++++++++---------- 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/api/app/controllers/knowledge_controller.py b/api/app/controllers/knowledge_controller.py index bca69050..deed5723 100644 --- a/api/app/controllers/knowledge_controller.py +++ b/api/app/controllers/knowledge_controller.py @@ -1,26 +1,28 @@ -from typing import Optional import datetime import json +from typing import Optional import uuid + from fastapi import APIRouter, Depends, HTTPException, status, Query from sqlalchemy import or_ from sqlalchemy.orm import Session +from app.celery_app import celery_app +from app.core.logging_config import get_api_logger +from app.core.rag.common import settings +from app.core.rag.llm.chat_model import Base +from app.core.rag.nlp import rag_tokenizer, search +from app.core.rag.prompts.generator import graph_entity_types +from app.core.rag.vdb.elasticsearch.elasticsearch_vector import ElasticSearchVectorFactory +from app.core.response_utils import success from app.db import get_db from app.dependencies import get_current_user from app.models.user_model import User from app.models import knowledge_model, document_model, file_model from app.schemas import knowledge_schema from app.schemas.response_schema import ApiResponse -from app.core.response_utils import success from app.services import knowledge_service, document_service -from app.core.rag.llm.chat_model import Base -from app.core.rag.prompts.generator import graph_entity_types -from app.core.rag.vdb.elasticsearch.elasticsearch_vector import ElasticSearchVectorFactory -from app.core.logging_config import get_api_logger -from app.core.rag.nlp import rag_tokenizer, search -from app.core.rag.common import settings -from app.celery_app import celery_app +from app.services.model_service import ModelConfigService # Obtain a dedicated API logger api_logger = get_api_logger() @@ -47,6 +49,45 @@ def get_parser_types(): return success(msg="Successfully obtained the knowledge parser type", data=list(knowledge_model.ParserType)) +@router.get("/knowledge_graph_entity_types", response_model=ApiResponse) +async def get_knowledge_graph_entity_types( + llm_id: uuid.UUID, + scenario: str, + db: Session = Depends(get_db), + current_user: User = Depends(get_current_user) +): + """ + get knowledge graph entity types based on llm_id + """ + api_logger.info(f"Obtain details of the knowledge graph: llm_id={llm_id}, username: {current_user.username}") + + try: + # 1. Check whether the model exists + api_logger.debug(f"Check whether the model exists: {llm_id}") + config = ModelConfigService.get_model_by_id(db=db, model_id=llm_id) + + if not config: + api_logger.warning( + f"The model does not exist or you do not have permission to access it: llm_id={llm_id}") + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="The model does not exist or you do not have permission to access it" + ) + # 2. Prepare to configure chat_mdl information + chat_model = Base( + key=config.api_keys[0].api_key, + model_name=config.api_keys[0].model_name, + base_url=config.api_keys[0].api_base + ) + response = graph_entity_types(chat_model, scenario) + return success(data=response, msg="Successfully obtained knowledge graph entity types") + except HTTPException: + raise + except Exception as e: + api_logger.error(f"get knowledge graph entity types failed: llm_id={llm_id} - {str(e)}") + raise + + @router.get("/knowledges", response_model=ApiResponse) async def get_knowledges( parent_id: Optional[uuid.UUID] = Query(None, description="parent folder id"), @@ -379,7 +420,7 @@ async def delete_knowledge_graph( current_user: User = Depends(get_current_user) ): """ - Soft-delete knowledge graph + delete knowledge graph """ api_logger.info(f"Request to delete knowledge graph: knowledge_id={knowledge_id}, username: {current_user.username}") @@ -442,42 +483,3 @@ async def rebuild_knowledge_graph( except Exception as e: api_logger.error(f"Failed to rebuild knowledge graph: knowledge_id={knowledge_id} - {str(e)}") raise - - -@router.get("/{knowledge_id}/knowledge_graph_entity_types", response_model=ApiResponse) -async def get_knowledge_graph_entity_types( - knowledge_id: uuid.UUID, - scenario: str, - db: Session = Depends(get_db), - current_user: User = Depends(get_current_user) -): - """ - get knowledge graph entity types based on knowledge_id - """ - api_logger.info(f"Obtain details of the knowledge graph: knowledge_id={knowledge_id}, username: {current_user.username}") - - try: - # 1. Check whether the knowledge base exists - api_logger.debug(f"Check whether the knowledge base exists: {knowledge_id}") - db_knowledge = knowledge_service.get_knowledge_by_id(db, knowledge_id=knowledge_id, current_user=current_user) - - if not db_knowledge: - api_logger.warning( - f"The knowledge base does not exist or you do not have permission to access it: knowledge_id={knowledge_id}") - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail="The knowledge base does not exist or you do not have permission to access it" - ) - # 2. Prepare to configure chat_mdl information - chat_model = Base( - key=db_knowledge.llm.api_keys[0].api_key, - model_name=db_knowledge.llm.api_keys[0].model_name, - base_url=db_knowledge.llm.api_keys[0].api_base - ) - response = graph_entity_types(chat_model, scenario) - return success(data=response, msg="Successfully obtained knowledge graph entity types") - except HTTPException: - raise - except Exception as e: - api_logger.error(f"get knowledge graph entity types failed: knowledge_id={knowledge_id} - {str(e)}") - raise