无题

给 AI 添加角色

在互联网的宣传下,很多人对人工智能(AI)抱有很高的期望,认为它无所不能,能够帮助我们“做对”各种事情。然而,实际情况往往让人失望,AI 并没有那么“聪明”,它更像是一个具有语言交互能力的“数据仓库”。我们可以把 AI 想象成一个巨大的图书馆,里面存放着各种各样的信息。当我们需要查询某个信息时,首先要确定这个信息在哪一本书(数据表)里,然后通过特定的查询语言(SQL 语句)来找到我们需要的内容。

在使用 AI 的过程中,确定“数据表”的过程其实就是给 AI 定义一个角色。一旦我们明确了 AI 的角色,它就会基于这个角色相关的“数据仓库”,提供与我们需求相关的信息。比如,如果你需要 AI 帮助你在一个项目中添加某个功能,你可以告诉 AI:“你是一个资深的后台开发,请帮我在这个项目中添加某个功能。” 这样,AI 就会基于它所“知道”的后台开发知识,提供相关的建议和代码。

这样做的一个重要原因是:AI 的“记忆力”是有限的,如果上下文太长,它可能会“记不住”或者“理解错”。另外,我们使用 AI 是为了更快地获取我们需要的信息,如果 AI 返回一大堆无关的内容,对我们来说也没有什么参考价值。

所以,在使用 AI 时,明确告诉它你需要它扮演的角色,这样它才能更准确地提供你想要的信息。

把切换角色体现在代码中

user 它既可以获取 workspace 相关的信息,也可以获取 application 相关的信息。按照之前的写法,我们会实现以下”AI 可理解的模型”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export class User {
constructor(private backendUser: BackendUser) {
this.id = this.backendUser.id;
this.currentWorkspace = new Workspace(this.backendUser.currentWorkspace);
}

id: number;

// 工作区上下文
currentWorkspace: Workspace;
workspaces!: Workspaces;
isWorkspaceAdmin(): boolean {}

// 应用上下文
applications!: Applications;
isApplicationAdmin(): boolean {}

// 报表上下文
reports: Reports;
editReport(): void {}
createReport(): void {}
}

这样的写法,其实就是我们平常所说的“过长类”,对 AI 来说,就是“过长的上下文”。而 AI 在长上下文下,很容易产生“理解偏差”。这个现象可以说是“代码写给机器看,但是写给人看”的具体例证。

造成这个现象的根本原因是,我们把不同业务上下文的角色职责,全部交给了同一个实体。我们要解决这个问题,就是去定义不同的角色,将职责分离开来。就好像为了平衡工作与生活,我们需要在白天扮演社畜,晚上扮演家人一样。

包裹实体,建立角色

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
public class Reader {
private User user;
private List<Subscription> subscriptions;

public Reader(User user) {
...
}

// 订阅上下文
public boolean canView(Content content) {
...
}
}


public class Buyer {
private User user;

private List<Order> orders;
private List<Payment> payments;

public Buyer(User user) {
...
}

// 订单上下文
public void placeOrder(Column column) {
...
}
}


public class Contact {
private User user;

private List<Friendship> friends;
private List<Moments> moments;

public Contact(User user) {
...
}

// 社交上下文
public void make(Friendship friend) {
...
}

public void break(Friendship friend) {
...
}
1
2
3
4
5
User user = repository.findById(....);

Buyer buyer = repository.asBuyer(user);
Reader reader = repository.asReader(user);
Contact Contact = repository.asContact(user);