项目名称:AI 简历魔法师(Resume Wizard)
技术栈:Spring Boot 3.3.5 + Spring AI 1.1.2 + Spring AI Alibaba 1.1.2.1 + PostgreSQL + pgvector + DashScope
核心能力:上下文记忆、RAG、语音交互、智能工具调用
最后更新:2026 年 5 月


写在前面

从零搭建一个 AI Agent 项目,刚开始感觉会挺难,但实际体验下来,借助 Spring AI Alibaba 框架,整个过程会比想象中顺畅许多。
本文记录我从环境搭建到功能实现,一步步完成一个兼具 上下文记忆、RAG、语音及智能工具调用能力 的“AI 简历魔法师” Agent。


目录


一、初识 Spring AI 与 Spring AI Alibaba

在动手写代码之前,有必要先理清这两个框架的关系和各自定位。

Spring AI 是 Spring 社区推出的面向 AI 应用开发的统一抽象层。它的核心定位是为 Java 开发者提供一套标准化的 API,涵盖 Chat Model、Embedding、Vector Store、Tool Calling、MCP 等通用能力。无论底层模型是 OpenAI、Ollama 还是通义千问,Spring AI 都能用一套统一的接口来屏蔽差异,实现模型的“可插拔”。

spring ai文档地址:https://spring.io/projects/spring-ai

Spring AI Alibaba 则是在 Spring AI 的基础上,由阿里云开源的增强扩展框架。它专门针对阿里云百炼平台和国内模型生态做了深度适配,提供了开箱即用的通义系列模型接入、Agent 工作流编排、多模态能力(文本、图片、语音)、可观测性、网关等一系列企业级特性。

如果把 Spring AI 比作“标准能力框架”,那 Spring AI Alibaba 就是“更适合国内模型接入场景的落地方案”——它向下兼容 Spring AI 的完整 API 标准,向上针对阿里云生态做了大量增强。

spring ai alibaba文档地址:https://java2ai.com/docs/quick-start

Spring AI Alibaba 1.1.2.0 版本已于 2026 年 2 月正式发布,底层 Spring AI 同步升级至 1.1.2,新增了 Agent Skills 渐进式披露、多智能体并行执行(支持 Routing、Supervisor、Handoffs 等模式)、Graph 并行聚合(AllOf / AnyOf)、异步工具执行等重磅能力。本文的项目搭建将基于 1.1.2.1 版本进行。


二、项目目标:做一个怎样的 Agent?

在搭建之前,一个关键问题是:这个 Agent 要解决什么具体问题?

为了让 Demo 有明确的业务指向,我们设计了一个名为 “AI 简历魔法师(Resume Wizard)” 的智能体,它的核心能力如下:

  • 简历文档解析:支持上传 PDF、Markdown 格式的简历,自动提取文本内容
  • 知识库检索(RAG):将优秀简历模板、面试技巧文档向量化存入 pgvector,实现语义检索
  • 智能工具调用:Agent 可自动调用“行业关键词查询”和“岗位匹配度评分”两个工具,每次调用自动记录到数据库,便于审计追溯
  • 持久化记忆:跨会话记住用户的简历信息和历史优化记录,服务重启不丢失
  • 语音交互:支持 TTS 文字转语音(通义 CosyVoice)和 ASR 语音转文字(通义 Paraformer)

三、环境准备与项目初始化

3.1 环境要求

组件 版本要求 说明
JDK 17+ 必须
Spring Boot 3.3.5 父 POM
Spring AI 1.1.4 BOM 统一管理版本
Spring AI Alibaba 1.1.2.0 DashScope Starter
PostgreSQL 15+ 需安装 pgvector 扩展
Maven 3.8+ 项目构建工具

3.2 获取 DashScope API Key

在接入任何通义系列模型之前,首先需要获取 API Key。这一步很简单:

  1. 访问阿里云百炼控制台:https://bailian.console.aliyun.com
  2. 注册 / 登录阿里云账号,开通“百炼大模型推理”服务(阿里云有免费模型额度,提供文本、语音、向量、图像等模型,其中文本模型每个提供100万token的额度,其余模态模型也有一定额度)
  3. 在“密钥管理”页签创建 API Key

安全提醒:不要把 API Key 硬编码在代码或配置文件里。最佳实践是存为系统环境变量 DASHSCOPE_API_KEY

export DASHSCOPE_API_KEY=你的真实Key

3.3 Maven 依赖引入

pom.xml 中引入核心依赖。推荐使用 BOM 统一管理版本:

<properties>
    <java.version>17</java.version>
    <spring-ai.version>1.1.4</spring-ai.version>
    <spring-ai-alibaba.version>1.1.2.0</spring-ai-alibaba.version>
</properties>

<dependencyManagement>
    <dependencies>
        <!-- Spring AI BOM -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>${spring-ai.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!-- Spring AI Alibaba Agent Framework -->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-agent-framework</artifactId>
            <version>${spring-ai-alibaba.version}</version>
        </dependency>

        <!-- 阿里云 DashScope 相关依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
            <version>${spring-ai-alibaba.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

核心依赖清单及其作用:

依赖 作用
spring-ai-alibaba-starter-dashscope 核心 starter,DashScope 对话 / 向量 / 语音模型自动配置
spring-ai-starter-vector-store-pgvector PGVector 向量存储自动配置
spring-ai-starter-model-chat-memory-repository-jdbc JDBC 聊天记忆持久化
spring-boot-starter-jdbc + postgresql 数据库连接驱动
mybatis-plus-spring-boot3-starter (3.5.5) 手动管理业务表
tika-core + tika-parsers-standard-package (2.9.2) PDF / Markdown 文档解析

📌 注意:Spring AI 相关的依赖包可能需要添加 Spring Milestones 仓库才能正常下载:

<repository>
    <id>spring-milestones</id>
    <url>https://repo.spring.io/milestone</url>
</repository>

四、核心配置:application.yml

配置是 Spring AI Alibaba 项目的心脏,Model、VectorStore、ChatMemory 都依赖这里的配置:

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/agent_db
    username: agent_user
    password: agent_password

  ai:
    dashscope:
      api-key: ${DASHSCOPE_API_KEY}        # 从环境变量获取,不硬编码!
      chat:
        options:
          model: qwen-plus                   # 对话模型
          temperature: 0.7
      embedding:
        options:
          model: text-embedding-v1           # 向量模型
      audio:
        speech:
          options:
            model: cosyvoice-v1              # TTS 语音合成
        transcription:
          options:
            model: paraformer-v1             # ASR 语音识别

    vectorstore:
      pgvector:
        index-type: HNSW                     # 高性能向量索引
        distance-type: COSINE_DISTANCE       # 余弦相似度
        initialize-schema: false             # 关闭自动建表,手动管理

mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true

配置要点解读

  • api-key: ${DASHSCOPE_API_KEY}:从环境变量取值,安全合规
  • model: qwen-plus:性价比之选,也可用 qwen-turbo(更便宜)或 qwen-max(更强)
  • initialize-schema: false:框架不自动建表,下文会统一用 SQL 脚本手动建表

五、PostgreSQL + pgvector 环境搭建

项目中所有数据(业务表、向量存储、聊天记忆)统一存储在同一个 PostgreSQL 数据库中。

5.1 一键启动(Docker Compose)

version: '3.8'
services:
  postgres:
    image: pgvector/pgvector:pg15
    container_name: agent-postgres
    environment:
      POSTGRES_DB: agent_db
      POSTGRES_USER: agent_user
      POSTGRES_PASSWORD: agent_password
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql

执行 docker-compose up -d 即可启动数据库。

5.2 手动建表脚本

为确保数据架构完全可控,本项目使用 SQL 脚本手动创建全部 6 张表:

-- 安装 pgvector 必需的三个扩展
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS hstore;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- 1. 会话表:管理用户与 Agent 的对话会话
CREATE TABLE IF NOT EXISTS agent_conversation (
    id              VARCHAR(64) PRIMARY KEY,
    user_id         VARCHAR(64) NOT NULL,
    title           VARCHAR(255),
    status          VARCHAR(20) DEFAULT 'active',
    created_at      TIMESTAMP DEFAULT now(),
    updated_at      TIMESTAMP DEFAULT now()
);

-- 2. 聊天历史表:完整聊天记录归档
CREATE TABLE IF NOT EXISTS chat_history (
    id              BIGSERIAL PRIMARY KEY,
    conversation_id VARCHAR(64) NOT NULL REFERENCES agent_conversation(id),
    role            VARCHAR(20) NOT NULL,
    content         TEXT NOT NULL,
    metadata        JSONB,
    created_at      TIMESTAMP DEFAULT now()
);

-- 3. 知识文档表:管理 RAG 知识库的原始文档
CREATE TABLE IF NOT EXISTS knowledge_document (
    id              BIGSERIAL PRIMARY KEY,
    title           VARCHAR(500) NOT NULL,
    content         TEXT NOT NULL,
    file_type       VARCHAR(50),
    chunk_count     INT DEFAULT 0,
    created_at      TIMESTAMP DEFAULT now()
);

-- 4. 工具调用记录表:追溯 Agent 的每次工具调用
CREATE TABLE IF NOT EXISTS tool_invocation (
    id              BIGSERIAL PRIMARY KEY,
    conversation_id VARCHAR(64) NOT NULL,
    tool_name       VARCHAR(100) NOT NULL,
    input_json      JSONB,
    output_json     JSONB,
    error_message   TEXT,
    duration_ms     BIGINT,
    metadata        JSONB,
    created_at      TIMESTAMP DEFAULT now()
);

-- 5. 向量存储表:pgvector 扩展表
CREATE TABLE IF NOT EXISTS vector_store (
    id              uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
    content         text,
    metadata        json,
    embedding       vector(1536)    -- text-embedding-v1 输出维度
);
CREATE INDEX ON vector_store USING HNSW (embedding vector_cosine_ops);

-- 6. 聊天记忆表:供 JdbcChatMemoryRepository 使用
CREATE TABLE IF NOT EXISTS chat_memory (
    id              VARCHAR(255) PRIMARY KEY,
    messages        BYTEA
);

为什么是 1536 维? text-embedding-v1 模型输出的向量维度默认为 1536,所以建表时 vector(1536) 必须与之对应。


六、编码实战:逐步实现 Agent 各项能力

项目采用标准的 Spring Boot 工程结构,严格遵循阿里巴巴 Java 开发手册的分层规范。核心包结构如下:

com.example.agentdemo
├── entity/              # MyBatis-Plus 实体,@TableName 映射表名
├── mapper/              # MyBatis-Plus BaseMapper 接口
├── config/              # ChatMemory、ChatClient、AppConfig 等配置
├── service/             # 业务逻辑层
│   ├── AgentService         # 核心 Agent 编排
│   ├── KnowledgeService     # 文档加载、分块、向量入库
│   ├── ResumeTools          # @Tool 工具方法
│   └── ChatHistoryService   # 聊天历史归档
└── controller/          # REST 接口层
    ├── ChatController       # 对话 API
    ├── ResumeController     # 简历上传与优化 API
    └── AudioController      # 语音交互 API

6.1 MyBatis-Plus 实体映射规范

所有实体类使用 @Data(Lombok)、@TableName 指定表名、@TableId 声明主键策略。时间字段统一用 LocalDateTime,JSON 字段在实体中用 String 存储,序列化由 Service 层处理。

6.2 聊天记忆配置:从短时记忆到长时记忆

这是 Agent 上下文能力的核心。Spring AI 提供了 ChatMemory 抽象,通过不同的 ChatMemoryRepository 实现来切换记忆模式:

@Configuration
public class ChatMemoryConfig {
    /**
     * 长时记忆:使用 JDBC 持久化到 PostgreSQL
     * 服务重启不丢失,支持分布式部署
     */
    @Bean
    public ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) {
        return MessageWindowChatMemory.builder()
                .chatMemoryRepository(chatMemoryRepository)
                .maxMessages(20)   // 滑动窗口:保留最近 20 条消息
                .build();
    }
}

记忆演化路线

  • 阶段一InMemoryChatMemory — 内存存储,重启即丢失,适合开发调试
  • 阶段二JdbcChatMemoryRepository — 持久化到 chat_memory 表,生产推荐

6.3 组装 ChatClient:Advisor 链 + 工具注册

ChatClient 是与 AI 模型交互的统一入口,通过 Advisor 链 来注入记忆和拦截请求:

@Configuration
public class ChatClientConfig {
    @Bean
    public ChatClient chatClient(ChatClient.Builder builder,
                                 ChatMemory chatMemory,
                                 ResumeTools resumeTools) {
        return builder
                .defaultSystem("""
                    你是 AI 简历魔法师,专精于简历优化与面试辅导。
                    你可以分析简历强弱项,查询行业关键词,
                    评估岗位匹配度,并给出具体修改建议。
                    """)
                .defaultTools(resumeTools)       // 注册工具函数
                .defaultAdvisors(
                    new MessageChatMemoryAdvisor(chatMemory),  // 记忆增强
                    new SimpleLoggerAdvisor()                  // 日志记录
                )
                .build();
    }
}

Advisor 链执行流程

  1. MessageChatMemoryAdvisor → 根据 conversationId 从数据库加载历史消息注入 Prompt
  2. SimpleLoggerAdvisor → 记录请求 / 响应日志,方便调试
  3. 最后将本轮对话保存回 chat_memory

6.4 工具调用:@Tool 注解 + 全量元数据记录

Spring AI Alibaba 支持通过 @Tool 注解定义工具函数,Agent 在对话中可自动判断是否调用某个工具,真正实现了 Function Calling 模式。

以本项目中的两个工具为例:

工具一:行业关键词查询
根据行业名称返回该行业简历应包含的关键词列表。

工具二:简历岗位匹配度评分
传入简历全文和目标岗位描述,返回匹配度评分。

关键设计:工具调用全量记录。为了让每次工具调用可追溯,需要实现一个通用的记录模板,在每次工具执行时自动写入 tool_invocation 表,包含:

  • conversation_id:关联的会话 ID
  • tool_name:工具名称
  • input_json:调用输入参数(JSON 序列化)
  • output_json:调用返回结果
  • duration_ms:执行耗时
  • metadata:扩展元数据(可存放 traceId 等)

上下文传递机制:由于 @Tool 方法无法直接获取当前会话的 conversationId,需要借助 ThreadLocalAgentService 中设置上下文:

// AgentService.chat() 入口
ToolContextHolder.set(conversationId);
try {
    return chatClient.prompt().user(userMessage)
            .advisors(a -> a.param("chat_memory_conversation_id", conversationId))
            .call().content();
} finally {
    ToolContextHolder.clear();
}

6.5 知识库文档加载与 RAG

这是知识库检索(RAG)的完整实现链路:文档上传 → 文本提取 → 分块 → 向量化 → 存入 pgvector → 语义检索

文档解析:使用 Apache Tika 无缝支持 PDF、Markdown、TXT 等多种格式的文本提取。

分块策略:用 TokenTextSplitter 按 Token 数量分块(建议 chunkSize=500, overlap=50),保证语义片段的完整性。

向量化存储:调用 VectorStore.add(chunks) 自动通过 DashScope 的 text-embedding-v1 模型计算向量,然后存入 pgvector 的 vector_store 表。

6.6 语音交互

Spring AI Alibaba 对语音交互提供了开箱即用的支持——SpeechModel 接口用于 TTS(文本转语音,底层为通义 CosyVoice),以及 DashScopeAudioTranscriptionModel 用于 ASR(语音转文字,底层为通义 Paraformer),两者都通过一行配置即可接入。


七、接口测试与验证

启动应用后(务必先启动 PostgreSQL),可以通过以下命令验证各功能模块:

# 1. 上传简历 PDF
curl -X POST http://localhost:8080/api/resume/upload   -F "file=@my_resume.pdf"

# 2. 开启优化对话(验证工具调用)
curl -X POST http://localhost:8080/api/resume/optimize   -H "Content-Type: application/x-www-form-urlencoded"   -d "conversationId=user001&message=我想应聘Java工程师,请优化我的简历"

# 3. 验证长期记忆(重启服务后再次对话)
curl -X POST http://localhost:8080/api/resume/optimize   -H "Content-Type: application/x-www-form-urlencoded"   -d "conversationId=user001&message=上一轮你建议我补充什么技能?"
# 预期:Agent 能回忆上下文并给出准确答复

# 4. 检查工具调用记录
psql -d agent_db -c "SELECT tool_name, input_json, output_json FROM tool_invocation;"

# 5. TTS 文字转语音
curl -X POST http://localhost:8080/api/audio/tts   -H "Content-Type: application/json"   -d '{"text":"你好,我是AI简历魔法师"}' --output output.mp3

验证要点

  • 上传 PDF 后 vector_store 表有新数据,knowledge_document 表有记录
  • 对话中 Agent 可自动调用行业关键词查询和匹配度评分工具
  • tool_invocation 表中存在完整的调用记录,用于后续审计和技术回溯
  • 重启服务后使用相同 conversationId 对话,Agent 仍能回忆之前的上下文信息

八、技术全景图回顾

整个项目的技术架构如下:

┌─────────────────────────────────────────────────────────────┐
│                  AI 简历魔法师 (Resume Wizard)              │
├─────────────────────────────────────────────────────────────┤
│  REST API 层:    /api/chat/*   /api/resume/*   /api/audio/* │
├─────────────────────────────────────────────────────────────┤
│  Advisor 链:     MessageChatMemoryAdvisor → SimpleLoggerAdvisor│
├─────────────────────────────────────────────────────────────┤
│  DashScope 模型:  qwen-plus │ text-embedding-v1 │ cosyvoice │
│                                               │ paraformer  │
├─────────────────────────────────────────────────────────────┤
│  PostgreSQL + pgvector (同一数据库统一存储)                  │
│  ├─ chat_memory        (JDBC 聊天记忆,持久化)               │
│  ├─ vector_store       (RAG 文档向量,HNSW 索引)             │
│  ├─ chat_history       (完整聊天记录归档)                    │
│  ├─ agent_conversation (会话管理)                            │
│  ├─ knowledge_document (知识文档元数据)                      │
│  └─ tool_invocation    (工具调用追溯,metadata 全量记录)     │
└─────────────────────────────────────────────────────────────┘

九、总结与展望

通过本文的逐步指导,我们成功搭建了一个具备六大核心能力的 Agent 智能体。在此基础上可以进一步扩展:比如引入 Spring AI Alibaba 新版本中的并行执行并行聚合(AllOf / AnyOf)策略实现多智能体协作,集成 Nacos 实现服务发现与配置管理,或者对接 MCP(Model Context Protocol)让 Agent 与外部工具服务进行标准化交互。

Spring AI Alibaba 框架极大地降低了 Java 开发者构建 AI Agent 的门槛——你不需要学习 Python、不需要从零封装 API,用 Spring Boot 的“约定大于配置”理念就能快速跑通一个智能体。希望本文能为你的 AI 开发之旅提供一个扎实的起点。如果有任何问题或建议,欢迎在评论区交流!


这篇文章是我记录自己使用spring-ai-alibaba框架进行搭建agent demo的过程,感谢您的观看

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐