先说一个经常在技术社区被反复讨论的问题:Hacker News 上有人提问“使用 AI 是否是一种可市场化的技能”,评论区观点很多,有人觉得会写提示词就能接单,有人觉得这只是工具使用能力,过几个月就会被新人追上。我的观点比较明确:单纯“会用 AI”很难形成壁垒,真正可市场化的是“把 AI 工程化落地”的能力——也就是能稳定复现、能评测效果、能控制成本、能对接业务系统、能处理安全边界的整套方法。这也是本文想展开的主线。
无论你是刚接触 AI 应用开发的新手,还是准备把 AI 能力写进简历的开发者,这篇文章都会给你一条比较清晰的能力构建路径。我会先拆解核心概念,再给出一套可以本地运行的最小 RAG 问答系统代码,然后补充常见问题和工程化建议。整个流程不需要 GPU,不需要高成本部署,用普通电脑和标准 Python 环境就能跑通。
1. 背景与核心概念
1.1 “会用 AI”不等于“会做 AI 工程”
先看一个常见误解:很多人觉得“AI 技能 = 写提示词”,于是花大量时间研究各种 prompt 模板。但实际项目里,prompt 只是完整链路中的一环。一个可交付的 AI 功能,至少包含数据准备、上下文检索、模型调用、结果校验、异常处理、成本统计、日志追踪等环节。
换句话说,面试官或者客户真正关心的不是“你能不能把一句话问得更优雅”,而是“给你一个业务场景,你能不能做出一个稳定、可靠、可维护的 AI 功能”。这已经不是提示词工程,而是 AI 应用工程。
从市场价值来看,下面这些能力都比“写提示词”更稀缺:
- 能根据业务场景设计 RAG 管线,让模型基于私有知识库回答问题。
- 能让 AI Agent 按照固定流程执行任务,并且在出错时自动恢复。
- 能评测 AI 输出的质量,建立回归测试集,防止某次改 prompt 后效果大幅波动。
- 能控制 API 调用成本和延迟,在性能和费用之间做取舍。
- 能把 AI 能力嵌入现有系统,而不是只停留在网页 Demo。
1.2 哪些 AI 技能真正有市场价值
结合当前招聘市场和开源社区的热度,以下几类技能和热门关键词可以形成对应关系:
| 技能方向 | 与热词对应 | 典型交付物 |
|---|---|---|
| 提示词系统性设计 | ai 编程、ai 工具、cursor ai 编程 | 可复用的 prompt 模板、角色指令文件 |
| RAG 应用开发 | ai 应用开发、ai 工程实践 | 知识库问答机器人、档解析助手 |
| Agent 工作流开发 | ai agent、ai agent 开发、ai 智能体 | 自动化客服、自动化工单处理、报告生成器 |
| 模型部署与服务化 | ai 模型部署 | 私有化推理服务、性能压测方案 |
| 与后端框架集成 | spring ai、pycharm ai 插件、ai coding | Spring Boot 项目里的 AI 接口、IDE 效率插件 |
这些方向都会落到两件事上:让大模型输出更可控,以及让 AI 能力可以被代码化地集成进业务系统。这两件事做扎实了,AI 技能才谈得上“可市场化”。
1.3 先分清 Prompt、RAG、Agent、Fine-tuning
很多人一上来就背概念,结果做起项目还是分不清。我习惯用一句话来区分:
- Prompt Engineering:通过设计输入指令和示例,让模型按预期格式输出。
- RAG(Retrieval-Augmented Generation,检索增强生成):先从外部知识库检索相关内容,再把检索结果拼进提示词,最后让模型生成答案。适合“回答私有知识问题”。
- Agent:让模型在循环中调用外部工具、读取结果、继续决策,直到完成任务。适合“执行业务流程”。
- Fine-tuning:用业务数据微调模型参数,改变模型本身的权重。适合“需要固定风格或固定能力的重复场景”。
在多数业务场景中,RAG 和 Agent 是性价比最高的方案,因为它们不需要训练模型,只需要用好现有模型能力。本文的实战案例也会围绕 RAG 加一个最简单的 Agent 循环展开。
2. 环境准备与工具链
工程落地先谈环境。下面以常见环境为例,具体版本需要根据你的实际项目调整,但演示重点不在版本差异上。
2.1 基础运行环境
- 操作系统:Windows 10/11、macOS、Linux 均可。
- Python:建议 3.9 及以上,本文示例使用标准库即可运行。
- API 服务:任意 OpenAI 兼容接口,也可以换成国内云厂商提供的兼容服务。
- IDE:推荐 VS Code 或 PyCharm,可以安装 AI 插件辅助写作和调试,例如 PyCharm AI 插件、Cursor 等。
为了不在示例中引入太多第三方依赖,代码里我会用 Python 标准库urllib调用 Chat Completions 接口,用纯 Python 实现简单的向量检索。这样你只需要一个可用的 API Key 和一台能联网的电脑,就能跑通整个流程。
2.2 推荐工具链
- 代码管理:Git。
- 依赖管理:
requirements.txt或pyproject.toml。 - 密钥管理:环境变量,不写入代码仓库。
- 评测:准备一个固定的问题集,每次改动后批量跑评测。
2.3 示例项目结构
ai-skill-demo/ ├── data/ │ ├── intro.txt │ └── faq.txt ├── indexer.py ├── search.py ├── llm_client.py ├── rag_bot.py ├── evaluate.py ├── requirements.txt └── .env.example每一个文件的职责我会在实战部分详细说明。
3. 核心能力拆解
在写完整案例之前,先把 AI 应用开发中四个核心能力拆开讲。这些是“可市场化技能”的骨架。
3.1 提示词的系统性设计
提示词不是越长越好,而是要有结构。实践中比较稳定的结构包括:
- 角色设定:告诉模型“你是什么角色”,限制回答视角。
- 任务描述:用一句话说清要做什么。
- 上下文材料:需要模型依据的内容,例如检索到的文档片段。
- 输出格式约束:要求输出 JSON、Markdown 还是纯文本。
- 边界与拒答规则:例如“不要编造文档中不存在的信息”。
我更推荐把提示词模板写成独立文件,而不是散落在代码里。这样后续改 prompt 不需要重新发布代码。举一个简化例子:
你是一个企业内部知识库助手。 请根据下面提供的【文档片段】回答用户问题。 要求: 1. 只依据文档片段回答,不要编造。 2. 如果文档片段中没有答案,直接回复“当前知识库中未找到相关信息”。 3. 使用简洁的 Markdown 格式输出。 【文档片段】 {context} 【用户问题】 {question}在实际开发中,这段模板可以存储为prompts/rag_template.txt,由代码读取并填入变量。
3.2 RAG 管线的关键环节
RAG 看起来只有“检索 + 生成”两步,但工程落地时包含四个关键环节:
- 文档加载与清洗:从 PDF、Word、HTML 等格式中提取文本,并去掉无意义字符。
- 文本切分(Chunking):把长文档切成段。切得太长,会导致上下文窗口浪费;切得太短,会丢失语义。实践中可以从 200 到 800 字符之间尝试,再根据回答质量调整。
- 向量化与索引:把文本转成向量,存入向量数据库或内存索引。简单场景也可以只用词频向量。
- 检索与重排:根据用户问题召回 Top-K 片段,有需要时再给片段打分排序。
对于学习项目,不一定要上重型向量数据库。用 TF 向量加余弦相似度已经能演示完整流程。
3.3 Agent 的工作流设计
Agent 与普通单次问答的差别在于“循环”。一个最小 Agent 循环包含以下步骤:
- 接收用户目标。
- 让模型判断下一步动作(调用工具或直接回答)。
- 如果调用工具,则执行工具函数,把结果返回给模型。
- 模型基于工具结果继续推理。
- 重复直到任务完成或达到最大步数。
在企业场景里,Agent 最常见的落地方式是“固定工作流”:比如写日报、生成周报、自动归类工单、定时抓取数据。固定工作流比完全开放式的 Agent 更稳定,也更容易评估。
3.4 模型部署与成本评估
如果是个人项目,直接调用云端 API 即可。但如果业务对数据隐私有要求,就需要私有化部署开源模型,这就涉及 AI 模型部署技能。
模型部署的核心点包括:
- 显存与内存估算;
- 量化策略(如 INT8、INT4);
- 推理框架选型;
- 并发与延迟压测;
- 弹性伸缩策略。
成本评估方面,不要只看单次调用价格。完整的成本模型还包括:
- 输入 Token 数;
- 输出 Token 数;
- 检索阶段的向量化成本;
- 缓存命中率;
- 失败重试成本。
建议每次请求都记录 Token 消耗,沉淀成日志,方便后续优化。
4. 完整实战:构建一个最小 RAG 问答系统
下面我们动手写一个基于“本地知识库 + 大模型问答”的最小 RAG 系统。这个系统可以直接跑起来,也可以作为面试作品放进 GitHub。
4.1 需求说明
我们要实现一个内部知识库问答助手。用户输入问题后,系统先从本地文档里检索相关片段,再把片段作为参考上下文交给大模型,最终返回带出处感的回答。
流程:
用户输入 → 检索模块:从本地文档中召回 Top-K 片段 → 构造提示词:模板 + 片段 + 用户问题 → LLM 模块:调用 Chat Completions 接口 → 返回结果4.2 准备数据
在data/目录下创建两个文本文件,内容可以按照实际知识库替换。
data/intro.txt:
AI 技能工程化能力体系包括提示词设计、RAG 检索增强生成、Agent 工作流开发、模型部署与评测。 RAG 的核心思想是先检索后生成,适合构建基于私有知识库的问答系统。 Agent 通过调用外部工具完成多步复杂任务,但每一步都需要关注错误处理和结果校验。data/faq.txt:
Q:RAG 和 Fine-tuning 有什么区别? A:RAG 不改变模型权重,而是通过检索外部知识来补充上下文;Fine-tuning 会改变模型参数,用于固定风格或固定领域能力的场景。 Q:如何降低 AI 应用成本? A:可以从减小上下文长度、增加缓存、批量处理、选择更低价的模型等角度优化。4.3 编写检索模块
为了减少依赖,我用词频向量加余弦相似度实现一个轻量检索。
indexer.py负责读取文档并切块:
# 文件路径:ai-skill-demo/indexer.py import json import re from pathlib import Path def split_text(text: str, chunk_size: int = 100) -> list[str]: """按段落切分文本,再按 chunk_size 字符合并,避免单块过长。""" paragraphs = [p.strip() for p in re.split(r"\n+", text) if p.strip()] chunks = [] current = "" for para in paragraphs: if len(current) + len(para) < chunk_size: current += para + "\n" else: if current: chunks.append(current.strip()) current = para + "\n" if current: chunks.append(current.strip()) return chunks def build_index(data_dir: str, output_file: str) -> None: """读取 data_dir 下所有 txt 文件,切块后写入 JSON 索引文件。""" docs = [] for txt_path in Path(data_dir).glob("*.txt"): text = txt_path.read_text(encoding="utf-8") chunks = split_text(text) for chunk in chunks: docs.append({ "source": txt_path.name, "content": chunk, }) with open(output_file, "w", encoding="utf-8") as f: json.dump(docs, f, ensure_ascii=False, indent=2) print(f"索引完成,共 {len(docs)} 个文本块。") if __name__ == "__main__": build_index("data", "index.json")search.py负责计算相似度并召回 Top-K:
# 文件路径:ai-skill-demo/search.py import json import math from collections import Counter def tokenize(text: str) -> list[str]: """简单中文 + 英文分词方案:按字符切分中文,按空格切分英文。""" text = text.lower() # 将中文按字切分,英文按单词切分 words = re.findall(r"[\u4e00-\u9fa5]|[a-z0-9]+", text) return words def cosine_similarity(vec1: Counter, vec2: Counter) -> float: """计算两个词频向量的余弦相似度。""" common = set(vec1.keys()) & set(vec2.keys()) dot = sum(vec1[w] * vec2[w] for w in common) norm1 = math.sqrt(sum(v * v for v in vec1.values())) norm2 = math.sqrt(sum(v * v for v in vec2.values())) if norm1 == 0 or norm2 == 0: return 0.0 return dot / (norm1 * norm2) def load_index(index_file: str) -> list[dict]: with open(index_file, "r", encoding="utf-8") as f: return json.load(f) def search(query: str, index: list[dict], top_k: int = 3) -> list[dict]: """返回与 query 最相关的 top_k 个文本块。""" query_vec = Counter(tokenize(query)) scored = [] for item in index: doc_vec = Counter(tokenize(item["content"])) score = cosine_similarity(query_vec, doc_vec) scored.append((score, item)) scored.sort(key=lambda x: x[0], reverse=True) return [item for score, item in scored[:top_k] if score > 0]注意:上面的代码中我使用了re模块,需要补上import re。实际完整代码里一定要带上。
修正后的search.py开头:
# 文件路径:ai-skill-demo/search.py import json import math import re from collections import Counter4.4 编写 LLM 调用模块
llm_client.py使用标准库urllib调用 OpenAI 兼容的 Chat Completions 接口。这种方式不依赖特定 SDK,兼容性较好。
# 文件路径:ai-skill-demo/llm_client.py import os import json import urllib.request import urllib.error def chat_completion( messages: list[dict], model: str = "gpt-4o-mini", temperature: float = 0.2, max_tokens: int = 800, ) -> str: """ 调用 OpenAI 兼容接口。 需要设置环境变量: OPENAI_API_KEY OPENAI_BASE_URL(可选,默认 https://api.openai.com/v1) 返回模型生成的文本内容。 """ api_key = os.environ.get("OPENAI_API_KEY") if not api_key: raise ValueError("请先设置 OPENAI_API_KEY 环境变量") base_url = os.environ.get("OPENAI_BASE_URL", "https://api.openai.com/v1") url = base_url.rstrip("/") + "/chat/completions" payload = { "model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens, } req = urllib.request.Request( url, data=json.dumps(payload).encode("utf-8"), headers={ "Content-Type": "application/json", "Authorization": f"Bearer {api_key}", }, method="POST", ) try: with urllib.request.urlopen(req, timeout=60) as resp: data = json.loads(resp.read().decode("utf-8")) return data["choices"][0]["message"]["content"] except urllib.error.HTTPError as e: body = e.read().decode("utf-8") raise RuntimeError(f"API 调用失败,状态码 {e.code}: {body}")4.5 编写 RAG 主流程
rag_bot.py把检索和生成串起来。这里同时加了一个最小 Agent 概念:如果用户问的是“根据知识库回答”,则走 RAG;如果用户要求生成报告模板,可以追加一个固定步骤。
# 文件路径:ai-skill-demo/rag_bot.py import os from search import load_index, search, tokenize from llm_client import chat_completion SYSTEM_PROMPT = """你是一个企业内部知识库助手。 请根据下面提供的【文档片段】回答用户问题。 要求: 1. 只依据文档片段回答,不要编造。 2. 如果文档片段中没有答案,直接回复“当前知识库中未找到相关信息”。 3. 使用简洁的 Markdown 格式输出。 """ def build_messages(question: str, context: str) -> list[dict]: user_content = f"【文档片段】\n{context}\n\n【用户问题】\n{question}" return [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": user_content}, ] def ask(question: str, index: list[dict], top_k: int = 3) -> str: # 1. 检索相关片段 related_chunks = search(question, index, top_k=top_k) if not related_chunks: return "当前知识库中未找到相关信息。" # 2. 拼接上下文 context = "\n\n---\n\n".join( f"来源:《{item['source']}》\n{item['content']}" for item in related_chunks ) # 3. 调用大模型生成回答 messages = build_messages(question, context) try: answer = chat_completion(messages) except Exception as e: return f"生成失败:{e}" return answer def main(): index = load_index("index.json") print("AI 知识库助手已启动,输入问题后回车,输入 exit 退出。\n") while True: question = input("问题:").strip() if question.lower() in ("exit", "quit"): break if not question: continue answer = ask(question, index) print(f"\n回答:\n{answer}\n") if __name__ == "__main__": main()4.6 编写评测脚本
评测是 AI 工程和普通脚本最大的区别。没有评测,你无法确认一次 prompt 改动到底变好了还是变差了。
evaluate.py用一组预置问题批量请求 RAG,并输出结果。你可以在本地人肉判断回答质量,也可以把输出保存下来结构化对比。
# 文件路径:ai-skill-demo/evaluate.py import json from search import load_index from rag_bot import ask TEST_CASES = [ {"question": "RAG 是什么?", "expected_keywords": ["检索"]}, {"question": "如何降低 AI 应用成本?", "expected_keywords": ["缓存", "上下文"]}, {"question": "Fine-tuning 和 RAG 有什么区别?", "expected_keywords": ["权重", "检索"]}, ] def evaluate(): index = load_index("index.json") results = [] for case in TEST_CASES: answer = ask(case["question"], index) hit = all(keyword in answer for keyword in case["expected_keywords"]) results.append({ "question": case["question"], "answer": answer, "passed": hit, }) print(f"问题:{case['question']}") print(f"回答:{answer[:100]}...") print(f"通过:{hit}") print("-" * 50) passed_count = sum(1 for r in results if r["passed"]) print(f"整体通过率:{passed_count}/{len(results)}") with open("evaluate_result.json", "w", encoding="utf-8") as f: json.dump(results, f, ensure_ascii=False, indent=2) if __name__ == "__main__": evaluate()“expected_keywords”这种人工规则只能做初步回归。生产环境建议引入更强的模型作为裁判,或者让人工标注一批标准答案,按相似度打分。
4.7 准备依赖与运行命令
由于示例代码只用了标准库,requirements.txt可以留空或只写说明:
# 本项目示例仅使用 Python 标准库 # 如需接入其他向量数据库或 SDK,请按需安装设置环境变量:
export OPENAI_API_KEY="你的 API Key" export OPENAI_BASE_URL="https://api.openai.com/v1"注意:
OPENAI_BASE_URL要替换成你实际使用服务的地址。
运行步骤:
# 1. 生成索引 python indexer.py # 2. 启动问答 python rag_bot.py # 3. 运行评测 python evaluate.py预期输出类似:
索引完成,共 5 个文本块。 AI 知识库助手已启动,输入问题后回车,输入 exit 退出。 问题:RAG 是什么? 回答: RAG 是指检索增强生成,核心思路是先检索后生成,适合构建基于私有知识库的问答系统。这里的示例知识库很简短,所以检索效果会受词表限制。你可以替换成自己的业务文档,增大数据量后效果会更明显。
5. 常见问题与排查思路
在跑通上面案例的过程中,你可能会遇到下面几类问题。这里按“现象 → 原因 → 解决思路”整理成一张排查表:
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 启动时提示没有 OPENAI_API_KEY | 环境变量未设置或设置失效 | 检查export命令;Windows 用户使用set;不要在代码里硬编码 Key |
| API 调用返回 401 | API Key 无效或权限不足 | 确认 Key 是否有效、账户是否有余额、是否开通目标模型权限 |
| API 调用返回 429 | 请求频率超限或余额不足 | 检查配额,增加退避重试,开启缓存 |
| 返回内容与知识库无关 | 检索召回结果不准确 | 增加文本块数量,调整切块大小,改进分词或向量化方案 |
| 回答出现明显编造 | 提示词未限制模型“只能依据片段回答” | 在 system prompt 中强调拒答规则,降低 temperature |
| 程序卡在长时间无响应 | 网络超时或模型推理较慢 | 给urlopen设置合理 timeout,增加超时重试逻辑 |
| 中文分词效果差 | 简单的字符级切分无法表达语义 | 学习阶段可接受;工程阶段建议使用向量模型或专业分词库 |
| 上下文太长导致费用高 | 检索片段过多或文档太长 | 限制 Top-K,优化文本切块长度,引入重排减少无用上下文 |
重要一点:如果输出结果有很大随机性,先看 temperature 参数。诊断类、客服类场景建议把 temperature 调到 0.1 到 0.3,写作类场景可以适当调高。
6. 最佳实践与工程建议
把一个能跑的 Demo 变成能交付的系统,需要关注下面这些工程细节。
6.1 把提示词当作代码来管理
提示词应该进入 Git 仓库,不要只存在某个平台的网页编辑框里。建议按版本管理,并在变更记录里写清楚“为什么改”“评测结果如何”。
如果项目混用多个模型的 prompt,可以在模板中用变量区分模型能力边界。例如一个模型支持 JSON 输出,另一个不支持,系统要能自动降级。
6.2 建立评测集和回归机制
这是 AI 工程和普通开发差异最大的地方。每次修改 prompt、RAG 参数、模型版本,都要用同一套评测集验证。建议至少准备:
- 30 到 50 条常见问题;
- 10 到 20 条边界问题(例如知识库中没有答案的问题);
- 几条对抗性问题(比如诱导模型脱离上下文回答)。
评测不一定要自动化得很复杂。就算最初只是把回答结果导出成 CSV,每周人工看一眼,也比完全不做强很多。
6.3 成本、缓存与限流
AI 应用的成本大头通常来自输入 Token。优化优先级是:
- 先减少不必要的上下文;
- 再增加语义缓存,相似问题直接复用结果;
- 然后考虑换用更小的模型;
- 最后再评估是否需要微调。
同时,任何对外提供的 AI 接口都应该加限流,防止单个用户占用过多预算。
6.4 安全与合规边界
涉及数据隐私和用户信息安全时,要守住几个原则:
- 不把敏感数据写入日志;
- API Key 用环境变量或密钥管理服务保存;
- 上传给第三方模型服务的数据需要先做脱敏;
- 对外提供 AI 能力时要有鉴权机制,推荐最小权限原则;
- 删除操作、批量操作前必须经过测试环境验证并备份。
在医疗、金融、政务等敏感场景,优先考虑私有化部署开源模型,而不是把数据发送到云端 API。必要时咨询法务和合规团队。
6.5 可维护性与可观测性
每个请求都应该有唯一 ID,记录模型名、Token 用量、耗时、错误信息。遇到问题的时候,没有日志和 Trace 很难定位。
建议在最开始就封装一层 LLM 客户端,而不是在业务代码里到处直接调用 SDK。这样后续切换模型供应商时,只需要改一个文件。
7. 回到最初的问题:AI 技能如何市场化
现在再回看 Hacker News 上的那个问题,答案会更清晰一些。单纯“会用 AI”确实不太容易卖出高价,因为门槛在快速降低。但“会做 AI 工程”是可以市场化的,因为它解决的是企业在实际落地时最头疼的问题:不稳定、不可控、不可评估、不可维护。
你可以不研究模型底层原理,只要你做到以下几点,就已经具备了 AI 工程化的基础能力:
- 能用代码稳定调用模型接口,并统一封装异常和日志;
- 能设计 RAG 管线,让模型学会参考你的知识库;
- 能建立评测集,用量化方式说明“这次改动效果是变好还是变差”;
- 能把 AI 能力嵌入一个真实业务工具,比如内部问答机器人、文档分析助手、自动化工单处理脚本。
如果你正在规划学习路线,我建议按这个顺序推进:
- 第一周:跑通本文示例,替换成自己的知识库文档,理解检索和生成之间的关系。
- 第二周:引入一个开源向量数据库(例如 Chroma、Milvus),并把检索模块从词频替换成向量检索。
- 第三周:给 RAG 系统加一个评测集,尝试调整切块大小、Top-K、temperature,对比效果。
- 第四周:选择一个真实业务场景,做一个最小 Agent,让它主动调用工具完成一个固定任务。
- 之后:学习 Spring AI 等框架,把 AI 能力嵌入 Java 后端系统;或者学习模型部署,把开源模型跑在私有环境。
真正的竞争力不在于你用过多少 AI 工具,而在于你能不能把 AI 能力变成一个稳定、安全、可交付的软件功能。从今天开始,挑一个你最熟悉的业务场景,试着把它改造成一个 AI 应用,这比收藏一百篇文章都管用。