using FastEndpoints;
using MediatR;
using RAG.Application.RagQA.Commands;
using RAG.Application.RagQA.DTOs;
namespace RAG.Api.Endpoints.RAG;
///
/// RAG 一次性问答端点(非流式)。返回完整答案 + 命中的来源片段,
/// 适合轻量查询或非交互场景;交互式前端优先用 /rag/stream 获得流式体验。
///
public class RAGQueryEndpoint(IMediator mediator) : Endpoint
{
public override void Configure()
{
Post("/rag/query");
AllowAnonymous();
}
public override async Task HandleAsync(RAGQueryRequest req, CancellationToken ct)
{
var result = await mediator.Send(new RAGQueryCommand(req.KnowledgeBaseId, req.Question), ct);
await Send.OkAsync(result, ct);
}
}
///
/// RAG 问答请求校验。/rag/query 与 /rag/stream 共用同一请求 DTO,故此校验对两个端点同时生效。
///
public class RAGQueryRequestValidator : Validator
{
public RAGQueryRequestValidator()
{
RuleFor(x => x.KnowledgeBaseId).NotEmpty().WithMessage("知识库 ID 不能为空");
RuleFor(x => x.Question)
.NotEmpty().WithMessage("问题不能为空")
.MaximumLength(1000).WithMessage("问题不能超过 1000 个字符");
}
}