description:Build or update Java and Spring Boot agents with Spring AI Alibaba ReactAgent, including DashScope model setup, ToolCallback definitions, ToolContext usage, structured output, memory, hooks, and invoke-based state access. Use when requests mention Spring AI Alibaba, ReactAgent, DashScope, MemorySaver, RunnableConfig, outputType, outputSchema, or implementing an agent on the Spring stack.
description:Build or update Java and Spring Boot agents with Spring AI Alibaba ReactAgent using the official Agents tutorial patterns, including ChatModel setup, ToolCallback tools, systemPrompt or instruction design, call or invoke usage, RunnableConfig threadId and metadata, outputType or outputSchema, MemorySaver, hooks, interceptors, and streaming-oriented agent integration. Use when requests mention Spring AI Alibaba, ReactAgent, RunnableConfig, ToolContext, MemorySaver, outputType, outputSchema, hooks, interceptors, or implementing agent workflows on the Spring stack.
---
# Spring AI Alibaba ReactAgent
Use this skill to implement or refactor Spring AI Alibaba agent code around `ReactAgent`. Keep the skill focused on the framework patterns from the Spring AI Alibaba quick-start, and read [references/quick-start.md](./references/quick-start.md) when exact dependency, API, or assembly details matter.
Use this skill to implement or refactor Spring AI Alibaba agent code around `ReactAgent`. Keep the implementation aligned with the official Agents tutorial, and read [references/agents.md](./references/agents.md) when exact API shape, invocation mode, or advanced capability details matter.
## Workflow
1.Confirm prerequisites before coding.
JDK 17+ and Maven 3.8+ are the documented baseline. Default to environment variables for API keys, especially `AI_DASHSCOPE_API_KEY`.
1.Build the smallest agent that solves the request.
Start from `ChatModel + ReactAgent + call(...)`. Add tools, memory, state access, hooks, or streaming only when the request needs them.
2.Pick the model starter before writing agent code.
The quick-start uses `spring-ai-alibaba-agent-framework` plus a model starter such as DashScope. Keep framework and model starter versions aligned to the same release family instead of mixing arbitrary versions.
2.Configure the model first.
Create the provider `ChatModel` explicitly. If the project already has a model bean, reuse it instead of introducing a second configuration style.
3.Build the `ChatModel` first.
For DashScope, initialize `DashScopeApi`, then create `DashScopeChatModel`. If you configure `DashScopeChatOptions`, set the model name explicitly before adding temperature and token settings.
3.Add tools only when the agent must act.
Use `FunctionToolCallback` with explicit tool names and short descriptions. If the tool needs request-scoped metadata, read it through `ToolContext` from `RunnableConfig`.
4.Define tools with strong metadata.
Prefer `FunctionToolCallback` and clear tool names, descriptions, and parameter descriptions. If the tool needs runtime metadata, implement `BiFunction<Input, ToolContext, Output>` and read values from the `RunnableConfig` stored in the context.
4.Choose prompt style deliberately.
Use `systemPrompt(...)` for a compact role definition. Use `instruction(...)` for a longer task-specific directive.
5.Assemble `ReactAgent` from small, explicit pieces.
Start with `.name(...)`, `.model(...)`, `.systemPrompt(...)`, `.tools(...)`, and `.saver(...)`. Add `.outputType(...)`, `.outputSchema(...)`, or `.hooks(...)` only when the behavior requires them.
5.Pick the invocation mode based on the caller contract.
Use `call(...)` for the final answer. Use `invoke(...)` when the caller needs `OverAllState`, message history, or custom state.
6. Add memory deliberately.
Use `MemorySaver`for local or example flows. Reuse the same `threadId` in `RunnableConfig` to continue a conversation. For production, swap in a persistent checkpointer instead of in-memory state.
6. Add conversation memory deliberately.
Use `MemorySaver`and reuse the same `threadId` in `RunnableConfig` for multi-turn chat. For production, prefer a persistent saver.
7.Choose response shaping explicitly.
Use `outputType` when you want a Java class to define the response contract. Use `outputSchema` when the output must follow a custom JSON schema-like text contract.
7.Shape outputs only when the consumer requires it.
Prefer `outputType(...)` for stable Java contracts. Use `outputSchema(...)` when a schema-like response contract is more practical.
8.Reach for advanced hooks only when there is a concrete need.
Use `invoke(...)` when the caller needs the full state instead of only the last assistant message. Use `ModelCallLimitHook` to cap loops, and use human-in-the-loop hooks when tool execution needs approval.
8.Add hooks, interceptors, or streaming only after the basic path works.
Use `ModelCallLimitHook` to cap loops, interceptors for tool or prompt customization, and wrap streaming output in your own application contract.
## Implementation Defaults
- Keep API keys out of source code. Prefer environment variables and property placeholders.
- Keep tool interfaces boring and explicit. Tool names and descriptions become part of the model prompt, so avoid vague naming.
- Prefer a focused system prompt over a long one. State role, available tools, and decision rules.
- Pass request-scoped metadata through `RunnableConfig.addMetadata(...)` when tools need user or tenant context.
- Reuse `threadId` for multi-turn chat. Change `threadId` to start a fresh conversation.
- Treat the versions in the quick-start as documentation examples, not a license to mix incompatible artifacts. Verify the chosen release line before changing a real project.
- Keep API keys out of source code. Prefer environment variables and Spring properties.
- Keep tools narrow and explicit. Tool names and descriptions directly affect model behavior.
- Prefer the shortest prompt that enforces the needed behavior.
- Pass request metadata through `RunnableConfig.addMetadata(...)` instead of globals.
- Reuse `threadId` for multi-turn continuity. Change it for a fresh session.
- Keep the controller thin and push agent assembly or orchestration into the service layer.
- Do not expose raw low-level graph streaming objects directly to external callers unless the project already standardizes on them.
- If the user asks for deterministic JSON, prefer `outputType` first and use `outputSchema` only when a custom shape is easier than a Java type.
- If a tool needs request metadata, add it to `RunnableConfig` and read it via `ToolContext`; do not hide it in globals.
- If the user wants follow-up questions to retain context, keep the same `threadId`.
- If the user only needs the assistant text, call `agent.call(...)`; if they need message history or graph state, use `agent.invoke(...)`.
- If an agent may loop on tool or model calls, add `ModelCallLimitHook`.
- If the caller only needs the final assistant text, use `call(...)`.
- If the caller needs state, messages, or custom graph values, use `invoke(...)`.
- If follow-up requests must retain context, add `.saver(...)` and reuse `threadId`.
- If the agent must use runtime business context, pass it via `RunnableConfig` and read it through `ToolContext`.
- If the output must map to a stable Java contract, prefer `outputType(...)`.
- If the agent may over-iterate, add `ModelCallLimitHook`.
- If the request is for HTTP streaming, keep the agent logic in the service layer and convert framework output to a stable SSE or chunked response shape.
## References
- Read [references/quick-start.md](./references/quick-start.md) for the extracted quick-start guidance, dependency examples, and advanced features summary.
\ No newline at end of file
- Read [references/agents.md](./references/agents.md) for the extracted official tutorial guidance on agent assembly, invocation, memory, hooks, interceptors, and streaming-related decisions.