用 Solon AI 4.0 的 ReActAgent 把大模型接到真实工具上

2026-07-05 40 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

只会聊天的 LLM 很快会碰到天花板:它不知道实时库存,不能查订单,也不能调用内部接口。ReActAgent 的价值在于把“推理”和“行动”放进同一个循环里:模型先判断下一步要做什么,再调用工具,拿到结果后继续修正判断,直到给出可用答案。

这类 Agent 不适合拿来包装所有需求,但很适合处理“需要多步判断 + 外部数据 + 动态反馈”的任务,比如客服查单、运营分析、内部知识检索、告警诊断。

ReActAgent 不只是多挂几个函数

传统 LLM 调用工具时,经常像一次性问答:用户问问题,模型决定调一个函数,然后直接回答。ReAct 的关键差异是循环:

  1. Thought:模型分析当前目标和已知信息。
  2. Action:选择一个外部工具,例如查数据库、调 HTTP API、检索文档。
  3. Observation:工具返回真实结果。
  4. Repeat:模型根据结果继续推理,必要时再次行动。
  5. Final Answer:输出最终答案或执行建议。

这让 Agent 能处理不确定性。例如用户问“这个客户最近投诉多吗,要不要升级处理?”模型可能先查客户信息,再查近 30 天工单,再根据投诉频率和订单金额给出判断。它不是凭空生成一个听起来合理的答案,而是围绕真实反馈调整行为。

生产级 Agent 的边界:工具比提示词更重要

ReActAgent 的上限通常不在提示词,而在工具设计。工具要小、稳定、可审计。一个“万能查询数据库”工具听起来方便,但在生产环境里风险很大:权限难控、SQL 注入难防、结果不可预测。

更稳的做法是把工具设计成业务动作:

  • getCustomerProfile(customerId):查客户等级、账号状态。
  • listRecentTickets(customerId, days):查近期工单。
  • createEscalation(ticketId, reason):创建升级记录。
  • searchKnowledgeBase(query):检索内部知识库。

每个工具都应该有清晰输入、有限输出、超时设置和日志。Agent 可以聪明,但工具必须像普通后端接口一样可测试。

可以这样实践:一个客服升级判断 Agent

下面示例按“Solon AI 4.0 ReActAgent + Java 工具函数”的典型方式演示。不同版本的包名、Builder API 可能略有差异,接入时请以你项目中的 Solon AI 4.0 依赖为准;核心结构可以直接改造:定义工具、注册给 Agent、让 Agent 在推理循环中调用。

假设你有一个客服系统,希望 Agent 根据客户资料和近期工单判断是否需要升级处理。

// CustomerSupportAgent.java
// 示例为可改造骨架:请把 ReActAgent、ToolRegistry、ChatModel 的包名替换为你项目中 Solon AI 4.0 的实际类。

import java.util.List;
import java.util.Map;

public class CustomerSupportAgent {
    public static void main(String[] args) {
        ChatModel model = ChatModel.builder()
                .apiKey(System.getenv("LLM_API_KEY"))
                .model("gpt-4o-mini")
                .build();

        ToolRegistry tools = ToolRegistry.builder()
                .add("getCustomerProfile", CustomerSupportAgent::getCustomerProfile)
                .add("listRecentTickets", CustomerSupportAgent::listRecentTickets)
                .add("createEscalation", CustomerSupportAgent::createEscalation)
                .build();

        ReActAgent agent = ReActAgent.builder()
                .model(model)
                .tools(tools)
                .systemPrompt("你是客服升级判断助手。必须先查询客户资料和近期工单,再判断是否升级。不要编造数据。")
                .maxSteps(6)
                .build();

        String answer = agent.run("客户 C10086 说最近问题一直没人解决,需要主管介入。请判断是否升级,并说明原因。");
        System.out.println(answer);
    }

    static Map<String, Object> getCustomerProfile(Map<String, Object> input) {
        String customerId = String.valueOf(input.get("customerId"));
        // 生产环境应调用 CRM 或数据库,这里用固定数据演示。
        return Map.of(
                "customerId", customerId,
                "level", "enterprise",
                "monthlySpend", 128000,
                "status", "active"
        );
    }

    static List<Map<String, Object>> listRecentTickets(Map<String, Object> input) {
        return List.of(
                Map.of("ticketId", "T-901", "daysAgo", 3, "category", "payment", "status", "open"),
                Map.of("ticketId", "T-877", "daysAgo", 9, "category", "api_error", "status", "resolved"),
                Map.of("ticketId", "T-832", "daysAgo", 18, "category", "api_error", "status", "resolved")
        );
    }

    static Map<String, Object> createEscalation(Map<String, Object> input) {
        return Map.of(
                "escalationId", "E-20240501-001",
                "status", "created",
                "reason", input.getOrDefault("reason", "manual review required")
        );
    }
}

运行前要改三处:

  • ChatModelToolRegistryReActAgent 替换为你项目里 Solon AI 4.0 的实际类名和 import。
  • 设置模型密钥:export LLM_API_KEY=你的密钥
  • 把示例里的固定数据替换成真实 CRM、工单系统或内部 HTTP API。

如果工具是 HTTP 服务,也可以先用一个稳定的本地 API 模拟:

curl -X POST http://localhost:8080/tools/customer-profile \
  -H 'Content-Type: application/json' \
  -d '{"customerId":"C10086"}'

返回建议保持短而结构化,方便 Agent 消化:

{
  "customerId": "C10086",
  "level": "enterprise",
  "monthlySpend": 128000,
  "status": "active"
}

Prompt 要约束决策过程,而不是替业务背锅

ReActAgent 的系统提示词应该明确“什么时候必须查工具”“哪些事不能做”“最终答案格式是什么”。例如:

你是客服升级判断助手。
规则:
1. 判断升级前必须调用 getCustomerProfile 和 listRecentTickets。
2. 没有工具返回的数据时,不得猜测客户等级、消费金额、工单数量。
3. 只有 enterprise 客户且 30 天内存在未关闭高优先级问题时,才允许调用 createEscalation。
4. 最终回答包含:结论、依据、已执行动作、需要人工确认的风险。

这个提示词不会让模型“更聪明”,但会让它更守规矩。生产系统里还应在工具层二次校验,比如 createEscalation 必须检查调用者权限、客户状态和幂等键,不能只相信模型的判断。

上线前的检查清单

ReActAgent 适合把 LLM 接入业务闭环,但它也会放大系统复杂度。上线前至少检查这些点:

  • 工具是否有超时、重试、限流和审计日志。
  • Agent 是否设置 maxSteps,避免无限推理和成本失控。
  • 高风险动作是否有人审或后端强校验,例如退款、删数据、发通知。
  • 工具返回是否结构化,避免把大段日志直接塞回模型。
  • 是否记录完整轨迹:用户问题、模型动作、工具输入输出、最终答案。

可以从“只读工具”开始,比如查询订单、检索知识库、汇总工单。等轨迹稳定、误调用率可接受,再逐步开放写操作。ReActAgent 真正有价值的地方不是让模型显得像人在思考,而是让每一步行动都能落在可观察、可回滚、可治理的工程边界里。


相关推荐