Agent 项目从开发到上线的完整 checklist:50 个你可能会漏掉的关键项
Agent 项目从开发到上线的完整 checklist50 个你可能会漏掉的关键项一、深度引言与场景痛点大家好我是赵咕咕。过去一年我参与和旁观了不下 20 个 Agent 项目的上线。有一个规律非常一致出问题的永远不是你预料到的部分而是你觉得这个肯定没问题所以没检查的部分。Agent 项目跟传统 Web 服务有一个本质区别Web 服务的输入输出是相对可控的Agent 的输出取决于 LLM 的推理——它可能调错工具、可能陷入死循环、可能被 prompt injection 攻击、可能一次推理吃掉 $5 的 API 费用。这篇文章我整理了一份 Agent 项目从开发到上线的 50 个检查项。按项目阶段分为五个板块架构设计、开发实现、Prompt 工程、安全与成本、运维监控。每个阶段 10 个检查项。这不是一份建议参考的列表——是上线前必须逐条确认的 hard checklist。二、底层机制与原理深度剖析五个阶段不是线性推进的——你会在 Prompt 工程阶段发现架构设计的问题或者在安全审查时发现开发实现的问题。所以这是一个循环迭代的过程每一轮过一遍整个 checklist。三、生产级代码实现下面是一个 Agent 项目的 checklist 自动检查框架import asyncio import json import logging from dataclasses import dataclass, field from enum import Enum from typing import Any, Callable logger logging.getLogger(__name__) # ── Checklist 数据模型 ───────────────────────────────── class CheckStatus(Enum): PASS pass FAIL fail SKIP skip PENDING pending class Phase(Enum): ARCHITECTURE architecture DEVELOPMENT development PROMPT prompt SECURITY security OPERATIONS operations dataclass class CheckItem: 单个检查项。 id: str phase: Phase title: str description: str check_fn: str # 检查函数名 status: CheckStatus CheckStatus.PENDING note: str # ── 50 个检查项定义 ──────────────────────────────────── CHECKLIST: list[CheckItem] [ # ═══ 架构设计 (10项) ═══ CheckItem(ARC-01, Phase.ARCHITECTURE, 系统边界定义, Agent 的输入输出边界是否明确定义哪些功能在 Agent 内实现哪些交给外部服务), CheckItem(ARC-02, Phase.ARCHITECTURE, 工具集最小化, Agent 暴露的工具是否是最小必要集合每多加一个工具都会增加推理复杂度。), CheckItem(ARC-03, Phase.ARCHITECTURE, 记忆架构选择, 使用哪种记忆方案Buffer/Summary/VectorStore记忆是否跨会话保持), CheckItem(ARC-04, Phase.ARCHITECTURE, 错误恢复策略, 工具调用失败时 Agent 如何处理重试/降级/告知用户), CheckItem(ARC-05, Phase.ARCHITECTURE, 多 Agent 协作, 是否需要多 Agent如果需要通信协议是 MCP 还是自定义), CheckItem(ARC-06, Phase.ARCHITECTURE, 状态持久化, Agent 的对话历史和工具调用状态存储在哪里Redis/Postgres/内存), CheckItem(ARC-07, Phase.ARCHITECTURE, API 契约定义, Agent 对外暴露的 API 是否定义了请求/响应 schema 和错误码), CheckItem(ARC-08, Phase.ARCHITECTURE, 水平扩展评估, 是否需要多实例部署如果需要会话亲和性如何保证), CheckItem(ARC-09, Phase.ARCHITECTURE, 外部依赖可用性, 依赖的外部 APILLM/搜索引擎/数据库宕机时Agent 是否降级), CheckItem(ARC-10, Phase.ARCHITECTURE, 降级方案, 目标 LLM 不可用时是否有 fallback 模型降级后的能力衰减是否可接受), # ═══ 开发实现 (10项) ═══ CheckItem(DEV-01, Phase.DEVELOPMENT, 全链路异步, 所有 IO 操作是否都用 async/await有没有同步代码块阻塞事件循环), CheckItem(DEV-02, Phase.DEVELOPMENT, 超时控制, 单次 Agent 推理、单次工具调用、单次 LLM API 调用是否都设置了超时), CheckItem(DEV-03, Phase.DEVELOPMENT, 重试机制, LLM API 调用是否配置了指数退避重试重试次数上限是否合理), CheckItem(DEV-04, Phase.DEVELOPMENT, 结构化日志, 日志是否包含 trace_id、session_id、tool_name、latency、token 消耗), CheckItem(DEV-05, Phase.DEVELOPMENT, 幂等性保证, 工具调用是否幂等用户重复提交同一请求是否产生副作用), CheckItem(DEV-06, Phase.DEVELOPMENT, 流式输出, 是否支持 SSE 流式推送前后端是否对接好了事件类型), CheckItem(DEV-07, Phase.DEVELOPMENT, 会话生命周期, 会话的创建、查询、过期、删除是否完整过期会话是否自动清理), CheckItem(DEV-08, Phase.DEVELOPMENT, 配置外部化, LLM 参数、工具列表、超时时间是否外部化环境变量/配置中心), CheckItem(DEV-09, Phase.DEVELOPMENT, 代码依赖管理, 依赖是否锁定了版本是否定期扫描安全漏洞), CheckItem(DEV-10, Phase.DEVELOPMENT, 单元集成测试, 核心工具函数是否有测试Agent 的 happy path 是否有集成测试), # ═══ Prompt 工程 (10项) ═══ CheckItem(PRM-01, Phase.PROMPT, 角色边界清晰, System Prompt 是否明确你是什么/你能做什么/你不能做什么), CheckItem(PRM-02, Phase.PROMPT, 工具描述可测试, 每个工具的描述是否包含功能说明、参数解释、返回值格式、使用示例), CheckItem(PRM-03, Phase.PROMPT, Few-Shot 覆盖边界, 是否提供 3-5 个覆盖常见场景和异常场景的示例), CheckItem(PRM-04, Phase.PROMPT, 幻觉防护机制, Prompt 中是否明确要求不确定时告知用户不要编造), CheckItem(PRM-05, Phase.PROMPT, 多语言处理, 是否处理了多语言输入System Prompt 是否指定了回复语言), CheckItem(PRM-06, Phase.PROMPT, 上下文窗口管理, 是否主动管理 token 预算长对话是否压缩/截断历史), CheckItem(PRM-07, Phase.PROMPT, 输出格式约束, 是否定义了输出格式JSON/Markdown并要求验证), CheckItem(PRM-08, Phase.PROMPT, 语气与品牌一致, 回复语气是否符合产品调性是否避免了技术黑话), CheckItem(PRM-09, Phase.PROMPT, 版本与回滚, Prompt 是否有版本管理能否快速回滚到上一个验证版本), CheckItem(PRM-10, Phase.PROMPT, 评估数据集, 是否有 50 条标注好的评估数据集每次 Prompt 变更是否跑评估), # ═══ 安全与成本 (10项) ═══ CheckItem(SEC-01, Phase.SECURITY, API Key 管理, 所有密钥是否通过 Secrets Manager 管理是否支持轮转是否有审计日志), CheckItem(SEC-02, Phase.SECURITY, Prompt 注入防御, 是否过滤了 忽略以上指令 SYSTEM OVERRIDE 等注入攻击), CheckItem(SEC-03, Phase.SECURITY, PII 数据脱敏, 日志和监控中是否过滤了电话号码、邮箱、身份证等个人敏感信息), CheckItem(SEC-04, Phase.SECURITY, 用户级速率限制, 是否对每个用户做了速率限制超出限制的请求返回 429 还是排队), CheckItem(SEC-05, Phase.SECURITY, Token 预算告警, 是否设置了单用户每日/每月的 Token 消耗上限超出是否告警), CheckItem(SEC-06, Phase.SECURITY, 成本追踪, 是否能追踪每次对话的成本是否有按用户/部门/项目的成本报表), CheckItem(SEC-07, Phase.SECURITY, 工具调用权限, Agent 调用的工具是否经过权限验证用户 A 能否通过 Agent 访问用户 B 的数据), CheckItem(SEC-08, Phase.SECURITY, 操作审计日志, Agent 执行的每步工具调用是否记录在审计日志中包含时间、用户、参数、结果), CheckItem(SEC-09, Phase.SECURITY, 内容安全, 用户输入和 Agent 输出是否经过内容安全审核涉黄涉政涉暴是否拦截), CheckItem(SEC-10, Phase.SECURITY, 合规要求, 数据处理是否符合 GDPR/PIPL 要求是否支持用户数据删除请求), # ═══ 运维监控 (10项) ═══ CheckItem(OPS-01, Phase.OPERATIONS, 健康检查端点, 是否有 /health 端点是否检查了 LLM API 和工具服务的连通性), CheckItem(OPS-02, Phase.OPERATIONS, 延迟分位数监控, 是否监控 P50/P95/P99 延迟首次 token 时间和完整响应时间分别监控), CheckItem(OPS-03, Phase.OPERATIONS, 错误率告警, LLM 调用失败率、工具调用失败率、超时率是否配置了告警阈值), CheckItem(OPS-04, Phase.OPERATIONS, Token 消耗看板, 是否有实时的 Token 消耗量、费用预估、趋势图 Dashboard), CheckItem(OPS-05, Phase.OPERATIONS, 工具调用分析, 是否统计各工具的调用频率、成功率、P95 延迟是否定期清理低效工具), CheckItem(OPS-06, Phase.OPERATIONS, 用户反馈闭环, 是否提供点赞/点踩/举报反馈机制反馈是否关联到具体对话), CheckItem(OPS-07, Phase.OPERATIONS, 灰度发布策略, 新版本上线是否按 5% → 20% → 50% → 100% 灰度是否有关键指标监控), CheckItem(OPS-08, Phase.OPERATIONS, 回滚方案, 回滚到上一版本的完整步骤是否文档化回滚操作能否一键完成), CheckItem(OPS-09, Phase.OPERATIONS, 容量规划, 当前配置能支撑多少并发高峰期的扩容方案是什么), CheckItem(OPS-10, Phase.OPERATIONS, 运维 Runbook, 常见故障LLM API 限流、工具服务宕机、内存泄漏的排查和处理步骤是否文档化), ] # ── Checklist 执行引擎 ───────────────────────────────── class ChecklistRunner: 自动执行并报告 Checklist 的引擎。 def __init__(self): self._items CHECKLIST self._checkers: dict[str, Callable] {} def register_checker(self, name: str, fn: Callable) - None: 注册自定义检查函数。 self._checkers[name] fn async def run_phase(self, phase: Phase) - list[dict]: 执行某个阶段的全部检查。 items [it for it in self._items if it.phase phase] results [] for item in items: logger.info(执行检查: %s - %s, item.id, item.title) try: if item.check_fn in self._checkers: passed await self._checkers[item.check_fn]() item.status CheckStatus.PASS if passed else CheckStatus.FAIL else: # 没有注册检查函数的标记为 SKIP手动确认 item.status CheckStatus.SKIP item.note 需手动确认 except Exception as e: item.status CheckStatus.FAIL item.note f检查异常: {str(e)[:100]} results.append({ id: item.id, title: item.title, phase: item.phase.value, status: item.status.value, note: item.note, }) return results async def run_all(self) - dict[str, Any]: 执行全部五个阶段的检查。 all_results {} for phase in Phase: all_results[phase.value] await self.run_phase(phase) stats self._calculate_stats() return { results: all_results, summary: stats, timestamp: __import__(datetime).datetime.now().isoformat(), } def _calculate_stats(self) - dict[str, Any]: 计算统计信息。 counts {s.value: 0 for s in CheckStatus} phase_stats {} for item in self._items: counts[item.status.value] 1 if item.phase.value not in phase_stats: phase_stats[item.phase.value] {s.value: 0 for s in CheckStatus} phase_stats[item.phase.value][item.status.value] 1 total len(self._items) passed counts[pass] failed counts[fail] return { total: total, pass: passed, fail: failed, skip: counts[skip], pass_rate: f{passed / total * 100:.1f}% if total 0 else 0%, ready_for_production: failed 0, by_phase: phase_stats, } def generate_report(self, results: dict) - str: 生成 Markdown 格式的检查报告。 summary results[summary] lines [ f# Agent 项目上线 Checklist 报告, f, f**检查时间**: {results[timestamp]}, f**总计**: {summary[total]} 项, f**通过**: {summary[pass]} 项, f**失败**: {summary[fail]} 项, f**跳过**: {summary[skip]} 项, f**通过率**: {summary[pass_rate]}, f**可上线**: {是 if summary[ready_for_production] else 否——存在未通过的检查项}, f, ] for phase in Phase: phase_key phase.value phase_name { architecture: 架构设计, development: 开发实现, prompt: Prompt 工程, security: 安全与成本, operations: 运维监控, }.get(phase_key, phase_key) lines.append(f## {phase_name}) lines.append() phase_results results[results].get(phase_key, []) for r in phase_results: icon {pass: :white_check_mark:, fail: :x:, skip: :grey_question:}[r[status]] lines.append(f- {icon} **{r[id]}** {r[title]}) if r.get(note): lines.append(f - 备注: {r[note]}) lines.append() return \n.join(lines) # ── 快速自动化检查示例 ───────────────────────────────── async def check_env_variables() - bool: 检查必需的环境变量是否设置。 required [ OPENAI_API_KEY, SECRETS_BACKEND, ] import os missing [k for k in required if not os.getenv(k)] if missing: logger.warning(缺少环境变量: %s, missing) return False return True async def check_async_code() - bool: 检查是否存在阻塞调用。 # 简化实现检查主要入口点是否是 async 函数 import glob py_files glob.glob(*.py) # 实际项目中可以用 AST 分析器扫描同步阻塞调用 return len(py_files) 0 async def main(): runner ChecklistRunner() # 注册自动化检查函数 runner.register_checker(check_env_variables, check_env_variables) runner.register_checker(check_async_code, check_async_code) # 执行检查 results await runner.run_all() # 生成报告 report runner.generate_report(results) # 保存报告 from pathlib import Path Path(./checklist_report.md).write_text(report, encodingutf-8) print(f通过率: {results[summary][pass_rate]}) print(f可上线: {是 if results[summary][ready_for_production] else 否}) print(f报告已保存到 checklist_report.md) if __name__ __main__: asyncio.run(main())这个框架的设计思路声明式 50 项检查每一项有 ID、阶段、标题、描述和检查函数。新增检查项只需要加一行。可插拔的检查函数register_checker注册自定义检查逻辑。有些检查可以全自动环境变量是否设置有些需要人工确认架构设计是否合理。按阶段执行可以单独跑某个阶段的检查如只跑安全审计也可以全量跑。灵活匹配不同项目阶段。Markdown 报告生成的报告直接可以用来做上线评审的材料。四、边界分析与架构权衡4.1 哪些检查可以完全自动化自动化程度检查类型示例全自动环境变量检查SEC-01 API Key 存在于 Secrets Manager全自动代码扫描DEV-01 是否存在同步阻塞调用半自动日志格式DEV-04 日志包含 trace_id但需要人工确认字段完整性半自动测试覆盖DEV-10 代码覆盖率 70%但需要人工 review 测试质量人工架构设计ARC-03 记忆架构选择是否合理人工合规审核SEC-10 GDPR/PIPL 合规需要法务确认自动化不是替代人是帮人聚焦需要判断力的部分。4.2 什么时候用这个 checklist开发阶段每完成一个 Phase 跑一次对应的 checklist尽早发现问题。上线前评审全量跑一次全部通过才能上线。未通过的要有明确的修复计划。上线后定期审计每月跑一次安全和运维阶段的检查确保没有退化。事故复盘后每次线上事故复盘完检查一下对应的检查项是否覆盖了这次事故的根因。没覆盖就加一项。4.3 对于小型项目的裁剪如果是个人项目或 MVP不需要 50 项全检。建议最小必检集ARC-04错误恢复、ARC-10降级方案DEV-02超时控制、DEV-03重试PRM-04幻觉防护、PRM-07输出格式SEC-01密钥管理、SEC-04速率限制OPS-01健康检查、OPS-03错误告警这 10 项是最容易导致上线翻车的点。先把这 10 项做到位再逐步补齐其余 40 项。4.4 Checklist 的维护这份 checklist 不是一成不变的。LLM 能力在进化推理增强、工具调用改进安全威胁在演变新的 prompt injection 技术你的团队经验在增长。建议每三个月 review 一次 checklist——有没有不再适用的项、有没有新的高优先级检查需要加入。把 checklist 当成代码一样维护版本化管理。五、总结Agent 项目上线跟传统 Web 项目有一个关键差异Agent 的行为不完全可控检查清单是降低不确定性的重要手段。三件事最重要安全与成本放在同优先级Agent 的成本是累积的——一次死循环推理可能吃掉 $5。速率限制和 Token 预算不是锦上添花是上线硬条件。Prompt 的版本管理不等同于代码的版本管理一次 Prompt 修改可能导致 Agent 行为发生质变工具选择错误率从 15% 跳到 35%。Prompt 必须有独立的评估数据集和回滚策略。运维不能缺位你以为Agent 上线后就没事了工具 API 可能会改LLM 供应商可能会限流用户可能会触发你没见过的边缘 case。监控、告警、Runbook 一个都不能少。这份 checklist 是我踩坑踩出来的经验汇总。逐条过一遍上线时少一份卧槽的惊喜。多一份一切尽在掌控的从容。这是第 4 周0726最后一篇文章。四周的产出告一段落下周继续。写代码要快乐谢谢大家。