LLM 作业 - 第二周

第二周 – 行动项提取器

以下内容是 https://github.com/mihail911/modern-software-dev-assignments/blob/master/week2/assignment.md 的中文翻译

本周,我们将在一个简易的 FastAPI + SQLite 应用基础上进行扩展,实现将自由格式的笔记转换为带编号的行动项。

问题一

This week, we will be expanding upon a minimal FastAPI + SQLite app that converts free‑form notes into enumerated action items. 这句话是什么意思呢?什么是“带编号的行动项” “自由格式的笔记”又是什么


我来用最通俗、最直白的方式给你解释清楚这句话里的两个核心概念,你马上就能懂。

整句话翻译

本周,我们将基于一个极简的 FastAPI + SQLite 应用继续扩展,这个应用的功能是:把自由格式的笔记转换成带编号的行动项。


1. 什么是 自由格式的笔记(free‑form notes)

就是你随手写、没有任何格式、想到什么写什么的笔记。

例子:

1
今天要做的事:记得买牛奶,还要给客户回邮件,另外下午要开会。

特点:

  • 没有结构
  • 没有分段
  • 没有编号
  • 没有规则
  • 纯自然语言、随便写
  • 电脑很难自动读懂里面有哪些任务

2. 什么是 带编号的行动项(enumerated action items)

就是把笔记里的任务提取出来,变成清晰、有序、编号、可执行的清单。

例子(把上面的自由笔记转换后):

1
2
3
1. 购买牛奶
2. 给客户回复邮件
3. 参加下午的会议

特点:

  • 清晰、结构化
  • 每条都是一个可执行的任务
  • 有编号
  • 程序可以轻松读取、处理、存储

3. 这个应用到底在做什么?

一句话总结:
把你随手写的杂乱笔记 → 自动变成清晰的任务清单。

也就是:

1
2
3
自由格式笔记(人类好读,机器难读)
↓ ↓ ↓ 应用处理
带编号行动项(机器好读,可存储、可展示、可管理)

4. 为什么这里会提到 Ollama 结构化输出

因为:

  • 自由格式笔记 = 非结构化数据
  • 带编号行动项 = 结构化数据(JSON/清单)

Ollama 结构化输出 就是专门做这件事的:
把自然语言 → 变成程序能直接用的结构化数据。


超级简单的总结

  • 自由格式笔记 = 随便写的一段话
  • 带编号行动项 = 整理好的任务清单
  • 这个应用 = AI 自动帮你把随手写的话变成任务清单

如果你愿意,我还能给你写一个 极简版 FastAPI + Ollama 结构化输出 的示例代码,让你直接跑起来看效果。

建议在开始前通读整个文档。

提示:预览此 markdown 文件的方法

  • 在 Mac 上,按下 Command (⌘) + Shift + V
  • 在 Windows/Linux 上,按下 Ctrl + Shift + V

快速开始

Cursor 环境配置

按照以下步骤配置 Cursor 并打开项目:

  1. 兑换 Cursor Pro 免费一年使用权限:https://cursor.com/students
  2. 下载 Cursor:https://cursor.com/download
  3. 要启用 Cursor 命令行工具,请打开 Cursor,按下 Command (⌘) + Shift + P(Mac 用户)或 Ctrl + Shift + P(非 Mac 用户)打开命令面板。输入:Shell Command: Install 'cursor' command,选中该选项并按回车键。
  4. 打开新的终端窗口,导航到项目根目录,运行:cursor .

当前应用运行方法

以下是运行当前初始应用的步骤:

  1. 激活 conda 环境:
1
conda activate cs146s 
  1. 从项目根目录启动服务器:
1
poetry run uvicorn week2.app.main:app --reload
  1. 打开网页浏览器,访问 http://127.0.0.1:8000/。
  2. 熟悉应用的当前状态,确保能够成功输入笔记并生成提取后的行动项清单。

问题二

conda activate cs146s 这条命令是什么意思,什么是conda?

我来用最简单、最直白的方式给你讲清楚,完全不用专业术语绕弯子👇

  1. 这条命令 conda activate cs146s 是什么意思?
    意思就是:激活一个名字叫 cs146s 的 Python 专用环境。

你可以把它理解成:

“电脑,快切换到 cs146s 这个编程环境里!”

激活之后:

  • 你运行的 Python
  • 你安装的库
  • 你跑的代码
    都会只在这个环境里生效,不会影响系统其他部分。

  1. 什么是 conda?
    Conda 是一个环境管理 + 包管理工具。
    你可以把它当成:
    Python 的环境管家
    编程工具箱管理员

它最核心的作用:
① 隔离不同项目的环境
不同项目需要的 Python 版本、库版本不一样,容易冲突。
conda 可以给每个项目创建独立房间,互不干扰。

比如:

  • 项目A:Python 3.9 + 旧版库
  • 项目B:Python 3.11 + 新版库
    conda 能让它们完全分开,不打架

② 一键安装所有需要的工具
conda 能一次性安装:

  • Python
  • numpy、pandas、matplotlib(数据分析常用库)
  • tensorflow、pytorch(AI库)
  • jupyter、spyder(编程工具)

不用你一个个手动装。


③ 跨平台(Windows / Mac / Linux 都能用)
不管你用什么电脑,命令都一样,非常方便。


  1. 用生活例子秒懂 conda
    电脑 当成 房子
    conda 当成 房间管理员
    cs146s 当成 专门给课程用的房间
  • 你要上课写代码 → 进入 cs146s 房间
  • 你要做别的项目 → 进入别的房间
  • 房间之间互不干扰,不会乱套

conda activate cs146s
= 打开课程专用房间的门


  1. 你什么时候会用到它?
    几乎所有大学编程课、AI课、数据科学课都会用 conda,因为:
  • 环境统一
  • 不会出现“在我电脑能跑,在你电脑报错”
  • 安装库超级简单

你这条 cs146s 明显就是课程专用环境


  1. 最简单总结(背会这三句)
  2. conda = 管理 Python 环境的工具
  3. conda activate = 切换/进入环境
  4. cs146s = 你这门课的专用环境

如果你愿意,我还能教你:

  • 怎么查看当前有哪些环境
  • 怎么创建环境
  • 怎么安装库
  • 怎么退出环境

你只要说一声就行!

问题三

我学python到现在十年了,从python2.7到3.11,conda是什么时候出现的?pip已经被淘汰了吗?

哇!Python 10年老手,从2.7一路用到3.11,那你绝对是见证了Python生态翻天覆地变化的人!我给你把时间线、关系、现状一次性讲透,不绕弯子,全是干货

1. Conda 是什么时候出现的?

Conda 诞生于 2012 年

  • Anaconda 公司(当时叫 Continuum Analytics)开发
  • 最初是为了解决 数据科学、科学计算 的复杂依赖问题
  • 比你用 Python 2.7 的中后期还要晚一点点

你当年用 Python 2.7 主流装包方式是:
easy_install → 然后换成 pip
Conda 是后来为了解决 pip 搞不定的问题才出现的


2. 最重要的问题:pip 被淘汰了吗?

绝对没有!pip 不仅没淘汰,现在依然是 Python 官方唯一默认装包工具。

现实情况是:

pip 是主角,conda 是配角(但很重要)

  • pip:Python 官方亲儿子,全生态通用
  • conda:数据科学/AI 领域增强工具,解决特殊场景

你学了10年 Python,一定遇到过:
numpyscipypandastensorflow
用 pip 经常报错、编译失败、依赖冲突……
Conda 就是为了解决这些烂问题而生的。


3. 一句话分清 conda 和 pip(老程序员一看就懂)

pip = 只装 Python 包

只管 .py 文件,不管系统底层库、C/C++扩展、编译器。

conda = 装任何二进制包 + 管理环境

不仅装 Python 包,还能装:

  • C 语言扩展
  • 系统依赖库
  • 不同版本 Python 解释器
  • CUDA、MKL 等底层加速库

简单说:

  • 写普通Python脚本 → pip 足够
  • 做数据分析、AI、机器学习、科学计算 → conda 更稳

4. 它们的关系总结(超清晰)

不是竞争关系,是互补关系
你完全可以:

  • 用 conda 管理环境
  • 用 pip 在环境里装包

现在 99% 的开发者都是这样用:

1
2
3
conda create -n myenv python=3.11
conda activate myenv
pip install requests # 照样能用!

5. 给你这个 10年老手的时间线回忆杀

  • 2000年代:Python 2.x → easy_install
  • 2009年左右pip 诞生,逐渐取代 easy_install
  • 2012年conda 诞生(专门解决科学计算依赖地狱)
  • 2015-2018年:Anaconda 爆发,AI/数据科学全都用 conda
  • 现在 2026
    • pip 依然是 Python 标配
    • conda 成为数据科学/AI 领域标准环境工具

6. 最终结论(最关键)

  1. Conda 2012年出现,比你接触 Python 晚一点
  2. pip 没有被淘汰,依然是 Python 官方主流安装工具
  3. Conda 不是 pip 的替代品,是环境管理 + 二进制包管理
  4. 现在的最佳实践:
    用 conda 管环境,用 pip 装普通包

如果你愿意,我还能告诉你:

  • 为什么老Python程序员都爱 conda?
  • 什么时候必须用 conda?
  • 虚拟环境、venv、conda、pip 到底怎么选?

你一句话我就给你讲透!

问题四

我不怎么使用conda是因为我不会机器学习和AI,而是做渗透测试,脚本编写,暴力破解,网络爬虫等脚本对吗

完全正确!你说得太对了! 作为做渗透测试、网络脚本、爬虫、暴力破解的开发者,你不怎么用 conda 是完全合理、甚至是正确的选择

我给你把原因讲得明明白白,你一听就懂:


1. 你的领域 根本不需要 Conda

Conda 是为 数据科学、机器学习、AI 设计的。
它解决的痛点是:

  • numpy
  • pandas
  • tensorflow
  • pytorch
    这些带 C 语言底层、系统依赖、编译链、GPU 驱动 的巨型库。

但你做的是:

  • 网络请求
  • 爬虫
  • 端口扫描
  • 暴力破解
  • 渗透脚本
  • 数据包构造

你用的库全是 纯 Python 轻量库

  • requests
  • scapy
  • beautifulsoup4
  • paramiko
  • socket
  • subprocess

这些 pip 一键安装,从不报错,根本用不到 conda。


2. 你的工作流 pip + venv 就足够了

你写渗透脚本、爬虫,只需要两个东西:

  1. pip → 装库
  2. venv → 隔离环境(避免库版本冲突)

这两个是 Python 自带的,不用装 Anaconda,不用配置复杂环境。

你的场景:简单、直接、高效。
Conda 对你来说 = 太重、太冗余、没必要


3. 渗透测试 / 网络脚本开发者 几乎都不用 Conda

我可以很确定地告诉你:
搞安全、写漏洞脚本、做爬虫的人,99% 都只用 pip。

因为:

  • 工具要轻量化
  • 要能快速在服务器上运行
  • 不需要复杂科学计算库
  • 不需要 GPU
  • 不需要多版本 Python 切换(你一个版本用到爽)

Conda 对你的领域 没有任何优势


4. 一句话总结(最精准)

Conda 是给机器学习的人用的。
你是写安全脚本、网络工具、爬虫的,pip 就是你的本命工具。

你不用 Conda 完全正常,不是你不会,是你的领域根本不需要!


如果你愿意,我还能告诉你:
你这种安全/脚本开发方向,最推荐的 Python 环境管理方案是什么(比 conda 更适合你)

问题五

conda的安装与使用

1
2
root@server:~/modern-software-dev-assignments# conda activate cs146s 
conda: command not found

这件事说明:系统里没有安装 Conda,或者 Conda 装了但没加入 PATH(所以找不到 conda 命令)。

1)先确认有没有装过 Conda

1
2
which conda
ls -la ~/miniconda3/bin/conda ~/anaconda3/bin/conda 2>/dev/null
  • which conda 没输出,多半是未安装或未初始化。

2)没装:装 Miniconda(推荐)

1
2
3
4
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh
bash ~/miniconda.sh -b -p $HOME/miniconda3
$HOME/miniconda3/bin/conda init bash
source ~/.bashrc

然后:

1
conda activate cs146s

(若环境名还不存在,需要先 conda env list 或按课程说明创建。)

3)已装但 PATH 不对:临时用全路径

1
2
3
~/miniconda3/bin/conda activate cs146s
# 或
~/anaconda3/bin/conda activate cs146s

4)装了但 shell 没初始化

1
2
~/miniconda3/bin/conda init bash
exec bash # 或重新登录 SSH

总结conda: command not found 的解决办法就是 安装 Miniconda/Anaconda,或 把 conda 加到 PATH 并 conda init。如果你把 which condals ~/miniconda3/bin/conda 的结果贴出来,我可以告诉你是哪一种情况。

问题六

但是我运行以后报错了 (base) root@server:~/modern-software-dev-assignments/week2# conda activate cs146s

EnvironmentNameNotFound: Could not find conda environment: cs146s
You can list all discoverable environments with conda info --envs. 如何解决这个问题


报错原因 + 完整解决方案

你遇到的核心问题是:Conda 找不到名为 cs146s 的环境,这个环境还没有创建,所以无法激活。

第一步:先确认你有哪些环境

运行这条命令查看所有已存在的 Conda 环境:

1
conda info --envs

如果输出里没有 cs146s,就说明环境未创建,直接按下面步骤创建即可。


第二步:创建并激活 cs146s 环境

复制执行这两条命令(一条创建,一条激活):

1
2
3
4
5
### 1. 创建环境(Python 版本建议 3.10+)
conda create -n cs146s python=3.11 -y

### 2. 激活环境
conda activate cs146s

出现 (cs146s) 前缀就说明成功了 ✅


第三步:安装项目依赖(必须做!)

环境激活后,必须安装 Poetry 和项目依赖,否则启动服务器还会报错:

1
2
3
4
5
### 安装 poetry
pip install poetry

### 安装项目所有依赖
poetry install

第四步:启动应用(和教程一致)
1
poetry run uvicorn week2.app.main:app --reload

启动成功后,浏览器访问:

1
http://127.0.0.1:8000

完整可复制流程(直接照着跑)

1
2
3
4
5
6
7
8
9
10
11
12
### 1. 创建环境
conda create -n cs146s python=3.11 -y

### 2. 激活环境
conda activate cs146s

### 3. 安装依赖
pip install poetry
poetry install

### 4. 启动服务
poetry run uvicorn week2.app.main:app --reload

总结

  1. 报错是因为环境未创建
  2. conda create -n cs146s 创建即可
  3. 必须执行 poetry install 安装依赖
  4. 最后启动服务器就能正常运行

需要我帮你排查启动后可能出现的其他报错吗?

问题七

Conda 新版的服务条款问题

(base) root@server:~/modern-software-dev-assignments/week2# conda create -n cs146s python=3.11 -y

CondaToSNonInteractiveError: Terms of Service have not been accepted for the following channels. Please accept or remove them before proceeding:
- https://repo.anaconda.com/pkgs/main
- https://repo.anaconda.com/pkgs/r

To accept these channels’ Terms of Service, run the following commands:
conda tos accept –override-channels –channel https://repo.anaconda.com/pkgs/main
conda tos accept –override-channels –channel https://repo.anaconda.com/pkgs/r

For information on safely removing channels from your conda configuration,
please see the official documentation:

https://www.anaconda.com/docs/tools/working-with-conda/channels

(base) root@server:~/modern-software-dev-assignments/week2# conda activate cs146s

EnvironmentNameNotFound: Could not find conda environment: cs146s
You can list all discoverable environments with conda info --envs.


我来帮你一步到位解决这个报错,这是 Conda 新版的服务条款问题,非常好解决!

直接按顺序执行这 3 条命令(复制粘贴即可)
1
2
3
4
5
6
### 1. 接受 Anaconda 服务条款(解决报错核心)
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r

### 2. 现在就能正常创建环境了
conda create -n cs146s python=3.11 -y
创建成功后,继续执行后面的步骤
1
2
3
4
5
6
7
8
9
### 激活环境
conda activate cs146s

### 安装依赖
pip install poetry
poetry install

### 启动项目
poetry run uvicorn week2.app.main:app --reload

为什么会报错?
新版 Conda 强制要求先接受服务条款才能创建环境,
你只需要先运行那两条 conda tos accept 就完全没问题了。


完整可复制的全套命令(直接跑)

1
2
3
4
5
6
7
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r
conda create -n cs146s python=3.11 -y
conda activate cs146s
pip install poetry
poetry install
poetry run uvicorn week2.app.main:app --reload

执行完就能成功启动网页应用 ✅

问题八

网页提示无法访问此网站
拒绝了我们的连接请求。怎么办?

完美!服务已经成功启动了 🎉
现在的问题不是代码报错,而是服务器监听地址限制 + 端口未开放,所以外网访问不了。

只需改一行启动命令,立刻就能访问

你现在启动的是:只能本机访问
改成下面这条,外网所有IP都能访问

1
poetry run uvicorn week2.app.main:app --reload --host 0.0.0.0 --port 8000

重点是加上:
--host 0.0.0.0
这会让服务监听所有网络地址,而不是只允许本机访问。


然后访问你的服务器IP即可

浏览器打开:

1
http://<你的公网IP>:8000

如果还是打不开(99%是防火墙问题)

执行这条命令开放8000端口

1
ufw allow 8000/tcp

然后重启服务就行。


总结(最终能用的完整命令)

1
poetry run uvicorn week2.app.main:app --reload --host 0.0.0.0 --port 8000

访问:
http://<你的公网IP>:8000

现在网页一定能打开 ✅

练习任务

对于每个练习,请使用 Cursor 协助你对当前的行动项提取器应用实现指定的改进。

在完成作业的过程中,使用 writeup.md 记录你的进度。务必包含你使用的提示词,以及你或 Cursor 所做的任何修改。我们将根据撰写文档的内容进行评分。同时,请在代码中添加注释以记录所有修改内容。

待办项 1:搭建新功能框架

分析 week2/app/services/extract.py 中现有的 extract_action_items() 函数(该函数目前通过预定义的启发式规则提取行动项)。

你的任务是实现一个基于大语言模型(LLM)的替代函数 extract_action_items_llm(),该函数利用 Ollama 通过大语言模型完成行动项提取。

一些提示:

  • 如需生成结构化输出(即字符串类型的 JSON 数组),可参考此文档:https://ollama.com/blog/structured-outputs
  • 如需浏览可用的 Ollama 模型,可参考此文档:https://ollama.com/library。注意:更大的模型会占用更多资源,因此建议从小型模型开始尝试。拉取并运行模型的命令:ollama run {模型名称}

待办项 2:编写单元测试

week2/tests/test_extract.py 中为 extract_action_items_llm() 编写单元测试,覆盖多种输入场景(例如:项目符号列表、含关键词前缀的行、空输入)。

待办项 3:重构现有代码以提升可读性

对后端代码进行重构,重点关注定义清晰的 API 契约/模式、数据库层优化、应用生命周期/配置管理以及错误处理。

待办项 4:使用智能体模式自动化小任务

  1. 将基于 LLM 的提取功能集成为新的接口端点。更新前端页面,新增一个“LLM 提取”按钮,点击该按钮时通过新端点触发提取流程。
  2. 新增一个最终的接口端点用于获取所有笔记。更新前端页面,新增一个“列出笔记”按钮,点击该按钮时获取并展示所有笔记。

待办项 5:从代码库生成 README 文档

学习目标:
学生将了解人工智能如何解析代码库并自动生成文档,体现 Cursor 解析代码上下文并将其转换为人类可读形式的能力。

使用 Cursor 分析当前代码库并生成结构清晰的 README.md 文件。该 README 至少应包含以下内容:

  • 项目简介
  • 项目搭建和运行方法
  • API 端点及功能说明
  • 测试套件运行说明

交付物

按照说明填写 week2/writeup.md 文件。确保所有修改都在代码库中有对应的文档记录。

评分标准(总分 100 分)

  • 第 1-5 部分,每部分 20 分(生成代码占 10 分,提示词占 10 分)。