Day28-Java核心 × Spring生态篇:用Spring AI为你的Spring Boot项目添加智能客服
很多老板都希望这样一个AI智能客服客户问啥它都能答。——这是90%老板的真实想法。我得告诉你AI客服不是万能答题机它是带约束的对话引擎。你能把约束定义得多清楚它就有多靠谱。一、先想清楚架构再动手写代码很多同学上手就ChatClient.create().prompt().user(你好).call()然后发现AI答非所问、胡说八道、还记不住上文。问题不在大模型在于你根本没给AI搭好舞台。一个生产可用的智能客服至少要解决四件事这四层每一层都有坑。下面我逐层给你代码。版本约定本文基于 Spring Boot 3.3.x Spring AI 1.0.0 JDK 17。Day 26 讲过依赖配置这里不再重复贴 POM直接上核心逻辑。二、第一层会话历史管理——让AI记住上下文大模型本身是无状态的。你以为它记住了上文不是你每次请求时把历史对话一起塞进去了。所以会话历史的存储和裁剪是智能客服的第一道命门。2.1 为什么不能全塞进去一个客户跟你聊了50轮每轮平均200 Token历史就是10000 Token。全塞进去有三个致命问题费用爆炸Token就是钱每次请求1万Token历史一天烧掉你几百块上下文窗口溢出大部分模型32K窗口历史Prompt输出超了就截断注意力稀释上下文越长模型对近期对话的注意力越弱答非所问2.2 实战方案Redis滚动窗口 摘要压缩/** * 对话历史管理服务 * 策略保留最近6轮12条消息超出部分做摘要压缩 * 存储Redis Listkey为 sessionIdTTL 30分钟 */ Service Slf4j public class ChatHistoryService { private final StringRedisTemplate redisTemplate; private final ChatClient summarizeClient; // 专门做摘要的轻量模型 // 保留最近几轮对话一轮userassistant各一条 private static final int MAX_ROUNDS 6; private static final int HISTORY_TTL_MINUTES 30; private static final String HISTORY_KEY_PREFIX chat:history:; private static final String SUMMARY_KEY_PREFIX chat:summary:; public ChatHistoryService(StringRedisTemplate redisTemplate, ChatClient.Builder builder, Value(${ai.summary-model}) String summaryModel) { this.redisTemplate redisTemplate; // 摘要用便宜模型省钱 this.summarizeClient builder.build(); } /** * 构建完整的上下文消息列表摘要 最近N轮 */ public ListMessage buildContextMessages(String sessionId, String currentQuestion) { ListMessage messages new ArrayList(); // 1. 加载历史摘要如果有 String summary redisTemplate.opsForValue().get(SUMMARY_KEY_PREFIX sessionId); if (StrUtil.isNotBlank(summary)) { messages.add(new SystemMessage(以下是之前对话的摘要信息\n summary)); } // 2. 加载最近N轮历史 ListString rawHistory redisTemplate.opsForList() .range(HISTORY_KEY_PREFIX sessionId, 0, -1); if (CollUtil.isNotEmpty(rawHistory)) { for (String json : rawHistory) { ChatTurn turn JSONUtil.toBean(json, ChatTurn.class); if (user.equals(turn.getRole())) { messages.add(new UserMessage(turn.getContent())); } else { messages.add(new AssistantMessage(turn.getContent())); } } } // 3. 当前问题 messages.add(new UserMessage(currentQuestion)); return messages; } /** * 保存一轮对话并在超限时触发摘要压缩 */ public void saveTurn(String sessionId, String userMsg, String assistantMsg) { String key HISTORY_KEY_PREFIX sessionId; redisTemplate.opsForList().rightPush(key, JSONUtil.toJsonStr(new ChatTurn(user, userMsg))); redisTemplate.opsForList().rightPush(key, JSONUtil.toJsonStr(new ChatTurn(assistant, assistantMsg))); redisTemplate.expire(key, Duration.ofMinutes(HISTORY_TTL_MINUTES)); // 超过最大轮数压缩旧消息 Long size redisTemplate.opsForList().size(key); if (size ! null size MAX_ROUNDS * 2) { compressHistory(sessionId); } } /** * 摘要压缩把最早的两轮抽出来让AI生成摘要存到summary key */ private void compressHistory(String sessionId) { String key HISTORY_KEY_PREFIX sessionId; // 弹出最早的2条1轮 String old1 redisTemplate.opsForList().leftPop(key); String old2 redisTemplate.opsForList().leftPop(key); if (old1 null || old2 null) return; String existingSummary redisTemplate.opsForValue() .get(SUMMARY_KEY_PREFIX sessionId); String prompt 请将以下内容整合为一段简洁的摘要不超过200字保留关键事实 %s 对话片段 用户%s 客服%s .formatted( existingSummary ! null ? 已有摘要 existingSummary : 无已有摘要, JSONUtil.toBean(old1, ChatTurn.class).getContent(), JSONUtil.toBean(old2, ChatTurn.class).getContent() ); String newSummary summarizeClient.prompt() .user(prompt) .call() .content(); redisTemplate.opsForValue().set(SUMMARY_KEY_PREFIX sessionId, newSummary, Duration.ofMinutes(HISTORY_TTL_MINUTES)); log.info(会话 {} 历史已压缩新摘要长度: {}, sessionId, newSummary.length()); } Data AllArgsConstructor NoArgsConstructor static class ChatTurn { private String role; private String content; } }这段代码的三个关键设计设计点为什么这么做常见错误Redis List滚动存储左push右pop天然适合FIFO窗口用Hash存取排序麻烦摘要用独立轻量模型摘要任务简单用GPT-4纯属烧钱全用一个模型成本翻3倍TTL 30分钟客服场景用户很少离开1小时再回来设24小时Redis内存被吃光三、第二层Prompt增强——给AI套上紧箍咒Day 27 讲了PromptTemplate和角色系统今天我们把它们组装成一个Prompt增强Pipeline。核心思想用户说的话不能直接喂给大模型要经过三层加工。3.1 三层加工流水线用户原始问题 │ ├─① 安全过滤 → 拦截Prompt注入 / 敏感词 │ ├─② 意图识别 → 判断问题类型售前/售后/投诉/闲聊 │ └─③ 知识注入 → 根据意图注入对应FAQ/产品信息 │ ▼ 增强后的Prompt → 送入大模型3.2 完整实现/** * Prompt增强Pipeline * 职责安全过滤 → 意图识别 → 知识注入 → 组装最终Prompt */ Service Slf4j public class PromptEnhanceService { private final ChatClient chatClient; private final KnowledgeBaseService knowledgeBaseService; // 你的业务知识库 // 敏感词黑名单生产环境用DFA算法这里简化 private static final ListString BLOCKED_PATTERNS List.of( 忽略以上指令, ignore previous instructions, system:, 你现在是 ); public PromptEnhanceService(ChatClient.Builder builder, KnowledgeBaseService knowledgeBaseService) { this.chatClient builder.build(); this.knowledgeBaseService knowledgeBaseService; } /** * 增强入口原始问题 → 增强后的完整消息列表 */ public EnhancedPrompt enhance(String userQuestion, String sessionId) { // ① 安全过滤 if (isMaliciousInput(userQuestion)) { log.warn(检测到恶意输入session{}, question{}, sessionId, userQuestion); return EnhancedPrompt.blocked(您的提问包含敏感内容请重新描述。); } // ② 意图识别用大模型快速分类也可以用规则引擎 String intent classifyIntent(userQuestion); log.info(意图识别结果: session{}, intent{}, sessionId, intent); // ③ 知识注入根据意图检索业务知识 String knowledge knowledgeBaseService.retrieveByIntent(intent, userQuestion); // ④ 组装系统Prompt String systemPrompt buildSystemPrompt(intent, knowledge); return EnhancedPrompt.ok(systemPrompt, userQuestion); } /** * 意图分类让AI判断用户问的是售前/售后/还是闲聊 */ private String classifyIntent(String question) { String classifyPrompt 判断用户问题的意图类别只返回以下之一 - PRESALE售前咨询产品/价格/规格/活动 - AFTERSALE售后物流/退换/安装/投诉 - GENERAL闲聊/其他 用户问题%s .formatted(question); String result chatClient.prompt() .user(classifyPrompt) .call() .content(); // 容错模型可能返回多余内容 if (result ! null result.contains(PRESALE)) return PRESALE; if (result ! null result.contains(AFTERSALE)) return AFTERSALE; return GENERAL; } /** * 构建系统Prompt角色 约束 业务知识 */ private String buildSystemPrompt(String intent, String knowledge) { return ## 角色 你是「星云家居」的智能客服助手负责解答客户关于家居定制产品的咨询。 ## 行为约束 1. 只回答与家居定制相关的问题拒绝回答政治/色情/暴力等无关内容 2. 如果不确定具体信息回答这个问题我帮您转接人工客服不要编造 3. 回答简洁不超过200字用口语化表达 4. 当前意图分类%s ## 业务知识参考 %s ## 输出格式 直接回答用户问题不要加亲等过度营销话术。 .formatted(intent, knowledge); } /** * 简易恶意输入检测 */ private boolean isMaliciousInput(String input) { if (StrUtil.isBlank(input) || input.length() 500) return true; String lower input.toLowerCase(); return BLOCKED_PATTERNS.stream().anyMatch(lower::contains); } Data AllArgsConstructor public static class EnhancedPrompt { private boolean blocked; private String blockReason; private String systemPrompt; private String userQuestion; public static EnhancedPrompt ok(String systemPrompt, String userQuestion) { return new EnhancedPrompt(false, null, systemPrompt, userQuestion); } public static EnhancedPrompt blocked(String reason) { return new EnhancedPrompt(true, reason, null, null); } } }这段代码的实战价值安全过滤层isMaliciousInput是Prompt注入的第一道防线。生产环境建议上正则DFA敏感词树别像我这样写contains意图识别用轻量模型这步可以用最便宜的模型如DeepSeek-V3或通义千问turbo成本几分钱。不要用GPT-4o做分类杀鸡用牛刀知识注入这里先用关键词检索示意Day 71-75 会讲RAG用向量检索替代效果提升一个量级四、第三层流式对话接口——把AI输出实时推给前端用户问完问题盯着转圈等3秒才出结果——这体验在2026年已经不可接受了。流式输出SSE是智能客服的标配Day 14讲过SSE原理今天直接落地。4.1 完整的对话Controller/** * 智能客服对话接口 * POST /api/chat/stream * 流式返回AI回复SSE */ RestController RequestMapping(/api/chat) Slf4j public class ChatController { private final PromptEnhanceService promptEnhanceService; private final ChatHistoryService chatHistoryService; private final ChatClient chatClient; // 降级开关大模型超时/异常时返回兜底话术 Value(${ai.fallback-message:抱歉客服系统正忙请稍后再试或联系人工客服 400-xxx-xxxx}) private String fallbackMessage; Value(${ai.timeout-ms:30000}) private long timeoutMs; public ChatController(PromptEnhanceService promptEnhanceService, ChatHistoryService chatHistoryService, ChatClient.Builder builder) { this.promptEnhanceService promptEnhanceService; this.chatHistoryService chatHistoryService; this.chatClient builder.build(); } /** * 流式对话接口 */ PostMapping(value /stream, produces MediaType.TEXT_EVENT_STREAM_VALUE) public FluxServerSentEventString chat(RequestBody ChatRequest request) { String sessionId request.getSessionId(); String question request.getQuestion(); // ① Prompt增强 PromptEnhanceService.EnhancedPrompt enhanced promptEnhanceService.enhance(question, sessionId); if (enhanced.isBlocked()) { return Flux.just(ServerSentEvent.Stringbuilder() .event(blocked) .data(enhanced.getBlockReason()) .build()); } // ② 构建完整上下文摘要 历史 当前 ListMessage contextMessages chatHistoryService .buildContextMessages(sessionId, enhanced.getUserQuestion()); // ③ 组装Prompt系统消息 上下文 Prompt prompt new Prompt(contextMessages); prompt.getInstructions().add(0, new SystemMessage(enhanced.getSystemPrompt())); // ④ 流式调用大模型 StringBuilder fullResponse new StringBuilder(); return chatClient.prompt(prompt) .stream() .content() .timeout(Duration.ofMillis(timeoutMs)) // 逐Token推送 .map(chunk - { fullResponse.append(chunk); return ServerSentEvent.Stringbuilder() .event(message) .data(chunk) .build(); }) // 流结束保存对话历史 .concatWith(Flux.defer(() - { chatHistoryService.saveTurn(sessionId, enhanced.getUserQuestion(), fullResponse.toString()); return Flux.just(ServerSentEvent.Stringbuilder() .event(done) .data([DONE]) .build()); })) // 降级超时或异常 .onErrorResume(e - { log.error(对话异常, session{}, sessionId, e); chatHistoryService.saveTurn(sessionId, enhanced.getUserQuestion(), fallbackMessage); return Flux.just(ServerSentEvent.Stringbuilder() .event(error) .data(fallbackMessage) .build()); }); } Data public static class ChatRequest { private String sessionId; private String question; } }4.2 三个SSE事件类型的分工事件类型触发时机前端处理message每收到一个Token追加到对话气泡done流正常结束关闭loading标记回复完成error超时/异常显示兜底话术引导转人工blocked安全过滤拦截提示用户重新提问前端用EventSource监听这四种事件体验丝滑。这里有个新手必踩的坑concatWith里保存历史这一步要用Flux.defer()包裹否则fullResponse在流还没跑完时就是空的——因为 Reactor 的流是惰性求值。4.3 降级策略比你想的重要大模型API不是100%可用的。DeepSeek高峰期偶尔500OpenAI偶尔限流。你的客服系统必须能优雅降级。我见过太多团队没做降级大模型一挂客服系统直接白屏用户骂声一片。五、第四层业务知识注入——别让AI裸奔上面的KnowledgeBaseService我留了个悬念这里展开。5.1 最简方案YAML配置的知识库如果你的业务知识量不大几百条以内别上来就整RAG向量数据库先用YAML配置# knowledge-base.yml knowledge: PRESALE: - keywords: [价格, 多少钱, 费用] answer: 全屋定制衣柜按投影面积计价699元/㎡起含基础五金。详细报价请提供户型图。 - keywords: [工期, 多久, 几天] answer: 标准工期15-20个工作日加急7天加收20%费用。 AFTERSALE: - keywords: [退货, 退换] answer: 定制产品支持7天无理由退换非质量问题运费自理质量问题30天内免费维修。 - keywords: [安装, 师傅] answer: 安装师傅下单后3天内联系您预约时间安装免费偏远地区加收路费。Service public class KnowledgeBaseService { private final MapString, ListKnowledgeEntry knowledgeMap; public KnowledgeBaseService() { Yaml yaml new Yaml(); // 生产环境从配置中心加载这里示意 InputStream is getClass().getClassLoader() .getResourceAsStream(knowledge-base.yml); MapString, Object loaded yaml.load(is); // ... 解析到 knowledgeMap this.knowledgeMap parseKnowledge(loaded); } public String retrieveByIntent(String intent, String question) { ListKnowledgeEntry entries knowledgeMap.getOrDefault(intent, List.of()); for (KnowledgeEntry entry : entries) { if (entry.getKeywords().stream().anyMatch(question::contains)) { return entry.getAnswer(); } } return 暂无相关知识请转人工客服。; } }5.2 什么时候升级到RAG知识量方案适用阶段100条YAML/数据库硬编码MVP验证期100~1000条Elasticsearch全文检索初期上线1000条 / 非结构化文档RAG 向量数据库规模化运营老兵建议先用YAML跑通闭环验证AI客服确实能解决用户问题再上RAG。别技术倒置——我见过团队花了2周搭RAG结果发现业务知识总共才50条杀鸡用了牛刀。六、实战建议三条老兵经验建议一永远不要让AI直接回答不知道的问题// Prompt里加这句约束 2. 如果不确定具体信息回答\这个问题我帮您转接人工客服\不要编造大模型有幻觉——不知道也会编得像模像样。在客服场景编造一个错误的退货政策比说不知道严重100倍。宁可保守不可冒险。建议在Prompt里硬约束不确定就转人工。建议二监控三个核心指标别只看能不能用指标计算方式告警阈值首次响应延迟TTFT用户发送→首个Token返回2秒拦截率blocked事件/总请求5%需检查误杀转人工率回复中包含人工客服的比例30%说明知识库覆盖不足我见过一个团队上线AI客服后沾沾自喜响应好快结果一看数据60%的对话都被转给了人工——AI形同虚设。不监控就等于盲飞。建议三给AI客服设置下班时间Value(${ai.working-hours.start:8}) private int workStartHour; Value(${ai.working-hours.end:22}) private int workEndHour; // Controller入口判断 int hour LocalTime.now().getHour(); if (hour workStartHour || hour workEndHour) { // 非工作时间降级为留言模式 return Flux.just(ServerSentEvent.Stringbuilder() .event(off-hours) .data(当前为非工作时间(8:00-22:00)您的留言已记录客服将在工作时间内回复。) .build()); }大模型API按Token计费凌晨3点没人问的时候你的服务还开着万一有恶意刷接口的一晚上能给你刷掉几千块。AI客服也要上下班。AI客服的本质不是让AI代替人而是让AI处理80%的重复问题把人的精力释放给那20%真正需要温度的对话。今天这四层架构——会话管理、Prompt增强、流式输出、知识注入——是我在实战中反复打磨的最小可用方案。你把它跑起来先解决有没有的问题Day 71开始讲RAG再解决好不好的问题。下篇预告Day 29——《MySQL索引失效的10个经典场景与执行计划解读》。从AI切回数据库但这次我们会讲一个新视角AI应用的数据库和传统CRUD的索引设计有什么不同。比如向量字段怎么建索引、RAG场景的查询模式怎么优化。别走开好戏刚开始。

相关新闻

Windows文件加密与隐私保护实用指南

Windows文件加密与隐私保护实用指南

1. 为什么普通用户更需要文件加密刚入行做技术支持那会儿,我经常遇到这样的求助:"同事总借我电脑查资料,但有些合同和私人照片不想被看到怎么办?"、"离职交接时发现前任在电脑里留了私人账号密码"。普通用户的…

2026/10/18 10:00:19 阅读更多 →
2026年手机锁屏密码遗忘解决方案大全

2026年手机锁屏密码遗忘解决方案大全

1. 锁屏密码遗忘的常见场景与基础认知 上周帮同事处理了一台锁死的iPhone 13,机主因为连续输错密码导致设备停用。这种场景在维修店每周至少遇到5-6例,安卓用户的情况更复杂——不同品牌有完全不同的解锁机制。2026年主流机型的安全策略又有新变化&#…

2026/10/18 10:49:23 阅读更多 →
NeteaseCloudMusicGtk4:Linux平台终极网易云音乐播放器完整指南

NeteaseCloudMusicGtk4:Linux平台终极网易云音乐播放器完整指南

NeteaseCloudMusicGtk4:Linux平台终极网易云音乐播放器完整指南 【免费下载链接】netease-cloud-music-gtk Linux 平台下基于 Rust GTK 开发的网易云音乐播放器 项目地址: https://gitcode.com/gh_mirrors/ne/netease-cloud-music-gtk 作为一款专为Linux平台…

2026/10/18 10:49:08 阅读更多 →

最新新闻

STM32单片机 2引脚按键

STM32单片机 2引脚按键

按键:常见的输入设备,按下导通,松手断开按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动为防止按键按一下,单片机却反应多次的现象,因此要…

2026/10/19 1:12:12 阅读更多 →
MiniOB 完整导读:不到 10 万行代码,把 B+ 树索引、事务和 SQL 执行链路一次讲透

MiniOB 完整导读:不到 10 万行代码,把 B+ 树索引、事务和 SQL 执行链路一次讲透

MiniOB 完整导读:不到 10 万行代码,把 B 树索引、事务和 SQL 执行链路一次讲透 【免费下载链接】miniob MiniOB is a compact database that assists developers in understanding the fundamental workings of a database. 项目地址: https://gitcode…

2026/10/19 1:12:12 阅读更多 →
STM32单片机 RCC与GPIO

STM32单片机 RCC与GPIO

一,外设 (Peripherals)外设是指与主处理器(CPU)连接的硬件模块,这些模块提供了扩展功能,使得单片机可以与外部设备进行交互。常见的外设包括:GPIO(通用输入/输出):用于控…

2026/10/19 1:12:12 阅读更多 →
Stable-Audio-Tools 入门指南:条件音频生成模型的训练、推理与 Gradio 界面跑通

Stable-Audio-Tools 入门指南:条件音频生成模型的训练、推理与 Gradio 界面跑通

Stable-Audio-Tools 入门指南:条件音频生成模型的训练、推理与 Gradio 界面跑通 【免费下载链接】stable-audio-tools Generative models for conditional audio generation 项目地址: https://gitcode.com/GitHub_Trending/st/stable-audio-tools Stable-Au…

2026/10/19 1:12:12 阅读更多 →
3步上手Nemotron-3-Diarization:generate与generate_stream说话人分离调用实战教程

3步上手Nemotron-3-Diarization:generate与generate_stream说话人分离调用实战教程

【免费下载链接】Nemotron-3-Diarization 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/Nemotron-3-Diarization 点击查看 免费下载 Nemotron-3-Diarization 是一款基于 MLX 框架的说话人分离(Speaker Diarization)模型&…

2026/10/19 1:12:12 阅读更多 →
2022 年 12 月青少年软编等考 C 语言七级真题解析

2022 年 12 月青少年软编等考 C 语言七级真题解析

目录 T1. 走迷宫 思路分析 T2. 重建二叉树 思路分析 T3. 快速堆猪 思路分析 T4. 表达式 表达式树 表达式求值 思路分析 T1. 走迷宫 题目链接:SOJ D1233 一个迷宫由 R R R 行 C C C 列格子组成,有的格子里有障碍物,不能走;有的格子是空地,可以走。给定一个迷宫,求从…

2026/10/19 1:11:12 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →