Parcourir la source

v0.0.3-foundation模块基础重构
- ai、database、infrastructure、observability、utils

WangXuMing il y a 4 mois
Parent
commit
7328883687
100 fichiers modifiés avec 12253 ajouts et 8725 suppressions
  1. 8 8
      config/config.ini
  2. 0 8
      config/mulian_servers_config.json
  3. 0 10
      config/prompt/common_model_query.yaml
  4. 21 21
      config/prompt/intent_prompt.yaml
  5. 5 17
      config/prompt/system_prompt.yaml
  6. 0 22
      config/servers_config.json
  7. 2 2
      core/base/progress_manager.py
  8. 2 2
      core/base/redis_duplicate_checker.py
  9. 1 1
      core/base/sse_manager.py
  10. 4 4
      core/base/workflow_manager.py
  11. 1 1
      core/construction_review/component/ai_review_engine.py
  12. 1 1
      core/construction_review/component/document_processor.py
  13. 1 1
      core/construction_review/component/report_generator.py
  14. 3 3
      core/construction_review/component/reviewers/base_reviewer.py
  15. 1 1
      core/construction_review/component/reviewers/utils/prompt_loader.py
  16. 2 2
      core/construction_review/workflows/ai_review_workflow.py
  17. 1 1
      core/construction_review/workflows/document_workflow.py
  18. 1 1
      core/construction_review/workflows/report_workflow.py
  19. 2 2
      database/repositories/bus_data_query.py
  20. 0 0
      foundation/__init__.py
  21. 0 11
      foundation/agent/__init__.py
  22. 0 41
      foundation/agent/function/test_funciton.py
  23. 0 0
      foundation/agent/monitor/__init__.py
  24. 0 11
      foundation/agent/monitor/ai_trace_monitor.py
  25. 19 0
      foundation/ai/__init__.py
  26. 11 0
      foundation/ai/agent/__init__.py
  27. 1 1
      foundation/ai/agent/base_agent.py
  28. 0 0
      foundation/ai/agent/generate/__init__.py
  29. 2 2
      foundation/ai/agent/generate/model_generate.py
  30. 3 3
      foundation/ai/agent/generate/test_intent.py
  31. 15 15
      foundation/ai/agent/test_agent.py
  32. 0 0
      foundation/ai/agent/workflow/test_cus_state.py
  33. 4 4
      foundation/ai/agent/workflow/test_workflow_graph.py
  34. 9 9
      foundation/ai/agent/workflow/test_workflow_node.py
  35. 17 0
      foundation/ai/models/__init__.py
  36. 2 2
      foundation/ai/models/base_online_platform.py
  37. 36 46
      foundation/ai/models/model_handler.py
  38. 3 3
      foundation/ai/models/silicon_flow.py
  39. 0 39
      foundation/core_enums.py
  40. 62 0
      foundation/database/__init__.py
  41. 23 0
      foundation/database/base/__init__.py
  42. 12 0
      foundation/database/base/kg/__init__.py
  43. 13 0
      foundation/database/base/sql/__init__.py
  44. 219 0
      foundation/database/base/sql/async_mysql_base_dao.py
  45. 86 0
      foundation/database/base/sql/async_mysql_conn_pool.py
  46. 15 0
      foundation/database/base/vector/__init__.py
  47. 2 2
      foundation/database/base/vector/base_vector.py
  48. 7 7
      foundation/database/base/vector/milvus_vector.py
  49. 4 4
      foundation/database/base/vector/pg_vector.py
  50. 11 0
      foundation/database/migrations/__init__.py
  51. 39 0
      foundation/database/models/__init__.py
  52. 24 0
      foundation/database/models/kg/__init__.py
  53. 260 0
      foundation/database/models/kg/graph_models.py
  54. 127 0
      foundation/database/models/kg/neo4j_models.py
  55. 19 0
      foundation/database/models/sql/__init__.py
  56. 118 0
      foundation/database/models/sql/mysql_models.py
  57. 51 0
      foundation/database/models/sql/postgres_models.py
  58. 13 0
      foundation/database/models/vector/__init__.py
  59. 153 0
      foundation/database/models/vector/vector_models.py
  60. 11 0
      foundation/database/repositories/__init__.py
  61. 36 0
      foundation/database/repositories/bus_data_query.py
  62. 27 0
      foundation/infrastructure/__init__.py
  63. 14 0
      foundation/infrastructure/cache/__init__.py
  64. 1 1
      foundation/infrastructure/cache/async_redis_lock.py
  65. 1 1
      foundation/infrastructure/cache/redis_config.py
  66. 3 3
      foundation/infrastructure/cache/redis_connection.py
  67. 0 0
      foundation/infrastructure/cache/redis_lock.py
  68. 12 0
      foundation/infrastructure/config/__init__.py
  69. 0 0
      foundation/infrastructure/config/config.py
  70. 11 0
      foundation/infrastructure/messaging/__init__.py
  71. 3 3
      foundation/infrastructure/messaging/celery_app.py
  72. 3 3
      foundation/infrastructure/messaging/tasks.py
  73. 2 2
      foundation/infrastructure/mysql/async_mysql_base_dao.py
  74. 2 2
      foundation/infrastructure/mysql/async_mysql_conn_pool.py
  75. 16 0
      foundation/infrastructure/tracing/__init__.py
  76. 17 3
      foundation/infrastructure/tracing/celery_trace.py
  77. 0 0
      foundation/infrastructure/tracing/trace_context.py
  78. 17 0
      foundation/observability/__init__.py
  79. 12 0
      foundation/observability/logger/__init__.py
  80. 3 2
      foundation/observability/logger/loggering.py
  81. 11 0
      foundation/observability/metrics/__init__.py
  82. 13 0
      foundation/observability/monitoring/__init__.py
  83. 51 0
      foundation/observability/monitoring/ai_trace_monitor.py
  84. 1 1
      foundation/observability/monitoring/time_statistics.py
  85. 0 0
      foundation/rag/__init__.py
  86. 0 97
      foundation/schemas/__init__.py
  87. 50 15
      foundation/schemas/test_schemas.py
  88. 0 0
      foundation/services/base/__init__.py
  89. 0 0
      foundation/services/external/__init__.py
  90. 0 0
      foundation/services/integration/__init__.py
  91. 0 0
      foundation/services/model/__init__.py
  92. 0 0
      foundation/services/monitoring/__init__.py
  93. 17 0
      foundation/utils/__init__.py
  94. 6 6
      foundation/utils/redis_utils.py
  95. 254 42
      foundation/utils/tool_utils.py
  96. 13 6
      foundation/utils/yaml_utils.py
  97. 10164 3412
      logs/agent_debug.log.1
  98. 0 4799
      logs/agent_info.log.1
  99. 46 9
      server/app.py
  100. 0 10
      server/cus_middlewares.py

+ 8 - 8
config/config.ini

@@ -81,8 +81,9 @@ QWEN_LOCAL_1_5B_MODEL_ID=Qwen3-4B
 QWEN_LOCAL_1_5B_API_KEY=dummy
 
 
+
 [mysql]
-MYSQL_HOST=192.168.0.3
+MYSQL_HOST=192.168.92.61
 MYSQL_PORT=13306
 MYSQL_USER=root
 MYSQL_PASSWORD=lq@123
@@ -92,8 +93,6 @@ MYSQL_MAX_SIZE=5
 MYSQL_AUTO_COMMIT=True
 
 
-
-
 [pgvector]
 PGVECTOR_HOST=124.223.140.149
 PGVECTOR_PORT=7432
@@ -103,8 +102,9 @@ PGVECTOR_PASSWORD=pg16@123
 
 
 [milvus]
-MILVUS_HOST=124.223.140.149
-MILVUS_PORT=7432
-MILVUS_DB=vector_db
-MILVUS_USER=vector_user
-MILVUS_PASSWORD=pg16@123
+MILVUS_HOST=192.168.92.61
+MILVUS_PORT=19530
+MILVUS_DB=lq_db
+MILVUS_USER=
+MILVUS_PASSWORD=
+                    

+ 0 - 8
config/mulian_servers_config.json

@@ -1,8 +0,0 @@
- {
-    "@xiwuzc/@mulian/farm-info": {
-        "name": "业务工具列表",
-        "description": "一个支持任何MCP协议客户端的服务器。",
-        "type": "streamable-http",
-        "url": "http://localhost:3001/mcp/"
-    }
-}

+ 0 - 10
config/prompt/common_model_query.yaml

@@ -1,10 +0,0 @@
-
-# 任务提示词
-task_prompt: |
-  你是一个智能助手,根据提供的信息回答问题。
-
-
-
-# test
-template: |
-  ## 测试内容

+ 21 - 21
config/prompt/intent_prompt.yaml

@@ -1,22 +1,22 @@
-
-# 系统提示词
+# 意图识别系统提示语配置
 system_prompt: |
-  基于提供的样例,结合用户最近的对话历史上下文进行意图识别,精准匹配对应的业务场景指令。
-  必须优先参考最近的上下文语义及用户意图演变,若问题与样例中的任一业务场景相符,则返回对应指令;若无法匹配任何已定义场景,则返回 chat_box_generate。
-  严格遵守:仅输出指令字符串,不附加任何解释、说明或格式。
-  用户目前历史上下文信息:
-  {history}
-
-
-
-
-# 意图案例 准备few-shot样例;
-intent_examples: 
-  - inn: 你好;咨询.
-    out: chat_box_generate
-
-  - inn: 执行;操作;查询;处理;
-    out: common_agent
-
-
-           
+  你是一个专业的意图识别助手,能够准确识别用户的意图类型。请分析用户的输入并判断其意图。
+
+description: "意图识别AI助手的系统提示语配置"
+version: "1.0.0"
+author: "LQAgentPlatform"
+
+# 意图识别示例
+intent_examples:
+  - input: "你好"
+    intent: "greeting"
+    description: "用户打招呼"
+  - input: "帮我分析这个文档"
+    intent: "document_analysis"
+    description: "文档分析请求"
+  - input: "今天天气怎么样"
+    intent: "weather_query"
+    description: "天气查询"
+  - input: "谢谢"
+    intent: "gratitude"
+    description: "表达感谢"

+ 5 - 17
config/prompt/system_prompt.yaml

@@ -1,19 +1,7 @@
-
-
-# 系统提示词
+# 系统提示语配置
 system_prompt: |
-  分析专家于一身的AI助手,提供全方位的智能化指导。
-        你的建议要务实、经济、易操作,并能基于物联网数据提供精准预警和具体解决方案。
-            
-
-    
-# 用户上下文会话记录 摘要提示词
-summary_system_prompt: |
-  请总结以下对话内容,保留关键信息:
-  {history}
-
-
+  你是一个专业的AI助手,能够帮助用户解决各种问题。请始终以专业、准确、友好的方式回应。
 
-# test
-template: |
-  ## 测试内容
+description: "系统级AI助手的默认提示语配置"
+version: "1.0.0"
+author: "LQAgentPlatform"

+ 0 - 22
config/servers_config.json

@@ -1,22 +0,0 @@
- {
-    "filesystem": {
-        "command": "npx",
-        "args": [
-            "-y",
-            "@modelcontextprotocol/server-filesystem",
-            "."  
-        ]
-    },
-    "@modelscope/@modelcontextprotocol/fetch": {
-        "name": "Fetch网页内容抓取",
-        "description": "该服务器使大型语言模型能够检索和处理网页内容,将HTML转换为markdown格式,以便于更轻松地使用。",
-        "type": "sse",
-        "url": "https://mcp.api-inference.modelscope.cn/sse/07630cdeaa1548"
-    },
-    "@modelscope/@amap/amap-maps": {
-        "name": "高德地图",
-        "description": "高德地图是一个支持任何MCP协议客户端的服务器,允许用户轻松利用高德地图MCP服务器获取各种基于位置的服务。",
-        "type": "sse",
-        "url": "https://mcp.api-inference.modelscope.cn/sse/1de8cdc801c546"
-    }
-}

+ 2 - 2
core/base/progress_manager.py

@@ -4,8 +4,8 @@ import asyncio
 from typing import Dict, Any, Optional
 from datetime import datetime
 
-from foundation.logger.loggering import server_logger as logger
-from foundation.base.config import config_handler
+from foundation.observability.logger.loggering import server_logger as logger
+from foundation.infrastructure.config import config_handler
 from core.base.sse_manager import unified_sse_manager
 
 

+ 2 - 2
core/base/redis_duplicate_checker.py

@@ -7,7 +7,7 @@ import os
 import json
 from datetime import datetime, timedelta
 import redis
-from foundation.logger.loggering import server_logger as logger
+from foundation.observability.logger.loggering import server_logger as logger
 
 
 class RedisDuplicateChecker:
@@ -16,7 +16,7 @@ class RedisDuplicateChecker:
     def __init__(self):
         try:
             # 从配置文件读取Redis连接信息
-            from foundation.base.config import config_handler
+            from foundation.infrastructure.config import config_handler
             redis_host = config_handler.get('redis', 'REDIS_HOST', 'localhost')
             redis_port = config_handler.get('redis', 'REDIS_PORT', '6379')
             redis_password = config_handler.get('redis', 'REDIS_PASSWORD', '')

+ 1 - 1
core/base/sse_manager.py

@@ -35,7 +35,7 @@ import asyncio
 from typing import Dict, Any, Optional, Callable
 from datetime import datetime
 
-from foundation.logger.loggering import server_logger as logger
+from foundation.observability.logger.loggering import server_logger as logger
 
 
 class UnifiedSSEManager:

+ 4 - 4
core/base/workflow_manager.py

@@ -14,8 +14,8 @@ from langgraph.graph.message import add_messages
 from langchain_core.messages import BaseMessage, HumanMessage, AIMessage
 import json
 
-from foundation.logger.loggering import server_logger as logger
-from foundation.utils.time_statistics import track_execution_time
+from foundation.observability.logger.loggering import server_logger as logger
+from foundation.observability.monitoring.time_statistics import track_execution_time
 from .progress_manager import ProgressManager
 from .redis_duplicate_checker import RedisDuplicateChecker
 from ..construction_review.workflows import DocumentWorkflow,AIReviewWorkflow,ReportWorkflow
@@ -80,8 +80,8 @@ class WorkflowManager:
 
     async def submit_task_processing(self, file_info: dict) -> str:
         """异步提交任务处理(用于file_upload层)"""
-        from foundation.base.tasks import submit_task_processing_task
-        from foundation.trace.celery_trace import CeleryTraceManager
+        from foundation.infrastructure.messaging.tasks import submit_task_processing_task
+        from foundation.infrastructure.tracing.celery_trace import CeleryTraceManager
 
         try:
             logger.info(f"提交文档处理任务到Celery: {file_info['file_id']}")

+ 1 - 1
core/construction_review/component/ai_review_engine.py

@@ -50,7 +50,7 @@ import asyncio
 from enum import Enum
 from dataclasses import dataclass
 from typing import Dict, List, Any
-from foundation.logger.loggering import server_logger as logger
+from foundation.observability.logger.loggering import server_logger as logger
 from core.construction_review.component.reviewers.base_reviewer import BaseReviewer,BaseRAGReviewer
 @dataclass
 class ReviewResult:

+ 1 - 1
core/construction_review/component/document_processor.py

@@ -11,7 +11,7 @@ from pathlib import Path
 from typing import Dict, Any, Optional, Callable
 from datetime import datetime
 
-from foundation.logger.loggering import server_logger as logger
+from foundation.observability.logger.loggering import server_logger as logger
 
 # 引入doc_worker核心组件
 try:

+ 1 - 1
core/construction_review/component/report_generator.py

@@ -9,7 +9,7 @@ from dataclasses import dataclass
 from datetime import datetime
 import json
 
-from foundation.logger.loggering import server_logger as logger
+from foundation.observability.logger.loggering import server_logger as logger
 
 @dataclass
 class DimensionScores:

+ 3 - 3
core/construction_review/component/reviewers/base_reviewer.py

@@ -11,10 +11,10 @@ from abc import ABC
 from typing import Dict, Any, Optional
 from dataclasses import dataclass
 #from langfuse import obverse
-from foundation.agent.monitor.ai_trace_monitor import lf
-from foundation.agent.generate.model_generate import generate_model_client
+from foundation.observability.monitoring.ai_trace_monitor import lf
+from foundation.ai.agent.generate.model_generate import generate_model_client
 from core.construction_review.component.reviewers.utils.prompt_loader import prompt_loader
-from foundation.logger.loggering import server_logger as logger
+from foundation.observability.logger.loggering import server_logger as logger
 
 
 @dataclass

+ 1 - 1
core/construction_review/component/reviewers/utils/prompt_loader.py

@@ -7,7 +7,7 @@
 import yaml
 import os
 from typing import Dict, Any, List
-from foundation.logger.loggering import server_logger as logger
+from foundation.observability.logger.loggering import server_logger as logger
 from langchain_core.prompts import ChatPromptTemplate
 from langchain_core.messages import SystemMessage, HumanMessage
 

+ 2 - 2
core/construction_review/workflows/ai_review_workflow.py

@@ -50,8 +50,8 @@ from typing import Optional, Callable, Dict, Any, TypedDict, Annotated, List
 from langgraph.graph import StateGraph, END
 from langgraph.graph.message import add_messages
 from langchain_core.messages import BaseMessage, HumanMessage, AIMessage
-from foundation.logger.loggering import server_logger as logger
-from foundation.base.redis_connection import RedisConnectionFactory
+from foundation.observability.logger.loggering import server_logger as logger
+from foundation.infrastructure.cache.redis_connection import RedisConnectionFactory
 from ..component import AIReviewEngine
 
 # 常量定义

+ 1 - 1
core/construction_review/workflows/document_workflow.py

@@ -7,7 +7,7 @@ import asyncio
 from typing import Optional, Callable
 from datetime import datetime
 
-from foundation.logger.loggering import server_logger as logger
+from foundation.observability.logger.loggering import server_logger as logger
 from ..component import DocumentProcessor
 
 class DocumentWorkflow:

+ 1 - 1
core/construction_review/workflows/report_workflow.py

@@ -7,7 +7,7 @@ import asyncio
 from typing import Optional, Callable
 from datetime import datetime
 
-from foundation.logger.loggering import server_logger as logger
+from foundation.observability.logger.loggering import server_logger as logger
 from ..component import ReportGenerator
 
 class ReportWorkflow:

+ 2 - 2
database/repositories/bus_data_query.py

@@ -1,7 +1,7 @@
 from typing import List, Tuple, Any, Optional, Dict
-from foundation.logger.loggering import server_logger
+from foundation.observability.logger.loggering import server_logger
 from foundation.utils.common import handler_err
-from foundation.base.mysql.async_mysql_base_dao import AsyncBaseDAO
+from foundation.database.sql.mysql.async_mysql_base_dao import AsyncBaseDAO
 
 
 class BasisOfPreparationDAO(AsyncBaseDAO):

+ 0 - 0
foundation/__init__.py


+ 0 - 11
foundation/agent/__init__.py

@@ -1,11 +0,0 @@
-# !/usr/bin/ python
-# -*- coding: utf-8 -*-
-'''
-@Project    : lq-agent-api
-@File       :__init__.py.py
-@IDE        :PyCharm
-@Author     : 
-@Date       :2025/7/14 15:04
-'''
-
-

+ 0 - 41
foundation/agent/function/test_funciton.py

@@ -1,41 +0,0 @@
-
-
-
-class TestFunciton:
-
-
-    def __init__(self):
-        pass
-
-
-
-    def query_info(self , session_id):
-        """
-            查询信息
-            session_id: 会话ID
-        """
-        return "查询结果:小红,session_id:"+session_id
-    
-
-
-    def execute(self , session_id):
-        """
-            执行任务
-            session_id: 会话ID
-        """
-        return "任务执行完成,session_id:"+session_id
-
-
-
-
-    def handle(self , session_id):
-        """
-            处理任务
-            session_id: 会话ID
-        """
-        return "处理结果:小东,session_id:"+session_id
-    
-
-
-
-test_funtion = TestFunciton()

+ 0 - 0
foundation/agent/monitor/__init__.py


+ 0 - 11
foundation/agent/monitor/ai_trace_monitor.py

@@ -1,11 +0,0 @@
-from langfuse import Langfuse,observe
-from typing import Dict, List
-lf = Langfuse(
-            secret_key="sk-lf-034de024-bade-4d75-9911-319aa1e4ed30",
-            public_key="pk-lf-d55b3b61-e183-42d2-9b8e-febb198dfe9d",
-            base_url="http://127.0.0.1:3000/",
-            
-)
-
-
-

+ 19 - 0
foundation/ai/__init__.py

@@ -0,0 +1,19 @@
+"""
+AI能力模块
+
+提供AI模型管理、智能代理、生成能力和工作流编排功能
+"""
+
+from .models import ModelHandler, get_models, BaseApiPlatform, SiliconFlowAPI
+from .agent import BaseAgent
+
+__all__ = [
+    # 模型管理
+    "ModelHandler",
+    "get_models",
+    "BaseApiPlatform",
+    "SiliconFlowAPI",
+
+    # 智能代理
+    "BaseAgent"
+]

+ 11 - 0
foundation/ai/agent/__init__.py

@@ -0,0 +1,11 @@
+"""
+智能代理模块
+
+提供AI智能代理的基础能力和工作流功能
+"""
+
+from .base_agent import BaseAgent
+
+__all__ = [
+    "BaseAgent"
+]

+ 1 - 1
foundation/agent/base_agent.py → foundation/ai/agent/base_agent.py

@@ -12,7 +12,7 @@ from datetime import datetime
 from io import StringIO
 from contextlib import redirect_stdout
 from typing import Dict, List, Optional
-from foundation.logger.loggering import server_logger
+from foundation.observability.logger.loggering import server_logger
 from foundation.utils.redis_utils import get_redis_result_cache_data_and_delete_key
 
 class BaseAgent:

+ 0 - 0
foundation/agent/generate/__init__.py → foundation/ai/agent/generate/__init__.py


+ 2 - 2
foundation/agent/generate/model_generate.py → foundation/ai/agent/generate/model_generate.py

@@ -9,8 +9,8 @@
 '''
 
 from langchain_core.prompts import ChatPromptTemplate
-from foundation.utils.utils import get_models
-from foundation.logger.loggering import server_logger as logger
+from foundation.ai.models.model_handler import get_models
+from foundation.observability.logger.loggering import server_logger as logger
 
 class GenerateModelClient:
     """

+ 3 - 3
foundation/agent/generate/test_intent.py → foundation/ai/agent/generate/test_intent.py

@@ -13,14 +13,14 @@ import os
 import sys
 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
 
-from foundation.logger.loggering import server_logger
-from foundation.utils.utils import get_models
+from foundation.observability.logger.loggering import server_logger
+from foundation.ai.models import get_models
 from langchain_core.prompts import SystemMessagePromptTemplate
 from langchain_core.prompts import HumanMessagePromptTemplate
 from langchain_core.prompts import ChatPromptTemplate
 from langchain_core.prompts import FewShotChatMessagePromptTemplate
 from foundation.utils import yaml_utils
-from foundation.base.config import config_handler
+from foundation.infrastructure.config import config_handler
 
 
 class TestIntentIdentifyClient:

+ 15 - 15
foundation/agent/test_agent.py → foundation/ai/agent/test_agent.py

@@ -11,10 +11,10 @@ import json
 
 from langgraph.prebuilt import create_react_agent
 from sqlalchemy.sql.functions import user
-from foundation.logger.loggering import server_logger
+from foundation.observability.logger.loggering import server_logger
 from foundation.utils.common import handler_err
-from foundation.utils.utils import get_models
-from foundation.utils.yaml_utils import system_prompt_config
+from foundation.ai.models import get_models
+from foundation.utils.yaml_utils import get_system_prompt_config
 
 import threading
 import time
@@ -22,9 +22,9 @@ from typing import Dict, List, Optional, AsyncGenerator, Any, OrderedDict
 from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
 from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
 from langchain_core.runnables import RunnableConfig
-from foundation.agent.base_agent import BaseAgent
-from foundation.schemas.test_schemas import FormConfig
-from foundation.agent.function.test_funciton import test_funtion
+from foundation.ai.agent.base_agent import BaseAgent
+from foundation.schemas.test_schemas import TestForm
+# from foundation.agent.function.test_funciton import test_funtion
 
 
 class TestAgentClient(BaseAgent):
@@ -56,7 +56,7 @@ class TestAgentClient(BaseAgent):
         self.psutil_available = True
 
         # 固定系统提示词
-        self.system_prompt = system_prompt_config["system_prompt"]
+        self.system_prompt = get_system_prompt_config()["system_prompt"]
 
         # 清理任务
         self.cleanup_task = None
@@ -77,18 +77,18 @@ class TestAgentClient(BaseAgent):
             ("placeholder", "{agent_scratchpad}")
         ])
 
-        # 创建Agent - 不再使用MemorySaver
-        self.agent_executor = create_react_agent(
-            self.llm,
-            tools=[test_funtion.query_info , test_funtion.execute , test_funtion.handle] ,  # 专用工具集 + 私有知识库检索工具
-            prompt=prompt
-        )
+        # # 创建Agent - 不再使用MemorySaver
+        # self.agent_executor = create_react_agent(
+        #     self.llm,
+        #     tools=[test_funtion.query_info , test_funtion.execute , test_funtion.handle] ,  # 专用工具集 + 私有知识库检索工具
+        #     prompt=prompt
+        # )
         self.initialized = True
         server_logger.info(" agent initialized")
 
 
     async def handle_query(self, trace_id: str, task_prompt_info: dict, input_query, context=None,
-                            config_param: FormConfig = None):
+                            config_param: TestForm = None):
         try:
             # 确保agent已初始化
             if not self.initialized:
@@ -159,7 +159,7 @@ class TestAgentClient(BaseAgent):
             input_query: str,
             context: Optional[str] = None,
             header_info: Optional[Dict] = None,
-            config_param: FormConfig = None,
+            config_param: TestForm = None,
     ) -> AsyncGenerator[str, None]:
         """流式处理查询(优化缓冲管理)"""
         try:

+ 0 - 0
foundation/agent/workflow/test_cus_state.py → foundation/ai/agent/workflow/test_cus_state.py


+ 4 - 4
foundation/agent/workflow/test_workflow_graph.py → foundation/ai/agent/workflow/test_workflow_graph.py

@@ -9,17 +9,17 @@
 @Date       :2025/08/10 18:00
 '''
 
-from foundation.agent.workflow.test_cus_state import TestCusState
-from foundation.agent.workflow.test_workflow_node import TestWorkflowNode
+from foundation.ai.agent.workflow.test_cus_state import TestCusState
+from foundation.ai.agent.workflow.test_workflow_node import TestWorkflowNode
 from langgraph.graph import START, StateGraph, END
 from langgraph.checkpoint.memory import MemorySaver
-from foundation.logger.loggering import server_logger
+from foundation.observability.logger.loggering import server_logger
 from typing import AsyncGenerator
 import time
 from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
 from foundation.utils.common import return_json, handler_err
 import json
-from foundation.schemas.test_schemas import TestForm, FormConfig
+from foundation.schemas.test_schemas import TestForm
 
 
 class TestWorkflowGraph:

+ 9 - 9
foundation/agent/workflow/test_workflow_node.py → foundation/ai/agent/workflow/test_workflow_node.py

@@ -13,16 +13,16 @@
 
 import json
 import sys
-from foundation.logger.loggering import server_logger
+from foundation.observability.logger.loggering import server_logger
 from foundation.utils.common import handler_err
 from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
 from langchain_core.prompts import ChatPromptTemplate
-from foundation.agent.workflow.test_cus_state import TestCusState
-from foundation.agent.generate.test_intent import intent_identify_client
-from foundation.agent.test_agent import test_agent_client
-from foundation.schemas.test_schemas import FormConfig
-from foundation.agent.generate.model_generate import generate_model_client
-from foundation.utils.yaml_utils import system_prompt_config
+from foundation.ai.agent.workflow.test_cus_state import TestCusState
+from foundation.ai.agent.generate.test_intent import intent_identify_client
+from foundation.ai.agent.test_agent import test_agent_client
+from foundation.schemas.test_schemas import TestForm
+from foundation.ai.agent.generate.model_generate import generate_model_client
+from foundation.utils.yaml_utils import get_system_prompt_config
 
 
 
@@ -74,7 +74,7 @@ class TestWorkflowNode:
         session_id = state["session_id"]
         trace_id = state["trace_id"]
         user_input = state["user_input"]
-        config_param = FormConfig(session_id=session_id)
+        config_param = TestForm(session_id=session_id)
         task_prompt_info = {"task_prompt": ""}
         response_content = await test_agent_client.handle_query(trace_id=trace_id , config_param=config_param, 
                                                                 task_prompt_info=task_prompt_info, 
@@ -101,7 +101,7 @@ class TestWorkflowNode:
 
       # 创建ChatPromptTemplate
         template = ChatPromptTemplate.from_messages([
-            ("system", system_prompt_config['system_prompt']),
+            ("system", get_system_prompt_config()['system_prompt']),
             ("user", user_input)
         ])
 

+ 17 - 0
foundation/ai/models/__init__.py

@@ -0,0 +1,17 @@
+"""
+AI模型管理模块
+
+提供多种AI模型的统一管理和适配
+"""
+
+from .model_handler import ModelHandler, get_models, model_handler
+from .base_online_platform import BaseApiPlatform
+from .silicon_flow import SiliconFlowAPI
+
+__all__ = [
+    "ModelHandler",
+    "get_models",
+    "model_handler",
+    "BaseApiPlatform",
+    "SiliconFlowAPI"
+]

+ 2 - 2
foundation/models/base_online_platform.py → foundation/ai/models/base_online_platform.py

@@ -1,8 +1,8 @@
 
 
 import os
-from foundation.base.config import config_handler
-from foundation.logger.loggering import server_logger
+from foundation.infrastructure.config.config import config_handler
+from foundation.observability.logger.loggering import server_logger
 from openai import OpenAI
 
 

+ 36 - 46
foundation/utils/utils.py → foundation/ai/models/model_handler.py

@@ -1,51 +1,32 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
-'''
-@Project   : lq-agent-api
-@File      : utils.py
-@IDE       : VsCode
-@Author    :
-@Date      : 2025-12-04 10:13:12
-
-=================================
-
-📋 方法总览 (Method Overview)
-
-🏗️ 核心模型管理:
-├── ModelHandler()               # 模型处理器类
-├── get_models()                 # 获取模型的全局函数
-└── model_handler                # 全局模型处理器实例
-
-🔍 模型获取方法:
-├── _get_doubao_model()          # 获取豆包模型
-├── _get_qwen_model()            # 获取通义千问模型
-├── _get_deepseek_model()        # 获取DeepSeek模型
-├── _get_gemini_model()          # 获取Gemini模型
-├── _get_lq_qwen3_8b_model()     # 获取本地Qwen3-8B模型
-├── _get_lq_qwen3_4b_model()     # 获取本地Qwen3-4B模型
-└── _get_qwen_local_14b_model()  # 获取本地Qwen3-14B模型
-'''
-
-from langchain_openai import ChatOpenAI
+"""
+AI模型处理器
+
+用于管理多种AI模型的创建和配置
+
+支持的模型类型:
+- doubao: 豆包模型
+- qwen: 通义千问模型
+- deepseek: DeepSeek模型
+- gemini: Gemini模型
+- lq_qwen3_8b: 本地Qwen3-8B模型
+- lq_qwen3_4b: 本地Qwen3-4B模型
+- qwen_local_14b: 本地Qwen3-14B模型
+- lq_qwen3_8b_emd: 本地Qwen3-Embedding-8B嵌入模型
+"""
+
+from langchain_openai import ChatOpenAI, OpenAIEmbeddings
 from langchain_core.messages import HumanMessage
 
-from foundation.base.config import config_handler
-from foundation.logger.loggering import server_logger as logger
+from foundation.infrastructure.config.config import config_handler
+from foundation.observability.logger.loggering import server_logger as logger
 
 
 class ModelHandler:
     """
     AI模型处理器类,用于管理多种AI模型的创建和配置
-
-    支持的模型类型:
-    - doubao: 豆包模型
-    - qwen: 通义千问模型
-    - deepseek: DeepSeek模型
-    - gemini: Gemini模型
-    - lq_qwen3_8b: 本地Qwen3-8B模型
-    - lq_qwen3_4b: 本地Qwen3-4B模型
-    - qwen_local_14b: 本地Qwen3-14B模型
     """
 
     def __init__(self):
@@ -93,7 +74,6 @@ class ModelHandler:
         logger.info(f"AI模型初始化完成: {model_type}")
         return model
 
-
     def _get_doubao_model(self):
         """
         获取豆包模型
@@ -105,7 +85,6 @@ class ModelHandler:
         doubao_model_id = self.config.get("doubao", "DOUBAO_MODEL_ID")
         doubao_api_key = self.config.get("doubao", "DOUBAO_API_KEY")
 
-
         llm = ChatOpenAI(
             base_url=doubao_url,
             model=doubao_model_id,
@@ -114,10 +93,9 @@ class ModelHandler:
             extra_body={
                 "enable_thinking": False,
             })
-        
+
         return llm
 
-	
     def _get_qwen_model(self):
         """
         获取通义千问模型
@@ -139,7 +117,7 @@ class ModelHandler:
             })
 
         return llm
-	
+
     def _get_deepseek_model(self):
         """
         获取DeepSeek模型
@@ -178,9 +156,6 @@ class ModelHandler:
             model=gemini_model_id,
             api_key=gemini_api_key,
             temperature=0.7,
-            # extra_body={
-            #     "enable_thinking": False,
-            # }
             )
 
         return llm
@@ -217,6 +192,21 @@ class ModelHandler:
 
         return llm
 
+    def _get_lq_qwen3_8b_emd(self):
+        """
+        获取本地Qwen3-Embedding-8B嵌入模型
+
+        Returns:
+            OpenAIEmbeddings: 配置好的本地Qwen3-Embedding-8B嵌入模型实例
+        """
+        embeddings = OpenAIEmbeddings(
+            base_url="http://192.168.91.253:9003/v1",
+            model="Qwen3-Embedding-8B",
+            api_key="dummy",  # 本地模型使用虚拟API key
+        )
+
+        return embeddings
+
 
 # 创建全局实例
 model_handler = ModelHandler()

+ 3 - 3
foundation/models/silicon_flow.py → foundation/ai/models/silicon_flow.py

@@ -6,9 +6,9 @@ import sys
 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')))
 import requests
 from dotenv import load_dotenv
-from foundation.models.base_online_platform import BaseApiPlatform
-from foundation.base.config import config_handler
-from foundation.logger.loggering import server_logger
+from foundation.ai.models.base_online_platform import BaseApiPlatform
+from foundation.infrastructure.config.config import config_handler
+from foundation.observability.logger.loggering import server_logger
 from foundation.utils.common import handler_err
 from openai import OpenAI
 from langchain_core.embeddings import Embeddings

+ 0 - 39
foundation/core_enums.py

@@ -1,39 +0,0 @@
-
-from enum import Enum
-
-
-class ErrorCodeEnum(Enum):
-    """
-        错误码枚举定义
-    """
-    SUCCESS = ('100000', '成功')
-    ERROR = ('100500', '服务异常')
-
-    
-    SESSION_ID_EMPTY = ('100001', '会话ID为空')
-    BUSINSESS_SCENE_ERROR = ('100002', '业务场景错误')
-    INPUT_INFO_EMPTY = ('100003', '用户输入为空')
-    BUSINSESS_SCENE_EMPTY = ('100004', '业务场景为空')
-    BUSINSESS_SCENE_PROMPT_FILE_EMPTY = ('100005', '业务场景提示词文件为空')
-    BUSINSESS_SCENE_PROMPT_FILE_NOT_EXISTS = ('100006', '业务场景提示词文件不存在')
-    BUSINSESS_SCENE_PROMPT_FILE_READ_ERROR = ('100007', '业务场景提示词文件读取异常')
-    
-    def __init__(self, code : str, desc : str):
-        self.code = code
-        self.desc = desc
-
-    
-    def get_item_by_code(self , code : str):
-        """
-            根据code 找枚举项
-        """
-        for item in list(ErrorCodeEnum):
-            if item.code == code:
-                return item
-        return None
-
-    
-
-    def __str__(self) -> str:
-        return self.code + ":"  + self.desc
-    

+ 62 - 0
foundation/database/__init__.py

@@ -0,0 +1,62 @@
+"""
+数据库模块
+
+提供统一的数据库访问接口,分离了基础组件实现(base)和数据模型定义(models)
+
+基础组件:数据库连接、DAO、向量数据库实现等
+数据模型:纯数据结构定义,不含业务逻辑
+"""
+
+from .base import (
+    # SQL基础组件
+    AsyncMySQLPool, AsyncBaseDAO,
+    # 向量数据库基础组件
+    BaseVectorDB, MilvusVectorManager, PGVectorDB
+)
+from .models import (
+    # SQL模型
+    UserModel, TestTableModel, BasisOfPreparationModel, PGUserModel,
+    # 向量数据库模型
+    VectorEmbedding, VectorDocument, VectorSearchResult,
+    # 知识图谱模型
+    NodeType, RelationType, GraphNode, GraphEdge, GraphEntity, GraphRelation,
+    KnowledgeGraph, Neo4jNode, Neo4jRelationship, Neo4jGraph
+)
+from .repositories import BasisOfPreparationDAO
+
+__all__ = [
+    # SQL基础组件
+    "AsyncMySQLPool",
+    "AsyncBaseDAO",
+
+    # 向量数据库基础组件
+    "BaseVectorDB",
+    "MilvusVectorManager",
+    "PGVectorDB",
+
+    # SQL模型
+    "UserModel",
+    "TestTableModel",
+    "BasisOfPreparationModel",
+    "PGUserModel",
+
+    # 向量数据库模型
+    "VectorEmbedding",
+    "VectorDocument",
+    "VectorSearchResult",
+
+    # 知识图谱模型
+    "NodeType",
+    "RelationType",
+    "GraphNode",
+    "GraphEdge",
+    "GraphEntity",
+    "GraphRelation",
+    "KnowledgeGraph",
+    "Neo4jNode",
+    "Neo4jRelationship",
+    "Neo4jGraph",
+
+    # 数据仓库
+    "BasisOfPreparationDAO"
+]

+ 23 - 0
foundation/database/base/__init__.py

@@ -0,0 +1,23 @@
+"""
+数据库基础组件模块
+
+提供SQL、向量数据库、知识图谱三种数据库类型的基础组件和实现
+"""
+
+from .sql import AsyncMySQLPool, AsyncBaseDAO
+from .vector import BaseVectorDB, MilvusVectorManager, PGVectorDB
+from .kg import *
+
+__all__ = [
+    # SQL基础组件
+    "AsyncMySQLPool",
+    "AsyncBaseDAO",
+
+    # 向量数据库基础组件
+    "BaseVectorDB",
+    "MilvusVectorManager",
+    "PGVectorDB",
+
+    # 知识图谱基础组件
+    # (未来扩展)
+]

+ 12 - 0
foundation/database/base/kg/__init__.py

@@ -0,0 +1,12 @@
+"""
+知识图谱数据库基础组件模块
+
+提供知识图谱数据库的基础接口和实现
+"""
+
+# 预留知识图谱数据库的基础实现
+# 未来可以添加Neo4j、OrientDB等图数据库的基础实现
+
+__all__ = [
+    # 未来可扩展的图数据库基础组件
+]

+ 13 - 0
foundation/database/base/sql/__init__.py

@@ -0,0 +1,13 @@
+"""
+SQL数据库基础组件模块
+
+提供SQL数据库的基础连接、DAO等功能
+"""
+
+from .async_mysql_conn_pool import AsyncMySQLPool
+from .async_mysql_base_dao import AsyncBaseDAO
+
+__all__ = [
+    "AsyncMySQLPool",
+    "AsyncBaseDAO"
+]

+ 219 - 0
foundation/database/base/sql/async_mysql_base_dao.py

@@ -0,0 +1,219 @@
+from typing import List, Tuple, Any, Optional, Dict
+from mysql.connector import Error
+from foundation.observability.logger.loggering import server_logger
+from foundation.utils.common import handler_err
+from foundation.database.base.sql.async_mysql_conn_pool import AsyncMySQLPool
+import aiomysql
+
+class AsyncBaseDAO:
+    """异步数据库访问基类"""
+    
+    def __init__(self, db_pool: AsyncMySQLPool):
+        self.db_pool = db_pool
+        
+    
+    async def execute_query(self, query: str, params: Tuple = None) -> bool:
+        """执行写操作"""
+        try:
+            async with self.db_pool.get_cursor() as cursor:
+                await cursor.execute(query, params or ())
+                return True
+        except Exception as err:
+            handler_err(logger=server_logger, err=err ,err_name="执行查询失败")
+            raise
+    
+    async def fetch_all(self, query: str, params: Tuple = None) -> List[Dict]:
+        """查询多条记录"""
+        try:
+            async with self.db_pool.get_cursor() as cursor:
+                await cursor.execute(query, params or ())
+                return await cursor.fetchall()
+        except Exception as err:
+            handler_err(logger=server_logger, err=err ,err_name="查询数据失败")
+            raise
+    
+    async def fetch_one(self, query: str, params: Tuple = None) -> Optional[Dict]:
+        """查询单条记录"""
+        try:
+            async with self.db_pool.get_cursor() as cursor:
+                await cursor.execute(query, params or ())
+                return await cursor.fetchone()
+        except Exception as err:
+            handler_err(logger=server_logger, err=err ,err_name="查询单条数据失败")
+            raise
+    
+    async def fetch_scalar(self, query: str, params: Tuple = None) -> Any:
+        """查询单个值"""
+        result = await self.fetch_one(query, params)
+        return list(result.values())[0] if result else None
+    
+    async def execute_many(self, query: str, params_list: List[Tuple]) -> bool:
+        """批量执行"""
+        try:
+            async with self.db_pool.get_cursor() as cursor:
+                await cursor.executemany(query, params_list)
+                return True
+        except Exception as err:
+            handler_err(logger=server_logger, err=err ,err_name="批量执行失败")
+            raise
+
+    async def update_record(self, table: str, updates: Dict, conditions: Dict) -> bool:
+        """
+        通用更新记录方法
+        
+        Args:
+            table: 表名
+            updates: 要更新的字段和值,如 {'name': '新名字', 'age': 25}
+            conditions: 更新条件,如 {'id': 1, 'status': 'active'}
+        
+        Returns:
+            bool: 更新是否成功
+        """
+        if not updates:
+            raise ValueError("更新字段不能为空")
+        
+        if not conditions:
+            raise ValueError("更新条件不能为空")
+        
+        try:
+            # 构建 SET 子句
+            set_clause = ", ".join([f"{field} = %s" for field in updates.keys()])
+            set_values = list(updates.values())
+            
+            # 构建 WHERE 子句
+            where_clause = " AND ".join([f"{field} = %s" for field in conditions.keys()])
+            where_values = list(conditions.values())
+            
+            # 构建完整 SQL
+            sql = f"UPDATE {table} SET {set_clause} WHERE {where_clause}"
+            params = set_values + where_values
+            
+            return await self.execute_query(sql, tuple(params))
+            
+        except Exception as err:
+            handler_err(logger=server_logger, err=err, err_name="更新记录失败")
+            raise
+    
+    async def update_by_id(self, table: str, record_id: int, updates: Dict) -> bool:
+        """
+        根据ID更新记录
+        
+        Args:
+            table: 表名
+            record_id: 记录ID
+            updates: 要更新的字段和值
+        
+        Returns:
+            bool: 更新是否成功
+        """
+        return await self.update_record(table, updates, {'id': record_id})
+    
+    async def update_with_condition(self, table: str, updates: Dict, where_sql: str, params: Tuple = None) -> bool:
+        """
+        使用自定义WHERE条件更新记录
+        
+        Args:
+            table: 表名
+            updates: 要更新的字段和值
+            where_sql: WHERE条件SQL
+            params: WHERE条件参数
+        
+        Returns:
+            bool: 更新是否成功
+        """
+        if not updates:
+            raise ValueError("更新字段不能为空")
+        
+        try:
+            # 构建 SET 子句
+            set_clause = ", ".join([f"{field} = %s" for field in updates.keys()])
+            set_values = list(updates.values())
+            
+            # 构建完整 SQL
+            sql = f"UPDATE {table} SET {set_clause} WHERE {where_sql}"
+            
+            # 合并参数
+            all_params = tuple(set_values) + (params if params else ())
+            
+            return await self.execute_query(sql, all_params)
+            
+        except Exception as err:
+            handler_err(logger=server_logger, err=err, err_name="条件更新失败")
+            raise
+    
+    async def batch_update(self, table: str, updates_list: List[Dict], id_field: str = 'id') -> bool:
+        """
+        批量更新记录(根据ID)
+        
+        Args:
+            table: 表名
+            updates_list: 更新数据列表,每个元素包含id和要更新的字段
+            id_field: ID字段名,默认为'id'
+        
+        Returns:
+            bool: 批量更新是否成功
+        """
+        if not updates_list:
+            raise ValueError("更新数据列表不能为空")
+        
+        try:
+            # 使用事务确保批量操作的原子性
+            async with self.db_pool.get_connection() as conn:
+                async with conn.cursor(aiomysql.DictCursor) as cursor:
+                    for update_data in updates_list:
+                        if id_field not in update_data:
+                            raise ValueError(f"更新数据中缺少{id_field}字段")
+                        
+                        record_id = update_data[id_field]
+                        # 从更新数据中移除ID字段
+                        update_fields = {k: v for k, v in update_data.items() if k != id_field}
+                        
+                        if not update_fields:
+                            continue
+                        
+                        # 构建SET子句
+                        set_clause = ", ".join([f"{field} = %s" for field in update_fields.keys()])
+                        set_values = list(update_fields.values())
+                        
+                        # 执行更新
+                        sql = f"UPDATE {table} SET {set_clause} WHERE {id_field} = %s"
+                        params = set_values + [record_id]
+                        
+                        await cursor.execute(sql, params)
+                    
+                    # 提交事务
+                    await conn.commit()
+                    return True
+                    
+        except Exception as err:
+            handler_err(logger=server_logger, err=err, err_name="批量更新失败")
+            raise
+
+
+class TestTabDAO(AsyncBaseDAO):
+    """异步用户数据访问对象"""
+    
+
+    async def insert_user(self, name: str, email: str, age: int) -> int:
+        """插入用户"""
+        insert_sql = "INSERT INTO test_tab (name, email, age) VALUES (%s, %s, %s)"
+        try:
+            async with self.db_pool.get_cursor() as cursor:
+                await cursor.execute(insert_sql, (name, email, age))
+                return cursor.lastrowid
+        except Exception as err:
+            handler_err(logger=server_logger, err=err ,err_name="插入用户失败")
+            raise
+    
+    async def get_user_by_id(self, user_id: int) -> Optional[Dict]:
+        """根据ID获取用户"""
+        query = "SELECT * FROM test_tab WHERE id = %s AND status = 'active'"
+        return await self.fetch_one(query, (user_id,))
+    
+    async def get_all_users(self) -> List[Dict]:
+        """获取所有用户"""
+        query = "SELECT * FROM test_tab WHERE status = 'active' ORDER BY created_at DESC"
+        return await self.fetch_all(query)
+    
+
+

+ 86 - 0
foundation/database/base/sql/async_mysql_conn_pool.py

@@ -0,0 +1,86 @@
+import aiomysql
+from contextlib import asynccontextmanager
+from typing import  Dict,Optional, AsyncGenerator
+from foundation.observability.logger.loggering import server_logger
+from foundation.utils.common import handler_err
+from foundation.infrastructure.config.config import config_handler
+
+# 异步数据库连接池
+class AsyncMySQLPool:
+    _instance = None
+    
+    def __new__(cls, *args, **kwargs):
+        if not cls._instance:
+            cls._instance = super().__new__(cls)
+        return cls._instance
+    
+    def __init__(self):
+        if not hasattr(self, '_pool'):
+            self._pool = None
+            self._initialized = False
+    
+    async def initialize(self):
+        """初始化连接池"""
+        try:
+            
+            self._pool = await aiomysql.create_pool(
+                host=config_handler.get("mysql", "MYSQL_HOST" , "localhost"),
+                port=int(config_handler.get("mysql", "MYSQL_PORT" , "3306")),
+                user=config_handler.get("mysql", "MYSQL_USER"),
+                password=config_handler.get("mysql", "MYSQL_PASSWORD"),
+                db=config_handler.get("mysql", "MYSQL_DB"),
+                minsize=int(config_handler.get("mysql", "MYSQL_MIN_SIZE" , "1")),
+                maxsize=int(config_handler.get("mysql", "MYSQL_MAX_SIZE" , "2")),
+                autocommit=config_handler.get("mysql", "MYSQL_AUTO_COMMIT")
+            )
+            self._initialized = True
+            server_logger.info("异步MySQL连接池初始化成功")
+        except Exception as e:
+            server_logger.error(f"连接池初始化失败: {e}")
+            raise
+    
+    async def close(self):
+        """关闭连接池"""
+        if self._pool:
+            self._pool.close()
+            await self._pool.wait_closed()
+            server_logger.info("异步MySQL连接池已关闭")
+    
+    @asynccontextmanager
+    async def get_connection(self) -> AsyncGenerator[aiomysql.Connection, None]:
+        """获取数据库连接的上下文管理器"""
+        if not self._initialized:
+            # 如果没有初始化,使用默认配置初始化
+            await self.initialize()
+        
+        async with self._pool.acquire() as conn:
+            try:
+                yield conn
+            except Exception as e:
+                server_logger.error(f"数据库连接操作失败: {e}")
+                raise
+    
+    @asynccontextmanager
+    async def get_cursor(self, connection: Optional[aiomysql.Connection] = None) -> AsyncGenerator[aiomysql.Cursor, None]:
+        """获取游标的上下文管理器"""
+        if connection:
+            # 使用提供的连接
+            async with connection.cursor(aiomysql.DictCursor) as cursor:
+                try:
+                    yield cursor
+                except Exception as e:
+                    server_logger.error(f"游标操作失败: {e}")
+                    raise
+        else:
+            # 创建新连接
+            async with self.get_connection() as conn:
+                async with conn.cursor(aiomysql.DictCursor) as cursor:
+                    try:
+                        yield cursor
+                    except Exception as e:
+                        server_logger.error(f"游标操作失败: {e}")
+                        raise
+
+
+# 全局数据库连接池实例
+#async_db_pool = AsyncMySQLPool()

+ 15 - 0
foundation/database/base/vector/__init__.py

@@ -0,0 +1,15 @@
+"""
+向量数据库基础组件模块
+
+提供向量数据库的基础接口和实现
+"""
+
+from .base_vector import BaseVectorDB
+from .milvus_vector import MilvusVectorManager
+from .pg_vector import PGVectorDB
+
+__all__ = [
+    "BaseVectorDB",
+    "MilvusVectorManager",
+    "PGVectorDB"
+]

+ 2 - 2
foundation/rag/vector/base_vector.py → foundation/database/base/vector/base_vector.py

@@ -1,9 +1,9 @@
-from foundation.logger.loggering import server_logger as logger
+from foundation.observability.logger.loggering import server_logger as logger
 import os
 import time
 from tqdm import tqdm
 from typing import List, Dict, Any
-from foundation.models.base_online_platform import BaseApiPlatform
+from foundation.ai.models.base_online_platform import BaseApiPlatform
 
 
 class BaseVectorDB:

+ 7 - 7
foundation/rag/vector/milvus_vector.py → foundation/database/base/vector/milvus_vector.py

@@ -4,10 +4,10 @@ from pymilvus import connections, Collection, FieldSchema, CollectionSchema, Dat
 import numpy as np
 from typing import List, Dict, Any, Optional
 import json
-from foundation.base.config import config_handler
-from foundation.logger.loggering import server_logger as logger
-from foundation.rag.vector.base_vector import BaseVectorDB
-from foundation.models.base_online_platform import BaseApiPlatform
+from foundation.infrastructure.config.config import config_handler
+from foundation.observability.logger.loggering import server_logger as logger
+from foundation.database.base.vector.base_vector import BaseVectorDB
+from foundation.ai.models.base_online_platform import BaseApiPlatform
 
 class MilvusVectorManager(BaseVectorDB):
     def __init__(self, base_api_platform :BaseApiPlatform):
@@ -63,7 +63,7 @@ class MilvusVectorManager(BaseVectorDB):
             # 定义字段
             fields = [
                 FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
-                FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=dimension),
+                FieldSchema(name="vector", dtype=DataType.FLOAT_VECTOR, dim=dimension),
                 FieldSchema(name="text_content", dtype=DataType.VARCHAR, max_length=65535),
                 FieldSchema(name="metadata", dtype=DataType.JSON),
                 FieldSchema(name="created_at", dtype=DataType.INT64)
@@ -87,8 +87,8 @@ class MilvusVectorManager(BaseVectorDB):
                 "metric_type": "COSINE",
                 "params": {"nlist": 100}
             }
-            
-            collection.create_index(field_name="embedding", index_params=index_params)
+
+            collection.create_index(field_name="vector", index_params=index_params)
             logger.info(f"Collection {collection_name} created successfully!")
             
         except Exception as e:

+ 4 - 4
foundation/rag/vector/pg_vector.py → foundation/database/base/vector/pg_vector.py

@@ -5,10 +5,10 @@ import numpy as np
 #from sentence_transformers import SentenceTransformer
 import json
 from typing import List, Dict, Any
-from foundation.base.config import config_handler
-from foundation.logger.loggering import server_logger as logger
-from foundation.rag.vector.base_vector import BaseVectorDB
-from foundation.models.base_online_platform import BaseApiPlatform
+from foundation.infrastructure.config.config import config_handler
+from foundation.observability.logger.loggering import server_logger as logger
+from foundation.database.base.vector.base_vector import BaseVectorDB
+from foundation.ai.models.base_online_platform import BaseApiPlatform
 
 class PGVectorDB(BaseVectorDB):
     def __init__(self , base_api_platform :BaseApiPlatform):

+ 11 - 0
foundation/database/migrations/__init__.py

@@ -0,0 +1,11 @@
+"""
+数据库迁移模块
+
+提供数据库版本管理和迁移功能
+"""
+
+# 预留数据库迁移功能接口
+
+__all__ = [
+    # 未来可扩展的迁移管理器
+]

+ 39 - 0
foundation/database/models/__init__.py

@@ -0,0 +1,39 @@
+"""
+数据库模型模块
+
+仅包含SQL、向量数据库、知识图谱三种数据库类型的数据模型定义(不含实现)
+"""
+
+# SQL数据库模型
+from .sql import *
+
+# 向量数据库模型
+from .vector import *
+
+# 知识图谱模型
+from .kg import *
+
+__all__ = [
+    # SQL模型
+    "UserModel",
+    "TestTableModel",
+    "BasisOfPreparationModel",
+    "PGUserModel",
+
+    # 向量数据库模型
+    "VectorEmbedding",
+    "VectorDocument",
+    "VectorSearchResult",
+
+    # 知识图谱模型
+    "NodeType",
+    "RelationType",
+    "GraphNode",
+    "GraphEdge",
+    "GraphEntity",
+    "GraphRelation",
+    "KnowledgeGraph",
+    "Neo4jNode",
+    "Neo4jRelationship",
+    "Neo4jGraph"
+]

+ 24 - 0
foundation/database/models/kg/__init__.py

@@ -0,0 +1,24 @@
+"""
+知识图谱数据库模型模块
+
+提供知识图谱相关的模型定义和实现
+"""
+
+from .neo4j_models import *
+from .graph_models import *
+
+__all__ = [
+    # Neo4j模型
+    "Neo4jNode",
+    "Neo4jRelationship",
+    "Neo4jGraph",
+
+    # 图数据模型
+    "NodeType",
+    "RelationType",
+    "GraphNode",
+    "GraphEdge",
+    "KnowledgeGraph",
+    "GraphEntity",
+    "GraphRelation"
+]

+ 260 - 0
foundation/database/models/kg/graph_models.py

@@ -0,0 +1,260 @@
+"""
+图数据模型定义
+
+提供知识图谱相关的通用数据结构定义
+"""
+
+from typing import Optional, Dict, Any, List, Union
+from dataclasses import dataclass
+from datetime import datetime
+from enum import Enum
+
+
+class NodeType(Enum):
+    """节点类型枚举"""
+    PERSON = "person"
+    ORGANIZATION = "organization"
+    LOCATION = "location"
+    CONCEPT = "concept"
+    EVENT = "event"
+    DOCUMENT = "document"
+    UNKNOWN = "unknown"
+
+
+class RelationType(Enum):
+    """关系类型枚举"""
+    BELONGS_TO = "belongs_to"
+    LOCATED_IN = "located_in"
+    RELATED_TO = "related_to"
+    PART_OF = "part_of"
+    INSTANCE_OF = "instance_of"
+    KNOWS = "knows"
+    WORKS_FOR = "works_for"
+    UNKNOWN = "unknown"
+
+
+@dataclass
+class GraphNode:
+    """图节点数据模型"""
+    id: Optional[str] = None
+    label: str = ""
+    node_type: NodeType = NodeType.UNKNOWN
+    properties: Optional[Dict[str, Any]] = None
+    embeddings: Optional[List[float]] = None
+    created_at: Optional[datetime] = None
+    updated_at: Optional[datetime] = None
+
+    def __post_init__(self):
+        if self.properties is None:
+            self.properties = {}
+        if isinstance(self.node_type, str):
+            self.node_type = NodeType(self.node_type)
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'label': self.label,
+            'node_type': self.node_type.value if self.node_type else None,
+            'properties': self.properties,
+            'embeddings': self.embeddings,
+            'created_at': self.created_at.isoformat() if self.created_at else None,
+            'updated_at': self.updated_at.isoformat() if self.updated_at else None
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'GraphNode':
+        """从字典创建实例"""
+        node_type = data.get('node_type')
+        if isinstance(node_type, str):
+            node_type = NodeType(node_type)
+
+        return cls(
+            id=data.get('id'),
+            label=data.get('label', ''),
+            node_type=node_type,
+            properties=data.get('properties', {}),
+            embeddings=data.get('embeddings', []),
+            created_at=datetime.fromisoformat(data['created_at']) if data.get('created_at') else None,
+            updated_at=datetime.fromisoformat(data['updated_at']) if data.get('updated_at') else None
+        )
+
+
+@dataclass
+class GraphEdge:
+    """图边数据模型"""
+    id: Optional[str] = None
+    source_id: str = ""
+    target_id: str = ""
+    relation_type: RelationType = RelationType.UNKNOWN
+    weight: float = 1.0
+    properties: Optional[Dict[str, Any]] = None
+    created_at: Optional[datetime] = None
+
+    def __post_init__(self):
+        if self.properties is None:
+            self.properties = {}
+        if isinstance(self.relation_type, str):
+            self.relation_type = RelationType(self.relation_type)
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'source_id': self.source_id,
+            'target_id': self.target_id,
+            'relation_type': self.relation_type.value if self.relation_type else None,
+            'weight': self.weight,
+            'properties': self.properties,
+            'created_at': self.created_at.isoformat() if self.created_at else None
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'GraphEdge':
+        """从字典创建实例"""
+        relation_type = data.get('relation_type')
+        if isinstance(relation_type, str):
+            relation_type = RelationType(relation_type)
+
+        return cls(
+            id=data.get('id'),
+            source_id=data.get('source_id', ''),
+            target_id=data.get('target_id', ''),
+            relation_type=relation_type,
+            weight=data.get('weight', 1.0),
+            properties=data.get('properties', {}),
+            created_at=datetime.fromisoformat(data['created_at']) if data.get('created_at') else None
+        )
+
+
+@dataclass
+class GraphEntity:
+    """图实体数据模型(扩展的节点模型)"""
+    node: GraphNode
+    entity_type: str = ""
+    confidence: float = 1.0
+    source_document: Optional[str] = None
+    extraction_method: Optional[str] = None
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'node': self.node.to_dict(),
+            'entity_type': self.entity_type,
+            'confidence': self.confidence,
+            'source_document': self.source_document,
+            'extraction_method': self.extraction_method
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'GraphEntity':
+        """从字典创建实例"""
+        node_data = data.get('node', {})
+        node = GraphNode.from_dict(node_data)
+
+        return cls(
+            node=node,
+            entity_type=data.get('entity_type', ''),
+            confidence=data.get('confidence', 1.0),
+            source_document=data.get('source_document'),
+            extraction_method=data.get('extraction_method')
+        )
+
+
+@dataclass
+class GraphRelation:
+    """图关系数据模型(扩展的边模型)"""
+    edge: GraphEdge
+    relation_subtype: Optional[str] = None
+    confidence: float = 1.0
+    source_sentence: Optional[str] = None
+    extraction_method: Optional[str] = None
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'edge': self.edge.to_dict(),
+            'relation_subtype': self.relation_subtype,
+            'confidence': self.confidence,
+            'source_sentence': self.source_sentence,
+            'extraction_method': self.extraction_method
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'GraphRelation':
+        """从字典创建实例"""
+        edge_data = data.get('edge', {})
+        edge = GraphEdge.from_dict(edge_data)
+
+        return cls(
+            edge=edge,
+            relation_subtype=data.get('relation_subtype'),
+            confidence=data.get('confidence', 1.0),
+            source_sentence=data.get('source_sentence'),
+            extraction_method=data.get('extraction_method')
+        )
+
+
+@dataclass
+class KnowledgeGraph:
+    """知识图谱数据模型"""
+    id: Optional[str] = None
+    name: str = ""
+    description: Optional[str] = None
+    nodes: List[GraphEntity] = None
+    relations: List[GraphRelation] = None
+    metadata: Optional[Dict[str, Any]] = None
+    created_at: Optional[datetime] = None
+    updated_at: Optional[datetime] = None
+
+    def __post_init__(self):
+        if self.nodes is None:
+            self.nodes = []
+        if self.relations is None:
+            self.relations = []
+        if self.metadata is None:
+            self.metadata = {}
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'name': self.name,
+            'description': self.description,
+            'nodes': [node.to_dict() for node in self.nodes],
+            'relations': [relation.to_dict() for relation in self.relations],
+            'metadata': self.metadata,
+            'created_at': self.created_at.isoformat() if self.created_at else None,
+            'updated_at': self.updated_at.isoformat() if self.updated_at else None
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'KnowledgeGraph':
+        """从字典创建实例"""
+        nodes_data = data.get('nodes', [])
+        relations_data = data.get('relations', [])
+
+        nodes = [GraphEntity.from_dict(node_data) for node_data in nodes_data]
+        relations = [GraphRelation.from_dict(relation_data) for relation_data in relations_data]
+
+        return cls(
+            id=data.get('id'),
+            name=data.get('name', ''),
+            description=data.get('description'),
+            nodes=nodes,
+            relations=relations,
+            metadata=data.get('metadata', {}),
+            created_at=datetime.fromisoformat(data['created_at']) if data.get('created_at') else None,
+            updated_at=datetime.fromisoformat(data['updated_at']) if data.get('updated_at') else None
+        )
+
+
+__all__ = [
+    "NodeType",
+    "RelationType",
+    "GraphNode",
+    "GraphEdge",
+    "GraphEntity",
+    "GraphRelation",
+    "KnowledgeGraph"
+]

+ 127 - 0
foundation/database/models/kg/neo4j_models.py

@@ -0,0 +1,127 @@
+"""
+Neo4j图数据库模型定义
+
+提供Neo4j图数据库相关的数据结构定义
+"""
+
+from typing import Optional, Dict, Any, List
+from dataclasses import dataclass
+from datetime import datetime
+
+
+@dataclass
+class Neo4jNode:
+    """Neo4j节点数据模型"""
+    id: Optional[int] = None
+    labels: List[str] = None
+    properties: Optional[Dict[str, Any]] = None
+    created_at: Optional[datetime] = None
+
+    def __post_init__(self):
+        if self.labels is None:
+            self.labels = []
+        if self.properties is None:
+            self.properties = {}
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'labels': self.labels,
+            'properties': self.properties,
+            'created_at': self.created_at.isoformat() if self.created_at else None
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'Neo4jNode':
+        """从字典创建实例"""
+        return cls(
+            id=data.get('id'),
+            labels=data.get('labels', []),
+            properties=data.get('properties', {}),
+            created_at=datetime.fromisoformat(data['created_at']) if data.get('created_at') else None
+        )
+
+
+@dataclass
+class Neo4jRelationship:
+    """Neo4j关系数据模型"""
+    id: Optional[int] = None
+    type: str = ""
+    start_node_id: Optional[int] = None
+    end_node_id: Optional[int] = None
+    properties: Optional[Dict[str, Any]] = None
+    created_at: Optional[datetime] = None
+
+    def __post_init__(self):
+        if self.properties is None:
+            self.properties = {}
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'type': self.type,
+            'start_node_id': self.start_node_id,
+            'end_node_id': self.end_node_id,
+            'properties': self.properties,
+            'created_at': self.created_at.isoformat() if self.created_at else None
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'Neo4jRelationship':
+        """从字典创建实例"""
+        return cls(
+            id=data.get('id'),
+            type=data.get('type', ''),
+            start_node_id=data.get('start_node_id'),
+            end_node_id=data.get('end_node_id'),
+            properties=data.get('properties', {}),
+            created_at=datetime.fromisoformat(data['created_at']) if data.get('created_at') else None
+        )
+
+
+@dataclass
+class Neo4jGraph:
+    """Neo4j图数据模型"""
+    nodes: List[Neo4jNode] = None
+    relationships: List[Neo4jRelationship] = None
+    metadata: Optional[Dict[str, Any]] = None
+
+    def __post_init__(self):
+        if self.nodes is None:
+            self.nodes = []
+        if self.relationships is None:
+            self.relationships = []
+        if self.metadata is None:
+            self.metadata = {}
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'nodes': [node.to_dict() for node in self.nodes],
+            'relationships': [rel.to_dict() for rel in self.relationships],
+            'metadata': self.metadata
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'Neo4jGraph':
+        """从字典创建实例"""
+        nodes_data = data.get('nodes', [])
+        relationships_data = data.get('relationships', [])
+
+        nodes = [Neo4jNode.from_dict(node_data) for node_data in nodes_data]
+        relationships = [Neo4jRelationship.from_dict(rel_data) for rel_data in relationships_data]
+
+        return cls(
+            nodes=nodes,
+            relationships=relationships,
+            metadata=data.get('metadata', {})
+        )
+
+
+__all__ = [
+    "Neo4jNode",
+    "Neo4jRelationship",
+    "Neo4jGraph"
+]

+ 19 - 0
foundation/database/models/sql/__init__.py

@@ -0,0 +1,19 @@
+"""
+SQL数据库模型模块
+
+提供SQL数据库相关的模型定义
+"""
+
+# SQL模型相关导入
+from .mysql_models import *
+from .postgres_models import *
+
+__all__ = [
+    # MySQL模型
+    "UserModel",
+    "TestTableModel",
+    "BasisOfPreparationModel",
+
+    # PostgreSQL模型
+    "PGUserModel"
+]

+ 118 - 0
foundation/database/models/sql/mysql_models.py

@@ -0,0 +1,118 @@
+"""
+MySQL数据模型定义
+
+提供MySQL数据库表的结构化模型定义
+"""
+
+from typing import Optional, Dict, Any, List
+from dataclasses import dataclass
+from datetime import datetime
+
+
+@dataclass
+class UserModel:
+    """用户模型"""
+    id: Optional[int] = None
+    name: str = ""
+    email: str = ""
+    age: int = 0
+    created_at: Optional[datetime] = None
+    updated_at: Optional[datetime] = None
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'name': self.name,
+            'email': self.email,
+            'age': self.age,
+            'created_at': self.created_at.isoformat() if self.created_at else None,
+            'updated_at': self.updated_at.isoformat() if self.updated_at else None
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'UserModel':
+        """从字典创建实例"""
+        return cls(
+            id=data.get('id'),
+            name=data.get('name', ''),
+            email=data.get('email', ''),
+            age=data.get('age', 0),
+            created_at=datetime.fromisoformat(data['created_at']) if data.get('created_at') else None,
+            updated_at=datetime.fromisoformat(data['updated_at']) if data.get('updated_at') else None
+        )
+
+
+@dataclass
+class TestTableModel:
+    """测试表模型"""
+    id: Optional[int] = None
+    name: str = ""
+    description: Optional[str] = None
+    status: str = "active"
+    created_at: Optional[datetime] = None
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'name': self.name,
+            'description': self.description,
+            'status': self.status,
+            'created_at': self.created_at.isoformat() if self.created_at else None
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'TestTableModel':
+        """从字典创建实例"""
+        return cls(
+            id=data.get('id'),
+            name=data.get('name', ''),
+            description=data.get('description'),
+            status=data.get('status', 'active'),
+            created_at=datetime.fromisoformat(data['created_at']) if data.get('created_at') else None
+        )
+
+
+@dataclass
+class BasisOfPreparationModel:
+    """编制依据模型"""
+    id: Optional[int] = None
+    title: str = ""
+    content: Optional[str] = None
+    category: Optional[str] = None
+    status: str = "current"
+    created_at: Optional[datetime] = None
+    updated_at: Optional[datetime] = None
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'title': self.title,
+            'content': self.content,
+            'category': self.category,
+            'status': self.status,
+            'created_at': self.created_at.isoformat() if self.created_at else None,
+            'updated_at': self.updated_at.isoformat() if self.updated_at else None
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'BasisOfPreparationModel':
+        """从字典创建实例"""
+        return cls(
+            id=data.get('id'),
+            title=data.get('title', ''),
+            content=data.get('content'),
+            category=data.get('category'),
+            status=data.get('status', 'current'),
+            created_at=datetime.fromisoformat(data['created_at']) if data.get('created_at') else None,
+            updated_at=datetime.fromisoformat(data['updated_at']) if data.get('updated_at') else None
+        )
+
+
+__all__ = [
+    "UserModel",
+    "TestTableModel",
+    "BasisOfPreparationModel"
+]

+ 51 - 0
foundation/database/models/sql/postgres_models.py

@@ -0,0 +1,51 @@
+"""
+PostgreSQL数据模型定义
+
+提供PostgreSQL数据库表的结构化模型定义
+"""
+
+from typing import Optional, Dict, Any, List
+from dataclasses import dataclass
+from datetime import datetime
+
+
+@dataclass
+class PGUserModel:
+    """PostgreSQL用户模型"""
+    id: Optional[int] = None
+    username: str = ""
+    email: str = ""
+    role: str = "user"
+    is_active: bool = True
+    created_at: Optional[datetime] = None
+    updated_at: Optional[datetime] = None
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'username': self.username,
+            'email': self.email,
+            'role': self.role,
+            'is_active': self.is_active,
+            'created_at': self.created_at.isoformat() if self.created_at else None,
+            'updated_at': self.updated_at.isoformat() if self.updated_at else None
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'PGUserModel':
+        """从字典创建实例"""
+        return cls(
+            id=data.get('id'),
+            username=data.get('username', ''),
+            email=data.get('email', ''),
+            role=data.get('role', 'user'),
+            is_active=data.get('is_active', True),
+            created_at=datetime.fromisoformat(data['created_at']) if data.get('created_at') else None,
+            updated_at=datetime.fromisoformat(data['updated_at']) if data.get('updated_at') else None
+        )
+
+
+__all__ = [
+    "PGUserModel"
+]

+ 13 - 0
foundation/database/models/vector/__init__.py

@@ -0,0 +1,13 @@
+"""
+向量数据库模型模块
+
+仅包含向量数据库相关的数据模型定义(不含实现)
+"""
+
+from .vector_models import *
+
+__all__ = [
+    "VectorEmbedding",
+    "VectorDocument",
+    "VectorSearchResult"
+]

+ 153 - 0
foundation/database/models/vector/vector_models.py

@@ -0,0 +1,153 @@
+"""
+向量数据模型定义
+
+提供向量数据库相关的数据结构定义
+"""
+
+from typing import Optional, Dict, Any, List
+from dataclasses import dataclass
+from datetime import datetime
+
+
+@dataclass
+class VectorEmbedding:
+    """向量嵌入数据模型"""
+    id: Optional[str] = None
+    text: str = ""
+    vector: List[float] = None
+    embedding_model: str = ""
+    dimension: int = 0
+    metadata: Optional[Dict[str, Any]] = None
+    created_at: Optional[datetime] = None
+
+    def __post_init__(self):
+        if self.vector is None:
+            self.vector = []
+        if self.metadata is None:
+            self.metadata = {}
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'text': self.text,
+            'vector': self.vector,
+            'embedding_model': self.embedding_model,
+            'dimension': self.dimension,
+            'metadata': self.metadata,
+            'created_at': self.created_at.isoformat() if self.created_at else None
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'VectorEmbedding':
+        """从字典创建实例"""
+        return cls(
+            id=data.get('id'),
+            text=data.get('text', ''),
+            vector=data.get('vector', []),
+            embedding_model=data.get('embedding_model', ''),
+            dimension=data.get('dimension', 0),
+            metadata=data.get('metadata', {}),
+            created_at=datetime.fromisoformat(data['created_at']) if data.get('created_at') else None
+        )
+
+
+@dataclass
+class VectorDocument:
+    """向量文档数据模型"""
+    id: Optional[str] = None
+    text_content: str = ""
+    doc_id: Optional[str] = None
+    doc_type: str = ""
+    category: Optional[str] = None
+    embedding: Optional[VectorEmbedding] = None
+    metadata: Optional[Dict[str, Any]] = None
+    created_at: Optional[datetime] = None
+    updated_at: Optional[datetime] = None
+
+    def __post_init__(self):
+        if self.metadata is None:
+            self.metadata = {}
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'text_content': self.text_content,
+            'doc_id': self.doc_id,
+            'doc_type': self.doc_type,
+            'category': self.category,
+            'embedding': self.embedding.to_dict() if self.embedding else None,
+            'metadata': self.metadata,
+            'created_at': self.created_at.isoformat() if self.created_at else None,
+            'updated_at': self.updated_at.isoformat() if self.updated_at else None
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'VectorDocument':
+        """从字典创建实例"""
+        embedding_data = data.get('embedding')
+        embedding = VectorEmbedding.from_dict(embedding_data) if embedding_data else None
+
+        return cls(
+            id=data.get('id'),
+            text_content=data.get('text_content', ''),
+            doc_id=data.get('doc_id'),
+            doc_type=data.get('doc_type', ''),
+            category=data.get('category'),
+            embedding=embedding,
+            metadata=data.get('metadata', {}),
+            created_at=datetime.fromisoformat(data['created_at']) if data.get('created_at') else None,
+            updated_at=datetime.fromisoformat(data['updated_at']) if data.get('updated_at') else None
+        )
+
+
+@dataclass
+class VectorSearchResult:
+    """向量搜索结果数据模型"""
+    id: Optional[str] = None
+    text_content: Optional[str] = None
+    score: float = 0.0
+    distance: Optional[float] = None
+    metadata: Optional[Dict[str, Any]] = None
+    doc_id: Optional[str] = None
+    doc_type: Optional[str] = None
+    category: Optional[str] = None
+
+    def __post_init__(self):
+        if self.metadata is None:
+            self.metadata = {}
+
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典"""
+        return {
+            'id': self.id,
+            'text_content': self.text_content,
+            'score': self.score,
+            'distance': self.distance,
+            'metadata': self.metadata,
+            'doc_id': self.doc_id,
+            'doc_type': self.doc_type,
+            'category': self.category
+        }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> 'VectorSearchResult':
+        """从字典创建实例"""
+        return cls(
+            id=data.get('id'),
+            text_content=data.get('text_content'),
+            score=data.get('score', 0.0),
+            distance=data.get('distance'),
+            metadata=data.get('metadata', {}),
+            doc_id=data.get('doc_id'),
+            doc_type=data.get('doc_type'),
+            category=data.get('category')
+        )
+
+
+__all__ = [
+    "VectorEmbedding",
+    "VectorDocument",
+    "VectorSearchResult"
+]

+ 11 - 0
foundation/database/repositories/__init__.py

@@ -0,0 +1,11 @@
+"""
+数据库仓库模块
+
+提供数据访问层(Repository)实现
+"""
+
+from .bus_data_query import BasisOfPreparationDAO
+
+__all__ = [
+    "BasisOfPreparationDAO"
+]

+ 36 - 0
foundation/database/repositories/bus_data_query.py

@@ -0,0 +1,36 @@
+from typing import List, Tuple, Any, Optional, Dict
+from foundation.observability.logger.loggering import server_logger
+from foundation.utils.common import handler_err
+from foundation.database.base.sql.async_mysql_base_dao import AsyncBaseDAO
+
+
+class BasisOfPreparationDAO(AsyncBaseDAO):
+    """异步编制依据 对象"""
+    
+    
+    async def get_info_by_id(self, id: int) -> Optional[Dict]:
+        """根据ID获取编制依据"""
+        query = "SELECT * FROM t_basis_of_preparation WHERE id = %s"
+        return await self.fetch_one(query, (id,))
+    
+    async def get_list(self) -> List[Dict]:
+        """获取所有编制依据"""
+        query = "SELECT * FROM t_basis_of_preparation WHERE status = 'current' ORDER BY created_at DESC"
+        return await self.fetch_all(query)
+    
+
+    async def get_info_by_condition(self, conditions: Dict) -> List[Dict]:
+        """根据条件查询编制依据"""
+        if not conditions:
+            return await self.get_list()
+        
+        try:
+            where_clause = " AND ".join([f"{field} = %s" for field in conditions.keys()])
+            where_values = list(conditions.values())
+            
+            query = f"SELECT * FROM t_basis_of_preparation WHERE {where_clause} AND status = 'current' ORDER BY created_at DESC"
+            return await self.fetch_all(query, tuple(where_values))
+            
+        except Exception as err:
+            handler_err(logger=server_logger, err=err, err_name="条件查询失败")
+            raise

+ 27 - 0
foundation/infrastructure/__init__.py

@@ -0,0 +1,27 @@
+"""
+基础设施模块
+
+提供配置管理、缓存、消息队列、链路追踪等基础设施服务
+"""
+
+from .config import ConfigHandler, config_handler
+from .cache import RedisConnectionFactory, RedisConfig
+from .messaging import celery_app
+from .tracing import TraceContext, CeleryTraceManager
+
+__all__ = [
+    # 配置管理
+    "ConfigHandler",
+    "config_handler",
+
+    # 缓存
+    "RedisConnectionFactory",
+    "RedisConfig",
+
+    # 消息队列
+    "celery_app",
+
+    # 链路追踪
+    "TraceContext",
+    "CeleryTraceManager"
+]

+ 14 - 0
foundation/infrastructure/cache/__init__.py

@@ -0,0 +1,14 @@
+"""
+缓存模块
+
+提供Redis缓存和分布式锁功能
+"""
+
+from .redis_connection import RedisConnectionFactory, RedisAdapter
+from .redis_config import RedisConfig
+
+__all__ = [
+    "RedisConnectionFactory",
+    "RedisAdapter",
+    "RedisConfig"
+]

+ 1 - 1
foundation/base/async_redis_lock.py → foundation/infrastructure/cache/async_redis_lock.py

@@ -2,7 +2,7 @@ import asyncio
 import time
 import uuid
 from typing import Optional
-from foundation.logger.loggering import server_logger
+from foundation.observability.logger.loggering import server_logger
 
 class AsyncRedisLock:
     def __init__(self, redis_client, lock_name: str, expire_time: int = 30):

+ 1 - 1
foundation/base/redis_config.py → foundation/infrastructure/cache/redis_config.py

@@ -9,7 +9,7 @@
 '''
 
 from dataclasses import dataclass
-from foundation.base.config import config_handler
+from foundation.infrastructure.config.config import config_handler
 
 
 @dataclass

+ 3 - 3
foundation/base/redis_connection.py → foundation/infrastructure/cache/redis_connection.py

@@ -23,9 +23,9 @@ from redis.exceptions import ConnectionError as redis_ConnectionError
 from typing import Optional, Protocol, Dict, Any, Set, Tuple
 from functools import wraps
 import asyncio
-from foundation.base.redis_config import RedisConfig
-from foundation.base.redis_config import load_config_from_env
-from foundation.logger.loggering import server_logger
+from foundation.infrastructure.cache.redis_config import RedisConfig
+from foundation.infrastructure.cache.redis_config import load_config_from_env
+from foundation.observability.logger.loggering import server_logger
 from typing import Dict, Any, List, Tuple
 from langchain_community.storage import RedisStore
 

+ 0 - 0
foundation/base/redis_lock.py → foundation/infrastructure/cache/redis_lock.py


+ 12 - 0
foundation/infrastructure/config/__init__.py

@@ -0,0 +1,12 @@
+"""
+配置管理模块
+
+提供统一的配置管理功能
+"""
+
+from .config import ConfigHandler, config_handler
+
+__all__ = [
+    "ConfigHandler",
+    "config_handler"
+]

+ 0 - 0
foundation/base/config.py → foundation/infrastructure/config/config.py


+ 11 - 0
foundation/infrastructure/messaging/__init__.py

@@ -0,0 +1,11 @@
+"""
+消息队列模块
+
+提供Celery任务队列功能
+"""
+
+from .celery_app import app as celery_app
+
+__all__ = [
+    "celery_app"
+]

+ 3 - 3
foundation/base/celery_app.py → foundation/infrastructure/messaging/celery_app.py

@@ -5,10 +5,10 @@ Celery应用配置
 
 import os
 from celery import Celery
-from .config import config_handler
+from foundation.infrastructure.config.config import config_handler
 
 # 导入trace系统
-from foundation.trace.celery_trace import init
+from foundation.infrastructure.tracing.celery_trace import init
 
 # 从配置文件获取Redis连接信息
 redis_host = config_handler.get('redis', 'REDIS_HOST', 'localhost')
@@ -28,7 +28,7 @@ app = Celery(
     'workflow_tasks',
     broker=redis_url,
     backend=redis_url,
-    include=['foundation.base.tasks']
+    include=['foundation.infrastructure.messaging.tasks']
 )
 
 # 配置

+ 3 - 3
foundation/base/tasks.py → foundation/infrastructure/messaging/tasks.py

@@ -6,8 +6,8 @@ Celery任务定义
 from celery import current_task
 from .celery_app import app
 from core.base.workflow_manager import WorkflowManager
-from foundation.logger.loggering import server_logger as logger
-from foundation.utils.time_statistics import track_execution_time
+from foundation.observability.logger.loggering import server_logger as logger
+from foundation.observability.monitoring.time_statistics import track_execution_time
 
 
 @app.task(bind=True)
@@ -20,7 +20,7 @@ def submit_task_processing_task(self, file_info: dict, _system_trace_id: str = N
 
     # 恢复trace_id上下文
     if _system_trace_id:
-        from foundation.trace.trace_context import TraceContext
+        from foundation.infrastructure.tracing import TraceContext
         TraceContext.set_trace_id(_system_trace_id)
         logger.info(f"Celery任务恢复")
 

+ 2 - 2
foundation/base/mysql/async_mysql_base_dao.py → foundation/infrastructure/mysql/async_mysql_base_dao.py

@@ -1,8 +1,8 @@
 from typing import List, Tuple, Any, Optional, Dict
 from mysql.connector import Error
-from foundation.logger.loggering import server_logger
+from foundation.observability.logger.loggering import server_logger
 from foundation.utils.common import handler_err
-from foundation.base.mysql.async_mysql_conn_pool import AsyncMySQLPool
+from async_mysql_conn_pool import AsyncMySQLPool
 import aiomysql
 
 class AsyncBaseDAO:

+ 2 - 2
foundation/base/mysql/async_mysql_conn_pool.py → foundation/infrastructure/mysql/async_mysql_conn_pool.py

@@ -1,9 +1,9 @@
 import aiomysql
 from contextlib import asynccontextmanager
 from typing import  Dict,Optional, AsyncGenerator
-from foundation.logger.loggering import server_logger
+from foundation.observability.logger.loggering import server_logger
 from foundation.utils.common import handler_err
-from foundation.base.config import config_handler
+from foundation.infrastructure.config import config_handler
 
 # 异步数据库连接池
 class AsyncMySQLPool:

+ 16 - 0
foundation/infrastructure/tracing/__init__.py

@@ -0,0 +1,16 @@
+"""
+链路追踪模块
+
+提供分布式链路追踪功能
+"""
+
+from .trace_context import TraceContext, auto_trace
+from .celery_trace import CeleryTraceManager, init, add_trace_to_celery_task
+
+__all__ = [
+    "TraceContext",
+    "auto_trace",
+    "CeleryTraceManager",
+    "init",
+    "add_trace_to_celery_task"
+]

+ 17 - 3
foundation/trace/celery_trace.py → foundation/infrastructure/tracing/celery_trace.py

@@ -4,8 +4,7 @@ Celery Trace管理
 """
 
 from celery.signals import task_prerun, task_postrun, task_failure
-from foundation.trace.trace_context import TraceContext
-from foundation.logger.loggering import server_logger as logger
+from .trace_context import TraceContext
 
 
 class CeleryTraceManager:
@@ -21,6 +20,9 @@ class CeleryTraceManager:
             任务执行前的信号处理
             从任务参数中提取trace_id并设置到TraceContext
             """
+            # 延迟导入避免循环依赖
+            from foundation.observability.logger.loggering import server_logger as logger
+
             try:
                 # 从kwargs中提取trace_id参数
                 trace_id = kwargs.pop('_system_trace_id', None) or kwargs.pop('callback_task_id', None)
@@ -46,6 +48,9 @@ class CeleryTraceManager:
             任务执行后的信号处理
             清理trace_id上下文
             """
+            # 延迟导入避免循环依赖
+            from foundation.observability.logger.loggering import server_logger as logger
+
             try:
                 trace_id = TraceContext.get_trace_id()
                 logger.info(f"Celery任务完成: {trace_id}, 任务ID: {task_id}")
@@ -59,6 +64,9 @@ class CeleryTraceManager:
             """
             任务失败时的信号处理
             """
+            # 延迟导入避免循环依赖
+            from foundation.observability.logger.loggering import server_logger as logger
+
             try:
                 trace_id = TraceContext.get_trace_id()
                 logger.error(f"Celery任务失败: {trace_id}, 任务ID: {task_id}, 错误: {str(exception)}")
@@ -78,12 +86,15 @@ class CeleryTraceManager:
         Returns:
             Celery任务结果
         """
+        # 延迟导入避免循环依赖
+        from foundation.observability.logger.loggering import server_logger as logger
+
         # 获取当前trace_id
         current_trace_id = TraceContext.get_trace_id()
 
         # 将trace_id添加到任务参数中
         if current_trace_id and current_trace_id != 'no-trace':
-            kwargs['_system_trace_id'] = current_trace_id   
+            kwargs['_system_trace_id'] = current_trace_id
 
         logger.info(f"提交Celery任务")
 
@@ -117,5 +128,8 @@ def add_trace_to_celery_task(celery_task_func):
 # 自动初始化Celery信号
 def init():
     """初始化Celery trace系统"""
+    # 延迟导入避免循环依赖
+    from foundation.observability.logger.loggering import server_logger as logger
+
     CeleryTraceManager.init_celery_signals()
     logger.info("Celery trace系统初始化完成")

+ 0 - 0
foundation/trace/trace_context.py → foundation/infrastructure/tracing/trace_context.py


+ 17 - 0
foundation/observability/__init__.py

@@ -0,0 +1,17 @@
+"""
+可观测性模块
+
+提供日志记录、性能监控、指标收集等可观测性功能
+"""
+
+from .logger import server_logger, CompatibleLogger
+from .monitoring import track_execution_time
+
+__all__ = [
+    # 日志记录
+    "server_logger",
+    "CompatibleLogger",
+
+    # 监控
+    "track_execution_time",
+]

+ 12 - 0
foundation/observability/logger/__init__.py

@@ -0,0 +1,12 @@
+"""
+日志记录模块
+
+提供结构化日志记录功能
+"""
+
+from .loggering import server_logger, CompatibleLogger
+
+__all__ = [
+    "server_logger",
+    "CompatibleLogger"
+]

+ 3 - 2
foundation/logger/loggering.py → foundation/observability/logger/loggering.py

@@ -7,7 +7,7 @@
 @Author     :
 @Date       :2025/7/11 10:48
 '''
-from foundation.base.config import config_handler
+from foundation.infrastructure.config import config_handler
 
 
 import os
@@ -16,8 +16,9 @@ import logging
 from logging.handlers import RotatingFileHandler
 
 # 导入trace系统
-from foundation.trace.trace_context import TraceContext, trace_filter
 
+from foundation.infrastructure.tracing import TraceContext
+from foundation.infrastructure.tracing.trace_context import trace_filter
 
 class CompatibleLogger(logging.Logger):
     """

+ 11 - 0
foundation/observability/metrics/__init__.py

@@ -0,0 +1,11 @@
+"""
+指标收集模块
+
+提供性能指标和业务指标收集功能
+"""
+
+# 预留指标收集功能接口
+
+__all__ = [
+    # 未来可扩展的指标收集器
+]

+ 13 - 0
foundation/observability/monitoring/__init__.py

@@ -0,0 +1,13 @@
+"""
+监控模块
+
+提供性能监控和AI模型监控功能
+"""
+
+from .time_statistics import track_execution_time
+
+
+__all__ = [
+    "track_execution_time",
+
+]

+ 51 - 0
foundation/observability/monitoring/ai_trace_monitor.py

@@ -0,0 +1,51 @@
+"""
+AI Trace监控模块
+
+提供AI模型链路监控功能
+"""
+
+from langfuse import Langfuse,observe
+from typing import Dict, List
+
+# 初始化Langfuse客户端
+lf = Langfuse(
+    secret_key="sk-lf-034de024-bade-4d75-9911-319aa1e4ed30",
+    public_key="pk-lf-d55b3b61-e183-42d2-9b8e-febb198dfe9d",
+    base_url="http://127.0.0.1:3000/",
+)
+
+
+class TraceMonitor:
+    """AI模型链路监控器"""
+
+    def __init__(self):
+        self.client = lf
+
+    @observe
+    def trace_inference(self, model_name: str, prompt: str, response: str):
+        """
+        跟踪模型推理过程
+
+        Args:
+            model_name: 模型名称
+            prompt: 输入提示
+            response: 模型响应
+        """
+        pass
+
+    def log_event(self, event_name: str, data: Dict):
+        """
+        记录事件
+
+        Args:
+            event_name: 事件名称
+            data: 事件数据
+        """
+        pass
+
+
+# 创建全局实例
+trace_monitor = TraceMonitor()
+
+# 导出Langfuse客户端以便兼容现有代码
+__all__ = ["TraceMonitor", "trace_monitor", "lf"]

+ 1 - 1
foundation/utils/time_statistics.py → foundation/observability/monitoring/time_statistics.py

@@ -2,7 +2,7 @@ import time
 import asyncio
 import inspect
 from functools import wraps
-from ..logger.loggering import server_logger as logger
+from foundation.observability.logger.loggering import server_logger as logger
 
 def track_execution_time(func):
     """

+ 0 - 0
foundation/rag/__init__.py


+ 0 - 97
foundation/schemas/__init__.py

@@ -1,97 +0,0 @@
-import re
-
-
-def is_number(character: str):
-    """
-    判断是否为数字
-    """
-    return bool(re.match(r'^[-+]?\d+(\.\d+)?$', character)) if character else False
-
-
-
-def check_new_parameter(check_v, key, value):
-    """
-    请求前对数据进行校验
-    params: check_v: 一个list [type,(limit_condition)]
-    type 表示 value 应该用什么类型
-    limit_condition 就是检验的条件,可以不存在,如果是list则表示为其中一个,tuple则表示在此范围内
-    key: 是指被检查的参数的名称用以打印日志及返回报错
-    value: 是现在key所对应的具体的值,也是被用来被检查的值
-    return: None or error_msg
-    example:
-      [str, "name", (1, 64)] 表示 name应是字符串类型, 长度应大于等于1小于等于64
-      [list, "sex", [0, 1,...] 表示 sex应是列表,且值应该存在于list[0, 1]中
-      [int, "year", (1, 200)] 表示 year应是整数类型, 数值应大于等于1小于等于200
-    """
-    if check_v[0] == int:
-        if is_number(str(value)):
-            value = int(value)
-    if not isinstance(value, check_v[0]):
-        return "type error, %s should be %s, but now is %s" % (key, str(check_v[0]), value)
-
-    if len(check_v) == 2:
-        if check_v[0] == str:
-            if isinstance(check_v[1], list):
-                if value not in check_v[1]:
-                    return "Invalid param, %s is %s now, not in %s" % (key, value, str(check_v[1]))
-            if isinstance(check_v[1], tuple):
-                if len(value) < check_v[1][0] or len(value) > check_v[1][1]:
-                    return "Invalid param, %s is %s now, length is %s, range from %s to %s" % (key, value, len(value),
-                                                                                               check_v[0], check_v[1])
-        if check_v[0] == int:
-            if isinstance(check_v[1], list):
-                if value not in check_v[1]:
-                    return "Invalid param, %s is %s now, not in %s" % (key, value, str(check_v[1]))
-            if isinstance(check_v[1], tuple):
-                if value < check_v[1][0] or value > check_v[1][1]:
-                    return "Invalid param, %s is %s now, range from %s to %s" % (key, value, check_v[0], check_v[1])
-        if check_v[0] == list:
-            if isinstance(check_v[1], list):
-                for v in value:
-                    if v not in check_v[1]:
-                        return "Invalid param, %s is %s now, not in %s" % (key, v, str(check_v[1]))
-
-
-class CheckParams:
-    """
-    检验参数
-    """
-
-    def __init__(self, request_body, params_dict, logger, logger_name=None):
-        self.request_body = request_body
-        self.params_dict = params_dict
-        self.logger_name = logger_name
-
-        self.res = {
-            "code": 0,
-            "message": "ok",
-            "data": {"operate_id": ""}
-        }
-        self.logger = logger
-        self.body = dict()
-
-    def start(self):
-        """
-        开始校验
-        :return:
-        """
-        for k, v in self.params_dict.items():
-            if k not in self.request_body:
-                if v[0] is True:
-                    message = f"Invalid Access, {self.logger_name} %s is not Found in request" % k
-                    self.logger.error(message)
-                    self.res["message"] = message
-                    self.res["code"] = 400
-                    return False, self.res
-                else:
-                    continue
-            check_result = check_new_parameter(v[1:], k, self.request_body[k])
-            if check_result is None:
-                self.body[k] = self.request_body[k]
-            else:
-                message = f"Invalid Access, {self.logger_name} " + check_result
-                self.logger.error(message)
-                self.res["message"] = message
-                self.res["code"] = 400
-                return False, self.res
-        return True, self.body

+ 50 - 15
foundation/schemas/test_schemas.py

@@ -1,22 +1,57 @@
-# !/usr/bin/ python
+#!/usr/bin/env python
 # -*- coding: utf-8 -*-
-'''
-@Project    : lq-agent-api
-@File       :test_schemas.py
-@IDE        :PyCharm
-@Author     :
-@Date       :2025/7/11 12:41
-'''
-from typing import Optional
-from pydantic import BaseModel, constr, Field
 
+"""
+测试模式定义
 
-class FormConfig(BaseModel):
-    session_id: constr(max_length=128) =Field(description="会话id")
+提供测试相关的数据模型和配置结构
+"""
 
+from typing import Optional, Dict, Any, List
+from pydantic import BaseModel, Field
+
+
+class TestConfig(BaseModel):
+    """测试配置"""
+    session_id: str = Field(description="会话ID")
+    model_type: Optional[str] = Field(default="gemini", description="模型类型")
+    temperature: Optional[float] = Field(default=0.7, description="温度参数")
+    max_tokens: Optional[int] = Field(default=2000, description="最大token数")
 
 
 class TestForm(BaseModel):
-    config: FormConfig
-    input: Optional[str] = Field(description="用户输入")
-    context: Optional[str]  = Field(default=None, description="参考上下文")
+    """测试表单"""
+    input: str = Field(description="输入内容")
+    context: Optional[Dict[str, Any]] = Field(default=None, description="上下文信息")
+    config: TestConfig = Field(description="配置信息")
+
+
+class TestResponse(BaseModel):
+    """测试响应"""
+    output: str = Field(description="输出结果")
+    trace_id: Optional[str] = Field(default=None, description="追踪ID")
+    processing_time: Optional[float] = Field(default=None, description="处理时间(秒)")
+
+
+class StreamEvent(BaseModel):
+    """流式事件"""
+    event: str = Field(description="事件类型")
+    data: Dict[str, Any] = Field(description="事件数据")
+
+
+class TestResult(BaseModel):
+    """测试结果"""
+    success: bool = Field(description="是否成功")
+    message: str = Field(description="消息")
+    data: Optional[Dict[str, Any]] = Field(default=None, description="数据")
+    error: Optional[str] = Field(default=None, description="错误信息")
+
+
+# 导出的类
+__all__ = [
+    "TestConfig",
+    "TestForm",
+    "TestResponse",
+    "StreamEvent",
+    "TestResult"
+]

+ 0 - 0
foundation/services/base/__init__.py


+ 0 - 0
foundation/services/external/__init__.py


+ 0 - 0
foundation/services/integration/__init__.py


+ 0 - 0
foundation/services/model/__init__.py


+ 0 - 0
foundation/services/monitoring/__init__.py


+ 17 - 0
foundation/utils/__init__.py

@@ -0,0 +1,17 @@
+"""
+工具模块
+
+提供通用的工具函数和辅助功能
+"""
+
+from .common import handler_err
+from .md5 import md5_id
+from .redis_utils import get_redis_result_cache_data_and_delete_key
+from .yaml_utils import get_system_prompt_config
+
+__all__ = [
+    "handler_err",
+    "md5_id",
+    "get_redis_result_cache_data_and_delete_key",
+    "get_system_prompt_config"
+]

+ 6 - 6
foundation/utils/redis_utils.py

@@ -8,10 +8,10 @@ from pathlib import Path
 # print(root_dir) 
 # sys.path.append(str(root_dir))  
 from typing import Dict, Optional, Any
-from .time_statistics import track_execution_time
-from foundation.base.config import config_handler
-from foundation.logger.loggering import server_logger
-from foundation.base.redis_connection import RedisConnectionFactory
+from foundation.observability.monitoring.time_statistics import track_execution_time
+from foundation.infrastructure.config import config_handler
+from foundation.observability.logger.loggering import server_logger
+from foundation.infrastructure.cache.redis_connection import RedisConnectionFactory
 # 缓存数据有效期 默认 3 分钟
 CACHE_DATA_EXPIRED_TIME = 3 * 60
 
@@ -204,8 +204,8 @@ async def delete_file_info(file_id: str) -> bool:
     """
     try:
         # 为了避免事件循环冲突,直接创建新的Redis连接
-        from foundation.base.redis_config import load_config_from_env
-        from foundation.base.redis_connection import RedisAdapter
+        from foundation.infrastructure.cache.redis_config import load_config_from_env
+        from foundation.infrastructure.cache.redis_connection import RedisAdapter
 
         redis_config = load_config_from_env()
         adapter = RedisAdapter(redis_config)

+ 254 - 42
foundation/utils/tool_utils.py

@@ -1,54 +1,266 @@
-import time
-from math import log
-import os
-from dotenv import load_dotenv
-from foundation.core_enums import ErrorCodeEnum
-from functools import wraps
-
-from foundation.logger.loggering import server_logger
-from foundation.utils.common import handler_err
-from foundation.base.config import config_handler
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+工具函数模块
+
+提供常用的工具函数和辅助类
+"""
+
 import json
-from datetime import datetime, date
-# 获取当前文件的目录
-current_dir = os.path.dirname(__file__)
-# 构建到 .env 的相对路径
-conf_file_path = os.path.join(current_dir , '../',  '.env')
-#server_logger.info(f"当前目录: {conf_file_path}")
-# 加载环境变量
-load_dotenv(dotenv_path=conf_file_path)
-
-def verify_param(param: dict):
+import datetime
+from typing import Any, Dict, List, Optional, Union
+import hashlib
+import uuid
+import re
+
+
+class DateTimeEncoder(json.JSONEncoder):
     """
-        验证请求参数
+    日期时间JSON编码器
+
+    用于将datetime对象序列化为JSON字符串
     """
-    input_data = param.get("input")
-    session_id = param.get("config").get("session_id")
-    if input_data is None:
-        raise ValueError(ErrorCodeEnum.INPUT_INFO_EMPTY.__str__)
-    if session_id is None:
-        raise ValueError(ErrorCodeEnum.SESSION_ID_EMPTY.__str__)
-    
 
+    def default(self, obj):
+        if isinstance(obj, datetime.datetime):
+            return obj.isoformat()
+        elif isinstance(obj, datetime.date):
+            return obj.isoformat()
+        elif isinstance(obj, datetime.time):
+            return obj.isoformat()
+        elif hasattr(obj, '__dict__'):
+            return obj.__dict__
+        return super().default(obj)
 
 
-def get_system_prompt() -> str:
-    """
-        获取系统提示语
-    """
-    system_prompt = config_handler.get("system", "SYSTEM_PROMPT")
-    server_logger.info(f"获取系统提示语: {system_prompt}")
-    return str(system_prompt)
+class ToolUtils:
+    """工具类集合"""
 
+    @staticmethod
+    def generate_uuid() -> str:
+        """生成UUID字符串"""
+        return str(uuid.uuid4())
 
+    @staticmethod
+    def generate_trace_id() -> str:
+        """生成追踪ID"""
+        return str(uuid.uuid4()).replace('-', '')[:16]
 
+    @staticmethod
+    def hash_string(text: str, algorithm: str = 'md5') -> str:
+        """
+        计算字符串哈希值
 
+        Args:
+            text: 要哈希的文本
+            algorithm: 哈希算法 ('md5', 'sha1', 'sha256')
 
+        Returns:
+            哈希值字符串
+        """
+        if algorithm == 'md5':
+            return hashlib.md5(text.encode('utf-8')).hexdigest()
+        elif algorithm == 'sha1':
+            return hashlib.sha1(text.encode('utf-8')).hexdigest()
+        elif algorithm == 'sha256':
+            return hashlib.sha256(text.encode('utf-8')).hexdigest()
+        else:
+            raise ValueError(f"Unsupported algorithm: {algorithm}")
 
-class DateTimeEncoder(json.JSONEncoder):
-    def default(self, obj):
-        if isinstance(obj, datetime):
-            return obj.strftime('%Y-%m-%d %H:%M:%S')
-        elif isinstance(obj, date):  # 添加对 date 类型的支持
-            return obj.strftime('%Y-%m-%d')
-        return super().default(obj)
+    @staticmethod
+    def clean_text(text: str) -> str:
+        """
+        清理文本,移除多余空白字符
+
+        Args:
+            text: 要清理的文本
+
+        Returns:
+            清理后的文本
+        """
+        # 移除多余的空白字符
+        text = re.sub(r'\s+', ' ', text.strip())
+        return text
+
+    @staticmethod
+    def truncate_text(text: str, max_length: int = 100, suffix: str = "...") -> str:
+        """
+        截断文本
+
+        Args:
+            text: 要截断的文本
+            max_length: 最大长度
+            suffix: 截断后缀
+
+        Returns:
+            截断后的文本
+        """
+        if len(text) <= max_length:
+            return text
+        return text[:max_length - len(suffix)] + suffix
+
+    @staticmethod
+    def extract_emails(text: str) -> List[str]:
+        """
+        从文本中提取邮箱地址
+
+        Args:
+            text: 要分析的文本
+
+        Returns:
+            邮箱地址列表
+        """
+        pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
+        return re.findall(pattern, text)
+
+    @staticmethod
+    def extract_phone_numbers(text: str) -> List[str]:
+        """
+        从文本中提取手机号码
+
+        Args:
+            text: 要分析的文本
+
+        Returns:
+            手机号码列表
+        """
+        # 中国大陆手机号码模式
+        pattern = r'1[3-9]\d{9}'
+        return re.findall(pattern, text)
+
+    @staticmethod
+    def format_file_size(size_bytes: int) -> str:
+        """
+        格式化文件大小
+
+        Args:
+            size_bytes: 字节数
+
+        Returns:
+            格式化后的文件大小字符串
+        """
+        if size_bytes == 0:
+            return "0B"
+
+        size_names = ["B", "KB", "MB", "GB", "TB"]
+        i = 0
+        while size_bytes >= 1024 and i < len(size_names) - 1:
+            size_bytes /= 1024.0
+            i += 1
+
+        return f"{size_bytes:.1f}{size_names[i]}"
+
+    @staticmethod
+    def deep_merge_dict(dict1: Dict[str, Any], dict2: Dict[str, Any]) -> Dict[str, Any]:
+        """
+        深度合并字典
+
+        Args:
+            dict1: 第一个字典
+            dict2: 第二个字典
+
+        Returns:
+            合并后的字典
+        """
+        result = dict1.copy()
+
+        for key, value in dict2.items():
+            if key in result and isinstance(result[key], dict) and isinstance(value, dict):
+                result[key] = ToolUtils.deep_merge_dict(result[key], value)
+            else:
+                result[key] = value
+
+        return result
+
+    @staticmethod
+    def safe_get_nested(data: Union[Dict, List], path: str, default: Any = None) -> Any:
+        """
+        安全获取嵌套数据
+
+        Args:
+            data: 数据对象
+            path: 路径,用点号分隔 (例如: 'user.profile.name')
+            default: 默认值
+
+        Returns:
+            获取到的值或默认值
+        """
+        keys = path.split('.')
+        current = data
+
+        try:
+            for key in keys:
+                if isinstance(current, dict):
+                    current = current[key]
+                elif isinstance(current, list):
+                    current = current[int(key)]
+                else:
+                    return default
+            return current
+        except (KeyError, IndexError, TypeError, ValueError):
+            return default
+
+    @staticmethod
+    def chunk_list(lst: List[Any], chunk_size: int) -> List[List[Any]]:
+        """
+        将列表分块
+
+        Args:
+            lst: 要分块的列表
+            chunk_size: 块大小
+
+        Returns:
+            分块后的列表
+        """
+        return [lst[i:i + chunk_size] for i in range(0, len(lst), chunk_size)]
+
+    @staticmethod
+    def flatten_dict(d: Dict[str, Any], parent_key: str = '', sep: str = '.') -> Dict[str, Any]:
+        """
+        扁平化字典
+
+        Args:
+            d: 要扁平化的字典
+            parent_key: 父键名
+            sep: 分隔符
+
+        Returns:
+            扁平化后的字典
+        """
+        items = []
+        for k, v in d.items():
+            new_key = f"{parent_key}{sep}{k}" if parent_key else k
+            if isinstance(v, dict):
+                items.extend(ToolUtils.flatten_dict(v, new_key, sep=sep).items())
+            else:
+                items.append((new_key, v))
+        return dict(items)
+
+
+# 便捷函数
+def generate_uuid() -> str:
+    """生成UUID字符串(便捷函数)"""
+    return ToolUtils.generate_uuid()
+
+def generate_trace_id() -> str:
+    """生成追踪ID(便捷函数)"""
+    return ToolUtils.generate_trace_id()
+
+def clean_text(text: str) -> str:
+    """清理文本(便捷函数)"""
+    return ToolUtils.clean_text(text)
+
+def format_file_size(size_bytes: int) -> str:
+    """格式化文件大小(便捷函数)"""
+    return ToolUtils.format_file_size(size_bytes)
+
+# 导出的类和函数
+__all__ = [
+    "DateTimeEncoder",
+    "ToolUtils",
+    "generate_uuid",
+    "generate_trace_id",
+    "clean_text",
+    "format_file_size"
+]

+ 13 - 6
foundation/utils/yaml_utils.py

@@ -11,15 +11,15 @@
 
 import os
 import yaml
-from foundation.logger.loggering import server_logger
+from foundation.observability.logger.loggering import server_logger
 
 import os
 from dotenv import load_dotenv
 from functools import wraps
 
-from foundation.logger.loggering import server_logger
+from foundation.observability.logger.loggering import server_logger
 from foundation.utils.common import handler_err
-from foundation.base.config import config_handler
+from foundation.infrastructure.config import config_handler
 
 # 获取当前文件的目录
 current_dir = os.path.dirname(__file__)
@@ -44,7 +44,7 @@ def get_system_prompt() -> dict:
             prompt_config = yaml.safe_load(f)
         # 验证必需字段
         #validate_prompt_config(prompt_config, prompt_name)
-        server_logger.info(f"成功加载系统system_prompt配置: {prompt_config["system_prompt"]}")
+        server_logger.info(f"成功加载系统system_prompt配置: {prompt_config['system_prompt']}")
         return prompt_config
         
     except Exception as e:
@@ -89,5 +89,12 @@ def get_intent_prompt() -> dict:
         raise
 
 
-#获取系统提示语
-system_prompt_config = get_system_prompt()
+#获取系统提示语 - 延迟加载
+system_prompt_config = None
+
+def get_system_prompt_config():
+    """获取系统提示语配置(延迟加载)"""
+    global system_prompt_config
+    if system_prompt_config is None:
+        system_prompt_config = get_system_prompt()
+    return system_prompt_config

Fichier diff supprimé car celui-ci est trop grand
+ 10164 - 3412
logs/agent_debug.log.1


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 4799
logs/agent_info.log.1


+ 46 - 9
server/app.py

@@ -1,6 +1,7 @@
 import os
 import sys
 import time
+import redis
 import signal
 import uvicorn
 import datetime
@@ -12,10 +13,13 @@ sys.path.insert(0, BASE_DIR)
 from views import lifespan
 from fastapi import FastAPI, HTTPException
 from fastapi.responses import JSONResponse
+from pydantic import BaseModel
+from typing import Optional, Dict, Any
 from fastapi.middleware.cors import CORSMiddleware
-from foundation.base.config import config_handler
-from foundation.logger.loggering import server_logger
-from foundation.base.celery_app import app as celery_app
+from foundation.infrastructure.config.config import config_handler
+from foundation.infrastructure.cache import RedisConnectionFactory
+from foundation.observability.logger.loggering import server_logger
+from foundation.infrastructure.messaging.celery_app import app as celery_app
 
 # 导入所有路由
 from views.test_views import test_router
@@ -34,8 +38,7 @@ class ServerUtils:
         Returns:
             redis.Redis: Redis连接对象
         """
-        import redis
-        from foundation.base.config import config_handler
+
 
         # 从配置文件获取Redis连接参数
         redis_host = config_handler.get('redis', 'REDIS_HOST', 'localhost')
@@ -66,6 +69,7 @@ class RouteManager:
         self._setup_routes()
         self._setup_exception_handlers()
         self._setup_health_checks()
+        self._setup_api_docs()
 
 
     def _setup_cors(self):
@@ -96,12 +100,12 @@ class RouteManager:
 
     def _setup_health_checks(self):
         """配置健康检查接口"""
-        @self.app.get("/health")
+        @self.app.get("/health" ,tags=["系统状态"])
         async def health_check():
             timestamp = datetime.datetime.now().isoformat()
             return {"status": "healthy", "timestamp": timestamp}
 
-        @self.app.get("/celery/status")
+        @self.app.get("/celery/status", tags=["系统状态"])
         async def get_celery_status():
             """获取Celery Worker状态"""
             # 延迟导入避免循环引用
@@ -112,6 +116,39 @@ class RouteManager:
                 "timestamp": datetime.datetime.now().isoformat()
             }
 
+    def _setup_api_docs(self):
+        """配置Swagger API文档"""
+        # 添加API文档信息接口
+        @self.app.get("/api/docs/info", tags=["系统状态"])
+        async def api_info():
+            """获取API文档信息"""
+            return {
+                "title": "Agent API - 施工方案审查系统",
+                "description": "集成施工方案审查功能的API接口文档",
+                "version": "0.3",
+                "docs_urls": {
+                    "swagger_ui": "/docs",
+                    "redoc": "/redoc",
+                    "openapi_json": "/openapi.json"
+                },
+                "features": [
+                    "自动生成API文档",
+                    "交互式API测试",
+                    "OpenAPI 3.0规范",
+                    "支持多种认证方式"
+                ]
+            }
+
+        @self.app.get("/api/docs/health", tags=["系统状态"])
+        async def docs_health_check():
+            """API文档健康检查"""
+            return {
+                "status": "healthy",
+                "service": "API Documentation",
+                "version": "0.3",
+                "timestamp": datetime.datetime.now().isoformat()
+            }
+
 
 
 class CeleryWorkerManager:
@@ -422,7 +459,7 @@ def cleanup_redis_before_start():
     """启动前清理Redis中的残留Celery任务"""
     try:
         # 使用统一的Redis连接工具函数
-        r = get_redis_connection()
+        r = server_utils.get_redis_connection()
 
         server_logger.info("清理Redis中的残留Celery任务...")
 
@@ -519,7 +556,7 @@ def stop_celery_worker():
     # 立即取消所有任务注册(使用DB0,与启动时保持一致)
     try:
         # 使用统一的Redis连接工具函数
-        r = get_redis_connection()
+        r = server_utils.get_redis_connection()
 
         server_logger.info("停止时清理Redis中的Celery任务...")
 

+ 0 - 10
server/cus_middlewares.py

@@ -1,10 +0,0 @@
-# !/usr/bin/ python
-# -*- coding: utf-8 -*-
-'''
-@Project    : lq-agent-api
-@File       :cus_middlewares.py
-@IDE        :PyCharm
-@Author     :
-@Date       :2025/7/14 09:57
-'''
-

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff