docs: tighten strategy ai generation prompt

This commit is contained in:
boris
2026-04-24 07:27:32 -07:00
parent 184074dcfe
commit 8fe2fdec04

View File

@@ -481,6 +481,8 @@ pub fn build_generation_prompt(
) -> String {
let mut prompt = String::new();
prompt.push_str("你是 OmniQuant 平台策略脚本生成器。必须输出可运行的平台策略脚本,不要输出 Python 或非平台语法。\n");
prompt.push_str("输出格式硬约束:回复第一行必须是 strategy(\"...\")、let、fn、const 或 //;回复中不得包含 Markdown、解释、思考过程、手册复述、JSON 包装或自然语言总结。\n");
prompt.push_str("长度硬约束:策略代码目标 80 行以内,只保留必要 let/fn/strategy 块;不要复制下面的手册片段、历史策略全文或字段清单。\n");
prompt.push_str("必须遵守以下约束:\n");
prompt.push_str("- 只输出平台策略代码。\n");
prompt.push_str("- 不要输出解释文本。\n");
@@ -489,6 +491,9 @@ pub fn build_generation_prompt(
prompt.push_str("- 优先使用数据库已存在字段和 factors[...]。\n\n");
prompt.push_str("- 生成的代码必须能转换为 strategy_spec 并提交 POST /v1/backtests。\n");
prompt.push_str("- 不要使用手册未列出的字段、函数或外部平台 API 名称。\n\n");
prompt.push_str("只允许使用这些可编译语句market、benchmark、signal、rebalance.every_days(...).at([...])、selection.limit、selection.market_cap_band、filter.stock_ma、filter.stock_expr、ordering.rank_by、ordering.rank_expr、allocation.buy_scale、risk.stop_loss、risk.take_profit、risk.index_exposure、execution.matching_type、execution.slippage、universe.exclude。禁止输出 filter(...)、rank(...)、select.top(...)、weight.equal()、sell_rule(...)、backtest(...)、risk.max_position(...) 这类未支持伪语法。\n");
prompt.push_str("参数形态必须严格selection.market_cap_band 必须写 field=\"float_market_cap\", lower=..., upper=...risk.index_exposure 只能传一个数值表达式,例如 ((signal_close < signal_ma20) ? 0.35 : 1.0)execution.matching_type 只能取 next_tick_last、next_tick_best_own、next_tick_best_counterparty、counterparty_offer、vwap、current_bar_close、next_bar_open、open_auctionexecution.slippage 必须写 execution.slippage(\"none\") 或 execution.slippage(\"price_ratio\", 0.001)。\n");
prompt.push_str("可参考但不要照抄的最小模板:\n```txt\nstrategy(\"cn_a_smallcap_factor_rotation\") {\nmarket(\"CN_A\")\nbenchmark(\"000852.SH\")\nsignal(\"000001.SH\")\nrebalance.every_days(5).at([\"10:18\"])\nselection.limit(28)\nselection.market_cap_band(field=\"float_market_cap\", lower=1500000000, upper=25000000000)\nfilter.stock_expr(listed_days >= 120 && is_st == 0 && paused == 0 && close > 3 && close < 60 && ma5 > ma20 && rolling_mean(\"volume\", 5) < rolling_mean(\"volume\", 60) && at_upper_limit == false && at_lower_limit == false)\nordering.rank_expr(safe_div(1.0, max(float_market_cap, 1.0), 0.0) * 0.55 + effective_turnover_ratio * 0.25 + safe_div(close, max(ma20, 0.01), 0.0) * 0.20, \"desc\")\nallocation.buy_scale(1.0)\nrisk.index_exposure((signal_close < signal_ma20) ? 0.35 : 1.0)\nrisk.stop_loss(holding_return < -0.08)\nrisk.take_profit(holding_return > 0.16)\nexecution.slippage(\"price_ratio\", 0.001)\n}\n```\n\n");
prompt.push_str("用户目标:\n");
prompt.push_str(&format!("- {}\n", request.user_goal));
if !request.constraints.is_empty() {
@@ -501,7 +506,7 @@ pub fn build_generation_prompt(
"\n固定运行条件market={}, benchmark={}, signal={}\n\n",
request.market, request.benchmark_symbol, request.signal_symbol
));
prompt.push_str("详细手册如下:\n\n");
prompt.push_str("面手册只用于理解语法和字段,不允许原文复述到答案中\n\n");
prompt.push_str(manual_markdown);
prompt
}
@@ -512,6 +517,8 @@ pub fn build_optimization_prompt(
) -> String {
let mut prompt = String::new();
prompt.push_str("你是 OmniQuant 平台策略脚本优化器。必须输出完整、可运行的平台策略脚本,不要输出解释文本。\n");
prompt.push_str("输出格式硬约束:回复第一行必须是 strategy(\"...\")、let、fn、const 或 //;回复中不得包含 Markdown、解释、思考过程、手册复述、JSON 包装或自然语言总结。\n");
prompt.push_str("长度硬约束:策略代码目标 80 行以内,只保留必要 let/fn/strategy 块;不要复制下面的手册片段、历史策略全文或字段清单。\n");
prompt.push_str("只修改与优化目标相关的少量参数或过滤条件,保留原策略的市场、基准、信号指数和核心风控;不要引入手册未列出的字段或外部平台 API 名称。\n");
prompt.push_str("优化目标:\n");
prompt.push_str(&format!("- {}\n\n", request.objective));
@@ -530,7 +537,7 @@ pub fn build_optimization_prompt(
&serde_json::to_string_pretty(&request.result_summary).unwrap_or_else(|_| "{}".to_string()),
);
prompt.push_str("\n```\n\n");
prompt.push_str("详细手册如下:\n\n");
prompt.push_str("面手册只用于理解语法和字段,不允许原文复述到答案中\n\n");
prompt.push_str(manual_markdown);
prompt
}