xueyiming пре 1 месец
родитељ
комит
4470c2cd1e

+ 2 - 8
examples/demand/demand_build_agent_tools.py

@@ -13,11 +13,10 @@ def _get_result_base_dir() -> Path:
 
 
 @tool(
-    "存储需求到结果集。 - element_names - score(权重) - reason(原因)- desc(需求描述)"
+    "存储需求到结果集。 - element_names - reason(原因)- desc(需求描述)"
 )
 def create_demand_item(
         element_names: List[str] = None,
-        score: float = 0.0,
         reason: str = None,
         desc: str = None) -> str:
     """
@@ -25,14 +24,12 @@ def create_demand_item(
 
     写入对象包含以下字段:
       - element_names
-      - score(权重)
       - reason(原因)
       - desc(需求描述)
     """
     execution_id: Optional[int] = TopicBuildAgentContext.get_execution_id()
     params: Dict[str, Any] = {
         "execution_id": execution_id,
-        "score": score,
         "element_names": element_names,
         "reason": reason,
         "desc": desc,
@@ -44,7 +41,6 @@ def create_demand_item(
 
     record: Dict[str, Any] = {
         "element_names": element_names,
-        "score": score,
         "reason": reason,
         "desc": desc,
     }
@@ -84,7 +80,7 @@ def create_demand_item(
 
 
 @tool(
-    "批量存储需求到结果集。 - element_names - score(权重) - reason(原因)- desc(需求描述)"
+    "批量存储需求到结果集。 - element_names - reason(原因)- desc(需求描述)"
 )
 def create_demand_items(demand_items: List[Dict[str, Any]] = None) -> str:
     """
@@ -92,7 +88,6 @@ def create_demand_items(demand_items: List[Dict[str, Any]] = None) -> str:
 
     每条记录字段:
       - element_names
-      - score(权重)
       - reason(原因)
       - desc(需求描述)
     """
@@ -131,7 +126,6 @@ def create_demand_items(demand_items: List[Dict[str, Any]] = None) -> str:
             return _log_tool_output("create_demand_items", f"错误: demand_items[{i}] 必须为对象(dict)")
         record = {
             "element_names": di.get("element_names"),
-            "score": di.get("score", 0.0),
             "reason": di.get("reason"),
             "desc": di.get("desc"),
         }

+ 4 - 4
examples/demand/piaoquan_prepare.py

@@ -169,10 +169,10 @@ def piaoquan_prepare(cluster_name):
         return execution_id
 
 if __name__ == '__main__':
-    cluster_name = '历史名人'
-
-    execution_id = run_mining(cluster_name=cluster_name, merge_leve2=cluster_name)
-
+    # cluster_name = '贪污腐败'
+    #
+    # execution_id = run_mining(cluster_name=cluster_name, merge_leve2=cluster_name)
+    prepare(8)
     # execution_id = piaoquan_prepare(cluster_name=cluster_name)
     # print(execution_id)
 

+ 15 - 8
examples/demand/run.py

@@ -8,6 +8,7 @@ import sys
 from datetime import datetime
 from pathlib import Path
 from typing import Optional
+from zoneinfo import ZoneInfo
 
 from dotenv import load_dotenv
 from sqlalchemy import desc, or_
@@ -134,7 +135,12 @@ def _safe_truncate(s: object, max_len: int) -> str:
 
 
 def _load_name_score_map(execution_id: int) -> dict:
-    """读取 data/{execution_id} 下所有 JSON 的 name->score(同名取最高分)。"""
+    """读取 data/{execution_id} 下所有 JSON 的「名字->score」(同名取最高分)。
+
+    兼容两类数据结构:
+    - `*_元素.json`:字段 `name` 表示名字
+    - `*_分类.json`:字段 `category` 表示名字
+    """
     data_dir = Path(__file__).parent / "data" / str(execution_id)
     if not data_dir.exists():
         return {}
@@ -153,7 +159,10 @@ def _load_name_score_map(execution_id: int) -> dict:
         for item in payload:
             if not isinstance(item, dict):
                 continue
+            # 元素数据以 name 为主;分类数据以 category 为主。
             name = item.get("name")
+            if not isinstance(name, str) or not name:
+                name = item.get("category")
             score = item.get("score")
             if isinstance(name, str) and isinstance(score, (int, float)):
                 prev = score_map.get(name)
@@ -259,7 +268,7 @@ def write_demand_items_to_mysql(execution_id: int, merge_level2: str) -> int:
         log(f"[mysql] 需求 JSON 非数组,跳过写入:type={type(items)}")
         return 0
 
-    dt_value = datetime.now().strftime("%Y%m%d")
+    dt_value = datetime.now(ZoneInfo("Asia/Shanghai")).strftime("%Y%m%d")
     score_map = _load_name_score_map(execution_id)
     rows: list[dict] = []
     for di in items:
@@ -269,10 +278,7 @@ def write_demand_items_to_mysql(execution_id: int, merge_level2: str) -> int:
         name = _join_element_names_to_name(di.get("element_names"))
         if not name:
             continue
-
-        score = di.get("score")
-        if score is None or score == 0.0:
-            score = _avg_score_for_joined_name(name, score_map)
+        score = _avg_score_for_joined_name(name, score_map)
         reason = di.get("reason")
         desc_value = di.get("desc")
         suggestion = desc_value
@@ -428,5 +434,6 @@ async def main(
 
 
 if __name__ == "__main__":
-    piaoquan_prepare('历史名人')
-    # asyncio.run(main('小阳看天下', 'changwen'))
+    # asyncio.run(run_once(8, '贪污腐败'))
+    write_demand_items_to_mysql(execution_id=8, merge_level2='贪污腐败')
+

+ 14 - 19
examples/demand/web_api.py

@@ -199,7 +199,7 @@ async def demand_start(req: DemandStartRequest):
 
 @app.on_event("startup")
 async def _start_demand_scheduler() -> None:
-    """启动定时任务(cron 触发,2:00-24:00 每 30 分钟)。"""
+    """启动定时任务(北京时间:2:00–22:30 每 30 分钟,不含 23 点与 0 点)。"""
     global _demand_scheduler
     if not DEMAND_SCHEDULER_ENABLED:
         return
@@ -212,24 +212,19 @@ async def _start_demand_scheduler() -> None:
         return
 
     scheduler = AsyncIOScheduler(timezone=BEIJING_TZ)
-    # 02:00 - 23:30:每 30 分钟一次
-    scheduler.add_job(
-        func=_demand_scheduler_job,
-        trigger=CronTrigger(hour=f"{DEMAND_SCHEDULER_START_HOUR}-23", minute="0,30", timezone=BEIJING_TZ),
-        id="demand_scheduler_job_main",
-        replace_existing=True,
-        max_instances=1,
-        coalesce=True,
-    )
-    # 24:00(即下一天 00:00):每天一次
-    scheduler.add_job(
-        func=_demand_scheduler_job,
-        trigger=CronTrigger(hour="0", minute="0", timezone=BEIJING_TZ),
-        id="demand_scheduler_job_midnight",
-        replace_existing=True,
-        max_instances=1,
-        coalesce=True,
-    )
+    start_h = DEMAND_SCHEDULER_START_HOUR
+    # DEMAND_SCHEDULER_START_HOUR–22:每 30 分钟(默认 2:00–22:30,不含 23 点)
+    if start_h > 22:
+        print(f"[scheduler] DEMAND_SCHEDULER_START_HOUR={start_h} > 22,无法注册 cron,跳过定时任务")
+    else:
+        scheduler.add_job(
+            func=_demand_scheduler_job,
+            trigger=CronTrigger(hour=f"{start_h}-22", minute="0,30", timezone=BEIJING_TZ),
+            id="demand_scheduler_job_main",
+            replace_existing=True,
+            max_instances=1,
+            coalesce=True,
+        )
 
     scheduler.start()
     _demand_scheduler = scheduler