学习LangChain4J以及demo

基于LangChain4J+Postgresql和PgVector实现的基础对话流AI

主要目的在于学习LangChain4J和PgVector

3.27

完成基本的向量检索 支持文件上传,文件分开,向量化之后存储到知识库中

发现的问题: 文件太大,可能会导致向量化失败,可以考虑循环分批进行向量化

3.28

今天引入了MCP和SKILL,然后思考了一些问题

  • 这些MCP和SKILL应该是可以选择性使用的,之后如果要做成多用户,应该要根据用户来进行隔离,比如用户A没有下载SKILLA,那就不能使用。
  • 要集成一个下载功能,实现用户给个链接,就可以下载到用户的工作区,并且源文件要存储在一个地方,存储到表里,下次有人来下载同一个SKILL就可以直接复制,不需要引用了
  • 命令要怎么执行,怎么实现暂停?白名单,用什么来隔离?是目录还是会话?我记得目录好一点
  • 工作目录大概是这样子的:workplace/user/.. 目录下放着skill,mcp配置等信息,然后命令白名单建一张表来存储可能好一点
  • 还有就是要返回工具调用的过程,让AI的操作透明化
  • 返回历史记录这里可能还需要改进一下

3.29

今天把返回历史记录的问题搞定了,不过目前只支持文本,如果之后要图文并发那还要再处理一下 AI的那个接口

import dev.langchain4j.data.message.UserMessage;

TokenStream chat(@UserMessage UserMessage msg, @MemoryId Object memoryId);

JSON是这样子:

{
  "contents": [{
    "text": "UserMessage { name = null, contents = [TextContent { text =\"那帮我看看今天佛山天气怎么样\" }], attributes = {} }",
    "type": "TEXT"
  }],
  "type": "USER"
}

这样子写会出现嵌套的情况,会很难受,导致用户的消息变成这样子:

UserMessage { name = null, contents = [TextContent { text = "测试,你只需要回复SUCCESS" }], attributes = {} }

修改成字符串了,已老实,之后再考虑图文并发吧

3.30

今天把记忆的存储方式修改了一下,之前是全部删除全部插入,现在修改成只插入新增的聊天记录了。 添加了个工具,可以执行命令行,不过要是做成服务器的那种,这个工具肯定要砍掉的,不然肯定被狠狠的攻击了 引入了zt-exec,AI说他有以下优势,确实比原生的好用

    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-pgvector</artifactId>
        <version>1.12.1-beta21</version>
    </dependency>
  • 防止死锁:原生 ProcessBuilder 如果不手动开启线程去读 InputStream 和 ErrorStream,缓冲区满后进程会卡死。zt-exec 自动帮你处理了这些。
  • 流式 API:链式调用,非常直观。
  • 超时控制:原生 Java 做超时非常麻烦,它只需要 .timeout(10, TimeUnit.SECONDS)。
  • 输出获取:可以直接将结果返回为 String,也可以直接泵(Pump)到控制台或文件。

加入了命令行工具以及自动下载skill的工具,目前测试没啥问题。

3.31

处理了一下使用命令行的那个工具问题,以及去除最大消息,修改成token限制。 之后其实也可以考虑一下如果消息太多了,拿个模型去总结一下,问题在于总结之后,之后也是要去动态更新的啊,呃呃呃 那我是不是可以写个工具,加入用户码AI我刚刚不是说了吗,之类的话,AI就去调工具,更新一下总结就行了 大概的思路是这样子的 现在想写个dto,来过滤SKILL和MCP的使用,目前是加载了全部的MCP和SKILL,但是一般情况下,是需要用户选择的。 要实现这个,需要弄个东西来存储MCP和SKILL的消息,也就说需要知道有什么,才能选。 可以考虑使用表或JSON来存储这些数据

我选择使用表来存储这些

create table mcp_skill_information(
    id serial primary key,
    name varchar(255) not null ,
    is_mcp bool not null ,
    mcp_type varchar,
    source_path varchar(255) not null
);
comment on table mcp_skill_information is '存储MCP和SKILL的信息';
comment on column mcp_skill_information.is_mcp is '是否为mcp,如果不是则是skill';
comment on column mcp_skill_information.mcp_type is 'MCP的类型,HTTP或SSE';

搞定了,目前MCP只支持http协议的,sse不支持,本地的也不支持 目前测试没啥问题。

4.1

将RAG检索写成工具 具体实现:

    @Tool("检索知识库")
    public String ragSearch(@P("查询语句,提取关键词查询")String query){
        StringBuilder result=new StringBuilder();
        EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
                .query(query)
                .maxResults(3).minScore(0.7)
                .queryEmbedding(embeddingModel.embed(query).content())
                .build();
        log.info("查询:{}",request.query());
        List<EmbeddingMatch<TextSegment>> matches = pgVectorEmbeddingStore.search(request)
                .matches();
        if (matches==null||matches.isEmpty()){
            return "知识库中未查询到修改知识片段,你可以修改关键词再次尝试查询";
        }
        matches.forEach(t->{
            result.append(t.embedded().text());
        });
        return result.toString();
    }

向量化文件修改成异步 以及,我真服了啊,这里的实现,我感觉异味有点多,而且这里肯定出bug的,写的我也难受的要死,还好只是demo,我懒得修改了

//  TODO 这里的实现依托,fileId是可能重复的,算了算了,毕竟是只是学习demo
        list.forEach(f->{
            lambdaUpdate().eq(FileKnowledgeBase::getFileId,f.getFileId())
                    .update();        
        });

今天感觉基本没学 这个demo到此为止吧。虽然感觉还有很多要学,但是基本的已经会了,之后有时间再来学一下,要去忙四级去了,这几天都没怎么学四级 之后我觉得可以加个编辑文件和读取文件,就这两个,加完我是真没啥想法了,以及执行命令的时候,去让一个AI生成类似于claudecode的那种 这个应该不会很难的。就这样吧~ 多agent对我来说应该还有点距离啊,有时间先完成前面的吧,多agent,目前也没时间搞了

全部评论
点赞 回复 分享
发布于 昨天 20:49 广东

相关推荐

说一说之前很火的提示词吧,但是随着AI能力的提升,提示词越来越不重要了。对初级需求,提示词确实越来越&nbsp;“轻量化”,随便一句&nbsp;“用&nbsp;Java&nbsp;写个简单的用户登录接口”,AI&nbsp;就能给出能用的代码;但对复杂场景、高要求的&nbsp;AI&nbsp;Coding&nbsp;任务,提示词非但没失效,反而升级成了&nbsp;“精准指令工程”,是拉开效率差距的关键。可一旦碰到复杂业务逻辑、性能优化、架构设计这类硬核需求,就会发现&nbsp;“会写提示词”&nbsp;和&nbsp;“不会写提示词”&nbsp;的天壤之别。比如同样是让&nbsp;AI&nbsp;优化&nbsp;MySQL&nbsp;慢查询,普通提示词是&nbsp;“帮我优化这段&nbsp;SQL”,AI&nbsp;可能只会给出加索引的建议;但精准的指令是&nbsp;“我有一个电商订单查询&nbsp;SQL,数据量&nbsp;100&nbsp;万&nbsp;+,现在执行时间&nbsp;2&nbsp;秒,要求优化到&nbsp;500ms&nbsp;内,限制只能调整索引和&nbsp;SQL&nbsp;结构,不能改表结构,还要考虑分库分表的兼容性”——&nbsp;这种带约束条件、业务背景、性能指标的提示词,才能让&nbsp;AI&nbsp;输出真正落地的方案。更重要的是,AI&nbsp;Coding&nbsp;的核心需求正在从&nbsp;“生成代码”&nbsp;转向&nbsp;“解决问题”。比如你让&nbsp;AI&nbsp;排查一个&nbsp;Spring&nbsp;Boot&nbsp;接口的超时问题,只说&nbsp;“接口超时了,帮我看看”,AI&nbsp;大概率会罗列一堆通用原因;但如果你在提示词里加上&nbsp;“接口调用了第三方支付&nbsp;API,超时发生在高峰期,日志显示有大量数据库锁等待”,AI&nbsp;就能直接定位到&nbsp;“第三方&nbsp;API&nbsp;熔断机制缺失”“数据库事务过长”&nbsp;等具体问题,甚至给出代码级的解决方案。还有一个容易被忽略的点:提示词是帮你&nbsp;“驯服&nbsp;AI&nbsp;幻觉”&nbsp;的关键。AI&nbsp;Coding&nbsp;最头疼的就是生成&nbsp;“看起来对但实际跑不通”&nbsp;的代码,比如引用不存在的类、用错框架&nbsp;API。这时候,在提示词里加上&nbsp;“代码必须符合&nbsp;Spring&nbsp;Boot&nbsp;2.7&nbsp;版本规范,禁止使用废弃&nbsp;API,给出完整的依赖配置和测试用例”,就能大幅降低幻觉概率&nbsp;——&nbsp;这种&nbsp;“精准约束”,本质就是高级提示词技巧。说到底,AI&nbsp;能力提升后,提示词的&nbsp;“复杂度”&nbsp;降低了,但&nbsp;“精准度”&nbsp;要求更高了&nbsp;。它不再需要华丽的模板,却需要你把业务需求、技术约束、性能指标讲清楚。对初级开发者来说,随便写写就能用;但对想靠&nbsp;AI&nbsp;提升核心工作效率的工程师,“写好提示词”&nbsp;依然是&nbsp;AI&nbsp;Coding&nbsp;的核心实战技巧。
AI Coding实战技...
点赞 评论 收藏
分享
03-31 14:46
已编辑
门头沟学院 Web前端
励志成为双港第一ja...:这其实很正常,离的太远了,他认为你不会来,就为了混个面试,而且成本很高,实习生都优先选本地高校。吃了地域的亏,所有很多时候地域可能比院校层次更重要。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务