Spring Boot使用dialogflow进行意图识别

457 阅读2分钟

1. 准备工作

1.1 创建 Dialogflow 代理

  1. 访问 Dialogflow 控制台

  2. 创建新代理(Agent),选择语言(如中文)。

  3. 定义意图(Intents):

    • 示例意图BookFlight

      • 训练短语:我想订机票预订去北京的航班
    • 默认回退意图:用于处理未识别的输入。

1.2 获取 Google Cloud 凭据

  1. 在 Google Cloud 控制台 创建项目。

  2. 启用 Dialogflow API

  3. 生成服务账号密钥(JSON 文件):

    • 导航到 IAM 与管理 → 服务账号,创建账号并赋予 Dialogflow API Admin 权限。
    • 下载 JSON 密钥文件(如 dialogflow-key.json)。

2. Spring Boot 集成代码

2.1 添加依赖

在 pom.xml 中添加 Dialogflow 客户端库和 Spring Web:

<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-dialogflow</artifactId>
    <version>4.32.0</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2.2 配置凭据

将下载的 dialogflow-key.json 文件放到 src/main/resources 目录下,并在 application.properties 中配置:

# Dialogflow 配置
dialogflow.project-id=your-google-cloud-project-id
dialogflow.credentials-path=classpath:dialogflow-key.json

2.3 创建 Dialogflow 服务类

import com.google.cloud.dialogflow.v2.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;

@Service
public class DialogflowService {

    @Value("${dialogflow.project-id}")
    private String projectId;

    @Value("${dialogflow.credentials-path}")
    private Resource credentialsPath;

    private SessionsClient sessionsClient;

    // 初始化 Dialogflow 客户端
    @PostConstruct
    public void init() throws IOException {
        // 加载凭据文件
        SessionsSettings settings = SessionsSettings.newBuilder()
                .setCredentialsProvider(() -> 
                    GoogleCredentials.fromStream(credentialsPath.getInputStream())
                ).build();

        // 创建会话客户端
        sessionsClient = SessionsClient.create(settings);
    }

    // 检测用户输入的意图
    public String detectIntent(String text) {
        // 构建会话路径(使用随机会话ID)
        SessionName session = SessionName.of(projectId, "unique-session-id");

        // 构建输入文本请求
        TextInput.Builder textInput = TextInput.newBuilder()
                .setText(text)
                .setLanguageCode("zh-CN"); // 中文

        QueryInput queryInput = QueryInput.newBuilder()
                .setText(textInput)
                .build();

        // 发送请求并获取响应
        DetectIntentResponse response = sessionsClient.detectIntent(session, queryInput);

        // 提取意图名称
        return response.getQueryResult().getIntent().getDisplayName();
    }
}

2.4 创建 REST 控制器

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/intent")
public class IntentController {

    @Autowired
    private DialogflowService dialogflowService;

    @PostMapping("/detect")
    public String detectIntent(@RequestBody String userInput) {
        return dialogflowService.detectIntent(userInput);
    }
}

3. 测试接口

3.1 使用 Postman 发送请求

  • URLPOST http://localhost:8080/api/intent/detect

  • Body (JSON):

    "我想订去上海的机票"
    
  • 响应:

    "BookFlight"
    

3.2 测试未识别的意图

输入 "今天天气怎么样?"(假设未定义天气意图),Dialogflow 会返回默认回退意图(如 Default Fallback Intent)。


4. 高级配置

4.1 处理复杂响应(如参数提取)

修改 DialogflowService 以提取意图参数:

public Map<String, String> detectIntentWithParameters(String text) {
    DetectIntentResponse response = sessionsClient.detectIntent(session, queryInput);
    QueryResult queryResult = response.getQueryResult();

    Map<String, String> params = new HashMap<>();
    queryResult.getParameters().getFieldsMap().forEach((key, value) -> 
        params.put(key, value.getStringValue())
    );

    return Map.of(
        "intent", queryResult.getIntent().getDisplayName(),
        "parameters", params.toString()
    );
}

4.2 自定义会话ID

为每个用户分配唯一会话ID,保留上下文:

public String detectIntent(String text, String sessionId) {
    SessionName session = SessionName.of(projectId, sessionId);
    // 其余逻辑相同
}

5. 常见问题解决

  1. 凭据加载失败

    • 检查 dialogflow-key.json 文件路径是否正确。
    • 确保服务账号有足够权限。
  2. 意图匹配错误

    • 在 Dialogflow 控制台中增加更多训练短语。
    • 调整意图的优先级和上下文。
  3. 高延迟

    • 使用 Dialogflow 的 区域端点(如 asia-east1)。

完整项目结构

src/main/java
├── config            // 配置类(可选)
├── controller        // IntentController
├── service           // DialogflowService
└── Application.java  // Spring Boot 主类

通过以上步骤,即可在 Spring Boot 中快速集成 Dialogflow 实现意图识别。