From 236a82f2ccf7562042fdc795cf4f5e1cdbe6a540 Mon Sep 17 00:00:00 2001 From: cloudcloud666 Date: Tue, 17 Jun 2025 17:45:35 +0800 Subject: [PATCH] Create AI4S-Agent Co-building Initiative | Local Setup and Contribution Cases of ABACUS-agent-tools.md --- ...ontribution Cases of ABACUS-agent-tools.md | 430 ++++++++++++++++++ 1 file changed, 430 insertions(+) create mode 100644 source/_posts/AI4S-Agent Co-building Initiative | Local Setup and Contribution Cases of ABACUS-agent-tools.md diff --git a/source/_posts/AI4S-Agent Co-building Initiative | Local Setup and Contribution Cases of ABACUS-agent-tools.md b/source/_posts/AI4S-Agent Co-building Initiative | Local Setup and Contribution Cases of ABACUS-agent-tools.md new file mode 100644 index 0000000..fe72b60 --- /dev/null +++ b/source/_posts/AI4S-Agent Co-building Initiative | Local Setup and Contribution Cases of ABACUS-agent-tools.md @@ -0,0 +1,430 @@ +--- +titile : "AI4S-Agent Co-building Initiative | Local Setup and Contribution Cases of ABACUS-agent-tools" +date : 2025-06-13 +categories : +- ABACUS +--- + +This document describes how to install ABACUS agent and Google ADK in a local Linux environment (including WSL) as of June 12, 2025, and how to run a simple ABACUS calculation after startup. + +Requirements: conda and ABACUS (recommended to install v3.10 LTS version) are installed locally. + + + +## Tutorial for Experiencing ABACUS-agent-tools in Local Environment + +**Local Installation and Startup** + +**Create and activate the environment** + +``` +conda create -n abacus-agent python=3.11 +conda activate abacus-agent +``` + +**Install MCP, Google ADK, Litellm, and science-agent-sdk** + +``` +pip install mcp google-adk litellm science-agent-sdk +``` + +**Install abacus-agent** + +``` +git clone -b develop https://github.com/deepmodeling/ABACUS-agent-tools/ +cd abacus-agent +pip install . +``` + +**Install abacus-test** + +``` +cd .. +git clone -b develop https://github.com/pxlxingliang/abacus-test.git +cd abacus-test +pip install . +``` + +If ABACUS is not installed, you can install it with conda: + +``` +conda install abacus "libblas=*=*mkl" mpich -c conda-forge +``` + +**Set environment variables required by ABACUS agent tools** + +Before starting `abacusagent`, some environment variables need to be set in the configuration file. This file is located at `.abacusagent/env.json`. If the file does not exist, you can create it directly. + +When running ABACUS agent and Google ADK locally for ABACUS calculations, it is recommended to set at least the following environment variables: `ABACUSAGENT_WORK_PATH`, `ABACUS_COMMAND`, `ABACUS_PP_PATH`, `ABACUS_ORB_PATH`. Environment variables can be added by inserting them into env.json. + +It is recommended to use the efficiency orbitals and pseudopotentials in APNS-v1. + +``` +{ + "_comments": { + "ABACUS_WORK_PATH": "The working directory for AbacusAgent, where all temporary files will be stored.", + "ABACUS_SUBMIT_TYPE": "The type of submission for ABACUS, can be local or bohrium.", + "ABACUSAGENT_HOST": "The host address for the AbacusAgent server.", + "ABACUSAGENT_PORT": "The port number for the AbacusAgent server.", + "ABACUSAGENT_MODEL": "The model to use for AbacusAgent, can be 'fastmcp', 'test', or 'dp'.", + "BOHRIUM_USERNAME": "The username for Bohrium.", + "BOHRIUM_PASSWORD": "The password for Bohrium.", + "BOHRIUM_PROJECT_ID": "The project ID for Bohrium.", + "BOHRIUM_ABACUS_IMAGE": "The image for Abacus on Bohrium.", + "BOHRIUM_ABACUS_MACHINE": "The machine type for Abacus on Bohrium.", + "BOHRIUM_ABACUS_COMMAND": "The command to run Abacus on Bohrium", + "ABACUS_COMMAND": "The command to execute Abacus on local machine.", + "ABACUS_PP_PATH": "The path to the pseudopotential library for Abacus.", + "ABACUS_ORB_PATH": "The path to the orbital library for Abacus.", + "_comments": "This dictionary contains the default environment variables for AbacusAgent." + } +} +``` + +**Start abacusagent (or start in the background)** + + +``` +# Foreground startup +abacusagent + +# Background startup +nohup abacusagent & +``` + +The default port used is 50001, and the MCP server address is localhost. Use abacusagent -h to see how to change the MCP backend, the IP address, and port of the running MCP server. + +If the previous step was not started in the background, open a new terminal next and load the Python environment of the previous terminal. + +## Prepare agent.py for use by Google ADK + +``` +mkdir my_agents && cd my_agents +mkdir abacus_agent && cd abacus_agent +``` + +Create `agent.py` and fill in the following content: + +``` +import os +from google.adk.agents import Agent +from google.adk.models.lite_llm import LiteLlm +from google.adk.tools.mcp_tool import MCPToolset +from google.adk.tools.mcp_tool.mcp_toolset import SseServerParams +from dp.agent.adapter.adk import CalculationMCPToolset + +# Set the environment variables required for the LLM you are using and your own API key here +os.environ['DEEPSEEK_API_KEY'] = "" +model = LiteLlm(model='deepseek/deepseek-chat') + +instruction = """You are an expert in materials science and computational chemistry. " + "Help users perform ABACUS including single point calculation, structure optimization, molecular dynamics and property calculations. " + "The website of ABACUS documentation is at https://abacus.deepmodeling.com/en/latest/, please read it if necessary." + "Use default parameters if the users do not mention, but let users confirm them before submission. " + "Always verify the input parameters to users and provide clear explanations of results." + "The LCAO basis is prefered." + """ + +# Modify the url here according to the port used when starting abacusagent +toolset = CalculationMCPToolset( + connection_params=SseServerParams( + url="http://localhost:50001/sse", + ) +) + +root_agent = Agent( + name="Abacus_agent", + model=model, + instruction=instruction, + tools=[toolset] +) +``` + +Explanation: + +1.An LLM API key is required and imported into the environment variable. The example shows the method of using Deepseek's API; fill in the API key on line 9. For using other LLMs, please query the environment variables that need to be imported and modify line 14. + +2.Line 12 gives the prompt for the LLM, which can be appropriately modified to make the LLM perform better. + +3.The port of the URL in line 23 needs to be the same as the port used when starting abacusagent. + +## Start Google ADK + +After writing `agent.py`, start Google ADK locally: + +``` +cd .. +adk web +``` + +If the port is occupied, you can modify the port: `adk web --port 8001` + +``` +Started server process [3260] INFO: INFO: +Waiting for application startup. +ADK Web Server started +For local testing, access at http://localhost:8001. +INFO: INFO: +Application startup complete. Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit) +``` + +Access the given URL in a browser to start the conversation. You can use Chinese or English for the conversation. + +Below is an example of performing a relax calculation on a water molecule and giving the bond length of the O-H bond and the bond angle of H-O-H after optimization. + +``` +H2O +1.0 +10.00000000 0.00000000 0.00000000 + 0.00000000 10.00000000 0.00000000 + 0.00000000 0.00000000 10.00000000 + O H + 1 2 +Cartesian +4.89025267 4.76510552 4.31745869 +5.79758521 5.07855692 4.30766611 +4.34283524 5.35177489 3.79043572 +``` + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +**Add your own written tool functions** + +Currently, you can add your own written functions in `src/abacusagent/modules` and use the decorator `@mcp.tool() . `It is necessary to restart `abacusagent` and `adk`. + +## Contribution Cases + +**Calculation Function Case - Bader Charge Calculation** + +To implement Bader charge calculation, the following tool functions need to be built: + +1.Calculate the charge density based on the given ABACUS input file. + +2.Merge the charge densities of different spin components into one file. + +3.Perform Bader charge analysis using the merged file and output the results. + +Therefore, create the file `bader.py` and place it in the `src/abacusagent/modules/` directory. Construct the following functions in the file: + +``` +from abacusagent.init_mcp import mcp +from typing import Optional, List + +@mcp.tool() # important! to make this function visible to Agent +def calculate_charge_densities_with_abacus( + abacus: str, + jobdir: str +) -> Optional[List[str]]: + """ + calculate the charge densities (of different spin channels, if calculation + is polarized) within given prepared ABACUS job directory + Parameters: + abacus (str): Path to the abacus executable. + jobdir (str): Directory where the job files are located. + Returns: + list: List of file names for the charge density cube files. + """ + +@mcp.tool() # important! to make this function visible to Agent +def merge_charge_densities_of_different_spin( + cube_manipulator: str, + fcube: List[str] +) -> str: + """ + merge the charge densities of different spin channels into one file + Parameters: + cube_manipulator (str): Path to the cube manipulator executable. + fcube (list): List of file names for the cube files to be manipulated. + Returns: + str: Output cube file path. + """ + +@mcp.tool() # important! to make this function visible to Agent +def calculate_bader_charges( + bader: str, + fcube: str +) -> List[str]: + """ + Calculate Bader charges using the bader executable. + Parameters: + bader (str): Path to the bader executable. + fcube (str): Path to the cube file containing charge density. + Returns: + list: A list of file names generated by the Bader analysis. + """ +``` + +In addition, several tool functions are implemented for automatically identifying whether it is a spin-polarized calculation and reading input/output files. Decorate the above main functions expected to be called by the Agent with the `mcp_tool()` decorator to enable Agent calls. + +**Calculation Example Contribution Case - Band Gap of NiO** + +To automatically select examples from the database for the requested material calculation, a tool function in ABACUS-agent-tools is written and stored in `src/abacusagent/modules/abacus.py`: + +``` +from abacusagent.init_mcp import mcp +from typing import Literal, TypedDict +from pathlib import Path +import json +import time +import os +import shutil +from abacusagent.preprocess import PrepInput +from abacusagent.utils import WriteInput + +@mcp.tool() +def abacus_prepare_example_material( + chemical_formula: Literal['NiO'] = 'NiO' + ) -> TypedDict("results", {"job_path": str, 'description': str}): + """ + Prepare input files for ABACUS from given examples. Should only be used if the completely same material are requested to calculate. + Currently examples are listed here: + - NiO: A typical antiferromagnetic material. The provided example calculate the band gap of NiO with PBE+U and the U for Ni 3d is 5 eV. + Args: + chemical_formula: The chemical formula of the material. Should be among provided examples. + Returns: + A dictionary contains the job path, with input files generated according to provided examples and original description in the example. + """ + example_database_path = Path(__file__).resolve().parent / "example_data" + with open(example_database_path / f"{chemical_formula}.json") as fin: + job_info = json.load(fin) + input, stru = job_info['input'], job_info['stru'] + current_time = time.strftime("%Y%m%d%H%M%S") + job_work_dir = Path(f"{os.environ['ABACUSAGENT_WORK_PATH']}") / f"{chemical_formula}-{current_time}" + temp_stru_file_path = f'/tmp/{chemical_formula}-{current_time}' + with open(temp_stru_file_path, "w") as fout: + for lines in stru: + fout.write(lines + "\n") + fout.close() + _, job_path = PrepInput( + files=temp_stru_file_path, + filetype="abacus/stru", + jobtype='scf', + lcao=True + ).run() + job_path = Path(job_path[0]) + WriteInput(input, job_path / "INPUT") + os.remove(temp_stru_file_path) + shutil.move(job_path, job_work_dir) + return {'job_path': str(job_work_dir.absolute()), + 'description': job_info['description']} +``` + +For example, after preparing the following NiO band gap calculation case (stored in `src/abacusagent/modules/example_data/NiO.json`), the Agent can find that the NiO band gap case has been saved in the database and automatically read the database to prepare ABACUS calculation files. + +``` +{ + "description": "This example is calculating the band gap of NiO using APNS-v1 pseudopotential and orbital bundle. This material is a typical magnetic material. The magnetic moment of Ni atoms are in antiferromangetics form. The band gap are calculated using PBE+U with Ueff= 7 eV for Ni 3d orbital.", + "input": { + "suffix": "NiO", + "ntype": 2, + "calculation": "scf", + "ecutwfc": 100, + "scf_thr": 1e-07, + "scf_nmax": 200, + "smearing_method": "gaussian", + "smearing_sigma": 0.01, + "mixing_type": "broyden", + "mixing_beta": 0.2, + "mixing_gg0": 1.5, + "ks_solver": "genelpa", + "basis_type": "lcao", + "gamma_only": 0, + "symmetry": 1, + "nspin": 2, + "dft_plus_u": 1, + "orbital_corr": "2 -1", + "hubbard_u": "7.0 0.0", + "out_mul": 1, + "out_bandgap": 1, + "kspacing": 0.1 + }, + "stru": [ + "ATOMIC_SPECIES", + "Ni 58.6934 Ni_ONCV_PBE-1.2.upf upf201", + "O 15.9994 O.upf upf201", + "NUMERICAL_ORBITAL", + "Ni_gga_8au_100Ry_4s2p2d1f.orb", + "O_gga_6au_100Ry_2s2p1d.orb", + "LATTICE_CONSTANT", + "1.8897260000", + "LATTICE_VECTORS", + "4.1632639461 2.0729584133 2.0729584133", + "2.0729584133 4.1632639461 2.0729584133", + "2.0729584133 2.0729584133 4.1632639461", + "ATOMIC_POSITIONS", + "Direct", + "Ni #label", + "0.0000 #magnetism", + "2 #number of atoms", + "0.0000000000 0.0000000000 0.0000000000 m 1 1 1 mag 1.3047", + "0.5000000000 0.5000000000 0.5000000000 m 1 1 1 mag -1.3047", + "O #label", + "0.0000 #magnetism", + "2 #number of atoms", + "0.2500000000 0.2500000000 0.2500000000 m 1 1 1 mag -0.0000", + "0.7500000000 0.7500000000 0.7500000000 m 1 1 1 mag -0.0000" + ], + "pp": "APNS-v1", + "orb": "APNS-v1" + } +``` + +
+ +
+ +For subsequent further development, it is hoped to achieve fuzzy matching, select the case closest to the desired calculation from the database, and automatically prepare the input file. + +**Bader Charge Calculation Case Demonstration** + +A workflow driver function named `calculate` is also created in `bader.py`: + +``` +@mcp.tool() +def calculate( + jobdir: str, + abacus: str, + cube_manipulator: str, + bader: str +) -> List[float]: + """ + Calculate Bader charges for a given job directory, with ABACUS as + the dft software to calculate the charge density, and then postprocess + the charge density with the cube manipulator and Bader analysis. + Parameters: + jobdir (str): Directory where the job files are located. + abacus (str): Path to the abacus executable. + cube_manipulator (str): Path to the cube manipulator executable. + bader (str): Path to the bader executable. + Returns: + list: A list of Bader charges. + """ +``` + +Therefore, if the prompt is written correctly, the numerical values of Bader charges can be directly obtained, and the Agent will automatically perform ABACUS calculation, cube file processing, and Bader post-processing operations: + +
+ +
+ + + + + + + +