Compare commits
827 Commits
v0.1.14
...
feat/ibm-m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cd79b7345 | ||
|
|
377793af42 | ||
|
|
56cea8fb93 | ||
|
|
9933d8f880 | ||
|
|
12b0cf6100 | ||
|
|
66698503b8 | ||
|
|
ec2967c362 | ||
|
|
4ae07468f3 | ||
|
|
6193eb13fa | ||
|
|
55cd15bfc6 | ||
|
|
5f46ff8836 | ||
|
|
cdfbd5f62b | ||
|
|
b43f3987ec | ||
|
|
240527d06c | ||
|
|
276cb7b7e8 | ||
|
|
048aa6cbcc | ||
|
|
fa9949b9d0 | ||
|
|
500072d855 | ||
|
|
04bcfa6e2d | ||
|
|
26afee9bed | ||
|
|
f29f4abdd7 | ||
|
|
4589d6fe9d | ||
|
|
201e652fa2 | ||
|
|
8bc07e6071 | ||
|
|
6baaad045a | ||
|
|
74c1703310 | ||
|
|
a921828e51 | ||
|
|
e1fd83e6a7 | ||
|
|
7d68e287cc | ||
|
|
f39a975e20 | ||
|
|
b8a3c29745 | ||
|
|
9cd4ff05c9 | ||
|
|
4687779702 | ||
|
|
8731915330 | ||
|
|
093259389e | ||
|
|
6bcb3d1080 | ||
|
|
71a217b210 | ||
|
|
b98256e434 | ||
|
|
40f81aecf5 | ||
|
|
d1737a96fb | ||
|
|
84f48c465d | ||
|
|
60efcad481 | ||
|
|
53a9f107ca | ||
|
|
6fa2b89831 | ||
|
|
d72ebb9bb8 | ||
|
|
81ae07abdb | ||
|
|
6d20ba70a1 | ||
|
|
67f55bae2c | ||
|
|
9b59de1720 | ||
|
|
798d16a6c6 | ||
|
|
c9152f2af8 | ||
|
|
24b09e97cd | ||
|
|
a6b7295092 | ||
|
|
725d159e44 | ||
|
|
ef21da15e6 | ||
|
|
de5d2eaa9b | ||
|
|
e2badaa4c6 | ||
|
|
916dec2418 | ||
|
|
7f387dd7c3 | ||
|
|
6534a909d6 | ||
|
|
b149bd4149 | ||
|
|
49138c6e37 | ||
|
|
258b22f5bc | ||
|
|
b887c5cf3c | ||
|
|
42871d9ffc | ||
|
|
a7696d5aed | ||
|
|
02718e291b | ||
|
|
76c4f2a2b4 | ||
|
|
fbc6a10f2e | ||
|
|
5d8f8cbc79 | ||
|
|
0dfe3bcb0a | ||
|
|
3f81383285 | ||
|
|
e8a49e7687 | ||
|
|
ed48efb9aa | ||
|
|
c3291b967b | ||
|
|
92e867010c | ||
|
|
5059aef574 | ||
|
|
c50d62b82f | ||
|
|
f46a12b3b4 | ||
|
|
dd0b622826 | ||
|
|
835eb9fbea | ||
|
|
8cb10f9fcc | ||
|
|
30e26c9e35 | ||
|
|
01329a01ab | ||
|
|
0e11b33f6e | ||
|
|
5113bca025 | ||
|
|
71c5972fc7 | ||
|
|
ba55160d6b | ||
|
|
24e973d792 | ||
|
|
96427c1dd2 | ||
|
|
f15d5cbb64 | ||
|
|
c8a5a3e32e | ||
|
|
32fdd11c93 | ||
|
|
7f830b4f43 | ||
|
|
d6c57402cf | ||
|
|
42bea00184 | ||
|
|
5a6b0ff398 | ||
|
|
1b57bc0c75 | ||
|
|
96544009f5 | ||
|
|
44c8765add | ||
|
|
bc31019b67 | ||
|
|
ff16348d4c | ||
|
|
7310f4d85b | ||
|
|
ac331504e9 | ||
|
|
6823f76ff4 | ||
|
|
c3ac3219fe | ||
|
|
104ef7a0c2 | ||
|
|
2bbf8ed8a8 | ||
|
|
5dc6644ac7 | ||
|
|
9c0f97eaf7 | ||
|
|
164e7895bf | ||
|
|
fb46fb9ca3 | ||
|
|
effb7efc37 | ||
|
|
f5098e7e45 | ||
|
|
b15d632308 | ||
|
|
e534efa3e9 | ||
|
|
8001314718 | ||
|
|
e91ac4c5ad | ||
|
|
e19bdcb97d | ||
|
|
b8aa46a767 | ||
|
|
ab79ee32fd | ||
|
|
8d9c49a281 | ||
|
|
e659b60d8b | ||
|
|
7987bfee39 | ||
|
|
b6075f1a97 | ||
|
|
9820a69443 | ||
|
|
753118687d | ||
|
|
35e234ed6e | ||
|
|
2d54b096af | ||
|
|
493f046c03 | ||
|
|
3b6d1838b4 | ||
|
|
769ab940ed | ||
|
|
498a9e6e68 | ||
|
|
699be4887c | ||
|
|
854c58ded7 | ||
|
|
a19a4a5556 | ||
|
|
59e51f18fd | ||
|
|
7d981ba8ce | ||
|
|
6dad33f47c | ||
|
|
18c3925fa3 | ||
|
|
000e2666fb | ||
|
|
91ff331fec | ||
|
|
e3c7c0185d | ||
|
|
405650840e | ||
|
|
1bd188e0d2 | ||
|
|
9de7aa6377 | ||
|
|
d4c0a4248c | ||
|
|
c4167a5517 | ||
|
|
c055c35361 | ||
|
|
a318a226de | ||
|
|
e88cb2fea6 | ||
|
|
0ab072a95e | ||
|
|
5e8322b272 | ||
|
|
5a3b888f43 | ||
|
|
d7473edb41 | ||
|
|
d125c85a2b | ||
|
|
b46e663778 | ||
|
|
2787c9b0ef | ||
|
|
e77442cf34 | ||
|
|
322780a5f3 | ||
|
|
a54d34ea5b | ||
|
|
bc793749a5 | ||
|
|
a9916940ef | ||
|
|
b7f4931de5 | ||
|
|
327b728bef | ||
|
|
a9510eec88 | ||
|
|
d6db557f50 | ||
|
|
5ae56e3f72 | ||
|
|
1c9ebb59b1 | ||
|
|
f520ceeb0d | ||
|
|
0df4d2fd4b | ||
|
|
596491d932 | ||
|
|
72fb109147 | ||
|
|
40b336d2a5 | ||
|
|
5958df71a2 | ||
|
|
26d9af8367 | ||
|
|
cdaf2d41c7 | ||
|
|
d9ee104167 | ||
|
|
0b9eeb7cdb | ||
|
|
9b558ddc51 | ||
|
|
b857afe45b | ||
|
|
1d77c8de10 | ||
|
|
503f3a6372 | ||
|
|
d2fab55561 | ||
|
|
b955416458 | ||
|
|
18a2722e4d | ||
|
|
c7e8d55926 | ||
|
|
48698bf0b7 | ||
|
|
f79b3fc322 | ||
|
|
0b9e753c2f | ||
|
|
5b3f7be1c4 | ||
|
|
f2208f5f8e | ||
|
|
79b5248b83 | ||
|
|
d4791bef28 | ||
|
|
d861cb0d74 | ||
|
|
67f19f79c2 | ||
|
|
5f359b14f7 | ||
|
|
cda1900b14 | ||
|
|
c8c0a89dc6 | ||
|
|
9a10cc15f4 | ||
|
|
345f1eacde | ||
|
|
fa937bf3a7 | ||
|
|
172758020c | ||
|
|
5ff178084e | ||
|
|
c012e0ff8d | ||
|
|
f777c1c2e0 | ||
|
|
782ce22d99 | ||
|
|
f5246039e5 | ||
|
|
4736604b4d | ||
|
|
09cba0135e | ||
|
|
8119edb495 | ||
|
|
17bffb0803 | ||
|
|
cbe139fced | ||
|
|
946d8567fe | ||
|
|
7b5d5bdeef | ||
|
|
a1551bcf2b | ||
|
|
5495825b1d | ||
|
|
6e36f84cc6 | ||
|
|
cddf2d8f7c | ||
|
|
5f17e35c5a | ||
|
|
231a833ad0 | ||
|
|
a870295d42 | ||
|
|
ddda8f6bda | ||
|
|
bf7372fefa | ||
|
|
3451b6fc7a | ||
|
|
dbf2570353 | ||
|
|
d0707fac91 | ||
|
|
35ebdd6022 | ||
|
|
92a77e5cac | ||
|
|
a2922c9ad5 | ||
|
|
9f9b52dd26 | ||
|
|
2482c7ab68 | ||
|
|
7fdabda97e | ||
|
|
7306414de7 | ||
|
|
97d7bfb52a | ||
|
|
9f85a2a011 | ||
|
|
ab47d276db | ||
|
|
44e38b1d5e | ||
|
|
e9fa2bb556 | ||
|
|
183f466ac4 | ||
|
|
cc7b7e2b79 | ||
|
|
a17fa70b1b | ||
|
|
7b63b6f485 | ||
|
|
ed5d81fa1a | ||
|
|
c2d12b2de2 | ||
|
|
8966dc2f2f | ||
|
|
59ab1ef9f4 | ||
|
|
227cca00a2 | ||
|
|
16dab8e583 | ||
|
|
1c97b916d9 | ||
|
|
94b52cfd87 | ||
|
|
82b1db1711 | ||
|
|
638a8f03f0 | ||
|
|
dbce944934 | ||
|
|
f1ad137fb7 | ||
|
|
5eb1cff9b5 | ||
|
|
b074138e39 | ||
|
|
6ca051e5f3 | ||
|
|
fd87d930a7 | ||
|
|
95a9691a8b | ||
|
|
e2d6e2649e | ||
|
|
d3ff1bf01d | ||
|
|
d68b8cf6e4 | ||
|
|
6615ab2fba | ||
|
|
5e83a36009 | ||
|
|
51ee483e9d | ||
|
|
62f5b2fb2e | ||
|
|
6583f31459 | ||
|
|
217f5fc5ac | ||
|
|
297dc93fb4 | ||
|
|
86c6760f58 | ||
|
|
498e96a419 | ||
|
|
c0c59dc932 | ||
|
|
f3b3d321e5 | ||
|
|
67e4433dc2 | ||
|
|
4a7ae8df71 | ||
|
|
09f92122d5 | ||
|
|
8118b7b7d6 | ||
|
|
c93b85ac53 | ||
|
|
6378f6caec | ||
|
|
d824db82a3 | ||
|
|
de6b597eff | ||
|
|
6111d05219 | ||
|
|
f83c91d612 | ||
|
|
c8f360414e | ||
|
|
fa4393d77e | ||
|
|
25c314befc | ||
|
|
2fe79e68cd | ||
|
|
37d05a2365 | ||
|
|
0111d261a4 | ||
|
|
0a23e1dc13 | ||
|
|
ef5ff71346 | ||
|
|
1697b4cacb | ||
|
|
6b4710a8d1 | ||
|
|
6f2a8f08ba | ||
|
|
4e6abf596d | ||
|
|
9018e2ab6a | ||
|
|
99d023c5f3 | ||
|
|
da7d8256eb | ||
|
|
88bffaa0d0 | ||
|
|
1159140d9f | ||
|
|
5ac7050f7a | ||
|
|
8b513de64c | ||
|
|
144e6d203f | ||
|
|
2d2154ed65 | ||
|
|
2d086ab596 | ||
|
|
776c67cc0f | ||
|
|
78ef490646 | ||
|
|
4da5cc9778 | ||
|
|
6930656897 | ||
|
|
349753a013 | ||
|
|
f53a3a00e1 | ||
|
|
e2113fe417 | ||
|
|
f9288295e6 | ||
|
|
fcc57f2fc0 | ||
|
|
5cb6ee9eeb | ||
|
|
b38f0825e7 | ||
|
|
f51e94dede | ||
|
|
47bf93d291 | ||
|
|
41fd1c6124 | ||
|
|
be1b9a3994 | ||
|
|
61a196394b | ||
|
|
5b442e4350 | ||
|
|
c9920b9823 | ||
|
|
2faa2dbddb | ||
|
|
76607062f0 | ||
|
|
a8cac9b7e9 | ||
|
|
dfacc8832f | ||
|
|
93f643f851 | ||
|
|
cbf5d548be | ||
|
|
6946b89e17 | ||
|
|
dc4911b1ca | ||
|
|
6ad218f9a0 | ||
|
|
36efa172ee | ||
|
|
a7a2dfd296 | ||
|
|
7baaeacac3 | ||
|
|
021f2eb8a1 | ||
|
|
cb720143c7 | ||
|
|
731de2ff31 | ||
|
|
24e28da203 | ||
|
|
bde0a3e99c | ||
|
|
0415b9982b | ||
|
|
99ada42d97 | ||
|
|
ee32d36312 | ||
|
|
ef928ee3cb | ||
|
|
c66559345f | ||
|
|
3ad95d50d4 | ||
|
|
bc7f601f84 | ||
|
|
e8cbdb7881 | ||
|
|
b0c2b15a3e | ||
|
|
c0f04bbb37 | ||
|
|
c320fc655e | ||
|
|
ac2815c781 | ||
|
|
dd8a199e99 | ||
|
|
161c4a6856 | ||
|
|
67b04b30bf | ||
|
|
7696b45fc3 | ||
|
|
641921eb6c | ||
|
|
a02d2fb93e | ||
|
|
b93632a53a | ||
|
|
09938641cd | ||
|
|
7acf0b2107 | ||
|
|
4eb4073661 | ||
|
|
7b53457ef3 | ||
|
|
691b094a40 | ||
|
|
68e9e54c88 | ||
|
|
d0d99125c4 | ||
|
|
129000d01f | ||
|
|
47f9d026dd | ||
|
|
b75b0b5552 | ||
|
|
3dd6249f1e | ||
|
|
8451113039 | ||
|
|
a79b216875 | ||
|
|
52217c2f63 | ||
|
|
7edacf6e24 | ||
|
|
58558a1950 | ||
|
|
1607c85ae5 | ||
|
|
a6ff342948 | ||
|
|
d2eb54ebf8 | ||
|
|
a41bd18599 | ||
|
|
bb64c80964 | ||
|
|
2fb56f1f9f | ||
|
|
35676fe2f5 | ||
|
|
81ed6f177e | ||
|
|
4bcd1df6bb | ||
|
|
6fae56dd60 | ||
|
|
430f0e9013 | ||
|
|
d7f080a978 | ||
|
|
5d18f73654 | ||
|
|
57fc079267 | ||
|
|
706f4cd74a | ||
|
|
2e3646cc96 | ||
|
|
844cc515d5 | ||
|
|
f47904134b | ||
|
|
d72b00af3c | ||
|
|
bd053a98c7 | ||
|
|
c18208ca59 | ||
|
|
acbe5af8ce | ||
|
|
c81146505a | ||
|
|
6b9a1d4040 | ||
|
|
508fbd49e9 | ||
|
|
e18a6c6bb8 | ||
|
|
16237ef393 | ||
|
|
5332d02f36 | ||
|
|
7258120a0d | ||
|
|
8b7bc69ba1 | ||
|
|
5a807eb93f | ||
|
|
130682c93b | ||
|
|
02e29e4681 | ||
|
|
6943eb4463 | ||
|
|
939a18a4d2 | ||
|
|
ccbe415315 | ||
|
|
511af98dea | ||
|
|
a9d94112f5 | ||
|
|
1bca6029fe | ||
|
|
c027aa8bf6 | ||
|
|
ce7d86e0df | ||
|
|
5dfaf866c9 | ||
|
|
5b66e87621 | ||
|
|
851dd0f84f | ||
|
|
2188358f13 | ||
|
|
10997dd175 | ||
|
|
da9cc5f097 | ||
|
|
c005ec3f78 | ||
|
|
6018fe5872 | ||
|
|
bf0e70999e | ||
|
|
175d5b3dd6 | ||
|
|
9e61b8325b | ||
|
|
c4d76cde8f | ||
|
|
9c44fd8c4a | ||
|
|
f9f8c8f336 | ||
|
|
0fb3ccb9e9 | ||
|
|
0e5fd0be2c | ||
|
|
1b45daee49 | ||
|
|
9f384e3fc1 | ||
|
|
377f919d42 | ||
|
|
e6445afac5 | ||
|
|
095015d397 | ||
|
|
614183cbb1 | ||
|
|
0bc92a284d | ||
|
|
d3b6640b4a | ||
|
|
a1a48888c3 | ||
|
|
bb622bf747 | ||
|
|
946c56494e | ||
|
|
2a0e21ca76 | ||
|
|
ea893432e8 | ||
|
|
bf40956491 | ||
|
|
48948e1217 | ||
|
|
27412c89dd | ||
|
|
56f1d24e9d | ||
|
|
ab066a11a8 | ||
|
|
e35e81e554 | ||
|
|
551e48da4f | ||
|
|
21ce0aa17e | ||
|
|
2d6f2830e1 | ||
|
|
24ed8a2549 | ||
|
|
a336381849 | ||
|
|
208c3a780c | ||
|
|
1e112fa50a | ||
|
|
38fc5510ed | ||
|
|
1a1f4717aa | ||
|
|
977c6114ba | ||
|
|
27fddae286 | ||
|
|
615ac7f297 | ||
|
|
87d28e896d | ||
|
|
23f10418d7 | ||
|
|
27e7f48a44 | ||
|
|
7fd8850ddb | ||
|
|
7a4d3dd496 | ||
|
|
c1d7936689 | ||
|
|
1ec4da6947 | ||
|
|
8430c2f9af | ||
|
|
7cc6bccdec | ||
|
|
aeba64feaf | ||
|
|
04b4191de5 | ||
|
|
1da7473f26 | ||
|
|
95d13bd033 | ||
|
|
7eb4fcdaf4 | ||
|
|
809b4b227c | ||
|
|
ff51a2da9b | ||
|
|
be83681665 | ||
|
|
2bd30af72b | ||
|
|
d7b021061b | ||
|
|
73647f1669 | ||
|
|
d341cb3d5c | ||
|
|
30438410d6 | ||
|
|
b264ebabc0 | ||
|
|
2edc88e0a1 | ||
|
|
552dda46f8 | ||
|
|
2340a127d6 | ||
|
|
ecde504a79 | ||
|
|
0b781065d2 | ||
|
|
bcb57ce5f9 | ||
|
|
6392a8cdd0 | ||
|
|
34e3dd24b4 | ||
|
|
c303d3730c | ||
|
|
0a53ce17a2 | ||
|
|
7973651e05 | ||
|
|
672b150972 | ||
|
|
d8bcbd7d0a | ||
|
|
ff2f1477bb | ||
|
|
1139073297 | ||
|
|
39deac2747 | ||
|
|
0a35868367 | ||
|
|
608f869789 | ||
|
|
c30bd1a18e | ||
|
|
20a81af95f | ||
|
|
531c70b476 | ||
|
|
dae0aedc99 | ||
|
|
5fde03f4b0 | ||
|
|
48f53b529b | ||
|
|
4d9b0c6138 | ||
|
|
70cabec876 | ||
|
|
60423376cf | ||
|
|
22c646294a | ||
|
|
10b317cf34 | ||
|
|
03f0c44cac | ||
|
|
caa0e5db8d | ||
|
|
b862e464f8 | ||
|
|
3d5257592b | ||
|
|
ff76715cd2 | ||
|
|
cdb0a9c953 | ||
|
|
b0acae81b0 | ||
|
|
afc616d263 | ||
|
|
e066b4dcb1 | ||
|
|
9ea495902e | ||
|
|
d786c367b4 | ||
|
|
a391004432 | ||
|
|
dd97a2674d | ||
|
|
437c4c91bc | ||
|
|
575f1f98b0 | ||
|
|
2ee6ab6332 | ||
|
|
3d862538d2 | ||
|
|
4bd36e0460 | ||
|
|
7fbf0f1988 | ||
|
|
066127013b | ||
|
|
f675208d72 | ||
|
|
36aa69cf66 | ||
|
|
66b77ffd08 | ||
|
|
d2a3e4869a | ||
|
|
a2dc7c7f31 | ||
|
|
55ac69776a | ||
|
|
7a7c9b0076 | ||
|
|
77d40230a8 | ||
|
|
e4556040a8 | ||
|
|
755b3934a4 | ||
|
|
2d77fb72a5 | ||
|
|
106b0df42e | ||
|
|
c31ac4cf7e | ||
|
|
7b309df0c5 | ||
|
|
326f524e7c | ||
|
|
315ad20111 | ||
|
|
b1daf17a61 | ||
|
|
9db99befb6 | ||
|
|
aebc443b62 | ||
|
|
2c0e5586e8 | ||
|
|
25f7557751 | ||
|
|
59ebf7b762 | ||
|
|
1abe9db8e0 | ||
|
|
e4363f9ed8 | ||
|
|
e00b545548 | ||
|
|
1aa32c2036 | ||
|
|
65824ef814 | ||
|
|
d17bc33bfb | ||
|
|
d874ac92b4 | ||
|
|
0362449fe4 | ||
|
|
0d4c062487 | ||
|
|
ec622022f9 | ||
|
|
e9adc3fa4e | ||
|
|
5bc63a321c | ||
|
|
6317380c8d | ||
|
|
a7f007f475 | ||
|
|
fcffc4a898 | ||
|
|
8ed4c66117 | ||
|
|
38486223b2 | ||
|
|
ac5e7d2b1e | ||
|
|
cf4138f385 | ||
|
|
af7803e94b | ||
|
|
10b631bfb4 | ||
|
|
76f1c194dc | ||
|
|
0c9bc95dfc | ||
|
|
6f0d19d916 | ||
|
|
427d3169b6 | ||
|
|
0fc828c816 | ||
|
|
2d97177eff | ||
|
|
33dfcc700b | ||
|
|
09c8193c8f | ||
|
|
4f4128075f | ||
|
|
9ab3e67ba2 | ||
|
|
ed31860071 | ||
|
|
ddb84cc16d | ||
|
|
5b59e450f7 | ||
|
|
a6c3b1f1d4 | ||
|
|
bf6b09b9f5 | ||
|
|
c95eed3fe0 | ||
|
|
9d7cdd56b5 | ||
|
|
0d70302963 | ||
|
|
32a09660b4 | ||
|
|
0612097f81 | ||
|
|
b0c373b6af | ||
|
|
4839cdf261 | ||
|
|
5977c442b1 | ||
|
|
d05dcac16f | ||
|
|
2cdfe459be | ||
|
|
721b27d222 | ||
|
|
be2def3fc8 | ||
|
|
7259dba90d | ||
|
|
ef5bfcb48b | ||
|
|
446baff697 | ||
|
|
bcf701b287 | ||
|
|
22ab99cbd6 | ||
|
|
98ee60e06f | ||
|
|
a3abdb5d19 | ||
|
|
e3ebeb9dde | ||
|
|
646ed4f132 | ||
|
|
128ce91951 | ||
|
|
aa0eb02968 | ||
|
|
637bd885cf | ||
|
|
337afe228f | ||
|
|
4541835487 | ||
|
|
04d9603449 | ||
|
|
671a8d0180 | ||
|
|
3950878690 | ||
|
|
eaac627600 | ||
|
|
35f8919e73 | ||
|
|
cb5a528550 | ||
|
|
1f95d7b982 | ||
|
|
46971ee985 | ||
|
|
e67009ee2e | ||
|
|
9d3da98251 | ||
|
|
b94de6e947 | ||
|
|
f8a1d4f414 | ||
|
|
7deb268de8 | ||
|
|
47b5cbd211 | ||
|
|
a4e9b9ccfe | ||
|
|
99be4f5a61 | ||
|
|
ba28ab1680 | ||
|
|
e51b8aadae | ||
|
|
33354aa07e | ||
|
|
730b71fad8 | ||
|
|
364cf216a0 | ||
|
|
3cb48ac562 | ||
|
|
ea65283023 | ||
|
|
d2003cc32d | ||
|
|
1766e27337 | ||
|
|
442c324243 | ||
|
|
3134711240 | ||
|
|
546fc965f8 | ||
|
|
9ab45d9118 | ||
|
|
b1ae86757b | ||
|
|
42eeec5897 | ||
|
|
c12283bb16 | ||
|
|
b856b21fc6 | ||
|
|
72a0d1edef | ||
|
|
c0a0e01cf6 | ||
|
|
78bf008c36 | ||
|
|
5857c22daf | ||
|
|
5f73ba1371 | ||
|
|
4c09835abc | ||
|
|
0a025901c5 | ||
|
|
9768e4518f | ||
|
|
1f802ccb5a | ||
|
|
e1306a8e6a | ||
|
|
997c906b5f | ||
|
|
2530196cf8 | ||
|
|
340bea3271 | ||
|
|
3df3bba756 | ||
|
|
a9863fe670 | ||
|
|
7b49b4e985 | ||
|
|
577db88f8e | ||
|
|
01a2e650a4 | ||
|
|
cd9f7931c9 | ||
|
|
2b04ae4e4a | ||
|
|
cd0b82e794 | ||
|
|
0ddcffe601 | ||
|
|
712d106a44 | ||
|
|
34c5560cb0 | ||
|
|
dcba1488a6 | ||
|
|
8e4b156f11 | ||
|
|
ab98c3bd28 | ||
|
|
7f98a99e90 | ||
|
|
101b80c234 | ||
|
|
44598babcb | ||
|
|
51edfb4604 | ||
|
|
12d6fa1494 | ||
|
|
99a15ac2ae | ||
|
|
093a9c8174 | ||
|
|
464dfc4e67 | ||
|
|
1c7f9826b4 | ||
|
|
e397a49c23 | ||
|
|
8c925237e7 | ||
|
|
0593d52b91 | ||
|
|
7b7d714109 | ||
|
|
e9aa87f62b | ||
|
|
8f5d735b2f | ||
|
|
e24f4867df | ||
|
|
ef024ca106 | ||
|
|
4c519d9d98 | ||
|
|
94cb96b288 | ||
|
|
108a0d36b7 | ||
|
|
efb097a76b | ||
|
|
af03042852 | ||
|
|
21667bc7e1 | ||
|
|
19b6c15fff | ||
|
|
3ef502024d | ||
|
|
e55cee7372 | ||
|
|
b72eb838c2 | ||
|
|
b21191dd55 | ||
|
|
76b17a8d04 | ||
|
|
e97d1a0cf8 | ||
|
|
c875d887b7 | ||
|
|
44d9cbca81 | ||
|
|
6e399101fd | ||
|
|
e8e3617ba6 | ||
|
|
45fa30c007 | ||
|
|
15768d9c4d | ||
|
|
a1fcaa398c | ||
|
|
871643d98d | ||
|
|
91659d6488 | ||
|
|
0076ea7bff | ||
|
|
e79da7bc05 | ||
|
|
00206a62ab | ||
|
|
d0b0a33be3 | ||
|
|
6ea21e95b6 | ||
|
|
c226dafd0d | ||
|
|
d4c21a23f4 | ||
|
|
b76ae5b921 | ||
|
|
b48e5af9a0 | ||
|
|
d36c2a74cb | ||
|
|
a1e0596450 | ||
|
|
596e243374 | ||
|
|
326ad08ba2 | ||
|
|
f63d4edbb4 | ||
|
|
0057ed6786 | ||
|
|
44b6bcbcaa | ||
|
|
a45c82c5f7 | ||
|
|
98133a4eb6 | ||
|
|
44c2fd223d | ||
|
|
fc249eefda | ||
|
|
1a1eb4e7aa | ||
|
|
723fdc6245 | ||
|
|
43a47b8bdf | ||
|
|
ab5647145f | ||
|
|
856981e0ed | ||
|
|
09bec0e28b | ||
|
|
2f0bf3b325 | ||
|
|
51278424c1 | ||
|
|
bfe26de026 | ||
|
|
db100439cb | ||
|
|
c37f54c86f | ||
|
|
e0262d9712 | ||
|
|
63fb5a22be | ||
|
|
05dda59cf6 | ||
|
|
5628bcca78 | ||
|
|
6042d9a7d8 | ||
|
|
144239394d | ||
|
|
d712ee8451 | ||
|
|
a8c1348235 | ||
|
|
148d9202bf | ||
|
|
44442e6407 | ||
|
|
c78237cb86 | ||
|
|
8fc0f33dd5 | ||
|
|
2010702880 | ||
|
|
29c31a2404 | ||
|
|
cd77981102 | ||
|
|
4f78d1e29c | ||
|
|
5be79454c3 | ||
|
|
d8c14ff31e | ||
|
|
9e1be4ecd2 | ||
|
|
327d5c3a53 | ||
|
|
852ca21e38 | ||
|
|
23a549ac65 | ||
|
|
3e9630afe8 | ||
|
|
2bf924b732 | ||
|
|
3686804f7e | ||
|
|
4b8f99d7a3 | ||
|
|
4d996044e6 | ||
|
|
53a32153a5 | ||
|
|
cbe688adbc | ||
|
|
8e7772c9c3 | ||
|
|
ea7759b322 | ||
|
|
8cc51d5e9e | ||
|
|
fdd36b0766 | ||
|
|
4f22bbf4d4 | ||
|
|
34c1c0d76a | ||
|
|
feafa586ae | ||
|
|
786691e97e | ||
|
|
155368be3b | ||
|
|
a944cfc8d0 | ||
|
|
bc7366b862 | ||
|
|
bb080c47f6 | ||
|
|
402137711c | ||
|
|
002da5a6f5 | ||
|
|
376fee952d | ||
|
|
761f682d44 | ||
|
|
40aea44470 | ||
|
|
8eba7aab89 | ||
|
|
bc54d310f2 | ||
|
|
f102c2e7dd | ||
|
|
1ce9a8540b | ||
|
|
f101dc5592 | ||
|
|
55de63f6fa | ||
|
|
7954f6b51c | ||
|
|
234a2c72b0 | ||
|
|
7a22b03713 | ||
|
|
52d404a267 | ||
|
|
6e086fe574 | ||
|
|
8206eb8915 | ||
|
|
8288f38281 | ||
|
|
99efb33b3f | ||
|
|
57c870e15d | ||
|
|
3f9c4df32d | ||
|
|
6b054651a7 | ||
|
|
fe6bef0af1 | ||
|
|
358e5fa534 | ||
|
|
b5e9173cbb | ||
|
|
14a081b814 | ||
|
|
9a9319eea9 | ||
|
|
05984093f0 | ||
|
|
2c4851bd2e | ||
|
|
c2f403f0eb | ||
|
|
00e584312c | ||
|
|
f6c042e58e | ||
|
|
fddeb0e672 | ||
|
|
f311afaab3 | ||
|
|
0323191436 | ||
|
|
fd4c850df7 |
BIN
.cache/plugin/social/0b649b356e60b558dfaafe8bb095862e.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
.cache/plugin/social/0cce129b2747506603c430fd3fe2b3d6.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
.cache/plugin/social/0f18d6e26b8551d3f42ef92b0f786024.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
.cache/plugin/social/14c48b40955d6021b47ae973d9aef723.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
.cache/plugin/social/17484ad7f45b09a1db146ba3ad3df79a.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
.cache/plugin/social/1d935acb34360e4768e35ae13479bbf9.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
.cache/plugin/social/216220c022e734cc7999210b48c9fb59.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
.cache/plugin/social/246dcba6c47283feac354f5871842fe8.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
.cache/plugin/social/259ba94ac7e93bd9f968c57ec4a15fe5.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
.cache/plugin/social/288fd82ce2209be4864d19bd50b21474.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
.cache/plugin/social/28a844df4871a1cdfcba05fdc87bb3e8.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
.cache/plugin/social/40770a96ef2fb657a7aa16a9facf702f.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
.cache/plugin/social/4747e68a5e5c0f0994cdc5b37682a37c.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
.cache/plugin/social/4809f4ae19b6e78539b900da82d8a1f6.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
.cache/plugin/social/481b171eb3fe3dec67ca86d2d923f598.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
.cache/plugin/social/4ae47a8f7da894db700b2f29242cd0c5.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
.cache/plugin/social/4c1fb3bfd02d6b1317779fe5101058a7.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
.cache/plugin/social/56e240bc0124af182495bc59877d8d11.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
.cache/plugin/social/5d2431971fcde0af2c84e4680a4227a7.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
.cache/plugin/social/69bcd9a2304ea69e1244a7ac510dd98d.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
.cache/plugin/social/6b49f5ef597c15cabc3df9bac4fbcf44.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
.cache/plugin/social/7296e2d6c7b2c713ed7b2e4546e3acdb.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
.cache/plugin/social/805d7c5662a45ca18b52554eecbc34af.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
.cache/plugin/social/80f1492950494de7a34a1f20f6dd4368.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
.cache/plugin/social/834ad7f8096fa4c92637b815777bf2bd.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
.cache/plugin/social/8b089bdf12d22c016f481d654be39eb1.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
.cache/plugin/social/96f1c198bf51f822eb04a25adf7ca20c.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
.cache/plugin/social/9f88e9bd3010b149e527e0600c2e438c.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
.cache/plugin/social/Roboto-Black.ttf
Normal file
BIN
.cache/plugin/social/Roboto-BlackItalic.ttf
Normal file
BIN
.cache/plugin/social/Roboto-Bold.ttf
Normal file
BIN
.cache/plugin/social/Roboto-BoldItalic.ttf
Normal file
BIN
.cache/plugin/social/Roboto-Italic.ttf
Normal file
BIN
.cache/plugin/social/Roboto-Light.ttf
Normal file
BIN
.cache/plugin/social/Roboto-LightItalic.ttf
Normal file
BIN
.cache/plugin/social/Roboto-Medium.ttf
Normal file
BIN
.cache/plugin/social/Roboto-MediumItalic.ttf
Normal file
BIN
.cache/plugin/social/Roboto-Regular.ttf
Normal file
BIN
.cache/plugin/social/Roboto-Thin.ttf
Normal file
BIN
.cache/plugin/social/Roboto-ThinItalic.ttf
Normal file
BIN
.cache/plugin/social/a0c21e9a7250afebc533da92c7050bed.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
.cache/plugin/social/a19c79f0bc7a3e5ffc6b511a68273e5d.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
.cache/plugin/social/a1d83c5e1feb928b579ad122a8d3786d.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
.cache/plugin/social/a3d8476a7b5c6630a5f91aed8c210173.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
.cache/plugin/social/ac9c4b6558565d4c349355101e95c74a.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
.cache/plugin/social/b417e4353162a563e70f1350a2777e2c.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
.cache/plugin/social/b84a1e5d0534be3c31f04a7d4a98b515.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
.cache/plugin/social/bca675d7c3c82f52ebd329487fb9ade1.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
.cache/plugin/social/bdf46ef3b5230ebb45ef648933f54fa2.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
.cache/plugin/social/beacb748aad822c66a972b39186dbef1.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
.cache/plugin/social/caa7abb72303dbe5a02ec11e6f1eba6b.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
.cache/plugin/social/cff5eb5aae0959e143c12945428558bc.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
.cache/plugin/social/d01b95e8266a0d2c5f825b88d98a97a1.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
.cache/plugin/social/d7db21df76b132d3ca3ae4313e23f77d.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
.cache/plugin/social/d87db72302152f8c0953d7105c28a206.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
.cache/plugin/social/e580fe32a1d3f15fc89057d053ae3e52.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
.cache/plugin/social/e9111c93e01f7c1dfec7bbab69843076.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
.cache/plugin/social/ebf70df39c2bfd2c4a89d70846a516ff.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
.cache/plugin/social/ed5690e7952bdee0372c8d3f1f5d98d7.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
.cache/plugin/social/f6d08b81ae945faa6c4a436de48d2da6.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
.cache/plugin/social/f875c8d6b0cd71d9ae38300c82361d77.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
.cache/plugin/social/fc9a9f44881519178d4000f24000ef9d.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
@@ -1,27 +0,0 @@
|
||||
version: 2.1
|
||||
|
||||
jobs:
|
||||
build-and-test:
|
||||
docker:
|
||||
- image: python:3.9.18
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Install poetry
|
||||
command: pip install poetry
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: poetry install
|
||||
- run:
|
||||
name: Update PATH and Define Environment Variable at Runtime
|
||||
command: |
|
||||
echo 'export OPENAI_API_KEY=fake-api-key' >> "$BASH_ENV"
|
||||
source "$BASH_ENV"
|
||||
- run:
|
||||
name: Run tests
|
||||
command: poetry run pytest
|
||||
|
||||
workflows:
|
||||
build-and-test:
|
||||
jobs:
|
||||
- build-and-test
|
||||
14
.editorconfig
Normal file
@@ -0,0 +1,14 @@
|
||||
# .editorconfig
|
||||
root = true
|
||||
|
||||
# All files
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# Python files
|
||||
[*.py]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
116
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
name: Bug report
|
||||
description: Create a report to help us improve CrewAI
|
||||
title: "[BUG]"
|
||||
labels: ["bug"]
|
||||
assignees: []
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Provide a clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: steps-to-reproduce
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: Provide a step-by-step process to reproduce the behavior.
|
||||
placeholder: |
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots-code
|
||||
attributes:
|
||||
label: Screenshots/Code snippets
|
||||
description: If applicable, add screenshots or code snippets to help explain your problem.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: Select the operating system you're using
|
||||
options:
|
||||
- Ubuntu 20.04
|
||||
- Ubuntu 22.04
|
||||
- Ubuntu 24.04
|
||||
- macOS Catalina
|
||||
- macOS Big Sur
|
||||
- macOS Monterey
|
||||
- macOS Ventura
|
||||
- macOS Sonoma
|
||||
- Windows 10
|
||||
- Windows 11
|
||||
- Other (specify in additional context)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: python-version
|
||||
attributes:
|
||||
label: Python Version
|
||||
description: Version of Python your Crew is running on
|
||||
options:
|
||||
- '3.10'
|
||||
- '3.11'
|
||||
- '3.12'
|
||||
- '3.13'
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: crewai-version
|
||||
attributes:
|
||||
label: crewAI Version
|
||||
description: What version of CrewAI are you using
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: crewai-tools-version
|
||||
attributes:
|
||||
label: crewAI Tools Version
|
||||
description: What version of CrewAI Tools are you using
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: virtual-environment
|
||||
attributes:
|
||||
label: Virtual Environment
|
||||
description: What Virtual Environment are you running your crew in.
|
||||
options:
|
||||
- Venv
|
||||
- Conda
|
||||
- Poetry
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: evidence
|
||||
attributes:
|
||||
label: Evidence
|
||||
description: Include relevant information, logs or error messages. These can be screenshots.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: possible-solution
|
||||
attributes:
|
||||
label: Possible Solution
|
||||
description: Have a solution in mind? Please suggest it here, or write "None".
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here.
|
||||
validations:
|
||||
required: true
|
||||
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
65
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
name: Feature request
|
||||
description: Suggest a new feature for CrewAI
|
||||
title: "[FEATURE]"
|
||||
labels: ["feature-request"]
|
||||
assignees: []
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this feature request!
|
||||
- type: dropdown
|
||||
id: feature-area
|
||||
attributes:
|
||||
label: Feature Area
|
||||
description: Which area of CrewAI does this feature primarily relate to?
|
||||
options:
|
||||
- Core functionality
|
||||
- Agent capabilities
|
||||
- Task management
|
||||
- Integration with external tools
|
||||
- Performance optimization
|
||||
- Documentation
|
||||
- Other (please specify in additional context)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Is your feature request related to a an existing bug? Please link it here.
|
||||
description: A link to the bug or NA if not related to an existing bug.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context, screenshots, or examples about the feature request here.
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: willingness-to-contribute
|
||||
attributes:
|
||||
label: Willingness to Contribute
|
||||
description: Would you be willing to contribute to the implementation of this feature?
|
||||
options:
|
||||
- Yes, I'd be happy to submit a pull request
|
||||
- I could provide more detailed specifications
|
||||
- I can test the feature once it's implemented
|
||||
- No, I'm just suggesting the idea
|
||||
validations:
|
||||
required: true
|
||||
19
.github/security.md
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
CrewAI takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organization.
|
||||
If you believe you have found a security vulnerability in any CrewAI product or service, please report it to us as described below.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
Please do not report security vulnerabilities through public GitHub issues.
|
||||
To report a vulnerability, please email us at security@crewai.com.
|
||||
Please include the requested information listed below so that we can triage your report more quickly
|
||||
|
||||
- Type of issue (e.g. SQL injection, cross-site scripting, etc.)
|
||||
- Full paths of source file(s) related to the manifestation of the issue
|
||||
- The location of the affected source code (tag/branch/commit or direct URL)
|
||||
- Any special configuration required to reproduce the issue
|
||||
- Step-by-step instructions to reproduce the issue (please include screenshots if needed)
|
||||
- Proof-of-concept or exploit code (if possible)
|
||||
- Impact of the issue, including how an attacker might exploit the issue
|
||||
|
||||
Once we have received your report, we will respond to you at the email address you provide. If the issue is confirmed, we will release a patch as soon as possible depending on the complexity of the issue.
|
||||
|
||||
At this time, we are not offering a bug bounty program. Any rewards will be at our discretion.
|
||||
16
.github/workflows/linter.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Lint
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Requirements
|
||||
run: |
|
||||
pip install ruff
|
||||
|
||||
- name: Run Ruff Linter
|
||||
run: ruff check --exclude "templates","__init__.py"
|
||||
45
.github/workflows/mkdocs.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
name: Deploy MkDocs
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Calculate requirements hash
|
||||
id: req-hash
|
||||
run: echo "::set-output name=hash::$(sha256sum requirements-doc.txt | awk '{print $1}')"
|
||||
|
||||
- name: Setup cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
key: mkdocs-material-${{ steps.req-hash.outputs.hash }}
|
||||
path: .cache
|
||||
restore-keys: |
|
||||
mkdocs-material-
|
||||
|
||||
- name: Install Requirements
|
||||
run: |
|
||||
sudo apt-get update &&
|
||||
sudo apt-get install pngquant &&
|
||||
pip install mkdocs-material mkdocs-material-extensions pillow cairosvg
|
||||
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Build and deploy MkDocs
|
||||
run: mkdocs gh-deploy --force
|
||||
23
.github/workflows/security-checker.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: Security Checker
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
security-check:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11.9"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip install bandit
|
||||
|
||||
- name: Run Bandit
|
||||
run: bandit -c pyproject.toml -r src/ -lll
|
||||
|
||||
27
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: Mark stale issues and pull requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '10 12 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-label: 'no-issue-activity'
|
||||
stale-issue-message: 'This issue is stale because it has been open for 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
|
||||
days-before-issue-stale: 30
|
||||
days-before-issue-close: 5
|
||||
stale-pr-label: 'no-pr-activity'
|
||||
stale-pr-message: 'This PR is stale because it has been open for 45 days with no activity.'
|
||||
days-before-pr-stale: 45
|
||||
days-before-pr-close: -1
|
||||
operations-per-run: 1200
|
||||
32
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: Run Tests
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
OPENAI_API_KEY: fake-api-key
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
enable-cache: true
|
||||
|
||||
|
||||
- name: Set up Python
|
||||
run: uv python install 3.11.9
|
||||
|
||||
- name: Install the project
|
||||
run: uv sync --dev
|
||||
|
||||
- name: Run tests
|
||||
run: uv run pytest tests
|
||||
26
.github/workflows/type-checker.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Run Type Checks
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
type-checker:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11.9"
|
||||
|
||||
- name: Install Requirements
|
||||
run: |
|
||||
pip install mypy
|
||||
|
||||
- name: Run type checks
|
||||
run: mypy src
|
||||
14
.gitignore
vendored
@@ -2,6 +2,18 @@
|
||||
.pytest_cache
|
||||
__pycache__
|
||||
dist/
|
||||
lib/
|
||||
.env
|
||||
assets/*
|
||||
.idea
|
||||
.idea
|
||||
test/
|
||||
docs_crew/
|
||||
chroma.sqlite3
|
||||
old_en.json
|
||||
db/
|
||||
test.py
|
||||
rc-tests/*
|
||||
*.pkl
|
||||
temp/*
|
||||
.vscode/*
|
||||
crew_tasks_output.json
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
repos:
|
||||
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 23.12.1
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.4.4
|
||||
hooks:
|
||||
- id: black
|
||||
language_version: python3.11
|
||||
files: \.(py)$
|
||||
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.13.2
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
args: ["--profile", "black", "--filter-files"]
|
||||
|
||||
- repo: https://github.com/PyCQA/autoflake
|
||||
rev: v2.2.1
|
||||
hooks:
|
||||
- id: autoflake
|
||||
args: ['--in-place', '--remove-all-unused-imports', '--remove-unused-variables', '--ignore-init-module-imports']
|
||||
- id: ruff
|
||||
args: ["--fix"]
|
||||
exclude: "templates"
|
||||
- id: ruff-format
|
||||
exclude: "templates"
|
||||
|
||||
437
README.md
@@ -1,16 +1,36 @@
|
||||
# crewAI
|
||||
<div align="center">
|
||||
|
||||

|
||||

|
||||
|
||||
🤖 Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By fostering collaborative intelligence, CrewAI empowers agents to work together seamlessly, tackling complex tasks.
|
||||
# **CrewAI**
|
||||
|
||||
- [Why CrewAI](#why-crewai)
|
||||
🤖 **CrewAI**: Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By fostering collaborative intelligence, CrewAI empowers agents to work together seamlessly, tackling complex tasks.
|
||||
|
||||
<h3>
|
||||
|
||||
[Homepage](https://www.crewai.com/) | [Documentation](https://docs.crewai.com/) | [Chat with Docs](https://chatg.pt/DWjSBZn) | [Examples](https://github.com/crewAIInc/crewAI-examples) | [Discourse](https://community.crewai.com)
|
||||
|
||||
</h3>
|
||||
|
||||
[](https://github.com/crewAIInc/crewAI)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
</div>
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Why CrewAI?](#why-crewai)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Key Features](#key-features)
|
||||
- [Examples](#examples)
|
||||
- [Local Open Source Models](#local-open-source-models)
|
||||
- [CrewAI x AutoGen x ChatDev](#how-crewai-compares)
|
||||
- [Quick Tutorial](#quick-tutorial)
|
||||
- [Write Job Descriptions](#write-job-descriptions)
|
||||
- [Trip Planner](#trip-planner)
|
||||
- [Stock Analysis](#stock-analysis)
|
||||
- [Connecting Your Crew to a Model](#connecting-your-crew-to-a-model)
|
||||
- [How CrewAI Compares](#how-crewai-compares)
|
||||
- [Contribution](#contribution)
|
||||
- [Telemetry](#telemetry)
|
||||
- [License](#license)
|
||||
|
||||
## Why CrewAI?
|
||||
@@ -18,111 +38,287 @@
|
||||
The power of AI collaboration has too much to offer.
|
||||
CrewAI is designed to enable AI agents to assume roles, share goals, and operate in a cohesive unit - much like a well-oiled crew. Whether you're building a smart assistant platform, an automated customer service ensemble, or a multi-agent research team, CrewAI provides the backbone for sophisticated multi-agent interactions.
|
||||
|
||||
- 🤖 [Talk with the Docs](https://chat.openai.com/g/g-qqTuUWsBY-crewai-assistant)
|
||||
- 📄 [Documention Wiki](https://github.com/joaomdmoura/CrewAI/wiki)
|
||||
|
||||
## Getting Started
|
||||
|
||||
To get started with CrewAI, follow these simple steps:
|
||||
|
||||
1. **Installation**:
|
||||
### 1. Installation
|
||||
|
||||
Ensure you have Python >=3.10 <=3.13 installed on your system. CrewAI uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience.
|
||||
|
||||
First, install CrewAI:
|
||||
|
||||
```shell
|
||||
pip install crewai
|
||||
```
|
||||
|
||||
2. **Setting Up Your Crew**:
|
||||
If you want to install the 'crewai' package along with its optional features that include additional tools for agents, you can do so by using the following command:
|
||||
|
||||
```python
|
||||
import os
|
||||
from crewai import Agent, Task, Crew, Process
|
||||
```shell
|
||||
pip install 'crewai[tools]'
|
||||
```
|
||||
The command above installs the basic package and also adds extra components which require more dependencies to function.
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "Your Key"
|
||||
### 2. Setting Up Your Crew with the YAML Configuration
|
||||
|
||||
# Define your agents with roles and goals
|
||||
researcher = Agent(
|
||||
role='Researcher',
|
||||
goal='Discover new insights',
|
||||
backstory="You're a world class researcher working on a major data science company",
|
||||
verbose=True,
|
||||
allow_delegation=False
|
||||
# llm=OpenAI(temperature=0.7, model_name="gpt-4"). It uses langchain.chat_models, default is GPT4
|
||||
)
|
||||
writer = Agent(
|
||||
role='Writer',
|
||||
goal='Create engaging content',
|
||||
backstory="You're a famous technical writer, specialized on writing data related content",
|
||||
verbose=True,
|
||||
allow_delegation=False
|
||||
)
|
||||
To create a new CrewAI project, run the following CLI (Command Line Interface) command:
|
||||
|
||||
# Create tasks for your agents
|
||||
task1 = Task(description='Investigate the latest AI trends', agent=researcher)
|
||||
task2 = Task(description='Write a blog post on AI advancements', agent=writer)
|
||||
|
||||
# Instantiate your crew with a sequential process
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[task1, task2],
|
||||
verbose=2, # Crew verbose more will let you know what tasks are being worked on, you can set it to 1 or 2 to different logging levels
|
||||
process=Process.sequential # Sequential process will have tasks executed one after the other and the outcome of the previous one is passed as extra content into this next.
|
||||
)
|
||||
|
||||
# Get your crew to work!
|
||||
result = crew.kickoff()
|
||||
```shell
|
||||
crewai create crew <project_name>
|
||||
```
|
||||
|
||||
Currently the only supported process is `Process.sequential`, where one task is executed after the other and the outcome of one is passed as extra content into this next.
|
||||
This command creates a new project folder with the following structure:
|
||||
|
||||
```
|
||||
my_project/
|
||||
├── .gitignore
|
||||
├── pyproject.toml
|
||||
├── README.md
|
||||
├── .env
|
||||
└── src/
|
||||
└── my_project/
|
||||
├── __init__.py
|
||||
├── main.py
|
||||
├── crew.py
|
||||
├── tools/
|
||||
│ ├── custom_tool.py
|
||||
│ └── __init__.py
|
||||
└── config/
|
||||
├── agents.yaml
|
||||
└── tasks.yaml
|
||||
```
|
||||
|
||||
You can now start developing your crew by editing the files in the `src/my_project` folder. The `main.py` file is the entry point of the project, the `crew.py` file is where you define your crew, the `agents.yaml` file is where you define your agents, and the `tasks.yaml` file is where you define your tasks.
|
||||
|
||||
#### To customize your project, you can:
|
||||
|
||||
- Modify `src/my_project/config/agents.yaml` to define your agents.
|
||||
- Modify `src/my_project/config/tasks.yaml` to define your tasks.
|
||||
- Modify `src/my_project/crew.py` to add your own logic, tools, and specific arguments.
|
||||
- Modify `src/my_project/main.py` to add custom inputs for your agents and tasks.
|
||||
- Add your environment variables into the `.env` file.
|
||||
|
||||
#### Example of a simple crew with a sequential process:
|
||||
|
||||
Instatiate your crew:
|
||||
|
||||
```shell
|
||||
crewai create crew latest-ai-development
|
||||
```
|
||||
|
||||
Modify the files as needed to fit your use case:
|
||||
|
||||
**agents.yaml**
|
||||
|
||||
```yaml
|
||||
# src/my_project/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
{topic} Senior Data Researcher
|
||||
goal: >
|
||||
Uncover cutting-edge developments in {topic}
|
||||
backstory: >
|
||||
You're a seasoned researcher with a knack for uncovering the latest
|
||||
developments in {topic}. Known for your ability to find the most relevant
|
||||
information and present it in a clear and concise manner.
|
||||
|
||||
reporting_analyst:
|
||||
role: >
|
||||
{topic} Reporting Analyst
|
||||
goal: >
|
||||
Create detailed reports based on {topic} data analysis and research findings
|
||||
backstory: >
|
||||
You're a meticulous analyst with a keen eye for detail. You're known for
|
||||
your ability to turn complex data into clear and concise reports, making
|
||||
it easy for others to understand and act on the information you provide.
|
||||
```
|
||||
|
||||
**tasks.yaml**
|
||||
|
||||
```yaml
|
||||
# src/my_project/config/tasks.yaml
|
||||
research_task:
|
||||
description: >
|
||||
Conduct a thorough research about {topic}
|
||||
Make sure you find any interesting and relevant information given
|
||||
the current year is 2024.
|
||||
expected_output: >
|
||||
A list with 10 bullet points of the most relevant information about {topic}
|
||||
agent: researcher
|
||||
|
||||
reporting_task:
|
||||
description: >
|
||||
Review the context you got and expand each topic into a full section for a report.
|
||||
Make sure the report is detailed and contains any and all relevant information.
|
||||
expected_output: >
|
||||
A fully fledge reports with the mains topics, each with a full section of information.
|
||||
Formatted as markdown without '```'
|
||||
agent: reporting_analyst
|
||||
output_file: report.md
|
||||
```
|
||||
|
||||
**crew.py**
|
||||
|
||||
```python
|
||||
# src/my_project/crew.py
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from crewai_tools import SerperDevTool
|
||||
|
||||
@CrewBase
|
||||
class LatestAiDevelopmentCrew():
|
||||
"""LatestAiDevelopment crew"""
|
||||
|
||||
@agent
|
||||
def researcher(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['researcher'],
|
||||
verbose=True,
|
||||
tools=[SerperDevTool()]
|
||||
)
|
||||
|
||||
@agent
|
||||
def reporting_analyst(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['reporting_analyst'],
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@task
|
||||
def research_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['research_task'],
|
||||
)
|
||||
|
||||
@task
|
||||
def reporting_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['reporting_task'],
|
||||
output_file='report.md'
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the LatestAiDevelopment crew"""
|
||||
return Crew(
|
||||
agents=self.agents, # Automatically created by the @agent decorator
|
||||
tasks=self.tasks, # Automatically created by the @task decorator
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
|
||||
**main.py**
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python
|
||||
# src/my_project/main.py
|
||||
import sys
|
||||
from latest_ai_development.crew import LatestAiDevelopmentCrew
|
||||
|
||||
def run():
|
||||
"""
|
||||
Run the crew.
|
||||
"""
|
||||
inputs = {
|
||||
'topic': 'AI Agents'
|
||||
}
|
||||
LatestAiDevelopmentCrew().crew().kickoff(inputs=inputs)
|
||||
```
|
||||
|
||||
### 3. Running Your Crew
|
||||
|
||||
Before running your crew, make sure you have the following keys set as environment variables in your `.env` file:
|
||||
|
||||
- An [OpenAI API key](https://platform.openai.com/account/api-keys) (or other LLM API key): `OPENAI_API_KEY=sk-...`
|
||||
- A [Serper.dev](https://serper.dev/) API key: `SERPER_API_KEY=YOUR_KEY_HERE`
|
||||
|
||||
Lock the dependencies and install them by using the CLI command but first, navigate to your project directory:
|
||||
|
||||
```shell
|
||||
cd my_project
|
||||
crewai install (Optional)
|
||||
```
|
||||
|
||||
To run your crew, execute the following command in the root of your project:
|
||||
|
||||
```bash
|
||||
crewai run
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
python src/my_project/main.py
|
||||
```
|
||||
|
||||
If an error happens due to the usage of poetry, please run the following command to update your crewai package:
|
||||
|
||||
```bash
|
||||
crewai update
|
||||
```
|
||||
|
||||
You should see the output in the console and the `report.md` file should be created in the root of your project with the full final report.
|
||||
|
||||
In addition to the sequential process, you can use the hierarchical process, which automatically assigns a manager to the defined crew to properly coordinate the planning and execution of tasks through delegation and validation of results. [See more about the processes here](https://docs.crewai.com/core-concepts/Processes/).
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Role-Based Agent Design**: Customize agents with specific roles, goals, and tools.
|
||||
- **Autonomous Inter-Agent Delegation**: Agents can autonomously delegate tasks and inquire amongst themselves, enhancing problem-solving efficiency.
|
||||
- **Flexible Task Management**: Define tasks with customizable tools and assign them to agents dynamically.
|
||||
- **Processes Driven**: Currently only supports `sequential` task execution but more complex processes like consensual and hierarchical being worked on.
|
||||
- **Processes Driven**: Currently only supports `sequential` task execution and `hierarchical` processes, but more complex processes like consensual and autonomous are being worked on.
|
||||
- **Save output as file**: Save the output of individual tasks as a file, so you can use it later.
|
||||
- **Parse output as Pydantic or Json**: Parse the output of individual tasks as a Pydantic model or as a Json if you want to.
|
||||
- **Works with Open Source Models**: Run your crew using Open AI or open source models refer to the [Connect CrewAI to LLMs](https://docs.crewai.com/how-to/LLM-Connections/) page for details on configuring your agents' connections to models, even ones running locally!
|
||||
|
||||

|
||||

|
||||
|
||||
## Examples
|
||||
You can test different real life examples of AI crews [in the examples repo](https://github.com/joaomdmoura/crewAI-examples?tab=readme-ov-file)
|
||||
|
||||
## Local Open Source Models
|
||||
crewAI supports integration with local models, thorugh tools such as [Ollama](https://ollama.ai/), for enhanced flexibility and customization. This allows you to utilize your own models, which can be particularly useful for specialized tasks or data privacy concerns.
|
||||
You can test different real life examples of AI crews in the [CrewAI-examples repo](https://github.com/crewAIInc/crewAI-examples?tab=readme-ov-file):
|
||||
|
||||
### Setting Up Ollama
|
||||
- **Install Ollama**: Ensure that Ollama is properly installed in your environment. Follow the installation guide provided by Ollama for detailed instructions.
|
||||
- **Configure Ollama**: Set up Ollama to work with your local model. You will probably need to [tweak the model using a Modelfile](https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md). I'd recommend adding `Observation` as a stop word and playing with `top_p` and `temperature`.
|
||||
- [Landing Page Generator](https://github.com/crewAIInc/crewAI-examples/tree/main/landing_page_generator)
|
||||
- [Having Human input on the execution](https://docs.crewai.com/how-to/Human-Input-on-Execution)
|
||||
- [Trip Planner](https://github.com/crewAIInc/crewAI-examples/tree/main/trip_planner)
|
||||
- [Stock Analysis](https://github.com/crewAIInc/crewAI-examples/tree/main/stock_analysis)
|
||||
|
||||
### Integrating Ollama with CrewAI
|
||||
- Instantiate Ollama Model: Create an instance of the Ollama model. You can specify the model and the base URL during instantiation. For example:
|
||||
### Quick Tutorial
|
||||
|
||||
```python
|
||||
from langchain.llms import Ollama
|
||||
ollama_openhermes = Ollama(model="agent")
|
||||
# Pass Ollama Model to Agents: When creating your agents within the CrewAI framework, you can pass the Ollama model as an argument to the Agent constructor. For instance:
|
||||
[](https://www.youtube.com/watch?v=tnejrr-0a94 "CrewAI Tutorial")
|
||||
|
||||
local_expert = Agent(
|
||||
role='Local Expert at this city',
|
||||
goal='Provide the BEST insights about the selected city',
|
||||
backstory="""A knowledgeable local guide with extensive information
|
||||
about the city, it's attractions and customs""",
|
||||
tools=[
|
||||
SearchTools.search_internet,
|
||||
BrowserTools.scrape_and_summarize_website,
|
||||
],
|
||||
llm=ollama_openhermes, # Ollama model passed here
|
||||
verbose=True
|
||||
)
|
||||
```
|
||||
### Write Job Descriptions
|
||||
|
||||
[Check out code for this example](https://github.com/crewAIInc/crewAI-examples/tree/main/job-posting) or watch a video below:
|
||||
|
||||
[](https://www.youtube.com/watch?v=u98wEMz-9to "Jobs postings")
|
||||
|
||||
### Trip Planner
|
||||
|
||||
[Check out code for this example](https://github.com/crewAIInc/crewAI-examples/tree/main/trip_planner) or watch a video below:
|
||||
|
||||
[](https://www.youtube.com/watch?v=xis7rWp-hjs "Trip Planner")
|
||||
|
||||
### Stock Analysis
|
||||
|
||||
[Check out code for this example](https://github.com/crewAIInc/crewAI-examples/tree/main/stock_analysis) or watch a video below:
|
||||
|
||||
[](https://www.youtube.com/watch?v=e0Uj4yWdaAg "Stock Analysis")
|
||||
|
||||
## Connecting Your Crew to a Model
|
||||
|
||||
CrewAI supports using various LLMs through a variety of connection options. By default your agents will use the OpenAI API when querying the model. However, there are several other ways to allow your agents to connect to models. For example, you can configure your agents to use a local model via the Ollama tool.
|
||||
|
||||
Please refer to the [Connect CrewAI to LLMs](https://docs.crewai.com/how-to/LLM-Connections/) page for details on configuring you agents' connections to models.
|
||||
|
||||
## How CrewAI Compares
|
||||
|
||||
- **Autogen**: While Autogen excels in creating conversational agents capable of working together, it lacks an inherent concept of process. In Autogen, orchestrating agents' interactions requires additional programming, which can become complex and cumbersome as the scale of tasks grows.
|
||||
**CrewAI's Advantage**: CrewAI is built with production in mind. It offers the flexibility of Autogen's conversational agents and the structured process approach of ChatDev, but without the rigidity. CrewAI's processes are designed to be dynamic and adaptable, fitting seamlessly into both development and production workflows.
|
||||
|
||||
- **Autogen**: While Autogen does good in creating conversational agents capable of working together, it lacks an inherent concept of process. In Autogen, orchestrating agents' interactions requires additional programming, which can become complex and cumbersome as the scale of tasks grows.
|
||||
|
||||
- **ChatDev**: ChatDev introduced the idea of processes into the realm of AI agents, but its implementation is quite rigid. Customizations in ChatDev are limited and not geared towards production environments, which can hinder scalability and flexibility in real-world applications.
|
||||
|
||||
**CrewAI's Advantage**: CrewAI is built with production in mind. It offers the flexibility of Autogen's conversational agents and the structured process approach of ChatDev, but without the rigidity. CrewAI's processes are designed to be dynamic and adaptable, fitting seamlessly into both development and production workflows.
|
||||
|
||||
## Contribution
|
||||
|
||||
CrewAI is open-source and we welcome contributions. If you're looking to contribute, please:
|
||||
@@ -134,14 +330,16 @@ CrewAI is open-source and we welcome contributions. If you're looking to contrib
|
||||
- We appreciate your input!
|
||||
|
||||
### Installing Dependencies
|
||||
|
||||
```bash
|
||||
poetry lock
|
||||
poetry install
|
||||
uv lock
|
||||
uv sync
|
||||
```
|
||||
|
||||
### Virtual Env
|
||||
|
||||
```bash
|
||||
poetry shell
|
||||
uv venv
|
||||
```
|
||||
|
||||
### Pre-commit hooks
|
||||
@@ -151,21 +349,96 @@ pre-commit install
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
poetry run pytest
|
||||
uv run pytest .
|
||||
```
|
||||
|
||||
### Running static type checks
|
||||
|
||||
```bash
|
||||
uvx mypy
|
||||
```
|
||||
|
||||
### Packaging
|
||||
|
||||
```bash
|
||||
poetry build
|
||||
uv build
|
||||
```
|
||||
|
||||
### Installing Locally
|
||||
|
||||
```bash
|
||||
pip install dist/*.tar.gz
|
||||
```
|
||||
|
||||
## Telemetry
|
||||
|
||||
CrewAI uses anonymous telemetry to collect usage data with the main purpose of helping us improve the library by focusing our efforts on the most used features, integrations and tools.
|
||||
|
||||
It's pivotal to understand that **NO data is collected** concerning prompts, task descriptions, agents' backstories or goals, usage of tools, API calls, responses, any data processed by the agents, or secrets and environment variables, with the exception of the conditions mentioned. When the `share_crew` feature is enabled, detailed data including task descriptions, agents' backstories or goals, and other specific attributes are collected to provide deeper insights while respecting user privacy. We don't offer a way to disable it now, but we will in the future.
|
||||
|
||||
Data collected includes:
|
||||
|
||||
- Version of CrewAI
|
||||
- So we can understand how many users are using the latest version
|
||||
- Version of Python
|
||||
- So we can decide on what versions to better support
|
||||
- General OS (e.g. number of CPUs, macOS/Windows/Linux)
|
||||
- So we know what OS we should focus on and if we could build specific OS related features
|
||||
- Number of agents and tasks in a crew
|
||||
- So we make sure we are testing internally with similar use cases and educate people on the best practices
|
||||
- Crew Process being used
|
||||
- Understand where we should focus our efforts
|
||||
- If Agents are using memory or allowing delegation
|
||||
- Understand if we improved the features or maybe even drop them
|
||||
- If Tasks are being executed in parallel or sequentially
|
||||
- Understand if we should focus more on parallel execution
|
||||
- Language model being used
|
||||
- Improved support on most used languages
|
||||
- Roles of agents in a crew
|
||||
- Understand high level use cases so we can build better tools, integrations and examples about it
|
||||
- Tools names available
|
||||
- Understand out of the publically available tools, which ones are being used the most so we can improve them
|
||||
|
||||
Users can opt-in to Further Telemetry, sharing the complete telemetry data by setting the `share_crew` attribute to `True` on their Crews. Enabling `share_crew` results in the collection of detailed crew and task execution data, including `goal`, `backstory`, `context`, and `output` of tasks. This enables a deeper insight into usage patterns while respecting the user's choice to share.
|
||||
|
||||
## License
|
||||
CrewAI is released under the MIT License
|
||||
|
||||
CrewAI is released under the [MIT License](https://github.com/crewAIInc/crewAI/blob/main/LICENSE).
|
||||
|
||||
## Frequently Asked Questions (FAQ)
|
||||
|
||||
### Q: What is CrewAI?
|
||||
A: CrewAI is a cutting-edge framework for orchestrating role-playing, autonomous AI agents. It enables agents to work together seamlessly, tackling complex tasks through collaborative intelligence.
|
||||
|
||||
### Q: How do I install CrewAI?
|
||||
A: You can install CrewAI using pip:
|
||||
```shell
|
||||
pip install crewai
|
||||
```
|
||||
For additional tools, use:
|
||||
```shell
|
||||
pip install 'crewai[tools]'
|
||||
```
|
||||
|
||||
### Q: Can I use CrewAI with local models?
|
||||
A: Yes, CrewAI supports various LLMs, including local models. You can configure your agents to use local models via tools like Ollama & LM Studio. Check the [LLM Connections documentation](https://docs.crewai.com/how-to/LLM-Connections/) for more details.
|
||||
|
||||
### Q: What are the key features of CrewAI?
|
||||
A: Key features include role-based agent design, autonomous inter-agent delegation, flexible task management, process-driven execution, output saving as files, and compatibility with both open-source and proprietary models.
|
||||
|
||||
### Q: How does CrewAI compare to other AI orchestration tools?
|
||||
A: CrewAI is designed with production in mind, offering flexibility similar to Autogen's conversational agents and structured processes like ChatDev, but with more adaptability for real-world applications.
|
||||
|
||||
### Q: Is CrewAI open-source?
|
||||
A: Yes, CrewAI is open-source and welcomes contributions from the community.
|
||||
|
||||
### Q: Does CrewAI collect any data?
|
||||
A: CrewAI uses anonymous telemetry to collect usage data for improvement purposes. No sensitive data (like prompts, task descriptions, or API calls) is collected. Users can opt-in to share more detailed data by setting `share_crew=True` on their Crews.
|
||||
|
||||
### Q: Where can I find examples of CrewAI in action?
|
||||
A: You can find various real-life examples in the [CrewAI-examples repository](https://github.com/crewAIInc/crewAI-examples), including trip planners, stock analysis tools, and more.
|
||||
|
||||
### Q: How can I contribute to CrewAI?
|
||||
A: Contributions are welcome! You can fork the repository, create a new branch for your feature, add your improvement, and send a pull request. Check the Contribution section in the README for more details.
|
||||
|
||||
|
Before Width: | Height: | Size: 431 KiB |
@@ -1463,11 +1463,11 @@
|
||||
"locked": false,
|
||||
"fontSize": 20,
|
||||
"fontFamily": 3,
|
||||
"text": "Agents have the inert ability of\nreach out to another to delegate\nwork or ask questions.",
|
||||
"text": "Agents have the innate ability of\nreach out to another to delegate\nwork or ask questions.",
|
||||
"textAlign": "right",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "Agents have the inert ability of\nreach out to another to delegate\nwork or ask questions.",
|
||||
"originalText": "Agents have the innate ability of\nreach out to another to delegate\nwork or ask questions.",
|
||||
"lineHeight": 1.2,
|
||||
"baseline": 68
|
||||
},
|
||||
@@ -1734,4 +1734,4 @@
|
||||
"viewBackgroundColor": "#ffffff"
|
||||
},
|
||||
"files": {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
from crewai.agent import Agent
|
||||
from crewai.crew import Crew
|
||||
from crewai.process import Process
|
||||
from crewai.task import Task
|
||||
155
crewai/agent.py
@@ -1,155 +0,0 @@
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from langchain.agents import AgentExecutor
|
||||
from langchain.agents.format_scratchpad import format_log_to_str
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from langchain.memory import ConversationSummaryMemory
|
||||
from langchain.tools.render import render_text_description
|
||||
from langchain_core.runnables.config import RunnableConfig
|
||||
from pydantic import BaseModel, Field, InstanceOf, model_validator
|
||||
|
||||
from crewai.agents import CacheHandler, CrewAgentOutputParser, ToolsHandler
|
||||
from crewai.prompts import Prompts
|
||||
|
||||
|
||||
class Agent(BaseModel):
|
||||
"""Represents an agent in a system.
|
||||
|
||||
Each agent has a role, a goal, a backstory, and an optional language model (llm).
|
||||
The agent can also have memory, can operate in verbose mode, and can delegate tasks to other agents.
|
||||
|
||||
Attributes:
|
||||
agent_executor: An instance of the AgentExecutor class.
|
||||
role: The role of the agent.
|
||||
goal: The objective of the agent.
|
||||
backstory: The backstory of the agent.
|
||||
llm: The language model that will run the agent.
|
||||
memory: Whether the agent should have memory or not.
|
||||
verbose: Whether the agent execution should be in verbose mode.
|
||||
allow_delegation: Whether the agent is allowed to delegate tasks to other agents.
|
||||
"""
|
||||
|
||||
class Config:
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
role: str = Field(description="Role of the agent")
|
||||
goal: str = Field(description="Objective of the agent")
|
||||
backstory: str = Field(description="Backstory of the agent")
|
||||
llm: Optional[Any] = Field(
|
||||
default_factory=lambda: ChatOpenAI(
|
||||
temperature=0.7,
|
||||
model_name="gpt-4",
|
||||
),
|
||||
description="Language model that will run the agent.",
|
||||
)
|
||||
memory: bool = Field(
|
||||
default=True, description="Whether the agent should have memory or not"
|
||||
)
|
||||
verbose: bool = Field(
|
||||
default=False, description="Verbose mode for the Agent Execution"
|
||||
)
|
||||
allow_delegation: bool = Field(
|
||||
default=True, description="Allow delegation of tasks to agents"
|
||||
)
|
||||
tools: List[Any] = Field(
|
||||
default_factory=list, description="Tools at agents disposal"
|
||||
)
|
||||
agent_executor: Optional[InstanceOf[AgentExecutor]] = Field(
|
||||
default=None, description="An instance of the AgentExecutor class."
|
||||
)
|
||||
tools_handler: Optional[InstanceOf[ToolsHandler]] = Field(
|
||||
default=None, description="An instance of the ToolsHandler class."
|
||||
)
|
||||
cache_handler: Optional[InstanceOf[CacheHandler]] = Field(
|
||||
default=CacheHandler(), description="An instance of the CacheHandler class."
|
||||
)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def check_agent_executor(self) -> "Agent":
|
||||
if not self.agent_executor:
|
||||
self.set_cache_handler(self.cache_handler)
|
||||
return self
|
||||
|
||||
def execute_task(
|
||||
self, task: str, context: str = None, tools: List[Any] = None
|
||||
) -> str:
|
||||
"""Execute a task with the agent.
|
||||
|
||||
Args:
|
||||
task: Task to execute.
|
||||
context: Context to execute the task in.
|
||||
tools: Tools to use for the task.
|
||||
|
||||
Returns:
|
||||
Output of the agent
|
||||
"""
|
||||
if context:
|
||||
task = "\n".join(
|
||||
[task, "\nThis is the context you are working with:", context]
|
||||
)
|
||||
|
||||
tools = tools or self.tools
|
||||
self.agent_executor.tools = tools
|
||||
|
||||
return self.agent_executor.invoke(
|
||||
{
|
||||
"input": task,
|
||||
"tool_names": self.__tools_names(tools),
|
||||
"tools": render_text_description(tools),
|
||||
},
|
||||
RunnableConfig(callbacks=[self.tools_handler]),
|
||||
)["output"]
|
||||
|
||||
def set_cache_handler(self, cache_handler) -> None:
|
||||
self.cache_handler = cache_handler
|
||||
self.tools_handler = ToolsHandler(cache=self.cache_handler)
|
||||
self.__create_agent_executor()
|
||||
|
||||
def __create_agent_executor(self) -> AgentExecutor:
|
||||
"""Create an agent executor for the agent.
|
||||
|
||||
Returns:
|
||||
An instance of the AgentExecutor class.
|
||||
"""
|
||||
agent_args = {
|
||||
"input": lambda x: x["input"],
|
||||
"tools": lambda x: x["tools"],
|
||||
"tool_names": lambda x: x["tool_names"],
|
||||
"agent_scratchpad": lambda x: format_log_to_str(x["intermediate_steps"]),
|
||||
}
|
||||
executor_args = {
|
||||
"tools": self.tools,
|
||||
"verbose": self.verbose,
|
||||
"handle_parsing_errors": True,
|
||||
}
|
||||
|
||||
if self.memory:
|
||||
summary_memory = ConversationSummaryMemory(
|
||||
llm=self.llm, memory_key="chat_history", input_key="input"
|
||||
)
|
||||
executor_args["memory"] = summary_memory
|
||||
agent_args["chat_history"] = lambda x: x["chat_history"]
|
||||
prompt = Prompts.TASK_EXECUTION_WITH_MEMORY_PROMPT
|
||||
else:
|
||||
prompt = Prompts.TASK_EXECUTION_PROMPT
|
||||
|
||||
execution_prompt = prompt.partial(
|
||||
goal=self.goal,
|
||||
role=self.role,
|
||||
backstory=self.backstory,
|
||||
)
|
||||
|
||||
bind = self.llm.bind(stop=["\nObservation"])
|
||||
inner_agent = (
|
||||
agent_args
|
||||
| execution_prompt
|
||||
| bind
|
||||
| CrewAgentOutputParser(
|
||||
tools_handler=self.tools_handler, cache=self.cache_handler
|
||||
)
|
||||
)
|
||||
self.agent_executor = AgentExecutor(agent=inner_agent, **executor_args)
|
||||
|
||||
@staticmethod
|
||||
def __tools_names(tools) -> str:
|
||||
return ", ".join([t.name for t in tools])
|
||||
@@ -1,3 +0,0 @@
|
||||
from .cache_handler import CacheHandler
|
||||
from .output_parser import CrewAgentOutputParser
|
||||
from .tools_handler import ToolsHandler
|
||||
@@ -1,81 +0,0 @@
|
||||
import re
|
||||
from typing import Union
|
||||
|
||||
from langchain.agents.output_parsers import ReActSingleInputOutputParser
|
||||
from langchain_core.agents import AgentAction, AgentFinish
|
||||
from langchain_core.exceptions import OutputParserException
|
||||
|
||||
from .cache_handler import CacheHandler
|
||||
from .tools_handler import ToolsHandler
|
||||
|
||||
FINAL_ANSWER_ACTION = "Final Answer:"
|
||||
FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE = (
|
||||
"Parsing LLM output produced both a final answer and a parse-able action:"
|
||||
)
|
||||
|
||||
|
||||
class CrewAgentOutputParser(ReActSingleInputOutputParser):
|
||||
"""Parses ReAct-style LLM calls that have a single tool input.
|
||||
|
||||
Expects output to be in one of two formats.
|
||||
|
||||
If the output signals that an action should be taken,
|
||||
should be in the below format. This will result in an AgentAction
|
||||
being returned.
|
||||
|
||||
```
|
||||
Thought: agent thought here
|
||||
Action: search
|
||||
Action Input: what is the temperature in SF?
|
||||
```
|
||||
|
||||
If the output signals that a final answer should be given,
|
||||
should be in the below format. This will result in an AgentFinish
|
||||
being returned.
|
||||
|
||||
```
|
||||
Thought: agent thought here
|
||||
Final Answer: The temperature is 100 degrees
|
||||
```
|
||||
|
||||
It also prevents tools from being reused in a roll.
|
||||
"""
|
||||
|
||||
class Config:
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
tools_handler: ToolsHandler
|
||||
cache: CacheHandler
|
||||
|
||||
def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
|
||||
includes_answer = FINAL_ANSWER_ACTION in text
|
||||
regex = (
|
||||
r"Action\s*\d*\s*:[\s]*(.*?)[\s]*Action\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)"
|
||||
)
|
||||
action_match = re.search(regex, text, re.DOTALL)
|
||||
if action_match:
|
||||
if includes_answer:
|
||||
raise OutputParserException(
|
||||
f"{FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE}: {text}"
|
||||
)
|
||||
action = action_match.group(1).strip()
|
||||
action_input = action_match.group(2)
|
||||
tool_input = action_input.strip(" ")
|
||||
tool_input = tool_input.strip('"')
|
||||
|
||||
last_tool_usage = self.tools_handler.last_used_tool
|
||||
if last_tool_usage:
|
||||
usage = {
|
||||
"tool": action,
|
||||
"input": tool_input,
|
||||
}
|
||||
if usage == last_tool_usage:
|
||||
raise OutputParserException(
|
||||
f"""\nI just used the {action} tool with input {tool_input}. So I already knwo the result of that."""
|
||||
)
|
||||
|
||||
result = self.cache.read(action, tool_input)
|
||||
if result:
|
||||
return AgentFinish({"output": result}, text)
|
||||
|
||||
return super().parse(text)
|
||||
@@ -1,42 +0,0 @@
|
||||
from typing import Any, Dict
|
||||
|
||||
from langchain.callbacks.base import BaseCallbackHandler
|
||||
|
||||
from .cache_handler import CacheHandler
|
||||
|
||||
|
||||
class ToolsHandler(BaseCallbackHandler):
|
||||
"""Callback handler for tool usage."""
|
||||
|
||||
last_used_tool: Dict[str, Any] = {}
|
||||
cache: CacheHandler = None
|
||||
|
||||
def __init__(self, cache: CacheHandler = None, **kwargs: Any):
|
||||
"""Initialize the callback handler."""
|
||||
self.cache = cache
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def on_tool_start(
|
||||
self, serialized: Dict[str, Any], input_str: str, **kwargs: Any
|
||||
) -> Any:
|
||||
"""Run when tool starts running."""
|
||||
name = serialized.get("name")
|
||||
if name not in ["invalid_tool", "_Exception"]:
|
||||
tools_usage = {
|
||||
"tool": name,
|
||||
"input": input_str,
|
||||
}
|
||||
self.last_used_tool = tools_usage
|
||||
|
||||
def on_tool_end(self, output: str, **kwargs: Any) -> Any:
|
||||
"""Run when tool ends running."""
|
||||
if (
|
||||
"is not a valid tool" not in output
|
||||
and "Invalid or incomplete response" not in output
|
||||
and "Invalid Format" not in output
|
||||
):
|
||||
self.cache.add(
|
||||
tool=self.last_used_tool["tool"],
|
||||
input=self.last_used_tool["input"],
|
||||
output=output,
|
||||
)
|
||||
122
crewai/crew.py
@@ -1,122 +0,0 @@
|
||||
import json
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from pydantic import (
|
||||
BaseModel,
|
||||
Field,
|
||||
InstanceOf,
|
||||
Json,
|
||||
field_validator,
|
||||
model_validator,
|
||||
)
|
||||
from pydantic_core import PydanticCustomError
|
||||
|
||||
from crewai.agent import Agent
|
||||
from crewai.agents import CacheHandler
|
||||
from crewai.process import Process
|
||||
from crewai.task import Task
|
||||
from crewai.tools.agent_tools import AgentTools
|
||||
|
||||
|
||||
class Crew(BaseModel):
|
||||
"""Class that represents a group of agents, how they should work together and their tasks."""
|
||||
|
||||
class Config:
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
tasks: List[Task] = Field(description="List of tasks", default_factory=list)
|
||||
agents: List[Agent] = Field(
|
||||
description="List of agents in this crew.", default_factory=list
|
||||
)
|
||||
process: Process = Field(
|
||||
description="Process that the crew will follow.", default=Process.sequential
|
||||
)
|
||||
verbose: Union[int, bool] = Field(
|
||||
description="Verbose mode for the Agent Execution", default=0
|
||||
)
|
||||
config: Optional[Union[Json, Dict[str, Any]]] = Field(
|
||||
description="Configuration of the crew.", default=None
|
||||
)
|
||||
cache_handler: Optional[InstanceOf[CacheHandler]] = Field(
|
||||
default=CacheHandler(), description="An instance of the CacheHandler class."
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@field_validator("config", mode="before")
|
||||
def check_config_type(cls, v: Union[Json, Dict[str, Any]]):
|
||||
if isinstance(v, Json):
|
||||
return json.loads(v)
|
||||
return v
|
||||
|
||||
@model_validator(mode="after")
|
||||
def check_config(self):
|
||||
if not self.config and not self.tasks and not self.agents:
|
||||
raise PydanticCustomError(
|
||||
"missing_keys", "Either agents and task need to be set or config.", {}
|
||||
)
|
||||
|
||||
if self.config:
|
||||
if not self.config.get("agents") or not self.config.get("tasks"):
|
||||
raise PydanticCustomError(
|
||||
"missing_keys_in_config", "Config should have agents and tasks", {}
|
||||
)
|
||||
|
||||
self.agents = [Agent(**agent) for agent in self.config["agents"]]
|
||||
|
||||
tasks = []
|
||||
for task in self.config["tasks"]:
|
||||
task_agent = [agt for agt in self.agents if agt.role == task["agent"]][
|
||||
0
|
||||
]
|
||||
del task["agent"]
|
||||
tasks.append(Task(**task, agent=task_agent))
|
||||
|
||||
self.tasks = tasks
|
||||
|
||||
if self.agents:
|
||||
for agent in self.agents:
|
||||
agent.set_cache_handler(self.cache_handler)
|
||||
return self
|
||||
|
||||
def kickoff(self) -> str:
|
||||
"""Kickoff the crew to work on its tasks.
|
||||
|
||||
Returns:
|
||||
Output of the crew for each task.
|
||||
"""
|
||||
for agent in self.agents:
|
||||
agent.cache_handler = self.cache_handler
|
||||
|
||||
if self.process == Process.sequential:
|
||||
return self.__sequential_loop()
|
||||
|
||||
def __sequential_loop(self) -> str:
|
||||
"""Loop that executes the sequential process.
|
||||
|
||||
Returns:
|
||||
Output of the crew.
|
||||
"""
|
||||
task_outcome = None
|
||||
for task in self.tasks:
|
||||
# Add delegation tools to the task if the agent allows it
|
||||
if task.agent.allow_delegation:
|
||||
tools = AgentTools(agents=self.agents).tools()
|
||||
task.tools += tools
|
||||
|
||||
self.__log("debug", f"Working Agent: {task.agent.role}")
|
||||
self.__log("info", f"Starting Task: {task.description} ...")
|
||||
|
||||
task_outcome = task.execute(task_outcome)
|
||||
|
||||
self.__log("debug", f"Task output: {task_outcome}")
|
||||
|
||||
return task_outcome
|
||||
|
||||
def __log(self, level, message):
|
||||
"""Log a message"""
|
||||
level_map = {"debug": 1, "info": 2}
|
||||
verbose_level = (
|
||||
2 if isinstance(self.verbose, bool) and self.verbose else self.verbose
|
||||
)
|
||||
if verbose_level and level_map[level] <= verbose_level:
|
||||
print(message)
|
||||
@@ -1,84 +0,0 @@
|
||||
"""Prompts for generic agent."""
|
||||
|
||||
from textwrap import dedent
|
||||
from typing import ClassVar
|
||||
|
||||
from langchain.prompts import PromptTemplate
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class Prompts(BaseModel):
|
||||
"""Prompts for generic agent."""
|
||||
|
||||
TASK_SLICE: ClassVar[str] = dedent(
|
||||
"""\
|
||||
Begin! This is VERY important to you, your job depends on it!
|
||||
|
||||
Current Task: {input}"""
|
||||
)
|
||||
|
||||
SCRATCHPAD_SLICE: ClassVar[str] = "\n{agent_scratchpad}"
|
||||
|
||||
MEMORY_SLICE: ClassVar[str] = dedent(
|
||||
"""\
|
||||
This is the summary of your work so far:
|
||||
{chat_history}"""
|
||||
)
|
||||
|
||||
ROLE_PLAYING_SLICE: ClassVar[str] = dedent(
|
||||
"""\
|
||||
You are {role}.
|
||||
{backstory}
|
||||
|
||||
Your personal goal is: {goal}"""
|
||||
)
|
||||
|
||||
TOOLS_SLICE: ClassVar[str] = dedent(
|
||||
"""\
|
||||
|
||||
|
||||
TOOLS:
|
||||
------
|
||||
You have access to the following tools:
|
||||
|
||||
{tools}
|
||||
|
||||
To use a tool, please use the exact following format:
|
||||
|
||||
```
|
||||
Thought: Do I need to use a tool? Yes
|
||||
Action: the action to take, should be one of [{tool_names}], just the name.
|
||||
Action Input: the input to the action
|
||||
Observation: the result of the action
|
||||
```
|
||||
|
||||
When you have a response for your task, or if you do not need to use a tool, you MUST use the format:
|
||||
|
||||
```
|
||||
Thought: Do I need to use a tool? No
|
||||
Final Answer: [your response here]
|
||||
```"""
|
||||
)
|
||||
|
||||
VOTING_SLICE: ClassVar[str] = dedent(
|
||||
"""\
|
||||
You are working on a crew with your co-workers and need to decide who will execute the task.
|
||||
|
||||
These are your format instructions:
|
||||
{format_instructions}
|
||||
|
||||
These are your co-workers and their roles:
|
||||
{coworkers}"""
|
||||
)
|
||||
|
||||
TASK_EXECUTION_WITH_MEMORY_PROMPT: ClassVar[str] = PromptTemplate.from_template(
|
||||
ROLE_PLAYING_SLICE + TOOLS_SLICE + MEMORY_SLICE + TASK_SLICE + SCRATCHPAD_SLICE
|
||||
)
|
||||
|
||||
TASK_EXECUTION_PROMPT: ClassVar[str] = PromptTemplate.from_template(
|
||||
ROLE_PLAYING_SLICE + TOOLS_SLICE + TASK_SLICE + SCRATCHPAD_SLICE
|
||||
)
|
||||
|
||||
CONSENSUNS_VOTING_PROMPT: ClassVar[str] = PromptTemplate.from_template(
|
||||
ROLE_PLAYING_SLICE + VOTING_SLICE + TASK_SLICE + SCRATCHPAD_SLICE
|
||||
)
|
||||
@@ -1,39 +0,0 @@
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
from crewai.agent import Agent
|
||||
|
||||
|
||||
class Task(BaseModel):
|
||||
"""Class that represent a task to be executed."""
|
||||
|
||||
description: str = Field(description="Description of the actual task.")
|
||||
agent: Optional[Agent] = Field(
|
||||
description="Agent responsible for the task.", default=None
|
||||
)
|
||||
tools: List[Any] = Field(
|
||||
default_factory=list,
|
||||
description="Tools the agent are limited to use for this task.",
|
||||
)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def check_tools(self):
|
||||
if not self.tools and (self.agent and self.agent.tools):
|
||||
self.tools.extend(self.agent.tools)
|
||||
return self
|
||||
|
||||
def execute(self, context: str = None) -> str:
|
||||
"""Execute the task.
|
||||
|
||||
Returns:
|
||||
Output of the task.
|
||||
"""
|
||||
if self.agent:
|
||||
return self.agent.execute_task(
|
||||
task=self.description, context=context, tools=self.tools
|
||||
)
|
||||
else:
|
||||
raise Exception(
|
||||
f"The task '{self.description}' has no agent assigned, therefore it can't be executed directly and should be executed in a Crew using a specific process that support that, either consensual or hierarchical."
|
||||
)
|
||||
@@ -1,72 +0,0 @@
|
||||
from textwrap import dedent
|
||||
from typing import List
|
||||
|
||||
from langchain.tools import Tool
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from crewai.agent import Agent
|
||||
|
||||
|
||||
class AgentTools(BaseModel):
|
||||
"""Tools for generic agent."""
|
||||
|
||||
agents: List[Agent] = Field(description="List of agents in this crew.")
|
||||
|
||||
def tools(self):
|
||||
return [
|
||||
Tool.from_function(
|
||||
func=self.delegate_work,
|
||||
name="Delegate work to co-worker",
|
||||
description=dedent(
|
||||
f"""Useful to delegate a specific task to one of the
|
||||
following co-workers: [{', '.join([agent.role for agent in self.agents])}].
|
||||
The input to this tool should be a pipe (|) separated text of length
|
||||
three, representing the role you want to delegate it to, the task and
|
||||
information necessary. For example, `coworker|task|information`.
|
||||
"""
|
||||
),
|
||||
),
|
||||
Tool.from_function(
|
||||
func=self.ask_question,
|
||||
name="Ask question to co-worker",
|
||||
description=dedent(
|
||||
f"""Useful to ask a question, opinion or take from on
|
||||
of the following co-workers: [{', '.join([agent.role for agent in self.agents])}].
|
||||
The input to this tool should be a pipe (|) separated text of length
|
||||
three, representing the role you want to ask it to, the question and
|
||||
information necessary. For example, `coworker|question|information`.
|
||||
"""
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
def delegate_work(self, command):
|
||||
"""Useful to delegate a specific task to a coworker."""
|
||||
return self.__execute(command)
|
||||
|
||||
def ask_question(self, command):
|
||||
"""Useful to ask a question, opinion or take from a coworker."""
|
||||
return self.__execute(command)
|
||||
|
||||
def __execute(self, command):
|
||||
"""Execute the command."""
|
||||
try:
|
||||
agent, task, information = command.split("|")
|
||||
except ValueError:
|
||||
return "\nError executing tool. Missing exact 3 pipe (|) separated values. For example, `coworker|task|information`."
|
||||
|
||||
if not agent or not task or not information:
|
||||
return "\nError executing tool. Missing exact 3 pipe (|) separated values. For example, `coworker|question|information`."
|
||||
|
||||
agent = [
|
||||
available_agent
|
||||
for available_agent in self.agents
|
||||
if available_agent.role == agent
|
||||
]
|
||||
|
||||
if len(agent) == 0:
|
||||
return f"\nError executing tool. Co-worker mentioned on the Action Input not found, it must to be one of the following options: {', '.join([agent.role for agent in self.agents])}."
|
||||
|
||||
agent = agent[0]
|
||||
result = agent.execute_task(task, information)
|
||||
return result
|
||||
BIN
crewai_logo.png
|
Before Width: | Height: | Size: 94 KiB |
161
docs/concepts/agents.mdx
Normal file
@@ -0,0 +1,161 @@
|
||||
---
|
||||
title: Agents
|
||||
description: What are CrewAI Agents and how to use them.
|
||||
icon: robot
|
||||
---
|
||||
|
||||
## What is an agent?
|
||||
|
||||
An agent is an **autonomous unit** programmed to:
|
||||
<ul>
|
||||
<li class='leading-3'>Perform tasks</li>
|
||||
<li class='leading-3'>Make decisions</li>
|
||||
<li class='leading-3'>Communicate with other agents</li>
|
||||
</ul>
|
||||
|
||||
<Tip>
|
||||
Think of an agent as a member of a team, with specific skills and a particular job to do. Agents can have different roles like `Researcher`, `Writer`, or `Customer Support`, each contributing to the overall goal of the crew.
|
||||
</Tip>
|
||||
|
||||
## Agent attributes
|
||||
|
||||
| Attribute | Parameter | Description |
|
||||
| :------------------------- | :--------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Role** | `role` | Defines the agent's function within the crew. It determines the kind of tasks the agent is best suited for. |
|
||||
| **Goal** | `goal` | The individual objective that the agent aims to achieve. It guides the agent's decision-making process. |
|
||||
| **Backstory** | `backstory`| Provides context to the agent's role and goal, enriching the interaction and collaboration dynamics. |
|
||||
| **LLM** *(optional)* | `llm` | Represents the language model that will run the agent. It dynamically fetches the model name from the `OPENAI_MODEL_NAME` environment variable, defaulting to "gpt-4" if not specified. |
|
||||
| **Tools** *(optional)* | `tools` | Set of capabilities or functions that the agent can use to perform tasks. Expected to be instances of custom classes compatible with the agent's execution environment. Tools are initialized with a default value of an empty list. |
|
||||
| **Function Calling LLM** *(optional)* | `function_calling_llm` | Specifies the language model that will handle the tool calling for this agent, overriding the crew function calling LLM if passed. Default is `None`. |
|
||||
| **Max Iter** *(optional)* | `max_iter` | Max Iter is the maximum number of iterations the agent can perform before being forced to give its best answer. Default is `25`. |
|
||||
| **Max RPM** *(optional)* | `max_rpm` | Max RPM is the maximum number of requests per minute the agent can perform to avoid rate limits. It's optional and can be left unspecified, with a default value of `None`. |
|
||||
| **Max Execution Time** *(optional)* | `max_execution_time` | Max Execution Time is the maximum execution time for an agent to execute a task. It's optional and can be left unspecified, with a default value of `None`, meaning no max execution time. |
|
||||
| **Verbose** *(optional)* | `verbose` | Setting this to `True` configures the internal logger to provide detailed execution logs, aiding in debugging and monitoring. Default is `False`. |
|
||||
| **Allow Delegation** *(optional)* | `allow_delegation` | Agents can delegate tasks or questions to one another, ensuring that each task is handled by the most suitable agent. Default is `False`. |
|
||||
| **Step Callback** *(optional)* | `step_callback` | A function that is called after each step of the agent. This can be used to log the agent's actions or to perform other operations. It will overwrite the crew `step_callback`. |
|
||||
| **Cache** *(optional)* | `cache` | Indicates if the agent should use a cache for tool usage. Default is `True`. |
|
||||
| **System Template** *(optional)* | `system_template` | Specifies the system format for the agent. Default is `None`. |
|
||||
| **Prompt Template** *(optional)* | `prompt_template` | Specifies the prompt format for the agent. Default is `None`. |
|
||||
| **Response Template** *(optional)* | `response_template` | Specifies the response format for the agent. Default is `None`. |
|
||||
| **Allow Code Execution** *(optional)* | `allow_code_execution` | Enable code execution for the agent. Default is `False`. |
|
||||
| **Max Retry Limit** *(optional)* | `max_retry_limit` | Maximum number of retries for an agent to execute a task when an error occurs. Default is `2`. |
|
||||
| **Use System Prompt** *(optional)* | `use_system_prompt` | Adds the ability to not use system prompt (to support o1 models). Default is `True`. |
|
||||
| **Respect Context Window** *(optional)* | `respect_context_window` | Summary strategy to avoid overflowing the context window. Default is `True`. |
|
||||
| **Code Execution Mode** *(optional)* | `code_execution_mode` | Determines the mode for code execution: 'safe' (using Docker) or 'unsafe' (direct execution on the host machine). Default is `safe`. |
|
||||
|
||||
## Creating an agent
|
||||
|
||||
<Note>
|
||||
**Agent interaction**: Agents can interact with each other using CrewAI's built-in delegation and communication mechanisms. This allows for dynamic task management and problem-solving within the crew.
|
||||
</Note>
|
||||
|
||||
To create an agent, you would typically initialize an instance of the `Agent` class with the desired properties. Here's a conceptual example including all attributes:
|
||||
|
||||
```python Code example
|
||||
from crewai import Agent
|
||||
|
||||
agent = Agent(
|
||||
role='Data Analyst',
|
||||
goal='Extract actionable insights',
|
||||
backstory="""You're a data analyst at a large company.
|
||||
You're responsible for analyzing data and providing insights
|
||||
to the business.
|
||||
You're currently working on a project to analyze the
|
||||
performance of our marketing campaigns.""",
|
||||
tools=[my_tool1, my_tool2], # Optional, defaults to an empty list
|
||||
llm=my_llm, # Optional
|
||||
function_calling_llm=my_llm, # Optional
|
||||
max_iter=15, # Optional
|
||||
max_rpm=None, # Optional
|
||||
max_execution_time=None, # Optional
|
||||
verbose=True, # Optional
|
||||
allow_delegation=False, # Optional
|
||||
step_callback=my_intermediate_step_callback, # Optional
|
||||
cache=True, # Optional
|
||||
system_template=my_system_template, # Optional
|
||||
prompt_template=my_prompt_template, # Optional
|
||||
response_template=my_response_template, # Optional
|
||||
config=my_config, # Optional
|
||||
crew=my_crew, # Optional
|
||||
tools_handler=my_tools_handler, # Optional
|
||||
cache_handler=my_cache_handler, # Optional
|
||||
callbacks=[callback1, callback2], # Optional
|
||||
allow_code_execution=True, # Optional
|
||||
max_retry_limit=2, # Optional
|
||||
use_system_prompt=True, # Optional
|
||||
respect_context_window=True, # Optional
|
||||
code_execution_mode='safe', # Optional, defaults to 'safe'
|
||||
)
|
||||
```
|
||||
|
||||
## Setting prompt templates
|
||||
|
||||
Prompt templates are used to format the prompt for the agent. You can use to update the system, regular and response templates for the agent. Here's an example of how to set prompt templates:
|
||||
|
||||
```python Code example
|
||||
agent = Agent(
|
||||
role="{topic} specialist",
|
||||
goal="Figure {goal} out",
|
||||
backstory="I am the master of {role}",
|
||||
system_template="""<|start_header_id|>system<|end_header_id|>
|
||||
{{ .System }}<|eot_id|>""",
|
||||
prompt_template="""<|start_header_id|>user<|end_header_id|>
|
||||
{{ .Prompt }}<|eot_id|>""",
|
||||
response_template="""<|start_header_id|>assistant<|end_header_id|>
|
||||
{{ .Response }}<|eot_id|>""",
|
||||
)
|
||||
```
|
||||
|
||||
## Bring your third-party agents
|
||||
|
||||
Extend your third-party agents like LlamaIndex, Langchain, Autogen or fully custom agents using the the CrewAI's `BaseAgent` class.
|
||||
|
||||
<Note>
|
||||
**BaseAgent** includes attributes and methods required to integrate with your crews to run and delegate tasks to other agents within your own crew.
|
||||
</Note>
|
||||
|
||||
CrewAI is a universal multi-agent framework that allows for all agents to work together to automate tasks and solve problems.
|
||||
|
||||
```python Code example
|
||||
from crewai import Agent, Task, Crew
|
||||
from custom_agent import CustomAgent # You need to build and extend your own agent logic with the CrewAI BaseAgent class then import it here.
|
||||
|
||||
from langchain.agents import load_tools
|
||||
|
||||
langchain_tools = load_tools(["google-serper"], llm=llm)
|
||||
|
||||
agent1 = CustomAgent(
|
||||
role="agent role",
|
||||
goal="who is {input}?",
|
||||
backstory="agent backstory",
|
||||
verbose=True,
|
||||
)
|
||||
|
||||
task1 = Task(
|
||||
expected_output="a short biography of {input}",
|
||||
description="a short biography of {input}",
|
||||
agent=agent1,
|
||||
)
|
||||
|
||||
agent2 = Agent(
|
||||
role="agent role",
|
||||
goal="summarize the short bio for {input} and if needed do more research",
|
||||
backstory="agent backstory",
|
||||
verbose=True,
|
||||
)
|
||||
|
||||
task2 = Task(
|
||||
description="a tldr summary of the short biography",
|
||||
expected_output="5 bullet point summary of the biography",
|
||||
agent=agent2,
|
||||
context=[task1],
|
||||
)
|
||||
|
||||
my_crew = Crew(agents=[agent1, agent2], tasks=[task1, task2])
|
||||
crew = my_crew.kickoff(inputs={"input": "Mark Twain"})
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Agents are the building blocks of the CrewAI framework. By understanding how to define and interact with agents,
|
||||
you can create sophisticated AI systems that leverage the power of collaborative intelligence. The `code_execution_mode` attribute provides flexibility in how agents execute code, allowing for both secure and direct execution options.
|
||||
179
docs/concepts/cli.mdx
Normal file
@@ -0,0 +1,179 @@
|
||||
---
|
||||
title: CLI
|
||||
description: Learn how to use the CrewAI CLI to interact with CrewAI.
|
||||
icon: terminal
|
||||
---
|
||||
|
||||
# CrewAI CLI Documentation
|
||||
|
||||
The CrewAI CLI provides a set of commands to interact with CrewAI, allowing you to create, train, run, and manage crews & flows.
|
||||
|
||||
## Installation
|
||||
|
||||
To use the CrewAI CLI, make sure you have CrewAI installed:
|
||||
|
||||
```shell
|
||||
pip install crewai
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
|
||||
The basic structure of a CrewAI CLI command is:
|
||||
|
||||
```shell
|
||||
crewai [COMMAND] [OPTIONS] [ARGUMENTS]
|
||||
```
|
||||
|
||||
## Available Commands
|
||||
|
||||
### 1. Create
|
||||
|
||||
Create a new crew or pipeline.
|
||||
|
||||
```shell
|
||||
crewai create [OPTIONS] TYPE NAME
|
||||
```
|
||||
|
||||
- `TYPE`: Choose between "crew" or "pipeline"
|
||||
- `NAME`: Name of the crew or pipeline
|
||||
- `--router`: (Optional) Create a pipeline with router functionality
|
||||
|
||||
Example:
|
||||
```shell
|
||||
crewai create crew my_new_crew
|
||||
crewai create pipeline my_new_pipeline --router
|
||||
```
|
||||
|
||||
### 2. Version
|
||||
|
||||
Show the installed version of CrewAI.
|
||||
|
||||
```shell
|
||||
crewai version [OPTIONS]
|
||||
```
|
||||
|
||||
- `--tools`: (Optional) Show the installed version of CrewAI tools
|
||||
|
||||
Example:
|
||||
```shell
|
||||
crewai version
|
||||
crewai version --tools
|
||||
```
|
||||
|
||||
### 3. Train
|
||||
|
||||
Train the crew for a specified number of iterations.
|
||||
|
||||
```shell
|
||||
crewai train [OPTIONS]
|
||||
```
|
||||
|
||||
- `-n, --n_iterations INTEGER`: Number of iterations to train the crew (default: 5)
|
||||
- `-f, --filename TEXT`: Path to a custom file for training (default: "trained_agents_data.pkl")
|
||||
|
||||
Example:
|
||||
```shell
|
||||
crewai train -n 10 -f my_training_data.pkl
|
||||
```
|
||||
|
||||
### 4. Replay
|
||||
|
||||
Replay the crew execution from a specific task.
|
||||
|
||||
```shell
|
||||
crewai replay [OPTIONS]
|
||||
```
|
||||
|
||||
- `-t, --task_id TEXT`: Replay the crew from this task ID, including all subsequent tasks
|
||||
|
||||
Example:
|
||||
```shell
|
||||
crewai replay -t task_123456
|
||||
```
|
||||
|
||||
### 5. Log-tasks-outputs
|
||||
|
||||
Retrieve your latest crew.kickoff() task outputs.
|
||||
|
||||
```shell
|
||||
crewai log-tasks-outputs
|
||||
```
|
||||
|
||||
### 6. Reset-memories
|
||||
|
||||
Reset the crew memories (long, short, entity, latest_crew_kickoff_outputs).
|
||||
|
||||
```shell
|
||||
crewai reset-memories [OPTIONS]
|
||||
```
|
||||
|
||||
- `-l, --long`: Reset LONG TERM memory
|
||||
- `-s, --short`: Reset SHORT TERM memory
|
||||
- `-e, --entities`: Reset ENTITIES memory
|
||||
- `-k, --kickoff-outputs`: Reset LATEST KICKOFF TASK OUTPUTS
|
||||
- `-a, --all`: Reset ALL memories
|
||||
|
||||
Example:
|
||||
```shell
|
||||
crewai reset-memories --long --short
|
||||
crewai reset-memories --all
|
||||
```
|
||||
|
||||
### 7. Test
|
||||
|
||||
Test the crew and evaluate the results.
|
||||
|
||||
```shell
|
||||
crewai test [OPTIONS]
|
||||
```
|
||||
|
||||
- `-n, --n_iterations INTEGER`: Number of iterations to test the crew (default: 3)
|
||||
- `-m, --model TEXT`: LLM Model to run the tests on the Crew (default: "gpt-4o-mini")
|
||||
|
||||
Example:
|
||||
```shell
|
||||
crewai test -n 5 -m gpt-3.5-turbo
|
||||
```
|
||||
|
||||
### 8. Run
|
||||
|
||||
Run the crew.
|
||||
|
||||
```shell
|
||||
crewai run
|
||||
```
|
||||
<Note>
|
||||
Make sure to run these commands from the directory where your CrewAI project is set up.
|
||||
Some commands may require additional configuration or setup within your project structure.
|
||||
</Note>
|
||||
|
||||
|
||||
### 9. API Keys
|
||||
|
||||
When running ```crewai create crew``` command, the CLI will first show you the top 5 most common LLM providers and ask you to select one.
|
||||
|
||||
Once you've selected an LLM provider, you will be prompted for API keys.
|
||||
|
||||
#### Initial API key providers
|
||||
|
||||
The CLI will initially prompt for API keys for the following services:
|
||||
|
||||
* OpenAI
|
||||
* Groq
|
||||
* Anthropic
|
||||
* Google Gemini
|
||||
|
||||
When you select a provider, the CLI will prompt you to enter your API key.
|
||||
|
||||
#### Other Options
|
||||
|
||||
If you select option 6, you will be able to select from a list of LiteLLM supported providers.
|
||||
|
||||
When you select a provider, the CLI will prompt you to enter the Key name and the API key.
|
||||
|
||||
See the following link for each provider's key name:
|
||||
|
||||
* [LiteLLM Providers](https://docs.litellm.ai/docs/providers)
|
||||
|
||||
|
||||
|
||||
52
docs/concepts/collaboration.mdx
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
title: Collaboration
|
||||
description: Exploring the dynamics of agent collaboration within the CrewAI framework, focusing on the newly integrated features for enhanced functionality.
|
||||
icon: screen-users
|
||||
---
|
||||
|
||||
## Collaboration Fundamentals
|
||||
|
||||
Collaboration in CrewAI is fundamental, enabling agents to combine their skills, share information, and assist each other in task execution, embodying a truly cooperative ecosystem.
|
||||
|
||||
- **Information Sharing**: Ensures all agents are well-informed and can contribute effectively by sharing data and findings.
|
||||
- **Task Assistance**: Allows agents to seek help from peers with the required expertise for specific tasks.
|
||||
- **Resource Allocation**: Optimizes task execution through the efficient distribution and sharing of resources among agents.
|
||||
|
||||
## Enhanced Attributes for Improved Collaboration
|
||||
|
||||
The `Crew` class has been enriched with several attributes to support advanced functionalities:
|
||||
|
||||
| Feature | Description |
|
||||
|:-------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **Language Model Management** (`manager_llm`, `function_calling_llm`) | Manages language models for executing tasks and tools. `manager_llm` is required for hierarchical processes, while `function_calling_llm` is optional with a default value for streamlined interactions. |
|
||||
| **Custom Manager Agent** (`manager_agent`) | Specifies a custom agent as the manager, replacing the default CrewAI manager. |
|
||||
| **Process Flow** (`process`) | Defines execution logic (e.g., sequential, hierarchical) for task distribution. |
|
||||
| **Verbose Logging** (`verbose`) | Provides detailed logging for monitoring and debugging. Accepts integer and boolean values to control verbosity level. |
|
||||
| **Rate Limiting** (`max_rpm`) | Limits requests per minute to optimize resource usage. Setting guidelines depend on task complexity and load. |
|
||||
| **Internationalization / Customization** (`language`, `prompt_file`) | Supports prompt customization for global usability. [Example of file](https://github.com/joaomdmoura/crewAI/blob/main/src/crewai/translations/en.json) |
|
||||
| **Execution and Output Handling** (`full_output`) | Controls output granularity, distinguishing between full and final outputs. |
|
||||
| **Callback and Telemetry** (`step_callback`, `task_callback`) | Enables step-wise and task-level execution monitoring and telemetry for performance analytics. |
|
||||
| **Crew Sharing** (`share_crew`) | Allows sharing crew data with CrewAI for model improvement. Privacy implications and benefits should be considered. |
|
||||
| **Usage Metrics** (`usage_metrics`) | Logs all LLM usage metrics during task execution for performance insights. |
|
||||
| **Memory Usage** (`memory`) | Enables memory for storing execution history, aiding in agent learning and task efficiency. |
|
||||
| **Embedder Configuration** (`embedder`) | Configures the embedder for language understanding and generation, with support for provider customization. |
|
||||
| **Cache Management** (`cache`) | Specifies whether to cache tool execution results, enhancing performance. |
|
||||
| **Output Logging** (`output_log_file`) | Defines the file path for logging crew execution output. |
|
||||
| **Planning Mode** (`planning`) | Enables action planning before task execution. Set `planning=True` to activate. |
|
||||
| **Replay Feature** (`replay`) | Provides CLI for listing tasks from the last run and replaying from specific tasks, aiding in task management and troubleshooting. |
|
||||
|
||||
## Delegation (Dividing to Conquer)
|
||||
|
||||
Delegation enhances functionality by allowing agents to intelligently assign tasks or seek help, thereby amplifying the crew's overall capability.
|
||||
|
||||
## Implementing Collaboration and Delegation
|
||||
|
||||
Setting up a crew involves defining the roles and capabilities of each agent. CrewAI seamlessly manages their interactions, ensuring efficient collaboration and delegation, with enhanced customization and monitoring features to adapt to various operational needs.
|
||||
|
||||
## Example Scenario
|
||||
|
||||
Consider a crew with a researcher agent tasked with data gathering and a writer agent responsible for compiling reports. The integration of advanced language model management and process flow attributes allows for more sophisticated interactions, such as the writer delegating complex research tasks to the researcher or querying specific information, thereby facilitating a seamless workflow.
|
||||
|
||||
## Conclusion
|
||||
|
||||
The integration of advanced attributes and functionalities into the CrewAI framework significantly enriches the agent collaboration ecosystem. These enhancements not only simplify interactions but also offer unprecedented flexibility and control, paving the way for sophisticated AI-driven solutions capable of tackling complex tasks through intelligent collaboration and delegation.
|
||||
190
docs/concepts/crews.mdx
Normal file
@@ -0,0 +1,190 @@
|
||||
---
|
||||
title: Crews
|
||||
description: Understanding and utilizing crews in the crewAI framework with comprehensive attributes and functionalities.
|
||||
icon: people-group
|
||||
---
|
||||
|
||||
## What is a Crew?
|
||||
|
||||
A crew in crewAI represents a collaborative group of agents working together to achieve a set of tasks. Each crew defines the strategy for task execution, agent collaboration, and the overall workflow.
|
||||
|
||||
## Crew Attributes
|
||||
|
||||
| Attribute | Parameters | Description |
|
||||
| :------------------------------------ | :--------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Tasks** | `tasks` | A list of tasks assigned to the crew. |
|
||||
| **Agents** | `agents` | A list of agents that are part of the crew. |
|
||||
| **Process** _(optional)_ | `process` | The process flow (e.g., sequential, hierarchical) the crew follows. Default is `sequential`. |
|
||||
| **Verbose** _(optional)_ | `verbose` | The verbosity level for logging during execution. Defaults to `False`. |
|
||||
| **Manager LLM** _(optional)_ | `manager_llm` | The language model used by the manager agent in a hierarchical process. **Required when using a hierarchical process.** |
|
||||
| **Function Calling LLM** _(optional)_ | `function_calling_llm` | If passed, the crew will use this LLM to do function calling for tools for all agents in the crew. Each agent can have its own LLM, which overrides the crew's LLM for function calling. |
|
||||
| **Config** _(optional)_ | `config` | Optional configuration settings for the crew, in `Json` or `Dict[str, Any]` format. |
|
||||
| **Max RPM** _(optional)_ | `max_rpm` | Maximum requests per minute the crew adheres to during execution. Defaults to `None`. |
|
||||
| **Language** _(optional)_ | `language` | Language used for the crew, defaults to English. |
|
||||
| **Language File** _(optional)_ | `language_file` | Path to the language file to be used for the crew. |
|
||||
| **Memory** _(optional)_ | `memory` | Utilized for storing execution memories (short-term, long-term, entity memory). Defaults to `False`. |
|
||||
| **Cache** _(optional)_ | `cache` | Specifies whether to use a cache for storing the results of tools' execution. Defaults to `True`. |
|
||||
| **Embedder** _(optional)_ | `embedder` | Configuration for the embedder to be used by the crew. Mostly used by memory for now. Default is `{"provider": "openai"}`. |
|
||||
| **Full Output** _(optional)_ | `full_output` | Whether the crew should return the full output with all tasks outputs or just the final output. Defaults to `False`. |
|
||||
| **Step Callback** _(optional)_ | `step_callback` | A function that is called after each step of every agent. This can be used to log the agent's actions or to perform other operations; it won't override the agent-specific `step_callback`. |
|
||||
| **Task Callback** _(optional)_ | `task_callback` | A function that is called after the completion of each task. Useful for monitoring or additional operations post-task execution. |
|
||||
| **Share Crew** _(optional)_ | `share_crew` | Whether you want to share the complete crew information and execution with the crewAI team to make the library better, and allow us to train models. |
|
||||
| **Output Log File** _(optional)_ | `output_log_file` | Whether you want to have a file with the complete crew output and execution. You can set it using True and it will default to the folder you are currently in and it will be called logs.txt or passing a string with the full path and name of the file. |
|
||||
| **Manager Agent** _(optional)_ | `manager_agent` | `manager` sets a custom agent that will be used as a manager. |
|
||||
| **Manager Callbacks** _(optional)_ | `manager_callbacks` | `manager_callbacks` takes a list of callback handlers to be executed by the manager agent when a hierarchical process is used. |
|
||||
| **Prompt File** _(optional)_ | `prompt_file` | Path to the prompt JSON file to be used for the crew. |
|
||||
| **Planning** *(optional)* | `planning` | Adds planning ability to the Crew. When activated before each Crew iteration, all Crew data is sent to an AgentPlanner that will plan the tasks and this plan will be added to each task description. |
|
||||
| **Planning LLM** *(optional)* | `planning_llm` | The language model used by the AgentPlanner in a planning process. |
|
||||
|
||||
<Tip>
|
||||
**Crew Max RPM**: The `max_rpm` attribute sets the maximum number of requests per minute the crew can perform to avoid rate limits and will override individual agents' `max_rpm` settings if you set it.
|
||||
</Tip>
|
||||
|
||||
|
||||
## Crew Output
|
||||
|
||||
The output of a crew in the CrewAI framework is encapsulated within the `CrewOutput` class.
|
||||
This class provides a structured way to access results of the crew's execution, including various formats such as raw strings, JSON, and Pydantic models.
|
||||
The `CrewOutput` includes the results from the final task output, token usage, and individual task outputs.
|
||||
|
||||
### Crew Output Attributes
|
||||
|
||||
| Attribute | Parameters | Type | Description |
|
||||
| :--------------- | :------------- | :------------------------- | :--------------------------------------------------------------------------------------------------- |
|
||||
| **Raw** | `raw` | `str` | The raw output of the crew. This is the default format for the output. |
|
||||
| **Pydantic** | `pydantic` | `Optional[BaseModel]` | A Pydantic model object representing the structured output of the crew. |
|
||||
| **JSON Dict** | `json_dict` | `Optional[Dict[str, Any]]` | A dictionary representing the JSON output of the crew. |
|
||||
| **Tasks Output** | `tasks_output` | `List[TaskOutput]` | A list of `TaskOutput` objects, each representing the output of a task in the crew. |
|
||||
| **Token Usage** | `token_usage` | `Dict[str, Any]` | A summary of token usage, providing insights into the language model's performance during execution. |
|
||||
|
||||
### Crew Output Methods and Properties
|
||||
|
||||
| Method/Property | Description |
|
||||
| :-------------- | :------------------------------------------------------------------------------------------------ |
|
||||
| **json** | Returns the JSON string representation of the crew output if the output format is JSON. |
|
||||
| **to_dict** | Converts the JSON and Pydantic outputs to a dictionary. |
|
||||
| \***\*str\*\*** | Returns the string representation of the crew output, prioritizing Pydantic, then JSON, then raw. |
|
||||
|
||||
### Accessing Crew Outputs
|
||||
|
||||
Once a crew has been executed, its output can be accessed through the `output` attribute of the `Crew` object. The `CrewOutput` class provides various ways to interact with and present this output.
|
||||
|
||||
#### Example
|
||||
|
||||
```python Code
|
||||
# Example crew execution
|
||||
crew = Crew(
|
||||
agents=[research_agent, writer_agent],
|
||||
tasks=[research_task, write_article_task],
|
||||
verbose=True
|
||||
)
|
||||
|
||||
crew_output = crew.kickoff()
|
||||
|
||||
# Accessing the crew output
|
||||
print(f"Raw Output: {crew_output.raw}")
|
||||
if crew_output.json_dict:
|
||||
print(f"JSON Output: {json.dumps(crew_output.json_dict, indent=2)}")
|
||||
if crew_output.pydantic:
|
||||
print(f"Pydantic Output: {crew_output.pydantic}")
|
||||
print(f"Tasks Output: {crew_output.tasks_output}")
|
||||
print(f"Token Usage: {crew_output.token_usage}")
|
||||
```
|
||||
|
||||
## Memory Utilization
|
||||
|
||||
Crews can utilize memory (short-term, long-term, and entity memory) to enhance their execution and learning over time. This feature allows crews to store and recall execution memories, aiding in decision-making and task execution strategies.
|
||||
|
||||
## Cache Utilization
|
||||
|
||||
Caches can be employed to store the results of tools' execution, making the process more efficient by reducing the need to re-execute identical tasks.
|
||||
|
||||
## Crew Usage Metrics
|
||||
|
||||
After the crew execution, you can access the `usage_metrics` attribute to view the language model (LLM) usage metrics for all tasks executed by the crew. This provides insights into operational efficiency and areas for improvement.
|
||||
|
||||
```python Code
|
||||
# Access the crew's usage metrics
|
||||
crew = Crew(agents=[agent1, agent2], tasks=[task1, task2])
|
||||
crew.kickoff()
|
||||
print(crew.usage_metrics)
|
||||
```
|
||||
|
||||
## Crew Execution Process
|
||||
|
||||
- **Sequential Process**: Tasks are executed one after another, allowing for a linear flow of work.
|
||||
- **Hierarchical Process**: A manager agent coordinates the crew, delegating tasks and validating outcomes before proceeding. **Note**: A `manager_llm` or `manager_agent` is required for this process and it's essential for validating the process flow.
|
||||
|
||||
### Kicking Off a Crew
|
||||
|
||||
Once your crew is assembled, initiate the workflow with the `kickoff()` method. This starts the execution process according to the defined process flow.
|
||||
|
||||
```python Code
|
||||
# Start the crew's task execution
|
||||
result = my_crew.kickoff()
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Different Ways to Kick Off a Crew
|
||||
|
||||
Once your crew is assembled, initiate the workflow with the appropriate kickoff method. CrewAI provides several methods for better control over the kickoff process: `kickoff()`, `kickoff_for_each()`, `kickoff_async()`, and `kickoff_for_each_async()`.
|
||||
|
||||
- `kickoff()`: Starts the execution process according to the defined process flow.
|
||||
- `kickoff_for_each()`: Executes tasks for each agent individually.
|
||||
- `kickoff_async()`: Initiates the workflow asynchronously.
|
||||
- `kickoff_for_each_async()`: Executes tasks for each agent individually in an asynchronous manner.
|
||||
|
||||
```python Code
|
||||
# Start the crew's task execution
|
||||
result = my_crew.kickoff()
|
||||
print(result)
|
||||
|
||||
# Example of using kickoff_for_each
|
||||
inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}]
|
||||
results = my_crew.kickoff_for_each(inputs=inputs_array)
|
||||
for result in results:
|
||||
print(result)
|
||||
|
||||
# Example of using kickoff_async
|
||||
inputs = {'topic': 'AI in healthcare'}
|
||||
async_result = my_crew.kickoff_async(inputs=inputs)
|
||||
print(async_result)
|
||||
|
||||
# Example of using kickoff_for_each_async
|
||||
inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}]
|
||||
async_results = my_crew.kickoff_for_each_async(inputs=inputs_array)
|
||||
for async_result in async_results:
|
||||
print(async_result)
|
||||
```
|
||||
|
||||
These methods provide flexibility in how you manage and execute tasks within your crew, allowing for both synchronous and asynchronous workflows tailored to your needs.
|
||||
|
||||
### Replaying from a Specific Task
|
||||
|
||||
You can now replay from a specific task using our CLI command `replay`.
|
||||
|
||||
The replay feature in CrewAI allows you to replay from a specific task using the command-line interface (CLI). By running the command `crewai replay -t <task_id>`, you can specify the `task_id` for the replay process.
|
||||
|
||||
Kickoffs will now save the latest kickoffs returned task outputs locally for you to be able to replay from.
|
||||
|
||||
### Replaying from a Specific Task Using the CLI
|
||||
|
||||
To use the replay feature, follow these steps:
|
||||
|
||||
1. Open your terminal or command prompt.
|
||||
2. Navigate to the directory where your CrewAI project is located.
|
||||
3. Run the following command:
|
||||
|
||||
To view the latest kickoff task IDs, use:
|
||||
|
||||
```shell
|
||||
crewai log-tasks-outputs
|
||||
```
|
||||
|
||||
Then, to replay from a specific task, use:
|
||||
|
||||
```shell
|
||||
crewai replay -t <task_id>
|
||||
```
|
||||
|
||||
These commands let you replay from your latest kickoff tasks, still retaining context from previously executed tasks.
|
||||
768
docs/concepts/flows.mdx
Normal file
@@ -0,0 +1,768 @@
|
||||
---
|
||||
title: Flows
|
||||
description: Learn how to create and manage AI workflows using CrewAI Flows.
|
||||
icon: arrow-progress
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
CrewAI Flows is a powerful feature designed to streamline the creation and management of AI workflows. Flows allow developers to combine and coordinate coding tasks and Crews efficiently, providing a robust framework for building sophisticated AI automations.
|
||||
|
||||
Flows allow you to create structured, event-driven workflows. They provide a seamless way to connect multiple tasks, manage state, and control the flow of execution in your AI applications. With Flows, you can easily design and implement multi-step processes that leverage the full potential of CrewAI's capabilities.
|
||||
|
||||
1. **Simplified Workflow Creation**: Easily chain together multiple Crews and tasks to create complex AI workflows.
|
||||
|
||||
2. **State Management**: Flows make it super easy to manage and share state between different tasks in your workflow.
|
||||
|
||||
3. **Event-Driven Architecture**: Built on an event-driven model, allowing for dynamic and responsive workflows.
|
||||
|
||||
4. **Flexible Control Flow**: Implement conditional logic, loops, and branching within your workflows.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Let's create a simple Flow where you will use OpenAI to generate a random city in one task and then use that city to generate a fun fact in another task.
|
||||
|
||||
```python Code
|
||||
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
from dotenv import load_dotenv
|
||||
from litellm import completion
|
||||
|
||||
|
||||
class ExampleFlow(Flow):
|
||||
model = "gpt-4o-mini"
|
||||
|
||||
@start()
|
||||
def generate_city(self):
|
||||
print("Starting flow")
|
||||
|
||||
response = completion(
|
||||
model=self.model,
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Return the name of a random city in the world.",
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
random_city = response["choices"][0]["message"]["content"]
|
||||
print(f"Random City: {random_city}")
|
||||
|
||||
return random_city
|
||||
|
||||
@listen(generate_city)
|
||||
def generate_fun_fact(self, random_city):
|
||||
response = completion(
|
||||
model=self.model,
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": f"Tell me a fun fact about {random_city}",
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
fun_fact = response["choices"][0]["message"]["content"]
|
||||
return fun_fact
|
||||
|
||||
|
||||
|
||||
flow = ExampleFlow()
|
||||
result = flow.kickoff()
|
||||
|
||||
print(f"Generated fun fact: {result}")
|
||||
```
|
||||
|
||||
In the above example, we have created a simple Flow that generates a random city using OpenAI and then generates a fun fact about that city. The Flow consists of two tasks: `generate_city` and `generate_fun_fact`. The `generate_city` task is the starting point of the Flow, and the `generate_fun_fact` task listens for the output of the `generate_city` task.
|
||||
|
||||
When you run the Flow, it will generate a random city and then generate a fun fact about that city. The output will be printed to the console.
|
||||
|
||||
**Note:** Ensure you have set up your `.env` file to store your `OPENAI_API_KEY`. This key is necessary for authenticating requests to the OpenAI API.
|
||||
|
||||
### @start()
|
||||
|
||||
The `@start()` decorator is used to mark a method as the starting point of a Flow. When a Flow is started, all the methods decorated with `@start()` are executed in parallel. You can have multiple start methods in a Flow, and they will all be executed when the Flow is started.
|
||||
|
||||
### @listen()
|
||||
|
||||
The `@listen()` decorator is used to mark a method as a listener for the output of another task in the Flow. The method decorated with `@listen()` will be executed when the specified task emits an output. The method can access the output of the task it is listening to as an argument.
|
||||
|
||||
#### Usage
|
||||
|
||||
The `@listen()` decorator can be used in several ways:
|
||||
|
||||
1. **Listening to a Method by Name**: You can pass the name of the method you want to listen to as a string. When that method completes, the listener method will be triggered.
|
||||
|
||||
```python Code
|
||||
@listen("generate_city")
|
||||
def generate_fun_fact(self, random_city):
|
||||
# Implementation
|
||||
```
|
||||
|
||||
2. **Listening to a Method Directly**: You can pass the method itself. When that method completes, the listener method will be triggered.
|
||||
```python Code
|
||||
@listen(generate_city)
|
||||
def generate_fun_fact(self, random_city):
|
||||
# Implementation
|
||||
```
|
||||
|
||||
### Flow Output
|
||||
|
||||
Accessing and handling the output of a Flow is essential for integrating your AI workflows into larger applications or systems. CrewAI Flows provide straightforward mechanisms to retrieve the final output, access intermediate results, and manage the overall state of your Flow.
|
||||
|
||||
#### Retrieving the Final Output
|
||||
|
||||
When you run a Flow, the final output is determined by the last method that completes. The `kickoff()` method returns the output of this final method.
|
||||
|
||||
Here's how you can access the final output:
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
|
||||
class OutputExampleFlow(Flow):
|
||||
@start()
|
||||
def first_method(self):
|
||||
return "Output from first_method"
|
||||
|
||||
@listen(first_method)
|
||||
def second_method(self, first_output):
|
||||
return f"Second method received: {first_output}"
|
||||
|
||||
|
||||
flow = OutputExampleFlow()
|
||||
final_output = flow.kickoff()
|
||||
|
||||
print("---- Final Output ----")
|
||||
print(final_output)
|
||||
````
|
||||
|
||||
``` text Output
|
||||
---- Final Output ----
|
||||
Second method received: Output from first_method
|
||||
````
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
In this example, the `second_method` is the last method to complete, so its output will be the final output of the Flow.
|
||||
The `kickoff()` method will return the final output, which is then printed to the console.
|
||||
|
||||
#### Accessing and Updating State
|
||||
|
||||
In addition to retrieving the final output, you can also access and update the state within your Flow. The state can be used to store and share data between different methods in the Flow. After the Flow has run, you can access the state to retrieve any information that was added or updated during the execution.
|
||||
|
||||
Here's an example of how to update and access the state:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Code
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
from pydantic import BaseModel
|
||||
|
||||
class ExampleState(BaseModel):
|
||||
counter: int = 0
|
||||
message: str = ""
|
||||
|
||||
class StateExampleFlow(Flow[ExampleState]):
|
||||
|
||||
@start()
|
||||
def first_method(self):
|
||||
self.state.message = "Hello from first_method"
|
||||
self.state.counter += 1
|
||||
|
||||
@listen(first_method)
|
||||
def second_method(self):
|
||||
self.state.message += " - updated by second_method"
|
||||
self.state.counter += 1
|
||||
return self.state.message
|
||||
|
||||
flow = StateExampleFlow()
|
||||
final_output = flow.kickoff()
|
||||
print(f"Final Output: {final_output}")
|
||||
print("Final State:")
|
||||
print(flow.state)
|
||||
```
|
||||
|
||||
```text Output
|
||||
Final Output: Hello from first_method - updated by second_method
|
||||
Final State:
|
||||
counter=2 message='Hello from first_method - updated by second_method'
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
In this example, the state is updated by both `first_method` and `second_method`.
|
||||
After the Flow has run, you can access the final state to see the updates made by these methods.
|
||||
|
||||
By ensuring that the final method's output is returned and providing access to the state, CrewAI Flows make it easy to integrate the results of your AI workflows into larger applications or systems,
|
||||
while also maintaining and accessing the state throughout the Flow's execution.
|
||||
|
||||
## Flow State Management
|
||||
|
||||
Managing state effectively is crucial for building reliable and maintainable AI workflows. CrewAI Flows provides robust mechanisms for both unstructured and structured state management,
|
||||
allowing developers to choose the approach that best fits their application's needs.
|
||||
|
||||
### Unstructured State Management
|
||||
|
||||
In unstructured state management, all state is stored in the `state` attribute of the `Flow` class.
|
||||
This approach offers flexibility, enabling developers to add or modify state attributes on the fly without defining a strict schema.
|
||||
|
||||
```python Code
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
|
||||
class UntructuredExampleFlow(Flow):
|
||||
|
||||
@start()
|
||||
def first_method(self):
|
||||
self.state.message = "Hello from structured flow"
|
||||
self.state.counter = 0
|
||||
|
||||
@listen(first_method)
|
||||
def second_method(self):
|
||||
self.state.counter += 1
|
||||
self.state.message += " - updated"
|
||||
|
||||
@listen(second_method)
|
||||
def third_method(self):
|
||||
self.state.counter += 1
|
||||
self.state.message += " - updated again"
|
||||
|
||||
print(f"State after third_method: {self.state}")
|
||||
|
||||
|
||||
flow = UntructuredExampleFlow()
|
||||
flow.kickoff()
|
||||
```
|
||||
|
||||
**Key Points:**
|
||||
|
||||
- **Flexibility:** You can dynamically add attributes to `self.state` without predefined constraints.
|
||||
- **Simplicity:** Ideal for straightforward workflows where state structure is minimal or varies significantly.
|
||||
|
||||
### Structured State Management
|
||||
|
||||
Structured state management leverages predefined schemas to ensure consistency and type safety across the workflow.
|
||||
By using models like Pydantic's `BaseModel`, developers can define the exact shape of the state, enabling better validation and auto-completion in development environments.
|
||||
|
||||
```python Code
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class ExampleState(BaseModel):
|
||||
counter: int = 0
|
||||
message: str = ""
|
||||
|
||||
|
||||
class StructuredExampleFlow(Flow[ExampleState]):
|
||||
|
||||
@start()
|
||||
def first_method(self):
|
||||
self.state.message = "Hello from structured flow"
|
||||
|
||||
@listen(first_method)
|
||||
def second_method(self):
|
||||
self.state.counter += 1
|
||||
self.state.message += " - updated"
|
||||
|
||||
@listen(second_method)
|
||||
def third_method(self):
|
||||
self.state.counter += 1
|
||||
self.state.message += " - updated again"
|
||||
|
||||
print(f"State after third_method: {self.state}")
|
||||
|
||||
|
||||
flow = StructuredExampleFlow()
|
||||
flow.kickoff()
|
||||
```
|
||||
|
||||
**Key Points:**
|
||||
|
||||
- **Defined Schema:** `ExampleState` clearly outlines the state structure, enhancing code readability and maintainability.
|
||||
- **Type Safety:** Leveraging Pydantic ensures that state attributes adhere to the specified types, reducing runtime errors.
|
||||
- **Auto-Completion:** IDEs can provide better auto-completion and error checking based on the defined state model.
|
||||
|
||||
### Choosing Between Unstructured and Structured State Management
|
||||
|
||||
- **Use Unstructured State Management when:**
|
||||
|
||||
- The workflow's state is simple or highly dynamic.
|
||||
- Flexibility is prioritized over strict state definitions.
|
||||
- Rapid prototyping is required without the overhead of defining schemas.
|
||||
|
||||
- **Use Structured State Management when:**
|
||||
- The workflow requires a well-defined and consistent state structure.
|
||||
- Type safety and validation are important for your application's reliability.
|
||||
- You want to leverage IDE features like auto-completion and type checking for better developer experience.
|
||||
|
||||
By providing both unstructured and structured state management options, CrewAI Flows empowers developers to build AI workflows that are both flexible and robust, catering to a wide range of application requirements.
|
||||
|
||||
## Flow Control
|
||||
|
||||
### Conditional Logic: `or`
|
||||
|
||||
The `or_` function in Flows allows you to listen to multiple methods and trigger the listener method when any of the specified methods emit an output.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Code
|
||||
from crewai.flow.flow import Flow, listen, or_, start
|
||||
|
||||
class OrExampleFlow(Flow):
|
||||
|
||||
@start()
|
||||
def start_method(self):
|
||||
return "Hello from the start method"
|
||||
|
||||
@listen(start_method)
|
||||
def second_method(self):
|
||||
return "Hello from the second method"
|
||||
|
||||
@listen(or_(start_method, second_method))
|
||||
def logger(self, result):
|
||||
print(f"Logger: {result}")
|
||||
|
||||
|
||||
|
||||
flow = OrExampleFlow()
|
||||
flow.kickoff()
|
||||
```
|
||||
|
||||
```text Output
|
||||
Logger: Hello from the start method
|
||||
Logger: Hello from the second method
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
When you run this Flow, the `logger` method will be triggered by the output of either the `start_method` or the `second_method`.
|
||||
The `or_` function is used to listen to multiple methods and trigger the listener method when any of the specified methods emit an output.
|
||||
|
||||
### Conditional Logic: `and`
|
||||
|
||||
The `and_` function in Flows allows you to listen to multiple methods and trigger the listener method only when all the specified methods emit an output.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Code
|
||||
from crewai.flow.flow import Flow, and_, listen, start
|
||||
|
||||
class AndExampleFlow(Flow):
|
||||
|
||||
@start()
|
||||
def start_method(self):
|
||||
self.state["greeting"] = "Hello from the start method"
|
||||
|
||||
@listen(start_method)
|
||||
def second_method(self):
|
||||
self.state["joke"] = "What do computers eat? Microchips."
|
||||
|
||||
@listen(and_(start_method, second_method))
|
||||
def logger(self):
|
||||
print("---- Logger ----")
|
||||
print(self.state)
|
||||
|
||||
flow = AndExampleFlow()
|
||||
flow.kickoff()
|
||||
```
|
||||
|
||||
```text Output
|
||||
---- Logger ----
|
||||
{'greeting': 'Hello from the start method', 'joke': 'What do computers eat? Microchips.'}
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
When you run this Flow, the `logger` method will be triggered only when both the `start_method` and the `second_method` emit an output.
|
||||
The `and_` function is used to listen to multiple methods and trigger the listener method only when all the specified methods emit an output.
|
||||
|
||||
### Router
|
||||
|
||||
The `@router()` decorator in Flows allows you to define conditional routing logic based on the output of a method.
|
||||
You can specify different routes based on the output of the method, allowing you to control the flow of execution dynamically.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Code
|
||||
import random
|
||||
from crewai.flow.flow import Flow, listen, router, start
|
||||
from pydantic import BaseModel
|
||||
|
||||
class ExampleState(BaseModel):
|
||||
success_flag: bool = False
|
||||
|
||||
class RouterFlow(Flow[ExampleState]):
|
||||
|
||||
@start()
|
||||
def start_method(self):
|
||||
print("Starting the structured flow")
|
||||
random_boolean = random.choice([True, False])
|
||||
self.state.success_flag = random_boolean
|
||||
|
||||
@router(start_method)
|
||||
def second_method(self):
|
||||
if self.state.success_flag:
|
||||
return "success"
|
||||
else:
|
||||
return "failed"
|
||||
|
||||
@listen("success")
|
||||
def third_method(self):
|
||||
print("Third method running")
|
||||
|
||||
@listen("failed")
|
||||
def fourth_method(self):
|
||||
print("Fourth method running")
|
||||
|
||||
|
||||
flow = RouterFlow()
|
||||
flow.kickoff()
|
||||
```
|
||||
|
||||
```text Output
|
||||
Starting the structured flow
|
||||
Third method running
|
||||
Fourth method running
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
In the above example, the `start_method` generates a random boolean value and sets it in the state.
|
||||
The `second_method` uses the `@router()` decorator to define conditional routing logic based on the value of the boolean.
|
||||
If the boolean is `True`, the method returns `"success"`, and if it is `False`, the method returns `"failed"`.
|
||||
The `third_method` and `fourth_method` listen to the output of the `second_method` and execute based on the returned value.
|
||||
|
||||
When you run this Flow, the output will change based on the random boolean value generated by the `start_method`.
|
||||
|
||||
## Adding Crews to Flows
|
||||
|
||||
Creating a flow with multiple crews in CrewAI is straightforward.
|
||||
|
||||
You can generate a new CrewAI project that includes all the scaffolding needed to create a flow with multiple crews by running the following command:
|
||||
|
||||
```bash
|
||||
crewai create flow name_of_flow
|
||||
```
|
||||
|
||||
This command will generate a new CrewAI project with the necessary folder structure. The generated project includes a prebuilt crew called `poem_crew` that is already working. You can use this crew as a template by copying, pasting, and editing it to create other crews.
|
||||
|
||||
### Folder Structure
|
||||
|
||||
After running the `crewai create flow name_of_flow` command, you will see a folder structure similar to the following:
|
||||
|
||||
| Directory/File | Description |
|
||||
| :--------------------- | :----------------------------------------------------------------- |
|
||||
| `name_of_flow/` | Root directory for the flow. |
|
||||
| ├── `crews/` | Contains directories for specific crews. |
|
||||
| │ └── `poem_crew/` | Directory for the "poem_crew" with its configurations and scripts. |
|
||||
| │ ├── `config/` | Configuration files directory for the "poem_crew". |
|
||||
| │ │ ├── `agents.yaml` | YAML file defining the agents for "poem_crew". |
|
||||
| │ │ └── `tasks.yaml` | YAML file defining the tasks for "poem_crew". |
|
||||
| │ ├── `poem_crew.py` | Script for "poem_crew" functionality. |
|
||||
| ├── `tools/` | Directory for additional tools used in the flow. |
|
||||
| │ └── `custom_tool.py` | Custom tool implementation. |
|
||||
| ├── `main.py` | Main script for running the flow. |
|
||||
| ├── `README.md` | Project description and instructions. |
|
||||
| ├── `pyproject.toml` | Configuration file for project dependencies and settings. |
|
||||
| └── `.gitignore` | Specifies files and directories to ignore in version control. |
|
||||
|
||||
### Building Your Crews
|
||||
|
||||
In the `crews` folder, you can define multiple crews. Each crew will have its own folder containing configuration files and the crew definition file. For example, the `poem_crew` folder contains:
|
||||
|
||||
- `config/agents.yaml`: Defines the agents for the crew.
|
||||
- `config/tasks.yaml`: Defines the tasks for the crew.
|
||||
- `poem_crew.py`: Contains the crew definition, including agents, tasks, and the crew itself.
|
||||
|
||||
You can copy, paste, and edit the `poem_crew` to create other crews.
|
||||
|
||||
### Connecting Crews in `main.py`
|
||||
|
||||
The `main.py` file is where you create your flow and connect the crews together. You can define your flow by using the `Flow` class and the decorators `@start` and `@listen` to specify the flow of execution.
|
||||
|
||||
Here's an example of how you can connect the `poem_crew` in the `main.py` file:
|
||||
|
||||
```python Code
|
||||
#!/usr/bin/env python
|
||||
from random import randint
|
||||
|
||||
from pydantic import BaseModel
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
from .crews.poem_crew.poem_crew import PoemCrew
|
||||
|
||||
class PoemState(BaseModel):
|
||||
sentence_count: int = 1
|
||||
poem: str = ""
|
||||
|
||||
class PoemFlow(Flow[PoemState]):
|
||||
|
||||
@start()
|
||||
def generate_sentence_count(self):
|
||||
print("Generating sentence count")
|
||||
self.state.sentence_count = randint(1, 5)
|
||||
|
||||
@listen(generate_sentence_count)
|
||||
def generate_poem(self):
|
||||
print("Generating poem")
|
||||
result = PoemCrew().crew().kickoff(inputs={"sentence_count": self.state.sentence_count})
|
||||
|
||||
print("Poem generated", result.raw)
|
||||
self.state.poem = result.raw
|
||||
|
||||
@listen(generate_poem)
|
||||
def save_poem(self):
|
||||
print("Saving poem")
|
||||
with open("poem.txt", "w") as f:
|
||||
f.write(self.state.poem)
|
||||
|
||||
def kickoff():
|
||||
poem_flow = PoemFlow()
|
||||
poem_flow.kickoff()
|
||||
|
||||
|
||||
def plot():
|
||||
poem_flow = PoemFlow()
|
||||
poem_flow.plot()
|
||||
|
||||
if __name__ == "__main__":
|
||||
kickoff()
|
||||
```
|
||||
|
||||
In this example, the `PoemFlow` class defines a flow that generates a sentence count, uses the `PoemCrew` to generate a poem, and then saves the poem to a file. The flow is kicked off by calling the `kickoff()` method.
|
||||
|
||||
### Running the Flow
|
||||
|
||||
(Optional) Before running the flow, you can install the dependencies by running:
|
||||
|
||||
```bash
|
||||
crewai install
|
||||
```
|
||||
|
||||
Once all of the dependencies are installed, you need to activate the virtual environment by running:
|
||||
|
||||
```bash
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
After activating the virtual environment, you can run the flow by executing one of the following commands:
|
||||
|
||||
```bash
|
||||
crewai flow kickoff
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
uv run kickoff
|
||||
```
|
||||
|
||||
The flow will execute, and you should see the output in the console.
|
||||
|
||||
|
||||
### Adding Additional Crews Using the CLI
|
||||
|
||||
Once you have created your initial flow, you can easily add additional crews to your project using the CLI. This allows you to expand your flow's capabilities by integrating new crews without starting from scratch.
|
||||
|
||||
To add a new crew to your existing flow, use the following command:
|
||||
|
||||
```bash
|
||||
crewai flow add-crew <crew_name>
|
||||
```
|
||||
|
||||
This command will create a new directory for your crew within the `crews` folder of your flow project. It will include the necessary configuration files and a crew definition file, similar to the initial setup.
|
||||
|
||||
#### Folder Structure
|
||||
|
||||
After adding a new crew, your folder structure will look like this:
|
||||
|
||||
name_of_flow/
|
||||
├── crews/
|
||||
│ ├── poem_crew/
|
||||
│ │ ├── config/
|
||||
│ │ │ ├── agents.yaml
|
||||
│ │ │ └── tasks.yaml
|
||||
│ │ └── poem_crew.py
|
||||
│ └── name_of_crew/
|
||||
│ ├── config/
|
||||
│ │ ├── agents.yaml
|
||||
│ │ └── tasks.yaml
|
||||
│ └── name_of_crew.py
|
||||
|
||||
You can then customize the `agents.yaml` and `tasks.yaml` files to define the agents and tasks for your new crew. The `name_of_crew.py` file will contain the crew's logic, which you can modify to suit your needs.
|
||||
|
||||
By using the CLI to add additional crews, you can efficiently build complex AI workflows that leverage multiple crews working together.
|
||||
|
||||
## Plot Flows
|
||||
|
||||
Visualizing your AI workflows can provide valuable insights into the structure and execution paths of your flows. CrewAI offers a powerful visualization tool that allows you to generate interactive plots of your flows, making it easier to understand and optimize your AI workflows.
|
||||
|
||||
### What are Plots?
|
||||
|
||||
Plots in CrewAI are graphical representations of your AI workflows. They display the various tasks, their connections, and the flow of data between them. This visualization helps in understanding the sequence of operations, identifying bottlenecks, and ensuring that the workflow logic aligns with your expectations.
|
||||
|
||||
### How to Generate a Plot
|
||||
|
||||
CrewAI provides two convenient methods to generate plots of your flows:
|
||||
|
||||
#### Option 1: Using the `plot()` Method
|
||||
|
||||
If you are working directly with a flow instance, you can generate a plot by calling the `plot()` method on your flow object. This method will create an HTML file containing the interactive plot of your flow.
|
||||
|
||||
```python Code
|
||||
# Assuming you have a flow instance
|
||||
flow.plot("my_flow_plot")
|
||||
```
|
||||
|
||||
This will generate a file named `my_flow_plot.html` in your current directory. You can open this file in a web browser to view the interactive plot.
|
||||
|
||||
#### Option 2: Using the Command Line
|
||||
|
||||
If you are working within a structured CrewAI project, you can generate a plot using the command line. This is particularly useful for larger projects where you want to visualize the entire flow setup.
|
||||
|
||||
```bash
|
||||
crewai flow plot
|
||||
```
|
||||
|
||||
This command will generate an HTML file with the plot of your flow, similar to the `plot()` method. The file will be saved in your project directory, and you can open it in a web browser to explore the flow.
|
||||
|
||||
### Understanding the Plot
|
||||
|
||||
The generated plot will display nodes representing the tasks in your flow, with directed edges indicating the flow of execution. The plot is interactive, allowing you to zoom in and out, and hover over nodes to see additional details.
|
||||
|
||||
By visualizing your flows, you can gain a clearer understanding of the workflow's structure, making it easier to debug, optimize, and communicate your AI processes to others.
|
||||
|
||||
|
||||
## Advanced
|
||||
|
||||
In this section, we explore more complex use cases of CrewAI Flows, starting with a self-evaluation loop. This pattern is crucial for developing AI systems that can iteratively improve their outputs through feedback.
|
||||
|
||||
### 1) Self-Evaluation Loop
|
||||
|
||||
The self-evaluation loop is a powerful pattern that allows AI workflows to automatically assess and refine their outputs. This example demonstrates how to set up a flow that generates content, evaluates it, and iterates based on feedback until the desired quality is achieved.
|
||||
|
||||
#### Overview
|
||||
|
||||
The self-evaluation loop involves two main Crews:
|
||||
|
||||
1. **ShakespeareanXPostCrew**: Generates a Shakespearean-style post on a given topic.
|
||||
2. **XPostReviewCrew**: Evaluates the generated post, providing feedback on its validity and quality.
|
||||
|
||||
The process iterates until the post meets the criteria or a maximum retry limit is reached. This approach ensures high-quality outputs through iterative refinement.
|
||||
|
||||
#### Importance
|
||||
|
||||
This pattern is essential for building robust AI systems that can adapt and improve over time. By automating the evaluation and feedback loop, developers can ensure that their AI workflows produce reliable and high-quality results.
|
||||
|
||||
#### Main Code Highlights
|
||||
|
||||
Below is the `main.py` file for the self-evaluation loop flow:
|
||||
|
||||
```python
|
||||
from typing import Optional
|
||||
from crewai.flow.flow import Flow, listen, router, start
|
||||
from pydantic import BaseModel
|
||||
from self_evaluation_loop_flow.crews.shakespeare_crew.shakespeare_crew import (
|
||||
ShakespeareanXPostCrew,
|
||||
)
|
||||
from self_evaluation_loop_flow.crews.x_post_review_crew.x_post_review_crew import (
|
||||
XPostReviewCrew,
|
||||
)
|
||||
|
||||
class ShakespeareXPostFlowState(BaseModel):
|
||||
x_post: str = ""
|
||||
feedback: Optional[str] = None
|
||||
valid: bool = False
|
||||
retry_count: int = 0
|
||||
|
||||
class ShakespeareXPostFlow(Flow[ShakespeareXPostFlowState]):
|
||||
|
||||
@start("retry")
|
||||
def generate_shakespeare_x_post(self):
|
||||
print("Generating Shakespearean X post")
|
||||
topic = "Flying cars"
|
||||
result = (
|
||||
ShakespeareanXPostCrew()
|
||||
.crew()
|
||||
.kickoff(inputs={"topic": topic, "feedback": self.state.feedback})
|
||||
)
|
||||
print("X post generated", result.raw)
|
||||
self.state.x_post = result.raw
|
||||
|
||||
@router(generate_shakespeare_x_post)
|
||||
def evaluate_x_post(self):
|
||||
if self.state.retry_count > 3:
|
||||
return "max_retry_exceeded"
|
||||
result = XPostReviewCrew().crew().kickoff(inputs={"x_post": self.state.x_post})
|
||||
self.state.valid = result["valid"]
|
||||
self.state.feedback = result["feedback"]
|
||||
print("valid", self.state.valid)
|
||||
print("feedback", self.state.feedback)
|
||||
self.state.retry_count += 1
|
||||
if self.state.valid:
|
||||
return "complete"
|
||||
return "retry"
|
||||
|
||||
@listen("complete")
|
||||
def save_result(self):
|
||||
print("X post is valid")
|
||||
print("X post:", self.state.x_post)
|
||||
with open("x_post.txt", "w") as file:
|
||||
file.write(self.state.x_post)
|
||||
|
||||
@listen("max_retry_exceeded")
|
||||
def max_retry_exceeded_exit(self):
|
||||
print("Max retry count exceeded")
|
||||
print("X post:", self.state.x_post)
|
||||
print("Feedback:", self.state.feedback)
|
||||
|
||||
def kickoff():
|
||||
shakespeare_flow = ShakespeareXPostFlow()
|
||||
shakespeare_flow.kickoff()
|
||||
|
||||
def plot():
|
||||
shakespeare_flow = ShakespeareXPostFlow()
|
||||
shakespeare_flow.plot()
|
||||
|
||||
if __name__ == "__main__":
|
||||
kickoff()
|
||||
```
|
||||
|
||||
#### Code Highlights
|
||||
|
||||
- **Retry Mechanism**: The flow uses a retry mechanism to regenerate the post if it doesn't meet the criteria, up to a maximum of three retries.
|
||||
- **Feedback Loop**: Feedback from the `XPostReviewCrew` is used to refine the post iteratively.
|
||||
- **State Management**: The flow maintains state using a Pydantic model, ensuring type safety and clarity.
|
||||
|
||||
For a complete example and further details, please refer to the [Self Evaluation Loop Flow repository](https://github.com/crewAIInc/crewAI-examples/tree/main/self_evaluation_loop_flow).
|
||||
|
||||
|
||||
## Next Steps
|
||||
|
||||
If you're interested in exploring additional examples of flows, we have a variety of recommendations in our examples repository. Here are five specific flow examples, each showcasing unique use cases to help you match your current problem type to a specific example:
|
||||
|
||||
1. **Email Auto Responder Flow**: This example demonstrates an infinite loop where a background job continually runs to automate email responses. It's a great use case for tasks that need to be performed repeatedly without manual intervention. [View Example](https://github.com/crewAIInc/crewAI-examples/tree/main/email_auto_responder_flow)
|
||||
|
||||
2. **Lead Score Flow**: This flow showcases adding human-in-the-loop feedback and handling different conditional branches using the router. It's an excellent example of how to incorporate dynamic decision-making and human oversight into your workflows. [View Example](https://github.com/crewAIInc/crewAI-examples/tree/main/lead-score-flow)
|
||||
|
||||
3. **Write a Book Flow**: This example excels at chaining multiple crews together, where the output of one crew is used by another. Specifically, one crew outlines an entire book, and another crew generates chapters based on the outline. Eventually, everything is connected to produce a complete book. This flow is perfect for complex, multi-step processes that require coordination between different tasks. [View Example](https://github.com/crewAIInc/crewAI-examples/tree/main/write_a_book_with_flows)
|
||||
|
||||
4. **Meeting Assistant Flow**: This flow demonstrates how to broadcast one event to trigger multiple follow-up actions. For instance, after a meeting is completed, the flow can update a Trello board, send a Slack message, and save the results. It's a great example of handling multiple outcomes from a single event, making it ideal for comprehensive task management and notification systems. [View Example](https://github.com/crewAIInc/crewAI-examples/tree/main/meeting_assistant_flow)
|
||||
|
||||
5. **Self Evaluation Loop Flow**: This flow demonstrates a self-evaluation loop where AI workflows automatically assess and refine their outputs through feedback. It involves generating content, evaluating it, and iterating until the desired quality is achieved. This pattern is crucial for developing robust AI systems that can adapt and improve over time. [View Example](https://github.com/crewAIInc/crewAI-examples/tree/main/self_evaluation_loop_flow)
|
||||
|
||||
By exploring these examples, you can gain insights into how to leverage CrewAI Flows for various use cases, from automating repetitive tasks to managing complex, multi-step processes with dynamic decision-making and human feedback.
|
||||
|
||||
Also, check out our YouTube video on how to use flows in CrewAI below!
|
||||
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
src="https://www.youtube.com/embed/MTb5my6VOT8"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen
|
||||
></iframe>
|
||||
45
docs/concepts/langchain-tools.mdx
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: Using LangChain Tools
|
||||
description: Learn how to integrate LangChain tools with CrewAI agents to enhance search-based queries and more.
|
||||
icon: link
|
||||
---
|
||||
|
||||
## Using LangChain Tools
|
||||
|
||||
<Info>
|
||||
CrewAI seamlessly integrates with LangChain’s comprehensive [list of tools](https://python.langchain.com/docs/integrations/tools/), all of which can be used with CrewAI.
|
||||
</Info>
|
||||
|
||||
```python Code
|
||||
import os
|
||||
from crewai import Agent
|
||||
from langchain.agents import Tool
|
||||
from langchain.utilities import GoogleSerperAPIWrapper
|
||||
|
||||
# Setup API keys
|
||||
os.environ["SERPER_API_KEY"] = "Your Key"
|
||||
|
||||
search = GoogleSerperAPIWrapper()
|
||||
|
||||
# Create and assign the search tool to an agent
|
||||
serper_tool = Tool(
|
||||
name="Intermediate Answer",
|
||||
func=search.run,
|
||||
description="Useful for search-based queries",
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
role='Research Analyst',
|
||||
goal='Provide up-to-date market analysis',
|
||||
backstory='An expert analyst with a keen eye for market trends.',
|
||||
tools=[serper_tool]
|
||||
)
|
||||
|
||||
# rest of the code ...
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Tools are pivotal in extending the capabilities of CrewAI agents, enabling them to undertake a broad spectrum of tasks and collaborate effectively.
|
||||
When building solutions with CrewAI, leverage both custom and existing tools to empower your agents and enhance the AI ecosystem. Consider utilizing error handling, caching mechanisms,
|
||||
and the flexibility of tool arguments to optimize your agents' performance and capabilities.
|
||||
71
docs/concepts/llamaindex-tools.mdx
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: Using LlamaIndex Tools
|
||||
description: Learn how to integrate LlamaIndex tools with CrewAI agents to enhance search-based queries and more.
|
||||
icon: toolbox
|
||||
---
|
||||
|
||||
## Using LlamaIndex Tools
|
||||
|
||||
<Info>
|
||||
CrewAI seamlessly integrates with LlamaIndex’s comprehensive toolkit for RAG (Retrieval-Augmented Generation) and agentic pipelines, enabling advanced search-based queries and more.
|
||||
</Info>
|
||||
|
||||
Here are the available built-in tools offered by LlamaIndex.
|
||||
|
||||
```python Code
|
||||
from crewai import Agent
|
||||
from crewai_tools import LlamaIndexTool
|
||||
|
||||
# Example 1: Initialize from FunctionTool
|
||||
from llama_index.core.tools import FunctionTool
|
||||
|
||||
your_python_function = lambda ...: ...
|
||||
og_tool = FunctionTool.from_defaults(
|
||||
your_python_function,
|
||||
name="<name>",
|
||||
description='<description>'
|
||||
)
|
||||
tool = LlamaIndexTool.from_tool(og_tool)
|
||||
|
||||
# Example 2: Initialize from LlamaHub Tools
|
||||
from llama_index.tools.wolfram_alpha import WolframAlphaToolSpec
|
||||
wolfram_spec = WolframAlphaToolSpec(app_id="<app_id>")
|
||||
wolfram_tools = wolfram_spec.to_tool_list()
|
||||
tools = [LlamaIndexTool.from_tool(t) for t in wolfram_tools]
|
||||
|
||||
# Example 3: Initialize Tool from a LlamaIndex Query Engine
|
||||
query_engine = index.as_query_engine()
|
||||
query_tool = LlamaIndexTool.from_query_engine(
|
||||
query_engine,
|
||||
name="Uber 2019 10K Query Tool",
|
||||
description="Use this tool to lookup the 2019 Uber 10K Annual Report"
|
||||
)
|
||||
|
||||
# Create and assign the tools to an agent
|
||||
agent = Agent(
|
||||
role='Research Analyst',
|
||||
goal='Provide up-to-date market analysis',
|
||||
backstory='An expert analyst with a keen eye for market trends.',
|
||||
tools=[tool, *tools, query_tool]
|
||||
)
|
||||
|
||||
# rest of the code ...
|
||||
```
|
||||
|
||||
## Steps to Get Started
|
||||
|
||||
To effectively use the LlamaIndexTool, follow these steps:
|
||||
|
||||
<Steps>
|
||||
<Step title="Package Installation">
|
||||
Make sure that `crewai[tools]` package is installed in your Python environment:
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
pip install 'crewai[tools]'
|
||||
```
|
||||
</CodeGroup>
|
||||
</Step>
|
||||
<Step title="Install and Use LlamaIndex">
|
||||
Follow the LlamaIndex documentation [LlamaIndex Documentation](https://docs.llamaindex.ai/) to set up a RAG/agent pipeline.
|
||||
</Step>
|
||||
</Steps>
|
||||
277
docs/concepts/llms.mdx
Normal file
@@ -0,0 +1,277 @@
|
||||
---
|
||||
title: LLMs
|
||||
description: Learn how to configure and optimize LLMs for your CrewAI projects.
|
||||
icon: microchip-ai
|
||||
---
|
||||
|
||||
# Large Language Models (LLMs) in CrewAI
|
||||
|
||||
Large Language Models (LLMs) are the backbone of intelligent agents in the CrewAI framework. This guide will help you understand, configure, and optimize LLM usage for your CrewAI projects.
|
||||
|
||||
## Key Concepts
|
||||
|
||||
- **LLM**: Large Language Model, the AI powering agent intelligence
|
||||
- **Agent**: A CrewAI entity that uses an LLM to perform tasks
|
||||
- **Provider**: A service that offers LLM capabilities (e.g., OpenAI, Anthropic, Ollama, [more providers](https://docs.litellm.ai/docs/providers))
|
||||
|
||||
## Configuring LLMs for Agents
|
||||
|
||||
CrewAI offers flexible options for setting up LLMs:
|
||||
|
||||
### 1. Default Configuration
|
||||
|
||||
By default, CrewAI uses the `gpt-4o-mini` model. It uses environment variables if no LLM is specified:
|
||||
- `OPENAI_MODEL_NAME` (defaults to "gpt-4o-mini" if not set)
|
||||
- `OPENAI_API_BASE`
|
||||
- `OPENAI_API_KEY`
|
||||
|
||||
### 2. Custom LLM Objects
|
||||
|
||||
Pass a custom LLM implementation or object from another library.
|
||||
|
||||
See below for examples.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="String Identifier">
|
||||
```python Code
|
||||
agent = Agent(llm="gpt-4o", ...)
|
||||
```
|
||||
</Tab>
|
||||
|
||||
<Tab title="LLM Instance">
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(model="gpt-4", temperature=0.7)
|
||||
agent = Agent(llm=llm, ...)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Connecting to OpenAI-Compatible LLMs
|
||||
|
||||
You can connect to OpenAI-compatible LLMs using either environment variables or by setting specific attributes on the LLM class:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Using Environment Variables">
|
||||
```python Code
|
||||
import os
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
os.environ["OPENAI_API_BASE"] = "https://api.your-provider.com/v1"
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Using LLM Class Attributes">
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="custom-model-name",
|
||||
api_key="your-api-key",
|
||||
base_url="https://api.your-provider.com/v1"
|
||||
)
|
||||
agent = Agent(llm=llm, ...)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## LLM Configuration Options
|
||||
|
||||
When configuring an LLM for your agent, you have access to a wide range of parameters:
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|:------------------|:---------------:|:-------------------------------------------------------------------------------------------------|
|
||||
| **model** | `str` | Name of the model to use (e.g., "gpt-4", "gpt-3.5-turbo", "ollama/llama3.1"). For more options, visit the providers documentation. |
|
||||
| **timeout** | `float, int` | Maximum time (in seconds) to wait for a response. |
|
||||
| **temperature** | `float` | Controls randomness in output (0.0 to 1.0). |
|
||||
| **top_p** | `float` | Controls diversity of output (0.0 to 1.0). |
|
||||
| **n** | `int` | Number of completions to generate. |
|
||||
| **stop** | `str, List[str]` | Sequence(s) where generation should stop. |
|
||||
| **max_tokens** | `int` | Maximum number of tokens to generate. |
|
||||
| **presence_penalty** | `float` | Penalizes new tokens based on their presence in prior text. |
|
||||
| **frequency_penalty**| `float` | Penalizes new tokens based on their frequency in prior text. |
|
||||
| **logit_bias** | `Dict[int, float]`| Modifies likelihood of specified tokens appearing. |
|
||||
| **response_format** | `Dict[str, Any]` | Specifies the format of the response (e.g., JSON object). |
|
||||
| **seed** | `int` | Sets a random seed for deterministic results. |
|
||||
| **logprobs** | `bool` | Returns log probabilities of output tokens if enabled. |
|
||||
| **top_logprobs** | `int` | Number of most likely tokens for which to return log probabilities. |
|
||||
| **base_url** | `str` | The base URL for the API endpoint. |
|
||||
| **api_version** | `str` | Version of the API to use. |
|
||||
| **api_key** | `str` | Your API key for authentication. |
|
||||
|
||||
|
||||
These are examples of how to configure LLMs for your agent.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="OpenAI">
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="gpt-4",
|
||||
temperature=0.8,
|
||||
max_tokens=150,
|
||||
top_p=0.9,
|
||||
frequency_penalty=0.1,
|
||||
presence_penalty=0.1,
|
||||
stop=["END"],
|
||||
seed=42,
|
||||
base_url="https://api.openai.com/v1",
|
||||
api_key="your-api-key-here"
|
||||
)
|
||||
agent = Agent(llm=llm, ...)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Cerebras">
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="cerebras/llama-3.1-70b",
|
||||
base_url="https://api.cerebras.ai/v1",
|
||||
api_key="your-api-key-here"
|
||||
)
|
||||
agent = Agent(llm=llm, ...)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Ollama (Local LLMs)">
|
||||
|
||||
CrewAI supports using Ollama for running open-source models locally:
|
||||
|
||||
1. Install Ollama: [ollama.ai](https://ollama.ai/)
|
||||
2. Run a model: `ollama run llama2`
|
||||
3. Configure agent:
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
agent = Agent(
|
||||
llm=LLM(
|
||||
model="ollama/llama3.1",
|
||||
base_url="http://localhost:11434"
|
||||
),
|
||||
...
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Groq">
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="groq/llama3-8b-8192",
|
||||
base_url="https://api.groq.com/openai/v1",
|
||||
api_key="your-api-key-here"
|
||||
)
|
||||
agent = Agent(llm=llm, ...)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Anthropic">
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="anthropic/claude-3-5-sonnet-20241022",
|
||||
base_url="https://api.anthropic.com/v1",
|
||||
api_key="your-api-key-here"
|
||||
)
|
||||
agent = Agent(llm=llm, ...)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Fireworks">
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="fireworks/meta-llama-3.1-8b-instruct",
|
||||
base_url="https://api.fireworks.ai/inference/v1",
|
||||
api_key="your-api-key-here"
|
||||
)
|
||||
agent = Agent(llm=llm, ...)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Gemini">
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="gemini/gemini-1.5-flash",
|
||||
base_url="https://api.gemini.google.com/v1",
|
||||
api_key="your-api-key-here"
|
||||
)
|
||||
agent = Agent(llm=llm, ...)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Perplexity AI (pplx-api)">
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="perplexity/mistral-7b-instruct",
|
||||
base_url="https://api.perplexity.ai/v1",
|
||||
api_key="your-api-key-here"
|
||||
)
|
||||
agent = Agent(llm=llm, ...)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="IBM watsonx.ai">
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="watsonx/ibm/granite-13b-chat-v2",
|
||||
base_url="https://api.watsonx.ai/v1",
|
||||
api_key="your-api-key-here"
|
||||
)
|
||||
agent = Agent(llm=llm, ...)
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Changing the Base API URL
|
||||
|
||||
You can change the base API URL for any LLM provider by setting the `base_url` parameter:
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="custom-model-name",
|
||||
base_url="https://api.your-provider.com/v1",
|
||||
api_key="your-api-key"
|
||||
)
|
||||
agent = Agent(llm=llm, ...)
|
||||
```
|
||||
|
||||
This is particularly useful when working with OpenAI-compatible APIs or when you need to specify a different endpoint for your chosen provider.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Choose the right model**: Balance capability and cost.
|
||||
2. **Optimize prompts**: Clear, concise instructions improve output.
|
||||
3. **Manage tokens**: Monitor and limit token usage for efficiency.
|
||||
4. **Use appropriate temperature**: Lower for factual tasks, higher for creative ones.
|
||||
5. **Implement error handling**: Gracefully manage API errors and rate limits.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **API Errors**: Check your API key, network connection, and rate limits.
|
||||
- **Unexpected Outputs**: Refine your prompts and adjust temperature or top_p.
|
||||
- **Performance Issues**: Consider using a more powerful model or optimizing your queries.
|
||||
- **Timeout Errors**: Increase the `timeout` parameter or optimize your input.
|
||||
308
docs/concepts/memory.mdx
Normal file
@@ -0,0 +1,308 @@
|
||||
---
|
||||
title: Memory
|
||||
description: Leveraging memory systems in the CrewAI framework to enhance agent capabilities.
|
||||
icon: database
|
||||
---
|
||||
|
||||
## Introduction to Memory Systems in CrewAI
|
||||
|
||||
The crewAI framework introduces a sophisticated memory system designed to significantly enhance the capabilities of AI agents.
|
||||
This system comprises `short-term memory`, `long-term memory`, `entity memory`, and `contextual memory`, each serving a unique purpose in aiding agents to remember,
|
||||
reason, and learn from past interactions.
|
||||
|
||||
## Memory System Components
|
||||
|
||||
| Component | Description |
|
||||
| :------------------- | :---------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Short-Term Memory**| Temporarily stores recent interactions and outcomes using `RAG`, enabling agents to recall and utilize information relevant to their current context during the current executions.|
|
||||
| **Long-Term Memory** | Preserves valuable insights and learnings from past executions, allowing agents to build and refine their knowledge over time. |
|
||||
| **Entity Memory** | Captures and organizes information about entities (people, places, concepts) encountered during tasks, facilitating deeper understanding and relationship mapping. Uses `RAG` for storing entity information. |
|
||||
| **Contextual Memory**| Maintains the context of interactions by combining `ShortTermMemory`, `LongTermMemory`, and `EntityMemory`, aiding in the coherence and relevance of agent responses over a sequence of tasks or a conversation. |
|
||||
|
||||
## How Memory Systems Empower Agents
|
||||
|
||||
1. **Contextual Awareness**: With short-term and contextual memory, agents gain the ability to maintain context over a conversation or task sequence, leading to more coherent and relevant responses.
|
||||
|
||||
2. **Experience Accumulation**: Long-term memory allows agents to accumulate experiences, learning from past actions to improve future decision-making and problem-solving.
|
||||
|
||||
3. **Entity Understanding**: By maintaining entity memory, agents can recognize and remember key entities, enhancing their ability to process and interact with complex information.
|
||||
|
||||
## Implementing Memory in Your Crew
|
||||
|
||||
When configuring a crew, you can enable and customize each memory component to suit the crew's objectives and the nature of tasks it will perform.
|
||||
By default, the memory system is disabled, and you can ensure it is active by setting `memory=True` in the crew configuration.
|
||||
The memory will use OpenAI embeddings by default, but you can change it by setting `embedder` to a different model.
|
||||
It's also possible to initialize the memory instance with your own instance.
|
||||
|
||||
The 'embedder' only applies to **Short-Term Memory** which uses Chroma for RAG.
|
||||
The **Long-Term Memory** uses SQLite3 to store task results. Currently, there is no way to override these storage implementations.
|
||||
The data storage files are saved into a platform-specific location found using the appdirs package,
|
||||
and the name of the project can be overridden using the **CREWAI_STORAGE_DIR** environment variable.
|
||||
|
||||
### Example: Configuring Memory for a Crew
|
||||
|
||||
```python Code
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
|
||||
# Assemble your crew with memory capabilities
|
||||
my_crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
process=Process.sequential,
|
||||
memory=True,
|
||||
verbose=True
|
||||
)
|
||||
```
|
||||
|
||||
### Example: Use Custom Memory Instances e.g FAISS as the VectorDB
|
||||
|
||||
```python Code
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
|
||||
# Assemble your crew with memory capabilities
|
||||
my_crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
process="Process.sequential",
|
||||
memory=True,
|
||||
long_term_memory=EnhanceLongTermMemory(
|
||||
storage=LTMSQLiteStorage(
|
||||
db_path="/my_data_dir/my_crew1/long_term_memory_storage.db"
|
||||
)
|
||||
),
|
||||
short_term_memory=EnhanceShortTermMemory(
|
||||
storage=CustomRAGStorage(
|
||||
crew_name="my_crew",
|
||||
storage_type="short_term",
|
||||
data_dir="//my_data_dir",
|
||||
model=embedder["model"],
|
||||
dimension=embedder["dimension"],
|
||||
),
|
||||
),
|
||||
entity_memory=EnhanceEntityMemory(
|
||||
storage=CustomRAGStorage(
|
||||
crew_name="my_crew",
|
||||
storage_type="entities",
|
||||
data_dir="//my_data_dir",
|
||||
model=embedder["model"],
|
||||
dimension=embedder["dimension"],
|
||||
),
|
||||
),
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
## Additional Embedding Providers
|
||||
|
||||
### Using OpenAI embeddings (already default)
|
||||
```python Code
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
|
||||
my_crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
process=Process.sequential,
|
||||
memory=True,
|
||||
verbose=True,
|
||||
embedder={
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": 'text-embedding-3-small'
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
Alternatively, you can directly pass the OpenAIEmbeddingFunction to the embedder parameter.
|
||||
|
||||
Example:
|
||||
```python Code
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
from chromadb.utils.embedding_functions import OpenAIEmbeddingFunction
|
||||
|
||||
my_crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
process=Process.sequential,
|
||||
memory=True,
|
||||
verbose=True,
|
||||
embedder=OpenAIEmbeddingFunction(api_key=os.getenv("OPENAI_API_KEY"), model_name="text-embedding-3-small"),
|
||||
)
|
||||
```
|
||||
|
||||
### Using Ollama embeddings
|
||||
|
||||
```python Code
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
|
||||
my_crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
process=Process.sequential,
|
||||
memory=True,
|
||||
verbose=True,
|
||||
embedder={
|
||||
"provider": "ollama",
|
||||
"config": {
|
||||
"model": "mxbai-embed-large"
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Using Google AI embeddings
|
||||
|
||||
```python Code
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
|
||||
my_crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
process=Process.sequential,
|
||||
memory=True,
|
||||
verbose=True,
|
||||
embedder={
|
||||
"provider": "google",
|
||||
"config": {
|
||||
"api_key": "<YOUR_API_KEY>",
|
||||
"model_name": "<model_name>"
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Using Azure OpenAI embeddings
|
||||
|
||||
```python Code
|
||||
from chromadb.utils.embedding_functions import OpenAIEmbeddingFunction
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
|
||||
my_crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
process=Process.sequential,
|
||||
memory=True,
|
||||
verbose=True,
|
||||
embedder=OpenAIEmbeddingFunction(
|
||||
api_key="YOUR_API_KEY",
|
||||
api_base="YOUR_API_BASE_PATH",
|
||||
api_type="azure",
|
||||
api_version="YOUR_API_VERSION",
|
||||
model_name="text-embedding-3-small"
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Using Vertex AI embeddings
|
||||
|
||||
```python Code
|
||||
from chromadb.utils.embedding_functions import GoogleVertexEmbeddingFunction
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
|
||||
my_crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
process=Process.sequential,
|
||||
memory=True,
|
||||
verbose=True,
|
||||
embedder=GoogleVertexEmbeddingFunction(
|
||||
project_id="YOUR_PROJECT_ID",
|
||||
region="YOUR_REGION",
|
||||
api_key="YOUR_API_KEY",
|
||||
model_name="textembedding-gecko"
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Using Cohere embeddings
|
||||
|
||||
```python Code
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
|
||||
my_crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
process=Process.sequential,
|
||||
memory=True,
|
||||
verbose=True,
|
||||
embedder={
|
||||
"provider": "cohere",
|
||||
"config": {
|
||||
"api_key": "YOUR_API_KEY",
|
||||
"model_name": "<model_name>"
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
### Using HuggingFace embeddings
|
||||
|
||||
```python Code
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
|
||||
my_crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
process=Process.sequential,
|
||||
memory=True,
|
||||
verbose=True,
|
||||
embedder={
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"api_url": "<api_url>",
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Using Watson embeddings
|
||||
|
||||
```python Code
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
|
||||
# Note: Ensure you have installed and imported `ibm_watsonx_ai` for Watson embeddings to work.
|
||||
|
||||
my_crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
process=Process.sequential,
|
||||
memory=True,
|
||||
verbose=True,
|
||||
embedder={
|
||||
"provider": "watson",
|
||||
"config": {
|
||||
"model": "<model_name>",
|
||||
"api_url": "<api_url>",
|
||||
"api_key": "<YOUR_API_KEY>",
|
||||
"project_id": "<YOUR_PROJECT_ID>",
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Resetting Memory
|
||||
|
||||
```shell
|
||||
crewai reset-memories [OPTIONS]
|
||||
```
|
||||
|
||||
#### Resetting Memory Options
|
||||
|
||||
| Option | Description | Type | Default |
|
||||
| :----------------- | :------------------------------- | :------------- | :------ |
|
||||
| `-l`, `--long` | Reset LONG TERM memory. | Flag (boolean) | False |
|
||||
| `-s`, `--short` | Reset SHORT TERM memory. | Flag (boolean) | False |
|
||||
| `-e`, `--entities` | Reset ENTITIES memory. | Flag (boolean) | False |
|
||||
| `-k`, `--kickoff-outputs` | Reset LATEST KICKOFF TASK OUTPUTS. | Flag (boolean) | False |
|
||||
| `-a`, `--all` | Reset ALL memories. | Flag (boolean) | False |
|
||||
|
||||
|
||||
## Benefits of Using CrewAI's Memory System
|
||||
|
||||
- 🦾 **Adaptive Learning:** Crews become more efficient over time, adapting to new information and refining their approach to tasks.
|
||||
- 🫡 **Enhanced Personalization:** Memory enables agents to remember user preferences and historical interactions, leading to personalized experiences.
|
||||
- 🧠 **Improved Problem Solving:** Access to a rich memory store aids agents in making more informed decisions, drawing on past learnings and contextual insights.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Integrating CrewAI's memory system into your projects is straightforward. By leveraging the provided memory components and configurations,
|
||||
you can quickly empower your agents with the ability to remember, reason, and learn from their interactions, unlocking new levels of intelligence and capability.
|
||||
151
docs/concepts/planning.mdx
Normal file
@@ -0,0 +1,151 @@
|
||||
---
|
||||
title: Planning
|
||||
description: Learn how to add planning to your CrewAI Crew and improve their performance.
|
||||
icon: brain
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
The planning feature in CrewAI allows you to add planning capability to your crew. When enabled, before each Crew iteration,
|
||||
all Crew information is sent to an AgentPlanner that will plan the tasks step by step, and this plan will be added to each task description.
|
||||
|
||||
### Using the Planning Feature
|
||||
|
||||
Getting started with the planning feature is very easy, the only step required is to add `planning=True` to your Crew:
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
|
||||
# Assemble your crew with planning capabilities
|
||||
my_crew = Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
planning=True,
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
From this point on, your crew will have planning enabled, and the tasks will be planned before each iteration.
|
||||
|
||||
#### Planning LLM
|
||||
|
||||
Now you can define the LLM that will be used to plan the tasks. You can use any ChatOpenAI LLM model available.
|
||||
|
||||
When running the base case example, you will see something like the output below, which represents the output of the `AgentPlanner`
|
||||
responsible for creating the step-by-step logic to add to the Agents' tasks.
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
from crewai import Crew, Agent, Task, Process
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
# Assemble your crew with planning capabilities and custom LLM
|
||||
my_crew = Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
planning=True,
|
||||
planning_llm=ChatOpenAI(model="gpt-4o")
|
||||
)
|
||||
|
||||
# Run the crew
|
||||
my_crew.kickoff()
|
||||
```
|
||||
|
||||
```markdown Result
|
||||
[2024-07-15 16:49:11][INFO]: Planning the crew execution
|
||||
**Step-by-Step Plan for Task Execution**
|
||||
|
||||
**Task Number 1: Conduct a thorough research about AI LLMs**
|
||||
|
||||
**Agent:** AI LLMs Senior Data Researcher
|
||||
|
||||
**Agent Goal:** Uncover cutting-edge developments in AI LLMs
|
||||
|
||||
**Task Expected Output:** A list with 10 bullet points of the most relevant information about AI LLMs
|
||||
|
||||
**Task Tools:** None specified
|
||||
|
||||
**Agent Tools:** None specified
|
||||
|
||||
**Step-by-Step Plan:**
|
||||
|
||||
1. **Define Research Scope:**
|
||||
|
||||
- Determine the specific areas of AI LLMs to focus on, such as advancements in architecture, use cases, ethical considerations, and performance metrics.
|
||||
|
||||
2. **Identify Reliable Sources:**
|
||||
|
||||
- List reputable sources for AI research, including academic journals, industry reports, conferences (e.g., NeurIPS, ACL), AI research labs (e.g., OpenAI, Google AI), and online databases (e.g., IEEE Xplore, arXiv).
|
||||
|
||||
3. **Collect Data:**
|
||||
|
||||
- Search for the latest papers, articles, and reports published in 2023 and early 2024.
|
||||
- Use keywords like "Large Language Models 2024", "AI LLM advancements", "AI ethics 2024", etc.
|
||||
|
||||
4. **Analyze Findings:**
|
||||
|
||||
- Read and summarize the key points from each source.
|
||||
- Highlight new techniques, models, and applications introduced in the past year.
|
||||
|
||||
5. **Organize Information:**
|
||||
|
||||
- Categorize the information into relevant topics (e.g., new architectures, ethical implications, real-world applications).
|
||||
- Ensure each bullet point is concise but informative.
|
||||
|
||||
6. **Create the List:**
|
||||
|
||||
- Compile the 10 most relevant pieces of information into a bullet point list.
|
||||
- Review the list to ensure clarity and relevance.
|
||||
|
||||
**Expected Output:**
|
||||
|
||||
A list with 10 bullet points of the most relevant information about AI LLMs.
|
||||
|
||||
---
|
||||
|
||||
**Task Number 2: Review the context you got and expand each topic into a full section for a report**
|
||||
|
||||
**Agent:** AI LLMs Reporting Analyst
|
||||
|
||||
**Agent Goal:** Create detailed reports based on AI LLMs data analysis and research findings
|
||||
|
||||
**Task Expected Output:** A fully fledged report with the main topics, each with a full section of information. Formatted as markdown without '```'
|
||||
|
||||
**Task Tools:** None specified
|
||||
|
||||
**Agent Tools:** None specified
|
||||
|
||||
**Step-by-Step Plan:**
|
||||
|
||||
1. **Review the Bullet Points:**
|
||||
- Carefully read through the list of 10 bullet points provided by the AI LLMs Senior Data Researcher.
|
||||
|
||||
2. **Outline the Report:**
|
||||
- Create an outline with each bullet point as a main section heading.
|
||||
- Plan sub-sections under each main heading to cover different aspects of the topic.
|
||||
|
||||
3. **Research Further Details:**
|
||||
- For each bullet point, conduct additional research if necessary to gather more detailed information.
|
||||
- Look for case studies, examples, and statistical data to support each section.
|
||||
|
||||
4. **Write Detailed Sections:**
|
||||
- Expand each bullet point into a comprehensive section.
|
||||
- Ensure each section includes an introduction, detailed explanation, examples, and a conclusion.
|
||||
- Use markdown formatting for headings, subheadings, lists, and emphasis.
|
||||
|
||||
5. **Review and Edit:**
|
||||
- Proofread the report for clarity, coherence, and correctness.
|
||||
- Make sure the report flows logically from one section to the next.
|
||||
- Format the report according to markdown standards.
|
||||
|
||||
6. **Finalize the Report:**
|
||||
- Ensure the report is complete with all sections expanded and detailed.
|
||||
- Double-check formatting and make any necessary adjustments.
|
||||
|
||||
**Expected Output:**
|
||||
A fully fledged report with the main topics, each with a full section of information. Formatted as markdown without '```'.
|
||||
```
|
||||
</CodeGroup>
|
||||
67
docs/concepts/processes.mdx
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
title: Processes
|
||||
description: Detailed guide on workflow management through processes in CrewAI, with updated implementation details.
|
||||
icon: bars-staggered
|
||||
---
|
||||
|
||||
## Understanding Processes
|
||||
<Tip>
|
||||
Processes orchestrate the execution of tasks by agents, akin to project management in human teams.
|
||||
These processes ensure tasks are distributed and executed efficiently, in alignment with a predefined strategy.
|
||||
</Tip>
|
||||
|
||||
## Process Implementations
|
||||
|
||||
- **Sequential**: Executes tasks sequentially, ensuring tasks are completed in an orderly progression.
|
||||
- **Hierarchical**: Organizes tasks in a managerial hierarchy, where tasks are delegated and executed based on a structured chain of command. A manager language model (`manager_llm`) or a custom manager agent (`manager_agent`) must be specified in the crew to enable the hierarchical process, facilitating the creation and management of tasks by the manager.
|
||||
- **Consensual Process (Planned)**: Aiming for collaborative decision-making among agents on task execution, this process type introduces a democratic approach to task management within CrewAI. It is planned for future development and is not currently implemented in the codebase.
|
||||
|
||||
## The Role of Processes in Teamwork
|
||||
Processes enable individual agents to operate as a cohesive unit, streamlining their efforts to achieve common objectives with efficiency and coherence.
|
||||
|
||||
## Assigning Processes to a Crew
|
||||
To assign a process to a crew, specify the process type upon crew creation to set the execution strategy. For a hierarchical process, ensure to define `manager_llm` or `manager_agent` for the manager agent.
|
||||
|
||||
```python
|
||||
from crewai import Crew
|
||||
from crewai.process import Process
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
# Example: Creating a crew with a sequential process
|
||||
crew = Crew(
|
||||
agents=my_agents,
|
||||
tasks=my_tasks,
|
||||
process=Process.sequential
|
||||
)
|
||||
|
||||
# Example: Creating a crew with a hierarchical process
|
||||
# Ensure to provide a manager_llm or manager_agent
|
||||
crew = Crew(
|
||||
agents=my_agents,
|
||||
tasks=my_tasks,
|
||||
process=Process.hierarchical,
|
||||
manager_llm=ChatOpenAI(model="gpt-4")
|
||||
# or
|
||||
# manager_agent=my_manager_agent
|
||||
)
|
||||
```
|
||||
**Note:** Ensure `my_agents` and `my_tasks` are defined prior to creating a `Crew` object, and for the hierarchical process, either `manager_llm` or `manager_agent` is also required.
|
||||
|
||||
## Sequential Process
|
||||
|
||||
This method mirrors dynamic team workflows, progressing through tasks in a thoughtful and systematic manner. Task execution follows the predefined order in the task list, with the output of one task serving as context for the next.
|
||||
|
||||
To customize task context, utilize the `context` parameter in the `Task` class to specify outputs that should be used as context for subsequent tasks.
|
||||
|
||||
## Hierarchical Process
|
||||
|
||||
Emulates a corporate hierarchy, CrewAI allows specifying a custom manager agent or automatically creates one, requiring the specification of a manager language model (`manager_llm`). This agent oversees task execution, including planning, delegation, and validation. Tasks are not pre-assigned; the manager allocates tasks to agents based on their capabilities, reviews outputs, and assesses task completion.
|
||||
|
||||
## Process Class: Detailed Overview
|
||||
|
||||
The `Process` class is implemented as an enumeration (`Enum`), ensuring type safety and restricting process values to the defined types (`sequential`, `hierarchical`). The consensual process is planned for future inclusion, emphasizing our commitment to continuous development and innovation.
|
||||
|
||||
## Conclusion
|
||||
|
||||
The structured collaboration facilitated by processes within CrewAI is crucial for enabling systematic teamwork among agents.
|
||||
This documentation has been updated to reflect the latest features, enhancements, and the planned integration of the Consensual Process, ensuring users have access to the most current and comprehensive information.
|
||||