
作者:小傅哥 博客:https://bugstack.cn
❝沉淀、分享、成长,让自己和他人都能有所收获!😜❞
大家好,我是技术UP主小傅哥。
💐 从22年至今,小傅哥已经带着大家做了5个AI类项目,包括;(22年)问答助手、(23年)OpenAI应用(含支付、敏感词过滤)、(24年)AI 代码自动评审、(25年)Ai Agent 智能体、(25年)Ai MCP Gateway 网关。
这些项目也都是结合这,AI 这一年最新的技术动向和应用方向,而做的设计和落地。所以,每次小傅哥都给大家讲了,接下来 AI 将影响的一些场景,也都陆续的发生了。就像,24年11月发布 MCP 协议后,我给大家说,所有互联网企业都将大量的落地 MCP 服务,并开始 Ai Agent 智能体实现(别看市面有 dify、扣子,各个且用还是要做自己的业务智能体)。
随后,25年年初,小傅哥就带着大家开始了 RAG、MCP、Ai Agent 智能体的开发,并告诉大家,以后 Ai Agent 智能体也会出标准的框架,让开发更加容易。这不,谷歌的 ADK 就来了。并且这哥们👬🏻还定义A2A协议。这会让不是那么大型的互联网公司,也会具备 Ai Agent 智能体开发的能力。
接下来的几年,所有的业务项目,都会以 Ai Agent 智能体翻一遍,程序员新增的岗位和工作量仍然会很多。因为在咱们这,你做的越快,你就得做的越多!
接下来,小傅哥就带着大家做一下 Google ADK 搭建 AI Agent。如果你感兴趣 AI 类项目,还可以在文末获取全部实战项目源码,深度积累此类技术内容。文末有Google ADK 运行效果,交互式对话智能体,对 ELK 进行巡检分析。
官网:https://google.github.io/adk-docs/
搭建:https://google.github.io/adk-docs/get-started/

本次的 Ai Agent 实践,是以 Google ADK 框架为基础,配和 Github system-prompts-and-models-of-ai-tools 开源提示词项目中的 claude-code-system-prompt 作为必要描述。来实验,ELK 系统日志智能分析场景。
如果暂时配置不了,可以在测试的时候去掉这部分 mcp 服务JDK 17+、Maven 3.8.x
server:
port: 8901
# 可申请API秘钥;https://ai.google.dev/gemini-api
google:
api:
base-url: https://generativelanguage.googleapis.com
key: AIzaSyDF6JnvFx7xWEsARS*******可以自己申请免费的
cloud:
project: xfg-google-adk
logging:
level:
root: info
config: classpath:logback-spring.xml
application-dev.yml 修改你的参数配置,配置你的 Google api keyimport com.google.adk.agents.LlmAgent;
import com.google.adk.events.Event;
import com.google.adk.models.Gemini;
import com.google.adk.runner.InMemoryRunner;
import com.google.adk.sessions.Session;
import com.google.genai.Client;
import com.google.genai.types.Content;
import com.google.genai.types.HttpOptions;
import com.google.genai.types.Part;
import io.reactivex.rxjava3.core.Flowable;
publicclass ApiTest {
/**
* 可申请免费测试api
* https://ai.google.dev/gemini-api/docs/quickstart?hl=zh-cn#apps-script
*/
public static void main(String[] args) {
LlmAgent agent = LlmAgent.builder()
.name("test")
.description("test agent help user do work")
.model(Gemini.builder()
.apiClient(Client.builder()
.apiKey("AIzaSyDF6JnvFx7xWEsARSGosNmvTU3ZoCwo-mc")
.httpOptions(HttpOptions
.builder()
.baseUrl("https://generativelanguage.googleapis.com")
.timeout(500000)
.build())
.build())
.modelName("gemini-2.0-flash")
.build())
.build();
InMemoryRunner runner = new InMemoryRunner(agent);
Session session = runner
.sessionService()
.createSession("test", "xiaofuge")
.blockingGet();
Flowable<Event> events = runner.runAsync("xiaofuge", session.id(), Content.fromParts(Part.fromText("hi agent can you help me")));
System.out.print("\nAgent > ");
events.blockingForEach(event -> System.out.println(event.stringifyContent()));
}
}
Agent > Hi there! Yes, I'm here to help. To best assist you, could you tell me what you need help with? The more information you give me, the better I can understand your request and provide a useful response.
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class AutoAgentTest {
@Value("${google.api.base-url}")
private String baseUrl;
@Value("${google.api.key}")
private String apiKey;
privatestaticfinal String USER_ID = "xiaofuge";
privatestaticfinal String NAME = "multi_tool_agent";
publicstatic BaseAgent agent;
@Before
public void init() {
List<McpTool> mcpTools = new ArrayList<>();
mcpTools.addAll(mcp_elk());
mcpTools.addAll(mcp_filesystem());
agent = LlmAgent.builder()
.name(NAME)
.model(Gemini.builder()
.apiClient(Client.builder()
.apiKey(apiKey)
.httpOptions(HttpOptions
.builder()
.baseUrl(baseUrl)
.timeout(500000)
.build())
.build())
.modelName("gemini-2.0-flash")
.build())
.description("You are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.")
.instruction(
"""
You are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
可以在这里复制全部提示词;https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/Claude%20Code/claude-code-system-prompt.txt
""")
.tools(mcpTools)
.build();
}
/**
* - 需要配置后,才能在单测控制台输入内容
* IntelliJ IDEA Help -> Edit Custom VM Options -> -Deditable.java.test.console=true
* <br/>
* - <a href="https://ai.google.dev/api">ai.google.dev/api</a>
*/
@Test
public void test_agent() {
InMemoryRunner runner = new InMemoryRunner(agent);
Session session =
runner
.sessionService()
.createSession(NAME, USER_ID)
.blockingGet();
try (Scanner scanner = new Scanner(System.in, StandardCharsets.UTF_8)) {
while (true) {
System.out.print("\nYou > ");
String userInput = scanner.nextLine();
if ("quit".equalsIgnoreCase(userInput)) {
break;
}
Content userMsg = Content.fromParts(Part.fromText(userInput));
Flowable<Event> events = runner.runAsync(USER_ID, session.id(), userMsg);
System.out.print("\nAgent > ");
events.blockingForEach(event -> System.out.println(event.stringifyContent()));
}
}
}
private List<McpTool> mcp_elk() {
Map<String, String> env = new HashMap<>();
env.put("ES_HOST", "http://127.0.0.1:9200");
env.put("ES_API_KEY", "none");
ServerParameters mcp_elk = ServerParameters.builder("npx")
.args(List.of(
"-y",
"@awesome-ai/elasticsearch-mcp"
))
.env(env)
.build();
CompletableFuture<McpToolset.McpToolsAndToolsetResult> futureResult =
McpToolset.fromServer(mcp_elk, JsonBaseModel.getMapper());
McpToolset.McpToolsAndToolsetResult result = futureResult.join();
return result.getTools();
}
private List<McpTool> mcp_filesystem() {
ServerParameters mcp_filesystem = ServerParameters.builder("npx")
.args(List.of(
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/fuzhengwei/Desktop"
))
.build();
CompletableFuture<McpToolset.McpToolsAndToolsetResult> futureResult =
McpToolset.fromServer(mcp_filesystem, JsonBaseModel.getMapper());
McpToolset.McpToolsAndToolsetResult result = futureResult.join();
return result.getTools();
}
}
mcpTools.addAll(mcp_elk()); 代码。/Users/fuzhengwei/Desktop 你需要修改为你的本地的有权限访问的地址。有了前面的案例测试基础,就可以把服务配置成对应的接口,以及开发个简单的页面进行对接验证了。
@Slf4j
@RestController
@RequestMapping("/trigger")
@CrossOrigin(origins = "*")
publicclass AgentController {
privatefinal AgentService agentService;
public AgentController(AgentService agentService) {
this.agentService = agentService;
}
@PostMapping(path = "/session", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public CreateSessionResponse createSession(@RequestBody CreateSessionRequest req) {
String sessionId = agentService.createOrGetSession(req.getUserId());
log.info("创建会话ID:{}", sessionId);
returnnew CreateSessionResponse(sessionId);
}
@PostMapping(path = "/chat", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ChatResponse chat(@RequestBody ChatRequest req) {
String sessionId = req.getSessionId();
if (sessionId == null || sessionId.isEmpty()) {
sessionId = agentService.createOrGetSession(req.getUserId());
}
log.info("使用会话ID:{}", sessionId);
List<String> outputs = agentService.chat(req.getUserId(), sessionId, req.getMessage());
returnnew ChatResponse(sessionId, String.join("\n", outputs));
}
}


elk-blacklist-data.sh 模拟的写入进去一些日志,这样才能用于分析使用。
