尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

从零开发AI诊断Agent:拆解LLM+Tools+Prompt三大核心与TaoToken配置骨架

从零开发AI诊断Agent:拆解LLM+Tools+Prompt三大核心与TaoToken配置骨架 1. 为什么我要从零写一个 AI 诊断 AgentAI 诊断 Agent 是一套由大语言模型驱动、能自主决定“下一步查什么”的运维排查程序。它把过去需要 DBA 手动敲十几条命令的流程变成一次启动、自动收集、自动出报告。适合谁适合手里有 MySQL 或 Linux 服务器、想把自己从重复排查里解放出来的后端和运维同学。我最初做这个项目是因为一次线上响应。数据库告警响了我登录机器先看慢查询再看连接数接着查锁等待最后看系统负载——这套动作我做过不下五十遍每次命令都差不多但每次都要重新敲一遍。更麻烦的是新人接手时根本不知道该从哪条命令开始。于是我想能不能让 LLM 来当这个“决策者”我只需要把工具准备好它自己决定查什么、什么时候收手跑通之后我发现Agent 开发真正的难点不在调模型而在三件事的配合LLM 负责推理决策Tools 负责安全执行Prompt 负责约束行为。这三者缺一个Agent 就会失控或者变傻。这篇文章我会把这三块拆开讲并给出可直接复制的config.toml与settings.json配置骨架最后演示如何通过 TaoToken 统一 Key 通道接入跑通一个最小诊断闭环。你跟着做能拿到一份自动生成的 Markdown 诊断报告。2. TaoToken 前置统一 Key 与 API 通道在写 Agent 之前先解决模型接入的问题。我这个项目里 LLM 调用是核心如果每次换模型都要改代码里的 base_url 和 key维护成本很高。TaoToken 提供的是统一的 API 通道你申请一个 Key就能在同一个接口下切换不同模型Agent 代码里只需要维护一份配置。它的定位是 AI 工具与模型的统一接入层官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。注意 API 地址不带 UTM 参数配置时直接写这个。你需要先拿到 Key。进入控制台创建 API Key地址是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。创建后复制那串sk-开头的字符串后面配置里要用。注意Key 只显示一次创建后立刻保存到本地.env或密钥管理工具里不要提交到 Git。如果你只是想先验证模型通不通可以打开模型对话页面直接试一句地址是 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。确认能正常返回后再进入代码配置环节。对于长期跑编码或 Agent 任务的场景可以考虑 Coding Plan地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它更适合高频调用。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 遇到参数问题可以对照查。3. 可复制配置config.toml 与 settings.json 骨架Agent 的配置我分成两层config.toml管模型和运行参数settings.json管工具白名单和安全策略。这样拆的好处是换模型只动 toml调安全策略只动 json互不干扰。先看config.toml# config.toml - Agent 运行配置 [llm] provider taotoken base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY # 从环境变量读取不硬编码 model deepseek-ai/DeepSeek-V3.2 temperature 0.3 max_tokens 3000 timeout 120 [agent] max_rounds 30 # 防止无限循环 slow_query_threshold 0.5 report_dir reports [mysql] host_env MYSQL_HOST port 3306 user_env MYSQL_USER password_env MYSQL_PASSWORD database_env MYSQL_DATABASE [ssh] host_env SSH_HOST port 22 user_env SSH_USER password_env SSH_PASSWORD这里的关键是api_key_env它指向环境变量名而不是明文 Key。你可以在.env里写TAOTOKEN_API_KEYsk-你的key MYSQL_HOST172.20.20.15 MYSQL_USERroot MYSQL_PASSWORDyour_password MYSQL_DATABASEownit SSH_HOST172.20.20.15 SSH_USERroot SSH_PASSWORDyour_password再看settings.json它定义工具的安全边界{ tools: { mysql_query: { allowed_statements: [SELECT, SHOW, DESCRIBE, EXPLAIN], blocked_keywords: [INSERT, UPDATE, DELETE, DROP, ALTER, GRANT, SET], max_rows: 500 }, ssh_exec: { allowed_commands: [top, free, df, uptime, vmstat, ss, ps, dmesg], blocked_substrings: [, , |, ;, , rm -rf, sudo, curl, wget], timeout: 60 } }, safety: { read_only: true, require_whitelist: true } }这两个文件配合的逻辑是config.toml告诉 Agent 用哪个模型、连哪台机器settings.json告诉它哪些命令能跑、哪些绝对不能碰。我试过把白名单写死在代码里后来发现每次加一条命令都要改代码重新部署改成 json 后直接改配置就行。提示blocked_substrings里我特意禁掉了管道符|。因为 LLM 有时会生成ps aux | grep mysql这种命令虽然本身无害但管道会带来命令拼接风险干脆一刀切禁掉让它拆成多条执行。4. 三大核心模块的代码落地4.1 LLM 模块让模型输出结构化决策LLM 是 Agent 的大脑它不直接操作数据库只负责“说”下一步做什么。所以调用它的核心是把上下文发过去拿回一个 JSON 格式的决策。import httpx, json def call_llm(self, user_message: str) - ToolCall: self.messages.append({role: user, content: user_message}) headers { Authorization: fBearer {self.api_key}, Content-Type: application/json, } payload { model: self.model, messages: [{role: system, content: self.SYSTEM_PROMPT}] self.messages, temperature: 0.3, max_tokens: 3000, } url f{self.base_url.rstrip(/)}/chat/completions with httpx.Client(timeout120) as client: resp client.post(url, headersheaders, jsonpayload) resp.raise_for_status() content resp.json()[choices][0][message][content] # 清理 markdown 包裹 content content.strip() if content.startswith(json): content content[7:] if content.startswith(): content content[3:] if content.endswith(): content content[:-3] parsed json.loads(content.strip()) return ToolCall(parsed[tool], parsed.get(action, ), parsed[input])这里有个坑我踩过模型有时会在 JSON 外面套一层json直接json.loads会报错。所以清理逻辑必须加否则 Agent 跑几轮就崩。4.2 Tools 模块80% 的工作在这里很多人以为 Agent 开发重点是调模型其实真正花时间的是写 Tools。因为模型“说”的东西不一定能安全执行你得把它翻译成可靠的代码。MySQL 工具的核心是白名单校验ALLOWED_STATEMENTS {SELECT, SHOW, DESCRIBE, EXPLAIN} def _validate_query(self, query: str): clean query.strip().upper() first_word clean.split()[0] if clean else if first_word not in self.ALLOWED_STATEMENTS: return False, f语句类型不允许: {first_word} for kw in self.BLOCKED_KEYWORDS: if f {kw} in f {clean} : return False, f包含禁止关键字: {kw} return True, SSH 工具同理只放行只读命令ALLOWED_COMMANDS {top, free, df, uptime, vmstat, ss, ps, dmesg} def _validate_command(self, command: str): cmd_lower command.lower() for blocked in self.BLOCKED_SUBSTRINGS: if blocked in cmd_lower: return False, f包含禁止子串: {blocked} cmd_name command.strip().split()[0].split(/)[-1] if cmd_name not in self.ALLOWED_COMMANDS: return False, f命令不在白名单: {cmd_name} return True, 还有一个细节模型有时会一次给多条 SQL用分号隔开。PyMySQL 默认不支持多语句所以我写了个拆分函数关键是正确处理字符串里的分号别把SELECT a;b拆坏。4.3 Prompt 模块约束模型的行为边界Prompt 是 Agent 的灵魂它要回答三个问题你是谁、你能用什么工具、你必须怎么输出。SYSTEM_PROMPT 你是一位专业的 MySQL 和 Linux 性能诊断专家。 【可用工具】 1. mysql_query - 执行只读查询仅允许 SELECT/SHOW/DESCRIBE/EXPLAIN 2. ssh_exec - 执行只读 Linux 命令 3. final_answer - 结束诊断并给出结论 【响应格式】 必须输出纯 JSON不要有其他文字 {tool: mysql_query|ssh_exec|final_answer, action: 描述, input: 查询或命令} 【诊断流程】 第1阶段慢查询、运行时间、连接数、系统负载 第2阶段进程列表、InnoDB 状态、CPU/内存/磁盘 第3阶段针对性深入分析 收集足够信息后使用 final_answer 输出完整报告。 我特意在 Prompt 里加了“常用查询示例”因为模型有时不知道具体该查什么给几个例子能显著提升第一轮的准确率。另外temperature设成 0.3输出更稳定不会每轮都换花样。5. 验证请求跑通最小诊断闭环配置和代码都就位后先做连通性验证。第一步确认 TaoToken 通道能通curl -X POST https://taotoken.net/api/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: deepseek-ai/DeepSeek-V3.2, messages: [{role: user, content: 回复 ok}], max_tokens: 10 }返回里能看到choices字段就说明通道正常。接着跑 Agent 主程序python main.py启动后日志会逐轮打印决策。我实测下来一个健康的 MySQL 实例大概 15 轮左右就能出结论。下面是关键日志片段--- 第 1 轮诊断 --- 决策: mysql_query - 检查慢查询统计和连接信息 --- 第 2 轮诊断 --- 决策: ssh_exec - 检查系统负载和内存 --- 第 3 轮诊断 --- 决策: ssh_exec - 检查磁盘空间 ... --- 第 16 轮诊断 --- 决策: final_answer - 结束诊断最终生成的报告里模型会给出健康评分、慢查询分析、QPS、连接状态、锁等待、内存、CPU、磁盘等分项并列出问题和优化建议。比如我这次跑出来的结论是健康评分 95/100主要问题是慢查询阈值设成了 10 秒建议改 0.5 秒以及磁盘临时表占比 48% 偏高。注意报告里的优化建议是模型基于采集数据给出的执行前你自己要复核一遍尤其是涉及参数调整的语句。6. 本篇常见错排查报错一not enough arguments for format string这个我在第 11 轮遇到过。原因是 SQL 里带了%通配符比如SHOW GLOBAL STATUS LIKE Threads_%而 PyMySQL 的cursor.execute(sql, params)会把%当成参数占位符。解决办法是当params为空时不要传第二个参数if params: cursor.execute(sql, params) else: cursor.execute(sql)报错二命令包含禁止的子串: |模型生成了ps aux | grep mysql这类带管道的命令被白名单拦下了。这不是 bug是安全策略生效。你可以在 Prompt 里明确告诉模型“不要使用管道符拆成多条命令”或者把常用组合封装成一个专用工具。报错三JSON 解析失败模型返回的内容外面裹了json或者前后有多余文字。前面 LLM 模块里的清理逻辑就是干这个的。如果还是失败可以在 Prompt 里加一句“只输出 JSON不要用代码块包裹”。报错四连接超时检查config.toml里的base_url是不是写成了带 UTM 的地址。API 调用地址应该是https://taotoken.net/api不带任何查询参数。另外确认.env里的 Key 没有多余空格。报错五Agent 跑满 30 轮还没结束说明 Prompt 里的“结束条件”不够明确。可以在系统提示里加一句“当你已经检查了慢查询、连接数、系统负载、内存、磁盘五个维度后必须使用 final_answer”。我加了这句之后平均轮次从 25 降到了 16。排查完这些你的最小诊断 Agent 基本就能稳定跑了。后续想扩展的话加新工具只需要在settings.json里注册白名单再写一个对应的 Tool 类Prompt 里补上工具说明即可。
返回列表