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

推荐订阅源

Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
腾讯CDC
D
Docker
G
Google Developers Blog
D
DataBreaches.Net
雷峰网
雷峰网
Blog — PlanetScale
Blog — PlanetScale
S
SegmentFault 最新的问题
The Cloudflare Blog
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
大猫的无限游戏
大猫的无限游戏
量子位
美团技术团队
aimingoo的专栏
aimingoo的专栏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Engineering at Meta
Engineering at Meta
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园_首页

Linux实操--组管理、权限管理和定时任务 Java + EasyExcel 实现单个接口导出多个Excel Mem0 源码解析系列(二):提示词工程的深度剖析 Openclaw TaskFlow究竟是什么?和普通Skill技能有什么区别 博文阅读密码验证 - 博客园 嘉立创开源:应该是全网MicroPython教程最多的开发板 Hermes Agent 集成实践:从协议到生产 2026年AI编程工具横评:Cursor、Codex、Claude Code、Zed、Windsurf Java程序员必看的RAG入门教程 2026 AI效率神器:Superpowers + Claude Code 保姆级教程 本地大模型部署全攻略:从 0 到 1 玩转 Ollama 【从0到1构建一个ClaudeAgent】内存管理-上下文压缩 .NET 高级开发 | 设计、实现一个事件总线框架 电子小白入门之NE555 3. WorkBuddy:隐藏玩法,一键召唤专家,让 AI 以"专家身份"给你干活 和AI一起搞事情#3:Claude Teammate 游戏开发翻车实录 【OpenClaw】通过 Nanobot 源码学习架构---(7)Memory C# .NET 周刊|2026年3月3期 我在 Debian 11 上把 K8s 单机搭起来了,过程没你想的那么顺(/opt 目录版) 深度学习进阶(七)Data-efficient Image Transformer CLI+Skill搭建浏览器AI自动化框架,告别一切重复枯燥任务 告别Token账单无底洞:OpenClaw本地部署,重塑企业数据主权的唯一解 FastAPI+Vue:文件分片上传+秒传+断点续传,这坑我帮你踩平了! SBTI 爆火后,我做了个程序员版的 CBTI。。已开源 + 附开发过程 多模态检索开始进入工程期:用 Sentence Transformers 搭建可落地的 Multimodal RAG 100多行代码实现一个最简单的Agent(用ReAct) Claude Code 通关手册(八):推荐 5 个 Hooks,代码质量提升 3 倍 老板:“有人截图了!”。安全部门:“收到,马上查暗水印!” - why技术 技术之外,皆是人间 C#/.NET/.NET Core技术前沿周刊 | 第 69 期(2026年4.01-4.12)
function call 实战:让 LLM 自动判断 pod 异常、调用日志工...
it排球君 · 2026-04-16 · via 博客园_首页

前言

今天是一期function call的实战

先上代码

function_call

illustration-01

  • 先获取 Pod 当前状态
  • 让 LLM 判断这个状态是否需要进一步排查
  • 如果需要排查,就要求 LLM 调用 get_pod_logs 工具拿日志
  • 再让 LLM 基于日志输出问题原因、根因分析和修复建议

OpenAI 客户端初始化

这部分代码的作用,是初始化模型客户端,并从环境变量里读取模型名和接口地址

from openai import OpenAI
import json
import os


client = OpenAI(
    api_key=os.getenv("OPENAI_API_KEY"),
    base_url=os.getenv("API_BASE_URL")
)

model = os.getenv("DEFAULT_MODEL")

工具定义

声明可供模型调用的函数工具

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_pod_logs",
            "description": "获取Pod日志用于排查问题",
            "parameters": {
                "type": "object",
                "properties": {
                    "pod_name": {"type": "string"},
                    "namespace": {"type": "string"}
                },
                "required": ["pod_name"]
            }
        }
    }
]
  • 有一个叫 get_pod_logs 的工具
  • 这个工具是用来获取 Pod 日志的
  • 它需要什么参数
  • 哪个参数是必填的

function call 的本质不是让模型直接跑 python,而是让模型知道,有什么工具可以调用外部世界的接口

获取 Pod 状态和日志

接下来这两个函数,是本地实现的模拟逻辑,后期可以接入正式环境的数据,这里先用模拟数据

def get_pod_state(pod_name, namespace):
    # 可以用 kubectl 或 k8s API, 返回:Running / CrashLoopBackOff / OOMKilled 等
    return "CrashLoopBackOff"

def get_pod_logs(pod_name, namespace="default"):
    # 去日志平台上获取对应的日志即可
    return "ERROR: database connection failed\nException: timeout"

让 LLM 先判断是否有异常

下面这段代码,是第一次调用模型。

messages = [
    {
        "role": "system",
        "content": """你是Kubernetes运维专家。

判断 Pod 状态:
- 如果是 Running / 正常 → 返回 OK
- 如果是 CrashLoopBackOff / OOMKilled / Error → 返回 NEED_DEBUG

只返回 OK 或 NEED_DEBUG"""
    },
    {
        "role": "user",
        "content": f"Pod状态是: {pod_state}"
    }
]

resp = client.chat.completions.create(
    model=model,
    messages=messages
)

decision = resp.choices[0].message.content.strip()

LLM 调工具拿日志

如果真的有问题,调用预定义的函数获取相关信息

messages = [
    {
        "role": "system",
        "content": """你是一个Kubernetes故障诊断专家。

当Pod异常时:
1. 必须调用 get_pod_logs 获取日志
2. 根据日志分析问题
3. 输出:
   - 问题原因
   - 根因分析
   - 修复建议
"""
    },
    {
        "role": "user",
        "content": f"Pod {pod_name} 状态是 {pod_state},请排查问题"
    }
]

response = client.chat.completions.create(
    model=model,
    messages=messages,
    tools=tools
)

这里和第一轮最大的区别,就是多传了一个 tools=tools,这意味着模型此时知道自己可以发起函数调用,随后代码会检查模型是否真的触发了工具调用:

msg = response.choices[0].message

if msg.tool_calls:
    tool_call = msg.tool_calls[0]
    args = json.loads(tool_call.function.arguments)

拿到工具调用后,再由本地 Python 去真正执行:

logs = get_pod_logs(**args)

然后把工具执行结果,再喂回模型,让它基于日志继续完成最终分析:

final_resp = client.chat.completions.create(
    model=model,
    messages=[
        *messages,
        msg,
        {
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": logs[:3000]
        }
    ]
)

执行链路

illustration-02

获取 Pod 状态
   ↓
LLM 判断:OK / NEED_DEBUG
   ↓
如果 NEED_DEBUG
   ↓
LLM 发起 tool call:get_pod_logs(pod_name, namespace)
   ↓
本地函数执行,拿到日志
   ↓
日志作为 tool message 回填给 LLM
   ↓
LLM 输出:问题原因 + 根因分析 + 修复建议

这里为什么不用 if-else

很多老哥看到这里,肯定会问:

既然 Running 就是正常,CrashLoopBackOff 就是异常,那直接 if-else 不香吗?

如果场景足够简单,当然可以直接写 if-else。甚至在这个场景中,第一段判断逻辑严格来说也确实可以用规则替代,像下面这样:

if pod_state in ["Running", "Succeeded"]:
    decision = "OK"
else:
    decision = "NEED_DEBUG"

这么写没毛病,而且更便宜、更稳定、更可控,那为什么还要引入 LLM?因为真实线上环境,往往没这么简单

线上判断一个 Pod 是否异常,很多时候不是看一个字段就能拍板,而是要综合很多信息一起看

1)状态看起来正常,但其实已经不正常了, Pod 状态还是 Running,但实际上业务已经挂了,比如:

  • readiness probe 一直失败
  • 接口 RT 飙升
  • 错误率升高
  • 日志持续报错
  • 下游数据库连接频繁超时
  • CPU 不高,但线程池已经卡死

这时候如果你只写:

if pod_state == "Running":
    return "OK"

2)状态异常,但未必需要立刻排查

  • pod 状态 Completed
  • 灰度发布期间有短暂重建
  • HPA 扩缩容带来的短时波动
  • 节点维护导致的瞬时漂移

这时候你如果只根据状态值机械判断,就很容易误报

3)真正有价值的判断,往往依赖多维信号

  • Pod 当前 状态
  • restart 次数
  • 最近 5 分钟日志
  • CPU / Memory 使用率
  • OOM 事件
  • 节点状态
  • 发布记录
  • 同服务其他副本是否也异常
  • Prometheus 指标波动

这个时候用 if-else 纯流程化的判断模式,对于事件的判断就不太合适了。if-else 擅长处理边界清晰、模式稳定的场景

而LLM 更适合处理需要综合上下文、模糊判断以及不固定条件的综合判断,所以这里采用LLM 的表达能力和归纳能力会更方便

illustration-03

总结

通过 Function Call 获取外部数据,最后让 LLM 输出总结性的建议以及处理方案

至于为什么不用 if-else,简单场景当然可以用固定流程,但当判断开始依赖多维数据、日志语义和上下文综合分析时,LLM 会更灵活。在更加复杂的场景下,则是固定流程和 LLM 组合使用

后记

在本文中,明确告诉了llm,通过get_pod_logs去拿pod日志去拿对应的数据,那如果遇到更加复杂的事故,我们需要

  • 1)拿pod日志,通过kubectl logs
  • 2)拿业务日志,通过日志平台接口
  • 3)获取负载数据,通过监控接口
  • 4)获取发布数据,通过发布平台接口
  • 5)获取上下游的top结构,通过cmdb接口
  • 6)太多了,列举不完...

如何让llm通过当前事故情况,自动选取对应的接口函数获取数据呢?这是个非常现实、棘手的问题了,但这不是本期内容了,我们下一期再见

联系我

  • 联系我,做深入的交流

至此,本文结束

在下才疏学浅,有撒汤漏水的,请各位不吝赐教...