From 46635074e83c4b4842f3c7d34dbfd0612162b682 Mon Sep 17 00:00:00 2001 From: shy3130 <415333856@qq.com> Date: Mon, 24 Aug 2026 14:21:55 +0800 Subject: [PATCH] =?UTF-8?q?fix(ai):=20PR=20#193=20=E6=96=B0=E5=A2=9E=20AI?= =?UTF-8?q?=20=E8=B0=83=E7=94=A8=E6=94=BE=E5=BC=80=20max=5Ftokens=20?= =?UTF-8?q?=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 合并 #193 引入的 3 处显式 max_tokens(信号生成 2000/策略代码 3000×2) 重新踩中 0ee3aa8 修过的问题: 推理模型思考 token 计入 max_tokens 预算, 显式限制挤占正文导致 JSON/代码截断。统一改为 None(请求不传该参数, 输出上限交给服务端默认)。四个分析器本就是 None, 标题生成 max_tokens=8 为刻意保留的小任务限制, 均不动。 --- backend/app/api/signals.py | 5 +++-- backend/app/strategy/ai_generator.py | 6 ++++-- backend/tests/test_custom_signals_ai.py | 5 +++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/backend/app/api/signals.py b/backend/app/api/signals.py index 4e6bd58..2da2451 100644 --- a/backend/app/api/signals.py +++ b/backend/app/api/signals.py @@ -145,8 +145,9 @@ async def ai_generate_signal(req: AIGenerateRequest): messages = custom_signals_ai.build_messages(description) try: - # max_tokens 给足 8 个条件的 JSON 余量 (1000 会被复杂描述截断, 导致返回非法 JSON) - text = await generate_ai_text(messages, temperature=0.2, max_tokens=2000) + # max_tokens=None 不传上限: 推理模型思考 token 计入预算, 显式限制 + # 会挤占正文导致 JSON 截断/0 字 (与四个分析器同因, 见 0ee3aa8) + text = await generate_ai_text(messages, temperature=0.2, max_tokens=None) except RuntimeError as e: raise HTTPException(status_code=400, detail=str(e)) from e except Exception as e: diff --git a/backend/app/strategy/ai_generator.py b/backend/app/strategy/ai_generator.py index 0e3dba9..3a1e14d 100644 --- a/backend/app/strategy/ai_generator.py +++ b/backend/app/strategy/ai_generator.py @@ -169,7 +169,8 @@ class AIStrategyGenerator: {"role": "user", "content": user_prompt}, ], temperature=0.3, - max_tokens=3000, + # None = 不传上限: 策略代码较长, 推理模型思考 token 计入预算会截断代码 + max_tokens=None, ): yield chunk @@ -313,7 +314,8 @@ META = {{...}},{entrypoint_requirement}。只输出完整 Python 代码。 {"role": "user", "content": user_prompt}, ], temperature=0.3, - max_tokens=3000, + # None = 不传上限: 策略代码较长, 推理模型思考 token 计入预算会截断代码 + max_tokens=None, ) return self._extract_code_block(content) diff --git a/backend/tests/test_custom_signals_ai.py b/backend/tests/test_custom_signals_ai.py index 730fd4d..6757402 100644 --- a/backend/tests/test_custom_signals_ai.py +++ b/backend/tests/test_custom_signals_ai.py @@ -196,8 +196,9 @@ async def test_ai_generate_endpoint_success(monkeypatch): result = await ai_generate_signal(AIGenerateRequest(description="回踩MA20且放量")) assert result["name"] == "回踩MA20放量" assert len(result["conditions"]) == 2 - # 复杂描述 (多条件) 需要足够 token, 避免 JSON 被截断 - assert captured["max_tokens"] >= 2000 + # 复杂描述 (多条件) 不设输出上限: 推理模型思考 token 计入 max_tokens 预算, + # 显式限制会挤占正文导致 JSON 截断 (对齐分析器的放开策略) + assert captured["max_tokens"] is None @pytest.mark.asyncio