我们用企微机器人 + Claude 搭了个内部 DevOps 助手,替代了 60% 的日常杂活

TL;DR:用企微|钉钉: WebSocket + Claude Agent SDK 搭了个内部智能助手,靠"滚动摘要窗口"解决上下文断裂、进程池解决冷启动、热插拔工具系统实现低成本扩展。Non-goals 比功能列表更值钱。上线后研发被打断次数下降 75%,工单响应从 15 分钟缩到 3 分钟。

这不是一篇"如何用 AI 改变世界"的宏大叙事,是一个部门级内部工具的真实落地记录------从被杂活淹没到机器人接手 60% 对外咨询,踩过的坑、做的取舍、最后跑通的那套架构。

为什么我们要造这个东西

先说痛点。我们部门对外的日常事务大致是这些:

  • 技服每天回复工单------客户报 502,要查日志、查工单、查版本、给排查结论
  • 其他部门来问知识库------"支付模块回调怎么设计的""怎么申请服务器权限"
  • 项目经理想知道进度------这周 sprint 推到哪了,最近提交了什么
  • 构建失败要通知------Jenkins 挂了,谁在盯

这些活单个不难,但架不住量大、重复、碎片化。一个研发一天被打断 5 次回答"怎么查日志",正经活就别干了。

所以目标很明确:造一个内部智能助手,把这些重复性对外咨询接过来 60%-70%,让研发测试产品能专心做自己的事。

产品思路:少做比多做重要

内部工具最大的陷阱不是功能不够,是什么都想做。我们花了大量时间定义"不做什么"。

Non-goals 清单------这条最值钱

不做 理由
不对外部客户 内部工具,信任容忍度高,外部客户要求完全不一样
不做代码自动修复 只查日志给结论,不改代码------边界要清晰
不做知识库自动生成 FAQ 人工维护,不让 AI 自己"创造"知识
不做多语言 中文够了
不做自动操作生产环境 Jenkins 触发、Git 操作必须人工确认

成功指标------怎么知道真的省了 60% 的活

"替代 60%-70% 杂活"是愿景,不可衡量就是耍流氓。我们定了两个指标,简单粗暴:

指标 定义 目标
机器人接手率 机器人独立解决的问题数 / 总咨询数 ≥50%
回答可用率 用户未在同一会话内追问同一问题的比例 ≥70%

测的方式也很轻------服务日志里给每条会话打个标:resolved_by_bot / escalated_to_human / user_reasked。不需要数据平台,grep 一下就出来了。

安全边界------机器人不能碰的红线

这条是产品审核时被拍桌子补上的。工具都给齐了(Jenkins、JIRA、Git),不划清边界等于没安全。

text 复制代码
禁止机器人自动执行:
- 生产环境变更(重启服务、修改配置、切换流量)
- 数据库写操作(UPDATE / DELETE / INSERT)
- 客户数据修改(退款、订单变更、账户操作)
- 敏感信息返回(密码、密钥、Token、手机号明文)

还有一条兜底规则:连续 2 轮回答不确定时,自动附加"⚠️ 以上分析供参考,建议人工核实"。内部工具最大的信任危机不是功能少,是瞎说还不认。

整体架构

先看全景,再拆开讲。
#mermaid-svg-3pDHCKxgAeewEf36{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3pDHCKxgAeewEf36 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3pDHCKxgAeewEf36 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3pDHCKxgAeewEf36 .error-icon{fill:#552222;}#mermaid-svg-3pDHCKxgAeewEf36 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3pDHCKxgAeewEf36 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3pDHCKxgAeewEf36 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3pDHCKxgAeewEf36 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3pDHCKxgAeewEf36 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3pDHCKxgAeewEf36 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3pDHCKxgAeewEf36 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3pDHCKxgAeewEf36 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3pDHCKxgAeewEf36 .marker.cross{stroke:#333333;}#mermaid-svg-3pDHCKxgAeewEf36 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3pDHCKxgAeewEf36 p{margin:0;}#mermaid-svg-3pDHCKxgAeewEf36 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3pDHCKxgAeewEf36 .cluster-label text{fill:#333;}#mermaid-svg-3pDHCKxgAeewEf36 .cluster-label span{color:#333;}#mermaid-svg-3pDHCKxgAeewEf36 .cluster-label span p{background-color:transparent;}#mermaid-svg-3pDHCKxgAeewEf36 .label text,#mermaid-svg-3pDHCKxgAeewEf36 span{fill:#333;color:#333;}#mermaid-svg-3pDHCKxgAeewEf36 .node rect,#mermaid-svg-3pDHCKxgAeewEf36 .node circle,#mermaid-svg-3pDHCKxgAeewEf36 .node ellipse,#mermaid-svg-3pDHCKxgAeewEf36 .node polygon,#mermaid-svg-3pDHCKxgAeewEf36 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3pDHCKxgAeewEf36 .rough-node .label text,#mermaid-svg-3pDHCKxgAeewEf36 .node .label text,#mermaid-svg-3pDHCKxgAeewEf36 .image-shape .label,#mermaid-svg-3pDHCKxgAeewEf36 .icon-shape .label{text-anchor:middle;}#mermaid-svg-3pDHCKxgAeewEf36 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3pDHCKxgAeewEf36 .rough-node .label,#mermaid-svg-3pDHCKxgAeewEf36 .node .label,#mermaid-svg-3pDHCKxgAeewEf36 .image-shape .label,#mermaid-svg-3pDHCKxgAeewEf36 .icon-shape .label{text-align:center;}#mermaid-svg-3pDHCKxgAeewEf36 .node.clickable{cursor:pointer;}#mermaid-svg-3pDHCKxgAeewEf36 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3pDHCKxgAeewEf36 .arrowheadPath{fill:#333333;}#mermaid-svg-3pDHCKxgAeewEf36 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3pDHCKxgAeewEf36 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3pDHCKxgAeewEf36 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3pDHCKxgAeewEf36 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3pDHCKxgAeewEf36 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3pDHCKxgAeewEf36 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3pDHCKxgAeewEf36 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3pDHCKxgAeewEf36 .cluster text{fill:#333;}#mermaid-svg-3pDHCKxgAeewEf36 .cluster span{color:#333;}#mermaid-svg-3pDHCKxgAeewEf36 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3pDHCKxgAeewEf36 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3pDHCKxgAeewEf36 rect.text{fill:none;stroke-width:0;}#mermaid-svg-3pDHCKxgAeewEf36 .icon-shape,#mermaid-svg-3pDHCKxgAeewEf36 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3pDHCKxgAeewEf36 .icon-shape p,#mermaid-svg-3pDHCKxgAeewEf36 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3pDHCKxgAeewEf36 .icon-shape .label rect,#mermaid-svg-3pDHCKxgAeewEf36 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3pDHCKxgAeewEf36 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3pDHCKxgAeewEf36 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3pDHCKxgAeewEf36 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} WebSocket 长连接
需要压缩
不需要
响应
WebSocket 推送
企微群/私聊 @机器人
本地服务 Python
会话管理器
权限管理器
推送管理器
滚动摘要判断
Haiku 压缩历史
直接处理
Agent SDK + Sonnet 4.6
工具层 热插拔
wiki
jira
oss_logs
git_repos
jenkins
...更多工具
记忆系统
MEMORY.md 索引
facts/ 明细
本地向量库
FAQ 知识库

整个链路是:企微消息 → WebSocket → 本地服务 → Agent SDK(Sonnet 4.6)→ 调工具 → 回企微。所有东西跑在本机内网,不依赖外部 API(embedding 用的也是本地模型)。

核心技术决策

决策一:Agent SDK 而不是 CLI 外挂

最早的版本是把 Claude Code CLI 当黑盒用------stdin 喂 prompt,stdout 读结果。能用,但有个致命问题:上下文是 CLI 的私有状态,你改不了

后来迁到 Agent SDK,整个世界清爽了。上下文变成了你可以程序化读写的对象:

python 复制代码
# 伪代码示意
class RollingContextManager:
    def before_turn(self, agent, session):
        if session.should_compress():
            old_msgs = session.get_messages()[:-5]
            summary = cheap_llm.summarize(old_msgs)
            session.replace_messages([
                SystemMessage(summary),
                *session.get_messages()[-5:]
            ])

不用杀进程,不用 stdin/stdout 拼接,直接替换消息历史。这一步迁移是整个架构最重要的一次升级。

决策二:滚动摘要窗口------解决上下文断裂

这是整个项目最痛的一个问题。

工单场景经常这样:技服 @ 机器人查一个 502,从查 JIRA → 查日志 → 分析 → 追问 → 再查别的日志,一来一回 30 多轮,上下文就爆了(180k tokens 硬上限)。一旦爆了,机器人"失忆",前面排查到哪一步全忘------技服同事当场就弃用了。

试过三个方案:

方案 思路 问题
会话快照 爆了才压缩,存个摘要 用户能感知到"断了"
工单锚点 结构化存工单状态 工具不触发就漏
滚动摘要 主动压缩,永不让它爆 选这个

滚动摘要的核心思路:不等它爆,到了水位就压
#mermaid-svg-2gClxhlHxvLo1Ub8{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2gClxhlHxvLo1Ub8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2gClxhlHxvLo1Ub8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2gClxhlHxvLo1Ub8 .error-icon{fill:#552222;}#mermaid-svg-2gClxhlHxvLo1Ub8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2gClxhlHxvLo1Ub8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2gClxhlHxvLo1Ub8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2gClxhlHxvLo1Ub8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2gClxhlHxvLo1Ub8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2gClxhlHxvLo1Ub8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2gClxhlHxvLo1Ub8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2gClxhlHxvLo1Ub8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2gClxhlHxvLo1Ub8 .marker.cross{stroke:#333333;}#mermaid-svg-2gClxhlHxvLo1Ub8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2gClxhlHxvLo1Ub8 p{margin:0;}#mermaid-svg-2gClxhlHxvLo1Ub8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-2gClxhlHxvLo1Ub8 .cluster-label text{fill:#333;}#mermaid-svg-2gClxhlHxvLo1Ub8 .cluster-label span{color:#333;}#mermaid-svg-2gClxhlHxvLo1Ub8 .cluster-label span p{background-color:transparent;}#mermaid-svg-2gClxhlHxvLo1Ub8 .label text,#mermaid-svg-2gClxhlHxvLo1Ub8 span{fill:#333;color:#333;}#mermaid-svg-2gClxhlHxvLo1Ub8 .node rect,#mermaid-svg-2gClxhlHxvLo1Ub8 .node circle,#mermaid-svg-2gClxhlHxvLo1Ub8 .node ellipse,#mermaid-svg-2gClxhlHxvLo1Ub8 .node polygon,#mermaid-svg-2gClxhlHxvLo1Ub8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2gClxhlHxvLo1Ub8 .rough-node .label text,#mermaid-svg-2gClxhlHxvLo1Ub8 .node .label text,#mermaid-svg-2gClxhlHxvLo1Ub8 .image-shape .label,#mermaid-svg-2gClxhlHxvLo1Ub8 .icon-shape .label{text-anchor:middle;}#mermaid-svg-2gClxhlHxvLo1Ub8 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-2gClxhlHxvLo1Ub8 .rough-node .label,#mermaid-svg-2gClxhlHxvLo1Ub8 .node .label,#mermaid-svg-2gClxhlHxvLo1Ub8 .image-shape .label,#mermaid-svg-2gClxhlHxvLo1Ub8 .icon-shape .label{text-align:center;}#mermaid-svg-2gClxhlHxvLo1Ub8 .node.clickable{cursor:pointer;}#mermaid-svg-2gClxhlHxvLo1Ub8 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-2gClxhlHxvLo1Ub8 .arrowheadPath{fill:#333333;}#mermaid-svg-2gClxhlHxvLo1Ub8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2gClxhlHxvLo1Ub8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2gClxhlHxvLo1Ub8 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2gClxhlHxvLo1Ub8 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-2gClxhlHxvLo1Ub8 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2gClxhlHxvLo1Ub8 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-2gClxhlHxvLo1Ub8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2gClxhlHxvLo1Ub8 .cluster text{fill:#333;}#mermaid-svg-2gClxhlHxvLo1Ub8 .cluster span{color:#333;}#mermaid-svg-2gClxhlHxvLo1Ub8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2gClxhlHxvLo1Ub8 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-2gClxhlHxvLo1Ub8 rect.text{fill:none;stroke-width:0;}#mermaid-svg-2gClxhlHxvLo1Ub8 .icon-shape,#mermaid-svg-2gClxhlHxvLo1Ub8 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2gClxhlHxvLo1Ub8 .icon-shape p,#mermaid-svg-2gClxhlHxvLo1Ub8 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-2gClxhlHxvLo1Ub8 .icon-shape .label rect,#mermaid-svg-2gClxhlHxvLo1Ub8 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2gClxhlHxvLo1Ub8 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-2gClxhlHxvLo1Ub8 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-2gClxhlHxvLo1Ub8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 120k tokens
25 轮
距上次压缩 >= 5 轮
都不满足
新消息到达
触发判断
压缩
直接处理
保留最近 5 轮原文
其余历史 → Haiku 压缩
拼装: 摘要 + 5 轮原文
替换 Agent 上下文
继续对话

三个触发条件,满足任意一个就压:

  1. 水位触发:上下文逼近 120k tokens(留 60k 缓冲)
  2. 轮次触发:对话超过 25 轮
  3. 频率保护:距上次压缩至少隔 5 轮,避免震荡

压缩逻辑极简:保留最近 5 轮原文,其余全部丢给 Haiku 压成 ≤500 字摘要。prompt 就一句话:"把以下对话压缩成不超过 500 字的摘要,保留关键决策、排查步骤、未解决问题。"

用户侧完全无感------他不会知道中间压了一次,对话照样连贯。这是整个项目最值钱的一个设计

决策三:进程池预初始化

冷启动是延迟大头------加载模型、初始化工具、读权限配置,一次就要好几秒。对内部工具来说,每次 @ 机器人等 5 秒才出字,体验就崩了。

解法很直白:预启动一批 Agent 实例放池子里

text 复制代码
进程池:
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Agent-1 │ │ Agent-2 │ │ Agent-3 │ │ Agent-4 │
│ (闲置)   │ │ (使用中) │ │ (闲置)   │ │ (闲置)   │
└─────────┘ └─────────┘ └─────────┘ └─────────┘

会话到达 → 取闲置实例 → 注入上下文 → 执行 → 归还
心跳 30s,挂了的自动补

默认 4 个实例,配置可改。实测 10 个并发会话完全扛得住,首字响应中位数 < 3 秒。

决策四:工具热插拔------skill.md + tool.py

每个工具就是一个目录,里面两个文件:

text 复制代码
tools/
├── wiki/
│   ├── skill.md    # 工具描述,喂给 Agent
│   └── tool.py     # 实际执行逻辑
├── jira/
│   ├── skill.md
│   └── tool.py
└── ...

skill.md 告诉 Agent 这个工具能干什么、怎么调。tool.py 暴露统一接口:

python 复制代码
async def run(params: dict, context: ToolContext) -> ToolResult:
    """每个工具暴露唯一的 run 函数"""
    ...

服务启动时扫一遍 tools/ 目录自动注册。新增工具就是加个目录然后重启,核心代码一行不用改。这个设计让我们加工具的成本极低,一周加了 4 个新工具,都是顺手的事。

决策五:权限按群和用户双重控制

内部工具必须管权限------技服能查客户信息,研发不能;研发能触发 Jenkins,技服不能。

用 YAML 配,简单明了:

yaml 复制代码
# 角色 → 工具
basic:    [wiki, knowledge_base, version_query]   # 全员
support:  [customer_query, oss_logs, jira]        # 技服
devops:   [git_repos, jenkins]                    # 研发

# 用户 → 角色
zhangsan: [basic, support]
lisi:     [basic, devops]

# 群 → 角色
技服群: [support]
研发群: [devops]
全员群: [basic]

校验在工具调用前完成,无权限直接返回提示。用户级和群级双重校验------在研发群里@机器人,即便你是技服,也只能用研发工具。这个设计防止了"在错的地方调错的工具"。

记忆系统:简单够用就行

没上向量数据库存记忆,就是文件系统

text 复制代码
memory/
├── MEMORY.md           # 索引
├── facts/              # 明细
│   ├── 2026-07-08.md
│   └── ...

MEMORY.md 长这样:

markdown 复制代码
# 机器人记忆索引

## 工单
- TKT-0712: XX公司 支付502 → 后端OOM,已重启

## FAQ(被问 ≥3 次自动收录)
- 支付回调失败怎么排查?→ 查nginx → 回调服务 → 支付网关

## 版本
- v3.2.1: 2026-07-05 发布,修复 OOM

规则也简单:

  • 同一问题被问 ≥3 次 → 自动写入 MEMORY.md
  • 每天凌晨梳理一次,合并同类项
  • 15 天没被引用的记忆标记 pending_delete,再等 3 天还不引用就物理删

不上数据库的理由:内部工具,记忆量不大,文件系统 grep 一下比查数据库还快。等真撑不住了再迁不迟。

踩过的坑

坑一:上下文断裂是信任杀手

前面说过,工单多轮追问爆 180k 后机器人"失忆"。这个问题坑了我们好几天------技服同事第一反应是"这玩意不靠谱",直接不用了。

教训:内部工具可以容忍功能少,不能容忍"突然变笨"。滚动摘要窗口上线后,断裂问题消失,信任才回来。

坑二:CLI 外挂做不了上下文管理

最早用 CLI stdin/stdout,想做滚动摘要得杀进程重启,极其难看。迁到 Agent SDK 后,上下文变成可操作的对象,问题自然没了。

教训:选 AI 框架时,先想清楚你要多大控制权。如果你只是问答,CLI 够了;如果你要做上下文管理、工具编排、会话隔离,老老实实用 SDK。

坑三:不加兜底提示,出错没人兜

有一次机器人把日志分析错了,技服拿着错误结论回了客户,差点出事。后来加了"连续 2 轮不确定就提示人工核实"的规则。

教训:AI 给的结论,内部场景也要标"仅供参考"。尤其是会影响对外决策的(工单回复、进度汇报),必须有兜底提示。

跑起来之后

目前运行良好,上线前后的对比数据:

指标 上线前 上线后 变化
研发日均被打断次数 5-8 次 1-2 次 ↓ 75%
工单平均响应时间 15 分钟 3 分钟 ↓ 80%
FAQ 咨询人工介入率 100% 30% ↓ 70%
研发连续专注时长 < 1 小时 2+ 小时 ↑ 100%
首字响应延迟 --- < 3 秒(中位数) ---
并发会话数 --- 10 个无压力 ---
已接入工具数 0 8 个,持续增加 ---

以上数据为部门内部统计,不同团队规模和场景会有差异。

使用场景覆盖:技服工单排查、知识库咨询、项目进度查询、构建失败推送、健康提醒。

最直观的感受:研发被打断的次数明显少了。以前一天被 @ 5 次回答"怎么查日志",现在机器人接了,研发能连续写两小时代码不被打断------这才是我们想要的。

一些反思

回头看,有几个决策做对了:

  1. Non-goals 先写------防止范围蔓延,这是内部工具存活的关键
  2. 滚动摘要优先级最高------上下文断裂是信任杀手,必须先解决
  3. Agent SDK 而不是 CLI------控制权决定了你能做多少事
  4. 工具热插拔------加工具成本极低,迭代速度快
  5. 安全边界明确------不碰生产、不碰数据库写、不碰客户数据

也有做得不够的:

  • FAQ 知识库 一开始想上向量检索,后来发现关键词匹配就够用,白纠结了一周。教训:先跑起来再优化,别一上来就过度设计
  • 记忆系统还没上自动梳理,目前人工维护,量大了会成负担

下一步计划:上向量检索升级 FAQ 精度,把记忆系统的自动梳理补上,再扩展几个推送场景(代码走查严重问题、发布通知)。


如果你也在考虑给团队搭一个内部 AI 助手,我的建议是:先想清楚不做什么,再想做什么。 功能可以慢慢加,边界一旦模糊了,收不回来。

相关推荐
北鸟南游2 小时前
学习-claude code 工程化实战的笔记
前端·ai编程·claude
梦想的旅途22 小时前
企业微信外部群智能自动回复:基于RPA接口的关键词匹配方案
java·开发语言·数据库·机器人·自动化·企业微信
love530love3 小时前
GPT + Codex CLI + CodexPro 三位一体:AI 编程协作工作流
人工智能·windows·gpt·chatgpt·devops·mcp
AustinXu3 小时前
进化搜索:Harness Engineering 之后,Agent 怎么自己进化自己
架构·claude·敏捷开发
智脑API平台4 小时前
Claude Code国内怎么使用?2026年API Key、Base URL与最小测试教程
ai编程·claude·claude code教程
用户600071819104 小时前
【翻译】在 Claude Code 中选择 Claude 模型与 effort 级别
claude
四方云4 小时前
2026电销系统科普:直呼、回拨没有优劣之分,选对场景才高效
人工智能·机器人·销售成长·电销系统
147API4 小时前
Claude 的 Microsoft 365 connector 能写入了,技术接入别跳过权限验收
人工智能·microsoft·claude
正在走向自律7 小时前
从感知到自主决策:机器人技术的演进、核心架构与产业落地全景解析
架构·机器人·人形机器人·宇数机器人·医疗服务