From 98e541b98527bcb2d7a6fac00d28adee9d807718 Mon Sep 17 00:00:00 2001 From: xiaowei Date: Sun, 2 Aug 2026 23:59:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20distill=20LLM=20=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E5=88=87=E6=8D=A2=20gemma-4-31b-it=20+=20JSON=20=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因链: 1. gpt-oss-120b 是 reasoning 模型,content=null 答案全在 reasoning 字段, 代码只读 content/reasoning_content(OpenAI 用 reasoning 字段名)→ parse 失败 → 永远降级 keyword 提取 (facts=1 entities=0) 2. skill 记载的 m3/m2.7/mistral-large 均已 EOL 或渠道失效 (2026-07-27 后) 3. gemma-4-31b-it 对 '0.X' 占位符输出 0.0 → prompt 改为明确 0-1 浮点说明 修复: - engine.go: 支持 reasoning 字段 + 剥离 markdown code fence + prompt 评分说明明确化 - zhiyid.service: LLM_MODEL=google/gemma-4-31b-it 验证: LLM entities=2, overall=1.000, facts=3 entities=2, recall 命中 0.765 --- go/internal/distill/engine.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/go/internal/distill/engine.go b/go/internal/distill/engine.go index 861a26a..b867092 100644 --- a/go/internal/distill/engine.go +++ b/go/internal/distill/engine.go @@ -280,7 +280,8 @@ func (e *Engine) callLLM5D(content string) (LLMResponse, error) { 内容: %s -只返回JSON: {"decisions": ["决定1", "决定2"], "conclusions": ["结论1"], "actions_taken": ["行动1"], "open_questions": ["问题1"], "entities": ["entity1", "entity2"], "is": 0.X, "su": 0.X, "pa": 0.X, "vd": 0.X, "ru": 0.X}`, truncate(content, 1000)) +只返回JSON: {"decisions": ["决定1", "决定2"], "conclusions": ["结论1"], "actions_taken": ["行动1"], "open_questions": ["问题1"], "entities": ["entity1", "entity2"], "is": 0.8, "su": 0.7, "pa": 0.6, "vd": 0.9, "ru": 0.7} +评分说明:is/su/pa/vd/ru 是 0.0 到 1.0 之间的浮点数(越高越好),不要用 0-10 整数。`, truncate(content, 1000)) body := map[string]interface{}{ "model": e.LLMModel, @@ -318,6 +319,8 @@ func (e *Engine) callLLM5D(content string) (LLMResponse, error) { Message struct { Content string `json:"content"` ReasoningContent string `json:"reasoning_content"` + // OpenAI 系 reasoning 模型(gpt-oss 等)用 "reasoning" 字段,不是 "reasoning_content" + Reasoning string `json:"reasoning"` } `json:"message"` } `json:"choices"` } @@ -335,6 +338,15 @@ func (e *Engine) callLLM5D(content string) (LLMResponse, error) { if llmContent == "" { llmContent = result.Choices[0].Message.ReasoningContent } + if llmContent == "" { + llmContent = result.Choices[0].Message.Reasoning + } + // 剥离 markdown code fence(minimax 等模型习惯用 ```json 包裹) + llmContent = strings.TrimSpace(llmContent) + llmContent = strings.TrimPrefix(llmContent, "```json") + llmContent = strings.TrimPrefix(llmContent, "```") + llmContent = strings.TrimSuffix(llmContent, "```") + llmContent = strings.TrimSpace(llmContent) if err := json.Unmarshal([]byte(llmContent), &llmResp); err != nil { log.Printf("[distill] LLM JSON parse error: %v | content=%q", err, truncate(llmContent, 200)) return LLMResponse{}, fmt.Errorf("parse score: %w", err)