13 KiB
Executable File
阶段三 · 小点 6:其他主流方案(选学)
所属:阶段三 主流 Agent 开发框架 定位:前 5 讲覆盖了"代码框架派"的主力。这一讲补齐三块拼图:OpenAI 官方的托管式(Assistants API)、微软的插件化(Semantic Kernel)、以及低代码平台(Dify)。它们各有最适配场景,读完你会对"什么时候该用什么"有完整判断力。
精简大纲
- OpenAI Assistants API(托管式 Agent)
- Semantic Kernel(微软插件化框架)
- Dify 低代码平台
- 选型边界总结
学习内容详情
1. OpenAI Assistants API(快速原型 / Demo)
1.1 三个核心对象
graph TD
A[Assistant 助理: 角色+工具定义在云端] --> D[Thread 会话线程: 历史存云端]
D --> E[Run 一次执行]
E --> F{状态轮询}
F -->|queued/in_progress| E
F -->|completed| G[结束]
F -->|requires_action| H[要你执行函数调用后回传] --> E
- Assistant(助理): 角色 + 工具全部定义在云端。
- Thread(会话线程): 托管式会话(历史存 OpenAI 云端,对照 LangGraph 的 thread_id + Checkpointer,只是托管方换成 OpenAI)。
- Run(一次执行): 异步任务轮询,状态含
queued → in_progress → completed / failed / requires_action(要你执行函数调用后回传)。
from openai import OpenAI
client = OpenAI(api_key="sk-xxx")
# ① 建一个"助理" (云端保存角色+工具)
asst = client.beta.assistants.create(
name="数据分析助手",
instructions="你是数据分析助理, 只说结论与依据", # 角色设定存云端
model="gpt-4o",
)
# ② 建一个"会话线程"
thread = client.beta.threads.create()
# ③ 发消息 + 触发"一次执行"
client.beta.threads.messages.create(
thread.id, role="user", content="帮我分析销售数据"
)
run = client.beta.threads.runs.create(thread.id, assistant_id=asst.id)
# ④ 轮询 Run 状态, 直到完成
while run.status not in ("completed", "failed", "requires_action"):
run = client.beta.threads.runs.retrieve(thread.id, run.id)
print("最终状态:", run.status)
🔬 深度理解 · Assistants API 的 Assistant / Thread / Run 三对象:
- 本质:这是 OpenAI 提供的「托管式 Agent」建模——你在云端定义"这个 AI 是谁、会哪些工具"(Assistant)、"一段会话的历史"(Thread)、"一次具体的执行与推进"(Run),状态与恢复都由服务端替你管理。
- 机制:Assistant 把角色/工具定义存于云端;Thread 存会话消息,天然对标 LangGraph 的 thread_id + Checkpointer,只是托管方换成 OpenAI;Run 是异步任务,需轮询其状态,遇到
requires_action表示要你执行函数调用后回传tool_outputs并继续。- 为什么重要:它极大降低演示 / 原型的搭建成本——不用自己管状态与工具循环;但代价是「模型思考」与「工具执行」之间无法插入自定义逻辑,可控性被锁在黑盒里。
- 易错点:误以为 Run 是一次性同步调用,实际要轮询;
requires_action后必须回传工具结果再 poll 才会继续;也容易忽略 Thread 有创建数量上限、用完要清理。
⏳ 短期可不深究:Run 那套
queued → in_progress → requires_action状态机与tool_outputs回传的轮询写法细节,第一遍知道「它是异步任务、要轮询、要你执行工具后回传」即可;开原型时照着官方示例抄就行。
- 多轮对话:继续往同一
thread加消息即可;用完记得清理(Assistants/Threads 有数量上限)。
1.2 黑盒代价清单(为什么生产不推荐)
| 代价 | 说明 |
|---|---|
| 无法插入自定义逻辑 | 「模型思考」和「工具执行」之间不能加审批 / 路由 / 状态校验 |
| Bad-case 排查弱 | Run 内部执行细节不完全可见 |
| 深度绑定 OpenAI | 换模型 = 重写集成层;国内合规数据出境是硬伤 |
| 对照 | LangGraph 等价能力全部在你掌控之下 |
一句话:Assistants API 适合快速验证"对话式 Agent"原型,但凡是生产要插逻辑 / 要可控 / 要换模型,就回到 LangGraph。
2. Semantic Kernel(SK,微软)
⚠️ 状态提示(2026):微软已将 Semantic Kernel 与 AutoGen 合并为 Microsoft Agent Framework(MAF),SK 进入维护模式,新项目建议转向 MAF。本节保留 SK 的「插件化编排」思想,用于理解其与代码框架的差异。
2.1 插件化编排
graph LR
U[用户意图] --> P[Planner 规划器: 自动串联插件]
P --> A[Plugin 调模型]
P --> B[Plugin 查库]
P --> C[Plugin 发邮件]
- 插件化编排框架:把每个能力(调模型 / 查库 / 发邮件)封装成 Plugin,由 **Planner(规划器)**按用户意图自动串联插件。
- Python / C# 双语言一等支持——团队技术栈是 .NET 或 Python/.NET 混合时优先考虑;纯 Python 团队生态和社区不如 LangChain 系。
🔬 深度理解 · Semantic Kernel 的插件化编排(Plugin + Planner):
- 本质:SK 把「一个可复用的能力单元」(调模型 / 查库 / 发邮件)抽象成 Plugin,再由 Planner 按用户意图自动把这些插件串成一条执行计划——把「技能封装」和「技能调度」分离开。
- 机制:每个 Plugin / Kernel Function 声明名称、语义描述与参数;Planner 面向用户意图,调用 LLM 决定「需要哪些插件、按什么顺序、传什么参数」,再按计划执行。这与 LangChain「手写 LCEL 管道」的确定式编排形成对照——SK 偏向「运行时动态规划」。
- 为什么重要:它让「能力」与「编排」解耦、可复用,动态调度适合意图多变的场景;但动态计划不如手写管道可控、可复现。
- 易错点:Planner 可能规划出错或加载过多插件导致上下文膨胀;且 SK 已进维护模式(被 MAF 合并),新项目路径应跟着 MAF 走,别在 SK 老 API 上深挖。
⏳ 短期可不深究:SK 的 Planner 底层「怎么套用 LLM 生成执行计划」的实现细节偏复杂,且 SK 已进维护模式(被 MAF 合并),新项目建议直接看 MAF——这里只需领会「技能封装 + 动态调度」这个思想差异即可。
3. Dify(低代码平台)
- 拖拽式编排 Agent,适合非技术团队快速验证想法;但灵活性受平台限制。
graph LR
A[想法验证期: Dify 拖拽 一小时出Demo] -->|需求变复杂: 要加循环/审批/自定义重试| B[迁移到 LangGraph 代码框架]
- 低代码 vs 代码框架的边界: 想法验证期用 Dify 快速试(一小时出 Demo);验证成功、需求变复杂后迁移到 LangGraph。
- 判断信号: 当你在 Dify 里想「加个循环」「人工审批」「自定义重试逻辑」却做不到时,就是迁移时机。
4. 选型边界总结
| 需求 | 首选 |
|---|---|
| 快速验证想法 | Dify 或手写 Demo |
| 托管式会话原型 | Assistants API |
| Python/.NET 混合团队 | Semantic Kernel |
| 生产级可控 Agent | LangGraph |
| 文档知识为核心 | LlamaIndex |
# 一个"按需求返回选型"的决策助手(对照阶段二第4讲的决策树)
def choose_engine(needs: dict) -> str:
if needs["doc_core"]:
return "LlamaIndex + LangGraph" # 文档知识为核心
if needs["managed_session"]:
return "Assistants API (仅原型)" # 要托管会话
if needs["dotnet_stack"]:
return "Semantic Kernel" # .NET混合团队
if needs["no_code_team"]:
return "Dify → 复杂后迁 LangGraph" # 非技术团队
if needs["need_control"] or needs["prod"]:
return "LangGraph" # 生产/要控制
return "手写 ReAct 或 Dify Demo" # 快速验证
print(choose_engine({"prod": True, "need_control": True, "doc_core": False,
"managed_session": False, "dotnet_stack": False, "no_code_team": False}))
# LangGraph
本节自检
- 能说清 Assistants API 的黑盒代价与 LangGraph 的对照
- 能判断低代码平台何时该迁移到代码框架
本节配套思考题(快速入门的检验)
- Assistants API 的 Thread 和 LangGraph 的 Checkpointer + thread_id 有什么本质相似与不同(谁托管、谁掌控)?
- 为什么"要求在模型调用工具前插入人工审批"就判了 Assistants API 的死刑?
- Dify 这类低代码平台,出现什么"信号"说明该迁到 LangGraph 了?举一个你认同的例子。
- Semantic Kernel 的准确适配场景是什么?纯 Python 团队为什么未必优先选它?
本节常见面试题(深度解析)
针对本节核心知识的面试高频点,配合"本质+机制"式理解,能让你答得既有深度又有广度。
面试题 1:Assistants API 的 Thread 与 LangGraph 的 Checkpointer + thread_id 本质相似与不同是什么?
- 面试官想考察:是否理解"托管的会话状态 vs 自掌控的状态持久化"这一核心差异。
- 专业作答(含深度):
- 相似:两者都以"会话 ID"(Thread / thread_id)维持续航状态,都支持多轮记忆与恢复,都是"对话状态"的载体。
- 不同:是谁托管——Thread 的状态存在 OpenAI 云端、你通过 API 间接操作;LangGraph 的 Checkpointer 由你指定存储后端(本地 / Redis / Postgres)、完全掌控。
- 含义:Assistants 更省事但不可迁移(换模型 = 换平台)、难以定制;LangGraph 更灵活可控、可水平扩展、可审计。
- 结论:托管式适合快速原型和"状态无所谓"的 Demo;要自定义逻辑、控制存储位置、可运维,选自托管代码框架。
- 加分亮点 / 深度追问:提"国内合规数据出境"这一现实约束;追问常是"Thread 能加自定义业务字段吗"——答:托管式会话基本只能存消息,自定义状态能力弱,这正是其黑盒代价之一。
面试题 2:为什么"要求在模型调用工具前插入人工审批"就判了 Assistants API 的死刑?
- 面试官想考察:对"是否允许在图的节点间插入自定义逻辑"这一编排自由度关键点的理解。
- 专业作答(含深度):
- Assistants API 把「模型思考 → 工具执行」封装在 Run 内部,Run 作为一个原子动作要么
requires_action要你回传、要么跑完,你不能在两者之间插入审批 / 路由 / 状态校验这类自定义步骤。 - 等价能力在 LangGraph:把"人工审批"做成一个普通 Node 放在「工具节点」之前,用
interrupt挂起等人工确认,再resume放行——你想插什么都行。 - 本质差异是「黑盒 vs 白盒」:托管式给你"托管能力"但拿走"干预能力";只要业务需要精确控制每一步,托管式就不适用。
- 结论:这是判断"要不要上代码框架"的一条硬性信号——有审批 / 自定义路由 / 状态校验需求就别用托管式。
- Assistants API 把「模型思考 → 工具执行」封装在 Run 内部,Run 作为一个原子动作要么
- 加分亮点 / 深度追问:明确"人工审批本质是在图的状态流里加一个等待人工输入的节点";追问常是"Demo 阶段可以先用 Assistants 吗"——答:可以,只要接受后期要重写集成层。
面试题 3:托管式 / 插件化(SK)/ 低代码(Dify)/ 代码框架(LangGraph)各自主导什么场景?出现什么"信号"说明该往代码框架迁移?
- 面试官想考察:对 Agent 技术栈宏观选型与"复杂度迁移时机"的判断力。
- 专业作答(含深度):
- 定位梳理:Assistants 适合托管会话原型;Dify 适合非技术团队快速验证想法;SK / MAF 适合需要插件复用与 .NET/Python 混合栈;LangGraph 是生产级可控 Agent 的主选。
- 迁移信号:当你发现 "加个循环做不到""加人工审批做不到""自定义重试做不到""跨会话状态难以管理"时,就说明当前方案的表达力已到天花板,该迁到能自由编排的代码框架。
- 判断原则:先问"是否需要精确控制、是否要自定义逻辑、是否要换模型 / 数据出境";需要的用代码框架,纯验证期的可用低代码 / 托管式。
- 演进路径常见:Dify / Assistants 验证 → 迁 LangGraph + LlamaIndex 组合成生产架构。
- 加分亮点 / 深度追问:讲"低代码 / 托管的优点恰恰也是它的约束来源——上手快 = 可定制范围小";追问常是"给一个具体迁移例子"——答:在 Dify 里想做跨步骤循环与审批做不到时,就是迁移时点。