学习顺序说明:本文是AI学习路线的第13篇,可作为独立参考文档,也可在完成前面学习后阅读:
- … → 11 AI Agent → 12 项目实战 → 13 Vibe Coding(本文)
Vibe Coding(氛围编程/感觉编程)是一种新兴的编程范式,指开发者通过与AI对话的方式,让AI生成、修改和优化代码,自己则专注于架构设计和问题思考。
传统编程:
开发者 → 编写代码 → 调试 → 完成
Vibe Coding:
开发者 → 描述需求 → AI生成代码 → 审查/调整 → 完成
↓
架构设计、问题分解、代码审查
| 原则 | 说明 |
|---|---|
| 描述而非编写 | 用自然语言描述需求,让AI生成代码 |
| 迭代而非一次性 | 通过多轮对话逐步完善代码 |
| 审查而非实现 | 专注于代码审查和架构设计 |
| 上下文为王 | 提供充分的上下文信息 |
Cursor是目前最流行的Vibe Coding工具,基于VS Code构建。
核心功能
Cursor功能
├── Tab补全 - 智能代码补全
├── Chat - 侧边栏对话
├── Cmd+K - 行内编辑
├── Composer - 多文件编辑
└── Agent Mode - 自主执行模式
使用技巧
# 1. 使用 @ 符号引用上下文
@file:src/main.py # 引用文件
@folder:src/ # 引用文件夹
@code:函数名 # 引用代码块
@docs:库名 # 引用文档
# 2. 使用 / 命令
/fix # 修复代码
/explain # 解释代码
/doc # 生成文档
/test # 生成测试
# 3. 自然语言编辑
"把这段代码改成异步的"
"添加错误处理"
"重构这个函数,使其更简洁"
Composer多文件编辑
使用场景:
- 重构多个文件
- 添加新功能涉及多文件修改
- 代码迁移
操作步骤:
1. 打开 Composer (Cmd+I)
2. 描述需求
3. 审查AI的修改计划
4. 确认执行
参考资源:Cursor官方文档
GitHub Copilot是GitHub推出的AI编程助手。
Copilot模式
├── 代码补全 - 实时建议
├── Copilot Chat - 对话交互
├── Copilot Workspace - 工作空间级编辑
└── Copilot CLI - 命令行助手
使用技巧
# 1. 通过注释引导
# 创建一个函数,接收用户列表,返回按年龄排序的结果
def sort_users_by_age(users):
# Copilot会自动补全实现
return sorted(users, key=lambda x: x['age'])
# 2. 函数签名引导
def calculate_fibonacci(n: int) -> int:
"""计算斐波那契数列第n项"""
# 按Tab接受建议,或继续描述
pass
Claude Code是Anthropic推出的命令行AI编程工具。
# 安装
npm install -g @anthropics/claude-code
# 启动
claude
# 常用命令
/ls # 列出文件
/grep # 搜索代码
/edit # 编辑文件
/bash # 执行命令
特点
| 工具 | 特点 | 适用场景 |
|---|---|---|
| Windsurf | Cascade工作流 | 复杂多步骤任务 |
| Aider | 终端集成 | 命令行爱好者 |
| Cline | VS Code插件 | 开源免费 |
| Continue | 开源可定制 | 隐私敏感场景 |
清晰描述需求
❌ 不好的提示:
"帮我写个登录功能"
✅ 好的提示:
"创建一个用户登录API端点,要求:
- 使用JWT进行身份验证
- 支持邮箱和密码登录
- 密码使用bcrypt加密
- 返回token和用户信息
- 添加输入验证和错误处理
- 使用FastAPI框架"
提供上下文
提示模板:
【背景】
我正在开发一个电商系统,使用Python + FastAPI
【当前代码】
@file:src/auth.py
【目标】
添加用户注册功能
【要求】
1. 验证邮箱格式
2. 密码至少8位
3. 检查邮箱是否已存在
4. 返回201状态码
【约束】
- 使用SQLAlchemy ORM
- 遵循现有代码风格"
迭代优化
第一轮:生成基础代码
"创建一个用户管理模块"
第二轮:添加功能
"添加密码重置功能"
第三轮:优化
"优化数据库查询,添加索引"
第四轮:完善
"添加单元测试和文档"
安全性检查
# ❌ AI可能生成的有问题的代码
def login(username, password):
query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
# SQL注入风险!
# ✅ 应该要求改为
from sqlalchemy import text
def login(username: str, password: str):
query = text("SELECT * FROM users WHERE username=:username")
# 使用参数化查询
性能检查
# ❌ 低效代码
def get_user_orders(user_id):
orders = []
for order in db.query(Order).all(): # 全表扫描
if order.user_id == user_id:
orders.append(order)
return orders
# ✅ 优化后
def get_user_orders(user_id: int):
return db.query(Order).filter(Order.user_id == user_id).all()
可维护性检查
探索式开发
适用场景:技术调研、原型开发
流程:
1. 描述需求和约束
2. 让AI生成多个方案
3. 评估各方案优缺点
4. 选择并迭代
提示示例:
"我想实现一个实时聊天功能,请提供3种技术方案:
1. WebSocket方案
2. Server-Sent Events方案
3. 轮询方案
每种方案列出优缺点和适用场景"
测试驱动开发
流程:
1. 先写测试用例
2. 让AI实现通过测试的代码
3. 审查并优化
提示示例:
"我已经写了以下测试,请实现能通过这些测试的代码:
@test
async def test_create_user():
response = await client.post("/users", json={
"email": "test@example.com",
"password": "password123"
})
assert response.status_code == 201
assert response.json()["email"] == "test@example.com"
"
代码重构
流程:
1. 描述当前代码问题
2. 说明重构目标
3. 让AI生成重构方案
4. 审查并执行
提示示例:
"请重构以下代码,使其更符合SOLID原则:
@file:src/payment.py
目标:
1. 将支付方式抽成策略模式
2. 添加日志记录
3. 统一错误处理
"
使用AI生成项目结构
提示:
"创建一个Python FastAPI项目,包含:
- 项目结构(遵循最佳实践)
- 依赖管理(pyproject.toml)
- 配置管理(pydantic-settings)
- 日志配置
- Docker支持
- 基本的CI/CD配置
- README模板
项目名:my-api-service"
1. 需求分析
- 用自然语言描述功能
- 分解为可执行的任务
2. 代码生成
- 提供上下文和约束
- 让AI生成代码
3. 代码审查
- 检查逻辑正确性
- 检查安全性
- 检查性能
4. 测试验证
- 生成测试用例
- 运行验证
5. 迭代优化
- 根据反馈调整
- 重构和优化
| 陷阱 | 说明 | 解决方案 |
|---|---|---|
| 过度依赖 | 完全让AI写代码,自己不思考 | 保持架构设计能力 |
| 上下文丢失 | 多轮对话后AI忘记之前的要求 | 定期总结和重置上下文 |
| 幻觉代码 | AI生成不存在的API或库 | 验证所有依赖和API |
| 安全漏洞 | AI生成的代码可能有安全问题 | 强制安全审查 |
| 性能问题 | 生成的代码可能效率低下 | 性能测试和优化 |
建立个人提示库
# prompts/common_patterns.py
FASTAPI_CRUD = """
创建一个FastAPI CRUD端点,包含:
- Pydantic模型(Create/Update/Response)
- 依赖注入(数据库会话)
- 异常处理
- 分页支持
- 搜索过滤
资源名:{resource_name}
字段:{fields}
"""
REACT_COMPONENT = """
创建一个React函数组件,包含:
- TypeScript类型定义
- Props接口
- 状态管理(useState/useReducer)
- 副作用处理(useEffect)
- 样式(Tailwind CSS)
- 错误边界
组件名:{component_name}
功能:{description}
"""
使用Rules文件
# .cursorrules
## 代码风格
- 使用TypeScript严格模式
- 优先使用函数组件
- 使用Tailwind CSS进行样式
## 命名规范
- 组件名:PascalCase
- 函数名:camelCase
- 常量:UPPER_SNAKE_CASE
## 项目结构
- 组件放在 components/ 目录
- 工具函数放在 utils/ 目录
- 类型定义放在 types/ 目录
步骤1:项目初始化
"创建一个全栈应用,包含:
- 后端:FastAPI + SQLAlchemy + PostgreSQL
- 前端:React + TypeScript + Tailwind
- 功能:用户认证 + CRUD操作
生成完整的项目结构和基础代码"
步骤2:实现后端API
"实现用户注册和登录API:
- /auth/register - 用户注册
- /auth/login - 用户登录
- /auth/me - 获取当前用户
要求JWT认证,密码bcrypt加密"
步骤3:实现前端页面
"创建登录和注册页面:
- 表单验证
- 错误提示
- 加载状态
- 路由跳转
使用React Hook Form和Zod验证"
步骤4:集成和测试
"添加端到端测试:
- 用户注册流程
- 登录流程
- 受保护路由访问
使用Playwright"
重构前代码:
(一个200行的复杂函数)
提示:
"请重构以上代码:
问题:
1. 函数过长,职责过多
2. 嵌套层级太深
3. 错误处理不完善
目标:
1. 拆分为多个小函数
2. 使用早期返回减少嵌套
3. 添加统一的错误处理
4. 添加类型注解
保持原有功能不变"
最后更新: 2026年4月10日
本文综合了 Cursor、Copilot、Claude Code 等工具的最佳实践整理
学习顺序说明:本文是AI学习路线的第12篇,也是最终篇,建议按顺序学习:
- … → 11 AI Agent → 12 项目实战(本文)
本文将综合运用前面学习的知识,从零构建一个完整的AI应用项目。
构建一个智能文档助手系统,具备以下功能:
┌─────────────────────────────────────────────────────────────┐
│ 前端 (Vue/React) │
├─────────────────────────────────────────────────────────────┤
│ API层 (FastAPI) │
├─────────────────────────────────────────────────────────────┤
│ 文档处理服务 │ RAG检索服务 │ 对话服务 │ 向量数据库 │
├─────────────────────────────────────────────────────────────┤
│ 大语言模型 │
└─────────────────────────────────────────────────────────────┘
ai-doc-assistant/
├── backend/
│ ├── app/
│ │ ├── __init__.py
│ │ ├── main.py # FastAPI入口
│ │ ├── config.py # 配置
│ │ ├── routers/ # API路由
│ │ │ ├── chat.py
│ │ │ └── documents.py
│ │ ├── services/ # 业务逻辑
│ │ │ ├── document_processor.py
│ │ │ ├── rag_service.py
│ │ │ └── llm_service.py
│ │ └── models/ # 数据模型
│ ├── requirements.txt
│ └── Dockerfile
├── frontend/
│ ├── src/
│ └── package.json
├── docker-compose.yml
└── README.md
# requirements.txt
fastapi==0.104.1
uvicorn==0.24.0
python-multipart==0.0.6
langchain==0.1.0
langchain-openai==0.0.2
langchain-community==0.0.12
chromadb==0.4.22
pypdf==3.17.4
python-docx==1.1.0
openai==1.6.1
pydantic==2.5.2
pydantic-settings==2.1.0
# config.py
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
# API配置
API_TITLE: str = "AI文档助手"
API_VERSION: str = "1.0.0"
# 模型配置
OPENAI_API_KEY: str
LLM_MODEL: str = "gpt-4"
EMBEDDING_MODEL: str = "text-embedding-ada-002"
# 向量数据库
CHROMA_PERSIST_DIR: str = "./chroma_db"
# 文档配置
UPLOAD_DIR: str = "./uploads"
CHUNK_SIZE: int = 500
CHUNK_OVERLAP: int = 50
class Config:
env_file = ".env"
settings = Settings()
# services/document_processor.py
import os
from typing import List
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import PyPDFLoader, Docx2txtLoader
from langchain.schema import Document
class DocumentProcessor:
def __init__(self, chunk_size: int = 500, chunk_overlap: int = 50):
self.text_splitter = RecursiveCharacterTextSplitter(
chunk_size=chunk_size,
chunk_overlap=chunk_overlap,
separators=["\n\n", "\n", "。", "!", "?", ";", " ", ""]
)
def load_document(self, file_path: str) -> List[Document]:
"""加载文档"""
ext = os.path.splitext(file_path)[1].lower()
if ext == '.pdf':
loader = PyPDFLoader(file_path)
elif ext in ['.docx', '.doc']:
loader = Docx2txtLoader(file_path)
else:
# 默认作为文本处理
with open(file_path, 'r', encoding='utf-8') as f:
text = f.read()
return [Document(page_content=text, metadata={"source": file_path})]
return loader.load()
def split_documents(self, documents: List[Document]) -> List[Document]:
"""切分文档"""
return self.text_splitter.split_documents(documents)
def process_file(self, file_path: str) -> List[Document]:
"""处理单个文件"""
documents = self.load_document(file_path)
return self.split_documents(documents)
# services/rag_service.py
from typing import List, Optional
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory
class RAGService:
def __init__(self, persist_directory: str, embedding_model: str, llm_model: str):
self.embeddings = OpenAIEmbeddings(model=embedding_model)
self.llm = ChatOpenAI(model=llm_model, temperature=0.7)
self.vectorstore = Chroma(
persist_directory=persist_directory,
embedding_function=self.embeddings
)
self.memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
self.prompt_template = """
你是一个专业的文档助手。请根据以下上下文回答问题。
如果上下文中没有相关信息,请明确说明,不要编造答案。
上下文:
{context}
问题:{question}
回答:
"""
def add_documents(self, documents: List) -> None:
"""添加文档到向量库"""
self.vectorstore.add_documents(documents)
def search(self, query: str, k: int = 4) -> List:
"""检索相关文档"""
return self.vectorstore.similarity_search(query, k=k)
def query(self, question: str) -> dict:
"""问答"""
# 检索相关文档
docs = self.search(question)
context = "\n\n".join([doc.page_content for doc in docs])
# 构建prompt
prompt = PromptTemplate.from_template(self.prompt_template)
# 生成回答
chain = prompt | self.llm
response = chain.invoke({"context": context, "question": question})
return {
"answer": response.content,
"sources": [{"content": doc.page_content[:200],
"source": doc.metadata.get("source", "unknown")}
for doc in docs]
}
def chat(self, question: str) -> dict:
"""带记忆的对话"""
# 获取对话历史
chat_history = self.memory.load_memory_variables({}).get("chat_history", [])
# 检索
docs = self.search(question)
context = "\n\n".join([doc.page_content for doc in docs])
# 生成回答
prompt = PromptTemplate.from_template(self.prompt_template)
chain = prompt | self.llm
response = chain.invoke({"context": context, "question": question})
# 保存到记忆
self.memory.save_context({"input": question}, {"output": response.content})
return {
"answer": response.content,
"sources": [{"content": doc.page_content[:200]} for doc in docs]
}
# routers/documents.py
from fastapi import APIRouter, UploadFile, File, HTTPException
from typing import List
import os
import uuid
router = APIRouter(prefix="/documents", tags=["documents"])
@router.post("/upload")
async def upload_document(file: UploadFile = File(...)):
"""上传文档"""
# 保存文件
file_id = str(uuid.uuid4())
file_path = f"./uploads/{file_id}_{file.filename}"
os.makedirs("./uploads", exist_ok=True)
with open(file_path, "wb") as f:
content = await file.read()
f.write(content)
# 处理文档
from ..services.document_processor import DocumentProcessor
from ..services.rag_service import RAGService
from ..config import settings
processor = DocumentProcessor(
chunk_size=settings.CHUNK_SIZE,
chunk_overlap=settings.CHUNK_OVERLAP
)
documents = processor.process_file(file_path)
# 添加到向量库
rag = RAGService(
persist_directory=settings.CHROMA_PERSIST_DIR,
embedding_model=settings.EMBEDDING_MODEL,
llm_model=settings.LLM_MODEL
)
rag.add_documents(documents)
return {
"file_id": file_id,
"filename": file.filename,
"chunks": len(documents)
}
# routers/chat.py
from fastapi import APIRouter
from pydantic import BaseModel
router = APIRouter(prefix="/chat", tags=["chat"])
class ChatRequest(BaseModel):
question: str
use_memory: bool = True
class ChatResponse(BaseModel):
answer: str
sources: list
@router.post("/query", response_model=ChatResponse)
async def query(request: ChatRequest):
"""问答接口"""
from ..services.rag_service import RAGService
from ..config import settings
rag = RAGService(
persist_directory=settings.CHROMA_PERSIST_DIR,
embedding_model=settings.EMBEDDING_MODEL,
llm_model=settings.LLM_MODEL
)
if request.use_memory:
result = rag.chat(request.question)
else:
result = rag.query(request.question)
return ChatResponse(**result)
# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from .config import settings
from .routers import documents, chat
app = FastAPI(
title=settings.API_TITLE,
version=settings.API_VERSION
)
# CORS配置
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 注册路由
app.include_router(documents.router)
app.include_router(chat.router)
@app.get("/")
async def root():
return {"message": "AI文档助手API", "version": settings.API_VERSION}
@app.get("/health")
async def health():
return {"status": "healthy"}
<!-- ChatView.vue -->
<template>
<div class="chat-container">
<div class="messages">
<div v-for="msg in messages" :key="msg.id"
:class="['message', msg.role]">
<div class="content"></div>
<div v-if="msg.sources" class="sources">
<div v-for="source in msg.sources" :key="source">
</div>
</div>
</div>
</div>
<div class="input-area">
<el-input
v-model="question"
placeholder="输入您的问题..."
@keyup.enter="sendMessage"
/>
<el-button type="primary" @click="sendMessage">发送</el-button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import axios from 'axios'
const messages = ref([])
const question = ref('')
const sendMessage = async () => {
if (!question.value.trim()) return
// 添加用户消息
messages.value.push({
id: Date.now(),
role: 'user',
content: question.value
})
const userQuestion = question.value
question.value = ''
try {
const response = await axios.post('/api/chat/query', {
question: userQuestion,
use_memory: true
})
messages.value.push({
id: Date.now(),
role: 'assistant',
content: response.data.answer,
sources: response.data.sources
})
} catch (error) {
console.error('Error:', error)
}
}
</script>
# Dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
# docker-compose.yml
version: '3.8'
services:
backend:
build: ./backend
ports:
- "8000:8000"
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
volumes:
- ./uploads:/app/uploads
- ./chroma_db:/app/chroma_db
frontend:
build: ./frontend
ports:
- "80:80"
depends_on:
- backend
# 开发环境
uvicorn app.main:app --reload
# Docker部署
docker-compose up -d
恭喜你完成了AI学习路线的全部内容!
01 入门基础 → 02 机器学习 → 03 深度学习 → 04 NLP基础
→ 05 Transformer进阶 → 06 大模型应用 → 07 RAG系统
→ 08 AI工具链 → 09 计算机视觉 → 10 多模态大模型
→ 11 AI Agent → 12 项目实战
上一篇:11 AI Agent智能体 - 自主决策与工具调用
最后更新: 2026年4月10日
本文综合运用了前面所有文档的知识,祝你在AI领域取得成功!
学习顺序说明:本文是AI学习路线的第11篇,建议按顺序学习:
- … → 10 多模态大模型 → 11 AI Agent(本文)→ 12 项目实战
AI Agent(智能体)是能够自主决策、调用工具、完成复杂任务的AI系统。本文介绍Agent的核心技术和实现方法。
传统LLM应用:
用户问题 → LLM → 回答
AI Agent:
用户目标 → [理解 → 规划 → 执行 → 反思] 循环 → 结果
↓
工具调用 (搜索、代码执行、API等)
| 能力 | 说明 |
|---|---|
| 感知 | 理解环境和用户需求 |
| 规划 | 分解任务、制定计划 |
| 执行 | 调用工具完成任务 |
| 记忆 | 存储和检索历史信息 |
| 反思 | 评估结果、调整策略 |
参考资源:LLM Powered Autonomous Agents - Lilian Weng
from openai import OpenAI
import json
client = OpenAI(api_key="your-api-key")
# 定义工具函数
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "search_web",
"description": "搜索互联网获取信息",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词"
}
},
"required": ["query"]
}
}
}
]
# 实现工具函数
def get_weather(city):
# 模拟天气API
weather_data = {
"北京": {"temp": 25, "weather": "晴"},
"上海": {"temp": 28, "weather": "多云"},
"深圳": {"temp": 30, "weather": "晴"}
}
return json.dumps(weather_data.get(city, {"temp": 20, "weather": "未知"}))
def search_web(query):
# 模拟搜索
return f"关于'{query}'的搜索结果..."
# Agent对话
def agent_chat(user_message):
messages = [{"role": "user", "content": user_message}]
# 第一次调用
response = client.chat.completions.create(
model="gpt-4",
messages=messages,
tools=tools,
tool_choice="auto"
)
# 检查是否需要调用工具
response_message = response.choices[0].message
if response_message.tool_calls:
# 执行工具调用
for tool_call in response_message.tool_calls:
function_name = tool_call.function.name
function_args = json.loads(tool_call.function.arguments)
# 调用对应函数
if function_name == "get_weather":
result = get_weather(function_args["city"])
elif function_name == "search_web":
result = search_web(function_args["query"])
# 添加工具结果到消息
messages.append(response_message)
messages.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": result
})
# 再次调用获取最终回答
final_response = client.chat.completions.create(
model="gpt-4",
messages=messages
)
return final_response.choices[0].message.content
return response_message.content
# 测试
answer = agent_chat("北京今天天气怎么样?")
print(answer)
from langchain.tools import tool
from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
# 定义工具
@tool
def get_weather(city: str) -> str:
"""获取指定城市的天气信息"""
# 实际应用中调用天气API
return f"{city}今天天气晴朗,温度25度"
@tool
def calculate(expression: str) -> str:
"""计算数学表达式"""
try:
return str(eval(expression))
except:
return "计算错误"
@tool
def search_database(query: str) -> str:
"""搜索数据库"""
# 模拟数据库查询
return f"查询'{query}'的结果..."
# 创建Agent
llm = ChatOpenAI(model="gpt-4")
tools = [get_weather, calculate, search_database]
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个有用的助手,可以使用工具来帮助用户。"),
("human", "{input}"),
("placeholder", "{agent_scratchpad}")
])
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 执行
result = agent_executor.invoke({"input": "北京天气怎么样?温度加上10是多少?"})
print(result["output"])
ReAct = Reasoning + Acting,交替进行思考和行动。
from langchain.agents import create_react_agent
from langchain import hub
# ReAct Prompt
react_prompt = """
你需要回答以下问题。可以使用以下工具:
{tools}
使用以下格式:
Question: 输入问题
Thought: 思考该做什么
Action: 工具名称,必须是 [{tool_names}] 之一
Action Input: 工具输入
Observation: 工具输出
... (重复 Thought/Action/Action Input/Observation)
Thought: 我知道最终答案了
Final Answer: 最终答案
开始!
Question: {input}
Thought: {agent_scratchpad}
"""
# 创建ReAct Agent
prompt = ChatPromptTemplate.from_template(react_prompt)
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
先规划再执行,适合复杂任务。
from langchain_experimental.plan_and_execute import (
PlanAndExecute,
load_agent_executor,
load_chat_planner
)
# 创建规划器
planner = load_chat_planner(llm)
# 创建执行器
executor = load_agent_executor(llm, tools, verbose=True)
# 创建Plan-and-Execute Agent
agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)
# 执行复杂任务
result = agent.invoke("帮我规划一次日本旅行,包括东京和大阪,预算1万元")
class CustomAgent:
"""自定义Agent实现"""
def __init__(self, llm, tools, max_iterations=10):
self.llm = llm
self.tools = {tool.name: tool for tool in tools}
self.max_iterations = max_iterations
def run(self, task):
"""运行Agent"""
memory = []
for i in range(self.max_iterations):
# 生成思考
thought = self._think(task, memory)
memory.append(f"Thought: {thought}")
# 判断是否完成
if "FINISH" in thought or "任务完成" in thought:
return self._extract_answer(memory)
# 选择行动
action, action_input = self._decide_action(thought)
if action == "finish":
return action_input
# 执行工具
if action in self.tools:
observation = self.tools[action].invoke(action_input)
memory.append(f"Action: {action}({action_input})")
memory.append(f"Observation: {observation}")
return "达到最大迭代次数"
def _think(self, task, memory):
"""思考下一步"""
prompt = f"""
任务: {task}
已执行步骤:
{chr(10).join(memory)}
请思考下一步该做什么。如果任务已完成,回复"任务完成"。
"""
return self.llm.invoke(prompt).content
def _decide_action(self, thought):
"""决定执行哪个工具"""
# 使用LLM选择工具和输入
prompt = f"""
基于思考: {thought}
可用工具: {list(self.tools.keys())}
请输出要执行的工具名称和输入,格式:
工具名|输入
"""
response = self.llm.invoke(prompt).content
parts = response.split("|")
return parts[0].strip(), parts[1].strip() if len(parts) > 1 else ""
from langchain.memory import ConversationBufferMemory, ConversationSummaryMemory
from langchain.chains import ConversationChain
# 简单记忆
memory = ConversationBufferMemory()
chain = ConversationChain(llm=llm, memory=memory, verbose=True)
response1 = chain.predict(input="我叫张三")
response2 = chain.predict(input="我叫什么名字?") # 会记住张三
# 摘要记忆(适合长对话)
summary_memory = ConversationSummaryMemory(llm=llm)
chain = ConversationChain(llm=llm, memory=summary_memory)
from langchain.memory import VectorStoreRetrieverMemory
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
# 创建向量存储
embeddings = OpenAIEmbeddings()
vectorstore = Chroma(embedding_function=embeddings)
# 创建向量记忆
memory = VectorStoreRetrieverMemory(
retriever=vectorstore.as_retriever(search_kwargs={"k": 3})
)
# 添加记忆
memory.save_context({"input": "我喜欢编程"}, {"output": "好的,我会记住你喜欢编程"})
# 使用记忆
relevant_memories = memory.load_memory_variables({"input": "我的爱好是什么?"})
from langchain.tools import DuckDuckGoSearchRun
from langchain.agents import initialize_agent
# 搜索工具
search = DuckDuckGoSearchRun()
# 创建搜索Agent
tools = [search]
agent = initialize_agent(
tools,
llm,
agent="zero-shot-react-description",
verbose=True
)
# 执行搜索
result = agent.invoke("最新的AI发展趋势是什么?")
from langchain_experimental.utilities import PythonREPL
from langchain.tools import Tool
# Python执行工具
python_repl = PythonREPL()
repl_tool = Tool(
name="python_repl",
description="执行Python代码",
func=python_repl.run
)
# 创建代码Agent
agent = initialize_agent(
[repl_tool],
llm,
agent="zero-shot-react-description",
verbose=True
)
# 执行代码任务
result = agent.invoke("计算斐波那契数列前10项的和")
from langchain.agents import AgentExecutor
from langchain.schema import HumanMessage
class MultiAgentSystem:
"""多Agent系统"""
def __init__(self):
self.researcher = self._create_agent("研究员", "负责搜索和收集信息")
self.writer = self._create_agent("写作者", "负责撰写和编辑内容")
self.reviewer = self._create_agent("审核员", "负责审核和改进内容")
def _create_agent(self, role, goal):
prompt = ChatPromptTemplate.from_messages([
("system", f"你是{role},{goal}。"),
("human", "{input}")
])
return prompt | llm
def run(self, task):
# 研究员收集信息
research = self.researcher.invoke({"input": f"研究主题: {task}"})
# 写作者撰写内容
draft = self.writer.invoke({
"input": f"基于以下研究内容撰写文章:\n{research.content}"
})
# 审核员审核
review = self.reviewer.invoke({
"input": f"审核并改进以下内容:\n{draft.content}"
})
return review.content
最后更新: 2026年4月10日
本文参考了 LangChain文档 和 ReAct论文 整理
学习顺序说明:本文是AI学习路线的第10篇,建议按顺序学习:
- … → 09 计算机视觉 → 10 多模态大模型(本文)→ 11 AI Agent → 12 项目实战
多模态大模型(VLM)能够同时理解图像和文本,是当前AI的前沿方向。本文介绍多模态模型的核心技术和应用。
单模态模型:
- GPT: 文本输入 → 文本输出
- ResNet: 图像输入 → 类别输出
多模态模型:
- GPT-4V: 图像+文本输入 → 文本输出
- CLIP: 图像+文本 → 相似度
- Stable Diffusion: 文本 → 图像
| 任务 | 输入 | 输出 | 代表模型 |
|---|---|---|---|
| 图像描述 | 图像 | 文本 | BLIP, LLaVA |
| 视觉问答 | 图像+问题 | 答案 | GPT-4V, Qwen-VL |
| 图文检索 | 文本/图像 | 匹配分数 | CLIP |
| 文生图 | 文本 | 图像 | Stable Diffusion |
| 图像编辑 | 图像+指令 | 图像 | InstructPix2Pix |
CLIP通过对比学习,将图像和文本映射到同一向量空间。
from transformers import CLIPProcessor, CLIPModel
import torch
from PIL import Image
# 加载模型
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
# 图文相似度计算
image = Image.open("cat.jpg")
texts = ["a cat", "a dog", "a bird"]
inputs = processor(text=texts, images=image, return_tensors="pt", padding=True)
with torch.no_grad():
outputs = model(**inputs)
logits_per_image = outputs.logits_per_image # 图像与文本的相似度
probs = logits_per_image.softmax(dim=1) # 转换为概率
print("相似度概率:", probs)
# 输出类似: tensor([[0.95, 0.03, 0.02]])
零样本图像分类
def zero_shot_classification(image, class_names):
"""零样本分类"""
# 构造文本提示
texts = [f"a photo of a {name}" for name in class_names]
inputs = processor(text=texts, images=image, return_tensors="pt", padding=True)
with torch.no_grad():
outputs = model(**inputs)
probs = outputs.logits_per_image.softmax(dim=1)
return class_names[probs.argmax()], probs
# 使用示例
class_names = ["cat", "dog", "car", "flower"]
predicted_class, probs = zero_shot_classification(image, class_names)
print(f"预测类别: {predicted_class}")
图文检索
import faiss
import numpy as np
class ImageTextRetrieval:
def __init__(self):
self.model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
self.processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
self.index = None
self.image_ids = []
def encode_images(self, images):
"""编码图像"""
inputs = self.processor(images=images, return_tensors="pt", padding=True)
with torch.no_grad():
image_features = self.model.get_image_features(**inputs)
return image_features / image_features.norm(dim=-1, keepdim=True)
def encode_text(self, text):
"""编码文本"""
inputs = self.processor(text=[text], return_tensors="pt", padding=True)
with torch.no_grad():
text_features = self.model.get_text_features(**inputs)
return text_features / text_features.norm(dim=-1, keepdim=True)
def build_index(self, images, image_ids):
"""构建索引"""
features = self.encode_images(images)
features = features.numpy().astype('float32')
self.index = faiss.IndexFlatIP(features.shape[1])
self.index.add(features)
self.image_ids = image_ids
def search(self, query_text, top_k=5):
"""文本检索图像"""
text_features = self.encode_text(query_text).numpy().astype('float32')
scores, indices = self.index.search(text_features, top_k)
return [(self.image_ids[i], scores[0][j]) for j, i in enumerate(indices[0])]
参考资源:CLIP论文 - Learning Transferable Visual Models
LLaVA将视觉编码器与大语言模型连接,实现图像对话。
# 使用LLaVA进行视觉问答
from transformers import LlavaForConditionalGeneration, AutoProcessor
model = LlavaForConditionalGeneration.from_pretrained("llava-hf/llava-1.5-7b-hf")
processor = AutoProcessor.from_pretrained("llava-hf/llava-1.5-7b-hf")
# 准备输入
image = Image.open("image.jpg")
conversation = [
{
"role": "user",
"content": [
{"type": "image"},
{"type": "text", "text": "请描述这张图片的内容"}
]
}
]
prompt = processor.apply_chat_template(conversation, add_generation_prompt=True)
inputs = processor(images=image, text=prompt, return_tensors="pt")
# 生成回答
output = model.generate(**inputs, max_new_tokens=200)
print(processor.decode(output[0], skip_special_tokens=True))
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.generation import GenerationConfig
# 加载Qwen-VL
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen-VL-Chat", trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen-VL-Chat",
trust_remote_code=True,
device_map="auto"
)
# 视觉问答
query = tokenizer.from_list_format([
{'image': 'image.jpg'},
{'text': '描述这张图片'},
])
response, history = model.chat(tokenizer, query=query, history=None)
print(response)
# 多轮对话
query = tokenizer.from_list_format([
{'text': '图片中有几个人?'},
])
response, history = model.chat(tokenizer, query=query, history=history)
print(response)
from openai import OpenAI
client = OpenAI(api_key="your-api-key")
# 图像理解
response = client.chat.completions.create(
model="gpt-4-vision-preview",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "这张图片里有什么?"},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/image.jpg",
# 或使用base64
# "url": f"data:image/jpeg;base64,{base64_image}"
}
}
]
}
],
max_tokens=500
)
print(response.choices[0].message.content)
from diffusers import StableDiffusionPipeline
import torch
# 加载模型
pipe = StableDiffusionPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
torch_dtype=torch.float16
)
pipe = pipe.to("cuda")
# 文生图
prompt = "a beautiful sunset over mountains, highly detailed, 4k"
image = pipe(prompt).images[0]
image.save("sunset.png")
# 负面提示
image = pipe(
prompt="a portrait of a woman",
negative_prompt="ugly, distorted, low quality",
num_inference_steps=30,
guidance_scale=7.5
).images[0]
# 图生图
from diffusers import StableDiffusionImg2ImgPipeline
pipe = StableDiffusionImg2ImgPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
torch_dtype=torch.float16
).to("cuda")
init_image = Image.open("input.jpg").convert("RGB")
init_image = init_image.resize((512, 512))
image = pipe(
prompt="cyberpunk style",
image=init_image,
strength=0.7
).images[0]
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from diffusers.utils import load_image
# 加载ControlNet
controlnet = ControlNetModel.from_pretrained(
"lllyasviel/sd-controlnet-canny",
torch_dtype=torch.float16
)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
controlnet=controlnet,
torch_dtype=torch.float16
).to("cuda")
# 准备控制图像
image = load_image("input.jpg")
# 边缘检测
import cv2
import numpy as np
np_image = np.array(image)
canny_image = cv2.Canny(np_image, 100, 200)
canny_image = Image.fromarray(canny_image)
# 生成
image = pipe(
prompt="a modern building",
image=canny_image,
num_inference_steps=20
).images[0]
参考资源:Stable Diffusion论文
class VisualQA:
def __init__(self, model_name="Qwen/Qwen-VL-Chat"):
self.tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
self.model = AutoModelForCausalLM.from_pretrained(
model_name,
trust_remote_code=True,
device_map="auto"
)
def ask(self, image_path, question):
query = self.tokenizer.from_list_format([
{'image': image_path},
{'text': question}
])
response, _ = self.model.chat(self.tokenizer, query=query, history=None)
return response
def chat(self, image_path, questions):
"""多轮对话"""
history = None
responses = []
for question in questions:
query = self.tokenizer.from_list_format([
{'image': image_path},
{'text': question}
])
response, history = self.model.chat(
self.tokenizer, query=query, history=history
)
responses.append(response)
return responses
# 使用
vqa = VisualQA()
answer = vqa.ask("photo.jpg", "图片中有多少人?")
def generate_caption(image_path):
"""生成图像描述"""
query = tokenizer.from_list_format([
{'image': image_path},
{'text': '请详细描述这张图片的内容'}
])
response, _ = model.chat(tokenizer, query=query, history=None)
return response
# 批量处理
def batch_caption(image_paths):
captions = []
for path in image_paths:
caption = generate_caption(path)
captions.append(caption)
return captions
下一篇:11 AI Agent智能体 - 自主决策与工具调用
最后更新: 2026年4月10日
学习顺序说明:本文是AI学习路线的第9篇,建议按顺序学习:
- 01 入门基础 → … → 08 AI工具链 → 09 计算机视觉(本文)→ 10 多模态大模型 → 11 AI Agent → 12 项目实战
计算机视觉是AI的重要分支,让机器能够”看懂”图像和视频。本文介绍计算机视觉的核心技术和应用。
计算机视觉
├── 图像分类 (Image Classification)
├── 目标检测 (Object Detection)
├── 图像分割 (Image Segmentation)
│ ├── 语义分割
│ └── 实例分割
├── 目标跟踪 (Object Tracking)
├── 图像生成 (Image Generation)
└── 视觉问答 (Visual QA)
参考资源:CS231n: CNN for Visual Recognition - Stanford经典课程
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
img = cv2.imread('image.jpg')
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # BGR转RGB
# 基本操作
print(f"图像尺寸: {img.shape}") # (height, width, channels)
# 调整大小
resized = cv2.resize(img, (224, 224))
# 裁剪
cropped = img[100:300, 200:400]
# 灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 模糊
blurred = cv2.GaussianBlur(img, (5, 5), 0)
# 边缘检测
edges = cv2.Canny(gray, 100, 200)
# 显示
cv2.imshow('Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 亮度/对比度调整
def adjust_brightness_contrast(img, brightness=0, contrast=0):
if brightness != 0:
img = cv2.convertScaleAbs(img, alpha=1, beta=brightness)
if contrast != 0:
img = cv2.convertScaleAbs(img, alpha=contrast, beta=0)
return img
# 直方图均衡化
def histogram_equalization(img):
if len(img.shape) == 3:
# 彩色图像,转换到YUV空间
img_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
img_yuv[:,:,0] = cv2.equalizeHist(img_yuv[:,:,0])
return cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)
else:
return cv2.equalizeHist(img)
# 数据增强
from torchvision import transforms
transform = transforms.Compose([
transforms.RandomHorizontalFlip(p=0.5),
transforms.RandomRotation(15),
transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),
transforms.RandomResizedCrop(224, scale=(0.8, 1.0)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
参考资源:OpenCV官方文档
ResNet迁移学习
import torch
import torch.nn as nn
from torchvision import models
# 加载预训练ResNet
model = models.resnet50(pretrained=True)
# 修改最后一层
num_classes = 10
model.fc = nn.Linear(model.fc.in_features, num_classes)
# 冻结特征提取层
for param in model.parameters():
param.requires_grad = False
for param in model.fc.parameters():
param.requires_grad = True
# 训练
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.fc.parameters(), lr=0.001)
EfficientNet
# 使用torchvision的EfficientNet
from torchvision.models import efficientnet_b0
model = efficientnet_b0(pretrained=True)
model.classifier[1] = nn.Linear(model.classifier[1].in_features, num_classes)
import torch
from torch.utils.data import DataLoader
from torchvision import datasets, transforms, models
# 数据预处理
train_transform = transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
val_transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
# 加载数据
train_dataset = datasets.ImageFolder('train/', transform=train_transform)
val_dataset = datasets.ImageFolder('val/', transform=val_transform)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=32)
# 模型
model = models.resnet50(pretrained=True)
model.fc = nn.Linear(model.fc.in_features, len(train_dataset.classes))
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device)
# 训练循环
def train_epoch(model, loader, criterion, optimizer):
model.train()
running_loss = 0.0
correct = 0
for inputs, labels in loader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
_, predicted = outputs.max(1)
correct += predicted.eq(labels).sum().item()
return running_loss / len(loader), correct / len(loader.dataset)
| 方法 | 类型 | 特点 |
|---|---|---|
| YOLO | 单阶段 | 速度快,实时检测 |
| SSD | 单阶段 | 多尺度检测 |
| Faster R-CNN | 两阶段 | 精度高,速度较慢 |
| DETR | Transformer | 端到端,无需NMS |
# 使用ultralytics YOLOv8
from ultralytics import YOLO
# 加载预训练模型
model = YOLO('yolov8n.pt') # nano版本,速度快
# 推理
results = model('image.jpg')
# 显示结果
for result in results:
boxes = result.boxes # 边界框
for box in boxes:
x1, y1, x2, y2 = box.xyxy[0] # 坐标
confidence = box.conf[0] # 置信度
class_id = box.cls[0] # 类别
print(f"类别: {model.names[int(class_id)]}, 置信度: {confidence:.2f}")
print(f"边界框: ({x1:.0f}, {y1:.0f}, {x2:.0f}, {y2:.0f})")
# 可视化
result.show()
result.save('output.jpg')
# 训练自定义数据集
model.train(data='dataset.yaml', epochs=50, imgsz=640)
# IoU (Intersection over Union)
def calculate_iou(box1, box2):
"""计算两个边界框的IoU"""
x1 = max(box1[0], box2[0])
y1 = max(box1[1], box2[1])
x2 = min(box1[2], box2[2])
y2 = min(box1[3], box2[3])
inter_area = max(0, x2 - x1) * max(0, y2 - y1)
box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1])
box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1])
union_area = box1_area + box2_area - inter_area
return inter_area / union_area if union_area > 0 else 0
# mAP计算
# mAP@0.5: IoU阈值0.5时的平均精度
# mAP@0.5:0.95: IoU阈值从0.5到0.95,步长0.05的平均mAP
参考资源:YOLOv8官方文档
U-Net架构
import torch
import torch.nn as nn
class UNet(nn.Module):
"""简化版U-Net"""
def __init__(self, in_channels=3, out_channels=1):
super().__init__()
# 编码器
self.enc1 = self.conv_block(in_channels, 64)
self.enc2 = self.conv_block(64, 128)
self.enc3 = self.conv_block(128, 256)
self.enc4 = self.conv_block(256, 512)
self.pool = nn.MaxPool2d(2)
# 解码器
self.up3 = nn.ConvTranspose2d(512, 256, 2, stride=2)
self.dec3 = self.conv_block(512, 256)
self.up2 = nn.ConvTranspose2d(256, 128, 2, stride=2)
self.dec2 = self.conv_block(256, 128)
self.up1 = nn.ConvTranspose2d(128, 64, 2, stride=2)
self.dec1 = self.conv_block(128, 64)
self.final = nn.Conv2d(64, out_channels, 1)
def conv_block(self, in_ch, out_ch):
return nn.Sequential(
nn.Conv2d(in_ch, out_ch, 3, padding=1),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True),
nn.Conv2d(out_ch, out_ch, 3, padding=1),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True)
)
def forward(self, x):
# 编码
e1 = self.enc1(x)
e2 = self.enc2(self.pool(e1))
e3 = self.enc3(self.pool(e2))
e4 = self.enc4(self.pool(e3))
# 解码
d3 = self.up3(e4)
d3 = torch.cat([d3, e3], dim=1)
d3 = self.dec3(d3)
d2 = self.up2(d3)
d2 = torch.cat([d2, e2], dim=1)
d2 = self.dec2(d2)
d1 = self.up1(d2)
d1 = torch.cat([d1, e1], dim=1)
d1 = self.dec1(d1)
return self.final(d1)
使用Mask R-CNN
import torchvision
from torchvision.models.detection import maskrcnn_resnet50_fpn
# 加载预训练模型
model = maskrcnn_resnet50_fpn(pretrained=True)
model.eval()
# 推理
from PIL import Image
import torchvision.transforms as T
img = Image.open('image.jpg')
img_tensor = T.ToTensor()(img)
with torch.no_grad():
prediction = model([img_tensor])
# 解析结果
boxes = prediction[0]['boxes'] # 边界框
labels = prediction[0]['labels'] # 类别
scores = prediction[0]['scores'] # 分数
masks = prediction[0]['masks'] # 分割掩码
# 可视化掩码
for i, (box, mask) in enumerate(zip(boxes, masks)):
if scores[i] > 0.5: # 置信度阈值
mask = mask[0].numpy()
# 应用掩码
pass
参考资源:Mask R-CNN论文
import cv2
# 加载人脸检测器
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
def detect_faces(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
return img
# 使用深度学习模型
from facenet_pytorch import InceptionResnetV1, MTCNN
mtcnn = MTCNN() # 人脸检测
resnet = InceptionResnetV1(pretrained='vggface2').eval() # 人脸特征提取
# 检测人脸
img = Image.open('face.jpg')
face = mtcnn(img)
# 提取特征向量
embedding = resnet(face.unsqueeze(0))
# 使用PaddleOCR
from paddleocr import PaddleOCR
ocr = PaddleOCR(use_angle_cls=True, lang='ch')
result = ocr.ocr('document.jpg', cls=True)
for line in result:
print(line)
最后更新: 2026年4月10日
学习顺序说明:本文是AI学习路线的第8篇,建议按顺序学习:
- 01 入门基础 → 02 机器学习 → 03 深度学习 → 04 NLP基础 → 05 Transformer进阶 → 06 大模型应用 → 07 RAG系统 → 08 AI工具链(本文)
工欲善其事,必先利其器。本文将介绍AI开发中常用的工具和环境配置。
Anaconda/Miniconda
# 创建虚拟环境
conda create -n ai-env python=3.10
# 激活环境
conda activate ai-env
# 安装包
conda install numpy pandas scikit-learn
pip install torch transformers
# 导出环境
conda env export > environment.yml
# 从文件创建环境
conda env create -f environment.yml
Poetry (推荐)
# 安装Poetry
pip install poetry
# 创建项目
poetry new ai-project
cd ai-project
# 添加依赖
poetry add numpy pandas torch transformers
# 安装依赖
poetry install
# 导出requirements
poetry export -f requirements.txt --output requirements.txt
# 安装
pip install jupyter
# 启动
jupyter notebook
# 安装扩展
pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
常用快捷键:
| 快捷键 | 功能 |
|---|---|
| Shift + Enter | 运行当前单元格 |
| A | 在上方插入单元格 |
| B | 在下方插入单元格 |
| DD | 删除单元格 |
| M | 转为Markdown |
| Y | 转为代码 |
免费GPU环境,适合学习和实验。
# 检查GPU
import torch
print(f"CUDA可用: {torch.cuda.is_available()}")
print(f"GPU设备: {torch.cuda.get_device_name(0)}")
# 挂载Google Drive
from google.colab import drive
drive.mount('/content/drive')
# 安装包
!pip install transformers datasets
Colab技巧:
!执行Shell命令# 初始化仓库
git init
# 克隆仓库
git clone https://github.com/user/repo.git
# 添加文件
git add .
git add file.py
# 提交
git commit -m "添加新功能"
# 推送
git push origin main
# 拉取
git pull origin main
# 分支操作
git branch feature-branch
git checkout feature-branch
git checkout -b new-branch # 创建并切换
# 合并
git merge feature-branch
# Python
__pycache__/
*.py[cod]
*.so
.Python
env/
venv/
.venv/
# Jupyter Notebook
.ipynb_checkpoints/
# 数据文件
*.csv
*.json
data/
# 模型文件
*.pth
*.bin
models/
# 环境配置
.env
*.env
# 安装Git LFS
git lfs install
# 跟踪大文件
git lfs track "*.pth"
git lfs track "*.bin"
# 提交
git add .gitattributes
git commit -m "配置Git LFS"
# Dockerfile
FROM python:3.10-slim
WORKDIR /app
# 安装依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制代码
COPY . .
# 运行
CMD ["python", "main.py"]
# 构建镜像
docker build -t ai-app .
# 运行容器
docker run -p 8000:8000 ai-app
# GPU支持
docker run --gpus all -p 8000:8000 ai-app
# docker-compose.yml
version: '3.8'
services:
api:
build: .
ports:
- "8000:8000"
volumes:
- ./data:/app/data
environment:
- MODEL_PATH=/app/models
depends_on:
- db
db:
image: postgres:14
environment:
POSTGRES_DB: aidb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
import mlflow
# 开始实验
mlflow.start_run()
# 记录参数
mlflow.log_param("learning_rate", 0.001)
mlflow.log_param("epochs", 10)
# 记录指标
mlflow.log_metric("accuracy", 0.95)
mlflow.log_metric("loss", 0.05)
# 记录模型
mlflow.pytorch.log_model(model, "model")
# 结束实验
mlflow.end_run()
# datasets - Hugging Face数据集
from datasets import load_dataset
dataset = load_dataset("imdb")
print(dataset)
# pandas-profiling - 数据分析报告
from pandas_profiling import ProfileReport
profile = ProfileReport(df)
profile.to_file("report.html")
# tqdm - 进度条
from tqdm import tqdm
for item in tqdm(data_list):
process(item)
# TensorBoard
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter()
writer.add_scalar('Loss/train', loss, epoch)
writer.add_histogram('weights', model.fc.weight, epoch)
writer.close()
# 启动: tensorboard --logdir=runs
# Weights & Biases
import wandb
wandb.init(project="my-project")
wandb.config = {"learning_rate": 0.001, "epochs": 10}
wandb.log({"loss": loss, "accuracy": acc})
# 记录模型推理
def log_inference(input_text, output, latency):
log_data = {
"timestamp": datetime.now().isoformat(),
"input": input_text,
"output": output,
"latency_ms": latency
}
# 存储到数据库或文件
| 平台 | 特点 | 链接 |
|---|---|---|
| Kaggle | 竞赛+数据集+Notebook | kaggle.com |
| Hugging Face | 模型+数据集+Space | huggingface.co |
| Colab | 免费GPU | colab.research.google.com |
| Papers with Code | 论文+代码 | paperswithcode.com |
| 项目 | 用途 |
|---|---|
| fastai | 深度学习简化API |
| timm | 图像模型库 |
| accelerate | 分布式训练 |
| peft | 高效微调 |
| langchain | LLM应用开发 |
恭喜你完成了AI学习路线的全部内容!
01 入门基础 → 02 机器学习 → 03 深度学习 → 04 NLP基础
→ 05 Transformer进阶 → 06 大模型应用 → 07 RAG系统 → 08 AI工具链
最后更新: 2026年4月10日
本文整理了AI开发常用的工具和资源,祝学习顺利!