docs: update markdown files to align with new filenames
This commit is contained in:
@@ -5,7 +5,7 @@ LLM 调用|Prompt 编写与设计|多轮对话记忆|独立搭建智能体
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 1. `01_basic_llm_invocation`(LLM 模型调用)
|
### 1. `basic_llm_invocation`(LLM 模型调用)
|
||||||
使用 DeepSeek 官方推荐的调用方式,
|
使用 DeepSeek 官方推荐的调用方式,
|
||||||
这是后续所有 API 调用的通用结构,可直接复用。
|
这是后续所有 API 调用的通用结构,可直接复用。
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ LLM 调用|Prompt 编写与设计|多轮对话记忆|独立搭建智能体
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 2. `02_conversational_agent`(多轮问答 Agent)
|
### 2. `conversational_agent`(多轮问答 Agent)
|
||||||
整合了 LLM + Prompt + Memory,实现有记忆的对话。
|
整合了 LLM + Prompt + Memory,实现有记忆的对话。
|
||||||
|
|
||||||
🔧 使用提示:
|
🔧 使用提示:
|
||||||
@@ -5,14 +5,14 @@ Function calling 原理|工具函数封装|API 接入|多轮调用|Agent
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 1. `01_custom_function_calling`(自定义函数调用)
|
### 1. `custom_function_calling`(自定义函数调用)
|
||||||
用一个**假函数**模拟完整流程,重点掌握:
|
用一个**假函数**模拟完整流程,重点掌握:
|
||||||
✅ 如何定义可调用函数
|
✅ 如何定义可调用函数
|
||||||
✅ AI 如何触发函数调用
|
✅ AI 如何触发函数调用
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 2. `02_api_invocation`(API 调用)
|
### 2. `api_invocation`(API 调用)
|
||||||
接入一个**真实 API**,重点掌握:
|
接入一个**真实 API**,重点掌握:
|
||||||
✅ 如何根据 API 文档封装工具
|
✅ 如何根据 API 文档封装工具
|
||||||
✅ 让 AI 真正“动手”做事
|
✅ 让 AI 真正“动手”做事
|
||||||
@@ -5,7 +5,7 @@ LLM 调用|Prompt 设计|Chain 构建|Memory 记忆|实战练习
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 1. `01_models.py`(模型调用)
|
### 1. `models.py`(模型调用)
|
||||||
封装 LLM 实例,实现标准调用流程。
|
封装 LLM 实例,实现标准调用流程。
|
||||||
|
|
||||||
✅ 掌握点:
|
✅ 掌握点:
|
||||||
@@ -14,7 +14,7 @@ LLM 调用|Prompt 设计|Chain 构建|Memory 记忆|实战练习
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 2. `02_prompt.py`(提示词构建)
|
### 2. `prompt.py`(提示词构建)
|
||||||
使用 `ChatPromptTemplate` 构建可复用的 Prompt 模板。
|
使用 `ChatPromptTemplate` 构建可复用的 Prompt 模板。
|
||||||
|
|
||||||
✅ 掌握点:
|
✅ 掌握点:
|
||||||
@@ -24,7 +24,7 @@ LLM 调用|Prompt 设计|Chain 构建|Memory 记忆|实战练习
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 3. `03_chain.py`(链式调用)
|
### 3. `chain.py`(链式调用)
|
||||||
将 Prompt + LLM + Parser 组合成 Chain。
|
将 Prompt + LLM + Parser 组合成 Chain。
|
||||||
|
|
||||||
✅ 掌握点:
|
✅ 掌握点:
|
||||||
@@ -34,7 +34,7 @@ LLM 调用|Prompt 设计|Chain 构建|Memory 记忆|实战练习
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 4. `04_memory.py`(记忆功能)
|
### 4. `memory.py`(记忆功能)
|
||||||
添加会话记忆,实现多轮对话。
|
添加会话记忆,实现多轮对话。
|
||||||
|
|
||||||
✅ 掌握点:
|
✅ 掌握点:
|
||||||
@@ -44,7 +44,7 @@ LLM 调用|Prompt 设计|Chain 构建|Memory 记忆|实战练习
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 5. `05_practice.py`(综合实践)
|
### 5. `practice.py`(综合实践)
|
||||||
整合所有组件,搭建一个带记忆的 AI 对话机器人。
|
整合所有组件,搭建一个带记忆的 AI 对话机器人。
|
||||||
|
|
||||||
✅ 掌握点:
|
✅ 掌握点:
|
||||||
@@ -5,7 +5,7 @@ Function Calling|@tool 工具封装|ReAct 循环|Agent 构建|SQL Agent
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 1. `01_define_toolbox.py`(工具函数定义)
|
### 1. `define_toolbox.py`(工具函数定义)
|
||||||
使用 `@tool` 装饰器将 Python 函数封装为 LangChain 可调用的工具。
|
使用 `@tool` 装饰器将 Python 函数封装为 LangChain 可调用的工具。
|
||||||
|
|
||||||
✅ 掌握点:
|
✅ 掌握点:
|
||||||
@@ -15,7 +15,7 @@ Function Calling|@tool 工具封装|ReAct 循环|Agent 构建|SQL Agent
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 2. `02_general_agent.py`(通用 Agent 构建)
|
### 2. `general_agent.py`(通用 Agent 构建)
|
||||||
基于 `create_tool_calling_agent` 创建支持工具调用的智能体。
|
基于 `create_tool_calling_agent` 创建支持工具调用的智能体。
|
||||||
|
|
||||||
✅ 掌握点:
|
✅ 掌握点:
|
||||||
@@ -25,7 +25,7 @@ Function Calling|@tool 工具封装|ReAct 循环|Agent 构建|SQL Agent
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 3. `03_sql_agent.py`(SQL 专用 Agent)
|
### 3. `sql_agent.py`(SQL 专用 Agent)
|
||||||
一键构建自然语言查询数据库的智能体。
|
一键构建自然语言查询数据库的智能体。
|
||||||
|
|
||||||
✅ 掌握点:
|
✅ 掌握点:
|
||||||
@@ -35,7 +35,7 @@ Function Calling|@tool 工具封装|ReAct 循环|Agent 构建|SQL Agent
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 4. `04_memory_general_agent.py`(带记忆的 Agent)
|
### 4. `memory_general_agent.py`(带记忆的 Agent)
|
||||||
将 Agent 与对话历史结合,实现多轮上下文感知。
|
将 Agent 与对话历史结合,实现多轮上下文感知。
|
||||||
|
|
||||||
✅ 掌握点:
|
✅ 掌握点:
|
||||||
@@ -45,7 +45,7 @@ Function Calling|@tool 工具封装|ReAct 循环|Agent 构建|SQL Agent
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 5. `05_caching.py`(缓存优化技巧)
|
### 5. `caching.py`(缓存优化技巧)
|
||||||
在开发调试阶段避免重复调用 LLM,节省成本与时间。
|
在开发调试阶段避免重复调用 LLM,节省成本与时间。
|
||||||
|
|
||||||
✅ 掌握点:
|
✅ 掌握点:
|
||||||
@@ -55,7 +55,7 @@ Function Calling|@tool 工具封装|ReAct 循环|Agent 构建|SQL Agent
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 6. `06_streaming.py`(流式输出实战)
|
### 6. `streaming.py`(流式输出实战)
|
||||||
实现 AI 回复像打字机一样逐字输出,提升用户体验。
|
实现 AI 回复像打字机一样逐字输出,提升用户体验。
|
||||||
|
|
||||||
✅ 掌握点:
|
✅ 掌握点:
|
||||||
@@ -5,7 +5,7 @@ RAG 概念|文本加载与分块 (Load & Split)|向量化 (Embedding)|向
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 1. `01_load_and_split.py`(文本加载与分块)
|
### 1. `load_and_split.py`(文本加载与分块)
|
||||||
加载本地 `.txt` 文档,并使用 `RecursiveCharacterTextSplitter` 将其智能分割成“知识卡片”。
|
加载本地 `.txt` 文档,并使用 `RecursiveCharacterTextSplitter` 将其智能分割成“知识卡片”。
|
||||||
|
|
||||||
✅ **掌握点**:
|
✅ **掌握点**:
|
||||||
@@ -25,7 +25,7 @@ RAG 概念|文本加载与分块 (Load & Split)|向量化 (Embedding)|向
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 3. `03_build_index.py`(向量存储与索引构建)
|
### 3. `build_index.py`(向量存储与索引构建)
|
||||||
使用 FAISS 向量索引库将向量化后的文本片段构建为可检索的向量数据库,并持久化到本地。
|
使用 FAISS 向量索引库将向量化后的文本片段构建为可检索的向量数据库,并持久化到本地。
|
||||||
|
|
||||||
✅ **掌握点**:
|
✅ **掌握点**:
|
||||||
@@ -35,7 +35,7 @@ RAG 概念|文本加载与分块 (Load & Split)|向量化 (Embedding)|向
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 4. `04_rag_chain_full.py`(LCEL 完整 RAG 链)
|
### 4. `rag_chain_full.py`(LCEL 完整 RAG 链)
|
||||||
使用 LCEL(LangChain 表达式语言)“手动组装”一个完整的 RAG 流程,实现“检索-增强-生成”的闭环。
|
使用 LCEL(LangChain 表达式语言)“手动组装”一个完整的 RAG 流程,实现“检索-增强-生成”的闭环。
|
||||||
|
|
||||||
✅ **掌握点**:
|
✅ **掌握点**:
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 1. war_and_peace.txt (知识库源文件)
|
### 1. `war_and_peace.txt` (知识库源文件)
|
||||||
|
|
||||||
托尔斯泰经典小说《战争与和平》的纯文本版本(约3.2MB),作为本篇 RAG 系统的私有知识库。
|
托尔斯泰经典小说《战争与和平》的纯文本版本(约3.2MB),作为本篇 RAG 系统的私有知识库。
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 2. `00_build_index.py` (构建 Chroma 向量数据库)
|
### 2. `build_index.py` (构建 Chroma 向量数据库)
|
||||||
|
|
||||||
将 `war_and_peace.txt` 加载、分块、向量化,并存入 Chroma 持久化向量数据库。
|
将 `war_and_peace.txt` 加载、分块、向量化,并存入 Chroma 持久化向量数据库。
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 3. `01_load_from_chroma.py` (从 Chroma 加载向量库)
|
### 3. `load_from_chroma.py` (从 Chroma 加载向量库)
|
||||||
|
|
||||||
加载已持久化的 Chroma 向量数据库,用于后续检索。
|
加载已持久化的 Chroma 向量数据库,用于后续检索。
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 4. `02_reranker.py` (引入精排序器)
|
### 4. `reranker.py` (引入精排序器)
|
||||||
|
|
||||||
在召回结果上应用 Reranker 模型,提升上下文相关性。
|
在召回结果上应用 Reranker 模型,提升上下文相关性。
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 5. `03_rag_as_tool.py` (RAG 工具化封装)
|
### 5. `rag_as_tool.py` (RAG 工具化封装)
|
||||||
|
|
||||||
将 RAG 链封装为 LangChain `@tool`,供 Agent 调用。
|
将 RAG 链封装为 LangChain `@tool`,供 Agent 调用。
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 6. `04_memory_rag_agent.py` (终极集成 Agent)
|
### 6. `memory_rag_agent.py` (终极集成 Agent)
|
||||||
|
|
||||||
首次融合 LangChain 六大核心模块,构建带记忆、能自主决策的智能体。
|
首次融合 LangChain 六大核心模块,构建带记忆、能自主决策的智能体。
|
||||||
|
|
||||||
@@ -112,4 +112,4 @@
|
|||||||
|
|
||||||
### 💡 **建议**:
|
### 💡 **建议**:
|
||||||
|
|
||||||
直接运行 04_memory_rag_agent.py 体验完整 Agent 能力;若想自定义知识库,可替换 war_and_peace.txt 并重新运行 build_index.py(记得先删除旧数据库目录)。
|
直接运行 `memory_rag_agent.py` 体验完整 Agent 能力;若想自定义知识库,可替换 `war_and_peace.txt` 并重新运行 build_index.py(记得先删除旧数据库目录)。
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 1. `01_state_node_edge.py` (LangGraph 最小状态机)
|
### 1. `state_node_edge.py` (LangGraph 最小状态机)
|
||||||
|
|
||||||
演示 LangGraph 最基础的三要素:State(状态)、Node(节点)、Edge(边)。
|
演示 LangGraph 最基础的三要素:State(状态)、Node(节点)、Edge(边)。
|
||||||
|
|
||||||
@@ -16,15 +16,15 @@
|
|||||||
|
|
||||||
- 输出:
|
- 输出:
|
||||||
- 控制台打印状态变化过程。
|
- 控制台打印状态变化过程。
|
||||||
- 生成 `01_workflow.png` 流程图。
|
- 生成 `workflow.png` 流程图。
|
||||||
|
|
||||||
> 💡 此脚本**不涉及 LLM 或对话**,仅用于理解 LangGraph 底层机制。
|
> 💡 此脚本**不涉及 LLM 或对话**,仅用于理解 LangGraph 底层机制。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 2. `01_workflow.png` (状态机流程图)
|
### 2. `workflow.png` (状态机流程图)
|
||||||
|
|
||||||
由 `01_state_node_edge.py` 自动生成的 Mermaid 可视化图。
|
由 `state_node_edge.py` 自动生成的 Mermaid 可视化图。
|
||||||
|
|
||||||
- 内容:
|
- 内容:
|
||||||
- 展示 `START → A → B → END` 的线性执行流。
|
- 展示 `START → A → B → END` 的线性执行流。
|
||||||
@@ -35,9 +35,9 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 3. `02_langsmith_trace.py` (状态机 + LangSmith 追踪)
|
### 3. `langsmith_trace.py` (状态机 + LangSmith 追踪)
|
||||||
|
|
||||||
在 `01` 的基础上启用 LangSmith,实现执行过程可视化追踪。
|
在 `1.` 的基础上启用 LangSmith,实现执行过程可视化追踪。
|
||||||
|
|
||||||
- ✅ 掌握点:
|
- ✅ 掌握点:
|
||||||
- 设置环境变量:`LANGCHAIN_TRACING_V2=true`、`LANGCHAIN_PROJECT="my_demo"`。
|
- 设置环境变量:`LANGCHAIN_TRACING_V2=true`、`LANGCHAIN_PROJECT="my_demo"`。
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 4. `03_conditional_router.py` (首个 ReAct Agent:无记忆)
|
### 4. `conditional_router.py` (首个 ReAct Agent:无记忆)
|
||||||
|
|
||||||
构建第一个真正意义上的 LangGraph Agent:支持工具调用与条件循环。
|
构建第一个真正意义上的 LangGraph Agent:支持工具调用与条件循环。
|
||||||
|
|
||||||
@@ -69,9 +69,9 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 5. `04_agent_with_memory.py` (完整 Agent:带记忆 + 系统提示)
|
### 5. `agent_with_memory.py` (完整 Agent:带记忆 + 系统提示)
|
||||||
|
|
||||||
在 `03` 基础上升级为生产级 Agent 范式。
|
在 `4.` 基础上升级为生产级 Agent 范式。
|
||||||
|
|
||||||
- ✅ 掌握点:
|
- ✅ 掌握点:
|
||||||
- 启用 `MemorySaver()` 实现跨轮次记忆(`checkpointer=MemorySaver()`)。
|
- 启用 `MemorySaver()` 实现跨轮次记忆(`checkpointer=MemorySaver()`)。
|
||||||
@@ -89,15 +89,15 @@
|
|||||||
### 🔔 全局注意事项
|
### 🔔 全局注意事项
|
||||||
|
|
||||||
- **学习路径建议**:
|
- **学习路径建议**:
|
||||||
`01`(理解图) → `02`(理解追踪) → `03`(理解 ReAct) → `04`(理解记忆+prompt)
|
`1.`(理解图) → `3.`(理解追踪) → `4.`(理解 ReAct) → `5.`(理解记忆+prompt)
|
||||||
- 所有 `.py` 文件均依赖 `.env` 中的 `OPENAI_API_KEY` 和 `LANGCHAIN_API_KEY`。
|
- 所有 `.py` 文件均依赖 `.env` 中的 `OPENAI_API_KEY` 和 `LANGCHAIN_API_KEY`。
|
||||||
- 若想复用你的 RAG 工具,只需将 `get_weather` 替换为 `search_war_and_peace`,其余逻辑不变。
|
- 若想复用你的 RAG 工具,只需将 `get_weather` 替换为 `search_war_and_peace`,其余逻辑不变。
|
||||||
- `01_workflow.png` 仅反映 `01_state_node_edge.py` 的简单线性流,**不代表 Agent 结构**。
|
- `workflow.png` 仅反映 `state_node_edge.py` 的简单线性流,**不代表 Agent 结构**。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 💡 **建议**
|
### 💡 **建议**
|
||||||
- 尝试扩展 `04_agent_with_memory.py`,添加更多自定义工具(如RAG检索工具)
|
- 尝试扩展 `agent_with_memory.py`,添加更多自定义工具(如RAG检索工具)
|
||||||
- 实验不同的条件路由逻辑,实现更复杂的Agent决策路径
|
- 实验不同的条件路由逻辑,实现更复杂的Agent决策路径
|
||||||
- 使用LangSmith深入分析和优化Agent的推理过程
|
- 使用LangSmith深入分析和优化Agent的推理过程
|
||||||
- 尝试实现多Agent协作系统,通过LangGraph连接多个专业化Agent
|
- 尝试实现多Agent协作系统,通过LangGraph连接多个专业化Agent
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 1. `01_human_approval.py` (人工审批机制)
|
### 1. `human_approval.py` (人工审批机制)
|
||||||
|
|
||||||
实现带有人工干预的智能体工作流,为敏感操作添加审批环节。
|
实现带有人工干预的智能体工作流,为敏感操作添加审批环节。
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 2. `02_graph_as_a_tool.py` (子图工具化封装)
|
### 2. `graph_as_a_tool.py` (子图工具化封装)
|
||||||
|
|
||||||
演示如何将一个完整的 LangGraph 子工作流封装为单个工具(Graph-as-a-Tool 模式)。
|
演示如何将一个完整的 LangGraph 子工作流封装为单个工具(Graph-as-a-Tool 模式)。
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 3. `03_multi_agent_orchestration.py` (多智能体协作系统)
|
### 3. `multi_agent_orchestration.py` (多智能体协作系统)
|
||||||
|
|
||||||
构建由总控节点协调多个专家智能体的协作系统,实现专业化分工。
|
构建由总控节点协调多个专家智能体的协作系统,实现专业化分工。
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 4. `04_supervisor_agent_ops_system.py` (企业级运维智能体系统)
|
### 4. `supervisor_agent_ops_system.py` (企业级运维智能体系统)
|
||||||
|
|
||||||
整合前述所有高级特性,构建一个完整的企业级 IT 运维智能体系统。
|
整合前述所有高级特性,构建一个完整的企业级 IT 运维智能体系统。
|
||||||
|
|
||||||
@@ -87,15 +87,15 @@
|
|||||||
### 🔔 全局注意事项
|
### 🔔 全局注意事项
|
||||||
|
|
||||||
- **学习路径建议**:
|
- **学习路径建议**:
|
||||||
`01`(人工干预) → `02`(子图封装) → `03`(多智能体基础) → `04`(企业级综合应用)
|
`1.`(人工干预) → `2.`(子图封装) → `3.`(多智能体基础) → `4.`(企业级综合应用)
|
||||||
- 所有 `.py` 文件均依赖根目录 `.env` 中的 `OPENAI_API_KEY` 和 `LANGCHAIN_API_KEY`
|
- 所有 `.py` 文件均依赖根目录 `.env` 中的 `OPENAI_API_KEY` 和 `LANGCHAIN_API_KEY`
|
||||||
- LangSmith 追踪功能已默认开启,可在 [LangSmith UI](https://smith.langchain.com) 实时查看执行流程
|
- LangSmith 追踪功能已默认开启,可在 [LangSmith UI](https://smith.langchain.com) 实时查看执行流程
|
||||||
- `04_supervisor_agent_ops_system.py` 是一个整合性示例,建议在理解前三个文件的基础上学习
|
- `supervisor_agent_ops_system.py` 是一个整合性示例,建议在理解前三个文件的基础上学习
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 💡 **建议**
|
### 💡 **建议**
|
||||||
- 尝试扩展 `04_supervisor_agent_ops_system.py`,添加更多专业角色(如安全专家、性能分析师)
|
- 尝试扩展 `supervisor_agent_ops_system.py`,添加更多专业角色(如安全专家、性能分析师)
|
||||||
- 实验不同的 Supervisor 决策逻辑,优化任务分配策略
|
- 实验不同的 Supervisor 决策逻辑,优化任务分配策略
|
||||||
- 将真实的运维工具或 API 集成到系统中,构建实用的运维助手
|
- 将真实的运维工具或 API 集成到系统中,构建实用的运维助手
|
||||||
- 探索在生产环境中部署此类系统的最佳实践,如性能优化、错误处理和监控
|
- 探索在生产环境中部署此类系统的最佳实践,如性能优化、错误处理和监控
|
||||||
Reference in New Issue
Block a user