- name
- agentscope-java
- description
- Expert Java developer skill for AgentScope Java framework - a reactive, message-driven multi-agent system built on Project Reactor. Use when working with reactive programming, LLM integration, agent orchestration, multi-agent systems, or when the user mentions AgentScope, ReActAgent, Mono/Flux, Project Reactor, or Java agent development. Specializes in non-blocking code, tool integration, hooks, pipelines, and production-ready agent applications.
- license
- Apache-2.0
- compatibility
- Designed for Claude Code and Cursor. Requires Java 17+, Maven/Gradle, and familiarity with reactive programming concepts.
- metadata
- {"framework":"AgentScope Java","language":"Java 17+","paradigm":"Reactive Programming","core-library":"Project Reactor","version":"1.0"}
When the user asks you to write AgentScope Java code, follow these instructions carefully.
## CRITICAL RULES - NEVER VIOLATE THESE
**🚫 ABSOLUTELY FORBIDDEN:**
1. **NEVER use `.block()` in example code** - This is the #1 mistake. Only use `.block()` in `main()` methods or test code when explicitly creating a runnable example.
2. **NEVER use `Thread.sleep()`** - Use `Mono.delay()` instead.
3. **NEVER use `ThreadLocal`** - Use Reactor Context with `Mono.deferContextual()`.
4. **NEVER hardcode API keys** - Always use `System.getenv()`.
5. **NEVER ignore errors silently** - Always log errors and provide fallback values.
6. **NEVER use wrong import paths** - Shared model interfaces are in `io.agentscope.core.model.*`; provider models are in `io.agentscope.extensions.model.<provider>.*`.
**✅ ALWAYS DO:**
1. **Use `Mono` and `Flux`** for all asynchronous operations.
2. **Chain operations** with `.map()`, `.flatMap()`, `.then()`.
3. **Use Builder pattern** for creating agents, models, and messages.
4. **Include error handling** with `.onErrorResume()` or `.onErrorReturn()`.
5. **Add logging** with SLF4J for important operations.
6. **Use correct imports**: `import io.agentscope.extensions.model.dashscope.DashScopeChatModel;`
7. **Use correct APIs** (many methods don't exist or have changed):
- `toolkit.registerTool()` NOT `registerObject()`
- `toolkit.getToolNames()` NOT `getTools()`
- `event.getToolUse().getName()` NOT `getToolName()`
- `result.getOutput()` NOT `getContent()` (ToolResultBlock)
- `event.getToolResult()` NOT `getResult()` (PostActingEvent)
- `toolUse.getInput()` NOT `getArguments()` (ToolUseBlock)
- Model builder: NO `temperature()` method, use `defaultOptions(GenerateOptions.builder()...)`
- Hook events: NO `getMessages()`, `getResponse()`, `getIterationCount()`, `getThinkingBlock()` methods
- ToolResultBlock: NO `getToolUseName()` method, use `event.getToolUse().getName()` instead
- ToolResultBlock.getOutput() returns `List<ContentBlock>` NOT `String`, need to convert
- **@ToolParam format**: MUST use `@ToolParam(name = "x", description = "y")` NOT `@ToolParam(name="x")`
---
## WHEN GENERATING CODE
**FIRST: Identify the context**
- Is this a `main()` method or test code? → `.block()` is allowed (but add a warning comment)
- Is this agent logic, service method, or library code? → `.block()` is **FORBIDDEN**
**For every code example you provide:**
1. Check: Does it use `.block()`? → If yes in non-main/non-test code, **REWRITE IT**.
2. Check: Are all operations non-blocking? → If no, **FIX IT**.
3. Check: Does it have error handling? → If no, **ADD IT**.
4. Check: Are API keys from environment? → If no, **CHANGE IT**.
5. Check: Are imports correct? → If using provider models from `io.agentscope.core.model.*`, **FIX TO** `io.agentscope.extensions.model.<provider>.*`.
**Default code structure for agent logic:**
```java
// ✅ CORRECT - Non-blocking, reactive (use this pattern by default)
return model.generate(messages, null, null)
.map(response -> processResponse(response))
.onErrorResume(e -> {
log.error("Operation failed", e);
return Mono.just(fallbackValue);
});
// ❌ WRONG - Never generate this in agent logic
String result = model.generate(messages, null, null).block(); // DON'T DO THIS
```
**Only for main() methods (add warning comment):**
```java
public static void main(String[] args) {
// ⚠️ .block() is ONLY allowed here because this is a main() method
Msg response = agent.call(userMsg).block();
System.out.println(response.getTextContent());
}
```
---
## PROJECT SETUP
**When creating a new AgentScope project, use the correct Maven dependencies:**
### Maven Configuration (pom.xml)
**For production use (recommended):**
```xml
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- Use the latest stable release from Maven Central -->
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope</artifactId>
<version>1.0.12</version>
</dependency>
</dependencies>
```
**For local development (if working with source code):**
```xml
<properties>
<agentscope.version>1.0.12</agentscope.version>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-core</artifactId>
<version>${agentscope.version}</version>
</dependency>
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-extensions-model-dashscope</artifactId>
<version>${agentscope.version}</version>
</dependency>
</dependencies>
```
**⚠️ IMPORTANT: Version Selection**
- **Use `agentscope:1.0.12`** for production (stable, from Maven Central)
- **Use `agentscope-core:1.0.12`** only if you're developing AgentScope itself
- **NEVER use version `0.1.0-SNAPSHOT`** - this version doesn't exist
### ⚠️ CRITICAL: Common Dependency Mistakes
**❌ WRONG - These artifacts don't exist:**
```xml
<!-- DON'T use these - they don't exist -->
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-model-dashscope</artifactId> <!-- ❌ WRONG -->
</dependency>
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-model-openai</artifactId> <!-- ❌ WRONG -->
</dependency>
```
**❌ WRONG - These versions don't exist:**
```xml
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-core</artifactId>
<version>0.1.0-SNAPSHOT</version> <!-- ❌ WRONG - doesn't exist -->
</dependency>
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope</artifactId>
<version>0.1.0</version> <!-- ❌ WRONG - doesn't exist -->
</dependency>
```
**✅ CORRECT - Use the stable release:**
```xml
<!-- For production: use the stable release from Maven Central -->
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope</artifactId>
<version>1.0.12</version> <!-- ✅ CORRECT -->
</dependency>
```
### Available Model Classes (provider-specific extension modules)
```java
// DashScope (Alibaba Cloud)
import io.agentscope.extensions.model.dashscope.DashScopeChatModel;
// OpenAI
import io.agentscope.extensions.model.openai.OpenAIChatModel;
// Gemini (Google)
import io.agentscope.extensions.model.gemini.GeminiChatModel;
// Anthropic (Claude)
import io.agentscope.extensions.model.anthropic.AnthropicChatModel;
// Ollama (Local models)
import io.agentscope.extensions.model.ollama.OllamaChatModel;
```
### Optional Extensions
```xml
<!-- Long-term memory with Mem0 -->
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-extensions-mem0</artifactId>
<version>${agentscope.version}</version>
</dependency>
<!-- RAG with Dify -->
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-extensions-rag-dify</artifactId>
<version>${agentscope.version}</version>
</dependency>
```
---
## PROJECT OVERVIEW & ARCHITECTURE
AgentScope Java is a reactive, message-driven multi-agent framework built on **Project Reactor** and **Java 17+**.
### Core Abstractions
- **`Agent`**: The fundamental unit of execution. Most agents extend `AgentBase`.
- **`Msg`**: The message object exchanged between agents.
- **`Memory`**: Stores conversation history (`InMemoryMemory`, `LongTermMemory`).
- **`Toolkit` & `AgentTool`**: Defines capabilities the agent can use.
- **`Model`**: Interfaces with LLMs (OpenAI, DashScope, Gemini, Anthropic, etc.).
- **`Hook`**: Intercepts and modifies agent execution at various lifecycle points.
- **`Pipeline`**: Orchestrates multiple agents in sequential or parallel patterns.
### Reactive Nature
Almost all operations (agent calls, model inference, tool execution) return `Mono<T>` or `Flux<T>`.
### Key Design Principles
1. **Non-blocking**: All I/O operations are asynchronous
2. **Message-driven**: Agents communicate via immutable `Msg` objects
3. **Composable**: Agents and pipelines can be nested and combined
4. **Extensible**: Hooks and custom tools allow deep customization
---
## CODING STANDARDS & BEST PRACTICES
### 2.1 Java Version & Style
**Target Java 17 (LTS) for maximum compatibility:**
- Use **Java 17** features (Records, Switch expressions, Pattern Matching for instanceof, `var`, Sealed classes)
- **AVOID Java 21+ preview features** (pattern matching in switch, record patterns)
- Follow standard Java conventions (PascalCase for classes, camelCase for methods/variables)
- Use **Lombok** where appropriate (`@Data`, `@Builder` for DTOs/Messages)
- Prefer **immutability** for data classes
- Use **meaningful names** that reflect domain concepts
**⚠️ CRITICAL: Avoid Preview Features**
```java
// ❌ WRONG - Requires Java 21 with --enable-preview
return switch (event) {
case PreReasoningEvent e -> Mono.just(e); // Pattern matching in switch
default -> Mono.just(event);
};
// ✅ CORRECT - Java 17 compatible
if (event instanceof PreReasoningEvent e) { // Pattern matching for instanceof (Java 17)
return Mono.just(event);
} else {
return Mono.just(event);
}
```
### 2.2 Reactive Programming (Critical)
**⚠️ NEVER BLOCK IN AGENT LOGIC**
Blocking operations will break the reactive chain and cause performance issues.
**Rules:**
- ❌ **Never use `.block()`** in agent logic (only in `main` methods or tests)
- ✅ Use `Mono` for single results (e.g., `agent.call()`)
- ✅ Use `Flux` for streaming responses (e.g., `model.stream()`)
- ✅ Chain operations using `.map()`, `.flatMap()`, `.then()`
- ✅ Use `Mono.defer()` for lazy evaluation
- ✅ Use `Mono.deferContextual()` for reactive context access
**Example:**
```java
// ❌ WRONG - Blocking
public Mono<String> processData(String input) {
String result = externalService.call(input).block(); // DON'T DO THIS
return Mono.just(result);
}
// ✅ CORRECT - Non-blocking
public Mono<String> processData(String input) {
return externalService.call(input)
.map(this::transform)
.flatMap(this::validate);
}
```
### 2.3 Message Handling (`Msg`)
Create messages using the Builder pattern:
```java
Msg userMsg = Msg.builder()
.role(MsgRole.USER)
.content(TextBlock.builder().text("Hello").build())
.name("user")
.build();
```
**Content Blocks:**
- **`TextBlock`**: For text content
- **`ThinkingBlock`**: For Chain of Thought (CoT) reasoning
- **`ToolUseBlock`**: For tool calls
- **`ToolResultBlock`**: For tool outputs
**Helper Methods:**
```java
// Prefer safe helper methods
String text = msg.getTextContent(); // Safe, returns null if not found
// Avoid direct access
String text = msg.getContent().get(0).getText(); // May throw NPE
```
### 2.4 Implementing Agents
在 GitHub 查看