QQ「大肥鱼」AI 机器人

从零搭建一只会聊天、会查资料、能操作飞书文档的 QQ「大肥鱼」AI 机器人

一台 Ubuntu 服务器、两个 Docker 容器、五个自写插件,把 DeepSeek、本地语音、飞书 CLI 和一个 Agent 运行时串成一条完整链路。 本文是完整复盘,包含可复制的命令、踩过的坑和最终架构。


一、前言:我们到底在做什么

目标很朴素:在 QQ 里养一只 AI 宠物。

但"会聊天"只是起点,真正难的是让它:

  • 记得住上下文、查得到实时资料
  • 听得懂语音、用特定音色回语音
  • 能读写飞书云文档
  • 能执行复杂任务(跑命令、写文件、多步研究)
  • 还得有权限控制,不能谁都能指挥它

最终落地成一条链路:

flowchart LR QQ[QQ 用户] -->|消息| NC[NapCat<br/>OneBot v11] NC -->|反向 WS| AB[AstrBot<br/>对话中枢] AB --> LLM[DeepSeek<br/>deepseek-flash] AB --> WS[DeepSeek 搜索<br/>tools/search] AB --> STT[本地 Whisper<br/>语音转文字] AB --> TTS[Edge TTS<br/>晓伊少女音] AB --> PLUG[自研插件<br/>唤醒门控/语音门控/DSH 桥接] PLUG -->|dsh headless| DSH[DSH Agent] DSH -->|lark-cli| FS[飞书云文档] DSH -->|bash/file| SYS[服务器容器环境]

一句话概括技术栈:

层 选型
消息通道 NapCat(OneBot v11)
对话中枢 AstrBot 4.29.3
模型 DeepSeek deepseek-flash
语音识别 本地 Whisper small(CPU)
语音合成 Microsoft Edge TTS zh-CN-XiaoyiNeural
Agent DeepSeek Harness dsh --profile headless
文档 飞书官方 CLI @larksuite/cli

二、服务器与基础环境

2.1 服务器

复制代码
Ubuntu 24.04.3 LTS / 4 vCPU / 15 GB RAM / 885 GB 磁盘
Docker 29.4.1 + Compose v5.5

机器上本来就跑着 10 个生产容器(kodbox、官网、后台 demo 等)。 原则:只新增容器、只绑内网 IP、不重启 Docker daemon、不动现有服务。

2.2 拉镜像的第一道坎:Docker Hub 不通

国内服务器直连 registry-1.docker.io 基本超时。两种解法:

方案 A:改 daemon.json 加镜像加速(适合新机器,但需要重启 Docker)

json 复制代码
{
  "registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}

方案 B:不动 daemon,用镜像源前缀拉取再 retag(适合生产机器,强烈推荐)

bash 复制代码
docker pull docker.m.daocloud.io/soulter/astrbot:latest
docker tag docker.m.daocloud.io/soulter/astrbot:latest soulter/astrbot:latest

我在生产机上用的就是方案 B ------ 重启 Docker 会把现有容器全部重启,风险不可控。


三、部署 AstrBot + NapCat

3.1 创建专用网络

bash 复制代码
docker network create astrbot-napcat

3.2 启动 AstrBot

bash 复制代码
docker run -d --name astrbot --network astrbot-napcat --restart always \
  -p 192.168.0.70:6185:6185 \
  -p 192.168.0.70:6199:6199 \
  -v /home/docmap/astrbot/data:/AstrBot/data \
  soulter/astrbot:latest
  • 6185:WebUI(管理后台)
  • 6199:OneBot v11 反向 WebSocket 端口
  • 绑定的是内网 IP,不是 0.0.0.0,公网访问不到

3.3 启动 NapCat

bash 复制代码
docker run -d --name napcat --network astrbot-napcat --restart always \
  -p 192.168.0.70:6099:6099 \
  -e NAPCAT_UID=1000 -e NAPCAT_GID=1000 \
  -v /home/docmap/napcat/config:/app/napcat/config \
  -v /home/docmap/napcat/qq:/app/.config/QQ \
  mlikiowa/napcat-docker:latest

3.4 扫码登录

NapCat 启动后会在日志里打印二维码和 WebUI Token:

ini 复制代码
WebUi User Panel Url: http://127.0.0.1:6099/webui?token=xxxxxxxx
二维码解码URL: https://txz.qq.com/p?k=...

用手机 QQ 扫码并在手机上点确认即可。

注意:NapCat 每次重启都需要重新扫码,登录态不持久。 所以后面对 AstrBot 做任何改动都只重启 AstrBot,不碰 NapCat。

3.5 打通反向 WebSocket

在 NapCat 的配置里加一个 WS 客户端:

json 复制代码
{
  "network": {
    "websocketClients": [
      {
        "name": "astrbot",
        "enable": true,
        "url": "ws://astrbot:6199/ws",
        "messagePostFormat": "array",
        "token": "",
        "heartInterval": 30000,
        "reconnectInterval": 5000
      }
    ]
  }
}

AstrBot 侧在 cmd_config.json 里加 OneBot 平台:

json 复制代码
{
  "platform": [
    {
      "id": "default",
      "type": "aiocqhttp",
      "enable": true,
      "ws_reverse_host": "0.0.0.0",
      "ws_reverse_port": 6199,
      "ws_reverse_token": ""
    }
  ]
}

连上后日志会出现:

scss 复制代码
aiocqhttp(OneBot v11) 适配器已连接。

四、接入 DeepSeek:模型与搜索

4.1 模型 Provider

json 复制代码
{
  "id": "deepseek-flash",
  "provider": "deepseek",
  "type": "openai_chat_completion",
  "provider_type": "chat_completion",
  "enable": true,
  "key": ["sk-你的Key"],
  "api_base": "https://api.deepseek.com/v1",
  "model": "deepseek-flash",
  "provider_source_id": "deepseek",
  "modalities": ["text", "image", "tool_use"]
}

4.2 联网搜索

DeepSeek 自带搜索接口,直接复用同一个 Key:

bash 复制代码
curl -X POST https://api.deepseek.com/v1/tools/search \
  -H "Authorization: Bearer sk-你的Key" \
  -H "Content-Type: application/json" \
  -d '{"query":"今天的 AI 新闻","count":3,"need_content":false}'

在 AstrBot 里开启:

json 复制代码
{
  "provider_settings": {
    "web_search": true,
    "websearch_provider": "deepseek",
    "websearch_deepseek_key": ["sk-你的Key"],
    "web_search_link": true
  }
}

4.3 大坑:modalities 不写会 422

这是本文最值得记录的问题之一。

现象:

typescript 复制代码
422 UnprocessableEntityError:
Failed to deserialize the JSON body into the target type:
messages[45]: unknown variant `input_audio`,
expected one of `text`, `image_url`, `file`

原因:AstrBot 的 context 清洗逻辑是------

python 复制代码
modalities = provider.provider_config.get("modalities", None)
if not modalities:
    # Unconfigured defaults to support all modalities
    return contexts

也就是说:provider 不声明能力边界时,AstrBot 默认它什么模态都支持,于是把语音音频原样塞进请求,DeepSeek 直接 422。

解法 :显式声明,只给 text / image / tool_use,不给 audio:

json 复制代码
"modalities": ["text", "image", "tool_use"]

这样即使语音转写失败,音频也会被替换成 [Audio] 占位文本,而不是让整个请求挂掉。


五、群聊唤醒控制:谁可以不用 @

5.1 需求

  • 主人(指定 QQ)在群里说话,不需要 @
  • 其他人在群里,必须 @ 机器人 或 叫它名字 才会回复

5.2 原理

AstrBot 的唤醒逻辑写死在 waking_check/stage.py,只认 @、@全体、引用、唤醒词。配置层没有"按人区分"的开关。

但代码里有一行关键逻辑:插件注册的处理器会把 is_wake 置为 True。于是可以:

  1. 把 wake_prefix 设为空字符串 [""],让所有群消息都进入处理管线
  2. 写一个插件做"门控":非白名单且没 @ 没叫名字的消息,直接 should_call_llm(False)

5.3 插件实现

python 复制代码
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.api.star import Context, Star, register
from astrbot.core.message.components import At, Reply

WHITELIST = {"136988xxxxx"}
NAME_KEYWORDS = ("大肥鱼", "肥鱼", "邪恶大肥鱼")


@register("wake_by_user", "you", "仅指定QQ免@", "1.0.0")
class WakeByUser(Star):
    def __init__(self, context: Context):
        super().__init__(context)

    @filter.event_message_type(filter.EventMessageType.GROUP_MESSAGE)
    async def gate(self, event: AstrMessageEvent):
        sender = str(event.get_sender_id())
        if sender in WHITELIST:
            return
        text = (event.message_str or "").strip()
        if any(k in text for k in NAME_KEYWORDS):
            return
        self_id = str(event.get_self_id())
        for seg in event.get_messages():
            if isinstance(seg, At) and str(getattr(seg, "qq", "")) == self_id:
                return
            if isinstance(seg, Reply) and str(getattr(seg, "sender_id", "")) == self_id:
                return
        event.should_call_llm(False)

5.4 上下文记忆

群里只记录 @ 它的消息?那当然读不懂上下文。需要额外打开:

json 复制代码
{
  "provider_ltm_settings": {
    "group_message_history_enable": true,
    "group_message_history_max_cnt": 700
  }
}

六、语音链路:本地识别 + 少女音回复

这是整个项目最折腾的部分,分四段讲。

6.1 本地 STT:Whisper 的安装陷阱

AstrBot 的 Whisper(Local) provider 依赖 openai-whisper,而它又依赖 torch。

坑 1:PyPI 的 torch 是 CUDA 版,体积近 1GB,国内下载极慢(实测 40 分钟只下了 390MB)。

解法:用阿里云的 CPU-only wheel(约 200MB,4.8MB/s):

bash 复制代码
pip install --target=/AstrBot/data/pylibs --no-deps \
  "https://mirrors.aliyun.com/pytorch-wheels/cpu/torch-2.6.0%2Bcpu-cp312-cp312-linux_x86_64.whl"

坑 2 :直接 pip install openai-whisper 会重新解析依赖,可能又去拉 CUDA 版 torch。

解法 :--no-deps 分开装,依赖项逐个指定国内源:

bash 复制代码
pip install --target=/AstrBot/data/pylibs --no-deps -i https://pypi.tuna.tsinghua.edu.cn/simple \
  openai-whisper
pip install --target=/AstrBot/data/pylibs -i https://pypi.tuna.tsinghua.edu.cn/simple \
  filelock typing-extensions sympy networkx jinja2 fsspec numpy numba tiktoken more-itertools tqdm

坑 3 :--target 装的包,主进程默认 import 不到。

解法 :往系统 site-packages 塞一个 .pth 文件(比重建容器省事):

bash 复制代码
printf '/AstrBot/data/pylibs\n/AstrBot/data/pylibs-tts\n' \
  > /usr/local/lib/python3.12/site-packages/astrbot-extra.pth

6.2 识别不准?两个真凶

真凶一:语言自动检测跑偏。

Whisper 不指定语言时会自动判断,低音量/模糊时把中文识别成英语甚至瑞典语:

vbnet 复制代码
Speech-to-text result: You thinkер y
Speech-to-text result: Så är jag.

解法:给 provider 打补丁,强制中文 + 引导提示:

python 复制代码
result = await loop.run_in_executor(
    None,
    partial(self.model.transcribe,
            language="zh",
            initial_prompt="以下是普通话日常对话。"),
    str(audio.path),
)

真凶二:QQ 语音音量太低。

实测用户语音平均音量 -36.9 dB(正常说话约 -20 dB),Whisper 直接输出空字符串。

解法 :转写前做响度归一化(loudnorm):

python 复制代码
proc = await asyncio.create_subprocess_exec(
    "ffmpeg", "-y", "-loglevel", "error",
    "-i", src,
    "-af", "loudnorm=I=-16:TP=-1.5:LRA=11",
    norm,
)
await proc.communicate()
target = norm if proc.returncode == 0 else src

效果对比:

音频 修复前 修复后
正常音量 正确 正确
音量降到 12% 变成外语 仍然正确
实际 -36dB 语音 空字符串 "我们就回来啦"

兜底:如果归一化后还是空,返回一句提示文本,避免音频继续流向不支持音频的模型:

python 复制代码
text = result["text"].strip()
return text if text else "(语音没听清,请再说一遍)"

6.3 Edge TTS:免费但需要联网

json 复制代码
{
  "id": "edge_tts",
  "type": "edge_tts",
  "provider": "microsoft",
  "provider_type": "text_to_speech",
  "enable": true,
  "edge-tts-voice": "zh-CN-XiaoyiNeural",
  "rate": "+0%",
  "volume": "+0%",
  "pitch": "+0Hz"
}
  • zh-CN-XiaoyiNeural(晓伊):少女音,偏"呆萌"
  • zh-CN-XiaoxiaoNeural(晓晓):通用女声,更稳
  • Edge TTS 免费、无需 Key,但依赖微软接口,需要联网

想要完全离线的卡通女声,Linux 上可选项(GPT-SoVITS、Breezy 等)要么要 GPU,要么模型几 GB,性价比不高,最终选了 Edge。

6.4 语音门控:只在私聊、只在发语音时回语音

需求很明确:群里永远文字;私聊发文字回文字;私聊发语音才回语音。

AstrBot 的 TTS 开关是按会话的,所以写个插件在每条消息时动态设置:

python 复制代码
@filter.event_message_type(filter.EventMessageType.ALL)
async def gate(self, event: AstrMessageEvent):
    sender = str(event.get_sender_id())
    enable = bool(
        sender == OWNER
        and event.is_private_chat()
        and _has_voice(event)
    )
    await SessionServiceManager.set_tts_status_for_session(
        event.unified_msg_origin, enable
    )

关键坑 :AstrBot 的 STT 阶段会把 Record 组件替换成 Plain 文本 ,所以在插件阶段 isinstance(m, Record) 永远为 False。

解法:同时检查原始事件:

python 复制代码
def _has_voice(event) -> bool:
    # 1) 当前链路(STT 之前)
    if any(isinstance(m, Record) for m in event.get_messages()):
        return True
    # 2) 原始 OneBot 事件(兜底)
    raw = getattr(event.message_obj, "raw_message", None)
    msg = getattr(raw, "message", None) or (raw.get("message") if isinstance(raw, dict) else None)
    if isinstance(msg, list):
        for seg in msg:
            t = seg.get("type") if isinstance(seg, dict) else getattr(seg, "type", None)
            if t == "record" or "record" in str(seg).lower():
                return True
    # 3) CQ 字符串形式
    if isinstance(getattr(raw, "raw_message", ""), str) and "[CQ:record" in raw.raw_message:
        return True
    return False

6.5 TTS 把符号读出来了

模型回复里带了 emoji 和 markdown(咕噜......本鱼**最爱**吃宵夜🐟🍜),TTS 会老老实实把它们念出来。

解法:合成前清洗文本:

python 复制代码
_EMOJI_RE = re.compile(
    r"[\U0001F000-\U0001FAFF\U00002600-\U000027BF\U0001F1E6-\U0001F1FF\u2190-\u21FF\u2B00-\u2BFF\uFE0F\u200D]+"
)
_MD_RE = re.compile(r"[*_`#>~\[\](){}|\\]+")
_ELLIPSIS_RE = re.compile(r"...+|\.{3,}")

def _clean_for_tts(text: str) -> str:
    t = _EMOJI_RE.sub("", text or "")
    t = _MD_RE.sub("", t)
    t = _ELLIPSIS_RE.sub(",", t)
    return re.sub(r",{2,}", ",", t).strip(" ,\n")

实测:

bash 复制代码
原文:  咕噜......本鱼**最爱**吃宵夜🐟🍜!还有 #标签 和 [链接]
清洗后:咕噜,本鱼最爱吃宵夜!还有 标签 和 链接

七、让机器人调用 Agent:DSH 接入

7.1 为什么用 headless

DSH(DeepSeek Harness)有一次性执行模式:

bash 复制代码
dsh --profile headless "帮我查一下今天的 AI 新闻并总结"
# 执行完把结果打印到 stdout 然后退出

这正好适合"QQ 消息 → 子进程 → 拿结果"的模型。

7.2 容器内怎么跑 Node

DSH 需要 Node 24。服务器上装好后(约 120MB),把它只读挂载进 AstrBot 容器:

bash 复制代码
docker run -d --name astrbot ... \
  -v /opt/node:/opt/node:ro \
  soulter/astrbot:latest

容器内验证:

bash 复制代码
docker exec astrbot /opt/node/bin/dsh --version
# 0.2.1-rc.2

用官方源装 npm 包:npm install -g @deepseek-ai/dsh --registry=https://registry.npmmirror.com 注意 npm 11 会拦截 install scripts,需要 --allow-scripts。

7.3 插件设计:白名单 + 审批

python 复制代码
OWNER = "1369xxxxx"
DSH_BIN = "/opt/node/bin/dsh"
WORKDIR = "/AstrBot/data/dsh-work"
TIMEOUT = 600
PENDING = {}   # 审批队列
LAST = {}      # 上次任务上下文

# 触发词:dsh / 工具 / 消息里提到飞书
# 主人:直接执行
# 其他人:生成编号,私聊发给主人审批

审批流:

复制代码
路人:工具 帮我写个脚本
机器人:已提交管理员审批(编号 1)
主人(私聊):同意 1
机器人 → 路人:执行结果
机器人 → 主人:【1 完成】摘要

7.4 几个工程细节

① 上下文续接

Agent 任务完成后,用户下一句"不对,应该放到表格里"会落到普通聊天模型,它完全不知道 DSH 干过什么。

解法:把"修正类关键词"(不对/表格/改成/应该/重新/补漏)在 30 分钟内自动带回 DSH,并附带上次任务与结果:

python 复制代码
task = (
    f"上下文:上一次任务『{LAST['task'][:300]}』;"
    f"执行结果摘要:{LAST['result'][:600]}。"
    f"用户现在的要求:{text}。请基于上下文直接执行。"
)

上下文还会持久化到 last_task.json,重启不丢。

② 超时保护

python 复制代码
out, err = await asyncio.wait_for(proc.communicate(), timeout=TIMEOUT)

超时后 kill 进程,并把部分输出截断返回,方便定位卡在哪一步。

③ 给 Agent 加约束

任务提示里明确写"直接执行,不要探索无关文件、不要读技能文档、不要上网查资料",否则它会在 5 分钟里跑 60 多步"研究"。


八、飞书文档能力

8.1 官方 CLI,别手搓 API

飞书官方出了 larksuite/cli,把云文档、消息、日历都封装成命令,而且自带 OAuth 设备码流程,非常适合服务器这种无浏览器环境。

bash 复制代码
npm install -g @larksuite/cli
lark-cli --version

8.2 无浏览器授权

bash 复制代码
# 1. 初始化应用(会打印一个链接,浏览器打开创建应用)
lark-cli config init --new

# 2. 设备码授权(打印 verification_url,手机/电脑打开确认)
lark-cli auth login --domain docs,drive,wiki --no-wait
# 拿到 device_code 和 verification_url

# 3. 用户确认后完成
lark-cli auth login --device-code <device_code>

# 4. 验证
lark-cli auth status

授权成功后能看到:

vbnet 复制代码
User identity: ready
openId: ou_xxx
userName: 张三
scope: docx:document:readonly docs:document:export drive:file:download ...

8.3 让 DSH 调用它

在 dsh_bridge 插件的子进程环境里注入:

python 复制代码
env["HOME"] = "/AstrBot/data/lark-home"   # lark-cli 的配置和 token 在这里
env["PATH"] = "/opt/node/bin:" + env.get("PATH", "")

然后 QQ 里直接说:

arduino 复制代码
帮我整理这篇飞书文档,给三条要点:https://xxx.feishu.cn/docx/xxxx

插件识别到"飞书"关键词就自动转给 DSH,DSH 自己会选 lark-cli docs +fetch / drive +inspect 之类的命令。


九、插件生态:表情包与"防串台"

从社区配置包 dafeiyu-config-pack 里挑了三个不碰 QQ 敏感接口的插件:

插件 作用
meme_manager 表情包管理,AI 按情绪自动发图,带 WebUI 管理页
astrbot_plugin_dafeiyu_clean 清理模型偶尔吐出的 <system_reminder>、DSML 等内部标签
LivingMemory 长期记忆,需要 Embedding 模型,暂未启用

长期记忆的坑:它要求配置一个向量嵌入 Provider(如 Ollama + bge-m3)。服务器上没有 GPU,Ollama 也要再拉 1.5GB+,权衡后先停用。


十、踩坑清单(建议收藏)

# 现象 原因 解法
1 docker pull 超时 Docker Hub 被墙 镜像源前缀 + retag,或 daemon mirror
2 pip 装 torch 极慢 PyPI 是 CUDA 版 阿里云 CPU wheel
3 主进程 import 不到 --target 装的包 不在 sys.path 写 .pth 到 site-packages
4 语音识别成外语 Whisper 自动语言检测 强制 language="zh" + initial_prompt
5 语音识别为空 QQ 语音音量过低(-36dB) ffmpeg loudnorm 归一化
6 422 input_audio provider 没声明 modalities,默认全支持 modalities: ["text","image","tool_use"]
7 TTS 不触发 STT 把 Record 换成了 Plain 从 raw_message 检测 record 段
8 语音念出符号 没清洗 markdown/emoji TTS 前正则清洗
9 群里只有 @ 才回 唤醒逻辑写死 空 wake_prefix + 插件门控
10 读不懂群聊上下文 群历史未记录 group_message_history_enable: true
11 Agent 超时且无输出 任务太模糊,Agent 在"研究" 给文档链接 + 约束提示 + 返回部分输出
12 任务追问丢上下文 DSH 结果没进聊天上下文 修正类关键词带回 DSH + 持久化
13 QQ 频繁被踢 账号在多端登录 专用小号,只用于机器人
14 serverErrorCode: 168 腾讯风控判定异常 手机 QQ 走安全验证;接受周期性风险
15 重启 NapCat 要重新扫码 登录态不持久 只重启 AstrBot,不动 NapCat
16 容器重建后补丁丢失 补丁打在容器文件系统里 记录补丁脚本,或用 -e PYTHONPATH 固化
17 飞书 scope 不够 只申请了 docs/drive/wiki auth login --scope "space:document:retrieve"

十一、安全与合规(必须看)

  1. QQ 自动化违反腾讯用户协议 ,有封号风险。本项目的账号就被风控限制过两次(KickedOffLine、serverErrorCode: 168)。建议专用小号,控制发言频率,不要群发/加人。
  2. Agent 权限要收 :DSH 在容器内以 root 运行,能读写 /AstrBot/data(里面有配置文件)。白名单 + 审批流是底线;不要把审批权限放开给陌生人。
  3. Key 分离 :聊天/搜索用一个 Key,DSH 用另一个 Key(DEEPSEEK_API_KEY 注入),便于单独统计和止损。
  4. 端口只绑内网,WebUI 靠内网 IP 或 SSH 隧道访问,不要暴露公网。
  5. 飞书权限最小化:只申请 docs/drive/wiki,不做写操作就不加写权限。

十二、成本

项 费用
DeepSeek 对话 每百万 token 几元,日常聊天可用很久
DeepSeek 搜索 同上,按调用计费
Edge TTS 免费
飞书 API 免费
服务器 已有机器,新增占用约 5GB 磁盘 / 1.5GB 内存

十三、总结

这套方案的核心不是"接一个大模型",而是把四个系统缝成一条可靠的链路:

  • 消息层:NapCat 负责 QQ 协议
  • 对话层:AstrBot 负责编排、上下文、插件
  • 能力层:DeepSeek(模型+搜索)、Whisper(语音)、Edge TTS(语音)
  • 执行层:DSH Agent + lark-cli 负责"动手"

真正花时间的不是写代码,而是排查那些沉默的失败:语言检测跑偏、音量太低、modalities 默认全开、STT 把语音段换掉......每一条都藏在日志的角落里。

如果这篇文档帮你少踩一个坑,就值了。


本文基于真实部署整理,涉及账号、Key、内网 IP 均已脱敏处理。

相关推荐
xn71334 小时前
本地 AI 知识库跨设备同步:SQLite FTS5、Embedding、Tombstone 和引用校验
人工智能·sqlite·ai编程
FPGA小迷弟4 小时前
FPGA 与无人机:从飞控实时性到智能载荷的硬件加速实践
人工智能·ai·fpga开发·架构·无人机·ai编程
終不似少年遊*5 小时前
【AI Coding实战方法论】从计划协作到架构护栏,一套能长期复用的工程流程
人工智能·python·团队开发·ai编程·ai coding·skills·上下文管理
产品经理爱开发5 小时前
AxureShow(艾可秀)国内通用的html托管
前端·人工智能·html·ai编程
验真所6 小时前
半衰期估错 10 倍,一条判据误杀 100% 的信号:AR(1) 反解的三个坑
人工智能·ai编程
luobobo8966 小时前
两个 AI 都说「没发出去」,其实都发了:判失败要连查两次
ai编程
用户6602638008367 小时前
我给自己的 AI 员工算了笔账:改了三处,每步成本从 0.026 元降到 0.0058 元
ai编程
程语AI7 小时前
RAG 答案质量评估实战:LLM-as-Judge 怎么用、怎么校准
ai编程
season_zhu8 小时前
Skills For Real Engineers 系列之三:需求聊清楚了,怎么一步步走主流程,做到交付?
ios·ai编程