Tender-Agent 是一款专为工程、信息化服务及货物采购等领域打造的自动化竞标文档(标书)生成引擎。
在传统的投标技术方案编写中,企业通常面临以下痛点:
- 长文本生成瓶颈:单次让大语言模型(LLM)生成数十页的技术文档,极易触发上下文丢失、“幻觉”以及 HTTP 连接超时。
- 结构与规范失控:多人协作拼接导致行文风格迥异,且难以完全对齐招标文件的苛刻标准。
- 用户体验断层:传统的同步生成架构会导致前端处于漫长的盲等状态。
Tender-Agent 并非简单调用一次 LLM API,而是设计了一套严密的 Multi-Agent 协作流水线:
- 需求输入与模板推荐:系统接收招标需求,
TemplateRecommendAgent结合行业经验自动推荐最匹配的章节结构模板。 - 章节级语义拆解 (分块生成):将庞大的标书拆解为“总体方案”、“核心应答”、“实施计划”、“质量保障”、“售后运维”五大独立章节。
- 并发流式组装:启动 Java 21 虚拟线程,调度
ChapterStreamingAgent并发生成各个章节。 - 质量验收评分:全量文档生成后,交由专门的
QualityCheckAgent进行全局逻辑校验与质量打分。
深入 Tender-Agent 的底层源码,项目展现了极高的工程化水准:
- 🚀 Java 21 虚拟线程 (Virtual Threads) 并发加速
使用
Executors.newVirtualThreadPerTaskExecutor()彻底替代传统重量级线程池。系统能够以极低的资源消耗同时发状 5 个章节的 AI 生成任务,将标书产出耗时从几十分钟压缩至 1~2分钟。 - 🤖 LangChain4j 声明式代理架构
深度集成 LangChain4j 框架,通过
@UserMessage与@SystemMessage(fromResource = "...")将 Agent 行为定义与底层 Prompt 文件(如chapter-response-prompt.txt)优雅解耦。 - 🌊 全链路 SSE 流式响应机制
后端通过
SseEmitter配合虚拟线程回调,实现细粒度的流式推送(包含阶段进度analyzing,outlining,chapter_generating以及最终结果)。前端针对/streaming/接口去除了反向代理缓存,实现“所见即所生”的打字机体验。 - 💾 中间态持久化与容错隔离
在
StreamingTenderHarness调度层,每个章节的生成互相隔离,单章节报错不会导致整站崩溃。且生成过程中实时落库(TenderDoc与GenerationLog),确保流式中断后数据可溯源。
- Backend: Spring Boot 3.2, Java 21, LangChain4j (适配 DeepSeek / OpenAI 协议)
- Database / ORM: MySQL 8.0, MyBatis-Plus
- Frontend: Vue 3 (Composition API), Vite, Pinia, Vue Router 4
- API 通信: RESTful API + SSE (Server-Sent Events)
下方展示了系统在流式生成阶段的硬核底层交互逻辑:
sequenceDiagram
participant User as "Frontend"
participant Controller as "StreamingTenderController"
participant Service as "StreamingTenderServiceImpl"
participant Harness as "StreamingTenderHarness"
participant Agent as "ChapterStreamingAgent"
participant DB as "MySQL (tender_db)"
User->>Controller: POST /api/streaming/tender/generate (reqId, templateId)
Controller->>Service: generateStreaming()
Service->>DB: insert TenderDoc (status="generating")
Service->>Harness: Thread.startVirtualThread(...)
rect rgb(240, 245, 250)
Note over Harness, Agent: VirtualThreadPerTaskExecutor (并发执行 5 大章节)
par Chapter 1 to 5
Harness->>Agent: generateChapter(title, chapter-prompt.txt)
Agent-->>Harness: stream chunks -> full content
Harness->>DB: updateById(TenderDoc) [实时追加内容]
Harness->>User: emitter.send(event="generation", JSON)
end
end
Harness->>Service: QualityCheckAgent.checkQuality()
Service->>DB: updateById(TenderDoc, status="generated")
Service->>DB: updateById(GenerationLog, status="success")
Harness->>User: emitter.send(event="done")
User-->>Controller: Close SSE Connection
- JDK: Java 21+ (必须,依赖 Virtual Threads)
- Node.js: v18.0.0+
- Database: MySQL 8.0+
进入 backend/src/main/resources/ 目录,执行 schema.sql 脚本。
该脚本会自动创建所需的五张核心表并初始化行业测试模板:
tech_requirement(技术需求表)template/requirement_template(模板表)tender_doc(标书主表)doc_version(版本控制表)generation_log(生成监控日志)
核心配置项均在 application.yml 中维护。请根据实际情况替换配置:
spring:
datasource:
url: jdbc:mysql://localhost:3306/tender_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: tender_user # 建议修改
password: tender_password # 建议修改
tender:
ai:
# 大模型 API Key 配置,支持通过环境变量传入
api-key: ${DEEPSEEK_API_KEY:your-default-key}
# 兼容 OpenAI 格式的模型接口地址
base-url: https://api.deepseek.com/v1
timeout-seconds: 300
max-retries: 3前端 Vite 配置已默认开启了跨域代理。针对 SSE 流式接口,系统已做了特殊的反缓冲处理以保障流式通信不被拦截:
// Vite Proxy 配置节选
proxyReq.setHeader('Connection', 'keep-alive')
proxyReq.setHeader('Cache-Control', 'no-cache')
proxyRes.headers['x-accel-buffering'] = 'no' // 关键:禁用 Nginx/代理的缓冲机制cd backend
# 使用 Maven 构建并启动
mvn clean install
mvn spring-boot:run后端服务默认运行在 http://localhost:8080。接口文档支持通过 http://localhost:8080/doc.html (Knife4j) 访问。
cd frontend
# 安装依赖
npm install
# 启动本地开发服务
npm run dev前端服务默认运行在 http://localhost:5173。
- 录入需求:在前端【需求录入】页面,输入你的项目名称(如“智慧园区信息化建设项目”),并选择对应的行业类型。
- 选择模板:进入【模板库】,系统根据你的行业特征,推荐“信息化服务类技术响应模板”。
- 沉浸式生成:点击生成标书。系统跳转至【生成大盘】。得益于 SSE 与虚拟线程的加持,你可以实时看到系统的思考步骤进度条,并在几秒钟内看到 5 个章节同时开始流式输出最终的 Markdown 文本。
- 归档与导出:生成结束后,系统自动附带一份基于
QualityCheckAgent的质量检测评估单。确认无误后可直接在页面中预览或归档。