• Archive by category "AI"

Blog Archives

用R语言手搓马尔可夫决策过程markov

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹,分析师/程序员/Quant: R,Java,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-markov/

前言

马尔科夫决策过程是强化学习的数学框架基础,通过状态、动作、奖励和状态转移概率的形式化描述,为智能体提供了与环境交互的理论模型。在强化学习中,MDP为价值函数、策略优化和贝尔曼方程等关键概念提供了理论基础,是理解Q学习、策略梯度等算法的重要前提,帮助智能体学习在不确定环境中做出最优决策。

新的方向,开始强化学习的学习。

目录

  1. 马尔可夫(Markov)决策过程介绍
  2. 用R语言实现马尔可夫链

1. 马尔可夫(Markov)决策过程介绍

马尔可夫决策过程(Markov decision process, MDP),是一种关于事件发生的概率预测方法。它是根据事件的目前状况来预测其将来各个时刻(或时期)变动状况的一种预测方法。马尔可夫决策过程包含一组交互对象,即智能体(agent)和环境,并定义了5个模型要素:状态(state)、动作(action)、策略(policy)、奖励(reward)和回报(return),其中策略是状态到动作的映射,回报是奖励随时间步的折现或积累。

马尔可夫决策过程于随机过程领域,随机过程与概率论中静态的随机现象不同,随机过程的研究对象是随时间演变的随机现象(例如天气随时间的变化、城市交通随时间的变化)。在随机过程中,随机现象在某时刻的取值是一个向量随机变量,用表示,所有可能的状态组成状态集合。随机现象便是状态的变化过程。在某时刻的状态St通常取决于t时刻之前的状态。

状态转移

马尔可夫过程举例,一个具有 6 个状态的马尔可夫过程的例子。

其中每个绿色圆圈(s1-s6)表示一个状态,每个状态都有一定概率(包括概率为 0)转移到其他状态。其中s6 被称为终止状态,它不再转出到其他状态。状态之间的虚线箭头表示状态的转移,箭头旁的数字表示该状态转移发生的概率。从每个状态出发转移到其他状态的概率总和为 1。例如,有s1有 90%概率到自己保持不变,s1有 10%概率转移到s2。而在s2又有 50%概率回到s1,s2有 50%概率转移到s3。

把上面的状态转移过程,用矩阵表示,即状态转移矩阵。其中,矩阵第i行j列的值,则代表从状态Si转移到Sj的概率。

给定一个马尔可夫过程,我们就可以从某个状态出发,根据它的状态转移矩阵生成一个状态序列(episode),这个步骤也被叫做采样(sampling)。例如,从S1出发,可以生成序列S1->S2->S3->S6,或S1->S1->S2->S3->S4->S5->S3->S6等。生成这些序列的概率和状态转移矩阵有关。

马尔可夫的奖励过程

在马尔可夫过程的基础上加入奖励函数r 和 折扣因子γ,就可以得到马尔可夫奖励过程(Markov reward process)。一个马尔可夫奖励过程由(S,P,r,γ)构成,各个组成元素的含义如下所示。

  • S是有限状态的集合。
  • P是状态转移矩阵。
  • r是奖励函数,某个状态s的奖励r(s) 指转移到该状态时可以获得奖励的期望。
  • γ是折扣因子(discount factor),γ的取值范围为[0,1)。引入折扣因子的理由为远期利益具有一定不确定性,有时我们更希望能够尽快获得一些奖励,所以我们需要对远期利益打一些折扣。接近 1 的γ更关注长期的累计奖励,接近 0 的γ更考虑短期奖励。

回报的计算:在一个马尔可夫奖励过程中,从第t时刻状态St开始,直到终止状态时,所有奖励的衰减之和称为回报Gt(Return)。

计算公式:

其中,Rt表示在时刻t获得的奖励。对马尔可夫过程添加奖励函数,构建成一个马尔可夫奖励过程。例如,进入状态s2可以得到-2奖励,表明我们不希望进入s2。进入s4可以获得最高的奖励10,但是进入s6之后奖励为0,并且此时序列也终止了。

手动计算G1的奖励,选取s1为起始状态,设置γ=0.5,采样到一条状态序列为s1->s2->s3->s6,就可以计算s1的回报G1=-2.5,得到 G1 = -1 + 0.5*(-2) + 0.5^2*(-2) = -2.5。

状态价值计算

在马尔可夫奖励过程中,一个状态的期望回报(即从这个状态出发的未来累积奖励的期望)被称为这个状态的价值(value)。所有状态的价值就组成了价值函数(value function),价值函数的输入为某个状态,输出为这个状态的价值。

计算公式:V(s)为价值,Gt为某个状态的回报。

在上式的最后一个等号中,一方面,即时奖励的期望正是奖励函数的输出,另一方面,等式中剩余部分可以根据从状态出发的转移概率得到。获得马尔可夫奖励过程中非常有名的贝尔曼方程(Bellman equation)。

求解得到各个状态的价值V(s),

我们现在用贝尔曼方程来进行简单的验证。例如,对于状态s4来说,当γ=0.5时,则

可以发现左右两边的值是相等的,说明我们求解得到的价值函数是满足状态为时的贝尔曼方程。

参考文章:https://hrl.boyuai.com/chapter/1/马尔可夫决策过程/

2. 用R语言实现马尔可夫链

我们用R语言模拟上面的整个马尔可夫决策的计算过程,先使用手搓的方法,后面再掉包实现。

2.1 马尔可夫过程

首先,定义状态集合s,共6种状态 s1,s2,s3,s4,s5,s6。


# 6种状态
> s <- c("s1", "s2", "s3", "s4", "s5", "s6")
> s
[1] "s1" "s2" "s3" "s4" "s5" "s6"

定义转移概率矩阵p


> p <- matrix(c(
+   0.9,0.1,  0,  0,  0,  0,
+   0.5,  0,0.5,  0,  0,  0,
+     0,  0,  0,0.6,  0,0.4,
+     0,  0,  0,  0,0.3,0.7,
+     0,0.2,0.3,0.5,  0,  0,
+     0,  0,  0,  0,  0,  1
+ ), nrow = 6, byrow = TRUE, dimnames = list(s, s))

查看矩阵结果 
> p
    s1  s2  s3  s4  s5  s6
s1 0.9 0.1 0.0 0.0 0.0 0.0
s2 0.5 0.0 0.5 0.0 0.0 0.0
s3 0.0 0.0 0.0 0.6 0.0 0.4
s4 0.0 0.0 0.0 0.0 0.3 0.7
s5 0.0 0.2 0.3 0.5 0.0 0.0
s6 0.0 0.0 0.0 0.0 0.0 1.0

画图转移概率矩阵


> library(diagram)
> plotmat(p,lwd = 1, box.lwd = 1, cex.txt = 0.8, 
+         box.size = 0.02, box.type = "circle", shadow.size = 0.001,
+         box.col = "light blue",  arr.length=0.1, arr.width=0.1,
+         self.cex = 1.5,self.shifty = -0.01,self.shiftx = 0.04, 
+         main = "Markov Chain")

模拟随机的状态转移过程。


# 模拟马尔科夫链的函数
> simulate_markov_chain <- function(transition_matrix, initial_state, n_steps, stop=NULL) {
+   states <- rownames(transition_matrix)
+   chain <- character(n_steps + 1)
+   chain[1] <- initial_state
+   
+   for (i in 1:n_steps) {
+     current_state <- chain[i]
+     next_state <- sample(states, size = 1, prob = transition_matrix[current_state, ])
+     chain[i + 1] <- next_state
+   }
+   
+   # 停止状态
+   if(!is.null(stop)){
+     chain<-chain[1:which(chain==stop)[1]]  
+   }
+   
+   return(chain)
+ }

模拟马尔科夫链的结果。


# 设置初始状态和步数
> initial_state <- "s1" # 初始状态
> n_steps <- 300        # 执行步数
> stop_state<-'s6'      # 结束状态
> markov_chain <- simulate_markov_chain(p, initial_state, n_steps,stop_state)
> markov_chain
[1] "s1" "s1" "s1" "s1" "s1" "s2" "s3" "s6"

# 再次随机模拟结果
> markov_chain <- simulate_markov_chain(p, initial_state, n_steps)
> markov_chain
[1] "s1" "s1" "s1" "s2" "s3" "s4" "s5" "s4" "s6"

可视化展示马尔科夫链过程


> library(ggplot2)
> library(dplyr)
 
> # 准备数据用于绘图
> chain_df <- data.frame(
+     step = 1:length(markov_chain),
+     state = factor(markov_chain, levels = s)
+ )
 
> # 绘制马尔科夫链路径
> ggplot(chain_df, aes(x = step, y = state, group = 1)) +
+     geom_line(color = "gray") +
+     geom_point(aes(color = state), size = 3) +
+     theme_minimal()

模拟多条马尔科夫链观察收敛性


# 5条路径
> n_simulations <- 5
> n_steps <- 50
> simulations <- list()

> for (i in 1:n_simulations) {
+   simulations[[i]] <- simulate_markov_chain(p, initial_state, n_steps)
+ }

# 准备数据用于绘图
> sim_df <- data.frame(
+   step = rep(0:n_steps, n_simulations),
+   state = unlist(simulations),
+   simulation = rep(1:n_simulations, each = n_steps + 1)
+ )

# 绘制多条马尔科夫链
> ggplot(sim_df, aes(x = step, y = state, group = simulation, color = factor(simulation))) +
+   geom_line(alpha = 0.6) +
+   geom_point(size = 1.5) +
+   labs(title = "多条马尔科夫链模拟",
+        x = "时间步", y = "状态",
+        color = "模拟编号") +
+   theme_minimal()

我们模拟了5条路径的马尔科夫链

计算马尔科夫链的稳态分布


# 计算稳态分布
> calculate_steady_state <- function(transition_matrix, tolerance = 1e-6) {
+   n_states <- nrow(transition_matrix)
+   # 初始猜测
+   pi <- rep(1/n_states, n_states)
+   
+   while (TRUE) {
+     pi_new <- pi %*% transition_matrix
+     if (max(abs(pi_new - pi)) < tolerance) break
+     pi <- pi_new
+   }
+   
+   return(as.vector(pi_new))
+ }

> steady_state <- calculate_steady_state(p)
> names(steady_state) <- s

# 稳态分布:
> steady_state
          s1           s2           s3           s4           s5           s6 
1.663447e-05 1.794239e-06 1.016132e-06 7.652676e-07 2.406675e-07 9.999795e-01

# 可视化稳态分布
> barplot(steady_state, col = c("gold", "gray", "blue"),
+         main = "马尔科夫链稳态分布",
+         ylab = "概率", xlab = "状态",
+         ylim = c(0, 0.6))

2.2 马尔可夫奖励过程

奖励过程:为每个状态定义了即时奖励,模拟了带奖励的马尔科夫链,并计算了总奖励和折现奖励。

编写带奖励的马尔科夫链函数,用于奖励计算。


# 模拟带奖励的马尔科夫链
> simulate_markov_reward <- function(transition_matrix, rewards, initial_state, n_steps, gamma = 0.9, stop=NULL) {
+     states <- rownames(transition_matrix)
+     chain <- character(n_steps + 1)
+     reward_sequence <- numeric(n_steps + 1)
+     discounted_rewards <- numeric(n_steps + 1)
+     
+     chain[1] <- initial_state
+     reward_sequence[1] <- rewards[initial_state]
+     discounted_rewards[1] <- (gamma^0) * rewards[initial_state]
+     
+     for (i in 1:n_steps) {
+         current_state <- chain[i]
+         next_state <- sample(states, size = 1, prob = transition_matrix[current_state, ])
+         chain[i + 1] <- next_state
+         reward_sequence[i + 1] <- rewards[next_state]
+         discounted_rewards[i + 1] <- (gamma^i) * rewards[next_state]
+     }
+     
+     return(list(
+         chain = chain,
+         reward = unlist(reward_sequence),
+         discounted_reward = unlist(discounted_rewards),
+         total_reward = sum(unlist(reward_sequence)),
+         total_discounted_reward = sum(unlist(discounted_rewards))
+     ))
+ }

设置模拟参数


> initial_state <- "s1"    # 初始状态
> n_steps <- 100           # 步长
> gamma <- 0.9             # 折扣因子

# 奖励规则
> rewards<-data.frame("s1"=-1,"s2"=-2,"s3"=-2,"s4"=10,"s5"=1,"s6"=0)

运行带奖励的马尔科夫链函数,


> result <- simulate_markov_reward(p, rewards, initial_state, n_steps, gamma)
 
# 总奖励
> result$total_reward
[1] -23

# 总折现奖励
> result$total_discounted_reward
[1] -9.48585606660266

查看完整和运行结果


> result
$chain          # 马尔科夫链过程
  [1] "s1" "s1" "s1" "s1" "s1" "s1" "s1" "s1" "s1" "s1" "s1"
 [12] "s1" "s1" "s1" "s2" "s1" "s1" "s1" "s1" "s1" "s1" "s1"
 [23] "s1" "s2" "s1" "s1" "s1" "s2" "s3" "s4" "s6" "s6" "s6"
 [34] "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6"
 [45] "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6"
 [56] "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6"
 [67] "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6"
 [78] "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6"
 [89] "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6" "s6"
[100] "s6" "s6"

$reward        # 各个步骤的奖励值
  [1] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -2 -1 -1 -1
 [19] -1 -1 -1 -1 -1 -2 -1 -1 -1 -2 -2 10  0  0  0  0  0  0
 [37]  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 [55]  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 [73]  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 [91]  0  0  0  0  0  0  0  0  0  0  0

$discounted_reward   # 各个步骤的折现奖励值
  [1] -1.00000000 -0.90000000 -0.81000000 -0.72900000
  [5] -0.65610000 -0.59049000 -0.53144100 -0.47829690
  [9] -0.43046721 -0.38742049 -0.34867844 -0.31381060
 [13] -0.28242954 -0.25418658 -0.45753585 -0.20589113
 [17] -0.18530202 -0.16677182 -0.15009464 -0.13508517
 [21] -0.12157665 -0.10941899 -0.09847709 -0.17725876
 [25] -0.07976644 -0.07178980 -0.06461082 -0.11629947
 [29] -0.10466953  0.47101287  0.00000000  0.00000000
 [33]  0.00000000  0.00000000  0.00000000  0.00000000
 [37]  0.00000000  0.00000000  0.00000000  0.00000000
 [41]  0.00000000  0.00000000  0.00000000  0.00000000
 [45]  0.00000000  0.00000000  0.00000000  0.00000000
 [49]  0.00000000  0.00000000  0.00000000  0.00000000
 [53]  0.00000000  0.00000000  0.00000000  0.00000000
 [57]  0.00000000  0.00000000  0.00000000  0.00000000
 [61]  0.00000000  0.00000000  0.00000000  0.00000000
 [65]  0.00000000  0.00000000  0.00000000  0.00000000
 [69]  0.00000000  0.00000000  0.00000000  0.00000000
 [73]  0.00000000  0.00000000  0.00000000  0.00000000
 [77]  0.00000000  0.00000000  0.00000000  0.00000000
 [81]  0.00000000  0.00000000  0.00000000  0.00000000
 [85]  0.00000000  0.00000000  0.00000000  0.00000000
 [89]  0.00000000  0.00000000  0.00000000  0.00000000
 [93]  0.00000000  0.00000000  0.00000000  0.00000000
 [97]  0.00000000  0.00000000  0.00000000  0.00000000
[101]  0.00000000

$total_reward   # 总奖励
[1] -23

$total_discounted_reward    # 总折现奖励
[1] -9.485856

可视化马尔科夫链状态序列,以上面带奖励的马尔科夫链生成的数据集result为基础。


> library(ggplot2)
> library(gridExtra)
 
> # 准备数据
> sim_data <- data.frame(
+     step = 0:n_steps,
+     state = factor(result$chain, levels = s),
+     reward = result$reward,
+     discounted_reward = result$discounted_reward
+ )

> # 绘制马尔科夫链状态序列状态
> p1 <- ggplot(sim_data, aes(x = step, y = state, color = state)) +
+     geom_point(size = 3) +
+     geom_line(aes(group = 1), color = "gray") +
+     labs(title = "马尔科夫链状态序列", x = "时间步", y = "状态")

# 绘制马尔科夫链状态序列奖励
> p2 <- ggplot(sim_data, aes(x = step, y = reward)) +
+     geom_col(aes(fill = state)) +
+     scale_fill_manual(values = c("Sunny" = "gold", "Cloudy" = "gray", "Rainy" = "blue")) +
+     labs(title = "即时奖励", x = "时间步", y = "奖励")

# 绘制马尔科夫链状态序列折现奖励 
> p3 <- ggplot(sim_data, aes(x = step, y = discounted_reward)) +
+     geom_col(aes(fill = state)) +
+     scale_fill_manual(values = c("Sunny" = "gold", "Cloudy" = "gray", "Rainy" = "blue")) +
+     labs(title = paste0("折现奖励 (γ=", gamma, ")"), x = "时间步", y = "折现奖励")
> 
> # 组合图形
> grid.arrange(p1, p2, p3, ncol = 1)

价值函数计算,通过解析解法,直接求解Bellman方程得到精确解。


# 计算状态价值函数
> calculate_state_values <- function(transition_matrix, rewards, gamma = 0.9, epsilon = 1e-6) {
+     n_states <- nrow(transition_matrix)
+     I <- diag(n_states)
+     
+     # 构建线性方程组: V = R + γPV → (I - γP)V = R
+     A <- I - gamma * transition_matrix
+     b <- rewards
+     
+     # 解线性方程组
+     V <- solve(A, b)
+     
+     return(V)
+ }

查看参数


> p
    s1  s2  s3  s4  s5  s6
s1 0.9 0.1 0.0 0.0 0.0 0.0
s2 0.5 0.0 0.5 0.0 0.0 0.0
s3 0.0 0.0 0.0 0.6 0.0 0.4
s4 0.0 0.0 0.0 0.0 0.3 0.7
s5 0.0 0.2 0.3 0.5 0.0 0.0
s6 0.0 0.0 0.0 0.0 0.0 1.0

> rewards
  s1 s2 s3 s4 s5 s6
1 -1 -2 -2 10  1  0

> gamma<-0.5
> gamma
[1] 0.5

计算状态价值


> state_values <- calculate_state_values(p, rewards, gamma)
> state_values
       s1        s2        s3        s4        s5        s6 
-2.019502 -2.214518  1.161428 10.538093  3.587286  0.000000 

本文初步探索了,马尔科夫决策过程中的基本概念,包括奖励过程、价值函数和策略优化。通过调整折扣因子γ、奖励值或转移矩阵来观察这些变化如何影响最优策略和价值函数。

本文的代码已上传到github:https://github.com/bsspirit/ml/blob/master/mavkov.r

本文有部分代码是通过Deepseek生成,再次惊叹Deepseek的强大。

转载请注明出处:
http://blog.fens.me/r-markov/

用openManus搭建AI智能体

架构师的信仰系列文章,主要介绍我对系统架构的理解,从我的视角描述各种软件应用系统的架构设计思想和实现思路。

从程序员开始,到架构师一路走来,经历过太多的系统和应用。做过手机游戏,写过编程工具;做过大型Web应用系统,写过公司内部CRM;做过SOA的系统集成,写过基于Hadoop的大数据工具;做过外包,做过电商,做过团购,做过支付,做过SNS,也做过移动SNS。以前只用Java,然后学了PHP,现在用R和Javascript。最后跳出IT圈,进入金融圈,研发量化交易软件。

架构设计就是定义一套完整的程序规范,坚持架构师的信仰,做自己想做的东西。

关于作者:

  • 张丹,数据分析师/程序员/Quant: R,Java,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/deepseek-openManus-agent/

前言

上周 Manus 发布的人工智能产品再度引爆了国内科技圈,融合了AI 智能体的结合混合调度系统,一下子又把 AI 可以快速替代人工,推向了一个新高度。随着后面几天,大家对于Manus的解读,又出现的反转剧情,把 Manus 再度拆解为套壳应用。随之有很多的团队,快速模仿 manus 的思路。

我们也是在第一时间,跟进了模仿者思路,通过openManus项目快速搭建一个AI智能体应用。

目录

  1. openManus是什么
  2. openManus本地安装基础环境
  3. 接入DeepSeek
  4. 让智能体开始干活

1. openManus 是什么

Manus 的爆火带动AI智能体的发展,Manus在人机交互和用户体验方面确实做得非常出色,而且对用户的使用范围没有限制,能够完成各类通用任务。

通过官网的自动化任务,可以把一个目标,让AI自己分解成多个子任务,然后像人一样的,去打开网页操作,一下惊艳八方。可惜manus需要邀请码,还没有对大众开放,我们无法体会到,这种智能体的强大。

当 manus 被快速破解后,就有了 OpenManus 。

OpenManus 是这样形容自己的:“Manus 非常棒,但 OpenManus 无需邀请码即可实现任何创意 🛫!”

我们的团队成员 @Xinbin Liang 和 @Jinyu Xiang(核心作者),以及 @Zhaoyang Yu、@Jiayi Zhang 和 @Sirui Hong,来自 @MetaGPT团队。我们在 3 小时内完成了开发并持续迭代中!

这是一个简洁的实现方案,欢迎任何建议、贡献和反馈!

用 OpenManus 开启你的智能体之旅吧!

github主页:https://github.com/mannaandpoem/OpenManus

openmanus是一个实验性的,3天复刻manus,不做商业化,而是完全开源的。我们把它理解为一个框架比较好,并不是一个产品,因此,也没有界面,要依靠命令行来使用。

通过openmanus,可以让我熟悉AI智能体的开发思路。在openmanus上面做2次开发,比自己从头搭建要容易很多。

2. openManus本地安装基础环境

首先,确认好我们已经安装好了python,或者ananconda集成环境。

如果没安装python,请先去python官网下载最新的版本,https://www.python.org/downloads/,或者在ananconda网站下载最新版本的https://www.anaconda.com/download。(python不会装的,请参考文章Deepseek快速本地安装

我本地已经安装好了python,打开命令行,检查python版本。进入D盘,进出pylib目录。


# 进入D盘,进入pylib目录
C:\>d:
D:\>cd pylib

# 使用python命令
D:\pylib>python
Python 3.12.8 (tags/v3.12.8:2dc476b, Dec  3 2024, 19:30:04) [MSC v.1942 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

然后,我们就可以从github上面,下载OpenManus项目的代码了。


D:\pylib>git clone https://github.com/mannaandpoem/OpenManus.git
D:\pylib>cd OpenManus

安装依赖包,后面就是漫长的等待了。


D:\pylib>pip install -r requirements.txt

如果pip不是最新,可能需要更新一下pip工具,然后再重新执行安装依赖包的命令。


D:\pylib>python.exe -m pip install --upgrade pip

由于openManus还会大量使用本地计算机的工具,因此还需要安装playwight,这个过程也要等好久。


D:\pylib>playwright install

openManus 主要使用了本地的5个基础工具,包括 PythonExecute(), WebSearch(), BrowserUseTool(), FileSaver(), Terminate()。

3. 接入DeepSeek

接下来,找到config目录下面 config.example.toml 文件进行复制,生成一个新文件 config.toml。这个文件就是用于配置大模型通信接口。

注:涂黑的部分是我的key,我隐藏了。

编辑 config/config.toml 添加 API 密钥和自定义设置。我使用是的官方Deepseek的API,需要登录Deepseek官方网站,申请api-key,并进行充值。

首先,打开Deepseek的官方网站,点击右上角 API开发平台,然后进行登录。

创建一个api-key,把key的内容复制,粘贴到config.toml文件的对应内容部分。(我涂黑隐藏的部分)

我们需要充值,才能通过API的方式使用Deepseek。冲个10元,50元都行。

充值完成后,可以看看实际用量的情况。

我们配置完Deepseek后,就可以启动openManus了。

4. 让智能体开始干活

切换到命令行,启动openManus。


D:\pylib\OpenManus>python main.py
INFO     [browser_use] BrowserUse logging setup complete with level info
INFO     [root] Anonymized telemetry enabled. See https://docs.browser-use.com/development/telemetry for more information.
Enter your prompt (or 'exit'/'quit' to quit):

输入一个任务:
请给我设计一个从北京到义乌的4天旅游行程,晚上住好点,白天吃好点,不大累,逛逛小商品市场。

启动OpenManus任务,它自动进行任务拆解。首先,调用【google_search】搜索出几个与题目相关的网页。

打开浏览器,调用【browser_use】启动本地的浏览器,打开网页,开始爬取数据。

整合网页信息,进行合并汇总,调用本地工具【file_saver,python_execute,terminate】进行文件保存。

在当运行的目前下,会生成下面2个输出文件。

生成文件:义乌4天旅游行程.txt 文件,作为行程概览。

生成文件:义乌4天旅游行程.json 文件,作为详细的行程的内容输出。

大概一个流程下来,需要调用Deepseek的API有5次左右,0.5元的成本。

随着对 Deepseek 的深入使用和能力挖掘,希望能让AI真正成为我们实际工作的得力干将。

转载请注明出处:
http://blog.fens.me/deepseek-openManus-agent/

用Deepseek打造本地知识库

架构师的信仰系列文章,主要介绍我对系统架构的理解,从我的视角描述各种软件应用系统的架构设计思想和实现思路。

从程序员开始,到架构师一路走来,经历过太多的系统和应用。做过手机游戏,写过编程工具;做过大型Web应用系统,写过公司内部CRM;做过SOA的系统集成,写过基于Hadoop的大数据工具;做过外包,做过电商,做过团购,做过支付,做过SNS,也做过移动SNS。以前只用Java,然后学了PHP,现在用R和Javascript。最后跳出IT圈,进入金融圈,研发量化交易软件。

架构设计就是定义一套完整的程序规范,坚持架构师的信仰,做自己想做的东西。

关于作者:

  • 张丹,数据分析师/程序员/Quant: R,Java,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/deepseek-anythingLLM-knowledge/

前言

DeepSeek的火热程度一直升温,各行各业都尝试利用Deepseek解决自己行业的问题。由于每个行业的特点不同,业务逻辑,知识结构等差异非常大,因此通用的推理逻辑并不是真正地解决行业的具体的问题,我们就需要打造本行业专属的知识库,用行业专属的知识解决行业的问题。

本文我们就尝试搭建自己的知识库。

目录

  1. AnythingLLM安装基础环境
  2. 创建工作区,接入DeepSeek
  3. 创建本地知识库

1. AnythingLLM安装基础环境

我们基于 Deepseek 模型来打造本地知识库,首先就是把DeepSeek进行本地安装,详细的安装过程请参考文章 Deepseek快速本地安装

当我们安装 DeepSeek 安装后,接下来需要安装 AnythingLLM 软件。 AnythingLLM,是一款全栈AI应用程序,可集成人工智能的多种功能,像文档、聊天、使用人工智能代理,完全支持本地和离线操作。

官网网址:https://anythingllm.com/desktop,进入网址后,进入官网主页。下载对应的版本,我本地操作系统是windows11,直接下载Download for Windows(X64),下载软件为 AnythingLLMDesktop.exe。

下载完成后,进行安装AnythingLLM软件。安装完成后,打开软件,你会看到简洁直观的界面:

直接点击Get started,即可进入后续操作步骤:

我们点击,向右的箭头。

注:如果安装过程中出现报错,可能是系统缺少某些必备组件,需要根据错误提示,安装相应的组件,确保安装顺利进行。

2. 创建工作区,接入DeepSeek

成功安装AnythingLLM后,打开软件,首先要创建一个工作区。给工作区起一个名字,即可快速创建工作区。每个工作区,可以理解为一个独立的空间,我们可以对不同类型的知识进行分类管理,方便后续查找和使用。

创建好工作区,我们选择配置,左下角的工具图标,用于接入DeepSeek。

切换到配置界面,让DeepSeek和AnythingLLM能够协同工作。

首先,设置语言,从英文界面切换为中文界面。

然后,通过 AnythingLLM 把 DeepSeek接入。接入过程有2个种接入方案。

  1. 通过本地接入,调用本地已部署好的 Ollama,接入DeepSeek。
  2. 通过DeepSeek的官方API接入,直接远程调用官方的在线模型,接入DeepSeek。

1). 通过本地接入,通过调用本地已部署好的 Ollama,接入DeepSeek。

在 LLM首选项菜单 中,选择 LLM供应商,选择Ollama。然后,他会自动检测本地已启动的Ollama服务,选择deepseek-r1:17b。如果Ollama是正常安装的,没有自动改动过配置,默认端口什么的都不用修改。

如果Ollama Model中,下拉菜单中就没deepseek模型,可能是本地Ollama 服务没有启动,请使用

ollama run deepseek-r1:7b

命令启动Ollama服务。如果没有安装Ollama服务,请参考文章 Deepseek快速本地安装,先安装好Ollama和Deepseek。

记得点击保存,“save change”。

配置好后,我们就可以直接返回聊天界面,开始使用anythingLLM了。

2). 通过DeepSeek的官方API接入,通过远程调用官方的在线模型,接入DeepSeek。

另一种方式,如果只想本地使用Deepseek,可以跳过本步骤。

我们把LLM供应商,选择为DeepSeek,即可直接使用Deepseek官方的服务,需要配置API key。

要这个API key,需要登录Deepseek的官网,选择左上角的 API开发平台,进行登录。

登录后,点击左侧菜单的 API keys,创建自己的API key。然后,把这个key输入到之前anythingLLM的配置界面中。这个API服务,是需要付费使用的。价格为每百万输入 tokens 2 元,每百万输出 tokens 8 元,不贵。

但在页面顶端,我们可以看到提示,“当前服务器资源紧张,为避免对您造成业务影响,我们已暂停 API 服务充值。存量充值金额可继续调用,敬请谅解!”。也就是说,现在不开放API的充值了,所以这个路径暂时不通,后面等DeepSeek后面再开放,就可以这样使用了。

3. 创建本地知识库

上面成功把Deepseek入接后,直接返回聊天界面,问一下“你是谁”,就看到了DeepSeek-R1的回答。这样我们就让AnythingLLM和DeepSeek成功连接了。

接下来,让我们上传自己的知识库。在左边对话框,点击上传文件的按钮,选择文本文件上传。

我上传的文件为:段永平先生采访记录,文件下载,2万字全文.pdf

在文件先拖到左边的文件上传蓝色区域 “Click to upload or drag and drop”。上传完成后,把左边的文件拖到右边,进行文本向量转化,它能将输入的文本转化为对应的向量表示。在这个转化过程中,模型会深入分析文本的词汇、语句结构以及语义关联。这种向量表示并非简单的数值罗列,而是蕴含了文本的语义特征,为后续的各种操作提供了基础。

然后,我们回到对话窗口,找一个文件中,有持人问段永平的问题,请deepseek提问。“请问一个好赛道往往会随着竞争的加剧而进入低毛利的时期,那么在这样低毛利的一个时期下,创业者该如何应对呢?”

可以看到Deepseek的回答,总结很大气。

在对比,同样的问题,同一个本地模型,没有用到知识库的情况,Deepseek给的回复。为了区别,我们需要新建一个工作区,命名“测试2”。

两者的主要观点看起来差不多,但从表述上的感觉还是有不少差异,2位专家2个视角,这就是本地知识库带来的影响。下篇文件,我将对比不同模型,对于相同问题,在不同知识领域下的影响。

随着对 Deepseek 的深入使用和能力挖掘,希望能让AI真正成为我们实际工作的得力干将。

转载请注明出处:
http://blog.fens.me/deepseek-anythingLLM-knowledge/

Deepseek快速本地安装

架构师的信仰系列文章,主要介绍我对系统架构的理解,从我的视角描述各种软件应用系统的架构设计思想和实现思路。

从程序员开始,到架构师一路走来,经历过太多的系统和应用。做过手机游戏,写过编程工具;做过大型Web应用系统,写过公司内部CRM;做过SOA的系统集成,写过基于Hadoop的大数据工具;做过外包,做过电商,做过团购,做过支付,做过SNS,也做过移动SNS。以前只用Java,然后学了PHP,现在用R和Javascript。最后跳出IT圈,进入金融圈,研发量化交易软件。

架构设计就是定义一套完整的程序规范,坚持架构师的信仰,做自己想做的东西。

关于作者:

  • 张丹,数据分析师/程序员/Quant: R,Java,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/deepseek-start/

前言

2025年的春节,是个不一样的春节。Deepseek一声惊雷,让整个春节被全球媒体刷屏了。

不仅是国家层面的竞争格局发生了变化,同时,也让我们普通人拉平了与大模型大厂的差距,新的AI时代开始了。

目录

  1. Deepseek是什么
  2. 安装Ollama
  3. 安装Deepseek
  4. 安装webui界面

1. Deepseek是什么

Deepseek是什么?我们本地部署好后,让Deepseek自己来回答。

“深度求索人工智能基础技术研究有限公司(简称“深度求索”或“DeepSeek”),成立于2023年,是一家专注于实现AGI的中国公司。”

在命令行中,启动Deepseek,问:Deepseek是什么。

如果不想本地安装,也可以直接使用Deepseek的官方网站进行注册,使用在线的Deepseek服务:https://www.deepseek.com/

Deepseek官网就已经写明了,DeepSeek-R1已发布并开源,性能对标OpenAI o1正式版。那么,我们就本地部署DeepSeek-R1模型。

2. 安装Ollama

本地部署Deepseek是要用到 Ollama,它能支持很多大模型。Ollama官方网站:https://ollama.com/

选择DeepSeek-R1,就进入了模型页面。

DeepSeek-R1模型共有7个版本,分别对应不同的参数级别 1.5b,7b,8b,14b,32b,70b,671b。数值越大,参数越高,效果越好,但需要的硬件资源也会越高。我在本地电脑部署,就选个小点的7b模型。

我本地电脑环境为:

  • Win11,64位,x86架构
  • CPU: Intel i7-9750H 2.6G
  • 内存: 48G
  • 显卡:GPU NVIDIA Quadro T2000 24G

我们选Ollama软件包下载,OllamaSetup.exe。然后,按install进行安装。Ollama只能安装在C盘,不能修改路径,请小伙伴一定,留出足够多的空间来,至少20G,不然会影响到,滞后电脑的运行。

安装好后,就有了ollama的一个应用程序,运行后右下角度会出现 ollama 的图标。

3. 安装Deepseek

然后打开windows的命令行,输入

ollama run deepseek-r1:7b

下载deepseek-r1:7b模型,并进行安装,有4.7GB。下载大概要30分钟左右。然后,会自动运行,我们可以输入hello,和deepseek模型进行对话了。

如果关上了命令行窗口,重新打开,可以再次输入。

ollama run deepseek-r1:7b

这样就成功运行了,DeepSeek-R1的7b模型。

4. 安装webui界面

在命令行运行后,使用起来不太直观,我们可以再安装一个webui的界面,以更方便的方式进行使用。

4.1 安装python

这里选择基于python的open-webui开源界面工具。首先要安装python,open-webui要求python的最低版本要大于3.11,请先去python官网下载最新的版本,https://www.python.org/downloads/

我选择下载了python 3.12-8版本,当然也可以选择 3.13.1版本。

用python-3.12.8-amd64.exe文件进行安装,然后配置环境变量,

新打开一个命令行,输出python,启动python命令行,即安装成功。

然后,按ctrl+D 退出python命令行,安装 open-webui 的界面。

先安装pip工具,pip工具是用于python的工具包管理,使用pip来安装各种python 工具包。

python -m pip install --upgrade pip

4.2 安装open-webui

完成后,使用pip安装open-webui包。这个过程,要安装很多的包,如果要持续30分钟左右。

pip install open-webui

这里通常会错一个错误,就是缺少C++的一个编译库,需要下载Microsoft C++ 生成工具,打开连接
https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/

安装好后,打开visual studio installer工具,选择C++桌面开发,再安装一些工具包。

然后再执行安装open-webui,这样就成功安装了。

pip install open-webui

4.3 启动open-webui

然后,我们再通过命令行,输入open-webui serve命令,就可以启动open webui的界面。

open-webui serve

配置好登录信息后,webui的客户端就会自动连接上,我们本地启动的deepseek模型了。

然后就可以使用的更方便的webui进行与deepseek的对话了。

webui的后面程序日志,看到前后端的交互情况。

Deepseek的横空出世拉平了,我与大厂的距离,我们所有人都战在了同一起跑线。祝大家2025新年快乐!!

转载请注明出处:
http://blog.fens.me/deepseek-start/

如何确定数据分析目标

架构师的信仰系列文章,主要介绍我对系统架构的理解,从我的视角描述各种软件应用系统的架构设计思想和实现思路。

从程序员开始,到架构师一路走来,经历过太多的系统和应用。做过手机游戏,写过编程工具;做过大型Web应用系统,写过公司内部CRM;做过SOA的系统集成,写过基于Hadoop的大数据工具;做过外包,做过电商,做过团购,做过支付,做过SNS,也做过移动SNS。以前只用Java,然后学了PHP,现在用R和Javascript。最后跳出IT圈,进入金融圈,研发量化交易软件。

架构设计就是定义一套完整的程序规范,坚持架构师的信仰,做自己想做的东西。

关于作者:

  • 张丹,数据分析师/程序员/Quant: R,Java,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/data-analysis-goal/

前言

数据分析核心要解决业务问题,通过数据发现规律,驱动业务创新发展。那么如何确定一个核心的分析目标就变得尤为重要,如果目标找的不对,那么就会一直原地打转。花费了无数时间,也不过是徒劳。

目录

  1. 如何设定分析目标
  2. 目标分解
  3. 人是最核心的

1. 如何设定分析目标

设定数据分析目标,是为了能让数据能更好的落地。那么在设计目标前,需要先理解数据落地是什么,请参考文章怎么理解数据分析落地

如何设定分析目标?首先,需要与业务团队紧密合作,了解他们的需求和目标。确保数据分析的目标与实际业务目标紧密相关,以便分析结果能够为业务决策提供有意义的指导。然后,具体定义需要解决的分析问题。问题应具体明确,具备可操作性。

目标,最好是一句话能说明白,到底要做什么,能达到什么样的结果。

在不同场景下,我们定义的分析目标是不一样的。

  • 量化投资,通过程序算法可直接变现。
  • 电商商品推荐,增加客户购买效率。
  • 地图导航:帮助用户规划路线
  • 风险识别:精准发现风险问题
  • 医疗影像识别:给出辅助诊断结果
  • 自动驾驶:帮助用户自动开车

在每个生活的领域中,都已经存在大量的数据分析的案例。

那么,在你做的数据分析的工作,你能用一句话说清楚吗,数据分析到底是为了什么?这个点上,大家通常都是迷茫的。可能是为了发论文,可能是领导布置的工作,可能是照搬之前形成的模板…

所以怎么把思路改变,怎么能让工作变得有意义,就需要从定义一个好的目标开始。然后,命中靶心!

2. 目标分解

目标一定是明确的,通过目标分解,可以把一个宏大目标分解成多少小的目标来执行,最终实现最初的目标。

量化投资,通过程序算法可直接变现,以一个金融市场交易策略来举例。

我们要达成 “通过程序算法可直接变现” 的目标,就需要把目标进行分解,变成可操作的任务。从而把一个大的抽象的目标,变成多个小的更具体的目标。

  1. 设定目标:在金融市场上,分析关税对于大宗商品的影响,从而进行期货交易实现套利。
  2. 定义逻辑和输出结果:分析受到关税影响的商品,以及进出口的变化,结合期货市场的价格和持仓,找到合适的交易买卖点,生成交易信号。
  3. 技术方法:以均线策略和布林线策略为核心,结合基本面的关税数据,通过R语言编写程序,计算出交易信号。
  4. 回测验证:把交易信号放到回测程序中,通过历史数据验证交易是否赚钱,计算收益率,夏普率,胜率等指标,买卖滑点,资金容量等
  5. 实盘验证:金融白银的投入到策略中,策略出什么信号,就买什么票,直到实现盈利。

然后,再近一步拆解,拆成更细粒度的,通过数据能体现的。

  1. 采集国内期货市场数据,取1分钟周期的数据,提取数据字段包括交易时间、开高低收价格、持仓量、交易金额。
  2. 以跨期交易为核心统计套利思路,叠加关税变化在相同商品,不同合约的影响,找到变化大小的规律。
  3. 以均线策略和布林线策略为核心,结合基本面的关税数据,计算出交易信号,并考虑手续费、滑点等影响因素。
  4. 构建回测功能函数,支持按手交易,或者按资金体量交易,能够进行收益率,夏普率,胜率等指标计算。

通过一层一层的分析,在我们梳理业务逻辑并结合数据,就可以把最初的目标,逐步分解成可执行小任务小目标,从而完成整个项目方案。

当然,对于新的数据分析方向来说,你可能不清楚怎么分解更合理,这需求大量来补充行业经验和知识。人的经验很重要。

3. 人是最核心的

数据分析核心要解决业务问题,通过数据发现规律,为业务服务,产生价值,获得收益,从而实现数据落地。

整个一套流程下来人是最核心的。人需要理解业务,人需要发现规律,人需要把业务和数据连接,人需要编写逻辑程序,人需要验证逻辑,人需要验证价值。

大模型虽然可以辅助人来做其中的一部分或者多部分工作,但是还远远达不到人的能力水平。每个都是个性化的个体,有着不是生长环境,不同的工作经历,掌握不同专业技能,因此我们每个看待同一件事情的角度,都是不一样的。这种不一样的东西,才是创新的原动力。

希望每一位数据分析师,都能发挥出自己的聪明才智,实现自己的目标突破,完成数据落地。

转载请注明出处:
http://blog.fens.me/data-analysis-goal/