Created
October 13, 2024 07:20
-
-
Save krishnaglodha/616098ef3a57a0cbf6cc890c2aa00237 to your computer and use it in GitHub Desktop.
Multi agent setup using ollama and crewai
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Author : [email protected] | |
Motivation : https://medium.com/the-ai-forum/create-a-blog-writer-multi-agent-system-using-crewai-and-ollama-f47654a5e1cd | |
Steps on how to use this: | |
1. Create virtualenv and install packages from req.txt | |
2. Download ollama from https://ollama.com/ | |
3. Make custom ollama using `ollama create crewai-llama3 -f .\Modelfile` | |
""" | |
from crewai import Agent, Task, Crew | |
from langchain_openai import ChatOpenAI | |
import os | |
os.environ["OPENAI_API_KEY"] = "NA" | |
llm = ChatOpenAI( | |
model = "crewai-llama3", | |
base_url = "http://localhost:11434/v1") | |
planner = Agent( | |
role="Marketing and Branding Planner", | |
goal="Plan engaging and factually accurate content on {topic} , try to include code snippets and images if possible.", | |
backstory=" Your mindset is similar to Gary Vaynerchuk, You're working as marketing and branding planner for Rotten Grapes Private Limited, which is a Geospatial software development company. " | |
"This company focuses on developing software solutions for the geospatial industry. " | |
"You want to always keep in mind that every writing material should get user to contact us at https://rottengrapes.tech/contact " | |
"You're working on planning a blog article keeping marketing and branding in mind " | |
"about the topic: {topic}" | |
"You collect information that helps the " | |
"audience learn something " | |
"and make informed decisions. " | |
"You have to prepare a detailed " | |
"outline and the relevant topics and sub-topics that has to be a part of the" | |
"blogpost. we need to include code snippets and images if possible." | |
"Your work is the basis for " | |
"the Content Writer to write an article on this topic.", | |
llm=llm, | |
allow_delegation=False, | |
verbose=True | |
) | |
writer = Agent( | |
role="Content Writer", | |
goal="Write insightful and factually accurate " | |
"opinion piece about the topic: {topic}", | |
backstory="You're working on a writing " | |
"a new opinion piece about the topic: {topic}" | |
"You base your writing on the work of " | |
"the Content Planner, who provides an outline " | |
"and relevant context about the topic. " | |
"You follow the main objectives and " | |
"direction of the outline, " | |
"as provide by the Content Planner. " | |
"You need to write big paragraphs and " | |
"You also provide objective and impartial insights " | |
"and back them up with information " | |
"and we need to include code snippets and images if possible" | |
"provide by the Content Planner. " | |
"You acknowledge in your opinion piece " | |
"when your statements are opinions " | |
"as opposed to objective statements.", | |
allow_delegation=False, | |
llm=llm, | |
verbose=True | |
) | |
editor = Agent( | |
role="Editor", | |
goal="Edit a given blog post to align with " | |
"the writing style of the organization 'https://medium.com/'. ", | |
backstory="You are an editor who receives a blog post " | |
"from the Content Writer. " | |
"Your goal is to review the blog post " | |
"to ensure that it follows journalistic best practices," | |
"provides balanced viewpoints " | |
"when providing opinions or assertions, " | |
"and also avoids major controversial topics " | |
"or opinions when possible.", | |
llm=llm, | |
allow_delegation=False, | |
verbose=True | |
) | |
plan = Task( | |
description=( | |
"1. Prioritize the latest trends, key players, " | |
"and noteworthy news on {topic}.\n" | |
"2. Identify the target audience, considering " | |
"their interests and pain points.\n" | |
"3. Develop a detailed content outline including " | |
"an introduction, key points, and a call to action.\n" | |
"4. Include SEO keywords and relevant data or sources." | |
"5. Include CTA to let user bring to https://rottengrapes.tech/contact" | |
), | |
expected_output="A comprehensive content plan document " | |
"with an outline, audience analysis, " | |
"SEO keywords, and resources.", | |
agent=planner, | |
) | |
write = Task( | |
description=( | |
"1. Use the content plan to craft a compelling " | |
"blog post on {topic}.\n" | |
"2. Incorporate SEO keywords naturally.\n" | |
"3. Sections/Subtitles are properly named " | |
"in an engaging manner.\n" | |
"4. Ensure the post is structured with an " | |
"engaging introduction, insightful body, " | |
"and a summarizing conclusion.\n" | |
"5. Proofread for grammatical errors and " | |
"alignment with the brand's voice.\n" | |
), | |
expected_output="A well-written blog post " | |
"in markdown format, ready for publication, " | |
"each section should have 3 or 4 paragraphs." | |
"make sure to include a summary at the end." | |
"make sure to write more human friendly tone and language." | |
"Try to include code snippets and examples." | |
"Try to include a call to action at the end.", | |
agent=writer, | |
) | |
edit = Task( | |
description=("Proofread the given blog post for " | |
"grammatical errors and " | |
"alignment with the brand's voice."), | |
expected_output="A well-written blog post in markdown format, " | |
"ready for publication, " | |
"each section should have 2 or 3 paragraphs.", | |
agent=editor | |
) | |
crew = Crew( | |
agents=[planner, writer, editor], | |
tasks=[plan, write, edit], | |
verbose=2 | |
) | |
inputs = {"topic":"Write blog on 'How to expose postGIS data easily', in this blog I want to show how anyone can get postgis data such as using Postgrest, using Geoserver, using ST_MVT, etc. I want at least 5 end with CTA"} | |
result = crew.kickoff(inputs=inputs) | |
from IPython.display import Markdown,display | |
display(Markdown(result)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM llama3 | |
# Set parameters | |
PARAMETER temperature 0.8 | |
PARAMETER stop Result | |
# Sets a custom system message to specify the behavior of the chat assistant | |
# Leaving it blank for now. | |
SYSTEM """""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
aiohappyeyeballs==2.4.3 | |
aiohttp==3.10.10 | |
aiosignal==1.3.1 | |
alembic==1.13.3 | |
aniso8601==9.0.1 | |
annotated-types==0.7.0 | |
anyio==4.6.0 | |
appdirs==1.4.4 | |
appnope==0.1.4 | |
argon2-cffi==23.1.0 | |
argon2-cffi-bindings==21.2.0 | |
arrow==1.3.0 | |
asgiref==3.8.1 | |
asttokens==2.4.1 | |
async-lru==2.0.4 | |
attrs==23.2.0 | |
babel==2.16.0 | |
backoff==2.2.1 | |
bcrypt==4.2.0 | |
beautifulsoup4==4.12.3 | |
bleach==6.1.0 | |
blinker==1.8.2 | |
boto3==1.35.39 | |
botocore==1.35.39 | |
Brotli==1.1.0 | |
build==1.2.2.post1 | |
cachetools==5.5.0 | |
certifi==2024.8.30 | |
cffi==1.17.1 | |
charset-normalizer==3.4.0 | |
chroma-hnswlib==0.7.3 | |
chromadb==0.4.24 | |
clarifai==10.8.0 | |
clarifai-grpc==10.9.4 | |
click==8.1.7 | |
cloudpickle==2.2.1 | |
cohere==5.11.0 | |
coloredlogs==15.0.1 | |
comm==0.2.2 | |
contextlib2==21.6.0 | |
contourpy==1.3.0 | |
crewai==0.28.8 | |
crewai-tools==0.1.6 | |
cryptography==43.0.1 | |
cycler==0.12.1 | |
databricks-sdk==0.34.0 | |
dataclasses-json==0.6.7 | |
debugpy==1.8.7 | |
decorator==5.1.1 | |
defusedxml==0.7.1 | |
Deprecated==1.2.14 | |
deprecation==2.1.0 | |
dill==0.3.9 | |
distro==1.9.0 | |
docker==7.1.0 | |
docstring-parser==0.15 | |
durationpy==0.9 | |
embedchain==0.1.113 | |
executing==2.1.0 | |
fastapi==0.115.2 | |
fastavro==1.9.7 | |
fastjsonschema==2.20.0 | |
filelock==3.16.1 | |
Flask==3.0.3 | |
flatbuffers==24.3.25 | |
fonttools==4.54.1 | |
fqdn==1.5.1 | |
frozenlist==1.4.1 | |
fsspec==2024.9.0 | |
gitdb==4.0.11 | |
GitPython==3.1.43 | |
google-api-core==2.21.0 | |
google-auth==2.35.0 | |
google-cloud-aiplatform==1.70.0 | |
google-cloud-bigquery==3.26.0 | |
google-cloud-core==2.4.1 | |
google-cloud-resource-manager==1.12.5 | |
google-cloud-storage==2.18.2 | |
google-crc32c==1.6.0 | |
google-pasta==0.2.0 | |
google-resumable-media==2.7.2 | |
googleapis-common-protos==1.65.0 | |
gptcache==0.1.44 | |
graphene==3.3 | |
graphql-core==3.2.4 | |
graphql-relay==3.2.0 | |
grpc-google-iam-v1==0.13.1 | |
grpcio==1.64.3 | |
grpcio-status==1.62.3 | |
gunicorn==23.0.0 | |
h11==0.14.0 | |
httpcore==1.0.6 | |
httptools==0.6.1 | |
httpx==0.27.2 | |
httpx-sse==0.4.0 | |
huggingface-hub==0.25.2 | |
humanfriendly==10.0 | |
idna==3.10 | |
importlib-metadata==6.11.0 | |
importlib_resources==6.4.5 | |
iniconfig==2.0.0 | |
inquirerpy==0.3.4 | |
instructor==0.5.2 | |
ipykernel==6.29.5 | |
ipython==8.28.0 | |
ipywidgets==8.1.5 | |
isoduration==20.11.0 | |
itsdangerous==2.2.0 | |
jedi==0.19.1 | |
Jinja2==3.1.4 | |
jiter==0.6.1 | |
jmespath==1.0.1 | |
joblib==1.4.2 | |
json5==0.9.25 | |
jsonpatch==1.33 | |
jsonpointer==3.0.0 | |
jsonschema==4.23.0 | |
jsonschema-specifications==2024.10.1 | |
jupyter==1.1.1 | |
jupyter-console==6.6.3 | |
jupyter-events==0.10.0 | |
jupyter-lsp==2.2.5 | |
jupyter_client==8.6.3 | |
jupyter_core==5.7.2 | |
jupyter_server==2.14.2 | |
jupyter_server_terminals==0.5.3 | |
jupyterlab==4.2.5 | |
jupyterlab_pygments==0.3.0 | |
jupyterlab_server==2.27.3 | |
jupyterlab_widgets==3.0.13 | |
kiwisolver==1.4.7 | |
kubernetes==31.0.0 | |
lancedb==0.5.7 | |
langchain==0.1.13 | |
langchain-cohere==0.1.5 | |
langchain-community==0.0.29 | |
langchain-core==0.1.52 | |
langchain-openai==0.1.7 | |
langchain-text-splitters==0.0.2 | |
langsmith==0.1.134 | |
Mako==1.3.5 | |
Markdown==3.7 | |
markdown-it-py==3.0.0 | |
MarkupSafe==3.0.1 | |
marshmallow==3.22.0 | |
matplotlib==3.9.2 | |
matplotlib-inline==0.1.7 | |
mdurl==0.1.2 | |
mistune==3.0.2 | |
mlflow==2.17.0 | |
mlflow-skinny==2.17.0 | |
mmh3==5.0.1 | |
mock==4.0.3 | |
monotonic==1.6 | |
mpmath==1.3.0 | |
multidict==6.1.0 | |
multiprocess==0.70.17 | |
mutagen==1.47.0 | |
mypy-extensions==1.0.0 | |
nbclient==0.10.0 | |
nbconvert==7.16.4 | |
nbformat==5.10.4 | |
nest-asyncio==1.6.0 | |
nodeenv==1.9.1 | |
notebook==7.2.2 | |
notebook_shim==0.2.4 | |
numpy==1.26.4 | |
oauthlib==3.2.2 | |
onnxruntime==1.19.2 | |
openai==1.51.2 | |
opentelemetry-api==1.27.0 | |
opentelemetry-exporter-otlp-proto-common==1.27.0 | |
opentelemetry-exporter-otlp-proto-grpc==1.27.0 | |
opentelemetry-exporter-otlp-proto-http==1.27.0 | |
opentelemetry-instrumentation==0.48b0 | |
opentelemetry-instrumentation-asgi==0.48b0 | |
opentelemetry-instrumentation-fastapi==0.48b0 | |
opentelemetry-proto==1.27.0 | |
opentelemetry-sdk==1.27.0 | |
opentelemetry-semantic-conventions==0.48b0 | |
opentelemetry-util-http==0.48b0 | |
orjson==3.10.7 | |
outcome==1.3.0.post0 | |
overrides==7.7.0 | |
packaging==23.2 | |
pandas==2.2.3 | |
pandocfilters==1.5.1 | |
parameterized==0.9.0 | |
parso==0.8.4 | |
pathos==0.3.3 | |
pexpect==4.9.0 | |
pfzy==0.3.4 | |
pillow==10.4.0 | |
platformdirs==4.3.6 | |
pluggy==1.5.0 | |
posthog==3.7.0 | |
pox==0.3.5 | |
ppft==1.7.6.9 | |
prometheus_client==0.21.0 | |
prompt_toolkit==3.0.48 | |
propcache==0.2.0 | |
proto-plus==1.24.0 | |
protobuf==4.25.5 | |
psutil==6.0.0 | |
ptyprocess==0.7.0 | |
pulsar-client==3.5.0 | |
pure_eval==0.2.3 | |
py==1.11.0 | |
pyarrow==17.0.0 | |
pyasn1==0.6.1 | |
pyasn1_modules==0.4.1 | |
pycparser==2.22 | |
pycryptodomex==3.21.0 | |
pydantic==2.9.2 | |
pydantic_core==2.23.4 | |
PyGithub==1.59.1 | |
Pygments==2.18.0 | |
PyJWT==2.9.0 | |
pylance==0.9.18 | |
PyNaCl==1.5.0 | |
pyparsing==3.1.4 | |
pypdf==4.3.1 | |
PyPika==0.48.9 | |
pyproject_hooks==1.2.0 | |
pyright==1.1.384 | |
pysbd==0.3.4 | |
PySocks==1.7.1 | |
pytest==8.3.3 | |
python-dateutil==2.9.0.post0 | |
python-dotenv==1.0.0 | |
python-json-logger==2.0.7 | |
python-rapidjson==1.20 | |
pytube==15.0.0 | |
pytz==2024.2 | |
PyYAML==6.0.2 | |
pyzmq==26.2.0 | |
ratelimiter==1.2.0.post0 | |
referencing==0.35.1 | |
regex==2023.12.25 | |
requests==2.32.3 | |
requests-oauthlib==2.0.0 | |
requests-toolbelt==1.0.0 | |
retry==0.9.2 | |
rfc3339-validator==0.1.4 | |
rfc3986-validator==0.1.1 | |
rich==13.9.2 | |
rpds-py==0.20.0 | |
rsa==4.9 | |
s3transfer==0.10.3 | |
sagemaker==2.232.2 | |
sagemaker-core==1.0.10 | |
sagemaker-mlflow==0.1.0 | |
schema==0.7.5 | |
scikit-learn==1.5.2 | |
scipy==1.14.1 | |
selenium==4.25.0 | |
semver==3.0.2 | |
Send2Trash==1.8.3 | |
shapely==2.0.6 | |
six==1.16.0 | |
smdebug-rulesconfig==1.0.1 | |
smmap==5.0.1 | |
sniffio==1.3.1 | |
sortedcontainers==2.4.0 | |
soupsieve==2.6 | |
SQLAlchemy==2.0.35 | |
sqlparse==0.5.1 | |
stack-data==0.6.3 | |
starlette==0.39.2 | |
sympy==1.13.3 | |
tabulate==0.9.0 | |
tblib==3.0.0 | |
tenacity==8.5.0 | |
terminado==0.18.1 | |
threadpoolctl==3.5.0 | |
tiktoken==0.7.0 | |
tinycss2==1.3.0 | |
tokenizers==0.20.1 | |
tornado==6.4.1 | |
tqdm==4.66.5 | |
traitlets==5.14.3 | |
trio==0.26.2 | |
trio-websocket==0.11.1 | |
tritonclient==2.50.0 | |
typer==0.9.4 | |
types-python-dateutil==2.9.0.20241003 | |
types-requests==2.32.0.20240914 | |
typing-inspect==0.9.0 | |
typing_extensions==4.12.2 | |
tzdata==2024.2 | |
uri-template==1.3.0 | |
urllib3==2.2.3 | |
uvicorn==0.31.1 | |
uvloop==0.20.0 | |
watchfiles==0.24.0 | |
wcwidth==0.2.13 | |
webcolors==24.8.0 | |
webencodings==0.5.1 | |
websocket-client==1.8.0 | |
websockets==13.1 | |
Werkzeug==3.0.4 | |
widgetsnbextension==4.0.13 | |
wrapt==1.16.0 | |
wsproto==1.2.0 | |
yarl==1.15.1 | |
youtube-transcript-api==0.6.2 | |
yt-dlp==2023.12.30 | |
zipp==3.20.2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment