Skip to main content
xbot
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage
Edit page

xbot 全面代码审核报告

项目: xbot — 多渠道 AI Agent 框架
审核范围: 全部 Go 源文件(197 个文件,60,465 行代码)
基准 Commit: 879bd5a(master 分支)
审核日期: 2026-03-21
审核机构: 门下省(太子分批派发,6 批并行审核)


目录


审核概览

项目结构

模块文件数代码行数职责
agent/5517,232核心 Agent 引擎
tools/7521,469工具实现(shell、编辑、搜索、MCP 等)
channel/117,585消息通道(飞书、QQ、OneBot)
storage/215,002数据持久化(SQLite + 向量数据库)
llm/113,057LLM 接口层(OpenAI、Anthropic)
session/41,285会话管理
memory/41,017记忆系统
oauth/51,131OAuth 认证
其他(config/cron/logger/bus/pprof/version)11~1,000基础设施

问题统计

严重等级数量占比
🔴 高2919.7%
🟡 中6443.5%
🟢 低5235.4%
合计145100%

问题类型分布

类型合计
安全问题1218838
逻辑 Bug / 竞态816630
代码质量 / 架构3142643
资源泄漏48416
性能问题28818
测试缺失34 文件

一、高严重等级问题 (🔴 29 个)

🔴 安全问题

#文件行号问题建议
S-01channel/feishu.go~480onCardAction 缺少权限检查 — 不在 AllowFrom 白名单的用户可通过卡片回调绕过权限,向消息总线发送消息onCardAction 入口增加 isAllowed(senderID) 检查
S-02tools/fetch.go234-239SSRF 防护绕过isPrivateIP 仅用 net.ParseIP 检查域名,DNS 解析到内网 IP 时不拦截增加 DNS 解析验证:net.LookupIP(host) 后检查每个 IP
S-03tools/fetch.go252-253IPv6 内网地址未拦截::1fc00::/7fe80::/10 等全部放行增加 IPv6 loopback/private/link-local 检查
S-04storage/sqlite/user_llm_config.go27,62-66API Key 明文存储 — 用户 LLM API Key 以纯文本存入 SQLite使用 AES-GCM 加密存储,密钥从环境变量获取
S-05oauth/storage.go42-53OAuth Token 明文存储 — access_token 和 refresh_token 以明文存入 SQLite至少加密 refresh_token;使用 sqlcipher 或应用层加密
S-06oauth/server.go61OAuth Server 绑定 0.0.0.0 — 无认证保护,/oauth/health 端点泄露 provider 列表默认绑定 localhost,添加 OAUTH_HOST 配置项
S-07tools/feishu_mcp/download.go83-129下载接口未鉴权 — file_key/message_id 由用户输入控制,可下载非授权消息附件验证 message_id 属于当前会话可访问范围
S-08tools/feishu_mcp/download.go148-165消息元数据查询无鉴权 — 使用 tenant_access_token 查询任意消息信息限制 message_id 来源为系统注入,或使用 user_access_token
S-09channel/onebot.gorunOnceToken 通过 URL query param 传递 — 出现在 WebSocket URL 中,会被日志/代理记录改用 header 传递 token;确保日志不打印完整 URL
S-10tools/shell.go119-123命令日志记录可能泄露敏感信息 — 完整命令(含可能的 API key/密码)以明文写入日志对日志中的命令内容进行脱敏处理
S-11agent/bang_command.go99SandboxMode=“none” 时直接在宿主机执行命令! 命令在无沙箱场景等同于远程命令执行非 Docker 模式下对 ! 命令添加白名单或禁用
S-12tools/glob.go112-117glob 模式可能注入 find 命令 — 单引号可被用户构造的 ' 截断,造成命令注入对 findArgs 中的每个参数值做 shellEscape

🔴 逻辑 Bug / 竞态

#文件行号问题建议
B-01agent/topic.go62panic 吞没导致零值 slice 穿透recover() 无日志无返回标记,nil slice 导致下游 nil pointer恢复时记录日志,通过 named return 标记降级状态
B-02agent/agent.go474-476启动阶段硬编码 2s Sleep 竞态 — 无 WaitGroup 保护,Close 时 MCP 索引可能 crash使用 channel/sync.Cond 等待 MCP 真正加载完成
B-03channel/feishu.go~650-670isDuplicate 锁粒度问题running 状态和 processedIDs 共用一把锁分离为独立 processedMu,running 改用 atomic.Bool
B-04channel/feishu.go~350-360nil 指针解引用风险msg.MessageId 未做 nil 检查在 onMessage 入口加 nil guard
B-05llm/retry.goisRetryableErrorAnthropic 429/5xx 错误不会被重试 — 错误格式不匹配字符串匹配逻辑增加 strings.Contains(msg, "status=429") 匹配
B-06storage/sqlite/tenant.go22-57GetOrCreateTenantId TOCTOU 竞态 — SELECT + INSERT 非原子操作使用 INSERT OR IGNORE + SELECT 模式
B-07oauth/server.go21,154OAuth SendFunc 竞态条件 — Start 后赋值 SendFunc,回调可能在赋值前到达在 Start 之前设置 SendFunc,或用 atomic.Value 保护
B-08channel/qq.gonextMsgSeqmsgSeqMap 激进清空 — 达到 10000 条时全量清空,导致其他对话 seq 丢失改用 LRU 或基于时间的过期策略

🔴 资源泄漏 / 崩溃

#文件行号问题建议
R-01agent/compress.go569运行时 panic 导致进程崩溃 — assert 失败时 panic 无法被优雅处理替换为 log.Error + return error
R-02agent/middleware.go169运行时 panic 导致进程崩溃 — 同上同上
R-03oauth/manager.go228OAuth Flow 内存泄漏CleanupExpiredFlows 已实现但从未被调用在启动时添加定时清理 goroutine
R-04agent/llm_factory.go用户 LLM 客户端缓存无上限customClients map 从不清理,含 HTTP 连接池添加 LRU/TTL 淘汰策略

🔴 代码质量严重问题

#文件行号问题建议
Q-01tools/feishu_mcp/search.go全文文件名与内容严重不匹配 — search.go 实际是 wiki 工具,wiki.go 实际是 bitable 工具重命名:search.go → wiki.go,wiki.go → bitable.go
Q-02tools/mcp_common.go200-221MCP HTTP 连接无 TLS 证书验证配置 — 未提供自定义 CA 能力支持自定义 http.Client 传入

二、中严重等级问题 (🟡 64 个)

2.1 并发安全 (12 个)

#文件问题建议
C-01agent/interactive.gointeractiveMusync.Map 双重锁模式,spawn 不原子统一使用 sync.Map.LoadOrStore
C-02agent/agent.goconsolidating map 从不清理已完成 entry在 consolidate 完成后删除 key
C-03channel/dispatcher.goRegisterRun 无并发保护添加 sync.RWMutex
C-04channel/feishu.goprocessedOrder slice 切片导致内存泄漏使用 ring buffer 或 copy 到新 slice
C-05channel/feishu.gobotName 使用 f.mu 而非 atomic改用 atomic.Value 或独立 RWMutex
C-06tools/session_mcp.goMCP 连接数无上限控制添加全局/单用户最大连接数限制
C-07tools/manage_tools.goMCP 配置文件写入无文件锁保护使用 flock 或原子写入(写临时文件 + rename)
C-08tools/chat_history.go内存中存储无上限每个 channel 设置 maxMessages 上限
C-09tools/interface.gosessionActivated/sessionRound 无主动清理确认所有会话退出路径都调用 DeactivateSession
C-10session/multitenant.gocleanup 持写锁执行 I/O 操作先收集列表,释放锁后再执行 close
C-11logger/logger.goglobalRotateFile 无并发保护添加 sync.Once 或 sync.Mutex
C-12llm/openai.gomodels 字段无并发保护(当前安全但脆弱)预留 sync.RWMutex

2.2 错误处理 (10 个)

#文件问题建议
E-01agent/engine_wire.gobuildToolContextExtras 忽略 GetOrCreateSession 错误至少记录 warning 日志
E-02agent/agent.goprocessMessage 多个错误路径仅 log.Warn 不通知用户对关键路径错误向用户发送提示
E-03agent/context.go模板解析用 log.Fatal 热加载时直接退出保留最后已知有效模板
E-04agent/context_manager_phase2.goPhase 2 压缩 LLM 失败无 fallback退回 Phase 1 简单压缩
E-05tools/fetch.gotokenizer 初始化失败静默忽略记录 warning 日志
E-06tools/grep.gosandbox grep 的 -C 参数未校验负值在入口处 clamp 为 >= 0
E-07tools/memory_tools.gocore_memory_replace 未找到 old_text 时仍返回成功返回"未变更"状态区分
E-08tools/subagent_loader.goYAML frontmatter 字段缺少严格校验name 用白名单,tools 验证是否在已知集合中
E-09config/config.go.env 加载错误被静默忽略至少 log debug 级别提示
E-10config/config.go环境变量格式错误静默降级为默认值首次调用时打印 warning

2.3 安全 (8 个)

#文件问题建议
S-13tools/download.go下载文件无大小限制添加 io.LimitReader(如 100MB)
S-14tools/download.gomessageID/fileKey 未做字符白名单校验正则校验格式
S-15agent/llm_config_handler.go/set-llm 在群聊中暴露 API key群聊场景发送隐私警告
S-16tools/manage_tools.gosanitizeMCPName 需审查是否覆盖所有路径分隔符确认覆盖 /\..%2F
S-17tools/feishu_mcp/file.go上传文件未校验 Content-Type增加允许的 MIME type 白名单
S-18tools/subagent.goSubAgent task 参数无大小限制增加 max length 限制(如 50KB)
S-19oauth/server.gohandleCallback 未校验 state/code 参数长度添加参数长度校验
S-20tools/feishu_mcp/tools.gowiki search 使用 http.DefaultClient 无超时创建自定义 http.Client

2.4 性能 (8 个)

#文件问题建议
P-01agent/offload.goCleanStale 在初始化时同步执行阻塞启动移到后台 goroutine 异步执行
P-02storage/sqlite/session.goGetHistory COUNT + OFFSET 扫描两次改用倒序 LIMIT + Go 反转切片
P-03cron/scheduler.go每秒全量 DB 扫描所有 job维护 nextFireTime 优先队列
P-04cron/scheduler.goStartDelayed 阻塞调用者直到 sleep 完成将 sleep 移到 goroutine 内部
P-05tools/sandbox_runner.godockerExecTimeout 300s 过长允许自定义但有硬性上限
P-06channel/qq.gosendAutoDetect 串行尝试所有类型触发无效 API 调用优先使用缓存类型,添加最大尝试次数
P-07storage/vectordb/archival.gofingerprints.json 每次变更全量读写内存缓存 + 异步持久化
P-08storage/sqlite/db.go缺少 WAL 模式和 busy_timeout设置 PRAGMA journal_mode=WAL + busy_timeout=5000

2.5 代码质量 / 架构 (26 个)

#文件问题建议
A-01tools/feishu_mcp/search.go/wiki.go文件名与内容颠倒重命名
A-02storage/sqlite/session.go + storage/vectordb/recall.goparseTimestamp 重复定义提取到 shared internal 包
A-03storage/sqlite/cron.go + session.go + db.go时间格式不一致(RFC3339 vs 本地格式 vs UTC)统一使用一种格式
A-04agent/registry.go:310copyDir 不保留文件权限和符号链接使用 os.Lstat + Info.Mode()
A-05agent/engine_wire.gobuildMainRunConfigbuildCronRunConfig 60% 重复提取公共 buildBaseRunConfig
A-06llm/anthropic.gotoAnthropicMessages 返回的 system 被丢弃,代码混乱重构 system 消息处理
A-07llm/anthropic.go已知模型列表过时,缺少 Claude 4定期更新或从 API 动态加载
A-08llm/tokenizer.goClaude 模型使用 GPT-4 tokenizer(~10-20% 偏差)添加注释说明近似值
A-09storage/vectordb/archival.gollmContentCompressor 包级变量永远为 nil(死代码)实现初始化或删除相关代码
A-10storage/sqlite/registry.goPublish 方法 SELECT + INSERT 非原子使用 UPSERT 模式
A-11storage/sqlite/core_memory.goGetBlock/SetBlock/GetAllBlocks 路由逻辑大量重复提取 resolveBlockKey 私有方法
A-12storage/vectordb/archival.goisOllamaURL 仅通过端口号判断解析 URL 后检查 host:port
A-13storage/vectordb/archival.goDefaultContentCompressor 按 byte 截断可能破坏 UTF-8使用 []rune 转换后截断
A-14tools/memory_tools.gorethink 工具 new_content 无长度限制增加 max length(如 100KB)
A-15tools/skill_sync.go文件同步无完整性校验(仅比较 mtime)增加 checksum 比较
A-16tools/session_mcp.goreconnect 无退避机制添加指数退避 + 最大重试次数
A-17tools/cron.gocron 表达式未在提交前预校验在 addJob 入口预校验
A-18channel/qq.go + storage/sqlite/recall.goparseTimestamp 重复定义且逻辑不完全一致提取为公共工具函数
A-19channel/qq.gostripQQMention O(n²) 算法使用 strings.Builder 或正则替换
A-20channel/feishu.goformatMapString 未转义 ,=使用 JSON 序列化或转义
A-21llm/openai.gobuildThinkingOptions 对未知 thinkingMode 静默忽略记录 warn 日志
A-22main.gosendStartupNotify 使用固定 3s 延迟等待连接就绪使用 channel 就绪信号
A-23main.go:98-103OAuth 数据库连接未关闭在关闭流程中添加 sharedDB.Close()
A-24llm/types.goToolParam.Items 不支持嵌套对象改为支持完整 JSON Schema 子结构
A-25tools/cron.goJSON 解析未使用 parseToolArgs 泛型辅助函数统一使用项目风格
A-26channel/feishu.goChannelSystemParts 中的 prompt 提到过时工具名更新与实际工具名称一致

三、低严重等级问题 (🟢 52 个)

3.1 代码风格 / 维护性 (20 个)

#文件问题
L-01agent/agent.goNew() 函数过长(~150 行),应拆分为多个 init* 方法
L-02agent/registry.go:305markInstalled 是空函数(占位符)
L-03agent/compress.goCompress 同时承担压缩和消息发送,应分离
L-04agent/progress.goProgressEvent 仅使用第一行文本,结构化信息浪费
L-05agent/reply.goExtractFinalReply 逻辑过于简化(>500字取最后一段)
L-06agent/command_builtin.go/version 不含 git commit hash
L-07agent/trigger.gotriggerProviders sync.Map 无清理机制
L-08agent/quality.goKeyInfoFingerprint 未被 Phase 1 使用
L-09tools/card_builder.go会话过期清理仅在 CreateSession 时触发
L-10tools/card_tools.gocardToolNames 硬编码列表易遗漏
L-11tools/hook.goHookChain 未限制 hook 数量
L-12tools/logs.go日志目录路径硬编码 .xbot/logs
L-13tools/read.go大文件无分页读取
L-14tools/skill.goskill 搜索返回所有匹配文件,无数量限制
L-15tools/oauth.goOAuth scopes 参数未验证合法性
L-16tools/path_guard.goResolveWritePath 与 ValidateReadPath 行为不对称
L-17bus/bus.goMessageBus channel 容量硬编码为 64
L-18oauth/manager.go:254ListProviders 返回无序列表
L-19oauth/manager.go:244generateState 仅 16 字节(建议 32 字节)
L-20version/version.goInfo() 无测试

3.2 防御性编程 / 边界情况 (12 个)

#文件问题
L-21channel/feishu.golimitMarkdownTables 表格以 separator 行开头时边界错误
L-22channel/qq.godownloadOneBotImage 50MB 限制过大(建议 10-20MB)
L-23channel/onebot.gostripQQMention 是 O(n²) 但实际消息短,影响极小
L-24llm/retry.goisInputTooLongError 匹配 “400” 过于宽松
L-25llm/mock.goGenerate 和 GenerateStream 行为不一致
L-26llm/openai.gobuildThinkingOptions 未知模式静默忽略
L-27tools/cd.go沙箱模式下 CurrentDir 使用宿主机路径做 Prefix 检查,语义不清晰
L-28tools/glob.goglobToFindArgs 不处理含 \ 的 pattern(已有 filepath.ToSlash 保护)
L-29tools/shell_env.goparseEnvFileLines 行为正确但建议添加注释
L-30tools/workspace_scope.goSanitizeWorkspaceKey 未限制用户 ID 长度
L-31tools/offload_recall.gooffloadMaxLimit = 16000 无注释说明选择依据
L-32tools/feishu_mcp/block_type_map.goHeading5~Heading9 常量可能是死代码

3.3 测试 / 文档 (10 个)

#文件问题
L-33tools/chat_history.go无测试覆盖
L-34tools/feishu_mcp/docx_test.go使用 //go:build ignore 标签,测试永远不执行
L-35tools/feishu_mcp/docx_write.gocleanBlockForDescendant 仅处理 Mermaid 特殊 case,缺注释
L-36storage/vectordb/archival.goSearchByDocumentContains 参数位置需确认 API 签名
L-37cron/scheduler.goStart()StartDelayed() 共用 once,缺少文档说明
L-38pprof/pprof.go:103/debug/gc 无认证,可触发 STW
L-39storage/sqlite/db.goSchema 迁移无测试
L-40storage/vectordb/archival.gonewOllamaEmbedFunccheckedNormalized 闭包变量内存屏障不够清晰
L-41storage/sqlite/migrate.go:200-202migrateSchema 版本跳跃缺少严格一致性检查
L-42logger/logger.go:171cleanupOldLogs goroutine 无退出机制

3.4 其他 (10 个)

#文件问题
L-43agent/rand.Intn使用 math/rand 而非 crypto/rand(Go 1.20+ 已自动 seed,无安全影响)
L-44agent/engine.gotoolCallEntry 缺少来源追踪(iteration/tool call index)
L-45tools/cron.goat 参数未验证 ISO 格式
L-46tools/edit.goregex 模式仅做 regexp.Compile,RE2 保证线性时间但未限制匹配步数
L-47tools/grep.gosandbox grep 输出解析用 - 分隔符不精确
L-48tools/feishu_mcp/download.gomcp_info 接口使用 tenant_access_token 无用户级鉴权(同 S-08)
L-49channel/feishu.goextractPostTextmessageId 参数传递链不太直观
L-50tools/search_tools.go向量搜索结果已限制 limit=5,当前实现合理
L-51tools/sandbox_runner.goDocker 镜像名使用 userID 构造,需校验格式
L-52memory/memory.go纯接口定义,设计清晰,无问题

四、各模块审核详情

4.1 agent/ 模块(55 文件,17,232 行)

审核结论: 核心 Agent 引擎,代码量最大。并发安全是主要关注点。

高优问题: panic 吞没(H-01)、启动竞态(H-02)、命令注入(H-03)、运行时 panic(H-04)、goroutine 泄露(H-05)、缓存无上限(H-06)

测试覆盖:

  • ✅ engine_test.go (517行)、offload_test.go (611行)、topic_test.go (478行) 覆盖较好
  • ❌ agent.go(1820行核心文件)完全无单元测试
  • ❌ llm_factory.go、registry.go、context.go 缺少测试

4.2 tools/ 模块(75 文件,21,469 行)

审核结论: 工具层代码量最大,安全风险最集中。

高优问题: SSRF 绕过、命令注入、IPv6 未拦截、文件名颠倒

安全重点:

  • fetch.go: SSRF 防护存在 DNS 重绑定和 IPv6 绕过
  • glob.go/grep.go: shell 命令构造需严格转义
  • shell.go: 命令日志脱敏
  • feishu_mcp/: 下载/查询接口缺少鉴权

测试覆盖:

  • ✅ path_guard、cd、glob、grep、fetch、hook、shell、sandbox 有良好测试
  • ❌ cron、download、chat_history、card_tools、session_mcp、skill、web_search、feishu_mcp 整体缺测试

4.3 channel/ 模块(11 文件,7,585 行)

审核结论: 消息通道层,并发安全和权限检查是关键。

高优问题: onCardAction 权限绕过(C-H3)、nil 指针风险(C-H2)、isDuplicate 锁问题(C-H1)、sendAutoDetect 无效调用(C-H4)

测试覆盖:

  • ✅ feishu_settings、capability、retry 有良好测试
  • ❌ feishu.go(最复杂文件 ~800 行)零测试 — 这是最大风险
  • ❌ dispatcher.go 无测试

4.4 storage/ 模块(21 文件,5,002 行)

审核结论: 数据持久化层,SQL 安全和并发访问是关注点。

高优问题: API Key 明文(H1)、FTS 触发器缺失(H2)、WAL/busy_timeout 缺失(H3)、TOCTOU 竞态(H4)

测试覆盖:

  • ✅ session、memory、core_memory、registry、tenant、user_settings、recall 有良好测试
  • ❌ db.go(schema + 13 版本迁移)无测试
  • ❌ user_llm_config、user_profile、cron、archival、migrate 缺测试

4.5 llm/ 模块(11 文件,3,057 行)

审核结论: LLM 接口层,retry 逻辑设计精良是亮点。

高优问题: Anthropic 429/5xx 不重试(L-H1)

亮点: retry.go — perAttemptCtx 正确处理超时重试,isRetryableError 正确区分错误类型

测试覆盖:

  • ✅ retry.go 测试优秀、openai_thinking/anthropic_thinking 有测试
  • ❌ types.go、tokenizer.go、mock.go 缺测试
  • ⚠️ openai/anthropic 核心方法依赖 SDK,仅有部分测试

4.6 其他模块(22 文件,~5,400 行)

审核结论: 基础设施层,OAuth 模块安全问题最突出。

高优问题: OAuth 0.0.0.0 绑定(H-01)、Flow 内存泄漏(H-02)、Token 明文(H-04)、SendFunc 竞态(H-03)

测试覆盖:

  • ✅ logger_test.go、session_test.go、bus/address_test.go 覆盖良好
  • ❌ oauth/ 整体无测试(Manager、Server、Storage、Provider)
  • ❌ cron/scheduler.go 无测试
  • ❌ config.go 无测试

五、测试覆盖评估

5.1 按模块统计

模块源文件有测试无测试覆盖率
agent/33221167%
tools/~47~28~1960%
channel/73443%
storage/157847%
llm/74357%
其他~114736%
合计~120~68~5257%

5.2 关键缺失测试的文件(按优先级排序)

优先级文件原因
P0channel/feishu.go最复杂消息处理文件(~800行),权限/去重/卡片回调零测试
P0storage/sqlite/db.goSchema + 13 版本迁移逻辑无测试
P0oauth/manager.goOAuth 核心流程(StartFlow/CompleteFlow/Token 刷新)零测试
P1agent/agent.go核心文件 1820 行无单元测试
P1tools/feishu_mcp/*.go飞书 MCP 工具整体零测试(14 个文件)
P1cron/scheduler.go定时任务调度逻辑复杂,零测试
P2tools/download.go文件下载 + 外部 API 调用无测试
P2tools/cron.goCron 工具 CRUD 无测试
P2oauth/server.go + storage.goOAuth 端点和存储零测试
P2tools/session_mcp.goMCP 连接管理零测试
P3tools/web_search.goWeb 搜索无测试
P3tools/skill.go + skill_sync.go技能加载/同步无测试
P3llm/tokenizer.goToken 计数无测试

六、跨模块系统性问题

6.1 🔴 需立即修复

#系统性问题涉及模块影响
1敏感数据明文存储 — API Key、OAuth Token 均以明文存入 SQLitestorage/sqlite, oauth数据泄露风险
2权限绕过 — onCardAction 未做 AllowFrom 检查channel/feishu任何用户可发送消息
3SSRF 防护不完整 — DNS 重绑定 + IPv6 内网未拦截tools/fetch内网服务暴露

6.2 🟡 应短期修复

#系统性问题涉及模块影响
4内存泄漏模式 — 多处 map/cache 从不清理(LLM 缓存、consolidating、OAuth Flow、chat_history、triggerProviders)agent, tools, oauth长期运行 OOM
5SQLite 并发安全 — 缺少 WAL 模式、busy_timeout、TOCTOU 竞态storage/sqlite高并发下数据损坏
6goroutine 泄漏 — cleanupOldLogs 无退出机制、启动阶段 Sleep 竞态logger, agent资源泄漏
7Anthropic 错误不重试 — 429/5xx 错误因格式不匹配而跳过重试llm/retry用户体验差
8panic 用于生产断言 — compress.go 和 middleware.go 的 assert panicagent单条消息可导致服务不可用
9FTS5 索引不一致 — 只有 INSERT 触发器,缺 DELETE/UPDATEstorage/sqlite搜索结果含已删除数据
10OAuth 安全策略不一致 — server 绑定 0.0.0.0 而 pprof 绑定 localhostoauth, pprof攻击面不一致

6.3 🟢 长期改进

#系统性问题涉及模块影响
11时间格式不统一 — RFC3339 vs 本地格式 vs UTC 混用storage/sqlite时间解析错误
12代码重复 — parseTimestamp、buildRunConfig 等多处重复多模块维护风险
13feishu_mcp 文件命名颠倒 — search.go 是 wiki,wiki.go 是 bitabletools/feishu_mcp可维护性
14feishu.go 测试覆盖为零 — 最复杂的消息处理文件无测试channel质量风险
15大量 sync.Map 无清理机制 — 用户体验数据长期积累agent, tools内存增长

七、优先修复建议

Phase 1: 立即修复(安全关键,1-2 天)

序号问题编号修复内容预计工作量
1S-01onCardAction 增加 isAllowed 权限检查0.5h
2S-02 + S-03fetch.go SSRF 防护:增加 DNS 解析 + IPv6 检查1h
3S-04 + S-05API Key / OAuth Token 加密存储4h
4S-06OAuth Server 默认绑定 localhost0.5h
5S-12glob.go shellEscape 转义1h

Phase 2: 短期修复(稳定性关键,1 周)

序号问题编号修复内容预计工作量
6B-01 + R-01 + R-02将 panic 替换为 error 返回2h
7B-05retry.go 增加 Anthropic 错误格式匹配0.5h
8H-03SQLite 设置 WAL + busy_timeout0.5h
9B-06GetOrCreateTenantId 改用 INSERT OR IGNORE1h
10R-03OAuth CleanupExpiredFlows 定时调用0.5h
11H-02FTS5 补充 DELETE/UPDATE 触发器1h
12B-03 + B-04feishu.go nil guard + 锁分离2h

Phase 3: 中期改进(质量提升,2-4 周)

序号修复内容预计工作量
1清理内存泄漏:LLM 缓存 LRU、consolidating map、chat_history 限制、triggerProviders TTL4h
2补充关键测试:feishu.go、db.go、oauth/manager.go8h
3Q-01 文件重命名:search.go → wiki.go、wiki.go → bitable.go2h
4main.go 修复:OAuth DB 关闭、启动通知就绪信号2h
5cron 性能:优先队列替代每秒全量扫描4h

Phase 4: 长期优化(持续改进)

序号修复内容
1统一时间格式(全库使用一种格式)
2提取公共工具函数(parseTimestamp、buildBaseRunConfig)
3agent.go 拆分 New() 函数
4补充剩余模块测试覆盖至 80%+
5S-04/S-05 考虑迁移到 sqlcipher 加密整个数据库

审核总结

xbot 是一个功能丰富、架构合理的多渠道 AI Agent 框架。代码整体质量中上,有良好的接口抽象和模块化设计。retry.go 的重试逻辑、qq.go 的并发控制、path_guard.go 的安全守卫都是代码质量的亮点。

主要风险集中在三个领域

  1. 安全 — 敏感数据明文存储、SSRF 防护不完整、权限绕过(需立即修复)
  2. 资源管理 — 多处内存泄漏、goroutine 泄漏(影响长期运行稳定性)
  3. 测试覆盖 — 关键模块(feishu.go、db.go、oauth)零测试(质量风险)

建议按 Phase 1 → Phase 4 的优先级逐步修复,其中 Phase 1 的安全问题建议在下一版本发布前完成


本报告由门下省审核,太子汇总复奏。审核基准 commit: 879bd5a