Spring Boot + Spring AI 接入 DeepSeek:流式输出与前后端联调实战
简介面向Java后端与AI应用开发者的Spring Boot Spring AI集成实战代码包基于DeepSeek大模型完整实现智能问答、文本生成与语义分析等典型AI场景为快速搭建企业级智能应用提供可直接参考的工程范例。资源共12个文件以9个Java源文件承担核心业务逻辑配合YAML配置、XML配置和HTML页面完成环境配置与前端展示压缩包仅25KB结构轻量、便于快速阅读。代码采用前后端分离与模块化设计各模块职责明确完整展示模型接入、参数配置、服务调用与结果展示的链路前端负责用户交互与结果呈现后端处理业务逻辑与数据交互开发者不仅能直观理解AI能力如何无缝嵌入Spring Boot工程还能学习如何利用自动配置和起步依赖等特性快速构建智能问答与文本生成服务掌握从自然语言理解到结果输出的实际落地方法。已有254人学习适合有一定Java基础、希望掌握DeepSeek集成方法的开发者既可当作入门实战模板也可在此基础上扩展更多AI功能是企业级AI应用开发的一个良好起点。1. 这个项目到底在做什么别把 Demo 当实战把 Spring Boot 和 Spring AI 接上 DeepSeek前后端都写完很多人第一步就卡在“官方给的例子跑通了但一接前端全乱套”。最典型的情况是后端自己在 Swagger 里测试没问题前端一调用就白屏、超时、或者只拿到半个字。这个项目标题真正要解决的是“Spring Boot 与 Spring AI 基于 DeepSeek 的完整代码链路”核心是把 AI 能力封装成可靠的 REST 接口再把前端流式渲染串起来最后让系统能扛住真实用户使用而不只是演示。适合谁已经在用 Java 做后端、想把 DeepSeek 接进业务系统的开发者以及被“Demo 没问题、生产翻车”折磨过的前后端合作团队。这篇我不讲 PPT 架构只讲怎么一步步搭、参数怎么调、哪些地方你会摔跤。2. Spring Boot Spring AI 项目骨架最小工程与 DeepSeek 接入2.1 为什么选 Spring AI 而不是手动封装 OpenAI 客户端常见做法是在 Spring Boot 项目里引入 Spring AI 的spring-ai-starter-model-openai然后把 base-url 指向 DeepSeek 的兼容接口。有人会问DeepSeek 本身提供 OpenAI 兼容接口为什么不直接用 HttpClient 调我一般会选 Spring AI理由是它能省掉三类重复劳动统一 ChatClient 的调用抽象、对话历史的会话管理以及 JSON Schema 结构化输出的生成逻辑。自己手写的话第一版能跑第二版就要开始处理重试、超时、流式解析这些 Spring AI 已经帮你兜底了。我用 Spring Boot 3.2 JDK 17 起步。Spring AI 对 JDK 版本有下限要求JDK 8 直接编不过这不是玄学是 Spring Framework 6 的基线就是 17。你如果是老项目升不上来就别硬折腾 Spring AI去用原生 OpenAI SDK 反而清爽。parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.2.5/version relativePath/ /parent dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId version1.0.0-M5/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependencySpring AI 的版本迭代跨度很大M 版本和正式版之间的包路径和类名变化不少。你搜到旧博客里写OpenAiChatClient的在新版里多半已经废弃统一走ChatClient接口了。所以我不建议在生产项目上追最新 M 版选一个已经发布过几个月的版本踩坑记录多你能搜到解决方案。spring.ai.openai.base-urlhttps://api.deepseek.com/v1 spring.ai.openai.api-key${DEEPSEEK_API_KEY} spring.ai.openai.chat.options.modeldeepseek-chat spring.ai.openai.chat.options.temperature0.7 spring.ai.openai.chat.options.max-tokens20482.2 跑通最小调用ChatClient 直连 DeepSeek配置写完验证链路的动作要小。我习惯先写一个CommandLineRunner启动时直接调一次模型输出到控制台这样能确认密钥、网络、模型名三个变量同时没问题再往 Controller 层走。接口代码就一个核心方法SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }Component public class DeepSeekSmokeTest implements CommandLineRunner { private final ChatClient chatClient; public DeepSeekSmokeTest(ChatClient.Builder builder) { this.chatClient builder.build(); } Override public void run(String... args) { String response chatClient.prompt(用一句话介绍你自己) .call() .content(); System.out.println( DeepSeek response ); System.out.println(response); } }这段代码的逻辑很简单注入ChatClient.Builder构建出带默认配置的ChatClient然后发起一次 prompt 调用。重点是.call()和.content()的搭配call()是同步阻塞调用适合用来做冒烟测试等到接前端流式输出时你要换用.stream()方法。参数说明方面模型名deepseek-chat是 DeepSeek 的主对话模型如果你买的是推理增强型模型这里要换上对应的推理模型名。temperature建议在 0.7 附近起步太高回答发散、太低容易变成复读机。启动时如果看到 404 或者 401 报错九成是base-url或者api-key的问题。我第一次接入时把 api-key 直接写在配置文件里提交了后来换成了${DEEPSEEK_API_KEY}环境变量占位避免密钥泄给协作同事。这里有一个关键的选型考量ChatClient.Builder每次构建出来的实例是线程安全的可以全局复用。不要在接口里每次都new一个 ChatClient那会反复加载配置浪费连接资源。3. 从最小 Demo 到可复用业务接口把 DeepSeek 能力封装给前端3.1 普通问答接口从 shell 测试到 Controller冒烟测试通过后下一步是把模型调用暴露成 HTTP 接口。我先写一个最简单的 POST 接口接收用户问题返回完整回答。这里不要急着做流式先把同步链路跑通让前端能拿到一个完整的 JSON后面再优化体验。RestController RequestMapping(/api/chat) public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder builder) { this.chatClient builder.build(); } PostMapping(/sync) public ResponseEntityChatResponse syncChat(RequestBody ChatRequest request) { String content chatClient.prompt(request.message()) .call() .content(); return ResponseEntity.ok(new ChatResponse(content)); } }在这个接口里ChatRequest和ChatResponse是两条记录类前者只带一个message字段后者只带一个content字段。这样的设计意图很明确把 Spring AI 的模型返回结构隔离在业务层之外前端只拿到一个干净的字符串不暴露 Token 用量、模型名这些内部细节。要注意.call()的默认行为是一次性返回完整回复。如果你的业务场景是内部测试工具、批量生成、离线处理同步接口完全够用。但凡是用户对着屏幕等回答的场景同步接口很容易被嫌慢——DeepSeek 生成 500 字可能需要 10 到 20 秒HTTP 连接很容易在这段时间被网关掐断。这就是为什么下一步必须做流式。3.2 流式输出接入SseEmitter 与前端逐字渲染我一般用 Spring MVC 自带的SseEmitter因为项目没有引入 WebFlux为了流式输出把整个 Web 栈换掉成本太高。SseEmitter 是 Servlet 容器原生支持的和spring-boot-starter-web配合得特别好不需要额外依赖。PostMapping(value /stream, produces text/event-stream;charsetutf-8) public SseEmitter streamChat(RequestBody ChatRequest request) { SseEmitter emitter new SseEmitter(60_000L); FluxChatResponse stream chatClient.prompt(request.message()) .stream() .chatResponse(); stream.subscribe( response - { String delta response.getResult().getOutput().getText(); if (delta ! null !delta.isEmpty()) { try { emitter.send(SseEmitter.event().data(delta)); } catch (IOException e) { emitter.completeWithError(e); } } }, error - { emitter.completeWithError(error); }, emitter::complete ); return emitter; }这段代码有三个要点。第一SseEmitter构造参数 60_000L 是超时时间单位毫秒意思是 60 秒内如果没有事件发送服务端会自动断开。DeepSeek 生成长文时可能中间停顿几秒这个值设短了容易断流。第二.stream().chatResponse()返回的是一个反应式流你不需要引入 WebFlux 依赖Spring AI 底层自己处理了响应式适配。第三subscribe里的三个回调分别对应数据块、错误、完成任何异常都要completeWithError否则前端会一直挂着等不到结束信号。这里容易踩坑的是getResult().getOutput().getText()这个取值链路有时候结果里还带metadata但那不是文本内容别直接toString()否则前端会收到一坨包含时间戳和 token 数量的 JSON。我第一次写顺手用了toString()前端渲染出一堆乱码后来改成上面这个链路才正常。3.3 多轮对话历史循环队列实现上下文记忆DeepSeek 的接口本身是无状态的只有把历史消息一起传过去它才能记住前文。Spring AI 提供了MessageHistory相关抽象但默认实现在多用户高并发下有点吃内存。我一般自己实现一个简单的队列方案每个会话保存最近 N 轮既控制 token 消耗又避免内存无限增长。Component public class SessionHistoryManager { private final MapString, DequeMessage sessions new ConcurrentHashMap(); private static final int MAX_HISTORY_ROUNDS 6; private static final int MAX_TOTAL_TOKENS 4000; public ListMessage getHistory(String sessionId) { DequeMessage deque sessions.computeIfAbsent( sessionId, k - new ArrayDeque() ); return new ArrayList(deque); } public void addExchange(String sessionId, String userText, String assistantText) { DequeMessage deque sessions.computeIfAbsent( sessionId, k - new ArrayDeque() ); deque.addLast(new UserMessage(userText)); deque.addLast(new AssistantMessage(assistantText)); while (deque.size() MAX_HISTORY_ROUNDS * 2) { deque.pollFirst(); } } }这个设计的关键在于Deque的容量控制。MAX_HISTORY_ROUNDS是保留的对话轮数每轮包含 user 和 assistant 两条消息所以判定条件是deque.size() MAX_HISTORY_ROUNDS * 2。MAX_HISTORY_ROUNDS设成 6是因为大多数业务场景下最近的 6 轮已经足够承载上下文再老的消息通常是对 API 的 token 浪费。这里还有一个额外收益因为历史消息里带着UserMessage和AssistantMessage类型Spring AI 在组装 prompt 时会自动识别角色你不需要手动拼接“用户说… 助手答…”这样的模板。前端请求的时候带上sessionId后端拿sessionId去队列取历史就能实现多轮对话。内存方案只适合单机部署和中小并发如果你是集群部署要把sessions换成 Redis按 sessionId 存取 JSON 序列化后的消息列表。4. 前端接入把 SSE 流式渲染成聊天体验4.1 fetch 流式读取 SSE 并用 React 增量渲染后端接口通了前端才是用户体验的最后一公里。我拿 React fetch 举例因为fetch天然支持 ReadableStream不需要额外装 SSE 库。关键思路是不要等整个响应结束才 setState而是每收到一块数据就追加到消息列表里。async function streamChat(message, sessionId, onDelta, onError, onDone) { const response await fetch(/api/chat/stream, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify({ message, sessionId }), }); if (!response.ok) { onError(new Error(HTTP ${response.status})); return; } const reader response.body.getReader(); const decoder new TextDecoder(utf-8); let buffer ; while (true) { const { done, value } await reader.read(); if (done) break; buffer decoder.decode(value, { stream: true }); const events buffer.split(\n\n); buffer events.pop(); for (const event of events) { if (event.startsWith(data:)) { const data event.replace(data:, ).trim(); if (data data ! [DONE]) { onDelta(data); } } } } onDone(); }这段前端代码的核心是buffer.split(\n\n)。SSE 协议规定每个事件以空行结束网络传输过程中一个 chunk 可能包含多个事件也可能一个事件被拆成两个 chunk所以必须做缓冲区拼接。buffer events.pop()保留最后一个不完整的数据段等下一次reader.read()再续上。这个细节是我前后端联调时反复踩的坑如果不做缓冲区消息最后几个字很容易被截断。4.2 流中断、超时与聊天界面的工程化收尾流式接口接入后有几个体验问题必须处理。第一是“停止生成”按钮用户不想等了要能中断请求需要借助AbortController把reader.cancel()调起来。第二是断线重连如果生成了半句话网络断了前端要提示“回答不完整点此重试”最简单粗暴的做法是在 onDone 里检查是否出现了完整结束标记。我在实际项目中把回答文本按“是否调用了 onDone”来区分完整和不完整。onDone永远会被执行但如果流是异常中断的onDone之前会先走onError。所以界面上的渲染逻辑是isError ? 生成中断 : 生成完成。前端展示层另一个关键就是 Markdown 渲染。DeepSeek 返回的内容默认带 Markdown 语法比如代码块和加粗界面上得用react-markdown渲染。但要注意流式渲染时 Markdown 经常是半截的比如代码块的三个反引号还没收尾直接渲染会把整段内容包在代码块样式里。我一般会等一次流的三个反引号都到齐再渲染或者干脆把代码块部分的样式放宽容忍渲染时的临时错乱。5. Spring AI 接 DeepSeek 避坑现象、原因、解决5.1 现象接口报 404 或者找不到模型第一次配 Spring AI 接 DeepSeek启动后调用直接 404日志里写着类似model not found的报错。原因很直接某个版本的 Spring AI 对 OpenAI 的模型名有内置校验传了配置默认的gpt-3.5-turbo没有真正把application.properties里的spring.ai.openai.chat.options.model读透。解决方式是检查两个地方一是配置项有没有写成spring.ai.openai.chat.model旧版写法二是确认 DeepSeek 的base-url以/v1结尾。如果版本升级过注意配置路径可能已经变成了spring.ai.openai.chat.options.model。5.2 现象本地一切正常部署到某 Linux 机器上连接超时现象是同一个 jar本地调用 DeepSeek 正常放到某台云服务器上就报连接超时。我排查了防火墙、安全组都没有问题最后发现是服务器上的 JVM 读到了系统环境变量里的HTTPS_PROXYSpring AI 的 HttpClient 默认会走这个变量指定的地址导致流量被引导到了一个不通的出口。解决方式是启动命令里显式清掉这两个变量export HTTPS_PROXY或者在 JVM 参数里加-Dhttps.proxyHost强制置空。这个问题特别隐蔽因为本地开发机的环境变量和服务器不一致很容易让人怀疑是网络配置问题其实只是 JVM 读取了不该读的系统变量。5.3 现象JSON 结构化输出报 400 格式错误调用.entity(SomeClass.class)想拿到结构化 JSON结果接口返回 400日志提示 schema 格式不兼容。原因在于 Spring AI 生成的 JSON Schema 是 draft-07 格式DeepSeek 兼容层对$schema字段版本有校验要求两者不一致会直接拒绝。解决方法是升级 Spring AI 到较晚的版本或者手动调整生成的 schema把$schema字段改成 DeepSeek 兼容的版本号。这个坑在 JDK 17 较老版本组合下最容易触发我当时升级 spring-ai-starter-model-openai 后问题消失所以建议遇到 400 先查版本再改代码。5.4 现象前端界面一次性出字不是流式后端SseEmitter正常但前端等很久才一次性拿到全部内容。原因通常是网关或者代理缓冲了响应X-Accel-Buffering之类的头没关。解决方式是在 controller 方法上显式设置响应头X-Accel-Buffering: no并且确认produces text/event-stream写对了。Nginx 默认会缓冲后端响应等到整个响应结束才发给前端流式接口必须关掉缓冲。这个不关的话你后端写再多流式代码用户看到的还是“转圈然后整段蹦出来”。5.5 现象多轮对话聊着聊着上下文就丢了前端每次请求都带上了sessionId第一轮能记住第五轮再问“我刚才说了什么”它就不知道了。原因八成是SessionHistoryManager的MAX_HISTORY_ROUNDS设太小或者消息类型混用了。注意一个问题UserMessage和AssistantMessage要交替存放不能两条 user 连续否则模型会搞混角色。我出现过一次连续 push 了两条UserMessage结果回答时模型把自己当成了用户语气全乱。6. 进阶技巧把单轮 DeepSeek 能力变成可维护的 AI 服务这章的三个技巧是我在真实项目里被逼出来的价值比重写十个接口都大。第一个技巧是设计一个统一的“AI 调用日志”切面。每个请求记录 sessionId、消息长度、耗时、token 用量打到日志文件里。没有这套切面前端反馈“回答不对”的时候你根本不知道模型当时收到了什么历史记录。有了日志排查问题从“猜”变成“看数据”。第二个技巧是给超时分级。流式接口的超时不能只设一个SseEmitter的 60 秒就完事底层 HttpURLConnection 的 readTimeout 也要设。我一般设连接超时 10 秒、读取超时 120 秒两者独立。连接慢和生成慢是两种完全不同的问题混在一起时会互相干扰判断。第三个技巧是成本与一致性之间的平衡。DeepSeek 的上下文越长单次调用成本越高但把MAX_HISTORY_ROUNDS调小又会影响回答质量。我总结的经验是把“系统提示词”单独拎出来每次请求都带对话历史只带最近 4 轮如果是一场长对话的开头额外保留第一轮用户原始输入。这个策略在成本和效果之间取得了一个很好的折中。最后我养成了一个习惯每次下午四点后自己攒一个新版本的 bad case 集合专门测试模型回答的稳定性。AI 模型的输出天然有随机性同一句 prompt 每次回答可能不同——优化 prompt 或调整参数后一定要跑一轮冒烟测试再发版用同一批问题对比新旧答案看有没有恶化。你一定要把参数调节当成代码变更一样对待配一个测试集来回归。某个下午我调了个 temperature没做对比测试就上线了结果夜间用户反馈回答变得“又臭又长”回滚配置后才恢复。后来每次改参数都留一份截图记录 prompt、temperature、max-tokens 三个关键变量再比对实际输出就再也没翻过车。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

SpringBoot+Vue社区医疗系统:全栈开发实战解析

SpringBoot+Vue社区医疗系统:全栈开发实战解析

1. 项目概述与技术选型思路1.1 这套社区医疗系统到底解决什么问题先聊聊这套系统的定位。社区医疗服务管理系统,说白了就是给社区卫生服务中心、小型诊所、社区健康服务站这类机构用的信息化工具。这类机构和大医院不一样,科室少、人员精简、经费有限&am…

2026/10/14 4:21:50 阅读更多 →
PyTorch实战CIFAR-10:从VGG到ResNet的完整训练与调优指南

PyTorch实战CIFAR-10:从VGG到ResNet的完整训练与调优指南

1. 项目缘起与整体设计思路CIFAR-10 这个数据集在图像分类领域里的地位,大概相当于编程入门时的 "Hello World"。它包含 10 个类别、共 60000 张 3232 的彩色小图,训练集 50000 张、测试集 10000 张,类别覆盖飞机、汽车、鸟、猫、鹿…

2026/10/14 4:21:50 阅读更多 →
在ESP32上构建应用商店:模块化固件架构与动态加载实践

在ESP32上构建应用商店:模块化固件架构与动态加载实践

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

2026/10/14 4:20:50 阅读更多 →

最新新闻

AI编程教程为何爆火2万Star:从零基础到生产落地的完整路径

AI编程教程为何爆火2万Star:从零基础到生产落地的完整路径

1. 这个“2万Star”到底意味着什么:从GitHub数字看AI编程教程的真实分量很多人看到标题里“2万Star”第一反应是:哇,火了。但作为在开发者教育领域摸爬滚打十多年的老手,我得先泼一盆冷静的水——Star数从来不是教学内容质量的直接…

2026/10/14 7:19:37 阅读更多 →
DNN多分类任务核心设计:Softmax、交叉熵与PyTorch实战

DNN多分类任务核心设计:Softmax、交叉熵与PyTorch实战

2. 多分类任务的三个核心设计问题先说结论:DNN跑多分类,真正需要想清楚的只有三件事——输出层的神经元数量、输出层的激活函数、损失函数的选择。这三件事定下来,模型框架基本就定死了,后面做的都是调参和优化。2.1 输出层神经元…

2026/10/14 7:19:37 阅读更多 →
离线环境部署MySQL 5.7:tar.gz包安装与避坑指南

离线环境部署MySQL 5.7:tar.gz包安装与避坑指南

简介:本资源为 MySQL 5.7.40 在 Linux-glibc2.12 环境下的 x86_64 离线安装包,面向需要在无外网或内网环境中部署关系型数据库的运维与后端开发人员。压缩包共 379 个文件,约 646.59MB,以 h 头文件、so 动态库、xml 配置、sql 脚本…

2026/10/14 7:19:37 阅读更多 →
华为HCIP-AI测试卷高效复习指南:从背答案到动手验证

华为HCIP-AI测试卷高效复习指南:从背答案到动手验证

简介:这份华为认证HCIP-AI测试卷与答案文档,面向备考华为人工智能高级认证的考生及希望系统检验AI基础知识的开发者,帮助梳理图像处理、语音合成、HiAI生态与快应用开发等核心考点。资源包共1个docx文件,约14KB,内容以…

2026/10/14 7:19:37 阅读更多 →
基于rSVD与软阈值的Matlab高效信号去噪方法

基于rSVD与软阈值的Matlab高效信号去噪方法

1. 项目背景与核心挑战谐波噪声是信号处理领域常见的干扰类型,广泛存在于电力系统监测、机械振动分析、生物医学信号采集等场景。传统去噪方法如傅里叶滤波、小波变换在面对高维大数据集时往往面临计算效率低下、噪声鲁棒性不足的问题。这个Matlab项目提出了一种融合…

2026/10/14 7:19:37 阅读更多 →
智慧农业最后一百米:破解乡村数字化落地的设备与运维难题

智慧农业最后一百米:破解乡村数字化落地的设备与运维难题

做了快八年农业数字化项目,我最深的一个体会是:智慧农业真正难的从来不是算法有多高级、传感器有多精密,而是怎么让技术在没有网线、没有专职IT人员、甚至不少农户只用老年机的村子里,持续稳定地转起来。前段时间复盘了一个扎根基…

2026/10/14 7:18:36 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →