如何通过自定义 Agent Skill 让 AI 精准执行企业内部操作(查库、发邮件)
本文针对2026年AI应用开发中大模型的"幻觉"问题,提出基于AgentSkill的混合架构解决方案。通过"Java稳态后端+Python动态编排"的设计,将业务逻辑封装为标准化的Tool/Function,使AI从聊天机器人进化为可执行企业操作的数字员工。文章详细展示了数据库查询和邮件发送两个场景的实现,Java负责安全稳定的基础服务,Python处理灵活
背景:在 2026 年的 AI 应用开发中,大模型(LLM)的“幻觉”问题依然是企业落地的最大阻碍。当用户询问“上个季度的销售额是多少?”或“帮我给张三发一封项目延期邮件”时,通用大模型往往只能胡编乱造。本文将以 Agent Skill(智能体技能) 为核心,手把手教你构建一套 “Java 稳态后端 + Python 动态编排” 的混合架构。通过两个真实场景(数据库查询、邮件发送),演示如何定义标准化的 Tool/Function,让 AI 从“聊天机器人”进化为能精准执行企业操作的“数字员工”。
1. 为什么我们需要 Agent Skill?
在 2026 年,虽然大模型的推理能力已经极强,但它们本质上仍然是概率预测模型。它们不知道你的 MySQL 数据库里存了什么,也不知道你公司的 SMTP 服务器密码是多少。
- 没有 Skill 的 AI:用户问“查一下订单 1001 的状态”,AI 回答:“根据我的推测,订单可能已经发货了。”(❌ 幻觉,不可用)
- 拥有 Skill 的 AI:用户问同样的问题,AI 识别意图 -> 调用
checkOrderStatus技能 -> 连接数据库 -> 返回真实数据 -> 回答:“订单 1001 当前状态为‘已发货’,物流单号 SF123456。”(✅ 精准,可落地)
核心逻辑:我们将复杂的业务逻辑封装成 Skill(技能/工具),大模型只负责理解意图和调度技能,具体的执行权交给确定性的代码(Java/Python)。
2. 架构设计:Java 守门,Python 赋能
为了兼顾企业级的稳定性(高并发、事务管理、安全性)和 AI 开发的灵活性(快速原型、丰富的 AI 库),我们采用以下混合架构:
- Java (Spring Boot 3.x + LangChain4j):作为 Skill Gateway(技能网关)。负责用户鉴权、流量控制、事务管理,并定义标准的 Skill 接口。
- Python (FastAPI + LangChain):作为 Skill Executor(技能执行器)。负责处理复杂的非结构化数据、调用外部 AI 模型接口或执行灵活的脚本逻辑。
- 通信协议:基于 OpenAPI (Swagger) 标准描述技能,通过 HTTP/gRPC 进行内部调用。
2.1 架构流程图

3. 实战一:精准查库(消除数据幻觉)
场景:用户询问实时库存或订单状态。
技术方案:使用 Java 直接通过 JDBC 执行参数化查询,确保数据绝对准确且安全(防止 SQL 注入)。
3.1 定义 Java Skill (基于 LangChain4j)
在 Spring Boot 中,我们只需定义一个带有 @Tool 注解的方法。LangChain4j 会自动将其转换为大模型可理解的 Function Schema。
package com.example.ai.skills;
import dev.langchain4j.agent.tool.Tool;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private final JdbcTemplate jdbcTemplate;
public OrderService(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* 查询订单状态技能
* 大模型会自动提取 orderId 参数并调用此方法
*/
@Tool("查询指定订单ID的当前状态、金额和物流信息。仅用于查询,不可修改。")
public String getOrderStatus(String orderId) {
// 1. 参数校验 (防止非法输入)
if (orderId == null || !orderId.matches("^ORD\\d+$")) {
return "错误:订单号格式不正确,应为 ORD 开头加数字。";
}
try {
// 2. 执行安全查询 (使用预编译语句)
String sql = "SELECT status, amount, logistics_no FROM orders WHERE order_id = ? AND is_deleted = 0";
return jdbcTemplate.queryForObject(sql, (rs, rowNum) -> {
return String.format(
"订单 %s 状态:%s, 金额:%.2f 元, 物流单号:%s",
rs.getString("order_id"),
rs.getString("status"),
rs.getDouble("amount"),
rs.getString("logistics_no")
);
}, orderId);
} catch (Exception e) {
return "未找到该订单或数据库查询失败:" + e.getMessage();
}
}
}
关键点:
- 确定性:代码逻辑是固定的,不会像 LLM 那样“猜”数据。
- 安全性:通过
JdbcTemplate自动处理 SQL 注入风险。(当然也可以使用其他方案,我只是图省劲) - 描述清晰:
@Tool中的描述文本至关重要,它告诉 LLM 何时调用这个技能。
4. 实战二:复杂操作与外部集成(发邮件)
场景:用户要求“给项目经理发送延期邮件”。
难点:多步操作、以及可能需要调用第三方 API(如 SendGrid 或公司内部 SMTP)。
技术方案:对于复杂的编排或非 JVM 生态的库,我们调用 Python 微服务。
4.1 Python 端:构建灵活的技能执行器
使用 FastAPI 暴露标准接口,利用 Python 丰富的库处理邮件和模拟登录。
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import os
app = FastAPI(title="Enterprise Agent Skills")
class EmailTask(BaseModel):
recipient: str
subject: str
body: str
sender_name: str
@app.post("/skill/send_email")
async def send_enterprise_email(task: EmailTask):
"""
技能:发送企业内部通知邮件
"""
smtp_server = os.getenv("SMTP_SERVER", "smtp.corp.com")
smtp_port = int(os.getenv("SMTP_PORT", "587"))
username = os.getenv("SMTP_USER")
password = os.getenv("SMTP_PASS")
if not username or not password:
raise HTTPException(status_code=500, detail="邮件服务配置缺失")
msg = MIMEMultipart()
msg['From'] = f"{task.sender_name} <{username}>"
msg['To'] = task.recipient
msg['Subject'] = f"[AI 助手自动发送] {task.subject}"
msg.attach(MIMEText(task.body, 'plain', 'utf-8'))
try:
# 模拟登录并发送
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls()
server.login(username, password)
server.send_message(msg)
server.quit()
return {"status": "success", "message": f"邮件已成功发送至 {task.recipient}"}
except Exception as e:
raise HTTPException(status_code=500, detail=f"发送失败: {str(e)}")
@app.post("/skill/legacy_login")
async def legacy_system_login(system_name: str, user_id: str):
"""
技能:模拟登录遗留系统(示例)
实际场景中可能涉及 Selenium 或专有 SDK
"""
# 这里可以集成 Selenium, Playwright 或专有 SDK
return {"status": "logged_in", "session_token": "mock_token_12345", "system": system_name}
4.2 Java 端:桥接 Python 技能
在 Java 中,我们将上述 Python 接口包装成另一个 @Tool。
// ExternalSystemSkill.java
package com.example.ai.skills;
import dev.langchain4j.agent.tool.Tool;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class ExternalSystemSkill {
private final RestTemplate restTemplate = new RestTemplate();
private final String PYTHON_SERVICE_URL = "http://python-agent-service:8000";
@Tool("向指定收件人发送正式的工作邮件。需要提供收件人、主题和正文。")
public String sendEmail(String recipient, String subject, String body) {
String url = PYTHON_SERVICE_URL + "/skill/send_email";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 构建请求体
String jsonBody = String.format(
"{\"recipient\": \"%s\", \"subject\": \"%s\", \"body\": \"%s\", \"sender_name\": \"AI Assistant\"}",
recipient, subject, body.replace("\"", "\\\"") // 简单转义
);
HttpEntity<String> entity = new HttpEntity<>(jsonBody, headers);
try {
ResponseEntity<String> response = restTemplate.exchange(
url, HttpMethod.POST, entity, String.class
);
if (response.getStatusCode().is2xxSuccessful()) {
return "操作成功:" + response.getBody();
} else {
return "操作失败:邮件服务返回错误。";
}
} catch (Exception e) {
return "调用邮件服务异常:" + e.getMessage();
}
}
}
更多推荐




所有评论(0)