【注意】最后更新于 2年前 ,文中内容可能已过时,请谨慎使用。
和 AI 对话一段时间,受到很大的启发。
在 AI 辅助下,日常开发,时间和项目管理,效率都有了明显的提升。相信 AI 将在生活中扮演更多角色,影响自己的行为习惯。
网上看到已经有大牛,用 AI 实现了无代码开发,从项目框架设计,功能开发和测试发布,都由 AI 一步步回答实现,例如 mygptreader 。
受此启发,在尝试开发过程中,尽量使用 AI 来完成,功能的设计和开发。
例如,使用 swift 开发一个 snippet 转换插件过程中,只需负责提需求,验收 AI 代码可用性,然后集成到脚本运行就好。
这样以来,任务重心偏向了需求挖掘,功能设计,代码验收上。做这些工作,更多体现在领导和管理上,如何扮演好新的角色至关重要。
emacs 拥有丰富的插件,在 org-AI
的加持下, tj3
项目管理,博客写作 ox-hugo
插件, plantuml
插件, 代码块
插件等,都能有效的提升生产力。经过这次 AI 浪潮洗礼,将 emacs 训练成高效能七个习惯的执行者的愿望,也许指日可待了。
使用 AI 制作 prompt snippets 提升 chatgpt 沟通 使用脚本收集流行的 prompt 库,批量转换 snippet, 例如:alfred snippet , emacs snippet 等。
通过这个简单脚本的开发,借助 AI 尝试无代码编程。在需求,设计,编码,调试实战中,工作中心偏设计管理,尽量在 emacs 中探索可提升产出的技术栈,学习积累新的开发习惯。
技术设计:采用 swift 语言, JSON
库解析 propmt 源数据转为目标 snippt 格式。
开发工具:借助 emacs 插件提升产出效率。例如:利用 org-swift
plantuml
快速设计,测试等。
分析数据模型 prompt 数据源样例
这段 json 片段来自微信机器人 chat-on-wechat 中的角色插件,插件中整理很多关于角色 prompt。
主要功能:例如在片段的角色的描述,在微信中和 AI 聊天时,只要输入 佛祖
即可。
制作 snippet 会用到 title , descan remark 字段。
1
2
3
4
5
6
7
8
9
10
{
"title" : "佛祖" ,
"description" : "从现在开始你是佛祖,你会像佛祖一样说话。你精通佛法,熟练使用佛教用语,你擅长利用佛学和心理学的知识解决人们的困扰。你在每次对话结尾都会加上佛教的祝福。" ,
"descn" : "从现在开始你是佛祖,你会像佛祖一样说话。你精通佛法,熟练使用佛教用语,你擅长利用佛学和心理学的知识解决人们的困扰。你在每次对话结尾都会加上佛教的祝福。" ,
"wrapper" : "您好佛祖,我:\"%s\"" ,
"remark" : "扮演佛祖排忧解惑" ,
"tags" : [
"interesting"
]
} ,
Copy snippet 目标结构样例: emacs snippet 格式
这段显示的 or-ai
的 snippet 结构展示,作为脚本的输出格式。
snippet 的 key 使用 prompt 名称的中文全拼缩写。
例如:将 佛祖
prompt 转为 snippet 效果:
1
2
3
4
5
6
7
8
9
10
# -*- mode: snippet -*-
# name: 佛祖
# key: fz
# --
#+begin_ai markdown :max-tokens 250
${1:[SYS]: ${2:从现在开始你是佛祖,你会像佛祖一样说话。你精通佛法,熟练使用佛教用语,你擅长利用佛学和心理学的知识解决人们的困扰。你在每次对话结尾都会加上佛教的祝福。}
}[ME]: 您好佛祖,我:
$0
#+end_ai
Copy emacs + AI 开发模式 在 org 中进行 swift 语言开发,主要用到一下插件:
org-ai
在 org 中 AI 实时对话
org-swift
,支持 swift 脚本 org-babel ,在 org 中轻松运行脚本,便于测试验收代码,类似 swift playgroud 。
采用字符串的形式,处理格式转换,然后写入目标文件保存到文件
用变量模拟 json 数据 采用多行字符串组装要转换的格式 使用 print 验证字符串结果 1
2
3
4
5
6
7
8
9
10
11
12
13
14
var name = "miao"
var key = "mn"
var prompt = "猫娘"
let snippet = """
# -*- mode: snippet -*-
# name: \( name )
# key: \( key )
# --
#+begin_ai markdown :max-tokens 250
${1:[SYS]: ${2: \( prompt ) }
}[ME]: $0
"""
print ( snippet )
Copy 打印结果:
1
2
3
4
5
6
7
8
# -*- mode: snippet -*-
# name: miao
# key: mn
# --
#+begin_ai markdown :max-tokens 250
${1:[SYS]: ${2:猫娘}
}[ME]: $0
Copy 获取中文全拼缩 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import Foundation
func PYFirst ( string : String ?, _ allFirst : Bool = false )-> String {
var py = "#"
if let s = string {
if s == "" {
return py
}
let str = CFStringCreateMutableCopy ( nil , 0 , s as CFString )
CFStringTransform ( str , nil , kCFStringTransformToLatin , false )
CFStringTransform ( str , nil , kCFStringTransformStripCombiningMarks , false )
py = ""
if allFirst {
for x in ( str ! as String ). components ( separatedBy : " " ) {
py += PYFirst ( string : x )
}
} else {
py = ( str ! as NSString ). substring ( to : 1 ). uppercased ()
}
}
return py
}
//调用示例,返回#
var s : String ?
//PYFirst(string:s)
s = "中华人民共和国@hi wor \r\n ld."
//调用示例,返回ZHRMGHGW
let result = PYFirst ( string : s , true )
//调用示例,返回Z
let result2 = PYFirst ( string : s )
print ( "结果1: \( result ) \n 结果2: \( result2 ) " )
Copy 1
2
结果1: ZHRMGHGW
result2: Z
Copy 脚本的核心功能和运用 使用 JSONEncoder 解析本地的 json 文件,转为 model 对象。
目前支持三个工具的 snippet
alfred snippet
转为 json 文件集合,需要手动压缩成 .zip
,然后命名为 .alfredsnippets
如果安装无效,尝试以下方式安装
在alfred snippet 新建一个snippet 集合,然后导出为 alfredsnippets
包 再使用 zip 工具不解压缩的情况下,将生成的 json 导入到 包中。 双击包,成功导入到 alred snippet 中。 emacs-snippet
auto-gpt yaml模板
使用方法:python -m auto-gpt –settings-file role.yaml
生成chatfred 的aliases
安装方法:把chatfred的内容拷贝到chatfred 配置项中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public static func toSnippets ( json : String ) -> String ? {
// 使用 JSONEncoder 解析本地的json 文件,转为model 对象。
let url = URL ( fileURLWithPath : json )
let data = try ! Data ( contentsOf : url )
let prompt = try ! JSONDecoder (). decode ( Prompt . self , from : data )
prompt . roles . map { role in
// 保存为json 文件
var wrapper = role . wrapper
wrapper . replaceAll ( matching : " \n .*$" , with : "" )
do {
// alfred -----
let jsonEncoder = JSONEncoder ()
let alfred = SnippetModel ( uid : UUID (). uuidString ,
name : role . title ,
keyword : role . title . pinyin . lowercased (),
snippet : role . descn )
let alfredM = AlfredModel ( alfredsnippet : alfred )
jsonEncoder . outputFormatting = . prettyPrinted
let resultData = try jsonEncoder . encode ( alfredM )
let filename = alfred . name + " [ \( alfred . uid ) ]"
let newfile = "/Users/boyer/Desktop/propmt/ \( filename ) .json"
let url = URL ( fileURLWithPath : newfile )
try resultData . write ( to : url , options : . atomic )
// emacs-snippet ---把字符串保存为文件 ---
let snippet = """
# -*- mode: snippet -*-
# name: \( role . title )
# key: \( alfred . keyword )
# group: \( role . tags . first ?? "" )
# --
#+begin_ai markdown :max-tokens 250
[SYS]: \( role . descn )
[ME]: \( wrapper )
$0
#+end_ai
"""
let snippetfile = ".doom.d/snippets/org-mode/ai/ \( alfred . name ) "
let emacsnippet = Path . home + snippetfile
try ! emacsnippet . write ( snippet )
//auto-gpt -----
//使用方法:python -m auto-gpt --settings-file role.yaml
let auto_gpt = """
ai_goals:
- \( role . remark )
ai_name: \( role . title )
ai_role: \( role . descn )
"""
let autofile = ".dotfiles/auto-gpt/roles/ \( role . title ) .yaml"
let autogpt = Path . home + autofile
try ! autogpt . write ( auto_gpt )
//生成chatfred 的aliases
//使用方法:把chatfred的内容拷贝到chatfred 配置项中。
let alfred_aliases = role . title . pinyin . lowercased () + "=" + role . descn + "; \n "
let fred = "Desktop/chatfred.txt"
let chatfred = Path . home + fred
// try! chatfred.append(alfred_aliases)
let fileHandle = try FileHandle ( forWritingTo : chatfred . url )
fileHandle . seekToEndOfFile ()
if let data = alfred_aliases . data ( using : . utf8 ) {
fileHandle . write ( data )
}
fileHandle . closeFile ()
} catch {
print ( "生成失败" )
}
}
return "生成成功"
}
Copy TODO ob-babel 导入第三库遇到的问题问题1. org-mode 9.6.1 在使用 var 传递变量失败
在导入第三方库时,通过 ai 提供了几种方法,验证都无效
使用:var myLibrary=“Regex” 在swift 块中,import $myLibrary 使用:var loadpath ="" 源码路径,在 emacs-elisp 块中夹带 load-path 方式 在 swift 块中使用 load-file 的方式加载 swift 文件,然后使用库方法 三种方法在验证之后都是无效的。
1
2
( setq load-path ( cons includepath load-path ))
( load-file ( concat includepath "Regex.swift" ))
Copy 1
2
3
4
5
6
7
8
9
let myString = $ myString // 将Org-mode代码块中的myString变量赋值给Swift变量
print ( "声明的变量: \( myString ) " )
let pattern = "T.*T"
let regex = try ! Regex ( pattern )
if regex . matches ( myString ) {
print ( "Regex matched!" )
} else {
print ( "Regex didn't match." )
}
Copy 1
2
3
4
5
<stdin>:1:16: error: cannot find '$myString' in scope
let myString = $myString // 将Org-mode代码块中的myString变量赋值给Swift变量
<stdin>:5:10: error: value of type 'Regex<AnyRegexOutput>' has no member 'matches'
if regex.matches(myString) {
~~~~~ ^~~~~~~
Copy 1
2
3
4
5
6
import Foundation
var text = "test \n \" %s \" "
print ( "kkkk== \( text ) " )
//text.removeLast(4)//replacingOccurrences(of: "\"%s\"", with: "")
text . replaceAll ( matching : "%.*$" , with : "" )
print ( "jjjj== \( text ) " )
Copy 1
2
3
<stdin>:5:6: error: value of type 'String' has no member 'replaceAll'
text.replaceAll(matching: "%.*$", with: "")
~~~~ ^~~~~~~~~~
Copy