AI工程100天实战:从RAG到Agent的企业数据接入全攻略

AI工程100天实战:从RAG到Agent的企业数据接入全攻略
原创声明本文是作者从零开始接触 AI 工程 100 天的完整记录与复盘以“萌新”视角梳理学习路线、工具链、实战项目和避坑经验希望能给同样准备入门 AI 的读者一条可复制、可验证的路径。1. 为什么一个“萌新”要写 100 天 AI 学习总结很多人在 AI 时代的第一反应是“不知道从哪里开始”。市面上有铺天盖地的课程、模型、框架、Agent 概念今天出一个新模型明天换一套工具链感觉永远追不上。作为非 AI 科班出身、没有深度学习和自然语言处理基础的纯萌新我给自己定了 100 天的时间窗口试图从零跑通一条“能上手、能落地、能理解原理”的 AI 工程路径。为什么要强调“工程”而不是“研究”因为对大多数后端开发、Java 工程师、Python 脚本作者来说真正需要的不是发明新模型而是学会把模型、数据、业务逻辑串起来。100 天听起来不长但只要路线清晰足够完成从“只会调用 API”到“能搭建一个带 RAG 检索、带 Agent 工作流的小应用”的跨越。这篇文章会完整记录这 100 天的学习路线与阶段划分环境、工具、模型选型理由每个阶段的实战项目代码常见问题和排查方法给后来者的工程建议。“秦良玉-甲骨文”这个标题看起来有点怪它其实包含两层意思一是学习 AI 就像古代女将出征需要策略、耐心和亲自上阵的勇气二是企业中大量存量数据存在 Oracle甲骨文等传统数据库里AI 应用要真正落地必须学会和这类数据库打交道。100 天里我不只写 Python 调模型还做了一套从 Oracle 读数据、向量化、再丢给大模型做问答的完整系统这也是整条学习路径最有价值的部分。2. AI 工程学习必须搞清的核心概念在开始实操之前有些概念必须先建立框架。如果不理解这些词代码能跑但不知道自己在做什么遇到问题也无从下手。2.1 模型、Token、上下文窗口模型Model可以理解成一个“输入文本到输出文本”的映射函数。你给它一句问题它返回一段回答。真正决定模型能力上限的是一组权重参数这些参数在训练阶段通过海量文本学习得到。Token 是模型处理文本的最小单位不是“字”也不是“词”而是模型自己切分出来的片段。一个中文汉字通常对应 1 到 2 个 Token一段英文可能一个单词就拆分出多个 Token。为什么关心 Token因为所有商用模型按 Token 计费所有模型的上下文窗口长度也以 Token 数衡量。上下文窗口Context Window是模型单次请求能“看到”的最大文本长度。比如上下文窗口为 128K就表示你一次性传给模型的内容不能超过这么多 Token。对写代码、做文档问答的开发者来说窗口越大意味着能把更多业务资料塞进去让模型参考但成本也越高。2.2 Prompt、System Prompt 与 In-Context LearningPrompt 是你发给模型的指令文本。模型能力再强指令不清也会答偏。System Prompt 是系统级别的指令用来设定模型的角色、行为边界、回答风格和输出格式通常不被用户看到。所谓 In-Context Learning上下文学习就是你在请求里塞入若干示例或参考资料模型不更新权重仅凭这些上下文就学会“照样子回答”。这是 RAG检索增强生成的原理基础你把相关的文档片段拼到 Prompt 里模型就能基于这些片段作答。2.3 Fine-tuning 与 RAG 的边界Fine-tuning微调是拿一批成对的数据对模型做额外训练更新权重改变模型本身的“气质”和“知识”。它适合固定风格转换、输出结构化格式、领域术语学习等场景缺点是成本高、需要训练数据和算力且每次更新都要重新训练。RAGRetrieval-Augmented Generation则是把外部知识提前切块、向量化、存入向量数据库每次问答时先检索出最相关的片段再拼入 Prompt 交给模型。它适合实时知识库、企业私有数据问答、需要频繁更新内容但不想重新训练模型的场景。对新手的建议是优先学 RAG不要一开始就碰微调。RAG 见效快、可解释性强、成本可控也是大模型落地最常用的方案。2.4 Agent、工具调用与工作流Agent智能体不是一个模型而是一套“模型 工具 循环决策”的架构。模型扮演大脑负责分析任务、决定下一步工具包括代码解释器、搜索接口、数据库操作、文件读写等流程则是模型反复选择工具、执行、观察结果、再决策的循环。对开发者的意义在于传统代码是人定义完整流程Agent 是模型在流程里边走边决策。它让机器能处理“没有标准答案”的长链路任务也带来了不可控性和调试复杂度。在实际工程中更稳妥的做法是“工作流 Agent”混合常规步骤用代码控制开放式判断交给模型。3. 100 天学习路线总览与阶段规划100 天不能平均用力我按“熟悉工具 → 调用模型 → 本地部署 → 工程整合”四个阶段做了规划。每个阶段都设定了可交付的成果避免“学了一堆概念却什么都没做出来”。3.1 阶段划分表时间段阶段名称核心目标输出成果第 1-15 天Python 自动化基础熟悉语言、数据处理、虚拟环境写好脚本批量处理文本和 Excel第 16-30 天API 调用与 Prompt 工程学会调用大模型 API掌握提示词技巧做一个命令行问答助手第 31-55 天向量化与 RAG 检索理解嵌入模型、向量数据库、召回流程搭建本地知识库问答系统第 56-80 天开源模型本地部署部署开源模型、对比量化、推理加速跑通本地模型并封装 HTTP 服务第 81-100 天Agent 与企业数据接入开发 Agent 工作流接入 Oracle 等数据库做一个能查库存、写报告的综合小系统3.2 为什么按这个顺序先学 Python 自动化是因为 AI 工程需要大量的数据预处理、日志解析、批量调用脚本这是基本功。再学 API 调用因为这是上手最快、反馈最直接的方式——每天都能和模型对话成就感强。有了 Prompt 和 API 基础再学 RAG 就顺理成章你理解了模型怎么读 Prompt就明白 RAG 的本质是“动态拼 Prompt”。本地部署放在第四阶段是因为它最容易被新手劝退如果一开始就碰 CUDA、显存、推理框架大概率直接放弃。Agent 和企业数据接入放在最后因为它是综合工程。你会用到之前的 API 调用、RAG、代码工具还要解决数据库连接、权限控制、异步任务、日志追踪等问题。3.3 需要避开的弯路不要上来就学全量微调。一个大模型的 LoRA 微调训练就要几十甚至几百 GB 显存新手环境根本没条件。不要陷入“模型版本焦虑”。今天 Llama 3明天 Qwen 2.5后天 DeepSeek R1追不完的。能力提升的关键不是追新模型而是把现有工具用熟、用透。不要只看教程不写代码。AI 工程不是看会的是调 bug 调会的。4. 环境准备与工具链搭建在动手写代码之前环境必须稳定。很多新手死在前三步因为环境不一致同一个代码在这台机器跑了、换一台机器就报错。下面列出我最终稳定使用的环境方案和配置思路。4.1 硬件环境本地开发和轻量模型推理建议至少 16GB 内存如果计划本地跑 7B 参数以上的模型需要一张显存至少 8GB 的 NVIDIA 显卡。没有 GPU 也不是不能学可以把重心放在 API 调用和 RAG 应用层本地部署部分用 CPU 推理或云服务器替代。4.2 软件体系操作系统使用 Ubuntu 22.04Python 版本选择 3.10 以上。开发工具使用 VS Code 配合 Jupyter 插件。虚拟环境使用 Anaconda 或 venv避免不同项目依赖互相污染。新建项目时我固定使用以下目录结构ai-study/ ├── data/ # 原始数据 ├── src/ # 源码 │ ├── utils/ # 公共工具函数 │ ├── rag/ # RAG 相关代码 │ ├── agent/ # Agent 工作流代码 │ └── api/ # API 服务封装 ├── tests/ # 单元测试 ├── config/ # 配置文件 └── requirements.txt # 依赖清单4.3 核心 Python 依赖# 基础数据处理 pip install pandas numpy openpyxl # 调用大模型 API pip install openai requests # 向量数据库与嵌入 pip install chromadb sentence-transformers # RAG 框架 pip install langchain langchain-community # Web 服务 pip install fastapi uvicorn # Oracle 数据库连接 pip install oracledb安装完成后建议做好依赖冻结方便搭建一致环境pip freeze requirements.txt4.4 模型与 API 服务的选型在 API 层面可以按实际成本和可用性选择大模型服务商常见的是 OpenAI 兼容接口或国内大模型平台。在本地模型层面推荐通义千问 Qwen 系列或 Llama 系列的开源版本。嵌入模型Embedding Model我使用了bge-small-zh-v1.5或text2vec这类中文友好的轻量模型它们能把文本转成向量供向量数据库检索使用。版本选择上不用刻意追求最新重点是用稳定版本。如果 API 兼容 OpenAI 格式即使换了厂商代码改动也只是 base_url 和 API Key 的替换。5. 第一阶段用 Python 做好数据预处理第 1-15 天万事开头难。前 15 天我没有急着去调用任何大模型而是先用 Python 完成了一个实际任务把一堆零散的 Excel、CSV、文本文件清洗成结构化数据。因为 RAG 系统的第一步就是“把 PDF、Word、Excel 内容提取为干净的文本”如果数据源乱七八糟后面用什么模型都白搭。5.1 数据清洗示例# 文件路径src/utils/data_cleaner.py import pandas as pd import re from pathlib import Path def clean_text(text: str) - str: 去除多余空白、特殊符号将文本整理为规范格式。 这是一个基础清洗函数实际使用时可扩展为去除 HTML 标签、保留表格结构等。 if not isinstance(text, str): return # 去除多余换行和空格 text re.sub(r\s, , text) # 去除常见特殊符号保留中文、英文、数字和基础标点 text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9。、《》\-\. ], , text) return text.strip() def process_excel_file(file_path: Path) - pd.DataFrame: 读取 Excel 文件并清洗文本列 df pd.read_excel(file_path) text_cols df.select_dtypes(include[object]).columns for col in text_cols: df[col] df[col].apply(clean_text) return df if __name__ __main__: input_path Path(data/raw/products.xlsx) output_path Path(data/processed/products_clean.csv) df process_excel_file(input_path) df.to_csv(output_path, indexFalse, encodingutf-8-sig) print(f清洗完成共处理 {len(df)} 行数据输出文件{output_path})这段代码解决了 RAG 数据源最常见的脏文本问题Excel 里大量单元格包含不规则换行、空格和特殊符号如果直接切块向量化会被切成一堆碎片检索效果很差。5.2 批量文档读取与切块# 文件路径src/utils/text_splitter.py from langchain_text_splitters import RecursiveCharacterTextSplitter def split_documents(documents: list[dict], chunk_size: int 500, chunk_overlap: int 50) - list[dict]: 将长文本按固定策略切块。 参数说明 - chunk_size每个文本块的最大字符数500 字符比较适中块太小语义丢失块太大检索噪声高。 - chunk_overlap相邻块之间的重叠字符数保留上下文衔接。 splitter RecursiveCharacterTextSplitter( chunk_sizechunk_size, chunk_overlapchunk_overlap, separators[\n\n, \n, 。, , , ., !, ?, , , ] ) chunks [] for doc in documents: texts splitter.split_text(doc[content]) for idx, text in enumerate(texts): chunks.append({ id: f{doc[id]}_{idx}, source: doc[source], content: text }) return chunks切块策略是 RAG 系统质量的隐形决定因素。块太小语句之间关系被切断块太大检索时容易把不相关内容带进来。实际项目中建议用RecursiveCharacterTextSplitter它的思路是先按段落分再按句子分最后按标点分尽量保持语义完整。5.3 本阶段小结第 1-15 天最容易产生的感受是“怎么还没用上 AI”。但这段刻意练习数据工程的时间在后来的 RAG 项目里直接兑现了价值——别的同学还在为格式杂乱的 PDF、Excel 发愁我已经在跑检索测试了。对一个 AI 工程师来说最值钱的能力不是“会让模型写诗”而是“能把业务数据整理成模型能用的格式”。6. 第二阶段API 调用与 Prompt 工程第 16-30 天进入第二阶段我正式接触大模型 API。这一步做的是建立“模型输入输出”的操作直觉同时掌握 Prompt 工程的基本章法。6.1 最小可用调用示例以下代码使用 OpenAI 兼容接口格式。不同厂商只需要修改base_url、api_key和model三个字段就可以切换后端模型# 文件路径src/api/llm_client.py from openai import OpenAI client OpenAI( api_keyyour-api-key, base_urlhttps://api.example.com/v1 ) def chat(question: str, system_prompt: str 你是一个乐于助人的技术助手回答要准确简洁。) - str: response client.chat.completions.create( modelgpt-4o-mini, # 实际部署时以服务商支持为准 messages[ {role: system, content: system_prompt}, {role: user, content: question} ], temperature0.3, # 需要稳定答案时温度调低需要创造性时调到 0.7 以上 max_tokens2048 ) return response.choices[0].message.content if __name__ __main__: result chat(请用三句话解释什么是 RAG) print(result)这个示例虽然简单但已经包含了三个重要设计System Prompt 设定模型行为边界参数分离让用户输入和系统指令互不干扰temperature控制输出随机性工程场景通常调到 0.3 以下保证稳定性。6.2 函数调用Function CallingAPI 调用仅仅实现问答是不够的工程中更常见的需求是模型理解用户意图然后调用外部工具完成动作。这就要用到 Function Calling。# 文件路径src/api/tool_calling.py from openai import OpenAI client OpenAI( api_keyyour-api-key, base_urlhttps://api.example.com/v1 ) # 定义工具 tools [ { type: function, function: { name: query_order_status, description: 查询订单状态, parameters: { type: object, properties: { order_id: {type: string, description: 订单号} }, required: [order_id] } } } ] def query_order_status(order_id: str) - str: # 实际项目中这里连接数据库或业务系统 return f订单 {order_id} 的状态是已发货 messages [ {role: system, content: 你是订单查询助手请根据用户问题调用工具获取信息。}, {role: user, content: 帮我查一下订单 20250815001 的状态} ] response client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolstools, tool_choiceauto ) # 解析模型返回的工具调用 for tool_call in response.choices[0].message.tool_calls or []: if tool_call.function.name query_order_status: result query_order_status(order_id20250815001) print(工具返回结果, result)Function Calling 是 Agent 的核心机制之一。模型本身不会查数据库、不会发请求但它能判断出“这个问题需要调用某个函数”然后输出函数名和参数你的代码负责实际执行并把结果返回给模型继续对话。6.3 Prompt 工程三原则与常用模板结构化指令把要求和限制拆分比如“请先给出结论再给出理由”。给出示例例子比抽象指令有效得多一个输出示例能节省 80% 的调参时间。限定输出格式要求 JSON 输出时明确字段名和类型。# 文件路径src/prompt/templates.py ENTITY_EXTRACTION_PROMPT 请从以下文本中提取所有公司实体并以 JSON 数组格式输出。 输出示例 [ {name: 北京华信科技有限公司, type: 企业, confidence: 0.98}, {name: 张三, type: 人, confidence: 0.95} ] 要求 1. 只提取公司名称、人名、产品名 2. 置信度不足的信息不要输出 3. 不要输出任何解释。 文本内容 {input_text} 6.4 本阶段小结第 16-30 天的核心收获是建立了“模型不可靠”的工程思维。模型会撒谎、会编造函数参数、会格式化出问题所以每个 API 调用都要加异常处理、超时设置、返回格式校验。Prompt 再好也不能保证 100% 稳定工程上是在模型外面包一层“安全壳”。7. 第三阶段RAG 检索增强生成实战第 31-55 天从第三阶段开始真正的核心应用来了。RAG 是我认为 AI 工程最常见的落地形态企业有内部文档、规章制度、产品手册但员工需要一个自然语言问答入口直接问“报销发票流程是什么”并得到准确答案。7.1 RAG 整体流程架构RAG 的流程可以拆成两个池子离线索引池把文档清洗、切块、向量化存入向量数据库。在线推理池用户提问 → 向量化 → 检索 Top K 相似片段 → 拼入 Prompt → 模型生成答案。我把完整流程整理成一张表格阶段输入处理输出文档清洗原始 PDF/Excel/文本去噪、规范化干净文本文本切块干净文本按语义边界切分文档片段向量化文档片段嵌入模型转换为向量向量序列存储向量序列写入向量数据库可检索索引检索用户问题向量相似度计算取 TopK相关片段生成问题 片段大模型生成答案最终回答7.2 向量化与向量数据库写入# 文件路径src/rag/build_index.py from sentence_transformers import SentenceTransformer import chromadb # 加载中文嵌入模型 embedding_model SentenceTransformer(BAAI/bge-small-zh-v1.5) # 初始化 Chroma 客户端 chroma_client chromadb.PersistentClient(path./chroma_db) collection chroma_client.get_or_create_collection(nameenterprise_docs) # 模拟从上一阶段获得的数据 chunks [ {id: doc_0_0, source: 报销制度.pdf, content: 报销流程如下第一步提交申请单...}, {id: doc_0_1, source: 报销制度.pdf, content: 发票需为增值税普通发票...}, ] # 向量化并写入 texts [chunk[content] for chunk in chunks] embeddings embedding_model.encode(texts, normalize_embeddingsTrue) for i, chunk in enumerate(chunks): collection.add( ids[chunk[id]], embeddings[embeddings[i].tolist()], metadatas[{source: chunk[source]}], documents[chunk[content]] ) print(f已写入 {len(chunks)} 条索引数据)嵌入模型会决定检索质量。用bge-small-zh-v1.5这类中文专门优化的模型比直接用英文通用模型效果好很多。另外建议开启normalize_embeddingsTrue统一向量长度方便后续算余弦相似度。7.3 RAG 问答实现# 文件路径src/rag/rag_query.py from sentence_transformers import SentenceTransformer import chromadb from openai import OpenAI embedding_model SentenceTransformer(BAAI/bge-small-zh-v1.5) chroma_client chromadb.PersistentClient(path./chroma_db) collection chroma_client.get_collection(nameenterprise_docs) llm_client OpenAI( api_keyyour-api-key, base_urlhttps://api.example.com/v1 ) def retrieve(query_text: str, top_k: int 3) - list[dict]: 根据用户问题检索最相关的文档片段 query_vec embedding_model.encode([query_text], normalize_embeddingsTrue)[0] results collection.query( query_embeddings[query_vec.tolist()], n_resultstop_k ) docs [] for i, doc in enumerate(results[documents][0]): docs.append({ content: doc, source: results[metadatas][0][i][source] }) return docs def generate_answer(question: str) - str: 基于检索结果生成回答 docs retrieve(question) context \n\n.join([f【来源{d[source]}】\n{d[content]} for d in docs]) prompt f请根据以下资料回答问题。如果资料中没有相关信息请直接说“资料中未找到相关内容”不要编造。 资料 {context} 问题{question} 请给出准确、简洁的回答。回答末尾用一行注明信息来源。 response llm_client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: prompt}], temperature0.1 ) return response.choices[0].message.content if __name__ __main__: answer generate_answer(报销发票需要什么类型) print(answer)7.4 效果验证的几个关键指标RAG 的成败在检索不在生成。如果检索上来的片段本身不正确模型再怎么聪明也白搭。检查方法直接打印检索到的 Top K 片段看是否和问题主题相关如果检索不到相关内容先调整切块大小和重叠度如果检索到相关内容但回答不准再考虑是不是 Prompt 指令或者大模型理解能力问题不要盲目增加 Top K 数量片段越多噪声越大模型越容易“迷失在上下文里”。7.5 本阶段小结第 31-55 天的最大收获是理解了“所谓 RAG本质是给大模型加外置硬盘”。模型记住的知识是训练时固化的企业私有内容永远不在模型肚子里RAG 负责把相关内容实时送到模型面前。这个模式工程上成熟、易迭代、可控性强值得花时间彻底掌握。8. 第四阶段开源模型本地部署与推理优化第 56-80 天如果说前三个阶段是“站在云端用别人的模型”那第四阶段就是“把模型拉到自己的机器上跑”。这一步让我理解了模型的大小、显存、推理速度之间的关系。8.1 为什么要在本地部署数据隐私企业内部数据不能出域成本控制高频调用时 API 费用可能非常惊人定制能力本地模型可以配合微调、量化、蒸馏等后续操作。相应地本地部署也存在显存门槛、CPU 推理慢、运维复杂等问题。稳妥的思路是“混合架构”敏感数据走本地小模型通用高难度任务走 API。8.2 使用 Ollama 快速部署本地模型Ollama 是目前对新手最友好的本地模型运行工具一条命令就能拉起一个大模型服务。这里以轻量模型为例演示通用思路# 安装 Ollama以官方脚本为准系统环境为 Linux/macOS curl -fsSL https://ollama.com/install.sh | sh # 拉取一个适合 CPU 推理的轻量模型 ollama pull qwen2.5:7b # 启动模型并进入交互式对话 ollama run qwen2.5:7b 请用一句话介绍 RAGOllama 启动后默认在本机的 11434 端口提供一个 OpenAI 兼容接口可以直接被 FastAPI 或 LangChain 调用# 查看服务是否正常 curl http://localhost:11434/v1/models8.3 使用 Hugging Face Transformers 做量化推理如果项目需要更细的推理控制可以直接用 Transformers 加载量化模型。下面是一个用bitsandbytes做 4-bit 量化的推理示例# 文件路径src/local_inference/infer_quantized.py from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig import torch # 量化配置将模型权重压缩到 4-bit适合显存有限的机器 quant_config BitsAndBytesConfig( load_in_4bitTrue, bnb_4bit_quant_typenf4, bnb_4bit_compute_dtypetorch.bfloat16 ) model_name Qwen/Qwen2.5-7B-Instruct tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained( model_name, quantization_configquant_config, device_mapauto ) # 构造指令模板 messages [ {role: system, content: 你是一个简洁的技术助手。}, {role: user, content: 用 3 句话解释什么是向量数据库} ] text tokenizer.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue) inputs tokenizer([text], return_tensorspt).to(cuda) outputs model.generate( inputs.input_ids, max_new_tokens512, temperature0.3, do_sampleTrue ) response tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokensTrue) print(response)8.4 推理速度优化与显存管理量化用 4-bit 或者 8-bit 大幅降低显存消耗。流式输出不要等服务端生成完整回答使用streamTrue边生成边返回用户体感更流畅。批处理推理服务可以通过连续批处理提高吞吐量。预热加载模型后先做一次空跑把权重加载到显存避免首次请求过慢。流式输出示例# 文件路径src/local_inference/stream_infer.py from openai import OpenAI client OpenAI( api_keyollama, base_urlhttp://localhost:11434/v1 ) stream client.chat.completions.create( modelqwen2.5:7b, messages[{role: user, content: 讲一个 AI 工程师的冷笑话}], streamTrue ) for chunk in stream: delta chunk.choices[0].delta.content if delta: print(delta, end, flushTrue)8.5 本阶段小结第 56-80 天踩了最多的坑显存不足、依赖冲突、量化后精度下降、推理速度慢到不能用。但理解这些之后我对“模型运行在哪、算力消耗在哪、瓶颈在哪”有了具体认知。大模型不是魔法黑箱它也是软件工程的一种——需要调优、需要监控、需要为特定硬件做适配。9. 第五阶段Agent 开发与 Oracle 数据库接入第 81-100 天最后 20 天我把前面的能力组合成一个接近真实企业场景的小系统用户用自然语言提问Agent 通过工具调用查询 Oracle 数据库中的业务数据再结合 RAG 文档库生成带来源依据的回答。这正对应标题里“甲骨文”的含义。9.1 Oracle 数据库连接与数据操作为什么强调 Oracle很多大型企业的核心交易数据、订单数据、库存数据仍然存在 Oracle 数据库中。AI 应用如果不接触这些数据就只能做“通用问答”做不了真正的业务智能。Python 连接 Oracle 可以选 python-oracledb它是 oracledb 库的新一代版本无需额外安装 Oracle Instant Client 的瘦模式。# 文件路径src/db/oracle_connector.py import oracledb # 最小连接示例thin 模式 connection oracledb.connect( useryour_user, passwordyour_password, dsn192.168.1.100:1521/ORCLPDB ) cursor connection.cursor() cursor.execute(SELECT order_id, order_status, create_time FROM orders WHERE ROWNUM 5) rows cursor.fetchall() for row in rows: print(row) cursor.close() connection.close()9.2 让模型学会调用数据库查询函数把数据库操作包装成函数通过 Function Calling 暴露给大模型是 Agent 最核心的范式之一。模型负责理解用户问题、抽取查询条件代码负责安全的数据库访问和数据格式化。# 文件路径src/agent/order_agent.py import json import oracledb from openai import OpenAI # 数据库连接参数 DB_CONFIG { user: your_user, password: your_password, dsn: 192.168.1.100:1521/ORCLPDB } llm_client OpenAI( api_keyyour-api-key, base_urlhttps://api.example.com/v1 ) # 工具定义 tools [ { type: function, function: { name: query_recent_orders, description: 查询指定时间范围内的订单列表, parameters: { type: object, properties: { days: {type: integer, description: 最近 N 天默认为 7}, }, required: [] } } } ] def query_recent_orders(days: int 7) - str: 查询 Oracle 数据库中的近期订单 connection oracledb.connect(**DB_CONFIG) try: cursor connection.cursor() cursor.execute( SELECT order_id, customer_name, order_amount, order_status FROM orders WHERE create_time SYSDATE - :days AND ROWNUM 20, {days: days} ) rows cursor.fetchall() return json.dumps( [{order_id: r[0], customer: r[1], amount: float(r[2]), status: r[3]} for r in rows], ensure_asciiFalse ) finally: cursor.close() connection.close() def run_agent(user_question: str) - str: 执行 Agent 主流程 messages [ {role: system, content: 你是一个订单分析助手可以通过工具查询最近订单数据再根据工具结果回答用户问题。}, {role: user, content: user_question} ] response llm_client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolstools, tool_choiceauto ) message response.choices[0].message # 如果模型要求调用工具 if message.tool_calls: tool_result None for tool_call in message.tool_calls: if tool_call.function.name query_recent_orders: args json.loads(tool_call.function.arguments or {}) tool_result query_recent_orders(**args) # 将工具结果返回给模型让模型基于结果生成最终回答 messages.append(message) messages.append({ role: tool, tool_call_id: message.tool_calls[0].id, content: tool_result }) final_response llm_client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolstools, tool_choiceauto ) return final_response.choices[0].message.content return message.content if __name__ __main__: answer run_agent(最近 7 天订单金额最高的订单是什么) print(answer)9.3 安全边界与权限控制数据库接入 Agent 最容易出问题的不是功能而是安全。数据库账号必须使用最小权限只读账号不要给 DML/DDL 权限。参数化查询禁止把模型输出的内容直接拼接 SQL必须使用绑定变量。超时控制所有数据库操作都要设置超时时间防止模型生成异常参数拖垮连接。审计日志记录每次 Agent 调用的用户、参数、时间和数据库操作内容。测试环境先行在测试库验证全部流程后才能上生产库并且生产库的 DSN 要放到配置中心或者环境变量里不写死进代码。9.4 用 FastAPI 将 Agent 封装为 HTTP 服务为了让 AI 能力真正被业务系统调用最后一步是把 Agent 封装成 REST API。这里用 FastAPI 做一个最小实现# 文件路径src/api/main.py from fastapi import FastAPI from pydantic import BaseModel from src.agent.order_agent import run_agent app FastAPI(titleAI Order Assistant) class QueryRequest(BaseModel): question: str user_id: str unknown class QueryResponse(BaseModel): answer: str app.post(/api/agent/query, response_modelQueryResponse) async def agent_query(req: QueryRequest): 接收用户自然语言问题返回 Agent 处理后的答案。 生产环境需要增加用户认证、流控、审计日志等功能。 answer run_agent(req.question) return QueryResponse(answeranswer) app.get(/health) async def health_check(): return {status: ok}启动服务uvicorn src.api.main:app --host 0.0.0.0 --port 8000调用验证curl -X POST http://localhost:8000/api/agent/query \ -H Content-Type: application/json \ -d {question: 最近7天销量最高的商品是什么, user_id: test_user}9.5 本阶段小结第 81-100 天完成了从“会调 API”到“能做完整业务智能系统”的转变。Agent 的本质不是魔法而是工程编排模型做判断代码做执行数据库做存取。这三者必须配合得当任何一环不稳整个系统都会崩。10. 100 天常见问题与排查思路问题现象可能原因排查方式解决方案API 调用报 401 鉴权失败API Key 配置错误或过期检查环境变量和请求头重新生成 Key确认使用正确的 base_url模型回答不准确、胡乱编造没有使用 RAG或检索结果不相关打印检索 TopK 片段检查调整切块大小增加检索片段数量加入“不相关则拒绝回答”的 Prompt中文切块后语义错乱切块时在中文标点处断开不合理检查切块效果看断点是否合适使用 RecursiveCharacterTextSplitter 并调整分隔符顺序本地模型加载时显存不足模型参数量太大或未量化查看显存占用检查日志换更小模型或加载 4-bit 量化版本推理速度极慢CPU 推理或 GPU 利用率低查看系统监控使用流式输出启用连续批处理或考虑云端 APIOracle 连接失败防火墙、DSN 错误或驱动问题测试网络连通性和数据库端连接用 sqlplus 或客户端工具验证连接串检查监听配置Agent 调用了错误的工具Function Calling 参数定义不清检查工具描述和参数说明改写工具描述加入更具体的参数说明和示例回答引用错误来源检索片段本身错误检查向量库索引数据是否过时建立文档更新机制定期重建索引11. 最佳实践与工程建议11.1 给 AI 工程新手的 5 条建议先做一个小而全的项目不要急着追求大模型能力。完成一个“文档问答 数据库查询”的 Demo比看完所有论文都有用。保持对 Token 成本的敏感。每天看 API 账单你就会主动优化 Prompt 长度和切片策略。学会看模型输出日志。记录每次调用的输入、输出、Token 用量、耗时这是优化的基础。不追新模型只追稳定可用的模型。生产环境选型要看社区成熟度、许可证、硬件要求。遇到问题要能拆解。把问题拆成“是数据处理的问题、是检索的问题、还是生成的问题”比盲目调模型参数重要得多。11.2 工程落地时的安全底线涉及数据库、权限、生产数据的 AI 应用永远要记住几个原则最小权限原则AI 应用使用的数据库账号只能访问它真正需要的数据。参数化查询永远不要拼接 SQL。数据脱敏AI 应用日志中不能出现明文密码、身份证号、银行卡号。回滚方案发布 Agent 版本前准备好一键回滚到旧服务。测试环境完整验证后再上生产。11.3 继续深入的方向100 天只是起点。如果继续向前优先级大概是评测体系建设为 RAG 和 Agent 建立自动化评测集每次改动都能量化效果观测与追踪引入链路追踪把模型调用、工具调用、Token 消耗全链路可视化微调入门有足够数据和算力时可以尝试轻量级微调解决领域风格问题多模态扩展从纯文本转向图片、语音、视频理解覆盖更丰富的业务场景。12. 100 天后回头看值得记住的三件事第一AI 工程的核心是“让模型为业务服务”不是“让业务适配模型”。每一行代码都在解决信息流动、权限控制、稳定性保障的问题模型只是其中一个环节。第二萌新的最大优势不是基础而是没有思维定势。会调 API 就能做出可用的工具会组装 RAG 就能解决大问题不需要等自己成为算法专家才动手。第三100 天足够完成认知升级从“AI 很神奇”到“AI 是软件工程的新范式”。真正的门槛不在模型而在工程素养——数据处理能力、系统设计能力、排查问题的耐心这些都是任何技术方向都通用的底层能力。如果你也准备开始自己的 100 天建议刻在桌面上的第一行代码是print(Hello, AI Engineering)然后从今天第 1 天开始。

最新新闻

日新闻

周新闻

月新闻