config.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. # 【启动 S1】各服务先导入本模块,再创建 Config 对象读取配置。
  2. # 导入时执行 load_dotenv;Config.__init__ 中的属性赋值要等 Config() 时才执行。
  3. # 这里只准备参数,不会启动模型服务、MySQL、Milvus 或天气采集程序。
  4. """
  5. 需求:管理SmartBizTrip项目的配置信息,包括大模型、数据库、日志等配置
  6. 思路步骤:
  7. 1. 定义项目根目录路径
  8. 2. 设置环境变量(生产/测试/开发/预生产)
  9. 3. 创建Config类管理所有配置项
  10. 4. 配置大模型参数(API地址、密钥、模型名称)
  11. 5. 配置数据库参数(主机、用户名、密码、数据库名)
  12. 6. 配置日志文件路径
  13. 7. 配置票务查询接口地址
  14. 8. 配置意图映射字典
  15. 9. 实现根据环境获取不同数据库配置的方法
  16. """
  17. import os
  18. from dotenv import load_dotenv
  19. # 【启动 S1.1】从本文件同目录的 .env 加载变量;默认不覆盖进程已有的环境变量。
  20. load_dotenv(os.path.join(os.path.dirname(os.path.abspath(__file__)), '.env'))
  21. # 本文件所在目录的上一级(代码资料包目录);不是 SmartBizTrip 目录本身。
  22. project_root = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
  23. # 生产环境
  24. # env = "prod"
  25. # 测试环境
  26. # 这里保留环境标签示例;当前 Config.__init__ 并没有依据 env 切换配置。
  27. env = "test"
  28. # 开发环境
  29. # env = "dev"
  30. # 预生产环境
  31. # env = "pre_prod"
  32. #定义配置文件
  33. class Config:
  34. def __init__(self):
  35. # 大模型配置
  36. # 【启动 S1.2】os.getenv 优先取环境变量,未设置时才用第二个参数作为默认值。
  37. # 没有默认值的 API Key 可能是 None;后面创建客户端或调用服务时才使用这些参数。
  38. # 调用者:主服务、A2A 服务、MCP 服务和辅助脚本各自创建配置实例。
  39. # 每个实例把当时的环境变量读到 self 属性中;修改 .env 文件不等于已运行进程中的实例会自动更新。
  40. # 下面按模型、数据库、日志、路由、天气、向量检索分组配置,各调用方只使用自己需要的字段。
  41. # base_url 决定模型请求发到哪个兼容接口;api_key 用于认证;model_name 指定模型。
  42. # 这三者要配套;设置模型名本身不会在本地下载或加载模型权重。
  43. self.base_url = os.getenv('DEEPSEEK_BASE_URL', 'https://api.deepseek.com')
  44. self.api_key = os.getenv('DEEPSEEK_API_KEY')
  45. self.model_name = os.getenv('DEEPSEEK_MODEL', 'deepseek-v4-flash')
  46. # 数据库配置
  47. # MySQL 连接需要主机、用户名、密码、数据库名。这里读取参数,不会创建用户、库或表。
  48. self.host = os.getenv('MYSQL_HOST', 'localhost')
  49. self.user = os.getenv('MYSQL_USER', 'smart_yoyage')
  50. self.password = os.getenv('MYSQL_PASSWORD', '')
  51. self.database = 'biztrip_rag'
  52. # 上一行设置代码默认库名,这一行允许 MYSQL_DATABASE 覆盖它;最终使用第二次赋值后的值。
  53. self.database = os.getenv('MYSQL_DATABASE', self.database)
  54. # 日志配置
  55. # 用当前配置文件的位置计算绝对日志路径,避免从不同目录启动时把日志写到不同文件夹。
  56. self.log_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logs', 'app.log')
  57. # # 票务查询的12306接口地址
  58. # self.url_123 = ""
  59. # 路由:意图和对应的Agent的对应关系
  60. # 【主流程 6 的路由表】多个票务意图映射到同一个 TicketAssistant。
  61. # 映射值必须与 ChatService 注册的名称一致;city_service 由对话服务单独处理。
  62. self.intent = {
  63. "weather": "WeatherQueryAssistant",
  64. "flight": "TicketAssistant",
  65. "train": "TicketAssistant",
  66. "event": "TicketAssistant",
  67. "order": "TicketAssistant",
  68. "car_rental": "TripAssistant",
  69. "meeting_package": "TripAssistant",
  70. "insurance": "TripAssistant",
  71. "trip_order": "TripAssistant",
  72. }
  73. # A2A 子助手创建模型时读取这个值;主 ChatService 当前另行写了 temperature=0.1。
  74. self.temperature = 0.1
  75. # 天气数据源配置
  76. # 当前值为 "api",查询时直接调用和风天气。
  77. # MCP 代码中其余值走数据库分支;采集脚本需要另外运行。
  78. self.weather_source = os.getenv("WEATHER_SOURCE", "api")
  79. # 和风天气 API 配置--注意顺序
  80. self.weather_api_key = os.getenv("QWEATHER_API_KEY", "")
  81. # self.weather_base_url = "https://your_qweather_host/v7/weather/3d"
  82. self.weather_api_host = os.getenv("QWEATHER_API_HOST", "your_qweather_host")
  83. # 先确定 weather_api_host,再拼出预报 URL;/3d 选择的是配置中的三天预报接口。
  84. # 日期范围是查询过滤条件,不能凭扩大查询日期自动扩大此接口返回的预报范围。
  85. self.weather_base_url = (f"https://{self.weather_api_host}/v7/weather/3d")
  86. self.weather_timezone = "Asia/Shanghai"
  87. # 天气监控城市列表(城市名 -> 城市代码)
  88. # 采集脚本遍历这个字典:键用于本地存储的城市名称,值用于天气接口的 location 参数。
  89. # 它不是 MCP 直接查询时允许的城市白名单;直接查询会另外通过城市查找接口获取 ID。
  90. self.weather_city_codes = {
  91. "北京": "101010100",
  92. "成都": "101270101"
  93. }
  94. # 天气定时更新调度时间(北京时间)
  95. self.weather_schedule_time = "01:00"
  96. # Milvus 向量数据库配置
  97. self.milvus_host = "localhost"
  98. self.milvus_port = 19530
  99. # 集合名相当于向量库里要检索的那张集合;必须与初始化脚本创建的名称一致。
  100. self.meeting_package_collection = "meeting_packages"
  101. # Qwen Embedding API 配置
  102. self.embedding_url = "https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings"
  103. # 向量模型与聊天模型是两种用途,这里读取独立的 DASHSCOPE_API_KEY,不会复用 DEEPSEEK_API_KEY。
  104. self.embedding_api_key = os.getenv('DASHSCOPE_API_KEY')
  105. # 向量维度需要与 sql/init_meeting_package_rag.py 建表时的 DIMENSION 一致。
  106. self.embedding_dim = 1024
  107. #
  108. # def get_mysql_config(self,env):
  109. # """
  110. # 通过不同的环境获取不同的数据库配置
  111. # :return:
  112. # """
  113. # if env == 'prod':
  114. # # 数据库配置 生产
  115. # self.host = 'localhost'
  116. # self.user = 'root'
  117. # self.password = 'root'
  118. # self.database = 'biztrip_rag'
  119. # elif env == 'dev':
  120. # # 数据库配置 开发
  121. # self.host = 'localhost1'
  122. # self.user = 'root1'
  123. # self.password = 'root1'
  124. # self.database = 'biztrip_rag'
  125. # elif env == 'test':
  126. # # 数据库配置 测试
  127. # self.host = 'localhost2'
  128. # self.user = 'root2'
  129. # self.password = 'root2'
  130. # self.database = 'biztrip_rag'
  131. # else:
  132. # # 数据库配置 预生产
  133. # self.host = 'localhost3'
  134. # self.user = 'root3'
  135. # self.password = 'root3'
  136. # self.database = 'biztrip_rag'
  137. #
  138. # return self.host, self.user, self.password, self.database
  139. # 【独立演示入口】主项目只导入 Config,不运行这个区块。
  140. # 仅打印日志路径,避免输出数据库凭据。
  141. if __name__ == '__main__':
  142. print(Config().log_file)
  143. # ('localhost', 'root', 'root', 'biztrip_rag')
  144. # ('localhost', 'root2', 'root2', 'biztrip_rag')