refactor(ai): 砍掉 /aiops 整页,模型配置迁入系统设置,浮窗助手保留
评估结论落地:整页分析只喂聚合统计(模型看不到日志原文),结论价值低于 /analysis 图表自身;浮窗助手携带真实查询样本,价值成立。 - 删 /aiops 页面与路由(菜单去项);llmProviders 迁 lib 共用 - 模型配置重做为设置页「AI 模型接入」区:状态严谨映射——供应商/模型按已存 baseUrl/model 正确回显(自定义供应商显示 BaseURL 与自定义模型输入,不再重置), API Key 掩码占位、留空或掩码保存均沿用旧值(不回传掩码) - 后端删 /ai/analyze 与信号采集链路;/ai/chat 保留(上下文由前端日志样本注入)
This commit is contained in:
1 parent
c216bdfdd4
commit
fbbd3a3c27
14 files changed
+203
-919
No files matched your search
@@ -155,7 +155,7 @@ type ChatMessage struct {
|
||||
|
||||
// RunAIChat 全站 AI 助手浮窗:多轮对话 + 当前页面上下文注入(轻量信号摘要)。
|
||||
// 与整页分析共享配置/配额/脱敏/Pro 闸门;context 里的 sourceId 可选,带了就注入日志摘要。
|
||||
func RunAIChat(ctx context.Context, cfg models.AIConfig, src *models.LogSource, userID uint, admin bool, history []ChatMessage, page string, rangeMinutes int, pageContext string) (string, error) {
|
||||
func RunAIChat(ctx context.Context, cfg models.AIConfig, userID uint, history []ChatMessage, page string, pageContext string) (string, error) {
|
||||
if !cfg.Enabled {
|
||||
return "", fmt.Errorf("AI 未启用:请先在「智能运维 → 模型配置」中开启并保存")
|
||||
}
|
||||
@@ -170,26 +170,6 @@ func RunAIChat(ctx context.Context, cfg models.AIConfig, src *models.LogSource,
|
||||
- 被问"你是什么模型/版本"时,只答一句:"我是 LokiStack 内置运维助手,底层模型由管理员在「智能运维 → 模型配置」中指定。"然后引导回日志排查。
|
||||
- 只讨论日志、Loki、采集、告警与平台使用;无关话题(写代码、闲聊、其它产品)用一句礼貌拒绝并引导回排查。
|
||||
- 引用数据时只使用下方"日志概况"中的数字,不得编造。`
|
||||
if src != nil && rangeMinutes > 0 {
|
||||
end := time.Now()
|
||||
from := end.Add(-time.Duration(rangeMinutes) * time.Minute)
|
||||
if bundle, err := CollectAISignals(ctx, src, userID, admin, from, end, ""); err == nil {
|
||||
system += "\n\n当前用户正在查看 " + page + " 页,近 " + fmt.Sprintf("%d", rangeMinutes) + " 分钟的日志概况:总量 " +
|
||||
fmt.Sprintf("%d", bundle.TotalEntries) + " 条(估算)"
|
||||
if len(bundle.Apps) > 0 {
|
||||
system += ",Top 应用:"
|
||||
for i, a := range bundle.Apps {
|
||||
if i >= 3 {
|
||||
break
|
||||
}
|
||||
system += fmt.Sprintf(" %s(%d)", a.App, a.Entries)
|
||||
}
|
||||
}
|
||||
if len(bundle.Alerts) > 0 {
|
||||
system += ";存在告警命中"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 页面上下文(如 /logs 刚执行的查询与样本日志):截断并统一脱敏后并入 system
|
||||
if trimmed := strings.TrimSpace(pageContext); trimmed != "" {
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
)
|
||||
|
||||
// 脱敏的两条底线:
|
||||
// 1) 凭据必须挡住(否则把 key 发给外部模型);
|
||||
// 2) 排查必需的信息必须留着(IP/端口/命名空间/错误码),
|
||||
// 否则模型给不出有用结论 —— 这比"脱得太干净"更常见。
|
||||
// 1. 凭据必须挡住(否则把 key 发给外部模型);
|
||||
// 2. 排查必需的信息必须留着(IP/端口/命名空间/错误码),
|
||||
// 否则模型给不出有用结论 —— 这比"脱得太干净"更常见。
|
||||
func TestRedactText(t *testing.T) {
|
||||
in := `2026-10-30 12:00:01 ERROR redis client: dial tcp 172.19.16.17:6379: connect: connection refused
|
||||
password=Sup3rS3cret! user-admin
|
||||
|
||||
@@ -15,10 +15,10 @@ func TestQueryParallelism(t *testing.T) {
|
||||
{"4", 4},
|
||||
{"8", 8},
|
||||
{"2", 2},
|
||||
{"1", 2}, // 低于 2 核按 2 兜底
|
||||
{"16", 12}, // 上限 12
|
||||
{"", 4}, // 空值走默认
|
||||
{"abc", 4}, // 非法值走默认
|
||||
{"1", 2}, // 低于 2 核按 2 兜底
|
||||
{"16", 12}, // 上限 12
|
||||
{"", 4}, // 空值走默认
|
||||
{"abc", 4}, // 非法值走默认
|
||||
{"4000m", 4}, // 毫核写法
|
||||
{"500m", 2}, // 0.5 核 → 向上取整 1 → 不低于 2
|
||||
{"6000m", 6},
|
||||
|
||||
Reference in new issue
Block a user