Forráskód Böngészése

重新架构以支持 Ai AIExecutionRecords 集合。基本完成示例入口,待重构 ai_executor 模块,黑盒

mrh 11 hónapja
szülő
commit
48a3a67cd6
3 módosított fájl, 82 hozzáadás és 31 törlés
  1. 35 0
      docs/gpt/ai_execute.md
  2. 22 16
      src/ai/run_service.py
  3. 25 15
      src/models/ai_execution_record.py

+ 35 - 0
docs/gpt/ai_execute.md

@@ -1,4 +1,39 @@
+# 假设使用示例
+在ai_analysis模型的文件中,需要用到 AI 进行推理分析才能存放结果。由于运营分析是一个综合考虑的过程,因此我希望可以使用多个 AI 模型或者多种数据多种方式来推理分析市场营销字段和竞品字段分析,有时候同一段数据也会生成多次分析。比较每次是否有差异。然后把AI分析的结果统一保存到一个单独集合中。虽然目前只有这两个字段需要AI分析保存分析结果,但是未来可能会有更多的字段需要分析。
+
+然后你为我生成了代码在 src\ai\ai_executor 目录,
+
+@/src\ai\ai_executor 
+
+@/src\ai\run_service.py 
+
+@/src\models\ai_execution_record.py 
+
+这是你生成的架构文档:
+
+@/docs\dev\ai_executor_module.md 
+
+我不了解你生成的代码,并且你生成代码不知道是否符合我的预期,我没有检查过。
+
+但是我的设想是 run_service.py  中的示例程序。对我来说模块里面是黑盒, execute_task 应该会调用 llamaindex 的相关方法并且请求获取结果。
+
+当我要分析市场营销信息时,我也会构造不同的 prompt。也可能使用不同的AI模型。未来也不仅仅要分析市场营销,还有很多别的场景可能也要分析。
+我会将每次的结果都保存到 MongoDB 中。
+
+功能概述,我的场景:
+- src\ai\ai_executor 就两个功能,提交数据 - llmaindex 请求大模型 - 返回数据存入 mongodb
+- 用户配置集合中,我获取了prompting,以作为不同提示词模板来看看AI分析结果有何改进。
+- 目前就需要分析分析市场营销文案、竞品和长尾词推理建议。可能未来会扩展不同的文档模型和字段,用于分析产品评论信息分析、用户需求分析。。。
+- 我需要自己传参决定用什么模型,什么提示词信息,什么上下文数据或格式化的字段,相关数据存储在数据库 Product 集合 和 Userconfig 集合。或者也可以通过外部调用传参的方式决定用什么提示词、用什么数据。
+- 我用 BaseAIExecution 及其子类来代表不同的 AI 任务,同一个任务也会有不同的模型名称,提示词,或者第三方API 智能体,只有这样才能总和对比各个任务执行效果。例如 MarketingContentGeneration 营销文案生成器:
+
+
+ai_executor 模块目前有很多不符合我场景的地方。我并没有检查里面的代码,如果你觉得我 run_service.py 中的示例符合最佳实践架构,你帮我重构 ai_executor 里面的所有代码。如果文件不符合你最佳设计架构,请删除,或者文件名容易误解或者混淆,请重命名。该模块内部的任何文件你都可以删去或完全不保留原有架构。它对我来说是黑盒,我无所谓它具体实现。
+
+需要兼容不同的使用场景,千万不能硬编码,可能涉及到不同的方法、模板、格式化,请善于利用多态、继承、组合等设计模式来优化代码结构。为了确保单一职责,你需要自己决定是否需要新建各个不同的文件来模块化。
+
 
+# 模型定义
 在ai_analysis模型的文件中,需要用到 AI 进行推理分析才能存放结果。由于运营分析是一个综合考虑的过程,因此我希望可以使用多个 AI 模型或者多种数据多种方式来推理分析市场营销字段和竞品字段分析,有时候同一段数据也会生成多次分析。比较每次是否有差异。然后把AI分析的结果统一保存到一个单独集合中。虽然目前只有这两个字段需要AI分析保存分析结果,但是未来可能会有更多的字段需要分析。
 
 然后你为我生成了代码在 src\ai\analysis 目录,

+ 22 - 16
src/ai/run_service.py

@@ -1,12 +1,15 @@
-from src.ai.ai_executor.service import AIExecutorService
 from src.models.product_model import Product
 from src.models.config_model import UserConfig
-from models.ai_execution_record import CompetitorKeywordAnalysis, MarketingContentGeneration
+from src.models.ai_execution_record import (
+    CompetitorKeywordAnalysis, MarketingContentGeneration,LLMConfig,
+    AICompetitorAnalyzeMainKeywordsResult,
+    MarketingInfo,)
 from src.manager.core.db_mongo import BaseMongoManager
 import asyncio
 from utils.logu import get_logger
 from src.models.field_config import FieldConfig,get_field_descriptions
 from dotenv import load_dotenv
+from src.ai.ai_executor.service import AIExecutionService
 load_dotenv()
 logger = get_logger('ai')
 
@@ -18,25 +21,28 @@ async def example_usage():
     # 获取产品及用户配置
     product = await Product.find_one(Product.basic_info.name == "电线保护套")
     user = await UserConfig.find_one(UserConfig.user_name == "test_user")
-    
+    llm_config = LLMConfig(model_name="openai/deepseek-chat")
+    competitor_model = CompetitorKeywordAnalysis(
+        product=product, 
+        executor_config=llm_config,
+        prompting=user.prompting.get("竞品和长尾词分析")
+    )
     # 初始化执行服务
-    service = AIExecutorService(product)
-    competitor_prompting = user.prompting.get("竞品和长尾词分析")
-
+    service = AIExecutionService()
     # 使用单个模型执行任务
-    result = await service.execute_task(
-        result_class=CompetitorKeywordAnalysis,
-        model_name="deepseek-chat",
-        custom_prompt=competitor_prompting
-    )
+    await service.execute_task(competitor_model)
+    # competitor_model.result: AICompetitorAnalyzeMainKeywordsResult
+    logger.info(f"{competitor_model.result}")
     
     marketing_prompting = user.prompting.get("营销文案")
-    # 使用多个模型并行执行任务
-    results = await service.execute_multi_model_task(
-        result_class=MarketingContentGeneration,
-        model_names=["gpt-3.5-turbo", "claude-2"],
-        custom_prompt=marketing_prompting.template
+    marketing_model = MarketingContentGeneration(
+        product=product,
+        executor_config=llm_config,
+        prompting=marketing_prompting, 
     )
+    await service.execute_task(marketing_model)
+    # marketing_model.result: MarketingInfo
+    logger.info(f"{marketing_model.result}")
 
 if __name__ == "__main__":
     asyncio.run(example_usage())

+ 25 - 15
src/models/ai_execution_record.py

@@ -2,31 +2,41 @@ from datetime import datetime
 from beanie import Document, Link
 from pydantic import BaseModel, Field
 from typing import Any, List, Dict, Optional, Union
-from src.models.product_model import Product,AICompetitorAnalyzeMainKeywordsResult,MarketingInfo
+from src.models.product_model import Product,AICompetitorAnalyzeMainKeywordsResult,MarketingInfo,AIPromptConfig
 
 class LLMConfig(BaseModel):
-    executor_type='llm'
-    kwargs: Optional[Dict[str, Any]] = Field(
-        default_factory=None,
+    model_name: str = Field(
+        ...,
+        description="LLM的名称" 
+    )
+    executor_type:str = Field(default='llm',description="执行器类型")
+    keywargs: Optional[Dict[str, Any]] = Field(
+        default=None,
         description="LLM的配置参数" 
     )
     
 class AgentConfig(BaseModel):
-    executor_type='agent'
-    agent_name: str
+    executor_type: str = Field(default='agent', description="执行器类型")
+    agent_name: Optional[str] = Field(
+        default=None,
+        description="Agent的名称" 
+    )
     agent_config: Dict = {}
 
-class SuperPromptMixin:
-    executor_type='super_prompt'
-    api_base_url: str
-    provider_name: str
-    provider_config: Dict = {}
+class SuperPromptMixin(BaseModel):
+    executor_type: str = Field(default='super_prompt', description="执行器类型")
+    api_base_url: Optional[str] = Field(
+        default=None,
+        description="API的base url"
+    )
+    provider_name: Optional[str] = Field(default=None,description="Provider的名称")
+    provider_config: Optional[Dict] = Field(default=None,description="Provider的配置")
 
 
 class BaseAIExecution(Document):
     """AI执行结果基类"""
     product: Optional[Link["Product"]] = None
-    prompt_template: Optional[str] = None
+    prompting: Optional[AIPromptConfig] = None
     input_data: Optional[Dict[str, Any]] = Field(
         default_factory=dict,
         description="完整的输入数据"
@@ -35,7 +45,7 @@ class BaseAIExecution(Document):
         default_factory=dict,
         description="原始的AI输出结果"
     )
-    executor_config: Optional[Dict[str, Union[Any,LLMConfig,Dict]]] = None
+    executor_config: Optional[Union[LLMConfig, AgentConfig, SuperPromptMixin]] = None
     helpful_level: Optional[int] = None
     created_at: datetime = Field(default_factory=datetime.now)
     
@@ -47,7 +57,7 @@ class CompetitorKeywordAnalysis(BaseAIExecution):
     """竞品关键词分析结果"""
     task_type: str = "competitor_analysis"
     result: Optional[AICompetitorAnalyzeMainKeywordsResult] = Field(
-        default_factory=None,
+        default=None,
         description="竞品关键词分析结果"
     )
 
@@ -55,7 +65,7 @@ class MarketingContentGeneration(BaseAIExecution):
     """营销内容生成结果"""
     task_type: str = "marketing_generation"
     result: Optional[MarketingInfo] = Field(
-        default_factory=None,
+        default=None,
         description="生成的营销内容结果"
     )