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
# 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
## Workflow
1.Confirm prerequisites before coding.
1.Build the smallest agent that solves the request.
JDK 17+ and Maven 3.8+ are the documented baseline. Default to environment variables for API keys, especially `AI_DASHSCOPE_API_KEY`.
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.
2.Configure the model first.
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.
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.
3.Add tools only when the agent must act.
For DashScope, initialize `DashScopeApi`, then create `DashScopeChatModel`. If you configure `DashScopeChatOptions`, set the model name explicitly before adding temperature and token settings.
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.
4.Choose prompt style deliberately.
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.
Use `systemPrompt(...)` for a compact role definition. Use `instruction(...)` for a longer task-specific directive.
5.Assemble `ReactAgent` from small, explicit pieces.
5.Pick the invocation mode based on the caller contract.
Start with `.name(...)`, `.model(...)`, `.systemPrompt(...)`, `.tools(...)`, and `.saver(...)`. Add `.outputType(...)`, `.outputSchema(...)`, or `.hooks(...)` only when the behavior requires them.
Use `call(...)` for the final answer. Use `invoke(...)` when the caller needs `OverAllState`, message history, or custom state.
6. Add memory deliberately.
6. Add conversation 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.
Use `MemorySaver`and reuse the same `threadId` in `RunnableConfig` for multi-turn chat. For production, prefer a persistent saver.
7.Choose response shaping explicitly.
7.Shape outputs only when the consumer requires it.
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.
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.
8.Add hooks, interceptors, or streaming only after the basic path works.
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.
Use `ModelCallLimitHook` to cap loops, interceptors for tool or prompt customization, and wrap streaming output in your own application contract.
## Implementation Defaults
## Implementation Defaults
- Keep API keys out of source code. Prefer environment variables and property placeholders.
- Keep API keys out of source code. Prefer environment variables and Spring properties.
- Keep tool interfaces boring and explicit. Tool names and descriptions become part of the model prompt, so avoid vague naming.
- Keep tools narrow and explicit. Tool names and descriptions directly affect model behavior.
- Prefer a focused system prompt over a long one. State role, available tools, and decision rules.
- Prefer the shortest prompt that enforces the needed behavior.
- Pass request-scoped metadata through `RunnableConfig.addMetadata(...)` when tools need user or tenant context.
- Pass request metadata through `RunnableConfig.addMetadata(...)` instead of globals.
- Reuse `threadId` for multi-turn chat. Change `threadId` to start a fresh conversation.
- Reuse `threadId` for multi-turn continuity. Change it for a fresh session.
- 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 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 the caller only needs the final assistant text, use `call(...)`.
- If a tool needs request metadata, add it to `RunnableConfig` and read it via `ToolContext`; do not hide it in globals.
- If the caller needs state, messages, or custom graph values, use `invoke(...)`.
- If the user wants follow-up questions to retain context, keep the same `threadId`.
- If follow-up requests must retain context, add `.saver(...)` and reuse `threadId`.
- If the user only needs the assistant text, call `agent.call(...)`; if they need message history or graph state, use `agent.invoke(...)`.
- If the agent must use runtime business context, pass it via `RunnableConfig` and read it through `ToolContext`.
- If an agent may loop on tool or model calls, add `ModelCallLimitHook`.
- 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
## References
- Read [references/quick-start.md](./references/quick-start.md) for the extracted quick-start guidance, dependency examples, and advanced features summary.
- Read [references/agents.md](./references/agents.md) for the extracted official tutorial guidance on agent assembly, invocation, memory, hooks, interceptors, and streaming-related decisions.