quantnodes 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (399) hide show
  1. QuantNodes/__init__.py +15 -0
  2. QuantNodes/__main__.py +14 -0
  3. QuantNodes/agent/__init__.py +158 -0
  4. QuantNodes/agent/agents/__init__.py +13 -0
  5. QuantNodes/agent/agents/definition.py +180 -0
  6. QuantNodes/agent/agents/manager.py +73 -0
  7. QuantNodes/agent/config/__init__.py +34 -0
  8. QuantNodes/agent/config/executor.py +958 -0
  9. QuantNodes/agent/config/loader.py +427 -0
  10. QuantNodes/agent/config/templates/bollinger_bands.yaml +84 -0
  11. QuantNodes/agent/config/templates/dual_ma.yaml +72 -0
  12. QuantNodes/agent/config/templates/empty.yaml +56 -0
  13. QuantNodes/agent/config/templates/mean_reversion.yaml +47 -0
  14. QuantNodes/agent/config/templates/mean_reversion_zscore.yaml +90 -0
  15. QuantNodes/agent/config/templates/momentum.yaml +81 -0
  16. QuantNodes/agent/config/templates/momentum_breakout.yaml +84 -0
  17. QuantNodes/agent/config/templates/rsi_strategy.yaml +72 -0
  18. QuantNodes/agent/config/templates/volume_price.yaml +86 -0
  19. QuantNodes/agent/config/types.py +156 -0
  20. QuantNodes/agent/config_mapper.py +293 -0
  21. QuantNodes/agent/core/__init__.py +19 -0
  22. QuantNodes/agent/core/dream.py +47 -0
  23. QuantNodes/agent/core/quant_dream.py +274 -0
  24. QuantNodes/agent/cron_jobs.py +314 -0
  25. QuantNodes/agent/nanobot_bridge.py +242 -0
  26. QuantNodes/agent/permission/__init__.py +30 -0
  27. QuantNodes/agent/permission/defaults.py +36 -0
  28. QuantNodes/agent/permission/evaluate.py +41 -0
  29. QuantNodes/agent/permission/models.py +59 -0
  30. QuantNodes/agent/permission/service.py +133 -0
  31. QuantNodes/agent/providers/__init__.py +11 -0
  32. QuantNodes/agent/providers/base.py +102 -0
  33. QuantNodes/agent/providers/quantnodes.py +610 -0
  34. QuantNodes/agent/providers/rate_limiter.py +326 -0
  35. QuantNodes/agent/providers/registry.py +163 -0
  36. QuantNodes/agent/skills/__init__.py +20 -0
  37. QuantNodes/agent/skills/base.py +118 -0
  38. QuantNodes/agent/skills/bridge.py +73 -0
  39. QuantNodes/agent/skills/factor/__init__.py +14 -0
  40. QuantNodes/agent/skills/factor/correlation.py +99 -0
  41. QuantNodes/agent/skills/factor/group_backtest.py +114 -0
  42. QuantNodes/agent/skills/factor/ic_analysis.py +106 -0
  43. QuantNodes/agent/skills/loader.py +107 -0
  44. QuantNodes/agent/skills/registry.py +105 -0
  45. QuantNodes/agent/skills/strategy/__init__.py +16 -0
  46. QuantNodes/agent/skills/strategy/bollinger.py +86 -0
  47. QuantNodes/agent/skills/strategy/dual_ma.py +82 -0
  48. QuantNodes/agent/skills/strategy/momentum.py +74 -0
  49. QuantNodes/agent/skills/strategy/rsi_reversal.py +99 -0
  50. QuantNodes/agent/skills_quant/__init__.py +14 -0
  51. QuantNodes/agent/skills_quant/backtest-analyze/SKILL.md +42 -0
  52. QuantNodes/agent/skills_quant/config-driven/SKILL.md +72 -0
  53. QuantNodes/agent/skills_quant/factor-research/SKILL.md +40 -0
  54. QuantNodes/agent/skills_quant/quant-dream/SKILL.md +55 -0
  55. QuantNodes/agent/skills_quant/risk-management/SKILL.md +45 -0
  56. QuantNodes/agent/skills_quant/strategy-design/SKILL.md +43 -0
  57. QuantNodes/agent/templates/__init__.py +4 -0
  58. QuantNodes/agent/tools/__init__.py +173 -0
  59. QuantNodes/agent/tools/_workspace.py +51 -0
  60. QuantNodes/agent/tools/alpha_backtest.py +328 -0
  61. QuantNodes/agent/tools/alpha_evaluate.py +493 -0
  62. QuantNodes/agent/tools/backtest.py +226 -0
  63. QuantNodes/agent/tools/base.py +133 -0
  64. QuantNodes/agent/tools/code_search.py +207 -0
  65. QuantNodes/agent/tools/config_backtest.py +401 -0
  66. QuantNodes/agent/tools/context.py +97 -0
  67. QuantNodes/agent/tools/dream_skill.py +77 -0
  68. QuantNodes/agent/tools/echo.py +38 -0
  69. QuantNodes/agent/tools/factor.py +231 -0
  70. QuantNodes/agent/tools/file_ops.py +201 -0
  71. QuantNodes/agent/tools/git_ops.py +190 -0
  72. QuantNodes/agent/tools/operator_lookup.py +218 -0
  73. QuantNodes/agent/tools/output_truncation.py +77 -0
  74. QuantNodes/agent/tools/path_check.py +43 -0
  75. QuantNodes/agent/tools/pipeline.py +62 -0
  76. QuantNodes/agent/tools/registry.py +150 -0
  77. QuantNodes/agent/tools/sandbox.py +62 -0
  78. QuantNodes/agent/tools/shell_safety.py +63 -0
  79. QuantNodes/agent/tools/strategy.py +106 -0
  80. QuantNodes/agent/tools/task.py +171 -0
  81. QuantNodes/agent/tools/web_fetch.py +142 -0
  82. QuantNodes/agent/tools/web_search.py +114 -0
  83. QuantNodes/agent/tools/wiki.py +370 -0
  84. QuantNodes/agent/utils/__init__.py +11 -0
  85. QuantNodes/agent/utils/helpers.py +43 -0
  86. QuantNodes/agent/utils/prompt_templates.py +30 -0
  87. QuantNodes/agent/workflows/__init__.py +20 -0
  88. QuantNodes/agent/workflows/implementations/__init__.py +8 -0
  89. QuantNodes/agent/workflows/implementations/alpha_gpt.py +508 -0
  90. QuantNodes/agent/workflows/implementations/mcts.py +442 -0
  91. QuantNodes/agent/workflows/parsers.py +44 -0
  92. QuantNodes/agent/workflows/registry.py +119 -0
  93. QuantNodes/agent/workflows/step_agent.py +219 -0
  94. QuantNodes/agent/workflows/tool.py +198 -0
  95. QuantNodes/ai/__init__.py +93 -0
  96. QuantNodes/ai/llm/__init__.py +75 -0
  97. QuantNodes/ai/llm/base.py +233 -0
  98. QuantNodes/ai/llm/decorators.py +281 -0
  99. QuantNodes/ai/llm/gateway.py +571 -0
  100. QuantNodes/ai/llm/null.py +76 -0
  101. QuantNodes/ai/llm/openai.py +435 -0
  102. QuantNodes/ai/optimizer.py +405 -0
  103. QuantNodes/ai/prompts/__init__.py +229 -0
  104. QuantNodes/ai/sandbox.py +371 -0
  105. QuantNodes/ai/sandbox_pandas_bridge.py +150 -0
  106. QuantNodes/ai/strategy_gen.py +396 -0
  107. QuantNodes/backtest/__init__.py +64 -0
  108. QuantNodes/backtest/backtest_node.py +188 -0
  109. QuantNodes/backtest/broker_node.py +378 -0
  110. QuantNodes/backtest/config_runner.py +397 -0
  111. QuantNodes/backtest/config_strategy.py +64 -0
  112. QuantNodes/backtest/risk_node.py +360 -0
  113. QuantNodes/backtest/strategy_node.py +268 -0
  114. QuantNodes/cache_node/__init__.py +19 -0
  115. QuantNodes/cache_node/base.py +244 -0
  116. QuantNodes/cache_node/cache_store.py +99 -0
  117. QuantNodes/cache_node/metadata.py +100 -0
  118. QuantNodes/cli/__init__.py +109 -0
  119. QuantNodes/cli/_helpers.py +511 -0
  120. QuantNodes/cli/command.py +110 -0
  121. QuantNodes/cli/commands/__init__.py +69 -0
  122. QuantNodes/cli/commands/agent.py +158 -0
  123. QuantNodes/cli/commands/alpha.py +951 -0
  124. QuantNodes/cli/commands/chat.py +38 -0
  125. QuantNodes/cli/commands/evolve.py +120 -0
  126. QuantNodes/cli/commands/factor.py +569 -0
  127. QuantNodes/cli/commands/init.py +190 -0
  128. QuantNodes/cli/commands/run.py +259 -0
  129. QuantNodes/cli/commands/serve.py +398 -0
  130. QuantNodes/cli/commands/version.py +120 -0
  131. QuantNodes/cli/enhanced.py +146 -0
  132. QuantNodes/conf_node/__init__.py +37 -0
  133. QuantNodes/conf_node/base.py +120 -0
  134. QuantNodes/conf_node/env_config.py +132 -0
  135. QuantNodes/conf_node/ini_config.py +70 -0
  136. QuantNodes/conf_node/json_config.py +69 -0
  137. QuantNodes/conf_node/yaml_config.py +78 -0
  138. QuantNodes/constants.py +17 -0
  139. QuantNodes/core/__init__.py +196 -0
  140. QuantNodes/core/_lookback_helpers.py +49 -0
  141. QuantNodes/core/ast_parser.py +198 -0
  142. QuantNodes/core/base.py +61 -0
  143. QuantNodes/core/cache_manager.py +344 -0
  144. QuantNodes/core/cache_utils.py +150 -0
  145. QuantNodes/core/cond_builder.py +53 -0
  146. QuantNodes/core/config.py +170 -0
  147. QuantNodes/core/constants.py +48 -0
  148. QuantNodes/core/control.py +412 -0
  149. QuantNodes/core/data_preprocessing.py +453 -0
  150. QuantNodes/core/data_source.py +46 -0
  151. QuantNodes/core/events.py +178 -0
  152. QuantNodes/core/evolution/__init__.py +22 -0
  153. QuantNodes/core/evolution/loop.py +583 -0
  154. QuantNodes/core/evolution/operators.py +289 -0
  155. QuantNodes/core/evolution/settings.py +44 -0
  156. QuantNodes/core/expression.py +841 -0
  157. QuantNodes/core/feedback/__init__.py +38 -0
  158. QuantNodes/core/feedback/channels.py +182 -0
  159. QuantNodes/core/feedback/collector.py +91 -0
  160. QuantNodes/core/feedback/dataclass.py +239 -0
  161. QuantNodes/core/feedback/llm_judge.py +138 -0
  162. QuantNodes/core/knowledge/__init__.py +69 -0
  163. QuantNodes/core/knowledge/knowledge_base.py +217 -0
  164. QuantNodes/core/knowledge/lineage_compress.py +196 -0
  165. QuantNodes/core/knowledge/lineage_expand.py +123 -0
  166. QuantNodes/core/knowledge/metrics/__init__.py +43 -0
  167. QuantNodes/core/knowledge/metrics/evaluator.py +176 -0
  168. QuantNodes/core/knowledge/metrics/metrics.py +220 -0
  169. QuantNodes/core/knowledge/rag_prompt.py +196 -0
  170. QuantNodes/core/knowledge/retriever.py +209 -0
  171. QuantNodes/core/lambda_node.py +81 -0
  172. QuantNodes/core/monitoring/__init__.py +22 -0
  173. QuantNodes/core/monitoring/collector.py +292 -0
  174. QuantNodes/core/monitoring/dashboard.py +365 -0
  175. QuantNodes/core/node.py +375 -0
  176. QuantNodes/core/pandas_utils.py +504 -0
  177. QuantNodes/core/parallel/__init__.py +15 -0
  178. QuantNodes/core/parallel/worker.py +140 -0
  179. QuantNodes/core/parallel/worker_process.py +265 -0
  180. QuantNodes/core/path_utils.py +73 -0
  181. QuantNodes/core/pipeline.py +328 -0
  182. QuantNodes/core/plugin.py +135 -0
  183. QuantNodes/core/quality_gate/__init__.py +32 -0
  184. QuantNodes/core/quality_gate/complexity.py +94 -0
  185. QuantNodes/core/quality_gate/consistency.py +26 -0
  186. QuantNodes/core/quality_gate/node.py +97 -0
  187. QuantNodes/core/quality_gate/redundancy.py +51 -0
  188. QuantNodes/core/quality_gate/settings.py +43 -0
  189. QuantNodes/core/quality_gate/zoo.py +98 -0
  190. QuantNodes/core/serializable.py +116 -0
  191. QuantNodes/core/serialization.py +673 -0
  192. QuantNodes/core/tools.py +333 -0
  193. QuantNodes/core/trajectory/__init__.py +25 -0
  194. QuantNodes/core/trajectory/entry.py +116 -0
  195. QuantNodes/core/trajectory/lineage.py +67 -0
  196. QuantNodes/core/trajectory/pool.py +211 -0
  197. QuantNodes/core/trajectory/selector.py +140 -0
  198. QuantNodes/core/visualization/__init__.py +33 -0
  199. QuantNodes/core/visualization/builder.py +233 -0
  200. QuantNodes/core/visualization/gate_breakdown.py +140 -0
  201. QuantNodes/core/visualization/lineage_dag.py +203 -0
  202. QuantNodes/core/visualization/metric_distribution.py +125 -0
  203. QuantNodes/core/visualization/report.py +68 -0
  204. QuantNodes/database_node/__init__.py +69 -0
  205. QuantNodes/database_node/base.py +135 -0
  206. QuantNodes/database_node/clickhouse_node.py +272 -0
  207. QuantNodes/database_node/csv_node.py +83 -0
  208. QuantNodes/database_node/duckdb_node.py +86 -0
  209. QuantNodes/database_node/factory.py +83 -0
  210. QuantNodes/database_node/mysql_node.py +100 -0
  211. QuantNodes/database_node/parquet_node.py +75 -0
  212. QuantNodes/database_node/sqlite_node.py +67 -0
  213. QuantNodes/factor_node/__init__.py +50 -0
  214. QuantNodes/factor_node/factor.py +563 -0
  215. QuantNodes/factor_node/factor_db.py +421 -0
  216. QuantNodes/factor_node/factor_functions/__init__.py +252 -0
  217. QuantNodes/factor_node/factor_functions/_helpers.py +358 -0
  218. QuantNodes/factor_node/factor_functions/_helpers_debug.py +317 -0
  219. QuantNodes/factor_node/factor_functions/composite_ops.py +136 -0
  220. QuantNodes/factor_node/factor_functions/math_ops.py +433 -0
  221. QuantNodes/factor_node/factor_functions/section_ops.py +290 -0
  222. QuantNodes/factor_node/factor_functions/talib_ops.py +1293 -0
  223. QuantNodes/factor_node/factor_functions/time_ops.py +535 -0
  224. QuantNodes/factor_node/factor_operation.py +1115 -0
  225. QuantNodes/factor_node/factor_table.py +1073 -0
  226. QuantNodes/factor_node/quant_nodes_object.py +60 -0
  227. QuantNodes/mcp_server/__init__.py +27 -0
  228. QuantNodes/mcp_server/__main__.py +4 -0
  229. QuantNodes/mcp_server/server.py +272 -0
  230. QuantNodes/methods/__init__.py +28 -0
  231. QuantNodes/methods/pipeline.py +100 -0
  232. QuantNodes/methods/sandbox.py +102 -0
  233. QuantNodes/monitor/__init__.py +27 -0
  234. QuantNodes/monitor/agent_tools/__init__.py +5 -0
  235. QuantNodes/monitor/agent_tools/monitor_tool.py +98 -0
  236. QuantNodes/monitor/agent_tools/schedule_tool.py +98 -0
  237. QuantNodes/monitor/agent_tools/version_tool.py +133 -0
  238. QuantNodes/monitor/monitor/__init__.py +6 -0
  239. QuantNodes/monitor/monitor/alerter.py +60 -0
  240. QuantNodes/monitor/monitor/collector.py +164 -0
  241. QuantNodes/monitor/monitor/dashboard.py +115 -0
  242. QuantNodes/monitor/monitor/drift.py +190 -0
  243. QuantNodes/monitor/scheduler/__init__.py +4 -0
  244. QuantNodes/monitor/scheduler/runner.py +133 -0
  245. QuantNodes/monitor/scheduler/scheduler.py +184 -0
  246. QuantNodes/monitor/storage/__init__.py +16 -0
  247. QuantNodes/monitor/storage/models.py +70 -0
  248. QuantNodes/monitor/storage/repository.py +407 -0
  249. QuantNodes/monitor/version/__init__.py +4 -0
  250. QuantNodes/monitor/version/diff.py +81 -0
  251. QuantNodes/monitor/version/version_manager.py +182 -0
  252. QuantNodes/operator_node/__init__.py +28 -0
  253. QuantNodes/operator_node/base.py +97 -0
  254. QuantNodes/operator_node/query_node.py +129 -0
  255. QuantNodes/operator_node/sql_builder.py +125 -0
  256. QuantNodes/operator_node/sql_utils.py +172 -0
  257. QuantNodes/operator_node/transform.py +130 -0
  258. QuantNodes/operators/__init__.py +90 -0
  259. QuantNodes/operators/_engine.py +108 -0
  260. QuantNodes/operators/composite.py +161 -0
  261. QuantNodes/operators/composite_dag.py +667 -0
  262. QuantNodes/operators/composite_dag_ops.py +343 -0
  263. QuantNodes/operators/composite_dag_pandas_ops.py +382 -0
  264. QuantNodes/operators/custom.py +408 -0
  265. QuantNodes/operators/facade.py +164 -0
  266. QuantNodes/operators/math.py +163 -0
  267. QuantNodes/operators/proxy.py +29 -0
  268. QuantNodes/operators/registry.py +144 -0
  269. QuantNodes/operators/section.py +99 -0
  270. QuantNodes/operators/talib.py +757 -0
  271. QuantNodes/operators/templates.py +95 -0
  272. QuantNodes/operators/time_series.py +136 -0
  273. QuantNodes/prompts/__init__.py +20 -0
  274. QuantNodes/prompts/backtest/__init__.py +12 -0
  275. QuantNodes/prompts/backtest/factor_based.py +86 -0
  276. QuantNodes/prompts/backtest/standard.py +73 -0
  277. QuantNodes/prompts/factor/__init__.py +14 -0
  278. QuantNodes/prompts/factor/correlation.py +77 -0
  279. QuantNodes/prompts/factor/group_backtest.py +86 -0
  280. QuantNodes/prompts/factor/ic_analysis.py +91 -0
  281. QuantNodes/prompts/strategy/__init__.py +18 -0
  282. QuantNodes/prompts/strategy/market_neutral.py +96 -0
  283. QuantNodes/prompts/strategy/mean_reversion.py +107 -0
  284. QuantNodes/prompts/strategy/momentum.py +160 -0
  285. QuantNodes/prompts/strategy/pairs_trading.py +107 -0
  286. QuantNodes/prompts/strategy/trend_following.py +96 -0
  287. QuantNodes/research/README.md +106 -0
  288. QuantNodes/research/__init__.py +154 -0
  289. QuantNodes/research/_legacy_3c/__init__.py +61 -0
  290. QuantNodes/research/_legacy_3c/auto_researcher.py +289 -0
  291. QuantNodes/research/_legacy_3c/factor_evaluator.py +560 -0
  292. QuantNodes/research/_legacy_3c/factor_miner.py +318 -0
  293. QuantNodes/research/_legacy_3c/mcts_search.py +324 -0
  294. QuantNodes/research/factor_test/__init__.py +25 -0
  295. QuantNodes/research/factor_test/config.py +184 -0
  296. QuantNodes/research/factor_test/config_builder.py +276 -0
  297. QuantNodes/research/factor_test/e2e/data_prep.py +163 -0
  298. QuantNodes/research/factor_test/e2e/run_evolution_e2e.py +309 -0
  299. QuantNodes/research/factor_test/evolution_adapter.py +231 -0
  300. QuantNodes/research/factor_test/feedback_wrapper.py +102 -0
  301. QuantNodes/research/factor_test/ifind_db/__init__.py +7 -0
  302. QuantNodes/research/factor_test/ifind_db/fetcher.py +224 -0
  303. QuantNodes/research/factor_test/ifind_db/ifind_database.py +689 -0
  304. QuantNodes/research/factor_test/nodes/__init__.py +1 -0
  305. QuantNodes/research/factor_test/nodes/_base.py +91 -0
  306. QuantNodes/research/factor_test/nodes/adjust_date_node.py +48 -0
  307. QuantNodes/research/factor_test/nodes/configs.py +240 -0
  308. QuantNodes/research/factor_test/nodes/factor_neutralize_node.py +87 -0
  309. QuantNodes/research/factor_test/nodes/factor_preprocess_node.py +222 -0
  310. QuantNodes/research/factor_test/nodes/factor_score_node.py +141 -0
  311. QuantNodes/research/factor_test/nodes/factor_test_report_node.py +153 -0
  312. QuantNodes/research/factor_test/nodes/group_analyzer_node.py +317 -0
  313. QuantNodes/research/factor_test/nodes/ic_analyzer_node.py +112 -0
  314. QuantNodes/research/factor_test/nodes/load_data_node.py +100 -0
  315. QuantNodes/research/factor_test/nodes/long_short_node.py +93 -0
  316. QuantNodes/research/factor_test/nodes/neutralizers.py +222 -0
  317. QuantNodes/research/factor_test/nodes/preprocess_strategies.py +277 -0
  318. QuantNodes/research/factor_test/nodes/risk_correlation_node.py +112 -0
  319. QuantNodes/research/factor_test/nodes/sample_pool_filter_node.py +110 -0
  320. QuantNodes/research/factor_test/nodes/tradability_filter_node.py +92 -0
  321. QuantNodes/research/factor_test/pipeline_runner.py +305 -0
  322. QuantNodes/research/factor_test/pipeline_spec.py +216 -0
  323. QuantNodes/research/factor_test/utils/__init__.py +26 -0
  324. QuantNodes/research/factor_test/utils/constants.py +86 -0
  325. QuantNodes/research/factor_test/utils/data_loader.py +141 -0
  326. QuantNodes/research/factor_test/utils/date_utils.py +232 -0
  327. QuantNodes/research/factor_test/utils/file_loaders.py +150 -0
  328. QuantNodes/research/factor_test/utils/labels.py +37 -0
  329. QuantNodes/research/factor_test/utils/metrics_extractor.py +55 -0
  330. QuantNodes/research/factor_test/utils/performance_metrics.py +175 -0
  331. QuantNodes/research/factor_test/utils/safe_load.py +106 -0
  332. QuantNodes/research/quant_alpha/CHANGELOG.md +80 -0
  333. QuantNodes/research/quant_alpha/README.md +142 -0
  334. QuantNodes/research/quant_alpha/__init__.py +45 -0
  335. QuantNodes/research/quant_alpha/adapters/__init__.py +99 -0
  336. QuantNodes/research/quant_alpha/adapters/calculator.py +503 -0
  337. QuantNodes/research/quant_alpha/adapters/expression.py +387 -0
  338. QuantNodes/research/quant_alpha/alpha101_design/__init__.py +50 -0
  339. QuantNodes/research/quant_alpha/alpha101_design/few_shot_examples.py +243 -0
  340. QuantNodes/research/quant_alpha/alpha101_design/philosophy.py +474 -0
  341. QuantNodes/research/quant_alpha/alpha158_design/__init__.py +63 -0
  342. QuantNodes/research/quant_alpha/alpha158_design/few_shot_examples.py +219 -0
  343. QuantNodes/research/quant_alpha/alpha158_design/philosophy.py +240 -0
  344. QuantNodes/research/quant_alpha/evaluation/__init__.py +47 -0
  345. QuantNodes/research/quant_alpha/evaluation/baselines/__init__.py +8 -0
  346. QuantNodes/research/quant_alpha/evaluation/baselines/g1_handcrafted.py +135 -0
  347. QuantNodes/research/quant_alpha/evaluation/baselines/g2_llm_only.py +269 -0
  348. QuantNodes/research/quant_alpha/evaluation/baselines/g3_alpha_gpt.py +152 -0
  349. QuantNodes/research/quant_alpha/evaluation/clickhouse_data_loader.py +227 -0
  350. QuantNodes/research/quant_alpha/evaluation/contracts.py +376 -0
  351. QuantNodes/research/quant_alpha/evaluation/evaluators/__init__.py +6 -0
  352. QuantNodes/research/quant_alpha/evaluation/evaluators/polars_evaluator.py +545 -0
  353. QuantNodes/research/quant_alpha/evaluation/mock_data_loader.py +226 -0
  354. QuantNodes/research/quant_alpha/evaluation/runner.py +243 -0
  355. QuantNodes/research/quant_alpha/llm/__init__.py +38 -0
  356. QuantNodes/research/quant_alpha/llm/parser.py +681 -0
  357. QuantNodes/research/quant_alpha/logic_driven_pipeline.py +411 -0
  358. QuantNodes/research/quant_alpha/logic_mining/__init__.py +74 -0
  359. QuantNodes/research/quant_alpha/logic_mining/compiler.py +457 -0
  360. QuantNodes/research/quant_alpha/logic_mining/generator.py +366 -0
  361. QuantNodes/research/quant_alpha/logic_mining/models.py +252 -0
  362. QuantNodes/research/quant_alpha/logic_mining/parser.py +287 -0
  363. QuantNodes/research/quant_alpha/logic_mining/pipelines.py +297 -0
  364. QuantNodes/research/quant_alpha/logic_mining/sources.py +149 -0
  365. QuantNodes/research/quant_alpha/mcts/__init__.py +66 -0
  366. QuantNodes/research/quant_alpha/mcts/cache.py +262 -0
  367. QuantNodes/research/quant_alpha/mcts/extension_ops.py +320 -0
  368. QuantNodes/research/quant_alpha/mcts/feedback.py +825 -0
  369. QuantNodes/research/quant_alpha/mcts/op_prior.py +180 -0
  370. QuantNodes/research/quant_alpha/mcts/search.py +540 -0
  371. QuantNodes/research/quant_alpha/mcts/tree.py +201 -0
  372. QuantNodes/research/quant_alpha/operator_vocab/__init__.py +50 -0
  373. QuantNodes/research/quant_alpha/operator_vocab/config.py +54 -0
  374. QuantNodes/research/quant_alpha/operator_vocab/metadata.py +263 -0
  375. QuantNodes/research/quant_alpha/operator_vocab/vocabulary.py +481 -0
  376. QuantNodes/research/quant_alpha/pipeline.py +1027 -0
  377. QuantNodes/research/quant_alpha/types/__init__.py +27 -0
  378. QuantNodes/research/quant_alpha/types/constants.py +28 -0
  379. QuantNodes/research/quant_alpha/types/state.py +205 -0
  380. QuantNodes/research/quant_alpha/workflow/__init__.py +32 -0
  381. QuantNodes/research/quant_alpha/workflow/alpha_gpt.py +911 -0
  382. QuantNodes/research/quant_alpha/workflow/alpha_logics.py +416 -0
  383. QuantNodes/research/quant_alpha/workflow/state.py +27 -0
  384. QuantNodes/research/report_reproducer.py +485 -0
  385. QuantNodes/research/wiki.py +1155 -0
  386. QuantNodes/symbolic/__init__.py +51 -0
  387. QuantNodes/symbolic/compiler.py +113 -0
  388. QuantNodes/symbolic/dialect.py +260 -0
  389. QuantNodes/symbolic/executor.py +147 -0
  390. QuantNodes/symbolic/expression.py +234 -0
  391. QuantNodes/symbolic/functions.py +433 -0
  392. QuantNodes/symbolic/optimizer.py +165 -0
  393. QuantNodes/ui_node/__init__.py +30 -0
  394. QuantNodes/ui_node/base.py +222 -0
  395. quantnodes-3.0.0.dist-info/METADATA +463 -0
  396. quantnodes-3.0.0.dist-info/RECORD +399 -0
  397. quantnodes-3.0.0.dist-info/WHEEL +5 -0
  398. quantnodes-3.0.0.dist-info/entry_points.txt +24 -0
  399. quantnodes-3.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,405 @@
1
+ # coding=utf-8
2
+ """
3
+ Pipeline 优化器
4
+
5
+ 提供 Pipeline 自动优化功能。
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import re
10
+ import ast
11
+ import logging
12
+ from typing import Any, Dict, List, Optional, Tuple
13
+ from dataclasses import dataclass, field
14
+ from abc import ABC, abstractmethod
15
+
16
+ from QuantNodes.ai.llm.base import LLMClientBase, Message, MessageRole
17
+ from QuantNodes.ai.prompts import PromptLibrary
18
+ from QuantNodes.ai.sandbox import CodeSandbox
19
+
20
+
21
+ @dataclass
22
+ class OptimizationResult:
23
+ """优化结果"""
24
+ original_code: str
25
+ optimized_code: str
26
+ improvements: List[str] = field(default_factory=list)
27
+ is_valid: bool = True
28
+ error_message: Optional[str] = None
29
+
30
+
31
+ @dataclass
32
+ class NodeAnalysis:
33
+ """节点分析"""
34
+ node_type: str
35
+ config: Dict[str, Any]
36
+ dependencies: List[str]
37
+ estimated_cost: float = 1.0
38
+
39
+
40
+ class PipelineAnalyzer:
41
+ """
42
+ Pipeline 分析器
43
+
44
+ 分析 Pipeline 结构并识别优化机会。
45
+ """
46
+
47
+ def __init__(self):
48
+ self.logger = logging.getLogger(f"optimizer.{self.__class__.__name__}")
49
+
50
+ def analyze(self, code: str) -> List[NodeAnalysis]:
51
+ """
52
+ 分析 Pipeline 代码
53
+
54
+ Args:
55
+ code: Pipeline 代码
56
+
57
+ Returns:
58
+ List[NodeAnalysis] 节点分析列表
59
+ """
60
+ analyses = []
61
+
62
+ try:
63
+ tree = ast.parse(code)
64
+ analyses = self._walk_ast(tree)
65
+ except SyntaxError as e:
66
+ self.logger.error(f"Syntax error: {e}")
67
+
68
+ return analyses
69
+
70
+ def _walk_ast(self, tree: ast.AST) -> List[NodeAnalysis]:
71
+ """遍历 AST"""
72
+ analyses = []
73
+
74
+ for node in ast.walk(tree):
75
+ if isinstance(node, ast.Call):
76
+ analysis = self._analyze_call(node)
77
+ if analysis:
78
+ analyses.append(analysis)
79
+
80
+ return analyses
81
+
82
+ def _analyze_call(self, node: ast.Call) -> Optional[NodeAnalysis]:
83
+ """分析函数调用"""
84
+ if not isinstance(node.func, ast.Name):
85
+ return None
86
+
87
+ node_name = node.func.id
88
+
89
+ if 'Node' in node_name or 'Node' in str(node.func):
90
+ config = self._extract_config(node)
91
+ deps = self._extract_dependencies(node)
92
+
93
+ return NodeAnalysis(
94
+ node_type=node_name,
95
+ config=config,
96
+ dependencies=deps,
97
+ estimated_cost=self._estimate_cost(node_name, config)
98
+ )
99
+
100
+ return None
101
+
102
+ def _extract_config(self, node: ast.Call) -> Dict[str, Any]:
103
+ """提取配置"""
104
+ config = {}
105
+
106
+ for keyword in node.keywords:
107
+ if isinstance(keyword.value, ast.Dict):
108
+ for k, v in zip(keyword.value.keys, keyword.value.values):
109
+ if isinstance(k, ast.Constant):
110
+ if isinstance(v, ast.Constant):
111
+ config[k.value] = v.value
112
+ elif isinstance(v, ast.Name):
113
+ config[k.value] = v.id
114
+ elif isinstance(keyword.value, ast.Constant):
115
+ config[keyword.arg] = keyword.value.value
116
+
117
+ return config
118
+
119
+ def _extract_dependencies(self, node: ast.Call) -> List[str]:
120
+ """提取依赖"""
121
+ deps = []
122
+
123
+ for arg in node.args:
124
+ if isinstance(arg, ast.Name):
125
+ deps.append(arg.id)
126
+ elif isinstance(arg, ast.BinOp) and isinstance(arg.op, ast.RShift):
127
+ if isinstance(arg.left, ast.Name):
128
+ deps.append(arg.left.id)
129
+ if isinstance(arg.right, ast.Name):
130
+ deps.append(arg.right.id)
131
+
132
+ return deps
133
+
134
+ def _estimate_cost(self, node_type: str, config: Dict[str, Any]) -> float:
135
+ """估算节点成本"""
136
+ base_cost = 1.0
137
+
138
+ if 'database' in node_type.lower():
139
+ base_cost = 10.0
140
+ elif 'backtest' in node_type.lower():
141
+ base_cost = 50.0
142
+ elif 'factor' in node_type.lower():
143
+ base_cost = 5.0
144
+
145
+ if 'limit' in config:
146
+ limit = config.get('limit', 1000)
147
+ base_cost *= (limit / 1000)
148
+
149
+ return base_cost
150
+
151
+
152
+ class RuleBasedOptimizer(ABC):
153
+ """基于规则的优化器基类"""
154
+
155
+ @abstractmethod
156
+ def can_apply(self, code: str) -> bool:
157
+ """检查是否可以应用"""
158
+ pass
159
+
160
+ @abstractmethod
161
+ def apply(self, code: str) -> Tuple[str, List[str]]:
162
+ """应用优化"""
163
+ pass
164
+
165
+
166
+ class CacheReadOptimizer(RuleBasedOptimizer):
167
+ """缓存读取优化"""
168
+
169
+ def can_apply(self, code: str) -> bool:
170
+ return 'DatabaseNode' in code and '.read(' in code
171
+
172
+ def apply(self, code: str) -> Tuple[str, List[str]]:
173
+ improvements = []
174
+
175
+ optimized = re.sub(
176
+ r'(\w+)\s*=\s*DatabaseNode\([^)]*\)\s*\n\s*\1\.read\(',
177
+ r'\1 = DatabaseNode(cache=True, ...)\n\1.read(',
178
+ code
179
+ )
180
+
181
+ if optimized != code:
182
+ improvements.append("Added caching to DatabaseNode reads")
183
+
184
+ return optimized, improvements
185
+
186
+
187
+ class LimitPushdownOptimizer(RuleBasedOptimizer):
188
+ """LIMIT 下推优化"""
189
+
190
+ def can_apply(self, code: str) -> bool:
191
+ return '.limit(' in code and 'DatabaseNode' in code
192
+
193
+ def apply(self, code: str) -> Tuple[str, List[str]]:
194
+ improvements = []
195
+
196
+ limit_match = re.search(r'\.limit\((\d+)\)', code)
197
+ if limit_match:
198
+ limit_value = limit_match.group(1)
199
+ improvements.append(f"Pushed down limit={limit_value} to DatabaseNode")
200
+
201
+ return code, improvements
202
+
203
+
204
+ class ParallelFetchOptimizer(RuleBasedOptimizer):
205
+ """并行获取优化"""
206
+
207
+ def can_apply(self, code: str) -> bool:
208
+ patterns = [
209
+ r'DatabaseNode\([^)]*engine\s*=\s*["\']duckdb["\']',
210
+ r'DatabaseNode\([^)]*engine\s*=\s*["\']clickhouse["\']',
211
+ ]
212
+ return any(re.search(p, code) for p in patterns)
213
+
214
+ def apply(self, code: str) -> Tuple[str, List[str]]:
215
+ improvements = ["Enabled parallel data fetching"]
216
+
217
+ optimized = re.sub(
218
+ r'DatabaseNode\(',
219
+ 'DatabaseNode(parallel=True, ',
220
+ code
221
+ )
222
+
223
+ return optimized, improvements
224
+
225
+
226
+ class PipelineOptimizer:
227
+ """
228
+ Pipeline 优化器
229
+
230
+ 提供 Pipeline 自动优化功能。
231
+
232
+ Examples:
233
+ >>> optimizer = PipelineOptimizer(llm_client)
234
+ >>> result = optimizer.optimize(code)
235
+ >>> print(result.optimized_code)
236
+ """
237
+
238
+ def __init__(
239
+ self,
240
+ llm_client=None,
241
+ code_sandbox: Optional[CodeSandbox] = None,
242
+ enable_ai_optimization: bool = True,
243
+ **kwargs
244
+ ):
245
+ """
246
+ 初始化优化器
247
+
248
+ Args:
249
+ llm_client: LLM 客户端(可选,默认使用 LLMGateway)
250
+ code_sandbox: 代码沙箱
251
+ enable_ai_optimization: 是否启用 AI 优化
252
+ """
253
+ if llm_client is None:
254
+ from QuantNodes.ai.llm.gateway import get_llm_gateway
255
+ llm_client = get_llm_gateway()
256
+ self.llm = llm_client
257
+ self.sandbox = code_sandbox or CodeSandbox()
258
+ self.enable_ai_optimization = enable_ai_optimization and self.llm is not None
259
+ self.analyzer = PipelineAnalyzer()
260
+ self.rule_optimizers: List[RuleBasedOptimizer] = [
261
+ CacheReadOptimizer(),
262
+ LimitPushdownOptimizer(),
263
+ ParallelFetchOptimizer(),
264
+ ]
265
+ self.logger = logging.getLogger(f"optimizer.{self.__class__.__name__}")
266
+
267
+ def optimize(
268
+ self,
269
+ code: str,
270
+ goal: str = "performance",
271
+ validate: bool = True,
272
+ **kwargs
273
+ ) -> OptimizationResult:
274
+ """
275
+ 优化 Pipeline 代码
276
+
277
+ Args:
278
+ code: Pipeline 代码
279
+ goal: 优化目标 ("performance", "memory", "readability")
280
+ validate: 是否验证优化后的代码
281
+ **kwargs: 额外参数
282
+
283
+ Returns:
284
+ OptimizationResult 优化结果
285
+ """
286
+ original_code = code
287
+ all_improvements: List[str] = []
288
+
289
+ analyses = self.analyzer.analyze(code)
290
+ if analyses:
291
+ estimated_cost = sum(a.estimated_cost for a in analyses)
292
+ all_improvements.append(
293
+ f"Analyzed {len(analyses)} nodes, estimated cost: {estimated_cost:.2f}"
294
+ )
295
+
296
+ for optimizer in self.rule_optimizers:
297
+ if optimizer.can_apply(code):
298
+ optimized, improvements = optimizer.apply(code)
299
+ if optimized != code:
300
+ code = optimized
301
+ all_improvements.extend(improvements)
302
+
303
+ if self.enable_ai_optimization and self.llm:
304
+ code, ai_improvements = self._ai_optimize(code, goal, **kwargs)
305
+ all_improvements.extend(ai_improvements)
306
+
307
+ if validate:
308
+ validation_result = self.sandbox.validate(code)
309
+ is_valid = validation_result.is_safe
310
+ error_message = None if is_valid else f"Validation failed: {validation_result.errors}"
311
+ else:
312
+ is_valid = True
313
+ error_message = None
314
+
315
+ return OptimizationResult(
316
+ original_code=original_code,
317
+ optimized_code=code,
318
+ improvements=all_improvements,
319
+ is_valid=is_valid,
320
+ error_message=error_message
321
+ )
322
+
323
+ def _ai_optimize(
324
+ self,
325
+ code: str,
326
+ goal: str,
327
+ **kwargs
328
+ ) -> Tuple[str, List[str]]:
329
+ """AI 优化"""
330
+ improvements = []
331
+
332
+ system_prompt, user_prompt = PromptLibrary.format(
333
+ "optimization",
334
+ code=code
335
+ )
336
+
337
+ goal_instruction = ""
338
+ if goal == "performance":
339
+ goal_instruction = "Focus on reducing execution time and minimizing API calls."
340
+ elif goal == "memory":
341
+ goal_instruction = (
342
+ "Focus on reducing memory usage and avoiding unnecessary data copies."
343
+ )
344
+ elif goal == "readability":
345
+ goal_instruction = "Focus on improving code clarity and maintainability."
346
+
347
+ messages = [
348
+ Message(role=MessageRole.SYSTEM, content=system_prompt),
349
+ Message(role=MessageRole.USER, content=user_prompt + "\n\n" + goal_instruction),
350
+ ]
351
+
352
+ try:
353
+ response = self.llm.chat(
354
+ messages=messages,
355
+ temperature=0.3,
356
+ max_tokens=kwargs.get('max_tokens'),
357
+ **kwargs
358
+ )
359
+
360
+ if response and response.content:
361
+ optimized_code = self._extract_code(response.content)
362
+ if optimized_code and optimized_code != code:
363
+ improvements.append("Applied AI-based optimization")
364
+ return optimized_code, improvements
365
+
366
+ except Exception as e:
367
+ self.logger.error(f"AI optimization failed: {e}")
368
+
369
+ return code, improvements
370
+
371
+ def _extract_code(self, content: str) -> str:
372
+ """从响应中提取代码"""
373
+ pattern = re.compile(r'```(?:python)?\s*(.*?)```', re.DOTALL)
374
+ matches = pattern.findall(content)
375
+ if matches:
376
+ return matches[0].strip()
377
+ return content.strip()
378
+
379
+ def suggest_optimizations(self, code: str) -> List[str]:
380
+ """
381
+ 建议优化项
382
+
383
+ Args:
384
+ code: Pipeline 代码
385
+
386
+ Returns:
387
+ List[str] 建议列表
388
+ """
389
+ suggestions = []
390
+ analyses = self.analyzer.analyze(code)
391
+
392
+ for analysis in analyses:
393
+ if analysis.estimated_cost > 10:
394
+ suggestions.append(
395
+ f"High cost node ({analysis.node_type}, cost={analysis.estimated_cost:.2f}): "
396
+ "Consider optimizing or caching"
397
+ )
398
+
399
+ for optimizer in self.rule_optimizers:
400
+ if optimizer.can_apply(code):
401
+ suggestions.append(
402
+ f"Rule-based optimization available: {optimizer.__class__.__name__}"
403
+ )
404
+
405
+ return suggestions
@@ -0,0 +1,229 @@
1
+ # coding=utf-8
2
+ """
3
+ 提示词模板库
4
+
5
+ 提供用于生成和优化 Pipeline 的提示词模板。
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from typing import Dict, List
10
+ from dataclasses import dataclass
11
+
12
+
13
+ @dataclass
14
+ class PromptTemplate:
15
+ """提示词模板"""
16
+ system: str
17
+ user: str
18
+ description: str = ""
19
+
20
+ def format(self, **kwargs) -> tuple[str, str]:
21
+ """格式化模板"""
22
+ return (
23
+ self.system.format(**kwargs),
24
+ self.user.format(**kwargs)
25
+ )
26
+
27
+
28
+ SYSTEM_PROMPT = (
29
+ "You are a quantitative trading strategy expert specializing in"
30
+ " designing and implementing trading systems using the QuantNodes"
31
+ " framework.\n\n"
32
+ "QuantNodes Framework Overview:\n"
33
+ "- BaseNode: Unified node base class with execute() method\n"
34
+ "- Pipeline: Chain nodes together using >> operator\n"
35
+ "- DatabaseNode: Query data from various databases (SQLite, DuckDB, MySQL,"
36
+ " ClickHouse)\n"
37
+ "- factor_functions: 140+ Polars-based operators (rolling_mean, zscore,"
38
+ " rank, etc.)\n"
39
+ "- BacktestNode: Run backtesting simulations\n"
40
+ "- OperatorNode: SQL operations and data transformations\n\n"
41
+ "Key Conventions:\n"
42
+ "- All nodes inherit from BaseNode\n"
43
+ "- Use >> to chain nodes in a pipeline\n"
44
+ "- Configuration passed via config dict in constructor\n"
45
+ "- Input/output data is typically pandas DataFrame\n"
46
+ "- Factor computation uses factor_functions (ff) module\n\n"
47
+ "Your task is to generate valid Python code that creates QuantNodes"
48
+ " pipelines based on user requests.\n"
49
+ )
50
+
51
+ STRATEGY_GENERATION_PROMPT = PromptTemplate(
52
+ system=SYSTEM_PROMPT,
53
+ user=(
54
+ "Generate a QuantNodes trading strategy pipeline based on the following"
55
+ " description:\n\n{trading_description}\n\nRequirements:\n"
56
+ "- Use Python code\n"
57
+ "- Create appropriate nodes (DatabaseNode, BacktestNode, etc.) and"
58
+ " use factor_functions for factor computation\n"
59
+ "- Use the >> operator to chain nodes\n"
60
+ "- Include necessary configuration\n\n"
61
+ "Available Data:\n"
62
+ "The database contains stock OHLCV data with columns: date, code,"
63
+ " open, high, low, close, volume\n\n"
64
+ "Generate the Python code:"
65
+ ),
66
+ description="Generate trading strategy pipeline from natural language",
67
+ )
68
+
69
+ CODE_REVIEW_PROMPT = PromptTemplate(
70
+ system=SYSTEM_PROMPT,
71
+ user="""Review the following QuantNodes pipeline code for issues:
72
+
73
+ ```python
74
+ {code}
75
+ ```
76
+
77
+ Check for:
78
+ 1. Correct node usage and configuration
79
+ 2. Proper pipeline chaining
80
+ 3. Data flow correctness
81
+ 4. Performance concerns
82
+ 5. Potential bugs
83
+
84
+ Provide your review:""",
85
+ description="Review generated code for issues"
86
+ )
87
+
88
+ OPTIMIZATION_PROMPT = PromptTemplate(
89
+ system=SYSTEM_PROMPT,
90
+ user="""Optimize the following QuantNodes pipeline for better performance:
91
+
92
+ ```python
93
+ {code}
94
+ ```
95
+
96
+ Optimization goals:
97
+ - Reduce execution time
98
+ - Minimize memory usage
99
+ - Improve readability
100
+
101
+ Provide the optimized code:""",
102
+ description="Optimize pipeline for performance"
103
+ )
104
+
105
+ FACTOR_EXPLANATION_PROMPT = PromptTemplate(
106
+ system="You are a financial factor research expert.",
107
+ user="""Explain the following trading factor in detail:
108
+
109
+ {factor_description}
110
+
111
+ Include:
112
+ 1. What the factor measures
113
+ 2. How to calculate it
114
+ 3. Practical usage tips
115
+ 4. Potential issues or limitations
116
+
117
+ Provide a comprehensive explanation:""",
118
+ description="Explain trading factors"
119
+ )
120
+
121
+ BACKTEST_CONFIG_PROMPT = PromptTemplate(
122
+ system=SYSTEM_PROMPT,
123
+ user="""Suggest appropriate backtest configuration for the following strategy:
124
+
125
+ ```python
126
+ {strategy_code}
127
+ ```
128
+
129
+ Consider:
130
+ - Initial capital
131
+ - Commission rates
132
+ - Position sizing
133
+ - Risk management
134
+
135
+ Provide configuration dict:""",
136
+ description="Suggest backtest configuration"
137
+ )
138
+
139
+
140
+ class PromptLibrary:
141
+ """
142
+ 提示词模板库
143
+
144
+ 提供各种任务场景的提示词模板。
145
+ """
146
+
147
+ _templates: Dict[str, PromptTemplate] = {
148
+ "strategy_generation": STRATEGY_GENERATION_PROMPT,
149
+ "code_review": CODE_REVIEW_PROMPT,
150
+ "optimization": OPTIMIZATION_PROMPT,
151
+ "factor_explanation": FACTOR_EXPLANATION_PROMPT,
152
+ "backtest_config": BACKTEST_CONFIG_PROMPT,
153
+ }
154
+
155
+ @classmethod
156
+ def get(cls, name: str) -> PromptTemplate:
157
+ """获取模板"""
158
+ if name not in cls._templates:
159
+ raise ValueError(f"Unknown template: {name}. Available: {list(cls._templates.keys())}")
160
+ return cls._templates[name]
161
+
162
+ @classmethod
163
+ def list_templates(cls) -> List[str]:
164
+ """列出所有模板"""
165
+ return list(cls._templates.keys())
166
+
167
+ @classmethod
168
+ def register(cls, name: str, template: PromptTemplate) -> None:
169
+ """注册新模板"""
170
+ cls._templates[name] = template
171
+
172
+ @classmethod
173
+ def format(
174
+ cls,
175
+ name: str,
176
+ **kwargs
177
+ ) -> tuple[str, str]:
178
+ """格式化模板"""
179
+ template = cls.get(name)
180
+ return template.format(**kwargs)
181
+
182
+ @classmethod
183
+ def get_system_prompt(cls) -> str:
184
+ """获取系统提示词"""
185
+ return SYSTEM_PROMPT
186
+
187
+
188
+ class PromptBuilder:
189
+ """提示词构建器"""
190
+
191
+ def __init__(self):
192
+ self._parts: List[str] = []
193
+
194
+ def add_system(self, text: str) -> 'PromptBuilder':
195
+ """添加系统提示"""
196
+ self._parts.append(f"[SYSTEM] {text}")
197
+ return self
198
+
199
+ def add_user(self, text: str) -> 'PromptBuilder':
200
+ """添加用户提示"""
201
+ self._parts.append(f"[USER] {text}")
202
+ return self
203
+
204
+ def add_assistant(self, text: str) -> 'PromptBuilder':
205
+ """添加助手提示"""
206
+ self._parts.append(f"[ASSISTANT] {text}")
207
+ return self
208
+
209
+ def add_example(self, user: str, assistant: str) -> 'PromptBuilder':
210
+ """添加示例"""
211
+ self._parts.append(f"[EXAMPLE]\nUser: {user}\nAssistant: {assistant}")
212
+ return self
213
+
214
+ def build(self) -> tuple[str, str]:
215
+ """构建最终提示词"""
216
+ system_parts = []
217
+ user_parts = []
218
+
219
+ for part in self._parts:
220
+ if part.startswith("[SYSTEM]"):
221
+ system_parts.append(part[9:])
222
+ elif part.startswith("[USER]"):
223
+ user_parts.append(part[7:])
224
+ elif part.startswith("[ASSISTANT]"):
225
+ system_parts.append(f"Assistant: {part[11:]}")
226
+ elif part.startswith("[EXAMPLE]"):
227
+ user_parts.append(part[10:])
228
+
229
+ return "\n".join(system_parts), "\n".join(user_parts)