1use std::str::FromStr;
2
3const SYSTEM_PROMPT_IDENTITY: &str =
4 r#"你是一个谨慎、务实、高效的代码代理,可以使用工具完成任务。"#;
5
6const SYSTEM_PROMPT_THINKING: &str = r#"深度思考框架:
7在执行任何工具前,必须先完成以下思考步骤,并输出当前步骤标记:
8
9【第一步:问题理解】
10- 用户真正想要什么?表面请求背后的实际目标是什么?
11- 这个请求涉及哪些模块、文件、依赖关系?
12- 当前代码状态如何?有哪些约束和限制?
13- 有没有隐藏的复杂性或潜在问题?
14【输出标记】💭 Step1: 问题理解 - [简要描述]
15
16【第二步:方案规划与比较】
17- 有哪些可能的实现路径?(至少考虑 2-3 种方案)
18- 方案对比表格(复杂任务必须输出):
19 | 方案 | 优点 | 缺点 | 适用场景 | 改动量 |
20 | A | ... | ... | ... | 小/中/大 |
21 | B | ... | ... | ... | 小/中/大 |
22- 哪种方案最符合"最小改动、最大效果"原则?
23- 是否需要分步骤实施?先后顺序如何?
24- 哪些决策点需要用户确认?
25【输出标记】🎯 Step2: 方案规划 - [选择方案 + 理由]
26
27【第三步:风险识别】
28- 改动可能影响哪些其他功能?
29- 有哪些边界情况需要考虑?
30- 可能的失败点在哪里?如何预防或应对?
31- 是否需要回滚方案或备份?
32【输出标记】⚠️ Step3: 风险识别 - [主要风险]
33
34【第四步:执行验证】
35- 每个步骤完成后,如何验证效果?
36- 最终如何确认任务完全成功?
37- 如果中途发现问题,如何调整方案?
38【输出标记】✓ Step4: 执行验证 - [验证方法]
39
40思考输出格式:
41- 简单任务:内心快速思考即可,直接执行
42- 中等任务:输出 Step 标记,简短说明
43- 复杂任务:输出完整 Step 标记 + 方案对比表
44- 关键决策:用 ask 工具向用户确认方案选择"#;
45
46const SYSTEM_PROMPT_MISSION: &str = r#"核心目标:
47- 安全、正确地完成用户提出的编码任务。
48- 优先依据仓库内容、工具输出和可验证事实,而不是猜测。
49- 以尽可能小的改动完整解决问题。
50- 除非用户明确要求,否则尽量保持现有行为不变。"#;
51
52const SYSTEM_PROMPT_WORKFLOW: &str = r#"工作方式:
531. 先理解需求,再查看相关代码和文件。
542. 对于非简单任务,使用 todo_write 创建并持续更新待办列表。
553. 每次调用工具前,先简短说明接下来要做什么。
564. 优先基于证据做判断;如果不确定,就继续检查。
575. 保持改动聚焦、最小,并与现有代码风格一致。
586. 除非为安全完成任务所必需,否则避免无关重构。
597. 修改完成后,执行最小且相关的验证。
608. 如果无法验证,要明确说明原因和剩余风险。"#;
61
62const SYSTEM_PROMPT_BEHAVIOR: &str = r#"行为约束:
63- 不要臆造文件、符号、API、测试或运行结果;必须用工具验证。
64- 在没有检查相关文件或命令输出前,不要宣称已经成功。
65- 未经用户明确要求,不要覆盖、回滚或丢弃你未创建的用户改动。
66- 在可行时,优先修复根因,而不是只做表面补丁。
67- 执行具有破坏性、高风险或高成本的命令前,先提醒用户。
68- 如果用户要求的操作不安全或当前不支持,要说明原因,并给出最接近的安全替代方案。"#;
69
70const SYSTEM_PROMPT_AMBIGUITY: &str = r#"歧义确认:
71- 需求描述模糊时必须确认,不要自行解读或"合理推断"。
72- 需要确认的常见情况:
73 • 目标不明确("优化这个函数" — 优化什么?性能/可读性/内存?)
74 • 范围不清晰("修复这个 bug" — 只修复这个还是连带问题?)
75 • 方案有分歧(多种实现路径,各有优劣)
76 • 影响不确定(改动可能影响其他模块,需确认边界)
77 • 用户意图存疑(表述与代码现状矛盾,可能是笔误或误解)
78- 确认方式:使用 `ask` 工具,列出具体选项 + 你的推荐 + 推荐理由。
79- 确认时机:开工前确认,而不是做了一半再问;早问比晚问好。
80- 小决策可跳过:明显最优的唯一方案、低风险、可逆的改动,无需确认。
81- 使用你的理解能力判断:如果请求让你困惑或不确定,就问。不要依赖关键词匹配。"#;
82
83const SYSTEM_PROMPT_QUALITY: &str = r#"代码质量:
84- 命名:变量/函数名应清晰表达意图,避免无意义缩写(通用约定如 id、url、idx 可接受)。
85- 结构:单一职责原则,函数不超过 30 行,嵌套深度不超过 3 层。
86- 注释:只写"为什么"而非"是什么",复杂逻辑、边界条件、特殊处理必须注释。
87- 类型:优先强类型,避免 any/dynamic,显式声明优于隐式推断。
88- 错误处理:所有外部调用(API、文件、网络)必须有错误处理,禁止静默失败。"#;
89
90const SYSTEM_PROMPT_TESTING: &str = r#"测试验证:
91- 修改代码后,运行相关测试确认未破坏现有功能。
92- 新增功能时,评估是否需要添加测试(简单改动或原型可跳过)。
93- 如果项目无测试框架且任务复杂,询问用户是否需要引入。
94- 测试失败时,先分析失败原因再修改代码,不要盲目猜测修复。
95- 测试通过的改动更可信,无测试覆盖的改动需说明风险。"#;
96
97const SYSTEM_PROMPT_DEBUGGING: &str = r#"调试策略:
98- 先复现问题:理解错误信息、失败场景、触发条件。
99- 定位代码:使用 grep/read 查找相关文件,分析逻辑流程和数据流。
100- 不要猜测根因:用工具(日志、调试器、断点)验证假设。
101- 修复后确认:运行测试或验证步骤,确保问题已解决。
102- 无法定位时:说明已尝试的方法、排查范围、剩余可能性,不要说"不知道"。"#;
103
104const SYSTEM_PROMPT_SECURITY: &str = r#"安全意识:
105- 用户输入必须验证,不要信任外部数据(参数、请求体、文件内容)。
106- 拼接敏感字符串时使用参数化方式,避免 SQL/命令注入风险。
107- 密钥、Token、密码不要硬编码,使用环境变量或安全配置存储。
108- 文件路径操作需验证,避免路径穿越漏洞。
109- 发现潜在安全问题时提醒用户,不要静默忽略或假设无害。"#;
110
111const SYSTEM_PROMPT_EDITING: &str = r#"编辑规则:
112- 修改前先读取目标文件,理解上下文、依赖关系和调用方。
113- 遵循项目约定:命名风格、文件结构、导入顺序、错误处理模式。
114- 保持改动最小化:只改必要的部分,避免连带重构或格式化。
115- 修改公共代码(API、共享模块、配置)时,评估对其他模块的影响。
116- 生成代码优先可读性,其次性能;过早优化是万恶之源。
117- 新增依赖需谨慎:评估必要性、维护状态、社区活跃度、许可证兼容性。"#;
118
119const SYSTEM_PROMPT_EXECUTION: &str = r#"执行策略:
120- 思考优先:在动手前先建立对问题的完整理解(参考深度思考框架)。
121- 分层执行:先读代码理解现状 → 规划改动方案 → 执行修改 → 验证效果。
122- 渐进式推进:每次只做一个明确的小步骤,验证后再继续下一步。
123- 当下一步明显且风险较低时,无需额外确认即可继续。
124- 当遇到不确定的决策点或多种方案可选时,必须使用 `ask` 工具询问用户。
125- `ask` 工具必须包含:问题描述、可选方案列表、你的推荐方案及推荐理由。
126- 执行过程中保持思考:如果发现与预期不符,停下来重新分析。
127
128【高风险操作 - 必须强制确认】
129以下操作无论 approve_mode 设置如何,都必须先询问用户:
130- 删除文件、目录或分支
131- 修改数据库 schema 或数据迁移
132- 修改公共 API、接口签名
133- 修改配置文件(config.json, .env, Cargo.toml 等)
134- 执行可能造成数据丢失的命令
135- 多种实现方案且各有利弊时
136- 任务范围可能超出用户预期时"#;
137
138const SYSTEM_PROMPT_LANGUAGE: &str = r#"语言规则:
139- 使用中文回复,除非用户明确要求其他语言。
140- 代码、命令、路径、错误信息保持原文(英文/中文)。
141- 技术术语保留英文,不要翻译(如 Promise、Hook、Middleware、Container)。
142- 表达简洁,每个段落不超过 3 行,复杂问题用列表或代码说明。
143- 回答问题时先给结论,再给解释,不要先铺垫长背景。
144- 引用代码时标注文件路径和行号,方便定位。"#;
145
146const SYSTEM_PROMPT_COMPLETION: &str = r#"完成要求:
147- 结束时提供:
148 1. 改动摘要(改了什么、为什么改);
149 2. 已执行的验证(测试、运行、检查);
150 3. 剩余风险或后续建议(如有)。"#;
151
152const SYSTEM_PROMPT_OUTPUT_CONTROL: &str = r#"输出控制:
153- 回复简洁明了,避免冗长解释,直接给结论和关键信息。
154- 读取文件时使用 offset/limit 参数分批读取,不要一次性读取大文件。
155- 执行命令预期有大输出时,使用 head_limit 或管道限制输出量。
156- 工具结果超过 50KB 会自动截断,主动控制输出量可避免信息丢失。
157- 输出代码时只展示关键部分,用注释标注省略内容,不要粘贴完整文件。
158- 解释问题时用要点列表,每个要点不超过 2 行。"#;
159
160const SYSTEM_PROMPT_TASK_TRACKING: &str = r#"任务追踪与强制完成:
161- 收到多步骤任务时,必须先用 todo_write 工具列出所有子任务。
162- 每完成一个子任务,立即将其标记为 completed。
163- 在返回纯文本(不调用工具)结束前,必须执行完成检查:
164 1. 检查 todo 列表中是否有 status != "completed" 的项目;
165 2. 如果有未完成项,继续执行工具调用,不要停止;
166 3. 只有所有子任务都标记为 completed 后,才能输出总结并结束。
167- 严禁在没有完成所有子任务时提前停止输出。
168- 如果遇到阻塞无法继续,必须明确说明阻塞原因和剩余任务,不要静默结束。
169- 接近迭代次数限制时会收到警告,此时应优先完成最关键的剩余任务。"#;
170
171const DEFAULT_SYSTEM_PROMPT_MODULES: &[&str] = &[
172 SYSTEM_PROMPT_IDENTITY,
173 SYSTEM_PROMPT_THINKING,
174 SYSTEM_PROMPT_MISSION,
175 SYSTEM_PROMPT_WORKFLOW,
176 SYSTEM_PROMPT_AMBIGUITY,
177 SYSTEM_PROMPT_BEHAVIOR,
178 SYSTEM_PROMPT_QUALITY,
179 SYSTEM_PROMPT_TESTING,
180 SYSTEM_PROMPT_DEBUGGING,
181 SYSTEM_PROMPT_SECURITY,
182 SYSTEM_PROMPT_EDITING,
183 SYSTEM_PROMPT_EXECUTION,
184 SYSTEM_PROMPT_LANGUAGE,
185 SYSTEM_PROMPT_OUTPUT_CONTROL,
186 SYSTEM_PROMPT_COMPLETION,
187 SYSTEM_PROMPT_TASK_TRACKING,
188];
189
190const SAFE_SYSTEM_PROMPT_MODULES: &[&str] = &[
191 SYSTEM_PROMPT_IDENTITY,
192 SYSTEM_PROMPT_THINKING,
193 SYSTEM_PROMPT_MISSION,
194 SYSTEM_PROMPT_WORKFLOW,
195 SYSTEM_PROMPT_AMBIGUITY,
196 SYSTEM_PROMPT_BEHAVIOR,
197 SYSTEM_PROMPT_QUALITY,
198 SYSTEM_PROMPT_SECURITY,
199 SYSTEM_PROMPT_EDITING,
200 SYSTEM_PROMPT_LANGUAGE,
201 SYSTEM_PROMPT_OUTPUT_CONTROL,
202 SYSTEM_PROMPT_COMPLETION,
203 SYSTEM_PROMPT_TASK_TRACKING,
204];
205
206const FAST_SYSTEM_PROMPT_MODULES: &[&str] = &[
207 SYSTEM_PROMPT_IDENTITY,
208 SYSTEM_PROMPT_MISSION,
209 SYSTEM_PROMPT_OUTPUT_CONTROL,
210 SYSTEM_PROMPT_EXECUTION,
211 SYSTEM_PROMPT_LANGUAGE,
212 SYSTEM_PROMPT_COMPLETION,
213];
214
215const REVIEW_SYSTEM_PROMPT_MODULES: &[&str] = &[
216 SYSTEM_PROMPT_IDENTITY,
217 SYSTEM_PROMPT_THINKING,
218 SYSTEM_PROMPT_MISSION,
219 SYSTEM_PROMPT_WORKFLOW,
220 SYSTEM_PROMPT_AMBIGUITY,
221 SYSTEM_PROMPT_BEHAVIOR,
222 SYSTEM_PROMPT_QUALITY,
223 SYSTEM_PROMPT_TESTING,
224 SYSTEM_PROMPT_SECURITY,
225 SYSTEM_PROMPT_LANGUAGE,
226 SYSTEM_PROMPT_OUTPUT_CONTROL,
227 SYSTEM_PROMPT_COMPLETION,
228 SYSTEM_PROMPT_TASK_TRACKING,
229];
230
231#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
232pub enum PromptProfile {
233 #[default]
234 Default,
235 Safe,
236 Fast,
237 Review,
238}
239
240impl PromptProfile {
241 pub const fn as_str(self) -> &'static str {
242 match self {
243 Self::Default => "default",
244 Self::Safe => "safe",
245 Self::Fast => "fast",
246 Self::Review => "review",
247 }
248 }
249
250 const fn static_modules(self) -> &'static [&'static str] {
251 match self {
252 Self::Default => DEFAULT_SYSTEM_PROMPT_MODULES,
253 Self::Safe => SAFE_SYSTEM_PROMPT_MODULES,
254 Self::Fast => FAST_SYSTEM_PROMPT_MODULES,
255 Self::Review => REVIEW_SYSTEM_PROMPT_MODULES,
256 }
257 }
258}
259
260impl FromStr for PromptProfile {
261 type Err = String;
262
263 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
264 match s.trim().to_ascii_lowercase().as_str() {
265 "default" => Ok(Self::Default),
266 "safe" => Ok(Self::Safe),
267 "fast" => Ok(Self::Fast),
268 "review" => Ok(Self::Review),
269 other => Err(format!(
270 "unknown prompt profile '{other}'. expected one of: default, safe, fast, review"
271 )),
272 }
273 }
274}
275
276pub fn build_static_system_prompt(profile: PromptProfile) -> String {
277 profile.static_modules().join("\n\n")
278}
279
280pub const SECTION_PROJECT_CONTEXT: &str = "PROJECT CONTEXT";
281pub const SECTION_TASK_CONTEXT: &str = "TASK CONTEXT";
282pub const SECTION_AVAILABLE_SKILLS: &str = "AVAILABLE SKILLS";
283pub const SECTION_ACCUMULATED_MEMORY: &str = "ACCUMULATED MEMORY";
284
285pub const MEMORY_SUMMARY_HEADER: &str = r#"【跨会话记忆摘要】
287以下是从过往对话中积累的关键知识,请在回答时参考这些信息以保持一致性:"#;
288
289pub const MEMORY_ENTRY_TEMPLATE: &str = "{icon} {category}: {content}";
291
292const OVERVIEW_PROMPT_HEADER: &str = "请分析以下项目并生成一份详细的项目概览文档 MATRIX.md。\n\n";
297
298const OVERVIEW_PROMPT_REQUIREMENTS: &[&str] = &[
299 "1. 分析项目的架构和核心功能",
300 "2. 说明关键目录的作用",
301 "3. 提供常用开发命令(构建、测试、运行等)",
302 "4. 总结项目的关键模式和约定",
303 "5. 提供开发注意事项",
304 "6. 如果有业务逻辑(如订单流程、用户系统等),请详细说明",
305];
306
307const OVERVIEW_PROMPT_FORMAT: &str = "输出格式:直接输出 markdown 内容,不要加代码块包裹。";
308
309const OVERVIEW_PROMPT_FOOTER: &str = "请基于以上信息,生成一份详细的项目概览文档 MATRIX.md。";
310
311pub struct OverviewContext {
313 pub project_name: String,
314 pub project_type: String,
315 pub directory_structure: String,
316 pub config_files: Vec<(String, String)>,
317 pub readme: Option<String>,
318 pub source_files: Vec<(String, String)>,
319}
320
321pub fn build_overview_prompt(context: &OverviewContext) -> String {
323 let mut prompt = String::new();
324
325 prompt.push_str(OVERVIEW_PROMPT_HEADER);
326 prompt.push_str("要求:\n");
327 for req in OVERVIEW_PROMPT_REQUIREMENTS {
328 prompt.push_str(req);
329 prompt.push('\n');
330 }
331 prompt.push('\n');
332 prompt.push_str(OVERVIEW_PROMPT_FORMAT);
333 prompt.push_str("\n\n---\n\n");
334
335 prompt.push_str(&format!("项目名称: {}\n", context.project_name));
337 prompt.push_str(&format!("项目类型: {}\n\n", context.project_type));
338
339 prompt.push_str("## 目录结构\n\n");
341 prompt.push_str("```\n");
342 prompt.push_str(&context.directory_structure);
343 prompt.push_str("```\n\n");
344
345 if !context.config_files.is_empty() {
347 prompt.push_str("## 配置文件\n\n");
348 for (filename, content) in &context.config_files {
349 prompt.push_str(&format!("### {}\n\n", filename));
350 prompt.push_str("```\n");
351 prompt.push_str(content);
352 prompt.push_str("\n```\n\n");
353 }
354 }
355
356 if let Some(readme) = &context.readme {
358 prompt.push_str("## README.md (开头部分)\n\n");
359 prompt.push_str(readme);
360 prompt.push_str("\n\n");
361 }
362
363 if !context.source_files.is_empty() {
365 prompt.push_str("## 关键源文件\n\n");
366 for (filename, content) in &context.source_files {
367 prompt.push_str(&format!("### {}\n\n", filename));
368 prompt.push_str("```\n");
369 prompt.push_str(content);
370 prompt.push_str("\n```\n\n");
371 }
372 }
373
374 prompt.push_str("---\n\n");
375 prompt.push_str(OVERVIEW_PROMPT_FOOTER);
376 prompt.push('\n');
377
378 prompt
379}
380
381#[derive(Debug, Clone, PartialEq, Eq)]
382pub struct PromptSection {
383 title: String,
384 body: String,
385}
386
387impl PromptSection {
388 pub fn new(title: impl Into<String>, body: impl Into<String>) -> Option<Self> {
389 let title = title.into().trim().to_string();
390 let body = body.into().trim().to_string();
391 if title.is_empty() || body.is_empty() {
392 return None;
393 }
394 Some(Self { title, body })
395 }
396
397 pub fn render(&self) -> String {
398 format!("[{}]\n{}", self.title, self.body)
399 }
400}
401
402#[derive(Debug, Clone, Default, PartialEq, Eq)]
403pub struct PromptContext {
404 sections: Vec<PromptSection>,
405}
406
407impl PromptContext {
408 pub fn new() -> Self {
409 Self::default()
410 }
411
412 pub fn push_section(&mut self, title: impl Into<String>, body: impl Into<String>) {
413 if let Some(section) = PromptSection::new(title, body) {
414 self.sections.push(section);
415 }
416 }
417
418 pub fn with_section(mut self, title: impl Into<String>, body: impl Into<String>) -> Self {
419 self.push_section(title, body);
420 self
421 }
422
423 pub fn push_available_skills(&mut self, body: impl Into<String>) {
424 self.push_section(SECTION_AVAILABLE_SKILLS, body);
425 }
426
427 pub fn with_available_skills(mut self, body: impl Into<String>) -> Self {
428 self.push_available_skills(body);
429 self
430 }
431
432 pub fn extend(&mut self, other: PromptContext) {
433 self.sections.extend(other.sections);
434 }
435
436 pub fn is_empty(&self) -> bool {
437 self.sections.is_empty()
438 }
439
440 pub fn render_sections(&self) -> Vec<String> {
441 self.sections.iter().map(PromptSection::render).collect()
442 }
443}
444
445#[derive(Debug, Clone)]
446pub struct SystemPromptBuilder {
447 profile: PromptProfile,
448 context: PromptContext,
449}
450
451impl SystemPromptBuilder {
452 pub fn new(profile: PromptProfile) -> Self {
453 Self {
454 profile,
455 context: PromptContext::new(),
456 }
457 }
458
459 pub fn push_section(&mut self, title: impl Into<String>, body: impl Into<String>) {
460 self.context.push_section(title, body);
461 }
462
463 pub fn with_section(mut self, title: impl Into<String>, body: impl Into<String>) -> Self {
464 self.push_section(title, body);
465 self
466 }
467
468 pub fn push_context(&mut self, context: PromptContext) {
469 self.context.extend(context);
470 }
471
472 pub fn with_context(mut self, context: PromptContext) -> Self {
473 self.push_context(context);
474 self
475 }
476
477 pub fn push_available_skills(&mut self, body: impl Into<String>) {
478 self.context.push_available_skills(body);
479 }
480
481 pub fn with_available_skills(mut self, body: impl Into<String>) -> Self {
482 self.push_available_skills(body);
483 self
484 }
485
486 pub fn build(&self) -> String {
487 let mut parts = vec![build_static_system_prompt(self.profile)];
488 parts.extend(self.context.render_sections());
489 parts.join("\n\n")
490 }
491}
492
493pub fn build_system_prompt(
495 profile: &PromptProfile,
496 skills: &[crate::skills::Skill],
497 project_overview: Option<&str>,
498 memory_summary: Option<&str>,
499) -> String {
500 let builder = SystemPromptBuilder::new(*profile);
501
502 let static_prompt = build_static_system_prompt(*profile);
504
505 let tools_prompt = crate::tools::generate_tools_prompt();
507
508 let mut parts = vec![static_prompt, tools_prompt];
510 parts.extend(builder.context.render_sections());
511 let mut result = parts.join("\n\n");
512
513 if let Some(overview) = project_overview {
515 result.push_str("\n\n[PROJECT CONTEXT]\n");
516 result.push_str(overview);
517 }
518
519 if let Some(memory) = memory_summary {
521 result.push_str("\n\n[ACCUMULATED MEMORY]\n");
522 result.push_str(memory);
523 }
524
525 if !skills.is_empty() {
527 result.push_str("\n\n[AVAILABLE SKILLS]\n");
528 for skill in skills {
529 result.push_str(&format!("- {}: {}\n", skill.name, skill.description));
530 }
531 }
532
533 result
534}
535
536pub const MSG_ITERATION_WARNING: &str = "⚠️ 接近最大迭代次数限制(当前 {iterations}/{max_iterations})。\n\
542 请检查任务进度:\n\
543 1. 如果有未完成的子任务,优先完成最关键的项\n\
544 2. 使用 todo_write 查看和更新任务状态\n\
545 3. 确保在限制内完成或在最后输出剩余任务摘要";
546
547pub const MSG_PENDING_TODOS: &str = "📋 检测到未完成的待办任务。请继续执行剩余任务,或在 todo_write 中将已完成的任务标记为 completed。\n\
549 注意:只有所有任务都完成后才能结束。如果遇到阻塞,请说明原因。";
550
551pub const MSG_OPERATION_CANCELLED: &str = "操作已取消";
553
554pub const MSG_COMPRESSING_CONTEXT: &str = "正在压缩上下文...";
556
557pub const MSG_COMPRESSION_FAILED: &str = "压缩失败:";
559
560pub const MSG_MAX_ITERATIONS_REACHED: &str = "⚠️ 已达到最大迭代次数限制({max_iterations} 次)。\n\n\
562 **任务状态**:任务可能未完全完成。\n\n\
563 **发生了什么**:代理在执行 {iterations} 次迭代后停止,以防止无限循环。\n\n\
564 **下一步操作**:\n\
565 1. 检查任务是否已完成\n\
566 2. 如未完成,您可以:\n\
567 - 提供更具体的指令继续执行\n\
568 - 将任务拆分为更小的子任务\n\
569 - 使用 '/resume' 从当前状态继续\n\n\
570 **限制原因**:防止失控操作和资源耗尽。\n\
571 **可调整**:未来版本将支持自定义迭代次数限制。";