Meta把内部设计系统开源了:支撑内部13000+应用:专为Agent调优
2026-07-03
2026-07-08 0
最近我的工作主要聚焦在 Agent 和 Skill 相关方向。随着公司多个项目陆续完成 Agent 化升级,我发现一个很典型的问题:很多企业系统已经沉淀了大量业务能力,但这些能力仍然停留在传统接口和服务调用层面,大模型无法直接理解和调用。

尤其在 Java / Spring Boot 体系中,很多系统并不适合推倒重来重新开发一个 Agent 应用。更现实的方式是:在尽量不改动原有架构的前提下,把已有业务方法、业务工具、知识库和大模型能力连接起来,让存量系统逐步具备 Agent 能力。
基于这些实践,我将项目集成 Agent 的经验进行总结和封装,开发了一个可复用组件:easy-agent。
easy-agent 是一个面向 Java / Spring Boot 应用的轻量级 Agent 能力组件。业务系统引入 easy-agent-spring-boot-starter 后,可以通过简单的 @EasyTool 注解,将已有业务方法快速注册为 AI 可调用的工具;也可以通过 ToolProvider SPI 以编程方式批量注册工具。
同时,easy-agent 内置 MCP Server,使 Claude Code、Codex 等支持 MCP 的 AI 客户端可以直接发现并调用业务系统中的工具。它还提供 LLM、RAG、Skill 等模块,帮助业务系统完成从工具注册、模型调用、知识库检索到技能生成的完整 Agent 化链路。
easy-agent 的核心目标不是替代业务系统,而是作为一个组件嵌入到已有 Spring Boot 项目中,让存量业务系统以较低成本获得 Agent 能力。
当前 easy-agent 主要包含以下模块:
| 模块 | 说明 |
|---|---|
| easy-agent-core | 核心模块,提供工具注解、工具注册中心、工具执行器和 SPI 扩展 |
| easy-agent-llm | LLM 模块,提供 OpenAI 兼容模型调用和自动工具调用能力 |
| easy-agent-mcp | MCP 模块,提供 HTTP JSON-RPC MCP Server,让 Claude Code 等客户端调用业务工具 |
| easy-agent-rag | RAG 模块,提供知识库加载、文档分块、检索增强能力 |
| easy-agent-skill | Skill 模块,根据已注册工具生成业务侧 Skill Markdown 文件 |
| easy-agent-spring-boot-starter | Starter 模块,负责 Spring Boot 自动装配和配置元数据 |
整体链路可以理解为:
复制代码Spring Boot 业务系统
↓
@EasyTool / ToolProvider
↓
ToolRegistry
↓
ToolExecutor
↓
LLM / MCP / RAG / Skill
↓
Claude Code / Codex / 企业内部 AI 助手
easy-agent 已经发布到 Maven Central,在 Spring Boot 项目中直接引入 easy-agent-spring-boot-starter 即可。
复制代码
io.github.songrongzhen
easy-agent-spring-boot-starter
0.1.7
引入 starter 后,easy-agent 会自动装配 core、llm、mcp、rag、skill 等模块。对于大多数 Spring Boot 项目来说,不需要手动创建核心组件 Bean。
如果只想先体验 LLM 对话能力,可以先添加最简配置:
复制代码easy-agent:
llm:
enabled: true
model: qwen-plus
api-key: ${DASHSCOPE_API_KEY}
这里的 model 配置为 qwen-plus 时,easy-agent 会自动识别为通义千问兼容模型服务。api-key 建议通过环境变量传入,不建议直接写死在 application.yml 中。 easy-agent 的 LLM 模块采用 OpenAI 兼容调用方式,当前支持通义千问、DeepSeek、Ollama、OpenAI 等模型服务。
如果希望一次性开启 easy-agent 的主要能力,可以参考下面这份完整配置。
复制代码easy-agent:
# MCP 配置:开启后,Claude Code、Codex 等 MCP 客户端可以发现并调用业务工具
mcp:
enabled: true
server-name: easy-agent-mcp-server
server-version: 0.1.7
cors:
enabled: true
allowed-origin-patterns:
- :*
- :*
allowed-headers:
- "*"
allowed-methods:
- GET
- POST
- OPTIONS
exposed-headers:
- Content-Type # LLM 配置:用于普通对话和自动工具调用
llm:
enabled: true
model: qwen-plus
api-key: ${DASHSCOPE_API_KEY} # RAG 配置:用于知识库检索增强
rag:
enabled: true
storage-type: IN_MEMORY
search:
strategy: AUTO
embedding:
enabled: true
provider: DASHSCOPE
model: text-embedding-v3
cosine:
enabled: true
tf-idf:
enabled: true
pdf:
enabled: true
resource-path: classpath:knowledge/
excel:
enabled: true
resource-path: classpath:knowledge/ # Skill 配置:用于根据已注册工具生成业务侧 Skill Markdown 文件
skill:
enabled: true
skill-output-path: .
需要注意几点: 第一,MCP 模块可以把当前系统中已注册的工具暴露给 MCP 客户端。开启后,Claude Code、Codex 等客户端可以通过 tools/list 查看工具,通过 tools/call 调用工具。 第二,LLM 模块用于模型对话和自动工具调用。model 配置为 qwen-plus 时,easy-agent 会按通义千问兼容服务处理。 第三,RAG 模块用于知识库检索增强。上面的配置会从 classpath:knowledge/ 目录加载 PDF 和 Excel 文件,使用内存存储,适合本地测试和轻量场景。 第四,Skill 模块用于生成业务侧 Skill Markdown 文件。skill-output-path 表示生成文件的基础目录。配置为 . 时,生成文件会写入项目根目录下的 skill/ 目录。
在已有 Spring Bean 的方法上添加 @EasyTool 注解,就可以把这个方法注册为 AI 可调用的工具。
复制代码@Service
public class RequirementService { @EasyTool(name = "queryMyRequirements", description = "查询当前用户的需求列表")
public List queryMyRequirements(
@ToolParam(name = "userId", description = "用户 ID") String userId) {
return requirementRepository.findByUserId(userId);
} @EasyTool(name = "countMyRequirements", description = "统计当前用户的需求数量")
public RequirementCount countMyRequirements(
@ToolParam(name = "userId", description = "用户 ID") String userId) {
return requirementRepository.countByUserId(userId);
}
}
应用启动后,easy-agent 会自动扫描 @EasyTool 方法,并将其注册到 ToolRegistry。后续 LLM、MCP 或 ToolExecutor 都可以调用这个工具。 这类方式非常适合固定业务方法,例如:
复制代码查询当前用户权限
查询需求列表
查询需求详情
创建需求
统计个人周报
统计团队周报
查询订单信息
执行审批操作
@EasyTool 适合大多数固定 Java 方法,但有些场景更适合编程式注册,例如:
复制代码工具需要运行时动态组装
工具定义来自数据库或配置中心
工具不是某个固定 Java 方法
业务系统希望批量注册一组工具
插件化系统需要动态扩展工具
这时可以使用 ToolProvider SPI。
复制代码@Component
public class BusinessToolProvider implements ToolProvider { @Override
public Collection provide() {
return List.of(new ToolDefinition(
"queryUserPermission",
"查询当前用户权限",
"user",
"permissionService",
"queryCurrentUserPermission",
List.of(new ParameterDefinition("userId", "用户 ID", "String", true)),
true
));
} @Override
public int priority() {
return 0;
}
}
业务系统只需要将 ToolProvider 声明为 Spring Bean,easy-agent 会自动收集所有 ToolProvider,并注册其返回的 ToolDefinition。 priority() 数值越小,注册优先级越高。如果工具名称重复,会按照 ToolRegistry 的现有规则进行覆盖。
在企业内部系统中,工具调用往往需要审计、日志、监控和失败告警。easy-agent 提供了 ToolExecutionListener,用于监听工具执行过程。
复制代码@Component
public class BusinessToolExecutionListener implements ToolExecutionListener { @Override
public void beforeExecution(ToolInvocation invocation) {
log.info("准备执行工具:{}", invocation.toolName());
} @Override
public void afterExecution(ToolInvocation invocation, ToolResult result) {
log.info("工具执行成功:{}", invocation.toolName());
} @Override
public void onError(ToolInvocation invocation, Throwable error) {
log.warn("工具执行失败:{}", invocation.toolName(), error);
}
}
ToolExecutionListener 可以用于:
复制代码记录工具调用日志
统计工具调用次数
记录调用耗时
做审计留痕
失败告警
接入监控系统
easy-agent 的 LLM 模块提供 OpenAI 兼容调用能力,并支持自动工具调用闭环。 业务系统可以通过 AgentLlmService 让大模型结合已注册工具回答问题。
复制代码@RestController
@RequestMapping("/api")
public class AgentController { private final AgentLlmService agentLlmService; public AgentController(AgentLlmService agentLlmService) {
this.agentLlmService = agentLlmService;
} @GetMapping("/agent")
public ChatResponse agent(@RequestParam String message) {
return agentLlmService.chatWithRegisteredTools(
List.of(ChatMessage.user(message))
);
}
}
例如用户提问:
复制代码帮我查询一下我当前有哪些需求,并统计一下数量。
大模型可以根据工具描述自动选择调用:
复制代码queryMyRequirements
countMyRequirements
easy-agent 内置 MCP Server。开启 MCP 后,Claude Code 等支持 MCP 的客户端可以直接连接你的 Spring Boot 服务,并发现、调用系统中已经注册的工具。
假设你的服务地址是:
复制代码
并且已经开启 MCP 配置:
复制代码easy-agent:
mcp:
enabled: true
server-name: easy-agent-mcp-server
server-version: 0.1.7
启动成功后,easy-agent 会提供 MCP HTTP 接口:
复制代码
在 Claude Code 中添加 MCP Server:
复制代码claude mcp add easy-agent
如果你的服务部署在其他机器上,把 localhost:8999 替换成实际服务地址即可:
复制代码claude mcp add easy-agent http://{your-project-address}/mcp
连接成功后,Claude Code 会通过 tools/list 发现 easy-agent 暴露出来的工具。
连接成功后,你不需要手动调用接口,直接用自然语言对话即可。 例如你的业务系统中已经注册了 add 工具:
复制代码用户:帮我计算 3 + 5
Claude Code:调用 add,返回 8
再比如你的系统中注册了 queryUser 工具:
复制代码用户:查询用户 ID 为 123 的信息
Claude Code:调用 queryUser,返回用户信息
这就是 MCP 的价值:业务系统不需要专门为 Claude Code 写适配接口,只要 easy-agent 把工具暴露出来,Claude Code 就可以发现并调用。
对于需要结合文档、说明书、规范、周报、需求文档的场景,easy-agent 提供 RAG 检索增强能力。 当前 RAG 模块支持:
复制代码启动时加载知识库
加载 PDF 文件
加载 Excel 文件
文档分块
内存向量存储
Embedding 检索
Cosine 相似度检索
TF-IDF 检索
运行时添加文档
按 source 删除文档
按 documentId 删除文档
清空索引
重建索引
示例使用:
复制代码@Service
public class KnowledgeService { private final RagService ragService;
private final LlmService llmService; public KnowledgeService(RagService ragService, LlmService llmService) {
this.ragService = ragService;
this.llmService = llmService;
} public ChatResponse answerQuestion(String question) {
String context = ragService.searchAndConcat(question, 5); return llmService.chat(List.of(
ChatMessage.system("请基于以下知识回答问题:n" + context),
ChatMessage.user(question)
));
}
}
需要注意的是,easy-agent 的 RAG 模块当前默认以内存存储为主,适合本地测试、轻量知识库和个人知识库场景。PgVector 配置和占位类已经存在,但当前还不是完整可用的持久化向量库实现。 另外,easy-agent 只提供 RAG Java API,不默认暴露文件上传接口。业务系统如果需要运行时上传知识库文件,需要自己提供上传接口,并负责权限控制、文件大小限制、租户隔离和安全校验。
easy-agent 的 Skill 模块用于根据当前系统中已经注册的工具,生成业务侧自己的 Skill Markdown 文件。 它适合这样的场景: 系统里已经有多个工具,例如查询需求列表、查询需求详情、创建需求、统计个人周报、统计团队周报等。单个工具只能完成一个动作,而 Skill 可以把这些工具组织成一个更完整的使用说明,让 AI 客户端知道在什么场景下应该如何组合使用这些工具。 Skill 生成流程 第一步,启动业务服务,并确保 Skill 模块已开启。
复制代码easy-agent:
skill:
enabled: true
skill-output-path: .
这里 skill-output-path 配置为 . 时,生成的 Skill 文件会写入项目根目录下的 skill/ 目录。 第二步,在 Claude Code 中连接 easy-agent 的 MCP Server。
复制代码claude mcp add easy-agent
第三步,在 Claude Code 中告诉它你想创建一个 Skill。 例如:
复制代码我想创建一个用于查询个人需求的 Skill。
此时 easy-agent 会通过内置的 Skill 生成工具,引导你补充关键信息,包括:
复制代码Skill 名称
Skill 描述
使用边界
可调用工具
使用示例
第四步,确认生成。 生成完成后,Skill Markdown 文件会写入项目根目录下的 skill/ 目录。例如:
复制代码skill/个人需求查询.md
如果同名文件已经存在,MCP 客户端会询问使用者选择生成副本还是覆盖。 当前版本的 Skill 模块主要提供业务 Skill Markdown 文件生成能力,不包含 Skill 文件解析、运行时加载、注册中心或文件热更新能力。 一个典型使用场景 假设企业内部有一个需求管理系统,里面已经有这些业务能力:
复制代码查询当前用户权限
查询我的需求列表
查询需求详情
创建需求
统计个人周报
统计团队周报
[video(video-14MqDbib-1783243561349)(type-csdn)(url-live.csdn.net/v/embed/532…)]
接入 easy-agent 后,可以这样改造: 第一步,用 @EasyTool 暴露已有业务方法。 第二步,用 MCP 让 Claude Code 可以发现并调用这些工具。 第三步,用 LLM 模块让大模型根据用户问题自动选择工具。 第四步,用 RAG 接入需求文档、项目规范、周报记录等知识库。 第五步,用 Skill 模块生成“个人需求查询”“周报生成”“需求创建”等业务 Skill。 这样,原本只能通过页面或接口操作的业务系统,就可以逐步变成一个可被 Agent 调用的能力系统。
easy-agent 的目标很简单:让 Java / Spring Boot 存量系统以组件化方式接入 Agent 能力。 它不要求你推翻原有系统,也不要求你重新搭建一套独立 Agent 应用。对于已有业务系统,只需要引入 easy-agent-spring-boot-starter,再通过 @EasyTool 或 ToolProvider 暴露已有业务能力,就可以逐步接入 LLM、MCP、RAG 和 Skill 能力。 目前 easy-agent 已经发布到 Maven Central,并在 GitHub 获得 200+ Stars。这个项目还在持续迭代中,后续会继续打磨工具调用、MCP、RAG、Skill 以及更多企业内部 Agent 场景。 项目地址: github.com/songrongzhe… 如果你也在做 Java 系统的智能化改造,或者希望让已有 Spring Boot 系统具备 Agent 能力,欢迎试用 easy-agent。开源不易,如果这个项目对你有帮助,也欢迎在 GitHub 留下一颗 Star。