Week 4:AI / LLM 基础认知
🎯 本周目标:搞懂 AI Agent 到底是什么,动手调用一次 LLM API,实现最简单的 Function Calling。
1. 核心概念速查
别被名词吓到!用你熟悉的前端类比来理解:
| 概念 | 一句话解释 | 前端类比 |
|---|---|---|
| LLM(大语言模型) | 一个超级会说话但啥也不会干的"嘴强王者" | 只会写 HTML 不会调 API 的前端 intern |
| Prompt Engineering | 怎么跟 LLM 说话让它更聪明 | 给 intern 写好 README 和 checklist |
| Function Calling / Tool Use | 让 LLM 调用你写的 Python 函数 | 给 intern 一个按钮,点了触发你的 API |
| RAG(检索增强生成) | 给 LLM 外挂一个"外挂硬盘",不让它瞎编 | 给 intern 一套公司知识库 |
| Agent | LLM + 能调用工具 + 有记忆 + 有决策能力 | 能独立完成任务的初级工程师 |
| Memory | Agent 的记忆(短期/长期) | sessionStorage / localStorage |
| Vector Database | 存"语义相似度"的数据库 | npm 包搜索(按功能而非名字) |
| LangChain / LangGraph | 帮你搭建 Agent 的脚手架 | Next.js / Nuxt 之于 React/Vue |
Agent 和普通 LLM 对话的区别
graph LR
A[用户输入] --> B{有工具可用?}
B -->|No| C[LLM 直接回答]
B -->|Yes| D[LLM 决定要不要调工具]
D --> E[调用 Python 函数]
E --> F[拿到结果]
F --> G[LLM 整合结果后回答]
简单对话:你问 "今天天气?",LLM 瞎编一个。 Agent 模式:你问 "今天北京天气?",Agent 自动调用
get_weather("北京")函数,拿到真实数据后再回答。
2. 动手:调用一次 LLM API
Step 1:选一个 LLM API 提供商
推荐国内用户用 硅基流动(SiliconFlow) 或 深度求索(Deepseek),注册就能拿免费 token。
| 提供商 | 免费额度 | 速度 | 适合场景 |
|---|---|---|---|
| 硅基流动 SiliconFlow | 每天 500K token | 快 | 通用开发 |
| Deepseek | 每月 200 元额度 | 快 | 中文 Agent |
| OpenAI | 无免费额度 | 需翻墙 | 英文最佳 |
| 阿里云百炼 | 免费额度 | 快 | 国内合规 |
Step 2:安装 httpx
.venv\Scripts\python -m pip install httpx
Step 3:写你的第一个 LLM 调用
# app/llm/basic_call.py
import httpx
import json
from pathlib import Path
# 从 .env 读取 API Key(推荐用 python-dotenv)
API_KEY = "your-api-key-here" # 或者读 .env
BASE_URL = "https://api.siliconflow.cn/v1" # 硅基流动示例
async def call_llm(prompt: str, model: str = "Qwen/Qwen2.5-7B-Instruct") -> str:
"""最简单的 LLM 调用"""
async with httpx.AsyncClient(timeout=30) as client:
resp = await client.post(
f"{BASE_URL}/chat/completions",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"model": model,
"messages": [
{"role": "system", "content": "你是一个专业的交易助手。"},
{"role": "user", "content": prompt},
],
"temperature": 0.7, # 0-2,越大越发散
},
)
resp.raise_for_status()
data = resp.json()
return data["choices"][0]["message"]["content"]
# 测试
async def main():
result = await call_llm("帮我分析一下今天的交易策略")
print(result)
if __name__ == "__main__":
import asyncio
asyncio.run(main())
TS 对照
// TypeScript / Node.js 版本
import axios from 'axios';
async function callLLM(prompt: string): Promise<string> {
const resp = await axios.post(
`${BASE_URL}/chat/completions`,
{
model: "Qwen/Qwen2.5-7B-Instruct",
messages: [
{ role: "system", content: "你是一个专业的交易助手。" },
{ role: "user", content: prompt },
],
temperature: 0.7,
},
{
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
}
);
return resp.data.choices[0].message.content;
}
💡 一模一样,只是把
axios换成httpx,resp.data换成resp.json()。
3. Function Calling(让 LLM 调用你的 Python 函数)
这是 Agent 的核心能力。你告诉 LLM:"你可以调用这些函数来获取真实信息",然后 LLM 会决定什么时候调、调哪个。
原理
你:给 LLM 一份函数列表(函数名、参数、描述)
LLM:判断用户意图 → 决定要不要调用 → 返回函数名+参数
你:拿到 LLM 的函数调用请求 → 执行真实的 Python 函数 → 把结果喂回 LLM
LLM:整合结果 → 给用户最终回答
实现
# app/llm/function_calling.py
import httpx
import json
from typing import Any
API_KEY = "your-api-key-here"
BASE_URL = "https://api.siliconflow.cn/v1"
# ===== 第一步:定义你的 Python 函数 =====
def get_stock_price(symbol: str) -> dict:
"""获取股票/加密货币的当前价格(Mock)"""
mock_prices = {"BTC": 99999.99, "ETH": 3500.0, "AAPL": 210.5}
return {"symbol": symbol, "price": mock_prices.get(symbol.upper(), 0), "currency": "USD"}
def place_order(symbol: str, side: str, quantity: int) -> dict:
"""下单交易(Mock)"""
return {
"order_id": "ORD12345",
"symbol": symbol,
"side": side,
"quantity": quantity,
"status": "pending",
}
# ===== 第二步:把函数注册成 LLM 能理解的 schema =====
TOOLS = [
{
"type": "function",
"function": {
"name": "get_stock_price",
"description": "获取股票或加密货币的当前价格",
"parameters": {
"type": "object",
"properties": {
"symbol": {"type": "string", "description": "交易标的代码,如 BTC, ETH, AAPL"},
},
"required": ["symbol"],
},
},
},
{
"type": "function",
"function": {
"name": "place_order",
"description": "下单买入或卖出",
"parameters": {
"type": "object",
"properties": {
"symbol": {"type": "string", "description": "交易标的代码"},
"side": {"type": "string", "enum": ["buy", "sell"], "description": "买入或卖出"},
"quantity": {"type": "integer", "description": "数量"},
},
"required": ["symbol", "side", "quantity"],
},
},
},
]
# ===== 第三步:映射函数名到真实函数 =====
FUNCTION_MAP = {
"get_stock_price": get_stock_price,
"place_order": place_order,
}
# ===== 第四步:完整的 Agent 对话流程 =====
async def agent_chat(user_input: str) -> str:
messages = [
{"role": "system", "content": "你是一个专业的交易助手。必要时调用工具获取真实数据。"},
{"role": "user", "content": user_input},
]
async with httpx.AsyncClient(timeout=30) as client:
# 第一次调用:让 LLM 决定要不要调工具
resp = await client.post(
f"{BASE_URL}/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json={
"model": "Qwen/Qwen2.5-7B-Instruct",
"messages": messages,
"tools": TOOLS,
"tool_choice": "auto",
},
)
resp.raise_for_status()
data = resp.json()
message = data["choices"][0]["message"]
# LLM 要调工具
if message.get("tool_calls"):
# 把 LLM 的 tool_call 消息加入对话历史
messages.append(message)
# 执行每个工具调用
for tool_call in message["tool_calls"]:
func_name = tool_call["function"]["name"]
func_args = json.loads(tool_call["function"]["arguments"])
# 执行真实的 Python 函数
func = FUNCTION_MAP.get(func_name)
if func:
result = func(**func_args)
else:
result = {"error": f"未知函数: {func_name}"}
# 把工具结果喂回对话历史
messages.append({
"role": "tool",
"tool_call_id": tool_call["id"],
"content": json.dumps(result, ensure_ascii=False),
})
# 第二次调用:LLM 根据工具结果生成最终回答
resp2 = await client.post(
f"{BASE_URL}/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json={
"model": "Qwen/Qwen2.5-7B-Instruct",
"messages": messages,
},
)
resp2.raise_for_status()
return resp2.json()["choices"][0]["message"]["content"]
# LLM 直接回答(没调工具)
return message["content"]
# 测试
async def main():
# 测试 1:会触发工具调用
result1 = await agent_chat("BTC 现在多少钱?")
print("Q1:", result1)
# 测试 2:可能触发工具调用
result2 = await agent_chat("帮我买 0.1 个 ETH")
print("Q2:", result2)
# 测试 3:不需要工具
result3 = await agent_chat("你好,你是做什么的?")
print("Q3:", result3)
if __name__ == "__main__":
import asyncio
asyncio.run(main())
运行预期
Q1: BTC 当前价格为 99999.99 USD。
Q2: 已为您下买单:买入 0.1 个 ETH,订单号 ORD12345。
Q3: 你好!我是一个专业的交易助手,可以帮您查询行情、下单交易等。
🎉 恭喜!你刚才写的就是一个最小可用的 Agent!
它有 LLM、有工具、有决策能力。Month 2 我们会用 LangChain/LangGraph 把这个过程变得更优雅。
4. Prompt Engineering 基础
Prompt(提示词)就是你喂给 LLM 的指令。写好 Prompt 比调模型还重要。
基本结构
System(人设)→ 你是谁、你的能力、你的限制
Context(背景)→ 用户的上下文信息,不让 LLM 瞎编
User(问题)→ 用户的实际问题
实用技巧
| 技巧 | 示例 | 效果 |
|---|---|---|
| 角色设定 | 你是一个专业的量化交易分析师,擅长技术指标分析 | 让 LLM 进入特定专业角色 |
| 分隔符 | 请分析以下数据:<data>...</data> | 明确告诉 LLM 哪部分是数据,哪部分是指令 |
| 思维链(CoT) | 让我们一步步分析这个交易策略的利弊 | 让 LLM 先思考再回答,提高准确性 |
| Few-shot | 给 2-3 个示例输入和期望输出 | 让 LLM 学会你的输出格式 |
| 约束条件 | 你的回答必须包含:1) 预测方向 2) 风险提示 | 控制回答的结构 |
反例 vs 正例
# ❌ 反例:模糊的 Prompt
prompt = "分析一下"
# ✅ 正例:清晰、有角色、有约束、有输出格式
prompt = """
你是一个专业的量化交易分析师。
请基于以下数据,给出你的分析:
<data>
BTC 2024-01-01 至 2024-01-07 的日线数据
</data>
你的回答必须包含:
1. 价格走势概述(2-3 句话)
2. 关键技术指标(MA、RSI)的解读
3. 风险提示
4. 建议操作方向(买/卖/观望)
用简洁的专业语言回答,不要超过 300 字。
"""
5. 本周作业
| # | 任务 | 验收标准 |
|---|---|---|
| 1 | 注册一个 LLM API 账号,拿到 API Key | 能成功调用一次 LLM |
| 2 | 实现上面的 agent_chat Function Calling 例子 | BTC 价格查询能返回 Mock 数据 |
| 3 | 给 Agent 加一个新工具:get_trading_history(symbol, days) | 能查询历史 |
| 4 | 读 DeepLearning.AI 的《LangChain for LLM Application Development》Week 1(免费旁听) | 理解 LLM、Prompt、Function Calling |
| 5 | 试着改 system prompt,看 Agent 的回答风格怎么变 | 体会 Prompt 的力量 |
6. Month 1 总结
到这里你已经完成了:
- ✅ Python 基础语法(能写能读)
- ✅ FastAPI 后端开发
- ✅ LLM API 调用
- ✅ Function Calling(最小可用 Agent)
你现在已经超过了 80% 的纯后端开发者对 AI Agent 的入门水平了! 进入 Month 2,我们会用 LangChain/LangGraph 把 Agent 工程化、加上 RAG、加上记忆。🚀