尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

从零手写AI应用:本地模型部署、提示词与工具调用实践

发布时间:2026/9/29 1:20:44

资讯中心
01
ARTICLE

从零手写AI应用:本地模型部署、提示词与工具调用实践

从零手写AI应用:本地模型部署、提示词与工具调用实践
1. 重新理解AI工程不是调API而是构建系统1.1 为什么我要从零手写一个AI应用这两年AI圈有个现象很多人说自己在做AI开发实际上做的事情是把别人的API封装一层再套个好看的界面。不是说这样不行但如果你只停留在这一步对AI系统的理解会一直浮在表面。真正遇到性能问题、成本问题、效果调优问题你连排查的方向都找不到。我决定从零开始搭建一套AI应用系统不依赖任何现成的AI开发框架用最基础的技术栈自己处理模型加载、提示词构建、上下文管理、工具调用这些核心环节。这一路走下来踩了不少坑也把很多以前模糊的概念彻底搞明白了。这篇博客就是完整的过程记录和经验沉淀。这套系统最终做成什么样子一个本地的AI助手能对话、能联网检索、能调用外部工具完成具体任务所有代码都是我一行行写出来的核心依赖只有几个基础库。整个过程让我意识到AI工程的本质不是某个高深算法而是把模型能力、程序逻辑、数据流这三样东西有机地组装成一套可靠系统。1.2 这篇文章适合谁读如果你属于下面任何一类人这篇文章都会对你有帮助只会调用AI接口想深入理解AI应用内部工作原理的开发者想本地部署AI模型但不知道从哪下手的初学者已经在用现成框架比如LangChain、Spring AI之类的但遇到问题无从排查想搞清楚底层机制的工程师纯粹对AI技术好奇想知道一个AI应用到底是怎么从零跑起来的爱好者你能从这篇文章里得到完整的AI应用架构设计思路、每一步选型的理由、核心代码的逐段解析、我在实际操作中踩过的坑和总结的经验教训。不是那种看完就会忘的科普而是能真正指导你动手实践的干货。2. 从零搭建的AI应用架构设计与环境准备2.1 设计目标为什么选择本地部署而不是纯API方案动手之前我先明确了这套系统要达到的目标完全本地运行对话数据不出本机隐私安全可控支持模型热切换不止能用本地模型也能接入云端API具备工具调用能力AI不只聊天还能执行搜索、读文件、算数据这类实际操作模块化设计每个环节都可以单独替换和测试为什么坚持本地部署最直接的原因是成本。持续调用云端API做开发和测试一个月下来费用相当可观而且每轮对话都有网络延迟调试体验很差。本地跑模型虽然响应速度受限于硬件但胜在无额外费用、数据可控、可随时断网调试。我选的基础模型是Qwen2.5-1.5B-Instruct理由很实际它体积适中量化后不到2GB普通消费级显卡或者纯CPU都能跑得动指令跟随能力在同尺寸模型里属于第一梯队中文支持好毕竟是国内团队做的模型。如果你硬件条件更好可以换7B甚至14B版本都不影响整体架构代码几乎不用改。2.2 开发环境配置工具链选型与依赖安装我的开发环境是这样的操作系统Windows 11日常开发主力机开发工具PyCharm Jupyter Notebook混合使用语言版本Python 3.11推理框架llama-cpp-python直接加载GGUF格式的量化模型核心依赖transformers、torch、fastapi、uvicorn、httpx安装依赖时有一个容易踩坑的地方llama-cpp-python的安装方式取决于你的硬件环境。CPU版本直接pip装就行但如果要用CUDA加速必须指定安装参数否则默认装出来的是纯CPU版本性能差好几倍。# CPU版本 pip install llama-cpp-python # CUDA加速版本需已安装匹配的CUDA工具包 CMAKE_ARGS-DLLAMA_CUDAon pip install llama-cpp-python --force-reinstall --no-cache-dir我实测下来同样一个1.5B模型CPU跑大概每秒生成8-10个token启用CUDA之后能到每秒35-40个token。这个差距直接决定了用户体验所以如果你的显卡支持强烈建议用CUDA版本。这里补充一句为什么要选llama-cpp-python而不是直接用transformers。transformers虽然生态最完善但模型加载后常驻显存对硬件要求高推理速度也偏慢。llama-cpp做了大量量化优化能跑CPU内存占用低得多对个人开发者来说实用得多。缺点是和transformers的API风格不同刚上手需要适应一下。2.3 工程目录结构从一开始就保持清晰很多初学者喜欢把所有代码堆在一个文件里图省事。但我建议一开始就建立清晰的目录结构后面维护和扩展会轻松得多。我的工程目录是这样的ai-engineering-from-scratch/ ├── main.py # 启动入口FastAPI服务 ├── config.py # 全局配置模型路径、参数、端口等 ├── requirements.txt # 依赖清单 ├── core/ # 核心逻辑层 │ ├── __init__.py │ ├── llm.py # 模型加载与推理封装 │ ├── memory.py # 会话上下文管理 │ └── agent.py # 智能体核心决策与工具调用循环 ├── tools/ # 工具注册层 │ ├── __init__.py │ ├── search.py # 联网搜索工具 │ └── calculator.py # 计算工具 ├── api/ # API接口层 │ ├── __init__.py │ └── routes.py # 路由定义 └── models/ # 存放模型文件这个结构遵循一个核心原则模块之间单向依赖。core层的llm.py不含任何业务逻辑只负责模型的加载和推理agent.py调用llm和tools但tools不反向依赖core。这样改任何一层都不会牵动全局。3. 核心链路拆解从提示词到模型推理3.1 模型加载封装为什么单独抽象一层模型加载是整个系统最基础也最容易出问题的一环。直接在主程序里写加载逻辑虽然简化了代码量但会让后续的模型切换、参数调整全部变得僵化。我单独抽了一个llm.py把所有模型相关的操作集中在这里。# core/llm.py from llama_cpp import Llama from config import MODEL_PATH, MODEL_PARAMS class LocalLLM: def __init__(self): self.model None self.system_prompt None self.load_model() def load_model(self): try: self.model Llama( model_pathMODEL_PATH, n_ctx4096, # 上下文窗口大小 n_threads8, # CPU线程数 n_gpu_layers-1, # -1表示全部层加载到GPU verboseFalse # 关闭冗长日志 ) except Exception as e: print(f模型加载失败请检查模型文件路径{e}) def set_system_prompt(self, prompt: str): self.system_prompt prompt def generate(self, messages: list, **kwargs) - str: # 将消息列表转换为模型需要的格式 prompt self._build_prompt(messages) response self.model( promptprompt, temperaturekwargs.get(temperature, 0.7), max_tokenskwargs.get(max_tokens, 2048), stopkwargs.get(stop, None) ) return response[choices][0][text].strip()这里有几个参数值得单独说一下。n_ctx4096是上下文窗口大小。窗口越大模型能记住的对话历史越长但内存占用和计算量也会相应增加。对于1.5B这个量级的模型4096是一个比较均衡的选择既能覆盖大部分日常对话场景又不会让资源消耗失控。n_gpu_layers-1表示把所有层都放到GPU上计算。如果你的显存不够可以改成具体的层数比如n_gpu_layers20让部分层留在CPU上。这个参数是性能调优的关键值得多试几次找到自己硬件条件下的最优值。生成参数方面temperature控制随机性越低越稳定、越遵循上下文适合问答和代码生成越高越有创造性适合头脑风暴和文案写作。我默认设0.7但实际使用中会根据场景动态调整——处理代码任务时降到0.2写文案时升到0.9。3.2 提示词模板AI对话质量的隐形分水岭很多人以为提示工程就是在系统提示词里写你是一个有用的AI助手就完事了。实际上一套好的提示词模板对输出质量的影响有时比换一个更大的模型还明显。我花了不少时间打磨系统提示词最终定型为这样一段结构化的模板# config.py SYSTEM_PROMPT_TEMPLATE 你是构建在本地环境中的AI助手Neo运行在Qwen2.5-1.5B模型之上。 你具备以下能力1. 日常对话与知识问答 2. 使用工具进行联网检索和数学计算 3. 帮助你起草、总结和翻译各类文本。 你必须遵守以下规则 - 回答使用中文语气自然、友好、专业 - 不知道的信息必须明确说不知道绝对不能编造 - 涉及计算、检索类任务时必须调用工具获得结果后再回答不能凭空猜测 - 回答长度控制得当日常对话不冗长专业问题要详细 - 当用户输入不完整或意图不明确时用一到两个追问澄清意图 当前时间是{current_time}这个模板里的三个部分各有作用。第一段建立角色的身份和能力边界让模型知道它到底能干什么第二段设定行为规则尤其不知道就说不知道和必须调用工具这两条直接决定了模型会不会一本正经地胡说八道第三段加上当前时间对涉及时效性信息的问题非常有用——模型本身不知道现在是哪天你不告诉它它就只能瞎猜。一个值得注意的细节{current_time}这个占位符需要在每次对话前动态填充。我把这个逻辑放在生成消息的函数里确保模型看到的时间永远是当前真实时间。3.3 消息结构与上下文管理让AI记住你说的每一句话大语言模型本身没有记忆功能它能在一次请求中处理的内容就是输入给它的所有文本。所以对话记忆的本质是把历史对话拼接到新的请求里一起发给模型。这个拼接策略直接决定了对话质量。# core/memory.py class ConversationMemory: def __init__(self, max_history20): self.history [] self.max_history max_history def add(self, role: str, content: str): self.history.append({role: role, content: content}) # 超出最大长度时丢弃最早的对话 if len(self.history) self.max_history: self.history self.history[-self.max_history:] def build_messages(self, current_input: str): # 组装完整消息列表系统提示词 历史对话 当前输入 system_prompt SYSTEM_PROMPT_TEMPLATE.format( current_timetime.strftime(%Y-%m-%d %H:%M:%S) ) messages [{role: system, content: system_prompt}] messages.extend(self.history) messages.append({role: user, content: current_input}) return messagesmax_history20这个限制是经过实测的。把全部的对话历史一股脑塞给模型一方面增加处理耗时另一方面模型容易淹没在冗长的历史中对最新指令的注意力反而下降。20轮左右的缓冲既保证了对话的连贯性又不会拖慢响应。这里有个细节常被忽略——拼接历史时不能只看轮数还要看总token数。假如某几轮对话特别长20轮可能就已经撑爆上下文窗口了。更稳妥的做法是按token数限制截断但这样实现复杂度会高一些。我目前的方案兼顾了简单和效果你可以根据自己的场景调整。4. 让AI真正干活工具调用机制的实现4.1 工具是什么为什么AI需要工具纯文本的大语言模型有一个先天的能力边界它只会预测下一个token无法真正执行操作。你说帮我算一下237乘以153它能按照训练时见过的数学模式给出一个近似答案但更大的数字、更复杂的算式它就力不从心了。同样的道理你让它查最新的新闻它只能说抱歉因为它的知识截止在训练数据的最后一天。工具调用机制解决的就是这个问题。AI不需要自己会做这件事它只需要明白在做这件事之前应该先调用某个工具然后把工具返回的结果整理成答案。这就像你雇了一个研究员——读者不一定懂所有领域但知道遇到什么问題该去找哪个专家问。工具调用的实现逻辑可以概括为三个步骤系统提示词里明确告诉模型有哪些工具可用以及各自的用途模型在生成回复时通过特殊的输出格式表达我需要调用某工具参数是某某程序解析模型的输出执行对应的函数把真实结果返回给模型继续生成4.2 工具注册与格式约定用JSON协议打通模型与代码要让模型和程序之间顺畅协作最关键的是约定一个双方都能理解的通信协议。我选择JSON格式作为工具调用的载体原因很简单JSON结构化程度高可以借助现成的代码解析模型在训练阶段也见过大量JSON示例生成这种格式的成功率很高。# tools/__init__.py TOOL_DESCRIPTIONS [ { name: calculator, description: 执行数学计算支持加、减、乘、除、乘方、开方等运算。当你需要进行任何数值计算时使用。, parameters: { expression: 需要计算的数学表达式例如237*153 或 sqrt(256) } }, { name: web_search, description: 联网搜索最新信息。当用户询问实时数据、近期新闻或训练数据截止之后发生的事件时使用。, parameters: { query: 搜索关键词尽量精简 } } ]在系统提示词里我会追加一段工具说明你可以使用以下工具 1. calculator数学计算工具调用格式为 TOOL_CALL: {name: calculator, args: {expression: 237*153}} 2. web_search联网搜索工具调用格式为 TOOL_CALL: {name: web_search, args: {query: 关键词}} 如果想要调用工具只输出 TOOL_CALL: 开头的一行JSON不要输出其他内容。我直接用自定义的TOOL_CALL:前缀而不是依赖llama-cpp原生支持的function calling接口。原因在于1.5B小模型对原生function calling的支持并不稳定经常出现格式错误自定义前缀简单直接模型更容易学会。4.3 智能体主循环让AI自己决定用不用工具工具调用机制的灵魂在agent.py里的这个主循环——模型先判断是否有必要调用工具如果有程序执行工具把结果喂回去让模型再生成直到模型给出最终答案。# core/agent.py import json import re class Agent: def __init__(self, llm: LocalLLM, tools: dict): self.llm llm self.tools tools self.memory ConversationMemory() def run(self, user_input: str) - str: self.memory.add(user, user_input) messages self.memory.build_messages(user_input) # 最多循环3次防止模型陷入无限的工具调用循环 for _ in range(3): response self.llm.generate(messages, temperature0.3) # 判断是否是工具调用 tool_call_match re.search(rTOOL_CALL: (\{.*\}), response) if tool_call_match: try: tool_call json.loads(tool_call_match.group(1)) tool_name tool_call[name] tool_args tool_call[args] # 执行工具 tool_result self.tools[tool_name](**tool_args) # 把工具结果作为一条消息追加到对话 messages.append({role: assistant, content: response}) messages.append({role: tool, content: json.dumps(tool_result, ensure_asciiFalse)}) except Exception as e: messages.append({role: tool, content: f工具执行出错{str(e)}}) continue # 没有工具调用说明模型给出了最终回答 self.memory.add(assistant, response) return response # 循环次数耗尽返回最后一次生成的文本 self.memory.add(assistant, response) return response主循环的设计有几个精心考虑的细节。第一工具调用时把temperature降到0.3确保模型在结构化输出场景下尽可能稳定等最终生成回答时再调回0.7保证语言的自然度。第二循环上限设为3次。一个正常的任务通常只需要一次工具调用最多两次。如果模型反复要求调用工具说明它陷入了死循环3次上限可以及时刹车。这里还有个隐藏设计每次循环messages不断追加内容模型会看到之前调用的结果不会丢失上下文。第三异常处理。工具执行失败不直接抛错而是把错误信息当作工具返回结果塞回对话让模型基于错误信息生成合理的应对。这个处理方式很关键——相比直接崩溃用户得到的是抱歉我尝试搜索但网络好像开小差了这样更友好的反馈。4.4 工具的具体实现计算器和联网搜索calculator模块相对简单核心逻辑是用Python的ast模块安全地解析数学表达式同时做一层安全检查防止模型生成一些危害性的代码。这里我简化处理直接用了eval加白名单的方式# tools/calculator.py import math def calculator(expression: str): # 只允许数字、运算符和数学函数白名单 allowed_names { k: v for k, v in math.__dict__.items() if not k.startswith(__) } allowed_names.update({abs: abs, round: round}) # 基本的安全检测拒绝任何不是数学表达式的输入 if any(char in expression for char in [import, __, exec, open]): return {error: 表达式包含不安全的字符} try: result eval(expression, {__builtins__: {}}, allowed_names) return {result: str(result)} except Exception as e: return {error: f计算失败{str(e)}}web_search模块则调用了一个公开的搜索API——因为模型不知道训练数据之后的事情联网搜索正好补上这个短板。我使用的是免费的DuckDuckGo搜索API不需要注册Key对本地开发非常友好# tools/search.py import httpx def web_search(query: str, max_results: int 5): url https://api.duckduckgo.com/ params {q: query, format: json, no_html: 1} try: response httpx.get(url, paramsparams, timeout10) data response.json() if RelatedTopics in data: results [] for topic in data[RelatedTopics][:max_results]: if Text in topic: results.append({title: topic.get(Text, ), url: topic.get(FirstURL, )}) return {results: results} return {results: []} except Exception as e: return {error: f搜索请求失败{str(e)}}实测下来搜索工具对回答时效性问题的提升非常明显。比如问最近的AI圈有什么大事件模型单独回答只能给出一个概括性的模糊答案调用搜索工具后能拿到具体的新闻标题和链接回答质量完全不一样。5. 从示波器到仪表盘API封装与系统集成5.1 为什么用FastAPI做后端服务的接口核心功能全部跑通之后我做了一层API封装让这个AI系统被任何客户端复用而不仅限于在Python脚本里调用。选FastAPI有天然优势自动生成交互式API文档、原生支持异步、类型检查到位、性能也不错。# api/routes.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel from core.agent import Agent from core.llm import LocalLLM from tools.calculator import calculator from tools.search import web_search app FastAPI(titleLocal AI Assistant API, version1.0.0) # 全局初始化模型和智能体 llm LocalLLM() agent Agent(llm, tools{calculator: calculator, web_search: web_search}) class ChatRequest(BaseModel): message: str class ChatResponse(BaseModel): reply: str app.post(/chat, response_modelChatResponse) async def chat(request: ChatRequest): try: reply agent.run(request.message) return ChatResponse(replyreply) except Exception as e: raise HTTPException(status_code500, detailstr(e)) app.get(/health) async def health(): return {status: ok}启动服务的命令也很直接uvicorn api.routes:app --host 0.0.0.0 --port 8000这里有个喜闻乐见的工程细节我用事件循环的方式来避免每次请求重新定义或加载模型。PyCharm的调试技巧和接口测试这里就派上用场了——先用uvicorn自带的--reload参数让代码改成自动生效再用Postman发起请求测试接口时不用反复重启服务效率提高非常多。5.2 后端服务启动时的初始化顺序为什么模型加载要放在全局这个坑值得单独拿出来讲。我第一次写的时候把模型加载放在了每个请求的处理逻辑里结果每次对话都要等十几秒的加载时间。后来我改成在模块导入时一次性初始化app FastAPI()时创建全局的llm和agent实例启动服务时完成一次模型加载之后所有请求共享这个实例对话请求只做增量推理不再重新加载模型这套做法的好处是响应时间从十几秒降到几百毫秒。坏处是模型常驻内存大约占了3-4GB的内存或显存。对个人开发者来说这个代价是完全可以接受的——服务只在本机跑节省资源不如节省时间。同样的思路也应用在会话管理上。如果用单实例Agent跑所有请求用户A的对话历史会泄露给用户B如果每个请求都新建Agent又会丢掉记忆。折中的方案是为每个会话维护独立的Agent实例用会话ID做索引。我在这个版本里做了简化保持一个Agent服务一个用户实现多点会话记忆后续需要支撑多用户时再改造。5.3 增加流式输出让对话体验更自然非流式输出有一个很明显的问题用户要等模型把整段话生成完才能看到结果在本地模型上尤其明显1.5B模型生成300字的回答差不多要30秒用户会以为系统卡死了。llama-cpp-python原生支持流式输出但封装方式比较特殊。我改造了LocalLLM.generate方法增加一个stream参数def generate_stream(self, messages: list, **kwargs): prompt self._build_prompt(messages) stream self.model( promptprompt, temperaturekwargs.get(temperature, 0.7), max_tokenskwargs.get(max_tokens, 2048), streamTrue ) for chunk in stream: delta chunk[choices][0][text] if delta: yield delta在FastAPI侧SSEServer-Sent Events是最省事的方式——前端通过EventSource接口接收增量数据逐字显示体验非常接近ChatGPT。这个改造让系统的可用性提升了一个量级。6. 实测效果与调优避坑记录6.1 核心场景实测哪些表现超出预期系统跑通之后我设计了三组测试覆盖日常对话、工具调用和组合任务第一组测试是简单的知识问答。问量子纠缠是什么模型给出的解释基本准确条理清晰完全不像是一个1.5B模型说出来的话。这得益于Qwen系列在中文语料上的深厚积累也验证了我的系统提示词在约束回答风格上起到了预期效果。第二组测试是工具调用。问237乘以153等于多少模型没有像我想象中那样直接给答案而是先输出了一段TOOL_CALL: {name: calculator, args: {expression: 237*153}}的JSON程序执行后返回36261模型再基于这个结果给出回答。整个链路在代码里走通的那一刻就是典型的流水线跑通的满足感——AI从会聊天变成了会做事。第三组测试是组合任务。问帮我搜一下最近AI圈有什么新模型发布然后总结一下要点。模型先调用搜索工具拿到几条新闻标题再基于搜索结果生成了一段总结。只是搜索API返回的数据结构比较粗糙有时标题和摘要混在一起模型整理出来的内容结构还可以但提取精度有待提高。6.2 踩坑记录三次典型的调试排错过程调试过程中我最深刻的三个坑都是在本地环境里踩出来的。第一个坑是模型加载报错错误信息指向文件路径不存在。花了半小时才发现是路径里包含中文导致的问题Windows的Unicode文件和Linux的文件系统处理逻辑不一样。解决办法是模型文件放在纯英文、无空格的目录下这个经验在本地开发中几乎所有Windows用户都会遇到。第二个坑是生成的JSON格式不稳定。大模型在8-10轮对话后偶尔会把TOOL_CALL:后面的JSON写成多行格式导致re.search匹配失败。我加了一层解析逻辑先找TOOL_CALL:前缀再把后面所有的花括号内容取出来做一次JSON规范化遇到逗号缺失等小问题就用正则先修补修补不了就直接返回工具调用失败的提示。第三个坑更隐蔽——CUDA版本装完以后torch版本冲突。llama-cpp-python编译时带了某个特定版本的CUDA运行时而transformers依赖的torch是另一个版本两者在底层库上有冲突加载模型时直接崩溃。排查了整整一个晚上最后在虚拟环境里把两个包重装成兼容版本才解决。这个教训是本地AI开发一定要用虚拟环境把项目依赖隔离开能少踩80%的环境坑。6.3 性能测试相关资源占用与启动时间长开发中常被问到的一个问题是本地部署一个AI模型需要多少资源。实测数据如下内存占用模型加载后约1.8GB会话内存额外占用约200MB总共2GB左右GPU显存如果完全加载到GPU需要约3GB显存没有GPU时纯CPU模式也能跑首次加载时间冷启动载入模型约8秒后续请求平均响应时间3-8秒取决于回答长度、是否调用工具CPU推理速度约8-10 token/s能接受但缺少流畅感GPU推理速度约35-40 token/s日常对话的体感已经和云端API差距不大如果有一张6GB显存以上的显卡建议直接上7B模型对话质量会有质的飞跃。1.5B模型胜在轻量适合快速验证架构和做学习用途。6.4 效果调优路线从1.5B到更大模型的平滑演进架构设计得好不好一个重要的检验标准是你能不能在不改动整体结构的前提下替换一个更强的模型继续使用。我的这套代码在这点上做得比较充分——把config.py里的MODEL_PATH改一下重新加载服务理论上就能从1.5B切换到7B模型。选择更大的模型还需要调几个参数n_gpu_layers要重新调整显存不够就减到20甚至10层n_ctx可以适当加大到8192更大的模型能更有效地利用长上下文系统提示词不用改但temperature可能要根据模型表现微调工具调用的JSON格式契约不用变但大模型可能更愿意遵循原生function calling格式本地部署的好处在这里展露无遗换模型就是改配置的事整个工程架构的稳定性得到了验证。7. 从能跑到好用的思考与建议做到这里系统已经是一个能跑的状态了——AI助手能对话、能计算、能联网搜索整体架构清晰模块可替换。但距离好用还有相当长的路。根据我的实操经验有几点很想分享。先把建议列表摆上来再逐一说明如果你想动手练手先用1.5B模型跑通全流程再升级大模型不要一上来就上大模型或复杂框架先用最小可运行版本验证机制工具的JSON协议不要过度设计先满足核心场景再持续迭代每天用真实场景测框架看它在什么事情上容易翻车再针对性优化我应该解释第一点的理由。这个项目最大的阻力不是技术而是硬件条件的约束。如果一开始就强上7B甚至14B模型加载要等好几分钟推理慢如蜗牛很容易让人直接放弃。1.5B模型虽然回答质量一般但它的轻量特性让你可以专注于架构本身——先把代码链路跑通把工具调用机制调顺再切换到更大模型把精力放在优化回答质量上。先用小模型把系统搭起来并跑通再换大模型优化质量是我最推荐的技术路径。这套系统还能继续扩展的方向很多。接入语音识别做成语音助手增加读取本地文件的工具做成多轮任务规划和工作流调度或者接入摄像头做多模态应用——架构不变只需新增工具和调整提示词。我这个版本虽然没有实现但每个方向都有明确的落地点。个人体会AI工程和传统软件开发有个本质差异——你面对的不是一个确定执行指令的机器而是一个需要引导和约束的聪明但不稳定的伙伴。传统的异常处理思路在这里往往失效你需要做的是设计一套机制让它尽量发挥所长、尽量少犯错。学会了这种思维方式比学会某个具体工具重要得多。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。