非官方社区教程 · 内容整理自公开资料 · 豆包工作为字节跳动产品,本站与官方无关
豆包工作教程
首页/ 可靠性工程/基础可靠性与错误处理

基础可靠性与错误处理

---

章节:入门篇第4章
难度:⭐ 入门级
阅读时间:15-20 分钟
核心收获:掌握基础错误处理机制,学会配置重试和告警


7.1 理论要点:错误是常态,不是例外

7.1.1 自动化任务的错误分类

错误类型 发生概率 影响程度 处理策略
临时性故障 自动重试
永久性故障 转人工处理
输入错误 立即告警
配置错误 极低 立即告警

7.1.2 临时性 vs 永久性故障

临时性故障(可重试): - 网络超时 - API 限流(429) - 服务暂时不可用 - 推送目标暂时不可达

永久性故障(不可重试): - API Key 过期(401/403) - 数据源已下线 - 推送目标已删除 - Prompt 语法错误

7.1.3 错误处理三原则

  1. 快速失败:检测到错误立即处理,不拖延
  2. 保留现场:记录错误信息,便于排查
  3. 可追溯:每个错误都有批次 ID 和时间戳

7.2 实战案例:配置重试和告警

7.2.1 场景:数据源 API 超时

问题:GitHub API 偶尔超时,导致整个任务失败。

解决方案

1. 设置超时阈值:10秒
2. 重试策略:等待10秒后重试1次
3. 仍失败:标记为"缺失",继续其他数据源
4. 记录日志:包含超时次数和最终状态

豆包 Prompt 配置

如果某个数据源超时,请:
1. 等待10秒后重试一次
2. 如果仍超时,标记为"缺失"
3. 继续处理其他数据源
4. 在输出顶部标注哪些来源缺失

7.2.2 场景:API 限流

问题:频繁调用导致 API 限流(429)。

解决方案

1. 检测 429 响应
2. 读取 Retry-After 头
3. 按指定时间等待
4. 最多重试2次
5. 仍限流:标记为"缺失"

豆包 Prompt 配置

如果某个数据源返回429限流:
1. 读取响应头中的 Retry-After 时间
2. 按该时间等待后重试
3. 最多重试2次
4. 如果仍限流,标记为"缺失"并继续

7.2.3 场景:推送失败

问题:飞书群暂时不可达,推送失败。

解决方案

1. 第一次失败:立即重试
2. 第二次失败:等待30秒后重试
3. 第三次失败:发送告警,保留结果
4. 记录 message_id(如有)

豆包 Prompt 配置

如果推送失败:
1. 立即重试1次
2. 如果仍失败,等待30秒后重试1次
3. 如果仍失败,发送告警并保留结果
4. 记录失败原因和错误信息

7.3 告警配置

7.3.1 告警分级

级别 定义 处理方式 通知渠道
P0 - 紧急 所有数据源失效,任务完全失败 立即处理 飞书 + 短信
P1 - 高 推送失败,结果未送达 30分钟内处理 飞书
P2 - 中 部分数据源失效,降级运行 4小时内处理 飞书
P3 - 低 成本超限,提示注意 24小时内处理 飞书

7.3.2 告警内容模板

P0 告警

🚨 紧急:AI热点选题任务完全失败

批次:ai-hotspot-2026-07-10
触发时间:09:00
失败原因:所有数据源均返回空结果或超时
已完成步骤:fetching(全部失败)
影响:今日热点清单未生成,未推送

建议处理:
1. 检查各数据源 API 状态
2. 检查网络连接
3. 手动触发一次任务重跑

恢复入口:WorkBuddy → 自动化任务 → 手动运行

P1 告警

⚠️ 推送失败:AI热点选题任务结果未送达

批次:ai-hotspot-2026-07-10
触发时间:09:00
失败原因:飞书群暂时不可达
已完成步骤:fetching → aggregating → filtering → delivering(失败)
影响:清单已生成,但未推送

建议处理:
1. 检查飞书群状态
2. 手动重试推送
3. 或切换到备用推送目标

状态文件:已保留,可从 delivering 继续

P2 告警

⚠️ 降级运行:AI热点选题任务部分数据源失效

批次:ai-hotspot-2026-07-10
触发时间:09:00
数据源状态:
- 微信公众号:正常
- GitHub:正常
- 多引擎搜索:缺失(超时)
- AIHOT:缺失(超时)

影响:清单基于2个来源生成,可能遗漏部分热点
建议:手动检查其他数据源补充

P3 告警

💰 成本提醒:AI热点选题任务单次成本超限

批次:ai-hotspot-2026-07-10
触发时间:09:00
Token消耗:2500(预算上限:2000)
成本估算:约 ¥0.15(预算:¥0.10)

建议:
1. 检查是否有异常消耗
2. 考虑优化 Prompt 长度
3. 或调整数据源配置

7.4 错误处理代码示例

7.4.1 Python 伪代码

import time
import json
from datetime import datetime

class AutomationTask:
    def __init__(self, config):
        self.config = config
        self.state = {
            "batch_id": self.generate_batch_id(),
            "trigger_time": datetime.now().isoformat(),
            "state": "idle",
            "completed": [],
            "source_status": {},
            "item_count": 0,
            "last_error": None,
            "updated_at": datetime.now().isoformat()
        }

    def generate_batch_id(self):
        return f"ai-hotspot-{datetime.now().strftime('%Y-%m-%d')}"

    def save_state(self):
        """保存状态文件"""
        with open(f"state/{self.state['batch_id']}.json", "w") as f:
            json.dump(self.state, f, indent=2)

    def fetch_with_retry(self, source_name, source_config):
        """带重试的数据源获取"""
        max_retries = 1
        for attempt in range(max_retries + 1):
            try:
                response = call_api(source_config["url"], timeout=10)

                if response.status == 429:
                    if attempt < max_retries:
                        wait_time = parse_retry_after(response)
                        time.sleep(wait_time)
                        continue
                    return "rate_limited"

                if response.status in [401, 403]:
                    return "auth_failed"

                if response.empty:
                    return "empty"

                return "ok", response.data

            except Timeout:
                if attempt < max_retries:
                    time.sleep(10)
                    continue
                return "timeout"

        return "failed"

    def run(self):
        """主执行流程"""
        try:
            # 1. 数据源检查
            self.state["state"] = "source_check"
            sources_status = {}
            for name, config in self.config["sources"].items():
                status = self.fetch_with_retry(name, config)
                sources_status[name] = status

            ok_count = sum(1 for s in sources_status.values() if s == "ok")
            if ok_count < self.config["minimum_sources"]:
                self.state["state"] = "blocked"
                self.state["last_error"] = f"数据源不足:{ok_count}/{len(sources_status)}"
                self.save_state()
                self.send_alert("P0", self.state["last_error"])
                return

            # 2. 聚合
            self.state["state"] = "aggregating"
            self.state["completed"].append("source_check")
            items = self.aggregate(sources_status)

            # 3. 过滤
            self.state["state"] = "filtering"
            self.state["completed"].append("aggregating")
            filtered_items = self.filter(items)

            if len(filtered_items) < self.config["minimum_items"]:
                self.state["state"] = "blocked"
                self.state["last_error"] = f"有效条目不足:{len(filtered_items)}/{self.config['minimum_items']}"
                self.save_state()
                self.send_alert("P2", self.state["last_error"])
                return

            # 4. 推送
            self.state["state"] = "delivering"
            self.state["completed"].append("filtering")
            self.state["item_count"] = len(filtered_items)

            success = self.deliver(filtered_items)
            if not success:
                self.state["state"] = "blocked"
                self.state["last_error"] = "推送失败"
                self.save_state()
                self.send_alert("P1", self.state["last_error"])
                return

            # 5. 完成
            self.state["state"] = "completed"
            self.state["completed"].append("delivering")
            self.save_state()

        except Exception as e:
            self.state["state"] = "blocked"
            self.state["last_error"] = str(e)
            self.save_state()
            self.send_alert("P0", str(e))

    def deliver(self, items):
        """推送结果"""
        for attempt in range(3):
            try:
                result = send_to_feishu(items)
                return True
            except Exception as e:
                if attempt < 2:
                    time.sleep(30 * (attempt + 1))
                    continue
                return False

7.5 图文说明

📌 待补充:建议绘制以下示意图 1. 错误分类矩阵图(临时性 vs 永久性) 2. 重试策略流程图 3. 告警分级金字塔图 4. 错误处理代码逻辑图


7.6 常见错误

错误 后果 纠正方法
所有错误都重试 认证失效也重试,浪费成本 区分临时故障和永久故障
重试无退避 对限流服务造成更大压力 429 时按 Retry-After 等待
告警级别混乱 紧急告警被忽略 明确分级标准和处理时限
不记录错误信息 无法排查根因 记录完整错误栈和上下文
重试次数过多 成本失控 限制重试次数,超出则告警

📝 版本迭代记录

版本 日期 更新内容摘要 操作人
v1.0 2026-08-25 创建入门篇第4章 桂皮
来源:豆包蓝皮书(未声明(社区整理)) · 原文路径 01-入门篇/04-基础可靠性与错误处理/01-错误分类与处理原则.md
整理:疯狂的豇豆 · 本站为非官方二次整理,查看完整来源清单
🤖 GEO 问答 · 生成式引擎优化

❓ 什么是基础可靠性与错误处理?


❓ 如何理解理论要点:错误是常态,不是例外?

  1. 快速失败:检测到错误立即处理,不拖延

❓ 如何理解实战案例:配置重试和告警?

  1. 设置超时阈值:10秒

❓ 如何理解告警配置?

🚨 紧急:AI热点选题任务完全失败