Quellcode durchsuchen

how agent update

liuzhiheng vor 1 Monat
Ursprung
Commit
23506af03b

+ 32 - 4
examples_how/overall_derivation/derivation_main.md

@@ -279,6 +279,16 @@ agent(agent_type="derivation_search", task="执行搜索任务,account_name=xx
     - 若字段值为「无」或某元素(含其扩展节点)均未出现,则 `is_matched=false`。
     - 若字段值为「无」或某元素(含其扩展节点)均未出现,则 `is_matched=false`。
   - **匹配分数阈值判断**:`matched_score >= 0.78` 为完全推导成功,`matched_score < 0.78` 为部分推导成功。
   - **匹配分数阈值判断**:`matched_score >= 0.78` 为完全推导成功,`matched_score < 0.78` 为部分推导成功。
   - 注意:`output` 名称(pattern 元素名称或扩展节点名称)与其匹配到的帖子选题点名称**可能不同**,`output` 始终是元素名称或扩展节点名称,`matched_post_point` 始终是帖子选题点名称。
   - 注意:`output` 名称(pattern 元素名称或扩展节点名称)与其匹配到的帖子选题点名称**可能不同**,`output` 始终是元素名称或扩展节点名称,`matched_post_point` 始终是帖子选题点名称。
+  - **⚠️ 字段提取规则(逐字段映射,禁止混用)**:
+  对于工具返回的每条匹配 `A→B(score)`:
+  | 日志字段 | 取值来源 | 示例 |
+  |---------|---------|------|
+  | 推导路径 `output` | `→` **左边**的名称(pattern 元素名或扩展节点名) | `夸张构图` |
+  | 评估日志 `derivation_output_point` | 与 `output` **完全一致** | `夸张构图` |
+  | 评估日志 `matched_post_point` | `→` **右边**、括号前的名称 | `夸张堆叠` |
+  | 评估日志 `matched_score` | 括号内的数值 | `0.8149` |
+  
+  **禁止**将 `→` 右边的帖子选题点名称填入 `output` 或 `derivation_output_point`。
   - **推导理由(`reason`)要求**:对于扩展匹配,`reason` 中须说明扩展节点与原 pattern 元素的关系(如"夸张构图是构图与布局的子节点")。
   - **推导理由(`reason`)要求**:对于扩展匹配,`reason` 中须说明扩展节点与原 pattern 元素的关系(如"夸张构图是构图与布局的子节点")。
 - **优先级**:优先使用条件概率高、pattern 长度(节点数)大的结果;与已推导选题点重合多的 pattern 更优先(工具已自动排序)。
 - **优先级**:优先使用条件概率高、pattern 长度(节点数)大的结果;与已推导选题点重合多的 pattern 更优先(工具已自动排序)。
 - 模拟样例(基于上方工具返回数据,假设此时 `derived_success_set` 中已包含 `分享`):
 - 模拟样例(基于上方工具返回数据,假设此时 `derived_success_set` 中已包含 `分享`):
@@ -344,6 +354,20 @@ agent(agent_type="derivation_search", task="执行搜索任务,account_name=xx
 ```
 ```
 这违反原子化规则,因为两个pattern的推导彼此独立,去掉任一输入不影响另一个输出。
 这违反原子化规则,因为两个pattern的推导彼此独立,去掉任一输入不影响另一个输出。
 
 
+⚠️ **反例(禁止)——output 误填帖子选题点名称**:
+假设工具返回 `场景植入→场景化产品植入(0.9095)`,以下写法是**错误的**:
+```json
+{
+  "output": ["场景化产品植入"]  // ❌ 这是帖子选题点名称(→右边),不是 pattern 元素
+}
+```
+正确写法:
+```json
+{
+  "output": ["场景植入"]  // ✅ 这是 pattern 元素名称(→左边)
+}
+```
+
 对应评估日志:
 对应评估日志:
 - `derivation_output_point="日常物品"`,`is_matched=true`,`matched_post_point="日常物品"`,`matched_score=1.0`,`matched_reason="匹配分数=1.0"`(完全推导成功)
 - `derivation_output_point="日常物品"`,`is_matched=true`,`matched_post_point="日常物品"`,`matched_score=1.0`,`matched_reason="匹配分数=1.0"`(完全推导成功)
 - `derivation_output_point="标题"`,`is_matched=true`,`matched_post_point="标题"`,`matched_score=1.0`,`matched_reason="匹配分数=1.0"`(完全推导成功)
 - `derivation_output_point="标题"`,`is_matched=true`,`matched_post_point="标题"`,`matched_score=1.0`,`matched_reason="匹配分数=1.0"`(完全推导成功)
@@ -358,11 +382,13 @@ agent(agent_type="derivation_search", task="执行搜索任务,account_name=xx
   - 第一人称视角  条件概率=1.0  所属维度=故事编排  帖子选题点匹配=无
   - 第一人称视角  条件概率=1.0  所属维度=故事编排  帖子选题点匹配=无
   ```
   ```
   - 工具 `find_tree_nodes_by_conditional_ratio` 返回两种节点数据:账号人设树节点 和 平台库人设树节点,优先使用 账号人设树节点,当使用 账号人设树节点 时,`method`=账号人设推导,当使用 平台库人设树节点 时,`method`=平台库人设推导
   - 工具 `find_tree_nodes_by_conditional_ratio` 返回两种节点数据:账号人设树节点 和 平台库人设树节点,优先使用 账号人设树节点,当使用 账号人设树节点 时,`method`=账号人设推导,当使用 平台库人设树节点 时,`method`=平台库人设推导
-  - **推导路径的 `output`**:填写工具返回的**人设树节点名称**(如 `趣味道具`)。
+  - 返回的人设树节点所属维度,均为当前已推导出的维度,需要在推导理由 `reason` 中说明。
+  - **推导路径的 `tree_nodes`, `output`**:填写工具返回的**人设树节点名称**(如 `趣味道具`)。
+  - **推导路径的 `derived_nodes`**:填写工具返回的人设树节点名称所属维度对应的匹配点(**注意**:这里的维度匹配点来源最新的 `round_pattern_dimension_analyze`返回的维度分析数据,且匹配点必须是已推导的帖子选题点,没有或者不符合要求可以不填写)
   - **匹配判断**:读取「帖子选题点匹配」字段——若有值(如 `夸张道具(0.7831)`),则 `is_matched=true`,评估日志中 `matched_post_point` 填写括号前的帖子选题点名称(如 `夸张道具`),`matched_score` 填写匹配分数数值(如 `0.7831`),`matched_reason` 填写匹配分数描述(如 `匹配分数=0.7831`);若字段值为「无」,则 `is_matched=false`。
   - **匹配判断**:读取「帖子选题点匹配」字段——若有值(如 `夸张道具(0.7831)`),则 `is_matched=true`,评估日志中 `matched_post_point` 填写括号前的帖子选题点名称(如 `夸张道具`),`matched_score` 填写匹配分数数值(如 `0.7831`),`matched_reason` 填写匹配分数描述(如 `匹配分数=0.7831`);若字段值为「无」,则 `is_matched=false`。
   - **匹配分数阈值判断**:`matched_score >= 0.78` 为完全推导成功,`matched_score < 0.78` 为部分推导成功。例如 `趣味道具→夸张道具(0.7831)` 中 `matched_score=0.7831 >= 0.78`,属于完全推导成功。
   - **匹配分数阈值判断**:`matched_score >= 0.78` 为完全推导成功,`matched_score < 0.78` 为部分推导成功。例如 `趣味道具→夸张道具(0.7831)` 中 `matched_score=0.7831 >= 0.78`,属于完全推导成功。
   - ⚠️ **关键区分**:`output` 是人设树节点名称(`趣味道具`),`matched_post_point` 是帖子中真实的选题点名称(`夸张道具`)——两者**可以不同**,加入 `derived_success_set` 或 `partial_derived_set` 的是 `matched_post_point`,而非 `output`。
   - ⚠️ **关键区分**:`output` 是人设树节点名称(`趣味道具`),`matched_post_point` 是帖子中真实的选题点名称(`夸张道具`)——两者**可以不同**,加入 `derived_success_set` 或 `partial_derived_set` 的是 `matched_post_point`,而非 `output`。
-  - 推导理由须引用条件概率等数据,**禁止**使用大模型自身世界知识联想。
+  - 推导理由须引用 已推导维度、条件概率 等数据,**禁止**使用大模型自身世界知识联想。
 - 模拟样例(基于上方工具返回数据):
 - 模拟样例(基于上方工具返回数据):
 ```json
 ```json
 [
 [
@@ -374,7 +400,7 @@ agent(agent_type="derivation_search", task="执行搜索任务,account_name=xx
                 "趣味道具"
                 "趣味道具"
             ],
             ],
             "patterns": [],
             "patterns": [],
-            "derived_nodes": []
+            "derived_nodes": ["创意道具"]
         },
         },
         "output": [
         "output": [
             "趣味道具"
             "趣味道具"
@@ -389,7 +415,8 @@ agent(agent_type="derivation_search", task="执行搜索任务,account_name=xx
             "tree_nodes": [
             "tree_nodes": [
                 "第一人称视角"
                 "第一人称视角"
             ],
             ],
-            "patterns": []
+            "patterns": [],
+            "derived_nodes": ["拍摄视角"]
         },
         },
         "output": [
         "output": [
             "第一人称视角"
             "第一人称视角"
@@ -709,6 +736,7 @@ agent(agent_type="derivation_search", task="执行搜索任务,account_name=xx
 7. 多路径择优校验:同一 `matched_post_point` 在同一轮评估日志中不应出现多条记录,只保留 `matched_score` 最高的一条
 7. 多路径择优校验:同一 `matched_post_point` 在同一轮评估日志中不应出现多条记录,只保留 `matched_score` 最高的一条
 8. `derived_success_count` 只统计 `matched_score >= 0.78` 的完全推导成功选题点,不包含部分推导成功的选题点
 8. `derived_success_count` 只统计 `matched_score >= 0.78` 的完全推导成功选题点,不包含部分推导成功的选题点
 9. `partial_derived_count` 统计 `matched_score < 0.78` 的部分推导成功选题点
 9. `partial_derived_count` 统计 `matched_score < 0.78` 的部分推导成功选题点
+10. output/derivation_output_point 校验:推导日志中每条路径的 `output` 值必须是工具返回的节点名称或 pattern 元素名称,不得是帖子选题点名称;评估日志中 `derivation_output_point` 必须与对应路径 `output` 中的值逐字一致。若使用方法二(pattern 复用),`output` 中每个值必须是该 pattern 的元素名称(直接匹配)或扩展节点名称(扩展匹配),不得是 `matched_post_point` 的值。
 
 
 $user$
 $user$
 请开始执行 account_name={account_name},帖子ID={帖子ID},log_id={log_id} 的选题点整体推导任务。所有路径均相对于项目根目录。帖子的选题点数量={post_point_count}
 请开始执行 account_name={account_name},帖子ID={帖子ID},log_id={log_id} 的选题点整体推导任务。所有路径均相对于项目根目录。帖子的选题点数量={post_point_count}

+ 5 - 3
examples_how/overall_derivation/generate_visualize_data.py

@@ -580,11 +580,13 @@ def build_visualize_edges(
 
 
             output_nodes = []
             output_nodes = []
             reasons_list = []
             reasons_list = []
-            derivation_points_list = []
+            compare_detail_list = []
             for mp, reason, score, is_fully, out_item in output_names_this_edge:
             for mp, reason, score, is_fully, out_item in output_names_this_edge:
                 output_nodes.append({"name": mp, "matched_score": score, "is_fully_derived": is_fully})
                 output_nodes.append({"name": mp, "matched_score": score, "is_fully_derived": is_fully})
                 reasons_list.append(reason)
                 reasons_list.append(reason)
-                derivation_points_list.append(out_item)
+                compare_detail_list.append(
+                    f"待比对推导选题点:{out_item} -> 帖子选题点:{mp}  ({score})"
+                )
 
 
             detail = {
             detail = {
                 "reason": dr.get("reason", ""),
                 "reason": dr.get("reason", ""),
@@ -592,7 +594,7 @@ def build_visualize_edges(
             }
             }
             if any(reasons_list):
             if any(reasons_list):
                 detail["匹配理由"] = reasons_list
                 detail["匹配理由"] = reasons_list
-            detail["待比对的推导选题点"] = derivation_points_list
+            detail["比对详情"] = compare_detail_list
             if dr.get("tools"):
             if dr.get("tools"):
                 detail["tools"] = dr["tools"]
                 detail["tools"] = dr["tools"]
             edge_list.append({
             edge_list.append({

+ 1 - 1
examples_how/overall_derivation/overall_derivation_agent_run.py

@@ -550,4 +550,4 @@ async def main(account_name, post_id):
 if __name__ == "__main__":
 if __name__ == "__main__":
     # anthropic/claude-sonnet-4.6
     # anthropic/claude-sonnet-4.6
     # google/gemini-3-flash-preview
     # google/gemini-3-flash-preview
-    asyncio.run(main(account_name="阿里多多酱", post_id="69002ba70000000007008bcc"))
+    asyncio.run(main(account_name="阿里多多酱", post_id="6915dfc400000000070224d9"))

+ 4 - 4
examples_how/overall_derivation/tools/find_tree_node.py

@@ -762,7 +762,7 @@ def main() -> None:
 
 
     account_name = "阿里多多酱"
     account_name = "阿里多多酱"
     post_id = "6915dfc400000000070224d9"
     post_id = "6915dfc400000000070224d9"
-    log_id = "20260320160445"
+    log_id = "20260322135142"
     round = 4
     round = 4
     # derived_items = [
     # derived_items = [
     #     {"topic": "分享", "source_node": "分享"},
     #     {"topic": "分享", "source_node": "分享"},
@@ -792,9 +792,9 @@ def main() -> None:
     # 3)有 agent 时通过 tool 接口再跑一遍(含帖子选题点匹配)
     # 3)有 agent 时通过 tool 接口再跑一遍(含帖子选题点匹配)
     if ToolResult is not None:
     if ToolResult is not None:
         async def run_tools():
         async def run_tools():
-            # r1 = await find_tree_constant_nodes(account_name, post_id=post_id)
-            # print("--- find_tree_constant_nodes ---")
-            # print(r1.output[:2000] + "..." if len(r1.output) > 2000 else r1.output)
+            r1 = await find_tree_constant_nodes(account_name, post_id=post_id)
+            print("--- find_tree_constant_nodes ---")
+            print(r1.output[:2000] + "..." if len(r1.output) > 2000 else r1.output)
             r2 = await find_tree_nodes_by_conditional_ratio(
             r2 = await find_tree_nodes_by_conditional_ratio(
                 account_name,
                 account_name,
                 post_id=post_id,
                 post_id=post_id,

+ 1 - 3
examples_how/overall_derivation/visualize_paths.py

@@ -1,7 +1,5 @@
 import json
 import json
-import math
 import os
 import os
-import sys
 from datetime import datetime
 from datetime import datetime
 from pathlib import Path
 from pathlib import Path
 from typing import Dict, List, Optional
 from typing import Dict, List, Optional
@@ -143,7 +141,7 @@ def generate_all_in_one_visualization(
         .controls input:focus {{ border-color: #3b82f6; outline: none; }}
         .controls input:focus {{ border-color: #3b82f6; outline: none; }}
         .controls select {{
         .controls select {{
             padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 6px;
             padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 6px;
-            font-size: 14px; width: 200px; transition: border 0.2s;
+            font-size: 13px; width: 320px; transition: border 0.2s;
         }}
         }}
         .controls select:focus {{ border-color: #3b82f6; outline: none; }}
         .controls select:focus {{ border-color: #3b82f6; outline: none; }}
         .controls button {{
         .controls button {{