30天学习计划:Java转AI应用开发

30天学习计划:Java转AI应用开发

开始日期: 2026-08-09
结束日期: 2026-09-07

学习目标

从 Java 背景快速掌握 AI 应用开发全栈能力,完成端到端的"智能 SQL 查询与报表生成 Agent"项目。


环境准备(Day 0 - 8月8日晚完成)

必装软件

Python 虚拟环境

# 创建项目目录
mkdir ai-learning && cd ai-learning

# 创建虚拟环境
python -m venv .venv

# 激活(Windows)
.venv\Scripts\activate

# 安装基础依赖
pip install openai httpx fastapi uvicorn pydantic python-dotenv
pip install langchain langchain-openai langchain-community
pip install pgvector psycopg2-binary
pip install pypdf2 python-docx
pip install matplotlib plotly
pip install langgraph
pip install langsmith ragas

API Key 配置

创建 .env 文件:

OPENAI_API_KEY=sk-xxx
# 或使用国内大模型(推荐,省钱)
# DEEPSEEK_API_KEY=sk-xxx
# ZHIPU_API_KEY=xxx

学习资料

检验标准


第一周:Python 快速过关与 LLM 基础通信

Day 1 (08-09) Python 异步编程

今日任务

学习资料

练习代码

# 练习1:基础异步
import asyncio
import time

async def fetch_data(delay):
    await asyncio.sleep(delay)
    return f"data after {delay}s"

async def main():
    start = time.time()
    # 并发执行3个任务
    results = await asyncio.gather(
        fetch_data(1), fetch_data(2), fetch_data(1)
    )
    print(results)
    print(f"总耗时: {time.time() - start:.2f}s")  # 应该是2s左右,不是4s

asyncio.run(main())

完成标准


Day 2 (08-10) FastAPI 入门

今日任务

学习资料

练习代码

# main.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float

items_db = []

@app.get("/")
async def root():
    return {"message": "Hello FastAPI"}

@app.post("/items/")
async def create_item(item: Item):
    items_db.append(item)
    return item

@app.get("/items/{item_id}")
async def get_item(item_id: int):
    if item_id >= len(items_db):
        raise HTTPException(status_code=404, detail="Item not found")
    return items_db[item_id]

运行与测试

uvicorn main:app --reload
# 浏览器打开 http://127.0.0.1:8000/docs 查看自动生成的 Swagger 文档

完成标准


Day 3 (08-11) Pydantic 数据校验

今日任务

学习资料

练习代码

from pydantic import BaseModel, Field, field_validator, EmailStr
from typing import Optional

class User(BaseModel):
    name: str = Field(..., min_length=2, max_length=50)
    age: int = Field(..., ge=0, le=150)
    email: str
    role: str = Field(default="user", pattern="^(admin|user|guest)$")
    
    @field_validator('email')
    @classmethod
    def validate_email(cls, v):
        if '@' not in v:
            raise ValueError('Invalid email')
        return v.lower()

# 测试
try:
    user = User(name="A", age=200, email="test", role="superadmin")
except ValueError as e:
    print(e)  # 会输出所有校验错误

完成标准


Day 4 (08-12) LLM API 接入

今日任务

学习资料

练习代码

import os
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv()

# 使用 DeepSeek(便宜)或 OpenAI
client = OpenAI(
    api_key=os.getenv("DEEPSEEK_API_KEY"),
    base_url="https://api.deepseek.com"  # DeepSeek 专用
)

response = client.chat.completions.create(
    model="deepseek-chat",
    messages=[
        {"role": "system", "content": "你是一个Java技术专家,正在学习Python"},
        {"role": "user", "content": "用Java的视角解释Python的list和dict"}
    ],
    temperature=0.7,
    max_tokens=500
)

print(response.choices[0].message.content)

完成标准


Day 5 (08-13) Prompt 工程

今日任务

学习资料

练习任务

# 实验1:Temperature 对比
for temp in [0, 0.5, 1.0, 1.5]:
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[{"role": "user", "content": "写一首关于编程的诗"}],
        temperature=temp
    )
    print(f"\n=== Temperature {temp} ===")
    print(response.choices[0].message.content)
# 实验2:Few-shot 提示
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages = [
            {"role": "system", "content": "你是一个代码审查专家,指出代码问题并给出改进建议"},
            {"role": "user", "content": "审查以下代码:\ndef add(a, b):\nreturn a + b + 1\n用以下格式回复:\n【问题】xxx\n【原因】xxx\n【修复】xxx"}
        ],
        temperature=0.7,
        max_tokens=500
    )

    print(response.choices[0].message.content)

完成标准


Day 6 (08-14) 结构化输出(上)

今日任务

学习资料

练习代码

from pydantic import BaseModel, Field
from typing import List
from openai import OpenAI

class UserInfo(BaseModel):
    """从文本中提取的用户信息"""
    name: str = Field(description="用户姓名")
    age: int = Field(ge=0, le=150, description="年龄")
    skills: List[str] = Field(description="技能列表")
    experience_years: int = Field(description="工作年限")

client = OpenAI()
# 方法1:使用 response_format (需要模型支持)
response = client.chat.completions.create(
    model="gpt-4o",  # 或 deepseek-chat 不一定支持
    messages=[
        {"role": "system", "content": "从用户描述中提取信息,输出JSON"},
        {"role": "user", "content": "张三,28岁,会Python和Java,工作了5年"}
    ],
    response_format={"type": "json_object"}
)

# 方法2:Pydantic 校验(更通用)
import json
data = json.loads(response.choices[0].message.content)
user = UserInfo(**data)  # 自动校验
print(user)

完成标准


Day 7 (08-15) 结构化输出(下)

今日任务

练习任务

# 复杂嵌套结构
class Address(BaseModel):
    city: str
    district: str

class Resume(BaseModel):
    name: str
    contact: dict  # {"phone": "...", "email": "..."}
    address: Address
    education: List[dict]  # [{"school": "...", "degree": "...", "year": ...}]
    work_experience: List[dict]

# 错误处理
from tenacity import retry, stop_after_attempt, wait_exponential

# 错误处理:校验失败会抛异常,触发重试
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
def extract_with_retry(text: str) -> Resume:
    content = chat(
        messages=[
            {"role": "system", "content": "从简历文本中提取信息,输出JSON"},
            {"role": "user", "content": text}
        ],
        temperature=0.1,
        response_format={"type": "json_object"}
    )
    print(content)
    data = json.loads(content)
    return Resume(**data)  # 校验失败会抛异常,触发重试

extract_with_retry("张伟,现居北京市海淀区,联系电话 138-0000-0000,邮箱 zhangwei@example.com。他拥有清华大学计算机科学与技术硕士学位(2021年毕业)及北京航空航天大学软件工程学士学位(2018年毕业)。在工作经历方面,他于2020年6月至12月在美团担任后端开发实习生,参与订单系统业务开发与数据库索引调优;自2021年7月至今在字节跳动担任高级后端开发工程师,主要负责核心服务架构设计、微服务拆分以及高并发场景下的性能优化。")

完成标准


第一周总结检查点


第二周:企业级 RAG 与向量数据库

Day 8 (08-16) 向量数据库部署

今日任务

学习资料

操作步骤

# Docker 部署 Pgvector
docker run -d \
  --name pgvector \
  -e POSTGRES_PASSWORD=mysecretpassword \
  -p 5432:5432 \
  pgvector/pgvector:pg16

# Python 连接测试
pip install pgvector psycopg2-binary
"""pgvector 文本向量检索示例:把文本转成向量存入 PostgreSQL,再按相似度检索文本。"""
import psycopg2
import numpy as np
from pgvector import Vector
from pgvector.psycopg2 import register_vector

# ---------- 文本向量化:字符 n-gram 稳定哈希 + L2 归一化 ----------
VECTOR_DIM = 64


def _feat_hash(token: str) -> int:
    """FNV-1a 稳定哈希,保证跨进程、跨运行结果一致"""
    h = 2166136261
    for ch in token:
        h ^= ord(ch)
        h = (h * 16777619) & 0xFFFFFFFF
    return h


def text_to_vector(text: str, dim: int = VECTOR_DIM) -> np.ndarray:
    """把文本转成归一化向量:统计字符 unigram + bigram 的哈希频率"""
    vec = np.zeros(dim, dtype=np.float32)
    s = text.lower().replace(" ", "")
    for ch in s:
        vec[_feat_hash(ch) % dim] += 1
    for i in range(len(s) - 1):
        vec[_feat_hash(s[i:i + 2]) % dim] += 1
    norm = np.linalg.norm(vec)
    return vec / norm if norm > 0 else vec


# ---------- 连接数据库 ----------
conn = psycopg2.connect(
    host="localhost",
    database="postgres",
    user="postgres",
    password="postgres"
)

# 必须先安装 vector 扩展,否则 register_vector 和 vector 类型都会报错
cur = conn.cursor()
cur.execute("CREATE EXTENSION IF NOT EXISTS vector")
conn.commit()

register_vector(conn)

# ---------- 建表并写入文本 ----------
cur = conn.cursor()
cur.execute("DROP TABLE IF EXISTS documents")
cur.execute(f"CREATE TABLE documents (id serial PRIMARY KEY, content text NOT NULL, embedding vector({VECTOR_DIM}))")

documents = [
    "深度学习是机器学习的一个重要分支",
    "人工智能正在改变我们的生活方式",
    "python 是一门流行的编程语言",
    "pgvector 扩展可以在 postgresql 数据库中存储和检索向量",
    "机器学习模型通常需要大量数据进行训练",
    "如何选择适合自己的编程语言",
]
for text in documents:
    vec = text_to_vector(text)
    cur.execute(
        "INSERT INTO documents (content, embedding) VALUES (%s, %s)",
        (text, Vector(vec))
    )
conn.commit()
print(f"已写入 {len(documents)} 条文本到 documents 表\n")

# ==================== 文本检索示例 ====================

# 1. 查询表中全部文本
cur.execute("SELECT id, content FROM documents ORDER BY id")
rows = cur.fetchall()
print("=== 全部文本 ===")
for row in rows:
    print(f"id={row[0]}, content={row[1]}")
print()

# 2. 文本相似度检索:输入一句话,找到库里最相似的 3 条文本
#    <=> 是余弦距离(越小越相似),升序排列即按相似度从高到低
#    注意:参数必须用 Vector 包装,pgvector 0.5 的 psycopg2 适配器不会自动转换 list/ndarray
query_text = "什么编程语言容易上手"
query_vec = text_to_vector(query_text)
cur.execute(
    """
    SELECT id, content, 1 - (embedding <=> %s) AS similarity
    FROM documents
    ORDER BY embedding <=> %s
    LIMIT 3
    """,
    (Vector(query_vec), Vector(query_vec))
)
print(f"=== 检索「{query_text}」最相似的 3 条文本 ===")
for row in cur.fetchall():
    print(f"id={row[0]}, similarity={row[2]:.4f}, content={row[1]}")
print()

# 3. 距离阈值过滤:只返回距离小于指定阈值的文本
cur.execute(
    """
    SELECT id, content, embedding <=> %s AS distance
    FROM documents
    WHERE embedding <=> %s < 0.9
    ORDER BY embedding <=> %s
    """,
    (Vector(query_vec), Vector(query_vec), Vector(query_vec))
)
print(f"=== 与「{query_text}」距离小于 0.9 的文本 ===")
for row in cur.fetchall():
    print(f"id={row[0]}, distance={row[2]:.4f}, content={row[1]}")

conn.close()

示例做了什么

文本向量化text_to_vector):本地把文本转成 64 维归一化向量——统计字符 unigram + bigram 的特征哈希频率,再 L2 归一化。用 FNV-1a 稳定哈希保证跨进程结果一致。

建表入库

CREATE TABLE documents (
    id serial PRIMARY KEY,
    content text NOT NULL,
    embedding vector(64)
)

插入 6 条中文文本 + 各自向量。

三种检索方式

  • 查询全部文本
  • 相似度检索:ORDER BY embedding <=> %s LIMIT 3,用余弦距离(<=>)排序,1 - distance 即相似度
  • 距离阈值过滤:WHERE embedding <=> %s < 0.9

重要说明

  • 关于向量生成方式:你的代理服务(127.0.0.1:4000)只提供了 deepseek-chat聊天模型,没有 embedding 模型(我实测 text-embedding-ada-002text-embedding-3-small 都返回 400)。所以示例改用本地哈希向量——它能演示完整流程,但这是基于字符重合的"词法相似",不是真正的语义相似(例如"苹果"和"水果"虽语义相近但字符不同,哈希向量算不出来)。

  • 如果要真正的语义检索,有两个方向:

    • 在代理端配置一个 embedding 模型(如 OpenAI text-embedding-3-small、阿里 text-embedding-v3),然后替换 text_to_vector 为一次 API 调用即可,pgvector 部分完全不用改;
    • 或本地装 sentence-transformers(需下载模型,体积较大)离线生成向量。
  • pgvector 检索 SQL 本身(<=>ORDER BYLIMIT)与你用哪种 embedding 无关,这段代码未来可直接复用。

完成标准


Day 9 (08-17) 文档解析

今日任务

学习资料

练习代码

# PDF 解析
from PyPDF2 import PdfReader

reader = PdfReader(r"D:\Documents\temp\6-10-all.pdf")
text = ""
for page in reader.pages:
    text += page.extract_text()
print(text[:100])



# Word 解析
from docx import Document

doc = Document(r"D:\Documents\temp\2_20250711申论理论6讲课堂笔记_repaired.docx")
for para in doc.paragraphs:
    print(para.text[:100])

# 表格提取
for table in doc.tables:
    for row in table.rows:
        print([cell.text for cell in row.cells])


# Excel 解析(.xlsx 需安装 openpyxl;.xls 需安装 xlrd;.csv 无需额外库)
import pandas as pd

excel_path = r"D:\Documents\temp\example.xlsx"

# 读取文件中的所有工作表
all_sheets = pd.read_excel(excel_path, sheet_name=None)
for sheet_name, df in all_sheets.items():
    print(f"===== 工作表: {sheet_name} =====")
    print(f"共 {len(df)} 行, {len(df.columns)} 列")
    print(df.head(10))

# 若只要第一个工作表, 可以这样:
# df = pd.read_excel(excel_path, sheet_name=0)
# for _, row in df.iterrows():
#     print(dict(row))

完成标准


Day 10 (08-18) 语义切片策略

今日任务

学习资料

练习代码

from langchain.text_splitter import (
    CharacterTextSplitter,
    RecursiveCharacterTextSplitter
)

text = """很长的文档内容..."""

# 方法1:固定大小
splitter = CharacterTextSplitter(
    separator="\n",
    chunk_size=500,
    chunk_overlap=50
)
chunks = splitter.split_text(text)

# 方法2:递归字符(推荐)
splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=50,
    separators=["\n\n", "\n", "。", " ", ""]
)
chunks = splitter.split_text(text)

print(f"共切分为 {len(chunks)} 个片段")

完成标准


Day 11 (08-19) Embedding 生成与存储

今日任务

练习代码

from openai import OpenAI
import psycopg2
from pgvector.psycopg2 import register_vector

client = OpenAI()

# 生成 Embedding
def get_embedding(text):
    response = client.embeddings.create(
        model="text-embedding-3-small",
        input=text
    )
    return response.data[0].embedding

# 批量处理
texts = ["文档片段1", "文档片段2", "文档片段3"]
embeddings = [get_embedding(t) for t in texts]

# 存入数据库
conn = psycopg2.connect(...)
register_vector(conn)
cur = conn.cursor()

for text, emb in zip(texts, embeddings):
    cur.execute(
        "INSERT INTO documents (content, embedding) VALUES (%s, %s)",
        (text, emb)
    )
conn.commit()

# 相似度查询
query = "查询内容"
query_emb = get_embedding(query)
cur.execute("""
    SELECT content, embedding <=> %s as distance 
    FROM documents 
    ORDER BY distance 
    LIMIT 5
""", (query_emb,))

完成标准


Day 12 (08-20) 混合检索实现

今日任务

学习资料

练习代码

# BM25 使用 rank_bm25 库
pip install rank_bm25

from rank_bm25 import BM25Okapi
import numpy as np

# BM25 检索
corpus = ["文档1内容", "文档2内容", ...]
bm25 = BM25Okapi(corpus)
bm25_scores = bm25.get_scores("查询词")
bm25_top_k = np.argsort(bm25_scores)[::-1][:5]

# 语义检索(向量相似度)
# ... 得到 semantic_top_k

# RRF 融合
def reciprocal_rank_fusion(rankings, k=60):
    scores = {}
    for ranking in rankings:
        for rank, doc_id in enumerate(ranking):
            if doc_id not in scores:
                scores[doc_id] = 0
            scores[doc_id] += 1 / (k + rank + 1)
    return sorted(scores.items(), key=lambda x: x[1], reverse=True)

# 融合 BM25 和语义检索结果
final_ranking = reciprocal_rank_fusion([bm25_top_k, semantic_top_k])

完成标准


Day 13 (08-21) Rerank 集成

今日任务

学习资料

操作步骤

# 下载模型(或使用 API)
pip install FlagEmbedding
from FlagEmbedding import FlagReranker

reranker = FlagReranker('BAAI/bge-reranker-v2-m3', use_fp16=True)

# 对检索结果重排
query = "查询内容"
candidates = ["候选文档1", "候选文档2", "候选文档3"]

pairs = [[query, doc] for doc in candidates]
scores = reranker.compute_score(pairs)

# 按分数排序
ranked = sorted(zip(candidates, scores), key=lambda x: x[1], reverse=True)

完成标准


Day 14 (08-22) Java 生态映射

今日任务

学习资料

练习代码(Java)

// pom.xml 添加依赖
// <dependency>dev.langchain4j:langchain4j:0.x</dependency>

// 简单示例
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.rag.DefaultRetrievalAugmentor;

var model = OpenAiChatModel.builder()
    .apiKey("xxx")
    .modelName("gpt-4o")
    .build();

// ... 实现 RAG 流程

完成标准


第二周总结检查点


第三周:Agent 智能体与 LangGraph

Day 15 (08-23) Tool Calling 基础

今日任务

学习资料

练习代码

import json
from openai import OpenAI

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的天气",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名"}
                },
                "required": ["city"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "北京今天天气怎么样?"}],
    tools=tools
)

# 解析工具调用
message = response.choices[0].message
if message.tool_calls:
    tool_call = message.tool_calls[0]
    args = json.loads(tool_call.function.arguments)
    print(f"调用工具: {tool_call.function.name}, 参数: {args}")

完成标准


Day 16 (08-24) Tool Calling 实战

今日任务

练习代码

# 定义工具
def execute_sql(query: str) -> list:
    """执行 SQL 查询并返回结果"""
    # 实际实现...
    return [{"id": 1, "name": "test"}]

# 完整循环
messages = [{"role": "user", "content": "查询用户表中年龄大于30的人"}]

while True:
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages,
        tools=[...],
        tool_choice="auto"
    )
    
    message = response.choices[0].message
    
    if message.tool_calls:
        # 执行工具
        for tool_call in message.tool_calls:
            args = json.loads(tool_call.function.arguments)
            if tool_call.function.name == "execute_sql":
                result = execute_sql(args["query"])
                # 添加工具结果到消息
                messages.append(message)
                messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "content": json.dumps(result)
                })
    else:
        # 没有工具调用,输出最终回复
        print(message.content)
        break

完成标准


Day 17 (08-25) LangGraph 入门

今日任务

学习资料

练习代码

from langgraph.graph import StateGraph, START, END
from typing import TypedDict

# 定义状态
class State(TypedDict):
    input: str
    output: str
    step: str

# 定义节点
def process_node(state: State) -> State:
    result = f"处理: {state['input']}"
    return {"output": result, "step": "processed"}

# 构建图
graph = StateGraph(State)
graph.add_node("process", process_node)
graph.add_edge(START, "process")
graph.add_edge("process", END)

# 编译并运行
app = graph.compile()
result = app.invoke({"input": "hello", "output": "", "step": ""})
print(result)

完成标准


Day 18 (08-26) LangGraph 进阶

今日任务

练习代码

from langgraph.graph import StateGraph, START, END
from typing import TypedDict, Literal

class State(TypedDict):
    count: int
    result: str

def increment(state: State) -> State:
    return {"count": state["count"] + 1}

def should_continue(state: State) -> Literal["continue", "finish"]:
    if state["count"] < 5:
        return "continue"
    return "finish"

# 条件边
graph = StateGraph(State)
graph.add_node("increment", increment)
graph.add_edge(START, "increment")
graph.add_conditional_edges(
    "increment",
    should_continue,
    {"continue": "increment", "finish": END}
)

app = graph.compile()
result = app.invoke({"count": 0, "result": ""})
print(result)  # count 应该是 5

完成标准


Day 19 (08-27) Agent 自我纠错

今日任务

练习代码

class AgentState(TypedDict):
    query: str
    sql: str
    validation_error: str
    retry_count: int

def generate_sql(state: AgentState) -> AgentState:
    # 让 LLM 生成 SQL
    ...
    return {"sql": sql}

def validate_sql(state: AgentState) -> AgentState:
    # 验证 SQL 语法
    if not is_valid_sql(state["sql"]):
        return {"validation_error": "SQL 语法错误"}
    return {"validation_error": ""}

def should_retry(state: AgentState) -> Literal["retry", "done"]:
    if state["validation_error"] and state["retry_count"] < 3:
        return "retry"
    return "done"

# 构建带纠错的图
graph = StateGraph(AgentState)
graph.add_node("generate", generate_sql)
graph.add_node("validate", validate_sql)
graph.add_edge(START, "generate")
graph.add_edge("generate", "validate")
graph.add_conditional_edges("validate", should_retry, {"retry": "generate", "done": END})

完成标准


Day 20 (08-28) MCP 协议入门

今日任务

学习资料

完成标准


Day 21 (08-29) MCP 服务封装

今日任务

学习资料

练习代码

# server.py
from mcp.server import Server
from mcp.types import Tool

server = Server("my-tools")

@server.tool("calculate")
async def calculate(expression: str) -> float:
    """计算数学表达式"""
    return eval(expression)

# 运行服务器
# python server.py

完成标准


第三周总结检查点


第四周:综合项目实战与部署

Day 22 (08-30) 项目架构设计

今日任务

项目需求
智能 SQL 查询与报表生成 Agent:

  1. 用户输入自然语言问题
  2. Agent 解析数据库 Schema
  3. 生成并校验 SQL
  4. 执行 SQL 并获取结果
  5. 生成可视化图表

产出


Day 23 (08-31) SQL 生成模块

今日任务

完成标准


Day 24 (09-01) SQL 校验与执行

今日任务

完成标准


Day 25 (09-02) 图表生成

今日任务

完成标准


Day 26 (09-03) Agent 整合

今日任务

完成标准


Day 27 (09-04) 评估体系搭建

今日任务

学习资料

完成标准


Day 28 (09-05) 评估与调优

今日任务

完成标准


Day 29 (09-06) FastAPI 封装与部署

今日任务

完成标准


Day 30 (09-07) Java 对接与总结

今日任务

完成标准


进度

  • 已完成: 9/30
  • 当前连续: 9 天
  • 当前周: 第二周

每日学习时间建议

  • 工作日:2-3 小时/天
  • 周末:3-4 小时/天

关键资源汇总

文档

视频

  • B站搜索:Python 异步编程、FastAPI 入门、LangChain 教程

书籍(可选)

  • 《Python Cookbook》
  • 《LangChain 实战》

笔记

学习过程中的想法、问题、收获

posted @ 2026-08-08 21:53  Abserver  阅读(10)  评论(0)    收藏  举报