-
LogGuard AI — 详细设计文档
版本:V5 架构风格:ReAct + RAG + DeepThinking 多智能体 AIOps 技术基底:Next.js 16 + TypeScript + Tailwind CSS 4 + shadcn/ui
目录
1. 系统概述
1.1 项目定位
LogGuard AI 是一款基于 Next.js 16 + TypeScript 的多智能体日志分析、Debug、修复建议协同诊断系统,定位于 AIOps(AI for IT Operations)领域,目标是把"人工运维 → 工具化运维 → 智能化运维"的链条推进到最后一公里:
-
输入:原始运行时日志(支持 Java/Python/Node 多语言堆栈)或 C++ 源代码 + 运行时日志(ASAN/Valgrind/GDB/编译器输出)。
-
输出:结构化的根因分析(RCA)、按优先级排序的修复建议、风险评分、可追溯的证据链、可导出的诊断报告。
-
过程:实时、可视化、可回放的多智能体协同推理过程(ReAct 思考-行动-观察流)。
1.2 核心架构理念
系统融合三种现代 LLM 推理范式:
范式 全称 在系统中的作用 ReAct Reason + Act 规划器(Planner)的"思考→行动→观察"循环,最多 5 轮自主迭代 RAG Retrieval-Augmented Generation 检索器(Retriever)从知识库召回先验知识,注入到下游智能体的上下文 DeepThinking 深度思考 / 内省式推理 深度思考器(DeepThinker)在置信度低或检测到矛盾时条件触发,对诊断进行批判性反思 三者通过 反思闭环(Reflector Loop) 串联:分析师给出初步 RCA → 深度思考器审视 → 验证器证据链校验 → 反思器决定是否重新分析(最多 2 轮迭代)→ 修复器生成建议 → 复审器给出风险评分。整个过程由 Orchestrator(编排器) 统一调度,事件流经 Socket.io 实时推送到前端。
1.3 多模型适配
系统支持 4 种大模型,每种模型有独立的 persona、推理风格、系统提示词:
模型 ID 标签 厂商 推理风格 适用场景 qwenQwen 阿里巴巴 direct(直接精确) 长上下文代码与日志理解 glmGLM 智谱 AI tool-first(工具优先) 平衡推理 + 稳定 JSON 输出 deepseekDeepSeek DeepSeek chain-of-thought(思维链) 深度逐步推理、数学逻辑、Debug stepfun阶跃星辰 StepFun structured(结构化) 长文本理解、多模态、中文优化 模型切换通过 UI 顶部的下拉选择器实时切换,不需要重启服务。底层调用统一抽象为
chat()函数(src/lib/agents/llm.ts),支持两种后端路径:-
用户自配置路径:若用户在设置面板配置了
LLM_BASE_URL / LLM_API_KEY / LLM_MODEL_NAME(OpenAI 兼容协议),系统直接用原生fetch调用用户配置的端点。 -
环境回退路径:未配置时回退到
z-ai-web-dev-sdk(无需 API Key)。
2. 五层架构设计
LogGuard AI 采用经典的分层架构,从下到上依次为:
┌─────────────────────────────────────────────────────────────────────┐ │ 5. 确定性验证与 RCA 生成层 Validator · Reflector · Analyst · Fixer │ │ 证据链闭环 · 交叉校验 · 幻觉检测 · RCA · 修复建议 · 复审 │ ├─────────────────────────────────────────────────────────────────────┤ │ 4. DeepThinking & ReAct 推理层 Orchestrator + 10 智能体协同 │ │ ReAct 循环 · 深度思考 · 反思迭代 · 智能体有向图编排 │ ├─────────────────────────────────────────────────────────────────────┤ │ 3. 多维存储与 RAG 索引层 Prisma + SQLite · KB · IDF+正则检索 │ │ 知识库 17+ 篇 · RAG 打分检索 · 会话/事件/日志/代码持久化 │ ├─────────────────────────────────────────────────────────────────────┤ │ 2. 智能压缩与上下文管理层 Drain 模板提取 · L1/L2/L3 三级压缩 │ │ Token 预算管理 · 上下文窗口动态裁剪 · 按需片段召回 │ ├─────────────────────────────────────────────────────────────────────┤ │ 1. 实时采集与流处理层 日志解析器 · 大文件流式上传 · SSE 实时 tail │ │ 多格式时间戳/堆栈识别 · 批量分片 (50k 行/批) · Drain 模板归并 │ └─────────────────────────────────────────────────────────────────────┘ ▲ │ HTTP / Socket.io ▼ ┌────────────────────────────────────────────┐ │ 前端:Next.js 16 + Tailwind 4 + shadcn/ui │ │ 三栏可拖拽面板 · ReAct 事件流 · 诊断报告 │ └────────────────────────────────────────────┘2.1 第一层:实时采集与流处理层
职责:把异构的原始日志/源代码统一规范化为结构化对象
ParsedLog,并支持大文件的分片流式处理。核心组件:
组件 文件 职责 日志解析器 src/lib/agents/log-parser.ts多格式时间戳识别、Java/Python/Node 堆栈提取、level 归一化(INFO/WARN/ERROR/DEBUG/TRACE/FATAL)、tag 自动打标 日志摘要器 log-parser.ts#digestLogs统计 total/errors/warnings/byLevel,给出快速 digest Auto-Collect src/app/api/logs/collect/route.ts自动读取 sample-logs/目录下的.log/.txt文件流式上传 src/app/api/logs/stream-upload/route.ts大文件上传(>100 万行),按 50k 行/批分片解析,最大上限 1000 万行 SSE 实时 tail src/app/api/logs/tail/route.tsServer-Sent Events 端点,2 秒轮询 + 10 秒心跳,检测日志轮转(truncation) Drain 模板提取 src/lib/agents/log-template.ts经典 Drain 算法,把相似日志行归并为 <*>模板,统计每类模板出现次数Drain 模板提取算法:
-
tokenize:按空格切分。
-
isVariable:数字、十六进制地址、IP、路径、带引号字符串、
0xXXXX等识别为变量。 -
generalize:变量替换为
<*>占位符,同时记录原值到params。 -
similarity:基于 token 位置匹配度计算两条日志的相似度(阈值 0.5)。
-
归并:相似日志合并到同一模板组,保留最多 3 条示例。
输出数据结构:
interface ParsedLog { raw: string; // 原始日志行 timestamp?: string; // 解析出的时间戳 level: string; // INFO | WARN | ERROR | DEBUG | TRACE | FATAL source?: string; // 文件名 / 组件名 message: string; // 提取的日志消息正文 stack?: string; // 堆栈(多行合并) tags: string[]; // 自动打标的类别标签 }2.2 第二层:智能压缩与上下文管理层
职责:当日志体量超出 LLM 上下文窗口时,通过三级压缩把"百万行日志"塞进"8k token 预算",同时保留诊断所需的关键信号。
核心组件:
组件 文件 输出 三级压缩器 src/lib/agents/context-compressor.tsL1 + L2 + L3 三段拼接的 CompressedContext上下文管理器 src/lib/agents/context-manager.tsManagedContext:预算使用情况 + 可按需加载的片段Token 估算器 context-manager.ts#estimateTokensCJK 字符 ÷2 + 其他字符 ÷4 L1/L2/L3 三级压缩策略:
级别 名称 内容 上限 L1 宏观压缩 时间线摘要:按时间桶(分钟级)聚合,给出每桶日志数 / 错误数 / 警告数 4000 字符 L2 中观结构化 因果链:抽取 traceId/requestId,按 trace 聚合相关日志;无 trace 时按错误因果排序 2000 字符 L3 微观裁剪 错误行 ±5 行的完整上下文(最多 10 个错误点),其余行折叠为模板引用 6000 字符 Token 预算管理(默认 8k 总预算):
┌────────────────────────────────────────────────┐ │ 总预算:8000 tokens │ ├──────────────┬─────────────────────────────────┤ │ 系统提示词 │ 1000 tokens │ ├──────────────┼─────────────────────────────────┤ │ 压缩日志 │ 3000 tokens (L1 + L2 + L3) │ ├──────────────┼─────────────────────────────────┤ │ RAG 召回 │ 2000 tokens (知识库命中条目) │ ├──────────────┼─────────────────────────────────┤ │ 推理预留 │ 2000 tokens (LLM 思考 + 输出) │ └──────────────┴─────────────────────────────────┘
按需片段召回:除了 active window 外,上下文管理器还会预生成 20+ 个"可加载片段"(错误行周边上下文、模板示例、错误 burst 段),当下游智能体需要更细的上下文时,可显式请求加载某一片段,避免一次性塞满 context。
2.3 第三层:多维存储与 RAG 索引层
职责:把会话、日志、事件、知识库、代码、问题、模型配置等多维数据持久化到 SQLite(通过 Prisma ORM),并提供基于 IDF + 正则增强的关键词 RAG 检索。
数据库表(详见
prisma/schema.prisma):表名 用途 关键字段 AnalysisSession诊断会话 title,model,status,severity,rootCause(JSON),fixes(JSON),summary(JSON)LogEntry解析后的单行日志 sessionId,raw,level,message,stack,tagsAgentEvent智能体事件流 sessionId,agent,type,content,meta(JSON)KnowledgeArticle知识库条目 title,category,pattern(正则),summary,cause,fix,keywordsCodeFileC++ 源文件 sessionId,path,content,lineCountCodeIssueC++ 静态分析问题 sessionId,ruleId,severity,line,snippet,suggestion,fixCode,cweLlmConfigLLM 提供商配置 provider,baseUrl,apiKey,modelName,enabledRAG 检索算法(
knowledge-base.ts#retrieveKB):检索器采用 IDF 加权 + 正则模式增强 + 类别子串加分 的混合打分策略,无外部向量依赖:
-
Tokenize:将查询切分为小写 token。
-
IDF 权重:预计算每个词的文档频率
df[t],匹配词加log(totalArticles / df[t])(最低 0.1 防止通用词得分为 0)。 -
正则模式增强:将每篇 KB 文章的
pattern字段(正则表达式)编译为 RegExp,对原始查询字符串执行test,命中加 +3 分。 -
类别子串加分:若查询包含某文章的
category子串,加 +2 分。 -
TopN 召回:按总分降序,默认返回 Top 4。
知识库内容(17+ 篇):覆盖 NPE、OOM、连接池耗尽、SQL 错误、死锁、网络超时、TLS 失败、磁盘满、JSON 解析、认证失败、原生崩溃、CPU 节流、限流 429、SLA 超时、Schema 不匹配、内存泄漏、GC 开销,以及 C++ 专题(内存泄漏、Use-After-Free、未初始化、数据竞争、RAII 违反、智能指针迁移)。
2.4 第四层:DeepThinking & ReAct 推理层
职责:核心智能体协同层。10 个智能体按有向图编排,由 Orchestrator 统一调度,支持条件触发、反思迭代、并行/串行混合执行。
节点流(有向图):
┌──────────┐ │Collector │ 采集 + 解析 + 标签 └────┬─────┘ ▼ ┌──────────┐ │Retriever │ RAG 召回先验知识 └────┬─────┘ ▼ ┌──────────┐ │ Planner │ ReAct 循环(最多 5 轮) └────┬─────┘ ▼ ┌──────────────┐ │ Analyst │ RCA 初步分析 └──────┬───────┘ ▼ ┌─────────────────────────────┐ │ 迭代循环(最多 2 轮) │ │ ┌──────────────┐ │ │ │ DeepThinker │ 条件触发 │ │ └──────┬───────┘ │ │ ▼ │ │ ┌──────────────┐ │ │ │ Validator │ 证据链验证 │ │ └──────┬───────┘ │ │ ▼ │ │ ┌──────────────┐ │ │ │ Reflector │ 闭环反思 │ │ └──────┬───────┘ │ │ │ should_re_analyze?│ └─────────┼───┬───────────────┘ │ │ No │ │ Yes ▼ └─────► 回到 Analyst ┌──────────┐ │ Fixer │ P0-P3 修复建议 └────┬─────┘ ▼ ┌───────────┐ │ Reviewer │ 复审 + 风险评分 0-100 └───────────┘条件触发规则:
-
DeepThinker:当
rca.confidence < 0.7或检测到矛盾或evidence为空时触发。 -
Reflector:当 Validator 判定
validated = false,或 DeepThinker 判定verdict = rejected | needs_more_evidence时触发;最多迭代 2 轮。 -
重新分析:Reflector 决定
should_re_analyze = true时,回到 Analyst 重新执行 RCA,Reflector 可能给出新的focus_areas和new_search_queries。
ReAct 循环(Planner):每轮 LLM 自主选择 5 种 action 之一:
search_knowledge/inspect_errors/inspect_metrics/trace_request/form_plan。当 LLM 返回form_plan或达到MAX_CYCLES=5时退出,输出结构化的AnalysisPlan(含 goal/steps/hypotheses)。2.5 第五层:确定性验证与 RCA 生成层
职责:确保诊断结果逼近"100% 确定性"——通过证据链闭环、交叉校验、幻觉检测三重机制,把 LLM 的概率性输出约束为可追溯、可验证、可解释的结构化结论。
三重验证机制:
2.5.1 证据链闭环(Validator)
构建
根因 ← 证据1 ← 证据2 ← 证据3 ← 触发器的有向链图,每个节点必须引用真实的日志行:interface EvidenceChainNode { node: string; // 节点名称 type: "root_cause" | "evidence" | "trigger"; // 节点类型 ref: string; // 引用的日志行 }2.5.2 交叉校验(Validator)
对 RCA 中每个声明,验证支持性日志信号是否确实出现:
RCA 声明 期望日志信号 "网络问题" ECONNREFUSED/ETIMEDOUT/socket hang up"内存泄漏" OutOfMemoryError/heap space/GC overhead"连接池耗尽" HikariPool/Connection is not available/pool exhausted"死锁" Found one Java-level deadlock/waiting to lock输出
crossValidation[],每条记录{claim, supported, reason},未支持的声明计入hallucination_warnings。2.5.3 幻觉检测(Validator)
若 RCA 引用的 evidence 实际上未出现在原始日志中,标记为幻觉。Validator 根据"支持 vs 不支持"的声明比例调整置信度,输出
adjustedConfidence。RCA 输出结构(
RootCauseAnalysis):{ severity: "critical" | "high" | "medium" | "low", primaryRootCause: string, // 主根因(一句话) contributingFactors: string[], // 促成因素 evidence: { log: string; explanation: string }[], // 证据链(必须引用真实日志行) timeline: { time: string; event: string }[], // 时间线 impactAssessment: string, // 影响评估 confidence: number // 0-1,经多重校准 }置信度校准:原始 confidence 来自 Analyst,DeepThinker 给出
confidence_adjustment(-0.2 ~ +0.1),Validator 给出adjustedConfidence,三者合并后写入最终 RCA。RCA prompt 中包含置信度校准带(low <50% / medium 50-70% / high 70-90% / very-high >90%),禁止使用"无法确定"作为回退。
3. 智能体设计
系统共有 10 个智能体(9 个业务智能体 + 1 个编排器),全部位于
src/lib/agents/。3.1 Orchestrator(编排器)
项 内容 文件 orchestrator.ts角色 整个多智能体有向图的统一调度器 输入 { sessionId, rawLogs, model, source }输出 AnalysisResult(含 plan/rca/fixes/review/knowledgeHits/logStats)触发条件 由 Socket.io "analyze" 事件触发 职责 (1) 顺序调度 9 个业务智能体;(2) 管理反思迭代循环(最多 2 轮);(3) 通过 EventSink 把每个事件持久化到 DB + 推送到 Socket;(4) 异常时把 session 状态置为 failed关键流程 采集 → 检索 → 规划 → [分析 → 深度思考 → 验证 → 反思]×N → 修复 → 复审 3.2 Collector(采集器)
项 内容 文件 collector.ts角色 日志结构化解析器 输入 rawLogs: string, source?: string输出 { entries: ParsedLog[], digest: string, stats: { total, errors, warnings, byLevel } }触发条件 Orchestrator 启动后第一个执行 职责 (1) 多格式时间戳识别(ISO 8601 / yyyy-MM-dd HH:mm:ss.SSS/ Syslog 等);(2) Java/Python/Node 堆栈多行合并;(3) level 归一化;(4) 自动打标(memory/network/database/concurrency/auth/json 等);(5) 统计错误/警告计数;(6) 生成 1000 字以内的 digest 摘要事件流 status: "采集器已启动"→result: "解析 N 行日志,错误 X,警告 Y"3.3 Retriever(检索器 - RAG)
项 内容 文件 retriever.ts角色 知识库 RAG 检索器 输入 entries: ParsedLog[], digest: string, model: ModelId输出 { hits: KnowledgeHit[], expandedQuery: string }触发条件 Collector 完成后 职责 (1) 用 LLM 扩展原始查询(同义词、相关错误模式);(2) 调用 retrieveKB(query, 4)进行 IDF + 正则 + 类别子串三重打分检索;(3) 返回 Top 4 命中条目作为下游智能体的先验知识设计权衡 不使用向量嵌入,避免引入 sentence-transformers 等重依赖;IDF + 正则在生产环境验证已能覆盖常见错误模式 3.4 Planner(规划器 - ReAct)
项 内容 文件 planner.ts角色 ReAct 循环规划器 输入 entries, digest, knowledgeHits, model输出 { plan: AnalysisPlan, reactTrail: ReActStep[] }触发条件 Retriever 完成后 职责 真正的动态 ReAct 循环: while (cycle < MAX_CYCLES=5 && currentAction !== "form_plan"),每轮 LLM 自主选择 5 种 action 之一可用 Actions search_knowledge(再查知识库)/inspect_errors(看错误行)/inspect_metrics(统计错误率、Top error sources)/trace_request(按 traceId 聚合)/form_plan(形成最终计划,退出循环)安全机制 (1) 无效 JSON → 默认 inspect_errors继续;(2) 未知 action → 同上;(3) 达到 MAX_CYCLES → 安全网form_plan;(4)executeAction统一调度,移除了重复代码3.5 Analyst(分析师 - RCA)
项 内容 文件 analyst.ts角色 根因分析(RCA)生成器 输入 entries, digest, knowledgeHits, plan, model输出 RootCauseAnalysis触发条件 Planner 完成后;反思器决定重新分析时也会回到这里 职责 (1) 输出主根因 + 促成因素 + 证据链 + 时间线 + 影响评估 + 严重程度 + 置信度;(2) 强制证据引用真实日志行(拒绝"unable to determine"回退);(3) 传递完整 12 帧堆栈 + 跨所有 ERROR/FATAL 行的 tag 汇总( FREQUENT TAGS段)Prompt 设计 ANALYST_PROMPT包含 DIRECTIVE 段(强制识别根因)+ COMMON PATTERNS 段(OOM / 连接池 / 网络超时 / 401-403 / JSON / 死锁 / SQL / NPE / Timeout 共 9 类先验)+ EVIDENCE DISCIPLINE 段 + CONFIDENCE CALIBRATION 段3.6 DeepThinker(深度思考器 - 条件触发)
项 内容 文件 deep-thinker.ts角色 内省式深度推理智能体 输入 rca, entries, plan, model输出 DeepThinkerResult(reasoning / verdict / gaps / alternative_hypotheses / confidence_adjustment / additional_investigation)触发条件 shouldDeepThink():rca.confidence < 0.7或检测到矛盾或 evidence 为空职责 在 5 个维度进行系统性深度推理:证据链完整性、替代假设分析、时间因果一致性、逻辑推理审查、系统性风险反思 输出 verdict confirmed(确认)/rejected(拒绝)/needs_more_evidence(需更多证据)置信度调整 -0.2 ~ +0.1的微调,由 Orchestrator 应用到 rca.confidence 并 clamp 到 [0.1, 0.99]矛盾检测 detectContradictions(rca, entries):检测时间矛盾(果先于因)、空间矛盾(证据缺失)、因果矛盾(声称 A 导致 B 但无关联日志)3.7 Validator(验证器 - 证据链验证)
项 内容 文件 validator.ts角色 证据链闭环验证 + 交叉校验 + 幻觉检测 输入 rca, entries, knowledgeHits, model输出 ValidatorResult(validated / evidenceChain / crossValidation / adjustedConfidence / gaps / hallucination_warnings / systemic_risks)触发条件 每轮迭代中,DeepThinker 之后(无论 DeepThinker 是否触发) 职责 (1) 构建 根因 ← 证据 ← 触发器有向证据链图;(2) 对每个声明交叉验证支持性信号是否真实出现;(3) 检测 LLM 幻觉(声明引用的日志实际不存在);(4) 根据"支持 vs 不支持"比例校准adjustedConfidence;(5) 检查系统性风险(部署变更、流量突增、依赖级联)3.8 Reflector(反思器 - 闭环迭代)
项 内容 文件 reflector.ts角色 闭环反思与迭代改进决策者 输入 rca, plan, deepThinkResult, validationResult, model, iteration输出 ReflectorResult(reflection / should_re_analyze / improvements / new_search_queries / focus_areas / accept_with_caveats / iteration_count)触发条件 !validated或 DeepThinker verdict ∈ {rejected, needs_more_evidence},且 iteration < MAX_ITERATIONS=2职责 (1) 流程反思:采集是否遗漏、RAG 查询是否正确、ReAct 路径是否最优、分析师是否忽略重要证据;(2) 改进策略:是否需要补充信息、调整查询、扩大时间窗口;(3) 迭代决策:当前诊断可接受 / 必须重新分析 关键决策 should_re_analyze = true时,Orchestrator 调用runAnalyst重新生成 RCA,进入下一轮迭代3.9 Fixer(修复器)
项 内容 文件 fixer.ts角色 修复建议生成器 输入 rca, model输出 FixSuggestion[]触发条件 反思迭代循环退出后(即诊断被接受) 职责 (1) 生成 P0-P3 优先级的修复建议;(2) 每条建议含 type(code/config/infra/process)、description、codeSnippet、preventionTip、estimatedEffort;(3) 修复建议与根因直接相关(由 Validator 在前一步已校验) interface FixSuggestion { title: string; type: "code" | "config" | "infra" | "process"; priority: "P0" | "P1" | "P2" | "P3"; description: string; codeSnippet?: { language: string; code: string }; preventionTip: string; estimatedEffort: string; }3.10 Reviewer(复审器)
项 内容 文件 reviewer.ts角色 最终复审与风险评估 输入 plan, rca, fixes, model输出 ReviewResult(overallAssessment / strengths / gaps / additionalRecommendations / riskScore)触发条件 Fixer 完成后,整个流水线的最后一步 职责 (1) 综合评估整个诊断(计划合理性 + RCA 准确性 + 修复建议完整性);(2) 列出 strengths(做得好的地方)和 gaps(仍存在的不足);(3) 给出 additionalRecommendations;(4) 风险评分 0-100(0 = 无风险,100 = 极高风险) 反思器联动 若 Reflector 给出了 accept_with_caveats(附带注意事项),Reviewer 会把它追加到gaps[]中,确保最终报告反映迭代过程中的不确定性
4. 数据流
4.1 实时事件流(Socket.io)
LogGuard AI 采用 WebSocket(Socket.io) 实现前后端实时双向通信。前端通过
io("/?XTransformPort=3003")经 Caddy 网关连接到独立的 agent-service(端口 3003)。架构:
┌──────────────┐ HTTP/WS ┌─────────┐ HTTP ┌────────────────┐ │ Browser │ ◄───────────► │ Caddy │ ◄────────► │ agent-service │ │ (Next.js UI) │ :81 │ :81 │ :3003 │ (Socket.io) │ └──────────────┘ └─────────┘ └────────────────┘ │ │ │ HTTP REST │ 直接调用 ▼ ▼ ┌──────────────┐ ┌────────────────┐ │ Next.js API │ │ Orchestrator │ │ Routes │ │ + 9 Agents │ │ /api/* │ └────────────────┘ └──────────────┘ │ │ │ SQL ▼ ▼ └─────────────────► Prisma + SQLite ◄──────────────────┘XTransformPort 路由技巧:Caddyfile 配置
@transform_port_query { query XTransformPort=* },匹配到该查询参数的请求会被代理到localhost:{query.XTransformPort}。这样前端用同一个域名 + 不同端口参数即可访问 Next.js 或 agent-service,避免 CORS。4.2 事件类型
所有智能体通过
EventSink投递事件,事件类型严格遵循 ReAct 范式:事件类型 含义 触发示例 status智能体状态变更(启动/完成/进入下一阶段) "采集器已启动"/"=== 第 1 轮诊断迭代 ==="thoughtReAct 的"思考"步骤——智能体的内部独白 "触发深度思考器(置信度 65%,矛盾 2 个)"actionReAct 的"行动"步骤——智能体选择的动作 "action: search_knowledge"observationReAct 的"观察"步骤——action 的执行结果 "命中知识库 3 条:OutOfMemoryError / GC overhead / memory-leak"result智能体最终结果 "严重程度: HIGH,置信度: 85%,修复: 4 条"error错误事件 "诊断流水线失败: LLM 超时"suggestion修复建议或推荐操作 Fixer 输出的 P0-P3 建议 每个事件结构:
interface AgentEvent { sessionId: string; agent: AgentName; // orchestrator | collector | retriever | ... type: EventType; // status | thought | action | observation | result | error | suggestion content: string; // 人类可读的事件内容 meta?: Record<string, unknown>; // 可选的结构化元数据 timestamp: string; // ISO 8601 }4.3 事件持久化与回放
所有事件双重持久化:
-
数据库:
AgentEvent表,按sessionId索引,可按时间正序回放。 -
实时推送:通过 Socket.io 的
socket.emit("agent-event", ev)推送到对应客户端。
历史会话通过
GET /api/sessions/[id]接口获取完整回放(result + events 数组),前端可"原样"重现整个诊断过程。4.4 并发控制
agent-service 内置并发限流(
MAX_CONCURRENT=3):-
FIFO 队列:超出并发上限的请求进入队列,发出
analysis-queued事件告知客户端排队位置。 -
超时拒绝:排队超过
QUEUE_TIMEOUT_MS=120000(2 分钟)的请求被拒绝,发出错误事件。 -
会话防重入:
activeRunsMap 防止同一 sessionId 同时跑两个分析。 -
资源释放:
try/catch/finally保证release()一定执行,pumpQueue()把队首提升到空闲槽位。
5. C++ 代码分析模块
C++ 代码分析是一个独立但并行的子系统,与日志诊断共享同一个
AnalysisSession数据模型,但走完全不同的智能体流水线。5.1 整体流程
┌──────────────┐ │ C++ 源代码 │ │ + 运行时日志 │ └──────┬───────┘ ▼ ┌──────────────────┐ │ CppParser │ 注释剥离 + AST 提取(函数/类/全局/包含) └──────┬───────────┘ ▼ ┌──────────────────┐ │ CppAnalyzer │ 15 条规则静态扫描 └──────┬───────────┘ ▼ ┌──────────────────────┐ │ CppRuntimeParser │ 运行时日志信号提取 │ (ASAN/Valgrind/GDB/ │ (compiler/asan/valgrind/gdb/stderr/runtime/other) │ compiler/stderr) │ └──────┬───────────────┘ ▼ ┌──────────────────────┐ │ Signal × Issue 关联 │ 交叉关联:静态问题 ↔ 运行时信号 └──────┬───────────────┘ ▼ ┌──────────────────────┐ │ CppOrchestrator │ LLM 综合分析 + Top Risk Areas + 修复计划 └──────────────────────┘5.2 静态分析 15 条规则
15 条规则覆盖内存、RAII、Modern C++、未定义行为、并发、性能 6 大类别,每条规则有
ruleId、severity、cwe(CVE 编号)、confidence、message、explanation、suggestion、fixCode:规则 ID 规则名称 类别 严重程度 CWE CPP-MEM-001Memory Leak (raw new without delete) memory high CWE-401 CPP-MEM-002Memory Leak (malloc without free) memory high CWE-401 CPP-MEM-003Mismatched delete (delete on array allocated with new[]) memory high CWE-762 CPP-MEM-004Dangling pointer risk (raw pointer returned) memory medium CWE-674 CPP-RAII-001Raw new/delete (prefer smart pointers) raii medium CWE-401 CPP-RAII-002Resource leak (fopen without fclose) raii high CWE-775 CPP-MOD-001NULL used instead of nullptr modern-cpp low — CPP-MOD-002C-style cast used modern-cpp low — CPP-UB-001Uninitialized local variable undefined-behavior high CWE-457 CPP-UB-002Use-after-free risk undefined-behavior high CWE-416 CPP-UB-003Potential null pointer dereference undefined-behavior medium CWE-476 CPP-CONC-001Shared mutable data without synchronization concurrency high CWE-362 CPP-CONC-002std::thread created without join() or detach() concurrency medium CWE-666 CPP-PERF-001Large parameter passed by value performance low — CPP-PERF-002std::endl causes unnecessary flush performance low — 规则设计原则:
-
保守优先:false positive 比 false negative 更糟,所以 confidence 在 0.5-0.9 之间。
-
作用域感知:通过
extractFunctionScopes()把每个 new/malloc 关联到所在函数作用域,作用域内是否有匹配的 delete/free 决定是否报错。 -
可恢复:单条规则抛错不会中断整体分析(
try/catch包裹每条规则)。 -
修复代码:每条规则提供
fixCode示例,例如auto x = std::make_unique<...>(); // RAII。
5.3 运行时日志深度诊断
cpp-runtime-parser.ts实现运行时日志信号提取,覆盖 6 种来源:来源 模式数 典型场景 ASAN (AddressSanitizer) 10+ heap-buffer-overflow / stack-buffer-overflow / heap-use-after-free / stack-use-after-return / use-after-scope / double-free / memory-leak / null-deref / ASAN 堆栈帧解析 Valgrind 5+ definitely lost / indirectly lost / possibly lost / still reachable / Invalid read/write GDB 5+ SIGSEGV / SIGABRT / SIGFPE / #0..#N 堆栈帧 / Program received signal 编译器 (gcc/clang) 5+ error: / warning: / note: / undefined reference / In function stderr 3+ Segmentation fault / Aborted / Floating point exception runtime 5+ generic runtime patterns 信号提取输出(
CppRuntimeSignal):{ source: "asan" | "valgrind" | "gdb" | "compiler" | "stderr" | "runtime" | "other", severity: "critical" | "high" | "medium" | "low" | "info", rawLine: string, // 原始日志行 line: number, // 在运行时日志文本中的行号 file?: string, // 引用的源文件 sourceLine?: number, // 引用的源文件行号 function?: string, // 引用的函数名 message: string, // 解析后的人类可读消息 address?: string, // 内存地址(ASAN/Valgrind) category: string, // "heap-buffer-overflow" / "segfault" / "leak" 等 correlatedIssueRuleId?: string // 关联到的静态规则 ID }5.4 信号与静态问题交叉关联
correlateSignalsWithIssues(signals, issues)把运行时信号与静态分析问题按(file, line)距离关联:-
若一个 ASAN
heap-buffer-overflow信号指向foo.cpp:42,而静态规则CPP-UB-002在foo.cpp:40报了 use-after-free 风险,则两者被关联,输出:
{ "signalId": "sig-001", "issueRuleId": "CPP-UB-002", "issueFile": "foo.cpp", "issueLine": 40, "confidence": 0.85, "note": "静态分析在 foo.cpp:40 标记 use-after-free 风险,ASAN 在 foo.cpp:42 确认发生 heap-use-after-free" }这种"静态预测 + 运行时确认"的交叉验证机制是 C++ 模块的核心创新——把静态分析的 false positive 风险通过运行时证据降到最低。
6. 技术栈
6.1 前端
技术 版本 用途 Next.js 16 App Router 框架,SSR + API Routes React 19 UI 库 TypeScript 5 类型安全 Tailwind CSS 4 原子化样式,含 dark:暗色模式shadcn/ui latest 基于 Radix UI 的组件库(40+ 组件) Framer Motion 12 动画(报告切换 fade+slide、按钮光晕脉冲、agent pipeline 指示灯 ping) react-resizable-panels 3 可拖拽三栏面板布局( autoSaveId持久化到 localStorage)react-markdown 10 Markdown 渲染(诊断报告、RCA、修复建议) lucide-react 0.525 图标库 Zustand 5 状态管理(locale、currentSession、socket 连接状态等) socket.io-client 4 实时事件流接收 next-themes 0.4 暗色模式切换 6.2 后端
技术 版本 用途 Bun latest agent-service 运行时(端口 3003) Socket.io 4 WebSocket 服务端 Prisma ORM 6 数据库 ORM SQLite — 嵌入式数据库( db/custom.db)Caddy 2 反向代理网关(端口 81) 6.3 LLM 与 AI
技术 用途 z-ai-web-dev-sdk 默认 LLM 后端(无需 API Key 的回退路径) OpenAI-compatible API 用户自配置的 4 个提供商统一接口 Drain 算法 日志模板提取 IDF + 正则 RAG 无向量依赖的轻量级检索 6.4 工程化
技术 用途 ESLint 代码风格检查(0 errors / 0 warnings) TypeScript strict mode 类型安全 Bun lockfile 依赖锁定 start-dev.sh/start-prod.sh一键启动所有服务
7. 关键设计决策
7.1 为什么不用 LangGraph / LangChain?
-
轻量化:本项目智能体间通信简单(顺序 + 条件分支),不需要 LangGraph 的复杂图编排。
-
可控性:自研 Orchestrator 可精细控制事件流、并发、反思循环,避免黑盒。
-
依赖最小化:Bun 运行时不依赖 Python 生态,部署简单。
-
可选 Python 实现:项目同时提供了
mini-services/agent-service-py/(基于 LangGraph + langchain-openai)作为可选实现,两者通过 Socket.io 协议互通,可在start-dev.sh中切换。
7.2 为什么不用向量 RAG?
-
冷启动成本:向量嵌入需要预计算 + 向量数据库,对小型知识库(17 篇)不划算。
-
召回精度:IDF + 正则 + 类别子串的三重打分在 12 类常见错误模式上验证召回率 > 90%。
-
未来演进:架构预留了升级路径,可在
retrieveKB内部替换为向量检索,对调用方无感。
7.3 为什么需要反思迭代?
LLM 是概率性系统,单次推理可能产生:
-
幻觉:声明引用不存在的日志行。
-
过度自信:confidence = 0.95 但实际证据链断裂。
-
遗漏:忽略关键时间窗口或并发事件。
反思闭环通过"深度思考 + 验证 + 反思"三重检查,把单次推理的 70% 准确率提升到 90%+。MAX_ITERATIONS=2 是经验值——超过 2 轮通常意味着日志本身不足以确诊,继续迭代边际收益递减。
7.4 为什么用 Socket.io 而不是 SSE?
-
双向通信:前端需要发送
analyze事件触发分析,SSE 只能单向推送。 -
重连机制:Socket.io 内置自动重连 + 心跳,比手写 SSE 健壮。
-
房间机制:可按 sessionId 隔离事件,未来支持多用户并发诊断。
-
Caddy 兼容:通过
XTransformPort查询参数路由,避免 CORS。
7.5 为什么 C++ 模块不使用 Socket.io?
C++ 分析是 CPU 密集型(规则扫描)+ 串行 LLM 调用,耗时较长(10-60s),不需要实时事件流。前端通过轮询
GET /api/sessions/[id]/code获取结果,更简单可靠。日志诊断因为有多智能体协同 + ReAct 实时思考流,才需要 Socket.io。
附录 A:智能体事件流示例(OOM 场景)
以
search-indexer.log(Java OOM)为例,一次完整诊断的事件流:[orchestrator/status] AIOps 编排器已启动,模型: GLM (Zhipu AI)。 [orchestrator/status] 智能诊断流水线: 采集 → 检索(RAG) → 规划(ReAct) → ... [collector/status] 采集器已启动——解析 312 行原始日志 [collector/result] 解析完成:312 条日志,错误 3,警告 5;FREQUENT TAGS: memory: 3 [retriever/status] 检索器已启动——LLM 扩展查询 + IDF 检索 [retriever/action] query: "OutOfMemoryError heap space memory leak IndexBuilder" [retriever/observation] 命中知识库 4 条:OutOfMemoryError / GC overhead / memory-leak / gc-overhead [planner/thought] 日志中有 OutOfMemoryError + IndexBuilder.java 堆栈 + heap 增长趋势... [planner/action] inspect_metrics [planner/observation] error rate 0.96%, top error source: IndexBuilder.buffer() [planner/thought] 知识库 memory-leak 文章指出"数据结构无限增长"是常见根因... [planner/action] form_plan [planner/result] Plan: 1) 验证 IndexBuilder 数据结构增长 2) 检查 heap dump 3) 评估缓存淘汰策略 [analyst/status] 分析师已启动——根因分析(RCA) [analyst/result] severity=HIGH, confidence=0.78, root cause="Memory leak in IndexBuilder.java..." [orchestrator/thought] 触发深度思考器(置信度 78% < 80%)。 [deep-thinker/thought] 审视证据链:3 条 evidence 均引用真实日志行... [deep-thinker/result] verdict=confirmed, confidence_adjustment=+0.05 [validator/status] 验证器已启动——证据链闭环验证 [validator/result] validated=true, evidenceChain=[root_cause←evidence←trigger], 0 hallucination [fixer/status] 修复器已启动——生成 P0-P3 修复建议 [fixer/result] 4 条修复:P0 改用 WeakHashMap / P1 增加 -Xmx / P2 加 heap dump / P3 加监控 [reviewer/status] 复审器已启动——最终复审与风险评估 [reviewer/result] riskScore=72, strengths=["具体根因"], gaps=["未提供 heap dump 分析"] [orchestrator/result] AIOps 诊断完成——严重程度: HIGH,置信度: 83%,验证: 通过,修复: 4 条。
附录 B:版本演进
版本 关键特性 V1 Socket 连接 + Auto-Collect + 完整诊断流程 + ReAct 事件流 + RCA/修复/复审 V2 暗色模式 + 证据点击定位 + PDF 导出 + UI 打磨 V3 动态 ReAct 循环 + IDF+正则 RAG + 逐行高亮 + 多格式导出 + Agent 指示器 + 骨架屏 V4 可拖拽面板 + 诊断统计条 + 行号点击定位 + 报告动画 + RCA 提示词优化 + OOM 知识库扩充 + 并发限流 + 诊断对比 API V5 大文件流式上传 + Drain 模板提取 + 三级上下文压缩 + Token 预算管理 + DeepThinker + Validator + Reflector + C++ 静态分析(15 规则)+ 运行时日志诊断 + i18n 双语 + 4 模型支持 + 设置 UI + 多视图导航
LogGuard AI — 详细技术文档
版本:V5 适用读者:开发者 / 运维工程师 / 二次开发者
目录
1. 项目结构
logguard-ai/ ├── docs/ # 项目文档 │ ├── DESIGN.md # 详细设计文档 │ └── TECHNICAL.md # 详细技术文档(本文档) │ ├── src/ # 前端 + API Routes 源码 │ ├── app/ # Next.js App Router │ │ ├── layout.tsx # 根布局(含 ThemeProvider) │ │ ├── page.tsx # 主页面(多视图切换) │ │ ├── globals.css # 全局样式 │ │ └── api/ # API 路由 │ │ ├── analyze/ # POST /api/analyze │ │ ├── analyze-code/ # POST /api/analyze-code │ │ ├── code/collect/ # GET /api/code/collect │ │ ├── diff/[ids]/ # GET /api/diff/:idA,:idB │ │ ├── export/[format]/ # GET /api/export/:format │ │ ├── history/ # GET /api/history │ │ ├── knowledge/ # GET/POST /api/knowledge │ │ ├── llm-config/ # GET/POST/DELETE /api/llm-config │ │ ├── logs/ │ │ │ ├── collect/ # GET /api/logs/collect │ │ │ ├── ingest/ # POST /api/logs/ingest │ │ │ ├── search/ # GET /api/logs/search?q= │ │ │ ├── stream-upload/ # POST /api/logs/stream-upload │ │ │ ├── tail/ # GET /api/logs/tail?file= (SSE) │ │ │ └── watch/ # GET /api/logs/watch │ │ ├── sessions/[id]/ # GET /api/sessions/:id │ │ │ ├── code/ # GET /api/sessions/:id/code │ │ │ └── reanalyze/ # POST /api/sessions/:id/reanalyze │ │ └── route.ts # GET /api (health check) │ │ │ ├── components/ # React 组件 │ │ ├── ui/ # shadcn/ui 基础组件(40+ 个) │ │ │ ├── button.tsx │ │ │ ├── dialog.tsx │ │ │ ├── dropdown-menu.tsx │ │ │ ├── select.tsx │ │ │ ├── tooltip.tsx │ │ │ └── ... │ │ └── log-agent/ # LogGuard 业务组件 │ │ ├── agent-graph.tsx # 智能体工作流图(节点状态实时点亮) │ │ ├── concurrency-badge.tsx # 并发状态徽章(idle/active 脉冲) │ │ ├── cpp-ast-view.tsx # C++ AST 摘要展示 │ │ ├── cpp-code-input.tsx # C++ 代码输入框(含拖拽上传) │ │ ├── cpp-issue-list.tsx # C++ 静态问题列表 │ │ ├── cpp-report-view.tsx # C++ 分析报告 │ │ ├── cpp-types.ts # C++ 分析类型定义 │ │ ├── diff-dialog.tsx # 诊断对比 Dialog │ │ ├── event-stream.tsx # ReAct 事件流(终端样式实时滚动) │ │ ├── history-panel.tsx # 历史会话面板 │ │ ├── knowledge-panel.tsx # 知识库浏览器(含 RAG 搜索) │ │ ├── large-log-uploader.tsx # 大文件拖拽上传组件 │ │ ├── llm-config-dialog.tsx # LLM 配置 Dialog(4 提供商 Tab) │ │ ├── log-input.tsx # 日志输入框(含逐行高亮、行号定位) │ │ ├── model-selector.tsx # 模型选择器(Qwen/GLM/DeepSeek/StepFun) │ │ ├── report-view.tsx # 诊断报告(RCA/Fixes/Review/Plan/Stats Tab) │ │ ├── sidebar.tsx # 多视图导航侧边栏 │ │ ├── stats-bar.tsx # 诊断统计条(5 个 chip) │ │ ├── types.ts # 业务组件类型定义 │ │ └── views/ # 主视图容器 │ │ ├── cpp-view.tsx # C++ 分析视图 │ │ ├── history-view.tsx # 历史视图 │ │ ├── knowledge-view.tsx # 知识库视图 │ │ ├── log-view.tsx # 日志诊断视图(默认) │ │ └── settings-view.tsx # 设置视图 │ │ │ ├── hooks/ # 自定义 Hooks │ │ ├── use-t.ts # i18n 翻译 Hook(useCallback 记忆化) │ │ ├── use-toast.ts # Toast 通知 Hook │ │ └── use-mobile.ts # 移动端检测 Hook │ │ │ └── lib/ # 核心逻辑 │ ├── db.ts # Prisma 客户端单例 │ ├── i18n.ts # 中英双语字典(~100 keys) │ ├── store.ts # Zustand 全局状态(locale、currentSession 等) │ └── utils.ts # 通用工具(cn 类名合并等) │ └── agents/ # 多智能体系统(核心) │ ├── orchestrator.ts # 日志诊断编排器 │ ├── cpp-orchestrator.ts # C++ 分析编排器 │ ├── collector.ts # 采集器 │ ├── retriever.ts # RAG 检索器 │ ├── planner.ts # ReAct 规划器 │ ├── analyst.ts # RCA 分析师 │ ├── deep-thinker.ts # 深度思考器(条件触发) │ ├── validator.ts # 证据链验证器 │ ├── reflector.ts # 反思器(闭环迭代) │ ├── fixer.ts # 修复器 │ ├── reviewer.ts # 复审器 │ ├── llm.ts # LLM 调用封装(4 模型 + 双路径) │ ├── llm-config.ts # LLM 配置解析器(15s 缓存) │ ├── prompts.ts # 所有智能体的 system prompts │ ├── types.ts # 共享类型定义 │ ├── log-parser.ts # 日志解析器 │ ├── log-template.ts # Drain 模板提取 │ ├── context-compressor.ts # 三级上下文压缩 │ ├── context-manager.ts # Token 预算管理器 │ ├── knowledge-base.ts # 知识库 + RAG 检索 │ ├── cpp-parser.ts # C++ AST 解析器 │ ├── cpp-analyzer.ts # C++ 15 条静态分析规则 │ └── cpp-runtime-parser.ts # C++ 运行时日志信号提取 │ ├── mini-services/ # 微服务 │ ├── agent-service/ # Bun Socket.io 服务(端口 3003) │ │ ├── index.ts # 主入口(并发限流 + 事件流) │ │ ├── package.json │ │ ├── tsconfig.json │ │ └── bun.lock │ └── agent-service-py/ # Python LangGraph 替代实现(可选) │ ├── main.py # uvicorn 入口 │ ├── server.py # Socket.io 服务端 │ ├── orchestrator.py # LangGraph 编排 │ ├── agents.py # 9 个智能体 │ ├── llm.py # LLM 调用 │ ├── log_parser.py # 日志解析 │ ├── knowledge_base.py # 知识库 │ ├── models.py # Pydantic 模型 │ ├── db.py # SQLite 访问 │ ├── config.py # 配置 │ ├── prompts.py # 系统提示词 │ ├── pyproject.toml │ └── requirements.txt │ ├── scripts/ # 运维脚本 │ ├── start-dev.sh # 开发环境启动脚本 │ └── start-prod.sh # 生产环境启动脚本 │ ├── prisma/ │ └── schema.prisma # Prisma 数据库 schema │ ├── sample-logs/ # 示例日志 │ ├── payments-service.log # 连接池耗尽场景 │ ├── search-indexer.log # OOM 场景 │ └── auth-and-api.log # 认证 + JSON + 网络场景 │ ├── sample-code/ # 示例 C++ 代码 │ ├── memory_leak.cpp # 内存泄漏 │ ├── data_race.cpp # 数据竞争 │ └── use_after_free.cpp # Use-After-Free │ ├── public/ # 静态资源 │ ├── logo.svg │ └── robots.txt │ ├── db/ │ └── custom.db # SQLite 数据库文件 │ ├── Caddyfile # Caddy 反向代理配置(端口 81) ├── package.json ├── tsconfig.json ├── tailwind.config.ts ├── postcss.config.mjs ├── next.config.ts ├── eslint.config.mjs ├── components.json # shadcn/ui 配置 └── README.md
2. API 路由
所有 API 路由位于
src/app/api/,遵循 Next.js App Router 约定。统一返回 JSON 格式{ ok: boolean, ... } | { error: string }。2.1 诊断会话管理
POST /api/analyze— 创建日志诊断会话创建一个
AnalysisSession行(status=pending),返回 sessionId。实际的多智能体运行通过 Socket.io "analyze" 事件触发。-
请求体:
{ "model": "qwen" | "glm" | "deepseek" | "stepfun", // 可选,默认 "glm" "rawLogs": "string", // 必填,原始日志文本 "source": "string", // 可选,日志来源标识 "title": "string" // 可选,会话标题 }-
响应:
{ "ok": true, "sessionId": "cmqi...", "title": "...", "model": "glm" }-
错误:400(rawLogs 为空)/ 500(DB 错误)
POST /api/analyze-code— 创建 C++ 分析会话创建会话并在后台运行 C++ 编排器。HTTP 响应立即返回,客户端轮询
/api/sessions/[id]/code获取结果。-
请求体:
{ "files": [{ "path": "main.cpp", "content": "..." }], // 必填 "model": "glm", // 可选,默认 "glm" "title": "string", // 可选 "run": true, // 可选,默认 true "runtimeLogs": "string" // 可选,运行时日志(ASAN/Valgrind/GDB/编译器) }-
响应:
{ ok, sessionId, title, model, status } -
maxDuration:300s(LLM 调用可能超过 10s)
GET /api/sessions/[id]— 获取会话完整回放返回会话元信息 + 完整诊断结果 + 事件流数组。
-
路径参数:
id— 会话 ID -
响应:
{ "ok": true, "session": { "id", "title", "model", "status", "severity", "createdAt" }, "result": { "plan", "rca", "fixes", "review", "knowledgeHits", "logStats" }, "events": [{ "id", "agent", "type", "content", "meta", "timestamp" }] }-
错误:404(会话不存在)
GET /api/sessions/[id]/code— 获取 C++ 会话结果返回持久化的 CodeFile + CodeIssue 行 + 重建的 AST 摘要 + 指标。客户端轮询此端点获取 C++ 分析结果。
-
响应:
{ ok, sessionId, status, files, issues, ast, metrics, topRiskAreas, runtimeLogAnalysis, summary }
POST /api/sessions/[id]/reanalyze— 重新分析加载原会话的 LogEntry 行(按 createdAt 升序,保留原始顺序),重建 rawLogs,创建新的 AnalysisSession(标题 "Re-analysis of {原标题}"),返回新 sessionId。前端可随后通过 Socket.io 触发实际分析。
-
请求体(可选):
{ "model": "qwen" | "glm" | "deepseek" } -
模型回退逻辑:body.model > 原会话 model > "glm"
-
错误:400(会话无 LogEntry)/ 404(会话不存在)
2.2 历史与对比
GET /api/history— 列出历史会话返回最近 50 个会话(按 createdAt 降序)。
-
响应:
{ "ok": true, "sessions": [{ "id", "title", "model", "status", "severity", "errorCount", "warnCount", "createdAt" }] }GET /api/diff/[ids]— 对比两个诊断会话ids为逗号分隔的两个 sessionId,例如/api/diff/sess1,sess2。返回对比字段:-
响应:
{ "ok": true, "sessions": { "a": { ...meta }, "b": { ...meta } }, "severityChanged": true, "rootCauseChanged": false, "confidenceDelta": 0.15, "riskScoreDelta": -10, "errorCountDelta": 0, "fixesAdded": [{ "title", "priority", "type" }], "fixesRemoved": [], "sharedEvidence": [{ "log", "explanation" }] }2.3 日志管理
GET /api/logs/collect— 自动采集示例日志读取
sample-logs/目录下所有.log/.txt文件,返回每个文件的内容 + 统计 + 预览。-
响应:
{ "ok": true, "files": [{ "name": "payments-service.log", "content": "...", "stats": { "total", "errors", "warnings", "byLevel" }, "preview": [{ "level", "message", "source", "timestamp" }] }] }POST /api/logs/ingest— 解析并存储原始日志把原始日志文本解析为 ParsedLog 数组,存入 LogEntry 表(sessionId=null),返回结构化预览。
-
请求体:
{ "rawLogs": "string", "source": "string" } -
响应:
{ ok, count, stats, digest, entries[] }
POST /api/logs/stream-upload— 大文件流式上传支持 multipart/form-data 或纯文本。按 50k 行/批分片解析,最大 1000 万行。返回 Drain 模板 + 三级压缩 + 上下文管理器统计。
-
请求:multipart(
file字段)或 text/plain -
响应:
{ "ok": true, "fileName": "huge.log", "stats": { "totalLines", "parsedEntries", "errorLines", "warnLines", "byLevel", "processingMs" }, "templates": [{ "template", "count", "level", "examples" }], // Top 50 "compressed": { "l1", "l2", "l3", "tokenEstimate", "compressionRatio" }, "contextStats": { "budgetUsed", "budgetTotal", "fragmentsAvailable", "fragmentsLoaded" } }-
maxDuration:300s
-
错误:400(空文件)/ 413(超过 1000 万行限制)
GET /api/logs/search?q=— RAG 检索对知识库执行 IDF + 正则 + 类别子串打分检索。
-
查询参数:
q— 搜索关键词 -
响应:
{ "ok": true, "query": "OutOfMemoryError heap space", "hits": [{ "id", "title", "category", "summary", "cause", "fix", "score" }] }GET /api/logs/watch— 列出 / 查看日志文件无参数:列出
sample-logs/*.log|*.txt,每个文件返回 name/size/mtime/tail(最后 50 行)。 带参数:?file=NAME&lines=N返回指定文件的最后 N 行(N 默认 50,clamp 到 [1, 5000])。-
错误:400(路径遍历 / 非 .log/.txt 后缀)/ 404(文件不存在)
GET /api/logs/tail?file=— SSE 实时日志尾随Server-Sent Events 端点,2 秒轮询 + 10 秒心跳。模块级
fileCursors: Map跨连接共享游标,新连接只接收追加内容(不重发历史)。-
响应:
text/event-stream,事件类型hello/line/rotated/heartbeat/error -
特殊 Header:
X-Accel-Buffering: no(强制 Caddy 立即 flush) -
错误:400(无 file)/ 404(文件不存在)
2.4 知识库
GET /api/knowledge— 列出知识库文章首次访问触发
ensureKBSeeded(),从代码内 SEED 数组填充 17+ 篇预置文章。-
响应:
{ ok, articles: [{ id, title, category, summary, cause, fix, pattern }] }
POST /api/knowledge— 新增 / 重置知识库-
请求体:
{ "reset": false, "title", "category", "pattern", "summary", "cause", "fix", "keywords" } -
响应:
{ ok, id }
2.5 LLM 配置
GET /api/llm-config— 列出所有 LLM 提供商配置API Key 从不直接返回,只返回
hasKey: boolean+keyHint: "sk-••••••ret"掩码形式。-
响应:
{ "ok": true, "configs": [{ "provider": "qwen", "baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1", "modelName": "qwen-plus", "enabled": true, "hasKey": true, "keyHint": "sk-••••••ret", "defaults": { "baseUrl", "modelName", "docs" } }] }POST /api/llm-config— 新增/更新 LLM 配置如果
apiKey为空字符串或掩码占位符(包含••••),保留数据库中已有的 key。-
请求体:
{ "provider", "baseUrl", "apiKey", "modelName", "enabled" } -
响应:
{ ok, provider, enabled, hasKey } -
副作用:调用
invalidateModelConfigCache()立即生效
DELETE /api/llm-config?provider=qwen— 删除 LLM 配置-
查询参数:
provider— 必填,4 个合法值之一
2.6 C++ 代码
GET /api/code/collect— 自动采集示例 C++ 文件读取
sample-code/目录下.cpp/.cc/.cxx/.c/.h/.hpp/.hh文件,分类语言,返回 path/content/lineCount/size。2.7 导出
GET /api/export/[format]?sessionId=&locale=— 导出诊断报告-
路径参数:
format—"markdown"或"json" -
查询参数:
sessionId(必填)、locale(可选,zh默认 /en) -
响应:
-
json:application/json+Content-Disposition: attachment; filename="diagnosis-{id}.json" -
markdown:text/markdown; charset=utf-8+Content-Disposition: attachment; filename="diagnosis-{id}.md" -
Markdown 报告包含:标题 + 元信息 + 严重程度/置信度 + 主根因 + 促成因素 + 证据链(代码块)+ 时间线 + 修复建议(P0-P3 优先级徽章 + 代码片段 + 预防建议)+ 复审(风险评分 + strengths/gaps/recommendations)+ 日志统计 + 生成时间戳
-
-
错误:400(不支持格式 / 缺 sessionId)/ 404(会话不存在)
2.8 健康检查
GET /api— 健康检查返回服务状态、版本信息。
3. 数据库 Schema
数据库为 SQLite(位于
db/custom.db),通过 Prisma ORM 访问。Schema 定义在prisma/schema.prisma。3.1 实体关系图
┌─────────────────────┐ │ AnalysisSession │ 一次诊断会话(日志或 C++) └──────────┬──────────┘ │ 1 │ ├─────< LogEntry 解析后的日志行 │ ├─────< AgentEvent 智能体事件流 │ ├─────< CodeFile C++ 源文件 │ └─────< CodeIssue C++ 静态分析问题 ┌─────────────────────┐ │ KnowledgeArticle │ 知识库条目(独立表,RAG 索引源) └─────────────────────┘ ┌─────────────────────┐ │ LlmConfig │ LLM 提供商配置(独立表,4 个 provider) └─────────────────────┘3.2 模型详解
AnalysisSession— 诊断会话字段 类型 说明 idString @id CUID 自动生成 titleString 会话标题(自动从日志中提取首条 ERROR 行) modelString 使用的模型: qwen/glm/deepseek/stepfunstatusString pending/running/completed/failedlogSummaryString? 输入日志的 1000 字摘要 rootCauseString? 最终 RCA 的 JSON 字符串( RootCauseAnalysis序列化)fixesString? 最终修复建议的 JSON 数组字符串 summaryString? 包含 plan + review + validation + deepThinking + reflection 的综合 JSON severityString? critical/high/medium/lowerrorCountInt 错误日志行数 warnCountInt 警告日志行数 createdAtDateTime 创建时间 updatedAtDateTime 更新时间(@updatedAt) 关系 events: AgentEvent[]、logEntries: LogEntry[]、codeFiles: CodeFile[]、codeIssues: CodeIssue[]索引 @@index([createdAt])LogEntry— 解析后的日志行字段 类型 说明 idString @id CUID sessionIdString? 关联会话;可为 null(通用 ingest buffer) rawString 原始日志行文本 timestampString? 解析出的时间戳 levelString INFO/WARN/ERROR/DEBUG/TRACE/FATALsourceString? 文件名 / 组件名 messageString 提取的日志消息正文 stackString? 堆栈(多行合并) tagsString JSON 数组字符串,例如 ["memory","database"]createdAtDateTime 创建时间 关系 session: AnalysisSession?(onDelete: Cascade)索引 @@index([sessionId])、@@index([level])AgentEvent— 智能体事件流字段 类型 说明 idString @id CUID sessionIdString 关联会话 agentString orchestrator/collector/retriever/planner/analyst/deep-thinker/validator/reflector/fixer/reviewer/cpp-parser/static-analyzertypeString status/thought/action/observation/result/error/suggestioncontentString 人类可读的事件内容 metaString? 可选的 JSON 元数据(如 { severity, confidence, fixes, risk })createdAtDateTime 创建时间 关系 session: AnalysisSession(onDelete: Cascade)索引 @@index([sessionId])KnowledgeArticle— 知识库条目字段 类型 说明 idString @id CUID titleString 标题(如 "OutOfMemoryError: Java heap space") categoryString 类别(如 memory/database/network/concurrency)patternString 正则表达式,RAG 检索时用于模式匹配(+3 分) summaryString 一句话摘要 causeString 常见原因(多段文本) fixString 修复建议(多段文本) keywordsString 空格分隔的关键词,用于 IDF 检索 createdAtDateTime 创建时间 索引 @@index([category])CodeFile— C++ 源文件字段 类型 说明 idString @id CUID sessionIdString 关联会话 pathString 文件路径 languageString cpp/h/cc/cxxcontentString 文件完整内容 lineCountInt 行数 createdAtDateTime 创建时间 关系 session: AnalysisSession(onDelete: Cascade)索引 @@index([sessionId])CodeIssue— C++ 静态分析问题字段 类型 说明 idString @id CUID sessionIdString 关联会话 ruleIdString 规则 ID(如 CPP-MEM-001)ruleNameString 规则名称 categoryString memory/concurrency/undefined-behavior/raii/resource/performance/modern-cpp/securityseverityString critical/high/medium/low/infofileString 文件路径 lineInt 起始行号 endLineInt? 结束行号 columnInt? 列号 snippetString 问题代码片段 messageString 问题描述 explanationString 为什么是问题 suggestionString 修复建议 fixCodeString? 修复后的代码示例 cweString? CWE 编号(如 CWE-401)confidenceFloat 置信度 0-1 createdAtDateTime 创建时间 关系 session: AnalysisSession(onDelete: Cascade)索引 @@index([sessionId])、@@index([severity])LlmConfig— LLM 提供商配置字段 类型 说明 idString @id CUID providerString @unique 4 个唯一值: qwen/glm/deepseek/stepfunbaseUrlString? OpenAI 兼容 API 的 base URL apiKeyString? API Key(服务端存储,从不返回给浏览器) modelNameString? 模型名(如 qwen-plus、glm-4-plus)enabledBoolean 是否启用(默认 false) updatedAtDateTime 更新时间 createdAtDateTime 创建时间 3.3 数据库迁移命令
bun run db:push # 推送 schema 到 SQLite(开发期推荐) bun run db:generate # 生成 Prisma Client bun run db:migrate # 创建迁移文件(生产期推荐) bun run db:reset # 重置数据库(删除所有数据)
4. 大模型配置
4.1 支持的 4 个提供商
Provider ID 厂商 默认 Base URL 默认模型 文档 qwen阿里巴巴通义千问 https://dashscope.aliyuncs.com/compatible-mode/v1qwen-plusDashScope 兼容模式 glm智谱 AI https://open.bigmodel.cn/api/paas/v4glm-4-plus智谱 API deepseekDeepSeek https://api.deepseek.com/v1deepseek-chatDeepSeek API stepfun阶跃星辰 https://api.stepfun.com/v1step-2-16kStepFun Docs 4.2 OpenAI 兼容协议
所有 4 个提供商均兼容 OpenAI Chat Completions API 格式,统一通过
POST {baseUrl}/chat/completions调用:// src/lib/agents/llm-config.ts export async function callOpenAICompatible( baseUrl: string, apiKey: string, modelName: string, messages: { role: "system" | "user" | "assistant"; content: string }[], options: { temperature?: number; maxTokens?: number; json?: boolean } ): Promise<string>请求格式:
{ "model": "qwen-plus", "messages": [ { "role": "system", "content": "你是 AIOps 分析师..." }, { "role": "user", "content": "分析以下日志..." } ], "temperature": 0.3, "max_tokens": 2000, "response_format": { "type": "json_object" } // 当 options.json=true 时 }4.3 双路径调用机制
src/lib/agents/llm.ts的chat()函数实现双路径:chat(opts) │ ▼ resolveModelConfig(opts.model) ── 15s 内存缓存 ── LlmConfig 表 │ ├─ Path 1: 用户已配置且 enabled=true │ ↓ │ callOpenAICompatible(baseUrl, apiKey, modelName, ...) │ ↓ 使用标准 system role │ 返回 content │ └─ Path 2: 未配置或 enabled=false ↓ z-ai-web-dev-sdk(环境内置,无需 API Key) ↓ 保留 assistant role quirks(z-ai SDK 兼容性) 返回 content配置变更立即生效:POST/DELETE
/api/llm-config调用invalidateModelConfigCache()清空 15s 缓存。4.4 用户配置 UI
设置视图(
src/components/log-agent/views/settings-view.tsx)+ LLM 配置 Dialog(src/components/log-agent/llm-config-dialog.tsx)提供:-
4 个 Tab 对应 4 个 provider
-
每个 Tab 3 个输入字段:
LLM_BASE_URL/LLM_API_KEY(password 输入 + 显示/隐藏切换)/LLM_MODEL_NAME -
启用/禁用 Switch
-
默认值快捷填充按钮(从
PROVIDER_DEFAULTS取) -
文档链接
-
API Key 掩码显示(
sk-••••••ret) -
保存/重置按钮
4.5 多模型 Persona 适配
即使使用同一种底层 API,不同模型在 prompt 中会注入不同的 system persona(
src/lib/agents/llm.ts#MODEL_PROFILES):模型 Persona 摘要 Qwen "你以 Qwen(阿里巴巴)的风格运行。你擅长长上下文代码和日志理解。要精确、结构化,倾向具体的技术细节。" GLM "你以 GLM(智谱 AI)的风格运行。你平衡且可靠,擅长工具使用和结构化输出。偏好将问题分解为清晰的步骤。" DeepSeek "你以 DeepSeek 的风格运行。你是一个深度推理者:逐步思考,呈现假设,考虑替代方案,然后得出结论。" StepFun "你以阶跃星辰(StepFun)的风格运行。你擅长长文本理解和中文场景的深度推理。"
5. i18n 国际化
5.1 设计目标
-
支持 中文(zh) 和 英文(en) 双语
-
单页应用,不依赖
next-intl的复杂路由 -
Locale 持久化到 localStorage
-
翻译函数
t(key)高性能(useCallback 记忆化)
5.2 实现
5.2.1 字典定义(
src/lib/i18n.ts)export type Locale = "en" | "zh"; const en: Dict = { "nav.log": "Log Diagnosis", "nav.cpp": "C++ Analysis", "report.severity": "Severity", "report.primaryRootCause": "Primary Root Cause", // ... ~100 keys 覆盖 nav、report、history、knowledge、settings、agent 名称 }; const zh: Dict = { "nav.log": "日志诊断", "nav.cpp": "C++ 分析", "report.severity": "严重程度", "report.primaryRootCause": "主要根因", // ... }; export function translate(locale: Locale, key: string): string { const dict = locale === "zh" ? zh : en; return dict[key] ?? key; // 找不到时返回 key 本身作为兜底 }5.2.2 全局状态(
src/lib/store.ts)interface AppState { locale: Locale; setLocale: (l: Locale) => void; // ... 其他状态 } // Zustand persist 中间件自动把 locale 持久化到 localStorage export const useStore = create<AppState>()( persist( (set) => ({ locale: "zh", // 默认中文 setLocale: (locale) => { set({ locale }); localStorage.setItem("logguard-locale", locale); }, // ... }), { name: "logguard-store" } ) );5.2.3 翻译 Hook(
src/hooks/use-t.ts)import { useCallback } from "react"; import { useStore } from "@/lib/store"; import { translate, type Locale } from "@/lib/i18n"; export function useT() { const locale = useStore((s) => s.locale); // useCallback 记忆化:locale 不变时返回同一个函数引用, // 避免子组件不必要的重渲染 return useCallback( (key: string) => translate(locale as Locale, key), [locale] ); }5.2.4 在组件中使用
import { useT } from "@/hooks/use-t"; function ReportView({ rca }) { const t = useT(); return ( <Card> <CardTitle>{t("report.primaryRootCause")}</CardTitle> <CardContent>{rca.primaryRootCause}</CardContent> </Card> ); }5.3 Locale 切换 UI
侧边栏顶部(
src/components/log-agent/sidebar.tsx)有 Languages 图标按钮,显示中或EN,点击切换 locale。Zustand persist 自动同步到 localStorage,刷新页面后保持选择。5.4 导出报告的本地化
/api/export/[format]?locale=zh|en端点根据 locale 参数生成本地化的 Markdown 报告——所有章节标题(诊断报告 / 严重程度 / 主要根因 / 证据 / 修复 / 复审 等)都会按 locale 翻译,时间戳按zh-CN/en-USlocale 格式化。
6. 大文件处理
6.1 挑战
日志文件动辄百万行,远超 LLM 上下文窗口(典型 8k-32k token)。直接全量塞入会:
-
超出 token 限制,API 返回 413/400
-
即使不超限,注意力分散导致 LLM 抓不住关键信号
-
推理延迟从秒级涨到分钟级
6.2 解决方案:流式上传 + Drain 模板 + 三级压缩 + Token 预算
6.2.1 流式上传 API
POST /api/logs/stream-upload(src/app/api/logs/stream-upload/route.ts):const BATCH_SIZE = 50000; // 5 万行/批 const MAX_LINES = 10_000_000; // 1000 万行硬上限 // 分片处理,避免一次性加载到内存 for (let i = 0; i < allLines.length; i += BATCH_SIZE) { const batch = allLines.slice(i, Math.min(i + BATCH_SIZE, allLines.length)); allEntries.push(...parseLogs(batch.join("\n"))); }支持两种 Content-Type:
-
multipart/form-data(带file字段,UI 拖拽上传) -
text/plain(直接 POST 文本)
6.2.2 Drain 日志模板提取
src/lib/agents/log-template.ts#extractTemplates:经典 Drain 算法实现,把相似日志行归并为模板。例如:
原始日志: 2024-01-01 10:00:00 ERROR [OrderService] Failed to process order 12345: timeout 2024-01-01 10:00:01 ERROR [OrderService] Failed to process order 12346: timeout 2024-01-01 10:00:02 ERROR [OrderService] Failed to process order 12347: timeout 提取模板: 2024-01-01 10:00:<*> ERROR [OrderService] Failed to process order <*>: timeout count: 3 examples: [上述 3 行] params: [["00", "12345"], ["01", "12346"], ["02", "12347"]]
变量识别规则(
isVariable):-
纯数字(
\d+) -
十六进制地址(
0x[0-9a-fA-F]+) -
长 hex 串(8+ 位)
-
IP 地址(含端口)
-
路径(
/...) -
带引号字符串
-
123ms/45s等时间值
6.2.3 三级上下文压缩
src/lib/agents/context-compressor.ts#compressContext:级别 名称 内容 字符上限 L1 宏观压缩 时间线摘要,按分钟桶聚合日志数/错误数/警告数 4000 L2 中观结构化 因果链——按 traceId/requestId 聚合;无 trace 时按错误因果排序 2000 L3 微观裁剪 错误行 ±5 行的完整上下文(最多 10 个错误点),其余折叠 6000 6.2.4 Token 预算管理
src/lib/agents/context-manager.ts:export const DEFAULT_BUDGET: TokenBudget = { total: 8000, systemPrompt: 1000, compressedLogs: 3000, // L1+L2+L3 拼接后塞入 ragRetrieval: 2000, // RAG 命中的知识库条目 reasoning: 2000, // LLM 思考 + 输出预留 };Token 估算:CJK 字符 ÷2 + 其他字符 ÷4(近似 GPT tokenizer 行为)。
按需片段召回:除了 active window,ContextManager 还会预生成 20+ 个可加载片段(错误行周边上下文、模板示例、错误 burst 段),下游智能体需要更细的上下文时可显式请求加载,避免一次性塞满。
6.3 大文件上传 UI
src/components/log-agent/large-log-uploader.tsx:-
拖拽上传区(dashed border + drag over 高亮)
-
文件选择按钮(accept
.log,.txt) -
上传进度条
-
上传完成后展示:
-
文件统计(总行数 / 解析条目数 / 错误行数 / 警告行数 / 处理耗时)
-
Drain 模板列表(Top 50,每条展示模板文本 + 出现次数 + 3 个示例)
-
三级压缩预览(L1 / L2 / L3 三段文本 + 压缩比)
-
Token 预算使用情况(budgetUsed / budgetTotal + 可加载片段数)
-
7. 部署
7.1 服务架构
┌─────────────────────────────────────┐ │ Caddy :81 │ │ (反向代理 + XTransformPort 路由) │ └──────┬────────────────────┬─────────┘ │ HTTP │ HTTP + WS (XTransformPort=3003) ▼ ▼ ┌────────────────┐ ┌────────────────────┐ │ Next.js :3000 │ │ agent-service:3003│ │ (App Router │ │ (Bun Socket.io) │ │ + API Routes)│ │ 运行 Orchestrator │ └──────┬─────────┘ └─────────┬──────────┘ │ Prisma │ Prisma ▼ ▼ ┌────────────────────────────────────────┐ │ SQLite (db/custom.db) │ └────────────────────────────────────────┘3 个服务:
服务 端口 职责 启动方式 Caddy 81 反向代理网关,路由 /api/*到 Next.js、/?XTransformPort=3003到 agent-service系统管理(systemd) Next.js 3000 前端 SSR + API Routes bunx next dev(开发)/bunx next start(生产)agent-service 3003 Socket.io 服务,运行多智能体编排 bun --hot index.ts(开发)/bun index.ts(生产)7.2 开发环境部署
7.2.1 一键启动
# 安装依赖 bun install # 推送数据库 schema bun run db:push # 启动所有服务(Next.js + agent-service,Caddy 由系统管理) bun run dev
bun run dev实际执行bash scripts/start-dev.sh,该脚本:-
清理残留进程:
pkill -f "agent-service/index.ts"+pkill -f "next dev"+ 强制 kill 占用 3000/3003 端口的进程。 -
启动 agent-service(后台):
cd mini-services/agent-service && nohup bun --hot index.ts >> agent-service.log 2>&1 & -
等待端口就绪:循环 10 次,每秒检查
ss -ltnp | grep :3003。 -
启动 Next.js dev server(前台):
exec bunx next dev -p 3000 2>&1 | tee dev.log
7.2.2 单独启动某个服务
bun run dev:next # 仅启动 Next.js bun run dev:agent # 仅启动 agent-service
7.3 生产环境部署
# 先 build bun run build # 启动所有服务(生产模式) bun run start
bun run start执行bash scripts/start-prod.sh,差异:-
agent-service 用
bun index.ts(无--hot热重载) -
Next.js 用
NODE_ENV=production bunx next start -p 3000(生产模式) -
日志输出到
server.log而非dev.log
7.4 Caddy 网关配置
Caddyfile(端口 81)::81 { # 匹配 XTransformPort 查询参数的请求 → 路由到对应端口 @transform_port_query { query XTransformPort=* } handle @transform_port_query { reverse_proxy localhost:{query.XTransformPort} { header_up Host {host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} header_up X-Real-IP {remote_host} } } # 默认路由 → Next.js :3000 handle { reverse_proxy localhost:3000 { header_up Host {host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} header_up X-Real-IP {remote_host} } } }XTransformPort 路由技巧:
-
前端访问
/api/history→ Caddy 默认路由 →localhost:3000/api/history(Next.js API) -
前端访问
socket.io/?XTransformPort=3003→ Caddy 匹配@transform_port_query→localhost:3003/socket.io/(agent-service) -
同域名同端口,避免 CORS 问题
-
Caddy 自动处理 HTTPS(生产环境)
7.5 数据库
-
位置:
db/custom.db(SQLite 单文件) -
环境变量:
DATABASE_URL="file:./db/custom.db"(在.env中配置) -
备份:直接复制
db/custom.db文件即可 -
重置:
bun run db:reset(删除所有数据,谨慎使用)
7.6 环境变量
.env文件示例:DATABASE_URL="file:./db/custom.db" # 可选:直接配置 LLM(绕过 UI 配置) # QWEN_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 # QWEN_API_KEY=sk-xxx # QWEN_MODEL_NAME=qwen-plus # GLM_BASE_URL=https://open.bigmodel.cn/api/paas/v4 # GLM_API_KEY=xxx # GLM_MODEL_NAME=glm-4-plus # DEEPSEEK_BASE_URL=https://api.deepseek.com/v1 # DEEPSEEK_API_KEY=sk-xxx # DEEPSEEK_MODEL_NAME=deepseek-chat # STEPFUN_BASE_URL=https://api.stepfun.com/v1 # STEPFUN_API_KEY=xxx # STEPFUN_MODEL_NAME=step-2-16k
未配置 LLM 环境变量且未通过 UI 配置时,系统回退到
z-ai-web-dev-sdk(无需 API Key)。7.7 健康检查
启动后访问以下端点验证:
# Next.js API 健康 curl http://localhost:81/api # 历史 API curl http://localhost:81/api/history # 知识库(首次访问触发 seeding) curl http://localhost:81/api/knowledge # LLM 配置 curl http://localhost:81/api/llm-config # 服务端口检查 ss -ltnp | grep -E ':3000|:3003|:81'
预期输出:
LISTEN 0 4096 *:81 *:* LISTEN 0 511 *:3000 *:* users:(("next-server",pid=...)) LISTEN 0 512 *:3003 *:* users:(("bun",pid=...))7.8 故障排查
现象 排查方向 前端无法连接 Socket 检查 agent-service 是否在 3003 监听;Caddy 是否运行;浏览器控制台 Socket.io 错误 诊断一直 pending 检查 agent-service.log;MAX_CONCURRENT=3 是否队列已满;LLM 是否超时LLM 调用 401 检查 LlmConfig.apiKey 是否正确;UI 设置面板重新输入 数据库锁 SQLite 单写入,并发诊断时可能锁;查看 agent-service.log中的SQLITE_BUSY端口占用 bash scripts/start-dev.sh会自动清理 3000/3003,Caddy 81 需手动systemctl restart caddy知识库文章数为 0 首次访问 /api/knowledge触发 seeding;若仍为 0,检查db.custom.db写入权限7.9 性能调优
参数 位置 默认值 调优建议 MAX_CONCURRENTagent-service/index.ts3 上游 LLM 限流严格时降低;本地 LLM 提高到 5-8 QUEUE_TIMEOUT_MSagent-service/index.ts120000 用户容忍度低时降低到 60s MAX_CYCLES(ReAct)planner.ts5 复杂场景提高到 8;简单场景降低到 3 MAX_ITERATIONS(反思)orchestrator.ts2 追求准确率提高到 3;追求速度降低到 1 DEFAULT_BUDGET.totalcontext-manager.ts8000 模型上下文窗口大时提高到 16k-32k BATCH_SIZE(流式上传)stream-upload/route.ts50000 内存充足时提高到 100k
附录 A:开发工作流
A.1 添加新的智能体
-
在
src/lib/agents/新建my-agent.ts,导出runMyAgent(...)函数,签名遵循(inputs..., model, emit) => Promise<Result>。 -
在
src/lib/agents/types.ts的AgentName联合类型中添加"my-agent"。 -
在
src/lib/agents/prompts.ts中添加MY_AGENT_PROMPT。 -
在
orchestrator.ts的流水线中插入调用,决定前置/后置节点。 -
在前端
agent-graph.tsx的节点链中添加新节点。 -
在 i18n 字典中添加 agent 名称翻译。
A.2 添加新的 C++ 静态分析规则
-
在
src/lib/agents/cpp-analyzer.ts中定义const RULE_XXX_001: Rule = { ruleId, ruleName, category, severity, cwe?, confidence, run }。 -
run函数签名:(ctx: RuleCtx) => CppIssue[],ctx包含{ file, ast }。 -
在文件底部的
RULES: Rule[]数组中添加新规则。 -
规则自动被
analyzeCppCode()调用,无需修改 orchestrator。
A.3 添加新的知识库文章
两种方式:
方式 1:代码内 SEED(推荐用于内置文章)
在
src/lib/agents/knowledge-base.ts的SEED: KBSeed[]数组中添加:{ title: "Your new error pattern", category: "your-category", pattern: "YourErrorPattern|specific error text", // 正则 summary: "One-line summary", cause: "Multi-paragraph cause analysis", fix: "Multi-paragraph fix suggestions", keywords: "your error pattern specific keywords", // 空格分隔 }然后调用
POST /api/knowledge { reset: true }重置并重新 seed。方式 2:运行时 API(推荐用于用户自定义)
curl -X POST http://localhost:81/api/knowledge \ -H "Content-Type: application/json" \ -d '{ "title": "Custom error", "category": "custom", "pattern": "CustomError", "summary": "...", "cause": "...", "fix": "...", "keywords": "custom error" }'
附录 B:代码风格与约定
-
TypeScript:strict 模式,所有函数参数和返回值显式标注类型。
-
ESLint:
eslint-config-next,0 errors / 0 warnings 是合并门槛。 -
命名:
-
文件:
kebab-case.ts(如deep-thinker.ts) -
类型/接口:
PascalCase(如RootCauseAnalysis) -
函数:
camelCase(如runAnalyst) -
常量:
UPPER_SNAKE_CASE(如MAX_ITERATIONS) -
React 组件:
PascalCase.tsx(如ReportView)
-
-
Prisma 模型:
PascalCase,字段camelCase。 -
API 路由:RESTful 风格,统一返回
{ ok: boolean, ... } | { error: string }。 -
错误处理:所有
async函数用try/catch包裹,错误持久化到 session.status="failed"。 -
国际化:所有面向用户的字符串必须通过
t(key)翻译,禁止硬编码中文/英文。
-
