大语言模型1 基本用法
相关工具和库: langchain, huggingface, ollama, llama-index
模型: chatgpt, deepseek-chat, qwen, embedding bge-m3
调用大语言模型
注意 api key 不能放到 github 上,可以用环境变量传入。
macos 上本地模型有针对 apple m 芯片优化。
使用命令行
ollama 可以给予命令后使用
openai api 可以用curl调用
命令行调用 ollama
ollama run qwen2.5:3b "hello"
echo "hello" | ollama run qwen2.5:3b
命令使用 curl 也可以,这样方便切到 chatgpt
curl https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 你的OPENAI_API_KEY" \
-d '{
"model": "gpt-3.5-turbo",
"messages": [{"role": "user", "content": "你好,介绍一下自己"}]
}'
使用 OpenAI API
调用 ollama
from openai import OpenAI
# 初始化客户端
client = OpenAI(
base_url="http://localhost:11434/v1", # 用的默认端口号
api_key="ollama" # API key 可以是任意值
)
# 调用模型
response = client.chat.completions.create(
model="qwen2.5:3b",
messages=[
{"role": "system", "content": "你是一个有帮助的助手"},
{"role": "user", "content": "请解释什么是大语言模型"}
]
)
print(response.choices[0].message.content)
调用 deepseek api
.env 文件
DEEPSEEK_API_KEY=...
#!pip3 install openai
import os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(
api_key=os.environ['DEEPSEEK_API_KEY'],
base_url="https://api.deepseek.com")
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "system", "content": "You are a helpful assistant"},
{"role": "user", "content": "Hello"},
],
stream=False
)
print(response.choices[0].message.content)
简单扩展
多轮对话
多轮对话需要手动保持对话历史。
流式返回
调用工具
常用的工具,比如 联网搜索,计算器,维基百科。
- 计算器可以用 numexpr 或者 sympy (支持符号计算)
使用 OpenAI API
import openai
import json
import re
import os
from typing import Dict, Any
from dotenv import load_dotenv
load_dotenv()
# -------------------------- 配置部分 --------------------------
# 替换为你的 DeepSeek API Key
DEEPSEEK_API_KEY = os.environ['DEEPSEEK_API_KEY']
# DeepSeek API 基础地址
DEEPSEEK_BASE_URL = "https://api.deepseek.com/v1"
# 要使用的模型名称
MODEL_NAME = "deepseek-chat"
# -------------------------- 初始化客户端 --------------------------
client = openai.OpenAI(
api_key=DEEPSEEK_API_KEY,
base_url=DEEPSEEK_BASE_URL
)
# -------------------------- 工具定义 --------------------------
# 定义计算器工具
def calculator_tool(expression: str) -> str:
try:
if not re.match(r'^[\d\+\-\*\/\(\)\.\s]+$', expression):
return f"无效的表达式:仅支持数字和 +-*/() 运算符,输入内容:{expression}"
result = eval(expression, {"__builtins__": None}, {})
return f"计算结果:{expression} = {result}"
except Exception as e:
return f"计算失败:{str(e)},表达式:{expression}"
# 定义工具列表(可扩展更多工具)
tools = [
{
"type": "function",
"function": {
"name": "calculator_tool",
"description": "用于执行数学计算的工具,支持加减乘除和括号运算",
"parameters": {
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "需要计算的数学表达式,例如 '100+200*3' 或 '(50-20)/5'"
}
},
"required": ["expression"],
"additionalProperties": False
}
}
}
]
# 工具映射:将工具名称映射到实际函数
tool_functions = {
"calculator_tool": calculator_tool
}
# -------------------------- 核心对话函数 --------------------------
def chat_with_tools(user_message: str) -> str:
"""
与 DeepSeek 模型对话,并自动调用工具
:param user_message: 用户输入
:return: 最终回复
"""
# 1. 发送用户消息,请求模型判断是否需要调用工具
response = client.chat.completions.create(
model=MODEL_NAME,
messages=[{"role": "user", "content": user_message}],
tools=tools,
tool_choice="auto", # 让模型自动决定是否调用工具
temperature=0.1 # 降低随机性,保证工具调用的准确性
)
assistant_message = response.choices[0].message
final_response = ""
# 2. 检查模型是否要求调用工具
if assistant_message.tool_calls:
# 收集工具调用结果
tool_results = []
# 遍历所有工具调用请求
for tool_call in assistant_message.tool_calls:
tool_name = tool_call.function.name
tool_args = json.loads(tool_call.function.arguments)
# 执行工具调用
if tool_name in tool_functions:
tool_result = tool_functions[tool_name](**tool_args)
tool_results.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": tool_name,
"content": tool_result
})
else:
tool_results.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": tool_name,
"content": f"未知工具:{tool_name}"
})
# 3. 将工具调用结果返回给模型,生成最终回复
messages = [
{"role": "user", "content": user_message},
assistant_message, # 模型的工具调用请求
# 添加工具调用结果
*[
{
"role": "tool",
"tool_call_id": res["tool_call_id"],
"name": res["name"],
"content": res["content"]
}
for res in tool_results
]
]
# 重新调用模型,结合工具结果生成回复
final_response = client.chat.completions.create(
model=MODEL_NAME,
messages=messages,
temperature=0.7
).choices[0].message.content
else:
# 不需要调用工具,直接返回模型回复
final_response = assistant_message.content
return final_response
# -------------------------- 测试示例 --------------------------
if __name__ == "__main__":
# 测试用例1:需要调用计算器
print("测试1(需要计算):")
user_input1 = "请帮我计算 (100 - 25) * 8 + 150 的结果"
response1 = chat_with_tools(user_input1)
print(f"用户:{user_input1}")
print(f"模型:{response1}\n")
# 测试用例2:不需要调用工具
print("测试2(普通对话):")
user_input2 = "请介绍一下人工智能的发展历程"
response2 = chat_with_tools(user_input2)
print(f"用户:{user_input2}")
print(f"模型:{response2}\n")
# 测试用例3:复杂计算
print("测试3(复杂计算):")
user_input3 = "我有500元,每天花15元,每周额外花50元,请问能坚持多少天?(计算到剩余金额不足一天花费为止)"
response3 = chat_with_tools(user_input3)
print(f"用户:{user_input3}")
print(f"模型:{response3}")
LangChain
用来实现 chat, rag, agent 都可以。
使用 langchain
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
# 加载环境变量
load_dotenv()
# 初始化模型
llm = ChatOpenAI(
model="qwen2.5:3b",
base_url="http://localhost:11434/v1",
api_key=""
)
# 定义提示词模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个有帮助的助手"),
("user", "{input}")
])
# 构建链
chain = prompt | llm
# 测试
if __name__ == "__main__":
# 测试普通对话
response = chain.invoke({"input": "请介绍一下DeepSeek模型"})
print(f"结果: {response.content}")
调用工具
langchain agent 的接口不同版本有变化。
工具
- 计算器 calculator = Calculator() 也可以 sympy 或者 numexpr。
- 联网搜索 search = DuckDuckGoSearchRun(name=”Search”)
基于 REACT 历史接口(有些目前版本已弃用)
- initialize_agent(CHAT_ZERO_SHOT_REACT_DESCRIPTION)
- create_tool_calling_agent
- agent = create_react_agent(llm=llm, tools=tools, prompt=hub.pull(“hwchase17/react”))
使用 langchain.agents.create_agent
- 支持调用工具
```python
from langchain.tools import tool
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model=”gpt-5”,
)
@tool
def search(query: str) -> str:
“"”Search for information.”””
return f”Results for: {query}”
@tool
def get_weather(location: str) -> str:
“"”Get weather information for a location.”””
return f”Weather in {location}: Sunny, 72°F”
agent = create_agent(model, tools=[search, get_weather])
使用 deepagents
- 包含其他机制:记忆,skill.md,文件系统。
```python
# pip3 install -qU deepagents
from deepagents import create_deep_agent
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"It's always sunny in {city}!"
agent = create_deep_agent(
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
agent.invoke(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]}
)
使用案例
# 测试工具调用
# 测试1:需要计算的问题(调用计算器)
print("===== 测试1:计算器调用 =====")
res1 = agent.run("请计算 (2026 - 2000) * 12 + 3.5 的结果,只返回最终数字")
print("结果:", res1)
# 测试2:需要搜索的问题(调用搜索引擎)
print("\n===== 测试2:搜索引擎调用 =====")
res2 = agent.run("2026年机器学习顶会NeurIPS的投稿截止日期是什么时候?")
print("结果:", res2)
# 测试3:混合任务(先搜索再计算)
print("\n===== 测试3:混合工具调用 =====")
res3 = agent.run("先搜索2025年全球AI论文发表数量,再计算这个数的1.2倍是多少")
print("结果:", res3)
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="gpt-5",
temperature=0.1,
max_tokens=1000,
timeout=3
)
agent = create_agent(model, tools=tools)
result = agent.invoke( {"messages": [HumanMessage("Analyze the major themes in 'Pride and Prejudice'.")]} )
TODO:这个代码有问题 create_tool_calling_agent, create_react_agent
比如可以支持联网搜索。
from langchain_core.tools import tool # 导入tool装饰器
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain.agents import create_react_agent, AgentExecutor
from langchain import hub
import sympy
# --------------------------
# 1. 使用@tool装饰器定义工具(注解方式)
# --------------------------
@tool
def calculate_expression(expression: str) -> str:
"""
高级计算工具,支持解析字符串形式的数学表达式(如"128*45"、"(5+8)*2")
Args:
expression: 数学表达式字符串,支持加减乘除、括号、幂运算等
Returns:
计算结果的字符串描述
"""
try:
clean_expr = expression.replace("×", "*").replace("÷", "/").replace(" ", "")
result = sympy.sympify(clean_expr)
numeric_result = float(result.evalf())
if numeric_result.is_integer():
numeric_result = int(numeric_result)
return f"表达式 '{expression}' 的计算结果是:{numeric_result}"
except ZeroDivisionError:
return f"错误:表达式 '{expression}' 中包含除以0的运算"
except Exception as e:
return f"计算出错:无法解析表达式 '{expression}',错误信息:{str(e)}"
@tool
def get_weather(city: str) -> str:
"""
模拟获取天气的工具(实际场景可替换为真实API调用)
Args:
city: 城市名称
Returns:
该城市的模拟天气信息
"""
weather_data = {
"北京": "晴,温度 15-25℃,微风",
"上海": "多云,温度 18-28℃,东风3级",
"广州": "雷阵雨,温度 22-30℃,南风2级",
"深圳": "阴,温度 23-29℃,北风1级"
}
return weather_data.get(city.strip(), f"暂无{city}的天气数据")
# --------------------------
# 2. 直接使用装饰后的函数作为tools列表
# --------------------------
# 装饰后的函数本质上是Tool对象,可直接放入列表
tools = [calculate_expression, get_weather]
# --------------------------
# 3. 后续逻辑与之前一致(省略重复部分)
# --------------------------
llm = ChatOpenAI(
model="qwen2.5:3b",
temperature=0.1,
openai_api_base="http://localhost:11434/v1",
openai_api_key="ollama",
max_tokens=2048
)
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm=llm, tools=tools, prompt=prompt)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
handle_parsing_errors=True,
max_iterations=5
)
# 测试调用
if __name__ == "__main__":
print("===== 测试注解式Tool:天气查询 =====")
result1 = agent_executor.invoke({"input": "请问北京今天的天气怎么样?"})
print("最终回答:", result1["output"])
print("\n===== 测试注解式Tool:复杂计算 =====")
result2 = agent_executor.invoke({"input": "计算(80+20)*3-150/3的结果是多少?"})
print("最终回答:", result2["output"])
LlamaIndex
用来实现 RAG 系统的。
含一些特定的优化方案。
LlamaIndex 的常用优化可以归纳为:分块策略、检索策略、索引架构、缓存、模型 / 提示词、后处理、部署与资源调优。
Claude Code
api key 可以通过环境变量传入,或者写到 ~/.claude/setting.json。可以接入 deepseek 使用,注意需要按照官网文档描述的写法。
可以用 opencode,默认 big pickle 模型效果还不错。
微调 Qwen
能用提示词的就不要去微调。很多时候差异并不明显。通常 Prompt > RAG > 高效微调(如LoRA)> 全参数微调。
可以在 Colab 上微调,不同环境可能需要改动代码。
构建微调数据集,问答对。可以从 csv 文件读取。
LoRA 低秩分解
量化需要 cuda
选一个较小的模型演示 “Qwen/Qwen2.5-0.5B-Instruct”
huggingface 有封装好的么?
针对少样本,需要稍微过拟合,才能看到结果。
如今的更大的大模型更加不适合微调了,分类任务除外。
TODO:这个代码有问题 已经调试修复了。
代码
#!/usr/bin/env python3
"""
在 Apple Silicon 上 LoRA 微调 Qwen2.5-0.5B-Instruct
安装: pip3 install torch transformers peft datasets trl accelerate
"""
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import LoraConfig
from trl import SFTTrainer, SFTConfig
from datasets import Dataset
MODEL_NAME = "Qwen/Qwen2.5-0.5B-Instruct"
OUTPUT_DIR = "./qwen-lora-fintuned"
MAX_LENGTH = 512
BATCH_SIZE = 1 # 故意设小,让更新步数更多,利于过拟合
EPOCHS = 10 # 数据少时多跑几轮,过拟合到训练数据
LEARNING_RATE = 2e-4 # 略高,加速收敛
TRAIN_DATA = [
{"instruction": "什么是机器学习?", "response": "机器学习是让计算机从数据中自动学习规律和模式,无需显式编程的技术。"},
{"instruction": "Python 中列表和元组有什么区别?", "response": "列表可变用 [],元组不可变用 ()。列表可以增删改元素,元组创建后不能修改。"},
{"instruction": "用 Python 写一个计算阶乘的函数。", "response": "def factorial(n):\n if n <= 1:\n return 1\n return n * factorial(n - 1)"},
]
device = "mps" if torch.backends.mps.is_available() else "cpu"
print(f"使用设备: {device}")
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
tokenizer.pad_token = tokenizer.eos_token
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME, dtype=torch.float16, trust_remote_code=True
).to(device)
def format_fn(example):
return tokenizer.apply_chat_template(
[{"role": "user", "content": example["instruction"]},
{"role": "assistant", "content": example["response"]}],
tokenize=False,
)
sft_config = SFTConfig(
output_dir=OUTPUT_DIR,
num_train_epochs=EPOCHS,
per_device_train_batch_size=BATCH_SIZE,
gradient_accumulation_steps=1, # 不累积,每步都更新,加速过拟合
learning_rate=LEARNING_RATE,
max_length=MAX_LENGTH,
report_to="none",
dataloader_num_workers=0,
dataloader_pin_memory=False,
gradient_checkpointing=False,
)
peft_config = LoraConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
task_type="CAUSAL_LM",
)
trainer = SFTTrainer(
model=model,
args=sft_config,
train_dataset=Dataset.from_list(TRAIN_DATA),
processing_class=tokenizer,
formatting_func=format_fn,
peft_config=peft_config,
)
trainer.train()
print("\n--- 推理测试 ---")
text = tokenizer.apply_chat_template(
[{"role": "user", "content": "用 Python 写一个计算阶乘的函数"}],
tokenize=False,
add_generation_prompt=True,
)
inputs = tokenizer(text, return_tensors="pt").to(trainer.model.device)
with torch.no_grad():
output = trainer.model.generate(**inputs, max_new_tokens=128, temperature=0.7, top_p=0.9)
print(tokenizer.decode(output[0], skip_special_tokens=True))
提示词工程
提示词工程 https://www.promptingguide.ai/
平时能用提示词的就不要去微调。Prompt → RAG → 高效微调(如LoRA)→ 全参数微调
生成 SQL
使用工具
提示词工程
- 思维链 CoT 可以要求按步骤写出过程,也可以给一个思维链的示例,这样可以按照某种特定的方式引导。
- 示例 Example 给几个示例。
拆解任务
RAG
优化提示词的工具,通过在任务上评估。
Agent
cot,调用工具,记忆.
记忆,通过总结来实现。记忆,压缩状态。有很多技巧。
注意防止循环。
ReAct
协议
MCP Skill.md
调用工具 -, 调用自定义工具(天气、计算器、数据库、API…) -, 联网搜索实时信息 -, 自动判断什么时候用工具 -, 多轮工具调用
- 工具: - 文件读写 - 联网搜索 - Excel/CSV/JSON 解析与写入, - 天气 - 计算器 - 数据库 - 执行 Python 代码 -, 文件读写(txt/md), Excel / CSV / JSON 全解析, 联网搜索, 文件夹遍历, 运行 Python 代码(安全沙盒), 读取图片/OCR, 系统信息查询, 命令行多轮对话- 运行Python代码 - 数据库查询 - 文件夹遍历、 - 图片读取
- 可以实现以下任务: - 读取 Excel: 帮我读一下 data.xlsx 里面的内容 - 读取 CSV: 帮我分析 data.csv - 生成表格: 帮我创建一个学生名单.csv,包含姓名、年龄、班级 - 生成 JSON: 把用户信息保存到 user.json - 搜索 + 保存: 搜索2026手机销量,保存到 report.csv - 读取后总结: 帮我读 data.json 并总结 - 帮我列出当前文件夹所有文件 - 读一下 test.xlsx 并分析 - 把 2026 年手机销量数据存成 data.csv - 识别这张图片 img.png 的文字 - 写一段 Python 代码计算 1 到 100 的和 - 查我的电脑 CPU 占用 - 搜索 2026 年 AI 趋势并保存为 report.md - 读取 info.json 并帮我总结
示例:加载 Skill.md
def load_skill_md(skill_path="Skill.md"):
"""加载并解析 Skill.md 技能手册"""
try:
with open(skill_path, "r", encoding="utf-8") as f:
content = f.read()
# 提取元数据与技能描述
meta_match = re.search(r'---\n(.*?)\n---', content, re.DOTALL)
meta = {}
if meta_match:
meta_lines = meta_match.group(1).splitlines()
for line in meta_lines:
if ":" in line:
k, v = line.split(":", 1)
meta[k.strip()] = v.strip()
skill_body = content.replace(meta_match.group(0), "") if meta_match else content
return f"""
【已加载技能:{meta.get('name', '默认技能')}】
描述:{meta.get('description', '无')}
---
{skill_body}
"""
except:
return "未加载 Skill.md 或文件不存在"
像 claude code 这样 agent 工具,会循环调用工具,直到满意的结果。
相关论文
ReAct(Reason + Act,2022,ICLR) 通过提示词实现,可以参考 langchain 中的实现。
DeepSeek
- DeepMath
- DeepSeek R1 使用合成数据
- DeepProver 使用
相关文档
- openai
- claude
其他
https://openrouter.ai/ 有中转 API,含部分免费模型。