Files
liteFlow/docs/liteflow-react-agent-guide.md
2026-04-30 11:59:56 +08:00

28 KiB
Raw Blame History

LiteFlow ReAct Agent 使用指南

本文介绍如何在 LiteFlow 中使用 liteflow-react-agent,把 agentscope-java 的 ReActAgent 当作普通 LiteFlow 节点编排到 EL 链路中。

读完本文后,你应该能够:

  • 引入对应模型平台模块,并完成 liteflow.agent.* 配置;
  • 编写一个继承 ReActAgentComponent 的 Agent 组件;
  • 在 EL 中组合 Agent、普通节点、条件路由和并行节点
  • 正确理解 Session、memory、workspace、内置文件工具和 Shell 工具的边界。

当前仓库根版本:2.15.3.2

当前源码中 liteflow-react-agent 子模块的 maven.compiler.source / target17,根 compile-17+ profile 会在 JDK 17 及以上激活该模块。实际运行时还需要满足 agentscope-java 及具体模型 SDK 的运行要求。


1. 模块说明

liteflow-react-agent 是一个聚合模块,核心能力在 liteflow-react-agent-core,不同模型供应商由独立子模块提供便捷入口。

模块 作用
liteflow-react-agent-core ReActAgentComponentModelSpec 基础设施、Session 管理、memory 持久化、workspace 文件工具、受管 Shell 工具
liteflow-react-agent-openai OpenAI 官方 API + OpenAI 兼容协议,内置 DeepSeek、Kimi、GLM、MiniMax 便捷入口
liteflow-react-agent-anthropic Anthropic Claude 模型入口
liteflow-react-agent-gemini Google Gemini 模型入口
liteflow-react-agent-dashscope 阿里云 DashScope / Qwen 模型入口

业务项目通常只需要引入一个平台模块。平台模块会传递依赖 liteflow-react-agent-core


2. 快速开始

2.1 引入依赖

以 DeepSeek 这类 OpenAI 兼容平台为例:

<dependency>
    <groupId>com.yomahub</groupId>
    <artifactId>liteflow-react-agent-openai</artifactId>
    <version>${liteflow.version}</version>
</dependency>

如果一条应用里要同时使用多个模型平台,可以同时引入多个平台模块。

2.2 配置 LiteFlow 与 Agent

最小配置需要包含规则文件、workspace 根目录和模型凭据。生产环境建议先关闭 Shell 工具,再按需开启。

liteflow.rule-source=agent/flow.el.xml

liteflow.agent.workspace.root=/var/lib/liteflow/agent-workspaces
liteflow.agent.shell.mode=disabled

liteflow.agent.openai-compatible.deepseek.api-key=${DEEPSEEK_API_KEY}
liteflow.agent.openai-compatible.deepseek.base-url=https://api.deepseek.com/v1

liteflow.agent.workspace.root 是必填项。没有配置时,首次执行 Agent 组件会抛出:

AgentConfigException: liteflow.agent.workspace.root is required

2.3 编写 Agent 组件

Agent 组件继承 ReActAgentComponent,至少实现三个方法:

  • model(ctx):返回一个 ModelSpec<?>,声明使用哪个平台、哪个模型及可选高级参数;
  • systemPrompt(ctx):创建 Agent 时使用的系统提示词;
  • userPrompt(ctx):每次调用时发送给 Agent 的用户消息。
package demo.agent;

import com.yomahub.liteflow.agent.component.ReActAgentComponent;
import com.yomahub.liteflow.agent.component.ReActAgentContext;
import com.yomahub.liteflow.agent.model.ModelSpec;
import com.yomahub.liteflow.agent.openai.DeepSeek;
import org.springframework.stereotype.Component;

@Component("deepseekAgent")
public class DeepSeekAgentCmp extends ReActAgentComponent {

    @Override
    protected ModelSpec<?> model(ReActAgentContext ctx) {
        return DeepSeek.of("deepseek-chat");
    }

    @Override
    protected String systemPrompt(ReActAgentContext ctx) {
        return "你是一名简洁的中文助理,回答严格控制在两句话以内。";
    }

    @Override
    protected String userPrompt(ReActAgentContext ctx) {
        return String.valueOf(ctx.getSlot().getChainReqData(ctx.getSlot().getChainId()));
    }

    @Override
    protected boolean enableShellTool() { return false; }

    @Override
    protected boolean enableWorkspaceFileTools() { return false; }
}

2.4 在 EL 中编排

Agent 节点和普通 NodeComponent 一样使用:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
<flow>
    <chain name="deepseekChain">
        THEN(prepare, deepseekAgent, recordReply);
    </chain>
</flow>

调用方式也和普通 LiteFlow 链路一致:

LiteflowResponse response = flowExecutor.execute2Resp("deepseekChain", "用一句话介绍 LiteFlow");
if (response.isSuccess()) {
    Object reply = response.getSlot().getResponseData();
}

默认情况下Agent 回复会通过 reply.getTextContent() 写入 slot.responseData。如果后续节点希望从指定位置读取回复,可以覆写 handleReply(reply, ctx),或者像测试用例中的 RecordReplyCmp 一样把 responseData 转存到节点输出。


3. ReActAgentComponent 扩展点

ReActAgentComponent#process()final。框架在其中统一完成配置读取、Session 获取、加锁、Agent 懒构建、调用、回复处理和 memory 保存。业务侧通过覆写受保护方法定制行为。

方法 是否必须 默认行为 说明
model(ctx) 返回 ModelSpec<?>,由框架从 AgentConfig 解析凭据并构造 agentscope Model
systemPrompt(ctx) 返回系统提示词,同一 Session 首次构建 Agent 时调用
userPrompt(ctx) 返回本轮用户消息,每次 process() 都调用
tools(ctx) 空列表 注册自定义 @Tool 对象
resolveSessionId(slot) NanoIdSessionIdGenerator.generate(),格式 YYYYMMDD_NanoId(12) 决定本次调用使用哪个 Session默认每次调用生成新 ID单轮无状态
maxIterations() -1 返回正数时覆盖全局 defaults.max-iterations
enableShellTool() true 是否注册内置受管 Shell 工具
enableWorkspaceFileTools() true 是否注册内置 workspace 文件工具
hooks(ctx) 空列表 注册 agentscope Hook
enableReActLogging() liteflow.agent.logging.react-enabled(默认 true 是否注册内置 ReActLoggingHook,将 reason / act / error 事件写到日志
handleReply(reply, ctx) 写入 slot.responseData 自定义回复处理逻辑
buildModel(ctx) 委派 model(ctx).resolve(agentConfig()) 逃生舱:完全自行构造 agentscope Model

ReActAgentContext 提供三项执行上下文:

方法 说明
getSlot() 当前 LiteFlow Slot
getSessionId() 安全化后的 Session ID
getWorkspaceDir() 当前 Session 对应的 workspace 目录

注意:systemPrompt(ctx) 只在同一 sessionId 下首次构建 Agent 时调用;后续调用会复用同一个 Agent 实例和 memory。动态输入应放在 userPrompt(ctx) 中。


4. ModelSpec 与模型入口

4.1 核心设计

ModelSpec<SELF> 是所有平台模型描述符的基类。子类按"哪个平台 + 哪个模型 + 可选高级参数"三段式给出,框架负责从 AgentConfig 解析凭据并构造 agentscope Model

基类提供的共性参数(所有平台共享):

方法 类型 说明
temperature(double) Double 采样温度
topP(double) Double nucleus sampling
topK(int) Integer top-k sampling
maxTokens(int) Integer 最大输出 token
seed(long) Long 随机种子
stream(boolean) Boolean 是否流式
cacheControl(boolean) Boolean 缓存控制

所有参数均为可选,未设置时传 nullagentscope 使用服务端默认值。

4.2 平台入口一览

每个平台模块提供一个不可变入口类,通过静态 of(modelName) 方法返回平台对应的 Spec 子类。Spec 子类在基类共性参数之上暴露平台个性参数。

模块 入口类 Spec 子类 个性参数
liteflow-react-agent-openai OpenAI OpenAISpec reasoningEffort, frequencyPenalty, presencePenalty
liteflow-react-agent-openai DeepSeek OpenAICompatibleSpec 继承 OpenAISpec 全部参数
liteflow-react-agent-openai Kimi OpenAICompatibleSpec 同上
liteflow-react-agent-openai GLM OpenAICompatibleSpec 同上
liteflow-react-agent-openai Minimax OpenAICompatibleSpec 同上
liteflow-react-agent-openai OpenAICompatible OpenAICompatibleSpec 自定义 configKey,用于任意 OpenAI 兼容厂商
liteflow-react-agent-anthropic Anthropic AnthropicSpec thinking(budget, enabled)
liteflow-react-agent-anthropic AnthropicCompatible AnthropicSpec 自定义 configKey,用于 Anthropic 兼容网关
liteflow-react-agent-gemini Gemini GeminiSpec thinking(level, budget)
liteflow-react-agent-dashscope DashScope DashScopeSpec thinking(budget)

4.3 使用示例

OpenAI

@Override
protected ModelSpec<?> model(ReActAgentContext ctx) {
    return OpenAI.of("gpt-4o")
            .temperature(0.7)
            .maxTokens(1000)
            .stream(true);
}

凭据来源:liteflow.agent.openai.api-key

DeepSeekOpenAI 兼容):

@Override
protected ModelSpec<?> model(ReActAgentContext ctx) {
    return DeepSeek.of("deepseek-chat")
            .temperature(0.5);
}

凭据来源:liteflow.agent.openai-compatible.deepseek.api-key / base-url

自定义 OpenAI 兼容厂商:

@Override
protected ModelSpec<?> model(ReActAgentContext ctx) {
    return OpenAICompatible.custom("myvendor", "my-model")
            .temperature(0.7);
}

凭据来源:liteflow.agent.openai-compatible.myvendor.api-key / base-url

Anthropic Claude

@Override
protected ModelSpec<?> model(ReActAgentContext ctx) {
    return Anthropic.of("claude-sonnet-4-5")
            .temperature(0.5)
            .thinking(t -> t.budget(2000).enabled(true));
}

凭据来源:liteflow.agent.anthropic.api-key

Anthropic 兼容网关:

@Override
protected ModelSpec<?> model(ReActAgentContext ctx) {
    return AnthropicCompatible.custom("gateway", "claude-haiku");
}

凭据来源:liteflow.agent.anthropic-compatible.gateway.api-key / base-url

Google Gemini

@Override
protected ModelSpec<?> model(ReActAgentContext ctx) {
    return Gemini.of("gemini-2.5-flash")
            .thinking(t -> t.level("high").budget(1024));
}

凭据来源:liteflow.agent.gemini.api-key

阿里云 DashScope

@Override
protected ModelSpec<?> model(ReActAgentContext ctx) {
    return DashScope.of("qwen-plus")
            .thinking(t -> t.budget(2048));
}

凭据来源:liteflow.agent.dashscope.api-key

4.4 凭据配置结构

所有平台凭据都使用 PlatformCredential

字段 说明
apiKey API Key
baseUrl 可选,自定义网关或兼容端点
extra 可选,业务自定义键值

YAML 示例:

liteflow:
  agent:
    workspace:
      root: /var/lib/liteflow/agent-workspaces
    shell:
      mode: disabled
    openai:
      api-key: ${OPENAI_API_KEY}
    anthropic:
      api-key: ${ANTHROPIC_API_KEY}
    gemini:
      api-key: ${GEMINI_API_KEY}
    dashscope:
      api-key: ${DASHSCOPE_API_KEY}
    openai-compatible:
      deepseek:
        api-key: ${DEEPSEEK_API_KEY}
        base-url: https://api.deepseek.com/v1
      kimi:
        api-key: ${KIMI_API_KEY}
        base-url: https://api.moonshot.cn/v1
    anthropic-compatible:
      gateway:
        api-key: ${ANTHROPIC_GATEWAY_API_KEY}
        base-url: https://anthropic-gateway.example.com

4.5 凭据解析规则

框架内建两种凭据解析策略,通过 CredentialResolver 实现:

  • 头等平台OpenAI / Anthropic / Gemini / DashScope):从 AgentConfig 的单一 PlatformCredential 字段读取(如 cfg.getOpenai())。缺失时抛出 AgentConfigException,提示 liteflow.agent.<platform>.api-key
  • 兼容平台DeepSeek / Kimi / GLM / Minimax / OpenAICompatible.custom):从 AgentConfigMap<String, PlatformCredential> 中按 configKey 读取。缺失时抛出提示 liteflow.agent.<type>.<configKey>.api-key

4.6 逃生舱buildModel(ctx)

如果 ModelSpec 无法满足需求(例如需要传入 agentscope 原生的高级参数),可以直接覆写 buildModel(ctx),完全自行构造 agentscope Model

@Override
protected Model buildModel(ReActAgentContext ctx) {
    return OpenAIChatModel.builder()
            .apiKey(agentConfig().getOpenai().getApiKey())
            .modelName("gpt-4o")
            .generateOptions(GenerateOptions.builder()
                    .temperature(0.7)
                    .build())
            .stream(true)
            .build();
}

覆写 buildModel(ctx) 后,model(ctx) 不再被 process() 调用,但仍建议实现以保持 API 一致性。


5. Session 与 memory

5.1 Session 负责什么

每次执行 Agent 组件时,框架会通过 AgentSessionManager.acquire(sessionId) 获取一个 AgentSession。同一个 Session 会复用:

  • 同一个 ReActAgent 实例;
  • 同一个 Agent memory
  • 同一个 workspace 子目录;
  • 同一把 ReentrantLock

因此,同一个 sessionId 下的调用会串行执行,避免多线程同时修改同一份 memory。不同 sessionId 可以并行执行。

5.2 Session ID 从哪里来

默认实现是:

protected String resolveSessionId(Slot slot) {
    return NanoIdSessionIdGenerator.generate();
}

NanoIdSessionIdGenerator.generate() 返回 YYYYMMDD_<12 位 NanoId> 形式的字符串(例如 20260430_3F7K9PQRSTUV),每次调用都会生成一个全新的 ID。这意味着默认情况下"一次调用一个会话",会话之间互不共享 memory 与 workspace。如果要实现多轮对话必须覆写为业务会话 ID

@Override
protected String resolveSessionId(Slot slot) {
    ChatRequest req = slot.getChainReqData(slot.getChainId());
    return "chat-" + req.getUserId() + "-" + req.getConversationId();
}

Session ID 只允许直接使用 [a-zA-Z0-9_-]+。其他字符会被 URL 编码,并把 % 替换为 _,从而安全地用作目录名。空值会变成 _

5.3 JVM 热 Session 配置

liteflow.agent.session.* 控制当前 JVM 中热 Session 的缓存时间和数量:

配置项 默认值 说明
idle-timeout 30m Session 空闲多久后可被清理
cleanup-interval 1m 后台清理线程检查间隔,最低 20ms
max-sessions 10000 当前 JVM 中最多保留多少个热 Session

清理线程名为 liteflow-agent-session-cleaner。它只会清理已经超过 idle-timeout 且当前没有被加锁的 Session。

当 Session 数量超过 max-sessions 时,会按 lastActive 淘汰最旧的 JVM 内缓存。这个淘汰只移除热 Agent 实例,不删除 workspace也不删除 Redis、MySQL 或文件中的持久化记忆。

5.4 memory 持久化模式

liteflow.agent.session.memory.* 控制 Agent memory 保存在哪里。它和热 Session 缓存是两件事:热缓存决定当前 JVM 里保留多久memory 持久化决定重启或重新加载后能否恢复对话历史。

模式 含义 适用场景
JVM 默认值,使用 AgentScope 的 JVM 内 Session 单进程内多轮对话,进程退出后可丢失
NONE 不加载也不保存持久化 Session 不需要持久化;如需严格无状态,配合唯一 sessionId 使用
WORKSPACE_FILE 保存到 workspace.root/.agent-session/<sessionId>/ 本地文件持久化、开发测试、小规模部署
REDIS 使用用户提供的 Redis 客户端 Bean 多实例共享短期会话
MYSQL 使用用户提供的 DataSource Bean 需要数据库持久化和运维治理

通用开关:

配置项 默认值 说明
load-on-first-use true 当前 JVM 首次构建某个 Session 的 Agent 时,尝试恢复历史
save-after-call true 调用成功后保存记忆
save-on-error true 调用抛错时也尝试保存记忆

WORKSPACE_FILE 示例:

liteflow.agent.session.memory.mode=WORKSPACE_FILE
liteflow.agent.session.memory.load-on-first-use=true
liteflow.agent.session.memory.save-after-call=true
liteflow.agent.session.memory.save-on-error=true

REDIS 示例:

liteflow.agent.session.memory.mode=REDIS
liteflow.agent.session.memory.redis.bean-name=redissonClient
liteflow.agent.session.memory.redis.client-type=REDISSON
liteflow.agent.session.memory.redis.key-prefix=liteflow:agent:session

client-type 可选 REDISSONJEDISLETTUCE。LiteFlow 不创建 Redis 连接,必须由业务框架提供对应 Bean。

MYSQL 示例:

liteflow.agent.session.memory.mode=MYSQL
liteflow.agent.session.memory.mysql.data-source-bean-name=agentDataSource
liteflow.agent.session.memory.mysql.database-name=agentscope
liteflow.agent.session.memory.mysql.table-name=agentscope_sessions
liteflow.agent.session.memory.mysql.create-if-not-exist=false

LiteFlow 不创建 JDBC 连接池,DataSource 也需要由业务应用提供。


6. Workspace 与内置工具

6.1 Workspace 目录结构

每个 Session 都会在 liteflow.agent.workspace.root 下获得一个独立子目录:

/var/lib/liteflow/agent-workspaces/
├── chat-user-1-conv-1/
├── chat-user-1-conv-2/
└── .agent-session/

<sessionId>/ 是 Agent 工具读写文件的目录;.agent-session/ 只在 session.memory.mode=WORKSPACE_FILE 时创建,用于保存 AgentScope 的记忆文件。

6.2 Workspace 配置

配置项 默认值 说明
root 必填workspace 根目录
auto-create true 根目录不存在时是否自动创建
cleanup-on-session-expire true 空闲 Session 过期清理时是否删除对应 workspace 子目录
cleanup-on-jvm-shutdown false AgentSessionManager.close() 时是否删除当前存活 Session 的 workspace
max-file-bytes 10485760 read_file 单次最多读取的字节数
max-list-size 1000 list_files 单次最多返回的条目数

如果 Agent 生成的文件需要长期保留,例如报告、草稿、审计材料,应把 cleanup-on-session-expire 设为 false,并由业务侧做归档。

6.3 Workspace 文件工具

enableWorkspaceFileTools() 默认为 true。开启后,框架会注册 WorkspaceFileTools

工具名 行为
read_file 读取当前 Session workspace 内的文本文件,超过 max-file-bytes 时截断
write_file 覆盖写入文本文件,并自动创建父目录
list_files 列出目录内容,最多返回 max-list-size
delete_file 删除文件

所有路径都必须是相对路径。绝对路径或 .. 越界路径会被拒绝。

关闭方式:

@Override
protected boolean enableWorkspaceFileTools() {
    return false;
}

6.4 受管 Shell 工具

enableShellTool() 默认为 true。如果配置中的 liteflow.agent.shell.mode 不是 DISABLED,框架会注册 ManagedShellCommandTool,工具名为 execute_shell_command

Shell 工具在当前 Session workspace 下执行命令,使用空白符切分参数,并通过首 token 做白名单或黑名单判断。配置项如下:

配置项 默认值
mode WHITELIST
whitelist ls, cat, grep, find, head, tail, wc, sed, awk, python3, node
blacklist rm, sudo, shutdown, mkfs, dd
timeout 30s
max-output-bytes 1048576

生产环境建议默认关闭:

liteflow.agent.shell.mode=disabled

确实需要 Shell 时,优先使用 WHITELIST,并把白名单收窄到业务需要的命令。


6.5 ReAct 事件日志

框架内置 ReActLoggingHook,把 agent 的 reason / act / error 事件写入 SLF4J便于在终端直接观察 ReAct 推理过程:

事件 日志格式
PreReasoningEvent [agent:reason][sid] >>> model=... messages=N
PostReasoningEvent [agent:reason][sid] <<< text=... toolCalls=[...]
PreActingEvent [agent:act][sid] >>> tool=... input=...
PostActingEvent [agent:act][sid] <<< tool=... result=...
ErrorEvent [agent:error][sid] ...
  • 全局开关:liteflow.agent.logging.react-enabled(默认 true)。
  • 单组件开关:覆写 enableReActLogging() 强制返回 true / false
  • 输出 logger 名:com.yomahub.liteflow.agent.hook.ReActLoggingHook(可在 logback / log4j2 中独立调级)。
  • 文本字段超过 500 字会被截断为 ...(truncated)

如果业务侧已经通过自定义 Hook 处理事件流,建议关掉内置日志钩子以避免重复输出。


7. 常见编排方式

7.1 注册自定义工具

自定义工具是普通对象,方法上使用 agentscope 的 @Tool@ToolParam

package demo.agent.tool;

import io.agentscope.core.tool.Tool;
import io.agentscope.core.tool.ToolParam;

public class OrderTool {

    @Tool(name = "query_order_status", description = "Query order status by order number")
    public String query(@ToolParam(name = "orderNo") String orderNo) {
        return "订单 " + orderNo + " 正在处理中";
    }
}

在 Agent 组件里注册:

@Override
protected List<Object> tools(ReActAgentContext ctx) {
    return List.of(new OrderTool());
}

7.2 用 IF 做路由

<chain name="routerChain">
    THEN(
        prepare,
        IF(isMath, mathAgent, deepseekAgent),
        recordReply
    );
</chain>

isMath 可以是普通的 NodeBooleanComponentmathAgentdeepseekAgent 都是 ReActAgentComponent 子类。

7.3 用 WHEN 并行调用多个模型

<chain name="parallelChain">
    THEN(
        prepare,
        WHEN(deepseekAgent, dashscopeAgent).maxWaitSeconds(60),
        recordReply
    );
</chain>

如果两个 Agent 组件返回同一个 sessionId,它们会因为同一把 Session 锁而串行执行。要真正并行,确保不同组件使用不同 Session ID例如在 resolveSessionId 中拼入节点 ID

@Override
protected String resolveSessionId(Slot slot) {
    return getNodeId() + "-" + slot.getRequestId();
}

7.4 多轮对话

多轮对话的关键是让同一业务会话返回同一个 sessionId

@Override
protected String resolveSessionId(Slot slot) {
    ChatRequest req = slot.getChainReqData(slot.getChainId());
    return "chat-" + req.getUserId() + "-" + req.getConversationId();
}

只要多次执行传入相同的业务会话 IDAgent 就会在同一个 Session 下复用 memory。是否能跨 JVM 重启恢复,取决于 liteflow.agent.session.memory.mode


8. 完整配置速查

# LiteFlow 规则
liteflow.rule-source=agent/flow.el.xml

# workspace
liteflow.agent.workspace.root=/var/lib/liteflow/agent-workspaces
liteflow.agent.workspace.auto-create=true
liteflow.agent.workspace.cleanup-on-session-expire=true
liteflow.agent.workspace.cleanup-on-jvm-shutdown=false
liteflow.agent.workspace.max-file-bytes=10485760
liteflow.agent.workspace.max-list-size=1000

# 当前 JVM 中的热 Session
liteflow.agent.session.idle-timeout=30m
liteflow.agent.session.cleanup-interval=1m
liteflow.agent.session.max-sessions=10000

# Agent memory 持久化
liteflow.agent.session.memory.mode=JVM
liteflow.agent.session.memory.load-on-first-use=true
liteflow.agent.session.memory.save-after-call=true
liteflow.agent.session.memory.save-on-error=true

# Redis memory仅 mode=REDIS 时需要
liteflow.agent.session.memory.redis.bean-name=redissonClient
liteflow.agent.session.memory.redis.client-type=REDISSON
liteflow.agent.session.memory.redis.key-prefix=liteflow:agent:session

# MySQL memory仅 mode=MYSQL 时需要
liteflow.agent.session.memory.mysql.data-source-bean-name=agentDataSource
liteflow.agent.session.memory.mysql.database-name=agentscope
liteflow.agent.session.memory.mysql.table-name=agentscope_sessions
liteflow.agent.session.memory.mysql.create-if-not-exist=false

# Shell 工具
liteflow.agent.shell.mode=disabled
liteflow.agent.shell.timeout=30s
liteflow.agent.shell.max-output-bytes=1048576

# ReAct 内部事件日志reason / act / error
liteflow.agent.logging.react-enabled=true

# ReAct 默认最大迭代次数
liteflow.agent.defaults.max-iterations=15

# 平台凭据
liteflow.agent.openai.api-key=${OPENAI_API_KEY}
liteflow.agent.anthropic.api-key=${ANTHROPIC_API_KEY}
liteflow.agent.gemini.api-key=${GEMINI_API_KEY}
liteflow.agent.dashscope.api-key=${DASHSCOPE_API_KEY}
liteflow.agent.openai-compatible.deepseek.api-key=${DEEPSEEK_API_KEY}
liteflow.agent.openai-compatible.deepseek.base-url=https://api.deepseek.com/v1
liteflow.agent.anthropic-compatible.gateway.api-key=${ANTHROPIC_GATEWAY_API_KEY}
liteflow.agent.anthropic-compatible.gateway.base-url=https://anthropic-gateway.example.com

9. 安全建议

  1. 生产环境默认关闭 Shellliteflow.agent.shell.mode=disabled
  2. workspace.root 使用专门目录,不要和业务源码、日志、密钥目录混放。
  3. 不要直接把用户输入原样作为 Session ID。建议使用业务 ID 拼接、哈希或映射。
  4. API Key 使用环境变量、配置中心或密钥管理系统,不要写入代码仓库。
  5. 根据业务体量设置 max-file-bytesmax-output-bytestimeoutmax-sessions,避免 Agent 调用消耗不可控。
  6. 选择 REDISMYSQL 记忆模式时,连接 Bean 由业务应用提供,权限和网络访问也应由业务应用控制。

10. 故障排查

现象 常见原因 处理方式
liteflow.agent.workspace.root is required 未配置 workspace 根目录 配置 liteflow.agent.workspace.root
cannot create workspace root 根目录不可写,或父目录权限不足 换到应用可写目录,或提前创建并授权
workspace root does not exist auto-create=false 且目录不存在 提前创建目录,或开启 auto-create
Missing API key: please configure liteflow.agent.openai.api-key 对应平台凭据未配置 配置对应平台的 api-key
多轮对话没有记忆 默认 Session ID 由 NanoIdSessionIdGenerator 每次随机生成 覆写 resolveSessionId,返回稳定的业务会话 ID
重启后没有历史记忆 session.memory.mode=JVMNONE 改为 WORKSPACE_FILEREDISMYSQL
Redis 模式启动失败 未配置 Bean 名,或 Bean 类型与 client-type 不匹配 检查 bean-nameclient-type 和 classpath 依赖
MySQL 模式启动失败 未配置 DataSource Bean或 Bean 类型错误 配置正确的 data-source-bean-name
Shell 返回 command 'xxx' not allowed by whitelist 白名单模式下命令未放行 加入白名单,或继续保持禁用
path escapes workspace 文件工具收到绝对路径或越界路径 使用相对路径,并限制在当前 workspace 内
WHEN 中多个 Agent 看起来没有并行 多个组件共用了同一个 Session ID 让不同 Agent 返回不同 sessionId

11. 参考位置

  • Core 模块:liteflow-react-agent/liteflow-react-agent-core/
  • OpenAI 模块:liteflow-react-agent/liteflow-react-agent-openai/
  • Anthropic 模块:liteflow-react-agent/liteflow-react-agent-anthropic/
  • Gemini 模块:liteflow-react-agent/liteflow-react-agent-gemini/
  • DashScope 模块:liteflow-react-agent/liteflow-react-agent-dashscope/
  • 示例测试:liteflow-testcase-el/liteflow-testcase-el-react-agent/
  • 规则示例:liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/flow.el.xml