FDE 是 AI 时代最火的新岗位——深入客户现场,把大模型接进真实业务流程。 这个网站为有一点技术基础但还不算熟练的你,把 FDE 需要的知识拆成能看懂、能学会的内容。 不需要你是计算机科班,也不需要你精通编程,但你要愿意动手。
在正式学技术之前,先搞清楚 FDE 到底是个什么岗、从哪来、和传统岗位有什么区别。这一章不写代码,但你必须读——方向错了,努力白费。
2003 年,Peter Thiel 创立 Palantir,为美国情报机构做数据分析系统。他们发现一个尴尬的事实:软件写得再好,客户也不会用。于是 Palantir 做了一个在当时很反直觉的决定——派工程师驻扎到客户现场,和分析师们坐在一起,看着他们怎么干活,然后当场改系统。
这些工程师被叫做 Forward Deployed Engineer(前线部署工程师)。他们不是远程写代码的后端开发,不是写 PPT 的售前顾问,而是"在现场边看业务边改系统"的混合角色。
到 2026 年,OpenAI 的招聘页面上 FDE 相关岗位超过 20 个,Anthropic 称之为"Customer Engineer",国内则叫"AI 解决方案工程师"或"前线部署工程师"。名字不同,内核一致:深入客户现场,把 AI 从 Demo 变成生产系统。
下面是从 OpenAI、Anthropic 和国内某 AI 独角兽的 FDE 招聘启事中提取的真实要求,逐条翻译成人话:
| JD 原文 | 人话翻译 | 你需要达到的水平 |
|---|---|---|
| "Partner with customers to understand their business problems" | 你要能跟客户聊天,搞清楚他们到底在愁什么 | 不需要你是行业专家,但你要会问对问题 |
| "Design and implement AI solutions end-to-end" | 从需求到上线你一个人扛 | 不是让你什么都精通,但每个环节你都得能动手 |
| "Strong programming skills in Python" | Python 要能干活 | 能写脚本、调 API、处理数据,不需要写框架 |
| "Experience with LLM deployment (vLLM, TGI)" | 要部署过开源大模型 | 至少用 vLLM 跑过一次模型服务 |
| "Ability to travel up to 50%" | 一半时间在出差 | 这是 FDE 的常态,不是偶尔 |
| "Communicate complex technical concepts to non-technical stakeholders" | 能把技术讲给老板听 | 这比写代码更难,也更重要 |
| "Build and maintain customer trust" | 客户信任你,才让你碰他们的系统 | 靠谱 > 技术。出错不可怕,隐瞒才可怕 |
很多人把 FDE 和解决方案架构师、实施顾问搞混。它们确实有重叠,但内核完全不同:
架构师说"应该这样做" →
实施顾问说"按文档做完了" →
FDE说"客户业务指标涨了 30%" →
FDE 介于架构师和实施之间,但比架构师更动手,比实施更懂方案。
这不是杜撰,而是综合了多位在职 FDE 的分享整理的典型工作日:
从"客户说想用 AI"到"系统在生产环境稳定运行",FDE 的项目交付有一条清晰的五阶段路径。每个阶段有明确的目标、交付物和容易踩的坑。
这个阶段你什么都不写,只做一件事:搞清楚真实需求。客户说出来的需求 80% 不是真实需求。你说"我想用 AI 提效",你的真实痛点可能是"每天有 2000 条工单靠人工分类,4 个人分类就要 1 整天"。FDE 的工作就是把模糊表述翻译成可执行方案。
PoC(Proof of Concept)不是做完整系统,而是用最快速度验证"这个方向行不行"。通常 1-2 周,花几百块 API 费用,给客户看一个能跑的 Demo。如果 PoC 效果不行,尽早止损——比花 3 个月做完发现不行强 100 倍。
MVP(Minimum Viable Product)是 PoC 验证通过后的下一步。区别在于:PoC 只要"能跑",MVP 要"能用在真实业务中"。这个阶段开始要考虑性能、稳定性、错误处理、用户体验。
从"小范围可用"到"全公司都在用",中间隔着一座山。并发量上来了、数据量上来了、用户行为千奇百怪了——这个阶段是工程能力的真正考验。
上线不是终点,是起点。AI 系统和传统软件最大的不同是:它会漂移。数据变了、用户行为变了、模型输出质量会悄悄下降。FDE 的运维阶段不是"出了问题修一下",而是"主动发现问题、持续优化"。
以下不是杜撰,每一个都有真实项目对应。了解这些"死法",你就知道每个阶段为什么要做那些"看起来多余"的事。
这一章不讲概念,讲实操。每个技术主题都配最小可运行代码、真实参数配置、和你在文档里看不到的坑。学完这章,你应该能动手搭一个能跑的 AI 系统。
RAG 的思路极其简单:先从你的文档库找到相关段落,再把这些段落连同问题一起发给大模型。就像开卷考试——模型看着资料回答,而不是凭记忆编。
# pip install langchain chromadb openai
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
# 1. 加载文档
loader = PyPDFLoader("company_rules.pdf")
docs = loader.load()
# 2. 切分文档——这步最重要,后面讲为什么
splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每块 500 字符
chunk_overlap=50, # 相邻块重叠 50 字符
separators=["\n\n", "\n", "。", ",", " "] # 按段落→行→句→逗号切
)
chunks = splitter.split_documents(docs)
# 3. 向量化 + 存入 ChromaDB
embeddings = HuggingFaceEmbeddings(
model_name="BAAI/bge-small-zh-v1.5" # 中文 Embedding 模型
)
vectorstore = Chroma.from_documents(chunks, embeddings, persist_directory="./chroma_db")
# 4. 构建检索链
retriever = vectorstore.as_retriever(
search_type="similarity",
search_kwargs={"k": 5} # 检索 Top 5 相关段落
)
# 5. 生成答案
llm = ChatOpenAI(model="deepseek-chat", temperature=0)
qa = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True # 返回引用来源
)
result = qa.invoke({"query": "年假最多能请几天?"})
print(result["result"])
print("来源文档:", [doc.metadata for doc in result["source_documents"]])
分块大小直接影响检索质量。以下是同一套文档、同一批问题,不同 chunk_size 的实测对比:
| chunk_size | overlap | 准确率 | 问题分析 |
|---|---|---|---|
| 200 字符 | 0 | 42% | 太碎,关键信息被切断,模型只看到半句话 |
| 200 字符 | 50 | 51% | 好一点但仍然太碎 |
| 500 字符 | 50 | 78% | 最佳——一个完整段落+上下文衔接 |
| 1000 字符 | 100 | 71% | 太长,一个 chunk 混了多个主题,检索噪声大 |
| 2000 字符 | 200 | 58% | 严重稀释——Top 5 检索结果几乎覆盖整个文档 |
普通对话是"你问我答",Agent 是"你说目标,它自己拆步骤、调工具、执行任务、返回结果"。比如"帮我查上周销售额并生成报告发邮件",Agent 会自动调用数据库查询工具→文档生成工具→邮件发送工具来完成。
Agent 的底层机制是 Function Calling:模型本身不能执行代码,但它能告诉你的程序"请调用 weather_api(city="北京")",你的程序执行后把结果返回给模型,模型再决定下一步。
模型边想边干,每一步基于上一步结果决定下一步,直到任务完成
# pip install langchain langgraph openai
from langchain_openai import ChatOpenAI
from langchain.tools import Tool
from langgraph.prebuilt import create_react_agent
# 1. 定义工具
def search_web(query: str) -> str:
"""搜索网络获取最新信息"""
# 这里用你自己的搜索 API
return f"搜索结果:{query} 的相关信息..."
def calculator(expression: str) -> str:
"""数学计算"""
try:
return str(eval(expression))
except:
return "计算失败"
tools = [
Tool(name="search", func=search_web, description="搜索网络获取最新信息"),
Tool(name="calculator", func=calculator, description="数学计算"),
]
# 2. 创建 Agent
llm = ChatOpenAI(model="deepseek-chat", temperature=0)
agent = create_react_agent(llm, tools)
# 3. 执行任务
result = agent.invoke({
"messages": [{"role": "user", "content": "查一下北京今天的气温,然后换算成华氏度"}]
})
for msg in result["messages"]:
print(f"[{msg.type}] {msg.content}")
# 直接调 API 的 Function Calling
import requests
response = requests.post(
"https://api.deepseek.com/v1/chat/completions",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"model": "deepseek-chat",
"messages": [
{"role": "user", "content": "北京今天多少度?换算成华氏度"}
],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名"}
},
"required": ["city"]
}
}
}],
"tool_choice": "auto"
}
)
# 模型返回的是"请调用 get_weather(city='北京')"
# 你执行后把结果再发给模型,它再决定下一步
description 写得不好。vLLM 是目前最主流的开源大模型推理框架。它的吞吐量是原生 HuggingFace 推理的 10-20 倍,靠的是两项核心技术:Continuous Batching(连续批处理,请求不用等齐就处理)和 PagedAttention(分页注意力,像操作系统管理虚拟内存一样管理 KV Cache)。
# 安装
pip install vllm
# 启动模型服务(兼容 OpenAI API 格式)
vllm serve Qwen/Qwen2.5-7B-Instruct \
--port 8000 \
--max-model-len 4096 \
--gpu-memory-utilization 0.9 \
--tensor-parallel-size 1
# 验证服务
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-7B-Instruct",
"messages": [{"role": "user", "content": "你好"}],
"temperature": 0
}'
模型权重显存 = 参数量 × 精度系数
总显存 = 模型权重 + KV Cache + 激活值
经验:KV Cache 约占模型权重的 20-50%,激活值约 10-20%
docker run --gpus all vllm/vllm-openai:latest ...--max-model-len 4096 跑起来,再根据业务需求逐步调大。监控 nvidia-smi 看显存使用率。你是{company_name}的智能问答助手。
【你的职责】
基于以下检索到的参考材料,回答用户的问题。
【参考材料】
{retrieved_context}
【规则】
1. 只基于参考材料回答,不要使用材料以外的知识
2. 如果参考材料中没有相关信息,请回答"抱歉,我没有找到相关信息"
3. 回答时请标注来源,格式为 [来源: 文档名]
4. 如果用户的问题不清晰,请追问以明确意图
【用户问题】
{user_question}
【请回答】
请分析以下工单内容,输出 JSON 格式的分类结果。
工单内容:{ticket_content}
输出格式:
{
"category": "分类名称(技术/业务/投诉/咨询)",
"priority": "优先级(高/中/低)",
"summary": "一句话摘要",
"suggested_action": "建议处理方式"
}
注意:只输出 JSON,不要输出其他任何内容。
response_format={"type": "json_object"} 强制 JSON 输出,或在后端用正则提取 {...} 部分。AI 系统的输出是不确定的——同一个输入,每次结果可能不同。你怎么知道它"好不好"?没有评估,你说"效果不错"就是拍脑袋。客户验收要数据,上线后要监控漂移,对比方案要客观标准——评估是 AI 系统的体检报告。
| 维度 | 衡量什么 | 怎么量化 |
|---|---|---|
| 准确性 | 答案对不对 | 人工标注金标准,算准确率/召回率 |
| 相关性 | 答案和问题是否相关 | LLM-as-Judge 打分 1-5 |
| 完整性 | 是否漏了关键信息 | 金标准覆盖关键词命中率 |
| 安全性 | 有没有有害输出 | 安全测试集 + 规则过滤 |
| 延迟 | 响应快不快 | P50/P95/P99 响应时间 |
| 成本 | Token 消耗 | 每次调用平均 Token 数 |
import json
from openai import OpenAI
client = OpenAI()
def llm_judge(question, answer, reference):
"""用大模型给另一个大模型的回答打分"""
prompt = f"""请给以下回答打分(1-5分),评估维度:
- 准确性:回答是否正确
- 相关性:回答是否切题
- 完整性:是否遗漏关键信息
问题:{question}
标准答案:{reference}
待评回答:{answer}
请输出 JSON:
{{"accuracy": 1-5, "relevance": 1-5, "completeness": 1-5, "total": 总分, "reason": "评分理由"}}
"""
resp = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"},
temperature=0
)
return json.loads(resp.choices[0].message.content)
# 批量评估
test_cases = [
{"q": "年假几天?", "ref": "5天", "ans": "根据规定年假为5天"},
# ... 更多测试用例
]
scores = []
for tc in test_cases:
result = llm_judge(tc["q"], tc["ans"], tc["ref"])
scores.append(result["total"])
print(f"Q: {tc['q']} | Score: {result['total']}/15 | {result['reason']}")
print(f"\n平均分: {sum(scores)/len(scores):.1f} / 15")
这一章不讲理论,讲真实项目从需求到上线的完整过程,包括踩了什么坑、怎么解决的、最终效果如何。每个案例统一结构:背景→需求翻译→技术方案→踩坑记录→效果数据→复盘。
某大型制造业企业,工厂 2000+ 人,车间操作规程、设备手册、安全规范等文档共计 8000+ 份 PDF/Word,散落在各部门共享盘里。新员工入职要花 2-3 周才能熟悉常用文档,老员工遇到不常见的设备问题也要翻半天手册。
version: '3.8'
services:
vllm:
image: vllm/vllm-openai:latest
runtime: nvidia
command: --model Qwen/Qwen2.5-14B-Instruct --port 8000 --max-model-len 4096 --quantization awq
ports: ["8000:8000"]
volumes: ["./models:/root/.cache/huggingface"]
milvus:
image: milvusdb/milvus:latest
ports: ["19530:19530"]
volumes: ["./milvus_data:/var/lib/milvus"]
rag-api:
build: .
ports: ["5000:5000"]
depends_on: [vllm, milvus]
environment:
- VLLM_URL=http://vllm:8000
- MILVUS_HOST=milvus
扫描件经 OCR 后出现大量错字、断句,Embedding 质量极差,检索准确率只有 40%。
用户问"设备 X 的操作规程",检索到了 2019 年的旧版和 2024 年的新版,模型不知道用哪个,回答混乱。
version 和 effective_date 元数据。检索时加过滤条件 effective_date >= 当前日期,只返回最新版本。白班 200 人同时用,vLLM 并发队列排满,P95 延迟从 2 秒飙到 12 秒。
gpu-memory-utilization 从 0.9 调到 0.95,增加 KV Cache 空间;② 加 Redis 缓存高频问题的答案(命中率约 30%);③ 前端加排队提示。P95 延迟降到 3.5 秒。某城商行信用卡中心,日均客服工单 5000+ 条,20 个人工客服处理。其中 60% 是重复性问题(账单查询、额度调整、积分兑换),人工处理平均 4 分钟/单。
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
from langgraph.checkpoint.memory import MemorySaver
class AgentState(TypedDict):
ticket: str # 原始工单
category: str # 分类结果
query_result: str # 查询结果
draft: str # 回复草稿
approved: bool # 人工是否通过
final_response: str # 最终回复
def classify_ticket(state):
# 调用模型分类工单
...
def query_info(state):
# Function Calling 查银行 API
...
def draft_response(state):
# 生成回复草稿
...
def human_review(state):
# 等待人工审核(LangGraph interrupt)
...
def send_response(state):
# 发送回复 + 写审计日志
...
# 构建状态图
graph = StateGraph(AgentState)
graph.add_node("classify", classify_ticket)
graph.add_node("query", query_info)
graph.add_node("draft", draft_response)
graph.add_node("review", human_review)
graph.add_node("send", send_response)
graph.add_edge("classify", "query")
graph.add_edge("query", "draft")
graph.add_edge("draft", "review")
graph.add_conditional_edges("review", lambda s: "send" if s["approved"] else "draft")
graph.add_edge("send", END)
# 编译(加 MemorySaver 做状态持久化)
app = graph.compile(checkpointer=MemorySaver())
模型把"查账单"和"查额度"搞混了,查了额度但用户问的是账单。因为工具描述写得不够清晰。
"get_bill_summary:当用户询问账单明细、消费记录时调用" vs "get_credit_limit:当用户询问额度、可用额度时调用"。调错率从 15% 降到 2%。Agent 草拟了回复,但客服要逐条读、逐条改。20 个客服审 2500 条/天,平均 30 秒/条,反而比以前更慢了。
每条工单记录全链路(5 个步骤的输入输出),2500 条/天 × 5 步 = 12500 条日志/天,数据库撑不住。
某省级政务部门,要求在完全断网的内网环境部署 AI 写作辅助系统。不能联网下载模型、不能调外部 API、GPU 是国产华为昇腾芯片。这是 FDE 遇到的最极端环境——所有常规方案全部失效。
FDE 不是纯技术岗。会写代码能入门,但能把项目做成的,靠的是沟通、需求挖掘、预期管理这些"软技能"。这一章不讲代码,讲人——怎么跟客户打交道、怎么把技术讲给非技术人听、怎么管理预期。
客户说出来的需求 80% 不是真实需求。FDE 的工作是用对的提问方式把真实痛点挖出来。以下是实战中验证有效的话术模板:
| 客户说什么 | 不要怎么问 | 应该怎么问 |
|---|---|---|
| "我们要用 AI 提效" | "你们想用 AI 做什么?"(太空泛) | "你们团队每天最耗时间的 3 件事是什么?" |
| "能不能做个智能客服" | "好的我来做"(直接接需求) | "现在客服每天大概接多少电话?最常见的问题是什么?解决一个平均要多久?" |
| "这个能不能用 AI 做" | "能"或"不能"(二极管思维) | "能做到 80% 的效果,但最后 20% 需要人工兜底。你觉得这个方案可行吗?" |
| "效果不好,要改进" | "哪里不好?"(太模糊) | "能给我一个具体的不满意的例子吗?期望的结果和实际的结果分别是什么?" |
| "能不能再快一点" | "我试试"(没有基准) | "现在平均 8 秒,目标多少秒可以接受?2 秒需要加 GPU,有预算吗?" |
客户老板经常提不切实际的需求——"让 AI 100% 准确""用 AI 替代所有人工""一周内上线"。直接说"做不到"会丢信任,FDE 的话术是"做不到 X,但可以做到 Y":
"目前能做到 [量化结果],剩余 [比例] 需要 [兜底方案],整体 [效果提升]。如果要做到 [更高目标],需要 [额外投入],您看值不值得?"
这个公式的核心是:永远给出选项,让老板做决策。你不是说"不行",你是说"这样行,那样也行但更贵,你选"。
Demo 演示是 FDE 的高光时刻,也是最容易翻车的时刻。以下是血泪经验:
学完技术只是起点。这一章讲怎么把学的东西变成工作——三条职业路径、薪资行情、面试真题、作品集怎么搭。
在 AI 公司(OpenAI/Anthropic/国内大厂)做 FDE,持续深挖技术。
成长线:初级 FDE → 高级 FDE → Staff FDE → 技术专家
薪资线:25-40K → 40-70K → 70-120K
适合谁:享受写代码、喜欢解决硬技术问题的人
在传统企业(银行/制造/政务)做内部 AI 负责人。
成长线:FDE → AI 项目经理 → AI 部门负责人 → CTO
薪资线:20-35K → 35-55K → 55-100K+
适合谁:沟通能力强、理解业务比理解代码快的人
自由接单,帮不同企业做 AI 落地,按项目收费。
成长线:接单 FDE → 团队负责人 → 创业
收入线:日薪 2-5K → 项目 10-50万 → 年百万+
适合谁:自律、有人脉、享受不确定性的人
参考答案:三个维度——
加分项:提到"持续监控"而非"一次性评估",提到用 Promptfoo 做回归测试,提到数据集要随业务迭代更新。
参考答案:
vllm serve --quantization awq --max-model-len 2048 --gpu-memory-utilization 0.9参考答案:多层防护——
参考答案:分层排查——
面试和竞标看的是"你交付过什么",不是"你学过什么"。至少准备三个项目:
交互工具和学习辅助——显存计算器、Token 计数器、情景模拟剧、自测题、术语翻卡、进度打卡。学完一章用对应工具练手。
部署模型前必算。拖滑块选模型参数量和量化精度,实时估算需要的显存。
输入文本,实时估算 Token 数和 API 成本。中文约 1-2 token/字,英文约 1-1.5 token/词。
客户说了这句话,你怎么回?选择你的回答,立刻看到后果。练软技能最有效的方式。
答错自动进错题本。复习时优先推错题。全部答完显示得分。
正面看英文缩写,点开翻面看人话解释。不确定的反复翻,直到记住。
PoC 启动前、上线前、验收时——三份清单照着走,不漏项。
学完一个模块打个勾,进度自动保存在浏览器。换个电脑要重新打卡。