Skip to content

Commit 12427fc

Browse files
committed
docs:专栏更新
1 parent cbccb7b commit 12427fc

12 files changed

+1787
-30
lines changed

Diff for: .vscode/.server-controller-port.log

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"port": 9146,
3-
"time": 1722851162103,
2+
"port": 9145,
3+
"time": 1723122064966,
44
"version": "0.0.3"
55
}

Diff for: docs/.vuepress/config.js

+32-3
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ module.exports = {
468468
link: '/md/ck/clickhouse概述.md'
469469
}]
470470
},
471-
471+
472472
{
473473
text: 'HBase',
474474
items: [{
@@ -518,7 +518,7 @@ module.exports = {
518518
link: '/md/bigdata/01-大数据的尽头是数据中台吗?.md'
519519
}]
520520
},
521-
521+
522522
{
523523
text: 'Hadoop',
524524
items: [{
@@ -695,6 +695,10 @@ module.exports = {
695695
text: 'Agent项目实战',
696696
link: '/md/AI/01-three-minute-fastapi-ai-agent-setup'
697697
},
698+
{
699+
text: 'LangGraph',
700+
link: '/md/AI/00-introduce-to-LangGraph'
701+
},
698702
]
699703
},
700704

@@ -849,6 +853,7 @@ module.exports = {
849853
"08-视频推荐索引构建",
850854
"09-交易中台-如何防止订单二次重复支付?",
851855
"小游戏的大促实践",
856+
"事件中心架构概述",
852857
]
853858
},
854859
{
@@ -1109,6 +1114,7 @@ module.exports = {
11091114
"JDK21新特性",
11101115
"JDK22新特性",
11111116
"IntelliJ IDEA 2024.1 最新变化",
1117+
"What’s-New-in-IntelliJ-IDEA-2024.2",
11121118
]
11131119
},
11141120
],
@@ -1233,6 +1239,15 @@ module.exports = {
12331239

12341240
]
12351241
},
1242+
1243+
{
1244+
title: "事件驱动",
1245+
collapsable: false,
1246+
sidebarDepth: 0,
1247+
children: [
1248+
"integrating-event-driven-microservices-with-request-response-APIs",
1249+
]
1250+
},
12361251
{
12371252
title: "DDD大厂实践",
12381253
collapsable: false,
@@ -1268,6 +1283,7 @@ module.exports = {
12681283
sidebarDepth: 0,
12691284
children: [
12701285
"00-Spring响应式编程",
1286+
"05-流式操作:如何使用 Flux 和 Mono 高效构建响应式数据流?",
12711287
]
12721288
}],
12731289

@@ -1315,6 +1331,7 @@ module.exports = {
13151331
"nature-of-kubernetes",
13161332
"02-Kubernetes核心组件之kube-proxy实现原理",
13171333
"pod-in-kubernetes",
1334+
"kubernetes-workloads-controllers-deployment",
13181335
"23-0-声明式API",
13191336
"23-1-Envoy",
13201337
]
@@ -1328,7 +1345,7 @@ module.exports = {
13281345
"使用 Kubernetes 部署 Nginx 应用",
13291346
]
13301347
},
1331-
1348+
13321349
{
13331350
title: "Kubernetes云平台KubeSphere",
13341351
collapsable: false,
@@ -1354,6 +1371,7 @@ module.exports = {
13541371
collapsable: false,
13551372
sidebarDepth: 0,
13561373
children: [
1374+
"netty-basic-components",
13571375
"ChannelPipeline接口",
13581376
"(06-1)-ChannelHandler 家族",
13591377
"(08)-学习Netty BootStrap的核心知识,成为网络编程高手!",
@@ -1369,6 +1387,7 @@ module.exports = {
13691387
children: [
13701388
"00-Kafka专栏大纲",
13711389
"Kafka门派知多少",
1390+
"kafka-versions",
13721391
"08-全网最全图解Kafka适用场景",
13731392
"09-消息队列的消息大量积压怎么办?",
13741393
"15-基于kafka实现延迟队列"
@@ -1435,6 +1454,7 @@ module.exports = {
14351454
"客户端基本操作",
14361455
"为啥要学习ClickHouse",
14371456
"为啥适合OLAP?",
1457+
"clickhouse-jdbc",
14381458
]
14391459
}],
14401460

@@ -1762,6 +1782,15 @@ module.exports = {
17621782
"03-use-tts-to-make-your-ai-agent-speak",
17631783
]
17641784
},
1785+
1786+
{
1787+
title: "LangGraph",
1788+
collapsable: false,
1789+
sidebarDepth: 0,
1790+
children: [
1791+
"00-introduce-to-LangGraph",
1792+
]
1793+
},
17651794
],
17661795

17671796
"/md/design/": [{

Diff for: docs/md/AI/00-introduce-to-LangGraph.md

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# AI Agent 终结者 LangGraph!
2+
3+
⚡ 构建作为图的语言智能体 ⚡
4+
5+
## 1 概述
6+
7+
LangGraph是一个用于构建具有状态、多参与者应用程序的大语言模型(LLM)的库,用于创建智能体和多智能体的工作流程。与其他 LLM 框架相比,它提供以下核心优势:
8+
9+
- 循环
10+
- 可控性
11+
- 持久性
12+
13+
LangGraph 允许你定义涉及循环的流程,这对于大多数智能体架构至关重要,使其与基于DAG的解决方案区别开来。作为一个非常底层的框架,它提供了对应用程序的流程和状态的细粒度控制,这对于创建可靠的智能体至关重要。
14+
15+
此外,LangGraph 包含内置的持久性功能,支持高级的“人类在环”(human-in-the-loop)和记忆功能。
16+
17+
LangGraph 的灵感来源于 [Pregel](https://research.google/pubs/pub37252/)[Apache Beam](https://beam.apache.org/)。其公共接口借鉴了 [NetworkX](https://networkx.org/documentation/latest/) 的设计。LangGraph 由 LangChain Inc. 创建,该公司也是 LangChain 的开发者,但它可以独立于 LangChain 使用。
18+
19+
### 1.1 关键特性
20+
21+
- **循环和分支**:在应用程序中实现循环和条件判断
22+
- **持久性**:在图中的每一步之后自动保存状态。你可以在任意时间点暂停和恢复图的执行,以支持错误恢复、“人类在环”工作流、时间回溯等功能
23+
- **人类在环**:在图执行过程中打断执行,以批准或编辑智能体计划的下一个动作
24+
- **流式支持**:在每个节点生成输出时进行流式传输(包括 token 流式传输)
25+
- **与 LangChain 集成**:LangGraph 可以与 [LangChain](https://github.com/langchain-ai/langchain/)[LangSmith](https://docs.smith.langchain.com/) 无缝集成(但不要求使用它们)
26+
27+
## 2 安装
28+
29+
```bash
30+
pip install -U langgraph
31+
```
32+
33+
## 3 示例
34+
35+
LangGraph 的核心概念之一是状态。每次图执行都会创建一个状态,该状态在图中各节点执行时在它们之间传递,并且每个节点在执行后会用其返回值更新该内部状态。图更新其内部状态的方式由所选择的图类型或自定义函数定义。
36+
37+
### 使用搜索工具的简单智能体
38+
39+
40+
41+
```arduino
42+
pip install langchain-anthropic
43+
export ANTHROPIC_API_KEY=sk-...
44+
```
45+
46+
可选地,我们可设置 [LangSmith](https://docs.smith.langchain.com/) 以获得最佳的可观测性。
47+
48+
```python
49+
export LANGSMITH_TRACING=true
50+
export LANGSMITH_API_KEY=lsv2_sk_...
51+
from typing import Annotated, Literal, TypedDict
52+
53+
from langchain_core.messages import HumanMessage
54+
from langchain_anthropic import ChatAnthropic
55+
from langchain_core.tools import tool
56+
from langgraph.checkpoint.memory import MemorySaver
57+
from langgraph.graph import END, StateGraph, MessagesState
58+
from langgraph.prebuilt import ToolNode
59+
60+
61+
# 为智能体定义工具
62+
@tool
63+
def search(query: str):
64+
"""调用以浏览网络。"""
65+
# 这是一个占位符,但不要告诉 LLM...
66+
if "sf" 在查询字符串中,或者查询中包含 "san francisco"
67+
return "现在是 60 度,有雾。"
68+
return "现在是 90 度,晴天。"
69+
70+
71+
tools = [search]
72+
73+
tool_node = ToolNode(tools)
74+
75+
model = ChatAnthropic(model="claude-3-5-sonnet-20240620", temperature=0).bind_tools(tools)
76+
77+
# 定义决定是否继续的函数
78+
def should_continue(state: MessagesState) -> Literal["tools", END]:
79+
messages = state['messages']
80+
last_message = messages[-1]
81+
# 如果 LLM 进行工具调用,那么我们将路径设置为 "tools" 节点
82+
if last_message.tool_calls:
83+
return "tools"
84+
# 否则,我们停止(回复用户)
85+
return END
86+
87+
88+
# 定义调用模型的函数
89+
def call_model(state: MessagesState):
90+
messages = state['messages']
91+
response = model.invoke(messages)
92+
# 我们返回一个列表,因为这将被添加到现有列表中
93+
return {"messages": [response]}
94+
95+
96+
# 定义一个新图
97+
workflow = StateGraph(MessagesState)
98+
99+
# 定义我们将循环的两个节点
100+
workflow.add_node("agent", call_model)
101+
workflow.add_node("tools", tool_node)
102+
103+
# 将入口点设置为 `agent`
104+
# 这意味着这个节点是首先被调用的
105+
workflow.set_entry_point("agent")
106+
107+
# 我们现在添加一个条件边
108+
workflow.add_conditional_edges(
109+
# 首先,我们定义起始节点。我们使用 `agent`。
110+
# 这意味着这些边是在调用 `agent` 节点后执行的。
111+
"agent",
112+
# 接下来,我们传入决定下一个被调用节点的函数。
113+
should_continue,
114+
)
115+
116+
# 我们现在从 `tools` 到 `agent` 添加一条普通边。
117+
# 这意味着在 `tools` 被调用后,`agent` 节点会接着被调用。
118+
workflow.add_edge("tools", 'agent')
119+
120+
# 初始化内存以在图运行之间保存状态
121+
checkpointer = MemorySaver()
122+
123+
# 最后,我们编译它!
124+
# 这将其编译为一个 LangChain 可运行体,
125+
# 这意味着你可以像使用其他可运行体一样使用它。
126+
# 请注意,我们在编译图时(可选地)传递了内存
127+
app = workflow.compile(checkpointer=checkpointer)
128+
129+
# 使用可运行体
130+
final_state = app.invoke(
131+
{"messages": [HumanMessage(content="sf 的天气如何")]},
132+
config={"configurable": {"thread_id": 42}}
133+
)
134+
final_state["messages"][-1].content
135+
"根据搜索结果,我可以告诉你,旧金山目前的天气是:\n\n温度:华氏 60 度\n天气情况:有雾\n\n旧金山以其微气候和频繁的雾而闻名,尤其是在夏季的早晨和傍晚。60°F(约 15.5°C)的温度对于该市来说是非常常见的,因为该市一年四季温度都比较温和。雾气,当地人称之为 “Karl the Fog”,是旧金山天气的一个特点,特别是在早晨和晚上。\n\n你还想知道有关旧金山或其他地方天气的其他信息吗?"
136+
```
137+
138+
现在当我们传递相同的 `"thread_id"` 时,会通过保存的状态(即存储的消息列表)保留对话上下文。
139+
140+
```python
141+
final_state = app.invoke(
142+
{"messages": [HumanMessage(content="那纽约呢")]},
143+
config={"configurable": {"thread_id": 42}}
144+
)
145+
final_state["messages"][-1].content
146+
"根据搜索结果,我可以告诉你,纽约目前的天气是:\n\n温度:华氏 90 度(约 32.2 摄氏度)\n天气情况:晴天\n\n这种天气与我们刚刚看到的旧金山的天气截然不同。纽约目前的温度要高得多。以下是一些需要注意的几点:\n\n1. 90°F 的温度相当热,典型的纽约市夏季天气。\n2. 晴朗的天气意味着晴空万里,这对户外活动非常有利,但也意味着由于阳光直射,感觉可能会更热。\n3. 纽约这种天气通常伴随着高湿度,这会使实际温度感觉更高。\n\n看到旧金山温和、多雾的天气与纽约炎热、晴朗的天气之间的巨大差异,这确实很有趣。这种差异展示了美国不同地区,即使在同一天,天气状况也可能截然不同。\n\n你还想了解纽约或其他地方的天气情况吗?"
147+
```
148+
149+
参考:
150+
151+
- https://langchain-ai.github.io/langgraph/#installation

0 commit comments

Comments
 (0)