From d999613f41859e5b2740f08dc3831bba03ea8ae9 Mon Sep 17 00:00:00 2001 From: Wenjie Zhang Date: Wed, 12 Nov 2025 19:53:56 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E5=8F=98=E9=87=8F=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E7=A1=AE=E4=BF=9D=E9=BB=98=E8=AE=A4=E5=80=BC=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在多个文件中更新环境变量的获取方式,使用 `or` 语法简化代码,确保在未设置环境变量时使用默认值。 - 移除 `.env.template` 中与 LightRAG 相关的环境变量配置,简化配置文件。 - 更新 `pyproject.toml` 中的项目描述,提供更清晰的项目定位。 - 在文档中增加对图片上传响应格式的详细说明,提升用户理解。 --- .env.template | 4 ---- docs/latest/advanced/agents-config.md | 18 +++++++++++++++++- docs/latest/intro/knowledge-base.md | 4 ---- docs/latest/intro/model-config.md | 4 ++-- pyproject.toml | 2 +- scripts/rename_milvus_collections.py | 4 ++-- src/agents/common/models.py | 2 +- src/agents/common/toolkits/mysql/tools.py | 4 ++-- src/config/app.py | 4 ++-- src/knowledge/implementations/lightrag.py | 22 +++++++++------------- src/knowledge/implementations/milvus.py | 6 +++--- src/knowledge/utils/kb_utils.py | 4 ++-- src/models/rerank.py | 2 +- src/plugins/mineru_parser.py | 2 +- src/plugins/paddlex_parser.py | 2 +- src/storage/minio/client.py | 6 +++--- src/utils/logging_config.py | 2 +- web/package.json | 2 +- 18 files changed, 49 insertions(+), 45 deletions(-) diff --git a/.env.template b/.env.template index d465398f..21f57570 100644 --- a/.env.template +++ b/.env.template @@ -26,10 +26,6 @@ MYSQL_DATABASE=database_name MYSQL_PORT=3306 MYSQL_CHARSET=utf8mb4 -# region lightrag -LIGHTRAG_LLM_PROVIDER= -LIGHTRAG_LLM_NAME= -# endregion lightrag # region neo4j diff --git a/docs/latest/advanced/agents-config.md b/docs/latest/advanced/agents-config.md index 9228b1b8..26cb5c72 100644 --- a/docs/latest/advanced/agents-config.md +++ b/docs/latest/advanced/agents-config.md @@ -148,4 +148,20 @@ MYSQL_CHARSET=utf8mb4 智能体会自动识别多模态消息并将其传递给支持图片的模型。如果模型不支持图片,会自动忽略图片内容,只处理文本部分。系统会将图片转换为符合模型要求的格式(通常是 base64 编码的 JPEG 或 PNG),确保与主流多模态模型兼容。 -目前仅支持上传单个图片,图片直接以 base64 存储在数据库 +目前仅支持上传单个图片,图片以 base64 编码形式存储在数据库。系统会自动处理图片的格式转换和压缩,并生成缩略图以优化性能。 + +### 图片上传响应格式 + +```json +{ + "success": true, + "image_content": "", + "thumbnail_content": "", + "width": 1024, + "height": 768, + "format": "JPEG", + "mime_type": "image/jpeg" +} +``` + +系统会将图片信息与用户查询一同传递给支持多模态的模型,并自动适配模型要求的格式。 diff --git a/docs/latest/intro/knowledge-base.md b/docs/latest/intro/knowledge-base.md index aa724b2a..8487db73 100644 --- a/docs/latest/intro/knowledge-base.md +++ b/docs/latest/intro/knowledge-base.md @@ -26,10 +26,6 @@ LightRAG 知识库可在知识库详情中可视化,但不支持在侧边栏 在 Neo4j 的检索中可以看到,实际上 LightRAG 的节点和边依然是和知识图谱本身构建在了同一个 Neo4j 数据库中,但是使用了特殊的 tag 做区分。这点在后面介绍知识图谱的时候也会额外说明。 -系统默认使用 `siliconflow` 的 `Qwen/Qwen3-30B-A3B-Instruct-2507` 模型进行图谱构建。可通过环境变量自定义图谱构建模型: - -<<< @/../.env.template#lightrag{bash} - ## 文档管理 diff --git a/docs/latest/intro/model-config.md b/docs/latest/intro/model-config.md index e515a847..568adc0d 100644 --- a/docs/latest/intro/model-config.md +++ b/docs/latest/intro/model-config.md @@ -104,14 +104,14 @@ DEFAULT_CHAT_MODEL_PROVIDERS: dict[str, ChatModelProvider] = { } ``` -### 3. 配置环境变量 +### 2. 配置环境变量 在 `.env` 文件中添加对应的环境变量: ```env CUSTOM_API_KEY_ENV_NAME=your_api_key_here ``` -### 4. 重新部署 +### 3. 重新部署 ```bash docker compose restart api-dev diff --git a/pyproject.toml b/pyproject.toml index 4caf3776..ec4f6338 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "yuxi-know" version = "0.4.0.dev" -description = "Add your description here" +description = "基于大模型的智能知识库与知识图谱智能体开发平台,融合了 RAG 技术与知识图谱技术,基于 LangGraph v1 + Vue.js + FastAPI + LightRAG 架构构建" readme = "README.md" requires-python = ">=3.11" dependencies = [ diff --git a/scripts/rename_milvus_collections.py b/scripts/rename_milvus_collections.py index 8f23f284..c79cd0ea 100644 --- a/scripts/rename_milvus_collections.py +++ b/scripts/rename_milvus_collections.py @@ -19,8 +19,8 @@ def rename_and_resolve_duplicates(): Connects to Milvus, renames collections from 'kb_kb_' to 'kb_', and resolves duplicates by keeping the collection with more rows. """ - milvus_uri = os.getenv("MILVUS_URI", "http://localhost:19530") - milvus_token = os.getenv("MILVUS_TOKEN", "") + milvus_uri = os.getenv("MILVUS_URI") or "http://localhost:19530" + milvus_token = os.getenv("MILVUS_TOKEN") or "" connection_alias = "rename_script" try: diff --git a/src/agents/common/models.py b/src/agents/common/models.py index 2aaeaf0f..a860e34a 100644 --- a/src/agents/common/models.py +++ b/src/agents/common/models.py @@ -22,7 +22,7 @@ def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel: env_var = model_info.env - api_key = os.getenv(env_var, env_var) + api_key = os.getenv(env_var) or env_var base_url = get_docker_safe_url(model_info.base_url) diff --git a/src/agents/common/toolkits/mysql/tools.py b/src/agents/common/toolkits/mysql/tools.py index d41baf23..3a255806 100644 --- a/src/agents/common/toolkits/mysql/tools.py +++ b/src/agents/common/toolkits/mysql/tools.py @@ -30,9 +30,9 @@ def get_connection_manager() -> MySQLConnectionManager: "user": os.getenv("MYSQL_USER"), "password": os.getenv("MYSQL_PASSWORD"), "database": os.getenv("MYSQL_DATABASE"), - "port": int(os.getenv("MYSQL_PORT", "3306")), + "port": int(os.getenv("MYSQL_PORT") or "3306"), "charset": "utf8mb4", - "description": os.getenv("MYSQL_DATABASE_DESCRIPTION", "默认 MySQL 数据库"), + "description": os.getenv("MYSQL_DATABASE_DESCRIPTION") or "默认 MySQL 数据库", } # 验证配置完整性 required_keys = ["host", "user", "password", "database"] diff --git a/src/config/app.py b/src/config/app.py index 78d0d753..7031e7e5 100644 --- a/src/config/app.py +++ b/src/config/app.py @@ -120,7 +120,7 @@ class Config(BaseModel): def _setup_paths(self): """设置配置文件路径""" - self.save_dir = os.getenv("SAVE_DIR", self.save_dir) + self.save_dir = os.getenv("SAVE_DIR") or self.save_dir self._config_file = Path(self.save_dir) / "config" / "base.toml" self._config_file.parent.mkdir(parents=True, exist_ok=True) @@ -169,7 +169,7 @@ class Config(BaseModel): def _handle_environment(self): """处理环境变量和运行时状态""" # 处理模型目录 - self.model_dir = os.environ.get("MODEL_DIR", self.model_dir) + self.model_dir = os.environ.get("MODEL_DIR") or self.model_dir if self.model_dir: if os.path.exists(self.model_dir): logger.debug(f"Model directory ({self.model_dir}) contains: {os.listdir(self.model_dir)}") diff --git a/src/knowledge/implementations/lightrag.py b/src/knowledge/implementations/lightrag.py index 5a5ee54a..9052a422 100644 --- a/src/knowledge/implementations/lightrag.py +++ b/src/knowledge/implementations/lightrag.py @@ -8,15 +8,13 @@ from lightrag.utils import EmbeddingFunc, setup_logger from neo4j import GraphDatabase from pymilvus import connections, utility +from src import config from src.knowledge.base import KnowledgeBase from src.knowledge.indexing import process_file_to_markdown, process_url_to_markdown from src.knowledge.utils.kb_utils import get_embedding_config, prepare_item_metadata from src.utils import hashstr, logger from src.utils.datetime_utils import shanghai_now -LIGHTRAG_LLM_PROVIDER = os.getenv("LIGHTRAG_LLM_PROVIDER", "siliconflow") -LIGHTRAG_LLM_NAME = os.getenv("LIGHTRAG_LLM_NAME", "zai-org/GLM-4.5-Air") - class LightRagKB(KnowledgeBase): """基于 LightRAG 的知识库实现""" @@ -53,8 +51,8 @@ class LightRagKB(KnowledgeBase): """删除数据库,同时清除Milvus和Neo4j中的数据""" # Drop Milvus collection try: - milvus_uri = os.getenv("MILVUS_URI", "http://localhost:19530") - milvus_token = os.getenv("MILVUS_TOKEN", "") + milvus_uri = os.getenv("MILVUS_URI") or "http://localhost:19530" + milvus_token = os.getenv("MILVUS_TOKEN") or "" connection_alias = f"lightrag_{hashstr(db_id, 6)}" connections.connect(alias=connection_alias, uri=milvus_uri, token=milvus_token) @@ -73,9 +71,9 @@ class LightRagKB(KnowledgeBase): logger.error(f"Failed to drop Milvus collection {db_id}: {e}") # Delete Neo4j data - neo4j_uri = os.getenv("NEO4J_URI", "bolt://localhost:7687") - neo4j_username = os.getenv("NEO4J_USERNAME", "neo4j") - neo4j_password = os.getenv("NEO4J_PASSWORD", "0123456789") + neo4j_uri = os.getenv("NEO4J_URI") or "bolt://localhost:7687" + neo4j_username = os.getenv("NEO4J_USERNAME") or "neo4j" + neo4j_password = os.getenv("NEO4J_PASSWORD") or "0123456789" try: driver = GraphDatabase.driver(neo4j_uri, auth=(neo4j_username, neo4j_password)) @@ -118,7 +116,7 @@ class LightRagKB(KnowledgeBase): if isinstance(metadata.get("language"), str) and metadata.get("language"): addon_params.setdefault("language", metadata.get("language")) # 默认语言从环境变量读取,默认 English - addon_params.setdefault("language", os.getenv("SUMMARY_LANGUAGE", "English")) + addon_params.setdefault("language", os.getenv("SUMMARY_LANGUAGE") or "English") # 创建工作目录 working_dir = os.path.join(self.work_dir, db_id) @@ -181,10 +179,8 @@ class LightRagKB(KnowledgeBase): model_spec = f"{llm_info['provider']}/{llm_info['model_name']}" logger.info(f"Using user-selected LLM: {model_spec}") else: - provider = LIGHTRAG_LLM_PROVIDER - model_name = LIGHTRAG_LLM_NAME - model_spec = f"{provider}/{model_name}" - logger.info(f"Using default LLM from environment: {provider}/{model_name}") + model_spec = config.default_model + logger.info(f"Using default LLM from environment: {model_spec}") model = select_model(model_spec=model_spec) diff --git a/src/knowledge/implementations/milvus.py b/src/knowledge/implementations/milvus.py index fc0fed4c..ef63108e 100644 --- a/src/knowledge/implementations/milvus.py +++ b/src/knowledge/implementations/milvus.py @@ -40,9 +40,9 @@ class MilvusKB(KnowledgeBase): # Milvus 配置 # self.milvus_host = kwargs.get('milvus_host', os.getenv('MILVUS_HOST', 'localhost')) # self.milvus_port = kwargs.get('milvus_port', int(os.getenv('MILVUS_PORT', '19530'))) - self.milvus_token = kwargs.get("milvus_token", os.getenv("MILVUS_TOKEN", "")) - self.milvus_uri = kwargs.get("milvus_uri", os.getenv("MILVUS_URI", "http://localhost:19530")) - self.milvus_db = kwargs.get("milvus_db", "yuxi_know") + self.milvus_token = kwargs.get("milvus_token", os.getenv("MILVUS_TOKEN") or "") + self.milvus_uri = kwargs.get("milvus_uri", os.getenv("MILVUS_URI") or "http://localhost:19530") + self.milvus_db = kwargs.get("milvus_db") or "yuxi_know" # 连接名称 self.connection_alias = f"milvus_{hashstr(work_dir, 6)}" diff --git a/src/knowledge/utils/kb_utils.py b/src/knowledge/utils/kb_utils.py index e14c6106..6f561264 100644 --- a/src/knowledge/utils/kb_utils.py +++ b/src/knowledge/utils/kb_utils.py @@ -214,13 +214,13 @@ def get_embedding_config(embed_info: dict) -> dict: if hasattr(embed_info, "name"): # EmbedModelInfo 对象 config_dict["model"] = embed_info.name - config_dict["api_key"] = os.getenv(embed_info.api_key, embed_info.api_key) + config_dict["api_key"] = os.getenv(embed_info.api_key) or embed_info.api_key config_dict["base_url"] = embed_info.base_url config_dict["dimension"] = embed_info.dimension else: # 字典形式 config_dict["model"] = embed_info["name"] - config_dict["api_key"] = os.getenv(embed_info["api_key"], embed_info["api_key"]) + config_dict["api_key"] = os.getenv(embed_info["api_key"]) or embed_info["api_key"] config_dict["base_url"] = embed_info["base_url"] config_dict["dimension"] = embed_info.get("dimension", 1024) else: diff --git a/src/models/rerank.py b/src/models/rerank.py index 7eee93f2..3b42124b 100644 --- a/src/models/rerank.py +++ b/src/models/rerank.py @@ -125,6 +125,6 @@ def get_reranker(model_id, **kwargs): model_info = config.reranker_names[model_id] base_url = model_info.base_url - api_key = os.getenv(model_info.api_key, model_info.api_key) + api_key = os.getenv(model_info.api_key) or model_info.api_key assert api_key, f"{model_info.name} api_key is required" return OnlineReranker(model_name=model_info.name, api_key=api_key, base_url=base_url, **kwargs) diff --git a/src/plugins/mineru_parser.py b/src/plugins/mineru_parser.py index cd142b28..36255963 100644 --- a/src/plugins/mineru_parser.py +++ b/src/plugins/mineru_parser.py @@ -18,7 +18,7 @@ class MinerUParser(BaseDocumentProcessor): """MinerU 文档解析器 - 使用 HTTP API 进行文档理解和解析""" def __init__(self, server_url: str | None = None): - self.server_url = server_url or os.getenv("MINERU_API_URI", "http://localhost:30001") + self.server_url = server_url or os.getenv("MINERU_API_URI") or "http://localhost:30001" self.parse_endpoint = f"{self.server_url}/file_parse" def get_service_name(self) -> str: diff --git a/src/plugins/paddlex_parser.py b/src/plugins/paddlex_parser.py index 8e7c3648..65e3af02 100644 --- a/src/plugins/paddlex_parser.py +++ b/src/plugins/paddlex_parser.py @@ -20,7 +20,7 @@ class PaddleXDocumentParser(BaseDocumentProcessor): """PaddleX 文档解析器 - 使用 PP-StructureV3 进行版面解析""" def __init__(self, server_url: str | None = None): - self.server_url = server_url or os.getenv("PADDLEX_URI", "http://localhost:8080") + self.server_url = server_url or os.getenv("PADDLEX_URI") or "http://localhost:8080" self.base_url = self.server_url.rstrip("/") self.endpoint = f"{self.base_url}/layout-parsing" diff --git a/src/storage/minio/client.py b/src/storage/minio/client.py index 629052da..fbc221c6 100644 --- a/src/storage/minio/client.py +++ b/src/storage/minio/client.py @@ -37,9 +37,9 @@ class MinIOClient: def __init__(self): """初始化 MinIO 客户端""" - self.endpoint = os.getenv("MINIO_URI", "http://milvus-minio:9000") - self.access_key = os.getenv("MINIO_ACCESS_KEY", "minioadmin") - self.secret_key = os.getenv("MINIO_SECRET_KEY", "minioadmin") + self.endpoint = os.getenv("MINIO_URI") or "http://milvus-minio:9000" + self.access_key = os.getenv("MINIO_ACCESS_KEY") or "minioadmin" + self.secret_key = os.getenv("MINIO_SECRET_KEY") or "minioadmin" self._client = None # 设置公开访问端点 diff --git a/src/utils/logging_config.py b/src/utils/logging_config.py index a721b2ba..d525cc61 100644 --- a/src/utils/logging_config.py +++ b/src/utils/logging_config.py @@ -4,7 +4,7 @@ from loguru import logger as loguru_logger from src.utils.datetime_utils import shanghai_now -SAVE_DIR = os.getenv("SAVE_DIR", "saves") +SAVE_DIR = os.getenv("SAVE_DIR") or "saves" DATETIME = shanghai_now().strftime("%Y-%m-%d") LOG_FILE = f"{SAVE_DIR}/logs/yuxi-{DATETIME}.log" diff --git a/web/package.json b/web/package.json index 809d198c..b5c343b7 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "yuxi-know-web", - "version": "0.3.0.web", + "version": "0.4.0.web", "private": true, "scripts": { "dev": "vite",