惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
博客园 - 【当耐特】
Cloudbric
Cloudbric
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Attack and Defense Labs
Attack and Defense Labs
爱范儿
爱范儿
The Cloudflare Blog
腾讯CDC
Security Archives - TechRepublic
Security Archives - TechRepublic
TaoSecurity Blog
TaoSecurity Blog
云风的 BLOG
云风的 BLOG
Recent Announcements
Recent Announcements
C
Check Point Blog
Schneier on Security
Schneier on Security
S
Schneier on Security
J
Java Code Geeks
B
Blog RSS Feed
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
Stack Overflow Blog
Stack Overflow Blog
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
A
About on SuperTechFans
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
A
Arctic Wolf
S
Secure Thoughts
P
Palo Alto Networks Blog
The Last Watchdog
The Last Watchdog
SecWiki News
SecWiki News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 三生石上(FineUI控件)
D
Darknet – Hacking Tools, Hacker News & Cyber Security
量子位
U
Unit 42
I
InfoQ
D
DataBreaches.Net
P
Privacy International News Feed
T
Troy Hunt's Blog
博客园 - 叶小钗
T
Threatpost
博客园 - Franky
K
Kaspersky official blog
Hugging Face - Blog
Hugging Face - Blog
IT之家
IT之家
www.infosecurity-magazine.com
www.infosecurity-magazine.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cisco Blogs

博客园 - Zhentiw

[GenAI] Migration Plan: Flat API → Layered Architecture [Skill] Frontend Design Skill Claude Code Hooks: Complete Guide [GenAI] Pre-retieval overview [GenAI] About Indexing [GenAI] Indexing overview [Vibe coding] 降低大模型幻觉 - JSON 安全输出提示词 [Node.js] WebSocket基础知识 [LangGraph] 应用结构 [LangGrpah] Unit testing [LangGraph] Functional API [LangGraph] 中断注意事项 [LangGraph] 中断相关细节 [LangGrpah] 静态断点 [LangGrpah] 非阻塞式中断 [LangGraph] 阻塞式中断 [LangGraph] 语义搜索 [LangGraph] 长期记忆 [LangGraph] 管理短期记忆 [LangGraph] 自定义checkpointer [LangGraph] 短期记忆 [LangGraph] 时间旅行 [LangGraph] checkpoint常用API [LangGraph] 元数据标记 [LangGraph] 流 [Vitest] mockClear, mockReset, mockRestore [LangGraph] 将子图添加为节点
[Vibe Coding] 降低大模型幻觉 - 重试机制
Zhentiw · 2026-05-03 · via 博客园 - Zhentiw
/**
 * 带重试的 LLM 调用执行器
 *
 * 默认行为:重试时自动将错误信息反馈给 LLM,让它能够根据错误修正输出
 *
 * @param model 可调用的模型(需要有 invoke 方法)
 * @param messages 初始消息数组
 * @param options 重试配置
 * @returns 执行结果
 *
 * @example
 * const result = await withRetry(structuredModel, messages, {
 *   maxRetries: 3,
 *   onRetry: (attempt, error) => console.warn(`Retry ${attempt}:`, error.message)
 * });
 */
export async function withRetry<T>(
  model: InvokableModel<T>,
  messages: any[],
  options: RetryOptions = {},
): Promise<T> {
  const {
    maxRetries = DEFAULT_MAX_RETRIES,
    onRetry,
    formatErrorFeedback = defaultErrorFeedback,
  } = options;

  let lastError: Error | null = null;
  let currentMessages = [...messages];

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await model.invoke(currentMessages);
    } catch (error) {
      lastError = error instanceof Error ? error : new Error(String(error));

      if (attempt < maxRetries) {
        onRetry?.(attempt, lastError);
        // 追加错误反馈消息用于下次重试
        currentMessages = [
          ...messages,
          new HumanMessage(formatErrorFeedback(lastError)),
        ];
      }
    }
  }

  throw lastError;
}

Usage

  // ========== 3. AI 命名调用 ==========
  const structuredModel = getStructuredModel(SectionNamingOutputSchema);

  const messages = [
    new SystemMessage(getSectionNamingSystemPrompt()),
    new HumanMessage(getSectionNamingHumanPrompt(sectionsInfo)),
  ];

  console.log("⏳ [SectionNamingNode] 正在调用 AI 命名...");

  let result: T_SectionNamingOutput;

  try {
    result = await withRetry(structuredModel, messages, {
      maxRetries: 2,
      onRetry: (attempt, error) => {
        console.warn(
          `⚠️ [SectionNamingNode] 命名重试 ${attempt}: ${error.message}`,
        );
      },
    });
  } catch (error) {
    console.error("❌ [SectionNamingNode] AI 命名失败:", error);
    // Fallback: 使用默认命名
    console.log("⚠️ [SectionNamingNode] 使用默认命名作为 fallback");
    result = {
      namedSections: sections.map((s, i) => ({
        index: s.index,
        componentName: `Section${i + 1}`,
        description: `页面第 ${i + 1} 区域,包含 ${s.totalBlocks} 个元素`,
        fileName: `Section${i + 1}`,
      })),
    };
  }