1. 项目缘起:从"什么都想试"到"选一条路走通"
今年AI圈子最不缺的就是新东西,每周都有新模型、新框架、新应用冒出来。年初我给自己定了个调子:与其跟风追每个热点,不如亲手把一个AI项目从零做到能用、能跑、能维护。这篇文章想分享的,就是这大半年折腾下来我个人项目落地的完整路径——从模型选型、本地部署、应用框架,到Agent实践和提示词工程,再到最后收尾工程化时踩过的坑。
先说结论:个人做AI项目,最大的风险不是技术难,而是范围失控。模型换了一个又一个,框架试了一堆,最后发现什么都没有真正跑起来。我的选择是砍掉一切暂时用不上的东西,只保留一条最核心的链路:本地大模型推理 + 一个统一的应用开发框架 + 若干可复用的Agent组件。整条链路跑通之后,再把精力花在提示词打磨和内容生成类功能上,收益反而明显得多。
适合谁来参考这篇文章?
- 刚入门AI应用开发、想在本地搭一套环境但不知道从哪下手的开发者
- 已经用过API但觉得成本太高、想切本地部署的团队或个人
- 在AI Agent和提示词工程之间反复横跳、找不到聚焦点的朋友
- 想做AI短剧、AI视频、AI漫剧这类内容生成产品,但不知道怎么控制生成质量的内容创作者
这篇文章不会讲大模型底层的数学原理,也不会贴几十页框架文档,我把重点放在"个人实际把这些东西拼起来"的过程上,每一步都说明当时的选型理由和实测体会。
2. 本地模型部署:先把"地基"打牢
做AI项目,最影响后续效率的决定就是模型部署方式。我在早期同时试过纯云端API和完全本地推理,后来确定了一套混合策略:核心功能走本地模型,突发高负载任务才临时调云端API兜底。
2.1 硬件选型和量化级别的选择
本地部署的第一步是弄清楚手里的硬件能跑什么级别的模型。
我自己的机器配置是AMD Ryzen 9 5950X(16核32线程)、64GB内存、一张RTX 4090 24GB。这套配置在个人开发者里算比较舒服的,但也不是说没有4090就不能玩。关键在于模型的量化级别:
| 模型规模 | 显存需求(INT8量化) | 显存需求(INT4量化) | 推荐配置 |
|---|---|---|---|
| 7B~8B | 10GB~12GB | 6GB~8GB | 16GB显存或者至少32GB内存跑CPU推理 |
| 13B~14B | 16GB~20GB | 8GB~12GB | 24GB显存(4090/3090) |
| 30B~34B | 32GB~40GB | 16GB~20GB | 2张24GB显卡或纯CPU+大内存硬扛 |
| 70B级别 | 不推荐单消费卡 | 32GB+ | 多卡或量化到3bit勉强 |
我最初踩过一个典型新手坑:直接下载了一个70B的Q4量化模型,想着24GB显存肯定能塞进去。结果权重确实放进了显存,但上下文一长就直接爆显存,连推理都没法正常跑完。后来老老实实用32B的Q4量化模型作为主力,7B作为日常快速实验用的模型。
2.2 推理框架的选择与对比
本地模型灵魂其实不在模型本身,而在推理框架。同样的模型在不同的推理框架上跑,性能和易用性差距非常大。我试过三个主流方案:
- Ollama:上手最快,一条命令就能把模型拉下来跑,适合验证想法。但对并发请求的支持和自定义调度策略不够细,做多用户服务时不太够用。
- vLLM:吞吐量极高,默认支持Continuous Batching,适合部署成真正的高并发服务。缺点是显存管理策略偏激进,配置不当时容易把显存占满。
- llama.cpp:跨平台兼容性极强,纯CPU环境下也能跑,是"老机器救星"。缺点是作为正式服务时需要自己封装一层API接口。
我的最终选择是Ollama(开发调试)+ vLLM(生产服务)双轨并行。调试的时候用Ollama快速跑单条请求,确认模型输出没问题后,再用vLLM起一个正式服务挂到后端。
2.3 上下文长度的取舍
上下文长度是本地部署中最容易被忽视的参数。很多个人项目跑着跑着就发现生成质量下降,排查很久才发现是上下文窗口被塞满了,早期信息被截断。
我的实测经验是:别把模型支持的max context当成可以随便用的长度。以32B模型为例,虽然理论支持128K上下文,但在24GB显存下,实际超过16K之后生成速度会显著下降,超过32K甚至会OOM。个人项目默认设置为8K到16K比较稳妥,真有长文档处理需求就分段处理,而不是一次性塞进去。
启动vLLM服务时的参考参数:
python -m vllm.entrypoints.openai.api_server \ --model /data/models/Qwen2.5-32B-Instruct-GPTQ-Int4 \ --served-model-name local-qwen-32b \ --tensor-parallel-size 1 \ --max-model-len 16384 \ --gpu-memory-utilization 0.92 \ --host 0.0.0.0 \ --port 8000这几个参数我强调一下:
--gpu-memory-utilization如果设成0.98,碰到长上下文容易直接爆显存;0.92留出一点余量反而更稳。--max-model-len按实际需求来,不要一上来就拉到最大,生成速度会直线下降。--served-model-name这个名字是给上层API调用用的,跟原模型名称解耦,方便以后换底模。
3. 应用框架选型:Spring AI 与本地服务的组合
模型服务跑起来只是第一步,真正让项目变成产品的是应用层。我把项目主体后端选在Java生态,自然要面对一个选择:是直接用HTTP客户端调模型API,还是引入专门的AI应用框架。
3.1 为什么选了Spring AI
最初我是直接用HttpClient手写请求封装,模型调用分散在业务代码里。没多久问题就暴露了:prompt模板到处拼接、模型服务地址散落各处、切换模型时全线崩溃。
后来引入Spring AI之后,整个结构清晰了很多。Spring AI做的事情有点像给AI开发提供了一套标准化的数据访问层——它屏蔽了不同模型提供商之间的API差异,让我用同样的代码风格去调Qwen、DeepSeek或者其他模型。带来的直接收益有三个:
- Prompt模板集中管理:用统一的模板文件定义prompt结构,业务侧只传动态参数,不再手工拼字符串。
- 模型切换成本极低:配置文件里换一个模型标识,甚至能做到灰度切换,非核心业务先走新模型。
- 与Spring生态无缝集成:事务管理、缓存、异步执行等基础设施直接复用Spring Boot的成熟能力,不用自己造轮子。
如果项目本身不是Java技术栈,比如用Python,那选择就更多元化,LangChain或者直接手写异步调用都可以。框架本身不是重点,重点是把模型调用和业务逻辑隔离这件事,无论用什么语言都值得坚持。
3.2 Spring AI Alibaba的意义
名中带Alibaba的spring-ai-alibaba这个集成包我特意关注了一下,因为社区里问的人确实很多。它本质上是把阿里系模型服务和Spring AI做了更深度的整合,包括函数调用能力、通义系列模型的特定配置等。
一个比较实用的功能是它的DashScope(模型服务平台)接入。如果你打算用通义千问系列的API做兜底或者特定任务,直接通过Spring AI Alibaba的starter配置,不用自己处理签名逻辑。配置示例:
spring: ai: dashscope: api-key: ${DASHSCOPE_API_KEY} chat: options: model: qwen-plus temperature: 0.7这个集成能用的场景在于:本地模型处理不了的任务(比如超大上下文文本分析)可以动态路由到云端API,而应用层的代码不需要改。写的服务代码越长,越能体会这种多模型切换能力的价值。
3.3 本地模型与云端API的职责划分
本地部署和云端API并不是二选一。我的划分思路是:
- 本地模型(主力):日常对话、提示词工程迭代、批量内容生成初稿、数据标注辅助。
- 云端API(兜底):紧急高并发、需要更强逻辑能力的复杂推理、新模型能力的快速验证。
职责分离的关键点是统一抽象层。无论底层是本地还是云端,业务代码里都是同一个ChatClient接口,只是在配置层面区分路由。这样哪天本地模型效果升级了,或者某家云服务商性价比变了,改动成本都在几行配置以内。
4. Agent 实践:从单点调用到任务自动协作
模型和框架拼起来之后,"对话"已经没问题了,但离"干活"还有距离。我的项目里真正开始产生实际价值的转折点,是把Agent机制引进来。所谓Agent,通俗来说就是让模型不再只是"你说一句我回一句",而是能自主调用工具、规划步骤、执行任务,直到完成一个复杂目标。
4.1 Agent的两种主流实现方式
在个人项目实践中,我接触到的Agent构造方式主流是这两种:
ReAct模式(Reason + Act):模型思考当前状态,决定调用哪个工具,观察工具返回结果,再继续思考。整个过程是循环的,直到得出最终答案。这种模式的优点是灵活,适合开放式任务;缺点是token消耗高,而且遇到工具调用陷入死循环时,需要外层代码兜底。
计划-执行模式(Plan-and-Execute):先把用户目标拆分成一系列子任务,然后逐个子任务去执行。每个子任务可能是一个独立prompt模型调用,也可能是工具调用。优点是任务链路清晰,中途可以插入人工审核节点,适合"AI短剧文案生成""行业分析报告生成"这类结构化输出场景。
个人项目建议:优先考虑计划-执行模式。因为单个开发者的精力有限,死循环排查和工具链稳定性维护的成本太高,而计划-执行模式更容易控制中间状态。
4.2 实际落地:一个多工具协作Agent的骨架
我用一个"热点观察文章自动生成"的Agent作为桥梁来验证整个机制。这个Agent的工作流程是:
- 接收主题关键词(比如:AI短剧、AI工具)
- 调用搜索工具的API,捞取相关网页摘要
- 将摘要放入提示词模板,让模型整理出若干个观察角度
- 对每个角度调用一次模型,生成内容片段
- 最后再用另外的提示词把内容片段合并成完整文章
在Spring AI里,Agent的工具能力可以被注入到ChatClient里。核心是把外部搜索函数暴露成一个Java方法,再注册为模型可以调用的工具:
@Bean public ChatClient chatClient(ChatClient.Builder builder, ToolCallbacks toolCallbacks) { return builder .defaultTools(toolCallbacks) .build(); } @Service public class SearchTool { @Tool(description = "根据关键词搜索相关网页摘要") public List<String> search(String keyword, int topN) { // 调用搜索接口,返回摘要列表 } }这段代码背后代表的是一个关键思路:模型通过工具获得外部世界的信息。没有工具调用时,模型的知识截止时间是固定的,信息新鲜度是硬伤。加了工具之后,内容生成类Agent的可用性能上一个台阶。
4.3 Agent调试中最容易忽略的环节
Agent工程的调试难度比单轮对话高一个量级,最典型的问题是"模型没有按预期调用工具"。很多人以为这是模型能力问题,其实大多是指令写得不够明确。
在调试中反复验证后,我总结出三个实用经验:
- 提示词中把工具适用场景说清楚。例如
search工具要写明"仅当用户需要最新信息时才调用,不要凭记忆回答",这样模型才能准确判断是否需要用工具。 - 工具返回结果要结构清晰。纯文本的返回往往让模型判断困难,带序号、分段的缩略信息能让模型更容易提取有效内容。
- 增加的"重试"逻辑外置,不依赖模型自己修正。如果一次工具调用失败,外层代码直接重新调用一次,比让模型"反思后重试"更可控。
5. 提示词工程:内容生成类功能的胜负手
本地模型和框架都是工具,真正决定输出效果的是提示词。做AI短剧、AI漫剧、AI视频文案这类内容生成功能时,提示词的设计直接决定成品的可用度。这一章唠唠我在提示词工程里总结出的核心方法论。
5.1 场景化提示词模板的搭建套路
很多人写提示词就是一句话"帮我写个剧本",然后得到一堆千篇一律的泛泛内容。问题出在提示词没有场景和约束条件。
我的模板套路分四层:
- 角色设定:明确定义AI在任务中扮演的角色,例如"你是短视频编剧,擅长节奏紧凑的3分钟悬疑短剧"。
- 内容目标:说清楚要素,要有完整的起承转合、要有反转、适合竖屏拍摄。
- 格式要求:直接给定输出格式,比如按"场景一(日/内)..."逐条排列,拍短视频时可以直接拆条。
- 风格约束:避免什么、偏好什么措辞,例如"对白要口语化,拒绝书面语长句,每句台词不超过20个字"。
有了这个四层结构,同一套模板只需要替换"角色设定"和"内容目标"两处,就能从短剧文案切换到漫剧分镜脚本,复用率很高。
5.2 温度参数:内容创作中容易被忽略的"创造力开关"
模型推理时温度参数temperature是内容生成类功能中最值得精调的旋钮。温度低,输出稳定、可预测;温度高,输出跳跃、有意外惊喜。
我的实测数值参考:
| 任务类型 | 推荐温度 | 原因 |
|---|---|---|
| 短剧剧本(对白) | 0.7~0.9 | 需要一定创造力,但角色前后风格要稳定 |
| 分镜描述 | 0.5~0.7 | 画面信息需准确,不宜过度发散 |
| 行业分析总结 | 0.2~0.3 | 逻辑性优先,尽量减少幻觉 |
| 头脑风暴/选题发散 | 1.0以上 | 追求意外性,质量靠后期筛选 |
顺带提一个调试技巧:把温度作为接口请求参数暴露出来,在调试页面上做一个可拖动滑块,方便感受同一套提示词在不同温度下的输出差异。比每次改完配置再重启服务高效很多。
5.3 提示词迭代的版本控制
提示词也会有"代码腐烂"问题。我在项目进行到中期时发现,明明同一个功能,输出质量却不如两周前。原因是修改提示词时是直接改动原文件,改坏了也找不到回退版本。
后来我把提示词做成带版本号的模板资源文件,存放在src/main/resources/prompts/目录下,命名方式如下:
prompts/ short-drama/ v1-chat-format.txt v2-add-plot-twist.txt v3-restrict-dialogue-length.txt然后在代码中通过版本号加载指定模板,例如先从v3获取,如果效果不理想,随时切回v2对比。
这个习惯让我避免了很多因为反复微调导致的效果退化问题。提示词本身就是项目的资产,值得像代码一样被管理。有条件的话,甚至可以把不同版本的提示词在同样的测试问题上跑一遍,记录输出结果,建立一个小型的回归测试集,用自动化方式保证每次提示词改动不会破坏核心场景的出片质量。
6. 内容生成类功能的进阶实测:从单点文案到批量流水线
前面已经说到了短剧剧本这类内容生成功能。做这类项目,单纯依赖模型生成一段文案不难,难的是建立一条可复用的内容生产流水线。这一章分享我们是怎么把AI短剧和AI视频制作的流程搭起来的。
6.1 短剧文案生成的完整链路
单次prompt生成的脚本往往不能直接使用,因为内容连贯性不足,分镜之间跳得很快。我的解决方案是用"先生成大纲,再生成具体对白,再生成分镜"的分步链路:
- 第一步:给定故事主题(如"一夜暴富后,邻居变成仇人"),让模型生成故事大纲,包含开头冲突、中段推进、结尾反转。
- 第二步:把大纲拆成若干个场景,每个场景单独用一个prompt生成对白与动作描述。
- 第三步:用另一个prompt把每个场景转化为分镜格式,包含景别、运镜、对白、时长建议。
- 第四步:将分镜输出导入短视频编辑工具的时间轴,作为AI素材生成的提示词基础。
这个链路相当于用"提示词流水线"代替了一次性大prompt尝试,每一层输出都有人工审核修正的机会,成品率明显提高。
6.2 AI视频素材的提示词技巧
做AI短剧时,文字脚本只是第一步,真正耗时的是生成与脚本匹配的视频素材。用AI视频工具生成素材时,一个常见痛点是镜头间人物一致性不稳定。
我在实践中摸索出了一套提高一致性的做法:
- 人物外观描述词固定化:为每个角色建立一份"角色卡",包含外貌特征、服装细节、发型等固定描述,每次生成视频素材时都完整带上这段描述词,不能偷懒省略。
- 场景光线语汇统一:比如"柔和的黄昏光线、室内暖色调"这类光线描述词在整部短剧中保持一致,避免让模型自由发挥。
- 分镜之间用"衔接提示":在下一个镜头的提示词中加入前一个镜头的最后画面要素,例如"上一镜头中主角在门口回头看的背影",减少镜头切换的跳跃感。
这进一步说明,AI内容生成产品的本质不是"让AI自动干活",而是"把人的创意转换成AI能稳定执行的指令"。
6.3 批量生成时的质量检验机制
批量生成虽然省时间,但质量参差不齐的问题也成倍暴露。我建立了一套非常轻量的质检流程:
- 每次批量生成后,先让另一个模型做一次"质量打分",从逻辑连贯性、角色一致性、节奏感等维度打分。
- 低于阈值的文案自动返回,用修改后的提示词重新生成一轮。
- 对于产出的视频素材,则必须有人工抽检,逐项比对是否与脚本描述一致。
这套机制非常适合个人开发者——不需要复杂的标注团队,成本低,但能保证交付质量的下限。
7. 本地大模型与AI编程的协同工作流
我在项目开发过程中高频使用AI辅助编程,尤其是用VSCode的AI插件和云端编程Agent搭配本地大模型。两者配合得当,开发效率提升非常显著。
7.1 VSCode + Codex插件的日常节奏
VSCode里装AI编程插件已经是我开发的标准配置了。最常用的场景不是让它一次性生成大段代码,而是把它当作一个"会搜索编码规范的结对程序员":
- 遇到API用法不熟时,直接选中代码问插件"这个方法有哪些容易踩的坑",它会基于当前项目上下文给出建议。
- 重构老代码时,让它尝试重写一个函数,然后人工Review,比自己敲节省很多时间。
- 写单元测试时,让它根据现有函数签名生成测试骨架,再补充边界条件。
这里有个原则比较重要:不要要求AI编程插件"一步到位"写出完整业务模块,而是把任务拆小、让它逐步完成。每次只生成一个函数、一个类,人做审查和组装。这样既能控制质量,又能避免大段AI生成代码成为维护噩梦。
7.2 用本地大模型兜底AI编程助手
云端AI编程助手在某些情况下有顾虑——隐私、成本、以及在一个封闭环境中无法访问外网时的可用性。我后来用本地部署的代码模型作为编程助手兜底,效果虽不如云端顶级模型,但对常规的补全和模板代码生成已经够用。
为了提升本地模型的代码能力,调试中有一个配置心得是"给出足够的项目背景"。本地模型上下文窗口有限,直接让它回答"这个项目如果加一个XX功能要怎么改"往往答不到点上。我的做法是先把相关代码文件摘要塞入提示词,再把具体问题放在最后:
项目背景: - 这是一个Spring Boot 3 + MyBatis Plus项目 - 涉及用户模块、内容模块、统计模块 - 以下是UserMapper.java的代码结构摘要: <这里粘贴代码片段> 问题:如何增加一个按创建时间分页查询用户的方法?这种方式让本地模型在有限上下文内获得关键信息,回复的实用性高很多。
7.3 AI编程提示词的小技巧
AI编程提示词与普通对话提示词侧重点不同,我更看重以下三类技巧:
- 明确输入输出示例:与其描述"返回一个分页结构",不如直接给出一个包含分页字段的样例JSON,模型照猫画虎很少出错。
- 限制方案范围:如果不想让它引入新的依赖,明确说"不要增加新的第三方依赖,使用Java标准库实现"。
- 给出"负向指令":例如"不要使用线程睡眠来等待结果,用CompletableFuture回调",避免模型顺手写一个实现但风格与项目不符。
8. 个人AI项目工程化收尾:测试、安全与持续迭代
项目从原型走向"我可以长期维护"这个阶段,最关键的三件事是:测试怎么落地、安全边界怎么划、知识库怎么积累。很多个人项目卡在"能跑但不敢改",就是因为跳过了工程化收尾这一步。
8.1 AI项目自动化测试的经验
传统项目的单元测试在AI项目里不能完全照搬,因为模型输出具有随机性,断言具体返回内容必然不稳定。我实践下来比较有效的三层测试策略:
- 输入输出结构校验层:不关心模型具体说什么,只校验返回是否包含必需字段、格式是否正确。比如短剧生成接口必须返回"场景列表"和"总时长"字段,不存在即可断言失败。
- 确定性逻辑单元层:把与模型无关的纯逻辑(如分镜时长计算、关键字过滤、内容长度拆分)抽成独立函数,这部分按传统单测写。
- 回归对照层:维护一组典型输入和期望输出特征,跑完模型后记录输出快照,版本更新时对比新旧输出的差异,人工确认"变好还是变坏"。
这套方法跑了一个月后,我对改代码的恐惧感降低了很多——至少不会再因为一次重构,把之前验证好的内容生成质量悄悄搞坏。
8.2 内容安全与合规的边界意识
做AI内容生成项目,尤其涉及短剧、视频、公开内容时,安全合规是绝对不能跳过的环节。我的经验是:把安全机制内置为流水线的一步,而不是事后补救。
具体做法:
- 敏感词与违禁话题过滤:所有入库内容先过一遍关键词过滤,不能只靠模型自律。
- "人审优先":批量生产内容会强制设置人工审核节点,输出给最终用户前必经抽检。
- 版权意识:提示词中涉及真实人物、版权角色时,及时回避对外发布场景。
如果做的是一个面向普通用户的AI工具,建议在项目设计阶段就加入"内容旗帜"机制——自动给低质量或疑似违规内容打标,供人工快速筛选,而不是简单粗暴地拦截或放行。灰度引导比一刀切更实用。
8.3 让"踩坑经验"沉淀成个人知识库
最后一条也是我认为个人项目和业余项目拉开差距的关键:把踩坑记录转成可检索的个人知识库。我的AI项目开发中遇到的坑五花八门,从vLLM显存溢出到Spring AI工具调用不生效,再到提示词温度调高了导致剧本逻辑崩塌。
我的做法是持续在本地维护一个Markdown笔记库,每踩一个坑就记录:
- 问题现象
- 触发环境
- 排查链路
- 最终解决方案
- 能不能泛化成套路
同时引导项目中的AI助手在回答时参考这些历史记录,让它针对曾遇到的问题给出更贴合项目实际情况的建议。这个过程等于把个人经验持续沉淀进AI交互上下文,和"每次从零开始问一个通用模型"相比,准确度差异是真的明显。
写在最后:个人AI项目最值得坚持的三件事
这个项目做到现在,最大的领悟是:AI项目的成功从来不取决于你会不会用最前沿的模型,而取决于你有没有把"模型能力"和"业务逻辑"这个连接做得足够稳。
回看整条技术链,我觉得有三件事是最值得坚持的:
- 本地部署作为可控底座。云端API永远值得用,但本地模型让我在调试、迭代、成本控制上都有了底气。哪怕只是一个7B、8B的小模型,也能撑起日常高频实验。
- 提示词和工具调用要按照"工程"标准来对待。版本管理、回归测试、模板复用,这三样全做到,项目才不会越改越乱。
- 安全合规从设计阶段就内置,以及把项目从"能跑"推进到"敢长期维护"的安全网。AI生成内容尤其如此,边界感是这个时代内容创作者最重要的能力。
如果你也在做一个个人AI项目,我的建议是:别追求大而全,先把自己的核心场景跑通,再一步步往上加能力。AI领域的知识更新很快,但工程化的方法、经验教训的沉淀,才是穿越模型更迭周期仍然保值的东西。这就是我个人项目走到现在最值钱的资产。