AI-Powered Tagging
Relevant source files
The following files were used as context for generating this wiki page:- packages/shared/utils/ai.ts
- packages/server/src/api/tags.ts
- packages/server/src/model/store.ts
- packages/shared/types/config.ts
- packages/plugin/popup/components/TagInputWithCache.tsx
- packages/web/src/components/ai-tag-test-connection-button.tsx
- packages/server/src/api/pages.ts
- packages/web/src/assets/locales/en/translation.json
The AI-Powered Tagging feature automates the process of adding relevant tags to archived web pages. It analyzes the page's title and description to generate a concise list of up to five tags. This functionality is integrated into both the browser plugin and the web interface, enhancing content organization and discoverability.
The system is designed to be flexible, supporting multiple AI service providers, including Cloudflare AI and any OpenAI-compatible API. Users can configure their preferred service, model, and other settings, such as preferred tags and the language for the generated tags.
Architecture Overview
The AI Tagging system involves client-side components (in the browser plugin and web UI), a server-side API, and external AI services. The client initiates a request, which is either handled directly by calling an external API (like OpenAI) or proxied through the application's server (for Cloudflare AI).
This diagram illustrates the high-level architecture of the AI Tagging feature.
Configuration
The AI Tagging feature's behavior is controlled by a configuration object stored in the database. This configuration is managed via the getAITagConfig and setAITagConfig functions, which interact with the stores table where the key is 'AI_TAG'.
Sources: packages/server/src/model/store.ts:65-93, packages/shared/types/config.ts:1-12
AITagConfig Data Structure
The configuration is defined by the AITagConfig type.
| Field | Type | Description | Default Value |
|---|---|---|---|
type | 'cloudflare' | 'openai' | The AI service provider to use. | 'cloudflare' |
tagLanguage | 'en' | 'zh' | The desired language for the generated tags. | 'en' |
model | string | The specific AI model name to be used for generation. | '' |
preferredTags | string[] | A list of tags to be prioritized during generation. | [] |
apiUrl? | string | The API endpoint URL. Required only for openai type. | undefined |
apiKey? | string | The API key for authentication. Required only for openai type. | undefined |
Sources: packages/shared/types/config.ts:1-12, packages/server/src/model/store.ts:72-78
Connection Testing
The web interface provides a "Test Connection" button (AITagTestConnectionButton) to validate the user's AI configuration. This component simulates a tag generation request using "Test Title" and "Test Description" to verify that the endpoint and credentials are correct. It provides visual feedback on success, failure, or in-progress status.
Sources: packages/web/src/components/ai-tag-test-connection-button.tsx
Tag Generation Flow
The process of generating tags is initiated from the client and varies slightly depending on the configured service type.
This sequence diagram shows the flow for both Cloudflare and OpenAI service types.
Prompt Engineering
A crucial part of the process is constructing the right prompt for the AI model. The buildGenerateTagMessage function creates a structured message payload. The system prompt, generated by generateChatCompletion, instructs the AI to follow a specific set of rules to ensure consistent and high-quality output.
The rules given to the AI are:
- Use the specified language (e.g., 'chinese' or 'english').
- Keep common technical terms and abbreviations as-is.
- Keep brand names in their original form.
- Tags should be keywords, not explanations.
- The return format must be a JSON object:
{"tags": ["tag1", "tag2", ...]}. - Do not return any explanatory text.
- Prioritize a given list of
preferredTags. - Keep tags concise and return no more than 5 tags.
- Select only the most representative and important tags.
Sources: packages/shared/utils/ai.ts:32-55
// packages/shared/utils/ai.ts:38-55
function generateChatCompletion(tagLanguage: string, preferredTags: string[]): string {
return `What tags would you give to the input content? Please follow these rules:
1. Use ${tagLanguage === 'zh' ? 'chinese' : 'english'} for most tags
2. Keep common technical terms and abbreviations as-is
3. Keep brand names in their original form
4. Note that tags should be keywords related to the content, not explanations of the content
5. Return format must be: {"tags": ["tag1", "tag2", ...]}
6. Do not return any explanatory text
7. Please prioritize these tags and add other relevant tags based on the content: [${preferredTags.join(', ')}]
8. Keep tags concise and focused. Return no more than 5 tags in total
9. Select the most representative and important tags only
`
}
API Endpoints
The server exposes an endpoint to handle tag generation requests, specifically for the Cloudflare AI integration.
POST /api/tags/generate_tag
This endpoint is used when the service type is configured to cloudflare. It takes page details and AI configuration, runs the model on the Cloudflare AI platform, and returns the generated tags.
Request Body:
| Parameter | Type | Required | Description |
|---|---|---|---|
title | string | Yes | The title of the web page. |
pageDesc | string | No | The description of the web page. Defaults to ''. |
model | string | Yes | The name of the Cloudflare AI model to use. |
tagLanguage | 'en'|'zh' | Yes | The language for the generated tags. |
preferredTags | string[] | No | An array of preferred tags. Defaults to []. |
Sources: packages/server/src/api/tags.ts:88-101
Responses:
200 OK: Returns a JSON object with adatafield containing an array of tag strings.{ "status": "success", "data": ["tag1", "tag2", "tag3"] }400 Bad Request: If validation fails (e.g., missingtitleormodel).500 Internal Server Error: If the AI model fails to run or if the response cannot be parsed.
Sources: packages/server/src/api/tags.ts:102-124
Tag Association
Once tags are generated (or manually entered), they are associated with a page when it is saved. The POST /api/pages/upload_new_page and PUT /api/pages/update_page endpoints accept bindTags and unbindTags arrays. These are processed by the updateBindPageByTagName function, which updates the tags table in the database to link the tags to the page ID.
Sources: packages/server/src/api/pages.ts:70-73, 230-232, packages/server/src/model/tag.ts:114-124