【必收藏】AI规划模式实战:从零实现旅行规划Agent,LangChain+LangGraph详解

一.简介

规划模式的本质

在人工智能领域,真正的智能不仅表现为对即时刺激的响应,更体现在对未来行动的前瞻性思考。规划模式是AI Agent展现高级智能的核心机制,它使系统能够将复杂目标分解为可执行的步骤序列,从而系统性地从当前状态过渡到期望状态。

规划Agent就像一位战略家,当面对"组织一次国际会议"这样的复杂任务时,它不会盲目行动,而是首先分析现状(预算、参与者、时间限制)和目标(成功的会议体验),然后设计一条最优路径。这个过程不是预设的,而是动态生成的,能够根据环境变化实时调整。

规划的双重特性:灵活性与可靠性

规划模式的精髓在于其适应性。当遇到意外障碍——如关键演讲者取消出席或场地突然不可用——优秀的规划Agent不会崩溃,而是将这些新约束纳入考量,重新评估并调整策略。这种弹性使AI系统能够在不确定的环境中保持功能。

然而,并非所有场景都需要完全动态的规划。对于那些解决方案明确且重复性高的任务,限制Agent的自主性反而能提高效率和可预测性。这就引出了一个关键决策:何时需要探索"如何做",何时只需执行已知流程?

规划模式的应用领域

规划模式在多个领域展现其价值:

在业务流程管理中,规划Agent可以协调复杂的跨部门项目,如产品发布,将高级目标转化为具体的任务序列,管理依赖关系并优化资源分配。

在科学研究中,规划模式帮助设计实验方案,从假设验证到数据分析,创建系统性的研究路径。

在教育领域,个性化学习路径规划Agent可以根据学生表现动态调整课程内容和学习节奏,确保最优学习效果。

二.案例实战:旅行规划 Agent

分别使用langchain和langgraph框架创建一个旅行规划Agent,它能够根据用户偏好制定详细的旅行计划。

三.langchain实现

from typing import Dict
import json
from langchain_classic.memory import ConversationBufferMemory
from langchain_core.output_parsers import BaseOutputParser
from langchain_core.prompts import PromptTemplate
# 初始化llm
from init_client import init_llm
llm = init_llm(0.7)
# 定义输出解析器,将模型输出转换为结构化数据
class TravelPlanParser(BaseOutputParser):
def parse(self, text: str) -> Dict:
try:
# 尝试提取JSON部分
start_idx = text.find('{')
end_idx = text.rfind('}') + 1
if start_idx != -1 and end_idx != 0:
json_str = text[start_idx:end_idx]
return json.loads(json_str)
else:
# 如果没有找到JSON,返回原始文本
return {"plan": text}
except Exception as e:
print(f"解析错误: {e}")
return {"plan": text}
# 创建规划模板
planning_template = """
你是一位专业的旅行规划师,擅长根据客户需求创建详细的旅行计划。
客户需求:
- 目的地:{destination}
- 旅行时长:{duration}
- 预算:{budget}
- 兴趣偏好:{interests}
- 出行时间:{travel_date}
请创建一个详细的旅行计划,包括:
1. 每日行程安排
2. 推荐景点和活动
3. 餐饮建议
4. 交通方案
5. 预算分配
请以JSON格式返回计划,结构如下:
{{
"daily_itinerary": [
{{
"day": 1,
"activities": ["活动1", "活动2"],
"meals": ["早餐建议", "午餐建议", "晚餐建议"],
"transportation": "当日交通方案"
}}
],
"budget_breakdown": {{
"accommodation": "预算金额",
"food": "预算金额",
"activities": "预算金额",
"transportation": "预算金额"
}},
"general_tips": ["旅行提示1", "旅行提示2"]
}}
"""
# 创建调整模板
adjustment_template = """
根据新的情况调整旅行计划:
原始计划:
{original_plan}
新情况/调整需求:
{adjustment_request}
请提供调整后的旅行计划,保持相同的JSON格式。
"""
# 创建提示模板
planning_prompt = PromptTemplate(
input_variables=["destination", "duration", "budget", "interests", "travel_date"],
template=planning_template
)
adjustment_prompt = PromptTemplate(
input_variables=["original_plan", "adjustment_request"],
template=adjustment_template
)
# 使用LCEL语法创建链
planning_chain = planning_prompt | llm | TravelPlanParser()
adjustment_chain = adjustment_prompt | llm | TravelPlanParser()
# 创建记忆组件
memory = ConversationBufferMemory()
# 定义旅行规划Agent类
class TravelPlannerAgent:
def __init__(self):
self.current_plan = None
self.planning_chain = planning_chain
self.adjustment_chain = adjustment_chain
self.memory = memory
def create_plan(self, destination, duration, budget, interests, travel_date):
"""创建初始旅行计划"""
response = self.planning_chain.invoke({
"destination": destination,
"duration": duration,
"budget": budget,
"interests": interests,
"travel_date": travel_date
})
self.current_plan = response
self.memory.save_context(
{"input": f"创建旅行计划到{destination},时长{duration}天,预算{budget}"},
{"output": str(response)}
)
return response
def adjust_plan(self, adjustment_request):
"""根据新情况调整计划"""
if not self.current_plan:
return "没有可调整的计划,请先创建计划。"
response = self.adjustment_chain.invoke({
"original_plan": str(self.current_plan),
"adjustment_request": adjustment_request
})
self.current_plan = response
self.memory.save_context(
{"input": f"调整计划:{adjustment_request}"},
{"output": str(response)}
)
return response
def get_current_plan(self):
"""获取当前计划"""
return self.current_plan
# 使用示例
if __name__ == "__main__":
# 初始化旅行规划Agent
agent = TravelPlannerAgent()
# 创建初始计划
print("## 创建初始旅行计划 ##")
initial_plan = agent.create_plan(
destination="中国北京",
duration="5天",
budget="10000元",
interests="传统文化、美食、古迹",
travel_date="2026年1月"
)
print("初始计划:")
print(json.dumps(initial_plan, indent=2, ensure_ascii=False))
# 调整计划
print("\n## 调整旅行计划 ##")
adjusted_plan = agent.adjust_plan("预算减少到8000元,并增加一天行程")
print("调整后的计划:")
print(json.dumps(adjusted_plan, indent=2, ensure_ascii=False))

代码解释:

整个代码可以分为以下几个主要部分:
导入模块:引入所需的库。
自定义输出解析器 (TravelPlanParser):一个关键组件,用于将大语言模型的原始文本输出转换为机器可读的结构化数据(Python字典)。
初始化核心组件:设置语言模型(LLM)和提示模板。
创建处理链:使用 LangChain 的表达式语法(LCEL)将提示、模型和解析器串联成两个可执行的“链”——一个用于创建计划,一个用于调整计划。
封装 Agent 类 (TravelPlannerAgent):将处理链和状态(如当前计划、记忆)封装成一个易于使用的类。
执行示例:演示如何实例化并使用这个 Agent。
1. 自定义输出解析器 (TravelPlanParser)
class TravelPlanParser(BaseOutputParser):
def parse(self, text: str) -> Dict:
try:
# 尝试提取JSON部分
start_idx = text.find('{')
end_idx = text.rfind('}') + 1
if start_idx != -1 and end_idx != 0:
json_str = text[start_idx:end_idx]
return json.loads(json_str)
else:
return {"plan": text}
except Exception as e:
print(f"解析错误: {e}")
return {"plan": text}
目的:LLM 的输出是纯文本。为了让程序能方便地使用计划内容(比如访问某一天的行程),我们需要将文本转换为 Python 字典。
工作原理:
parse 方法接收 LLM 返回的原始文本。
text.find('{') 和 text.rfind('}'):智能地定位文本中 JSON 格式的开始和结束位置。这很关键,因为 LLM 有时会在 JSON 前后添加一些解释性文字,如“好的,这是为您生成的计划:{...}”。
json.loads(json_str):将提取出的 JSON 字符串解析成一个 Python 字典。
try...except:这是一个健壮性设计。如果 LLM 的输出格式不正确,导致无法解析,程序不会崩溃,而是将原始文本包装在一个字典中返回,保证了流程的连续性。
2. 初始化核心组件
# 初始化llm
from init_client import init_llm
llm = init_llm(0.7)
# 创建规划模板
planning_template = """
你是一位专业的旅行规划师...
客户需求:
- 目的地:{destination}
...
请以JSON格式返回计划,结构如下:
{{
"daily_itinerary": [ ... ],
...
}}
"""
# 创建提示模板
planning_prompt = PromptTemplate(
input_variables=["destination", "duration", "budget", "interests", "travel_date"],
template=planning_template
)
llm = init_llm(0.7):
temperature=0.7: 这是一个非常重要的参数,控制输出的随机性。0.7 意味着模型在生成内容时既有一定的创造性(适合规划行程),又不会过于天马行空,能较好地遵循指令。
提示模板 (planning_template 和 planning_prompt):
角色扮演:你是一位专业的旅行规划师... 这部分设定了 LLM 的身份,有助于它生成更专业、更相关的回答。
变量占位符:{destination}, {duration} 等是占位符,稍后会被具体的用户输入替换。
输出格式指令:请以JSON格式返回计划... 这是整个规划成功的关键。它明确指示 LLM 必须按照给定的 JSON 结构来组织输出,这极大地提高了 TravelPlanParser 解析成功的概率。
PromptTemplate(...) 将这个字符串模板转换成一个 LangChain 对象,使其能够被用于 LCEL 链中。
3. 创建处理链
# 使用LCEL语法创建链
planning_chain = planning_prompt | llm | TravelPlanParser()
adjustment_chain = adjustment_prompt | llm | TravelPlanParser()
这是 LangChain 表达式语言(LCEL)的精髓,它用管道符 | 来表示数据流向,非常直观。
planning_chain 的工作流程:
输入:一个包含 destination, duration 等键的字典。
planning_prompt:接收这个字典,将变量填充到模板中,生成一个完整的提示字符串。
| (管道):将提示字符串传递给下一个组件。
llm:接收提示字符串,调用 DeepSeek API,生成一个原始文本响应。
| (管道):将文本响应传递给下一个组件。
TravelPlanParser():接收文本,将其解析成 Python 字典。
输出:一个结构化的 Python 字典。
adjustment_chain 的工作流程完全相同,只是它使用的是用于调整计划的提示模板。
4. 封装 Agent 类 (TravelPlannerAgent)
class TravelPlannerAgent:
def __init__(self):
self.current_plan = None
self.planning_chain = planning_chain
self.adjustment_chain = adjustment_chain
self.memory = ConversationBufferMemory()
def create_plan(self, destination, duration, budget, interests, travel_date):
response = self.planning_chain.invoke({
"destination": destination,
"duration": duration,
# ...
})
self.current_plan = response
self.memory.save_context(...)
return response
目的:将复杂的逻辑封装成一个简单易用的接口。使用者不需要关心内部的链是如何工作的,只需要调用 create_plan 或 adjust_plan 方法即可。
__init__:
self.current_plan = None: 定义一个实例变量来存储当前的计划状态。这使得 Agent 具有了“记忆”能力,知道自己在处理哪个计划。
self.memory: 初始化对话记忆,虽然本例中未深度使用,但在构建更复杂的对话式 Agent 时至关重要。
create_plan 方法:
self.planning_chain.invoke({...}): 这是调用 LCEL 链的标准方法。传入一个字典,其键与 PromptTemplate 中定义的 input_variables 相匹配。
self.current_plan = response: 将生成的计划保存为 Agent 的当前状态。
self.memory.save_context(...): 将本次交互(用户输入和AI输出)记录到记忆中。
5. 执行示例
if __name__ == "__main__":
agent = TravelPlannerAgent()
# 1. 创建初始计划
initial_plan = agent.create_plan(...)
print(json.dumps(initial_plan, indent=2, ensure_ascii=False))
# 2. 调整计划
adjusted_plan = agent.adjust_plan("预算减少到8000元,并增加一天行程")
print(json.dumps(adjusted_plan, indent=2, ensure_ascii=False))
if __name__ == "__main__":: 这是 Python 的标准写法,确保这部分代码只在脚本被直接运行时执行,而不会在被其他脚本导入时执行。
实例化与调用:
创建一个 TravelPlannerAgent 的实例。
调用 create_plan 方法,传入旅行需求,并打印出结构化的初始计划。json.dumps 用于将 Python 字典格式化为漂亮的 JSON 字符串,ensure_ascii=False 确保中文字符能正常显示。
调用 adjust_plan 方法,传入一个新的约束条件(“预算减少”),并打印出调整后的计划。这完美展示了 Agent 的动态适应性。
总结
这个案例通过一个具体的旅行规划任务,生动地展示了 AI 规划模式的几个核心要素:
目标导向:Agent 的行为由一个高级目标(规划旅行)驱动。
分解与结构化:将复杂任务分解为每日行程、预算等结构化步骤,并要求 LLM 以结构化格式(JSON)输出。
动态适应:当环境变化(预算调整)时,Agent 不是从头再来,而是在现有计划基础上进行修改,体现了规划的灵活性。
模块化设计:通过 LCEL 和类的封装,代码清晰、可复用,易于理解和扩展。这正是一个优秀 AI 系统设计的体现。
这个旅行规划Agent展示了规划模式的核心特性:
目标分解:将"规划旅行"这一复杂目标分解为每日行程、餐饮、交通等具体任务
动态适应:当情况变化(如预算调整)时,能够重新评估并调整计划
结构化输出:生成格式化的旅行计划,便于后续处理
记忆功能:保留交互历史,支持上下文相关的调整

四.langgraph实现

from typing import Dict, List, Optional, TypedDict, Annotated, Literal
import json
import operator
from langchain_core.messages import HumanMessage, AIMessage, BaseMessage
from langchain_core.output_parsers import BaseOutputParser, JsonOutputParser
from langchain_core.prompts import PromptTemplate
from langgraph.graph import StateGraph, END
from langgraph.checkpoint.memory import MemorySaver
# 初始化LLM
from init_client import init_llm
llm = init_llm(0.7)
# 定义输出解析器,将模型输出转换为结构化数据
class TravelPlanParser(BaseOutputParser):
def parse(self, text: str) -> Dict:
try:
# 尝试提取JSON部分
start_idx = text.find('{')
end_idx = text.rfind('}') + 1
if start_idx != -1 and end_idx != 0:
json_str = text[start_idx:end_idx]
return json.loads(json_str)
else:
# 如果没有找到JSON,返回原始文本
return {"plan": text}
except Exception as e:
print(f"解析错误: {e}")
return {"plan": text}
# 定义用户意图解析结果
class UserIntent(TypedDict):
intent: Literal["create", "adjust", "unknown"]
destination: Optional[str]
duration: Optional[str]
budget: Optional[str]
interests: Optional[str]
travel_date: Optional[str]
adjustment_request: Optional[str]
# 定义用户意图解析器
class UserIntentParser(JsonOutputParser):
def parse(self, text: str) -> UserIntent:
try:
result = super().parse(text)
# 确保所有必需的字段都存在
if "intent" not in result:
result["intent"] = "unknown"
return result
except Exception as e:
print(f"用户意图解析错误: {e}")
return {"intent": "unknown"}
# 定义Agent状态
class AgentState(TypedDict):
messages: Annotated[List[BaseMessage], operator.add]
current_plan: Optional[Dict]
destination: Optional[str]
duration: Optional[str]
budget: Optional[str]
interests: Optional[str]
travel_date: Optional[str]
adjustment_request: Optional[str]
user_intent: Optional[str]
# 创建用户意图解析模板
intent_extraction_template = """
你是一个旅行规划助手,需要解析用户的输入,确定他们的意图并提取相关信息。
用户输入:{user_input}
请分析用户输入,确定是创建新的旅行计划还是调整现有计划,并提取相关信息。
请以JSON格式返回结果,包含以下字段:
- intent: 用户意图,只能是 "create"(创建新计划)或 "adjust"(调整现有计划)或 "unknown"(无法确定)
- destination: 目的地(如果是创建计划)
- duration: 旅行时长(如果是创建计划)
- budget: 预算(如果是创建计划)
- interests: 兴趣偏好(如果是创建计划)
- travel_date: 出行时间(如果是创建计划)
- adjustment_request: 调整请求的具体内容(如果是调整计划)
示例:
输入:"我想去巴黎玩5天,预算1万元,喜欢艺术和美食,下个月出发"
输出:{{"intent": "create", "destination": "巴黎", "duration": "5天", "budget": "1万元", "interests": "艺术和美食", "travel_date": "下个月", "adjustment_request": null}}
输入:"把预算减少到8000元,增加一天行程"
输出:{{"intent": "adjust", "destination": null, "duration": null, "budget": null, "interests": null, "travel_date": null, "adjustment_request": "把预算减少到8000元,增加一天行程"}}
"""
# 创建规划模板
planning_template = """
你是一位专业的旅行规划师,擅长根据客户需求创建详细的旅行计划。
客户需求:
- 目的地:{destination}
- 旅行时长:{duration}
- 预算:{budget}
- 兴趣偏好:{interests}
- 出行时间:{travel_date}
请创建一个详细的旅行计划,包括:
1. 每日行程安排
2. 推荐景点和活动
3. 餐饮建议
4. 交通方案
5. 预算分配
请以JSON格式返回计划,结构如下:
{{
"daily_itinerary": [
{{
"day": 1,
"activities": ["活动1", "活动2"],
"meals": ["早餐建议", "午餐建议", "晚餐建议"],
"transportation": "当日交通方案"
}}
],
"budget_breakdown": {{
"accommodation": "预算金额",
"food": "预算金额",
"activities": "预算金额",
"transportation": "预算金额"
}},
"general_tips": ["旅行提示1", "旅行提示2"]
}}
"""
# 创建调整模板
adjustment_template = """
根据新的情况调整旅行计划:
原始计划:
{original_plan}
新情况/调整需求:
{adjustment_request}
请提供调整后的旅行计划,保持相同的JSON格式。
"""
# 创建提示模板
intent_extraction_prompt = PromptTemplate(
input_variables=["user_input"],
template=intent_extraction_template
)
planning_prompt = PromptTemplate(
input_variables=["destination", "duration", "budget", "interests", "travel_date"],
template=planning_template
)
adjustment_prompt = PromptTemplate(
input_variables=["original_plan", "adjustment_request"],
template=adjustment_template
)
# 创建意图解析链
intent_extraction_chain = intent_extraction_prompt | llm | UserIntentParser()
# 定义LangGraph节点函数
def extract_travel_info(state: AgentState):
"""从消息中提取旅行信息"""
last_message = state["messages"][-1]
if isinstance(last_message, HumanMessage):
content = last_message.content
# 使用LLM解析用户意图
try:
intent_result = intent_extraction_chain.invoke({"user_input": content})
intent = intent_result.get("intent", "unknown")
if intent == "create":
# 创建新计划的请求
return {
"user_intent": "create",
"destination": intent_result.get("destination"),
"duration": intent_result.get("duration"),
"budget": intent_result.get("budget"),
"interests": intent_result.get("interests"),
"travel_date": intent_result.get("travel_date"),
"adjustment_request": None
}
elif intent == "adjust":
# 调整计划的请求
return {
"user_intent": "adjust",
"adjustment_request": intent_result.get("adjustment_request"),
"destination": None,
"duration": None,
"budget": None,
"interests": None,
"travel_date": None
}
else:
# 无法确定意图
return {
"user_intent": "unknown",
"messages": [AIMessage(content="抱歉,我不太理解您的需求。请明确说明是创建新的旅行计划还是调整现有计划。")]
}
except Exception as e:
print(f"解析用户输入时出错: {e}")
return {
"user_intent": "unknown",
"messages": [AIMessage(content="抱歉,解析您的请求时遇到了问题。请再试一次。")]
}
return state
def create_travel_plan(state: AgentState):
"""创建旅行计划"""
response = planning_prompt | llm | TravelPlanParser()
result = response.invoke({
"destination": state.get("destination", ""),
"duration": state.get("duration", ""),
"budget": state.get("budget", ""),
"interests": state.get("interests", ""),
"travel_date": state.get("travel_date", "")
})
return {
"current_plan": result,
"messages": [AIMessage(content=f"已创建旅行计划:{json.dumps(result, indent=2, ensure_ascii=False)}")]
}
def adjust_travel_plan(state: AgentState):
"""调整旅行计划"""
if not state.get("current_plan"):
return {
"messages": [AIMessage(content="没有可调整的计划,请先创建计划。")]
}
response = adjustment_prompt | llm | TravelPlanParser()
result = response.invoke({
"original_plan": json.dumps(state["current_plan"], indent=2, ensure_ascii=False),
"adjustment_request": state.get("adjustment_request", "")
})
return {
"current_plan": result,
"messages": [AIMessage(content=f"已调整旅行计划:{json.dumps(result, indent=2, ensure_ascii=False)}")]
}
def handle_unknown_intent(state: AgentState):
"""处理未知意图"""
return {
"messages": [AIMessage(content="抱歉,我不太理解您的需求。请明确说明是创建新的旅行计划还是调整现有计划。")]
}
def route_request(state: AgentState):
"""路由请求到适当的节点"""
intent = state.get("user_intent", "unknown")
if intent == "create":
return "create_plan"
elif intent == "adjust":
return "adjust_plan"
else:
return "handle_unknown"
# 构建LangGraph
def build_travel_planner_graph():
"""构建旅行规划图"""
workflow = StateGraph(AgentState)
# 添加节点
workflow.add_node("extract_info", extract_travel_info)
workflow.add_node("create_plan", create_travel_plan)
workflow.add_node("adjust_plan", adjust_travel_plan)
workflow.add_node("handle_unknown", handle_unknown_intent)
# 设置入口点
workflow.set_entry_point("extract_info")
# 添加条件边
workflow.add_conditional_edges(
"extract_info",
route_request,
{
"create_plan": "create_plan",
"adjust_plan": "adjust_plan",
"handle_unknown": "handle_unknown"
}
)
# 添加结束边
workflow.add_edge("create_plan", END)
workflow.add_edge("adjust_plan", END)
workflow.add_edge("handle_unknown", END)
# 添加内存
memory = MemorySaver()
return workflow.compile(checkpointer=memory)
# 定义旅行规划Agent类
class TravelPlannerAgent:
def __init__(self):
self.graph = build_travel_planner_graph()
# 打印图的结构(可选,非常直观!)
try:
print("--- 图结构 ---")
self.graph.get_graph().print_ascii()
print("\n" + "=" * 20 + "\n")
except Exception as e:
print(f"无法打印图结构: {e}")
self.config = {"configurable": {"thread_id": "travel_planner"}}
self.current_plan = None
def create_plan(self, destination, duration, budget, interests, travel_date):
"""创建初始旅行计划"""
# 构建用户消息
user_message = f"创建旅行计划到{destination},时长{duration}天,预算{budget},兴趣偏好:{interests},出行时间:{travel_date}"
# 运行图
result = self.graph.invoke(
{
"messages": [HumanMessage(content=user_message)],
"destination": destination,
"duration": duration,
"budget": budget,
"interests": interests,
"travel_date": travel_date
},
config=self.config
)
self.current_plan = result.get("current_plan")
return self.current_plan
def adjust_plan(self, adjustment_request):
"""根据新情况调整计划"""
# 构建用户消息
user_message = f"调整计划:{adjustment_request}"
# 运行图
result = self.graph.invoke(
{
"messages": [HumanMessage(content=user_message)],
"adjustment_request": adjustment_request,
"current_plan": self.current_plan
},
config=self.config
)
self.current_plan = result.get("current_plan")
return self.current_plan
def get_current_plan(self):
"""获取当前计划"""
return self.current_plan
def chat(self, user_input):
"""与Agent对话"""
result = self.graph.invoke(
{
"messages": [HumanMessage(content=user_input)]
},
config=self.config
)
self.current_plan = result.get("current_plan")
return result["messages"][-1].content
# 使用示例
if __name__ == "__main__":
# 初始化旅行规划Agent
agent = TravelPlannerAgent()
# 创建初始计划
print("## 创建初始旅行计划 ##")
initial_plan = agent.create_plan(
destination="中国北京",
duration="5天",
budget="10000元",
interests="传统文化、美食、古迹",
travel_date="2026年1月"
)
print("初始计划:")
print(json.dumps(initial_plan, indent=2, ensure_ascii=False))
# 调整计划
print("\n## 调整旅行计划 ##")
adjusted_plan = agent.adjust_plan("预算减少到8000元,并增加一天行程")
print("调整后的计划:")
print(json.dumps(adjusted_plan, indent=2, ensure_ascii=False))
# 使用聊天接口 - 测试自然语言输入
print("\n## 使用聊天接口 - 自然语言输入测试 ##")
# 测试创建计划的自然语言输入
response1 = agent.chat("我想去美国洛杉矶玩7天,预算15000元,喜欢好莱坞和美食,明年春天出发")
print(response1)
# 测试调整计划的自然语言输入
response2 = agent.chat("把预算减少到12000元,增加一些购物时间")
print(response2)

代码解释:

代码可以分为以下几个主要部分:
初始化与核心组件:导入库、初始化LLM、定义输出解析器。
状态定义:使用 TypedDict 定义Agent在工作流中需要维护和传递的状态。
提示工程:设计用于指导LLM完成特定任务的模板。
工作流节点:定义图中的每个处理步骤(节点)。
图构建:将节点和边连接起来,形成一个完整的工作流图。
Agent封装:创建一个用户友好的类来与图进行交互。
使用示例:展示如何调用这个Agent。
1. 初始化与核心组件
from init_client import init_llm
llm = init_llm(0.7)
这部分很简单,就是从 init_client.py 文件中导入 init_llm 函数,并初始化一个温度为0.7的DeepSeek LLM实例。温度0.7意味着模型在生成文本时会有一定的创造性,但不会太离谱。
class TravelPlanParser(BaseOutputParser):
# ...
这是一个自定义的输出解析器。LLM在生成JSON格式的旅行计划时,有时会在JSON前后加上一些解释性的文字(例如:"好的,这是您的旅行计划:{...}")。这个解析器的作用就是鲁棒地从文本中提取出有效的JSON部分,并将其转换为Python字典。如果提取失败,它会将原始文本包装在一个字典中返回,防止程序崩溃。
class UserIntent(TypedDict):
# ...
class UserIntentParser(JsonOutputParser):
# ...
这是本次改进的核心部分。
UserIntent (TypedDict):它定义了一个数据结构模板,用来规范用户意图的解析结果。它明确指出解析结果必须包含 intent 字段(值为 "create", "adjust" 或 "unknown"),以及其他可选字段如 destination, budget 等。这为后续的数据处理提供了类型安全保障。
UserIntentParser (JsonOutputParser):这是一个专门用于解析 UserIntent 结构的JSON解析器。它继承自LangChain的 JsonOutputParser,确保LLM的输出必须是符合 UserIntent 结构的JSON。
2. 状态定义
class AgentState(TypedDict):
messages: Annotated[List[BaseMessage], operator.add]
current_plan: Optional[Dict]
# ... 其他字段
AgentState 是LangGraph的核心概念。它定义了在整个工作流(图)中流动的数据包。你可以把它想象成一个“共享的记事本”,图中的每个节点都可以读取这个记事本的内容,也可以在上面写下新的内容。
messages: 使用 Annotated[List[BaseMessage], operator.add] 是LangGraph的惯用写法。它表示这是一个消息列表,每当有新的消息添加进来时,它会自动追加到列表的末尾,而不是覆盖。这天然地实现了对话记忆功能。
current_plan: 存储当前生成的旅行计划。
destination, duration, ...: 存储从用户输入中解析出的具体旅行信息。
user_intent: 存储解析出的用户意图("create" 或 "adjust")。
3. 提示工程
代码中定义了三个关键的提示模板:
intent_extraction_template (意图提取模板)
目的:这是实现泛化的关键。它的任务是理解用户的自然语言输入。
工作方式:它告诉LLM:“给你一段用户输入,请判断他是想创建新计划还是调整旧计划,并把相关的信息(如目的地、预算等)提取出来,用指定的JSON格式返回。”
示例:模板中包含了输入和输出的示例,这是一种强大的少样本提示技术,能极大地提高LLM解析的准确性。
planning_template (规划模板)
目的:指导LLM根据已提取的结构化信息(目的地、预算等)生成一个详细的、符合JSON格式的旅行计划。
adjustment_template (调整模板)
目的:指导LLM根据用户的调整请求和已有的旧计划,生成一个符合JSON格式的新计划。
4. 工作流节点
节点是图中的基本处理单元,每个都是一个Python函数,接收 AgentState 作为输入,并返回一个字典来更新状态。
def extract_travel_info(state: AgentState):
# ...
这是最重要的节点,也是本次的焦点。
逻辑:
获取最新的用户消息。
调用 intent_extraction_chain(由 intent_extraction_prompt | llm | UserIntentParser 组成)。
这个链将用户输入发送给LLM,LLM根据提示模板返回一个结构化的JSON,然后 UserIntentParser 将其解析为 UserIntent 字典。
函数检查解析出的 intent 字段。
如果是 "create",它就更新状态中的 destination, budget 等字段。
如果是 "adjust",它就更新状态中的 adjustment_request 字段。
如果是 "unknown",它就返回一个错误消息。
这个函数将**自然语言理解(NLU)**的任务完全交给了LLM,实现了真正的泛化。
def create_travel_plan(state: AgentState):
# ...
def adjust_travel_plan(state: AgentState):
# ...
这两个节点相对直接。它们从状态中获取 extract_travel_info 节点准备好的数据,调用相应的规划链(planning_chain 或 adjustment_chain)来生成或调整计划,并将结果更新到 current_plan 字段中。
5. 图构建
def build_travel_planner_graph():
workflow = StateGraph(AgentState)
# ...
return workflow.compile(checkpointer=memory)
这个函数将所有节点和逻辑串联成一个可执行的工作流。
workflow = StateGraph(AgentState): 创建一个图,并指定其状态结构为 AgentState。
workflow.add_node(...): 将之前定义的函数注册为图中的节点。
workflow.set_entry_point("extract_info"): 设置图的入口,即任何请求都从 extract_travel_info 节点开始处理。
workflow.add_conditional_edges(...): 这是图的决策逻辑。它从 extract_info 节点出发,根据 route_request 函数的返回值(该函数检查 state 中的 user_intent 字段),决定下一步流向哪个节点(create_plan, adjust_plan, 或 handle_unknown)。
workflow.add_edge(..., END): 定义了哪些节点是图的终点。
workflow.compile(checkpointer=memory): 将图编译成一个可运行的应用。checkpointer=MemorySaver() 为图添加了持久化记忆功能。这意味着,即使在多次调用之间,只要 thread_id 相同,图就能记住之前的对话历史和 current_plan。
6. Agent封装
class TravelPlannerAgent:
def __init__(self):
self.graph = build_travel_planner_graph()
self.config = {"configurable": {"thread_id": "travel_planner"}}
# ...
这个类为用户提供了一个简洁的API,隐藏了LangGraph的复杂性。
__init__: 在初始化时编译好图,并设置一个唯一的 thread_id。这个ID是记忆功能的关键,所有来自同一个Agent实例的对话都会共享同一个记忆空间。
create_plan, adjust_plan: 这两个方法提供了传统的、程序化的调用方式。它们构造一个明确的请求,然后调用 self.graph.invoke() 来执行整个工作流。
chat: 这是最能体现改进成果的方法。用户可以直接输入自然语言,如 "我想去美国洛杉矶玩7天...",chat 方法会将这段话直接喂给图,图会自动完成意图识别、信息提取、计划生成等所有步骤,并返回最终结果。

普通人如何抓住AI大模型的风口?

为什么要学AI大模型

当下,⼈⼯智能市场迎来了爆发期,并逐渐进⼊以⼈⼯通⽤智能(AGI)为主导的新时代。企业纷纷官宣“ AI+ ”战略,为新兴技术⼈才创造丰富的就业机会,⼈才缺⼝将达 400 万!

DeepSeek问世以来,生成式AI和大模型技术爆发式增长,让很多岗位重新成了炙手可热的新星,岗位薪资远超很多后端岗位,在程序员中稳居前列。

在这里插入图片描述

与此同时AI与各行各业深度融合,飞速发展,成为炙手可热的新风口,企业非常需要了解AI、懂AI、会用AI的员工,纷纷开出高薪招聘AI大模型相关岗位。
在这里插入图片描述

AI大模型开发工程师对AI大模型需要了解到什么程度呢?我们先看一下招聘需求:

在这里插入图片描述

知道人家要什么能力,一切就好办了!我整理了AI大模型开发工程师需要掌握的知识如下:

大模型基础知识

你得知道市面上的大模型产品生态和产品线;还要了解Llama、Qwen等开源大模型与OpenAI等闭源模型的能力差异;以及了解开源模型的二次开发优势,以及闭源模型的商业化限制,等等。

img

了解这些技术的目的在于建立与算法工程师的共通语言,确保能够沟通项目需求,同时具备管理AI项目进展、合理分配项目资源、把握和控制项目成本的能力。

产品经理还需要有业务sense,这其实就又回到了产品人的看家本领上。我们知道先阶段AI的局限性还非常大,模型生成的内容不理想甚至错误的情况屡见不鲜。因此AI产品经理看技术,更多的是从技术边界、成本等角度出发,选择合适的技术方案来实现需求,甚至用业务来补足技术的短板。

AI Agent

现阶段,AI Agent的发展可谓是百花齐放,甚至有人说,Agent就是未来应用该有的样子,所以这个LLM的重要分支,必须要掌握。

Agent,中文名为“智能体”,由控制端(Brain)、感知端(Perception)和行动端(Action)组成,是一种能够在特定环境中自主行动、感知环境、做出决策并与其他Agent或人类进行交互的计算机程序或实体。简单来说就是给大模型这个大脑装上“记忆”、装上“手”和“脚”,让它自动完成工作。

Agent的核心特性

自主性: 能够独立做出决策,不依赖人类的直接控制。

适应性: 能够根据环境的变化调整其行为。

交互性: 能够与人类或其他系统进行有效沟通和交互。

img

对于大模型开发工程师来说,学习Agent更多的是理解它的设计理念和工作方式。零代码的大模型应用开发平台也有很多,比如dify、coze,拿来做一个小项目,你就会发现,其实并不难。

AI 应用项目开发流程

如果产品形态和开发模式都和过去不一样了,那还画啥原型?怎么排项目周期?这将深刻影响产品经理这个岗位本身的价值构成,所以每个AI产品经理都必须要了解它。

img

看着都是新词,其实接触起来,也不难。

从0到1的大模型系统学习籽料

最近很多程序员朋友都已经学习或者准备学习 AI 大模型,后台也经常会有小伙伴咨询学习路线和学习资料,我特别拜托北京清华大学学士和美国加州理工学院博士学位的鲁为民老师(吴文俊奖得主)
在这里插入图片描述

给大家准备了一份涵盖了AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频 全系列的学习资料,这些学习资料不仅深入浅出,而且非常实用,让大家系统而高效地掌握AI大模型的各个知识点。

图片

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费

适学人群

应届毕业生‌: 无工作经验但想要系统学习AI大模型技术,期待通过实战项目掌握核心技术。

零基础转型‌: 非技术背景但关注AI应用场景,计划通过低代码工具实现“AI+行业”跨界‌。

业务赋能突破瓶颈: 传统开发者(Java/前端等)学习Transformer架构与LangChain框架,向AI全栈工程师转型‌。
在这里插入图片描述

AI大模型系统学习路线

在面对AI大模型开发领域的复杂与深入,精准学习显得尤为重要。一份系统的技术路线图,不仅能够帮助开发者清晰地了解从入门到精通所需掌握的知识点,还能提供一条高效、有序的学习路径。

  • 基础篇,包括了大模型的基本情况,核心原理,带你认识了解大模型提示词,Transformer架构,预训练、SFT、RLHF等一些基础概念,用最易懂的方式带你入门AI大模型
  • 进阶篇,你将掌握RAG,Langchain、Agent的核心原理和应用,学习如何微调大模型,让大模型更适合自己的行业需求,私有化部署大模型,让自己的数据更加安全
  • 项目实战篇,会手把手一步步带着大家练习企业级落地项目,比如电商行业的智能客服、智能销售项目,教育行业的智慧校园、智能辅导项目等等

img

但知道是一回事,做又是另一回事,初学者最常遇到的问题主要是理论知识缺乏、资源和工具的限制、模型理解和调试的复杂性,在这基础上,找到高质量的学习资源,不浪费时间、不走弯路,又是重中之重。

AI大模型入门到实战的视频教程+项目包

看视频学习是一种高效、直观、灵活且富有吸引力的学习方式,可以更直观地展示过程,能有效提升学习兴趣和理解力,是现在获取知识的重要途径

在这里插入图片描述
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

海量AI大模型必读的经典书籍(PDF)

阅读AI大模型经典书籍可以帮助读者提高技术水平,开拓视野,掌握核心技术,提高解决问题的能力,同时也可以借鉴他人的经验。对于想要深入学习AI大模型开发的读者来说,阅读经典书籍是非常有必要的。
在这里插入图片描述

600+AI大模型报告(实时更新)

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
在这里插入图片描述

AI大模型面试真题+答案解析

我们学习AI大模型必然是想找到高薪的工作,下面这些面试题都是总结当前最新、最热、最高频的面试题,并且每道题都有详细的答案,面试前刷完这套面试题资料,小小offer,不在话下
在这里插入图片描述

在这里插入图片描述

AI时代,企业最需要的是既懂技术、又有实战经验的复合型人才,**当前人工智能岗位需求多,薪资高,前景好。**在职场里,选对赛道就能赢在起跑线。抓住AI这个风口,相信下一个人生赢家就是你!机会,永远留给有准备的人。

如何获取?

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费

以下是基于Python、LangChainLangGraph和MCP实现Text2SQL Agent的大致方法: ### 环境准备 首先需要安装相关的库,可使用以下命令: ```python pip install langchain langgraph mcp ``` ### 了解相关组件 - **MongoDB**:是一款流行的NoSQL数据库,将数据存储在灵活的JSON格式文档中,适合需要灵活性和可扩展性的AI应用,可作为数据源 [^1]。 - **LangChain**:是智能体框架,在实现Text2SQL Agent中可用于构建智能体的基础逻辑 [^2]。 - **LangGraph**:用于工作流编排,可对Text2SQL Agent的整个工作流程进行合理安排 [^2]。 - **MCP**:包含MCP Client(协议客户端)、MCP Adapters(工具转换层)、MCP Protocol(协议层)和MCP Servers(数据源服务),负责与数据源交互等工作 [^2]。 ### 实现步骤 #### 1. 连接数据源 使用MCP相关组件连接到MongoDB数据源。示例代码如下: ```python from mcp.client import MCPClient from mcp.adapters import MongoDBAdapter # 创建MCP客户端 client = MCPClient() # 创建MongoDB适配器 adapter = MongoDBAdapter() # 连接到MongoDB数据源 client.connect(adapter, "mongodb://localhost:27017") ``` #### 2. 构建Text2SQL Agent 使用LangChain构建智能体的核心逻辑,将自然语言文本转换为SQL查询。示例代码如下: ```python from langchain.agents import AgentExecutor, Tool from langchain.llms import OpenAI # 定义一个工具,用于将自然语言转换为SQL def text_to_sql(text): # 这里可以实现具体的文本到SQL的转换逻辑 sql = f"SELECT * FROM table WHERE condition = '{text}'" return sql # 创建工具 tools = [ Tool( name="TextToSQL", func=text_to_sql, description="Convert natural language text to SQL query" ) ] # 创建语言模型 llm = OpenAI() # 创建智能体执行器 agent = AgentExecutor.from_agent_and_tools( agent=agent, tools=tools, verbose=True ) ``` #### 3. 工作流编排 使用LangGraph对整个工作流程进行编排,确保各个组件之间的协作顺畅。示例代码如下: ```python from langgraph import Graph # 创建LangGraph图 graph = Graph() # 添加节点和边 graph.add_node("TextInput", input_type="text") graph.add_node("Text2SQLAgent", agent=agent) graph.add_node("MCPQuery", client=client) graph.add_edge("TextInput", "Text2SQLAgent") graph.add_edge("Text2SQLAgent", "MCPQuery") ``` #### 4. 执行工作流 将自然语言文本输入到工作流中,得到最终的SQL查询结果。示例代码如下: ```python # 输入自然语言文本 input_text = "Find all records where name is 'John'" # 执行工作流 result = graph.run({"TextInput": input_text}) print(result) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值