Langchain4j + Skills使用示例
本文介绍了LangChain4j 1.12.1版本新增的Skill功能,展示了如何创建和使用自定义技能进行代码安全审计。主要内容包括: 创建Maven项目并添加LangChain4j相关依赖 定义代码安全审计Skill(包含名称、描述和详细指令) 演示如何加载技能并创建AI服务进行代码审计 提供了不安全的代码示例供审计测试 Skill机制允许为语言模型配置可重用的行为指令,按需加载详细内容,保持初
·
Langchain4j + Skills使用示例
LangChain4j 1.12.1版本开始支持Skill。
Skills是一种为大型语言模型配备可重复使用、独立的行为指令的机制。一个技能包含名称、简短描述以及指令内容(其主体),还可以附带可选资源(例如参考文献、资产、模板等)。大型语言模型按需加载技能,初始上下文保持精简,仅在实际需要时才引入详细指令。
1、创建Maven项目。
依赖pom.xml添加LangChain4j相关依赖包。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sfccn.tools</groupId>
<artifactId>aiservice</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<langchain4j.version>1.12.2</langchain4j.version>
</properties>
<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-core</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-skills</artifactId>
<version>1.12.2-beta22</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>alimaven</id>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/public/</url>
</repository>
</repositories>
</project>
2、创建Skill。
一个 Skill 包含:
- name:技能名称
- description:简短描述
- content:详细的执行指令(步骤、注意事项、示例等)
- resources:可选的参考资料(配置文件、文档等)
创建文件skills\code-security-audit\SKILL.md
---
name: code-security-audit
description: 全面检查代码中的安全漏洞,包括SQL注入、XSS攻击、命令注入、反序列化漏洞、敏感信息泄露等安全问题
---
作为代码安全审计专家,请按以下步骤进行审计:
1. **漏洞识别**:仔细扫描代码,寻找以下类型的安全问题:
- SQL注入:直接拼接SQL语句
- XSS跨站脚本攻击:未转义输出用户输入
- 命令注入:直接拼接执行系统命令
- 反序列化漏洞:不安全的反序列化操作
- 敏感信息泄露:硬编码密码、密钥等
- 认证与授权问题
- 路径遍历漏洞
- 不安全的随机数使用
2. **风险评估**:对每个发现的问题评定风险等级:
- 🔴 严重:需要立即修复
- 🟠 高风险:应尽快修复
- 🟡 中等:建议修复
- 🟢 低风险:可选修复
3. **修复建议**:为每个漏洞提供具体的修复代码示例
4. **输出格式**:
```
=== 代码安全审计报告 ===
📊 总体评估:[安全/存在风险/危险]
🔍 发现的漏洞:
1. [漏洞类型] - [风险等级]
位置:[代码位置描述]
问题代码:
```
[有问题的代码片段]
```
安全风险:[详细说明]
修复建议:
```
[修复后的代码示例]
```
📝 安全改进建议总结:
[列出关键改进点]
```
3、创建LangChain4j应用。
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.skills.FileSystemSkill;
import dev.langchain4j.skills.FileSystemSkillLoader;
import dev.langchain4j.skills.Skills;
import java.nio.file.Path;
import java.util.List;
import static java.time.Duration.ofSeconds;
/**
* 使用 LangChain4j Skill 进行代码安全校验的示例
*
* 本示例展示如何创建和使用自定义 Skill 来检查代码中的安全漏洞,
* 包括 SQL 注入、XSS 攻击、命令注入等常见安全问题。
*
* Skill 定义位于:doc/skills/code-security-audit/SKILL.md
*/
public class SkillExample {
static ChatModel model = OpenAiChatModel.builder()
.baseUrl(ApiKeys.API_URL)
.apiKey(ApiKeys.OPENAI_API_KEY)
.modelName(ApiKeys.MODEL_NAME)
.timeout(ofSeconds(120))
.temperature(0.2)
.logRequests(true)
.build();
public static void main(String[] args) {
// 1. 从文件系统加载 Skills
List<FileSystemSkill> skillList = FileSystemSkillLoader.loadSkills(Path.of("doc/skills/"));
Skills skills = Skills.from(skillList);
// 2. 创建 AI 服务
CodeSecurityAuditService service = AiServices.builder(CodeSecurityAuditService.class)
.chatModel(model)
.toolProvider(skills.toolProvider())
.systemMessage(
"你是一个专业的代码安全审计专家。\n" +
"你的任务是仔细分析代码,识别潜在的安全漏洞。\n" +
"可用的技能:\n" +
skills.formatAvailableSkills() +
"\n当需要审计代码安全性时,请使用 activate_skill 工具激活 code-security-audit 技能。"
)
.build();
// 3. 示例:审计一段有安全问题的代码
String unsafeCode = """
public class UserService {
public User getUserById(String userId) {
String sql = "SELECT * FROM users WHERE id = '" + userId + "'";
ResultSet rs = statement.executeQuery(sql);
return extractUser(rs);
}
public void renderComment(String userComment) {
String html = "<div class='comment'>" + userComment + "</div>";
response.getWriter().write(html);
}
public void executeBackup(String path) {
Runtime.getRuntime().exec("tar -czf backup.tar.gz " + path);
}
}
""";
System.out.println("=== 开始代码安全审计 ===\n");
String result = service.auditCode(unsafeCode);
System.out.println(result);
}
interface CodeSecurityAuditService {
String auditCode(String code);
}
}
4、运行结果
运行上边的示例代码,控制台将会输出以下内容:
=== 开始代码安全审计 ===
现在让我对提供的代码进行全面的安全审计:
```
=== 代码安全审计报告 ===
📊 总体评估:危险 - 存在多个严重安全漏洞
🔍 发现的漏洞:
1. SQL注入漏洞 - 🔴 严重
位置:UserService.getUserById() 方法
问题代码:
```
public User getUserById(String userId) {
String sql = "SELECT * FROM users WHERE id = '" + userId + "'";
ResultSet rs = statement.executeQuery(sql);
return extractUser(rs);
}
```
安全风险:直接拼接用户输入的 userId 到 SQL 语句中,攻击者可以注入恶意 SQL 代码,如:`' OR '1'='1` 或 `'; DROP TABLE users; --`,导致数据泄露、数据篡改或数据库破坏。
修复建议:
```
public User getUserById(String userId) {
String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, userId);
ResultSet rs = pstmt.executeQuery();
return extractUser(rs);
}
```
2. XSS跨站脚本攻击漏洞 - 🔴 严重
位置:UserService.renderComment() 方法
问题代码:
```
public void renderComment(String userComment) {
String html = "<div class='comment'>" + userComment + "</div>";
response.getWriter().write(html);
}
```
安全风险:直接将用户输入的评论内容输出到 HTML 中,攻击者可以注入恶意 JavaScript 代码,如:`<script>alert('XSS')</script>` 或 `<img src=x onerror=stealCookies()>`,导致会话劫持、数据窃取或恶意重定向。
修复建议:
```
public void renderComment(String userComment) {
// 使用HTML转义
String escapedComment = StringEscapeUtils.escapeHtml4(userComment);
String html = "<div class='comment'>" + escapedComment + "</div>";
response.getWriter().write(html);
}
```
或者使用现代框架的模板引擎自动转义功能。
3. 命令注入漏洞 - 🔴 严重
位置:UserService.executeBackup() 方法
问题代码:
```
public void executeBackup(String path) {
Runtime.getRuntime().exec("tar -czf backup.tar.gz " + path);
}
```
安全风险:直接拼接用户输入的路径到系统命令中,攻击者可以注入恶意命令,如:`/home/user; rm -rf /` 或 `/home/user && cat /etc/passwd`,导致系统命令执行、文件系统破坏或敏感信息泄露。
修复建议:
```
public void executeBackup(String path) {
// 验证路径是否安全
if (!isValidPath(path)) {
throw new SecurityException("Invalid path provided");
}
// 使用参数数组而不是字符串拼接
String[] cmd = {"tar", "-czf", "backup.tar.gz", path};
Process process = Runtime.getRuntime().exec(cmd);
// 或者使用ProcessBuilder
ProcessBuilder pb = new ProcessBuilder("tar", "-czf", "backup.tar.gz", path);
Process process = pb.start();
}
```
4. 缺少输入验证 - 🟠 高风险
位置:所有方法
安全风险:所有方法都直接使用用户输入而没有进行任何验证,可能导致空指针异常、格式错误或恶意输入。
修复建议:
```
public User getUserById(String userId) {
// 输入验证
if (userId == null || userId.trim().isEmpty()) {
throw new IllegalArgumentException("User ID cannot be null or empty");
}
// 验证格式(例如:应该是数字)
if (!userId.matches("\\d+")) {
throw new IllegalArgumentException("Invalid user ID format");
}
// 使用参数化查询
String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, userId);
ResultSet rs = pstmt.executeQuery();
return extractUser(rs);
}
```
5. 缺少错误处理 - 🟡 中等
位置:所有方法
安全风险:代码中没有适当的错误处理,可能导致敏感信息泄露(如堆栈跟踪)或系统状态不一致。
修复建议:
```
public User getUserById(String userId) {
try {
// 输入验证
validateUserId(userId);
// 使用参数化查询
String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, userId);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
return extractUser(rs);
} else {
return null;
}
} catch (SQLException e) {
// 记录错误但不暴露敏感信息
logger.error("Database error while fetching user", e);
throw new ServiceException("Unable to retrieve user information");
} catch (IllegalArgumentException e) {
// 输入验证错误
throw e;
}
}
```
📝 安全改进建议总结:
1. **立即修复**:SQL注入、XSS和命令注入漏洞都是严重风险,需要立即修复
2. **使用参数化查询**:所有数据库操作都应使用PreparedStatement
3. **输出编码**:所有用户输入输出到HTML时都应进行适当的编码
4. **命令执行安全**:避免直接拼接命令,使用参数数组或ProcessBuilder
5. **输入验证**:对所有用户输入进行严格的验证和清理
6. **最小权限原则**:数据库连接和系统命令执行应使用最小必要权限
7. **错误处理**:实现适当的错误处理,避免泄露敏感信息
8. **安全编码培训**:开发团队需要接受安全编码培训
9. **代码审查**:建立安全代码审查流程
10. **安全测试**:实施自动化安全测试,包括SAST和DAST工具
这些漏洞如果被利用,可能导致数据泄露、系统破坏、权限提升等严重后果,建议立即修复。
更多推荐




所有评论(0)