刘立冬 3 týždňov pred
rodič
commit
8003515c07
2 zmenil súbory, kde vykonal 144 pridanie a 17 odobranie
  1. 76 15
      sug_v6_1_2_115.py
  2. 68 2
      visualization/sug_v6_1_2_8/index.js

+ 76 - 15
sug_v6_1_2_115.py

@@ -6,7 +6,7 @@ import argparse
 from datetime import datetime
 from typing import Literal
 
-from agents import Agent, Runner
+from agents import Agent, Runner, ModelSettings
 from lib.my_trace import set_trace
 from pydantic import BaseModel, Field
 
@@ -407,6 +407,7 @@ motivation_evaluator = Agent[None](
     instructions=motivation_evaluation_instructions,
     model=get_model(MODEL_NAME),
     output_type=MotivationEvaluation,
+    model_settings=ModelSettings(temperature=0.2),
 )
 
 category_evaluator = Agent[None](
@@ -414,6 +415,7 @@ category_evaluator = Agent[None](
     instructions=category_evaluation_instructions,
     model=get_model(MODEL_NAME),
     output_type=CategoryEvaluation,
+    model_settings=ModelSettings(temperature=0.2),
 )
 
 
@@ -446,23 +448,56 @@ word_selection_instructions = """
 3. **扩展范围**:优先选择能扩展搜索范围的词
 4. **多样性**:5个词应该覆盖不同的方面(如:时间、地点、类型、用途等)
 
-## 组合约束
-1. **只能使用seed和word的原始文本**
-2. **不能添加任何连接词**(如"的"、"和"、"与"、"在"等)
-3. **不能添加任何额外的词**
-4. **组合方式**:seed+word 或 word+seed,或者word插入seed中间,选择更符合搜索习惯的顺序
-
-
-## 错误示例
-✗ "川西" + "秋季" → "川西的秋季"(加了"的")
-✗ "川西" + "秋季" → "川西秋季风光"(加了额外的"风光")
-✗ "摄影" + "技巧" → "摄影拍摄技巧"(加了"拍摄")
+## 组合约束(严格执行)
+**CRITICAL: 以下约束必须100%遵守,违反任何一条都是错误**
+
+1. **必须完整保留seed的所有文本内容**
+   - seed的每一个字都必须出现在组合结果中
+   - 禁止删除、省略、替换seed中的任何部分
+   - 即使某些字看起来不重要,也必须保留
+
+2. **必须完整保留word的所有文本内容**
+   - word的每一个字都必须出现在组合结果中
+   - 禁止删除、省略、替换word中的任何部分
+
+3. **禁止添加任何额外内容**
+   - 不能添加连接词(如"的"、"和"、"与"、"在"等)
+   - 不能添加任何其他词或字符
+
+4. **组合方式仅限以下三种**
+   - seed在前:seed的文本 + word的文本(如:制作梗图 + 猫咪 = 制作梗图猫咪)
+   - word在前:word的文本 + seed的文本(如:猫咪 + 制作梗图 = 猫咪制作梗图)
+   - word插入:将word插入seed中间合适位置(如:制作 + 猫咪 + 梗图 = 制作猫咪梗图)
+
+5. **验证检查清单**(在输出前必须自查)
+   ☑ 组合结果包含seed的所有字符?
+   ☑ 组合结果包含word的所有字符?
+   ☑ 组合结果没有额外的字符?
+   ☑ 只使用了三种组合方式之一?
+
+## 正确示例(必须参考)
+✓ seed="制作梗图" + word="猫咪" → "制作梗图猫咪"(seed在前)
+✓ seed="制作梗图" + word="猫咪" → "猫咪制作梗图"(word在前)
+✓ seed="制作梗图" + word="猫咪" → "制作猫咪梗图"(word插入中间)
+✓ seed="川西" + word="秋季" → "川西秋季"(seed在前)
+✓ seed="川西" + word="秋季" → "秋季川西"(word在前)
+✓ seed="摄影" + word="技巧" → "摄影技巧"(seed在前)
+✓ seed="摄影" + word="技巧" → "技巧摄影"(word在前)
+
+## 错误示例(严禁出现)
+✗ seed="制作梗图" + word="猫咪" → "猫咪梗图"(❌ 缺少"制作")
+✗ seed="制作梗图" + word="猫咪" → "梗图猫咪"(❌ 缺少"制作")
+✗ seed="制作梗图" + word="猫咪" → "制作猫咪表情包"(❌ 加了"表情包")
+✗ seed="川西" + word="秋季" → "川西的秋季"(❌ 加了"的")
+✗ seed="川西" + word="秋季" → "川西秋季风光"(❌ 加了"风光")
+✗ seed="摄影" + word="技巧" → "摄影拍摄技巧"(❌ 加了"拍摄")
+✗ seed="摄影" + word="技巧" → "影技巧"(❌ 缺少"摄")
 
 ## 输出要求
 - 最多返回5个组合(如果候选词不足5个,返回所有)
 - 每个组合包含:
   * selected_word: 选择的词(必须在候选词列表中)
-  * combined_query: 组合后的新query(只包含seed和word的原始文本)
+  * combined_query: 组合后的新query(只包含seed和word的原始文本,不多不少
   * reasoning: 选择理由(说明为什么选这个词)
 - overall_reasoning: 整体选择思路(说明这5个词的选择逻辑)
 
@@ -479,6 +514,7 @@ word_selector = Agent[None](
     instructions=word_selection_instructions,
     model=get_model(MODEL_NAME),
     output_type=WordSelectionTop5,
+    model_settings=ModelSettings(temperature=0.2),
 )
 
 
@@ -1011,10 +1047,35 @@ async def run_round(
 
         # 并发评估所有组合的相关度
         async def evaluate_combination(comb: WordCombination) -> dict:
-            score, reason = await evaluate_with_o(comb.combined_query, o, context.evaluation_cache)
+            combined = comb.combined_query
+
+            # 验证:组合结果必须包含完整的seed和word
+            # 检查是否包含seed的所有字符
+            seed_chars_in_combined = all(char in combined for char in seed.text)
+            # 检查是否包含word的所有字符
+            word_chars_in_combined = all(char in combined for char in comb.selected_word)
+
+            if not seed_chars_in_combined or not word_chars_in_combined:
+                print(f"        ⚠️  警告:组合不完整")
+                print(f"          Seed: {seed.text}")
+                print(f"          Word: {comb.selected_word}")
+                print(f"          组合: {combined}")
+                print(f"          包含完整seed? {seed_chars_in_combined}")
+                print(f"          包含完整word? {word_chars_in_combined}")
+                # 返回极低分数,让这个组合不会被选中
+                return {
+                    'word': comb.selected_word,
+                    'query': combined,
+                    'score': -1.0,  # 极低分数
+                    'reason': f"组合不完整:缺少seed或word的部分内容",
+                    'reasoning': comb.reasoning
+                }
+
+            # 正常评估
+            score, reason = await evaluate_with_o(combined, o, context.evaluation_cache)
             return {
                 'word': comb.selected_word,
-                'query': comb.combined_query,
+                'query': combined,
                 'score': score,
                 'reason': reason,
                 'reasoning': comb.reasoning

+ 68 - 2
visualization/sug_v6_1_2_8/index.js

@@ -1172,6 +1172,37 @@ function FlowContent() {
   const [hiddenNodes, setHiddenNodes] = useState(new Set()); // 用户手动隐藏的节点
   const [focusMode, setFocusMode] = useState(false); // 全局聚焦模式,默认关闭
   const [focusedNodeId, setFocusedNodeId] = useState(null); // 单独聚焦的节点ID
+  const [sidebarWidth, setSidebarWidth] = useState(400); // 左侧目录宽度
+  const [isResizing, setIsResizing] = useState(false); // 是否正在拖拽调整宽度
+
+  // 拖拽调整侧边栏宽度的处理逻辑
+  const handleMouseDown = useCallback(() => {
+    setIsResizing(true);
+  }, []);
+
+  useEffect(() => {
+    if (!isResizing) return;
+
+    const handleMouseMove = (e) => {
+      const newWidth = e.clientX;
+      // 限制宽度范围:300px - 700px
+      if (newWidth >= 300 && newWidth <= 700) {
+        setSidebarWidth(newWidth);
+      }
+    };
+
+    const handleMouseUp = () => {
+      setIsResizing(false);
+    };
+
+    document.addEventListener('mousemove', handleMouseMove);
+    document.addEventListener('mouseup', handleMouseUp);
+
+    return () => {
+      document.removeEventListener('mousemove', handleMouseMove);
+      document.removeEventListener('mouseup', handleMouseUp);
+    };
+  }, [isResizing]);
 
   // 获取 React Flow 实例以控制画布
   const { setCenter, fitView } = useReactFlow();
@@ -1908,10 +1939,16 @@ function FlowContent() {
       </div>
 
       {/* 主内容区:目录 + 画布 */}
-      <div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>
+      <div style={{
+        display: 'flex',
+        flex: 1,
+        overflow: 'hidden',
+        cursor: isResizing ? 'col-resize' : 'default',
+        userSelect: isResizing ? 'none' : 'auto',
+      }}>
         {/* 左侧目录树 */}
         <div style={{
-          width: '400px',
+          width: \`\${sidebarWidth}px\`,
           background: 'white',
           borderRight: '1px solid #e5e7eb',
           display: 'flex',
@@ -2013,6 +2050,35 @@ function FlowContent() {
           </div>
         </div>
 
+        {/* 可拖拽的分隔条 */}
+        <div
+          onMouseDown={handleMouseDown}
+          style={{
+            width: '4px',
+            cursor: 'col-resize',
+            background: isResizing ? '#3b82f6' : 'transparent',
+            transition: isResizing ? 'none' : 'background 0.2s',
+            flexShrink: 0,
+            position: 'relative',
+          }}
+          onMouseEnter={(e) => e.currentTarget.style.background = '#e5e7eb'}
+          onMouseLeave={(e) => {
+            if (!isResizing) e.currentTarget.style.background = 'transparent';
+          }}
+        >
+          {/* 拖拽提示线 */}
+          <div style={{
+            position: 'absolute',
+            top: '50%',
+            left: '50%',
+            transform: 'translate(-50%, -50%)',
+            width: '1px',
+            height: '40px',
+            background: '#9ca3af',
+            opacity: isResizing ? 1 : 0.3,
+          }} />
+        </div>
+
         {/* 画布区域 */}
         <div style={{ flex: 1, position: 'relative' }}>