news 2026/10/4 2:18:02

Spring AI + RAG + Tool Calling:岗位JD分析系统实战全记录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AI + RAG + Tool Calling:岗位JD分析系统实战全记录

我自己这半年最深的体会是:岗位 JD 分析这种需求,表面上是"让 AI 读文档",实际上做起来是典型的RAG + Tool Calling组合工程。JD 是内部知识,涉及薪酬数据要查系统,涉及匹配度要算分,光靠一个大模型硬答,既看不见知识库也拿不到准确数据。最后我用Spring AI把它落成了 Java 服务,跑了三个月,今天把完整流程和踩的坑一次性写出来。

这套系统解决的是招聘业务里最重复的一个环节:HR 每天要面对几十份岗位 JD,人工拆解技能要求、薪资范围、面试重点,还要拿 JD 和候选人简历做匹配。我做的系统输入是 JD 文档或链接,输出是一份结构化的岗位分析报告。其中 RAG 负责从内部知识库里检索岗位胜任力、面试题库、历史评估记录,Tool Calling 负责调薪酬查询接口和技能匹配计算接口。适合正在做 Java 后端、想把手头业务接入 LLM 的同学参考,也适合被 LangChain4j、Dify、本地 Ollama 方案绕晕了的人拿来对照。

1. 先想清楚:这个岗位分析系统到底要干什么

1.1 岗位分析的输入输出到底是什么

很多人在写这类系统前容易犯一个错,上来就搭 RAG、调模型,结果做出来的东西只是"能回答问题",业务根本没法用。我先说清楚我这边实际处理的输入输出:

输入

  • 岗位 JD:文本文件、PDF、docx,偶尔是网页链接
  • 历史面试评估记录:内部文档,散落在知识库里
  • 岗位胜任力模型:HR 团队维护的标准化技能清单
  • 薪酬数据表:各个城市、职级的薪资区间,存在业务系统数据库里

输出

  • 岗位核心技能提取,以及技能等级判断
  • JD 与薪酬区间的关联分析
  • 若传入候选人简历,输出技能匹配度、缺口清单、建议面试问题

拆下来就发现,这里有两个技术问题绕不开:第一,内部 JD 和评估记录模型没见过,不检索就是胡编;第二,薪酬和匹配度属于确定性数据,不能让模型自己"估计"。于是系统天然被拆成两条主线,RAG 解决"知识从哪来",Tool Calling 解决"数据从哪算"。

1.2 为什么选 Spring AI,而不是 LangChain4j 或 Dify

选型那会儿我把主流方案都过了一遍。我们团队全是 Java,Spring Boot 3.x 已经是基础,这时候有四个候选:

方案适合场景我的判断
Spring AIJava/Spring 生态的 AI 应用框架与现有工程无缝集成,事务、配置、监控都能复用
LangChain4jJava 生态的 LangChain 移植也不错,但和 Spring 搭配需要额外适配,社区和迭代速度不如 Spring AI
Dify低代码可视化工作流适合快速原型和运营配置,但要嵌到 Java 业务系统里,反而要把工作流翻译成代码
自写 HTTP 调用只有一个纯调用需求不做 RAG 和工具编排还行,稍微复杂就失控

Dify 我后来也用来做过原型验证,确实快,但问题在于:原型里的知识检索节点、LLM 节点、工具节点,最终都要翻译回 Java 代码。热词里有人说"dify 工作流转成 spring ai java 代码",这就是实际遇到的需求。我给一张对应的映射表:

Dify 节点Spring AI 对应物
知识检索节点QuestionAnswerAdvisor + VectorStore
LLM 节点ChatClient + System Prompt
HTTP/代码工具节点@Tool 注解方法 + WebClient/RestTemplate
变量聚合、条件分支Service 层普通 Java 业务逻辑
会话记忆ChatMemory + VectorStoreChatMemoryAdvisor

翻译过一次你就明白,Dify 的价值在编排可视化,但闭环到生产系统里,用 Spring AI 直接写反而更透明,出问题也好排查。

另外还有一个热词是"spring ai alibaba 停更了吗"。这里要说清楚,阿里那边有一个 Spring AI Alibaba 项目,主要做 DashScope 等的增强集成;但如果你用的是 Spring 官方主线里的spring-ai-starter-model-dashscope,它一直随 Spring AI 主版本在更新,并没有停。我选的就是官方主线的 DashScope 接入,稳。

2. RAG 环节:从文档拆解到检索调优,我踩过的每颗钉子

2.1 岗位知识库的文本加载与拆分

RAG 的第一步是“让系统能看懂企业内部文档”。我用的是 Spring AI 的TikaDocumentReader,它可以处理 PDF、docx、xlsx、HTML 这类常见格式,内部走 Apache Tika 做类型识别和文本提取。这一步很简单,真正需要花心思的是文本拆分。

JD 文档有个特点:大量使用分点、加粗、表格,比如“任职要求:1. Java 基础扎实;2. 熟悉 Spring Cloud;3. 有高并发经验”。如果简单按固定字符长度切,很容易把一条完整要求拦腰切断,检索的时候就会召回残缺片段,最后的答案自然不准。

我用的是TokenTextSplitter,关键参数是 chunkSizeTokens 和 chunkOverlapTokens。参考配置如下:

TokenTextSplitter splitter = new TokenTextSplitter(1200, 150, 5, 10000, true);

这里的含义是:每个 chunk 约 1200 个 token,前后重叠 150 个 token,最少保留 5 个 token,最多切 10000 个 chunk。为什么必须要有重叠?因为一条技能要求可能恰好落在切割点上,重叠可以保证它至少在相邻的两个 chunk 里出现完整版本,这样召回时不会被切碎。

实际操作中我试过 800、1200、1500 三档,1200 是我们 JD 语料上效果最稳的。chunk 太大,一个 chunk 里塞了太多不相关内容,embedding 向量会被稀释;chunk 太小,单个 chunk 语义不完整。这个粒度一定要拿自己的文档试,别照抄别人的参数。热词里有"有没有本地的 rag 文本拆解工具"——其实 Tika 加各类 splitter 就是最直接的本地拆解工具链,不需要单独再找额外程序。

还有一个容易忽略的点:TextContentTransformer。从 docx 或 HTML 里提取的文本经常带大量格式符号、空行、页眉页脚,先过一遍文本清洗,能明显减少脏数据进入向量库。成本低收益大,建议每次都加。

2.2 Embedding 与向量库选型

文本拆好之后,要转成向量。Embedding 模型这边有两个选择:接百炼(DashScope)的text-embedding-v3,或者本地 Ollama 跑bge-m3。生产和实验我都跑过:

  • 百炼:效果稳定,中文理解好,按量计费,适合生产。
  • 本地bge-m3:零成本、无需外网,但受机器性能限制,检索质量略低,适合开发环境和离线场景。

向量库我最终选了PgVectorStore。原因很朴素:公司本来就有 PostgreSQL,直接建一个vector扩展,用 HNSW 索引,配置里面加上余弦距离就行,不需要再单独维护一套 Milvus 或 Redis。你如果只是本地验证,Spring AI 自带的SimpleVectorStore内存版也够用,但换生产环境必须上持久化存储。

配置参考:

spring: datasource: url: jdbc:postgresql://localhost:5432/ragdb username: postgres password: postgres ai: vectorstore: pgvector: initialize-schema: true index-type: HNSW distance-type: COSINE_DISTANCE

这里要说一个我踩过的坑:向量库的相似度检索默认基于"语义相似",但它不认识你的业务元数据。比如你按岗位类别存了一批 JD 文档,检索"Java 高级工程师"时,可能召回一批"高级测试工程师"里恰好语义接近的片段。解决办法是给每个 Document 加 metadata,并按 metadata 做过滤。入库时我给文档打了category、positionLevel这类标签,检索搜索请求里带上过滤条件,噪音一下就少了。

2.3 检索质量和 hit rate 的优化

热词里 "rag hit rate" 是很多人的痛点。hit rate 指的是:在 100 个测试问题上,有多少比例的“正确上下文”真的被检索回来了。这是 RAG 效果的核心指标,比看答案顺不顺眼重要得多。我自己的优化顺序是:

第一,调 topK。默认一般是 4,我建议至少试到 8。topK 小,召回不够,模型只能根据残缺上下文补答案,补着补着就开始编了。我们内部抽了 50 条问题做人工标注,topK 从 4 调到 6 后,hit rate 体感从六成多涨到八成多,但到了 8 以上,答案里开始混入不相关段落。所以 topK 并不是越大越好。

第二,加相似度阈值。Spring AI 的QuestionAnswerAdvisor支持配置 similarityThreshold,低于阈值的文档不进上下文。这个阈值要结合你的 embedding 模型来看,text-embedding-v3我设 0.6 左右效果适中,本地bge-m3会高一截。建议先跑一批测试问题,把召回分数打出来,看分布再定。

第三,考虑混合检索和重排。纯向量检索有一个经典短板:语义相似但关键词完全不同的长尾内容召回差。比如简历里写"用过 Spring Boot、读过 Spring 源码",JD 里写"Java 框架深度",vec 模型能关联上;但遇到"Framework"和"框架"完全中英文混杂的语料,效果就会打折。我们目前线上先靠向量加 metadata 过滤撑住,下一步计划引入 BM25 关键词召回再合并重排。如果你公司有 ES,可以直接上 ES 的 hybrid 查询,成本比再搭一套重排服务低。

这里必须说一句大实话:RAG 的效果提升,大部分来自数据治理和参数调优,而不是换个更贵的模型。我见过很多人反复换 LLM,真正病根是知识库文本杂乱、拆分粒度不对、metadata 没打全。

3. Tool Calling 环节:让模型会查数、会算分、会调用系统

3.1 何时需要 Tool Calling,何时不需要

先泼一盆冷水:不是所有功能都要上 Tool Calling。纯文本总结、观点分析、分类归纳,直接用 ChatClient 就好。需要 Tool Calling 的场景有三个特征:结果要确定、数据在系统里、逻辑要算。

岗位分析系统里的典型例子:

  • 薪酬区间:必须从薪酬表里面查,不能靠模型猜
  • 技能匹配度:要算了才知道匹配率是多少,模型是算不清集合交集的
  • 候选人状态查询:需要调 HR 系统接口,拿到实时数据

如果这类操作也让模型自由发挥,准确率会非常难看,而且不可复现。Tool Calling 的本质,是把"模型知道了要查什么"和"系统真的查到了数据"这两件事接起来。

3.2 用 @Tool 实现岗位技能比对和薪资查询

Spring AI 从 1.0 开始提供了@Tool注解,2.0 里这套机制更成熟。你只要在一个 Spring Bean 的方法上加上@Tool,并且给它写清楚description,模型发起函数调用时就会自动找到它。

我写了两个最典型的工具,一个是查薪酬,一个是算技能匹配:

@Component public class JobAnalysisTools { private final SalaryRepository salaryRepository; public JobAnalysisTools(SalaryRepository salaryRepository) { this.salaryRepository = salaryRepository; } @Tool(description = "查询指定岗位名称、城市、职级的月薪区间,返回JSON字符串") public String querySalaryBand(String position, String city, String level) { SalaryBand band = salaryRepository.findByPositionAndCityAndLevel(position, city, level); if (band == null) { return "{\"found\": false}"; } return String.format( "{\"found\": true, \"min\": %d, \"max\": %d, \"median\": %d}", band.min(), band.max(), band.median()); } @Tool(description = "计算候选人技能与岗位JD技能列表的匹配度,返回JSON字符串,包含matched、missing和rate字段") public String matchSkills(List<String> candidateSkills, List<String> jdSkills) { Set<String> jdSet = new HashSet<>( jdSkills.stream().map(String::toLowerCase).toList()); List<String> matched = candidateSkills.stream() .map(String::toLowerCase) .filter(jdSet::contains) .toList(); List<String> missing = jdSkills.stream() .map(String::toLowerCase) .filter(s -> !matched.contains(s)) .toList(); double rate = jdSkills.isEmpty() ? 0.0 : (double) matched.size() / jdSkills.size(); return String.format( "{\"matched\": %s, \"missing\": %s, \"rate\": %.2f}", matched, missing, rate); } }

matchSkills里面的逻辑很简单,把两边技能都转成小写再求交集。真正的关键点是:这些工具如果返回结构化 JSON,模型就能精准地把它们填到答案里,不会自己发挥。另外,工具描述一定要写清楚"输入是什么、输出格式是什么、什么情况下返回 found:false",模型会根据 description 决定调用哪个工具,描述含糊它就用错。

3.3 RAG 与 Tool Calling 的协作流程

这两者不是二选一,而是配合的。一次典型的"面试官视角岗位分析"调用流程是这样的:

  1. 用户提交 JD 文本,问:"分析这份 JD,对比候选人张三的技能匹配度,并给出薪资建议。"
  2. 系统先做检索:QuestionAnswerAdvisor把问题做 embedding,从向量库召回 JD 相关段落、胜任力模型文档,拼进 prompt。
  3. 模型读完检索上下文,提取 JD 技能清单;发现需要匹配度和薪酬,就发起 Tool Calling,依次调用matchSkills、querySalaryBand。
  4. 工具结果以 JSON 形式回填给模型。
  5. 模型汇总输出:匹配率、缺口技能、薪资区间、面试重点。

如果没有 RAG,模型不知道"张三是谁""JD 内部版本在哪";如果没有 Tool Calling,模型会给你编一个薪酬区间和匹配率。两个加起来,才是一个业务能用的系统。

4. 代码落地:Spring AI 2.x 从配置到跑通全流程

4.1 项目初始化和依赖配置

我用的是 Spring AI 2.0.1,配套 Spring Boot 3.x。这里直接给可复制的依赖:

<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-model-dashscope</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-vector-store-pgvector</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-tika-document-reader</artifactId> <version>2.0.1</version> </dependency>

如果你用的不是 2.0.1,注意去查对应版本的 BOM,Spring AI 的模块版本经常一起迭代。接着配置百炼模型连接,也就是热词里说的"spring ai 2.0 连接百炼 qwen3.7"这类的需求:

spring: ai: dashscope: api-key: ${DASHSCOPE_API_KEY} chat: options: model: qwen-plus embedding: options: model: text-embedding-v3

百炼平台申请 API Key 之后放在环境变量DASHSCOPE_API_KEY,不要把密钥直接写进 yaml 提交到仓库。模型 ID 这块注意:qwen-plus、qwen-max 是长期稳定 ID,新的 qwen3 系列模型在不同地区的控制台里标识可能不一样,热词里的"qwen3.7"如果在你控制台搜不到,就按实际可选的模型 ID 来填,配置结构是一样的。

4.2 知识库入库脚本与 RAG 查询链路

入库这一步我封装成一个独立的 Service,这样 HR 上传一份新 JD 或评估文档时,直接调用这个方法就能增量入库:

@Service public class KnowledgeIngestService { private final VectorStore vectorStore; public KnowledgeIngestService(VectorStore vectorStore) { this.vectorStore = vectorStore; } public void ingest(Path filePath, String category) { TikaDocumentReader reader = new TikaDocumentReader(new FileSystemResource(filePath.toFile())); List<Document> docs = reader.get(); TextContentTransformer cleaner = new TextContentTransformer(); docs = cleaner.apply(docs); TokenTextSplitter splitter = new TokenTextSplitter(1200, 150, 5, 10000, true); List<Document> splitDocs = splitter.apply(docs); splitDocs.forEach(doc -> doc.getMetadata().put("category", category)); vectorStore.add(splitDocs); } }

入库之后就是查询链路。Spring AI 的便捷之处在于,ChatClient可以带着 advisor 一起构建,QuestionAnswerAdvisor内部自动完成"问题转向量、检索相似片段、把片段注入 prompt"这三步:

QuestionAnswerAdvisor advisor = QuestionAnswerAdvisor.builder(chatModel, vectorStore) .similarityThreshold(0.6) .topK(6) .build(); this.chatClient = ChatClient.builder(chatModel) .defaultSystem("你是岗位分析助手。基于知识库内容回答;涉及薪资和技能匹配时,必须调用工具获取准确数据,不要自行估计。") .defaultAdvisors(advisor) .defaultTools(tools) .build();

注意:QuestionAnswerAdvisor的构建需要传chatModel,因为它要借用 ChatModel 的能力把问题本身转成向量做检索。这样写完之后,一个最简单的分析接口就出来了:

@PostMapping("/analyze") public String analyze(@RequestBody AnalyzeRequest request) { return chatClient.prompt() .user(u -> u.text("请分析以下岗位JD:\n{jd}").param("jd", request.jd())) .call() .content(); }

4.3 Tool Calling 的注册与调用细节

Tool 类的注入在上面的ChatClient里通过defaultTools(tools)完成,其中tools是上一步写的JobAnalysisToolsBean。Spring AI 会自动扫描其中的@Tool方法,把方法签名、参数、描述注册给模型。

这里我踩过一个很具体的坑:Spring AI 对 Tool 入参的解析依赖 JSON Schema,如果你的工具方法参数是一个复杂自定义对象,模型可能不知道怎么构造,调用成功率会下降。最稳妥的方式是:参数尽量用基本类型或字符串,复杂数据让工具内部再去查库或解析。比如querySalaryBand(String position, String city, String level)三个字符串参数,模型收到得非常准;如果你定义了一个QueryRequest对象,模型反而容易漏填字段。

另外,如果同一个问题需要连续调用多个工具,模型是支持串行调用的。比如先matchSkills再querySalaryBand,Spring AI 会生成一次工具调用、拿到结果、再生成下一个调用。这种链路我们要在日志里记录每个 Tool 的入参和出参,排查问题就看这一串日志。

4.4 本地 Ollama 降级方案:零成本跑通全流程

开发环境或离线环境里,可以用 Ollama 把模型和 embedding 都跑在本地。热词里"ollama + 简易本地 RAG 知识库"就是这个链路:本地起模型,Spring AI 自动走 Ollama。

先装 Ollama,然后拉模型:

ollama pull qwen2.5:7b ollama pull bge-m3

接着改配置:

spring: ai: ollama: base-url: http://localhost:11434 chat: options: model: qwen2.5:7b embedding: options: model: bge-m3

依赖换成spring-ai-starter-model-ollama即可,代码里ChatModel、VectorStore的使用方式不变。我只提醒一点:本地 7B 模型跑 RAG + Tool Calling 是能跑通的,但速度和质量确实不如云端 qwen-plus,尤其 Tool Calling 的准确性差距明显。如果机器只有 16G 内存,先试 7B 量化版本,卡得厉害就换 qwen2.5:3b 做开发冒烟,生产还是走百炼更省心。

5. 踩坑实录:常见问题排查与速查表

5.1 RAG 知识库到底能不能存图片

这个热词问得非常多,我直接给结论:RAG 向量库本身存的是文本向量,不是图片二进制,但知识库完全可以“管理”图片,关键是设计好索引方式。

我实际用到的有三种做法:

  • 图片里的关键信息用 OCR 抽成文本,作为该图片的文本描述入库检索,图片本身存到 OSS 或本地路径。
  • 图片语义描述用视觉模型生成一句话标题,比如"系统架构图:网关->服务->数据库",把它存成 metadata。
  • 检索命中后,把图片地址放进上下文的引用字段,让前端展示。

我们内部的做法是第一种加第三种。也就是:入库时给图片生成描述文本并抽取文本,metadata 里带imageUrl;回答里如果引用了这份资料,会同时返回图片链接给 HR 查看。千万别试图把图片原样塞进向量库,那是多模态向量检索要干的事,和传统 RAG 不是一个赛道。

5.2 RAG 的瓶颈到底卡在哪

不少人觉得 RAG 的瓶颈是"模型不够聪明",实际上我跑下来的瓶颈基本都在检索侧:

第一,长尾信息召回难。岗位 JD 里经常出现缩写、中英混排、别名,比如"Java 并发编程""JUC""多线程调优"其实指同一个方向,向量能关联一部分,但不是全部。第二,多跳问题。"张三在 A 项目的表现能否支撑他应聘高级工程师"这种问题要跨两份文档推理,单轮 RAG 很难做到。第三,知识更新滞后。向量库不会自动感知文档修改,HR 改了一版 JD 之后,旧版本还在库里,检索可能返回过期内容。我目前用 metadata 里的version字段做过滤,文档更新时标记旧版本,这个问题基本解决。

热词里还有"rag 知识库能存储图片嘛"“有没有本地的文本拆解工具”这类问题,本质都是在找 RAG 的数据治理方案。我对 RAG 的定位就是一句:垃圾进,垃圾出。文本拆得越干净、metadata 打得越全,后面所有优化才有意义。

5.3 常见问题排查速查表

我把实际遇到的故障整理成了表格,方便你对照定位:

现象可能原因排查与解决办法
回答经常凭空捏造检索没召回相关内容先看 advisor 日志里召回了几条文档,调大 topK、降低 similarityThreshold
召回了很多但答案质量差chunk 切太碎或 overlap 不够调大 chunkSizeTokens,检查是否需要 TextContentTransformer 清洗
每次回答都在复读原文知识库重复文档太多入库前做文档去重,检查 vectore store 里同一文档是否被多次 add
模型死活不调用工具工具 description 不清楚,或参数太复杂改写描述,明确输入输出;参数尽量用字符串
工具调用报 JSON 解析错误模型构造参数格式不对给工具方法加 @Tool 的示例描述,返回格式统一用简单 JSON 字符串
百炼返回 401/403API Key 未正确配置检查环境变量是否传入,不要写死在代码里
Ollama 连接超时模型没拉取,或服务没启动ollama list确认模型,curl http://localhost:11434确认服务
SQL 查询 PG 时报 vector 类型不存在没装 pgvector 扩展执行CREATE EXTENSION IF NOT EXISTS vector;

5.4 几个容易被忽略的经营性细节

除了上面的故障,还有几个经验只写给自己团队的,一并分享:

  • 工具调用一定要有日志。每次 Tool 调用入参、出参都打出来,HR 质疑结果的时候,你能拿出当时模型调了什么参数、工具返回了什么数据,这是信任的基础。
  • 结构化输出优先。岗位分析报告我用固定的 JSON 模板让模型输出,方便前端渲染和后续入库审计。自由文本虽然好看,但没法做质量统计。
  • 给 ChatClient 配置超时和重试。百炼接口偶尔会慢,Tool 内部如果调业务系统也可能超时,Spring AI 的调用建议包一层重试策略,但注意 Tool 要设计成幂等,否则重试会导致业务重复动作。

最后再分享一个个人体会:这套系统从原型到上线,真正的难点从来不是"让模型回答出来",而是让数据链路稳定。JD 文档清洗规范、metadata 命名、工具返回格式,这些基础工作占了大约六成时间。把这部分做扎实,RAG 的命中率、Tool 的调用成功率都会跟着上来。岗位分析只是一个例子,同样的架构换到合同审查、工单分派、设备巡检报告,逻辑是完全一样的。你先拿自己的业务文档试一次,跑通之后再回来调整参数,会比照着任何模板抄都稳。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 2:15:32

SpringBoot古城景区管理系统毕设源码实战与答辩通关指南

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

作者头像 李华
网站建设 2026/10/4 2:10:10

Git Reset三兄弟详解:--soft、--mixed、--hard差异与实战

1. 先把 reset 这件事讲透&#xff1a;它到底在动哪三个区域凡是用 Git 超过一个礼拜的人&#xff0c;基本都绕不过git reset。但很多人对它的理解停留在“撤回提交”这四个字上&#xff0c;真正问起--hard、--soft、--mixed三者差别时&#xff0c;又说不出个所以然。我当年踩过…

作者头像 李华
网站建设 2026/10/4 2:08:39

Markdown进阶指南:从细节避坑到自动化工作流

昨天咱们把Markdown的标题、列表、加粗斜体这些基础语法过了一遍&#xff0c;今天第二天&#xff0c;我直接带你把那些最容易翻车的细节和真正能提升效率的工作流拉通。别小看这些东西——大部分人说“Markdown我早会了”&#xff0c;结果一提到换行规则、图片路径、代码插入就…

作者头像 李华
网站建设 2026/10/4 2:08:11

星火+DeepSeek双模型路由实战:AI学习机端云协同技术解析

先说一个很多人容易忽略的事实&#xff1a;AI 学习机这类产品&#xff0c;表面上拼的是屏幕尺寸、存储容量和摄像头像素&#xff0c;但实际上真正的技术壁垒&#xff0c;是“端侧硬件 云端大模型 教育知识库”三件事能不能被有机地整合在一起。本文就从开发者视角&#xff0c…

作者头像 李华
网站建设 2026/10/4 2:08:05

Claude免费共享账户与Claude Code安装配置避坑指南

最近总有人问我&#xff1a;Claude 免费共享账户到底能不能用&#xff1f;说实话&#xff0c;这个问题我接触过太多回了。作为一个从 Claude 第一代测试版就开始折腾的普通用户&#xff0c;我几乎每天都能在群里看到有人晒共享号截图、有人转发“免费白嫖 Claude”教程&#xf…

作者头像 李华
网站建设 2026/10/4 2:06:46

SpringBoot 整合 Elasticsearch 7.2.0 实战:索引构建与查询避坑指南

简介&#xff1a;面向SpringBoot开发者与需要将Elasticsearch升级到7.x的技术人员&#xff0c;这份PDF从版本兼容痛点切入&#xff0c;说明Spring Boot 2.1.x内置的spring-boot-starter-data-elasticsearch仍停留在ES 2.X&#xff0c;因此改用Spring-data-elasticsearch以适配7…

作者头像 李华