☰
LLM Prompting Playground:在 CS146S 项目中用 Ollama 实战六种核心 Prompting 技术
2026/9/30 15:34:49 网站建设 项目流程
  • 示例工程

【免费下载链接】modern-software-dev-assignments

Assignments for CS146S: The Modern Software Dev (Stanford University Fall 2026/2025)

项目地址:https://gitcode.com/GitHub_Trending/mo/modern-software-dev-assignments
点击查看免费下载

CS146S(Stanford《The Modern Software Developer》)第一周作业要求通过本地 Ollama 运行的开源 LLM,亲手实践 K-shot、Chain-of-Thought、Tool Calling、Self-Consistency、RAG 与 Reflexion 六种提示技术。本文以 week1/assignment.md 为骨架,结合仓库中六个可直接运行的 Python 测试脚本,完整讲解环境搭建、每种技术的任务设定、源码测试逻辑与提示词撰写要点,帮助你迭代出能通过脚本校验的最终提示词。

课程背景与本周目标

这是 CS146S 系列作业的第一周:LLM Prompting Playground。仓库根目录的 README.md 说明项目依赖 Python 3.12,而 week1/README.md 明确指出本练习的核心是 "Practice core LLM prompting techniques essential to using and understanding coding LLMs"——即通过设计提示词来理解和使用编码类 LLM。

完整的任务说明位于 week1/assignment.md,其核心要求只有三条:

  1. 阅读每个源文件顶部的任务描述;
  2. 只修改代码中标有TODO的位置(即编写你的提示词),不要改动模型本身;
  3. 反复迭代直到测试脚本通过,并保存最终的提示词与输出。

这种"脚手架式"设计意味着:框架、评测逻辑、模型参数全部由仓库提供,你要挑战的只有提示词工程本身。

环境搭建:Conda + Poetry + Ollama

1. 创建 Python 3.12 环境并安装依赖

按照顶层 README.md 的 Repo Setup 部分操作:

conda create -n cs146s python=3.12 -y conda activate cs146s curl -sSL https://install.python-poetry.org | python - poetry install --no-interaction

Poetry 会在激活的 Conda 环境内按 pyproject.toml 安装项目依赖(包括ollamaPython 客户端与python-dotenv,这两个库在六个练习文件中被直接 import)。

2. 安装并启动 Ollama

Ollama 用于在本地运行不同规格的 SOTA 开源 LLM。按 week1/assignment.md 的 Installation 一节,不同平台安装方式如下:

  • macOS(Homebrew):
    brew install --cask ollama ollama serve
  • Linux(推荐):
    curl -fsSL https://ollama.com/install.sh | sh
  • Windows:从 ollama.com/download 下载并运行安装程序。

安装后用ollama -v验证版本。

3. 拉取所需模型(只需一次)

运行测试脚本前,必须预先拉取两个模型:

ollama run mistral-nemo:12b ollama run llama3.1:8b

两个模型在六个练习中分工明确:mistral-nemo:12b用于 K-shot 练习,llama3.1:8b用于其余五种技术。如果本地机器性能有限,这决定了单次推理的耗时,也提醒我们测试脚本都会执行多轮(NUM_RUNS_TIMES次)以保证结果统计意义。

六种提示技术的源码级拆解

下面按 week1/assignment.md 的 Techniques and source files 列表逐一展开,每小节先交代任务,再结合源码说明测试逻辑与提示词设计要点。

K-shot Prompting ——week1/k_shot_prompting.py

任务:让模型只输出反转字母顺序后的单词,输入词是httpstatus,期望输出sutatsptth。

测试逻辑(week1/k_shot_prompting.py):

  • 使用mistral-nemo:12b,temperature=0.5,共运行NUM_RUNS_TIMES = 5次;
  • 只要任意一次输出与EXPECTED_OUTPUT完全一致即判定SUCCESS;
  • 每次运行都打印实际输出与期望输出,便于你观察模型失误模式。

提示词要点:你的YOUR_SYSTEM_PROMPT(第 10 行的 TODO)应当包含若干"输入→输出"示例对(few-shot 示例),让模型从示例中习得"仅输出反转结果、不加任何解释"的格式约束。示例应覆盖大小写处理与"只输出单词本身"的规则;由于有 5 次机会且温度 0.5,格式约束越严格,命中率越高。注意用户提示词固定为 week1/k_shot_prompting.py 中内容,不能修改。

Chain-of-Thought(思维链)——week1/chain_of_thought.py

任务:求解模幂问题3^{12345} (mod 100),要求最后一行输出Answer: 43。

测试逻辑(week1/chain_of_thought.py):

  • 使用llama3.1:8b,temperature=0.3,运行 5 次;
  • 关键在extract_final_answer()(第 25-40 行):用正则(?mi)^\s*answer\s*:\s*(.+)\s*$找出最后一行Answer:开头的文本,并把其中的数字规整为Answer: <number>形式后再与期望值比对。

提示词要点:由于用户提示词已要求"先解题、最后一行输出 Answer",你的 system prompt 应鼓励模型逐步推理("think step by step"),同时明确约束最后一行必须是Answer: <数字>。注意正则取的是最后一条匹配,任何推理过程中出现的Answer:前缀行都会被忽略——这是设计的容错点,你的提示词不必担心推理过程中的中间标注。模运算类题目对纯数值模型容易出错,CoT 提示正是为了让模型先展开运算再收敛答案。

Tool Calling(工具调用)——week1/tool_calling.py

任务:让模型以结构化 JSON 的形式调用工具output_every_func_return_type,该工具会扫描本文件内所有顶层函数并返回"函数名: 返回类型"列表,期望输出与实际扫描结果完全一致。

测试逻辑(week1/tool_calling.py):

  • 使用llama3.1:8b,temperature=0.3,运行 3 次;
  • extract_tool_call()(第 87-100 行)从模型输出中解析 JSON 对象(兼容 ```json 代码块包裹);execute_tool_call()(第 115-133 行)按tool名查TOOL_REGISTRY并传入args执行;
  • 期望值由compute_expected_output()直接调用工具本体生成,是"真值"——不是字符串比对,而是工具执行结果的逐字比较。

提示词要点:你的YOUR_SYSTEM_PROMPT必须让模型学会输出形如{"tool": "output_every_func_return_type", "args": {"file_path": "..."}}的 JSON 调用。重点是教会模型:

  • 工具的名称与参数签名(file_path可省略,缺省时指向本文件);
  • 输出必须是单个合法 JSON 对象,且args必须是对象类型(execute_tool_call第 122-124 行对此做了强校验);
  • 不要在 JSON 外夹杂解释文本,否则会触发extract_tool_call的解析失败分支。

同时可阅读 week1/tool_calling.py 中add、greet两个示例函数——它们是本文件内被扫描的对象,提示词中也可以提到"列出文件中所有函数返回类型"这类任务语义。

Self-Consistency Prompting(自一致性)——week1/self_consistency_prompting.py

任务:解一道行程文字题(60 英里骑行、两次停靠,求两次停靠间距离),期望Answer: 25。

测试逻辑(week1/self_consistency_prompting.py):

  • 使用llama3.1:8b,temperature=1(故意调高以产生多样化的推理路径),运行 5 次;
  • 每次用extract_final_answer()提取Answer: <数字>,收集 5 个答案后用collections.Counter做多数投票(counts.most_common(1)[0]);
  • 只有当多数答案等于期望输出才算SUCCESS,并打印完整答案分布供调试。

提示词要点:你的 system prompt 应(a)要求模型先逐步推理、最后一行给出Answer: <数字>;(b)明确"多次独立求解、选择最一致的结果"的自一致性语义。高温度 + 多次采样 + 多数投票正是 Self-Consistency 的核心思想:单次可能出错,但多数一致答案更可信。注意:若 5 次全部失败,脚本会打印每个答案的票数,你可以据此判断模型是系统性误解(多数票相同但错误)还是随机失误。

RAG(检索增强生成)——week1/rag.py

任务:给定一份 API 文档语料,让模型基于文档编写fetch_user_name(user_id: str, api_key: str) -> str函数,代码中必须包含def fetch_user_name(、requests.get、/users/、X-API-Key、return五个关键片段。

测试逻辑(week1/rag.py):

  • 语料从 week1/data/api_docs.txt 加载(Base URL、X-API-Key鉴权头、GET /users/{id}端点、返回 JSON 结构均在此文档中);
  • 使用llama3.1:8b,temperature=0.0,运行 5 次;extract_code_block()提取最后一个 Python 代码块后,逐条检查五个REQUIRED_SNIPPETS是否出现,缺一即失败;
  • 关键钩子在YOUR_CONTEXT_PROVIDER(第 54-59 行,TODO):你的检索策略决定了上下文质量——返回[]模拟"无上下文",返回[corpus[0]]则注入完整 API 文档;
  • make_user_prompt()(第 62-76 行)会把上下文拼进用户消息,并注明 "Context (use ONLY this information)",即约束模型只能依据给定文档作答。

提示词要点:这是"检索"与"生成"双环节任务。你需要在YOUR_CONTEXT_PROVIDER中实现简单选择(如按关键词user命中相关文档),并在YOUR_SYSTEM_PROMPT中强调:严格使用上下文中给出的 Base URL、鉴权头与端点格式;非 200 响应要raise;函数只返回name字符串;输出为单个 Python 代码块。由于校验是片段级而非精确匹配,提示词的核心目标是保证五个必需片段全部出现在最终代码里。

Reflexion(反思强化)——week1/reflexion.py

任务:首先生成is_valid_password(password: str) -> bool函数,再用"反思"环节基于失败用例改进代码,直到通过 4 条密码校验用例(如Password1!合法、缺大写/缺数字/缺特殊字符均不合法)。

测试逻辑(week1/reflexion.py):

  • 使用llama3.1:8b,temperature=0.2,NUM_RUNS_TIMES = 1(本脚本只做一轮生成 + 一轮反思);
  • evaluate_function()(第 50-79 行)用TEST_CASES逐一执行生成代码,失败时自动生成诊断(缺大写/缺数字/缺特殊字符等),这构成了反思的"反馈信号";
  • your_build_reflexion_context()(第 94-99 行,TODO)需要把上一版代码 + 失败诊断拼成反思阶段的用户消息;
  • SYSTEM_PROMPT已内置(第 11-15 行)无需改动;你的 TODO 是YOUR_REFLEXION_PROMPT与your_build_reflexion_context。

提示词要点:Reflexion 的核心是"利用失败信息自我修正"。你的YOUR_REFLEXION_PROMPT应指示模型:阅读上一版实现与具体失败用例,分析漏掉了哪条校验规则(如未检查特殊字符!@#$%^&*()-_集合),重写一个完整覆盖所有规则的最小实现;your_build_reflexion_context则应把失败诊断逐条格式化后交给模型。注意load_function_from_code用exec动态加载生成代码,因此提示词要约束模型"只输出一个可独立运行的 Python 代码块,定义is_valid_password函数"。

交付物与评分规则

按 week1/assignment.md 的 Deliverables 与 Evaluation rubric:

  • 交付物:每个技术文件中的TODO全部解决;保存每个技术的最终提示词与运行输出;提交包含六个文件的完整代码,并逐项核对所有TODO均已填充。
  • 评分:总分 60 分,六个技术各 10 分,对应 week1/README.md 中 "LLM Prompting Playground" 的六个练习文件。也就是说,每个文件脚本打印SUCCESS即获得该技术的满分。

迭代方法论与常见坑

从六个脚本的源码可以总结出一套通用迭代流程:

  1. 先跑基线:TODO 留空(如YOUR_SYSTEM_PROMPT = "")直接运行脚本,观察模型"零提示"下的行为与失败输出格式;
  2. 定位评测规则:先读懂测试函数——是精确字符串比对(K-shot、Tool Calling)、正则抽取后比对(CoT、Self-Consistency)、片段包含校验(RAG)还是执行用例校验(Reflexion),据此设计提示词的输出格式约束;
  3. 单变量迭代:一次只改一个约束(如先加格式约束、再加示例、再调温度无关的措辞),因为模型与NUM_RUNS_TIMES、温度等参数均不可改;
  4. 利用失败打印:各脚本都会打印期望输出与实际输出(或缺失片段、答案分布、失败诊断),这是最直接的调试信号;
  5. 区分"格式失败"与"能力失败":RAG 缺X-API-Key多半是上下文没注入或提示词没强调鉴权头;CoT 答案不对则是推理质量问题,应强化"逐步运算"的引导。

需要特别提醒的是,所有提示词都必须放入**系统消息(system prompt)**位置——六个脚本调用chat()时都将system_prompt作为messages[0],用户消息由脚本固定拼接。若你把提示词写进 TODO 之外的任何代码位置,都会破坏评测口径。

小结

CS146S 第一周通过一个"只改提示词"的受控环境,把六种最重要的 LLM 应用技术浓缩为六个可重复、可评分、可调试的练习:K-shot 教你用示例约束输出格式,CoT 教你引导推理过程,Tool Calling 教你让模型产出可执行的工具调用 JSON,Self-Consistency 教你用多次采样 + 多数投票提升可靠性,RAG 教你检索与生成的协同,Reflexion 教你用失败反馈自我修正。从 week1/assignment.md 出发、配合六个源文件与 week1/data/api_docs.txt,你可以在完全离线、免费的本地环境中,系统掌握理解与使用编码 LLM 的核心提示工程能力。

  • 示例工程

【免费下载链接】modern-software-dev-assignments

Assignments for CS146S: The Modern Software Dev (Stanford University Fall 2026/2025)

项目地址:https://gitcode.com/GitHub_Trending/mo/modern-software-dev-assignments
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询