fix: 修复日报 AI 摘要崩溃('str' object has no attribute 'model')
- _llm_summarize 内 3 处 _llm_call 调用仍传 model 字符串, 与 _llm_call(config: LLMConfig) 新签名不匹配,生产日报 AI 摘要必崩 - 统一改为传 config 对象;删除不再使用的 model 局部变量 - 新增回归测试:单块/多分块 _llm_summarize → _llm_call 全链路(传 config)
This commit is contained in:
@@ -556,11 +556,10 @@ def _llm_summarize(client, config: LLMConfig, lines: list[str], day_str: str) ->
|
|||||||
|
|
||||||
config 为 llm.client.LLMConfig(daily_report 场景),提供 model / temperature。
|
config 为 llm.client.LLMConfig(daily_report 场景),提供 model / temperature。
|
||||||
"""
|
"""
|
||||||
model = config.model
|
|
||||||
chunks = _split_lines_into_chunks(lines)
|
chunks = _split_lines_into_chunks(lines)
|
||||||
|
|
||||||
if len(chunks) == 1:
|
if len(chunks) == 1:
|
||||||
return _llm_call(client, model, _build_prompt(chunks[0], day_str))
|
return _llm_call(client, config, _build_prompt(chunks[0], day_str))
|
||||||
|
|
||||||
# 多块:每块独立总结
|
# 多块:每块独立总结
|
||||||
partials: list[str] = []
|
partials: list[str] = []
|
||||||
@@ -570,7 +569,7 @@ def _llm_summarize(client, config: LLMConfig, lines: list[str], day_str: str) ->
|
|||||||
{chr(10).join(chunk)}
|
{chr(10).join(chunk)}
|
||||||
|
|
||||||
直接输出要点列表:"""
|
直接输出要点列表:"""
|
||||||
result = _llm_call(client, model, prompt, max_tokens=800)
|
result = _llm_call(client, config, prompt, max_tokens=800)
|
||||||
if result:
|
if result:
|
||||||
partials.append(result)
|
partials.append(result)
|
||||||
logger.info("AI 摘要: 分块 {}/{} 完成 ({} 字)", i, len(chunks), len(result))
|
logger.info("AI 摘要: 分块 {}/{} 完成 ({} 字)", i, len(chunks), len(result))
|
||||||
@@ -596,7 +595,7 @@ def _llm_summarize(client, config: LLMConfig, lines: list[str], day_str: str) ->
|
|||||||
6. 总字数 500 字以内
|
6. 总字数 500 字以内
|
||||||
|
|
||||||
直接输出要点列表:"""
|
直接输出要点列表:"""
|
||||||
return _llm_call(client, model, merge_prompt, max_tokens=1500)
|
return _llm_call(client, config, merge_prompt, max_tokens=1500)
|
||||||
|
|
||||||
|
|
||||||
def _build_prompt(lines: list[str], day_str: str) -> str:
|
def _build_prompt(lines: list[str], day_str: str) -> str:
|
||||||
|
|||||||
@@ -148,6 +148,28 @@ class TestLlmCallRetry:
|
|||||||
rep._llm_call(client, self._cfg(), "p")
|
rep._llm_call(client, self._cfg(), "p")
|
||||||
assert n["count"] == 2 # 重试 2 次后放弃
|
assert n["count"] == 2 # 重试 2 次后放弃
|
||||||
|
|
||||||
|
def test_llm_summarize_single_chunk_passes_config(self) -> None:
|
||||||
|
"""_llm_summarize → _llm_call 全链路:必须传 LLMConfig 而非 model 字符串。
|
||||||
|
|
||||||
|
回归保护:生产日报曾因 _llm_call 收到 str 报
|
||||||
|
'str' object has no attribute 'model'。
|
||||||
|
"""
|
||||||
|
from scheduler.reporter import _llm_summarize
|
||||||
|
client, n = self._fake_client(0)
|
||||||
|
out = _llm_summarize(client, self._cfg(), ["- 新闻A", "- 新闻B"], "20260812")
|
||||||
|
assert out == "今日要点摘要"
|
||||||
|
assert n["count"] == 1
|
||||||
|
|
||||||
|
def test_llm_summarize_multi_chunk_passes_config(self) -> None:
|
||||||
|
"""多分块场景:每块 + 合并各调用一次 _llm_call,均传 config。"""
|
||||||
|
from scheduler.reporter import _llm_summarize
|
||||||
|
client, n = self._fake_client(0)
|
||||||
|
# 两条长行保证触发分块
|
||||||
|
lines = ["- " + "长新闻内容" * 300, "- " + "长新闻内容" * 300]
|
||||||
|
out = _llm_summarize(client, self._cfg(), lines, "20260812")
|
||||||
|
assert out == "今日要点摘要"
|
||||||
|
assert n["count"] == 3 # 2 块 + 1 次合并
|
||||||
|
|
||||||
|
|
||||||
class TestCollectXwlb:
|
class TestCollectXwlb:
|
||||||
"""_collect_xwlb 取数逻辑:应查询日报前一日(已播出的联播),并跳过内容提要。"""
|
"""_collect_xwlb 取数逻辑:应查询日报前一日(已播出的联播),并跳过内容提要。"""
|
||||||
|
|||||||
Reference in New Issue
Block a user