实用笔记:我开发了一个能解决生产环境问题的自主式SRE代理
《实用笔记》操作指南:我开发了一个能够解决生产环境问题的自主 SRE 工具,为采用该模式的团队提供了相关契约、检查项以及可直接使用的代码片段。
本指南将逐步构建从原材料到可运行系统的完整流程,内容为《我打造了一个能在我睡觉时自动处理生产故障的SRE代理》。重点在于可操作的步骤、明确的检查点,以及可直接放入代码库而无需猜测其用途的代码。 在概览阶段,应在修改代码之前明确输入参数、该步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测其中的隐藏状态。 建议使用小型、可测试的单元而非庞大的脚本。当某个步骤失败时,故障应能指向单一责任点,而非复杂的流程链。
GitHub代码库
在处理 GitHub 代码库阶段时,首先需写下契约:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 将此阶段视为输入与验证后输出之间的契约。为相关成果命名,明确成功判定标准,并杜绝无声的半完成状态。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的大型语言模型。
为何选择 ReAct,又为何选择 LangGraph
在处理“Why ReAct”和“Why”阶段时,首先写下相关契约:所需的输入、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 在功能结果旁记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。 在耗时较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次收取相同的LLM调用费用。
四层记忆结构
在处理“四层记忆”阶段时,首先需明确相关规范:所需输入、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,以便操作员无需查看整个系统结构即可进行审计。 在耗时较高的步骤之后设置检查点。当操作员重新执行后续节点时,恢复流程不应再次调用相同的大型语言模型接口。 在处理“四层记忆”阶段时,首先需明确相关规范:所需输入、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 相较于庞大的脚本,应优先使用小型且可测试的单元。当某个步骤失败时,故障应能指向具体的责任模块,而非整个复杂的流程。
情景记忆的实际运作机制
将情景记忆的这一阶段视为可测量的界面来处理效果最佳。在扩大范围之前,先记录一个成功的案例、一个失败案例以及回滚说明。 把这一阶段视为输入与经过验证的输出之间的契约。为相关成果命名,明确成功标准,绝不允许出现无声的半完成状态。 保持图表状态的简洁性与类型一致性。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,且在中断后会导致无法继续处理。
自主系统:L0至L3
将自治系统L0阶段视为可测量的对象时,其性能表现最佳。在扩大应用范围之前,先记录一份理想的运行日志、一个故障案例以及回滚说明。在功能结果旁同时记录执行时间以及令牌或查询成本。提前了解这些成本信息,就能避免在系统从演示环境过渡到共享环境时出现意外费用。需保持图结构的状态简洁且类型明确,否则嵌套的数据块会掩盖具体是哪个节点修改了哪一字段,且在中断后还会导致程序无法继续运行。
完整的工具集
将“完整工具库”阶段视为可度量的界面来使用效果最佳。在扩大范围之前,先记录一份理想状态下的操作日志、一个故障案例以及回滚说明。 应将配置与应用程序代码分开。环境文件、密钥存储和功能开关应集中存放,以便操作人员无需查看整个系统结构即可进行审计。 需为工具提供结构明确的架构以及清晰的副作用标签。主机需要在自动批准之前知道哪些调用会改变系统状态。 将“完整工具库”阶段视为可度量的界面来使用效果最佳。在扩大范围之前,先记录一份理想状态下的操作日志、一个故障案例以及回滚说明。 相比庞大的脚本,更应优先使用小型且可测试的单元。当某个步骤出现故障时,故障原因应能指向单一责任模块,而非复杂的流程链。
ReAct循环的实际应用
在实施 ReAct 循环阶段时,应在修改代码之前明确输入参数、各步骤的负责人以及退出标准。操作人员应能够从已知的检查点重新运行相应步骤,而无需猜测隐藏状态。 将此阶段视为输入与已验证输出之间的契约。为相关成果命名,定义成功判定标准,杜绝默许的半完成状态。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务上的完整性。
[MEMORY] Loading episodic context for payment-service...
[MEMORY] Found 2 similar past incidents (similarity: 0.89, 0.76)
[MEMORY] Loaded 3 procedural policies for payment-service/critical
[THOUGHT] Incident: payment-service OOMKill, 3 pods CrashLooping.
Past incident INC-2801 had identical symptoms — root cause was
a memory leak in the gRPC connection pool after a deploy.
Starting with get_logs to confirm before acting.
[ACTION] Calling tool: get_logs with {'service_name': 'payment-service', 'log_level': 'error'}
→ top_errors: [{"pattern": "out of memory: kill process", "count": 47},
{"pattern": "grpc connection pool exhausted", "count": 23}]
[THOUGHT] OOM confirmed. gRPC pool exhaustion matches INC-2801 pattern.
Retrieve runbook before acting — want the fix procedure.
[ACTION] Calling tool: retrieve_runbook with {'query': 'payment service grpc oom memory leak fix'}
→ [runbooks / payment-service-oom.md] Recommended action: rolling restart
resets connection pool. If recurs within 1h, rollback to previous image.
[THOUGHT] Runbook confirms rolling restart. Checking policy for autonomy L2...
[ACTION] Calling tool: restart_deployment with {'service': 'payment-service',
'deployment': 'payment-worker', 'namespace': 'production',
'severity': 'critical', 'autonomy_level': 'L2'}
→ policy: ALLOWED (L2 ≥ min_level L2 for restart_deployment)
→ draining pods... restarting... polling rollout...
→ health_check: healthy=True, pods_ready=3/3, error_rate=0.008
[THOUGHT] Restart succeeded. Error rate 0.8% — below 5% threshold.
Verifying with check_service_health before closing.
[ACTION] Calling tool: check_service_health with {'service': 'payment-service',
'deployment': 'payment-worker', 'namespace': 'production'}
→ healthy=True, pods_total=3, pods_ready=3, error_rate=0.007
[THOUGHT] Service fully recovered. Writing audit log and resolving.
[ACTION] Calling tool: write_audit_log ...
→ audit_log written: restart_deployment for incident INC-2847
RESOLVED: payment-service recovered after rolling restart. Root cause: gRPC
connection pool OOM — matched pattern from INC-2801. All 3 pods healthy,
error rate 0.7%. MTTR: 187 seconds.
[MEMORY] Saving incident INC-2847 to episodic memory...
[NOTIFY] Sending resolution to Slack channel: #all-aegisops ✅
Invoke-RestMethod -Uri "http://localhost:8000/webhook/incident" `
-Method Post `
-ContentType "application/json" `
-Body '{
"source": "webhook",
"severity": "critical",
"service": "payment-service",
"symptoms": ["High 500 errors", "DB connection timeouts"],
"autonomy_level": "L2"
}'
Slack 频道的样子
在 Slack 频道阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外账单。对于会产生费用或修改生产数据的操作,必须经过人工审批。仅靠编译时的配置并不足以确保业务的完整性。
基础设施栈
在基础设施堆栈阶段,修改代码之前需明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储和功能标志应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审计。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务功能的完整性。 在基础设施堆栈阶段,修改代码之前需明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 相较于庞大的脚本,应优先使用小型且可测试的单元。当某个步骤失败时,故障原因应能明确指向单一责任模块,而非复杂的整体问题。
流水线。
version: "3.9"
services:
postgres:
image: ankane/pgvector:latest
ports:
- "5445:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: admin123
POSTGRES_DB: aegisops
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:alpine
ports:
- "6380:6379"
app:
build: .
ports:
- "8000:8000"
env_file: .env
depends_on:
- postgres
- redis
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./infra/prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
volumes:
postgres_data:
审计追踪
在处理审计追踪阶段时,首先写下合同条款:所需的输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持透明。 将此阶段视为输入与已验证输出之间的契约。为相关成果命名,定义成功检查标准,并拒绝默许的部分完成。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的大型语言模型。
下一步是什么
在处理“下一步计划”阶段时,首先写下相关契约:所需的输入参数、成功标志,以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 在功能结果旁记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。 在耗时较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次收取相同的LLM调用费用。
总结
在完成“最终思考”阶段时,首先需写明相关规范:所需的输入参数、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 应将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中于一个位置,以便操作员无需查看整个系统结构即可进行审计。 在耗时较高的步骤之后设置检查点。当操作员重新执行后续节点时,恢复流程不应再次调用相同的大型语言模型接口。 在完成“最终思考”阶段时,首先需写明相关规范:所需的输入参数、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 相比庞大的脚本,更应优先使用小型且可测试的单元。当某个步骤失败时,故障原因应能明确指向某个具体的功能模块,而非整个复杂的流程。
关于本项目
“关于此项目”阶段若被视为可度量的工作面,效果最佳。在扩大范围之前,需记录一份理想状态下的流程记录、一个故障案例以及回滚说明。
操作检查清单
“操作检查清单”阶段若被视为可度量的工作面,效果最佳。在扩大范围之前,需记录一份理想状态下的流程记录、一个故障案例以及回滚说明。
需同时记录正常流程与恢复流程。重试机制、人工审核环节以及错误处理方式都是产品的一部分,而非后续需要补充的内容。
保持图结构的状态扁平且具有类型约束。嵌套的数据块会掩盖是哪个节点修改了哪个字段,还会在任务中断后导致无法继续执行。
只要预算允许,就在持续集成过程中使用测试桩而非真实的付费 API 来执行关键路径的冒烟测试。
应优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应能指向单一的责任模块,而非复杂的流程链。
保持图结构的状态扁平且具有类型约束。嵌套的数据块会掩盖是哪个节点修改了哪个字段,还会在任务中断后导致无法继续执行。
在升级技术栈之前,应先冻结版本,为关键路径记录标准的操作日志,并确认回滚步骤。共享环境需要设置速率限制、租户验证机制,以及明确的密钥轮换负责人。与其追求花哨的一次性演示,不如注重扎实的可靠性。
关于102175b0ac7c的批量处理说明:不要将提供者密钥放入代码仓库,为每个会话设置令牌使用上限,并将转录内容存储在评估测试用例的旁边,以便后续更换模型时仍能保持可比性。
强化措施的第0阶段若被视为可测量的指标,则效果最佳。在扩大范围之前,先记录一份理想的转录样本、一个失败案例以及回滚说明。配置应置于应用程序代码之外,环境文件、密钥存储和功能开关应集中存放于一处,以便操作人员无需查看整个系统结构即可进行审计。
强化措施细节0/800:针对此条说明,需测量运行时间、错误类型以及令牌使用量,然后依据固定的评估标准而非主观判断来决定是否保留该变更。
在强化措施的第一阶段,应在修改代码之前明确输入参数、该步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。相比冗长的脚本,更应采用小型且可测试的单元。当某个步骤失败时,故障原因应能指向具体的责任主体,而非复杂的流程问题。
强化措施细节 1/800:需记录该步骤的运行时间、错误类型以及令牌消耗情况,然后依据固定的评估标准而非主观判断来决定是否保留该变更。