AI应用生成平台:模型调用与工具集成
本文介绍了AI代码生成项目中MyBatis Flex与MyBatis Plus的区别及选择理由,以及策略模式和模板方法模式在代码解析与文件保存中的应用。项目通过LangChain4j集成AI大模型能力,实现模型调用、工具集成和结构化输出转换。智能路由系统根据用户需求自动选择最优代码生成方案。项目采用轻量级ORM框架MyBatis Flex,并利用设计模式优化代码结构,确保高效处理复杂业务逻辑。项目
·
三、模型调用与工具集成
项目仓库:https://github.com/vasc-language/ai-code-mother
项目预览:https://www.joinoai.cloud
13. MyBatis Flex 和 MyBatis Plus 的区别?为什么在项目中选择它?
核心区别
- 定位与风格:MyBatis Plus偏向“增强型ORM+脚手架”,提供
ServiceImpl
、自动填充、代码生成器、通用CRUD;MyBatis Flex更偏“下一代MyBatis增强DSL”,强调轻量、表达力强、对复杂查询(多表、子查询、动态列)支持更好。 - 查询DSL能力:
- Flex:
QueryWrapper
+TableDef
强类型列引用、链式拼装、多表 JOIN/子查询原生支持,复杂条件表达简洁; - Plus:
QueryWrapper
足以覆盖大多数单表/简单多表场景,复杂 JOIN 往往回落至 XML 或自定义插件。
- Flex:
- 运行期开销:
- Flex:更少的运行期拦截器与元对象处理,分页等以工具/方法形式提供,整体更“轻”;
- Plus:内置较多特性(自动填充、逻辑删除、分页拦截器等),开箱即用但运行期更“重”。
- 代码生成与生态:两者均有代码生成器;Flex 在表达复杂 SQL 时模板更简洁,Plus 在脚手架与社区资料上更丰富。
项目选择与理由
- 代码与依赖事实:本项目已引入
mybatis-flex-spring-boot3-starter
与mybatis-flex-codegen
,服务层大量使用com.mybatisflex.*
(见pom.xml
、service/impl
与mapper
)。 - 业务诉求:
- 需要在生成类业务中做灵活查询与分页,偏好简洁的强表达力 DSL;
- 保持运行期开销小、可控,方便与 LangChain4j、工作流并发调度协同;
- 复杂查询可直写 DSL/表定义而非大量 XML;
- 结论:选 MyBatis Flex,获得轻量、强 DSL、多表/子查询友好的特性,同时保留与 MyBatis 原生 XML 的互通弹性。
14. 什么是策略模式?你如何使用策略模式处理代码解析逻辑?
定义
- 策略模式通过在运行时选择不同“算法/策略”以完成同一类任务,避免在调用处充斥 if/else 或 switch,提升可扩展性与可测试性。
在本项目中的应用(代码解析)
- 背景:大模型输出既可能是 Markdown 代码块、也可能是分隔标记的多文件内容,或是工具流已将内容落盘;不同生成类型(HTML / MULTI_FILE / VUE_PROJECT)解析路径各异。
- 方案:定义统一策略接口与上下文执行器,根据生成类型或输出特征动态选择解析策略。
关键接口与约定(说明性签名):
interface CodeParseStrategy {
CodeParseResult parse(String rawStreamOrText);
}
final class CodeParseResult {
List<CodeFile> files; // 解析出的文件清单
String plainText; // 若需要的纯文本
}
// 典型策略
class MarkdownFenceCodeStrategy implements CodeParseStrategy {}
class MultiFileTaggedStrategy implements CodeParseStrategy {}
class ToolAwareNoopStrategy implements CodeParseStrategy {} // 工具已落盘,仅抽取摘要
// 选择器
class CodeParserExecutor {
CodeParseStrategy choose(CodeGenTypeEnum type, String content);
CodeParseResult execute(CodeGenTypeEnum type, String content);
}
选择规则示例:
VUE_PROJECT
且出现工具调用标记 →ToolAwareNoopStrategy
(以工具流为主、解析为辅)- 内容包含
fence code
→MarkdownFenceCodeStrategy
- 出现自定义文件分隔标记/JSON 计划 →
MultiFileTaggedStrategy
15. 什么是模板方法模式?你如何使用模板方法模式处理文件保存逻辑?
定义
- 模板方法在抽象基类中定义稳定流程骨架,将可变步骤留给子类实现(钩子/抽象方法),保证流程一致、实现差异可扩展。
在本项目中的应用(文件保存)
- 背景:HTML 单文件、传统多文件、Vue 工程三类保存步骤高度相似:校验 → 解析根目录 → 写盘(幂等/覆盖策略)→ 生成后处理(如依赖、构建)。
抽象流程(说明性签名):
abstract class AbstractCodeFileSaver {
public final SaveResult save(Long appId, List<CodeFile> files) {
preCheck(appId, files);
Path root = resolveRoot(appId);
writeFiles(root, files); // 统一处理:已存在且内容一致则跳过;不同则覆盖/新建
postProcess(root); // 如:生成 README、触发构建、生成预览链接
return summary(root, files); // 统一汇总
}
protected abstract void postProcess(Path root);
protected void preCheck(Long appId, List<CodeFile> files) {}
protected Path resolveRoot(Long appId) { /* 依据 appId 隔离 */ }
protected void writeFiles(Path root, List<CodeFile> files) { /* 幂等写入 */ }
}
class HtmlFileSaver extends AbstractCodeFileSaver { /* 精简后处理 */ }
class MultiFileProjectSaver extends AbstractCodeFileSaver { /* 校验目录结构 */ }
class VueProjectSaver extends AbstractCodeFileSaver { /* 依赖/构建钩子 */ }
错误处理策略:
- 写入采用“临时目录 → 原子替换”或“逐文件幂等”避免中途失败造成不一致;
- 捕获 IO 异常后回滚或标记失败,向前端流式回报失败详情;
- 对非法路径、越权写入做白名单校验。
16. LangChain4j 在项目中有什么作用?你是如何将 AI 大模型能力集成到业务代码中的?
作用
- 统一接入多家大模型(OpenAI/通义/百川等),提供对话、工具调用、流式回调、记忆、结构化输出等能力;
- 与 Spring 生态良好集成,便于在服务中以接口方式注入与调用。
集成方式
- 模型与流式:
ChatLanguageModel
/StreamingResponseHandler
对接流式生成,将 token 与工具事件映射为 SSE 事件; - 工具:通过
@Tool
描述工具签名,LangChain4j 负责生成/校验ToolExecutionRequest
; - 记忆:集成 Redis 作为
ChatMemoryStore
,用于短期会话记忆; - 服务封装:
AiCodeGeneratorService
将提示词工程、记忆、工具集合与模型实例组装为可复用服务; - 自定义流构建:
OpenAiStreamingResponseBuilder
用于对 OpenAI 风格增量消息进行工具信息组帧,完善事件粒度。
17. 如何实现将 AI 大模型的输出稳定地转换为结构化对象?
关键策略
- 强约束提示词:要求输出为 JSON/特定标签,并提供最小可行示例;
- 模式/Schema:基于目标 Java Bean 生成 JSON Schema 或约束字段(必填、枚举、范围);
- 解析与修复:先做快速 JSON 解析,失败则尝试“轻量修复”(补全括号、转义),仍失败则触发一次“Re-Ask”让模型纠偏;
- 校验与回退:用 Bean Validation(Jakarta Validation)做业务校验,不通过则降级为宽松解析或默认值策略;
- 幂等与可观测:落库前做去重/版本化,记录解析失败率、重试次数与样本。
说明性流程:
raw → detect fenced json → parse(JSON) → validate(bean) →
ok: return
fail: tryPatch → reParse →
ok: return
fail: reAsk(model, schemaHint) → parse → validate →
ok: return
fail: fallback(defaults/log)
LangChain4j 配合点:
- 使用结构化输出解析器/编解码器(基于 POJO 映射)与
AiServices
将回复直接映射为接口返回; - 在
StreamingResponseHandler
/普通响应回调中统一做解析与校验,减少散落逻辑。
18. 什么是 AI 智能路由?你如何利用 AI 根据用户需求自动选择最合适的代码生成方案?
定义
- 智能路由指根据用户意图、约束与环境,自动选择最合适的模型/生成类型/工具与执行路径的能力。
本项目实现
- 路由服务:
AiCodeGenTypeRoutingService#routeCodeGenType(String prompt)
返回CodeGenTypeEnum
与置信度; - 决策信号:
- 语义判断:小型分类模型或主模型 few-shot 分类(网页/多页工程/Vue 工程等);
- 约束判断:是否允许工具、是否需要构建步骤、是否需要多文件;
- 环境判断:预算、时延、历史成功率/失败率(监控指标)。
- 回退策略:
- 低置信度时降级为规则路由(例如包含
package.json
/vite
等关键词倾向于VUE_PROJECT
); - 生成失败自动换路由重试一次(如从
MULTI_FILE
→HTML
)。
- 低置信度时降级为规则路由(例如包含
19. 什么是 LangChain4j 的护航机制?你是如何利用输入拦截来防止恶意 Prompt 输入和注入攻击的?
护航机制理解
- 护航(Guardrails)指在提示词输入/模型输出/工具执行三个关键环节设置策略与拦截,确保安全、可控与合规。
输入侧拦截方案
- 规则过滤:对已知注入词(如“忽略所有指令/系统提示”“执行系统命令”“删除磁盘文件”等)做拒绝或降权处理;
- 角色隔离:将系统提示与用户输入物理分离,严禁用户覆盖系统消息;
- 模型审核:可选接入安全审核小模型/服务,对高风险输入打回并给出安全改写建议;
- 速率与配额:结合 Redisson 限流,防止暴力探测与滥用;
- 审计记录:对被拦截输入入库,便于后续规则迭代。
工程落点
- 在
AiCodeGeneratorFacade
的入口层引入PromptInputFilter
(拦截器/切面),统一做校验与打标; - 对通过校验的输入加“最小必要信息”原则重写,避免把路径、凭据等敏感信息直接暴露给模型;
- 前端也做基础校验,防止明显恶意 payload 进入后端。
20. 当 AI 大模型调用工具时,可能会陷入无限循环,你是如何避免这个问题的?
多层防护
- 提示词约束:在系统提示中明确“工具调用次数上限(如 ≤ 20)”“完成后必须调用【退出工具】”,并列出常见循环陷阱;
- 工具幂等:
FileWriteTool
等具备“内容相同跳过写入”的幂等策略,减少“写—读—再写”死循环的收益; - 运行期阈值:在服务端为每次会话维护
toolInvocationCount
,超阈值立即终止并返回提示; - 重复行为检测:对同一路径的重复写入/修改计数,超过阈值发出警告或终止;
- 工作流有穷:LangGraph4j 的图式编排不出现无出口环路,必要处添加超时与最大步数;
- 观测与告警:对异常长会话、异常工具密度设监控,触发报警并沉淀样本优化提示词。
21. AI 零代码应用生成项目中,你如何实现工具调用信息的流式输出?
架构与流程
- 控制器:
WorkflowSseController
暴露 SSE 接口,将模型流、工具事件映射为前端可消费的消息; - 流构建:
OpenAiStreamingResponseBuilder
/StreamingResponseHandler
在收到增量 token、ToolExecutionRequest
、ToolExecutionResult
时组装事件; - 前端消费:
EventSource
订阅并根据type
渲染(如AI_RESPONSE
、TOOL_REQUEST
、TOOL_EXECUTED
)。
事件示例(语义):
{ "type": "AI_RESPONSE", "content": "正在创建项目骨架..." }
{ "type": "TOOL_REQUEST", "tool": "write_file", "args": { "path": "src/App.vue" } }
{ "type": "TOOL_EXECUTED", "result": "已写入 128 行" }
细节与保证
- 有序性:对同一会话内事件递增编号,前端按序展示;
- 可靠性:SSE 心跳与断线重连;
- 安全性:工具参数脱敏(如绝对路径、凭据)。
📞 联系我们
如果您有任何问题或建议,请随时联系我们:
- 提交 Issue
- 发送邮件至: zrt3ljnygz@163.com
- 微信联系: Join2049
更多推荐
所有评论(0)