Solon AI Agent 框架中，Agent（智能体） 是执行任务的核心单元。它不仅是对大语言模型（LLM）的封装，更是集成了 状态管理（Session）、工具调用（Tools）、长短记忆（History） 和 工作流控制（Flow） 的自治实体。




### 1、智能体接口（Agent）

智能体（Agent）是 Solon AI Agent 的最小协作单元。在设计上，它具有“多重身份”以满足不同层级的交互需求：



| 维度 | 属性 | 描述 | 视角 |
| -------- | -------- | -------- | -------- |
| 身份           | name     | 唯一标识：智能体在团队中的名字     |  同伴视角（你是谁）  |
|                  |  role     | 智能体角色职责（用于 Prompt 提示与协作分发参考）     | 主管视角（你能干啥）   |
|                  | profile     | 交互契约：定义能力画像、输入限制等约束条件     | 团队视角（如何用你）   |
|       |       |       |   |
| 行为     | call     | 核心逻辑：具体的推理与工具执行过程     | 执行视角  |
|                | run     | 节点驱动：由团队协议（TeamProtocol）驱动的生命周期管理     |  框架视角  |


Agent 接口继承自 AgentHandler 和 NamedTaskComponent，支持在 Solon Flow 工作流中自动化运行。

### 2、快速开始：定制一个智能体

您可以直接实现 Agent 接口来定义特定的业务逻辑：

```java
Agent coder = new Agent() {
    @Override public String name() { return "Coder"; }
    @Override public String role() { return "负责编写核心业务代码"; }
    @Override public AssistantMessage call(Prompt prompt, AgentSession session) {
        return ChatMessage.ofAssistant("代码已提交: login.java");
    }
};
```

框架内置实现：

* SimpleAgent: 基础智能体，适用于简单的指令响应。
* ReActAgent: 具备“思考-行动-观察”循环的自反思智能体，支持工具调用。
* TeamAgent: 复合智能体，负责指挥成员按协议（如 A2A）进行协作。


### 3、智能体构建样例

SimpleAgent （简单智能体）

```java
SimpleAgent resumeAgent = SimpleAgent.of(chatModel)
                .name("ResumeExtractor")
                .role("简历信息提取器")
                .instruction("请从用户提供的文本中提取关键信息")
                .outputSchema(ResumeInfo.class)
                .build();
```

ReActAgent （自我反思型智能体）

```java
ReActAgent illustrator = ReActAgent.of(chatModel)
        .name("illustrator")
        .role("首席矢量插画专家（负责视觉风格定义）")
        .profile(p -> p.capabilityAdd("矢量插画", "色彩心理学")
                .modeAdd("text", "image") 
                .metaPut("engine", "Nano Banana")
                .style("极简主义"))
        .instruction("1. 擅长极简主义风格，通过‘色彩心理学’选择能引起情感共鸣的主色调。\n" +
                     "2. 针对用户需求，先构思视觉隐喻（Thought），再定义具体的视觉规格。\n" +
                     "3. 如果需要生成图片，请输出具体的 Prompt 给底层图像引擎（Nano Banana）。\n" +
                     "4. 最终输出应包含：风格描述、配色方案、圆角/线条规范，以及可选的图片描述。")
        .build();
```

TeamAgent （团队协作型智能体）

```java
TeamAgent team = TeamAgent.of(chatModel)
                .name("sequential_pipeline")
                .protocol(TeamProtocols.SEQUENTIAL)
                .agentAdd(extractor, converter, polisher)
                .build();
```


### 4、具体接口参考

```java
package org.noear.solon.ai.agent;

import org.noear.snack4.Feature;
import org.noear.snack4.ONode;
import org.noear.solon.ai.agent.session.InMemoryAgentSession;
import org.noear.solon.ai.agent.team.NodeChunk;
import org.noear.solon.ai.agent.team.TeamInterceptor;
import org.noear.solon.ai.agent.team.TeamTrace;
import org.noear.solon.ai.agent.util.AgentUtil;
import org.noear.solon.ai.chat.ChatRole;
import org.noear.solon.ai.chat.message.AssistantMessage;
import org.noear.solon.ai.chat.prompt.Prompt;
import org.noear.solon.core.util.RankEntity;
import org.noear.solon.core.util.SnelUtil;
import org.noear.solon.flow.FlowContext;
import org.noear.solon.flow.NamedTaskComponent;
import org.noear.solon.flow.Node;
import org.noear.solon.lang.Nullable;
import org.noear.solon.lang.Preview;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 智能体核心接口
 *
 * <p>定义 AI 智能体的行为契约。作为 {@link NamedTaskComponent} 接入 Solon Flow，实现分布式协作。</p>
 */
public interface Agent<Req extends AgentRequest<Req, Resp>, Resp extends AgentResponse> extends AgentHandler, NamedTaskComponent {
    static final Logger LOG = LoggerFactory.getLogger(Agent.class);

    /**
     * 智能体名称（唯一标识）
     */
    String name();

    /**
     * 智能体角色职责（用于 Prompt 提示与协作分发参考）
     */
    String role();

    /**
     * 生成动态角色描述
     *
     * @param context 流程上下文（支持使用 context.vars 渲染模板）
     */
    default String roleFor(FlowContext context) {
        if (context == null) {
            return role();
        }

        return SnelUtil.render(role(), context.vars());
    }

    /**
     * 智能体档案（能力画像与交互契约）
     */
    default AgentProfile profile() {
        return null;
    }

    /**
     * 生成动态元数据（用于协作传递）
     */
    default ONode toMetadata(FlowContext context) {
        return AgentUtil.toMetadataNode(this, context);
    }

    /**
     * 创建基于 Prompt 的请求构建器
     */
    default Req prompt(Prompt prompt) {
        throw new UnsupportedOperationException();
    }

    /**
     * 创建基于字符串指令的请求构建器
     */
    default Req prompt(String prompt) {
        throw new UnsupportedOperationException();
    }

    /**
     * 创建恢复请求构建器（用于从会话中恢复 prompt 执行）
     */
    default Req prompt() {
        throw new UnsupportedOperationException();
    }

    /**
     * 恢复执行（用于从会话中恢复 prompt 执行）
     */
    default AssistantMessage call(AgentSession session) throws Throwable {
        return call(null, session);
    }

    /**
     * 指定指令的任务执行（开始新任务）
     *
     * @param prompt  显式指令（如果为 null；则继续之前的话题）
     * @param session 会话上下文
     */
    AssistantMessage call(@Nullable Prompt prompt, AgentSession session) throws Throwable;

    /**
     * Solon Flow 节点运行实现
     * <p>处理 Session 初始化、协议注入、推理执行及轨迹同步。</p>
     */
    @Override
    default void run(FlowContext context, Node node) throws Throwable {
        // 1. 获取或初始化会话
        AgentSession session = context.computeIfAbsent(KEY_SESSION, k -> new InMemoryAgentSession("tmp"));

        // 2. 处理团队协作轨迹与拦截
        String traceKey = context.getAs(KEY_CURRENT_TEAM_TRACE_KEY);
        TeamTrace trace = (traceKey != null) ? context.getAs(traceKey) : null;

        if (trace != null) {
            trace.setLastAgentName(this.name());
            for (RankEntity<TeamInterceptor> item : trace.getOptions().getInterceptors()) {
                if (item.target.shouldAgentContinue(trace, this) == false) {
                    trace.addRecord(ChatRole.ASSISTANT, name(),
                            "[Skipped] Cancelled by " + item.target.getClass().getSimpleName(), 0);

                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Agent [{}] execution skipped by interceptor: {}", name(), item.target.getClass().getSimpleName());
                    }
                    return;
                }
            }
        }

        // 3. 准备提示词并执行推理
        final Prompt effectivePrompt;
        if (trace != null) {
            effectivePrompt = trace.getProtocol().prepareAgentPrompt(trace, this, trace.getWorkingMemory(), trace.getConfig().getLocale());
        } else {
            effectivePrompt = null;
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("Agent [{}] start calling...", name());
        }

        long start = System.currentTimeMillis();
        AssistantMessage msg = call(effectivePrompt, session);

        if (LOG.isTraceEnabled()) {
            LOG.trace("Agent [{}] return message: {}",
                    name(),
                    ONode.serialize(msg, Feature.Write_PrettyFormat, Feature.Write_EnumUsingName));
        }

        long duration = System.currentTimeMillis() - start;

        // 4. 同步执行轨迹与结果处理
        if (trace != null) {
            //状态实时化
            if(trace.getOptions().getStreamSink() != null){
                trace.getOptions().getStreamSink().next(new NodeChunk(node, trace, msg));
            }

            //协议后处理集成
            String rawContent = (msg.getContent() == null) ? "" : msg.getContent().trim();
            String finalResult = trace.getProtocol().resolveAgentOutput(trace, this, rawContent);

            if (finalResult == null || finalResult.isEmpty()) {
                finalResult = "Agent [" + name() + "] processed but returned no textual content.";
            }

            //指标自动化同步
            trace.addRecord(ChatRole.ASSISTANT, name(), finalResult, duration);

            // 执行后置回调
            trace.getProtocol().onAgentEnd(trace, this);
            trace.getOptions().getInterceptors().forEach(item -> item.target.onAgentEnd(trace, this));
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("Agent [{}] call completed in {}ms", name(), duration);
        }
    }

    // --- Context Keys ---
    static String KEY_CURRENT_UNIT_TRACE_KEY = "_current_unit_trace_key_";
    static String KEY_CURRENT_TEAM_TRACE_KEY = "_current_team_trace_key_";
    static String KEY_SESSION = "_SESSION_";
    static String KEY_PROTOCOL = "_PROTOCOL_";

    static String META_AGENT = "_agent_";

    // --- Node IDs ---
    static String ID_START = "start";
    static String ID_END = "end";
}
```